[Pkg-golang-commits] [golang] 01/01: Imported Upstream version 1.4

Tianon Gravi admwiggin at gmail.com
Thu Jan 15 18:54:53 UTC 2015


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

tianon-guest pushed a commit to branch upstream-experimental
in repository golang.

commit f154da9e12608589e8d5f0508f908a0c3e88a1bb
Author: Tianon Gravi <admwiggin at gmail.com>
Date:   Thu Jan 15 11:54:00 2015 -0700

    Imported Upstream version 1.4
---
 AUTHORS                                            |    35 +-
 CONTRIBUTORS                                       |    47 +-
 VERSION                                            |     2 +-
 api/except.txt                                     |     1 +
 api/go1.4.txt                                      |   604 +
 api/next.txt                                       |    24 +
 doc/articles/go_command.html                       |    15 +-
 doc/articles/race_detector.html                    |    27 +-
 doc/asm.html                                       |   157 +-
 doc/cmd.html                                       |     8 +-
 doc/code.html                                      |   187 +-
 doc/contrib.html                                   |    33 +-
 doc/contribute.html                                |   674 +-
 doc/debugging_with_gdb.html                        |    50 +-
 doc/devel/release.html                             |    10 +-
 doc/devel/weekly.html                              |     2 +-
 doc/docs.html                                      |     4 +-
 doc/effective_go.html                              |     4 +-
 doc/gccgo_contribute.html                          |     2 +-
 doc/gccgo_install.html                             |     4 +
 doc/go1.3.html                                     |     4 +-
 doc/go1.4.html                                     |   896 ++
 doc/go1.html                                       |     2 +-
 doc/go1compat.html                                 |    35 +-
 doc/go_faq.html                                    |   100 +-
 doc/go_mem.html                                    |    23 +
 doc/go_spec.html                                   |   899 +-
 doc/gopher/biplane.jpg                             |   Bin 0 -> 203420 bytes
 doc/gopher/fiveyears.jpg                           |   Bin 0 -> 220526 bytes
 doc/help.html                                      |     2 +-
 doc/install-source.html                            |     6 +-
 doc/install.html                                   |    29 +-
 include/bio.h                                      |     8 +
 include/link.h                                     |    35 +-
 lib/time/update.bash                               |     4 +-
 lib/time/zoneinfo.zip                              |   Bin 358933 -> 360713 bytes
 misc/IntelliJIDEA/Go.xml                           |    99 -
 misc/android/README                                |    11 +
 misc/android/go_android_exec.go                    |    96 +
 misc/bash/go                                       |   237 -
 misc/bbedit/Go.plist                               |   104 -
 misc/benchcmp                                      |     2 +-
 misc/cgo/errors/issue7757.go                       |    14 +
 misc/cgo/errors/issue8442.go                       |    17 +
 misc/cgo/errors/test.bash                          |     2 +
 misc/cgo/test/backdoor/backdoor.go                 |     3 +-
 misc/cgo/test/backdoor/backdoor_gccgo.go           |    11 -
 misc/cgo/test/backdoor/runtime.c                   |    32 -
 misc/cgo/test/backdoor/thunk.s                     |    16 +
 misc/cgo/test/basic.go                             |     5 +
 misc/cgo/test/buildid_linux.go                     |    77 +
 misc/cgo/test/callback.go                          |    67 +-
 misc/cgo/test/callback_c.c                         |    16 +
 misc/cgo/test/callback_c_gc.c                      |    59 +
 misc/cgo/test/callback_c_gccgo.c                   |    53 +
 misc/cgo/test/cgo_linux_test.go                    |     5 +-
 misc/cgo/test/cgo_test.go                          |    97 +-
 misc/cgo/test/exports.go                           |     6 +
 misc/cgo/test/issue5242.go                         |    31 +
 misc/cgo/test/issue5548.go                         |     9 +-
 misc/cgo/test/issue6997_linux.go                   |     2 +-
 misc/cgo/test/issue7695_test.go                    |    27 -
 misc/cgo/test/issue7978.go                         |    10 +-
 misc/cgo/test/issue8092.go                         |    36 +
 misc/cgo/test/issue8428.go                         |    52 +
 misc/cgo/test/issue8517.go                         |    13 +
 misc/cgo/test/issue8517_windows.c                  |    24 +
 misc/cgo/test/issue8517_windows.go                 |    45 +
 misc/cgo/test/issue8694.go                         |    38 +
 misc/cgo/test/issue8811.c                          |     8 +
 misc/cgo/test/issue8811.go                         |    22 +
 misc/cgo/test/issue8828.go                         |    16 +
 misc/cgo/test/issue8828/issue8828.c                |     7 +
 misc/cgo/test/issue8828/trivial.go                 |     8 +
 misc/cgo/test/issue9026.go                         |     9 +
 misc/cgo/test/issue9026/issue9026.go               |    36 +
 misc/cgo/testcdefs/cdefstest.c                     |     1 +
 misc/cgo/testcdefs/cdefstest.go                    |    19 +
 misc/cgo/testcdefs/main.c                          |    28 +
 misc/cgo/testgodefs/anonunion.go                   |    26 +
 misc/cgo/testgodefs/issue8478.go                   |    20 +
 misc/cgo/testgodefs/main.go                        |    15 +
 misc/cgo/testgodefs/test.bash                      |    20 +
 misc/editors                                       |     5 +
 misc/emacs/go-mode-load.el                         |    96 -
 misc/emacs/go-mode.el                              |  1196 --
 misc/fraise/go.plist                               |    92 -
 misc/fraise/readme.txt                             |    16 -
 misc/kate/go.xml                                   |   150 -
 misc/makerelease/makerelease.go                    |    83 +-
 misc/makerelease/windows/installer.wxs             |    11 +-
 misc/nacl/README                                   |    97 +-
 misc/nacl/go_nacl_arm_exec                         |    10 +
 misc/nacl/mkzip.go                                 |    10 +-
 misc/nacl/testzip.proto                            |   164 +-
 misc/notepadplus/README                            |    59 -
 misc/notepadplus/functionList.xml                  |    50 -
 misc/notepadplus/go.xml                            |   133 -
 misc/notepadplus/userDefineLang.xml                |    64 -
 misc/pprof                                         |  5094 -------
 misc/vim/autoload/go/complete.vim                  |   103 -
 misc/vim/compiler/go.vim                           |    30 -
 misc/vim/ftdetect/gofiletype.vim                   |    23 -
 misc/vim/ftplugin/go.vim                           |    19 -
 misc/vim/ftplugin/go/fmt.vim                       |    69 -
 misc/vim/ftplugin/go/import.vim                    |   250 -
 misc/vim/ftplugin/go/test.sh                       |    78 -
 misc/vim/indent/go.vim                             |    77 -
 misc/vim/plugin/godoc.vim                          |   130 -
 misc/vim/readme.txt                                |   103 -
 misc/vim/syntax/go.vim                             |   207 -
 misc/vim/syntax/godoc.vim                          |    20 -
 misc/xcode/3/README                                |     3 -
 misc/xcode/3/go.pbfilespec                         |    31 -
 misc/xcode/3/go.xclangspec                         |   293 -
 misc/xcode/4/README                                |     2 -
 misc/xcode/4/go.xclangspec                         |   290 -
 misc/xcode/4/go4xcode.sh                           |   112 -
 misc/zsh/go                                        |   161 -
 src/androidtest.bash                               |    55 +
 src/{pkg => }/archive/tar/common.go                |     0
 src/{pkg => }/archive/tar/example_test.go          |     0
 src/archive/tar/reader.go                          |   820 ++
 src/{pkg => }/archive/tar/reader_test.go           |     0
 src/{pkg => }/archive/tar/stat_atim.go             |     0
 src/{pkg => }/archive/tar/stat_atimespec.go        |     0
 src/{pkg => }/archive/tar/stat_unix.go             |     0
 src/{pkg => }/archive/tar/tar_test.go              |     0
 src/{pkg => }/archive/tar/testdata/gnu.tar         |   Bin
 src/{pkg => }/archive/tar/testdata/nil-uid.tar     |   Bin
 src/{pkg => }/archive/tar/testdata/pax.tar         |   Bin
 src/{pkg => }/archive/tar/testdata/small.txt       |     0
 src/{pkg => }/archive/tar/testdata/small2.txt      |     0
 .../archive/tar/testdata/sparse-formats.tar        |   Bin
 src/{pkg => }/archive/tar/testdata/star.tar        |   Bin
 src/{pkg => }/archive/tar/testdata/ustar.tar       |   Bin
 src/{pkg => }/archive/tar/testdata/v7.tar          |   Bin
 .../archive/tar/testdata/writer-big-long.tar       |   Bin
 src/{pkg => }/archive/tar/testdata/writer-big.tar  |   Bin
 src/{pkg => }/archive/tar/testdata/writer.tar      |   Bin
 src/{pkg => }/archive/tar/testdata/xattrs.tar      |   Bin
 src/archive/tar/writer.go                          |   396 +
 src/archive/tar/writer_test.go                     |   491 +
 src/{pkg => }/archive/zip/example_test.go          |     0
 src/archive/zip/reader.go                          |   453 +
 src/archive/zip/reader_test.go                     |   533 +
 src/{pkg => }/archive/zip/register.go              |     0
 src/{pkg => }/archive/zip/struct.go                |     0
 .../archive/zip/testdata/crc32-not-streamed.zip    |   Bin
 src/{pkg => }/archive/zip/testdata/dd.zip          |   Bin
 .../archive/zip/testdata/go-no-datadesc-sig.zip    |   Bin
 .../archive/zip/testdata/go-with-datadesc-sig.zip  |   Bin
 .../archive/zip/testdata/gophercolor16x16.png      |   Bin
 src/{pkg => }/archive/zip/testdata/readme.notzip   |   Bin
 src/{pkg => }/archive/zip/testdata/readme.zip      |   Bin
 src/{pkg => }/archive/zip/testdata/symlink.zip     |   Bin
 .../archive/zip/testdata/test-trailing-junk.zip    |   Bin
 src/{pkg => }/archive/zip/testdata/test.zip        |   Bin
 src/{pkg => }/archive/zip/testdata/unix.zip        |   Bin
 src/{pkg => }/archive/zip/testdata/winxp.zip       |   Bin
 src/{pkg => }/archive/zip/testdata/zip64-2.zip     |   Bin
 src/{pkg => }/archive/zip/testdata/zip64.zip       |   Bin
 src/archive/zip/writer.go                          |   357 +
 src/archive/zip/writer_test.go                     |   164 +
 src/{pkg => }/archive/zip/zip_test.go              |     0
 src/bufio/bufio.go                                 |   698 +
 src/bufio/bufio_test.go                            |  1426 ++
 src/{pkg => }/bufio/example_test.go                |     0
 src/{pkg => }/bufio/export_test.go                 |     0
 src/bufio/scan.go                                  |   359 +
 src/bufio/scan_test.go                             |   524 +
 src/{pkg => }/builtin/builtin.go                   |     0
 src/{pkg => }/bytes/buffer.go                      |     0
 src/{pkg => }/bytes/buffer_test.go                 |     0
 src/bytes/bytes.go                                 |   703 +
 src/{pkg => }/bytes/bytes_decl.go                  |     0
 src/bytes/bytes_test.go                            |  1240 ++
 src/{pkg => }/bytes/compare_test.go                |     0
 src/{pkg => }/bytes/equal_test.go                  |     0
 src/{pkg => }/bytes/example_test.go                |     0
 src/{pkg => }/bytes/export_test.go                 |     0
 src/{pkg => }/bytes/reader.go                      |     0
 src/{pkg => }/bytes/reader_test.go                 |     0
 src/cmd/5a/a.y                                     |     2 +-
 src/cmd/5a/lex.c                                   |     5 +-
 src/cmd/5a/y.tab.c                                 |     2 +-
 src/cmd/5c/cgen.c                                  |    38 +-
 src/cmd/5c/gc.h                                    |     5 +-
 src/cmd/5c/peep.c                                  |     4 +
 src/cmd/5c/reg.c                                   |    19 +-
 src/cmd/5c/sgen.c                                  |     2 +-
 src/cmd/5c/swt.c                                   |    11 +-
 src/cmd/5c/txt.c                                   |    40 +-
 src/cmd/5g/cgen.c                                  |    81 +-
 src/cmd/5g/galign.c                                |     8 +-
 src/cmd/5g/gg.h                                    |    12 +-
 src/cmd/5g/ggen.c                                  |    25 +-
 src/cmd/5g/gsubr.c                                 |    27 +-
 src/cmd/5g/opt.h                                   |    20 +
 src/cmd/5g/peep.c                                  |     6 +
 src/cmd/5g/reg.c                                   |    12 +-
 src/cmd/5l/5.out.h                                 |   166 +-
 src/cmd/5l/asm.c                                   |    75 +-
 src/cmd/5l/l.h                                     |    76 -
 src/cmd/5l/mkenam                                  |    45 -
 src/cmd/5l/noop.c                                  |    43 -
 src/cmd/5l/obj.c                                   |    13 +-
 src/cmd/6a/a.y                                     |     2 +-
 src/cmd/6a/lex.c                                   |    35 +-
 src/cmd/6a/y.tab.c                                 |     2 +-
 src/cmd/6c/cgen.c                                  |    36 +-
 src/cmd/6c/gc.h                                    |     5 +-
 src/cmd/6c/reg.c                                   |    14 +-
 src/cmd/6c/sgen.c                                  |     9 +-
 src/cmd/6c/swt.c                                   |     9 +-
 src/cmd/6c/txt.c                                   |    40 +-
 src/cmd/6g/cgen.c                                  |    10 +-
 src/cmd/6g/galign.c                                |     8 +-
 src/cmd/6g/gg.h                                    |     2 -
 src/cmd/6g/ggen.c                                  |    61 +-
 src/cmd/6g/gsubr.c                                 |    29 +-
 src/cmd/6g/opt.h                                   |    20 +
 src/cmd/6g/reg.c                                   |     8 +-
 src/cmd/6l/6.out.h                                 |     2 +-
 src/cmd/6l/asm.c                                   |    17 +-
 src/cmd/6l/l.h                                     |    10 -
 src/cmd/6l/mkenam                                  |    45 -
 src/cmd/8a/a.y                                     |     2 +-
 src/cmd/8a/lex.c                                   |    35 +-
 src/cmd/8a/y.tab.c                                 |     2 +-
 src/cmd/8c/cgen.c                                  |    38 +-
 src/cmd/8c/gc.h                                    |     5 +-
 src/cmd/8c/reg.c                                   |     9 +-
 src/cmd/8c/sgen.c                                  |     2 +-
 src/cmd/8c/swt.c                                   |     9 +-
 src/cmd/8c/txt.c                                   |    40 +-
 src/cmd/8g/cgen.c                                  |    88 +-
 src/cmd/8g/galign.c                                |     8 +-
 src/cmd/8g/gg.h                                    |     1 -
 src/cmd/8g/ggen.c                                  |    49 +-
 src/cmd/8g/gsubr.c                                 |    26 +-
 src/cmd/8g/opt.h                                   |    20 +
 src/cmd/8g/peep.c                                  |     4 +-
 src/cmd/8g/reg.c                                   |     6 +
 src/cmd/8l/8.out.h                                 |     2 +-
 src/cmd/8l/asm.c                                   |    18 +-
 src/cmd/8l/l.h                                     |     7 -
 src/cmd/8l/mkenam                                  |    45 -
 src/cmd/addr2line/addr2line_test.go                |     5 +-
 src/cmd/addr2line/main.go                          |   166 +-
 src/cmd/api/goapi.go                               |   158 +-
 src/cmd/api/goapi_test.go                          |    24 +-
 src/cmd/api/run.go                                 |     9 +-
 src/cmd/cc/bv.c                                    |    45 -
 src/cmd/cc/cc.h                                    |     8 +-
 src/cmd/cc/cc.y                                    |     1 +
 src/cmd/cc/dcl.c                                   |    25 +-
 src/cmd/cc/godefs.c                                |    67 +-
 src/cmd/cc/lex.c                                   |     3 +
 src/cmd/cc/pgen.c                                  |   202 +-
 src/cmd/cc/y.tab.c                                 |  1147 +-
 src/cmd/cc/y.tab.h                                 |    68 +-
 src/cmd/cgo/ast.go                                 |     5 +-
 src/cmd/cgo/doc.go                                 |     2 +-
 src/cmd/cgo/gcc.go                                 |   187 +-
 src/cmd/cgo/out.go                                 |   243 +-
 src/cmd/dist/a.h                                   |     4 +-
 src/cmd/dist/arm.c                                 |     3 +-
 src/cmd/dist/buf.c                                 |     2 +-
 src/cmd/dist/build.c                               |   267 +-
 src/cmd/dist/buildgc.c                             |    38 +-
 src/cmd/dist/buildruntime.c                        |    84 +-
 src/cmd/dist/goc2c.c                               |   833 --
 src/cmd/dist/plan9.c                               |     6 +-
 src/cmd/dist/unix.c                                |    16 +-
 src/cmd/dist/windows.c                             |     6 +-
 src/cmd/fix/doc.go                                 |     2 +-
 src/cmd/fix/fix.go                                 |     2 +-
 src/cmd/gc/align.c                                 |     4 +-
 src/cmd/gc/bisonerrors                             |    18 +-
 src/cmd/gc/builtin.c                               |    33 +-
 src/cmd/gc/bv.c                                    |     5 +-
 src/cmd/gc/const.c                                 |     9 +-
 src/cmd/gc/dcl.c                                   |    14 +
 src/cmd/gc/esc.c                                   |     3 +-
 src/cmd/gc/fmt.c                                   |    36 +-
 src/cmd/gc/gen.c                                   |    75 +-
 src/cmd/gc/go.h                                    |    17 +-
 src/cmd/gc/go.y                                    |    15 +-
 src/cmd/gc/lex.c                                   |   363 +-
 src/cmd/gc/md5.c                                   |    12 +-
 src/cmd/gc/mparith1.c                              |     2 +-
 src/cmd/gc/mparith2.c                              |     4 +-
 src/cmd/gc/mparith3.c                              |     4 +-
 src/cmd/gc/obj.c                                   |     9 +-
 src/cmd/gc/order.c                                 |    48 +-
 src/cmd/gc/pgen.c                                  |    57 +-
 src/cmd/gc/plive.c                                 |    34 +-
 src/cmd/gc/popt.c                                  |     6 +-
 src/cmd/gc/racewalk.c                              |    26 +-
 src/cmd/gc/range.c                                 |    48 +-
 src/cmd/gc/reflect.c                               |   591 +-
 src/cmd/gc/runtime.go                              |    40 +-
 src/cmd/gc/select.c                                |    65 +-
 src/cmd/gc/sinit.c                                 |    32 +-
 src/cmd/gc/subr.c                                  |   193 +-
 src/cmd/gc/swt.c                                   |     1 +
 src/cmd/gc/typecheck.c                             |   122 +-
 src/cmd/gc/walk.c                                  |   543 +-
 src/cmd/gc/y.tab.c                                 |  2566 ++--
 src/cmd/gc/yerr.h                                  |    84 +-
 src/cmd/go/build.go                                |   226 +-
 src/cmd/go/doc.go                                  |   206 +-
 src/cmd/go/generate.go                             |   398 +
 src/cmd/go/generate_test.go                        |    48 +
 src/cmd/go/get.go                                  |    35 +-
 src/cmd/go/go_windows_test.go                      |    55 +
 src/cmd/go/help.go                                 |    29 +-
 src/cmd/go/list.go                                 |    39 +-
 src/cmd/go/main.go                                 |     5 +-
 src/cmd/go/mkdoc.sh                                |     2 +-
 src/cmd/go/pkg.go                                  |   180 +-
 src/cmd/go/test.bash                               |   405 +-
 src/cmd/go/test.go                                 |   178 +-
 src/cmd/go/testdata/generate/test1.go              |    13 +
 src/cmd/go/testdata/generate/test2.go              |    10 +
 src/cmd/go/testdata/generate/test3.go              |     9 +
 src/cmd/go/testdata/importcom/bad.go               |     3 +
 src/cmd/go/testdata/importcom/conflict.go          |     3 +
 src/cmd/go/testdata/importcom/src/bad/bad.go       |     1 +
 src/cmd/go/testdata/importcom/src/conflict/a.go    |     1 +
 src/cmd/go/testdata/importcom/src/conflict/b.go    |     1 +
 src/cmd/go/testdata/importcom/src/works/x/x.go     |     1 +
 src/cmd/go/testdata/importcom/src/works/x/x1.go    |     1 +
 src/cmd/go/testdata/importcom/src/wrongplace/x.go  |     1 +
 src/cmd/go/testdata/importcom/works.go             |     3 +
 src/cmd/go/testdata/importcom/wrongplace.go        |     3 +
 src/cmd/go/testdata/norunexample/example_test.go   |    11 +
 src/cmd/go/testdata/norunexample/test_test.go      |    10 +
 src/cmd/go/testdata/src/badc/x.c                   |     1 +
 src/cmd/go/testdata/src/badc/x.go                  |     1 +
 src/cmd/go/testdata/src/badtest/badexec/x_test.go  |     5 +
 src/cmd/go/testdata/src/badtest/badsyntax/x.go     |     1 +
 .../go/testdata/src/badtest/badsyntax/x_test.go    |     3 +
 src/cmd/go/testdata/src/badtest/badvar/x.go        |     1 +
 src/cmd/go/testdata/src/badtest/badvar/x_test.go   |     5 +
 src/cmd/go/testdata/src/vetpkg/a_test.go           |     1 +
 src/cmd/go/testdata/src/vetpkg/b.go                |     7 +
 src/cmd/go/testdata/testinternal/p.go              |     3 +
 src/cmd/go/testdata/testinternal2/p.go             |     3 +
 .../testdata/testinternal2/x/y/z/internal/w/w.go   |     1 +
 src/cmd/go/testflag.go                             |     7 +-
 src/cmd/go/testgo.go                               |    21 +
 src/cmd/go/tool.go                                 |    14 +-
 src/cmd/go/vcs.go                                  |   149 +-
 src/cmd/go/vcs_test.go                             |   124 +
 src/cmd/go/vet.go                                  |    25 +-
 src/cmd/gofmt/doc.go                               |     2 +-
 src/cmd/gofmt/gofmt.go                             |   193 +-
 src/cmd/gofmt/gofmt_test.go                        |   121 +-
 src/cmd/gofmt/long_test.go                         |     4 +-
 src/cmd/gofmt/rewrite.go                           |     3 -
 src/cmd/gofmt/simplify.go                          |    50 +-
 src/cmd/gofmt/testdata/composites.golden           |     2 +
 src/cmd/gofmt/testdata/composites.input            |     2 +
 src/cmd/gofmt/testdata/crlf.golden                 |     1 +
 src/cmd/gofmt/testdata/crlf.input                  |     1 +
 src/cmd/gofmt/testdata/emptydecl.golden            |    14 +
 src/cmd/gofmt/testdata/emptydecl.input             |    16 +
 src/cmd/gofmt/testdata/ranges.golden               |    30 +
 src/cmd/gofmt/testdata/ranges.input                |    20 +
 src/cmd/gofmt/testdata/rewrite1.golden             |     2 +
 src/cmd/gofmt/testdata/rewrite1.input              |     2 +
 src/cmd/gofmt/testdata/rewrite2.golden             |     2 +
 src/cmd/gofmt/testdata/rewrite2.input              |     2 +
 src/cmd/gofmt/testdata/rewrite3.golden             |     2 +
 src/cmd/gofmt/testdata/rewrite3.input              |     2 +
 src/cmd/gofmt/testdata/rewrite4.golden             |     2 +
 src/cmd/gofmt/testdata/rewrite4.input              |     2 +
 src/cmd/gofmt/testdata/rewrite5.golden             |     2 +
 src/cmd/gofmt/testdata/rewrite5.input              |     2 +
 src/cmd/gofmt/testdata/rewrite6.golden             |     2 +
 src/cmd/gofmt/testdata/rewrite6.input              |     2 +
 src/cmd/gofmt/testdata/rewrite7.golden             |     2 +
 src/cmd/gofmt/testdata/rewrite7.input              |     2 +
 src/cmd/gofmt/testdata/rewrite8.golden             |     2 +
 src/cmd/gofmt/testdata/rewrite8.input              |     2 +
 src/cmd/gofmt/testdata/slices1.golden              |     8 +
 src/cmd/gofmt/testdata/slices1.input               |     8 +
 src/cmd/gofmt/testdata/slices2.golden              |     2 +
 src/cmd/gofmt/testdata/slices2.input               |     2 +
 src/cmd/gofmt/testdata/stdin1.golden               |     2 +
 src/cmd/gofmt/testdata/stdin1.golden.gofmt         |     3 -
 src/cmd/gofmt/testdata/stdin1.input                |     2 +
 src/cmd/gofmt/testdata/stdin1.input.gofmt          |     3 -
 src/cmd/gofmt/testdata/stdin2.golden               |     2 +-
 src/cmd/gofmt/testdata/stdin2.golden.gofmt         |    10 -
 src/cmd/gofmt/testdata/stdin2.input                |     2 +-
 src/cmd/gofmt/testdata/stdin2.input.gofmt          |    11 -
 src/cmd/gofmt/testdata/stdin3.golden               |     1 +
 src/cmd/gofmt/testdata/stdin3.golden.gofmt         |     7 -
 src/cmd/gofmt/testdata/stdin3.input                |     1 +
 src/cmd/gofmt/testdata/stdin3.input.gofmt          |     7 -
 src/cmd/gofmt/testdata/stdin4.golden               |     2 +
 src/cmd/gofmt/testdata/stdin4.golden.gofmt         |     3 -
 src/cmd/gofmt/testdata/stdin4.input                |     2 +
 src/cmd/gofmt/testdata/stdin4.input.gofmt          |     3 -
 src/cmd/gofmt/testdata/stdin5.golden               |     3 +
 src/cmd/gofmt/testdata/stdin5.input                |     3 +
 src/cmd/gofmt/testdata/stdin6.golden               |    19 +
 src/cmd/gofmt/testdata/stdin6.input                |    21 +
 src/cmd/gofmt/testdata/stdin7.golden               |    19 +
 src/cmd/gofmt/testdata/stdin7.input                |    21 +
 src/cmd/internal/goobj/read.go                     |   666 +
 src/cmd/internal/goobj/read_test.go                |    28 +
 src/cmd/internal/objfile/disasm.go                 |   248 +
 src/cmd/internal/objfile/elf.go                    |   104 +
 src/cmd/internal/objfile/goobj.go                  |    93 +
 src/cmd/internal/objfile/macho.go                  |   116 +
 src/cmd/internal/objfile/objfile.go                |    94 +
 src/cmd/internal/objfile/pe.go                     |   201 +
 src/cmd/internal/objfile/plan9obj.go               |   146 +
 src/cmd/internal/rsc.io/arm/armasm/Makefile        |     2 +
 src/cmd/internal/rsc.io/arm/armasm/decode.go       |   567 +
 src/cmd/internal/rsc.io/arm/armasm/decode_test.go  |    69 +
 src/cmd/internal/rsc.io/arm/armasm/ext_test.go     |   614 +
 src/cmd/internal/rsc.io/arm/armasm/gnu.go          |   164 +
 src/cmd/internal/rsc.io/arm/armasm/inst.go         |   438 +
 src/cmd/internal/rsc.io/arm/armasm/objdump_test.go |   258 +
 .../internal/rsc.io/arm/armasm/objdumpext_test.go  |   260 +
 src/cmd/internal/rsc.io/arm/armasm/plan9x.go       |   211 +
 src/cmd/internal/rsc.io/arm/armasm/tables.go       |  9448 +++++++++++++
 .../internal/rsc.io/arm/armasm/testdata/Makefile   |     5 +
 .../internal/rsc.io/arm/armasm/testdata/decode.txt |   306 +
 src/cmd/internal/rsc.io/x86/x86asm/Makefile        |     3 +
 src/cmd/internal/rsc.io/x86/x86asm/decode.go       |  1616 +++
 src/cmd/internal/rsc.io/x86/x86asm/decode_test.go  |    71 +
 src/cmd/internal/rsc.io/x86/x86asm/ext_test.go     |   811 ++
 src/cmd/internal/rsc.io/x86/x86asm/gnu.go          |   926 ++
 src/cmd/internal/rsc.io/x86/x86asm/inst.go         |   641 +
 src/cmd/internal/rsc.io/x86/x86asm/inst_test.go    |    20 +
 src/cmd/internal/rsc.io/x86/x86asm/intel.go        |   518 +
 src/cmd/internal/rsc.io/x86/x86asm/objdump_test.go |   383 +
 .../internal/rsc.io/x86/x86asm/objdumpext_test.go  |   314 +
 .../internal/rsc.io/x86/x86asm/plan9ext_test.go    |   120 +
 src/cmd/internal/rsc.io/x86/x86asm/plan9x.go       |   346 +
 src/cmd/internal/rsc.io/x86/x86asm/plan9x_test.go  |    54 +
 src/cmd/internal/rsc.io/x86/x86asm/tables.go       |  9760 +++++++++++++
 .../internal/rsc.io/x86/x86asm/testdata/Makefile   |    12 +
 .../internal/rsc.io/x86/x86asm/testdata/decode.txt |  6731 +++++++++
 src/cmd/internal/rsc.io/x86/x86asm/xed_test.go     |   211 +
 src/cmd/internal/rsc.io/x86/x86asm/xedext_test.go  |   206 +
 src/cmd/ld/data.c                                  |   357 +-
 src/cmd/ld/decodesym.c                             |    38 +-
 src/cmd/ld/doc.go                                  |     6 +-
 src/cmd/ld/dwarf.c                                 |   156 +-
 src/cmd/ld/elf.c                                   |     3 +-
 src/cmd/ld/ldelf.c                                 |     8 +-
 src/cmd/ld/ldmacho.c                               |     4 +-
 src/cmd/ld/ldpe.c                                  |    32 +-
 src/cmd/ld/lib.c                                   |    91 +-
 src/cmd/ld/lib.h                                   |    14 +-
 src/cmd/ld/macho.c                                 |     3 +-
 src/cmd/ld/pass.c                                  |   104 -
 src/cmd/ld/pcln.c                                  |     6 +-
 src/cmd/ld/pobj.c                                  |    22 +-
 src/cmd/ld/symtab.c                                |    55 +-
 src/cmd/ld/textflag.h                              |    13 +
 src/cmd/nm/debug_goobj.go                          |   670 -
 src/cmd/nm/elf.go                                  |    57 -
 src/cmd/nm/goobj.go                                |    67 -
 src/cmd/nm/macho.go                                |    69 -
 src/cmd/nm/nm.go                                   |    57 +-
 src/cmd/nm/nm_test.go                              |    11 +-
 src/cmd/nm/pe.go                                   |    98 -
 src/cmd/nm/plan9obj.go                             |    48 -
 src/cmd/objdump/Makefile                           |    10 -
 src/cmd/objdump/armasm.go                          | 10821 ---------------
 src/cmd/objdump/elf.go                             |    65 -
 src/cmd/objdump/macho.go                           |    77 -
 src/cmd/objdump/main.go                            |   456 +-
 src/cmd/objdump/objdump_test.go                    |   122 +-
 src/cmd/objdump/pe.go                              |    99 -
 src/cmd/objdump/plan9obj.go                        |    63 -
 src/cmd/objdump/x86.go                             | 13800 -------------------
 src/cmd/pack/doc.go                                |     4 +
 src/cmd/pack/pack.go                               |    50 +-
 src/cmd/pack/pack_test.go                          |    33 +-
 src/cmd/pprof/README                               |     8 +
 src/cmd/pprof/doc.go                               |    12 +
 src/cmd/pprof/internal/commands/commands.go        |   215 +
 src/cmd/pprof/internal/driver/driver.go            |  1036 ++
 src/cmd/pprof/internal/driver/interactive.go       |   492 +
 src/cmd/pprof/internal/fetch/fetch.go              |    82 +
 src/cmd/pprof/internal/plugin/plugin.go            |   213 +
 src/cmd/pprof/internal/profile/encode.go           |   470 +
 src/cmd/pprof/internal/profile/filter.go           |   157 +
 src/cmd/pprof/internal/profile/legacy_profile.go   |  1250 ++
 src/cmd/pprof/internal/profile/profile.go          |   567 +
 src/cmd/pprof/internal/profile/proto.go            |   298 +
 src/cmd/pprof/internal/profile/prune.go            |    97 +
 src/cmd/pprof/internal/report/report.go            |  1718 +++
 src/cmd/pprof/internal/report/source.go            |   450 +
 src/cmd/pprof/internal/report/source_html.go       |    77 +
 src/cmd/pprof/internal/svg/svg.go                  |    75 +
 src/cmd/pprof/internal/symbolizer/symbolizer.go    |   195 +
 src/cmd/pprof/internal/symbolz/symbolz.go          |   111 +
 src/cmd/pprof/internal/tempfile/tempfile.go        |    45 +
 src/cmd/pprof/pprof.go                             |   237 +
 src/cmd/yacc/Makefile                              |    12 -
 src/cmd/yacc/doc.go                                |     5 +-
 src/cmd/yacc/expr.y                                |   205 -
 src/cmd/yacc/testdata/expr/README                  |    20 +
 src/cmd/yacc/testdata/expr/expr.y                  |   202 +
 src/cmd/yacc/testdata/expr/main.go                 |    15 +
 src/cmd/yacc/yacc.go                               |    90 +-
 src/{pkg => }/compress/bzip2/bit_reader.go         |     0
 src/compress/bzip2/bzip2.go                        |   503 +
 src/compress/bzip2/bzip2_test.go                   |   419 +
 src/{pkg => }/compress/bzip2/huffman.go            |     0
 src/compress/bzip2/move_to_front.go                |    53 +
 .../bzip2/testdata/Mark.Twain-Tom.Sawyer.txt.bz2   |   Bin
 src/{pkg => }/compress/bzip2/testdata/e.txt.bz2    |   Bin
 src/{pkg => }/compress/flate/copy.go               |     0
 src/{pkg => }/compress/flate/copy_test.go          |     0
 src/{pkg => }/compress/flate/deflate.go            |     0
 src/{pkg => }/compress/flate/deflate_test.go       |     0
 src/compress/flate/fixedhuff.go                    |    78 +
 src/{pkg => }/compress/flate/flate_test.go         |     0
 src/compress/flate/gen.go                          |   190 +
 src/{pkg => }/compress/flate/huffman_bit_writer.go |     0
 src/{pkg => }/compress/flate/huffman_code.go       |     0
 src/compress/flate/inflate.go                      |   739 +
 src/compress/flate/inflate_test.go                 |    39 +
 src/{pkg => }/compress/flate/reader_test.go        |     0
 src/{pkg => }/compress/flate/reverse_bits.go       |     0
 src/{pkg => }/compress/flate/token.go              |     0
 src/{pkg => }/compress/flate/writer_test.go        |     0
 src/compress/gzip/gunzip.go                        |   287 +
 src/compress/gzip/gunzip_test.go                   |   410 +
 src/{pkg => }/compress/gzip/gzip.go                |     0
 src/{pkg => }/compress/gzip/gzip_test.go           |     0
 src/{pkg => }/compress/gzip/testdata/issue6550.gz  |   Bin
 src/compress/lzw/reader.go                         |   259 +
 src/{pkg => }/compress/lzw/reader_test.go          |     0
 src/{pkg => }/compress/lzw/writer.go               |     0
 src/{pkg => }/compress/lzw/writer_test.go          |     0
 .../compress/testdata/Mark.Twain-Tom.Sawyer.txt    |     0
 src/{pkg => }/compress/testdata/e.txt              |     0
 src/{pkg => }/compress/testdata/pi.txt             |     0
 src/{pkg => }/compress/zlib/example_test.go        |     0
 src/compress/zlib/reader.go                        |   161 +
 src/{pkg => }/compress/zlib/reader_test.go         |     0
 src/{pkg => }/compress/zlib/writer.go              |     0
 src/{pkg => }/compress/zlib/writer_test.go         |     0
 .../container/heap/example_intheap_test.go         |     0
 src/{pkg => }/container/heap/example_pq_test.go    |     0
 src/{pkg => }/container/heap/heap.go               |     0
 src/{pkg => }/container/heap/heap_test.go          |     0
 src/{pkg => }/container/list/example_test.go       |     0
 src/{pkg => }/container/list/list.go               |     0
 src/{pkg => }/container/list/list_test.go          |     0
 src/{pkg => }/container/ring/ring.go               |     0
 src/{pkg => }/container/ring/ring_test.go          |     0
 src/{pkg => }/crypto/aes/aes_test.go               |     0
 src/crypto/aes/asm_amd64.s                         |   289 +
 src/{pkg => }/crypto/aes/block.go                  |     0
 src/{pkg => }/crypto/aes/cipher.go                 |     0
 src/{pkg => }/crypto/aes/cipher_asm.go             |     0
 src/{pkg => }/crypto/aes/cipher_generic.go         |     0
 src/{pkg => }/crypto/aes/const.go                  |     0
 src/{pkg => }/crypto/cipher/benchmark_test.go      |     0
 src/{pkg => }/crypto/cipher/cbc.go                 |     0
 src/{pkg => }/crypto/cipher/cbc_aes_test.go        |     0
 src/{pkg => }/crypto/cipher/cfb.go                 |     0
 src/crypto/cipher/cfb_test.go                      |   113 +
 src/{pkg => }/crypto/cipher/cipher.go              |     0
 src/{pkg => }/crypto/cipher/cipher_test.go         |     0
 src/{pkg => }/crypto/cipher/common_test.go         |     0
 src/{pkg => }/crypto/cipher/ctr.go                 |     0
 src/{pkg => }/crypto/cipher/ctr_aes_test.go        |     0
 src/crypto/cipher/example_test.go                  |   283 +
 src/{pkg => }/crypto/cipher/gcm.go                 |     0
 src/{pkg => }/crypto/cipher/gcm_test.go            |     0
 src/{pkg => }/crypto/cipher/io.go                  |     0
 src/{pkg => }/crypto/cipher/ofb.go                 |     0
 src/{pkg => }/crypto/cipher/ofb_test.go            |     0
 src/{pkg => }/crypto/cipher/xor.go                 |     0
 src/{pkg => }/crypto/cipher/xor_test.go            |     0
 src/crypto/crypto.go                               |   126 +
 src/{pkg => }/crypto/des/block.go                  |     0
 src/{pkg => }/crypto/des/cipher.go                 |     0
 src/{pkg => }/crypto/des/const.go                  |     0
 src/{pkg => }/crypto/des/des_test.go               |     0
 src/{pkg => }/crypto/des/example_test.go           |     0
 src/{pkg => }/crypto/dsa/dsa.go                    |     0
 src/{pkg => }/crypto/dsa/dsa_test.go               |     0
 src/crypto/ecdsa/ecdsa.go                          |   189 +
 src/{pkg => }/crypto/ecdsa/ecdsa_test.go           |     0
 src/{pkg => }/crypto/ecdsa/testdata/SigVer.rsp.bz2 |   Bin
 src/{pkg => }/crypto/elliptic/elliptic.go          |     0
 src/{pkg => }/crypto/elliptic/elliptic_test.go     |     0
 src/{pkg => }/crypto/elliptic/p224.go              |     0
 src/{pkg => }/crypto/elliptic/p224_test.go         |     0
 src/{pkg => }/crypto/elliptic/p256.go              |     0
 src/{pkg => }/crypto/hmac/hmac.go                  |     0
 src/{pkg => }/crypto/hmac/hmac_test.go             |     0
 src/{pkg => }/crypto/md5/example_test.go           |     0
 src/crypto/md5/gen.go                              |   331 +
 src/crypto/md5/md5.go                              |   136 +
 src/{pkg => }/crypto/md5/md5_test.go               |     0
 src/crypto/md5/md5block.go                         |   265 +
 src/crypto/md5/md5block_386.s                      |   182 +
 src/crypto/md5/md5block_amd64.s                    |   179 +
 src/crypto/md5/md5block_amd64p32.s                 |   184 +
 src/crypto/md5/md5block_arm.s                      |   299 +
 src/{pkg => }/crypto/md5/md5block_decl.go          |     0
 src/{pkg => }/crypto/md5/md5block_generic.go       |     0
 src/{pkg => }/crypto/rand/example_test.go          |     0
 src/{pkg => }/crypto/rand/rand.go                  |     0
 src/crypto/rand/rand_linux.go                      |    39 +
 src/{pkg => }/crypto/rand/rand_test.go             |     0
 src/crypto/rand/rand_unix.go                       |   147 +
 src/{pkg => }/crypto/rand/rand_windows.go          |     0
 src/{pkg => }/crypto/rand/util.go                  |     0
 src/{pkg => }/crypto/rand/util_test.go             |     0
 src/{pkg => }/crypto/rc4/rc4.go                    |     0
 src/crypto/rc4/rc4_386.s                           |    53 +
 src/crypto/rc4/rc4_amd64.s                         |   179 +
 src/crypto/rc4/rc4_amd64p32.s                      |   192 +
 src/crypto/rc4/rc4_arm.s                           |    62 +
 src/crypto/rc4/rc4_asm.go                          |    18 +
 src/crypto/rc4/rc4_ref.go                          |    13 +
 src/{pkg => }/crypto/rc4/rc4_test.go               |     0
 src/{pkg => }/crypto/rsa/pkcs1v15.go               |     0
 src/{pkg => }/crypto/rsa/pkcs1v15_test.go          |     0
 src/crypto/rsa/pss.go                              |   297 +
 src/{pkg => }/crypto/rsa/pss_test.go               |     0
 src/crypto/rsa/rsa.go                              |   557 +
 src/{pkg => }/crypto/rsa/rsa_test.go               |     0
 src/{pkg => }/crypto/rsa/testdata/pss-vect.txt.bz2 |   Bin
 src/{pkg => }/crypto/sha1/example_test.go          |     0
 src/{pkg => }/crypto/sha1/sha1.go                  |     0
 src/{pkg => }/crypto/sha1/sha1_test.go             |     0
 src/{pkg => }/crypto/sha1/sha1block.go             |     0
 src/crypto/sha1/sha1block_386.s                    |   233 +
 src/crypto/sha1/sha1block_amd64.s                  |   216 +
 src/crypto/sha1/sha1block_amd64p32.s               |   216 +
 src/crypto/sha1/sha1block_arm.s                    |   217 +
 src/{pkg => }/crypto/sha1/sha1block_decl.go        |     0
 src/{pkg => }/crypto/sha1/sha1block_generic.go     |     0
 src/{pkg => }/crypto/sha256/sha256.go              |     0
 src/{pkg => }/crypto/sha256/sha256_test.go         |     0
 src/{pkg => }/crypto/sha256/sha256block.go         |     0
 src/{pkg => }/crypto/sha256/sha256block_386.s      |     0
 src/crypto/sha256/sha256block_amd64.s              |   256 +
 src/{pkg => }/crypto/sha256/sha256block_decl.go    |     0
 src/{pkg => }/crypto/sha512/sha512.go              |     0
 src/{pkg => }/crypto/sha512/sha512_test.go         |     0
 src/{pkg => }/crypto/sha512/sha512block.go         |     0
 src/crypto/sha512/sha512block_amd64.s              |   273 +
 src/{pkg => }/crypto/sha512/sha512block_decl.go    |     0
 src/crypto/subtle/constant_time.go                 |    73 +
 src/crypto/subtle/constant_time_test.go            |   127 +
 src/crypto/tls/alert.go                            |    79 +
 src/crypto/tls/cipher_suites.go                    |   275 +
 src/crypto/tls/common.go                           |   621 +
 src/crypto/tls/conn.go                             |  1030 ++
 src/crypto/tls/conn_test.go                        |   118 +
 src/{pkg => }/crypto/tls/example_test.go           |     0
 src/crypto/tls/generate_cert.go                    |   161 +
 src/crypto/tls/handshake_client.go                 |   638 +
 src/crypto/tls/handshake_client_test.go            |   490 +
 src/crypto/tls/handshake_messages.go               |  1438 ++
 src/crypto/tls/handshake_messages_test.go          |   251 +
 src/crypto/tls/handshake_server.go                 |   685 +
 src/crypto/tls/handshake_server_test.go            |   868 ++
 src/{pkg => }/crypto/tls/handshake_test.go         |     0
 src/crypto/tls/key_agreement.go                    |   413 +
 src/{pkg => }/crypto/tls/prf.go                    |     0
 src/{pkg => }/crypto/tls/prf_test.go               |     0
 .../testdata/Client-TLSv10-ClientCert-ECDSA-ECDSA  |     0
 .../testdata/Client-TLSv10-ClientCert-ECDSA-RSA    |     0
 .../testdata/Client-TLSv10-ClientCert-RSA-ECDSA    |     0
 .../tls/testdata/Client-TLSv10-ClientCert-RSA-RSA  |     0
 .../tls/testdata/Client-TLSv10-ECDHE-ECDSA-AES     |     0
 .../tls/testdata/Client-TLSv10-ECDHE-RSA-AES       |     0
 .../crypto/tls/testdata/Client-TLSv10-RSA-RC4      |     0
 .../tls/testdata/Client-TLSv11-ECDHE-ECDSA-AES     |     0
 .../tls/testdata/Client-TLSv11-ECDHE-RSA-AES       |     0
 .../crypto/tls/testdata/Client-TLSv11-RSA-RC4      |     0
 src/crypto/tls/testdata/Client-TLSv12-ALPN         |    97 +
 src/crypto/tls/testdata/Client-TLSv12-ALPN-NoMatch |    95 +
 .../testdata/Client-TLSv12-ClientCert-ECDSA-ECDSA  |     0
 .../testdata/Client-TLSv12-ClientCert-ECDSA-RSA    |     0
 .../testdata/Client-TLSv12-ClientCert-RSA-ECDSA    |     0
 .../tls/testdata/Client-TLSv12-ClientCert-RSA-RSA  |     0
 .../tls/testdata/Client-TLSv12-ECDHE-ECDSA-AES     |     0
 .../tls/testdata/Client-TLSv12-ECDHE-ECDSA-AES-GCM |     0
 .../tls/testdata/Client-TLSv12-ECDHE-RSA-AES       |     0
 .../crypto/tls/testdata/Client-TLSv12-RSA-RC4      |     0
 .../crypto/tls/testdata/Server-SSLv3-RSA-3DES      |     0
 .../crypto/tls/testdata/Server-SSLv3-RSA-AES       |     0
 .../crypto/tls/testdata/Server-SSLv3-RSA-RC4       |     0
 .../tls/testdata/Server-TLSv10-ECDHE-ECDSA-AES     |     0
 .../crypto/tls/testdata/Server-TLSv10-RSA-3DES     |     0
 .../crypto/tls/testdata/Server-TLSv10-RSA-AES      |     0
 .../crypto/tls/testdata/Server-TLSv10-RSA-RC4      |     0
 src/crypto/tls/testdata/Server-TLSv11-FallbackSCSV |    17 +
 .../crypto/tls/testdata/Server-TLSv11-RSA-RC4      |     0
 src/crypto/tls/testdata/Server-TLSv12-ALPN         |   122 +
 src/crypto/tls/testdata/Server-TLSv12-ALPN-NoMatch |   121 +
 .../Server-TLSv12-CipherSuiteCertPreferenceECDSA   |     0
 .../Server-TLSv12-CipherSuiteCertPreferenceRSA     |     0
 .../Server-TLSv12-ClientAuthRequestedAndECDSAGiven |     0
 .../Server-TLSv12-ClientAuthRequestedAndGiven      |     0
 .../Server-TLSv12-ClientAuthRequestedNotGiven      |     0
 .../tls/testdata/Server-TLSv12-ECDHE-ECDSA-AES     |     0
 .../crypto/tls/testdata/Server-TLSv12-IssueTicket  |     0
 .../testdata/Server-TLSv12-IssueTicketPreDisable   |     0
 .../crypto/tls/testdata/Server-TLSv12-RSA-3DES     |     0
 .../crypto/tls/testdata/Server-TLSv12-RSA-AES      |     0
 .../crypto/tls/testdata/Server-TLSv12-RSA-AES-GCM  |     0
 .../crypto/tls/testdata/Server-TLSv12-RSA-RC4      |     0
 .../crypto/tls/testdata/Server-TLSv12-Resume       |     0
 .../tls/testdata/Server-TLSv12-ResumeDisabled      |     0
 .../crypto/tls/testdata/Server-TLSv12-SNI          |     0
 src/{pkg => }/crypto/tls/ticket.go                 |     0
 src/{pkg => }/crypto/tls/tls.go                    |     0
 src/crypto/tls/tls_test.go                         |   282 +
 src/{pkg => }/crypto/x509/cert_pool.go             |     0
 src/{pkg => }/crypto/x509/example_test.go          |     0
 src/{pkg => }/crypto/x509/pem_decrypt.go           |     0
 src/crypto/x509/pem_decrypt_test.go                |   223 +
 src/{pkg => }/crypto/x509/pkcs1.go                 |     0
 src/{pkg => }/crypto/x509/pkcs8.go                 |     0
 src/{pkg => }/crypto/x509/pkcs8_test.go            |     0
 src/crypto/x509/pkix/pkix.go                       |   178 +
 src/{pkg => }/crypto/x509/root.go                  |     0
 src/{pkg => }/crypto/x509/root_cgo_darwin.go       |     0
 src/{pkg => }/crypto/x509/root_darwin.go           |     0
 src/{pkg => }/crypto/x509/root_darwin_test.go      |     0
 src/{pkg => }/crypto/x509/root_nocgo_darwin.go     |     0
 src/{pkg => }/crypto/x509/root_plan9.go            |     0
 src/crypto/x509/root_unix.go                       |    64 +
 src/{pkg => }/crypto/x509/root_windows.go          |     0
 src/{pkg => }/crypto/x509/sec1.go                  |     0
 src/{pkg => }/crypto/x509/sec1_test.go             |     0
 src/crypto/x509/verify.go                          |   476 +
 src/{pkg => }/crypto/x509/verify_test.go           |     0
 src/crypto/x509/x509.go                            |  1916 +++
 src/crypto/x509/x509_test.go                       |  1027 ++
 src/{pkg => }/crypto/x509/x509_test_import.go      |     0
 src/{pkg => }/database/sql/convert.go              |     0
 src/database/sql/convert_test.go                   |   348 +
 src/{pkg => }/database/sql/doc.txt                 |     0
 src/{pkg => }/database/sql/driver/driver.go        |     0
 src/{pkg => }/database/sql/driver/types.go         |     0
 src/{pkg => }/database/sql/driver/types_test.go    |     0
 src/{pkg => }/database/sql/example_test.go         |     0
 src/database/sql/fakedb_test.go                    |   829 ++
 src/database/sql/sql.go                            |  1770 +++
 src/database/sql/sql_test.go                       |  1987 +++
 src/{pkg => }/debug/dwarf/buf.go                   |     0
 src/{pkg => }/debug/dwarf/const.go                 |     0
 src/{pkg => }/debug/dwarf/entry.go                 |     0
 src/{pkg => }/debug/dwarf/open.go                  |     0
 src/{pkg => }/debug/dwarf/testdata/typedef.c       |     0
 src/{pkg => }/debug/dwarf/testdata/typedef.elf     |   Bin
 src/{pkg => }/debug/dwarf/testdata/typedef.elf4    |   Bin
 src/{pkg => }/debug/dwarf/testdata/typedef.macho   |   Bin
 src/debug/dwarf/type.go                            |   696 +
 src/{pkg => }/debug/dwarf/type_test.go             |     0
 src/{pkg => }/debug/dwarf/typeunit.go              |     0
 src/{pkg => }/debug/dwarf/unit.go                  |     0
 src/debug/elf/elf.go                               |  1773 +++
 src/{pkg => }/debug/elf/elf_test.go                |     0
 src/debug/elf/file.go                              |   953 ++
 src/debug/elf/file_test.go                         |   345 +
 src/debug/elf/symbols_test.go                      |   834 ++
 .../debug/elf/testdata/gcc-386-freebsd-exec        |   Bin
 .../debug/elf/testdata/gcc-amd64-linux-exec        |   Bin
 .../testdata/gcc-amd64-openbsd-debug-with-rela.obj |   Bin
 .../elf/testdata/go-relocation-test-clang-x86.obj  |   Bin
 .../testdata/go-relocation-test-gcc424-x86-64.obj  |   Bin
 .../testdata/go-relocation-test-gcc441-x86-64.obj  |   Bin
 .../elf/testdata/go-relocation-test-gcc441-x86.obj |   Bin
 .../testdata/go-relocation-test-gcc482-aarch64.obj |   Bin 0 -> 3392 bytes
 .../debug/elf/testdata/hello-world-core.gz         |   Bin
 src/{pkg => }/debug/elf/testdata/hello.c           |     0
 src/{pkg => }/debug/gosym/pclinetest.asm           |     0
 src/{pkg => }/debug/gosym/pclinetest.h             |     0
 src/{pkg => }/debug/gosym/pclntab.go               |     0
 src/{pkg => }/debug/gosym/pclntab_test.go          |     0
 src/debug/gosym/symtab.go                          |   710 +
 src/{pkg => }/debug/macho/fat.go                   |     0
 src/{pkg => }/debug/macho/file.go                  |     0
 src/{pkg => }/debug/macho/file_test.go             |     0
 src/{pkg => }/debug/macho/macho.go                 |     0
 .../macho/testdata/fat-gcc-386-amd64-darwin-exec   |   Bin
 .../debug/macho/testdata/gcc-386-darwin-exec       |   Bin
 .../debug/macho/testdata/gcc-amd64-darwin-exec     |   Bin
 .../macho/testdata/gcc-amd64-darwin-exec-debug     |   Bin
 src/{pkg => }/debug/macho/testdata/hello.c         |     0
 src/debug/pe/file.go                               |   394 +
 src/debug/pe/file_test.go                          |   243 +
 src/{pkg => }/debug/pe/pe.go                       |     0
 src/{pkg => }/debug/pe/testdata/gcc-386-mingw-exec |   Bin
 src/{pkg => }/debug/pe/testdata/gcc-386-mingw-obj  |   Bin
 src/debug/pe/testdata/gcc-amd64-mingw-exec         |   Bin 0 -> 273083 bytes
 .../debug/pe/testdata/gcc-amd64-mingw-obj          |   Bin
 src/{pkg => }/debug/pe/testdata/hello.c            |     0
 src/debug/plan9obj/file.go                         |   328 +
 src/debug/plan9obj/file_test.go                    |    81 +
 src/{pkg => }/debug/plan9obj/plan9obj.go           |     0
 .../debug/plan9obj/testdata/386-plan9-exec         |   Bin
 .../debug/plan9obj/testdata/amd64-plan9-exec       |   Bin
 src/{pkg => }/debug/plan9obj/testdata/hello.c      |     0
 src/encoding/ascii85/ascii85.go                    |   310 +
 src/{pkg => }/encoding/ascii85/ascii85_test.go     |     0
 src/encoding/asn1/asn1.go                          |   922 ++
 src/encoding/asn1/asn1_test.go                     |   867 ++
 src/{pkg => }/encoding/asn1/common.go              |     0
 src/encoding/asn1/marshal.go                       |   646 +
 src/encoding/asn1/marshal_test.go                  |   164 +
 src/encoding/base32/base32.go                      |   426 +
 src/encoding/base32/base32_test.go                 |   302 +
 src/{pkg => }/encoding/base32/example_test.go      |     0
 src/encoding/base64/base64.go                      |   391 +
 src/encoding/base64/base64_test.go                 |   360 +
 src/{pkg => }/encoding/base64/example_test.go      |     0
 src/encoding/binary/binary.go                      |   634 +
 src/encoding/binary/binary_test.go                 |   416 +
 src/{pkg => }/encoding/binary/example_test.go      |     0
 src/{pkg => }/encoding/binary/varint.go            |     0
 src/{pkg => }/encoding/binary/varint_test.go       |     0
 src/{pkg => }/encoding/csv/reader.go               |     0
 src/{pkg => }/encoding/csv/reader_test.go          |     0
 src/encoding/csv/writer.go                         |   139 +
 src/encoding/csv/writer_test.go                    |    85 +
 src/{pkg => }/encoding/encoding.go                 |     0
 src/encoding/gob/codec_test.go                     |  1475 ++
 src/encoding/gob/debug.go                          |   705 +
 src/encoding/gob/dec_helpers.go                    |   468 +
 src/encoding/gob/decgen.go                         |   240 +
 src/encoding/gob/decode.go                         |  1217 ++
 src/encoding/gob/decoder.go                        |   218 +
 src/{pkg => }/encoding/gob/doc.go                  |     0
 src/{pkg => }/encoding/gob/dump.go                 |     0
 src/encoding/gob/enc_helpers.go                    |   414 +
 src/encoding/gob/encgen.go                         |   218 +
 src/encoding/gob/encode.go                         |   696 +
 src/encoding/gob/encoder.go                        |   248 +
 src/encoding/gob/encoder_test.go                   |   956 ++
 src/{pkg => }/encoding/gob/error.go                |     0
 src/{pkg => }/encoding/gob/example_encdec_test.go  |     0
 .../encoding/gob/example_interface_test.go         |     0
 src/{pkg => }/encoding/gob/example_test.go         |     0
 src/encoding/gob/gobencdec_test.go                 |   798 ++
 src/encoding/gob/timing_test.go                    |   325 +
 src/encoding/gob/type.go                           |   923 ++
 src/{pkg => }/encoding/gob/type_test.go            |     0
 src/{pkg => }/encoding/hex/hex.go                  |     0
 src/{pkg => }/encoding/hex/hex_test.go             |     0
 src/{pkg => }/encoding/json/bench_test.go          |     0
 src/encoding/json/decode.go                        |  1084 ++
 src/encoding/json/decode_test.go                   |  1373 ++
 src/encoding/json/encode.go                        |  1183 ++
 src/encoding/json/encode_test.go                   |   532 +
 src/{pkg => }/encoding/json/example_test.go        |     0
 src/{pkg => }/encoding/json/fold.go                |     0
 src/{pkg => }/encoding/json/fold_test.go           |     0
 src/{pkg => }/encoding/json/indent.go              |     0
 src/{pkg => }/encoding/json/scanner.go             |     0
 src/{pkg => }/encoding/json/scanner_test.go        |     0
 src/encoding/json/stream.go                        |   200 +
 src/{pkg => }/encoding/json/stream_test.go         |     0
 src/{pkg => }/encoding/json/tagkey_test.go         |     0
 src/{pkg => }/encoding/json/tags.go                |     0
 src/{pkg => }/encoding/json/tags_test.go           |     0
 src/{pkg => }/encoding/json/testdata/code.json.gz  |   Bin
 src/{pkg => }/encoding/pem/pem.go                  |     0
 src/{pkg => }/encoding/pem/pem_test.go             |     0
 src/{pkg => }/encoding/xml/atom_test.go            |     0
 src/{pkg => }/encoding/xml/example_test.go         |     0
 src/{pkg => }/encoding/xml/marshal.go              |     0
 src/{pkg => }/encoding/xml/marshal_test.go         |     0
 src/{pkg => }/encoding/xml/read.go                 |     0
 src/{pkg => }/encoding/xml/read_test.go            |     0
 src/{pkg => }/encoding/xml/typeinfo.go             |     0
 src/encoding/xml/xml.go                            |  1945 +++
 src/encoding/xml/xml_test.go                       |   749 +
 src/{pkg => }/errors/errors.go                     |     0
 src/{pkg => }/errors/errors_test.go                |     0
 src/{pkg => }/errors/example_test.go               |     0
 src/{pkg => }/expvar/expvar.go                     |     0
 src/{pkg => }/expvar/expvar_test.go                |     0
 src/{pkg => }/flag/example_test.go                 |     0
 src/{pkg => }/flag/export_test.go                  |     0
 src/flag/flag.go                                   |   858 ++
 src/flag/flag_test.go                              |   379 +
 src/fmt/doc.go                                     |   295 +
 src/{pkg => }/fmt/export_test.go                   |     0
 src/fmt/fmt_test.go                                |  1310 ++
 src/fmt/format.go                                  |   524 +
 src/fmt/print.go                                   |  1223 ++
 src/fmt/scan.go                                    |  1169 ++
 src/fmt/scan_test.go                               |   992 ++
 src/{pkg => }/fmt/stringer_test.go                 |     0
 src/go/ast/ast.go                                  |   995 ++
 src/{pkg => }/go/ast/ast_test.go                   |     0
 src/{pkg => }/go/ast/commentmap.go                 |     0
 src/{pkg => }/go/ast/commentmap_test.go            |     0
 src/{pkg => }/go/ast/example_test.go               |     0
 src/{pkg => }/go/ast/filter.go                     |     0
 src/{pkg => }/go/ast/filter_test.go                |     0
 src/{pkg => }/go/ast/import.go                     |     0
 src/{pkg => }/go/ast/print.go                      |     0
 src/{pkg => }/go/ast/print_test.go                 |     0
 src/{pkg => }/go/ast/resolve.go                    |     0
 src/go/ast/scope.go                                |   162 +
 src/go/ast/walk.go                                 |   386 +
 src/go/build/build.go                              |  1391 ++
 src/go/build/build_test.go                         |   224 +
 src/go/build/deps_test.go                          |   443 +
 src/go/build/doc.go                                |   139 +
 src/{pkg => }/go/build/read.go                     |     0
 src/{pkg => }/go/build/read_test.go                |     0
 src/go/build/syslist.go                            |     8 +
 src/{pkg => }/go/build/syslist_test.go             |     0
 src/go/build/testdata/empty/dummy                  |     0
 src/go/build/testdata/multi/file.go                |     5 +
 src/go/build/testdata/multi/file_appengine.go      |     5 +
 src/{pkg => }/go/build/testdata/other/file/file.go |     0
 src/{pkg => }/go/build/testdata/other/main.go      |     0
 src/{pkg => }/go/doc/Makefile                      |     0
 src/{pkg => }/go/doc/comment.go                    |     0
 src/{pkg => }/go/doc/comment_test.go               |     0
 src/{pkg => }/go/doc/doc.go                        |     0
 src/{pkg => }/go/doc/doc_test.go                   |     0
 src/{pkg => }/go/doc/example.go                    |     0
 src/{pkg => }/go/doc/example_test.go               |     0
 src/go/doc/exports.go                              |   205 +
 src/{pkg => }/go/doc/filter.go                     |     0
 src/go/doc/headscan.go                             |   114 +
 src/{pkg => }/go/doc/reader.go                     |     0
 src/{pkg => }/go/doc/synopsis.go                   |     0
 src/{pkg => }/go/doc/synopsis_test.go              |     0
 src/{pkg => }/go/doc/testdata/a.0.golden           |     0
 src/{pkg => }/go/doc/testdata/a.1.golden           |     0
 src/{pkg => }/go/doc/testdata/a.2.golden           |     0
 src/{pkg => }/go/doc/testdata/a0.go                |     0
 src/{pkg => }/go/doc/testdata/a1.go                |     0
 src/{pkg => }/go/doc/testdata/b.0.golden           |     0
 src/{pkg => }/go/doc/testdata/b.1.golden           |     0
 src/{pkg => }/go/doc/testdata/b.2.golden           |     0
 src/{pkg => }/go/doc/testdata/b.go                 |     0
 src/{pkg => }/go/doc/testdata/benchmark.go         |     0
 src/go/doc/testdata/blank.0.golden                 |    37 +
 src/go/doc/testdata/blank.1.golden                 |    46 +
 src/go/doc/testdata/blank.2.golden                 |    37 +
 src/go/doc/testdata/blank.go                       |    38 +
 src/{pkg => }/go/doc/testdata/bugpara.0.golden     |     0
 src/{pkg => }/go/doc/testdata/bugpara.1.golden     |     0
 src/{pkg => }/go/doc/testdata/bugpara.2.golden     |     0
 src/{pkg => }/go/doc/testdata/bugpara.go           |     0
 src/{pkg => }/go/doc/testdata/c.0.golden           |     0
 src/{pkg => }/go/doc/testdata/c.1.golden           |     0
 src/{pkg => }/go/doc/testdata/c.2.golden           |     0
 src/{pkg => }/go/doc/testdata/c.go                 |     0
 src/{pkg => }/go/doc/testdata/d.0.golden           |     0
 src/{pkg => }/go/doc/testdata/d.1.golden           |     0
 src/{pkg => }/go/doc/testdata/d.2.golden           |     0
 src/{pkg => }/go/doc/testdata/d1.go                |     0
 src/{pkg => }/go/doc/testdata/d2.go                |     0
 src/{pkg => }/go/doc/testdata/e.0.golden           |     0
 src/{pkg => }/go/doc/testdata/e.1.golden           |     0
 src/{pkg => }/go/doc/testdata/e.2.golden           |     0
 src/{pkg => }/go/doc/testdata/e.go                 |     0
 src/{pkg => }/go/doc/testdata/error1.0.golden      |     0
 src/{pkg => }/go/doc/testdata/error1.1.golden      |     0
 src/{pkg => }/go/doc/testdata/error1.2.golden      |     0
 src/{pkg => }/go/doc/testdata/error1.go            |     0
 src/{pkg => }/go/doc/testdata/error2.0.golden      |     0
 src/{pkg => }/go/doc/testdata/error2.1.golden      |     0
 src/{pkg => }/go/doc/testdata/error2.2.golden      |     0
 src/{pkg => }/go/doc/testdata/error2.go            |     0
 src/{pkg => }/go/doc/testdata/example.go           |     0
 src/{pkg => }/go/doc/testdata/f.0.golden           |     0
 src/{pkg => }/go/doc/testdata/f.1.golden           |     0
 src/{pkg => }/go/doc/testdata/f.2.golden           |     0
 src/{pkg => }/go/doc/testdata/f.go                 |     0
 src/{pkg => }/go/doc/testdata/template.txt         |     0
 src/{pkg => }/go/doc/testdata/testing.0.golden     |     0
 src/{pkg => }/go/doc/testdata/testing.1.golden     |     0
 src/{pkg => }/go/doc/testdata/testing.2.golden     |     0
 src/{pkg => }/go/doc/testdata/testing.go           |     0
 src/go/format/format.go                            |   266 +
 src/go/format/format_test.go                       |   128 +
 src/go/parser/error_test.go                        |   182 +
 src/{pkg => }/go/parser/example_test.go            |     0
 src/go/parser/interface.go                         |   198 +
 src/go/parser/parser.go                            |  2462 ++++
 src/go/parser/parser_test.go                       |   449 +
 src/{pkg => }/go/parser/performance_test.go        |     0
 src/go/parser/short_test.go                        |   104 +
 src/{pkg => }/go/parser/testdata/commas.src        |     0
 src/{pkg => }/go/parser/testdata/issue3106.src     |     0
 src/{pkg => }/go/printer/example_test.go           |     0
 src/go/printer/nodes.go                            |  1606 +++
 src/{pkg => }/go/printer/performance_test.go       |     0
 src/{pkg => }/go/printer/printer.go                |     0
 src/go/printer/printer_test.go                     |   562 +
 src/{pkg => }/go/printer/testdata/comments.golden  |     0
 src/{pkg => }/go/printer/testdata/comments.input   |     0
 src/{pkg => }/go/printer/testdata/comments.x       |     0
 src/{pkg => }/go/printer/testdata/comments2.golden |     0
 src/{pkg => }/go/printer/testdata/comments2.input  |     0
 src/go/printer/testdata/declarations.golden        |   978 ++
 src/go/printer/testdata/declarations.input         |   992 ++
 src/{pkg => }/go/printer/testdata/empty.golden     |     0
 src/{pkg => }/go/printer/testdata/empty.input      |     0
 src/go/printer/testdata/expressions.golden         |   686 +
 src/go/printer/testdata/expressions.input          |   715 +
 src/go/printer/testdata/expressions.raw            |   686 +
 .../go/printer/testdata/linebreaks.golden          |     0
 src/{pkg => }/go/printer/testdata/linebreaks.input |     0
 src/{pkg => }/go/printer/testdata/parser.go        |     0
 src/{pkg => }/go/printer/testdata/slow.golden      |     0
 src/{pkg => }/go/printer/testdata/slow.input       |     0
 src/go/printer/testdata/statements.golden          |   644 +
 src/go/printer/testdata/statements.input           |   555 +
 src/{pkg => }/go/scanner/errors.go                 |     0
 src/{pkg => }/go/scanner/example_test.go           |     0
 src/{pkg => }/go/scanner/scanner.go                |     0
 src/{pkg => }/go/scanner/scanner_test.go           |     0
 src/go/token/position.go                           |   485 +
 src/go/token/position_test.go                      |   297 +
 src/{pkg => }/go/token/serialize.go                |     0
 src/{pkg => }/go/token/serialize_test.go           |     0
 src/{pkg => }/go/token/token.go                    |     0
 src/{pkg => }/hash/adler32/adler32.go              |     0
 src/{pkg => }/hash/adler32/adler32_test.go         |     0
 src/hash/crc32/crc32.go                            |   135 +
 src/hash/crc32/crc32_amd64.s                       |    64 +
 src/hash/crc32/crc32_amd64p32.s                    |    64 +
 src/{pkg => }/hash/crc32/crc32_amd64x.go           |     0
 src/{pkg => }/hash/crc32/crc32_generic.go          |     0
 src/{pkg => }/hash/crc32/crc32_test.go             |     0
 src/{pkg => }/hash/crc64/crc64.go                  |     0
 src/{pkg => }/hash/crc64/crc64_test.go             |     0
 src/{pkg => }/hash/fnv/fnv.go                      |     0
 src/{pkg => }/hash/fnv/fnv_test.go                 |     0
 src/{pkg => }/hash/hash.go                         |     0
 src/{pkg => }/hash/test_cases.txt                  |     0
 src/{pkg => }/hash/test_gen.awk                    |     0
 src/{pkg => }/html/entity.go                       |     0
 src/{pkg => }/html/entity_test.go                  |     0
 src/{pkg => }/html/escape.go                       |     0
 src/{pkg => }/html/escape_test.go                  |     0
 src/{pkg => }/html/template/attr.go                |     0
 src/{pkg => }/html/template/clone_test.go          |     0
 src/{pkg => }/html/template/content.go             |     0
 src/{pkg => }/html/template/content_test.go        |     0
 src/{pkg => }/html/template/context.go             |     0
 src/{pkg => }/html/template/css.go                 |     0
 src/{pkg => }/html/template/css_test.go            |     0
 src/{pkg => }/html/template/doc.go                 |     0
 src/html/template/error.go                         |   205 +
 src/html/template/escape.go                        |   807 ++
 src/html/template/escape_test.go                   |  1697 +++
 src/{pkg => }/html/template/html.go                |     0
 src/{pkg => }/html/template/html_test.go           |     0
 src/{pkg => }/html/template/js.go                  |     0
 src/html/template/js_test.go                       |   401 +
 src/html/template/template.go                      |   389 +
 src/html/template/transition.go                    |   550 +
 src/{pkg => }/html/template/url.go                 |     0
 src/{pkg => }/html/template/url_test.go            |     0
 src/{pkg => }/image/color/color.go                 |     0
 src/image/color/palette/gen.go                     |   121 +
 src/image/color/palette/generate.go                |     8 +
 src/image/color/palette/palette.go                 |   503 +
 src/{pkg => }/image/color/ycbcr.go                 |     0
 src/{pkg => }/image/color/ycbcr_test.go            |     0
 src/{pkg => }/image/decode_example_test.go         |     0
 src/{pkg => }/image/decode_test.go                 |     0
 src/{pkg => }/image/draw/bench_test.go             |     0
 src/{pkg => }/image/draw/clip_test.go              |     0
 src/{pkg => }/image/draw/draw.go                   |     0
 src/{pkg => }/image/draw/draw_test.go              |     0
 src/{pkg => }/image/format.go                      |     0
 src/{pkg => }/image/geom.go                        |     0
 src/image/gif/reader.go                            |   465 +
 src/image/gif/reader_test.go                       |   247 +
 src/image/gif/writer.go                            |   333 +
 src/image/gif/writer_test.go                       |   227 +
 src/image/image.go                                 |   936 ++
 src/{pkg => }/image/image_test.go                  |     0
 src/{pkg => }/image/jpeg/dct_test.go               |     0
 src/{pkg => }/image/jpeg/fdct.go                   |     0
 src/image/jpeg/huffman.go                          |   244 +
 src/{pkg => }/image/jpeg/idct.go                   |     0
 src/image/jpeg/reader.go                           |   527 +
 src/image/jpeg/reader_test.go                      |   270 +
 src/image/jpeg/scan.go                             |   442 +
 src/image/jpeg/writer.go                           |   614 +
 src/image/jpeg/writer_test.go                      |   232 +
 src/{pkg => }/image/names.go                       |     0
 src/image/png/paeth.go                             |    71 +
 src/image/png/paeth_test.go                        |    91 +
 src/image/png/reader.go                            |   820 ++
 src/image/png/reader_test.go                       |   362 +
 src/{pkg => }/image/png/testdata/benchGray.png     |   Bin
 .../image/png/testdata/benchNRGBA-gradient.png     |   Bin
 .../image/png/testdata/benchNRGBA-opaque.png       |   Bin
 src/{pkg => }/image/png/testdata/benchPaletted.png |   Bin
 src/image/png/testdata/benchRGB-interlace.png      |   Bin 0 -> 47483 bytes
 src/{pkg => }/image/png/testdata/benchRGB.png      |   Bin
 src/{pkg => }/image/png/testdata/invalid-crc32.png |   Bin
 src/{pkg => }/image/png/testdata/invalid-noend.png |   Bin
 src/{pkg => }/image/png/testdata/invalid-trunc.png |   Bin
 src/{pkg => }/image/png/testdata/invalid-zlib.png  |   Bin
 src/{pkg => }/image/png/testdata/pngsuite/README   |     0
 .../image/png/testdata/pngsuite/README.original    |     0
 .../image/png/testdata/pngsuite/basn0g01-30.png    |   Bin
 .../image/png/testdata/pngsuite/basn0g01-30.sng    |     0
 .../image/png/testdata/pngsuite/basn0g01.png       |   Bin
 .../image/png/testdata/pngsuite/basn0g01.sng       |     0
 .../image/png/testdata/pngsuite/basn0g02-29.png    |   Bin
 .../image/png/testdata/pngsuite/basn0g02-29.sng    |     0
 .../image/png/testdata/pngsuite/basn0g02.png       |   Bin
 .../image/png/testdata/pngsuite/basn0g02.sng       |     0
 .../image/png/testdata/pngsuite/basn0g04-31.png    |   Bin
 .../image/png/testdata/pngsuite/basn0g04-31.sng    |     0
 .../image/png/testdata/pngsuite/basn0g04.png       |   Bin
 .../image/png/testdata/pngsuite/basn0g04.sng       |     0
 .../image/png/testdata/pngsuite/basn0g08.png       |   Bin
 .../image/png/testdata/pngsuite/basn0g08.sng       |     0
 .../image/png/testdata/pngsuite/basn0g16.png       |   Bin
 .../image/png/testdata/pngsuite/basn0g16.sng       |     0
 .../image/png/testdata/pngsuite/basn2c08.png       |   Bin
 .../image/png/testdata/pngsuite/basn2c08.sng       |     0
 .../image/png/testdata/pngsuite/basn2c16.png       |   Bin
 .../image/png/testdata/pngsuite/basn2c16.sng       |     0
 .../image/png/testdata/pngsuite/basn3p01.png       |   Bin
 .../image/png/testdata/pngsuite/basn3p01.sng       |     0
 .../image/png/testdata/pngsuite/basn3p02.png       |   Bin
 .../image/png/testdata/pngsuite/basn3p02.sng       |     0
 src/image/png/testdata/pngsuite/basn3p04-31i.png   |   Bin 0 -> 358 bytes
 src/image/png/testdata/pngsuite/basn3p04-31i.sng   |    57 +
 .../image/png/testdata/pngsuite/basn3p04.png       |   Bin
 .../image/png/testdata/pngsuite/basn3p04.sng       |     0
 .../image/png/testdata/pngsuite/basn3p08-trns.png  |   Bin
 .../image/png/testdata/pngsuite/basn3p08-trns.sng  |     0
 .../image/png/testdata/pngsuite/basn3p08.png       |   Bin
 .../image/png/testdata/pngsuite/basn3p08.sng       |     0
 .../image/png/testdata/pngsuite/basn4a08.png       |   Bin
 .../image/png/testdata/pngsuite/basn4a08.sng       |     0
 .../image/png/testdata/pngsuite/basn4a16.png       |   Bin
 .../image/png/testdata/pngsuite/basn4a16.sng       |     0
 .../image/png/testdata/pngsuite/basn6a08.png       |   Bin
 .../image/png/testdata/pngsuite/basn6a08.sng       |     0
 .../image/png/testdata/pngsuite/basn6a16.png       |   Bin
 .../image/png/testdata/pngsuite/basn6a16.sng       |     0
 src/image/png/writer.go                            |   530 +
 src/image/png/writer_test.go                       |   210 +
 src/{pkg => }/image/testdata/video-001.5bpp.gif    |   Bin
 src/{pkg => }/image/testdata/video-001.gif         |   Bin
 .../image/testdata/video-001.interlaced.gif        |   Bin
 src/{pkg => }/image/testdata/video-001.jpeg        |   Bin
 src/{pkg => }/image/testdata/video-001.png         |   Bin
 .../image/testdata/video-001.progressive.jpeg      |   Bin
 .../image/testdata/video-001.q50.420.jpeg          |   Bin
 .../testdata/video-001.q50.420.progressive.jpeg    |   Bin
 .../image/testdata/video-001.q50.422.jpeg          |   Bin
 .../testdata/video-001.q50.422.progressive.jpeg    |   Bin
 .../image/testdata/video-001.q50.440.jpeg          |   Bin
 .../testdata/video-001.q50.440.progressive.jpeg    |   Bin
 .../image/testdata/video-001.q50.444.jpeg          |   Bin
 .../testdata/video-001.q50.444.progressive.jpeg    |   Bin
 .../video-001.separate.dc.progression.jpeg         |   Bin
 ...eo-001.separate.dc.progression.progressive.jpeg |   Bin
 src/{pkg => }/image/testdata/video-005.gray.gif    |   Bin
 src/{pkg => }/image/testdata/video-005.gray.jpeg   |   Bin
 src/{pkg => }/image/testdata/video-005.gray.png    |   Bin
 .../image/testdata/video-005.gray.q50.2x2.jpeg     |   Bin
 .../video-005.gray.q50.2x2.progressive.jpeg        |   Bin
 .../image/testdata/video-005.gray.q50.jpeg         |   Bin
 .../testdata/video-005.gray.q50.progressive.jpeg   |   Bin
 src/image/ycbcr.go                                 |   157 +
 src/{pkg => }/image/ycbcr_test.go                  |     0
 src/{pkg => }/index/suffixarray/qsufsort.go        |     0
 src/{pkg => }/index/suffixarray/suffixarray.go     |     0
 src/index/suffixarray/suffixarray_test.go          |   304 +
 src/internal/syscall/getrandom_linux.go            |    56 +
 src/io/io.go                                       |   502 +
 src/{pkg => }/io/io_test.go                        |     0
 src/{pkg => }/io/ioutil/ioutil.go                  |     0
 src/{pkg => }/io/ioutil/ioutil_test.go             |     0
 src/{pkg => }/io/ioutil/tempfile.go                |     0
 src/{pkg => }/io/ioutil/tempfile_test.go           |     0
 src/{pkg => }/io/multi.go                          |     0
 src/{pkg => }/io/multi_test.go                     |     0
 src/{pkg => }/io/pipe.go                           |     0
 src/{pkg => }/io/pipe_test.go                      |     0
 src/lib9/fmt/dofmt.c                               |     6 -
 src/lib9/tempdir_windows.c                         |    19 +-
 src/liblink/asm5.c                                 |   618 +-
 src/liblink/asm6.c                                 |  1672 +--
 src/liblink/asm8.c                                 |  1074 +-
 src/liblink/data.c                                 |     2 +
 src/liblink/ld.c                                   |    36 +-
 src/liblink/list5.c                                |    17 +
 src/liblink/list6.c                                |     2 +-
 src/liblink/list8.c                                |     2 +-
 src/liblink/obj5.c                                 |   250 +-
 src/liblink/obj6.c                                 |   263 +-
 src/liblink/obj8.c                                 |   129 +-
 src/liblink/objfile.c                              |    78 +-
 src/liblink/pcln.c                                 |     2 +-
 src/liblink/sym.c                                  |    43 +-
 src/{pkg => }/log/example_test.go                  |     0
 src/{pkg => }/log/log.go                           |     0
 src/{pkg => }/log/log_test.go                      |     0
 src/{pkg => }/log/syslog/syslog.go                 |     0
 src/{pkg => }/log/syslog/syslog_plan9.go           |     0
 src/log/syslog/syslog_test.go                      |   358 +
 src/log/syslog/syslog_unix.go                      |    31 +
 src/{pkg => }/log/syslog/syslog_windows.go         |     0
 src/make.bash                                      |     2 +-
 src/make.bat                                       |     3 +-
 src/make.rc                                        |     2 +-
 src/{pkg => }/math/abs.go                          |     0
 src/math/abs_386.s                                 |    12 +
 src/math/abs_amd64.s                               |    14 +
 src/{pkg => }/math/abs_amd64p32.s                  |     0
 src/math/abs_arm.s                                 |    13 +
 src/{pkg => }/math/acosh.go                        |     0
 src/math/all_test.go                               |  2992 ++++
 src/{pkg => }/math/asin.go                         |     0
 src/math/asin_386.s                                |    30 +
 src/math/asin_amd64.s                              |    11 +
 src/{pkg => }/math/asin_amd64p32.s                 |     0
 src/math/asin_arm.s                                |    11 +
 src/{pkg => }/math/asinh.go                        |     0
 src/{pkg => }/math/atan.go                         |     0
 src/{pkg => }/math/atan2.go                        |     0
 src/math/atan2_386.s                               |    13 +
 src/math/atan2_amd64.s                             |     8 +
 src/{pkg => }/math/atan2_amd64p32.s                |     0
 src/math/atan2_arm.s                               |     8 +
 src/math/atan_386.s                                |    13 +
 src/math/atan_amd64.s                              |     8 +
 src/{pkg => }/math/atan_amd64p32.s                 |     0
 src/math/atan_arm.s                                |     8 +
 src/{pkg => }/math/atanh.go                        |     0
 src/{pkg => }/math/big/arith.go                    |     0
 src/math/big/arith_386.s                           |   278 +
 src/math/big/arith_amd64.s                         |   401 +
 src/math/big/arith_amd64p32.s                      |    41 +
 src/math/big/arith_arm.s                           |   300 +
 src/{pkg => }/math/big/arith_decl.go               |     0
 src/{pkg => }/math/big/arith_test.go               |     0
 src/{pkg => }/math/big/calibrate_test.go           |     0
 src/{pkg => }/math/big/example_test.go             |     0
 src/{pkg => }/math/big/gcd_test.go                 |     0
 src/{pkg => }/math/big/hilbert_test.go             |     0
 src/math/big/int.go                                |  1031 ++
 src/math/big/int_test.go                           |  1625 +++
 src/{pkg => }/math/big/nat.go                      |     0
 src/{pkg => }/math/big/nat_test.go                 |     0
 src/math/big/rat.go                                |   716 +
 src/math/big/rat_test.go                           |  1160 ++
 src/{pkg => }/math/bits.go                         |     0
 src/{pkg => }/math/cbrt.go                         |     0
 src/{pkg => }/math/cmplx/abs.go                    |     0
 src/{pkg => }/math/cmplx/asin.go                   |     0
 src/{pkg => }/math/cmplx/cmath_test.go             |     0
 src/{pkg => }/math/cmplx/conj.go                   |     0
 src/{pkg => }/math/cmplx/exp.go                    |     0
 src/{pkg => }/math/cmplx/isinf.go                  |     0
 src/{pkg => }/math/cmplx/isnan.go                  |     0
 src/{pkg => }/math/cmplx/log.go                    |     0
 src/{pkg => }/math/cmplx/phase.go                  |     0
 src/{pkg => }/math/cmplx/polar.go                  |     0
 src/{pkg => }/math/cmplx/pow.go                    |     0
 src/{pkg => }/math/cmplx/rect.go                   |     0
 src/{pkg => }/math/cmplx/sin.go                    |     0
 src/{pkg => }/math/cmplx/sqrt.go                   |     0
 src/{pkg => }/math/cmplx/tan.go                    |     0
 src/{pkg => }/math/const.go                        |     0
 src/{pkg => }/math/copysign.go                     |     0
 src/{pkg => }/math/dim.go                          |     0
 src/math/dim_386.s                                 |    14 +
 src/math/dim_amd64.s                               |   144 +
 src/{pkg => }/math/dim_amd64p32.s                  |     0
 src/math/dim_arm.s                                 |    14 +
 src/{pkg => }/math/erf.go                          |     0
 src/{pkg => }/math/exp.go                          |     0
 src/math/exp2_386.s                                |    40 +
 src/math/exp2_amd64.s                              |     8 +
 src/{pkg => }/math/exp2_amd64p32.s                 |     0
 src/math/exp2_arm.s                                |     8 +
 src/math/exp_386.s                                 |    41 +
 src/math/exp_amd64.s                               |   114 +
 src/{pkg => }/math/exp_amd64p32.s                  |     0
 src/math/exp_arm.s                                 |     8 +
 src/{pkg => }/math/expm1.go                        |     0
 src/math/expm1_386.s                               |    57 +
 src/math/expm1_amd64.s                             |     8 +
 src/{pkg => }/math/expm1_amd64p32.s                |     0
 src/math/expm1_arm.s                               |     8 +
 src/{pkg => }/math/export_test.go                  |     0
 src/{pkg => }/math/floor.go                        |     0
 src/math/floor_386.s                               |    46 +
 src/math/floor_amd64.s                             |    76 +
 src/{pkg => }/math/floor_amd64p32.s                |     0
 src/math/floor_arm.s                               |    14 +
 src/{pkg => }/math/frexp.go                        |     0
 src/math/frexp_386.s                               |    25 +
 src/math/frexp_amd64.s                             |     8 +
 src/{pkg => }/math/frexp_amd64p32.s                |     0
 src/math/frexp_arm.s                               |     8 +
 src/{pkg => }/math/gamma.go                        |     0
 src/{pkg => }/math/hypot.go                        |     0
 src/math/hypot_386.s                               |    59 +
 src/math/hypot_amd64.s                             |    52 +
 src/{pkg => }/math/hypot_amd64p32.s                |     0
 src/math/hypot_arm.s                               |     8 +
 src/{pkg => }/math/j0.go                           |     0
 src/{pkg => }/math/j1.go                           |     0
 src/{pkg => }/math/jn.go                           |     0
 src/{pkg => }/math/ldexp.go                        |     0
 src/math/ldexp_386.s                               |    14 +
 src/math/ldexp_amd64.s                             |     8 +
 src/{pkg => }/math/ldexp_amd64p32.s                |     0
 src/math/ldexp_arm.s                               |     8 +
 src/{pkg => }/math/lgamma.go                       |     0
 src/{pkg => }/math/log.go                          |     0
 src/{pkg => }/math/log10.go                        |     0
 src/math/log10_386.s                               |    21 +
 src/math/log10_amd64.s                             |    11 +
 src/{pkg => }/math/log10_amd64p32.s                |     0
 src/math/log10_arm.s                               |    11 +
 src/{pkg => }/math/log1p.go                        |     0
 src/math/log1p_386.s                               |    27 +
 src/math/log1p_amd64.s                             |     8 +
 src/{pkg => }/math/log1p_amd64p32.s                |     0
 src/math/log1p_arm.s                               |     8 +
 src/math/log_386.s                                 |    13 +
 src/math/log_amd64.s                               |   111 +
 src/{pkg => }/math/log_amd64p32.s                  |     0
 src/math/log_arm.s                                 |     8 +
 src/{pkg => }/math/logb.go                         |     0
 src/{pkg => }/math/mod.go                          |     0
 src/math/mod_386.s                                 |    17 +
 src/math/mod_amd64.s                               |     8 +
 src/{pkg => }/math/mod_amd64p32.s                  |     0
 src/math/mod_arm.s                                 |     8 +
 src/{pkg => }/math/modf.go                         |     0
 src/math/modf_386.s                                |    21 +
 src/math/modf_amd64.s                              |     8 +
 src/{pkg => }/math/modf_amd64p32.s                 |     0
 src/math/modf_arm.s                                |     8 +
 src/math/nextafter.go                              |    47 +
 src/{pkg => }/math/pow.go                          |     0
 src/{pkg => }/math/pow10.go                        |     0
 src/{pkg => }/math/rand/example_test.go            |     0
 src/{pkg => }/math/rand/exp.go                     |     0
 src/{pkg => }/math/rand/normal.go                  |     0
 src/{pkg => }/math/rand/rand.go                    |     0
 src/{pkg => }/math/rand/rand_test.go               |     0
 src/{pkg => }/math/rand/regress_test.go            |     0
 src/{pkg => }/math/rand/rng.go                     |     0
 src/{pkg => }/math/rand/zipf.go                    |     0
 src/{pkg => }/math/remainder.go                    |     0
 src/math/remainder_386.s                           |    17 +
 src/math/remainder_amd64.s                         |     8 +
 src/{pkg => }/math/remainder_amd64p32.s            |     0
 src/math/remainder_arm.s                           |     8 +
 src/{pkg => }/math/signbit.go                      |     0
 src/{pkg => }/math/sin.go                          |     0
 src/math/sin_386.s                                 |    47 +
 src/math/sin_amd64.s                               |    11 +
 src/{pkg => }/math/sin_amd64p32.s                  |     0
 src/math/sin_arm.s                                 |    11 +
 src/{pkg => }/math/sincos.go                       |     0
 src/math/sincos_386.s                              |    28 +
 src/math/sincos_amd64.s                            |   142 +
 src/{pkg => }/math/sincos_amd64p32.s               |     0
 src/math/sincos_arm.s                              |     8 +
 src/{pkg => }/math/sinh.go                         |     0
 src/math/sqrt.go                                   |   143 +
 src/math/sqrt_386.s                                |    12 +
 src/math/sqrt_amd64.s                              |    11 +
 src/{pkg => }/math/sqrt_amd64p32.s                 |     0
 src/math/sqrt_arm.s                                |    12 +
 src/{pkg => }/math/tan.go                          |     0
 src/math/tan_386.s                                 |    28 +
 src/math/tan_amd64.s                               |     8 +
 src/{pkg => }/math/tan_amd64p32.s                  |     0
 src/math/tan_arm.s                                 |     8 +
 src/{pkg => }/math/tanh.go                         |     0
 src/{pkg => }/math/unsafe.go                       |     0
 src/{pkg => }/mime/grammar.go                      |     0
 src/{pkg => }/mime/mediatype.go                    |     0
 src/{pkg => }/mime/mediatype_test.go               |     0
 src/mime/multipart/example_test.go                 |    53 +
 src/{pkg => }/mime/multipart/formdata.go           |     0
 src/{pkg => }/mime/multipart/formdata_test.go      |     0
 src/mime/multipart/multipart.go                    |   348 +
 src/{pkg => }/mime/multipart/multipart_test.go     |     0
 src/{pkg => }/mime/multipart/quotedprintable.go    |     0
 .../mime/multipart/quotedprintable_test.go         |     0
 src/{pkg => }/mime/multipart/testdata/nested-mime  |     0
 src/{pkg => }/mime/multipart/writer.go             |     0
 src/mime/multipart/writer_test.go                  |   128 +
 src/{pkg => }/mime/testdata/test.types             |     0
 src/{pkg => }/mime/testdata/test.types.plan9       |     0
 src/mime/type.go                                   |   121 +
 src/mime/type_plan9.go                             |    53 +
 src/mime/type_test.go                              |    54 +
 src/mime/type_unix.go                              |    60 +
 src/mime/type_windows.go                           |    63 +
 src/nacltest.bash                                  |    31 +-
 src/net/cgo_android.go                             |    14 +
 src/{pkg => }/net/cgo_bsd.go                       |     0
 src/net/cgo_linux.go                               |    22 +
 src/{pkg => }/net/cgo_netbsd.go                    |     0
 src/{pkg => }/net/cgo_openbsd.go                   |     0
 src/{pkg => }/net/cgo_stub.go                      |     0
 src/{pkg => }/net/cgo_unix.go                      |     0
 src/{pkg => }/net/cgo_unix_test.go                 |     0
 src/net/conn_test.go                               |   124 +
 src/net/dial.go                                    |   302 +
 src/{pkg => }/net/dial_gen.go                      |     0
 src/{pkg => }/net/dial_gen_test.go                 |     0
 src/net/dial_test.go                               |   548 +
 src/{pkg => }/net/dialgoogle_test.go               |     0
 src/net/dnsclient.go                               |   249 +
 src/{pkg => }/net/dnsclient_test.go                |     0
 src/net/dnsclient_unix.go                          |   423 +
 src/net/dnsclient_unix_test.go                     |   246 +
 src/net/dnsconfig_unix.go                          |    96 +
 src/net/dnsconfig_unix_test.go                     |    69 +
 src/{pkg => }/net/dnsmsg.go                        |     0
 src/{pkg => }/net/dnsmsg_test.go                   |     0
 src/{pkg => }/net/dnsname_test.go                  |     0
 src/{pkg => }/net/example_test.go                  |     0
 src/{pkg => }/net/fd_mutex.go                      |     0
 src/{pkg => }/net/fd_mutex_test.go                 |     0
 src/{pkg => }/net/fd_plan9.go                      |     0
 src/{pkg => }/net/fd_poll_nacl.go                  |     0
 src/{pkg => }/net/fd_poll_runtime.go               |     0
 src/net/fd_unix.go                                 |   518 +
 src/{pkg => }/net/fd_unix_test.go                  |     0
 src/net/fd_windows.go                              |   656 +
 src/{pkg => }/net/file_plan9.go                    |     0
 src/net/file_stub.go                               |    38 +
 src/net/file_test.go                               |   205 +
 src/net/file_unix.go                               |   139 +
 src/{pkg => }/net/file_windows.go                  |     0
 src/net/hosts.go                                   |    86 +
 src/{pkg => }/net/hosts_test.go                    |     0
 src/{pkg => }/net/http/cgi/child.go                |     0
 src/{pkg => }/net/http/cgi/child_test.go           |     0
 src/{pkg => }/net/http/cgi/host.go                 |     0
 src/{pkg => }/net/http/cgi/host_test.go            |     0
 src/{pkg => }/net/http/cgi/matryoshka_test.go      |     0
 src/{pkg => }/net/http/cgi/plan9_test.go           |     0
 src/{pkg => }/net/http/cgi/posix_test.go           |     0
 src/{pkg => }/net/http/cgi/testdata/test.cgi       |     0
 src/net/http/client.go                             |   511 +
 src/net/http/client_test.go                        |  1075 ++
 src/net/http/cookie.go                             |   363 +
 src/net/http/cookie_test.go                        |   412 +
 src/net/http/cookiejar/jar.go                      |   497 +
 src/{pkg => }/net/http/cookiejar/jar_test.go       |     0
 src/{pkg => }/net/http/cookiejar/punycode.go       |     0
 src/{pkg => }/net/http/cookiejar/punycode_test.go  |     0
 src/{pkg => }/net/http/doc.go                      |     0
 src/{pkg => }/net/http/example_test.go             |     0
 src/net/http/export_test.go                        |   108 +
 src/{pkg => }/net/http/fcgi/child.go               |     0
 src/{pkg => }/net/http/fcgi/fcgi.go                |     0
 src/{pkg => }/net/http/fcgi/fcgi_test.go           |     0
 src/{pkg => }/net/http/filetransport.go            |     0
 src/{pkg => }/net/http/filetransport_test.go       |     0
 src/net/http/fs.go                                 |   556 +
 src/net/http/fs_test.go                            |   917 ++
 src/{pkg => }/net/http/header.go                   |     0
 src/{pkg => }/net/http/header_test.go              |     0
 src/{pkg => }/net/http/httptest/example_test.go    |     0
 src/{pkg => }/net/http/httptest/recorder.go        |     0
 src/{pkg => }/net/http/httptest/recorder_test.go   |     0
 src/net/http/httptest/server.go                    |   228 +
 src/net/http/httptest/server_test.go               |    29 +
 src/net/http/httputil/dump.go                      |   284 +
 src/net/http/httputil/dump_test.go                 |   291 +
 src/net/http/httputil/httputil.go                  |    39 +
 src/{pkg => }/net/http/httputil/persist.go         |     0
 src/net/http/httputil/reverseproxy.go              |   225 +
 .../net/http/httputil/reverseproxy_test.go         |     0
 src/net/http/internal/chunked.go                   |   202 +
 src/net/http/internal/chunked_test.go              |   156 +
 src/{pkg => }/net/http/jar.go                      |     0
 src/{pkg => }/net/http/lex.go                      |     0
 src/{pkg => }/net/http/lex_test.go                 |     0
 src/net/http/main_test.go                          |   109 +
 src/{pkg => }/net/http/npn_test.go                 |     0
 src/net/http/pprof/pprof.go                        |   209 +
 src/{pkg => }/net/http/proxy_test.go               |     0
 src/{pkg => }/net/http/race.go                     |     0
 src/{pkg => }/net/http/range_test.go               |     0
 src/net/http/readrequest_test.go                   |   358 +
 src/net/http/request.go                            |   921 ++
 src/net/http/request_test.go                       |   680 +
 src/net/http/requestwrite_test.go                  |   623 +
 src/{pkg => }/net/http/response.go                 |     0
 src/net/http/response_test.go                      |   674 +
 src/{pkg => }/net/http/responsewrite_test.go       |     0
 src/net/http/serve_test.go                         |  3094 +++++
 src/net/http/server.go                             |  2096 +++
 src/{pkg => }/net/http/sniff.go                    |     0
 src/{pkg => }/net/http/sniff_test.go               |     0
 src/{pkg => }/net/http/status.go                   |     0
 src/{pkg => }/net/http/testdata/file               |     0
 src/{pkg => }/net/http/testdata/index.html         |     0
 src/{pkg => }/net/http/testdata/style.css          |     0
 src/net/http/transfer.go                           |   737 +
 src/{pkg => }/net/http/transfer_test.go            |     0
 src/net/http/transport.go                          |  1275 ++
 src/net/http/transport_test.go                     |  2324 ++++
 src/{pkg => }/net/http/triv.go                     |     0
 src/{pkg => }/net/interface.go                     |     0
 src/{pkg => }/net/interface_bsd.go                 |     0
 src/{pkg => }/net/interface_bsd_test.go            |     0
 src/{pkg => }/net/interface_darwin.go              |     0
 src/{pkg => }/net/interface_dragonfly.go           |     0
 src/{pkg => }/net/interface_freebsd.go             |     0
 src/{pkg => }/net/interface_linux.go               |     0
 src/{pkg => }/net/interface_linux_test.go          |     0
 src/{pkg => }/net/interface_netbsd.go              |     0
 src/{pkg => }/net/interface_openbsd.go             |     0
 src/{pkg => }/net/interface_stub.go                |     0
 src/{pkg => }/net/interface_test.go                |     0
 src/{pkg => }/net/interface_unix_test.go           |     0
 src/{pkg => }/net/interface_windows.go             |     0
 src/net/ip.go                                      |   689 +
 src/net/ip_test.go                                 |   465 +
 src/net/ipraw_test.go                              |   294 +
 src/{pkg => }/net/iprawsock.go                     |     0
 src/{pkg => }/net/iprawsock_plan9.go               |     0
 src/net/iprawsock_posix.go                         |   227 +
 src/{pkg => }/net/ipsock.go                        |     0
 src/{pkg => }/net/ipsock_plan9.go                  |     0
 src/net/ipsock_posix.go                            |   177 +
 src/{pkg => }/net/ipsock_test.go                   |     0
 src/net/lookup.go                                  |   142 +
 src/{pkg => }/net/lookup_plan9.go                  |     0
 src/net/lookup_stub.go                             |    49 +
 src/net/lookup_test.go                             |   231 +
 src/net/lookup_unix.go                             |   168 +
 src/net/lookup_windows.go                          |   381 +
 src/net/lookup_windows_test.go                     |   243 +
 src/{pkg => }/net/mac.go                           |     0
 src/{pkg => }/net/mac_test.go                      |     0
 src/net/mail/message.go                            |   556 +
 src/net/mail/message_test.go                       |   314 +
 src/{pkg => }/net/mockicmp_test.go                 |     0
 src/{pkg => }/net/mockserver_test.go               |     0
 src/net/multicast_test.go                          |   188 +
 src/net/net.go                                     |   425 +
 src/{pkg => }/net/net_test.go                      |     0
 src/{pkg => }/net/net_windows_test.go              |     0
 src/{pkg => }/net/netgo_unix_test.go               |     0
 src/{pkg => }/net/packetconn_test.go               |     0
 src/net/parse.go                                   |   247 +
 src/net/parse_test.go                              |    53 +
 src/{pkg => }/net/pipe.go                          |     0
 src/{pkg => }/net/pipe_test.go                     |     0
 src/{pkg => }/net/port.go                          |     0
 src/net/port_test.go                               |    59 +
 src/net/port_unix.go                               |    73 +
 src/{pkg => }/net/protoconn_test.go                |     0
 src/{pkg => }/net/race.go                          |     0
 src/{pkg => }/net/race0.go                         |     0
 src/net/rpc/client.go                              |   317 +
 src/net/rpc/client_test.go                         |    91 +
 src/net/rpc/debug.go                               |    93 +
 src/{pkg => }/net/rpc/jsonrpc/all_test.go          |     0
 src/{pkg => }/net/rpc/jsonrpc/client.go            |     0
 src/{pkg => }/net/rpc/jsonrpc/server.go            |     0
 src/net/rpc/server.go                              |   709 +
 src/{pkg => }/net/rpc/server_test.go               |     0
 src/{pkg => }/net/sendfile_dragonfly.go            |     0
 src/{pkg => }/net/sendfile_freebsd.go              |     0
 src/{pkg => }/net/sendfile_linux.go                |     0
 src/{pkg => }/net/sendfile_stub.go                 |     0
 src/{pkg => }/net/sendfile_windows.go              |     0
 src/{pkg => }/net/server_test.go                   |     0
 src/net/singleflight.go                            |   109 +
 src/{pkg => }/net/smtp/auth.go                     |     0
 src/{pkg => }/net/smtp/example_test.go             |     0
 src/{pkg => }/net/smtp/smtp.go                     |     0
 src/net/smtp/smtp_test.go                          |   694 +
 src/net/sock_bsd.go                                |    37 +
 src/{pkg => }/net/sock_cloexec.go                  |     0
 src/{pkg => }/net/sock_linux.go                    |     0
 src/{pkg => }/net/sock_plan9.go                    |     0
 src/net/sock_posix.go                              |   216 +
 src/net/sock_stub.go                               |    15 +
 src/{pkg => }/net/sock_windows.go                  |     0
 src/net/sockopt_bsd.go                             |    54 +
 src/{pkg => }/net/sockopt_linux.go                 |     0
 src/{pkg => }/net/sockopt_plan9.go                 |     0
 src/net/sockopt_posix.go                           |   141 +
 src/{pkg => }/net/sockopt_solaris.go               |     0
 src/net/sockopt_stub.go                            |    37 +
 src/{pkg => }/net/sockopt_windows.go               |     0
 src/net/sockoptip_bsd.go                           |    34 +
 src/{pkg => }/net/sockoptip_linux.go               |     0
 src/net/sockoptip_posix.go                         |    57 +
 src/net/sockoptip_stub.go                          |    39 +
 src/{pkg => }/net/sockoptip_windows.go             |     0
 src/{pkg => }/net/sys_cloexec.go                   |     0
 src/{pkg => }/net/tcp_test.go                      |     0
 src/{pkg => }/net/tcpsock.go                       |     0
 src/{pkg => }/net/tcpsock_plan9.go                 |     0
 src/net/tcpsock_posix.go                           |   299 +
 src/net/tcpsockopt_darwin.go                       |    29 +
 src/net/tcpsockopt_dragonfly.go                    |    26 +
 src/net/tcpsockopt_openbsd.go                      |    16 +
 src/{pkg => }/net/tcpsockopt_plan9.go              |     0
 src/net/tcpsockopt_posix.go                        |    20 +
 src/net/tcpsockopt_stub.go                         |    20 +
 src/net/tcpsockopt_unix.go                         |    27 +
 src/net/tcpsockopt_windows.go                      |    32 +
 src/net/testdata/domain-resolv.conf                |     5 +
 src/net/testdata/empty-resolv.conf                 |     1 +
 src/{pkg => }/net/testdata/hosts                   |     0
 src/{pkg => }/net/testdata/hosts_singleline        |     0
 src/{pkg => }/net/testdata/igmp                    |     0
 src/{pkg => }/net/testdata/igmp6                   |     0
 src/net/testdata/resolv.conf                       |     8 +
 src/net/testdata/search-resolv.conf                |     5 +
 src/{pkg => }/net/textproto/header.go              |     0
 src/{pkg => }/net/textproto/pipeline.go            |     0
 src/{pkg => }/net/textproto/reader.go              |     0
 src/{pkg => }/net/textproto/reader_test.go         |     0
 src/{pkg => }/net/textproto/textproto.go           |     0
 src/{pkg => }/net/textproto/writer.go              |     0
 src/{pkg => }/net/textproto/writer_test.go         |     0
 src/{pkg => }/net/timeout_test.go                  |     0
 src/net/udp_test.go                                |   298 +
 src/{pkg => }/net/udpsock.go                       |     0
 src/{pkg => }/net/udpsock_plan9.go                 |     0
 src/net/udpsock_posix.go                           |   268 +
 src/net/unicast_posix_test.go                      |   469 +
 src/net/unix_test.go                               |   333 +
 src/{pkg => }/net/unixsock.go                      |     0
 src/{pkg => }/net/unixsock_plan9.go                |     0
 src/net/unixsock_posix.go                          |   362 +
 src/net/url/example_test.go                        |    71 +
 src/net/url/url.go                                 |   719 +
 src/net/url/url_test.go                            |   961 ++
 src/net/z_last_test.go                             |    99 +
 src/{pkg => }/os/dir_plan9.go                      |     0
 src/os/dir_unix.go                                 |    58 +
 src/{pkg => }/os/dir_windows.go                    |     0
 src/{pkg => }/os/doc.go                            |     0
 src/os/env.go                                      |   108 +
 src/os/env_test.go                                 |    96 +
 src/{pkg => }/os/env_unix_test.go                  |     0
 src/{pkg => }/os/error.go                          |     0
 src/os/error_plan9.go                              |    54 +
 src/{pkg => }/os/error_test.go                     |     0
 src/{pkg => }/os/error_unix.go                     |     0
 src/{pkg => }/os/error_windows.go                  |     0
 src/{pkg => }/os/error_windows_test.go             |     0
 src/{pkg => }/os/exec.go                           |     0
 src/{pkg => }/os/exec/example_test.go              |     0
 src/os/exec/exec.go                                |   500 +
 src/os/exec/exec_test.go                           |   719 +
 src/{pkg => }/os/exec/lp_plan9.go                  |     0
 src/{pkg => }/os/exec/lp_test.go                   |     0
 src/{pkg => }/os/exec/lp_unix.go                   |     0
 src/{pkg => }/os/exec/lp_unix_test.go              |     0
 src/{pkg => }/os/exec/lp_windows.go                |     0
 src/{pkg => }/os/exec/lp_windows_test.go           |     0
 src/{pkg => }/os/exec_plan9.go                     |     0
 src/{pkg => }/os/exec_posix.go                     |     0
 src/os/exec_unix.go                                |    81 +
 src/os/exec_windows.go                             |   118 +
 src/{pkg => }/os/export_test.go                    |     0
 src/os/file.go                                     |   266 +
 src/os/file_plan9.go                               |   469 +
 src/os/file_posix.go                               |   149 +
 src/os/file_unix.go                                |   339 +
 src/os/file_windows.go                             |   596 +
 src/os/getwd.go                                    |   123 +
 src/{pkg => }/os/getwd_darwin.go                   |     0
 src/os/os_test.go                                  |  1484 ++
 src/{pkg => }/os/os_unix_test.go                   |     0
 src/os/os_windows_test.go                          |    81 +
 src/os/path.go                                     |   131 +
 src/{pkg => }/os/path_plan9.go                     |     0
 src/os/path_test.go                                |   220 +
 src/{pkg => }/os/path_unix.go                      |     0
 src/{pkg => }/os/path_windows.go                   |     0
 src/{pkg => }/os/pipe_bsd.go                       |     0
 src/{pkg => }/os/pipe_linux.go                     |     0
 src/os/proc.go                                     |    49 +
 src/{pkg => }/os/signal/example_test.go            |     0
 src/os/signal/sig.s                                |    23 +
 src/{pkg => }/os/signal/signal.go                  |     0
 src/{pkg => }/os/signal/signal_stub.go             |     0
 src/os/signal/signal_test.go                       |   208 +
 src/{pkg => }/os/signal/signal_unix.go             |     0
 src/{pkg => }/os/signal/signal_windows_test.go     |     0
 src/{pkg => }/os/stat_darwin.go                    |     0
 src/{pkg => }/os/stat_dragonfly.go                 |     0
 src/{pkg => }/os/stat_freebsd.go                   |     0
 src/{pkg => }/os/stat_linux.go                     |     0
 src/{pkg => }/os/stat_nacl.go                      |     0
 src/{pkg => }/os/stat_netbsd.go                    |     0
 src/{pkg => }/os/stat_openbsd.go                   |     0
 src/{pkg => }/os/stat_plan9.go                     |     0
 src/{pkg => }/os/stat_solaris.go                   |     0
 src/os/stat_windows.go                             |   170 +
 src/{pkg => }/os/str.go                            |     0
 src/{pkg => }/os/sys_bsd.go                        |     0
 src/{pkg => }/os/sys_darwin.go                     |     0
 src/{pkg => }/os/sys_freebsd.go                    |     0
 src/{pkg => }/os/sys_linux.go                      |     0
 src/{pkg => }/os/sys_nacl.go                       |     0
 src/{pkg => }/os/sys_plan9.go                      |     0
 src/{pkg => }/os/sys_solaris.go                    |     0
 src/{pkg => }/os/sys_unix.go                       |     0
 src/{pkg => }/os/sys_windows.go                    |     0
 src/{pkg => }/os/types.go                          |     0
 src/{pkg => }/os/types_notwin.go                   |     0
 src/os/types_windows.go                            |   107 +
 src/{pkg => }/os/user/lookup.go                    |     0
 src/{pkg => }/os/user/lookup_plan9.go              |     0
 src/os/user/lookup_stubs.go                        |    28 +
 src/os/user/lookup_unix.go                         |   112 +
 src/{pkg => }/os/user/lookup_windows.go            |     0
 src/{pkg => }/os/user/user.go                      |     0
 src/{pkg => }/os/user/user_test.go                 |     0
 src/{pkg => }/path/example_test.go                 |     0
 src/{pkg => }/path/filepath/example_unix_test.go   |     0
 src/{pkg => }/path/filepath/export_test.go         |     0
 src/path/filepath/match.go                         |   309 +
 src/path/filepath/match_test.go                    |   211 +
 src/path/filepath/path.go                          |   464 +
 src/path/filepath/path_plan9.go                    |    34 +
 src/path/filepath/path_test.go                     |  1028 ++
 src/path/filepath/path_unix.go                     |    36 +
 src/path/filepath/path_windows.go                  |   110 +
 src/path/filepath/path_windows_test.go             |   113 +
 src/path/filepath/symlink.go                       |    72 +
 src/path/filepath/symlink_unix.go                  |     7 +
 src/path/filepath/symlink_windows.go               |    74 +
 src/{pkg => }/path/match.go                        |     0
 src/{pkg => }/path/match_test.go                   |     0
 src/path/path.go                                   |   210 +
 src/{pkg => }/path/path_test.go                    |     0
 src/pkg/archive/tar/reader.go                      |   817 --
 src/pkg/archive/tar/writer.go                      |   383 -
 src/pkg/archive/tar/writer_test.go                 |   456 -
 src/pkg/archive/zip/reader.go                      |   448 -
 src/pkg/archive/zip/reader_test.go                 |   510 -
 src/pkg/archive/zip/writer.go                      |   351 -
 src/pkg/archive/zip/writer_test.go                 |   145 -
 src/pkg/bufio/bufio.go                             |   698 -
 src/pkg/bufio/bufio_test.go                        |  1417 --
 src/pkg/bufio/scan.go                              |   346 -
 src/pkg/bufio/scan_test.go                         |   406 -
 src/pkg/bytes/bytes.go                             |   697 -
 src/pkg/bytes/bytes.s                              |     5 -
 src/pkg/bytes/bytes_test.go                        |  1234 --
 src/pkg/compress/bzip2/bzip2.go                    |   484 -
 src/pkg/compress/bzip2/bzip2_test.go               |   363 -
 src/pkg/compress/bzip2/move_to_front.go            |    98 -
 src/pkg/compress/flate/fixedhuff.go                |    78 -
 src/pkg/compress/flate/gen.go                      |   165 -
 src/pkg/compress/flate/inflate.go                  |   708 -
 src/pkg/compress/gzip/gunzip.go                    |   255 -
 src/pkg/compress/gzip/gunzip_test.go               |   369 -
 src/pkg/compress/lzw/reader.go                     |   253 -
 src/pkg/compress/zlib/reader.go                    |   132 -
 src/pkg/crypto/aes/asm_amd64.s                     |   289 -
 src/pkg/crypto/cipher/cfb_test.go                  |    38 -
 src/pkg/crypto/cipher/example_test.go              |   283 -
 src/pkg/crypto/crypto.go                           |    85 -
 src/pkg/crypto/ecdsa/ecdsa.go                      |   165 -
 src/pkg/crypto/md5/gen.go                          |   316 -
 src/pkg/crypto/md5/md5.go                          |   134 -
 src/pkg/crypto/md5/md5block.go                     |   265 -
 src/pkg/crypto/md5/md5block_386.s                  |   182 -
 src/pkg/crypto/md5/md5block_amd64.s                |   179 -
 src/pkg/crypto/md5/md5block_amd64p32.s             |   184 -
 src/pkg/crypto/md5/md5block_arm.s                  |   299 -
 src/pkg/crypto/rand/rand_unix.go                   |   138 -
 src/pkg/crypto/rc4/rc4_386.s                       |    53 -
 src/pkg/crypto/rc4/rc4_amd64.s                     |   179 -
 src/pkg/crypto/rc4/rc4_amd64p32.s                  |   192 -
 src/pkg/crypto/rc4/rc4_arm.s                       |    60 -
 src/pkg/crypto/rc4/rc4_asm.go                      |    18 -
 src/pkg/crypto/rc4/rc4_ref.go                      |    13 -
 src/pkg/crypto/rsa/pss.go                          |   282 -
 src/pkg/crypto/rsa/rsa.go                          |   538 -
 src/pkg/crypto/sha1/sha1block_386.s                |   233 -
 src/pkg/crypto/sha1/sha1block_amd64.s              |   216 -
 src/pkg/crypto/sha1/sha1block_amd64p32.s           |   216 -
 src/pkg/crypto/sha1/sha1block_arm.s                |   217 -
 src/pkg/crypto/sha256/sha256block_amd64.s          |   256 -
 src/pkg/crypto/sha512/sha512block_amd64.s          |   273 -
 src/pkg/crypto/subtle/constant_time.go             |    74 -
 src/pkg/crypto/subtle/constant_time_test.go        |   125 -
 src/pkg/crypto/tls/alert.go                        |    77 -
 src/pkg/crypto/tls/cipher_suites.go                |   270 -
 src/pkg/crypto/tls/common.go                       |   568 -
 src/pkg/crypto/tls/conn.go                         |  1024 --
 src/pkg/crypto/tls/conn_test.go                    |   106 -
 src/pkg/crypto/tls/generate_cert.go                |   115 -
 src/pkg/crypto/tls/handshake_client.go             |   601 -
 src/pkg/crypto/tls/handshake_client_test.go        |   439 -
 src/pkg/crypto/tls/handshake_messages.go           |  1344 --
 src/pkg/crypto/tls/handshake_messages_test.go      |   246 -
 src/pkg/crypto/tls/handshake_server.go             |   654 -
 src/pkg/crypto/tls/handshake_server_test.go        |   726 -
 src/pkg/crypto/tls/key_agreement.go                |   407 -
 src/pkg/crypto/tls/tls_test.go                     |   237 -
 src/pkg/crypto/x509/pem_decrypt_test.go            |   223 -
 src/pkg/crypto/x509/pkix/pkix.go                   |   178 -
 src/pkg/crypto/x509/root_unix.go                   |    37 -
 src/pkg/crypto/x509/verify.go                      |   474 -
 src/pkg/crypto/x509/x509.go                        |  1903 ---
 src/pkg/crypto/x509/x509_test.go                   |   952 --
 src/pkg/database/sql/convert_test.go               |   337 -
 src/pkg/database/sql/fakedb_test.go                |   805 --
 src/pkg/database/sql/sql.go                        |  1720 ---
 src/pkg/database/sql/sql_test.go                   |  1949 ---
 src/pkg/debug/dwarf/type.go                        |   659 -
 src/pkg/debug/elf/elf.go                           |  1521 --
 src/pkg/debug/elf/file.go                          |   881 --
 src/pkg/debug/elf/file_test.go                     |   339 -
 src/pkg/debug/gosym/symtab.go                      |   710 -
 src/pkg/debug/pe/file.go                           |   390 -
 src/pkg/debug/pe/file_test.go                      |   236 -
 src/pkg/debug/pe/testdata/gcc-amd64-mingw-exec     |   Bin 37376 -> 0 bytes
 src/pkg/debug/plan9obj/file.go                     |   325 -
 src/pkg/debug/plan9obj/file_test.go                |    81 -
 src/pkg/encoding/ascii85/ascii85.go                |   311 -
 src/pkg/encoding/asn1/asn1.go                      |   908 --
 src/pkg/encoding/asn1/asn1_test.go                 |   814 --
 src/pkg/encoding/asn1/marshal.go                   |   632 -
 src/pkg/encoding/asn1/marshal_test.go              |   157 -
 src/pkg/encoding/base32/base32.go                  |   428 -
 src/pkg/encoding/base32/base32_test.go             |   286 -
 src/pkg/encoding/base64/base64.go                  |   393 -
 src/pkg/encoding/base64/base64_test.go             |   344 -
 src/pkg/encoding/binary/binary.go                  |   639 -
 src/pkg/encoding/binary/binary_test.go             |   397 -
 src/pkg/encoding/csv/writer.go                     |   127 -
 src/pkg/encoding/csv/writer_test.go                |    74 -
 src/pkg/encoding/gob/codec_test.go                 |  1506 --
 src/pkg/encoding/gob/debug.go                      |   705 -
 src/pkg/encoding/gob/decode.go                     |  1317 --
 src/pkg/encoding/gob/decoder.go                    |   237 -
 src/pkg/encoding/gob/encode.go                     |   760 -
 src/pkg/encoding/gob/encoder.go                    |   253 -
 src/pkg/encoding/gob/encoder_test.go               |   862 --
 src/pkg/encoding/gob/gobencdec_test.go             |   797 --
 src/pkg/encoding/gob/timing_test.go                |   109 -
 src/pkg/encoding/gob/type.go                       |   893 --
 src/pkg/encoding/json/decode.go                    |  1050 --
 src/pkg/encoding/json/decode_test.go               |  1356 --
 src/pkg/encoding/json/encode.go                    |  1175 --
 src/pkg/encoding/json/encode_test.go               |   454 -
 src/pkg/encoding/json/stream.go                    |   201 -
 src/pkg/encoding/xml/xml.go                        |  1935 ---
 src/pkg/encoding/xml/xml_test.go                   |   726 -
 src/pkg/flag/flag.go                               |   849 --
 src/pkg/flag/flag_test.go                          |   369 -
 src/pkg/fmt/doc.go                                 |   272 -
 src/pkg/fmt/fmt_test.go                            |  1147 --
 src/pkg/fmt/format.go                              |   492 -
 src/pkg/fmt/print.go                               |  1199 --
 src/pkg/fmt/scan.go                                |  1168 --
 src/pkg/fmt/scan_test.go                           |   960 --
 src/pkg/go/ast/ast.go                              |   995 --
 src/pkg/go/ast/scope.go                            |   162 -
 src/pkg/go/ast/walk.go                             |   384 -
 src/pkg/go/build/build.go                          |  1219 --
 src/pkg/go/build/build_test.go                     |   186 -
 src/pkg/go/build/deps_test.go                      |   442 -
 src/pkg/go/build/doc.go                            |   137 -
 src/pkg/go/build/syslist.go                        |     8 -
 src/pkg/go/doc/exports.go                          |   199 -
 src/pkg/go/doc/headscan.go                         |   113 -
 src/pkg/go/format/format.go                        |   199 -
 src/pkg/go/format/format_test.go                   |   124 -
 src/pkg/go/parser/error_test.go                    |   183 -
 src/pkg/go/parser/interface.go                     |   198 -
 src/pkg/go/parser/parser.go                        |  2478 ----
 src/pkg/go/parser/parser_test.go                   |   431 -
 src/pkg/go/parser/short_test.go                    |    98 -
 src/pkg/go/printer/nodes.go                        |  1599 ---
 src/pkg/go/printer/printer_test.go                 |   569 -
 src/pkg/go/printer/testdata/declarations.golden    |   955 --
 src/pkg/go/printer/testdata/declarations.input     |   967 --
 src/pkg/go/printer/testdata/expressions.golden     |   681 -
 src/pkg/go/printer/testdata/expressions.input      |   710 -
 src/pkg/go/printer/testdata/expressions.raw        |   681 -
 src/pkg/go/printer/testdata/statements.golden      |   635 -
 src/pkg/go/printer/testdata/statements.input       |   550 -
 src/pkg/go/token/position.go                       |   464 -
 src/pkg/go/token/position_test.go                  |   238 -
 src/pkg/hash/crc32/crc32.go                        |   135 -
 src/pkg/hash/crc32/crc32_amd64.s                   |    64 -
 src/pkg/hash/crc32/crc32_amd64p32.s                |    64 -
 src/pkg/html/template/error.go                     |   197 -
 src/pkg/html/template/escape.go                    |   815 --
 src/pkg/html/template/escape_test.go               |  1692 ---
 src/pkg/html/template/js_test.go                   |   401 -
 src/pkg/html/template/template.go                  |   381 -
 src/pkg/html/template/transition.go                |   550 -
 src/pkg/image/color/palette/gen.go                 |   101 -
 src/pkg/image/color/palette/palette.go             |   504 -
 src/pkg/image/gif/reader.go                        |   460 -
 src/pkg/image/gif/reader_test.go                   |   201 -
 src/pkg/image/gif/writer.go                        |   323 -
 src/pkg/image/gif/writer_test.go                   |   204 -
 src/pkg/image/image.go                             |   904 --
 src/pkg/image/jpeg/huffman.go                      |   219 -
 src/pkg/image/jpeg/reader.go                       |   377 -
 src/pkg/image/jpeg/reader_test.go                  |   225 -
 src/pkg/image/jpeg/scan.go                         |   439 -
 src/pkg/image/jpeg/writer.go                       |   553 -
 src/pkg/image/jpeg/writer_test.go                  |   204 -
 src/pkg/image/png/paeth.go                         |    70 -
 src/pkg/image/png/paeth_test.go                    |    91 -
 src/pkg/image/png/reader.go                        |   699 -
 src/pkg/image/png/reader_test.go                   |   350 -
 src/pkg/image/png/writer.go                        |   482 -
 src/pkg/image/png/writer_test.go                   |   191 -
 src/pkg/image/ycbcr.go                             |   153 -
 src/pkg/index/suffixarray/suffixarray_test.go      |   304 -
 src/pkg/io/io.go                                   |   493 -
 src/pkg/log/syslog/syslog_test.go                  |   358 -
 src/pkg/log/syslog/syslog_unix.go                  |    31 -
 src/pkg/math/abs_386.s                             |    12 -
 src/pkg/math/abs_amd64.s                           |    14 -
 src/pkg/math/abs_arm.s                             |    13 -
 src/pkg/math/all_test.go                           |  2935 ----
 src/pkg/math/asin_386.s                            |    30 -
 src/pkg/math/asin_amd64.s                          |    11 -
 src/pkg/math/asin_arm.s                            |    11 -
 src/pkg/math/atan2_386.s                           |    13 -
 src/pkg/math/atan2_amd64.s                         |     8 -
 src/pkg/math/atan2_arm.s                           |     8 -
 src/pkg/math/atan_386.s                            |    13 -
 src/pkg/math/atan_amd64.s                          |     8 -
 src/pkg/math/atan_arm.s                            |     8 -
 src/pkg/math/big/arith_386.s                       |   278 -
 src/pkg/math/big/arith_amd64.s                     |   401 -
 src/pkg/math/big/arith_amd64p32.s                  |    41 -
 src/pkg/math/big/arith_arm.s                       |   300 -
 src/pkg/math/big/int.go                            |  1011 --
 src/pkg/math/big/int_test.go                       |  1601 ---
 src/pkg/math/big/rat.go                            |   600 -
 src/pkg/math/big/rat_test.go                       |   994 --
 src/pkg/math/dim_386.s                             |    14 -
 src/pkg/math/dim_amd64.s                           |   144 -
 src/pkg/math/dim_arm.s                             |    14 -
 src/pkg/math/exp2_386.s                            |    40 -
 src/pkg/math/exp2_amd64.s                          |     8 -
 src/pkg/math/exp2_arm.s                            |     8 -
 src/pkg/math/exp_386.s                             |    41 -
 src/pkg/math/exp_amd64.s                           |   114 -
 src/pkg/math/exp_arm.s                             |     8 -
 src/pkg/math/expm1_386.s                           |    57 -
 src/pkg/math/expm1_amd64.s                         |     8 -
 src/pkg/math/expm1_arm.s                           |     8 -
 src/pkg/math/floor_386.s                           |    46 -
 src/pkg/math/floor_amd64.s                         |    76 -
 src/pkg/math/floor_arm.s                           |    14 -
 src/pkg/math/frexp_386.s                           |    25 -
 src/pkg/math/frexp_amd64.s                         |     8 -
 src/pkg/math/frexp_arm.s                           |     8 -
 src/pkg/math/hypot_386.s                           |    59 -
 src/pkg/math/hypot_amd64.s                         |    52 -
 src/pkg/math/hypot_arm.s                           |     8 -
 src/pkg/math/ldexp_386.s                           |    14 -
 src/pkg/math/ldexp_amd64.s                         |     8 -
 src/pkg/math/ldexp_arm.s                           |     8 -
 src/pkg/math/log10_386.s                           |    21 -
 src/pkg/math/log10_amd64.s                         |    11 -
 src/pkg/math/log10_arm.s                           |    11 -
 src/pkg/math/log1p_386.s                           |    27 -
 src/pkg/math/log1p_amd64.s                         |     8 -
 src/pkg/math/log1p_arm.s                           |     8 -
 src/pkg/math/log_386.s                             |    13 -
 src/pkg/math/log_amd64.s                           |   111 -
 src/pkg/math/log_arm.s                             |     8 -
 src/pkg/math/mod_386.s                             |    17 -
 src/pkg/math/mod_amd64.s                           |     8 -
 src/pkg/math/mod_arm.s                             |     8 -
 src/pkg/math/modf_386.s                            |    21 -
 src/pkg/math/modf_amd64.s                          |     8 -
 src/pkg/math/modf_arm.s                            |     8 -
 src/pkg/math/nextafter.go                          |    27 -
 src/pkg/math/remainder_386.s                       |    17 -
 src/pkg/math/remainder_amd64.s                     |     8 -
 src/pkg/math/remainder_arm.s                       |     8 -
 src/pkg/math/sin_386.s                             |    47 -
 src/pkg/math/sin_amd64.s                           |    11 -
 src/pkg/math/sin_arm.s                             |    11 -
 src/pkg/math/sincos_386.s                          |    28 -
 src/pkg/math/sincos_amd64.s                        |   145 -
 src/pkg/math/sincos_arm.s                          |     8 -
 src/pkg/math/sqrt.go                               |   143 -
 src/pkg/math/sqrt_386.s                            |    12 -
 src/pkg/math/sqrt_amd64.s                          |    11 -
 src/pkg/math/sqrt_arm.s                            |    12 -
 src/pkg/math/tan_386.s                             |    28 -
 src/pkg/math/tan_amd64.s                           |     8 -
 src/pkg/math/tan_arm.s                             |     8 -
 src/pkg/mime/multipart/example_test.go             |    53 -
 src/pkg/mime/multipart/multipart.go                |   349 -
 src/pkg/mime/multipart/writer_test.go              |   113 -
 src/pkg/mime/type.go                               |    77 -
 src/pkg/mime/type_plan9.go                         |    53 -
 src/pkg/mime/type_test.go                          |    29 -
 src/pkg/mime/type_unix.go                          |    60 -
 src/pkg/mime/type_windows.go                       |    63 -
 src/pkg/net/cgo_linux.go                           |    22 -
 src/pkg/net/conn_test.go                           |   124 -
 src/pkg/net/dial.go                                |   305 -
 src/pkg/net/dial_test.go                           |   536 -
 src/pkg/net/dnsclient.go                           |   251 -
 src/pkg/net/dnsclient_unix.go                      |   364 -
 src/pkg/net/dnsclient_unix_test.go                 |   159 -
 src/pkg/net/dnsconfig_unix.go                      |   109 -
 src/pkg/net/dnsconfig_unix_test.go                 |    46 -
 src/pkg/net/empty.c                                |     8 -
 src/pkg/net/fd_unix.go                             |   518 -
 src/pkg/net/fd_windows.go                          |   644 -
 src/pkg/net/file_test.go                           |   205 -
 src/pkg/net/file_unix.go                           |   139 -
 src/pkg/net/hosts.go                               |    86 -
 src/pkg/net/http/chunked.go                        |   203 -
 src/pkg/net/http/chunked_test.go                   |   159 -
 src/pkg/net/http/client.go                         |   487 -
 src/pkg/net/http/client_test.go                    |  1038 --
 src/pkg/net/http/cookie.go                         |   363 -
 src/pkg/net/http/cookie_test.go                    |   380 -
 src/pkg/net/http/cookiejar/jar.go                  |   497 -
 src/pkg/net/http/export_test.go                    |    72 -
 src/pkg/net/http/fs.go                             |   549 -
 src/pkg/net/http/fs_test.go                        |   858 --
 src/pkg/net/http/httptest/server.go                |   228 -
 src/pkg/net/http/httptest/server_test.go           |    53 -
 src/pkg/net/http/httputil/chunked.go               |   203 -
 src/pkg/net/http/httputil/chunked_test.go          |   159 -
 src/pkg/net/http/httputil/dump.go                  |   276 -
 src/pkg/net/http/httputil/dump_test.go             |   263 -
 src/pkg/net/http/httputil/httputil.go              |    32 -
 src/pkg/net/http/httputil/reverseproxy.go          |   211 -
 src/pkg/net/http/pprof/pprof.go                    |   205 -
 src/pkg/net/http/readrequest_test.go               |   331 -
 src/pkg/net/http/request.go                        |   875 --
 src/pkg/net/http/request_test.go                   |   610 -
 src/pkg/net/http/requestwrite_test.go              |   565 -
 src/pkg/net/http/response_test.go                  |   645 -
 src/pkg/net/http/serve_test.go                     |  2848 ----
 src/pkg/net/http/server.go                         |  2052 ---
 src/pkg/net/http/transfer.go                       |   730 -
 src/pkg/net/http/transport.go                      |  1208 --
 src/pkg/net/http/transport_test.go                 |  2173 ---
 src/pkg/net/http/z_last_test.go                    |    97 -
 src/pkg/net/ip.go                                  |   681 -
 src/pkg/net/ip_test.go                             |   439 -
 src/pkg/net/ipraw_test.go                          |   289 -
 src/pkg/net/iprawsock_posix.go                     |   227 -
 src/pkg/net/ipsock_posix.go                        |   177 -
 src/pkg/net/lookup.go                              |   137 -
 src/pkg/net/lookup_test.go                         |   137 -
 src/pkg/net/lookup_unix.go                         |   168 -
 src/pkg/net/lookup_windows.go                      |   322 -
 src/pkg/net/mail/message.go                        |   545 -
 src/pkg/net/mail/message_test.go                   |   304 -
 src/pkg/net/multicast_test.go                      |   188 -
 src/pkg/net/net.go                                 |   426 -
 src/pkg/net/parse.go                               |   247 -
 src/pkg/net/parse_test.go                          |    53 -
 src/pkg/net/port_test.go                           |    53 -
 src/pkg/net/port_unix.go                           |    73 -
 src/pkg/net/rpc/client.go                          |   317 -
 src/pkg/net/rpc/client_test.go                     |    36 -
 src/pkg/net/rpc/debug.go                           |    93 -
 src/pkg/net/rpc/server.go                          |   686 -
 src/pkg/net/singleflight.go                        |    53 -
 src/pkg/net/smtp/smtp_test.go                      |   694 -
 src/pkg/net/sock_bsd.go                            |    37 -
 src/pkg/net/sock_posix.go                          |   192 -
 src/pkg/net/sock_solaris.go                        |    13 -
 src/pkg/net/sockopt_bsd.go                         |    54 -
 src/pkg/net/sockopt_posix.go                       |   141 -
 src/pkg/net/sockoptip_bsd.go                       |    34 -
 src/pkg/net/sockoptip_posix.go                     |    57 -
 src/pkg/net/sockoptip_stub.go                      |    39 -
 src/pkg/net/tcpsock_posix.go                       |   299 -
 src/pkg/net/tcpsockopt_darwin.go                   |    27 -
 src/pkg/net/tcpsockopt_dragonfly.go                |    29 -
 src/pkg/net/tcpsockopt_openbsd.go                  |    27 -
 src/pkg/net/tcpsockopt_posix.go                    |    20 -
 src/pkg/net/tcpsockopt_solaris.go                  |    27 -
 src/pkg/net/tcpsockopt_unix.go                     |    31 -
 src/pkg/net/tcpsockopt_windows.go                  |    34 -
 src/pkg/net/testdata/resolv.conf                   |     6 -
 src/pkg/net/udp_test.go                            |   257 -
 src/pkg/net/udpsock_posix.go                       |   268 -
 src/pkg/net/unicast_posix_test.go                  |   466 -
 src/pkg/net/unix_test.go                           |   326 -
 src/pkg/net/unixsock_posix.go                      |   373 -
 src/pkg/net/url/example_test.go                    |    41 -
 src/pkg/net/url/url.go                             |   700 -
 src/pkg/net/url/url_test.go                        |   905 --
 src/pkg/net/z_last_test.go                         |    37 -
 src/pkg/os/dir_unix.go                             |    58 -
 src/pkg/os/env.go                                  |   103 -
 src/pkg/os/env_test.go                             |    70 -
 src/pkg/os/error_plan9.go                          |    53 -
 src/pkg/os/exec/exec.go                            |   493 -
 src/pkg/os/exec/exec_test.go                       |   726 -
 src/pkg/os/exec_unix.go                            |    73 -
 src/pkg/os/exec_windows.go                         |   115 -
 src/pkg/os/file.go                                 |   257 -
 src/pkg/os/file_plan9.go                           |   468 -
 src/pkg/os/file_posix.go                           |   169 -
 src/pkg/os/file_unix.go                            |   314 -
 src/pkg/os/file_windows.go                         |   495 -
 src/pkg/os/getwd.go                                |   119 -
 src/pkg/os/os_test.go                              |  1339 --
 src/pkg/os/path.go                                 |   123 -
 src/pkg/os/path_test.go                            |   215 -
 src/pkg/os/proc.go                                 |    36 -
 src/pkg/os/signal/sig.s                            |    23 -
 src/pkg/os/signal/signal_test.go                   |   208 -
 src/pkg/os/stat_windows.go                         |   160 -
 src/pkg/os/types_windows.go                        |   104 -
 src/pkg/os/user/lookup_stubs.go                    |    28 -
 src/pkg/os/user/lookup_unix.go                     |   112 -
 src/pkg/path/filepath/match.go                     |   309 -
 src/pkg/path/filepath/match_test.go                |   206 -
 src/pkg/path/filepath/path.go                      |   467 -
 src/pkg/path/filepath/path_plan9.go                |    30 -
 src/pkg/path/filepath/path_test.go                 |  1017 --
 src/pkg/path/filepath/path_unix.go                 |    32 -
 src/pkg/path/filepath/path_windows.go              |   105 -
 src/pkg/path/filepath/path_windows_test.go         |    93 -
 src/pkg/path/filepath/symlink.go                   |    67 -
 src/pkg/path/filepath/symlink_windows.go           |    69 -
 src/pkg/path/path.go                               |   218 -
 src/pkg/reflect/all_test.go                        |  3841 ------
 src/pkg/reflect/asm_386.s                          |    27 -
 src/pkg/reflect/asm_amd64.s                        |    27 -
 src/pkg/reflect/asm_amd64p32.s                     |    27 -
 src/pkg/reflect/asm_arm.s                          |    27 -
 src/pkg/reflect/export_test.go                     |    19 -
 src/pkg/reflect/makefunc.go                        |   120 -
 src/pkg/reflect/type.go                            |  1926 ---
 src/pkg/reflect/value.go                           |  2684 ----
 src/pkg/regexp/all_test.go                         |   645 -
 src/pkg/regexp/onepass.go                          |   582 -
 src/pkg/regexp/regexp.go                           |  1120 --
 src/pkg/regexp/syntax/doc.go                       |   131 -
 src/pkg/regexp/syntax/parse.go                     |  1863 ---
 src/pkg/regexp/syntax/parse_test.go                |   559 -
 src/pkg/regexp/syntax/regexp.go                    |   319 -
 src/pkg/runtime/Makefile                           |     5 -
 src/pkg/runtime/alg.goc                            |   549 -
 src/pkg/runtime/arch_386.h                         |    16 -
 src/pkg/runtime/arch_amd64.h                       |    20 -
 src/pkg/runtime/arch_amd64p32.h                    |    16 -
 src/pkg/runtime/arch_arm.h                         |    12 -
 src/pkg/runtime/asm_386.s                          |  2166 ---
 src/pkg/runtime/asm_amd64.s                        |  2200 ---
 src/pkg/runtime/asm_amd64p32.s                     |  1073 --
 src/pkg/runtime/asm_arm.s                          |  1179 --
 src/pkg/runtime/atomic_386.c                       |    46 -
 src/pkg/runtime/atomic_amd64x.c                    |    29 -
 src/pkg/runtime/atomic_arm.c                       |   169 -
 src/pkg/runtime/callback_windows.c                 |    77 -
 src/pkg/runtime/cgo/asm_386.s                      |    31 -
 src/pkg/runtime/cgo/asm_amd64.s                    |    47 -
 src/pkg/runtime/cgo/asm_arm.s                      |    24 -
 src/pkg/runtime/cgo/asm_nacl_amd64p32.s            |    13 -
 src/pkg/runtime/cgo/callbacks.c                    |   102 -
 src/pkg/runtime/cgo/cgo.go                         |    32 -
 src/pkg/runtime/cgo/dragonfly.c                    |    13 -
 src/pkg/runtime/cgo/freebsd.c                      |    13 -
 src/pkg/runtime/cgo/gcc_arm.S                      |    46 -
 src/pkg/runtime/cgo/gcc_darwin_386.c               |   165 -
 src/pkg/runtime/cgo/gcc_darwin_amd64.c             |   135 -
 src/pkg/runtime/cgo/gcc_dragonfly_386.c            |    77 -
 src/pkg/runtime/cgo/gcc_dragonfly_amd64.c          |    77 -
 src/pkg/runtime/cgo/gcc_freebsd_386.c              |    77 -
 src/pkg/runtime/cgo/gcc_freebsd_amd64.c            |    77 -
 src/pkg/runtime/cgo/gcc_freebsd_arm.c              |    89 -
 src/pkg/runtime/cgo/gcc_linux_386.c                |    80 -
 src/pkg/runtime/cgo/gcc_linux_amd64.c              |    75 -
 src/pkg/runtime/cgo/gcc_linux_arm.c                |    77 -
 src/pkg/runtime/cgo/gcc_netbsd_386.c               |    76 -
 src/pkg/runtime/cgo/gcc_netbsd_amd64.c             |    77 -
 src/pkg/runtime/cgo/gcc_netbsd_arm.c               |    73 -
 src/pkg/runtime/cgo/gcc_openbsd_386.c              |   165 -
 src/pkg/runtime/cgo/gcc_openbsd_amd64.c            |   166 -
 src/pkg/runtime/cgo/gcc_setenv.c                   |    16 -
 src/pkg/runtime/cgo/gcc_windows_386.c              |    62 -
 src/pkg/runtime/cgo/gcc_windows_amd64.c            |    62 -
 src/pkg/runtime/cgo/libcgo.h                       |    61 -
 src/pkg/runtime/cgo/netbsd.c                       |    13 -
 src/pkg/runtime/cgo/openbsd.c                      |    21 -
 src/pkg/runtime/cgo/setenv.c                       |    10 -
 src/pkg/runtime/cgocall.c                          |   322 -
 src/pkg/runtime/cgocall.h                          |    12 -
 src/pkg/runtime/chan.goc                           |  1155 --
 src/pkg/runtime/chan.h                             |    75 -
 src/pkg/runtime/chan_test.go                       |   711 -
 src/pkg/runtime/complex.goc                        |    58 -
 src/pkg/runtime/cpuprof.goc                        |   433 -
 src/pkg/runtime/crash_cgo_test.go                  |   119 -
 src/pkg/runtime/crash_test.go                      |   366 -
 src/pkg/runtime/debug.go                           |   172 -
 src/pkg/runtime/debug/garbage.go                   |   153 -
 src/pkg/runtime/debug/garbage_test.go              |   102 -
 src/pkg/runtime/debug/stack_test.go                |    62 -
 src/pkg/runtime/defs.c                             |    14 -
 src/pkg/runtime/defs1_linux.go                     |    37 -
 src/pkg/runtime/defs2_linux.go                     |   146 -
 src/pkg/runtime/defs_arm_linux.go                  |   124 -
 src/pkg/runtime/defs_darwin_386.h                  |   392 -
 src/pkg/runtime/defs_darwin_amd64.h                |   395 -
 src/pkg/runtime/defs_dragonfly.go                  |   126 -
 src/pkg/runtime/defs_dragonfly_386.h               |   198 -
 src/pkg/runtime/defs_dragonfly_amd64.h             |   208 -
 src/pkg/runtime/defs_freebsd.go                    |   133 -
 src/pkg/runtime/defs_freebsd_386.h                 |   213 -
 src/pkg/runtime/defs_freebsd_amd64.h               |   224 -
 src/pkg/runtime/defs_freebsd_arm.h                 |   186 -
 src/pkg/runtime/defs_linux.go                      |   123 -
 src/pkg/runtime/defs_linux_386.h                   |   211 -
 src/pkg/runtime/defs_linux_amd64.h                 |   254 -
 src/pkg/runtime/defs_linux_arm.h                   |   168 -
 src/pkg/runtime/defs_nacl_amd64p32.h               |    90 -
 src/pkg/runtime/defs_netbsd.go                     |   125 -
 src/pkg/runtime/defs_netbsd_386.h                  |   182 -
 src/pkg/runtime/defs_netbsd_amd64.h                |   194 -
 src/pkg/runtime/defs_netbsd_arm.h                  |   184 -
 src/pkg/runtime/defs_openbsd.go                    |   121 -
 src/pkg/runtime/defs_openbsd_386.h                 |   168 -
 src/pkg/runtime/defs_openbsd_amd64.h               |   179 -
 src/pkg/runtime/defs_plan9_386.h                   |    29 -
 src/pkg/runtime/defs_plan9_amd64.h                 |    34 -
 src/pkg/runtime/defs_solaris.go                    |   156 -
 src/pkg/runtime/defs_solaris_amd64.h               |   254 -
 src/pkg/runtime/defs_windows.go                    |    70 -
 src/pkg/runtime/defs_windows_386.h                 |   113 -
 src/pkg/runtime/defs_windows_amd64.h               |   128 -
 src/pkg/runtime/env_plan9.c                        |    42 -
 src/pkg/runtime/env_posix.c                        |    73 -
 src/pkg/runtime/error.go                           |   124 -
 src/pkg/runtime/export_futex_test.go               |    13 -
 src/pkg/runtime/export_test.go                     |    92 -
 src/pkg/runtime/extern.go                          |   205 -
 src/pkg/runtime/funcdata.h                         |    24 -
 src/pkg/runtime/gc_test.go                         |   236 -
 src/pkg/runtime/hash_test.go                       |   512 -
 src/pkg/runtime/hashmap.goc                        |  1078 --
 src/pkg/runtime/hashmap.h                          |   147 -
 src/pkg/runtime/hashmap_fast.c                     |   233 -
 src/pkg/runtime/heapdump.c                         |   981 --
 src/pkg/runtime/iface.goc                          |   620 -
 src/pkg/runtime/lfstack.goc                        |    81 -
 src/pkg/runtime/lock_futex.c                       |   201 -
 src/pkg/runtime/lock_sema.c                        |   266 -
 src/pkg/runtime/malloc.goc                         |   939 --
 src/pkg/runtime/malloc.h                           |   643 -
 src/pkg/runtime/malloc1.go                         |    26 -
 src/pkg/runtime/malloc_test.go                     |   156 -
 src/pkg/runtime/mallocrand.go                      |    93 -
 src/pkg/runtime/mallocrep.go                       |    72 -
 src/pkg/runtime/mallocrep1.go                      |   144 -
 src/pkg/runtime/map_test.go                        |   477 -
 src/pkg/runtime/mapspeed_test.go                   |   300 -
 src/pkg/runtime/mcache.c                           |   130 -
 src/pkg/runtime/mcentral.c                         |   307 -
 src/pkg/runtime/mem.go                             |    75 -
 src/pkg/runtime/mem_darwin.c                       |    80 -
 src/pkg/runtime/mem_dragonfly.c                    |   103 -
 src/pkg/runtime/mem_freebsd.c                      |    98 -
 src/pkg/runtime/mem_linux.c                        |   160 -
 src/pkg/runtime/mem_nacl.c                         |   118 -
 src/pkg/runtime/mem_netbsd.c                       |    98 -
 src/pkg/runtime/mem_openbsd.c                      |    98 -
 src/pkg/runtime/mem_plan9.c                        |    82 -
 src/pkg/runtime/mem_solaris.c                      |    99 -
 src/pkg/runtime/mem_windows.c                      |   118 -
 src/pkg/runtime/memclr_386.s                       |   127 -
 src/pkg/runtime/memclr_amd64.s                     |   116 -
 src/pkg/runtime/memclr_arm.s                       |    87 -
 src/pkg/runtime/memclr_plan9_386.s                 |    50 -
 src/pkg/runtime/memclr_plan9_amd64.s               |    48 -
 src/pkg/runtime/memmove_386.s                      |   175 -
 src/pkg/runtime/memmove_amd64.s                    |   207 -
 src/pkg/runtime/memmove_arm.s                      |   261 -
 src/pkg/runtime/memmove_nacl_amd64p32.s            |    46 -
 src/pkg/runtime/memmove_plan9_386.s                |   127 -
 src/pkg/runtime/memmove_plan9_amd64.s              |   126 -
 src/pkg/runtime/memmove_test.go                    |   243 -
 src/pkg/runtime/mfinal_test.go                     |   239 -
 src/pkg/runtime/mgc0.c                             |  2892 ----
 src/pkg/runtime/mgc0.go                            |    27 -
 src/pkg/runtime/mgc0.h                             |    87 -
 src/pkg/runtime/mheap.c                            |   932 --
 src/pkg/runtime/mprof.goc                          |   527 -
 src/pkg/runtime/msize.c                            |   184 -
 src/pkg/runtime/netpoll.goc                        |   467 -
 src/pkg/runtime/netpoll_epoll.c                    |   102 -
 src/pkg/runtime/netpoll_kqueue.c                   |   111 -
 src/pkg/runtime/netpoll_nacl.c                     |    37 -
 src/pkg/runtime/netpoll_solaris.c                  |   268 -
 src/pkg/runtime/netpoll_windows.c                  |   163 -
 src/pkg/runtime/noasm_arm.goc                      |    74 -
 src/pkg/runtime/os_darwin.c                        |   529 -
 src/pkg/runtime/os_darwin.h                        |    42 -
 src/pkg/runtime/os_dragonfly.c                     |   292 -
 src/pkg/runtime/os_dragonfly.h                     |    29 -
 src/pkg/runtime/os_freebsd.c                       |   300 -
 src/pkg/runtime/os_freebsd.h                       |    29 -
 src/pkg/runtime/os_freebsd_arm.c                   |    24 -
 src/pkg/runtime/os_linux.c                         |   342 -
 src/pkg/runtime/os_linux.h                         |    40 -
 src/pkg/runtime/os_linux_386.c                     |    38 -
 src/pkg/runtime/os_linux_arm.c                     |    80 -
 src/pkg/runtime/os_nacl.c                          |   278 -
 src/pkg/runtime/os_netbsd.c                        |   338 -
 src/pkg/runtime/os_netbsd.h                        |    30 -
 src/pkg/runtime/os_netbsd_arm.c                    |    34 -
 src/pkg/runtime/os_openbsd.c                       |   312 -
 src/pkg/runtime/os_openbsd.h                       |    25 -
 src/pkg/runtime/os_plan9.c                         |   418 -
 src/pkg/runtime/os_plan9.h                         |    89 -
 src/pkg/runtime/os_plan9_386.c                     |   150 -
 src/pkg/runtime/os_plan9_amd64.c                   |   158 -
 src/pkg/runtime/os_solaris.c                       |   583 -
 src/pkg/runtime/os_solaris.h                       |    51 -
 src/pkg/runtime/os_windows.c                       |   517 -
 src/pkg/runtime/os_windows.h                       |    36 -
 src/pkg/runtime/os_windows_386.c                   |   138 -
 src/pkg/runtime/os_windows_amd64.c                 |   144 -
 src/pkg/runtime/panic.c                            |   566 -
 src/pkg/runtime/parfor.c                           |   199 -
 src/pkg/runtime/pprof/pprof.go                     |   679 -
 src/pkg/runtime/pprof/pprof_test.go                |   403 -
 src/pkg/runtime/print.c                            |   393 -
 src/pkg/runtime/proc.c                             |  3153 -----
 src/pkg/runtime/proc_test.go                       |   476 -
 src/pkg/runtime/race.c                             |   292 -
 src/pkg/runtime/race.go                            |    31 -
 src/pkg/runtime/race/README                        |    12 -
 src/pkg/runtime/race/race.go                       |    15 -
 src/pkg/runtime/race/race_darwin_amd64.syso        |   Bin 222964 -> 0 bytes
 src/pkg/runtime/race/race_linux_amd64.syso         |   Bin 243208 -> 0 bytes
 src/pkg/runtime/race/race_windows_amd64.syso       |   Bin 210859 -> 0 bytes
 src/pkg/runtime/race/testdata/atomic_test.go       |   290 -
 src/pkg/runtime/race/testdata/chan_test.go         |   659 -
 src/pkg/runtime/race/testdata/map_test.go          |   240 -
 src/pkg/runtime/race/testdata/mop_test.go          |  1957 ---
 src/pkg/runtime/race/testdata/slice_test.go        |   485 -
 src/pkg/runtime/race0.c                            |   124 -
 src/pkg/runtime/race_amd64.s                       |   244 -
 src/pkg/runtime/rdebug.goc                         |    27 -
 src/pkg/runtime/rt0_darwin_386.s                   |    16 -
 src/pkg/runtime/rt0_darwin_amd64.s                 |    15 -
 src/pkg/runtime/rt0_dragonfly_386.s                |    16 -
 src/pkg/runtime/rt0_dragonfly_amd64.s              |    15 -
 src/pkg/runtime/rt0_freebsd_386.s                  |    16 -
 src/pkg/runtime/rt0_freebsd_amd64.s                |    15 -
 src/pkg/runtime/rt0_freebsd_arm.s                  |    18 -
 src/pkg/runtime/rt0_linux_386.s                    |    25 -
 src/pkg/runtime/rt0_linux_amd64.s                  |    15 -
 src/pkg/runtime/rt0_linux_arm.s                    |    91 -
 src/pkg/runtime/rt0_nacl_386.s                     |    22 -
 src/pkg/runtime/rt0_nacl_amd64p32.s                |    30 -
 src/pkg/runtime/rt0_netbsd_386.s                   |    16 -
 src/pkg/runtime/rt0_netbsd_amd64.s                 |    15 -
 src/pkg/runtime/rt0_netbsd_arm.s                   |    13 -
 src/pkg/runtime/rt0_openbsd_386.s                  |    16 -
 src/pkg/runtime/rt0_openbsd_amd64.s                |    15 -
 src/pkg/runtime/rt0_plan9_386.s                    |    42 -
 src/pkg/runtime/rt0_plan9_amd64.s                  |    14 -
 src/pkg/runtime/rt0_solaris_amd64.s                |    18 -
 src/pkg/runtime/rt0_windows_386.s                  |    20 -
 src/pkg/runtime/rt0_windows_amd64.s                |    19 -
 src/pkg/runtime/rune.c                             |   231 -
 src/pkg/runtime/runtime.c                          |   396 -
 src/pkg/runtime/runtime.h                          |  1151 --
 src/pkg/runtime/runtime1.goc                       |   128 -
 src/pkg/runtime/runtime_test.go                    |   204 -
 src/pkg/runtime/sema.goc                           |   294 -
 src/pkg/runtime/signal_386.c                       |   122 -
 src/pkg/runtime/signal_amd64x.c                    |   156 -
 src/pkg/runtime/signal_arm.c                       |   122 -
 src/pkg/runtime/signal_nacl_amd64p32.h             |    31 -
 src/pkg/runtime/signal_unix.c                      |   119 -
 src/pkg/runtime/signals_darwin.h                   |    50 -
 src/pkg/runtime/signals_dragonfly.h                |    51 -
 src/pkg/runtime/signals_freebsd.h                  |    51 -
 src/pkg/runtime/signals_linux.h                    |    83 -
 src/pkg/runtime/signals_nacl.h                     |    50 -
 src/pkg/runtime/signals_netbsd.h                   |    51 -
 src/pkg/runtime/signals_openbsd.h                  |    51 -
 src/pkg/runtime/signals_plan9.h                    |    60 -
 src/pkg/runtime/signals_solaris.h                  |    94 -
 src/pkg/runtime/sigqueue.goc                       |   165 -
 src/pkg/runtime/slice.goc                          |   204 -
 src/pkg/runtime/softfloat_arm.c                    |   620 -
 src/pkg/runtime/stack.c                            |   947 --
 src/pkg/runtime/stack.h                            |   113 -
 src/pkg/runtime/stack_gen_test.go                  |  1473 --
 src/pkg/runtime/stack_test.go                      |   283 -
 src/pkg/runtime/string.goc                         |   430 -
 src/pkg/runtime/string_test.go                     |    77 -
 src/pkg/runtime/symtab.goc                         |   332 -
 src/pkg/runtime/sys_darwin_386.s                   |   522 -
 src/pkg/runtime/sys_darwin_amd64.s                 |   480 -
 src/pkg/runtime/sys_dragonfly_386.s                |   369 -
 src/pkg/runtime/sys_dragonfly_amd64.s              |   330 -
 src/pkg/runtime/sys_freebsd_386.s                  |   381 -
 src/pkg/runtime/sys_freebsd_amd64.s                |   345 -
 src/pkg/runtime/sys_freebsd_arm.s                  |   373 -
 src/pkg/runtime/sys_linux_386.s                    |   477 -
 src/pkg/runtime/sys_linux_amd64.s                  |   394 -
 src/pkg/runtime/sys_linux_arm.s                    |   448 -
 src/pkg/runtime/sys_nacl_386.s                     |   243 -
 src/pkg/runtime/sys_nacl_amd64p32.s                |   413 -
 src/pkg/runtime/sys_netbsd_386.s                   |   374 -
 src/pkg/runtime/sys_netbsd_amd64.s                 |   344 -
 src/pkg/runtime/sys_netbsd_arm.s                   |   339 -
 src/pkg/runtime/sys_openbsd_386.s                  |   390 -
 src/pkg/runtime/sys_openbsd_amd64.s                |   336 -
 src/pkg/runtime/sys_plan9_386.s                    |   199 -
 src/pkg/runtime/sys_plan9_amd64.s                  |   237 -
 src/pkg/runtime/sys_solaris_amd64.s                |   267 -
 src/pkg/runtime/sys_windows_386.s                  |   363 -
 src/pkg/runtime/sys_windows_amd64.s                |   377 -
 src/pkg/runtime/syscall_solaris.goc                |   374 -
 src/pkg/runtime/syscall_windows.goc                |   145 -
 src/pkg/runtime/syscall_windows_test.go            |   451 -
 src/pkg/runtime/time.goc                           |   344 -
 src/pkg/runtime/time_plan9_386.c                   |    36 -
 src/pkg/runtime/traceback_arm.c                    |   357 -
 src/pkg/runtime/traceback_x86.c                    |   430 -
 src/pkg/runtime/type.go                            |    56 -
 src/pkg/runtime/type.h                             |   102 -
 src/pkg/runtime/typekind.h                         |    38 -
 src/pkg/runtime/vdso_linux_amd64.c                 |   337 -
 src/pkg/runtime/vlop_386.s                         |    54 -
 src/pkg/runtime/vlop_arm.s                         |   300 -
 src/pkg/runtime/vlrt_386.c                         |   829 --
 src/pkg/runtime/vlrt_arm.c                         |   807 --
 src/pkg/strconv/atoi.go                            |   198 -
 src/pkg/strconv/isprint.go                         |   562 -
 src/pkg/strconv/makeisprint.go                     |   165 -
 src/pkg/strconv/quote.go                           |   443 -
 src/pkg/strconv/quote_test.go                      |   262 -
 src/pkg/strings/replace.go                         |   549 -
 src/pkg/strings/replace_test.go                    |   506 -
 src/pkg/strings/strings.go                         |   725 -
 src/pkg/strings/strings_test.go                    |  1176 --
 src/pkg/sync/atomic/64bit_arm.go                   |    46 -
 src/pkg/sync/atomic/asm_386.s                      |   214 -
 src/pkg/sync/atomic/asm_amd64.s                    |   146 -
 src/pkg/sync/atomic/asm_amd64p32.s                 |   159 -
 src/pkg/sync/atomic/asm_arm.s                      |   197 -
 src/pkg/sync/atomic/asm_freebsd_arm.s              |   109 -
 src/pkg/sync/atomic/asm_linux_arm.s                |   236 -
 src/pkg/sync/atomic/asm_netbsd_arm.s               |   109 -
 src/pkg/sync/atomic/atomic_test.go                 |  1509 --
 src/pkg/sync/atomic/doc.go                         |   151 -
 src/pkg/sync/atomic/export_linux_arm_test.go       |     9 -
 src/pkg/sync/atomic/race.go                        |   276 -
 src/pkg/sync/once.go                               |    43 -
 src/pkg/sync/once_test.go                          |    70 -
 src/pkg/sync/pool.go                               |   223 -
 src/pkg/sync/pool_test.go                          |   151 -
 src/pkg/sync/runtime.go                            |    36 -
 src/pkg/sync/rwmutex.go                            |   128 -
 src/pkg/sync/rwmutex_test.go                       |   212 -
 src/pkg/sync/waitgroup.go                          |   134 -
 src/pkg/syscall/asm_darwin_386.s                   |   142 -
 src/pkg/syscall/asm_darwin_amd64.s                 |   106 -
 src/pkg/syscall/asm_dragonfly_386.s                |   139 -
 src/pkg/syscall/asm_dragonfly_amd64.s              |   133 -
 src/pkg/syscall/asm_freebsd_386.s                  |   142 -
 src/pkg/syscall/asm_freebsd_amd64.s                |   141 -
 src/pkg/syscall/asm_freebsd_arm.s                  |   129 -
 src/pkg/syscall/asm_linux_386.s                    |   186 -
 src/pkg/syscall/asm_linux_amd64.s                  |   126 -
 src/pkg/syscall/asm_linux_arm.s                    |   155 -
 src/pkg/syscall/asm_nacl_386.s                     |    43 -
 src/pkg/syscall/asm_nacl_amd64p32.s                |    41 -
 src/pkg/syscall/asm_netbsd_386.s                   |   142 -
 src/pkg/syscall/asm_netbsd_amd64.s                 |   135 -
 src/pkg/syscall/asm_netbsd_arm.s                   |   126 -
 src/pkg/syscall/asm_openbsd_386.s                  |   142 -
 src/pkg/syscall/asm_openbsd_amd64.s                |   135 -
 src/pkg/syscall/asm_plan9_386.s                    |   164 -
 src/pkg/syscall/asm_plan9_amd64.s                  |   170 -
 src/pkg/syscall/asm_solaris_amd64.s                |     7 -
 src/pkg/syscall/asm_windows_386.s                  |     7 -
 src/pkg/syscall/asm_windows_amd64.s                |     7 -
 src/pkg/syscall/dll_windows.go                     |   279 -
 src/pkg/syscall/env_plan9.go                       |   142 -
 src/pkg/syscall/env_unix.go                        |   119 -
 src/pkg/syscall/env_windows.go                     |    82 -
 src/pkg/syscall/exec_linux.go                      |   262 -
 src/pkg/syscall/exec_windows.go                    |   341 -
 src/pkg/syscall/fs_nacl.go                         |   815 --
 src/pkg/syscall/mkall.sh                           |   263 -
 src/pkg/syscall/mkall_windows.bat                  |    21 -
 src/pkg/syscall/mksyscall.pl                       |   313 -
 src/pkg/syscall/mksyscall_solaris.pl               |   279 -
 src/pkg/syscall/mksyscall_windows.go               |   662 -
 src/pkg/syscall/net_nacl.go                        |   912 --
 src/pkg/syscall/netlink_linux.go                   |   177 -
 src/pkg/syscall/route_bsd.go                       |   224 -
 src/pkg/syscall/so_solaris.go                      |   260 -
 src/pkg/syscall/str.go                             |    20 -
 src/pkg/syscall/syscall.go                         |    81 -
 src/pkg/syscall/syscall_bsd.go                     |   553 -
 src/pkg/syscall/syscall_darwin.go                  |   508 -
 src/pkg/syscall/syscall_linux.go                   |  1025 --
 src/pkg/syscall/syscall_linux_386.go               |   356 -
 src/pkg/syscall/syscall_linux_amd64.go             |   115 -
 src/pkg/syscall/syscall_linux_arm.go               |   196 -
 src/pkg/syscall/syscall_plan9.go                   |   344 -
 src/pkg/syscall/syscall_plan9_386.go               |    32 -
 src/pkg/syscall/syscall_plan9_amd64.go             |    14 -
 src/pkg/syscall/syscall_test.go                    |    30 -
 src/pkg/syscall/syscall_unix.go                    |   299 -
 src/pkg/syscall/syscall_windows.go                 |   936 --
 src/pkg/syscall/time_nacl_386.s                    |    11 -
 src/pkg/syscall/time_nacl_amd64p32.s               |    11 -
 src/pkg/syscall/zsyscall_darwin_386.go             |  1387 --
 src/pkg/syscall/zsyscall_darwin_amd64.go           |  1387 --
 src/pkg/syscall/zsyscall_dragonfly_386.go          |  1287 --
 src/pkg/syscall/zsyscall_dragonfly_amd64.go        |  1287 --
 src/pkg/syscall/zsyscall_freebsd_386.go            |  1298 --
 src/pkg/syscall/zsyscall_freebsd_amd64.go          |  1298 --
 src/pkg/syscall/zsyscall_freebsd_arm.go            |  1298 --
 src/pkg/syscall/zsyscall_linux_386.go              |  1737 ---
 src/pkg/syscall/zsyscall_linux_amd64.go            |  1930 ---
 src/pkg/syscall/zsyscall_linux_arm.go              |  1885 ---
 src/pkg/syscall/zsyscall_netbsd_386.go             |  1224 --
 src/pkg/syscall/zsyscall_netbsd_amd64.go           |  1224 --
 src/pkg/syscall/zsyscall_netbsd_arm.go             |  1224 --
 src/pkg/syscall/zsyscall_openbsd_386.go            |  1262 --
 src/pkg/syscall/zsyscall_openbsd_amd64.go          |  1262 --
 src/pkg/syscall/zsyscall_plan9_386.go              |   282 -
 src/pkg/syscall/zsyscall_plan9_amd64.go            |   282 -
 src/pkg/syscall/zsyscall_solaris_amd64.go          |   883 --
 src/pkg/syscall/zsyscall_windows_386.go            |  1760 ---
 src/pkg/syscall/zsyscall_windows_amd64.go          |  1760 ---
 src/pkg/syscall/zsysnum_plan9_386.go               |    47 -
 src/pkg/syscall/zsysnum_plan9_amd64.go             |    48 -
 src/pkg/syscall/ztypes_windows.go                  |  1044 --
 src/pkg/testing/benchmark.go                       |   444 -
 src/pkg/testing/benchmark_test.go                  |   111 -
 src/pkg/testing/cover.go                           |    86 -
 src/pkg/testing/example.go                         |   100 -
 src/pkg/testing/quick/quick.go                     |   358 -
 src/pkg/testing/testing.go                         |   657 -
 src/pkg/text/scanner/scanner.go                    |   674 -
 src/pkg/text/scanner/scanner_test.go               |   596 -
 src/pkg/text/template/doc.go                       |   405 -
 src/pkg/text/template/exec.go                      |   838 --
 src/pkg/text/template/exec_test.go                 |   989 --
 src/pkg/text/template/funcs.go                     |   580 -
 src/pkg/text/template/parse/node.go                |   722 -
 src/pkg/text/template/parse/parse.go               |   671 -
 src/pkg/text/template/parse/parse_test.go          |   420 -
 src/pkg/time/Makefile                              |     9 -
 src/pkg/time/example_test.go                       |   160 -
 src/pkg/time/format.go                             |  1247 --
 src/pkg/time/format_test.go                        |   517 -
 src/pkg/time/genzabbrs.go                          |   145 -
 src/pkg/time/internal_test.go                      |    92 -
 src/pkg/time/sleep.go                              |   122 -
 src/pkg/time/sleep_test.go                         |   393 -
 src/pkg/time/time.go                               |  1206 --
 src/pkg/time/time_test.go                          |  1081 --
 src/pkg/time/zoneinfo_abbrs_windows.go             |   115 -
 src/pkg/time/zoneinfo_windows.go                   |   270 -
 src/pkg/unicode/Makefile                           |    16 -
 src/pkg/unicode/letter.go                          |   354 -
 src/pkg/unicode/maketables.go                      |  1320 --
 src/pkg/unicode/script_test.go                     |   264 -
 src/pkg/unicode/tables.go                          |  6391 ---------
 src/pkg/unicode/utf8/utf8.go                       |   435 -
 src/pkg/unsafe/unsafe.go                           |    37 -
 src/race.bash                                      |     7 +-
 src/reflect/all_test.go                            |  4158 ++++++
 src/reflect/asm_386.s                              |    30 +
 src/reflect/asm_amd64.s                            |    30 +
 src/reflect/asm_amd64p32.s                         |    30 +
 src/reflect/asm_arm.s                              |    30 +
 src/{pkg => }/reflect/deepequal.go                 |     0
 src/{pkg => }/reflect/example_test.go              |     0
 src/reflect/export_test.go                         |    38 +
 src/reflect/makefunc.go                            |   129 +
 src/{pkg => }/reflect/set_test.go                  |     0
 src/{pkg => }/reflect/tostring_test.go             |     0
 src/reflect/type.go                                |  1929 +++
 src/reflect/value.go                               |  2443 ++++
 src/regexp/all_test.go                             |   656 +
 src/{pkg => }/regexp/example_test.go               |     0
 src/{pkg => }/regexp/exec.go                       |     0
 src/{pkg => }/regexp/exec2_test.go                 |     0
 src/{pkg => }/regexp/exec_test.go                  |     0
 src/{pkg => }/regexp/find_test.go                  |     0
 src/regexp/onepass.go                              |   581 +
 src/{pkg => }/regexp/onepass_test.go               |     0
 src/regexp/regexp.go                               |  1120 ++
 src/{pkg => }/regexp/syntax/compile.go             |     0
 src/regexp/syntax/doc.go                           |   131 +
 src/{pkg => }/regexp/syntax/make_perl_groups.pl    |     0
 src/regexp/syntax/parse.go                         |  1902 +++
 src/regexp/syntax/parse_test.go                    |   572 +
 src/{pkg => }/regexp/syntax/perl_groups.go         |     0
 src/{pkg => }/regexp/syntax/prog.go                |     0
 src/{pkg => }/regexp/syntax/prog_test.go           |     0
 src/regexp/syntax/regexp.go                        |   319 +
 src/{pkg => }/regexp/syntax/simplify.go            |     0
 src/{pkg => }/regexp/syntax/simplify_test.go       |     0
 src/{pkg => }/regexp/testdata/README               |     0
 src/{pkg => }/regexp/testdata/basic.dat            |     0
 src/{pkg => }/regexp/testdata/nullsubexpr.dat      |     0
 .../regexp/testdata/re2-exhaustive.txt.bz2         |   Bin
 src/{pkg => }/regexp/testdata/re2-search.txt       |     0
 src/{pkg => }/regexp/testdata/repetition.dat       |     0
 src/{pkg => }/regexp/testdata/testregex.c          |     0
 src/run.bash                                       |    65 +-
 src/run.rc                                         |     2 +-
 src/runtime/Makefile                               |     5 +
 src/runtime/alg.go                                 |   352 +
 src/{pkg => }/runtime/append_test.go               |     0
 src/runtime/arch_386.go                            |     8 +
 src/runtime/arch_386.h                             |    17 +
 src/runtime/arch_amd64.go                          |     8 +
 src/runtime/arch_amd64.h                           |    25 +
 src/runtime/arch_amd64p32.go                       |     8 +
 src/runtime/arch_amd64p32.h                        |    17 +
 src/runtime/arch_arm.go                            |     8 +
 src/runtime/arch_arm.h                             |    17 +
 src/runtime/asm.s                                  |    14 +
 src/runtime/asm_386.s                              |  2292 +++
 src/runtime/asm_amd64.s                            |  2237 +++
 src/runtime/asm_amd64p32.s                         |  1087 ++
 src/runtime/asm_arm.s                              |  1328 ++
 src/runtime/atomic.go                              |    51 +
 src/runtime/atomic_386.c                           |    46 +
 src/runtime/atomic_amd64x.c                        |    29 +
 src/runtime/atomic_arm.go                          |   155 +
 src/runtime/cgo/asm_386.s                          |    31 +
 src/runtime/cgo/asm_amd64.s                        |    47 +
 src/runtime/cgo/asm_arm.s                          |    24 +
 src/runtime/cgo/asm_nacl_amd64p32.s                |    13 +
 src/runtime/cgo/callbacks.c                        |    83 +
 src/runtime/cgo/cgo.go                             |    26 +
 src/runtime/cgo/dragonfly.c                        |    19 +
 src/runtime/cgo/freebsd.c                          |    19 +
 src/{pkg => }/runtime/cgo/gcc_386.S                |     0
 src/{pkg => }/runtime/cgo/gcc_amd64.S              |     0
 src/runtime/cgo/gcc_android.c                      |    31 +
 src/runtime/cgo/gcc_android_arm.c                  |    43 +
 src/runtime/cgo/gcc_arm.S                          |    42 +
 src/runtime/cgo/gcc_darwin_386.c                   |   148 +
 src/runtime/cgo/gcc_darwin_amd64.c                 |   119 +
 src/runtime/cgo/gcc_dragonfly_386.c                |    70 +
 src/runtime/cgo/gcc_dragonfly_amd64.c              |    70 +
 src/runtime/cgo/gcc_fatalf.c                       |    23 +
 src/runtime/cgo/gcc_freebsd_386.c                  |    70 +
 src/runtime/cgo/gcc_freebsd_amd64.c                |    70 +
 src/runtime/cgo/gcc_freebsd_arm.c                  |    82 +
 src/runtime/cgo/gcc_linux_386.c                    |    72 +
 src/runtime/cgo/gcc_linux_amd64.c                  |    67 +
 src/runtime/cgo/gcc_linux_arm.c                    |    73 +
 src/runtime/cgo/gcc_netbsd_386.c                   |    69 +
 src/runtime/cgo/gcc_netbsd_amd64.c                 |    70 +
 src/runtime/cgo/gcc_netbsd_arm.c                   |    66 +
 src/runtime/cgo/gcc_openbsd_386.c                  |   158 +
 src/runtime/cgo/gcc_openbsd_amd64.c                |   159 +
 src/runtime/cgo/gcc_setenv.c                       |    23 +
 src/{pkg => }/runtime/cgo/gcc_util.c               |     0
 src/runtime/cgo/gcc_windows_386.c                  |    61 +
 src/runtime/cgo/gcc_windows_amd64.c                |    61 +
 src/{pkg => }/runtime/cgo/iscgo.c                  |     0
 src/runtime/cgo/libcgo.h                           |    65 +
 src/runtime/cgo/netbsd.c                           |    19 +
 src/runtime/cgo/openbsd.c                          |    27 +
 src/runtime/cgo/setenv.c                           |    13 +
 src/runtime/cgocall.go                             |   279 +
 src/runtime/cgocall.h                              |    13 +
 src/runtime/cgocallback.go                         |    40 +
 src/runtime/chan.go                                |   655 +
 src/runtime/chan.h                                 |    68 +
 src/runtime/chan_test.go                           |   820 ++
 src/{pkg => }/runtime/closure_test.go              |     0
 src/{pkg => }/runtime/compiler.go                  |     0
 src/runtime/complex.go                             |    52 +
 src/{pkg => }/runtime/complex_test.go              |     0
 src/runtime/cpuprof.go                             |   425 +
 src/runtime/crash_cgo_test.go                      |   196 +
 src/runtime/crash_test.go                          |   515 +
 src/runtime/debug.go                               |    70 +
 .../debug/debug.c => runtime/debug/debug.s}        |     0
 src/runtime/debug/garbage.go                       |   159 +
 src/runtime/debug/garbage_test.go                  |   115 +
 src/{pkg => }/runtime/debug/heapdump_test.go       |     0
 src/{pkg => }/runtime/debug/stack.go               |     0
 src/runtime/debug/stack_test.go                    |    62 +
 src/runtime/debug/stubs.go                         |    20 +
 src/runtime/debug/stubs.s                          |    21 +
 src/runtime/defs.c                                 |    15 +
 src/runtime/defs1_linux.go                         |    37 +
 src/runtime/defs2_linux.go                         |   146 +
 src/runtime/defs_android_arm.h                     |     3 +
 src/runtime/defs_arm_linux.go                      |   124 +
 src/{pkg => }/runtime/defs_darwin.go               |     0
 src/runtime/defs_darwin_386.h                      |   392 +
 src/runtime/defs_darwin_amd64.h                    |   395 +
 src/runtime/defs_dragonfly.go                      |   126 +
 src/runtime/defs_dragonfly_386.h                   |   198 +
 src/runtime/defs_dragonfly_amd64.h                 |   208 +
 src/runtime/defs_freebsd.go                        |   133 +
 src/runtime/defs_freebsd_386.h                     |   213 +
 src/runtime/defs_freebsd_amd64.h                   |   224 +
 src/runtime/defs_freebsd_arm.h                     |   186 +
 src/runtime/defs_linux.go                          |   124 +
 src/runtime/defs_linux_386.h                       |   211 +
 src/runtime/defs_linux_amd64.h                     |   254 +
 src/runtime/defs_linux_arm.h                       |   168 +
 src/{pkg => }/runtime/defs_nacl_386.h              |     0
 src/runtime/defs_nacl_amd64p32.h                   |    90 +
 src/runtime/defs_nacl_arm.h                        |    70 +
 src/runtime/defs_netbsd.go                         |   125 +
 src/{pkg => }/runtime/defs_netbsd_386.go           |     0
 src/runtime/defs_netbsd_386.h                      |   182 +
 src/{pkg => }/runtime/defs_netbsd_amd64.go         |     0
 src/runtime/defs_netbsd_amd64.h                    |   194 +
 src/{pkg => }/runtime/defs_netbsd_arm.go           |     0
 src/runtime/defs_netbsd_arm.h                      |   184 +
 src/runtime/defs_openbsd.go                        |   121 +
 src/runtime/defs_openbsd_386.h                     |   168 +
 src/runtime/defs_openbsd_amd64.h                   |   179 +
 src/runtime/defs_plan9_386.h                       |    26 +
 src/runtime/defs_plan9_amd64.h                     |    34 +
 src/runtime/defs_solaris.go                        |   156 +
 src/{pkg => }/runtime/defs_solaris_amd64.go        |     0
 src/runtime/defs_solaris_amd64.h                   |   254 +
 src/runtime/defs_windows.go                        |    73 +
 src/runtime/defs_windows_386.h                     |   116 +
 src/runtime/defs_windows_amd64.h                   |   131 +
 src/runtime/env_plan9.go                           |    56 +
 src/runtime/env_posix.go                           |    63 +
 src/runtime/error.go                               |   107 +
 src/runtime/export_futex_test.go                   |    10 +
 src/runtime/export_test.go                         |   165 +
 src/runtime/extern.go                              |   168 +
 src/{pkg => }/runtime/float.c                      |     0
 src/runtime/funcdata.h                             |    60 +
 src/{pkg => }/runtime/futex_test.go                |     0
 src/runtime/gc_test.go                             |   292 +
 src/runtime/gcinfo_test.go                         |   193 +
 src/runtime/hash_test.go                           |   572 +
 src/runtime/hashmap.go                             |   953 ++
 src/runtime/hashmap_fast.go                        |   379 +
 src/runtime/heapdump.c                             |   864 ++
 src/runtime/iface.go                               |   439 +
 src/{pkg => }/runtime/iface_test.go                |     0
 src/runtime/lfstack.c                              |    87 +
 src/{pkg => }/runtime/lfstack_test.go              |     0
 src/runtime/lock_futex.go                          |   205 +
 src/runtime/lock_sema.go                           |   270 +
 src/runtime/malloc.c                               |   396 +
 src/runtime/malloc.go                              |   837 ++
 src/runtime/malloc.h                               |   621 +
 src/runtime/malloc_test.go                         |   189 +
 src/runtime/map_test.go                            |   537 +
 src/runtime/mapspeed_test.go                       |   300 +
 src/runtime/mcache.c                               |   115 +
 src/runtime/mcentral.c                             |   214 +
 src/runtime/mem.go                                 |   108 +
 src/runtime/mem_darwin.c                           |    82 +
 src/runtime/mem_dragonfly.c                        |   105 +
 src/runtime/mem_freebsd.c                          |   100 +
 src/runtime/mem_linux.c                            |   162 +
 src/runtime/mem_nacl.c                             |   120 +
 src/runtime/mem_netbsd.c                           |   100 +
 src/runtime/mem_openbsd.c                          |   100 +
 src/runtime/mem_plan9.c                            |   121 +
 src/runtime/mem_solaris.c                          |   101 +
 src/runtime/mem_windows.c                          |   132 +
 src/runtime/memclr_386.s                           |   130 +
 src/runtime/memclr_amd64.s                         |   119 +
 src/runtime/memclr_arm.s                           |    87 +
 src/runtime/memclr_plan9_386.s                     |    51 +
 src/runtime/memclr_plan9_amd64.s                   |    21 +
 src/runtime/memmove_386.s                          |   176 +
 src/runtime/memmove_amd64.s                        |   252 +
 src/runtime/memmove_arm.s                          |   261 +
 src/{pkg => }/runtime/memmove_linux_amd64_test.go  |     0
 src/runtime/memmove_nacl_amd64p32.s                |    46 +
 src/runtime/memmove_plan9_386.s                    |   128 +
 src/runtime/memmove_plan9_amd64.s                  |   127 +
 src/runtime/memmove_test.go                        |   295 +
 src/runtime/mfinal_test.go                         |   246 +
 src/{pkg => }/runtime/mfixalloc.c                  |     0
 src/runtime/mgc0.c                                 |  2010 +++
 src/runtime/mgc0.go                                |   152 +
 src/runtime/mgc0.h                                 |    78 +
 src/runtime/mheap.c                                |   889 ++
 src/{pkg => }/runtime/mknacl.sh                    |     0
 src/runtime/mprof.go                               |   672 +
 src/runtime/msize.c                                |   184 +
 src/runtime/netpoll.go                             |   455 +
 src/runtime/netpoll_epoll.go                       |    97 +
 src/runtime/netpoll_kqueue.go                      |   101 +
 src/runtime/netpoll_nacl.go                        |    26 +
 src/runtime/netpoll_solaris.c                      |   264 +
 src/{pkg => }/runtime/netpoll_stub.c               |     0
 src/runtime/netpoll_windows.c                      |   163 +
 src/runtime/noasm_arm.go                           |    54 +
 src/{pkg => }/runtime/norace_test.go               |     0
 src/runtime/os_android.c                           |    16 +
 src/runtime/os_android.h                           |     1 +
 src/runtime/os_darwin.c                            |   567 +
 src/runtime/os_darwin.go                           |    24 +
 src/runtime/os_darwin.h                            |    43 +
 src/runtime/os_dragonfly.c                         |   312 +
 src/runtime/os_dragonfly.go                        |    20 +
 src/runtime/os_dragonfly.h                         |    30 +
 src/runtime/os_freebsd.c                           |   320 +
 src/runtime/os_freebsd.go                          |    17 +
 src/runtime/os_freebsd.h                           |    29 +
 src/runtime/os_freebsd_arm.c                       |    24 +
 src/runtime/os_linux.c                             |   342 +
 src/runtime/os_linux.go                            |    17 +
 src/runtime/os_linux.h                             |    41 +
 src/runtime/os_linux_386.c                         |    38 +
 src/runtime/os_linux_arm.c                         |    80 +
 src/runtime/os_nacl.c                              |   312 +
 src/runtime/os_nacl.go                             |    39 +
 src/{pkg => }/runtime/os_nacl.h                    |     0
 src/runtime/os_nacl_arm.c                          |    24 +
 src/runtime/os_netbsd.c                            |   368 +
 src/runtime/os_netbsd.go                           |    20 +
 src/runtime/os_netbsd.h                            |    31 +
 src/{pkg => }/runtime/os_netbsd_386.c              |     0
 src/{pkg => }/runtime/os_netbsd_amd64.c            |     0
 src/runtime/os_netbsd_arm.c                        |    34 +
 src/runtime/os_openbsd.c                           |   309 +
 src/runtime/os_openbsd.go                          |    17 +
 src/runtime/os_openbsd.h                           |    26 +
 src/runtime/os_plan9.c                             |   362 +
 src/runtime/os_plan9.go                            |   103 +
 src/runtime/os_plan9.h                             |    93 +
 src/runtime/os_plan9_386.c                         |   150 +
 src/runtime/os_plan9_amd64.c                       |   158 +
 src/runtime/os_solaris.c                           |   557 +
 src/runtime/os_solaris.go                          |   100 +
 src/runtime/os_solaris.h                           |    55 +
 src/runtime/os_windows.c                           |   636 +
 src/runtime/os_windows.go                          |    58 +
 src/runtime/os_windows.h                           |    42 +
 src/runtime/os_windows_386.c                       |   128 +
 src/runtime/os_windows_386.go                      |    11 +
 src/runtime/os_windows_amd64.c                     |   150 +
 src/runtime/os_windows_amd64.go                    |    11 +
 src/runtime/panic.c                                |   200 +
 src/runtime/panic.go                               |   505 +
 src/runtime/parfor.c                               |   226 +
 src/{pkg => }/runtime/parfor_test.go               |     0
 src/runtime/pprof/mprof_test.go                    |    99 +
 src/runtime/pprof/pprof.go                         |   673 +
 src/runtime/pprof/pprof_test.go                    |   452 +
 src/runtime/print1.go                              |   323 +
 src/runtime/proc.c                                 |  3521 +++++
 src/runtime/proc.go                                |   246 +
 src/runtime/proc_test.go                           |   480 +
 src/runtime/race.c                                 |   347 +
 src/runtime/race.go                                |   127 +
 src/{pkg => }/runtime/race.h                       |     0
 src/runtime/race/README                            |    12 +
 src/{pkg => }/runtime/race/doc.go                  |     0
 src/{pkg => }/runtime/race/output_test.go          |     0
 src/runtime/race/race.go                           |    15 +
 src/runtime/race/race_darwin_amd64.syso            |   Bin 0 -> 278328 bytes
 src/runtime/race/race_freebsd_amd64.syso           |   Bin 0 -> 294224 bytes
 src/runtime/race/race_linux_amd64.syso             |   Bin 0 -> 298064 bytes
 src/{pkg => }/runtime/race/race_test.go            |     0
 src/runtime/race/race_unix_test.go                 |    30 +
 src/runtime/race/race_windows_amd64.syso           |   Bin 0 -> 292311 bytes
 src/runtime/race/testdata/atomic_test.go           |   288 +
 src/{pkg => }/runtime/race/testdata/cgo_test.go    |     0
 .../runtime/race/testdata/cgo_test_main.go         |     0
 src/runtime/race/testdata/chan_test.go             |   659 +
 src/{pkg => }/runtime/race/testdata/comp_test.go   |     0
 .../runtime/race/testdata/finalizer_test.go        |     0
 src/{pkg => }/runtime/race/testdata/io_test.go     |     0
 src/runtime/race/testdata/map_test.go              |   333 +
 src/runtime/race/testdata/mop_test.go              |  1957 +++
 src/{pkg => }/runtime/race/testdata/mutex_test.go  |     0
 .../runtime/race/testdata/regression_test.go       |     0
 .../runtime/race/testdata/rwmutex_test.go          |     0
 src/{pkg => }/runtime/race/testdata/select_test.go |     0
 src/runtime/race/testdata/slice_test.go            |   485 +
 src/{pkg => }/runtime/race/testdata/sync_test.go   |     0
 .../runtime/race/testdata/waitgroup_test.go        |     0
 src/runtime/race0.go                               |    37 +
 src/runtime/race_amd64.s                           |   414 +
 src/runtime/rdebug.go                              |    37 +
 src/runtime/rt0_android_arm.s                      |    11 +
 src/runtime/rt0_darwin_386.s                       |    16 +
 src/runtime/rt0_darwin_amd64.s                     |    15 +
 src/runtime/rt0_dragonfly_386.s                    |    16 +
 src/runtime/rt0_dragonfly_amd64.s                  |    15 +
 src/runtime/rt0_freebsd_386.s                      |    16 +
 src/runtime/rt0_freebsd_amd64.s                    |    15 +
 src/runtime/rt0_freebsd_arm.s                      |    18 +
 src/runtime/rt0_linux_386.s                        |    25 +
 src/runtime/rt0_linux_amd64.s                      |    15 +
 src/runtime/rt0_linux_arm.s                        |    91 +
 src/runtime/rt0_nacl_386.s                         |    22 +
 src/runtime/rt0_nacl_amd64p32.s                    |    30 +
 src/runtime/rt0_nacl_arm.s                         |    20 +
 src/runtime/rt0_netbsd_386.s                       |    16 +
 src/runtime/rt0_netbsd_amd64.s                     |    15 +
 src/runtime/rt0_netbsd_arm.s                       |    13 +
 src/runtime/rt0_openbsd_386.s                      |    16 +
 src/runtime/rt0_openbsd_amd64.s                    |    15 +
 src/runtime/rt0_plan9_386.s                        |    23 +
 src/runtime/rt0_plan9_amd64.s                      |    21 +
 src/runtime/rt0_solaris_amd64.s                    |    18 +
 src/runtime/rt0_windows_386.s                      |    20 +
 src/runtime/rt0_windows_amd64.s                    |    19 +
 src/runtime/rune.go                                |   219 +
 src/{pkg => }/runtime/runtime-gdb.py               |     0
 src/runtime/runtime.c                              |   399 +
 src/runtime/runtime.go                             |    60 +
 src/runtime/runtime.h                              |  1132 ++
 src/{pkg => }/runtime/runtime_linux_test.go        |     0
 src/runtime/runtime_test.go                        |   249 +
 src/{pkg => }/runtime/runtime_unix_test.go         |     0
 src/runtime/select.go                              |   651 +
 src/runtime/sema.go                                |   275 +
 src/runtime/signal.c                               |    25 +
 src/runtime/signal_386.c                           |   122 +
 src/runtime/signal_amd64x.c                        |   156 +
 src/runtime/signal_android_386.h                   |     1 +
 src/runtime/signal_android_arm.h                   |     1 +
 src/runtime/signal_arm.c                           |   121 +
 src/{pkg => }/runtime/signal_darwin_386.h          |     0
 src/{pkg => }/runtime/signal_darwin_amd64.h        |     0
 src/{pkg => }/runtime/signal_dragonfly_386.h       |     0
 src/{pkg => }/runtime/signal_dragonfly_amd64.h     |     0
 src/{pkg => }/runtime/signal_freebsd_386.h         |     0
 src/{pkg => }/runtime/signal_freebsd_amd64.h       |     0
 src/{pkg => }/runtime/signal_freebsd_arm.h         |     0
 src/{pkg => }/runtime/signal_linux_386.h           |     0
 src/{pkg => }/runtime/signal_linux_amd64.h         |     0
 src/{pkg => }/runtime/signal_linux_arm.h           |     0
 src/{pkg => }/runtime/signal_nacl_386.h            |     0
 src/runtime/signal_nacl_amd64p32.h                 |    31 +
 src/runtime/signal_nacl_arm.h                      |    28 +
 src/{pkg => }/runtime/signal_netbsd_386.h          |     0
 src/{pkg => }/runtime/signal_netbsd_amd64.h        |     0
 src/{pkg => }/runtime/signal_netbsd_arm.h          |     0
 src/{pkg => }/runtime/signal_openbsd_386.h         |     0
 src/{pkg => }/runtime/signal_openbsd_amd64.h       |     0
 src/{pkg => }/runtime/signal_solaris_amd64.h       |     0
 src/runtime/signal_unix.c                          |   119 +
 src/runtime/signal_unix.go                         |    13 +
 src/{pkg => }/runtime/signal_unix.h                |     0
 src/runtime/signals_android.h                      |     1 +
 src/runtime/signals_darwin.h                       |    53 +
 src/runtime/signals_dragonfly.h                    |    54 +
 src/runtime/signals_freebsd.h                      |    54 +
 src/runtime/signals_linux.h                        |    86 +
 src/runtime/signals_nacl.h                         |    53 +
 src/runtime/signals_netbsd.h                       |    54 +
 src/runtime/signals_openbsd.h                      |    54 +
 src/runtime/signals_plan9.h                        |    63 +
 src/runtime/signals_solaris.h                      |    97 +
 src/{pkg => }/runtime/signals_windows.h            |     0
 src/runtime/sigpanic_unix.go                       |    40 +
 src/runtime/sigqueue.go                            |   173 +
 src/runtime/slice.go                               |   139 +
 src/{pkg => }/runtime/softfloat64.go               |     0
 src/{pkg => }/runtime/softfloat64_test.go          |     0
 src/runtime/softfloat_arm.c                        |   687 +
 src/{pkg => }/runtime/sqrt.go                      |     0
 src/runtime/stack.c                                |   892 ++
 src/runtime/stack.go                               |    13 +
 src/runtime/stack.h                                |   118 +
 src/runtime/stack_test.go                          |   397 +
 src/runtime/string.c                               |   226 +
 src/runtime/string.go                              |   298 +
 src/runtime/string_test.go                         |   160 +
 src/runtime/stubs.go                               |   316 +
 src/runtime/symtab.go                              |   288 +
 src/{pkg => }/runtime/symtab_test.go               |     0
 src/{pkg => }/runtime/sys_arm.c                    |     0
 src/runtime/sys_darwin_386.s                       |   541 +
 src/runtime/sys_darwin_amd64.s                     |   505 +
 src/runtime/sys_dragonfly_386.s                    |   381 +
 src/runtime/sys_dragonfly_amd64.s                  |   344 +
 src/runtime/sys_freebsd_386.s                      |   391 +
 src/runtime/sys_freebsd_amd64.s                    |   357 +
 src/runtime/sys_freebsd_arm.s                      |   382 +
 src/runtime/sys_linux_386.s                        |   489 +
 src/runtime/sys_linux_amd64.s                      |   410 +
 src/runtime/sys_linux_arm.s                        |   461 +
 src/runtime/sys_nacl_386.s                         |   363 +
 src/runtime/sys_nacl_amd64p32.s                    |   459 +
 src/runtime/sys_nacl_arm.s                         |   320 +
 src/runtime/sys_netbsd_386.s                       |   384 +
 src/runtime/sys_netbsd_amd64.s                     |   358 +
 src/runtime/sys_netbsd_arm.s                       |   351 +
 src/runtime/sys_openbsd_386.s                      |   398 +
 src/runtime/sys_openbsd_amd64.s                    |   350 +
 src/runtime/sys_plan9_386.s                        |   249 +
 src/runtime/sys_plan9_amd64.s                      |   254 +
 src/runtime/sys_solaris_amd64.s                    |   351 +
 src/runtime/sys_windows_386.s                      |   433 +
 src/runtime/sys_windows_amd64.s                    |   462 +
 src/{pkg => }/runtime/sys_x86.c                    |     0
 src/{pkg => }/runtime/syscall_nacl.h               |     0
 src/runtime/syscall_solaris.c                      |    23 +
 src/runtime/syscall_solaris.go                     |   322 +
 src/runtime/syscall_windows.go                     |   170 +
 src/runtime/syscall_windows_test.go                |   535 +
 src/runtime/thunk.s                                |   183 +
 src/runtime/thunk_solaris_amd64.s                  |    88 +
 src/runtime/thunk_windows.s                        |    30 +
 src/runtime/time.go                                |   289 +
 src/runtime/tls_arm.s                              |    69 +
 src/runtime/traceback.go                           |   659 +
 src/runtime/type.h                                 |   113 +
 src/runtime/typekind.go                            |    44 +
 src/runtime/typekind.h                             |    38 +
 src/runtime/vdso_linux_amd64.c                     |   371 +
 src/runtime/vlop_386.s                             |    56 +
 src/runtime/vlop_arm.s                             |   317 +
 src/{pkg => }/runtime/vlop_arm_test.go             |     0
 src/runtime/vlrt.c                                 |   914 ++
 src/runtime/vlrt.go                                |   258 +
 src/{pkg => }/sort/example_interface_test.go       |     0
 src/{pkg => }/sort/example_keys_test.go            |     0
 src/{pkg => }/sort/example_multi_test.go           |     0
 src/{pkg => }/sort/example_test.go                 |     0
 src/{pkg => }/sort/example_wrapper_test.go         |     0
 src/{pkg => }/sort/export_test.go                  |     0
 src/{pkg => }/sort/search.go                       |     0
 src/{pkg => }/sort/search_test.go                  |     0
 src/{pkg => }/sort/sort.go                         |     0
 src/{pkg => }/sort/sort_test.go                    |     0
 src/{pkg => }/strconv/atob.go                      |     0
 src/{pkg => }/strconv/atob_test.go                 |     0
 src/{pkg => }/strconv/atof.go                      |     0
 src/{pkg => }/strconv/atof_test.go                 |     0
 src/strconv/atoi.go                                |   198 +
 src/{pkg => }/strconv/atoi_test.go                 |     0
 src/{pkg => }/strconv/decimal.go                   |     0
 src/{pkg => }/strconv/decimal_test.go              |     0
 src/{pkg => }/strconv/extfloat.go                  |     0
 src/{pkg => }/strconv/fp_test.go                   |     0
 src/{pkg => }/strconv/ftoa.go                      |     0
 src/{pkg => }/strconv/ftoa_test.go                 |     0
 src/{pkg => }/strconv/internal_test.go             |     0
 src/strconv/isprint.go                             |   624 +
 src/{pkg => }/strconv/itoa.go                      |     0
 src/{pkg => }/strconv/itoa_test.go                 |     0
 src/strconv/makeisprint.go                         |   187 +
 src/strconv/quote.go                               |   455 +
 src/{pkg => }/strconv/quote_example_test.go        |     0
 src/strconv/quote_test.go                          |   266 +
 src/{pkg => }/strconv/strconv_test.go              |     0
 src/{pkg => }/strconv/testdata/testfp.txt          |     0
 src/{pkg => }/strings/example_test.go              |     0
 src/{pkg => }/strings/export_test.go               |     0
 src/{pkg => }/strings/reader.go                    |     0
 src/{pkg => }/strings/reader_test.go               |     0
 src/strings/replace.go                             |   518 +
 src/strings/replace_test.go                        |   542 +
 src/{pkg => }/strings/search.go                    |     0
 src/{pkg => }/strings/search_test.go               |     0
 src/strings/strings.go                             |   762 +
 src/{pkg => }/strings/strings.s                    |     0
 src/{pkg => }/strings/strings_decl.go              |     0
 src/strings/strings_test.go                        |  1204 ++
 src/sync/atomic/64bit_arm.go                       |    58 +
 src/sync/atomic/asm_386.s                          |   214 +
 src/sync/atomic/asm_amd64.s                        |   146 +
 src/sync/atomic/asm_amd64p32.s                     |   159 +
 src/sync/atomic/asm_arm.s                          |   197 +
 src/sync/atomic/asm_freebsd_arm.s                  |   109 +
 src/sync/atomic/asm_linux_arm.s                    |   216 +
 src/sync/atomic/asm_nacl_arm.s                     |   109 +
 src/sync/atomic/asm_netbsd_arm.s                   |   109 +
 src/{pkg => }/sync/atomic/atomic_linux_arm_test.go |     0
 src/sync/atomic/atomic_test.go                     |  1509 ++
 src/sync/atomic/doc.go                             |   149 +
 src/sync/atomic/export_linux_arm_test.go           |     7 +
 src/sync/atomic/race.s                             |     8 +
 src/sync/atomic/value.go                           |    85 +
 src/sync/atomic/value_test.go                      |   195 +
 src/{pkg => }/sync/cond.go                         |     0
 src/{pkg => }/sync/cond_test.go                    |     0
 src/{pkg => }/sync/example_test.go                 |     0
 src/{pkg => }/sync/export_test.go                  |     0
 src/{pkg => }/sync/mutex.go                        |     0
 src/{pkg => }/sync/mutex_test.go                   |     0
 src/sync/once.go                                   |    46 +
 src/sync/once_test.go                              |    68 +
 src/sync/pool.go                                   |   225 +
 src/sync/pool_test.go                              |   163 +
 src/{pkg => }/sync/race.go                         |     0
 src/{pkg => }/sync/race0.go                        |     0
 src/sync/runtime.go                                |    40 +
 src/{pkg => }/sync/runtime_sema_test.go            |     0
 src/sync/rwmutex.go                                |   136 +
 src/sync/rwmutex_test.go                           |   254 +
 src/sync/waitgroup.go                              |   137 +
 src/{pkg => }/sync/waitgroup_test.go               |     0
 src/syscall/asm.s                                  |     8 +
 src/syscall/asm_darwin_386.s                       |   143 +
 src/syscall/asm_darwin_amd64.s                     |   107 +
 src/syscall/asm_dragonfly_386.s                    |   140 +
 src/syscall/asm_dragonfly_amd64.s                  |   134 +
 src/syscall/asm_freebsd_386.s                      |   143 +
 src/syscall/asm_freebsd_amd64.s                    |   142 +
 src/syscall/asm_freebsd_arm.s                      |   130 +
 src/syscall/asm_linux_386.s                        |   187 +
 src/syscall/asm_linux_amd64.s                      |   127 +
 src/syscall/asm_linux_arm.s                        |   159 +
 src/syscall/asm_nacl_386.s                         |    44 +
 src/syscall/asm_nacl_amd64p32.s                    |    42 +
 src/syscall/asm_nacl_arm.s                         |    44 +
 src/syscall/asm_netbsd_386.s                       |   143 +
 src/syscall/asm_netbsd_amd64.s                     |   136 +
 src/syscall/asm_netbsd_arm.s                       |   127 +
 src/syscall/asm_openbsd_386.s                      |   143 +
 src/syscall/asm_openbsd_amd64.s                    |   136 +
 src/syscall/asm_plan9_386.s                        |   166 +
 src/syscall/asm_plan9_amd64.s                      |   164 +
 src/syscall/asm_solaris_amd64.s                    |    81 +
 src/{pkg => }/syscall/bpf_bsd.go                   |     0
 src/{pkg => }/syscall/creds_test.go                |     0
 src/{pkg => }/syscall/dir_plan9.go                 |     0
 src/syscall/dll_windows.go                         |   280 +
 src/syscall/env_plan9.go                           |   108 +
 src/syscall/env_unix.go                            |   149 +
 src/syscall/env_windows.go                         |    90 +
 src/{pkg => }/syscall/exec_bsd.go                  |     0
 src/syscall/exec_linux.go                          |   363 +
 src/{pkg => }/syscall/exec_plan9.go                |     0
 src/{pkg => }/syscall/exec_solaris.go              |     0
 src/{pkg => }/syscall/exec_unix.go                 |     0
 src/syscall/exec_windows.go                        |   340 +
 src/syscall/export_test.go                         |     7 +
 src/{pkg => }/syscall/fd_nacl.go                   |     0
 src/{pkg => }/syscall/flock.go                     |     0
 src/{pkg => }/syscall/flock_linux_32bit.go         |     0
 src/syscall/fs_nacl.go                             |   838 ++
 src/{pkg => }/syscall/lsf_linux.go                 |     0
 src/syscall/mkall.sh                               |   263 +
 src/syscall/mkall_windows.bat                      |    15 +
 src/{pkg => }/syscall/mkerrors.sh                  |     0
 src/syscall/mksyscall.pl                           |   319 +
 src/syscall/mksyscall_solaris.pl                   |   283 +
 src/syscall/mksyscall_windows.go                   |   759 +
 src/{pkg => }/syscall/mksysctl_openbsd.pl          |     0
 src/{pkg => }/syscall/mksysnum_darwin.pl           |     0
 src/{pkg => }/syscall/mksysnum_dragonfly.pl        |     0
 src/{pkg => }/syscall/mksysnum_freebsd.pl          |     0
 src/{pkg => }/syscall/mksysnum_linux.pl            |     0
 src/{pkg => }/syscall/mksysnum_netbsd.pl           |     0
 src/{pkg => }/syscall/mksysnum_openbsd.pl          |     0
 src/{pkg => }/syscall/mksysnum_plan9.sh            |     0
 src/{pkg => }/syscall/mmap_unix_test.go            |     0
 src/syscall/net_nacl.go                            |   913 ++
 src/syscall/netlink_linux.go                       |   178 +
 src/{pkg => }/syscall/race.go                      |     0
 src/{pkg => }/syscall/race0.go                     |     0
 src/syscall/route_bsd.go                           |   224 +
 src/{pkg => }/syscall/route_darwin.go              |     0
 src/{pkg => }/syscall/route_dragonfly.go           |     0
 src/{pkg => }/syscall/route_freebsd.go             |     0
 src/{pkg => }/syscall/route_freebsd_32bit.go       |     0
 src/{pkg => }/syscall/route_freebsd_64bit.go       |     0
 src/{pkg => }/syscall/route_netbsd.go              |     0
 src/{pkg => }/syscall/route_openbsd.go             |     0
 src/{pkg => }/syscall/security_windows.go          |     0
 src/syscall/so_solaris.go                          |   262 +
 src/{pkg => }/syscall/sockcmsg_linux.go            |     0
 src/{pkg => }/syscall/sockcmsg_unix.go             |     0
 src/{pkg => }/syscall/srpc_nacl.go                 |     0
 src/syscall/str.go                                 |    24 +
 src/syscall/syscall.go                             |    95 +
 src/syscall/syscall_bsd.go                         |   588 +
 src/{pkg => }/syscall/syscall_bsd_test.go          |     0
 src/syscall/syscall_darwin.go                      |   509 +
 src/{pkg => }/syscall/syscall_darwin_386.go        |     0
 src/{pkg => }/syscall/syscall_darwin_amd64.go      |     0
 src/{pkg => }/syscall/syscall_dragonfly.go         |     0
 src/{pkg => }/syscall/syscall_dragonfly_386.go     |     0
 src/{pkg => }/syscall/syscall_dragonfly_amd64.go   |     0
 src/{pkg => }/syscall/syscall_freebsd.go           |     0
 src/{pkg => }/syscall/syscall_freebsd_386.go       |     0
 src/{pkg => }/syscall/syscall_freebsd_amd64.go     |     0
 src/{pkg => }/syscall/syscall_freebsd_arm.go       |     0
 src/syscall/syscall_linux.go                       |  1042 ++
 src/syscall/syscall_linux_386.go                   |   356 +
 src/syscall/syscall_linux_amd64.go                 |   114 +
 src/syscall/syscall_linux_arm.go                   |   196 +
 src/{pkg => }/syscall/syscall_nacl.go              |     0
 src/{pkg => }/syscall/syscall_nacl_386.go          |     0
 src/{pkg => }/syscall/syscall_nacl_amd64p32.go     |     0
 src/syscall/syscall_nacl_arm.go                    |    32 +
 src/{pkg => }/syscall/syscall_netbsd.go            |     0
 src/{pkg => }/syscall/syscall_netbsd_386.go        |     0
 src/{pkg => }/syscall/syscall_netbsd_amd64.go      |     0
 src/{pkg => }/syscall/syscall_netbsd_arm.go        |     0
 src/{pkg => }/syscall/syscall_no_getwd.go          |     0
 src/{pkg => }/syscall/syscall_openbsd.go           |     0
 src/{pkg => }/syscall/syscall_openbsd_386.go       |     0
 src/{pkg => }/syscall/syscall_openbsd_amd64.go     |     0
 src/syscall/syscall_plan9.go                       |   341 +
 src/{pkg => }/syscall/syscall_solaris.go           |     0
 src/{pkg => }/syscall/syscall_solaris_amd64.go     |     0
 src/syscall/syscall_test.go                        |    47 +
 src/syscall/syscall_unix.go                        |   299 +
 src/{pkg => }/syscall/syscall_unix_test.go         |     0
 src/syscall/syscall_windows.go                     |  1013 ++
 src/{pkg => }/syscall/syscall_windows_386.go       |     0
 src/{pkg => }/syscall/syscall_windows_amd64.go     |     0
 src/{pkg => }/syscall/syscall_windows_test.go      |     0
 src/{pkg => }/syscall/tables_nacl.go               |     0
 src/syscall/time_nacl_386.s                        |    11 +
 src/syscall/time_nacl_amd64p32.s                   |    11 +
 src/syscall/time_nacl_arm.s                        |    11 +
 src/{pkg => }/syscall/types_darwin.go              |     0
 src/{pkg => }/syscall/types_dragonfly.go           |     0
 src/{pkg => }/syscall/types_freebsd.go             |     0
 src/{pkg => }/syscall/types_linux.go               |     0
 src/{pkg => }/syscall/types_netbsd.go              |     0
 src/{pkg => }/syscall/types_openbsd.go             |     0
 src/{pkg => }/syscall/types_plan9.c                |     0
 src/{pkg => }/syscall/types_solaris.go             |     0
 src/{pkg => }/syscall/unzip_nacl.go                |     0
 src/{pkg => }/syscall/zerrors_darwin_386.go        |     0
 src/{pkg => }/syscall/zerrors_darwin_amd64.go      |     0
 src/{pkg => }/syscall/zerrors_dragonfly_386.go     |     0
 src/{pkg => }/syscall/zerrors_dragonfly_amd64.go   |     0
 src/{pkg => }/syscall/zerrors_freebsd_386.go       |     0
 src/{pkg => }/syscall/zerrors_freebsd_amd64.go     |     0
 src/{pkg => }/syscall/zerrors_freebsd_arm.go       |     0
 src/{pkg => }/syscall/zerrors_linux_386.go         |     0
 src/{pkg => }/syscall/zerrors_linux_amd64.go       |     0
 src/{pkg => }/syscall/zerrors_linux_arm.go         |     0
 src/{pkg => }/syscall/zerrors_netbsd_386.go        |     0
 src/{pkg => }/syscall/zerrors_netbsd_amd64.go      |     0
 src/{pkg => }/syscall/zerrors_netbsd_arm.go        |     0
 src/{pkg => }/syscall/zerrors_openbsd_386.go       |     0
 src/{pkg => }/syscall/zerrors_openbsd_amd64.go     |     0
 src/{pkg => }/syscall/zerrors_plan9_386.go         |     0
 src/{pkg => }/syscall/zerrors_plan9_amd64.go       |     0
 src/{pkg => }/syscall/zerrors_solaris_amd64.go     |     0
 src/{pkg => }/syscall/zerrors_windows.go           |     0
 src/{pkg => }/syscall/zerrors_windows_386.go       |     0
 src/{pkg => }/syscall/zerrors_windows_amd64.go     |     0
 src/syscall/zsyscall_darwin_386.go                 |  1419 ++
 src/syscall/zsyscall_darwin_amd64.go               |  1419 ++
 src/syscall/zsyscall_dragonfly_386.go              |  1317 ++
 src/syscall/zsyscall_dragonfly_amd64.go            |  1317 ++
 src/syscall/zsyscall_freebsd_386.go                |  1328 ++
 src/syscall/zsyscall_freebsd_amd64.go              |  1328 ++
 src/syscall/zsyscall_freebsd_arm.go                |  1328 ++
 src/syscall/zsyscall_linux_386.go                  |  1767 +++
 src/syscall/zsyscall_linux_amd64.go                |  1961 +++
 src/syscall/zsyscall_linux_arm.go                  |  1915 +++
 src/{pkg => }/syscall/zsyscall_nacl_386.go         |     0
 src/{pkg => }/syscall/zsyscall_nacl_amd64p32.go    |     0
 src/syscall/zsyscall_nacl_arm.go                   |    63 +
 src/syscall/zsyscall_netbsd_386.go                 |  1251 ++
 src/syscall/zsyscall_netbsd_amd64.go               |  1251 ++
 src/syscall/zsyscall_netbsd_arm.go                 |  1251 ++
 src/syscall/zsyscall_openbsd_386.go                |  1291 ++
 src/syscall/zsyscall_openbsd_amd64.go              |  1291 ++
 src/syscall/zsyscall_plan9_386.go                  |   292 +
 src/syscall/zsyscall_plan9_amd64.go                |   292 +
 src/syscall/zsyscall_solaris_amd64.go              |   906 ++
 src/syscall/zsyscall_windows.go                    |  1870 +++
 src/{pkg => }/syscall/zsysctl_openbsd.go           |     0
 src/{pkg => }/syscall/zsysnum_darwin_386.go        |     0
 src/{pkg => }/syscall/zsysnum_darwin_amd64.go      |     0
 src/{pkg => }/syscall/zsysnum_dragonfly_386.go     |     0
 src/{pkg => }/syscall/zsysnum_dragonfly_amd64.go   |     0
 src/{pkg => }/syscall/zsysnum_freebsd_386.go       |     0
 src/{pkg => }/syscall/zsysnum_freebsd_amd64.go     |     0
 src/{pkg => }/syscall/zsysnum_freebsd_arm.go       |     0
 src/{pkg => }/syscall/zsysnum_linux_386.go         |     0
 src/{pkg => }/syscall/zsysnum_linux_amd64.go       |     0
 src/{pkg => }/syscall/zsysnum_linux_arm.go         |     0
 src/{pkg => }/syscall/zsysnum_netbsd_386.go        |     0
 src/{pkg => }/syscall/zsysnum_netbsd_amd64.go      |     0
 src/{pkg => }/syscall/zsysnum_netbsd_arm.go        |     0
 src/{pkg => }/syscall/zsysnum_openbsd_386.go       |     0
 src/{pkg => }/syscall/zsysnum_openbsd_amd64.go     |     0
 src/syscall/zsysnum_plan9_386.go                   |    49 +
 src/syscall/zsysnum_plan9_amd64.go                 |    49 +
 src/{pkg => }/syscall/zsysnum_solaris_amd64.go     |     0
 src/{pkg => }/syscall/zsysnum_windows_386.go       |     0
 src/{pkg => }/syscall/zsysnum_windows_amd64.go     |     0
 src/{pkg => }/syscall/ztypes_darwin_386.go         |     0
 src/{pkg => }/syscall/ztypes_darwin_amd64.go       |     0
 src/{pkg => }/syscall/ztypes_dragonfly_386.go      |     0
 src/{pkg => }/syscall/ztypes_dragonfly_amd64.go    |     0
 src/{pkg => }/syscall/ztypes_freebsd_386.go        |     0
 src/{pkg => }/syscall/ztypes_freebsd_amd64.go      |     0
 src/{pkg => }/syscall/ztypes_freebsd_arm.go        |     0
 src/{pkg => }/syscall/ztypes_linux_386.go          |     0
 src/{pkg => }/syscall/ztypes_linux_amd64.go        |     0
 src/{pkg => }/syscall/ztypes_linux_arm.go          |     0
 src/{pkg => }/syscall/ztypes_netbsd_386.go         |     0
 src/{pkg => }/syscall/ztypes_netbsd_amd64.go       |     0
 src/{pkg => }/syscall/ztypes_netbsd_arm.go         |     0
 src/{pkg => }/syscall/ztypes_openbsd_386.go        |     0
 src/{pkg => }/syscall/ztypes_openbsd_amd64.go      |     0
 src/{pkg => }/syscall/ztypes_plan9_386.go          |     0
 src/{pkg => }/syscall/ztypes_plan9_amd64.go        |     0
 src/{pkg => }/syscall/ztypes_solaris_amd64.go      |     0
 src/syscall/ztypes_windows.go                      |  1105 ++
 src/{pkg => }/syscall/ztypes_windows_386.go        |     0
 src/{pkg => }/syscall/ztypes_windows_amd64.go      |     0
 src/{pkg => }/testing/allocs.go                    |     0
 src/testing/allocs_test.go                         |    29 +
 src/testing/benchmark.go                           |   446 +
 src/testing/benchmark_test.go                      |   113 +
 src/testing/cover.go                               |   112 +
 src/testing/example.go                             |   100 +
 src/{pkg => }/testing/export_test.go               |     0
 src/{pkg => }/testing/iotest/logger.go             |     0
 src/{pkg => }/testing/iotest/reader.go             |     0
 src/{pkg => }/testing/iotest/writer.go             |     0
 src/testing/quick/quick.go                         |   358 +
 src/{pkg => }/testing/quick/quick_test.go          |     0
 src/testing/testing.go                             |   709 +
 src/testing/testing_test.go                        |    18 +
 src/text/scanner/scanner.go                        |   693 +
 src/text/scanner/scanner_test.go                   |   618 +
 src/{pkg => }/text/tabwriter/example_test.go       |     0
 src/{pkg => }/text/tabwriter/tabwriter.go          |     0
 src/{pkg => }/text/tabwriter/tabwriter_test.go     |     0
 src/text/template/doc.go                           |   406 +
 src/{pkg => }/text/template/example_test.go        |     0
 src/{pkg => }/text/template/examplefiles_test.go   |     0
 src/{pkg => }/text/template/examplefunc_test.go    |     0
 src/text/template/exec.go                          |   844 ++
 src/text/template/exec_test.go                     |  1044 ++
 src/text/template/funcs.go                         |   598 +
 src/{pkg => }/text/template/helper.go              |     0
 src/{pkg => }/text/template/multi_test.go          |     0
 src/{pkg => }/text/template/parse/lex.go           |     0
 src/{pkg => }/text/template/parse/lex_test.go      |     0
 src/text/template/parse/node.go                    |   834 ++
 src/text/template/parse/parse.go                   |   677 +
 src/text/template/parse/parse_test.go              |   423 +
 src/{pkg => }/text/template/template.go            |     0
 src/{pkg => }/text/template/testdata/file1.tmpl    |     0
 src/{pkg => }/text/template/testdata/file2.tmpl    |     0
 src/{pkg => }/text/template/testdata/tmpl1.tmpl    |     0
 src/{pkg => }/text/template/testdata/tmpl2.tmpl    |     0
 src/time/example_test.go                           |   160 +
 src/{pkg => }/time/export_test.go                  |     0
 src/{pkg => }/time/export_windows_test.go          |     0
 src/time/format.go                                 |  1248 ++
 src/time/format_test.go                            |   518 +
 src/time/genzabbrs.go                              |   159 +
 src/time/internal_test.go                          |    59 +
 src/time/sleep.go                                  |   130 +
 src/time/sleep_test.go                             |   430 +
 src/{pkg => }/time/sys_plan9.go                    |     0
 src/{pkg => }/time/sys_unix.go                     |     0
 src/{pkg => }/time/sys_windows.go                  |     0
 src/{pkg => }/time/tick.go                         |     0
 src/{pkg => }/time/tick_test.go                    |     0
 src/time/time.go                                   |  1203 ++
 src/time/time_test.go                              |  1081 ++
 src/{pkg => }/time/zoneinfo.go                     |     0
 src/time/zoneinfo_abbrs_windows.go                 |   116 +
 src/{pkg => }/time/zoneinfo_plan9.go               |     0
 src/{pkg => }/time/zoneinfo_read.go                |     0
 src/{pkg => }/time/zoneinfo_test.go                |     0
 src/{pkg => }/time/zoneinfo_unix.go                |     0
 src/time/zoneinfo_windows.go                       |   272 +
 src/{pkg => }/time/zoneinfo_windows_test.go        |     0
 src/{pkg => }/unicode/casetables.go                |     0
 src/{pkg => }/unicode/digit.go                     |     0
 src/{pkg => }/unicode/digit_test.go                |     0
 src/{pkg => }/unicode/graphic.go                   |     0
 src/{pkg => }/unicode/graphic_test.go              |     0
 src/unicode/letter.go                              |   357 +
 src/{pkg => }/unicode/letter_test.go               |     0
 src/unicode/maketables.go                          |  1376 ++
 src/unicode/script_test.go                         |   287 +
 src/unicode/tables.go                              |  7029 ++++++++++
 src/{pkg => }/unicode/utf16/export_test.go         |     0
 src/{pkg => }/unicode/utf16/utf16.go               |     0
 src/{pkg => }/unicode/utf16/utf16_test.go          |     0
 src/{pkg => }/unicode/utf8/example_test.go         |     0
 src/unicode/utf8/utf8.go                           |   445 +
 src/{pkg => }/unicode/utf8/utf8_test.go            |     0
 src/unsafe/unsafe.go                               |    40 +
 test/assign.go                                     |    12 +
 test/bench/garbage/parser.go                       |     2 +-
 test/bench/shootout/chameneosredux.go              |     2 +-
 test/chan/perm.go                                  |     3 +
 test/chan/select5.go                               |     6 +-
 test/escape2.go                                    |     2 +
 test/escape2n.go                                   |  1494 ++
 test/fixedbugs/bug173.go                           |     2 +
 test/fixedbugs/bug255.go                           |    19 +-
 test/fixedbugs/bug299.go                           |    10 +-
 test/fixedbugs/bug371.go                           |     6 +-
 test/fixedbugs/bug406.go                           |     2 +
 test/fixedbugs/bug486.go                           |    14 +
 test/fixedbugs/bug487.go                           |    24 +
 test/fixedbugs/bug488.dir/a.go                     |     7 +
 test/fixedbugs/bug488.dir/b.go                     |     9 +
 test/fixedbugs/bug488.go                           |    12 +
 test/fixedbugs/bug489.go                           |    22 +
 test/fixedbugs/bug490.go                           |    16 +
 test/fixedbugs/bug491.go                           |   110 +
 test/fixedbugs/issue4232.go                        |    29 +-
 test/fixedbugs/issue4388.go                        |     6 +-
 test/fixedbugs/issue5856.go                        |     2 +-
 test/fixedbugs/issue6703a.go                       |    16 +
 test/fixedbugs/issue6703b.go                       |    16 +
 test/fixedbugs/issue6703c.go                       |    18 +
 test/fixedbugs/issue6703d.go                       |    18 +
 test/fixedbugs/issue6703e.go                       |    18 +
 test/fixedbugs/issue6703f.go                       |    18 +
 test/fixedbugs/issue6703g.go                       |    20 +
 test/fixedbugs/issue6703h.go                       |    20 +
 test/fixedbugs/issue6703i.go                       |    20 +
 test/fixedbugs/issue6703j.go                       |    20 +
 test/fixedbugs/issue6703k.go                       |    21 +
 test/fixedbugs/issue6703l.go                       |    21 +
 test/fixedbugs/issue6703m.go                       |    25 +
 test/fixedbugs/issue6703n.go                       |    25 +
 test/fixedbugs/issue6703o.go                       |    23 +
 test/fixedbugs/issue6703p.go                       |    23 +
 test/fixedbugs/issue6703q.go                       |    28 +
 test/fixedbugs/issue6703r.go                       |    28 +
 test/fixedbugs/issue6703s.go                       |    18 +
 test/fixedbugs/issue6703t.go                       |    18 +
 test/fixedbugs/issue6703u.go                       |    18 +
 test/fixedbugs/issue6703v.go                       |    18 +
 test/fixedbugs/issue6703w.go                       |    21 +
 test/fixedbugs/issue6703x.go                       |    21 +
 test/fixedbugs/issue6703y.go                       |    23 +
 test/fixedbugs/issue6703z.go                       |    23 +
 test/fixedbugs/issue7690.go                        |    49 +
 test/fixedbugs/issue7760.go                        |    25 +
 test/fixedbugs/issue8017.go                        |    26 +
 test/fixedbugs/issue8060.dir/a.go                  |     7 +
 test/fixedbugs/issue8060.dir/b.go                  |    13 +
 test/fixedbugs/issue8060.go                        |     9 +
 test/fixedbugs/issue8074.go                        |    16 +
 test/fixedbugs/issue8079.go                        |    11 +
 test/fixedbugs/issue8280.dir/a.go                  |     3 +
 test/fixedbugs/issue8280.dir/b.go                  |     5 +
 test/fixedbugs/issue8280.go                        |     9 +
 test/fixedbugs/issue8311.go                        |    16 +
 test/fixedbugs/issue8336.go                        |    29 +
 test/fixedbugs/issue8347.go                        |    27 +
 test/fixedbugs/issue8475.go                        |    25 +
 test/fixedbugs/issue8507.go                        |    16 +
 test/fixedbugs/issue8612.go                        |    34 +
 test/fixedbugs/issue8761.go                        |    26 +
 test/fixedbugs/issue8947.go                        |    53 +
 test/fixedbugs/issue8961.go                        |    20 +
 test/fixedbugs/issue9006.go                        |    37 +
 test/fixedbugs/issue9110.go                        |    90 +
 test/interface/explicit.go                         |     4 +-
 test/interface/fail.go                             |    14 -
 test/linkx.go                                      |    12 +-
 test/linkx_run.go                                  |    33 +
 test/live.go                                       |    77 +-
 test/live2.go                                      |    12 +-
 test/map.go                                        |     2 +-
 test/maplinear.go                                  |   172 +
 test/mapnan.go                                     |    56 -
 test/named1.go                                     |     8 +-
 test/nosplit.go                                    |    23 +-
 test/print.go                                      |    42 +
 test/print.out                                     |    24 +
 test/range.go                                      |    92 +
 test/recover.go                                    |    92 +-
 test/run.go                                        |    49 +-
 test/shift1.go                                     |     2 +
 test/sinit.go                                      |    77 +-
 test/sinit_run.go                                  |    40 +
 test/slice3.go                                     |    18 +-
 test/slicecap.go                                   |    90 +
 test/stress/maps.go                                |     2 +
 test/stress/parsego.go                             |     2 +-
 test/torture.go                                    |     7 +
 3538 files changed, 374164 insertions(+), 344674 deletions(-)

diff --git a/AUTHORS b/AUTHORS
index d4fbbd1..46fd9fd 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -13,8 +13,11 @@ Abhinav Gupta <abhinav.g90 at gmail.com>
 Adrian Nos <nos.adrian at gmail.com>
 Adrian O'Grady <elpollouk at gmail.com>
 Adrien Bustany <adrien-xx-google at bustany.org>
+Ahmed Waheed Moanes <oneofone at gmail.com>
 Akshat Kumar <seed at mail.nanosouffle.net>
+Alan Shreve <alan at inconshreveable.com>
 Albert Strasheim <fullung at gmail.com>
+Alberto Donizetti <alb.donizetti at gmail.com>
 Alberto García Hierro <alberto at garciahierro.com> <alberto.garcia.hierro at gmail.com>
 Aleksandar Dezelin <dezelin at gmail.com>
 Alex A Skinner <alex at lx.lc>
@@ -34,6 +37,7 @@ Amrut Joshi <amrut.joshi at gmail.com>
 Andrei Vieru <euvieru at gmail.com>
 Andrew Balholm <andybalholm at gmail.com>
 Andrew Bonventre <andybons at chromium.org>
+Andrew Bursavich <abursavich at gmail.com>
 Andrew Harding <andrew at spacemonkey.com>
 Andrew Lutomirski <andy at luto.us>
 Andrew Pritchard <awpritchard at gmail.com>
@@ -61,6 +65,7 @@ Aulus Egnatius Varialus <varialus at gmail.com>
 Ben Olive <sionide21 at gmail.com>
 Benjamin Black <b at b3k.us>
 Benny Siegert <bsiegert at gmail.com>
+Benoit Sigoure <tsunanet at gmail.com>
 Berengar Lehr <berengar.lehr at gmx.de>
 Billie Harold Cleek <bhcleek at gmail.com>
 Bjorn Tillenius <bjorn at tillenius.me>
@@ -87,6 +92,7 @@ Chris Farmiloe <chrisfarms at gmail.com>
 Chris Howey <howeyc at gmail.com>
 Chris Jones <chris at cjones.org>
 Chris Lennert <calennert at gmail.com>
+Chris McGee <sirnewton_01 at yahoo.ca> <newton688 at gmail.com>
 Christian Himpel <chressie at googlemail.com>
 Christine Hansmann <chhansmann at gmail.com>
 Christoffer Buchholz <christoffer.buchholz at gmail.com>
@@ -98,6 +104,7 @@ Christopher Wedgwood <cw at f00f.org>
 Clement Skau <clementskau at gmail.com>
 Conrad Meyer <cemeyer at cs.washington.edu>
 Corey Thomasson <cthom.lists at gmail.com>
+Cristian Staretu <unclejacksons at gmail.com>
 Damian Gryski <dgryski at gmail.com>
 Dan Callahan <dan.callahan at gmail.com>
 Dan Peterson <dpiddy at gmail.com>
@@ -115,10 +122,12 @@ David du Colombier <0intro at gmail.com>
 David Forsythe <dforsythe at gmail.com>
 David G. Andersen <dave.andersen at gmail.com>
 David Jakob Fritz <david.jakob.fritz at gmail.com>
+David Leon Gil <coruus at gmail.com>
 David Thomas <davidthomas426 at gmail.com>
 David Titarenco <david.titarenco at gmail.com>
 Dean Prichard <dean.prichard at gmail.com>
 Denis Brandolini <denis.brandolini at gmail.com>
+Derek Parker <parkerderek86 at gmail.com>
 Devon H. O'Dell <devon.odell at gmail.com>
 Dhiru Kholia <dhiru.kholia at gmail.com>
 Dimitri Tcaciuc <dtcaciuc at gmail.com>
@@ -136,7 +145,7 @@ Egon Elbre <egonelbre at gmail.com>
 Ehren Kret <ehren.kret at gmail.com>
 Eivind Uggedal <eivind at uggedal.com>
 Elias Naur <elias.naur at gmail.com>
-Emil Hessman <c.emil.hessman at gmail.com>
+Emil Hessman <c.emil.hessman at gmail.com> <emil at hessman.se>
 Eoghan Sherry <ejsherry at gmail.com>
 Eric Clark <zerohp at gmail.com>
 Eric Milliken <emilliken at gmail.com>
@@ -148,6 +157,8 @@ Evan Shaw <chickencha at gmail.com>
 Ewan Chou <coocood at gmail.com>
 Fabrizio Milo <mistobaan at gmail.com>
 Fan Hongjian <fan.howard at gmail.com>
+Fastly, Inc.
+Fatih Arslan <fatih at arslan.io>
 Fazlul Shahriar <fshahriar at gmail.com>
 Felix Geisendörfer <haimuiba at gmail.com>
 Firmansyah Adiputra <frm.adiputra at gmail.com>
@@ -157,6 +168,7 @@ Francisco Souza <franciscossouza at gmail.com>
 Frederick Kelly Mayle III <frederickmayle at gmail.com>
 Fredrik Enestad <fredrik.enestad at soundtrackyourbrand.com>
 Frithjof Schulze <schulze at math.uni-hannover.de> <sfrithjof at gmail.com>
+Gabriel Aszalos <gabriel.aszalos at gmail.com>
 Gary Burd <gary at beagledreams.com>
 Gautham Thambidorai <gautham.dorai at gmail.com>
 Georg Reinke <guelfey at gmail.com>
@@ -174,6 +186,8 @@ Gustavo Niemeyer <gustavo at niemeyer.net>
 Gwenael Treguier <gwenn.kahz at gmail.com>
 Harley Laue <losinggeneration at gmail.com>
 Hector Chu <hectorchu at gmail.com>
+Hector Martin Cantero <hector at marcansoft.com>
+Henning Schmiedehausen <henning at schmiedehausen.org>
 Henrik Edwards <henrik.edwards at gmail.com>
 Herbert Georg Fischer <herbert.fischer at gmail.com>
 Hong Ruiqi <hongruiqi at gmail.com>
@@ -203,17 +217,21 @@ Jeff Hodges <jeff at somethingsimilar.com>
 Jeff R. Allen <jra at nella.org>
 Jeff Sickel <jas at corpus-callosum.com>
 Jeff Wendling <jeff at spacemonkey.com>
+Jens Frederich <jfrederich at gmail.com>
 Jeremy Jackins <jeremyjackins at gmail.com>
 Jim McGrath <jimmc2 at gmail.com>
 Jimmy Zelinskie <jimmyzelinskie at gmail.com>
 Jingcheng Zhang <diogin at gmail.com>
 Joakim Sernbrant <serbaut at gmail.com>
 Joe Poirier <jdpoirier at gmail.com>
+Joe Shaw <joe at joeshaw.org>
+Joel Stemmer <stemmertech at gmail.com>
 John Asmuth <jasmuth at gmail.com>
 John C Barstow <jbowtie at amathaine.com>
 John Graham-Cumming <jgc at jgc.org> <jgrahamc at gmail.com>
 John Howard Palevich <jack.palevich at gmail.com>
 John Shahid <jvshahid at gmail.com>
+John Tuley <john at tuley.org>
 Jonathan Gold <jgold.bg at gmail.com>
 Jonathan Mark <jhmark at xenops.com>
 Jonathan Rudenberg <jonathan at titanous.com>
@@ -225,6 +243,7 @@ Josh Bleecher Snyder <josharian at gmail.com>
 Josh Goebel <dreamer3 at gmail.com>
 Josh Holland <jrh at joshh.co.uk>
 Joshua Chase <jcjoshuachase at gmail.com>
+JT Olds <jtolds at xnet5.com>
 Jukka-Pekka Kekkonen <karatepekka at gmail.com>
 Julian Phillips <julian at quantumfyre.co.uk>
 Julien Schmidt <google at julienschmidt.com>
@@ -250,10 +269,13 @@ Lucio De Re <lucio.dere at gmail.com>
 Luit van Drongelen <luitvd at gmail.com>
 Luka Zakrajšek <tr00.g33k at gmail.com>
 Luke Curley <qpingu at gmail.com>
+Manuel Mendez <mmendez534 at gmail.com>
 Marc Weistroff <marc at weistroff.net>
 Marco Hennings <marco.hennings at freiheit.com>
+Mark Theunissen <mark.theunissen at gmail.com>
 Marko Juhani Silokunnas <marko.silokunnas at gmail.com>
 Marko Tiikkaja <marko at joh.to>
+Markover Inc. DBA Poptip
 Markus Duft <markus.duft at salomon.at>
 Markus Sonderegger <marraison at gmail.com>
 Markus Zimmermann <zimmski at gmail.com>
@@ -276,6 +298,7 @@ Michael Fraenkel <michael.fraenkel at gmail.com>
 Michael Gehring <mg at ebfe.org> <gnirheg.leahcim at gmail.com>
 Michael Hoisie <hoisie at gmail.com>
 Michael Lewis <mikelikespie at gmail.com>
+Michael MacInnis <Michael.P.MacInnis at gmail.com>
 Michael Pearson <mipearson at gmail.com>
 Michael Stapelberg <michael at stapelberg.de>
 Michael Teichgräber <mteichgraeber at gmx.de>
@@ -295,6 +318,7 @@ Moriyoshi Koizumi <mozo at mozo.jp>
 Môshe van der Sterre <moshevds at gmail.com>
 Nan Deng <monnand at gmail.com>
 Nathan John Youngman <nj at nathany.com>
+Nathan P Finch <nate.finch at gmail.com>
 ngmoco, LLC
 Nicholas Katsaros <nick at nickkatsaros.com>
 Nicholas Presta <nick at nickpresta.ca> <nick1presta at gmail.com>
@@ -325,6 +349,7 @@ Paul Lalonde <paul.a.lalonde at gmail.com>
 Paul Sbarra <Sbarra.Paul at gmail.com>
 Paul van Brouwershaven <paul at vanbrouwershaven.com>
 Pavel Zinovkin <pavel.zinovkin at gmail.com>
+Percy Wegmann <ox.to.a.cart at gmail.com>
 Petar Maymounkov <petarm at gmail.com>
 Peter Armitage <peter.armitage at gmail.com>
 Peter Froehlich <peter.hans.froehlich at gmail.com>
@@ -340,6 +365,7 @@ Pietro Gagliardi <pietro10 at mac.com>
 Preetam Jinka <pj at preet.am>
 Quan Yong Zhai <qyzhai at gmail.com>
 Raif S. Naffah <go at naffah-raif.name>
+Red Hat, Inc.
 Rémy Oudompheng <oudomphe at phare.normalesup.org>
 Richard Crowley <r at rcrowley.org>
 Richard Eric Gavaletz <gavaletz at gmail.com>
@@ -356,6 +382,7 @@ Rodrigo Moraes de Oliveira <rodrigo.moraes at gmail.com>
 Rodrigo Rafael Monti Kochenburger <divoxx at gmail.com>
 Roger Pau Monné <royger at gmail.com>
 Roger Peppe <rogpeppe at gmail.com>
+Ron Hashimoto <mail at h2so5.net>
 Ron Minnich <rminnich at gmail.com>
 Ross Light <rlight2 at gmail.com>
 Rowan Worth <sqweek at gmail.com>
@@ -374,6 +401,7 @@ Shane Hansen <shanemhansen at gmail.com>
 Shawn Smith <shawn.p.smith at gmail.com>
 Shenghou Ma <minux.ma at gmail.com>
 Shivakumar GN <shivakumar.gn at gmail.com>
+Simon Whitehead <chemnova at gmail.com>
 Sokolov Yura <funny.falcon at gmail.com>
 Spring Mc <heresy.mc at gmail.com>
 StalkR <stalkr at stalkr.net>
@@ -390,10 +418,14 @@ Tad Glines <tad.glines at gmail.com>
 Taj Khattra <taj.khattra at gmail.com>
 Tarmigan Casebolt <tarmigan at gmail.com>
 Taru Karttunen <taruti at taruti.net>
+Tetsuo Kiso <tetsuokiso9 at gmail.com>
+Thiago Fransosi Farina <thiago.farina at gmail.com>
 Thomas Alan Copeland <talan.copeland at gmail.com>
 Thomas Kappler <tkappler at gmail.com>
 Timo Savola <timo.savola at gmail.com>
+Timo Truyts <alkaloid.btx at gmail.com>
 Tobias Columbus <tobias.columbus at gmail.com>
+Tom Linford <tomlinford at gmail.com>
 Tor Andersson <tor.andersson at gmail.com>
 Travis Cline <travis.cline at gmail.com>
 Tudor Golubenco <tudor.g at gmail.com>
@@ -412,6 +444,7 @@ Wei Guangjing <vcc.163 at gmail.com>
 Willem van der Schyff <willemvds at gmail.com>
 William Josephson <wjosephson at gmail.com>
 William Orr <will at worrbase.com> <ay1244 at gmail.com>
+Xia Bin <snyh at snyh.org>
 Xing Xing <mikespook at gmail.com>
 Yasuhiro Matsumoto <mattn.jp at gmail.com>
 Yissakhar Z. Beck <yissakhar.beck at gmail.com>
diff --git a/CONTRIBUTORS b/CONTRIBUTORS
index 3722298..b5e709e 100644
--- a/CONTRIBUTORS
+++ b/CONTRIBUTORS
@@ -38,9 +38,12 @@ Adam Langley <agl at golang.org>
 Adrian Nos <nos.adrian at gmail.com>
 Adrian O'Grady <elpollouk at gmail.com>
 Adrien Bustany <adrien-xx-google at bustany.org>
+Ahmed Waheed Moanes <oneofone at gmail.com>
 Akshat Kumar <seed at mail.nanosouffle.net>
 Alan Donovan <adonovan at google.com>
+Alan Shreve <alan at inconshreveable.com>
 Albert Strasheim <fullung at gmail.com>
+Alberto Donizetti <alb.donizetti at gmail.com>
 Alberto García Hierro <alberto at garciahierro.com> <alberto.garcia.hierro at gmail.com>
 Aleksandar Dezelin <dezelin at gmail.com>
 Alex A Skinner <alex at lx.lc>
@@ -63,8 +66,10 @@ Amrut Joshi <amrut.joshi at gmail.com>
 Andrea Spadaccini <spadaccio at google.com>
 Andreas Jellinghaus <andreas at ionisiert.de> <anj at google.com>
 Andrei Vieru <euvieru at gmail.com>
+Andres Erbsen <andreser at google.com>
 Andrew Balholm <andybalholm at gmail.com>
 Andrew Bonventre <andybons at chromium.org>
+Andrew Bursavich <abursavich at gmail.com>
 Andrew Gerrand <adg at golang.org>
 Andrew Harding <andrew at spacemonkey.com>
 Andrew Lutomirski <andy at luto.us>
@@ -91,7 +96,7 @@ Arvindh Rajesh Tamilmani <art at a-30.net>
 Asim Shankar <asimshankar at gmail.com>
 Ato Araki <ato.araki at gmail.com>
 Aulus Egnatius Varialus <varialus at gmail.com>
-Austin Clements <aclements at csail.mit.edu>
+Austin Clements <austin at google.com> <aclements at csail.mit.edu>
 Balazs Lecz <leczb at google.com>
 Ben Eitzen <eitzenb at golang.org>
 Ben Fried <ben.fried at gmail.com>
@@ -99,6 +104,7 @@ Ben Lynn <benlynn at gmail.com>
 Ben Olive <sionide21 at gmail.com>
 Benjamin Black <b at b3k.us>
 Benny Siegert <bsiegert at gmail.com>
+Benoit Sigoure <tsunanet at gmail.com>
 Berengar Lehr <Berengar.Lehr at gmx.de>
 Bill Neubauer <wcn at golang.org> <wcn at google.com> <bill.neubauer at gmail.com>
 Bill Thiede <couchmoney at gmail.com>
@@ -138,6 +144,7 @@ Chris Hundt <hundt at google.com>
 Chris Jones <chris at cjones.org> <chris.jones.yar at gmail.com>
 Chris Lennert <calennert at gmail.com>
 Chris Manghane <cmang at golang.org>
+Chris McGee <sirnewton_01 at yahoo.ca> <newton688 at gmail.com>
 Christian Himpel <chressie at googlemail.com> <chressie at gmail.com>
 Christine Hansmann <chhansmann at gmail.com>
 Christoffer Buchholz <christoffer.buchholz at gmail.com>
@@ -152,7 +159,9 @@ Colby Ranger <cranger at google.com>
 Conrad Meyer <cemeyer at cs.washington.edu>
 Corey Thomasson <cthom.lists at gmail.com>
 Cosmos Nicolaou <cnicolaou at google.com>
+Cristian Staretu <unclejacksons at gmail.com>
 Damian Gryski <dgryski at gmail.com>
+Damien Neil <dneil at google.com>
 Dan Callahan <dan.callahan at gmail.com>
 Dan Peterson <dpiddy at gmail.com>
 Dan Sinclair <dan.sinclair at gmail.com>
@@ -177,6 +186,7 @@ David du Colombier <0intro at gmail.com>
 David Forsythe <dforsythe at gmail.com>
 David G. Andersen <dave.andersen at gmail.com>
 David Jakob Fritz <david.jakob.fritz at gmail.com>
+David Leon Gil <coruus at gmail.com>
 David McLeish <davemc at google.com>
 David Presotto <presotto at gmail.com>
 David Symonds <dsymonds at golang.org>
@@ -184,6 +194,7 @@ David Thomas <davidthomas426 at gmail.com>
 David Titarenco <david.titarenco at gmail.com>
 Dean Prichard <dean.prichard at gmail.com>
 Denis Brandolini <denis.brandolini at gmail.com>
+Derek Parker <parkerderek86 at gmail.com>
 Devon H. O'Dell <devon.odell at gmail.com>
 Dhiru Kholia <dhiru.kholia at gmail.com>
 Dimitri Tcaciuc <dtcaciuc at gmail.com>
@@ -195,6 +206,7 @@ Dominik Honnef <dominik.honnef at gmail.com>
 Donovan Hide <donovanhide at gmail.com>
 Drew Hintz <adhintz at google.com>
 Duncan Holm <mail at frou.org>
+Dustin Long <dustmop at gmail.com>
 Dustin Sallings <dsallings at gmail.com>
 Dustin Shields-Cloues <dcloues at gmail.com>
 Eden Li <eden.li at gmail.com>
@@ -202,7 +214,7 @@ Egon Elbre <egonelbre at gmail.com>
 Ehren Kret <ehren.kret at gmail.com>
 Eivind Uggedal <eivind at uggedal.com>
 Elias Naur <elias.naur at gmail.com>
-Emil Hessman <c.emil.hessman at gmail.com>
+Emil Hessman <c.emil.hessman at gmail.com> <emil at hessman.se>
 Eoghan Sherry <ejsherry at gmail.com>
 Eric Clark <zerohp at gmail.com>
 Eric Milliken <emilliken at gmail.com>
@@ -210,11 +222,13 @@ Eric Roshan-Eisner <eric.d.eisner at gmail.com>
 Erik St. Martin <alakriti at gmail.com>
 Erik Westrup <erik.westrup at gmail.com>
 Esko Luontola <esko.luontola at gmail.com>
+Evan Kroske <evankroske at google.com>
 Evan Martin <evan.martin at gmail.com>
 Evan Shaw <chickencha at gmail.com>
 Ewan Chou <coocood at gmail.com>
 Fabrizio Milo <mistobaan at gmail.com>
 Fan Hongjian <fan.howard at gmail.com>
+Fatih Arslan <fatih at arslan.io>
 Fazlul Shahriar <fshahriar at gmail.com>
 Felix Geisendörfer <haimuiba at gmail.com>
 Firmansyah Adiputra <frm.adiputra at gmail.com>
@@ -228,12 +242,14 @@ Fredrik Enestad <fredrik.enestad at soundtrackyourbrand.com>
 Frithjof Schulze <schulze at math.uni-hannover.de> <sfrithjof at gmail.com>
 Fumitoshi Ukai <ukai at google.com>
 Gaal Yahas <gaal at google.com>
+Gabriel Aszalos <gabriel.aszalos at gmail.com>
 Gary Burd <gary at beagledreams.com> <gary.burd at gmail.com>
 Gautham Thambidorai <gautham.dorai at gmail.com>
 Georg Reinke <guelfey at gmail.com>
 Gerasimos Dimitriadis <gedimitr at gmail.com>
 Gideon Jan-Wessel Redelinghuys <gjredelinghuys at gmail.com>
 Giles Lean <giles.lean at pobox.com>
+Glenn Lewis <gmlewis at google.com>
 Gordon Klaus <gordon.klaus at gmail.com>
 Graham King <graham4king at gmail.com>
 Graham Miller <graham.miller at gmail.com>
@@ -243,9 +259,12 @@ Gustav Paul <gustav.paul at gmail.com>
 Gustavo Franco <gustavorfranco at gmail.com>
 Gustavo Niemeyer <gustavo at niemeyer.net> <n13m3y3r at gmail.com>
 Gwenael Treguier <gwenn.kahz at gmail.com>
+Hana Kim <hyangah at gmail.com>
 Han-Wen Nienhuys <hanwen at google.com>
 Harley Laue <losinggeneration at gmail.com>
 Hector Chu <hectorchu at gmail.com>
+Hector Martin Cantero <hector at marcansoft.com>
+Henning Schmiedehausen <henning at schmiedehausen.org>
 Henrik Edwards <henrik.edwards at gmail.com>
 Herbert Georg Fischer <herbert.fischer at gmail.com>
 Hong Ruiqi <hongruiqi at gmail.com>
@@ -264,6 +283,7 @@ James Fysh <james.fysh at gmail.com>
 James Gray <james at james4k.com>
 James Meneghello <rawrz0r at gmail.com>
 James P. Cooper <jamespcooper at gmail.com>
+James Robinson <jamesr at google.com> <jamesr.gatech at gmail.com>
 James Toy <nil at opensesame.st>
 James Tucker <raggi at google.com>
 James Whitehead <jnwhiteh at gmail.com>
@@ -281,10 +301,12 @@ Jason Del Ponte <delpontej at gmail.com>
 Jason Travis <infomaniac7 at gmail.com>
 Jay Weisskopf <jay at jayschwa.net>
 Jean-Marc Eurin <jmeurin at google.com>
+Jed Denlea <jed at fastly.com>
 Jeff Hodges <jeff at somethingsimilar.com>
 Jeff R. Allen <jra at nella.org> <jeff.allen at gmail.com>
 Jeff Sickel <jas at corpus-callosum.com>
 Jeff Wendling <jeff at spacemonkey.com>
+Jens Frederich <jfrederich at gmail.com>
 Jeremiah Harmsen <jeremiah at google.com>
 Jeremy Jackins <jeremyjackins at gmail.com>
 Jeremy Schlatter <jeremy.schlatter at gmail.com>
@@ -293,7 +315,9 @@ Jimmy Zelinskie <jimmyzelinskie at gmail.com>
 Jingcheng Zhang <diogin at gmail.com>
 Joakim Sernbrant <serbaut at gmail.com>
 Joe Poirier <jdpoirier at gmail.com>
+Joe Shaw <joe at joeshaw.org>
 Joel Sing <jsing at google.com>
+Joel Stemmer <stemmertech at gmail.com>
 Johan Euphrosine <proppy at google.com>
 John Asmuth <jasmuth at gmail.com>
 John Beisley <huin at google.com>
@@ -303,6 +327,7 @@ John Graham-Cumming <jgc at jgc.org> <jgrahamc at gmail.com>
 John Howard Palevich <jack.palevich at gmail.com>
 John Newlin <jnewlin at google.com>
 John Shahid <jvshahid at gmail.com>
+John Tuley <john at tuley.org>
 Jonathan Allie <jonallie at google.com>
 Jonathan Feinberg <feinberg at google.com>
 Jonathan Gold <jgold.bg at gmail.com>
@@ -323,6 +348,7 @@ Josh Hoak <jhoak at google.com>
 Josh Holland <jrh at joshh.co.uk>
 Joshua Chase <jcjoshuachase at gmail.com>
 JP Sugarbroad <jpsugar at google.com>
+JT Olds <jtolds at xnet5.com>
 Jukka-Pekka Kekkonen <karatepekka at gmail.com>
 Julian Phillips <julian at quantumfyre.co.uk>
 Julien Schmidt <google at julienschmidt.com>
@@ -357,9 +383,11 @@ Luke Curley <qpingu at gmail.com>
 Luuk van Dijk <lvd at golang.org> <lvd at google.com>
 Manoj Dayaram <platform-dev at moovweb.com> <manoj.dayaram at moovweb.com>
 Manu Garg <manugarg at google.com>
+Manuel Mendez <mmendez534 at gmail.com>
 Marc Weistroff <marc at weistroff.net>
 Marcel van Lohuizen <mpvl at golang.org>
 Marco Hennings <marco.hennings at freiheit.com>
+Mark Theunissen <mark.theunissen at gmail.com>
 Mark Zavislak <zavislak at google.com>
 Marko Juhani Silokunnas <marko.silokunnas at gmail.com>
 Marko Mikulicic <mkm at google.com>
@@ -393,6 +421,7 @@ Michael Hoisie <hoisie at gmail.com>
 Michael Hudson-Doyle <michael.hudson at linaro.org>
 Michael Kelly <mjk at google.com>
 Michael Lewis <mikelikespie at gmail.com>
+Michael MacInnis <Michael.P.MacInnis at gmail.com>
 Michael Matloob <matloob at google.com>
 Michael Pearson <mipearson at gmail.com>
 Michael Piatek <piatek at google.com>
@@ -415,12 +444,15 @@ Mikkel Krautz <mikkel at krautz.dk> <krautz at gmail.com>
 Miquel Sabaté Solà <mikisabate at gmail.com>
 Moriyoshi Koizumi <mozo at mozo.jp>
 Môshe van der Sterre <moshevds at gmail.com>
+Mrunal Patel <mrunalp at gmail.com>
 Nan Deng <monnand at gmail.com>
 Nathan John Youngman <nj at nathany.com>
+Nathan P Finch <nate.finch at gmail.com>
 Nicholas Katsaros <nick at nickkatsaros.com>
 Nicholas Presta <nick at nickpresta.ca> <nick1presta at gmail.com>
 Nicholas Sullivan <nicholas.sullivan at gmail.com>
 Nicholas Waples <nwaples at gmail.com>
+Nick Cooper <nmvc at google.com>
 Nick Craig-Wood <nick at craig-wood.com> <nickcw at gmail.com>
 Nicolas Kaiser <nikai at nikai.net>
 Nicolas Owens <mischief at offblast.org>
@@ -447,10 +479,12 @@ Paul Borman <borman at google.com>
 Paul Chang <paulchang at google.com>
 Paul Hammond <paul at paulhammond.org>
 Paul Lalonde <paul.a.lalonde at gmail.com>
+Paul Nasrat <pnasrat at google.com>
 Paul Sbarra <Sbarra.Paul at gmail.com>
 Paul van Brouwershaven <paul at vanbrouwershaven.com>
 Pavel Zinovkin <pavel.zinovkin at gmail.com>
 Pawel Szczur <filemon at google.com>
+Percy Wegmann <ox.to.a.cart at gmail.com>
 Petar Maymounkov <petarm at gmail.com>
 Peter Armitage <peter.armitage at gmail.com>
 Peter Collingbourne <pcc at google.com>
@@ -472,11 +506,13 @@ Preetam Jinka <pj at preet.am>
 Quan Yong Zhai <qyzhai at gmail.com>
 Raif S. Naffah <go at naffah-raif.name>
 Raph Levien <raph at google.com>
+Raul Silvera <rsilvera at google.com>
 Rémy Oudompheng <oudomphe at phare.normalesup.org> <remyoudompheng at gmail.com>
 Richard Crowley <r at rcrowley.org>
 Richard Eric Gavaletz <gavaletz at gmail.com>
 Richard Musiol <mail at richard-musiol.de> <neelance at gmail.com>
 Rick Arnold <rickarnoldjr at gmail.com>
+Rick Hudson <rlh at golang.org>
 Risto Jaakko Saarelma <rsaarelm at gmail.com>
 Rob Pike <r at golang.org>
 Robert Daniel Kortschak <dan.kortschak at adelaide.edu.au>
@@ -492,6 +528,7 @@ Rodrigo Moraes de Oliveira <rodrigo.moraes at gmail.com>
 Rodrigo Rafael Monti Kochenburger <divoxx at gmail.com>
 Roger Pau Monné <royger at gmail.com>
 Roger Peppe <rogpeppe at gmail.com>
+Ron Hashimoto <mail at h2so5.net>
 Ron Minnich <rminnich at gmail.com>
 Ross Light <rlight2 at gmail.com>
 Rowan Worth <sqweek at gmail.com>
@@ -518,6 +555,7 @@ Shawn Ledbetter <sledbetter at google.com>
 Shawn Smith <shawn.p.smith at gmail.com>
 Shenghou Ma <minux at golang.org> <minux.ma at gmail.com>
 Shivakumar GN <shivakumar.gn at gmail.com>
+Simon Whitehead <chemnova at gmail.com>
 Sokolov Yura <funny.falcon at gmail.com>
 Spring Mc <heresy.mc at gmail.com>
 StalkR <stalkr at stalkr.net>
@@ -536,12 +574,16 @@ Tad Glines <tad.glines at gmail.com>
 Taj Khattra <taj.khattra at gmail.com>
 Tarmigan Casebolt <tarmigan at gmail.com>
 Taru Karttunen <taruti at taruti.net>
+Tetsuo Kiso <tetsuokiso9 at gmail.com>
+Thiago Fransosi Farina <thiago.farina at gmail.com> <tfarina at chromium.org>
 Thomas Alan Copeland <talan.copeland at gmail.com>
 Thomas Habets <habets at google.com>
 Thomas Kappler <tkappler at gmail.com>
 Timo Savola <timo.savola at gmail.com>
+Timo Truyts <alkaloid.btx at gmail.com>
 Tobias Columbus <tobias.columbus at gmail.com> <tobias.columbus at googlemail.com>
 Todd Wang <toddwang at gmail.com>
+Tom Linford <tomlinford at gmail.com>
 Tom Szymanski <tgs at google.com>
 Tor Andersson <tor.andersson at gmail.com>
 Travis Cline <travis.cline at gmail.com>
@@ -566,6 +608,7 @@ Willem van der Schyff <willemvds at gmail.com>
 William Chan <willchan at chromium.org>
 William Josephson <wjosephson at gmail.com>
 William Orr <will at worrbase.com> <ay1244 at gmail.com>
+Xia Bin <snyh at snyh.org>
 Xing Xing <mikespook at gmail.com>
 Yan Zou <yzou at google.com>
 Yasuhiro Matsumoto <mattn.jp at gmail.com>
diff --git a/VERSION b/VERSION
index 61592c3..40c8f5c 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-go1.3.3
\ No newline at end of file
+go1.4
\ No newline at end of file
diff --git a/api/except.txt b/api/except.txt
index 1a82966..6e40e18 100644
--- a/api/except.txt
+++ b/api/except.txt
@@ -327,3 +327,4 @@ pkg syscall (netbsd-arm), const SizeofIfData = 132
 pkg syscall (netbsd-arm), type IfMsghdr struct, Pad_cgo_1 [4]uint8
 pkg syscall (netbsd-arm-cgo), const SizeofIfData = 132
 pkg syscall (netbsd-arm-cgo), type IfMsghdr struct, Pad_cgo_1 [4]uint8
+pkg unicode, const Version = "6.3.0"
diff --git a/api/go1.4.txt b/api/go1.4.txt
new file mode 100644
index 0000000..08cb17f
--- /dev/null
+++ b/api/go1.4.txt
@@ -0,0 +1,604 @@
+# CL 134210043 archive/zip: add Writer.Flush, Brad Fitzpatrick <bradfitz at golang.org>
+pkg archive/zip, method (*Writer) Flush() error
+
+# CL 97140043 compress/flate: add Reset() to allow reusing large buffers to compress multiple buffers, James Robinson <jamesr at google.com>
+pkg compress/flate, type Resetter interface { Reset }
+pkg compress/flate, type Resetter interface, Reset(io.Reader, []uint8) error
+pkg compress/zlib, type Resetter interface { Reset }
+pkg compress/zlib, type Resetter interface, Reset(io.Reader, []uint8) error
+
+# CL 159120044 compress/gzip: allow stopping at end of first stream, Russ Cox <rsc at golang.org>
+pkg compress/gzip, method (*Reader) Multistream(bool)
+
+# CL 138800043 crypto: Add SHA3 functions in go.crypto/sha3 to the Hash enum., David Leon Gil <coruus at gmail.com>
+pkg crypto, const SHA3_224 = 10
+pkg crypto, const SHA3_224 Hash
+pkg crypto, const SHA3_256 = 11
+pkg crypto, const SHA3_256 Hash
+pkg crypto, const SHA3_384 = 12
+pkg crypto, const SHA3_384 Hash
+pkg crypto, const SHA3_512 = 13
+pkg crypto, const SHA3_512 Hash
+
+# CL 114680043 crypto: add Signer, Adam Langley <agl at golang.org>
+pkg crypto, method (Hash) HashFunc() Hash
+pkg crypto, type Signer interface { Public, Sign }
+pkg crypto, type Signer interface, Public() PublicKey
+pkg crypto, type Signer interface, Sign(io.Reader, []uint8, SignerOpts) ([]uint8, error)
+pkg crypto, type SignerOpts interface { HashFunc }
+pkg crypto, type SignerOpts interface, HashFunc() Hash
+pkg crypto/ecdsa, method (*PrivateKey) Public() crypto.PublicKey
+pkg crypto/ecdsa, method (*PrivateKey) Sign(io.Reader, []uint8, crypto.SignerOpts) ([]uint8, error)
+pkg crypto/rsa, method (*PSSOptions) HashFunc() crypto.Hash
+pkg crypto/rsa, method (*PrivateKey) Public() crypto.PublicKey
+pkg crypto/rsa, method (*PrivateKey) Sign(io.Reader, []uint8, crypto.SignerOpts) ([]uint8, error)
+pkg crypto/rsa, type PSSOptions struct, Hash crypto.Hash
+
+# CL 157090043 crypto/tls: support TLS_FALLBACK_SCSV as a server., Adam Langley <agl at golang.org>
+pkg crypto/tls, const TLS_FALLBACK_SCSV = 22016
+pkg crypto/tls, const TLS_FALLBACK_SCSV uint16
+
+# CL 107400043 crypto/tls: Added dynamic alternative to NameToCertificate map for SNI, Percy Wegmann <ox.to.a.cart at gmail.com>
+pkg crypto/tls, type ClientHelloInfo struct
+pkg crypto/tls, type ClientHelloInfo struct, CipherSuites []uint16
+pkg crypto/tls, type ClientHelloInfo struct, ServerName string
+pkg crypto/tls, type ClientHelloInfo struct, SupportedCurves []CurveID
+pkg crypto/tls, type ClientHelloInfo struct, SupportedPoints []uint8
+pkg crypto/tls, type Config struct, GetCertificate func(*ClientHelloInfo) (*Certificate, error)
+pkg crypto/tls, type ConnectionState struct, TLSUnique []uint8
+
+# CL 153420045 crypto/x509: continue to recognise MaxPathLen of zero as "no value"., Adam Langley <agl at golang.org>
+pkg crypto/x509, type Certificate struct, MaxPathLenZero bool
+
+# CL 158950043 database/sql: add Drivers, returning list of registered drivers, Russ Cox <rsc at golang.org>
+pkg database/sql, func Drivers() []string
+
+# CL 117280043 debug/dwarf: fix Reader panic on DW_TAG_unspecified_type, Derek Parker <parkerderek86 at gmail.com>
+pkg debug/dwarf, method (*UnspecifiedType) Basic() *BasicType
+pkg debug/dwarf, method (*UnspecifiedType) Common() *CommonType
+pkg debug/dwarf, method (*UnspecifiedType) Size() int64
+pkg debug/dwarf, method (*UnspecifiedType) String() string
+pkg debug/dwarf, type UnspecifiedType struct
+pkg debug/dwarf, type UnspecifiedType struct, embedded BasicType
+
+# CL 132000043 debug/elf: support arm64 relocations, Michael Hudson-Doyle <michael.hudson at linaro.org>
+pkg debug/elf, const EM_AARCH64 = 183
+pkg debug/elf, const EM_AARCH64 Machine
+pkg debug/elf, const R_AARCH64_ABS16 = 259
+pkg debug/elf, const R_AARCH64_ABS16 R_AARCH64
+pkg debug/elf, const R_AARCH64_ABS32 = 258
+pkg debug/elf, const R_AARCH64_ABS32 R_AARCH64
+pkg debug/elf, const R_AARCH64_ABS64 = 257
+pkg debug/elf, const R_AARCH64_ABS64 R_AARCH64
+pkg debug/elf, const R_AARCH64_ADD_ABS_LO12_NC = 277
+pkg debug/elf, const R_AARCH64_ADD_ABS_LO12_NC R_AARCH64
+pkg debug/elf, const R_AARCH64_ADR_GOT_PAGE = 311
+pkg debug/elf, const R_AARCH64_ADR_GOT_PAGE R_AARCH64
+pkg debug/elf, const R_AARCH64_ADR_PREL_LO21 = 274
+pkg debug/elf, const R_AARCH64_ADR_PREL_LO21 R_AARCH64
+pkg debug/elf, const R_AARCH64_ADR_PREL_PG_HI21 = 275
+pkg debug/elf, const R_AARCH64_ADR_PREL_PG_HI21 R_AARCH64
+pkg debug/elf, const R_AARCH64_ADR_PREL_PG_HI21_NC = 276
+pkg debug/elf, const R_AARCH64_ADR_PREL_PG_HI21_NC R_AARCH64
+pkg debug/elf, const R_AARCH64_CALL26 = 283
+pkg debug/elf, const R_AARCH64_CALL26 R_AARCH64
+pkg debug/elf, const R_AARCH64_CONDBR19 = 280
+pkg debug/elf, const R_AARCH64_CONDBR19 R_AARCH64
+pkg debug/elf, const R_AARCH64_COPY = 1024
+pkg debug/elf, const R_AARCH64_COPY R_AARCH64
+pkg debug/elf, const R_AARCH64_GLOB_DAT = 1025
+pkg debug/elf, const R_AARCH64_GLOB_DAT R_AARCH64
+pkg debug/elf, const R_AARCH64_GOT_LD_PREL19 = 309
+pkg debug/elf, const R_AARCH64_GOT_LD_PREL19 R_AARCH64
+pkg debug/elf, const R_AARCH64_IRELATIVE = 1032
+pkg debug/elf, const R_AARCH64_IRELATIVE R_AARCH64
+pkg debug/elf, const R_AARCH64_JUMP26 = 282
+pkg debug/elf, const R_AARCH64_JUMP26 R_AARCH64
+pkg debug/elf, const R_AARCH64_JUMP_SLOT = 1026
+pkg debug/elf, const R_AARCH64_JUMP_SLOT R_AARCH64
+pkg debug/elf, const R_AARCH64_LD64_GOT_LO12_NC = 312
+pkg debug/elf, const R_AARCH64_LD64_GOT_LO12_NC R_AARCH64
+pkg debug/elf, const R_AARCH64_LDST128_ABS_LO12_NC = 299
+pkg debug/elf, const R_AARCH64_LDST128_ABS_LO12_NC R_AARCH64
+pkg debug/elf, const R_AARCH64_LDST16_ABS_LO12_NC = 284
+pkg debug/elf, const R_AARCH64_LDST16_ABS_LO12_NC R_AARCH64
+pkg debug/elf, const R_AARCH64_LDST32_ABS_LO12_NC = 285
+pkg debug/elf, const R_AARCH64_LDST32_ABS_LO12_NC R_AARCH64
+pkg debug/elf, const R_AARCH64_LDST64_ABS_LO12_NC = 286
+pkg debug/elf, const R_AARCH64_LDST64_ABS_LO12_NC R_AARCH64
+pkg debug/elf, const R_AARCH64_LDST8_ABS_LO12_NC = 278
+pkg debug/elf, const R_AARCH64_LDST8_ABS_LO12_NC R_AARCH64
+pkg debug/elf, const R_AARCH64_LD_PREL_LO19 = 273
+pkg debug/elf, const R_AARCH64_LD_PREL_LO19 R_AARCH64
+pkg debug/elf, const R_AARCH64_MOVW_SABS_G0 = 270
+pkg debug/elf, const R_AARCH64_MOVW_SABS_G0 R_AARCH64
+pkg debug/elf, const R_AARCH64_MOVW_SABS_G1 = 271
+pkg debug/elf, const R_AARCH64_MOVW_SABS_G1 R_AARCH64
+pkg debug/elf, const R_AARCH64_MOVW_SABS_G2 = 272
+pkg debug/elf, const R_AARCH64_MOVW_SABS_G2 R_AARCH64
+pkg debug/elf, const R_AARCH64_MOVW_UABS_G0 = 263
+pkg debug/elf, const R_AARCH64_MOVW_UABS_G0 R_AARCH64
+pkg debug/elf, const R_AARCH64_MOVW_UABS_G0_NC = 264
+pkg debug/elf, const R_AARCH64_MOVW_UABS_G0_NC R_AARCH64
+pkg debug/elf, const R_AARCH64_MOVW_UABS_G1 = 265
+pkg debug/elf, const R_AARCH64_MOVW_UABS_G1 R_AARCH64
+pkg debug/elf, const R_AARCH64_MOVW_UABS_G1_NC = 266
+pkg debug/elf, const R_AARCH64_MOVW_UABS_G1_NC R_AARCH64
+pkg debug/elf, const R_AARCH64_MOVW_UABS_G2 = 267
+pkg debug/elf, const R_AARCH64_MOVW_UABS_G2 R_AARCH64
+pkg debug/elf, const R_AARCH64_MOVW_UABS_G2_NC = 268
+pkg debug/elf, const R_AARCH64_MOVW_UABS_G2_NC R_AARCH64
+pkg debug/elf, const R_AARCH64_MOVW_UABS_G3 = 269
+pkg debug/elf, const R_AARCH64_MOVW_UABS_G3 R_AARCH64
+pkg debug/elf, const R_AARCH64_NONE = 0
+pkg debug/elf, const R_AARCH64_NONE R_AARCH64
+pkg debug/elf, const R_AARCH64_NULL = 256
+pkg debug/elf, const R_AARCH64_NULL R_AARCH64
+pkg debug/elf, const R_AARCH64_P32_ABS16 = 2
+pkg debug/elf, const R_AARCH64_P32_ABS16 R_AARCH64
+pkg debug/elf, const R_AARCH64_P32_ABS32 = 1
+pkg debug/elf, const R_AARCH64_P32_ABS32 R_AARCH64
+pkg debug/elf, const R_AARCH64_P32_ADD_ABS_LO12_NC = 12
+pkg debug/elf, const R_AARCH64_P32_ADD_ABS_LO12_NC R_AARCH64
+pkg debug/elf, const R_AARCH64_P32_ADR_GOT_PAGE = 26
+pkg debug/elf, const R_AARCH64_P32_ADR_GOT_PAGE R_AARCH64
+pkg debug/elf, const R_AARCH64_P32_ADR_PREL_LO21 = 10
+pkg debug/elf, const R_AARCH64_P32_ADR_PREL_LO21 R_AARCH64
+pkg debug/elf, const R_AARCH64_P32_ADR_PREL_PG_HI21 = 11
+pkg debug/elf, const R_AARCH64_P32_ADR_PREL_PG_HI21 R_AARCH64
+pkg debug/elf, const R_AARCH64_P32_CALL26 = 21
+pkg debug/elf, const R_AARCH64_P32_CALL26 R_AARCH64
+pkg debug/elf, const R_AARCH64_P32_CONDBR19 = 19
+pkg debug/elf, const R_AARCH64_P32_CONDBR19 R_AARCH64
+pkg debug/elf, const R_AARCH64_P32_COPY = 180
+pkg debug/elf, const R_AARCH64_P32_COPY R_AARCH64
+pkg debug/elf, const R_AARCH64_P32_GLOB_DAT = 181
+pkg debug/elf, const R_AARCH64_P32_GLOB_DAT R_AARCH64
+pkg debug/elf, const R_AARCH64_P32_GOT_LD_PREL19 = 25
+pkg debug/elf, const R_AARCH64_P32_GOT_LD_PREL19 R_AARCH64
+pkg debug/elf, const R_AARCH64_P32_IRELATIVE = 188
+pkg debug/elf, const R_AARCH64_P32_IRELATIVE R_AARCH64
+pkg debug/elf, const R_AARCH64_P32_JUMP26 = 20
+pkg debug/elf, const R_AARCH64_P32_JUMP26 R_AARCH64
+pkg debug/elf, const R_AARCH64_P32_JUMP_SLOT = 182
+pkg debug/elf, const R_AARCH64_P32_JUMP_SLOT R_AARCH64
+pkg debug/elf, const R_AARCH64_P32_LD32_GOT_LO12_NC = 27
+pkg debug/elf, const R_AARCH64_P32_LD32_GOT_LO12_NC R_AARCH64
+pkg debug/elf, const R_AARCH64_P32_LDST128_ABS_LO12_NC = 17
+pkg debug/elf, const R_AARCH64_P32_LDST128_ABS_LO12_NC R_AARCH64
+pkg debug/elf, const R_AARCH64_P32_LDST16_ABS_LO12_NC = 14
+pkg debug/elf, const R_AARCH64_P32_LDST16_ABS_LO12_NC R_AARCH64
+pkg debug/elf, const R_AARCH64_P32_LDST32_ABS_LO12_NC = 15
+pkg debug/elf, const R_AARCH64_P32_LDST32_ABS_LO12_NC R_AARCH64
+pkg debug/elf, const R_AARCH64_P32_LDST64_ABS_LO12_NC = 16
+pkg debug/elf, const R_AARCH64_P32_LDST64_ABS_LO12_NC R_AARCH64
+pkg debug/elf, const R_AARCH64_P32_LDST8_ABS_LO12_NC = 13
+pkg debug/elf, const R_AARCH64_P32_LDST8_ABS_LO12_NC R_AARCH64
+pkg debug/elf, const R_AARCH64_P32_LD_PREL_LO19 = 9
+pkg debug/elf, const R_AARCH64_P32_LD_PREL_LO19 R_AARCH64
+pkg debug/elf, const R_AARCH64_P32_MOVW_SABS_G0 = 8
+pkg debug/elf, const R_AARCH64_P32_MOVW_SABS_G0 R_AARCH64
+pkg debug/elf, const R_AARCH64_P32_MOVW_UABS_G0 = 5
+pkg debug/elf, const R_AARCH64_P32_MOVW_UABS_G0 R_AARCH64
+pkg debug/elf, const R_AARCH64_P32_MOVW_UABS_G0_NC = 6
+pkg debug/elf, const R_AARCH64_P32_MOVW_UABS_G0_NC R_AARCH64
+pkg debug/elf, const R_AARCH64_P32_MOVW_UABS_G1 = 7
+pkg debug/elf, const R_AARCH64_P32_MOVW_UABS_G1 R_AARCH64
+pkg debug/elf, const R_AARCH64_P32_PREL16 = 4
+pkg debug/elf, const R_AARCH64_P32_PREL16 R_AARCH64
+pkg debug/elf, const R_AARCH64_P32_PREL32 = 3
+pkg debug/elf, const R_AARCH64_P32_PREL32 R_AARCH64
+pkg debug/elf, const R_AARCH64_P32_RELATIVE = 183
+pkg debug/elf, const R_AARCH64_P32_RELATIVE R_AARCH64
+pkg debug/elf, const R_AARCH64_P32_TLSDESC = 187
+pkg debug/elf, const R_AARCH64_P32_TLSDESC R_AARCH64
+pkg debug/elf, const R_AARCH64_P32_TLSDESC_ADD_LO12_NC = 126
+pkg debug/elf, const R_AARCH64_P32_TLSDESC_ADD_LO12_NC R_AARCH64
+pkg debug/elf, const R_AARCH64_P32_TLSDESC_ADR_PAGE21 = 124
+pkg debug/elf, const R_AARCH64_P32_TLSDESC_ADR_PAGE21 R_AARCH64
+pkg debug/elf, const R_AARCH64_P32_TLSDESC_ADR_PREL21 = 123
+pkg debug/elf, const R_AARCH64_P32_TLSDESC_ADR_PREL21 R_AARCH64
+pkg debug/elf, const R_AARCH64_P32_TLSDESC_CALL = 127
+pkg debug/elf, const R_AARCH64_P32_TLSDESC_CALL R_AARCH64
+pkg debug/elf, const R_AARCH64_P32_TLSDESC_LD32_LO12_NC = 125
+pkg debug/elf, const R_AARCH64_P32_TLSDESC_LD32_LO12_NC R_AARCH64
+pkg debug/elf, const R_AARCH64_P32_TLSDESC_LD_PREL19 = 122
+pkg debug/elf, const R_AARCH64_P32_TLSDESC_LD_PREL19 R_AARCH64
+pkg debug/elf, const R_AARCH64_P32_TLSGD_ADD_LO12_NC = 82
+pkg debug/elf, const R_AARCH64_P32_TLSGD_ADD_LO12_NC R_AARCH64
+pkg debug/elf, const R_AARCH64_P32_TLSGD_ADR_PAGE21 = 81
+pkg debug/elf, const R_AARCH64_P32_TLSGD_ADR_PAGE21 R_AARCH64
+pkg debug/elf, const R_AARCH64_P32_TLSIE_ADR_GOTTPREL_PAGE21 = 103
+pkg debug/elf, const R_AARCH64_P32_TLSIE_ADR_GOTTPREL_PAGE21 R_AARCH64
+pkg debug/elf, const R_AARCH64_P32_TLSIE_LD32_GOTTPREL_LO12_NC = 104
+pkg debug/elf, const R_AARCH64_P32_TLSIE_LD32_GOTTPREL_LO12_NC R_AARCH64
+pkg debug/elf, const R_AARCH64_P32_TLSIE_LD_GOTTPREL_PREL19 = 105
+pkg debug/elf, const R_AARCH64_P32_TLSIE_LD_GOTTPREL_PREL19 R_AARCH64
+pkg debug/elf, const R_AARCH64_P32_TLSLE_ADD_TPREL_HI12 = 109
+pkg debug/elf, const R_AARCH64_P32_TLSLE_ADD_TPREL_HI12 R_AARCH64
+pkg debug/elf, const R_AARCH64_P32_TLSLE_ADD_TPREL_LO12 = 110
+pkg debug/elf, const R_AARCH64_P32_TLSLE_ADD_TPREL_LO12 R_AARCH64
+pkg debug/elf, const R_AARCH64_P32_TLSLE_ADD_TPREL_LO12_NC = 111
+pkg debug/elf, const R_AARCH64_P32_TLSLE_ADD_TPREL_LO12_NC R_AARCH64
+pkg debug/elf, const R_AARCH64_P32_TLSLE_MOVW_TPREL_G0 = 107
+pkg debug/elf, const R_AARCH64_P32_TLSLE_MOVW_TPREL_G0 R_AARCH64
+pkg debug/elf, const R_AARCH64_P32_TLSLE_MOVW_TPREL_G0_NC = 108
+pkg debug/elf, const R_AARCH64_P32_TLSLE_MOVW_TPREL_G0_NC R_AARCH64
+pkg debug/elf, const R_AARCH64_P32_TLSLE_MOVW_TPREL_G1 = 106
+pkg debug/elf, const R_AARCH64_P32_TLSLE_MOVW_TPREL_G1 R_AARCH64
+pkg debug/elf, const R_AARCH64_P32_TLS_DTPMOD = 184
+pkg debug/elf, const R_AARCH64_P32_TLS_DTPMOD R_AARCH64
+pkg debug/elf, const R_AARCH64_P32_TLS_DTPREL = 185
+pkg debug/elf, const R_AARCH64_P32_TLS_DTPREL R_AARCH64
+pkg debug/elf, const R_AARCH64_P32_TLS_TPREL = 186
+pkg debug/elf, const R_AARCH64_P32_TLS_TPREL R_AARCH64
+pkg debug/elf, const R_AARCH64_P32_TSTBR14 = 18
+pkg debug/elf, const R_AARCH64_P32_TSTBR14 R_AARCH64
+pkg debug/elf, const R_AARCH64_PREL16 = 262
+pkg debug/elf, const R_AARCH64_PREL16 R_AARCH64
+pkg debug/elf, const R_AARCH64_PREL32 = 261
+pkg debug/elf, const R_AARCH64_PREL32 R_AARCH64
+pkg debug/elf, const R_AARCH64_PREL64 = 260
+pkg debug/elf, const R_AARCH64_PREL64 R_AARCH64
+pkg debug/elf, const R_AARCH64_RELATIVE = 1027
+pkg debug/elf, const R_AARCH64_RELATIVE R_AARCH64
+pkg debug/elf, const R_AARCH64_TLSDESC = 1031
+pkg debug/elf, const R_AARCH64_TLSDESC R_AARCH64
+pkg debug/elf, const R_AARCH64_TLSDESC_ADD = 568
+pkg debug/elf, const R_AARCH64_TLSDESC_ADD R_AARCH64
+pkg debug/elf, const R_AARCH64_TLSDESC_ADD_LO12_NC = 564
+pkg debug/elf, const R_AARCH64_TLSDESC_ADD_LO12_NC R_AARCH64
+pkg debug/elf, const R_AARCH64_TLSDESC_ADR_PAGE21 = 562
+pkg debug/elf, const R_AARCH64_TLSDESC_ADR_PAGE21 R_AARCH64
+pkg debug/elf, const R_AARCH64_TLSDESC_ADR_PREL21 = 561
+pkg debug/elf, const R_AARCH64_TLSDESC_ADR_PREL21 R_AARCH64
+pkg debug/elf, const R_AARCH64_TLSDESC_CALL = 569
+pkg debug/elf, const R_AARCH64_TLSDESC_CALL R_AARCH64
+pkg debug/elf, const R_AARCH64_TLSDESC_LD64_LO12_NC = 563
+pkg debug/elf, const R_AARCH64_TLSDESC_LD64_LO12_NC R_AARCH64
+pkg debug/elf, const R_AARCH64_TLSDESC_LDR = 567
+pkg debug/elf, const R_AARCH64_TLSDESC_LDR R_AARCH64
+pkg debug/elf, const R_AARCH64_TLSDESC_LD_PREL19 = 560
+pkg debug/elf, const R_AARCH64_TLSDESC_LD_PREL19 R_AARCH64
+pkg debug/elf, const R_AARCH64_TLSDESC_OFF_G0_NC = 566
+pkg debug/elf, const R_AARCH64_TLSDESC_OFF_G0_NC R_AARCH64
+pkg debug/elf, const R_AARCH64_TLSDESC_OFF_G1 = 565
+pkg debug/elf, const R_AARCH64_TLSDESC_OFF_G1 R_AARCH64
+pkg debug/elf, const R_AARCH64_TLSGD_ADD_LO12_NC = 514
+pkg debug/elf, const R_AARCH64_TLSGD_ADD_LO12_NC R_AARCH64
+pkg debug/elf, const R_AARCH64_TLSGD_ADR_PAGE21 = 513
+pkg debug/elf, const R_AARCH64_TLSGD_ADR_PAGE21 R_AARCH64
+pkg debug/elf, const R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 = 541
+pkg debug/elf, const R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 R_AARCH64
+pkg debug/elf, const R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC = 542
+pkg debug/elf, const R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC R_AARCH64
+pkg debug/elf, const R_AARCH64_TLSIE_LD_GOTTPREL_PREL19 = 543
+pkg debug/elf, const R_AARCH64_TLSIE_LD_GOTTPREL_PREL19 R_AARCH64
+pkg debug/elf, const R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC = 540
+pkg debug/elf, const R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC R_AARCH64
+pkg debug/elf, const R_AARCH64_TLSIE_MOVW_GOTTPREL_G1 = 539
+pkg debug/elf, const R_AARCH64_TLSIE_MOVW_GOTTPREL_G1 R_AARCH64
+pkg debug/elf, const R_AARCH64_TLSLE_ADD_TPREL_HI12 = 549
+pkg debug/elf, const R_AARCH64_TLSLE_ADD_TPREL_HI12 R_AARCH64
+pkg debug/elf, const R_AARCH64_TLSLE_ADD_TPREL_LO12 = 550
+pkg debug/elf, const R_AARCH64_TLSLE_ADD_TPREL_LO12 R_AARCH64
+pkg debug/elf, const R_AARCH64_TLSLE_ADD_TPREL_LO12_NC = 551
+pkg debug/elf, const R_AARCH64_TLSLE_ADD_TPREL_LO12_NC R_AARCH64
+pkg debug/elf, const R_AARCH64_TLSLE_MOVW_TPREL_G0 = 547
+pkg debug/elf, const R_AARCH64_TLSLE_MOVW_TPREL_G0 R_AARCH64
+pkg debug/elf, const R_AARCH64_TLSLE_MOVW_TPREL_G0_NC = 548
+pkg debug/elf, const R_AARCH64_TLSLE_MOVW_TPREL_G0_NC R_AARCH64
+pkg debug/elf, const R_AARCH64_TLSLE_MOVW_TPREL_G1 = 545
+pkg debug/elf, const R_AARCH64_TLSLE_MOVW_TPREL_G1 R_AARCH64
+pkg debug/elf, const R_AARCH64_TLSLE_MOVW_TPREL_G1_NC = 546
+pkg debug/elf, const R_AARCH64_TLSLE_MOVW_TPREL_G1_NC R_AARCH64
+pkg debug/elf, const R_AARCH64_TLSLE_MOVW_TPREL_G2 = 544
+pkg debug/elf, const R_AARCH64_TLSLE_MOVW_TPREL_G2 R_AARCH64
+pkg debug/elf, const R_AARCH64_TLS_DTPMOD64 = 1028
+pkg debug/elf, const R_AARCH64_TLS_DTPMOD64 R_AARCH64
+pkg debug/elf, const R_AARCH64_TLS_DTPREL64 = 1029
+pkg debug/elf, const R_AARCH64_TLS_DTPREL64 R_AARCH64
+pkg debug/elf, const R_AARCH64_TLS_TPREL64 = 1030
+pkg debug/elf, const R_AARCH64_TLS_TPREL64 R_AARCH64
+pkg debug/elf, const R_AARCH64_TSTBR14 = 279
+pkg debug/elf, const R_AARCH64_TSTBR14 R_AARCH64
+pkg debug/elf, method (R_AARCH64) GoString() string
+pkg debug/elf, method (R_AARCH64) String() string
+pkg debug/elf, type R_AARCH64 int
+
+# CL 107530043 debug/elf: add (*File).DynamicSymbols, ErrNoSymbols, and tests for (*File).Symbols and (*File).DynamicSymbols, and formalize symbol order., Pietro Gagliardi <pietro10 at mac.com>
+pkg debug/elf, method (*File) DynamicSymbols() ([]Symbol, error)
+pkg debug/elf, var ErrNoSymbols error
+
+# CL 106460044 debug/plan9obj, cmd/addr2line: on Plan 9 use a.out header, Aram Hăvărneanu <aram at mgk.ro>
+pkg debug/plan9obj, type FileHeader struct, HdrSize uint64
+pkg debug/plan9obj, type FileHeader struct, LoadAddress uint64
+
+# CL 122960043 encoding/xml: add InputOffset method to Decoder, Russ Cox <rsc at golang.org>
+pkg encoding/xml, method (*Decoder) InputOffset() int64
+
+# CL 124940043 cmd/go, go/build: implement import comment checking, Russ Cox <rsc at golang.org>
+pkg go/build, const ImportComment = 4
+pkg go/build, const ImportComment ImportMode
+pkg go/build, type Package struct, ImportComment string
+
+# CL 155050043 go/build: Return MultiplePackageError on importing a dir containing multiple packages, Jens Frederich <jfrederich at gmail.com>
+pkg go/build, method (*MultiplePackageError) Error() string
+pkg go/build, type MultiplePackageError struct
+pkg go/build, type MultiplePackageError struct, Dir string
+pkg go/build, type MultiplePackageError struct, Files []string
+pkg go/build, type MultiplePackageError struct, Packages []string
+
+# CL 135110044 go/token: implement PositionFor accessors, Robert Griesemer <gri at golang.org>
+pkg go/token, method (*File) PositionFor(Pos, bool) Position
+pkg go/token, method (*FileSet) PositionFor(Pos, bool) Position
+
+# CL 109000049 image: add RGBAAt, Gray16At, etc., ChaiShushan <chaishushan at gmail.com>
+pkg image, method (*Alpha) AlphaAt(int, int) color.Alpha
+pkg image, method (*Alpha16) Alpha16At(int, int) color.Alpha16
+pkg image, method (*Gray) GrayAt(int, int) color.Gray
+pkg image, method (*Gray16) Gray16At(int, int) color.Gray16
+pkg image, method (*NRGBA) NRGBAAt(int, int) color.NRGBA
+pkg image, method (*NRGBA64) NRGBA64At(int, int) color.NRGBA64
+pkg image, method (*RGBA) RGBAAt(int, int) color.RGBA
+pkg image, method (*RGBA64) RGBA64At(int, int) color.RGBA64
+pkg image, method (*YCbCr) YCbCrAt(int, int) color.YCbCr
+
+# CL 129190043 png: make the encoder configurable, Jeff R. Allen <jra at nella.org>
+pkg image/png, const BestCompression = -3
+pkg image/png, const BestCompression CompressionLevel
+pkg image/png, const BestSpeed = -2
+pkg image/png, const BestSpeed CompressionLevel
+pkg image/png, const DefaultCompression = 0
+pkg image/png, const DefaultCompression CompressionLevel
+pkg image/png, const NoCompression = -1
+pkg image/png, const NoCompression CompressionLevel
+pkg image/png, method (*Encoder) Encode(io.Writer, image.Image) error
+pkg image/png, type CompressionLevel int
+pkg image/png, type Encoder struct
+pkg image/png, type Encoder struct, CompressionLevel CompressionLevel
+
+# CL 101750048 math: implement Nextafter32, Robert Griesemer <gri at golang.org>
+pkg math, func Nextafter32(float32, float32) float32
+
+# CL 93550043 math/big: implement Rat.Float32, Robert Griesemer <gri at golang.org>
+pkg math/big, method (*Rat) Float32() (float32, bool)
+
+# CL 76540043 net/http: add BasicAuth method to *http.Request, Kelsey Hightower <kelsey.hightower at gmail.com>
+pkg net/http, method (*Request) BasicAuth() (string, string, bool)
+
+# CL 137940043 net/http: add Transport.DialTLS hook, Brad Fitzpatrick <bradfitz at golang.org>
+pkg net/http, type Transport struct, DialTLS func(string, string) (net.Conn, error)
+
+# CL 132750043 net/http/httputil: Pass a Logger to ReverseProxy, allowing the user to control logging., Mark Theunissen <mark.theunissen at gmail.com>
+pkg net/http/httputil, type ReverseProxy struct, ErrorLog *log.Logger
+
+# CL 148370043 os, syscall: add Unsetenv, Brad Fitzpatrick <bradfitz at golang.org>
+pkg os, func Unsetenv(string) error
+pkg syscall, func Unsetenv(string) error
+
+# CL 144020043 reflect: add Type.Comparable, Russ Cox <rsc at golang.org>
+pkg reflect, type Type interface, Comparable() bool
+
+# CL 153670043 runtime: add PauseEnd array to MemStats and GCStats, Jens Frederich <jfrederich at gmail.com>
+pkg runtime, type MemStats struct, PauseEnd [256]uint64
+pkg runtime/debug, type GCStats struct, PauseEnd []time.Time
+
+# CL 136710045 sync/atomic: add Value, Dmitriy Vyukov <dvyukov at google.com>
+pkg sync/atomic, method (*Value) Load() interface{}
+pkg sync/atomic, method (*Value) Store(interface{})
+pkg sync/atomic, type Value struct
+
+# CL 126190043 syscall: support UID/GID map files for Linux user namespaces, Mrunal Patel <mrunalp at gmail.com>
+pkg syscall (linux-386), type SysProcAttr struct, GidMappings []SysProcIDMap
+pkg syscall (linux-386), type SysProcAttr struct, UidMappings []SysProcIDMap
+pkg syscall (linux-386), type SysProcIDMap struct
+pkg syscall (linux-386), type SysProcIDMap struct, ContainerID int
+pkg syscall (linux-386), type SysProcIDMap struct, HostID int
+pkg syscall (linux-386), type SysProcIDMap struct, Size int
+pkg syscall (linux-386-cgo), type SysProcAttr struct, GidMappings []SysProcIDMap
+pkg syscall (linux-386-cgo), type SysProcAttr struct, UidMappings []SysProcIDMap
+pkg syscall (linux-386-cgo), type SysProcIDMap struct
+pkg syscall (linux-386-cgo), type SysProcIDMap struct, ContainerID int
+pkg syscall (linux-386-cgo), type SysProcIDMap struct, HostID int
+pkg syscall (linux-386-cgo), type SysProcIDMap struct, Size int
+pkg syscall (linux-amd64), type SysProcAttr struct, GidMappings []SysProcIDMap
+pkg syscall (linux-amd64), type SysProcAttr struct, UidMappings []SysProcIDMap
+pkg syscall (linux-amd64), type SysProcIDMap struct
+pkg syscall (linux-amd64), type SysProcIDMap struct, ContainerID int
+pkg syscall (linux-amd64), type SysProcIDMap struct, HostID int
+pkg syscall (linux-amd64), type SysProcIDMap struct, Size int
+pkg syscall (linux-amd64-cgo), type SysProcAttr struct, GidMappings []SysProcIDMap
+pkg syscall (linux-amd64-cgo), type SysProcAttr struct, UidMappings []SysProcIDMap
+pkg syscall (linux-amd64-cgo), type SysProcIDMap struct
+pkg syscall (linux-amd64-cgo), type SysProcIDMap struct, ContainerID int
+pkg syscall (linux-amd64-cgo), type SysProcIDMap struct, HostID int
+pkg syscall (linux-amd64-cgo), type SysProcIDMap struct, Size int
+pkg syscall (linux-arm), type SysProcAttr struct, GidMappings []SysProcIDMap
+pkg syscall (linux-arm), type SysProcAttr struct, UidMappings []SysProcIDMap
+pkg syscall (linux-arm), type SysProcIDMap struct
+pkg syscall (linux-arm), type SysProcIDMap struct, ContainerID int
+pkg syscall (linux-arm), type SysProcIDMap struct, HostID int
+pkg syscall (linux-arm), type SysProcIDMap struct, Size int
+pkg syscall (linux-arm-cgo), type SysProcAttr struct, GidMappings []SysProcIDMap
+pkg syscall (linux-arm-cgo), type SysProcAttr struct, UidMappings []SysProcIDMap
+pkg syscall (linux-arm-cgo), type SysProcIDMap struct
+pkg syscall (linux-arm-cgo), type SysProcIDMap struct, ContainerID int
+pkg syscall (linux-arm-cgo), type SysProcIDMap struct, HostID int
+pkg syscall (linux-arm-cgo), type SysProcIDMap struct, Size int
+
+# CL 122200043 net: fix CNAME resolving on Windows, Egon Elbre <egonelbre at gmail.com>
+pkg syscall (windows-386), const DNS_INFO_NO_RECORDS = 9501
+pkg syscall (windows-386), const DNS_INFO_NO_RECORDS ideal-int
+pkg syscall (windows-386), const DnsSectionAdditional = 3
+pkg syscall (windows-386), const DnsSectionAdditional ideal-int
+pkg syscall (windows-386), const DnsSectionAnswer = 1
+pkg syscall (windows-386), const DnsSectionAnswer ideal-int
+pkg syscall (windows-386), const DnsSectionAuthority = 2
+pkg syscall (windows-386), const DnsSectionAuthority ideal-int
+pkg syscall (windows-386), const DnsSectionQuestion = 0
+pkg syscall (windows-386), const DnsSectionQuestion ideal-int
+pkg syscall (windows-386), func DnsNameCompare(*uint16, *uint16) bool
+pkg syscall (windows-amd64), const DNS_INFO_NO_RECORDS = 9501
+pkg syscall (windows-amd64), const DNS_INFO_NO_RECORDS ideal-int
+pkg syscall (windows-amd64), const DnsSectionAdditional = 3
+pkg syscall (windows-amd64), const DnsSectionAdditional ideal-int
+pkg syscall (windows-amd64), const DnsSectionAnswer = 1
+pkg syscall (windows-amd64), const DnsSectionAnswer ideal-int
+pkg syscall (windows-amd64), const DnsSectionAuthority = 2
+pkg syscall (windows-amd64), const DnsSectionAuthority ideal-int
+pkg syscall (windows-amd64), const DnsSectionQuestion = 0
+pkg syscall (windows-amd64), const DnsSectionQuestion ideal-int
+pkg syscall (windows-amd64), func DnsNameCompare(*uint16, *uint16) bool
+
+# CL 86160044 os: Implement symlink support for Windows, Michael Fraenkel <michael.fraenkel at gmail.com>
+pkg syscall (windows-386), const ERROR_PRIVILEGE_NOT_HELD = 1314
+pkg syscall (windows-386), const ERROR_PRIVILEGE_NOT_HELD Errno
+pkg syscall (windows-amd64), const ERROR_PRIVILEGE_NOT_HELD = 1314
+pkg syscall (windows-amd64), const ERROR_PRIVILEGE_NOT_HELD Errno
+
+# CL 86160044 os: Implement symlink support for Windows, Michael Fraenkel <michael.fraenkel at gmail.com>
+pkg syscall (windows-386), const FILE_ATTRIBUTE_REPARSE_POINT = 1024
+pkg syscall (windows-386), const FILE_ATTRIBUTE_REPARSE_POINT ideal-int
+pkg syscall (windows-386), const FILE_FLAG_OPEN_REPARSE_POINT = 2097152
+pkg syscall (windows-386), const FILE_FLAG_OPEN_REPARSE_POINT ideal-int
+pkg syscall (windows-386), const FSCTL_GET_REPARSE_POINT = 589992
+pkg syscall (windows-386), const FSCTL_GET_REPARSE_POINT ideal-int
+pkg syscall (windows-386), const IO_REPARSE_TAG_SYMLINK = 2684354572
+pkg syscall (windows-386), const IO_REPARSE_TAG_SYMLINK ideal-int
+pkg syscall (windows-386), const MAXIMUM_REPARSE_DATA_BUFFER_SIZE = 16384
+pkg syscall (windows-386), const MAXIMUM_REPARSE_DATA_BUFFER_SIZE ideal-int
+pkg syscall (windows-386), const SYMBOLIC_LINK_FLAG_DIRECTORY = 1
+pkg syscall (windows-386), const SYMBOLIC_LINK_FLAG_DIRECTORY ideal-int
+pkg syscall (windows-386), func CreateHardLink(*uint16, *uint16, uintptr) error
+pkg syscall (windows-386), func CreateSymbolicLink(*uint16, *uint16, uint32) error
+pkg syscall (windows-386), func DeviceIoControl(Handle, uint32, *uint8, uint32, *uint8, uint32, *uint32, *Overlapped) error
+pkg syscall (windows-386), func LoadCreateSymbolicLink() error
+pkg syscall (windows-amd64), const FILE_ATTRIBUTE_REPARSE_POINT = 1024
+pkg syscall (windows-amd64), const FILE_ATTRIBUTE_REPARSE_POINT ideal-int
+pkg syscall (windows-amd64), const FILE_FLAG_OPEN_REPARSE_POINT = 2097152
+pkg syscall (windows-amd64), const FILE_FLAG_OPEN_REPARSE_POINT ideal-int
+pkg syscall (windows-amd64), const FSCTL_GET_REPARSE_POINT = 589992
+pkg syscall (windows-amd64), const FSCTL_GET_REPARSE_POINT ideal-int
+pkg syscall (windows-amd64), const IO_REPARSE_TAG_SYMLINK = 2684354572
+pkg syscall (windows-amd64), const IO_REPARSE_TAG_SYMLINK ideal-int
+pkg syscall (windows-amd64), const MAXIMUM_REPARSE_DATA_BUFFER_SIZE = 16384
+pkg syscall (windows-amd64), const MAXIMUM_REPARSE_DATA_BUFFER_SIZE ideal-int
+pkg syscall (windows-amd64), const SYMBOLIC_LINK_FLAG_DIRECTORY = 1
+pkg syscall (windows-amd64), const SYMBOLIC_LINK_FLAG_DIRECTORY ideal-int
+pkg syscall (windows-amd64), func CreateHardLink(*uint16, *uint16, uintptr) error
+pkg syscall (windows-amd64), func CreateSymbolicLink(*uint16, *uint16, uint32) error
+pkg syscall (windows-amd64), func DeviceIoControl(Handle, uint32, *uint8, uint32, *uint8, uint32, *uint32, *Overlapped) error
+pkg syscall (windows-amd64), func LoadCreateSymbolicLink() error
+
+# CL 149510043 net: disable SIO_UDP_CONNRESET behavior on windows., Ron Hashimoto <mail at h2so5.net>
+pkg syscall (windows-386), const SIO_UDP_CONNRESET = 2550136844
+pkg syscall (windows-386), const SIO_UDP_CONNRESET ideal-int
+pkg syscall (windows-amd64), const SIO_UDP_CONNRESET = 2550136844
+pkg syscall (windows-amd64), const SIO_UDP_CONNRESET ideal-int
+
+# CL 102320044 syscall: implement syscall.Getppid() on Windows, Alan Shreve <alan at inconshreveable.com>
+pkg syscall (windows-386), const TH32CS_INHERIT = 2147483648
+pkg syscall (windows-386), const TH32CS_INHERIT ideal-int
+pkg syscall (windows-386), const TH32CS_SNAPALL = 15
+pkg syscall (windows-386), const TH32CS_SNAPALL ideal-int
+pkg syscall (windows-386), const TH32CS_SNAPHEAPLIST = 1
+pkg syscall (windows-386), const TH32CS_SNAPHEAPLIST ideal-int
+pkg syscall (windows-386), const TH32CS_SNAPMODULE = 8
+pkg syscall (windows-386), const TH32CS_SNAPMODULE ideal-int
+pkg syscall (windows-386), const TH32CS_SNAPMODULE32 = 16
+pkg syscall (windows-386), const TH32CS_SNAPMODULE32 ideal-int
+pkg syscall (windows-386), const TH32CS_SNAPPROCESS = 2
+pkg syscall (windows-386), const TH32CS_SNAPPROCESS ideal-int
+pkg syscall (windows-386), const TH32CS_SNAPTHREAD = 4
+pkg syscall (windows-386), const TH32CS_SNAPTHREAD ideal-int
+pkg syscall (windows-386), func CreateToolhelp32Snapshot(uint32, uint32) (Handle, error)
+pkg syscall (windows-386), func Process32First(Handle, *ProcessEntry32) error
+pkg syscall (windows-386), func Process32Next(Handle, *ProcessEntry32) error
+pkg syscall (windows-386), type ProcessEntry32 struct
+pkg syscall (windows-386), type ProcessEntry32 struct, DefaultHeapID uintptr
+pkg syscall (windows-386), type ProcessEntry32 struct, ExeFile [260]uint16
+pkg syscall (windows-386), type ProcessEntry32 struct, Flags uint32
+pkg syscall (windows-386), type ProcessEntry32 struct, ModuleID uint32
+pkg syscall (windows-386), type ProcessEntry32 struct, ParentProcessID uint32
+pkg syscall (windows-386), type ProcessEntry32 struct, PriClassBase int32
+pkg syscall (windows-386), type ProcessEntry32 struct, ProcessID uint32
+pkg syscall (windows-386), type ProcessEntry32 struct, Size uint32
+pkg syscall (windows-386), type ProcessEntry32 struct, Threads uint32
+pkg syscall (windows-386), type ProcessEntry32 struct, Usage uint32
+pkg syscall (windows-amd64), const TH32CS_INHERIT = 2147483648
+pkg syscall (windows-amd64), const TH32CS_INHERIT ideal-int
+pkg syscall (windows-amd64), const TH32CS_SNAPALL = 15
+pkg syscall (windows-amd64), const TH32CS_SNAPALL ideal-int
+pkg syscall (windows-amd64), const TH32CS_SNAPHEAPLIST = 1
+pkg syscall (windows-amd64), const TH32CS_SNAPHEAPLIST ideal-int
+pkg syscall (windows-amd64), const TH32CS_SNAPMODULE = 8
+pkg syscall (windows-amd64), const TH32CS_SNAPMODULE ideal-int
+pkg syscall (windows-amd64), const TH32CS_SNAPMODULE32 = 16
+pkg syscall (windows-amd64), const TH32CS_SNAPMODULE32 ideal-int
+pkg syscall (windows-amd64), const TH32CS_SNAPPROCESS = 2
+pkg syscall (windows-amd64), const TH32CS_SNAPPROCESS ideal-int
+pkg syscall (windows-amd64), const TH32CS_SNAPTHREAD = 4
+pkg syscall (windows-amd64), const TH32CS_SNAPTHREAD ideal-int
+pkg syscall (windows-amd64), func CreateToolhelp32Snapshot(uint32, uint32) (Handle, error)
+pkg syscall (windows-amd64), func Process32First(Handle, *ProcessEntry32) error
+pkg syscall (windows-amd64), func Process32Next(Handle, *ProcessEntry32) error
+pkg syscall (windows-amd64), type ProcessEntry32 struct
+pkg syscall (windows-amd64), type ProcessEntry32 struct, DefaultHeapID uintptr
+pkg syscall (windows-amd64), type ProcessEntry32 struct, ExeFile [260]uint16
+pkg syscall (windows-amd64), type ProcessEntry32 struct, Flags uint32
+pkg syscall (windows-amd64), type ProcessEntry32 struct, ModuleID uint32
+pkg syscall (windows-amd64), type ProcessEntry32 struct, ParentProcessID uint32
+pkg syscall (windows-amd64), type ProcessEntry32 struct, PriClassBase int32
+pkg syscall (windows-amd64), type ProcessEntry32 struct, ProcessID uint32
+pkg syscall (windows-amd64), type ProcessEntry32 struct, Size uint32
+pkg syscall (windows-amd64), type ProcessEntry32 struct, Threads uint32
+pkg syscall (windows-amd64), type ProcessEntry32 struct, Usage uint32
+
+# CL 127740043 os: make SameFile handle paths like c:a.txt properly, Alex Brainman <alex.brainman at gmail.com>
+pkg syscall (windows-386), func FullPath(string) (string, error)
+pkg syscall (windows-amd64), func FullPath(string) (string, error)
+
+# CL 98150043 testing: add Coverage function, Russ Cox <rsc at golang.org>
+pkg testing, func Coverage() float64
+
+# CL 148770043 cmd/go, testing: add TestMain support, Russ Cox <rsc at golang.org>
+pkg testing, func MainStart(func(string, string) (bool, error), []InternalTest, []InternalBenchmark, []InternalExample) *M
+pkg testing, method (*M) Run() int
+pkg testing, type M struct
+
+# CL 108030044 text/scanner: provide facility for custom identifiers, Robert Griesemer <gri at golang.org>
+pkg text/scanner, type Scanner struct, IsIdentRune func(int32, int) bool
+
+# CL 130620043 text/template: add back pointer to Nodes for better error generation, Rob Pike <r at golang.org>
+pkg text/template/parse, type DotNode struct, embedded NodeType
+pkg text/template/parse, type NilNode struct, embedded NodeType
+pkg text/template/parse, method (*BranchNode) Copy() Node
+pkg text/template/parse, method (*IdentifierNode) SetTree(*Tree) *IdentifierNode
+pkg html/template, type Error struct, Node parse.Node
+
+# CL 127470043 unicode: strconv: regexp: Upgrade to Unicode 7.0.0., Marcel van Lohuizen <mpvl at golang.org>
+pkg unicode, const Version = "7.0.0"
+pkg unicode, var Bassa_Vah *RangeTable
+pkg unicode, var Caucasian_Albanian *RangeTable
+pkg unicode, var Duployan *RangeTable
+pkg unicode, var Elbasan *RangeTable
+pkg unicode, var Grantha *RangeTable
+pkg unicode, var Khojki *RangeTable
+pkg unicode, var Khudawadi *RangeTable
+pkg unicode, var Linear_A *RangeTable
+pkg unicode, var Mahajani *RangeTable
+pkg unicode, var Manichaean *RangeTable
+pkg unicode, var Mende_Kikakui *RangeTable
+pkg unicode, var Modi *RangeTable
+pkg unicode, var Mro *RangeTable
+pkg unicode, var Nabataean *RangeTable
+pkg unicode, var Old_North_Arabian *RangeTable
+pkg unicode, var Old_Permic *RangeTable
+pkg unicode, var Pahawh_Hmong *RangeTable
+pkg unicode, var Palmyrene *RangeTable
+pkg unicode, var Pau_Cin_Hau *RangeTable
+pkg unicode, var Psalter_Pahlavi *RangeTable
+pkg unicode, var Siddham *RangeTable
+pkg unicode, var Tirhuta *RangeTable
+pkg unicode, var Warang_Citi *RangeTable
diff --git a/api/next.txt b/api/next.txt
index 5e49b3f..e8570a6 100644
--- a/api/next.txt
+++ b/api/next.txt
@@ -115,3 +115,27 @@ pkg debug/goobj, type Var struct, Kind int
 pkg debug/goobj, type Var struct, Name string
 pkg debug/goobj, type Var struct, Offset int
 pkg debug/goobj, type Var struct, Type SymID
+pkg unicode, const Version = "7.0.0"
+pkg unicode, var Bassa_Vah *RangeTable
+pkg unicode, var Caucasian_Albanian *RangeTable
+pkg unicode, var Duployan *RangeTable
+pkg unicode, var Elbasan *RangeTable
+pkg unicode, var Grantha *RangeTable
+pkg unicode, var Khojki *RangeTable
+pkg unicode, var Khudawadi *RangeTable
+pkg unicode, var Linear_A *RangeTable
+pkg unicode, var Mahajani *RangeTable
+pkg unicode, var Manichaean *RangeTable
+pkg unicode, var Mende_Kikakui *RangeTable
+pkg unicode, var Modi *RangeTable
+pkg unicode, var Mro *RangeTable
+pkg unicode, var Nabataean *RangeTable
+pkg unicode, var Old_North_Arabian *RangeTable
+pkg unicode, var Old_Permic *RangeTable
+pkg unicode, var Pahawh_Hmong *RangeTable
+pkg unicode, var Palmyrene *RangeTable
+pkg unicode, var Pau_Cin_Hau *RangeTable
+pkg unicode, var Psalter_Pahlavi *RangeTable
+pkg unicode, var Siddham *RangeTable
+pkg unicode, var Tirhuta *RangeTable
+pkg unicode, var Warang_Citi *RangeTable
diff --git a/doc/articles/go_command.html b/doc/articles/go_command.html
index fddca41..2978628 100644
--- a/doc/articles/go_command.html
+++ b/doc/articles/go_command.html
@@ -78,17 +78,18 @@ well-established conventions.</p>
 source code.  For Bitbucket, GitHub, Google Code, and Launchpad, the
 root directory of the repository is identified by the repository's
 main URL, without the <code>http://</code> prefix.  Subdirectories are named by
-adding to that path.  For example, the supplemental networking
-libraries for Go are obtained by running</p>
+adding to that path.
+For example, the Go example programs are obtained by running</p>
 
 <pre>
-hg clone http://code.google.com/p/go.net
+git clone https://github.com/golang/example
 </pre>
 
 <p>and thus the import path for the root directory of that repository is
-"<code>code.google.com/p/go.net</code>".  The websocket package is stored in a
-subdirectory, so its import path is
-"<code>code.google.com/p/go.net/websocket</code>".</p>
+"<code>github.com/golang/example</code>".
+The <a href="https://godoc.org/github.com/golang/example/stringutil">stringutil</a>
+package is stored in a subdirectory, so its import path is
+"<code>github.com/golang/example/stringutil</code>".</p>
 
 <p>These paths are on the long side, but in exchange we get an
 automatically managed name space for import paths and the ability for
@@ -99,7 +100,7 @@ deduce where to obtain the source code.</p>
 in a known way from the import path.  Specifically, the first choice
 is <code>$GOPATH/src/<import-path></code>.  If <code>$GOPATH</code> is
 unset, the go command will fall back to storing source code alongside the
-standard Go packages, in <code>$GOROOT/src/pkg/<import-path></code>.
+standard Go packages, in <code>$GOROOT/src/<import-path></code>.
 If <code>$GOPATH</code> is set to a list of paths, the go command tries
 <code><dir>/src/<import-path></code> for each of the directories in
 that list.</p>
diff --git a/doc/articles/race_detector.html b/doc/articles/race_detector.html
index 282db8b..6defd98 100644
--- a/doc/articles/race_detector.html
+++ b/doc/articles/race_detector.html
@@ -57,35 +57,35 @@ Here is an example:
 WARNING: DATA RACE
 Read by goroutine 185:
   net.(*pollServer).AddFD()
-      src/pkg/net/fd_unix.go:89 +0x398
+      src/net/fd_unix.go:89 +0x398
   net.(*pollServer).WaitWrite()
-      src/pkg/net/fd_unix.go:247 +0x45
+      src/net/fd_unix.go:247 +0x45
   net.(*netFD).Write()
-      src/pkg/net/fd_unix.go:540 +0x4d4
+      src/net/fd_unix.go:540 +0x4d4
   net.(*conn).Write()
-      src/pkg/net/net.go:129 +0x101
+      src/net/net.go:129 +0x101
   net.func·060()
-      src/pkg/net/timeout_test.go:603 +0xaf
+      src/net/timeout_test.go:603 +0xaf
 
 Previous write by goroutine 184:
   net.setWriteDeadline()
-      src/pkg/net/sockopt_posix.go:135 +0xdf
+      src/net/sockopt_posix.go:135 +0xdf
   net.setDeadline()
-      src/pkg/net/sockopt_posix.go:144 +0x9c
+      src/net/sockopt_posix.go:144 +0x9c
   net.(*conn).SetDeadline()
-      src/pkg/net/net.go:161 +0xe3
+      src/net/net.go:161 +0xe3
   net.func·061()
-      src/pkg/net/timeout_test.go:616 +0x3ed
+      src/net/timeout_test.go:616 +0x3ed
 
 Goroutine 185 (running) created at:
   net.func·061()
-      src/pkg/net/timeout_test.go:609 +0x288
+      src/net/timeout_test.go:609 +0x288
 
 Goroutine 184 (running) created at:
   net.TestProlongTimeout()
-      src/pkg/net/timeout_test.go:618 +0x298
+      src/net/timeout_test.go:618 +0x298
   testing.tRunner()
-      src/pkg/testing/testing.go:301 +0xe8
+      src/testing/testing.go:301 +0xe8
 </pre>
 
 <h2 id="Options">Options</h2>
@@ -377,7 +377,8 @@ func (w *Watchdog) Start() {
 <h2 id="Supported_Systems">Supported Systems</h2>
 
 <p>
-The race detector runs on <code>darwin/amd64</code>, <code>linux/amd64</code>, and <code>windows/amd64</code>.
+The race detector runs on <code>darwin/amd64</code>, <code>freebsd/amd64</code>,
+<code>linux/amd64</code>, and <code>windows/amd64</code>.
 </p>
 
 <h2 id="Runtime_Overheads">Runtime Overhead</h2>
diff --git a/doc/asm.html b/doc/asm.html
index d44cb79..771c493 100644
--- a/doc/asm.html
+++ b/doc/asm.html
@@ -117,6 +117,9 @@ All user-defined symbols other than jump labels are written as offsets to these
 <p>
 The <code>SB</code> pseudo-register can be thought of as the origin of memory, so the symbol <code>foo(SB)</code>
 is the name <code>foo</code> as an address in memory.
+This form is used to name global functions and data.
+Adding <code><></code> to the name, as in <code>foo<>(SB)</code>, makes the name
+visible only in the current source file, like a top-level <code>static</code> declaration in a C file.
 </p>
 
 <p>
@@ -128,8 +131,11 @@ Thus <code>0(FP)</code> is the first argument to the function,
 When referring to a function argument this way, it is conventional to place the name
 at the beginning, as in <code>first_arg+0(FP)</code> and <code>second_arg+8(FP)</code>.
 Some of the assemblers enforce this convention, rejecting plain <code>0(FP)</code> and <code>8(FP)</code>.
-For assembly functions with Go prototypes, <code>go vet</code> will check that the argument names
+For assembly functions with Go prototypes, <code>go</code> <code>vet</code> will check that the argument names
 and offsets match.
+On 32-bit systems, the low and high 32 bits of a 64-bit value are distinguished by adding
+a <code>_lo</code> or <code>_hi</code> suffix to the name, as in <code>arg_lo+0(FP)</code> or <code>arg_hi+4(FP)</code>.
+If a Go prototype does not name its result, the expected assembly name is <code>ret</code>.
 </p>
 
 <p>
@@ -149,7 +155,7 @@ hardware's <code>SP</code> register.
 <p>
 Instructions, registers, and assembler directives are always in UPPER CASE to remind you
 that assembly programming is a fraught endeavor.
-(Exceptions: the <code>m</code> and <code>g</code> register renamings on ARM.)
+(Exception: the <code>g</code> register renaming on ARM.)
 </p>
 
 <p>
@@ -206,6 +212,8 @@ The frame size <code>$24-8</code> states that the function has a 24-byte frame
 and is called with 8 bytes of argument, which live on the caller's frame.
 If <code>NOSPLIT</code> is not specified for the <code>TEXT</code>,
 the argument size must be provided.
+For assembly functions with Go prototypes, <code>go</code> <code>vet</code> will check that the
+argument size is correct.
 </p>
 
 <p>
@@ -216,19 +224,20 @@ simple name <code>profileloop</code>.
 </p>
 
 <p>
-For <code>DATA</code> directives, the symbol is followed by a slash and the number
-of bytes the memory associated with the symbol occupies.
-The arguments are optional flags and the data itself.
-For instance,
-</p>
+Global data symbols are defined by a sequence of initializing
+<code>DATA</code> directives followed by a <code>GLOBL</code> directive.
+Each <code>DATA</code> directive initializes a section of the
+corresponding memory.
+The memory not explicitly initialized is zeroed.
+The general form of the <code>DATA</code> directive is
 
 <pre>
-DATA  runtime·isplan9(SB)/4, $1
+DATA	symbol+offset(SB)/width, value
 </pre>
 
 <p>
-declares the local symbol <code>runtime·isplan9</code> of size 4 and value 1.
-Again the symbol has the middle dot and is offset from <code>SB</code>.
+which initializes the symbol memory at the given offset and width with the given value.
+The <code>DATA</code> directives for a given symbol must be written with increasing offsets.
 </p>
 
 <p>
@@ -237,15 +246,26 @@ The arguments are optional flags and the size of the data being declared as a gl
 which will have initial value all zeros unless a <code>DATA</code> directive
 has initialized it.
 The <code>GLOBL</code> directive must follow any corresponding <code>DATA</code> directives.
-This example
+</p>
+
+<p>
+For example,
 </p>
 
 <pre>
-GLOBL runtime·tlsoffset(SB),$4
+DATA divtab<>+0x00(SB)/4, $0xf4f8fcff
+DATA divtab<>+0x04(SB)/4, $0xe6eaedf0
+...
+DATA divtab<>+0x3c(SB)/4, $0x81828384
+GLOBL divtab<>(SB), RODATA, $64
+
+GLOBL runtime·tlsoffset(SB), NOPTR, $4
 </pre>
 
 <p>
-declares <code>runtime·tlsoffset</code> to have size 4.
+declares and initializes <code>divtab<></code>, a read-only 64-byte table of 4-byte integer values,
+and declares <code>runtime·tlsoffset</code>, a 4-byte, implicitly zeroed variable that
+contains no pointers.
 </p>
 
 <p>
@@ -253,7 +273,7 @@ There may be one or two arguments to the directives.
 If there are two, the first is a bit mask of flags,
 which can be written as numeric expressions, added or or-ed together,
 or can be set symbolically for easier absorption by a human.
-Their values, defined in the file <code>src/cmd/ld/textflag.h</code>, are:
+Their values, defined in the standard <code>#include</code>  file <code>textflag.h</code>, are:
 </p>
 
 <ul>
@@ -299,6 +319,80 @@ This is a wrapper function and should not count as disabling <code>recover</code
 </li>
 </ul>
 
+<h3 id="runtime">Runtime Coordination</h3>
+
+<p>
+For garbage collection to run correctly, the runtime must know the
+location of pointers in all global data and in most stack frames.
+The Go compiler emits this information when compiling Go source files,
+but assembly programs must define it explicitly.
+</p>
+
+<p>
+A data symbol marked with the <code>NOPTR</code> flag (see above)
+is treated as containing no pointers to runtime-allocated data.
+A data symbol with the <code>RODATA</code> flag
+is allocated in read-only memory and is therefore treated
+as implicitly marked <code>NOPTR</code>.
+A data symbol with a total size smaller than a pointer
+is also treated as implicitly marked <code>NOPTR</code>.
+It is not possible to define a symbol containing pointers in an assembly source file;
+such a symbol must be defined in a Go source file instead.
+Assembly source can still refer to the symbol by name
+even without <code>DATA</code> and <code>GLOBL</code> directives.
+A good general rule of thumb is to define all non-<code>RODATA</code>
+symbols in Go instead of in assembly.
+</p>
+
+<p>
+Each function also needs annotations giving the location of
+live pointers in its arguments, results, and local stack frame.
+For an assembly function with no pointer results and
+either no local stack frame or no function calls,
+the only requirement is to define a Go prototype for the function
+in a Go source file in the same package.
+For more complex situations, explicit annotation is needed.
+These annotations use pseudo-instructions defined in the standard
+<code>#include</code> file <code>funcdata.h</code>.
+</p>
+
+<p>
+If a function has no arguments and no results,
+the pointer information can be omitted.
+This is indicated by an argument size annotation of <code>$<i>n</i>-0</code>
+on the <code>TEXT</code> instruction.
+Otherwise, pointer information must be provided by
+a Go prototype for the function in a Go source file,
+even for assembly functions not called directly from Go.
+(The prototype will also let <code>go</code> <code>vet</code> check the argument references.)
+At the start of the function, the arguments are assumed
+to be initialized but the results are assumed uninitialized.
+If the results will hold live pointers during a call instruction,
+the function should start by zeroing the results and then 
+executing the pseudo-instruction <code>GO_RESULTS_INITIALIZED</code>.
+This instruction records that the results are now initialized
+and should be scanned during stack movement and garbage collection.
+It is typically easier to arrange that assembly functions do not
+return pointers or do not contain call instructions;
+no assembly functions in the standard library use
+<code>GO_RESULTS_INITIALIZED</code>.
+</p>
+
+<p>
+If a function has no local stack frame,
+the pointer information can be omitted.
+This is indicated by a local frame size annotation of <code>$0-<i>n</i></code>
+on the <code>TEXT</code> instruction.
+The pointer information can also be omitted if the
+function contains no call instructions.
+Otherwise, the local stack frame must not contain pointers,
+and the assembly must confirm this fact by executing the 
+pseudo-instruction <code>NO_LOCAL_POINTERS</code>.
+Because stack resizing is implemented by moving the stack,
+the stack pointer may change during any function call:
+even pointers to stack data must not be kept in local variables.
+</p>
+
 <h2 id="architectures">Architecture-specific details</h2>
 
 <p>
@@ -344,7 +438,7 @@ Here follows some descriptions of key Go-specific details for the supported arch
 <h3 id="x86">32-bit Intel 386</h3>
 
 <p>
-The runtime pointers to the <code>m</code> and <code>g</code> structures are maintained
+The runtime pointer to the <code>g</code> structure is maintained
 through the value of an otherwise unused (as far as Go is concerned) register in the MMU.
 A OS-dependent macro <code>get_tls</code> is defined for the assembler if the source includes
 an architecture-dependent header file, like this:
@@ -356,14 +450,15 @@ an architecture-dependent header file, like this:
 
 <p>
 Within the runtime, the <code>get_tls</code> macro loads its argument register
-with a pointer to a pair of words representing the <code>g</code> and <code>m</code> pointers.
+with a pointer to the <code>g</code> pointer, and the <code>g</code> struct
+contains the <code>m</code> pointer.
 The sequence to load <code>g</code> and <code>m</code> using <code>CX</code> looks like this:
 </p>
 
 <pre>
 get_tls(CX)
-MOVL	g(CX), AX	// Move g into AX.
-MOVL	m(CX), BX	// Move m into BX.
+MOVL	g(CX), AX     // Move g into AX.
+MOVL	g_m(AX), BX   // Move g->m into BX.
 </pre>
 
 <h3 id="amd64">64-bit Intel 386 (a.k.a. amd64)</h3>
@@ -376,22 +471,21 @@ pointers is the same as on the 386, except it uses <code>MOVQ</code> rather than
 
 <pre>
 get_tls(CX)
-MOVQ	g(CX), AX	// Move g into AX.
-MOVQ	m(CX), BX	// Move m into BX.
+MOVQ	g(CX), AX     // Move g into AX.
+MOVQ	g_m(AX), BX   // Move g->m into BX.
 </pre>
 
 <h3 id="arm">ARM</h3>
 
 <p>
-The registers <code>R9</code>, <code>R10</code>, and <code>R11</code>
+The registers <code>R10</code> and <code>R11</code>
 are reserved by the compiler and linker.
 </p>
 
 <p>
-<code>R9</code> and <code>R10</code> point to the <code>m</code> (machine) and <code>g</code>
-(goroutine) structures, respectively.
-Within assembler source code, these pointers must be referred to as <code>m</code> and <code>g</code>;
-the names <code>R9</code> and <code>R10</code> are not recognized.
+<code>R10</code> points to the <code>g</code> (goroutine) structure.
+Within assembler source code, this pointer must be referred to as <code>g</code>;
+the name <code>R10</code> is not recognized.
 </p>
 
 <p>
@@ -434,13 +528,10 @@ Here's how the 386 runtime defines the 64-bit atomic load function.
 // so actually
 // void atomicload64(uint64 *res, uint64 volatile *addr);
 TEXT runtime·atomicload64(SB), NOSPLIT, $0-8
-	MOVL	4(SP), BX
-	MOVL	8(SP), AX
-	// MOVQ (%EAX), %MM0
-	BYTE $0x0f; BYTE $0x6f; BYTE $0x00
-	// MOVQ %MM0, 0(%EBX)
-	BYTE $0x0f; BYTE $0x7f; BYTE $0x03
-	// EMMS
-	BYTE $0x0F; BYTE $0x77
+	MOVL	ptr+0(FP), AX
+	LEAL	ret_lo+4(FP), BX
+	BYTE $0x0f; BYTE $0x6f; BYTE $0x00	// MOVQ (%EAX), %MM0
+	BYTE $0x0f; BYTE $0x7f; BYTE $0x03	// MOVQ %MM0, 0(%EBX)
+	BYTE $0x0F; BYTE $0x77			// EMMS
 	RET
 </pre>
diff --git a/doc/cmd.html b/doc/cmd.html
index 725666f..5d20d38 100644
--- a/doc/cmd.html
+++ b/doc/cmd.html
@@ -62,10 +62,10 @@ details.
 </tr>
 
 <tr>
-<td><a href="//godoc.org/code.google.com/p/go.tools/cmd/cover/">cover</a></td>
+<td><a href="//godoc.org/golang.org/x/tools/cmd/cover/">cover</a></td>
 <td>    </td>
 <td>Cover is a program for creating and analyzing the coverage profiles
-generated by <code>"go test -coverprofile"</code>.
+generated by <code>"go test -coverprofile"</code>.</td>
 </tr>
 
 <tr>
@@ -83,13 +83,13 @@ gofmt</a> command with more general options.</td>
 </tr>
 
 <tr>
-<td><a href="//godoc.org/code.google.com/p/go.tools/cmd/godoc/">godoc</a></td>
+<td><a href="//godoc.org/golang.org/x/tools/cmd/godoc/">godoc</a></td>
 <td>    </td>
 <td>Godoc extracts and generates documentation for Go packages.</td>
 </tr>
 
 <tr>
-<td><a href="//godoc.org/code.google.com/p/go.tools/cmd/vet/">vet</a></td>
+<td><a href="//godoc.org/golang.org/x/tools/cmd/vet/">vet</a></td>
 <td>    </td>
 <td>Vet examines Go source code and reports suspicious constructs, such as Printf
 calls whose arguments do not align with the format string.</td>
diff --git a/doc/code.html b/doc/code.html
index f019306..a4638f9 100644
--- a/doc/code.html
+++ b/doc/code.html
@@ -60,37 +60,35 @@ To give you an idea of how a workspace looks in practice, here's an example:
 
 <pre>
 bin/
-    streak                         # command executable
-    todo                           # command executable
+    hello                          # command executable
+    outyet                         # command executable
 pkg/
     linux_amd64/
-        code.google.com/p/goauth2/
-            oauth.a                # package object
-        github.com/nf/todo/
-            task.a                 # package object
+        github.com/golang/example/
+            stringutil.a           # package object
 src/
-    code.google.com/p/goauth2/
-        .hg/                       # mercurial repository metadata
-        oauth/
-            oauth.go               # package source
-            oauth_test.go          # test source
-    github.com/nf/
-        streak/
-            .git/                  # git repository metadata
-            oauth.go               # command source
-            streak.go              # command source
-        todo/
-            .git/                  # git repository metadata
-            task/
-                task.go            # package source
-            todo.go                # command source
+    <a href="https://github.com/golang/example/">github.com/golang/example/</a>
+        .git/                      # Git repository metadata
+	hello/
+	    hello.go               # command source
+	outyet/
+	    main.go                # command source
+	    main_test.go           # test source
+	stringutil/
+	    reverse.go             # package source
+	    reverse_test.go        # test source
 </pre>
 
 <p>
-This workspace contains three repositories (<code>goauth2</code>,
-<code>streak</code>, and <code>todo</code>) comprising two commands
-(<code>streak</code> and <code>todo</code>) and two libraries
-(<code>oauth</code> and <code>task</code>).
+This workspace contains one repository (<code>example</code>)
+comprising two commands (<code>hello</code> and <code>outyet</code>)
+and one library (<code>stringutil</code>).
+</p>
+
+<p>
+A typical workspace would contain many source repositories containing many
+packages and commands. Most Go programmers keep <i>all</i> their Go source code
+and dependencies in a single workspace.
 </p>
 
 <p>
@@ -277,29 +275,29 @@ Let's write a library and use it from the <code>hello</code> program.
 
 <p>
 Again, the first step is to choose a package path (we'll use
-<code>github.com/user/newmath</code>) and create the package directory:
+<code>github.com/user/stringutil</code>) and create the package directory:
 </p>
 
 <pre>
-$ <b>mkdir $GOPATH/src/github.com/user/newmath</b>
+$ <b>mkdir $GOPATH/src/github.com/user/stringutil</b>
 </pre>
 
 <p>
-Next, create a file named <code>sqrt.go</code> in that directory with the
+Next, create a file named <code>reverse.go</code> in that directory with the
 following contents.
 </p>
 
 <pre>
-// Package newmath is a trivial example package.
-package newmath
-
-// Sqrt returns an approximation to the square root of x.
-func Sqrt(x float64) float64 {
-	z := 1.0
-	for i := 0; i < 1000; i++ {
-		z -= (z*z - x) / (2 * z)
+// Package stringutil contains utility functions for working with strings.
+package stringutil
+
+// Reverse returns its argument string reversed rune-wise left to right.
+func Reverse(s string) string {
+	r := []rune(s)
+	for i, j := 0, len(r)-1; i < len(r)/2; i, j = i+1, j-1 {
+		r[i], r[j] = r[j], r[i]
 	}
-	return z
+	return string(r)
 }
 </pre>
 
@@ -308,7 +306,7 @@ Now, test that the package compiles with <code>go build</code>:
 </p>
 
 <pre>
-$ <b>go build github.com/user/newmath</b>
+$ <b>go build github.com/user/stringutil</b>
 </pre>
 
 <p>
@@ -326,7 +324,7 @@ directory of the workspace.
 </p>
 
 <p>
-After confirming that the <code>newmath</code> package builds,
+After confirming that the <code>stringutil</code> package builds,
 modify your original <code>hello.go</code> (which is in
 <code>$GOPATH/src/github.com/user/hello</code>) to use it:
 </p>
@@ -337,18 +335,18 @@ package main
 import (
 	"fmt"
 
-	<b>"github.com/user/newmath"</b>
+	<b>"github.com/user/stringutil"</b>
 )
 
 func main() {
-	fmt.Printf("Hello, world.  <b>Sqrt(2) = %v\n", newmath.Sqrt(2)</b>)
+	fmt.Printf(stringutil.Reverse("!oG ,olleH"))
 }
 </pre>
 
 <p>
 Whenever the <code>go</code> tool installs a package or binary, it also
-installs whatever dependencies it has. So when you install the <code>hello</code>
-program
+installs whatever dependencies it has.
+So when you install the <code>hello</code> program
 </p>
 
 <pre>
@@ -356,16 +354,16 @@ $ <b>go install github.com/user/hello</b>
 </pre>
 
 <p>
-the <code>newmath</code> package will be installed as well, automatically.
+the <code>stringutil</code> package will be installed as well, automatically.
 </p>
 
 <p>
-Running the new version of the program, you should see some numerical output:
+Running the new version of the program, you should see a new, reversed message:
 </p>
 
 <pre>
 $ <b>hello</b>
-Hello, world.  Sqrt(2) = 1.414213562373095
+Hello, Go!
 </pre>
 
 <p>
@@ -374,22 +372,22 @@ After the steps above, your workspace should look like this:
 
 <pre>
 bin/
-    hello              # command executable
+    hello                 # command executable
 pkg/
-    linux_amd64/       # this will reflect your OS and architecture
+    linux_amd64/          # this will reflect your OS and architecture
         github.com/user/
-            newmath.a  # package object
+            stringutil.a  # package object
 src/
     github.com/user/
         hello/
-            hello.go   # command source
-        newmath/
-            sqrt.go    # package source
+            hello.go      # command source
+        stringutil/
+            reverse.go    # package source
 </pre>
 
 <p>
-Note that <code>go install</code> placed the <code>newmath.a</code> object in a
-directory inside <code>pkg/linux_amd64</code> that mirrors its source
+Note that <code>go install</code> placed the <code>stringutil.a</code> object
+in a directory inside <code>pkg/linux_amd64</code> that mirrors its source
 directory.
 This is so that future invocations of the <code>go</code> tool can find the
 package object and avoid recompiling the package unnecessarily.
@@ -457,20 +455,29 @@ if the function calls a failure function such as <code>t.Error</code> or
 </p>
 
 <p>
-Add a test to the <code>newmath</code> package by creating the file
-<code>$GOPATH/src/github.com/user/newmath/sqrt_test.go</code> containing the
-following Go code.
+Add a test to the <code>stringutil</code> package by creating the file
+<code>$GOPATH/src/github.com/user/stringutil/reverse_test.go</code> containing
+the following Go code.
 </p>
 
 <pre>
-package newmath
+package stringutil
 
 import "testing"
 
-func TestSqrt(t *testing.T) {
-	const in, out = 4, 2
-	if x := Sqrt(in); x != out {
-		t.Errorf("Sqrt(%v) = %v, want %v", in, x, out)
+func TestReverse(t *testing.T) {
+	cases := []struct {
+		in, want string
+	}{
+		{"Hello, world", "dlrow ,olleH"},
+		{"Hello, 世界", "界世 ,olleH"},
+		{"", ""},
+	}
+	for _, c := range cases {
+		got := Reverse(c.in)
+		if got != c.want {
+			t.Errorf("Reverse(%q) == %q, want %q", c.in, got, c.want)
+		}
 	}
 }
 </pre>
@@ -480,8 +487,8 @@ Then run the test with <code>go test</code>:
 </p>
 
 <pre>
-$ <b>go test github.com/user/newmath</b>
-ok  	github.com/user/newmath 0.165s
+$ <b>go test github.com/user/stringutil</b>
+ok  	github.com/user/stringutil 0.165s
 </pre>
 
 <p>
@@ -491,7 +498,7 @@ directory, you can omit the package path:
 
 <pre>
 $ <b>go test</b>
-ok  	github.com/user/newmath 0.165s
+ok  	github.com/user/stringutil 0.165s
 </pre>
 
 <p>
@@ -507,16 +514,16 @@ An import path can describe how to obtain the package source code using a
 revision control system such as Git or Mercurial. The <code>go</code> tool uses
 this property to automatically fetch packages from remote repositories.
 For instance, the examples described in this document are also kept in a
-Mercurial repository hosted at Google Code,
-<code><a href="//code.google.com/p/go.example">code.google.com/p/go.example</a></code>.
+Git repository hosted at GitHub
+<code><a href="https://github.com/golang/example">github.com/golang/example</a></code>.
 If you include the repository URL in the package's import path,
 <code>go get</code> will fetch, build, and install it automatically:
 </p>
 
 <pre>
-$ <b>go get code.google.com/p/go.example/hello</b>
+$ <b>go get github.com/golang/example/hello</b>
 $ <b>$GOPATH/bin/hello</b>
-Hello, world.  Sqrt(2) = 1.414213562373095
+Hello, Go examples!
 </pre>
 
 <p>
@@ -533,43 +540,45 @@ tree should now look like this:
 
 <pre>
 bin/
-    hello                 # command executable
+    hello                           # command executable
 pkg/
     linux_amd64/
-        code.google.com/p/go.example/
-            newmath.a     # package object
+        github.com/golang/example/
+            stringutil.a            # package object
         github.com/user/
-            newmath.a     # package object
+            stringutil.a            # package object
 src/
-    code.google.com/p/go.example/
+    github.com/golang/example/
+	.git/                       # Git repository metadata
         hello/
-            hello.go      # command source
-        newmath/
-            sqrt.go       # package source
-            sqrt_test.go  # test source
+            hello.go                # command source
+        stringutil/
+            reverse.go              # package source
+            reverse_test.go         # test source
     github.com/user/
         hello/
-            hello.go      # command source
-        newmath/
-            sqrt.go       # package source
-            sqrt_test.go  # test source
+            hello.go                # command source
+        stringutil/
+            reverse.go              # package source
+            reverse_test.go         # test source
 </pre>
 
 <p>
-The <code>hello</code> command hosted at Google Code depends on the
-<code>newmath</code> package within the same repository. The imports in
-<code>hello.go</code> file use the same import path convention, so the <code>go
-get</code> command is able to locate and install the dependent package, too.
+The <code>hello</code> command hosted at GitHub depends on the
+<code>stringutil</code> package within the same repository. The imports in
+<code>hello.go</code> file use the same import path convention, so the
+<code>go get</code> command is able to locate and install the dependent
+package, too.
 </p>
 
 <pre>
-import "code.google.com/p/go.example/newmath"
+import "github.com/golang/example/stringutil"
 </pre>
 
 <p>
 This convention is the easiest way to make your Go packages available for
 others to use.
-The <a href="//code.google.com/p/go-wiki/wiki/Projects">Go Wiki</a>
+The <a href="//golang.org/wiki/Projects">Go Wiki</a>
 and <a href="//godoc.org/">godoc.org</a>
 provide lists of external Go projects.
 </p>
@@ -618,5 +627,5 @@ The official mailing list for discussion of the Go language is
 
 <p>
 Report bugs using the
-<a href="//code.google.com/p/go/issues/list">Go issue tracker</a>.
+<a href="//golang.org/issue">Go issue tracker</a>.
 </p>
diff --git a/doc/contrib.html b/doc/contrib.html
index a615fc6..93a609f 100644
--- a/doc/contrib.html
+++ b/doc/contrib.html
@@ -30,21 +30,16 @@ We encourage all Go users to subscribe to
 <h2 id="go1">Version history</h2>
 
 <h3 id="release"><a href="/doc/devel/release.html">Release History</a></h3>
-<p>A summary of the changes between Go releases.</p>
 
-<h4 id="go1notes"><a href="/doc/go1">Go 1 Release Notes</a></h4>
-<p>
-A guide for updating your code to work with Go 1.
-</p>
+<p>A <a href="/doc/devel/release.html">summary</a> of the changes between Go releases. Notes for the major releases:</p>
 
-<h4 id="release notes"><a href="/doc/go1.1">Go 1.1 Release Notes</a></h4>
-<p>
-A list of significant changes in Go 1.1, with instructions for updating
-your code where necessary.
-Each point release includes a similar document appropriate for that
-release: <a href="/doc/go1.2">Go 1.2</a>, <a href="/doc/go1.3">Go 1.3</a>,
-and so on.
-</p>
+<ul>
+	<li><a href="/doc/go1.4">Go 1.4</a> <small>(December 2014)</small></li>
+	<li><a href="/doc/go1.3">Go 1.3</a> <small>(June 2014)</small></li>
+	<li><a href="/doc/go1.2">Go 1.2</a> <small>(December 2013)</small></li>
+	<li><a href="/doc/go1.1">Go 1.1</a> <small>(May 2013)</small></li>
+	<li><a href="/doc/go1">Go 1</a> <small>(March 2012)</small></li>
+</ul>
 
 <h3 id="go1compat"><a href="/doc/go1compat">Go 1 and the Future of Go Programs</a></h3>
 <p>
@@ -55,7 +50,7 @@ Go 1 matures.
 
 <h2 id="resources">Developer Resources</h2>
 
-<h3 id="source"><a href="https://code.google.com/p/go/source">Source Code</a></h3>
+<h3 id="source"><a href="https://golang.org/change">Source Code</a></h3>
 <p>Check out the Go source code.</p>
 
 <h3 id="golang-dev"><a href="https://groups.google.com/group/golang-dev">Developer</a> and
@@ -81,13 +76,13 @@ systems and architectures.</p>
 
 <h2 id="howto">How you can help</h2>
 
-<h3><a href="https://code.google.com/p/go/issues">Reporting issues</a></h3>
+<h3><a href="//golang.org/issue">Reporting issues</a></h3>
 
 <p>
 If you spot bugs, mistakes, or inconsistencies in the Go project's code or
 documentation, please let us know by
-<a href="https://code.google.com/p/go/issues/entry">filing a ticket</a>
-on our <a href="https://code.google.com/p/go/issues">issue tracker</a>.
+<a href="//golang.org/issue/new">filing a ticket</a>
+on our <a href="//golang.org/issue">issue tracker</a>.
 (Of course, you should check it's not an existing issue before creating
 a new one.)
 </p>
@@ -106,8 +101,8 @@ To get started, read these <a href="/doc/contribute.html">contribution
 guidelines</a> for information on design, testing, and our code review process.
 </p>
 <p>
-Check <a href="https://code.google.com/p/go/issues">the tracker</a> for 
+Check <a href="//golang.org/issue">the tracker</a> for 
 open issues that interest you. Those labeled
-<a href="https://code.google.com/p/go/issues/list?q=status=HelpWanted">HelpWanted</a>
+<a href="https://github.com/golang/go/issues?q=is%3Aopen+is%3Aissue+label%3Ahelpwanted">helpwanted</a>
 are particularly in need of outside help.
 </p>
diff --git a/doc/contribute.html b/doc/contribute.html
index 3927349..ba550d5 100644
--- a/doc/contribute.html
+++ b/doc/contribute.html
@@ -6,9 +6,21 @@
 
 <p>
 This document explains how to contribute changes to the Go project.
-It assumes you have installed Go using the
+It assumes you have installed Go from source:
+<p>
+
+<pre>
+$ git clone https://go.googlesource.com/go
+$ cd go/src
+$ ./all.bash
+</pre>
+<!--
+TODO(adg): delete the above, restore the below after we have updated install-source.html
 <a href="/doc/install/source">installation instructions</a> and
 have <a href="code.html">written and tested your code</a>.
+-->
+
+<p>
 (Note that the <code>gccgo</code> frontend lives elsewhere;
 see <a href="gccgo_contribute.html">Contributing to gccgo</a>.)
 </p>
@@ -54,7 +66,8 @@ $ ./all.bash
 </p>
 
 <p>
-After running for a while, the command should print "<code>ALL TESTS PASSED</code>".
+After running for a while, the command should print
+"<code>ALL</code> <code>TESTS</code> <code>PASSED</code>".
 </p>
 
 <h2 id="Code_review">Code review</h2>
@@ -64,208 +77,229 @@ Changes to Go must be reviewed before they are submitted,
 no matter who makes the change.
 (In exceptional cases, such as fixing a build, the review can
 follow shortly after submitting.)
-A Mercurial extension helps manage the code review process.
-The extension is included in the Go source tree but needs
-to be added to your Mercurial configuration.
+A custom git command called <code>git-review</code>,
+discussed below, helps manage the code review process through a Google-hosted
+<a href="https://go-review.googlesource.com/">instance</a> of the code review
+system called <a href="https://code.google.com/p/gerrit/">Gerrit</a>.
 </p>
 
-<h3>Caveat for Mercurial aficionados</h3>
+<h3>Set up authentication for code review</h3>
 
 <p>
-<i>Using Mercurial with the code review extension is not the same
-as using standard Mercurial.</i>
+The Git code hosting server and Gerrit code review server both use a Google
+Account to authenticate. You therefore need a Google Account to proceed.
+(If you can use the account to
+<a href="https://www.google.com/accounts/Login">sign in at google.com</a>,
+you can use it to sign in to the code review server.)
+The email address you use with the code review system
+will be recorded in the <a href="https://go.googlesource.com/go">change log</a>
+and in the <a href="/CONTRIBUTORS"><code>CONTRIBUTORS</code></a> file.
+You can <a href="https://www.google.com/accounts/NewAccount">create a Google Account</a>
+associated with any address where you receive email.
+</p>
+
+<p>
+Visit the site <a href="https://go.googlesource.com">go.googlesource.com</a>
+and log in using your Google Account.
+Click on the "Generate Password" link that appears at the top of the page.
 </p>
 
 <p>
-The Go repository is maintained as a single line of reviewed changes;
-we prefer to avoid the complexity of Mercurial's arbitrary change graph.
-The code review extension helps here: its <code>hg submit</code> command
-automatically checks for and warns about the local repository
-being out of date compared to the remote one.
-The <code>hg submit</code> command also verifies other
-properties about the Go repository.
-For example,
-it checks that Go code being checked in is formatted in the standard style,
-as defined by <a href="/cmd/gofmt">gofmt</a>,
-and it checks that the author of the code is properly recorded for
-<a href="#copyright">copyright purposes</a>.
+Click the radio button that says "Only <code>go.googlesource.com</code>"
+to use this authentication token only for the Go project.
 </p>
 
 <p>
-To help ensure changes are only created by <code>hg submit</code>,
-the code review extension disables the standard <code>hg commit</code>
-command.
+Further down the page is a box containing commands to install
+the authentication cookie in file called <code>.gitcookies</code> in your home
+directory.
+Copy the text for the commands into a Unix shell window to execute it.
+That will install the authentication token.
 </p>
 
-<h3>Configure the extension</h3>
+<p>
+(If you are on a Windows computer, you should instead follow the instructions
+in the yellow box to run the command.)
+</p>
 
-<p>Edit <code>.hg/hgrc</code> in the root of your Go checkout to add:</p>
+<h3>Register with Gerrit</h3>
 
-<pre>
-[extensions]
-codereview = /path/to/go/lib/codereview/codereview.py
+<p>
+Now that you have a Google account and the authentication token,
+you need to register your account with Gerrit, the code review system.
+To do this, visit <a href="https://golang.org/cl">golang.org/cl</a>
+and log in using the same Google Account you used above.
+That is all that is required.
+</p>
 
-[ui]
-username = Your Name <you at server.dom>
+<h3>Install the git-review command</h3>
+
+<p>
+Now install the <code>git-review</code> command by running,
+</p>
+
+<pre>
+go get -u golang.org/x/review/git-review
 </pre>
 
 <p>
-The <code>username</code> information will not be used unless
-you are a committer (see below), but Mercurial complains if it is missing.
+Make sure <code>git-review</code> is installed in your shell path, so that the
+<code>git</code> command can find it. Check that
 </p>
 
+<pre>
+$ git review help
+</pre>
+ 
 <p>
-As the codereview extension is only enabled for your Go checkout, the remainder of this document assumes you
-are inside the go directory when issuing commands.
+prints help text, not an error.
 </p>
 
-<p>To contribute to subrepositories, edit the <code>.hg/hgrc</code> for each
-subrepository in the same way. For example, add the codereview extension to
-<code>code.google.com/p/go.tools/.hg/hgrc</code>.
+<p>
+Note to Git aficionados: The <code>git-review</code> command is not required to
+upload and manage Gerrit code reviews. For those who prefer plain Git, the text
+below gives the Git equivalent of each git-review command. If you do use plain
+Git, note that you still need the commit hooks that the git-review command
+configures; those hooks add a Gerrit <code>Change-Id</code> line to the commit
+message and check that all Go source files have been formatted with gofmt. Even
+if you intend to use plain Git for daily work, install the hooks in a new Git
+checkout by running <code>git-review</code> <code>hooks</code>).
 </p>
 
-<h3>Understanding the extension</h3>
+<h3>Set up git aliases</h3>
 
-<p>After adding the code review extension, you can run</p>
+<p>
+The <code>git-review</code> command can be run directly from the shell
+by typing, for instance,
+</p>
 
 <pre>
-$ hg help codereview
+$ git review sync
 </pre>
 
-<p>to learn more about its commands. To learn about a specific code-review-specific
-command such as <code>change</code>, run</p>
+<p>
+but it is more convenient to set up aliases for <code>git-review</code>'s own
+subcommands, so that the above becomes,
+</p>
 
 <pre>
-$ hg help change
+$ git sync
 </pre>
 
-<p>
-Windows users may need to perform extra steps to get the code review
-extension working. See the
-<a href="https://code.google.com/p/go-wiki/wiki/CodeReview">CodeReview page</a>
-on the <a href="https://code.google.com/p/go-wiki/wiki">Go Wiki</a> for details.
 </p>
-
-<h3>Log in to the code review site.</h3>
+The <code>git-review</code> subcommands have been chosen to be distinct from
+Git's own, so it's safe to do so.
+</p>
 
 <p>
-The code review server uses a Google Account to authenticate.
-(If you can use the account to
-<a href="https://www.google.com/accounts/Login?hl=en&continue=http://www.google.com/">sign in at google.com</a>,
-you can use it to sign in to the code review server.)
-The email address you use on the Code Review site
-will be recorded in the <a href="https://code.google.com/p/go/source/list">Mercurial change log</a>
-and in the <a href="/CONTRIBUTORS"><code>CONTRIBUTORS</code></a> file.
-You can <a href="https://www.google.com/accounts/NewAccount">create a Google Account</a>
-associated with any address where you receive email.
-If you've enabled the two-step verification feature, don't forget to generate an
-application-specific password and use that when prompted for a password.
+The aliases are optional, but in the rest of this document we will assume
+they are installed.
+To install them, copy this text into your Git configuration file
+(usually <code>.gitconfig</code> in your home directory):
 </p>
 
 <pre>
-$ hg code-login
-Email (login for uploading to codereview.appspot.com): rsc at golang.org
-Password for rsc at golang.org:
-
-Saving authentication cookies to /Users/rsc/.codereview_upload_cookies_codereview.appspot.com
+[alias]
+	change = review change
+	gofmt = review gofmt
+	mail = review mail
+	pending = review pending
+	sync = review sync
 </pre>
 
-<h3>Configure your account settings.</h3>
+<h3>Understanding the git-review command</h3>
 
-<p>Edit your <a href="https://codereview.appspot.com/settings">code review settings</a>.
-Grab a nickname.
-Many people prefer to set the Context option to
-“Whole file” to see more context when reviewing changes.
-</p>
+<p>After installing the <code>git-review</code> command, you can run</p>
+
+<pre>
+$ git review help
+</pre>
 
-<p>Once you have chosen a nickname in the settings page, others
-can use that nickname as a shorthand for naming reviewers and the CC list.
-For example, <code>rsc</code> is an alias for <code>rsc at golang.org</code>.
+<p>
+to learn more about its commands.
+You can also read the <a href="https://godoc.org/golang.org/x/review/git-review">command documentation</a>.
 </p>
 
-<h3>Switch to the default branch</h3>
+<h3>Switch to the master branch</h3>
 
 <p>
 Most Go installations use a release branch, but new changes should
-only be made to the default branch. (They may be applied later to a release
-branch as part of the release process.)
-Before making a change, make sure you use the default branch:
+only be made based on the master branch.
+(They may be applied later to a release branch as part of the release process,
+but most contributors won't do this themselves.)
+Before making a change, make sure you start on the master branch:
 </p>
 
 <pre>
-$ hg update default
+$ git checkout master
+$ git sync
 </pre>
 
+<p>
+(In Git terms, <code>git</code> <code>sync</code> runs
+<code>git</code> <code>pull</code> <code>-r</code>.)
+</p>
+
 <h3>Make a change</h3>
 
 <p>
 The entire checked-out tree is writable.
-If you need to edit files, just edit them: Mercurial will figure out which ones changed.
-You do need to inform Mercurial of added, removed, copied, or renamed files,
-by running
-<code>hg add</code>,
-<code>hg rm</code>,
-<code>hg cp</code>,
-or
-<code>hg mv</code>.
+Once you have edited files, you must tell Git that they have been modified.
+You must also tell Git about any files that are added, removed, or renamed files.
+These operations are done with the usual Git commands,
+<code>git</code> <code>add</code>,
+<code>git</code> <code>rm</code>,
+and
+<code>git</code> <code>mv</code>.
 </p>
 
-<p>When you are ready to send a change out for review, run</p>
+<p>
+If you wish to checkpoint your work, or are ready to send the code out for review, run</p>
 
 <pre>
-$ hg change
+$ git change <i><branch></i>
 </pre>
 
-<p>from any directory in your Go repository.
-Mercurial will open a change description file in your editor.
-(It uses the editor named by the <code>$EDITOR</code> environment variable, <code>vi</code> by default.)
-The file will look like:
+<p>
+from any directory in your Go repository to commit the changes so far.
+The name <i><branch></i> is an arbitrary one you choose to identify the
+local branch containing your changes.
 </p>
 
-<pre>
-# Change list.
-# Lines beginning with # are ignored.
-# Multi-line values should be indented.
+<p>
+(In Git terms, <code>git</code> <code>change</code> <code><branch></code>
+runs <code>git</code> <code>checkout</code> <code>-b</code> <code>branch</code>,
+then <code>git</code> <code>branch</code> <code>--set-upstream-to</code> <code>origin/master</code>,
+then <code>git</code> <code>commit</code>.)
+</p>
 
-Reviewer:
-CC:
+<p>
+Git will open a change description file in your editor.
+(It uses the editor named by the <code>$EDITOR</code> environment variable,
+<code>vi</code> by default.)
+The file will look like:
+</p>
 
-Description:
-	<enter description here>
+<pre>
 
-Files:
-	src/pkg/math/sin.go
-	src/pkg/math/tan.go
-	src/pkg/regexp/regexp.go
+# Please enter the commit message for your changes. Lines starting
+# with '#' will be ignored, and an empty message aborts the commit.
+# On branch foo
+# Changes not staged for commit:
+#	modified:   editedfile.go
+#
 </pre>
 
 <p>
-The <code>Reviewer</code> line lists the reviewers assigned
-to this change, and the <code>CC</code> line lists people to
-notify about the change.
-These can be code review nicknames or arbitrary email addresses.
-Unless explicitly told otherwise, such as in the discussion leading
-up to sending in the change list, leave the reviewer field blank.
-This means that the
-<a href="https://groups.google.com/group/golang-codereviews">golang-codereviews at googlegroups.com</a>
-mailing list will be used as the reviewer.
-</p>
-
-<p>
-Replace “<code><enter description here></code>”
-with a description of your change.
+At the beginning of this file is a blank line; replace it
+with a thorough description of your change.
 The first line of the change description is conventionally a one-line
 summary of the change, prefixed by the primary affected package,
-and is used as the subject for code review mail; the rest of the
-description elaborates.
-</p>
-
-<p>
-The <code>Files</code> section lists all the modified files
-in your client.
-It is best to keep unrelated changes in different change lists.
-In this example, we can include just the changes to package <code>math</code>
-by deleting the line mentioning <code>regexp.go</code>.
+and is used as the subject for code review mail.
+The rest of the
+description elaborates and should provide context for the
+change and explain what it does.
+If there is a helpful reference, mention it here.
 </p>
 
 <p>
@@ -273,343 +307,314 @@ After editing, the template might now read:
 </p>
 
 <pre>
-# Change list.
-# Lines beginning with # are ignored.
-# Multi-line values should be indented.
+math: improved Sin, Cos and Tan precision for very large arguments
 
-Reviewer: golang-codereviews at googlegroups.com
-CC: math-nuts at swtch.com
+The existing implementation has poor numerical properties for
+large arguments, so use the McGillicutty algorithm to improve
+accuracy above 1e10.
 
-Description:
-	math: improved Sin, Cos and Tan precision for very large arguments.
+The algorithm is described at http://wikipedia.org/wiki/McGillicutty_Algorithm
 
-	See Bimmler and Shaney, ``Extreme sinusoids,'' J. Math 3(14).
-	Fixes issue 159.
+Fixes #159
 
-Files:
-	src/pkg/math/sin.go
-	src/pkg/math/tan.go
+# Please enter the commit message for your changes. Lines starting
+# with '#' will be ignored, and an empty message aborts the commit.
+# On branch foo
+# Changes not staged for commit:
+#	modified:   editedfile.go
+#
 </pre>
 
 <p>
-The special sentence “Fixes issue 159.” associates
-the change with issue 159 in the <a href="https://code.google.com/p/go/issues/list">Go issue tracker</a>.
+The commented section of the file lists all the modified files in your client.
+It is best to keep unrelated changes in different change lists,
+so if you see a file listed that should not be included, abort
+the command and move that file to a different branch.
+</p>
+
+<p>
+The special notation "Fixes #159" associates the change with issue 159 in the
+<a href="https://golang.org/issue/159">Go issue tracker</a>.
 When this change is eventually submitted, the issue
 tracker will automatically mark the issue as fixed.
-(These conventions are described in detail by the
-<a href="https://code.google.com/p/support/wiki/IssueTracker#Integration_with_version_control">Google Project Hosting Issue Tracker documentation</a>.)
+(There are several such conventions, described in detail in the
+<a href="https://help.github.com/articles/closing-issues-via-commit-messages/">GitHub Issue Tracker documentation</a>.)
 </p>
 
 <p>
-Save the file and exit the editor.</p>
+Once you have finished writing the commit message,
+save the file and exit the editor.
+</p>
 
 <p>
-The code review server assigns your change an issue number and URL,
-which <code>hg change</code> will print, something like:
+If you wish to do more editing, re-stage your changes using
+<code>git</code> <code>add</code>, and then run
 </p>
 
 <pre>
-CL created: https://codereview.appspot.com/99999
+$ git change
 </pre>
 
-<h3>Adding or removing files from an existing change</h3>
-
 <p>
-If you need to re-edit the change description, or change the files included in the CL,
-run <code>hg change 99999</code>.
+to update the change description and incorporate the staged changes.  The
+change description contains a <code>Change-Id</code> line near the bottom,
+added by a Git commit hook during the initial
+<code>git</code> <code>change</code>.
+That line is used by Gerrit to match successive uploads of the same change.
+Do not edit or delete it.
 </p>
 
 <p>
-Alternatively, you can use
+(In Git terms, <code>git</code> <code>change</code> with no branch name
+runs <code>git</code> <code>commit</code> <code>--amend</code>.)
+</p> 
+
+<h3>Mail the change for review</h3>
+
+<p>
+Once the change is ready, mail it out for review:
 </p>
 
 <pre>
-$ hg file 99999 somefile
+$ git mail
 </pre>
 
 <p>
-to add <code>somefile</code> to CL 99999, and
+You can specify a reviewer or CC interested parties
+using the <code>-r</code> or <code>-cc</code> options.
+Both accept a comma-separated list of email addresses:
 </p>
 
 <pre>
-$ hg file -d 99999 somefile
+$ git mail -r joe at golang.org -cc mabel at example.com,math-nuts at swtch.com
 </pre>
 
 <p>
-to remove <code>somefile</code> from the CL.
+Unless explicitly told otherwise, such as in the discussion leading
+up to sending in the change list, it's better not to specify a reviewer.
+All changes are automatically CC'ed to the
+<a href="https://groups.google.com/group/golang-codereviews">golang-codereviews at googlegroups.com</a>
+mailing list.
 </p>
 
 <p>
-A file may only belong to a single active CL at a time. <code>hg file</code>
-will issue a warning if a file is moved between changes.
+(In Git terms, <code>git</code> <code>mail</code> pushes the local committed
+changes to Gerrit using <code>git</code> <code>push</code> <code>origin</code>
+<code>HEAD:refs/for/master</code>.)
 </p>
 
-<h3>Synchronize your client</h3>
-
-<p>While you were working, others might have submitted changes
-to the repository.  To update your client, run</p>
-
-<pre>
-$ hg sync
-</pre>
-
-<p>(For Mercurial fans, <code>hg sync</code> runs <code>hg pull -u</code>
-but then also synchronizes the local change list state against the new data.)</p>
-
 <p>
-If files you were editing have changed, Mercurial does its best to merge the
-remote changes into your local changes.  It may leave some files to merge by hand.
+If your change relates to an open issue, please add a comment to the issue
+announcing your proposed fix, including a link to your CL.
 </p>
 
 <p>
-For example, suppose you have edited <code>flag_test.go</code> but
-someone else has committed an independent change.
-When you run <code>hg sync</code>, you will get the (scary-looking) output
-(emphasis added):
+The code review server assigns your change an issue number and URL,
+which <code>git</code> <code>mail</code> will print, something like:
+</p>
 
 <pre>
-$ hg sync
-adding changesets
-adding manifests
-adding file changes
-added 1 changeset with 2 changes to 2 files
-getting src/pkg/flag/flag.go
-couldn't find merge tool hgmerge
-merging src/pkg/flag/flag_test.go
-warning: conflicts during merge.
-<i>merging src/pkg/flag/flag_test.go failed!</i>
-1 file updated, 0 files merged, 0 files removed, 1 file unresolved
-use 'hg resolve' to retry unresolved file merges
-$
+remote: New Changes:
+remote:   https://go-review.googlesource.com/99999 math: improved Sin, Cos and Tan precision for very large arguments
 </pre>
 
+<h3>Reviewing code</h3>
+
 <p>
-The only important part in that transcript is the italicized line:
-Mercurial failed to merge your changes with the independent change.
-When this happens, Mercurial leaves both edits in the file,
-marked by <code><<<<<<<</code> and
-<code>>>>>>>></code>.
-it is now your job to edit the file to combine them.
-Continuing the example, searching for those strings in <code>flag_test.go</code>
-might turn up:
+Running <code>git</code> <code>mail</code> will send an email to you and the
+reviewers asking them to visit the issue's URL and make comments on the change.
+When done, the reviewer adds comments through the Gerrit user interface
+and clicks "Reply" to send comments back.
+You will receive a mail notification when this happens.
+You must reply through the web interface.
+(Unlike with the old Rietveld review system, replying by mail has no effect.)
 </p>
 
-<pre>
-	VisitAll(visitor);
-<<<<<<< local
-	if len(m) != 7 {
-=======
-	if len(m) != 8 {
->>>>>>> other
-		t.Error("VisitAll misses some flags");
-</pre>
+<h3>Revise and upload</h3>
 
 <p>
-Mercurial doesn't show it, but suppose the original text that both edits
-started with was 6; you added 1 and the other change added 2,
-so the correct answer might now be 9.  First, edit the section
-to remove the markers and leave the correct code:
+You must respond to review comments through the web interface.
+(Unlike with the old Rietveld review system, responding by mail has no effect.)
 </p>
 
-<pre>
-	VisitAll(visitor);
-	if len(m) != 9 {
-		t.Error("VisitAll misses some flags");
-</pre>
-
 <p>
-Then ask Mercurial to mark the conflict as resolved:
+When you have revised the code and are ready for another round of review,
+stage those changes and use <code>git</code> <code>change</code> to update the
+commit.
+To send the update change list for another round of review,
+run <code>git</code> <code>mail</code> again.
 </p>
 
-<pre>
-$ hg resolve -m flag_test.go
-</pre>
-
 <p>
-If you had been editing the file, say for debugging, but do not
-care to preserve your changes, you can run
-<code>hg revert flag_test.go</code> to abandon your
-changes, but you may still need to run
-<code>hg resolve -m</code> to mark the conflict resolved.
+The reviewer can comment on the new copy, and the process repeats.
+The reviewer approves the change by giving it a positive score
+(+1 or +2) and replying <code>LGTM</code>: looks good to me.
 </p>
 
-<h3>Mail the change for review</h3>
-
 <p>
-Creating or uploading the change uploads a copy of the diff to the code review server,
-but it does not notify anyone about it. To do that, you need to run <code>hg mail</code>
-(see below).
+You can see a list of your pending changes by running <code>git</code>
+<code>pending</code>, and switch between change branches with <code>git</code>
+<code>change</code> <code><i><branch></i></code>.
 </p>
 
-<p>To send out a change for review, run <code>hg mail</code> using the change list number
-assigned during <code>hg change</code>:</p>
-
-<pre>
-$ hg mail 99999
-</pre>
+<h3>Synchronize your client</h3>
 
-<p>You can add to the <code>Reviewer:</code> and <code>CC:</code> lines
-using the <code>-r</code> or <code>--cc</code> options.
-In the above example, we could have left the <code>Reviewer</code> and <code>CC</code>
-lines blank and then run:
+<p>
+While you were working, others might have submitted changes to the repository.
+To update your local branch, run
 </p>
 
 <pre>
-$ hg mail -r golang-codereviews at googlegroups.com --cc math-nuts at swtch.com 99999
+$ git sync
 </pre>
 
-<p>to achieve the same effect.</p>
-
-<p>Note that <code>-r</code> and <code>--cc</code> cannot be spelled <code>--r</code> or <code>-cc</code>.</p>
-
 <p>
-If your change relates to an open issue, please add a comment to the issue
-announcing your proposed fix, including a link to your CL.
+(In git terms, git sync runs
+<code>git</code> <code>pull</code> <code>-r</code>.)
 </p>
 
-<h3>Reviewing code</h3>
-
 <p>
-Running <code>hg mail</code> will send an email to you and the reviewers
-asking them to visit the issue's URL and make comments on the change.
-When done, the reviewer clicks “Publish and Mail comments”
-to send comments back.
+If files you were editing have changed, Git does its best to merge the
+remote changes into your local changes.
+It may leave some files to merge by hand.
 </p>
 
-
-<h3>Revise and upload</h3>
-
 <p>
-When you have revised the code and are ready for another round of review,
-you can upload your change and send mail asking the reviewers to
-please take another look (<code>PTAL</code>). Use the change list number
-assigned during <code>hg change</code>
-</p>
+For example, suppose you have edited <code>sin.go</code> but
+someone else has committed an independent change.
+When you run <code>git</code> <code>sync</code>,
+you will get the (scary-looking) output:
 
 <pre>
-$ hg mail 99999
+$ git sync
+Failed to merge in the changes.
+Patch failed at 0023 math: improved Sin, Cos and Tan precision for very large arguments
+The copy of the patch that failed is found in:
+   /home/you/repo/.git/rebase-apply/patch
+
+When you have resolved this problem, run "git rebase --continue".
+If you prefer to skip this patch, run "git rebase --skip" instead.
+To check out the original branch and stop rebasing, run "git rebase --abort".
 </pre>
 
-
 <p>
-Or to upload your change without sending a notification, run
+If this happens, run
 </p>
 
 <pre>
-$ hg upload 99999
+$ git status
 </pre>
 
 <p>
-You will probably revise your code in response to the reviewer comments.
-You might also visit the code review web page and reply to the comments,
-letting the reviewer know that you've addressed them or explain why you
-haven't.  When you're done replying, click “Publish and Mail comments”
-to send the line-by-line replies and any other comments.
+to see which files failed to merge.
+The output will look something like this:
 </p>
 
-<p>
-The reviewer can comment on the new copy, and the process repeats.
-The reviewer approves the change by replying with a mail that says
-<code>LGTM</code>: looks good to me.
-</p>
+<pre>
+rebase in progress; onto a24c3eb
+You are currently rebasing branch 'mcgillicutty' on 'a24c3eb'.
+  (fix conflicts and then run "git rebase --continue")
+  (use "git rebase --skip" to skip this patch)
+  (use "git rebase --abort" to check out the original branch)
 
-<p>
-You can see a list of your pending changes by running <code>hg pending</code> (<code>hg p</code> for short).
-</p>
+Unmerged paths:
+  (use "git reset HEAD <file>..." to unstage)
+  (use "git add <file>..." to mark resolution)
 
-<h3>Reviewing code by others</h3>
+	<i>both modified:   sin.go</i>
+</pre>
 
 <p>
-You can import a CL proposed by someone else into your local Mercurial client
-by using the <code>hg clpatch</code> command. Running
+The only important part in that transcript is the italicized "both modified"
+line: Git failed to merge your changes with the conflicting change.
+When this happens, Git leaves both sets of edits in the file,
+with conflicts marked by <code><<<<<<<</code> and
+<code>>>>>>>></code>.
+It is now your job to edit the file to combine them.
+Continuing the example, searching for those strings in <code>sin.go</code>
+might turn up:
 </p>
 
 <pre>
-$ hg clpatch 99999
+	arg = scale(arg)
+<<<<<<< HEAD
+	if arg > 1e9 {
+=======
+	if arg > 1e10 {
+>>>>>>> mcgillicutty
+		largeReduce(arg)
 </pre>
 
 <p>
-will apply the latest diff for CL 99999 to your working copy. If any of the
-files referenced in CL 99999 have local modifications, <code>clpatch</code>
-will refuse to apply the whole diff. Once applied, CL 99999 will show up in
-the output of <code>hg pending</code> and others.
-</p>
-
-<p>
-To revert a CL you have applied locally, use the <code>hg revert</code>
-command. Running
+Git doesn't show it, but suppose the original text that both edits
+started with was 1e8; you changed it to 1e10 and the other change to 1e9,
+so the correct answer might now be 1e10.  First, edit the section
+to remove the markers and leave the correct code:
 </p>
 
 <pre>
-$ hg revert @99999
+	arg = scale(arg)
+	if arg > 1e10 {
+		largeReduce(arg)
 </pre>
 
 <p>
-will revert any files mentioned on CL 99999 to their original state. This can
-be an effective way of reverting one CL revision and applying another.
+Then tell Git that the conflict is resolved by running
 </p>
 
-<p>
-Once the CL has been submitted, the next time you run <code>hg sync</code>
-it will be removed from your local pending list. Occasionally the pending list
-can get out of sync leaving stale references to closed or abandoned CLs.
-You can use <code>hg change -D 99999</code> to remove the reference to CL 99999.
-</p>
-
-<h3>Submit the change after the review</h3>
+<pre>
+$ git add sin.go
+</pre>
 
 <p>
-After the code has been <code>LGTM</code>'ed, it is time to submit
-it to the Mercurial repository.
+If you had been editing the file, say for debugging, but do not
+care to preserve your changes, you can run
+<code>git</code> <code>reset</code> <code>HEAD</code> <code>sin.go</code>
+to abandon your changes.
+Then run <code>git</code> <code>rebase</code> <code>--continue</code> to
+restore the change commit.
 </p>
 
+<h3>Reviewing code by others</h3>
+
 <p>
-If you are not a committer, you cannot submit the change directly.
-Instead a committer, usually the reviewer who said <code>LGTM</code>,
-will run:
+You can import a change proposed by someone else into your local Git repository.
+On the Gerrit review page, click the "Download ▼" link in the upper right
+corner, copy the "Checkout" command and run it from your local Git repo.
+It should look something like this:
 </p>
 
 <pre>
-$ hg clpatch 99999
-$ hg submit 99999
+$ git fetch https://go.googlesource.com/review refs/changes/21/1221/1 && git checkout FETCH_HEAD
 </pre>
 
 <p>
-The <code>submit</code> command submits the code.  You will be listed as the
-author, but the change message will also indicate who the committer was.
-Your local client will notice that the change has been submitted
-when you next run <code>hg sync</code>.
+To revert, change back to the branch you were working in.
 </p>
 
+<h3>Submit the change after the review</h3>
+
 <p>
-If you are a committer, you can run:
+After the code has been <code>LGTM</code>'ed, an approver may
+submit it to the master branch using the Gerrit UI.
+There is a "Submit" button on the web page for the change
+that appears once the change is approved (marked +2).
 </p>
 
-<pre>
-$ hg submit 99999
-</pre>
-
 <p>
 This checks the change into the repository.
 The change description will include a link to the code review,
 and the code review will be updated with a link to the change
 in the repository.
+Since the method used to integrate the changes is "Cherry Pick",
+the commit hashes in the repository will be changed by
+the submit operation.
 </p>
 
-<p>
-If your local copy of the repository is out of date,
-<code>hg submit</code> will refuse the change:
-</p>
-
-<pre>
-$ hg submit 99999
-local repository out of date; must sync before submit
-</pre>
-
 <h3>More information</h3>
 
 <p>
-In addition to the information here, the Go community maintains a <a href="https://code.google.com/p/go-wiki/wiki/CodeReview">CodeReview</a> wiki page.
+In addition to the information here, the Go community maintains a <a href="https://golang.org/wiki/CodeReview">CodeReview</a> wiki page.
 Feel free to contribute to this page as you learn the review process.
 </p>
 
@@ -617,7 +622,8 @@ Feel free to contribute to this page as you learn the review process.
 
 <p>Files in the Go repository don't list author names,
 both to avoid clutter and to avoid having to keep the lists up to date.
-Instead, your name will appear in the <a href="https://code.google.com/p/go/source/list">Mercurial change log</a>
+Instead, your name will appear in the
+<a href="https://golang.org/change">change log</a>
 and in the <a href="/CONTRIBUTORS"><code>CONTRIBUTORS</code></a> file
 and perhaps the <a href="/AUTHORS"><code>AUTHORS</code></a> file.
 </p>
diff --git a/doc/debugging_with_gdb.html b/doc/debugging_with_gdb.html
index afaedf7..8368164 100644
--- a/doc/debugging_with_gdb.html
+++ b/doc/debugging_with_gdb.html
@@ -120,7 +120,7 @@ For example:
 
 <p>
 If you'd like to see how this works, or want to extend it, take a look at <a
-href="/src/pkg/runtime/runtime-gdb.py">src/pkg/runtime/runtime-gdb.py</a> in
+href="/src/runtime/runtime-gdb.py">src/runtime/runtime-gdb.py</a> in
 the Go source distribution. It depends on some special magic types
 (<code>hash<T,U></code>) and variables (<code>runtime.m</code> and
 <code>runtime.g</code>) that the linker
@@ -153,7 +153,7 @@ the form <code>pkg.(*MyType).Meth</code>.
 <p>
 In this tutorial we will inspect the binary of the
 <a href="/pkg/regexp/">regexp</a> package's unit tests. To build the binary,
-change to <code>$GOROOT/src/pkg/regexp</code> and run <code>go test -c</code>.
+change to <code>$GOROOT/src/regexp</code> and run <code>go test -c</code>.
 This should produce an executable file named <code>regexp.test</code>.
 </p>
 
@@ -172,7 +172,7 @@ License GPLv  3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.htm
 Type "show copying" and "show warranty" for licensing/warranty details.
 This GDB was configured as "x86_64-linux".
 
-Reading symbols from  /home/user/go/src/pkg/regexp/regexp.test...
+Reading symbols from  /home/user/go/src/regexp/regexp.test...
 done.
 Loading Go Runtime support.
 (gdb) 
@@ -180,7 +180,7 @@ Loading Go Runtime support.
 
 <p>
 The message <code>"Loading Go Runtime support"</code> means that GDB loaded the
-extension from <code>$GOROOT/src/pkg/runtime/runtime-gdb.py</code>.
+extension from <code>$GOROOT/src/runtime/runtime-gdb.py</code>.
 </p>
 
 <p>
@@ -199,7 +199,7 @@ it by hand by telling gdb (assuming you have the go sources in
 </p>
 
 <pre>
-(gdb) <b>source ~/go/src/pkg/runtime/runtime-gdb.py</b>
+(gdb) <b>source ~/go/src/runtime/runtime-gdb.py</b>
 Loading Go Runtime support.
 </pre>
 
@@ -259,7 +259,7 @@ Set a breakpoint at the <code>TestFind</code> function:
 
 <pre>
 (gdb) <b>b 'regexp.TestFind'</b>
-Breakpoint 1 at 0x424908: file /home/user/go/src/pkg/regexp/find_test.go, line 148.
+Breakpoint 1 at 0x424908: file /home/user/go/src/regexp/find_test.go, line 148.
 </pre>
 
 <p>
@@ -268,9 +268,9 @@ Run the program:
 
 <pre>
 (gdb) <b>run</b>
-Starting program: /home/user/go/src/pkg/regexp/regexp.test
+Starting program: /home/user/go/src/regexp/regexp.test
 
-Breakpoint 1, regexp.TestFind (t=0xf8404a89c0) at /home/user/go/src/pkg/regexp/find_test.go:148
+Breakpoint 1, regexp.TestFind (t=0xf8404a89c0) at /home/user/go/src/regexp/find_test.go:148
 148	func TestFind(t *testing.T) {
 </pre>
 
@@ -297,9 +297,9 @@ Look at the stack trace for where we’ve paused the program:
 
 <pre>
 (gdb) <b>bt</b>  <i># backtrace</i>
-#0  regexp.TestFind (t=0xf8404a89c0) at /home/user/go/src/pkg/regexp/find_test.go:148
-#1  0x000000000042f60b in testing.tRunner (t=0xf8404a89c0, test=0x573720) at /home/user/go/src/pkg/testing/testing.go:156
-#2  0x000000000040df64 in runtime.initdone () at /home/user/go/src/pkg/runtime/proc.c:242
+#0  regexp.TestFind (t=0xf8404a89c0) at /home/user/go/src/regexp/find_test.go:148
+#1  0x000000000042f60b in testing.tRunner (t=0xf8404a89c0, test=0x573720) at /home/user/go/src/testing/testing.go:156
+#2  0x000000000040df64 in runtime.initdone () at /home/user/go/src/runtime/proc.c:242
 #3  0x000000f8404a89c0 in ?? ()
 #4  0x0000000000573720 in ?? ()
 #5  0x0000000000000000 in ?? ()
@@ -311,18 +311,18 @@ The other goroutine, number 1, is stuck in <code>runtime.gosched</code>, blocked
 
 <pre>
 (gdb) <b>goroutine 1 bt</b>
-#0  0x000000000040facb in runtime.gosched () at /home/user/go/src/pkg/runtime/proc.c:873
+#0  0x000000000040facb in runtime.gosched () at /home/user/go/src/runtime/proc.c:873
 #1  0x00000000004031c9 in runtime.chanrecv (c=void, ep=void, selected=void, received=void)
- at  /home/user/go/src/pkg/runtime/chan.c:342
-#2  0x0000000000403299 in runtime.chanrecv1 (t=void, c=void) at/home/user/go/src/pkg/runtime/chan.c:423
+ at  /home/user/go/src/runtime/chan.c:342
+#2  0x0000000000403299 in runtime.chanrecv1 (t=void, c=void) at/home/user/go/src/runtime/chan.c:423
 #3  0x000000000043075b in testing.RunTests (matchString={void (struct string, struct string, bool *, error *)}
- 0x7ffff7f9ef60, tests=  []testing.InternalTest = {...}) at /home/user/go/src/pkg/testing/testing.go:201
+ 0x7ffff7f9ef60, tests=  []testing.InternalTest = {...}) at /home/user/go/src/testing/testing.go:201
 #4  0x00000000004302b1 in testing.Main (matchString={void (struct string, struct string, bool *, error *)} 
  0x7ffff7f9ef80, tests= []testing.InternalTest = {...}, benchmarks= []testing.InternalBenchmark = {...})
-at /home/user/go/src/pkg/testing/testing.go:168
-#5  0x0000000000400dc1 in main.main () at /home/user/go/src/pkg/regexp/_testmain.go:98
-#6  0x00000000004022e7 in runtime.mainstart () at /home/user/go/src/pkg/runtime/amd64/asm.s:78
-#7  0x000000000040ea6f in runtime.initdone () at /home/user/go/src/pkg/runtime/proc.c:243
+at /home/user/go/src/testing/testing.go:168
+#5  0x0000000000400dc1 in main.main () at /home/user/go/src/regexp/_testmain.go:98
+#6  0x00000000004022e7 in runtime.mainstart () at /home/user/go/src/runtime/amd64/asm.s:78
+#7  0x000000000040ea6f in runtime.initdone () at /home/user/go/src/runtime/proc.c:243
 #8  0x0000000000000000 in ?? ()
 </pre>
 
@@ -333,7 +333,7 @@ The stack frame shows we’re currently executing the <code>regexp.TestFind</cod
 <pre>
 (gdb) <b>info frame</b>
 Stack level 0, frame at 0x7ffff7f9ff88:
- rip = 0x425530 in regexp.TestFind (/home/user/go/src/pkg/regexp/find_test.go:148); 
+ rip = 0x425530 in regexp.TestFind (/home/user/go/src/regexp/find_test.go:148); 
     saved rip 0x430233
  called by frame at 0x7ffff7f9ffa8
  source language minimal.
@@ -410,7 +410,7 @@ We can step into the <code>String</code>function call with <code>"s"</code>:
 
 <pre>
 (gdb) <b>s</b>
-regexp.(*Regexp).String (re=0xf84068d070, noname=void) at /home/user/go/src/pkg/regexp/regexp.go:97
+regexp.(*Regexp).String (re=0xf84068d070, noname=void) at /home/user/go/src/regexp/regexp.go:97
 97      func (re *Regexp) String() string {
 </pre>
 
@@ -421,12 +421,12 @@ Get a stack trace to see where we are:
 <pre>
 (gdb) <b>bt</b>
 #0  regexp.(*Regexp).String (re=0xf84068d070, noname=void)
-    at /home/user/go/src/pkg/regexp/regexp.go:97
+    at /home/user/go/src/regexp/regexp.go:97
 #1  0x0000000000425615 in regexp.TestFind (t=0xf840688b60)
-    at /home/user/go/src/pkg/regexp/find_test.go:151
+    at /home/user/go/src/regexp/find_test.go:151
 #2  0x0000000000430233 in testing.tRunner (t=0xf840688b60, test=0x5747b8)
-    at /home/user/go/src/pkg/testing/testing.go:156
-#3  0x000000000040ea6f in runtime.initdone () at /home/user/go/src/pkg/runtime/proc.c:243
+    at /home/user/go/src/testing/testing.go:156
+#3  0x000000000040ea6f in runtime.initdone () at /home/user/go/src/runtime/proc.c:243
 ....
 </pre>
 
diff --git a/doc/devel/release.html b/doc/devel/release.html
index 1a84391..5b5d6ab 100644
--- a/doc/devel/release.html
+++ b/doc/devel/release.html
@@ -3,8 +3,7 @@
 }-->
 
 <p>This page summarizes the changes between official stable releases of Go.
-The <a href="//code.google.com/p/go/source/list">Mercurial change log</a>
-has the full details.</p>
+The <a href="//golang.org/change">change log</a> has the full details.</p>
 
 <p>To update to a specific release, use:</p>
 
@@ -13,6 +12,13 @@ hg pull
 hg update <i>tag</i>
 </pre>
 
+<h2 id="go1.4">go1.4 (released 2014/12/10)</h2>
+
+<p>
+Go 1.4 is a major release of Go.
+Read the <a href="/doc/go1.4">Go 1.4 Release Notes</a> for more information.
+</p>
+
 <h2 id="go1.3">go1.3 (released 2014/06/18)</h2>
 
 <p>
diff --git a/doc/devel/weekly.html b/doc/devel/weekly.html
index 34c87dc..5a9c51e 100644
--- a/doc/devel/weekly.html
+++ b/doc/devel/weekly.html
@@ -5,7 +5,7 @@
 <p>This page summarizes the changes between tagged weekly snapshots of Go.
 Such snapshots are no longer created. This page remains as a historical reference only.</p>
 
-<p>For recent information, see the <a href="//code.google.com/p/go/source/list">Mercurial change log</a> and <a href="//groups.google.com/group/golang-dev/">development mailing list</a>.</p>
+<p>For recent information, see the <a href="//golang.org/change">change log</a> and <a href="//groups.google.com/group/golang-dev/">development mailing list</a>.</p>
 
 <h2 id="2012-03-27">2012-03-27 (<a href="release.html#go1">Go 1</a>)</h2>
 
diff --git a/doc/docs.html b/doc/docs.html
index 642f36d..7eb3a3a 100644
--- a/doc/docs.html
+++ b/doc/docs.html
@@ -147,8 +147,8 @@ Guided tours of Go programs.
 <li><a href="/blog/godoc-documenting-go-code">Godoc: documenting Go code</a> - writing good documentation for <a href="/cmd/godoc/">godoc</a>.</li>
 <li><a href="/blog/profiling-go-programs">Profiling Go Programs</a></li>
 <li><a href="/doc/articles/race_detector.html">Data Race Detector</a> - a manual for the data race detector.</li>
-<li><a href="/blog/race-detector">Introducing the Go Race Detector</a> - an introduction to the race detector.
-<li><a href="/doc/asm">A Quick Guide to Go's Assembler</a> - an introduction to the assembler used by Go.
+<li><a href="/blog/race-detector">Introducing the Go Race Detector</a> - an introduction to the race detector.</li>
+<li><a href="/doc/asm">A Quick Guide to Go's Assembler</a> - an introduction to the assembler used by Go.</li>
 </ul>
 
 <h4 id="articles_more">More</h4>
diff --git a/doc/effective_go.html b/doc/effective_go.html
index c1e3107..4dd1a3e 100644
--- a/doc/effective_go.html
+++ b/doc/effective_go.html
@@ -37,7 +37,7 @@ should read first.
 <h3 id="examples">Examples</h3>
 
 <p>
-The <a href="/src/pkg/">Go package sources</a>
+The <a href="/src/">Go package sources</a>
 are intended to serve not
 only as the core library but also as examples of how to
 use the language.
@@ -344,7 +344,7 @@ determines just which package is being used.
 <p>
 Another convention is that the package name is the base name of
 its source directory;
-the package in <code>src/pkg/encoding/base64</code>
+the package in <code>src/encoding/base64</code>
 is imported as <code>"encoding/base64"</code> but has name <code>base64</code>,
 not <code>encoding_base64</code> and not <code>encodingBase64</code>.
 </p>
diff --git a/doc/gccgo_contribute.html b/doc/gccgo_contribute.html
index 9dd6ecb..db7d1ab 100644
--- a/doc/gccgo_contribute.html
+++ b/doc/gccgo_contribute.html
@@ -73,7 +73,7 @@ script <code>libgo/merge.sh</code>.  Accordingly, most library changes
 should be made in the main Go repository.  The files outside
 of <code>libgo/go</code> are gccgo-specific; that said, some of the
 files in <code>libgo/runtime</code> are based on files
-in <code>src/pkg/runtime</code> in the main Go repository.
+in <code>src/runtime</code> in the main Go repository.
 </p>
 
 <h2>Testing</h2>
diff --git a/doc/gccgo_install.html b/doc/gccgo_install.html
index 4c1a8c2..acb315a 100644
--- a/doc/gccgo_install.html
+++ b/doc/gccgo_install.html
@@ -42,6 +42,10 @@ identical to Go 1.1.  The GCC 4.8.2 release includes a complete Go
 1.1.2 implementation.
 </p>
 
+<p>
+The GCC 4.9 releases include a complete Go 1.2 implementation.
+</p>
+
 <h2 id="Source_code">Source code</h2>
 
 <p>
diff --git a/doc/go1.3.html b/doc/go1.3.html
index 042de1b..d51052b 100644
--- a/doc/go1.3.html
+++ b/doc/go1.3.html
@@ -298,7 +298,7 @@ For example,
 <h3 id="godoc">Changes to godoc</h3>
 <p>
 When invoked with the <code>-analysis</code> flag, 
-<a href="//godoc.org/code.google.com/p/go.tools/cmd/godoc">godoc</a>
+<a href="//godoc.org/golang.org/x/tools/cmd/godoc">godoc</a>
 now performs sophisticated <a href="/lib/godoc/analysis/help.html">static
 analysis</a> of the code it indexes.  
 The results of analysis are presented in both the source view and the
@@ -318,7 +318,7 @@ call sites and their callees.
 The program <code>misc/benchcmp</code> that compares
 performance across benchmarking runs has been rewritten.
 Once a shell and awk script in the main repository, it is now a Go program in the <code>go.tools</code> repo.
-Documentation is <a href="//godoc.org/code.google.com/p/go.tools/cmd/benchcmp">here</a>.
+Documentation is <a href="//godoc.org/golang.org/x/tools/cmd/benchcmp">here</a>.
 </p>
 
 <p>
diff --git a/doc/go1.4.html b/doc/go1.4.html
new file mode 100644
index 0000000..b4f9619
--- /dev/null
+++ b/doc/go1.4.html
@@ -0,0 +1,896 @@
+<!--{
+	"Title": "Go 1.4 Release Notes",
+	"Path":  "/doc/go1.4",
+	"Template": true
+}-->
+
+<h2 id="introduction">Introduction to Go 1.4</h2>
+
+<p>
+The latest Go release, version 1.4, arrives as scheduled six months after 1.3.
+</p>
+
+<p>
+It contains only one tiny language change,
+in the form of a backwards-compatible simple variant of <code>for</code>-<code>range</code> loop,
+and a possibly breaking change to the compiler involving methods on pointers-to-pointers.
+</p>
+
+<p>
+The release focuses primarily on implementation work, improving the garbage collector
+and preparing the ground for a fully concurrent collector to be rolled out in the
+next few releases.
+Stacks are now contiguous, reallocated when necessary rather than linking on new
+"segments";
+this release therefore eliminates the notorious "hot stack split" problem.
+There are some new tools available including support in the <code>go</code> command
+for build-time source code generation.
+The release also adds support for ARM processors on Android and Native Client (NaCl)
+and for AMD64 on Plan 9.
+</p>
+
+<p>
+As always, Go 1.4 keeps the <a href="/doc/go1compat.html">promise
+of compatibility</a>,
+and almost everything 
+will continue to compile and run without change when moved to 1.4.
+</p>
+
+<h2 id="language">Changes to the language</h2>
+
+<h3 id="forrange">For-range loops</h3>
+<p>
+Up until Go 1.3, <code>for</code>-<code>range</code> loop had two forms
+</p>
+
+<pre>
+for i, v := range x {
+	...
+}
+</pre>
+
+<p>
+and
+</p>
+
+<pre>
+for i := range x {
+	...
+}
+</pre>
+
+<p>
+If one was not interested in the loop values, only the iteration itself, it was still
+necessary to mention a variable (probably the <a href="/ref/spec#Blank_identifier">blank identifier</a>, as in
+<code>for</code> <code>_</code> <code>=</code> <code>range</code> <code>x</code>), because
+the form
+</p>
+
+<pre>
+for range x {
+	...
+}
+</pre>
+
+<p>
+was not syntactically permitted.
+</p>
+
+<p>
+This situation seemed awkward, so as of Go 1.4 the variable-free form is now legal.
+The pattern arises rarely but the code can be cleaner when it does.
+</p>
+
+<p>
+<em>Updating</em>: The change is strictly backwards compatible to existing Go
+programs, but tools that analyze Go parse trees may need to be modified to accept
+this new form as the
+<code>Key</code> field of <a href="/pkg/go/ast/#RangeStmt"><code>RangeStmt</code></a>
+may now be <code>nil</code>.
+</p>
+
+<h3 id="methodonpointertopointer">Method calls on **T</h3>
+
+<p>
+Given these declarations,
+</p>
+
+<pre>
+type T int
+func (T) M() {}
+var x **T
+</pre>
+
+<p>
+both <code>gc</code> and <code>gccgo</code> accepted the method call
+</p>
+
+<pre>
+x.M()
+</pre>
+
+<p>
+which is a double dereference of the pointer-to-pointer <code>x</code>.
+The Go specification allows a single dereference to be inserted automatically,
+but not two, so this call is erroneous according to the language definition.
+It has therefore been disallowed in Go 1.4, which is a breaking change,
+although very few programs will be affected.
+</p>
+
+<p>
+<em>Updating</em>: Code that depends on the old, erroneous behavior will no longer
+compile but is easy to fix by adding an explicit dereference.
+</p>
+
+<h2 id="os">Changes to the supported operating systems and architectures</h2>
+
+<h3 id="android">Android</h3>
+
+<p>
+Go 1.4 can build binaries for ARM processors running the Android operating system.
+It can also build a <code>.so</code> library that can be loaded by an Android application
+using the supporting packages in the <a href="https://golang.org/x/mobile">mobile</a> subrepository.
+A brief description of the plans for this experimental port are available
+<a href="https://golang.org/s/go14android">here</a>.
+</p>
+
+<h3 id="naclarm">NaCl on ARM</h3>
+
+<p>
+The previous release introduced Native Client (NaCl) support for the 32-bit x86
+(<code>GOARCH=386</code>)
+and 64-bit x86 using 32-bit pointers (GOARCH=amd64p32).
+The 1.4 release adds NaCl support for ARM (GOARCH=arm).
+</p>
+
+<h3 id="plan9amd64">Plan9 on AMD64</h3>
+
+<p>
+This release adds support for the Plan 9 operating system on AMD64 processors,
+provided the kernel supports the <code>nsec</code> system call and uses 4K pages.
+</p>
+
+<h2 id="compatibility">Changes to the compatibility guidelines</h2>
+
+<p>
+The <a href="/pkg/unsafe/"><code>unsafe</code></a> package allows one
+to defeat Go's type system by exploiting internal details of the implementation
+or machine representation of data.
+It was never explicitly specified what use of <code>unsafe</code> meant
+with respect to compatibility as specified in the
+<a href="go1compat.html">Go compatibility guidelines</a>.
+The answer, of course, is that we can make no promise of compatibility
+for code that does unsafe things.
+</p>
+
+<p>
+We have clarified this situation in the documentation included in the release.
+The <a href="go1compat.html">Go compatibility guidelines</a> and the
+docs for the <a href="/pkg/unsafe/"><code>unsafe</code></a> package
+are now explicit that unsafe code is not guaranteed to remain compatible.
+</p>
+  
+<p>
+<em>Updating</em>: Nothing technical has changed; this is just a clarification
+of the documentation.
+</p>
+
+
+<h2 id="impl">Changes to the implementations and tools</h2>
+
+<h3 id="runtime">Changes to the runtime</h3>
+
+<p>
+Prior to Go 1.4, the runtime (garbage collector, concurrency support, interface management,
+maps, slices, strings, ...) was mostly written in C, with some assembler support.
+In 1.4, much of the code has been translated to Go so that the garbage collector can scan
+the stacks of programs in the runtime and get accurate information about what variables
+are active.
+This change was large but should have no semantic effect on programs.
+</p>
+
+<p>
+This rewrite allows the garbage collector in 1.4 to be fully precise,
+meaning that it is aware of the location of all active pointers in the program.
+This means the heap will be smaller as there will be no false positives keeping non-pointers alive.
+Other related changes also reduce the heap size, which is smaller by 10%-30% overall
+relative to the previous release.
+</p>
+
+<p>
+A consequence is that stacks are no longer segmented, eliminating the "hot split" problem.
+When a stack limit is reached, a new, larger stack is allocated, all active frames for
+the goroutine are copied there, and any pointers into the stack are updated.
+Performance can be noticeably better in some cases and is always more predictable.
+Details are available in <a href="https://golang.org/s/contigstacks">the design document</a>.
+</p>
+
+<p>
+The use of contiguous stacks means that stacks can start smaller without triggering performance issues,
+so the default starting size for a goroutine's stack in 1.4 has been reduced from 8192 bytes to 2048 bytes.
+</p>
+
+<p>
+As preparation for the concurrent garbage collector scheduled for the 1.5 release,
+writes to pointer values in the heap are now done by a function call,
+called a write barrier, rather than directly from the function updating the value.
+In this next release, this will permit the garbage collector to mediate writes to the heap while it is running.
+This change has no semantic effect on programs in 1.4, but was
+included in the release to test the compiler and the resulting performance.
+</p>
+
+<p>
+The implementation of interface values has been modified.
+In earlier releases, the interface contained a word that was either a pointer or a one-word
+scalar value, depending on the type of the concrete object stored.
+This implementation was problematical for the garbage collector,
+so as of 1.4 interface values always hold a pointer.
+In running programs, most interface values were pointers anyway,
+so the effect is minimal, but programs that store integers (for example) in
+interfaces will see more allocations.
+</p>
+
+<p>
+As of Go 1.3, the runtime crashes if it finds a memory word that should contain
+a valid pointer but instead contains an obviously invalid pointer (for example, the value 3).
+Programs that store integers in pointer values may run afoul of this check and crash.
+In Go 1.4, setting the <a href="/pkg/runtime/"><code>GODEBUG</code></a> variable
+<code>invalidptr=0</code> disables
+the crash as a workaround, but we cannot guarantee that future releases will be
+able to avoid the crash; the correct fix is to rewrite code not to alias integers and pointers.
+</p>
+
+<h3 id="asm">Assembly</h3>
+
+<p>
+The language accepted by the assemblers <code>cmd/5a</code>, <code>cmd/6a</code>
+and <code>cmd/8a</code> has had several changes,
+mostly to make it easier to deliver type information to the runtime.
+</p>
+
+<p>
+First, the <code>textflag.h</code> file that defines flags for <code>TEXT</code> directives
+has been copied from the linker source directory to a standard location so it can be
+included with the simple directive
+</p>
+
+<pre>
+#include "textflag.h"
+</pre>
+
+<p>
+The more important changes are in how assembler source can define the necessary
+type information.
+For most programs it will suffice to move data
+definitions (<code>DATA</code> and <code>GLOBL</code> directives)
+out of assembly into Go files
+and to write a Go declaration for each assembly function.
+The <a href="/doc/asm#runtime">assembly document</a> describes what to do.
+</p>
+
+<p>
+<em>Updating</em>:
+Assembly files that include <code>textflag.h</code> from its old
+location will still work, but should be updated.
+For the type information, most assembly routines will need no change,
+but all should be examined.
+Assembly source files that define data,
+functions with non-empty stack frames, or functions that return pointers
+need particular attention.
+A description of the necessary (but simple) changes
+is in the <a href="/doc/asm#runtime">assembly document</a>.
+</p>
+
+<p>
+More information about these changes is in the <a href="/doc/asm">assembly document</a>.
+</p>
+
+<h3 id="gccgo">Status of gccgo</h3>
+
+<p>
+The release schedules for the GCC and Go projects do not coincide.
+GCC release 4.9 contains the Go 1.2 version of gccgo.
+The next release, GCC 5, will likely have the Go 1.4 version of gccgo.
+</p>
+
+<h3 id="internalpackages">Internal packages</h3>
+
+<p>
+Go's package system makes it easy to structure programs into components with clean boundaries,
+but there are only two forms of access: local (unexported) and global (exported).
+Sometimes one wishes to have components that are not exported,
+for instance to avoid acquiring clients of interfaces to code that is part of a public repository
+but not intended for use outside the program to which it belongs.
+</p>
+
+<p>
+The Go language does not have the power to enforce this distinction, but as of Go 1.4 the
+<a href="/cmd/go/"><code>go</code></a> command introduces
+a mechanism to define "internal" packages that may not be imported by packages outside
+the source subtree in which they reside.
+</p>
+
+<p>
+To create such a package, place it in a directory named <code>internal</code> or in a subdirectory of a directory
+named internal.
+When the <code>go</code> command sees an import of a package with <code>internal</code> in its path,
+it verifies that the package doing the import
+is within the tree rooted at the parent of the <code>internal</code> directory.
+For example, a package <code>.../a/b/c/internal/d/e/f</code>
+can be imported only by code in the directory tree rooted at <code>.../a/b/c</code>.
+It cannot be imported by code in <code>.../a/b/g</code> or in any other repository.
+</p>
+
+<p>
+For Go 1.4, the internal package mechanism is enforced for the main Go repository;
+from 1.5 and onward it will be enforced for any repository.
+</p>
+
+<p>
+Full details of the mechanism are in
+<a href="https://golang.org/s/go14internal">the design document</a>.
+</p>
+
+<h3 id="canonicalimports">Canonical import paths</h3>
+
+<p>
+Code often lives in repositories hosted by public services such as <code>github.com</code>,
+meaning that the import paths for packages begin with the name of the hosting service,
+<code>github.com/rsc/pdf</code> for example.
+One can use
+<a href="/cmd/go/#hdr-Remote_import_paths">an existing mechanism</a>
+to provide a "custom" or "vanity" import path such as
+<code>rsc.io/pdf</code>, but
+that creates two valid import paths for the package.
+That is a problem: one may inadvertently import the package through the two
+distinct paths in a single program, which is wasteful;
+miss an update to a package because the path being used is not recognized to be
+out of date;
+or break clients using the old path by moving the package to a different hosting service.
+</p>
+
+<p>
+Go 1.4 introduces an annotation for package clauses in Go source that identify a canonical
+import path for the package.
+If an import is attempted using a path that is not canonical,
+the <a href="/cmd/go/"><code>go</code></a> command
+will refuse to compile the importing package.
+</p>
+
+<p>
+The syntax is simple: put an identifying comment on the package line.
+For our example, the package clause would read:
+</p>
+
+<pre>
+package pdf // import "rsc.io/pdf"
+</pre>
+
+<p>
+With this in place,
+the <code>go</code> command will
+refuse to compile a package that imports <code>github.com/rsc/pdf</code>, 
+ensuring that the code can be moved without breaking users.
+</p>
+
+<p>
+The check is at build time, not download time, so if <code>go</code> <code>get</code>
+fails because of this check, the mis-imported package has been copied to the local machine
+and should be removed manually.
+</p>
+
+<p>
+To complement this new feature, a check has been added at update time to verify
+that the local package's remote repository matches that of its custom import.
+The <code>go</code> <code>get</code> <code>-u</code> command will fail to
+update a package if its remote repository has changed since it was first
+downloaded.
+The new <code>-f</code> flag overrides this check.
+</p>
+
+<p>
+Further information is in
+<a href="https://golang.org/s/go14customimport">the design document</a>.
+</p>
+
+<h3 id="subrepo">Import paths for the subrepositories</h3>
+
+<p>
+The Go project subrepositories (<code>code.google.com/p/go.tools</code> and so on)
+are now available under custom import paths replacing <code>code.google.com/p/go.</code> with <code>golang.org/x/</code>,
+as in <code>golang.org/x/tools</code>.
+We will add canonical import comments to the code around June 1, 2015,
+at which point Go 1.4 and later will stop accepting the old <code>code.google.com</code> paths.
+</p>
+
+<p>
+<em>Updating</em>: All code that imports from subrepositories should change
+to use the new <code>golang.org</code> paths.
+Go 1.0 and later can resolve and import the new paths, so updating will not break
+compatibility with older releases.
+Code that has not updated will stop compiling with Go 1.4 around June 1, 2015.
+</p>
+
+<h3 id="gogenerate">The go generate subcommand</h3>
+
+<p>
+The <a href="/cmd/go/"><code>go</code></a> command has a new subcommand,
+<a href="/cmd/go/#hdr-Generate_Go_files_by_processing_source"><code>go generate</code></a>,
+to automate the running of tools to generate source code before compilation.
+For example, it can be used to run the <a href="/cmd/yacc"><code>yacc</code></a>
+compiler-compiler on a <code>.y</code> file to produce the Go source file implementing the grammar,
+or to automate the generation of <code>String</code> methods for typed constants using the new
+<a href="http://godoc.org/golang.org/x/tools/cmd/stringer">stringer</a>
+tool in the <code>golang.org/x/tools</code> subrepository.
+</p>
+
+<p>
+For more information, see the 
+<a href="https://golang.org/s/go1.4-generate">design document</a>.
+</p>
+
+<h3 id="filenames">Change to file name handling</h3>
+
+<p>
+Build constraints, also known as build tags, control compilation by including or excluding files
+(see the documentation <a href="/pkg/go/build/"><code>/go/build</code></a>).
+Compilation can also be controlled by the name of the file itself by "tagging" the file with
+a suffix (before the <code>.go</code> or <code>.s</code> extension) with an underscore
+and the name of the architecture or operating system.
+For instance, the file <code>gopher_arm.go</code> will only be compiled if the target
+processor is an ARM.
+</p>
+
+<p>
+Before Go 1.4, a file called just <code>arm.go</code> was similarly tagged, but this behavior
+can break sources when new architectures are added, causing files to suddenly become tagged.
+In 1.4, therefore, a file will be tagged in this manner only if the tag (architecture or operating
+system name) is preceded by an underscore.
+</p>
+
+<p>
+<em>Updating</em>: Packages that depend on the old behavior will no longer compile correctly.
+Files with names like <code>windows.go</code> or <code>amd64.go</code> should either
+have explicit build tags added to the source or be renamed to something like
+<code>os_windows.go</code> or <code>support_amd64.go</code>.
+</p>
+
+<h3 id="gocmd">Other changes to the go command</h3>
+
+<p>
+There were a number of minor changes to the
+<a href="/cmd/go/"><code>cmd/go</code></a>
+command worth noting.
+</p>
+
+<ul>
+
+<li>
+Unless <a href="/cmd/cgo/"><code>cgo</code></a> is being used to build the package,
+the <code>go</code> command now refuses to compile C source files,
+since the relevant C compilers
+(<a href="/cmd/6c/"><code>6c</code></a> etc.)
+are intended to be removed from the installation in some future release.
+(They are used today only to build part of the runtime.)
+It is difficult to use them correctly in any case, so any extant uses are likely incorrect,
+so we have disabled them.
+</li>
+
+<li>
+The <a href="/cmd/go/#hdr-Test_packages"><code>go</code> <code>test</code></a>
+subcommand has a new flag, <code>-o</code>, to set the name of the resulting binary,
+corresponding to the same flag in other subcommands.
+The non-functional <code>-file</code> flag has been removed.
+</li>
+
+<li>
+The <a href="/cmd/go/#hdr-Test_packages"><code>go</code> <code>test</code></a>
+subcommand will compile and link all <code>*_test.go</code> files in the package,
+even when there are no <code>Test</code> functions in them. 
+It previously ignored such files.
+</li>
+
+<li>
+The behavior of the
+<a href="/cmd/go/#hdr-Test_packages"><code>go</code> <code>build</code></a>
+subcommand's
+<code>-a</code> flag has been changed for non-development installations.
+For installations running a released distribution, the <code>-a</code> flag will no longer
+rebuild the standard library and commands, to avoid overwriting the installation's files.
+</li>
+
+</ul>
+
+<h3 id="pkg">Changes to package source layout</h3>
+
+<p>
+In the main Go source repository, the source code for the packages was kept in
+the directory <code>src/pkg</code>, which made sense but differed from
+other repositories, including the Go subrepositories.
+In Go 1.4, the<code> pkg</code> level of the source tree is now gone, so for example
+the <a href="/pkg/fmt/"><code>fmt</code></a> package's source, once kept in
+directory <code>src/pkg/fmt</code>, now lives one level higher in <code>src/fmt</code>.
+</p>
+
+<p>
+<em>Updating</em>: Tools like <code>godoc</code> that discover source code
+need to know about the new location. All tools and services maintained by the Go team
+have been updated.
+</p>
+
+
+<h3 id="swig">SWIG</h3>
+
+<p>
+Due to runtime changes in this release, Go 1.4 requires SWIG 3.0.3.
+</p>
+
+<h3 id="misc">Miscellany</h3>
+
+<p>
+The standard repository's top-level <code>misc</code> directory used to contain
+Go support for editors and IDEs: plugins, initialization scripts and so on.
+Maintaining these was becoming time-consuming
+and needed external help because many of the editors listed were not used by
+members of the core team.
+It also required us to make decisions about which plugin was best for a given
+editor, even for editors we do not use.
+</p>
+
+<p>
+The Go community at large is much better suited to managing this information.
+In Go 1.4, therefore, this support has been removed from the repository.
+Instead, there is a curated, informative list of what's available on
+a <a href="//golang.org/wiki/IDEsAndTextEditorPlugins">wiki page</a>.
+</p>
+
+<h2 id="performance">Performance</h2>
+
+<p>
+Most programs will run about the same speed or slightly faster in 1.4 than in 1.3;
+some will be slightly slower.
+There are many changes, making it hard to be precise about what to expect.
+</p>
+
+<p>
+As mentioned above, much of the runtime was translated to Go from C,
+which led to some reduction in heap sizes.
+It also improved performance slightly because the Go compiler is better
+at optimization, due to things like inlining, than the C compiler used to build
+the runtime.
+</p>
+
+<p>
+The garbage collector was sped up, leading to measurable improvements for
+garbage-heavy programs.
+On the other hand, the new write barriers slow things down again, typically
+by about the same amount but, depending on their behavior, some programs
+may be somewhat slower or faster.
+</p>
+
+<p>
+Library changes that affect performance are documented below.
+</p>
+
+<h2 id="library">Changes to the standard library</h2>
+
+<h3 id="new_packages">New packages</h3>
+
+<p>
+There are no new packages in this release.
+</p>
+
+<h3 id="major_library_changes">Major changes to the library</h3>
+
+<h4 id="scanner">bufio.Scanner</h4>
+
+<p>
+The <a href="/pkg/bufio/#Scanner"><code>Scanner</code></a> type in the
+<a href="/pkg/bufio/"><code>bufio</code></a> package
+has had a bug fixed that may require changes to custom
+<a href="/pkg/bufio/#SplitFunc"><code>split functions</code></a>. 
+The bug made it impossible to generate an empty token at EOF; the fix
+changes the end conditions seen by the split function.
+Previously, scanning stopped at EOF if there was no more data.
+As of 1.4, the split function will be called once at EOF after input is exhausted,
+so the split function can generate a final empty token
+as the documentation already promised.
+</p>
+
+<p>
+<em>Updating</em>: Custom split functions may need to be modified to
+handle empty tokens at EOF as desired.
+</p>
+
+<h4 id="syscall">syscall</h4>
+
+<p>
+The <a href="/pkg/syscall/"><code>syscall</code></a> package is now frozen except
+for changes needed to maintain the core repository.
+In particular, it will no longer be extended to support new or different system calls
+that are not used by the core.
+The reasons are described at length in <a href="https://golang.org/s/go1.4-syscall">a
+separate document</a>.
+</p>
+
+<p>
+A new subrepository, <a href="https://golang.org/x/sys">golang.org/x/sys</a>,
+has been created to serve as the location for new developments to support system
+calls on all kernels.
+It has a nicer structure, with three packages that each hold the implementation of
+system calls for one of
+<a href="http://godoc.org/golang.org/x/sys/unix">Unix</a>,
+<a href="http://godoc.org/golang.org/x/sys/windows">Windows</a> and
+<a href="http://godoc.org/golang.org/x/sys/plan9">Plan 9</a>.
+These packages will be curated more generously, accepting all reasonable changes
+that reflect kernel interfaces in those operating systems.
+See the documentation and the article mentioned above for more information.
+</p>
+
+<p>
+<em>Updating</em>: Existing programs are not affected as the <code>syscall</code>
+package is largely unchanged from the 1.3 release.
+Future development that requires system calls not in the <code>syscall</code> package
+should build on <code>golang.org/x/sys</code> instead.
+</p>
+
+<h3 id="minor_library_changes">Minor changes to the library</h3>
+
+<p>
+The following list summarizes a number of minor changes to the library, mostly additions.
+See the relevant package documentation for more information about each change.
+</p>
+
+<ul>
+
+<li>
+The <a href="/pkg/archive/zip/"><code>archive/zip</code></a> package's
+<a href="/pkg/archive/zip/#Writer"><code>Writer</code></a> now supports a
+<a href="/pkg/archive/zip/#Writer.Flush"><code>Flush</code></a> method.
+</li>
+
+<li>
+The <a href="/pkg/compress/flate/"><code>compress/flate</code></a>,
+<a href="/pkg/compress/gzip/"><code>compress/gzip</code></a>,
+and <a href="/pkg/compress/zlib/"><code>compress/zlib</code></a>
+packages now support a <code>Reset</code> method
+for the decompressors, allowing them to reuse buffers and improve performance.
+The <a href="/pkg/compress/gzip/"><code>compress/gzip</code></a> package also has a
+<a href="/pkg/compress/gzip/#Reader.Multistream"><code>Multistream</code></a> method to control support
+for multistream files.
+</li>
+
+<li>
+The <a href="/pkg/crypto/"><code>crypto</code></a> package now has a
+<a href="/pkg/crypto/#Signer"><code>Signer</code></a> interface, implemented by the
+<code>PrivateKey</code> types in
+<a href="/pkg/crypto/ecdsa"><code>crypto/ecdsa</code></a> and
+<a href="/pkg/crypto/rsa"><code>crypto/rsa</code></a>.
+</li>
+
+<li>
+The <a href="/pkg/crypto/tls/"><code>crypto/tls</code></a> package
+now supports ALPN as defined in <a href="http://tools.ietf.org/html/rfc7301">RFC 7301</a>.
+</li>
+
+<li>
+The <a href="/pkg/crypto/tls/"><code>crypto/tls</code></a> package
+now supports programmatic selection of server certificates
+through the new <a href="/pkg/crypto/tls/#Config.CertificateForName"><code>CertificateForName</code></a> function
+of the <a href="/pkg/crypo/tls/#Config"><code>Config</code></a> struct.
+</li>
+
+<li>
+Also in the crypto/tls package, the server now supports 
+<a href="https://tools.ietf.org/html/draft-ietf-tls-downgrade-scsv-00">TLS_FALLBACK_SCSV</a>
+to help clients detect fallback attacks.
+(The Go client does not support fallback at all, so it is not vulnerable to
+those attacks.)
+</li>
+
+<li>
+The <a href="/pkg/database/sql/"><code>database/sql</code></a> package can now list all registered
+<a href="/pkg/database/sql/#Drivers"><code>Drivers</code></a>.
+</li>
+
+<li>
+The <a href="/pkg/debug/dwarf/"><code>debug/dwarf</code></a> package now supports
+<a href="/pkg/debug/dwarf/#UnspecifiedType"><code>UnspecifiedType</code></a>s.
+</li>
+
+<li>
+In the <a href="/pkg/encoding/asn1/"><code>encoding/asn1</code></a> package,
+optional elements with a default value will now only be omitted if they have that value.
+</li>
+
+<li>
+The <a href="/pkg/encoding/csv/"><code>encoding/csv</code></a> package no longer
+quotes empty strings but does quote the end-of-data marker <code>\.</code> (backslash dot).
+This is permitted by the definition of CSV and allows it to work better with Postgres.
+</li>
+
+<li>
+The <a href="/pkg/encoding/gob/"><code>encoding/gob</code></a> package has been rewritten to eliminate
+the use of unsafe operations, allowing it to be used in environments that do not permit use of the
+<a href="/pkg/unsafe/"><code>unsafe</code></a> package.
+For typical uses it will be 10-30% slower, but the delta is dependent on the type of the data and
+in some cases, especially involving arrays, it can be faster.
+There is no functional change.
+</li>
+
+<li>
+The <a href="/pkg/encoding/xml/"><code>encoding/xml</code></a> package's
+<a href="/pkg/encoding/xml/#Decoder"><code>Decoder</code></a> can now report its input offset.
+</li>
+
+<li>
+In the <a href="/pkg/fmt/"><code>fmt</code></a> package,
+formatting of pointers to maps has changed to be consistent with that of pointers
+to structs, arrays, and so on.
+For instance, <code>&map[string]int{"one":</code> <code>1}</code> now prints by default as
+<code>&map[one:</code> <code>1]</code> rather than as a hexadecimal pointer value.
+</li>
+
+<li>
+The <a href="/pkg/image/"><code>image</code></a> package's
+<a href="/pkg/image/#Image"><code>Image</code></a>
+implementations like
+<a href="/pkg/image/#RGBA"><code>RGBA</code></a> and
+<a href="/pkg/image/#Gray"><code>Gray</code></a> have specialized
+<a href="/pkg/image/#RGBA.RGBAAt"><code>RGBAAt</code></a> and
+<a href="/pkg/image/#Gray.GrayAt"><code>GrayAt</code></a> methods alongside the general
+<a href="/pkg/image/#Image.At"><code>At</code></a> method.
+</li>
+
+<li>
+The <a href="/pkg/image/png/"><code>image/png</code></a> package now has an
+<a href="/pkg/image/png/#Encoder"><code>Encoder</code></a>
+type to control the compression level used for encoding.
+</li>
+
+<li>
+The <a href="/pkg/math/"><code>math</code></a> package now has a
+<a href="/pkg/math/#Nextafter32"><code>Nextafter32</code><a/> function.
+</li>
+
+<li>
+The <a href="/pkg/net/http/"><code>net/http</code></a> package's
+<a href="/pkg/net/http/#Request"><code>Request</code></a> type
+has a new <a href="/pkg/net/http/#Request.BasicAuth"><code>BasicAuth</code></a> method
+that returns the username and password from authenticated requests using the
+HTTP Basic Authentication
+Scheme.
+</li>
+
+<li>The <a href="/pkg/net/http/"><code>net/http</code></a> package's
+<a href="/pkg/net/http/#Request"><code>Transport</code></a> type
+has a new <a href="/pkg/net/http/#Transport.DialTLS"><code>DialTLS</code></a> hook
+that allows customizing the behavior of outbound TLS connections.
+</li>
+
+<li>
+The <a href="/pkg/net/http/httputil/"><code>net/http/httputil</code></a> package's
+<a href="/pkg/net/http/httputil/#ReverseProxy"><code>ReverseProxy</code></a> type
+has a new field,
+<a href="/pkg/net/http/#ReverseProxy.ErrorLog"><code>ErrorLog</code></a>, that
+provides user control of logging.
+</li>
+
+<li>
+The <a href="/pkg/os/"><code>os</code></a> package
+now implements symbolic links on the Windows operating system
+through the <a href="/pkg/os/#Symlink"><code>Symlink</code></a> function.
+Other operating systems already have this functionality.
+There is also a new <a href="/pkg/os/#Unsetenv"><code>Unsetenv</code></a> function.
+</li>
+
+<li>
+The <a href="/pkg/reflect/"><code>reflect</code></a> package's
+<a href="/pkg/reflect/#Type"><code>Type</code></a> interface
+has a new method, <a href="/pkg/reflect/#type.Comparable"><code>Comparable</code></a>,
+that reports whether the type implements general comparisons.
+</li>
+
+<li>
+Also in the <a href="/pkg/reflect/"><code>reflect</code></a> package, the
+<a href="/pkg/reflect/#Value"><code>Value</code></a> interface is now three instead of four words
+because of changes to the implementation of interfaces in the runtime.
+This saves memory but has no semantic effect.
+</li>
+
+<li>
+The <a href="/pkg/runtime/"><code>runtime</code></a> package
+now implements monotonic clocks on Windows,
+as it already did for the other systems.
+</li>
+
+<li>
+The <a href="/pkg/runtime/"><code>runtime</code></a> package's
+<a href="/pkg/runtime/#MemStats.Mallocs"><code>Mallocs</code></a> counter
+now counts very small allocations that were missed in Go 1.3.
+This may break tests using <a href="/pkg/runtime/#ReadMemStats"><code>ReadMemStats</code></a>
+or <a href="/pkg/testing/#AllocsPerRun"><code>AllocsPerRun</code></a>
+due to the more accurate answer.
+</li>
+
+<li>
+In the <a href="/pkg/runtime/"><code>runtime</code></a> package,
+an array <a href="/pkg/runtime/#MemStats.PauseEnd"><code>PauseEnd</code></a>
+has been added to the
+<a href="/pkg/runtime/#MemStats"><code>MemStats</code></a>
+and <a href="/pkg/runtime/#GCStats"><code>GCStats</code></a> structs.
+This array is a circular buffer of times when garbage collection pauses ended.
+The corresponding pause durations are already recorded in
+<a href="/pkg/runtime/#MemStats.PauseNs"><code>PauseNs</code></a>
+</li>
+
+<li>
+The <a href="/pkg/runtime/race/"><code>runtime/race</code></a> package
+now supports FreeBSD, which means the
+<a href="/pkg/cmd/go/"><code>go</code></a> command's <code>-race</code>
+flag now works on FreeBSD.
+</li>
+
+<li>
+The <a href="/pkg/sync/atomic/"><code>sync/atomic</code></a> package
+has a new type, <a href="/pkg/sync/atomic/#Value"><code>Value</code></a>.
+<code>Value</code> provides an efficient mechanism for atomic loads and
+stores of values of arbitrary type.
+</li>
+
+<li>
+In the <a href="/pkg/syscall/"><code>syscall</code></a> package's
+implementation on Linux, the
+<a href="/pkg/syscall/#Setuid"><code>Setuid</code></a>
+and <a href="/pkg/syscall/#Setgid"><code>Setgid</code></a> have been disabled
+because those system calls operate on the calling thread, not the whole process, which is
+different from other platforms and not the expected result.
+</li>
+
+<li>
+The <a href="/pkg/testing/"><code>testing</code></a> package
+has a new facility to provide more control over running a set of tests.
+If the test code contains a function
+<pre>
+func TestMain(m *<a href="/pkg/testing/#M"><code>testing.M</code></a>) 
+</pre>
+
+that function will be called instead of running the tests directly.
+The <code>M</code> struct contains methods to access and run the tests.
+</li>
+
+<li>
+Also in the <a href="/pkg/testing/"><code>testing</code></a> package,
+a new <a href="/pkg/testing/#Coverage"><code>Coverage</code></a>
+function reports the current test coverage fraction,
+enabling individual tests to report how much they are contributing to the
+overall coverage.
+</li>
+
+<li>
+The <a href="/pkg/text/scanner/"><code>text/scanner</code></a> package's
+<a href="/pkg/text/scanner/#Scanner"><code>Scanner</code></a> type
+has a new function,
+<a href="/pkg/text/scanner/#Scanner.IsIdentRune"><code>IsIdentRune</code></a>,
+allowing one to control the definition of an identifier when scanning.
+</li>
+
+<li>
+The <a href="/pkg/text/template/"><code>text/template</code></a> package's boolean
+functions <code>eq</code>, <code>lt</code>, and so on have been generalized to allow comparison
+of signed and unsigned integers, simplifying their use in practice.
+(Previously one could only compare values of the same signedness.)
+All negative values compare less than all unsigned values.
+</li>
+
+<li>
+The <code>time</code> package now uses the standard symbol for the micro prefix,
+the micro symbol (U+00B5 'µ'), to print microsecond durations.
+<a href="/pkg/time/#ParseDuration"><code>ParseDuration</code></a> still accepts <code>us</code>
+but the package no longer prints microseconds as <code>us</code>.
+<br>
+<em>Updating</em>: Code that depends on the output format of durations
+but does not use ParseDuration will need to be updated.
+</li>
+
+</ul>
diff --git a/doc/go1.html b/doc/go1.html
index 5cf5df9..1665d74 100644
--- a/doc/go1.html
+++ b/doc/go1.html
@@ -2035,4 +2035,4 @@ They are available for many combinations of architecture and operating system
 Installation details are described on the
 <a href="/doc/install">Getting Started</a> page, while
 the distributions themselves are listed on the
-<a href="/dl/">downloads page</a>.
+<a href="https://golang.org/dl/">downloads page</a>.
diff --git a/doc/go1compat.html b/doc/go1compat.html
index d10b9af..d800dec 100644
--- a/doc/go1compat.html
+++ b/doc/go1compat.html
@@ -83,16 +83,16 @@ break if the bug is fixed. We reserve the right to fix such bugs.
 <li>
 Struct literals. For the addition of features in later point
 releases, it may be necessary to add fields to exported structs in
-the API. Code that uses untagged struct literals (such as pkg.T{3,
+the API. Code that uses unkeyed struct literals (such as pkg.T{3,
 "x"}) to create values of these types would fail to compile after
-such a change. However, code that uses tagged literals (pkg.T{A:
+such a change. However, code that uses keyed literals (pkg.T{A:
 3, B: "x"}) will continue to compile after such a change. We will
-update such data structures in a way that allows tagged struct
-literals to remain compatible, although untagged literals may fail
+update such data structures in a way that allows keyed struct
+literals to remain compatible, although unkeyed literals may fail
 to compile. (There are also more intricate cases involving nested
 data structures or interfaces, but they have the same resolution.)
 We therefore recommend that composite literals whose type is defined
-in a separate package should use the tagged notation.
+in a separate package should use the keyed notation.
 </li>
 
 <li>
@@ -104,6 +104,14 @@ outside of tests, and using it may cause a program to fail
 to compile in future releases.
 </li>
 
+<li>
+Use of package <code>unsafe</code>. Packages that import
+<a href="/pkg/unsafe/"><code>unsafe</code></a>
+may depend on internal properties of the Go implementation.
+We reserve the right to make changes to the implementation
+that may break such programs.
+</li>
+
 </ul>
 
 <p>
@@ -145,13 +153,28 @@ developed software based on Go 1.
 
 <p>
 Code in sub-repositories of the main go tree, such as
-<a href="//code.google.com/p/go.net">code.google.com/p/go.net</a>,
+<a href="//golang.org/x/net">golang.org/x/net</a>,
 may be developed under
 looser compatibility requirements. However, the sub-repositories
 will be tagged as appropriate to identify versions that are compatible
 with the Go 1 point releases.
 </p>
 
+<h2 id="operating_systems">Operating systems</h2>
+
+<p>
+It is impossible to guarantee long-term compatibility with operating
+system interfaces, which are changed by outside parties.
+The <a href="/pkg/syscall/"><code>syscall</code></a> package
+is therefore outside the purview of the guarantees made here.
+As of Go version 1.4, the <code>syscall</code> package is frozen.
+Any evolution of the system call interface must be supported elsewhere,
+such as in the
+<a href="//golang.org/x/sys">go.sys</a> subrepository.
+For details and background, see
+<a href="//golang.org/s/go1.4-syscall">this document</a>.
+</p>
+
 <h2 id="tools">Tools</h2>
 
 <p>
diff --git a/doc/go_faq.html b/doc/go_faq.html
index f2082ef..6b77f1c 100644
--- a/doc/go_faq.html
+++ b/doc/go_faq.html
@@ -228,7 +228,7 @@ document server running in a production configuration on
 </p>
 
 <p>
-Other examples include the <a href="https://code.google.com/p/vitess/">Vitess</a>
+Other examples include the <a href="//code.google.com/p/vitess/">Vitess</a>
 system for large-scale SQL installations and Google's download server, <code>dl.google.com</code>,
 which delivers Chrome binaries and other large installables such as <code>apt-get</code>
 packages.
@@ -889,6 +889,11 @@ type is generic; if you care about how many bits an integer holds, Go
 encourages you to be explicit.
 </p>
 
+<p>
+A blog post, title <a href="http://blog.golang.org/constants">Constants</a>,
+explores this topic in more detail.
+</p>
+
 <h3 id="builtin_maps">
 Why are maps built in?</h3>
 <p>
@@ -971,7 +976,7 @@ It is a handy reference for people doing code reviews for Go projects.
 How do I submit patches to the Go libraries?</h3>
 
 <p>
-The library sources are in <code>go/src/pkg</code>.
+The library sources are in the <code>src</code> directory of the repository.
 If you want to make a significant change, please discuss on the mailing list before embarking.
 </p>
 
@@ -981,32 +986,6 @@ See the document
 for more information about how to proceed.
 </p>
 
-<h3 id="Why_does_the_project_use_Mercurial_and_not_git">
-Why does the project use Mercurial and not git?</h3>
-
-<p>
-The Go project, hosted by Google Code at
-<a href="//code.google.com/p/go">code.google.com/p/go</a>,
-uses Mercurial as its version control system.
-When the project launched,
-Google Code supported only Subversion and Mercurial.
-Mercurial was a better choice because of its plugin mechanism
-that allowed us to create the "codereview" plugin to connect
-the project to the excellent code review tools at
-<a href="//codereview.appspot.com">codereview.appspot.com</a>.
-</p>
-
-<p>
-Programmers who work
-with the Go project's source rather than release downloads sometimes
-ask for the project to switch to git.
-That would be possible, but it would be a lot of work and
-would also require reimplementing the codereview plugin.
-Given that Mercurial works today, with code review support,
-combined with the Go project's mostly linear, non-branching use of
-version control, a switch to git doesn't seem worthwhile.
-</p>
-
 <h3 id="git_https">
 Why does "go get" use HTTPS when cloning a repository?</h3>
 
@@ -1110,7 +1089,7 @@ error but the situation can still be confusing, because sometimes a
 <a href="#different_method_sets">pointer
 is necessary to satisfy an interface</a>.
 The insight is that although a pointer to a concrete type can satisfy
-an interface, with one exception <em>a pointer to an interface can never satisfy a interface</em>.
+an interface, with one exception <em>a pointer to an interface can never satisfy an interface</em>.
 </p>
 
 <p>
@@ -1351,7 +1330,7 @@ to speed it up.
 </p>
 
 <p>
-Go's goroutine scheduler is not as good as it needs to be. In future, it
+Go's goroutine scheduler is not as good as it needs to be. In the future, it
 should recognize such cases and optimize its use of OS threads. For now,
 <code>GOMAXPROCS</code> should be set on a per-application basis.
 </p>
@@ -1571,7 +1550,7 @@ table-driven, iterating over a list of inputs and outputs defined
 in a data structure (Go has excellent support for data structure literals).
 The work to write a good test and good error messages will then be amortized over many
 test cases. The standard Go library is full of illustrative examples, such as in
-<a href="/src/pkg/fmt/fmt_test.go">the formatting tests for the <code>fmt</code> package</a>.
+<a href="/src/fmt/fmt_test.go">the formatting tests for the <code>fmt</code> package</a>.
 </p>
 
 
@@ -1590,30 +1569,40 @@ and uses a variant of the Plan 9 loader to generate ELF/Mach-O/PE binaries.
 </p>
 
 <p>
-We considered writing <code>gc</code>, the original Go compiler, in Go itself but
+We considered using LLVM for <code>gc</code> but we felt it was too large and
+slow to meet our performance goals.
+</p>
+
+<p>
+We also considered writing <code>gc</code>, the original Go compiler, in Go itself but
 elected not to do so because of the difficulties of bootstrapping and
 especially of open source distribution—you'd need a Go compiler to
 set up a Go environment. <code>Gccgo</code>, which came later, makes it possible to
-consider writing a compiler in Go, which might well happen.
-(Go would be a
-fine language in which to implement a compiler; a native lexer and
-parser are already available in the <a href="/pkg/go/"><code>go</code></a> package
-and a type checker is in the works.)
+consider writing a compiler in Go.
+A plan to do that by machine translation of the existing compiler is under development.
+<a href="http://golang.org/s/go13compiler">A separate document</a>
+explains the reason for this approach.
 </p>
 
 <p>
-We also considered using LLVM for <code>gc</code> but we felt it was too large and
-slow to meet our performance goals.
+That plan aside,
+Go is a
+fine language in which to implement a self-hosting compiler: a native lexer and
+parser are already available in the <a href="/pkg/go/"><code>go</code></a> package
+and a separate type checking
+<a href="http://godoc.org/golang.org/x/tools/go/types">package</a>
+has also been written.
 </p>
 
 <h3 id="How_is_the_run_time_support_implemented">
 How is the run-time support implemented?</h3>
 
 <p>
-Again due to bootstrapping issues, the run-time code is mostly in C (with a
-tiny bit of assembler) although Go is capable of implementing most of
-it now. <code>Gccgo</code>'s run-time support uses <code>glibc</code>.
-<code>Gc</code> uses a custom library to keep the footprint under
+Again due to bootstrapping issues, the run-time code was originally written mostly in C (with a
+tiny bit of assembler) although much of it has been translated to Go since then
+and one day all of it might be (except for the assembler bits).
+<code>Gccgo</code>'s run-time support uses <code>glibc</code>.
+<code>Gc</code> uses a custom C library to keep the footprint under
 control; it is
 compiled with a version of the Plan 9 C compiler that supports
 resizable stacks for goroutines.
@@ -1637,8 +1626,8 @@ A simple C "hello, world" program compiled and linked statically using gcc
 on Linux is around 750 kB,
 including an implementation of <code>printf</code>.
 An equivalent Go program using <code>fmt.Printf</code>
-is around 1.2 MB, but
-that includes more powerful run-time support.
+is around 1.9 MB, but
+that includes more powerful run-time support and type information.
 </p>
 
 <h3 id="unused_variables_and_imports">
@@ -1646,14 +1635,17 @@ Can I stop these complaints about my unused variable/import?</h3>
 
 <p>
 The presence of an unused variable may indicate a bug, while
-unused imports just slow down compilation.
-Accumulate enough unused imports in your code tree and
-things can get very slow.
-For these reasons, Go allows neither.
+unused imports just slow down compilation,
+an effect that can become substantial as a program accumulates
+code and programmers over time.
+For these reasons, Go refuses to compile programs with unused
+variables or imports,
+trading short-term convenience for long-term build speed and
+program clarity.
 </p>
 
 <p>
-When developing code, it's common to create these situations
+Still, when developing code, it's common to create these situations
 temporarily and it can be annoying to have to edit them out before the
 program will compile.
 </p>
@@ -1695,6 +1687,14 @@ func main() {
 }
 </pre>
 
+<p>
+Nowadays, most Go programmers use a tool,
+<a href="http://godoc.org/golang.org/x/tools/cmd/goimports">goimports</a>,
+which automatically rewrites a Go source file to have the correct imports,
+eliminating the unused imports issue in practice.
+This program is easily connected to most editors to run automatically when a Go source file is written.
+</p>
+
 <h2 id="Performance">Performance</h2>
 
 <h3 id="Why_does_Go_perform_badly_on_benchmark_x">
diff --git a/doc/go_mem.html b/doc/go_mem.html
index 2ea1ded..5dd48ff 100644
--- a/doc/go_mem.html
+++ b/doc/go_mem.html
@@ -21,6 +21,29 @@ reads of a variable in one goroutine can be guaranteed to
 observe values produced by writes to the same variable in a different goroutine.
 </p>
 
+
+<h2>Advice</h2>
+
+<p>
+Programs that modify data being simultaneously accessed by multiple goroutines
+must serialize such access.
+</p>
+
+<p>
+To serialize access, protect the data with channel operations or other synchronization primitives
+such as those in the <a href="/pkg/sync/"><code>sync</code></a>
+and <a href="/pkg/sync/atomic/"><code>sync/atomic</code></a> packages.
+</p>
+
+<p>
+If you must read the rest of this document to understand the behavior of your program,
+you are being too clever.
+</p>
+
+<p>
+Don't be clever.
+</p>
+
 <h2>Happens Before</h2>
 
 <p>
diff --git a/doc/go_spec.html b/doc/go_spec.html
index 660c853..ca0deb5 100644
--- a/doc/go_spec.html
+++ b/doc/go_spec.html
@@ -1,6 +1,6 @@
 <!--{
 	"Title": "The Go Programming Language Specification",
-	"Subtitle": "Version of May 28, 2014",
+	"Subtitle": "Version of November 11, 2014",
 	"Path": "/ref/spec"
 }-->
 
@@ -479,7 +479,7 @@ Interpreted string literals are character sequences between double
 quotes <code>""</code>. The text between the quotes,
 which may not contain newlines, forms the
 value of the literal, with backslash escapes interpreted as they
-are in rune literals (except that <code>\'</code> is illegal and
+are in <a href="#Rune_literals">rune literals</a> (except that <code>\'</code> is illegal and
 <code>\"</code> is legal), with the same restrictions.
 The three-digit octal (<code>\</code><i>nnn</i>)
 and two-digit hexadecimal (<code>\x</code><i>nn</i>) escapes represent individual
@@ -577,7 +577,7 @@ Numeric constants represent values of arbitrary precision and do not overflow.
 </p>
 
 <p>
-Constants may be <a href="#Types">typed</a> or untyped.
+Constants may be <a href="#Types">typed</a> or <i>untyped</i>.
 Literal constants, <code>true</code>, <code>false</code>, <code>iota</code>,
 and certain <a href="#Constant_expressions">constant expressions</a>
 containing only untyped constant operands are untyped.
@@ -598,6 +598,17 @@ not <code>int32</code> or <code>string</code>.
 </p>
 
 <p>
+An untyped constant has a <i>default type</i> which is the type to which the
+constant is implicitly converted in contexts where a typed value is required,
+for instance, in a <a href="#Short_variable_declarations">short variable declaration</a>
+such as <code>i := 0</code> where there is no explicit type.
+The default type of an untyped constant is <code>bool</code>, <code>rune</code>,
+<code>int</code>, <code>float64</code>, <code>complex128</code> or <code>string</code>
+respectively, depending on whether it is a boolean, rune, integer, floating-point,
+complex, or string constant.
+</p>
+
+<p>
 There are no constants denoting the IEEE-754 infinity and not-a-number values,
 but the <a href="/pkg/math/"><code>math</code> package</a>'s
 <a href="/pkg/math/#Inf">Inf</a>,
@@ -636,6 +647,65 @@ of evaluating <a href="#Constant_expressions">constant
 expressions</a>.
 </p>
 
+<h2 id="Variables">Variables</h2>
+
+<p>
+A variable is a storage location for holding a <i>value</i>.
+The set of permissible values is determined by the
+variable's <i><a href="#Types">type</a></i>.
+</p>
+
+<p>
+A <a href="#Variable_declarations">variable declaration</a>
+or, for function parameters and results, the signature
+of a <a href="#Function_declarations">function declaration</a>
+or <a href="#Function_literals">function literal</a> reserves
+storage for a named variable.
+
+Calling the built-in function <a href="#Allocation"><code>new</code></a>
+or taking the address of a <a href="#Composite_literals">composite literal</a>
+allocates storage for a variable at run time.
+Such an anonymous variable is referred to via a (possibly implicit)
+<a href="#Address_operators">pointer indirection</a>.
+</p>
+
+<p>
+<i>Structured</i> variables of <a href="#Array_types">array</a>, <a href="#Slice_types">slice</a>,
+and <a href="#Struct_types">struct</a> types have elements and fields that may
+be <a href="#Address_operators">addressed</a> individually. Each such element
+acts like a variable.
+</p>
+
+<p>
+The <i>static type</i> (or just <i>type</i>) of a variable is the	
+type given in its declaration, the type provided in the
+<code>new</code> call or composite literal, or the type of
+an element of a structured variable.
+Variables of interface type also have a distinct <i>dynamic type</i>,
+which is the concrete type of the value assigned to the variable at run time
+(unless the value is the predeclared identifier <code>nil</code>,
+which has no type).
+The dynamic type may vary during execution but values stored in interface
+variables are always <a href="#Assignability">assignable</a>
+to the static type of the variable.	
+</p>	
+
+<pre>
+var x interface{}  // x is nil and has static type interface{}
+var v *T           // v has value nil, static type *T
+x = 42             // x has value 42 and dynamic type int
+x = v              // x has value (*T)(nil) and dynamic type *T
+</pre>
+
+<p>
+A variable's value is retrieved by referring to the variable in an
+<a href="#Expressions">expression</a>; it is the most recent value
+<a href="#Assignments">assigned</a> to the variable.
+If a variable has not yet been assigned a value, its value is the
+<a href="#The_zero_value">zero value</a> for its type.
+</p>
+
+
 <h2 id="Types">Types</h2>
 
 <p>
@@ -662,17 +732,6 @@ type literals.
 </p>
 
 <p>
-The <i>static type</i> (or just <i>type</i>) of a variable is the
-type defined by its declaration.  Variables of interface type
-also have a distinct <i>dynamic type</i>, which
-is the actual type of the value stored in the variable at run time.
-The dynamic type may vary during execution but is always
-<a href="#Assignability">assignable</a>
-to the static type of the interface variable.  For non-interface
-types, the dynamic type is always the static type.
-</p>
-
-<p>
 Each type <code>T</code> has an <i>underlying type</i>: If <code>T</code>
 is one of the predeclared boolean, numeric, or string types, or a type literal,
 the corresponding underlying
@@ -1027,14 +1086,14 @@ struct {
 <h3 id="Pointer_types">Pointer types</h3>
 
 <p>
-A pointer type denotes the set of all pointers to variables of a given
+A pointer type denotes the set of all pointers to <a href="#Variables">variables</a> of a given
 type, called the <i>base type</i> of the pointer.
 The value of an uninitialized pointer is <code>nil</code>.
 </p>
 
 <pre class="ebnf">
 PointerType = "*" BaseType .
-BaseType = Type .
+BaseType    = Type .
 </pre>
 
 <pre>
@@ -1154,11 +1213,11 @@ interface{}
 <p>
 Similarly, consider this interface specification,
 which appears within a <a href="#Type_declarations">type declaration</a>
-to define an interface called <code>Lock</code>:
+to define an interface called <code>Locker</code>:
 </p>
 
 <pre>
-type Lock interface {
+type Locker interface {
 	Lock()
 	Unlock()
 }
@@ -1174,28 +1233,35 @@ func (p T) Unlock() { … }
 </pre>
 
 <p>
-they implement the <code>Lock</code> interface as well
+they implement the <code>Locker</code> interface as well
 as the <code>File</code> interface.
 </p>
+
 <p>
-An interface may use an interface type name <code>T</code>
-in place of a method specification.
-The effect, called embedding an interface,
-is equivalent to enumerating the methods of <code>T</code> explicitly
-in the interface.
+An interface <code>T</code> may use a (possibly qualified) interface type
+name <code>E</code> in place of a method specification. This is called
+<i>embedding</i> interface <code>E</code> in <code>T</code>; it adds
+all (exported and non-exported) methods of <code>E</code> to the interface
+<code>T</code>.
 </p>
 
 <pre>
-type ReadWrite interface {
+type ReadWriter interface {
 	Read(b Buffer) bool
 	Write(b Buffer) bool
 }
 
 type File interface {
-	ReadWrite  // same as enumerating the methods in ReadWrite
-	Lock       // same as enumerating the methods in Lock
+	ReadWriter  // same as adding the methods of ReadWriter
+	Locker      // same as adding the methods of Locker
 	Close()
 }
+
+type LockedFile interface {
+	Locker
+	File        // illegal: Lock, Unlock not unique
+	Lock()      // illegal: Lock not unique
+}
 </pre>
 
 <p>
@@ -1443,7 +1509,7 @@ is different from <code>[]string</code>.
 <h3 id="Assignability">Assignability</h3>
 
 <p>
-A value <code>x</code> is <i>assignable</i> to a variable of type <code>T</code>
+A value <code>x</code> is <i>assignable</i> to a <a href="#Variables">variable</a> of type <code>T</code>
 ("<code>x</code> is assignable to <code>T</code>") in any of these cases:
 </p>
 
@@ -1875,9 +1941,10 @@ func (tz TimeZone) String() string {
 <h3 id="Variable_declarations">Variable declarations</h3>
 
 <p>
-A variable declaration creates a variable, binds an identifier to it and
-gives it a type and optionally an initial value.
+A variable declaration creates one or more variables, binds corresponding
+identifiers to them, and gives each a type and an initial value.
 </p>
+
 <pre class="ebnf">
 VarDecl     = "var" ( VarSpec | "(" { VarSpec ";" } ")" ) .
 VarSpec     = IdentifierList ( Type [ "=" ExpressionList ] | "=" ExpressionList ) .
@@ -1898,22 +1965,27 @@ var _, found = entries[name]  // map lookup; only interested in "found"
 
 <p>
 If a list of expressions is given, the variables are initialized
-by <a href="#Assignments">assigning</a> the expressions to the variables
-in order; all expressions must be consumed and all variables initialized from them.
+with the expressions following the rules for <a href="#Assignments">assignments</a>.
 Otherwise, each variable is initialized to its <a href="#The_zero_value">zero value</a>.
 </p>
 
 <p>
-If the type is present, each variable is given that type.
-Otherwise, the types are deduced from the assignment
-of the expression list.
+If a type is present, each variable is given that type.
+Otherwise, each variable is given the type of the corresponding
+initialization value in the assignment.
+If that value is an untyped constant, it is first
+<a href="#Conversions">converted</a> to its <a href="#Constants">default type</a>;
+if it is an untyped boolean value, it is first converted to type <code>bool</code>.
+The predeclared value <code>nil</code> cannot be used to initialize a variable
+with no explicit type.
 </p>
 
-<p>
-If the type is absent and the corresponding expression evaluates to an
-untyped <a href="#Constants">constant</a>, the type of the declared variable
-is as described in §<a href="#Assignments">Assignments</a>.
-</p>
+<pre>
+var d = math.Sin(0.5)  // d is int64
+var i = 42             // i is int
+var t, ok = x.(T)      // t is T, ok is bool
+var n = nil            // illegal
+</pre>
 
 <p>
 Implementation restriction: A compiler may make it illegal to declare a variable
@@ -2029,13 +2101,14 @@ and associates the method with the receiver's <i>base type</i>.
 
 <pre class="ebnf">
 MethodDecl   = "func" Receiver MethodName ( Function | Signature ) .
-Receiver     = "(" [ identifier ] [ "*" ] BaseTypeName ")" .
-BaseTypeName = identifier .
+Receiver     = Parameters .
 </pre>
 
 <p>
-The receiver type must be of the form <code>T</code> or <code>*T</code> where
-<code>T</code> is a type name. The type denoted by <code>T</code> is called
+The receiver is specified via an extra parameter section preceeding the method
+name. That parameter section must declare a single parameter, the receiver.
+Its type must be of the form <code>T</code> or <code>*T</code> (possibly using
+parentheses) where <code>T</code> is a type name. The type denoted by <code>T</code> is called
 the receiver <i>base type</i>; it must not be a pointer or interface type and
 it must be declared in the same package as the method.
 The method is said to be <i>bound</i> to the base type and the method name
@@ -2117,9 +2190,9 @@ operand only on the left-hand side of an <a href="#Assignments">assignment</a>.
 </p>
 
 <pre class="ebnf">
-Operand    = Literal | OperandName | MethodExpr | "(" Expression ")" .
-Literal    = BasicLit | CompositeLit | FunctionLit .
-BasicLit   = int_lit | float_lit | imaginary_lit | rune_lit | string_lit .
+Operand     = Literal | OperandName | MethodExpr | "(" Expression ")" .
+Literal     = BasicLit | CompositeLit | FunctionLit .
+BasicLit    = int_lit | float_lit | imaginary_lit | rune_lit | string_lit .
 OperandName = identifier | QualifiedIdent.
 </pre>
 
@@ -2241,7 +2314,8 @@ For array and slice literals the following rules apply:
 
 <p>
 <a href="#Address_operators">Taking the address</a> of a composite literal
-generates a pointer to a unique instance of the literal's value.
+generates a pointer to a unique <a href="#Variables">variable</a> initialized
+with the literal's value.
 </p>
 <pre>
 var pointer *Point3D = &Point3D{y: 1000}
@@ -2375,12 +2449,11 @@ Primary expressions are the operands for unary and binary expressions.
 PrimaryExpr =
 	Operand |
 	Conversion |
-	BuiltinCall |
 	PrimaryExpr Selector |
 	PrimaryExpr Index |
 	PrimaryExpr Slice |
 	PrimaryExpr TypeAssertion |
-	PrimaryExpr Call .
+	PrimaryExpr Arguments .
 
 Selector       = "." identifier .
 Index          = "[" Expression "]" .
@@ -2388,8 +2461,7 @@ Slice          = "[" ( [ Expression ] ":" [ Expression ] ) |
                      ( [ Expression ] ":" Expression ":" Expression )
                  "]" .
 TypeAssertion  = "." "(" Type ")" .
-Call           = "(" [ ArgumentList [ "," ] ] ")" .
-ArgumentList   = ExpressionList [ "..." ] .
+Arguments      = "(" [ ( ExpressionList | Type [ "," ExpressionList ] ) [ "..." ] [ "," ] ] ")" .
 </pre>
 
 
@@ -2449,30 +2521,40 @@ The following rules apply to selectors:
 <ol>
 <li>
 For a value <code>x</code> of type <code>T</code> or <code>*T</code>
-where <code>T</code> is not an interface type,
+where <code>T</code> is not a pointer or interface type,
 <code>x.f</code> denotes the field or method at the shallowest depth
 in <code>T</code> where there
 is such an <code>f</code>.
 If there is not exactly <a href="#Uniqueness_of_identifiers">one <code>f</code></a>
 with shallowest depth, the selector expression is illegal.
 </li>
+
 <li>
-For a variable <code>x</code> of type <code>I</code> where <code>I</code>
+For a value <code>x</code> of type <code>I</code> where <code>I</code>
 is an interface type, <code>x.f</code> denotes the actual method with name
-<code>f</code> of the value assigned to <code>x</code>.
+<code>f</code> of the dynamic value of <code>x</code>.
 If there is no method with name <code>f</code> in the
 <a href="#Method_sets">method set</a> of <code>I</code>, the selector
 expression is illegal.
 </li>
+
+<li>
+As an exception, if the type of <code>x</code> is a named pointer type
+and <code>(*x).f</code> is a valid selector expression denoting a field
+(but not a method), <code>x.f</code> is shorthand for <code>(*x).f</code>.
+</li>
+
 <li>
 In all other cases, <code>x.f</code> is illegal.
 </li>
+
 <li>
 If <code>x</code> is of pointer type and has the value
 <code>nil</code> and <code>x.f</code> denotes a struct field,
 assigning to or evaluating <code>x.f</code>
 causes a <a href="#Run_time_panics">run-time panic</a>.
 </li>
+
 <li>
 If <code>x</code> is of interface type and has the value
 <code>nil</code>, <a href="#Calls">calling</a> or
@@ -2482,18 +2564,6 @@ causes a <a href="#Run_time_panics">run-time panic</a>.
 </ol>
 
 <p>
-Selectors automatically <a href="#Address_operators">dereference</a>
-pointers to structs.
-If <code>x</code> is a pointer to a struct, <code>x.y</code>
-is shorthand for <code>(*x).y</code>; if the field <code>y</code>
-is also a pointer to a struct, <code>x.y.z</code> is shorthand
-for <code>(*(*x).y).z</code>, and so on.
-If <code>x</code> contains an anonymous field of type <code>*A</code>,
-where <code>A</code> is also a struct type,
-<code>x.f</code> is shorthand for <code>(*x.A).f</code>.
-</p>
-
-<p>
 For example, given the declarations:
 </p>
 
@@ -2502,13 +2572,13 @@ type T0 struct {
 	x int
 }
 
-func (recv *T0) M0()
+func (*T0) M0()
 
 type T1 struct {
 	y int
 }
 
-func (recv T1) M1()
+func (T1) M1()
 
 type T2 struct {
 	z int
@@ -2516,9 +2586,13 @@ type T2 struct {
 	*T0
 }
 
-func (recv *T2) M2()
+func (*T2) M2()
 
-var p *T2  // with p != nil and p.T0 != nil
+type Q *T2
+
+var t T2     // with t.T0 != nil
+var p *T2    // with p != nil and (*p).T0 != nil
+var q Q = p
 </pre>
 
 <p>
@@ -2526,13 +2600,254 @@ one may write:
 </p>
 
 <pre>
-p.z   // (*p).z
-p.y   // ((*p).T1).y
-p.x   // (*(*p).T0).x
+t.z          // t.z
+t.y          // t.T1.y
+t.x          // (*t.TO).x
+
+p.z          // (*p).z
+p.y          // (*p).T1.y
+p.x          // (*(*p).T0).x
+
+q.x          // (*(*q).T0).x        (*q).x is a valid field selector
+
+p.M2()       // p.M2()              M2 expects *T2 receiver
+p.M1()       // ((*p).T1).M1()      M1 expects T1 receiver
+p.M0()       // ((&(*p).T0)).M0()   M0 expects *T0 receiver, see section on Calls
+</pre>
+
+<p>
+but the following is invalid:
+</p>
+
+<pre>
+q.M0()       // (*q).M0 is valid but not a field selector
+</pre>
+
+
+<h3 id="Method_expressions">Method expressions</h3>
+
+<p>
+If <code>M</code> is in the <a href="#Method_sets">method set</a> of type <code>T</code>,
+<code>T.M</code> is a function that is callable as a regular function
+with the same arguments as <code>M</code> prefixed by an additional
+argument that is the receiver of the method.
+</p>
+
+<pre class="ebnf">
+MethodExpr    = ReceiverType "." MethodName .
+ReceiverType  = TypeName | "(" "*" TypeName ")" | "(" ReceiverType ")" .
+</pre>
+
+<p>
+Consider a struct type <code>T</code> with two methods,
+<code>Mv</code>, whose receiver is of type <code>T</code>, and
+<code>Mp</code>, whose receiver is of type <code>*T</code>.
+</p>
+
+<pre>
+type T struct {
+	a int
+}
+func (tv  T) Mv(a int) int         { return 0 }  // value receiver
+func (tp *T) Mp(f float32) float32 { return 1 }  // pointer receiver
+
+var t T
+</pre>
+
+<p>
+The expression
+</p>
+
+<pre>
+T.Mv
+</pre>
+
+<p>
+yields a function equivalent to <code>Mv</code> but
+with an explicit receiver as its first argument; it has signature
+</p>
+
+<pre>
+func(tv T, a int) int
+</pre>
+
+<p>
+That function may be called normally with an explicit receiver, so
+these five invocations are equivalent:
+</p>
+
+<pre>
+t.Mv(7)
+T.Mv(t, 7)
+(T).Mv(t, 7)
+f1 := T.Mv; f1(t, 7)
+f2 := (T).Mv; f2(t, 7)
+</pre>
+
+<p>
+Similarly, the expression
+</p>
+
+<pre>
+(*T).Mp
+</pre>
+
+<p>
+yields a function value representing <code>Mp</code> with signature
+</p>
+
+<pre>
+func(tp *T, f float32) float32
+</pre>
+
+<p>
+For a method with a value receiver, one can derive a function
+with an explicit pointer receiver, so
+</p>
+
+<pre>
+(*T).Mv
+</pre>
+
+<p>
+yields a function value representing <code>Mv</code> with signature
+</p>
+
+<pre>
+func(tv *T, a int) int
+</pre>
+
+<p>
+Such a function indirects through the receiver to create a value
+to pass as the receiver to the underlying method;
+the method does not overwrite the value whose address is passed in
+the function call.
+</p>
+
+<p>
+The final case, a value-receiver function for a pointer-receiver method,
+is illegal because pointer-receiver methods are not in the method set
+of the value type.
+</p>
+
+<p>
+Function values derived from methods are called with function call syntax;
+the receiver is provided as the first argument to the call.
+That is, given <code>f := T.Mv</code>, <code>f</code> is invoked
+as <code>f(t, 7)</code> not <code>t.f(7)</code>.
+To construct a function that binds the receiver, use a
+<a href="#Function_literals">function literal</a> or
+<a href="#Method_values">method value</a>.
+</p>
+
+<p>
+It is legal to derive a function value from a method of an interface type.
+The resulting function takes an explicit receiver of that interface type.
+</p>
+
+<h3 id="Method_values">Method values</h3>
+
+<p>
+If the expression <code>x</code> has static type <code>T</code> and
+<code>M</code> is in the <a href="#Method_sets">method set</a> of type <code>T</code>,
+<code>x.M</code> is called a <i>method value</i>.
+The method value <code>x.M</code> is a function value that is callable
+with the same arguments as a method call of <code>x.M</code>.
+The expression <code>x</code> is evaluated and saved during the evaluation of the
+method value; the saved copy is then used as the receiver in any calls,
+which may be executed later.
+</p>
+
+<p>
+The type <code>T</code> may be an interface or non-interface type.
+</p>
+
+<p>
+As in the discussion of <a href="#Method_expressions">method expressions</a> above,
+consider a struct type <code>T</code> with two methods,
+<code>Mv</code>, whose receiver is of type <code>T</code>, and
+<code>Mp</code>, whose receiver is of type <code>*T</code>.
+</p>
+
+<pre>
+type T struct {
+	a int
+}
+func (tv  T) Mv(a int) int         { return 0 }  // value receiver
+func (tp *T) Mp(f float32) float32 { return 1 }  // pointer receiver
+
+var t T
+var pt *T
+func makeT() T
+</pre>
+
+<p>
+The expression
+</p>
+
+<pre>
+t.Mv
+</pre>
+
+<p>
+yields a function value of type
+</p>
+
+<pre>
+func(int) int
+</pre>
+
+<p>
+These two invocations are equivalent:
+</p>
+
+<pre>
+t.Mv(7)
+f := t.Mv; f(7)
+</pre>
+
+<p>
+Similarly, the expression
+</p>
+
+<pre>
+pt.Mp
+</pre>
+
+<p>
+yields a function value of type
+</p>
+
+<pre>
+func(float32) float32
+</pre>
 
-p.M2()  // (*p).M2()
-p.M1()  // ((*p).T1).M1()
-p.M0()  // ((*p).T0).M0()
+<p>
+As with <a href="#Selectors">selectors</a>, a reference to a non-interface method with a value receiver
+using a pointer will automatically dereference that pointer: <code>pt.Mv</code> is equivalent to <code>(*pt).Mv</code>.
+</p>
+
+<p>
+As with <a href="#Calls">method calls</a>, a reference to a non-interface method with a pointer receiver
+using an addressable value will automatically take the address of that value: <code>t.Mp</code> is equivalent to <code>(&t).Mp</code>.
+</p>
+
+<pre>
+f := t.Mv; f(7)   // like t.Mv(7)
+f := pt.Mp; f(7)  // like pt.Mp(7)
+f := pt.Mv; f(7)  // like (*pt).Mv(7)
+f := t.Mp; f(7)   // like (&t).Mp(7)
+f := makeT().Mp   // invalid: result of makeT() is not addressable
+</pre>
+
+<p>
+Although the examples above use non-interface types, it is also legal to create a method value
+from a value of interface type.
+</p>
+
+<pre>
+var i interface { M(int) } = myVal
+f := i.M; f(7)  // like i.M(7)
 </pre>
 
 
@@ -2625,7 +2940,7 @@ Otherwise <code>a[x]</code> is illegal.
 
 <p>
 An index expression on a map <code>a</code> of type <code>map[K]V</code>
-may be used in an assignment or initialization of the special form
+used in an <a href="#Assignments">assignment</a> or initialization of the special form
 </p>
 
 <pre>
@@ -2635,11 +2950,9 @@ var v, ok = a[x]
 </pre>
 
 <p>
-where the result of the index expression is a pair of values with types
-<code>(V, bool)</code>. In this form, the value of <code>ok</code> is
+yields an additional untyped boolean value. The value of <code>ok</code> is
 <code>true</code> if the key <code>x</code> is present in the map, and
-<code>false</code> otherwise. The value of <code>v</code> is the value
-<code>a[x]</code> as in the single-result form.
+<code>false</code> otherwise.
 </p>
 
 <p>
@@ -2824,7 +3137,7 @@ r := y.(io.Reader)     // r has type io.Reader and y must implement both I and i
 </pre>
 
 <p>
-If a type assertion is used in an <a href="#Assignments">assignment</a> or initialization of the form
+A type assertion used in an <a href="#Assignments">assignment</a> or initialization of the special form
 </p>
 
 <pre>
@@ -2834,13 +3147,10 @@ var v, ok = x.(T)
 </pre>
 
 <p>
-the result of the assertion is a pair of values with types <code>(T, bool)</code>.
-If the assertion holds, the expression returns the pair <code>(x.(T), true)</code>;
-otherwise, the expression returns <code>(Z, false)</code> where <code>Z</code>
-is the <a href="#The_zero_value">zero value</a> for type <code>T</code>.
+yields an additional untyped boolean value. The value of <code>ok</code> is <code>true</code>
+if the assertion holds. Otherwise it is <code>false</code> and the value of <code>v</code> is
+the <a href="#The_zero_value">zero value</a> for type <code>T</code>.
 No run-time panic occurs in this case.
-The type assertion in this construct thus acts like a function call
-returning a value and a boolean indicating success.
 </p>
 
 
@@ -2870,7 +3180,7 @@ the method.
 <pre>
 math.Atan2(x, y)  // function call
 var pt *Point
-pt.Scale(3.5)  // method call with receiver pt
+pt.Scale(3.5)     // method call with receiver pt
 </pre>
 
 <p>
@@ -3375,13 +3685,13 @@ or an array indexing operation of an addressable array.
 As an exception to the addressability requirement, <code>x</code> may also be a
 (possibly parenthesized)
 <a href="#Composite_literals">composite literal</a>.
-If the evaluation of <code>x</code> would cause a <a href="#Run_time_panics">run-time panic</a>, 
+If the evaluation of <code>x</code> would cause a <a href="#Run_time_panics">run-time panic</a>,
 then the evaluation of <code>&x</code> does too.
 </p>
 
 <p>
 For an operand <code>x</code> of pointer type <code>*T</code>, the pointer
-indirection <code>*x</code> denotes the value of type <code>T</code> pointed
+indirection <code>*x</code> denotes the <a href="#Variables">variable</a> of type <code>T</code> pointed
 to by <code>x</code>.
 If <code>x</code> is <code>nil</code>, an attempt to evaluate <code>*x</code>
 will cause a <a href="#Run_time_panics">run-time panic</a>.
@@ -3422,7 +3732,7 @@ f(<-ch)
 </pre>
 
 <p>
-A receive expression used in an assignment or initialization of the form
+A receive expression used in an <a href="#Assignments">assignment</a> or initialization of the special form
 </p>
 
 <pre>
@@ -3432,7 +3742,7 @@ var x, ok = <-ch
 </pre>
 
 <p>
-yields an additional result of type <code>bool</code> reporting whether the
+yields an additional untyped boolean result reporting whether the
 communication succeeded. The value of <code>ok</code> is <code>true</code>
 if the value received was delivered by a successful send operation to the
 channel, or <code>false</code> if it is a zero value generated because the
@@ -3440,232 +3750,6 @@ channel is closed and empty.
 </p>
 
 
-<h3 id="Method_expressions">Method expressions</h3>
-
-<p>
-If <code>M</code> is in the <a href="#Method_sets">method set</a> of type <code>T</code>,
-<code>T.M</code> is a function that is callable as a regular function
-with the same arguments as <code>M</code> prefixed by an additional
-argument that is the receiver of the method.
-</p>
-
-<pre class="ebnf">
-MethodExpr    = ReceiverType "." MethodName .
-ReceiverType  = TypeName | "(" "*" TypeName ")" | "(" ReceiverType ")" .
-</pre>
-
-<p>
-Consider a struct type <code>T</code> with two methods,
-<code>Mv</code>, whose receiver is of type <code>T</code>, and
-<code>Mp</code>, whose receiver is of type <code>*T</code>.
-</p>
-
-<pre>
-type T struct {
-	a int
-}
-func (tv  T) Mv(a int) int         { return 0 }  // value receiver
-func (tp *T) Mp(f float32) float32 { return 1 }  // pointer receiver
-
-var t T
-</pre>
-
-<p>
-The expression
-</p>
-
-<pre>
-T.Mv
-</pre>
-
-<p>
-yields a function equivalent to <code>Mv</code> but
-with an explicit receiver as its first argument; it has signature
-</p>
-
-<pre>
-func(tv T, a int) int
-</pre>
-
-<p>
-That function may be called normally with an explicit receiver, so
-these five invocations are equivalent:
-</p>
-
-<pre>
-t.Mv(7)
-T.Mv(t, 7)
-(T).Mv(t, 7)
-f1 := T.Mv; f1(t, 7)
-f2 := (T).Mv; f2(t, 7)
-</pre>
-
-<p>
-Similarly, the expression
-</p>
-
-<pre>
-(*T).Mp
-</pre>
-
-<p>
-yields a function value representing <code>Mp</code> with signature
-</p>
-
-<pre>
-func(tp *T, f float32) float32
-</pre>
-
-<p>
-For a method with a value receiver, one can derive a function
-with an explicit pointer receiver, so
-</p>
-
-<pre>
-(*T).Mv
-</pre>
-
-<p>
-yields a function value representing <code>Mv</code> with signature
-</p>
-
-<pre>
-func(tv *T, a int) int
-</pre>
-
-<p>
-Such a function indirects through the receiver to create a value
-to pass as the receiver to the underlying method;
-the method does not overwrite the value whose address is passed in
-the function call.
-</p>
-
-<p>
-The final case, a value-receiver function for a pointer-receiver method,
-is illegal because pointer-receiver methods are not in the method set
-of the value type.
-</p>
-
-<p>
-Function values derived from methods are called with function call syntax;
-the receiver is provided as the first argument to the call.
-That is, given <code>f := T.Mv</code>, <code>f</code> is invoked
-as <code>f(t, 7)</code> not <code>t.f(7)</code>.
-To construct a function that binds the receiver, use a
-<a href="#Function_literals">function literal</a> or
-<a href="#Method_values">method value</a>.
-</p>
-
-<p>
-It is legal to derive a function value from a method of an interface type.
-The resulting function takes an explicit receiver of that interface type.
-</p>
-
-<h3 id="Method_values">Method values</h3>
-
-<p>
-If the expression <code>x</code> has static type <code>T</code> and
-<code>M</code> is in the <a href="#Method_sets">method set</a> of type <code>T</code>,
-<code>x.M</code> is called a <i>method value</i>.
-The method value <code>x.M</code> is a function value that is callable
-with the same arguments as a method call of <code>x.M</code>.
-The expression <code>x</code> is evaluated and saved during the evaluation of the
-method value; the saved copy is then used as the receiver in any calls,
-which may be executed later.
-</p>
-
-<p>
-The type <code>T</code> may be an interface or non-interface type.
-</p>
-
-<p>
-As in the discussion of <a href="#Method_expressions">method expressions</a> above,
-consider a struct type <code>T</code> with two methods,
-<code>Mv</code>, whose receiver is of type <code>T</code>, and
-<code>Mp</code>, whose receiver is of type <code>*T</code>.
-</p>
-
-<pre>
-type T struct {
-	a int
-}
-func (tv  T) Mv(a int) int         { return 0 }  // value receiver
-func (tp *T) Mp(f float32) float32 { return 1 }  // pointer receiver
-
-var t T
-var pt *T
-func makeT() T
-</pre>
-
-<p>
-The expression
-</p>
-
-<pre>
-t.Mv
-</pre>
-
-<p>
-yields a function value of type
-</p>
-
-<pre>
-func(int) int
-</pre>
-
-<p>
-These two invocations are equivalent:
-</p>
-
-<pre>
-t.Mv(7)
-f := t.Mv; f(7)
-</pre>
-
-<p>
-Similarly, the expression
-</p>
-
-<pre>
-pt.Mp
-</pre>
-
-<p>
-yields a function value of type
-</p>
-
-<pre>
-func(float32) float32
-</pre>
-
-<p>
-As with <a href="#Selectors">selectors</a>, a reference to a non-interface method with a value receiver
-using a pointer will automatically dereference that pointer: <code>pt.Mv</code> is equivalent to <code>(*pt).Mv</code>.
-</p>
-
-<p>
-As with <a href="#Calls">method calls</a>, a reference to a non-interface method with a pointer receiver
-using an addressable value will automatically take the address of that value: <code>t.Mp</code> is equivalent to <code>(&t).Mp</code>.
-</p>
-
-<pre>
-f := t.Mv; f(7)   // like t.Mv(7)
-f := pt.Mp; f(7)  // like pt.Mp(7)
-f := pt.Mv; f(7)  // like (*pt).Mv(7)
-f := t.Mp; f(7)   // like (&t).Mp(7)
-f := makeT().Mp   // invalid: result of makeT() is not addressable
-</pre>
-
-<p>
-Although the examples above use non-interface types, it is also legal to create a method value
-from a value of interface type.
-</p>
-
-<pre>
-var i interface { M(int) } = myVal
-f := i.M; f(7)  // like i.M(7)
-</pre>
-
 <h3 id="Conversions">Conversions</h3>
 
 <p>
@@ -4055,7 +4139,7 @@ n := map[int]int{a: f()}      // n may be {2: 3} or {3: 3}: evaluation order bet
 <p>
 At package level, initialization dependencies override the left-to-right rule
 for individual initialization expressions, but not for operands within each
-expression: 
+expression:
 </p>
 
 <pre>
@@ -4314,7 +4398,7 @@ a[i] = 23
 
 <p>
 An <i>assignment operation</i> <code>x</code> <i>op</i><code>=</code>
-<code>y</code> where <i>op</i> is a binary arithmetic operation equivalent
+<code>y</code> where <i>op</i> is a binary arithmetic operation is equivalent
 to <code>x</code> <code>=</code> <code>x</code> <i>op</i>
 <code>y</code> but evaluates <code>x</code>
 only once.  The <i>op</i><code>=</code> construct is a single token.
@@ -4332,8 +4416,8 @@ i &^= 1<<n
 A tuple assignment assigns the individual elements of a multi-valued
 operation to a list of variables.  There are two forms.  In the
 first, the right hand operand is a single multi-valued expression
-such as a function evaluation or <a href="#Channel_types">channel</a> or
-<a href="#Map_types">map</a> operation or a <a href="#Type_assertions">type assertion</a>.
+such as a function call, a <a href="#Channel_types">channel</a> or
+<a href="#Map_types">map</a> operation, or a <a href="#Type_assertions">type assertion</a>.
 The number of operands on the left
 hand side must match the number of values.  For instance, if
 <code>f</code> is a function returning two values,
@@ -4407,23 +4491,21 @@ to the type of the operand to which it is assigned, with the following special c
 </p>
 
 <ol>
-<li><p>
-	If an untyped <a href="#Constants">constant</a>
+<li>
+	Any typed value may be assigned to the blank identifier.
+</li>
+
+<li>
+	If an untyped constant
 	is assigned to a variable of interface type or the blank identifier,
-	the constant is first <a href="#Conversions">converted</a> to type
-	<code>bool</code>, <code>rune</code>, <code>int</code>, <code>float64</code>,
-	<code>complex128</code> or <code>string</code> respectively, depending on
-	whether the value is a boolean, rune, integer, floating-point, complex, or
-	string constant.
-</p></li>
-
-<li><p>
-	<!-- Note that the result of a comparison is an untyped bool that may not be constant. -->
-	If a left-hand side is the blank identifier, any typed or non-constant
-	value except for the predeclared identifier
-	<a href="#Predeclared_identifiers"><code>nil</code></a>
-	may be assigned to it.
-</p></li>
+	the constant is first <a href="#Conversions">converted</a> to its
+	 <a href="#Constants">default type</a>.
+</li>
+
+<li>
+	If an untyped boolean value is assigned to a variable of interface type or
+	the blank identifier, it is first converted to type <code>bool</code>.
+</li>
 </ol>
 
 <h3 id="If_statements">If statements</h3>
@@ -4678,6 +4760,7 @@ additionally it may specify an <i>init</i>
 and a <i>post</i> statement, such as an assignment,
 an increment or decrement statement. The init statement may be a
 <a href="#Short_variable_declarations">short variable declaration</a>, but the post statement must not.
+Variables declared by the init statement are re-used in each iteration.
 </p>
 
 <pre class="ebnf">
@@ -4713,41 +4796,42 @@ for      { S() }    is the same as    for true     { S() }
 A "for" statement with a "range" clause
 iterates through all entries of an array, slice, string or map,
 or values received on a channel. For each entry it assigns <i>iteration values</i>
-to corresponding <i>iteration variables</i> and then executes the block.
+to corresponding <i>iteration variables</i> if present and then executes the block.
 </p>
 
 <pre class="ebnf">
-RangeClause = ( ExpressionList "=" | IdentifierList ":=" ) "range" Expression .
+RangeClause = [ ExpressionList "=" | IdentifierList ":=" ] "range" Expression .
 </pre>
 
 <p>
 The expression on the right in the "range" clause is called the <i>range expression</i>,
 which may be an array, pointer to an array, slice, string, map, or channel permitting
 <a href="#Receive_operator">receive operations</a>.
-As with an assignment, the operands on the left must be
+As with an assignment, if present the operands on the left must be
 <a href="#Address_operators">addressable</a> or map index expressions; they
-denote the iteration variables. If the range expression is a channel, only
-one iteration variable is permitted, otherwise there may be one or two. In the latter case,
-if the second iteration variable is the <a href="#Blank_identifier">blank identifier</a>,
-the range clause is equivalent to the same clause with only the first variable present.
+denote the iteration variables. If the range expression is a channel, at most
+one iteration variable is permitted, otherwise there may be up to two.
+If the last iteration variable is the <a href="#Blank_identifier">blank identifier</a>,
+the range clause is equivalent to the same clause without that identifier.
 </p>
 
 <p>
 The range expression is evaluated once before beginning the loop,
-with one exception. If the range expression is an array or a pointer to an array
-and only the first iteration value is present, only the range expression's
-length is evaluated; if that length is constant
-<a href="#Length_and_capacity">by definition</a>,
+with one exception: if the range expression is an array or a pointer to an array
+and at most one iteration variable is present, only the range expression's
+length is evaluated; if that length is constant,
+<a href="#Length_and_capacity">by definition</a>
 the range expression itself will not be evaluated.
 </p>
 
 <p>
 Function calls on the left are evaluated once per iteration.
-For each iteration, iteration values are produced as follows:
+For each iteration, iteration values are produced as follows
+if the respective iteration variables are present:
 </p>
 
 <pre class="grammar">
-Range expression                          1st value          2nd value (if 2nd variable is present)
+Range expression                          1st value          2nd value
 
 array or slice  a  [n]E, *[n]E, or []E    index    i  int    a[i]       E
 string          s  string type            index    i  int    see below  rune
@@ -4759,7 +4843,7 @@ channel         c  chan E, <-chan E       element  e  E
 <li>
 For an array, pointer to array, or slice value <code>a</code>, the index iteration
 values are produced in increasing order, starting at element index 0.
-If only the first iteration variable is present, the range loop produces
+If at most one iteration variable is present, the range loop produces
 iteration values from 0 up to <code>len(a)-1</code> and does not index into the array
 or slice itself. For a <code>nil</code> slice, the number of iterations is 0.
 </li>
@@ -4803,7 +4887,7 @@ The iteration variables may be declared by the "range" clause using a form of
 <a href="#Short_variable_declarations">short variable declaration</a>
 (<code>:=</code>).
 In this case their types are set to the types of the respective iteration values
-and their <a href="#Declarations_and_scope">scope</a> ends at the end of the "for"
+and their <a href="#Declarations_and_scope">scope</a> is the block of the "for"
 statement; they are re-used in each iteration.
 If the iteration variables are declared outside the "for" statement,
 after execution their values will be those of the last iteration.
@@ -4840,6 +4924,9 @@ var ch chan Work = producer()
 for w := range ch {
 	doWork(w)
 }
+
+// empty a channel
+for range ch {}
 </pre>
 
 
@@ -5242,13 +5329,16 @@ Calls of built-in functions are restricted as for
 </p>
 
 <p>
-Each time the "defer" statement
+Each time a "defer" statement
 executes, the function value and parameters to the call are
 <a href="#Calls">evaluated as usual</a>
-and saved anew but the actual function body is not executed.
-Instead, deferred functions are executed immediately before
+and saved anew but the actual function is not invoked.
+Instead, deferred functions are invoked immediately before
 the surrounding function returns, in the reverse order
 they were deferred.
+If a deferred function value evaluates
+to <code>nil</code>, execution <a href="#Handling_panics">panics</a>
+when the function is invoked, not when the "defer" statement is executed.
 </p>
 
 <p>
@@ -5295,11 +5385,6 @@ so they can only appear in <a href="#Calls">call expressions</a>;
 they cannot be used as function values.
 </p>
 
-<pre class="ebnf">
-BuiltinCall = identifier "(" [ BuiltinArgs [ "," ] ] ")" .
-BuiltinArgs = Type [ "," ArgumentList ] | ArgumentList .
-</pre>
-
 <h3 id="Close">Close</h3>
 
 <p>
@@ -5378,9 +5463,11 @@ var z complex128
 <h3 id="Allocation">Allocation</h3>
 
 <p>
-The built-in function <code>new</code> takes a type <code>T</code> and
-returns a value of type <code>*T</code>.
-The memory is initialized as described in the section on
+The built-in function <code>new</code> takes a type <code>T</code>,
+allocates storage for a <a href="#Variables">variable</a> of that type
+at run time, and returns a value of type <code>*T</code>
+<a href="#Pointer_types">pointing</a> to it.
+The variable is initialized as described in the section on
 <a href="#The_zero_value">initial values</a>.
 </p>
 
@@ -5398,10 +5485,10 @@ new(S)
 </pre>
 
 <p>
-dynamically allocates memory for a variable of type <code>S</code>,
+allocates storage for a variable of type <code>S</code>,
 initializes it (<code>a=0</code>, <code>b=0.0</code>),
 and returns a value of type <code>*S</code> containing the address
-of the memory.
+of the location.
 </p>
 
 <h3 id="Making_slices_maps_and_channels">Making slices, maps and channels</h3>
@@ -5868,10 +5955,12 @@ func main() {
 
 <h3 id="The_zero_value">The zero value</h3>
 <p>
-When memory is allocated to store a value, either through a declaration
-or a call of <code>make</code> or <code>new</code>,
-and no explicit initialization is provided, the memory is
-given a default initialization.  Each element of such a value is
+When storage is allocated for a <a href="#Variables">variable</a>,
+either through a declaration or a call of <code>new</code>, or when
+a new value is created, either through a composite literal or a call
+of <code>make</code>,
+and no explicit initialization is provided, the variable or value is
+given a default value.  Each element of such a variable or value is
 set to the <i>zero value</i> for its type: <code>false</code> for booleans,
 <code>0</code> for integers, <code>0.0</code> for floats, <code>""</code>
 for strings, and <code>nil</code> for pointers, functions, interfaces, slices, channels, and maps.
@@ -5915,20 +6004,42 @@ var t T
 </pre>
 
 <h3 id="Package_initialization">Package initialization</h3>
+
 <p>
-Within a package, package-level variables are initialized according
-to their <i>dependencies</i>: if a variable <code>x</code> depends on
-a variable <code>y</code>, <code>x</code> will be initialized after
-<code>y</code>.
+Within a package, package-level variables are initialized in
+<i>declaration order</i> but after any of the variables
+they <i>depend</i> on.
+</p>
+
+<p>
+More precisely, a package-level variable is considered <i>ready for
+initialization</i> if it is not yet initialized and either has
+no <a href="#Variable_declarations">initialization expression</a> or
+its initialization expression has no dependencies on uninitialized variables.
+Initialization proceeds by repeatedly initializing the next package-level
+variable that is earliest in declaration order and ready for initialization,
+until there are no variables ready for initialization.
+</p>
+
+<p>
+If any variables are still uninitialized when this
+process ends, those variables are part of one or more initialization cycles,
+and the program is not valid.
+</p>
+
+<p>
+The declaration order of variables declared in multiple files is determined
+by the order in which the files are presented to the compiler: Variables
+declared in the first file are declared before any of the variables declared
+in the second file, and so on.
 </p>
 
 <p>
 Dependency analysis does not rely on the actual values of the
 variables, only on lexical <i>references</i> to them in the source,
-analyzed transitively. For instance, a variable <code>x</code>'s
-<a href="#Variable_declarations">initialization expression</a>
-may refer to a function whose body refers to variable <code>y</code>;
-if so, <code>x</code> depends on <code>y</code>.
+analyzed transitively. For instance, if a variable <code>x</code>'s
+initialization expression refers to a function whose body refers to
+variable <code>y</code> then <code>x</code> depends on <code>y</code>.
 Specifically:
 </p>
 
@@ -5941,7 +6052,7 @@ variable or function.
 <li>
 A reference to a method <code>m</code> is a
 <a href="#Method_values">method value</a> or
-<a href="#Method_expressions">method expression</a> of the form 
+<a href="#Method_expressions">method expression</a> of the form
 <code>t.m</code>, where the (static) type of <code>t</code> is
 not an interface type, and the method <code>m</code> is in the
 <a href="#Method_sets">method set</a> of <code>t</code>.
@@ -5950,7 +6061,7 @@ It is immaterial whether the resulting function value
 </li>
 
 <li>
-A variable, function, or method <code>x</code> depends on a variable 
+A variable, function, or method <code>x</code> depends on a variable
 <code>y</code> if <code>x</code>'s initialization expression or body
 (for functions and methods) contains a reference to <code>y</code>
 or to a function or method that depends on <code>y</code>.
@@ -5961,11 +6072,6 @@ or to a function or method that depends on <code>y</code>.
 Dependency analysis is performed per package; only references referring
 to variables, functions, and methods declared in the current package
 are considered.
-It is an error if variable dependencies form a cycle
-(but dependency cycles containing no variables are permitted).
-If two variables are independent of each other,
-they are initialized in the order they are declared
-in the source, possibly in multiple files, as presented to the compiler.
 </p>
 
 <p>
@@ -5988,8 +6094,6 @@ func f() int {
 
 <p>
 the initialization order is <code>d</code>, <code>b</code>, <code>c</code>, <code>a</code>.
-Since <code>b</code> and <code>c</code> are independent of each other, they are
-initialized in declaration order (<code>b</code> before <code>c</code>).
 </p>
 
 <p>
@@ -6002,7 +6106,7 @@ func init() { … }
 </pre>
 
 <p>
-Multiple such functions may be defined, even within a single 
+Multiple such functions may be defined, even within a single
 source file. The <code>init</code> identifier is not
 <a href="#Declarations_and_scope">declared</a> and thus
 <code>init</code> functions cannot be referred to from anywhere
@@ -6032,6 +6136,12 @@ the <code>init</code> functions: it will not invoke the next one
 until the previous one has returned.
 </p>
 
+<p>
+To ensure reproducible initialization behavior, build systems are encouraged
+to present multiple files belonging to the same package in lexical file name
+order to a compiler.
+</p>
+
 
 <h3 id="Program_execution">Program execution</h3>
 <p>
@@ -6106,8 +6216,8 @@ type Error interface {
 The built-in package <code>unsafe</code>, known to the compiler,
 provides facilities for low-level programming including operations
 that violate the type system. A package using <code>unsafe</code>
-must be vetted manually for type safety.  The package provides the
-following interface:
+must be vetted manually for type safety and may not be portable.
+The package provides the following interface:
 </p>
 
 <pre class="grammar">
@@ -6122,10 +6232,11 @@ func Sizeof(variable ArbitraryType) uintptr
 </pre>
 
 <p>
-Any pointer or value of <a href="#Types">underlying type</a> <code>uintptr</code> can be converted to
-a <code>Pointer</code> type and vice versa.
 A <code>Pointer</code> is a <a href="#Pointer_types">pointer type</a> but a <code>Pointer</code>
 value may not be <a href="#Address_operators">dereferenced</a>.
+Any pointer or value of <a href="#Types">underlying type</a> <code>uintptr</code> can be converted to
+a <code>Pointer</code> type and vice versa.
+The effect of converting between <code>Pointer</code> and <code>uintptr</code> is implementation-defined.
 </p>
 
 <pre>
diff --git a/doc/gopher/biplane.jpg b/doc/gopher/biplane.jpg
new file mode 100644
index 0000000..d5e666f
Binary files /dev/null and b/doc/gopher/biplane.jpg differ
diff --git a/doc/gopher/fiveyears.jpg b/doc/gopher/fiveyears.jpg
new file mode 100644
index 0000000..df10648
Binary files /dev/null and b/doc/gopher/fiveyears.jpg differ
diff --git a/doc/help.html b/doc/help.html
index a307b2a..2cc4780 100644
--- a/doc/help.html
+++ b/doc/help.html
@@ -24,7 +24,7 @@ Need help with Go? Try these resources.
 <p>
 Search the <a href="//groups.google.com/group/golang-nuts">golang-nuts</a>
 archives and consult the <a href="/doc/go_faq.html">FAQ</a> and
-<a href="//code.google.com/p/go-wiki/wiki">wiki</a> before posting.
+<a href="//golang.org/wiki">wiki</a> before posting.
 </p>
 
 <h3 id="irc"><a href="irc:irc.freenode.net/go-nuts">Go IRC Channel</a></h3>
diff --git a/doc/install-source.html b/doc/install-source.html
index 82859b5..f53deb4 100644
--- a/doc/install-source.html
+++ b/doc/install-source.html
@@ -241,12 +241,12 @@ provides <b>essential setup instructions</b> for using the Go tools.
 
 <p>
 The source code for several Go tools (including <a href="/cmd/godoc/">godoc</a>)
-is kept in <a href="https://code.google.com/p/go.tools">the go.tools repository</a>.
+is kept in <a href="https://golang.org/x/tools">the go.tools repository</a>.
 To install all of them, run the <code>go</code> <code>get</code> command:
 </p>
 
 <pre>
-$ go get code.google.com/p/go.tools/cmd/...
+$ go get golang.org/x/tools/cmd/...
 </pre>
 
 <p>
@@ -254,7 +254,7 @@ Or if you just want to install a specific command (<code>godoc</code> in this ca
 </p>
 
 <pre>
-$ go get code.google.com/p/go.tools/cmd/godoc
+$ go get golang.org/x/tools/cmd/godoc
 </pre>
 
 <p>
diff --git a/doc/install.html b/doc/install.html
index 2de0447..9561fdd 100644
--- a/doc/install.html
+++ b/doc/install.html
@@ -6,14 +6,14 @@
 <h2 id="download">Download the Go distribution</h2>
 
 <p>
-<a href="/dl/" id="start" class="download" target="_blank">
+<a href="https://golang.org/dl/" id="start" class="download" target="_blank">
 <span class="big">Download Go</span>
 <span class="desc">Click here to visit the downloads page</span>
 </a>
 </p>
 
 <p>
-<a href="https://code.google.com/p/go/wiki/Downloads?tm=2" target="_blank">Official binary
+<a href="https://golang.org/dl/" target="_blank">Official binary
 distributions</a> are available for the FreeBSD (release 8 and above), Linux, Mac OS X (Snow Leopard
 and above), and Windows operating systems and the 32-bit (<code>386</code>) and
 64-bit (<code>amd64</code>) x86 processor architectures.
@@ -47,7 +47,7 @@ proceeding. If your OS or architecture is not on the list, it's possible that
 <tr><td>FreeBSD 8 or later</td> <td>amd64, 386, arm</td> <td>Debian GNU/kFreeBSD not supported; FreeBSD/ARM needs FreeBSD 10 or later</td></tr>
 <tr><td>Linux 2.6.23 or later with glibc</td> <td>amd64, 386, arm</td> <td>CentOS/RHEL 5.x not supported; no binary distribution for ARM yet</td></tr>
 <tr><td>Mac OS X 10.6 or later</td> <td>amd64, 386</td> <td>use the gcc<sup>†</sup> that comes with Xcode<sup>‡</sup></td></tr>
-<tr><td>Windows XP or later</td> <td>amd64, 386</td> <td>use MinGW gcc<sup>†</sup>. No need for cgywin or msys.</td></tr>
+<tr><td>Windows XP or later</td> <td>amd64, 386</td> <td>use MinGW gcc<sup>†</sup>. No need for cygwin or msys.</td></tr>
 </table>
 
 <p>
@@ -70,7 +70,7 @@ first <a href="#uninstall">remove the existing version</a>.
 <h3 id="tarball">Linux, Mac OS X, and FreeBSD tarballs</h3>
 
 <p>
-<a href="https://code.google.com/p/go/wiki/Downloads?tm=2">Download the archive</a>
+<a href="https://golang.org/dl/">Download the archive</a>
 and extract it into <code>/usr/local</code>, creating a Go tree in
 <code>/usr/local/go</code>. For example:
 </p>
@@ -127,7 +127,7 @@ location.
 <h3 id="osx">Mac OS X package installer</h3>
 
 <p>
-<a href="https://code.google.com/p/go/wiki/Downloads?tm=2">Download the package file</a>,
+<a href="https://golang.org/dl/">Download the package file</a>,
 open it, and follow the prompts to install the Go tools.
 The package installs the Go distribution to <code>/usr/local/go</code>.
 </p>
@@ -150,7 +150,7 @@ MSI installer that configures your installation automatically.
 <h4 id="windows_msi">MSI installer</h4>
 
 <p>
-Open the <a href="https://code.google.com/p/go/wiki/Downloads?tm=2">MSI file</a>
+Open the <a href="https://golang.org/dl/">MSI file</a>
 and follow the prompts to install the Go tools.
 By default, the installer puts the Go distribution in <code>c:\Go</code>.
 </p>
@@ -164,7 +164,7 @@ command prompts for the change to take effect.
 <h4 id="windows_zip">Zip archive</h4>
 
 <p>
-<a href="https://code.google.com/p/go/wiki/Downloads?tm=2">Download the zip file</a> and extract it into the directory of your choice (we suggest <code>c:\Go</code>).
+<a href="https://golang.org/dl/">Download the zip file</a> and extract it into the directory of your choice (we suggest <code>c:\Go</code>).
 </p>
 
 <p>
@@ -224,19 +224,12 @@ If you see the "hello, world" message then your Go installation is working.
 
 <p>
 You're almost done.
-You just need to do a little more setup.
+You just need to set up your environment.
 </p>
 
 <p>
-<a href="/doc/code.html" class="download" id="writing">
-<span class="big">How to Write Go Code</span>
-<span class="desc">Learn how to set up and use the Go tools</span>
-</a>
-</p>
-
-<p>
-The <a href="/doc/code.html">How to Write Go Code</a> document
-provides <b>essential setup instructions</b> for using the Go tools.
+Read the <a href="/doc/code.html">How to Write Go Code</a> document,
+which provides <b>essential setup instructions</b> for using the Go tools.
 </p>
 
 
@@ -277,5 +270,3 @@ The official mailing list for discussion of the Go language is
 Report bugs using the
 <a href="//golang.org/issue">Go issue tracker</a>.
 </p>
-
-
diff --git a/include/bio.h b/include/bio.h
index f61409b..982b881 100644
--- a/include/bio.h
+++ b/include/bio.h
@@ -129,6 +129,14 @@ int	Bungetc(Biobuf*);
 int	Bungetrune(Biobuf*);
 long	Bwrite(Biobuf*, void*, long);
 int	Bvprint(Biobuf*, char*, va_list);
+/*c2go
+int	BGETC(Biobuf*);
+int	BGETLE2(Biobuf*);
+int	BGETLE4(Biobuf*);
+int	BPUTC(Biobuf*, int);
+int	BPUTLE2(Biobuf*, int);
+int	BPUTLE4(Biobuf*, int);
+*/
 
 #if defined(__cplusplus)
 }
diff --git a/include/link.h b/include/link.h
index 2484978..05e117c 100644
--- a/include/link.h
+++ b/include/link.h
@@ -105,13 +105,15 @@ struct	Prog
 	int32	spadj;
 	uchar	mark;
 	uchar	back;	// 6l, 8l
-	char	ft;	/* 6l, 8l oclass cache */
-	char	tt;	// 6l, 8l
-	uchar	optab;	// 5l
+	uchar	ft;	/* 6l, 8l oclass cache */
+	uchar	tt;	// 6l, 8l
+	uint16	optab;	// 5l
 	uchar	isize;	// 6l, 8l
 
 	char	width;	/* fake for DATA */
 	char	mode;	/* 16, 32, or 64 in 6l, 8l; internal use in 5g, 6g, 8g */
+	
+	/*c2go uchar TEXTFLAG; */
 };
 
 // prevent incompatible type signatures between liblink and 8l on Plan 9
@@ -124,6 +126,7 @@ struct	LSym
 	short	type;
 	short	version;
 	uchar	dupok;
+	uchar	cfunc;
 	uchar	external;
 	uchar	nosplit;
 	uchar	reachable;
@@ -167,7 +170,7 @@ struct	LSym
 
 	// SDATA, SBSS
 	uchar*	p;
-	int32	np;
+	int	np;
 	int32	maxp;
 	Reloc*	r;
 	int32	nr;
@@ -201,10 +204,10 @@ enum
 	SELFSECT,
 	SMACHO,	/* Mach-O __nl_symbol_ptr */
 	SMACHOGOT,
+	SWINDOWS,
 	SNOPTRDATA,
 	SINITARR,
 	SDATA,
-	SWINDOWS,
 	SBSS,
 	SNOPTRBSS,
 	STLSBSS,
@@ -370,6 +373,7 @@ struct	Link
 	char*	trimpath;
 	char*	goroot;
 	char*	goroot_final;
+	int32	enforce_data_order;	// for use by assembler
 
 	// hash table of all symbols
 	LSym*	hash[LINKHASH];
@@ -389,9 +393,9 @@ struct	Link
 	LSym*	sym_divu;
 	LSym*	sym_mod;
 	LSym*	sym_modu;
-	LSym*	symmorestack[20];
-	LSym*	gmsym;
-	LSym*	plan9tos;
+	LSym*	symmorestack[2];
+	LSym*	tlsg;
+	LSym*	plan9privates;
 	Prog*	curp;
 	Prog*	printp;
 	Prog*	blitrl;
@@ -403,7 +407,7 @@ struct	Link
 	int	asmode;
 	uchar*	andptr;
 	uchar	and[100];
-	int32	instoffset;
+	int64	instoffset;
 	int32	autosize;
 	int32	armsize;
 
@@ -429,11 +433,17 @@ struct	Link
 	LSym*	filesyms;
 };
 
+enum {
+	LittleEndian = 0x04030201,
+	BigEndian = 0x01020304,
+};
+
 // LinkArch is the definition of a single architecture.
 struct LinkArch
 {
 	char*	name; // "arm", "amd64", and so on
 	int	thechar;	// '5', '6', and so on
+	int32	endian; // LittleEndian or BigEndian
 
 	void	(*addstacksplit)(Link*, LSym*);
 	void	(*assemble)(Link*, LSym*);
@@ -462,6 +472,7 @@ struct LinkArch
 	int	D_PARAM;
 	int	D_SCONST;
 	int	D_STATIC;
+	int	D_OREG;
 
 	int	ACALL;
 	int	ADATA;
@@ -532,6 +543,7 @@ vlong	adduint8(Link *ctxt, LSym *s, uint8 v);
 vlong	adduintxx(Link *ctxt, LSym *s, uint64 v, int wid);
 void	mangle(char *file);
 void	savedata(Link *ctxt, LSym *s, Prog *p, char *pn);
+void	savedata1(Link *ctxt, LSym *s, Prog *p, char *pn, int enforce_order);
 vlong	setaddr(Link *ctxt, LSym *s, vlong off, LSym *t);
 vlong	setaddrplus(Link *ctxt, LSym *s, vlong off, LSym *t, vlong add);
 vlong	setuint16(Link *ctxt, LSym *s, vlong r, uint16 v);
@@ -558,7 +570,7 @@ int	find1(int32 l, int c);
 void	linkgetline(Link *ctxt, int32 line, LSym **f, int32 *l);
 void	histtoauto(Link *ctxt);
 void	mkfwd(LSym*);
-void	nuxiinit(void);
+void	nuxiinit(LinkArch*);
 void	savehist(Link *ctxt, int32 line, int32 off);
 Prog*	copyp(Link*, Prog*);
 Prog*	appendp(Link*, Prog*);
@@ -600,6 +612,8 @@ extern	char*	anames5[];
 extern	char*	anames6[];
 extern	char*	anames8[];
 
+extern	char*	cnames5[];
+
 extern	LinkArch	link386;
 extern	LinkArch	linkamd64;
 extern	LinkArch	linkamd64p32;
@@ -610,6 +624,7 @@ extern	LinkArch	linkarm;
 #pragma	varargck	type	"lD"	Addr*
 #pragma	varargck	type	"P"	Prog*
 #pragma	varargck	type	"R"	int
+#pragma varargck	type	"^"	int
 
 // TODO(ality): remove this workaround.
 //   It's here because Pconv in liblink/list?.c references %L.
diff --git a/lib/time/update.bash b/lib/time/update.bash
index 8e1662a..caa8450 100755
--- a/lib/time/update.bash
+++ b/lib/time/update.bash
@@ -7,8 +7,8 @@
 # downloaded from the ICANN/IANA distribution.
 
 # Versions to use.
-CODE=2014d
-DATA=2014d
+CODE=2014j
+DATA=2014j
 
 set -e
 rm -rf work
diff --git a/lib/time/zoneinfo.zip b/lib/time/zoneinfo.zip
index e0d3afe..425d7c9 100644
Binary files a/lib/time/zoneinfo.zip and b/lib/time/zoneinfo.zip differ
diff --git a/misc/IntelliJIDEA/Go.xml b/misc/IntelliJIDEA/Go.xml
deleted file mode 100644
index 51abdf4..0000000
--- a/misc/IntelliJIDEA/Go.xml
+++ /dev/null
@@ -1,99 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-    Copyright 2011 The Go Authors. All rights reserved.
-    Use of this source code is governed by a BSD-style
-    license that can be found in the LICENSE file.
-
-Copy this custom language definition & configuration file to
-        * Mac             : ~/Library/Preferences/IntelliJIdea10/filetypes/
-        * Linux & Windows : ~/.IntelliJIdea10/config/filetypes/
--->
-
-<filetype binary="false" default_extension="" description="Go" name="Go">
-    <highlighting>
-        <options>
-            <option name="LINE_COMMENT" value="//"/>
-            <option name="COMMENT_START" value="/*"/>
-            <option name="COMMENT_END" value="*/"/>
-            <option name="HEX_PREFIX" value="0x"/>
-            <option name="NUM_POSTFIXES" value=""/>
-            <option name="HAS_BRACKETS" value="true"/>
-            <option name="HAS_BRACES" value="true"/>
-            <option name="HAS_PARENS" value="true"/>
-            <option name="HAS_STRING_ESCAPES" value="true"/>
-        </options>
-        <keywords ignore_case="false">
-            <keyword name="break"/>
-            <keyword name="case"/>
-            <keyword name="chan"/>
-            <keyword name="const"/>
-            <keyword name="continue"/>
-            <keyword name="default"/>
-            <keyword name="defer"/>
-            <keyword name="else"/>
-            <keyword name="fallthrough"/>
-            <keyword name="for"/>
-            <keyword name="func"/>
-            <keyword name="go"/>
-            <keyword name="goto"/>
-            <keyword name="if"/>
-            <keyword name="import"/>
-            <keyword name="interface"/>
-            <keyword name="map"/>
-            <keyword name="package"/>
-            <keyword name="range"/>
-            <keyword name="return"/>
-            <keyword name="select"/>
-            <keyword name="struct"/>
-            <keyword name="switch"/>
-            <keyword name="type"/>
-            <keyword name="var"/>
-        </keywords>
-        <keywords2>
-            <keyword name="bool"/>
-            <keyword name="byte"/>
-            <keyword name="complex64"/>
-            <keyword name="complex128"/>
-            <keyword name="float32"/>
-            <keyword name="float64"/>
-            <keyword name="int"/>
-            <keyword name="int8"/>
-            <keyword name="int16"/>
-            <keyword name="int32"/>
-            <keyword name="int64"/>
-            <keyword name="string"/>
-            <keyword name="uint"/>
-            <keyword name="uint8"/>
-            <keyword name="uint16"/>
-            <keyword name="uint32"/>
-            <keyword name="uint64"/>
-            <keyword name="uintptr"/>
-        </keywords2>
-        <keywords3>
-            <keyword name="append"/>
-            <keyword name="cap"/>
-            <keyword name="close"/>
-            <keyword name="complex"/>
-            <keyword name="copy"/>
-            <keyword name="delete"/>
-            <keyword name="imag"/>
-            <keyword name="len"/>
-            <keyword name="make"/>
-            <keyword name="new"/>
-            <keyword name="panic"/>
-            <keyword name="print"/>
-            <keyword name="println"/>
-            <keyword name="real"/>
-            <keyword name="recover"/>
-        </keywords3>
-        <keywords4>
-            <keyword name="false"/>
-            <keyword name="iota"/>
-            <keyword name="nil"/>
-            <keyword name="true"/>
-        </keywords4>
-    </highlighting>
-    <extensionMap>
-        <mapping ext="go"/>
-    </extensionMap>
-</filetype>
diff --git a/misc/android/README b/misc/android/README
new file mode 100644
index 0000000..5f24faf
--- /dev/null
+++ b/misc/android/README
@@ -0,0 +1,11 @@
+Android
+=======
+
+For details on developing Go for Android, see the documentation in the
+go.mobile subrepository:
+
+	https://code.google.com/p/go/source/browse/README?repo=mobile
+
+To run the standard library tests, see androidtest.bash. Run it as
+
+	CC_FOR_TARGET=.../ndk-gcc GOARCH=arm GOARM=7 ./androidtest.bash
diff --git a/misc/android/go_android_exec.go b/misc/android/go_android_exec.go
new file mode 100644
index 0000000..e32a805
--- /dev/null
+++ b/misc/android/go_android_exec.go
@@ -0,0 +1,96 @@
+// 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 can be used as go_android_GOARCH_exec by the Go tool.
+// It executes binaries on an android device using adb.
+package main
+
+import (
+	"bytes"
+	"fmt"
+	"io"
+	"log"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"runtime"
+	"strconv"
+	"strings"
+)
+
+func run(args ...string) string {
+	buf := new(bytes.Buffer)
+	cmd := exec.Command("adb", args...)
+	cmd.Stdout = io.MultiWriter(os.Stdout, buf)
+	cmd.Stderr = os.Stderr
+	log.Printf("adb %s", strings.Join(args, " "))
+	err := cmd.Run()
+	if err != nil {
+		log.Fatalf("adb %s: %v", strings.Join(args, " "), err)
+	}
+	return buf.String()
+}
+
+func main() {
+	log.SetFlags(0)
+	log.SetPrefix("go_android_exec: ")
+
+	// Determine thepackage by examining the current working
+	// directory, which will look something like
+	// "$GOROOT/src/mime/multipart". We extract everything
+	// after the $GOROOT to run on the same relative directory
+	// on the target device.
+	//
+	// TODO(crawshaw): Pick useful subdir when we are not
+	// inside a GOROOT, e.g. we are in a GOPATH.
+	cwd, err := os.Getwd()
+	if err != nil {
+		log.Fatal(err)
+	}
+	subdir, err := filepath.Rel(runtime.GOROOT(), cwd)
+	if err != nil {
+		log.Fatal(err)
+	}
+	subdir = filepath.ToSlash(subdir)
+
+	// Binary names can conflict.
+	// E.g. template.test from the {html,text}/template packages.
+	binName := filepath.Base(os.Args[1])
+	deviceGoroot := "/data/local/tmp/goroot"
+	deviceBin := fmt.Sprintf("%s/%s-%d", deviceGoroot, binName, os.Getpid())
+
+	// The push of the binary happens in parallel with other tests.
+	// Unfortunately, a simultaneous call to adb shell hold open
+	// file descriptors, so it is necessary to push then move to
+	// avoid a "text file busy" error on execution.
+	// https://code.google.com/p/android/issues/detail?id=65857
+	run("push", os.Args[1], deviceBin+"-tmp")
+	run("shell", "cp '"+deviceBin+"-tmp' '"+deviceBin+"'")
+	run("shell", "rm '"+deviceBin+"-tmp'")
+
+	// The adb shell command will return an exit code of 0 regardless
+	// of the command run. E.g.
+	//	$ adb shell false
+	//	$ echo $?
+	//	0
+	// https://code.google.com/p/android/issues/detail?id=3254
+	// So we append the exitcode to the output and parse it from there.
+	const exitstr = "exitcode="
+	cmd := `export TMPDIR="/data/local/tmp"` +
+		`; export GOROOT="` + deviceGoroot + `"` +
+		`; cd "$GOROOT/` + subdir + `"` +
+		"; '" + deviceBin + "' " + strings.Join(os.Args[2:], " ") +
+		"; echo -n " + exitstr + "$?"
+	output := run("shell", cmd)
+	run("shell", "rm '"+deviceBin+"'") // cleanup
+	output = output[strings.LastIndex(output, "\n")+1:]
+	if !strings.HasPrefix(output, exitstr) {
+		log.Fatalf("no exit code: %q", output)
+	}
+	code, err := strconv.Atoi(output[len(exitstr):])
+	if err != nil {
+		log.Fatalf("bad exit code: %v", err)
+	}
+	os.Exit(code)
+}
diff --git a/misc/bash/go b/misc/bash/go
deleted file mode 100644
index 50f4f72..0000000
--- a/misc/bash/go
+++ /dev/null
@@ -1,237 +0,0 @@
-# install in /etc/bash_completion.d/ or your personal directory
-
-complete -f -X '!*.8' 8l
-complete -f -X '!*.6' 6l
-complete -f -X '!*.5' 5l
-complete -f -X '!*.go' 8g 6g 5g gofmt gccgo
-
-_go_importpath()
-{
-  echo "$(compgen -W "$(go list all) all std" -- "$1")"
-}
-
-_go()
-{
-  # TODO: Only allow flags before other arguments. run already does
-  # this.
-
-  local cur=`_get_cword`
-  local prev="${COMP_WORDS[COMP_CWORD-1]}"
-
-  local cmd="${COMP_WORDS[1]}"
-
-  local cmds="build clean env fix fmt get
-    install list run test tool version vet"
-  local addhelp="c gopath importpath packages testflag testfunc"
-  local other="help"
-
-  if [ "$COMP_CWORD" == 1 ]; then
-    for opt in $cmds; do
-      if [[ "$opt" == "$cmd" ]]; then
-        COMPREPLY=("$opt")
-        return
-      fi
-    done
-  fi
-
-  case "$cmd" in
-    'build')
-      case "$prev" in
-        '-o')
-          _filedir
-          ;;
-        '-p')
-          ;;
-        *)
-          if [[ "$cur" == -* ]]; then
-            COMPREPLY=($(compgen -W "-a -n -o -p -v -x" -- "$cur"))
-          else
-            local found=0
-            for ((i=0; i < ${#COMP_WORDS[@]}; i++)); do
-              case "$i" in
-                0|1|"$COMP_CWORD")
-                  continue
-                  ;;
-              esac
-              local opt="${COMP_WORDS[i]}"
-              if [[ "$opt" != -* ]]; then
-                if [[ "$opt" == *.go && -f "$opt" ]]; then
-                  found=1
-                  break
-                else
-                  found=2
-                  break
-                fi
-              fi
-            done
-            case "$found" in
-              0)
-                _filedir go
-                COMPREPLY+=(`_go_importpath "$cur"`)
-                ;;
-              1)
-                _filedir go
-                ;;
-              2)
-                COMPREPLY=(`_go_importpath "$cur"`)
-                ;;
-            esac
-          fi
-          ;;
-      esac
-      ;;
-    'clean')
-      if [[ "$cur" == -* ]]; then
-        COMPREPLY=($(compgen -W "-i -r -n -x" -- "$cur"))
-      else
-        COMPREPLY=(`_go_importpath "$cur"`)
-      fi
-      ;;
-    'fix')
-      COMPREPLY=(`_go_importpath "$cur"`)
-      ;;
-    'fmt')
-      COMPREPLY=(`_go_importpath "$cur"`)
-      ;;
-    'get')
-      case "$prev" in
-        '-p')
-          ;;
-        *)
-          if [[ "$cur" == -* ]]; then
-            COMPREPLY=($(compgen -W "-a -d -fix -n -p -u -v -x" -- "$cur"))
-          else
-            COMPREPLY=(`_go_importpath "$cur"`)
-          fi
-          ;;
-      esac
-      ;;
-    'install')
-      case "$prev" in
-        '-p')
-          ;;
-        *)
-          if [[ "$cur" == -* ]]; then
-            COMPREPLY=($(compgen -W "-a -n -p -v -x" -- "$cur"))
-          else
-            COMPREPLY=(`_go_importpath "$cur"`)
-          fi
-          ;;
-      esac
-      ;;
-    'list')
-      case "$prev" in
-        '-f')
-          ;;
-        *)
-          if [[ "$cur" == -* ]]; then
-            COMPREPLY=($(compgen -W "-e -f -json" -- "$cur"))
-          else
-            COMPREPLY=(`_go_importpath "$cur"`)
-          fi
-          ;;
-      esac
-      ;;
-    'run')
-      if [[ "$cur" == -* && "$prev" != *.go ]]; then
-        COMPREPLY=($(compgen -W "-a -n -x" -- "$cur"))
-      else
-        _filedir
-      fi
-      ;;
-    'test') # TODO: Support for testflags.
-      case "$prev" in
-        '-file')
-          _filedir go
-          ;;
-        '-p')
-          ;;
-        *)
-          if [[ "$cur" == -* ]]; then
-            COMPREPLY=($(compgen -W "-c -file -i -p -x" -- "$cur"))
-          else
-            COMPREPLY=(`_go_importpath "$cur"`)
-          fi
-          ;;
-        esac
-      ;;
-    'tool')
-      if [ "$COMP_CWORD" == 2 ]; then
-        COMPREPLY=($(compgen -W "$(go tool)" -- "$cur"))
-      else
-        case "${COMP_WORDS[2]}" in
-          [568]a) # TODO: Implement something.
-            #_go_tool_568a
-            ;;
-          [568]c) # TODO: Implement something.
-            #_go_tool_568c
-            ;;
-          [568]g) # TODO: Implement something.
-            #_go_tool_568g
-            ;;
-          [568]l) # TODO: Implement something.
-            #_go_tool_568l
-            ;;
-          'api') # TODO: Implement something.
-            #_go_tool_api
-            ;;
-          'cgo') # TODO: Implement something.
-            #_go_tool_cgo
-            ;;
-          'cov') # TODO: Implement something.
-            #_go_tool_cov
-            ;;
-          'dist') # TODO: Implement something.
-            #_go_tool_dist
-            ;;
-          'fix') # TODO: Implement something.
-            #_go_tool_fix
-            ;;
-          'nm') # TODO: Implement something.
-            #_go_tool_nm
-            ;;
-          'pack') # TODO: Implement something.
-            #_go_tool_pack
-            ;;
-          'pprof') # TODO: Implement something.
-            #_go_tool_pprof
-            ;;
-          'vet') # TODO: Implement something.
-            #_go_tool_vet
-            ;;
-          'yacc') # TODO: Implement something.
-            #_go_tool_yacc
-            ;;
-        esac
-        if [[ "$cur" == -* ]]; then
-          COMPREPLY=($(compgen -W "${COMPREPLY[*]} -h" -- "$cur"))
-        fi
-      fi
-      ;;
-    'version')
-      ;;
-    'vet')
-      if [[ "$cur" == -* ]]; then
-        :
-      else
-        COMPREPLY=(`_go_importpath "$cur"`)
-      fi
-      ;;
-    'help')
-      if [ "$COMP_CWORD" == 2 ]; then
-        COMPREPLY=($(compgen -W "$cmds $addhelp" -- "$cur"))
-      fi
-      ;;
-    *)
-      if [ "$COMP_CWORD" == 1 ]; then
-        COMPREPLY=($(compgen -W "$cmds $other" -- "$cur"))
-      else
-        _filedir
-      fi
-      ;;
-  esac
-}
-
-complete $filenames -F _go go
-
-# vim:ts=2 sw=2 et syn=sh
diff --git a/misc/bbedit/Go.plist b/misc/bbedit/Go.plist
deleted file mode 100644
index 1220d6e..0000000
--- a/misc/bbedit/Go.plist
+++ /dev/null
@@ -1,104 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-{
-	BBEditDocumentType = "CodelessLanguageModule";
-	BBLMColorsSyntax = YES;
-	BBLMIsCaseSensitive = YES;
-	BBLMKeywordList = (
-		append,
-		bool,
-		break,
-		byte,
-		cap,
-		case,
-		chan,
-		close,
-		complex,
-		complex128,
-		complex64,
-		const,
-		continue,
-		copy,
-		default,
-		defer,
-		delete,
-		else,
-		error,
-		fallthrough,
-		false,
-		float32,
-		float64,
-		for,
-		func,         
-		go,
-		goto,
-		if,
-		iota,
-		imag,
-		import,
-		int,
-		int16,
-		int32,
-		int64,
-		int8,
-		interface,
-		len,
-		make,
-		map,
-		new,
-		nil,
-		package,
-		panic,
-		print,
-		println,
-		range,
-		real,
-		recover,
-		return,
-		rune,
-		select,
-		string,
-		struct,
-		switch,
-		true,
-		type,
-		uint,
-		uint16,
-		uint32,
-		uint64,
-		uint8,
-		uintptr,
-		var,
-	);
-	BBLMLanguageCode = go;
-	"BBLMLanguageDisplayName" = "Go";
-	BBLMScansFunctions = YES;
-	BBLMSuffixMap = (
-		{
-			BBLMLanguageSuffix = ".go";
-		},
-	);
-	"Language Features" = {
-		"Close Block Comments" = "*/";
-		"Close Parameter Lists" = ")";
-		"Close Statement Blocks" = "}";
-		"Close Strings 1" = "`";
-		"Close Strings 2" = "\"";
-		"End-of-line Ends Strings 1" = YES;
-		"End-of-line Ends Strings 2" = YES;
-		"Escape Char in Strings 1" = "\\";
-		"Escape Char in Strings 2" = "\\";
-		"Identifier and Keyword Characters" = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz";
-		"Open Block Comments" = "/*";
-		"Open Line Comments" = "//";
-		"Open Parameter Lists" = "(";
-		"Open Statement Blocks" = "{";
-		"Open Strings 1" = "`";
-		"Open Strings 2" = "\"";
-		"Prefix for Functions" = "func";
-		"Prefix for Procedures" = "func";
-		"Terminator for Prototypes 1" = ";";
-		"Terminator for Prototypes 2" = "";
-	};
-}
diff --git a/misc/benchcmp b/misc/benchcmp
index 28a3739..84d92ee 100755
--- a/misc/benchcmp
+++ b/misc/benchcmp
@@ -1,5 +1,5 @@
 #!/bin/bash
 
 echo 'misc/benchcmp has moved:' >&2
-echo '	go get -u code.google.com/p/go.tools/cmd/benchcmp' >&2
+echo '	go get -u golang.org/x/tools/cmd/benchcmp' >&2
 exit 2
diff --git a/misc/cgo/errors/issue7757.go b/misc/cgo/errors/issue7757.go
new file mode 100644
index 0000000..5eafd22
--- /dev/null
+++ b/misc/cgo/errors/issue7757.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.
+
+package main
+
+/*
+void foo() {}
+*/
+import "C"
+
+func main() {
+	C.foo = C.foo // ERROR HERE
+}
diff --git a/misc/cgo/errors/issue8442.go b/misc/cgo/errors/issue8442.go
new file mode 100644
index 0000000..45daf8e
--- /dev/null
+++ b/misc/cgo/errors/issue8442.go
@@ -0,0 +1,17 @@
+// Copyright 2014 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+// Issue 8442.  Cgo output unhelpful error messages for
+// invalid C preambles.
+
+/*
+void issue8442foo(UNDEF*); // ERROR HERE
+*/
+import "C"
+
+func main() {
+	C.issue8442foo(nil)
+}
diff --git a/misc/cgo/errors/test.bash b/misc/cgo/errors/test.bash
index f0f60c8..c962643 100755
--- a/misc/cgo/errors/test.bash
+++ b/misc/cgo/errors/test.bash
@@ -27,6 +27,8 @@ check() {
 check err1.go
 check err2.go
 check err3.go
+check issue7757.go
+check issue8442.go
 
 rm -rf errs _obj
 exit 0
diff --git a/misc/cgo/test/backdoor/backdoor.go b/misc/cgo/test/backdoor/backdoor.go
index 7398772..3a97349 100644
--- a/misc/cgo/test/backdoor/backdoor.go
+++ b/misc/cgo/test/backdoor/backdoor.go
@@ -4,5 +4,4 @@
 
 package backdoor
 
-func LockedOSThread() bool // in runtime.c
-func Issue7695(x1, x2, x3, x4, x5, x6, x7, x8 uintptr)
+func LockedOSThread() bool // in thunk.s
diff --git a/misc/cgo/test/backdoor/backdoor_gccgo.go b/misc/cgo/test/backdoor/backdoor_gccgo.go
deleted file mode 100644
index 514f76e..0000000
--- a/misc/cgo/test/backdoor/backdoor_gccgo.go
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2014 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// This is the gccgo version of the stub in runtime.c.
-
-// +build gccgo
-
-package backdoor
-
-func Issue7695(x1, x2, x3, x4, x5, x6, x7, x8 uintptr) {}
diff --git a/misc/cgo/test/backdoor/runtime.c b/misc/cgo/test/backdoor/runtime.c
deleted file mode 100644
index 7e6b448..0000000
--- a/misc/cgo/test/backdoor/runtime.c
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2011 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Expose some runtime functions for testing.
-// Must be in a non-cgo-using package so that
-// the go command compiles this file with 6c, not gcc.
-
-// +build gc
-
-typedef char bool;
-
-bool runtime·lockedOSThread(void);
-
-static void
-FLUSH(void*)
-{
-}
-
-void
-·LockedOSThread(bool b)
-{
-	b = runtime·lockedOSThread();
-	FLUSH(&b);
-}
-
-// This is what a cgo-compiled stub declaration looks like.
-void
-·Issue7695(struct{void *y[8*sizeof(void*)];}p)
-{
-	USED(p);
-}
diff --git a/misc/cgo/test/backdoor/thunk.s b/misc/cgo/test/backdoor/thunk.s
new file mode 100644
index 0000000..ae735c8
--- /dev/null
+++ b/misc/cgo/test/backdoor/thunk.s
@@ -0,0 +1,16 @@
+// 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.
+
+// Assembly to get into package runtime without using exported symbols.
+
+// +build amd64 amd64p32 arm 386
+
+#include "textflag.h"
+
+#ifdef GOARCH_arm
+#define JMP B
+#endif
+
+TEXT ·LockedOSThread(SB),NOSPLIT,$0-0
+	JMP	runtime·lockedOSThread(SB)
diff --git a/misc/cgo/test/basic.go b/misc/cgo/test/basic.go
index 79cbf2b..019139d 100644
--- a/misc/cgo/test/basic.go
+++ b/misc/cgo/test/basic.go
@@ -157,3 +157,8 @@ func testUnsignedInt(t *testing.T) {
 		t.Errorf("Incorrect unsigned int - got %x, want %x", a, b)
 	}
 }
+
+// Static (build-time) test that syntax traversal visits all operands of s[i:j:k].
+func sliceOperands(array [2000]int) {
+	_ = array[C.KILO:C.KILO:C.KILO] // no type error
+}
diff --git a/misc/cgo/test/buildid_linux.go b/misc/cgo/test/buildid_linux.go
new file mode 100644
index 0000000..a3a86ed
--- /dev/null
+++ b/misc/cgo/test/buildid_linux.go
@@ -0,0 +1,77 @@
+// 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 cgotest
+
+// Test that we have no more than one build ID.  In the past we used
+// to generate a separate build ID for each package using cgo, and the
+// linker concatenated them all.  We don't want that--we only want
+// one.
+
+import (
+	"bytes"
+	"debug/elf"
+	"os"
+	"testing"
+)
+
+func testBuildID(t *testing.T) {
+	f, err := elf.Open("/proc/self/exe")
+	if err != nil {
+		if os.IsNotExist(err) {
+			t.Skip("no /proc/self/exe")
+		}
+		t.Fatalf("opening /proc/self/exe: ", err)
+	}
+	defer f.Close()
+
+	c := 0
+	for i, s := range f.Sections {
+		if s.Type != elf.SHT_NOTE {
+			continue
+		}
+
+		d, err := s.Data()
+		if err != nil {
+			t.Logf("reading data of note section %d: %v", i, err)
+			continue
+		}
+
+		for len(d) > 0 {
+
+			// ELF standards differ as to the sizes in
+			// note sections.  Both the GNU linker and
+			// gold always generate 32-bit sizes, so that
+			// is what we assume here.
+
+			if len(d) < 12 {
+				t.Logf("note section %d too short (%d < 12)", i, len(d))
+				continue
+			}
+
+			namesz := f.ByteOrder.Uint32(d)
+			descsz := f.ByteOrder.Uint32(d[4:])
+			typ := f.ByteOrder.Uint32(d[8:])
+
+			an := (namesz + 3) &^ 3
+			ad := (descsz + 3) &^ 3
+
+			if int(12+an+ad) > len(d) {
+				t.Logf("note section %d too short for header (%d < 12 + align(%d,4) + align(%d,4))", i, len(d), namesz, descsz)
+				continue
+			}
+
+			// 3 == NT_GNU_BUILD_ID
+			if typ == 3 && namesz == 4 && bytes.Equal(d[12:16], []byte("GNU\000")) {
+				c++
+			}
+
+			d = d[12+an+ad:]
+		}
+	}
+
+	if c > 1 {
+		t.Errorf("found %d build ID notes", c)
+	}
+}
diff --git a/misc/cgo/test/callback.go b/misc/cgo/test/callback.go
index 82ed015..44167e6 100644
--- a/misc/cgo/test/callback.go
+++ b/misc/cgo/test/callback.go
@@ -9,16 +9,21 @@ void callback(void *f);
 void callGoFoo(void);
 void callGoStackCheck(void);
 void callPanic(void);
+void callCgoAllocate(void);
+int callGoReturnVal(void);
+int returnAfterGrow(void);
+int returnAfterGrowFromGo(void);
 */
 import "C"
 
 import (
-	"./backdoor"
 	"path"
 	"runtime"
 	"strings"
 	"testing"
 	"unsafe"
+
+	"./backdoor"
 )
 
 // nestedCall calls into C, back into Go, and finally to f.
@@ -152,11 +157,13 @@ func testCallbackCallers(t *testing.T) {
 	n := 0
 	name := []string{
 		"test.goCallback",
+		"runtime.call16",
 		"runtime.cgocallbackg1",
 		"runtime.cgocallbackg",
 		"runtime.cgocallback_gofunc",
-		"runtime.asmcgocall",
-		"runtime.cgocall",
+		"asmcgocall",
+		"runtime.asmcgocall_errno",
+		"runtime.cgocall_errno",
 		"test._Cfunc_callback",
 		"test.nestedCall",
 		"test.testCallbackCallers",
@@ -181,8 +188,12 @@ func testCallbackCallers(t *testing.T) {
 		if strings.HasPrefix(fname, "_") {
 			fname = path.Base(f.Name()[1:])
 		}
-		if fname != name[i] {
-			t.Errorf("expected function name %s, got %s", name[i], fname)
+		namei := ""
+		if i < len(name) {
+			namei = name[i]
+		}
+		if fname != namei {
+			t.Errorf("stk[%d] = %q, want %q", i, fname, namei)
 		}
 	}
 }
@@ -200,6 +211,52 @@ func testPanicFromC(t *testing.T) {
 	C.callPanic()
 }
 
+func testAllocateFromC(t *testing.T) {
+	C.callCgoAllocate() // crashes or exits on failure
+}
+
+// Test that C code can return a value if it calls a Go function that
+// causes a stack copy.
+func testReturnAfterGrow(t *testing.T) {
+	// Use a new goroutine so that we get a small stack.
+	c := make(chan int)
+	go func() {
+		c <- int(C.returnAfterGrow())
+	}()
+	if got, want := <-c, 123456; got != want {
+		t.Errorf("got %d want %d", got, want)
+	}
+}
+
+// Test that we can return a value from Go->C->Go if the Go code
+// causes a stack copy.
+func testReturnAfterGrowFromGo(t *testing.T) {
+	// Use a new goroutine so that we get a small stack.
+	c := make(chan int)
+	go func() {
+		c <- int(C.returnAfterGrowFromGo())
+	}()
+	if got, want := <-c, 129*128/2; got != want {
+		t.Errorf("got %d want %d", got, want)
+	}
+}
+
+//export goReturnVal
+func goReturnVal() (r C.int) {
+	// Force a stack copy.
+	var f func(int) int
+	f = func(i int) int {
+		var buf [256]byte
+		use(buf[:])
+		if i == 0 {
+			return 0
+		}
+		return i + f(i-1)
+	}
+	r = C.int(f(128))
+	return
+}
+
 func testCallbackStack(t *testing.T) {
 	// Make cgo call and callback with different amount of stack stack available.
 	// We do not do any explicit checks, just ensure that it does not crash.
diff --git a/misc/cgo/test/callback_c.c b/misc/cgo/test/callback_c.c
index dcd4ddd..5bb6425 100644
--- a/misc/cgo/test/callback_c.c
+++ b/misc/cgo/test/callback_c.c
@@ -64,3 +64,19 @@ callGoStackCheck(void)
 	extern void goStackCheck(void);
 	goStackCheck();
 }
+
+int
+returnAfterGrow(void)
+{
+	extern int goReturnVal(void);
+	goReturnVal();
+	return 123456;
+}
+
+int
+returnAfterGrowFromGo(void)
+{
+	extern int goReturnVal(void);
+	return goReturnVal();
+}
+
diff --git a/misc/cgo/test/callback_c_gc.c b/misc/cgo/test/callback_c_gc.c
index 8953b74..28a62c6 100644
--- a/misc/cgo/test/callback_c_gc.c
+++ b/misc/cgo/test/callback_c_gc.c
@@ -5,11 +5,15 @@
 // +build gc
 
 #include "_cgo_export.h"
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
 
 /* Test calling panic from C.  This is what SWIG does.  */
 
 extern void crosscall2(void (*fn)(void *, int), void *, int);
 extern void _cgo_panic(void *, int);
+extern void _cgo_allocate(void *, int);
 
 void
 callPanic(void)
@@ -19,3 +23,58 @@ callPanic(void)
 	crosscall2(_cgo_panic, &a, sizeof a);
 	*(int*)1 = 1;
 }
+
+/* Test calling cgo_allocate from C. This is what SWIG does. */
+
+typedef struct List List;
+struct List
+{
+	List *next;
+	int x;
+};
+
+void
+callCgoAllocate(void)
+{
+	int i;
+	struct { size_t n; void *ret; } a;
+	List *l, *head, **tail;
+
+	// Make sure this doesn't crash.
+	// And make sure it returns non-nil.
+	a.n = 0;
+	a.ret = 0;
+	crosscall2(_cgo_allocate, &a, sizeof a);
+	if(a.ret == 0) {
+		fprintf(stderr, "callCgoAllocate: alloc 0 returned nil\n");
+		exit(2);
+	}
+	
+	head = 0;
+	tail = &head;
+	for(i=0; i<100; i++) {
+		a.n = sizeof *l;
+		crosscall2(_cgo_allocate, &a, sizeof a);
+		l = a.ret;
+		l->x = i;
+		l->next = 0;
+		*tail = l;
+		tail = &l->next;
+	}
+	
+	gc();
+	
+	l = head;
+	for(i=0; i<100; i++) {
+		if(l->x != i) {
+			fprintf(stderr, "callCgoAllocate: lost memory\n");
+			exit(2);
+		}
+		l = l->next;
+	}
+	if(l != 0) {
+		fprintf(stderr, "callCgoAllocate: lost memory\n");
+		exit(2);
+	}
+}
+
diff --git a/misc/cgo/test/callback_c_gccgo.c b/misc/cgo/test/callback_c_gccgo.c
index 0ea7296..d367b7b 100644
--- a/misc/cgo/test/callback_c_gccgo.c
+++ b/misc/cgo/test/callback_c_gccgo.c
@@ -5,13 +5,66 @@
 // +build gccgo
 
 #include "_cgo_export.h"
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
 
 /* Test calling panic from C.  This is what SWIG does.  */
 
 extern void _cgo_panic(const char *);
+extern void *_cgo_allocate(size_t);
 
 void
 callPanic(void)
 {
 	_cgo_panic("panic from C");
 }
+
+/* Test calling cgo_allocate from C. This is what SWIG does. */
+
+typedef struct List List;
+struct List
+{
+	List *next;
+	int x;
+};
+
+void
+callCgoAllocate(void)
+{
+	int i;
+	List *l, *head, **tail;
+	
+	// Make sure this doesn't crash.
+	// And make sure it returns non-nil.
+	if(_cgo_allocate(0) == 0) {
+		fprintf(stderr, "callCgoAllocate: alloc 0 returned nil\n");
+		exit(2);
+	}
+
+	head = 0;
+	tail = &head;
+	for(i=0; i<100; i++) {
+		l = _cgo_allocate(sizeof *l);
+		l->x = i;
+		l->next = 0;
+		*tail = l;
+		tail = &l->next;
+	}
+	
+	gc();
+	
+	l = head;
+	for(i=0; i<100; i++) {
+		if(l->x != i) {
+			fprintf(stderr, "callCgoAllocate: lost memory\n");
+			exit(2);
+		}
+		l = l->next;
+	}
+	if(l != 0) {
+		fprintf(stderr, "callCgoAllocate: lost memory\n");
+		exit(2);
+	}
+}
+
diff --git a/misc/cgo/test/cgo_linux_test.go b/misc/cgo/test/cgo_linux_test.go
index 0a405c7..4fe0db1 100644
--- a/misc/cgo/test/cgo_linux_test.go
+++ b/misc/cgo/test/cgo_linux_test.go
@@ -6,5 +6,6 @@ package cgotest
 
 import "testing"
 
-func TestSetgid(t *testing.T) { testSetgid(t) }
-func Test6997(t *testing.T)   { test6997(t) }
+func TestSetgid(t *testing.T)  { testSetgid(t) }
+func Test6997(t *testing.T)    { test6997(t) }
+func TestBuildID(t *testing.T) { testBuildID(t) }
diff --git a/misc/cgo/test/cgo_test.go b/misc/cgo/test/cgo_test.go
index e2e5a2b..fbdfac8 100644
--- a/misc/cgo/test/cgo_test.go
+++ b/misc/cgo/test/cgo_test.go
@@ -10,49 +10,58 @@ import "testing"
 // so that they can use cgo (import "C").
 // These wrappers are here for gotest to find.
 
-func TestAlign(t *testing.T)               { testAlign(t) }
-func TestConst(t *testing.T)               { testConst(t) }
-func TestEnum(t *testing.T)                { testEnum(t) }
-func TestAtol(t *testing.T)                { testAtol(t) }
-func TestErrno(t *testing.T)               { testErrno(t) }
-func TestMultipleAssign(t *testing.T)      { testMultipleAssign(t) }
-func TestUnsignedInt(t *testing.T)         { testUnsignedInt(t) }
-func TestCallback(t *testing.T)            { testCallback(t) }
-func TestCallbackGC(t *testing.T)          { testCallbackGC(t) }
-func TestCallbackPanic(t *testing.T)       { testCallbackPanic(t) }
-func TestCallbackPanicLoop(t *testing.T)   { testCallbackPanicLoop(t) }
-func TestCallbackPanicLocked(t *testing.T) { testCallbackPanicLocked(t) }
-func TestPanicFromC(t *testing.T)          { testPanicFromC(t) }
-func TestZeroArgCallback(t *testing.T)     { testZeroArgCallback(t) }
-func TestBlocking(t *testing.T)            { testBlocking(t) }
-func Test1328(t *testing.T)                { test1328(t) }
-func TestParallelSleep(t *testing.T)       { testParallelSleep(t) }
-func TestSetEnv(t *testing.T)              { testSetEnv(t) }
-func TestHelpers(t *testing.T)             { testHelpers(t) }
-func TestLibgcc(t *testing.T)              { testLibgcc(t) }
-func Test1635(t *testing.T)                { test1635(t) }
-func TestPrintf(t *testing.T)              { testPrintf(t) }
-func Test4029(t *testing.T)                { test4029(t) }
-func TestBoolAlign(t *testing.T)           { testBoolAlign(t) }
-func Test3729(t *testing.T)                { test3729(t) }
-func Test3775(t *testing.T)                { test3775(t) }
-func TestCthread(t *testing.T)             { testCthread(t) }
-func TestCallbackCallers(t *testing.T)     { testCallbackCallers(t) }
-func Test5227(t *testing.T)                { test5227(t) }
-func TestCflags(t *testing.T)              { testCflags(t) }
-func Test5337(t *testing.T)                { test5337(t) }
-func Test5548(t *testing.T)                { test5548(t) }
-func Test5603(t *testing.T)                { test5603(t) }
-func Test6833(t *testing.T)                { test6833(t) }
-func Test3250(t *testing.T)                { test3250(t) }
-func TestCallbackStack(t *testing.T)       { testCallbackStack(t) }
-func TestFpVar(t *testing.T)               { testFpVar(t) }
-func Test4339(t *testing.T)                { test4339(t) }
-func Test6390(t *testing.T)                { test6390(t) }
-func Test5986(t *testing.T)                { test5986(t) }
-func Test7665(t *testing.T)                { test7665(t) }
-func TestNaming(t *testing.T)              { testNaming(t) }
-func Test7560(t *testing.T)                { test7560(t) }
-func Test7978(t *testing.T)                { test7978(t) }
+func TestAlign(t *testing.T)                 { testAlign(t) }
+func TestConst(t *testing.T)                 { testConst(t) }
+func TestEnum(t *testing.T)                  { testEnum(t) }
+func TestAtol(t *testing.T)                  { testAtol(t) }
+func TestErrno(t *testing.T)                 { testErrno(t) }
+func TestMultipleAssign(t *testing.T)        { testMultipleAssign(t) }
+func TestUnsignedInt(t *testing.T)           { testUnsignedInt(t) }
+func TestCallback(t *testing.T)              { testCallback(t) }
+func TestCallbackGC(t *testing.T)            { testCallbackGC(t) }
+func TestCallbackPanic(t *testing.T)         { testCallbackPanic(t) }
+func TestCallbackPanicLoop(t *testing.T)     { testCallbackPanicLoop(t) }
+func TestCallbackPanicLocked(t *testing.T)   { testCallbackPanicLocked(t) }
+func TestPanicFromC(t *testing.T)            { testPanicFromC(t) }
+func TestAllocateFromC(t *testing.T)         { testAllocateFromC(t) }
+func TestZeroArgCallback(t *testing.T)       { testZeroArgCallback(t) }
+func TestBlocking(t *testing.T)              { testBlocking(t) }
+func Test1328(t *testing.T)                  { test1328(t) }
+func TestParallelSleep(t *testing.T)         { testParallelSleep(t) }
+func TestSetEnv(t *testing.T)                { testSetEnv(t) }
+func TestHelpers(t *testing.T)               { testHelpers(t) }
+func TestLibgcc(t *testing.T)                { testLibgcc(t) }
+func Test1635(t *testing.T)                  { test1635(t) }
+func TestPrintf(t *testing.T)                { testPrintf(t) }
+func Test4029(t *testing.T)                  { test4029(t) }
+func TestBoolAlign(t *testing.T)             { testBoolAlign(t) }
+func Test3729(t *testing.T)                  { test3729(t) }
+func Test3775(t *testing.T)                  { test3775(t) }
+func TestCthread(t *testing.T)               { testCthread(t) }
+func TestCallbackCallers(t *testing.T)       { testCallbackCallers(t) }
+func Test5227(t *testing.T)                  { test5227(t) }
+func TestCflags(t *testing.T)                { testCflags(t) }
+func Test5337(t *testing.T)                  { test5337(t) }
+func Test5548(t *testing.T)                  { test5548(t) }
+func Test5603(t *testing.T)                  { test5603(t) }
+func Test6833(t *testing.T)                  { test6833(t) }
+func Test3250(t *testing.T)                  { test3250(t) }
+func TestCallbackStack(t *testing.T)         { testCallbackStack(t) }
+func TestFpVar(t *testing.T)                 { testFpVar(t) }
+func Test4339(t *testing.T)                  { test4339(t) }
+func Test6390(t *testing.T)                  { test6390(t) }
+func Test5986(t *testing.T)                  { test5986(t) }
+func Test7665(t *testing.T)                  { test7665(t) }
+func TestNaming(t *testing.T)                { testNaming(t) }
+func Test7560(t *testing.T)                  { test7560(t) }
+func Test5242(t *testing.T)                  { test5242(t) }
+func Test8092(t *testing.T)                  { test8092(t) }
+func Test7978(t *testing.T)                  { test7978(t) }
+func Test8694(t *testing.T)                  { test8694(t) }
+func Test8517(t *testing.T)                  { test8517(t) }
+func Test8811(t *testing.T)                  { test8811(t) }
+func TestReturnAfterGrow(t *testing.T)       { testReturnAfterGrow(t) }
+func TestReturnAfterGrowFromGo(t *testing.T) { testReturnAfterGrowFromGo(t) }
+func Test9026(t *testing.T)                  { test9026(t) }
 
 func BenchmarkCgoCall(b *testing.B) { benchCgoCall(b) }
diff --git a/misc/cgo/test/exports.go b/misc/cgo/test/exports.go
index f96c60b..4fe1703 100644
--- a/misc/cgo/test/exports.go
+++ b/misc/cgo/test/exports.go
@@ -5,8 +5,14 @@
 package cgotest
 
 import "C"
+import "runtime"
 
 //export ReturnIntLong
 func ReturnIntLong() (int, C.long) {
 	return 1, 2
 }
+
+//export gc
+func gc() {
+	runtime.GC()
+}
diff --git a/misc/cgo/test/issue5242.go b/misc/cgo/test/issue5242.go
new file mode 100644
index 0000000..fe0a632
--- /dev/null
+++ b/misc/cgo/test/issue5242.go
@@ -0,0 +1,31 @@
+// 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.
+
+// Issue 5242.  Cgo incorrectly computed the alignment of structs
+// with no Go accessible fields as 0, and then panicked on
+// modulo-by-zero computations.
+
+package cgotest
+
+/*
+typedef struct {
+} foo;
+
+typedef struct {
+	int x : 1;
+} bar;
+
+int issue5242(foo f, bar b) {
+	return 5242;
+}
+*/
+import "C"
+
+import "testing"
+
+func test5242(t *testing.T) {
+	if got := C.issue5242(C.foo{}, C.bar{}); got != 5242 {
+		t.Errorf("got %v", got)
+	}
+}
diff --git a/misc/cgo/test/issue5548.go b/misc/cgo/test/issue5548.go
index b41f465..c879f2a 100644
--- a/misc/cgo/test/issue5548.go
+++ b/misc/cgo/test/issue5548.go
@@ -14,13 +14,14 @@ import "C"
 //export issue5548FromC
 func issue5548FromC(s string, i int) int {
 	if len(s) == 4 && s == "test" && i == 42 {
-		return 1
+		return 12345
 	}
-	return 0
+	println("got", len(s), i)
+	return 9876
 }
 
 func test5548(t *testing.T) {
-	if C.issue5548_in_c() == 0 {
-		t.Fail()
+	if x := C.issue5548_in_c(); x != 12345 {
+		t.Errorf("issue5548_in_c = %d, want %d", x, 12345)
 	}
 }
diff --git a/misc/cgo/test/issue6997_linux.go b/misc/cgo/test/issue6997_linux.go
index 871bd51..5455f0c 100644
--- a/misc/cgo/test/issue6997_linux.go
+++ b/misc/cgo/test/issue6997_linux.go
@@ -34,7 +34,7 @@ func test6997(t *testing.T) {
 		if r == 0 {
 			t.Error("pthread finished but wasn't cancelled??")
 		}
-	case <-time.After(5 * time.Second):
+	case <-time.After(30 * time.Second):
 		t.Error("hung in pthread_cancel/pthread_join")
 	}
 }
diff --git a/misc/cgo/test/issue7695_test.go b/misc/cgo/test/issue7695_test.go
deleted file mode 100644
index 4bd6f8e..0000000
--- a/misc/cgo/test/issue7695_test.go
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2014 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Demo of deferred C function with untrue prototype
-// breaking stack copying. See golang.org/issue/7695.
-
-package cgotest
-
-import (
-	"testing"
-
-	"./backdoor"
-)
-
-func TestIssue7695(t *testing.T) {
-	defer backdoor.Issue7695(1, 0, 2, 0, 0, 3, 0, 4)
-	recurse(100)
-}
-
-func recurse(n int) {
-	var x [128]int
-	n += x[0]
-	if n > 0 {
-		recurse(n - 1)
-	}
-}
diff --git a/misc/cgo/test/issue7978.go b/misc/cgo/test/issue7978.go
index 432e006..5feed07 100644
--- a/misc/cgo/test/issue7978.go
+++ b/misc/cgo/test/issue7978.go
@@ -83,21 +83,21 @@ func issue7978go() {
 
 func test7978(t *testing.T) {
 	if os.Getenv("GOTRACEBACK") != "2" {
-		t.Fatal("GOTRACEBACK must be 2")
+		t.Fatalf("GOTRACEBACK must be 2")
 	}
 	issue7978sync = 0
 	go issue7978go()
 	// test in c code, before callback
 	issue7978wait(0, 1)
-	issue7978check(t, "runtime.cgocall(", "", 1)
+	issue7978check(t, "runtime.cgocall_errno(", "", 1)
 	// test in go code, during callback
 	issue7978wait(2, 3)
-	issue7978check(t, "test.issue7978cb(", "test.issue7978go", 4)
+	issue7978check(t, "test.issue7978cb(", "test.issue7978go", 3)
 	// test in c code, after callback
 	issue7978wait(4, 5)
-	issue7978check(t, "runtime.cgocall(", "runtime.cgocallback", 1)
+	issue7978check(t, "runtime.cgocall_errno(", "runtime.cgocallback", 1)
 	// test in go code, after return from cgo
 	issue7978wait(6, 7)
-	issue7978check(t, "test.issue7978go(", "", 4)
+	issue7978check(t, "test.issue7978go(", "", 3)
 	atomic.StoreUint32(&issue7978sync, 8)
 }
diff --git a/misc/cgo/test/issue8092.go b/misc/cgo/test/issue8092.go
new file mode 100644
index 0000000..8a14ce6
--- /dev/null
+++ b/misc/cgo/test/issue8092.go
@@ -0,0 +1,36 @@
+// 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.
+
+// Issue 8092. Test that linker defined symbols (e.g., text, data) don't
+// conflict with C symbols.
+
+package cgotest
+
+/*
+char text[] = "text";
+char data[] = "data";
+char *ctext(void) { return text; }
+char *cdata(void) { return data; }
+*/
+import "C"
+
+import "testing"
+
+func test8092(t *testing.T) {
+	tests := []struct {
+		s    string
+		a, b *C.char
+	}{
+		{"text", &C.text[0], C.ctext()},
+		{"data", &C.data[0], C.cdata()},
+	}
+	for _, test := range tests {
+		if test.a != test.b {
+			t.Errorf("%s: pointer mismatch: %v != %v", test.s, test.a, test.b)
+		}
+		if got := C.GoString(test.a); got != test.s {
+			t.Errorf("%s: points at %#v, want %#v", test.s, got, test.s)
+		}
+	}
+}
diff --git a/misc/cgo/test/issue8428.go b/misc/cgo/test/issue8428.go
new file mode 100644
index 0000000..a3dc575
--- /dev/null
+++ b/misc/cgo/test/issue8428.go
@@ -0,0 +1,52 @@
+// 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 test fails on older versions of OS X because they use older buggy
+// versions of Clang that emit ambiguous DWARF info.  See issue 8611.
+// +build !darwin
+
+package cgotest
+
+// Issue 8428.  Cgo inconsistently translated zero size arrays.
+
+/*
+struct issue8428one {
+	char b;
+	char rest[];
+};
+
+struct issue8428two {
+	void *p;
+	char b;
+	char rest[0];
+};
+
+struct issue8428three {
+	char w[1][2][3][0];
+	char x[2][3][0][1];
+	char y[3][0][1][2];
+	char z[0][1][2][3];
+};
+*/
+import "C"
+
+import "unsafe"
+
+var _ = C.struct_issue8428one{
+	b:    C.char(0),
+	rest: [0]C.char{},
+}
+
+var _ = C.struct_issue8428two{
+	p:    unsafe.Pointer(nil),
+	b:    C.char(0),
+	rest: [0]C.char{},
+}
+
+var _ = C.struct_issue8428three{
+	w: [1][2][3][0]C.char{},
+	x: [2][3][0][1]C.char{},
+	y: [3][0][1][2]C.char{},
+	z: [0][1][2][3]C.char{},
+}
diff --git a/misc/cgo/test/issue8517.go b/misc/cgo/test/issue8517.go
new file mode 100644
index 0000000..4e431df
--- /dev/null
+++ b/misc/cgo/test/issue8517.go
@@ -0,0 +1,13 @@
+// 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.
+
+// +build !windows
+
+package cgotest
+
+import "testing"
+
+func test8517(t *testing.T) {
+	t.Skip("skipping windows only test")
+}
diff --git a/misc/cgo/test/issue8517_windows.c b/misc/cgo/test/issue8517_windows.c
new file mode 100644
index 0000000..a0b94c1
--- /dev/null
+++ b/misc/cgo/test/issue8517_windows.c
@@ -0,0 +1,24 @@
+// 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 "windows.h"
+
+extern void testHandleLeaksCallback();
+
+DWORD WINAPI testHandleLeaksFunc(LPVOID lpThreadParameter)
+{
+	int i;
+	for(i = 0; i < 100; i++) {
+		testHandleLeaksCallback();
+	}
+	return 0;
+}
+
+void testHandleLeaks()
+{
+	HANDLE h;
+	h = CreateThread(NULL, 0, &testHandleLeaksFunc, 0, 0, NULL);
+	WaitForSingleObject(h, INFINITE);
+	CloseHandle(h);
+}
diff --git a/misc/cgo/test/issue8517_windows.go b/misc/cgo/test/issue8517_windows.go
new file mode 100644
index 0000000..3782631
--- /dev/null
+++ b/misc/cgo/test/issue8517_windows.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 cgotest
+
+//void testHandleLeaks();
+import "C"
+
+import (
+	"syscall"
+	"testing"
+	"unsafe"
+)
+
+var issue8517counter int
+
+var (
+	kernel32              = syscall.MustLoadDLL("kernel32.dll")
+	getProcessHandleCount = kernel32.MustFindProc("GetProcessHandleCount")
+)
+
+func processHandleCount(t *testing.T) int {
+	const current_process = ^uintptr(0)
+	var c uint32
+	r, _, err := getProcessHandleCount.Call(current_process, uintptr(unsafe.Pointer(&c)))
+	if r == 0 {
+		t.Fatal(err)
+	}
+	return int(c)
+}
+
+func test8517(t *testing.T) {
+	c1 := processHandleCount(t)
+	C.testHandleLeaks()
+	c2 := processHandleCount(t)
+	if c1+issue8517counter <= c2 {
+		t.Fatalf("too many handles leaked: issue8517counter=%v c1=%v c2=%v", issue8517counter, c1, c2)
+	}
+}
+
+//export testHandleLeaksCallback
+func testHandleLeaksCallback() {
+	issue8517counter++
+}
diff --git a/misc/cgo/test/issue8694.go b/misc/cgo/test/issue8694.go
new file mode 100644
index 0000000..1876f78
--- /dev/null
+++ b/misc/cgo/test/issue8694.go
@@ -0,0 +1,38 @@
+// 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 cgotest
+
+/*
+#include <complex.h>
+
+complex float complexFloatSquared(complex float a) { return a*a; }
+complex double complexDoubleSquared(complex double a) { return a*a; }
+*/
+import "C"
+
+import (
+	"runtime"
+	"testing"
+)
+
+func test8694(t *testing.T) {
+	if runtime.GOARCH == "arm" {
+		t.Skip("test8694 is disabled on ARM because 5l cannot handle thumb library.")
+	}
+	// Really just testing that this compiles, but check answer anyway.
+	x := complex64(2 + 3i)
+	x2 := x * x
+	cx2 := C.complexFloatSquared(x)
+	if cx2 != x2 {
+		t.Errorf("C.complexFloatSquared(%v) = %v, want %v", x, cx2, x2)
+	}
+
+	y := complex128(2 + 3i)
+	y2 := y * y
+	cy2 := C.complexDoubleSquared(y)
+	if cy2 != y2 {
+		t.Errorf("C.complexDoubleSquared(%v) = %v, want %v", y, cy2, y2)
+	}
+}
diff --git a/misc/cgo/test/issue8811.c b/misc/cgo/test/issue8811.c
new file mode 100644
index 0000000..584bb39
--- /dev/null
+++ b/misc/cgo/test/issue8811.c
@@ -0,0 +1,8 @@
+// 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.
+
+int issue8811Initialized = 0;
+
+void issue8811Init() {
+}
diff --git a/misc/cgo/test/issue8811.go b/misc/cgo/test/issue8811.go
new file mode 100644
index 0000000..2e217d9
--- /dev/null
+++ b/misc/cgo/test/issue8811.go
@@ -0,0 +1,22 @@
+// 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 cgotest
+
+/*
+extern int issue8811Initialized;
+extern void issue8811Init();
+
+void issue8811Execute() {
+	if(!issue8811Initialized)
+		issue8811Init();
+}
+*/
+import "C"
+
+import "testing"
+
+func test8811(t *testing.T) {
+	C.issue8811Execute()
+}
diff --git a/misc/cgo/test/issue8828.go b/misc/cgo/test/issue8828.go
new file mode 100644
index 0000000..304797c
--- /dev/null
+++ b/misc/cgo/test/issue8828.go
@@ -0,0 +1,16 @@
+// compile
+
+// 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.
+
+// Issue 8828: compiling a file with -compiler=gccgo fails if a .c file
+// has the same name as compiled directory.
+
+package cgotest
+
+import "./issue8828"
+
+func p() {
+	issue8828.Bar()
+}
diff --git a/misc/cgo/test/issue8828/issue8828.c b/misc/cgo/test/issue8828/issue8828.c
new file mode 100644
index 0000000..2950f87
--- /dev/null
+++ b/misc/cgo/test/issue8828/issue8828.c
@@ -0,0 +1,7 @@
+// Copyright 2014 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+void foo()
+{
+}
diff --git a/misc/cgo/test/issue8828/trivial.go b/misc/cgo/test/issue8828/trivial.go
new file mode 100644
index 0000000..e7b9a4e
--- /dev/null
+++ b/misc/cgo/test/issue8828/trivial.go
@@ -0,0 +1,8 @@
+package issue8828
+
+//void foo();
+import "C"
+
+func Bar() {
+	C.foo()
+}
diff --git a/misc/cgo/test/issue9026.go b/misc/cgo/test/issue9026.go
new file mode 100644
index 0000000..8848d0e
--- /dev/null
+++ b/misc/cgo/test/issue9026.go
@@ -0,0 +1,9 @@
+package cgotest
+
+import (
+	"testing"
+
+	"./issue9026"
+)
+
+func test9026(t *testing.T) { issue9026.Test(t) }
diff --git a/misc/cgo/test/issue9026/issue9026.go b/misc/cgo/test/issue9026/issue9026.go
new file mode 100644
index 0000000..0af86e6
--- /dev/null
+++ b/misc/cgo/test/issue9026/issue9026.go
@@ -0,0 +1,36 @@
+package issue9026
+
+// This file appears in its own package since the assertion tests the
+// per-package counter used to create fresh identifiers.
+
+/*
+typedef struct {} git_merge_file_input;
+
+typedef struct {} git_merge_file_options;
+
+void git_merge_file(
+        git_merge_file_input *in,
+        git_merge_file_options *opts) {}
+*/
+import "C"
+import (
+	"fmt"
+	"testing"
+)
+
+func Test(t *testing.T) {
+	var in C.git_merge_file_input
+	var opts *C.git_merge_file_options
+	C.git_merge_file(&in, opts)
+
+	// Test that the generated type names are deterministic.
+	// (Previously this would fail about 10% of the time.)
+	//
+	// Brittle: the assertion may fail spuriously when the algorithm
+	// changes, but should remain stable otherwise.
+	got := fmt.Sprintf("%T %T", in, opts)
+	want := "issue9026._Ctype_struct___0 *issue9026._Ctype_struct___1"
+	if got != want {
+		t.Errorf("Non-deterministic type names: got %s, want %s", got, want)
+	}
+}
diff --git a/misc/cgo/testcdefs/cdefstest.c b/misc/cgo/testcdefs/cdefstest.c
index 10cdd66..ce670e7 100644
--- a/misc/cgo/testcdefs/cdefstest.c
+++ b/misc/cgo/testcdefs/cdefstest.c
@@ -6,3 +6,4 @@
 #include "cdefstest.h"
 
 struct CdefsTest test;
+struct PackedTest packed;
diff --git a/misc/cgo/testcdefs/cdefstest.go b/misc/cgo/testcdefs/cdefstest.go
index e6305b7..5e613c7 100644
--- a/misc/cgo/testcdefs/cdefstest.go
+++ b/misc/cgo/testcdefs/cdefstest.go
@@ -35,7 +35,26 @@ struct cdefsTest {
 	// Correct: -> Array [20][20]**int8 -> int8 **array[20][20]
 	char **array5[20][20];
 };
+
+// Test that packed structures can be translated to C correctly too.
+// See issue 8477.
+
+struct packedTest {
+	char first;
+	int second;
+	long long third;
+} __attribute__((packed));
+
+// Test that conflicting type definitions don't cause problems with cgo.
+// See issue 8477.
+
+typedef struct timespec {
+	double bogus;
+} pid_t;
+
 */
 import "C"
 
 type CdefsTest C.struct_cdefsTest
+
+//type PackedTest C.struct_packedTest
diff --git a/misc/cgo/testcdefs/main.c b/misc/cgo/testcdefs/main.c
index 2d3ee4d..594a431 100644
--- a/misc/cgo/testcdefs/main.c
+++ b/misc/cgo/testcdefs/main.c
@@ -17,11 +17,25 @@ struct CdefsOrig {
 	int8 **array5[20][20];
 };
 
+// Packed structs are no longer supported for -cdefs.
+/*
+typedef struct PackedOrig PackedOrig;
+#pragma pack on
+struct PackedOrig {
+	int8 first;
+	int32 second;
+	int64 third;
+};
+#pragma pack off
+*/
+
 void
 main·test(int32 ret)
 {
 	CdefsOrig o;
 	CdefsTest t;
+	// PackedOrig po;
+	// PackedTest pt;
 	
 	ret = 0;
 	if(sizeof(t.array1) != sizeof(o.array1) || offsetof(CdefsTest, array1[0]) != offsetof(CdefsOrig, array1[0])) {
@@ -44,5 +58,19 @@ main·test(int32 ret)
 		runtime·printf("array5: size, offset = %d, %d, want %d, %d\n", sizeof(t.array5), offsetof(CdefsTest, array5[0][0]), sizeof(o.array5), offsetof(CdefsOrig, array5[0][0]));
 		ret = 1;
 	}
+/*
+	if(sizeof(pt.first) != sizeof(po.first) || offsetof(PackedTest, first) != offsetof(PackedOrig, first)) {
+		runtime·printf("first: size, offset = %d, %d, want %d, %d\n", sizeof(pt.first), offsetof(PackedTest, first), sizeof(po.first), offsetof(PackedOrig, first));
+		ret = 1;
+	}
+	if(sizeof(pt.second) != sizeof(po.second) || offsetof(PackedTest, second) != offsetof(PackedOrig, second)) {
+		runtime·printf("second: size, offset = %d, %d, want %d, %d\n", sizeof(pt.second), offsetof(PackedTest, second), sizeof(po.second), offsetof(PackedOrig, second));
+		ret = 1;
+	}
+	if(sizeof(pt.third) != sizeof(po.third) || offsetof(PackedTest, third) != offsetof(PackedOrig, third)) {
+		runtime·printf("third: size, offset = %d, %d, want %d, %d\n", sizeof(pt.third), offsetof(PackedTest, third), sizeof(po.third), offsetof(PackedOrig, third));
+		ret = 1;
+	}
+*/
 	FLUSH(&ret); // flush return value
 }
diff --git a/misc/cgo/testgodefs/anonunion.go b/misc/cgo/testgodefs/anonunion.go
new file mode 100644
index 0000000..7bc736b
--- /dev/null
+++ b/misc/cgo/testgodefs/anonunion.go
@@ -0,0 +1,26 @@
+// 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.
+//
+// +build ignore
+
+package main
+
+// This file tests that when cgo -godefs sees a struct with a field
+// that is an anonymous union, the first field in the union is
+// promoted to become a field of the struct.  See issue 6677 for
+// background.
+
+/*
+typedef struct {
+	union {
+		long l;
+		int c;
+	};
+} t;
+*/
+import "C"
+
+// Input for cgo -godefs.
+
+type T C.t
diff --git a/misc/cgo/testgodefs/issue8478.go b/misc/cgo/testgodefs/issue8478.go
new file mode 100644
index 0000000..92258fd
--- /dev/null
+++ b/misc/cgo/testgodefs/issue8478.go
@@ -0,0 +1,20 @@
+// 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.
+//
+// +build ignore
+
+package main
+
+// Issue 8478.  Test that void* is consistently mapped to *byte.
+
+/*
+typedef struct {
+	void *p;
+	void **q;
+	void ***r;
+} s;
+*/
+import "C"
+
+type Issue8478 C.s
diff --git a/misc/cgo/testgodefs/main.go b/misc/cgo/testgodefs/main.go
new file mode 100644
index 0000000..7faccf2
--- /dev/null
+++ b/misc/cgo/testgodefs/main.go
@@ -0,0 +1,15 @@
+// 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
+
+// Test that the struct field in anonunion.go was promoted.
+var v1 T
+var v2 = v1.L
+
+// Test that P, Q, and R all point to byte.
+var v3 = Issue8478{P: (*byte)(nil), Q: (**byte)(nil), R: (***byte)(nil)}
+
+func main() {
+}
diff --git a/misc/cgo/testgodefs/test.bash b/misc/cgo/testgodefs/test.bash
new file mode 100755
index 0000000..5281b10
--- /dev/null
+++ b/misc/cgo/testgodefs/test.bash
@@ -0,0 +1,20 @@
+# 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.
+
+# We are testing cgo -godefs, which translates Go files that use
+# import "C" into Go files with Go definitions of types defined in the
+# import "C" block.  Add more tests here.
+FILE_PREFIXES="anonunion issue8478"
+
+RM=
+for FP in $FILE_PREFIXES
+do
+  go tool cgo -godefs ${FP}.go > ${FP}_defs.go
+  RM="${RM} ${FP}_defs.go"
+done
+
+go build . && ./testgodefs
+EXIT=$?
+rm -rf _obj testgodefs ${RM}
+exit $EXIT
diff --git a/misc/editors b/misc/editors
new file mode 100644
index 0000000..850ec34
--- /dev/null
+++ b/misc/editors
@@ -0,0 +1,5 @@
+For information about plugins and other support for Go in editors and shells,
+see this page on the Go Wiki:
+
+https://code.google.com/p/go-wiki/wiki/IDEsAndTextEditorPlugins
+
diff --git a/misc/emacs/go-mode-load.el b/misc/emacs/go-mode-load.el
deleted file mode 100644
index 3fc35c1..0000000
--- a/misc/emacs/go-mode-load.el
+++ /dev/null
@@ -1,96 +0,0 @@
-;;; go-mode-load.el --- automatically extracted autoloads
-;;; Commentary:
-
-;; To install go-mode, add the following lines to your .emacs file:
-;;   (add-to-list 'load-path "PATH CONTAINING go-mode-load.el" t)
-;;   (require 'go-mode-load)
-;;
-;; After this, go-mode will be used for files ending in '.go'.
-;;
-;; To compile go-mode from the command line, run the following
-;;   emacs -batch -f batch-byte-compile go-mode.el
-;;
-;; See go-mode.el for documentation.
-;;
-;; To update this file, evaluate the following form
-;;   (let ((generated-autoload-file buffer-file-name)) (update-file-autoloads "go-mode.el"))
-
-;;; Code:
-
-

-;;;### (autoloads (go-download-play godoc gofmt-before-save go-mode)
-;;;;;;  "go-mode" "go-mode.el" (20767 50749))
-;;; Generated autoloads from go-mode.el
-
-(autoload 'go-mode "go-mode" "\
-Major mode for editing Go source text.
-
-This mode provides (not just) basic editing capabilities for
-working with Go code. It offers almost complete syntax
-highlighting, indentation that is almost identical to gofmt,
-proper parsing of the buffer content to allow features such as
-navigation by function, manipulation of comments or detection of
-strings.
-
-Additionally to these core features, it offers various features to
-help with writing Go code. You can directly run buffer content
-through gofmt, read godoc documentation from within Emacs, modify
-and clean up the list of package imports or interact with the
-Playground (uploading and downloading pastes).
-
-The following extra functions are defined:
-
-- `gofmt'
-- `godoc'
-- `go-import-add'
-- `go-remove-unused-imports'
-- `go-goto-imports'
-- `go-play-buffer' and `go-play-region'
-- `go-download-play'
-
-If you want to automatically run `gofmt' before saving a file,
-add the following hook to your emacs configuration:
-
-\(add-hook 'before-save-hook 'gofmt-before-save)
-
-If you're looking for even more integration with Go, namely
-on-the-fly syntax checking, auto-completion and snippets, it is
-recommended to look at goflymake
-\(https://github.com/dougm/goflymake), gocode
-\(https://github.com/nsf/gocode) and yasnippet-go
-\(https://github.com/dominikh/yasnippet-go)
-
-\(fn)" t nil)
-
-(add-to-list 'auto-mode-alist (cons "\\.go\\'" 'go-mode))
-
-(autoload 'gofmt-before-save "go-mode" "\
-Add this to .emacs to run gofmt on the current buffer when saving:
- (add-hook 'before-save-hook 'gofmt-before-save).
-
-Note that this will cause go-mode to get loaded the first time
-you save any file, kind of defeating the point of autoloading.
-
-\(fn)" t nil)
-
-(autoload 'godoc "go-mode" "\
-Show go documentation for a query, much like M-x man.
-
-\(fn QUERY)" t nil)
-
-(autoload 'go-download-play "go-mode" "\
-Downloads a paste from the playground and inserts it in a Go
-buffer. Tries to look for a URL at point.
-
-\(fn URL)" t nil)
-
-;;;***
-

-(provide 'go-mode-load)
-;; Local Variables:
-;; version-control: never
-;; no-byte-compile: t
-;; no-update-autoloads: t
-;; coding: utf-8
-;; End:
-;;; go-mode-load.el ends here
diff --git a/misc/emacs/go-mode.el b/misc/emacs/go-mode.el
deleted file mode 100644
index 6333ff9..0000000
--- a/misc/emacs/go-mode.el
+++ /dev/null
@@ -1,1196 +0,0 @@
-;;; go-mode.el --- Major mode for the Go programming language
-
-;; Copyright 2013 The Go Authors. All rights reserved.
-;; Use of this source code is governed by a BSD-style
-;; license that can be found in the LICENSE file.
-
-(require 'cl)
-(require 'etags)
-(require 'ffap)
-(require 'find-file)
-(require 'ring)
-(require 'url)
-
-;; XEmacs compatibility guidelines
-;; - Minimum required version of XEmacs: 21.5.32
-;;   - Feature that cannot be backported: POSIX character classes in
-;;     regular expressions
-;;   - Functions that could be backported but won't because 21.5.32
-;;     covers them: plenty.
-;;   - Features that are still partly broken:
-;;     - godef will not work correctly if multibyte characters are
-;;       being used
-;;     - Fontification will not handle unicode correctly
-;;
-;; - Do not use \_< and \_> regexp delimiters directly; use
-;;   go--regexp-enclose-in-symbol
-;;
-;; - The character `_` must not be a symbol constituent but a
-;;   character constituent
-;;
-;; - Do not use process-lines
-;;
-;; - Use go--old-completion-list-style when using a plain list as the
-;;   collection for completing-read
-;;
-;; - Use go--kill-whole-line instead of kill-whole-line (called
-;;   kill-entire-line in XEmacs)
-;;
-;; - Use go--position-bytes instead of position-bytes
-(defmacro go--xemacs-p ()
-  `(featurep 'xemacs))
-
-(defalias 'go--kill-whole-line
-  (if (fboundp 'kill-whole-line)
-      #'kill-whole-line
-    #'kill-entire-line))
-
-;; Delete the current line without putting it in the kill-ring.
-(defun go--delete-whole-line (&optional arg)
-  ;; Emacs uses both kill-region and kill-new, Xemacs only uses
-  ;; kill-region. In both cases we turn them into operations that do
-  ;; not modify the kill ring. This solution does depend on the
-  ;; implementation of kill-line, but it's the only viable solution
-  ;; that does not require to write kill-line from scratch.
-  (flet ((kill-region (beg end)
-                      (delete-region beg end))
-         (kill-new (s) ()))
-    (go--kill-whole-line arg)))
-
-;; declare-function is an empty macro that only byte-compile cares
-;; about. Wrap in always false if to satisfy Emacsen without that
-;; macro.
-(if nil
-    (declare-function go--position-bytes "go-mode" (point)))
-
-;; XEmacs unfortunately does not offer position-bytes. We can fall
-;; back to just using (point), but it will be incorrect as soon as
-;; multibyte characters are being used.
-(if (fboundp 'position-bytes)
-    (defalias 'go--position-bytes #'position-bytes)
-  (defun go--position-bytes (point) point))
-
-(defun go--old-completion-list-style (list)
-  (mapcar (lambda (x) (cons x nil)) list))
-
-;; GNU Emacs 24 has prog-mode, older GNU Emacs and XEmacs do not, so
-;; copy its definition for those.
-(if (not (fboundp 'prog-mode))
-    (define-derived-mode prog-mode fundamental-mode "Prog"
-      "Major mode for editing source code."
-      (set (make-local-variable 'require-final-newline) mode-require-final-newline)
-      (set (make-local-variable 'parse-sexp-ignore-comments) t)
-      (setq bidi-paragraph-direction 'left-to-right)))
-
-(defun go--regexp-enclose-in-symbol (s)
-  ;; XEmacs does not support \_<, GNU Emacs does. In GNU Emacs we make
-  ;; extensive use of \_< to support unicode in identifiers. Until we
-  ;; come up with a better solution for XEmacs, this solution will
-  ;; break fontification in XEmacs for identifiers such as "typeµ".
-  ;; XEmacs will consider "type" a keyword, GNU Emacs won't.
-
-  (if (go--xemacs-p)
-      (concat "\\<" s "\\>")
-    (concat "\\_<" s "\\_>")))
-
-;; Move up one level of parentheses.
-(defun go-goto-opening-parenthesis (&optional legacy-unused)
-  ;; The old implementation of go-goto-opening-parenthesis had an
-  ;; optional argument to speed up the function. It didn't change the
-  ;; function's outcome.
-
-  ;; Silently fail if there's no matching opening parenthesis.
-  (condition-case nil
-      (backward-up-list)
-    (scan-error nil)))
-
-
-(defconst go-dangling-operators-regexp "[^-]-\\|[^+]\\+\\|[/*&><.=|^]")
-(defconst go-identifier-regexp "[[:word:][:multibyte:]]+")
-(defconst go-label-regexp go-identifier-regexp)
-(defconst go-type-regexp "[[:word:][:multibyte:]*]+")
-(defconst go-func-regexp (concat (go--regexp-enclose-in-symbol "func") "\\s *\\(" go-identifier-regexp "\\)"))
-(defconst go-func-meth-regexp (concat
-                               (go--regexp-enclose-in-symbol "func") "\\s *\\(?:(\\s *"
-                               "\\(" go-identifier-regexp "\\s +\\)?" go-type-regexp
-                               "\\s *)\\s *\\)?\\("
-                               go-identifier-regexp
-                               "\\)("))
-(defconst go-builtins
-  '("append" "cap"   "close"   "complex" "copy"
-    "delete" "imag"  "len"     "make"    "new"
-    "panic"  "print" "println" "real"    "recover")
-  "All built-in functions in the Go language. Used for font locking.")
-
-(defconst go-mode-keywords
-  '("break"    "default"     "func"   "interface" "select"
-    "case"     "defer"       "go"     "map"       "struct"
-    "chan"     "else"        "goto"   "package"   "switch"
-    "const"    "fallthrough" "if"     "range"     "type"
-    "continue" "for"         "import" "return"    "var")
-  "All keywords in the Go language.  Used for font locking.")
-
-(defconst go-constants '("nil" "true" "false" "iota"))
-(defconst go-type-name-regexp (concat "\\(?:[*(]\\)*\\(?:" go-identifier-regexp "\\.\\)?\\(" go-identifier-regexp "\\)"))
-
-(defvar go-dangling-cache)
-(defvar go-godoc-history nil)
-(defvar go--coverage-current-file-name)
-
-(defgroup go nil
-  "Major mode for editing Go code"
-  :group 'languages)
-
-(defgroup go-cover nil
-  "Options specific to `cover`"
-  :group 'go)
-
-(defcustom go-fontify-function-calls t
-  "Fontify function and method calls if this is non-nil."
-  :type 'boolean
-  :group 'go)
-
-(defcustom go-mode-hook nil
-  "Hook called by `go-mode'."
-  :type 'hook
-  :group 'go)
-
-(defcustom go-command "go"
-  "The 'go' command.  Some users have multiple Go development
-trees and invoke the 'go' tool via a wrapper that sets GOROOT and
-GOPATH based on the current directory.  Such users should
-customize this variable to point to the wrapper script."
-  :type 'string
-  :group 'go)
-
-(defcustom gofmt-command "gofmt"
-  "The 'gofmt' command.  Some users may replace this with 'goimports'
-from https://github.com/bradfitz/goimports."
-  :type 'string
-  :group 'go)
-
-(defcustom go-other-file-alist
-  '(("_test\\.go\\'" (".go"))
-    ("\\.go\\'" ("_test.go")))
-  "See the documentation of `ff-other-file-alist' for details."
-  :type '(repeat (list regexp (choice (repeat string) function)))
-  :group 'go)
-
-(defface go-coverage-untracked
-  '((t (:foreground "#505050")))
-  "Coverage color of untracked code."
-  :group 'go-cover)
-
-(defface go-coverage-0
-  '((t (:foreground "#c00000")))
-  "Coverage color for uncovered code."
-  :group 'go-cover)
-(defface go-coverage-1
-  '((t (:foreground "#808080")))
-  "Coverage color for covered code with weight 1."
-  :group 'go-cover)
-(defface go-coverage-2
-  '((t (:foreground "#748c83")))
-  "Coverage color for covered code with weight 2."
-  :group 'go-cover)
-(defface go-coverage-3
-  '((t (:foreground "#689886")))
-  "Coverage color for covered code with weight 3."
-  :group 'go-cover)
-(defface go-coverage-4
-  '((t (:foreground "#5ca489")))
-  "Coverage color for covered code with weight 4."
-  :group 'go-cover)
-(defface go-coverage-5
-  '((t (:foreground "#50b08c")))
-  "Coverage color for covered code with weight 5."
-  :group 'go-cover)
-(defface go-coverage-6
-  '((t (:foreground "#44bc8f")))
-  "Coverage color for covered code with weight 6."
-  :group 'go-cover)
-(defface go-coverage-7
-  '((t (:foreground "#38c892")))
-  "Coverage color for covered code with weight 7."
-  :group 'go-cover)
-(defface go-coverage-8
-  '((t (:foreground "#2cd495")))
-  "Coverage color for covered code with weight 8.
-For mode=set, all covered lines will have this weight."
-  :group 'go-cover)
-(defface go-coverage-9
-  '((t (:foreground "#20e098")))
-  "Coverage color for covered code with weight 9."
-  :group 'go-cover)
-(defface go-coverage-10
-  '((t (:foreground "#14ec9b")))
-  "Coverage color for covered code with weight 10."
-  :group 'go-cover)
-(defface go-coverage-covered
-  '((t (:foreground "#2cd495")))
-  "Coverage color of covered code."
-  :group 'go-cover)
-
-(defvar go-mode-syntax-table
-  (let ((st (make-syntax-table)))
-    (modify-syntax-entry ?+  "." st)
-    (modify-syntax-entry ?-  "." st)
-    (modify-syntax-entry ?%  "." st)
-    (modify-syntax-entry ?&  "." st)
-    (modify-syntax-entry ?|  "." st)
-    (modify-syntax-entry ?^  "." st)
-    (modify-syntax-entry ?!  "." st)
-    (modify-syntax-entry ?=  "." st)
-    (modify-syntax-entry ?<  "." st)
-    (modify-syntax-entry ?>  "." st)
-    (modify-syntax-entry ?/ (if (go--xemacs-p) ". 1456" ". 124b") st)
-    (modify-syntax-entry ?*  ". 23" st)
-    (modify-syntax-entry ?\n "> b" st)
-    (modify-syntax-entry ?\" "\"" st)
-    (modify-syntax-entry ?\' "\"" st)
-    (modify-syntax-entry ?`  "\"" st)
-    (modify-syntax-entry ?\\ "\\" st)
-    ;; It would be nicer to have _ as a symbol constituent, but that
-    ;; would trip up XEmacs, which does not support the \_< anchor
-    (modify-syntax-entry ?_  "w" st)
-
-    st)
-  "Syntax table for Go mode.")
-
-(defun go--build-font-lock-keywords ()
-  ;; we cannot use 'symbols in regexp-opt because GNU Emacs <24
-  ;; doesn't understand that
-  (append
-   `((,(go--regexp-enclose-in-symbol (regexp-opt go-mode-keywords t)) . font-lock-keyword-face)
-     (,(concat "\\(" (go--regexp-enclose-in-symbol (regexp-opt go-builtins t)) "\\)[[:space:]]*(") 1 font-lock-builtin-face)
-     (,(go--regexp-enclose-in-symbol (regexp-opt go-constants t)) . font-lock-constant-face)
-     (,go-func-regexp 1 font-lock-function-name-face)) ;; function (not method) name
-
-   (if go-fontify-function-calls
-       `((,(concat "\\(" go-identifier-regexp "\\)[[:space:]]*(") 1 font-lock-function-name-face) ;; function call/method name
-         (,(concat "[^[:word:][:multibyte:]](\\(" go-identifier-regexp "\\))[[:space:]]*(") 1 font-lock-function-name-face)) ;; bracketed function call
-     `((,go-func-meth-regexp 2 font-lock-function-name-face))) ;; method name
-
-   `(
-     ("\\(`[^`]*`\\)" 1 font-lock-multiline) ;; raw string literal, needed for font-lock-syntactic-keywords
-     (,(concat (go--regexp-enclose-in-symbol "type") "[[:space:]]+\\([^[:space:]]+\\)") 1 font-lock-type-face) ;; types
-     (,(concat (go--regexp-enclose-in-symbol "type") "[[:space:]]+" go-identifier-regexp "[[:space:]]*" go-type-name-regexp) 1 font-lock-type-face) ;; types
-     (,(concat "[^[:word:][:multibyte:]]\\[\\([[:digit:]]+\\|\\.\\.\\.\\)?\\]" go-type-name-regexp) 2 font-lock-type-face) ;; Arrays/slices
-     (,(concat "\\(" go-identifier-regexp "\\)" "{") 1 font-lock-type-face)
-     (,(concat (go--regexp-enclose-in-symbol "map") "\\[[^]]+\\]" go-type-name-regexp) 1 font-lock-type-face) ;; map value type
-     (,(concat (go--regexp-enclose-in-symbol "map") "\\[" go-type-name-regexp) 1 font-lock-type-face) ;; map key type
-     (,(concat (go--regexp-enclose-in-symbol "chan") "[[:space:]]*\\(?:<-\\)?" go-type-name-regexp) 1 font-lock-type-face) ;; channel type
-     (,(concat (go--regexp-enclose-in-symbol "\\(?:new\\|make\\)") "\\(?:[[:space:]]\\|)\\)*(" go-type-name-regexp) 1 font-lock-type-face) ;; new/make type
-     ;; TODO do we actually need this one or isn't it just a function call?
-     (,(concat "\\.\\s *(" go-type-name-regexp) 1 font-lock-type-face) ;; Type conversion
-     (,(concat (go--regexp-enclose-in-symbol "func") "[[:space:]]+(" go-identifier-regexp "[[:space:]]+" go-type-name-regexp ")") 1 font-lock-type-face) ;; Method receiver
-     (,(concat (go--regexp-enclose-in-symbol "func") "[[:space:]]+(" go-type-name-regexp ")") 1 font-lock-type-face) ;; Method receiver without variable name
-     ;; Like the original go-mode this also marks compound literal
-     ;; fields. There, it was marked as to fix, but I grew quite
-     ;; accustomed to it, so it'll stay for now.
-     (,(concat "^[[:space:]]*\\(" go-label-regexp "\\)[[:space:]]*:\\(\\S.\\|$\\)") 1 font-lock-constant-face) ;; Labels and compound literal fields
-     (,(concat (go--regexp-enclose-in-symbol "\\(goto\\|break\\|continue\\)") "[[:space:]]*\\(" go-label-regexp "\\)") 2 font-lock-constant-face)))) ;; labels in goto/break/continue
-
-(defconst go--font-lock-syntactic-keywords
-  ;; Override syntax property of raw string literal contents, so that
-  ;; backslashes have no special meaning in ``. Used in Emacs 23 or older.
-  '((go--match-raw-string-literal
-     (1 (7 . ?`))
-     (2 (15 . nil))  ;; 15 = "generic string"
-     (3 (7 . ?`)))))
-
-(defvar go-mode-map
-  (let ((m (make-sparse-keymap)))
-    (define-key m "}" #'go-mode-insert-and-indent)
-    (define-key m ")" #'go-mode-insert-and-indent)
-    (define-key m "," #'go-mode-insert-and-indent)
-    (define-key m ":" #'go-mode-insert-and-indent)
-    (define-key m "=" #'go-mode-insert-and-indent)
-    (define-key m (kbd "C-c C-a") #'go-import-add)
-    (define-key m (kbd "C-c C-j") #'godef-jump)
-    (define-key m (kbd "C-x 4 C-c C-j") #'godef-jump-other-window)
-    (define-key m (kbd "C-c C-d") #'godef-describe)
-    m)
-  "Keymap used by Go mode to implement electric keys.")
-
-(defun go-mode-insert-and-indent (key)
-  "Invoke the global binding of KEY, then reindent the line."
-
-  (interactive (list (this-command-keys)))
-  (call-interactively (lookup-key (current-global-map) key))
-  (indent-according-to-mode))
-
-(defmacro go-paren-level ()
-  `(car (syntax-ppss)))
-
-(defmacro go-in-string-or-comment-p ()
-  `(nth 8 (syntax-ppss)))
-
-(defmacro go-in-string-p ()
-  `(nth 3 (syntax-ppss)))
-
-(defmacro go-in-comment-p ()
-  `(nth 4 (syntax-ppss)))
-
-(defmacro go-goto-beginning-of-string-or-comment ()
-  `(goto-char (nth 8 (syntax-ppss))))
-
-(defun go--backward-irrelevant (&optional stop-at-string)
-  "Skips backwards over any characters that are irrelevant for
-indentation and related tasks.
-
-It skips over whitespace, comments, cases and labels and, if
-STOP-AT-STRING is not true, over strings."
-
-  (let (pos (start-pos (point)))
-    (skip-chars-backward "\n\s\t")
-    (if (and (save-excursion (beginning-of-line) (go-in-string-p)) (looking-back "`") (not stop-at-string))
-        (backward-char))
-    (if (and (go-in-string-p) (not stop-at-string))
-        (go-goto-beginning-of-string-or-comment))
-    (if (looking-back "\\*/")
-        (backward-char))
-    (if (go-in-comment-p)
-        (go-goto-beginning-of-string-or-comment))
-    (setq pos (point))
-    (beginning-of-line)
-    (if (or (looking-at (concat "^" go-label-regexp ":")) (looking-at "^[[:space:]]*\\(case .+\\|default\\):"))
-        (end-of-line 0)
-      (goto-char pos))
-    (if (/= start-pos (point))
-        (go--backward-irrelevant stop-at-string))
-    (/= start-pos (point))))
-
-(defun go--buffer-narrowed-p ()
-  "Return non-nil if the current buffer is narrowed."
-  (/= (buffer-size)
-      (- (point-max)
-         (point-min))))
-
-(defun go--match-raw-string-literal (end)
-  "Search for a raw string literal. Set point to the end of the
-occurence found on success. Returns nil on failure."
-  (when (search-forward "`" end t)
-    (goto-char (match-beginning 0))
-    (if (go-in-string-or-comment-p)
-        (progn (goto-char (match-end 0))
-               (go--match-raw-string-literal end))
-      (when (looking-at "\\(`\\)\\([^`]*\\)\\(`\\)")
-        (goto-char (match-end 0))
-        t))))
-
-(defun go-previous-line-has-dangling-op-p ()
-  "Returns non-nil if the current line is a continuation line."
-  (let* ((cur-line (line-number-at-pos))
-         (val (gethash cur-line go-dangling-cache 'nope)))
-    (if (or (go--buffer-narrowed-p) (equal val 'nope))
-        (save-excursion
-          (beginning-of-line)
-          (go--backward-irrelevant t)
-          (setq val (looking-back go-dangling-operators-regexp))
-          (if (not (go--buffer-narrowed-p))
-              (puthash cur-line val go-dangling-cache))))
-    val))
-
-(defun go--at-function-definition ()
-  "Return non-nil if point is on the opening curly brace of a
-function definition.
-
-We do this by first calling (beginning-of-defun), which will take
-us to the start of *some* function. We then look for the opening
-curly brace of that function and compare its position against the
-curly brace we are checking. If they match, we return non-nil."
-  (if (= (char-after) ?\{)
-      (save-excursion
-        (let ((old-point (point))
-              start-nesting)
-          (beginning-of-defun)
-          (when (looking-at "func ")
-            (setq start-nesting (go-paren-level))
-            (skip-chars-forward "^{")
-            (while (> (go-paren-level) start-nesting)
-              (forward-char)
-              (skip-chars-forward "^{") 0)
-            (if (and (= (go-paren-level) start-nesting) (= old-point (point)))
-                t))))))
-
-(defun go--indentation-for-opening-parenthesis ()
-  "Return the semantic indentation for the current opening parenthesis.
-
-If point is on an opening curly brace and said curly brace
-belongs to a function declaration, the indentation of the func
-keyword will be returned. Otherwise the indentation of the
-current line will be returned."
-  (save-excursion
-    (if (go--at-function-definition)
-        (progn
-          (beginning-of-defun)
-          (current-indentation))
-      (current-indentation))))
-
-(defun go-indentation-at-point ()
-  (save-excursion
-    (let (start-nesting)
-      (back-to-indentation)
-      (setq start-nesting (go-paren-level))
-
-      (cond
-       ((go-in-string-p)
-        (current-indentation))
-       ((looking-at "[])}]")
-        (go-goto-opening-parenthesis)
-        (if (go-previous-line-has-dangling-op-p)
-            (- (current-indentation) tab-width)
-          (go--indentation-for-opening-parenthesis)))
-       ((progn (go--backward-irrelevant t) (looking-back go-dangling-operators-regexp))
-        ;; only one nesting for all dangling operators in one operation
-        (if (go-previous-line-has-dangling-op-p)
-            (current-indentation)
-          (+ (current-indentation) tab-width)))
-       ((zerop (go-paren-level))
-        0)
-       ((progn (go-goto-opening-parenthesis) (< (go-paren-level) start-nesting))
-        (if (go-previous-line-has-dangling-op-p)
-            (current-indentation)
-          (+ (go--indentation-for-opening-parenthesis) tab-width)))
-       (t
-        (current-indentation))))))
-
-(defun go-mode-indent-line ()
-  (interactive)
-  (let (indent
-        shift-amt
-        (pos (- (point-max) (point)))
-        (point (point))
-        (beg (line-beginning-position)))
-    (back-to-indentation)
-    (if (go-in-string-or-comment-p)
-        (goto-char point)
-      (setq indent (go-indentation-at-point))
-      (if (looking-at (concat go-label-regexp ":\\([[:space:]]*/.+\\)?$\\|case .+:\\|default:"))
-          (decf indent tab-width))
-      (setq shift-amt (- indent (current-column)))
-      (if (zerop shift-amt)
-          nil
-        (delete-region beg (point))
-        (indent-to indent))
-      ;; If initial point was within line's indentation,
-      ;; position after the indentation.  Else stay at same point in text.
-      (if (> (- (point-max) pos) (point))
-          (goto-char (- (point-max) pos))))))
-
-(defun go-beginning-of-defun (&optional count)
-  (setq count (or count 1))
-  (let ((first t)
-        failure)
-    (dotimes (i (abs count))
-      (while (and (not failure)
-                  (or first (go-in-string-or-comment-p)))
-        (if (>= count 0)
-            (progn
-              (go--backward-irrelevant)
-              (if (not (re-search-backward go-func-meth-regexp nil t))
-                  (setq failure t)))
-          (if (looking-at go-func-meth-regexp)
-              (forward-char))
-          (if (not (re-search-forward go-func-meth-regexp nil t))
-              (setq failure t)))
-        (setq first nil)))
-    (if (< count 0)
-        (beginning-of-line))
-    (not failure)))
-
-(defun go-end-of-defun ()
-  (let (orig-level)
-    ;; It can happen that we're not placed before a function by emacs
-    (if (not (looking-at "func"))
-        (go-beginning-of-defun -1))
-    (skip-chars-forward "^{")
-    (forward-char)
-    (setq orig-level (go-paren-level))
-    (while (>= (go-paren-level) orig-level)
-      (skip-chars-forward "^}")
-      (forward-char))))
-
-;;;###autoload
-(define-derived-mode go-mode prog-mode "Go"
-  "Major mode for editing Go source text.
-
-This mode provides (not just) basic editing capabilities for
-working with Go code. It offers almost complete syntax
-highlighting, indentation that is almost identical to gofmt and
-proper parsing of the buffer content to allow features such as
-navigation by function, manipulation of comments or detection of
-strings.
-
-In addition to these core features, it offers various features to
-help with writing Go code. You can directly run buffer content
-through gofmt, read godoc documentation from within Emacs, modify
-and clean up the list of package imports or interact with the
-Playground (uploading and downloading pastes).
-
-The following extra functions are defined:
-
-- `gofmt'
-- `godoc'
-- `go-import-add'
-- `go-remove-unused-imports'
-- `go-goto-imports'
-- `go-play-buffer' and `go-play-region'
-- `go-download-play'
-- `godef-describe' and `godef-jump'
-- `go-coverage'
-
-If you want to automatically run `gofmt' before saving a file,
-add the following hook to your emacs configuration:
-
-\(add-hook 'before-save-hook #'gofmt-before-save)
-
-If you want to use `godef-jump' instead of etags (or similar),
-consider binding godef-jump to `M-.', which is the default key
-for `find-tag':
-
-\(add-hook 'go-mode-hook (lambda ()
-                          (local-set-key (kbd \"M-.\") #'godef-jump)))
-
-Please note that godef is an external dependency. You can install
-it with
-
-go get code.google.com/p/rog-go/exp/cmd/godef
-
-
-If you're looking for even more integration with Go, namely
-on-the-fly syntax checking, auto-completion and snippets, it is
-recommended that you look at goflymake
-\(https://github.com/dougm/goflymake), gocode
-\(https://github.com/nsf/gocode), go-eldoc
-\(github.com/syohex/emacs-go-eldoc) and yasnippet-go
-\(https://github.com/dominikh/yasnippet-go)"
-
-  ;; Font lock
-  (set (make-local-variable 'font-lock-defaults)
-       '(go--build-font-lock-keywords))
-
-  ;; Indentation
-  (set (make-local-variable 'indent-line-function) #'go-mode-indent-line)
-
-  ;; Comments
-  (set (make-local-variable 'comment-start) "// ")
-  (set (make-local-variable 'comment-end)   "")
-  (set (make-local-variable 'comment-use-syntax) t)
-  (set (make-local-variable 'comment-start-skip) "\\(//+\\|/\\*+\\)\\s *")
-
-  (set (make-local-variable 'beginning-of-defun-function) #'go-beginning-of-defun)
-  (set (make-local-variable 'end-of-defun-function) #'go-end-of-defun)
-
-  (set (make-local-variable 'parse-sexp-lookup-properties) t)
-  (if (boundp 'syntax-propertize-function)
-      (set (make-local-variable 'syntax-propertize-function) #'go-propertize-syntax)
-    (set (make-local-variable 'font-lock-syntactic-keywords)
-         go--font-lock-syntactic-keywords)
-    (set (make-local-variable 'font-lock-multiline) t))
-
-  (set (make-local-variable 'go-dangling-cache) (make-hash-table :test 'eql))
-  (add-hook 'before-change-functions (lambda (x y) (setq go-dangling-cache (make-hash-table :test 'eql))) t t)
-
-  ;; ff-find-other-file
-  (setq ff-other-file-alist 'go-other-file-alist)
-
-  (setq imenu-generic-expression
-        '(("type" "^type *\\([^ \t\n\r\f]*\\)" 1)
-          ("func" "^func *\\(.*\\) {" 1)))
-  (imenu-add-to-menubar "Index")
-
-  ;; Go style
-  (setq indent-tabs-mode t)
-
-  ;; Handle unit test failure output in compilation-mode
-  ;;
-  ;; Note the final t argument to add-to-list for append, ie put these at the
-  ;; *ends* of compilation-error-regexp-alist[-alist]. We want go-test to be
-  ;; handled first, otherwise other elements will match that don't work, and
-  ;; those alists are traversed in *reverse* order:
-  ;; http://lists.gnu.org/archive/html/bug-gnu-emacs/2001-12/msg00674.html
-  (when (and (boundp 'compilation-error-regexp-alist)
-             (boundp 'compilation-error-regexp-alist-alist))
-    (add-to-list 'compilation-error-regexp-alist 'go-test t)
-    (add-to-list 'compilation-error-regexp-alist-alist
-                 '(go-test . ("^\t+\\([^()\t\n]+\\):\\([0-9]+\\):? .*$" 1 2)) t)))
-
-;;;###autoload
-(add-to-list 'auto-mode-alist (cons "\\.go\\'" 'go-mode))
-
-(defun go--apply-rcs-patch (patch-buffer)
-  "Apply an RCS-formatted diff from PATCH-BUFFER to the current
-buffer."
-  (let ((target-buffer (current-buffer))
-        ;; Relative offset between buffer line numbers and line numbers
-        ;; in patch.
-        ;;
-        ;; Line numbers in the patch are based on the source file, so
-        ;; we have to keep an offset when making changes to the
-        ;; buffer.
-        ;;
-        ;; Appending lines decrements the offset (possibly making it
-        ;; negative), deleting lines increments it. This order
-        ;; simplifies the forward-line invocations.
-        (line-offset 0))
-    (save-excursion
-      (with-current-buffer patch-buffer
-        (goto-char (point-min))
-        (while (not (eobp))
-          (unless (looking-at "^\\([ad]\\)\\([0-9]+\\) \\([0-9]+\\)")
-            (error "invalid rcs patch or internal error in go--apply-rcs-patch"))
-          (forward-line)
-          (let ((action (match-string 1))
-                (from (string-to-number (match-string 2)))
-                (len  (string-to-number (match-string 3))))
-            (cond
-             ((equal action "a")
-              (let ((start (point)))
-                (forward-line len)
-                (let ((text (buffer-substring start (point))))
-                  (with-current-buffer target-buffer
-                    (decf line-offset len)
-                    (goto-char (point-min))
-                    (forward-line (- from len line-offset))
-                    (insert text)))))
-             ((equal action "d")
-              (with-current-buffer target-buffer
-                (go--goto-line (- from line-offset))
-                (incf line-offset len)
-                (go--delete-whole-line len)))
-             (t
-              (error "invalid rcs patch or internal error in go--apply-rcs-patch")))))))))
-
-(defun gofmt ()
-  "Formats the current buffer according to the gofmt tool."
-
-  (interactive)
-  (let ((tmpfile (make-temp-file "gofmt" nil ".go"))
-        (patchbuf (get-buffer-create "*Gofmt patch*"))
-        (errbuf (get-buffer-create "*Gofmt Errors*"))
-        (coding-system-for-read 'utf-8)
-        (coding-system-for-write 'utf-8))
-
-    (with-current-buffer errbuf
-      (setq buffer-read-only nil)
-      (erase-buffer))
-    (with-current-buffer patchbuf
-      (erase-buffer))
-
-    (write-region nil nil tmpfile)
-
-    ;; We're using errbuf for the mixed stdout and stderr output. This
-    ;; is not an issue because gofmt -w does not produce any stdout
-    ;; output in case of success.
-    (if (zerop (call-process gofmt-command nil errbuf nil "-w" tmpfile))
-        (if (zerop (call-process-region (point-min) (point-max) "diff" nil patchbuf nil "-n" "-" tmpfile))
-            (progn
-              (kill-buffer errbuf)
-              (message "Buffer is already gofmted"))
-          (go--apply-rcs-patch patchbuf)
-          (kill-buffer errbuf)
-          (message "Applied gofmt"))
-      (message "Could not apply gofmt. Check errors for details")
-      (gofmt--process-errors (buffer-file-name) tmpfile errbuf))
-
-    (kill-buffer patchbuf)
-    (delete-file tmpfile)))
-
-
-(defun gofmt--process-errors (filename tmpfile errbuf)
-  ;; Convert the gofmt stderr to something understood by the compilation mode.
-  (with-current-buffer errbuf
-    (goto-char (point-min))
-    (insert "gofmt errors:\n")
-    (while (search-forward-regexp (concat "^\\(" (regexp-quote tmpfile) "\\):") nil t)
-      (replace-match (file-name-nondirectory filename) t t nil 1))
-    (compilation-mode)
-    (display-buffer errbuf)))
-
-;;;###autoload
-(defun gofmt-before-save ()
-  "Add this to .emacs to run gofmt on the current buffer when saving:
- (add-hook 'before-save-hook 'gofmt-before-save).
-
-Note that this will cause go-mode to get loaded the first time
-you save any file, kind of defeating the point of autoloading."
-
-  (interactive)
-  (when (eq major-mode 'go-mode) (gofmt)))
-
-(defun godoc--read-query ()
-  "Read a godoc query from the minibuffer."
-  ;; Compute the default query as the symbol under the cursor.
-  ;; TODO: This does the wrong thing for e.g. multipart.NewReader (it only grabs
-  ;; half) but I see no way to disambiguate that from e.g. foobar.SomeMethod.
-  (let* ((bounds (bounds-of-thing-at-point 'symbol))
-         (symbol (if bounds
-                     (buffer-substring-no-properties (car bounds)
-                                                     (cdr bounds)))))
-    (completing-read (if symbol
-                         (format "godoc (default %s): " symbol)
-                       "godoc: ")
-                     (go--old-completion-list-style (go-packages)) nil nil nil 'go-godoc-history symbol)))
-
-(defun godoc--get-buffer (query)
-  "Get an empty buffer for a godoc query."
-  (let* ((buffer-name (concat "*godoc " query "*"))
-         (buffer (get-buffer buffer-name)))
-    ;; Kill the existing buffer if it already exists.
-    (when buffer (kill-buffer buffer))
-    (get-buffer-create buffer-name)))
-
-(defun godoc--buffer-sentinel (proc event)
-  "Sentinel function run when godoc command completes."
-  (with-current-buffer (process-buffer proc)
-    (cond ((string= event "finished\n")  ;; Successful exit.
-           (goto-char (point-min))
-           (view-mode 1)
-           (display-buffer (current-buffer) t))
-          ((/= (process-exit-status proc) 0)  ;; Error exit.
-           (let ((output (buffer-string)))
-             (kill-buffer (current-buffer))
-             (message (concat "godoc: " output)))))))
-
-;;;###autoload
-(defun godoc (query)
-  "Show go documentation for a query, much like M-x man."
-  (interactive (list (godoc--read-query)))
-  (unless (string= query "")
-    (set-process-sentinel
-     (start-process-shell-command "godoc" (godoc--get-buffer query)
-                                  (concat "godoc " query))
-     'godoc--buffer-sentinel)
-    nil))
-
-(defun go-goto-imports ()
-  "Move point to the block of imports.
-
-If using
-
-  import (
-    \"foo\"
-    \"bar\"
-  )
-
-it will move point directly behind the last import.
-
-If using
-
-  import \"foo\"
-  import \"bar\"
-
-it will move point to the next line after the last import.
-
-If no imports can be found, point will be moved after the package
-declaration."
-  (interactive)
-  ;; FIXME if there's a block-commented import before the real
-  ;; imports, we'll jump to that one.
-
-  ;; Generally, this function isn't very forgiving. it'll bark on
-  ;; extra whitespace. It works well for clean code.
-  (let ((old-point (point)))
-    (goto-char (point-min))
-    (cond
-     ((re-search-forward "^import ()" nil t)
-      (backward-char 1)
-      'block-empty)
-     ((re-search-forward "^import ([^)]+)" nil t)
-      (backward-char 2)
-      'block)
-     ((re-search-forward "\\(^import \\([^\"]+ \\)?\"[^\"]+\"\n?\\)+" nil t)
-      'single)
-     ((re-search-forward "^[[:space:]\n]*package .+?\n" nil t)
-      (message "No imports found, moving point after package declaration")
-      'none)
-     (t
-      (goto-char old-point)
-      (message "No imports or package declaration found. Is this really a Go file?")
-      'fail))))
-
-(defun go-play-buffer ()
-  "Like `go-play-region', but acts on the entire buffer."
-  (interactive)
-  (go-play-region (point-min) (point-max)))
-
-(defun go-play-region (start end)
-  "Send the region to the Playground and stores the resulting
-link in the kill ring."
-  (interactive "r")
-  (let* ((url-request-method "POST")
-         (url-request-extra-headers
-          '(("Content-Type" . "application/x-www-form-urlencoded")))
-         (url-request-data
-          (encode-coding-string
-           (buffer-substring-no-properties start end)
-           'utf-8))
-         (content-buf (url-retrieve
-                       "http://play.golang.org/share"
-                       (lambda (arg)
-                         (cond
-                          ((equal :error (car arg))
-                           (signal 'go-play-error (cdr arg)))
-                          (t
-                           (re-search-forward "\n\n")
-                           (kill-new (format "http://play.golang.org/p/%s" (buffer-substring (point) (point-max))))
-                           (message "http://play.golang.org/p/%s" (buffer-substring (point) (point-max)))))))))))
-
-;;;###autoload
-(defun go-download-play (url)
-  "Downloads a paste from the playground and inserts it in a Go
-buffer. Tries to look for a URL at point."
-  (interactive (list (read-from-minibuffer "Playground URL: " (ffap-url-p (ffap-string-at-point 'url)))))
-  (with-current-buffer
-      (let ((url-request-method "GET") url-request-data url-request-extra-headers)
-        (url-retrieve-synchronously (concat url ".go")))
-    (let ((buffer (generate-new-buffer (concat (car (last (split-string url "/"))) ".go"))))
-      (goto-char (point-min))
-      (re-search-forward "\n\n")
-      (copy-to-buffer buffer (point) (point-max))
-      (kill-buffer)
-      (with-current-buffer buffer
-        (go-mode)
-        (switch-to-buffer buffer)))))
-
-(defun go-propertize-syntax (start end)
-  (save-excursion
-    (goto-char start)
-    (while (search-forward "\\" end t)
-      (put-text-property (1- (point)) (point) 'syntax-table (if (= (char-after) ?`) '(1) '(9))))))
-
-(defun go-import-add (arg import)
-  "Add a new import to the list of imports.
-
-When called with a prefix argument asks for an alternative name
-to import the package as.
-
-If no list exists yet, one will be created if possible.
-
-If an identical import has been commented, it will be
-uncommented, otherwise a new import will be added."
-
-  ;; - If there's a matching `// import "foo"`, uncomment it
-  ;; - If we're in an import() block and there's a matching `"foo"`, uncomment it
-  ;; - Otherwise add a new import, with the appropriate syntax
-  (interactive
-   (list
-    current-prefix-arg
-    (replace-regexp-in-string "^[\"']\\|[\"']$" "" (completing-read "Package: " (go--old-completion-list-style (go-packages))))))
-  (save-excursion
-    (let (as line import-start)
-      (if arg
-          (setq as (read-from-minibuffer "Import as: ")))
-      (if as
-          (setq line (format "%s \"%s\"" as import))
-        (setq line (format "\"%s\"" import)))
-
-      (goto-char (point-min))
-      (if (re-search-forward (concat "^[[:space:]]*//[[:space:]]*import " line "$") nil t)
-          (uncomment-region (line-beginning-position) (line-end-position))
-        (case (go-goto-imports)
-          ('fail (message "Could not find a place to add import."))
-          ('block-empty
-           (insert "\n\t" line "\n"))
-          ('block
-              (save-excursion
-                (re-search-backward "^import (")
-                (setq import-start (point)))
-            (if (re-search-backward (concat "^[[:space:]]*//[[:space:]]*" line "$")  import-start t)
-                (uncomment-region (line-beginning-position) (line-end-position))
-              (insert "\n\t" line)))
-          ('single (insert "import " line "\n"))
-          ('none (insert "\nimport (\n\t" line "\n)\n")))))))
-
-(defun go-root-and-paths ()
-  (let* ((output (split-string (shell-command-to-string (concat go-command " env GOROOT GOPATH"))
-                               "\n"))
-         (root (car output))
-         (paths (split-string (cadr output) ":")))
-    (append (list root) paths)))
-
-(defun go--string-prefix-p (s1 s2 &optional ignore-case)
-  "Return non-nil if S1 is a prefix of S2.
-If IGNORE-CASE is non-nil, the comparison is case-insensitive."
-  (eq t (compare-strings s1 nil nil
-                         s2 0 (length s1) ignore-case)))
-
-(defun go--directory-dirs (dir)
-  "Recursively return all subdirectories in DIR."
-  (if (file-directory-p dir)
-      (let ((dir (directory-file-name dir))
-            (dirs '())
-            (files (directory-files dir nil nil t)))
-        (dolist (file files)
-          (unless (member file '("." ".."))
-            (let ((file (concat dir "/" file)))
-              (if (file-directory-p file)
-                  (setq dirs (append (cons file
-                                           (go--directory-dirs file))
-                                     dirs))))))
-        dirs)
-    '()))
-
-
-(defun go-packages ()
-  (sort
-   (delete-dups
-    (mapcan
-     (lambda (topdir)
-       (let ((pkgdir (concat topdir "/pkg/")))
-         (mapcan (lambda (dir)
-                   (mapcar (lambda (file)
-                             (let ((sub (substring file (length pkgdir) -2)))
-                               (unless (or (go--string-prefix-p "obj/" sub) (go--string-prefix-p "tool/" sub))
-                                 (mapconcat #'identity (cdr (split-string sub "/")) "/"))))
-                           (if (file-directory-p dir)
-                               (directory-files dir t "\\.a$"))))
-                 (if (file-directory-p pkgdir)
-                     (go--directory-dirs pkgdir)))))
-     (go-root-and-paths)))
-   #'string<))
-
-(defun go-unused-imports-lines ()
-  ;; FIXME Technically, -o /dev/null fails in quite some cases (on
-  ;; Windows, when compiling from within GOPATH). Practically,
-  ;; however, it has the same end result: There won't be a
-  ;; compiled binary/archive, and we'll get our import errors when
-  ;; there are any.
-  (reverse (remove nil
-                   (mapcar
-                    (lambda (line)
-                      (if (string-match "^\\(.+\\):\\([[:digit:]]+\\): imported and not used: \".+\".*$" line)
-                          (if (string= (file-truename (match-string 1 line)) (file-truename buffer-file-name))
-                              (string-to-number (match-string 2 line)))))
-                    (split-string (shell-command-to-string
-                                   (concat go-command
-                                           (if (string-match "_test\.go$" buffer-file-truename)
-                                               " test -c"
-                                             " build -o /dev/null"))) "\n")))))
-
-(defun go-remove-unused-imports (arg)
-  "Removes all unused imports. If ARG is non-nil, unused imports
-will be commented, otherwise they will be removed completely."
-  (interactive "P")
-  (save-excursion
-    (let ((cur-buffer (current-buffer)) flymake-state lines)
-      (when (boundp 'flymake-mode)
-        (setq flymake-state flymake-mode)
-        (flymake-mode-off))
-      (save-some-buffers nil (lambda () (equal cur-buffer (current-buffer))))
-      (if (buffer-modified-p)
-          (message "Cannot operate on unsaved buffer")
-        (setq lines (go-unused-imports-lines))
-        (dolist (import lines)
-          (go--goto-line import)
-          (beginning-of-line)
-          (if arg
-              (comment-region (line-beginning-position) (line-end-position))
-            (go--delete-whole-line)))
-        (message "Removed %d imports" (length lines)))
-      (if flymake-state (flymake-mode-on)))))
-
-(defun godef--find-file-line-column (specifier other-window)
-  "Given a file name in the format of `filename:line:column',
-visit FILENAME and go to line LINE and column COLUMN."
-  (if (not (string-match "\\(.+\\):\\([0-9]+\\):\\([0-9]+\\)" specifier))
-      ;; We've only been given a directory name
-      (funcall (if other-window #'find-file-other-window #'find-file) specifier)
-    (let ((filename (match-string 1 specifier))
-          (line (string-to-number (match-string 2 specifier)))
-          (column (string-to-number (match-string 3 specifier))))
-      (with-current-buffer (funcall (if other-window #'find-file-other-window #'find-file) filename)
-        (go--goto-line line)
-        (beginning-of-line)
-        (forward-char (1- column))
-        (if (buffer-modified-p)
-            (message "Buffer is modified, file position might not have been correct"))))))
-
-(defun godef--call (point)
-  "Call godef, acquiring definition position and expression
-description at POINT."
-  (if (go--xemacs-p)
-      (error "godef does not reliably work in XEmacs, expect bad results"))
-  (if (not (buffer-file-name (go--coverage-origin-buffer)))
-      (error "Cannot use godef on a buffer without a file name")
-    (let ((outbuf (get-buffer-create "*godef*")))
-      (with-current-buffer outbuf
-        (erase-buffer))
-      (call-process-region (point-min)
-                           (point-max)
-                           "godef"
-                           nil
-                           outbuf
-                           nil
-                           "-i"
-                           "-t"
-                           "-f"
-                           (file-truename (buffer-file-name (go--coverage-origin-buffer)))
-                           "-o"
-                           (number-to-string (go--position-bytes point)))
-      (with-current-buffer outbuf
-        (split-string (buffer-substring-no-properties (point-min) (point-max)) "\n")))))
-
-(defun godef-describe (point)
-  "Describe the expression at POINT."
-  (interactive "d")
-  (condition-case nil
-      (let ((description (cdr (butlast (godef--call point) 1))))
-        (if (not description)
-            (message "No description found for expression at point")
-          (message "%s" (mapconcat #'identity description "\n"))))
-    (file-error (message "Could not run godef binary"))))
-
-(defun godef-jump (point &optional other-window)
-  "Jump to the definition of the expression at POINT."
-  (interactive "d")
-  (condition-case nil
-      (let ((file (car (godef--call point))))
-        (cond
-         ((string= "-" file)
-          (message "godef: expression is not defined anywhere"))
-         ((string= "godef: no identifier found" file)
-          (message "%s" file))
-         ((go--string-prefix-p "godef: no declaration found for " file)
-          (message "%s" file))
-         ((go--string-prefix-p "error finding import path for " file)
-          (message "%s" file))
-         (t
-          (push-mark)
-          (ring-insert find-tag-marker-ring (point-marker))
-          (godef--find-file-line-column file other-window))))
-    (file-error (message "Could not run godef binary"))))
-
-(defun godef-jump-other-window (point)
-  (interactive "d")
-  (godef-jump point t))
-
-(defun go--goto-line (line)
-  (goto-char (point-min))
-  (forward-line (1- line)))
-
-(defun go--line-column-to-point (line column)
-  (save-excursion
-    (go--goto-line line)
-    (forward-char (1- column))
-    (point)))
-
-(defstruct go--covered
-  start-line start-column end-line end-column covered count)
-
-(defun go--coverage-file ()
-  "Return the coverage file to use, either by reading it from the
-current coverage buffer or by prompting for it."
-  (if (boundp 'go--coverage-current-file-name)
-      go--coverage-current-file-name
-    (read-file-name "Coverage file: " nil nil t)))
-
-(defun go--coverage-origin-buffer ()
-  "Return the buffer to base the coverage on."
-  (or (buffer-base-buffer) (current-buffer)))
-
-(defun go--coverage-face (count divisor)
-  "Return the intensity face for COUNT when using DIVISOR
-to scale it to a range [0,10].
-
-DIVISOR scales the absolute cover count to values from 0 to 10.
-For DIVISOR = 0 the count will always translate to 8."
-  (let* ((norm (cond
-                ((= count 0)
-                 -0.1) ;; Uncovered code, set to -0.1 so n becomes 0.
-                ((= divisor 0)
-                 0.8) ;; covermode=set, set to 0.8 so n becomes 8.
-                (t
-                 (/ (log count) divisor))))
-         (n (1+ (floor (* norm 9))))) ;; Convert normalized count [0,1] to intensity [0,10]
-    (concat "go-coverage-" (number-to-string n))))
-
-(defun go--coverage-make-overlay (range divisor)
-  "Create a coverage overlay for a RANGE of covered/uncovered
-code. Uses DIVISOR to scale absolute counts to a [0,10] scale."
-  (let* ((count (go--covered-count range))
-         (face (go--coverage-face count divisor))
-         (ov (make-overlay (go--line-column-to-point (go--covered-start-line range)
-                                                     (go--covered-start-column range))
-                           (go--line-column-to-point (go--covered-end-line range)
-                                                     (go--covered-end-column range)))))
-
-    (overlay-put ov 'face face)
-    (overlay-put ov 'help-echo (format "Count: %d" count))))
-
-(defun go--coverage-clear-overlays ()
-  "Remove existing overlays and put a single untracked overlay
-over the entire buffer."
-  (remove-overlays)
-  (overlay-put (make-overlay (point-min) (point-max))
-               'face
-               'go-coverage-untracked))
-
-(defun go--coverage-parse-file (coverage-file file-name)
-  "Parse COVERAGE-FILE and extract coverage information and
-divisor for FILE-NAME."
-  (let (ranges
-        (max-count 0))
-    (with-temp-buffer
-      (insert-file-contents coverage-file)
-      (go--goto-line 2) ;; Skip over mode
-      (while (not (eobp))
-        (let* ((parts (split-string (buffer-substring (point-at-bol) (point-at-eol)) ":"))
-               (file (car parts))
-               (rest (split-string (nth 1 parts) "[., ]")))
-
-          (destructuring-bind
-              (start-line start-column end-line end-column num count)
-              (mapcar #'string-to-number rest)
-
-            (when (string= (file-name-nondirectory file) file-name)
-              (if (> count max-count)
-                  (setq max-count count))
-              (push (make-go--covered :start-line start-line
-                                      :start-column start-column
-                                      :end-line end-line
-                                      :end-column end-column
-                                      :covered (/= count 0)
-                                      :count count)
-                    ranges)))
-
-          (forward-line)))
-
-      (list ranges (if (> max-count 0) (log max-count) 0)))))
-
-(defun go-coverage (&optional coverage-file)
-  "Open a clone of the current buffer and overlay it with
-coverage information gathered via go test -coverprofile=COVERAGE-FILE.
-
-If COVERAGE-FILE is nil, it will either be inferred from the
-current buffer if it's already a coverage buffer, or be prompted
-for."
-  (interactive)
-  (let* ((cur-buffer (current-buffer))
-         (origin-buffer (go--coverage-origin-buffer))
-         (gocov-buffer-name (concat (buffer-name origin-buffer) "<gocov>"))
-         (coverage-file (or coverage-file (go--coverage-file)))
-         (ranges-and-divisor (go--coverage-parse-file
-                              coverage-file
-                              (file-name-nondirectory (buffer-file-name origin-buffer))))
-         (cov-mtime (nth 5 (file-attributes coverage-file)))
-         (cur-mtime (nth 5 (file-attributes (buffer-file-name origin-buffer)))))
-
-    (if (< (float-time cov-mtime) (float-time cur-mtime))
-        (message "Coverage file is older than the source file."))
-
-    (with-current-buffer (or (get-buffer gocov-buffer-name)
-                             (make-indirect-buffer origin-buffer gocov-buffer-name t))
-      (set (make-local-variable 'go--coverage-current-file-name) coverage-file)
-
-      (save-excursion
-        (go--coverage-clear-overlays)
-        (dolist (range (car ranges-and-divisor))
-          (go--coverage-make-overlay range (cadr ranges-and-divisor))))
-
-      (if (not (eq cur-buffer (current-buffer)))
-          (display-buffer (current-buffer) #'display-buffer-reuse-window)))))
-
-(provide 'go-mode)
diff --git a/misc/fraise/go.plist b/misc/fraise/go.plist
deleted file mode 100644
index 17f4162..0000000
--- a/misc/fraise/go.plist
+++ /dev/null
@@ -1,92 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
-	<key>beginCommand</key>
-	<string></string>
-	<key>endCommand</key>
-	<string></string>
-	<key>beginInstruction</key>
-	<string></string>
-	<key>endInstruction</key>
-	<string></string>
-	<key>beginVariable</key>
-	<string></string>
-	<key>endVariable</key>
-	<string></string>
-	<key>firstString</key>
-	<string>"</string>
-	<key>secondString</key>
-	<string>'</string>
-	<key>firstSingleLineComment</key>
-	<string>//</string>
-	<key>secondSingleLineComment</key>
-	<string></string>
-	<key>beginFirstMultiLineComment</key>
-	<string>/*</string>
-	<key>endFirstMultiLineComment</key>
-	<string>*/</string>
-	<key>beginSecondMultiLineComment</key>
-	<string></string>
-	<key>endSecondMultiLineComment</key>
-	<string></string>
-	<key>functionDefinition</key>
-	<string>^func\s*.*\(.*\)\s?\{</string>
-	<key>removeFromFunction</key>
-	<string></string>
-	<key>keywordsCaseSensitive</key>
-	<true/>
-	<key>recolourKeywordIfAlreadyColoured</key>
-	<true/>
-	<key>keywords</key>
-	<array>
-		<string>break</string>
-		<string>case</string>
-		<string>chan</string>
-		<string>const</string>
-		<string>continue</string>
-		<string>default</string>
-		<string>defer</string>
-		<string>else</string>
-		<string>fallthrough</string>
-		<string>for</string>
-		<string>func</string>
-		<string>go</string>
-		<string>goto</string>
-		<string>if</string>
-		<string>import</string>
-		<string>interface</string>
-		<string>map</string>
-		<string>package</string>
-		<string>range</string>
-		<string>return</string>
-		<string>select</string>
-		<string>struct</string>
-		<string>switch</string>
-		<string>type</string>
-		<string>var</string>
-		<string>bool</string>
-		<string>byte</string>
-		<string>chan</string>
-		<string>complex64</string>
-		<string>complex128</string>
-		<string>float32</string>
-		<string>float64</string>
-		<string>int</string>
-		<string>int8</string>
-		<string>int16</string>
-		<string>int32</string>
-		<string>int64</string>
-		<string>map</string>
-		<string>string</string>
-		<string>uint</string>
-		<string>uintptr</string>
-		<string>uint8</string>
-		<string>uint16</string>
-		<string>uint32</string>
-		<string>uint64</string>
-	</array>
-	<key>autocompleteWords</key>
-	<array/>
-</dict>
-</plist>
diff --git a/misc/fraise/readme.txt b/misc/fraise/readme.txt
deleted file mode 100644
index fb0f2c8..0000000
--- a/misc/fraise/readme.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-##Instructions for enabling Go syntax highlighting in Fraise.app##
-1. Move go.plist to /Applications/Fraise.app/Contents/Resources/Syntax\ Definitions/
-2. Open /Applications/Fraise.app/Contents/Resources/SyntaxDefinitions.plist and add
-
-	<dict>
-		<key>name</key>
-		<string>GoogleGo</string>
-		<key>file</key>
-		<string>go</string>
-		<key>extensions</key>
-		<string>go</string>
-	</dict>
-	
-before </array>
-
-3. Restart Fraise and you're good to Go!
\ No newline at end of file
diff --git a/misc/kate/go.xml b/misc/kate/go.xml
deleted file mode 100644
index 03f4f2a..0000000
--- a/misc/kate/go.xml
+++ /dev/null
@@ -1,150 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE language SYSTEM "language.dtd">
-<language name="Go" section="Sources"
-          version="1.00" kateversion="2.4"
-          indenter="cstyle"
-          extensions="*.go"
-          mimetype=""
-          priority="5"
-          author="The Go Authors"
-          license="BSD">
-  <highlighting>
-    <list name="keywords">
-      <item> break </item>
-      <item> case </item>
-      <item> chan </item>
-      <item> const </item>
-      <item> continue </item>
-      <item> default </item>
-      <item> defer </item>
-      <item> else </item>
-      <item> fallthrough </item>
-      <item> for </item>
-      <item> func </item>
-      <item> go </item>
-      <item> goto </item>
-      <item> if </item>
-      <item> import </item>
-      <item> interface </item>
-      <item> map </item>
-      <item> package </item>
-      <item> range </item>
-      <item> return </item>
-      <item> select </item>
-      <item> struct </item>
-      <item> switch </item>
-      <item> type </item>
-      <item> var </item>
-    </list>
-    <list name="predeclared">
-      <item> false </item>
-      <item> iota </item>
-      <item> nil </item>
-      <item> true </item>
-    </list>
-    <list name="types">
-      <item> bool </item>
-      <item> byte </item>
-      <item> complex64 </item>
-      <item> complex128 </item>
-      <item> error </item>
-      <item> float32 </item>
-      <item> float64 </item>
-      <item> int </item>
-      <item> int8 </item>
-      <item> int16 </item>
-      <item> int32 </item>
-      <item> int64 </item>
-      <item> rune </item>
-      <item> string </item>
-      <item> uint </item>
-      <item> uintptr </item>
-      <item> uint8 </item>
-      <item> uint16 </item>
-      <item> uint32 </item>
-      <item> uint64 </item>
-    </list>
-    <list name="functions">
-      <item> append </item>
-      <item> cap </item>
-      <item> close </item>
-      <item> complex </item>
-      <item> copy </item>
-      <item> delete </item>
-      <item> imag </item>
-      <item> len </item>
-      <item> make </item>
-      <item> new </item>
-      <item> panic </item>
-      <item> print </item>
-      <item> println </item>
-      <item> real </item>
-      <item> recover </item>
-    </list>
-    <contexts>
-      <context attribute="Normal Text" lineEndContext="#stay" name="Normal">
-        <DetectSpaces />
-        <keyword attribute="Keyword" context="#stay" String="keywords"/>
-        <keyword attribute="Predeclared Identifier" context="#stay"
-          String="predeclared"/>
-        <keyword attribute="Data Type" context="#stay" String="types"/>
-        <keyword attribute="Builtin Function" context="#stay" String="functions"/>
-        <DetectIdentifier />
-        <DetectChar attribute="Symbol" context="#stay" char="{" beginRegion="Brace1" />
-        <DetectChar attribute="Symbol" context="#stay" char="}" endRegion="Brace1" />
-        <HlCOct attribute="Octal" context="#stay"/>
-        <HlCHex attribute="Hex" context="#stay"/>
-        <HlCChar attribute="Char" context="#stay"/>
-        <DetectChar attribute="String" context="String" char="""/>
-        <DetectChar attribute="String" context="Multiline String" char="`"/>
-        <Detect2Chars attribute="Comment" context="Comment 1" char="/" char1="/"/>
-        <Detect2Chars attribute="Comment" context="Comment 2" char="/" char1="*" beginRegion="Comment"/>
-        <AnyChar attribute="Symbol" context="#stay" String=":!%&()+,-/.*<=>?[]|~^;"/>
-      </context>
-
-      <context attribute="String" lineEndContext="#pop" name="String">
-        <LineContinue attribute="String" context="#stay"/>
-        <HlCStringChar attribute="String Char" context="#stay"/>
-        <DetectChar attribute="String" context="#pop" char="""/>
-      </context>
-
-      <context attribute="String" lineEndContext="#stay" name="Multiline String">
-        <LineContinue attribute="String" context="#stay"/>
-        <HlCStringChar attribute="String Char" context="#stay"/>
-        <DetectChar attribute="String" context="#pop" char="`"/>
-      </context>
-
-      <context attribute="Comment" lineEndContext="#pop" name="Comment 1">
-        <LineContinue attribute="Comment" context="#stay"/>
-      </context>
-
-      <context attribute="Comment" lineEndContext="#stay" name="Comment 2">
-        <Detect2Chars attribute="Comment" context="#pop" char="*" char1="/" endRegion="Comment"/>
-      </context>
-    </contexts>
-    <itemDatas>
-      <itemData name="Normal Text"  defStyleNum="dsNormal" spellChecking="false"/>
-      <itemData name="Keyword"      defStyleNum="dsKeyword" spellChecking="false"/>
-      <itemData name="Predeclared Identifier" defStyleNum="dsOthers" spellChecking="false"/>
-      <itemData name="Builtin Function" defStyleNum="dsFunction" spellChecking="false"/>
-      <itemData name="Data Type"    defStyleNum="dsDataType" spellChecking="false"/>
-      <itemData name="Decimal"      defStyleNum="dsDecVal" spellChecking="false"/>
-      <itemData name="Octal"        defStyleNum="dsBaseN" spellChecking="false"/>
-      <itemData name="Hex"          defStyleNum="dsBaseN" spellChecking="false"/>
-      <itemData name="Float"        defStyleNum="dsFloat" spellChecking="false"/>
-      <itemData name="Char"         defStyleNum="dsChar" spellChecking="false"/>
-      <itemData name="String"       defStyleNum="dsString"/>
-      <itemData name="String Char"  defStyleNum="dsChar"/>
-      <itemData name="Comment"      defStyleNum="dsComment"/>
-      <itemData name="Symbol"       defStyleNum="dsNormal" spellChecking="false"/>
-      <itemData name="Error"        defStyleNum="dsError" spellChecking="false"/>
-    </itemDatas>
-  </highlighting>
-  <general>
-    <comments>
-      <comment name="singleLine" start="//" />
-      <comment name="multiLine" start="/*" end="*/" />
-    </comments>
-    <keywords casesensitive="1" additionalDeliminator="'"" />
-  </general>
-</language>
diff --git a/misc/makerelease/makerelease.go b/misc/makerelease/makerelease.go
index 2496a86..3b511b1 100644
--- a/misc/makerelease/makerelease.go
+++ b/misc/makerelease/makerelease.go
@@ -14,6 +14,7 @@ import (
 	"compress/gzip"
 	"crypto/sha1"
 	"encoding/json"
+	"errors"
 	"flag"
 	"fmt"
 	"io"
@@ -30,7 +31,7 @@ import (
 	"strings"
 
 	"code.google.com/p/goauth2/oauth"
-	"code.google.com/p/google-api-go-client/storage/v1beta2"
+	storage "code.google.com/p/google-api-go-client/storage/v1"
 )
 
 var (
@@ -53,20 +54,20 @@ var (
 )
 
 const (
-	blogPath       = "code.google.com/p/go.blog"
-	toolPath       = "code.google.com/p/go.tools"
+	blogPath       = "golang.org/x/blog"
+	toolPath       = "golang.org/x/tools"
 	tourPath       = "code.google.com/p/go-tour"
-	defaultToolTag = "release-branch.go1.2"
-	defaultTourTag = "release-branch.go1.2"
+	defaultToolTag = "release-branch.go1.4"
+	defaultTourTag = "release-branch.go1.4"
 )
 
 // Import paths for tool commands.
 // These must be the command that cmd/go knows to install to $GOROOT/bin
 // or $GOROOT/pkg/tool.
 var toolPaths = []string{
-	"code.google.com/p/go.tools/cmd/cover",
-	"code.google.com/p/go.tools/cmd/godoc",
-	"code.google.com/p/go.tools/cmd/vet",
+	"golang.org/x/tools/cmd/cover",
+	"golang.org/x/tools/cmd/godoc",
+	"golang.org/x/tools/cmd/vet",
 }
 
 var preBuildCleanFiles = []string{
@@ -74,8 +75,8 @@ var preBuildCleanFiles = []string{
 	"misc/dashboard/godashboard",
 	"src/cmd/cov",
 	"src/cmd/prof",
-	"src/pkg/exp",
-	"src/pkg/old",
+	"src/exp",
+	"src/old",
 }
 
 var cleanFiles = []string{
@@ -154,6 +155,7 @@ func main() {
 			log.Fatalln("setupOAuthClient:", err)
 		}
 	}
+	ok := true
 	for _, targ := range flag.Args() {
 		var b Build
 		if m := fileRe.FindStringSubmatch(targ); m != nil {
@@ -205,8 +207,12 @@ func main() {
 		}
 		if err := b.Do(); err != nil {
 			log.Printf("%s: %v", targ, err)
+			ok = false
 		}
 	}
+	if !ok {
+		os.Exit(1)
+	}
 }
 
 type Build struct {
@@ -432,7 +438,8 @@ func (b *Build) Do() error {
 		// Build package.
 		_, err = b.run(work, "candle",
 			"-nologo",
-			"-dVersion="+version,
+			"-dGoVersion="+version,
+			"-dWixGoVersion="+wixVersion(version),
 			"-dArch="+b.Arch,
 			"-dSourceDir=go",
 			installer, appfiles)
@@ -466,6 +473,22 @@ func (b *Build) Do() error {
 	return err
 }
 
+var versionRe = regexp.MustCompile(`^go([0-9]+(\.[0-9]+)*)`)
+
+// The Microsoft installer requires version format major.minor.build
+// (http://msdn.microsoft.com/en-us/library/aa370859%28v=vs.85%29.aspx).
+// Where the major and minor field has a maximum value of 255 and build 65535.
+// The offical Go version format is goMAJOR.MINOR.PATCH at $GOROOT/VERSION.
+// It's based on the Mercurial tag. Remove prefix and suffix to make the
+// installer happy.
+func wixVersion(v string) string {
+	m := versionRe.FindStringSubmatch(v)
+	if m == nil {
+		return "0.0.0"
+	}
+	return m[1]
+}
+
 // extras fetches the go.tools, go.blog, and go-tour repositories,
 // builds them and copies the resulting binaries and static assets
 // to the new GOROOT.
@@ -482,16 +505,38 @@ func (b *Build) extras() error {
 }
 
 func (b *Build) get(repoPath, revision string) error {
-	// Fetch the packages (without building/installing).
-	_, err := b.run(b.gopath, filepath.Join(b.root, "bin", "go"),
-		"get", "-d", repoPath+"/...")
-	if err != nil {
-		return err
+	dest := filepath.Join(b.gopath, "src", filepath.FromSlash(repoPath))
+
+	if strings.HasPrefix(repoPath, "golang.org/x/") {
+		// For sub-repos, fetch the old Mercurial repo; bypass "go get".
+		// DO NOT import this special case into the git tree.
+
+		if err := os.MkdirAll(filepath.Dir(dest), 0755); err != nil {
+			return err
+		}
+		repo := strings.Replace(repoPath, "golang.org/x/", "https://code.google.com/p/go.", 1)
+		if _, err := b.run(b.gopath, "hg", "clone", repo, dest); err != nil {
+			return err
+		}
+	} else {
+		// Fetch the packages (without building/installing).
+		_, err := b.run(b.gopath, filepath.Join(b.root, "bin", "go"),
+			"get", "-d", repoPath+"/...")
+		if err != nil {
+			return err
+		}
 	}
 
 	// Update the repo to the specified revision.
-	p := filepath.Join(b.gopath, "src", filepath.FromSlash(repoPath))
-	_, err = b.run(p, "hg", "update", revision)
+	var err error
+	switch {
+	case exists(filepath.Join(dest, ".git")):
+		_, err = b.run(dest, "git", "checkout", revision)
+	case exists(filepath.Join(dest, ".hg")):
+		_, err = b.run(dest, "hg", "update", revision)
+	default:
+		err = errors.New("unknown version control system")
+	}
 	return err
 }
 
@@ -721,7 +766,7 @@ type File struct {
 func setupOAuthClient() error {
 	config := &oauth.Config{
 		ClientId:     "999119582588-h7kpj5pcm6d9solh5lgrbusmvvk4m9dn.apps.googleusercontent.com",
-		ClientSecret: "8YLFgOhXIELWbO",
+		ClientSecret: "8YLFgOhXIELWbO-NtF3iqIQz",
 		Scope:        storage.DevstorageRead_writeScope,
 		AuthURL:      "https://accounts.google.com/o/oauth2/auth",
 		TokenURL:     "https://accounts.google.com/o/oauth2/token",
diff --git a/misc/makerelease/windows/installer.wxs b/misc/makerelease/windows/installer.wxs
index b170b98..01178e2 100644
--- a/misc/makerelease/windows/installer.wxs
+++ b/misc/makerelease/windows/installer.wxs
@@ -18,13 +18,12 @@
 
 <Product
     Id="FF5B30B2-08C2-11E1-85A2-6ACA4824019B"
-    Name="Go Programming Language $(var.Arch) $(var.Version)"
+    Name="Go Programming Language $(var.Arch) $(var.GoVersion)"
     Language="1033"
     Codepage="1252"
-    Version="0.0.0.0"
+    Version="$(var.WixGoVersion)"
     Manufacturer="http://golang.org"
     UpgradeCode="$(var.UpgradeCode)" >
-    <!-- Version="$(var.Version)" TODO: Version requires X.X.X.X format -->
 
 <Package
     Id='*' 
@@ -40,9 +39,9 @@
 
 <Property Id="ARPCOMMENTS" Value="The Go programming language is a fast, statically typed, compiled language that feels like a dynamically typed, interpreted language." />
 <Property Id="ARPCONTACT" Value="golang-nuts at googlegroups.com" />
-<Property Id="ARPHELPLINK" Value="golang.org/doc/community.html" />
-<Property Id="ARPREADME" Value="golang.org" />
-<Property Id="ARPURLINFOABOUT" Value="golang.org" />
+<Property Id="ARPHELPLINK" Value="https://golang.org/help/" />
+<Property Id="ARPREADME" Value="https://golang.org" />
+<Property Id="ARPURLINFOABOUT" Value="https://golang.org" />
 <Property Id="LicenseAccepted">1</Property>
 <Icon Id="gopher.ico" SourceFile="images\gopher.ico"/>
 <Property Id="ARPPRODUCTICON" Value="gopher.ico" />
diff --git a/misc/nacl/README b/misc/nacl/README
index 9cc2bda..72d0e08 100644
--- a/misc/nacl/README
+++ b/misc/nacl/README
@@ -1,63 +1,122 @@
 Native Client
 =============
 
-This document outlines the basics of building and developing the Go runtime and programs in the Native Client (NaCl) environment.
+This document outlines the basics of building and developing the Go runtime and
+programs in the Native Client (NaCl) environment.
 
-Go 1.3 supports two architectures
+Go 1.3 supports three architectures
 
  * nacl/386 which is standard 386.
- * nacl/amd64p32 which is a 64 bit architecture, where the address space is limited to a 4gb window. 
+ * nacl/amd64p32 which is a 64 bit architecture, where the address space is
+   limited to a 4gb window. 
+ * nacl/arm which is 32-bit ARMv7A architecture with 1GB address space.
 
 For background it is recommended that you read http://golang.org/s/go13nacl.
 
 Prerequisites
 -------------
 
-Native Client programs are executed inside a sandbox, the NaCl runtime. This runtime must be installed before you can use NaCl programs.
+Native Client programs are executed inside a sandbox, the NaCl runtime. This
+runtime must be installed before you can use NaCl programs.
 
-The NaCl distribution comes with an installer which ensures you have access to the latest version of the runtime. The version tracks the Chrome numbering scheme.
+The NaCl distribution comes with an installer which ensures you have access to
+the latest version of the runtime. The version tracks the Chrome numbering
+scheme.
 
 # Download NaCl
 
-Download nacl_sdk.zip file from https://developers.google.com/native-client/dev/sdk/download, and unpack it. I chose /opt/nacl_sdk
+Download nacl_sdk.zip file from
+	https://developers.google.com/native-client/dev/sdk/download
+and unpack it. I chose /opt/nacl_sdk.
 
 # Update
 
-The zip file contains a small skeleton that can be used to download the correct sdk. These are released every 6-8 weeks, in line with Chrome releases.
+The zip file contains a small skeleton that can be used to download the correct
+sdk. These are released every 6-8 weeks, in line with Chrome releases.
 	
 	% cd /opt/nacl_sdk
 	% ./naclsdk update
 
-At this time pepper_33 is the stable version. If naclsdk downloads a later version, please adjust accordingly.
+At this time pepper_34 is the stable version. If naclsdk downloads a later
+version, please adjust accordingly. As of June 2014, only the canary sdk
+provides support for nacl/arm.
 
-The cmd/go helper scripts expect that the runtime loaders, sel_ldr_x86_{32,64} are in your path. I find it easiest to make a symlink from the NaCl distribution to my $GOPATH/bin directory.
+The cmd/go helper scripts expect that the loaders sel_ldr_{x86_{32,64},arm} and
+nacl_helper_bootstrap_arm are in your path. I find it easiest to make a symlink
+from the NaCl distribution to my $GOPATH/bin directory.
 
-	% ln -nfs /opt/nacl_sdk/pepper_33/tools/sel_ldr_x86_32 $GOPATH/bin/sel_ldr_x86_32
-	% ln -nfs /opt/nacl_sdk/pepper_33/tools/sel_ldr_x86_64 $GOPATH/bin/sel_ldr_x86_64
+	% ln -nfs /opt/nacl_sdk/pepper_34/tools/sel_ldr_x86_32 $GOPATH/bin/sel_ldr_x86_32
+	% ln -nfs /opt/nacl_sdk/pepper_34/tools/sel_ldr_x86_64 $GOPATH/bin/sel_ldr_x86_64
+	% ln -nfs /opt/nacl_sdk/pepper_canary/tools/sel_ldr_arm $GOPATH/bin/sel_ldr_arm
+
+Additionally, for NaCl/ARM only:
+
+	% ln -nfs /opt/nacl_sdk/pepper_canary/tools/nacl_helper_bootstrap_arm $GOPATH/bin/nacl_helper_bootstrap_arm 
 
 Support scripts
 ---------------
 
-Symlink the two scripts in this directory into your $PATH, just as you did with NaCl sdk above.
+Symlink the two scripts in this directory into your $PATH, just as you did with
+NaCl sdk above.
 
-	% ln -nfs $GOROOT/go/misc/nacl/go_nacl_amd64p32_exec $GOPATH/bin/go_nacl_amd64p32_exec
-	% ln -nfs $GOROOT/go/misc/nacl/go_nacl_386_exec $GOPATH/bin/go_nacl_386_exec
+	% ln -nfs $GOROOT/misc/nacl/go_nacl_amd64p32_exec $GOPATH/bin/go_nacl_amd64p32_exec
+	% ln -nfs $GOROOT/misc/nacl/go_nacl_386_exec $GOPATH/bin/go_nacl_386_exec
+	% ln -nfs $GOROOT/misc/nacl/go_nacl_arm_exec $GOPATH/bin/go_nacl_arm_exec
 
 Building and testing
 --------------------
 
-Building for NaCl is similar to cross compiling for other platforms. However, as it is not possible to ever build in a `native` NaCl environment, the cmd/go tool has been enhanced to allow the full build, all.bash, to be executed, rather than just the compile stage, make.bash.
+Building for NaCl is similar to cross compiling for other platforms. However,
+as it is not possible to ever build in a `native` NaCl environment, the cmd/go
+tool has been enhanced to allow the full build, all.bash, to be executed,
+rather than just the compile stage, make.bash.
 
-The cmd/go tool knows that if GOOS is set to `nacl` it should not try to execute any binaries itself. Instead it passes their execution to a support script which sets up a Native Client environment and invokes the NaCl sandbox.
+The cmd/go tool knows that if GOOS is set to `nacl` it should not try to
+execute any binaries itself. Instead it passes their execution to a support
+script which sets up a Native Client environment and invokes the NaCl sandbox.
 
-The script's name has a special format, go_$GOOS_$GOARCH_exec, so cmd/go can find it.
+The script's name has a special format, go_$GOOS_$GOARCH_exec, so cmd/go can
+find it.
 
-In short, if the support scripts are in place, the cmd/go tool can be used as per normal.
+In short, if the support scripts are in place, the cmd/go tool can be used as
+per normal.
 
 # Build and test Go for NaCl
 
-NaCl does not permit direct file system access. Instead, package syscall provides a simulated file system served by in-memory data. The script nacltest.bash is the NaCl equivalent of all.bash. It builds NaCl with an in-memory file system containing files needed for tests, and then it runs the tests.
+NaCl does not permit direct file system access. Instead, package syscall
+provides a simulated file system served by in-memory data. The script
+nacltest.bash is the NaCl equivalent of all.bash. It builds NaCl with an
+in-memory file system containing files needed for tests, and then it runs the
+tests.
 
 	% cd go/src
 	% env GOARCH=amd64p32 ./nacltest.bash
 
+Debugging
+---------
+
+Assuming that you have built nacl/amd64p32 binary ./mybin and can run as:
+
+	% sel_ldr_x86_64 -l /dev/null -S -e ./mybin
+
+Create the nacl manifest file mybin.manifest with the following contents:
+
+	{ "program": { "x86-64": { "url": "mybin" } } }
+
+url is the path to the binary relative to the manifest file.
+Then, run the program as:
+
+	% sel_ldr_x86_64 -g -l /dev/null -S -e ./mybin
+
+The -g flag instructs the loader to stop at startup. Then, in another console:
+
+	% /opt/nacl_sdk/pepper_34/toolchain/linux_x86_glibc/bin/x86_64-nacl-gdb
+	% nacl-manifest mybin.manifest
+	% target remote :4014
+
+If you see that the program is stopped in _rt0_amd64p32_nacl, then symbols are
+loaded successfully and you can type 'c' to start the program.
+Next time you can automate it as:
+
+	% /opt/nacl_sdk/pepper_34/toolchain/linux_x86_glibc/bin/x86_64-nacl-gdb \
+		-ex 'nacl-manifest mybin.manifest' -ex 'target remote :4014'
diff --git a/misc/nacl/go_nacl_arm_exec b/misc/nacl/go_nacl_arm_exec
new file mode 100755
index 0000000..4275cb1
--- /dev/null
+++ b/misc/nacl/go_nacl_arm_exec
@@ -0,0 +1,10 @@
+#!/bin/bash
+
+eval $(go env)
+
+export NACLENV_GOARCH=$GOARCH
+export NACLENV_GOOS=$GOOS
+export NACLENV_GOROOT=/go
+export NACLENV_NACLPWD=$(pwd | sed "s;$GOROOT;/go;")
+
+exec nacl_helper_bootstrap_arm $(which sel_ldr_arm) --reserved_at_zero=0xXXXXXXXXXXXXXXXX -l /dev/null -S -e "$@"
diff --git a/misc/nacl/mkzip.go b/misc/nacl/mkzip.go
index 7b2de7d..aaf37f1 100644
--- a/misc/nacl/mkzip.go
+++ b/misc/nacl/mkzip.go
@@ -71,7 +71,13 @@ func main() {
 
 	var w io.Writer = zf
 	if *gopackage != "" {
-		fmt.Fprintf(zf, "package %s\n\nfunc init() {\n\tunzip(\"", *gopackage)
+		fmt.Fprintf(zf, `package %s
+import "sync"
+func init() {
+	var once sync.Once
+	fsinit = func() {
+		once.Do(func() {
+			unzip("`, *gopackage)
 		gw := &goWriter{b: bufio.NewWriter(w)}
 		defer func() {
 			if err := gw.Close(); err != nil {
@@ -214,7 +220,7 @@ func (w *goWriter) Write(b []byte) (int, error) {
 }
 
 func (w *goWriter) Close() error {
-	fmt.Fprintf(w.b, "\")\n}\n")
+	fmt.Fprintf(w.b, "\")\n\t\t})\n\t}\n}")
 	w.b.Flush()
 	return nil
 }
diff --git a/misc/nacl/testzip.proto b/misc/nacl/testzip.proto
index 2701ff4..07d4a1d 100644
--- a/misc/nacl/testzip.proto
+++ b/misc/nacl/testzip.proto
@@ -10,101 +10,105 @@ usr	src=../misc/nacl/testdata
 go	src=..
 	src
 		cmd
+			internal
+				objfile
+					objfile.go
 			gofmt
+				gofmt.go
+				gofmt_test.go
 				testdata
 					+
-		pkg
-			archive
-				tar
-					testdata
-						+
-				zip
-					testdata
-						+
-			compress
-				bzip2
-					testdata
-						+
-				flate
-				gzip
-					testdata
-						+
-				lzw
-				testdata
-					+
-				zlib
-			crypto
-				rsa
-					testdata
-						+
-				tls
-					testdata
-						+
-			debug
-				dwarf
-					testdata
-						+
-				elf
-					testdata
-						+
-				macho
-					testdata
-						+
-				pe
-					testdata
-						+
-				plan9obj
-					testdata
-						+
-			go
-				build
-					+
-				doc
-					testdata
-						+
-				format
-					+
-				parser
-					+
-				printer
-					+
-			image
-				testdata
-					+
-				draw
-				gif
-				jpeg
-				png
-					testdata
-						+
-			io
+		archive
+			tar
+				testdata
+					+
+			zip
+				testdata
+					+
+		compress
+			bzip2
+				testdata
+					+
+			flate
+			gzip
+				testdata
+					+
+			lzw
+			testdata
 				+
-			mime
+			zlib
+		crypto
+			rsa
+				testdata
+					+
+			tls
+				testdata
+					+
+		debug
+			dwarf
+				testdata
+					+
+			elf
+				testdata
+					+
+			macho
 				testdata
 					+
-				multipart
-					testdata
-						+
-			net
-				http
+			pe
+				testdata
 					+
+			plan9obj
 				testdata
 					+
-			os
+		go
+			build
 				+
-			path
-				filepath
+			doc
+				testdata
 					+
-			regexp
+			format
+				+
+			parser
+				+
+			printer
+				+
+		image
+			testdata
+				+
+			draw
+			gif
+			jpeg
+			png
 				testdata
 					+
-			strconv
+		io
+			+
+		mime
+			testdata
+				+
+			multipart
+				testdata
+					+
+		net
+			http
+				+
+			testdata
+				+
+		os
+			+
+		path
+			filepath
+				+
+		regexp
+			testdata
+				+
+		strconv
+			testdata
+				+
+		text
+			template
 				testdata
 					+
-			text
-				template
-					testdata
-						+
 	lib
 		time
 			zoneinfo.zip
diff --git a/misc/notepadplus/README b/misc/notepadplus/README
deleted file mode 100644
index fca4f5f..0000000
--- a/misc/notepadplus/README
+++ /dev/null
@@ -1,59 +0,0 @@
-Notepad++ syntax highlighting
------------------------------
-
-The userDefineLang.xml uses the new User Defined Language system (UDL2),
-which needs Notepad++ v6.2 or higher.
-
-Installing from Notepad++ Installer
-
-  1. Add the contents of userDefineLang.xml at %APPDATA%\Notepad++\userDefineLang.xml
-     between <NotepadPlus> ... </NotepadPlus>
-  2. Restart Notepad++
-
-Installing from Notepad++ zip/7z package
-
-  1. Given a Notepad++ installation at <DIR>.
-  2. Add the contents of userDefineLang.xml at <DIR>\userDefineLang.xml
-     between <NotepadPlus> ... </NotepadPlus>
-  3. Restart Notepad++
-
-Reference
-
-  1. http://sourceforge.net/apps/mediawiki/notepad-plus/index.php?title=User_Defined_Languages
-  2. http://notepad-plus-plus.org/news/notepad-6.2-release-udl2.html
-  3. http://udl20.weebly.com/index.html
-
-
-Notepad++ keyword auto-completion
----------------------------------
-
-  1. Given a Notepad++ installation at <DIR>.
-  2. Copy go.xml to <DIR>\plugins\APIs
-  3. Restart Notepad++
-
-Reference
-
-  1. http://sourceforge.net/apps/mediawiki/notepad-plus/index.php?title=Auto_Completion
-
-Notepad++ Function List
------------------------
-
-The functionList.xml uses the Function List Pane new feature,
-which needs Notepad++ v6.4 or higher.
-
-Installing from Notepad++ Installer
-
-  1. Add the contents of userDefineLang.xml at %APPDATA%\Notepad++\functionList.xml
-     between <associationMap> ... </associationMap> and <parsers> ... </parsers>
-  2. Restart Notepad++
-
-Installing from Notepad++ zip/7z package
-
-  1. Given a Notepad++ installation at <DIR>.
-  2. Add the contents of functionList.xml at <DIR>\functionList.xml
-     between <associationMap> ... </associationMap> and <parsers> ... </parsers>
-  3. Restart Notepad++
-
-Reference
-
-  1. http://notepad-plus-plus.org/features/function-list.html
diff --git a/misc/notepadplus/functionList.xml b/misc/notepadplus/functionList.xml
deleted file mode 100644
index 7c605db..0000000
--- a/misc/notepadplus/functionList.xml
+++ /dev/null
@@ -1,50 +0,0 @@
-<!-- <NotepadPlus> -->
-	<!-- <functionList> -->
-		<!-- <associationMap> -->
-
-		<!--
-			if npp version == 6.4:
-			<association ext=".go" id="go"/>
-
-			if npp version >= 6.5:
-			<association userDefinedLangName="go" id="go"/>
-		-->
-
-		<!-- </associationMap> -->
-		<!-- <parsers> -->
-			<parser id="go" displayName="Go" commentExpr="((/\*.*?\*)/|(//.*?$))">
-				<classRange
-					mainExpr="^type\s+\w+\s+interface\s*\{"
-					openSymbole = "\{"
-					closeSymbole = "\}"
-					displayMode="node">
-					<className>
-						<nameExpr expr="type\s+\w+"/>
-						<nameExpr expr="\s+\w+"/>
-						<nameExpr expr="\w+"/>
-					</className>
-					<function
-						mainExpr="^\s+\w+\s*\(">
-						<functionName>
-							<funcNameExpr expr="\w+"/>
-						</functionName>
-					</function>
-				</classRange>
-				<function
-					mainExpr="(^func\s+\w+)|(^func\s*\(\s*\w*\s*\*?\s*\w+\s*\)\s*\w+)"
-					displayMode="$className->$functionName">
-					<functionName>
-						<nameExpr expr="((func\s+\w+)|(\)\s*\w+))"/>
-						<nameExpr expr="((\s+\w+)|(\)\s*\w+))"/>
-						<nameExpr expr="\w+"/>
-					</functionName>
-					<className>
-						<nameExpr expr="\w+\s*\)"/>
-						<nameExpr expr="\w+"/>
-					</className>
-				</function>
-			</parser>
-
-		<!-- </parsers> -->
-	<!-- </functionList> -->
-<!-- </NotepadPlus> -->
diff --git a/misc/notepadplus/go.xml b/misc/notepadplus/go.xml
deleted file mode 100644
index 59e4116..0000000
--- a/misc/notepadplus/go.xml
+++ /dev/null
@@ -1,133 +0,0 @@
-<NotepadPlus>
-	<!-- Go Programming Language  builtins and keywords -->
-	<AutoComplete>
-		<KeyWord name="append" func="yes">
-			<Overload retVal="[]Type">
-				<Param name="slice []Type" />
-				<Param name="elems ...Type" />
-			</Overload>
-		</KeyWord>
-		<KeyWord name="bool" />
-		<KeyWord name="break" />
-		<KeyWord name="byte" />
-		<KeyWord name="cap" func="yes">
-			<Overload retVal="int">
-				<Param name="v Type" />
-			</Overload>
-		</KeyWord>
-		<KeyWord name="case" />
-		<KeyWord name="chan" />
-		<KeyWord name="close" func="yes">
-			<Overload retVal="">
-				<Param name="c chan<- Type" />
-			</Overload>
-		</KeyWord>
-		<KeyWord name="complex" func="yes">
-			<Overload retVal="ComplexType">
-				<Param name="r" />
-				<Param name="i FloatType" />
-			</Overload>
-		</KeyWord>
-		<KeyWord name="complex128" />
-		<KeyWord name="complex64" />
-		<KeyWord name="const" />
-		<KeyWord name="continue" />
-		<KeyWord name="copy" func="yes">
-			<Overload retVal="int">
-				<Param name="dst" />
-				<Param name="src []Type" />
-			</Overload>
-		</KeyWord>
-		<KeyWord name="default" />
-		<KeyWord name="defer" />
-		<KeyWord name="delete" func="yes">
-			<Overload retVal="">
-				<Param name="m map[Type]Type1" />
-				<Param name="key Type" />
-			</Overload>
-		</KeyWord>
-		<KeyWord name="else" />
-		<KeyWord name="error" />
-		<KeyWord name="fallthrough" />
-		<KeyWord name="false" />
-		<KeyWord name="float32" />
-		<KeyWord name="float64" />
-		<KeyWord name="for" />
-		<KeyWord name="func" />
-		<KeyWord name="go" />
-		<KeyWord name="goto" />
-		<KeyWord name="if" />
-		<KeyWord name="iota" />
-		<KeyWord name="imag" func="yes">
-			<Overload retVal="FloatType">
-				<Param name="c ComplexType" />
-			</Overload>
-		</KeyWord>
-		<KeyWord name="import" />
-		<KeyWord name="int" />
-		<KeyWord name="int16" />
-		<KeyWord name="int32" />
-		<KeyWord name="int64" />
-		<KeyWord name="int8" />
-		<KeyWord name="interface" />
-		<KeyWord name="len" func="yes">
-			<Overload retVal="int">
-				<Param name="v Type" />
-			</Overload>
-		</KeyWord>
-		<KeyWord name="make" func="yes">
-			<Overload retVal="Type">
-				<Param name="Type" />
-				<Param name="size IntegerType" />
-			</Overload>
-		</KeyWord>
-		<KeyWord name="map" />
-		<KeyWord name="new" func="yes">
-			<Overload retVal="*Type">
-				<Param name="Type" />
-			</Overload>
-		</KeyWord>
-		<KeyWord name="nil" />
-		<KeyWord name="package" />
-		<KeyWord name="panic" func="yes">
-			<Overload retVal="">
-				<Param name="v interface{}" />
-			</Overload>
-		</KeyWord>
-		<KeyWord name="print" func="yes">
-			<Overload retVal="">
-				<Param name="args ...Type" />
-			</Overload>
-		</KeyWord>
-		<KeyWord name="println" func="yes">
-			<Overload retVal="" >
-				<Param name="args ...Type" />
-			</Overload>
-		</KeyWord>
-		<KeyWord name="range" />
-		<KeyWord name="real" func="yes">
-			<Overload retVal="FloatType">
-				<Param name="c ComplexType" />
-			</Overload>
-		</KeyWord>
-		<KeyWord name="recover" func="yes">
-			<Overload retVal="interface{}">
-			</Overload>
-		</KeyWord>
-		<KeyWord name="return" />
-		<KeyWord name="rune" />
-		<KeyWord name="select" />
-		<KeyWord name="string" />
-		<KeyWord name="struct" />
-		<KeyWord name="switch" />
-		<KeyWord name="true" />
-		<KeyWord name="type" />
-		<KeyWord name="uint" />
-		<KeyWord name="uint16" />
-		<KeyWord name="uint32" />
-		<KeyWord name="uint64" />
-		<KeyWord name="uint8" />
-		<KeyWord name="uintptr" />
-		<KeyWord name="var" />
-	</AutoComplete>
-</NotepadPlus>
diff --git a/misc/notepadplus/userDefineLang.xml b/misc/notepadplus/userDefineLang.xml
deleted file mode 100644
index 9751f79..0000000
--- a/misc/notepadplus/userDefineLang.xml
+++ /dev/null
@@ -1,64 +0,0 @@
-<!-- <NotepadPlus> -->
-    <UserLang name="go" ext="go" udlVersion="2.1">
-        <Settings>
-            <Global caseIgnored="no" allowFoldOfComments="yes" foldCompact="no" forcePureLC="0" decimalSeparator="0" />
-            <Prefix Keywords1="no" Keywords2="no" Keywords3="no" Keywords4="no" Keywords5="no" Keywords6="no" Keywords7="no" Keywords8="no" />
-        </Settings>
-        <KeywordLists>
-            <Keywords name="Comments">00// 01 02 03/* 04*/</Keywords>
-            <Keywords name="Numbers, prefix1"></Keywords>
-            <Keywords name="Numbers, prefix2">0x 0X</Keywords>
-            <Keywords name="Numbers, extras1">a b c d e f A B C D E F</Keywords>
-            <Keywords name="Numbers, extras2"></Keywords>
-            <Keywords name="Numbers, suffix1"></Keywords>
-            <Keywords name="Numbers, suffix2">i</Keywords>
-            <Keywords name="Numbers, range"></Keywords>
-            <Keywords name="Operators1">( ) [ ] { } ... , ; & ^ % > < ! = + - * / | :</Keywords>
-            <Keywords name="Operators2"></Keywords>
-            <Keywords name="Folders in code1, open"></Keywords>
-            <Keywords name="Folders in code1, middle"></Keywords>
-            <Keywords name="Folders in code1, close"></Keywords>
-            <Keywords name="Folders in code2, open"></Keywords>
-            <Keywords name="Folders in code2, middle"></Keywords>
-            <Keywords name="Folders in code2, close"></Keywords>
-            <Keywords name="Folders in comment, open"></Keywords>
-            <Keywords name="Folders in comment, middle"></Keywords>
-            <Keywords name="Folders in comment, close"></Keywords>
-            <Keywords name="Keywords1">break default func interface select case defer go map struct chan else goto package switch const fallthrough if range type continue for import return var</Keywords>
-            <Keywords name="Keywords2">bool byte complex64 complex128 error float32 float64 int int8 int16 int32 int64 rune string uint uint8 uint16 uint32 uint64 uintptr true false iota nil</Keywords>
-            <Keywords name="Keywords3">append cap close complex copy delete imag len make new panic print println real recover _</Keywords>
-            <Keywords name="Keywords4"></Keywords>
-            <Keywords name="Keywords5"></Keywords>
-            <Keywords name="Keywords6"></Keywords>
-            <Keywords name="Keywords7"></Keywords>
-            <Keywords name="Keywords8"></Keywords>
-            <Keywords name="Delimiters">00" 01\ 02" 03' 04\ 05' 06` 07 08` 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23</Keywords>
-        </KeywordLists>
-        <Styles>
-            <WordsStyle name="DEFAULT" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
-            <WordsStyle name="COMMENTS" fgColor="008000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
-            <WordsStyle name="LINE COMMENTS" fgColor="008000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
-            <WordsStyle name="NUMBERS" fgColor="A52A2A" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
-            <WordsStyle name="KEYWORDS1" fgColor="AA0000" bgColor="FFFFFF" fontName="" fontStyle="1" nesting="0" />
-            <WordsStyle name="KEYWORDS2" fgColor="AA0000" bgColor="FFFFFF" fontName="" fontStyle="1" nesting="0" />
-            <WordsStyle name="KEYWORDS3" fgColor="AA0000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
-            <WordsStyle name="KEYWORDS4" fgColor="A00000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
-            <WordsStyle name="KEYWORDS5" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
-            <WordsStyle name="KEYWORDS6" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
-            <WordsStyle name="KEYWORDS7" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
-            <WordsStyle name="KEYWORDS8" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
-            <WordsStyle name="OPERATORS" fgColor="8000FF" bgColor="FFFFFF" fontName="" fontStyle="1" nesting="0" />
-            <WordsStyle name="FOLDER IN CODE1" fgColor="8000FF" bgColor="FFFFFF" fontName="" fontStyle="1" nesting="0" />
-            <WordsStyle name="FOLDER IN CODE2" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
-            <WordsStyle name="FOLDER IN COMMENT" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
-            <WordsStyle name="DELIMITERS1" fgColor="0000FF" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
-            <WordsStyle name="DELIMITERS2" fgColor="0000FF" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
-            <WordsStyle name="DELIMITERS3" fgColor="0000FF" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
-            <WordsStyle name="DELIMITERS4" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
-            <WordsStyle name="DELIMITERS5" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
-            <WordsStyle name="DELIMITERS6" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
-            <WordsStyle name="DELIMITERS7" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
-            <WordsStyle name="DELIMITERS8" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
-        </Styles>
-    </UserLang>
-<!-- </NotepadPlus> -->
diff --git a/misc/pprof b/misc/pprof
deleted file mode 100755
index ad3f1eb..0000000
--- a/misc/pprof
+++ /dev/null
@@ -1,5094 +0,0 @@
-#! /usr/bin/env perl
-
-# This is a copy of http://google-perftools.googlecode.com/svn/trunk/src/pprof
-# with local modifications to handle generation of SVG images and
-# the Go-style pprof paths.  These modifications will probably filter
-# back into the official source before long.
-# It's convenient to have a copy here because we need just the one
-# Perl script, not all the C++ libraries that surround it.
-
-# Copyright (c) 1998-2007, Google Inc.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-#     * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-#     * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-#     * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-# ---
-# Program for printing the profile generated by common/profiler.cc,
-# or by the heap profiler (common/debugallocation.cc)
-#
-# The profile contains a sequence of entries of the form:
-#       <count> <stack trace>
-# This program parses the profile, and generates user-readable
-# output.
-#
-# Examples:
-#
-# % tools/pprof "program" "profile"
-#   Enters "interactive" mode
-#
-# % tools/pprof --text "program" "profile"
-#   Generates one line per procedure
-#
-# % tools/pprof --gv "program" "profile"
-#   Generates annotated call-graph and displays via "gv"
-#
-# % tools/pprof --gv --focus=Mutex "program" "profile"
-#   Restrict to code paths that involve an entry that matches "Mutex"
-#
-# % tools/pprof --gv --focus=Mutex --ignore=string "program" "profile"
-#   Restrict to code paths that involve an entry that matches "Mutex"
-#   and does not match "string"
-#
-# % tools/pprof --list=IBF_CheckDocid "program" "profile"
-#   Generates disassembly listing of all routines with at least one
-#   sample that match the --list=<regexp> pattern.  The listing is
-#   annotated with the flat and cumulative sample counts at each line.
-#
-# % tools/pprof --disasm=IBF_CheckDocid "program" "profile"
-#   Generates disassembly listing of all routines with at least one
-#   sample that match the --disasm=<regexp> pattern.  The listing is
-#   annotated with the flat and cumulative sample counts at each PC value.
-#
-# TODO: Use color to indicate files?
-
-use strict;
-use warnings;
-use Getopt::Long;
-use File::Temp;
-use File::Copy;
-
-my $PPROF_VERSION = "1.5";
-
-# NOTE: All mentions of c++filt have been expunged from this script
-# because (1) we don't use C++, and (2) the copy of c++filt that ships
-# on OS X is from 2007 and destroys nm output by "demangling" the
-# first two columns (address and symbol type).
-
-# These are the object tools we use which can come from a
-# user-specified location using --tools, from the PPROF_TOOLS
-# environment variable, or from the environment.
-my %obj_tool_map = (
-  "objdump" => "objdump",
-  "nm" => "nm",
-  "addr2line" => "addr2line",
-  ## ConfigureObjTools may add architecture-specific entries:
-  #"nm_pdb" => "nm-pdb",       # for reading windows (PDB-format) executables
-  #"addr2line_pdb" => "addr2line-pdb",                                # ditto
-  #"otool" => "otool",         # equivalent of objdump on OS X
-);
-my $DOT = "dot";          # leave non-absolute, since it may be in /usr/local
-my $GV = "gv";
-my $KCACHEGRIND = "kcachegrind";
-my $PS2PDF = "ps2pdf";
-# These are used for dynamic profiles
-
-# These are the web pages that servers need to support for dynamic profiles
-my $HEAP_PAGE = "/pprof/heap";
-my $THREAD_PAGE = "/pprof/thread";
-my $PROFILE_PAGE = "/pprof/profile";   # must support cgi-param "?seconds=#"
-my $BLOCK_PAGE = "/pprof/block";
-my $PMUPROFILE_PAGE = "/pprof/pmuprofile(?:\\?.*)?"; # must support cgi-param
-                                                # ?seconds=#&event=x&period=n
-my $GROWTH_PAGE = "/pprof/growth";
-my $CONTENTION_PAGE = "/pprof/contention";
-my $WALL_PAGE = "/pprof/wall(?:\\?.*)?";  # accepts options like namefilter
-my $FILTEREDPROFILE_PAGE = "/pprof/filteredprofile(?:\\?.*)?";
-my $SYMBOL_PAGE = "/pprof/symbol";     # must support symbol lookup via POST
-my $PROGRAM_NAME_PAGE = "/pprof/cmdline";
-
-# default binary name
-my $UNKNOWN_BINARY = "(unknown)";
-
-# There is a pervasive dependency on the length (in hex characters,
-# i.e., nibbles) of an address, distinguishing between 32-bit and
-# 64-bit profiles.  To err on the safe size, default to 64-bit here:
-my $address_length = 16;
-
-# A list of paths to search for shared object files
-my @prefix_list = ();
-
-# Special routine name that should not have any symbols.
-# Used as separator to parse "addr2line -i" output.
-my $sep_symbol = '_fini';
-my $sep_address = undef;
-
-my $OS = $^O;
-my $DEVNULL = "/dev/null";
-if ($^O =~ /MSWin32|cygwin|msys/) {
-  $OS = "windows";
-  $DEVNULL = "NUL";
-}
-
-##### Argument parsing #####
-
-sub usage_string {
-  return <<EOF;
-Usage:
-pprof [options] <program> <profiles>
-   <profiles> is a space separated list of profile names.
-pprof [options] <symbolized-profiles>
-   <symbolized-profiles> is a list of profile files where each file contains
-   the necessary symbol mappings  as well as profile data (likely generated
-   with --raw).
-pprof [options] <profile>
-   <profile> is a remote form.  Symbols are obtained from host:port$SYMBOL_PAGE
-
-   Each name can be:
-   /path/to/profile        - a path to a profile file
-   host:port[/<service>]   - a location of a service to get profile from
-
-   The /<service> can be $HEAP_PAGE, $PROFILE_PAGE, /pprof/pmuprofile,
-                         $GROWTH_PAGE, $CONTENTION_PAGE, /pprof/wall,
-                         $THREAD_PAGE, $BLOCK_PAGE or /pprof/filteredprofile.
-   For instance:
-     pprof http://myserver.com:80$HEAP_PAGE
-   If /<service> is omitted, the service defaults to $PROFILE_PAGE (cpu profiling).
-pprof --symbols <program>
-   Maps addresses to symbol names.  In this mode, stdin should be a
-   list of library mappings, in the same format as is found in the heap-
-   and cpu-profile files (this loosely matches that of /proc/self/maps
-   on linux), followed by a list of hex addresses to map, one per line.
-
-   For more help with querying remote servers, including how to add the
-   necessary server-side support code, see this filename (or one like it):
-
-   /usr/doc/google-perftools-$PPROF_VERSION/pprof_remote_servers.html
-
-Options:
-   --cum               Sort by cumulative data
-   --base=<base>       Subtract <base> from <profile> before display
-   --interactive       Run in interactive mode (interactive "help" gives help) [default]
-   --seconds=<n>       Length of time for dynamic profiles [default=30 secs]
-   --add_lib=<file>    Read additional symbols and line info from the given library
-   --lib_prefix=<dir>  Comma separated list of library path prefixes
-
-Reporting Granularity:
-   --addresses         Report at address level
-   --lines             Report at source line level
-   --functions         Report at function level [default]
-   --files             Report at source file level
-
-Output type:
-   --text              Generate text report
-   --callgrind         Generate callgrind format to stdout
-   --gv                Generate Postscript and display
-   --web               Generate SVG and display
-   --list=<regexp>     Generate source listing of matching routines
-   --disasm=<regexp>   Generate disassembly of matching routines
-   --symbols           Print demangled symbol names found at given addresses
-   --dot               Generate DOT file to stdout
-   --ps                Generate Postcript to stdout
-   --pdf               Generate PDF to stdout
-   --svg               Generate SVG to stdout
-   --gif               Generate GIF to stdout
-   --raw               Generate symbolized pprof data (useful with remote fetch)
-
-Heap-Profile Options:
-   --inuse_space       Display in-use (mega)bytes [default]
-   --inuse_objects     Display in-use objects
-   --alloc_space       Display allocated (mega)bytes
-   --alloc_objects     Display allocated objects
-   --show_bytes        Display space in bytes
-   --drop_negative     Ignore negative differences
-
-Contention-profile options:
-   --total_delay       Display total delay at each region [default]
-   --contentions       Display number of delays at each region
-   --mean_delay        Display mean delay at each region
-
-Call-graph Options:
-   --nodecount=<n>     Show at most so many nodes [default=80]
-   --nodefraction=<f>  Hide nodes below <f>*total [default=.005]
-   --edgefraction=<f>  Hide edges below <f>*total [default=.001]
-   --focus=<regexp>    Focus on nodes matching <regexp>
-   --ignore=<regexp>   Ignore nodes matching <regexp>
-   --scale=<n>         Set GV scaling [default=0]
-   --heapcheck         Make nodes with non-0 object counts
-                       (i.e. direct leak generators) more visible
-
-Miscellaneous:
-   --tools=<prefix>    Prefix for object tool pathnames
-   --test              Run unit tests
-   --help              This message
-   --version           Version information
-
-Environment Variables:
-   PPROF_TMPDIR        Profiles directory. Defaults to \$HOME/pprof
-   PPROF_TOOLS         Prefix for object tools pathnames
-
-Examples:
-
-pprof /bin/ls ls.prof
-                       Enters "interactive" mode
-pprof --text /bin/ls ls.prof
-                       Outputs one line per procedure
-pprof --web /bin/ls ls.prof
-                       Displays annotated call-graph in web browser
-pprof --gv /bin/ls ls.prof
-                       Displays annotated call-graph via 'gv'
-pprof --gv --focus=Mutex /bin/ls ls.prof
-                       Restricts to code paths including a .*Mutex.* entry
-pprof --gv --focus=Mutex --ignore=string /bin/ls ls.prof
-                       Code paths including Mutex but not string
-pprof --list=getdir /bin/ls ls.prof
-                       (Per-line) annotated source listing for getdir()
-pprof --disasm=getdir /bin/ls ls.prof
-                       (Per-PC) annotated disassembly for getdir()
-
-pprof http://localhost:1234/
-                       Enters "interactive" mode
-pprof --text localhost:1234
-                       Outputs one line per procedure for localhost:1234
-pprof --raw localhost:1234 > ./local.raw
-pprof --text ./local.raw
-                       Fetches a remote profile for later analysis and then
-                       analyzes it in text mode.
-EOF
-}
-
-sub version_string {
-  return <<EOF
-pprof (part of google-perftools $PPROF_VERSION)
-
-Copyright 1998-2007 Google Inc.
-
-This is BSD licensed software; see the source for copying conditions
-and license information.
-There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
-PARTICULAR PURPOSE.
-EOF
-}
-
-sub usage {
-  my $msg = shift;
-  print STDERR "$msg\n\n";
-  print STDERR usage_string();
-  print STDERR "\nFATAL ERROR: $msg\n";    # just as a reminder
-  exit(1);
-}
-
-sub Init() {
-  # Setup tmp-file name and handler to clean it up.
-  # We do this in the very beginning so that we can use
-  # error() and cleanup() function anytime here after.
-  $main::tmpfile_sym = File::Temp->new()->filename;
-  $main::tmpfile_ps = File::Temp->new()->filename;
-  
-  $main::next_tmpfile = 0;
-  $SIG{'INT'} = \&sighandler;
-
-  # Cache from filename/linenumber to source code
-  $main::source_cache = ();
-
-  $main::opt_help = 0;
-  $main::opt_version = 0;
-
-  $main::opt_cum = 0;
-  $main::opt_base = '';
-  $main::opt_addresses = 0;
-  $main::opt_lines = 0;
-  $main::opt_functions = 0;
-  $main::opt_files = 0;
-  $main::opt_lib_prefix = "";
-
-  $main::opt_text = 0;
-  $main::opt_callgrind = 0;
-  $main::opt_list = "";
-  $main::opt_disasm = "";
-  $main::opt_symbols = 0;
-  $main::opt_gv = 0;
-  $main::opt_web = 0;
-  $main::opt_dot = 0;
-  $main::opt_ps = 0;
-  $main::opt_pdf = 0;
-  $main::opt_gif = 0;
-  $main::opt_svg = 0;
-  $main::opt_raw = 0;
-
-  $main::opt_nodecount = 80;
-  $main::opt_nodefraction = 0.005;
-  $main::opt_edgefraction = 0.001;
-  $main::opt_focus = '';
-  $main::opt_ignore = '';
-  $main::opt_scale = 0;
-  $main::opt_heapcheck = 0;
-  $main::opt_seconds = 30;
-  $main::opt_lib = "";
-
-  $main::opt_inuse_space   = 0;
-  $main::opt_inuse_objects = 0;
-  $main::opt_alloc_space   = 0;
-  $main::opt_alloc_objects = 0;
-  $main::opt_show_bytes    = 0;
-  $main::opt_drop_negative = 0;
-  $main::opt_interactive   = 0;
-
-  $main::opt_total_delay = 0;
-  $main::opt_contentions = 0;
-  $main::opt_mean_delay = 0;
-
-  $main::opt_tools   = "";
-  $main::opt_debug   = 0;
-  $main::opt_test    = 0;
-
-  # These are undocumented flags used only by unittests.
-  $main::opt_test_stride = 0;
-
-  # Are we using $SYMBOL_PAGE?
-  $main::use_symbol_page = 0;
-
-  # Files returned by TempName.
-  %main::tempnames = ();
-
-  # Type of profile we are dealing with
-  # Supported types:
-  #     cpu
-  #     heap
-  #     growth
-  #     contention
-  $main::profile_type = '';     # Empty type means "unknown"
-
-  GetOptions("help!"          => \$main::opt_help,
-             "version!"       => \$main::opt_version,
-             "cum!"           => \$main::opt_cum,
-             "base=s"         => \$main::opt_base,
-             "seconds=i"      => \$main::opt_seconds,
-             "add_lib=s"      => \$main::opt_lib,
-             "lib_prefix=s"   => \$main::opt_lib_prefix,
-             "functions!"     => \$main::opt_functions,
-             "lines!"         => \$main::opt_lines,
-             "addresses!"     => \$main::opt_addresses,
-             "files!"         => \$main::opt_files,
-             "text!"          => \$main::opt_text,
-             "callgrind!"     => \$main::opt_callgrind,
-             "list=s"         => \$main::opt_list,
-             "disasm=s"       => \$main::opt_disasm,
-             "symbols!"       => \$main::opt_symbols,
-             "gv!"            => \$main::opt_gv,
-             "web!"           => \$main::opt_web,
-             "dot!"           => \$main::opt_dot,
-             "ps!"            => \$main::opt_ps,
-             "pdf!"           => \$main::opt_pdf,
-             "svg!"           => \$main::opt_svg,
-             "gif!"           => \$main::opt_gif,
-             "raw!"           => \$main::opt_raw,
-             "interactive!"   => \$main::opt_interactive,
-             "nodecount=i"    => \$main::opt_nodecount,
-             "nodefraction=f" => \$main::opt_nodefraction,
-             "edgefraction=f" => \$main::opt_edgefraction,
-             "focus=s"        => \$main::opt_focus,
-             "ignore=s"       => \$main::opt_ignore,
-             "scale=i"        => \$main::opt_scale,
-             "heapcheck"      => \$main::opt_heapcheck,
-             "inuse_space!"   => \$main::opt_inuse_space,
-             "inuse_objects!" => \$main::opt_inuse_objects,
-             "alloc_space!"   => \$main::opt_alloc_space,
-             "alloc_objects!" => \$main::opt_alloc_objects,
-             "show_bytes!"    => \$main::opt_show_bytes,
-             "drop_negative!" => \$main::opt_drop_negative,
-             "total_delay!"   => \$main::opt_total_delay,
-             "contentions!"   => \$main::opt_contentions,
-             "mean_delay!"    => \$main::opt_mean_delay,
-             "tools=s"        => \$main::opt_tools,
-             "test!"          => \$main::opt_test,
-             "debug!"         => \$main::opt_debug,
-             # Undocumented flags used only by unittests:
-             "test_stride=i"  => \$main::opt_test_stride,
-      ) || usage("Invalid option(s)");
-
-  # Deal with the standard --help and --version
-  if ($main::opt_help) {
-    print usage_string();
-    exit(0);
-  }
-
-  if ($main::opt_version) {
-    print version_string();
-    exit(0);
-  }
-
-  # Disassembly/listing/symbols mode requires address-level info
-  if ($main::opt_disasm || $main::opt_list || $main::opt_symbols) {
-    $main::opt_functions = 0;
-    $main::opt_lines = 0;
-    $main::opt_addresses = 1;
-    $main::opt_files = 0;
-  }
-
-  # Check heap-profiling flags
-  if ($main::opt_inuse_space +
-      $main::opt_inuse_objects +
-      $main::opt_alloc_space +
-      $main::opt_alloc_objects > 1) {
-    usage("Specify at most on of --inuse/--alloc options");
-  }
-
-  # Check output granularities
-  my $grains =
-      $main::opt_functions +
-      $main::opt_lines +
-      $main::opt_addresses +
-      $main::opt_files +
-      0;
-  if ($grains > 1) {
-    usage("Only specify one output granularity option");
-  }
-  if ($grains == 0) {
-    $main::opt_functions = 1;
-  }
-
-  # Check output modes
-  my $modes =
-      $main::opt_text +
-      $main::opt_callgrind +
-      ($main::opt_list eq '' ? 0 : 1) +
-      ($main::opt_disasm eq '' ? 0 : 1) +
-      ($main::opt_symbols == 0 ? 0 : 1) +
-      $main::opt_gv +
-      $main::opt_web +
-      $main::opt_dot +
-      $main::opt_ps +
-      $main::opt_pdf +
-      $main::opt_svg +
-      $main::opt_gif +
-      $main::opt_raw +
-      $main::opt_interactive +
-      0;
-  if ($modes > 1) {
-    usage("Only specify one output mode");
-  }
-  if ($modes == 0) {
-    if (-t STDOUT) {  # If STDOUT is a tty, activate interactive mode
-      $main::opt_interactive = 1;
-    } else {
-      $main::opt_text = 1;
-    }
-  }
-
-  if ($main::opt_test) {
-    RunUnitTests();
-    # Should not return
-    exit(1);
-  }
-
-  # Binary name and profile arguments list
-  $main::prog = "";
-  @main::pfile_args = ();
-
-  # Remote profiling without a binary (using $SYMBOL_PAGE instead)
-  if (IsProfileURL($ARGV[0])) {
-    $main::use_symbol_page = 1;
-  } elsif ($ARGV[0] && IsSymbolizedProfileFile($ARGV[0])) {
-    $main::use_symbolized_profile = 1;
-    $main::prog = $UNKNOWN_BINARY;  # will be set later from the profile file
-  }
-
-  if ($main::use_symbol_page || $main::use_symbolized_profile) {
-    # We don't need a binary!
-    my %disabled = ('--lines' => $main::opt_lines,
-                    '--disasm' => $main::opt_disasm);
-    for my $option (keys %disabled) {
-      usage("$option cannot be used without a binary") if $disabled{$option};
-    }
-    # Set $main::prog later...
-    scalar(@ARGV) || usage("Did not specify profile file");
-  } elsif ($main::opt_symbols) {
-    # --symbols needs a binary-name (to run nm on, etc) but not profiles
-    $main::prog = shift(@ARGV) || usage("Did not specify program");
-  } else {
-    $main::prog = shift(@ARGV) || usage("Did not specify program");
-    scalar(@ARGV) || usage("Did not specify profile file");
-  }
-
-  # Parse profile file/location arguments
-  foreach my $farg (@ARGV) {
-    if ($farg =~ m/(.*)\@([0-9]+)(|\/.*)$/ ) {
-      my $machine = $1;
-      my $num_machines = $2;
-      my $path = $3;
-      for (my $i = 0; $i < $num_machines; $i++) {
-        unshift(@main::pfile_args, "$i.$machine$path");
-      }
-    } else {
-      unshift(@main::pfile_args, $farg);
-    }
-  }
-
-  if ($main::use_symbol_page) {
-    unless (IsProfileURL($main::pfile_args[0])) {
-      error("The first profile should be a remote form to use $SYMBOL_PAGE\n");
-    }
-    CheckSymbolPage();
-    $main::prog = FetchProgramName();
-  } elsif (!$main::use_symbolized_profile) {  # may not need objtools!
-    ConfigureObjTools($main::prog)
-  }
-
-  # Break the opt_lib_prefix into the prefix_list array
-  @prefix_list = split (',', $main::opt_lib_prefix);
-
-  # Remove trailing / from the prefixes, in the list to prevent
-  # searching things like /my/path//lib/mylib.so
-  foreach (@prefix_list) {
-    s|/+$||;
-  }
-}
-
-sub Main() {
-  Init();
-  $main::collected_profile = undef;
-  @main::profile_files = ();
-  $main::op_time = time();
-
-  # Printing symbols is special and requires a lot less info that most.
-  if ($main::opt_symbols) {
-    PrintSymbols(*STDIN);   # Get /proc/maps and symbols output from stdin
-    return;
-  }
-
-  # Fetch all profile data
-  FetchDynamicProfiles();
-
-  # this will hold symbols that we read from the profile files
-  my $symbol_map = {};
-
-  # Read one profile, pick the last item on the list
-  my $data = ReadProfile($main::prog, pop(@main::profile_files));
-  my $profile = $data->{profile};
-  my $pcs = $data->{pcs};
-  my $libs = $data->{libs};   # Info about main program and shared libraries
-  $symbol_map = MergeSymbols($symbol_map, $data->{symbols});
-
-  # Add additional profiles, if available.
-  if (scalar(@main::profile_files) > 0) {
-    foreach my $pname (@main::profile_files) {
-      my $data2 = ReadProfile($main::prog, $pname);
-      $profile = AddProfile($profile, $data2->{profile});
-      $pcs = AddPcs($pcs, $data2->{pcs});
-      $symbol_map = MergeSymbols($symbol_map, $data2->{symbols});
-    }
-  }
-
-  # Subtract base from profile, if specified
-  if ($main::opt_base ne '') {
-    my $base = ReadProfile($main::prog, $main::opt_base);
-    $profile = SubtractProfile($profile, $base->{profile});
-    $pcs = AddPcs($pcs, $base->{pcs});
-    $symbol_map = MergeSymbols($symbol_map, $base->{symbols});
-  }
-
-  # Get total data in profile
-  my $total = TotalProfile($profile);
-
-  # Collect symbols
-  my $symbols;
-  if ($main::use_symbolized_profile) {
-    $symbols = FetchSymbols($pcs, $symbol_map);
-  } elsif ($main::use_symbol_page) {
-    $symbols = FetchSymbols($pcs);
-  } else {
-    $symbols = ExtractSymbols($libs, $pcs);
-  }
-
-  # Remove uniniteresting stack items
-  $profile = RemoveUninterestingFrames($symbols, $profile);
-
-  # Focus?
-  if ($main::opt_focus ne '') {
-    $profile = FocusProfile($symbols, $profile, $main::opt_focus);
-  }
-
-  # Ignore?
-  if ($main::opt_ignore ne '') {
-    $profile = IgnoreProfile($symbols, $profile, $main::opt_ignore);
-  }
-
-  my $calls = ExtractCalls($symbols, $profile);
-
-  # Reduce profiles to required output granularity, and also clean
-  # each stack trace so a given entry exists at most once.
-  my $reduced = ReduceProfile($symbols, $profile);
-
-  # Get derived profiles
-  my $flat = FlatProfile($reduced);
-  my $cumulative = CumulativeProfile($reduced);
-
-  # Print
-  if (!$main::opt_interactive) {
-    if ($main::opt_disasm) {
-      PrintDisassembly($libs, $flat, $cumulative, $main::opt_disasm, $total);
-    } elsif ($main::opt_list) {
-      PrintListing($total, $libs, $flat, $cumulative, $main::opt_list, 0);
-    } elsif ($main::opt_text) {
-      # Make sure the output is empty when have nothing to report
-      # (only matters when --heapcheck is given but we must be
-      # compatible with old branches that did not pass --heapcheck always):
-      if ($total != 0) {
-        Infof("Total: %s %s\n", Unparse($total), Units());
-      }
-      PrintText($symbols, $flat, $cumulative, $total, -1);
-    } elsif ($main::opt_raw) {
-      PrintSymbolizedProfile($symbols, $profile, $main::prog);
-    } elsif ($main::opt_callgrind) {
-      PrintCallgrind($calls);
-    } else {
-      if (PrintDot($main::prog, $symbols, $profile, $flat, $cumulative, $total)) {
-        if ($main::opt_gv) {
-          RunGV(TempName($main::next_tmpfile, "ps"), "");
-        } elsif ($main::opt_web) {
-          my $tmp = TempName($main::next_tmpfile, "svg");
-          RunWeb($tmp);
-          # The command we run might hand the file name off
-          # to an already running browser instance and then exit.
-          # Normally, we'd remove $tmp on exit (right now),
-          # but fork a child to remove $tmp a little later, so that the
-          # browser has time to load it first.
-          delete $main::tempnames{$tmp};
-          if (fork() == 0) {
-            sleep 5;
-            unlink($tmp);
-            exit(0);
-          }
-        }
-      } else {
-        exit(1);
-      }
-    }
-  } else {
-    InteractiveMode($profile, $symbols, $libs, $total);
-  }
-
-  cleanup();
-  exit(0);
-}
-
-##### Entry Point #####
-
-Main();
-
-# Temporary code to detect if we're running on a Goobuntu system.
-# These systems don't have the right stuff installed for the special
-# Readline libraries to work, so as a temporary workaround, we default
-# to using the normal stdio code, rather than the fancier readline-based
-# code
-sub ReadlineMightFail {
-  if (-e '/lib/libtermcap.so.2') {
-    return 0;  # libtermcap exists, so readline should be okay
-  } else {
-    return 1;
-  }
-}
-
-sub RunGV {
-  my $fname = shift;
-  my $bg = shift;       # "" or " &" if we should run in background
-  if (!system("$GV --version >$DEVNULL 2>&1")) {
-    # Options using double dash are supported by this gv version.
-    # Also, turn on noantialias to better handle bug in gv for
-    # postscript files with large dimensions.
-    # TODO: Maybe we should not pass the --noantialias flag
-    # if the gv version is known to work properly without the flag.
-    system("$GV --scale=$main::opt_scale --noantialias " . $fname . $bg);
-  } else {
-    # Old gv version - only supports options that use single dash.
-    print STDERR "$GV -scale $main::opt_scale\n";
-    system("$GV -scale $main::opt_scale " . $fname . $bg);
-  }
-}
-
-sub RunWeb {
-  my $fname = shift;
-  print STDERR "Loading web page file:///$fname\n";
-
-  if (`uname` =~ /Darwin/) {
-    # OS X: open will use standard preference for SVG files.
-    system("/usr/bin/open", $fname);
-    return;
-  }
-
-  if (`uname` =~ /CYGWIN/) {
-    # Windows(cygwin): open will use standard preference for SVG files.
-    my $winname = `cygpath -wa $fname`;
-    system("explorer.exe", $winname);
-    return;
-  }
-
-  # Some kind of Unix; try generic symlinks, then specific browsers.
-  # (Stop once we find one.)
-  # Works best if the browser is already running.
-  my @alt = (
-    "/etc/alternatives/gnome-www-browser",
-    "/etc/alternatives/x-www-browser",
-    "google-chrome",
-    "firefox",
-  );
-  foreach my $b (@alt) {
-    if (system($b, $fname) == 0) {
-      return;
-    }
-  }
-
-  print STDERR "Could not load web browser.\n";
-}
-
-sub RunKcachegrind {
-  my $fname = shift;
-  my $bg = shift;       # "" or " &" if we should run in background
-  print STDERR "Starting '$KCACHEGRIND " . $fname . $bg . "'\n";
-  system("$KCACHEGRIND " . $fname . $bg);
-}
-
-
-##### Interactive helper routines #####
-
-sub InteractiveMode {
-  $| = 1;  # Make output unbuffered for interactive mode
-  my ($orig_profile, $symbols, $libs, $total) = @_;
-
-  print STDERR "Welcome to pprof!  For help, type 'help'.\n";
-
-  # Use ReadLine if it's installed and input comes from a console.
-  if ( -t STDIN &&
-       !ReadlineMightFail() &&
-       defined(eval {require Term::ReadLine}) ) {
-    my $term = new Term::ReadLine 'pprof';
-    while ( defined ($_ = $term->readline('(pprof) '))) {
-      $term->addhistory($_) if /\S/;
-      if (!InteractiveCommand($orig_profile, $symbols, $libs, $total, $_)) {
-        last;    # exit when we get an interactive command to quit
-      }
-    }
-  } else {       # don't have readline
-    while (1) {
-      print STDERR "(pprof) ";
-      $_ = <STDIN>;
-      last if ! defined $_ ;
-      s/\r//g;         # turn windows-looking lines into unix-looking lines
-
-      # Save some flags that might be reset by InteractiveCommand()
-      my $save_opt_lines = $main::opt_lines;
-
-      if (!InteractiveCommand($orig_profile, $symbols, $libs, $total, $_)) {
-        last;    # exit when we get an interactive command to quit
-      }
-
-      # Restore flags
-      $main::opt_lines = $save_opt_lines;
-    }
-  }
-}
-
-# Takes two args: orig profile, and command to run.
-# Returns 1 if we should keep going, or 0 if we were asked to quit
-sub InteractiveCommand {
-  my($orig_profile, $symbols, $libs, $total, $command) = @_;
-  $_ = $command;                # just to make future m//'s easier
-  if (!defined($_)) {
-    print STDERR "\n";
-    return 0;
-  }
-  if (m/^\s*quit/) {
-    return 0;
-  }
-  if (m/^\s*help/) {
-    InteractiveHelpMessage();
-    return 1;
-  }
-  # Clear all the mode options -- mode is controlled by "$command"
-  $main::opt_text = 0;
-  $main::opt_callgrind = 0;
-  $main::opt_disasm = 0;
-  $main::opt_list = 0;
-  $main::opt_gv = 0;
-  $main::opt_cum = 0;
-
-  if (m/^\s*(text|top)(\d*)\s*(.*)/) {
-    $main::opt_text = 1;
-
-    my $line_limit = ($2 ne "") ? int($2) : 10;
-
-    my $routine;
-    my $ignore;
-    ($routine, $ignore) = ParseInteractiveArgs($3);
-
-    my $profile = ProcessProfile($total, $orig_profile, $symbols, "", $ignore);
-    my $reduced = ReduceProfile($symbols, $profile);
-
-    # Get derived profiles
-    my $flat = FlatProfile($reduced);
-    my $cumulative = CumulativeProfile($reduced);
-
-    PrintText($symbols, $flat, $cumulative, $total, $line_limit);
-    return 1;
-  }
-  if (m/^\s*callgrind\s*([^ \n]*)/) {
-    $main::opt_callgrind = 1;
-
-    # Get derived profiles
-    my $calls = ExtractCalls($symbols, $orig_profile);
-    my $filename = $1;
-    if ( $1 eq '' ) {
-      $filename = TempName($main::next_tmpfile, "callgrind");
-    }
-    PrintCallgrind($calls, $filename);
-    if ( $1 eq '' ) {
-      RunKcachegrind($filename, " & ");
-      $main::next_tmpfile++;
-    }
-
-    return 1;
-  }
-  if (m/^\s*(web)?list\s*(.+)/) {
-    my $html = (defined($1) && ($1 eq "web"));
-    $main::opt_list = 1;
-
-    my $routine;
-    my $ignore;
-    ($routine, $ignore) = ParseInteractiveArgs($2);
-
-    my $profile = ProcessProfile($total, $orig_profile, $symbols, "", $ignore);
-    my $reduced = ReduceProfile($symbols, $profile);
-
-    # Get derived profiles
-    my $flat = FlatProfile($reduced);
-    my $cumulative = CumulativeProfile($reduced);
-
-    PrintListing($total, $libs, $flat, $cumulative, $routine, $html);
-    return 1;
-  }
-  if (m/^\s*disasm\s*(.+)/) {
-    $main::opt_disasm = 1;
-
-    my $routine;
-    my $ignore;
-    ($routine, $ignore) = ParseInteractiveArgs($1);
-
-    # Process current profile to account for various settings
-    my $profile = ProcessProfile($total, $orig_profile, $symbols, "", $ignore);
-    my $reduced = ReduceProfile($symbols, $profile);
-
-    # Get derived profiles
-    my $flat = FlatProfile($reduced);
-    my $cumulative = CumulativeProfile($reduced);
-
-    PrintDisassembly($libs, $flat, $cumulative, $routine, $total);
-    return 1;
-  }
-  if (m/^\s*(gv|web)\s*(.*)/) {
-    $main::opt_gv = 0;
-    $main::opt_web = 0;
-    if ($1 eq "gv") {
-      $main::opt_gv = 1;
-    } elsif ($1 eq "web") {
-      $main::opt_web = 1;
-    }
-
-    my $focus;
-    my $ignore;
-    ($focus, $ignore) = ParseInteractiveArgs($2);
-
-    # Process current profile to account for various settings
-    my $profile = ProcessProfile($total, $orig_profile, $symbols, $focus, $ignore);
-    my $reduced = ReduceProfile($symbols, $profile);
-
-    # Get derived profiles
-    my $flat = FlatProfile($reduced);
-    my $cumulative = CumulativeProfile($reduced);
-
-    if (PrintDot($main::prog, $symbols, $profile, $flat, $cumulative, $total)) {
-      if ($main::opt_gv) {
-        RunGV(TempName($main::next_tmpfile, "ps"), " &");
-      } elsif ($main::opt_web) {
-        RunWeb(TempName($main::next_tmpfile, "svg"));
-      }
-      $main::next_tmpfile++;
-    }
-    return 1;
-  }
-  if (m/^\s*$/) {
-    return 1;
-  }
-  print STDERR "Unknown command: try 'help'.\n";
-  return 1;
-}
-
-
-sub ProcessProfile {
-  my $total_count = shift;
-  my $orig_profile = shift;
-  my $symbols = shift;
-  my $focus = shift;
-  my $ignore = shift;
-
-  # Process current profile to account for various settings
-  my $profile = $orig_profile;
-  printf("Total: %s %s\n", Unparse($total_count), Units());
-  if ($focus ne '') {
-    $profile = FocusProfile($symbols, $profile, $focus);
-    my $focus_count = TotalProfile($profile);
-    Infof("After focusing on '%s': %s %s of %s (%0.1f%%)\n",
-           $focus,
-           Unparse($focus_count), Units(),
-           Unparse($total_count), ($focus_count*100.0) / $total_count);
-  }
-  if ($ignore ne '') {
-    $profile = IgnoreProfile($symbols, $profile, $ignore);
-    my $ignore_count = TotalProfile($profile);
-    Infof("After ignoring '%s': %s %s of %s (%0.1f%%)\n",
-           $ignore,
-           Unparse($ignore_count), Units(),
-           Unparse($total_count),
-           ($ignore_count*100.0) / $total_count);
-  }
-
-  return $profile;
-}
-
-sub InteractiveHelpMessage {
-  print STDERR <<ENDOFHELP;
-Interactive pprof mode
-
-Commands:
-  gv
-  gv [focus] [-ignore1] [-ignore2]
-      Show graphical hierarchical display of current profile.  Without
-      any arguments, shows all samples in the profile.  With the optional
-      "focus" argument, restricts the samples shown to just those where
-      the "focus" regular expression matches a routine name on the stack
-      trace.
-
-  web
-  web [focus] [-ignore1] [-ignore2]
-      Like GV, but displays profile in your web browser instead of using
-      Ghostview. Works best if your web browser is already running.
-      To change the browser that gets used:
-      On Linux, set the /etc/alternatives/gnome-www-browser symlink.
-      On OS X, change the Finder association for SVG files.
-
-  list [routine_regexp] [-ignore1] [-ignore2]
-      Show source listing of routines whose names match "routine_regexp"
-
-  weblist [routine_regexp] [-ignore1] [-ignore2]
-      Displays a source listing of routines whose names match "routine_regexp"
-      in a web browser.  You can click on source lines to view the
-      corresponding disassembly.
-
-  top [--cum] [-ignore1] [-ignore2]
-  top20 [--cum] [-ignore1] [-ignore2]
-  top37 [--cum] [-ignore1] [-ignore2]
-      Show top lines ordered by flat profile count, or cumulative count
-      if --cum is specified.  If a number is present after 'top', the
-      top K routines will be shown (defaults to showing the top 10)
-
-  disasm [routine_regexp] [-ignore1] [-ignore2]
-      Show disassembly of routines whose names match "routine_regexp",
-      annotated with sample counts.
-
-  callgrind
-  callgrind [filename]
-      Generates callgrind file. If no filename is given, kcachegrind is called.
-
-  help - This listing
-  quit or ^D - End pprof
-
-For commands that accept optional -ignore tags, samples where any routine in
-the stack trace matches the regular expression in any of the -ignore
-parameters will be ignored.
-
-Further pprof details are available at this location (or one similar):
-
- /usr/doc/google-perftools-$PPROF_VERSION/cpu_profiler.html
- /usr/doc/google-perftools-$PPROF_VERSION/heap_profiler.html
-
-ENDOFHELP
-}
-sub ParseInteractiveArgs {
-  my $args = shift;
-  my $focus = "";
-  my $ignore = "";
-  my @x = split(/ +/, $args);
-  foreach $a (@x) {
-    if ($a =~ m/^(--|-)lines$/) {
-      $main::opt_lines = 1;
-    } elsif ($a =~ m/^(--|-)cum$/) {
-      $main::opt_cum = 1;
-    } elsif ($a =~ m/^-(.*)/) {
-      $ignore .= (($ignore ne "") ? "|" : "" ) . $1;
-    } else {
-      $focus .= (($focus ne "") ? "|" : "" ) . $a;
-    }
-  }
-  if ($ignore ne "") {
-    print STDERR "Ignoring samples in call stacks that match '$ignore'\n";
-  }
-  return ($focus, $ignore);
-}
-
-##### Output code #####
-
-sub TempName {
-  my $fnum = shift;
-  my $ext = shift;
-  my $file = "$main::tmpfile_ps.$fnum.$ext";
-  $main::tempnames{$file} = 1;
-  return $file;
-}
-
-# Print profile data in packed binary format (64-bit) to standard out
-sub PrintProfileData {
-  my $profile = shift;
-
-  # print header (64-bit style)
-  # (zero) (header-size) (version) (sample-period) (zero)
-  print pack('L*', 0, 0, 3, 0, 0, 0, 1, 0, 0, 0);
-
-  foreach my $k (keys(%{$profile})) {
-    my $count = $profile->{$k};
-    my @addrs = split(/\n/, $k);
-    if ($#addrs >= 0) {
-      my $depth = $#addrs + 1;
-      # int(foo / 2**32) is the only reliable way to get rid of bottom
-      # 32 bits on both 32- and 64-bit systems.
-      print pack('L*', $count & 0xFFFFFFFF, int($count / 2**32));
-      print pack('L*', $depth & 0xFFFFFFFF, int($depth / 2**32));
-
-      foreach my $full_addr (@addrs) {
-        my $addr = $full_addr;
-        $addr =~ s/0x0*//;  # strip off leading 0x, zeroes
-        if (length($addr) > 16) {
-          print STDERR "Invalid address in profile: $full_addr\n";
-          next;
-        }
-        my $low_addr = substr($addr, -8);       # get last 8 hex chars
-        my $high_addr = substr($addr, -16, 8);  # get up to 8 more hex chars
-        print pack('L*', hex('0x' . $low_addr), hex('0x' . $high_addr));
-      }
-    }
-  }
-}
-
-# Print symbols and profile data
-sub PrintSymbolizedProfile {
-  my $symbols = shift;
-  my $profile = shift;
-  my $prog = shift;
-
-  $SYMBOL_PAGE =~ m,[^/]+$,;    # matches everything after the last slash
-  my $symbol_marker = $&;
-
-  print '--- ', $symbol_marker, "\n";
-  if (defined($prog)) {
-    print 'binary=', $prog, "\n";
-  }
-  while (my ($pc, $name) = each(%{$symbols})) {
-    my $sep = ' ';
-    print '0x', $pc;
-    # We have a list of function names, which include the inlined
-    # calls.  They are separated (and terminated) by --, which is
-    # illegal in function names.
-    for (my $j = 2; $j <= $#{$name}; $j += 3) {
-      print $sep, $name->[$j];
-      $sep = '--';
-    }
-    print "\n";
-  }
-  print '---', "\n";
-
-  $PROFILE_PAGE =~ m,[^/]+$,;    # matches everything after the last slash
-  my $profile_marker = $&;
-  print '--- ', $profile_marker, "\n";
-  if (defined($main::collected_profile)) {
-    # if used with remote fetch, simply dump the collected profile to output.
-    open(SRC, "<$main::collected_profile");
-    while (<SRC>) {
-      print $_;
-    }
-    close(SRC);
-  } else {
-    # dump a cpu-format profile to standard out
-    PrintProfileData($profile);
-  }
-}
-
-# Print information conditionally filtered out depending on the output
-# format.
-sub Infof {
-  my $format = shift;
-  my @args = @_;
-  return if $main::opt_svg;
-  printf($format, @args);
-}
-
-# Print text output
-sub PrintText {
-  my $symbols = shift;
-  my $flat = shift;
-  my $cumulative = shift;
-  my $total = shift;
-  my $line_limit = shift;
-
-  # Which profile to sort by?
-  my $s = $main::opt_cum ? $cumulative : $flat;
-
-  my $running_sum = 0;
-  my $lines = 0;
-  foreach my $k (sort { GetEntry($s, $b) <=> GetEntry($s, $a) || $a cmp $b }
-                 keys(%{$cumulative})) {
-    my $f = GetEntry($flat, $k);
-    my $c = GetEntry($cumulative, $k);
-    $running_sum += $f;
-
-    my $sym = $k;
-    if (exists($symbols->{$k})) {
-      $sym = $symbols->{$k}->[0] . " " . $symbols->{$k}->[1];
-      if ($main::opt_addresses) {
-        $sym = $k . " " . $sym;
-      }
-    }
-
-    if ($f != 0 || $c != 0) {
-      printf("%8s %6s %6s %8s %6s %s\n",
-             Unparse($f),
-             Percent($f, $total),
-             Percent($running_sum, $total),
-             Unparse($c),
-             Percent($c, $total),
-             $sym);
-    }
-    $lines++;
-    last if ($line_limit >= 0 && $lines >= $line_limit);
-  }
-}
-
-# Print the call graph in a way that's suiteable for callgrind.
-sub PrintCallgrind {
-  my $calls = shift;
-  my $filename;
-  if ($main::opt_interactive) {
-    $filename = shift;
-    print STDERR "Writing callgrind file to '$filename'.\n"
-  } else {
-    $filename = "&STDOUT";
-  }
-  open(CG, ">".$filename );
-  printf CG ("events: Hits\n\n");
-  foreach my $call ( map { $_->[0] }
-                     sort { $a->[1] cmp $b ->[1] ||
-                            $a->[2] <=> $b->[2] }
-                     map { /([^:]+):(\d+):([^ ]+)( -> ([^:]+):(\d+):(.+))?/;
-                           [$_, $1, $2] }
-                     keys %$calls ) {
-    my $count = int($calls->{$call});
-    $call =~ /([^:]+):(\d+):([^ ]+)( -> ([^:]+):(\d+):(.+))?/;
-    my ( $caller_file, $caller_line, $caller_function,
-         $callee_file, $callee_line, $callee_function ) =
-       ( $1, $2, $3, $5, $6, $7 );
-
-    printf CG ("fl=$caller_file\nfn=$caller_function\n");
-    if (defined $6) {
-      printf CG ("cfl=$callee_file\n");
-      printf CG ("cfn=$callee_function\n");
-      printf CG ("calls=$count $callee_line\n");
-    }
-    printf CG ("$caller_line $count\n\n");
-  }
-}
-
-# Print disassembly for all all routines that match $main::opt_disasm
-sub PrintDisassembly {
-  my $libs = shift;
-  my $flat = shift;
-  my $cumulative = shift;
-  my $disasm_opts = shift;
-  my $total = shift;
-
-  foreach my $lib (@{$libs}) {
-    my $symbol_table = GetProcedureBoundaries($lib->[0], $disasm_opts);
-    my $offset = AddressSub($lib->[1], $lib->[3]);
-    foreach my $routine (sort ByName keys(%{$symbol_table})) {
-      my $start_addr = $symbol_table->{$routine}->[0];
-      my $end_addr = $symbol_table->{$routine}->[1];
-      # See if there are any samples in this routine
-      my $length = hex(AddressSub($end_addr, $start_addr));
-      my $addr = AddressAdd($start_addr, $offset);
-      for (my $i = 0; $i < $length; $i++) {
-        if (defined($cumulative->{$addr})) {
-          PrintDisassembledFunction($lib->[0], $offset,
-                                    $routine, $flat, $cumulative,
-                                    $start_addr, $end_addr, $total);
-          last;
-        }
-        $addr = AddressInc($addr);
-      }
-    }
-  }
-}
-
-# Return reference to array of tuples of the form:
-#       [start_address, filename, linenumber, instruction, limit_address]
-# E.g.,
-#       ["0x806c43d", "/foo/bar.cc", 131, "ret", "0x806c440"]
-sub Disassemble {
-  my $prog = shift;
-  my $offset = shift;
-  my $start_addr = shift;
-  my $end_addr = shift;
-
-  my $objdump = $obj_tool_map{"objdump"};
-  my $cmd = sprintf("$objdump -C -d -l --no-show-raw-insn " .
-                    "--start-address=0x$start_addr " .
-                    "--stop-address=0x$end_addr $prog");
-
-  if (system("$objdump --help >$DEVNULL 2>&1") != 0) {
-    # objdump must not exist.  Fall back to go tool objdump.
-    $objdump = "go tool objdump";
-    $cmd = "$objdump $prog 0x$start_addr 0x$end_addr";
-  }
-
-  open(OBJDUMP, "$cmd |") || error("$objdump: $!\n");
-  my @result = ();
-  my $filename = "";
-  my $linenumber = -1;
-  my $last = ["", "", "", ""];
-  while (<OBJDUMP>) {
-    s/\r//g;         # turn windows-looking lines into unix-looking lines
-    chop;
-    if (m|\s*(.+):(\d+)\s*$|) {
-      # Location line of the form:
-      #   <filename>:<linenumber>
-      $filename = $1;
-      $linenumber = $2;
-    } elsif (m/^ +([0-9a-f]+):\s*(.*)/) {
-      # Disassembly line -- zero-extend address to full length
-      my $addr = HexExtend($1);
-      my $k = AddressAdd($addr, $offset);
-      $last->[4] = $k;   # Store ending address for previous instruction
-      $last = [$k, $filename, $linenumber, $2, $end_addr];
-      push(@result, $last);
-    }
-  }
-  close(OBJDUMP);
-  return @result;
-}
-
-# The input file should contain lines of the form /proc/maps-like
-# output (same format as expected from the profiles) or that looks
-# like hex addresses (like "0xDEADBEEF").  We will parse all
-# /proc/maps output, and for all the hex addresses, we will output
-# "short" symbol names, one per line, in the same order as the input.
-sub PrintSymbols {
-  my $maps_and_symbols_file = shift;
-
-  # ParseLibraries expects pcs to be in a set.  Fine by us...
-  my @pclist = ();   # pcs in sorted order
-  my $pcs = {};
-  my $map = "";
-  foreach my $line (<$maps_and_symbols_file>) {
-    $line =~ s/\r//g;    # turn windows-looking lines into unix-looking lines
-    if ($line =~ /\b(0x[0-9a-f]+)\b/i) {
-      push(@pclist, HexExtend($1));
-      $pcs->{$pclist[-1]} = 1;
-    } else {
-      $map .= $line;
-    }
-  }
-
-  my $libs = ParseLibraries($main::prog, $map, $pcs);
-  my $symbols = ExtractSymbols($libs, $pcs);
-
-  foreach my $pc (@pclist) {
-    # ->[0] is the shortname, ->[2] is the full name
-    print(($symbols->{$pc}->[0] || "??") . "\n");
-  }
-}
-
-
-# For sorting functions by name
-sub ByName {
-  return ShortFunctionName($a) cmp ShortFunctionName($b);
-}
-
-# Print source-listing for all all routines that match $main::opt_list
-sub PrintListing {
-  my $total = shift;
-  my $libs = shift;
-  my $flat = shift;
-  my $cumulative = shift;
-  my $list_opts = shift;
-  my $html = shift;
-
-  my $output = \*STDOUT;
-  my $fname = "";
-
-
-  if ($html) {
-    # Arrange to write the output to a temporary file
-    $fname = TempName($main::next_tmpfile, "html");
-    $main::next_tmpfile++;
-    if (!open(TEMP, ">$fname")) {
-      print STDERR "$fname: $!\n";
-      return;
-    }
-    $output = \*TEMP;
-    print $output HtmlListingHeader();
-    printf $output ("<div class=\"legend\">%s<br>Total: %s %s</div>\n",
-                    $main::prog, Unparse($total), Units());
-  }
-
-  my $listed = 0;
-  foreach my $lib (@{$libs}) {
-    my $symbol_table = GetProcedureBoundaries($lib->[0], $list_opts);
-    my $offset = AddressSub($lib->[1], $lib->[3]);
-    foreach my $routine (sort ByName keys(%{$symbol_table})) {
-      # Print if there are any samples in this routine
-      my $start_addr = $symbol_table->{$routine}->[0];
-      my $end_addr = $symbol_table->{$routine}->[1];
-      my $length = hex(AddressSub($end_addr, $start_addr));
-      my $addr = AddressAdd($start_addr, $offset);
-      for (my $i = 0; $i < $length; $i++) {
-        if (defined($cumulative->{$addr})) {
-          $listed += PrintSource(
-            $lib->[0], $offset,
-            $routine, $flat, $cumulative,
-            $start_addr, $end_addr,
-            $html,
-            $output);
-          last;
-        }
-        $addr = AddressInc($addr);
-      }
-    }
-  }
-
-  if ($html) {
-    if ($listed > 0) {
-      print $output HtmlListingFooter();
-      close($output);
-      RunWeb($fname);
-    } else {
-      close($output);
-      unlink($fname);
-    }
-  }
-}
-
-sub HtmlListingHeader {
-  return <<'EOF';
-<!DOCTYPE html>
-<html>
-<head>
-<title>Pprof listing</title>
-<style type="text/css">
-body {
-  font-family: sans-serif;
-}
-h1 {
-  font-size: 1.5em;
-  margin-bottom: 4px;
-}
-.legend {
-  font-size: 1.25em;
-}
-.line {
-  color: #aaaaaa;
-}
-.livesrc {
-  color: #0000ff;
-  cursor: pointer;
-}
-.livesrc:hover {
-  background-color: #cccccc;
-}
-.asm {
-  color: #888888;
-  display: none;
-}
-</style>
-<script type="text/javascript">
-function pprof_toggle_asm(e) {
-  var target;
-  if (!e) e = window.event;
-  if (e.target) target = e.target;
-  else if (e.srcElement) target = e.srcElement;
-
-  if (target && target.className == "livesrc") {
-    var asm = target.nextSibling;
-    if (asm && asm.className == "asm") {
-      asm.style.display = (asm.style.display == "block" ? "none" : "block");
-      e.preventDefault();
-      return false;
-    }
-  }
-}
-</script>
-</head>
-<body>
-EOF
-}
-
-sub HtmlListingFooter {
-  return <<'EOF';
-</body>
-</html>
-EOF
-}
-
-sub HtmlEscape {
-  my $text = shift;
-  $text =~ s/&/&/g;
-  $text =~ s/</</g;
-  $text =~ s/>/>/g;
-  return $text;
-}
-
-# Returns the indentation of the line, if it has any non-whitespace
-# characters.  Otherwise, returns -1.
-sub Indentation {
-  my $line = shift;
-  if (m/^(\s*)\S/) {
-    return length($1);
-  } else {
-    return -1;
-  }
-}
-
-# Print source-listing for one routine
-sub PrintSource {
-  my $prog = shift;
-  my $offset = shift;
-  my $routine = shift;
-  my $flat = shift;
-  my $cumulative = shift;
-  my $start_addr = shift;
-  my $end_addr = shift;
-  my $html = shift;
-  my $output = shift;
-
-  # Disassemble all instructions (just to get line numbers)
-  my @instructions = Disassemble($prog, $offset, $start_addr, $end_addr);
-
-  # Hack 1: assume that the first source file encountered in the
-  # disassembly contains the routine
-  my $filename = undef;
-  for (my $i = 0; $i <= $#instructions; $i++) {
-    if ($instructions[$i]->[2] >= 0) {
-      $filename = $instructions[$i]->[1];
-      last;
-    }
-  }
-  if (!defined($filename)) {
-    print STDERR "no filename found in $routine\n";
-    return 0;
-  }
-
-  # Hack 2: assume that the largest line number from $filename is the
-  # end of the procedure.  This is typically safe since if P1 contains
-  # an inlined call to P2, then P2 usually occurs earlier in the
-  # source file.  If this does not work, we might have to compute a
-  # density profile or just print all regions we find.
-  my $lastline = 0;
-  for (my $i = 0; $i <= $#instructions; $i++) {
-    my $f = $instructions[$i]->[1];
-    my $l = $instructions[$i]->[2];
-    if (($f eq $filename) && ($l > $lastline)) {
-      $lastline = $l;
-    }
-  }
-
-  # Hack 3: assume the first source location from "filename" is the start of
-  # the source code.
-  my $firstline = 1;
-  for (my $i = 0; $i <= $#instructions; $i++) {
-    if ($instructions[$i]->[1] eq $filename) {
-      $firstline = $instructions[$i]->[2];
-      last;
-    }
-  }
-
-  # Hack 4: Extend last line forward until its indentation is less than
-  # the indentation we saw on $firstline
-  my $oldlastline = $lastline;
-  {
-    if (!open(FILE, "<$filename")) {
-      print STDERR "$filename: $!\n";
-      return 0;
-    }
-    my $l = 0;
-    my $first_indentation = -1;
-    while (<FILE>) {
-      s/\r//g;         # turn windows-looking lines into unix-looking lines
-      $l++;
-      my $indent = Indentation($_);
-      if ($l >= $firstline) {
-        if ($first_indentation < 0 && $indent >= 0) {
-          $first_indentation = $indent;
-          last if ($first_indentation == 0);
-        }
-      }
-      if ($l >= $lastline && $indent >= 0) {
-        if ($indent >= $first_indentation) {
-          $lastline = $l+1;
-        } else {
-          last;
-        }
-      }
-    }
-    close(FILE);
-  }
-
-  # Assign all samples to the range $firstline,$lastline,
-  # Hack 4: If an instruction does not occur in the range, its samples
-  # are moved to the next instruction that occurs in the range.
-  my $samples1 = {};        # Map from line number to flat count
-  my $samples2 = {};        # Map from line number to cumulative count
-  my $running1 = 0;         # Unassigned flat counts
-  my $running2 = 0;         # Unassigned cumulative counts
-  my $total1 = 0;           # Total flat counts
-  my $total2 = 0;           # Total cumulative counts
-  my %disasm = ();          # Map from line number to disassembly
-  my $running_disasm = "";  # Unassigned disassembly
-  my $skip_marker = "---\n";
-  if ($html) {
-    $skip_marker = "";
-    for (my $l = $firstline; $l <= $lastline; $l++) {
-      $disasm{$l} = "";
-    }
-  }
-  foreach my $e (@instructions) {
-    # Add up counts for all address that fall inside this instruction
-    my $c1 = 0;
-    my $c2 = 0;
-    for (my $a = $e->[0]; $a lt $e->[4]; $a = AddressInc($a)) {
-      $c1 += GetEntry($flat, $a);
-      $c2 += GetEntry($cumulative, $a);
-    }
-
-    if ($html) {
-      $running_disasm .= sprintf("      %6s %6s \t\t%8s: %s\n",
-                                 HtmlPrintNumber($c1),
-                                 HtmlPrintNumber($c2),
-                                 $e->[0],
-                                 CleanDisassembly($e->[3]));
-    }
-
-    $running1 += $c1;
-    $running2 += $c2;
-    $total1 += $c1;
-    $total2 += $c2;
-    my $file = $e->[1];
-    my $line = $e->[2];
-    if (($file eq $filename) &&
-        ($line >= $firstline) &&
-        ($line <= $lastline)) {
-      # Assign all accumulated samples to this line
-      AddEntry($samples1, $line, $running1);
-      AddEntry($samples2, $line, $running2);
-      $running1 = 0;
-      $running2 = 0;
-      if ($html) {
-        $disasm{$line} .= $running_disasm;
-        $running_disasm = '';
-      }
-    }
-  }
-
-  # Assign any leftover samples to $lastline
-  AddEntry($samples1, $lastline, $running1);
-  AddEntry($samples2, $lastline, $running2);
-
-  if ($html) {
-    printf $output (
-      "<h1>%s</h1>%s\n<pre onClick=\"pprof_toggle_asm()\">\n" .
-      "Total:%6s %6s (flat / cumulative %s)\n",
-      HtmlEscape(ShortFunctionName($routine)),
-      HtmlEscape($filename),
-      Unparse($total1),
-      Unparse($total2),
-      Units());
-  } else {
-    printf $output (
-      "ROUTINE ====================== %s in %s\n" .
-      "%6s %6s Total %s (flat / cumulative)\n",
-      ShortFunctionName($routine),
-      $filename,
-      Unparse($total1),
-      Unparse($total2),
-      Units());
-  }
-  if (!open(FILE, "<$filename")) {
-    print STDERR "$filename: $!\n";
-    return 0;
-  }
-  my $l = 0;
-  while (<FILE>) {
-    s/\r//g;         # turn windows-looking lines into unix-looking lines
-    $l++;
-    if ($l >= $firstline - 5 &&
-        (($l <= $oldlastline + 5) || ($l <= $lastline))) {
-      chop;
-      my $text = $_;
-      if ($l == $firstline) { print $output $skip_marker; }
-      my $n1 = GetEntry($samples1, $l);
-      my $n2 = GetEntry($samples2, $l);
-      if ($html) {
-        my $dis = $disasm{$l};
-        if (!defined($dis) || $n1 + $n2 == 0) {
-          # No samples/disassembly for this source line
-          printf $output (
-            "<span class=\"line\">%5d</span> " .
-            "<span class=\"deadsrc\">%6s %6s %s</span>\n",
-            $l,
-            HtmlPrintNumber($n1),
-            HtmlPrintNumber($n2),
-            HtmlEscape($text));
-        } else {
-          printf $output (
-            "<span class=\"line\">%5d</span> " .
-            "<span class=\"livesrc\">%6s %6s %s</span>" .
-            "<span class=\"asm\">%s</span>\n",
-            $l,
-            HtmlPrintNumber($n1),
-            HtmlPrintNumber($n2),
-            HtmlEscape($text),
-            HtmlEscape($dis));
-        }
-      } else {
-        printf $output(
-          "%6s %6s %4d: %s\n",
-          UnparseAlt($n1),
-          UnparseAlt($n2),
-          $l,
-          $text);
-      }
-      if ($l == $lastline)  { print $output $skip_marker; }
-    };
-  }
-  close(FILE);
-  if ($html) {
-    print $output "</pre>\n";
-  }
-  return 1;
-}
-
-# Return the source line for the specified file/linenumber.
-# Returns undef if not found.
-sub SourceLine {
-  my $file = shift;
-  my $line = shift;
-
-  # Look in cache
-  if (!defined($main::source_cache{$file})) {
-    if (100 < scalar keys(%main::source_cache)) {
-      # Clear the cache when it gets too big
-      $main::source_cache = ();
-    }
-
-    # Read all lines from the file
-    if (!open(FILE, "<$file")) {
-      print STDERR "$file: $!\n";
-      $main::source_cache{$file} = [];  # Cache the negative result
-      return undef;
-    }
-    my $lines = [];
-    push(@{$lines}, "");        # So we can use 1-based line numbers as indices
-    while (<FILE>) {
-      push(@{$lines}, $_);
-    }
-    close(FILE);
-
-    # Save the lines in the cache
-    $main::source_cache{$file} = $lines;
-  }
-
-  my $lines = $main::source_cache{$file};
-  if (($line < 0) || ($line > $#{$lines})) {
-    return undef;
-  } else {
-    return $lines->[$line];
-  }
-}
-
-# Print disassembly for one routine with interspersed source if available
-sub PrintDisassembledFunction {
-  my $prog = shift;
-  my $offset = shift;
-  my $routine = shift;
-  my $flat = shift;
-  my $cumulative = shift;
-  my $start_addr = shift;
-  my $end_addr = shift;
-  my $total = shift;
-
-  # Disassemble all instructions
-  my @instructions = Disassemble($prog, $offset, $start_addr, $end_addr);
-
-  # Make array of counts per instruction
-  my @flat_count = ();
-  my @cum_count = ();
-  my $flat_total = 0;
-  my $cum_total = 0;
-  foreach my $e (@instructions) {
-    # Add up counts for all address that fall inside this instruction
-    my $c1 = 0;
-    my $c2 = 0;
-    for (my $a = $e->[0]; $a lt $e->[4]; $a = AddressInc($a)) {
-      $c1 += GetEntry($flat, $a);
-      $c2 += GetEntry($cumulative, $a);
-    }
-    push(@flat_count, $c1);
-    push(@cum_count, $c2);
-    $flat_total += $c1;
-    $cum_total += $c2;
-  }
-
-  # Print header with total counts
-  printf("ROUTINE ====================== %s\n" .
-         "%6s %6s %s (flat, cumulative) %.1f%% of total\n",
-         ShortFunctionName($routine),
-         Unparse($flat_total),
-         Unparse($cum_total),
-         Units(),
-         ($cum_total * 100.0) / $total);
-
-  # Process instructions in order
-  my $current_file = "";
-  for (my $i = 0; $i <= $#instructions; ) {
-    my $e = $instructions[$i];
-
-    # Print the new file name whenever we switch files
-    if ($e->[1] ne $current_file) {
-      $current_file = $e->[1];
-      my $fname = $current_file;
-      $fname =~ s|^\./||;   # Trim leading "./"
-
-      # Shorten long file names
-      if (length($fname) >= 58) {
-        $fname = "..." . substr($fname, -55);
-      }
-      printf("-------------------- %s\n", $fname);
-    }
-
-    # TODO: Compute range of lines to print together to deal with
-    # small reorderings.
-    my $first_line = $e->[2];
-    my $last_line = $first_line;
-    my %flat_sum = ();
-    my %cum_sum = ();
-    for (my $l = $first_line; $l <= $last_line; $l++) {
-      $flat_sum{$l} = 0;
-      $cum_sum{$l} = 0;
-    }
-
-    # Find run of instructions for this range of source lines
-    my $first_inst = $i;
-    while (($i <= $#instructions) &&
-           ($instructions[$i]->[2] >= $first_line) &&
-           ($instructions[$i]->[2] <= $last_line)) {
-      $e = $instructions[$i];
-      $flat_sum{$e->[2]} += $flat_count[$i];
-      $cum_sum{$e->[2]} += $cum_count[$i];
-      $i++;
-    }
-    my $last_inst = $i - 1;
-
-    # Print source lines
-    for (my $l = $first_line; $l <= $last_line; $l++) {
-      my $line = SourceLine($current_file, $l);
-      if (!defined($line)) {
-        $line = "?\n";
-        next;
-      } else {
-        $line =~ s/^\s+//;
-      }
-      printf("%6s %6s %5d: %s",
-             UnparseAlt($flat_sum{$l}),
-             UnparseAlt($cum_sum{$l}),
-             $l,
-             $line);
-    }
-
-    # Print disassembly
-    for (my $x = $first_inst; $x <= $last_inst; $x++) {
-      my $e = $instructions[$x];
-      my $address = $e->[0];
-      $address = AddressSub($address, $offset);  # Make relative to section
-      $address =~ s/^0x//;
-      $address =~ s/^0*//;
-
-      printf("%6s %6s    %8s: %6s\n",
-             UnparseAlt($flat_count[$x]),
-             UnparseAlt($cum_count[$x]),
-             $address,
-             CleanDisassembly($e->[3]));
-    }
-  }
-}
-
-# Print DOT graph
-sub PrintDot {
-  my $prog = shift;
-  my $symbols = shift;
-  my $raw = shift;
-  my $flat = shift;
-  my $cumulative = shift;
-  my $overall_total = shift;
-
-  # Get total
-  my $local_total = TotalProfile($flat);
-  my $nodelimit = int($main::opt_nodefraction * $local_total);
-  my $edgelimit = int($main::opt_edgefraction * $local_total);
-  my $nodecount = $main::opt_nodecount;
-
-  # Find nodes to include
-  my @list = (sort { abs(GetEntry($cumulative, $b)) <=>
-                     abs(GetEntry($cumulative, $a))
-                     || $a cmp $b }
-              keys(%{$cumulative}));
-  my $last = $nodecount - 1;
-  if ($last > $#list) {
-    $last = $#list;
-  }
-  while (($last >= 0) &&
-         (abs(GetEntry($cumulative, $list[$last])) <= $nodelimit)) {
-    $last--;
-  }
-  if ($last < 0) {
-    print STDERR "No nodes to print\n";
-    cleanup();
-    return 0;
-  }
-
-  if ($nodelimit > 0 || $edgelimit > 0) {
-    printf STDERR ("Dropping nodes with <= %s %s; edges with <= %s abs(%s)\n",
-                   Unparse($nodelimit), Units(),
-                   Unparse($edgelimit), Units());
-  }
-
-  # Open DOT output file
-  my $output;
-  if ($main::opt_gv) {
-    $output = "| $DOT -Tps2 >" . TempName($main::next_tmpfile, "ps");
-  } elsif ($main::opt_ps) {
-    $output = "| $DOT -Tps2";
-  } elsif ($main::opt_pdf) {
-    $output = "| $DOT -Tps2 | $PS2PDF - -";
-  } elsif ($main::opt_web || $main::opt_svg) {
-    # We need to post-process the SVG, so write to a temporary file always.
-    $output = "| $DOT -Tsvg >" . TempName($main::next_tmpfile, "svg");
-  } elsif ($main::opt_gif) {
-    $output = "| $DOT -Tgif";
-  } else {
-    $output = ">&STDOUT";
-  }
-  open(DOT, $output) || error("$output: $!\n");
-
-  # Title
-  printf DOT ("digraph \"%s; %s %s\" {\n",
-              $prog,
-              Unparse($overall_total),
-              Units());
-  if ($main::opt_pdf) {
-    # The output is more printable if we set the page size for dot.
-    printf DOT ("size=\"8,11\"\n");
-  }
-  printf DOT ("node [width=0.375,height=0.25];\n");
-
-  # Print legend
-  printf DOT ("Legend [shape=box,fontsize=24,shape=plaintext," .
-              "label=\"%s\\l%s\\l%s\\l%s\\l%s\\l\"];\n",
-              $prog,
-              sprintf("Total %s: %s", Units(), Unparse($overall_total)),
-              sprintf("Focusing on: %s", Unparse($local_total)),
-              sprintf("Dropped nodes with <= %s abs(%s)",
-                      Unparse($nodelimit), Units()),
-              sprintf("Dropped edges with <= %s %s",
-                      Unparse($edgelimit), Units())
-              );
-
-  # Print nodes
-  my %node = ();
-  my $nextnode = 1;
-  foreach my $a (@list[0..$last]) {
-    # Pick font size
-    my $f = GetEntry($flat, $a);
-    my $c = GetEntry($cumulative, $a);
-
-    my $fs = 8;
-    if ($local_total > 0) {
-      $fs = 8 + (50.0 * sqrt(abs($f * 1.0 / $local_total)));
-    }
-
-    $node{$a} = $nextnode++;
-    my $sym = $a;
-    $sym =~ s/\s+/\\n/g;
-    $sym =~ s/::/\\n/g;
-
-    # Extra cumulative info to print for non-leaves
-    my $extra = "";
-    if ($f != $c) {
-      $extra = sprintf("\\rof %s (%s)",
-                       Unparse($c),
-                       Percent($c, $overall_total));
-    }
-    my $style = "";
-    if ($main::opt_heapcheck) {
-      if ($f > 0) {
-        # make leak-causing nodes more visible (add a background)
-        $style = ",style=filled,fillcolor=gray"
-      } elsif ($f < 0) {
-        # make anti-leak-causing nodes (which almost never occur)
-        # stand out as well (triple border)
-        $style = ",peripheries=3"
-      }
-    }
-
-    printf DOT ("N%d [label=\"%s\\n%s (%s)%s\\r" .
-                "\",shape=box,fontsize=%.1f%s];\n",
-                $node{$a},
-                $sym,
-                Unparse($f),
-                Percent($f, $overall_total),
-                $extra,
-                $fs,
-                $style,
-               );
-  }
-
-  # Get edges and counts per edge
-  my %edge = ();
-  my $n;
-  foreach my $k (keys(%{$raw})) {
-    # TODO: omit low %age edges
-    $n = $raw->{$k};
-    my @translated = TranslateStack($symbols, $k);
-    for (my $i = 1; $i <= $#translated; $i++) {
-      my $src = $translated[$i];
-      my $dst = $translated[$i-1];
-      #next if ($src eq $dst);  # Avoid self-edges?
-      if (exists($node{$src}) && exists($node{$dst})) {
-        my $edge_label = "$src\001$dst";
-        if (!exists($edge{$edge_label})) {
-          $edge{$edge_label} = 0;
-        }
-        $edge{$edge_label} += $n;
-      }
-    }
-  }
-
-  # Print edges
-  foreach my $e (keys(%edge)) {
-    my @x = split(/\001/, $e);
-    $n = $edge{$e};
-
-    if (abs($n) > $edgelimit) {
-      # Compute line width based on edge count
-      my $fraction = abs($local_total ? (3 * ($n / $local_total)) : 0);
-      if ($fraction > 1) { $fraction = 1; }
-      my $w = $fraction * 2;
-      if ($w < 1 && ($main::opt_web || $main::opt_svg)) {
-        # SVG output treats line widths < 1 poorly.
-        $w = 1;
-      }
-
-      # Dot sometimes segfaults if given edge weights that are too large, so
-      # we cap the weights at a large value
-      my $edgeweight = abs($n) ** 0.7;
-      if ($edgeweight > 100000) { $edgeweight = 100000; }
-      $edgeweight = int($edgeweight);
-
-      my $style = sprintf("setlinewidth(%f)", $w);
-      if ($x[1] =~ m/\(inline\)/) {
-        $style .= ",dashed";
-      }
-
-      # Use a slightly squashed function of the edge count as the weight
-      printf DOT ("N%s -> N%s [label=%s, weight=%d, style=\"%s\"];\n",
-                  $node{$x[0]},
-                  $node{$x[1]},
-                  Unparse($n),
-                  $edgeweight,
-                  $style);
-    }
-  }
-
-  print DOT ("}\n");
-  close(DOT);
-
-  if ($main::opt_web || $main::opt_svg) {
-    # Rewrite SVG to be more usable inside web browser.
-    RewriteSvg(TempName($main::next_tmpfile, "svg"));
-  }
-
-  return 1;
-}
-
-sub RewriteSvg {
-  my $svgfile = shift;
-
-  open(SVG, $svgfile) || die "open temp svg: $!";
-  my @svg = <SVG>;
-  close(SVG);
-  unlink $svgfile;
-  my $svg = join('', @svg);
-
-  # Dot's SVG output is
-  #
-  #    <svg width="___" height="___"
-  #     viewBox="___" xmlns=...>
-  #    <g id="graph0" transform="...">
-  #    ...
-  #    </g>
-  #    </svg>
-  #
-  # Change it to
-  #
-  #    <svg width="100%" height="100%"
-  #     xmlns=...>
-  #    $svg_javascript
-  #    <g id="viewport" transform="translate(0,0)">
-  #    <g id="graph0" transform="...">
-  #    ...
-  #    </g>
-  #    </g>
-  #    </svg>
-
-  # Fix width, height; drop viewBox.
-  $svg =~ s/(?s)<svg width="[^"]+" height="[^"]+"(.*?)viewBox="[^"]+"/<svg width="100%" height="100%"$1/;
-
-  # Insert script, viewport <g> above first <g>
-  my $svg_javascript = SvgJavascript();
-  my $viewport = "<g id=\"viewport\" transform=\"translate(0,0)\">\n";
-  $svg =~ s/<g id="graph\d"/$svg_javascript$viewport$&/;
-
-  # Insert final </g> above </svg>.
-  $svg =~ s/(.*)(<\/svg>)/$1<\/g>$2/;
-  $svg =~ s/<g id="graph\d"(.*?)/<g id="viewport"$1/;
-
-  if ($main::opt_svg) {
-    # --svg: write to standard output.
-    print $svg;
-  } else {
-    # Write back to temporary file.
-    open(SVG, ">$svgfile") || die "open $svgfile: $!";
-    print SVG $svg;
-    close(SVG);
-  }
-}
-
-sub SvgJavascript {
-  return <<'EOF';
-<script type="text/ecmascript"><![CDATA[
-// SVGPan
-// http://www.cyberz.org/blog/2009/12/08/svgpan-a-javascript-svg-panzoomdrag-library/
-// Local modification: if(true || ...) below to force panning, never moving.
-// Local modification: add clamping to fix bug in handleMouseWheel.
-
-/**
- *  SVGPan library 1.2
- * ====================
- *
- * Given an unique existing element with id "viewport", including the
- * the library into any SVG adds the following capabilities:
- *
- *  - Mouse panning
- *  - Mouse zooming (using the wheel)
- *  - Object dargging
- *
- * Known issues:
- *
- *  - Zooming (while panning) on Safari has still some issues
- *
- * Releases:
- *
- * 1.2, Sat Mar 20 08:42:50 GMT 2010, Zeng Xiaohui
- *	Fixed a bug with browser mouse handler interaction
- *
- * 1.1, Wed Feb  3 17:39:33 GMT 2010, Zeng Xiaohui
- *	Updated the zoom code to support the mouse wheel on Safari/Chrome
- *
- * 1.0, Andrea Leofreddi
- *	First release
- *
- * This code is licensed under the following BSD license:
- *
- * Copyright 2009-2010 Andrea Leofreddi <a.leofreddi at itcharm.com>. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification, are
- * permitted provided that the following conditions are met:
- *
- *    1. Redistributions of source code must retain the above copyright notice, this list of
- *       conditions and the following disclaimer.
- *
- *    2. Redistributions in binary form must reproduce the above copyright notice, this list
- *       of conditions and the following disclaimer in the documentation and/or other materials
- *       provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY Andrea Leofreddi ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Andrea Leofreddi OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * The views and conclusions contained in the software and documentation are those of the
- * authors and should not be interpreted as representing official policies, either expressed
- * or implied, of Andrea Leofreddi.
- */
-
-var root = document.documentElement;
-
-var state = 'none', stateTarget, stateOrigin, stateTf;
-
-setupHandlers(root);
-
-/**
- * Register handlers
- */
-function setupHandlers(root){
-	setAttributes(root, {
-		"onmouseup" : "add(evt)",
-		"onmousedown" : "handleMouseDown(evt)",
-		"onmousemove" : "handleMouseMove(evt)",
-		"onmouseup" : "handleMouseUp(evt)",
-		//"onmouseout" : "handleMouseUp(evt)", // Decomment this to stop the pan functionality when dragging out of the SVG element
-	});
-
-	if(navigator.userAgent.toLowerCase().indexOf('webkit') >= 0)
-		window.addEventListener('mousewheel', handleMouseWheel, false); // Chrome/Safari
-	else
-		window.addEventListener('DOMMouseScroll', handleMouseWheel, false); // Others
-
-	var g = svgDoc.getElementById("svg");
-	g.width = "100%";
-	g.height = "100%";
-}
-
-/**
- * Instance an SVGPoint object with given event coordinates.
- */
-function getEventPoint(evt) {
-	var p = root.createSVGPoint();
-
-	p.x = evt.clientX;
-	p.y = evt.clientY;
-
-	return p;
-}
-
-/**
- * Sets the current transform matrix of an element.
- */
-function setCTM(element, matrix) {
-	var s = "matrix(" + matrix.a + "," + matrix.b + "," + matrix.c + "," + matrix.d + "," + matrix.e + "," + matrix.f + ")";
-
-	element.setAttribute("transform", s);
-}
-
-/**
- * Dumps a matrix to a string (useful for debug).
- */
-function dumpMatrix(matrix) {
-	var s = "[ " + matrix.a + ", " + matrix.c + ", " + matrix.e + "\n  " + matrix.b + ", " + matrix.d + ", " + matrix.f + "\n  0, 0, 1 ]";
-
-	return s;
-}
-
-/**
- * Sets attributes of an element.
- */
-function setAttributes(element, attributes){
-	for (i in attributes)
-		element.setAttributeNS(null, i, attributes[i]);
-}
-
-/**
- * Handle mouse move event.
- */
-function handleMouseWheel(evt) {
-	if(evt.preventDefault)
-		evt.preventDefault();
-
-	evt.returnValue = false;
-
-	var svgDoc = evt.target.ownerDocument;
-
-	var delta;
-
-	if(evt.wheelDelta)
-		delta = evt.wheelDelta / 3600; // Chrome/Safari
-	else
-		delta = evt.detail / -90; // Mozilla
-
-	var z = 1 + delta; // Zoom factor: 0.9/1.1
-
-	// Clamp to reasonable values.
-	// The 0.1 check is important because
-	// a very large scroll can turn into a
-	// negative z, which rotates the image 180 degrees.
-	if(z < 0.1)
-		z = 0.1;
-	if(z > 10.0)
-		z = 10.0;
-
-	var g = svgDoc.getElementById("viewport");
-
-	var p = getEventPoint(evt);
-
-	p = p.matrixTransform(g.getCTM().inverse());
-
-	// Compute new scale matrix in current mouse position
-	var k = root.createSVGMatrix().translate(p.x, p.y).scale(z).translate(-p.x, -p.y);
-
-        setCTM(g, g.getCTM().multiply(k));
-
-	stateTf = stateTf.multiply(k.inverse());
-}
-
-/**
- * Handle mouse move event.
- */
-function handleMouseMove(evt) {
-	if(evt.preventDefault)
-		evt.preventDefault();
-
-	evt.returnValue = false;
-
-	var svgDoc = evt.target.ownerDocument;
-
-	var g = svgDoc.getElementById("viewport");
-
-	if(state == 'pan') {
-		// Pan mode
-		var p = getEventPoint(evt).matrixTransform(stateTf);
-
-		setCTM(g, stateTf.inverse().translate(p.x - stateOrigin.x, p.y - stateOrigin.y));
-	} else if(state == 'move') {
-		// Move mode
-		var p = getEventPoint(evt).matrixTransform(g.getCTM().inverse());
-
-		setCTM(stateTarget, root.createSVGMatrix().translate(p.x - stateOrigin.x, p.y - stateOrigin.y).multiply(g.getCTM().inverse()).multiply(stateTarget.getCTM()));
-
-		stateOrigin = p;
-	}
-}
-
-/**
- * Handle click event.
- */
-function handleMouseDown(evt) {
-	if(evt.preventDefault)
-		evt.preventDefault();
-
-	evt.returnValue = false;
-
-	var svgDoc = evt.target.ownerDocument;
-
-	var g = svgDoc.getElementById("viewport");
-
-	if(true || evt.target.tagName == "svg") {
-		// Pan mode
-		state = 'pan';
-
-		stateTf = g.getCTM().inverse();
-
-		stateOrigin = getEventPoint(evt).matrixTransform(stateTf);
-	} else {
-		// Move mode
-		state = 'move';
-
-		stateTarget = evt.target;
-
-		stateTf = g.getCTM().inverse();
-
-		stateOrigin = getEventPoint(evt).matrixTransform(stateTf);
-	}
-}
-
-/**
- * Handle mouse button release event.
- */
-function handleMouseUp(evt) {
-	if(evt.preventDefault)
-		evt.preventDefault();
-
-	evt.returnValue = false;
-
-	var svgDoc = evt.target.ownerDocument;
-
-	if(state == 'pan' || state == 'move') {
-		// Quit pan mode
-		state = '';
-	}
-}
-
-]]></script>
-EOF
-}
-
-# Translate a stack of addresses into a stack of symbols
-sub TranslateStack {
-  my $symbols = shift;
-  my $k = shift;
-
-  my @addrs = split(/\n/, $k);
-  my @result = ();
-  for (my $i = 0; $i <= $#addrs; $i++) {
-    my $a = $addrs[$i];
-
-    # Skip large addresses since they sometimes show up as fake entries on RH9
-    if (length($a) > 8 && $a gt "7fffffffffffffff") {
-      next;
-    }
-
-    if ($main::opt_disasm || $main::opt_list) {
-      # We want just the address for the key
-      push(@result, $a);
-      next;
-    }
-
-    my $symlist = $symbols->{$a};
-    if (!defined($symlist)) {
-      $symlist = [$a, "", $a];
-    }
-
-    # We can have a sequence of symbols for a particular entry
-    # (more than one symbol in the case of inlining).  Callers
-    # come before callees in symlist, so walk backwards since
-    # the translated stack should contain callees before callers.
-    for (my $j = $#{$symlist}; $j >= 2; $j -= 3) {
-      my $func = $symlist->[$j-2];
-      my $fileline = $symlist->[$j-1];
-      my $fullfunc = $symlist->[$j];
-      if ($j > 2) {
-        $func = "$func (inline)";
-      }
-      if ($main::opt_addresses) {
-        push(@result, "$a $func $fileline");
-      } elsif ($main::opt_lines) {
-        if ($func eq '??' && $fileline eq '??:0') {
-          push(@result, "$a");
-        } else {
-          push(@result, "$func $fileline");
-        }
-      } elsif ($main::opt_functions) {
-        if ($func eq '??') {
-          push(@result, "$a");
-        } else {
-          push(@result, $func);
-        }
-      } elsif ($main::opt_files) {
-        if ($fileline eq '??:0' || $fileline eq '') {
-          push(@result, "$a");
-        } else {
-          my $f = $fileline;
-          $f =~ s/:\d+$//;
-          push(@result, $f);
-        }
-      } else {
-        push(@result, $a);
-        last;  # Do not print inlined info
-      }
-    }
-  }
-
-  # print join(",", @addrs), " => ", join(",", @result), "\n";
-  return @result;
-}
-
-# Generate percent string for a number and a total
-sub Percent {
-  my $num = shift;
-  my $tot = shift;
-  if ($tot != 0) {
-    return sprintf("%.1f%%", $num * 100.0 / $tot);
-  } else {
-    return ($num == 0) ? "nan" : (($num > 0) ? "+inf" : "-inf");
-  }
-}
-
-# Generate pretty-printed form of number
-sub Unparse {
-  my $num = shift;
-  if ($main::profile_type eq 'heap' || $main::profile_type eq 'growth') {
-    if ($main::opt_inuse_objects || $main::opt_alloc_objects) {
-      return sprintf("%d", $num);
-    } else {
-      if ($main::opt_show_bytes) {
-        return sprintf("%d", $num);
-      } else {
-        return sprintf("%.1f", $num / 1048576.0);
-      }
-    }
-  } elsif ($main::profile_type eq 'contention' && !$main::opt_contentions) {
-    return sprintf("%.3f", $num / 1e9); # Convert nanoseconds to seconds
-  } else {
-    return sprintf("%d", $num);
-  }
-}
-
-# Alternate pretty-printed form: 0 maps to "."
-sub UnparseAlt {
-  my $num = shift;
-  if ($num == 0) {
-    return ".";
-  } else {
-    return Unparse($num);
-  }
-}
-
-# Alternate pretty-printed form: 0 maps to ""
-sub HtmlPrintNumber {
-  my $num = shift;
-  if ($num == 0) {
-    return "";
-  } else {
-    return Unparse($num);
-  }
-}
-
-# Return output units
-sub Units {
-  if ($main::profile_type eq 'heap' || $main::profile_type eq 'growth') {
-    if ($main::opt_inuse_objects || $main::opt_alloc_objects) {
-      return "objects";
-    } else {
-      if ($main::opt_show_bytes) {
-        return "B";
-      } else {
-        return "MB";
-      }
-    }
-  } elsif ($main::profile_type eq 'contention' && !$main::opt_contentions) {
-    return "seconds";
-  } elsif ($main::profile_type eq 'thread') {
-    return "threads";
-  } else {
-    return "samples";
-  }
-}
-
-##### Profile manipulation code #####
-
-# Generate flattened profile:
-# If count is charged to stack [a,b,c,d], in generated profile,
-# it will be charged to [a]
-sub FlatProfile {
-  my $profile = shift;
-  my $result = {};
-  foreach my $k (keys(%{$profile})) {
-    my $count = $profile->{$k};
-    my @addrs = split(/\n/, $k);
-    if ($#addrs >= 0) {
-      AddEntry($result, $addrs[0], $count);
-    }
-  }
-  return $result;
-}
-
-# Generate cumulative profile:
-# If count is charged to stack [a,b,c,d], in generated profile,
-# it will be charged to [a], [b], [c], [d]
-sub CumulativeProfile {
-  my $profile = shift;
-  my $result = {};
-  foreach my $k (keys(%{$profile})) {
-    my $count = $profile->{$k};
-    my @addrs = split(/\n/, $k);
-    foreach my $a (@addrs) {
-      AddEntry($result, $a, $count);
-    }
-  }
-  return $result;
-}
-
-# If the second-youngest PC on the stack is always the same, returns
-# that pc.  Otherwise, returns undef.
-sub IsSecondPcAlwaysTheSame {
-  my $profile = shift;
-
-  my $second_pc = undef;
-  foreach my $k (keys(%{$profile})) {
-    my @addrs = split(/\n/, $k);
-    if ($#addrs < 1) {
-      return undef;
-    }
-    if (not defined $second_pc) {
-      $second_pc = $addrs[1];
-    } else {
-      if ($second_pc ne $addrs[1]) {
-        return undef;
-      }
-    }
-  }
-  return $second_pc;
-}
-
-sub ExtractSymbolLocation {
-  my $symbols = shift;
-  my $address = shift;
-  # 'addr2line' outputs "??:0" for unknown locations; we do the
-  # same to be consistent.
-  my $location = "??:0:unknown";
-  if (exists $symbols->{$address}) {
-    my $file = $symbols->{$address}->[1];
-    if ($file eq "?") {
-      $file = "??:0"
-    }
-    $location = $file . ":" . $symbols->{$address}->[0];
-  }
-  return $location;
-}
-
-# Extracts a graph of calls.
-sub ExtractCalls {
-  my $symbols = shift;
-  my $profile = shift;
-
-  my $calls = {};
-  while( my ($stack_trace, $count) = each %$profile ) {
-    my @address = split(/\n/, $stack_trace);
-    my $destination = ExtractSymbolLocation($symbols, $address[0]);
-    AddEntry($calls, $destination, $count);
-    for (my $i = 1; $i <= $#address; $i++) {
-      my $source = ExtractSymbolLocation($symbols, $address[$i]);
-      my $call = "$source -> $destination";
-      AddEntry($calls, $call, $count);
-      $destination = $source;
-    }
-  }
-
-  return $calls;
-}
-
-sub RemoveUninterestingFrames {
-  my $symbols = shift;
-  my $profile = shift;
-
-  # List of function names to skip
-  my %skip = ();
-  my $skip_regexp = 'NOMATCH';
-  if ($main::profile_type eq 'heap' || $main::profile_type eq 'growth') {
-    foreach my $name ('calloc',
-                      'cfree',
-                      'malloc',
-                      'free',
-                      'memalign',
-                      'posix_memalign',
-                      'pvalloc',
-                      'valloc',
-                      'realloc',
-                      'tc_calloc',
-                      'tc_cfree',
-                      'tc_malloc',
-                      'tc_free',
-                      'tc_memalign',
-                      'tc_posix_memalign',
-                      'tc_pvalloc',
-                      'tc_valloc',
-                      'tc_realloc',
-                      'tc_new',
-                      'tc_delete',
-                      'tc_newarray',
-                      'tc_deletearray',
-                      'tc_new_nothrow',
-                      'tc_newarray_nothrow',
-                      'do_malloc',
-                      '::do_malloc',   # new name -- got moved to an unnamed ns
-                      '::do_malloc_or_cpp_alloc',
-                      'DoSampledAllocation',
-                      'simple_alloc::allocate',
-                      '__malloc_alloc_template::allocate',
-                      '__builtin_delete',
-                      '__builtin_new',
-                      '__builtin_vec_delete',
-                      '__builtin_vec_new',
-                      'operator new',
-                      'operator new[]',
-                      # Go
-                      'catstring',
-                      'cnew',
-                      'copyin',
-                      'gostring',
-                      'gostringsize',
-                      'growslice1',
-                      'appendslice1',
-                      'hash_init',
-                      'hash_subtable_new',
-                      'hash_conv',
-                      'hash_grow',
-                      'hash_insert_internal',
-                      'hash_insert',
-                      'mapassign',
-                      'runtime.mapassign',
-                      'runtime.appendslice',
-                      'runtime.mapassign1',
-                      'makechan',
-                      'makemap',
-                      'mal',
-                      'profilealloc',
-                      'runtime.new',
-                      'makeslice1',
-                      'runtime.malloc',
-                      'unsafe.New',
-                      'runtime.mallocgc',
-                      'runtime.catstring',
-                      'runtime.cnew',
-                      'runtime.cnewarray',
-                      'runtime.growslice',
-                      'runtime.ifaceT2E',
-                      'runtime.ifaceT2I',
-                      'runtime.makechan',
-                      'runtime.makechan_c',
-                      'runtime.makemap',
-                      'runtime.makemap_c',
-                      'runtime.makeslice',
-                      'runtime.mal',
-                      'runtime.settype',
-                      'runtime.settype_flush',
-                      'runtime.slicebytetostring',
-                      'runtime.sliceinttostring',
-                      'runtime.stringtoslicebyte',
-                      'runtime.stringtosliceint',
-                      # These mark the beginning/end of our custom sections
-                      '__start_google_malloc',
-                      '__stop_google_malloc',
-                      '__start_malloc_hook',
-                      '__stop_malloc_hook') {
-      $skip{$name} = 1;
-      $skip{"_" . $name} = 1;   # Mach (OS X) adds a _ prefix to everything
-    }
-    # TODO: Remove TCMalloc once everything has been
-    # moved into the tcmalloc:: namespace and we have flushed
-    # old code out of the system.
-    $skip_regexp = "TCMalloc|^tcmalloc::";
-  } elsif ($main::profile_type eq 'contention') {
-    foreach my $vname ('Mutex::Unlock', 'Mutex::UnlockSlow') {
-      $skip{$vname} = 1;
-    }
-  } elsif ($main::profile_type eq 'cpu') {
-    # Drop signal handlers used for CPU profile collection
-    # TODO(dpeng): this should not be necessary; it's taken
-    # care of by the general 2nd-pc mechanism below.
-    foreach my $name ('ProfileData::Add',           # historical
-                      'ProfileData::prof_handler',  # historical
-                      'CpuProfiler::prof_handler',
-                      '__FRAME_END__',
-                      '__pthread_sighandler',
-                      '__restore') {
-      $skip{$name} = 1;
-    }
-  } else {
-    # Nothing skipped for unknown types
-  }
-
-  # Go doesn't have the problem that this heuristic tries to fix.  Disable.
-  if (0 && $main::profile_type eq 'cpu') {
-    # If all the second-youngest program counters are the same,
-    # this STRONGLY suggests that it is an artifact of measurement,
-    # i.e., stack frames pushed by the CPU profiler signal handler.
-    # Hence, we delete them.
-    # (The topmost PC is read from the signal structure, not from
-    # the stack, so it does not get involved.)
-    while (my $second_pc = IsSecondPcAlwaysTheSame($profile)) {
-      my $result = {};
-      my $func = '';
-      if (exists($symbols->{$second_pc})) {
-        $second_pc = $symbols->{$second_pc}->[0];
-      }
-      print STDERR "Removing $second_pc from all stack traces.\n";
-      foreach my $k (keys(%{$profile})) {
-        my $count = $profile->{$k};
-        my @addrs = split(/\n/, $k);
-        splice @addrs, 1, 1;
-        my $reduced_path = join("\n", @addrs);
-        AddEntry($result, $reduced_path, $count);
-      }
-      $profile = $result;
-    }
-  }
-
-  my $result = {};
-  foreach my $k (keys(%{$profile})) {
-    my $count = $profile->{$k};
-    my @addrs = split(/\n/, $k);
-    my @path = ();
-    foreach my $a (@addrs) {
-      if (exists($symbols->{$a})) {
-        my $func = $symbols->{$a}->[0];
-        if ($skip{$func} || ($func =~ m/$skip_regexp/)) {
-          next;
-        }
-      }
-      push(@path, $a);
-    }
-    my $reduced_path = join("\n", @path);
-    AddEntry($result, $reduced_path, $count);
-  }
-  return $result;
-}
-
-# Reduce profile to granularity given by user
-sub ReduceProfile {
-  my $symbols = shift;
-  my $profile = shift;
-  my $result = {};
-  foreach my $k (keys(%{$profile})) {
-    my $count = $profile->{$k};
-    my @translated = TranslateStack($symbols, $k);
-    my @path = ();
-    my %seen = ();
-    $seen{''} = 1;      # So that empty keys are skipped
-    foreach my $e (@translated) {
-      # To avoid double-counting due to recursion, skip a stack-trace
-      # entry if it has already been seen
-      if (!$seen{$e}) {
-        $seen{$e} = 1;
-        push(@path, $e);
-      }
-    }
-    my $reduced_path = join("\n", @path);
-    AddEntry($result, $reduced_path, $count);
-  }
-  return $result;
-}
-
-# Does the specified symbol array match the regexp?
-sub SymbolMatches {
-  my $sym = shift;
-  my $re = shift;
-  if (defined($sym)) {
-    for (my $i = 0; $i < $#{$sym}; $i += 3) {
-      if ($sym->[$i] =~ m/$re/ || $sym->[$i+1] =~ m/$re/) {
-        return 1;
-      }
-    }
-  }
-  return 0;
-}
-
-# Focus only on paths involving specified regexps
-sub FocusProfile {
-  my $symbols = shift;
-  my $profile = shift;
-  my $focus = shift;
-  my $result = {};
-  foreach my $k (keys(%{$profile})) {
-    my $count = $profile->{$k};
-    my @addrs = split(/\n/, $k);
-    foreach my $a (@addrs) {
-      # Reply if it matches either the address/shortname/fileline
-      if (($a =~ m/$focus/) || SymbolMatches($symbols->{$a}, $focus)) {
-        AddEntry($result, $k, $count);
-        last;
-      }
-    }
-  }
-  return $result;
-}
-
-# Focus only on paths not involving specified regexps
-sub IgnoreProfile {
-  my $symbols = shift;
-  my $profile = shift;
-  my $ignore = shift;
-  my $result = {};
-  foreach my $k (keys(%{$profile})) {
-    my $count = $profile->{$k};
-    my @addrs = split(/\n/, $k);
-    my $matched = 0;
-    foreach my $a (@addrs) {
-      # Reply if it matches either the address/shortname/fileline
-      if (($a =~ m/$ignore/) || SymbolMatches($symbols->{$a}, $ignore)) {
-        $matched = 1;
-        last;
-      }
-    }
-    if (!$matched) {
-      AddEntry($result, $k, $count);
-    }
-  }
-  return $result;
-}
-
-# Get total count in profile
-sub TotalProfile {
-  my $profile = shift;
-  my $result = 0;
-  foreach my $k (keys(%{$profile})) {
-    $result += $profile->{$k};
-  }
-  return $result;
-}
-
-# Add A to B
-sub AddProfile {
-  my $A = shift;
-  my $B = shift;
-
-  my $R = {};
-  # add all keys in A
-  foreach my $k (keys(%{$A})) {
-    my $v = $A->{$k};
-    AddEntry($R, $k, $v);
-  }
-  # add all keys in B
-  foreach my $k (keys(%{$B})) {
-    my $v = $B->{$k};
-    AddEntry($R, $k, $v);
-  }
-  return $R;
-}
-
-# Merges symbol maps
-sub MergeSymbols {
-  my $A = shift;
-  my $B = shift;
-
-  my $R = {};
-  foreach my $k (keys(%{$A})) {
-    $R->{$k} = $A->{$k};
-  }
-  if (defined($B)) {
-    foreach my $k (keys(%{$B})) {
-      $R->{$k} = $B->{$k};
-    }
-  }
-  return $R;
-}
-
-
-# Add A to B
-sub AddPcs {
-  my $A = shift;
-  my $B = shift;
-
-  my $R = {};
-  # add all keys in A
-  foreach my $k (keys(%{$A})) {
-    $R->{$k} = 1
-  }
-  # add all keys in B
-  foreach my $k (keys(%{$B})) {
-    $R->{$k} = 1
-  }
-  return $R;
-}
-
-# Subtract B from A
-sub SubtractProfile {
-  my $A = shift;
-  my $B = shift;
-
-  my $R = {};
-  foreach my $k (keys(%{$A})) {
-    my $v = $A->{$k} - GetEntry($B, $k);
-    if ($v < 0 && $main::opt_drop_negative) {
-      $v = 0;
-    }
-    AddEntry($R, $k, $v);
-  }
-  if (!$main::opt_drop_negative) {
-    # Take care of when subtracted profile has more entries
-    foreach my $k (keys(%{$B})) {
-      if (!exists($A->{$k})) {
-        AddEntry($R, $k, 0 - $B->{$k});
-      }
-    }
-  }
-  return $R;
-}
-
-# Get entry from profile; zero if not present
-sub GetEntry {
-  my $profile = shift;
-  my $k = shift;
-  if (exists($profile->{$k})) {
-    return $profile->{$k};
-  } else {
-    return 0;
-  }
-}
-
-# Add entry to specified profile
-sub AddEntry {
-  my $profile = shift;
-  my $k = shift;
-  my $n = shift;
-  if (!exists($profile->{$k})) {
-    $profile->{$k} = 0;
-  }
-  $profile->{$k} += $n;
-}
-
-# Add a stack of entries to specified profile, and add them to the $pcs
-# list.
-sub AddEntries {
-  my $profile = shift;
-  my $pcs = shift;
-  my $stack = shift;
-  my $count = shift;
-  my @k = ();
-
-  foreach my $e (split(/\s+/, $stack)) {
-    my $pc = HexExtend($e);
-    $pcs->{$pc} = 1;
-    push @k, $pc;
-  }
-  AddEntry($profile, (join "\n", @k), $count);
-}
-
-sub IsSymbolizedProfileFile {
-  my $file_name = shift;
-
-  if (!(-e $file_name) || !(-r $file_name)) {
-    return 0;
-  }
-
-  $SYMBOL_PAGE =~ m,[^/]+$,;    # matches everything after the last slash
-  my $symbol_marker = $&;
-  # Check if the file contains a symbol-section marker.
-  open(TFILE, "<$file_name");
-  my @lines = <TFILE>;
-  my $result = grep(/^--- *$symbol_marker/, @lines);
-  close(TFILE);
-  return $result > 0;
-}
-
-##### Code to profile a server dynamically #####
-
-sub CheckSymbolPage {
-  my $url = SymbolPageURL();
-print STDERR "Read $url\n";
-
-  my $line = FetchHTTP($url);
-  $line =~ s/\r//g;         # turn windows-looking lines into unix-looking lines
-  unless (defined($line)) {
-    error("$url doesn't exist\n");
-  }
-
-  if ($line =~ /^num_symbols:\s+(\d+)$/) {
-    if ($1 == 0) {
-      error("Stripped binary. No symbols available.\n");
-    }
-  } else {
-    error("Failed to get the number of symbols from $url\n");
-  }
-}
-
-sub IsProfileURL {
-  my $profile_name = shift;
-  my ($scheme, $host, $port, $prefix, $path) = ParseProfileURL($profile_name);
-  return defined($host) and defined($port) and defined($path);
-}
-
-sub ParseProfileURL {
-  my $profile_name = shift;
-  if (defined($profile_name) &&
-      $profile_name =~ m,^(?:(https?)://|)([^/:]+):(\d+)(|\@\d+)(|/|(.*?)($PROFILE_PAGE|$PMUPROFILE_PAGE|$HEAP_PAGE|$GROWTH_PAGE|$THREAD_PAGE|$BLOCK_PAGE|$CONTENTION_PAGE|$WALL_PAGE|$FILTEREDPROFILE_PAGE))$,o) {
-    # $7 is $PROFILE_PAGE/$HEAP_PAGE/etc.  $5 is *everything* after
-    # the hostname, as long as that everything is the empty string,
-    # a slash, or something ending in $PROFILE_PAGE/$HEAP_PAGE/etc.
-    # So "$7 || $5" is $PROFILE_PAGE/etc if there, or else it's "/" or "".
-    return ($1 || "http", $2, $3, $6, $7 || $5);
-  }
-  return ();
-}
-
-# We fetch symbols from the first profile argument.
-sub SymbolPageURL {
-  my ($scheme, $host, $port, $prefix, $path) = ParseProfileURL($main::pfile_args[0]);
-  return "$scheme://$host:$port$prefix$SYMBOL_PAGE";
-}
-
-sub FetchProgramName() {
-  my ($scheme, $host, $port, $prefix, $path) = ParseProfileURL($main::pfile_args[0]);
-  my $url = "$scheme://$host:$port$prefix$PROGRAM_NAME_PAGE";
-  
-  my $cmdline = FetchHTTP($url);
-  $cmdline =~ s/\n.*//s; # first line only
-  $cmdline =~ s/\r//g;   # turn windows-looking lines into unix-looking lines
-  error("Failed to get program name from $url\n") unless defined($cmdline);
-  $cmdline =~ s/\x00.+//;  # Remove argv[1] and latters.
-  $cmdline =~ s!\n!!g;  # Remove LFs.
-  return $cmdline;
-}
-
-# Reads a symbol map from the file handle name given as $1, returning
-# the resulting symbol map.  Also processes variables relating to symbols.
-# Currently, the only variable processed is 'binary=<value>' which updates
-# $main::prog to have the correct program name.
-sub ReadSymbols {
-  my $in = shift;
-  my $map = shift;
-  while (<$in>) {
-    s/\r//g;         # turn windows-looking lines into unix-looking lines
-    # Removes all the leading zeroes from the symbols, see comment below.
-    if (m/^0x0*([0-9a-f]+)\s+(.+)/) {
-      $map->{$1} = $2;
-    } elsif (m/^---/) {
-      last;
-    } elsif (m/^([a-z][^=]*)=(.*)$/ ) {
-      my ($variable, $value) = ($1, $2);
-      for ($variable, $value) {
-        s/^\s+//;
-        s/\s+$//;
-      }
-      if ($variable eq "binary") {
-        if ($main::prog ne $UNKNOWN_BINARY && $main::prog ne $value) {
-          printf STDERR ("Warning: Mismatched binary name '%s', using '%s'.\n",
-                         $main::prog, $value);
-        }
-        $main::prog = $value;
-      } else {
-        printf STDERR ("Ignoring unknown variable in symbols list: " .
-            "'%s' = '%s'\n", $variable, $value);
-      }
-    }
-  }
-  return $map;
-}
-
-# Fetches and processes symbols to prepare them for use in the profile output
-# code.  If the optional 'symbol_map' arg is not given, fetches symbols from
-# $SYMBOL_PAGE for all PC values found in profile.  Otherwise, the raw symbols
-# are assumed to have already been fetched into 'symbol_map' and are simply
-# extracted and processed.
-sub FetchSymbols {
-  my $pcset = shift;
-  my $symbol_map = shift;
-
-  my %seen = ();
-  my @pcs = grep { !$seen{$_}++ } keys(%$pcset);  # uniq
-
-  if (!defined($symbol_map)) {
-    $symbol_map = {};
-
-    my $post_data = join("+", sort((map {"0x" . "$_"} @pcs)));
-    my $url = SymbolPageURL();
-    my $content = PostHTTP($url, $post_data);
-    
-    my $tmp_symbol = File::Temp->new()->filename;
-    open(SYMBOL, ">$tmp_symbol");
-    print SYMBOL $content;
-    close(SYMBOL);
-    
-    open(SYMBOL, "<$tmp_symbol") || error("$tmp_symbol");
-    ReadSymbols(*SYMBOL{IO}, $symbol_map);
-    close(SYMBOL);
-  }
-
-  my $symbols = {};
-  foreach my $pc (@pcs) {
-    my $fullname;
-    # For 64 bits binaries, symbols are extracted with 8 leading zeroes.
-    # Then /symbol reads the long symbols in as uint64, and outputs
-    # the result with a "0x%08llx" format which get rid of the zeroes.
-    # By removing all the leading zeroes in both $pc and the symbols from
-    # /symbol, the symbols match and are retrievable from the map.
-    my $shortpc = $pc;
-    $shortpc =~ s/^0*//;
-    # Each line may have a list of names, which includes the function
-    # and also other functions it has inlined.  They are separated
-    # (in PrintSymbolizedFile), by --, which is illegal in function names.
-    my $fullnames;
-    if (defined($symbol_map->{$shortpc})) {
-      $fullnames = $symbol_map->{$shortpc};
-    } else {
-      $fullnames = "0x" . $pc;  # Just use addresses
-    }
-    my $sym = [];
-    $symbols->{$pc} = $sym;
-    foreach my $fullname (split("--", $fullnames)) {
-      my $name = ShortFunctionName($fullname);
-      push(@{$sym}, $name, "?", $fullname);
-    }
-  }
-  return $symbols;
-}
-
-sub BaseName {
-  my $file_name = shift;
-  $file_name =~ s!^.*/!!;  # Remove directory name
-  return $file_name;
-}
-
-sub MakeProfileBaseName {
-  my ($binary_name, $profile_name) = @_;
-  my ($scheme, $host, $port, $prefix, $path) = ParseProfileURL($profile_name);
-  my $binary_shortname = BaseName($binary_name);
-  return sprintf("%s.%s.%s-port%s",
-                 $binary_shortname, $main::op_time, $host, $port);
-}
-
-sub FetchDynamicProfile {
-  my $binary_name = shift;
-  my $profile_name = shift;
-  my $fetch_name_only = shift;
-  my $encourage_patience = shift;
-
-  if (!IsProfileURL($profile_name)) {
-    return $profile_name;
-  } else {
-    my ($scheme, $host, $port, $prefix, $path) = ParseProfileURL($profile_name);
-    if ($path eq "" || $path eq "/") {
-      # Missing type specifier defaults to cpu-profile
-      $path = $PROFILE_PAGE;
-    }
-
-    my $profile_file = MakeProfileBaseName($binary_name, $profile_name);
-
-    my $url;
-    my $timeout;
-    if (($path =~ m/$PROFILE_PAGE/) || ($path =~ m/$PMUPROFILE_PAGE/)) {
-      if ($path =~ m/$PROFILE_PAGE/) {
-        $url = sprintf("$scheme://$host:$port$prefix$path?seconds=%d",
-            $main::opt_seconds);
-      } else {
-        if ($profile_name =~ m/[?]/) {
-          $profile_name .= "&"
-        } else {
-          $profile_name .= "?"
-        }
-        $url = sprintf("$scheme://$profile_name" . "seconds=%d",
-            $main::opt_seconds);
-      }
-      $timeout = int($main::opt_seconds * 1.01 + 60);
-    } else {
-      # For non-CPU profiles, we add a type-extension to
-      # the target profile file name.
-      my $suffix = $path;
-      $suffix =~ s,/,.,g;
-      $profile_file .= "$suffix";
-      $url = "$scheme://$host:$port$prefix$path";
-    }
-
-    my $tmp_profile = File::Temp->new()->filename;
-    my $real_profile = File::Temp->new()->filename;
-
-    if ($fetch_name_only > 0) {
-      return $real_profile;
-    }
-
-    if (($path =~ m/$PROFILE_PAGE/) || ($path =~ m/$PMUPROFILE_PAGE/)){
-      print STDERR "Gathering CPU profile from $url for $main::opt_seconds seconds to\n  ${real_profile}\n";
-      if ($encourage_patience) {
-        print STDERR "Be patient...\n";
-      }
-    } else {
-      print STDERR "Fetching $path profile from $host:$port to\n  ${real_profile}\n";
-    }
-
-    my $content = FetchHTTP($url, $timeout);
-    
-    open(OUTFILE, ">$tmp_profile");
-    binmode(OUTFILE);
-    print OUTFILE $content;
-    close(OUTFILE);
-    
-    my $line = $content;
-    $line !~ /^Could not enable CPU profiling/ || error($line);
-    
-    copy($tmp_profile, $real_profile) || error("Unable to copy profile\n");
-    print STDERR "Wrote profile to $real_profile\n";
-    $main::collected_profile = $real_profile;
-    return $main::collected_profile;
-  }
-}
-
-# Collect profiles in parallel
-sub FetchDynamicProfiles {
-  my $items = scalar(@main::pfile_args);
-  my $levels = log($items) / log(2);
-
-  if ($items == 1) {
-    $main::profile_files[0] = FetchDynamicProfile($main::prog, $main::pfile_args[0], 0, 1);
-  } else {
-    # math rounding issues
-    if ((2 ** $levels) < $items) {
-     $levels++;
-    }
-    my $count = scalar(@main::pfile_args);
-    for (my $i = 0; $i < $count; $i++) {
-      $main::profile_files[$i] = FetchDynamicProfile($main::prog, $main::pfile_args[$i], 1, 0);
-    }
-    print STDERR "Fetching $count profiles, Be patient...\n";
-    FetchDynamicProfilesRecurse($levels, 0, 0);
-    $main::collected_profile = join(" \\\n    ", @main::profile_files);
-  }
-}
-
-# Recursively fork a process to get enough processes
-# collecting profiles
-sub FetchDynamicProfilesRecurse {
-  my $maxlevel = shift;
-  my $level = shift;
-  my $position = shift;
-
-  if (my $pid = fork()) {
-    $position = 0 | ($position << 1);
-    TryCollectProfile($maxlevel, $level, $position);
-    wait;
-  } else {
-    $position = 1 | ($position << 1);
-    TryCollectProfile($maxlevel, $level, $position);
-    exit(0);
-  }
-}
-
-# Collect a single profile
-sub TryCollectProfile {
-  my $maxlevel = shift;
-  my $level = shift;
-  my $position = shift;
-
-  if ($level >= ($maxlevel - 1)) {
-    if ($position < scalar(@main::pfile_args)) {
-      FetchDynamicProfile($main::prog, $main::pfile_args[$position], 0, 0);
-    }
-  } else {
-    FetchDynamicProfilesRecurse($maxlevel, $level+1, $position);
-  }
-}
-
-##### Parsing code #####
-
-# Provide a small streaming-read module to handle very large
-# cpu-profile files.  Stream in chunks along a sliding window.
-# Provides an interface to get one 'slot', correctly handling
-# endian-ness differences.  A slot is one 32-bit or 64-bit word
-# (depending on the input profile).  We tell endianness and bit-size
-# for the profile by looking at the first 8 bytes: in cpu profiles,
-# the second slot is always 3 (we'll accept anything that's not 0).
-BEGIN {
-  package CpuProfileStream;
-
-  sub new {
-    my ($class, $file, $fname) = @_;
-    my $self = { file        => $file,
-                 base        => 0,
-                 stride      => 512 * 1024,   # must be a multiple of bitsize/8
-                 slots       => [],
-                 unpack_code => "",           # N for big-endian, V for little
-    };
-    bless $self, $class;
-    # Let unittests adjust the stride
-    if ($main::opt_test_stride > 0) {
-      $self->{stride} = $main::opt_test_stride;
-    }
-    # Read the first two slots to figure out bitsize and endianness.
-    my $slots = $self->{slots};
-    my $str;
-    read($self->{file}, $str, 8);
-    # Set the global $address_length based on what we see here.
-    # 8 is 32-bit (8 hexadecimal chars); 16 is 64-bit (16 hexadecimal chars).
-    $address_length = ($str eq (chr(0)x8)) ? 16 : 8;
-    if ($address_length == 8) {
-      if (substr($str, 6, 2) eq chr(0)x2) {
-        $self->{unpack_code} = 'V';  # Little-endian.
-      } elsif (substr($str, 4, 2) eq chr(0)x2) {
-        $self->{unpack_code} = 'N';  # Big-endian
-      } else {
-        ::error("$fname: header size >= 2**16\n");
-      }
-      @$slots = unpack($self->{unpack_code} . "*", $str);
-    } else {
-      # If we're a 64-bit profile, make sure we're a 64-bit-capable
-      # perl.  Otherwise, each slot will be represented as a float
-      # instead of an int64, losing precision and making all the
-      # 64-bit addresses right.  We *could* try to handle this with
-      # software emulation of 64-bit ints, but that's added complexity
-      # for no clear benefit (yet).  We use 'Q' to test for 64-bit-ness;
-      # perl docs say it's only available on 64-bit perl systems.
-      my $has_q = 0;
-      eval { $has_q = pack("Q", "1") ? 1 : 1; };
-      if (!$has_q) {
-        ::error("$fname: need a 64-bit perl to process this 64-bit profile.\n");
-      }
-      read($self->{file}, $str, 8);
-      if (substr($str, 4, 4) eq chr(0)x4) {
-        # We'd love to use 'Q', but it's a) not universal, b) not endian-proof.
-        $self->{unpack_code} = 'V';  # Little-endian.
-      } elsif (substr($str, 0, 4) eq chr(0)x4) {
-        $self->{unpack_code} = 'N';  # Big-endian
-      } else {
-        ::error("$fname: header size >= 2**32\n");
-      }
-      my @pair = unpack($self->{unpack_code} . "*", $str);
-      # Since we know one of the pair is 0, it's fine to just add them.
-      @$slots = (0, $pair[0] + $pair[1]);
-    }
-    return $self;
-  }
-
-  # Load more data when we access slots->get(X) which is not yet in memory.
-  sub overflow {
-    my ($self) = @_;
-    my $slots = $self->{slots};
-    $self->{base} += $#$slots + 1;   # skip over data we're replacing
-    my $str;
-    read($self->{file}, $str, $self->{stride});
-    if ($address_length == 8) {      # the 32-bit case
-      # This is the easy case: unpack provides 32-bit unpacking primitives.
-      @$slots = unpack($self->{unpack_code} . "*", $str);
-    } else {
-      # We need to unpack 32 bits at a time and combine.
-      my @b32_values = unpack($self->{unpack_code} . "*", $str);
-      my @b64_values = ();
-      for (my $i = 0; $i < $#b32_values; $i += 2) {
-        # TODO(csilvers): if this is a 32-bit perl, the math below
-        #    could end up in a too-large int, which perl will promote
-        #    to a double, losing necessary precision.  Deal with that.
-        if ($self->{unpack_code} eq 'V') {    # little-endian
-          push(@b64_values, $b32_values[$i] + $b32_values[$i+1] * (2**32));
-        } else {
-          push(@b64_values, $b32_values[$i] * (2**32) + $b32_values[$i+1]);
-        }
-      }
-      @$slots = @b64_values;
-    }
-  }
-
-  # Access the i-th long in the file (logically), or -1 at EOF.
-  sub get {
-    my ($self, $idx) = @_;
-    my $slots = $self->{slots};
-    while ($#$slots >= 0) {
-      if ($idx < $self->{base}) {
-        # The only time we expect a reference to $slots[$i - something]
-        # after referencing $slots[$i] is reading the very first header.
-        # Since $stride > |header|, that shouldn't cause any lookback
-        # errors.  And everything after the header is sequential.
-        print STDERR "Unexpected look-back reading CPU profile";
-        return -1;   # shrug, don't know what better to return
-      } elsif ($idx > $self->{base} + $#$slots) {
-        $self->overflow();
-      } else {
-        return $slots->[$idx - $self->{base}];
-      }
-    }
-    # If we get here, $slots is [], which means we've reached EOF
-    return -1;  # unique since slots is supposed to hold unsigned numbers
-  }
-}
-
-# Parse profile generated by common/profiler.cc and return a reference
-# to a map:
-#      $result->{version}     Version number of profile file
-#      $result->{period}      Sampling period (in microseconds)
-#      $result->{profile}     Profile object
-#      $result->{map}         Memory map info from profile
-#      $result->{pcs}         Hash of all PC values seen, key is hex address
-sub ReadProfile {
-  my $prog = shift;
-  my $fname = shift;
-
-  if (IsSymbolizedProfileFile($fname) && !$main::use_symbolized_profile) {
-    # we have both a binary and symbolized profiles, abort
-    usage("Symbolized profile '$fname' cannot be used with a binary arg.  " .
-          "Try again without passing '$prog'.");
-  }
-
-  $main::profile_type = '';
-
-  $CONTENTION_PAGE =~ m,[^/]+$,;    # matches everything after the last slash
-  my $contention_marker = $&;
-  $GROWTH_PAGE  =~ m,[^/]+$,;    # matches everything after the last slash
-  my $growth_marker = $&;
-  $SYMBOL_PAGE =~ m,[^/]+$,;    # matches everything after the last slash
-  my $symbol_marker = $&;
-  $PROFILE_PAGE =~ m,[^/]+$,;    # matches everything after the last slash
-  my $profile_marker = $&;
-
-  # Look at first line to see if it is a heap or a CPU profile.
-  # CPU profile may start with no header at all, and just binary data
-  # (starting with \0\0\0\0) -- in that case, don't try to read the
-  # whole firstline, since it may be gigabytes(!) of data.
-  open(PROFILE, "<$fname") || error("$fname: $!\n");
-  binmode PROFILE;      # New perls do UTF-8 processing
-  my $firstchar = "";
-  my $header = "";
-  read(PROFILE, $firstchar, 1);
-  seek(PROFILE, -1, 1);          # unread the firstchar
-  if ($firstchar ne "\0") {
-    $header = <PROFILE>;
-    if (!defined($header)) {
-      error("Profile is empty.\n");
-    }
-    $header =~ s/\r//g;   # turn windows-looking lines into unix-looking lines
-  }
-
-  my $symbols;
-  if ($header =~ m/^--- *$symbol_marker/o) {
-    # read the symbol section of the symbolized profile file
-    $symbols = ReadSymbols(*PROFILE{IO});
-
-    # read the next line to get the header for the remaining profile
-    $header = "";
-    read(PROFILE, $firstchar, 1);
-    seek(PROFILE, -1, 1);          # unread the firstchar
-    if ($firstchar ne "\0") {
-      $header = <PROFILE>;
-      $header =~ s/\r//g;
-    }
-  }
-
-  my $result;
-
-  if ($header =~ m/^heap profile:.*$growth_marker/o) {
-    $main::profile_type = 'growth';
-    $result =  ReadHeapProfile($prog, $fname, $header);
-  } elsif ($header =~ m/^heap profile:/) {
-    $main::profile_type = 'heap';
-    $result =  ReadHeapProfile($prog, $fname, $header);
-  } elsif ($header =~ m/^--- *$contention_marker/o) {
-    $main::profile_type = 'contention';
-    $result = ReadSynchProfile($prog, $fname);
-  } elsif ($header =~ m/^--- *Stacks:/) {
-    print STDERR
-      "Old format contention profile: mistakenly reports " .
-      "condition variable signals as lock contentions.\n";
-    $main::profile_type = 'contention';
-    $result = ReadSynchProfile($prog, $fname);
-  } elsif ($header =~ m/^thread creation profile:/) {
-    $main::profile_type = 'thread';
-    $result = ReadThreadProfile($prog, $fname);
-  } elsif ($header =~ m/^--- *$profile_marker/) {
-    # the binary cpu profile data starts immediately after this line
-    $main::profile_type = 'cpu';
-    $result = ReadCPUProfile($prog, $fname);
-  } else {
-    if (defined($symbols)) {
-      # a symbolized profile contains a format we don't recognize, bail out
-      error("$fname: Cannot recognize profile section after symbols.\n");
-    }
-    # no ascii header present -- must be a CPU profile
-    $main::profile_type = 'cpu';
-    $result = ReadCPUProfile($prog, $fname);
-  }
-
-  # if we got symbols along with the profile, return those as well
-  if (defined($symbols)) {
-    $result->{symbols} = $symbols;
-  }
-
-  return $result;
-}
-
-# Subtract one from caller pc so we map back to call instr.
-# However, don't do this if we're reading a symbolized profile
-# file, in which case the subtract-one was done when the file
-# was written.
-#
-# We apply the same logic to all readers, though ReadCPUProfile uses an
-# independent implementation.
-sub FixCallerAddresses {
-  my $stack = shift;
-  if ($main::use_symbolized_profile) {
-    return $stack;
-  } else {
-    $stack =~ /(\s)/;
-    my $delimiter = $1;
-    my @addrs = split(' ', $stack);
-    my @fixedaddrs;
-    $#fixedaddrs = $#addrs;
-    if ($#addrs >= 0) {
-      $fixedaddrs[0] = $addrs[0];
-    }
-    for (my $i = 1; $i <= $#addrs; $i++) {
-      $fixedaddrs[$i] = AddressSub($addrs[$i], "0x1");
-    }
-    return join $delimiter, @fixedaddrs;
-  }
-}
-
-# CPU profile reader
-sub ReadCPUProfile {
-  my $prog = shift;
-  my $fname = shift;
-  my $version;
-  my $period;
-  my $i;
-  my $profile = {};
-  my $pcs = {};
-
-  # Parse string into array of slots.
-  my $slots = CpuProfileStream->new(*PROFILE, $fname);
-
-  # Read header.  The current header version is a 5-element structure
-  # containing:
-  #   0: header count (always 0)
-  #   1: header "words" (after this one: 3)
-  #   2: format version (0)
-  #   3: sampling period (usec)
-  #   4: unused padding (always 0)
-  if ($slots->get(0) != 0 ) {
-    error("$fname: not a profile file, or old format profile file\n");
-  }
-  $i = 2 + $slots->get(1);
-  $version = $slots->get(2);
-  $period = $slots->get(3);
-  # Do some sanity checking on these header values.
-  if ($version > (2**32) || $period > (2**32) || $i > (2**32) || $i < 5) {
-    error("$fname: not a profile file, or corrupted profile file\n");
-  }
-
-  # Parse profile
-  while ($slots->get($i) != -1) {
-    my $n = $slots->get($i++);
-    my $d = $slots->get($i++);
-    if ($d > (2**16)) {  # TODO(csilvers): what's a reasonable max-stack-depth?
-      my $addr = sprintf("0%o", $i * ($address_length == 8 ? 4 : 8));
-      print STDERR "At index $i (address $addr):\n";
-      error("$fname: stack trace depth >= 2**32\n");
-    }
-    if ($slots->get($i) == 0) {
-      # End of profile data marker
-      $i += $d;
-      last;
-    }
-
-    # Make key out of the stack entries
-    my @k = ();
-    for (my $j = 0; $j < $d; $j++) {
-      my $pc = $slots->get($i+$j);
-      # Subtract one from caller pc so we map back to call instr.
-      # However, don't do this if we're reading a symbolized profile
-      # file, in which case the subtract-one was done when the file
-      # was written.
-      if ($j > 0 && !$main::use_symbolized_profile) {
-        $pc--;
-      }
-      $pc = sprintf("%0*x", $address_length, $pc);
-      $pcs->{$pc} = 1;
-      push @k, $pc;
-    }
-
-    AddEntry($profile, (join "\n", @k), $n);
-    $i += $d;
-  }
-
-  # Parse map
-  my $map = '';
-  seek(PROFILE, $i * 4, 0);
-  read(PROFILE, $map, (stat PROFILE)[7]);
-  close(PROFILE);
-
-  my $r = {};
-  $r->{version} = $version;
-  $r->{period} = $period;
-  $r->{profile} = $profile;
-  $r->{libs} = ParseLibraries($prog, $map, $pcs);
-  $r->{pcs} = $pcs;
-
-  return $r;
-}
-
-sub ReadHeapProfile {
-  my $prog = shift;
-  my $fname = shift;
-  my $header = shift;
-
-  my $index = 1;
-  if ($main::opt_inuse_space) {
-    $index = 1;
-  } elsif ($main::opt_inuse_objects) {
-    $index = 0;
-  } elsif ($main::opt_alloc_space) {
-    $index = 3;
-  } elsif ($main::opt_alloc_objects) {
-    $index = 2;
-  }
-
-  # Find the type of this profile.  The header line looks like:
-  #    heap profile:   1246:  8800744 [  1246:  8800744] @ <heap-url>/266053
-  # There are two pairs <count: size>, the first inuse objects/space, and the
-  # second allocated objects/space.  This is followed optionally by a profile
-  # type, and if that is present, optionally by a sampling frequency.
-  # For remote heap profiles (v1):
-  # The interpretation of the sampling frequency is that the profiler, for
-  # each sample, calculates a uniformly distributed random integer less than
-  # the given value, and records the next sample after that many bytes have
-  # been allocated.  Therefore, the expected sample interval is half of the
-  # given frequency.  By default, if not specified, the expected sample
-  # interval is 128KB.  Only remote-heap-page profiles are adjusted for
-  # sample size.
-  # For remote heap profiles (v2):
-  # The sampling frequency is the rate of a Poisson process. This means that
-  # the probability of sampling an allocation of size X with sampling rate Y
-  # is 1 - exp(-X/Y)
-  # For version 2, a typical header line might look like this:
-  # heap profile:   1922: 127792360 [  1922: 127792360] @ <heap-url>_v2/524288
-  # the trailing number (524288) is the sampling rate. (Version 1 showed
-  # double the 'rate' here)
-  my $sampling_algorithm = 0;
-  my $sample_adjustment = 0;
-  chomp($header);
-  my $type = "unknown";
-  if ($header =~ m"^heap profile:\s*(\d+):\s+(\d+)\s+\[\s*(\d+):\s+(\d+)\](\s*@\s*([^/]*)(/(\d+))?)?") {
-    if (defined($6) && ($6 ne '')) {
-      $type = $6;
-      my $sample_period = $8;
-      # $type is "heapprofile" for profiles generated by the
-      # heap-profiler, and either "heap" or "heap_v2" for profiles
-      # generated by sampling directly within tcmalloc.  It can also
-      # be "growth" for heap-growth profiles.  The first is typically
-      # found for profiles generated locally, and the others for
-      # remote profiles.
-      if (($type eq "heapprofile") || ($type !~ /heap/) ) {
-        # No need to adjust for the sampling rate with heap-profiler-derived data
-        $sampling_algorithm = 0;
-      } elsif ($type =~ /_v2/) {
-        $sampling_algorithm = 2;     # version 2 sampling
-        if (defined($sample_period) && ($sample_period ne '')) {
-          $sample_adjustment = int($sample_period);
-        }
-      } else {
-        $sampling_algorithm = 1;     # version 1 sampling
-        if (defined($sample_period) && ($sample_period ne '')) {
-          $sample_adjustment = int($sample_period)/2;
-        }
-      }
-    } else {
-      # We detect whether or not this is a remote-heap profile by checking
-      # that the total-allocated stats ($n2,$s2) are exactly the
-      # same as the in-use stats ($n1,$s1).  It is remotely conceivable
-      # that a non-remote-heap profile may pass this check, but it is hard
-      # to imagine how that could happen.
-      # In this case it's so old it's guaranteed to be remote-heap version 1.
-      my ($n1, $s1, $n2, $s2) = ($1, $2, $3, $4);
-      if (($n1 == $n2) && ($s1 == $s2)) {
-        # This is likely to be a remote-heap based sample profile
-        $sampling_algorithm = 1;
-      }
-    }
-  }
-
-  if ($sampling_algorithm > 0) {
-    # For remote-heap generated profiles, adjust the counts and sizes to
-    # account for the sample rate (we sample once every 128KB by default).
-    if ($sample_adjustment == 0) {
-      # Turn on profile adjustment.
-      $sample_adjustment = 128*1024;
-      print STDERR "Adjusting heap profiles for 1-in-128KB sampling rate\n";
-    } else {
-      printf STDERR ("Adjusting heap profiles for 1-in-%d sampling rate\n",
-                     $sample_adjustment);
-    }
-    if ($sampling_algorithm > 1) {
-      # We don't bother printing anything for the original version (version 1)
-      printf STDERR "Heap version $sampling_algorithm\n";
-    }
-  }
-
-  my $profile = {};
-  my $pcs = {};
-  my $map = "";
-
-  while (<PROFILE>) {
-    s/\r//g;         # turn windows-looking lines into unix-looking lines
-    if (/^MAPPED_LIBRARIES:/) {
-      # Read the /proc/self/maps data
-      while (<PROFILE>) {
-        s/\r//g;         # turn windows-looking lines into unix-looking lines
-        $map .= $_;
-      }
-      last;
-    }
-
-    if (/^--- Memory map:/) {
-      # Read /proc/self/maps data as formatted by DumpAddressMap()
-      my $buildvar = "";
-      while (<PROFILE>) {
-        s/\r//g;         # turn windows-looking lines into unix-looking lines
-        # Parse "build=<dir>" specification if supplied
-        if (m/^\s*build=(.*)\n/) {
-          $buildvar = $1;
-        }
-
-        # Expand "$build" variable if available
-        $_ =~ s/\$build\b/$buildvar/g;
-
-        $map .= $_;
-      }
-      last;
-    }
-
-    # Read entry of the form:
-    #  <count1>: <bytes1> [<count2>: <bytes2>] @ a1 a2 a3 ... an
-    s/^\s*//;
-    s/\s*$//;
-    if (m/^\s*(\d+):\s+(\d+)\s+\[\s*(\d+):\s+(\d+)\]\s+@\s+(.*)$/) {
-      my $stack = $5;
-      my ($n1, $s1, $n2, $s2) = ($1, $2, $3, $4);
-
-      if ($sample_adjustment) {
-        if ($sampling_algorithm == 2) {
-          # Remote-heap version 2
-          # The sampling frequency is the rate of a Poisson process.
-          # This means that the probability of sampling an allocation of
-          # size X with sampling rate Y is 1 - exp(-X/Y)
-          my $ratio;
-          $ratio = (($s1*1.0)/$n1)/($sample_adjustment);
-          my $scale_factor;
-          $scale_factor = 1/(1 - exp(-$ratio));
-          $n1 *= $scale_factor;
-          $s1 *= $scale_factor;
-          $ratio = (($s2*1.0)/$n2)/($sample_adjustment);
-          $scale_factor = 1/(1 - exp(-$ratio));
-          $n2 *= $scale_factor;
-          $s2 *= $scale_factor;
-        } else {
-          # Remote-heap version 1
-          my $ratio;
-          if ($n1 > 0) {
-            $ratio = (($s1*1.0)/$n1)/($sample_adjustment);
-            if ($ratio < 1) {
-                $n1 /= $ratio;
-                $s1 /= $ratio;
-            }
-          }
-          if ($n2 > 0) {
-            $ratio = (($s2*1.0)/$n2)/($sample_adjustment);
-            if ($ratio < 1) {
-                $n2 /= $ratio;
-                $s2 /= $ratio;
-            }
-          }
-        }
-      }
-
-      my @counts = ($n1, $s1, $n2, $s2);
-      AddEntries($profile, $pcs, FixCallerAddresses($stack), $counts[$index]);
-    }
-  }
-
-  my $r = {};
-  $r->{version} = "heap";
-  $r->{period} = 1;
-  $r->{profile} = $profile;
-  $r->{libs} = ParseLibraries($prog, $map, $pcs);
-  $r->{pcs} = $pcs;
-  return $r;
-}
-
-sub ReadThreadProfile {
-  my $prog = shift;
-  my $fname = shift;
-
-  my $profile = {};
-  my $pcs = {};
-  my $map = "";
-
-  while (<PROFILE>) {
-    s/\r//g;         # turn windows-looking lines into unix-looking lines
-    if (/^MAPPED_LIBRARIES:/) {
-      # Read the /proc/self/maps data
-      while (<PROFILE>) {
-        s/\r//g;         # turn windows-looking lines into unix-looking lines
-        $map .= $_;
-      }
-      last;
-    }
-
-    if (/^--- Memory map:/) {
-      # Read /proc/self/maps data as formatted by DumpAddressMap()
-      my $buildvar = "";
-      while (<PROFILE>) {
-        s/\r//g;         # turn windows-looking lines into unix-looking lines
-        # Parse "build=<dir>" specification if supplied
-        if (m/^\s*build=(.*)\n/) {
-          $buildvar = $1;
-        }
-
-        # Expand "$build" variable if available
-        $_ =~ s/\$build\b/$buildvar/g;
-
-        $map .= $_;
-      }
-      last;
-    }
-
-    # Read entry of the form:
-    #  @ a1 a2 a3 ... an
-    s/^\s*//;
-    s/\s*$//;
-    if (m/^@\s+(.*)$/) {
-      AddEntries($profile, $pcs, FixCallerAddresses($1), 1);
-    }
-  }
-
-  my $r = {};
-  $r->{version} = "thread";
-  $r->{period} = 1;
-  $r->{profile} = $profile;
-  $r->{libs} = ParseLibraries($prog, $map, $pcs);
-  $r->{pcs} = $pcs;
-  return $r;
-}
-
-sub ReadSynchProfile {
-  my ($prog, $fname, $header) = @_;
-
-  my $map = '';
-  my $profile = {};
-  my $pcs = {};
-  my $sampling_period = 1;
-  my $cyclespernanosec = 2.8;   # Default assumption for old binaries
-  my $seen_clockrate = 0;
-  my $line;
-
-  my $index = 0;
-  if ($main::opt_total_delay) {
-    $index = 0;
-  } elsif ($main::opt_contentions) {
-    $index = 1;
-  } elsif ($main::opt_mean_delay) {
-    $index = 2;
-  }
-
-  while ( $line = <PROFILE> ) {
-    $line =~ s/\r//g;      # turn windows-looking lines into unix-looking lines
-    if ( $line =~ /^\s*(\d+)\s+(\d+) \@\s*(.*?)\s*$/ ) {
-      my ($cycles, $count, $stack) = ($1, $2, $3);
-
-      # Convert cycles to nanoseconds
-      $cycles /= $cyclespernanosec;
-
-      # Adjust for sampling done by application
-      $cycles *= $sampling_period;
-      $count *= $sampling_period;
-
-      my @values = ($cycles, $count, $cycles / $count);
-      AddEntries($profile, $pcs, FixCallerAddresses($stack), $values[$index]);
-
-    } elsif ( $line =~ /^(slow release).*thread \d+  \@\s*(.*?)\s*$/ ||
-              $line =~ /^\s*(\d+) \@\s*(.*?)\s*$/ ) {
-      my ($cycles, $stack) = ($1, $2);
-      if ($cycles !~ /^\d+$/) {
-        next;
-      }
-
-      # Convert cycles to nanoseconds
-      $cycles /= $cyclespernanosec;
-
-      # Adjust for sampling done by application
-      $cycles *= $sampling_period;
-
-      AddEntries($profile, $pcs, FixCallerAddresses($stack), $cycles);
-
-    } elsif ( $line =~ m/^([a-z][^=]*)=(.*)$/ ) {
-      my ($variable, $value) = ($1,$2);
-      for ($variable, $value) {
-        s/^\s+//;
-        s/\s+$//;
-      }
-      if ($variable eq "cycles/second") {
-        $cyclespernanosec = $value / 1e9;
-        $seen_clockrate = 1;
-      } elsif ($variable eq "sampling period") {
-        $sampling_period = $value;
-      } elsif ($variable eq "ms since reset") {
-        # Currently nothing is done with this value in pprof
-        # So we just silently ignore it for now
-      } elsif ($variable eq "discarded samples") {
-        # Currently nothing is done with this value in pprof
-        # So we just silently ignore it for now
-      } else {
-        printf STDERR ("Ignoring unnknown variable in /contention output: " .
-                       "'%s' = '%s'\n",$variable,$value);
-      }
-    } else {
-      # Memory map entry
-      $map .= $line;
-    }
-  }
-  close PROFILE;
-
-  if (!$seen_clockrate) {
-    printf STDERR ("No cycles/second entry in profile; Guessing %.1f GHz\n",
-                   $cyclespernanosec);
-  }
-
-  my $r = {};
-  $r->{version} = 0;
-  $r->{period} = $sampling_period;
-  $r->{profile} = $profile;
-  $r->{libs} = ParseLibraries($prog, $map, $pcs);
-  $r->{pcs} = $pcs;
-  return $r;
-}
-
-# Given a hex value in the form "0x1abcd" return "0001abcd" or
-# "000000000001abcd", depending on the current address length.
-# There's probably a more idiomatic (or faster) way to do this...
-sub HexExtend {
-  my $addr = shift;
-
-  $addr =~ s/^0x//;
-
-  if (length $addr > $address_length) {
-    printf STDERR "Warning:  address $addr is longer than address length $address_length\n";
-  }
-
-  return substr("000000000000000".$addr, -$address_length);
-}
-
-##### Symbol extraction #####
-
-# Aggressively search the lib_prefix values for the given library
-# If all else fails, just return the name of the library unmodified.
-# If the lib_prefix is "/my/path,/other/path" and $file is "/lib/dir/mylib.so"
-# it will search the following locations in this order, until it finds a file:
-#   /my/path/lib/dir/mylib.so
-#   /other/path/lib/dir/mylib.so
-#   /my/path/dir/mylib.so
-#   /other/path/dir/mylib.so
-#   /my/path/mylib.so
-#   /other/path/mylib.so
-#   /lib/dir/mylib.so              (returned as last resort)
-sub FindLibrary {
-  my $file = shift;
-  my $suffix = $file;
-
-  # Search for the library as described above
-  do {
-    foreach my $prefix (@prefix_list) {
-      my $fullpath = $prefix . $suffix;
-      if (-e $fullpath) {
-        return $fullpath;
-      }
-    }
-  } while ($suffix =~ s|^/[^/]+/|/|);
-  return $file;
-}
-
-# Return path to library with debugging symbols.
-# For libc libraries, the copy in /usr/lib/debug contains debugging symbols
-sub DebuggingLibrary {
-  my $file = shift;
-  if ($file =~ m|^/| && -f "/usr/lib/debug$file") {
-    return "/usr/lib/debug$file";
-  }
-  return undef;
-}
-
-# Parse text section header of a library using objdump
-sub ParseTextSectionHeaderFromObjdump {
-  my $lib = shift;
-
-  my $size = undef;
-  my $vma;
-  my $file_offset;
-  # Get objdump output from the library file to figure out how to
-  # map between mapped addresses and addresses in the library.
-  my $objdump = $obj_tool_map{"objdump"};
-  open(OBJDUMP, "$objdump -h $lib |")
-                || error("$objdump $lib: $!\n");
-  while (<OBJDUMP>) {
-    s/\r//g;         # turn windows-looking lines into unix-looking lines
-    # Idx Name          Size      VMA       LMA       File off  Algn
-    #  10 .text         00104b2c  420156f0  420156f0  000156f0  2**4
-    # For 64-bit objects, VMA and LMA will be 16 hex digits, size and file
-    # offset may still be 8.  But AddressSub below will still handle that.
-    my @x = split;
-    if (($#x >= 6) && ($x[1] eq '.text')) {
-      $size = $x[2];
-      $vma = $x[3];
-      $file_offset = $x[5];
-      last;
-    }
-  }
-  close(OBJDUMP);
-
-  if (!defined($size)) {
-    return undef;
-  }
-
-  my $r = {};
-  $r->{size} = $size;
-  $r->{vma} = $vma;
-  $r->{file_offset} = $file_offset;
-
-  return $r;
-}
-
-# Parse text section header of a library using otool (on OS X)
-sub ParseTextSectionHeaderFromOtool {
-  my $lib = shift;
-
-  my $size = undef;
-  my $vma = undef;
-  my $file_offset = undef;
-  # Get otool output from the library file to figure out how to
-  # map between mapped addresses and addresses in the library.
-  my $otool = $obj_tool_map{"otool"};
-  open(OTOOL, "$otool -l $lib |")
-                || error("$otool $lib: $!\n");
-  my $cmd = "";
-  my $sectname = "";
-  my $segname = "";
-  foreach my $line (<OTOOL>) {
-    $line =~ s/\r//g;      # turn windows-looking lines into unix-looking lines
-    # Load command <#>
-    #       cmd LC_SEGMENT
-    # [...]
-    # Section
-    #   sectname __text
-    #    segname __TEXT
-    #       addr 0x000009f8
-    #       size 0x00018b9e
-    #     offset 2552
-    #      align 2^2 (4)
-    # We will need to strip off the leading 0x from the hex addresses,
-    # and convert the offset into hex.
-    if ($line =~ /Load command/) {
-      $cmd = "";
-      $sectname = "";
-      $segname = "";
-    } elsif ($line =~ /Section/) {
-      $sectname = "";
-      $segname = "";
-    } elsif ($line =~ /cmd (\w+)/) {
-      $cmd = $1;
-    } elsif ($line =~ /sectname (\w+)/) {
-      $sectname = $1;
-    } elsif ($line =~ /segname (\w+)/) {
-      $segname = $1;
-    } elsif (!(($cmd eq "LC_SEGMENT" || $cmd eq "LC_SEGMENT_64") &&
-               $sectname eq "__text" &&
-               $segname eq "__TEXT")) {
-      next;
-    } elsif ($line =~ /\baddr 0x([0-9a-fA-F]+)/) {
-      $vma = $1;
-    } elsif ($line =~ /\bsize 0x([0-9a-fA-F]+)/) {
-      $size = $1;
-    } elsif ($line =~ /\boffset ([0-9]+)/) {
-      $file_offset = sprintf("%016x", $1);
-    }
-    if (defined($vma) && defined($size) && defined($file_offset)) {
-      last;
-    }
-  }
-  close(OTOOL);
-
-  if (!defined($vma) || !defined($size) || !defined($file_offset)) {
-     return undef;
-  }
-
-  my $r = {};
-  $r->{size} = $size;
-  $r->{vma} = $vma;
-  $r->{file_offset} = $file_offset;
-
-  return $r;
-}
-
-sub ParseTextSectionHeader {
-  # obj_tool_map("otool") is only defined if we're in a Mach-O environment
-  if (defined($obj_tool_map{"otool"})) {
-    my $r = ParseTextSectionHeaderFromOtool(@_);
-    if (defined($r)){
-      return $r;
-    }
-  }
-  # If otool doesn't work, or we don't have it, fall back to objdump
-  return ParseTextSectionHeaderFromObjdump(@_);
-}
-
-# Split /proc/pid/maps dump into a list of libraries
-sub ParseLibraries {
-  return if $main::use_symbol_page;  # We don't need libraries info.
-  my $prog = shift;
-  my $map = shift;
-  my $pcs = shift;
-
-  my $result = [];
-  my $h = "[a-f0-9]+";
-  my $zero_offset = HexExtend("0");
-
-  my $buildvar = "";
-  foreach my $l (split("\n", $map)) {
-    if ($l =~ m/^\s*build=(.*)$/) {
-      $buildvar = $1;
-    }
-
-    my $start;
-    my $finish;
-    my $offset;
-    my $lib;
-    if ($l =~ /^($h)-($h)\s+..x.\s+($h)\s+\S+:\S+\s+\d+\s+(\S+\.(so|dll|dylib|bundle)((\.\d+)+\w*(\.\d+){0,3})?)$/i) {
-      # Full line from /proc/self/maps.  Example:
-      #   40000000-40015000 r-xp 00000000 03:01 12845071   /lib/ld-2.3.2.so
-      $start = HexExtend($1);
-      $finish = HexExtend($2);
-      $offset = HexExtend($3);
-      $lib = $4;
-      $lib =~ s|\\|/|g;     # turn windows-style paths into unix-style paths
-    } elsif ($l =~ /^\s*($h)-($h):\s*(\S+\.so(\.\d+)*)/) {
-      # Cooked line from DumpAddressMap.  Example:
-      #   40000000-40015000: /lib/ld-2.3.2.so
-      $start = HexExtend($1);
-      $finish = HexExtend($2);
-      $offset = $zero_offset;
-      $lib = $3;
-    } else {
-      next;
-    }
-
-    # Expand "$build" variable if available
-    $lib =~ s/\$build\b/$buildvar/g;
-
-    $lib = FindLibrary($lib);
-
-    # Check for pre-relocated libraries, which use pre-relocated symbol tables
-    # and thus require adjusting the offset that we'll use to translate
-    # VM addresses into symbol table addresses.
-    # Only do this if we're not going to fetch the symbol table from a
-    # debugging copy of the library.
-    if (!DebuggingLibrary($lib)) {
-      my $text = ParseTextSectionHeader($lib);
-      if (defined($text)) {
-         my $vma_offset = AddressSub($text->{vma}, $text->{file_offset});
-         $offset = AddressAdd($offset, $vma_offset);
-      }
-    }
-
-    push(@{$result}, [$lib, $start, $finish, $offset]);
-  }
-
-  # Append special entry for additional library (not relocated)
-  if ($main::opt_lib ne "") {
-    my $text = ParseTextSectionHeader($main::opt_lib);
-    if (defined($text)) {
-       my $start = $text->{vma};
-       my $finish = AddressAdd($start, $text->{size});
-
-       push(@{$result}, [$main::opt_lib, $start, $finish, $start]);
-    }
-  }
-
-  # Append special entry for the main program.  This covers
-  # 0..max_pc_value_seen, so that we assume pc values not found in one
-  # of the library ranges will be treated as coming from the main
-  # program binary.
-  my $min_pc = HexExtend("0");
-  my $max_pc = $min_pc;          # find the maximal PC value in any sample
-  foreach my $pc (keys(%{$pcs})) {
-    if (HexExtend($pc) gt $max_pc) { $max_pc = HexExtend($pc); }
-  }
-  push(@{$result}, [$prog, $min_pc, $max_pc, $zero_offset]);
-
-  return $result;
-}
-
-# Add two hex addresses of length $address_length.
-# Run pprof --test for unit test if this is changed.
-sub AddressAdd {
-  my $addr1 = shift;
-  my $addr2 = shift;
-  my $sum;
-
-  if ($address_length == 8) {
-    # Perl doesn't cope with wraparound arithmetic, so do it explicitly:
-    $sum = (hex($addr1)+hex($addr2)) % (0x10000000 * 16);
-    return sprintf("%08x", $sum);
-
-  } else {
-    # Do the addition in 7-nibble chunks to trivialize carry handling.
-
-    if ($main::opt_debug and $main::opt_test) {
-      print STDERR "AddressAdd $addr1 + $addr2 = ";
-    }
-
-    my $a1 = substr($addr1,-7);
-    $addr1 = substr($addr1,0,-7);
-    my $a2 = substr($addr2,-7);
-    $addr2 = substr($addr2,0,-7);
-    $sum = hex($a1) + hex($a2);
-    my $c = 0;
-    if ($sum > 0xfffffff) {
-      $c = 1;
-      $sum -= 0x10000000;
-    }
-    my $r = sprintf("%07x", $sum);
-
-    $a1 = substr($addr1,-7);
-    $addr1 = substr($addr1,0,-7);
-    $a2 = substr($addr2,-7);
-    $addr2 = substr($addr2,0,-7);
-    $sum = hex($a1) + hex($a2) + $c;
-    $c = 0;
-    if ($sum > 0xfffffff) {
-      $c = 1;
-      $sum -= 0x10000000;
-    }
-    $r = sprintf("%07x", $sum) . $r;
-
-    $sum = hex($addr1) + hex($addr2) + $c;
-    if ($sum > 0xff) { $sum -= 0x100; }
-    $r = sprintf("%02x", $sum) . $r;
-
-    if ($main::opt_debug and $main::opt_test) { print STDERR "$r\n"; }
-
-    return $r;
-  }
-}
-
-
-# Subtract two hex addresses of length $address_length.
-# Run pprof --test for unit test if this is changed.
-sub AddressSub {
-  my $addr1 = shift;
-  my $addr2 = shift;
-  my $diff;
-
-  if ($address_length == 8) {
-    # Perl doesn't cope with wraparound arithmetic, so do it explicitly:
-    $diff = (hex($addr1)-hex($addr2)) % (0x10000000 * 16);
-    return sprintf("%08x", $diff);
-
-  } else {
-    # Do the addition in 7-nibble chunks to trivialize borrow handling.
-    # if ($main::opt_debug) { print STDERR "AddressSub $addr1 - $addr2 = "; }
-
-    my $a1 = hex(substr($addr1,-7));
-    $addr1 = substr($addr1,0,-7);
-    my $a2 = hex(substr($addr2,-7));
-    $addr2 = substr($addr2,0,-7);
-    my $b = 0;
-    if ($a2 > $a1) {
-      $b = 1;
-      $a1 += 0x10000000;
-    }
-    $diff = $a1 - $a2;
-    my $r = sprintf("%07x", $diff);
-
-    $a1 = hex(substr($addr1,-7));
-    $addr1 = substr($addr1,0,-7);
-    $a2 = hex(substr($addr2,-7)) + $b;
-    $addr2 = substr($addr2,0,-7);
-    $b = 0;
-    if ($a2 > $a1) {
-      $b = 1;
-      $a1 += 0x10000000;
-    }
-    $diff = $a1 - $a2;
-    $r = sprintf("%07x", $diff) . $r;
-
-    $a1 = hex($addr1);
-    $a2 = hex($addr2) + $b;
-    if ($a2 > $a1) { $a1 += 0x100; }
-    $diff = $a1 - $a2;
-    $r = sprintf("%02x", $diff) . $r;
-
-    # if ($main::opt_debug) { print STDERR "$r\n"; }
-
-    return $r;
-  }
-}
-
-# Increment a hex addresses of length $address_length.
-# Run pprof --test for unit test if this is changed.
-sub AddressInc {
-  my $addr = shift;
-  my $sum;
-
-  if ($address_length == 8) {
-    # Perl doesn't cope with wraparound arithmetic, so do it explicitly:
-    $sum = (hex($addr)+1) % (0x10000000 * 16);
-    return sprintf("%08x", $sum);
-
-  } else {
-    # Do the addition in 7-nibble chunks to trivialize carry handling.
-    # We are always doing this to step through the addresses in a function,
-    # and will almost never overflow the first chunk, so we check for this
-    # case and exit early.
-
-    # if ($main::opt_debug) { print STDERR "AddressInc $addr1 = "; }
-
-    my $a1 = substr($addr,-7);
-    $addr = substr($addr,0,-7);
-    $sum = hex($a1) + 1;
-    my $r = sprintf("%07x", $sum);
-    if ($sum <= 0xfffffff) {
-      $r = $addr . $r;
-      # if ($main::opt_debug) { print STDERR "$r\n"; }
-      return HexExtend($r);
-    } else {
-      $r = "0000000";
-    }
-
-    $a1 = substr($addr,-7);
-    $addr = substr($addr,0,-7);
-    $sum = hex($a1) + 1;
-    $r = sprintf("%07x", $sum) . $r;
-    if ($sum <= 0xfffffff) {
-      $r = $addr . $r;
-      # if ($main::opt_debug) { print STDERR "$r\n"; }
-      return HexExtend($r);
-    } else {
-      $r = "00000000000000";
-    }
-
-    $sum = hex($addr) + 1;
-    if ($sum > 0xff) { $sum -= 0x100; }
-    $r = sprintf("%02x", $sum) . $r;
-
-    # if ($main::opt_debug) { print STDERR "$r\n"; }
-    return $r;
-  }
-}
-
-# Extract symbols for all PC values found in profile
-sub ExtractSymbols {
-  my $libs = shift;
-  my $pcset = shift;
-
-  my $symbols = {};
-
-  # Map each PC value to the containing library
-  my %seen = ();
-  foreach my $lib (@{$libs}) {
-    my $libname = $lib->[0];
-    my $start = $lib->[1];
-    my $finish = $lib->[2];
-    my $offset = $lib->[3];
-
-    # Get list of pcs that belong in this library.
-    my $contained = [];
-    foreach my $pc (keys(%{$pcset})) {
-      if (!$seen{$pc} && ($pc ge $start) && ($pc le $finish)) {
-        $seen{$pc} = 1;
-        push(@{$contained}, $pc);
-      }
-    }
-    # Map to symbols
-    MapToSymbols($libname, AddressSub($start, $offset), $contained, $symbols);
-  }
-
-  return $symbols;
-}
-
-# Map list of PC values to symbols for a given image
-sub MapToSymbols {
-  my $image = shift;
-  my $offset = shift;
-  my $pclist = shift;
-  my $symbols = shift;
-
-  my $debug = 0;
-
-  # Ignore empty binaries
-  if ($#{$pclist} < 0) { return; }
-
-  # Figure out the addr2line command to use
-  my $addr2line = $obj_tool_map{"addr2line"};
-  my $cmd = "$addr2line -f -C -e $image";
-  if (exists $obj_tool_map{"addr2line_pdb"}) {
-    $addr2line = $obj_tool_map{"addr2line_pdb"};
-    $cmd = "$addr2line --demangle -f -C -e $image";
-  }
-
-  # Use the go version because we know it works on all platforms
-  $addr2line = "go tool addr2line";
-  $cmd = "$addr2line $image";
-
-  # If "addr2line" isn't installed on the system at all, just use
-  # nm to get what info we can (function names, but not line numbers).
-  if (system("$addr2line --help >$DEVNULL 2>&1") != 0) {
-    MapSymbolsWithNM($image, $offset, $pclist, $symbols);
-    return;
-  }
-
-  # "addr2line -i" can produce a variable number of lines per input
-  # address, with no separator that allows us to tell when data for
-  # the next address starts.  So we find the address for a special
-  # symbol (_fini) and interleave this address between all real
-  # addresses passed to addr2line.  The name of this special symbol
-  # can then be used as a separator.
-  $sep_address = undef;  # May be filled in by MapSymbolsWithNM()
-  my $nm_symbols = {};
-  MapSymbolsWithNM($image, $offset, $pclist, $nm_symbols);
-  # TODO(csilvers): only add '-i' if addr2line supports it.
-  if (defined($sep_address)) {
-    # Only add " -i" to addr2line if the binary supports it.
-    # addr2line --help returns 0, but not if it sees an unknown flag first.
-    if (system("$cmd -i --help >$DEVNULL 2>&1") == 0) {
-      $cmd .= " -i";
-    } else {
-      $sep_address = undef;   # no need for sep_address if we don't support -i
-    }
-  }
-
-  # Make file with all PC values with intervening 'sep_address' so
-  # that we can reliably detect the end of inlined function list
-  open(ADDRESSES, ">$main::tmpfile_sym") || error("$main::tmpfile_sym: $!\n");
-  if ($debug) { print("---- $image ---\n"); }
-  for (my $i = 0; $i <= $#{$pclist}; $i++) {
-    # addr2line always reads hex addresses, and does not need '0x' prefix.
-    if ($debug) { printf STDERR ("%s\n", $pclist->[$i]); }
-    printf ADDRESSES ("%s\n", AddressSub($pclist->[$i], $offset));
-    if (defined($sep_address)) {
-      printf ADDRESSES ("%s\n", $sep_address);
-    }
-  }
-  close(ADDRESSES);
-  if ($debug) {
-    print("----\n");
-    system("cat $main::tmpfile_sym");
-    print("---- $cmd\n");
-    system("$cmd <$main::tmpfile_sym");
-    print("----\n");
-  }
-
-  open(SYMBOLS, "$cmd <$main::tmpfile_sym |") || error("$cmd: $!\n");
-  my $count = 0;   # Index in pclist
-  while (<SYMBOLS>) {
-    # Read fullfunction and filelineinfo from next pair of lines
-    s/\r?\n$//g;
-    my $fullfunction = $_;
-    $_ = <SYMBOLS>;
-    s/\r?\n$//g;
-    my $filelinenum = $_;
-
-    if (defined($sep_address) && $fullfunction eq $sep_symbol) {
-      # Terminating marker for data for this address
-      $count++;
-      next;
-    }
-
-    $filelinenum =~ s|\\|/|g; # turn windows-style paths into unix-style paths
-
-    my $pcstr = $pclist->[$count];
-    my $function = ShortFunctionName($fullfunction);
-    if ($fullfunction eq '??') {
-      # See if nm found a symbol
-      my $nms = $nm_symbols->{$pcstr};
-      if (defined($nms)) {
-        $function = $nms->[0];
-        $fullfunction = $nms->[2];
-      }
-    }
-
-    # Prepend to accumulated symbols for pcstr
-    # (so that caller comes before callee)
-    my $sym = $symbols->{$pcstr};
-    if (!defined($sym)) {
-      $sym = [];
-      $symbols->{$pcstr} = $sym;
-    }
-    unshift(@{$sym}, $function, $filelinenum, $fullfunction);
-    if ($debug) { printf STDERR ("%s => [%s]\n", $pcstr, join(" ", @{$sym})); }
-    if (!defined($sep_address)) {
-      # Inlining is off, se this entry ends immediately
-      $count++;
-    }
-  }
-  close(SYMBOLS);
-}
-
-# Use nm to map the list of referenced PCs to symbols.  Return true iff we
-# are able to read procedure information via nm.
-sub MapSymbolsWithNM {
-  my $image = shift;
-  my $offset = shift;
-  my $pclist = shift;
-  my $symbols = shift;
-
-  # Get nm output sorted by increasing address
-  my $symbol_table = GetProcedureBoundaries($image, ".");
-  if (!%{$symbol_table}) {
-    return 0;
-  }
-  # Start addresses are already the right length (8 or 16 hex digits).
-  my @names = sort { $symbol_table->{$a}->[0] cmp $symbol_table->{$b}->[0] }
-    keys(%{$symbol_table});
-
-  if ($#names < 0) {
-    # No symbols: just use addresses
-    foreach my $pc (@{$pclist}) {
-      my $pcstr = "0x" . $pc;
-      $symbols->{$pc} = [$pcstr, "?", $pcstr];
-    }
-    return 0;
-  }
-
-  # Sort addresses so we can do a join against nm output
-  my $index = 0;
-  my $fullname = $names[0];
-  my $name = ShortFunctionName($fullname);
-  foreach my $pc (sort { $a cmp $b } @{$pclist}) {
-    # Adjust for mapped offset
-    my $mpc = AddressSub($pc, $offset);
-    while (($index < $#names) && ($mpc ge $symbol_table->{$fullname}->[1])){
-      $index++;
-      $fullname = $names[$index];
-      $name = ShortFunctionName($fullname);
-    }
-    if ($mpc lt $symbol_table->{$fullname}->[1]) {
-      $symbols->{$pc} = [$name, "?", $fullname];
-    } else {
-      my $pcstr = "0x" . $pc;
-      $symbols->{$pc} = [$pcstr, "?", $pcstr];
-    }
-  }
-  return 1;
-}
-
-sub ShortFunctionName {
-  my $function = shift;
-  while ($function =~ s/(?<!\.)\([^()]*\)(\s*const)?//g) { }   # Argument types
-  while ($function =~ s/<[^<>]*>//g)  { }    # Remove template arguments
-  $function =~ s/^.*\s+(\w+::)/$1/;          # Remove leading type
-  return $function;
-}
-
-# Trim overly long symbols found in disassembler output
-sub CleanDisassembly {
-  my $d = shift;
-  while ($d =~ s/(?<!\.)\([^()%A-Z]*\)(\s*const)?//g) { } # Argument types, not (%rax)
-  while ($d =~ s/(\w+)<[^<>]*>/$1/g)  { }       # Remove template arguments
-  return $d;
-}
-
-##### Miscellaneous #####
-
-# Find the right versions of the above object tools to use.  The
-# argument is the program file being analyzed, and should be an ELF
-# 32-bit or ELF 64-bit executable file.  The location of the tools
-# is determined by considering the following options in this order:
-#   1) --tools option, if set
-#   2) PPROF_TOOLS environment variable, if set
-#   3) the environment
-sub ConfigureObjTools {
-  my $prog_file = shift;
-
-  # Check for the existence of $prog_file because /usr/bin/file does not
-  # predictably return error status in prod.
-  (-e $prog_file)  || error("$prog_file does not exist.\n");
-
-  # Follow symlinks (at least for systems where "file" supports that)
-  my $file_cmd = "/usr/bin/file -L $prog_file 2>$DEVNULL || /usr/bin/file $prog_file 2>$DEVNULL";
-  if ($^O eq "MSWin32") {
-    $file_cmd = "file -L $prog_file 2>NUL || file $prog_file 2>NUL";
-  }
-  my $file_type = `$file_cmd`;
-
-  if ($file_type =~ /64-bit/) {
-    # Change $address_length to 16 if the program file is ELF 64-bit.
-    # We can't detect this from many (most?) heap or lock contention
-    # profiles, since the actual addresses referenced are generally in low
-    # memory even for 64-bit programs.
-    $address_length = 16;
-  }
-
-  if (($file_type =~ /MS Windows/) || ($OS eq "windows")) {
-    # For windows, we provide a version of nm and addr2line as part of
-    # the opensource release, which is capable of parsing
-    # Windows-style PDB executables.  It should live in the path, or
-    # in the same directory as pprof.
-    $obj_tool_map{"nm_pdb"} = "nm-pdb";
-    $obj_tool_map{"addr2line_pdb"} = "addr2line-pdb";
-    $obj_tool_map{"objdump"} = "false";  # no objdump
-  }
-
-  if ($file_type =~ /Mach-O/) {
-    # OS X uses otool to examine Mach-O files, rather than objdump.
-    $obj_tool_map{"otool"} = "otool";
-    $obj_tool_map{"addr2line"} = "false";  # no addr2line
-    $obj_tool_map{"objdump"} = "false";  # no objdump
-  }
-
-  # Go fill in %obj_tool_map with the pathnames to use:
-  foreach my $tool (keys %obj_tool_map) {
-    $obj_tool_map{$tool} = ConfigureTool($obj_tool_map{$tool});
-  }
-}
-
-# Returns the path of a caller-specified object tool.  If --tools or
-# PPROF_TOOLS are specified, then returns the full path to the tool
-# with that prefix.  Otherwise, returns the path unmodified (which
-# means we will look for it on PATH).
-sub ConfigureTool {
-  my $tool = shift;
-  my $path;
-
-  if ($main::opt_tools ne "") {
-    # Use a prefix specified by the --tools option...
-    $path = $main::opt_tools . $tool;
-    if (!-x $path) {
-      error("No '$tool' found with prefix specified by --tools $main::opt_tools\n");
-    }
-  } elsif (exists $ENV{"PPROF_TOOLS"} &&
-           $ENV{"PPROF_TOOLS"} ne "") {
-    #... or specified with the PPROF_TOOLS environment variable...
-    $path = $ENV{"PPROF_TOOLS"} . $tool;
-    if (!-x $path) {
-      error("No '$tool' found with prefix specified by PPROF_TOOLS=$ENV{PPROF_TOOLS}\n");
-    }
-  } else {
-    # ... otherwise use the version that exists in the same directory as
-    # pprof.  If there's nothing there, use $PATH.
-    $0 =~ m,[^/]*$,;     # this is everything after the last slash
-    my $dirname = $`;    # this is everything up to and including the last slash
-    if (-x "$dirname$tool") {
-      $path = "$dirname$tool";
-    } else {
-      $path = $tool;
-    }
-  }
-  if ($main::opt_debug) { print STDERR "Using '$path' for '$tool'.\n"; }
-  return $path;
-}
-
-# FetchHTTP retrieves a URL using either curl or LWP::UserAgent.
-# It returns the entire body of the page on success, or exits the program
-# with an error message on any failure.
-sub FetchHTTP {
-  my $url = shift;
-  my $timeout = shift;  # optional, in seconds
-  eval "use LWP::UserAgent ();";
-  if ($@) {
-    my @max;
-    push @max, "--max-time", $timeout if $timeout;
-    open(my $fh, "-|", "curl", @max, "-s", $url) or error("Neither LWP::UserAgent nor curl is installed: $!\n");
-    my $slurp = do { local $/; <$fh> };
-    close($fh);
-    if ($? != 0) {
-      error("Error fetching $url with curl: exit $?")
-    }
-    return $slurp;
-  }
-  my $ua = LWP::UserAgent->new;
-  $ua->timeout($timeout) if $timeout;
-  my $res = $ua->get($url);
-  error("Failed to fetch $url\n") unless $res->is_success();
-  return $res->content();
-}
-
-sub PostHTTP {
-  my ($url, $post_data) = @_;
-  eval "use LWP::UserAgent ();";
-  if ($@) {
-    open(POSTFILE, ">$main::tmpfile_sym");
-    print POSTFILE $post_data;
-    close(POSTFILE);
-
-    open(my $fh, "-|", "curl", "-s", "-d", "\@$main::tmpfile_sym", $url) or error("Neither LWP::UserAgent nor curl is installed: $!\n");
-    my $slurp = do { local $/; <$fh> };
-    close($fh);
-    if ($? != 0) {
-      error("Error fetching $url with curl: exit $?")
-    }
-    return $slurp;
-  }
-  my $req = HTTP::Request->new(POST => $url);
-  $req->content($post_data);
-  my $ua = LWP::UserAgent->new;
-  my $res = $ua->request($req);
-  error("Failed to POST to $url\n") unless $res->is_success();
-  return $res->content();
-}
-
-sub cleanup {
-  unlink($main::tmpfile_sym) if defined $main::tmpfile_sym;
-  unlink(keys %main::tempnames) if %main::tempnames;
-  unlink($main::collected_profile) if defined $main::collected_profile;
-
-  # We leave any collected profiles in $HOME/pprof in case the user wants
-  # to look at them later.  We print a message informing them of this.
-  if ((scalar(@main::profile_files) > 0) &&
-      defined($main::collected_profile)) {
-    if (scalar(@main::profile_files) == 1) {
-      print STDERR "Dynamically gathered profile is in $main::collected_profile\n";
-    }
-    print STDERR "If you want to investigate this profile further, you can do:\n";
-    print STDERR "\n";
-    print STDERR "  pprof \\\n";
-    print STDERR "    $main::prog \\\n";
-    print STDERR "    $main::collected_profile\n";
-    print STDERR "\n";
-  }
-}
-
-sub sighandler {
-  cleanup();
-  exit(1);
-}
-
-sub error {
-  my $msg = shift;
-  print STDERR $msg;
-  cleanup();
-  exit(1);
-}
-
-
-# Run $nm_command and get all the resulting procedure boundaries whose
-# names match "$regexp" and returns them in a hashtable mapping from
-# procedure name to a two-element vector of [start address, end address]
-sub GetProcedureBoundariesViaNm {
-  my $nm_command = shift;
-  my $regexp = shift;
-
-  my $symbol_table = {};
-  open(NM, "$nm_command |") || error("$nm_command: $!\n");
-  my $last_start = "0";
-  my $routine = "";
-  while (<NM>) {
-    s/\r//g;         # turn windows-looking lines into unix-looking lines
-    if (m/^\s*([0-9a-f]+) (.) (..*)/) {
-      my $start_val = $1;
-      my $type = $2;
-      my $this_routine = $3;
-
-      # It's possible for two symbols to share the same address, if
-      # one is a zero-length variable (like __start_google_malloc) or
-      # one symbol is a weak alias to another (like __libc_malloc).
-      # In such cases, we want to ignore all values except for the
-      # actual symbol, which in nm-speak has type "T".  The logic
-      # below does this, though it's a bit tricky: what happens when
-      # we have a series of lines with the same address, is the first
-      # one gets queued up to be processed.  However, it won't
-      # *actually* be processed until later, when we read a line with
-      # a different address.  That means that as long as we're reading
-      # lines with the same address, we have a chance to replace that
-      # item in the queue, which we do whenever we see a 'T' entry --
-      # that is, a line with type 'T'.  If we never see a 'T' entry,
-      # we'll just go ahead and process the first entry (which never
-      # got touched in the queue), and ignore the others.
-      if ($start_val eq $last_start && $type =~ /t/i) {
-        # We are the 'T' symbol at this address, replace previous symbol.
-        $routine = $this_routine;
-        next;
-      } elsif ($start_val eq $last_start) {
-        # We're not the 'T' symbol at this address, so ignore us.
-        next;
-      }
-
-      if ($this_routine eq $sep_symbol) {
-        $sep_address = HexExtend($start_val);
-      }
-
-      # Tag this routine with the starting address in case the image
-      # has multiple occurrences of this routine.  We use a syntax
-      # that resembles template paramters that are automatically
-      # stripped out by ShortFunctionName()
-      $this_routine .= "<$start_val>";
-
-      if (defined($routine) && $routine =~ m/$regexp/) {
-        $symbol_table->{$routine} = [HexExtend($last_start),
-                                     HexExtend($start_val)];
-      }
-      $last_start = $start_val;
-      $routine = $this_routine;
-    } elsif (m/^Loaded image name: (.+)/) {
-      # The win32 nm workalike emits information about the binary it is using.
-      if ($main::opt_debug) { print STDERR "Using Image $1\n"; }
-    } elsif (m/^PDB file name: (.+)/) {
-      # The win32 nm workalike emits information about the pdb it is using.
-      if ($main::opt_debug) { print STDERR "Using PDB $1\n"; }
-    }
-  }
-  close(NM);
-  # Handle the last line in the nm output.  Unfortunately, we don't know
-  # how big this last symbol is, because we don't know how big the file
-  # is.  For now, we just give it a size of 0.
-  # TODO(csilvers): do better here.
-  if (defined($routine) && $routine =~ m/$regexp/) {
-    $symbol_table->{$routine} = [HexExtend($last_start),
-                                 HexExtend($last_start)];
-  }
-  return $symbol_table;
-}
-
-# Gets the procedure boundaries for all routines in "$image" whose names
-# match "$regexp" and returns them in a hashtable mapping from procedure
-# name to a two-element vector of [start address, end address].
-# Will return an empty map if nm is not installed or not working properly.
-sub GetProcedureBoundaries {
-  my $image = shift;
-  my $regexp = shift;
-
-  # For libc libraries, the copy in /usr/lib/debug contains debugging symbols
-  my $debugging = DebuggingLibrary($image);
-  if ($debugging) {
-    $image = $debugging;
-  }
-
-  my $nm = $obj_tool_map{"nm"};
-
-  # nm can fail for two reasons: 1) $image isn't a debug library; 2) nm
-  # binary doesn't support --demangle.  In addition, for OS X we need
-  # to use the -f flag to get 'flat' nm output (otherwise we don't sort
-  # properly and get incorrect results).  Unfortunately, GNU nm uses -f
-  # in an incompatible way.  So first we test whether our nm supports
-  # --demangle and -f.
-  my $demangle_flag = "";
-  if (system("$nm --demangle $image >$DEVNULL 2>&1") == 0) {
-    # In this mode, we do "nm --demangle <foo>"
-    $demangle_flag = "--demangle";
-  }
-  my $flatten_flag = "";
-  if (system("$nm -f $image >$DEVNULL 2>&1") == 0) {
-    $flatten_flag = "-f";
-  }
-
-  # Finally, in the case $image isn't a debug library, we try again with
-  # -D to at least get *exported* symbols.  If we can't use --demangle, too bad.
-  my @nm_commands = ("$nm -n $flatten_flag $demangle_flag" .
-                     " $image 2>$DEVNULL",
-                     "$nm -D -n $flatten_flag $demangle_flag" .
-                     " $image 2>$DEVNULL",
-                     # go tool nm is for Go binaries
-                     "go tool nm $image 2>$DEVNULL | sort");
-
-  foreach my $nm_command (@nm_commands) {
-    my $symbol_table = GetProcedureBoundariesViaNm($nm_command, $regexp);
-    return $symbol_table if (%{$symbol_table});
-  }
-  my $symbol_table = {};
-  return $symbol_table;
-}
-
-
-# The test vectors for AddressAdd/Sub/Inc are 8-16-nibble hex strings.
-# To make them more readable, we add underscores at interesting places.
-# This routine removes the underscores, producing the canonical representation
-# used by pprof to represent addresses, particularly in the tested routines.
-sub CanonicalHex {
-  my $arg = shift;
-  return join '', (split '_',$arg);
-}
-
-
-# Unit test for AddressAdd:
-sub AddressAddUnitTest {
-  my $test_data_8 = shift;
-  my $test_data_16 = shift;
-  my $error_count = 0;
-  my $fail_count = 0;
-  my $pass_count = 0;
-  # print STDERR "AddressAddUnitTest: ", 1+$#{$test_data_8}, " tests\n";
-
-  # First a few 8-nibble addresses.  Note that this implementation uses
-  # plain old arithmetic, so a quick sanity check along with verifying what
-  # happens to overflow (we want it to wrap):
-  $address_length = 8;
-  foreach my $row (@{$test_data_8}) {
-    if ($main::opt_debug and $main::opt_test) { print STDERR "@{$row}\n"; }
-    my $sum = AddressAdd ($row->[0], $row->[1]);
-    if ($sum ne $row->[2]) {
-      printf STDERR "ERROR: %s != %s + %s = %s\n", $sum,
-             $row->[0], $row->[1], $row->[2];
-      ++$fail_count;
-    } else {
-      ++$pass_count;
-    }
-  }
-  printf STDERR "AddressAdd 32-bit tests: %d passes, %d failures\n",
-         $pass_count, $fail_count;
-  $error_count = $fail_count;
-  $fail_count = 0;
-  $pass_count = 0;
-
-  # Now 16-nibble addresses.
-  $address_length = 16;
-  foreach my $row (@{$test_data_16}) {
-    if ($main::opt_debug and $main::opt_test) { print STDERR "@{$row}\n"; }
-    my $sum = AddressAdd (CanonicalHex($row->[0]), CanonicalHex($row->[1]));
-    my $expected = join '', (split '_',$row->[2]);
-    if ($sum ne CanonicalHex($row->[2])) {
-      printf STDERR "ERROR: %s != %s + %s = %s\n", $sum,
-             $row->[0], $row->[1], $row->[2];
-      ++$fail_count;
-    } else {
-      ++$pass_count;
-    }
-  }
-  printf STDERR "AddressAdd 64-bit tests: %d passes, %d failures\n",
-         $pass_count, $fail_count;
-  $error_count += $fail_count;
-
-  return $error_count;
-}
-
-
-# Unit test for AddressSub:
-sub AddressSubUnitTest {
-  my $test_data_8 = shift;
-  my $test_data_16 = shift;
-  my $error_count = 0;
-  my $fail_count = 0;
-  my $pass_count = 0;
-  # print STDERR "AddressSubUnitTest: ", 1+$#{$test_data_8}, " tests\n";
-
-  # First a few 8-nibble addresses.  Note that this implementation uses
-  # plain old arithmetic, so a quick sanity check along with verifying what
-  # happens to overflow (we want it to wrap):
-  $address_length = 8;
-  foreach my $row (@{$test_data_8}) {
-    if ($main::opt_debug and $main::opt_test) { print STDERR "@{$row}\n"; }
-    my $sum = AddressSub ($row->[0], $row->[1]);
-    if ($sum ne $row->[3]) {
-      printf STDERR "ERROR: %s != %s - %s = %s\n", $sum,
-             $row->[0], $row->[1], $row->[3];
-      ++$fail_count;
-    } else {
-      ++$pass_count;
-    }
-  }
-  printf STDERR "AddressSub 32-bit tests: %d passes, %d failures\n",
-         $pass_count, $fail_count;
-  $error_count = $fail_count;
-  $fail_count = 0;
-  $pass_count = 0;
-
-  # Now 16-nibble addresses.
-  $address_length = 16;
-  foreach my $row (@{$test_data_16}) {
-    if ($main::opt_debug and $main::opt_test) { print STDERR "@{$row}\n"; }
-    my $sum = AddressSub (CanonicalHex($row->[0]), CanonicalHex($row->[1]));
-    if ($sum ne CanonicalHex($row->[3])) {
-      printf STDERR "ERROR: %s != %s - %s = %s\n", $sum,
-             $row->[0], $row->[1], $row->[3];
-      ++$fail_count;
-    } else {
-      ++$pass_count;
-    }
-  }
-  printf STDERR "AddressSub 64-bit tests: %d passes, %d failures\n",
-         $pass_count, $fail_count;
-  $error_count += $fail_count;
-
-  return $error_count;
-}
-
-
-# Unit test for AddressInc:
-sub AddressIncUnitTest {
-  my $test_data_8 = shift;
-  my $test_data_16 = shift;
-  my $error_count = 0;
-  my $fail_count = 0;
-  my $pass_count = 0;
-  # print STDERR "AddressIncUnitTest: ", 1+$#{$test_data_8}, " tests\n";
-
-  # First a few 8-nibble addresses.  Note that this implementation uses
-  # plain old arithmetic, so a quick sanity check along with verifying what
-  # happens to overflow (we want it to wrap):
-  $address_length = 8;
-  foreach my $row (@{$test_data_8}) {
-    if ($main::opt_debug and $main::opt_test) { print STDERR "@{$row}\n"; }
-    my $sum = AddressInc ($row->[0]);
-    if ($sum ne $row->[4]) {
-      printf STDERR "ERROR: %s != %s + 1 = %s\n", $sum,
-             $row->[0], $row->[4];
-      ++$fail_count;
-    } else {
-      ++$pass_count;
-    }
-  }
-  printf STDERR "AddressInc 32-bit tests: %d passes, %d failures\n",
-         $pass_count, $fail_count;
-  $error_count = $fail_count;
-  $fail_count = 0;
-  $pass_count = 0;
-
-  # Now 16-nibble addresses.
-  $address_length = 16;
-  foreach my $row (@{$test_data_16}) {
-    if ($main::opt_debug and $main::opt_test) { print STDERR "@{$row}\n"; }
-    my $sum = AddressInc (CanonicalHex($row->[0]));
-    if ($sum ne CanonicalHex($row->[4])) {
-      printf STDERR "ERROR: %s != %s + 1 = %s\n", $sum,
-             $row->[0], $row->[4];
-      ++$fail_count;
-    } else {
-      ++$pass_count;
-    }
-  }
-  printf STDERR "AddressInc 64-bit tests: %d passes, %d failures\n",
-         $pass_count, $fail_count;
-  $error_count += $fail_count;
-
-  return $error_count;
-}
-
-
-# Driver for unit tests.
-# Currently just the address add/subtract/increment routines for 64-bit.
-sub RunUnitTests {
-  my $error_count = 0;
-
-  # This is a list of tuples [a, b, a+b, a-b, a+1]
-  my $unit_test_data_8 = [
-    [qw(aaaaaaaa 50505050 fafafafa 5a5a5a5a aaaaaaab)],
-    [qw(50505050 aaaaaaaa fafafafa a5a5a5a6 50505051)],
-    [qw(ffffffff aaaaaaaa aaaaaaa9 55555555 00000000)],
-    [qw(00000001 ffffffff 00000000 00000002 00000002)],
-    [qw(00000001 fffffff0 fffffff1 00000011 00000002)],
-  ];
-  my $unit_test_data_16 = [
-    # The implementation handles data in 7-nibble chunks, so those are the
-    # interesting boundaries.
-    [qw(aaaaaaaa 50505050
-        00_000000f_afafafa 00_0000005_a5a5a5a 00_000000a_aaaaaab)],
-    [qw(50505050 aaaaaaaa
-        00_000000f_afafafa ff_ffffffa_5a5a5a6 00_0000005_0505051)],
-    [qw(ffffffff aaaaaaaa
-        00_000001a_aaaaaa9 00_0000005_5555555 00_0000010_0000000)],
-    [qw(00000001 ffffffff
-        00_0000010_0000000 ff_ffffff0_0000002 00_0000000_0000002)],
-    [qw(00000001 fffffff0
-        00_000000f_ffffff1 ff_ffffff0_0000011 00_0000000_0000002)],
-
-    [qw(00_a00000a_aaaaaaa 50505050
-        00_a00000f_afafafa 00_a000005_a5a5a5a 00_a00000a_aaaaaab)],
-    [qw(0f_fff0005_0505050 aaaaaaaa
-        0f_fff000f_afafafa 0f_ffefffa_5a5a5a6 0f_fff0005_0505051)],
-    [qw(00_000000f_fffffff 01_800000a_aaaaaaa
-        01_800001a_aaaaaa9 fe_8000005_5555555 00_0000010_0000000)],
-    [qw(00_0000000_0000001 ff_fffffff_fffffff
-        00_0000000_0000000 00_0000000_0000002 00_0000000_0000002)],
-    [qw(00_0000000_0000001 ff_fffffff_ffffff0
-        ff_fffffff_ffffff1 00_0000000_0000011 00_0000000_0000002)],
-  ];
-
-  $error_count += AddressAddUnitTest($unit_test_data_8, $unit_test_data_16);
-  $error_count += AddressSubUnitTest($unit_test_data_8, $unit_test_data_16);
-  $error_count += AddressIncUnitTest($unit_test_data_8, $unit_test_data_16);
-  if ($error_count > 0) {
-    print STDERR $error_count, " errors: FAILED\n";
-  } else {
-    print STDERR "PASS\n";
-  }
-  exit ($error_count);
-}
diff --git a/misc/vim/autoload/go/complete.vim b/misc/vim/autoload/go/complete.vim
deleted file mode 100644
index a4fa6b6..0000000
--- a/misc/vim/autoload/go/complete.vim
+++ /dev/null
@@ -1,103 +0,0 @@
-" Copyright 2011 The Go Authors. All rights reserved.
-" Use of this source code is governed by a BSD-style
-" license that can be found in the LICENSE file.
-"
-" This file provides a utility function that performs auto-completion of
-" package names, for use by other commands.
-
-let s:goos = $GOOS
-let s:goarch = $GOARCH
-
-if len(s:goos) == 0
-  if exists('g:golang_goos')
-    let s:goos = g:golang_goos
-  elseif has('win32') || has('win64')
-    let s:goos = 'windows'
-  elseif has('macunix')
-    let s:goos = 'darwin'
-  else
-    let s:goos = '*'
-  endif
-endif
-
-if len(s:goarch) == 0
-  if exists('g:golang_goarch')
-    let s:goarch = g:golang_goarch
-  else
-    let s:goarch = '*'
-  endif
-endif
-
-function! go#complete#PackageMembers(package, member)
-  silent! let content = system('godoc ' . a:package)
-  if v:shell_error || !len(content)
-    return []
-  endif
-  let lines = filter(split(content, "\n"),"v:val !~ '^\\s\\+$'")
-  try
-    let mx1 = '^\s\+\(\S+\)\s\+=\s\+.*'
-    let mx2 = '^\%(const\|var\|type\|func\) \([A-Z][^ (]\+\).*'
-    let candidates =
-    \   map(filter(copy(lines), 'v:val =~ mx1'), 'substitute(v:val, mx1, "\\1", "")')
-    \ + map(filter(copy(lines), 'v:val =~ mx2'), 'substitute(v:val, mx2, "\\1", "")')
-    return filter(candidates, '!stridx(v:val, a:member)')
-  catch
-    return []
-  endtry
-endfunction
-
-function! go#complete#Package(ArgLead, CmdLine, CursorPos)
-  let dirs = []
-
-  let words = split(a:CmdLine, '\s\+', 1)
-  if len(words) > 2
-    " Complete package members
-    return go#complete#PackageMembers(words[1], words[2])
-  endif
-
-  if executable('go')
-    let goroot = substitute(system('go env GOROOT'), '\n', '', 'g')
-    if v:shell_error
-      echomsg '''go env GOROOT'' failed'
-    endif
-  else
-    let goroot = $GOROOT
-  endif
-
-  if len(goroot) != 0 && isdirectory(goroot)
-    let dirs += [goroot]
-  endif
-
-  let pathsep = ':'
-  if s:goos == 'windows'
-    let pathsep = ';'
-  endif
-  let workspaces = split($GOPATH, pathsep)
-  if workspaces != []
-    let dirs += workspaces
-  endif
-
-  if len(dirs) == 0
-    " should not happen
-    return []
-  endif
-
-  let ret = {}
-  for dir in dirs
-    " this may expand to multiple lines
-    let root = split(expand(dir . '/pkg/' . s:goos . '_' . s:goarch), "\n")
-    call add(root, expand(dir . '/src'))
-    for r in root
-      for i in split(globpath(r, a:ArgLead.'*'), "\n")
-        if isdirectory(i)
-          let i .= '/'
-        elseif i !~ '\.a$'
-          continue
-        endif
-        let i = substitute(substitute(i[len(r)+1:], '[\\]', '/', 'g'), '\.a$', '', 'g')
-        let ret[i] = i
-      endfor
-    endfor
-  endfor
-  return sort(keys(ret))
-endfunction
diff --git a/misc/vim/compiler/go.vim b/misc/vim/compiler/go.vim
deleted file mode 100644
index 2c8cce4..0000000
--- a/misc/vim/compiler/go.vim
+++ /dev/null
@@ -1,30 +0,0 @@
-" Copyright 2013 The Go Authors. All rights reserved.
-" Use of this source code is governed by a BSD-style
-" license that can be found in the LICENSE file.
-"
-" compiler/go.vim: Vim compiler file for Go.
-
-if exists("current_compiler")
-    finish
-endif
-let current_compiler = "go"
-
-if exists(":CompilerSet") != 2
-    command -nargs=* CompilerSet setlocal <args>
-endif
-
-let s:save_cpo = &cpo
-set cpo-=C
-
-CompilerSet makeprg=go\ build
-CompilerSet errorformat=
-        \%-G#\ %.%#,
-        \%A%f:%l:%c:\ %m,
-        \%A%f:%l:\ %m,
-        \%C%*\\s%m,
-        \%-G%.%#
-
-let &cpo = s:save_cpo
-unlet s:save_cpo
-
-" vim:ts=4:sw=4:et
diff --git a/misc/vim/ftdetect/gofiletype.vim b/misc/vim/ftdetect/gofiletype.vim
deleted file mode 100644
index b658f6b..0000000
--- a/misc/vim/ftdetect/gofiletype.vim
+++ /dev/null
@@ -1,23 +0,0 @@
-" We take care to preserve the user's fileencodings and fileformats,
-" because those settings are global (not buffer local), yet we want
-" to override them for loading Go files, which are defined to be UTF-8.
-let s:current_fileformats = ''
-let s:current_fileencodings = ''
-
-" define fileencodings to open as utf-8 encoding even if it's ascii.
-function! s:gofiletype_pre()
-  let s:current_fileformats = &g:fileformats
-  let s:current_fileencodings = &g:fileencodings
-  set fileencodings=utf-8 fileformats=unix
-  setlocal filetype=go
-endfunction
-
-" restore fileencodings as others
-function! s:gofiletype_post()
-  let &g:fileformats = s:current_fileformats
-  let &g:fileencodings = s:current_fileencodings
-endfunction
-
-au BufNewFile *.go setlocal filetype=go fileencoding=utf-8 fileformat=unix
-au BufRead *.go call s:gofiletype_pre()
-au BufReadPost *.go call s:gofiletype_post()
diff --git a/misc/vim/ftplugin/go.vim b/misc/vim/ftplugin/go.vim
deleted file mode 100644
index 532fb17..0000000
--- a/misc/vim/ftplugin/go.vim
+++ /dev/null
@@ -1,19 +0,0 @@
-" Copyright 2013 The Go Authors. All rights reserved.
-" Use of this source code is governed by a BSD-style
-" license that can be found in the LICENSE file.
-"
-" go.vim: Vim filetype plugin for Go.
-
-if exists("b:did_ftplugin")
-    finish
-endif
-let b:did_ftplugin = 1
-
-setlocal formatoptions-=t
-
-setlocal comments=s1:/*,mb:*,ex:*/,://
-setlocal commentstring=//\ %s
-
-let b:undo_ftplugin = "setl fo< com< cms<"
-
-" vim:ts=4:sw=4:et
diff --git a/misc/vim/ftplugin/go/fmt.vim b/misc/vim/ftplugin/go/fmt.vim
deleted file mode 100644
index 359545b..0000000
--- a/misc/vim/ftplugin/go/fmt.vim
+++ /dev/null
@@ -1,69 +0,0 @@
-" Copyright 2011 The Go Authors. All rights reserved.
-" Use of this source code is governed by a BSD-style
-" license that can be found in the LICENSE file.
-"
-" fmt.vim: Vim command to format Go files with gofmt.
-"
-" This filetype plugin add a new commands for go buffers:
-"
-"   :Fmt
-"
-"       Filter the current Go buffer through gofmt.
-"       It tries to preserve cursor position and avoids
-"       replacing the buffer with stderr output.
-"
-" Options:
-"
-"   g:go_fmt_commands [default=1]
-"
-"       Flag to indicate whether to enable the commands listed above.
-"
-"   g:gofmt_command [default="gofmt"]
-"
-"       Flag naming the gofmt executable to use.
-"
-if exists("b:did_ftplugin_go_fmt")
-    finish
-endif
-
-if !exists("g:go_fmt_commands")
-    let g:go_fmt_commands = 1
-endif
-
-if !exists("g:gofmt_command")
-    let g:gofmt_command = "gofmt"
-endif
-
-if g:go_fmt_commands
-    command! -buffer Fmt call s:GoFormat()
-endif
-
-function! s:GoFormat()
-    let view = winsaveview()
-    silent execute "%!" . g:gofmt_command
-    if v:shell_error
-        let errors = []
-        for line in getline(1, line('$'))
-            let tokens = matchlist(line, '^\(.\{-}\):\(\d\+\):\(\d\+\)\s*\(.*\)')
-            if !empty(tokens)
-                call add(errors, {"filename": @%,
-                                 \"lnum":     tokens[2],
-                                 \"col":      tokens[3],
-                                 \"text":     tokens[4]})
-            endif
-        endfor
-        if empty(errors)
-            % | " Couldn't detect gofmt error format, output errors
-        endif
-        undo
-        if !empty(errors)
-            call setqflist(errors, 'r')
-        endif
-        echohl Error | echomsg "Gofmt returned error" | echohl None
-    endif
-    call winrestview(view)
-endfunction
-
-let b:did_ftplugin_go_fmt = 1
-
-" vim:ts=4:sw=4:et
diff --git a/misc/vim/ftplugin/go/import.vim b/misc/vim/ftplugin/go/import.vim
deleted file mode 100644
index 91c8697..0000000
--- a/misc/vim/ftplugin/go/import.vim
+++ /dev/null
@@ -1,250 +0,0 @@
-" Copyright 2011 The Go Authors. All rights reserved.
-" Use of this source code is governed by a BSD-style
-" license that can be found in the LICENSE file.
-"
-" import.vim: Vim commands to import/drop Go packages.
-"
-" This filetype plugin adds three new commands for go buffers:
-"
-"   :Import {path}
-"
-"       Import ensures that the provided package {path} is imported
-"       in the current Go buffer, using proper style and ordering.
-"       If {path} is already being imported, an error will be
-"       displayed and the buffer will be untouched.
-"
-"   :ImportAs {localname} {path}
-"
-"       Same as Import, but uses a custom local name for the package.
-"
-"   :Drop {path}
-"
-"       Remove the import line for the provided package {path}, if
-"       present in the current Go buffer.  If {path} is not being
-"       imported, an error will be displayed and the buffer will be
-"       untouched.
-"
-" If you would like to add shortcuts, you can do so by doing the following:
-"
-"   Import fmt
-"   au Filetype go nnoremap <buffer> <LocalLeader>f :Import fmt<CR>
-"
-"   Drop fmt
-"   au Filetype go nnoremap <buffer> <LocalLeader>F :Drop fmt<CR>
-"
-"   Import the word under your cursor
-"   au Filetype go nnoremap <buffer> <LocalLeader>k
-"       \ :exe 'Import ' . expand('<cword>')<CR>
-"
-" The backslash '\' is the default maplocalleader, so it is possible that
-" your vim is set to use a different character (:help maplocalleader).
-"
-" Options:
-"
-"   g:go_import_commands [default=1]
-"
-"       Flag to indicate whether to enable the commands listed above.
-"
-if exists("b:did_ftplugin_go_import")
-    finish
-endif
-
-if !exists("g:go_import_commands")
-    let g:go_import_commands = 1
-endif
-
-if g:go_import_commands
-    command! -buffer -nargs=? -complete=customlist,go#complete#Package Drop call s:SwitchImport(0, '', <f-args>)
-    command! -buffer -nargs=1 -complete=customlist,go#complete#Package Import call s:SwitchImport(1, '', <f-args>)
-    command! -buffer -nargs=* -complete=customlist,go#complete#Package ImportAs call s:SwitchImport(1, <f-args>)
-endif
-
-function! s:SwitchImport(enabled, localname, path)
-    let view = winsaveview()
-    let path = a:path
-
-    " Quotes are not necessary, so remove them if provided.
-    if path[0] == '"'
-        let path = strpart(path, 1)
-    endif
-    if path[len(path)-1] == '"'
-        let path = strpart(path, 0, len(path) - 1)
-    endif
-    if path == ''
-        call s:Error('Import path not provided')
-        return
-    endif
-
-    " Extract any site prefix (e.g. github.com/).
-    " If other imports with the same prefix are grouped separately,
-    " we will add this new import with them.
-    " Only up to and including the first slash is used.
-    let siteprefix = matchstr(path, "^[^/]*/")
-
-    let qpath = '"' . path . '"'
-    if a:localname != ''
-        let qlocalpath = a:localname . ' ' . qpath
-    else
-        let qlocalpath = qpath
-    endif
-    let indentstr = 0
-    let packageline = -1 " Position of package name statement
-    let appendline = -1  " Position to introduce new import
-    let deleteline = -1  " Position of line with existing import
-    let linesdelta = 0   " Lines added/removed
-
-    " Find proper place to add/remove import.
-    let line = 0
-    while line <= line('$')
-        let linestr = getline(line)
-
-        if linestr =~# '^package\s'
-            let packageline = line
-            let appendline = line
-
-        elseif linestr =~# '^import\s\+('
-            let appendstr = qlocalpath
-            let indentstr = 1
-            let appendline = line
-            let firstblank = -1
-            let lastprefix = ""
-            while line <= line("$")
-                let line = line + 1
-                let linestr = getline(line)
-                let m = matchlist(getline(line), '^\()\|\(\s\+\)\(\S*\s*\)"\(.\+\)"\)')
-                if empty(m)
-                    if siteprefix == "" && a:enabled
-                        " must be in the first group
-                        break
-                    endif
-                    " record this position, but keep looking
-                    if firstblank < 0
-                        let firstblank = line
-                    endif
-                    continue
-                endif
-                if m[1] == ')'
-                    " if there's no match, add it to the first group
-                    if appendline < 0 && firstblank >= 0
-                        let appendline = firstblank
-                    endif
-                    break
-                endif
-                let lastprefix = matchstr(m[4], "^[^/]*/")
-                if a:localname != '' && m[3] != ''
-                    let qlocalpath = printf('%-' . (len(m[3])-1) . 's %s', a:localname, qpath)
-                endif
-                let appendstr = m[2] . qlocalpath
-                let indentstr = 0
-                if m[4] == path
-                    let appendline = -1
-                    let deleteline = line
-                    break
-                elseif m[4] < path
-                    " don't set candidate position if we have a site prefix,
-                    " we've passed a blank line, and this doesn't share the same
-                    " site prefix.
-                    if siteprefix == "" || firstblank < 0 || match(m[4], "^" . siteprefix) >= 0
-                        let appendline = line
-                    endif
-                elseif siteprefix != "" && match(m[4], "^" . siteprefix) >= 0
-                    " first entry of site group
-                    let appendline = line - 1
-                    break
-                endif
-            endwhile
-            break
-
-        elseif linestr =~# '^import '
-            if appendline == packageline
-                let appendstr = 'import ' . qlocalpath
-                let appendline = line - 1
-            endif
-            let m = matchlist(linestr, '^import\(\s\+\)\(\S*\s*\)"\(.\+\)"')
-            if !empty(m)
-                if m[3] == path
-                    let appendline = -1
-                    let deleteline = line
-                    break
-                endif
-                if m[3] < path
-                    let appendline = line
-                endif
-                if a:localname != '' && m[2] != ''
-                    let qlocalpath = printf("%s %" . len(m[2])-1 . "s", a:localname, qpath)
-                endif
-                let appendstr = 'import' . m[1] . qlocalpath
-            endif
-
-        elseif linestr =~# '^\(var\|const\|type\|func\)\>'
-            break
-
-        endif
-        let line = line + 1
-    endwhile
-
-    " Append or remove the package import, as requested.
-    if a:enabled
-        if deleteline != -1
-            call s:Error(qpath . ' already being imported')
-        elseif appendline == -1
-            call s:Error('No package line found')
-        else
-            if appendline == packageline
-                call append(appendline + 0, '')
-                call append(appendline + 1, 'import (')
-                call append(appendline + 2, ')')
-                let appendline += 2
-                let linesdelta += 3
-                let appendstr = qlocalpath
-                let indentstr = 1
-            endif
-            call append(appendline, appendstr)
-            execute appendline + 1
-            if indentstr
-                execute 'normal >>'
-            endif
-            let linesdelta += 1
-        endif
-    else
-        if deleteline == -1
-            call s:Error(qpath . ' not being imported')
-        else
-            execute deleteline . 'd'
-            let linesdelta -= 1
-
-            if getline(deleteline-1) =~# '^import\s\+(' && getline(deleteline) =~# '^)'
-                " Delete empty import block
-                let deleteline -= 1
-                execute deleteline . "d"
-                execute deleteline . "d"
-                let linesdelta -= 2
-            endif
-
-            if getline(deleteline) == '' && getline(deleteline - 1) == ''
-                " Delete spacing for removed line too.
-                execute deleteline . "d"
-                let linesdelta -= 1
-            endif
-        endif
-    endif
-
-    " Adjust view for any changes.
-    let view.lnum += linesdelta
-    let view.topline += linesdelta
-    if view.topline < 0
-        let view.topline = 0
-    endif
-
-    " Put buffer back where it was.
-    call winrestview(view)
-
-endfunction
-
-function! s:Error(s)
-    echohl Error | echo a:s | echohl None
-endfunction
-
-let b:did_ftplugin_go_import = 1
-
-" vim:ts=4:sw=4:et
diff --git a/misc/vim/ftplugin/go/test.sh b/misc/vim/ftplugin/go/test.sh
deleted file mode 100755
index d8a5b89..0000000
--- a/misc/vim/ftplugin/go/test.sh
+++ /dev/null
@@ -1,78 +0,0 @@
-#!/bin/bash -e
-#
-# Copyright 2012 The Go Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style
-# license that can be found in the LICENSE file.
-#
-# Tests for import.vim.
-
-cd $(dirname $0)
-
-cat > base.go <<EOF
-package test
-
-import (
-	"bytes"
-	"io"
-	"net"
-
-	"mycorp/foo"
-)
-EOF
-
-fail=0
-
-# usage: test_one command pattern
-# Pattern is a PCRE expression that will match across lines.
-test_one() {
-  echo 2>&1 -n "$1: "
-  vim -e -s -u /dev/null -U /dev/null --noplugin -c "source import.vim" \
-    -c "$1" -c 'wq! test.go' base.go
-  # ensure blank lines are treated correctly
-  if ! gofmt test.go | cmp test.go -; then
-    echo 2>&1 "gofmt conflict"
-    gofmt test.go | diff -u test.go - | sed "s/^/	/" 2>&1
-    fail=1
-    return
-  fi
-  if ! [[ $(cat test.go) =~ $2 ]]; then
-    echo 2>&1 "$2 did not match"
-    cat test.go | sed "s/^/	/" 2>&1
-    fail=1
-    return
-  fi
-  echo 2>&1 "ok"
-}
-
-# Tests for Import
-
-test_one "Import baz" '"baz".*"bytes"'
-test_one "Import io/ioutil" '"io".*"io/ioutil".*"net"'
-test_one "Import myc" '"io".*"myc".*"net"'  # prefix of a site prefix
-test_one "Import nat" '"io".*"nat".*"net"'
-test_one "Import net/http" '"net".*"net/http".*"mycorp/foo"'
-test_one "Import zoo" '"net".*"zoo".*"mycorp/foo"'
-test_one "Import mycorp/bar" '"net".*"mycorp/bar".*"mycorp/foo"'
-test_one "Import mycorp/goo" '"net".*"mycorp/foo".*"mycorp/goo"'
-
-# Tests for Drop
-
-cat > base.go <<EOF
-package test
-
-import (
-	"foo"
-
-	"something"
-	"zoo"
-)
-EOF
-
-test_one "Drop something" '\([^"]*"foo"[^"]*"zoo"[^"]*\)'
-
-rm -f base.go test.go
-if [ $fail -gt 0 ]; then
-  echo 2>&1 "FAIL"
-  exit 1
-fi
-echo 2>&1 "PASS"
diff --git a/misc/vim/indent/go.vim b/misc/vim/indent/go.vim
deleted file mode 100644
index e3d6e84..0000000
--- a/misc/vim/indent/go.vim
+++ /dev/null
@@ -1,77 +0,0 @@
-" Copyright 2011 The Go Authors. All rights reserved.
-" Use of this source code is governed by a BSD-style
-" license that can be found in the LICENSE file.
-"
-" indent/go.vim: Vim indent file for Go.
-"
-" TODO:
-" - function invocations split across lines
-" - general line splits (line ends in an operator)
-
-if exists("b:did_indent")
-    finish
-endif
-let b:did_indent = 1
-
-" C indentation is too far off useful, mainly due to Go's := operator.
-" Let's just define our own.
-setlocal nolisp
-setlocal autoindent
-setlocal indentexpr=GoIndent(v:lnum)
-setlocal indentkeys+=<:>,0=},0=)
-
-if exists("*GoIndent")
-  finish
-endif
-
-" The shiftwidth() function is relatively new.
-" Don't require it to exist.
-if exists('*shiftwidth')
-  func s:sw()
-    return shiftwidth()
-  endfunc
-else
-  func s:sw()
-    return &shiftwidth
-  endfunc
-endif
-
-function! GoIndent(lnum)
-  let prevlnum = prevnonblank(a:lnum-1)
-  if prevlnum == 0
-    " top of file
-    return 0
-  endif
-
-  " grab the previous and current line, stripping comments.
-  let prevl = substitute(getline(prevlnum), '//.*$', '', '')
-  let thisl = substitute(getline(a:lnum), '//.*$', '', '')
-  let previ = indent(prevlnum)
-
-  let ind = previ
-
-  if prevl =~ '[({]\s*$'
-    " previous line opened a block
-    let ind += s:sw()
-  endif
-  if prevl =~# '^\s*\(case .*\|default\):$'
-    " previous line is part of a switch statement
-    let ind += s:sw()
-  endif
-  " TODO: handle if the previous line is a label.
-
-  if thisl =~ '^\s*[)}]'
-    " this line closed a block
-    let ind -= s:sw()
-  endif
-
-  " Colons are tricky.
-  " We want to outdent if it's part of a switch ("case foo:" or "default:").
-  " We ignore trying to deal with jump labels because (a) they're rare, and
-  " (b) they're hard to disambiguate from a composite literal key.
-  if thisl =~# '^\s*\(case .*\|default\):$'
-    let ind -= s:sw()
-  endif
-
-  return ind
-endfunction
diff --git a/misc/vim/plugin/godoc.vim b/misc/vim/plugin/godoc.vim
deleted file mode 100644
index a145d31..0000000
--- a/misc/vim/plugin/godoc.vim
+++ /dev/null
@@ -1,130 +0,0 @@
-" Copyright 2011 The Go Authors. All rights reserved.
-" Use of this source code is governed by a BSD-style
-" license that can be found in the LICENSE file.
-"
-" godoc.vim: Vim command to see godoc.
-"
-"
-" Commands:
-"
-"   :Godoc
-"
-"       Open the relevant Godoc for either the word[s] passed to the command or
-"       the, by default, the word under the cursor.
-"
-" Options:
-"
-"   g:go_godoc_commands [default=1]
-"
-"       Flag to indicate whether to enable the commands listed above.
-
-if exists("g:loaded_godoc")
-  finish
-endif
-let g:loaded_godoc = 1
-
-let s:buf_nr = -1
-let s:last_word = ''
-
-if !exists('g:go_godoc_commands')
-  let g:go_godoc_commands = 1
-endif
-
-if g:go_godoc_commands
-  command! -nargs=* -range -complete=customlist,go#complete#Package Godoc :call s:Godoc(<f-args>)
-endif
-
-nnoremap <silent> <Plug>(godoc-keyword) :<C-u>call <SID>Godoc('')<CR>
-
-function! s:GodocView()
-  if !bufexists(s:buf_nr)
-    leftabove new
-    file `="[Godoc]"`
-    let s:buf_nr = bufnr('%')
-  elseif bufwinnr(s:buf_nr) == -1
-    leftabove split
-    execute s:buf_nr . 'buffer'
-    delete _
-  elseif bufwinnr(s:buf_nr) != bufwinnr('%')
-    execute bufwinnr(s:buf_nr) . 'wincmd w'
-  endif
-
-  setlocal filetype=godoc
-  setlocal bufhidden=delete
-  setlocal buftype=nofile
-  setlocal noswapfile
-  setlocal nobuflisted
-  setlocal modifiable
-  setlocal nocursorline
-  setlocal nocursorcolumn
-  setlocal iskeyword+=:
-  setlocal iskeyword-=-
-
-  nnoremap <buffer> <silent> K :Godoc<cr>
-
-  au BufHidden <buffer> call let <SID>buf_nr = -1
-endfunction
-
-function! s:GodocWord(word)
-  if !executable('godoc')
-    echohl WarningMsg
-    echo "godoc command not found."
-    echo "  install with: go get code.google.com/p/go.tools/cmd/godoc"
-    echohl None
-    return 0
-  endif
-  let word = a:word
-  silent! let content = system('godoc ' . word)
-  if v:shell_error || !len(content)
-    if len(s:last_word)
-      silent! let content = system('godoc ' . s:last_word.'/'.word)
-      if v:shell_error || !len(content)
-        echo 'No documentation found for "' . word . '".'
-        return 0
-      endif
-      let word = s:last_word.'/'.word
-    else
-      echo 'No documentation found for "' . word . '".'
-      return 0
-    endif
-  endif
-  let s:last_word = word
-  silent! call s:GodocView()
-  setlocal modifiable
-  silent! %d _
-  silent! put! =content
-  silent! normal gg
-  setlocal nomodifiable
-  setfiletype godoc
-  return 1
-endfunction
-
-function! s:Godoc(...)
-  if !len(a:000)
-    let oldiskeyword = &iskeyword
-    setlocal iskeyword+=.
-    let word = expand('<cword>')
-    let &iskeyword = oldiskeyword
-    let word = substitute(word, '[^a-zA-Z0-9\\/._~-]', '', 'g')
-    let words = split(word, '\.\ze[^./]\+$')
-  else
-    let words = a:000
-  endif
-  if !len(words)
-    return
-  endif
-  if s:GodocWord(words[0])
-    if len(words) > 1
-      if search('^\%(const\|var\|type\|\s\+\) ' . words[1] . '\s\+=\s')
-        return
-      endif
-      if search('^func ' . words[1] . '(')
-        silent! normal zt
-        return
-      endif
-      echo 'No documentation found for "' . words[1] . '".'
-    endif
-  endif
-endfunction
-
-" vim:ts=4:sw=4:et
diff --git a/misc/vim/readme.txt b/misc/vim/readme.txt
deleted file mode 100644
index 9a9e228..0000000
--- a/misc/vim/readme.txt
+++ /dev/null
@@ -1,103 +0,0 @@
-Vim plugins for Go (http://golang.org)
-======================================
-
-To use all the Vim plugins, add these lines to your $HOME/.vimrc.
-
-  " Some Linux distributions set filetype in /etc/vimrc.
-  " Clear filetype flags before changing runtimepath to force Vim to reload them.
-  if exists("g:did_load_filetypes")
-    filetype off
-    filetype plugin indent off
-  endif
-  set runtimepath+=$GOROOT/misc/vim " replace $GOROOT with the output of: go env GOROOT
-  filetype plugin indent on
-  syntax on
-
-If you want to select fewer plugins, use the instructions in the rest of
-this file.
-
-A popular configuration is to gofmt Go source files when they are saved.
-To do that, add this line to the end of your $HOME/.vimrc.
-
-  autocmd FileType go autocmd BufWritePre <buffer> Fmt
-
-
-Vim syntax highlighting
------------------------
-
-To install automatic syntax highlighting for GO programs:
-
-  1. Copy or link the filetype detection script to the ftdetect directory
-     underneath your vim runtime directory (normally $HOME/.vim/ftdetect)
-  2. Copy or link syntax/go.vim to the syntax directory underneath your vim
-     runtime directory (normally $HOME/.vim/syntax). Linking this file rather
-     than just copying it will ensure any changes are automatically reflected
-     in your syntax highlighting.
-  3. Add the following line to your .vimrc file (normally $HOME/.vimrc):
-
-     syntax on
-
-In a typical unix environment you might accomplish this using the following
-commands:
-
-  mkdir -p $HOME/.vim/ftdetect
-  mkdir -p $HOME/.vim/syntax
-  mkdir -p $HOME/.vim/autoload/go
-  ln -s $GOROOT/misc/vim/ftdetect/gofiletype.vim $HOME/.vim/ftdetect/
-  ln -s $GOROOT/misc/vim/syntax/go.vim $HOME/.vim/syntax
-  ln -s $GOROOT/misc/vim/autoload/go/complete.vim $HOME/.vim/autoload/go
-  echo "syntax on" >> $HOME/.vimrc
-
-
-Vim filetype plugins
---------------------
-
-To install one of the available filetype plugins:
-
-  1. Same as 1 above.
-  2. Copy or link ftplugin/go.vim to the ftplugin directory underneath your vim
-     runtime directory (normally $HOME/.vim/ftplugin). Copy or link one or more
-     additional plugins from ftplugin/go/*.vim to the Go-specific subdirectory
-     in the same place ($HOME/.vim/ftplugin/go/*.vim).
-  3. Add the following line to your .vimrc file (normally $HOME/.vimrc):
-
-     filetype plugin on
-
-
-Vim indentation plugin
-----------------------
-
-To install automatic indentation:
-
-  1. Same as 1 above.
-  2. Copy or link indent/go.vim to the indent directory underneath your vim
-     runtime directory (normally $HOME/.vim/indent).
-  3. Add the following line to your .vimrc file (normally $HOME/.vimrc):
-
-     filetype indent on
-
-
-Vim compiler plugin
--------------------
-
-To install the compiler plugin:
-
-  1. Same as 1 above.
-  2. Copy or link compiler/go.vim to the compiler directory underneath your vim
-     runtime directory (normally $HOME/.vim/compiler).
-  3. Activate the compiler plugin with ":compiler go". To always enable the
-     compiler plugin in Go source files add an autocommand to your .vimrc file
-     (normally $HOME/.vimrc):
-
-     autocmd FileType go compiler go
-
-
-Godoc plugin
-------------
-
-To install godoc plugin:
-
-  1. Same as 1 above.
-  2. Copy or link plugin/godoc.vim to $HOME/.vim/plugin/godoc,
-     syntax/godoc.vim to $HOME/.vim/syntax/godoc.vim,
-     and autoload/go/complete.vim to $HOME/.vim/autoload/go/complete.vim.
diff --git a/misc/vim/syntax/go.vim b/misc/vim/syntax/go.vim
deleted file mode 100644
index 1ce6cb2..0000000
--- a/misc/vim/syntax/go.vim
+++ /dev/null
@@ -1,207 +0,0 @@
-" Copyright 2009 The Go Authors. All rights reserved.
-" Use of this source code is governed by a BSD-style
-" license that can be found in the LICENSE file.
-"
-" go.vim: Vim syntax file for Go.
-"
-" Options:
-"   There are some options for customizing the highlighting; the recommended
-"   settings are the default values, but you can write:
-"     let OPTION_NAME = 0
-"   in your ~/.vimrc file to disable particular options. You can also write:
-"     let OPTION_NAME = 1
-"   to enable particular options. At present, all options default to on.
-"
-"   - go_highlight_array_whitespace_error
-"     Highlights white space after "[]".
-"   - go_highlight_chan_whitespace_error
-"     Highlights white space around the communications operator that don't follow
-"     the standard style.
-"   - go_highlight_extra_types
-"     Highlights commonly used library types (io.Reader, etc.).
-"   - go_highlight_space_tab_error
-"     Highlights instances of tabs following spaces.
-"   - go_highlight_trailing_whitespace_error
-"     Highlights trailing white space.
-
-" Quit when a (custom) syntax file was already loaded
-if exists("b:current_syntax")
-  finish
-endif
-
-if !exists("go_highlight_array_whitespace_error")
-  let go_highlight_array_whitespace_error = 1
-endif
-if !exists("go_highlight_chan_whitespace_error")
-  let go_highlight_chan_whitespace_error = 1
-endif
-if !exists("go_highlight_extra_types")
-  let go_highlight_extra_types = 1
-endif
-if !exists("go_highlight_space_tab_error")
-  let go_highlight_space_tab_error = 1
-endif
-if !exists("go_highlight_trailing_whitespace_error")
-  let go_highlight_trailing_whitespace_error = 1
-endif
-
-syn case match
-
-syn keyword     goDirective         package import
-syn keyword     goDeclaration       var const type
-syn keyword     goDeclType          struct interface
-
-hi def link     goDirective         Statement
-hi def link     goDeclaration       Keyword
-hi def link     goDeclType          Keyword
-
-" Keywords within functions
-syn keyword     goStatement         defer go goto return break continue fallthrough
-syn keyword     goConditional       if else switch select
-syn keyword     goLabel             case default
-syn keyword     goRepeat            for range
-
-hi def link     goStatement         Statement
-hi def link     goConditional       Conditional
-hi def link     goLabel             Label
-hi def link     goRepeat            Repeat
-
-" Predefined types
-syn keyword     goType              chan map bool string error
-syn keyword     goSignedInts        int int8 int16 int32 int64 rune
-syn keyword     goUnsignedInts      byte uint uint8 uint16 uint32 uint64 uintptr
-syn keyword     goFloats            float32 float64
-syn keyword     goComplexes         complex64 complex128
-
-hi def link     goType              Type
-hi def link     goSignedInts        Type
-hi def link     goUnsignedInts      Type
-hi def link     goFloats            Type
-hi def link     goComplexes         Type
-
-" Treat func specially: it's a declaration at the start of a line, but a type
-" elsewhere. Order matters here.
-syn match       goType              /\<func\>/
-syn match       goDeclaration       /^func\>/
-
-" Predefined functions and values
-syn keyword     goBuiltins          append cap close complex copy delete imag len
-syn keyword     goBuiltins          make new panic print println real recover
-syn keyword     goConstants         iota true false nil
-
-hi def link     goBuiltins          Keyword
-hi def link     goConstants         Keyword
-
-" Comments; their contents
-syn keyword     goTodo              contained TODO FIXME XXX BUG
-syn cluster     goCommentGroup      contains=goTodo
-syn region      goComment           start="/\*" end="\*/" contains=@goCommentGroup, at Spell
-syn region      goComment           start="//" end="$" contains=@goCommentGroup, at Spell
-
-hi def link     goComment           Comment
-hi def link     goTodo              Todo
-
-" Go escapes
-syn match       goEscapeOctal       display contained "\\[0-7]\{3}"
-syn match       goEscapeC           display contained +\\[abfnrtv\\'"]+
-syn match       goEscapeX           display contained "\\x\x\{2}"
-syn match       goEscapeU           display contained "\\u\x\{4}"
-syn match       goEscapeBigU        display contained "\\U\x\{8}"
-syn match       goEscapeError       display contained +\\[^0-7xuUabfnrtv\\'"]+
-
-hi def link     goEscapeOctal       goSpecialString
-hi def link     goEscapeC           goSpecialString
-hi def link     goEscapeX           goSpecialString
-hi def link     goEscapeU           goSpecialString
-hi def link     goEscapeBigU        goSpecialString
-hi def link     goSpecialString     Special
-hi def link     goEscapeError       Error
-
-" Strings and their contents
-syn cluster     goStringGroup       contains=goEscapeOctal,goEscapeC,goEscapeX,goEscapeU,goEscapeBigU,goEscapeError
-syn region      goString            start=+"+ skip=+\\\\\|\\"+ end=+"+ contains=@goStringGroup
-syn region      goRawString         start=+`+ end=+`+
-
-hi def link     goString            String
-hi def link     goRawString         String
-
-" Characters; their contents
-syn cluster     goCharacterGroup    contains=goEscapeOctal,goEscapeC,goEscapeX,goEscapeU,goEscapeBigU
-syn region      goCharacter         start=+'+ skip=+\\\\\|\\'+ end=+'+ contains=@goCharacterGroup
-
-hi def link     goCharacter         Character
-
-" Regions
-syn region      goBlock             start="{" end="}" transparent fold
-syn region      goParen             start='(' end=')' transparent
-
-" Integers
-syn match       goDecimalInt        "\<\d\+\([Ee]\d\+\)\?\>"
-syn match       goHexadecimalInt    "\<0x\x\+\>"
-syn match       goOctalInt          "\<0\o\+\>"
-syn match       goOctalError        "\<0\o*[89]\d*\>"
-
-hi def link     goDecimalInt        Integer
-hi def link     goHexadecimalInt    Integer
-hi def link     goOctalInt          Integer
-hi def link     Integer             Number
-
-" Floating point
-syn match       goFloat             "\<\d\+\.\d*\([Ee][-+]\d\+\)\?\>"
-syn match       goFloat             "\<\.\d\+\([Ee][-+]\d\+\)\?\>"
-syn match       goFloat             "\<\d\+[Ee][-+]\d\+\>"
-
-hi def link     goFloat             Float
-
-" Imaginary literals
-syn match       goImaginary         "\<\d\+i\>"
-syn match       goImaginary         "\<\d\+\.\d*\([Ee][-+]\d\+\)\?i\>"
-syn match       goImaginary         "\<\.\d\+\([Ee][-+]\d\+\)\?i\>"
-syn match       goImaginary         "\<\d\+[Ee][-+]\d\+i\>"
-
-hi def link     goImaginary         Number
-
-" Spaces after "[]"
-if go_highlight_array_whitespace_error != 0
-  syn match goSpaceError display "\(\[\]\)\@<=\s\+"
-endif
-
-" Spacing errors around the 'chan' keyword
-if go_highlight_chan_whitespace_error != 0
-  " receive-only annotation on chan type
-  syn match goSpaceError display "\(<-\)\@<=\s\+\(chan\>\)\@="
-  " send-only annotation on chan type
-  syn match goSpaceError display "\(\<chan\)\@<=\s\+\(<-\)\@="
-  " value-ignoring receives in a few contexts
-  syn match goSpaceError display "\(\(^\|[={(,;]\)\s*<-\)\@<=\s\+"
-endif
-
-" Extra types commonly seen
-if go_highlight_extra_types != 0
-  syn match goExtraType /\<bytes\.\(Buffer\)\>/
-  syn match goExtraType /\<io\.\(Reader\|Writer\|ReadWriter\|ReadWriteCloser\)\>/
-  syn match goExtraType /\<reflect\.\(Kind\|Type\|Value\)\>/
-  syn match goExtraType /\<unsafe\.Pointer\>/
-endif
-
-" Space-tab error
-if go_highlight_space_tab_error != 0
-  syn match goSpaceError display " \+\t"me=e-1
-endif
-
-" Trailing white space error
-if go_highlight_trailing_whitespace_error != 0
-  syn match goSpaceError display excludenl "\s\+$"
-endif
-
-hi def link     goExtraType         Type
-hi def link     goSpaceError        Error
-
-" Search backwards for a global declaration to start processing the syntax.
-"syn sync match goSync grouphere NONE /^\(const\|var\|type\|func\)\>/
-
-" There's a bug in the implementation of grouphere. For now, use the
-" following as a more expensive/less precise workaround.
-syn sync minlines=500
-
-let b:current_syntax = "go"
diff --git a/misc/vim/syntax/godoc.vim b/misc/vim/syntax/godoc.vim
deleted file mode 100644
index bd4443f..0000000
--- a/misc/vim/syntax/godoc.vim
+++ /dev/null
@@ -1,20 +0,0 @@
-" Copyright 2011 The Go Authors. All rights reserved.
-" Use of this source code is governed by a BSD-style
-" license that can be found in the LICENSE file.
-
-if exists("b:current_syntax")
-  finish
-endif
-
-syn case match
-syn match  godocTitle "^\([A-Z][A-Z ]*\)$"
-
-command -nargs=+ HiLink hi def link <args>
-
-HiLink godocTitle Title
-
-delcommand HiLink
-
-let b:current_syntax = "godoc"
-
-" vim:ts=4 sts=2 sw=2:
diff --git a/misc/xcode/3/README b/misc/xcode/3/README
deleted file mode 100644
index 69f371c..0000000
--- a/misc/xcode/3/README
+++ /dev/null
@@ -1,3 +0,0 @@
-This directory contains files for Go syntax highlighting in Xcode 3.x.
-See the comments in go.pbfilespec and go.xclangspec for installation
-instructions.
diff --git a/misc/xcode/3/go.pbfilespec b/misc/xcode/3/go.pbfilespec
deleted file mode 100644
index 1034778..0000000
--- a/misc/xcode/3/go.pbfilespec
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
-	Copyright 2009 The Go Authors. All rights reserved.
-	Use of this source code is governed by a BSD-style
-	license that can be found in the LICENSE file.
-
-	go.pbfilespec
-	Go source file spec for Xcode 3
-
-	There is not much documentation available regarding the format
-	of .pbfilespec files. As a starting point, see for instance the
-	outdated documentation at:
-	http://maxao.free.fr/xcode-plugin-interface/specifications.html
-	and the files in:
-	/Developer/Library/PrivateFrameworks/XcodeEdit.framework/Versions/A/Resources/
-
-	Place this file in directory:
-	~/Library/Application Support/Developer/Shared/Xcode/Specifications/
-*/
-
-(
-	{
-		Identifier = sourcecode.go;
-		BasedOn = sourcecode;
-		Name = "Go Files";
-		Extensions = ("go");
-		MIMETypes = ("text/go");
-		Language = "xcode.lang.go";
-		IsTextFile = YES;
-		IsSourceFile = YES;
-	}
-)
diff --git a/misc/xcode/3/go.xclangspec b/misc/xcode/3/go.xclangspec
deleted file mode 100644
index 4a8c94d..0000000
--- a/misc/xcode/3/go.xclangspec
+++ /dev/null
@@ -1,293 +0,0 @@
-/*
-	Copyright 2009 The Go Authors. All rights reserved.
-	Use of this source code is governed by a BSD-style
-	license that can be found in the LICENSE file.
-
-	Go.xclangspec
-	Go language specification for Xcode 3
-
-	This is a preliminary version that supports basic syntax high-lighting
-	(such as keywords, literals, and comments) and an attempt to provide
-	some structure information (incomplete).
-
-	There is not much documentation available regarding the format
-	of .xclangspec files. As a starting point, see for instance the
-	outdated documentation at:
-	http://maxao.free.fr/xcode-plugin-interface/specifications.html
-	and the files in:
-	/Developer/Library/PrivateFrameworks/XcodeEdit.framework/Versions/A/Resources/
-
-	Place this file in directory:
-	~/Library/Application Support/Developer/Shared/Xcode/Specifications/
-*/
-
-(
-
-// ----------------------------------------------------------------------------
-// Keywords
-
-// TODO How do we get general Unicode identifiers?
-
-	{
-		Identifier = "xcode.lang.go.identifier";
-		Syntax = {
-			StartChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_";
-			Chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_";
-			Words = (
-				"break",
-				"case",
-				"chan",
-				"const",
-				"continue",
-
-				"default",
-				"defer",
-				"else",
-				"fallthrough",
-				"for",
-
-				"func",
-				"go",
-				"goto",
-				"if",
-				"import",
-
-				"interface",
-				"map",
-				"package",
-				"range",
-				"return",
-
-				"select",
-				"struct",
-				"switch",
-				"type",
-				"var",
-			);
-			Type = "xcode.syntax.keyword";
-			AltType = "xcode.syntax.identifier";  // non-keywords are identifiers
-		};
-	},
-
-// TODO decide what should go here, if anything
-	{
-		Identifier = "xcode.lang.go.interestingOperators";
-		Syntax = {
-			Words = (
-				"...",
-				".",
-				"*",
-				",",
-				":",
- 			);
-			Type = "xcode.syntax.plain";
-		};
-	},
-
-	{
-		Identifier = "xcode.lang.go.rawstring";
-		Syntax = {
-			Start = "`";
-			End = "`";
-			Type = "xcode.syntax.string";
-		};
-	},
-
-// ----------------------------------------------------------------------------
-// Syntax Coloring
-
-	{
-		Identifier = "xcode.lang.go";
-		Description = "Go Coloring";
-		BasedOn = "xcode.lang.simpleColoring";
-		IncludeInMenu = YES;
-		Name = "Go";
-		Syntax = {
-			Tokenizer = "xcode.lang.go.lexer.toplevel";
-			IncludeRules = (
-				"xcode.lang.go.block",
-				"xcode.lang.go.bracketexpr",
-				"xcode.lang.go.parenexpr",
-			);
-			Type = "xcode.syntax.plain";
-		};
-	},
-
-	// The following rule returns tokens to the other rules
-	{
-		Identifier = "xcode.lang.go.lexer";
-		Syntax = {
-			IncludeRules = (
-				"xcode.lang.go.comment",
-				"xcode.lang.go.comment.singleline",
-				"xcode.lang.string",
-				"xcode.lang.character",
-				"xcode.lang.go.rawstring",
-				"xcode.lang.go.identifier",
-				"xcode.lang.number",
-				"xcode.lang.go.interestingOperators",
-			);
-		};
-	},
-
-	{
-		Identifier = "xcode.lang.go.lexer.toplevel";
-		Syntax = {
-			IncludeRules = (
-				"xcode.lang.go.comment",
-				"xcode.lang.go.comment.singleline",
-				"xcode.lang.string",
-				"xcode.lang.character",
-				"xcode.lang.go.rawstring",
-				"xcode.lang.go.type.declaration",
-				"xcode.lang.go.method.declaration",
-				"xcode.lang.go.function.declaration",
-				"xcode.lang.go.identifier",
-				"xcode.lang.number",
-			);
-		};
-	},
-
-	{
-		Identifier = "xcode.lang.go.method.declaration";
-		Syntax = {
-			Tokenizer = "xcode.lang.go.lexer";
-			Rules = (
-				"func",
-				"xcode.lang.go.parenexpr",
-				"xcode.lang.go.identifier",
-				"xcode.lang.go.parenexpr",
-			);
-			Type = "xcode.syntax.declaration.method";
-		};
-	},
-
-	{
-		Identifier = "xcode.lang.go.type.declaration";
-		Syntax = {
-			Tokenizer = "xcode.lang.go.lexer";
-			Rules = (
-				"type",
-				"xcode.lang.go.identifier",
-			);
-			Type = "xcode.syntax.typedef";
-		};
-	},
-
-	{
-		Identifier = "xcode.lang.go.function.declaration";
-		Syntax = {
-			Tokenizer = "xcode.lang.go.lexer";
-			Rules = (
-				"func",
-				"xcode.lang.go.identifier",
-				"xcode.lang.go.parenexpr",
-			);
-			Type = "xcode.syntax.declaration.function";
-		};
-	},
-
-// ----------------------------------------------------------------------------
-// Blocks
-
-	{
-		Identifier = "xcode.lang.go.block";
-		Syntax = {
-			Tokenizer = "xcode.lang.go.lexer";
-			Start = "{";
-			End = "}";
-			Foldable = YES;
-			Recursive = YES;
-			IncludeRules = (
-				"xcode.lang.go.bracketexpr",
-				"xcode.lang.go.parenexpr",
-			);
-		};
-	},
-
-	{
-		Identifier = "xcode.lang.go.parenexpr";
-		Syntax = {
-			Tokenizer = "xcode.lang.go.lexer";
-			Start = "(";
-			End = ")";
-			Recursive = YES;
-			IncludeRules = (
-				"xcode.lang.go.bracketexpr",
-				"xcode.lang.go.block",
-			);
-		};
-	},
-
-	{
-		Identifier = "xcode.lang.go.bracketexpr";
-		Syntax = {
-			Tokenizer = "xcode.lang.go.lexer";
-			Start = "[";
-			End = "]";
-			Recursive = YES;
-			IncludeRules = (
-				"xcode.lang.go.parenexpr",
-			);
-		};
-	},
-
-	{
-		Identifier = "xcode.lang.go.comment";
-		Syntax = {
-			Start = "/*";
-			End = "*/";
-			Foldable = YES;
-			IncludeRules = (
-				"xcode.lang.url",
-				"xcode.lang.url.mail",
-				"xcode.lang.comment.mark",
-			);
-			Type = "xcode.syntax.comment";
-		};
-	},
-
-	{
-		Identifier = "xcode.lang.go.comment.singleline";
-		Syntax = {
-			Start = "//";
-			End = "\n";
-			IncludeRules = (
-				"xcode.lang.url",
-				"xcode.lang.url.mail",
-				"xcode.lang.comment.mark",
-			);
-			Type = "xcode.syntax.comment";
-		};
-	},
-
-	// This rule recognizes special comments markers and adds them
-	// to the list of file markers at the top of the editor window.
-	// This overrides the markers specified in
-	// /Developer/Library/PrivateFrameworks/XcodeEdit.framework/Versions/A/Resources/BaseSupport.xclangspec
-	// and appears to apply them to all languages. Thus, for now
-	// "inherit" the existing markers here for backward-compatibility.
-	{
-		Identifier = "xcode.lang.comment.mark";
-		Syntax = {
-			StartChars = "BMTF!?";
-			Match = (
-				// Go-specific markers
-				"^\(BUG.*$\)$",			// include "BUG" in the markers list
-				"^\(TODO.*$\)$",		// include "TODO" in the markers list
-				// inherited markers
-				"^MARK:[ \t]+\(.*\)$",
-				"^\(TODO:[ \t]+.*\)$",		// include "TODO: " in the markers list
-				"^\(FIXME:[ \t]+.*\)$",		// include "FIXME: " in the markers list
-				"^\(!!!:.*\)$",			// include "!!!:" in the markers list
-				"^\(\\?\\?\\?:.*\)$"		// include "???:" in the markers list
-			);
-			// This is the order of captures. All of the match strings above need the same order.
-			CaptureTypes = (
-				"xcode.syntax.mark"
-			);
-			Type = "xcode.syntax.comment";
-		};
-	},
-
-)
diff --git a/misc/xcode/4/README b/misc/xcode/4/README
deleted file mode 100644
index 09576d6..0000000
--- a/misc/xcode/4/README
+++ /dev/null
@@ -1,2 +0,0 @@
-This directory contains files for Go syntax highlighting in Xcode 4.x.
-For installation, read, edit, and run go4xcode.sh .
\ No newline at end of file
diff --git a/misc/xcode/4/go.xclangspec b/misc/xcode/4/go.xclangspec
deleted file mode 100644
index 96edc80..0000000
--- a/misc/xcode/4/go.xclangspec
+++ /dev/null
@@ -1,290 +0,0 @@
-/*
-	Copyright 2012 The Go Authors. All rights reserved.
-	Use of this source code is governed by a BSD-style
-	license that can be found in the LICENSE file.
-
-	go.xclangspec
-	Go language specification for Xcode 4.x.
-
-	This is a preliminary version that supports basic syntax coloring
-	(such as keywords, literals, and comments) and an attempt to provide
-	some structure information (incomplete).
-
-	There is not much documentation available regarding the format
-	of .xclangspec files. As a starting point, see for instance the
-	outdated documentation at:
-
-		http://maxao.free.fr/xcode-plugin-interface/specifications.html
-
-*/
-
-(
-
-// ----------------------------------------------------------------------------
-// Keywords
-
-// TODO How do we get general Unicode identifiers?
-
-	{
-		Identifier = "xcode.lang.go.identifier";
-		Syntax = {
-			StartChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_";
-			Chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_";
-			Words = (
-				"break",
-				"case",
-				"chan",
-				"const",
-				"continue",
-
-				"default",
-				"defer",
-				"else",
-				"fallthrough",
-				"for",
-
-				"func",
-				"go",
-				"goto",
-				"if",
-				"import",
-
-				"interface",
-				"map",
-				"package",
-				"range",
-				"return",
-
-				"select",
-				"struct",
-				"switch",
-				"type",
-				"var",
-			);
-			Type = "xcode.syntax.keyword";
-			AltType = "xcode.syntax.identifier";  // non-keywords are identifiers
-		};
-	},
-
-// TODO decide what should go here, if anything
-	{
-		Identifier = "xcode.lang.go.interestingOperators";
-		Syntax = {
-			Words = (
-				"...",
-				".",
-				"*",
-				",",
-				":",
- 			);
-			Type = "xcode.syntax.plain";
-		};
-	},
-
-	{
-		Identifier = "xcode.lang.go.rawstring";
-		Syntax = {
-			Start = "`";
-			End = "`";
-			Type = "xcode.syntax.string";
-		};
-	},
-
-// ----------------------------------------------------------------------------
-// Syntax Coloring
-
-	{
-		Identifier = "xcode.lang.go";
-		Description = "Go Coloring";
-		BasedOn = "xcode.lang.simpleColoring";
-		IncludeInMenu = YES;
-		Name = "Go";
-		Syntax = {
-			Tokenizer = "xcode.lang.go.lexer.toplevel";
-			IncludeRules = (
-				"xcode.lang.go.block",
-				"xcode.lang.go.bracketexpr",
-				"xcode.lang.go.parenexpr",
-			);
-			Type = "xcode.syntax.plain";
-		};
-	},
-
-	// The following rule returns tokens to the other rules
-	{
-		Identifier = "xcode.lang.go.lexer";
-		Syntax = {
-			IncludeRules = (
-				"xcode.lang.go.comment",
-				"xcode.lang.go.comment.singleline",
-				"xcode.lang.string",
-				"xcode.lang.character",
-				"xcode.lang.go.rawstring",
-				"xcode.lang.go.identifier",
-				"xcode.lang.number",
-				"xcode.lang.go.interestingOperators",
-			);
-		};
-	},
-
-	{
-		Identifier = "xcode.lang.go.lexer.toplevel";
-		Syntax = {
-			IncludeRules = (
-				"xcode.lang.go.comment",
-				"xcode.lang.go.comment.singleline",
-				"xcode.lang.string",
-				"xcode.lang.character",
-				"xcode.lang.go.rawstring",
-				"xcode.lang.go.type.declaration",
-				"xcode.lang.go.method.declaration",
-				"xcode.lang.go.function.declaration",
-				"xcode.lang.go.identifier",
-				"xcode.lang.number",
-			);
-		};
-	},
-
-	{
-		Identifier = "xcode.lang.go.method.declaration";
-		Syntax = {
-			Tokenizer = "xcode.lang.go.lexer";
-			Rules = (
-				"func",
-				"xcode.lang.go.parenexpr",
-				"xcode.lang.go.identifier",
-				"xcode.lang.go.parenexpr",
-			);
-			Type = "xcode.syntax.declaration.method";
-		};
-	},
-
-	{
-		Identifier = "xcode.lang.go.type.declaration";
-		Syntax = {
-			Tokenizer = "xcode.lang.go.lexer";
-			Rules = (
-				"type",
-				"xcode.lang.go.identifier",
-			);
-			Type = "xcode.syntax.typedef";
-		};
-	},
-
-	{
-		Identifier = "xcode.lang.go.function.declaration";
-		Syntax = {
-			Tokenizer = "xcode.lang.go.lexer";
-			Rules = (
-				"func",
-				"xcode.lang.go.identifier",
-				"xcode.lang.go.parenexpr",
-			);
-			Type = "xcode.syntax.declaration.function";
-		};
-	},
-
-// ----------------------------------------------------------------------------
-// Blocks
-
-	{
-		Identifier = "xcode.lang.go.block";
-		Syntax = {
-			Tokenizer = "xcode.lang.go.lexer";
-			Start = "{";
-			End = "}";
-			Foldable = YES;
-			Recursive = YES;
-			IncludeRules = (
-				"xcode.lang.go.bracketexpr",
-				"xcode.lang.go.parenexpr",
-			);
-		};
-	},
-
-	{
-		Identifier = "xcode.lang.go.parenexpr";
-		Syntax = {
-			Tokenizer = "xcode.lang.go.lexer";
-			Start = "(";
-			End = ")";
-			Recursive = YES;
-			IncludeRules = (
-				"xcode.lang.go.bracketexpr",
-				"xcode.lang.go.block",
-			);
-		};
-	},
-
-	{
-		Identifier = "xcode.lang.go.bracketexpr";
-		Syntax = {
-			Tokenizer = "xcode.lang.go.lexer";
-			Start = "[";
-			End = "]";
-			Recursive = YES;
-			IncludeRules = (
-				"xcode.lang.go.parenexpr",
-			);
-		};
-	},
-
-	{
-		Identifier = "xcode.lang.go.comment";
-		Syntax = {
-			Start = "/*";
-			End = "*/";
-			Foldable = YES;
-			IncludeRules = (
-				"xcode.lang.url",
-				"xcode.lang.url.mail",
-				"xcode.lang.comment.mark",
-			);
-			Type = "xcode.syntax.comment";
-		};
-	},
-
-	{
-		Identifier = "xcode.lang.go.comment.singleline";
-		Syntax = {
-			Start = "//";
-			End = "\n";
-			IncludeRules = (
-				"xcode.lang.url",
-				"xcode.lang.url.mail",
-				"xcode.lang.comment.mark",
-			);
-			Type = "xcode.syntax.comment";
-		};
-	},
-
-	// This rule recognizes special comments markers and adds them
-	// to the list of file markers at the top of the editor window.
-	// This overrides the markers specified in
-	// /Developer/Library/PrivateFrameworks/XcodeEdit.framework/Versions/A/Resources/BaseSupport.xclangspec
-	// and appears to apply them to all languages. Thus, for now
-	// "inherit" the existing markers here for backward-compatibility.
-	{
-		Identifier = "xcode.lang.comment.mark";
-		Syntax = {
-			StartChars = "BMTF!?";
-			Match = (
-				// Go-specific markers
-				"^\(BUG.*$\)$",			// include "BUG" in the markers list
-				"^\(TODO.*$\)$",		// include "TODO" in the markers list
-				// inherited markers
-				"^MARK:[ \t]+\(.*\)$",
-				"^\(TODO:[ \t]+.*\)$",		// include "TODO: " in the markers list
-				"^\(FIXME:[ \t]+.*\)$",		// include "FIXME: " in the markers list
-				"^\(!!!:.*\)$",			// include "!!!:" in the markers list
-				"^\(\\?\\?\\?:.*\)$"		// include "???:" in the markers list
-			);
-			// This is the order of captures. All of the match strings above need the same order.
-			CaptureTypes = (
-				"xcode.syntax.mark"
-			);
-			Type = "xcode.syntax.comment";
-		};
-	},
-
-)
diff --git a/misc/xcode/4/go4xcode.sh b/misc/xcode/4/go4xcode.sh
deleted file mode 100755
index 4b0125e..0000000
--- a/misc/xcode/4/go4xcode.sh
+++ /dev/null
@@ -1,112 +0,0 @@
-#!/usr/bin/env bash
-# Copyright 2012 The Go Authors.  All rights reserved.
-# Use of this source code is governed by a BSD-style
-# license that can be found in the LICENSE file.
-
-# Illustrates how a Go language specification can be installed for Xcode 4+,
-# to enable syntax coloring, by adding an entry to a plugindata file.
-#
-# FIXME: Write a decent Xcode plugin to handle the file type association and
-# language specification properly instead of altering Xcode library files.
-
-set -e
-
-# Assumes Xcode 4+.
-XCODE_MAJOR_VERSION=`xcodebuild -version | awk 'NR == 1 {print substr($2,1,1)}'`
-if [ "$XCODE_MAJOR_VERSION" -lt "4" ]; then
-	echo "Xcode 4+ not found."
-	exit 1
-fi
-
-# DVTFOUNDATION_DIR may vary depending on Xcode setup. If Xcode has installed
-# the `xcode-select` command, it will be determined automatically. Otherwise,
-# change it to reflect your current Xcode setup. Find suitable path with e.g.:
-#
-#	find / -type f -name 'DVTFoundation.xcplugindata' 2> /dev/null
-#
-# Example of DVTFOUNDATION_DIR's from "default" Xcode 4+ setups;
-#
-#	Xcode 4.1: /Developer/Library/PrivateFrameworks/DVTFoundation.framework/Versions/A/Resources/
-#	Xcode 4.3: /Applications/Xcode.app/Contents/SharedFrameworks/DVTFoundation.framework/Versions/A/Resources/
-
-# Defaults to Xcode 4.3's DVTFOUNDATION_DIR. Path is modified automatically if
-# `xcode-select` command is available, as mentioned above.
-DVTFOUNDATION_DIR="/Applications/Xcode.app/Contents/SharedFrameworks/DVTFoundation.framework/Versions/A/Resources/"
-
-if type "xcode-select" > /dev/null; then
-    DVTFOUNDATION_DIR=`xcode-select --print-path`
-    DVTFOUNDATION_DIR+="/.."
-    FRAMEWORK_NAME="DVTFoundation.framework"    
-    DVTFOUNDATION_DIR=`find $DVTFOUNDATION_DIR -name $FRAMEWORK_NAME -print`
-    DVTFOUNDATION_DIR+="/Versions/A/Resources"
-fi
-
-PLUGINDATA_FILE="DVTFoundation.xcplugindata"
-
-PLISTBUDDY=/usr/libexec/PlistBuddy
-PLIST_FILE=tmp.plist
-
-# Provide means of deleting the Go entry from the plugindata file.
-if [ "$1" = "--delete-entry" ]; then
-	echo "Removing Go language specification entry."
-	$PLISTBUDDY -c "Delete :plug-in:extensions:Xcode.SourceCodeLanguage.Go" $DVTFOUNDATION_DIR/$PLUGINDATA_FILE
-	echo "Run 'sudo rm -rf /var/folders/*' and restart Xcode to update change immediately."
-	exit 0
-fi
-
-GO_VERSION="`go version`"
-
-GO_LANG_ENTRY="
-	<?xml version=\"1.0\" encoding=\"UTF-8\"?>
-	<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">
-	<plist version=\"1.0\">
-		<dict>
-			<key>Xcode.SourceCodeLanguage.Go</key>
-			<dict>
-				<key>conformsTo</key>
-				<array>
-					<dict>
-						<key>identifier</key>
-						<string>Xcode.SourceCodeLanguage.Generic</string>
-					</dict>
-				</array>
-				<key>documentationAbbreviation</key>
-				<string>go</string>
-				<key>fileDataType</key>
-				<array>
-					<dict>
-						<key>identifier</key>
-						<string>com.apple.xcode.go-source</string>
-					</dict>
-				</array>
-				<key>id</key>
-				<string>Xcode.SourceCodeLanguage.Go</string>
-				<key>languageName</key>
-				<string>Go</string>
-				<key>languageSpecification</key>
-				<string>xcode.lang.go</string>
-				<key>name</key>
-				<string>The Go Programming Language</string>
-				<key>point</key>
-				<string>Xcode.SourceCodeLanguage</string>
-				<key>version</key>
-				<string>$GO_VERSION</string>
-			</dict>
-		</dict>
-	</plist>
-"
-
-echo "Backing up plugindata file (copied to $PLUGINDATA_FILE.bak)."
-cp $DVTFOUNDATION_DIR/$PLUGINDATA_FILE $DVTFOUNDATION_DIR/$PLUGINDATA_FILE.bak
-
-echo "Adding Go language specification entry."
-echo $GO_LANG_ENTRY > $PLIST_FILE
-$PLISTBUDDY -c "Merge $PLIST_FILE plug-in:extensions" $DVTFOUNDATION_DIR/$PLUGINDATA_FILE
-
-rm -f $PLIST_FILE
-
-echo "Installing Go language specification file for Xcode."
-cp $GOROOT/misc/xcode/4/go.xclangspec $DVTFOUNDATION_DIR
-
-echo "Run 'sudo rm -rf /var/folders/*' and restart Xcode to update change immediately."
-echo "Syntax coloring must be manually selected from the Editor - Syntax Coloring menu in Xcode."
diff --git a/misc/zsh/go b/misc/zsh/go
deleted file mode 100644
index 066cf40..0000000
--- a/misc/zsh/go
+++ /dev/null
@@ -1,161 +0,0 @@
-# install in /etc/zsh/zshrc or your personal .zshrc
-
-# gc
-prefixes=(5 6 8)
-for p in $prefixes; do
-	compctl -g "*.${p}" ${p}l
-	compctl -g "*.go" ${p}g
-done
-
-# standard go tools
-compctl -g "*.go" gofmt
-
-# gccgo
-compctl -g "*.go" gccgo
-
-# go tool
-__go_tool_complete() {
-  typeset -a commands build_flags
-  commands+=(
-    'build[compile packages and dependencies]'
-    'clean[remove object files]'
-    'env[print Go environment information]'
-    'fix[run go tool fix on packages]'
-    'fmt[run gofmt on package sources]'
-    'get[download and install packages and dependencies]'
-    'help[display help]'
-    'install[compile and install packages and dependencies]'
-    'list[list packages]'
-    'run[compile and run Go program]'
-    'test[test packages]'
-    'tool[run specified go tool]'
-    'version[print Go version]'
-    'vet[run go tool vet on packages]'
-  )
-  if (( CURRENT == 2 )); then
-    # explain go commands
-    _values 'go tool commands' ${commands[@]}
-    return
-  fi
-  build_flags=(
-    '-a[force reinstallation of packages that are already up-to-date]'
-    '-n[print the commands but do not run them]'
-    '-p[number of parallel builds]:number'
-    '-race[enable data race detection]'
-    '-x[print the commands]'
-    '-work[print temporary directory name and keep it]'
-    '-ccflags[flags for 5c/6c/8c]:flags'
-    '-gcflags[flags for 5g/6g/8g]:flags'
-    '-ldflags[flags for 5l/6l/8l]:flags'
-    '-gccgoflags[flags for gccgo]:flags'
-    '-compiler[name of compiler to use]:name'
-    '-installsuffix[suffix to add to package directory]:suffix'
-    '-tags[list of build tags to consider satisfied]:tags'
-  )
-  __go_list() {
-      local expl importpaths
-      declare -a importpaths
-      importpaths=($(go list ${words[$CURRENT]}... 2>/dev/null))
-      _wanted importpaths expl 'import paths' compadd "$@" - "${importpaths[@]}"
-  }
-  case ${words[2]} in
-  clean|doc)
-      _arguments -s -w : '*:importpaths:__go_list'
-      ;;
-  fix|fmt|list|vet)
-      _alternative ':importpaths:__go_list' ':files:_path_files -g "*.go"'
-      ;;
-  install)
-      _arguments -s -w : ${build_flags[@]} \
-        "-v[show package names]" \
-        '*:importpaths:__go_list'
-      ;;
-  get)
-      _arguments -s -w : \
-        ${build_flags[@]}
-      ;;
-  build)
-      _arguments -s -w : \
-        ${build_flags[@]} \
-        "-v[show package names]" \
-        "-o[output file]:file:_files" \
-        "*:args:{ _alternative ':importpaths:__go_list' ':files:_path_files -g \"*.go\"' }"
-      ;;
-  test)
-      _arguments -s -w : \
-        ${build_flags[@]} \
-        "-c[do not run, compile the test binary]" \
-        "-i[do not run, install dependencies]" \
-        "-v[print test output]" \
-        "-x[print the commands]" \
-        "-short[use short mode]" \
-        "-parallel[number of parallel tests]:number" \
-        "-cpu[values of GOMAXPROCS to use]:number list" \
-	"-cover[enable coverage analysis]" \
-        "-run[run tests and examples matching regexp]:regexp" \
-        "-bench[run benchmarks matching regexp]:regexp" \
-        "-benchmem[print memory allocation stats]" \
-        "-benchtime[run each benchmark until taking this long]:duration" \
-        "-blockprofile[write goroutine blocking profile to file]:file" \
-        "-blockprofilerate[set sampling rate of goroutine blocking profile]:number" \
-        "-timeout[kill test after that duration]:duration" \
-        "-cpuprofile[write CPU profile to file]:file:_files" \
-        "-memprofile[write heap profile to file]:file:_files" \
-        "-memprofilerate[set heap profiling rate]:number" \
-        "*:args:{ _alternative ':importpaths:__go_list' ':files:_path_files -g \"*.go\"' }"
-      ;;
-  help)
-      _values "${commands[@]}" \
-        'c[how to call C code]' \
-        'importpath[description of import path]' \
-        'gopath[GOPATH environment variable]' \
-        'packages[description of package lists]' \
-        'testflag[description of testing flags]' \
-        'testfunc[description of testing functions]'
-      ;;
-  run)
-      _arguments -s -w : \
-          ${build_flags[@]} \
-          '*:file:_path_files -g "*.go"'
-      ;;
-  tool)
-      if (( CURRENT == 3 )); then
-          _values "go tool" $(go tool)
-          return
-      fi
-      case ${words[3]} in
-      [568]g)
-          _arguments -s -w : \
-              '-I[search for packages in DIR]:includes:_path_files -/' \
-              '-L[show full path in file:line prints]' \
-              '-S[print the assembly language]' \
-              '-V[print the compiler version]' \
-              '-e[no limit on number of errors printed]' \
-              '-h[panic on an error]' \
-              '-l[disable inlining]' \
-              '-m[print optimization decisions]' \
-              '-o[file specify output file]:file' \
-              '-p[assumed import path for this code]:importpath' \
-              '-u[disable package unsafe]' \
-              "*:file:_files -g '*.go'"
-          ;;
-      [568]l)
-          local O=${words[3]%l}
-          _arguments -s -w : \
-              '-o[file specify output file]:file' \
-              '-L[search for packages in DIR]:includes:_path_files -/' \
-              "*:file:_files -g '*.[ao$O]'"
-          ;;
-      dist)
-          _values "dist tool" banner bootstrap clean env install version
-          ;;
-      *)
-          # use files by default
-          _files
-          ;;
-      esac
-      ;;
-  esac
-}
-
-compdef __go_tool_complete go
diff --git a/src/androidtest.bash b/src/androidtest.bash
new file mode 100755
index 0000000..504d276
--- /dev/null
+++ b/src/androidtest.bash
@@ -0,0 +1,55 @@
+#!/usr/bin/env bash
+# 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.
+
+# For testing Android.
+# The compiler runs locally, then a copy of the GOROOT is pushed to a
+# target device using adb, and the tests are run there.
+
+set -e
+ulimit -c 0 # no core files
+
+if [ ! -f make.bash ]; then
+	echo 'nacl.bash must be run from $GOROOT/src' 1>&2
+	exit 1
+fi
+
+if [ -z $GOOS ]; then
+	export GOOS=android
+fi
+if [ "$GOOS" != "android" ]; then
+	echo "androidtest.bash requires GOOS=android, got GOOS=$GOOS" 1>&2
+	exit 1
+fi
+
+export CGO_ENABLED=1
+
+# Run the build for the host bootstrap, so we can build go_android_exec.
+# Also lets us fail early before the (slow) adb push if the build is broken.
+./make.bash
+export GOROOT=$(dirname $(pwd))
+export PATH=$GOROOT/bin:$PATH
+GOOS=$GOHOSTOS GOARCH=$GOHOSTARCH go build \
+	-o ../bin/go_android_${GOARCH}_exec \
+	../misc/android/go_android_exec.go
+
+# Push GOROOT to target device.
+#
+# The adb sync command will sync either the /system or /data
+# directories of an android device from a similar directory
+# on the host. So we fake one with symlinks to push the GOROOT
+# into a subdirectory of /data.
+export ANDROID_PRODUCT_OUT=/tmp/androidtest-$$
+FAKE_GOROOT=$ANDROID_PRODUCT_OUT/data/local/tmp/goroot
+mkdir -p $FAKE_GOROOT
+ln -s $GOROOT/src $FAKE_GOROOT/src
+ln -s $GOROOT/test $FAKE_GOROOT/test
+ln -s $GOROOT/lib $FAKE_GOROOT/lib
+echo '# Syncing test files to android device'
+time adb sync data &> /dev/null
+echo ''
+rm -rf "$ANDROID_PRODUCT_OUT"
+
+# Run standard build and tests.
+./all.bash --no-clean
diff --git a/src/pkg/archive/tar/common.go b/src/archive/tar/common.go
similarity index 100%
rename from src/pkg/archive/tar/common.go
rename to src/archive/tar/common.go
diff --git a/src/pkg/archive/tar/example_test.go b/src/archive/tar/example_test.go
similarity index 100%
rename from src/pkg/archive/tar/example_test.go
rename to src/archive/tar/example_test.go
diff --git a/src/archive/tar/reader.go b/src/archive/tar/reader.go
new file mode 100644
index 0000000..a27559d
--- /dev/null
+++ b/src/archive/tar/reader.go
@@ -0,0 +1,820 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tar
+
+// TODO(dsymonds):
+//   - pax extensions
+
+import (
+	"bytes"
+	"errors"
+	"io"
+	"io/ioutil"
+	"os"
+	"strconv"
+	"strings"
+	"time"
+)
+
+var (
+	ErrHeader = errors.New("archive/tar: invalid tar header")
+)
+
+const maxNanoSecondIntSize = 9
+
+// A Reader provides sequential access to the contents of a tar archive.
+// A tar archive consists of a sequence of files.
+// The Next method advances to the next file in the archive (including the first),
+// and then it can be treated as an io.Reader to access the file's data.
+type Reader struct {
+	r       io.Reader
+	err     error
+	pad     int64           // amount of padding (ignored) after current file entry
+	curr    numBytesReader  // reader for current file entry
+	hdrBuff [blockSize]byte // buffer to use in readHeader
+}
+
+// A numBytesReader is an io.Reader with a numBytes method, returning the number
+// of bytes remaining in the underlying encoded data.
+type numBytesReader interface {
+	io.Reader
+	numBytes() int64
+}
+
+// A regFileReader is a numBytesReader for reading file data from a tar archive.
+type regFileReader struct {
+	r  io.Reader // underlying reader
+	nb int64     // number of unread bytes for current file entry
+}
+
+// A sparseFileReader is a numBytesReader for reading sparse file data from a tar archive.
+type sparseFileReader struct {
+	rfr *regFileReader // reads the sparse-encoded file data
+	sp  []sparseEntry  // the sparse map for the file
+	pos int64          // keeps track of file position
+	tot int64          // total size of the file
+}
+
+// Keywords for GNU sparse files in a PAX extended header
+const (
+	paxGNUSparseNumBlocks = "GNU.sparse.numblocks"
+	paxGNUSparseOffset    = "GNU.sparse.offset"
+	paxGNUSparseNumBytes  = "GNU.sparse.numbytes"
+	paxGNUSparseMap       = "GNU.sparse.map"
+	paxGNUSparseName      = "GNU.sparse.name"
+	paxGNUSparseMajor     = "GNU.sparse.major"
+	paxGNUSparseMinor     = "GNU.sparse.minor"
+	paxGNUSparseSize      = "GNU.sparse.size"
+	paxGNUSparseRealSize  = "GNU.sparse.realsize"
+)
+
+// Keywords for old GNU sparse headers
+const (
+	oldGNUSparseMainHeaderOffset               = 386
+	oldGNUSparseMainHeaderIsExtendedOffset     = 482
+	oldGNUSparseMainHeaderNumEntries           = 4
+	oldGNUSparseExtendedHeaderIsExtendedOffset = 504
+	oldGNUSparseExtendedHeaderNumEntries       = 21
+	oldGNUSparseOffsetSize                     = 12
+	oldGNUSparseNumBytesSize                   = 12
+)
+
+// NewReader creates a new Reader reading from r.
+func NewReader(r io.Reader) *Reader { return &Reader{r: r} }
+
+// Next advances to the next entry in the tar archive.
+func (tr *Reader) Next() (*Header, error) {
+	var hdr *Header
+	if tr.err == nil {
+		tr.skipUnread()
+	}
+	if tr.err != nil {
+		return hdr, tr.err
+	}
+	hdr = tr.readHeader()
+	if hdr == nil {
+		return hdr, tr.err
+	}
+	// Check for PAX/GNU header.
+	switch hdr.Typeflag {
+	case TypeXHeader:
+		//  PAX extended header
+		headers, err := parsePAX(tr)
+		if err != nil {
+			return nil, err
+		}
+		// We actually read the whole file,
+		// but this skips alignment padding
+		tr.skipUnread()
+		hdr = tr.readHeader()
+		mergePAX(hdr, headers)
+
+		// Check for a PAX format sparse file
+		sp, err := tr.checkForGNUSparsePAXHeaders(hdr, headers)
+		if err != nil {
+			tr.err = err
+			return nil, err
+		}
+		if sp != nil {
+			// Current file is a PAX format GNU sparse file.
+			// Set the current file reader to a sparse file reader.
+			tr.curr = &sparseFileReader{rfr: tr.curr.(*regFileReader), sp: sp, tot: hdr.Size}
+		}
+		return hdr, nil
+	case TypeGNULongName:
+		// We have a GNU long name header. Its contents are the real file name.
+		realname, err := ioutil.ReadAll(tr)
+		if err != nil {
+			return nil, err
+		}
+		hdr, err := tr.Next()
+		hdr.Name = cString(realname)
+		return hdr, err
+	case TypeGNULongLink:
+		// We have a GNU long link header.
+		realname, err := ioutil.ReadAll(tr)
+		if err != nil {
+			return nil, err
+		}
+		hdr, err := tr.Next()
+		hdr.Linkname = cString(realname)
+		return hdr, err
+	}
+	return hdr, tr.err
+}
+
+// checkForGNUSparsePAXHeaders checks the PAX headers for GNU sparse headers. If they are found, then
+// this function reads the sparse map and returns it. Unknown sparse formats are ignored, causing the file to
+// be treated as a regular file.
+func (tr *Reader) checkForGNUSparsePAXHeaders(hdr *Header, headers map[string]string) ([]sparseEntry, error) {
+	var sparseFormat string
+
+	// Check for sparse format indicators
+	major, majorOk := headers[paxGNUSparseMajor]
+	minor, minorOk := headers[paxGNUSparseMinor]
+	sparseName, sparseNameOk := headers[paxGNUSparseName]
+	_, sparseMapOk := headers[paxGNUSparseMap]
+	sparseSize, sparseSizeOk := headers[paxGNUSparseSize]
+	sparseRealSize, sparseRealSizeOk := headers[paxGNUSparseRealSize]
+
+	// Identify which, if any, sparse format applies from which PAX headers are set
+	if majorOk && minorOk {
+		sparseFormat = major + "." + minor
+	} else if sparseNameOk && sparseMapOk {
+		sparseFormat = "0.1"
+	} else if sparseSizeOk {
+		sparseFormat = "0.0"
+	} else {
+		// Not a PAX format GNU sparse file.
+		return nil, nil
+	}
+
+	// Check for unknown sparse format
+	if sparseFormat != "0.0" && sparseFormat != "0.1" && sparseFormat != "1.0" {
+		return nil, nil
+	}
+
+	// Update hdr from GNU sparse PAX headers
+	if sparseNameOk {
+		hdr.Name = sparseName
+	}
+	if sparseSizeOk {
+		realSize, err := strconv.ParseInt(sparseSize, 10, 0)
+		if err != nil {
+			return nil, ErrHeader
+		}
+		hdr.Size = realSize
+	} else if sparseRealSizeOk {
+		realSize, err := strconv.ParseInt(sparseRealSize, 10, 0)
+		if err != nil {
+			return nil, ErrHeader
+		}
+		hdr.Size = realSize
+	}
+
+	// Set up the sparse map, according to the particular sparse format in use
+	var sp []sparseEntry
+	var err error
+	switch sparseFormat {
+	case "0.0", "0.1":
+		sp, err = readGNUSparseMap0x1(headers)
+	case "1.0":
+		sp, err = readGNUSparseMap1x0(tr.curr)
+	}
+	return sp, err
+}
+
+// mergePAX merges well known headers according to PAX standard.
+// In general headers with the same name as those found
+// in the header struct overwrite those found in the header
+// struct with higher precision or longer values. Esp. useful
+// for name and linkname fields.
+func mergePAX(hdr *Header, headers map[string]string) error {
+	for k, v := range headers {
+		switch k {
+		case paxPath:
+			hdr.Name = v
+		case paxLinkpath:
+			hdr.Linkname = v
+		case paxGname:
+			hdr.Gname = v
+		case paxUname:
+			hdr.Uname = v
+		case paxUid:
+			uid, err := strconv.ParseInt(v, 10, 0)
+			if err != nil {
+				return err
+			}
+			hdr.Uid = int(uid)
+		case paxGid:
+			gid, err := strconv.ParseInt(v, 10, 0)
+			if err != nil {
+				return err
+			}
+			hdr.Gid = int(gid)
+		case paxAtime:
+			t, err := parsePAXTime(v)
+			if err != nil {
+				return err
+			}
+			hdr.AccessTime = t
+		case paxMtime:
+			t, err := parsePAXTime(v)
+			if err != nil {
+				return err
+			}
+			hdr.ModTime = t
+		case paxCtime:
+			t, err := parsePAXTime(v)
+			if err != nil {
+				return err
+			}
+			hdr.ChangeTime = t
+		case paxSize:
+			size, err := strconv.ParseInt(v, 10, 0)
+			if err != nil {
+				return err
+			}
+			hdr.Size = int64(size)
+		default:
+			if strings.HasPrefix(k, paxXattr) {
+				if hdr.Xattrs == nil {
+					hdr.Xattrs = make(map[string]string)
+				}
+				hdr.Xattrs[k[len(paxXattr):]] = v
+			}
+		}
+	}
+	return nil
+}
+
+// parsePAXTime takes a string of the form %d.%d as described in
+// the PAX specification.
+func parsePAXTime(t string) (time.Time, error) {
+	buf := []byte(t)
+	pos := bytes.IndexByte(buf, '.')
+	var seconds, nanoseconds int64
+	var err error
+	if pos == -1 {
+		seconds, err = strconv.ParseInt(t, 10, 0)
+		if err != nil {
+			return time.Time{}, err
+		}
+	} else {
+		seconds, err = strconv.ParseInt(string(buf[:pos]), 10, 0)
+		if err != nil {
+			return time.Time{}, err
+		}
+		nano_buf := string(buf[pos+1:])
+		// Pad as needed before converting to a decimal.
+		// For example .030 -> .030000000 -> 30000000 nanoseconds
+		if len(nano_buf) < maxNanoSecondIntSize {
+			// Right pad
+			nano_buf += strings.Repeat("0", maxNanoSecondIntSize-len(nano_buf))
+		} else if len(nano_buf) > maxNanoSecondIntSize {
+			// Right truncate
+			nano_buf = nano_buf[:maxNanoSecondIntSize]
+		}
+		nanoseconds, err = strconv.ParseInt(string(nano_buf), 10, 0)
+		if err != nil {
+			return time.Time{}, err
+		}
+	}
+	ts := time.Unix(seconds, nanoseconds)
+	return ts, nil
+}
+
+// parsePAX parses PAX headers.
+// If an extended header (type 'x') is invalid, ErrHeader is returned
+func parsePAX(r io.Reader) (map[string]string, error) {
+	buf, err := ioutil.ReadAll(r)
+	if err != nil {
+		return nil, err
+	}
+
+	// For GNU PAX sparse format 0.0 support.
+	// This function transforms the sparse format 0.0 headers into sparse format 0.1 headers.
+	var sparseMap bytes.Buffer
+
+	headers := make(map[string]string)
+	// Each record is constructed as
+	//     "%d %s=%s\n", length, keyword, value
+	for len(buf) > 0 {
+		// or the header was empty to start with.
+		var sp int
+		// The size field ends at the first space.
+		sp = bytes.IndexByte(buf, ' ')
+		if sp == -1 {
+			return nil, ErrHeader
+		}
+		// Parse the first token as a decimal integer.
+		n, err := strconv.ParseInt(string(buf[:sp]), 10, 0)
+		if err != nil {
+			return nil, ErrHeader
+		}
+		// Extract everything between the decimal and the n -1 on the
+		// beginning to eat the ' ', -1 on the end to skip the newline.
+		var record []byte
+		record, buf = buf[sp+1:n-1], buf[n:]
+		// The first equals is guaranteed to mark the end of the key.
+		// Everything else is value.
+		eq := bytes.IndexByte(record, '=')
+		if eq == -1 {
+			return nil, ErrHeader
+		}
+		key, value := record[:eq], record[eq+1:]
+
+		keyStr := string(key)
+		if keyStr == paxGNUSparseOffset || keyStr == paxGNUSparseNumBytes {
+			// GNU sparse format 0.0 special key. Write to sparseMap instead of using the headers map.
+			sparseMap.Write(value)
+			sparseMap.Write([]byte{','})
+		} else {
+			// Normal key. Set the value in the headers map.
+			headers[keyStr] = string(value)
+		}
+	}
+	if sparseMap.Len() != 0 {
+		// Add sparse info to headers, chopping off the extra comma
+		sparseMap.Truncate(sparseMap.Len() - 1)
+		headers[paxGNUSparseMap] = sparseMap.String()
+	}
+	return headers, nil
+}
+
+// cString parses bytes as a NUL-terminated C-style string.
+// If a NUL byte is not found then the whole slice is returned as a string.
+func cString(b []byte) string {
+	n := 0
+	for n < len(b) && b[n] != 0 {
+		n++
+	}
+	return string(b[0:n])
+}
+
+func (tr *Reader) octal(b []byte) int64 {
+	// Check for binary format first.
+	if len(b) > 0 && b[0]&0x80 != 0 {
+		var x int64
+		for i, c := range b {
+			if i == 0 {
+				c &= 0x7f // ignore signal bit in first byte
+			}
+			x = x<<8 | int64(c)
+		}
+		return x
+	}
+
+	// Because unused fields are filled with NULs, we need
+	// to skip leading NULs. Fields may also be padded with
+	// spaces or NULs.
+	// So we remove leading and trailing NULs and spaces to
+	// be sure.
+	b = bytes.Trim(b, " \x00")
+
+	if len(b) == 0 {
+		return 0
+	}
+	x, err := strconv.ParseUint(cString(b), 8, 64)
+	if err != nil {
+		tr.err = err
+	}
+	return int64(x)
+}
+
+// skipUnread skips any unread bytes in the existing file entry, as well as any alignment padding.
+func (tr *Reader) skipUnread() {
+	nr := tr.numBytes() + tr.pad // number of bytes to skip
+	tr.curr, tr.pad = nil, 0
+	if sr, ok := tr.r.(io.Seeker); ok {
+		if _, err := sr.Seek(nr, os.SEEK_CUR); err == nil {
+			return
+		}
+	}
+	_, tr.err = io.CopyN(ioutil.Discard, tr.r, nr)
+}
+
+func (tr *Reader) verifyChecksum(header []byte) bool {
+	if tr.err != nil {
+		return false
+	}
+
+	given := tr.octal(header[148:156])
+	unsigned, signed := checksum(header)
+	return given == unsigned || given == signed
+}
+
+func (tr *Reader) readHeader() *Header {
+	header := tr.hdrBuff[:]
+	copy(header, zeroBlock)
+
+	if _, tr.err = io.ReadFull(tr.r, header); tr.err != nil {
+		return nil
+	}
+
+	// Two blocks of zero bytes marks the end of the archive.
+	if bytes.Equal(header, zeroBlock[0:blockSize]) {
+		if _, tr.err = io.ReadFull(tr.r, header); tr.err != nil {
+			return nil
+		}
+		if bytes.Equal(header, zeroBlock[0:blockSize]) {
+			tr.err = io.EOF
+		} else {
+			tr.err = ErrHeader // zero block and then non-zero block
+		}
+		return nil
+	}
+
+	if !tr.verifyChecksum(header) {
+		tr.err = ErrHeader
+		return nil
+	}
+
+	// Unpack
+	hdr := new(Header)
+	s := slicer(header)
+
+	hdr.Name = cString(s.next(100))
+	hdr.Mode = tr.octal(s.next(8))
+	hdr.Uid = int(tr.octal(s.next(8)))
+	hdr.Gid = int(tr.octal(s.next(8)))
+	hdr.Size = tr.octal(s.next(12))
+	hdr.ModTime = time.Unix(tr.octal(s.next(12)), 0)
+	s.next(8) // chksum
+	hdr.Typeflag = s.next(1)[0]
+	hdr.Linkname = cString(s.next(100))
+
+	// The remainder of the header depends on the value of magic.
+	// The original (v7) version of tar had no explicit magic field,
+	// so its magic bytes, like the rest of the block, are NULs.
+	magic := string(s.next(8)) // contains version field as well.
+	var format string
+	switch {
+	case magic[:6] == "ustar\x00": // POSIX tar (1003.1-1988)
+		if string(header[508:512]) == "tar\x00" {
+			format = "star"
+		} else {
+			format = "posix"
+		}
+	case magic == "ustar  \x00": // old GNU tar
+		format = "gnu"
+	}
+
+	switch format {
+	case "posix", "gnu", "star":
+		hdr.Uname = cString(s.next(32))
+		hdr.Gname = cString(s.next(32))
+		devmajor := s.next(8)
+		devminor := s.next(8)
+		if hdr.Typeflag == TypeChar || hdr.Typeflag == TypeBlock {
+			hdr.Devmajor = tr.octal(devmajor)
+			hdr.Devminor = tr.octal(devminor)
+		}
+		var prefix string
+		switch format {
+		case "posix", "gnu":
+			prefix = cString(s.next(155))
+		case "star":
+			prefix = cString(s.next(131))
+			hdr.AccessTime = time.Unix(tr.octal(s.next(12)), 0)
+			hdr.ChangeTime = time.Unix(tr.octal(s.next(12)), 0)
+		}
+		if len(prefix) > 0 {
+			hdr.Name = prefix + "/" + hdr.Name
+		}
+	}
+
+	if tr.err != nil {
+		tr.err = ErrHeader
+		return nil
+	}
+
+	// Maximum value of hdr.Size is 64 GB (12 octal digits),
+	// so there's no risk of int64 overflowing.
+	nb := int64(hdr.Size)
+	tr.pad = -nb & (blockSize - 1) // blockSize is a power of two
+
+	// Set the current file reader.
+	tr.curr = &regFileReader{r: tr.r, nb: nb}
+
+	// Check for old GNU sparse format entry.
+	if hdr.Typeflag == TypeGNUSparse {
+		// Get the real size of the file.
+		hdr.Size = tr.octal(header[483:495])
+
+		// Read the sparse map.
+		sp := tr.readOldGNUSparseMap(header)
+		if tr.err != nil {
+			return nil
+		}
+		// Current file is a GNU sparse file. Update the current file reader.
+		tr.curr = &sparseFileReader{rfr: tr.curr.(*regFileReader), sp: sp, tot: hdr.Size}
+	}
+
+	return hdr
+}
+
+// A sparseEntry holds a single entry in a sparse file's sparse map.
+// A sparse entry indicates the offset and size in a sparse file of a
+// block of data.
+type sparseEntry struct {
+	offset   int64
+	numBytes int64
+}
+
+// readOldGNUSparseMap reads the sparse map as stored in the old GNU sparse format.
+// The sparse map is stored in the tar header if it's small enough. If it's larger than four entries,
+// then one or more extension headers are used to store the rest of the sparse map.
+func (tr *Reader) readOldGNUSparseMap(header []byte) []sparseEntry {
+	isExtended := header[oldGNUSparseMainHeaderIsExtendedOffset] != 0
+	spCap := oldGNUSparseMainHeaderNumEntries
+	if isExtended {
+		spCap += oldGNUSparseExtendedHeaderNumEntries
+	}
+	sp := make([]sparseEntry, 0, spCap)
+	s := slicer(header[oldGNUSparseMainHeaderOffset:])
+
+	// Read the four entries from the main tar header
+	for i := 0; i < oldGNUSparseMainHeaderNumEntries; i++ {
+		offset := tr.octal(s.next(oldGNUSparseOffsetSize))
+		numBytes := tr.octal(s.next(oldGNUSparseNumBytesSize))
+		if tr.err != nil {
+			tr.err = ErrHeader
+			return nil
+		}
+		if offset == 0 && numBytes == 0 {
+			break
+		}
+		sp = append(sp, sparseEntry{offset: offset, numBytes: numBytes})
+	}
+
+	for isExtended {
+		// There are more entries. Read an extension header and parse its entries.
+		sparseHeader := make([]byte, blockSize)
+		if _, tr.err = io.ReadFull(tr.r, sparseHeader); tr.err != nil {
+			return nil
+		}
+		isExtended = sparseHeader[oldGNUSparseExtendedHeaderIsExtendedOffset] != 0
+		s = slicer(sparseHeader)
+		for i := 0; i < oldGNUSparseExtendedHeaderNumEntries; i++ {
+			offset := tr.octal(s.next(oldGNUSparseOffsetSize))
+			numBytes := tr.octal(s.next(oldGNUSparseNumBytesSize))
+			if tr.err != nil {
+				tr.err = ErrHeader
+				return nil
+			}
+			if offset == 0 && numBytes == 0 {
+				break
+			}
+			sp = append(sp, sparseEntry{offset: offset, numBytes: numBytes})
+		}
+	}
+	return sp
+}
+
+// readGNUSparseMap1x0 reads the sparse map as stored in GNU's PAX sparse format version 1.0.
+// The sparse map is stored just before the file data and padded out to the nearest block boundary.
+func readGNUSparseMap1x0(r io.Reader) ([]sparseEntry, error) {
+	buf := make([]byte, 2*blockSize)
+	sparseHeader := buf[:blockSize]
+
+	// readDecimal is a helper function to read a decimal integer from the sparse map
+	// while making sure to read from the file in blocks of size blockSize
+	readDecimal := func() (int64, error) {
+		// Look for newline
+		nl := bytes.IndexByte(sparseHeader, '\n')
+		if nl == -1 {
+			if len(sparseHeader) >= blockSize {
+				// This is an error
+				return 0, ErrHeader
+			}
+			oldLen := len(sparseHeader)
+			newLen := oldLen + blockSize
+			if cap(sparseHeader) < newLen {
+				// There's more header, but we need to make room for the next block
+				copy(buf, sparseHeader)
+				sparseHeader = buf[:newLen]
+			} else {
+				// There's more header, and we can just reslice
+				sparseHeader = sparseHeader[:newLen]
+			}
+
+			// Now that sparseHeader is large enough, read next block
+			if _, err := io.ReadFull(r, sparseHeader[oldLen:newLen]); err != nil {
+				return 0, err
+			}
+
+			// Look for a newline in the new data
+			nl = bytes.IndexByte(sparseHeader[oldLen:newLen], '\n')
+			if nl == -1 {
+				// This is an error
+				return 0, ErrHeader
+			}
+			nl += oldLen // We want the position from the beginning
+		}
+		// Now that we've found a newline, read a number
+		n, err := strconv.ParseInt(string(sparseHeader[:nl]), 10, 0)
+		if err != nil {
+			return 0, ErrHeader
+		}
+
+		// Update sparseHeader to consume this number
+		sparseHeader = sparseHeader[nl+1:]
+		return n, nil
+	}
+
+	// Read the first block
+	if _, err := io.ReadFull(r, sparseHeader); err != nil {
+		return nil, err
+	}
+
+	// The first line contains the number of entries
+	numEntries, err := readDecimal()
+	if err != nil {
+		return nil, err
+	}
+
+	// Read all the entries
+	sp := make([]sparseEntry, 0, numEntries)
+	for i := int64(0); i < numEntries; i++ {
+		// Read the offset
+		offset, err := readDecimal()
+		if err != nil {
+			return nil, err
+		}
+		// Read numBytes
+		numBytes, err := readDecimal()
+		if err != nil {
+			return nil, err
+		}
+
+		sp = append(sp, sparseEntry{offset: offset, numBytes: numBytes})
+	}
+
+	return sp, nil
+}
+
+// readGNUSparseMap0x1 reads the sparse map as stored in GNU's PAX sparse format version 0.1.
+// The sparse map is stored in the PAX headers.
+func readGNUSparseMap0x1(headers map[string]string) ([]sparseEntry, error) {
+	// Get number of entries
+	numEntriesStr, ok := headers[paxGNUSparseNumBlocks]
+	if !ok {
+		return nil, ErrHeader
+	}
+	numEntries, err := strconv.ParseInt(numEntriesStr, 10, 0)
+	if err != nil {
+		return nil, ErrHeader
+	}
+
+	sparseMap := strings.Split(headers[paxGNUSparseMap], ",")
+
+	// There should be two numbers in sparseMap for each entry
+	if int64(len(sparseMap)) != 2*numEntries {
+		return nil, ErrHeader
+	}
+
+	// Loop through the entries in the sparse map
+	sp := make([]sparseEntry, 0, numEntries)
+	for i := int64(0); i < numEntries; i++ {
+		offset, err := strconv.ParseInt(sparseMap[2*i], 10, 0)
+		if err != nil {
+			return nil, ErrHeader
+		}
+		numBytes, err := strconv.ParseInt(sparseMap[2*i+1], 10, 0)
+		if err != nil {
+			return nil, ErrHeader
+		}
+		sp = append(sp, sparseEntry{offset: offset, numBytes: numBytes})
+	}
+
+	return sp, nil
+}
+
+// numBytes returns the number of bytes left to read in the current file's entry
+// in the tar archive, or 0 if there is no current file.
+func (tr *Reader) numBytes() int64 {
+	if tr.curr == nil {
+		// No current file, so no bytes
+		return 0
+	}
+	return tr.curr.numBytes()
+}
+
+// Read reads from the current entry in the tar archive.
+// It returns 0, io.EOF when it reaches the end of that entry,
+// until Next is called to advance to the next entry.
+func (tr *Reader) Read(b []byte) (n int, err error) {
+	if tr.curr == nil {
+		return 0, io.EOF
+	}
+	n, err = tr.curr.Read(b)
+	if err != nil && err != io.EOF {
+		tr.err = err
+	}
+	return
+}
+
+func (rfr *regFileReader) Read(b []byte) (n int, err error) {
+	if rfr.nb == 0 {
+		// file consumed
+		return 0, io.EOF
+	}
+	if int64(len(b)) > rfr.nb {
+		b = b[0:rfr.nb]
+	}
+	n, err = rfr.r.Read(b)
+	rfr.nb -= int64(n)
+
+	if err == io.EOF && rfr.nb > 0 {
+		err = io.ErrUnexpectedEOF
+	}
+	return
+}
+
+// numBytes returns the number of bytes left to read in the file's data in the tar archive.
+func (rfr *regFileReader) numBytes() int64 {
+	return rfr.nb
+}
+
+// readHole reads a sparse file hole ending at offset toOffset
+func (sfr *sparseFileReader) readHole(b []byte, toOffset int64) int {
+	n64 := toOffset - sfr.pos
+	if n64 > int64(len(b)) {
+		n64 = int64(len(b))
+	}
+	n := int(n64)
+	for i := 0; i < n; i++ {
+		b[i] = 0
+	}
+	sfr.pos += n64
+	return n
+}
+
+// Read reads the sparse file data in expanded form.
+func (sfr *sparseFileReader) Read(b []byte) (n int, err error) {
+	if len(sfr.sp) == 0 {
+		// No more data fragments to read from.
+		if sfr.pos < sfr.tot {
+			// We're in the last hole
+			n = sfr.readHole(b, sfr.tot)
+			return
+		}
+		// Otherwise, we're at the end of the file
+		return 0, io.EOF
+	}
+	if sfr.pos < sfr.sp[0].offset {
+		// We're in a hole
+		n = sfr.readHole(b, sfr.sp[0].offset)
+		return
+	}
+
+	// We're not in a hole, so we'll read from the next data fragment
+	posInFragment := sfr.pos - sfr.sp[0].offset
+	bytesLeft := sfr.sp[0].numBytes - posInFragment
+	if int64(len(b)) > bytesLeft {
+		b = b[0:bytesLeft]
+	}
+
+	n, err = sfr.rfr.Read(b)
+	sfr.pos += int64(n)
+
+	if int64(n) == bytesLeft {
+		// We're done with this fragment
+		sfr.sp = sfr.sp[1:]
+	}
+
+	if err == io.EOF && sfr.pos < sfr.tot {
+		// We reached the end of the last fragment's data, but there's a final hole
+		err = nil
+	}
+	return
+}
+
+// numBytes returns the number of bytes left to read in the sparse file's
+// sparse-encoded data in the tar archive.
+func (sfr *sparseFileReader) numBytes() int64 {
+	return sfr.rfr.nb
+}
diff --git a/src/pkg/archive/tar/reader_test.go b/src/archive/tar/reader_test.go
similarity index 100%
rename from src/pkg/archive/tar/reader_test.go
rename to src/archive/tar/reader_test.go
diff --git a/src/pkg/archive/tar/stat_atim.go b/src/archive/tar/stat_atim.go
similarity index 100%
rename from src/pkg/archive/tar/stat_atim.go
rename to src/archive/tar/stat_atim.go
diff --git a/src/pkg/archive/tar/stat_atimespec.go b/src/archive/tar/stat_atimespec.go
similarity index 100%
rename from src/pkg/archive/tar/stat_atimespec.go
rename to src/archive/tar/stat_atimespec.go
diff --git a/src/pkg/archive/tar/stat_unix.go b/src/archive/tar/stat_unix.go
similarity index 100%
rename from src/pkg/archive/tar/stat_unix.go
rename to src/archive/tar/stat_unix.go
diff --git a/src/pkg/archive/tar/tar_test.go b/src/archive/tar/tar_test.go
similarity index 100%
rename from src/pkg/archive/tar/tar_test.go
rename to src/archive/tar/tar_test.go
diff --git a/src/pkg/archive/tar/testdata/gnu.tar b/src/archive/tar/testdata/gnu.tar
similarity index 100%
rename from src/pkg/archive/tar/testdata/gnu.tar
rename to src/archive/tar/testdata/gnu.tar
diff --git a/src/pkg/archive/tar/testdata/nil-uid.tar b/src/archive/tar/testdata/nil-uid.tar
similarity index 100%
rename from src/pkg/archive/tar/testdata/nil-uid.tar
rename to src/archive/tar/testdata/nil-uid.tar
diff --git a/src/pkg/archive/tar/testdata/pax.tar b/src/archive/tar/testdata/pax.tar
similarity index 100%
rename from src/pkg/archive/tar/testdata/pax.tar
rename to src/archive/tar/testdata/pax.tar
diff --git a/src/pkg/archive/tar/testdata/small.txt b/src/archive/tar/testdata/small.txt
similarity index 100%
rename from src/pkg/archive/tar/testdata/small.txt
rename to src/archive/tar/testdata/small.txt
diff --git a/src/pkg/archive/tar/testdata/small2.txt b/src/archive/tar/testdata/small2.txt
similarity index 100%
rename from src/pkg/archive/tar/testdata/small2.txt
rename to src/archive/tar/testdata/small2.txt
diff --git a/src/pkg/archive/tar/testdata/sparse-formats.tar b/src/archive/tar/testdata/sparse-formats.tar
similarity index 100%
rename from src/pkg/archive/tar/testdata/sparse-formats.tar
rename to src/archive/tar/testdata/sparse-formats.tar
diff --git a/src/pkg/archive/tar/testdata/star.tar b/src/archive/tar/testdata/star.tar
similarity index 100%
rename from src/pkg/archive/tar/testdata/star.tar
rename to src/archive/tar/testdata/star.tar
diff --git a/src/pkg/archive/tar/testdata/ustar.tar b/src/archive/tar/testdata/ustar.tar
similarity index 100%
rename from src/pkg/archive/tar/testdata/ustar.tar
rename to src/archive/tar/testdata/ustar.tar
diff --git a/src/pkg/archive/tar/testdata/v7.tar b/src/archive/tar/testdata/v7.tar
similarity index 100%
rename from src/pkg/archive/tar/testdata/v7.tar
rename to src/archive/tar/testdata/v7.tar
diff --git a/src/pkg/archive/tar/testdata/writer-big-long.tar b/src/archive/tar/testdata/writer-big-long.tar
similarity index 100%
rename from src/pkg/archive/tar/testdata/writer-big-long.tar
rename to src/archive/tar/testdata/writer-big-long.tar
diff --git a/src/pkg/archive/tar/testdata/writer-big.tar b/src/archive/tar/testdata/writer-big.tar
similarity index 100%
rename from src/pkg/archive/tar/testdata/writer-big.tar
rename to src/archive/tar/testdata/writer-big.tar
diff --git a/src/pkg/archive/tar/testdata/writer.tar b/src/archive/tar/testdata/writer.tar
similarity index 100%
rename from src/pkg/archive/tar/testdata/writer.tar
rename to src/archive/tar/testdata/writer.tar
diff --git a/src/pkg/archive/tar/testdata/xattrs.tar b/src/archive/tar/testdata/xattrs.tar
similarity index 100%
rename from src/pkg/archive/tar/testdata/xattrs.tar
rename to src/archive/tar/testdata/xattrs.tar
diff --git a/src/archive/tar/writer.go b/src/archive/tar/writer.go
new file mode 100644
index 0000000..dafb2ca
--- /dev/null
+++ b/src/archive/tar/writer.go
@@ -0,0 +1,396 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tar
+
+// TODO(dsymonds):
+// - catch more errors (no first header, etc.)
+
+import (
+	"bytes"
+	"errors"
+	"fmt"
+	"io"
+	"os"
+	"path"
+	"strconv"
+	"strings"
+	"time"
+)
+
+var (
+	ErrWriteTooLong    = errors.New("archive/tar: write too long")
+	ErrFieldTooLong    = errors.New("archive/tar: header field too long")
+	ErrWriteAfterClose = errors.New("archive/tar: write after close")
+	errNameTooLong     = errors.New("archive/tar: name too long")
+	errInvalidHeader   = errors.New("archive/tar: header field too long or contains invalid values")
+)
+
+// A Writer provides sequential writing of a tar archive in POSIX.1 format.
+// A tar archive consists of a sequence of files.
+// Call WriteHeader to begin a new file, and then call Write to supply that file's data,
+// writing at most hdr.Size bytes in total.
+type Writer struct {
+	w          io.Writer
+	err        error
+	nb         int64 // number of unwritten bytes for current file entry
+	pad        int64 // amount of padding to write after current file entry
+	closed     bool
+	usedBinary bool            // whether the binary numeric field extension was used
+	preferPax  bool            // use pax header instead of binary numeric header
+	hdrBuff    [blockSize]byte // buffer to use in writeHeader when writing a regular header
+	paxHdrBuff [blockSize]byte // buffer to use in writeHeader when writing a pax header
+}
+
+// NewWriter creates a new Writer writing to w.
+func NewWriter(w io.Writer) *Writer { return &Writer{w: w} }
+
+// Flush finishes writing the current file (optional).
+func (tw *Writer) Flush() error {
+	if tw.nb > 0 {
+		tw.err = fmt.Errorf("archive/tar: missed writing %d bytes", tw.nb)
+		return tw.err
+	}
+
+	n := tw.nb + tw.pad
+	for n > 0 && tw.err == nil {
+		nr := n
+		if nr > blockSize {
+			nr = blockSize
+		}
+		var nw int
+		nw, tw.err = tw.w.Write(zeroBlock[0:nr])
+		n -= int64(nw)
+	}
+	tw.nb = 0
+	tw.pad = 0
+	return tw.err
+}
+
+// Write s into b, terminating it with a NUL if there is room.
+// If the value is too long for the field and allowPax is true add a paxheader record instead
+func (tw *Writer) cString(b []byte, s string, allowPax bool, paxKeyword string, paxHeaders map[string]string) {
+	needsPaxHeader := allowPax && len(s) > len(b) || !isASCII(s)
+	if needsPaxHeader {
+		paxHeaders[paxKeyword] = s
+		return
+	}
+	if len(s) > len(b) {
+		if tw.err == nil {
+			tw.err = ErrFieldTooLong
+		}
+		return
+	}
+	ascii := toASCII(s)
+	copy(b, ascii)
+	if len(ascii) < len(b) {
+		b[len(ascii)] = 0
+	}
+}
+
+// Encode x as an octal ASCII string and write it into b with leading zeros.
+func (tw *Writer) octal(b []byte, x int64) {
+	s := strconv.FormatInt(x, 8)
+	// leading zeros, but leave room for a NUL.
+	for len(s)+1 < len(b) {
+		s = "0" + s
+	}
+	tw.cString(b, s, false, paxNone, nil)
+}
+
+// Write x into b, either as octal or as binary (GNUtar/star extension).
+// If the value is too long for the field and writingPax is enabled both for the field and the add a paxheader record instead
+func (tw *Writer) numeric(b []byte, x int64, allowPax bool, paxKeyword string, paxHeaders map[string]string) {
+	// Try octal first.
+	s := strconv.FormatInt(x, 8)
+	if len(s) < len(b) {
+		tw.octal(b, x)
+		return
+	}
+
+	// If it is too long for octal, and pax is preferred, use a pax header
+	if allowPax && tw.preferPax {
+		tw.octal(b, 0)
+		s := strconv.FormatInt(x, 10)
+		paxHeaders[paxKeyword] = s
+		return
+	}
+
+	// Too big: use binary (big-endian).
+	tw.usedBinary = true
+	for i := len(b) - 1; x > 0 && i >= 0; i-- {
+		b[i] = byte(x)
+		x >>= 8
+	}
+	b[0] |= 0x80 // highest bit indicates binary format
+}
+
+var (
+	minTime = time.Unix(0, 0)
+	// There is room for 11 octal digits (33 bits) of mtime.
+	maxTime = minTime.Add((1<<33 - 1) * time.Second)
+)
+
+// WriteHeader writes hdr and prepares to accept the file's contents.
+// WriteHeader calls Flush if it is not the first header.
+// Calling after a Close will return ErrWriteAfterClose.
+func (tw *Writer) WriteHeader(hdr *Header) error {
+	return tw.writeHeader(hdr, true)
+}
+
+// WriteHeader writes hdr and prepares to accept the file's contents.
+// WriteHeader calls Flush if it is not the first header.
+// Calling after a Close will return ErrWriteAfterClose.
+// As this method is called internally by writePax header to allow it to
+// suppress writing the pax header.
+func (tw *Writer) writeHeader(hdr *Header, allowPax bool) error {
+	if tw.closed {
+		return ErrWriteAfterClose
+	}
+	if tw.err == nil {
+		tw.Flush()
+	}
+	if tw.err != nil {
+		return tw.err
+	}
+
+	// a map to hold pax header records, if any are needed
+	paxHeaders := make(map[string]string)
+
+	// TODO(shanemhansen): we might want to use PAX headers for
+	// subsecond time resolution, but for now let's just capture
+	// too long fields or non ascii characters
+
+	var header []byte
+
+	// We need to select which scratch buffer to use carefully,
+	// since this method is called recursively to write PAX headers.
+	// If allowPax is true, this is the non-recursive call, and we will use hdrBuff.
+	// If allowPax is false, we are being called by writePAXHeader, and hdrBuff is
+	// already being used by the non-recursive call, so we must use paxHdrBuff.
+	header = tw.hdrBuff[:]
+	if !allowPax {
+		header = tw.paxHdrBuff[:]
+	}
+	copy(header, zeroBlock)
+	s := slicer(header)
+
+	// keep a reference to the filename to allow to overwrite it later if we detect that we can use ustar longnames instead of pax
+	pathHeaderBytes := s.next(fileNameSize)
+
+	tw.cString(pathHeaderBytes, hdr.Name, true, paxPath, paxHeaders)
+
+	// Handle out of range ModTime carefully.
+	var modTime int64
+	if !hdr.ModTime.Before(minTime) && !hdr.ModTime.After(maxTime) {
+		modTime = hdr.ModTime.Unix()
+	}
+
+	tw.octal(s.next(8), hdr.Mode)                                   // 100:108
+	tw.numeric(s.next(8), int64(hdr.Uid), true, paxUid, paxHeaders) // 108:116
+	tw.numeric(s.next(8), int64(hdr.Gid), true, paxGid, paxHeaders) // 116:124
+	tw.numeric(s.next(12), hdr.Size, true, paxSize, paxHeaders)     // 124:136
+	tw.numeric(s.next(12), modTime, false, paxNone, nil)            // 136:148 --- consider using pax for finer granularity
+	s.next(8)                                                       // chksum (148:156)
+	s.next(1)[0] = hdr.Typeflag                                     // 156:157
+
+	tw.cString(s.next(100), hdr.Linkname, true, paxLinkpath, paxHeaders)
+
+	copy(s.next(8), []byte("ustar\x0000"))                        // 257:265
+	tw.cString(s.next(32), hdr.Uname, true, paxUname, paxHeaders) // 265:297
+	tw.cString(s.next(32), hdr.Gname, true, paxGname, paxHeaders) // 297:329
+	tw.numeric(s.next(8), hdr.Devmajor, false, paxNone, nil)      // 329:337
+	tw.numeric(s.next(8), hdr.Devminor, false, paxNone, nil)      // 337:345
+
+	// keep a reference to the prefix to allow to overwrite it later if we detect that we can use ustar longnames instead of pax
+	prefixHeaderBytes := s.next(155)
+	tw.cString(prefixHeaderBytes, "", false, paxNone, nil) // 345:500  prefix
+
+	// Use the GNU magic instead of POSIX magic if we used any GNU extensions.
+	if tw.usedBinary {
+		copy(header[257:265], []byte("ustar  \x00"))
+	}
+
+	_, paxPathUsed := paxHeaders[paxPath]
+	// try to use a ustar header when only the name is too long
+	if !tw.preferPax && len(paxHeaders) == 1 && paxPathUsed {
+		suffix := hdr.Name
+		prefix := ""
+		if len(hdr.Name) > fileNameSize && isASCII(hdr.Name) {
+			var err error
+			prefix, suffix, err = tw.splitUSTARLongName(hdr.Name)
+			if err == nil {
+				// ok we can use a ustar long name instead of pax, now correct the fields
+
+				// remove the path field from the pax header. this will suppress the pax header
+				delete(paxHeaders, paxPath)
+
+				// update the path fields
+				tw.cString(pathHeaderBytes, suffix, false, paxNone, nil)
+				tw.cString(prefixHeaderBytes, prefix, false, paxNone, nil)
+
+				// Use the ustar magic if we used ustar long names.
+				if len(prefix) > 0 && !tw.usedBinary {
+					copy(header[257:265], []byte("ustar\x00"))
+				}
+			}
+		}
+	}
+
+	// The chksum field is terminated by a NUL and a space.
+	// This is different from the other octal fields.
+	chksum, _ := checksum(header)
+	tw.octal(header[148:155], chksum)
+	header[155] = ' '
+
+	if tw.err != nil {
+		// problem with header; probably integer too big for a field.
+		return tw.err
+	}
+
+	if allowPax {
+		for k, v := range hdr.Xattrs {
+			paxHeaders[paxXattr+k] = v
+		}
+	}
+
+	if len(paxHeaders) > 0 {
+		if !allowPax {
+			return errInvalidHeader
+		}
+		if err := tw.writePAXHeader(hdr, paxHeaders); err != nil {
+			return err
+		}
+	}
+	tw.nb = int64(hdr.Size)
+	tw.pad = (blockSize - (tw.nb % blockSize)) % blockSize
+
+	_, tw.err = tw.w.Write(header)
+	return tw.err
+}
+
+// writeUSTARLongName splits a USTAR long name hdr.Name.
+// name must be < 256 characters. errNameTooLong is returned
+// if hdr.Name can't be split. The splitting heuristic
+// is compatible with gnu tar.
+func (tw *Writer) splitUSTARLongName(name string) (prefix, suffix string, err error) {
+	length := len(name)
+	if length > fileNamePrefixSize+1 {
+		length = fileNamePrefixSize + 1
+	} else if name[length-1] == '/' {
+		length--
+	}
+	i := strings.LastIndex(name[:length], "/")
+	// nlen contains the resulting length in the name field.
+	// plen contains the resulting length in the prefix field.
+	nlen := len(name) - i - 1
+	plen := i
+	if i <= 0 || nlen > fileNameSize || nlen == 0 || plen > fileNamePrefixSize {
+		err = errNameTooLong
+		return
+	}
+	prefix, suffix = name[:i], name[i+1:]
+	return
+}
+
+// writePaxHeader writes an extended pax header to the
+// archive.
+func (tw *Writer) writePAXHeader(hdr *Header, paxHeaders map[string]string) error {
+	// Prepare extended header
+	ext := new(Header)
+	ext.Typeflag = TypeXHeader
+	// Setting ModTime is required for reader parsing to
+	// succeed, and seems harmless enough.
+	ext.ModTime = hdr.ModTime
+	// The spec asks that we namespace our pseudo files
+	// with the current pid.
+	pid := os.Getpid()
+	dir, file := path.Split(hdr.Name)
+	fullName := path.Join(dir,
+		fmt.Sprintf("PaxHeaders.%d", pid), file)
+
+	ascii := toASCII(fullName)
+	if len(ascii) > 100 {
+		ascii = ascii[:100]
+	}
+	ext.Name = ascii
+	// Construct the body
+	var buf bytes.Buffer
+
+	for k, v := range paxHeaders {
+		fmt.Fprint(&buf, paxHeader(k+"="+v))
+	}
+
+	ext.Size = int64(len(buf.Bytes()))
+	if err := tw.writeHeader(ext, false); err != nil {
+		return err
+	}
+	if _, err := tw.Write(buf.Bytes()); err != nil {
+		return err
+	}
+	if err := tw.Flush(); err != nil {
+		return err
+	}
+	return nil
+}
+
+// paxHeader formats a single pax record, prefixing it with the appropriate length
+func paxHeader(msg string) string {
+	const padding = 2 // Extra padding for space and newline
+	size := len(msg) + padding
+	size += len(strconv.Itoa(size))
+	record := fmt.Sprintf("%d %s\n", size, msg)
+	if len(record) != size {
+		// Final adjustment if adding size increased
+		// the number of digits in size
+		size = len(record)
+		record = fmt.Sprintf("%d %s\n", size, msg)
+	}
+	return record
+}
+
+// Write writes to the current entry in the tar archive.
+// Write returns the error ErrWriteTooLong if more than
+// hdr.Size bytes are written after WriteHeader.
+func (tw *Writer) Write(b []byte) (n int, err error) {
+	if tw.closed {
+		err = ErrWriteTooLong
+		return
+	}
+	overwrite := false
+	if int64(len(b)) > tw.nb {
+		b = b[0:tw.nb]
+		overwrite = true
+	}
+	n, err = tw.w.Write(b)
+	tw.nb -= int64(n)
+	if err == nil && overwrite {
+		err = ErrWriteTooLong
+		return
+	}
+	tw.err = err
+	return
+}
+
+// Close closes the tar archive, flushing any unwritten
+// data to the underlying writer.
+func (tw *Writer) Close() error {
+	if tw.err != nil || tw.closed {
+		return tw.err
+	}
+	tw.Flush()
+	tw.closed = true
+	if tw.err != nil {
+		return tw.err
+	}
+
+	// trailer: two zero blocks
+	for i := 0; i < 2; i++ {
+		_, tw.err = tw.w.Write(zeroBlock)
+		if tw.err != nil {
+			break
+		}
+	}
+	return tw.err
+}
diff --git a/src/archive/tar/writer_test.go b/src/archive/tar/writer_test.go
new file mode 100644
index 0000000..5e42e32
--- /dev/null
+++ b/src/archive/tar/writer_test.go
@@ -0,0 +1,491 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tar
+
+import (
+	"bytes"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"os"
+	"reflect"
+	"strings"
+	"testing"
+	"testing/iotest"
+	"time"
+)
+
+type writerTestEntry struct {
+	header   *Header
+	contents string
+}
+
+type writerTest struct {
+	file    string // filename of expected output
+	entries []*writerTestEntry
+}
+
+var writerTests = []*writerTest{
+	// The writer test file was produced with this command:
+	// tar (GNU tar) 1.26
+	//   ln -s small.txt link.txt
+	//   tar -b 1 --format=ustar -c -f writer.tar small.txt small2.txt link.txt
+	{
+		file: "testdata/writer.tar",
+		entries: []*writerTestEntry{
+			{
+				header: &Header{
+					Name:     "small.txt",
+					Mode:     0640,
+					Uid:      73025,
+					Gid:      5000,
+					Size:     5,
+					ModTime:  time.Unix(1246508266, 0),
+					Typeflag: '0',
+					Uname:    "dsymonds",
+					Gname:    "eng",
+				},
+				contents: "Kilts",
+			},
+			{
+				header: &Header{
+					Name:     "small2.txt",
+					Mode:     0640,
+					Uid:      73025,
+					Gid:      5000,
+					Size:     11,
+					ModTime:  time.Unix(1245217492, 0),
+					Typeflag: '0',
+					Uname:    "dsymonds",
+					Gname:    "eng",
+				},
+				contents: "Google.com\n",
+			},
+			{
+				header: &Header{
+					Name:     "link.txt",
+					Mode:     0777,
+					Uid:      1000,
+					Gid:      1000,
+					Size:     0,
+					ModTime:  time.Unix(1314603082, 0),
+					Typeflag: '2',
+					Linkname: "small.txt",
+					Uname:    "strings",
+					Gname:    "strings",
+				},
+				// no contents
+			},
+		},
+	},
+	// The truncated test file was produced using these commands:
+	//   dd if=/dev/zero bs=1048576 count=16384 > /tmp/16gig.txt
+	//   tar -b 1 -c -f- /tmp/16gig.txt | dd bs=512 count=8 > writer-big.tar
+	{
+		file: "testdata/writer-big.tar",
+		entries: []*writerTestEntry{
+			{
+				header: &Header{
+					Name:     "tmp/16gig.txt",
+					Mode:     0640,
+					Uid:      73025,
+					Gid:      5000,
+					Size:     16 << 30,
+					ModTime:  time.Unix(1254699560, 0),
+					Typeflag: '0',
+					Uname:    "dsymonds",
+					Gname:    "eng",
+				},
+				// fake contents
+				contents: strings.Repeat("\x00", 4<<10),
+			},
+		},
+	},
+	// The truncated test file was produced using these commands:
+	//   dd if=/dev/zero bs=1048576 count=16384 > (longname/)*15 /16gig.txt
+	//   tar -b 1 -c -f- (longname/)*15 /16gig.txt | dd bs=512 count=8 > writer-big-long.tar
+	{
+		file: "testdata/writer-big-long.tar",
+		entries: []*writerTestEntry{
+			{
+				header: &Header{
+					Name:     strings.Repeat("longname/", 15) + "16gig.txt",
+					Mode:     0644,
+					Uid:      1000,
+					Gid:      1000,
+					Size:     16 << 30,
+					ModTime:  time.Unix(1399583047, 0),
+					Typeflag: '0',
+					Uname:    "guillaume",
+					Gname:    "guillaume",
+				},
+				// fake contents
+				contents: strings.Repeat("\x00", 4<<10),
+			},
+		},
+	},
+	// This file was produced using gnu tar 1.17
+	// gnutar  -b 4 --format=ustar (longname/)*15 + file.txt
+	{
+		file: "testdata/ustar.tar",
+		entries: []*writerTestEntry{
+			{
+				header: &Header{
+					Name:     strings.Repeat("longname/", 15) + "file.txt",
+					Mode:     0644,
+					Uid:      0765,
+					Gid:      024,
+					Size:     06,
+					ModTime:  time.Unix(1360135598, 0),
+					Typeflag: '0',
+					Uname:    "shane",
+					Gname:    "staff",
+				},
+				contents: "hello\n",
+			},
+		},
+	},
+}
+
+// Render byte array in a two-character hexadecimal string, spaced for easy visual inspection.
+func bytestr(offset int, b []byte) string {
+	const rowLen = 32
+	s := fmt.Sprintf("%04x ", offset)
+	for _, ch := range b {
+		switch {
+		case '0' <= ch && ch <= '9', 'A' <= ch && ch <= 'Z', 'a' <= ch && ch <= 'z':
+			s += fmt.Sprintf("  %c", ch)
+		default:
+			s += fmt.Sprintf(" %02x", ch)
+		}
+	}
+	return s
+}
+
+// Render a pseudo-diff between two blocks of bytes.
+func bytediff(a []byte, b []byte) string {
+	const rowLen = 32
+	s := fmt.Sprintf("(%d bytes vs. %d bytes)\n", len(a), len(b))
+	for offset := 0; len(a)+len(b) > 0; offset += rowLen {
+		na, nb := rowLen, rowLen
+		if na > len(a) {
+			na = len(a)
+		}
+		if nb > len(b) {
+			nb = len(b)
+		}
+		sa := bytestr(offset, a[0:na])
+		sb := bytestr(offset, b[0:nb])
+		if sa != sb {
+			s += fmt.Sprintf("-%v\n+%v\n", sa, sb)
+		}
+		a = a[na:]
+		b = b[nb:]
+	}
+	return s
+}
+
+func TestWriter(t *testing.T) {
+testLoop:
+	for i, test := range writerTests {
+		expected, err := ioutil.ReadFile(test.file)
+		if err != nil {
+			t.Errorf("test %d: Unexpected error: %v", i, err)
+			continue
+		}
+
+		buf := new(bytes.Buffer)
+		tw := NewWriter(iotest.TruncateWriter(buf, 4<<10)) // only catch the first 4 KB
+		big := false
+		for j, entry := range test.entries {
+			big = big || entry.header.Size > 1<<10
+			if err := tw.WriteHeader(entry.header); err != nil {
+				t.Errorf("test %d, entry %d: Failed writing header: %v", i, j, err)
+				continue testLoop
+			}
+			if _, err := io.WriteString(tw, entry.contents); err != nil {
+				t.Errorf("test %d, entry %d: Failed writing contents: %v", i, j, err)
+				continue testLoop
+			}
+		}
+		// Only interested in Close failures for the small tests.
+		if err := tw.Close(); err != nil && !big {
+			t.Errorf("test %d: Failed closing archive: %v", i, err)
+			continue testLoop
+		}
+
+		actual := buf.Bytes()
+		if !bytes.Equal(expected, actual) {
+			t.Errorf("test %d: Incorrect result: (-=expected, +=actual)\n%v",
+				i, bytediff(expected, actual))
+		}
+		if testing.Short() { // The second test is expensive.
+			break
+		}
+	}
+}
+
+func TestPax(t *testing.T) {
+	// Create an archive with a large name
+	fileinfo, err := os.Stat("testdata/small.txt")
+	if err != nil {
+		t.Fatal(err)
+	}
+	hdr, err := FileInfoHeader(fileinfo, "")
+	if err != nil {
+		t.Fatalf("os.Stat: %v", err)
+	}
+	// Force a PAX long name to be written
+	longName := strings.Repeat("ab", 100)
+	contents := strings.Repeat(" ", int(hdr.Size))
+	hdr.Name = longName
+	var buf bytes.Buffer
+	writer := NewWriter(&buf)
+	if err := writer.WriteHeader(hdr); err != nil {
+		t.Fatal(err)
+	}
+	if _, err = writer.Write([]byte(contents)); err != nil {
+		t.Fatal(err)
+	}
+	if err := writer.Close(); err != nil {
+		t.Fatal(err)
+	}
+	// Simple test to make sure PAX extensions are in effect
+	if !bytes.Contains(buf.Bytes(), []byte("PaxHeaders.")) {
+		t.Fatal("Expected at least one PAX header to be written.")
+	}
+	// Test that we can get a long name back out of the archive.
+	reader := NewReader(&buf)
+	hdr, err = reader.Next()
+	if err != nil {
+		t.Fatal(err)
+	}
+	if hdr.Name != longName {
+		t.Fatal("Couldn't recover long file name")
+	}
+}
+
+func TestPaxSymlink(t *testing.T) {
+	// Create an archive with a large linkname
+	fileinfo, err := os.Stat("testdata/small.txt")
+	if err != nil {
+		t.Fatal(err)
+	}
+	hdr, err := FileInfoHeader(fileinfo, "")
+	hdr.Typeflag = TypeSymlink
+	if err != nil {
+		t.Fatalf("os.Stat:1 %v", err)
+	}
+	// Force a PAX long linkname to be written
+	longLinkname := strings.Repeat("1234567890/1234567890", 10)
+	hdr.Linkname = longLinkname
+
+	hdr.Size = 0
+	var buf bytes.Buffer
+	writer := NewWriter(&buf)
+	if err := writer.WriteHeader(hdr); err != nil {
+		t.Fatal(err)
+	}
+	if err := writer.Close(); err != nil {
+		t.Fatal(err)
+	}
+	// Simple test to make sure PAX extensions are in effect
+	if !bytes.Contains(buf.Bytes(), []byte("PaxHeaders.")) {
+		t.Fatal("Expected at least one PAX header to be written.")
+	}
+	// Test that we can get a long name back out of the archive.
+	reader := NewReader(&buf)
+	hdr, err = reader.Next()
+	if err != nil {
+		t.Fatal(err)
+	}
+	if hdr.Linkname != longLinkname {
+		t.Fatal("Couldn't recover long link name")
+	}
+}
+
+func TestPaxNonAscii(t *testing.T) {
+	// Create an archive with non ascii. These should trigger a pax header
+	// because pax headers have a defined utf-8 encoding.
+	fileinfo, err := os.Stat("testdata/small.txt")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	hdr, err := FileInfoHeader(fileinfo, "")
+	if err != nil {
+		t.Fatalf("os.Stat:1 %v", err)
+	}
+
+	// some sample data
+	chineseFilename := "文件名"
+	chineseGroupname := "組"
+	chineseUsername := "用戶名"
+
+	hdr.Name = chineseFilename
+	hdr.Gname = chineseGroupname
+	hdr.Uname = chineseUsername
+
+	contents := strings.Repeat(" ", int(hdr.Size))
+
+	var buf bytes.Buffer
+	writer := NewWriter(&buf)
+	if err := writer.WriteHeader(hdr); err != nil {
+		t.Fatal(err)
+	}
+	if _, err = writer.Write([]byte(contents)); err != nil {
+		t.Fatal(err)
+	}
+	if err := writer.Close(); err != nil {
+		t.Fatal(err)
+	}
+	// Simple test to make sure PAX extensions are in effect
+	if !bytes.Contains(buf.Bytes(), []byte("PaxHeaders.")) {
+		t.Fatal("Expected at least one PAX header to be written.")
+	}
+	// Test that we can get a long name back out of the archive.
+	reader := NewReader(&buf)
+	hdr, err = reader.Next()
+	if err != nil {
+		t.Fatal(err)
+	}
+	if hdr.Name != chineseFilename {
+		t.Fatal("Couldn't recover unicode name")
+	}
+	if hdr.Gname != chineseGroupname {
+		t.Fatal("Couldn't recover unicode group")
+	}
+	if hdr.Uname != chineseUsername {
+		t.Fatal("Couldn't recover unicode user")
+	}
+}
+
+func TestPaxXattrs(t *testing.T) {
+	xattrs := map[string]string{
+		"user.key": "value",
+	}
+
+	// Create an archive with an xattr
+	fileinfo, err := os.Stat("testdata/small.txt")
+	if err != nil {
+		t.Fatal(err)
+	}
+	hdr, err := FileInfoHeader(fileinfo, "")
+	if err != nil {
+		t.Fatalf("os.Stat: %v", err)
+	}
+	contents := "Kilts"
+	hdr.Xattrs = xattrs
+	var buf bytes.Buffer
+	writer := NewWriter(&buf)
+	if err := writer.WriteHeader(hdr); err != nil {
+		t.Fatal(err)
+	}
+	if _, err = writer.Write([]byte(contents)); err != nil {
+		t.Fatal(err)
+	}
+	if err := writer.Close(); err != nil {
+		t.Fatal(err)
+	}
+	// Test that we can get the xattrs back out of the archive.
+	reader := NewReader(&buf)
+	hdr, err = reader.Next()
+	if err != nil {
+		t.Fatal(err)
+	}
+	if !reflect.DeepEqual(hdr.Xattrs, xattrs) {
+		t.Fatalf("xattrs did not survive round trip: got %+v, want %+v",
+			hdr.Xattrs, xattrs)
+	}
+}
+
+func TestPAXHeader(t *testing.T) {
+	medName := strings.Repeat("CD", 50)
+	longName := strings.Repeat("AB", 100)
+	paxTests := [][2]string{
+		{paxPath + "=/etc/hosts", "19 path=/etc/hosts\n"},
+		{"a=b", "6 a=b\n"},          // Single digit length
+		{"a=names", "11 a=names\n"}, // Test case involving carries
+		{paxPath + "=" + longName, fmt.Sprintf("210 path=%s\n", longName)},
+		{paxPath + "=" + medName, fmt.Sprintf("110 path=%s\n", medName)}}
+
+	for _, test := range paxTests {
+		key, expected := test[0], test[1]
+		if result := paxHeader(key); result != expected {
+			t.Fatalf("paxHeader: got %s, expected %s", result, expected)
+		}
+	}
+}
+
+func TestUSTARLongName(t *testing.T) {
+	// Create an archive with a path that failed to split with USTAR extension in previous versions.
+	fileinfo, err := os.Stat("testdata/small.txt")
+	if err != nil {
+		t.Fatal(err)
+	}
+	hdr, err := FileInfoHeader(fileinfo, "")
+	hdr.Typeflag = TypeDir
+	if err != nil {
+		t.Fatalf("os.Stat:1 %v", err)
+	}
+	// Force a PAX long name to be written. The name was taken from a practical example
+	// that fails and replaced ever char through numbers to anonymize the sample.
+	longName := "/0000_0000000/00000-000000000/0000_0000000/00000-0000000000000/0000_0000000/00000-0000000-00000000/0000_0000000/00000000/0000_0000000/000/0000_0000000/00000000v00/0000_0000000/000000/0000_0000000/0000000/0000_0000000/00000y-00/0000/0000/00000000/0x000000/"
+	hdr.Name = longName
+
+	hdr.Size = 0
+	var buf bytes.Buffer
+	writer := NewWriter(&buf)
+	if err := writer.WriteHeader(hdr); err != nil {
+		t.Fatal(err)
+	}
+	if err := writer.Close(); err != nil {
+		t.Fatal(err)
+	}
+	// Test that we can get a long name back out of the archive.
+	reader := NewReader(&buf)
+	hdr, err = reader.Next()
+	if err != nil {
+		t.Fatal(err)
+	}
+	if hdr.Name != longName {
+		t.Fatal("Couldn't recover long name")
+	}
+}
+
+func TestValidTypeflagWithPAXHeader(t *testing.T) {
+	var buffer bytes.Buffer
+	tw := NewWriter(&buffer)
+
+	fileName := strings.Repeat("ab", 100)
+
+	hdr := &Header{
+		Name:     fileName,
+		Size:     4,
+		Typeflag: 0,
+	}
+	if err := tw.WriteHeader(hdr); err != nil {
+		t.Fatalf("Failed to write header: %s", err)
+	}
+	if _, err := tw.Write([]byte("fooo")); err != nil {
+		t.Fatalf("Failed to write the file's data: %s", err)
+	}
+	tw.Close()
+
+	tr := NewReader(&buffer)
+
+	for {
+		header, err := tr.Next()
+		if err == io.EOF {
+			break
+		}
+		if err != nil {
+			t.Fatalf("Failed to read header: %s", err)
+		}
+		if header.Typeflag != 0 {
+			t.Fatalf("Typeflag should've been 0, found %d", header.Typeflag)
+		}
+	}
+}
diff --git a/src/pkg/archive/zip/example_test.go b/src/archive/zip/example_test.go
similarity index 100%
rename from src/pkg/archive/zip/example_test.go
rename to src/archive/zip/example_test.go
diff --git a/src/archive/zip/reader.go b/src/archive/zip/reader.go
new file mode 100644
index 0000000..8136b84
--- /dev/null
+++ b/src/archive/zip/reader.go
@@ -0,0 +1,453 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package zip
+
+import (
+	"bufio"
+	"encoding/binary"
+	"errors"
+	"hash"
+	"hash/crc32"
+	"io"
+	"os"
+)
+
+var (
+	ErrFormat    = errors.New("zip: not a valid zip file")
+	ErrAlgorithm = errors.New("zip: unsupported compression algorithm")
+	ErrChecksum  = errors.New("zip: checksum error")
+)
+
+type Reader struct {
+	r       io.ReaderAt
+	File    []*File
+	Comment string
+}
+
+type ReadCloser struct {
+	f *os.File
+	Reader
+}
+
+type File struct {
+	FileHeader
+	zipr         io.ReaderAt
+	zipsize      int64
+	headerOffset int64
+}
+
+func (f *File) hasDataDescriptor() bool {
+	return f.Flags&0x8 != 0
+}
+
+// OpenReader will open the Zip file specified by name and return a ReadCloser.
+func OpenReader(name string) (*ReadCloser, error) {
+	f, err := os.Open(name)
+	if err != nil {
+		return nil, err
+	}
+	fi, err := f.Stat()
+	if err != nil {
+		f.Close()
+		return nil, err
+	}
+	r := new(ReadCloser)
+	if err := r.init(f, fi.Size()); err != nil {
+		f.Close()
+		return nil, err
+	}
+	r.f = f
+	return r, nil
+}
+
+// NewReader returns a new Reader reading from r, which is assumed to
+// have the given size in bytes.
+func NewReader(r io.ReaderAt, size int64) (*Reader, error) {
+	zr := new(Reader)
+	if err := zr.init(r, size); err != nil {
+		return nil, err
+	}
+	return zr, nil
+}
+
+func (z *Reader) init(r io.ReaderAt, size int64) error {
+	end, err := readDirectoryEnd(r, size)
+	if err != nil {
+		return err
+	}
+	z.r = r
+	z.File = make([]*File, 0, end.directoryRecords)
+	z.Comment = end.comment
+	rs := io.NewSectionReader(r, 0, size)
+	if _, err = rs.Seek(int64(end.directoryOffset), os.SEEK_SET); err != nil {
+		return err
+	}
+	buf := bufio.NewReader(rs)
+
+	// The count of files inside a zip is truncated to fit in a uint16.
+	// Gloss over this by reading headers until we encounter
+	// a bad one, and then only report a ErrFormat or UnexpectedEOF if
+	// the file count modulo 65536 is incorrect.
+	for {
+		f := &File{zipr: r, zipsize: size}
+		err = readDirectoryHeader(f, buf)
+		if err == ErrFormat || err == io.ErrUnexpectedEOF {
+			break
+		}
+		if err != nil {
+			return err
+		}
+		z.File = append(z.File, f)
+	}
+	if uint16(len(z.File)) != uint16(end.directoryRecords) { // only compare 16 bits here
+		// Return the readDirectoryHeader error if we read
+		// the wrong number of directory entries.
+		return err
+	}
+	return nil
+}
+
+// Close closes the Zip file, rendering it unusable for I/O.
+func (rc *ReadCloser) Close() error {
+	return rc.f.Close()
+}
+
+// DataOffset returns the offset of the file's possibly-compressed
+// data, relative to the beginning of the zip file.
+//
+// Most callers should instead use Open, which transparently
+// decompresses data and verifies checksums.
+func (f *File) DataOffset() (offset int64, err error) {
+	bodyOffset, err := f.findBodyOffset()
+	if err != nil {
+		return
+	}
+	return f.headerOffset + bodyOffset, nil
+}
+
+// Open returns a ReadCloser that provides access to the File's contents.
+// Multiple files may be read concurrently.
+func (f *File) Open() (rc io.ReadCloser, err error) {
+	bodyOffset, err := f.findBodyOffset()
+	if err != nil {
+		return
+	}
+	size := int64(f.CompressedSize64)
+	r := io.NewSectionReader(f.zipr, f.headerOffset+bodyOffset, size)
+	dcomp := decompressor(f.Method)
+	if dcomp == nil {
+		err = ErrAlgorithm
+		return
+	}
+	rc = dcomp(r)
+	var desr io.Reader
+	if f.hasDataDescriptor() {
+		desr = io.NewSectionReader(f.zipr, f.headerOffset+bodyOffset+size, dataDescriptorLen)
+	}
+	rc = &checksumReader{rc, crc32.NewIEEE(), f, desr, nil}
+	return
+}
+
+type checksumReader struct {
+	rc   io.ReadCloser
+	hash hash.Hash32
+	f    *File
+	desr io.Reader // if non-nil, where to read the data descriptor
+	err  error     // sticky error
+}
+
+func (r *checksumReader) Read(b []byte) (n int, err error) {
+	if r.err != nil {
+		return 0, r.err
+	}
+	n, err = r.rc.Read(b)
+	r.hash.Write(b[:n])
+	if err == nil {
+		return
+	}
+	if err == io.EOF {
+		if r.desr != nil {
+			if err1 := readDataDescriptor(r.desr, r.f); err1 != nil {
+				err = err1
+			} else if r.hash.Sum32() != r.f.CRC32 {
+				err = ErrChecksum
+			}
+		} else {
+			// If there's not a data descriptor, we still compare
+			// the CRC32 of what we've read against the file header
+			// or TOC's CRC32, if it seems like it was set.
+			if r.f.CRC32 != 0 && r.hash.Sum32() != r.f.CRC32 {
+				err = ErrChecksum
+			}
+		}
+	}
+	r.err = err
+	return
+}
+
+func (r *checksumReader) Close() error { return r.rc.Close() }
+
+// findBodyOffset does the minimum work to verify the file has a header
+// and returns the file body offset.
+func (f *File) findBodyOffset() (int64, error) {
+	var buf [fileHeaderLen]byte
+	if _, err := f.zipr.ReadAt(buf[:], f.headerOffset); err != nil {
+		return 0, err
+	}
+	b := readBuf(buf[:])
+	if sig := b.uint32(); sig != fileHeaderSignature {
+		return 0, ErrFormat
+	}
+	b = b[22:] // skip over most of the header
+	filenameLen := int(b.uint16())
+	extraLen := int(b.uint16())
+	return int64(fileHeaderLen + filenameLen + extraLen), nil
+}
+
+// readDirectoryHeader attempts to read a directory header from r.
+// It returns io.ErrUnexpectedEOF if it cannot read a complete header,
+// and ErrFormat if it doesn't find a valid header signature.
+func readDirectoryHeader(f *File, r io.Reader) error {
+	var buf [directoryHeaderLen]byte
+	if _, err := io.ReadFull(r, buf[:]); err != nil {
+		return err
+	}
+	b := readBuf(buf[:])
+	if sig := b.uint32(); sig != directoryHeaderSignature {
+		return ErrFormat
+	}
+	f.CreatorVersion = b.uint16()
+	f.ReaderVersion = b.uint16()
+	f.Flags = b.uint16()
+	f.Method = b.uint16()
+	f.ModifiedTime = b.uint16()
+	f.ModifiedDate = b.uint16()
+	f.CRC32 = b.uint32()
+	f.CompressedSize = b.uint32()
+	f.UncompressedSize = b.uint32()
+	f.CompressedSize64 = uint64(f.CompressedSize)
+	f.UncompressedSize64 = uint64(f.UncompressedSize)
+	filenameLen := int(b.uint16())
+	extraLen := int(b.uint16())
+	commentLen := int(b.uint16())
+	b = b[4:] // skipped start disk number and internal attributes (2x uint16)
+	f.ExternalAttrs = b.uint32()
+	f.headerOffset = int64(b.uint32())
+	d := make([]byte, filenameLen+extraLen+commentLen)
+	if _, err := io.ReadFull(r, d); err != nil {
+		return err
+	}
+	f.Name = string(d[:filenameLen])
+	f.Extra = d[filenameLen : filenameLen+extraLen]
+	f.Comment = string(d[filenameLen+extraLen:])
+
+	if len(f.Extra) > 0 {
+		b := readBuf(f.Extra)
+		for len(b) >= 4 { // need at least tag and size
+			tag := b.uint16()
+			size := b.uint16()
+			if int(size) > len(b) {
+				return ErrFormat
+			}
+			if tag == zip64ExtraId {
+				// update directory values from the zip64 extra block
+				eb := readBuf(b[:size])
+				if len(eb) >= 8 {
+					f.UncompressedSize64 = eb.uint64()
+				}
+				if len(eb) >= 8 {
+					f.CompressedSize64 = eb.uint64()
+				}
+				if len(eb) >= 8 {
+					f.headerOffset = int64(eb.uint64())
+				}
+			}
+			b = b[size:]
+		}
+		// Should have consumed the whole header.
+		// But popular zip & JAR creation tools are broken and
+		// may pad extra zeros at the end, so accept those
+		// too. See golang.org/issue/8186.
+		for _, v := range b {
+			if v != 0 {
+				return ErrFormat
+			}
+		}
+	}
+	return nil
+}
+
+func readDataDescriptor(r io.Reader, f *File) error {
+	var buf [dataDescriptorLen]byte
+
+	// The spec says: "Although not originally assigned a
+	// signature, the value 0x08074b50 has commonly been adopted
+	// as a signature value for the data descriptor record.
+	// Implementers should be aware that ZIP files may be
+	// encountered with or without this signature marking data
+	// descriptors and should account for either case when reading
+	// ZIP files to ensure compatibility."
+	//
+	// dataDescriptorLen includes the size of the signature but
+	// first read just those 4 bytes to see if it exists.
+	if _, err := io.ReadFull(r, buf[:4]); err != nil {
+		return err
+	}
+	off := 0
+	maybeSig := readBuf(buf[:4])
+	if maybeSig.uint32() != dataDescriptorSignature {
+		// No data descriptor signature. Keep these four
+		// bytes.
+		off += 4
+	}
+	if _, err := io.ReadFull(r, buf[off:12]); err != nil {
+		return err
+	}
+	b := readBuf(buf[:12])
+	if b.uint32() != f.CRC32 {
+		return ErrChecksum
+	}
+
+	// The two sizes that follow here can be either 32 bits or 64 bits
+	// but the spec is not very clear on this and different
+	// interpretations has been made causing incompatibilities. We
+	// already have the sizes from the central directory so we can
+	// just ignore these.
+
+	return nil
+}
+
+func readDirectoryEnd(r io.ReaderAt, size int64) (dir *directoryEnd, err error) {
+	// look for directoryEndSignature in the last 1k, then in the last 65k
+	var buf []byte
+	var directoryEndOffset int64
+	for i, bLen := range []int64{1024, 65 * 1024} {
+		if bLen > size {
+			bLen = size
+		}
+		buf = make([]byte, int(bLen))
+		if _, err := r.ReadAt(buf, size-bLen); err != nil && err != io.EOF {
+			return nil, err
+		}
+		if p := findSignatureInBlock(buf); p >= 0 {
+			buf = buf[p:]
+			directoryEndOffset = size - bLen + int64(p)
+			break
+		}
+		if i == 1 || bLen == size {
+			return nil, ErrFormat
+		}
+	}
+
+	// read header into struct
+	b := readBuf(buf[4:]) // skip signature
+	d := &directoryEnd{
+		diskNbr:            uint32(b.uint16()),
+		dirDiskNbr:         uint32(b.uint16()),
+		dirRecordsThisDisk: uint64(b.uint16()),
+		directoryRecords:   uint64(b.uint16()),
+		directorySize:      uint64(b.uint32()),
+		directoryOffset:    uint64(b.uint32()),
+		commentLen:         b.uint16(),
+	}
+	l := int(d.commentLen)
+	if l > len(b) {
+		return nil, errors.New("zip: invalid comment length")
+	}
+	d.comment = string(b[:l])
+
+	p, err := findDirectory64End(r, directoryEndOffset)
+	if err == nil && p >= 0 {
+		err = readDirectory64End(r, p, d)
+	}
+	if err != nil {
+		return nil, err
+	}
+
+	// Make sure directoryOffset points to somewhere in our file.
+	if o := int64(d.directoryOffset); o < 0 || o >= size {
+		return nil, ErrFormat
+	}
+	return d, nil
+}
+
+// findDirectory64End tries to read the zip64 locator just before the
+// directory end and returns the offset of the zip64 directory end if
+// found.
+func findDirectory64End(r io.ReaderAt, directoryEndOffset int64) (int64, error) {
+	locOffset := directoryEndOffset - directory64LocLen
+	if locOffset < 0 {
+		return -1, nil // no need to look for a header outside the file
+	}
+	buf := make([]byte, directory64LocLen)
+	if _, err := r.ReadAt(buf, locOffset); err != nil {
+		return -1, err
+	}
+	b := readBuf(buf)
+	if sig := b.uint32(); sig != directory64LocSignature {
+		return -1, nil
+	}
+	b = b[4:]       // skip number of the disk with the start of the zip64 end of central directory
+	p := b.uint64() // relative offset of the zip64 end of central directory record
+	return int64(p), nil
+}
+
+// readDirectory64End reads the zip64 directory end and updates the
+// directory end with the zip64 directory end values.
+func readDirectory64End(r io.ReaderAt, offset int64, d *directoryEnd) (err error) {
+	buf := make([]byte, directory64EndLen)
+	if _, err := r.ReadAt(buf, offset); err != nil {
+		return err
+	}
+
+	b := readBuf(buf)
+	if sig := b.uint32(); sig != directory64EndSignature {
+		return ErrFormat
+	}
+
+	b = b[12:]                        // skip dir size, version and version needed (uint64 + 2x uint16)
+	d.diskNbr = b.uint32()            // number of this disk
+	d.dirDiskNbr = b.uint32()         // number of the disk with the start of the central directory
+	d.dirRecordsThisDisk = b.uint64() // total number of entries in the central directory on this disk
+	d.directoryRecords = b.uint64()   // total number of entries in the central directory
+	d.directorySize = b.uint64()      // size of the central directory
+	d.directoryOffset = b.uint64()    // offset of start of central directory with respect to the starting disk number
+
+	return nil
+}
+
+func findSignatureInBlock(b []byte) int {
+	for i := len(b) - directoryEndLen; i >= 0; i-- {
+		// defined from directoryEndSignature in struct.go
+		if b[i] == 'P' && b[i+1] == 'K' && b[i+2] == 0x05 && b[i+3] == 0x06 {
+			// n is length of comment
+			n := int(b[i+directoryEndLen-2]) | int(b[i+directoryEndLen-1])<<8
+			if n+directoryEndLen+i <= len(b) {
+				return i
+			}
+		}
+	}
+	return -1
+}
+
+type readBuf []byte
+
+func (b *readBuf) uint16() uint16 {
+	v := binary.LittleEndian.Uint16(*b)
+	*b = (*b)[2:]
+	return v
+}
+
+func (b *readBuf) uint32() uint32 {
+	v := binary.LittleEndian.Uint32(*b)
+	*b = (*b)[4:]
+	return v
+}
+
+func (b *readBuf) uint64() uint64 {
+	v := binary.LittleEndian.Uint64(*b)
+	*b = (*b)[8:]
+	return v
+}
diff --git a/src/archive/zip/reader_test.go b/src/archive/zip/reader_test.go
new file mode 100644
index 0000000..29d0652
--- /dev/null
+++ b/src/archive/zip/reader_test.go
@@ -0,0 +1,533 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package zip
+
+import (
+	"bytes"
+	"encoding/binary"
+	"encoding/hex"
+	"io"
+	"io/ioutil"
+	"os"
+	"path/filepath"
+	"regexp"
+	"strings"
+	"testing"
+	"time"
+)
+
+type ZipTest struct {
+	Name    string
+	Source  func() (r io.ReaderAt, size int64) // if non-nil, used instead of testdata/<Name> file
+	Comment string
+	File    []ZipTestFile
+	Error   error // the error that Opening this file should return
+}
+
+type ZipTestFile struct {
+	Name       string
+	Content    []byte // if blank, will attempt to compare against File
+	ContentErr error
+	File       string // name of file to compare to (relative to testdata/)
+	Mtime      string // modified time in format "mm-dd-yy hh:mm:ss"
+	Mode       os.FileMode
+}
+
+// Caution: The Mtime values found for the test files should correspond to
+//          the values listed with unzip -l <zipfile>. However, the values
+//          listed by unzip appear to be off by some hours. When creating
+//          fresh test files and testing them, this issue is not present.
+//          The test files were created in Sydney, so there might be a time
+//          zone issue. The time zone information does have to be encoded
+//          somewhere, because otherwise unzip -l could not provide a different
+//          time from what the archive/zip package provides, but there appears
+//          to be no documentation about this.
+
+var tests = []ZipTest{
+	{
+		Name:    "test.zip",
+		Comment: "This is a zipfile comment.",
+		File: []ZipTestFile{
+			{
+				Name:    "test.txt",
+				Content: []byte("This is a test text file.\n"),
+				Mtime:   "09-05-10 12:12:02",
+				Mode:    0644,
+			},
+			{
+				Name:  "gophercolor16x16.png",
+				File:  "gophercolor16x16.png",
+				Mtime: "09-05-10 15:52:58",
+				Mode:  0644,
+			},
+		},
+	},
+	{
+		Name:    "test-trailing-junk.zip",
+		Comment: "This is a zipfile comment.",
+		File: []ZipTestFile{
+			{
+				Name:    "test.txt",
+				Content: []byte("This is a test text file.\n"),
+				Mtime:   "09-05-10 12:12:02",
+				Mode:    0644,
+			},
+			{
+				Name:  "gophercolor16x16.png",
+				File:  "gophercolor16x16.png",
+				Mtime: "09-05-10 15:52:58",
+				Mode:  0644,
+			},
+		},
+	},
+	{
+		Name:   "r.zip",
+		Source: returnRecursiveZip,
+		File: []ZipTestFile{
+			{
+				Name:    "r/r.zip",
+				Content: rZipBytes(),
+				Mtime:   "03-04-10 00:24:16",
+				Mode:    0666,
+			},
+		},
+	},
+	{
+		Name: "symlink.zip",
+		File: []ZipTestFile{
+			{
+				Name:    "symlink",
+				Content: []byte("../target"),
+				Mode:    0777 | os.ModeSymlink,
+			},
+		},
+	},
+	{
+		Name: "readme.zip",
+	},
+	{
+		Name:  "readme.notzip",
+		Error: ErrFormat,
+	},
+	{
+		Name: "dd.zip",
+		File: []ZipTestFile{
+			{
+				Name:    "filename",
+				Content: []byte("This is a test textfile.\n"),
+				Mtime:   "02-02-11 13:06:20",
+				Mode:    0666,
+			},
+		},
+	},
+	{
+		// created in windows XP file manager.
+		Name: "winxp.zip",
+		File: crossPlatform,
+	},
+	{
+		// created by Zip 3.0 under Linux
+		Name: "unix.zip",
+		File: crossPlatform,
+	},
+	{
+		// created by Go, before we wrote the "optional" data
+		// descriptor signatures (which are required by OS X)
+		Name: "go-no-datadesc-sig.zip",
+		File: []ZipTestFile{
+			{
+				Name:    "foo.txt",
+				Content: []byte("foo\n"),
+				Mtime:   "03-08-12 16:59:10",
+				Mode:    0644,
+			},
+			{
+				Name:    "bar.txt",
+				Content: []byte("bar\n"),
+				Mtime:   "03-08-12 16:59:12",
+				Mode:    0644,
+			},
+		},
+	},
+	{
+		// created by Go, after we wrote the "optional" data
+		// descriptor signatures (which are required by OS X)
+		Name: "go-with-datadesc-sig.zip",
+		File: []ZipTestFile{
+			{
+				Name:    "foo.txt",
+				Content: []byte("foo\n"),
+				Mode:    0666,
+			},
+			{
+				Name:    "bar.txt",
+				Content: []byte("bar\n"),
+				Mode:    0666,
+			},
+		},
+	},
+	{
+		Name:   "Bad-CRC32-in-data-descriptor",
+		Source: returnCorruptCRC32Zip,
+		File: []ZipTestFile{
+			{
+				Name:       "foo.txt",
+				Content:    []byte("foo\n"),
+				Mode:       0666,
+				ContentErr: ErrChecksum,
+			},
+			{
+				Name:    "bar.txt",
+				Content: []byte("bar\n"),
+				Mode:    0666,
+			},
+		},
+	},
+	// Tests that we verify (and accept valid) crc32s on files
+	// with crc32s in their file header (not in data descriptors)
+	{
+		Name: "crc32-not-streamed.zip",
+		File: []ZipTestFile{
+			{
+				Name:    "foo.txt",
+				Content: []byte("foo\n"),
+				Mtime:   "03-08-12 16:59:10",
+				Mode:    0644,
+			},
+			{
+				Name:    "bar.txt",
+				Content: []byte("bar\n"),
+				Mtime:   "03-08-12 16:59:12",
+				Mode:    0644,
+			},
+		},
+	},
+	// Tests that we verify (and reject invalid) crc32s on files
+	// with crc32s in their file header (not in data descriptors)
+	{
+		Name:   "crc32-not-streamed.zip",
+		Source: returnCorruptNotStreamedZip,
+		File: []ZipTestFile{
+			{
+				Name:       "foo.txt",
+				Content:    []byte("foo\n"),
+				Mtime:      "03-08-12 16:59:10",
+				Mode:       0644,
+				ContentErr: ErrChecksum,
+			},
+			{
+				Name:    "bar.txt",
+				Content: []byte("bar\n"),
+				Mtime:   "03-08-12 16:59:12",
+				Mode:    0644,
+			},
+		},
+	},
+	{
+		Name: "zip64.zip",
+		File: []ZipTestFile{
+			{
+				Name:    "README",
+				Content: []byte("This small file is in ZIP64 format.\n"),
+				Mtime:   "08-10-12 14:33:32",
+				Mode:    0644,
+			},
+		},
+	},
+	// Another zip64 file with different Extras fields. (golang.org/issue/7069)
+	{
+		Name: "zip64-2.zip",
+		File: []ZipTestFile{
+			{
+				Name:    "README",
+				Content: []byte("This small file is in ZIP64 format.\n"),
+				Mtime:   "08-10-12 14:33:32",
+				Mode:    0644,
+			},
+		},
+	},
+}
+
+var crossPlatform = []ZipTestFile{
+	{
+		Name:    "hello",
+		Content: []byte("world \r\n"),
+		Mode:    0666,
+	},
+	{
+		Name:    "dir/bar",
+		Content: []byte("foo \r\n"),
+		Mode:    0666,
+	},
+	{
+		Name:    "dir/empty/",
+		Content: []byte{},
+		Mode:    os.ModeDir | 0777,
+	},
+	{
+		Name:    "readonly",
+		Content: []byte("important \r\n"),
+		Mode:    0444,
+	},
+}
+
+func TestReader(t *testing.T) {
+	for _, zt := range tests {
+		readTestZip(t, zt)
+	}
+}
+
+func readTestZip(t *testing.T, zt ZipTest) {
+	var z *Reader
+	var err error
+	if zt.Source != nil {
+		rat, size := zt.Source()
+		z, err = NewReader(rat, size)
+	} else {
+		var rc *ReadCloser
+		rc, err = OpenReader(filepath.Join("testdata", zt.Name))
+		if err == nil {
+			defer rc.Close()
+			z = &rc.Reader
+		}
+	}
+	if err != zt.Error {
+		t.Errorf("%s: error=%v, want %v", zt.Name, err, zt.Error)
+		return
+	}
+
+	// bail if file is not zip
+	if err == ErrFormat {
+		return
+	}
+
+	// bail here if no Files expected to be tested
+	// (there may actually be files in the zip, but we don't care)
+	if zt.File == nil {
+		return
+	}
+
+	if z.Comment != zt.Comment {
+		t.Errorf("%s: comment=%q, want %q", zt.Name, z.Comment, zt.Comment)
+	}
+	if len(z.File) != len(zt.File) {
+		t.Fatalf("%s: file count=%d, want %d", zt.Name, len(z.File), len(zt.File))
+	}
+
+	// test read of each file
+	for i, ft := range zt.File {
+		readTestFile(t, zt, ft, z.File[i])
+	}
+
+	// test simultaneous reads
+	n := 0
+	done := make(chan bool)
+	for i := 0; i < 5; i++ {
+		for j, ft := range zt.File {
+			go func(j int, ft ZipTestFile) {
+				readTestFile(t, zt, ft, z.File[j])
+				done <- true
+			}(j, ft)
+			n++
+		}
+	}
+	for ; n > 0; n-- {
+		<-done
+	}
+}
+
+func readTestFile(t *testing.T, zt ZipTest, ft ZipTestFile, f *File) {
+	if f.Name != ft.Name {
+		t.Errorf("%s: name=%q, want %q", zt.Name, f.Name, ft.Name)
+	}
+
+	if ft.Mtime != "" {
+		mtime, err := time.Parse("01-02-06 15:04:05", ft.Mtime)
+		if err != nil {
+			t.Error(err)
+			return
+		}
+		if ft := f.ModTime(); !ft.Equal(mtime) {
+			t.Errorf("%s: %s: mtime=%s, want %s", zt.Name, f.Name, ft, mtime)
+		}
+	}
+
+	testFileMode(t, zt.Name, f, ft.Mode)
+
+	var b bytes.Buffer
+	r, err := f.Open()
+	if err != nil {
+		t.Errorf("%s: %v", zt.Name, err)
+		return
+	}
+
+	_, err = io.Copy(&b, r)
+	if err != ft.ContentErr {
+		t.Errorf("%s: copying contents: %v (want %v)", zt.Name, err, ft.ContentErr)
+	}
+	if err != nil {
+		return
+	}
+	r.Close()
+
+	size := uint64(f.UncompressedSize)
+	if size == uint32max {
+		size = f.UncompressedSize64
+	}
+	if g := uint64(b.Len()); g != size {
+		t.Errorf("%v: read %v bytes but f.UncompressedSize == %v", f.Name, g, size)
+	}
+
+	var c []byte
+	if ft.Content != nil {
+		c = ft.Content
+	} else if c, err = ioutil.ReadFile("testdata/" + ft.File); err != nil {
+		t.Error(err)
+		return
+	}
+
+	if b.Len() != len(c) {
+		t.Errorf("%s: len=%d, want %d", f.Name, b.Len(), len(c))
+		return
+	}
+
+	for i, b := range b.Bytes() {
+		if b != c[i] {
+			t.Errorf("%s: content[%d]=%q want %q", f.Name, i, b, c[i])
+			return
+		}
+	}
+}
+
+func testFileMode(t *testing.T, zipName string, f *File, want os.FileMode) {
+	mode := f.Mode()
+	if want == 0 {
+		t.Errorf("%s: %s mode: got %v, want none", zipName, f.Name, mode)
+	} else if mode != want {
+		t.Errorf("%s: %s mode: want %v, got %v", zipName, f.Name, want, mode)
+	}
+}
+
+func TestInvalidFiles(t *testing.T) {
+	const size = 1024 * 70 // 70kb
+	b := make([]byte, size)
+
+	// zeroes
+	_, err := NewReader(bytes.NewReader(b), size)
+	if err != ErrFormat {
+		t.Errorf("zeroes: error=%v, want %v", err, ErrFormat)
+	}
+
+	// repeated directoryEndSignatures
+	sig := make([]byte, 4)
+	binary.LittleEndian.PutUint32(sig, directoryEndSignature)
+	for i := 0; i < size-4; i += 4 {
+		copy(b[i:i+4], sig)
+	}
+	_, err = NewReader(bytes.NewReader(b), size)
+	if err != ErrFormat {
+		t.Errorf("sigs: error=%v, want %v", err, ErrFormat)
+	}
+}
+
+func messWith(fileName string, corrupter func(b []byte)) (r io.ReaderAt, size int64) {
+	data, err := ioutil.ReadFile(filepath.Join("testdata", fileName))
+	if err != nil {
+		panic("Error reading " + fileName + ": " + err.Error())
+	}
+	corrupter(data)
+	return bytes.NewReader(data), int64(len(data))
+}
+
+func returnCorruptCRC32Zip() (r io.ReaderAt, size int64) {
+	return messWith("go-with-datadesc-sig.zip", func(b []byte) {
+		// Corrupt one of the CRC32s in the data descriptor:
+		b[0x2d]++
+	})
+}
+
+func returnCorruptNotStreamedZip() (r io.ReaderAt, size int64) {
+	return messWith("crc32-not-streamed.zip", func(b []byte) {
+		// Corrupt foo.txt's final crc32 byte, in both
+		// the file header and TOC. (0x7e -> 0x7f)
+		b[0x11]++
+		b[0x9d]++
+
+		// TODO(bradfitz): add a new test that only corrupts
+		// one of these values, and verify that that's also an
+		// error. Currently, the reader code doesn't verify the
+		// fileheader and TOC's crc32 match if they're both
+		// non-zero and only the second line above, the TOC,
+		// is what matters.
+	})
+}
+
+// rZipBytes returns the bytes of a recursive zip file, without
+// putting it on disk and triggering certain virus scanners.
+func rZipBytes() []byte {
+	s := `
+0000000 50 4b 03 04 14 00 00 00 08 00 08 03 64 3c f9 f4
+0000010 89 64 48 01 00 00 b8 01 00 00 07 00 00 00 72 2f
+0000020 72 2e 7a 69 70 00 25 00 da ff 50 4b 03 04 14 00
+0000030 00 00 08 00 08 03 64 3c f9 f4 89 64 48 01 00 00
+0000040 b8 01 00 00 07 00 00 00 72 2f 72 2e 7a 69 70 00
+0000050 2f 00 d0 ff 00 25 00 da ff 50 4b 03 04 14 00 00
+0000060 00 08 00 08 03 64 3c f9 f4 89 64 48 01 00 00 b8
+0000070 01 00 00 07 00 00 00 72 2f 72 2e 7a 69 70 00 2f
+0000080 00 d0 ff c2 54 8e 57 39 00 05 00 fa ff c2 54 8e
+0000090 57 39 00 05 00 fa ff 00 05 00 fa ff 00 14 00 eb
+00000a0 ff c2 54 8e 57 39 00 05 00 fa ff 00 05 00 fa ff
+00000b0 00 14 00 eb ff 42 88 21 c4 00 00 14 00 eb ff 42
+00000c0 88 21 c4 00 00 14 00 eb ff 42 88 21 c4 00 00 14
+00000d0 00 eb ff 42 88 21 c4 00 00 14 00 eb ff 42 88 21
+00000e0 c4 00 00 00 00 ff ff 00 00 00 ff ff 00 34 00 cb
+00000f0 ff 42 88 21 c4 00 00 00 00 ff ff 00 00 00 ff ff
+0000100 00 34 00 cb ff 42 e8 21 5e 0f 00 00 00 ff ff 0a
+0000110 f0 66 64 12 61 c0 15 dc e8 a0 48 bf 48 af 2a b3
+0000120 20 c0 9b 95 0d c4 67 04 42 53 06 06 06 40 00 06
+0000130 00 f9 ff 6d 01 00 00 00 00 42 e8 21 5e 0f 00 00
+0000140 00 ff ff 0a f0 66 64 12 61 c0 15 dc e8 a0 48 bf
+0000150 48 af 2a b3 20 c0 9b 95 0d c4 67 04 42 53 06 06
+0000160 06 40 00 06 00 f9 ff 6d 01 00 00 00 00 50 4b 01
+0000170 02 14 00 14 00 00 00 08 00 08 03 64 3c f9 f4 89
+0000180 64 48 01 00 00 b8 01 00 00 07 00 00 00 00 00 00
+0000190 00 00 00 00 00 00 00 00 00 00 00 72 2f 72 2e 7a
+00001a0 69 70 50 4b 05 06 00 00 00 00 01 00 01 00 35 00
+00001b0 00 00 6d 01 00 00 00 00`
+	s = regexp.MustCompile(`[0-9a-f]{7}`).ReplaceAllString(s, "")
+	s = regexp.MustCompile(`\s+`).ReplaceAllString(s, "")
+	b, err := hex.DecodeString(s)
+	if err != nil {
+		panic(err)
+	}
+	return b
+}
+
+func returnRecursiveZip() (r io.ReaderAt, size int64) {
+	b := rZipBytes()
+	return bytes.NewReader(b), int64(len(b))
+}
+
+func TestIssue8186(t *testing.T) {
+	// Directory headers & data found in the TOC of a JAR file.
+	dirEnts := []string{
+		"PK\x01\x02\n\x00\n\x00\x00\b\x00\x004\x9d3?\xaa\x1b\x06\xf0\x81\x02\x00\x00\x81\x02\x00\x00-\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00res/drawable-xhdpi-v4/ic_actionbar_accept.png\xfe\xca\x00\x00\x00",
+		"PK\x01\x02\n\x00\n\x00\x00\b\x00\x004\x9d3?\x90K\x89\xc7t\n\x00\x00t\n\x00\x00\x0e\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd1\x02\x00\x00resources.arsc\x00\x00\x00",
+		"PK\x01\x02\x14\x00\x14\x00\b\b\b\x004\x9d3?\xff$\x18\xed3\x03\x00\x00\xb4\b\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00t\r\x00\x00AndroidManifest.xml",
+		"PK\x01\x02\x14\x00\x14\x00\b\b\b\x004\x9d3?\x14\xc5K\xab\x192\x02\x00\xc8\xcd\x04\x00\v\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe8\x10\x00\x00classes.dex",
+		"PK\x01\x02\x14\x00\x14\x00\b\b\b\x004\x9d3?E\x96\nD\xac\x01\x00\x00P\x03\x00\x00&\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00:C\x02\x00res/layout/actionbar_set_wallpaper.xml",
+		"PK\x01\x02\x14\x00\x14\x00\b\b\b\x004\x9d3?Ļ\x14\xe3\xd8\x01\x00\x00\xd8\x03\x00\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00:E\x02\x00res/layout/wallpaper_cropper.xml",
+		"PK\x01\x02\x14\x00\x14\x00\b\b\b\x004\x9d3?}\xc1\x15\x9eZ\x01\x00\x00!\x02\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00`G\x02\x00META-INF/MANIFEST.MF",
+		"PK\x01\x02\x14\x00\x14\x00\b\b\b\x004\x9d3?\xe6\x98Ьo\x01\x00\x00\x84\x02\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfcH\x02\x00META-INF/CERT.SF",
+		"PK\x01\x02\x14\x00\x14\x00\b\b\b\x004\x9d3?\xbfP\x96b\x86\x04\x00\x00\xb2\x06\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa9J\x02\x00META-INF/CERT.RSA",
+	}
+	for i, s := range dirEnts {
+		var f File
+		err := readDirectoryHeader(&f, strings.NewReader(s))
+		if err != nil {
+			t.Errorf("error reading #%d: %v", i, err)
+		}
+	}
+}
diff --git a/src/pkg/archive/zip/register.go b/src/archive/zip/register.go
similarity index 100%
rename from src/pkg/archive/zip/register.go
rename to src/archive/zip/register.go
diff --git a/src/pkg/archive/zip/struct.go b/src/archive/zip/struct.go
similarity index 100%
rename from src/pkg/archive/zip/struct.go
rename to src/archive/zip/struct.go
diff --git a/src/pkg/archive/zip/testdata/crc32-not-streamed.zip b/src/archive/zip/testdata/crc32-not-streamed.zip
similarity index 100%
rename from src/pkg/archive/zip/testdata/crc32-not-streamed.zip
rename to src/archive/zip/testdata/crc32-not-streamed.zip
diff --git a/src/pkg/archive/zip/testdata/dd.zip b/src/archive/zip/testdata/dd.zip
similarity index 100%
rename from src/pkg/archive/zip/testdata/dd.zip
rename to src/archive/zip/testdata/dd.zip
diff --git a/src/pkg/archive/zip/testdata/go-no-datadesc-sig.zip b/src/archive/zip/testdata/go-no-datadesc-sig.zip
similarity index 100%
rename from src/pkg/archive/zip/testdata/go-no-datadesc-sig.zip
rename to src/archive/zip/testdata/go-no-datadesc-sig.zip
diff --git a/src/pkg/archive/zip/testdata/go-with-datadesc-sig.zip b/src/archive/zip/testdata/go-with-datadesc-sig.zip
similarity index 100%
rename from src/pkg/archive/zip/testdata/go-with-datadesc-sig.zip
rename to src/archive/zip/testdata/go-with-datadesc-sig.zip
diff --git a/src/pkg/archive/zip/testdata/gophercolor16x16.png b/src/archive/zip/testdata/gophercolor16x16.png
similarity index 100%
rename from src/pkg/archive/zip/testdata/gophercolor16x16.png
rename to src/archive/zip/testdata/gophercolor16x16.png
diff --git a/src/pkg/archive/zip/testdata/readme.notzip b/src/archive/zip/testdata/readme.notzip
similarity index 100%
rename from src/pkg/archive/zip/testdata/readme.notzip
rename to src/archive/zip/testdata/readme.notzip
diff --git a/src/pkg/archive/zip/testdata/readme.zip b/src/archive/zip/testdata/readme.zip
similarity index 100%
rename from src/pkg/archive/zip/testdata/readme.zip
rename to src/archive/zip/testdata/readme.zip
diff --git a/src/pkg/archive/zip/testdata/symlink.zip b/src/archive/zip/testdata/symlink.zip
similarity index 100%
rename from src/pkg/archive/zip/testdata/symlink.zip
rename to src/archive/zip/testdata/symlink.zip
diff --git a/src/pkg/archive/zip/testdata/test-trailing-junk.zip b/src/archive/zip/testdata/test-trailing-junk.zip
similarity index 100%
rename from src/pkg/archive/zip/testdata/test-trailing-junk.zip
rename to src/archive/zip/testdata/test-trailing-junk.zip
diff --git a/src/pkg/archive/zip/testdata/test.zip b/src/archive/zip/testdata/test.zip
similarity index 100%
rename from src/pkg/archive/zip/testdata/test.zip
rename to src/archive/zip/testdata/test.zip
diff --git a/src/pkg/archive/zip/testdata/unix.zip b/src/archive/zip/testdata/unix.zip
similarity index 100%
rename from src/pkg/archive/zip/testdata/unix.zip
rename to src/archive/zip/testdata/unix.zip
diff --git a/src/pkg/archive/zip/testdata/winxp.zip b/src/archive/zip/testdata/winxp.zip
similarity index 100%
rename from src/pkg/archive/zip/testdata/winxp.zip
rename to src/archive/zip/testdata/winxp.zip
diff --git a/src/pkg/archive/zip/testdata/zip64-2.zip b/src/archive/zip/testdata/zip64-2.zip
similarity index 100%
rename from src/pkg/archive/zip/testdata/zip64-2.zip
rename to src/archive/zip/testdata/zip64-2.zip
diff --git a/src/pkg/archive/zip/testdata/zip64.zip b/src/archive/zip/testdata/zip64.zip
similarity index 100%
rename from src/pkg/archive/zip/testdata/zip64.zip
rename to src/archive/zip/testdata/zip64.zip
diff --git a/src/archive/zip/writer.go b/src/archive/zip/writer.go
new file mode 100644
index 0000000..170beec
--- /dev/null
+++ b/src/archive/zip/writer.go
@@ -0,0 +1,357 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package zip
+
+import (
+	"bufio"
+	"encoding/binary"
+	"errors"
+	"hash"
+	"hash/crc32"
+	"io"
+)
+
+// TODO(adg): support zip file comments
+// TODO(adg): support specifying deflate level
+
+// Writer implements a zip file writer.
+type Writer struct {
+	cw     *countWriter
+	dir    []*header
+	last   *fileWriter
+	closed bool
+}
+
+type header struct {
+	*FileHeader
+	offset uint64
+}
+
+// NewWriter returns a new Writer writing a zip file to w.
+func NewWriter(w io.Writer) *Writer {
+	return &Writer{cw: &countWriter{w: bufio.NewWriter(w)}}
+}
+
+// Flush flushes any buffered data to the underlying writer.
+// Calling Flush is not normally necessary; calling Close is sufficient.
+func (w *Writer) Flush() error {
+	return w.cw.w.(*bufio.Writer).Flush()
+}
+
+// Close finishes writing the zip file by writing the central directory.
+// It does not (and can not) close the underlying writer.
+func (w *Writer) Close() error {
+	if w.last != nil && !w.last.closed {
+		if err := w.last.close(); err != nil {
+			return err
+		}
+		w.last = nil
+	}
+	if w.closed {
+		return errors.New("zip: writer closed twice")
+	}
+	w.closed = true
+
+	// write central directory
+	start := w.cw.count
+	for _, h := range w.dir {
+		var buf [directoryHeaderLen]byte
+		b := writeBuf(buf[:])
+		b.uint32(uint32(directoryHeaderSignature))
+		b.uint16(h.CreatorVersion)
+		b.uint16(h.ReaderVersion)
+		b.uint16(h.Flags)
+		b.uint16(h.Method)
+		b.uint16(h.ModifiedTime)
+		b.uint16(h.ModifiedDate)
+		b.uint32(h.CRC32)
+		if h.isZip64() || h.offset > uint32max {
+			// the file needs a zip64 header. store maxint in both
+			// 32 bit size fields (and offset later) to signal that the
+			// zip64 extra header should be used.
+			b.uint32(uint32max) // compressed size
+			b.uint32(uint32max) // uncompressed size
+
+			// append a zip64 extra block to Extra
+			var buf [28]byte // 2x uint16 + 3x uint64
+			eb := writeBuf(buf[:])
+			eb.uint16(zip64ExtraId)
+			eb.uint16(24) // size = 3x uint64
+			eb.uint64(h.UncompressedSize64)
+			eb.uint64(h.CompressedSize64)
+			eb.uint64(h.offset)
+			h.Extra = append(h.Extra, buf[:]...)
+		} else {
+			b.uint32(h.CompressedSize)
+			b.uint32(h.UncompressedSize)
+		}
+		b.uint16(uint16(len(h.Name)))
+		b.uint16(uint16(len(h.Extra)))
+		b.uint16(uint16(len(h.Comment)))
+		b = b[4:] // skip disk number start and internal file attr (2x uint16)
+		b.uint32(h.ExternalAttrs)
+		if h.offset > uint32max {
+			b.uint32(uint32max)
+		} else {
+			b.uint32(uint32(h.offset))
+		}
+		if _, err := w.cw.Write(buf[:]); err != nil {
+			return err
+		}
+		if _, err := io.WriteString(w.cw, h.Name); err != nil {
+			return err
+		}
+		if _, err := w.cw.Write(h.Extra); err != nil {
+			return err
+		}
+		if _, err := io.WriteString(w.cw, h.Comment); err != nil {
+			return err
+		}
+	}
+	end := w.cw.count
+
+	records := uint64(len(w.dir))
+	size := uint64(end - start)
+	offset := uint64(start)
+
+	if records > uint16max || size > uint32max || offset > uint32max {
+		var buf [directory64EndLen + directory64LocLen]byte
+		b := writeBuf(buf[:])
+
+		// zip64 end of central directory record
+		b.uint32(directory64EndSignature)
+		b.uint64(directory64EndLen)
+		b.uint16(zipVersion45) // version made by
+		b.uint16(zipVersion45) // version needed to extract
+		b.uint32(0)            // number of this disk
+		b.uint32(0)            // number of the disk with the start of the central directory
+		b.uint64(records)      // total number of entries in the central directory on this disk
+		b.uint64(records)      // total number of entries in the central directory
+		b.uint64(size)         // size of the central directory
+		b.uint64(offset)       // offset of start of central directory with respect to the starting disk number
+
+		// zip64 end of central directory locator
+		b.uint32(directory64LocSignature)
+		b.uint32(0)           // number of the disk with the start of the zip64 end of central directory
+		b.uint64(uint64(end)) // relative offset of the zip64 end of central directory record
+		b.uint32(1)           // total number of disks
+
+		if _, err := w.cw.Write(buf[:]); err != nil {
+			return err
+		}
+
+		// store max values in the regular end record to signal that
+		// that the zip64 values should be used instead
+		records = uint16max
+		size = uint32max
+		offset = uint32max
+	}
+
+	// write end record
+	var buf [directoryEndLen]byte
+	b := writeBuf(buf[:])
+	b.uint32(uint32(directoryEndSignature))
+	b = b[4:]                 // skip over disk number and first disk number (2x uint16)
+	b.uint16(uint16(records)) // number of entries this disk
+	b.uint16(uint16(records)) // number of entries total
+	b.uint32(uint32(size))    // size of directory
+	b.uint32(uint32(offset))  // start of directory
+	// skipped size of comment (always zero)
+	if _, err := w.cw.Write(buf[:]); err != nil {
+		return err
+	}
+
+	return w.cw.w.(*bufio.Writer).Flush()
+}
+
+// Create adds a file to the zip file using the provided name.
+// It returns a Writer to which the file contents should be written.
+// The name must be a relative path: it must not start with a drive
+// letter (e.g. C:) or leading slash, and only forward slashes are
+// allowed.
+// The file's contents must be written to the io.Writer before the next
+// call to Create, CreateHeader, or Close.
+func (w *Writer) Create(name string) (io.Writer, error) {
+	header := &FileHeader{
+		Name:   name,
+		Method: Deflate,
+	}
+	return w.CreateHeader(header)
+}
+
+// CreateHeader adds a file to the zip file using the provided FileHeader
+// for the file metadata.
+// It returns a Writer to which the file contents should be written.
+// The file's contents must be written to the io.Writer before the next
+// call to Create, CreateHeader, or Close.
+func (w *Writer) CreateHeader(fh *FileHeader) (io.Writer, error) {
+	if w.last != nil && !w.last.closed {
+		if err := w.last.close(); err != nil {
+			return nil, err
+		}
+	}
+
+	fh.Flags |= 0x8 // we will write a data descriptor
+
+	fh.CreatorVersion = fh.CreatorVersion&0xff00 | zipVersion20 // preserve compatibility byte
+	fh.ReaderVersion = zipVersion20
+
+	fw := &fileWriter{
+		zipw:      w.cw,
+		compCount: &countWriter{w: w.cw},
+		crc32:     crc32.NewIEEE(),
+	}
+	comp := compressor(fh.Method)
+	if comp == nil {
+		return nil, ErrAlgorithm
+	}
+	var err error
+	fw.comp, err = comp(fw.compCount)
+	if err != nil {
+		return nil, err
+	}
+	fw.rawCount = &countWriter{w: fw.comp}
+
+	h := &header{
+		FileHeader: fh,
+		offset:     uint64(w.cw.count),
+	}
+	w.dir = append(w.dir, h)
+	fw.header = h
+
+	if err := writeHeader(w.cw, fh); err != nil {
+		return nil, err
+	}
+
+	w.last = fw
+	return fw, nil
+}
+
+func writeHeader(w io.Writer, h *FileHeader) error {
+	var buf [fileHeaderLen]byte
+	b := writeBuf(buf[:])
+	b.uint32(uint32(fileHeaderSignature))
+	b.uint16(h.ReaderVersion)
+	b.uint16(h.Flags)
+	b.uint16(h.Method)
+	b.uint16(h.ModifiedTime)
+	b.uint16(h.ModifiedDate)
+	b.uint32(0) // since we are writing a data descriptor crc32,
+	b.uint32(0) // compressed size,
+	b.uint32(0) // and uncompressed size should be zero
+	b.uint16(uint16(len(h.Name)))
+	b.uint16(uint16(len(h.Extra)))
+	if _, err := w.Write(buf[:]); err != nil {
+		return err
+	}
+	if _, err := io.WriteString(w, h.Name); err != nil {
+		return err
+	}
+	_, err := w.Write(h.Extra)
+	return err
+}
+
+type fileWriter struct {
+	*header
+	zipw      io.Writer
+	rawCount  *countWriter
+	comp      io.WriteCloser
+	compCount *countWriter
+	crc32     hash.Hash32
+	closed    bool
+}
+
+func (w *fileWriter) Write(p []byte) (int, error) {
+	if w.closed {
+		return 0, errors.New("zip: write to closed file")
+	}
+	w.crc32.Write(p)
+	return w.rawCount.Write(p)
+}
+
+func (w *fileWriter) close() error {
+	if w.closed {
+		return errors.New("zip: file closed twice")
+	}
+	w.closed = true
+	if err := w.comp.Close(); err != nil {
+		return err
+	}
+
+	// update FileHeader
+	fh := w.header.FileHeader
+	fh.CRC32 = w.crc32.Sum32()
+	fh.CompressedSize64 = uint64(w.compCount.count)
+	fh.UncompressedSize64 = uint64(w.rawCount.count)
+
+	if fh.isZip64() {
+		fh.CompressedSize = uint32max
+		fh.UncompressedSize = uint32max
+		fh.ReaderVersion = zipVersion45 // requires 4.5 - File uses ZIP64 format extensions
+	} else {
+		fh.CompressedSize = uint32(fh.CompressedSize64)
+		fh.UncompressedSize = uint32(fh.UncompressedSize64)
+	}
+
+	// Write data descriptor. This is more complicated than one would
+	// think, see e.g. comments in zipfile.c:putextended() and
+	// http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7073588.
+	// The approach here is to write 8 byte sizes if needed without
+	// adding a zip64 extra in the local header (too late anyway).
+	var buf []byte
+	if fh.isZip64() {
+		buf = make([]byte, dataDescriptor64Len)
+	} else {
+		buf = make([]byte, dataDescriptorLen)
+	}
+	b := writeBuf(buf)
+	b.uint32(dataDescriptorSignature) // de-facto standard, required by OS X
+	b.uint32(fh.CRC32)
+	if fh.isZip64() {
+		b.uint64(fh.CompressedSize64)
+		b.uint64(fh.UncompressedSize64)
+	} else {
+		b.uint32(fh.CompressedSize)
+		b.uint32(fh.UncompressedSize)
+	}
+	_, err := w.zipw.Write(buf)
+	return err
+}
+
+type countWriter struct {
+	w     io.Writer
+	count int64
+}
+
+func (w *countWriter) Write(p []byte) (int, error) {
+	n, err := w.w.Write(p)
+	w.count += int64(n)
+	return n, err
+}
+
+type nopCloser struct {
+	io.Writer
+}
+
+func (w nopCloser) Close() error {
+	return nil
+}
+
+type writeBuf []byte
+
+func (b *writeBuf) uint16(v uint16) {
+	binary.LittleEndian.PutUint16(*b, v)
+	*b = (*b)[2:]
+}
+
+func (b *writeBuf) uint32(v uint32) {
+	binary.LittleEndian.PutUint32(*b, v)
+	*b = (*b)[4:]
+}
+
+func (b *writeBuf) uint64(v uint64) {
+	binary.LittleEndian.PutUint64(*b, v)
+	*b = (*b)[8:]
+}
diff --git a/src/archive/zip/writer_test.go b/src/archive/zip/writer_test.go
new file mode 100644
index 0000000..184a7d9
--- /dev/null
+++ b/src/archive/zip/writer_test.go
@@ -0,0 +1,164 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package zip
+
+import (
+	"bytes"
+	"io"
+	"io/ioutil"
+	"math/rand"
+	"os"
+	"testing"
+)
+
+// TODO(adg): a more sophisticated test suite
+
+type WriteTest struct {
+	Name   string
+	Data   []byte
+	Method uint16
+	Mode   os.FileMode
+}
+
+var writeTests = []WriteTest{
+	{
+		Name:   "foo",
+		Data:   []byte("Rabbits, guinea pigs, gophers, marsupial rats, and quolls."),
+		Method: Store,
+		Mode:   0666,
+	},
+	{
+		Name:   "bar",
+		Data:   nil, // large data set in the test
+		Method: Deflate,
+		Mode:   0644,
+	},
+	{
+		Name:   "setuid",
+		Data:   []byte("setuid file"),
+		Method: Deflate,
+		Mode:   0755 | os.ModeSetuid,
+	},
+	{
+		Name:   "setgid",
+		Data:   []byte("setgid file"),
+		Method: Deflate,
+		Mode:   0755 | os.ModeSetgid,
+	},
+	{
+		Name:   "symlink",
+		Data:   []byte("../link/target"),
+		Method: Deflate,
+		Mode:   0755 | os.ModeSymlink,
+	},
+}
+
+func TestWriter(t *testing.T) {
+	largeData := make([]byte, 1<<17)
+	for i := range largeData {
+		largeData[i] = byte(rand.Int())
+	}
+	writeTests[1].Data = largeData
+	defer func() {
+		writeTests[1].Data = nil
+	}()
+
+	// write a zip file
+	buf := new(bytes.Buffer)
+	w := NewWriter(buf)
+
+	for _, wt := range writeTests {
+		testCreate(t, w, &wt)
+	}
+
+	if err := w.Close(); err != nil {
+		t.Fatal(err)
+	}
+
+	// read it back
+	r, err := NewReader(bytes.NewReader(buf.Bytes()), int64(buf.Len()))
+	if err != nil {
+		t.Fatal(err)
+	}
+	for i, wt := range writeTests {
+		testReadFile(t, r.File[i], &wt)
+	}
+}
+
+func TestWriterFlush(t *testing.T) {
+	var buf bytes.Buffer
+	w := NewWriter(struct{ io.Writer }{&buf})
+	_, err := w.Create("foo")
+	if err != nil {
+		t.Fatal(err)
+	}
+	if buf.Len() > 0 {
+		t.Fatalf("Unexpected %d bytes already in buffer", buf.Len())
+	}
+	if err := w.Flush(); err != nil {
+		t.Fatal(err)
+	}
+	if buf.Len() == 0 {
+		t.Fatal("No bytes written after Flush")
+	}
+}
+
+func testCreate(t *testing.T, w *Writer, wt *WriteTest) {
+	header := &FileHeader{
+		Name:   wt.Name,
+		Method: wt.Method,
+	}
+	if wt.Mode != 0 {
+		header.SetMode(wt.Mode)
+	}
+	f, err := w.CreateHeader(header)
+	if err != nil {
+		t.Fatal(err)
+	}
+	_, err = f.Write(wt.Data)
+	if err != nil {
+		t.Fatal(err)
+	}
+}
+
+func testReadFile(t *testing.T, f *File, wt *WriteTest) {
+	if f.Name != wt.Name {
+		t.Fatalf("File name: got %q, want %q", f.Name, wt.Name)
+	}
+	testFileMode(t, wt.Name, f, wt.Mode)
+	rc, err := f.Open()
+	if err != nil {
+		t.Fatal("opening:", err)
+	}
+	b, err := ioutil.ReadAll(rc)
+	if err != nil {
+		t.Fatal("reading:", err)
+	}
+	err = rc.Close()
+	if err != nil {
+		t.Fatal("closing:", err)
+	}
+	if !bytes.Equal(b, wt.Data) {
+		t.Errorf("File contents %q, want %q", b, wt.Data)
+	}
+}
+
+func BenchmarkCompressedZipGarbage(b *testing.B) {
+	b.ReportAllocs()
+	var buf bytes.Buffer
+	bigBuf := bytes.Repeat([]byte("a"), 1<<20)
+	for i := 0; i < b.N; i++ {
+		buf.Reset()
+		zw := NewWriter(&buf)
+		for j := 0; j < 3; j++ {
+			w, _ := zw.CreateHeader(&FileHeader{
+				Name:   "foo",
+				Method: Deflate,
+			})
+			w.Write(bigBuf)
+		}
+		zw.Close()
+	}
+}
diff --git a/src/pkg/archive/zip/zip_test.go b/src/archive/zip/zip_test.go
similarity index 100%
rename from src/pkg/archive/zip/zip_test.go
rename to src/archive/zip/zip_test.go
diff --git a/src/bufio/bufio.go b/src/bufio/bufio.go
new file mode 100644
index 0000000..d3c68fe
--- /dev/null
+++ b/src/bufio/bufio.go
@@ -0,0 +1,698 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package bufio implements buffered I/O.  It wraps an io.Reader or io.Writer
+// object, creating another object (Reader or Writer) that also implements
+// the interface but provides buffering and some help for textual I/O.
+package bufio
+
+import (
+	"bytes"
+	"errors"
+	"io"
+	"unicode/utf8"
+)
+
+const (
+	defaultBufSize = 4096
+)
+
+var (
+	ErrInvalidUnreadByte = errors.New("bufio: invalid use of UnreadByte")
+	ErrInvalidUnreadRune = errors.New("bufio: invalid use of UnreadRune")
+	ErrBufferFull        = errors.New("bufio: buffer full")
+	ErrNegativeCount     = errors.New("bufio: negative count")
+)
+
+// Buffered input.
+
+// Reader implements buffering for an io.Reader object.
+type Reader struct {
+	buf          []byte
+	rd           io.Reader // reader provided by the client
+	r, w         int       // buf read and write positions
+	err          error
+	lastByte     int
+	lastRuneSize int
+}
+
+const minReadBufferSize = 16
+const maxConsecutiveEmptyReads = 100
+
+// NewReaderSize returns a new Reader whose buffer has at least the specified
+// size. If the argument io.Reader is already a Reader with large enough
+// size, it returns the underlying Reader.
+func NewReaderSize(rd io.Reader, size int) *Reader {
+	// Is it already a Reader?
+	b, ok := rd.(*Reader)
+	if ok && len(b.buf) >= size {
+		return b
+	}
+	if size < minReadBufferSize {
+		size = minReadBufferSize
+	}
+	r := new(Reader)
+	r.reset(make([]byte, size), rd)
+	return r
+}
+
+// NewReader returns a new Reader whose buffer has the default size.
+func NewReader(rd io.Reader) *Reader {
+	return NewReaderSize(rd, defaultBufSize)
+}
+
+// Reset discards any buffered data, resets all state, and switches
+// the buffered reader to read from r.
+func (b *Reader) Reset(r io.Reader) {
+	b.reset(b.buf, r)
+}
+
+func (b *Reader) reset(buf []byte, r io.Reader) {
+	*b = Reader{
+		buf:          buf,
+		rd:           r,
+		lastByte:     -1,
+		lastRuneSize: -1,
+	}
+}
+
+var errNegativeRead = errors.New("bufio: reader returned negative count from Read")
+
+// fill reads a new chunk into the buffer.
+func (b *Reader) fill() {
+	// Slide existing data to beginning.
+	if b.r > 0 {
+		copy(b.buf, b.buf[b.r:b.w])
+		b.w -= b.r
+		b.r = 0
+	}
+
+	if b.w >= len(b.buf) {
+		panic("bufio: tried to fill full buffer")
+	}
+
+	// Read new data: try a limited number of times.
+	for i := maxConsecutiveEmptyReads; i > 0; i-- {
+		n, err := b.rd.Read(b.buf[b.w:])
+		if n < 0 {
+			panic(errNegativeRead)
+		}
+		b.w += n
+		if err != nil {
+			b.err = err
+			return
+		}
+		if n > 0 {
+			return
+		}
+	}
+	b.err = io.ErrNoProgress
+}
+
+func (b *Reader) readErr() error {
+	err := b.err
+	b.err = nil
+	return err
+}
+
+// Peek returns the next n bytes without advancing the reader. The bytes stop
+// being valid at the next read call. If Peek returns fewer than n bytes, it
+// also returns an error explaining why the read is short. The error is
+// ErrBufferFull if n is larger than b's buffer size.
+func (b *Reader) Peek(n int) ([]byte, error) {
+	if n < 0 {
+		return nil, ErrNegativeCount
+	}
+	if n > len(b.buf) {
+		return nil, ErrBufferFull
+	}
+	// 0 <= n <= len(b.buf)
+	for b.w-b.r < n && b.err == nil {
+		b.fill() // b.w-b.r < len(b.buf) => buffer is not full
+	}
+
+	var err error
+	if avail := b.w - b.r; avail < n {
+		// not enough data in buffer
+		n = avail
+		err = b.readErr()
+		if err == nil {
+			err = ErrBufferFull
+		}
+	}
+	return b.buf[b.r : b.r+n], err
+}
+
+// Read reads data into p.
+// It returns the number of bytes read into p.
+// It calls Read at most once on the underlying Reader,
+// hence n may be less than len(p).
+// At EOF, the count will be zero and err will be io.EOF.
+func (b *Reader) Read(p []byte) (n int, err error) {
+	n = len(p)
+	if n == 0 {
+		return 0, b.readErr()
+	}
+	if b.r == b.w {
+		if b.err != nil {
+			return 0, b.readErr()
+		}
+		if len(p) >= len(b.buf) {
+			// Large read, empty buffer.
+			// Read directly into p to avoid copy.
+			n, b.err = b.rd.Read(p)
+			if n < 0 {
+				panic(errNegativeRead)
+			}
+			if n > 0 {
+				b.lastByte = int(p[n-1])
+				b.lastRuneSize = -1
+			}
+			return n, b.readErr()
+		}
+		b.fill() // buffer is empty
+		if b.r == b.w {
+			return 0, b.readErr()
+		}
+	}
+
+	// copy as much as we can
+	n = copy(p, b.buf[b.r:b.w])
+	b.r += n
+	b.lastByte = int(b.buf[b.r-1])
+	b.lastRuneSize = -1
+	return n, nil
+}
+
+// ReadByte reads and returns a single byte.
+// If no byte is available, returns an error.
+func (b *Reader) ReadByte() (c byte, err error) {
+	b.lastRuneSize = -1
+	for b.r == b.w {
+		if b.err != nil {
+			return 0, b.readErr()
+		}
+		b.fill() // buffer is empty
+	}
+	c = b.buf[b.r]
+	b.r++
+	b.lastByte = int(c)
+	return c, nil
+}
+
+// UnreadByte unreads the last byte.  Only the most recently read byte can be unread.
+func (b *Reader) UnreadByte() error {
+	if b.lastByte < 0 || b.r == 0 && b.w > 0 {
+		return ErrInvalidUnreadByte
+	}
+	// b.r > 0 || b.w == 0
+	if b.r > 0 {
+		b.r--
+	} else {
+		// b.r == 0 && b.w == 0
+		b.w = 1
+	}
+	b.buf[b.r] = byte(b.lastByte)
+	b.lastByte = -1
+	b.lastRuneSize = -1
+	return nil
+}
+
+// ReadRune reads a single UTF-8 encoded Unicode character and returns the
+// rune and its size in bytes. If the encoded rune is invalid, it consumes one byte
+// and returns unicode.ReplacementChar (U+FFFD) with a size of 1.
+func (b *Reader) ReadRune() (r rune, size int, err error) {
+	for b.r+utf8.UTFMax > b.w && !utf8.FullRune(b.buf[b.r:b.w]) && b.err == nil && b.w-b.r < len(b.buf) {
+		b.fill() // b.w-b.r < len(buf) => buffer is not full
+	}
+	b.lastRuneSize = -1
+	if b.r == b.w {
+		return 0, 0, b.readErr()
+	}
+	r, size = rune(b.buf[b.r]), 1
+	if r >= 0x80 {
+		r, size = utf8.DecodeRune(b.buf[b.r:b.w])
+	}
+	b.r += size
+	b.lastByte = int(b.buf[b.r-1])
+	b.lastRuneSize = size
+	return r, size, nil
+}
+
+// UnreadRune unreads the last rune.  If the most recent read operation on
+// the buffer was not a ReadRune, UnreadRune returns an error.  (In this
+// regard it is stricter than UnreadByte, which will unread the last byte
+// from any read operation.)
+func (b *Reader) UnreadRune() error {
+	if b.lastRuneSize < 0 || b.r < b.lastRuneSize {
+		return ErrInvalidUnreadRune
+	}
+	b.r -= b.lastRuneSize
+	b.lastByte = -1
+	b.lastRuneSize = -1
+	return nil
+}
+
+// Buffered returns the number of bytes that can be read from the current buffer.
+func (b *Reader) Buffered() int { return b.w - b.r }
+
+// ReadSlice reads until the first occurrence of delim in the input,
+// returning a slice pointing at the bytes in the buffer.
+// The bytes stop being valid at the next read.
+// If ReadSlice encounters an error before finding a delimiter,
+// it returns all the data in the buffer and the error itself (often io.EOF).
+// ReadSlice fails with error ErrBufferFull if the buffer fills without a delim.
+// Because the data returned from ReadSlice will be overwritten
+// by the next I/O operation, most clients should use
+// ReadBytes or ReadString instead.
+// ReadSlice returns err != nil if and only if line does not end in delim.
+func (b *Reader) ReadSlice(delim byte) (line []byte, err error) {
+	for {
+		// Search buffer.
+		if i := bytes.IndexByte(b.buf[b.r:b.w], delim); i >= 0 {
+			line = b.buf[b.r : b.r+i+1]
+			b.r += i + 1
+			break
+		}
+
+		// Pending error?
+		if b.err != nil {
+			line = b.buf[b.r:b.w]
+			b.r = b.w
+			err = b.readErr()
+			break
+		}
+
+		// Buffer full?
+		if b.Buffered() >= len(b.buf) {
+			b.r = b.w
+			line = b.buf
+			err = ErrBufferFull
+			break
+		}
+
+		b.fill() // buffer is not full
+	}
+
+	// Handle last byte, if any.
+	if i := len(line) - 1; i >= 0 {
+		b.lastByte = int(line[i])
+		b.lastRuneSize = -1
+	}
+
+	return
+}
+
+// ReadLine is a low-level line-reading primitive. Most callers should use
+// ReadBytes('\n') or ReadString('\n') instead or use a Scanner.
+//
+// ReadLine tries to return a single line, not including the end-of-line bytes.
+// If the line was too long for the buffer then isPrefix is set and the
+// beginning of the line is returned. The rest of the line will be returned
+// from future calls. isPrefix will be false when returning the last fragment
+// of the line. The returned buffer is only valid until the next call to
+// ReadLine. ReadLine either returns a non-nil line or it returns an error,
+// never both.
+//
+// The text returned from ReadLine does not include the line end ("\r\n" or "\n").
+// No indication or error is given if the input ends without a final line end.
+// Calling UnreadByte after ReadLine will always unread the last byte read
+// (possibly a character belonging to the line end) even if that byte is not
+// part of the line returned by ReadLine.
+func (b *Reader) ReadLine() (line []byte, isPrefix bool, err error) {
+	line, err = b.ReadSlice('\n')
+	if err == ErrBufferFull {
+		// Handle the case where "\r\n" straddles the buffer.
+		if len(line) > 0 && line[len(line)-1] == '\r' {
+			// Put the '\r' back on buf and drop it from line.
+			// Let the next call to ReadLine check for "\r\n".
+			if b.r == 0 {
+				// should be unreachable
+				panic("bufio: tried to rewind past start of buffer")
+			}
+			b.r--
+			line = line[:len(line)-1]
+		}
+		return line, true, nil
+	}
+
+	if len(line) == 0 {
+		if err != nil {
+			line = nil
+		}
+		return
+	}
+	err = nil
+
+	if line[len(line)-1] == '\n' {
+		drop := 1
+		if len(line) > 1 && line[len(line)-2] == '\r' {
+			drop = 2
+		}
+		line = line[:len(line)-drop]
+	}
+	return
+}
+
+// ReadBytes reads until the first occurrence of delim in the input,
+// returning a slice containing the data up to and including the delimiter.
+// If ReadBytes encounters an error before finding a delimiter,
+// it returns the data read before the error and the error itself (often io.EOF).
+// ReadBytes returns err != nil if and only if the returned data does not end in
+// delim.
+// For simple uses, a Scanner may be more convenient.
+func (b *Reader) ReadBytes(delim byte) (line []byte, err error) {
+	// Use ReadSlice to look for array,
+	// accumulating full buffers.
+	var frag []byte
+	var full [][]byte
+	err = nil
+
+	for {
+		var e error
+		frag, e = b.ReadSlice(delim)
+		if e == nil { // got final fragment
+			break
+		}
+		if e != ErrBufferFull { // unexpected error
+			err = e
+			break
+		}
+
+		// Make a copy of the buffer.
+		buf := make([]byte, len(frag))
+		copy(buf, frag)
+		full = append(full, buf)
+	}
+
+	// Allocate new buffer to hold the full pieces and the fragment.
+	n := 0
+	for i := range full {
+		n += len(full[i])
+	}
+	n += len(frag)
+
+	// Copy full pieces and fragment in.
+	buf := make([]byte, n)
+	n = 0
+	for i := range full {
+		n += copy(buf[n:], full[i])
+	}
+	copy(buf[n:], frag)
+	return buf, err
+}
+
+// ReadString reads until the first occurrence of delim in the input,
+// returning a string containing the data up to and including the delimiter.
+// If ReadString encounters an error before finding a delimiter,
+// it returns the data read before the error and the error itself (often io.EOF).
+// ReadString returns err != nil if and only if the returned data does not end in
+// delim.
+// For simple uses, a Scanner may be more convenient.
+func (b *Reader) ReadString(delim byte) (line string, err error) {
+	bytes, err := b.ReadBytes(delim)
+	line = string(bytes)
+	return line, err
+}
+
+// WriteTo implements io.WriterTo.
+func (b *Reader) WriteTo(w io.Writer) (n int64, err error) {
+	n, err = b.writeBuf(w)
+	if err != nil {
+		return
+	}
+
+	if r, ok := b.rd.(io.WriterTo); ok {
+		m, err := r.WriteTo(w)
+		n += m
+		return n, err
+	}
+
+	if w, ok := w.(io.ReaderFrom); ok {
+		m, err := w.ReadFrom(b.rd)
+		n += m
+		return n, err
+	}
+
+	if b.w-b.r < len(b.buf) {
+		b.fill() // buffer not full
+	}
+
+	for b.r < b.w {
+		// b.r < b.w => buffer is not empty
+		m, err := b.writeBuf(w)
+		n += m
+		if err != nil {
+			return n, err
+		}
+		b.fill() // buffer is empty
+	}
+
+	if b.err == io.EOF {
+		b.err = nil
+	}
+
+	return n, b.readErr()
+}
+
+var errNegativeWrite = errors.New("bufio: writer returned negative count from Write")
+
+// writeBuf writes the Reader's buffer to the writer.
+func (b *Reader) writeBuf(w io.Writer) (int64, error) {
+	n, err := w.Write(b.buf[b.r:b.w])
+	if n < 0 {
+		panic(errNegativeWrite)
+	}
+	b.r += n
+	return int64(n), err
+}
+
+// buffered output
+
+// Writer implements buffering for an io.Writer object.
+// If an error occurs writing to a Writer, no more data will be
+// accepted and all subsequent writes will return the error.
+// After all data has been written, the client should call the
+// Flush method to guarantee all data has been forwarded to
+// the underlying io.Writer.
+type Writer struct {
+	err error
+	buf []byte
+	n   int
+	wr  io.Writer
+}
+
+// NewWriterSize returns a new Writer whose buffer has at least the specified
+// size. If the argument io.Writer is already a Writer with large enough
+// size, it returns the underlying Writer.
+func NewWriterSize(w io.Writer, size int) *Writer {
+	// Is it already a Writer?
+	b, ok := w.(*Writer)
+	if ok && len(b.buf) >= size {
+		return b
+	}
+	if size <= 0 {
+		size = defaultBufSize
+	}
+	return &Writer{
+		buf: make([]byte, size),
+		wr:  w,
+	}
+}
+
+// NewWriter returns a new Writer whose buffer has the default size.
+func NewWriter(w io.Writer) *Writer {
+	return NewWriterSize(w, defaultBufSize)
+}
+
+// Reset discards any unflushed buffered data, clears any error, and
+// resets b to write its output to w.
+func (b *Writer) Reset(w io.Writer) {
+	b.err = nil
+	b.n = 0
+	b.wr = w
+}
+
+// Flush writes any buffered data to the underlying io.Writer.
+func (b *Writer) Flush() error {
+	err := b.flush()
+	return err
+}
+
+func (b *Writer) flush() error {
+	if b.err != nil {
+		return b.err
+	}
+	if b.n == 0 {
+		return nil
+	}
+	n, err := b.wr.Write(b.buf[0:b.n])
+	if n < b.n && err == nil {
+		err = io.ErrShortWrite
+	}
+	if err != nil {
+		if n > 0 && n < b.n {
+			copy(b.buf[0:b.n-n], b.buf[n:b.n])
+		}
+		b.n -= n
+		b.err = err
+		return err
+	}
+	b.n = 0
+	return nil
+}
+
+// Available returns how many bytes are unused in the buffer.
+func (b *Writer) Available() int { return len(b.buf) - b.n }
+
+// Buffered returns the number of bytes that have been written into the current buffer.
+func (b *Writer) Buffered() int { return b.n }
+
+// Write writes the contents of p into the buffer.
+// It returns the number of bytes written.
+// If nn < len(p), it also returns an error explaining
+// why the write is short.
+func (b *Writer) Write(p []byte) (nn int, err error) {
+	for len(p) > b.Available() && b.err == nil {
+		var n int
+		if b.Buffered() == 0 {
+			// Large write, empty buffer.
+			// Write directly from p to avoid copy.
+			n, b.err = b.wr.Write(p)
+		} else {
+			n = copy(b.buf[b.n:], p)
+			b.n += n
+			b.flush()
+		}
+		nn += n
+		p = p[n:]
+	}
+	if b.err != nil {
+		return nn, b.err
+	}
+	n := copy(b.buf[b.n:], p)
+	b.n += n
+	nn += n
+	return nn, nil
+}
+
+// WriteByte writes a single byte.
+func (b *Writer) WriteByte(c byte) error {
+	if b.err != nil {
+		return b.err
+	}
+	if b.Available() <= 0 && b.flush() != nil {
+		return b.err
+	}
+	b.buf[b.n] = c
+	b.n++
+	return nil
+}
+
+// WriteRune writes a single Unicode code point, returning
+// the number of bytes written and any error.
+func (b *Writer) WriteRune(r rune) (size int, err error) {
+	if r < utf8.RuneSelf {
+		err = b.WriteByte(byte(r))
+		if err != nil {
+			return 0, err
+		}
+		return 1, nil
+	}
+	if b.err != nil {
+		return 0, b.err
+	}
+	n := b.Available()
+	if n < utf8.UTFMax {
+		if b.flush(); b.err != nil {
+			return 0, b.err
+		}
+		n = b.Available()
+		if n < utf8.UTFMax {
+			// Can only happen if buffer is silly small.
+			return b.WriteString(string(r))
+		}
+	}
+	size = utf8.EncodeRune(b.buf[b.n:], r)
+	b.n += size
+	return size, nil
+}
+
+// WriteString writes a string.
+// It returns the number of bytes written.
+// If the count is less than len(s), it also returns an error explaining
+// why the write is short.
+func (b *Writer) WriteString(s string) (int, error) {
+	nn := 0
+	for len(s) > b.Available() && b.err == nil {
+		n := copy(b.buf[b.n:], s)
+		b.n += n
+		nn += n
+		s = s[n:]
+		b.flush()
+	}
+	if b.err != nil {
+		return nn, b.err
+	}
+	n := copy(b.buf[b.n:], s)
+	b.n += n
+	nn += n
+	return nn, nil
+}
+
+// ReadFrom implements io.ReaderFrom.
+func (b *Writer) ReadFrom(r io.Reader) (n int64, err error) {
+	if b.Buffered() == 0 {
+		if w, ok := b.wr.(io.ReaderFrom); ok {
+			return w.ReadFrom(r)
+		}
+	}
+	var m int
+	for {
+		if b.Available() == 0 {
+			if err1 := b.flush(); err1 != nil {
+				return n, err1
+			}
+		}
+		nr := 0
+		for nr < maxConsecutiveEmptyReads {
+			m, err = r.Read(b.buf[b.n:])
+			if m != 0 || err != nil {
+				break
+			}
+			nr++
+		}
+		if nr == maxConsecutiveEmptyReads {
+			return n, io.ErrNoProgress
+		}
+		b.n += m
+		n += int64(m)
+		if err != nil {
+			break
+		}
+	}
+	if err == io.EOF {
+		// If we filled the buffer exactly, flush pre-emptively.
+		if b.Available() == 0 {
+			err = b.flush()
+		} else {
+			err = nil
+		}
+	}
+	return n, err
+}
+
+// buffered input and output
+
+// ReadWriter stores pointers to a Reader and a Writer.
+// It implements io.ReadWriter.
+type ReadWriter struct {
+	*Reader
+	*Writer
+}
+
+// NewReadWriter allocates a new ReadWriter that dispatches to r and w.
+func NewReadWriter(r *Reader, w *Writer) *ReadWriter {
+	return &ReadWriter{r, w}
+}
diff --git a/src/bufio/bufio_test.go b/src/bufio/bufio_test.go
new file mode 100644
index 0000000..550dac9
--- /dev/null
+++ b/src/bufio/bufio_test.go
@@ -0,0 +1,1426 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package bufio_test
+
+import (
+	. "bufio"
+	"bytes"
+	"errors"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"strings"
+	"testing"
+	"testing/iotest"
+	"time"
+	"unicode/utf8"
+)
+
+// Reads from a reader and rot13s the result.
+type rot13Reader struct {
+	r io.Reader
+}
+
+func newRot13Reader(r io.Reader) *rot13Reader {
+	r13 := new(rot13Reader)
+	r13.r = r
+	return r13
+}
+
+func (r13 *rot13Reader) Read(p []byte) (int, error) {
+	n, err := r13.r.Read(p)
+	for i := 0; i < n; i++ {
+		c := p[i] | 0x20 // lowercase byte
+		if 'a' <= c && c <= 'm' {
+			p[i] += 13
+		} else if 'n' <= c && c <= 'z' {
+			p[i] -= 13
+		}
+	}
+	return n, err
+}
+
+// Call ReadByte to accumulate the text of a file
+func readBytes(buf *Reader) string {
+	var b [1000]byte
+	nb := 0
+	for {
+		c, err := buf.ReadByte()
+		if err == io.EOF {
+			break
+		}
+		if err == nil {
+			b[nb] = c
+			nb++
+		} else if err != iotest.ErrTimeout {
+			panic("Data: " + err.Error())
+		}
+	}
+	return string(b[0:nb])
+}
+
+func TestReaderSimple(t *testing.T) {
+	data := "hello world"
+	b := NewReader(strings.NewReader(data))
+	if s := readBytes(b); s != "hello world" {
+		t.Errorf("simple hello world test failed: got %q", s)
+	}
+
+	b = NewReader(newRot13Reader(strings.NewReader(data)))
+	if s := readBytes(b); s != "uryyb jbeyq" {
+		t.Errorf("rot13 hello world test failed: got %q", s)
+	}
+}
+
+type readMaker struct {
+	name string
+	fn   func(io.Reader) io.Reader
+}
+
+var readMakers = []readMaker{
+	{"full", func(r io.Reader) io.Reader { return r }},
+	{"byte", iotest.OneByteReader},
+	{"half", iotest.HalfReader},
+	{"data+err", iotest.DataErrReader},
+	{"timeout", iotest.TimeoutReader},
+}
+
+// Call ReadString (which ends up calling everything else)
+// to accumulate the text of a file.
+func readLines(b *Reader) string {
+	s := ""
+	for {
+		s1, err := b.ReadString('\n')
+		if err == io.EOF {
+			break
+		}
+		if err != nil && err != iotest.ErrTimeout {
+			panic("GetLines: " + err.Error())
+		}
+		s += s1
+	}
+	return s
+}
+
+// Call Read to accumulate the text of a file
+func reads(buf *Reader, m int) string {
+	var b [1000]byte
+	nb := 0
+	for {
+		n, err := buf.Read(b[nb : nb+m])
+		nb += n
+		if err == io.EOF {
+			break
+		}
+	}
+	return string(b[0:nb])
+}
+
+type bufReader struct {
+	name string
+	fn   func(*Reader) string
+}
+
+var bufreaders = []bufReader{
+	{"1", func(b *Reader) string { return reads(b, 1) }},
+	{"2", func(b *Reader) string { return reads(b, 2) }},
+	{"3", func(b *Reader) string { return reads(b, 3) }},
+	{"4", func(b *Reader) string { return reads(b, 4) }},
+	{"5", func(b *Reader) string { return reads(b, 5) }},
+	{"7", func(b *Reader) string { return reads(b, 7) }},
+	{"bytes", readBytes},
+	{"lines", readLines},
+}
+
+const minReadBufferSize = 16
+
+var bufsizes = []int{
+	0, minReadBufferSize, 23, 32, 46, 64, 93, 128, 1024, 4096,
+}
+
+func TestReader(t *testing.T) {
+	var texts [31]string
+	str := ""
+	all := ""
+	for i := 0; i < len(texts)-1; i++ {
+		texts[i] = str + "\n"
+		all += texts[i]
+		str += string(i%26 + 'a')
+	}
+	texts[len(texts)-1] = all
+
+	for h := 0; h < len(texts); h++ {
+		text := texts[h]
+		for i := 0; i < len(readMakers); i++ {
+			for j := 0; j < len(bufreaders); j++ {
+				for k := 0; k < len(bufsizes); k++ {
+					readmaker := readMakers[i]
+					bufreader := bufreaders[j]
+					bufsize := bufsizes[k]
+					read := readmaker.fn(strings.NewReader(text))
+					buf := NewReaderSize(read, bufsize)
+					s := bufreader.fn(buf)
+					if s != text {
+						t.Errorf("reader=%s fn=%s bufsize=%d want=%q got=%q",
+							readmaker.name, bufreader.name, bufsize, text, s)
+					}
+				}
+			}
+		}
+	}
+}
+
+type zeroReader struct{}
+
+func (zeroReader) Read(p []byte) (int, error) {
+	return 0, nil
+}
+
+func TestZeroReader(t *testing.T) {
+	var z zeroReader
+	r := NewReader(z)
+
+	c := make(chan error)
+	go func() {
+		_, err := r.ReadByte()
+		c <- err
+	}()
+
+	select {
+	case err := <-c:
+		if err == nil {
+			t.Error("error expected")
+		} else if err != io.ErrNoProgress {
+			t.Error("unexpected error:", err)
+		}
+	case <-time.After(time.Second):
+		t.Error("test timed out (endless loop in ReadByte?)")
+	}
+}
+
+// A StringReader delivers its data one string segment at a time via Read.
+type StringReader struct {
+	data []string
+	step int
+}
+
+func (r *StringReader) Read(p []byte) (n int, err error) {
+	if r.step < len(r.data) {
+		s := r.data[r.step]
+		n = copy(p, s)
+		r.step++
+	} else {
+		err = io.EOF
+	}
+	return
+}
+
+func readRuneSegments(t *testing.T, segments []string) {
+	got := ""
+	want := strings.Join(segments, "")
+	r := NewReader(&StringReader{data: segments})
+	for {
+		r, _, err := r.ReadRune()
+		if err != nil {
+			if err != io.EOF {
+				return
+			}
+			break
+		}
+		got += string(r)
+	}
+	if got != want {
+		t.Errorf("segments=%v got=%s want=%s", segments, got, want)
+	}
+}
+
+var segmentList = [][]string{
+	{},
+	{""},
+	{"日", "本語"},
+	{"\u65e5", "\u672c", "\u8a9e"},
+	{"\U000065e5", "\U0000672c", "\U00008a9e"},
+	{"\xe6", "\x97\xa5\xe6", "\x9c\xac\xe8\xaa\x9e"},
+	{"Hello", ", ", "World", "!"},
+	{"Hello", ", ", "", "World", "!"},
+}
+
+func TestReadRune(t *testing.T) {
+	for _, s := range segmentList {
+		readRuneSegments(t, s)
+	}
+}
+
+func TestUnreadRune(t *testing.T) {
+	segments := []string{"Hello, world:", "日本語"}
+	r := NewReader(&StringReader{data: segments})
+	got := ""
+	want := strings.Join(segments, "")
+	// Normal execution.
+	for {
+		r1, _, err := r.ReadRune()
+		if err != nil {
+			if err != io.EOF {
+				t.Error("unexpected error on ReadRune:", err)
+			}
+			break
+		}
+		got += string(r1)
+		// Put it back and read it again.
+		if err = r.UnreadRune(); err != nil {
+			t.Fatal("unexpected error on UnreadRune:", err)
+		}
+		r2, _, err := r.ReadRune()
+		if err != nil {
+			t.Fatal("unexpected error reading after unreading:", err)
+		}
+		if r1 != r2 {
+			t.Fatalf("incorrect rune after unread: got %c, want %c", r1, r2)
+		}
+	}
+	if got != want {
+		t.Errorf("got %q, want %q", got, want)
+	}
+}
+
+func TestUnreadByte(t *testing.T) {
+	segments := []string{"Hello, ", "world"}
+	r := NewReader(&StringReader{data: segments})
+	got := ""
+	want := strings.Join(segments, "")
+	// Normal execution.
+	for {
+		b1, err := r.ReadByte()
+		if err != nil {
+			if err != io.EOF {
+				t.Error("unexpected error on ReadByte:", err)
+			}
+			break
+		}
+		got += string(b1)
+		// Put it back and read it again.
+		if err = r.UnreadByte(); err != nil {
+			t.Fatal("unexpected error on UnreadByte:", err)
+		}
+		b2, err := r.ReadByte()
+		if err != nil {
+			t.Fatal("unexpected error reading after unreading:", err)
+		}
+		if b1 != b2 {
+			t.Fatalf("incorrect byte after unread: got %q, want %q", b1, b2)
+		}
+	}
+	if got != want {
+		t.Errorf("got %q, want %q", got, want)
+	}
+}
+
+func TestUnreadByteMultiple(t *testing.T) {
+	segments := []string{"Hello, ", "world"}
+	data := strings.Join(segments, "")
+	for n := 0; n <= len(data); n++ {
+		r := NewReader(&StringReader{data: segments})
+		// Read n bytes.
+		for i := 0; i < n; i++ {
+			b, err := r.ReadByte()
+			if err != nil {
+				t.Fatalf("n = %d: unexpected error on ReadByte: %v", n, err)
+			}
+			if b != data[i] {
+				t.Fatalf("n = %d: incorrect byte returned from ReadByte: got %q, want %q", n, b, data[i])
+			}
+		}
+		// Unread one byte if there is one.
+		if n > 0 {
+			if err := r.UnreadByte(); err != nil {
+				t.Errorf("n = %d: unexpected error on UnreadByte: %v", n, err)
+			}
+		}
+		// Test that we cannot unread any further.
+		if err := r.UnreadByte(); err == nil {
+			t.Errorf("n = %d: expected error on UnreadByte", n)
+		}
+	}
+}
+
+func TestUnreadByteOthers(t *testing.T) {
+	// A list of readers to use in conjunction with UnreadByte.
+	var readers = []func(*Reader, byte) ([]byte, error){
+		(*Reader).ReadBytes,
+		(*Reader).ReadSlice,
+		func(r *Reader, delim byte) ([]byte, error) {
+			data, err := r.ReadString(delim)
+			return []byte(data), err
+		},
+		// ReadLine doesn't fit the data/pattern easily
+		// so we leave it out. It should be covered via
+		// the ReadSlice test since ReadLine simply calls
+		// ReadSlice, and it's that function that handles
+		// the last byte.
+	}
+
+	// Try all readers with UnreadByte.
+	for rno, read := range readers {
+		// Some input data that is longer than the minimum reader buffer size.
+		const n = 10
+		var buf bytes.Buffer
+		for i := 0; i < n; i++ {
+			buf.WriteString("abcdefg")
+		}
+
+		r := NewReaderSize(&buf, minReadBufferSize)
+		readTo := func(delim byte, want string) {
+			data, err := read(r, delim)
+			if err != nil {
+				t.Fatalf("#%d: unexpected error reading to %c: %v", rno, delim, err)
+			}
+			if got := string(data); got != want {
+				t.Fatalf("#%d: got %q, want %q", rno, got, want)
+			}
+		}
+
+		// Read the data with occasional UnreadByte calls.
+		for i := 0; i < n; i++ {
+			readTo('d', "abcd")
+			for j := 0; j < 3; j++ {
+				if err := r.UnreadByte(); err != nil {
+					t.Fatalf("#%d: unexpected error on UnreadByte: %v", rno, err)
+				}
+				readTo('d', "d")
+			}
+			readTo('g', "efg")
+		}
+
+		// All data should have been read.
+		_, err := r.ReadByte()
+		if err != io.EOF {
+			t.Errorf("#%d: got error %v; want EOF", rno, err)
+		}
+	}
+}
+
+// Test that UnreadRune fails if the preceding operation was not a ReadRune.
+func TestUnreadRuneError(t *testing.T) {
+	buf := make([]byte, 3) // All runes in this test are 3 bytes long
+	r := NewReader(&StringReader{data: []string{"日本語日本語日本語"}})
+	if r.UnreadRune() == nil {
+		t.Error("expected error on UnreadRune from fresh buffer")
+	}
+	_, _, err := r.ReadRune()
+	if err != nil {
+		t.Error("unexpected error on ReadRune (1):", err)
+	}
+	if err = r.UnreadRune(); err != nil {
+		t.Error("unexpected error on UnreadRune (1):", err)
+	}
+	if r.UnreadRune() == nil {
+		t.Error("expected error after UnreadRune (1)")
+	}
+	// Test error after Read.
+	_, _, err = r.ReadRune() // reset state
+	if err != nil {
+		t.Error("unexpected error on ReadRune (2):", err)
+	}
+	_, err = r.Read(buf)
+	if err != nil {
+		t.Error("unexpected error on Read (2):", err)
+	}
+	if r.UnreadRune() == nil {
+		t.Error("expected error after Read (2)")
+	}
+	// Test error after ReadByte.
+	_, _, err = r.ReadRune() // reset state
+	if err != nil {
+		t.Error("unexpected error on ReadRune (2):", err)
+	}
+	for range buf {
+		_, err = r.ReadByte()
+		if err != nil {
+			t.Error("unexpected error on ReadByte (2):", err)
+		}
+	}
+	if r.UnreadRune() == nil {
+		t.Error("expected error after ReadByte")
+	}
+	// Test error after UnreadByte.
+	_, _, err = r.ReadRune() // reset state
+	if err != nil {
+		t.Error("unexpected error on ReadRune (3):", err)
+	}
+	_, err = r.ReadByte()
+	if err != nil {
+		t.Error("unexpected error on ReadByte (3):", err)
+	}
+	err = r.UnreadByte()
+	if err != nil {
+		t.Error("unexpected error on UnreadByte (3):", err)
+	}
+	if r.UnreadRune() == nil {
+		t.Error("expected error after UnreadByte (3)")
+	}
+	// Test error after ReadSlice.
+	_, _, err = r.ReadRune() // reset state
+	if err != nil {
+		t.Error("unexpected error on ReadRune (4):", err)
+	}
+	_, err = r.ReadSlice(0)
+	if err != io.EOF {
+		t.Error("unexpected error on ReadSlice (4):", err)
+	}
+	if r.UnreadRune() == nil {
+		t.Error("expected error after ReadSlice (4)")
+	}
+}
+
+func TestUnreadRuneAtEOF(t *testing.T) {
+	// UnreadRune/ReadRune should error at EOF (was a bug; used to panic)
+	r := NewReader(strings.NewReader("x"))
+	r.ReadRune()
+	r.ReadRune()
+	r.UnreadRune()
+	_, _, err := r.ReadRune()
+	if err == nil {
+		t.Error("expected error at EOF")
+	} else if err != io.EOF {
+		t.Error("expected EOF; got", err)
+	}
+}
+
+func TestReadWriteRune(t *testing.T) {
+	const NRune = 1000
+	byteBuf := new(bytes.Buffer)
+	w := NewWriter(byteBuf)
+	// Write the runes out using WriteRune
+	buf := make([]byte, utf8.UTFMax)
+	for r := rune(0); r < NRune; r++ {
+		size := utf8.EncodeRune(buf, r)
+		nbytes, err := w.WriteRune(r)
+		if err != nil {
+			t.Fatalf("WriteRune(0x%x) error: %s", r, err)
+		}
+		if nbytes != size {
+			t.Fatalf("WriteRune(0x%x) expected %d, got %d", r, size, nbytes)
+		}
+	}
+	w.Flush()
+
+	r := NewReader(byteBuf)
+	// Read them back with ReadRune
+	for r1 := rune(0); r1 < NRune; r1++ {
+		size := utf8.EncodeRune(buf, r1)
+		nr, nbytes, err := r.ReadRune()
+		if nr != r1 || nbytes != size || err != nil {
+			t.Fatalf("ReadRune(0x%x) got 0x%x,%d not 0x%x,%d (err=%s)", r1, nr, nbytes, r1, size, err)
+		}
+	}
+}
+
+func TestWriter(t *testing.T) {
+	var data [8192]byte
+
+	for i := 0; i < len(data); i++ {
+		data[i] = byte(' ' + i%('~'-' '))
+	}
+	w := new(bytes.Buffer)
+	for i := 0; i < len(bufsizes); i++ {
+		for j := 0; j < len(bufsizes); j++ {
+			nwrite := bufsizes[i]
+			bs := bufsizes[j]
+
+			// Write nwrite bytes using buffer size bs.
+			// Check that the right amount makes it out
+			// and that the data is correct.
+
+			w.Reset()
+			buf := NewWriterSize(w, bs)
+			context := fmt.Sprintf("nwrite=%d bufsize=%d", nwrite, bs)
+			n, e1 := buf.Write(data[0:nwrite])
+			if e1 != nil || n != nwrite {
+				t.Errorf("%s: buf.Write %d = %d, %v", context, nwrite, n, e1)
+				continue
+			}
+			if e := buf.Flush(); e != nil {
+				t.Errorf("%s: buf.Flush = %v", context, e)
+			}
+
+			written := w.Bytes()
+			if len(written) != nwrite {
+				t.Errorf("%s: %d bytes written", context, len(written))
+			}
+			for l := 0; l < len(written); l++ {
+				if written[i] != data[i] {
+					t.Errorf("wrong bytes written")
+					t.Errorf("want=%q", data[0:len(written)])
+					t.Errorf("have=%q", written)
+				}
+			}
+		}
+	}
+}
+
+// Check that write errors are returned properly.
+
+type errorWriterTest struct {
+	n, m   int
+	err    error
+	expect error
+}
+
+func (w errorWriterTest) Write(p []byte) (int, error) {
+	return len(p) * w.n / w.m, w.err
+}
+
+var errorWriterTests = []errorWriterTest{
+	{0, 1, nil, io.ErrShortWrite},
+	{1, 2, nil, io.ErrShortWrite},
+	{1, 1, nil, nil},
+	{0, 1, io.ErrClosedPipe, io.ErrClosedPipe},
+	{1, 2, io.ErrClosedPipe, io.ErrClosedPipe},
+	{1, 1, io.ErrClosedPipe, io.ErrClosedPipe},
+}
+
+func TestWriteErrors(t *testing.T) {
+	for _, w := range errorWriterTests {
+		buf := NewWriter(w)
+		_, e := buf.Write([]byte("hello world"))
+		if e != nil {
+			t.Errorf("Write hello to %v: %v", w, e)
+			continue
+		}
+		// Two flushes, to verify the error is sticky.
+		for i := 0; i < 2; i++ {
+			e = buf.Flush()
+			if e != w.expect {
+				t.Errorf("Flush %d/2 %v: got %v, wanted %v", i+1, w, e, w.expect)
+			}
+		}
+	}
+}
+
+func TestNewReaderSizeIdempotent(t *testing.T) {
+	const BufSize = 1000
+	b := NewReaderSize(strings.NewReader("hello world"), BufSize)
+	// Does it recognize itself?
+	b1 := NewReaderSize(b, BufSize)
+	if b1 != b {
+		t.Error("NewReaderSize did not detect underlying Reader")
+	}
+	// Does it wrap if existing buffer is too small?
+	b2 := NewReaderSize(b, 2*BufSize)
+	if b2 == b {
+		t.Error("NewReaderSize did not enlarge buffer")
+	}
+}
+
+func TestNewWriterSizeIdempotent(t *testing.T) {
+	const BufSize = 1000
+	b := NewWriterSize(new(bytes.Buffer), BufSize)
+	// Does it recognize itself?
+	b1 := NewWriterSize(b, BufSize)
+	if b1 != b {
+		t.Error("NewWriterSize did not detect underlying Writer")
+	}
+	// Does it wrap if existing buffer is too small?
+	b2 := NewWriterSize(b, 2*BufSize)
+	if b2 == b {
+		t.Error("NewWriterSize did not enlarge buffer")
+	}
+}
+
+func TestWriteString(t *testing.T) {
+	const BufSize = 8
+	buf := new(bytes.Buffer)
+	b := NewWriterSize(buf, BufSize)
+	b.WriteString("0")                         // easy
+	b.WriteString("123456")                    // still easy
+	b.WriteString("7890")                      // easy after flush
+	b.WriteString("abcdefghijklmnopqrstuvwxy") // hard
+	b.WriteString("z")
+	if err := b.Flush(); err != nil {
+		t.Error("WriteString", err)
+	}
+	s := "01234567890abcdefghijklmnopqrstuvwxyz"
+	if string(buf.Bytes()) != s {
+		t.Errorf("WriteString wants %q gets %q", s, string(buf.Bytes()))
+	}
+}
+
+func TestBufferFull(t *testing.T) {
+	const longString = "And now, hello, world! It is the time for all good men to come to the aid of their party"
+	buf := NewReaderSize(strings.NewReader(longString), minReadBufferSize)
+	line, err := buf.ReadSlice('!')
+	if string(line) != "And now, hello, " || err != ErrBufferFull {
+		t.Errorf("first ReadSlice(,) = %q, %v", line, err)
+	}
+	line, err = buf.ReadSlice('!')
+	if string(line) != "world!" || err != nil {
+		t.Errorf("second ReadSlice(,) = %q, %v", line, err)
+	}
+}
+
+func TestPeek(t *testing.T) {
+	p := make([]byte, 10)
+	// string is 16 (minReadBufferSize) long.
+	buf := NewReaderSize(strings.NewReader("abcdefghijklmnop"), minReadBufferSize)
+	if s, err := buf.Peek(1); string(s) != "a" || err != nil {
+		t.Fatalf("want %q got %q, err=%v", "a", string(s), err)
+	}
+	if s, err := buf.Peek(4); string(s) != "abcd" || err != nil {
+		t.Fatalf("want %q got %q, err=%v", "abcd", string(s), err)
+	}
+	if _, err := buf.Peek(-1); err != ErrNegativeCount {
+		t.Fatalf("want ErrNegativeCount got %v", err)
+	}
+	if _, err := buf.Peek(32); err != ErrBufferFull {
+		t.Fatalf("want ErrBufFull got %v", err)
+	}
+	if _, err := buf.Read(p[0:3]); string(p[0:3]) != "abc" || err != nil {
+		t.Fatalf("want %q got %q, err=%v", "abc", string(p[0:3]), err)
+	}
+	if s, err := buf.Peek(1); string(s) != "d" || err != nil {
+		t.Fatalf("want %q got %q, err=%v", "d", string(s), err)
+	}
+	if s, err := buf.Peek(2); string(s) != "de" || err != nil {
+		t.Fatalf("want %q got %q, err=%v", "de", string(s), err)
+	}
+	if _, err := buf.Read(p[0:3]); string(p[0:3]) != "def" || err != nil {
+		t.Fatalf("want %q got %q, err=%v", "def", string(p[0:3]), err)
+	}
+	if s, err := buf.Peek(4); string(s) != "ghij" || err != nil {
+		t.Fatalf("want %q got %q, err=%v", "ghij", string(s), err)
+	}
+	if _, err := buf.Read(p[0:]); string(p[0:]) != "ghijklmnop" || err != nil {
+		t.Fatalf("want %q got %q, err=%v", "ghijklmnop", string(p[0:minReadBufferSize]), err)
+	}
+	if s, err := buf.Peek(0); string(s) != "" || err != nil {
+		t.Fatalf("want %q got %q, err=%v", "", string(s), err)
+	}
+	if _, err := buf.Peek(1); err != io.EOF {
+		t.Fatalf("want EOF got %v", err)
+	}
+
+	// Test for issue 3022, not exposing a reader's error on a successful Peek.
+	buf = NewReaderSize(dataAndEOFReader("abcd"), 32)
+	if s, err := buf.Peek(2); string(s) != "ab" || err != nil {
+		t.Errorf(`Peek(2) on "abcd", EOF = %q, %v; want "ab", nil`, string(s), err)
+	}
+	if s, err := buf.Peek(4); string(s) != "abcd" || err != nil {
+		t.Errorf(`Peek(4) on "abcd", EOF = %q, %v; want "abcd", nil`, string(s), err)
+	}
+	if n, err := buf.Read(p[0:5]); string(p[0:n]) != "abcd" || err != nil {
+		t.Fatalf("Read after peek = %q, %v; want abcd, EOF", p[0:n], err)
+	}
+	if n, err := buf.Read(p[0:1]); string(p[0:n]) != "" || err != io.EOF {
+		t.Fatalf(`second Read after peek = %q, %v; want "", EOF`, p[0:n], err)
+	}
+}
+
+type dataAndEOFReader string
+
+func (r dataAndEOFReader) Read(p []byte) (int, error) {
+	return copy(p, r), io.EOF
+}
+
+func TestPeekThenUnreadRune(t *testing.T) {
+	// This sequence used to cause a crash.
+	r := NewReader(strings.NewReader("x"))
+	r.ReadRune()
+	r.Peek(1)
+	r.UnreadRune()
+	r.ReadRune() // Used to panic here
+}
+
+var testOutput = []byte("0123456789abcdefghijklmnopqrstuvwxy")
+var testInput = []byte("012\n345\n678\n9ab\ncde\nfgh\nijk\nlmn\nopq\nrst\nuvw\nxy")
+var testInputrn = []byte("012\r\n345\r\n678\r\n9ab\r\ncde\r\nfgh\r\nijk\r\nlmn\r\nopq\r\nrst\r\nuvw\r\nxy\r\n\n\r\n")
+
+// TestReader wraps a []byte and returns reads of a specific length.
+type testReader struct {
+	data   []byte
+	stride int
+}
+
+func (t *testReader) Read(buf []byte) (n int, err error) {
+	n = t.stride
+	if n > len(t.data) {
+		n = len(t.data)
+	}
+	if n > len(buf) {
+		n = len(buf)
+	}
+	copy(buf, t.data)
+	t.data = t.data[n:]
+	if len(t.data) == 0 {
+		err = io.EOF
+	}
+	return
+}
+
+func testReadLine(t *testing.T, input []byte) {
+	//for stride := 1; stride < len(input); stride++ {
+	for stride := 1; stride < 2; stride++ {
+		done := 0
+		reader := testReader{input, stride}
+		l := NewReaderSize(&reader, len(input)+1)
+		for {
+			line, isPrefix, err := l.ReadLine()
+			if len(line) > 0 && err != nil {
+				t.Errorf("ReadLine returned both data and error: %s", err)
+			}
+			if isPrefix {
+				t.Errorf("ReadLine returned prefix")
+			}
+			if err != nil {
+				if err != io.EOF {
+					t.Fatalf("Got unknown error: %s", err)
+				}
+				break
+			}
+			if want := testOutput[done : done+len(line)]; !bytes.Equal(want, line) {
+				t.Errorf("Bad line at stride %d: want: %x got: %x", stride, want, line)
+			}
+			done += len(line)
+		}
+		if done != len(testOutput) {
+			t.Errorf("ReadLine didn't return everything: got: %d, want: %d (stride: %d)", done, len(testOutput), stride)
+		}
+	}
+}
+
+func TestReadLine(t *testing.T) {
+	testReadLine(t, testInput)
+	testReadLine(t, testInputrn)
+}
+
+func TestLineTooLong(t *testing.T) {
+	data := make([]byte, 0)
+	for i := 0; i < minReadBufferSize*5/2; i++ {
+		data = append(data, '0'+byte(i%10))
+	}
+	buf := bytes.NewReader(data)
+	l := NewReaderSize(buf, minReadBufferSize)
+	line, isPrefix, err := l.ReadLine()
+	if !isPrefix || !bytes.Equal(line, data[:minReadBufferSize]) || err != nil {
+		t.Errorf("bad result for first line: got %q want %q %v", line, data[:minReadBufferSize], err)
+	}
+	data = data[len(line):]
+	line, isPrefix, err = l.ReadLine()
+	if !isPrefix || !bytes.Equal(line, data[:minReadBufferSize]) || err != nil {
+		t.Errorf("bad result for second line: got %q want %q %v", line, data[:minReadBufferSize], err)
+	}
+	data = data[len(line):]
+	line, isPrefix, err = l.ReadLine()
+	if isPrefix || !bytes.Equal(line, data[:minReadBufferSize/2]) || err != nil {
+		t.Errorf("bad result for third line: got %q want %q %v", line, data[:minReadBufferSize/2], err)
+	}
+	line, isPrefix, err = l.ReadLine()
+	if isPrefix || err == nil {
+		t.Errorf("expected no more lines: %x %s", line, err)
+	}
+}
+
+func TestReadAfterLines(t *testing.T) {
+	line1 := "this is line1"
+	restData := "this is line2\nthis is line 3\n"
+	inbuf := bytes.NewReader([]byte(line1 + "\n" + restData))
+	outbuf := new(bytes.Buffer)
+	maxLineLength := len(line1) + len(restData)/2
+	l := NewReaderSize(inbuf, maxLineLength)
+	line, isPrefix, err := l.ReadLine()
+	if isPrefix || err != nil || string(line) != line1 {
+		t.Errorf("bad result for first line: isPrefix=%v err=%v line=%q", isPrefix, err, string(line))
+	}
+	n, err := io.Copy(outbuf, l)
+	if int(n) != len(restData) || err != nil {
+		t.Errorf("bad result for Read: n=%d err=%v", n, err)
+	}
+	if outbuf.String() != restData {
+		t.Errorf("bad result for Read: got %q; expected %q", outbuf.String(), restData)
+	}
+}
+
+func TestReadEmptyBuffer(t *testing.T) {
+	l := NewReaderSize(new(bytes.Buffer), minReadBufferSize)
+	line, isPrefix, err := l.ReadLine()
+	if err != io.EOF {
+		t.Errorf("expected EOF from ReadLine, got '%s' %t %s", line, isPrefix, err)
+	}
+}
+
+func TestLinesAfterRead(t *testing.T) {
+	l := NewReaderSize(bytes.NewReader([]byte("foo")), minReadBufferSize)
+	_, err := ioutil.ReadAll(l)
+	if err != nil {
+		t.Error(err)
+		return
+	}
+
+	line, isPrefix, err := l.ReadLine()
+	if err != io.EOF {
+		t.Errorf("expected EOF from ReadLine, got '%s' %t %s", line, isPrefix, err)
+	}
+}
+
+func TestReadLineNonNilLineOrError(t *testing.T) {
+	r := NewReader(strings.NewReader("line 1\n"))
+	for i := 0; i < 2; i++ {
+		l, _, err := r.ReadLine()
+		if l != nil && err != nil {
+			t.Fatalf("on line %d/2; ReadLine=%#v, %v; want non-nil line or Error, but not both",
+				i+1, l, err)
+		}
+	}
+}
+
+type readLineResult struct {
+	line     []byte
+	isPrefix bool
+	err      error
+}
+
+var readLineNewlinesTests = []struct {
+	input  string
+	expect []readLineResult
+}{
+	{"012345678901234\r\n012345678901234\r\n", []readLineResult{
+		{[]byte("012345678901234"), true, nil},
+		{nil, false, nil},
+		{[]byte("012345678901234"), true, nil},
+		{nil, false, nil},
+		{nil, false, io.EOF},
+	}},
+	{"0123456789012345\r012345678901234\r", []readLineResult{
+		{[]byte("0123456789012345"), true, nil},
+		{[]byte("\r012345678901234"), true, nil},
+		{[]byte("\r"), false, nil},
+		{nil, false, io.EOF},
+	}},
+}
+
+func TestReadLineNewlines(t *testing.T) {
+	for _, e := range readLineNewlinesTests {
+		testReadLineNewlines(t, e.input, e.expect)
+	}
+}
+
+func testReadLineNewlines(t *testing.T, input string, expect []readLineResult) {
+	b := NewReaderSize(strings.NewReader(input), minReadBufferSize)
+	for i, e := range expect {
+		line, isPrefix, err := b.ReadLine()
+		if !bytes.Equal(line, e.line) {
+			t.Errorf("%q call %d, line == %q, want %q", input, i, line, e.line)
+			return
+		}
+		if isPrefix != e.isPrefix {
+			t.Errorf("%q call %d, isPrefix == %v, want %v", input, i, isPrefix, e.isPrefix)
+			return
+		}
+		if err != e.err {
+			t.Errorf("%q call %d, err == %v, want %v", input, i, err, e.err)
+			return
+		}
+	}
+}
+
+func createTestInput(n int) []byte {
+	input := make([]byte, n)
+	for i := range input {
+		// 101 and 251 are arbitrary prime numbers.
+		// The idea is to create an input sequence
+		// which doesn't repeat too frequently.
+		input[i] = byte(i % 251)
+		if i%101 == 0 {
+			input[i] ^= byte(i / 101)
+		}
+	}
+	return input
+}
+
+func TestReaderWriteTo(t *testing.T) {
+	input := createTestInput(8192)
+	r := NewReader(onlyReader{bytes.NewReader(input)})
+	w := new(bytes.Buffer)
+	if n, err := r.WriteTo(w); err != nil || n != int64(len(input)) {
+		t.Fatalf("r.WriteTo(w) = %d, %v, want %d, nil", n, err, len(input))
+	}
+
+	for i, val := range w.Bytes() {
+		if val != input[i] {
+			t.Errorf("after write: out[%d] = %#x, want %#x", i, val, input[i])
+		}
+	}
+}
+
+type errorWriterToTest struct {
+	rn, wn     int
+	rerr, werr error
+	expected   error
+}
+
+func (r errorWriterToTest) Read(p []byte) (int, error) {
+	return len(p) * r.rn, r.rerr
+}
+
+func (w errorWriterToTest) Write(p []byte) (int, error) {
+	return len(p) * w.wn, w.werr
+}
+
+var errorWriterToTests = []errorWriterToTest{
+	{1, 0, nil, io.ErrClosedPipe, io.ErrClosedPipe},
+	{0, 1, io.ErrClosedPipe, nil, io.ErrClosedPipe},
+	{0, 0, io.ErrUnexpectedEOF, io.ErrClosedPipe, io.ErrClosedPipe},
+	{0, 1, io.EOF, nil, nil},
+}
+
+func TestReaderWriteToErrors(t *testing.T) {
+	for i, rw := range errorWriterToTests {
+		r := NewReader(rw)
+		if _, err := r.WriteTo(rw); err != rw.expected {
+			t.Errorf("r.WriteTo(errorWriterToTests[%d]) = _, %v, want _,%v", i, err, rw.expected)
+		}
+	}
+}
+
+func TestWriterReadFrom(t *testing.T) {
+	ws := []func(io.Writer) io.Writer{
+		func(w io.Writer) io.Writer { return onlyWriter{w} },
+		func(w io.Writer) io.Writer { return w },
+	}
+
+	rs := []func(io.Reader) io.Reader{
+		iotest.DataErrReader,
+		func(r io.Reader) io.Reader { return r },
+	}
+
+	for ri, rfunc := range rs {
+		for wi, wfunc := range ws {
+			input := createTestInput(8192)
+			b := new(bytes.Buffer)
+			w := NewWriter(wfunc(b))
+			r := rfunc(bytes.NewReader(input))
+			if n, err := w.ReadFrom(r); err != nil || n != int64(len(input)) {
+				t.Errorf("ws[%d],rs[%d]: w.ReadFrom(r) = %d, %v, want %d, nil", wi, ri, n, err, len(input))
+				continue
+			}
+			if err := w.Flush(); err != nil {
+				t.Errorf("Flush returned %v", err)
+				continue
+			}
+			if got, want := b.String(), string(input); got != want {
+				t.Errorf("ws[%d], rs[%d]:\ngot  %q\nwant %q\n", wi, ri, got, want)
+			}
+		}
+	}
+}
+
+type errorReaderFromTest struct {
+	rn, wn     int
+	rerr, werr error
+	expected   error
+}
+
+func (r errorReaderFromTest) Read(p []byte) (int, error) {
+	return len(p) * r.rn, r.rerr
+}
+
+func (w errorReaderFromTest) Write(p []byte) (int, error) {
+	return len(p) * w.wn, w.werr
+}
+
+var errorReaderFromTests = []errorReaderFromTest{
+	{0, 1, io.EOF, nil, nil},
+	{1, 1, io.EOF, nil, nil},
+	{0, 1, io.ErrClosedPipe, nil, io.ErrClosedPipe},
+	{0, 0, io.ErrClosedPipe, io.ErrShortWrite, io.ErrClosedPipe},
+	{1, 0, nil, io.ErrShortWrite, io.ErrShortWrite},
+}
+
+func TestWriterReadFromErrors(t *testing.T) {
+	for i, rw := range errorReaderFromTests {
+		w := NewWriter(rw)
+		if _, err := w.ReadFrom(rw); err != rw.expected {
+			t.Errorf("w.ReadFrom(errorReaderFromTests[%d]) = _, %v, want _,%v", i, err, rw.expected)
+		}
+	}
+}
+
+// TestWriterReadFromCounts tests that using io.Copy to copy into a
+// bufio.Writer does not prematurely flush the buffer. For example, when
+// buffering writes to a network socket, excessive network writes should be
+// avoided.
+func TestWriterReadFromCounts(t *testing.T) {
+	var w0 writeCountingDiscard
+	b0 := NewWriterSize(&w0, 1234)
+	b0.WriteString(strings.Repeat("x", 1000))
+	if w0 != 0 {
+		t.Fatalf("write 1000 'x's: got %d writes, want 0", w0)
+	}
+	b0.WriteString(strings.Repeat("x", 200))
+	if w0 != 0 {
+		t.Fatalf("write 1200 'x's: got %d writes, want 0", w0)
+	}
+	io.Copy(b0, onlyReader{strings.NewReader(strings.Repeat("x", 30))})
+	if w0 != 0 {
+		t.Fatalf("write 1230 'x's: got %d writes, want 0", w0)
+	}
+	io.Copy(b0, onlyReader{strings.NewReader(strings.Repeat("x", 9))})
+	if w0 != 1 {
+		t.Fatalf("write 1239 'x's: got %d writes, want 1", w0)
+	}
+
+	var w1 writeCountingDiscard
+	b1 := NewWriterSize(&w1, 1234)
+	b1.WriteString(strings.Repeat("x", 1200))
+	b1.Flush()
+	if w1 != 1 {
+		t.Fatalf("flush 1200 'x's: got %d writes, want 1", w1)
+	}
+	b1.WriteString(strings.Repeat("x", 89))
+	if w1 != 1 {
+		t.Fatalf("write 1200 + 89 'x's: got %d writes, want 1", w1)
+	}
+	io.Copy(b1, onlyReader{strings.NewReader(strings.Repeat("x", 700))})
+	if w1 != 1 {
+		t.Fatalf("write 1200 + 789 'x's: got %d writes, want 1", w1)
+	}
+	io.Copy(b1, onlyReader{strings.NewReader(strings.Repeat("x", 600))})
+	if w1 != 2 {
+		t.Fatalf("write 1200 + 1389 'x's: got %d writes, want 2", w1)
+	}
+	b1.Flush()
+	if w1 != 3 {
+		t.Fatalf("flush 1200 + 1389 'x's: got %d writes, want 3", w1)
+	}
+}
+
+// A writeCountingDiscard is like ioutil.Discard and counts the number of times
+// Write is called on it.
+type writeCountingDiscard int
+
+func (w *writeCountingDiscard) Write(p []byte) (int, error) {
+	*w++
+	return len(p), nil
+}
+
+type negativeReader int
+
+func (r *negativeReader) Read([]byte) (int, error) { return -1, nil }
+
+func TestNegativeRead(t *testing.T) {
+	// should panic with a description pointing at the reader, not at itself.
+	// (should NOT panic with slice index error, for example.)
+	b := NewReader(new(negativeReader))
+	defer func() {
+		switch err := recover().(type) {
+		case nil:
+			t.Fatal("read did not panic")
+		case error:
+			if !strings.Contains(err.Error(), "reader returned negative count from Read") {
+				t.Fatalf("wrong panic: %v", err)
+			}
+		default:
+			t.Fatalf("unexpected panic value: %T(%v)", err, err)
+		}
+	}()
+	b.Read(make([]byte, 100))
+}
+
+var errFake = errors.New("fake error")
+
+type errorThenGoodReader struct {
+	didErr bool
+	nread  int
+}
+
+func (r *errorThenGoodReader) Read(p []byte) (int, error) {
+	r.nread++
+	if !r.didErr {
+		r.didErr = true
+		return 0, errFake
+	}
+	return len(p), nil
+}
+
+func TestReaderClearError(t *testing.T) {
+	r := &errorThenGoodReader{}
+	b := NewReader(r)
+	buf := make([]byte, 1)
+	if _, err := b.Read(nil); err != nil {
+		t.Fatalf("1st nil Read = %v; want nil", err)
+	}
+	if _, err := b.Read(buf); err != errFake {
+		t.Fatalf("1st Read = %v; want errFake", err)
+	}
+	if _, err := b.Read(nil); err != nil {
+		t.Fatalf("2nd nil Read = %v; want nil", err)
+	}
+	if _, err := b.Read(buf); err != nil {
+		t.Fatalf("3rd Read with buffer = %v; want nil", err)
+	}
+	if r.nread != 2 {
+		t.Errorf("num reads = %d; want 2", r.nread)
+	}
+}
+
+// Test for golang.org/issue/5947
+func TestWriterReadFromWhileFull(t *testing.T) {
+	buf := new(bytes.Buffer)
+	w := NewWriterSize(buf, 10)
+
+	// Fill buffer exactly.
+	n, err := w.Write([]byte("0123456789"))
+	if n != 10 || err != nil {
+		t.Fatalf("Write returned (%v, %v), want (10, nil)", n, err)
+	}
+
+	// Use ReadFrom to read in some data.
+	n2, err := w.ReadFrom(strings.NewReader("abcdef"))
+	if n2 != 6 || err != nil {
+		t.Fatalf("ReadFrom returned (%v, %v), want (6, nil)", n2, err)
+	}
+}
+
+type emptyThenNonEmptyReader struct {
+	r io.Reader
+	n int
+}
+
+func (r *emptyThenNonEmptyReader) Read(p []byte) (int, error) {
+	if r.n <= 0 {
+		return r.r.Read(p)
+	}
+	r.n--
+	return 0, nil
+}
+
+// Test for golang.org/issue/7611
+func TestWriterReadFromUntilEOF(t *testing.T) {
+	buf := new(bytes.Buffer)
+	w := NewWriterSize(buf, 5)
+
+	// Partially fill buffer
+	n, err := w.Write([]byte("0123"))
+	if n != 4 || err != nil {
+		t.Fatalf("Write returned (%v, %v), want (4, nil)", n, err)
+	}
+
+	// Use ReadFrom to read in some data.
+	r := &emptyThenNonEmptyReader{r: strings.NewReader("abcd"), n: 3}
+	n2, err := w.ReadFrom(r)
+	if n2 != 4 || err != nil {
+		t.Fatalf("ReadFrom returned (%v, %v), want (4, nil)", n2, err)
+	}
+	w.Flush()
+	if got, want := string(buf.Bytes()), "0123abcd"; got != want {
+		t.Fatalf("buf.Bytes() returned %q, want %q", got, want)
+	}
+}
+
+func TestWriterReadFromErrNoProgress(t *testing.T) {
+	buf := new(bytes.Buffer)
+	w := NewWriterSize(buf, 5)
+
+	// Partially fill buffer
+	n, err := w.Write([]byte("0123"))
+	if n != 4 || err != nil {
+		t.Fatalf("Write returned (%v, %v), want (4, nil)", n, err)
+	}
+
+	// Use ReadFrom to read in some data.
+	r := &emptyThenNonEmptyReader{r: strings.NewReader("abcd"), n: 100}
+	n2, err := w.ReadFrom(r)
+	if n2 != 0 || err != io.ErrNoProgress {
+		t.Fatalf("buf.Bytes() returned (%v, %v), want (0, io.ErrNoProgress)", n2, err)
+	}
+}
+
+func TestReaderReset(t *testing.T) {
+	r := NewReader(strings.NewReader("foo foo"))
+	buf := make([]byte, 3)
+	r.Read(buf)
+	if string(buf) != "foo" {
+		t.Errorf("buf = %q; want foo", buf)
+	}
+	r.Reset(strings.NewReader("bar bar"))
+	all, err := ioutil.ReadAll(r)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if string(all) != "bar bar" {
+		t.Errorf("ReadAll = %q; want bar bar", all)
+	}
+}
+
+func TestWriterReset(t *testing.T) {
+	var buf1, buf2 bytes.Buffer
+	w := NewWriter(&buf1)
+	w.WriteString("foo")
+	w.Reset(&buf2) // and not flushed
+	w.WriteString("bar")
+	w.Flush()
+	if buf1.String() != "" {
+		t.Errorf("buf1 = %q; want empty", buf1.String())
+	}
+	if buf2.String() != "bar" {
+		t.Errorf("buf2 = %q; want bar", buf2.String())
+	}
+}
+
+// An onlyReader only implements io.Reader, no matter what other methods the underlying implementation may have.
+type onlyReader struct {
+	io.Reader
+}
+
+// An onlyWriter only implements io.Writer, no matter what other methods the underlying implementation may have.
+type onlyWriter struct {
+	io.Writer
+}
+
+func BenchmarkReaderCopyOptimal(b *testing.B) {
+	// Optimal case is where the underlying reader implements io.WriterTo
+	srcBuf := bytes.NewBuffer(make([]byte, 8192))
+	src := NewReader(srcBuf)
+	dstBuf := new(bytes.Buffer)
+	dst := onlyWriter{dstBuf}
+	for i := 0; i < b.N; i++ {
+		srcBuf.Reset()
+		src.Reset(srcBuf)
+		dstBuf.Reset()
+		io.Copy(dst, src)
+	}
+}
+
+func BenchmarkReaderCopyUnoptimal(b *testing.B) {
+	// Unoptimal case is where the underlying reader doesn't implement io.WriterTo
+	srcBuf := bytes.NewBuffer(make([]byte, 8192))
+	src := NewReader(onlyReader{srcBuf})
+	dstBuf := new(bytes.Buffer)
+	dst := onlyWriter{dstBuf}
+	for i := 0; i < b.N; i++ {
+		srcBuf.Reset()
+		src.Reset(onlyReader{srcBuf})
+		dstBuf.Reset()
+		io.Copy(dst, src)
+	}
+}
+
+func BenchmarkReaderCopyNoWriteTo(b *testing.B) {
+	srcBuf := bytes.NewBuffer(make([]byte, 8192))
+	srcReader := NewReader(srcBuf)
+	src := onlyReader{srcReader}
+	dstBuf := new(bytes.Buffer)
+	dst := onlyWriter{dstBuf}
+	for i := 0; i < b.N; i++ {
+		srcBuf.Reset()
+		srcReader.Reset(srcBuf)
+		dstBuf.Reset()
+		io.Copy(dst, src)
+	}
+}
+
+func BenchmarkReaderWriteToOptimal(b *testing.B) {
+	const bufSize = 16 << 10
+	buf := make([]byte, bufSize)
+	r := bytes.NewReader(buf)
+	srcReader := NewReaderSize(onlyReader{r}, 1<<10)
+	if _, ok := ioutil.Discard.(io.ReaderFrom); !ok {
+		b.Fatal("ioutil.Discard doesn't support ReaderFrom")
+	}
+	for i := 0; i < b.N; i++ {
+		r.Seek(0, 0)
+		srcReader.Reset(onlyReader{r})
+		n, err := srcReader.WriteTo(ioutil.Discard)
+		if err != nil {
+			b.Fatal(err)
+		}
+		if n != bufSize {
+			b.Fatalf("n = %d; want %d", n, bufSize)
+		}
+	}
+}
+
+func BenchmarkWriterCopyOptimal(b *testing.B) {
+	// Optimal case is where the underlying writer implements io.ReaderFrom
+	srcBuf := bytes.NewBuffer(make([]byte, 8192))
+	src := onlyReader{srcBuf}
+	dstBuf := new(bytes.Buffer)
+	dst := NewWriter(dstBuf)
+	for i := 0; i < b.N; i++ {
+		srcBuf.Reset()
+		dstBuf.Reset()
+		dst.Reset(dstBuf)
+		io.Copy(dst, src)
+	}
+}
+
+func BenchmarkWriterCopyUnoptimal(b *testing.B) {
+	srcBuf := bytes.NewBuffer(make([]byte, 8192))
+	src := onlyReader{srcBuf}
+	dstBuf := new(bytes.Buffer)
+	dst := NewWriter(onlyWriter{dstBuf})
+	for i := 0; i < b.N; i++ {
+		srcBuf.Reset()
+		dstBuf.Reset()
+		dst.Reset(onlyWriter{dstBuf})
+		io.Copy(dst, src)
+	}
+}
+
+func BenchmarkWriterCopyNoReadFrom(b *testing.B) {
+	srcBuf := bytes.NewBuffer(make([]byte, 8192))
+	src := onlyReader{srcBuf}
+	dstBuf := new(bytes.Buffer)
+	dstWriter := NewWriter(dstBuf)
+	dst := onlyWriter{dstWriter}
+	for i := 0; i < b.N; i++ {
+		srcBuf.Reset()
+		dstBuf.Reset()
+		dstWriter.Reset(dstBuf)
+		io.Copy(dst, src)
+	}
+}
+
+func BenchmarkReaderEmpty(b *testing.B) {
+	b.ReportAllocs()
+	str := strings.Repeat("x", 16<<10)
+	for i := 0; i < b.N; i++ {
+		br := NewReader(strings.NewReader(str))
+		n, err := io.Copy(ioutil.Discard, br)
+		if err != nil {
+			b.Fatal(err)
+		}
+		if n != int64(len(str)) {
+			b.Fatal("wrong length")
+		}
+	}
+}
+
+func BenchmarkWriterEmpty(b *testing.B) {
+	b.ReportAllocs()
+	str := strings.Repeat("x", 1<<10)
+	bs := []byte(str)
+	for i := 0; i < b.N; i++ {
+		bw := NewWriter(ioutil.Discard)
+		bw.Flush()
+		bw.WriteByte('a')
+		bw.Flush()
+		bw.WriteRune('B')
+		bw.Flush()
+		bw.Write(bs)
+		bw.Flush()
+		bw.WriteString(str)
+		bw.Flush()
+	}
+}
+
+func BenchmarkWriterFlush(b *testing.B) {
+	b.ReportAllocs()
+	bw := NewWriter(ioutil.Discard)
+	str := strings.Repeat("x", 50)
+	for i := 0; i < b.N; i++ {
+		bw.WriteString(str)
+		bw.Flush()
+	}
+}
diff --git a/src/pkg/bufio/example_test.go b/src/bufio/example_test.go
similarity index 100%
rename from src/pkg/bufio/example_test.go
rename to src/bufio/example_test.go
diff --git a/src/pkg/bufio/export_test.go b/src/bufio/export_test.go
similarity index 100%
rename from src/pkg/bufio/export_test.go
rename to src/bufio/export_test.go
diff --git a/src/bufio/scan.go b/src/bufio/scan.go
new file mode 100644
index 0000000..364d159
--- /dev/null
+++ b/src/bufio/scan.go
@@ -0,0 +1,359 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package bufio
+
+import (
+	"bytes"
+	"errors"
+	"io"
+	"unicode/utf8"
+)
+
+// Scanner provides a convenient interface for reading data such as
+// a file of newline-delimited lines of text. Successive calls to
+// the Scan method will step through the 'tokens' of a file, skipping
+// the bytes between the tokens. The specification of a token is
+// defined by a split function of type SplitFunc; the default split
+// function breaks the input into lines with line termination stripped. Split
+// functions are defined in this package for scanning a file into
+// lines, bytes, UTF-8-encoded runes, and space-delimited words. The
+// client may instead provide a custom split function.
+//
+// Scanning stops unrecoverably at EOF, the first I/O error, or a token too
+// large to fit in the buffer. When a scan stops, the reader may have
+// advanced arbitrarily far past the last token. Programs that need more
+// control over error handling or large tokens, or must run sequential scans
+// on a reader, should use bufio.Reader instead.
+//
+type Scanner struct {
+	r            io.Reader // The reader provided by the client.
+	split        SplitFunc // The function to split the tokens.
+	maxTokenSize int       // Maximum size of a token; modified by tests.
+	token        []byte    // Last token returned by split.
+	buf          []byte    // Buffer used as argument to split.
+	start        int       // First non-processed byte in buf.
+	end          int       // End of data in buf.
+	err          error     // Sticky error.
+	empties      int       // Count of successive empty tokens.
+}
+
+// SplitFunc is the signature of the split function used to tokenize the
+// input. The arguments are an initial substring of the remaining unprocessed
+// data and a flag, atEOF, that reports whether the Reader has no more data
+// to give. The return values are the number of bytes to advance the input
+// and the next token to return to the user, plus an error, if any. If the
+// data does not yet hold a complete token, for instance if it has no newline
+// while scanning lines, SplitFunc can return (0, nil, nil) to signal the
+// Scanner to read more data into the slice and try again with a longer slice
+// starting at the same point in the input.
+//
+// If the returned error is non-nil, scanning stops and the error
+// is returned to the client.
+//
+// The function is never called with an empty data slice unless atEOF
+// is true. If atEOF is true, however, data may be non-empty and,
+// as always, holds unprocessed text.
+type SplitFunc func(data []byte, atEOF bool) (advance int, token []byte, err error)
+
+// Errors returned by Scanner.
+var (
+	ErrTooLong         = errors.New("bufio.Scanner: token too long")
+	ErrNegativeAdvance = errors.New("bufio.Scanner: SplitFunc returns negative advance count")
+	ErrAdvanceTooFar   = errors.New("bufio.Scanner: SplitFunc returns advance count beyond input")
+)
+
+const (
+	// MaxScanTokenSize is the maximum size used to buffer a token.
+	// The actual maximum token size may be smaller as the buffer
+	// may need to include, for instance, a newline.
+	MaxScanTokenSize = 64 * 1024
+)
+
+// NewScanner returns a new Scanner to read from r.
+// The split function defaults to ScanLines.
+func NewScanner(r io.Reader) *Scanner {
+	return &Scanner{
+		r:            r,
+		split:        ScanLines,
+		maxTokenSize: MaxScanTokenSize,
+		buf:          make([]byte, 4096), // Plausible starting size; needn't be large.
+	}
+}
+
+// Err returns the first non-EOF error that was encountered by the Scanner.
+func (s *Scanner) Err() error {
+	if s.err == io.EOF {
+		return nil
+	}
+	return s.err
+}
+
+// Bytes returns the most recent token generated by a call to Scan.
+// The underlying array may point to data that will be overwritten
+// by a subsequent call to Scan. It does no allocation.
+func (s *Scanner) Bytes() []byte {
+	return s.token
+}
+
+// Text returns the most recent token generated by a call to Scan
+// as a newly allocated string holding its bytes.
+func (s *Scanner) Text() string {
+	return string(s.token)
+}
+
+// Scan advances the Scanner to the next token, which will then be
+// available through the Bytes or Text method. It returns false when the
+// scan stops, either by reaching the end of the input or an error.
+// After Scan returns false, the Err method will return any error that
+// occurred during scanning, except that if it was io.EOF, Err
+// will return nil.
+// Split panics if the split function returns 100 empty tokens without
+// advancing the input. This is a common error mode for scanners.
+func (s *Scanner) Scan() bool {
+	// Loop until we have a token.
+	for {
+		// See if we can get a token with what we already have.
+		// If we've run out of data but have an error, give the split function
+		// a chance to recover any remaining, possibly empty token.
+		if s.end > s.start || s.err != nil {
+			advance, token, err := s.split(s.buf[s.start:s.end], s.err != nil)
+			if err != nil {
+				s.setErr(err)
+				return false
+			}
+			if !s.advance(advance) {
+				return false
+			}
+			s.token = token
+			if token != nil {
+				if s.err == nil || advance > 0 {
+					s.empties = 0
+				} else {
+					// Returning tokens not advancing input at EOF.
+					s.empties++
+					if s.empties > 100 {
+						panic("bufio.Scan: 100 empty tokens without progressing")
+					}
+				}
+				return true
+			}
+		}
+		// We cannot generate a token with what we are holding.
+		// If we've already hit EOF or an I/O error, we are done.
+		if s.err != nil {
+			// Shut it down.
+			s.start = 0
+			s.end = 0
+			return false
+		}
+		// Must read more data.
+		// First, shift data to beginning of buffer if there's lots of empty space
+		// or space is needed.
+		if s.start > 0 && (s.end == len(s.buf) || s.start > len(s.buf)/2) {
+			copy(s.buf, s.buf[s.start:s.end])
+			s.end -= s.start
+			s.start = 0
+		}
+		// Is the buffer full? If so, resize.
+		if s.end == len(s.buf) {
+			if len(s.buf) >= s.maxTokenSize {
+				s.setErr(ErrTooLong)
+				return false
+			}
+			newSize := len(s.buf) * 2
+			if newSize > s.maxTokenSize {
+				newSize = s.maxTokenSize
+			}
+			newBuf := make([]byte, newSize)
+			copy(newBuf, s.buf[s.start:s.end])
+			s.buf = newBuf
+			s.end -= s.start
+			s.start = 0
+			continue
+		}
+		// Finally we can read some input. Make sure we don't get stuck with
+		// a misbehaving Reader. Officially we don't need to do this, but let's
+		// be extra careful: Scanner is for safe, simple jobs.
+		for loop := 0; ; {
+			n, err := s.r.Read(s.buf[s.end:len(s.buf)])
+			s.end += n
+			if err != nil {
+				s.setErr(err)
+				break
+			}
+			if n > 0 {
+				s.empties = 0
+				break
+			}
+			loop++
+			if loop > maxConsecutiveEmptyReads {
+				s.setErr(io.ErrNoProgress)
+				break
+			}
+		}
+	}
+}
+
+// advance consumes n bytes of the buffer. It reports whether the advance was legal.
+func (s *Scanner) advance(n int) bool {
+	if n < 0 {
+		s.setErr(ErrNegativeAdvance)
+		return false
+	}
+	if n > s.end-s.start {
+		s.setErr(ErrAdvanceTooFar)
+		return false
+	}
+	s.start += n
+	return true
+}
+
+// setErr records the first error encountered.
+func (s *Scanner) setErr(err error) {
+	if s.err == nil || s.err == io.EOF {
+		s.err = err
+	}
+}
+
+// Split sets the split function for the Scanner. If called, it must be
+// called before Scan. The default split function is ScanLines.
+func (s *Scanner) Split(split SplitFunc) {
+	s.split = split
+}
+
+// Split functions
+
+// ScanBytes is a split function for a Scanner that returns each byte as a token.
+func ScanBytes(data []byte, atEOF bool) (advance int, token []byte, err error) {
+	if atEOF && len(data) == 0 {
+		return 0, nil, nil
+	}
+	return 1, data[0:1], nil
+}
+
+var errorRune = []byte(string(utf8.RuneError))
+
+// ScanRunes is a split function for a Scanner that returns each
+// UTF-8-encoded rune as a token. The sequence of runes returned is
+// equivalent to that from a range loop over the input as a string, which
+// means that erroneous UTF-8 encodings translate to U+FFFD = "\xef\xbf\xbd".
+// Because of the Scan interface, this makes it impossible for the client to
+// distinguish correctly encoded replacement runes from encoding errors.
+func ScanRunes(data []byte, atEOF bool) (advance int, token []byte, err error) {
+	if atEOF && len(data) == 0 {
+		return 0, nil, nil
+	}
+
+	// Fast path 1: ASCII.
+	if data[0] < utf8.RuneSelf {
+		return 1, data[0:1], nil
+	}
+
+	// Fast path 2: Correct UTF-8 decode without error.
+	_, width := utf8.DecodeRune(data)
+	if width > 1 {
+		// It's a valid encoding. Width cannot be one for a correctly encoded
+		// non-ASCII rune.
+		return width, data[0:width], nil
+	}
+
+	// We know it's an error: we have width==1 and implicitly r==utf8.RuneError.
+	// Is the error because there wasn't a full rune to be decoded?
+	// FullRune distinguishes correctly between erroneous and incomplete encodings.
+	if !atEOF && !utf8.FullRune(data) {
+		// Incomplete; get more bytes.
+		return 0, nil, nil
+	}
+
+	// We have a real UTF-8 encoding error. Return a properly encoded error rune
+	// but advance only one byte. This matches the behavior of a range loop over
+	// an incorrectly encoded string.
+	return 1, errorRune, nil
+}
+
+// dropCR drops a terminal \r from the data.
+func dropCR(data []byte) []byte {
+	if len(data) > 0 && data[len(data)-1] == '\r' {
+		return data[0 : len(data)-1]
+	}
+	return data
+}
+
+// ScanLines is a split function for a Scanner that returns each line of
+// text, stripped of any trailing end-of-line marker. The returned line may
+// be empty. The end-of-line marker is one optional carriage return followed
+// by one mandatory newline. In regular expression notation, it is `\r?\n`.
+// The last non-empty line of input will be returned even if it has no
+// newline.
+func ScanLines(data []byte, atEOF bool) (advance int, token []byte, err error) {
+	if atEOF && len(data) == 0 {
+		return 0, nil, nil
+	}
+	if i := bytes.IndexByte(data, '\n'); i >= 0 {
+		// We have a full newline-terminated line.
+		return i + 1, dropCR(data[0:i]), nil
+	}
+	// If we're at EOF, we have a final, non-terminated line. Return it.
+	if atEOF {
+		return len(data), dropCR(data), nil
+	}
+	// Request more data.
+	return 0, nil, nil
+}
+
+// isSpace reports whether the character is a Unicode white space character.
+// We avoid dependency on the unicode package, but check validity of the implementation
+// in the tests.
+func isSpace(r rune) bool {
+	if r <= '\u00FF' {
+		// Obvious ASCII ones: \t through \r plus space. Plus two Latin-1 oddballs.
+		switch r {
+		case ' ', '\t', '\n', '\v', '\f', '\r':
+			return true
+		case '\u0085', '\u00A0':
+			return true
+		}
+		return false
+	}
+	// High-valued ones.
+	if '\u2000' <= r && r <= '\u200a' {
+		return true
+	}
+	switch r {
+	case '\u1680', '\u2028', '\u2029', '\u202f', '\u205f', '\u3000':
+		return true
+	}
+	return false
+}
+
+// ScanWords is a split function for a Scanner that returns each
+// space-separated word of text, with surrounding spaces deleted. It will
+// never return an empty string. The definition of space is set by
+// unicode.IsSpace.
+func ScanWords(data []byte, atEOF bool) (advance int, token []byte, err error) {
+	// Skip leading spaces.
+	start := 0
+	for width := 0; start < len(data); start += width {
+		var r rune
+		r, width = utf8.DecodeRune(data[start:])
+		if !isSpace(r) {
+			break
+		}
+	}
+	// Scan until space, marking end of word.
+	for width, i := 0, start; i < len(data); i += width {
+		var r rune
+		r, width = utf8.DecodeRune(data[i:])
+		if isSpace(r) {
+			return i + width, data[start:i], nil
+		}
+	}
+	// If we're at EOF, we have a final, non-empty, non-terminated word. Return it.
+	if atEOF && len(data) > start {
+		return len(data), data[start:], nil
+	}
+	// Request more data.
+	return start, nil, nil
+}
diff --git a/src/bufio/scan_test.go b/src/bufio/scan_test.go
new file mode 100644
index 0000000..eea87cb
--- /dev/null
+++ b/src/bufio/scan_test.go
@@ -0,0 +1,524 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package bufio_test
+
+import (
+	. "bufio"
+	"bytes"
+	"errors"
+	"io"
+	"strings"
+	"testing"
+	"unicode"
+	"unicode/utf8"
+)
+
+const smallMaxTokenSize = 256 // Much smaller for more efficient testing.
+
+// Test white space table matches the Unicode definition.
+func TestSpace(t *testing.T) {
+	for r := rune(0); r <= utf8.MaxRune; r++ {
+		if IsSpace(r) != unicode.IsSpace(r) {
+			t.Fatalf("white space property disagrees: %#U should be %t", r, unicode.IsSpace(r))
+		}
+	}
+}
+
+var scanTests = []string{
+	"",
+	"a",
+	"¼",
+	"☹",
+	"\x81",   // UTF-8 error
+	"\uFFFD", // correctly encoded RuneError
+	"abcdefgh",
+	"abc def\n\t\tgh    ",
+	"abc¼☹\x81\uFFFD日本語\x82abc",
+}
+
+func TestScanByte(t *testing.T) {
+	for n, test := range scanTests {
+		buf := strings.NewReader(test)
+		s := NewScanner(buf)
+		s.Split(ScanBytes)
+		var i int
+		for i = 0; s.Scan(); i++ {
+			if b := s.Bytes(); len(b) != 1 || b[0] != test[i] {
+				t.Errorf("#%d: %d: expected %q got %q", n, i, test, b)
+			}
+		}
+		if i != len(test) {
+			t.Errorf("#%d: termination expected at %d; got %d", n, len(test), i)
+		}
+		err := s.Err()
+		if err != nil {
+			t.Errorf("#%d: %v", n, err)
+		}
+	}
+}
+
+// Test that the rune splitter returns same sequence of runes (not bytes) as for range string.
+func TestScanRune(t *testing.T) {
+	for n, test := range scanTests {
+		buf := strings.NewReader(test)
+		s := NewScanner(buf)
+		s.Split(ScanRunes)
+		var i, runeCount int
+		var expect rune
+		// Use a string range loop to validate the sequence of runes.
+		for i, expect = range string(test) {
+			if !s.Scan() {
+				break
+			}
+			runeCount++
+			got, _ := utf8.DecodeRune(s.Bytes())
+			if got != expect {
+				t.Errorf("#%d: %d: expected %q got %q", n, i, expect, got)
+			}
+		}
+		if s.Scan() {
+			t.Errorf("#%d: scan ran too long, got %q", n, s.Text())
+		}
+		testRuneCount := utf8.RuneCountInString(test)
+		if runeCount != testRuneCount {
+			t.Errorf("#%d: termination expected at %d; got %d", n, testRuneCount, runeCount)
+		}
+		err := s.Err()
+		if err != nil {
+			t.Errorf("#%d: %v", n, err)
+		}
+	}
+}
+
+var wordScanTests = []string{
+	"",
+	" ",
+	"\n",
+	"a",
+	" a ",
+	"abc def",
+	" abc def ",
+	" abc\tdef\nghi\rjkl\fmno\vpqr\u0085stu\u00a0\n",
+}
+
+// Test that the word splitter returns the same data as strings.Fields.
+func TestScanWords(t *testing.T) {
+	for n, test := range wordScanTests {
+		buf := strings.NewReader(test)
+		s := NewScanner(buf)
+		s.Split(ScanWords)
+		words := strings.Fields(test)
+		var wordCount int
+		for wordCount = 0; wordCount < len(words); wordCount++ {
+			if !s.Scan() {
+				break
+			}
+			got := s.Text()
+			if got != words[wordCount] {
+				t.Errorf("#%d: %d: expected %q got %q", n, wordCount, words[wordCount], got)
+			}
+		}
+		if s.Scan() {
+			t.Errorf("#%d: scan ran too long, got %q", n, s.Text())
+		}
+		if wordCount != len(words) {
+			t.Errorf("#%d: termination expected at %d; got %d", n, len(words), wordCount)
+		}
+		err := s.Err()
+		if err != nil {
+			t.Errorf("#%d: %v", n, err)
+		}
+	}
+}
+
+// slowReader is a reader that returns only a few bytes at a time, to test the incremental
+// reads in Scanner.Scan.
+type slowReader struct {
+	max int
+	buf io.Reader
+}
+
+func (sr *slowReader) Read(p []byte) (n int, err error) {
+	if len(p) > sr.max {
+		p = p[0:sr.max]
+	}
+	return sr.buf.Read(p)
+}
+
+// genLine writes to buf a predictable but non-trivial line of text of length
+// n, including the terminal newline and an occasional carriage return.
+// If addNewline is false, the \r and \n are not emitted.
+func genLine(buf *bytes.Buffer, lineNum, n int, addNewline bool) {
+	buf.Reset()
+	doCR := lineNum%5 == 0
+	if doCR {
+		n--
+	}
+	for i := 0; i < n-1; i++ { // Stop early for \n.
+		c := 'a' + byte(lineNum+i)
+		if c == '\n' || c == '\r' { // Don't confuse us.
+			c = 'N'
+		}
+		buf.WriteByte(c)
+	}
+	if addNewline {
+		if doCR {
+			buf.WriteByte('\r')
+		}
+		buf.WriteByte('\n')
+	}
+	return
+}
+
+// Test the line splitter, including some carriage returns but no long lines.
+func TestScanLongLines(t *testing.T) {
+	// Build a buffer of lots of line lengths up to but not exceeding smallMaxTokenSize.
+	tmp := new(bytes.Buffer)
+	buf := new(bytes.Buffer)
+	lineNum := 0
+	j := 0
+	for i := 0; i < 2*smallMaxTokenSize; i++ {
+		genLine(tmp, lineNum, j, true)
+		if j < smallMaxTokenSize {
+			j++
+		} else {
+			j--
+		}
+		buf.Write(tmp.Bytes())
+		lineNum++
+	}
+	s := NewScanner(&slowReader{1, buf})
+	s.Split(ScanLines)
+	s.MaxTokenSize(smallMaxTokenSize)
+	j = 0
+	for lineNum := 0; s.Scan(); lineNum++ {
+		genLine(tmp, lineNum, j, false)
+		if j < smallMaxTokenSize {
+			j++
+		} else {
+			j--
+		}
+		line := tmp.String() // We use the string-valued token here, for variety.
+		if s.Text() != line {
+			t.Errorf("%d: bad line: %d %d\n%.100q\n%.100q\n", lineNum, len(s.Bytes()), len(line), s.Text(), line)
+		}
+	}
+	err := s.Err()
+	if err != nil {
+		t.Fatal(err)
+	}
+}
+
+// Test that the line splitter errors out on a long line.
+func TestScanLineTooLong(t *testing.T) {
+	const smallMaxTokenSize = 256 // Much smaller for more efficient testing.
+	// Build a buffer of lots of line lengths up to but not exceeding smallMaxTokenSize.
+	tmp := new(bytes.Buffer)
+	buf := new(bytes.Buffer)
+	lineNum := 0
+	j := 0
+	for i := 0; i < 2*smallMaxTokenSize; i++ {
+		genLine(tmp, lineNum, j, true)
+		j++
+		buf.Write(tmp.Bytes())
+		lineNum++
+	}
+	s := NewScanner(&slowReader{3, buf})
+	s.Split(ScanLines)
+	s.MaxTokenSize(smallMaxTokenSize)
+	j = 0
+	for lineNum := 0; s.Scan(); lineNum++ {
+		genLine(tmp, lineNum, j, false)
+		if j < smallMaxTokenSize {
+			j++
+		} else {
+			j--
+		}
+		line := tmp.Bytes()
+		if !bytes.Equal(s.Bytes(), line) {
+			t.Errorf("%d: bad line: %d %d\n%.100q\n%.100q\n", lineNum, len(s.Bytes()), len(line), s.Bytes(), line)
+		}
+	}
+	err := s.Err()
+	if err != ErrTooLong {
+		t.Fatalf("expected ErrTooLong; got %s", err)
+	}
+}
+
+// Test that the line splitter handles a final line without a newline.
+func testNoNewline(text string, lines []string, t *testing.T) {
+	buf := strings.NewReader(text)
+	s := NewScanner(&slowReader{7, buf})
+	s.Split(ScanLines)
+	for lineNum := 0; s.Scan(); lineNum++ {
+		line := lines[lineNum]
+		if s.Text() != line {
+			t.Errorf("%d: bad line: %d %d\n%.100q\n%.100q\n", lineNum, len(s.Bytes()), len(line), s.Bytes(), line)
+		}
+	}
+	err := s.Err()
+	if err != nil {
+		t.Fatal(err)
+	}
+}
+
+var noNewlineLines = []string{
+	"abcdefghijklmn\nopqrstuvwxyz",
+}
+
+// Test that the line splitter handles a final line without a newline.
+func TestScanLineNoNewline(t *testing.T) {
+	const text = "abcdefghijklmn\nopqrstuvwxyz"
+	lines := []string{
+		"abcdefghijklmn",
+		"opqrstuvwxyz",
+	}
+	testNoNewline(text, lines, t)
+}
+
+// Test that the line splitter handles a final line with a carriage return but no newline.
+func TestScanLineReturnButNoNewline(t *testing.T) {
+	const text = "abcdefghijklmn\nopqrstuvwxyz\r"
+	lines := []string{
+		"abcdefghijklmn",
+		"opqrstuvwxyz",
+	}
+	testNoNewline(text, lines, t)
+}
+
+// Test that the line splitter handles a final empty line.
+func TestScanLineEmptyFinalLine(t *testing.T) {
+	const text = "abcdefghijklmn\nopqrstuvwxyz\n\n"
+	lines := []string{
+		"abcdefghijklmn",
+		"opqrstuvwxyz",
+		"",
+	}
+	testNoNewline(text, lines, t)
+}
+
+// Test that the line splitter handles a final empty line with a carriage return but no newline.
+func TestScanLineEmptyFinalLineWithCR(t *testing.T) {
+	const text = "abcdefghijklmn\nopqrstuvwxyz\n\r"
+	lines := []string{
+		"abcdefghijklmn",
+		"opqrstuvwxyz",
+		"",
+	}
+	testNoNewline(text, lines, t)
+}
+
+var testError = errors.New("testError")
+
+// Test the correct error is returned when the split function errors out.
+func TestSplitError(t *testing.T) {
+	// Create a split function that delivers a little data, then a predictable error.
+	numSplits := 0
+	const okCount = 7
+	errorSplit := func(data []byte, atEOF bool) (advance int, token []byte, err error) {
+		if atEOF {
+			panic("didn't get enough data")
+		}
+		if numSplits >= okCount {
+			return 0, nil, testError
+		}
+		numSplits++
+		return 1, data[0:1], nil
+	}
+	// Read the data.
+	const text = "abcdefghijklmnopqrstuvwxyz"
+	buf := strings.NewReader(text)
+	s := NewScanner(&slowReader{1, buf})
+	s.Split(errorSplit)
+	var i int
+	for i = 0; s.Scan(); i++ {
+		if len(s.Bytes()) != 1 || text[i] != s.Bytes()[0] {
+			t.Errorf("#%d: expected %q got %q", i, text[i], s.Bytes()[0])
+		}
+	}
+	// Check correct termination location and error.
+	if i != okCount {
+		t.Errorf("unexpected termination; expected %d tokens got %d", okCount, i)
+	}
+	err := s.Err()
+	if err != testError {
+		t.Fatalf("expected %q got %v", testError, err)
+	}
+}
+
+// Test that an EOF is overridden by a user-generated scan error.
+func TestErrAtEOF(t *testing.T) {
+	s := NewScanner(strings.NewReader("1 2 33"))
+	// This spitter will fail on last entry, after s.err==EOF.
+	split := func(data []byte, atEOF bool) (advance int, token []byte, err error) {
+		advance, token, err = ScanWords(data, atEOF)
+		if len(token) > 1 {
+			if s.ErrOrEOF() != io.EOF {
+				t.Fatal("not testing EOF")
+			}
+			err = testError
+		}
+		return
+	}
+	s.Split(split)
+	for s.Scan() {
+	}
+	if s.Err() != testError {
+		t.Fatal("wrong error:", s.Err())
+	}
+}
+
+// Test for issue 5268.
+type alwaysError struct{}
+
+func (alwaysError) Read(p []byte) (int, error) {
+	return 0, io.ErrUnexpectedEOF
+}
+
+func TestNonEOFWithEmptyRead(t *testing.T) {
+	scanner := NewScanner(alwaysError{})
+	for scanner.Scan() {
+		t.Fatal("read should fail")
+	}
+	err := scanner.Err()
+	if err != io.ErrUnexpectedEOF {
+		t.Errorf("unexpected error: %v", err)
+	}
+}
+
+// Test that Scan finishes if we have endless empty reads.
+type endlessZeros struct{}
+
+func (endlessZeros) Read(p []byte) (int, error) {
+	return 0, nil
+}
+
+func TestBadReader(t *testing.T) {
+	scanner := NewScanner(endlessZeros{})
+	for scanner.Scan() {
+		t.Fatal("read should fail")
+	}
+	err := scanner.Err()
+	if err != io.ErrNoProgress {
+		t.Errorf("unexpected error: %v", err)
+	}
+}
+
+func TestScanWordsExcessiveWhiteSpace(t *testing.T) {
+	const word = "ipsum"
+	s := strings.Repeat(" ", 4*smallMaxTokenSize) + word
+	scanner := NewScanner(strings.NewReader(s))
+	scanner.MaxTokenSize(smallMaxTokenSize)
+	scanner.Split(ScanWords)
+	if !scanner.Scan() {
+		t.Fatalf("scan failed: %v", scanner.Err())
+	}
+	if token := scanner.Text(); token != word {
+		t.Fatalf("unexpected token: %v", token)
+	}
+}
+
+// Test that empty tokens, including at end of line or end of file, are found by the scanner.
+// Issue 8672: Could miss final empty token.
+
+func commaSplit(data []byte, atEOF bool) (advance int, token []byte, err error) {
+	for i := 0; i < len(data); i++ {
+		if data[i] == ',' {
+			return i + 1, data[:i], nil
+		}
+	}
+	if !atEOF {
+		return 0, nil, nil
+	}
+	return 0, data, nil
+}
+
+func TestEmptyTokens(t *testing.T) {
+	s := NewScanner(strings.NewReader("1,2,3,"))
+	values := []string{"1", "2", "3", ""}
+	s.Split(commaSplit)
+	var i int
+	for i = 0; i < len(values); i++ {
+		if !s.Scan() {
+			break
+		}
+		if s.Text() != values[i] {
+			t.Errorf("%d: expected %q got %q", i, values[i], s.Text())
+		}
+	}
+	if i != len(values) {
+		t.Errorf("got %d fields, expected %d", i, len(values))
+	}
+	if err := s.Err(); err != nil {
+		t.Fatal(err)
+	}
+}
+
+func loopAtEOFSplit(data []byte, atEOF bool) (advance int, token []byte, err error) {
+	if len(data) > 0 {
+		return 1, data[:1], nil
+	}
+	return 0, data, nil
+}
+
+func TestDontLoopForever(t *testing.T) {
+	s := NewScanner(strings.NewReader("abc"))
+	s.Split(loopAtEOFSplit)
+	// Expect a panic
+	defer func() {
+		err := recover()
+		if err == nil {
+			t.Fatal("should have panicked")
+		}
+		if msg, ok := err.(string); !ok || !strings.Contains(msg, "empty tokens") {
+			panic(err)
+		}
+	}()
+	for count := 0; s.Scan(); count++ {
+		if count > 1000 {
+			t.Fatal("looping")
+		}
+	}
+	if s.Err() != nil {
+		t.Fatal("after scan:", s.Err())
+	}
+}
+
+func TestBlankLines(t *testing.T) {
+	s := NewScanner(strings.NewReader(strings.Repeat("\n", 1000)))
+	for count := 0; s.Scan(); count++ {
+		if count > 2000 {
+			t.Fatal("looping")
+		}
+	}
+	if s.Err() != nil {
+		t.Fatal("after scan:", s.Err())
+	}
+}
+
+type countdown int
+
+func (c *countdown) split(data []byte, atEOF bool) (advance int, token []byte, err error) {
+	if *c > 0 {
+		*c--
+		return 1, data[:1], nil
+	}
+	return 0, nil, nil
+}
+
+// Check that the looping-at-EOF check doesn't trigger for merely empty tokens.
+func TestEmptyLinesOK(t *testing.T) {
+	c := countdown(10000)
+	s := NewScanner(strings.NewReader(strings.Repeat("\n", 10000)))
+	s.Split(c.split)
+	for s.Scan() {
+	}
+	if s.Err() != nil {
+		t.Fatal("after scan:", s.Err())
+	}
+	if c != 0 {
+		t.Fatalf("stopped with %d left to process", c)
+	}
+}
diff --git a/src/pkg/builtin/builtin.go b/src/builtin/builtin.go
similarity index 100%
rename from src/pkg/builtin/builtin.go
rename to src/builtin/builtin.go
diff --git a/src/pkg/bytes/buffer.go b/src/bytes/buffer.go
similarity index 100%
rename from src/pkg/bytes/buffer.go
rename to src/bytes/buffer.go
diff --git a/src/pkg/bytes/buffer_test.go b/src/bytes/buffer_test.go
similarity index 100%
rename from src/pkg/bytes/buffer_test.go
rename to src/bytes/buffer_test.go
diff --git a/src/bytes/bytes.go b/src/bytes/bytes.go
new file mode 100644
index 0000000..7634707
--- /dev/null
+++ b/src/bytes/bytes.go
@@ -0,0 +1,703 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package bytes implements functions for the manipulation of byte slices.
+// It is analogous to the facilities of the strings package.
+package bytes
+
+import (
+	"unicode"
+	"unicode/utf8"
+)
+
+func equalPortable(a, b []byte) bool {
+	if len(a) != len(b) {
+		return false
+	}
+	for i, c := range a {
+		if c != b[i] {
+			return false
+		}
+	}
+	return true
+}
+
+// explode splits s into a slice of UTF-8 sequences, one per Unicode character (still slices of bytes),
+// up to a maximum of n byte slices. Invalid UTF-8 sequences are chopped into individual bytes.
+func explode(s []byte, n int) [][]byte {
+	if n <= 0 {
+		n = len(s)
+	}
+	a := make([][]byte, n)
+	var size int
+	na := 0
+	for len(s) > 0 {
+		if na+1 >= n {
+			a[na] = s
+			na++
+			break
+		}
+		_, size = utf8.DecodeRune(s)
+		a[na] = s[0:size]
+		s = s[size:]
+		na++
+	}
+	return a[0:na]
+}
+
+// Count counts the number of non-overlapping instances of sep in s.
+func Count(s, sep []byte) int {
+	n := len(sep)
+	if n == 0 {
+		return utf8.RuneCount(s) + 1
+	}
+	if n > len(s) {
+		return 0
+	}
+	count := 0
+	c := sep[0]
+	i := 0
+	t := s[:len(s)-n+1]
+	for i < len(t) {
+		if t[i] != c {
+			o := IndexByte(t[i:], c)
+			if o < 0 {
+				break
+			}
+			i += o
+		}
+		if n == 1 || Equal(s[i:i+n], sep) {
+			count++
+			i += n
+			continue
+		}
+		i++
+	}
+	return count
+}
+
+// Contains reports whether subslice is within b.
+func Contains(b, subslice []byte) bool {
+	return Index(b, subslice) != -1
+}
+
+// Index returns the index of the first instance of sep in s, or -1 if sep is not present in s.
+func Index(s, sep []byte) int {
+	n := len(sep)
+	if n == 0 {
+		return 0
+	}
+	if n > len(s) {
+		return -1
+	}
+	c := sep[0]
+	if n == 1 {
+		return IndexByte(s, c)
+	}
+	i := 0
+	t := s[:len(s)-n+1]
+	for i < len(t) {
+		if t[i] != c {
+			o := IndexByte(t[i:], c)
+			if o < 0 {
+				break
+			}
+			i += o
+		}
+		if Equal(s[i:i+n], sep) {
+			return i
+		}
+		i++
+	}
+	return -1
+}
+
+func indexBytePortable(s []byte, c byte) int {
+	for i, b := range s {
+		if b == c {
+			return i
+		}
+	}
+	return -1
+}
+
+// LastIndex returns the index of the last instance of sep in s, or -1 if sep is not present in s.
+func LastIndex(s, sep []byte) int {
+	n := len(sep)
+	if n == 0 {
+		return len(s)
+	}
+	c := sep[0]
+	for i := len(s) - n; i >= 0; i-- {
+		if s[i] == c && (n == 1 || Equal(s[i:i+n], sep)) {
+			return i
+		}
+	}
+	return -1
+}
+
+// IndexRune interprets s as a sequence of UTF-8-encoded Unicode code points.
+// It returns the byte index of the first occurrence in s of the given rune.
+// It returns -1 if rune is not present in s.
+func IndexRune(s []byte, r rune) int {
+	for i := 0; i < len(s); {
+		r1, size := utf8.DecodeRune(s[i:])
+		if r == r1 {
+			return i
+		}
+		i += size
+	}
+	return -1
+}
+
+// IndexAny interprets s as a sequence of UTF-8-encoded Unicode code points.
+// It returns the byte index of the first occurrence in s of any of the Unicode
+// code points in chars.  It returns -1 if chars is empty or if there is no code
+// point in common.
+func IndexAny(s []byte, chars string) int {
+	if len(chars) > 0 {
+		var r rune
+		var width int
+		for i := 0; i < len(s); i += width {
+			r = rune(s[i])
+			if r < utf8.RuneSelf {
+				width = 1
+			} else {
+				r, width = utf8.DecodeRune(s[i:])
+			}
+			for _, ch := range chars {
+				if r == ch {
+					return i
+				}
+			}
+		}
+	}
+	return -1
+}
+
+// LastIndexAny interprets s as a sequence of UTF-8-encoded Unicode code
+// points.  It returns the byte index of the last occurrence in s of any of
+// the Unicode code points in chars.  It returns -1 if chars is empty or if
+// there is no code point in common.
+func LastIndexAny(s []byte, chars string) int {
+	if len(chars) > 0 {
+		for i := len(s); i > 0; {
+			r, size := utf8.DecodeLastRune(s[0:i])
+			i -= size
+			for _, ch := range chars {
+				if r == ch {
+					return i
+				}
+			}
+		}
+	}
+	return -1
+}
+
+// Generic split: splits after each instance of sep,
+// including sepSave bytes of sep in the subslices.
+func genSplit(s, sep []byte, sepSave, n int) [][]byte {
+	if n == 0 {
+		return nil
+	}
+	if len(sep) == 0 {
+		return explode(s, n)
+	}
+	if n < 0 {
+		n = Count(s, sep) + 1
+	}
+	c := sep[0]
+	start := 0
+	a := make([][]byte, n)
+	na := 0
+	for i := 0; i+len(sep) <= len(s) && na+1 < n; i++ {
+		if s[i] == c && (len(sep) == 1 || Equal(s[i:i+len(sep)], sep)) {
+			a[na] = s[start : i+sepSave]
+			na++
+			start = i + len(sep)
+			i += len(sep) - 1
+		}
+	}
+	a[na] = s[start:]
+	return a[0 : na+1]
+}
+
+// SplitN slices s into subslices separated by sep and returns a slice of
+// the subslices between those separators.
+// If sep is empty, SplitN splits after each UTF-8 sequence.
+// The count determines the number of subslices to return:
+//   n > 0: at most n subslices; the last subslice will be the unsplit remainder.
+//   n == 0: the result is nil (zero subslices)
+//   n < 0: all subslices
+func SplitN(s, sep []byte, n int) [][]byte { return genSplit(s, sep, 0, n) }
+
+// SplitAfterN slices s into subslices after each instance of sep and
+// returns a slice of those subslices.
+// If sep is empty, SplitAfterN splits after each UTF-8 sequence.
+// The count determines the number of subslices to return:
+//   n > 0: at most n subslices; the last subslice will be the unsplit remainder.
+//   n == 0: the result is nil (zero subslices)
+//   n < 0: all subslices
+func SplitAfterN(s, sep []byte, n int) [][]byte {
+	return genSplit(s, sep, len(sep), n)
+}
+
+// Split slices s into all subslices separated by sep and returns a slice of
+// the subslices between those separators.
+// If sep is empty, Split splits after each UTF-8 sequence.
+// It is equivalent to SplitN with a count of -1.
+func Split(s, sep []byte) [][]byte { return genSplit(s, sep, 0, -1) }
+
+// SplitAfter slices s into all subslices after each instance of sep and
+// returns a slice of those subslices.
+// If sep is empty, SplitAfter splits after each UTF-8 sequence.
+// It is equivalent to SplitAfterN with a count of -1.
+func SplitAfter(s, sep []byte) [][]byte {
+	return genSplit(s, sep, len(sep), -1)
+}
+
+// Fields splits the slice s around each instance of one or more consecutive white space
+// characters, returning a slice of subslices of s or an empty list if s contains only white space.
+func Fields(s []byte) [][]byte {
+	return FieldsFunc(s, unicode.IsSpace)
+}
+
+// FieldsFunc interprets s as a sequence of UTF-8-encoded Unicode code points.
+// It splits the slice s at each run of code points c satisfying f(c) and
+// returns a slice of subslices of s.  If all code points in s satisfy f(c), or
+// len(s) == 0, an empty slice is returned.
+// FieldsFunc makes no guarantees about the order in which it calls f(c).
+// If f does not return consistent results for a given c, FieldsFunc may crash.
+func FieldsFunc(s []byte, f func(rune) bool) [][]byte {
+	n := 0
+	inField := false
+	for i := 0; i < len(s); {
+		r, size := utf8.DecodeRune(s[i:])
+		wasInField := inField
+		inField = !f(r)
+		if inField && !wasInField {
+			n++
+		}
+		i += size
+	}
+
+	a := make([][]byte, n)
+	na := 0
+	fieldStart := -1
+	for i := 0; i <= len(s) && na < n; {
+		r, size := utf8.DecodeRune(s[i:])
+		if fieldStart < 0 && size > 0 && !f(r) {
+			fieldStart = i
+			i += size
+			continue
+		}
+		if fieldStart >= 0 && (size == 0 || f(r)) {
+			a[na] = s[fieldStart:i]
+			na++
+			fieldStart = -1
+		}
+		if size == 0 {
+			break
+		}
+		i += size
+	}
+	return a[0:na]
+}
+
+// Join concatenates the elements of s to create a new byte slice. The separator
+// sep is placed between elements in the resulting slice.
+func Join(s [][]byte, sep []byte) []byte {
+	if len(s) == 0 {
+		return []byte{}
+	}
+	if len(s) == 1 {
+		// Just return a copy.
+		return append([]byte(nil), s[0]...)
+	}
+	n := len(sep) * (len(s) - 1)
+	for _, v := range s {
+		n += len(v)
+	}
+
+	b := make([]byte, n)
+	bp := copy(b, s[0])
+	for _, v := range s[1:] {
+		bp += copy(b[bp:], sep)
+		bp += copy(b[bp:], v)
+	}
+	return b
+}
+
+// HasPrefix tests whether the byte slice s begins with prefix.
+func HasPrefix(s, prefix []byte) bool {
+	return len(s) >= len(prefix) && Equal(s[0:len(prefix)], prefix)
+}
+
+// HasSuffix tests whether the byte slice s ends with suffix.
+func HasSuffix(s, suffix []byte) bool {
+	return len(s) >= len(suffix) && Equal(s[len(s)-len(suffix):], suffix)
+}
+
+// Map returns a copy of the byte slice s with all its characters modified
+// according to the mapping function. If mapping returns a negative value, the character is
+// dropped from the string with no replacement.  The characters in s and the
+// output are interpreted as UTF-8-encoded Unicode code points.
+func Map(mapping func(r rune) rune, s []byte) []byte {
+	// In the worst case, the slice can grow when mapped, making
+	// things unpleasant.  But it's so rare we barge in assuming it's
+	// fine.  It could also shrink but that falls out naturally.
+	maxbytes := len(s) // length of b
+	nbytes := 0        // number of bytes encoded in b
+	b := make([]byte, maxbytes)
+	for i := 0; i < len(s); {
+		wid := 1
+		r := rune(s[i])
+		if r >= utf8.RuneSelf {
+			r, wid = utf8.DecodeRune(s[i:])
+		}
+		r = mapping(r)
+		if r >= 0 {
+			rl := utf8.RuneLen(r)
+			if rl < 0 {
+				rl = len(string(utf8.RuneError))
+			}
+			if nbytes+rl > maxbytes {
+				// Grow the buffer.
+				maxbytes = maxbytes*2 + utf8.UTFMax
+				nb := make([]byte, maxbytes)
+				copy(nb, b[0:nbytes])
+				b = nb
+			}
+			nbytes += utf8.EncodeRune(b[nbytes:maxbytes], r)
+		}
+		i += wid
+	}
+	return b[0:nbytes]
+}
+
+// Repeat returns a new byte slice consisting of count copies of b.
+func Repeat(b []byte, count int) []byte {
+	nb := make([]byte, len(b)*count)
+	bp := copy(nb, b)
+	for bp < len(nb) {
+		copy(nb[bp:], nb[:bp])
+		bp *= 2
+	}
+	return nb
+}
+
+// ToUpper returns a copy of the byte slice s with all Unicode letters mapped to their upper case.
+func ToUpper(s []byte) []byte { return Map(unicode.ToUpper, s) }
+
+// ToLower returns a copy of the byte slice s with all Unicode letters mapped to their lower case.
+func ToLower(s []byte) []byte { return Map(unicode.ToLower, s) }
+
+// ToTitle returns a copy of the byte slice s with all Unicode letters mapped to their title case.
+func ToTitle(s []byte) []byte { return Map(unicode.ToTitle, s) }
+
+// ToUpperSpecial returns a copy of the byte slice s with all Unicode letters mapped to their
+// upper case, giving priority to the special casing rules.
+func ToUpperSpecial(_case unicode.SpecialCase, s []byte) []byte {
+	return Map(func(r rune) rune { return _case.ToUpper(r) }, s)
+}
+
+// ToLowerSpecial returns a copy of the byte slice s with all Unicode letters mapped to their
+// lower case, giving priority to the special casing rules.
+func ToLowerSpecial(_case unicode.SpecialCase, s []byte) []byte {
+	return Map(func(r rune) rune { return _case.ToLower(r) }, s)
+}
+
+// ToTitleSpecial returns a copy of the byte slice s with all Unicode letters mapped to their
+// title case, giving priority to the special casing rules.
+func ToTitleSpecial(_case unicode.SpecialCase, s []byte) []byte {
+	return Map(func(r rune) rune { return _case.ToTitle(r) }, s)
+}
+
+// isSeparator reports whether the rune could mark a word boundary.
+// TODO: update when package unicode captures more of the properties.
+func isSeparator(r rune) bool {
+	// ASCII alphanumerics and underscore are not separators
+	if r <= 0x7F {
+		switch {
+		case '0' <= r && r <= '9':
+			return false
+		case 'a' <= r && r <= 'z':
+			return false
+		case 'A' <= r && r <= 'Z':
+			return false
+		case r == '_':
+			return false
+		}
+		return true
+	}
+	// Letters and digits are not separators
+	if unicode.IsLetter(r) || unicode.IsDigit(r) {
+		return false
+	}
+	// Otherwise, all we can do for now is treat spaces as separators.
+	return unicode.IsSpace(r)
+}
+
+// Title returns a copy of s with all Unicode letters that begin words
+// mapped to their title case.
+//
+// BUG: The rule Title uses for word boundaries does not handle Unicode punctuation properly.
+func Title(s []byte) []byte {
+	// Use a closure here to remember state.
+	// Hackish but effective. Depends on Map scanning in order and calling
+	// the closure once per rune.
+	prev := ' '
+	return Map(
+		func(r rune) rune {
+			if isSeparator(prev) {
+				prev = r
+				return unicode.ToTitle(r)
+			}
+			prev = r
+			return r
+		},
+		s)
+}
+
+// TrimLeftFunc returns a subslice of s by slicing off all leading UTF-8-encoded
+// Unicode code points c that satisfy f(c).
+func TrimLeftFunc(s []byte, f func(r rune) bool) []byte {
+	i := indexFunc(s, f, false)
+	if i == -1 {
+		return nil
+	}
+	return s[i:]
+}
+
+// TrimRightFunc returns a subslice of s by slicing off all trailing UTF-8
+// encoded Unicode code points c that satisfy f(c).
+func TrimRightFunc(s []byte, f func(r rune) bool) []byte {
+	i := lastIndexFunc(s, f, false)
+	if i >= 0 && s[i] >= utf8.RuneSelf {
+		_, wid := utf8.DecodeRune(s[i:])
+		i += wid
+	} else {
+		i++
+	}
+	return s[0:i]
+}
+
+// TrimFunc returns a subslice of s by slicing off all leading and trailing
+// UTF-8-encoded Unicode code points c that satisfy f(c).
+func TrimFunc(s []byte, f func(r rune) bool) []byte {
+	return TrimRightFunc(TrimLeftFunc(s, f), f)
+}
+
+// TrimPrefix returns s without the provided leading prefix string.
+// If s doesn't start with prefix, s is returned unchanged.
+func TrimPrefix(s, prefix []byte) []byte {
+	if HasPrefix(s, prefix) {
+		return s[len(prefix):]
+	}
+	return s
+}
+
+// TrimSuffix returns s without the provided trailing suffix string.
+// If s doesn't end with suffix, s is returned unchanged.
+func TrimSuffix(s, suffix []byte) []byte {
+	if HasSuffix(s, suffix) {
+		return s[:len(s)-len(suffix)]
+	}
+	return s
+}
+
+// IndexFunc interprets s as a sequence of UTF-8-encoded Unicode code points.
+// It returns the byte index in s of the first Unicode
+// code point satisfying f(c), or -1 if none do.
+func IndexFunc(s []byte, f func(r rune) bool) int {
+	return indexFunc(s, f, true)
+}
+
+// LastIndexFunc interprets s as a sequence of UTF-8-encoded Unicode code points.
+// It returns the byte index in s of the last Unicode
+// code point satisfying f(c), or -1 if none do.
+func LastIndexFunc(s []byte, f func(r rune) bool) int {
+	return lastIndexFunc(s, f, true)
+}
+
+// indexFunc is the same as IndexFunc except that if
+// truth==false, the sense of the predicate function is
+// inverted.
+func indexFunc(s []byte, f func(r rune) bool, truth bool) int {
+	start := 0
+	for start < len(s) {
+		wid := 1
+		r := rune(s[start])
+		if r >= utf8.RuneSelf {
+			r, wid = utf8.DecodeRune(s[start:])
+		}
+		if f(r) == truth {
+			return start
+		}
+		start += wid
+	}
+	return -1
+}
+
+// lastIndexFunc is the same as LastIndexFunc except that if
+// truth==false, the sense of the predicate function is
+// inverted.
+func lastIndexFunc(s []byte, f func(r rune) bool, truth bool) int {
+	for i := len(s); i > 0; {
+		r, size := rune(s[i-1]), 1
+		if r >= utf8.RuneSelf {
+			r, size = utf8.DecodeLastRune(s[0:i])
+		}
+		i -= size
+		if f(r) == truth {
+			return i
+		}
+	}
+	return -1
+}
+
+func makeCutsetFunc(cutset string) func(r rune) bool {
+	return func(r rune) bool {
+		for _, c := range cutset {
+			if c == r {
+				return true
+			}
+		}
+		return false
+	}
+}
+
+// Trim returns a subslice of s by slicing off all leading and
+// trailing UTF-8-encoded Unicode code points contained in cutset.
+func Trim(s []byte, cutset string) []byte {
+	return TrimFunc(s, makeCutsetFunc(cutset))
+}
+
+// TrimLeft returns a subslice of s by slicing off all leading
+// UTF-8-encoded Unicode code points contained in cutset.
+func TrimLeft(s []byte, cutset string) []byte {
+	return TrimLeftFunc(s, makeCutsetFunc(cutset))
+}
+
+// TrimRight returns a subslice of s by slicing off all trailing
+// UTF-8-encoded Unicode code points that are contained in cutset.
+func TrimRight(s []byte, cutset string) []byte {
+	return TrimRightFunc(s, makeCutsetFunc(cutset))
+}
+
+// TrimSpace returns a subslice of s by slicing off all leading and
+// trailing white space, as defined by Unicode.
+func TrimSpace(s []byte) []byte {
+	return TrimFunc(s, unicode.IsSpace)
+}
+
+// Runes returns a slice of runes (Unicode code points) equivalent to s.
+func Runes(s []byte) []rune {
+	t := make([]rune, utf8.RuneCount(s))
+	i := 0
+	for len(s) > 0 {
+		r, l := utf8.DecodeRune(s)
+		t[i] = r
+		i++
+		s = s[l:]
+	}
+	return t
+}
+
+// Replace returns a copy of the slice s with the first n
+// non-overlapping instances of old replaced by new.
+// If old is empty, it matches at the beginning of the slice
+// and after each UTF-8 sequence, yielding up to k+1 replacements
+// for a k-rune slice.
+// If n < 0, there is no limit on the number of replacements.
+func Replace(s, old, new []byte, n int) []byte {
+	m := 0
+	if n != 0 {
+		// Compute number of replacements.
+		m = Count(s, old)
+	}
+	if m == 0 {
+		// Just return a copy.
+		return append([]byte(nil), s...)
+	}
+	if n < 0 || m < n {
+		n = m
+	}
+
+	// Apply replacements to buffer.
+	t := make([]byte, len(s)+n*(len(new)-len(old)))
+	w := 0
+	start := 0
+	for i := 0; i < n; i++ {
+		j := start
+		if len(old) == 0 {
+			if i > 0 {
+				_, wid := utf8.DecodeRune(s[start:])
+				j += wid
+			}
+		} else {
+			j += Index(s[start:], old)
+		}
+		w += copy(t[w:], s[start:j])
+		w += copy(t[w:], new)
+		start = j + len(old)
+	}
+	w += copy(t[w:], s[start:])
+	return t[0:w]
+}
+
+// EqualFold reports whether s and t, interpreted as UTF-8 strings,
+// are equal under Unicode case-folding.
+func EqualFold(s, t []byte) bool {
+	for len(s) != 0 && len(t) != 0 {
+		// Extract first rune from each.
+		var sr, tr rune
+		if s[0] < utf8.RuneSelf {
+			sr, s = rune(s[0]), s[1:]
+		} else {
+			r, size := utf8.DecodeRune(s)
+			sr, s = r, s[size:]
+		}
+		if t[0] < utf8.RuneSelf {
+			tr, t = rune(t[0]), t[1:]
+		} else {
+			r, size := utf8.DecodeRune(t)
+			tr, t = r, t[size:]
+		}
+
+		// If they match, keep going; if not, return false.
+
+		// Easy case.
+		if tr == sr {
+			continue
+		}
+
+		// Make sr < tr to simplify what follows.
+		if tr < sr {
+			tr, sr = sr, tr
+		}
+		// Fast check for ASCII.
+		if tr < utf8.RuneSelf && 'A' <= sr && sr <= 'Z' {
+			// ASCII, and sr is upper case.  tr must be lower case.
+			if tr == sr+'a'-'A' {
+				continue
+			}
+			return false
+		}
+
+		// General case.  SimpleFold(x) returns the next equivalent rune > x
+		// or wraps around to smaller values.
+		r := unicode.SimpleFold(sr)
+		for r != sr && r < tr {
+			r = unicode.SimpleFold(r)
+		}
+		if r == tr {
+			continue
+		}
+		return false
+	}
+
+	// One string is empty.  Are both?
+	return len(s) == len(t)
+}
diff --git a/src/pkg/bytes/bytes_decl.go b/src/bytes/bytes_decl.go
similarity index 100%
rename from src/pkg/bytes/bytes_decl.go
rename to src/bytes/bytes_decl.go
diff --git a/src/bytes/bytes_test.go b/src/bytes/bytes_test.go
new file mode 100644
index 0000000..980c41d
--- /dev/null
+++ b/src/bytes/bytes_test.go
@@ -0,0 +1,1240 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package bytes_test
+
+import (
+	. "bytes"
+	"math/rand"
+	"reflect"
+	"testing"
+	"unicode"
+	"unicode/utf8"
+)
+
+func eq(a, b []string) bool {
+	if len(a) != len(b) {
+		return false
+	}
+	for i := 0; i < len(a); i++ {
+		if a[i] != b[i] {
+			return false
+		}
+	}
+	return true
+}
+
+func sliceOfString(s [][]byte) []string {
+	result := make([]string, len(s))
+	for i, v := range s {
+		result[i] = string(v)
+	}
+	return result
+}
+
+// For ease of reading, the test cases use strings that are converted to byte
+// slices before invoking the functions.
+
+var abcd = "abcd"
+var faces = "☺☻☹"
+var commas = "1,2,3,4"
+var dots = "1....2....3....4"
+
+type BinOpTest struct {
+	a string
+	b string
+	i int
+}
+
+var equalTests = []struct {
+	a, b []byte
+	i    int
+}{
+	{[]byte(""), []byte(""), 0},
+	{[]byte("a"), []byte(""), 1},
+	{[]byte(""), []byte("a"), -1},
+	{[]byte("abc"), []byte("abc"), 0},
+	{[]byte("ab"), []byte("abc"), -1},
+	{[]byte("abc"), []byte("ab"), 1},
+	{[]byte("x"), []byte("ab"), 1},
+	{[]byte("ab"), []byte("x"), -1},
+	{[]byte("x"), []byte("a"), 1},
+	{[]byte("b"), []byte("x"), -1},
+	// test runtime·memeq's chunked implementation
+	{[]byte("abcdefgh"), []byte("abcdefgh"), 0},
+	{[]byte("abcdefghi"), []byte("abcdefghi"), 0},
+	{[]byte("abcdefghi"), []byte("abcdefghj"), -1},
+	// nil tests
+	{nil, nil, 0},
+	{[]byte(""), nil, 0},
+	{nil, []byte(""), 0},
+	{[]byte("a"), nil, 1},
+	{nil, []byte("a"), -1},
+}
+
+func TestEqual(t *testing.T) {
+	for _, tt := range compareTests {
+		eql := Equal(tt.a, tt.b)
+		if eql != (tt.i == 0) {
+			t.Errorf(`Equal(%q, %q) = %v`, tt.a, tt.b, eql)
+		}
+		eql = EqualPortable(tt.a, tt.b)
+		if eql != (tt.i == 0) {
+			t.Errorf(`EqualPortable(%q, %q) = %v`, tt.a, tt.b, eql)
+		}
+	}
+}
+
+func TestEqualExhaustive(t *testing.T) {
+	var size = 128
+	if testing.Short() {
+		size = 32
+	}
+	a := make([]byte, size)
+	b := make([]byte, size)
+	b_init := make([]byte, size)
+	// randomish but deterministic data
+	for i := 0; i < size; i++ {
+		a[i] = byte(17 * i)
+		b_init[i] = byte(23*i + 100)
+	}
+
+	for len := 0; len <= size; len++ {
+		for x := 0; x <= size-len; x++ {
+			for y := 0; y <= size-len; y++ {
+				copy(b, b_init)
+				copy(b[y:y+len], a[x:x+len])
+				if !Equal(a[x:x+len], b[y:y+len]) || !Equal(b[y:y+len], a[x:x+len]) {
+					t.Errorf("Equal(%d, %d, %d) = false", len, x, y)
+				}
+			}
+		}
+	}
+}
+
+// make sure Equal returns false for minimally different strings.  The data
+// is all zeros except for a single one in one location.
+func TestNotEqual(t *testing.T) {
+	var size = 128
+	if testing.Short() {
+		size = 32
+	}
+	a := make([]byte, size)
+	b := make([]byte, size)
+
+	for len := 0; len <= size; len++ {
+		for x := 0; x <= size-len; x++ {
+			for y := 0; y <= size-len; y++ {
+				for diffpos := x; diffpos < x+len; diffpos++ {
+					a[diffpos] = 1
+					if Equal(a[x:x+len], b[y:y+len]) || Equal(b[y:y+len], a[x:x+len]) {
+						t.Errorf("NotEqual(%d, %d, %d, %d) = true", len, x, y, diffpos)
+					}
+					a[diffpos] = 0
+				}
+			}
+		}
+	}
+}
+
+var indexTests = []BinOpTest{
+	{"", "", 0},
+	{"", "a", -1},
+	{"", "foo", -1},
+	{"fo", "foo", -1},
+	{"foo", "baz", -1},
+	{"foo", "foo", 0},
+	{"oofofoofooo", "f", 2},
+	{"oofofoofooo", "foo", 4},
+	{"barfoobarfoo", "foo", 3},
+	{"foo", "", 0},
+	{"foo", "o", 1},
+	{"abcABCabc", "A", 3},
+	// cases with one byte strings - test IndexByte and special case in Index()
+	{"", "a", -1},
+	{"x", "a", -1},
+	{"x", "x", 0},
+	{"abc", "a", 0},
+	{"abc", "b", 1},
+	{"abc", "c", 2},
+	{"abc", "x", -1},
+	{"barfoobarfooyyyzzzyyyzzzyyyzzzyyyxxxzzzyyy", "x", 33},
+	{"foofyfoobarfoobar", "y", 4},
+	{"oooooooooooooooooooooo", "r", -1},
+}
+
+var lastIndexTests = []BinOpTest{
+	{"", "", 0},
+	{"", "a", -1},
+	{"", "foo", -1},
+	{"fo", "foo", -1},
+	{"foo", "foo", 0},
+	{"foo", "f", 0},
+	{"oofofoofooo", "f", 7},
+	{"oofofoofooo", "foo", 7},
+	{"barfoobarfoo", "foo", 9},
+	{"foo", "", 3},
+	{"foo", "o", 2},
+	{"abcABCabc", "A", 3},
+	{"abcABCabc", "a", 6},
+}
+
+var indexAnyTests = []BinOpTest{
+	{"", "", -1},
+	{"", "a", -1},
+	{"", "abc", -1},
+	{"a", "", -1},
+	{"a", "a", 0},
+	{"aaa", "a", 0},
+	{"abc", "xyz", -1},
+	{"abc", "xcz", 2},
+	{"ab☺c", "x☺yz", 2},
+	{"aRegExp*", ".(|)*+?^$[]", 7},
+	{dots + dots + dots, " ", -1},
+}
+
+var lastIndexAnyTests = []BinOpTest{
+	{"", "", -1},
+	{"", "a", -1},
+	{"", "abc", -1},
+	{"a", "", -1},
+	{"a", "a", 0},
+	{"aaa", "a", 2},
+	{"abc", "xyz", -1},
+	{"abc", "ab", 1},
+	{"a☺b☻c☹d", "uvw☻xyz", 2 + len("☺")},
+	{"a.RegExp*", ".(|)*+?^$[]", 8},
+	{dots + dots + dots, " ", -1},
+}
+
+var indexRuneTests = []BinOpTest{
+	{"", "a", -1},
+	{"", "☺", -1},
+	{"foo", "☹", -1},
+	{"foo", "o", 1},
+	{"foo☺bar", "☺", 3},
+	{"foo☺☻☹bar", "☹", 9},
+}
+
+// Execute f on each test case.  funcName should be the name of f; it's used
+// in failure reports.
+func runIndexTests(t *testing.T, f func(s, sep []byte) int, funcName string, testCases []BinOpTest) {
+	for _, test := range testCases {
+		a := []byte(test.a)
+		b := []byte(test.b)
+		actual := f(a, b)
+		if actual != test.i {
+			t.Errorf("%s(%q,%q) = %v; want %v", funcName, a, b, actual, test.i)
+		}
+	}
+}
+
+func runIndexAnyTests(t *testing.T, f func(s []byte, chars string) int, funcName string, testCases []BinOpTest) {
+	for _, test := range testCases {
+		a := []byte(test.a)
+		actual := f(a, test.b)
+		if actual != test.i {
+			t.Errorf("%s(%q,%q) = %v; want %v", funcName, a, test.b, actual, test.i)
+		}
+	}
+}
+
+func TestIndex(t *testing.T)     { runIndexTests(t, Index, "Index", indexTests) }
+func TestLastIndex(t *testing.T) { runIndexTests(t, LastIndex, "LastIndex", lastIndexTests) }
+func TestIndexAny(t *testing.T)  { runIndexAnyTests(t, IndexAny, "IndexAny", indexAnyTests) }
+func TestLastIndexAny(t *testing.T) {
+	runIndexAnyTests(t, LastIndexAny, "LastIndexAny", lastIndexAnyTests)
+}
+
+func TestIndexByte(t *testing.T) {
+	for _, tt := range indexTests {
+		if len(tt.b) != 1 {
+			continue
+		}
+		a := []byte(tt.a)
+		b := tt.b[0]
+		pos := IndexByte(a, b)
+		if pos != tt.i {
+			t.Errorf(`IndexByte(%q, '%c') = %v`, tt.a, b, pos)
+		}
+		posp := IndexBytePortable(a, b)
+		if posp != tt.i {
+			t.Errorf(`indexBytePortable(%q, '%c') = %v`, tt.a, b, posp)
+		}
+	}
+}
+
+// test a larger buffer with different sizes and alignments
+func TestIndexByteBig(t *testing.T) {
+	var n = 1024
+	if testing.Short() {
+		n = 128
+	}
+	b := make([]byte, n)
+	for i := 0; i < n; i++ {
+		// different start alignments
+		b1 := b[i:]
+		for j := 0; j < len(b1); j++ {
+			b1[j] = 'x'
+			pos := IndexByte(b1, 'x')
+			if pos != j {
+				t.Errorf("IndexByte(%q, 'x') = %v", b1, pos)
+			}
+			b1[j] = 0
+			pos = IndexByte(b1, 'x')
+			if pos != -1 {
+				t.Errorf("IndexByte(%q, 'x') = %v", b1, pos)
+			}
+		}
+		// different end alignments
+		b1 = b[:i]
+		for j := 0; j < len(b1); j++ {
+			b1[j] = 'x'
+			pos := IndexByte(b1, 'x')
+			if pos != j {
+				t.Errorf("IndexByte(%q, 'x') = %v", b1, pos)
+			}
+			b1[j] = 0
+			pos = IndexByte(b1, 'x')
+			if pos != -1 {
+				t.Errorf("IndexByte(%q, 'x') = %v", b1, pos)
+			}
+		}
+		// different start and end alignments
+		b1 = b[i/2 : n-(i+1)/2]
+		for j := 0; j < len(b1); j++ {
+			b1[j] = 'x'
+			pos := IndexByte(b1, 'x')
+			if pos != j {
+				t.Errorf("IndexByte(%q, 'x') = %v", b1, pos)
+			}
+			b1[j] = 0
+			pos = IndexByte(b1, 'x')
+			if pos != -1 {
+				t.Errorf("IndexByte(%q, 'x') = %v", b1, pos)
+			}
+		}
+	}
+}
+
+func TestIndexRune(t *testing.T) {
+	for _, tt := range indexRuneTests {
+		a := []byte(tt.a)
+		r, _ := utf8.DecodeRuneInString(tt.b)
+		pos := IndexRune(a, r)
+		if pos != tt.i {
+			t.Errorf(`IndexRune(%q, '%c') = %v`, tt.a, r, pos)
+		}
+	}
+}
+
+var bmbuf []byte
+
+func BenchmarkIndexByte32(b *testing.B)          { bmIndexByte(b, IndexByte, 32) }
+func BenchmarkIndexByte4K(b *testing.B)          { bmIndexByte(b, IndexByte, 4<<10) }
+func BenchmarkIndexByte4M(b *testing.B)          { bmIndexByte(b, IndexByte, 4<<20) }
+func BenchmarkIndexByte64M(b *testing.B)         { bmIndexByte(b, IndexByte, 64<<20) }
+func BenchmarkIndexBytePortable32(b *testing.B)  { bmIndexByte(b, IndexBytePortable, 32) }
+func BenchmarkIndexBytePortable4K(b *testing.B)  { bmIndexByte(b, IndexBytePortable, 4<<10) }
+func BenchmarkIndexBytePortable4M(b *testing.B)  { bmIndexByte(b, IndexBytePortable, 4<<20) }
+func BenchmarkIndexBytePortable64M(b *testing.B) { bmIndexByte(b, IndexBytePortable, 64<<20) }
+
+func bmIndexByte(b *testing.B, index func([]byte, byte) int, n int) {
+	if len(bmbuf) < n {
+		bmbuf = make([]byte, n)
+	}
+	b.SetBytes(int64(n))
+	buf := bmbuf[0:n]
+	buf[n-1] = 'x'
+	for i := 0; i < b.N; i++ {
+		j := index(buf, 'x')
+		if j != n-1 {
+			b.Fatal("bad index", j)
+		}
+	}
+	buf[n-1] = '\x00'
+}
+
+func BenchmarkEqual0(b *testing.B) {
+	var buf [4]byte
+	buf1 := buf[0:0]
+	buf2 := buf[1:1]
+	for i := 0; i < b.N; i++ {
+		eq := Equal(buf1, buf2)
+		if !eq {
+			b.Fatal("bad equal")
+		}
+	}
+}
+
+func BenchmarkEqual1(b *testing.B)           { bmEqual(b, Equal, 1) }
+func BenchmarkEqual6(b *testing.B)           { bmEqual(b, Equal, 6) }
+func BenchmarkEqual9(b *testing.B)           { bmEqual(b, Equal, 9) }
+func BenchmarkEqual15(b *testing.B)          { bmEqual(b, Equal, 15) }
+func BenchmarkEqual16(b *testing.B)          { bmEqual(b, Equal, 16) }
+func BenchmarkEqual20(b *testing.B)          { bmEqual(b, Equal, 20) }
+func BenchmarkEqual32(b *testing.B)          { bmEqual(b, Equal, 32) }
+func BenchmarkEqual4K(b *testing.B)          { bmEqual(b, Equal, 4<<10) }
+func BenchmarkEqual4M(b *testing.B)          { bmEqual(b, Equal, 4<<20) }
+func BenchmarkEqual64M(b *testing.B)         { bmEqual(b, Equal, 64<<20) }
+func BenchmarkEqualPort1(b *testing.B)       { bmEqual(b, EqualPortable, 1) }
+func BenchmarkEqualPort6(b *testing.B)       { bmEqual(b, EqualPortable, 6) }
+func BenchmarkEqualPort32(b *testing.B)      { bmEqual(b, EqualPortable, 32) }
+func BenchmarkEqualPort4K(b *testing.B)      { bmEqual(b, EqualPortable, 4<<10) }
+func BenchmarkEqualPortable4M(b *testing.B)  { bmEqual(b, EqualPortable, 4<<20) }
+func BenchmarkEqualPortable64M(b *testing.B) { bmEqual(b, EqualPortable, 64<<20) }
+
+func bmEqual(b *testing.B, equal func([]byte, []byte) bool, n int) {
+	if len(bmbuf) < 2*n {
+		bmbuf = make([]byte, 2*n)
+	}
+	b.SetBytes(int64(n))
+	buf1 := bmbuf[0:n]
+	buf2 := bmbuf[n : 2*n]
+	buf1[n-1] = 'x'
+	buf2[n-1] = 'x'
+	for i := 0; i < b.N; i++ {
+		eq := equal(buf1, buf2)
+		if !eq {
+			b.Fatal("bad equal")
+		}
+	}
+	buf1[n-1] = '\x00'
+	buf2[n-1] = '\x00'
+}
+
+func BenchmarkIndex32(b *testing.B)  { bmIndex(b, Index, 32) }
+func BenchmarkIndex4K(b *testing.B)  { bmIndex(b, Index, 4<<10) }
+func BenchmarkIndex4M(b *testing.B)  { bmIndex(b, Index, 4<<20) }
+func BenchmarkIndex64M(b *testing.B) { bmIndex(b, Index, 64<<20) }
+
+func bmIndex(b *testing.B, index func([]byte, []byte) int, n int) {
+	if len(bmbuf) < n {
+		bmbuf = make([]byte, n)
+	}
+	b.SetBytes(int64(n))
+	buf := bmbuf[0:n]
+	buf[n-1] = 'x'
+	for i := 0; i < b.N; i++ {
+		j := index(buf, buf[n-7:])
+		if j != n-7 {
+			b.Fatal("bad index", j)
+		}
+	}
+	buf[n-1] = '\x00'
+}
+
+func BenchmarkIndexEasy32(b *testing.B)  { bmIndexEasy(b, Index, 32) }
+func BenchmarkIndexEasy4K(b *testing.B)  { bmIndexEasy(b, Index, 4<<10) }
+func BenchmarkIndexEasy4M(b *testing.B)  { bmIndexEasy(b, Index, 4<<20) }
+func BenchmarkIndexEasy64M(b *testing.B) { bmIndexEasy(b, Index, 64<<20) }
+
+func bmIndexEasy(b *testing.B, index func([]byte, []byte) int, n int) {
+	if len(bmbuf) < n {
+		bmbuf = make([]byte, n)
+	}
+	b.SetBytes(int64(n))
+	buf := bmbuf[0:n]
+	buf[n-1] = 'x'
+	buf[n-7] = 'x'
+	for i := 0; i < b.N; i++ {
+		j := index(buf, buf[n-7:])
+		if j != n-7 {
+			b.Fatal("bad index", j)
+		}
+	}
+	buf[n-1] = '\x00'
+	buf[n-7] = '\x00'
+}
+
+func BenchmarkCount32(b *testing.B)  { bmCount(b, Count, 32) }
+func BenchmarkCount4K(b *testing.B)  { bmCount(b, Count, 4<<10) }
+func BenchmarkCount4M(b *testing.B)  { bmCount(b, Count, 4<<20) }
+func BenchmarkCount64M(b *testing.B) { bmCount(b, Count, 64<<20) }
+
+func bmCount(b *testing.B, count func([]byte, []byte) int, n int) {
+	if len(bmbuf) < n {
+		bmbuf = make([]byte, n)
+	}
+	b.SetBytes(int64(n))
+	buf := bmbuf[0:n]
+	buf[n-1] = 'x'
+	for i := 0; i < b.N; i++ {
+		j := count(buf, buf[n-7:])
+		if j != 1 {
+			b.Fatal("bad count", j)
+		}
+	}
+	buf[n-1] = '\x00'
+}
+
+func BenchmarkCountEasy32(b *testing.B)  { bmCountEasy(b, Count, 32) }
+func BenchmarkCountEasy4K(b *testing.B)  { bmCountEasy(b, Count, 4<<10) }
+func BenchmarkCountEasy4M(b *testing.B)  { bmCountEasy(b, Count, 4<<20) }
+func BenchmarkCountEasy64M(b *testing.B) { bmCountEasy(b, Count, 64<<20) }
+
+func bmCountEasy(b *testing.B, count func([]byte, []byte) int, n int) {
+	if len(bmbuf) < n {
+		bmbuf = make([]byte, n)
+	}
+	b.SetBytes(int64(n))
+	buf := bmbuf[0:n]
+	buf[n-1] = 'x'
+	buf[n-7] = 'x'
+	for i := 0; i < b.N; i++ {
+		j := count(buf, buf[n-7:])
+		if j != 1 {
+			b.Fatal("bad count", j)
+		}
+	}
+	buf[n-1] = '\x00'
+	buf[n-7] = '\x00'
+}
+
+type ExplodeTest struct {
+	s string
+	n int
+	a []string
+}
+
+var explodetests = []ExplodeTest{
+	{"", -1, []string{}},
+	{abcd, -1, []string{"a", "b", "c", "d"}},
+	{faces, -1, []string{"☺", "☻", "☹"}},
+	{abcd, 2, []string{"a", "bcd"}},
+}
+
+func TestExplode(t *testing.T) {
+	for _, tt := range explodetests {
+		a := SplitN([]byte(tt.s), nil, tt.n)
+		result := sliceOfString(a)
+		if !eq(result, tt.a) {
+			t.Errorf(`Explode("%s", %d) = %v; want %v`, tt.s, tt.n, result, tt.a)
+			continue
+		}
+		s := Join(a, []byte{})
+		if string(s) != tt.s {
+			t.Errorf(`Join(Explode("%s", %d), "") = "%s"`, tt.s, tt.n, s)
+		}
+	}
+}
+
+type SplitTest struct {
+	s   string
+	sep string
+	n   int
+	a   []string
+}
+
+var splittests = []SplitTest{
+	{abcd, "a", 0, nil},
+	{abcd, "a", -1, []string{"", "bcd"}},
+	{abcd, "z", -1, []string{"abcd"}},
+	{abcd, "", -1, []string{"a", "b", "c", "d"}},
+	{commas, ",", -1, []string{"1", "2", "3", "4"}},
+	{dots, "...", -1, []string{"1", ".2", ".3", ".4"}},
+	{faces, "☹", -1, []string{"☺☻", ""}},
+	{faces, "~", -1, []string{faces}},
+	{faces, "", -1, []string{"☺", "☻", "☹"}},
+	{"1 2 3 4", " ", 3, []string{"1", "2", "3 4"}},
+	{"1 2", " ", 3, []string{"1", "2"}},
+	{"123", "", 2, []string{"1", "23"}},
+	{"123", "", 17, []string{"1", "2", "3"}},
+}
+
+func TestSplit(t *testing.T) {
+	for _, tt := range splittests {
+		a := SplitN([]byte(tt.s), []byte(tt.sep), tt.n)
+		result := sliceOfString(a)
+		if !eq(result, tt.a) {
+			t.Errorf(`Split(%q, %q, %d) = %v; want %v`, tt.s, tt.sep, tt.n, result, tt.a)
+			continue
+		}
+		if tt.n == 0 {
+			continue
+		}
+		s := Join(a, []byte(tt.sep))
+		if string(s) != tt.s {
+			t.Errorf(`Join(Split(%q, %q, %d), %q) = %q`, tt.s, tt.sep, tt.n, tt.sep, s)
+		}
+		if tt.n < 0 {
+			b := Split([]byte(tt.s), []byte(tt.sep))
+			if !reflect.DeepEqual(a, b) {
+				t.Errorf("Split disagrees withSplitN(%q, %q, %d) = %v; want %v", tt.s, tt.sep, tt.n, b, a)
+			}
+		}
+		if len(a) > 0 {
+			in, out := a[0], s
+			if cap(in) == cap(out) && &in[:1][0] == &out[:1][0] {
+				t.Errorf("Join(%#v, %q) didn't copy", a, tt.sep)
+			}
+		}
+	}
+}
+
+var splitaftertests = []SplitTest{
+	{abcd, "a", -1, []string{"a", "bcd"}},
+	{abcd, "z", -1, []string{"abcd"}},
+	{abcd, "", -1, []string{"a", "b", "c", "d"}},
+	{commas, ",", -1, []string{"1,", "2,", "3,", "4"}},
+	{dots, "...", -1, []string{"1...", ".2...", ".3...", ".4"}},
+	{faces, "☹", -1, []string{"☺☻☹", ""}},
+	{faces, "~", -1, []string{faces}},
+	{faces, "", -1, []string{"☺", "☻", "☹"}},
+	{"1 2 3 4", " ", 3, []string{"1 ", "2 ", "3 4"}},
+	{"1 2 3", " ", 3, []string{"1 ", "2 ", "3"}},
+	{"1 2", " ", 3, []string{"1 ", "2"}},
+	{"123", "", 2, []string{"1", "23"}},
+	{"123", "", 17, []string{"1", "2", "3"}},
+}
+
+func TestSplitAfter(t *testing.T) {
+	for _, tt := range splitaftertests {
+		a := SplitAfterN([]byte(tt.s), []byte(tt.sep), tt.n)
+		result := sliceOfString(a)
+		if !eq(result, tt.a) {
+			t.Errorf(`Split(%q, %q, %d) = %v; want %v`, tt.s, tt.sep, tt.n, result, tt.a)
+			continue
+		}
+		s := Join(a, nil)
+		if string(s) != tt.s {
+			t.Errorf(`Join(Split(%q, %q, %d), %q) = %q`, tt.s, tt.sep, tt.n, tt.sep, s)
+		}
+		if tt.n < 0 {
+			b := SplitAfter([]byte(tt.s), []byte(tt.sep))
+			if !reflect.DeepEqual(a, b) {
+				t.Errorf("SplitAfter disagrees withSplitAfterN(%q, %q, %d) = %v; want %v", tt.s, tt.sep, tt.n, b, a)
+			}
+		}
+	}
+}
+
+type FieldsTest struct {
+	s string
+	a []string
+}
+
+var fieldstests = []FieldsTest{
+	{"", []string{}},
+	{" ", []string{}},
+	{" \t ", []string{}},
+	{"  abc  ", []string{"abc"}},
+	{"1 2 3 4", []string{"1", "2", "3", "4"}},
+	{"1  2  3  4", []string{"1", "2", "3", "4"}},
+	{"1\t\t2\t\t3\t4", []string{"1", "2", "3", "4"}},
+	{"1\u20002\u20013\u20024", []string{"1", "2", "3", "4"}},
+	{"\u2000\u2001\u2002", []string{}},
+	{"\n™\t™\n", []string{"™", "™"}},
+	{faces, []string{faces}},
+}
+
+func TestFields(t *testing.T) {
+	for _, tt := range fieldstests {
+		a := Fields([]byte(tt.s))
+		result := sliceOfString(a)
+		if !eq(result, tt.a) {
+			t.Errorf("Fields(%q) = %v; want %v", tt.s, a, tt.a)
+			continue
+		}
+	}
+}
+
+func TestFieldsFunc(t *testing.T) {
+	for _, tt := range fieldstests {
+		a := FieldsFunc([]byte(tt.s), unicode.IsSpace)
+		result := sliceOfString(a)
+		if !eq(result, tt.a) {
+			t.Errorf("FieldsFunc(%q, unicode.IsSpace) = %v; want %v", tt.s, a, tt.a)
+			continue
+		}
+	}
+	pred := func(c rune) bool { return c == 'X' }
+	var fieldsFuncTests = []FieldsTest{
+		{"", []string{}},
+		{"XX", []string{}},
+		{"XXhiXXX", []string{"hi"}},
+		{"aXXbXXXcX", []string{"a", "b", "c"}},
+	}
+	for _, tt := range fieldsFuncTests {
+		a := FieldsFunc([]byte(tt.s), pred)
+		result := sliceOfString(a)
+		if !eq(result, tt.a) {
+			t.Errorf("FieldsFunc(%q) = %v, want %v", tt.s, a, tt.a)
+		}
+	}
+}
+
+// Test case for any function which accepts and returns a byte slice.
+// For ease of creation, we write the byte slices as strings.
+type StringTest struct {
+	in, out string
+}
+
+var upperTests = []StringTest{
+	{"", ""},
+	{"abc", "ABC"},
+	{"AbC123", "ABC123"},
+	{"azAZ09_", "AZAZ09_"},
+	{"\u0250\u0250\u0250\u0250\u0250", "\u2C6F\u2C6F\u2C6F\u2C6F\u2C6F"}, // grows one byte per char
+}
+
+var lowerTests = []StringTest{
+	{"", ""},
+	{"abc", "abc"},
+	{"AbC123", "abc123"},
+	{"azAZ09_", "azaz09_"},
+	{"\u2C6D\u2C6D\u2C6D\u2C6D\u2C6D", "\u0251\u0251\u0251\u0251\u0251"}, // shrinks one byte per char
+}
+
+const space = "\t\v\r\f\n\u0085\u00a0\u2000\u3000"
+
+var trimSpaceTests = []StringTest{
+	{"", ""},
+	{"abc", "abc"},
+	{space + "abc" + space, "abc"},
+	{" ", ""},
+	{" \t\r\n \t\t\r\r\n\n ", ""},
+	{" \t\r\n x\t\t\r\r\n\n ", "x"},
+	{" \u2000\t\r\n x\t\t\r\r\ny\n \u3000", "x\t\t\r\r\ny"},
+	{"1 \t\r\n2", "1 \t\r\n2"},
+	{" x\x80", "x\x80"},
+	{" x\xc0", "x\xc0"},
+	{"x \xc0\xc0 ", "x \xc0\xc0"},
+	{"x \xc0", "x \xc0"},
+	{"x \xc0 ", "x \xc0"},
+	{"x \xc0\xc0 ", "x \xc0\xc0"},
+	{"x ☺\xc0\xc0 ", "x ☺\xc0\xc0"},
+	{"x ☺ ", "x ☺"},
+}
+
+// Execute f on each test case.  funcName should be the name of f; it's used
+// in failure reports.
+func runStringTests(t *testing.T, f func([]byte) []byte, funcName string, testCases []StringTest) {
+	for _, tc := range testCases {
+		actual := string(f([]byte(tc.in)))
+		if actual != tc.out {
+			t.Errorf("%s(%q) = %q; want %q", funcName, tc.in, actual, tc.out)
+		}
+	}
+}
+
+func tenRunes(r rune) string {
+	runes := make([]rune, 10)
+	for i := range runes {
+		runes[i] = r
+	}
+	return string(runes)
+}
+
+// User-defined self-inverse mapping function
+func rot13(r rune) rune {
+	const step = 13
+	if r >= 'a' && r <= 'z' {
+		return ((r - 'a' + step) % 26) + 'a'
+	}
+	if r >= 'A' && r <= 'Z' {
+		return ((r - 'A' + step) % 26) + 'A'
+	}
+	return r
+}
+
+func TestMap(t *testing.T) {
+	// Run a couple of awful growth/shrinkage tests
+	a := tenRunes('a')
+
+	// 1.  Grow.  This triggers two reallocations in Map.
+	maxRune := func(r rune) rune { return unicode.MaxRune }
+	m := Map(maxRune, []byte(a))
+	expect := tenRunes(unicode.MaxRune)
+	if string(m) != expect {
+		t.Errorf("growing: expected %q got %q", expect, m)
+	}
+
+	// 2. Shrink
+	minRune := func(r rune) rune { return 'a' }
+	m = Map(minRune, []byte(tenRunes(unicode.MaxRune)))
+	expect = a
+	if string(m) != expect {
+		t.Errorf("shrinking: expected %q got %q", expect, m)
+	}
+
+	// 3. Rot13
+	m = Map(rot13, []byte("a to zed"))
+	expect = "n gb mrq"
+	if string(m) != expect {
+		t.Errorf("rot13: expected %q got %q", expect, m)
+	}
+
+	// 4. Rot13^2
+	m = Map(rot13, Map(rot13, []byte("a to zed")))
+	expect = "a to zed"
+	if string(m) != expect {
+		t.Errorf("rot13: expected %q got %q", expect, m)
+	}
+
+	// 5. Drop
+	dropNotLatin := func(r rune) rune {
+		if unicode.Is(unicode.Latin, r) {
+			return r
+		}
+		return -1
+	}
+	m = Map(dropNotLatin, []byte("Hello, 세계"))
+	expect = "Hello"
+	if string(m) != expect {
+		t.Errorf("drop: expected %q got %q", expect, m)
+	}
+
+	// 6. Invalid rune
+	invalidRune := func(r rune) rune {
+		return utf8.MaxRune + 1
+	}
+	m = Map(invalidRune, []byte("x"))
+	expect = "\uFFFD"
+	if string(m) != expect {
+		t.Errorf("invalidRune: expected %q got %q", expect, m)
+	}
+}
+
+func TestToUpper(t *testing.T) { runStringTests(t, ToUpper, "ToUpper", upperTests) }
+
+func TestToLower(t *testing.T) { runStringTests(t, ToLower, "ToLower", lowerTests) }
+
+func TestTrimSpace(t *testing.T) { runStringTests(t, TrimSpace, "TrimSpace", trimSpaceTests) }
+
+type RepeatTest struct {
+	in, out string
+	count   int
+}
+
+var RepeatTests = []RepeatTest{
+	{"", "", 0},
+	{"", "", 1},
+	{"", "", 2},
+	{"-", "", 0},
+	{"-", "-", 1},
+	{"-", "----------", 10},
+	{"abc ", "abc abc abc ", 3},
+}
+
+func TestRepeat(t *testing.T) {
+	for _, tt := range RepeatTests {
+		tin := []byte(tt.in)
+		tout := []byte(tt.out)
+		a := Repeat(tin, tt.count)
+		if !Equal(a, tout) {
+			t.Errorf("Repeat(%q, %d) = %q; want %q", tin, tt.count, a, tout)
+			continue
+		}
+	}
+}
+
+func runesEqual(a, b []rune) bool {
+	if len(a) != len(b) {
+		return false
+	}
+	for i, r := range a {
+		if r != b[i] {
+			return false
+		}
+	}
+	return true
+}
+
+type RunesTest struct {
+	in    string
+	out   []rune
+	lossy bool
+}
+
+var RunesTests = []RunesTest{
+	{"", []rune{}, false},
+	{" ", []rune{32}, false},
+	{"ABC", []rune{65, 66, 67}, false},
+	{"abc", []rune{97, 98, 99}, false},
+	{"\u65e5\u672c\u8a9e", []rune{26085, 26412, 35486}, false},
+	{"ab\x80c", []rune{97, 98, 0xFFFD, 99}, true},
+	{"ab\xc0c", []rune{97, 98, 0xFFFD, 99}, true},
+}
+
+func TestRunes(t *testing.T) {
+	for _, tt := range RunesTests {
+		tin := []byte(tt.in)
+		a := Runes(tin)
+		if !runesEqual(a, tt.out) {
+			t.Errorf("Runes(%q) = %v; want %v", tin, a, tt.out)
+			continue
+		}
+		if !tt.lossy {
+			// can only test reassembly if we didn't lose information
+			s := string(a)
+			if s != tt.in {
+				t.Errorf("string(Runes(%q)) = %x; want %x", tin, s, tin)
+			}
+		}
+	}
+}
+
+type TrimTest struct {
+	f            string
+	in, arg, out string
+}
+
+var trimTests = []TrimTest{
+	{"Trim", "abba", "a", "bb"},
+	{"Trim", "abba", "ab", ""},
+	{"TrimLeft", "abba", "ab", ""},
+	{"TrimRight", "abba", "ab", ""},
+	{"TrimLeft", "abba", "a", "bba"},
+	{"TrimRight", "abba", "a", "abb"},
+	{"Trim", "<tag>", "<>", "tag"},
+	{"Trim", "* listitem", " *", "listitem"},
+	{"Trim", `"quote"`, `"`, "quote"},
+	{"Trim", "\u2C6F\u2C6F\u0250\u0250\u2C6F\u2C6F", "\u2C6F", "\u0250\u0250"},
+	//empty string tests
+	{"Trim", "abba", "", "abba"},
+	{"Trim", "", "123", ""},
+	{"Trim", "", "", ""},
+	{"TrimLeft", "abba", "", "abba"},
+	{"TrimLeft", "", "123", ""},
+	{"TrimLeft", "", "", ""},
+	{"TrimRight", "abba", "", "abba"},
+	{"TrimRight", "", "123", ""},
+	{"TrimRight", "", "", ""},
+	{"TrimRight", "☺\xc0", "☺", "☺\xc0"},
+	{"TrimPrefix", "aabb", "a", "abb"},
+	{"TrimPrefix", "aabb", "b", "aabb"},
+	{"TrimSuffix", "aabb", "a", "aabb"},
+	{"TrimSuffix", "aabb", "b", "aab"},
+}
+
+func TestTrim(t *testing.T) {
+	for _, tc := range trimTests {
+		name := tc.f
+		var f func([]byte, string) []byte
+		var fb func([]byte, []byte) []byte
+		switch name {
+		case "Trim":
+			f = Trim
+		case "TrimLeft":
+			f = TrimLeft
+		case "TrimRight":
+			f = TrimRight
+		case "TrimPrefix":
+			fb = TrimPrefix
+		case "TrimSuffix":
+			fb = TrimSuffix
+		default:
+			t.Errorf("Undefined trim function %s", name)
+		}
+		var actual string
+		if f != nil {
+			actual = string(f([]byte(tc.in), tc.arg))
+		} else {
+			actual = string(fb([]byte(tc.in), []byte(tc.arg)))
+		}
+		if actual != tc.out {
+			t.Errorf("%s(%q, %q) = %q; want %q", name, tc.in, tc.arg, actual, tc.out)
+		}
+	}
+}
+
+type predicate struct {
+	f    func(r rune) bool
+	name string
+}
+
+var isSpace = predicate{unicode.IsSpace, "IsSpace"}
+var isDigit = predicate{unicode.IsDigit, "IsDigit"}
+var isUpper = predicate{unicode.IsUpper, "IsUpper"}
+var isValidRune = predicate{
+	func(r rune) bool {
+		return r != utf8.RuneError
+	},
+	"IsValidRune",
+}
+
+type TrimFuncTest struct {
+	f       predicate
+	in, out string
+}
+
+func not(p predicate) predicate {
+	return predicate{
+		func(r rune) bool {
+			return !p.f(r)
+		},
+		"not " + p.name,
+	}
+}
+
+var trimFuncTests = []TrimFuncTest{
+	{isSpace, space + " hello " + space, "hello"},
+	{isDigit, "\u0e50\u0e5212hello34\u0e50\u0e51", "hello"},
+	{isUpper, "\u2C6F\u2C6F\u2C6F\u2C6FABCDhelloEF\u2C6F\u2C6FGH\u2C6F\u2C6F", "hello"},
+	{not(isSpace), "hello" + space + "hello", space},
+	{not(isDigit), "hello\u0e50\u0e521234\u0e50\u0e51helo", "\u0e50\u0e521234\u0e50\u0e51"},
+	{isValidRune, "ab\xc0a\xc0cd", "\xc0a\xc0"},
+	{not(isValidRune), "\xc0a\xc0", "a"},
+}
+
+func TestTrimFunc(t *testing.T) {
+	for _, tc := range trimFuncTests {
+		actual := string(TrimFunc([]byte(tc.in), tc.f.f))
+		if actual != tc.out {
+			t.Errorf("TrimFunc(%q, %q) = %q; want %q", tc.in, tc.f.name, actual, tc.out)
+		}
+	}
+}
+
+type IndexFuncTest struct {
+	in          string
+	f           predicate
+	first, last int
+}
+
+var indexFuncTests = []IndexFuncTest{
+	{"", isValidRune, -1, -1},
+	{"abc", isDigit, -1, -1},
+	{"0123", isDigit, 0, 3},
+	{"a1b", isDigit, 1, 1},
+	{space, isSpace, 0, len(space) - 3}, // last rune in space is 3 bytes
+	{"\u0e50\u0e5212hello34\u0e50\u0e51", isDigit, 0, 18},
+	{"\u2C6F\u2C6F\u2C6F\u2C6FABCDhelloEF\u2C6F\u2C6FGH\u2C6F\u2C6F", isUpper, 0, 34},
+	{"12\u0e50\u0e52hello34\u0e50\u0e51", not(isDigit), 8, 12},
+
+	// tests of invalid UTF-8
+	{"\x801", isDigit, 1, 1},
+	{"\x80abc", isDigit, -1, -1},
+	{"\xc0a\xc0", isValidRune, 1, 1},
+	{"\xc0a\xc0", not(isValidRune), 0, 2},
+	{"\xc0☺\xc0", not(isValidRune), 0, 4},
+	{"\xc0☺\xc0\xc0", not(isValidRune), 0, 5},
+	{"ab\xc0a\xc0cd", not(isValidRune), 2, 4},
+	{"a\xe0\x80cd", not(isValidRune), 1, 2},
+}
+
+func TestIndexFunc(t *testing.T) {
+	for _, tc := range indexFuncTests {
+		first := IndexFunc([]byte(tc.in), tc.f.f)
+		if first != tc.first {
+			t.Errorf("IndexFunc(%q, %s) = %d; want %d", tc.in, tc.f.name, first, tc.first)
+		}
+		last := LastIndexFunc([]byte(tc.in), tc.f.f)
+		if last != tc.last {
+			t.Errorf("LastIndexFunc(%q, %s) = %d; want %d", tc.in, tc.f.name, last, tc.last)
+		}
+	}
+}
+
+type ReplaceTest struct {
+	in       string
+	old, new string
+	n        int
+	out      string
+}
+
+var ReplaceTests = []ReplaceTest{
+	{"hello", "l", "L", 0, "hello"},
+	{"hello", "l", "L", -1, "heLLo"},
+	{"hello", "x", "X", -1, "hello"},
+	{"", "x", "X", -1, ""},
+	{"radar", "r", "<r>", -1, "<r>ada<r>"},
+	{"", "", "<>", -1, "<>"},
+	{"banana", "a", "<>", -1, "b<>n<>n<>"},
+	{"banana", "a", "<>", 1, "b<>nana"},
+	{"banana", "a", "<>", 1000, "b<>n<>n<>"},
+	{"banana", "an", "<>", -1, "b<><>a"},
+	{"banana", "ana", "<>", -1, "b<>na"},
+	{"banana", "", "<>", -1, "<>b<>a<>n<>a<>n<>a<>"},
+	{"banana", "", "<>", 10, "<>b<>a<>n<>a<>n<>a<>"},
+	{"banana", "", "<>", 6, "<>b<>a<>n<>a<>n<>a"},
+	{"banana", "", "<>", 5, "<>b<>a<>n<>a<>na"},
+	{"banana", "", "<>", 1, "<>banana"},
+	{"banana", "a", "a", -1, "banana"},
+	{"banana", "a", "a", 1, "banana"},
+	{"☺☻☹", "", "<>", -1, "<>☺<>☻<>☹<>"},
+}
+
+func TestReplace(t *testing.T) {
+	for _, tt := range ReplaceTests {
+		in := append([]byte(tt.in), "<spare>"...)
+		in = in[:len(tt.in)]
+		out := Replace(in, []byte(tt.old), []byte(tt.new), tt.n)
+		if s := string(out); s != tt.out {
+			t.Errorf("Replace(%q, %q, %q, %d) = %q, want %q", tt.in, tt.old, tt.new, tt.n, s, tt.out)
+		}
+		if cap(in) == cap(out) && &in[:1][0] == &out[:1][0] {
+			t.Errorf("Replace(%q, %q, %q, %d) didn't copy", tt.in, tt.old, tt.new, tt.n)
+		}
+	}
+}
+
+type TitleTest struct {
+	in, out string
+}
+
+var TitleTests = []TitleTest{
+	{"", ""},
+	{"a", "A"},
+	{" aaa aaa aaa ", " Aaa Aaa Aaa "},
+	{" Aaa Aaa Aaa ", " Aaa Aaa Aaa "},
+	{"123a456", "123a456"},
+	{"double-blind", "Double-Blind"},
+	{"ÿøû", "Ÿøû"},
+	{"with_underscore", "With_underscore"},
+	{"unicode \xe2\x80\xa8 line separator", "Unicode \xe2\x80\xa8 Line Separator"},
+}
+
+func TestTitle(t *testing.T) {
+	for _, tt := range TitleTests {
+		if s := string(Title([]byte(tt.in))); s != tt.out {
+			t.Errorf("Title(%q) = %q, want %q", tt.in, s, tt.out)
+		}
+	}
+}
+
+var ToTitleTests = []TitleTest{
+	{"", ""},
+	{"a", "A"},
+	{" aaa aaa aaa ", " AAA AAA AAA "},
+	{" Aaa Aaa Aaa ", " AAA AAA AAA "},
+	{"123a456", "123A456"},
+	{"double-blind", "DOUBLE-BLIND"},
+	{"ÿøû", "ŸØÛ"},
+}
+
+func TestToTitle(t *testing.T) {
+	for _, tt := range ToTitleTests {
+		if s := string(ToTitle([]byte(tt.in))); s != tt.out {
+			t.Errorf("ToTitle(%q) = %q, want %q", tt.in, s, tt.out)
+		}
+	}
+}
+
+var EqualFoldTests = []struct {
+	s, t string
+	out  bool
+}{
+	{"abc", "abc", true},
+	{"ABcd", "ABcd", true},
+	{"123abc", "123ABC", true},
+	{"αβδ", "ΑΒΔ", true},
+	{"abc", "xyz", false},
+	{"abc", "XYZ", false},
+	{"abcdefghijk", "abcdefghijX", false},
+	{"abcdefghijk", "abcdefghij\u212A", true},
+	{"abcdefghijK", "abcdefghij\u212A", true},
+	{"abcdefghijkz", "abcdefghij\u212Ay", false},
+	{"abcdefghijKz", "abcdefghij\u212Ay", false},
+}
+
+func TestEqualFold(t *testing.T) {
+	for _, tt := range EqualFoldTests {
+		if out := EqualFold([]byte(tt.s), []byte(tt.t)); out != tt.out {
+			t.Errorf("EqualFold(%#q, %#q) = %v, want %v", tt.s, tt.t, out, tt.out)
+		}
+		if out := EqualFold([]byte(tt.t), []byte(tt.s)); out != tt.out {
+			t.Errorf("EqualFold(%#q, %#q) = %v, want %v", tt.t, tt.s, out, tt.out)
+		}
+	}
+}
+
+func TestBufferGrowNegative(t *testing.T) {
+	defer func() {
+		if err := recover(); err == nil {
+			t.Fatal("Grow(-1) should have panicked")
+		}
+	}()
+	var b Buffer
+	b.Grow(-1)
+}
+
+func TestBufferTruncateNegative(t *testing.T) {
+	defer func() {
+		if err := recover(); err == nil {
+			t.Fatal("Truncate(-1) should have panicked")
+		}
+	}()
+	var b Buffer
+	b.Truncate(-1)
+}
+
+func TestBufferTruncateOutOfRange(t *testing.T) {
+	defer func() {
+		if err := recover(); err == nil {
+			t.Fatal("Truncate(20) should have panicked")
+		}
+	}()
+	var b Buffer
+	b.Write(make([]byte, 10))
+	b.Truncate(20)
+}
+
+var containsTests = []struct {
+	b, subslice []byte
+	want        bool
+}{
+	{[]byte("hello"), []byte("hel"), true},
+	{[]byte("日本語"), []byte("日本"), true},
+	{[]byte("hello"), []byte("Hello, world"), false},
+	{[]byte("東京"), []byte("京東"), false},
+}
+
+func TestContains(t *testing.T) {
+	for _, tt := range containsTests {
+		if got := Contains(tt.b, tt.subslice); got != tt.want {
+			t.Errorf("Contains(%q, %q) = %v, want %v", tt.b, tt.subslice, got, tt.want)
+		}
+	}
+}
+
+var makeFieldsInput = func() []byte {
+	x := make([]byte, 1<<20)
+	// Input is ~10% space, ~10% 2-byte UTF-8, rest ASCII non-space.
+	for i := range x {
+		switch rand.Intn(10) {
+		case 0:
+			x[i] = ' '
+		case 1:
+			if i > 0 && x[i-1] == 'x' {
+				copy(x[i-1:], "χ")
+				break
+			}
+			fallthrough
+		default:
+			x[i] = 'x'
+		}
+	}
+	return x
+}
+
+var fieldsInput = makeFieldsInput()
+
+func BenchmarkFields(b *testing.B) {
+	b.SetBytes(int64(len(fieldsInput)))
+	for i := 0; i < b.N; i++ {
+		Fields(fieldsInput)
+	}
+}
+
+func BenchmarkFieldsFunc(b *testing.B) {
+	b.SetBytes(int64(len(fieldsInput)))
+	for i := 0; i < b.N; i++ {
+		FieldsFunc(fieldsInput, unicode.IsSpace)
+	}
+}
+
+func BenchmarkTrimSpace(b *testing.B) {
+	s := []byte("  Some text.  \n")
+	for i := 0; i < b.N; i++ {
+		TrimSpace(s)
+	}
+}
+
+func BenchmarkRepeat(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		Repeat([]byte("-"), 80)
+	}
+}
diff --git a/src/pkg/bytes/compare_test.go b/src/bytes/compare_test.go
similarity index 100%
rename from src/pkg/bytes/compare_test.go
rename to src/bytes/compare_test.go
diff --git a/src/pkg/bytes/equal_test.go b/src/bytes/equal_test.go
similarity index 100%
rename from src/pkg/bytes/equal_test.go
rename to src/bytes/equal_test.go
diff --git a/src/pkg/bytes/example_test.go b/src/bytes/example_test.go
similarity index 100%
rename from src/pkg/bytes/example_test.go
rename to src/bytes/example_test.go
diff --git a/src/pkg/bytes/export_test.go b/src/bytes/export_test.go
similarity index 100%
rename from src/pkg/bytes/export_test.go
rename to src/bytes/export_test.go
diff --git a/src/pkg/bytes/reader.go b/src/bytes/reader.go
similarity index 100%
rename from src/pkg/bytes/reader.go
rename to src/bytes/reader.go
diff --git a/src/pkg/bytes/reader_test.go b/src/bytes/reader_test.go
similarity index 100%
rename from src/pkg/bytes/reader_test.go
rename to src/bytes/reader_test.go
diff --git a/src/cmd/5a/a.y b/src/cmd/5a/a.y
index 56d0c56..ad64760 100644
--- a/src/cmd/5a/a.y
+++ b/src/cmd/5a/a.y
@@ -33,7 +33,7 @@
 #include <stdio.h>	/* if we don't, bison will, and a.h re-#defines getc */
 #include <libc.h>
 #include "a.h"
-#include "../../pkg/runtime/funcdata.h"
+#include "../../runtime/funcdata.h"
 %}
 %union
 {
diff --git a/src/cmd/5a/lex.c b/src/cmd/5a/lex.c
index 571fdf7..9c69709 100644
--- a/src/cmd/5a/lex.c
+++ b/src/cmd/5a/lex.c
@@ -85,6 +85,7 @@ main(int argc, char *argv[])
 	ctxt = linknew(&linkarm);
 	ctxt->diag = yyerror;
 	ctxt->bso = &bstdout;
+	ctxt->enforce_data_order = 1;
 	Binit(&bstdout, 1, OWRITE);
 	listinit5();
 	fmtinstall('L', Lconv);
@@ -199,8 +200,8 @@ struct
 	"R6",		LREG,	6,
 	"R7",		LREG,	7,
 	"R8",		LREG,	8,
-	"m",		LREG,	9, // avoid unintentionally clobber m/g using R9/R10
-	"g",		LREG,	10,
+	"R9",		LREG,	9,
+	"g",		LREG,	10, // avoid unintentionally clobber g using R10
 	"R11",		LREG,	11,
 	"R12",		LREG,	12,
 	"R13",		LREG,	13,
diff --git a/src/cmd/5a/y.tab.c b/src/cmd/5a/y.tab.c
index 0bc8c34..a6251b8 100644
--- a/src/cmd/5a/y.tab.c
+++ b/src/cmd/5a/y.tab.c
@@ -69,7 +69,7 @@
 #include <stdio.h>	/* if we don't, bison will, and a.h re-#defines getc */
 #include <libc.h>
 #include "a.h"
-#include "../../pkg/runtime/funcdata.h"
+#include "../../runtime/funcdata.h"
 
 /* Line 371 of yacc.c  */
 #line 76 "y.tab.c"
diff --git a/src/cmd/5c/cgen.c b/src/cmd/5c/cgen.c
index 08ed360..5a049ae 100644
--- a/src/cmd/5c/cgen.c
+++ b/src/cmd/5c/cgen.c
@@ -29,7 +29,7 @@
 // THE SOFTWARE.
 
 #include "gc.h"
-#include "../../pkg/runtime/funcdata.h"
+#include "../../runtime/funcdata.h"
 
 void
 _cgen(Node *n, Node *nn, int inrel)
@@ -46,7 +46,7 @@ _cgen(Node *n, Node *nn, int inrel)
 	}
 	if(n == Z || n->type == T)
 		return;
-	if(typesuv[n->type->etype]) {
+	if(typesuv[n->type->etype] && (n->op != OFUNC || nn != Z)) {
 		sugen(n, nn, n->type->width);
 		return;
 	}
@@ -75,7 +75,7 @@ _cgen(Node *n, Node *nn, int inrel)
 	if(r != Z && r->complex >= FNX)
 	switch(o) {
 	default:
-		regret(&nod, r);
+		regret(&nod, r, 0, 0);
 		cgen(r, &nod);
 
 		regsalloc(&nod1, r);
@@ -107,7 +107,7 @@ _cgen(Node *n, Node *nn, int inrel)
 		if(l->addable >= INDEXED && l->complex < FNX) {
 			if(nn != Z || r->addable < INDEXED) {
 				if(r->complex >= FNX && nn == Z)
-					regret(&nod, r);
+					regret(&nod, r, 0, 0);
 				else
 					regalloc(&nod, r, nn);
 				cgen(r, &nod);
@@ -348,7 +348,7 @@ _cgen(Node *n, Node *nn, int inrel)
 			if(l->op != OIND)
 				diag(n, "bad function call");
 
-			regret(&nod, l->left);
+			regret(&nod, l->left, 0, 0);
 			cgen(l->left, &nod);
 			regsalloc(&nod1, l->left);
 			gopcode(OAS, &nod, Z, &nod1);
@@ -366,22 +366,20 @@ _cgen(Node *n, Node *nn, int inrel)
 		if(REGARG >= 0)
 			o = reg[REGARG];
 		gargs(r, &nod, &nod1);
-		gpcdata(PCDATA_ArgSize, curarg);
 		if(l->addable < INDEXED) {
 			reglcgen(&nod, l, Z);
 			gopcode(OFUNC, Z, Z, &nod);
 			regfree(&nod);
 		} else
 			gopcode(OFUNC, Z, Z, l);
-		gpcdata(PCDATA_ArgSize, -1);
 		if(REGARG >= 0)
 			if(o != reg[REGARG])
 				reg[REGARG]--;
-		if(nn != Z) {
-			regret(&nod, n);
-			gopcode(OAS, &nod, Z, nn);
+		regret(&nod, n, l->type, 1);
+		if(nn != Z)
+			gmove(&nod, nn);
+		if(nod.op == OREGISTER)
 			regfree(&nod);
-		}
 		break;
 
 	case OIND:
@@ -823,7 +821,7 @@ boolgen(Node *n, int true, Node *nn)
 		if(true)
 			o = comrel[relindex(o)];
 		if(l->complex >= FNX && r->complex >= FNX) {
-			regret(&nod, r);
+			regret(&nod, r, 0, 0);
 			cgenrel(r, &nod);
 			regsalloc(&nod1, r);
 			gopcode(OAS, &nod, Z, &nod1);
@@ -957,7 +955,7 @@ sugen(Node *n, Node *nn, int32 w)
 		if(nn != Z && side(nn)) {
 			nod1 = *n;
 			nod1.type = typ(TIND, n->type);
-			regret(&nod2, &nod1);
+			regret(&nod2, &nod1, 0, 0);
 			lcgen(nn, &nod2);
 			regsalloc(&nod0, &nod1);
 			gopcode(OAS, &nod2, Z, &nod0);
@@ -1036,6 +1034,20 @@ sugen(Node *n, Node *nn, int32 w)
 		break;
 
 	case OFUNC:
+		if(!hasdotdotdot(n->left->type)) {
+			cgen(n, Z);
+			if(nn != Z) {
+				curarg -= n->type->width;
+				regret(&nod1, n, n->left->type, 1);
+				if(nn->complex >= FNX) {
+					regsalloc(&nod2, n);
+					cgen(&nod1, &nod2);
+					nod1 = nod2;
+				}
+				cgen(&nod1, nn);
+			}
+			break;
+		}
 		if(nn == Z) {
 			sugen(n, nodrat, w);
 			break;
diff --git a/src/cmd/5c/gc.h b/src/cmd/5c/gc.h
index 40d3a2b..7417b7d 100644
--- a/src/cmd/5c/gc.h
+++ b/src/cmd/5c/gc.h
@@ -144,7 +144,6 @@ EXTERN	Prog*	lastp;
 EXTERN	int32	maxargsafe;
 EXTERN	int	mnstring;
 EXTERN	Multab	multab[20];
-EXTERN	int	retok;
 extern	int	hintabsize;
 EXTERN	Node*	nodrat;
 EXTERN	Node*	nodret;
@@ -211,7 +210,7 @@ void	usedset(Node*, int);
 void	xcom(Node*);
 int	bcomplex(Node*, Node*);
 Prog*	gtext(Sym*, int32);
-vlong	argsize(void);
+vlong	argsize(int);
 
 /*
  * cgen.c
@@ -237,7 +236,7 @@ Node*	nodconst(int32);
 Node*	nod32const(vlong);
 Node*	nodfconst(double);
 void	nodreg(Node*, Node*, int);
-void	regret(Node*, Node*);
+void	regret(Node*, Node*, Type*, int);
 int	tmpreg(void);
 void	regalloc(Node*, Node*, Node*);
 void	regfree(Node*);
diff --git a/src/cmd/5c/peep.c b/src/cmd/5c/peep.c
index 143400a..1de56b5 100644
--- a/src/cmd/5c/peep.c
+++ b/src/cmd/5c/peep.c
@@ -853,11 +853,15 @@ xtramodes(Reg *r, Addr *a)
 				switch (p1->from.type) {
 				case D_REG:
 					/* register offset */
+					if(nacl)
+						return 0;
 					a->type = D_SHIFT;
 					a->offset = p1->from.reg;
 					break;
 				case D_SHIFT:
 					/* scaled register offset */
+					if(nacl)
+						return 0;
 					a->type = D_SHIFT;
 				case D_CONST:
 					/* immediate offset */
diff --git a/src/cmd/5c/reg.c b/src/cmd/5c/reg.c
index b9ac21a..9024d5f 100644
--- a/src/cmd/5c/reg.c
+++ b/src/cmd/5c/reg.c
@@ -204,6 +204,16 @@ regopt(Prog *p)
 			break;
 		}
 
+		/* the mod/div runtime routines smash R12 */
+		switch(p->as) {
+		case AMOD:
+		case AMODU:
+		case ADIV:
+		case ADIVU:
+			regbits |= RtoB(12);
+			break;
+		}
+
 		if(p->as == AMOVM) {
 			if(p->from.type == D_CONST)
 				z = p->from.offset;
@@ -396,7 +406,7 @@ loop2:
 			rgp->cost = change;
 			nregion++;
 			if(nregion >= NRGN) {
-				warn(Z, "too many regions");
+				fatal(Z, "too many regions");
 				goto brk;
 			}
 			rgp++;
@@ -632,11 +642,8 @@ mkvar(Addr *a, int docon)
 	if(s)
 		if(s->name[0] == '.')
 			goto none;
-	if(nvar >= NVAR) {
-		if(debug['w'] > 1 && s)
-			warn(Z, "variable not optimized: %s", s->name);
-		goto none;
-	}
+	if(nvar >= NVAR)
+		fatal(Z, "variable not optimized: %s", s->name);
 	i = nvar;
 	nvar++;
 	v = &var[i];
diff --git a/src/cmd/5c/sgen.c b/src/cmd/5c/sgen.c
index efcc043..a36612c 100644
--- a/src/cmd/5c/sgen.c
+++ b/src/cmd/5c/sgen.c
@@ -36,7 +36,7 @@ gtext(Sym *s, int32 stkoff)
 {
 	int32 a;
 
-	a = argsize();
+	a = argsize(1);
 	if((textflag & NOSPLIT) != 0 && stkoff >= 128)
 		yyerror("stack frame too large for NOSPLIT function");
 
diff --git a/src/cmd/5c/swt.c b/src/cmd/5c/swt.c
index fd81a4e..f39963b 100644
--- a/src/cmd/5c/swt.c
+++ b/src/cmd/5c/swt.c
@@ -60,7 +60,7 @@ swit2(C1 *q, int nc, int32 def, Node *n)
 
 	if(nc >= 3) {
 		i = (q+nc-1)->val - (q+0)->val;
-		if(i > 0 && i < nc*2)
+		if(!nacl && i > 0 && i < nc*2)
 			goto direct;
 	}
 	if(nc < 5) {
@@ -374,10 +374,11 @@ align(int32 i, Type *t, int op, int32 *maxalign)
 {
 	int32 o;
 	Type *v;
-	int w;
+	int w, packw;
 
 	o = i;
 	w = 1;
+	packw = 0;
 	switch(op) {
 	default:
 		diag(Z, "unknown align opcode %d", op);
@@ -388,7 +389,7 @@ align(int32 i, Type *t, int op, int32 *maxalign)
 		if(w < 1)
 			w = 1;
 		if(packflg)
-			w = packflg;
+			packw = packflg;
 		break;
 
 	case Ael1:	/* initial align of struct element */
@@ -404,7 +405,7 @@ align(int32 i, Type *t, int op, int32 *maxalign)
 		if(w < 1 || w > SZ_LONG)
 			fatal(Z, "align");
 		if(packflg) 
-			w = packflg;
+			packw = packflg;
 		break;
 
 	case Ael2:	/* width of a struct element */
@@ -440,6 +441,8 @@ align(int32 i, Type *t, int op, int32 *maxalign)
 		w = SZ_LONG;	/* because of a pun in cc/dcl.c:contig() */
 		break;
 	}
+	if(packw != 0 && xround(o, w) != xround(o, packw))
+		diag(Z, "#pragma pack changes offset of %T", t);
 	o = xround(o, w);
 	if(maxalign != nil && *maxalign < w)
 		*maxalign = w;
diff --git a/src/cmd/5c/txt.c b/src/cmd/5c/txt.c
index a753510..af40220 100644
--- a/src/cmd/5c/txt.c
+++ b/src/cmd/5c/txt.c
@@ -274,15 +274,43 @@ nodreg(Node *n, Node *nn, int reg)
 }
 
 void
-regret(Node *n, Node *nn)
+regret(Node *n, Node *nn, Type *t, int mode)
 {
 	int r;
 
-	r = REGRET;
-	if(typefd[nn->type->etype])
-		r = FREGRET+NREG;
-	nodreg(n, nn, r);
-	reg[r]++;
+	if(mode == 0 || hasdotdotdot(t) || nn->type->width == 0) {
+		r = REGRET;
+		if(typefd[nn->type->etype])
+			r = FREGRET+NREG;
+		nodreg(n, nn, r);
+		reg[r]++;
+		return;
+	}
+	
+	if(mode == 1) {
+		// fetch returned value after call.
+		// already called gargs, so curarg is set.
+		curarg = (curarg+3) & ~3;
+		regaalloc(n, nn);
+		return;
+	}
+	
+	if(mode == 2) {
+		// store value to be returned.
+		// must compute arg offset.
+		if(t->etype != TFUNC)
+			fatal(Z, "bad regret func %T", t);
+		*n = *nn;
+		n->op = ONAME;
+		n->class = CPARAM;
+		n->sym = slookup(".ret");
+		n->complex = nodret->complex;
+		n->xoffset = argsize(0);
+		n->addable = 20;
+		return;
+	}
+	
+	fatal(Z, "bad regret");
 }
 
 int
diff --git a/src/cmd/5g/cgen.c b/src/cmd/5g/cgen.c
index 9011b20..c535cfb 100644
--- a/src/cmd/5g/cgen.c
+++ b/src/cmd/5g/cgen.c
@@ -254,7 +254,6 @@ cgen(Node *n, Node *res)
 	case OOR:
 	case OXOR:
 	case OADD:
-	case OADDPTR:
 	case OMUL:
 		a = optoas(n->op, nl->type);
 		goto sbop;
@@ -1107,11 +1106,10 @@ bgen(Node *n, int true, int likely, Prog *to)
 {
 	int et, a;
 	Node *nl, *nr, *r;
-	Node n1, n2, n3, n4, tmp;
+	Node n1, n2, n3, tmp;
 	NodeList *ll;
 	Prog *p1, *p2;
 
-	USED(n4);			// in unreachable code below
 	if(debug['g']) {
 		dump("\nbgen", n);
 	}
@@ -1497,7 +1495,7 @@ sgen(Node *n, Node *res, int64 w)
 	if(osrc < odst && odst < osrc+w)
 		dir = -dir;
 
-	if(op == AMOVW && dir > 0 && c >= 4 && c <= 128) {
+	if(op == AMOVW && !nacl && dir > 0 && c >= 4 && c <= 128) {
 		r0.op = OREGISTER;
 		r0.val.u.reg = REGALLOC_R0;
 		r1.op = OREGISTER;
@@ -1524,7 +1522,7 @@ sgen(Node *n, Node *res, int64 w)
 		f = sysfunc("duffcopy");
 		p = gins(ADUFFCOPY, N, f);
 		afunclit(&p->to, f);
-		// 8 and 128 = magic constants: see ../../pkg/runtime/asm_arm.s
+		// 8 and 128 = magic constants: see ../../runtime/asm_arm.s
 		p->to.offset = 8*(128-c);
 
 		regfree(&tmp);
@@ -1636,7 +1634,10 @@ int
 componentgen(Node *nr, Node *nl)
 {
 	Node nodl, nodr, tmp;
+	Type *t;
 	int freel, freer;
+	vlong fldcount;
+	vlong loffset, roffset;
 
 	freel = 0;
 	freer = 0;
@@ -1646,8 +1647,33 @@ componentgen(Node *nr, Node *nl)
 		goto no;
 
 	case TARRAY:
-		if(!isslice(nl->type))
+		t = nl->type;
+
+		// Slices are ok.
+		if(isslice(t))
+			break;
+		// Small arrays are ok.
+		if(t->bound > 0 && t->bound <= 3 && !isfat(t->type))
+			break;
+
+		goto no;
+
+	case TSTRUCT:
+		// Small structs with non-fat types are ok.
+		// Zero-sized structs are treated separately elsewhere.
+		fldcount = 0;
+		for(t=nl->type->type; t; t=t->down) {
+			if(isfat(t->type))
+				goto no;
+			if(t->etype != TFIELD)
+				fatal("componentgen: not a TFIELD: %lT", t);
+			fldcount++;
+		}
+		if(fldcount == 0 || fldcount > 4)
 			goto no;
+
+		break;
+
 	case TSTRING:
 	case TINTER:
 		break;
@@ -1675,6 +1701,7 @@ componentgen(Node *nr, Node *nl)
 		freer = 1;
 	}
 
+	
 	// nl and nr are 'cadable' which basically means they are names (variables) now.
 	// If they are the same variable, don't generate any code, because the
 	// VARDEF we generate will mark the old value as dead incorrectly.
@@ -1684,8 +1711,25 @@ componentgen(Node *nr, Node *nl)
 
 	switch(nl->type->etype) {
 	case TARRAY:
+		// componentgen for arrays.
 		if(nl->op == ONAME)
 			gvardef(nl);
+		t = nl->type;
+		if(!isslice(t)) {
+			nodl.type = t->type;
+			nodr.type = nodl.type;
+			for(fldcount=0; fldcount < t->bound; fldcount++) {
+				if(nr == N)
+					clearslim(&nodl);
+				else
+					gmove(&nodr, &nodl);
+				nodl.xoffset += t->type->width;
+				nodr.xoffset += t->type->width;
+			}
+			goto yes;
+		}
+
+		// componentgen for slices.
 		nodl.xoffset += Array_array;
 		nodl.type = ptrto(nl->type->type);
 
@@ -1760,6 +1804,31 @@ componentgen(Node *nr, Node *nl)
 		gmove(&nodr, &nodl);
 
 		goto yes;
+
+	case TSTRUCT:
+		if(nl->op == ONAME)
+			gvardef(nl);
+		loffset = nodl.xoffset;
+		roffset = nodr.xoffset;
+		// funarg structs may not begin at offset zero.
+		if(nl->type->etype == TSTRUCT && nl->type->funarg && nl->type->type)
+			loffset -= nl->type->type->width;
+		if(nr != N && nr->type->etype == TSTRUCT && nr->type->funarg && nr->type->type)
+			roffset -= nr->type->type->width;
+
+		for(t=nl->type->type; t; t=t->down) {
+			nodl.xoffset = loffset + t->width;
+			nodl.type = t->type;
+
+			if(nr == N)
+				clearslim(&nodl);
+			else {
+				nodr.xoffset = roffset + t->width;
+				nodr.type = nodl.type;
+				gmove(&nodr, &nodl);
+			}
+		}
+		goto yes;
 	}
 
 no:
diff --git a/src/cmd/5g/galign.c b/src/cmd/5g/galign.c
index a62102e..b4c45da 100644
--- a/src/cmd/5g/galign.c
+++ b/src/cmd/5g/galign.c
@@ -23,10 +23,10 @@ vlong MAXWIDTH = (1LL<<32) - 1;
  */
 Typedef	typedefs[] =
 {
-	"int",		TINT,		TINT32,
-	"uint",		TUINT,		TUINT32,
-	"uintptr",	TUINTPTR,	TUINT32,
-	0
+	{"int",		TINT,		TINT32},
+	{"uint",		TUINT,		TUINT32},
+	{"uintptr",	TUINTPTR,	TUINT32},
+	{0}
 };
 
 void
diff --git a/src/cmd/5g/gg.h b/src/cmd/5g/gg.h
index 413e93c..00914bf 100644
--- a/src/cmd/5g/gg.h
+++ b/src/cmd/5g/gg.h
@@ -11,10 +11,13 @@
 
 #define TEXTFLAG reg
 
-#define REGALLOC_R0 0
-#define REGALLOC_RMAX REGEXT
-#define REGALLOC_F0 NREG
-#define REGALLOC_FMAX (REGALLOC_F0 + FREGEXT)
+enum
+{
+	REGALLOC_R0 = 0,
+	REGALLOC_RMAX = REGEXT,
+	REGALLOC_F0 = NREG,
+	REGALLOC_FMAX = REGALLOC_F0 + FREGEXT,
+};
 
 EXTERN	int32	dynloc;
 EXTERN	uchar	reg[REGALLOC_FMAX+1];
@@ -106,7 +109,6 @@ void	split64(Node*, Node*, Node*);
 void	splitclean(void);
 Node*	ncon(uint32 i);
 void	gtrack(Sym*);
-void	gargsize(int32);
 
 /*
  * obj.c
diff --git a/src/cmd/5g/ggen.c b/src/cmd/5g/ggen.c
index fb32c2f..53cddb7 100644
--- a/src/cmd/5g/ggen.c
+++ b/src/cmd/5g/ggen.c
@@ -76,7 +76,7 @@ zerorange(Prog *p, vlong frame, vlong lo, vlong hi, uint32 *r0)
 	if(cnt < 4*widthptr) {
 		for(i = 0; i < cnt; i += widthptr) 
 			p = appendpp(p, AMOVW, D_REG, 0, 0, D_OREG, REGSP, 4+frame+lo+i);
-	} else if(cnt <= 128*widthptr) {
+	} else if(!nacl && (cnt <= 128*widthptr)) {
 		p = appendpp(p, AADD, D_CONST, NREG, 4+frame+lo, D_REG, 1, 0);
 		p->reg = REGSP;
 		p = appendpp(p, ADUFFZERO, D_NONE, NREG, 0, D_OREG, NREG, 0);
@@ -179,28 +179,12 @@ fixautoused(Prog* p)
 void
 ginscall(Node *f, int proc)
 {
-	int32 arg;
 	Prog *p;
 	Node n1, r, r1, con;
 
 	if(f->type != T)
 		setmaxarg(f->type);
 
-	arg = -1;
-	// Most functions have a fixed-size argument block, so traceback uses that during unwind.
-	// Not all, though: there are some variadic functions in package runtime,
-	// and for those we emit call-specific metadata recorded by caller.
-	// Reflect generates functions with variable argsize (see reflect.methodValueCall/makeFuncStub),
-	// so we do this for all indirect calls as well.
-	if(f->type != T && (f->sym == S || (f->sym != S && f->sym->pkg == runtimepkg) || proc == 1 || proc == 2)) {
-		arg = f->type->argwid;
-		if(proc == 1 || proc == 2)
-			arg += 3*widthptr;
-	}
-
-	if(arg != -1)
-		gargsize(arg);
-
 	switch(proc) {
 	default:
 		fatal("ginscall: bad proc %d", proc);
@@ -297,9 +281,6 @@ ginscall(Node *f, int proc)
 		}
 		break;
 	}
-	
-	if(arg != -1)
-		gargsize(-1);
 }
 
 /*
@@ -906,11 +887,11 @@ clearfat(Node *nl)
 		patch(gbranch(ABNE, T, 0), pl);
 
 		regfree(&end);
-	} else if(q >= 4) {
+	} else if(q >= 4 && !nacl) {
 		f = sysfunc("duffzero");
 		p = gins(ADUFFZERO, N, f);
 		afunclit(&p->to, f);
-		// 4 and 128 = magic constants: see ../../pkg/runtime/asm_arm.s
+		// 4 and 128 = magic constants: see ../../runtime/asm_arm.s
 		p->to.offset = 4*(128-q);
 	} else
 	while(q > 0) {
diff --git a/src/cmd/5g/gsubr.c b/src/cmd/5g/gsubr.c
index f66c87b..06e274e 100644
--- a/src/cmd/5g/gsubr.c
+++ b/src/cmd/5g/gsubr.c
@@ -31,11 +31,11 @@
 #include <u.h>
 #include <libc.h>
 #include "gg.h"
-#include "../../pkg/runtime/funcdata.h"
+#include "../../runtime/funcdata.h"
 
 // TODO(rsc): Can make this bigger if we move
 // the text segment up higher in 5l for all GOOS.
-// At the same time, can raise StackBig in ../../pkg/runtime/stack.h.
+// At the same time, can raise StackBig in ../../runtime/stack.h.
 long unmappedzero = 4096;
 
 void
@@ -206,17 +206,7 @@ ggloblnod(Node *nam)
 }
 
 void
-gargsize(int32 size)
-{
-	Node n1, n2;
-	
-	nodconst(&n1, types[TINT32], PCDATA_ArgSize);
-	nodconst(&n2, types[TINT32], size);
-	gins(APCDATA, &n1, &n2);
-}
-
-void
-ggloblsym(Sym *s, int32 width, int dupok, int rodata)
+ggloblsym(Sym *s, int32 width, int8 flags)
 {
 	Prog *p;
 
@@ -227,10 +217,7 @@ ggloblsym(Sym *s, int32 width, int dupok, int rodata)
 	p->to.type = D_CONST;
 	p->to.name = D_NONE;
 	p->to.offset = width;
-	if(dupok)
-		p->reg |= DUPOK;
-	if(rodata)
-		p->reg |= RODATA;
+	p->reg = flags;
 }
 
 void
@@ -374,7 +361,7 @@ regalloc(Node *n, Type *t, Node *o)
 		print("registers allocated at\n");
 		for(i=REGALLOC_R0; i<=REGALLOC_RMAX; i++)
 			print("%d %p\n", i, regpc[i]);
-		yyerror("out of fixed registers");
+		fatal("out of fixed registers");
 		goto err;
 
 	case TFLOAT32:
@@ -387,7 +374,7 @@ regalloc(Node *n, Type *t, Node *o)
 		for(i=REGALLOC_F0; i<=REGALLOC_FMAX; i++)
 			if(reg[i] == 0)
 				goto out;
-		yyerror("out of floating point registers");
+		fatal("out of floating point registers");
 		goto err;
 
 	case TCOMPLEX64:
@@ -636,6 +623,7 @@ splitclean(void)
 }
 
 #define	CASE(a,b)	(((a)<<16)|((b)<<0))
+/*c2go int CASE(int, int); */
 
 void
 gmove(Node *f, Node *t)
@@ -1601,7 +1589,6 @@ optoas(int op, Type *t)
 	case CASE(OADD, TINT32):
 	case CASE(OADD, TUINT32):
 	case CASE(OADD, TPTR32):
-	case CASE(OADDPTR, TPTR32):
 		a = AADD;
 		break;
 
diff --git a/src/cmd/5g/opt.h b/src/cmd/5g/opt.h
index e3e3f78..1946c1d 100644
--- a/src/cmd/5g/opt.h
+++ b/src/cmd/5g/opt.h
@@ -49,6 +49,24 @@
 typedef	struct	Reg	Reg;
 typedef	struct	Rgn	Rgn;
 
+/*c2go
+extern Node *Z;
+enum
+{
+	D_HI = D_NONE,
+	D_LO = D_NONE,
+	CLOAD = 5,
+	CREF = 5,
+	CINF = 1000,
+	LOOP = 3,
+};
+
+uint32 BLOAD(Reg*);
+uint32 BSTORE(Reg*);
+uint32 LOAD(Reg*);
+uint32 STORE(Reg*);
+*/
+
 // A Reg is a wrapper around a single Prog (one instruction) that holds
 // register optimization information while the optimizer runs.
 // r->prog is the instruction.
@@ -71,8 +89,10 @@ struct	Reg
 	int32	regu;		// register used bitmap
 };
 #define	R	((Reg*)0)
+/*c2go extern Reg *R; */
 
 #define	NRGN	600
+/*c2go enum { NRGN = 600 }; */
 struct	Rgn
 {
 	Reg*	enter;
diff --git a/src/cmd/5g/peep.c b/src/cmd/5g/peep.c
index 4aa6452..639f4c5 100644
--- a/src/cmd/5g/peep.c
+++ b/src/cmd/5g/peep.c
@@ -564,6 +564,8 @@ gotit:
  * ..
  */
 #define FAIL(msg) { if(debug['P']) print("\t%s; FAILURE\n", msg); return 0; }
+/*c2go void FAIL(char*); */
+
 int
 shiftprop(Flow *r)
 {
@@ -875,11 +877,15 @@ xtramodes(Graph *g, Flow *r, Adr *a)
 				switch (p1->from.type) {
 				case D_REG:
 					/* register offset */
+					if(nacl)
+						return 0;
 					a->type = D_SHIFT;
 					a->offset = p1->from.reg;
 					break;
 				case D_SHIFT:
 					/* scaled register offset */
+					if(nacl)
+						return 0;
 					a->type = D_SHIFT;
 				case D_CONST:
 					/* immediate offset */
diff --git a/src/cmd/5g/reg.c b/src/cmd/5g/reg.c
index 4762df5..b78c268 100644
--- a/src/cmd/5g/reg.c
+++ b/src/cmd/5g/reg.c
@@ -36,6 +36,11 @@
 
 #define	NREGVAR	32
 #define	REGBITS	((uint32)0xffffffff)
+/*c2go enum {
+	NREGVAR = 32,
+	REGBITS = 0xffffffff,
+};
+*/
 
 	void	addsplits(void);
 static	Reg*	firstr;
@@ -194,7 +199,7 @@ regopt(Prog *firstp)
 		proginfo(&info, p);
 
 		// Avoid making variables for direct-called functions.
-		if(p->as == ABL && p->to.type == D_EXTERN)
+		if(p->as == ABL && p->to.name == D_EXTERN)
 			continue;
 
 		bit = mkvar(r, &p->from);
@@ -222,6 +227,10 @@ regopt(Prog *firstp)
 				for(z=0; z<BITS; z++)
 					r->set.b[z] |= bit.b[z];
 		}
+
+		/* the mod/div runtime routines smash R12 */
+		if(p->as == ADIV || p->as == ADIVU || p->as == AMOD || p->as == AMODU)
+			r->set.b[0] |= RtoB(12);
 	}
 	if(firstr == R)
 		return;
@@ -1306,6 +1315,7 @@ void
 addreg(Adr *a, int rn)
 {
 	a->sym = nil;
+	a->node = nil;
 	a->name = D_NONE;
 	a->type = D_REG;
 	a->reg = rn;
diff --git a/src/cmd/5l/5.out.h b/src/cmd/5l/5.out.h
index 9e8acee..7b16ac4 100644
--- a/src/cmd/5l/5.out.h
+++ b/src/cmd/5l/5.out.h
@@ -28,34 +28,94 @@
 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 // THE SOFTWARE.
 
-#define	NSNAME		8
-#define	NSYM		50
-#define	NREG		16
+enum
+{
+	NSNAME = 8,
+	NSYM = 50,
+	NREG = 16,
+};
 #include "../ld/textflag.h"
 
-#define	REGRET		0
 /* -1 disables use of REGARG */
 #define	REGARG		-1
-/* compiler allocates R1 up as temps */
-/* compiler allocates register variables R3 up */
-#define	REGEXT		10
-/* these two registers are declared in runtime.h */
-#define REGG        (REGEXT-0)
-#define REGM        (REGEXT-1)
-/* compiler allocates external registers R10 down */
-#define	REGTMP		11
-#define	REGSP		13
-#define	REGLINK		14
-#define	REGPC		15
-
-#define	NFREG		16
-#define	FREGRET		0
-#define	FREGEXT		7
-#define	FREGTMP		15
+/*c2go enum { REGARG = -1 }; */
+
+enum
+{
+	REGRET = 0,
+	/* compiler allocates R1 up as temps */
+	/* compiler allocates register variables R3 up */
+	/* compiler allocates external registers R10 down */
+	REGEXT = 10,
+	/* these two registers are declared in runtime.h */
+	REGG = REGEXT-0,
+	REGM = REGEXT-1,
+
+	REGTMP = 11,
+	REGSP = 13,
+	REGLINK = 14,
+	REGPC = 15,
+	
+	NFREG = 16,
+	FREGRET = 0,
+	FREGEXT = 7,
+	FREGTMP = 15,
+};
 /* compiler allocates register variables F0 up */
 /* compiler allocates external registers F7 down */
 
-enum	as
+enum
+{
+	C_NONE,
+	C_REG,
+	C_REGREG,
+	C_REGREG2,
+	C_SHIFT,
+	C_FREG,
+	C_PSR,
+	C_FCR,
+
+	C_RCON,		/* 0xff rotated */
+	C_NCON,		/* ~RCON */
+	C_SCON,		/* 0xffff */
+	C_LCON,
+	C_LCONADDR,
+	C_ZFCON,
+	C_SFCON,
+	C_LFCON,
+
+	C_RACON,
+	C_LACON,
+
+	C_SBRA,
+	C_LBRA,
+
+	C_HAUTO,	/* halfword insn offset (-0xff to 0xff) */
+	C_FAUTO,	/* float insn offset (0 to 0x3fc, word aligned) */
+	C_HFAUTO,	/* both H and F */
+	C_SAUTO,	/* -0xfff to 0xfff */
+	C_LAUTO,
+
+	C_HOREG,
+	C_FOREG,
+	C_HFOREG,
+	C_SOREG,
+	C_ROREG,
+	C_SROREG,	/* both nil and R */
+	C_LOREG,
+
+	C_PC,
+	C_SP,
+	C_HREG,
+
+	C_ADDR,		/* reference to relocatable address */
+
+	C_GOK,
+
+	C_NCLASS,	/* must be the last */
+};
+
+enum
 {
 	AXXX,
 
@@ -202,6 +262,8 @@ enum	as
 	AVARKILL,
 	ADUFFCOPY,
 	ADUFFZERO,
+	ADATABUNDLE,
+	ADATABUNDLEEND,
 
 	AMRC, // MRC/MCR
 
@@ -209,35 +271,38 @@ enum	as
 };
 
 /* scond byte */
-#define	C_SCOND	((1<<4)-1)
-#define	C_SBIT	(1<<4)
-#define	C_PBIT	(1<<5)
-#define	C_WBIT	(1<<6)
-#define	C_FBIT	(1<<7)	/* psr flags-only */
-#define	C_UBIT	(1<<7)	/* up bit, unsigned bit */
-
-#define C_SCOND_EQ	0
-#define C_SCOND_NE	1
-#define C_SCOND_HS	2
-#define C_SCOND_LO	3
-#define C_SCOND_MI	4
-#define C_SCOND_PL	5
-#define C_SCOND_VS	6
-#define C_SCOND_VC	7
-#define C_SCOND_HI	8
-#define C_SCOND_LS	9
-#define C_SCOND_GE	10
-#define C_SCOND_LT	11
-#define C_SCOND_GT	12
-#define C_SCOND_LE	13
-#define C_SCOND_NONE	14
-#define C_SCOND_NV	15
-
-/* D_SHIFT type */
-#define SHIFT_LL		0<<5
-#define SHIFT_LR		1<<5
-#define SHIFT_AR		2<<5
-#define SHIFT_RR		3<<5
+enum
+{
+	C_SCOND = (1<<4)-1,
+	C_SBIT = 1<<4,
+	C_PBIT = 1<<5,
+	C_WBIT = 1<<6,
+	C_FBIT = 1<<7,	/* psr flags-only */
+	C_UBIT = 1<<7,	/* up bit, unsigned bit */
+
+	C_SCOND_EQ = 0,
+	C_SCOND_NE = 1,
+	C_SCOND_HS = 2,
+	C_SCOND_LO = 3,
+	C_SCOND_MI = 4,
+	C_SCOND_PL = 5,
+	C_SCOND_VS = 6,
+	C_SCOND_VC = 7,
+	C_SCOND_HI = 8,
+	C_SCOND_LS = 9,
+	C_SCOND_GE = 10,
+	C_SCOND_LT = 11,
+	C_SCOND_GT = 12,
+	C_SCOND_LE = 13,
+	C_SCOND_NONE = 14,
+	C_SCOND_NV = 15,
+
+	/* D_SHIFT type */
+	SHIFT_LL = 0<<5,
+	SHIFT_LR = 1<<5,
+	SHIFT_AR = 2<<5,
+	SHIFT_RR = 3<<5,
+};
 
 enum
 {
@@ -279,3 +344,4 @@ enum
  * this is the ranlib header
  */
 #define	SYMDEF	"__.GOSYMDEF"
+/*c2go extern char SYMDEF[]; */
diff --git a/src/cmd/5l/asm.c b/src/cmd/5l/asm.c
index e879212..9c1c04e 100644
--- a/src/cmd/5l/asm.c
+++ b/src/cmd/5l/asm.c
@@ -648,19 +648,20 @@ asmb(void)
 	switch(HEADTYPE) {
 	default:
 	case Hplan9:	/* plan 9 */
-		lput(0x647);			/* magic */
-		lput(segtext.filelen);			/* sizes */
-		lput(segdata.filelen);
-		lput(segdata.len - segdata.filelen);
-		lput(symsize);			/* nsyms */
-		lput(entryvalue());		/* va of entry */
-		lput(0L);
-		lput(lcsize);
+		LPUT(0x647);			/* magic */
+		LPUT(segtext.filelen);			/* sizes */
+		LPUT(segdata.filelen);
+		LPUT(segdata.len - segdata.filelen);
+		LPUT(symsize);			/* nsyms */
+		LPUT(entryvalue());		/* va of entry */
+		LPUT(0L);
+		LPUT(lcsize);
 		break;
 	case Hlinux:
 	case Hfreebsd:
 	case Hnetbsd:
 	case Hopenbsd:
+	case Hnacl:
 		asmbelf(symo);
 		break;
 	}
@@ -675,64 +676,6 @@ asmb(void)
 	}
 }
 
-/*
-void
-cput(int32 c)
-{
-	*cbp++ = c;
-	if(--cbc <= 0)
-		cflush();
-}
-*/
-
-void
-wput(int32 l)
-{
-
-	cbp[0] = l>>8;
-	cbp[1] = l;
-	cbp += 2;
-	cbc -= 2;
-	if(cbc <= 0)
-		cflush();
-}
-
-
-void
-hput(int32 l)
-{
-
-	cbp[0] = l>>8;
-	cbp[1] = l;
-	cbp += 2;
-	cbc -= 2;
-	if(cbc <= 0)
-		cflush();
-}
-
-void
-lput(int32 l)
-{
-
-	cbp[0] = l>>24;
-	cbp[1] = l>>16;
-	cbp[2] = l>>8;
-	cbp[3] = l;
-	cbp += 4;
-	cbc -= 4;
-	if(cbc <= 0)
-		cflush();
-}
-
-void
-nopstat(char *f, Count *c)
-{
-	if(c->outof)
-	Bprint(&bso, "%s delay %d/%d (%.2f)\n", f,
-		c->outof - c->count, c->outof,
-		(double)(c->outof - c->count)/c->outof);
-}
-
 int32
 rnd(int32 v, int32 r)
 {
diff --git a/src/cmd/5l/l.h b/src/cmd/5l/l.h
index 761bc86..c881a54 100644
--- a/src/cmd/5l/l.h
+++ b/src/cmd/5l/l.h
@@ -48,23 +48,8 @@ enum
 #define	EXTERN	extern
 #endif
 
-/* do not undefine this - code will be removed eventually */
-#define	CALLEEBX
-
-#define	dynptrsize	0
-
 #define	P		((Prog*)0)
 #define	S		((LSym*)0)
-#define	TNAME		(ctxt->cursym?ctxt->cursym->name:noname)
-
-#define SIGNINTERN	(1729*325*1729)
-
-typedef	struct	Count	Count;
-struct	Count
-{
-	int32	count;
-	int32	outof;
-};
 
 enum
 {
@@ -73,62 +58,9 @@ enum
 	LABEL		= 1<<1,
 	LEAF		= 1<<2,
 
-	STRINGSZ	= 200,
-	MINSIZ		= 64,
-	NENT		= 100,
-	MAXIO		= 8192,
-	MAXHIST		= 40,	/* limit of path elements for history symbols */
 	MINLC	= 4,
-
-	C_NONE		= 0,
-	C_REG,
-	C_REGREG,
-	C_REGREG2,
-	C_SHIFT,
-	C_FREG,
-	C_PSR,
-	C_FCR,
-
-	C_RCON,		/* 0xff rotated */
-	C_NCON,		/* ~RCON */
-	C_SCON,		/* 0xffff */
-	C_LCON,
-	C_LCONADDR,
-	C_ZFCON,
-	C_SFCON,
-	C_LFCON,
-
-	C_RACON,
-	C_LACON,
-
-	C_SBRA,
-	C_LBRA,
-
-	C_HAUTO,	/* halfword insn offset (-0xff to 0xff) */
-	C_FAUTO,	/* float insn offset (0 to 0x3fc, word aligned) */
-	C_HFAUTO,	/* both H and F */
-	C_SAUTO,	/* -0xfff to 0xfff */
-	C_LAUTO,
-
-	C_HOREG,
-	C_FOREG,
-	C_HFOREG,
-	C_SOREG,
-	C_ROREG,
-	C_SROREG,	/* both nil and R */
-	C_LOREG,
-
-	C_PC,
-	C_SP,
-	C_HREG,
-
-	C_ADDR,		/* reference to relocatable address */
-
-	C_GOK,
 };
 
-#ifndef COFFCVT
-
 EXTERN	int32	autosize;
 EXTERN	LSym*	datap;
 EXTERN	int	debug[128];
@@ -152,26 +84,18 @@ void	adddynrela(LSym *rel, LSym *s, Reloc *r);
 void	adddynsym(Link *ctxt, LSym *s);
 int	archreloc(Reloc *r, LSym *s, vlong *val);
 void	asmb(void);
-void	cput(int32 c);
 int	elfreloc1(Reloc *r, vlong sectoff);
 void	elfsetupplt(void);
-void	hput(int32 l);
 void	listinit(void);
-void	lput(int32 l);
 int	machoreloc1(Reloc *r, vlong sectoff);
 void	main(int argc, char *argv[]);
-void	noops(void);
-void	nopstat(char *f, Count *c);
 int32	rnd(int32 v, int32 r);
-void	wput(int32 l);
 
 /* Native is little-endian */
 #define	LPUT(a)	lputl(a)
 #define	WPUT(a)	wputl(a)
 #define	VPUT(a)	abort()
 
-#endif
-
 /* Used by ../ld/dwarf.c */
 enum
 {
diff --git a/src/cmd/5l/mkenam b/src/cmd/5l/mkenam
deleted file mode 100644
index 6cccb02..0000000
--- a/src/cmd/5l/mkenam
+++ /dev/null
@@ -1,45 +0,0 @@
-# Inferno utils/5c/mkenam
-# http://code.google.com/p/inferno-os/source/browse/utils/5c/mkenam
-#
-#	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-#	Portions Copyright © 1995-1997 C H Forsyth (forsyth at terzarima.net)
-#	Portions Copyright © 1997-1999 Vita Nuova Limited
-#	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-#	Portions Copyright © 2004,2006 Bruce Ellis
-#	Portions Copyright © 2005-2007 C H Forsyth (forsyth at terzarima.net)
-#	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-#	Portions Copyright © 2009 The Go Authors.  All rights reserved.
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-# THE SOFTWARE.
-
-awk '
-BEGIN {
-	print "char*	anames[] ="
-	print "{"
-}
-
-/^	A/ {
-	name=$1
-	sub(/,/, "", name)
-	sub(/^A/, "", name)
-	print "\t\"" name "\","
-}
-
-END { print "};" }
-' ../5l/5.out.h >enam.c
diff --git a/src/cmd/5l/noop.c b/src/cmd/5l/noop.c
deleted file mode 100644
index d42c862..0000000
--- a/src/cmd/5l/noop.c
+++ /dev/null
@@ -1,43 +0,0 @@
-// Inferno utils/5l/noop.c
-// http://code.google.com/p/inferno-os/source/browse/utils/5l/noop.c
-//
-//	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//	Portions Copyright © 1995-1997 C H Forsyth (forsyth at terzarima.net)
-//	Portions Copyright © 1997-1999 Vita Nuova Limited
-//	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//	Portions Copyright © 2004,2006 Bruce Ellis
-//	Portions Copyright © 2005-2007 C H Forsyth (forsyth at terzarima.net)
-//	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//	Portions Copyright © 2009 The Go Authors.  All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-// Code transformations.
-
-#include	"l.h"
-#include	"../ld/lib.h"
-
-void
-noops(void)
-{
-	LSym *s;
-	
-	for(s = ctxt->textp; s != nil; s = s->next)
-		ctxt->arch->addstacksplit(ctxt, s);
-}
diff --git a/src/cmd/5l/obj.c b/src/cmd/5l/obj.c
index 86a0ece..c6f60ee 100644
--- a/src/cmd/5l/obj.c
+++ b/src/cmd/5l/obj.c
@@ -63,6 +63,7 @@ archinit(void)
 		break;
 	case Hlinux:
 	case Hfreebsd:
+	case Hnacl:
 		break;
 	}
 
@@ -82,7 +83,6 @@ archinit(void)
 	case Hlinux:	/* arm elf */
 	case Hfreebsd:
 	case Hnetbsd:
-	case Hnacl:
 		debug['d'] = 0;	// with dynamic linking
 		elfinit();
 		HEADR = ELFRESERVE;
@@ -93,6 +93,17 @@ archinit(void)
 		if(INITRND == -1)
 			INITRND = 4096;
 		break;
+	case Hnacl:
+		elfinit();
+		HEADR = 0x10000;
+		funcalign = 16;
+		if(INITTEXT == -1)
+			INITTEXT = 0x20000;
+		if(INITDAT == -1)
+			INITDAT = 0;
+		if(INITRND == -1)
+			INITRND = 0x10000;
+		break;
 	}
 	if(INITDAT != 0 && INITRND != 0)
 		print("warning: -D0x%ux is ignored because of -R0x%ux\n",
diff --git a/src/cmd/6a/a.y b/src/cmd/6a/a.y
index 6fd4910..1089d40 100644
--- a/src/cmd/6a/a.y
+++ b/src/cmd/6a/a.y
@@ -33,7 +33,7 @@
 #include <stdio.h>	/* if we don't, bison will, and a.h re-#defines getc */
 #include <libc.h>
 #include "a.h"
-#include "../../pkg/runtime/funcdata.h"
+#include "../../runtime/funcdata.h"
 %}
 %union	{
 	Sym	*sym;
diff --git a/src/cmd/6a/lex.c b/src/cmd/6a/lex.c
index 167e6b6..8973d69 100644
--- a/src/cmd/6a/lex.c
+++ b/src/cmd/6a/lex.c
@@ -101,6 +101,7 @@ main(int argc, char *argv[])
 	ctxt = linknew(thelinkarch);
 	ctxt->diag = yyerror;
 	ctxt->bso = &bstdout;
+	ctxt->enforce_data_order = 1;
 	Binit(&bstdout, 1, OWRITE);
 	listinit6();
 	fmtinstall('L', Lconv);
@@ -435,49 +436,49 @@ struct
 	"IRETQ",	LTYPE0,	AIRETQ,
 	"IRETW",	LTYPE0,	AIRETW,
 
-	"JOS",		LTYPER,	AJOS,
+	"JOS",		LTYPER,	AJOS,	/* overflow set (OF = 1) */
 	"JO",		LTYPER,	AJOS,	/* alternate */
-	"JOC",		LTYPER,	AJOC,
+	"JOC",		LTYPER,	AJOC,	/* overflow clear (OF = 0) */
 	"JNO",		LTYPER,	AJOC,	/* alternate */
-	"JCS",		LTYPER,	AJCS,
+	"JCS",		LTYPER,	AJCS,	/* carry set (CF = 1) */
 	"JB",		LTYPER,	AJCS,	/* alternate */
 	"JC",		LTYPER,	AJCS,	/* alternate */
 	"JNAE",		LTYPER,	AJCS,	/* alternate */
 	"JLO",		LTYPER,	AJCS,	/* alternate */
-	"JCC",		LTYPER,	AJCC,
+	"JCC",		LTYPER,	AJCC,	/* carry clear (CF = 0) */
 	"JAE",		LTYPER,	AJCC,	/* alternate */
 	"JNB",		LTYPER,	AJCC,	/* alternate */
 	"JNC",		LTYPER,	AJCC,	/* alternate */
 	"JHS",		LTYPER,	AJCC,	/* alternate */
-	"JEQ",		LTYPER,	AJEQ,
+	"JEQ",		LTYPER,	AJEQ,	/* equal (ZF = 1) */
 	"JE",		LTYPER,	AJEQ,	/* alternate */
 	"JZ",		LTYPER,	AJEQ,	/* alternate */
-	"JNE",		LTYPER,	AJNE,
+	"JNE",		LTYPER,	AJNE,	/* not equal (ZF = 0) */
 	"JNZ",		LTYPER,	AJNE,	/* alternate */
-	"JLS",		LTYPER,	AJLS,
+	"JLS",		LTYPER,	AJLS,	/* lower or same (unsigned) (CF = 1 || ZF = 1) */
 	"JBE",		LTYPER,	AJLS,	/* alternate */
 	"JNA",		LTYPER,	AJLS,	/* alternate */
-	"JHI",		LTYPER,	AJHI,
+	"JHI",		LTYPER,	AJHI,	/* higher (unsigned) (CF = 0 && ZF = 0) */
 	"JA",		LTYPER,	AJHI,	/* alternate */
 	"JNBE",		LTYPER,	AJHI,	/* alternate */
-	"JMI",		LTYPER,	AJMI,
+	"JMI",		LTYPER,	AJMI,	/* negative (minus) (SF = 1) */
 	"JS",		LTYPER,	AJMI,	/* alternate */
-	"JPL",		LTYPER,	AJPL,
+	"JPL",		LTYPER,	AJPL,	/* non-negative (plus) (SF = 0) */
 	"JNS",		LTYPER,	AJPL,	/* alternate */
-	"JPS",		LTYPER,	AJPS,
+	"JPS",		LTYPER,	AJPS,	/* parity set (PF = 1) */
 	"JP",		LTYPER,	AJPS,	/* alternate */
 	"JPE",		LTYPER,	AJPS,	/* alternate */
-	"JPC",		LTYPER,	AJPC,
+	"JPC",		LTYPER,	AJPC,	/* parity clear (PF = 0) */
 	"JNP",		LTYPER,	AJPC,	/* alternate */
 	"JPO",		LTYPER,	AJPC,	/* alternate */
-	"JLT",		LTYPER,	AJLT,
+	"JLT",		LTYPER,	AJLT,	/* less than (signed) (SF != OF) */
 	"JL",		LTYPER,	AJLT,	/* alternate */
 	"JNGE",		LTYPER,	AJLT,	/* alternate */
-	"JGE",		LTYPER,	AJGE,
+	"JGE",		LTYPER,	AJGE,	/* greater than or equal (signed) (SF = OF) */
 	"JNL",		LTYPER,	AJGE,	/* alternate */
-	"JLE",		LTYPER,	AJLE,
+	"JLE",		LTYPER,	AJLE,	/* less than or equal (signed) (ZF = 1 || SF != OF) */
 	"JNG",		LTYPER,	AJLE,	/* alternate */
-	"JGT",		LTYPER,	AJGT,
+	"JGT",		LTYPER,	AJGT,	/* greater than (signed) (ZF = 0 && SF = OF) */
 	"JG",		LTYPER,	AJGT,	/* alternate */
 	"JNLE",		LTYPER,	AJGT,	/* alternate */
 	"JCXZL",	LTYPER,	AJCXZL,
@@ -612,7 +613,7 @@ struct
 	"SCASL",	LTYPE0,	ASCASL,
 	"SCASQ",	LTYPE0,	ASCASQ,
 	"SCASW",	LTYPE0,	ASCASW,
-	"SETCC",	LTYPE1,	ASETCC,
+	"SETCC",	LTYPE1,	ASETCC,	/* see JCC etc above for condition codes */
 	"SETCS",	LTYPE1,	ASETCS,
 	"SETEQ",	LTYPE1,	ASETEQ,
 	"SETGE",	LTYPE1,	ASETGE,
diff --git a/src/cmd/6a/y.tab.c b/src/cmd/6a/y.tab.c
index a4f0f74..b69fd95 100644
--- a/src/cmd/6a/y.tab.c
+++ b/src/cmd/6a/y.tab.c
@@ -150,7 +150,7 @@
 #include <stdio.h>	/* if we don't, bison will, and a.h re-#defines getc */
 #include <libc.h>
 #include "a.h"
-#include "../../pkg/runtime/funcdata.h"
+#include "../../runtime/funcdata.h"
 
 
 /* Enabling traces.  */
diff --git a/src/cmd/6c/cgen.c b/src/cmd/6c/cgen.c
index bdef76f..68dd7bb 100644
--- a/src/cmd/6c/cgen.c
+++ b/src/cmd/6c/cgen.c
@@ -29,7 +29,7 @@
 // THE SOFTWARE.
 
 #include "gc.h"
-#include "../../pkg/runtime/funcdata.h"
+#include "../../runtime/funcdata.h"
 
 /* ,x/^(print|prtree)\(/i/\/\/ */
 int castup(Type*, Type*);
@@ -51,7 +51,7 @@ cgen(Node *n, Node *nn)
 	}
 	if(n == Z || n->type == T)
 		return;
-	if(typesu[n->type->etype]) {
+	if(typesu[n->type->etype] && (n->op != OFUNC || nn != Z)) {
 		sugen(n, nn, n->type->width);
 		return;
 	}
@@ -88,7 +88,7 @@ cgen(Node *n, Node *nn)
 		if(cond(o) && typesu[l->type->etype])
 			break;
 
-		regret(&nod, r);
+		regret(&nod, r, 0, 0);
 		cgen(r, &nod);
 
 		regsalloc(&nod1, r);
@@ -135,7 +135,7 @@ cgen(Node *n, Node *nn)
 		if(!hardleft) {
 			if(nn != Z || r->addable < INDEXED || hardconst(r)) {
 				if(r->complex >= FNX && nn == Z)
-					regret(&nod, r);
+					regret(&nod, r, 0, 0);
 				else
 					regalloc(&nod, r, nn);
 				cgen(r, &nod);
@@ -929,7 +929,7 @@ cgen(Node *n, Node *nn)
 			if(l->op != OIND)
 				diag(n, "bad function call");
 
-			regret(&nod, l->left);
+			regret(&nod, l->left, 0, 0);
 			cgen(l->left, &nod);
 			regsalloc(&nod1, l->left);
 			gmove(&nod, &nod1);
@@ -945,7 +945,6 @@ cgen(Node *n, Node *nn)
 			return;
 		}
 		gargs(r, &nod, &nod1);
-		gpcdata(PCDATA_ArgSize, curarg);
 		if(l->addable < INDEXED) {
 			reglcgen(&nod, l, nn);
 			nod.op = OREGISTER;
@@ -953,14 +952,13 @@ cgen(Node *n, Node *nn)
 			regfree(&nod);
 		} else
 			gopcode(OFUNC, n->type, Z, l);
-		gpcdata(PCDATA_ArgSize, -1);
 		if(REGARG >= 0 && reg[REGARG])
 			reg[REGARG]--;
-		if(nn != Z) {
-			regret(&nod, n);
+		regret(&nod, n, l->type, 1); // update maxarg if nothing else
+		if(nn != Z)
 			gmove(&nod, nn);
+		if(nod.op == OREGISTER)
 			regfree(&nod);
-		}
 		break;
 
 	case OIND:
@@ -1382,7 +1380,7 @@ boolgen(Node *n, int true, Node *nn)
 		if(true)
 			o = comrel[relindex(o)];
 		if(l->complex >= FNX && r->complex >= FNX) {
-			regret(&nod, r);
+			regret(&nod, r, 0, 0);
 			cgen(r, &nod);
 			regsalloc(&nod1, r);
 			gmove(&nod, &nod1);
@@ -1535,7 +1533,7 @@ sugen(Node *n, Node *nn, int32 w)
 		if(nn != Z && side(nn)) {
 			nod1 = *n;
 			nod1.type = typ(TIND, n->type);
-			regret(&nod2, &nod1);
+			regret(&nod2, &nod1, 0, 0);
 			lcgen(nn, &nod2);
 			regsalloc(&nod0, &nod1);
 			cgen(&nod2, &nod0);
@@ -1617,6 +1615,20 @@ sugen(Node *n, Node *nn, int32 w)
 		break;
 
 	case OFUNC:
+		if(!hasdotdotdot(n->left->type)) {
+			cgen(n, Z);
+			if(nn != Z) {
+				curarg -= n->type->width;
+				regret(&nod1, n, n->left->type, 1);
+				if(nn->complex >= FNX) {
+					regsalloc(&nod2, n);
+					cgen(&nod1, &nod2);
+					nod1 = nod2;
+				}
+				cgen(&nod1, nn);
+			}
+			break;
+		}
 		if(nn == Z) {
 			sugen(n, nodrat, w);
 			break;
diff --git a/src/cmd/6c/gc.h b/src/cmd/6c/gc.h
index a196e55..aa9d95d 100644
--- a/src/cmd/6c/gc.h
+++ b/src/cmd/6c/gc.h
@@ -143,7 +143,6 @@ EXTERN	int32	cursafe;
 EXTERN	Prog*	lastp;
 EXTERN	int32	maxargsafe;
 EXTERN	int	mnstring;
-EXTERN	int	retok;
 EXTERN	Node*	nodrat;
 EXTERN	Node*	nodret;
 EXTERN	Node*	nodsafe;
@@ -211,7 +210,7 @@ void	xcom(Node*);
 void	indx(Node*);
 int	bcomplex(Node*, Node*);
 Prog*	gtext(Sym*, int32);
-vlong	argsize(void);
+vlong	argsize(int);
 
 /*
  * cgen.c
@@ -240,7 +239,7 @@ Node*	nodfconst(double);
 Node*	nodgconst(vlong, Type*);
 int	nodreg(Node*, Node*, int);
 int	isreg(Node*, int);
-void	regret(Node*, Node*);
+void	regret(Node*, Node*, Type*, int);
 void	regalloc(Node*, Node*, Node*);
 void	regfree(Node*);
 void	regialloc(Node*, Node*, Node*);
diff --git a/src/cmd/6c/reg.c b/src/cmd/6c/reg.c
index 348d747..6f8d3ce 100644
--- a/src/cmd/6c/reg.c
+++ b/src/cmd/6c/reg.c
@@ -585,14 +585,11 @@ loop2:
 			}
 			rgp->cost = change;
 			nregion++;
-			if(nregion >= NRGN) {
-				warn(Z, "too many regions");
-				goto brk;
-			}
+			if(nregion >= NRGN)
+				fatal(Z, "too many regions");
 			rgp++;
 		}
 	}
-brk:
 	qsort(region, nregion, sizeof(region[0]), rcmp);
 
 	/*
@@ -808,11 +805,8 @@ mkvar(Reg *r, Addr *a)
 			goto out;
 		v++;
 	}
-	if(nvar >= NVAR) {
-		if(debug['w'] > 1 && s)
-			warn(Z, "variable not optimized: %s", s->name);
-		goto none;
-	}
+	if(nvar >= NVAR)
+		fatal(Z, "variable not optimized: %s", s->name);
 	i = nvar;
 	nvar++;
 	v = &var[i];
diff --git a/src/cmd/6c/sgen.c b/src/cmd/6c/sgen.c
index ba1c1f6..fceb332 100644
--- a/src/cmd/6c/sgen.c
+++ b/src/cmd/6c/sgen.c
@@ -29,14 +29,14 @@
 // THE SOFTWARE.
 
 #include "gc.h"
-#include "../../pkg/runtime/funcdata.h"
+#include "../../runtime/funcdata.h"
 
 Prog*
 gtext(Sym *s, int32 stkoff)
 {
 	vlong v;
 
-	v = ((uvlong)argsize() << 32) | (stkoff & 0xffffffff);
+	v = ((uvlong)argsize(1) << 32) | (stkoff & 0xffffffff);
 	if((textflag & NOSPLIT) && stkoff >= 128)
 		yyerror("stack frame too large for NOSPLIT function");
 
@@ -124,10 +124,7 @@ xcom(Node *n)
 		break;
 
 	case ONAME:
-		if(flag_largemodel)
-			n->addable = 9;
-		else
-			n->addable = 10;
+		n->addable = 9;
 		if(n->class == CPARAM || n->class == CAUTO)
 			n->addable = 11;
 		break;
diff --git a/src/cmd/6c/swt.c b/src/cmd/6c/swt.c
index d771364..6e918eb 100644
--- a/src/cmd/6c/swt.c
+++ b/src/cmd/6c/swt.c
@@ -250,10 +250,11 @@ align(int32 i, Type *t, int op, int32 *maxalign)
 {
 	int32 o;
 	Type *v;
-	int w;
+	int w, packw;
 
 	o = i;
 	w = 1;
+	packw = 0;
 	switch(op) {
 	default:
 		diag(Z, "unknown align opcode %d", op);
@@ -264,7 +265,7 @@ align(int32 i, Type *t, int op, int32 *maxalign)
 		if(w < 1)
 			w = 1;
 		if(packflg)
-			w = packflg;
+			packw = packflg;
 		break;
 
 	case Ael1:	/* initial align of struct element */
@@ -277,7 +278,7 @@ align(int32 i, Type *t, int op, int32 *maxalign)
 		if(w < 1 || w > SZ_VLONG)
 			fatal(Z, "align");
 		if(packflg) 
-			w = packflg;
+			packw = packflg;
 		break;
 
 	case Ael2:	/* width of a struct element */
@@ -331,6 +332,8 @@ align(int32 i, Type *t, int op, int32 *maxalign)
 		o = align(o, t, Ael2, nil);
 		break;
 	}
+	if(packw != 0 && xround(o, w) != xround(o, packw))
+		diag(Z, "#pragma pack changes offset of %T", t);
 	o = xround(o, w);
 	if(maxalign && *maxalign < w)
 		*maxalign = w;
diff --git a/src/cmd/6c/txt.c b/src/cmd/6c/txt.c
index 4d07436..3bdbf41 100644
--- a/src/cmd/6c/txt.c
+++ b/src/cmd/6c/txt.c
@@ -351,15 +351,43 @@ nodreg(Node *n, Node *nn, int r)
 }
 
 void
-regret(Node *n, Node *nn)
+regret(Node *n, Node *nn, Type *t, int mode)
 {
 	int r;
+	
+	if(mode == 0 || hasdotdotdot(t) || nn->type->width == 0) {
+		r = REGRET;
+		if(typefd[nn->type->etype])
+			r = FREGRET;
+		nodreg(n, nn, r);
+		reg[r]++;
+		return;
+	}
+	
+	if(mode == 1) {
+		// fetch returned value after call.
+		// already called gargs, so curarg is set.
+		curarg = (curarg+7) & ~7;
+		regaalloc(n, nn);
+		return;
+	}
 
-	r = REGRET;
-	if(typefd[nn->type->etype])
-		r = FREGRET;
-	nodreg(n, nn, r);
-	reg[r]++;
+	if(mode == 2) {
+		// store value to be returned.
+		// must compute arg offset.
+		if(t->etype != TFUNC)
+			fatal(Z, "bad regret func %T", t);
+		*n = *nn;
+		n->op = ONAME;
+		n->class = CPARAM;
+		n->sym = slookup(".ret");
+		n->complex = nodret->complex;
+		n->addable = 20;
+		n->xoffset = argsize(0);
+		return;
+	}
+	
+	fatal(Z, "bad regret");	
 }
 
 void
diff --git a/src/cmd/6g/cgen.c b/src/cmd/6g/cgen.c
index 4dd505b..d13c98d 100644
--- a/src/cmd/6g/cgen.c
+++ b/src/cmd/6g/cgen.c
@@ -247,7 +247,6 @@ cgen(Node *n, Node *res)
 	case OOR:
 	case OXOR:
 	case OADD:
-	case OADDPTR:
 	case OMUL:
 		a = optoas(n->op, nl->type);
 		if(a == AIMULB) {
@@ -752,12 +751,7 @@ agenr(Node *n, Node *a, Node *res)
 			regalloc(&n3, types[tptr], res);
 			p1 = gins(ALEAQ, N, &n3);
 			datastring(nl->val.u.sval->s, nl->val.u.sval->len, &p1->from);
-			if(flag_largemodel) {
-				gins(AADDQ, &n2, &n3);
-			} else {
-				p1->from.scale = 1;
-				p1->from.index = n2.val.u.reg;
-			}
+			gins(AADDQ, &n2, &n3);
 			goto indexdone;
 		}
 
@@ -1457,7 +1451,7 @@ sgen(Node *n, Node *ns, int64 w)
 			p = gins(ADUFFCOPY, N, N);
 			p->to.type = D_ADDR;
 			p->to.sym = linksym(pkglookup("duffcopy", runtimepkg));
-			// 14 and 128 = magic constants: see ../../pkg/runtime/asm_amd64.s
+			// 14 and 128 = magic constants: see ../../runtime/asm_amd64.s
 			p->to.offset = 14*(128-q);
 		} else
 		while(q > 0) {
diff --git a/src/cmd/6g/galign.c b/src/cmd/6g/galign.c
index 1d32c5a..5670e6f 100644
--- a/src/cmd/6g/galign.c
+++ b/src/cmd/6g/galign.c
@@ -30,10 +30,10 @@ int	cmpptr = ACMPQ;
  */
 Typedef	typedefs[] =
 {
-	"int",		TINT,		TINT64,
-	"uint",		TUINT,		TUINT64,
-	"uintptr",	TUINTPTR,	TUINT64,
-	0
+	{"int",		TINT,		TINT64},
+	{"uint",		TUINT,		TUINT64},
+	{"uintptr",	TUINTPTR,	TUINT64},
+	{0}
 };
 
 void
diff --git a/src/cmd/6g/gg.h b/src/cmd/6g/gg.h
index a5da17d..fe69d5c 100644
--- a/src/cmd/6g/gg.h
+++ b/src/cmd/6g/gg.h
@@ -51,7 +51,6 @@ void	allocparams(void);
 void	checklabels(void);
 void	ginscall(Node*, int);
 int	gen_as_init(Node*);
-void	clearslim(Node*);
 
 /*
  * cgen.c
@@ -100,7 +99,6 @@ int	sudoaddable(int, Node*, Addr*);
 void	afunclit(Addr*, Node*);
 void	nodfconst(Node*, Type*, Mpflt*);
 void	gtrack(Sym*);
-void	gargsize(vlong);
 void	fixlargeoffset(Node *n);
 
 /*
diff --git a/src/cmd/6g/ggen.c b/src/cmd/6g/ggen.c
index 9665d83..3636207 100644
--- a/src/cmd/6g/ggen.c
+++ b/src/cmd/6g/ggen.c
@@ -175,7 +175,6 @@ fixautoused(Prog *p)
 void
 ginscall(Node *f, int proc)
 {
-	int32 arg;
 	Prog *p;
 	Node reg, con;
 	Node r1;
@@ -183,21 +182,6 @@ ginscall(Node *f, int proc)
 	if(f->type != T)
 		setmaxarg(f->type);
 
-	arg = -1;
-	// Most functions have a fixed-size argument block, so traceback uses that during unwind.
-	// Not all, though: there are some variadic functions in package runtime,
-	// and for those we emit call-specific metadata recorded by caller.
-	// Reflect generates functions with variable argsize (see reflect.methodValueCall/makeFuncStub),
-	// so we do this for all indirect calls as well.
-	if(f->type != T && (f->sym == S || (f->sym != S && f->sym->pkg == runtimepkg) || proc == 1 || proc == 2)) {
-		arg = f->type->argwid;
-		if(proc == 1 || proc == 2)
-			arg += 2*widthptr;
-	}
-
-	if(arg != -1)
-		gargsize(arg);
-
 	switch(proc) {
 	default:
 		fatal("ginscall: bad proc %d", proc);
@@ -275,9 +259,6 @@ ginscall(Node *f, int proc)
 		}
 		break;
 	}
-
-	if(arg != -1)
-		gargsize(-1);
 }
 
 /*
@@ -1121,26 +1102,54 @@ clearfat(Node *nl)
 	c = w % 8;	// bytes
 	q = w / 8;	// quads
 
+	if(q < 4) {
+		// Write sequence of MOV 0, off(base) instead of using STOSQ.
+		// The hope is that although the code will be slightly longer,
+		// the MOVs will have no dependencies and pipeline better
+		// than the unrolled STOSQ loop.
+		// NOTE: Must use agen, not igen, so that optimizer sees address
+		// being taken. We are not writing on field boundaries.
+		agenr(nl, &n1, N);
+		n1.op = OINDREG;
+		nodconst(&z, types[TUINT64], 0);
+		while(q-- > 0) {
+			n1.type = z.type;
+			gins(AMOVQ, &z, &n1);
+			n1.xoffset += 8;
+		}
+		if(c >= 4) {
+			nodconst(&z, types[TUINT32], 0);
+			n1.type = z.type;
+			gins(AMOVL, &z, &n1);
+			n1.xoffset += 4;
+			c -= 4;
+		}
+		nodconst(&z, types[TUINT8], 0);
+		while(c-- > 0) {
+			n1.type = z.type;
+			gins(AMOVB, &z, &n1);
+			n1.xoffset++;
+		}
+		regfree(&n1);
+		return;
+	}
+
 	savex(D_DI, &n1, &oldn1, N, types[tptr]);
 	agen(nl, &n1);
 
 	savex(D_AX, &ax, &oldax, N, types[tptr]);
 	gconreg(AMOVL, 0, D_AX);
 
-	if(q > 128 || (q >= 4 && nacl)) {
+	if(q > 128 || nacl) {
 		gconreg(movptr, q, D_CX);
 		gins(AREP, N, N);	// repeat
 		gins(ASTOSQ, N, N);	// STOQ AL,*(DI)+
-	} else if(q >= 4) {
+	} else {
 		p = gins(ADUFFZERO, N, N);
 		p->to.type = D_ADDR;
 		p->to.sym = linksym(pkglookup("duffzero", runtimepkg));
-		// 2 and 128 = magic constants: see ../../pkg/runtime/asm_amd64.s
+		// 2 and 128 = magic constants: see ../../runtime/asm_amd64.s
 		p->to.offset = 2*(128-q);
-	} else
-	while(q > 0) {
-		gins(ASTOSQ, N, N);	// STOQ AL,*(DI)+
-		q--;
 	}
 
 	z = ax;
diff --git a/src/cmd/6g/gsubr.c b/src/cmd/6g/gsubr.c
index e4d00bf..5bd9246 100644
--- a/src/cmd/6g/gsubr.c
+++ b/src/cmd/6g/gsubr.c
@@ -31,11 +31,11 @@
 #include <u.h>
 #include <libc.h>
 #include "gg.h"
-#include "../../pkg/runtime/funcdata.h"
+#include "../../runtime/funcdata.h"
 
 // TODO(rsc): Can make this bigger if we move
 // the text segment up higher in 6l for all GOOS.
-// At the same time, can raise StackBig in ../../pkg/runtime/stack.h.
+// At the same time, can raise StackBig in ../../runtime/stack.h.
 vlong unmappedzero = 4096;
 
 void
@@ -215,17 +215,7 @@ gtrack(Sym *s)
 }
 
 void
-gargsize(vlong size)
-{
-	Node n1, n2;
-	
-	nodconst(&n1, types[TINT32], PCDATA_ArgSize);
-	nodconst(&n2, types[TINT32], size);
-	gins(APCDATA, &n1, &n2);
-}
-
-void
-ggloblsym(Sym *s, int32 width, int dupok, int rodata)
+ggloblsym(Sym *s, int32 width, int8 flags)
 {
 	Prog *p;
 
@@ -236,10 +226,7 @@ ggloblsym(Sym *s, int32 width, int dupok, int rodata)
 	p->to.type = D_CONST;
 	p->to.index = D_NONE;
 	p->to.offset = width;
-	if(dupok)
-		p->from.scale |= DUPOK;
-	if(rodata)
-		p->from.scale |= RODATA;
+	p->from.scale = flags;
 }
 
 int
@@ -584,6 +571,7 @@ ginscon(int as, vlong c, Node *n2)
 }
 
 #define	CASE(a,b)	(((a)<<16)|((b)<<0))
+/*c2go int CASE(int, int); */
 
 /*
  * Is this node a memory operand?
@@ -600,11 +588,8 @@ ismem(Node *n)
 	case ONAME:
 	case OPARAM:
 	case OCLOSUREVAR:
-		return 1;
 	case OADDR:
-		if(flag_largemodel)
-			return 1;
-		break;
+		return 1;
 	}
 	return 0;
 }
@@ -1542,14 +1527,12 @@ optoas(int op, Type *t)
 	case CASE(OADD, TINT32):
 	case CASE(OADD, TUINT32):
 	case CASE(OADD, TPTR32):
-	case CASE(OADDPTR, TPTR32):
 		a = AADDL;
 		break;
 
 	case CASE(OADD, TINT64):
 	case CASE(OADD, TUINT64):
 	case CASE(OADD, TPTR64):
-	case CASE(OADDPTR, TPTR64):
 		a = AADDQ;
 		break;
 
diff --git a/src/cmd/6g/opt.h b/src/cmd/6g/opt.h
index bf356af..dbd039d 100644
--- a/src/cmd/6g/opt.h
+++ b/src/cmd/6g/opt.h
@@ -49,6 +49,24 @@
 typedef	struct	Reg	Reg;
 typedef	struct	Rgn	Rgn;
 
+/*c2go
+extern Node *Z;
+enum
+{
+	D_HI = D_NONE,
+	D_LO = D_NONE,
+	CLOAD = 5,
+	CREF = 5,
+	CINF = 1000,
+	LOOP = 3,
+};
+
+uint32 BLOAD(Reg*);
+uint32 BSTORE(Reg*);
+uint32 LOAD(Reg*);
+uint32 STORE(Reg*);
+*/
+
 // A Reg is a wrapper around a single Prog (one instruction) that holds
 // register optimization information while the optimizer runs.
 // r->prog is the instruction.
@@ -71,8 +89,10 @@ struct	Reg
 	int32	regu;		// register used bitmap
 };
 #define	R	((Reg*)0)
+/*c2go extern Reg *R; */
 
 #define	NRGN	600
+/*c2go enum { NRGN = 600 }; */
 struct	Rgn
 {
 	Reg*	enter;
diff --git a/src/cmd/6g/reg.c b/src/cmd/6g/reg.c
index f3b1e55..1f757e1 100644
--- a/src/cmd/6g/reg.c
+++ b/src/cmd/6g/reg.c
@@ -35,6 +35,11 @@
 
 #define	NREGVAR	32	/* 16 general + 16 floating */
 #define	REGBITS	((uint32)0xffffffff)
+/*c2go enum {
+	NREGVAR = 32,
+	REGBITS = 0xffffffff,
+};
+*/
 
 static	Reg*	firstr;
 static	int	first	= 1;
@@ -839,7 +844,7 @@ prop(Reg *r, Bits ref, Bits cal)
 					if(v == v1 || ((cal.b[j/32]>>(j&31))&1) == 0) {
 						for(; v1 != nil; v1 = v1->nextinnode) {
 							j = v1 - var;
-							cal.b[j/32] |= 1<<(j&31);
+							cal.b[j/32] |= 1UL<<(j&31);
 						}
 					}
 				}
@@ -1186,6 +1191,7 @@ void
 addreg(Adr *a, int rn)
 {
 	a->sym = nil;
+	a->node = nil;
 	a->offset = 0;
 	a->type = rn;
 
diff --git a/src/cmd/6l/6.out.h b/src/cmd/6l/6.out.h
index 1e2a148..af72784 100644
--- a/src/cmd/6l/6.out.h
+++ b/src/cmd/6l/6.out.h
@@ -36,7 +36,7 @@
  *	amd64
  */
 
-enum	as
+enum
 {
 	AXXX,
 	AAAA,
diff --git a/src/cmd/6l/asm.c b/src/cmd/6l/asm.c
index 7828e28..18b5aa3 100644
--- a/src/cmd/6l/asm.c
+++ b/src/cmd/6l/asm.c
@@ -290,7 +290,6 @@ elfreloc1(Reloc *r, vlong sectoff)
 		break;
 		
 	case R_CALL:
-	case R_PCREL:
 		if(r->siz == 4) {
 			if(r->xsym->type == SDYNIMPORT)
 				VPUT(R_X86_64_GOTPCREL | (uint64)elfsym<<32);
@@ -299,7 +298,14 @@ elfreloc1(Reloc *r, vlong sectoff)
 		} else
 			return -1;
 		break;
-	
+
+	case R_PCREL:
+		if(r->siz == 4) {
+			VPUT(R_X86_64_PC32 | (uint64)elfsym<<32);
+		} else
+			return -1;
+		break;
+
 	case R_TLS:
 		if(r->siz == 4) {
 			if(flag_shared)
@@ -323,7 +329,7 @@ machoreloc1(Reloc *r, vlong sectoff)
 	
 	rs = r->xsym;
 
-	if(rs->type == SHOSTOBJ) {
+	if(rs->type == SHOSTOBJ || r->type == R_PCREL) {
 		if(rs->dynid < 0) {
 			diag("reloc %d to non-macho symbol %s type=%d", r->type, rs->name, rs->type);
 			return -1;
@@ -345,10 +351,13 @@ machoreloc1(Reloc *r, vlong sectoff)
 		v |= MACHO_X86_64_RELOC_UNSIGNED<<28;
 		break;
 	case R_CALL:
-	case R_PCREL:
 		v |= 1<<24; // pc-relative bit
 		v |= MACHO_X86_64_RELOC_BRANCH<<28;
 		break;
+	case R_PCREL:
+		// NOTE: Only works with 'external' relocation. Forced above.
+		v |= 1<<24; // pc-relative bit
+		v |= MACHO_X86_64_RELOC_SIGNED<<28;
 	}
 	
 	switch(r->siz) {
diff --git a/src/cmd/6l/l.h b/src/cmd/6l/l.h
index 7303910..ff2e694 100644
--- a/src/cmd/6l/l.h
+++ b/src/cmd/6l/l.h
@@ -68,14 +68,9 @@ EXTERN	int	RegSize;
 
 #define	P		((Prog*)0)
 #define	S		((LSym*)0)
-#define	TNAME		(ctxt->cursym?ctxt->cursym->name:noname)
 enum
 {
-	MINSIZ		= 8,
-	STRINGSZ	= 200,
 	MINLC		= 1,
-	MAXIO		= 8192,
-	MAXHIST		= 40,				/* limit of path elements for history symbols */
 };
 
 #pragma	varargck	type	"I"	uchar*
@@ -89,9 +84,6 @@ EXTERN	int32	spsize;
 EXTERN	LSym*	symlist;
 EXTERN	int32	symsize;
 
-EXTERN	vlong	textstksiz;
-EXTERN	vlong	textarg;
-
 int	Iconv(Fmt *fp);
 void	adddynlib(char *lib);
 void	adddynrel(LSym *s, Reloc *r);
@@ -103,8 +95,6 @@ int	elfreloc1(Reloc *r, vlong sectoff);
 void	elfsetupplt(void);
 void	listinit(void);
 int	machoreloc1(Reloc *r, vlong sectoff);
-void	main(int argc, char *argv[]);
-void	parsetextconst(vlong arg);
 vlong	rnd(vlong v, vlong r);
 
 /* Native is little-endian */
diff --git a/src/cmd/6l/mkenam b/src/cmd/6l/mkenam
deleted file mode 100644
index 3001dbe..0000000
--- a/src/cmd/6l/mkenam
+++ /dev/null
@@ -1,45 +0,0 @@
-# Inferno utils/6c/mkenam
-# http://code.google.com/p/inferno-os/source/browse/utils/6c/mkenam
-#
-#	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-#	Portions Copyright © 1995-1997 C H Forsyth (forsyth at terzarima.net)
-#	Portions Copyright © 1997-1999 Vita Nuova Limited
-#	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-#	Portions Copyright © 2004,2006 Bruce Ellis
-#	Portions Copyright © 2005-2007 C H Forsyth (forsyth at terzarima.net)
-#	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-#	Portions Copyright © 2009 The Go Authors.  All rights reserved.
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-# THE SOFTWARE.
-
-awk '
-BEGIN {
-	print "char*	anames[] ="
-	print "{"
-}
-
-/^	A/ {
-	name=$1
-	sub(/,/, "", name)
-	sub(/^A/, "", name)
-	print "\t\"" name "\","
-}
-
-END { print "};" }
-' ../6l/6.out.h >enam.c
diff --git a/src/cmd/8a/a.y b/src/cmd/8a/a.y
index d7ff623..6bcf131 100644
--- a/src/cmd/8a/a.y
+++ b/src/cmd/8a/a.y
@@ -33,7 +33,7 @@
 #include <stdio.h>	/* if we don't, bison will, and a.h re-#defines getc */
 #include <libc.h>
 #include "a.h"
-#include "../../pkg/runtime/funcdata.h"
+#include "../../runtime/funcdata.h"
 %}
 %union	{
 	Sym	*sym;
diff --git a/src/cmd/8a/lex.c b/src/cmd/8a/lex.c
index 32c099b..6ce6a18 100644
--- a/src/cmd/8a/lex.c
+++ b/src/cmd/8a/lex.c
@@ -90,6 +90,7 @@ main(int argc, char *argv[])
 	ctxt = linknew(&link386);
 	ctxt->diag = yyerror;
 	ctxt->bso = &bstdout;
+	ctxt->enforce_data_order = 1;
 	Binit(&bstdout, 1, OWRITE);
 	listinit8();
 	fmtinstall('L', Lconv);
@@ -352,49 +353,49 @@ struct
 	"IRETL",	LTYPE0,	AIRETL,
 	"IRETW",	LTYPE0,	AIRETW,
 
-	"JOS",		LTYPER,	AJOS,
+	"JOS",		LTYPER,	AJOS,	/* overflow set (OF = 1) */
 	"JO",		LTYPER,	AJOS,	/* alternate */
-	"JOC",		LTYPER,	AJOC,
+	"JOC",		LTYPER,	AJOC,	/* overflow clear (OF = 0) */
 	"JNO",		LTYPER,	AJOC,	/* alternate */
-	"JCS",		LTYPER,	AJCS,
+	"JCS",		LTYPER,	AJCS,	/* carry set (CF = 1) */
 	"JB",		LTYPER,	AJCS,	/* alternate */
 	"JC",		LTYPER,	AJCS,	/* alternate */
 	"JNAE",		LTYPER,	AJCS,	/* alternate */
 	"JLO",		LTYPER,	AJCS,	/* alternate */
-	"JCC",		LTYPER,	AJCC,
+	"JCC",		LTYPER,	AJCC,	/* carry clear (CF = 0) */
 	"JAE",		LTYPER,	AJCC,	/* alternate */
 	"JNB",		LTYPER,	AJCC,	/* alternate */
 	"JNC",		LTYPER,	AJCC,	/* alternate */
 	"JHS",		LTYPER,	AJCC,	/* alternate */
-	"JEQ",		LTYPER,	AJEQ,
+	"JEQ",		LTYPER,	AJEQ,	/* equal (ZF = 1) */
 	"JE",		LTYPER,	AJEQ,	/* alternate */
 	"JZ",		LTYPER,	AJEQ,	/* alternate */
-	"JNE",		LTYPER,	AJNE,
+	"JNE",		LTYPER,	AJNE,	/* not equal (ZF = 0) */
 	"JNZ",		LTYPER,	AJNE,	/* alternate */
-	"JLS",		LTYPER,	AJLS,
+	"JLS",		LTYPER,	AJLS,	/* lower or same (unsigned) (CF = 1 || ZF = 1) */
 	"JBE",		LTYPER,	AJLS,	/* alternate */
 	"JNA",		LTYPER,	AJLS,	/* alternate */
-	"JHI",		LTYPER,	AJHI,
+	"JHI",		LTYPER,	AJHI,	/* higher (unsigned) (CF = 0 && ZF = 0) */
 	"JA",		LTYPER,	AJHI,	/* alternate */
 	"JNBE",		LTYPER,	AJHI,	/* alternate */
-	"JMI",		LTYPER,	AJMI,
+	"JMI",		LTYPER,	AJMI,	/* negative (minus) (SF = 1) */
 	"JS",		LTYPER,	AJMI,	/* alternate */
-	"JPL",		LTYPER,	AJPL,
+	"JPL",		LTYPER,	AJPL,	/* non-negative (plus) (SF = 0) */
 	"JNS",		LTYPER,	AJPL,	/* alternate */
-	"JPS",		LTYPER,	AJPS,
+	"JPS",		LTYPER,	AJPS,	/* parity set (PF = 1) */
 	"JP",		LTYPER,	AJPS,	/* alternate */
 	"JPE",		LTYPER,	AJPS,	/* alternate */
-	"JPC",		LTYPER,	AJPC,
+	"JPC",		LTYPER,	AJPC,	/* parity clear (PF = 0) */
 	"JNP",		LTYPER,	AJPC,	/* alternate */
 	"JPO",		LTYPER,	AJPC,	/* alternate */
-	"JLT",		LTYPER,	AJLT,
+	"JLT",		LTYPER,	AJLT,	/* less than (signed) (SF != OF) */
 	"JL",		LTYPER,	AJLT,	/* alternate */
 	"JNGE",		LTYPER,	AJLT,	/* alternate */
-	"JGE",		LTYPER,	AJGE,
+	"JGE",		LTYPER,	AJGE,	/* greater than or equal (signed) (SF = OF) */
 	"JNL",		LTYPER,	AJGE,	/* alternate */
-	"JLE",		LTYPER,	AJLE,
+	"JLE",		LTYPER,	AJLE,	/* less than or equal (signed) (ZF = 1 || SF != OF) */
 	"JNG",		LTYPER,	AJLE,	/* alternate */
-	"JGT",		LTYPER,	AJGT,
+	"JGT",		LTYPER,	AJGT,	/* greater than (signed) (ZF = 0 && SF = OF) */
 	"JG",		LTYPER,	AJGT,	/* alternate */
 	"JNLE",		LTYPER,	AJGT,	/* alternate */
 
@@ -493,7 +494,7 @@ struct
 	"SCASB",	LTYPE0,	ASCASB,
 	"SCASL",	LTYPE0,	ASCASL,
 	"SCASW",	LTYPE0,	ASCASW,
-	"SETCC",	LTYPE1,	ASETCC,
+	"SETCC",	LTYPE1,	ASETCC,	/* see JCC etc above for condition codes */
 	"SETCS",	LTYPE1,	ASETCS,
 	"SETEQ",	LTYPE1,	ASETEQ,
 	"SETGE",	LTYPE1,	ASETGE,
diff --git a/src/cmd/8a/y.tab.c b/src/cmd/8a/y.tab.c
index f48c9fe..85279c2 100644
--- a/src/cmd/8a/y.tab.c
+++ b/src/cmd/8a/y.tab.c
@@ -146,7 +146,7 @@
 #include <stdio.h>	/* if we don't, bison will, and a.h re-#defines getc */
 #include <libc.h>
 #include "a.h"
-#include "../../pkg/runtime/funcdata.h"
+#include "../../runtime/funcdata.h"
 
 
 /* Enabling traces.  */
diff --git a/src/cmd/8c/cgen.c b/src/cmd/8c/cgen.c
index f541022..87e8fda 100644
--- a/src/cmd/8c/cgen.c
+++ b/src/cmd/8c/cgen.c
@@ -29,7 +29,7 @@
 // THE SOFTWARE.
 
 #include "gc.h"
-#include "../../pkg/runtime/funcdata.h"
+#include "../../runtime/funcdata.h"
 
 /* ,x/^(print|prtree)\(/i/\/\/ */
 
@@ -49,7 +49,7 @@ cgen(Node *n, Node *nn)
 	}
 	if(n == Z || n->type == T)
 		return;
-	if(typesuv[n->type->etype]) {
+	if(typesuv[n->type->etype] && (n->op != OFUNC || nn != Z)) {
 		sugen(n, nn, n->type->width);
 		return;
 	}
@@ -86,7 +86,7 @@ cgen(Node *n, Node *nn)
 		if(cond(o) && typesuv[l->type->etype])
 			break;
 
-		regret(&nod, r);
+		regret(&nod, r, 0, 0);
 		cgen(r, &nod);
 
 		regsalloc(&nod1, r);
@@ -147,7 +147,7 @@ cgen(Node *n, Node *nn)
 		if(!hardleft) {
 			if(nn != Z || r->addable < INDEXED) {
 				if(r->complex >= FNX && nn == Z)
-					regret(&nod, r);
+					regret(&nod, r, 0, 0);
 				else
 					regalloc(&nod, r, nn);
 				cgen(r, &nod);
@@ -922,7 +922,7 @@ cgen(Node *n, Node *nn)
 			if(l->op != OIND)
 				diag(n, "bad function call");
 
-			regret(&nod, l->left);
+			regret(&nod, l->left, 0, 0);
 			cgen(l->left, &nod);
 			regsalloc(&nod1, l->left);
 			gmove(&nod, &nod1);
@@ -938,7 +938,6 @@ cgen(Node *n, Node *nn)
 			return;
 		}
 		gargs(r, &nod, &nod1);
-		gpcdata(PCDATA_ArgSize, curarg);
 		if(l->addable < INDEXED) {
 			reglcgen(&nod, l, nn);
 			nod.op = OREGISTER;
@@ -946,15 +945,14 @@ cgen(Node *n, Node *nn)
 			regfree(&nod);
 		} else
 			gopcode(OFUNC, n->type, Z, l);
-		gpcdata(PCDATA_ArgSize, -1);
 		if(REGARG >= 0 && reg[REGARG])
 			reg[REGARG]--;
-		if(nn != Z) {
-			regret(&nod, n);
+		regret(&nod, n, l->type, 1); // update maxarg if nothing else
+		if(nn != Z)
 			gmove(&nod, nn);
+		if(nod.op == OREGISTER)
 			regfree(&nod);
-		} else
-		if(typefd[n->type->etype])
+		if(nn == Z && hasdotdotdot(l->type) && typefd[n->type->etype])
 			gins(AFMOVDP, &fregnode0, &fregnode0);
 		break;
 
@@ -1374,7 +1372,7 @@ boolgen(Node *n, int true, Node *nn)
 		if(true)
 			o = comrel[relindex(o)];
 		if(l->complex >= FNX && r->complex >= FNX) {
-			regret(&nod, r);
+			regret(&nod, r, 0, 0);
 			cgen(r, &nod);
 			regsalloc(&nod1, r);
 			gmove(&nod, &nod1);
@@ -1567,7 +1565,7 @@ sugen(Node *n, Node *nn, int32 w)
 		if(nn != Z && side(nn)) {
 			nod1 = *n;
 			nod1.type = typ(TIND, n->type);
-			regret(&nod2, &nod1);
+			regret(&nod2, &nod1, 0, 0);
 			lcgen(nn, &nod2);
 			regsalloc(&nod0, &nod1);
 			cgen(&nod2, &nod0);
@@ -1649,6 +1647,20 @@ sugen(Node *n, Node *nn, int32 w)
 		break;
 
 	case OFUNC:
+		if(!hasdotdotdot(n->left->type)) {
+			cgen(n, Z);
+			if(nn != Z) {
+				curarg -= n->type->width;
+				regret(&nod1, n, n->left->type, 1);
+				if(nn->complex >= FNX) {
+					regsalloc(&nod2, n);
+					cgen(&nod1, &nod2);
+					nod1 = nod2;
+				}
+				cgen(&nod1, nn);
+			}
+			break;
+		}
 		if(nn == Z) {
 			sugen(n, nodrat, w);
 			break;
diff --git a/src/cmd/8c/gc.h b/src/cmd/8c/gc.h
index 87b8e22..aa3888d 100644
--- a/src/cmd/8c/gc.h
+++ b/src/cmd/8c/gc.h
@@ -143,7 +143,6 @@ EXTERN	int32	cursafe;
 EXTERN	Prog*	lastp;
 EXTERN	int32	maxargsafe;
 EXTERN	int	mnstring;
-EXTERN	int	retok;
 EXTERN	Node*	nodrat;
 EXTERN	Node*	nodret;
 EXTERN	Node*	nodsafe;
@@ -211,7 +210,7 @@ void	xcom(Node*);
 void	indx(Node*);
 int	bcomplex(Node*, Node*);
 Prog*	gtext(Sym*, int32);
-vlong	argsize(void);
+vlong	argsize(int);
 
 /*
  * cgen.c
@@ -245,7 +244,7 @@ Node*	nodconst(int32);
 Node*	nodfconst(double);
 int	nodreg(Node*, Node*, int);
 int	isreg(Node*, int);
-void	regret(Node*, Node*);
+void	regret(Node*, Node*, Type*, int);
 void	regalloc(Node*, Node*, Node*);
 void	regfree(Node*);
 void	regialloc(Node*, Node*, Node*);
diff --git a/src/cmd/8c/reg.c b/src/cmd/8c/reg.c
index e6ba8bc..ea862f3 100644
--- a/src/cmd/8c/reg.c
+++ b/src/cmd/8c/reg.c
@@ -518,7 +518,7 @@ loop2:
 			rgp->cost = change;
 			nregion++;
 			if(nregion >= NRGN) {
-				warn(Z, "too many regions");
+				fatal(Z, "too many regions");
 				goto brk;
 			}
 			rgp++;
@@ -746,11 +746,8 @@ mkvar(Reg *r, Addr *a)
 			goto out;
 		v++;
 	}
-	if(nvar >= NVAR) {
-		if(debug['w'] > 1 && s)
-			warn(Z, "variable not optimized: %s", s->name);
-		goto none;
-	}
+	if(nvar >= NVAR)
+		fatal(Z, "variable not optimized: %s", s->name);
 	i = nvar;
 	nvar++;
 	v = &var[i];
diff --git a/src/cmd/8c/sgen.c b/src/cmd/8c/sgen.c
index 069bbc1..d647010 100644
--- a/src/cmd/8c/sgen.c
+++ b/src/cmd/8c/sgen.c
@@ -35,7 +35,7 @@ gtext(Sym *s, int32 stkoff)
 {
 	int32 a;
 
-	a = argsize();
+	a = argsize(1);
 	if((textflag & NOSPLIT) != 0 && stkoff >= 128)
 		yyerror("stack frame too large for NOSPLIT function");
 
diff --git a/src/cmd/8c/swt.c b/src/cmd/8c/swt.c
index ae36f84..d960519 100644
--- a/src/cmd/8c/swt.c
+++ b/src/cmd/8c/swt.c
@@ -255,10 +255,11 @@ align(int32 i, Type *t, int op, int32 *maxalign)
 {
 	int32 o;
 	Type *v;
-	int w;
+	int w, packw;
 
 	o = i;
 	w = 1;
+	packw = 0;
 	switch(op) {
 	default:
 		diag(Z, "unknown align opcode %d", op);
@@ -269,7 +270,7 @@ align(int32 i, Type *t, int op, int32 *maxalign)
 		if(w < 1)
 			w = 1;
 		if(packflg)
-			w = packflg;
+			packw = packflg;
 		break;
 
 	case Ael1:	/* initial align of struct element */
@@ -285,7 +286,7 @@ align(int32 i, Type *t, int op, int32 *maxalign)
 		if(w < 1 || w > SZ_LONG)
 			fatal(Z, "align");
 		if(packflg) 
-			w = packflg;
+			packw = packflg;
 		break;
 
 	case Ael2:	/* width of a struct element */
@@ -320,6 +321,8 @@ align(int32 i, Type *t, int op, int32 *maxalign)
 		o = align(o, t, Ael2, nil);
 		break;
 	}
+	if(packw != 0 && xround(o, w) != xround(o, packw))
+		diag(Z, "#pragma pack changes offset of %T", t);
 	o = xround(o, w);
 	if(maxalign && *maxalign < w)
 		*maxalign = w;
diff --git a/src/cmd/8c/txt.c b/src/cmd/8c/txt.c
index 25082de..7f87a0a 100644
--- a/src/cmd/8c/txt.c
+++ b/src/cmd/8c/txt.c
@@ -311,15 +311,43 @@ nodreg(Node *n, Node *nn, int r)
 }
 
 void
-regret(Node *n, Node *nn)
+regret(Node *n, Node *nn, Type *t, int mode)
 {
 	int r;
 
-	r = REGRET;
-	if(typefd[nn->type->etype])
-		r = FREGRET;
-	nodreg(n, nn, r);
-	reg[r]++;
+	if(mode == 0 || hasdotdotdot(t) || nn->type->width == 0) {
+		r = REGRET;
+		if(typefd[nn->type->etype])
+			r = FREGRET;
+		nodreg(n, nn, r);
+		reg[r]++;
+		return;
+	}
+	
+	if(mode == 1) {
+		// fetch returned value after call.
+		// already called gargs, so curarg is set.
+		curarg = (curarg+3) & ~3;
+		regaalloc(n, nn);
+		return;
+	}
+	
+	if(mode == 2) {
+		// store value to be returned.
+		// must compute arg offset.
+		if(t->etype != TFUNC)
+			fatal(Z, "bad regret func %T", t);
+		*n = *nn;
+		n->op = ONAME;
+		n->class = CPARAM;
+		n->sym = slookup(".retx");
+		n->complex = 0;
+		n->addable = 20;
+		n->xoffset = argsize(0);
+		return;
+	}
+	
+	fatal(Z, "bad regret");
 }
 
 void
diff --git a/src/cmd/8g/cgen.c b/src/cmd/8g/cgen.c
index d626c2e..2735fb6 100644
--- a/src/cmd/8g/cgen.c
+++ b/src/cmd/8g/cgen.c
@@ -242,7 +242,6 @@ cgen(Node *n, Node *res)
 	case OOR:
 	case OXOR:
 	case OADD:
-	case OADDPTR:
 	case OMUL:
 		a = optoas(n->op, nl->type);
 		if(a == AIMULB) {
@@ -347,8 +346,11 @@ cgen(Node *n, Node *res)
 		if(istype(nl->type, TCHAN)) {
 			// chan has cap in the second 32-bit word.
 			// a zero pointer means zero length
-			regalloc(&n1, types[tptr], res);
+			tempname(&n1, types[tptr]);
 			cgen(nl, &n1);
+			regalloc(&n2, types[tptr], N);
+			gmove(&n1, &n2);
+			n1 = n2;
 
 			nodconst(&n2, types[tptr], 0);
 			gins(optoas(OCMP, types[tptr]), &n1, &n2);
@@ -1324,7 +1326,7 @@ sgen(Node *n, Node *res, int64 w)
 			p = gins(ADUFFCOPY, N, N);
 			p->to.type = D_ADDR;
 			p->to.sym = linksym(pkglookup("duffcopy", runtimepkg));
-			// 10 and 128 = magic constants: see ../../pkg/runtime/asm_386.s
+			// 10 and 128 = magic constants: see ../../runtime/asm_386.s
 			p->to.offset = 10*(128-q);
 		} else
 		while(q > 0) {
@@ -1364,7 +1366,10 @@ int
 componentgen(Node *nr, Node *nl)
 {
 	Node nodl, nodr;
+	Type *t;
 	int freel, freer;
+	vlong fldcount;
+	vlong loffset, roffset;
 
 	freel = 0;
 	freer = 0;
@@ -1374,8 +1379,33 @@ componentgen(Node *nr, Node *nl)
 		goto no;
 
 	case TARRAY:
-		if(!isslice(nl->type))
+		t = nl->type;
+
+		// Slices are ok.
+		if(isslice(t))
+			break;
+		// Small arrays are ok.
+		if(t->bound > 0 && t->bound <= 3 && !isfat(t->type))
+			break;
+
+		goto no;
+
+	case TSTRUCT:
+		// Small structs with non-fat types are ok.
+		// Zero-sized structs are treated separately elsewhere.
+		fldcount = 0;
+		for(t=nl->type->type; t; t=t->down) {
+			if(isfat(t->type))
+				goto no;
+			if(t->etype != TFIELD)
+				fatal("componentgen: not a TFIELD: %lT", t);
+			fldcount++;
+		}
+		if(fldcount == 0 || fldcount > 4)
 			goto no;
+
+		break;
+
 	case TSTRING:
 	case TINTER:
 		break;
@@ -1396,7 +1426,7 @@ componentgen(Node *nr, Node *nl)
 			freer = 1;
 		}
 	}
-
+	
 	// nl and nr are 'cadable' which basically means they are names (variables) now.
 	// If they are the same variable, don't generate any code, because the
 	// VARDEF we generate will mark the old value as dead incorrectly.
@@ -1406,8 +1436,25 @@ componentgen(Node *nr, Node *nl)
 
 	switch(nl->type->etype) {
 	case TARRAY:
+		// componentgen for arrays.
 		if(nl->op == ONAME)
 			gvardef(nl);
+		t = nl->type;
+		if(!isslice(t)) {
+			nodl.type = t->type;
+			nodr.type = nodl.type;
+			for(fldcount=0; fldcount < t->bound; fldcount++) {
+				if(nr == N)
+					clearslim(&nodl);
+				else
+					gmove(&nodr, &nodl);
+				nodl.xoffset += t->type->width;
+				nodr.xoffset += t->type->width;
+			}
+			goto yes;
+		}
+
+		// componentgen for slices.
 		nodl.xoffset += Array_array;
 		nodl.type = ptrto(nl->type->type);
 
@@ -1419,7 +1466,7 @@ componentgen(Node *nr, Node *nl)
 		gmove(&nodr, &nodl);
 
 		nodl.xoffset += Array_nel-Array_array;
-		nodl.type = types[TUINT32];
+		nodl.type = types[simtype[TUINT]];
 
 		if(nr != N) {
 			nodr.xoffset += Array_nel-Array_array;
@@ -1429,7 +1476,7 @@ componentgen(Node *nr, Node *nl)
 		gmove(&nodr, &nodl);
 
 		nodl.xoffset += Array_cap-Array_nel;
-		nodl.type = types[TUINT32];
+		nodl.type = types[simtype[TUINT]];
 
 		if(nr != N) {
 			nodr.xoffset += Array_cap-Array_nel;
@@ -1454,7 +1501,7 @@ componentgen(Node *nr, Node *nl)
 		gmove(&nodr, &nodl);
 
 		nodl.xoffset += Array_nel-Array_array;
-		nodl.type = types[TUINT32];
+		nodl.type = types[simtype[TUINT]];
 
 		if(nr != N) {
 			nodr.xoffset += Array_nel-Array_array;
@@ -1489,6 +1536,31 @@ componentgen(Node *nr, Node *nl)
 		gmove(&nodr, &nodl);
 
 		goto yes;
+
+	case TSTRUCT:
+		if(nl->op == ONAME)
+			gvardef(nl);
+		loffset = nodl.xoffset;
+		roffset = nodr.xoffset;
+		// funarg structs may not begin at offset zero.
+		if(nl->type->etype == TSTRUCT && nl->type->funarg && nl->type->type)
+			loffset -= nl->type->type->width;
+		if(nr != N && nr->type->etype == TSTRUCT && nr->type->funarg && nr->type->type)
+			roffset -= nr->type->type->width;
+
+		for(t=nl->type->type; t; t=t->down) {
+			nodl.xoffset = loffset + t->width;
+			nodl.type = t->type;
+
+			if(nr == N)
+				clearslim(&nodl);
+			else {
+				nodr.xoffset = roffset + t->width;
+				nodr.type = nodl.type;
+				gmove(&nodr, &nodl);
+			}
+		}
+		goto yes;
 	}
 
 no:
diff --git a/src/cmd/8g/galign.c b/src/cmd/8g/galign.c
index fbd2e9a..a0eb349 100644
--- a/src/cmd/8g/galign.c
+++ b/src/cmd/8g/galign.c
@@ -23,10 +23,10 @@ vlong MAXWIDTH = (1LL<<32) - 1;
  */
 Typedef	typedefs[] =
 {
-	"int",		TINT,		TINT32,
-	"uint",		TUINT,		TUINT32,
-	"uintptr",	TUINTPTR,	TUINT32,
-	0
+	{"int",		TINT,		TINT32},
+	{"uint",		TUINT,		TUINT32},
+	{"uintptr",	TUINTPTR,	TUINT32},
+	{0}
 };
 
 void
diff --git a/src/cmd/8g/gg.h b/src/cmd/8g/gg.h
index bdefa93..238f927 100644
--- a/src/cmd/8g/gg.h
+++ b/src/cmd/8g/gg.h
@@ -114,7 +114,6 @@ void	split64(Node*, Node*, Node*);
 void	splitclean(void);
 void	nswap(Node*, Node*);
 void	gtrack(Sym*);
-void	gargsize(int32);
 /*
  * cplx.c
  */
diff --git a/src/cmd/8g/ggen.c b/src/cmd/8g/ggen.c
index 5e31404..6333a60 100644
--- a/src/cmd/8g/ggen.c
+++ b/src/cmd/8g/ggen.c
@@ -157,7 +157,7 @@ void
 clearfat(Node *nl)
 {
 	uint32 w, c, q;
-	Node n1;
+	Node n1, z;
 	Prog *p;
 
 	/* clear a fat object */
@@ -172,6 +172,32 @@ clearfat(Node *nl)
 	c = w % 4;	// bytes
 	q = w / 4;	// quads
 
+	if(q < 4) {
+		// Write sequence of MOV 0, off(base) instead of using STOSL.
+		// The hope is that although the code will be slightly longer,
+		// the MOVs will have no dependencies and pipeline better
+		// than the unrolled STOSL loop.
+		// NOTE: Must use agen, not igen, so that optimizer sees address
+		// being taken. We are not writing on field boundaries.
+		regalloc(&n1, types[tptr], N);
+		agen(nl, &n1);
+		n1.op = OINDREG;
+		nodconst(&z, types[TUINT64], 0);
+		while(q-- > 0) {
+			n1.type = z.type;
+			gins(AMOVL, &z, &n1);
+			n1.xoffset += 4;
+		}
+		nodconst(&z, types[TUINT8], 0);
+		while(c-- > 0) {
+			n1.type = z.type;
+			gins(AMOVB, &z, &n1);
+			n1.xoffset++;
+		}
+		regfree(&n1);
+		return;
+	}
+
 	nodreg(&n1, types[tptr], D_DI);
 	agen(nl, &n1);
 	gconreg(AMOVL, 0, D_AX);
@@ -184,7 +210,7 @@ clearfat(Node *nl)
 		p = gins(ADUFFZERO, N, N);
 		p->to.type = D_ADDR;
 		p->to.sym = linksym(pkglookup("duffzero", runtimepkg));
-		// 1 and 128 = magic constants: see ../../pkg/runtime/asm_386.s
+		// 1 and 128 = magic constants: see ../../runtime/asm_386.s
 		p->to.offset = 1*(128-q);
 	} else
 	while(q > 0) {
@@ -210,28 +236,12 @@ clearfat(Node *nl)
 void
 ginscall(Node *f, int proc)
 {
-	int32 arg;
 	Prog *p;
 	Node reg, r1, con;
 
 	if(f->type != T)
 		setmaxarg(f->type);
 
-	arg = -1;
-	// Most functions have a fixed-size argument block, so traceback uses that during unwind.
-	// Not all, though: there are some variadic functions in package runtime,
-	// and for those we emit call-specific metadata recorded by caller.
-	// Reflect generates functions with variable argsize (see reflect.methodValueCall/makeFuncStub),
-	// so we do this for all indirect calls as well.
-	if(f->type != T && (f->sym == S || (f->sym != S && f->sym->pkg == runtimepkg) || proc == 1 || proc == 2)) {
-		arg = f->type->argwid;
-		if(proc == 1 || proc == 2)
-			arg += 2*widthptr;
-	}
-
-	if(arg != -1)
-		gargsize(arg);
-
 	switch(proc) {
 	default:
 		fatal("ginscall: bad proc %d", proc);
@@ -293,9 +303,6 @@ ginscall(Node *f, int proc)
 		}
 		break;
 	}
-	
-	if(arg != -1)
-		gargsize(-1);
 }
 
 /*
diff --git a/src/cmd/8g/gsubr.c b/src/cmd/8g/gsubr.c
index 2f3cb28..3077e0a 100644
--- a/src/cmd/8g/gsubr.c
+++ b/src/cmd/8g/gsubr.c
@@ -31,14 +31,15 @@
 #include <u.h>
 #include <libc.h>
 #include "gg.h"
-#include "../../pkg/runtime/funcdata.h"
+#include "../../runtime/funcdata.h"
 
 // TODO(rsc): Can make this bigger if we move
 // the text segment up higher in 8l for all GOOS.
-// At the same time, can raise StackBig in ../../pkg/runtime/stack.h.
+// At the same time, can raise StackBig in ../../runtime/stack.h.
 uint32 unmappedzero = 4096;
 
 #define	CASE(a,b)	(((a)<<16)|((b)<<0))
+/*c2go int CASE(int, int);*/
 
 void
 clearp(Prog *p)
@@ -205,17 +206,7 @@ ggloblnod(Node *nam)
 }
 
 void
-gargsize(int32 size)
-{
-	Node n1, n2;
-	
-	nodconst(&n1, types[TINT32], PCDATA_ArgSize);
-	nodconst(&n2, types[TINT32], size);
-	gins(APCDATA, &n1, &n2);
-}
-
-void
-ggloblsym(Sym *s, int32 width, int dupok, int rodata)
+ggloblsym(Sym *s, int32 width, int8 flags)
 {
 	Prog *p;
 
@@ -226,10 +217,7 @@ ggloblsym(Sym *s, int32 width, int dupok, int rodata)
 	p->to.type = D_CONST;
 	p->to.index = D_NONE;
 	p->to.offset = width;
-	if(dupok)
-		p->from.scale |= DUPOK;
-	if(rodata)
-		p->from.scale |= RODATA;
+	p->from.scale = flags;
 }
 
 void
@@ -432,7 +420,6 @@ optoas(int op, Type *t)
 	case CASE(OADD, TINT32):
 	case CASE(OADD, TUINT32):
 	case CASE(OADD, TPTR32):
-	case CASE(OADDPTR, TPTR32):
 		a = AADDL;
 		break;
 
@@ -697,6 +684,7 @@ optoas(int op, Type *t)
 }
 
 #define FCASE(a, b, c)  (((a)<<16)|((b)<<8)|(c))
+/*c2go int FCASE(int, int, int); */
 int
 foptoas(int op, Type *t, int flg)
 {
@@ -950,7 +938,7 @@ regalloc(Node *n, Type *t, Node *o)
 		fprint(2, "registers allocated at\n");
 		for(i=D_AX; i<=D_DI; i++)
 			fprint(2, "\t%R\t%#lux\n", i, regpc[i]);
-		yyerror("out of fixed registers");
+		fatal("out of fixed registers");
 		goto err;
 
 	case TFLOAT32:
diff --git a/src/cmd/8g/opt.h b/src/cmd/8g/opt.h
index 77a69e1..09f58c4 100644
--- a/src/cmd/8g/opt.h
+++ b/src/cmd/8g/opt.h
@@ -49,6 +49,24 @@
 typedef	struct	Reg	Reg;
 typedef	struct	Rgn	Rgn;
 
+/*c2go
+extern Node *Z;
+enum
+{
+	D_HI = D_NONE,
+	D_LO = D_NONE,
+	CLOAD = 5,
+	CREF = 5,
+	CINF = 1000,
+	LOOP = 3,
+};
+
+uint32 BLOAD(Reg*);
+uint32 BSTORE(Reg*);
+uint32 LOAD(Reg*);
+uint32 STORE(Reg*);
+*/
+
 // A Reg is a wrapper around a single Prog (one instruction) that holds
 // register optimization information while the optimizer runs.
 // r->prog is the instruction.
@@ -84,8 +102,10 @@ struct	Reg
 	Prog*	prog;   	// actual instruction
 };
 #define	R	((Reg*)0)
+/*c2go extern Reg *R; */
 
 #define	NRGN	600
+/*c2go enum { NRGN = 600 }; */
 struct	Rgn
 {
 	Reg*	enter;
diff --git a/src/cmd/8g/peep.c b/src/cmd/8g/peep.c
index e2f3a00..91a91d2 100644
--- a/src/cmd/8g/peep.c
+++ b/src/cmd/8g/peep.c
@@ -33,7 +33,9 @@
 #include "gg.h"
 #include "opt.h"
 
-#define	REGEXT	0
+enum {
+	REGEXT = 0,
+};
 
 static void	conprop(Flow *r);
 static void	elimshortmov(Graph*);
diff --git a/src/cmd/8g/reg.c b/src/cmd/8g/reg.c
index fd610f8..302b273 100644
--- a/src/cmd/8g/reg.c
+++ b/src/cmd/8g/reg.c
@@ -35,6 +35,11 @@
 
 #define	NREGVAR	16	/* 8 integer + 8 floating */
 #define	REGBITS	((uint32)0xffff)
+/*c2go enum {
+	NREGVAR = 16,
+	REGBITS = (1<<NREGVAR) - 1,
+};
+*/
 
 static	Reg*	firstr;
 static	int	first	= 1;
@@ -1163,6 +1168,7 @@ void
 addreg(Adr *a, int rn)
 {
 	a->sym = nil;
+	a->node = nil;
 	a->offset = 0;
 	a->type = rn;
 
diff --git a/src/cmd/8l/8.out.h b/src/cmd/8l/8.out.h
index 8e642d3..ed54f67 100644
--- a/src/cmd/8l/8.out.h
+++ b/src/cmd/8l/8.out.h
@@ -32,7 +32,7 @@
 #define	NSNAME	8
 #include "../ld/textflag.h"
 
-enum	as
+enum
 {
 	AXXX,
 	AAAA,
diff --git a/src/cmd/8l/asm.c b/src/cmd/8l/asm.c
index c135dce..98c0424 100644
--- a/src/cmd/8l/asm.c
+++ b/src/cmd/8l/asm.c
@@ -117,13 +117,21 @@ adddynrel(LSym *s, Reloc *r)
 	case 256 + R_386_GOT32:
 		if(targ->type != SDYNIMPORT) {
 			// have symbol
-			// turn MOVL of GOT entry into LEAL of symbol itself
-			if(r->off < 2 || s->p[r->off-2] != 0x8b) {
-				diag("unexpected GOT reloc for non-dynamic symbol %s", targ->name);
+			if(r->off >= 2 && s->p[r->off-2] == 0x8b) {
+				// turn MOVL of GOT entry into LEAL of symbol address, relative to GOT.
+				s->p[r->off-2] = 0x8d;
+				r->type = R_GOTOFF;
 				return;
 			}
-			s->p[r->off-2] = 0x8d;
-			r->type = R_GOTOFF;
+			if(r->off >= 2 && s->p[r->off-2] == 0xff && s->p[r->off-1] == 0xb3) {
+				// turn PUSHL of GOT entry into PUSHL of symbol itself.
+				// use unnecessary SS prefix to keep instruction same length.
+				s->p[r->off-2] = 0x36;
+				s->p[r->off-1] = 0x68;
+				r->type = R_ADDR;
+				return;
+			}
+			diag("unexpected GOT reloc for non-dynamic symbol %s", targ->name);
 			return;
 		}
 		addgotsym(ctxt, targ);
diff --git a/src/cmd/8l/l.h b/src/cmd/8l/l.h
index c9695ad..70d3a4b 100644
--- a/src/cmd/8l/l.h
+++ b/src/cmd/8l/l.h
@@ -50,15 +50,10 @@ enum
 
 #define	P		((Prog*)0)
 #define	S		((LSym*)0)
-#define	TNAME		(ctxt->cursym?ctxt->cursym->name:noname)
 
 enum
 {
-	MINSIZ		= 4,
-	STRINGSZ	= 200,
 	MINLC		= 1,
-	MAXIO		= 8192,
-	MAXHIST		= 40,				/* limit of path elements for history symbols */
 };
 
 #pragma	varargck	type	"I"	uchar*
@@ -72,7 +67,6 @@ EXTERN	char*	rpath;
 EXTERN	int32	spsize;
 EXTERN	LSym*	symlist;
 EXTERN	int32	symsize;
-EXTERN	int32	textsize;
 
 int	Iconv(Fmt *fp);
 void	adddynlib(char *lib);
@@ -85,7 +79,6 @@ int	elfreloc1(Reloc *r, vlong sectoff);
 void	elfsetupplt(void);
 void	listinit(void);
 int	machoreloc1(Reloc *r, vlong sectoff);
-void	main(int argc, char *argv[]);
 int32	rnd(int32 v, int32 r);
 void	s8put(char *n);
 char*	xsymname(LSym *s);
diff --git a/src/cmd/8l/mkenam b/src/cmd/8l/mkenam
deleted file mode 100644
index 992aa31..0000000
--- a/src/cmd/8l/mkenam
+++ /dev/null
@@ -1,45 +0,0 @@
-# Inferno utils/8c/mkenam
-# http://code.google.com/p/inferno-os/source/browse/utils/8c/mkenam
-#
-#	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-#	Portions Copyright © 1995-1997 C H Forsyth (forsyth at terzarima.net)
-#	Portions Copyright © 1997-1999 Vita Nuova Limited
-#	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-#	Portions Copyright © 2004,2006 Bruce Ellis
-#	Portions Copyright © 2005-2007 C H Forsyth (forsyth at terzarima.net)
-#	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-#	Portions Copyright © 2009 The Go Authors.  All rights reserved.
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-# THE SOFTWARE.
-
-awk '
-BEGIN {
-	print "char*	anames[] ="
-	print "{"
-}
-
-/^	A/ {
-	name=$1
-	sub(/,/, "", name)
-	sub(/^A/, "", name)
-	print "\t\"" name "\","
-}
-
-END { print "};" }
-' ../8l/8.out.h >enam.c
diff --git a/src/cmd/addr2line/addr2line_test.go b/src/cmd/addr2line/addr2line_test.go
index b278d08..10d1dc9 100644
--- a/src/cmd/addr2line/addr2line_test.go
+++ b/src/cmd/addr2line/addr2line_test.go
@@ -92,8 +92,9 @@ func testAddr2Line(t *testing.T, exepath, addr string) {
 
 // This is line 93. The test depends on that.
 func TestAddr2Line(t *testing.T) {
-	if runtime.GOOS == "nacl" {
-		t.Skip("skipping on nacl")
+	switch runtime.GOOS {
+	case "nacl", "android":
+		t.Skipf("skipping on %s", runtime.GOOS)
 	}
 
 	syms := loadSyms(t)
diff --git a/src/cmd/addr2line/main.go b/src/cmd/addr2line/main.go
index b94ba12..267f417 100644
--- a/src/cmd/addr2line/main.go
+++ b/src/cmd/addr2line/main.go
@@ -19,17 +19,14 @@ package main
 
 import (
 	"bufio"
-	"debug/elf"
-	"debug/gosym"
-	"debug/macho"
-	"debug/pe"
-	"debug/plan9obj"
 	"flag"
 	"fmt"
 	"log"
 	"os"
 	"strconv"
 	"strings"
+
+	"cmd/internal/objfile"
 )
 
 func printUsage(w *os.File) {
@@ -60,18 +57,12 @@ func main() {
 		usage()
 	}
 
-	f, err := os.Open(flag.Arg(0))
+	f, err := objfile.Open(flag.Arg(0))
 	if err != nil {
 		log.Fatal(err)
 	}
 
-	textStart, symtab, pclntab, err := loadTables(f)
-	if err != nil {
-		log.Fatalf("reading %s: %v", flag.Arg(0), err)
-	}
-
-	pcln := gosym.NewLineTable(pclntab, textStart)
-	tab, err := gosym.NewTable(symtab, pcln)
+	tab, err := f.PCLineTable()
 	if err != nil {
 		log.Fatalf("reading %s: %v", flag.Arg(0), err)
 	}
@@ -102,152 +93,3 @@ func main() {
 	}
 	stdout.Flush()
 }
-
-func loadTables(f *os.File) (textStart uint64, symtab, pclntab []byte, err error) {
-	if obj, err := elf.NewFile(f); err == nil {
-		if sect := obj.Section(".text"); sect != nil {
-			textStart = sect.Addr
-		}
-		if sect := obj.Section(".gosymtab"); sect != nil {
-			if symtab, err = sect.Data(); err != nil {
-				return 0, nil, nil, err
-			}
-		}
-		if sect := obj.Section(".gopclntab"); sect != nil {
-			if pclntab, err = sect.Data(); err != nil {
-				return 0, nil, nil, err
-			}
-		}
-		return textStart, symtab, pclntab, nil
-	}
-
-	if obj, err := macho.NewFile(f); err == nil {
-		if sect := obj.Section("__text"); sect != nil {
-			textStart = sect.Addr
-		}
-		if sect := obj.Section("__gosymtab"); sect != nil {
-			if symtab, err = sect.Data(); err != nil {
-				return 0, nil, nil, err
-			}
-		}
-		if sect := obj.Section("__gopclntab"); sect != nil {
-			if pclntab, err = sect.Data(); err != nil {
-				return 0, nil, nil, err
-			}
-		}
-		return textStart, symtab, pclntab, nil
-	}
-
-	if obj, err := pe.NewFile(f); err == nil {
-		var imageBase uint64
-		switch oh := obj.OptionalHeader.(type) {
-		case *pe.OptionalHeader32:
-			imageBase = uint64(oh.ImageBase)
-		case *pe.OptionalHeader64:
-			imageBase = oh.ImageBase
-		default:
-			return 0, nil, nil, fmt.Errorf("pe file format not recognized")
-		}
-		if sect := obj.Section(".text"); sect != nil {
-			textStart = imageBase + uint64(sect.VirtualAddress)
-		}
-		if pclntab, err = loadPETable(obj, "pclntab", "epclntab"); err != nil {
-			return 0, nil, nil, err
-		}
-		if symtab, err = loadPETable(obj, "symtab", "esymtab"); err != nil {
-			return 0, nil, nil, err
-		}
-		return textStart, symtab, pclntab, nil
-	}
-
-	if obj, err := plan9obj.NewFile(f); err == nil {
-		sym, err := findPlan9Symbol(obj, "text")
-		if err != nil {
-			return 0, nil, nil, err
-		}
-		textStart = sym.Value
-		if pclntab, err = loadPlan9Table(obj, "pclntab", "epclntab"); err != nil {
-			return 0, nil, nil, err
-		}
-		if symtab, err = loadPlan9Table(obj, "symtab", "esymtab"); err != nil {
-			return 0, nil, nil, err
-		}
-		return textStart, symtab, pclntab, nil
-	}
-
-	return 0, nil, nil, fmt.Errorf("unrecognized binary format")
-}
-
-func findPESymbol(f *pe.File, name string) (*pe.Symbol, error) {
-	for _, s := range f.Symbols {
-		if s.Name != name {
-			continue
-		}
-		if s.SectionNumber <= 0 {
-			return nil, fmt.Errorf("symbol %s: invalid section number %d", name, s.SectionNumber)
-		}
-		if len(f.Sections) < int(s.SectionNumber) {
-			return nil, fmt.Errorf("symbol %s: section number %d is larger than max %d", name, s.SectionNumber, len(f.Sections))
-		}
-		return s, nil
-	}
-	return nil, fmt.Errorf("no %s symbol found", name)
-}
-
-func loadPETable(f *pe.File, sname, ename string) ([]byte, error) {
-	ssym, err := findPESymbol(f, sname)
-	if err != nil {
-		return nil, err
-	}
-	esym, err := findPESymbol(f, ename)
-	if err != nil {
-		return nil, err
-	}
-	if ssym.SectionNumber != esym.SectionNumber {
-		return nil, fmt.Errorf("%s and %s symbols must be in the same section", sname, ename)
-	}
-	sect := f.Sections[ssym.SectionNumber-1]
-	data, err := sect.Data()
-	if err != nil {
-		return nil, err
-	}
-	return data[ssym.Value:esym.Value], nil
-}
-
-func findPlan9Symbol(f *plan9obj.File, name string) (*plan9obj.Sym, error) {
-	syms, err := f.Symbols()
-	if err != nil {
-		return nil, err
-	}
-	for _, s := range syms {
-		if s.Name != name {
-			continue
-		}
-		return &s, nil
-	}
-	return nil, fmt.Errorf("no %s symbol found", name)
-}
-
-func loadPlan9Table(f *plan9obj.File, sname, ename string) ([]byte, error) {
-	ssym, err := findPlan9Symbol(f, sname)
-	if err != nil {
-		return nil, err
-	}
-	esym, err := findPlan9Symbol(f, ename)
-	if err != nil {
-		return nil, err
-	}
-	text, err := findPlan9Symbol(f, "text")
-	if err != nil {
-		return nil, err
-	}
-	sect := f.Section("text")
-	if sect == nil {
-		return nil, err
-	}
-	data, err := sect.Data()
-	if err != nil {
-		return nil, err
-	}
-	return data[ssym.Value-text.Value : esym.Value-text.Value], nil
-}
diff --git a/src/cmd/api/goapi.go b/src/cmd/api/goapi.go
index 4bde794..4a63eac 100644
--- a/src/cmd/api/goapi.go
+++ b/src/cmd/api/goapi.go
@@ -107,6 +107,8 @@ func setContexts() {
 	}
 }
 
+var internalPkg = regexp.MustCompile(`(^|/)internal($|/)`)
+
 func main() {
 	flag.Parse()
 
@@ -132,12 +134,16 @@ func main() {
 		if err != nil {
 			log.Fatal(err)
 		}
-		pkgNames = strings.Fields(string(stds))
+		for _, pkg := range strings.Fields(string(stds)) {
+			if !internalPkg.MatchString(pkg) {
+				pkgNames = append(pkgNames, pkg)
+			}
+		}
 	}
 
 	var featureCtx = make(map[string]map[string]bool) // feature -> context name -> true
 	for _, context := range contexts {
-		w := NewWalker(context, filepath.Join(build.Default.GOROOT, "src/pkg"))
+		w := NewWalker(context, filepath.Join(build.Default.GOROOT, "src"))
 
 		for _, name := range pkgNames {
 			// - Package "unsafe" contains special signatures requiring
@@ -277,7 +283,7 @@ func compareAPI(w io.Writer, features, required, optional, exception []string) (
 				delete(optionalSet, newFeature)
 			} else {
 				fmt.Fprintf(w, "+%s\n", newFeature)
-				if !*allowNew {
+				if !*allowNew || !strings.Contains(runtime.Version(), "devel") {
 					ok = false // we're in lock-down mode for next release
 				}
 			}
@@ -307,11 +313,15 @@ func fileFeatures(filename string) []string {
 	if err != nil {
 		log.Fatalf("Error reading file %s: %v", filename, err)
 	}
-	text := strings.TrimSpace(string(bs))
-	if text == "" {
-		return nil
+	lines := strings.Split(string(bs), "\n")
+	var nonblank []string
+	for _, line := range lines {
+		line = strings.TrimSpace(line)
+		if line != "" && !strings.HasPrefix(line, "#") {
+			nonblank = append(nonblank, line)
+		}
 	}
-	return strings.Split(text, "\n")
+	return nonblank
 }
 
 var fset = token.NewFileSet()
@@ -370,6 +380,106 @@ func (w *Walker) parseFile(dir, file string) (*ast.File, error) {
 			log.Fatalf("incorrect generated file: %s", err)
 		}
 	}
+	if w.context != nil && file == fmt.Sprintf("zruntime_defs_%s_%s.go", w.context.GOOS, w.context.GOARCH) {
+		// Just enough to keep the api checker happy. Keep sorted.
+		src := "package runtime; type (" +
+			" _defer struct{};" +
+			" _func struct{};" +
+			" _panic struct{};" +
+			" _select struct{}; " +
+			" _type struct{};" +
+			" alg struct{};" +
+			" chantype struct{};" +
+			" context struct{};" + // windows
+			" eface struct{};" +
+			" epollevent struct{};" +
+			" funcval struct{};" +
+			" g struct{};" +
+			" gobuf struct{};" +
+			" hchan struct{};" +
+			" iface struct{};" +
+			" interfacetype struct{};" +
+			" itab struct{};" +
+			" keventt struct{};" +
+			" m struct{};" +
+			" maptype struct{};" +
+			" mcache struct{};" +
+			" mspan struct{};" +
+			" mutex struct{};" +
+			" note struct{};" +
+			" p struct{};" +
+			" parfor struct{};" +
+			" slicetype struct{};" +
+			" stkframe struct{};" +
+			" sudog struct{};" +
+			" timespec struct{};" +
+			" waitq struct{};" +
+			" wincallbackcontext struct{};" +
+			"); " +
+			"const (" +
+			" cb_max = 2000;" +
+			" _CacheLineSize = 64;" +
+			" _Gidle = 1;" +
+			" _Grunnable = 2;" +
+			" _Grunning = 3;" +
+			" _Gsyscall = 4;" +
+			" _Gwaiting = 5;" +
+			" _Gdead = 6;" +
+			" _Genqueue = 7;" +
+			" _Gcopystack = 8;" +
+			" _NSIG = 32;" +
+			" _FlagNoScan = iota;" +
+			" _FlagNoZero;" +
+			" _TinySize;" +
+			" _TinySizeClass;" +
+			" _MaxSmallSize;" +
+			" _PageShift;" +
+			" _PageSize;" +
+			" _PageMask;" +
+			" _BitsPerPointer;" +
+			" _BitsMask;" +
+			" _PointersPerByte;" +
+			" _MaxGCMask;" +
+			" _BitsDead;" +
+			" _BitsPointer;" +
+			" _MSpanInUse;" +
+			" _ConcurrentSweep;" +
+			" _KindBool;" +
+			" _KindInt;" +
+			" _KindInt8;" +
+			" _KindInt16;" +
+			" _KindInt32;" +
+			" _KindInt64;" +
+			" _KindUint;" +
+			" _KindUint8;" +
+			" _KindUint16;" +
+			" _KindUint32;" +
+			" _KindUint64;" +
+			" _KindUintptr;" +
+			" _KindFloat32;" +
+			" _KindFloat64;" +
+			" _KindComplex64;" +
+			" _KindComplex128;" +
+			" _KindArray;" +
+			" _KindChan;" +
+			" _KindFunc;" +
+			" _KindInterface;" +
+			" _KindMap;" +
+			" _KindPtr;" +
+			" _KindSlice;" +
+			" _KindString;" +
+			" _KindStruct;" +
+			" _KindUnsafePointer;" +
+			" _KindDirectIface;" +
+			" _KindGCProg;" +
+			" _KindNoPointers;" +
+			" _KindMask;" +
+			")"
+		f, err = parser.ParseFile(fset, filename, src, 0)
+		if err != nil {
+			log.Fatalf("incorrect generated file: %s", err)
+		}
+	}
 
 	if f == nil {
 		f, err = parser.ParseFile(fset, filename, nil, 0)
@@ -391,6 +501,11 @@ func contains(list []string, s string) bool {
 	return false
 }
 
+// The package cache doesn't operate correctly in rare (so far artificial)
+// circumstances (issue 8425). Disable before debugging non-obvious errors
+// from the type-checker.
+const usePkgCache = true
+
 var (
 	pkgCache = map[string]*types.Package{} // map tagKey to package
 	pkgTags  = map[string][]string{}       // map import dir to list of relevant tags
@@ -452,11 +567,13 @@ func (w *Walker) Import(name string) (pkg *types.Package) {
 	// If we've already done an import with the same set
 	// of relevant tags, reuse the result.
 	var key string
-	if tags, ok := pkgTags[dir]; ok {
-		key = tagKey(dir, context, tags)
-		if pkg := pkgCache[key]; pkg != nil {
-			w.imported[name] = pkg
-			return pkg
+	if usePkgCache {
+		if tags, ok := pkgTags[dir]; ok {
+			key = tagKey(dir, context, tags)
+			if pkg := pkgCache[key]; pkg != nil {
+				w.imported[name] = pkg
+				return pkg
+			}
 		}
 	}
 
@@ -469,9 +586,11 @@ func (w *Walker) Import(name string) (pkg *types.Package) {
 	}
 
 	// Save tags list first time we see a directory.
-	if _, ok := pkgTags[dir]; !ok {
-		pkgTags[dir] = info.AllTags
-		key = tagKey(dir, context, info.AllTags)
+	if usePkgCache {
+		if _, ok := pkgTags[dir]; !ok {
+			pkgTags[dir] = info.AllTags
+			key = tagKey(dir, context, info.AllTags)
+		}
 	}
 
 	filenames := append(append([]string{}, info.GoFiles...), info.CgoFiles...)
@@ -488,6 +607,11 @@ func (w *Walker) Import(name string) (pkg *types.Package) {
 		if !contains(filenames, n) {
 			filenames = append(filenames, n)
 		}
+
+		n = fmt.Sprintf("zruntime_defs_%s_%s.go", w.context.GOOS, w.context.GOARCH)
+		if !contains(filenames, n) {
+			filenames = append(filenames, n)
+		}
 	}
 
 	// Parse package files.
@@ -519,7 +643,9 @@ func (w *Walker) Import(name string) (pkg *types.Package) {
 		log.Fatalf("error typechecking package %s: %s (%s)", name, err, ctxt)
 	}
 
-	pkgCache[key] = pkg
+	if usePkgCache {
+		pkgCache[key] = pkg
+	}
 
 	w.imported[name] = pkg
 	return
diff --git a/src/cmd/api/goapi_test.go b/src/cmd/api/goapi_test.go
index b909c32..f4fb7d3 100644
--- a/src/cmd/api/goapi_test.go
+++ b/src/cmd/api/goapi_test.go
@@ -38,7 +38,7 @@ func TestGolden(t *testing.T) {
 			continue
 		}
 
-		goldenFile := filepath.Join("testdata", "src", "pkg", fi.Name(), "golden.txt")
+		goldenFile := filepath.Join("testdata", "src", fi.Name(), "golden.txt")
 		w := NewWalker(nil, "testdata/src/pkg")
 		w.export(w.Import(fi.Name()))
 
@@ -142,6 +142,26 @@ func TestCompareAPI(t *testing.T) {
 	}
 }
 
+func TestSkipInternal(t *testing.T) {
+	tests := []struct {
+		pkg  string
+		want bool
+	}{
+		{"net/http", true},
+		{"net/http/internal-foo", true},
+		{"net/http/internal", false},
+		{"net/http/internal/bar", false},
+		{"internal/foo", false},
+		{"internal", false},
+	}
+	for _, tt := range tests {
+		got := !internalPkg.MatchString(tt.pkg)
+		if got != tt.want {
+			t.Errorf("%s is internal = %v; want %v", tt.pkg, got, tt.want)
+		}
+	}
+}
+
 func BenchmarkAll(b *testing.B) {
 	stds, err := exec.Command("go", "list", "std").Output()
 	if err != nil {
@@ -156,7 +176,7 @@ func BenchmarkAll(b *testing.B) {
 
 	for i := 0; i < b.N; i++ {
 		for _, context := range contexts {
-			w := NewWalker(context, filepath.Join(build.Default.GOROOT, "src/pkg"))
+			w := NewWalker(context, filepath.Join(build.Default.GOROOT, "src"))
 			for _, name := range pkgNames {
 				if name != "unsafe" && !strings.HasPrefix(name, "cmd/") {
 					w.export(w.Import(name))
diff --git a/src/cmd/api/run.go b/src/cmd/api/run.go
index 896b2b4..ed5613e 100644
--- a/src/cmd/api/run.go
+++ b/src/cmd/api/run.go
@@ -21,6 +21,7 @@ import (
 	"os/exec"
 	"os/user"
 	"path/filepath"
+	"runtime"
 	"strings"
 )
 
@@ -53,7 +54,7 @@ func main() {
 	}
 
 	out, err = exec.Command("go", "tool", "api",
-		"-c", file("go1", "go1.1", "go1.2", "go1.3"),
+		"-c", file("go1", "go1.1", "go1.2", "go1.3", "go1.4"),
 		"-next", file("next"),
 		"-except", file("except")).CombinedOutput()
 	if err != nil {
@@ -98,16 +99,14 @@ func prepGoPath() string {
 	if err == nil {
 		username = u.Username
 	} else {
-		// Only need to handle Unix here, as Windows's os/user uses
-		// native syscall and should work fine without cgo.
 		username = os.Getenv("USER")
 		if username == "" {
-			log.Fatalf("Error getting current user: %v", err)
+			username = "nobody"
 		}
 	}
 
 	// The GOPATH we'll return
-	gopath := filepath.Join(os.TempDir(), "gopath-api-"+cleanUsername(username), goToolsVersion)
+	gopath := filepath.Join(os.TempDir(), "gopath-api-"+cleanUsername(username)+"-"+cleanUsername(strings.Fields(runtime.Version())[0]), goToolsVersion)
 
 	// cloneDir is where we run "hg clone".
 	cloneDir := filepath.Join(gopath, "src", "code.google.com", "p")
diff --git a/src/cmd/cc/bv.c b/src/cmd/cc/bv.c
deleted file mode 100644
index 51b7f40..0000000
--- a/src/cmd/cc/bv.c
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include <u.h>
-#include "cc.h"
-
-enum {
-	WORDSIZE = sizeof(uint32),
-	WORDBITS = 32,
-};
-
-uintptr
-bvsize(uintptr n)
-{
-	return ((n + WORDBITS - 1) / WORDBITS) * WORDSIZE;
-}
-
-Bvec*
-bvalloc(int32 n)
-{
-	Bvec *bv;
-	uintptr nbytes;
-
-	if(n < 0)
-		fatal(Z, "bvalloc: initial size is negative\n");
-	nbytes = sizeof(Bvec) + bvsize(n);
-	bv = malloc(nbytes);
-	if(bv == nil)
-		fatal(Z, "bvalloc: malloc failed\n");
-	memset(bv, 0, nbytes);
-	bv->n = n;
-	return bv;
-}
-
-void
-bvset(Bvec *bv, int32 i)
-{
-	uint32 mask;
-
-	if(i < 0 || i >= bv->n)
-		fatal(Z, "bvset: index %d is out of bounds with length %d\n", i, bv->n);
-	mask = 1 << (i % WORDBITS);
-	bv->b[i / WORDBITS] |= mask;
-}
diff --git a/src/cmd/cc/cc.h b/src/cmd/cc/cc.h
index c8aac12..9530f5c 100644
--- a/src/cmd/cc/cc.h
+++ b/src/cmd/cc/cc.h
@@ -762,12 +762,6 @@ int	beq(Bits, Bits);
 int	bset(Bits, uint);
 
 /*
- *	bv.c
- */
-Bvec*	bvalloc(int32 n);
-void	bvset(Bvec *bv, int32 i);
-
-/*
  * dpchk.c
  */
 void	dpcheck(Node*);
@@ -794,7 +788,7 @@ void	xcom(Node*);
 int32	exreg(Type*);
 int32	align(int32, Type*, int, int32*);
 int32	maxround(int32, int32);
-int	hasdotdotdot(void);
+int	hasdotdotdot(Type*);
 void    linkarchinit(void);
 
 extern	schar	ewidth[];
diff --git a/src/cmd/cc/cc.y b/src/cmd/cc/cc.y
index 11ee444..8d7cb14 100644
--- a/src/cmd/cc/cc.y
+++ b/src/cmd/cc/cc.y
@@ -1043,6 +1043,7 @@ complex:
 	}
 |	LSTRUCT sbody
 	{
+		diag(Z, "struct must have tag");
 		taggen++;
 		sprint(symb, "_%d_", taggen);
 		$$ = dotag(lookup(), TSTRUCT, autobn);
diff --git a/src/cmd/cc/dcl.c b/src/cmd/cc/dcl.c
index a7a9426..117508f 100644
--- a/src/cmd/cc/dcl.c
+++ b/src/cmd/cc/dcl.c
@@ -30,6 +30,9 @@
 
 #include <u.h>
 #include "cc.h"
+#include "../ld/textflag.h"
+
+static int haspointers(Type*);
 
 Node*
 dodecl(void (*f)(int,Type*,Sym*), int c, Type *t, Node *n)
@@ -123,7 +126,8 @@ loop:
 		if(dataflag) {
 			s->dataflag = dataflag;
 			dataflag = 0;
-		}
+		} else if(s->type != T && !haspointers(s->type))
+			s->dataflag = NOPTR;
 		firstbit = 0;
 		n->sym = s;
 		n->type = s->type;
@@ -568,9 +572,8 @@ haspointers(Type *t)
 		return 0;
 	case TARRAY:
 		return haspointers(t->link);
-	case TFUNC:
 	case TIND:
-		return 1;
+		return t->link->etype != TFUNC;
 	default:
 		return 0;
 	}
@@ -697,7 +700,8 @@ argmark(Node *n, int pass)
 {
 	Type *t;
 
-	autoffset = align(0, thisfn->link, Aarg0, nil);
+	if(hasdotdotdot(thisfn->link))
+		autoffset = align(0, thisfn->link, Aarg0, nil);
 	stkoff = 0;
 	for(; n->left != Z; n = n->left) {
 		if(n->op != OFUNC || n->left->op != ONAME)
@@ -1401,6 +1405,10 @@ xdecl(int c, Type *t, Sym *s)
 		}
 	tmerge(t, s);
 	s->type = t;
+	if(c == CTYPEDEF && (typechlv[t->etype] || typefd[t->etype])) {
+		s->type = copytyp(t);
+		s->type->tag = s;
+	}
 	s->class = c;
 	s->block = 0;
 	s->offset = o;
@@ -1481,12 +1489,9 @@ edecl(int c, Type *t, Sym *s)
 {
 	Type *t1;
 
-	if(s == S) {
-		if(!typesu[t->etype])
-			diag(Z, "unnamed structure element must be struct/union");
-		if(c != CXXX)
-			diag(Z, "unnamed structure element cannot have class");
-	} else
+	if(s == S)
+		diag(Z, "unnamed structure elements not supported");
+	else
 		if(c != CXXX)
 			diag(Z, "structure element cannot have class: %s", s->name);
 	t1 = t;
diff --git a/src/cmd/cc/godefs.c b/src/cmd/cc/godefs.c
index 7457bd0..d9f67f0 100644
--- a/src/cmd/cc/godefs.c
+++ b/src/cmd/cc/godefs.c
@@ -154,7 +154,6 @@ static void
 printtypename(Type *t)
 {
 	Sym *s;
-	Type *t1;
 	int w;
 	char *n;
 
@@ -188,40 +187,27 @@ printtypename(Type *t)
 
 	switch(t->etype) {
 	case TINT:
-		Bprint(&outbuf, "int32");
-		break;
 	case TUINT:
-		Bprint(&outbuf, "uint32");
-		break;
 	case TCHAR:
-		Bprint(&outbuf, "int8");
-		break;
 	case TUCHAR:
-		Bprint(&outbuf, "uint8");
-		break;
 	case TSHORT:
-		Bprint(&outbuf, "int16");
-		break;
 	case TUSHORT:
-		Bprint(&outbuf, "uint16");
-		break;
 	case TLONG:
-		Bprint(&outbuf, "int32");
-		break;
 	case TULONG:
-		Bprint(&outbuf, "uint32");
-		break;
 	case TVLONG:
-		Bprint(&outbuf, "int64");
-		break;
 	case TUVLONG:
-		Bprint(&outbuf, "uint64");
-		break;
 	case TFLOAT:
-		Bprint(&outbuf, "float32");
-		break;
 	case TDOUBLE:
-		Bprint(&outbuf, "float64");
+		// All names used in the runtime code should be typedefs.
+		if(t->tag != nil) {
+			if(strcmp(t->tag->name, "intgo") == 0)
+				Bprint(&outbuf, "int");
+			else if(strcmp(t->tag->name, "uintgo") == 0)
+				Bprint(&outbuf, "uint");
+			else
+				Bprint(&outbuf, "%s", t->tag->name);
+		} else	
+			Bprint(&outbuf, "C.%T", t);
 		break;
 	case TUNION:
 	case TSTRUCT:
@@ -231,27 +217,18 @@ printtypename(Type *t)
 			n = s->name;
 		else if(t->tag)
 			n = t->tag->name;
-		if(strcmp(n, "String") == 0){
+		if(strcmp(n, "String") == 0)
 			Bprint(&outbuf, "string");
-		} else if(strcmp(n, "Slice") == 0){
+		else if(strcmp(n, "Slice") == 0)
 			Bprint(&outbuf, "[]byte");
-		} else
+		else if(strcmp(n, "Eface") == 0)
+			Bprint(&outbuf, "interface{}");
+		else
 			Bprint(&outbuf, "%U", n);
 		break;
 	case TFUNC:
-		Bprint(&outbuf, "func(");
-		for(t1 = t->down; t1 != T; t1 = t1->down) {
-			if(t1->etype == TVOID)
-				break;
-			if(t1 != t->down)
-				Bprint(&outbuf, ", ");
-			printtypename(t1);
-		}
-		Bprint(&outbuf, ")");
-		if(t->link && t->link->etype != TVOID) {
-			Bprint(&outbuf, " ");
-			printtypename(t->link);
-		}
+		// There's no equivalent to a C function in the Go world.
+		Bprint(&outbuf, "unsafe.Pointer");
 		break;
 	case TDOT:
 		Bprint(&outbuf, "...interface{}");
@@ -340,9 +317,9 @@ godefvar(Sym *s)
 	switch(t->etype) {
 	case TENUM:
 		if(!typefd[t->etype])
-			Bprint(&outbuf, "const %U = %lld\n", s->name, s->vconst);
+			Bprint(&outbuf, "const %s = %lld\n", s->name, s->vconst);
 		else
-			Bprint(&outbuf, "const %U = %f\n;", s->name, s->fconst);
+			Bprint(&outbuf, "const %s = %f\n;", s->name, s->fconst);
 		break;
 
 	case TFUNC:
@@ -376,8 +353,10 @@ godefvar(Sym *s)
 		case CSTATIC:
 		case CEXTERN:
 		case CGLOBL:
-			if(strchr(s->name, '$') != nil)	 // TODO(lvd)
-			    break;
+			if(strchr(s->name, '$') != nil)
+				break;
+			if(strncmp(s->name, "go.weak.", 8) == 0)
+				break;
 			Bprint(&outbuf, "var %U\t", s->name);
 			printtypename(t);
 			Bprint(&outbuf, "\n");
diff --git a/src/cmd/cc/lex.c b/src/cmd/cc/lex.c
index 4248437..7c9f718 100644
--- a/src/cmd/cc/lex.c
+++ b/src/cmd/cc/lex.c
@@ -31,6 +31,7 @@
 #include	<u.h>
 #include	"cc.h"
 #include	"y.tab.h"
+#include	"../ld/textflag.h"
 
 #ifndef	CPP
 #define	CPP	"cpp"
@@ -203,6 +204,7 @@ main(int argc, char *argv[])
 	
 	flagparse(&argc, &argv, usage);
 	ctxt->debugasm = debug['S'];
+	ctxt->debugvlog = debug['v'];
 
 	if(argc < 1 && outfile == 0)
 		usage();
@@ -1316,6 +1318,7 @@ cinit(void)
 	t->width = 0;
 	symstring = slookup(".string");
 	symstring->class = CSTATIC;
+	symstring->dataflag = NOPTR;
 	symstring->type = t;
 
 	t = typ(TARRAY, types[TCHAR]);
diff --git a/src/cmd/cc/pgen.c b/src/cmd/cc/pgen.c
index 10bebc1..db9aae9 100644
--- a/src/cmd/cc/pgen.c
+++ b/src/cmd/cc/pgen.c
@@ -29,51 +29,27 @@
 // THE SOFTWARE.
 
 #include "gc.h"
-#include "../../pkg/runtime/funcdata.h"
-
-enum { BitsPerPointer = 2 };
-
-static void dumpgcargs(Type *fn, Sym *sym);
-
-static Sym*
-makefuncdatasym(char *namefmt, int64 funcdatakind)
-{
-	Node nod;
-	Sym *sym;
-	static int32 nsym;
-	static char namebuf[40];
-
-	snprint(namebuf, sizeof(namebuf), namefmt, nsym++);
-	sym = slookup(namebuf);
-	sym->class = CSTATIC;
-	memset(&nod, 0, sizeof nod);
-	nod.op = ONAME;
-	nod.sym = sym;
-	nod.class = CSTATIC;
-	gins(AFUNCDATA, nodconst(funcdatakind), &nod);
-	linksym(sym)->type = SRODATA;
-	return sym;
-}
+#include "../../runtime/funcdata.h"
 
 int
-hasdotdotdot(void)
+hasdotdotdot(Type *t)
 {
-	Type *t;
-
-	for(t=thisfn->down; t!=T; t=t->down)
+	for(t=t->down; t!=T; t=t->down)
 		if(t->etype == TDOT)
 			return 1;
 	return 0;
 }
 
 vlong
-argsize(void)
+argsize(int doret)
 {
 	Type *t;
 	int32 s;
 
 //print("t=%T\n", thisfn);
-	s = align(0, thisfn->link, Aarg0, nil);
+	s = 0;
+	if(hasdotdotdot(thisfn))
+		s = align(s, thisfn->link, Aarg0, nil);
 	for(t=thisfn->down; t!=T; t=t->down) {
 		switch(t->etype) {
 		case TVOID:
@@ -93,6 +69,14 @@ argsize(void)
 		s = (s+7) & ~7;
 	else
 		s = (s+3) & ~3;
+	if(doret && thisfn->link->etype != TVOID) {
+		s = align(s, thisfn->link, Aarg1, nil);
+		s = align(s, thisfn->link, Aarg2, nil);
+		if(thechar == '6')
+			s = (s+7) & ~7;
+		else
+			s = (s+3) & ~3;
+	}
 	return s;
 }
 
@@ -101,9 +85,6 @@ codgen(Node *n, Node *nn)
 {
 	Prog *sp;
 	Node *n1, nod, nod1;
-	Sym *gcargs;
-	Sym *gclocals;
-	int isvarargs;
 
 	cursafe = 0;
 	curarg = 0;
@@ -123,19 +104,10 @@ codgen(Node *n, Node *nn)
 	nearln = nn->lineno;
 
 	p = gtext(n1->sym, stkoff);
+	p->from.sym->cfunc = 1;
 	sp = p;
 
 	/*
-	 * generate funcdata symbol for this function.
-	 * data is filled in at the end of codgen().
-	 */
-	isvarargs = hasdotdotdot();
-	gcargs = nil;
-	if(!isvarargs)
-		gcargs = makefuncdatasym("gcargs·%d", FUNCDATA_ArgsPointerMaps);
-	gclocals = makefuncdatasym("gclocals·%d", FUNCDATA_LocalsPointerMaps);
-
-	/*
 	 * isolate first argument
 	 */
 	if(REGARG >= 0) {
@@ -155,8 +127,6 @@ codgen(Node *n, Node *nn)
 		}
 	}
 
-	retok = 0;
-
 	canreach = 1;
 	warnreach = 1;
 	gen(n);
@@ -171,22 +141,6 @@ codgen(Node *n, Node *nn)
 	if(thechar=='6' || thechar=='7')	/* [sic] */
 		maxargsafe = xround(maxargsafe, 8);
 	sp->to.offset += maxargsafe;
-
-	if(!isvarargs)
-		dumpgcargs(thisfn, gcargs);
-
-	// TODO(rsc): "stkoff" is not right. It does not account for
-	// the possibility of data stored in .safe variables.
-	// Unfortunately those move up and down just like
-	// the argument frame (and in fact dovetail with it)
-	// so the number we need is not available or even
-	// well-defined. Probably we need to make the safe
-	// area its own section.
-	// That said, we've been using stkoff for months
-	// and nothing too terrible has happened.
-	gextern(gclocals, nodconst(-stkoff), 0, 4); // locals
-	gclocals->type = typ(0, T);
-	gclocals->type->width = 4;
 }
 
 void
@@ -214,7 +168,7 @@ supgen(Node *n)
 void
 gen(Node *n)
 {
-	Node *l, nod;
+	Node *l, nod, nod1;
 	Prog *sp, *spc, *spb;
 	Case *cn;
 	long sbc, scc;
@@ -275,14 +229,26 @@ loop:
 			gbranch(ORETURN);
 			break;
 		}
+		if(typecmplx[n->type->etype] && !hasdotdotdot(thisfn)) {
+			regret(&nod, n, thisfn, 2);
+			sugen(l, &nod, n->type->width);
+			noretval(3);
+			gbranch(ORETURN);
+			break;
+		}
 		if(typecmplx[n->type->etype]) {
 			sugen(l, nodret, n->type->width);
 			noretval(3);
 			gbranch(ORETURN);
 			break;
 		}
-		regret(&nod, n);
+		regret(&nod1, n, thisfn, 2);
+		nod = nod1;
+		if(nod.op != OREGISTER)
+			regalloc(&nod, n, Z);
 		cgen(l, &nod);
+		if(nod1.op != OREGISTER)
+			gmove(&nod, &nod1);
 		regfree(&nod);
 		if(typefd[n->type->etype])
 			noretval(1);
@@ -654,111 +620,3 @@ bcomplex(Node *n, Node *c)
 	boolgen(n, 1, Z);
 	return 0;
 }
-
-// Updates the bitvector with a set bit for each pointer containing
-// value in the type description starting at offset.
-static void
-walktype1(Type *t, int32 offset, Bvec *bv, int param)
-{
-	Type *t1;
-	int32 o;
-	int32 widthptr;
-
-	widthptr = ewidth[TIND];
-	switch(t->etype) {
-	case TCHAR:
-	case TUCHAR:
-	case TSHORT:
-	case TUSHORT:
-	case TINT:
-	case TUINT:
-	case TLONG:
-	case TULONG:
-	case TVLONG:
-	case TUVLONG:
-	case TFLOAT:
-	case TDOUBLE:
-		// non-pointer types
-		for(o = 0; o < t->width; o++)
-			bvset(bv, ((offset + t->offset + o) / widthptr) * BitsPerPointer); // 1 = live scalar
-		break;
-
-	case TIND:
-	pointer:
-		// pointer types
-		if((offset + t->offset) % widthptr != 0)
-			yyerror("unaligned pointer");
-		bvset(bv, ((offset + t->offset) / widthptr)*BitsPerPointer + 1); // 2 = live ptr
-		break;
-
-	case TARRAY:
-		if(param)	// unlike Go, C passes arrays by reference
-			goto pointer;
-		// array in struct or union is an actual array
-		for(o = 0; o < t->width; o += t->link->width)
-			walktype1(t->link, offset+o, bv, 0);
-		break;
-
-	case TSTRUCT:
-		// build map recursively
-		for(t1 = t->link; t1 != T; t1 = t1->down)
-			walktype1(t1, offset, bv, 0);
-		break;
-
-	case TUNION:
-		walktype1(t->link, offset, bv, 0);
-		break;
-
-	default:
-		yyerror("can't handle arg type %s\n", tnames[t->etype]);
-	}
-}
-
-// Compute a bit vector to describe the pointer containing locations
-// in the argument list.  Adds the data to gcsym and returns the offset
-// of end of the bit vector.
-static void
-dumpgcargs(Type *fn, Sym *sym)
-{
-	Bvec *bv;
-	Type *t;
-	int32 i;
-	int32 argbytes;
-	int32 symoffset, argoffset;
-
-	// Dump the length of the bitmap array.  This value is always one for
-	// functions written in C.
-	symoffset = 0;
-	gextern(sym, nodconst(1), symoffset, 4);
-	symoffset += 4;
-	argbytes = (argsize() + ewidth[TIND] - 1);
-	bv = bvalloc((argbytes  / ewidth[TIND]) * BitsPerPointer);
-	argoffset = align(0, fn->link, Aarg0, nil);
-	if(argoffset > 0) {
-		// The C calling convention returns structs by copying them to a
-		// location pointed to by a hidden first argument.  This first
-		// argument is a pointer.
-		if(argoffset != ewidth[TIND])
-			yyerror("passbyptr arg not the right size");
-		bvset(bv, 1); // 2 = live ptr
-	}
-	for(t = fn->down; t != T; t = t->down) {
-		if(t->etype == TVOID)
-			continue;
-		argoffset = align(argoffset, t, Aarg1, nil);
-		walktype1(t, argoffset, bv, 1);
-		argoffset = align(argoffset, t, Aarg2, nil);
-	}
-	// Dump the length of the bitmap.
-	gextern(sym, nodconst(bv->n), symoffset, 4);
-	symoffset += 4;
-	// Dump the words of the bitmap.
-	for(i = 0; i < bv->n; i += 32) {
-		gextern(sym, nodconst(bv->b[i/32]), symoffset, 4);
-		symoffset += 4;
-	}
-	free(bv);
-	// Finalize the gc symbol.
-	sym->type = typ(0, T);
-	sym->type->width = symoffset;
-}
diff --git a/src/cmd/cc/y.tab.c b/src/cmd/cc/y.tab.c
index 8588515..94932ef 100644
--- a/src/cmd/cc/y.tab.c
+++ b/src/cmd/cc/y.tab.c
@@ -1,21 +1,24 @@
-/* A Bison parser, made by GNU Bison 2.7.12-4996.  */
+/* A Bison parser, made by GNU Bison 2.3.  */
 
-/* Bison implementation for Yacc-like parsers in C
-   
-      Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc.
-   
-   This program is free software: you can redistribute it and/or modify
+/* Skeleton implementation for Bison's Yacc-like parsers in C
+
+   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+   Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation, either version 3 of the License, or
-   (at your option) any later version.
-   
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-   
+
    You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
 
 /* As a special exception, you may create a larger work that contains
    part or all of the Bison parser skeleton and distribute that work
@@ -26,7 +29,7 @@
    special exception, which will cause the skeleton and the resulting
    Bison output files to be licensed under the GNU General Public
    License without this special exception.
-   
+
    This special exception was added by the Free Software Foundation in
    version 2.2 of Bison.  */
 
@@ -44,7 +47,7 @@
 #define YYBISON 1
 
 /* Bison version.  */
-#define YYBISON_VERSION "2.7.12-4996"
+#define YYBISON_VERSION "2.3"
 
 /* Skeleton name.  */
 #define YYSKELETON_NAME "yacc.c"
@@ -52,53 +55,10 @@
 /* Pure parsers.  */
 #define YYPURE 0
 
-/* Push parsers.  */
-#define YYPUSH 0
-
-/* Pull parsers.  */
-#define YYPULL 1
-
-
-
-
-/* Copy the first part of user declarations.  */
-/* Line 371 of yacc.c  */
-#line 31 "cc.y"
-
-#include <u.h>
-#include <stdio.h>	/* if we don't, bison will, and cc.h re-#defines getc */
-#include "cc.h"
+/* Using locations.  */
+#define YYLSP_NEEDED 0
 
-/* Line 371 of yacc.c  */
-#line 74 "y.tab.c"
 
-# ifndef YY_NULL
-#  if defined __cplusplus && 201103L <= __cplusplus
-#   define YY_NULL nullptr
-#  else
-#   define YY_NULL 0
-#  endif
-# endif
-
-/* Enabling verbose error messages.  */
-#ifdef YYERROR_VERBOSE
-# undef YYERROR_VERBOSE
-# define YYERROR_VERBOSE 1
-#else
-# define YYERROR_VERBOSE 0
-#endif
-
-/* In a future release of Bison, this section will be replaced
-   by #include "y.tab.h".  */
-#ifndef YY_YY_Y_TAB_H_INCLUDED
-# define YY_YY_Y_TAB_H_INCLUDED
-/* Enabling traces.  */
-#ifndef YYDEBUG
-# define YYDEBUG 0
-#endif
-#if YYDEBUG
-extern int yydebug;
-#endif
 
 /* Tokens.  */
 #ifndef YYTOKENTYPE
@@ -256,12 +216,37 @@ extern int yydebug;
 
 
 
+
+/* Copy the first part of user declarations.  */
+#line 31 "cc.y"
+
+#include <u.h>
+#include <stdio.h>	/* if we don't, bison will, and cc.h re-#defines getc */
+#include "cc.h"
+
+
+/* Enabling traces.  */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+
+/* Enabling verbose error messages.  */
+#ifdef YYERROR_VERBOSE
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
+#else
+# define YYERROR_VERBOSE 0
+#endif
+
+/* Enabling the token table.  */
+#ifndef YYTOKEN_TABLE
+# define YYTOKEN_TABLE 0
+#endif
+
 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
 typedef union YYSTYPE
-{
-/* Line 387 of yacc.c  */
 #line 36 "cc.y"
-
+{
 	Node*	node;
 	Sym*	sym;
 	Type*	type;
@@ -285,38 +270,22 @@ typedef union YYSTYPE
 	int32	lval;
 	double	dval;
 	vlong	vval;
-
-
-/* Line 387 of yacc.c  */
-#line 292 "y.tab.c"
-} YYSTYPE;
-# define YYSTYPE_IS_TRIVIAL 1
+}
+/* Line 193 of yacc.c.  */
+#line 276 "y.tab.c"
+	YYSTYPE;
 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
 #endif
 
-extern YYSTYPE yylval;
 
-#ifdef YYPARSE_PARAM
-#if defined __STDC__ || defined __cplusplus
-int yyparse (void *YYPARSE_PARAM);
-#else
-int yyparse ();
-#endif
-#else /* ! YYPARSE_PARAM */
-#if defined __STDC__ || defined __cplusplus
-int yyparse (void);
-#else
-int yyparse ();
-#endif
-#endif /* ! YYPARSE_PARAM */
-
-#endif /* !YY_YY_Y_TAB_H_INCLUDED  */
 
 /* Copy the second part of user declarations.  */
 
-/* Line 390 of yacc.c  */
-#line 320 "y.tab.c"
+
+/* Line 216 of yacc.c.  */
+#line 289 "y.tab.c"
 
 #ifdef short
 # undef short
@@ -369,45 +338,36 @@ typedef short int yytype_int16;
 # if defined YYENABLE_NLS && YYENABLE_NLS
 #  if ENABLE_NLS
 #   include <libintl.h> /* INFRINGES ON USER NAME SPACE */
-#   define YY_(Msgid) dgettext ("bison-runtime", Msgid)
+#   define YY_(msgid) dgettext ("bison-runtime", msgid)
 #  endif
 # endif
 # ifndef YY_
-#  define YY_(Msgid) Msgid
-# endif
-#endif
-
-#ifndef __attribute__
-/* This feature is available in gcc versions 2.5 and later.  */
-# if (! defined __GNUC__ || __GNUC__ < 2 \
-      || (__GNUC__ == 2 && __GNUC_MINOR__ < 5))
-#  define __attribute__(Spec) /* empty */
+#  define YY_(msgid) msgid
 # endif
 #endif
 
 /* Suppress unused-variable warnings by "using" E.  */
 #if ! defined lint || defined __GNUC__
-# define YYUSE(E) ((void) (E))
+# define YYUSE(e) ((void) (e))
 #else
-# define YYUSE(E) /* empty */
+# define YYUSE(e) /* empty */
 #endif
 
-
 /* Identity function, used to suppress warnings about constant conditions.  */
 #ifndef lint
-# define YYID(N) (N)
+# define YYID(n) (n)
 #else
 #if (defined __STDC__ || defined __C99__FUNC__ \
      || defined __cplusplus || defined _MSC_VER)
 static int
-YYID (int yyi)
+YYID (int i)
 #else
 static int
-YYID (yyi)
-    int yyi;
+YYID (i)
+    int i;
 #endif
 {
-  return yyi;
+  return i;
 }
 #endif
 
@@ -428,12 +388,11 @@ YYID (yyi)
 #    define alloca _alloca
 #   else
 #    define YYSTACK_ALLOC alloca
-#    if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
+#    if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
      || defined __cplusplus || defined _MSC_VER)
 #     include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-      /* Use EXIT_SUCCESS as a witness for stdlib.h.  */
-#     ifndef EXIT_SUCCESS
-#      define EXIT_SUCCESS 0
+#     ifndef _STDLIB_H
+#      define _STDLIB_H 1
 #     endif
 #    endif
 #   endif
@@ -456,24 +415,24 @@ YYID (yyi)
 #  ifndef YYSTACK_ALLOC_MAXIMUM
 #   define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
 #  endif
-#  if (defined __cplusplus && ! defined EXIT_SUCCESS \
+#  if (defined __cplusplus && ! defined _STDLIB_H \
        && ! ((defined YYMALLOC || defined malloc) \
 	     && (defined YYFREE || defined free)))
 #   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-#   ifndef EXIT_SUCCESS
-#    define EXIT_SUCCESS 0
+#   ifndef _STDLIB_H
+#    define _STDLIB_H 1
 #   endif
 #  endif
 #  ifndef YYMALLOC
 #   define YYMALLOC malloc
-#   if ! defined malloc && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
+#   if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
      || defined __cplusplus || defined _MSC_VER)
 void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
 #   endif
 #  endif
 #  ifndef YYFREE
 #   define YYFREE free
-#   if ! defined free && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
+#   if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
      || defined __cplusplus || defined _MSC_VER)
 void free (void *); /* INFRINGES ON USER NAME SPACE */
 #   endif
@@ -489,9 +448,9 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */
 /* A type that is properly aligned for any stack member.  */
 union yyalloc
 {
-  yytype_int16 yyss_alloc;
-  YYSTYPE yyvs_alloc;
-};
+  yytype_int16 yyss;
+  YYSTYPE yyvs;
+  };
 
 /* The size of the maximum gap between one aligned stack and the next.  */
 # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
@@ -502,19 +461,35 @@ union yyalloc
      ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
       + YYSTACK_GAP_MAXIMUM)
 
-# define YYCOPY_NEEDED 1
+/* Copy COUNT objects from FROM to TO.  The source and destination do
+   not overlap.  */
+# ifndef YYCOPY
+#  if defined __GNUC__ && 1 < __GNUC__
+#   define YYCOPY(To, From, Count) \
+      __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
+#  else
+#   define YYCOPY(To, From, Count)		\
+      do					\
+	{					\
+	  YYSIZE_T yyi;				\
+	  for (yyi = 0; yyi < (Count); yyi++)	\
+	    (To)[yyi] = (From)[yyi];		\
+	}					\
+      while (YYID (0))
+#  endif
+# endif
 
 /* Relocate STACK from its old location to the new one.  The
    local variables YYSIZE and YYSTACKSIZE give the old and new number of
    elements in the stack, and YYPTR gives the new location of the
    stack.  Advance YYPTR to a properly aligned location for the next
    stack.  */
-# define YYSTACK_RELOCATE(Stack_alloc, Stack)				\
+# define YYSTACK_RELOCATE(Stack)					\
     do									\
       {									\
 	YYSIZE_T yynewbytes;						\
-	YYCOPY (&yyptr->Stack_alloc, Stack, yysize);			\
-	Stack = &yyptr->Stack_alloc;					\
+	YYCOPY (&yyptr->Stack, Stack, yysize);				\
+	Stack = &yyptr->Stack;						\
 	yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
 	yyptr += yynewbytes / sizeof (*yyptr);				\
       }									\
@@ -522,26 +497,6 @@ union yyalloc
 
 #endif
 
-#if defined YYCOPY_NEEDED && YYCOPY_NEEDED
-/* Copy COUNT objects from SRC to DST.  The source and destination do
-   not overlap.  */
-# ifndef YYCOPY
-#  if defined __GNUC__ && 1 < __GNUC__
-#   define YYCOPY(Dst, Src, Count) \
-      __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src)))
-#  else
-#   define YYCOPY(Dst, Src, Count)              \
-      do                                        \
-        {                                       \
-          YYSIZE_T yyi;                         \
-          for (yyi = 0; yyi < (Count); yyi++)   \
-            (Dst)[yyi] = (Src)[yyi];            \
-        }                                       \
-      while (YYID (0))
-#  endif
-# endif
-#endif /* !YYCOPY_NEEDED */
-
 /* YYFINAL -- State number of the termination state.  */
 #define YYFINAL  2
 /* YYLAST -- Last index in YYTABLE.  */
@@ -737,16 +692,16 @@ static const yytype_uint16 yyrline[] =
      794,   798,   802,   803,   810,   817,   824,   831,   838,   845,
      852,   859,   860,   863,   873,   891,   901,   919,   922,   925,
      926,   933,   932,   955,   959,   962,   967,   972,   978,   986,
-     992,   998,  1004,  1012,  1020,  1027,  1033,  1032,  1044,  1052,
-    1058,  1057,  1069,  1077,  1086,  1090,  1085,  1107,  1106,  1115,
-    1121,  1122,  1128,  1131,  1137,  1138,  1139,  1142,  1143,  1149,
-    1150,  1153,  1157,  1161,  1162,  1165,  1166,  1167,  1168,  1169,
-    1170,  1171,  1172,  1173,  1176,  1177,  1178,  1179,  1180,  1181,
-    1182,  1185,  1186,  1187,  1190,  1205,  1217,  1218
+     992,   998,  1004,  1012,  1020,  1027,  1033,  1032,  1044,  1053,
+    1059,  1058,  1070,  1078,  1087,  1091,  1086,  1108,  1107,  1116,
+    1122,  1123,  1129,  1132,  1138,  1139,  1140,  1143,  1144,  1150,
+    1151,  1154,  1158,  1162,  1163,  1166,  1167,  1168,  1169,  1170,
+    1171,  1172,  1173,  1174,  1177,  1178,  1179,  1180,  1181,  1182,
+    1183,  1186,  1187,  1188,  1191,  1206,  1218,  1219
 };
 #endif
 
-#if YYDEBUG || YYERROR_VERBOSE || 0
+#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
 /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
    First, the terminals, then, starting at YYNTOKENS, nonterminals.  */
 static const char *const yytname[] =
@@ -764,16 +719,16 @@ static const char *const yytname[] =
   "LTYPEDEF", "LTYPESTR", "LUNION", "LUNSIGNED", "LWHILE", "LVOID",
   "LENUM", "LSIGNED", "LCONSTNT", "LVOLATILE", "LSET", "LSIGNOF",
   "LRESTRICT", "LINLINE", "')'", "']'", "'{'", "'}'", "'!'", "'~'",
-  "$accept", "prog", "xdecl", "$@1", "$@2", "xdlist", "$@3", "xdecor",
-  "xdecor2", "adecl", "adlist", "$@4", "pdecl", "pdlist", "edecl", "$@5",
-  "$@6", "zedlist", "edlist", "edecor", "abdecor", "abdecor1", "abdecor2",
+  "$accept", "prog", "xdecl", "@1", "@2", "xdlist", "@3", "xdecor",
+  "xdecor2", "adecl", "adlist", "@4", "pdecl", "pdlist", "edecl", "@5",
+  "@6", "zedlist", "edlist", "edecor", "abdecor", "abdecor1", "abdecor2",
   "abdecor3", "init", "qual", "qlist", "ilist", "zarglist", "arglist",
-  "block", "slist", "labels", "label", "stmnt", "forexpr", "ulstmnt",
-  "$@7", "$@8", "zcexpr", "zexpr", "lexpr", "cexpr", "expr", "xuexpr",
-  "uexpr", "pexpr", "string", "lstring", "zelist", "elist", "sbody", "@9",
-  "zctlist", "types", "tlist", "ctlist", "complex", "$@10", "$@11", "$@12",
-  "$@13", "$@14", "gctnlist", "zgnlist", "gctname", "gcnlist", "gcname",
-  "enum", "tname", "cname", "gname", "name", "tag", "ltag", YY_NULL
+  "block", "slist", "labels", "label", "stmnt", "forexpr", "ulstmnt", "@7",
+  "@8", "zcexpr", "zexpr", "lexpr", "cexpr", "expr", "xuexpr", "uexpr",
+  "pexpr", "string", "lstring", "zelist", "elist", "sbody", "@9",
+  "zctlist", "types", "tlist", "ctlist", "complex", "@10", "@11", "@12",
+  "@13", "@14", "gctnlist", "zgnlist", "gctname", "gcnlist", "gcname",
+  "enum", "tname", "cname", "gname", "name", "tag", "ltag", 0
 };
 #endif
 
@@ -855,8 +810,8 @@ static const yytype_uint8 yyr2[] =
        1,     1,     1,     1,     1,     1,     1,     1
 };
 
-/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM.
-   Performed when YYTABLE doesn't specify something else to do.  Zero
+/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
+   STATE-NUM when YYTABLE doesn't specify something else to do.  Zero
    means the default is an error.  */
 static const yytype_uint8 yydefact[] =
 {
@@ -981,7 +936,8 @@ static const yytype_int16 yypgoto[] =
 
 /* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
    positive, shift that token.  If negative, reduce the rule which
-   number is the opposite.  If YYTABLE_NINF, syntax error.  */
+   number is the opposite.  If zero, do what YYDEFACT says.
+   If YYTABLE_NINF, syntax error.  */
 #define YYTABLE_NINF -205
 static const yytype_int16 yytable[] =
 {
@@ -1106,12 +1062,6 @@ static const yytype_int16 yytable[] =
      178,   179,   180,   181,   182,   183,   184,   185,   186
 };
 
-#define yypact_value_is_default(Yystate) \
-  (!!((Yystate) == (-331)))
-
-#define yytable_value_is_error(Yytable_value) \
-  YYID (0)
-
 static const yytype_int16 yycheck[] =
 {
        1,    27,    14,    91,   131,    17,    30,    58,    20,    33,
@@ -1295,50 +1245,78 @@ static const yytype_uint8 yystos[] =
 
 /* Like YYERROR except do call yyerror.  This remains here temporarily
    to ease the transition to the new meaning of YYERROR, for GCC.
-   Once GCC version 2 has supplanted version 1, this can go.  However,
-   YYFAIL appears to be in use.  Nevertheless, it is formally deprecated
-   in Bison 2.4.2's NEWS entry, where a plan to phase it out is
-   discussed.  */
+   Once GCC version 2 has supplanted version 1, this can go.  */
 
 #define YYFAIL		goto yyerrlab
-#if defined YYFAIL
-  /* This is here to suppress warnings from the GCC cpp's
-     -Wunused-macros.  Normally we don't worry about that warning, but
-     some users do, and we want to make it easy for users to remove
-     YYFAIL uses, which will produce warnings from Bison 2.5.  */
-#endif
 
 #define YYRECOVERING()  (!!yyerrstatus)
 
-#define YYBACKUP(Token, Value)                                  \
-do                                                              \
-  if (yychar == YYEMPTY)                                        \
-    {                                                           \
-      yychar = (Token);                                         \
-      yylval = (Value);                                         \
-      YYPOPSTACK (yylen);                                       \
-      yystate = *yyssp;                                         \
-      goto yybackup;                                            \
-    }                                                           \
-  else                                                          \
-    {                                                           \
+#define YYBACKUP(Token, Value)					\
+do								\
+  if (yychar == YYEMPTY && yylen == 1)				\
+    {								\
+      yychar = (Token);						\
+      yylval = (Value);						\
+      yytoken = YYTRANSLATE (yychar);				\
+      YYPOPSTACK (1);						\
+      goto yybackup;						\
+    }								\
+  else								\
+    {								\
       yyerror (YY_("syntax error: cannot back up")); \
       YYERROR;							\
     }								\
 while (YYID (0))
 
-/* Error token number */
+
 #define YYTERROR	1
 #define YYERRCODE	256
 
 
-/* This macro is provided for backward compatibility. */
+/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
+   If N is 0, then set CURRENT to the empty location which ends
+   the previous symbol: RHS[0] (always defined).  */
+
+#define YYRHSLOC(Rhs, K) ((Rhs)[K])
+#ifndef YYLLOC_DEFAULT
+# define YYLLOC_DEFAULT(Current, Rhs, N)				\
+    do									\
+      if (YYID (N))                                                    \
+	{								\
+	  (Current).first_line   = YYRHSLOC (Rhs, 1).first_line;	\
+	  (Current).first_column = YYRHSLOC (Rhs, 1).first_column;	\
+	  (Current).last_line    = YYRHSLOC (Rhs, N).last_line;		\
+	  (Current).last_column  = YYRHSLOC (Rhs, N).last_column;	\
+	}								\
+      else								\
+	{								\
+	  (Current).first_line   = (Current).last_line   =		\
+	    YYRHSLOC (Rhs, 0).last_line;				\
+	  (Current).first_column = (Current).last_column =		\
+	    YYRHSLOC (Rhs, 0).last_column;				\
+	}								\
+    while (YYID (0))
+#endif
+
+
+/* YY_LOCATION_PRINT -- Print the location on the stream.
+   This macro was not mandated originally: define only if we know
+   we won't break user code: when these are the locations we know.  */
+
 #ifndef YY_LOCATION_PRINT
-# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
+#  define YY_LOCATION_PRINT(File, Loc)			\
+     fprintf (File, "%d.%d-%d.%d",			\
+	      (Loc).first_line, (Loc).first_column,	\
+	      (Loc).last_line,  (Loc).last_column)
+# else
+#  define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+# endif
 #endif
 
 
 /* YYLEX -- calling `yylex' with the right arguments.  */
+
 #ifdef YYLEX_PARAM
 # define YYLEX yylex (YYLEX_PARAM)
 #else
@@ -1388,8 +1366,6 @@ yy_symbol_value_print (yyoutput, yytype, yyvaluep)
     YYSTYPE const * const yyvaluep;
 #endif
 {
-  FILE *yyo = yyoutput;
-  YYUSE (yyo);
   if (!yyvaluep)
     return;
 # ifdef YYPRINT
@@ -1398,7 +1374,11 @@ yy_symbol_value_print (yyoutput, yytype, yyvaluep)
 # else
   YYUSE (yyoutput);
 # endif
-  YYUSE (yytype);
+  switch (yytype)
+    {
+      default:
+	break;
+    }
 }
 
 
@@ -1435,20 +1415,17 @@ yy_symbol_print (yyoutput, yytype, yyvaluep)
 #if (defined __STDC__ || defined __C99__FUNC__ \
      || defined __cplusplus || defined _MSC_VER)
 static void
-yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
+yy_stack_print (yytype_int16 *bottom, yytype_int16 *top)
 #else
 static void
-yy_stack_print (yybottom, yytop)
-    yytype_int16 *yybottom;
-    yytype_int16 *yytop;
+yy_stack_print (bottom, top)
+    yytype_int16 *bottom;
+    yytype_int16 *top;
 #endif
 {
   YYFPRINTF (stderr, "Stack now");
-  for (; yybottom <= yytop; yybottom++)
-    {
-      int yybot = *yybottom;
-      YYFPRINTF (stderr, " %d", yybot);
-    }
+  for (; bottom <= top; ++bottom)
+    YYFPRINTF (stderr, " %d", *bottom);
   YYFPRINTF (stderr, "\n");
 }
 
@@ -1482,11 +1459,11 @@ yy_reduce_print (yyvsp, yyrule)
   /* The symbols being reduced.  */
   for (yyi = 0; yyi < yynrhs; yyi++)
     {
-      YYFPRINTF (stderr, "   $%d = ", yyi + 1);
+      fprintf (stderr, "   $%d = ", yyi + 1);
       yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
 		       &(yyvsp[(yyi + 1) - (yynrhs)])
 		       		       );
-      YYFPRINTF (stderr, "\n");
+      fprintf (stderr, "\n");
     }
 }
 
@@ -1523,6 +1500,7 @@ int yydebug;
 # define YYMAXDEPTH 10000
 #endif
 
+

 
 #if YYERROR_VERBOSE
 
@@ -1625,145 +1603,115 @@ yytnamerr (char *yyres, const char *yystr)
 }
 # endif
 
-/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message
-   about the unexpected token YYTOKEN for the state stack whose top is
-   YYSSP.
-
-   Return 0 if *YYMSG was successfully written.  Return 1 if *YYMSG is
-   not large enough to hold the message.  In that case, also set
-   *YYMSG_ALLOC to the required number of bytes.  Return 2 if the
-   required number of bytes is too large to store.  */
-static int
-yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
-                yytype_int16 *yyssp, int yytoken)
+/* Copy into YYRESULT an error message about the unexpected token
+   YYCHAR while in state YYSTATE.  Return the number of bytes copied,
+   including the terminating null byte.  If YYRESULT is null, do not
+   copy anything; just return the number of bytes that would be
+   copied.  As a special case, return 0 if an ordinary "syntax error"
+   message will do.  Return YYSIZE_MAXIMUM if overflow occurs during
+   size calculation.  */
+static YYSIZE_T
+yysyntax_error (char *yyresult, int yystate, int yychar)
 {
-  YYSIZE_T yysize0 = yytnamerr (YY_NULL, yytname[yytoken]);
-  YYSIZE_T yysize = yysize0;
-  enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
-  /* Internationalized format string. */
-  const char *yyformat = YY_NULL;
-  /* Arguments of yyformat. */
-  char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
-  /* Number of reported tokens (one for the "unexpected", one per
-     "expected"). */
-  int yycount = 0;
-
-  /* There are many possibilities here to consider:
-     - Assume YYFAIL is not used.  It's too flawed to consider.  See
-       <http://lists.gnu.org/archive/html/bison-patches/2009-12/msg00024.html>
-       for details.  YYERROR is fine as it does not invoke this
-       function.
-     - If this state is a consistent state with a default action, then
-       the only way this function was invoked is if the default action
-       is an error action.  In that case, don't check for expected
-       tokens because there are none.
-     - The only way there can be no lookahead present (in yychar) is if
-       this state is a consistent state with a default action.  Thus,
-       detecting the absence of a lookahead is sufficient to determine
-       that there is no unexpected or expected token to report.  In that
-       case, just report a simple "syntax error".
-     - Don't assume there isn't a lookahead just because this state is a
-       consistent state with a default action.  There might have been a
-       previous inconsistent state, consistent state with a non-default
-       action, or user semantic action that manipulated yychar.
-     - Of course, the expected token list depends on states to have
-       correct lookahead information, and it depends on the parser not
-       to perform extra reductions after fetching a lookahead from the
-       scanner and before detecting a syntax error.  Thus, state merging
-       (from LALR or IELR) and default reductions corrupt the expected
-       token list.  However, the list is correct for canonical LR with
-       one exception: it will still contain any token that will not be
-       accepted due to an error action in a later state.
-  */
-  if (yytoken != YYEMPTY)
-    {
-      int yyn = yypact[*yyssp];
-      yyarg[yycount++] = yytname[yytoken];
-      if (!yypact_value_is_default (yyn))
-        {
-          /* Start YYX at -YYN if negative to avoid negative indexes in
-             YYCHECK.  In other words, skip the first -YYN actions for
-             this state because they are default actions.  */
-          int yyxbegin = yyn < 0 ? -yyn : 0;
-          /* Stay within bounds of both yycheck and yytname.  */
-          int yychecklim = YYLAST - yyn + 1;
-          int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
-          int yyx;
-
-          for (yyx = yyxbegin; yyx < yyxend; ++yyx)
-            if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR
-                && !yytable_value_is_error (yytable[yyx + yyn]))
-              {
-                if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
-                  {
-                    yycount = 1;
-                    yysize = yysize0;
-                    break;
-                  }
-                yyarg[yycount++] = yytname[yyx];
-                {
-                  YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULL, yytname[yyx]);
-                  if (! (yysize <= yysize1
-                         && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
-                    return 2;
-                  yysize = yysize1;
-                }
-              }
-        }
-    }
+  int yyn = yypact[yystate];
 
-  switch (yycount)
-    {
-# define YYCASE_(N, S)                      \
-      case N:                               \
-        yyformat = S;                       \
-      break
-      YYCASE_(0, YY_("syntax error"));
-      YYCASE_(1, YY_("syntax error, unexpected %s"));
-      YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
-      YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s"));
-      YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s"));
-      YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"));
-# undef YYCASE_
-    }
+  if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
+    return 0;
+  else
+    {
+      int yytype = YYTRANSLATE (yychar);
+      YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
+      YYSIZE_T yysize = yysize0;
+      YYSIZE_T yysize1;
+      int yysize_overflow = 0;
+      enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+      char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+      int yyx;
+
+# if 0
+      /* This is so xgettext sees the translatable formats that are
+	 constructed on the fly.  */
+      YY_("syntax error, unexpected %s");
+      YY_("syntax error, unexpected %s, expecting %s");
+      YY_("syntax error, unexpected %s, expecting %s or %s");
+      YY_("syntax error, unexpected %s, expecting %s or %s or %s");
+      YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
+# endif
+      char *yyfmt;
+      char const *yyf;
+      static char const yyunexpected[] = "syntax error, unexpected %s";
+      static char const yyexpecting[] = ", expecting %s";
+      static char const yyor[] = " or %s";
+      char yyformat[sizeof yyunexpected
+		    + sizeof yyexpecting - 1
+		    + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
+		       * (sizeof yyor - 1))];
+      char const *yyprefix = yyexpecting;
+
+      /* Start YYX at -YYN if negative to avoid negative indexes in
+	 YYCHECK.  */
+      int yyxbegin = yyn < 0 ? -yyn : 0;
+
+      /* Stay within bounds of both yycheck and yytname.  */
+      int yychecklim = YYLAST - yyn + 1;
+      int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+      int yycount = 1;
+
+      yyarg[0] = yytname[yytype];
+      yyfmt = yystpcpy (yyformat, yyunexpected);
+
+      for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+	if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+	  {
+	    if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+	      {
+		yycount = 1;
+		yysize = yysize0;
+		yyformat[sizeof yyunexpected - 1] = '\0';
+		break;
+	      }
+	    yyarg[yycount++] = yytname[yyx];
+	    yysize1 = yysize + yytnamerr (0, yytname[yyx]);
+	    yysize_overflow |= (yysize1 < yysize);
+	    yysize = yysize1;
+	    yyfmt = yystpcpy (yyfmt, yyprefix);
+	    yyprefix = yyor;
+	  }
 
-  {
-    YYSIZE_T yysize1 = yysize + yystrlen (yyformat);
-    if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
-      return 2;
-    yysize = yysize1;
-  }
+      yyf = YY_(yyformat);
+      yysize1 = yysize + yystrlen (yyf);
+      yysize_overflow |= (yysize1 < yysize);
+      yysize = yysize1;
 
-  if (*yymsg_alloc < yysize)
-    {
-      *yymsg_alloc = 2 * yysize;
-      if (! (yysize <= *yymsg_alloc
-             && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM))
-        *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM;
-      return 1;
-    }
+      if (yysize_overflow)
+	return YYSIZE_MAXIMUM;
 
-  /* Avoid sprintf, as that infringes on the user's name space.
-     Don't have undefined behavior even if the translation
-     produced a string with the wrong number of "%s"s.  */
-  {
-    char *yyp = *yymsg;
-    int yyi = 0;
-    while ((*yyp = *yyformat) != '\0')
-      if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount)
-        {
-          yyp += yytnamerr (yyp, yyarg[yyi++]);
-          yyformat += 2;
-        }
-      else
-        {
-          yyp++;
-          yyformat++;
-        }
-  }
-  return 0;
+      if (yyresult)
+	{
+	  /* Avoid sprintf, as that infringes on the user's name space.
+	     Don't have undefined behavior even if the translation
+	     produced a string with the wrong number of "%s"s.  */
+	  char *yyp = yyresult;
+	  int yyi = 0;
+	  while ((*yyp = *yyf) != '\0')
+	    {
+	      if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
+		{
+		  yyp += yytnamerr (yyp, yyarg[yyi++]);
+		  yyf += 2;
+		}
+	      else
+		{
+		  yyp++;
+		  yyf++;
+		}
+	    }
+	}
+      return yysize;
+    }
 }
 #endif /* YYERROR_VERBOSE */
+

 
 /*-----------------------------------------------.
 | Release the memory associated to this symbol.  |
@@ -1788,31 +1736,44 @@ yydestruct (yymsg, yytype, yyvaluep)
     yymsg = "Deleting";
   YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
 
-  YYUSE (yytype);
-}
+  switch (yytype)
+    {
 
+      default:
+	break;
+    }
+}
+

 
+/* Prevent warnings from -Wmissing-prototypes.  */
 
+#ifdef YYPARSE_PARAM
+#if defined __STDC__ || defined __cplusplus
+int yyparse (void *YYPARSE_PARAM);
+#else
+int yyparse ();
+#endif
+#else /* ! YYPARSE_PARAM */
+#if defined __STDC__ || defined __cplusplus
+int yyparse (void);
+#else
+int yyparse ();
+#endif
+#endif /* ! YYPARSE_PARAM */
 
-/* The lookahead symbol.  */
-int yychar;
 
 
-#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
-# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
-# define YY_IGNORE_MAYBE_UNINITIALIZED_END
-#endif
-#ifndef YY_INITIAL_VALUE
-# define YY_INITIAL_VALUE(Value) /* Nothing. */
-#endif
+/* The look-ahead symbol.  */
+int yychar;
 
-/* The semantic value of the lookahead symbol.  */
-YYSTYPE yylval YY_INITIAL_VALUE(yyval_default);
+/* The semantic value of the look-ahead symbol.  */
+YYSTYPE yylval;
 
 /* Number of syntax errors so far.  */
 int yynerrs;
 
 
+
 /*----------.
 | yyparse.  |
 `----------*/
@@ -1839,37 +1800,14 @@ yyparse ()
 #endif
 #endif
 {
-    int yystate;
-    /* Number of tokens to shift before error messages enabled.  */
-    int yyerrstatus;
-
-    /* The stacks and their tools:
-       `yyss': related to states.
-       `yyvs': related to semantic values.
-
-       Refer to the stacks through separate pointers, to allow yyoverflow
-       to reallocate them elsewhere.  */
-
-    /* The state stack.  */
-    yytype_int16 yyssa[YYINITDEPTH];
-    yytype_int16 *yyss;
-    yytype_int16 *yyssp;
-
-    /* The semantic value stack.  */
-    YYSTYPE yyvsa[YYINITDEPTH];
-    YYSTYPE *yyvs;
-    YYSTYPE *yyvsp;
-
-    YYSIZE_T yystacksize;
-
+  
+  int yystate;
   int yyn;
   int yyresult;
-  /* Lookahead token as an internal (translated) token number.  */
+  /* Number of tokens to shift before error messages enabled.  */
+  int yyerrstatus;
+  /* Look-ahead token as an internal (translated) token number.  */
   int yytoken = 0;
-  /* The variables used to return semantic value and location from the
-     action routines.  */
-  YYSTYPE yyval;
-
 #if YYERROR_VERBOSE
   /* Buffer for error messages, and its allocated size.  */
   char yymsgbuf[128];
@@ -1877,22 +1815,54 @@ yyparse ()
   YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
 #endif
 
+  /* Three stacks and their tools:
+     `yyss': related to states,
+     `yyvs': related to semantic values,
+     `yyls': related to locations.
+
+     Refer to the stacks thru separate pointers, to allow yyoverflow
+     to reallocate them elsewhere.  */
+
+  /* The state stack.  */
+  yytype_int16 yyssa[YYINITDEPTH];
+  yytype_int16 *yyss = yyssa;
+  yytype_int16 *yyssp;
+
+  /* The semantic value stack.  */
+  YYSTYPE yyvsa[YYINITDEPTH];
+  YYSTYPE *yyvs = yyvsa;
+  YYSTYPE *yyvsp;
+
+
+
 #define YYPOPSTACK(N)   (yyvsp -= (N), yyssp -= (N))
 
+  YYSIZE_T yystacksize = YYINITDEPTH;
+
+  /* The variables used to return semantic value and location from the
+     action routines.  */
+  YYSTYPE yyval;
+
+
   /* The number of symbols on the RHS of the reduced rule.
      Keep to zero when no symbol should be popped.  */
   int yylen = 0;
 
-  yyssp = yyss = yyssa;
-  yyvsp = yyvs = yyvsa;
-  yystacksize = YYINITDEPTH;
-
   YYDPRINTF ((stderr, "Starting parse\n"));
 
   yystate = 0;
   yyerrstatus = 0;
   yynerrs = 0;
-  yychar = YYEMPTY; /* Cause a token to be read.  */
+  yychar = YYEMPTY;		/* Cause a token to be read.  */
+
+  /* Initialize stack pointers.
+     Waste one element of value and location stack
+     so that they stay on the same level as the state stack.
+     The wasted elements are never initialized.  */
+
+  yyssp = yyss;
+  yyvsp = yyvs;
+
   goto yysetstate;
 
 /*------------------------------------------------------------.
@@ -1919,6 +1889,7 @@ yyparse ()
 	YYSTYPE *yyvs1 = yyvs;
 	yytype_int16 *yyss1 = yyss;
 
+
 	/* Each stack pointer address is followed by the size of the
 	   data in use in that stack, in bytes.  This used to be a
 	   conditional around just the two extra args, but that might
@@ -1926,6 +1897,7 @@ yyparse ()
 	yyoverflow (YY_("memory exhausted"),
 		    &yyss1, yysize * sizeof (*yyssp),
 		    &yyvs1, yysize * sizeof (*yyvsp),
+
 		    &yystacksize);
 
 	yyss = yyss1;
@@ -1948,8 +1920,9 @@ yyparse ()
 	  (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
 	if (! yyptr)
 	  goto yyexhaustedlab;
-	YYSTACK_RELOCATE (yyss_alloc, yyss);
-	YYSTACK_RELOCATE (yyvs_alloc, yyvs);
+	YYSTACK_RELOCATE (yyss);
+	YYSTACK_RELOCATE (yyvs);
+
 #  undef YYSTACK_RELOCATE
 	if (yyss1 != yyssa)
 	  YYSTACK_FREE (yyss1);
@@ -1960,6 +1933,7 @@ yyparse ()
       yyssp = yyss + yysize - 1;
       yyvsp = yyvs + yysize - 1;
 
+
       YYDPRINTF ((stderr, "Stack size increased to %lu\n",
 		  (unsigned long int) yystacksize));
 
@@ -1969,9 +1943,6 @@ yyparse ()
 
   YYDPRINTF ((stderr, "Entering state %d\n", yystate));
 
-  if (yystate == YYFINAL)
-    YYACCEPT;
-
   goto yybackup;
 
 /*-----------.
@@ -1980,16 +1951,16 @@ yyparse ()
 yybackup:
 
   /* Do appropriate processing given the current state.  Read a
-     lookahead token if we need one and don't already have one.  */
+     look-ahead token if we need one and don't already have one.  */
 
-  /* First try to decide what to do without reference to lookahead token.  */
+  /* First try to decide what to do without reference to look-ahead token.  */
   yyn = yypact[yystate];
-  if (yypact_value_is_default (yyn))
+  if (yyn == YYPACT_NINF)
     goto yydefault;
 
-  /* Not known => get a lookahead token if don't already have one.  */
+  /* Not known => get a look-ahead token if don't already have one.  */
 
-  /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol.  */
+  /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol.  */
   if (yychar == YYEMPTY)
     {
       YYDPRINTF ((stderr, "Reading a token: "));
@@ -2015,27 +1986,29 @@ yybackup:
   yyn = yytable[yyn];
   if (yyn <= 0)
     {
-      if (yytable_value_is_error (yyn))
-        goto yyerrlab;
+      if (yyn == 0 || yyn == YYTABLE_NINF)
+	goto yyerrlab;
       yyn = -yyn;
       goto yyreduce;
     }
 
+  if (yyn == YYFINAL)
+    YYACCEPT;
+
   /* Count tokens shifted since error; after three, turn off error
      status.  */
   if (yyerrstatus)
     yyerrstatus--;
 
-  /* Shift the lookahead token.  */
+  /* Shift the look-ahead token.  */
   YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
 
-  /* Discard the shifted token.  */
-  yychar = YYEMPTY;
+  /* Discard the shifted token unless it is eof.  */
+  if (yychar != YYEOF)
+    yychar = YYEMPTY;
 
   yystate = yyn;
-  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
   *++yyvsp = yylval;
-  YY_IGNORE_MAYBE_UNINITIALIZED_END
 
   goto yynewstate;
 
@@ -2072,7 +2045,6 @@ yyreduce:
   switch (yyn)
     {
         case 4:
-/* Line 1787 of yacc.c  */
 #line 109 "cc.y"
     {
 		dodecl(xdecl, lastclass, lasttype, Z);
@@ -2080,7 +2052,6 @@ yyreduce:
     break;
 
   case 6:
-/* Line 1787 of yacc.c  */
 #line 114 "cc.y"
     {
 		lastdcl = T;
@@ -2098,7 +2069,6 @@ yyreduce:
     break;
 
   case 7:
-/* Line 1787 of yacc.c  */
 #line 128 "cc.y"
     {
 		argmark((yyvsp[(2) - (4)].node), 1);
@@ -2106,7 +2076,6 @@ yyreduce:
     break;
 
   case 8:
-/* Line 1787 of yacc.c  */
 #line 132 "cc.y"
     {
 		Node *n;
@@ -2120,7 +2089,6 @@ yyreduce:
     break;
 
   case 9:
-/* Line 1787 of yacc.c  */
 #line 144 "cc.y"
     {
 		dodecl(xdecl, lastclass, lasttype, (yyvsp[(1) - (1)].node));
@@ -2128,7 +2096,6 @@ yyreduce:
     break;
 
   case 10:
-/* Line 1787 of yacc.c  */
 #line 148 "cc.y"
     {
 		(yyvsp[(1) - (1)].node) = dodecl(xdecl, lastclass, lasttype, (yyvsp[(1) - (1)].node));
@@ -2136,7 +2103,6 @@ yyreduce:
     break;
 
   case 11:
-/* Line 1787 of yacc.c  */
 #line 152 "cc.y"
     {
 		doinit((yyvsp[(1) - (4)].node)->sym, (yyvsp[(1) - (4)].node)->type, 0L, (yyvsp[(4) - (4)].node));
@@ -2144,7 +2110,6 @@ yyreduce:
     break;
 
   case 14:
-/* Line 1787 of yacc.c  */
 #line 160 "cc.y"
     {
 		(yyval.node) = new(OIND, (yyvsp[(3) - (3)].node), Z);
@@ -2153,7 +2118,6 @@ yyreduce:
     break;
 
   case 16:
-/* Line 1787 of yacc.c  */
 #line 168 "cc.y"
     {
 		(yyval.node) = (yyvsp[(2) - (3)].node);
@@ -2161,7 +2125,6 @@ yyreduce:
     break;
 
   case 17:
-/* Line 1787 of yacc.c  */
 #line 172 "cc.y"
     {
 		(yyval.node) = new(OFUNC, (yyvsp[(1) - (4)].node), (yyvsp[(3) - (4)].node));
@@ -2169,7 +2132,6 @@ yyreduce:
     break;
 
   case 18:
-/* Line 1787 of yacc.c  */
 #line 176 "cc.y"
     {
 		(yyval.node) = new(OARRAY, (yyvsp[(1) - (4)].node), (yyvsp[(3) - (4)].node));
@@ -2177,7 +2139,6 @@ yyreduce:
     break;
 
   case 19:
-/* Line 1787 of yacc.c  */
 #line 185 "cc.y"
     {
 		(yyval.node) = dodecl(adecl, lastclass, lasttype, Z);
@@ -2185,7 +2146,6 @@ yyreduce:
     break;
 
   case 20:
-/* Line 1787 of yacc.c  */
 #line 189 "cc.y"
     {
 		(yyval.node) = (yyvsp[(2) - (3)].node);
@@ -2193,7 +2153,6 @@ yyreduce:
     break;
 
   case 21:
-/* Line 1787 of yacc.c  */
 #line 195 "cc.y"
     {
 		dodecl(adecl, lastclass, lasttype, (yyvsp[(1) - (1)].node));
@@ -2202,7 +2161,6 @@ yyreduce:
     break;
 
   case 22:
-/* Line 1787 of yacc.c  */
 #line 200 "cc.y"
     {
 		(yyvsp[(1) - (1)].node) = dodecl(adecl, lastclass, lasttype, (yyvsp[(1) - (1)].node));
@@ -2210,7 +2168,6 @@ yyreduce:
     break;
 
   case 23:
-/* Line 1787 of yacc.c  */
 #line 204 "cc.y"
     {
 		int32 w;
@@ -2222,7 +2179,6 @@ yyreduce:
     break;
 
   case 24:
-/* Line 1787 of yacc.c  */
 #line 212 "cc.y"
     {
 		(yyval.node) = (yyvsp[(1) - (3)].node);
@@ -2235,7 +2191,6 @@ yyreduce:
     break;
 
   case 27:
-/* Line 1787 of yacc.c  */
 #line 229 "cc.y"
     {
 		dodecl(pdecl, lastclass, lasttype, (yyvsp[(1) - (1)].node));
@@ -2243,7 +2198,6 @@ yyreduce:
     break;
 
   case 29:
-/* Line 1787 of yacc.c  */
 #line 239 "cc.y"
     {
 		lasttype = (yyvsp[(1) - (1)].type);
@@ -2251,7 +2205,6 @@ yyreduce:
     break;
 
   case 31:
-/* Line 1787 of yacc.c  */
 #line 244 "cc.y"
     {
 		lasttype = (yyvsp[(2) - (2)].type);
@@ -2259,7 +2212,6 @@ yyreduce:
     break;
 
   case 33:
-/* Line 1787 of yacc.c  */
 #line 250 "cc.y"
     {
 		lastfield = 0;
@@ -2268,7 +2220,6 @@ yyreduce:
     break;
 
   case 35:
-/* Line 1787 of yacc.c  */
 #line 258 "cc.y"
     {
 		dodecl(edecl, CXXX, lasttype, (yyvsp[(1) - (1)].node));
@@ -2276,7 +2227,6 @@ yyreduce:
     break;
 
   case 37:
-/* Line 1787 of yacc.c  */
 #line 265 "cc.y"
     {
 		lastbit = 0;
@@ -2285,7 +2235,6 @@ yyreduce:
     break;
 
   case 38:
-/* Line 1787 of yacc.c  */
 #line 270 "cc.y"
     {
 		(yyval.node) = new(OBIT, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
@@ -2293,7 +2242,6 @@ yyreduce:
     break;
 
   case 39:
-/* Line 1787 of yacc.c  */
 #line 274 "cc.y"
     {
 		(yyval.node) = new(OBIT, Z, (yyvsp[(2) - (2)].node));
@@ -2301,7 +2249,6 @@ yyreduce:
     break;
 
   case 40:
-/* Line 1787 of yacc.c  */
 #line 282 "cc.y"
     {
 		(yyval.node) = (Z);
@@ -2309,7 +2256,6 @@ yyreduce:
     break;
 
   case 42:
-/* Line 1787 of yacc.c  */
 #line 289 "cc.y"
     {
 		(yyval.node) = new(OIND, (Z), Z);
@@ -2318,7 +2264,6 @@ yyreduce:
     break;
 
   case 43:
-/* Line 1787 of yacc.c  */
 #line 294 "cc.y"
     {
 		(yyval.node) = new(OIND, (yyvsp[(3) - (3)].node), Z);
@@ -2327,7 +2272,6 @@ yyreduce:
     break;
 
   case 46:
-/* Line 1787 of yacc.c  */
 #line 303 "cc.y"
     {
 		(yyval.node) = new(OFUNC, (yyvsp[(1) - (4)].node), (yyvsp[(3) - (4)].node));
@@ -2335,7 +2279,6 @@ yyreduce:
     break;
 
   case 47:
-/* Line 1787 of yacc.c  */
 #line 307 "cc.y"
     {
 		(yyval.node) = new(OARRAY, (yyvsp[(1) - (4)].node), (yyvsp[(3) - (4)].node));
@@ -2343,7 +2286,6 @@ yyreduce:
     break;
 
   case 48:
-/* Line 1787 of yacc.c  */
 #line 313 "cc.y"
     {
 		(yyval.node) = new(OFUNC, (Z), Z);
@@ -2351,7 +2293,6 @@ yyreduce:
     break;
 
   case 49:
-/* Line 1787 of yacc.c  */
 #line 317 "cc.y"
     {
 		(yyval.node) = new(OARRAY, (Z), (yyvsp[(2) - (3)].node));
@@ -2359,7 +2300,6 @@ yyreduce:
     break;
 
   case 50:
-/* Line 1787 of yacc.c  */
 #line 321 "cc.y"
     {
 		(yyval.node) = (yyvsp[(2) - (3)].node);
@@ -2367,7 +2307,6 @@ yyreduce:
     break;
 
   case 52:
-/* Line 1787 of yacc.c  */
 #line 328 "cc.y"
     {
 		(yyval.node) = new(OINIT, invert((yyvsp[(2) - (3)].node)), Z);
@@ -2375,7 +2314,6 @@ yyreduce:
     break;
 
   case 53:
-/* Line 1787 of yacc.c  */
 #line 334 "cc.y"
     {
 		(yyval.node) = new(OARRAY, (yyvsp[(2) - (3)].node), Z);
@@ -2383,7 +2321,6 @@ yyreduce:
     break;
 
   case 54:
-/* Line 1787 of yacc.c  */
 #line 338 "cc.y"
     {
 		(yyval.node) = new(OELEM, Z, Z);
@@ -2392,7 +2329,6 @@ yyreduce:
     break;
 
   case 57:
-/* Line 1787 of yacc.c  */
 #line 347 "cc.y"
     {
 		(yyval.node) = new(OLIST, (yyvsp[(1) - (3)].node), (yyvsp[(2) - (3)].node));
@@ -2400,7 +2336,6 @@ yyreduce:
     break;
 
   case 59:
-/* Line 1787 of yacc.c  */
 #line 352 "cc.y"
     {
 		(yyval.node) = new(OLIST, (yyvsp[(1) - (2)].node), (yyvsp[(2) - (2)].node));
@@ -2408,7 +2343,6 @@ yyreduce:
     break;
 
   case 62:
-/* Line 1787 of yacc.c  */
 #line 360 "cc.y"
     {
 		(yyval.node) = new(OLIST, (yyvsp[(1) - (2)].node), (yyvsp[(2) - (2)].node));
@@ -2416,7 +2350,6 @@ yyreduce:
     break;
 
   case 63:
-/* Line 1787 of yacc.c  */
 #line 365 "cc.y"
     {
 		(yyval.node) = Z;
@@ -2424,7 +2357,6 @@ yyreduce:
     break;
 
   case 64:
-/* Line 1787 of yacc.c  */
 #line 369 "cc.y"
     {
 		(yyval.node) = invert((yyvsp[(1) - (1)].node));
@@ -2432,7 +2364,6 @@ yyreduce:
     break;
 
   case 66:
-/* Line 1787 of yacc.c  */
 #line 377 "cc.y"
     {
 		(yyval.node) = new(OPROTO, (yyvsp[(2) - (2)].node), Z);
@@ -2441,7 +2372,6 @@ yyreduce:
     break;
 
   case 67:
-/* Line 1787 of yacc.c  */
 #line 382 "cc.y"
     {
 		(yyval.node) = new(OPROTO, (yyvsp[(2) - (2)].node), Z);
@@ -2450,7 +2380,6 @@ yyreduce:
     break;
 
   case 68:
-/* Line 1787 of yacc.c  */
 #line 387 "cc.y"
     {
 		(yyval.node) = new(ODOTDOT, Z, Z);
@@ -2458,7 +2387,6 @@ yyreduce:
     break;
 
   case 69:
-/* Line 1787 of yacc.c  */
 #line 391 "cc.y"
     {
 		(yyval.node) = new(OLIST, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
@@ -2466,7 +2394,6 @@ yyreduce:
     break;
 
   case 70:
-/* Line 1787 of yacc.c  */
 #line 397 "cc.y"
     {
 		(yyval.node) = invert((yyvsp[(2) - (3)].node));
@@ -2478,7 +2405,6 @@ yyreduce:
     break;
 
   case 71:
-/* Line 1787 of yacc.c  */
 #line 406 "cc.y"
     {
 		(yyval.node) = Z;
@@ -2486,7 +2412,6 @@ yyreduce:
     break;
 
   case 72:
-/* Line 1787 of yacc.c  */
 #line 410 "cc.y"
     {
 		(yyval.node) = new(OLIST, (yyvsp[(1) - (2)].node), (yyvsp[(2) - (2)].node));
@@ -2494,7 +2419,6 @@ yyreduce:
     break;
 
   case 73:
-/* Line 1787 of yacc.c  */
 #line 414 "cc.y"
     {
 		(yyval.node) = new(OLIST, (yyvsp[(1) - (2)].node), (yyvsp[(2) - (2)].node));
@@ -2502,7 +2426,6 @@ yyreduce:
     break;
 
   case 75:
-/* Line 1787 of yacc.c  */
 #line 421 "cc.y"
     {
 		(yyval.node) = new(OLIST, (yyvsp[(1) - (2)].node), (yyvsp[(2) - (2)].node));
@@ -2510,7 +2433,6 @@ yyreduce:
     break;
 
   case 76:
-/* Line 1787 of yacc.c  */
 #line 427 "cc.y"
     {
 		(yyval.node) = new(OCASE, (yyvsp[(2) - (3)].node), Z);
@@ -2518,7 +2440,6 @@ yyreduce:
     break;
 
   case 77:
-/* Line 1787 of yacc.c  */
 #line 431 "cc.y"
     {
 		(yyval.node) = new(OCASE, Z, Z);
@@ -2526,7 +2447,6 @@ yyreduce:
     break;
 
   case 78:
-/* Line 1787 of yacc.c  */
 #line 435 "cc.y"
     {
 		(yyval.node) = new(OLABEL, dcllabel((yyvsp[(1) - (2)].sym), 1), Z);
@@ -2534,7 +2454,6 @@ yyreduce:
     break;
 
   case 79:
-/* Line 1787 of yacc.c  */
 #line 441 "cc.y"
     {
 		(yyval.node) = Z;
@@ -2542,7 +2461,6 @@ yyreduce:
     break;
 
   case 81:
-/* Line 1787 of yacc.c  */
 #line 446 "cc.y"
     {
 		(yyval.node) = new(OLIST, (yyvsp[(1) - (2)].node), (yyvsp[(2) - (2)].node));
@@ -2550,7 +2468,6 @@ yyreduce:
     break;
 
   case 83:
-/* Line 1787 of yacc.c  */
 #line 453 "cc.y"
     {
 		(yyval.node) = (yyvsp[(2) - (2)].node);
@@ -2558,7 +2475,6 @@ yyreduce:
     break;
 
   case 85:
-/* Line 1787 of yacc.c  */
 #line 459 "cc.y"
     {
 		markdcl();
@@ -2566,7 +2482,6 @@ yyreduce:
     break;
 
   case 86:
-/* Line 1787 of yacc.c  */
 #line 463 "cc.y"
     {
 		(yyval.node) = revertdcl();
@@ -2578,7 +2493,6 @@ yyreduce:
     break;
 
   case 87:
-/* Line 1787 of yacc.c  */
 #line 471 "cc.y"
     {
 		(yyval.node) = new(OIF, (yyvsp[(3) - (5)].node), new(OLIST, (yyvsp[(5) - (5)].node), Z));
@@ -2588,7 +2502,6 @@ yyreduce:
     break;
 
   case 88:
-/* Line 1787 of yacc.c  */
 #line 477 "cc.y"
     {
 		(yyval.node) = new(OIF, (yyvsp[(3) - (7)].node), new(OLIST, (yyvsp[(5) - (7)].node), (yyvsp[(7) - (7)].node)));
@@ -2600,13 +2513,11 @@ yyreduce:
     break;
 
   case 89:
-/* Line 1787 of yacc.c  */
 #line 484 "cc.y"
     { markdcl(); }
     break;
 
   case 90:
-/* Line 1787 of yacc.c  */
 #line 485 "cc.y"
     {
 		(yyval.node) = revertdcl();
@@ -2621,7 +2532,6 @@ yyreduce:
     break;
 
   case 91:
-/* Line 1787 of yacc.c  */
 #line 496 "cc.y"
     {
 		(yyval.node) = new(OWHILE, (yyvsp[(3) - (5)].node), (yyvsp[(5) - (5)].node));
@@ -2629,7 +2539,6 @@ yyreduce:
     break;
 
   case 92:
-/* Line 1787 of yacc.c  */
 #line 500 "cc.y"
     {
 		(yyval.node) = new(ODWHILE, (yyvsp[(5) - (7)].node), (yyvsp[(2) - (7)].node));
@@ -2637,7 +2546,6 @@ yyreduce:
     break;
 
   case 93:
-/* Line 1787 of yacc.c  */
 #line 504 "cc.y"
     {
 		(yyval.node) = new(ORETURN, (yyvsp[(2) - (3)].node), Z);
@@ -2646,7 +2554,6 @@ yyreduce:
     break;
 
   case 94:
-/* Line 1787 of yacc.c  */
 #line 509 "cc.y"
     {
 		(yyval.node) = new(OCONST, Z, Z);
@@ -2664,7 +2571,6 @@ yyreduce:
     break;
 
   case 95:
-/* Line 1787 of yacc.c  */
 #line 523 "cc.y"
     {
 		(yyval.node) = new(OBREAK, Z, Z);
@@ -2672,7 +2578,6 @@ yyreduce:
     break;
 
   case 96:
-/* Line 1787 of yacc.c  */
 #line 527 "cc.y"
     {
 		(yyval.node) = new(OCONTINUE, Z, Z);
@@ -2680,7 +2585,6 @@ yyreduce:
     break;
 
   case 97:
-/* Line 1787 of yacc.c  */
 #line 531 "cc.y"
     {
 		(yyval.node) = new(OGOTO, dcllabel((yyvsp[(2) - (3)].sym), 0), Z);
@@ -2688,7 +2592,6 @@ yyreduce:
     break;
 
   case 98:
-/* Line 1787 of yacc.c  */
 #line 535 "cc.y"
     {
 		(yyval.node) = new(OUSED, (yyvsp[(3) - (5)].node), Z);
@@ -2696,7 +2599,6 @@ yyreduce:
     break;
 
   case 99:
-/* Line 1787 of yacc.c  */
 #line 539 "cc.y"
     {
 		(yyval.node) = new(OPREFETCH, (yyvsp[(3) - (5)].node), Z);
@@ -2704,7 +2606,6 @@ yyreduce:
     break;
 
   case 100:
-/* Line 1787 of yacc.c  */
 #line 543 "cc.y"
     {
 		(yyval.node) = new(OSET, (yyvsp[(3) - (5)].node), Z);
@@ -2712,7 +2613,6 @@ yyreduce:
     break;
 
   case 101:
-/* Line 1787 of yacc.c  */
 #line 548 "cc.y"
     {
 		(yyval.node) = Z;
@@ -2720,7 +2620,6 @@ yyreduce:
     break;
 
   case 103:
-/* Line 1787 of yacc.c  */
 #line 554 "cc.y"
     {
 		(yyval.node) = Z;
@@ -2728,7 +2627,6 @@ yyreduce:
     break;
 
   case 105:
-/* Line 1787 of yacc.c  */
 #line 561 "cc.y"
     {
 		(yyval.node) = new(OCAST, (yyvsp[(1) - (1)].node), Z);
@@ -2737,7 +2635,6 @@ yyreduce:
     break;
 
   case 107:
-/* Line 1787 of yacc.c  */
 #line 569 "cc.y"
     {
 		(yyval.node) = new(OCOMMA, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
@@ -2745,7 +2642,6 @@ yyreduce:
     break;
 
   case 109:
-/* Line 1787 of yacc.c  */
 #line 576 "cc.y"
     {
 		(yyval.node) = new(OMUL, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
@@ -2753,7 +2649,6 @@ yyreduce:
     break;
 
   case 110:
-/* Line 1787 of yacc.c  */
 #line 580 "cc.y"
     {
 		(yyval.node) = new(ODIV, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
@@ -2761,7 +2656,6 @@ yyreduce:
     break;
 
   case 111:
-/* Line 1787 of yacc.c  */
 #line 584 "cc.y"
     {
 		(yyval.node) = new(OMOD, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
@@ -2769,7 +2663,6 @@ yyreduce:
     break;
 
   case 112:
-/* Line 1787 of yacc.c  */
 #line 588 "cc.y"
     {
 		(yyval.node) = new(OADD, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
@@ -2777,7 +2670,6 @@ yyreduce:
     break;
 
   case 113:
-/* Line 1787 of yacc.c  */
 #line 592 "cc.y"
     {
 		(yyval.node) = new(OSUB, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
@@ -2785,7 +2677,6 @@ yyreduce:
     break;
 
   case 114:
-/* Line 1787 of yacc.c  */
 #line 596 "cc.y"
     {
 		(yyval.node) = new(OASHR, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
@@ -2793,7 +2684,6 @@ yyreduce:
     break;
 
   case 115:
-/* Line 1787 of yacc.c  */
 #line 600 "cc.y"
     {
 		(yyval.node) = new(OASHL, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
@@ -2801,7 +2691,6 @@ yyreduce:
     break;
 
   case 116:
-/* Line 1787 of yacc.c  */
 #line 604 "cc.y"
     {
 		(yyval.node) = new(OLT, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
@@ -2809,7 +2698,6 @@ yyreduce:
     break;
 
   case 117:
-/* Line 1787 of yacc.c  */
 #line 608 "cc.y"
     {
 		(yyval.node) = new(OGT, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
@@ -2817,7 +2705,6 @@ yyreduce:
     break;
 
   case 118:
-/* Line 1787 of yacc.c  */
 #line 612 "cc.y"
     {
 		(yyval.node) = new(OLE, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
@@ -2825,7 +2712,6 @@ yyreduce:
     break;
 
   case 119:
-/* Line 1787 of yacc.c  */
 #line 616 "cc.y"
     {
 		(yyval.node) = new(OGE, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
@@ -2833,7 +2719,6 @@ yyreduce:
     break;
 
   case 120:
-/* Line 1787 of yacc.c  */
 #line 620 "cc.y"
     {
 		(yyval.node) = new(OEQ, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
@@ -2841,7 +2726,6 @@ yyreduce:
     break;
 
   case 121:
-/* Line 1787 of yacc.c  */
 #line 624 "cc.y"
     {
 		(yyval.node) = new(ONE, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
@@ -2849,7 +2733,6 @@ yyreduce:
     break;
 
   case 122:
-/* Line 1787 of yacc.c  */
 #line 628 "cc.y"
     {
 		(yyval.node) = new(OAND, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
@@ -2857,7 +2740,6 @@ yyreduce:
     break;
 
   case 123:
-/* Line 1787 of yacc.c  */
 #line 632 "cc.y"
     {
 		(yyval.node) = new(OXOR, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
@@ -2865,7 +2747,6 @@ yyreduce:
     break;
 
   case 124:
-/* Line 1787 of yacc.c  */
 #line 636 "cc.y"
     {
 		(yyval.node) = new(OOR, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
@@ -2873,7 +2754,6 @@ yyreduce:
     break;
 
   case 125:
-/* Line 1787 of yacc.c  */
 #line 640 "cc.y"
     {
 		(yyval.node) = new(OANDAND, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
@@ -2881,7 +2761,6 @@ yyreduce:
     break;
 
   case 126:
-/* Line 1787 of yacc.c  */
 #line 644 "cc.y"
     {
 		(yyval.node) = new(OOROR, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
@@ -2889,7 +2768,6 @@ yyreduce:
     break;
 
   case 127:
-/* Line 1787 of yacc.c  */
 #line 648 "cc.y"
     {
 		(yyval.node) = new(OCOND, (yyvsp[(1) - (5)].node), new(OLIST, (yyvsp[(3) - (5)].node), (yyvsp[(5) - (5)].node)));
@@ -2897,7 +2775,6 @@ yyreduce:
     break;
 
   case 128:
-/* Line 1787 of yacc.c  */
 #line 652 "cc.y"
     {
 		(yyval.node) = new(OAS, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
@@ -2905,7 +2782,6 @@ yyreduce:
     break;
 
   case 129:
-/* Line 1787 of yacc.c  */
 #line 656 "cc.y"
     {
 		(yyval.node) = new(OASADD, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
@@ -2913,7 +2789,6 @@ yyreduce:
     break;
 
   case 130:
-/* Line 1787 of yacc.c  */
 #line 660 "cc.y"
     {
 		(yyval.node) = new(OASSUB, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
@@ -2921,7 +2796,6 @@ yyreduce:
     break;
 
   case 131:
-/* Line 1787 of yacc.c  */
 #line 664 "cc.y"
     {
 		(yyval.node) = new(OASMUL, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
@@ -2929,7 +2803,6 @@ yyreduce:
     break;
 
   case 132:
-/* Line 1787 of yacc.c  */
 #line 668 "cc.y"
     {
 		(yyval.node) = new(OASDIV, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
@@ -2937,7 +2810,6 @@ yyreduce:
     break;
 
   case 133:
-/* Line 1787 of yacc.c  */
 #line 672 "cc.y"
     {
 		(yyval.node) = new(OASMOD, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
@@ -2945,7 +2817,6 @@ yyreduce:
     break;
 
   case 134:
-/* Line 1787 of yacc.c  */
 #line 676 "cc.y"
     {
 		(yyval.node) = new(OASASHL, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
@@ -2953,7 +2824,6 @@ yyreduce:
     break;
 
   case 135:
-/* Line 1787 of yacc.c  */
 #line 680 "cc.y"
     {
 		(yyval.node) = new(OASASHR, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
@@ -2961,7 +2831,6 @@ yyreduce:
     break;
 
   case 136:
-/* Line 1787 of yacc.c  */
 #line 684 "cc.y"
     {
 		(yyval.node) = new(OASAND, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
@@ -2969,7 +2838,6 @@ yyreduce:
     break;
 
   case 137:
-/* Line 1787 of yacc.c  */
 #line 688 "cc.y"
     {
 		(yyval.node) = new(OASXOR, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
@@ -2977,7 +2845,6 @@ yyreduce:
     break;
 
   case 138:
-/* Line 1787 of yacc.c  */
 #line 692 "cc.y"
     {
 		(yyval.node) = new(OASOR, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
@@ -2985,7 +2852,6 @@ yyreduce:
     break;
 
   case 140:
-/* Line 1787 of yacc.c  */
 #line 699 "cc.y"
     {
 		(yyval.node) = new(OCAST, (yyvsp[(5) - (5)].node), Z);
@@ -2996,7 +2862,6 @@ yyreduce:
     break;
 
   case 141:
-/* Line 1787 of yacc.c  */
 #line 706 "cc.y"
     {
 		(yyval.node) = new(OSTRUCT, (yyvsp[(6) - (7)].node), Z);
@@ -3006,7 +2871,6 @@ yyreduce:
     break;
 
   case 143:
-/* Line 1787 of yacc.c  */
 #line 715 "cc.y"
     {
 		(yyval.node) = new(OIND, (yyvsp[(2) - (2)].node), Z);
@@ -3014,7 +2878,6 @@ yyreduce:
     break;
 
   case 144:
-/* Line 1787 of yacc.c  */
 #line 719 "cc.y"
     {
 		(yyval.node) = new(OADDR, (yyvsp[(2) - (2)].node), Z);
@@ -3022,7 +2885,6 @@ yyreduce:
     break;
 
   case 145:
-/* Line 1787 of yacc.c  */
 #line 723 "cc.y"
     {
 		(yyval.node) = new(OPOS, (yyvsp[(2) - (2)].node), Z);
@@ -3030,7 +2892,6 @@ yyreduce:
     break;
 
   case 146:
-/* Line 1787 of yacc.c  */
 #line 727 "cc.y"
     {
 		(yyval.node) = new(ONEG, (yyvsp[(2) - (2)].node), Z);
@@ -3038,7 +2899,6 @@ yyreduce:
     break;
 
   case 147:
-/* Line 1787 of yacc.c  */
 #line 731 "cc.y"
     {
 		(yyval.node) = new(ONOT, (yyvsp[(2) - (2)].node), Z);
@@ -3046,7 +2906,6 @@ yyreduce:
     break;
 
   case 148:
-/* Line 1787 of yacc.c  */
 #line 735 "cc.y"
     {
 		(yyval.node) = new(OCOM, (yyvsp[(2) - (2)].node), Z);
@@ -3054,7 +2913,6 @@ yyreduce:
     break;
 
   case 149:
-/* Line 1787 of yacc.c  */
 #line 739 "cc.y"
     {
 		(yyval.node) = new(OPREINC, (yyvsp[(2) - (2)].node), Z);
@@ -3062,7 +2920,6 @@ yyreduce:
     break;
 
   case 150:
-/* Line 1787 of yacc.c  */
 #line 743 "cc.y"
     {
 		(yyval.node) = new(OPREDEC, (yyvsp[(2) - (2)].node), Z);
@@ -3070,7 +2927,6 @@ yyreduce:
     break;
 
   case 151:
-/* Line 1787 of yacc.c  */
 #line 747 "cc.y"
     {
 		(yyval.node) = new(OSIZE, (yyvsp[(2) - (2)].node), Z);
@@ -3078,7 +2934,6 @@ yyreduce:
     break;
 
   case 152:
-/* Line 1787 of yacc.c  */
 #line 751 "cc.y"
     {
 		(yyval.node) = new(OSIGN, (yyvsp[(2) - (2)].node), Z);
@@ -3086,7 +2941,6 @@ yyreduce:
     break;
 
   case 153:
-/* Line 1787 of yacc.c  */
 #line 757 "cc.y"
     {
 		(yyval.node) = (yyvsp[(2) - (3)].node);
@@ -3094,7 +2948,6 @@ yyreduce:
     break;
 
   case 154:
-/* Line 1787 of yacc.c  */
 #line 761 "cc.y"
     {
 		(yyval.node) = new(OSIZE, Z, Z);
@@ -3104,7 +2957,6 @@ yyreduce:
     break;
 
   case 155:
-/* Line 1787 of yacc.c  */
 #line 767 "cc.y"
     {
 		(yyval.node) = new(OSIGN, Z, Z);
@@ -3114,7 +2966,6 @@ yyreduce:
     break;
 
   case 156:
-/* Line 1787 of yacc.c  */
 #line 773 "cc.y"
     {
 		(yyval.node) = new(OFUNC, (yyvsp[(1) - (4)].node), Z);
@@ -3126,7 +2977,6 @@ yyreduce:
     break;
 
   case 157:
-/* Line 1787 of yacc.c  */
 #line 781 "cc.y"
     {
 		(yyval.node) = new(OIND, new(OADD, (yyvsp[(1) - (4)].node), (yyvsp[(3) - (4)].node)), Z);
@@ -3134,7 +2984,6 @@ yyreduce:
     break;
 
   case 158:
-/* Line 1787 of yacc.c  */
 #line 785 "cc.y"
     {
 		(yyval.node) = new(ODOT, new(OIND, (yyvsp[(1) - (3)].node), Z), Z);
@@ -3143,7 +2992,6 @@ yyreduce:
     break;
 
   case 159:
-/* Line 1787 of yacc.c  */
 #line 790 "cc.y"
     {
 		(yyval.node) = new(ODOT, (yyvsp[(1) - (3)].node), Z);
@@ -3152,7 +3000,6 @@ yyreduce:
     break;
 
   case 160:
-/* Line 1787 of yacc.c  */
 #line 795 "cc.y"
     {
 		(yyval.node) = new(OPOSTINC, (yyvsp[(1) - (2)].node), Z);
@@ -3160,7 +3007,6 @@ yyreduce:
     break;
 
   case 161:
-/* Line 1787 of yacc.c  */
 #line 799 "cc.y"
     {
 		(yyval.node) = new(OPOSTDEC, (yyvsp[(1) - (2)].node), Z);
@@ -3168,7 +3014,6 @@ yyreduce:
     break;
 
   case 163:
-/* Line 1787 of yacc.c  */
 #line 804 "cc.y"
     {
 		(yyval.node) = new(OCONST, Z, Z);
@@ -3179,7 +3024,6 @@ yyreduce:
     break;
 
   case 164:
-/* Line 1787 of yacc.c  */
 #line 811 "cc.y"
     {
 		(yyval.node) = new(OCONST, Z, Z);
@@ -3190,7 +3034,6 @@ yyreduce:
     break;
 
   case 165:
-/* Line 1787 of yacc.c  */
 #line 818 "cc.y"
     {
 		(yyval.node) = new(OCONST, Z, Z);
@@ -3201,7 +3044,6 @@ yyreduce:
     break;
 
   case 166:
-/* Line 1787 of yacc.c  */
 #line 825 "cc.y"
     {
 		(yyval.node) = new(OCONST, Z, Z);
@@ -3212,7 +3054,6 @@ yyreduce:
     break;
 
   case 167:
-/* Line 1787 of yacc.c  */
 #line 832 "cc.y"
     {
 		(yyval.node) = new(OCONST, Z, Z);
@@ -3223,7 +3064,6 @@ yyreduce:
     break;
 
   case 168:
-/* Line 1787 of yacc.c  */
 #line 839 "cc.y"
     {
 		(yyval.node) = new(OCONST, Z, Z);
@@ -3234,7 +3074,6 @@ yyreduce:
     break;
 
   case 169:
-/* Line 1787 of yacc.c  */
 #line 846 "cc.y"
     {
 		(yyval.node) = new(OCONST, Z, Z);
@@ -3245,7 +3084,6 @@ yyreduce:
     break;
 
   case 170:
-/* Line 1787 of yacc.c  */
 #line 853 "cc.y"
     {
 		(yyval.node) = new(OCONST, Z, Z);
@@ -3256,7 +3094,6 @@ yyreduce:
     break;
 
   case 173:
-/* Line 1787 of yacc.c  */
 #line 864 "cc.y"
     {
 		(yyval.node) = new(OSTRING, Z, Z);
@@ -3270,7 +3107,6 @@ yyreduce:
     break;
 
   case 174:
-/* Line 1787 of yacc.c  */
 #line 874 "cc.y"
     {
 		char *s;
@@ -3290,7 +3126,6 @@ yyreduce:
     break;
 
   case 175:
-/* Line 1787 of yacc.c  */
 #line 892 "cc.y"
     {
 		(yyval.node) = new(OLSTRING, Z, Z);
@@ -3304,7 +3139,6 @@ yyreduce:
     break;
 
   case 176:
-/* Line 1787 of yacc.c  */
 #line 902 "cc.y"
     {
 		char *s;
@@ -3324,7 +3158,6 @@ yyreduce:
     break;
 
   case 177:
-/* Line 1787 of yacc.c  */
 #line 919 "cc.y"
     {
 		(yyval.node) = Z;
@@ -3332,7 +3165,6 @@ yyreduce:
     break;
 
   case 180:
-/* Line 1787 of yacc.c  */
 #line 927 "cc.y"
     {
 		(yyval.node) = new(OLIST, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
@@ -3340,7 +3172,6 @@ yyreduce:
     break;
 
   case 181:
-/* Line 1787 of yacc.c  */
 #line 933 "cc.y"
     {
 		(yyval.tyty).t1 = strf;
@@ -3357,7 +3188,6 @@ yyreduce:
     break;
 
   case 182:
-/* Line 1787 of yacc.c  */
 #line 946 "cc.y"
     {
 		(yyval.type) = strf;
@@ -3369,7 +3199,6 @@ yyreduce:
     break;
 
   case 183:
-/* Line 1787 of yacc.c  */
 #line 955 "cc.y"
     {
 		lastclass = CXXX;
@@ -3378,7 +3207,6 @@ yyreduce:
     break;
 
   case 185:
-/* Line 1787 of yacc.c  */
 #line 963 "cc.y"
     {
 		(yyval.tycl).t = (yyvsp[(1) - (1)].type);
@@ -3387,7 +3215,6 @@ yyreduce:
     break;
 
   case 186:
-/* Line 1787 of yacc.c  */
 #line 968 "cc.y"
     {
 		(yyval.tycl).t = simplet((yyvsp[(1) - (1)].lval));
@@ -3396,7 +3223,6 @@ yyreduce:
     break;
 
   case 187:
-/* Line 1787 of yacc.c  */
 #line 973 "cc.y"
     {
 		(yyval.tycl).t = simplet((yyvsp[(1) - (1)].lval));
@@ -3406,7 +3232,6 @@ yyreduce:
     break;
 
   case 188:
-/* Line 1787 of yacc.c  */
 #line 979 "cc.y"
     {
 		(yyval.tycl).t = (yyvsp[(1) - (2)].type);
@@ -3418,7 +3243,6 @@ yyreduce:
     break;
 
   case 189:
-/* Line 1787 of yacc.c  */
 #line 987 "cc.y"
     {
 		(yyval.tycl).t = simplet(typebitor((yyvsp[(1) - (2)].lval), (yyvsp[(2) - (2)].lval)));
@@ -3428,7 +3252,6 @@ yyreduce:
     break;
 
   case 190:
-/* Line 1787 of yacc.c  */
 #line 993 "cc.y"
     {
 		(yyval.tycl).t = (yyvsp[(2) - (3)].type);
@@ -3438,7 +3261,6 @@ yyreduce:
     break;
 
   case 191:
-/* Line 1787 of yacc.c  */
 #line 999 "cc.y"
     {
 		(yyval.tycl).t = simplet((yyvsp[(2) - (2)].lval));
@@ -3448,7 +3270,6 @@ yyreduce:
     break;
 
   case 192:
-/* Line 1787 of yacc.c  */
 #line 1005 "cc.y"
     {
 		(yyval.tycl).t = simplet(typebitor((yyvsp[(2) - (3)].lval), (yyvsp[(3) - (3)].lval)));
@@ -3458,7 +3279,6 @@ yyreduce:
     break;
 
   case 193:
-/* Line 1787 of yacc.c  */
 #line 1013 "cc.y"
     {
 		(yyval.type) = (yyvsp[(1) - (1)].tycl).t;
@@ -3468,7 +3288,6 @@ yyreduce:
     break;
 
   case 194:
-/* Line 1787 of yacc.c  */
 #line 1021 "cc.y"
     {
 		lasttype = (yyvsp[(1) - (1)].tycl).t;
@@ -3477,7 +3296,6 @@ yyreduce:
     break;
 
   case 195:
-/* Line 1787 of yacc.c  */
 #line 1028 "cc.y"
     {
 		dotag((yyvsp[(2) - (2)].sym), TSTRUCT, 0);
@@ -3486,7 +3304,6 @@ yyreduce:
     break;
 
   case 196:
-/* Line 1787 of yacc.c  */
 #line 1033 "cc.y"
     {
 		dotag((yyvsp[(2) - (2)].sym), TSTRUCT, autobn);
@@ -3494,7 +3311,6 @@ yyreduce:
     break;
 
   case 197:
-/* Line 1787 of yacc.c  */
 #line 1037 "cc.y"
     {
 		(yyval.type) = (yyvsp[(2) - (4)].sym)->suetag;
@@ -3506,9 +3322,9 @@ yyreduce:
     break;
 
   case 198:
-/* Line 1787 of yacc.c  */
 #line 1045 "cc.y"
     {
+		diag(Z, "struct must have tag");
 		taggen++;
 		sprint(symb, "_%d_", taggen);
 		(yyval.type) = dotag(lookup(), TSTRUCT, autobn);
@@ -3518,8 +3334,7 @@ yyreduce:
     break;
 
   case 199:
-/* Line 1787 of yacc.c  */
-#line 1053 "cc.y"
+#line 1054 "cc.y"
     {
 		dotag((yyvsp[(2) - (2)].sym), TUNION, 0);
 		(yyval.type) = (yyvsp[(2) - (2)].sym)->suetag;
@@ -3527,16 +3342,14 @@ yyreduce:
     break;
 
   case 200:
-/* Line 1787 of yacc.c  */
-#line 1058 "cc.y"
+#line 1059 "cc.y"
     {
 		dotag((yyvsp[(2) - (2)].sym), TUNION, autobn);
 	}
     break;
 
   case 201:
-/* Line 1787 of yacc.c  */
-#line 1062 "cc.y"
+#line 1063 "cc.y"
     {
 		(yyval.type) = (yyvsp[(2) - (4)].sym)->suetag;
 		if((yyval.type)->link != T)
@@ -3547,8 +3360,7 @@ yyreduce:
     break;
 
   case 202:
-/* Line 1787 of yacc.c  */
-#line 1070 "cc.y"
+#line 1071 "cc.y"
     {
 		taggen++;
 		sprint(symb, "_%d_", taggen);
@@ -3559,8 +3371,7 @@ yyreduce:
     break;
 
   case 203:
-/* Line 1787 of yacc.c  */
-#line 1078 "cc.y"
+#line 1079 "cc.y"
     {
 		dotag((yyvsp[(2) - (2)].sym), TENUM, 0);
 		(yyval.type) = (yyvsp[(2) - (2)].sym)->suetag;
@@ -3571,16 +3382,14 @@ yyreduce:
     break;
 
   case 204:
-/* Line 1787 of yacc.c  */
-#line 1086 "cc.y"
+#line 1087 "cc.y"
     {
 		dotag((yyvsp[(2) - (2)].sym), TENUM, autobn);
 	}
     break;
 
   case 205:
-/* Line 1787 of yacc.c  */
-#line 1090 "cc.y"
+#line 1091 "cc.y"
     {
 		en.tenum = T;
 		en.cenum = T;
@@ -3588,8 +3397,7 @@ yyreduce:
     break;
 
   case 206:
-/* Line 1787 of yacc.c  */
-#line 1095 "cc.y"
+#line 1096 "cc.y"
     {
 		(yyval.type) = (yyvsp[(2) - (7)].sym)->suetag;
 		if((yyval.type)->link != T)
@@ -3604,8 +3412,7 @@ yyreduce:
     break;
 
   case 207:
-/* Line 1787 of yacc.c  */
-#line 1107 "cc.y"
+#line 1108 "cc.y"
     {
 		en.tenum = T;
 		en.cenum = T;
@@ -3613,186 +3420,158 @@ yyreduce:
     break;
 
   case 208:
-/* Line 1787 of yacc.c  */
-#line 1112 "cc.y"
+#line 1113 "cc.y"
     {
 		(yyval.type) = en.tenum;
 	}
     break;
 
   case 209:
-/* Line 1787 of yacc.c  */
-#line 1116 "cc.y"
+#line 1117 "cc.y"
     {
 		(yyval.type) = tcopy((yyvsp[(1) - (1)].sym)->type);
 	}
     break;
 
   case 211:
-/* Line 1787 of yacc.c  */
-#line 1123 "cc.y"
+#line 1124 "cc.y"
     {
 		(yyval.lval) = typebitor((yyvsp[(1) - (2)].lval), (yyvsp[(2) - (2)].lval));
 	}
     break;
 
   case 212:
-/* Line 1787 of yacc.c  */
-#line 1128 "cc.y"
+#line 1129 "cc.y"
     {
 		(yyval.lval) = 0;
 	}
     break;
 
   case 213:
-/* Line 1787 of yacc.c  */
-#line 1132 "cc.y"
+#line 1133 "cc.y"
     {
 		(yyval.lval) = typebitor((yyvsp[(1) - (2)].lval), (yyvsp[(2) - (2)].lval));
 	}
     break;
 
   case 218:
-/* Line 1787 of yacc.c  */
-#line 1144 "cc.y"
+#line 1145 "cc.y"
     {
 		(yyval.lval) = typebitor((yyvsp[(1) - (2)].lval), (yyvsp[(2) - (2)].lval));
 	}
     break;
 
   case 221:
-/* Line 1787 of yacc.c  */
-#line 1154 "cc.y"
+#line 1155 "cc.y"
     {
 		doenum((yyvsp[(1) - (1)].sym), Z);
 	}
     break;
 
   case 222:
-/* Line 1787 of yacc.c  */
-#line 1158 "cc.y"
+#line 1159 "cc.y"
     {
 		doenum((yyvsp[(1) - (3)].sym), (yyvsp[(3) - (3)].node));
 	}
     break;
 
   case 225:
-/* Line 1787 of yacc.c  */
-#line 1165 "cc.y"
+#line 1166 "cc.y"
     { (yyval.lval) = BCHAR; }
     break;
 
   case 226:
-/* Line 1787 of yacc.c  */
-#line 1166 "cc.y"
+#line 1167 "cc.y"
     { (yyval.lval) = BSHORT; }
     break;
 
   case 227:
-/* Line 1787 of yacc.c  */
-#line 1167 "cc.y"
+#line 1168 "cc.y"
     { (yyval.lval) = BINT; }
     break;
 
   case 228:
-/* Line 1787 of yacc.c  */
-#line 1168 "cc.y"
+#line 1169 "cc.y"
     { (yyval.lval) = BLONG; }
     break;
 
   case 229:
-/* Line 1787 of yacc.c  */
-#line 1169 "cc.y"
+#line 1170 "cc.y"
     { (yyval.lval) = BSIGNED; }
     break;
 
   case 230:
-/* Line 1787 of yacc.c  */
-#line 1170 "cc.y"
+#line 1171 "cc.y"
     { (yyval.lval) = BUNSIGNED; }
     break;
 
   case 231:
-/* Line 1787 of yacc.c  */
-#line 1171 "cc.y"
+#line 1172 "cc.y"
     { (yyval.lval) = BFLOAT; }
     break;
 
   case 232:
-/* Line 1787 of yacc.c  */
-#line 1172 "cc.y"
+#line 1173 "cc.y"
     { (yyval.lval) = BDOUBLE; }
     break;
 
   case 233:
-/* Line 1787 of yacc.c  */
-#line 1173 "cc.y"
+#line 1174 "cc.y"
     { (yyval.lval) = BVOID; }
     break;
 
   case 234:
-/* Line 1787 of yacc.c  */
-#line 1176 "cc.y"
+#line 1177 "cc.y"
     { (yyval.lval) = BAUTO; }
     break;
 
   case 235:
-/* Line 1787 of yacc.c  */
-#line 1177 "cc.y"
+#line 1178 "cc.y"
     { (yyval.lval) = BSTATIC; }
     break;
 
   case 236:
-/* Line 1787 of yacc.c  */
-#line 1178 "cc.y"
+#line 1179 "cc.y"
     { (yyval.lval) = BEXTERN; }
     break;
 
   case 237:
-/* Line 1787 of yacc.c  */
-#line 1179 "cc.y"
+#line 1180 "cc.y"
     { (yyval.lval) = BTYPEDEF; }
     break;
 
   case 238:
-/* Line 1787 of yacc.c  */
-#line 1180 "cc.y"
+#line 1181 "cc.y"
     { (yyval.lval) = BTYPESTR; }
     break;
 
   case 239:
-/* Line 1787 of yacc.c  */
-#line 1181 "cc.y"
+#line 1182 "cc.y"
     { (yyval.lval) = BREGISTER; }
     break;
 
   case 240:
-/* Line 1787 of yacc.c  */
-#line 1182 "cc.y"
+#line 1183 "cc.y"
     { (yyval.lval) = 0; }
     break;
 
   case 241:
-/* Line 1787 of yacc.c  */
-#line 1185 "cc.y"
+#line 1186 "cc.y"
     { (yyval.lval) = BCONSTNT; }
     break;
 
   case 242:
-/* Line 1787 of yacc.c  */
-#line 1186 "cc.y"
+#line 1187 "cc.y"
     { (yyval.lval) = BVOLATILE; }
     break;
 
   case 243:
-/* Line 1787 of yacc.c  */
-#line 1187 "cc.y"
+#line 1188 "cc.y"
     { (yyval.lval) = 0; }
     break;
 
   case 244:
-/* Line 1787 of yacc.c  */
-#line 1191 "cc.y"
+#line 1192 "cc.y"
     {
 		(yyval.node) = new(ONAME, Z, Z);
 		if((yyvsp[(1) - (1)].sym)->class == CLOCAL)
@@ -3809,8 +3588,7 @@ yyreduce:
     break;
 
   case 245:
-/* Line 1787 of yacc.c  */
-#line 1206 "cc.y"
+#line 1207 "cc.y"
     {
 		(yyval.node) = new(ONAME, Z, Z);
 		(yyval.node)->sym = (yyvsp[(1) - (1)].sym);
@@ -3824,21 +3602,10 @@ yyreduce:
     break;
 
 
-/* Line 1787 of yacc.c  */
-#line 3829 "y.tab.c"
+/* Line 1267 of yacc.c.  */
+#line 3607 "y.tab.c"
       default: break;
     }
-  /* User semantic actions sometimes alter yychar, and that requires
-     that yytoken be updated with the new translation.  We take the
-     approach of translating immediately before every use of yytoken.
-     One alternative is translating here after every semantic action,
-     but that translation would be missed if the semantic action invokes
-     YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or
-     if it invokes YYBACKUP.  In the case of YYABORT or YYACCEPT, an
-     incorrect destructor might then be invoked immediately.  In the
-     case of YYERROR or YYBACKUP, subsequent parser actions might lead
-     to an incorrect destructor call or verbose syntax error message
-     before the lookahead is translated.  */
   YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
 
   YYPOPSTACK (yylen);
@@ -3847,6 +3614,7 @@ yyreduce:
 
   *++yyvsp = yyval;
 
+
   /* Now `shift' the result of the reduction.  Determine what state
      that goes to, based on the state we popped back to and the rule
      number reduced by.  */
@@ -3866,10 +3634,6 @@ yyreduce:
 | yyerrlab -- here on detecting error |
 `------------------------------------*/
 yyerrlab:
-  /* Make sure we have latest lookahead translation.  See comments at
-     user semantic actions for why this is necessary.  */
-  yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar);
-
   /* If not already recovering from an error, report this error.  */
   if (!yyerrstatus)
     {
@@ -3877,36 +3641,37 @@ yyerrlab:
 #if ! YYERROR_VERBOSE
       yyerror (YY_("syntax error"));
 #else
-# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \
-                                        yyssp, yytoken)
       {
-        char const *yymsgp = YY_("syntax error");
-        int yysyntax_error_status;
-        yysyntax_error_status = YYSYNTAX_ERROR;
-        if (yysyntax_error_status == 0)
-          yymsgp = yymsg;
-        else if (yysyntax_error_status == 1)
-          {
-            if (yymsg != yymsgbuf)
-              YYSTACK_FREE (yymsg);
-            yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc);
-            if (!yymsg)
-              {
-                yymsg = yymsgbuf;
-                yymsg_alloc = sizeof yymsgbuf;
-                yysyntax_error_status = 2;
-              }
-            else
-              {
-                yysyntax_error_status = YYSYNTAX_ERROR;
-                yymsgp = yymsg;
-              }
-          }
-        yyerror (yymsgp);
-        if (yysyntax_error_status == 2)
-          goto yyexhaustedlab;
+	YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
+	if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
+	  {
+	    YYSIZE_T yyalloc = 2 * yysize;
+	    if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
+	      yyalloc = YYSTACK_ALLOC_MAXIMUM;
+	    if (yymsg != yymsgbuf)
+	      YYSTACK_FREE (yymsg);
+	    yymsg = (char *) YYSTACK_ALLOC (yyalloc);
+	    if (yymsg)
+	      yymsg_alloc = yyalloc;
+	    else
+	      {
+		yymsg = yymsgbuf;
+		yymsg_alloc = sizeof yymsgbuf;
+	      }
+	  }
+
+	if (0 < yysize && yysize <= yymsg_alloc)
+	  {
+	    (void) yysyntax_error (yymsg, yystate, yychar);
+	    yyerror (yymsg);
+	  }
+	else
+	  {
+	    yyerror (YY_("syntax error"));
+	    if (yysize != 0)
+	      goto yyexhaustedlab;
+	  }
       }
-# undef YYSYNTAX_ERROR
 #endif
     }
 
@@ -3914,7 +3679,7 @@ yyerrlab:
 
   if (yyerrstatus == 3)
     {
-      /* If just tried and failed to reuse lookahead token after an
+      /* If just tried and failed to reuse look-ahead token after an
 	 error, discard it.  */
 
       if (yychar <= YYEOF)
@@ -3931,7 +3696,7 @@ yyerrlab:
 	}
     }
 
-  /* Else will try to reuse lookahead token after shifting the error
+  /* Else will try to reuse look-ahead token after shifting the error
      token.  */
   goto yyerrlab1;
 
@@ -3965,7 +3730,7 @@ yyerrlab1:
   for (;;)
     {
       yyn = yypact[yystate];
-      if (!yypact_value_is_default (yyn))
+      if (yyn != YYPACT_NINF)
 	{
 	  yyn += YYTERROR;
 	  if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
@@ -3988,9 +3753,10 @@ yyerrlab1:
       YY_STACK_PRINT (yyss, yyssp);
     }
 
-  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+  if (yyn == YYFINAL)
+    YYACCEPT;
+
   *++yyvsp = yylval;
-  YY_IGNORE_MAYBE_UNINITIALIZED_END
 
 
   /* Shift the error token.  */
@@ -4014,7 +3780,7 @@ yyabortlab:
   yyresult = 1;
   goto yyreturn;
 
-#if !defined yyoverflow || YYERROR_VERBOSE
+#ifndef yyoverflow
 /*-------------------------------------------------.
 | yyexhaustedlab -- memory exhaustion comes here.  |
 `-------------------------------------------------*/
@@ -4025,14 +3791,9 @@ yyexhaustedlab:
 #endif
 
 yyreturn:
-  if (yychar != YYEMPTY)
-    {
-      /* Make sure we have latest lookahead translation.  See comments at
-         user semantic actions for why this is necessary.  */
-      yytoken = YYTRANSLATE (yychar);
-      yydestruct ("Cleanup: discarding lookahead",
-                  yytoken, &yylval);
-    }
+  if (yychar != YYEOF && yychar != YYEMPTY)
+     yydestruct ("Cleanup: discarding lookahead",
+		 yytoken, &yylval);
   /* Do not reclaim the symbols of the rule which action triggered
      this YYABORT or YYACCEPT.  */
   YYPOPSTACK (yylen);
@@ -4056,6 +3817,6 @@ yyreturn:
 }
 
 
-/* Line 2050 of yacc.c  */
-#line 1219 "cc.y"
+#line 1220 "cc.y"
+
 
diff --git a/src/cmd/cc/y.tab.h b/src/cmd/cc/y.tab.h
index b26d659..32daca9 100644
--- a/src/cmd/cc/y.tab.h
+++ b/src/cmd/cc/y.tab.h
@@ -1,21 +1,24 @@
-/* A Bison parser, made by GNU Bison 2.7.12-4996.  */
+/* A Bison parser, made by GNU Bison 2.3.  */
 
-/* Bison interface for Yacc-like parsers in C
-   
-      Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc.
-   
-   This program is free software: you can redistribute it and/or modify
+/* Skeleton interface for Bison's Yacc-like parsers in C
+
+   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+   Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation, either version 3 of the License, or
-   (at your option) any later version.
-   
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-   
+
    You should have received a copy of the GNU General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
 
 /* As a special exception, you may create a larger work that contains
    part or all of the Bison parser skeleton and distribute that work
@@ -26,20 +29,10 @@
    special exception, which will cause the skeleton and the resulting
    Bison output files to be licensed under the GNU General Public
    License without this special exception.
-   
+
    This special exception was added by the Free Software Foundation in
    version 2.2 of Bison.  */
 
-#ifndef YY_YY_Y_TAB_H_INCLUDED
-# define YY_YY_Y_TAB_H_INCLUDED
-/* Enabling traces.  */
-#ifndef YYDEBUG
-# define YYDEBUG 0
-#endif
-#if YYDEBUG
-extern int yydebug;
-#endif
-
 /* Tokens.  */
 #ifndef YYTOKENTYPE
 # define YYTOKENTYPE
@@ -196,12 +189,11 @@ extern int yydebug;
 
 
 
+
 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
 typedef union YYSTYPE
-{
-/* Line 2053 of yacc.c  */
 #line 36 "cc.y"
-
+{
 	Node*	node;
 	Sym*	sym;
 	Type*	type;
@@ -225,30 +217,14 @@ typedef union YYSTYPE
 	int32	lval;
 	double	dval;
 	vlong	vval;
-
-
-/* Line 2053 of yacc.c  */
-#line 232 "y.tab.h"
-} YYSTYPE;
-# define YYSTYPE_IS_TRIVIAL 1
+}
+/* Line 1529 of yacc.c.  */
+#line 223 "y.tab.h"
+	YYSTYPE;
 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
 #endif
 
 extern YYSTYPE yylval;
 
-#ifdef YYPARSE_PARAM
-#if defined __STDC__ || defined __cplusplus
-int yyparse (void *YYPARSE_PARAM);
-#else
-int yyparse ();
-#endif
-#else /* ! YYPARSE_PARAM */
-#if defined __STDC__ || defined __cplusplus
-int yyparse (void);
-#else
-int yyparse ();
-#endif
-#endif /* ! YYPARSE_PARAM */
-
-#endif /* !YY_YY_Y_TAB_H_INCLUDED  */
diff --git a/src/cmd/cgo/ast.go b/src/cmd/cgo/ast.go
index 7757efa..10e2278 100644
--- a/src/cmd/cgo/ast.go
+++ b/src/cmd/cgo/ast.go
@@ -272,7 +272,7 @@ func (f *File) walk(x interface{}, context string, visit func(*File, interface{}
 
 	case nil:
 
-	// These are ordered and grouped to match ../../pkg/go/ast/ast.go
+	// These are ordered and grouped to match ../../go/ast/ast.go
 	case *ast.Field:
 		if len(n.Names) == 0 && context == "field" {
 			f.walk(&n.Type, "embed-type", visit)
@@ -308,6 +308,9 @@ func (f *File) walk(x interface{}, context string, visit func(*File, interface{}
 		if n.High != nil {
 			f.walk(&n.High, "expr", visit)
 		}
+		if n.Max != nil {
+			f.walk(&n.Max, "expr", visit)
+		}
 	case *ast.TypeAssertExpr:
 		f.walk(&n.X, "expr", visit)
 		f.walk(&n.Type, "type", visit)
diff --git a/src/cmd/cgo/doc.go b/src/cmd/cgo/doc.go
index 69c7ce8..6179c7a 100644
--- a/src/cmd/cgo/doc.go
+++ b/src/cmd/cgo/doc.go
@@ -152,7 +152,7 @@ In C, a function argument written as a fixed size array
 actually requires a pointer to the first element of the array.
 C compilers are aware of this calling convention and adjust
 the call accordingly, but Go cannot.  In Go, you must pass
-the pointer to the first element explicitly: C.f(&x[0]).
+the pointer to the first element explicitly: C.f(&C.x[0]).
 
 A few special functions convert between Go and C types
 by making copies of the data.  In pseudo-Go definitions:
diff --git a/src/cmd/cgo/gcc.go b/src/cmd/cgo/gcc.go
index f55cfba..abdd369 100644
--- a/src/cmd/cgo/gcc.go
+++ b/src/cmd/cgo/gcc.go
@@ -229,7 +229,8 @@ func (p *Package) guessKinds(f *File) []*Name {
 	// Determine kinds for names we already know about,
 	// like #defines or 'struct foo', before bothering with gcc.
 	var names, needType []*Name
-	for _, n := range f.Name {
+	for _, key := range nameKeys(f.Name) {
+		n := f.Name[key]
 		// If we've already found this name as a #define
 		// and we can translate it as a constant value, do so.
 		if n.Define != "" {
@@ -331,6 +332,7 @@ func (p *Package) guessKinds(f *File) []*Name {
 	const (
 		notType = 1 << iota
 		notConst
+		notDeclared
 	)
 	for _, line := range strings.Split(stderr, "\n") {
 		if !strings.Contains(line, ": error:") {
@@ -365,7 +367,7 @@ func (p *Package) guessKinds(f *File) []*Name {
 			completed = true
 
 		case "not-declared":
-			error_(token.NoPos, "%s", strings.TrimSpace(line[c2+1:]))
+			sniff[i] |= notDeclared
 		case "not-type":
 			sniff[i] |= notType
 		case "not-const":
@@ -374,12 +376,12 @@ func (p *Package) guessKinds(f *File) []*Name {
 	}
 
 	if !completed {
-		fatalf("%s did not produce error at completed:1\non input:\n%s", p.gccBaseCmd()[0], b.Bytes())
+		fatalf("%s did not produce error at completed:1\non input:\n%s\nfull error output:\n%s", p.gccBaseCmd()[0], b.Bytes(), stderr)
 	}
 
 	for i, n := range names {
 		switch sniff[i] {
-		case 0:
+		default:
 			error_(token.NoPos, "could not determine kind of name for C.%s", fixGo(n.Go))
 		case notType:
 			n.Kind = "const"
@@ -390,6 +392,14 @@ func (p *Package) guessKinds(f *File) []*Name {
 		}
 	}
 	if nerrors > 0 {
+		// Check if compiling the preamble by itself causes any errors,
+		// because the messages we've printed out so far aren't helpful
+		// to users debugging preamble mistakes.  See issue 8442.
+		preambleErrors := p.gccErrors([]byte(f.Preamble))
+		if len(preambleErrors) > 0 {
+			error_(token.NoPos, "\n%s errors for preamble:\n%s", p.gccBaseCmd()[0], preambleErrors)
+		}
+
 		fatalf("unresolved names")
 	}
 
@@ -649,7 +659,13 @@ func (p *Package) rewriteRef(f *File) {
 					f.Name[fpName] = name
 				}
 				r.Name = name
-				expr = ast.NewIdent(name.Mangle)
+				// Rewrite into call to _Cgo_ptr to prevent assignments.  The _Cgo_ptr
+				// function is defined in out.go and simply returns its argument. See
+				// issue 7757.
+				expr = &ast.CallExpr{
+					Fun:  &ast.Ident{NamePos: (*r.Expr).Pos(), Name: "_Cgo_ptr"},
+					Args: []ast.Expr{ast.NewIdent(name.Mangle)},
+				}
 			} else if r.Name.Kind == "type" {
 				// Okay - might be new(T)
 				expr = r.Name.Type.Go
@@ -928,9 +944,8 @@ type typeConv struct {
 
 	// Map from types to incomplete pointers to those types.
 	ptrs map[dwarf.Type][]*Type
-
-	// Fields to be processed by godefsField after completing pointers.
-	todoFlds [][]*ast.Field
+	// Keys of ptrs in insertion order (deterministic worklist)
+	ptrKeys []dwarf.Type
 
 	// Predeclared types.
 	bool                                   ast.Expr
@@ -940,9 +955,9 @@ type typeConv struct {
 	float32, float64                       ast.Expr
 	complex64, complex128                  ast.Expr
 	void                                   ast.Expr
-	unsafePointer                          ast.Expr
 	string                                 ast.Expr
 	goVoid                                 ast.Expr // _Ctype_void, denotes C's void
+	goVoidPtr                              ast.Expr // unsafe.Pointer or *byte
 
 	ptrSize int64
 	intSize int64
@@ -972,10 +987,17 @@ func (c *typeConv) Init(ptrSize, intSize int64) {
 	c.float64 = c.Ident("float64")
 	c.complex64 = c.Ident("complex64")
 	c.complex128 = c.Ident("complex128")
-	c.unsafePointer = c.Ident("unsafe.Pointer")
 	c.void = c.Ident("void")
 	c.string = c.Ident("string")
 	c.goVoid = c.Ident("_Ctype_void")
+
+	// Normally cgo translates void* to unsafe.Pointer,
+	// but for historical reasons -cdefs and -godefs use *byte instead.
+	if *cdefs || *godefs {
+		c.goVoidPtr = &ast.StarExpr{X: c.byte}
+	} else {
+		c.goVoidPtr = c.Ident("unsafe.Pointer")
+	}
 }
 
 // base strips away qualifiers and typedefs to get the underlying type
@@ -1037,29 +1059,22 @@ func (tr *TypeRepr) Set(repr string, fargs ...interface{}) {
 }
 
 // FinishType completes any outstanding type mapping work.
-// In particular, it resolves incomplete pointer types and also runs
-// godefsFields on any new struct types.
+// In particular, it resolves incomplete pointer types.
 func (c *typeConv) FinishType(pos token.Pos) {
 	// Completing one pointer type might produce more to complete.
 	// Keep looping until they're all done.
-	for len(c.ptrs) > 0 {
-		for dtype := range c.ptrs {
-			// Note Type might invalidate c.ptrs[dtype].
-			t := c.Type(dtype, pos)
-			for _, ptr := range c.ptrs[dtype] {
-				ptr.Go.(*ast.StarExpr).X = t.Go
-				ptr.C.Set("%s*", t.C)
-			}
-			delete(c.ptrs, dtype)
-		}
-	}
+	for len(c.ptrKeys) > 0 {
+		dtype := c.ptrKeys[0]
+		c.ptrKeys = c.ptrKeys[1:]
 
-	// Now that pointer types are completed, we can invoke godefsFields
-	// to rewrite struct definitions.
-	for _, fld := range c.todoFlds {
-		godefsFields(fld)
+		// Note Type might invalidate c.ptrs[dtype].
+		t := c.Type(dtype, pos)
+		for _, ptr := range c.ptrs[dtype] {
+			ptr.Go.(*ast.StarExpr).X = t.Go
+			ptr.C.Set("%s*", t.C)
+		}
+		c.ptrs[dtype] = nil // retain the map key
 	}
-	c.todoFlds = nil
 }
 
 // Type returns a *Type with the same memory layout as
@@ -1072,12 +1087,6 @@ func (c *typeConv) Type(dtype dwarf.Type, pos token.Pos) *Type {
 		return t
 	}
 
-	// clang won't generate DW_AT_byte_size for pointer types,
-	// so we have to fix it here.
-	if dt, ok := base(dtype).(*dwarf.PtrType); ok && dt.ByteSize == -1 {
-		dt.ByteSize = c.ptrSize
-	}
-
 	t := new(Type)
 	t.Size = dtype.Size() // note: wrong for array of pointers, corrected below
 	t.Align = -1
@@ -1101,12 +1110,20 @@ func (c *typeConv) Type(dtype dwarf.Type, pos token.Pos) *Type {
 			t.Go = c.Opaque(t.Size)
 			break
 		}
+		count := dt.Count
+		if count == -1 {
+			// Indicates flexible array member, which Go doesn't support.
+			// Translate to zero-length array instead.
+			count = 0
+		}
 		sub := c.Type(dt.Type, pos)
 		t.Align = sub.Align
 		t.Go = &ast.ArrayType{
-			Len: c.intExpr(dt.Count),
+			Len: c.intExpr(count),
 			Elt: sub.Go,
 		}
+		// Recalculate t.Size now that we know sub.Size.
+		t.Size = count * sub.Size
 		t.C.Set("__typeof__(%s[%d])", sub.C, dt.Count)
 
 	case *dwarf.BoolType:
@@ -1207,11 +1224,15 @@ func (c *typeConv) Type(dtype dwarf.Type, pos token.Pos) *Type {
 		}
 
 	case *dwarf.PtrType:
+		// Clang doesn't emit DW_AT_byte_size for pointer types.
+		if t.Size != c.ptrSize && t.Size != -1 {
+			fatalf("%s: unexpected: %d-byte pointer type - %s", lineno(pos), t.Size, dtype)
+		}
+		t.Size = c.ptrSize
 		t.Align = c.ptrSize
 
-		// Translate void* as unsafe.Pointer
 		if _, ok := base(dt.Type).(*dwarf.VoidType); ok {
-			t.Go = c.unsafePointer
+			t.Go = c.goVoidPtr
 			t.C.Set("void*")
 			break
 		}
@@ -1219,6 +1240,9 @@ func (c *typeConv) Type(dtype dwarf.Type, pos token.Pos) *Type {
 		// Placeholder initialization; completed in FinishType.
 		t.Go = &ast.StarExpr{}
 		t.C.Set("<incomplete>*")
+		if _, ok := c.ptrs[dt.Type]; !ok {
+			c.ptrKeys = append(c.ptrKeys, dt.Type)
+		}
 		c.ptrs[dt.Type] = append(c.ptrs[dt.Type], t)
 
 	case *dwarf.QualType:
@@ -1379,34 +1403,24 @@ func (c *typeConv) Type(dtype dwarf.Type, pos token.Pos) *Type {
 		}
 	}
 
-	if t.Size <= 0 {
-		// Clang does not record the size of a pointer in its DWARF entry,
-		// so if dtype is an array, the call to dtype.Size at the top of the function
-		// computed the size as the array length * 0 = 0.
-		// The type switch called Type (this function) recursively on the pointer
-		// entry, and the code near the top of the function updated the size to
-		// be correct, so calling dtype.Size again will produce the correct value.
-		t.Size = dtype.Size()
-		if t.Size < 0 {
-			// Unsized types are [0]byte, unless they're typedefs of other types
-			// or structs with tags.
-			// if so, use the name we've already defined.
-			t.Size = 0
-			switch dt := dtype.(type) {
-			case *dwarf.TypedefType:
-				// ok
-			case *dwarf.StructType:
-				if dt.StructName != "" {
-					break
-				}
-				t.Go = c.Opaque(0)
-			default:
-				t.Go = c.Opaque(0)
-			}
-			if t.C.Empty() {
-				t.C.Set("void")
+	if t.Size < 0 {
+		// Unsized types are [0]byte, unless they're typedefs of other types
+		// or structs with tags.
+		// if so, use the name we've already defined.
+		t.Size = 0
+		switch dt := dtype.(type) {
+		case *dwarf.TypedefType:
+			// ok
+		case *dwarf.StructType:
+			if dt.StructName != "" {
+				break
 			}
-			return t
+			t.Go = c.Opaque(0)
+		default:
+			t.Go = c.Opaque(0)
+		}
+		if t.C.Empty() {
+			t.C.Set("void")
 		}
 	}
 
@@ -1538,6 +1552,9 @@ func (c *typeConv) pad(fld []*ast.Field, size int64) []*ast.Field {
 
 // Struct conversion: return Go and (6g) C syntax for type.
 func (c *typeConv) Struct(dt *dwarf.StructType, pos token.Pos) (expr *ast.StructType, csyntax string, align int64) {
+	// Minimum alignment for a struct is 1 byte.
+	align = 1
+
 	var buf bytes.Buffer
 	buf.WriteString("struct {")
 	fld := make([]*ast.Field, 0, 2*len(dt.Field)+1) // enough for padding around every field
@@ -1579,7 +1596,27 @@ func (c *typeConv) Struct(dt *dwarf.StructType, pos token.Pos) (expr *ast.Struct
 			fld = c.pad(fld, f.ByteOffset-off)
 			off = f.ByteOffset
 		}
-		t := c.Type(f.Type, pos)
+
+		name := f.Name
+		ft := f.Type
+
+		// In godefs or cdefs mode, if this field is a C11
+		// anonymous union then treat the first field in the
+		// union as the field in the struct.  This handles
+		// cases like the glibc <sys/resource.h> file; see
+		// issue 6677.
+		if *godefs || *cdefs {
+			if st, ok := f.Type.(*dwarf.StructType); ok && name == "" && st.Kind == "union" && len(st.Field) > 0 && !used[st.Field[0].Name] {
+				name = st.Field[0].Name
+				ident[name] = name
+				ft = st.Field[0].Type
+			}
+		}
+
+		// TODO: Handle fields that are anonymous structs by
+		// promoting the fields of the inner struct.
+
+		t := c.Type(ft, pos)
 		tgo := t.Go
 		size := t.Size
 		talign := t.Align
@@ -1598,17 +1635,18 @@ func (c *typeConv) Struct(dt *dwarf.StructType, pos token.Pos) (expr *ast.Struct
 			talign = size
 		}
 
-		if talign > 0 && f.ByteOffset%talign != 0 {
+		if talign > 0 && f.ByteOffset%talign != 0 && !*cdefs {
 			// Drop misaligned fields, the same way we drop integer bit fields.
 			// The goal is to make available what can be made available.
 			// Otherwise one bad and unneeded field in an otherwise okay struct
 			// makes the whole program not compile. Much of the time these
 			// structs are in system headers that cannot be corrected.
+			// Exception: In -cdefs mode, we use #pragma pack, so misaligned
+			// fields should still work.
 			continue
 		}
 		n := len(fld)
 		fld = fld[0 : n+1]
-		name := f.Name
 		if name == "" {
 			name = fmt.Sprintf("anon%d", anon)
 			anon++
@@ -1635,7 +1673,7 @@ func (c *typeConv) Struct(dt *dwarf.StructType, pos token.Pos) (expr *ast.Struct
 	csyntax = buf.String()
 
 	if *godefs || *cdefs {
-		c.todoFlds = append(c.todoFlds, fld)
+		godefsFields(fld)
 	}
 	expr = &ast.StructType{Fields: &ast.FieldList{List: fld}}
 	return
@@ -1673,19 +1711,6 @@ func godefsFields(fld []*ast.Field) {
 				n.Name = upper(n.Name)
 			}
 		}
-		p := &f.Type
-		t := *p
-		if star, ok := t.(*ast.StarExpr); ok {
-			star = &ast.StarExpr{X: star.X}
-			*p = star
-			p = &star.X
-			t = *p
-		}
-		if id, ok := t.(*ast.Ident); ok {
-			if id.Name == "unsafe.Pointer" {
-				*p = ast.NewIdent("*byte")
-			}
-		}
 	}
 }
 
diff --git a/src/cmd/cgo/out.go b/src/cmd/cgo/out.go
index 76c7247..d92bed9 100644
--- a/src/cmd/cgo/out.go
+++ b/src/cmd/cgo/out.go
@@ -44,6 +44,7 @@ func (p *Package) writeDefs() {
 	fmt.Fprintf(fm, "int main() { return 0; }\n")
 	if *importRuntimeCgo {
 		fmt.Fprintf(fm, "void crosscall2(void(*fn)(void*, int), void *a, int c) { }\n")
+		fmt.Fprintf(fm, "char* _cgo_topofstack(void) { return (char*)0; }\n")
 	} else {
 		// If we're not importing runtime/cgo, we *are* runtime/cgo,
 		// which provides crosscall2.  We just need a prototype.
@@ -58,16 +59,14 @@ func (p *Package) writeDefs() {
 	fmt.Fprintf(fgo2, "// Created by cgo - DO NOT EDIT\n\n")
 	fmt.Fprintf(fgo2, "package %s\n\n", p.PackageName)
 	fmt.Fprintf(fgo2, "import \"unsafe\"\n\n")
-	if *importSyscall {
-		fmt.Fprintf(fgo2, "import \"syscall\"\n\n")
-	}
 	if !*gccgo && *importRuntimeCgo {
 		fmt.Fprintf(fgo2, "import _ \"runtime/cgo\"\n\n")
 	}
-	fmt.Fprintf(fgo2, "type _ unsafe.Pointer\n\n")
 	if *importSyscall {
-		fmt.Fprintf(fgo2, "func _Cerrno(dst *error, x int32) { *dst = syscall.Errno(x) }\n")
+		fmt.Fprintf(fgo2, "import \"syscall\"\n\n")
+		fmt.Fprintf(fgo2, "var _ syscall.Errno\n")
 	}
+	fmt.Fprintf(fgo2, "func _Cgo_ptr(ptr unsafe.Pointer) unsafe.Pointer { return ptr }\n\n")
 
 	typedefNames := make([]string, 0, len(typedef))
 	for name := range typedef {
@@ -87,9 +86,10 @@ func (p *Package) writeDefs() {
 	}
 
 	if *gccgo {
-		fmt.Fprintf(fc, p.cPrologGccgo())
+		fmt.Fprint(fc, p.cPrologGccgo())
 	} else {
-		fmt.Fprintf(fc, cProlog)
+		fmt.Fprint(fc, cProlog)
+		fmt.Fprint(fgo2, goProlog)
 	}
 
 	gccgoSymbolPrefix := p.gccgoSymbolPrefix()
@@ -130,6 +130,7 @@ func (p *Package) writeDefs() {
 			fmt.Fprintf(fc, `extern void *%s __asm__("%s.%s");`, n.Mangle, gccgoSymbolPrefix, n.Mangle)
 			fmt.Fprintf(&gccgoInit, "\t%s = %s%s;\n", n.Mangle, amp, n.C)
 		} else {
+			fmt.Fprintf(fc, "#pragma dataflag NOPTR /* C pointer, not heap pointer */ \n")
 			fmt.Fprintf(fc, "void *·%s = %s%s;\n", n.Mangle, amp, n.C)
 		}
 		fmt.Fprintf(fc, "\n")
@@ -296,10 +297,6 @@ func (p *Package) structType(n *Name) (string, int64) {
 		fmt.Fprintf(&buf, "\t\tchar __pad%d[%d];\n", off, pad)
 		off += pad
 	}
-	if n.AddError {
-		fmt.Fprint(&buf, "\t\tint e[2*sizeof(void *)/sizeof(int)]; /* error */\n")
-		off += 2 * p.PtrSize
-	}
 	if off == 0 {
 		fmt.Fprintf(&buf, "\t\tchar unused;\n") // avoid empty struct
 	}
@@ -334,19 +331,18 @@ func (p *Package) writeDefsFunc(fc, fgo2 *os.File, n *Name) {
 	}
 
 	// Builtins defined in the C prolog.
-	inProlog := name == "CString" || name == "GoString" || name == "GoStringN" || name == "GoBytes" || name == "_CMalloc"
+	inProlog := builtinDefs[name] != ""
+	cname := fmt.Sprintf("_cgo%s%s", cPrefix, n.Mangle)
+	paramnames := []string(nil)
+	for i, param := range d.Type.Params.List {
+		paramName := fmt.Sprintf("p%d", i)
+		param.Names = []*ast.Ident{ast.NewIdent(paramName)}
+		paramnames = append(paramnames, paramName)
+	}
 
 	if *gccgo {
 		// Gccgo style hooks.
 		fmt.Fprint(fgo2, "\n")
-		cname := fmt.Sprintf("_cgo%s%s", cPrefix, n.Mangle)
-		paramnames := []string(nil)
-		for i, param := range d.Type.Params.List {
-			paramName := fmt.Sprintf("p%d", i)
-			param.Names = []*ast.Ident{ast.NewIdent(paramName)}
-			paramnames = append(paramnames, paramName)
-		}
-
 		conf.Fprint(fgo2, fset, d)
 		fmt.Fprint(fgo2, " {\n")
 		if !inProlog {
@@ -383,7 +379,7 @@ func (p *Package) writeDefsFunc(fc, fgo2 *os.File, n *Name) {
 		fmt.Fprint(fgo2, "}\n")
 
 		// declare the C function.
-		fmt.Fprintf(fgo2, "//extern _cgo%s%s\n", cPrefix, n.Mangle)
+		fmt.Fprintf(fgo2, "//extern %s\n", cname)
 		d.Name = ast.NewIdent(cname)
 		if n.AddError {
 			l := d.Type.Results.List
@@ -394,61 +390,50 @@ func (p *Package) writeDefsFunc(fc, fgo2 *os.File, n *Name) {
 
 		return
 	}
-	conf.Fprint(fgo2, fset, d)
-	fmt.Fprint(fgo2, "\n")
 
 	if inProlog {
+		fmt.Fprint(fgo2, builtinDefs[name])
 		return
 	}
 
-	var argSize int64
-	_, argSize = p.structType(n)
-
 	// C wrapper calls into gcc, passing a pointer to the argument frame.
-	fmt.Fprintf(fc, "#pragma cgo_import_static _cgo%s%s\n", cPrefix, n.Mangle)
-	fmt.Fprintf(fc, "void _cgo%s%s(void*);\n", cPrefix, n.Mangle)
-	fmt.Fprintf(fc, "\n")
-	fmt.Fprintf(fc, "void\n")
-	if argSize == 0 {
-		argSize++
+	fmt.Fprintf(fc, "#pragma cgo_import_static %s\n", cname)
+	fmt.Fprintf(fc, "void %s(void*);\n", cname)
+	fmt.Fprintf(fc, "#pragma dataflag NOPTR\n")
+	fmt.Fprintf(fc, "void *·%s = %s;\n", cname, cname)
+
+	nret := 0
+	if !void {
+		d.Type.Results.List[0].Names = []*ast.Ident{ast.NewIdent("r1")}
+		nret = 1
 	}
-	// TODO(rsc): The struct here should declare pointers only where
-	// there are pointers in the actual argument frame.
-	// This is a workaround for golang.org/issue/6397.
-	fmt.Fprintf(fc, "·%s(struct{", n.Mangle)
-	if n := argSize / p.PtrSize; n > 0 {
-		fmt.Fprintf(fc, "void *y[%d];", n)
+	if n.AddError {
+		d.Type.Results.List[nret].Names = []*ast.Ident{ast.NewIdent("r2")}
 	}
-	if n := argSize % p.PtrSize; n > 0 {
-		fmt.Fprintf(fc, "uint8 x[%d];", n)
+
+	fmt.Fprint(fgo2, "\n")
+	fmt.Fprintf(fgo2, "var %s unsafe.Pointer\n", cname)
+	conf.Fprint(fgo2, fset, d)
+	fmt.Fprint(fgo2, " {\n")
+
+	// NOTE: Using uintptr to hide from escape analysis.
+	arg := "0"
+	if len(paramnames) > 0 {
+		arg = "uintptr(unsafe.Pointer(&p0))"
+	} else if !void {
+		arg = "uintptr(unsafe.Pointer(&r1))"
 	}
-	fmt.Fprintf(fc, "}p)\n")
-	fmt.Fprintf(fc, "{\n")
-	fmt.Fprintf(fc, "\truntime·cgocall(_cgo%s%s, &p);\n", cPrefix, n.Mangle)
+
+	prefix := ""
 	if n.AddError {
-		// gcc leaves errno in first word of interface at end of p.
-		// check whether it is zero; if so, turn interface into nil.
-		// if not, turn interface into errno.
-		// Go init function initializes ·_Cerrno with an os.Errno
-		// for us to copy.
-		fmt.Fprintln(fc, `	{
-			int32 e;
-			void **v;
-			v = (void**)(&p+1) - 2;	/* v = final two void* of p */
-			e = *(int32*)v;
-			v[0] = (void*)0xdeadbeef;
-			v[1] = (void*)0xdeadbeef;
-			if(e == 0) {
-				/* nil interface */
-				v[0] = 0;
-				v[1] = 0;
-			} else {
-				·_Cerrno(v, e);	/* fill in v as error for errno e */
-			}
-		}`)
+		prefix = "errno := "
 	}
-	fmt.Fprintf(fc, "}\n")
-	fmt.Fprintf(fc, "\n")
+	fmt.Fprintf(fgo2, "\t%s_cgo_runtime_cgocall_errno(%s, %s)\n", prefix, cname, arg)
+	if n.AddError {
+		fmt.Fprintf(fgo2, "\tif errno != 0 { r2 = syscall.Errno(errno) }\n")
+	}
+	fmt.Fprintf(fgo2, "\treturn\n")
+	fmt.Fprintf(fgo2, "}\n")
 }
 
 // writeOutput creates stubs for a specific source file to be compiled by 6g
@@ -521,7 +506,11 @@ func (p *Package) writeOutputFunc(fgcc *os.File, n *Name) {
 
 	// Gcc wrapper unpacks the C argument struct
 	// and calls the actual C function.
-	fmt.Fprintf(fgcc, "void\n")
+	if n.AddError {
+		fmt.Fprintf(fgcc, "int\n")
+	} else {
+		fmt.Fprintf(fgcc, "void\n")
+	}
 	fmt.Fprintf(fgcc, "_cgo%s%s(void *v)\n", cPrefix, n.Mangle)
 	fmt.Fprintf(fgcc, "{\n")
 	if n.AddError {
@@ -531,9 +520,13 @@ func (p *Package) writeOutputFunc(fgcc *os.File, n *Name) {
 	// Use packed attribute to force no padding in this struct in case
 	// gcc has different packing requirements.
 	fmt.Fprintf(fgcc, "\t%s %v *a = v;\n", ctype, p.packedAttribute())
+	if n.FuncType.Result != nil {
+		// Save the stack top for use below.
+		fmt.Fprintf(fgcc, "\tchar *stktop = _cgo_topofstack();\n")
+	}
 	fmt.Fprintf(fgcc, "\t")
 	if t := n.FuncType.Result; t != nil {
-		fmt.Fprintf(fgcc, "a->r = ")
+		fmt.Fprintf(fgcc, "__typeof__(a->r) r = ")
 		if c := t.C.String(); c[len(c)-1] == '*' {
 			fmt.Fprint(fgcc, "(__typeof__(a->r)) ")
 		}
@@ -556,8 +549,15 @@ func (p *Package) writeOutputFunc(fgcc *os.File, n *Name) {
 		fmt.Fprintf(fgcc, "a->p%d", i)
 	}
 	fmt.Fprintf(fgcc, ");\n")
+	if n.FuncType.Result != nil {
+		// The cgo call may have caused a stack copy (via a callback).
+		// Adjust the return value pointer appropriately.
+		fmt.Fprintf(fgcc, "\ta = (void*)((char*)a + (_cgo_topofstack() - stktop));\n")
+		// Save the return value.
+		fmt.Fprintf(fgcc, "\ta->r = r;\n")
+	}
 	if n.AddError {
-		fmt.Fprintf(fgcc, "\t*(int*)(a->e) = errno;\n")
+		fmt.Fprintf(fgcc, "\treturn errno;\n")
 	}
 	fmt.Fprintf(fgcc, "}\n")
 	fmt.Fprintf(fgcc, "\n")
@@ -1016,7 +1016,7 @@ func forFieldList(fl *ast.FieldList, fn func(int, ast.Expr)) {
 			fn(i, r.Type)
 			i++
 		} else {
-			for _ = range r.Names {
+			for range r.Names {
 				fn(i, r.Type)
 				i++
 			}
@@ -1143,21 +1143,17 @@ __cgo_size_assert(__cgo_long_long, 8)
 __cgo_size_assert(float, 4)
 __cgo_size_assert(double, 8)
 
+extern char* _cgo_topofstack(void);
+
 #include <errno.h>
 #include <string.h>
 `
 
 const builtinProlog = `
-#include <sys/types.h> /* for size_t below */
+#include <stddef.h> /* for ptrdiff_t and size_t below */
 
 /* Define intgo when compiling with GCC.  */
-#ifdef __PTRDIFF_TYPE__
-typedef __PTRDIFF_TYPE__ intgo;
-#elif defined(_LP64)
-typedef long long intgo;
-#else
-typedef int intgo;
-#endif
+typedef ptrdiff_t intgo;
 
 typedef struct { char *p; intgo n; } _GoString_;
 typedef struct { char *p; intgo n; intgo c; } _GoBytes_;
@@ -1171,47 +1167,86 @@ void *_CMalloc(size_t);
 const cProlog = `
 #include "runtime.h"
 #include "cgocall.h"
+#include "textflag.h"
+
+#pragma dataflag NOPTR
+static void *cgocall_errno = runtime·cgocall_errno;
+#pragma dataflag NOPTR
+void *·_cgo_runtime_cgocall_errno = &cgocall_errno;
+
+#pragma dataflag NOPTR
+static void *runtime_gostring = runtime·gostring;
+#pragma dataflag NOPTR
+void *·_cgo_runtime_gostring = &runtime_gostring;
+
+#pragma dataflag NOPTR
+static void *runtime_gostringn = runtime·gostringn;
+#pragma dataflag NOPTR
+void *·_cgo_runtime_gostringn = &runtime_gostringn;
+
+#pragma dataflag NOPTR
+static void *runtime_gobytes = runtime·gobytes;
+#pragma dataflag NOPTR
+void *·_cgo_runtime_gobytes = &runtime_gobytes;
+
+#pragma dataflag NOPTR
+static void *runtime_cmalloc = runtime·cmalloc;
+#pragma dataflag NOPTR
+void *·_cgo_runtime_cmalloc = &runtime_cmalloc;
 
 void ·_Cerrno(void*, int32);
+`
 
-void
-·_Cfunc_GoString(int8 *p, String s)
-{
-	s = runtime·gostring((byte*)p);
-	FLUSH(&s);
+const goProlog = `
+var _cgo_runtime_cgocall_errno func(unsafe.Pointer, uintptr) int32
+var _cgo_runtime_cmalloc func(uintptr) unsafe.Pointer
+`
+
+const goStringDef = `
+var _cgo_runtime_gostring func(*_Ctype_char) string
+func _Cfunc_GoString(p *_Ctype_char) string {
+	return _cgo_runtime_gostring(p)
 }
+`
 
-void
-·_Cfunc_GoStringN(int8 *p, int32 l, String s)
-{
-	s = runtime·gostringn((byte*)p, l);
-	FLUSH(&s);
+const goStringNDef = `
+var _cgo_runtime_gostringn func(*_Ctype_char, int) string
+func _Cfunc_GoStringN(p *_Ctype_char, l _Ctype_int) string {
+	return _cgo_runtime_gostringn(p, int(l))
 }
+`
 
-void
-·_Cfunc_GoBytes(int8 *p, int32 l, Slice s)
-{
-	s = runtime·gobytes((byte*)p, l);
-	FLUSH(&s);
+const goBytesDef = `
+var _cgo_runtime_gobytes func(unsafe.Pointer, int) []byte
+func _Cfunc_GoBytes(p unsafe.Pointer, l _Ctype_int) []byte {
+	return _cgo_runtime_gobytes(p, int(l))
 }
+`
 
-void
-·_Cfunc_CString(String s, int8 *p)
-{
-	p = runtime·cmalloc(s.len+1);
-	runtime·memmove((byte*)p, s.str, s.len);
-	p[s.len] = 0;
-	FLUSH(&p);
+const cStringDef = `
+func _Cfunc_CString(s string) *_Ctype_char {
+	p := _cgo_runtime_cmalloc(uintptr(len(s)+1))
+	pp := (*[1<<30]byte)(p)
+	copy(pp[:], s)
+	pp[len(s)] = 0
+	return (*_Ctype_char)(p)
 }
+`
 
-void
-·_Cfunc__CMalloc(uintptr n, int8 *p)
-{
-	p = runtime·cmalloc(n);
-	FLUSH(&p);
+const cMallocDef = `
+func _Cfunc__CMalloc(n _Ctype_size_t) unsafe.Pointer {
+	return _cgo_runtime_cmalloc(uintptr(n))
 }
 `
 
+var builtinDefs = map[string]string{
+	"GoString":  goStringDef,
+	"GoStringN": goStringNDef,
+	"GoBytes":   goBytesDef,
+	"CString":   cStringDef,
+	"_CMalloc":  cMallocDef,
+}
+
 func (p *Package) cPrologGccgo() string {
 	return strings.Replace(cPrologGccgo, "PREFIX", cPrefix, -1)
 }
diff --git a/src/cmd/dist/a.h b/src/cmd/dist/a.h
index 6222e50..288063b 100644
--- a/src/cmd/dist/a.h
+++ b/src/cmd/dist/a.h
@@ -108,9 +108,6 @@ void	mkzexperiment(char*, char*);
 // buildgo.c
 void	mkzdefaultcc(char*, char*);
 
-// goc2c.c
-void	goc2c(char*, char*);
-
 // main.c
 extern int vflag;
 extern int sflag;
@@ -129,6 +126,7 @@ bool	isfile(char *p);
 char*	lastelem(char*);
 Time	mtime(char*);
 void	readfile(Buf*, char*);
+void	copyfile(char*, char*, int);
 void	run(Buf *b, char *dir, int mode, char *cmd, ...);
 void	runv(Buf *b, char *dir, int mode, Vec *argv);
 void	bgrunv(char *dir, int mode, Vec *argv);
diff --git a/src/cmd/dist/arm.c b/src/cmd/dist/arm.c
index 52a621c..1ce7b77 100644
--- a/src/cmd/dist/arm.c
+++ b/src/cmd/dist/arm.c
@@ -21,7 +21,8 @@ xgetgoarm(void)
 	// FreeBSD has broken VFP support
 	return "5";
 #endif
-	if(xtryexecfunc(useVFPv3))
+	// NaCl always has VFP support.
+	if(streq(goos, "nacl") || xtryexecfunc(useVFPv3))
 		return "7";
 	else if(xtryexecfunc(useVFPv1))
 		return "6";
diff --git a/src/cmd/dist/buf.c b/src/cmd/dist/buf.c
index 45fb195..2ddc6be 100644
--- a/src/cmd/dist/buf.c
+++ b/src/cmd/dist/buf.c
@@ -202,7 +202,7 @@ vadd(Vec *v, char *p)
 }
 
 // vaddn adds a string consisting of the n bytes at p to the vector.
-void
+static void
 vaddn(Vec *v, char *p, int n)
 {
 	char *q;
diff --git a/src/cmd/dist/build.c b/src/cmd/dist/build.c
index 6884e0a..d638ae4 100644
--- a/src/cmd/dist/build.c
+++ b/src/cmd/dist/build.c
@@ -35,7 +35,6 @@ bool	rebuildall;
 bool defaultclang;
 
 static bool shouldbuild(char*, char*);
-static void copy(char*, char*, int);
 static void dopack(char*, char*, char**, int);
 static char *findgoversion(void);
 
@@ -56,6 +55,7 @@ static char *okgoos[] = {
 	"darwin",
 	"dragonfly",
 	"linux",
+	"android",
 	"solaris",
 	"freebsd",
 	"nacl",
@@ -366,8 +366,8 @@ static char *oldtool[] = {
 // not be in release branches.
 static char *unreleased[] = {
 	"src/cmd/link",
-	"src/pkg/debug/goobj",
-	"src/pkg/old",
+	"src/debug/goobj",
+	"src/old",
 };
 
 // setup sets up the tree for the initial build.
@@ -590,7 +590,7 @@ static struct {
 		"$GOROOT/pkg/obj/$GOHOSTOS_$GOHOSTARCH/libbio.a",
 		"$GOROOT/pkg/obj/$GOHOSTOS_$GOHOSTARCH/lib9.a",
 	}},
-	{"pkg/runtime", {
+	{"runtime", {
 		"zaexperiment.h", // must sort above zasm
 		"zasm_$GOOS_$GOARCH.h",
 		"zsys_$GOOS_$GOARCH.s",
@@ -607,7 +607,6 @@ char *depsuffix[] = {
 	".h",
 	".s",
 	".go",
-	".goc",
 };
 
 // gentab records how to generate some trivial files.
@@ -639,7 +638,7 @@ install(char *dir)
 {
 	char *name, *p, *elem, *prefix, *exe;
 	bool islib, ispkg, isgo, stale, ispackcmd;
-	Buf b, b1, path;
+	Buf b, b1, path, final_path, final_name;
 	Vec compile, files, link, go, missing, clean, lib, extra;
 	Time ttarg, t;
 	int i, j, k, n, doclean, targ;
@@ -654,6 +653,8 @@ install(char *dir)
 	binit(&b);
 	binit(&b1);
 	binit(&path);
+	binit(&final_path);
+	binit(&final_name);
 	vinit(&compile);
 	vinit(&files);
 	vinit(&link);
@@ -666,15 +667,9 @@ install(char *dir)
 
 	// path = full path to dir.
 	bpathf(&path, "%s/src/%s", goroot, dir);
+	bpathf(&final_path, "%s/src/%s", goroot_final, dir);
 	name = lastelem(dir);
 
-	// For misc/prof, copy into the tool directory and we're done.
-	if(hasprefix(dir, "misc/")) {
-		copy(bpathf(&b, "%s/%s", tooldir, name),
-			bpathf(&b1, "%s/misc/%s", goroot, name), 1);
-		goto out;
-	}
-
 	// set up gcc command line on first run.
 	if(gccargs.len == 0) {
 		bprintf(&b, "%s %s", defaultcc, defaultcflags);
@@ -704,7 +699,7 @@ install(char *dir)
 	}
 
 	islib = hasprefix(dir, "lib") || streq(dir, "cmd/cc") || streq(dir, "cmd/gc");
-	ispkg = hasprefix(dir, "pkg");
+	ispkg = !islib && !hasprefix(dir, "cmd/");
 	isgo = ispkg || streq(dir, "cmd/go") || streq(dir, "cmd/cgo");
 
 	exe = "";
@@ -730,11 +725,11 @@ install(char *dir)
 		// Go library (package).
 		ispackcmd = 1;
 		vadd(&link, "pack"); // program name - unused here, but all the other cases record one
-		p = bprintf(&b, "%s/pkg/%s_%s/%s", goroot, goos, goarch, dir+4);
+		p = bprintf(&b, "%s/pkg/%s_%s/%s", goroot, goos, goarch, dir);
 		*xstrrchr(p, '/') = '\0';
 		xmkdirall(p);
 		targ = link.len;
-		vadd(&link, bpathf(&b, "%s/pkg/%s_%s/%s.a", goroot, goos, goarch, dir+4));
+		vadd(&link, bpathf(&b, "%s/pkg/%s_%s/%s.a", goroot, goos, goarch, dir));
 	} else if(streq(dir, "cmd/go") || streq(dir, "cmd/cgo")) {
 		// Go command.
 		vadd(&link, bpathf(&b, "%s/%sl", tooldir, gochar));
@@ -881,18 +876,22 @@ install(char *dir)
 		goto out;
 
 	// For package runtime, copy some files into the work space.
-	if(streq(dir, "pkg/runtime")) {
-		copy(bpathf(&b, "%s/arch_GOARCH.h", workdir),
+	if(streq(dir, "runtime")) {
+		copyfile(bpathf(&b, "%s/arch_GOARCH.h", workdir),
 			bpathf(&b1, "%s/arch_%s.h", bstr(&path), goarch), 0);
-		copy(bpathf(&b, "%s/defs_GOOS_GOARCH.h", workdir),
+		copyfile(bpathf(&b, "%s/defs_GOOS_GOARCH.h", workdir),
 			bpathf(&b1, "%s/defs_%s_%s.h", bstr(&path), goos, goarch), 0);
 		p = bpathf(&b1, "%s/signal_%s_%s.h", bstr(&path), goos, goarch);
 		if(isfile(p))
-			copy(bpathf(&b, "%s/signal_GOOS_GOARCH.h", workdir), p, 0);
-		copy(bpathf(&b, "%s/os_GOOS.h", workdir),
+			copyfile(bpathf(&b, "%s/signal_GOOS_GOARCH.h", workdir), p, 0);
+		copyfile(bpathf(&b, "%s/os_GOOS.h", workdir),
 			bpathf(&b1, "%s/os_%s.h", bstr(&path), goos), 0);
-		copy(bpathf(&b, "%s/signals_GOOS.h", workdir),
+		copyfile(bpathf(&b, "%s/signals_GOOS.h", workdir),
 			bpathf(&b1, "%s/signals_%s.h", bstr(&path), goos), 0);
+		copyfile(bpathf(&b, "%s/pkg/%s_%s/textflag.h", goroot, goos, goarch),
+			bpathf(&b1, "%s/src/cmd/ld/textflag.h", goroot), 0);
+		copyfile(bpathf(&b, "%s/pkg/%s_%s/funcdata.h", goroot, goos, goarch),
+			bpathf(&b1, "%s/src/runtime/funcdata.h", goroot), 0);
 	}
 
 	// Generate any missing files; regenerate existing ones.
@@ -907,7 +906,7 @@ install(char *dir)
 					errprintf("generate %s\n", p);
 				gentab[j].gen(bstr(&path), p);
 				// Do not add generated file to clean list.
-				// In pkg/runtime, we want to be able to
+				// In runtime, we want to be able to
 				// build the package with the go tool,
 				// and it assumes these generated files already
 				// exist (it does not know how to build them).
@@ -925,27 +924,11 @@ install(char *dir)
 	// One more copy for package runtime.
 	// The last batch was required for the generators.
 	// This one is generated.
-	if(streq(dir, "pkg/runtime")) {
-		copy(bpathf(&b, "%s/zasm_GOOS_GOARCH.h", workdir),
+	if(streq(dir, "runtime")) {
+		copyfile(bpathf(&b, "%s/zasm_GOOS_GOARCH.h", workdir),
 			bpathf(&b1, "%s/zasm_%s_%s.h", bstr(&path), goos, goarch), 0);
 	}
 
-	// Generate .c files from .goc files.
-	if(streq(dir, "pkg/runtime")) {
-		for(i=0; i<files.len; i++) {
-			p = files.p[i];
-			if(!hassuffix(p, ".goc"))
-				continue;
-			// b = path/zp but with _goos_goarch.c instead of .goc
-			bprintf(&b, "%s%sz%s", bstr(&path), slash, lastelem(p));
-			b.len -= 4;
-			bwritef(&b, "_%s_%s.c", goos, goarch);
-			goc2c(p, bstr(&b));
-			vadd(&files, bstr(&b));
-		}
-		vuniq(&files);
-	}
-
 	if((!streq(goos, gohostos) || !streq(goarch, gohostarch)) && isgo) {
 		// We've generated the right files; the go command can do the build.
 		if(vflag > 1)
@@ -1086,7 +1069,7 @@ install(char *dir)
 		else
 			vadd(&compile, "main");
 
-		if(streq(dir, "pkg/runtime"))
+		if(streq(dir, "runtime"))
 			vadd(&compile, "-+");
 
 		vcopy(&compile, go.p, go.len);
@@ -1115,11 +1098,11 @@ install(char *dir)
 nobuild:
 	// In package runtime, we install runtime.h and cgocall.h too,
 	// for use by cgo compilation.
-	if(streq(dir, "pkg/runtime")) {
-		copy(bpathf(&b, "%s/pkg/%s_%s/cgocall.h", goroot, goos, goarch),
-			bpathf(&b1, "%s/src/pkg/runtime/cgocall.h", goroot), 0);
-		copy(bpathf(&b, "%s/pkg/%s_%s/runtime.h", goroot, goos, goarch),
-			bpathf(&b1, "%s/src/pkg/runtime/runtime.h", goroot), 0);
+	if(streq(dir, "runtime")) {
+		copyfile(bpathf(&b, "%s/pkg/%s_%s/cgocall.h", goroot, goos, goarch),
+			bpathf(&b1, "%s/src/runtime/cgocall.h", goroot), 0);
+		copyfile(bpathf(&b, "%s/pkg/%s_%s/runtime.h", goroot, goos, goarch),
+			bpathf(&b1, "%s/src/runtime/runtime.h", goroot), 0);
 	}
 
 
@@ -1149,7 +1132,7 @@ matchfield(char *f)
 
 	p = xstrrchr(f, ',');
 	if(p == nil)
-		return streq(f, goos) || streq(f, goarch) || streq(f, "cmd_go_bootstrap") || streq(f, "go1.1");
+		return streq(f, goos) || streq(f, goarch) || streq(f, "cmd_go_bootstrap") || streq(f, "go1.1") || (streq(goos, "android") && streq(f, "linux"));
 	*p = 0;
 	res = matchfield(f) && matchfield(p+1);
 	*p = ',';
@@ -1241,8 +1224,8 @@ out:
 }
 
 // copy copies the file src to dst, via memory (so only good for small files).
-static void
-copy(char *dst, char *src, int exec)
+void
+copyfile(char *dst, char *src, int exec)
 {
 	Buf b;
 
@@ -1303,8 +1286,6 @@ static char *buildorder[] = {
 	"libbio",
 	"liblink",
 
-	"misc/pprof",
-
 	"cmd/cc",  // must be before c
 	"cmd/gc",  // must be before g
 	"cmd/%sl",  // must be before a, c, g
@@ -1316,47 +1297,47 @@ static char *buildorder[] = {
 	// back when there were build scripts.  Will have to
 	// be maintained by hand, but shouldn't change very
 	// often.
-	"pkg/runtime",
-	"pkg/errors",
-	"pkg/sync/atomic",
-	"pkg/sync",
-	"pkg/io",
-	"pkg/unicode",
-	"pkg/unicode/utf8",
-	"pkg/unicode/utf16",
-	"pkg/bytes",
-	"pkg/math",
-	"pkg/strings",
-	"pkg/strconv",
-	"pkg/bufio",
-	"pkg/sort",
-	"pkg/container/heap",
-	"pkg/encoding/base64",
-	"pkg/syscall",
-	"pkg/time",
-	"pkg/os",
-	"pkg/reflect",
-	"pkg/fmt",
-	"pkg/encoding",
-	"pkg/encoding/json",
-	"pkg/flag",
-	"pkg/path/filepath",
-	"pkg/path",
-	"pkg/io/ioutil",
-	"pkg/log",
-	"pkg/regexp/syntax",
-	"pkg/regexp",
-	"pkg/go/token",
-	"pkg/go/scanner",
-	"pkg/go/ast",
-	"pkg/go/parser",
-	"pkg/os/exec",
-	"pkg/os/signal",
-	"pkg/net/url",
-	"pkg/text/template/parse",
-	"pkg/text/template",
-	"pkg/go/doc",
-	"pkg/go/build",
+	"runtime",
+	"errors",
+	"sync/atomic",
+	"sync",
+	"io",
+	"unicode",
+	"unicode/utf8",
+	"unicode/utf16",
+	"bytes",
+	"math",
+	"strings",
+	"strconv",
+	"bufio",
+	"sort",
+	"container/heap",
+	"encoding/base64",
+	"syscall",
+	"time",
+	"os",
+	"reflect",
+	"fmt",
+	"encoding",
+	"encoding/json",
+	"flag",
+	"path/filepath",
+	"path",
+	"io/ioutil",
+	"log",
+	"regexp/syntax",
+	"regexp",
+	"go/token",
+	"go/scanner",
+	"go/ast",
+	"go/parser",
+	"os/exec",
+	"os/signal",
+	"net/url",
+	"text/template/parse",
+	"text/template",
+	"go/doc",
+	"go/build",
 	"cmd/go",
 };
 
@@ -1364,6 +1345,7 @@ static char *buildorder[] = {
 // It is bigger than the buildorder because we clean all the
 // compilers but build only the $GOARCH ones.
 static char *cleantab[] = {
+	// Commands and C libraries.
 	"cmd/5a",
 	"cmd/5c",
 	"cmd/5g",
@@ -1382,46 +1364,48 @@ static char *cleantab[] = {
 	"lib9",
 	"libbio",
 	"liblink",
-	"pkg/bufio",
-	"pkg/bytes",
-	"pkg/container/heap",
-	"pkg/encoding",
-	"pkg/encoding/base64",
-	"pkg/encoding/json",
-	"pkg/errors",
-	"pkg/flag",
-	"pkg/fmt",
-	"pkg/go/ast",
-	"pkg/go/build",
-	"pkg/go/doc",
-	"pkg/go/parser",
-	"pkg/go/scanner",
-	"pkg/go/token",
-	"pkg/io",
-	"pkg/io/ioutil",
-	"pkg/log",
-	"pkg/math",
-	"pkg/net/url",
-	"pkg/os",
-	"pkg/os/exec",
-	"pkg/path",
-	"pkg/path/filepath",
-	"pkg/reflect",
-	"pkg/regexp",
-	"pkg/regexp/syntax",
-	"pkg/runtime",
-	"pkg/sort",
-	"pkg/strconv",
-	"pkg/strings",
-	"pkg/sync",
-	"pkg/sync/atomic",
-	"pkg/syscall",
-	"pkg/text/template",
-	"pkg/text/template/parse",
-	"pkg/time",
-	"pkg/unicode",
-	"pkg/unicode/utf16",
-	"pkg/unicode/utf8",
+
+	// Go packages.
+	"bufio",
+	"bytes",
+	"container/heap",
+	"encoding",
+	"encoding/base64",
+	"encoding/json",
+	"errors",
+	"flag",
+	"fmt",
+	"go/ast",
+	"go/build",
+	"go/doc",
+	"go/parser",
+	"go/scanner",
+	"go/token",
+	"io",
+	"io/ioutil",
+	"log",
+	"math",
+	"net/url",
+	"os",
+	"os/exec",
+	"path",
+	"path/filepath",
+	"reflect",
+	"regexp",
+	"regexp/syntax",
+	"runtime",
+	"sort",
+	"strconv",
+	"strings",
+	"sync",
+	"sync/atomic",
+	"syscall",
+	"text/template",
+	"text/template/parse",
+	"time",
+	"unicode",
+	"unicode/utf16",
+	"unicode/utf8",
 };
 
 static void
@@ -1450,9 +1434,9 @@ clean(void)
 			xremove(bpathf(&b, "%s/%s", bstr(&path), cleantab[i]+4));
 	}
 
-	// remove src/pkg/runtime/z* unconditionally
+	// remove src/runtime/z* unconditionally
 	vreset(&dir);
-	bpathf(&path, "%s/src/pkg/runtime", goroot);
+	bpathf(&path, "%s/src/runtime", goroot);
 	xreaddir(&dir, bstr(&path));
 	for(j=0; j<dir.len; j++) {
 		if(hasprefix(dir.p[j], "z"))
@@ -1589,6 +1573,15 @@ cmdbootstrap(int argc, char **argv)
 	if(argc > 0)
 		usage();
 
+	if(isdir(bpathf(&b, "%s/src/pkg", goroot))) {
+		fatal("\n\n"
+			"The Go package sources have moved to $GOROOT/src.\n"
+			"*** %s still exists. ***\n"
+			"It probably contains stale files that may confuse the build.\n"
+			"Please (check what's there and) remove it and try again.\n"
+			"See http://golang.org/s/go14nopkg\n", bpathf(&b, "%s/src/pkg", goroot));
+	}
+	
 	if(rebuildall)
 		clean();
 	goversion = findgoversion();
@@ -1619,9 +1612,9 @@ cmdbootstrap(int argc, char **argv)
 	xsetenv("GOARCH", goarch);
 	xsetenv("GOOS", goos);
 
-	// Build pkg/runtime for actual goos/goarch too.
+	// Build runtime for actual goos/goarch too.
 	if(!streq(goos, gohostos) || !streq(goarch, gohostarch))
-		install("pkg/runtime");
+		install("runtime");
 
 	bfree(&b);
 }
diff --git a/src/cmd/dist/buildgc.c b/src/cmd/dist/buildgc.c
index 1f0625d..66adf68 100644
--- a/src/cmd/dist/buildgc.c
+++ b/src/cmd/dist/buildgc.c
@@ -65,24 +65,35 @@ gcopnames(char *dir, char *file)
 
 // mkanames reads [568].out.h and writes anames[568].c
 // The format is much the same as the Go opcodes above.
+// it also writes out cnames array for C_* constants.
 void
 mkanames(char *dir, char *file)
 {
-	int i, ch;
-	Buf in, b, out;
+	int i, j, ch;
+	Buf in, b, out, out2;
 	Vec lines;
 	char *p;
 
 	binit(&b);
 	binit(&in);
 	binit(&out);
+	binit(&out2);
 	vinit(&lines);
 
 	ch = file[xstrlen(file)-3];
 	bprintf(&b, "%s/../cmd/%cl/%c.out.h", dir, ch, ch);
 	readfile(&in, bstr(&b));
 	splitlines(&lines, bstr(&in));
-	bprintf(&out, "char*	anames%c[] = {\n", ch);
+	
+	// Include link.h so that the extern declaration there is
+	// checked against the non-extern declaration we are generating.
+	bwritestr(&out, bprintf(&b, "#include <u.h>\n"));
+	bwritestr(&out, bprintf(&b, "#include <libc.h>\n"));
+	bwritestr(&out, bprintf(&b, "#include <bio.h>\n"));
+	bwritestr(&out, bprintf(&b, "#include <link.h>\n"));
+	bwritestr(&out, bprintf(&b, "\n"));
+
+	bwritestr(&out, bprintf(&b, "char*	anames%c[] = {\n", ch));
 	for(i=0; i<lines.len; i++) {
 		if(hasprefix(lines.p[i], "\tA")) {
 			p = xstrstr(lines.p[i], ",");
@@ -96,10 +107,31 @@ mkanames(char *dir, char *file)
 		}
 	}
 	bwritestr(&out, "};\n");
+
+	j=0;
+	bprintf(&out2, "char*	cnames%c[] = {\n", ch);
+	for(i=0; i<lines.len; i++) {
+		if(hasprefix(lines.p[i], "\tC_")) {
+			p = xstrstr(lines.p[i], ",");
+			if(p)
+				*p = '\0';
+			p = xstrstr(lines.p[i], "\n");
+			if(p)
+				*p = '\0';
+			p = lines.p[i] + 3;
+			bwritestr(&out2, bprintf(&b, "\t\"%s\",\n", p));
+			j++;
+		}
+	}
+	bwritestr(&out2, "};\n");
+	if(j>0)
+		bwriteb(&out, &out2);
+
 	writefile(&out, file, 0);
 
 	bfree(&b);
 	bfree(&in);
 	bfree(&out);
+	bfree(&out2);
 	vfree(&lines);
 }
diff --git a/src/cmd/dist/buildruntime.c b/src/cmd/dist/buildruntime.c
index ba5993b..bb774e0 100644
--- a/src/cmd/dist/buildruntime.c
+++ b/src/cmd/dist/buildruntime.c
@@ -5,7 +5,7 @@
 #include "a.h"
 
 /*
- * Helpers for building pkg/runtime.
+ * Helpers for building runtime.
  */
 
 // mkzversion writes zversion.go:
@@ -30,7 +30,8 @@ mkzversion(char *dir, char *file)
 		"package runtime\n"
 		"\n"
 		"const defaultGoroot = `%s`\n"
-		"const theVersion = `%s`\n", goroot_final, goversion));
+		"const theVersion = `%s`\n"
+		"var buildVersion = theVersion\n", goroot_final, goversion));
 
 	writefile(&out, file, 0);
 	
@@ -108,10 +109,14 @@ mkzgoos(char *dir, char *file)
 	
 	binit(&b);
 	binit(&out);
+
+	bwritestr(&out, "// auto generated by go tool dist\n\n");
+
+	if(streq(goos, "linux")) {
+		bwritestr(&out, "// +build !android\n\n");
+	}
 	
 	bwritestr(&out, bprintf(&b,
-		"// auto generated by go tool dist\n"
-		"\n"
 		"package runtime\n"
 		"\n"
 		"const theGoos = `%s`\n", goos));
@@ -130,17 +135,14 @@ static struct {
 	{"386", "",
 		"#define	get_tls(r)	MOVL TLS, r\n"
 		"#define	g(r)	0(r)(TLS*1)\n"
-		"#define	m(r)	4(r)(TLS*1)\n"
 	},
 	{"amd64p32", "",
 		"#define	get_tls(r)	MOVL TLS, r\n"
 		"#define	g(r)	0(r)(TLS*1)\n"
-		"#define	m(r)	4(r)(TLS*1)\n"
 	},
 	{"amd64", "",
 		"#define	get_tls(r)	MOVQ TLS, r\n"
 		"#define	g(r)	0(r)(TLS*1)\n"
-		"#define	m(r)	8(r)(TLS*1)\n"
 	},	
 
 	{"arm", "",
@@ -160,11 +162,12 @@ mkzasm(char *dir, char *file)
 {
 	int i, n;
 	char *aggr, *p;
-	Buf in, b, out, exp;
+	Buf in, b, b1, out, exp;
 	Vec argv, lines, fields;
 
 	binit(&in);
 	binit(&b);
+	binit(&b1);
 	binit(&out);
 	binit(&exp);
 	vinit(&argv);
@@ -172,6 +175,10 @@ mkzasm(char *dir, char *file)
 	vinit(&fields);
 	
 	bwritestr(&out, "// auto generated by go tool dist\n\n");
+	if(streq(goos, "linux")) {
+		bwritestr(&out, "// +build !android\n\n");
+	}
+	
 	for(i=0; i<nelem(zasmhdr); i++) {
 		if(hasprefix(goarch, zasmhdr[i].goarch) && hasprefix(goos, zasmhdr[i].goos)) {
 			bwritestr(&out, zasmhdr[i].hdr);
@@ -181,6 +188,9 @@ mkzasm(char *dir, char *file)
 	fatal("unknown $GOOS/$GOARCH in mkzasm");
 ok:
 
+	copyfile(bpathf(&b, "%s/pkg/%s_%s/textflag.h", goroot, goos, goarch),
+		bpathf(&b1, "%s/src/cmd/ld/textflag.h", goroot), 0);
+
 	// Run 6c -D GOOS_goos -D GOARCH_goarch -I workdir -a -n -o workdir/proc.acid proc.c
 	// to get acid [sic] output. Run once without the -a -o workdir/proc.acid in order to
 	// report compilation failures (the -o redirects all messages, unfortunately).
@@ -192,6 +202,8 @@ ok:
 	vadd(&argv, bprintf(&b, "GOARCH_%s", goarch));
 	vadd(&argv, "-I");
 	vadd(&argv, bprintf(&b, "%s", workdir));
+	vadd(&argv, "-I");
+	vadd(&argv, bprintf(&b, "%s/pkg/%s_%s", goroot, goos, goarch));
 	vadd(&argv, "-n");
 	vadd(&argv, "-a");
 	vadd(&argv, "-o");
@@ -230,6 +242,12 @@ ok:
 				aggr = "cbctxt";
 			else if(streq(fields.p[1], "SEH"))
 				aggr = "seh";
+			else if(streq(fields.p[1], "Alg"))
+				aggr = "alg";
+			else if(streq(fields.p[1], "Panic"))
+				aggr = "panic";
+			else if(streq(fields.p[1], "Stack"))
+				aggr = "stack";
 		}
 		if(hasprefix(lines.p[i], "}"))
 			aggr = nil;
@@ -262,6 +280,7 @@ ok:
 
 	bfree(&in);
 	bfree(&b);
+	bfree(&b1);
 	bfree(&out);
 	bfree(&exp);
 	vfree(&argv);
@@ -283,6 +302,10 @@ mkzsys(char *dir, char *file)
 	binit(&out);
 	
 	bwritestr(&out, "// auto generated by go tool dist\n\n");
+	if(streq(goos, "linux")) {
+		bwritestr(&out, "// +build !android\n\n");
+	}
+	
 	if(streq(goos, "windows")) {
 		bwritef(&out,
 			"// runtime·callbackasm is called by external code to\n"
@@ -306,16 +329,20 @@ mkzsys(char *dir, char *file)
 
 static char *runtimedefs[] = {
 	"defs.c",
+	"malloc.c",
+	"mcache.c",
+	"mgc0.c",
 	"proc.c",
 	"parfor.c",
+	"stack.c",
 };
 
 // mkzruntimedefs writes zruntime_defs_$GOOS_$GOARCH.h,
 // which contains Go struct definitions equivalent to the C ones.
 // Mostly we just write the output of 6c -q to the file.
 // However, we run it on multiple files, so we have to delete
-// the duplicated definitions, and we don't care about the funcs
-// and consts, so we delete those too.
+// the duplicated definitions, and we don't care about the funcs,
+// so we delete those too.
 // 
 void
 mkzruntimedefs(char *dir, char *file)
@@ -335,13 +362,24 @@ mkzruntimedefs(char *dir, char *file)
 	vinit(&seen);
 	
 	bwritestr(&out, "// auto generated by go tool dist\n"
-		"\n"
+		"\n");
+
+	if(streq(goos, "linux")) {
+		bwritestr(&out, "// +build !android\n\n");
+	}
+	
+	bwritestr(&out,
 		"package runtime\n"
 		"import \"unsafe\"\n"
 		"var _ unsafe.Pointer\n"
 		"\n"
 	);
 
+	// Do not emit definitions for these.
+	vadd(&seen, "true");
+	vadd(&seen, "false");
+	vadd(&seen, "raceenabled");
+	vadd(&seen, "allgs");
 	
 	// Run 6c -D GOOS_goos -D GOARCH_goarch -I workdir -q -n -o workdir/runtimedefs
 	// on each of the runtimedefs C files.
@@ -352,6 +390,8 @@ mkzruntimedefs(char *dir, char *file)
 	vadd(&argv, bprintf(&b, "GOARCH_%s", goarch));
 	vadd(&argv, "-I");
 	vadd(&argv, bprintf(&b, "%s", workdir));
+	vadd(&argv, "-I");
+	vadd(&argv, bprintf(&b, "%s/pkg/%s_%s", goroot, goos, goarch));
 	vadd(&argv, "-q");
 	vadd(&argv, "-n");
 	vadd(&argv, "-o");
@@ -371,15 +411,15 @@ mkzruntimedefs(char *dir, char *file)
 	splitlines(&lines, bstr(&in));
 	for(i=0; i<lines.len; i++) {
 		p = lines.p[i];
-		// Drop comment, func, and const lines.
-		if(hasprefix(p, "//") || hasprefix(p, "const") || hasprefix(p, "func"))
+		// Drop comment and func lines.
+		if(hasprefix(p, "//") || hasprefix(p, "func"))
 			continue;
 		
 		// Note beginning of type or var decl, which can be multiline.
 		// Remove duplicates.  The linear check of seen here makes the
 		// whole processing quadratic in aggregate, but there are only
 		// about 100 declarations, so this is okay (and simple).
-		if(hasprefix(p, "type ") || hasprefix(p, "var ")) {
+		if(hasprefix(p, "type ") || hasprefix(p, "var ") || hasprefix(p, "const ")) {
 			splitfields(&fields, p);
 			if(fields.len < 2)
 				continue;
@@ -390,6 +430,17 @@ mkzruntimedefs(char *dir, char *file)
 			}
 			vadd(&seen, fields.p[1]);
 		}
+
+		// Const lines are printed in original case (usually upper). Add a leading _ as needed.
+		if(hasprefix(p, "const ")) {
+			if('A' <= p[6] && p[6] <= 'Z')
+				bwritestr(&out, "const _");
+			else
+				bwritestr(&out, "const ");
+			bwritestr(&out, p+6);
+			continue;
+		}
+
 		if(skip) {
 			if(hasprefix(p, "}"))
 				skip = 0;
@@ -398,6 +449,11 @@ mkzruntimedefs(char *dir, char *file)
 		
 		bwritestr(&out, p);
 	}
+
+	// Some windows specific const.
+	if(streq(goos, "windows")) {
+		bwritestr(&out, bprintf(&b, "const cb_max = %d\n", MAXWINCB));
+	}
 	
 	writefile(&out, file, 0);
 
diff --git a/src/cmd/dist/goc2c.c b/src/cmd/dist/goc2c.c
deleted file mode 100644
index 3862765..0000000
--- a/src/cmd/dist/goc2c.c
+++ /dev/null
@@ -1,833 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "a.h"
-
-/*
- * Translate a .goc file into a .c file.  A .goc file is a combination
- * of a limited form of Go with C.
- */
-
-/*
-	package PACKAGENAME
-	{# line}
-	func NAME([NAME TYPE { , NAME TYPE }]) [(NAME TYPE { , NAME TYPE })] \{
-	  C code with proper brace nesting
-	\}
-*/
-
-/*
- * We generate C code which implements the function such that it can
- * be called from Go and executes the C code.
- */
-
-static char *input;
-static Buf *output;
-#define EOF -1
-
-enum
-{
-	use64bitint = 1,
-};
-
-static int
-xgetchar(void)
-{
-	int c;
-	
-	c = *input;
-	if(c == 0)
-		return EOF;
-	input++;
-	return c;
-}
-
-static void
-xungetc(void)
-{
-	input--;
-}
-
-static void
-xputchar(char c)
-{
-	bwrite(output, &c, 1);
-}
-
-static int
-xisspace(int c)
-{
-	return c == ' ' || c == '\t' || c == '\r' || c == '\n';
-}
-
-/* Whether we're emitting for gcc */
-static int gcc;
-
-/* File and line number */
-static const char *file;
-static unsigned int lineno;
-
-/* List of names and types.  */
-struct params {
-	struct params *next;
-	char *name;
-	char *type;
-};
-
-/* index into type_table */
-enum {
-	Bool,
-	Float,
-	Int,
-	Uint,
-	Uintptr,
-	String,
-	Slice,
-	Eface,
-	Complex128,
-	Float32,
-	Float64,
-};
-
-static struct {
-	char *name;
-	int size;
-	int rnd; // alignment
-} type_table[] = {
-	/* 
-	 * variable sized first, for easy replacement.
-	 * order matches enum above.
-	 * default is 32-bit architecture sizes.
-	 * spelling as in package runtime, so intgo/uintgo not int/uint.
-	 */
-	{"bool",	1},
-	{"float",	4},
-	{"intgo",		4},
-	{"uintgo",	4},
-	{"uintptr",	4},
-	{"String",	8},
-	{"Slice",	12},
-	{"Eface",	8},
-	{"Complex128", 16},
-
-	/* fixed size */
-	{"float32",	4},
-	{"float64",	8},
-	{"byte",	1},
-	{"int8",	1},
-	{"uint8",	1},
-	{"int16",	2},
-	{"uint16",	2},
-	{"int32",	4},
-	{"rune",	4},
-	{"uint32",	4},
-	{"int64",	8},
-	{"uint64",	8},
-
-	{nil, 0},
-};
-
-/* Fixed structure alignment (non-gcc only) */
-int structround = 4;
-
-/* Unexpected EOF.  */
-static void
-bad_eof(void)
-{
-	fatal("%s:%d: unexpected EOF\n", file, lineno);
-}
-
-/* Free a list of parameters.  */
-static void
-free_params(struct params *p)
-{
-	while (p != nil) {
-		struct params *next;
-
-		next = p->next;
-		xfree(p->name);
-		xfree(p->type);
-		xfree(p);
-		p = next;
-	}
-}
-
-/* Read a character, tracking lineno.  */
-static int
-getchar_update_lineno(void)
-{
-	int c;
-
-	c = xgetchar();
-	if (c == '\n')
-		++lineno;
-	return c;
-}
-
-/* Read a character, giving an error on EOF, tracking lineno.  */
-static int
-getchar_no_eof(void)
-{
-	int c;
-
-	c = getchar_update_lineno();
-	if (c == EOF)
-		bad_eof();
-	return c;
-}
-
-/* Read a character, skipping comments.  */
-static int
-getchar_skipping_comments(void)
-{
-	int c;
-
-	while (1) {
-		c = getchar_update_lineno();
-		if (c != '/')
-			return c;
-
-		c = xgetchar();
-		if (c == '/') {
-			do {
-				c = getchar_update_lineno();
-			} while (c != EOF && c != '\n');
-			return c;
-		} else if (c == '*') {
-			while (1) {
-				c = getchar_update_lineno();
-				if (c == EOF)
-					return EOF;
-				if (c == '*') {
-					do {
-						c = getchar_update_lineno();
-					} while (c == '*');
-					if (c == '/')
-						break;
-				}
-			}
-		} else {
-			xungetc();
-			return '/';
-		}
-	}
-}
-
-/*
- * Read and return a token.  Tokens are string or character literals
- * or else delimited by whitespace or by [(),{}].
- * The latter are all returned as single characters.
- */
-static char *
-read_token(void)
-{
-	int c, q;
-	char *buf;
-	unsigned int alc, off;
-	char* delims = "(),{}";
-
-	while (1) {
-		c = getchar_skipping_comments();
-		if (c == EOF)
-			return nil;
-		if (!xisspace(c))
-			break;
-	}
-	alc = 16;
-	buf = xmalloc(alc + 1);
-	off = 0;
-	if(c == '"' || c == '\'') {
-		q = c;
-		buf[off] = c;
-		++off;
-		while (1) {
-			if (off+2 >= alc) { // room for c and maybe next char
-				alc *= 2;
-				buf = xrealloc(buf, alc + 1);
-			}
-			c = getchar_no_eof();
-			buf[off] = c;
-			++off;
-			if(c == q)
-				break;
-			if(c == '\\') {
-				buf[off] = getchar_no_eof();
-				++off;
-			}
-		}
-	} else if (xstrrchr(delims, c) != nil) {
-		buf[off] = c;
-		++off;
-	} else {
-		while (1) {
-			if (off >= alc) {
-				alc *= 2;
-				buf = xrealloc(buf, alc + 1);
-			}
-			buf[off] = c;
-			++off;
-			c = getchar_skipping_comments();
-			if (c == EOF)
-				break;
-			if (xisspace(c) || xstrrchr(delims, c) != nil) {
-				if (c == '\n')
-					lineno--;
-				xungetc();
-				break;
-			}
-		}
-	}
-	buf[off] = '\0';
-	return buf;
-}
-
-/* Read a token, giving an error on EOF.  */
-static char *
-read_token_no_eof(void)
-{
-	char *token = read_token();
-	if (token == nil)
-		bad_eof();
-	return token;
-}
-
-/* Read the package clause, and return the package name.  */
-static char *
-read_package(void)
-{
-	char *token;
-
-	token = read_token_no_eof();
-	if (token == nil)
-		fatal("%s:%d: no token\n", file, lineno);
-	if (!streq(token, "package")) {
-		fatal("%s:%d: expected \"package\", got \"%s\"\n",
-			file, lineno, token);
-	}
-	return read_token_no_eof();
-}
-
-/* Read and copy preprocessor lines.  */
-static void
-read_preprocessor_lines(void)
-{
-	int first;
-	
-	first = 1;
-	while (1) {
-		int c;
-
-		do {
-			c = getchar_skipping_comments();
-		} while (xisspace(c));
-		if (c != '#') {
-			xungetc();
-			break;
-		}
-		if(first) {
-			first = 0;
-			xputchar('\n');
-		}
-		xputchar(c);
-		do {
-			c = getchar_update_lineno();
-			xputchar(c);
-		} while (c != '\n');
-	}
-}
-
-/*
- * Read a type in Go syntax and return a type in C syntax.  We only
- * permit basic types and pointers.
- */
-static char *
-read_type(void)
-{
-	char *p, *op, *q;
-	int pointer_count;
-	unsigned int len;
-
-	p = read_token_no_eof();
-	if (*p != '*' && !streq(p, "int") && !streq(p, "uint"))
-		return p;
-	op = p;
-	pointer_count = 0;
-	while (*p == '*') {
-		++pointer_count;
-		++p;
-	}
-	len = xstrlen(p);
-	q = xmalloc(len + 2 + pointer_count + 1);
-	xmemmove(q, p, len);
-
-	// Turn int/uint into intgo/uintgo.
-	if((len == 3 && xmemcmp(q, "int", 3) == 0) || (len == 4 && xmemcmp(q, "uint", 4) == 0)) {
-		q[len++] = 'g';
-		q[len++] = 'o';
-	}
-
-	while (pointer_count-- > 0)
-		q[len++] = '*';
-	
-	q[len] = '\0';
-	xfree(op);
-	return q;
-}
-
-/* Return the size of the given type. */
-static int
-type_size(char *p, int *rnd)
-{
-	int i;
-
-	if(p[xstrlen(p)-1] == '*') {
-		*rnd = type_table[Uintptr].rnd;
-		return type_table[Uintptr].size;
-	}
-
-	if(streq(p, "Iface"))
-		p = "Eface";
-
-	for(i=0; type_table[i].name; i++)
-		if(streq(type_table[i].name, p)) {
-			*rnd = type_table[i].rnd;
-			return type_table[i].size;
-		}
-	fatal("%s:%d: unknown type %s\n", file, lineno, p);
-	return 0;
-}
-
-/*
- * Read a list of parameters.  Each parameter is a name and a type.
- * The list ends with a ')'.  We have already read the '('.
- */
-static struct params *
-read_params(int *poffset)
-{
-	char *token;
-	struct params *ret, **pp, *p;
-	int offset, size, rnd;
-
-	ret = nil;
-	pp = &ret;
-	token = read_token_no_eof();
-	offset = 0;
-	if (!streq(token, ")")) {
-		while (1) {
-			p = xmalloc(sizeof(struct params));
-			p->name = token;
-			p->next = nil;
-			*pp = p;
-			pp = &p->next;
-
-			if(streq(token, "...")) {
-				p->type = xstrdup("");
-			} else {
-				p->type = read_type();
-				rnd = 0;
-				size = type_size(p->type, &rnd);
-				if(rnd > structround)
-					rnd = structround;
-				if(offset%rnd)
-					offset += rnd - offset%rnd;
-				offset += size;
-			}
-
-			token = read_token_no_eof();
-			if (!streq(token, ","))
-				break;
-			token = read_token_no_eof();
-		}
-	}
-	if (!streq(token, ")")) {
-		fatal("%s:%d: expected '('\n",
-			file, lineno);
-	}
-	if (poffset != nil)
-		*poffset = offset;
-	return ret;
-}
-
-/*
- * Read a function header.  This reads up to and including the initial
- * '{' character.  Returns 1 if it read a header, 0 at EOF.
- */
-static int
-read_func_header(char **name, struct params **params, int *paramwid, struct params **rets)
-{
-	int lastline;
-	char *token;
-
-	lastline = -1;
-	while (1) {
-		read_preprocessor_lines();
-		token = read_token();
-		if (token == nil)
-			return 0;
-		if (streq(token, "func")) {
-			if(lastline != -1)
-				bwritef(output, "\n");
-			break;
-		}
-		if (lastline != lineno) {
-			if (lastline == lineno-1)
-				bwritef(output, "\n");
-			else
-				bwritef(output, "\n#line %d \"%s\"\n", lineno, file);
-			lastline = lineno;
-		}
-		bwritef(output, "%s ", token);
-	}
-
-	*name = read_token_no_eof();
-
-	token = read_token();
-	if (token == nil || !streq(token, "(")) {
-		fatal("%s:%d: expected \"(\"\n",
-			file, lineno);
-	}
-	*params = read_params(paramwid);
-
-	token = read_token();
-	if (token == nil || !streq(token, "("))
-		*rets = nil;
-	else {
-		*rets = read_params(nil);
-		token = read_token();
-	}
-	if (token == nil || !streq(token, "{")) {
-		fatal("%s:%d: expected \"{\"\n",
-			file, lineno);
-	}
-	return 1;
-}
-
-/* Write out parameters.  */
-static void
-write_params(struct params *params, int *first)
-{
-	struct params *p;
-
-	for (p = params; p != nil; p = p->next) {
-		if (*first)
-			*first = 0;
-		else
-			bwritef(output, ", ");
-		bwritef(output, "%s %s", p->type, p->name);
-	}
-}
-
-/* Write a 6g function header.  */
-static void
-write_6g_func_header(char *package, char *name, struct params *params,
-		     int paramwid, struct params *rets)
-{
-	int first, n;
-	struct params *p;
-
-	bwritef(output, "void\n");
-	if(!contains(name, "·"))
-		bwritef(output, "%s·", package);
-	bwritef(output, "%s(", name);
-
-	first = 1;
-	write_params(params, &first);
-
-	/* insert padding to align output struct */
-	if(rets != nil && paramwid%structround != 0) {
-		n = structround - paramwid%structround;
-		if(n & 1)
-			bwritef(output, ", uint8");
-		if(n & 2)
-			bwritef(output, ", uint16");
-		if(n & 4)
-			bwritef(output, ", uint32");
-	}
-
-	write_params(rets, &first);
-	bwritef(output, ")\n{\n");
-	
-	for (p = rets; p != nil; p = p->next) {
-		if(streq(p->name, "..."))
-			continue;
-		if(streq(p->type, "Slice"))
-			bwritef(output, "\t%s.array = 0;\n\t%s.len = 0;\n\t%s.cap = 0;\n", p->name, p->name, p->name);
-		else if(streq(p->type, "String"))
-			bwritef(output, "\t%s.str = 0;\n\t%s.len = 0;\n", p->name, p->name);
-		else if(streq(p->type, "Eface"))
-			bwritef(output, "\t%s.type = 0;\n\t%s.data = 0;\n", p->name, p->name);
-		else if(streq(p->type, "Iface"))
-			bwritef(output, "\t%s.tab = 0;\n\t%s.data = 0;\n", p->name, p->name);
-		else if(streq(p->type, "Complex128"))
-			bwritef(output, "\t%s.real = 0;\n\t%s.imag = 0;\n", p->name, p->name);
-		else
-			bwritef(output, "\t%s = 0;\n", p->name);
-		bwritef(output, "\tFLUSH(&%s);\n", p->name);
-	}
-}
-
-/* Write a 6g function trailer.  */
-static void
-write_6g_func_trailer(struct params *rets)
-{
-	struct params *p;
-
-	for (p = rets; p != nil; p = p->next)
-		if(!streq(p->name, "..."))
-			bwritef(output, "\tFLUSH(&%s);\n", p->name);
-	bwritef(output, "}\n");
-}
-
-/* Define the gcc function return type if necessary.  */
-static void
-define_gcc_return_type(char *package, char *name, struct params *rets)
-{
-	struct params *p;
-
-	if (rets == nil || rets->next == nil)
-		return;
-	bwritef(output, "struct %s_%s_ret {\n", package, name);
-	for (p = rets; p != nil; p = p->next)
-		bwritef(output, "  %s %s;\n", p->type, p->name);
-	bwritef(output, "};\n");
-}
-
-/* Write out the gcc function return type.  */
-static void
-write_gcc_return_type(char *package, char *name, struct params *rets)
-{
-	if (rets == nil)
-		bwritef(output, "void");
-	else if (rets->next == nil)
-		bwritef(output, "%s", rets->type);
-	else
-		bwritef(output, "struct %s_%s_ret", package, name);
-}
-
-/* Write out a gcc function header.  */
-static void
-write_gcc_func_header(char *package, char *name, struct params *params,
-		      struct params *rets)
-{
-	int first;
-	struct params *p;
-
-	define_gcc_return_type(package, name, rets);
-	write_gcc_return_type(package, name, rets);
-	bwritef(output, " %s_%s(", package, name);
-	first = 1;
-	write_params(params, &first);
-	bwritef(output, ") asm (\"%s.%s\");\n", package, name);
-	write_gcc_return_type(package, name, rets);
-	bwritef(output, " %s_%s(", package, name);
-	first = 1;
-	write_params(params, &first);
-	bwritef(output, ")\n{\n");
-	for (p = rets; p != nil; p = p->next)
-		bwritef(output, "  %s %s;\n", p->type, p->name);
-}
-
-/* Write out a gcc function trailer.  */
-static void
-write_gcc_func_trailer(char *package, char *name, struct params *rets)
-{
-	if (rets == nil) {
-		// nothing to do
-	}
-	else if (rets->next == nil)
-		bwritef(output, "return %s;\n", rets->name);
-	else {
-		struct params *p;
-
-		bwritef(output, "  {\n    struct %s_%s_ret __ret;\n", package, name);
-		for (p = rets; p != nil; p = p->next)
-			bwritef(output, "    __ret.%s = %s;\n", p->name, p->name);
-		bwritef(output, "    return __ret;\n  }\n");
-	}
-	bwritef(output, "}\n");
-}
-
-/* Write out a function header.  */
-static void
-write_func_header(char *package, char *name,
-		  struct params *params, int paramwid,
-		  struct params *rets)
-{
-	if (gcc)
-		write_gcc_func_header(package, name, params, rets);
-	else
-		write_6g_func_header(package, name, params, paramwid, rets);
-	bwritef(output, "#line %d \"%s\"\n", lineno, file);
-}
-
-/* Write out a function trailer.  */
-static void
-write_func_trailer(char *package, char *name,
-		   struct params *rets)
-{
-	if (gcc)
-		write_gcc_func_trailer(package, name, rets);
-	else
-		write_6g_func_trailer(rets);
-}
-
-/*
- * Read and write the body of the function, ending in an unnested }
- * (which is read but not written).
- */
-static void
-copy_body(void)
-{
-	int nesting = 0;
-	while (1) {
-		int c;
-
-		c = getchar_no_eof();
-		if (c == '}' && nesting == 0)
-			return;
-		xputchar(c);
-		switch (c) {
-		default:
-			break;
-		case '{':
-			++nesting;
-			break;
-		case '}':
-			--nesting;
-			break;
-		case '/':
-			c = getchar_update_lineno();
-			xputchar(c);
-			if (c == '/') {
-				do {
-					c = getchar_no_eof();
-					xputchar(c);
-				} while (c != '\n');
-			} else if (c == '*') {
-				while (1) {
-					c = getchar_no_eof();
-					xputchar(c);
-					if (c == '*') {
-						do {
-							c = getchar_no_eof();
-							xputchar(c);
-						} while (c == '*');
-						if (c == '/')
-							break;
-					}
-				}
-			}
-			break;
-		case '"':
-		case '\'':
-			{
-				int delim = c;
-				do {
-					c = getchar_no_eof();
-					xputchar(c);
-					if (c == '\\') {
-						c = getchar_no_eof();
-						xputchar(c);
-						c = '\0';
-					}
-				} while (c != delim);
-			}
-			break;
-		}
-	}
-}
-
-/* Process the entire file.  */
-static void
-process_file(void)
-{
-	char *package, *name, *p, *n;
-	struct params *params, *rets;
-	int paramwid;
-
-	package = read_package();
-	read_preprocessor_lines();
-	while (read_func_header(&name, &params, &paramwid, &rets)) {
-		// name may have a package override already
-		n = xstrstr(name, "·");
-		if(n != nil) {
-			p = xmalloc(n - name + 1);
-			xmemmove(p, name, n - name);
-			p[n - name] = 0;
-			n += xstrlen("·");
-		} else {
-			p = package;
-			n = name;
-		}
-		write_func_header(p, n, params, paramwid, rets);
-		copy_body();
-		write_func_trailer(p, n, rets);
-		xfree(name);
-		if(p != package) xfree(p);
-		free_params(params);
-		free_params(rets);
-	}
-	xfree(package);
-}
-
-void
-goc2c(char *goc, char *c)
-{
-	int i;
-	Buf in, out;
-	
-	binit(&in);
-	binit(&out);
-	
-	file = goc;
-	readfile(&in, goc);
-
-	// TODO: set gcc=1 when using gcc
-
-	if(!gcc) {
-		if(streq(goarch, "amd64")) {
-			type_table[Uintptr].size = 8;
-			if(use64bitint) {
-				type_table[Int].size = 8;
-			} else {
-				type_table[Int].size = 4;
-			}
-			structround = 8;
-		} else if(streq(goarch, "amd64p32")) {
-			type_table[Uintptr].size = 4;
-			type_table[Int].size = 4;
-			structround = 8;
-		} else {
-			// NOTE: These are set in the initializer,
-			// but they might have been changed by a
-			// previous invocation of goc2c, so we have
-			// to restore them.
-			type_table[Uintptr].size = 4;
-			type_table[Int].size = 4;
-			structround = 4;
-		}
-
-		type_table[Uint].size = type_table[Int].size;
-		type_table[Slice].size = type_table[Uintptr].size+2*type_table[Int].size;
-		type_table[Eface].size = 2*type_table[Uintptr].size;
-		type_table[String].size = 2*type_table[Uintptr].size;
-
-		for(i=0; i<nelem(type_table); i++)
-			type_table[i].rnd = type_table[i].size;
-
-		type_table[String].rnd = type_table[Uintptr].rnd;
-		type_table[Slice].rnd = type_table[Uintptr].rnd;
-		type_table[Eface].rnd = type_table[Uintptr].rnd;
-		type_table[Complex128].rnd = type_table[Float64].rnd;
-	}
-
-	bprintf(&out, "// auto generated by go tool dist\n// goos=%s goarch=%s\n\n", goos, goarch);
-	input = bstr(&in);
-	output = &out;
-
-	lineno = 1;
-	process_file();
-	
-	writefile(&out, c, 0);
-}
diff --git a/src/cmd/dist/plan9.c b/src/cmd/dist/plan9.c
index 8d492eb..e4bf251 100644
--- a/src/cmd/dist/plan9.c
+++ b/src/cmd/dist/plan9.c
@@ -23,7 +23,7 @@ bprintf(Buf *b, char *fmt, ...)
 {
 	va_list arg;
 	char buf[4096];
-	
+
 	breset(b);
 	va_start(arg, fmt);
 	vsnprintf(buf, sizeof buf, fmt, arg);
@@ -572,10 +572,10 @@ bool
 hassuffix(char *p, char *suffix)
 {
 	int np, ns;
-	
+
 	np = strlen(p);
 	ns = strlen(suffix);
-	return np >= ns && strcmp(p+np-ns, suffix) == 0;
+	return np >= ns && streq(p+np-ns, suffix);
 }
 
 // hasprefix reports whether p begins with prefix.
diff --git a/src/cmd/dist/unix.c b/src/cmd/dist/unix.c
index 8b943a2..4a78684 100644
--- a/src/cmd/dist/unix.c
+++ b/src/cmd/dist/unix.c
@@ -431,7 +431,7 @@ xremoveall(char *p)
 	}
 	
 	bfree(&b);
-	vfree(&dir);	
+	vfree(&dir);
 }
 
 // xreaddir replaces dst with a list of the names of the files in dir.
@@ -441,13 +441,13 @@ xreaddir(Vec *dst, char *dir)
 {
 	DIR *d;
 	struct dirent *dp;
-	
+
 	vreset(dst);
 	d = opendir(dir);
 	if(d == nil)
 		fatal("opendir %s: %s", dir, strerror(errno));
 	while((dp = readdir(d)) != nil) {
-		if(strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0)
+		if(streq(dp->d_name, ".") || streq(dp->d_name, ".."))
 			continue;
 		vadd(dst, dp->d_name);
 	}
@@ -461,7 +461,7 @@ xworkdir(void)
 {
 	Buf b;
 	char *p;
-	
+
 	binit(&b);
 
 	xgetenv(&b, "TMPDIR");
@@ -546,10 +546,10 @@ bool
 hassuffix(char *p, char *suffix)
 {
 	int np, ns;
-	
+
 	np = strlen(p);
 	ns = strlen(suffix);
-	return np >= ns && strcmp(p+np-ns, suffix) == 0;
+	return np >= ns && streq(p+np-ns, suffix);
 }
 
 // hasprefix reports whether p begins with prefix.
@@ -712,7 +712,7 @@ main(int argc, char **argv)
 			fatal("unknown architecture: %s", u.machine);
 	}
 
-	if(strcmp(gohostarch, "arm") == 0)
+	if(streq(gohostarch, "arm"))
 		maxnbg = 1;
 
 	// The OS X 10.6 linker does not support external linking mode.
@@ -724,7 +724,7 @@ main(int argc, char **argv)
 	//
 	// Roughly, OS X 10.N shows up as uname release (N+4),
 	// so OS X 10.6 is uname version 10 and OS X 10.8 is uname version 12.
-	if(strcmp(gohostos, "darwin") == 0) {
+	if(streq(gohostos, "darwin")) {
 		if(uname(&u) < 0)
 			fatal("uname: %s", strerror(errno));
 		osx = atoi(u.release) - 4;
diff --git a/src/cmd/dist/windows.c b/src/cmd/dist/windows.c
index 2839c4b..ff1a273 100644
--- a/src/cmd/dist/windows.c
+++ b/src/cmd/dist/windows.c
@@ -770,10 +770,10 @@ bool
 hassuffix(char *p, char *suffix)
 {
 	int np, ns;
-	
+
 	np = strlen(p);
 	ns = strlen(suffix);
-	return np >= ns && strcmp(p+np-ns, suffix) == 0;
+	return np >= ns && streq(p+np-ns, suffix);
 }
 
 bool
@@ -929,7 +929,7 @@ xsamefile(char *f1, char *f2)
 		return 1;
 	
 	torune(&ru, f1);
-	// refer to ../../pkg/os/stat_windows.go:/sameFile
+	// refer to ../../os/stat_windows.go:/sameFile
 	fd1 = CreateFileW(ru, 0, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
 	xfree(ru);
 	if(fd1 == INVALID_HANDLE_VALUE)
diff --git a/src/cmd/fix/doc.go b/src/cmd/fix/doc.go
index 5de3e08..0570169 100644
--- a/src/cmd/fix/doc.go
+++ b/src/cmd/fix/doc.go
@@ -27,7 +27,7 @@ rewrites are idempotent, so that it is safe to apply fix to updated
 or partially updated code even without using the -r flag.
 
 Fix prints the full list of fixes it can apply in its help output;
-to see them, run go tool fix -?.
+to see them, run go tool fix -help.
 
 Fix does not make backup copies of the files that it edits.
 Instead, use a version control system's ``diff'' functionality to inspect
diff --git a/src/cmd/fix/fix.go b/src/cmd/fix/fix.go
index a100be7..a07bbac 100644
--- a/src/cmd/fix/fix.go
+++ b/src/cmd/fix/fix.go
@@ -101,7 +101,7 @@ func walkBeforeAfter(x interface{}, before, after func(interface{})) {
 	case *[]ast.Stmt:
 		walkBeforeAfter(*n, before, after)
 
-	// These are ordered and grouped to match ../../pkg/go/ast/ast.go
+	// These are ordered and grouped to match ../../go/ast/ast.go
 	case *ast.Field:
 		walkBeforeAfter(&n.Names, before, after)
 		walkBeforeAfter(&n.Type, before, after)
diff --git a/src/cmd/gc/align.c b/src/cmd/gc/align.c
index b809640..6e5d149 100644
--- a/src/cmd/gc/align.c
+++ b/src/cmd/gc/align.c
@@ -119,8 +119,10 @@ dowidth(Type *t)
 	if(t->width == -2) {
 		lno = lineno;
 		lineno = t->lineno;
-		if(!t->broke)
+		if(!t->broke) {
+			t->broke = 1;
 			yyerror("invalid recursive type %T", t);
+		}
 		t->width = 0;
 		lineno = lno;
 		return;
diff --git a/src/cmd/gc/bisonerrors b/src/cmd/gc/bisonerrors
index 1f97fc8..fa74c67 100755
--- a/src/cmd/gc/bisonerrors
+++ b/src/cmd/gc/bisonerrors
@@ -22,6 +22,7 @@ BEGIN{
 	bison = 1
 	grammar = 0
 	states = 0
+	open = 0
 }
 
 # In Grammar section of y.output,
@@ -130,11 +131,26 @@ $1 == "%" {
 			continue
 
 		# No shift or reduce applied - found the error.
-		printf("\t%s, %s,\n", state, tok);
+		printf("\t{%s, %s,\n", state, tok);
+		open = 1;
 		break
 	}
 	next
 }
 
 # Print other lines verbatim.
+open && /,$/ {
+	s = $0;
+	sub(",", "},", s)
+	print s
+	open = 0
+	next
+}
+
+open && /"$/ {
+	print $0 "}"
+	open = 0
+	next
+}
+
 {print}
diff --git a/src/cmd/gc/builtin.c b/src/cmd/gc/builtin.c
index 5ca5aeb..fbca4ee 100644
--- a/src/cmd/gc/builtin.c
+++ b/src/cmd/gc/builtin.c
@@ -2,18 +2,19 @@
 char *runtimeimport =
 	"package runtime\n"
 	"import runtime \"runtime\"\n"
-	"func @\"\".new (@\"\".typ·2 *byte) (? *any)\n"
+	"func @\"\".newobject (@\"\".typ·2 *byte) (? *any)\n"
 	"func @\"\".panicindex ()\n"
 	"func @\"\".panicslice ()\n"
 	"func @\"\".panicdivide ()\n"
 	"func @\"\".throwreturn ()\n"
 	"func @\"\".throwinit ()\n"
 	"func @\"\".panicwrap (? string, ? string, ? string)\n"
-	"func @\"\".panic (? interface {})\n"
-	"func @\"\".recover (? *int32) (? interface {})\n"
+	"func @\"\".gopanic (? interface {})\n"
+	"func @\"\".gorecover (? *int32) (? interface {})\n"
 	"func @\"\".printbool (? bool)\n"
 	"func @\"\".printfloat (? float64)\n"
 	"func @\"\".printint (? int64)\n"
+	"func @\"\".printhex (? uint64)\n"
 	"func @\"\".printuint (? uint64)\n"
 	"func @\"\".printcomplex (? complex128)\n"
 	"func @\"\".printstring (? string)\n"
@@ -23,7 +24,6 @@ char *runtimeimport =
 	"func @\"\".printslice (? any)\n"
 	"func @\"\".printnl ()\n"
 	"func @\"\".printsp ()\n"
-	"func @\"\".goprintf ()\n"
 	"func @\"\".concatstring2 (? string, ? string) (? string)\n"
 	"func @\"\".concatstring3 (? string, ? string, ? string) (? string)\n"
 	"func @\"\".concatstring4 (? string, ? string, ? string, ? string) (? string)\n"
@@ -39,7 +39,7 @@ char *runtimeimport =
 	"func @\"\".stringtoslicerune (? string) (? []rune)\n"
 	"func @\"\".stringiter (? string, ? int) (? int)\n"
 	"func @\"\".stringiter2 (? string, ? int) (@\"\".retk·1 int, @\"\".retv·2 rune)\n"
-	"func @\"\".copy (@\"\".to·2 any, @\"\".fr·3 any, @\"\".wid·4 uintptr) (? int)\n"
+	"func @\"\".slicecopy (@\"\".to·2 any, @\"\".fr·3 any, @\"\".wid·4 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"
@@ -64,7 +64,6 @@ char *runtimeimport =
 	"func @\"\".efaceeq (@\"\".i1·2 any, @\"\".i2·3 any) (@\"\".ret·1 bool)\n"
 	"func @\"\".ifacethash (@\"\".i1·2 any) (@\"\".ret·1 uint32)\n"
 	"func @\"\".efacethash (@\"\".i1·2 any) (@\"\".ret·1 uint32)\n"
-	"func @\"\".equal (@\"\".typ·2 *byte, @\"\".x1·3 any, @\"\".x2·4 any) (@\"\".ret·1 bool)\n"
 	"func @\"\".makemap (@\"\".mapType·2 *byte, @\"\".hint·3 int64) (@\"\".hmap·1 map[any]any)\n"
 	"func @\"\".mapaccess1 (@\"\".mapType·2 *byte, @\"\".hmap·3 map[any]any, @\"\".key·4 *any) (@\"\".val·1 *any)\n"
 	"func @\"\".mapaccess1_fast32 (@\"\".mapType·2 *byte, @\"\".hmap·3 map[any]any, @\"\".key·4 any) (@\"\".val·1 *any)\n"
@@ -83,10 +82,18 @@ char *runtimeimport =
 	"func @\"\".chanrecv2 (@\"\".chanType·2 *byte, @\"\".hchan·3 <-chan any, @\"\".elem·4 *any) (? bool)\n"
 	"func @\"\".chansend1 (@\"\".chanType·1 *byte, @\"\".hchan·2 chan<- any, @\"\".elem·3 *any)\n"
 	"func @\"\".closechan (@\"\".hchan·1 any)\n"
+	"func @\"\".writebarrierptr (@\"\".dst·1 *any, @\"\".src·2 any)\n"
+	"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 @\"\".writebarrierfat2 (@\"\".dst·1 *any, _ *byte, @\"\".src·3 any)\n"
+	"func @\"\".writebarrierfat3 (@\"\".dst·1 *any, _ *byte, @\"\".src·3 any)\n"
+	"func @\"\".writebarrierfat4 (@\"\".dst·1 *any, _ *byte, @\"\".src·3 any)\n"
+	"func @\"\".writebarrierfat (@\"\".typ·1 *byte, @\"\".dst·2 *any, @\"\".src·3 *any)\n"
 	"func @\"\".selectnbsend (@\"\".chanType·2 *byte, @\"\".hchan·3 chan<- any, @\"\".elem·4 *any) (? bool)\n"
 	"func @\"\".selectnbrecv (@\"\".chanType·2 *byte, @\"\".elem·3 *any, @\"\".hchan·4 <-chan any) (? bool)\n"
 	"func @\"\".selectnbrecv2 (@\"\".chanType·2 *byte, @\"\".elem·3 *any, @\"\".received·4 *bool, @\"\".hchan·5 <-chan any) (? bool)\n"
-	"func @\"\".newselect (@\"\".size·2 int32) (@\"\".sel·1 *byte)\n"
+	"func @\"\".newselect (@\"\".sel·1 *byte, @\"\".selsize·2 int64, @\"\".size·3 int32)\n"
 	"func @\"\".selectsend (@\"\".sel·2 *byte, @\"\".hchan·3 chan<- any, @\"\".elem·4 *any) (@\"\".selected·1 bool)\n"
 	"func @\"\".selectrecv (@\"\".sel·2 *byte, @\"\".hchan·3 <-chan any, @\"\".elem·4 *any) (@\"\".selected·1 bool)\n"
 	"func @\"\".selectrecv2 (@\"\".sel·2 *byte, @\"\".hchan·3 <-chan any, @\"\".elem·4 *any, @\"\".received·5 *bool) (@\"\".selected·1 bool)\n"
@@ -96,12 +103,12 @@ char *runtimeimport =
 	"func @\"\".makeslice (@\"\".typ·2 *byte, @\"\".nel·3 int64, @\"\".cap·4 int64) (@\"\".ary·1 []any)\n"
 	"func @\"\".growslice (@\"\".typ·2 *byte, @\"\".old·3 []any, @\"\".n·4 int64) (@\"\".ary·1 []any)\n"
 	"func @\"\".memmove (@\"\".to·1 *any, @\"\".frm·2 *any, @\"\".length·3 uintptr)\n"
-	"func @\"\".memequal (@\"\".eq·1 *bool, @\"\".size·2 uintptr, @\"\".x·3 *any, @\"\".y·4 *any)\n"
-	"func @\"\".memequal8 (@\"\".eq·1 *bool, @\"\".size·2 uintptr, @\"\".x·3 *any, @\"\".y·4 *any)\n"
-	"func @\"\".memequal16 (@\"\".eq·1 *bool, @\"\".size·2 uintptr, @\"\".x·3 *any, @\"\".y·4 *any)\n"
-	"func @\"\".memequal32 (@\"\".eq·1 *bool, @\"\".size·2 uintptr, @\"\".x·3 *any, @\"\".y·4 *any)\n"
-	"func @\"\".memequal64 (@\"\".eq·1 *bool, @\"\".size·2 uintptr, @\"\".x·3 *any, @\"\".y·4 *any)\n"
-	"func @\"\".memequal128 (@\"\".eq·1 *bool, @\"\".size·2 uintptr, @\"\".x·3 *any, @\"\".y·4 *any)\n"
+	"func @\"\".memequal (@\"\".x·2 *any, @\"\".y·3 *any, @\"\".size·4 uintptr) (? bool)\n"
+	"func @\"\".memequal8 (@\"\".x·2 *any, @\"\".y·3 *any, @\"\".size·4 uintptr) (? bool)\n"
+	"func @\"\".memequal16 (@\"\".x·2 *any, @\"\".y·3 *any, @\"\".size·4 uintptr) (? bool)\n"
+	"func @\"\".memequal32 (@\"\".x·2 *any, @\"\".y·3 *any, @\"\".size·4 uintptr) (? bool)\n"
+	"func @\"\".memequal64 (@\"\".x·2 *any, @\"\".y·3 *any, @\"\".size·4 uintptr) (? bool)\n"
+	"func @\"\".memequal128 (@\"\".x·2 *any, @\"\".y·3 *any, @\"\".size·4 uintptr) (? bool)\n"
 	"func @\"\".int64div (? int64, ? int64) (? int64)\n"
 	"func @\"\".uint64div (? uint64, ? uint64) (? uint64)\n"
 	"func @\"\".int64mod (? int64, ? int64) (? int64)\n"
diff --git a/src/cmd/gc/bv.c b/src/cmd/gc/bv.c
index 0e8f8d4..cfd1cd2 100644
--- a/src/cmd/gc/bv.c
+++ b/src/cmd/gc/bv.c
@@ -108,6 +108,9 @@ bvnext(Bvec *bv, int32 i)
 {
 	uint32 w;
 
+	if(i >= bv->n)
+		return -1;
+
 	// Jump i ahead to next word with bits.
 	if((bv->b[i>>WORDSHIFT]>>(i&WORDMASK)) == 0) {
 		i &= ~WORDMASK;
@@ -117,7 +120,7 @@ bvnext(Bvec *bv, int32 i)
 	}
 	if(i >= bv->n)
 		return -1;
-	
+
 	// Find 1 bit.
 	w = bv->b[i>>WORDSHIFT]>>(i&WORDMASK);
 	while((w&1) == 0) {
diff --git a/src/cmd/gc/const.c b/src/cmd/gc/const.c
index 143c173..e418b9c 100644
--- a/src/cmd/gc/const.c
+++ b/src/cmd/gc/const.c
@@ -6,6 +6,7 @@
 #include	<libc.h>
 #include	"go.h"
 #define	TUP(x,y)	(((x)<<16)|(y))
+/*c2go int TUP(int, int); */
 
 static	Val	tocplx(Val);
 static	Val	toflt(Val);
@@ -1565,7 +1566,6 @@ isgoconst(Node *n)
 	case ORSH:
 	case OSUB:
 	case OXOR:
-	case OCONV:
 	case OIOTA:
 	case OCOMPLEX:
 	case OREAL:
@@ -1573,7 +1573,12 @@ isgoconst(Node *n)
 		if(isgoconst(n->left) && (n->right == N || isgoconst(n->right)))
 			return 1;
 		break;
-	
+
+	case OCONV:
+		if(okforconst[n->type->etype] && isgoconst(n->left))
+			return 1;
+		break;
+
 	case OLEN:
 	case OCAP:
 		l = n->left;
diff --git a/src/cmd/gc/dcl.c b/src/cmd/gc/dcl.c
index 73c2581..dfcf475 100644
--- a/src/cmd/gc/dcl.c
+++ b/src/cmd/gc/dcl.c
@@ -488,6 +488,10 @@ colasdefn(NodeList *left, Node *defn)
 	NodeList *l;
 	Node *n;
 
+	for(l=left; l; l=l->next)
+		if(l->n->sym != S)
+			l->n->sym->flags |= SymUniq;
+
 	nnew = 0;
 	nerr = 0;
 	for(l=left; l; l=l->next) {
@@ -499,6 +503,13 @@ colasdefn(NodeList *left, Node *defn)
 			nerr++;
 			continue;
 		}
+		if((n->sym->flags & SymUniq) == 0) {
+			yyerrorl(defn->lineno, "%S repeated on left side of :=", n->sym);
+			n->diag++;
+			nerr++;
+			continue;
+		}
+		n->sym->flags &= ~SymUniq;
 		if(n->sym->block == block)
 			continue;
 
@@ -547,6 +558,9 @@ ifacedcl(Node *n)
 	if(n->op != ODCLFIELD || n->right == N)
 		fatal("ifacedcl");
 
+	if(isblank(n->left))
+		yyerror("methods must have a unique non-blank name");
+
 	dclcontext = PPARAM;
 	markdcl();
 	funcdepth++;
diff --git a/src/cmd/gc/esc.c b/src/cmd/gc/esc.c
index 78624d7..324f24f 100644
--- a/src/cmd/gc/esc.c
+++ b/src/cmd/gc/esc.c
@@ -495,7 +495,7 @@ esc(EscState *e, Node *n, Node *up)
 
 	case ORANGE:
 		// Everything but fixed array is a dereference.
-		if(isfixedarray(n->type) && n->list->next)
+		if(isfixedarray(n->type) && n->list && n->list->next)
 			escassign(e, n->list->next->n, n->right);
 		break;
 
@@ -1110,6 +1110,7 @@ escflood(EscState *e, Node *dst)
 // pass all the tests we have written so far, which we assume matches
 // the level of complexity we want the escape analysis code to handle.
 #define MinLevel (-2)
+/*c2go enum { MinLevel = -2 };*/
 
 static void
 escwalk(EscState *e, int level, Node *dst, Node *src)
diff --git a/src/cmd/gc/fmt.c b/src/cmd/gc/fmt.c
index b5f8a83..89d2a14 100644
--- a/src/cmd/gc/fmt.c
+++ b/src/cmd/gc/fmt.c
@@ -649,7 +649,7 @@ typefmt(Fmt *fp, Type *t)
 
 		if(t->funarg) {
 			fmtstrcpy(fp, "(");
-			if(fmtmode == FTypeId || fmtmode == FErr) {	// no argument names on function signature, and no "noescape" tags
+			if(fmtmode == FTypeId || fmtmode == FErr) {	// no argument names on function signature, and no "noescape"/"nosplit" tags
 				for(t1=t->type; t1!=T; t1=t1->down)
 					if(t1->down)
 						fmtprint(fp, "%hT, ", t1);
@@ -810,6 +810,13 @@ stmtfmt(Fmt *f, Node *n)
 		break;
 
 	case OASOP:
+		if(n->implicit) {
+			if(n->etype == OADD)
+				fmtprint(f, "%N++", n->left);
+			else
+				fmtprint(f, "%N--", n->left);
+			break;
+		}
 		fmtprint(f, "%N %#O= %N", n->left, n->etype, n->right);
 		break;
 
@@ -880,7 +887,11 @@ stmtfmt(Fmt *f, Node *n)
 			fmtstrcpy(f, "for loop");
 			break;
 		}
-
+		
+		if(n->list == nil) {
+			fmtprint(f, "for range %N { %H }", n->right, n->nbody);
+			break;
+		}
 		fmtprint(f, "for %,H = range %N { %H }", n->list, n->right, n->nbody);
 		break;
 
@@ -974,7 +985,6 @@ static int opprec[] = {
 	[OTFUNC] = 8,
 	[OTINTER] = 8,
 	[OTMAP] = 8,
-	[OTPAREN] = 8,
 	[OTSTRUCT] = 8,
 
 	[OINDEXMAP] = 8,
@@ -1105,16 +1115,11 @@ exprfmt(Fmt *f, Node *n, int prec)
 
 	case ONAME:
 		// Special case: name used as local variable in export.
-		switch(n->class&~PHEAP){
-		case PAUTO:
-		case PPARAM:
-		case PPARAMOUT:
-			// _ becomes ~b%d internally; print as _ for export
-			if(fmtmode == FExp && n->sym && n->sym->name[0] == '~' && n->sym->name[1] == 'b')
-				return fmtprint(f, "_");
-			if(fmtmode == FExp && n->sym && !isblank(n) && n->vargen > 0)
-				return fmtprint(f, "%S·%d", n->sym, n->vargen);
-		}
+		// _ becomes ~b%d internally; print as _ for export
+		if(fmtmode == FExp && n->sym && n->sym->name[0] == '~' && n->sym->name[1] == 'b')
+			return fmtprint(f, "_");
+		if(fmtmode == FExp && n->sym && !isblank(n) && n->vargen > 0)
+			return fmtprint(f, "%S·%d", n->sym, n->vargen);
 
 		// Special case: explicit name of func (*T) method(...) is turned into pkg.(*T).method,
 		// but for export, this should be rendered as (*pkg.T).meth.
@@ -1140,9 +1145,6 @@ exprfmt(Fmt *f, Node *n, int prec)
 			return fmtprint(f, "[]%N", n->left);
 		return fmtprint(f, "[]%N", n->right);  // happens before typecheck
 
-	case OTPAREN:
-		return fmtprint(f, "(%N)", n->left);
-
 	case OTMAP:
 		return fmtprint(f, "map[%N]%N", n->left, n->right);
 
@@ -1153,7 +1155,7 @@ exprfmt(Fmt *f, Node *n, int prec)
 		case Csend:
 			return fmtprint(f, "chan<- %N", n->left);
 		default:
-			if(n->left != N && n->left->op == TCHAN && n->left->sym == S && n->left->etype == Crecv)
+			if(n->left != N && n->left->op == OTCHAN && n->left->sym == S && n->left->etype == Crecv)
 				return fmtprint(f, "chan (%N)", n->left);
 			else
 				return fmtprint(f, "chan %N", n->left);
diff --git a/src/cmd/gc/gen.c b/src/cmd/gc/gen.c
index cf630f3..c7c9fcd 100644
--- a/src/cmd/gc/gen.c
+++ b/src/cmd/gc/gen.c
@@ -54,9 +54,6 @@ addrescapes(Node *n)
 		if(n->class == PAUTO && n->esc == EscNever)
 			break;
 
-		if(debug['N'] && n->esc != EscUnknown)
-			fatal("without escape analysis, only PAUTO's should have esc: %N", n);
-
 		switch(n->class) {
 		case PPARAMREF:
 			addrescapes(n->defn);
@@ -91,8 +88,7 @@ addrescapes(Node *n)
 			snprint(buf, sizeof buf, "&%S", n->sym);
 			n->heapaddr->sym = lookup(buf);
 			n->heapaddr->orig->sym = n->heapaddr->sym;
-			if(!debug['N'])
-				n->esc = EscHeap;
+			n->esc = EscHeap;
 			if(debug['m'])
 				print("%L: moved to heap: %N\n", n->lineno, n);
 			curfn = oldfn;
@@ -584,6 +580,8 @@ cgen_dcl(Node *n)
 	}
 	if(!(n->class & PHEAP))
 		return;
+	if(compiling_runtime)
+		yyerror("%N escapes to heap, not allowed in runtime.", n);
 	if(n->alloc == nil)
 		n->alloc = callnew(n->type);
 	cgen_as(n->heapaddr, n->alloc);
@@ -733,14 +731,10 @@ cgen_as(Node *nl, Node *nr)
 		return;
 	}
 
-	if(nr == N || isnil(nr)) {
-		// externals and heaps should already be clear
-		if(nr == N) {
-			if(nl->class == PEXTERN)
-				return;
-			if(nl->class & PHEAP)
-				return;
-		}
+	if(nr == N || iszero(nr)) {
+		// heaps should already be clear
+		if(nr == N && (nl->class & PHEAP))
+			return;
 
 		tl = nl->type;
 		if(tl == T)
@@ -804,7 +798,8 @@ cgen_eface(Node *n, Node *res)
 void
 cgen_slice(Node *n, Node *res)
 {
-	Node src, dst, *cap, *len, *offs, *add, *base;
+	Node src, dst, *cap, *len, *offs, *add, *base, *tmpcap, *tmplen, *cmp, con;
+	Prog *p1, *p2;
 
 	cap = n->list->n;
 	len = n->list->next->n;
@@ -821,6 +816,11 @@ cgen_slice(Node *n, Node *res)
 	// garbage collector can see.
 	
 	base = temp(types[TUINTPTR]);
+	tmplen = temp(types[TINT]);
+	if(n->op != OSLICESTR)
+		tmpcap = temp(types[TINT]);
+	else
+		tmpcap = tmplen;
 
 	if(isnil(n->left)) {
 		tempname(&src, n->left->type);
@@ -835,43 +835,62 @@ cgen_slice(Node *n, Node *res)
 			fatal("slicearr is supposed to work on pointer: %+N\n", n);
 		cgen(&src, base);
 		cgen_checknil(base);
-		if(offs != N) {
-			add = nod(OADD, base, offs);
-			typecheck(&add, Erv);
-			cgen(add, base);
-		}
-	} else if(offs == N) {
-		src.type = types[tptr];
-		cgen(&src, base);
 	} else {
 		src.type = types[tptr];
-		add = nod(OADDPTR, &src, offs);
-		typecheck(&add, Erv);
-		cgen(add, base);
+		cgen(&src, base);
 	}
 	
 	// committed to the update
 	gvardef(res);
 
+	// compute len and cap.
+	// len = n-i, cap = m-i, and offs = i*width.
+	// computing offs last lets the multiply overwrite i.
+	cgen(len, tmplen);
+	if(n->op != OSLICESTR)
+		cgen(cap, tmpcap);
+
+	// if new cap != 0 { base += add }
+	// This avoids advancing base past the end of the underlying array/string,
+	// so that it cannot point at the next object in memory.
+	// If cap == 0, the base doesn't matter except insofar as it is 0 or non-zero.
+	// In essence we are replacing x[i:j:k] where i == j == k
+	// or x[i:j] where i == j == cap(x) with x[0:0:0].
+	if(offs != N) {
+		p1 = gjmp(P);
+		p2 = gjmp(P);
+		patch(p1, pc);
+
+		nodconst(&con, tmpcap->type, 0);
+		cmp = nod(OEQ, tmpcap, &con);
+		typecheck(&cmp, Erv);
+		bgen(cmp, 1, -1, p2);
+
+		add = nod(OADD, base, offs);
+		typecheck(&add, Erv);
+		cgen(add, base);
+
+		patch(p2, pc);
+	}
+
 	// dst.array = src.array  [ + lo *width ]
 	dst = *res;
 	dst.xoffset += Array_array;
 	dst.type = types[tptr];
-	
 	cgen(base, &dst);
 
 	// dst.len = hi [ - lo ]
 	dst = *res;
 	dst.xoffset += Array_nel;
 	dst.type = types[simtype[TUINT]];
-	cgen(len, &dst);
+	cgen(tmplen, &dst);
 
 	if(n->op != OSLICESTR) {
 		// dst.cap = cap [ - lo ]
 		dst = *res;
 		dst.xoffset += Array_cap;
 		dst.type = types[simtype[TUINT]];
-		cgen(cap, &dst);
+		cgen(tmpcap, &dst);
 	}
 }
 
diff --git a/src/cmd/gc/go.h b/src/cmd/gc/go.h
index ee879f6..965a055 100644
--- a/src/cmd/gc/go.h
+++ b/src/cmd/gc/go.h
@@ -269,6 +269,7 @@ struct	Node
 	uchar	colas;		// OAS resulting from :=
 	uchar	diag;		// already printed error about this
 	uchar	noescape;	// func arguments do not escape
+	uchar	nosplit;	// func should not execute on separate stack
 	uchar	builtin;	// built-in name, like len or close
 	uchar	walkdef;
 	uchar	typecheck;
@@ -282,6 +283,7 @@ struct	Node
 	uchar	addrtaken;	// address taken, even if not moved to heap
 	uchar	dupok;	// duplicate definitions ok (for func)
 	uchar	wrapper;	// is method wrapper (for func)
+	uchar	reslice;	// this is a reslice x = x[0:y] or x = append(x, ...)
 	schar	likely; // likeliness of if statement
 	uchar	hasbreak;	// has break statement
 	uchar	needzero; // if it contains pointers, needs to be zeroed on function entry
@@ -380,7 +382,6 @@ enum
 	SymExported	= 1<<2,	// already written out by export
 	SymUniq		= 1<<3,
 	SymSiggen	= 1<<4,
-	SymGcgen	= 1<<5,
 };
 
 struct	Sym
@@ -447,7 +448,6 @@ enum
 	OSUB,	// x - y
 	OOR,	// x | y
 	OXOR,	// x ^ y
-	OADDPTR,	// ptr + uintptr, inserted by compiler only, used to avoid unsafe type changes during codegen
 	OADDSTR,	// s + "foo"
 	OADDR,	// &x
 	OANDAND,	// b0 && b1
@@ -573,7 +573,6 @@ enum
 	OTINTER,	// interface{}
 	OTFUNC,	// func()
 	OTARRAY,	// []int, [8]int, [N]int or [...]int
-	OTPAREN,	// (T)
 
 	// misc
 	ODDD,	// func f(args ...int) or f(l...) or var a = [...]int{0, 1, 2}.
@@ -975,11 +974,13 @@ EXTERN	int	funcdepth;
 EXTERN	int	typecheckok;
 EXTERN	int	compiling_runtime;
 EXTERN	int	compiling_wrappers;
+EXTERN	int	use_writebarrier;
 EXTERN	int	pure_go;
 EXTERN	char*	flag_installsuffix;
 EXTERN	int	flag_race;
 EXTERN	int	flag_largemodel;
 EXTERN	int	noescape;
+EXTERN	int	nosplit;
 EXTERN	int	debuglive;
 EXTERN	Link*	ctxt;
 
@@ -1169,6 +1170,7 @@ void	cgen_callmeth(Node *n, int proc);
 void	cgen_eface(Node* n, Node* res);
 void	cgen_slice(Node* n, Node* res);
 void	clearlabels(void);
+void	clearslim(Node*);
 void	checklabels(void);
 int	dotoffset(Node *n, int64 *oary, Node **nn);
 void	gen(Node *n);
@@ -1284,6 +1286,7 @@ LSym*	linksym(Sym*);
  *	order.c
  */
 void	order(Node *fn);
+void	orderstmtinplace(Node **stmt);
 
 /*
  *	range.c
@@ -1302,7 +1305,6 @@ Sym*	typenamesym(Type *t);
 Sym*	tracksym(Type *t);
 Sym*	typesymprefix(char *prefix, Type *t);
 int	haspointers(Type *t);
-void	usefield(Node*);
 Type*	hiter(Type* t);
 
 /*
@@ -1364,6 +1366,7 @@ int	is64(Type *t);
 int	isbadimport(Strlit *s);
 int	isblank(Node *n);
 int	isblanksym(Sym *s);
+int	isdirectiface(Type*);
 int	isfixedarray(Type *t);
 int	isideal(Type *t);
 int	isinter(Type *t);
@@ -1372,6 +1375,7 @@ int	isnilinter(Type *t);
 int	isptrto(Type *t, int et);
 int	isslice(Type *t);
 int	istype(Type *t, int et);
+int	iszero(Node *n);
 void	linehist(char *file, int32 off, int relative);
 NodeList*	list(NodeList *l, Node *n);
 NodeList*	list1(Node *n);
@@ -1464,7 +1468,9 @@ void	walkstmt(Node **np);
 void	walkstmtlist(NodeList *l);
 Node*	conv(Node*, Type*);
 int	candiscard(Node*);
+int	needwritebarrier(Node*, Node*);
 Node*	outervalue(Node*);
+void	usefield(Node*);
 
 /*
  *	arch-specific ggen.c/gsubr.c/gobj.c/pgen.c/plive.c
@@ -1505,7 +1511,7 @@ void	gdata(Node*, Node*, int);
 void	gdatacomplex(Node*, Mpcplx*);
 void	gdatastring(Node*, Strlit*);
 void	ggloblnod(Node *nam);
-void	ggloblsym(Sym *s, int32 width, int dupok, int rodata);
+void	ggloblsym(Sym *s, int32 width, int8 flags);
 void	gvardef(Node*);
 void	gvarkill(Node*);
 Prog*	gjmp(Prog*);
@@ -1514,6 +1520,7 @@ void	movelarge(NodeList*);
 int	isfat(Type*);
 void	linkarchinit(void);
 void	liveness(Node*, Prog*, Sym*, Sym*);
+void	twobitwalktype1(Type*, vlong*, Bvec*);
 void	markautoused(Prog*);
 Plist*	newplist(void);
 Node*	nodarg(Type*, int);
diff --git a/src/cmd/gc/go.y b/src/cmd/gc/go.y
index 2f354f7..68fccc1 100644
--- a/src/cmd/gc/go.y
+++ b/src/cmd/gc/go.y
@@ -460,11 +460,13 @@ simple_stmt:
 |	expr LINC
 	{
 		$$ = nod(OASOP, $1, nodintconst(1));
+		$$->implicit = 1;
 		$$->etype = OADD;
 	}
 |	expr LDEC
 	{
 		$$ = nod(OASOP, $1, nodintconst(1));
+		$$->implicit = 1;
 		$$->etype = OSUB;
 	}
 
@@ -613,6 +615,11 @@ range_stmt:
 		$$->colas = 1;
 		colasdefn($1, $$);
 	}
+|	LRANGE expr
+	{
+		$$ = nod(ORANGE, N, $2);
+		$$->etype = 0; // := flag
+	}
 
 for_header:
 	osimple_stmt ';' osimple_stmt ';' osimple_stmt
@@ -1180,7 +1187,7 @@ ntype:
 |	dotname
 |	'(' ntype ')'
 	{
-		$$ = nod(OTPAREN, $2, N);
+		$$ = $2;
 	}
 
 non_expr_type:
@@ -1199,7 +1206,7 @@ non_recvchantype:
 |	dotname
 |	'(' ntype ')'
 	{
-		$$ = nod(OTPAREN, $2, N);
+		$$ = $2;
 	}
 
 convtype:
@@ -1311,6 +1318,7 @@ xfndcl:
 		$$->nbody = $3;
 		$$->endlineno = lineno;
 		$$->noescape = noescape;
+		$$->nosplit = nosplit;
 		funcbody($$);
 	}
 
@@ -1365,8 +1373,6 @@ fndcl:
 			yyerror("bad receiver in method");
 			break;
 		}
-		if(rcvr->right->op == OTPAREN || (rcvr->right->op == OIND && rcvr->right->left->op == OTPAREN))
-			yyerror("cannot parenthesize receiver type");
 
 		t = nod(OTFUNC, rcvr, N);
 		t->list = $6;
@@ -1495,6 +1501,7 @@ xdcl_list:
 			testdclstack();
 		nointerface = 0;
 		noescape = 0;
+		nosplit = 0;
 	}
 
 vardcl_list:
diff --git a/src/cmd/gc/lex.c b/src/cmd/gc/lex.c
index a50101c..523ba37 100644
--- a/src/cmd/gc/lex.c
+++ b/src/cmd/gc/lex.c
@@ -45,7 +45,7 @@ static struct {
 };
 
 // Debug arguments.
-// These can be specified with the -d flag, as in "-d checknil"
+// These can be specified with the -d flag, as in "-d nil"
 // to set the debug_checknil variable. In general the list passed
 // to -d can be comma-separated.
 static struct {
@@ -139,6 +139,8 @@ yy_isalnum(int c)
 #define isalnum use_yy_isalnum_instead_of_isalnum
 
 #define	DBG	if(!debug['x']){}else print
+/*c2go void DBG(char*, ...); */
+
 enum
 {
 	EOF		= -1,
@@ -310,6 +312,8 @@ main(int argc, char *argv[])
 	flagcount("u", "reject unsafe code", &safemode);
 	flagcount("v", "increase debug verbosity", &debug['v']);
 	flagcount("w", "debug type checking", &debug['w']);
+	use_writebarrier = 1;
+	flagcount("wb", "enable write barrier", &use_writebarrier);
 	flagcount("x", "debug lexer", &debug['x']);
 	flagcount("y", "debug declarations in canned imports (with -d)", &debug['y']);
 	if(thechar == '6')
@@ -317,6 +321,7 @@ main(int argc, char *argv[])
 
 	flagparse(&argc, &argv, usage);
 	ctxt->debugasm = debug['S'];
+	ctxt->debugvlog = debug['v'];
 
 	if(argc < 1)
 		usage();
@@ -339,8 +344,8 @@ main(int argc, char *argv[])
 					break;
 				}
 			}
-			if(j == nelem(debugtab))
-				fatal("unknown debug information -d '%s'\n", f[i]);
+			if(debugtab[j].name == nil)
+				sysfatal("unknown debug information -d '%s'\n", f[i]);
 		}
 	}
 
@@ -476,8 +481,12 @@ main(int argc, char *argv[])
 	}
 
 	// Phase 5: Escape analysis.
-	if(!debug['N'])
-		escapes(xtop);
+	// Required for moving heap allocations onto stack,
+	// which in turn is required by the closure implementation,
+	// which stores the addresses of stack variables into the closure.
+	// If the closure does not escape, it needs to be on the stack
+	// or else the stack copier will not update it.
+	escapes(xtop);
 	
 	// Escape analysis moved escaped values off stack.
 	// Move large values off stack too.
@@ -516,24 +525,18 @@ saveerrors(void)
 	nerrors = 0;
 }
 
-/*
- *	macro to portably read/write archive header.
- *	'cmd' is read/write/Bread/Bwrite, etc.
- */
-#define	HEADER_IO(cmd, f, h)	cmd(f, h.name, sizeof(h.name)) != sizeof(h.name)\
-				|| cmd(f, h.date, sizeof(h.date)) != sizeof(h.date)\
-				|| cmd(f, h.uid, sizeof(h.uid)) != sizeof(h.uid)\
-				|| cmd(f, h.gid, sizeof(h.gid)) != sizeof(h.gid)\
-				|| cmd(f, h.mode, sizeof(h.mode)) != sizeof(h.mode)\
-				|| cmd(f, h.size, sizeof(h.size)) != sizeof(h.size)\
-				|| cmd(f, h.fmag, sizeof(h.fmag)) != sizeof(h.fmag)
-
 static int
 arsize(Biobuf *b, char *name)
 {
 	struct ar_hdr a;
 
-	if (HEADER_IO(Bread, b, a))
+	if(Bread(b, a.name, sizeof(a.name)) != sizeof(a.name) ||
+	   Bread(b, a.date, sizeof(a.date)) != sizeof(a.date) ||
+	   Bread(b, a.uid, sizeof(a.uid)) != sizeof(a.uid) ||
+	   Bread(b, a.gid, sizeof(a.gid)) != sizeof(a.gid) ||
+	   Bread(b, a.mode, sizeof(a.mode)) != sizeof(a.mode) ||
+	   Bread(b, a.size, sizeof(a.size)) != sizeof(a.size) ||
+	   Bread(b, a.fmag, sizeof(a.fmag)) != sizeof(a.fmag))
 		return -1;
 
 	if(strncmp(a.name, name, strlen(name)) != 0)
@@ -1592,6 +1595,10 @@ go:
 		noescape = 1;
 		goto out;
 	}
+	if(strcmp(lexbuf, "go:nosplit") == 0) {
+		nosplit = 1;
+		goto out;
+	}
 	
 out:
 	return c;
@@ -1854,74 +1861,74 @@ static	struct
 /*	name		lexical		etype		op
  */
 /* basic types */
-	"int8",		LNAME,		TINT8,		OXXX,
-	"int16",	LNAME,		TINT16,		OXXX,
-	"int32",	LNAME,		TINT32,		OXXX,
-	"int64",	LNAME,		TINT64,		OXXX,
-
-	"uint8",	LNAME,		TUINT8,		OXXX,
-	"uint16",	LNAME,		TUINT16,	OXXX,
-	"uint32",	LNAME,		TUINT32,	OXXX,
-	"uint64",	LNAME,		TUINT64,	OXXX,
-
-	"float32",	LNAME,		TFLOAT32,	OXXX,
-	"float64",	LNAME,		TFLOAT64,	OXXX,
-
-	"complex64",	LNAME,		TCOMPLEX64,	OXXX,
-	"complex128",	LNAME,		TCOMPLEX128,	OXXX,
-
-	"bool",		LNAME,		TBOOL,		OXXX,
-	"string",	LNAME,		TSTRING,	OXXX,
-
-	"any",		LNAME,		TANY,		OXXX,
-
-	"break",	LBREAK,		Txxx,		OXXX,
-	"case",		LCASE,		Txxx,		OXXX,
-	"chan",		LCHAN,		Txxx,		OXXX,
-	"const",	LCONST,		Txxx,		OXXX,
-	"continue",	LCONTINUE,	Txxx,		OXXX,
-	"default",	LDEFAULT,	Txxx,		OXXX,
-	"else",		LELSE,		Txxx,		OXXX,
-	"defer",	LDEFER,		Txxx,		OXXX,
-	"fallthrough",	LFALL,		Txxx,		OXXX,
-	"for",		LFOR,		Txxx,		OXXX,
-	"func",		LFUNC,		Txxx,		OXXX,
-	"go",		LGO,		Txxx,		OXXX,
-	"goto",		LGOTO,		Txxx,		OXXX,
-	"if",		LIF,		Txxx,		OXXX,
-	"import",	LIMPORT,	Txxx,		OXXX,
-	"interface",	LINTERFACE,	Txxx,		OXXX,
-	"map",		LMAP,		Txxx,		OXXX,
-	"package",	LPACKAGE,	Txxx,		OXXX,
-	"range",	LRANGE,		Txxx,		OXXX,
-	"return",	LRETURN,	Txxx,		OXXX,
-	"select",	LSELECT,	Txxx,		OXXX,
-	"struct",	LSTRUCT,	Txxx,		OXXX,
-	"switch",	LSWITCH,	Txxx,		OXXX,
-	"type",		LTYPE,		Txxx,		OXXX,
-	"var",		LVAR,		Txxx,		OXXX,
-
-	"append",	LNAME,		Txxx,		OAPPEND,
-	"cap",		LNAME,		Txxx,		OCAP,
-	"close",	LNAME,		Txxx,		OCLOSE,
-	"complex",	LNAME,		Txxx,		OCOMPLEX,
-	"copy",		LNAME,		Txxx,		OCOPY,
-	"delete",	LNAME,		Txxx,		ODELETE,
-	"imag",		LNAME,		Txxx,		OIMAG,
-	"len",		LNAME,		Txxx,		OLEN,
-	"make",		LNAME,		Txxx,		OMAKE,
-	"new",		LNAME,		Txxx,		ONEW,
-	"panic",	LNAME,		Txxx,		OPANIC,
-	"print",	LNAME,		Txxx,		OPRINT,
-	"println",	LNAME,		Txxx,		OPRINTN,
-	"real",		LNAME,		Txxx,		OREAL,
-	"recover",	LNAME,		Txxx,		ORECOVER,
-
-	"notwithstanding",		LIGNORE,	Txxx,		OXXX,
-	"thetruthofthematter",		LIGNORE,	Txxx,		OXXX,
-	"despiteallobjections",		LIGNORE,	Txxx,		OXXX,
-	"whereas",			LIGNORE,	Txxx,		OXXX,
-	"insofaras",			LIGNORE,	Txxx,		OXXX,
+	{"int8",		LNAME,		TINT8,		OXXX},
+	{"int16",	LNAME,		TINT16,		OXXX},
+	{"int32",	LNAME,		TINT32,		OXXX},
+	{"int64",	LNAME,		TINT64,		OXXX},
+
+	{"uint8",	LNAME,		TUINT8,		OXXX},
+	{"uint16",	LNAME,		TUINT16,	OXXX},
+	{"uint32",	LNAME,		TUINT32,	OXXX},
+	{"uint64",	LNAME,		TUINT64,	OXXX},
+
+	{"float32",	LNAME,		TFLOAT32,	OXXX},
+	{"float64",	LNAME,		TFLOAT64,	OXXX},
+
+	{"complex64",	LNAME,		TCOMPLEX64,	OXXX},
+	{"complex128",	LNAME,		TCOMPLEX128,	OXXX},
+
+	{"bool",		LNAME,		TBOOL,		OXXX},
+	{"string",	LNAME,		TSTRING,	OXXX},
+
+	{"any",		LNAME,		TANY,		OXXX},
+
+	{"break",	LBREAK,		Txxx,		OXXX},
+	{"case",		LCASE,		Txxx,		OXXX},
+	{"chan",		LCHAN,		Txxx,		OXXX},
+	{"const",	LCONST,		Txxx,		OXXX},
+	{"continue",	LCONTINUE,	Txxx,		OXXX},
+	{"default",	LDEFAULT,	Txxx,		OXXX},
+	{"else",		LELSE,		Txxx,		OXXX},
+	{"defer",	LDEFER,		Txxx,		OXXX},
+	{"fallthrough",	LFALL,		Txxx,		OXXX},
+	{"for",		LFOR,		Txxx,		OXXX},
+	{"func",		LFUNC,		Txxx,		OXXX},
+	{"go",		LGO,		Txxx,		OXXX},
+	{"goto",		LGOTO,		Txxx,		OXXX},
+	{"if",		LIF,		Txxx,		OXXX},
+	{"import",	LIMPORT,	Txxx,		OXXX},
+	{"interface",	LINTERFACE,	Txxx,		OXXX},
+	{"map",		LMAP,		Txxx,		OXXX},
+	{"package",	LPACKAGE,	Txxx,		OXXX},
+	{"range",	LRANGE,		Txxx,		OXXX},
+	{"return",	LRETURN,	Txxx,		OXXX},
+	{"select",	LSELECT,	Txxx,		OXXX},
+	{"struct",	LSTRUCT,	Txxx,		OXXX},
+	{"switch",	LSWITCH,	Txxx,		OXXX},
+	{"type",		LTYPE,		Txxx,		OXXX},
+	{"var",		LVAR,		Txxx,		OXXX},
+
+	{"append",	LNAME,		Txxx,		OAPPEND},
+	{"cap",		LNAME,		Txxx,		OCAP},
+	{"close",	LNAME,		Txxx,		OCLOSE},
+	{"complex",	LNAME,		Txxx,		OCOMPLEX},
+	{"copy",		LNAME,		Txxx,		OCOPY},
+	{"delete",	LNAME,		Txxx,		ODELETE},
+	{"imag",		LNAME,		Txxx,		OIMAG},
+	{"len",		LNAME,		Txxx,		OLEN},
+	{"make",		LNAME,		Txxx,		OMAKE},
+	{"new",		LNAME,		Txxx,		ONEW},
+	{"panic",	LNAME,		Txxx,		OPANIC},
+	{"print",	LNAME,		Txxx,		OPRINT},
+	{"println",	LNAME,		Txxx,		OPRINTN},
+	{"real",		LNAME,		Txxx,		OREAL},
+	{"recover",	LNAME,		Txxx,		ORECOVER},
+
+	{"notwithstanding",		LIGNORE,	Txxx,		OXXX},
+	{"thetruthofthematter",		LIGNORE,	Txxx,		OXXX},
+	{"despiteallobjections",		LIGNORE,	Txxx,		OXXX},
+	{"whereas",			LIGNORE,	Txxx,		OXXX},
+	{"insofaras",			LIGNORE,	Txxx,		OXXX},
 };
 
 static void
@@ -2171,50 +2178,50 @@ struct
 	char*	name;
 } lexn[] =
 {
-	LANDAND,	"ANDAND",
-	LANDNOT,	"ANDNOT",
-	LASOP,		"ASOP",
-	LBREAK,		"BREAK",
-	LCASE,		"CASE",
-	LCHAN,		"CHAN",
-	LCOLAS,		"COLAS",
-	LCOMM,		"<-",
-	LCONST,		"CONST",
-	LCONTINUE,	"CONTINUE",
-	LDDD,		"...",
-	LDEC,		"DEC",
-	LDEFAULT,	"DEFAULT",
-	LDEFER,		"DEFER",
-	LELSE,		"ELSE",
-	LEQ,		"EQ",
-	LFALL,		"FALL",
-	LFOR,		"FOR",
-	LFUNC,		"FUNC",
-	LGE,		"GE",
-	LGO,		"GO",
-	LGOTO,		"GOTO",
-	LGT,		"GT",
-	LIF,		"IF",
-	LIMPORT,	"IMPORT",
-	LINC,		"INC",
-	LINTERFACE,	"INTERFACE",
-	LLE,		"LE",
-	LLITERAL,	"LITERAL",
-	LLSH,		"LSH",
-	LLT,		"LT",
-	LMAP,		"MAP",
-	LNAME,		"NAME",
-	LNE,		"NE",
-	LOROR,		"OROR",
-	LPACKAGE,	"PACKAGE",
-	LRANGE,		"RANGE",
-	LRETURN,	"RETURN",
-	LRSH,		"RSH",
-	LSELECT,	"SELECT",
-	LSTRUCT,	"STRUCT",
-	LSWITCH,	"SWITCH",
-	LTYPE,		"TYPE",
-	LVAR,		"VAR",
+	{LANDAND,	"ANDAND"},
+	{LANDNOT,	"ANDNOT"},
+	{LASOP,		"ASOP"},
+	{LBREAK,		"BREAK"},
+	{LCASE,		"CASE"},
+	{LCHAN,		"CHAN"},
+	{LCOLAS,		"COLAS"},
+	{LCOMM,		"<-"},
+	{LCONST,		"CONST"},
+	{LCONTINUE,	"CONTINUE"},
+	{LDDD,		"..."},
+	{LDEC,		"DEC"},
+	{LDEFAULT,	"DEFAULT"},
+	{LDEFER,		"DEFER"},
+	{LELSE,		"ELSE"},
+	{LEQ,		"EQ"},
+	{LFALL,		"FALL"},
+	{LFOR,		"FOR"},
+	{LFUNC,		"FUNC"},
+	{LGE,		"GE"},
+	{LGO,		"GO"},
+	{LGOTO,		"GOTO"},
+	{LGT,		"GT"},
+	{LIF,		"IF"},
+	{LIMPORT,	"IMPORT"},
+	{LINC,		"INC"},
+	{LINTERFACE,	"INTERFACE"},
+	{LLE,		"LE"},
+	{LLITERAL,	"LITERAL"},
+	{LLSH,		"LSH"},
+	{LLT,		"LT"},
+	{LMAP,		"MAP"},
+	{LNAME,		"NAME"},
+	{LNE,		"NE"},
+	{LOROR,		"OROR"},
+	{LPACKAGE,	"PACKAGE"},
+	{LRANGE,		"RANGE"},
+	{LRETURN,	"RETURN"},
+	{LRSH,		"RSH"},
+	{LSELECT,	"SELECT"},
+	{LSTRUCT,	"STRUCT"},
+	{LSWITCH,	"SWITCH"},
+	{LTYPE,		"TYPE"},
+	{LVAR,		"VAR"},
 };
 
 char*
@@ -2236,56 +2243,56 @@ struct
 	char *want;
 } yytfix[] =
 {
-	"$end",	"EOF",
-	"LLITERAL",	"literal",
-	"LASOP",	"op=",
-	"LBREAK",	"break",
-	"LCASE",	"case",
-	"LCHAN",	"chan",
-	"LCOLAS",	":=",
-	"LCONST",	"const",
-	"LCONTINUE",	"continue",
-	"LDDD",	"...",
-	"LDEFAULT",	"default",
-	"LDEFER",	"defer",
-	"LELSE",	"else",
-	"LFALL",	"fallthrough",
-	"LFOR",	"for",
-	"LFUNC",	"func",
-	"LGO",	"go",
-	"LGOTO",	"goto",
-	"LIF",	"if",
-	"LIMPORT",	"import",
-	"LINTERFACE",	"interface",
-	"LMAP",	"map",
-	"LNAME",	"name",
-	"LPACKAGE",	"package",
-	"LRANGE",	"range",
-	"LRETURN",	"return",
-	"LSELECT",	"select",
-	"LSTRUCT",	"struct",
-	"LSWITCH",	"switch",
-	"LTYPE",	"type",
-	"LVAR",	"var",
-	"LANDAND",	"&&",
-	"LANDNOT",	"&^",
-	"LBODY",	"{",
-	"LCOMM",	"<-",
-	"LDEC",	"--",
-	"LINC",	"++",
-	"LEQ",	"==",
-	"LGE",	">=",
-	"LGT",	">",
-	"LLE",	"<=",
-	"LLT",	"<",
-	"LLSH",	"<<",
-	"LRSH",	">>",
-	"LOROR",	"||",
-	"LNE",	"!=",
+	{"$end",	"EOF"},
+	{"LLITERAL",	"literal"},
+	{"LASOP",	"op="},
+	{"LBREAK",	"break"},
+	{"LCASE",	"case"},
+	{"LCHAN",	"chan"},
+	{"LCOLAS",	":="},
+	{"LCONST",	"const"},
+	{"LCONTINUE",	"continue"},
+	{"LDDD",	"..."},
+	{"LDEFAULT",	"default"},
+	{"LDEFER",	"defer"},
+	{"LELSE",	"else"},
+	{"LFALL",	"fallthrough"},
+	{"LFOR",	"for"},
+	{"LFUNC",	"func"},
+	{"LGO",	"go"},
+	{"LGOTO",	"goto"},
+	{"LIF",	"if"},
+	{"LIMPORT",	"import"},
+	{"LINTERFACE",	"interface"},
+	{"LMAP",	"map"},
+	{"LNAME",	"name"},
+	{"LPACKAGE",	"package"},
+	{"LRANGE",	"range"},
+	{"LRETURN",	"return"},
+	{"LSELECT",	"select"},
+	{"LSTRUCT",	"struct"},
+	{"LSWITCH",	"switch"},
+	{"LTYPE",	"type"},
+	{"LVAR",	"var"},
+	{"LANDAND",	"&&"},
+	{"LANDNOT",	"&^"},
+	{"LBODY",	"{"},
+	{"LCOMM",	"<-"},
+	{"LDEC",	"--"},
+	{"LINC",	"++"},
+	{"LEQ",	"=="},
+	{"LGE",	">="},
+	{"LGT",	">"},
+	{"LLE",	"<="},
+	{"LLT",	"<"},
+	{"LLSH",	"<<"},
+	{"LRSH",	">>"},
+	{"LOROR",	"||"},
+	{"LNE",	"!="},
 	
 	// spell out to avoid confusion with punctuation in error messages
-	"';'",	"semicolon or newline",
-	"','",	"comma",
+	{"';'",	"semicolon or newline"},
+	{"','",	"comma"},
 };
 
 static void
diff --git a/src/cmd/gc/md5.c b/src/cmd/gc/md5.c
index 0051ac9..46cb6b7 100644
--- a/src/cmd/gc/md5.c
+++ b/src/cmd/gc/md5.c
@@ -3,7 +3,7 @@
 // license that can be found in the LICENSE file.
 
 // 64-bit MD5 (does full MD5 but returns 64 bits only).
-// Translation of ../../pkg/crypto/md5/md5*.go.
+// Translation of ../../crypto/md5/md5*.go.
 
 #include <u.h>
 #include <libc.h>
@@ -20,7 +20,15 @@ enum {
 #define _Init1 0xEFCDAB89
 #define _Init2 0x98BADCFE
 #define _Init3 0x10325476
-
+/*c2go
+enum {
+	_Init0 = 0x67452301,
+	_Init1 = 0xEFCDAB89,
+	_Init2 = 0x98BADCFE,
+	_Init3 = 0x10325476
+};
+*/
+	
 void
 md5reset(MD5 *d)
 {
diff --git a/src/cmd/gc/mparith1.c b/src/cmd/gc/mparith1.c
index 1519cae..d33a81e 100644
--- a/src/cmd/gc/mparith1.c
+++ b/src/cmd/gc/mparith1.c
@@ -591,7 +591,7 @@ Fconv(Fmt *fp)
 			d = mpgetflt(fvp);
 			if(d >= 0 && (fp->flags & FmtSign))
 				fmtprint(fp, "+");
-			return fmtprint(fp, "%g", d, exp, fvp);
+			return fmtprint(fp, "%g", d);
 		}
 		
 		// very out of range. compute decimal approximation by hand.
diff --git a/src/cmd/gc/mparith2.c b/src/cmd/gc/mparith2.c
index 5cf98c6..fd9f591 100644
--- a/src/cmd/gc/mparith2.c
+++ b/src/cmd/gc/mparith2.c
@@ -656,7 +656,7 @@ mpdivmodfixfix(Mpint *q, Mpint *r, Mpint *n, Mpint *d)
 }
 
 static int
-iszero(Mpint *a)
+mpiszero(Mpint *a)
 {
 	long *a1;
 	int i;
@@ -687,7 +687,7 @@ mpdivfract(Mpint *a, Mpint *b)
 		for(j=0; j<Mpscale; j++) {
 			x <<= 1;
 			if(mpcmp(&d, &n) <= 0) {
-				if(!iszero(&d))
+				if(!mpiszero(&d))
 					x |= 1;
 				mpsubfixfix(&n, &d);
 			}
diff --git a/src/cmd/gc/mparith3.c b/src/cmd/gc/mparith3.c
index 95618f1..6afd75c 100644
--- a/src/cmd/gc/mparith3.c
+++ b/src/cmd/gc/mparith3.c
@@ -251,8 +251,8 @@ mpgetfltN(Mpflt *a, int prec, int bias)
 		s = minexp - e;
 		if(s > prec+1)
 			s = prec+1;
-		if((v & ((1<<s)-1)) != 0)
-			v |= 1<<s;
+		if((v & ((1ULL<<s)-1)) != 0)
+			v |= 1ULL<<s;
 		v >>= s;
 		e = minexp;
 	}
diff --git a/src/cmd/gc/obj.c b/src/cmd/gc/obj.c
index 4eeb03a..b752a13 100644
--- a/src/cmd/gc/obj.c
+++ b/src/cmd/gc/obj.c
@@ -5,6 +5,7 @@
 #include <u.h>
 #include <libc.h>
 #include "go.h"
+#include "../ld/textflag.h"
 
 /*
  * architecture-independent object file output
@@ -84,7 +85,7 @@ dumpobj(void)
 	externdcl = tmp;
 
 	zero = pkglookup("zerovalue", runtimepkg);
-	ggloblsym(zero, zerosize, 1, 1);
+	ggloblsym(zero, zerosize, DUPOK|RODATA);
 
 	dumpdata();
 	writeobj(ctxt, bout);
@@ -128,7 +129,7 @@ dumpglobls(void)
 	for(l=funcsyms; l; l=l->next) {
 		n = l->n;
 		dsymptr(n->sym, 0, n->sym->def->shortname->sym, 0);
-		ggloblsym(n->sym, widthptr, 1, 1);
+		ggloblsym(n->sym, widthptr, DUPOK|RODATA);
 	}
 	
 	// Do not reprocess funcsyms on next dumpglobls call.
@@ -249,7 +250,7 @@ stringsym(char *s, int len)
 	}
 	off = duint8(sym, off, 0);  // terminating NUL for runtime
 	off = (off+widthptr-1)&~(widthptr-1);  // round to pointer alignment
-	ggloblsym(sym, off, 1, 1);
+	ggloblsym(sym, off, DUPOK|RODATA);
 
 	return sym;	
 }
@@ -272,7 +273,7 @@ slicebytes(Node *nam, char *s, int len)
 			m = len-n;
 		off = dsname(sym, off, s+n, m);
 	}
-	ggloblsym(sym, off, 0, 0);
+	ggloblsym(sym, off, NOPTR);
 	
 	if(nam->op != ONAME)
 		fatal("slicebytes %N", nam);
diff --git a/src/cmd/gc/order.c b/src/cmd/gc/order.c
index 30dbc7d..76820fd 100644
--- a/src/cmd/gc/order.c
+++ b/src/cmd/gc/order.c
@@ -317,7 +317,7 @@ orderexprinplace(Node **np, Order *outer)
 
 // Orderstmtinplace orders the side effects of the single statement *np
 // and replaces it with the resulting statement list.
-static void
+void
 orderstmtinplace(Node **np)
 {
 	Node *n;
@@ -438,6 +438,9 @@ ordercall(Node *n, Order *order)
 // cases they are also typically registerizable, so not much harm done.
 // And this only applies to the multiple-assignment form.
 // We could do a more precise analysis if needed, like in walk.c.
+//
+// Ordermapassign also inserts these temporaries if needed for
+// calling writebarrierfat with a pointer to n->right.
 static void
 ordermapassign(Node *n, Order *order)
 {
@@ -451,7 +454,8 @@ ordermapassign(Node *n, Order *order)
 
 	case OAS:
 		order->out = list(order->out, n);
-		if(n->left->op == OINDEXMAP && !isaddrokay(n->right)) {
+		// We call writebarrierfat only for values > 4 pointers long. See walk.c.
+		if((n->left->op == OINDEXMAP || (needwritebarrier(n->left, n->right) && n->left->type->width > 4*widthptr)) && !isaddrokay(n->right)) {
 			m = n->left;
 			n->left = ordertemp(m->type, order, 0);
 			a = nod(OAS, m, n->left);
@@ -593,7 +597,10 @@ orderstmt(Node *n, Order *order)
 		orderexpr(&n->rlist->n->left, order);  // arg to recv
 		ch = n->rlist->n->left->type;
 		tmp1 = ordertemp(ch->type, order, haspointers(ch->type));
-		tmp2 = ordertemp(types[TBOOL], order, 0);
+		if(!isblank(n->list->next->n))
+			tmp2 = ordertemp(n->list->next->n->type, order, 0);
+		else
+			tmp2 = ordertemp(types[TBOOL], order, 0);
 		order->out = list(order->out, n);
 		r = nod(OAS, n->list->n, tmp1);
 		typecheck(&r, Etop);
@@ -768,6 +775,12 @@ orderstmt(Node *n, Order *order)
 		// Special: clean case temporaries in each block entry.
 		// Select must enter one of its blocks, so there is no
 		// need for a cleaning at the end.
+		// Doubly special: evaluation order for select is stricter
+		// than ordinary expressions. Even something like p.c
+		// has to be hoisted into a temporary, so that it cannot be
+		// reordered after the channel evaluation for a different
+		// case (if p were nil, then the timing of the fault would
+		// give this away).
 		t = marktemp(order);
 		for(l=n->list; l; l=l->next) {
 			if(l->n->op != OXCASE)
@@ -810,6 +823,8 @@ orderstmt(Node *n, Order *order)
 					// r->left == N means 'case <-c'.
 					// c is always evaluated; x and ok are only evaluated when assigned.
 					orderexpr(&r->right->left, order);
+					if(r->right->left->op != ONAME)
+						r->right->left = ordercopyexpr(r->right->left, r->right->left->type, order, 0);
 
 					// Introduce temporary for receive and move actual copy into case body.
 					// avoids problems with target being addressed, as usual.
@@ -1017,11 +1032,21 @@ orderexpr(Node **np, Order *order)
 		orderexprinplace(&n->right, order);
 		break;
 	
+	case OAPPEND:
 	case OCALLFUNC:
-	case OCALLMETH:
 	case OCALLINTER:
-	case OAPPEND:
+	case OCALLMETH:
+	case OCAP:
 	case OCOMPLEX:
+	case OCOPY:
+	case OIMAG:
+	case OLEN:
+	case OMAKECHAN:
+	case OMAKEMAP:
+	case OMAKESLICE:
+	case ONEW:
+	case OREAL:
+	case ORECOVER:
 		ordercall(n, order);
 		n = ordercopyexpr(n, n->type, order, 0);
 		break;
@@ -1055,6 +1080,19 @@ orderexpr(Node **np, Order *order)
 		orderexpr(&n->left, order);
 		n = ordercopyexpr(n, n->type, order, 1);
 		break;
+
+	case OEQ:
+	case ONE:
+		orderexpr(&n->left, order);
+		orderexpr(&n->right, order);
+		t = n->left->type;
+		if(t->etype == TSTRUCT || isfixedarray(t)) {
+			// for complex comparisons, we need both args to be
+			// addressable so we can pass them to the runtime.
+			orderaddrtemp(&n->left, order);
+			orderaddrtemp(&n->right, order);
+		}
+		break;
 	}
 	
 	lineno = lno;
diff --git a/src/cmd/gc/pgen.c b/src/cmd/gc/pgen.c
index 40620c3..39028e3 100644
--- a/src/cmd/gc/pgen.c
+++ b/src/cmd/gc/pgen.c
@@ -11,9 +11,10 @@
 #include	"md5.h"
 #include	"gg.h"
 #include	"opt.h"
-#include	"../../pkg/runtime/funcdata.h"
+#include	"../../runtime/funcdata.h"
 
 static void allocauto(Prog* p);
+static void emitptrargsmap(void);
 
 static Sym*
 makefuncdatasym(char *namefmt, int64 funcdatakind)
@@ -173,9 +174,17 @@ compile(Node *fn)
 
 	lno = setlineno(fn);
 
+	curfn = fn;
+	dowidth(curfn->type);
+
 	if(fn->nbody == nil) {
-		if(pure_go || strncmp(fn->nname->sym->name, "init·", 6) == 0)
+		if(pure_go || strncmp(fn->nname->sym->name, "init·", 6) == 0) {
 			yyerror("missing function body", fn);
+			goto ret;
+		}
+		if(debug['A'])
+			goto ret;
+		emitptrargsmap();
 		goto ret;
 	}
 
@@ -184,9 +193,6 @@ compile(Node *fn)
 	// set up domain for labels
 	clearlabels();
 
-	curfn = fn;
-	dowidth(curfn->type);
-
 	if(curfn->type->outnamed) {
 		// add clearing of the output parameters
 		t = structfirst(&save, getoutarg(curfn->type));
@@ -229,9 +235,11 @@ compile(Node *fn)
 		ptxt->TEXTFLAG |= WRAPPER;
 	if(fn->needctxt)
 		ptxt->TEXTFLAG |= NEEDCTXT;
+	if(fn->nosplit)
+		ptxt->TEXTFLAG |= NOSPLIT;
 
 	// Clumsy but important.
-	// See test/recover.go for test cases and src/pkg/reflect/value.go
+	// See test/recover.go for test cases and src/reflect/value.go
 	// for the actual functions being considered.
 	if(myimportpath != nil && strcmp(myimportpath, "reflect") == 0) {
 		if(strcmp(curfn->nname->sym->name, "callReflect") == 0 || strcmp(curfn->nname->sym->name, "callMethod") == 0)
@@ -327,6 +335,43 @@ ret:
 	lineno = lno;
 }
 
+static void
+emitptrargsmap(void)
+{
+	int nptr, nbitmap, j, off;
+	vlong xoffset;
+	Bvec *bv;
+	Sym *sym;
+	
+	sym = lookup(smprint("%s.args_stackmap", curfn->nname->sym->name));
+
+	nptr = curfn->type->argwid / widthptr;
+	bv = bvalloc(nptr*2);
+	nbitmap = 1;
+	if(curfn->type->outtuple > 0)
+		nbitmap = 2;
+	off = duint32(sym, 0, nbitmap);
+	off = duint32(sym, off, bv->n);
+	if(curfn->type->thistuple > 0) {
+		xoffset = 0;
+		twobitwalktype1(getthisx(curfn->type), &xoffset, bv);
+	}
+	if(curfn->type->intuple > 0) {
+		xoffset = 0;
+		twobitwalktype1(getinargx(curfn->type), &xoffset, bv);
+	}
+	for(j = 0; j < bv->n; j += 32)
+		off = duint32(sym, off, bv->b[j/32]);
+	if(curfn->type->outtuple > 0) {
+		xoffset = 0;
+		twobitwalktype1(getoutargx(curfn->type), &xoffset, bv);
+		for(j = 0; j < bv->n; j += 32)
+			off = duint32(sym, off, bv->b[j/32]);
+	}
+	ggloblsym(sym, off, RODATA);
+	free(bv);
+}
+
 // Sort the list of stack variables. Autos after anything else,
 // within autos, unused after used, within used, things with
 // pointers first, zeroed things first, and then decreasing size.
diff --git a/src/cmd/gc/plive.c b/src/cmd/gc/plive.c
index 7a40ab5..0feb2c7 100644
--- a/src/cmd/gc/plive.c
+++ b/src/cmd/gc/plive.c
@@ -17,9 +17,9 @@
 #include <libc.h>
 #include "gg.h"
 #include "opt.h"
-#include "../../pkg/runtime/funcdata.h"
-
-enum { BitsPerPointer = 2 };
+#include "../ld/textflag.h"
+#include "../../runtime/funcdata.h"
+#include "../../runtime/mgc0.h"
 
 enum {
 	UNVISITED = 0,
@@ -674,8 +674,8 @@ static void
 progeffects(Prog *prog, Array *vars, Bvec *uevar, Bvec *varkill, Bvec *avarinit)
 {
 	ProgInfo info;
-	Adr *from;
-	Adr *to;
+	Addr *from;
+	Addr *to;
 	Node *node;
 	int32 i;
 	int32 pos;
@@ -1063,7 +1063,7 @@ checkptxt(Node *fn, Prog *firstp)
 // and then simply copied into bv at the correct offset on future calls with
 // the same type t. On https://rsc.googlecode.com/hg/testdata/slow.go, twobitwalktype1
 // accounts for 40% of the 6g execution time.
-static void
+void
 twobitwalktype1(Type *t, vlong *xoffset, Bvec *bv)
 {
 	vlong fieldoffset;
@@ -1113,8 +1113,7 @@ twobitwalktype1(Type *t, vlong *xoffset, Bvec *bv)
 		// struct { byte *str; intgo len; }
 		if((*xoffset & (widthptr-1)) != 0)
 			fatal("twobitwalktype1: invalid alignment, %T", t);
-		bvset(bv, (*xoffset / widthptr) * BitsPerPointer + 0);
-		bvset(bv, (*xoffset / widthptr) * BitsPerPointer + 1); // 3:0 = multiword:string
+		bvset(bv, (*xoffset / widthptr) * BitsPerPointer + 1); // 2 = live ptr in first slot
 		*xoffset += t->width;
 		break;
 
@@ -1145,9 +1144,7 @@ twobitwalktype1(Type *t, vlong *xoffset, Bvec *bv)
 			// struct { byte *array; uintgo len; uintgo cap; }
 			if((*xoffset & (widthptr-1)) != 0)
 				fatal("twobitwalktype1: invalid TARRAY alignment, %T", t);
-			bvset(bv, (*xoffset / widthptr) * BitsPerPointer + 0);
-			bvset(bv, (*xoffset / widthptr) * BitsPerPointer + 1);
-			bvset(bv, (*xoffset / widthptr) * BitsPerPointer + 2); // 3:1 = multiword/slice
+			bvset(bv, (*xoffset / widthptr) * BitsPerPointer + 1); // 2 = live ptr in first slot
 			*xoffset += t->width;
 		} else
 			for(i = 0; i < t->bound; i++)
@@ -1683,6 +1680,13 @@ livenessepilogue(Liveness *lv)
 // FNV-1 hash function constants.
 #define H0 2166136261UL
 #define Hp 16777619UL
+/*c2go
+enum
+{
+	H0 = 2166136261,
+	Hp = 16777619,
+};
+*/
 
 static uint32
 hashbitmap(uint32 h, Bvec *bv)
@@ -1932,11 +1936,15 @@ twobitwritesymbol(Array *arr, Sym *sym)
 			break;
 		for(j = 0; j < bv->n; j += 32) {
 			word = bv->b[j/32];
-			off = duint32(sym, off, word);
+			// Runtime reads the bitmaps as byte arrays. Oblige.
+			off = duint8(sym, off, word);
+			off = duint8(sym, off, word>>8);
+			off = duint8(sym, off, word>>16);
+			off = duint8(sym, off, word>>24);
 		}
 	}
 	duint32(sym, 0, i); // number of bitmaps
-	ggloblsym(sym, off, 0, 1);
+	ggloblsym(sym, off, RODATA);
 }
 
 static void
diff --git a/src/cmd/gc/popt.c b/src/cmd/gc/popt.c
index ea88b94..993bb24 100644
--- a/src/cmd/gc/popt.c
+++ b/src/cmd/gc/popt.c
@@ -49,7 +49,7 @@ noreturn(Prog *p)
 		symlist[0] = pkglookup("panicindex", runtimepkg);
 		symlist[1] = pkglookup("panicslice", runtimepkg);
 		symlist[2] = pkglookup("throwinit", runtimepkg);
-		symlist[3] = pkglookup("panic", runtimepkg);
+		symlist[3] = pkglookup("gopanic", runtimepkg);
 		symlist[4] = pkglookup("panicwrap", runtimepkg);
 		symlist[5] = pkglookup("throwreturn", runtimepkg);
 		symlist[6] = pkglookup("selectgo", runtimepkg);
@@ -98,6 +98,10 @@ chasejmp(Prog *p, int *jmploop)
  */
 #define alive ((void*)0)
 #define dead ((void*)1)
+/*c2go
+extern void *alive;
+extern void *dead;
+*/
 
 /* mark all code reachable from firstp as alive */
 static void
diff --git a/src/cmd/gc/racewalk.c b/src/cmd/gc/racewalk.c
index 285bd78..c9e27fe 100644
--- a/src/cmd/gc/racewalk.c
+++ b/src/cmd/gc/racewalk.c
@@ -208,6 +208,26 @@ racewalknode(Node **np, NodeList **init, int wr, int skip)
 		goto ret;
 
 	case OCALLFUNC:
+		// Instrument dst argument of runtime.writebarrier* calls
+		// as we do not instrument runtime code.
+		if(n->left->sym != S && n->left->sym->pkg == runtimepkg && strncmp(n->left->sym->name, "writebarrier", 12) == 0) {
+			// Find the dst argument.
+			// The list can be reordered, so it's not necessary just the first or the second element.
+			for(l = n->list; l; l = l->next) {
+				if(strcmp(n->left->sym->name, "writebarrierfat") == 0) {
+					if(l->n->left->xoffset == widthptr)
+						break;
+				} else {
+					if(l->n->left->xoffset == 0)
+						break;
+				}
+			}
+			if(l == nil)
+				fatal("racewalk: writebarrier no arg");
+			if(l->n->right->op != OADDR)
+				fatal("racewalk: writebarrier bad arg");
+			callinstr(&l->n->right->left, init, 1, 0);
+		}
 		racewalknode(&n->left, init, 0, 0);
 		goto ret;
 
@@ -419,8 +439,10 @@ racewalknode(Node **np, NodeList **init, int wr, int skip)
 ret:
 	if(n->op != OBLOCK)  // OBLOCK is handled above in a special way.
 		racewalklist(n->list, init);
-	racewalknode(&n->ntest, &n->ntest->ninit, 0, 0);
-	racewalknode(&n->nincr, &n->nincr->ninit, 0, 0);
+	if(n->ntest != N)
+		racewalknode(&n->ntest, &n->ntest->ninit, 0, 0);
+	if(n->nincr != N)
+		racewalknode(&n->nincr, &n->nincr->ninit, 0, 0);
 	racewalklist(n->nbody, nil);
 	racewalklist(n->nelse, nil);
 	racewalklist(n->rlist, nil);
diff --git a/src/cmd/gc/range.c b/src/cmd/gc/range.c
index 45aa521..4ed4528 100644
--- a/src/cmd/gc/range.c
+++ b/src/cmd/gc/range.c
@@ -67,9 +67,11 @@ typecheckrange(Node *n)
 		yyerror("too many variables in range");
 	}
 
-	v1 = n->list->n;
+	v1 = N;
+	if(n->list)
+		v1 = n->list->n;
 	v2 = N;
-	if(n->list->next)
+	if(n->list && n->list->next)
 		v2 = n->list->next->n;
 
 	// this is not only a optimization but also a requirement in the spec.
@@ -77,14 +79,17 @@ typecheckrange(Node *n)
 	// clause is equivalent to the same clause with only the first variable
 	// present."
 	if(isblank(v2)) {
-		n->list = list1(v1);
+		if(v1 != N)
+			n->list = list1(v1);
 		v2 = N;
 	}
 
-	if(v1->defn == n)
-		v1->type = t1;
-	else if(v1->type != T && assignop(t1, v1->type, &why) == 0)
-		yyerror("cannot assign type %T to %lN in range%s", t1, v1, why);
+	if(v1) {
+		if(v1->defn == n)
+			v1->type = t1;
+		else if(v1->type != T && assignop(t1, v1->type, &why) == 0)
+			yyerror("cannot assign type %T to %lN in range%s", t1, v1, why);
+	}
 	if(v2) {
 		if(v2->defn == n)
 			v2->type = t2;
@@ -123,9 +128,11 @@ walkrange(Node *n)
 	a = n->right;
 	lno = setlineno(a);
 
-	v1 = n->list->n;
+	v1 = N;
+	if(n->list)
+		v1 = n->list->n;
 	v2 = N;
-	if(n->list->next && !isblank(n->list->next->n))
+	if(n->list && n->list->next && !isblank(n->list->next->n))
 		v2 = n->list->next->n;
 	// n->list has no meaning anymore, clear it
 	// to avoid erroneous processing by racewalk.
@@ -154,7 +161,9 @@ walkrange(Node *n)
 
 		n->ntest = nod(OLT, hv1, hn);
 		n->nincr = nod(OAS, hv1, nod(OADD, hv1, nodintconst(1)));
-		if(v2 == N)
+		if(v1 == N)
+			body = nil;
+		else if(v2 == N)
 			body = list1(nod(OAS, v1, hv1));
 		else {
 			a = nod(OAS2, N, N);
@@ -205,16 +214,18 @@ walkrange(Node *n)
 
 		key = nod(ODOT, hit, keyname);
 		key = nod(OIND, key, N);
-		if(v2 == N) {
-			a = nod(OAS, v1, key);
+		if(v1 == N)
+			body = nil;
+		else if(v2 == N) {
+			body = list1(nod(OAS, v1, key));
 		} else {
 			val = nod(ODOT, hit, valname);
 			val = nod(OIND, val, N);
 			a = nod(OAS2, N, N);
 			a->list = list(list1(v1), v2);
 			a->rlist = list(list1(key), val);
+			body = list1(a);
 		}
-		body = list1(a);
 		break;
 
 	case TCHAN:
@@ -223,6 +234,7 @@ walkrange(Node *n)
 		n->ntest = N;
 		
 		hv1 = temp(t->type);
+		hv1->typecheck = 1;
 		if(haspointers(t->type))
 			init = list(init, nod(OAS, hv1, N));
 		hb = temp(types[TBOOL]);
@@ -233,7 +245,10 @@ walkrange(Node *n)
 		a->list = list(list1(hv1), hb);
 		a->rlist = list1(nod(ORECV, ha, N));
 		n->ntest->ninit = list1(a);
-		body = list1(nod(OAS, v1, hv1));
+		if(v1 == N)
+			body = nil;
+		else
+			body = list1(nod(OAS, v1, hv1));
 		break;
 
 	case TSTRING:
@@ -257,7 +272,10 @@ walkrange(Node *n)
 		n->ntest = nod(ONE, hv1, nodintconst(0));
 		n->ntest->ninit = list(list1(nod(OAS, ohv1, hv1)), a);
 
-		body = list1(nod(OAS, v1, ohv1));
+		
+		body = nil;
+		if(v1 != N)
+			body = list1(nod(OAS, v1, ohv1));
 		if(v2 != N)
 			body = list(body, nod(OAS, v2, hv2));
 		break;
diff --git a/src/cmd/gc/reflect.c b/src/cmd/gc/reflect.c
index dbb447e..b2ff2fb 100644
--- a/src/cmd/gc/reflect.c
+++ b/src/cmd/gc/reflect.c
@@ -5,7 +5,9 @@
 #include <u.h>
 #include <libc.h>
 #include "go.h"
-#include "../../pkg/runtime/mgc0.h"
+#include "../ld/textflag.h"
+#include "../../runtime/mgc0.h"
+#include "../../runtime/typekind.h"
 
 /*
  * runtime interface and reflection data structures
@@ -15,7 +17,9 @@ static	NodeList*	signatlist;
 static	Sym*	dtypesym(Type*);
 static	Sym*	weaktypesym(Type*);
 static	Sym*	dalgsym(Type*);
-static	Sym*	dgcsym(Type*);
+static	int	usegcprog(Type*);
+static	void	gengcprog(Type*, Sym**, Sym**);
+static	void	gengcmask(Type*, uint8[16]);
 
 static int
 sigcmp(Sig *a, Sig *b)
@@ -105,7 +109,7 @@ lsort(Sig *l, int(*f)(Sig*, Sig*))
 // the given map type.  This type is not visible to users -
 // we include only enough information to generate a correct GC
 // program for it.
-// Make sure this stays in sync with ../../pkg/runtime/hashmap.c!
+// Make sure this stays in sync with ../../runtime/hashmap.c!
 enum {
 	BUCKETSIZE = 8,
 	MAXKEYSIZE = 128,
@@ -188,7 +192,7 @@ mapbucket(Type *t)
 // the given map type.  This type is not visible to users -
 // we include only enough information to generate a correct GC
 // program for it.
-// Make sure this stays in sync with ../../pkg/runtime/hashmap.c!
+// Make sure this stays in sync with ../../runtime/hashmap.go!
 static Type*
 hmap(Type *t)
 {
@@ -207,10 +211,6 @@ hmap(Type *t)
 	offset += 4;       // flags
 	offset += 4;       // hash0
 	offset += 1;       // B
-	offset += 1;       // keysize
-	offset += 1;       // valuesize
-	offset = (offset + 1) / 2 * 2;
-	offset += 2;       // bucketsize
 	offset = (offset + widthptr - 1) / widthptr * widthptr;
 	
 	bucketsfield = typ(TFIELD);
@@ -261,7 +261,7 @@ hiter(Type *t)
 	//    bptr *Bucket
 	//    other [4]uintptr
 	// }
-	// must match ../../pkg/runtime/hashmap.c:hash_iter.
+	// must match ../../runtime/hashmap.c:hash_iter.
 	field[0] = typ(TFIELD);
 	field[0]->type = ptrto(t->down);
 	field[0]->sym = mal(sizeof(Sym));
@@ -378,7 +378,7 @@ methods(Type *t)
 
 	// type stored in interface word
 	it = t;
-	if(it->width > widthptr)
+	if(!isdirectiface(it))
 		it = ptrto(t);
 
 	// make list of methods for t,
@@ -524,7 +524,7 @@ dimportpath(Pkg *p)
 	p->pathsym = n->sym;
 
 	gdatastring(n, p->path);
-	ggloblsym(n->sym, types[TSTRING]->width, 1, 1);
+	ggloblsym(n->sym, types[TSTRING]->width, DUPOK|RODATA);
 }
 
 static int
@@ -550,7 +550,7 @@ dgopkgpath(Sym *s, int ot, Pkg *pkg)
 
 /*
  * uncommonType
- * ../../pkg/runtime/type.go:/uncommonType
+ * ../../runtime/type.go:/uncommonType
  */
 static int
 dextratype(Sym *sym, int off, Type *t, int ptroff)
@@ -564,6 +564,7 @@ dextratype(Sym *sym, int off, Type *t, int ptroff)
 		return off;
 
 	// fill in *extraType pointer in header
+	off = rnd(off, widthptr);
 	dsymptr(sym, ptroff, sym, off);
 
 	n = 0;
@@ -593,7 +594,7 @@ dextratype(Sym *sym, int off, Type *t, int ptroff)
 	// methods
 	for(a=m; a; a=a->link) {
 		// method
-		// ../../pkg/runtime/type.go:/method
+		// ../../runtime/type.go:/method
 		ot = dgostringptr(s, ot, a->name);
 		ot = dgopkgpath(s, ot, a->pkg);
 		ot = dsymptr(s, ot, dtypesym(a->mtype), 0);
@@ -611,37 +612,6 @@ dextratype(Sym *sym, int off, Type *t, int ptroff)
 	return ot;
 }
 
-enum {
-	KindBool = 1,
-	KindInt,
-	KindInt8,
-	KindInt16,
-	KindInt32,
-	KindInt64,
-	KindUint,
-	KindUint8,
-	KindUint16,
-	KindUint32,
-	KindUint64,
-	KindUintptr,
-	KindFloat32,
-	KindFloat64,
-	KindComplex64,
-	KindComplex128,
-	KindArray,
-	KindChan,
-	KindFunc,
-	KindInterface,
-	KindMap,
-	KindPtr,
-	KindSlice,
-	KindString,
-	KindStruct,
-	KindUnsafePointer,
-
-	KindNoPointers = 1<<7,
-};
-
 static int
 kinds[] =
 {
@@ -740,28 +710,30 @@ haspointers(Type *t)
 
 /*
  * commonType
- * ../../pkg/runtime/type.go:/commonType
+ * ../../runtime/type.go:/commonType
  */
 static int
 dcommontype(Sym *s, int ot, Type *t)
 {
-	int i, alg, sizeofAlg;
-	Sym *sptr, *algsym, *zero;
+	int i, alg, sizeofAlg, gcprog;
+	Sym *sptr, *algsym, *zero, *gcprog0, *gcprog1, *sbits;
+	uint8 gcmask[16];
 	static Sym *algarray;
+	uint64 x1, x2;
 	char *p;
 	
 	if(ot != 0)
 		fatal("dcommontype %d", ot);
 
-	sizeofAlg = 4*widthptr;
+	sizeofAlg = 2*widthptr;
 	if(algarray == nil)
 		algarray = pkglookup("algarray", runtimepkg);
+	dowidth(t);
 	alg = algtype(t);
 	algsym = S;
 	if(alg < 0)
 		algsym = dalgsym(t);
 
-	dowidth(t);
 	if(t->sym != nil && !isptr[t->etype])
 		sptr = dtypesym(ptrto(t));
 	else
@@ -808,17 +780,52 @@ dcommontype(Sym *s, int ot, Type *t)
 	ot = duint8(s, ot, t->align);	// align
 	ot = duint8(s, ot, t->align);	// fieldAlign
 
+	gcprog = usegcprog(t);
 	i = kinds[t->etype];
 	if(t->etype == TARRAY && t->bound < 0)
 		i = KindSlice;
 	if(!haspointers(t))
 		i |= KindNoPointers;
+	if(isdirectiface(t))
+		i |= KindDirectIface;
+	if(gcprog)
+		i |= KindGCProg;
 	ot = duint8(s, ot, i);  // kind
 	if(alg >= 0)
 		ot = dsymptr(s, ot, algarray, alg*sizeofAlg);
 	else
 		ot = dsymptr(s, ot, algsym, 0);
-	ot = dsymptr(s, ot, dgcsym(t), 0);  // gc
+	// gc
+	if(gcprog) {
+		gengcprog(t, &gcprog0, &gcprog1);
+		if(gcprog0 != S)
+			ot = dsymptr(s, ot, gcprog0, 0);
+		else
+			ot = duintptr(s, ot, 0);
+		ot = dsymptr(s, ot, gcprog1, 0);
+	} else {
+		gengcmask(t, gcmask);
+		x1 = 0;
+		for(i=0; i<8; i++)
+			x1 = x1<<8 | gcmask[i];
+		if(widthptr == 4) {
+			p = smprint("gcbits.%#016llux", x1);
+		} else {
+			x2 = 0;
+			for(i=0; i<8; i++)
+				x2 = x2<<8 | gcmask[i+8];
+			p = smprint("gcbits.%#016llux%016llux", x1, x2);
+		}
+		sbits = pkglookup(p, runtimepkg);
+		if((sbits->flags & SymUniq) == 0) {
+			sbits->flags |= SymUniq;
+			for(i = 0; i < 2*widthptr; i++)
+				duint8(sbits, i, gcmask[i]);
+			ggloblsym(sbits, 2*widthptr, DUPOK|RODATA);
+		}
+		ot = dsymptr(s, ot, sbits, 0);
+		ot = duintptr(s, ot, 0);
+	}
 	p = smprint("%-uT", t);
 	//print("dcommontype: %s\n", p);
 	ot = dgostringptr(s, ot, p);	// string
@@ -975,7 +982,9 @@ dtypesym(Type *t)
 	tbase = t;
 	if(isptr[t->etype] && t->sym == S && t->type->sym != S)
 		tbase = t->type;
-	dupok = tbase->sym == S;
+	dupok = 0;
+	if(tbase->sym == S)
+		dupok = DUPOK;
 
 	if(compiling_runtime &&
 			(tbase == types[tbase->etype] ||
@@ -1002,7 +1011,7 @@ ok:
 
 	case TARRAY:
 		if(t->bound >= 0) {
-			// ../../pkg/runtime/type.go:/ArrayType
+			// ../../runtime/type.go:/ArrayType
 			s1 = dtypesym(t->type);
 			t2 = typ(TARRAY);
 			t2->type = t->type;
@@ -1014,7 +1023,7 @@ ok:
 			ot = dsymptr(s, ot, s2, 0);
 			ot = duintptr(s, ot, t->bound);
 		} else {
-			// ../../pkg/runtime/type.go:/SliceType
+			// ../../runtime/type.go:/SliceType
 			s1 = dtypesym(t->type);
 			ot = dcommontype(s, ot, t);
 			xt = ot - 3*widthptr;
@@ -1023,7 +1032,7 @@ ok:
 		break;
 
 	case TCHAN:
-		// ../../pkg/runtime/type.go:/ChanType
+		// ../../runtime/type.go:/ChanType
 		s1 = dtypesym(t->type);
 		ot = dcommontype(s, ot, t);
 		xt = ot - 3*widthptr;
@@ -1073,14 +1082,14 @@ ok:
 			n++;
 		}
 
-		// ../../pkg/runtime/type.go:/InterfaceType
+		// ../../runtime/type.go:/InterfaceType
 		ot = dcommontype(s, ot, t);
 		xt = ot - 3*widthptr;
 		ot = dsymptr(s, ot, s, ot+widthptr+2*widthint);
 		ot = duintxx(s, ot, n, widthint);
 		ot = duintxx(s, ot, n, widthint);
 		for(a=m; a; a=a->link) {
-			// ../../pkg/runtime/type.go:/imethod
+			// ../../runtime/type.go:/imethod
 			ot = dgostringptr(s, ot, a->name);
 			ot = dgopkgpath(s, ot, a->pkg);
 			ot = dsymptr(s, ot, dtypesym(a->type), 0);
@@ -1088,7 +1097,7 @@ ok:
 		break;
 
 	case TMAP:
-		// ../../pkg/runtime/type.go:/MapType
+		// ../../runtime/type.go:/MapType
 		s1 = dtypesym(t->down);
 		s2 = dtypesym(t->type);
 		s3 = dtypesym(mapbucket(t));
@@ -1099,16 +1108,31 @@ ok:
 		ot = dsymptr(s, ot, s2, 0);
 		ot = dsymptr(s, ot, s3, 0);
 		ot = dsymptr(s, ot, s4, 0);
+		if(t->down->width > MAXKEYSIZE) {
+			ot = duint8(s, ot, widthptr);
+			ot = duint8(s, ot, 1); // indirect
+		} else {
+			ot = duint8(s, ot, t->down->width);
+			ot = duint8(s, ot, 0); // not indirect
+		}
+		if(t->type->width > MAXVALSIZE) {
+			ot = duint8(s, ot, widthptr);
+			ot = duint8(s, ot, 1); // indirect
+		} else {
+			ot = duint8(s, ot, t->type->width);
+			ot = duint8(s, ot, 0); // not indirect
+		}
+		ot = duint16(s, ot, mapbucket(t)->width);
 		break;
 
 	case TPTR32:
 	case TPTR64:
 		if(t->type->etype == TANY) {
-			// ../../pkg/runtime/type.go:/UnsafePointerType
+			// ../../runtime/type.go:/UnsafePointerType
 			ot = dcommontype(s, ot, t);
 			break;
 		}
-		// ../../pkg/runtime/type.go:/PtrType
+		// ../../runtime/type.go:/PtrType
 		s1 = dtypesym(t->type);
 		ot = dcommontype(s, ot, t);
 		xt = ot - 3*widthptr;
@@ -1116,7 +1140,7 @@ ok:
 		break;
 
 	case TSTRUCT:
-		// ../../pkg/runtime/type.go:/StructType
+		// ../../runtime/type.go:/StructType
 		// for security, only the exported fields.
 		n = 0;
 		for(t1=t->type; t1!=T; t1=t1->down) {
@@ -1129,7 +1153,7 @@ ok:
 		ot = duintxx(s, ot, n, widthint);
 		ot = duintxx(s, ot, n, widthint);
 		for(t1=t->type; t1!=T; t1=t1->down) {
-			// ../../pkg/runtime/type.go:/structField
+			// ../../runtime/type.go:/structField
 			if(t1->sym && !t1->embedded) {
 				ot = dgostringptr(s, ot, t1->sym->name);
 				if(exportname(t1->sym->name))
@@ -1150,7 +1174,7 @@ ok:
 		break;
 	}
 	ot = dextratype(s, ot, t, xt);
-	ggloblsym(s, ot, dupok, 1);
+	ggloblsym(s, ot, dupok|RODATA);
 
 	// generate typelink.foo pointing at s = type.foo.
 	// The linker will leave a table of all the typelinks for
@@ -1164,7 +1188,7 @@ ok:
 		case TMAP:
 			slink = typelinksym(t);
 			dsymptr(slink, 0, s, 0);
-			ggloblsym(slink, widthptr, dupok, 1);
+			ggloblsym(slink, widthptr, dupok|RODATA);
 		}
 	}
 
@@ -1236,8 +1260,7 @@ static Sym*
 dalgsym(Type *t)
 {
 	int ot;
-	Sym *s, *hash, *eq;
-	char buf[100];
+	Sym *s, *hash, *hashfunc, *eq, *eqfunc;
 
 	// dalgsym is only called for a type that needs an algorithm table,
 	// which implies that the type is comparable (or else it would use ANOEQ).
@@ -1248,55 +1271,225 @@ dalgsym(Type *t)
 	eq = typesymprefix(".eq", t);
 	geneq(eq, t);
 
-	// ../../pkg/runtime/runtime.h:/Alg
+	// make Go funcs (closures) for calling hash and equal from Go
+	hashfunc = typesymprefix(".hashfunc", t);
+	dsymptr(hashfunc, 0, hash, 0);
+	ggloblsym(hashfunc, widthptr, DUPOK|RODATA);
+	eqfunc = typesymprefix(".eqfunc", t);
+	dsymptr(eqfunc, 0, eq, 0);
+	ggloblsym(eqfunc, widthptr, DUPOK|RODATA);
+
+	// ../../runtime/alg.go:/typeAlg
 	ot = 0;
-	ot = dsymptr(s, ot, hash, 0);
-	ot = dsymptr(s, ot, eq, 0);
-	ot = dsymptr(s, ot, pkglookup("memprint", runtimepkg), 0);
-	switch(t->width) {
-	default:
-		ot = dsymptr(s, ot, pkglookup("memcopy", runtimepkg), 0);
-		break;
-	case 1:
-	case 2:
-	case 4:
-	case 8:
-	case 16:
-		snprint(buf, sizeof buf, "memcopy%d", (int)t->width*8);
-		ot = dsymptr(s, ot, pkglookup(buf, runtimepkg), 0);
-		break;
-	}
+	ot = dsymptr(s, ot, hashfunc, 0);
+	ot = dsymptr(s, ot, eqfunc, 0);
 
-	ggloblsym(s, ot, 1, 1);
+	ggloblsym(s, ot, DUPOK|RODATA);
 	return s;
 }
 
 static int
-gcinline(Type *t)
+usegcprog(Type *t)
 {
-	switch(t->etype) {
-	case TARRAY:
-		if(t->bound == 1)
-			return 1;
-		if(t->width <= 4*widthptr)
-			return 1;
-		break;
+	vlong size, nptr;
+
+	if(!haspointers(t))
+		return 0;
+	if(t->width == BADWIDTH)
+		dowidth(t);
+	// Calculate size of the unrolled GC mask.
+	nptr = (t->width+widthptr-1)/widthptr;
+	size = nptr;
+	if(size%2)
+		size *= 2;	// repeated
+	size = size*gcBits/8;	// 4 bits per word
+	// Decide whether to use unrolled GC mask or GC program.
+	// We could use a more elaborate condition, but this seems to work well in practice.
+	// For small objects GC program can't give significant reduction.
+	// While large objects usually contain arrays; and even if it don't
+	// the program uses 2-bits per word while mask uses 4-bits per word,
+	// so the program is still smaller.
+	return size > 2*widthptr;
+}
+
+// Generates sparse GC bitmask (4 bits per word).
+static void
+gengcmask(Type *t, uint8 gcmask[16])
+{
+	Bvec *vec;
+	vlong xoffset, nptr, i, j;
+	int  half, mw;
+	uint8 bits, *pos;
+
+	memset(gcmask, 0, 16);
+	if(!haspointers(t))
+		return;
+
+	// Generate compact mask as stacks use.
+	xoffset = 0;
+	vec = bvalloc(2*widthptr*8);
+	twobitwalktype1(t, &xoffset, vec);
+
+	// Unfold the mask for the GC bitmap format:
+	// 4 bits per word, 2 high bits encode pointer info.
+	pos = (uint8*)gcmask;
+	nptr = (t->width+widthptr-1)/widthptr;
+	half = 0;
+	mw = 0;
+	// If number of words is odd, repeat the mask.
+	// This makes simpler handling of arrays in runtime.
+	for(j=0; j<=(nptr%2); j++) {
+		for(i=0; i<nptr; i++) {
+			bits = bvget(vec, i*BitsPerPointer) | bvget(vec, i*BitsPerPointer+1)<<1;
+			// Some fake types (e.g. Hmap) has missing fileds.
+			// twobitwalktype1 generates BitsDead for that holes,
+			// replace BitsDead with BitsScalar.
+			if(!mw && bits == BitsDead)
+				bits = BitsScalar;
+			mw = !mw && bits == BitsMultiWord;
+			bits <<= 2;
+			if(half)
+				bits <<= 4;
+			*pos |= bits;
+			half = !half;
+			if(!half)
+				pos++;
+		}
 	}
-	return 0;
 }
 
-static int
-dgcsym1(Sym *s, int ot, Type *t, vlong *off, int stack_size)
+// Helper object for generation of GC programs.
+typedef struct ProgGen ProgGen;
+struct ProgGen
 {
-	Type *t1;
-	vlong o, off2, fieldoffset, i;
+	Sym*	s;
+	int32	datasize;
+	uint8	data[256/PointersPerByte];
+	vlong	ot;
+};
 
-	if(t->align > 0 && (*off % t->align) != 0)
-		fatal("dgcsym1: invalid initial alignment, %T", t);
+static void
+proggeninit(ProgGen *g, Sym *s)
+{
+	g->s = s;
+	g->datasize = 0;
+	g->ot = 0;
+	memset(g->data, 0, sizeof(g->data));
+}
+
+static void
+proggenemit(ProgGen *g, uint8 v)
+{
+	g->ot = duint8(g->s, g->ot, v);
+}
+
+// Emits insData block from g->data.
+static void
+proggendataflush(ProgGen *g)
+{
+	int32 i, s;
+
+	if(g->datasize == 0)
+		return;
+	proggenemit(g, insData);
+	proggenemit(g, g->datasize);
+	s = (g->datasize + PointersPerByte - 1)/PointersPerByte;
+	for(i = 0; i < s; i++)
+		proggenemit(g, g->data[i]);
+	g->datasize = 0;
+	memset(g->data, 0, sizeof(g->data));
+}
+
+static void
+proggendata(ProgGen *g, uint8 d)
+{
+	g->data[g->datasize/PointersPerByte] |= d << ((g->datasize%PointersPerByte)*BitsPerPointer);
+	g->datasize++;
+	if(g->datasize == 255)
+		proggendataflush(g);
+}
+
+// Skip v bytes due to alignment, etc.
+static void
+proggenskip(ProgGen *g, vlong off, vlong v)
+{
+	vlong i;
+
+	for(i = off; i < off+v; i++) {
+		if((i%widthptr) == 0)
+			proggendata(g, BitsScalar);
+	}
+}
+
+// Emit insArray instruction.
+static void
+proggenarray(ProgGen *g, vlong len)
+{
+	int32 i;
+
+	proggendataflush(g);
+	proggenemit(g, insArray);
+	for(i = 0; i < widthptr; i++, len >>= 8)
+		proggenemit(g, len);
+}
+
+static void
+proggenarrayend(ProgGen *g)
+{
+	proggendataflush(g);
+	proggenemit(g, insArrayEnd);
+}
+
+static vlong
+proggenfini(ProgGen *g)
+{
+	proggendataflush(g);
+	proggenemit(g, insEnd);
+	return g->ot;
+}
+
+static void gengcprog1(ProgGen *g, Type *t, vlong *xoffset);
+
+// Generates GC program for large types.
+static void
+gengcprog(Type *t, Sym **pgc0, Sym **pgc1)
+{
+	Sym *gc0, *gc1;
+	vlong nptr, size, ot, xoffset;
+	ProgGen g;
+
+	nptr = (t->width+widthptr-1)/widthptr;
+	size = nptr;
+	if(size%2)
+		size *= 2;	// repeated twice
+	size = size*PointersPerByte/8;	// 4 bits per word
+	size++;	// unroll flag in the beginning, used by runtime (see runtime.markallocated)
+	// emity space in BSS for unrolled program
+	*pgc0 = S;
+	// Don't generate it if it's too large, runtime will unroll directly into GC bitmap.
+	if(size <= MaxGCMask) {
+		gc0 = typesymprefix(".gc", t);
+		ggloblsym(gc0, size, DUPOK|NOPTR);
+		*pgc0 = gc0;
+	}
+
+	// program in RODATA
+	gc1 = typesymprefix(".gcprog", t);
+	proggeninit(&g, gc1);
+	xoffset = 0;
+	gengcprog1(&g, t, &xoffset);
+	ot = proggenfini(&g);
+	ggloblsym(gc1, ot, DUPOK|RODATA);
+	*pgc1 = gc1;
+}
+
+// Recursively walks type t and writes GC program into g.
+static void
+gengcprog1(ProgGen *g, Type *t, vlong *xoffset)
+{
+	vlong fieldoffset, i, o, n;
+	Type *t1;
 
-	if(t->width == BADWIDTH)
-		dowidth(t);
-	
 	switch(t->etype) {
 	case TINT8:
 	case TUINT8:
@@ -1314,187 +1507,71 @@ dgcsym1(Sym *s, int ot, Type *t, vlong *off, int stack_size)
 	case TFLOAT64:
 	case TCOMPLEX64:
 	case TCOMPLEX128:
-		*off += t->width;
+		proggenskip(g, *xoffset, t->width);
+		*xoffset += t->width;
 		break;
-
 	case TPTR32:
 	case TPTR64:
-		// NOTE: Any changes here need to be made to reflect.PtrTo as well.
-		if(*off % widthptr != 0)
-			fatal("dgcsym1: invalid alignment, %T", t);
-
-		// NOTE(rsc): Emitting GC_APTR here for *nonptrtype
-		// (pointer to non-pointer-containing type) means that
-		// we do not record 'nonptrtype' and instead tell the 
-		// garbage collector to look up the type of the memory in
-		// type information stored in the heap. In effect we are telling
-		// the collector "we don't trust our information - use yours".
-		// It's not completely clear why we want to do this.
-		// It does have the effect that if you have a *SliceHeader and a *[]int
-		// pointing at the same actual slice header, *SliceHeader will not be
-		// used as an authoritative type for the memory, which is good:
-		// if the collector scanned the memory as type *SliceHeader, it would
-		// see no pointers inside but mark the block as scanned, preventing
-		// the seeing of pointers when we followed the *[]int pointer.
-		// Perhaps that kind of situation is the rationale.
-		if(!haspointers(t->type)) {
-			ot = duintptr(s, ot, GC_APTR);
-			ot = duintptr(s, ot, *off);
-		} else {
-			ot = duintptr(s, ot, GC_PTR);
-			ot = duintptr(s, ot, *off);
-			ot = dsymptr(s, ot, dgcsym(t->type), 0);
-		}
-		*off += t->width;
-		break;
-
 	case TUNSAFEPTR:
 	case TFUNC:
-		if(*off % widthptr != 0)
-			fatal("dgcsym1: invalid alignment, %T", t);
-		ot = duintptr(s, ot, GC_APTR);
-		ot = duintptr(s, ot, *off);
-		*off += t->width;
-		break;
-
-	// struct Hchan*
 	case TCHAN:
-		// NOTE: Any changes here need to be made to reflect.ChanOf as well.
-		if(*off % widthptr != 0)
-			fatal("dgcsym1: invalid alignment, %T", t);
-		ot = duintptr(s, ot, GC_CHAN_PTR);
-		ot = duintptr(s, ot, *off);
-		ot = dsymptr(s, ot, dtypesym(t), 0);
-		*off += t->width;
-		break;
-
-	// struct Hmap*
 	case TMAP:
-		// NOTE: Any changes here need to be made to reflect.MapOf as well.
-		if(*off % widthptr != 0)
-			fatal("dgcsym1: invalid alignment, %T", t);
-		ot = duintptr(s, ot, GC_PTR);
-		ot = duintptr(s, ot, *off);
-		ot = dsymptr(s, ot, dgcsym(hmap(t)), 0);
-		*off += t->width;
+		proggendata(g, BitsPointer);
+		*xoffset += t->width;
 		break;
-
-	// struct { byte *str; int32 len; }
 	case TSTRING:
-		if(*off % widthptr != 0)
-			fatal("dgcsym1: invalid alignment, %T", t);
-		ot = duintptr(s, ot, GC_STRING);
-		ot = duintptr(s, ot, *off);
-		*off += t->width;
+		proggendata(g, BitsPointer);
+		proggendata(g, BitsScalar);
+		*xoffset += t->width;
 		break;
-
-	// struct { Itab* tab;  void* data; }
-	// struct { Type* type; void* data; }	// When isnilinter(t)==true
 	case TINTER:
-		if(*off % widthptr != 0)
-			fatal("dgcsym1: invalid alignment, %T", t);
-		if(isnilinter(t)) {
-			ot = duintptr(s, ot, GC_EFACE);
-			ot = duintptr(s, ot, *off);
-		} else {
-			ot = duintptr(s, ot, GC_IFACE);
-			ot = duintptr(s, ot, *off);
-		}
-		*off += t->width;
+		proggendata(g, BitsMultiWord);
+		if(isnilinter(t))
+			proggendata(g, BitsEface);
+		else
+			proggendata(g, BitsIface);
+		*xoffset += t->width;
 		break;
-
 	case TARRAY:
-		if(t->bound < -1)
-			fatal("dgcsym1: invalid bound, %T", t);
-		if(t->type->width == BADWIDTH)
-			dowidth(t->type);
 		if(isslice(t)) {
-			// NOTE: Any changes here need to be made to reflect.SliceOf as well.
-			// struct { byte* array; uint32 len; uint32 cap; }
-			if(*off % widthptr != 0)
-				fatal("dgcsym1: invalid alignment, %T", t);
-			if(t->type->width != 0) {
-				ot = duintptr(s, ot, GC_SLICE);
-				ot = duintptr(s, ot, *off);
-				ot = dsymptr(s, ot, dgcsym(t->type), 0);
-			} else {
-				ot = duintptr(s, ot, GC_APTR);
-				ot = duintptr(s, ot, *off);
-			}
-			*off += t->width;
+			proggendata(g, BitsPointer);
+			proggendata(g, BitsScalar);
+			proggendata(g, BitsScalar);
 		} else {
-			// NOTE: Any changes here need to be made to reflect.ArrayOf as well,
-			// at least once ArrayOf's gc info is implemented and ArrayOf is exported.
-			// struct { byte* array; uint32 len; uint32 cap; }
-			if(t->bound < 1 || !haspointers(t->type)) {
-				*off += t->width;
-			} else if(gcinline(t)) {
-				for(i=0; i<t->bound; i++)
-					ot = dgcsym1(s, ot, t->type, off, stack_size);  // recursive call of dgcsym1
+			t1 = t->type;
+			if(t1->width == 0) {
+				// ignore
+			} if(t->bound <= 1 || t->bound*t1->width < 32*widthptr) {
+				for(i = 0; i < t->bound; i++)
+					gengcprog1(g, t1, xoffset);
+			} else if(!haspointers(t1)) {
+				n = t->width;
+				n -= -*xoffset&(widthptr-1); // skip to next ptr boundary
+				proggenarray(g, (n+widthptr-1)/widthptr);
+				proggendata(g, BitsScalar);
+				proggenarrayend(g);
+				*xoffset -= (n+widthptr-1)/widthptr*widthptr - t->width;
 			} else {
-				if(stack_size < GC_STACK_CAPACITY) {
-					ot = duintptr(s, ot, GC_ARRAY_START);  // a stack push during GC
-					ot = duintptr(s, ot, *off);
-					ot = duintptr(s, ot, t->bound);
-					ot = duintptr(s, ot, t->type->width);
-					off2 = 0;
-					ot = dgcsym1(s, ot, t->type, &off2, stack_size+1);  // recursive call of dgcsym1
-					ot = duintptr(s, ot, GC_ARRAY_NEXT);  // a stack pop during GC
-				} else {
-					ot = duintptr(s, ot, GC_REGION);
-					ot = duintptr(s, ot, *off);
-					ot = duintptr(s, ot, t->width);
-					ot = dsymptr(s, ot, dgcsym(t), 0);
-				}
-				*off += t->width;
+				proggenarray(g, t->bound);
+				gengcprog1(g, t1, xoffset);
+				*xoffset += (t->bound-1)*t1->width;
+				proggenarrayend(g);
 			}
 		}
 		break;
-
 	case TSTRUCT:
 		o = 0;
-		for(t1=t->type; t1!=T; t1=t1->down) {
+		for(t1 = t->type; t1 != T; t1 = t1->down) {
 			fieldoffset = t1->width;
-			*off += fieldoffset - o;
-			ot = dgcsym1(s, ot, t1->type, off, stack_size);  // recursive call of dgcsym1
+			proggenskip(g, *xoffset, fieldoffset - o);
+			*xoffset += fieldoffset - o;
+			gengcprog1(g, t1->type, xoffset);
 			o = fieldoffset + t1->type->width;
 		}
-		*off += t->width - o;
+		proggenskip(g, *xoffset, t->width - o);
+		*xoffset += t->width - o;
 		break;
-
 	default:
-		fatal("dgcsym1: unexpected type %T", t);
+		fatal("gengcprog1: unexpected type, %T", t);
 	}
-
-	return ot;
-}
-
-static Sym*
-dgcsym(Type *t)
-{
-	int ot;
-	vlong off;
-	Sym *s;
-
-	s = typesymprefix(".gc", t);
-	if(s->flags & SymGcgen)
-		return s;
-	s->flags |= SymGcgen;
-
-	if(t->width == BADWIDTH)
-		dowidth(t);
-
-	ot = 0;
-	off = 0;
-	ot = duintptr(s, ot, t->width);
-	ot = dgcsym1(s, ot, t, &off, 0);
-	ot = duintptr(s, ot, GC_END);
-	ggloblsym(s, ot, 1, 1);
-
-	if(t->align > 0)
-		off = rnd(off, t->align);
-	if(off != t->width)
-		fatal("dgcsym: off=%lld, size=%lld, type %T", off, t->width, t);
-
-	return s;
 }
diff --git a/src/cmd/gc/runtime.go b/src/cmd/gc/runtime.go
index fb5c2a1..0fb15c2 100644
--- a/src/cmd/gc/runtime.go
+++ b/src/cmd/gc/runtime.go
@@ -12,7 +12,7 @@ package PACKAGE
 
 // emitted by compiler, not referred to by go programs
 
-func new(typ *byte) *any
+func newobject(typ *byte) *any
 func panicindex()
 func panicslice()
 func panicdivide()
@@ -20,12 +20,13 @@ func throwreturn()
 func throwinit()
 func panicwrap(string, string, string)
 
-func panic(interface{})
-func recover(*int32) interface{}
+func gopanic(interface{})
+func gorecover(*int32) interface{}
 
 func printbool(bool)
 func printfloat(float64)
 func printint(int64)
+func printhex(uint64)
 func printuint(uint64)
 func printcomplex(complex128)
 func printstring(string)
@@ -35,7 +36,6 @@ func printeface(any)
 func printslice(any)
 func printnl()
 func printsp()
-func goprintf()
 
 func concatstring2(string, string) string
 func concatstring3(string, string, string) string
@@ -53,7 +53,7 @@ func stringtoslicebyte(string) []byte
 func stringtoslicerune(string) []rune
 func stringiter(string, int) int
 func stringiter2(string, int) (retk int, retv rune)
-func copy(to any, fr any, wid uintptr) int
+func slicecopy(to any, fr any, wid uintptr) int
 func slicestringcopy(to any, fr any) int
 
 // interface conversions
@@ -84,8 +84,6 @@ func efaceeq(i1 any, i2 any) (ret bool)
 func ifacethash(i1 any) (ret uint32)
 func efacethash(i1 any) (ret uint32)
 
-func equal(typ *byte, x1, x2 any) (ret bool)
-
 // *byte is really *runtime.Type
 func makemap(mapType *byte, hint int64) (hmap map[any]any)
 func mapaccess1(mapType *byte, hmap map[any]any, key *any) (val *any)
@@ -108,11 +106,25 @@ func chanrecv2(chanType *byte, hchan <-chan any, elem *any) bool
 func chansend1(chanType *byte, hchan chan<- any, elem *any)
 func closechan(hchan any)
 
+// *byte is really *runtime.Type
+func writebarrierptr(dst *any, src any)
+func writebarrierstring(dst *any, src any)
+func writebarrierslice(dst *any, src any)
+func writebarrieriface(dst *any, src any)
+
+// The unused *byte argument makes sure that src is 2-pointer-aligned,
+// which is the maximum alignment on NaCl amd64p32
+// (and possibly on 32-bit systems if we start 64-bit aligning uint64s).
+func writebarrierfat2(dst *any, _ *byte, src any)
+func writebarrierfat3(dst *any, _ *byte, src any)
+func writebarrierfat4(dst *any, _ *byte, src any)
+func writebarrierfat(typ *byte, dst *any, src *any)
+
 func selectnbsend(chanType *byte, hchan chan<- any, elem *any) bool
 func selectnbrecv(chanType *byte, elem *any, hchan <-chan any) bool
 func selectnbrecv2(chanType *byte, elem *any, received *bool, hchan <-chan any) bool
 
-func newselect(size int32) (sel *byte)
+func newselect(sel *byte, selsize int64, size int32)
 func selectsend(sel *byte, hchan chan<- any, elem *any) (selected bool)
 func selectrecv(sel *byte, hchan <-chan any, elem *any) (selected bool)
 func selectrecv2(sel *byte, hchan <-chan any, elem *any, received *bool) (selected bool)
@@ -124,12 +136,12 @@ func makeslice(typ *byte, nel int64, cap int64) (ary []any)
 func growslice(typ *byte, old []any, n int64) (ary []any)
 func memmove(to *any, frm *any, length uintptr)
 
-func memequal(eq *bool, size uintptr, x, y *any)
-func memequal8(eq *bool, size uintptr, x, y *any)
-func memequal16(eq *bool, size uintptr, x, y *any)
-func memequal32(eq *bool, size uintptr, x, y *any)
-func memequal64(eq *bool, size uintptr, x, y *any)
-func memequal128(eq *bool, size uintptr, x, y *any)
+func memequal(x, y *any, size uintptr) bool
+func memequal8(x, y *any, size uintptr) bool
+func memequal16(x, y *any, size uintptr) bool
+func memequal32(x, y *any, size uintptr) bool
+func memequal64(x, y *any, size uintptr) bool
+func memequal128(x, y *any, size uintptr) bool
 
 // only used on 32-bit
 func int64div(int64, int64) int64
diff --git a/src/cmd/gc/select.c b/src/cmd/gc/select.c
index 58a1206..965ad27 100644
--- a/src/cmd/gc/select.c
+++ b/src/cmd/gc/select.c
@@ -10,6 +10,8 @@
 #include <libc.h>
 #include "go.h"
 
+static Type* selecttype(int32 size);
+
 void
 typecheckselect(Node *sel)
 {
@@ -95,7 +97,7 @@ void
 walkselect(Node *sel)
 {
 	int lno, i;
-	Node *n, *r, *a, *var, *cas, *dflt, *ch;
+	Node *n, *r, *a, *var, *selv, *cas, *dflt, *ch;
 	NodeList *l, *init;
 	
 	if(sel->list == nil && sel->xoffset != 0)
@@ -257,8 +259,12 @@ walkselect(Node *sel)
 
 	// generate sel-struct
 	setlineno(sel);
-	var = temp(ptrto(types[TUINT8]));
-	r = nod(OAS, var, mkcall("newselect", var->type, nil, nodintconst(sel->xoffset)));
+	selv = temp(selecttype(sel->xoffset));
+	r = nod(OAS, selv, N);
+	typecheck(&r, Etop);
+	init = list(init, r);
+	var = conv(conv(nod(OADDR, selv, N), types[TUNSAFEPTR]), ptrto(types[TUINT8]));
+	r = mkcall("newselect", T, nil, var, nodintconst(selv->type->width), nodintconst(sel->xoffset));
 	typecheck(&r, Etop);
 	init = list(init, r);
 
@@ -301,6 +307,8 @@ walkselect(Node *sel)
 				break;
 			}
 		}
+		// selv is no longer alive after use.
+		r->nbody = list(r->nbody, nod(OVARKILL, selv, N));
 		r->nbody = concat(r->nbody, cas->nbody);
 		r->nbody = list(r->nbody, nod(OBREAK, N, N));
 		init = list(init, r);
@@ -316,3 +324,54 @@ out:
 	walkstmtlist(sel->nbody);
 	lineno = lno;
 }
+
+// Keep in sync with src/runtime/chan.h.
+static Type*
+selecttype(int32 size)
+{
+	Node *sel, *sudog, *scase, *arr;
+
+	// TODO(dvyukov): it's possible to generate SudoG and Scase only once
+	// and then cache; and also cache Select per size.
+	sudog = nod(OTSTRUCT, N, N);
+	sudog->list = list(sudog->list, nod(ODCLFIELD, newname(lookup("g")), typenod(ptrto(types[TUINT8]))));
+	sudog->list = list(sudog->list, nod(ODCLFIELD, newname(lookup("selectdone")), typenod(ptrto(types[TUINT8]))));
+	sudog->list = list(sudog->list, nod(ODCLFIELD, newname(lookup("link")), typenod(ptrto(types[TUINT8]))));
+	sudog->list = list(sudog->list, nod(ODCLFIELD, newname(lookup("prev")), typenod(ptrto(types[TUINT8]))));
+	sudog->list = list(sudog->list, nod(ODCLFIELD, newname(lookup("elem")), typenod(ptrto(types[TUINT8]))));
+	sudog->list = list(sudog->list, nod(ODCLFIELD, newname(lookup("releasetime")), typenod(types[TUINT64])));
+	sudog->list = list(sudog->list, nod(ODCLFIELD, newname(lookup("nrelease")), typenod(types[TINT32])));
+	sudog->list = list(sudog->list, nod(ODCLFIELD, newname(lookup("waitlink")), typenod(ptrto(types[TUINT8]))));
+	typecheck(&sudog, Etype);
+	sudog->type->noalg = 1;
+	sudog->type->local = 1;
+
+	scase = nod(OTSTRUCT, N, N);
+	scase->list = list(scase->list, nod(ODCLFIELD, newname(lookup("elem")), typenod(ptrto(types[TUINT8]))));
+	scase->list = list(scase->list, nod(ODCLFIELD, newname(lookup("chan")), typenod(ptrto(types[TUINT8]))));
+	scase->list = list(scase->list, nod(ODCLFIELD, newname(lookup("pc")), typenod(types[TUINTPTR])));
+	scase->list = list(scase->list, nod(ODCLFIELD, newname(lookup("kind")), typenod(types[TUINT16])));
+	scase->list = list(scase->list, nod(ODCLFIELD, newname(lookup("so")), typenod(types[TUINT16])));
+	scase->list = list(scase->list, nod(ODCLFIELD, newname(lookup("receivedp")), typenod(ptrto(types[TUINT8]))));
+	scase->list = list(scase->list, nod(ODCLFIELD, newname(lookup("releasetime")), typenod(types[TUINT64])));
+	typecheck(&scase, Etype);
+	scase->type->noalg = 1;
+	scase->type->local = 1;
+
+	sel = nod(OTSTRUCT, N, N);
+	sel->list = list(sel->list, nod(ODCLFIELD, newname(lookup("tcase")), typenod(types[TUINT16])));
+	sel->list = list(sel->list, nod(ODCLFIELD, newname(lookup("ncase")), typenod(types[TUINT16])));
+	sel->list = list(sel->list, nod(ODCLFIELD, newname(lookup("pollorder")), typenod(ptrto(types[TUINT8]))));
+	sel->list = list(sel->list, nod(ODCLFIELD, newname(lookup("lockorder")), typenod(ptrto(types[TUINT8]))));
+	arr = nod(OTARRAY, nodintconst(size), scase);
+	sel->list = list(sel->list, nod(ODCLFIELD, newname(lookup("scase")), arr));
+	arr = nod(OTARRAY, nodintconst(size), typenod(ptrto(types[TUINT8])));
+	sel->list = list(sel->list, nod(ODCLFIELD, newname(lookup("lockorderarr")), arr));
+	arr = nod(OTARRAY, nodintconst(size), typenod(types[TUINT16]));
+	sel->list = list(sel->list, nod(ODCLFIELD, newname(lookup("pollorderarr")), arr));
+	typecheck(&sel, Etype);
+	sel->type->noalg = 1;
+	sel->type->local = 1;
+
+	return sel->type;
+}
diff --git a/src/cmd/gc/sinit.c b/src/cmd/gc/sinit.c
index 59804cd..8ad7ae7 100644
--- a/src/cmd/gc/sinit.c
+++ b/src/cmd/gc/sinit.c
@@ -17,7 +17,6 @@ enum
 	InitPending = 2,
 };
 
-static int iszero(Node*);
 static void initplan(Node*);
 static NodeList *initlist;
 static void init2(Node*, NodeList**);
@@ -207,7 +206,7 @@ init2(Node *n, NodeList **out)
 	
 	if(n->op == OCLOSURE)
 		init2list(n->closure->nbody, out);
-	if(n->op == ODOTMETH)
+	if(n->op == ODOTMETH || n->op == OCALLPART)
 		init2(n->type->nname, out);
 }
 
@@ -633,11 +632,14 @@ structlit(int ctxt, int pass, Node *n, Node *var, NodeList **init)
 		a = nod(ODOT, var, newname(index->sym));
 		a = nod(OAS, a, value);
 		typecheck(&a, Etop);
-		walkexpr(&a, init);
 		if(pass == 1) {
+			walkexpr(&a, init);	// add any assignments in r to top
 			if(a->op != OAS)
 				fatal("structlit: not as");
 			a->dodata = 2;
+		} else {
+			orderstmtinplace(&a);
+			walkstmt(&a);
 		}
 		*init = list(*init, a);
 	}
@@ -693,11 +695,14 @@ arraylit(int ctxt, int pass, Node *n, Node *var, NodeList **init)
 		a = nod(OINDEX, var, index);
 		a = nod(OAS, a, value);
 		typecheck(&a, Etop);
-		walkexpr(&a, init);	// add any assignments in r to top
 		if(pass == 1) {
+			walkexpr(&a, init);
 			if(a->op != OAS)
-				fatal("structlit: not as");
+				fatal("arraylit: not as");
 			a->dodata = 2;
+		} else {
+			orderstmtinplace(&a);
+			walkstmt(&a);
 		}
 		*init = list(*init, a);
 	}
@@ -807,7 +812,8 @@ slicelit(int ctxt, Node *n, Node *var, NodeList **init)
 	// make slice out of heap (5)
 	a = nod(OAS, var, nod(OSLICE, vauto, nod(OKEY, N, N)));
 	typecheck(&a, Etop);
-	walkexpr(&a, init);
+	orderstmtinplace(&a);
+	walkstmt(&a);
 	*init = list(*init, a);
 
 	// put dynamics into slice (6)
@@ -839,7 +845,8 @@ slicelit(int ctxt, Node *n, Node *var, NodeList **init)
 		// build list of var[c] = expr
 		a = nod(OAS, a, value);
 		typecheck(&a, Etop);
-		walkexpr(&a, init);
+		orderstmtinplace(&a);
+		walkstmt(&a);
 		*init = list(*init, a);
 	}
 }
@@ -1060,7 +1067,7 @@ anylit(int ctxt, Node *n, Node *var, NodeList **init)
 		if(t->etype != TSTRUCT)
 			fatal("anylit: not struct");
 
-		if(simplename(var)) {
+		if(simplename(var) && count(n->list) > 4) {
 
 			if(ctxt == 0) {
 				// lay out static data
@@ -1083,7 +1090,7 @@ anylit(int ctxt, Node *n, Node *var, NodeList **init)
 		}
 
 		// initialize of not completely specified
-		if(count(n->list) < structcount(t)) {
+		if(simplename(var) || count(n->list) < structcount(t)) {
 			a = nod(OAS, var, N);
 			typecheck(&a, Etop);
 			walkexpr(&a, init);
@@ -1100,7 +1107,7 @@ anylit(int ctxt, Node *n, Node *var, NodeList **init)
 			break;
 		}
 
-		if(simplename(var)) {
+		if(simplename(var) && count(n->list) > 4) {
 
 			if(ctxt == 0) {
 				// lay out static data
@@ -1123,7 +1130,7 @@ anylit(int ctxt, Node *n, Node *var, NodeList **init)
 		}
 
 		// initialize of not completely specified
-		if(count(n->list) < t->bound) {
+		if(simplename(var) || count(n->list) < t->bound) {
 			a = nod(OAS, var, N);
 			typecheck(&a, Etop);
 			walkexpr(&a, init);
@@ -1348,7 +1355,6 @@ no:
 	return 0;
 }
 
-static int iszero(Node*);
 static int isvaluelit(Node*);
 static InitEntry* entry(InitPlan*);
 static void addvalue(InitPlan*, vlong, Node*, Node*);
@@ -1432,7 +1438,7 @@ addvalue(InitPlan *p, vlong xoffset, Node *key, Node *n)
 	e->expr = n;
 }
 
-static int
+int
 iszero(Node *n)
 {
 	NodeList *l;
diff --git a/src/cmd/gc/subr.c b/src/cmd/gc/subr.c
index 72a9ac2..c3bc5af 100644
--- a/src/cmd/gc/subr.c
+++ b/src/cmd/gc/subr.c
@@ -529,7 +529,8 @@ algtype1(Type *t, Type **bad)
 	
 	if(bad)
 		*bad = T;
-
+	if(t->broke)
+		return AMEM;
 	if(t->noalg)
 		return ANOEQ;
 
@@ -656,11 +657,15 @@ maptype(Type *key, Type *val)
 {
 	Type *t;
 	Type *bad;
-	int atype;
+	int atype, mtype;
 
 	if(key != nil) {
 		atype = algtype1(key, &bad);
-		switch(bad == T ? key->etype : bad->etype) {
+		if(bad == T)
+			mtype = key->etype;
+		else
+			mtype = bad->etype;
+		switch(mtype) {
 		default:
 			if(atype == ANOEQ)
 				yyerror("invalid map key type %T", key);
@@ -2625,9 +2630,10 @@ hashmem(Type *t)
 	n = newname(sym);
 	n->class = PFUNC;
 	tfn = nod(OTFUNC, N, N);
-	tfn->list = list(tfn->list, nod(ODCLFIELD, N, typenod(ptrto(types[TUINTPTR]))));
-	tfn->list = list(tfn->list, nod(ODCLFIELD, N, typenod(types[TUINTPTR])));
 	tfn->list = list(tfn->list, nod(ODCLFIELD, N, typenod(ptrto(t))));
+	tfn->list = list(tfn->list, nod(ODCLFIELD, N, typenod(types[TUINTPTR])));
+	tfn->list = list(tfn->list, nod(ODCLFIELD, N, typenod(types[TUINTPTR])));
+	tfn->rlist = list(tfn->rlist, nod(ODCLFIELD, N, typenod(types[TUINTPTR])));
 	typecheck(&tfn, Etype);
 	n->type = tfn->type;
 	return n;
@@ -2673,9 +2679,10 @@ hashfor(Type *t)
 	n = newname(sym);
 	n->class = PFUNC;
 	tfn = nod(OTFUNC, N, N);
-	tfn->list = list(tfn->list, nod(ODCLFIELD, N, typenod(ptrto(types[TUINTPTR]))));
-	tfn->list = list(tfn->list, nod(ODCLFIELD, N, typenod(types[TUINTPTR])));
 	tfn->list = list(tfn->list, nod(ODCLFIELD, N, typenod(ptrto(t))));
+	tfn->list = list(tfn->list, nod(ODCLFIELD, N, typenod(types[TUINTPTR])));
+	tfn->list = list(tfn->list, nod(ODCLFIELD, N, typenod(types[TUINTPTR])));
+	tfn->rlist = list(tfn->rlist, nod(ODCLFIELD, N, typenod(types[TUINTPTR])));
 	typecheck(&tfn, Etype);
 	n->type = tfn->type;
 	return n;
@@ -2687,7 +2694,7 @@ hashfor(Type *t)
 void
 genhash(Sym *sym, Type *t)
 {
-	Node *n, *fn, *np, *nh, *ni, *call, *nx, *na, *tfn;
+	Node *n, *fn, *np, *nh, *ni, *call, *nx, *na, *tfn, *r;
 	Node *hashel;
 	Type *first, *t1;
 	int old_safemode;
@@ -2700,21 +2707,23 @@ genhash(Sym *sym, Type *t)
 	dclcontext = PEXTERN;
 	markdcl();
 
-	// func sym(h *uintptr, s uintptr, p *T)
+	// func sym(p *T, s uintptr, h uintptr) uintptr
 	fn = nod(ODCLFUNC, N, N);
 	fn->nname = newname(sym);
 	fn->nname->class = PFUNC;
 	tfn = nod(OTFUNC, N, N);
 	fn->nname->ntype = tfn;
 
-	n = nod(ODCLFIELD, newname(lookup("h")), typenod(ptrto(types[TUINTPTR])));
+	n = nod(ODCLFIELD, newname(lookup("p")), typenod(ptrto(t)));
 	tfn->list = list(tfn->list, n);
-	nh = n->left;
+	np = n->left;
 	n = nod(ODCLFIELD, newname(lookup("s")), typenod(types[TUINTPTR]));
 	tfn->list = list(tfn->list, n);
-	n = nod(ODCLFIELD, newname(lookup("p")), typenod(ptrto(t)));
+	n = nod(ODCLFIELD, newname(lookup("h")), typenod(types[TUINTPTR]));
 	tfn->list = list(tfn->list, n);
-	np = n->left;
+	nh = n->left;
+	n = nod(ODCLFIELD, N, typenod(types[TUINTPTR])); // return value
+	tfn->rlist = list(tfn->rlist, n);
 
 	funchdr(fn);
 	typecheck(&fn->nname->ntype, Etype);
@@ -2740,15 +2749,17 @@ genhash(Sym *sym, Type *t)
 		colasdefn(n->list, n);
 		ni = n->list->n;
 
-		// *h = *h<<3 | *h>>61
+		// TODO: with aeshash we don't need these shift/mul parts
+
+		// h = h<<3 | h>>61
 		n->nbody = list(n->nbody,
 			nod(OAS,
-				nod(OIND, nh, N),
+			    nh,
 				nod(OOR,
-					nod(OLSH, nod(OIND, nh, N), nodintconst(3)),
-					nod(ORSH, nod(OIND, nh, N), nodintconst(widthptr*8-3)))));
+					nod(OLSH, nh, nodintconst(3)),
+					nod(ORSH, nh, nodintconst(widthptr*8-3)))));
 
-		// *h *= mul
+		// h *= mul
 		// Same multipliers as in runtime.memhash.
 		if(widthptr == 4)
 			mul = 3267000013LL;
@@ -2756,19 +2767,19 @@ genhash(Sym *sym, Type *t)
 			mul = 23344194077549503LL;
 		n->nbody = list(n->nbody,
 			nod(OAS,
-				nod(OIND, nh, N),
-				nod(OMUL, nod(OIND, nh, N), nodintconst(mul))));
+				nh,
+				nod(OMUL, nh, nodintconst(mul))));
 
-		// hashel(h, sizeof(p[i]), &p[i])
+		// h = hashel(&p[i], sizeof(p[i]), h)
 		call = nod(OCALL, hashel, N);
-		call->list = list(call->list, nh);
-		call->list = list(call->list, nodintconst(t->type->width));
 		nx = nod(OINDEX, np, ni);
 		nx->bounded = 1;
 		na = nod(OADDR, nx, N);
 		na->etype = 1;  // no escape to heap
 		call->list = list(call->list, na);
-		n->nbody = list(n->nbody, call);
+		call->list = list(call->list, nodintconst(t->type->width));
+		call->list = list(call->list, nh);
+		n->nbody = list(n->nbody, nod(OAS, nh, call));
 
 		fn->nbody = list(fn->nbody, n);
 		break;
@@ -2793,15 +2804,15 @@ genhash(Sym *sym, Type *t)
 			if(first != T) {
 				size = offend - first->width; // first->width is offset
 				hashel = hashmem(first->type);
-				// hashel(h, size, &p.first)
+				// h = hashel(&p.first, size, h)
 				call = nod(OCALL, hashel, N);
-				call->list = list(call->list, nh);
-				call->list = list(call->list, nodintconst(size));
 				nx = nod(OXDOT, np, newname(first->sym));  // TODO: fields from other packages?
 				na = nod(OADDR, nx, N);
 				na->etype = 1;  // no escape to heap
 				call->list = list(call->list, na);
-				fn->nbody = list(fn->nbody, call);
+				call->list = list(call->list, nodintconst(size));
+				call->list = list(call->list, nh);
+				fn->nbody = list(fn->nbody, nod(OAS, nh, call));
 
 				first = T;
 			}
@@ -2812,20 +2823,21 @@ genhash(Sym *sym, Type *t)
 
 			// Run hash for this field.
 			hashel = hashfor(t1->type);
-			// hashel(h, size, &p.t1)
+			// h = hashel(&p.t1, size, h)
 			call = nod(OCALL, hashel, N);
-			call->list = list(call->list, nh);
-			call->list = list(call->list, nodintconst(t1->type->width));
 			nx = nod(OXDOT, np, newname(t1->sym));  // TODO: fields from other packages?
 			na = nod(OADDR, nx, N);
 			na->etype = 1;  // no escape to heap
 			call->list = list(call->list, na);
-			fn->nbody = list(fn->nbody, call);
+			call->list = list(call->list, nodintconst(t1->type->width));
+			call->list = list(call->list, nh);
+			fn->nbody = list(fn->nbody, nod(OAS, nh, call));
 		}
-		// make sure body is not empty.
-		fn->nbody = list(fn->nbody, nod(ORETURN, N, N));
 		break;
 	}
+	r = nod(ORETURN, N, N);
+	r->list = list(r->list, nh);
+	fn->nbody = list(fn->nbody, r);
 
 	if(debug['r'])
 		dumplist("genhash body", fn->nbody);
@@ -2849,18 +2861,19 @@ genhash(Sym *sym, Type *t)
 }
 
 // Return node for
-//	if p.field != q.field { *eq = false; return }
+//	if p.field != q.field { return false }
 static Node*
-eqfield(Node *p, Node *q, Node *field, Node *eq)
+eqfield(Node *p, Node *q, Node *field)
 {
-	Node *nif, *nx, *ny;
+	Node *nif, *nx, *ny, *r;
 
 	nx = nod(OXDOT, p, field);
 	ny = nod(OXDOT, q, field);
 	nif = nod(OIF, N, N);
 	nif->ntest = nod(ONE, nx, ny);
-	nif->nbody = list(nif->nbody, nod(OAS, nod(OIND, eq, N), nodbool(0)));
-	nif->nbody = list(nif->nbody, nod(ORETURN, N, N));
+	r = nod(ORETURN, N, N);
+	r->list = list(r->list, nodbool(0));
+	nif->nbody = list(nif->nbody, r);
 	return nif;
 }
 
@@ -2889,11 +2902,11 @@ eqmemfunc(vlong size, Type *type)
 }
 
 // Return node for
-//	if memequal(size, &p.field, &q.field, eq); !*eq { return }
+//	if !memequal(&p.field, &q.field, size) { return false }
 static Node*
-eqmem(Node *p, Node *q, Node *field, vlong size, Node *eq)
+eqmem(Node *p, Node *q, Node *field, vlong size)
 {
-	Node *nif, *nx, *ny, *call;
+	Node *nif, *nx, *ny, *call, *r;
 
 	nx = nod(OADDR, nod(OXDOT, p, field), N);
 	nx->etype = 1;  // does not escape
@@ -2903,15 +2916,16 @@ eqmem(Node *p, Node *q, Node *field, vlong size, Node *eq)
 	typecheck(&ny, Erv);
 
 	call = nod(OCALL, eqmemfunc(size, nx->type->type), N);
-	call->list = list(call->list, eq);
-	call->list = list(call->list, nodintconst(size));
 	call->list = list(call->list, nx);
 	call->list = list(call->list, ny);
+	call->list = list(call->list, nodintconst(size));
 
 	nif = nod(OIF, N, N);
 	nif->ninit = list(nif->ninit, call);
-	nif->ntest = nod(ONOT, nod(OIND, eq, N), N);
-	nif->nbody = list(nif->nbody, nod(ORETURN, N, N));
+	nif->ntest = nod(ONOT, call, N);
+	r = nod(ORETURN, N, N);
+	r->list = list(r->list, nodbool(0));
+	nif->nbody = list(nif->nbody, r);
 	return nif;
 }
 
@@ -2921,7 +2935,7 @@ eqmem(Node *p, Node *q, Node *field, vlong size, Node *eq)
 void
 geneq(Sym *sym, Type *t)
 {
-	Node *n, *fn, *np, *neq, *nq, *tfn, *nif, *ni, *nx, *ny, *nrange;
+	Node *n, *fn, *np, *nq, *tfn, *nif, *ni, *nx, *ny, *nrange, *r;
 	Type *t1, *first;
 	int old_safemode;
 	int64 size;
@@ -2934,24 +2948,23 @@ geneq(Sym *sym, Type *t)
 	dclcontext = PEXTERN;
 	markdcl();
 
-	// func sym(eq *bool, s uintptr, p, q *T)
+	// func sym(p, q *T, s uintptr) bool
 	fn = nod(ODCLFUNC, N, N);
 	fn->nname = newname(sym);
 	fn->nname->class = PFUNC;
 	tfn = nod(OTFUNC, N, N);
 	fn->nname->ntype = tfn;
 
-	n = nod(ODCLFIELD, newname(lookup("eq")), typenod(ptrto(types[TBOOL])));
-	tfn->list = list(tfn->list, n);
-	neq = n->left;
-	n = nod(ODCLFIELD, newname(lookup("s")), typenod(types[TUINTPTR]));
-	tfn->list = list(tfn->list, n);
 	n = nod(ODCLFIELD, newname(lookup("p")), typenod(ptrto(t)));
 	tfn->list = list(tfn->list, n);
 	np = n->left;
 	n = nod(ODCLFIELD, newname(lookup("q")), typenod(ptrto(t)));
 	tfn->list = list(tfn->list, n);
 	nq = n->left;
+	n = nod(ODCLFIELD, newname(lookup("s")), typenod(types[TUINTPTR]));
+	tfn->list = list(tfn->list, n);
+	n = nod(ODCLFIELD, N, typenod(types[TBOOL]));
+	tfn->rlist = list(tfn->rlist, n);
 
 	funchdr(fn);
 
@@ -2977,7 +2990,7 @@ geneq(Sym *sym, Type *t)
 		colasdefn(nrange->list, nrange);
 		ni = nrange->list->n;
 		
-		// if p[i] != q[i] { *eq = false; return }
+		// if p[i] != q[i] { return false }
 		nx = nod(OINDEX, np, ni);
 		nx->bounded = 1;
 		ny = nod(OINDEX, nq, ni);
@@ -2985,13 +2998,11 @@ geneq(Sym *sym, Type *t)
 
 		nif = nod(OIF, N, N);
 		nif->ntest = nod(ONE, nx, ny);
-		nif->nbody = list(nif->nbody, nod(OAS, nod(OIND, neq, N), nodbool(0)));
-		nif->nbody = list(nif->nbody, nod(ORETURN, N, N));
+		r = nod(ORETURN, N, N);
+		r->list = list(r->list, nodbool(0));
+		nif->nbody = list(nif->nbody, r);
 		nrange->nbody = list(nrange->nbody, nif);
 		fn->nbody = list(fn->nbody, nrange);
-
-		// *eq = true;
-		fn->nbody = list(fn->nbody, nod(OAS, nod(OIND, neq, N), nodbool(1)));
 		break;
 
 	case TSTRUCT:
@@ -3016,16 +3027,16 @@ geneq(Sym *sym, Type *t)
 			// cross-package unexported fields.
 			if(first != T) {
 				if(first->down == t1) {
-					fn->nbody = list(fn->nbody, eqfield(np, nq, newname(first->sym), neq));
+					fn->nbody = list(fn->nbody, eqfield(np, nq, newname(first->sym)));
 				} else if(first->down->down == t1) {
-					fn->nbody = list(fn->nbody, eqfield(np, nq, newname(first->sym), neq));
+					fn->nbody = list(fn->nbody, eqfield(np, nq, newname(first->sym)));
 					first = first->down;
 					if(!isblanksym(first->sym))
-						fn->nbody = list(fn->nbody, eqfield(np, nq, newname(first->sym), neq));
+						fn->nbody = list(fn->nbody, eqfield(np, nq, newname(first->sym)));
 				} else {
 					// More than two fields: use memequal.
 					size = offend - first->width; // first->width is offset
-					fn->nbody = list(fn->nbody, eqmem(np, nq, newname(first->sym), size, neq));
+					fn->nbody = list(fn->nbody, eqmem(np, nq, newname(first->sym), size));
 				}
 				first = T;
 			}
@@ -3035,14 +3046,17 @@ geneq(Sym *sym, Type *t)
 				continue;
 
 			// Check this field, which is not just memory.
-			fn->nbody = list(fn->nbody, eqfield(np, nq, newname(t1->sym), neq));
+			fn->nbody = list(fn->nbody, eqfield(np, nq, newname(t1->sym)));
 		}
 
-		// *eq = true;
-		fn->nbody = list(fn->nbody, nod(OAS, nod(OIND, neq, N), nodbool(1)));
 		break;
 	}
 
+	// return true
+	r = nod(ORETURN, N, N);
+	r->list = list(r->list, nodbool(1));
+	fn->nbody = list(fn->nbody, r);
+
 	if(debug['r'])
 		dumplist("geneq body", fn->nbody);
 
@@ -3445,7 +3459,7 @@ smagic(Magic *m)
 		mask = 0xffffffffLL;
 		break;
 	case 64:
-		mask = 0xffffffffffffffffLL;
+		mask = 0xffffffffffffffffULL;
 		break;
 	}
 	two31 = mask ^ (mask>>1);
@@ -3453,7 +3467,7 @@ smagic(Magic *m)
 	p = m->w-1;
 	ad = m->sd;
 	if(m->sd < 0)
-		ad = -m->sd;
+		ad = -(uvlong)m->sd;
 
 	// bad denominators
 	if(ad == 0 || ad == 1 || ad == two31) {
@@ -3543,7 +3557,7 @@ umagic(Magic *m)
 		mask = 0xffffffffLL;
 		break;
 	case 64:
-		mask = 0xffffffffffffffffLL;
+		mask = 0xffffffffffffffffULL;
 		break;
 	}
 	two31 = mask ^ (mask>>1);
@@ -3628,7 +3642,7 @@ ngotype(Node *n)
  * users if we escape that as little as possible.
  *
  * If you edit this, edit ../ld/lib.c:/^pathtoprefix too.
- * If you edit this, edit ../../pkg/debug/goobj/read.go:/importPathToPrefix too.
+ * If you edit this, edit ../../debug/goobj/read.go:/importPathToPrefix too.
  */
 static char*
 pathtoprefix(char *s)
@@ -3785,3 +3799,42 @@ checknil(Node *x, NodeList **init)
 	n->typecheck = 1;
 	*init = list(*init, n);
 }
+
+/*
+ * Can this type be stored directly in an interface word?
+ */
+int
+isdirectiface(Type *t)
+{
+	// Setting IfacePointerOnly = 1 changes the
+	// interface representation so that the data word
+	// in an interface value must always be a pointer.
+	// Setting it to 0 uses the original representation,
+	// where the data word can hold a pointer or any
+	// non-pointer value no bigger than a pointer.
+	enum {
+		IfacePointerOnly = 1,
+	};
+
+	if(IfacePointerOnly) {
+		switch(t->etype) {
+		case TPTR32:
+		case TPTR64:
+		case TCHAN:
+		case TMAP:
+		case TFUNC:
+		case TUNSAFEPTR:
+			return 1;
+		case TARRAY:
+			// Array of 1 direct iface type can be direct.
+			return t->bound == 1 && isdirectiface(t->type);
+		case TSTRUCT:
+			// Struct with 1 field of direct iface type can be direct.
+			return t->type != T && t->type->down == T && isdirectiface(t->type->type);
+		}
+		return 0;
+	}
+	
+	dowidth(t);
+	return t->width <= widthptr;
+}
diff --git a/src/cmd/gc/swt.c b/src/cmd/gc/swt.c
index ce01905..e1d8af8 100644
--- a/src/cmd/gc/swt.c
+++ b/src/cmd/gc/swt.c
@@ -34,6 +34,7 @@ struct	Case
 	Case*	link;		// linked list to link
 };
 #define	C	((Case*)nil)
+/*c2go Case *C; */
 
 void
 dumpcase(Case *c0)
diff --git a/src/cmd/gc/typecheck.c b/src/cmd/gc/typecheck.c
index c50b228..714c662 100644
--- a/src/cmd/gc/typecheck.c
+++ b/src/cmd/gc/typecheck.c
@@ -33,7 +33,7 @@ static void	stringtoarraylit(Node**);
 static Node*	resolve(Node*);
 static void	checkdefergo(Node*);
 static int	checkmake(Type*, char*, Node*);
-static int	checksliceindex(Node*, Type*);
+static int	checksliceindex(Node*, Node*, Type*);
 static int	checksliceconst(Node*, Node*);
 
 static	NodeList*	typecheckdefstack;
@@ -311,6 +311,7 @@ typecheck1(Node **np, int top)
 	Type *t, *tp, *missing, *have, *badtype;
 	Val v;
 	char *why, *desc, descbuf[64];
+	vlong x;
 	
 	n = *np;
 
@@ -382,16 +383,6 @@ reswitch:
 		if(n->type == T)
 			goto error;
 		break;
-
-	case OTPAREN:
-		ok |= Etype;
-		l = typecheck(&n->left, Etype);
-		if(l->type == T)
-			goto error;
-		n->op = OTYPE;
-		n->type = l->type;
-		n->left = N;
-		break;
 	
 	case OTARRAY:
 		ok |= Etype;
@@ -418,7 +409,10 @@ reswitch:
 				v = toint(l->val);
 				break;
 			default:
-				yyerror("invalid array bound %N", l);
+				if(l->type != T && isint[l->type->etype] && l->op != OLITERAL)
+					yyerror("non-constant array bound %N", l);
+				else
+					yyerror("invalid array bound %N", l);
 				goto error;
 			}
 			t->bound = mpgetfix(v.u.xval);
@@ -535,19 +529,6 @@ reswitch:
 		op = n->etype;
 		goto arith;
 
-	case OADDPTR:
-		ok |= Erv;
-		l = typecheck(&n->left, Erv);
-		r = typecheck(&n->right, Erv);
-		if(l->type == T || r->type == T)
-			goto error;
-		if(l->type->etype != tptr)
-			fatal("bad OADDPTR left type %E for %N", l->type->etype, n->left);
-		if(r->type->etype != TUINTPTR)
-			fatal("bad OADDPTR right type %E for %N", r->type->etype, n->right);
-		n->type = types[tptr];
-		goto ret;
-
 	case OADD:
 	case OAND:
 	case OANDAND:
@@ -620,6 +601,10 @@ reswitch:
 		}
 		if(t->etype != TIDEAL && !eqtype(l->type, r->type)) {
 			defaultlit2(&l, &r, 1);
+			if(n->op == OASOP && n->implicit) {
+				yyerror("invalid operation: %N (non-numeric type %T)", n, l->type);
+				goto error;
+			}
 			yyerror("invalid operation: %N (mismatched types %T and %T)", n, l->type, r->type);
 			goto error;
 		}
@@ -756,10 +741,6 @@ reswitch:
 		l = n->left;
 		if((t = l->type) == T)
 			goto error;
-		// top&Eindir means this is &x in *&x.  (or the arg to built-in print)
-		// n->etype means code generator flagged it as non-escaping.
-		if(debug['N'] && !(top & Eindir) && !n->etype)
-			addrescapes(n->left);
 		n->type = ptrto(t);
 		goto ret;
 
@@ -915,11 +896,12 @@ reswitch:
 				break;
 			}
 			if(isconst(n->right, CTINT)) {
-				if(mpgetfix(n->right->val.u.xval) < 0)
+				x = mpgetfix(n->right->val.u.xval);
+				if(x < 0)
 					yyerror("invalid %s index %N (index must be non-negative)", why, n->right);
-				else if(isfixedarray(t) && t->bound > 0 && mpgetfix(n->right->val.u.xval) >= t->bound)
+				else if(isfixedarray(t) && t->bound > 0 && x >= t->bound)
 					yyerror("invalid array index %N (out of bounds for %d-element array)", n->right, t->bound);
-				else if(isconst(n->left, CTSTR) && mpgetfix(n->right->val.u.xval) >= n->left->val.u.sval->len)
+				else if(isconst(n->left, CTSTR) && x >= n->left->val.u.sval->len)
 					yyerror("invalid string index %N (out of bounds for %d-byte string)", n->right, n->left->val.u.sval->len);
 				else if(mpcmpfixfix(n->right->val.u.xval, maxintval[TINT]) > 0)
 					yyerror("invalid %s index %N (index too large)", why, n->right);
@@ -1019,9 +1001,9 @@ reswitch:
 			yyerror("cannot slice %N (type %T)", l, t);
 			goto error;
 		}
-		if((lo = n->right->left) != N && checksliceindex(lo, tp) < 0)
+		if((lo = n->right->left) != N && checksliceindex(l, lo, tp) < 0)
 			goto error;
-		if((hi = n->right->right) != N && checksliceindex(hi, tp) < 0)
+		if((hi = n->right->right) != N && checksliceindex(l, hi, tp) < 0)
 			goto error;
 		if(checksliceconst(lo, hi) < 0)
 			goto error;
@@ -1068,11 +1050,11 @@ reswitch:
 			yyerror("cannot slice %N (type %T)", l, t);
 			goto error;
 		}
-		if((lo = n->right->left) != N && checksliceindex(lo, tp) < 0)
+		if((lo = n->right->left) != N && checksliceindex(l, lo, tp) < 0)
 			goto error;
-		if((mid = n->right->right->left) != N && checksliceindex(mid, tp) < 0)
+		if((mid = n->right->right->left) != N && checksliceindex(l, mid, tp) < 0)
 			goto error;
-		if((hi = n->right->right->right) != N && checksliceindex(hi, tp) < 0)
+		if((hi = n->right->right->right) != N && checksliceindex(l, hi, tp) < 0)
 			goto error;
 		if(checksliceconst(lo, hi) < 0 || checksliceconst(lo, mid) < 0 || checksliceconst(mid, hi) < 0)
 			goto error;
@@ -1842,7 +1824,7 @@ out:
 }
 
 static int
-checksliceindex(Node *r, Type *tp)
+checksliceindex(Node *l, Node *r, Type *tp)
 {
 	Type *t;
 
@@ -1859,6 +1841,9 @@ checksliceindex(Node *r, Type *tp)
 		} else if(tp != nil && tp->bound > 0 && mpgetfix(r->val.u.xval) > tp->bound) {
 			yyerror("invalid slice index %N (out of bounds for %d-element array)", r, tp->bound);
 			return -1;
+		} else if(isconst(l, CTSTR) && mpgetfix(r->val.u.xval) > l->val.u.sval->len) {
+			yyerror("invalid slice index %N (out of bounds for %d-byte string)", r, l->val.u.sval->len);
+			return -1;
 		} else if(mpcmpfixfix(r->val.u.xval, maxintval[TINT]) > 0) {
 			yyerror("invalid slice index %N (index too large)", r);
 			return -1;
@@ -2139,18 +2124,19 @@ lookdot(Node *n, Type *t, int dostrcmp)
 		if(!eqtype(rcvr, tt)) {
 			if(rcvr->etype == tptr && eqtype(rcvr->type, tt)) {
 				checklvalue(n->left, "call pointer method on");
-				if(debug['N'])
-					addrescapes(n->left);
 				n->left = nod(OADDR, n->left, N);
 				n->left->implicit = 1;
 				typecheck(&n->left, Etype|Erv);
-			} else if(tt->etype == tptr && eqtype(tt->type, rcvr)) {
+			} else if(tt->etype == tptr && rcvr->etype != tptr && eqtype(tt->type, rcvr)) {
 				n->left = nod(OIND, n->left, N);
 				n->left->implicit = 1;
 				typecheck(&n->left, Etype|Erv);
-			} else if(tt->etype == tptr && tt->type->etype == tptr && eqtype(derefall(tt), rcvr)) {
+			} else if(tt->etype == tptr && tt->type->etype == tptr && eqtype(derefall(tt), derefall(rcvr))) {
 				yyerror("calling method %N with receiver %lN requires explicit dereference", n->right, n->left);
 				while(tt->etype == tptr) {
+					// Stop one level early for method with pointer receiver.
+					if(rcvr->etype == tptr && tt->type->etype != tptr)
+						break;
 					n->left = nod(OIND, n->left, N);
 					n->left->implicit = 1;
 					typecheck(&n->left, Etype|Erv);
@@ -2831,6 +2817,33 @@ checkassignlist(NodeList *l)
 		checkassign(l->n);
 }
 
+// Check whether l and r are the same side effect-free expression,
+// so that it is safe to reuse one instead of computing both.
+static int
+samesafeexpr(Node *l, Node *r)
+{
+	if(l->op != r->op || !eqtype(l->type, r->type))
+		return 0;
+	
+	switch(l->op) {
+	case ONAME:
+	case OCLOSUREVAR:
+		return l == r;
+	
+	case ODOT:
+	case ODOTPTR:
+		return l->right != nil && r->right != nil && l->right->sym == r->right->sym && samesafeexpr(l->left, r->left);
+	
+	case OIND:
+		return samesafeexpr(l->left, r->left);
+	
+	case OINDEX:
+		return samesafeexpr(l->left, r->left) && samesafeexpr(l->right, r->right);
+	}
+	
+	return 0;
+}
+
 /*
  * type check assignment.
  * if this assignment is the definition of a var on the left side,
@@ -2868,6 +2881,29 @@ typecheckas(Node *n)
 	n->typecheck = 1;
 	if(n->left->typecheck == 0)
 		typecheck(&n->left, Erv | Easgn);
+	
+	// Recognize slices being updated in place, for better code generation later.
+	// Don't rewrite if using race detector, to avoid needing to teach race detector
+	// about this optimization.
+	if(n->left && n->left->op != OINDEXMAP && n->right && !flag_race) {
+		switch(n->right->op) {
+		case OSLICE:
+		case OSLICE3:
+		case OSLICESTR:
+			// For x = x[0:y], x can be updated in place, without touching pointer.
+			if(samesafeexpr(n->left, n->right->left) && (n->right->right->left == N || iszero(n->right->right->left)))
+				n->right->reslice = 1;
+			break;
+		
+		case OAPPEND:
+			// For x = append(x, ...), x can be updated in place when there is capacity,
+			// without touching the pointer; otherwise the emitted code to growslice
+			// can take care of updating the pointer, and only in that case.
+			if(n->right->list != nil && samesafeexpr(n->left, n->right->list->n))
+				n->right->reslice = 1;
+			break;
+		}
+	}
 }
 
 static void
@@ -2975,7 +3011,7 @@ typecheckas2(Node *n)
 			if(l->defn == n)
 				l->type = r->type;
 			l = n->list->next->n;
-			if(l->type != T)
+			if(l->type != T && l->type->etype != TBOOL)
 				checkassignto(types[TBOOL], l);
 			if(l->defn == n && l->ntype == N)
 				l->type = types[TBOOL];
diff --git a/src/cmd/gc/walk.c b/src/cmd/gc/walk.c
index 1cb2551..ff9b362 100644
--- a/src/cmd/gc/walk.c
+++ b/src/cmd/gc/walk.c
@@ -5,8 +5,11 @@
 #include	<u.h>
 #include	<libc.h>
 #include	"go.h"
+#include	"../ld/textflag.h"
 
-static	Node*	walkprint(Node*, NodeList**, int);
+static	Node*	walkprint(Node*, NodeList**);
+static	Node*	writebarrierfn(char*, Type*, Type*);
+static	Node*	applywritebarrier(Node*, NodeList**);
 static	Node*	mapfn(char*, Type*);
 static	Node*	mapfndel(char*, Type*);
 static	Node*	ascompatee1(int, Node*, Node*, NodeList**);
@@ -29,6 +32,7 @@ static	void	walkmul(Node**, NodeList**);
 static	void	walkdiv(Node**, NodeList**);
 static	int	bounded(Node*, int64);
 static	Mpint	mpzero;
+static	void	walkprintfunc(Node**, NodeList**);
 
 void
 walk(Node *fn)
@@ -134,6 +138,8 @@ walkstmt(Node **np)
 	n = *np;
 	if(n == N)
 		return;
+	if(n->dodata == 2) // don't walk, generated by anylit.
+		return;
 
 	setlineno(n);
 
@@ -221,8 +227,7 @@ walkstmt(Node **np)
 		switch(n->left->op) {
 		case OPRINT:
 		case OPRINTN:
-			walkexprlist(n->left->list, &n->ninit);
-			n->left = walkprint(n->left, &n->ninit, 1);
+			walkprintfunc(&n->left, &n->ninit);
 			break;
 		case OCOPY:
 			n->left = copyany(n->left, &n->ninit, 1);
@@ -255,8 +260,7 @@ walkstmt(Node **np)
 		switch(n->left->op) {
 		case OPRINT:
 		case OPRINTN:
-			walkexprlist(n->left->list, &n->ninit);
-			n->left = walkprint(n->left, &n->ninit, 1);
+			walkprintfunc(&n->left, &n->ninit);
 			break;
 		case OCOPY:
 			n->left = copyany(n->left, &n->ninit, 1);
@@ -538,15 +542,15 @@ walkexpr(Node **np, NodeList **init)
 	case OPRINT:
 	case OPRINTN:
 		walkexprlist(n->list, init);
-		n = walkprint(n, init, 0);
+		n = walkprint(n, init);
 		goto ret;
 
 	case OPANIC:
-		n = mkcall("panic", T, init, n->left);
+		n = mkcall("gopanic", T, init, n->left);
 		goto ret;
 
 	case ORECOVER:
-		n = mkcall("recover", n->type, init, nod(OADDR, nodfp, N));
+		n = mkcall("gorecover", n->type, init, nod(OADDR, nodfp, N));
 		goto ret;
 
 	case OLITERAL:
@@ -609,7 +613,7 @@ walkexpr(Node **np, NodeList **init)
 		if(oaslit(n, init))
 			goto ret;
 
-		if(n->right == N)
+		if(n->right == N || iszero(n->right) && !flag_race)
 			goto ret;
 
 		switch(n->right->op) {
@@ -632,6 +636,7 @@ walkexpr(Node **np, NodeList **init)
 			r = convas(nod(OAS, n->left, n->right), init);
 			r->dodata = n->dodata;
 			n = r;
+			n = applywritebarrier(n, init);
 		}
 
 		goto ret;
@@ -643,6 +648,8 @@ walkexpr(Node **np, NodeList **init)
 		walkexprlistsafe(n->rlist, init);
 		ll = ascompatee(OAS, n->list, n->rlist, init);
 		ll = reorder3(ll);
+		for(lr = ll; lr != nil; lr = lr->next)
+			lr->n = applywritebarrier(lr->n, init);
 		n = liststmt(ll);
 		goto ret;
 
@@ -655,6 +662,8 @@ walkexpr(Node **np, NodeList **init)
 		walkexpr(&r, init);
 
 		ll = ascompatet(n->op, n->list, &r->type, 0, init);
+		for(lr = ll; lr != nil; lr = lr->next)
+			lr->n = applywritebarrier(lr->n, init);
 		n = liststmt(concat(list1(r), ll));
 		goto ret;
 
@@ -672,7 +681,7 @@ walkexpr(Node **np, NodeList **init)
 			n1 = nod(OADDR, n->list->n, N);
 		n1->etype = 1; // addr does not escape
 		fn = chanfn("chanrecv2", 2, r->left->type);
-		r = mkcall1(fn, types[TBOOL], init, typename(r->left->type), r->left, n1);
+		r = mkcall1(fn, n->list->next->n->type, init, typename(r->left->type), r->left, n1);
 		n = nod(OAS, n->list->next->n, r);
 		typecheck(&n, Etop);
 		goto ret;
@@ -687,7 +696,7 @@ walkexpr(Node **np, NodeList **init)
 		walkexpr(&r->right, init);
 		t = r->left->type;
 		p = nil;
-		if(t->type->width <= 128) { // Check ../../pkg/runtime/hashmap.c:MAXVALUESIZE before changing.
+		if(t->type->width <= 128) { // Check ../../runtime/hashmap.c:MAXVALUESIZE before changing.
 			switch(simsimtype(t->down)) {
 			case TINT32:
 			case TUINT32:
@@ -722,6 +731,12 @@ walkexpr(Node **np, NodeList **init)
 		var->typecheck = 1;
 		fn = mapfn(p, t);
 		r = mkcall1(fn, getoutargx(fn->type), init, typename(t), r->left, key);
+
+		// mapaccess2* returns a typed bool, but due to spec changes,
+		// the boolean result of i.(T) is now untyped so we make it the
+		// same type as the variable on the lhs.
+		if(!isblank(n->list->next->n))
+			r->type->type->down->type = n->list->next->n->type;
 		n->rlist = list1(r);
 		n->op = OAS2FUNC;
 		n->list->n = var;
@@ -769,6 +784,12 @@ walkexpr(Node **np, NodeList **init)
 			*p = '\0';
 			
 			fn = syslook(buf, 1);
+
+			// runtime.assert(E|I)2TOK returns a typed bool, but due
+			// to spec changes, the boolean result of i.(T) is now untyped
+			// so we make it the same type as the variable on the lhs.
+			if(!isblank(n->list->next->n))
+				fn->type->type->down->type->type = n->list->next->n->type;
 			ll = list1(typename(r->type));
 			ll = list(ll, r->left);
 			argtype(fn, r->left->type);
@@ -821,9 +842,7 @@ walkexpr(Node **np, NodeList **init)
 		walkexpr(&n->left, init);
 
 		// Optimize convT2E as a two-word copy when T is uintptr-shaped.
-		if(!isinter(n->left->type) && isnilinter(n->type) &&
-		   (n->left->type->width == widthptr) &&
-		   isint[simsimtype(n->left->type)]) {
+		if(isnilinter(n->type) && isdirectiface(n->left->type) && n->left->type->width == widthptr && isint[simsimtype(n->left->type)]) {
 			l = nod(OEFACE, typename(n->left->type), n->left);
 			l->type = n->type;
 			l->typecheck = n->typecheck;
@@ -865,14 +884,13 @@ walkexpr(Node **np, NodeList **init)
 				l->class = PEXTERN;
 				l->xoffset = 0;
 				sym->def = l;
-				ggloblsym(sym, widthptr, 1, 0);
+				ggloblsym(sym, widthptr, DUPOK|NOPTR);
 			}
 			l = nod(OADDR, sym->def, N);
 			l->addable = 1;
 			ll = list(ll, l);
 
-			if(n->left->type->width == widthptr &&
-		   	   isint[simsimtype(n->left->type)]) {
+			if(isdirectiface(n->left->type) && n->left->type->width == widthptr && isint[simsimtype(n->left->type)]) {
 				/* For pointer types, we can make a special form of optimization
 				 *
 				 * These statements are put onto the expression init list:
@@ -1073,7 +1091,7 @@ walkexpr(Node **np, NodeList **init)
 
 		t = n->left->type;
 		p = nil;
-		if(t->type->width <= 128) {  // Check ../../pkg/runtime/hashmap.c:MAXVALUESIZE before changing.
+		if(t->type->width <= 128) {  // Check ../../runtime/hashmap.c:MAXVALUESIZE before changing.
 			switch(simsimtype(t->down)) {
 			case TINT32:
 			case TUINT32:
@@ -1371,7 +1389,6 @@ walkexpr(Node **np, NodeList **init)
 	case OMAPLIT:
 	case OSTRUCTLIT:
 	case OPTRLIT:
-		// XXX TODO do we need to clear var?
 		var = temp(n->type);
 		anylit(0, n, var, init);
 		n = var;
@@ -1471,8 +1488,13 @@ ascompatee(int op, NodeList *nl, NodeList *nr, NodeList **init)
 static int
 fncall(Node *l, Type *rt)
 {
+	Node r;
+
 	if(l->ullman >= UINF || l->op == OINDEXMAP)
 		return 1;
+	memset(&r, 0, sizeof r);
+	if(needwritebarrier(l, &r))
+		return 1;
 	if(eqtype(l->type, rt))
 		return 0;
 	return 1;
@@ -1523,8 +1545,10 @@ ascompatet(int op, NodeList *nl, Type **nr, int fp, NodeList **init)
 		a = nod(OAS, l, nodarg(r, fp));
 		a = convas(a, init);
 		ullmancalc(a);
-		if(a->ullman >= UINF)
+		if(a->ullman >= UINF) {
+			dump("ascompatet ucount", a);
 			ucount++;
+		}
 		nn = list(nn, a);
 		r = structnext(&saver);
 	}
@@ -1732,7 +1756,7 @@ ret:
 
 // generate code for print
 static Node*
-walkprint(Node *nn, NodeList **init, int defer)
+walkprint(Node *nn, NodeList **init)
 {
 	Node *r;
 	Node *n;
@@ -1740,31 +1764,17 @@ walkprint(Node *nn, NodeList **init, int defer)
 	Node *on;
 	Type *t;
 	int notfirst, et, op;
-	NodeList *calls, *intypes, *args;
-	Fmt fmt;
+	NodeList *calls;
 
 	on = nil;
 	op = nn->op;
 	all = nn->list;
 	calls = nil;
 	notfirst = 0;
-	intypes = nil;
-	args = nil;
-
-	memset(&fmt, 0, sizeof fmt);
-	if(defer) {
-		// defer print turns into defer printf with format string
-		fmtstrinit(&fmt);
-		intypes = list(intypes, nod(ODCLFIELD, N, typenod(types[TSTRING])));
-		args = list1(nod(OXXX, N, N));
-	}
 
 	for(l=all; l; l=l->next) {
 		if(notfirst) {
-			if(defer)
-				fmtprint(&fmt, " ");
-			else
-				calls = list(calls, mkcall("printsp", T, init));
+			calls = list(calls, mkcall("printsp", T, init));
 		}
 		notfirst = op == OPRINTN;
 
@@ -1792,119 +1802,63 @@ walkprint(Node *nn, NodeList **init, int defer)
 		t = n->type;
 		et = n->type->etype;
 		if(isinter(n->type)) {
-			if(defer) {
-				if(isnilinter(n->type))
-					fmtprint(&fmt, "%%e");
-				else
-					fmtprint(&fmt, "%%i");
-			} else {
-				if(isnilinter(n->type))
-					on = syslook("printeface", 1);
-				else
-					on = syslook("printiface", 1);
-				argtype(on, n->type);		// any-1
-			}
+			if(isnilinter(n->type))
+				on = syslook("printeface", 1);
+			else
+				on = syslook("printiface", 1);
+			argtype(on, n->type);		// any-1
 		} else if(isptr[et] || et == TCHAN || et == TMAP || et == TFUNC || et == TUNSAFEPTR) {
-			if(defer) {
-				fmtprint(&fmt, "%%p");
-			} else {
-				on = syslook("printpointer", 1);
-				argtype(on, n->type);	// any-1
-			}
+			on = syslook("printpointer", 1);
+			argtype(on, n->type);	// any-1
 		} else if(isslice(n->type)) {
-			if(defer) {
-				fmtprint(&fmt, "%%a");
-			} else {
-				on = syslook("printslice", 1);
-				argtype(on, n->type);	// any-1
-			}
+			on = syslook("printslice", 1);
+			argtype(on, n->type);	// any-1
 		} else if(isint[et]) {
-			if(defer) {
-				if(et == TUINT64)
-					fmtprint(&fmt, "%%U");
-				else {
-					fmtprint(&fmt, "%%D");
-					t = types[TINT64];
-				}
-			} else {
-				if(et == TUINT64)
-					on = syslook("printuint", 0);
+			if(et == TUINT64) {
+				if((t->sym->pkg == runtimepkg || compiling_runtime) && strcmp(t->sym->name, "hex") == 0)
+					on = syslook("printhex", 0);
 				else
-					on = syslook("printint", 0);
-			}
-		} else if(isfloat[et]) {
-			if(defer) {
-				fmtprint(&fmt, "%%f");
-				t = types[TFLOAT64];
+					on = syslook("printuint", 0);
 			} else
-				on = syslook("printfloat", 0);
+				on = syslook("printint", 0);
+		} else if(isfloat[et]) {
+			on = syslook("printfloat", 0);
 		} else if(iscomplex[et]) {
-			if(defer) {
-				fmtprint(&fmt, "%%C");
-				t = types[TCOMPLEX128];
-			} else
-				on = syslook("printcomplex", 0);
+			on = syslook("printcomplex", 0);
 		} else if(et == TBOOL) {
-			if(defer)
-				fmtprint(&fmt, "%%t");
-			else
-				on = syslook("printbool", 0);
+			on = syslook("printbool", 0);
 		} else if(et == TSTRING) {
-			if(defer)
-				fmtprint(&fmt, "%%S");
-			else
-				on = syslook("printstring", 0);
+			on = syslook("printstring", 0);
 		} else {
 			badtype(OPRINT, n->type, T);
 			continue;
 		}
 
-		if(!defer) {
-			t = *getinarg(on->type);
-			if(t != nil)
-				t = t->type;
-			if(t != nil)
-				t = t->type;
-		}
+		t = *getinarg(on->type);
+		if(t != nil)
+			t = t->type;
+		if(t != nil)
+			t = t->type;
 
 		if(!eqtype(t, n->type)) {
 			n = nod(OCONV, n, N);
 			n->type = t;
 		}
 
-		if(defer) {
-			intypes = list(intypes, nod(ODCLFIELD, N, typenod(t)));
-			args = list(args, n);
-		} else {
-			r = nod(OCALL, on, N);
-			r->list = list1(n);
-			calls = list(calls, r);
-		}
+		r = nod(OCALL, on, N);
+		r->list = list1(n);
+		calls = list(calls, r);
 	}
 
-	if(defer) {
-		if(op == OPRINTN)
-			fmtprint(&fmt, "\n");
-		on = syslook("goprintf", 1);
-		on->type = functype(nil, intypes, nil);
-		args->n = nod(OLITERAL, N, N);
-		args->n->val.ctype = CTSTR;
-		args->n->val.u.sval = strlit(fmtstrflush(&fmt));
-		r = nod(OCALL, on, N);
-		r->list = args;
-		typecheck(&r, Etop);
-		walkexpr(&r, init);
-	} else {
-		if(op == OPRINTN)
-			calls = list(calls, mkcall("printnl", T, nil));
-		typechecklist(calls, Etop);
-		walkexprlist(calls, init);
+	if(op == OPRINTN)
+		calls = list(calls, mkcall("printnl", T, nil));
+	typechecklist(calls, Etop);
+	walkexprlist(calls, init);
 
-		r = nod(OEMPTY, N, N);
-		typecheck(&r, Etop);
-		walkexpr(&r, init);
-		r->ninit = calls;
-	}
+	r = nod(OEMPTY, N, N);
+	typecheck(&r, Etop);
+	walkexpr(&r, init);
+	r->ninit = calls;
 	return r;
 }
 
@@ -1914,11 +1868,166 @@ callnew(Type *t)
 	Node *fn;
 
 	dowidth(t);
-	fn = syslook("new", 1);
+	fn = syslook("newobject", 1);
 	argtype(fn, t);
 	return mkcall1(fn, ptrto(t), nil, typename(t));
 }
 
+static int
+isstack(Node *n)
+{
+	while(n->op == ODOT || n->op == OPAREN || n->op == OCONVNOP || n->op == OINDEX && isfixedarray(n->left->type))
+		n = n->left;
+	
+	switch(n->op) {
+	case OINDREG:
+		// OINDREG only ends up in walk if it's indirect of SP.
+		return 1;
+
+	case ONAME:
+		switch(n->class) {
+		case PAUTO:
+		case PPARAM:
+		case PPARAMOUT:
+			return 1;
+		}
+		break;
+	}
+	
+	return 0;
+}
+
+static int
+isglobal(Node *n)
+{
+	while(n->op == ODOT || n->op == OPAREN || n->op == OCONVNOP || n->op == OINDEX && isfixedarray(n->left->type))
+		n = n->left;
+	
+	switch(n->op) {
+	case ONAME:
+		switch(n->class) {
+		case PEXTERN:
+			return 1;
+		}
+		break;
+	}
+	
+	return 0;
+}
+
+// Do we need a write barrier for the assignment l = r?
+int
+needwritebarrier(Node *l, Node *r)
+{
+	if(!use_writebarrier)
+		return 0;
+
+	if(l == N || isblank(l))
+		return 0;
+
+	// No write barrier for write of non-pointers.
+	dowidth(l->type);
+	if(!haspointers(l->type))
+		return 0;
+
+	// No write barrier for write to stack.
+	if(isstack(l))
+		return 0;
+
+	// No write barrier for implicit or explicit zeroing.
+	if(r == N || iszero(r))
+		return 0;
+
+	// No write barrier for initialization to constant.
+	if(r->op == OLITERAL)
+		return 0;
+
+	// No write barrier for storing static (read-only) data.
+	if(r->op == ONAME && strncmp(r->sym->name, "statictmp_", 10) == 0)
+		return 0;
+
+	// No write barrier for storing address of stack values,
+	// which are guaranteed only to be written to the stack.
+	if(r->op == OADDR && isstack(r->left))
+		return 0;
+
+	// No write barrier for storing address of global, which
+	// is live no matter what.
+	if(r->op == OADDR && isglobal(r->left))
+		return 0;
+
+	// No write barrier for reslice: x = x[0:y] or x = append(x, ...).
+	// Both are compiled to modify x directly.
+	// In the case of append, a write barrier may still be needed
+	// if the underlying array grows, but the append code can
+	// generate the write barrier directly in that case.
+	// (It does not yet, but the cost of the write barrier will be
+	// small compared to the cost of the allocation.)
+	if(r->reslice) {
+		switch(r->op) {
+		case OSLICE:
+		case OSLICE3:
+		case OSLICESTR:
+		case OAPPEND:
+			break;
+		default:
+			dump("bad reslice-l", l);
+			dump("bad reslice-r", r);
+			break;
+		}
+		return 0;
+	}
+
+	// Otherwise, be conservative and use write barrier.
+	return 1;
+}
+
+// TODO(rsc): Perhaps componentgen should run before this.
+static Node*
+applywritebarrier(Node *n, NodeList **init)
+{
+	Node *l, *r;
+	Type *t;
+
+	if(n->left && n->right && needwritebarrier(n->left, n->right)) {
+		t = n->left->type;
+		l = nod(OADDR, n->left, N);
+		l->etype = 1; // addr does not escape
+		if(t->width == widthptr) {
+			n = mkcall1(writebarrierfn("writebarrierptr", t, n->right->type), T, init,
+				l, n->right);
+		} else if(t->etype == TSTRING) {
+			n = mkcall1(writebarrierfn("writebarrierstring", t, n->right->type), T, init,
+				l, n->right);
+		} else if(isslice(t)) {
+			n = mkcall1(writebarrierfn("writebarrierslice", t, n->right->type), T, init,
+				l, n->right);
+		} else if(isinter(t)) {
+			n = mkcall1(writebarrierfn("writebarrieriface", t, n->right->type), T, init,
+				l, n->right);
+		} else if(t->width == 2*widthptr) {
+			n = mkcall1(writebarrierfn("writebarrierfat2", t, n->right->type), T, init,
+				l, nodnil(), n->right);
+		} else if(t->width == 3*widthptr) {
+			n = mkcall1(writebarrierfn("writebarrierfat3", t, n->right->type), T, init,
+				l, nodnil(), n->right);
+		} else if(t->width == 4*widthptr) {
+			n = mkcall1(writebarrierfn("writebarrierfat4", t, n->right->type), T, init,
+				l, nodnil(), n->right);
+		} else {
+			r = n->right;
+			while(r->op == OCONVNOP)
+				r = r->left;
+			r = nod(OADDR, r, N);
+			r->etype = 1; // addr does not escape
+			//warnl(n->lineno, "writebarrierfat %T %N", t, r);
+			n = mkcall1(writebarrierfn("writebarrierfat", t, r->left->type), T, init,
+				typename(t), l, r);
+		}
+	}
+	return n;
+}
+
 static Node*
 convas(Node *n, NodeList **init)
 {
@@ -1958,11 +2067,10 @@ convas(Node *n, NodeList **init)
 		goto out;
 	}
 
-	if(eqtype(lt, rt))
-		goto out;
-
-	n->right = assignconv(n->right, lt, "assignment");
-	walkexpr(&n->right, init);
+	if(!eqtype(lt, rt)) {
+		n->right = assignconv(n->right, lt, "assignment");
+		walkexpr(&n->right, init);
+	}
 
 out:
 	ullmancalc(n);
@@ -2355,6 +2463,8 @@ paramstoheap(Type **argin, int out)
 			continue;
 
 		// generate allocation & copying code
+		if(compiling_runtime)
+			yyerror("%N escapes to heap, not allowed in runtime.", v);
 		if(v->alloc == nil)
 			v->alloc = callnew(v->type);
 		nn = list(nn, nod(OAS, v->heapaddr, v->alloc));
@@ -2512,6 +2622,17 @@ mapfndel(char *name, Type *t)
 }
 
 static Node*
+writebarrierfn(char *name, Type *l, Type *r)
+{
+	Node *fn;
+
+	fn = syslook(name, 1);
+	argtype(fn, l);
+	argtype(fn, r);
+	return fn;
+}
+
+static Node*
 addstr(Node *n, NodeList **init)
 {
 	Node *r, *cat, *slice;
@@ -2620,7 +2741,7 @@ appendslice(Node *n, NodeList **init)
 		if(l2->type->etype == TSTRING)
 			fn = syslook("slicestringcopy", 1);
 		else
-			fn = syslook("copy", 1);
+			fn = syslook("slicecopy", 1);
 		argtype(fn, l1->type);
 		argtype(fn, l2->type);
 		nt = mkcall1(fn, types[TINT], &l,
@@ -2758,7 +2879,7 @@ copyany(Node *n, NodeList **init, int runtimecall)
 		if(n->right->type->etype == TSTRING)
 			fn = syslook("slicestringcopy", 1);
 		else
-			fn = syslook("copy", 1);
+			fn = syslook("slicecopy", 1);
 		argtype(fn, n->left->type);
 		argtype(fn, n->right->type);
 		return mkcall1(fn, n->type, init,
@@ -2863,14 +2984,14 @@ sliceany(Node* n, NodeList **init)
 			lb = N;
 	}
 
-	// dynamic checks convert all bounds to unsigned to save us the bound < 0 comparison
-	// generate
-	//     if hb > bound || lb > hb { panicslice() }
+	// Checking src[lb:hb:cb] or src[lb:hb].
+	// if chk0 || chk1 || chk2 { panicslice() }
 	chk = N;
-	chk0 = N;
-	chk1 = N;
-	chk2 = N;
+	chk0 = N; // cap(src) < cb
+	chk1 = N; // cb < hb for src[lb:hb:cb]; cap(src) < hb for src[lb:hb]
+	chk2 = N; // hb < lb
 
+	// All comparisons are unsigned to avoid testing < 0.
 	bt = types[simtype[TUINT]];
 	if(cb != N && cb->type->width > 4)
 		bt = types[TUINT64];
@@ -3010,10 +3131,10 @@ eqfor(Type *t)
 	n = newname(sym);
 	n->class = PFUNC;
 	ntype = nod(OTFUNC, N, N);
-	ntype->list = list(ntype->list, nod(ODCLFIELD, N, typenod(ptrto(types[TBOOL]))));
-	ntype->list = list(ntype->list, nod(ODCLFIELD, N, typenod(types[TUINTPTR])));
 	ntype->list = list(ntype->list, nod(ODCLFIELD, N, typenod(ptrto(t))));
 	ntype->list = list(ntype->list, nod(ODCLFIELD, N, typenod(ptrto(t))));
+	ntype->list = list(ntype->list, nod(ODCLFIELD, N, typenod(types[TUINTPTR])));
+	ntype->rlist = list(ntype->rlist, nod(ODCLFIELD, N, typenod(types[TBOOL])));
 	typecheck(&ntype, Etype);
 	n->type = ntype->type;
 	return n;
@@ -3034,10 +3155,9 @@ countfield(Type *t)
 static void
 walkcompare(Node **np, NodeList **init)
 {
-	Node *n, *l, *r, *fn, *call, *a, *li, *ri, *expr;
+	Node *n, *l, *r, *call, *a, *li, *ri, *expr, *cmpl, *cmpr;
 	int andor, i;
 	Type *t, *t1;
-	static Node *tempbool;
 	
 	n = *np;
 	
@@ -3055,17 +3175,25 @@ walkcompare(Node **np, NodeList **init)
 		break;
 	}
 	
-	if(!islvalue(n->left) || !islvalue(n->right))
-		goto hard;
+	cmpl = n->left;
+	while(cmpl != N && cmpl->op == OCONVNOP)
+		cmpl = cmpl->left;
+	cmpr = n->right;
+	while(cmpr != N && cmpr->op == OCONVNOP)
+		cmpr = cmpr->left;
+	
+	if(!islvalue(cmpl) || !islvalue(cmpr)) {
+		fatal("arguments of comparison must be lvalues - %N %N", cmpl, cmpr);
+	}
 
 	l = temp(ptrto(t));
-	a = nod(OAS, l, nod(OADDR, n->left, N));
+	a = nod(OAS, l, nod(OADDR, cmpl, N));
 	a->right->etype = 1;  // addr does not escape
 	typecheck(&a, Etop);
 	*init = list(*init, a);
 
 	r = temp(ptrto(t));
-	a = nod(OAS, r, nod(OADDR, n->right, N));
+	a = nod(OAS, r, nod(OADDR, cmpr, N));
 	a->right->etype = 1;  // addr does not escape
 	typecheck(&a, Etop);
 	*init = list(*init, a);
@@ -3115,57 +3243,16 @@ walkcompare(Node **np, NodeList **init)
 		goto ret;
 	}
 
-	// Chose not to inline, but still have addresses.
-	// Call equality function directly.
-	// The equality function requires a bool pointer for
-	// storing its address, because it has to be callable
-	// from C, and C can't access an ordinary Go return value.
-	// To avoid creating many temporaries, cache one per function.
-	if(tempbool == N || tempbool->curfn != curfn)
-		tempbool = temp(types[TBOOL]);
-	
+	// Chose not to inline.  Call equality function directly.
 	call = nod(OCALL, eqfor(t), N);
-	a = nod(OADDR, tempbool, N);
-	a->etype = 1;  // does not escape
-	call->list = list(call->list, a);
-	call->list = list(call->list, nodintconst(t->width));
 	call->list = list(call->list, l);
 	call->list = list(call->list, r);
-	typecheck(&call, Etop);
-	walkstmt(&call);
-	*init = list(*init, call);
-
-	// tempbool cannot be used directly as multiple comparison
-	// expressions may exist in the same statement. Create another
-	// temporary to hold the value (its address is not taken so it can
-	// be optimized away).
-	r = temp(types[TBOOL]);
-	a = nod(OAS, r, tempbool);
-	typecheck(&a, Etop);
-	walkstmt(&a);
-	*init = list(*init, a);
-
+	call->list = list(call->list, nodintconst(t->width));
+	r = call;
 	if(n->op != OEQ)
 		r = nod(ONOT, r, N);
 	goto ret;
 
-hard:
-	// Cannot take address of one or both of the operands.
-	// Instead, pass directly to runtime helper function.
-	// Easier on the stack than passing the address
-	// of temporary variables, because we are better at reusing
-	// the argument space than temporary variable space.
-	fn = syslook("equal", 1);
-	l = n->left;
-	r = n->right;
-	argtype(fn, n->left->type);
-	argtype(fn, n->left->type);
-	r = mkcall1(fn, n->type, init, typename(n->left->type), l, r);
-	if(n->op == ONE) {
-		r = nod(ONOT, r, N);
-	}
-	goto ret;
-
 ret:
 	typecheck(&r, Erv);
 	walkexpr(&r, init);
@@ -3780,3 +3867,71 @@ candiscard(Node *n)
 	
 	return 1;
 }
+
+// rewrite
+//	print(x, y, z)
+// into
+//	func(a1, a2, a3) {
+//		print(a1, a2, a3)
+//	}(x, y, z)
+// and same for println.
+static void
+walkprintfunc(Node **np, NodeList **init)
+{
+	Node *n;
+	Node *a, *fn, *t, *oldfn;
+	NodeList *l, *printargs;
+	int num;
+	char buf[100];
+	static int prgen;
+	
+	n = *np;
+
+	if(n->ninit != nil) {
+		walkstmtlist(n->ninit);
+		*init = concat(*init, n->ninit);
+		n->ninit = nil;
+	}
+
+	t = nod(OTFUNC, N, N);
+	num = 0;
+	printargs = nil;
+	for(l=n->list; l != nil; l=l->next) {
+		snprint(buf, sizeof buf, "a%d", num++);
+		a = nod(ODCLFIELD, newname(lookup(buf)), typenod(l->n->type));
+		t->list = list(t->list, a);
+		printargs = list(printargs, a->left);
+	}
+
+	fn = nod(ODCLFUNC, N, N);
+	snprint(buf, sizeof buf, "print·%d", ++prgen);
+	fn->nname = newname(lookup(buf));
+	fn->nname->defn = fn;
+	fn->nname->ntype = t;
+	declare(fn->nname, PFUNC);
+
+	oldfn = curfn;
+	curfn = nil;
+	funchdr(fn);
+	
+	a = nod(n->op, N, N);
+	a->list = printargs;
+	typecheck(&a, Etop);
+	walkstmt(&a);
+	
+	fn->nbody = list1(a);
+
+	funcbody(fn);
+	
+	typecheck(&fn, Etop);
+	typechecklist(fn->nbody, Etop);
+	xtop = list(xtop, fn);
+	curfn = oldfn;
+
+	a = nod(OCALL, N, N);
+	a->left = fn->nname;
+	a->list = n->list;
+	typecheck(&a, Etop);
+	walkexpr(&a, init);
+	*np = a;
+}
diff --git a/src/cmd/gc/y.tab.c b/src/cmd/gc/y.tab.c
index 08d8ecf..f464126 100644
--- a/src/cmd/gc/y.tab.c
+++ b/src/cmd/gc/y.tab.c
@@ -440,16 +440,16 @@ union yyalloc
 /* YYFINAL -- State number of the termination state.  */
 #define YYFINAL  4
 /* YYLAST -- Last index in YYTABLE.  */
-#define YYLAST   2270
+#define YYLAST   2201
 
 /* YYNTOKENS -- Number of terminals.  */
 #define YYNTOKENS  76
 /* YYNNTS -- Number of nonterminals.  */
 #define YYNNTS  142
 /* YYNRULES -- Number of rules.  */
-#define YYNRULES  351
+#define YYNRULES  352
 /* YYNRULES -- Number of states.  */
-#define YYNSTATES  667
+#define YYNSTATES  669
 
 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
 #define YYUNDEFTOK  2
@@ -506,35 +506,35 @@ static const yytype_uint16 yyprhs[] =
      129,   132,   137,   141,   146,   150,   152,   155,   157,   159,
      162,   164,   168,   172,   176,   179,   182,   186,   192,   198,
      201,   202,   207,   208,   212,   213,   216,   217,   222,   227,
-     232,   238,   240,   242,   245,   246,   250,   252,   256,   257,
-     258,   259,   268,   269,   275,   276,   279,   280,   283,   284,
-     285,   293,   294,   300,   302,   306,   310,   314,   318,   322,
-     326,   330,   334,   338,   342,   346,   350,   354,   358,   362,
-     366,   370,   374,   378,   382,   384,   387,   390,   393,   396,
-     399,   402,   405,   408,   412,   418,   425,   427,   429,   433,
-     439,   445,   450,   457,   466,   468,   474,   480,   486,   494,
-     496,   497,   501,   503,   508,   510,   515,   517,   521,   523,
-     525,   527,   529,   531,   533,   535,   536,   538,   540,   542,
-     544,   549,   554,   556,   558,   560,   563,   565,   567,   569,
-     571,   573,   577,   579,   581,   583,   586,   588,   590,   592,
-     594,   598,   600,   602,   604,   606,   608,   610,   612,   614,
-     616,   620,   625,   630,   633,   637,   643,   645,   647,   650,
-     654,   660,   664,   670,   674,   678,   684,   693,   699,   708,
-     714,   715,   719,   720,   722,   726,   728,   733,   736,   737,
-     741,   743,   747,   749,   753,   755,   759,   761,   765,   767,
-     771,   775,   778,   783,   787,   793,   799,   801,   805,   807,
-     810,   812,   816,   821,   823,   826,   829,   831,   833,   837,
-     838,   841,   842,   844,   846,   848,   850,   852,   854,   856,
-     858,   860,   861,   866,   868,   871,   874,   877,   880,   883,
-     886,   888,   892,   894,   898,   900,   904,   906,   910,   912,
-     916,   918,   920,   924,   928,   929,   932,   933,   935,   936,
-     938,   939,   941,   942,   944,   945,   947,   948,   950,   951,
-     953,   954,   956,   957,   959,   964,   969,   975,   982,   987,
-     992,   994,   996,   998,  1000,  1002,  1004,  1006,  1008,  1010,
-    1014,  1019,  1025,  1030,  1035,  1038,  1041,  1046,  1050,  1054,
-    1060,  1064,  1069,  1073,  1079,  1081,  1082,  1084,  1088,  1090,
-    1092,  1095,  1097,  1099,  1105,  1106,  1109,  1111,  1115,  1117,
-    1121,  1123
+     232,   235,   241,   243,   245,   248,   249,   253,   255,   259,
+     260,   261,   262,   271,   272,   278,   279,   282,   283,   286,
+     287,   288,   296,   297,   303,   305,   309,   313,   317,   321,
+     325,   329,   333,   337,   341,   345,   349,   353,   357,   361,
+     365,   369,   373,   377,   381,   385,   387,   390,   393,   396,
+     399,   402,   405,   408,   411,   415,   421,   428,   430,   432,
+     436,   442,   448,   453,   460,   469,   471,   477,   483,   489,
+     497,   499,   500,   504,   506,   511,   513,   518,   520,   524,
+     526,   528,   530,   532,   534,   536,   538,   539,   541,   543,
+     545,   547,   552,   557,   559,   561,   563,   566,   568,   570,
+     572,   574,   576,   580,   582,   584,   586,   589,   591,   593,
+     595,   597,   601,   603,   605,   607,   609,   611,   613,   615,
+     617,   619,   623,   628,   633,   636,   640,   646,   648,   650,
+     653,   657,   663,   667,   673,   677,   681,   687,   696,   702,
+     711,   717,   718,   722,   723,   725,   729,   731,   736,   739,
+     740,   744,   746,   750,   752,   756,   758,   762,   764,   768,
+     770,   774,   778,   781,   786,   790,   796,   802,   804,   808,
+     810,   813,   815,   819,   824,   826,   829,   832,   834,   836,
+     840,   841,   844,   845,   847,   849,   851,   853,   855,   857,
+     859,   861,   863,   864,   869,   871,   874,   877,   880,   883,
+     886,   889,   891,   895,   897,   901,   903,   907,   909,   913,
+     915,   919,   921,   923,   927,   931,   932,   935,   936,   938,
+     939,   941,   942,   944,   945,   947,   948,   950,   951,   953,
+     954,   956,   957,   959,   960,   962,   967,   972,   978,   985,
+     990,   995,   997,   999,  1001,  1003,  1005,  1007,  1009,  1011,
+    1013,  1017,  1022,  1028,  1033,  1038,  1041,  1044,  1049,  1053,
+    1057,  1063,  1067,  1072,  1076,  1082,  1084,  1085,  1087,  1091,
+    1093,  1095,  1098,  1100,  1102,  1108,  1109,  1112,  1114,  1118,
+    1120,  1124,  1126
 };
 
 /* YYRHS -- A `-1'-separated list of the rules' RHS.  */
@@ -563,96 +563,96 @@ static const yytype_int16 yyrhs[] =
       -1,    -1,    67,   101,   183,    68,    -1,    -1,    99,   103,
      183,    -1,    -1,   104,   102,    -1,    -1,    35,   106,   183,
       68,    -1,   186,    65,    26,   126,    -1,   186,     5,    26,
-     126,    -1,   194,    62,   194,    62,   194,    -1,   194,    -1,
-     107,    -1,   108,   105,    -1,    -1,    16,   111,   109,    -1,
-     194,    -1,   194,    62,   194,    -1,    -1,    -1,    -1,    20,
-     114,   112,   115,   105,   116,   119,   120,    -1,    -1,    14,
-      20,   118,   112,   105,    -1,    -1,   119,   117,    -1,    -1,
-      14,   100,    -1,    -1,    -1,    30,   122,   112,   123,    35,
-     104,    68,    -1,    -1,    28,   125,    35,   104,    68,    -1,
-     127,    -1,   126,    47,   126,    -1,   126,    33,   126,    -1,
-     126,    38,   126,    -1,   126,    46,   126,    -1,   126,    45,
-     126,    -1,   126,    43,   126,    -1,   126,    39,   126,    -1,
-     126,    40,   126,    -1,   126,    49,   126,    -1,   126,    50,
-     126,    -1,   126,    51,   126,    -1,   126,    52,   126,    -1,
-     126,    53,   126,    -1,   126,    54,   126,    -1,   126,    55,
-     126,    -1,   126,    56,   126,    -1,   126,    34,   126,    -1,
-     126,    44,   126,    -1,   126,    48,   126,    -1,   126,    36,
-     126,    -1,   134,    -1,    53,   127,    -1,    56,   127,    -1,
-      49,   127,    -1,    50,   127,    -1,    69,   127,    -1,    70,
-     127,    -1,    52,   127,    -1,    36,   127,    -1,   134,    59,
-      60,    -1,   134,    59,   187,   191,    60,    -1,   134,    59,
-     187,    11,   191,    60,    -1,     3,    -1,   143,    -1,   134,
-      63,   141,    -1,   134,    63,    59,   135,    60,    -1,   134,
-      63,    59,    31,    60,    -1,   134,    71,   126,    72,    -1,
-     134,    71,   192,    66,   192,    72,    -1,   134,    71,   192,
-      66,   192,    66,   192,    72,    -1,   128,    -1,   149,    59,
-     126,   191,    60,    -1,   150,   137,   130,   189,    68,    -1,
-     129,    67,   130,   189,    68,    -1,    59,   135,    60,    67,
-     130,   189,    68,    -1,   165,    -1,    -1,   126,    66,   133,
-      -1,   126,    -1,    67,   130,   189,    68,    -1,   126,    -1,
-      67,   130,   189,    68,    -1,   129,    -1,    59,   135,    60,
-      -1,   126,    -1,   147,    -1,   146,    -1,    35,    -1,    67,
-      -1,   141,    -1,   141,    -1,    -1,   138,    -1,    24,    -1,
-     142,    -1,    73,    -1,    74,     3,    63,    24,    -1,    74,
-       3,    63,    73,    -1,   141,    -1,   138,    -1,    11,    -1,
-      11,   146,    -1,   155,    -1,   161,    -1,   153,    -1,   154,
-      -1,   152,    -1,    59,   146,    60,    -1,   155,    -1,   161,
-      -1,   153,    -1,    53,   147,    -1,   161,    -1,   153,    -1,
-     154,    -1,   152,    -1,    59,   146,    60,    -1,   161,    -1,
-     153,    -1,   153,    -1,   155,    -1,   161,    -1,   153,    -1,
-     154,    -1,   152,    -1,   143,    -1,   143,    63,   141,    -1,
-      71,   192,    72,   146,    -1,    71,    11,    72,   146,    -1,
-       8,   148,    -1,     8,    36,   146,    -1,    23,    71,   146,
-      72,   146,    -1,   156,    -1,   157,    -1,    53,   146,    -1,
-      36,     8,   146,    -1,    29,   137,   170,   190,    68,    -1,
-      29,   137,    68,    -1,    22,   137,   171,   190,    68,    -1,
-      22,   137,    68,    -1,    17,   159,   162,    -1,   141,    59,
-     179,    60,   163,    -1,    59,   179,    60,   141,    59,   179,
-      60,   163,    -1,   200,    59,   195,    60,   210,    -1,    59,
-     215,    60,   141,    59,   195,    60,   210,    -1,    17,    59,
-     179,    60,   163,    -1,    -1,    67,   183,    68,    -1,    -1,
-     151,    -1,    59,   179,    60,    -1,   161,    -1,   164,   137,
-     183,    68,    -1,   164,     1,    -1,    -1,   166,    90,    62,
-      -1,    93,    -1,   167,    62,    93,    -1,    95,    -1,   168,
-      62,    95,    -1,    97,    -1,   169,    62,    97,    -1,   172,
-      -1,   170,    62,   172,    -1,   175,    -1,   171,    62,   175,
-      -1,   184,   146,   198,    -1,   174,   198,    -1,    59,   174,
-      60,   198,    -1,    53,   174,   198,    -1,    59,    53,   174,
-      60,   198,    -1,    53,    59,   174,    60,   198,    -1,    24,
-      -1,    24,    63,   141,    -1,   173,    -1,   138,   176,    -1,
-     173,    -1,    59,   173,    60,    -1,    59,   179,    60,   163,
-      -1,   136,    -1,   141,   136,    -1,   141,   145,    -1,   145,
-      -1,   177,    -1,   178,    75,   177,    -1,    -1,   178,   191,
-      -1,    -1,   100,    -1,    91,    -1,   181,    -1,     1,    -1,
-      98,    -1,   110,    -1,   121,    -1,   124,    -1,   113,    -1,
-      -1,   144,    66,   182,   180,    -1,    15,    -1,     6,   140,
-      -1,    10,   140,    -1,    18,   128,    -1,    13,   128,    -1,
-      19,   138,    -1,    27,   193,    -1,   180,    -1,   183,    62,
-     180,    -1,   138,    -1,   184,    75,   138,    -1,   139,    -1,
-     185,    75,   139,    -1,   126,    -1,   186,    75,   126,    -1,
-     135,    -1,   187,    75,   135,    -1,   131,    -1,   132,    -1,
-     188,    75,   131,    -1,   188,    75,   132,    -1,    -1,   188,
-     191,    -1,    -1,    62,    -1,    -1,    75,    -1,    -1,   126,
-      -1,    -1,   186,    -1,    -1,    98,    -1,    -1,   215,    -1,
-      -1,   216,    -1,    -1,   217,    -1,    -1,     3,    -1,    21,
-      24,     3,    62,    -1,    32,   200,   202,    62,    -1,     9,
-     200,    65,   213,    62,    -1,     9,   200,   202,    65,   213,
-      62,    -1,    31,   201,   202,    62,    -1,    17,   160,   162,
-      62,    -1,   142,    -1,   200,    -1,   204,    -1,   205,    -1,
-     206,    -1,   204,    -1,   206,    -1,   142,    -1,    24,    -1,
-      71,    72,   202,    -1,    71,     3,    72,   202,    -1,    23,
-      71,   202,    72,   202,    -1,    29,    67,   196,    68,    -1,
-      22,    67,   197,    68,    -1,    53,   202,    -1,     8,   203,
-      -1,     8,    59,   205,    60,    -1,     8,    36,   202,    -1,
-      36,     8,   202,    -1,    17,    59,   195,    60,   210,    -1,
-     141,   202,   198,    -1,   141,    11,   202,   198,    -1,   141,
-     202,   198,    -1,   141,    59,   195,    60,   210,    -1,   202,
-      -1,    -1,   211,    -1,    59,   195,    60,    -1,   202,    -1,
-       3,    -1,    50,     3,    -1,   141,    -1,   212,    -1,    59,
-     212,    49,   212,    60,    -1,    -1,   214,   199,    -1,   207,
-      -1,   215,    75,   207,    -1,   208,    -1,   216,    62,   208,
-      -1,   209,    -1,   217,    62,   209,    -1
+     126,    -1,    26,   126,    -1,   194,    62,   194,    62,   194,
+      -1,   194,    -1,   107,    -1,   108,   105,    -1,    -1,    16,
+     111,   109,    -1,   194,    -1,   194,    62,   194,    -1,    -1,
+      -1,    -1,    20,   114,   112,   115,   105,   116,   119,   120,
+      -1,    -1,    14,    20,   118,   112,   105,    -1,    -1,   119,
+     117,    -1,    -1,    14,   100,    -1,    -1,    -1,    30,   122,
+     112,   123,    35,   104,    68,    -1,    -1,    28,   125,    35,
+     104,    68,    -1,   127,    -1,   126,    47,   126,    -1,   126,
+      33,   126,    -1,   126,    38,   126,    -1,   126,    46,   126,
+      -1,   126,    45,   126,    -1,   126,    43,   126,    -1,   126,
+      39,   126,    -1,   126,    40,   126,    -1,   126,    49,   126,
+      -1,   126,    50,   126,    -1,   126,    51,   126,    -1,   126,
+      52,   126,    -1,   126,    53,   126,    -1,   126,    54,   126,
+      -1,   126,    55,   126,    -1,   126,    56,   126,    -1,   126,
+      34,   126,    -1,   126,    44,   126,    -1,   126,    48,   126,
+      -1,   126,    36,   126,    -1,   134,    -1,    53,   127,    -1,
+      56,   127,    -1,    49,   127,    -1,    50,   127,    -1,    69,
+     127,    -1,    70,   127,    -1,    52,   127,    -1,    36,   127,
+      -1,   134,    59,    60,    -1,   134,    59,   187,   191,    60,
+      -1,   134,    59,   187,    11,   191,    60,    -1,     3,    -1,
+     143,    -1,   134,    63,   141,    -1,   134,    63,    59,   135,
+      60,    -1,   134,    63,    59,    31,    60,    -1,   134,    71,
+     126,    72,    -1,   134,    71,   192,    66,   192,    72,    -1,
+     134,    71,   192,    66,   192,    66,   192,    72,    -1,   128,
+      -1,   149,    59,   126,   191,    60,    -1,   150,   137,   130,
+     189,    68,    -1,   129,    67,   130,   189,    68,    -1,    59,
+     135,    60,    67,   130,   189,    68,    -1,   165,    -1,    -1,
+     126,    66,   133,    -1,   126,    -1,    67,   130,   189,    68,
+      -1,   126,    -1,    67,   130,   189,    68,    -1,   129,    -1,
+      59,   135,    60,    -1,   126,    -1,   147,    -1,   146,    -1,
+      35,    -1,    67,    -1,   141,    -1,   141,    -1,    -1,   138,
+      -1,    24,    -1,   142,    -1,    73,    -1,    74,     3,    63,
+      24,    -1,    74,     3,    63,    73,    -1,   141,    -1,   138,
+      -1,    11,    -1,    11,   146,    -1,   155,    -1,   161,    -1,
+     153,    -1,   154,    -1,   152,    -1,    59,   146,    60,    -1,
+     155,    -1,   161,    -1,   153,    -1,    53,   147,    -1,   161,
+      -1,   153,    -1,   154,    -1,   152,    -1,    59,   146,    60,
+      -1,   161,    -1,   153,    -1,   153,    -1,   155,    -1,   161,
+      -1,   153,    -1,   154,    -1,   152,    -1,   143,    -1,   143,
+      63,   141,    -1,    71,   192,    72,   146,    -1,    71,    11,
+      72,   146,    -1,     8,   148,    -1,     8,    36,   146,    -1,
+      23,    71,   146,    72,   146,    -1,   156,    -1,   157,    -1,
+      53,   146,    -1,    36,     8,   146,    -1,    29,   137,   170,
+     190,    68,    -1,    29,   137,    68,    -1,    22,   137,   171,
+     190,    68,    -1,    22,   137,    68,    -1,    17,   159,   162,
+      -1,   141,    59,   179,    60,   163,    -1,    59,   179,    60,
+     141,    59,   179,    60,   163,    -1,   200,    59,   195,    60,
+     210,    -1,    59,   215,    60,   141,    59,   195,    60,   210,
+      -1,    17,    59,   179,    60,   163,    -1,    -1,    67,   183,
+      68,    -1,    -1,   151,    -1,    59,   179,    60,    -1,   161,
+      -1,   164,   137,   183,    68,    -1,   164,     1,    -1,    -1,
+     166,    90,    62,    -1,    93,    -1,   167,    62,    93,    -1,
+      95,    -1,   168,    62,    95,    -1,    97,    -1,   169,    62,
+      97,    -1,   172,    -1,   170,    62,   172,    -1,   175,    -1,
+     171,    62,   175,    -1,   184,   146,   198,    -1,   174,   198,
+      -1,    59,   174,    60,   198,    -1,    53,   174,   198,    -1,
+      59,    53,   174,    60,   198,    -1,    53,    59,   174,    60,
+     198,    -1,    24,    -1,    24,    63,   141,    -1,   173,    -1,
+     138,   176,    -1,   173,    -1,    59,   173,    60,    -1,    59,
+     179,    60,   163,    -1,   136,    -1,   141,   136,    -1,   141,
+     145,    -1,   145,    -1,   177,    -1,   178,    75,   177,    -1,
+      -1,   178,   191,    -1,    -1,   100,    -1,    91,    -1,   181,
+      -1,     1,    -1,    98,    -1,   110,    -1,   121,    -1,   124,
+      -1,   113,    -1,    -1,   144,    66,   182,   180,    -1,    15,
+      -1,     6,   140,    -1,    10,   140,    -1,    18,   128,    -1,
+      13,   128,    -1,    19,   138,    -1,    27,   193,    -1,   180,
+      -1,   183,    62,   180,    -1,   138,    -1,   184,    75,   138,
+      -1,   139,    -1,   185,    75,   139,    -1,   126,    -1,   186,
+      75,   126,    -1,   135,    -1,   187,    75,   135,    -1,   131,
+      -1,   132,    -1,   188,    75,   131,    -1,   188,    75,   132,
+      -1,    -1,   188,   191,    -1,    -1,    62,    -1,    -1,    75,
+      -1,    -1,   126,    -1,    -1,   186,    -1,    -1,    98,    -1,
+      -1,   215,    -1,    -1,   216,    -1,    -1,   217,    -1,    -1,
+       3,    -1,    21,    24,     3,    62,    -1,    32,   200,   202,
+      62,    -1,     9,   200,    65,   213,    62,    -1,     9,   200,
+     202,    65,   213,    62,    -1,    31,   201,   202,    62,    -1,
+      17,   160,   162,    62,    -1,   142,    -1,   200,    -1,   204,
+      -1,   205,    -1,   206,    -1,   204,    -1,   206,    -1,   142,
+      -1,    24,    -1,    71,    72,   202,    -1,    71,     3,    72,
+     202,    -1,    23,    71,   202,    72,   202,    -1,    29,    67,
+     196,    68,    -1,    22,    67,   197,    68,    -1,    53,   202,
+      -1,     8,   203,    -1,     8,    59,   205,    60,    -1,     8,
+      36,   202,    -1,    36,     8,   202,    -1,    17,    59,   195,
+      60,   210,    -1,   141,   202,   198,    -1,   141,    11,   202,
+     198,    -1,   141,   202,   198,    -1,   141,    59,   195,    60,
+     210,    -1,   202,    -1,    -1,   211,    -1,    59,   195,    60,
+      -1,   202,    -1,     3,    -1,    50,     3,    -1,   141,    -1,
+     212,    -1,    59,   212,    49,   212,    60,    -1,    -1,   214,
+     199,    -1,   207,    -1,   215,    75,   207,    -1,   208,    -1,
+     216,    62,   208,    -1,   209,    -1,   217,    62,   209,    -1
 };
 
 /* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
@@ -663,37 +663,37 @@ static const yytype_uint16 yyrline[] =
      263,   264,   271,   271,   284,   288,   289,   293,   298,   304,
      308,   312,   316,   322,   328,   334,   339,   343,   347,   353,
      359,   363,   367,   373,   377,   383,   384,   388,   394,   403,
-     409,   427,   432,   444,   460,   465,   472,   492,   510,   519,
-     538,   537,   552,   551,   583,   586,   593,   592,   603,   609,
-     618,   629,   635,   638,   646,   645,   656,   662,   674,   678,
-     683,   673,   704,   703,   716,   719,   725,   728,   740,   744,
-     739,   762,   761,   777,   778,   782,   786,   790,   794,   798,
-     802,   806,   810,   814,   818,   822,   826,   830,   834,   838,
-     842,   846,   850,   855,   861,   862,   866,   877,   881,   885,
-     889,   894,   898,   908,   912,   917,   925,   929,   930,   941,
-     945,   949,   953,   957,   965,   966,   972,   979,   985,   992,
-     995,  1002,  1008,  1025,  1032,  1033,  1040,  1041,  1060,  1061,
-    1064,  1067,  1071,  1082,  1091,  1097,  1100,  1103,  1110,  1111,
-    1117,  1130,  1145,  1153,  1165,  1170,  1176,  1177,  1178,  1179,
-    1180,  1181,  1187,  1188,  1189,  1190,  1196,  1197,  1198,  1199,
-    1200,  1206,  1207,  1210,  1213,  1214,  1215,  1216,  1217,  1220,
-    1221,  1234,  1238,  1243,  1248,  1253,  1257,  1258,  1261,  1267,
-    1274,  1280,  1287,  1293,  1304,  1318,  1347,  1387,  1412,  1430,
-    1439,  1442,  1450,  1454,  1458,  1465,  1471,  1476,  1488,  1491,
-    1501,  1502,  1508,  1509,  1515,  1519,  1525,  1526,  1532,  1536,
-    1542,  1565,  1570,  1576,  1582,  1589,  1598,  1607,  1622,  1628,
-    1633,  1637,  1644,  1657,  1658,  1664,  1670,  1673,  1677,  1683,
-    1686,  1695,  1698,  1699,  1703,  1704,  1710,  1711,  1712,  1713,
-    1714,  1716,  1715,  1730,  1736,  1740,  1744,  1748,  1752,  1757,
-    1776,  1782,  1790,  1794,  1800,  1804,  1810,  1814,  1820,  1824,
-    1833,  1837,  1841,  1845,  1851,  1854,  1862,  1863,  1865,  1866,
-    1869,  1872,  1875,  1878,  1881,  1884,  1887,  1890,  1893,  1896,
-    1899,  1902,  1905,  1908,  1914,  1918,  1922,  1926,  1930,  1934,
-    1954,  1961,  1972,  1973,  1974,  1977,  1978,  1981,  1985,  1995,
-    1999,  2003,  2007,  2011,  2015,  2019,  2025,  2031,  2039,  2047,
-    2053,  2060,  2076,  2098,  2102,  2108,  2111,  2114,  2118,  2128,
-    2132,  2151,  2159,  2160,  2172,  2173,  2176,  2180,  2186,  2190,
-    2196,  2200
+     409,   427,   432,   444,   460,   466,   474,   494,   512,   521,
+     540,   539,   554,   553,   585,   588,   595,   594,   605,   611,
+     618,   625,   636,   642,   645,   653,   652,   663,   669,   681,
+     685,   690,   680,   711,   710,   723,   726,   732,   735,   747,
+     751,   746,   769,   768,   784,   785,   789,   793,   797,   801,
+     805,   809,   813,   817,   821,   825,   829,   833,   837,   841,
+     845,   849,   853,   857,   862,   868,   869,   873,   884,   888,
+     892,   896,   901,   905,   915,   919,   924,   932,   936,   937,
+     948,   952,   956,   960,   964,   972,   973,   979,   986,   992,
+     999,  1002,  1009,  1015,  1032,  1039,  1040,  1047,  1048,  1067,
+    1068,  1071,  1074,  1078,  1089,  1098,  1104,  1107,  1110,  1117,
+    1118,  1124,  1137,  1152,  1160,  1172,  1177,  1183,  1184,  1185,
+    1186,  1187,  1188,  1194,  1195,  1196,  1197,  1203,  1204,  1205,
+    1206,  1207,  1213,  1214,  1217,  1220,  1221,  1222,  1223,  1224,
+    1227,  1228,  1241,  1245,  1250,  1255,  1260,  1264,  1265,  1268,
+    1274,  1281,  1287,  1294,  1300,  1311,  1326,  1355,  1393,  1418,
+    1436,  1445,  1448,  1456,  1460,  1464,  1471,  1477,  1482,  1494,
+    1497,  1508,  1509,  1515,  1516,  1522,  1526,  1532,  1533,  1539,
+    1543,  1549,  1572,  1577,  1583,  1589,  1596,  1605,  1614,  1629,
+    1635,  1640,  1644,  1651,  1664,  1665,  1671,  1677,  1680,  1684,
+    1690,  1693,  1702,  1705,  1706,  1710,  1711,  1717,  1718,  1719,
+    1720,  1721,  1723,  1722,  1737,  1743,  1747,  1751,  1755,  1759,
+    1764,  1783,  1789,  1797,  1801,  1807,  1811,  1817,  1821,  1827,
+    1831,  1840,  1844,  1848,  1852,  1858,  1861,  1869,  1870,  1872,
+    1873,  1876,  1879,  1882,  1885,  1888,  1891,  1894,  1897,  1900,
+    1903,  1906,  1909,  1912,  1915,  1921,  1925,  1929,  1933,  1937,
+    1941,  1961,  1968,  1979,  1980,  1981,  1984,  1985,  1988,  1992,
+    2002,  2006,  2010,  2014,  2018,  2022,  2026,  2032,  2038,  2046,
+    2054,  2060,  2067,  2083,  2105,  2109,  2115,  2118,  2121,  2125,
+    2135,  2139,  2158,  2166,  2167,  2179,  2180,  2183,  2187,  2193,
+    2197,  2203,  2207
 };
 #endif
 
@@ -772,35 +772,35 @@ static const yytype_uint8 yyr1[] =
       93,    93,    93,    94,    94,    95,    95,    95,    96,    97,
       98,    98,    98,    98,    98,    98,    99,    99,    99,    99,
      101,   100,   103,   102,   104,   104,   106,   105,   107,   107,
-     108,   108,   108,   109,   111,   110,   112,   112,   114,   115,
-     116,   113,   118,   117,   119,   119,   120,   120,   122,   123,
-     121,   125,   124,   126,   126,   126,   126,   126,   126,   126,
+     107,   108,   108,   108,   109,   111,   110,   112,   112,   114,
+     115,   116,   113,   118,   117,   119,   119,   120,   120,   122,
+     123,   121,   125,   124,   126,   126,   126,   126,   126,   126,
      126,   126,   126,   126,   126,   126,   126,   126,   126,   126,
-     126,   126,   126,   126,   127,   127,   127,   127,   127,   127,
-     127,   127,   127,   128,   128,   128,   129,   129,   129,   129,
+     126,   126,   126,   126,   126,   127,   127,   127,   127,   127,
+     127,   127,   127,   127,   128,   128,   128,   129,   129,   129,
      129,   129,   129,   129,   129,   129,   129,   129,   129,   129,
-     130,   131,   132,   132,   133,   133,   134,   134,   135,   135,
-     136,   137,   137,   138,   139,   140,   140,   141,   141,   141,
-     142,   142,   143,   144,   145,   145,   146,   146,   146,   146,
-     146,   146,   147,   147,   147,   147,   148,   148,   148,   148,
-     148,   149,   149,   150,   151,   151,   151,   151,   151,   152,
-     152,   153,   153,   153,   153,   153,   153,   153,   154,   155,
-     156,   156,   157,   157,   158,   159,   159,   160,   160,   161,
-     162,   162,   163,   163,   163,   164,   165,   165,   166,   166,
-     167,   167,   168,   168,   169,   169,   170,   170,   171,   171,
-     172,   172,   172,   172,   172,   172,   173,   173,   174,   175,
-     175,   175,   176,   177,   177,   177,   177,   178,   178,   179,
-     179,   180,   180,   180,   180,   180,   181,   181,   181,   181,
-     181,   182,   181,   181,   181,   181,   181,   181,   181,   181,
-     183,   183,   184,   184,   185,   185,   186,   186,   187,   187,
-     188,   188,   188,   188,   189,   189,   190,   190,   191,   191,
-     192,   192,   193,   193,   194,   194,   195,   195,   196,   196,
-     197,   197,   198,   198,   199,   199,   199,   199,   199,   199,
-     200,   201,   202,   202,   202,   203,   203,   204,   204,   204,
-     204,   204,   204,   204,   204,   204,   204,   204,   205,   206,
-     207,   207,   208,   209,   209,   210,   210,   211,   211,   212,
-     212,   212,   213,   213,   214,   214,   215,   215,   216,   216,
-     217,   217
+     129,   130,   131,   132,   132,   133,   133,   134,   134,   135,
+     135,   136,   137,   137,   138,   139,   140,   140,   141,   141,
+     141,   142,   142,   143,   144,   145,   145,   146,   146,   146,
+     146,   146,   146,   147,   147,   147,   147,   148,   148,   148,
+     148,   148,   149,   149,   150,   151,   151,   151,   151,   151,
+     152,   152,   153,   153,   153,   153,   153,   153,   153,   154,
+     155,   156,   156,   157,   157,   158,   159,   159,   160,   160,
+     161,   162,   162,   163,   163,   163,   164,   165,   165,   166,
+     166,   167,   167,   168,   168,   169,   169,   170,   170,   171,
+     171,   172,   172,   172,   172,   172,   172,   173,   173,   174,
+     175,   175,   175,   176,   177,   177,   177,   177,   178,   178,
+     179,   179,   180,   180,   180,   180,   180,   181,   181,   181,
+     181,   181,   182,   181,   181,   181,   181,   181,   181,   181,
+     181,   183,   183,   184,   184,   185,   185,   186,   186,   187,
+     187,   188,   188,   188,   188,   189,   189,   190,   190,   191,
+     191,   192,   192,   193,   193,   194,   194,   195,   195,   196,
+     196,   197,   197,   198,   198,   199,   199,   199,   199,   199,
+     199,   200,   201,   202,   202,   202,   203,   203,   204,   204,
+     204,   204,   204,   204,   204,   204,   204,   204,   204,   205,
+     206,   207,   207,   208,   209,   209,   210,   210,   211,   211,
+     212,   212,   212,   213,   213,   214,   214,   215,   215,   216,
+     216,   217,   217
 };
 
 /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
@@ -813,35 +813,35 @@ static const yytype_uint8 yyr2[] =
        2,     4,     3,     4,     3,     1,     2,     1,     1,     2,
        1,     3,     3,     3,     2,     2,     3,     5,     5,     2,
        0,     4,     0,     3,     0,     2,     0,     4,     4,     4,
-       5,     1,     1,     2,     0,     3,     1,     3,     0,     0,
-       0,     8,     0,     5,     0,     2,     0,     2,     0,     0,
-       7,     0,     5,     1,     3,     3,     3,     3,     3,     3,
+       2,     5,     1,     1,     2,     0,     3,     1,     3,     0,
+       0,     0,     8,     0,     5,     0,     2,     0,     2,     0,
+       0,     7,     0,     5,     1,     3,     3,     3,     3,     3,
        3,     3,     3,     3,     3,     3,     3,     3,     3,     3,
-       3,     3,     3,     3,     1,     2,     2,     2,     2,     2,
-       2,     2,     2,     3,     5,     6,     1,     1,     3,     5,
-       5,     4,     6,     8,     1,     5,     5,     5,     7,     1,
-       0,     3,     1,     4,     1,     4,     1,     3,     1,     1,
-       1,     1,     1,     1,     1,     0,     1,     1,     1,     1,
-       4,     4,     1,     1,     1,     2,     1,     1,     1,     1,
-       1,     3,     1,     1,     1,     2,     1,     1,     1,     1,
-       3,     1,     1,     1,     1,     1,     1,     1,     1,     1,
-       3,     4,     4,     2,     3,     5,     1,     1,     2,     3,
-       5,     3,     5,     3,     3,     5,     8,     5,     8,     5,
-       0,     3,     0,     1,     3,     1,     4,     2,     0,     3,
-       1,     3,     1,     3,     1,     3,     1,     3,     1,     3,
-       3,     2,     4,     3,     5,     5,     1,     3,     1,     2,
-       1,     3,     4,     1,     2,     2,     1,     1,     3,     0,
-       2,     0,     1,     1,     1,     1,     1,     1,     1,     1,
-       1,     0,     4,     1,     2,     2,     2,     2,     2,     2,
-       1,     3,     1,     3,     1,     3,     1,     3,     1,     3,
-       1,     1,     3,     3,     0,     2,     0,     1,     0,     1,
-       0,     1,     0,     1,     0,     1,     0,     1,     0,     1,
-       0,     1,     0,     1,     4,     4,     5,     6,     4,     4,
-       1,     1,     1,     1,     1,     1,     1,     1,     1,     3,
-       4,     5,     4,     4,     2,     2,     4,     3,     3,     5,
-       3,     4,     3,     5,     1,     0,     1,     3,     1,     1,
-       2,     1,     1,     5,     0,     2,     1,     3,     1,     3,
-       1,     3
+       3,     3,     3,     3,     3,     1,     2,     2,     2,     2,
+       2,     2,     2,     2,     3,     5,     6,     1,     1,     3,
+       5,     5,     4,     6,     8,     1,     5,     5,     5,     7,
+       1,     0,     3,     1,     4,     1,     4,     1,     3,     1,
+       1,     1,     1,     1,     1,     1,     0,     1,     1,     1,
+       1,     4,     4,     1,     1,     1,     2,     1,     1,     1,
+       1,     1,     3,     1,     1,     1,     2,     1,     1,     1,
+       1,     3,     1,     1,     1,     1,     1,     1,     1,     1,
+       1,     3,     4,     4,     2,     3,     5,     1,     1,     2,
+       3,     5,     3,     5,     3,     3,     5,     8,     5,     8,
+       5,     0,     3,     0,     1,     3,     1,     4,     2,     0,
+       3,     1,     3,     1,     3,     1,     3,     1,     3,     1,
+       3,     3,     2,     4,     3,     5,     5,     1,     3,     1,
+       2,     1,     3,     4,     1,     2,     2,     1,     1,     3,
+       0,     2,     0,     1,     1,     1,     1,     1,     1,     1,
+       1,     1,     0,     4,     1,     2,     2,     2,     2,     2,
+       2,     1,     3,     1,     3,     1,     3,     1,     3,     1,
+       3,     1,     1,     3,     3,     0,     2,     0,     1,     0,
+       1,     0,     1,     0,     1,     0,     1,     0,     1,     0,
+       1,     0,     1,     0,     1,     4,     4,     5,     6,     4,
+       4,     1,     1,     1,     1,     1,     1,     1,     1,     1,
+       3,     4,     5,     4,     4,     2,     2,     4,     3,     3,
+       5,     3,     4,     3,     5,     1,     0,     1,     3,     1,
+       1,     2,     1,     1,     5,     0,     2,     1,     3,     1,
+       3,     1,     3
 };
 
 /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
@@ -849,656 +849,642 @@ static const yytype_uint8 yyr2[] =
    means the default is an error.  */
 static const yytype_uint16 yydefact[] =
 {
-       5,     0,     3,     0,     1,     0,     7,     0,    22,   157,
-     159,     0,     0,   158,   218,    20,     6,   344,     0,     4,
+       5,     0,     3,     0,     1,     0,     7,     0,    22,   158,
+     160,     0,     0,   159,   219,    20,     6,   345,     0,     4,
        0,     0,     0,    21,     0,     0,     0,    16,     0,     0,
-       9,    22,     0,     8,    28,   126,   155,     0,    39,   155,
-       0,   263,    74,     0,     0,     0,    78,     0,     0,   292,
-      91,     0,    88,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,   290,     0,    25,     0,   256,   257,
-     260,   258,   259,    50,    93,   134,   146,   114,   163,   162,
-     127,     0,     0,     0,   183,   196,   197,    26,   215,     0,
-     139,    27,     0,    19,     0,     0,     0,     0,     0,     0,
-     345,   160,   161,    11,    14,   286,    18,    22,    13,    17,
-     156,   264,   153,     0,     0,     0,     0,   162,   189,   193,
-     179,   177,   178,   176,   265,   134,     0,   294,   249,     0,
-     210,   134,   268,   294,   151,   152,     0,     0,   276,   293,
-     269,     0,     0,   294,     0,     0,    36,    48,     0,    29,
-     274,   154,     0,   122,   117,   118,   121,   115,   116,     0,
-       0,   148,     0,   149,   174,   172,   173,   119,   120,     0,
-     291,     0,   219,     0,    32,     0,     0,     0,     0,     0,
+       9,    22,     0,     8,    28,   127,   156,     0,    39,   156,
+       0,   264,    75,     0,     0,     0,    79,     0,     0,   293,
+      92,     0,    89,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,   291,     0,    25,     0,   257,   258,
+     261,   259,   260,    50,    94,   135,   147,   115,   164,   163,
+     128,     0,     0,     0,   184,   197,   198,    26,   216,     0,
+     140,    27,     0,    19,     0,     0,     0,     0,     0,     0,
+     346,   161,   162,    11,    14,   287,    18,    22,    13,    17,
+     157,   265,   154,     0,     0,     0,     0,   163,   190,   194,
+     180,   178,   179,   177,   266,   135,     0,   295,   250,     0,
+     211,   135,   269,   295,   152,   153,     0,     0,   277,   294,
+     270,     0,     0,   295,     0,     0,    36,    48,     0,    29,
+     275,   155,     0,   123,   118,   119,   122,   116,   117,     0,
+       0,   149,     0,   150,   175,   173,   174,   120,   121,     0,
+     292,     0,   220,     0,    32,     0,     0,     0,     0,     0,
       55,     0,     0,     0,    54,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,     0,   140,
-       0,     0,   290,   261,     0,   140,   217,     0,     0,     0,
-       0,   310,     0,     0,   210,     0,     0,   311,     0,     0,
-      23,   287,     0,    12,   249,     0,     0,   194,   170,   168,
-     169,   166,   167,   198,     0,     0,   295,    72,     0,    75,
-       0,    71,   164,   243,   162,   246,   150,   247,   288,     0,
-     249,     0,   204,    79,    76,   157,     0,   203,     0,   286,
-     240,   228,     0,    64,     0,     0,   201,   272,   286,   226,
-     238,   302,     0,    89,    38,   224,   286,    49,    31,   220,
-     286,     0,     0,    40,     0,   175,   147,     0,     0,    35,
-     286,     0,     0,    51,    95,   110,   113,    96,   100,   101,
-      99,   111,    98,    97,    94,   112,   102,   103,   104,   105,
-     106,   107,   108,   109,   284,   123,   278,   288,     0,   128,
-     291,     0,     0,   288,   284,   255,    60,   253,   252,   270,
-     254,     0,    53,    52,   277,     0,     0,     0,     0,   318,
-       0,     0,     0,     0,     0,   317,     0,   312,   313,   314,
-       0,   346,     0,     0,   296,     0,     0,     0,    15,    10,
-       0,     0,     0,   180,   190,    66,    73,     0,     0,   294,
-     165,   244,   245,   289,   250,   212,     0,     0,     0,   294,
-       0,   236,     0,   249,   239,   287,     0,     0,     0,     0,
-     302,     0,     0,   287,     0,   303,   231,     0,   302,     0,
-     287,     0,   287,     0,    42,   275,     0,     0,     0,   199,
-     170,   168,   169,   167,   140,   192,   191,   287,     0,    44,
-       0,   140,   142,   280,   281,   288,     0,   288,   289,     0,
-       0,     0,   131,   290,   262,   289,     0,     0,     0,     0,
-     216,     0,     0,   325,   315,   316,   296,   300,     0,   298,
-       0,   324,   339,     0,     0,   341,   342,     0,     0,     0,
-       0,     0,   302,     0,     0,   309,     0,   297,   304,   308,
-     305,   212,   171,     0,     0,     0,     0,   248,   249,   162,
-     213,   188,   186,   187,   184,   185,   209,   212,   211,    80,
-      77,   237,   241,     0,   229,   202,   195,     0,     0,    92,
-      62,    65,     0,   233,     0,   302,   227,   200,   273,   230,
-      64,   225,    37,   221,    30,    41,     0,   284,    45,   222,
-     286,    47,    33,    43,   284,     0,   289,   285,   137,     0,
-     279,   124,   130,   129,     0,   135,   136,     0,   271,   327,
-       0,     0,   318,     0,   317,     0,   334,   350,   301,     0,
-       0,     0,   348,   299,   328,   340,     0,   306,     0,   319,
-       0,   302,   330,     0,   347,   335,     0,    69,    68,   294,
-       0,   249,   205,    84,   212,     0,    59,     0,   302,   302,
-     232,     0,   171,     0,   287,     0,    46,     0,   140,   144,
-     141,   282,   283,   125,   290,   132,    61,   326,   335,   296,
-     323,     0,     0,   302,   322,     0,     0,   320,   307,   331,
-     296,   296,   338,   207,   336,    67,    70,   214,     0,    86,
-     242,     0,     0,    56,     0,    63,   235,   234,    90,   138,
-     223,    34,   143,   284,     0,   329,     0,   351,   321,   332,
-     349,     0,     0,     0,   212,     0,    85,    81,     0,     0,
-       0,   133,   335,   343,   335,   337,   206,    82,    87,    58,
-      57,   145,   333,   208,   294,     0,    83
+       0,     0,     0,     0,     0,     0,     0,     0,     0,   141,
+       0,     0,   291,   262,     0,   141,   218,     0,     0,     0,
+       0,   311,     0,     0,   211,     0,     0,   312,     0,     0,
+      23,   288,     0,    12,   250,     0,     0,   195,   171,   169,
+     170,   167,   168,   199,     0,     0,     0,   296,    73,     0,
+      76,     0,    72,   165,   244,   163,   247,   151,   248,   289,
+       0,   250,     0,   205,    80,    77,   158,     0,   204,     0,
+     287,   241,   229,     0,    64,     0,     0,   202,   273,   287,
+     227,   239,   303,     0,    90,    38,   225,   287,    49,    31,
+     221,   287,     0,     0,    40,     0,   176,   148,     0,     0,
+      35,   287,     0,     0,    51,    96,   111,   114,    97,   101,
+     102,   100,   112,    99,    98,    95,   113,   103,   104,   105,
+     106,   107,   108,   109,   110,   285,   124,   279,   289,     0,
+     129,   292,     0,     0,   289,   285,   256,    60,   254,   253,
+     271,   255,     0,    53,    52,   278,     0,     0,     0,     0,
+     319,     0,     0,     0,     0,     0,   318,     0,   313,   314,
+     315,     0,   347,     0,     0,   297,     0,     0,     0,    15,
+      10,     0,     0,     0,   181,   191,    70,    66,    74,     0,
+       0,   295,   166,   245,   246,   290,   251,   213,     0,     0,
+       0,   295,     0,   237,     0,   250,   240,   288,     0,     0,
+       0,     0,   303,     0,     0,   288,     0,   304,   232,     0,
+     303,     0,   288,     0,   288,     0,    42,   276,     0,     0,
+       0,   200,   171,   169,   170,   168,   141,   193,   192,   288,
+       0,    44,     0,   141,   143,   281,   282,   289,     0,   289,
+     290,     0,     0,     0,   132,   291,   263,   290,     0,     0,
+       0,     0,   217,     0,     0,   326,   316,   317,   297,   301,
+       0,   299,     0,   325,   340,     0,     0,   342,   343,     0,
+       0,     0,     0,     0,   303,     0,     0,   310,     0,   298,
+     305,   309,   306,   213,   172,     0,     0,     0,     0,   249,
+     250,   163,   214,   189,   187,   188,   185,   186,   210,   213,
+     212,    81,    78,   238,   242,     0,   230,   203,   196,     0,
+       0,    93,    62,    65,     0,   234,     0,   303,   228,   201,
+     274,   231,    64,   226,    37,   222,    30,    41,     0,   285,
+      45,   223,   287,    47,    33,    43,   285,     0,   290,   286,
+     138,     0,   280,   125,   131,   130,     0,   136,   137,     0,
+     272,   328,     0,     0,   319,     0,   318,     0,   335,   351,
+     302,     0,     0,     0,   349,   300,   329,   341,     0,   307,
+       0,   320,     0,   303,   331,     0,   348,   336,     0,    69,
+      68,   295,     0,   250,   206,    85,   213,     0,    59,     0,
+     303,   303,   233,     0,   172,     0,   288,     0,    46,     0,
+     141,   145,   142,   283,   284,   126,   291,   133,    61,   327,
+     336,   297,   324,     0,     0,   303,   323,     0,     0,   321,
+     308,   332,   297,   297,   339,   208,   337,    67,    71,   215,
+       0,    87,   243,     0,     0,    56,     0,    63,   236,   235,
+      91,   139,   224,    34,   144,   285,     0,   330,     0,   352,
+     322,   333,   350,     0,     0,     0,   213,     0,    86,    82,
+       0,     0,     0,   134,   336,   344,   336,   338,   207,    83,
+      88,    58,    57,   146,   334,   209,   295,     0,    84
 };
 
 /* YYDEFGOTO[NTERM-NUM].  */
 static const yytype_int16 yydefgoto[] =
 {
       -1,     1,     6,     2,     3,    14,    21,    30,   105,    31,
-       8,    24,    16,    17,    65,   327,    67,   149,   518,   519,
-     145,   146,    68,   500,   328,   438,   501,   577,   388,   366,
-     473,   237,   238,   239,    69,   127,   253,    70,   133,   378,
-     573,   646,   664,   619,   647,    71,   143,   399,    72,   141,
-      73,    74,    75,    76,   314,   423,   424,   590,    77,   316,
-     243,   136,    78,   150,   111,   117,    13,    80,    81,   245,
-     246,   163,   119,    82,    83,   480,   228,    84,   230,   231,
-      85,    86,    87,   130,   214,    88,   252,   486,    89,    90,
-      22,   280,   520,   276,   268,   259,   269,   270,   271,   261,
-     384,   247,   248,   249,   329,   330,   322,   331,   272,   152,
-      92,   317,   425,   426,   222,   374,   171,   140,   254,   466,
-     551,   545,   396,   100,   212,   218,   612,   443,   347,   348,
-     349,   351,   552,   547,   613,   614,   456,   457,    25,   467,
-     553,   548
+       8,    24,    16,    17,    65,   328,    67,   149,   520,   521,
+     145,   146,    68,   502,   329,   440,   503,   579,   390,   368,
+     475,   238,   239,   240,    69,   127,   254,    70,   133,   380,
+     575,   648,   666,   621,   649,    71,   143,   401,    72,   141,
+      73,    74,    75,    76,   315,   425,   426,   592,    77,   317,
+     244,   136,    78,   150,   111,   117,    13,    80,    81,   246,
+     247,   163,   119,    82,    83,   482,   228,    84,   230,   231,
+      85,    86,    87,   130,   214,    88,   253,   488,    89,    90,
+      22,   281,   522,   277,   269,   260,   270,   271,   272,   262,
+     386,   248,   249,   250,   330,   331,   323,   332,   273,   152,
+      92,   318,   427,   428,   222,   376,   171,   140,   255,   468,
+     553,   547,   398,   100,   212,   218,   614,   445,   348,   349,
+     350,   352,   554,   549,   615,   616,   458,   459,    25,   469,
+     555,   550
 };
 
 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
    STATE-NUM.  */
-#define YYPACT_NINF -474
+#define YYPACT_NINF -473
 static const yytype_int16 yypact[] =
 {
-    -474,    48,    28,    35,  -474,   258,  -474,    37,  -474,  -474,
-    -474,    61,    12,  -474,    85,   107,  -474,  -474,    70,  -474,
-     156,    82,  1059,  -474,   122,   328,    22,  -474,    56,   199,
-    -474,    35,   211,  -474,  -474,  -474,   258,   767,  -474,   258,
-     459,  -474,  -474,   152,   459,   258,  -474,    23,   145,  1650,
-    -474,    23,  -474,   294,   359,  1650,  1650,  1650,  1650,  1650,
-    1650,  1693,  1650,  1650,  1289,   159,  -474,   412,  -474,  -474,
-    -474,  -474,  -474,   939,  -474,  -474,   157,   302,  -474,   168,
-    -474,   175,   184,    23,   204,  -474,  -474,  -474,   219,    54,
-    -474,  -474,    47,  -474,   227,   -12,   269,   227,   227,   239,
-    -474,  -474,  -474,  -474,  -474,   240,  -474,  -474,  -474,  -474,
-    -474,  -474,  -474,   250,  1813,  1813,  1813,  -474,   259,  -474,
-    -474,  -474,  -474,  -474,  -474,    64,   302,  1650,  1805,   262,
-     260,   174,  -474,  1650,  -474,  -474,   221,  1813,  2166,   255,
-    -474,   290,   237,  1650,   304,  1813,  -474,  -474,   420,  -474,
-    -474,  -474,   580,  -474,  -474,  -474,  -474,  -474,  -474,  1736,
-    1693,  2166,   280,  -474,   253,  -474,    50,  -474,  -474,   275,
-    2166,   285,  -474,   430,  -474,   612,  1650,  1650,  1650,  1650,
-    -474,  1650,  1650,  1650,  -474,  1650,  1650,  1650,  1650,  1650,
-    1650,  1650,  1650,  1650,  1650,  1650,  1650,  1650,  1650,  -474,
-    1332,   428,  1650,  -474,  1650,  -474,  -474,  1234,  1650,  1650,
-    1650,  -474,   763,   258,   260,   293,   369,  -474,  1992,  1992,
-    -474,    51,   326,  -474,  1805,   392,  1813,  -474,  -474,  -474,
-    -474,  -474,  -474,  -474,   341,   258,  -474,  -474,   371,  -474,
-      89,   342,  1813,  -474,  1805,  -474,  -474,  -474,   335,   360,
-    1805,  1234,  -474,  -474,   357,    99,   399,  -474,   365,   380,
-    -474,  -474,   377,  -474,   173,   151,  -474,  -474,   381,  -474,
-    -474,   456,  1779,  -474,  -474,  -474,   401,  -474,  -474,  -474,
-     404,  1650,   258,   366,  1838,  -474,   405,  1813,  1813,  -474,
-     407,  1650,   410,  2166,   650,  -474,  2190,   877,   877,   877,
-     877,  -474,   877,   877,  2214,  -474,   461,   461,   461,   461,
-    -474,  -474,  -474,  -474,  1387,  -474,  -474,    52,  1442,  -474,
-    2064,   411,  1160,  2031,  1387,  -474,  -474,  -474,  -474,  -474,
-    -474,    19,   255,   255,  2166,  1905,   447,   441,   439,  -474,
-     444,   505,  1992,   225,    27,  -474,   454,  -474,  -474,  -474,
-    1931,  -474,   125,   458,   258,   460,   465,   466,  -474,  -474,
-     463,  1813,   480,  -474,  -474,  -474,  -474,  1497,  1552,  1650,
-    -474,  -474,  -474,  1805,  -474,  1872,   484,    24,   371,  1650,
-     258,   485,   487,  1805,  -474,   472,   481,  1813,    81,   399,
-     456,   399,   490,   289,   483,  -474,  -474,   258,   456,   519,
-     258,   495,   258,   496,   255,  -474,  1650,  1897,  1813,  -474,
-     321,   349,   350,   354,  -474,  -474,  -474,   258,   497,   255,
-    1650,  -474,  2094,  -474,  -474,   488,   491,   489,  1693,   498,
-     500,   502,  -474,  1650,  -474,  -474,   506,   503,  1234,  1160,
-    -474,  1992,   534,  -474,  -474,  -474,   258,  1958,  1992,   258,
-    1992,  -474,  -474,   565,   149,  -474,  -474,   510,   504,  1992,
-     225,  1992,   456,   258,   258,  -474,   514,   507,  -474,  -474,
-    -474,  1872,  -474,  1234,  1650,  1650,   515,  -474,  1805,   520,
-    -474,  -474,  -474,  -474,  -474,  -474,  -474,  1872,  -474,  -474,
-    -474,  -474,  -474,   518,  -474,  -474,  -474,  1693,   517,  -474,
-    -474,  -474,   524,  -474,   525,   456,  -474,  -474,  -474,  -474,
-    -474,  -474,  -474,  -474,  -474,   255,   526,  1387,  -474,  -474,
-     527,   612,  -474,   255,  1387,  1595,  1387,  -474,  -474,   530,
-    -474,  -474,  -474,  -474,   116,  -474,  -474,   141,  -474,  -474,
-     539,   540,   521,   542,   546,   538,  -474,  -474,   548,   543,
-    1992,   549,  -474,   552,  -474,  -474,   562,  -474,  1992,  -474,
-     556,   456,  -474,   560,  -474,  1984,   238,  2166,  2166,  1650,
-     561,  1805,  -474,  -474,  1872,    32,  -474,  1160,   456,   456,
-    -474,   186,   370,   554,   258,   563,   410,   557,  -474,  2166,
-    -474,  -474,  -474,  -474,  1650,  -474,  -474,  -474,  1984,   258,
-    -474,  1958,  1992,   456,  -474,   258,   149,  -474,  -474,  -474,
-     258,   258,  -474,  -474,  -474,  -474,  -474,  -474,   564,   613,
-    -474,  1650,  1650,  -474,  1693,   566,  -474,  -474,  -474,  -474,
-    -474,  -474,  -474,  1387,   558,  -474,   571,  -474,  -474,  -474,
-    -474,   577,   582,   583,  1872,    36,  -474,  -474,  2118,  2142,
-     572,  -474,  1984,  -474,  1984,  -474,  -474,  -474,  -474,  -474,
-    -474,  -474,  -474,  -474,  1650,   371,  -474
+    -473,    65,    22,    49,  -473,   261,  -473,    64,  -473,  -473,
+    -473,    95,    52,  -473,   143,   145,  -473,  -473,   104,  -473,
+      68,   128,  1049,  -473,   142,   305,    16,  -473,    56,   204,
+    -473,    49,   220,  -473,  -473,  -473,   261,   974,  -473,   261,
+     562,  -473,  -473,   288,   562,   261,  -473,    14,   147,  1615,
+    -473,    14,  -473,   395,   401,  1615,  1615,  1615,  1615,  1615,
+    1615,  1658,  1615,  1615,   737,   168,  -473,   414,  -473,  -473,
+    -473,  -473,  -473,   649,  -473,  -473,   165,   122,  -473,   169,
+    -473,   177,   218,    14,   219,  -473,  -473,  -473,   235,    89,
+    -473,  -473,    34,  -473,   206,   124,   286,   206,   206,   260,
+    -473,  -473,  -473,  -473,  -473,   265,  -473,  -473,  -473,  -473,
+    -473,  -473,  -473,   270,  1803,  1803,  1803,  -473,   269,  -473,
+    -473,  -473,  -473,  -473,  -473,    39,   122,   882,  1777,   283,
+     277,   230,  -473,  1615,  -473,  -473,   292,  1803,  2097,   280,
+    -473,   332,   315,  1615,   215,  1803,  -473,  -473,   244,  -473,
+    -473,  -473,   949,  -473,  -473,  -473,  -473,  -473,  -473,  1701,
+    1658,  2097,   298,  -473,     9,  -473,    59,  -473,  -473,   303,
+    2097,   319,  -473,   330,  -473,  1744,  1615,  1615,  1615,  1615,
+    -473,  1615,  1615,  1615,  -473,  1615,  1615,  1615,  1615,  1615,
+    1615,  1615,  1615,  1615,  1615,  1615,  1615,  1615,  1615,  -473,
+    1297,   455,  1615,  -473,  1615,  -473,  -473,  1225,  1615,  1615,
+    1615,  -473,   594,   261,   277,   328,   403,  -473,  1308,  1308,
+    -473,   152,   352,  -473,  1777,   405,  1803,  -473,  -473,  -473,
+    -473,  -473,  -473,  -473,   354,   261,  1615,  -473,  -473,   382,
+    -473,    47,   360,  1803,  -473,  1777,  -473,  -473,  -473,   351,
+     367,  1777,  1225,  -473,  -473,   366,    84,   407,  -473,   374,
+     373,  -473,  -473,   372,  -473,   138,    42,  -473,  -473,   377,
+    -473,  -473,   442,  1769,  -473,  -473,  -473,   384,  -473,  -473,
+    -473,   389,  1615,   261,   391,  1830,  -473,   394,  1803,  1803,
+    -473,   409,  1615,   411,  2097,  1935,  -473,  2121,  1080,  1080,
+    1080,  1080,  -473,  1080,  1080,  2145,  -473,   503,   503,   503,
+     503,  -473,  -473,  -473,  -473,  1352,  -473,  -473,    27,  1407,
+    -473,  1995,   412,  1147,  1962,  1352,  -473,  -473,  -473,  -473,
+    -473,  -473,     7,   280,   280,  2097,   698,   418,   415,   413,
+    -473,   416,   477,  1308,   188,    31,  -473,   425,  -473,  -473,
+    -473,  1897,  -473,   221,   433,   261,   434,   436,   439,  -473,
+    -473,   432,  1803,   452,  -473,  -473,  2097,  -473,  -473,  1462,
+    1517,  1615,  -473,  -473,  -473,  1777,  -473,  1856,   453,    91,
+     382,  1615,   261,   454,   456,  1777,  -473,   475,   451,  1803,
+     133,   407,   442,   407,   460,   326,   462,  -473,  -473,   261,
+     442,   467,   261,   478,   261,   486,   280,  -473,  1615,  1864,
+    1803,  -473,    26,   248,   264,   430,  -473,  -473,  -473,   261,
+     492,   280,  1615,  -473,  2025,  -473,  -473,   485,   493,   487,
+    1658,   504,   506,   508,  -473,  1615,  -473,  -473,   512,   505,
+    1225,  1147,  -473,  1308,   517,  -473,  -473,  -473,   261,  1889,
+    1308,   261,  1308,  -473,  -473,   571,   155,  -473,  -473,   514,
+     509,  1308,   188,  1308,   442,   261,   261,  -473,   518,   507,
+    -473,  -473,  -473,  1856,  -473,  1225,  1615,  1615,   521,  -473,
+    1777,   528,  -473,  -473,  -473,  -473,  -473,  -473,  -473,  1856,
+    -473,  -473,  -473,  -473,  -473,   520,  -473,  -473,  -473,  1658,
+     522,  -473,  -473,  -473,   530,  -473,   532,   442,  -473,  -473,
+    -473,  -473,  -473,  -473,  -473,  -473,  -473,   280,   535,  1352,
+    -473,  -473,   536,  1744,  -473,   280,  1352,  1560,  1352,  -473,
+    -473,   539,  -473,  -473,  -473,  -473,   247,  -473,  -473,   308,
+    -473,  -473,   541,   543,   545,   546,   547,   544,  -473,  -473,
+     551,   548,  1308,   554,  -473,   557,  -473,  -473,   576,  -473,
+    1308,  -473,   564,   442,  -473,   568,  -473,  1923,   318,  2097,
+    2097,  1615,   569,  1777,  -473,  -473,  1856,   156,  -473,  1147,
+     442,   442,  -473,   243,   483,   563,   261,   577,   411,   570,
+    -473,  2097,  -473,  -473,  -473,  -473,  1615,  -473,  -473,  -473,
+    1923,   261,  -473,  1889,  1308,   442,  -473,   261,   155,  -473,
+    -473,  -473,   261,   261,  -473,  -473,  -473,  -473,  -473,  -473,
+     579,   627,  -473,  1615,  1615,  -473,  1658,   580,  -473,  -473,
+    -473,  -473,  -473,  -473,  -473,  1352,   572,  -473,   583,  -473,
+    -473,  -473,  -473,   585,   586,   590,  1856,    77,  -473,  -473,
+    2049,  2073,   584,  -473,  1923,  -473,  1923,  -473,  -473,  -473,
+    -473,  -473,  -473,  -473,  -473,  -473,  1615,   382,  -473
 };
 
 /* YYPGOTO[NTERM-NUM].  */
 static const yytype_int16 yypgoto[] =
 {
-    -474,  -474,  -474,  -474,  -474,  -474,  -474,   -15,  -474,  -474,
-     616,  -474,    -3,  -474,  -474,   622,  -474,  -125,   -27,    66,
-    -474,  -124,  -112,  -474,    11,  -474,  -474,  -474,   147,  -368,
-    -474,  -474,  -474,  -474,  -474,  -474,  -140,  -474,  -474,  -474,
-    -474,  -474,  -474,  -474,  -474,  -474,  -474,  -474,  -474,  -474,
-     532,    10,   247,  -474,  -194,   132,   135,  -474,   279,   -59,
-     418,    67,     5,   384,   624,   425,   317,    20,  -474,   424,
-     636,   509,  -474,  -474,  -474,  -474,   -36,   -37,   -31,   -49,
-    -474,  -474,  -474,  -474,  -474,   -32,   464,  -473,  -474,  -474,
-    -474,  -474,  -474,  -474,  -474,  -474,   277,  -119,  -231,   287,
-    -474,   300,  -474,  -205,  -300,   652,  -474,  -242,  -474,   -63,
-     106,   182,  -474,  -316,  -241,  -285,  -195,  -474,  -111,  -420,
-    -474,  -474,  -245,  -474,   402,  -474,  -176,  -474,   345,   249,
-     346,   218,    87,    96,  -415,  -474,  -429,   252,  -474,   522,
-    -474,  -474
+    -473,  -473,  -473,  -473,  -473,  -473,  -473,   -12,  -473,  -473,
+     624,  -473,    -1,  -473,  -473,   635,  -473,  -137,   -48,    74,
+    -473,  -130,  -112,  -473,    11,  -473,  -473,  -473,   149,  -372,
+    -473,  -473,  -473,  -473,  -473,  -473,  -140,  -473,  -473,  -473,
+    -473,  -473,  -473,  -473,  -473,  -473,  -473,  -473,  -473,  -473,
+     662,   448,   257,  -473,  -196,   135,   139,  -473,   262,   -59,
+     424,   -16,    -3,   387,   632,   427,   313,    20,  -473,   428,
+     -89,   524,  -473,  -473,  -473,  -473,   -36,   -37,   -31,   -49,
+    -473,  -473,  -473,  -473,  -473,   -32,   458,  -472,  -473,  -473,
+    -473,  -473,  -473,  -473,  -473,  -473,   279,  -108,  -211,   290,
+    -473,   306,  -473,  -214,  -291,   658,  -473,  -230,  -473,   -63,
+      -6,   191,  -473,  -302,  -219,  -254,  -195,  -473,  -107,  -435,
+    -473,  -473,  -347,  -473,   323,  -473,    72,  -473,   371,   268,
+     380,   242,   102,   110,  -468,  -473,  -438,   255,  -473,   515,
+    -473,  -473
 };
 
 /* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
    positive, shift that token.  If negative, reduce the rule which
    number is the opposite.  If zero, do what YYDEFACT says.
    If YYTABLE_NINF, syntax error.  */
-#define YYTABLE_NINF -277
+#define YYTABLE_NINF -278
 static const yytype_int16 yytable[] =
 {
-     121,   120,   162,   273,   175,   123,   122,   321,   437,   377,
-     489,   324,   165,   104,   572,   236,   241,   260,   386,   360,
-     275,   236,   434,   279,   164,   556,   541,   394,   108,   166,
-     458,   236,   429,   390,   392,   401,   346,   621,   436,   403,
-     174,   110,   356,   357,   110,   376,   101,   213,     4,   418,
-     132,  -215,   208,     5,    27,   206,   657,   118,   134,    27,
-       7,    15,    11,   427,    18,   153,   154,   155,   156,   157,
-     158,  -267,   167,   168,    19,     9,  -267,   229,   229,   229,
-       9,   439,   232,   232,   232,  -215,   439,   440,   497,   134,
-     135,   229,   488,   498,   367,   102,   232,   622,   623,   459,
-     229,   620,  -236,   326,   223,   232,    20,   624,   229,  -181,
-     175,   165,   209,   232,    29,   229,   103,  -215,   142,    29,
-     232,   135,   210,   164,    10,    11,  -267,   428,   166,    10,
-      11,    23,  -267,    26,   118,   118,   118,   382,   229,   538,
-     527,   258,   529,   232,    33,   503,   290,   267,   118,   499,
-     205,   165,   452,   509,   368,   139,   207,   118,   502,    27,
-     504,  -236,   380,   164,   210,   118,   451,  -236,   166,   153,
-     157,   656,   118,     9,   462,   381,     9,   641,   493,   636,
-       9,  -266,   594,   635,    93,   463,  -266,   229,   595,   229,
-     642,   643,   232,   497,   232,   118,   537,   381,   498,   453,
-     464,   583,   106,   439,   391,   229,   358,   229,   587,   596,
-     232,   128,   232,   229,   109,    28,   137,   562,   232,    29,
-     517,   172,    10,    11,   199,    10,    11,   524,   452,    10,
-      11,   566,   389,   240,  -153,   229,  -266,   662,   534,   663,
-     232,   203,  -266,   204,   118,   255,   118,   411,   410,     9,
-     229,   229,   413,   412,   628,   232,   232,   236,   476,   431,
-     580,   255,   118,  -182,   118,   539,   260,   236,   490,   165,
-     118,   546,   549,   570,   554,   453,   511,   513,  -181,   585,
-     256,   164,     9,   559,   454,   561,   166,   125,  -183,   257,
-     264,   131,   118,   216,    10,    11,   265,   666,    10,    11,
-     439,    11,   221,   220,   118,   266,   615,   118,   118,   224,
-      10,    11,  -182,   255,   332,   333,   609,   650,     9,   126,
-    -183,   250,   235,   126,   229,   263,   484,   251,     9,   232,
-     210,    10,    11,   626,   627,   625,   229,    94,   482,   481,
-     286,   232,   264,   485,   483,    95,   229,   287,   265,    96,
-     229,   232,   354,   144,   521,   232,  -179,   288,   639,    97,
-      98,   200,    10,    11,   274,   201,   618,    10,    11,   530,
-     229,   229,   355,   202,   603,   232,   232,    10,    11,   165,
-    -179,   118,   607,     9,  -177,  -178,   359,   404,  -179,  -176,
-     258,   164,    99,   118,   633,   118,   166,   419,   267,   634,
-     361,   363,   508,   118,   369,  -180,   365,   118,  -177,  -178,
-     373,   211,   211,  -176,   211,   211,  -177,  -178,   148,   379,
-     375,  -176,   484,   381,   383,   546,   638,   118,   118,  -180,
-      12,   406,    10,    11,   482,   481,     9,  -180,   484,   485,
-     483,   229,   385,   393,     9,    32,   232,    79,   165,   387,
-     482,   481,     9,    32,     9,   485,   483,   236,   616,   395,
-     164,   112,    35,   400,   112,   166,   402,    37,   129,   417,
-     112,   173,   414,   332,   333,   420,   113,   433,   147,   151,
-     278,    47,    48,     9,   229,    10,    11,   318,    51,   232,
-     289,   118,   151,    10,    11,   178,   255,   215,   118,   217,
-     219,    10,    11,    10,    11,   186,   446,   118,   447,   190,
-     448,   449,   515,   450,   195,   196,   197,   198,    61,   460,
-     465,   521,   468,   471,   665,   484,   523,   469,   470,   345,
-      64,   256,    10,    11,   229,   345,   345,   482,   481,   232,
-     472,   118,   485,   483,   487,    10,    11,   492,   380,   495,
-     505,   507,   236,   244,   510,   512,   514,   522,   531,   528,
-     532,   112,   533,   526,   435,   530,   535,   112,   555,   147,
-     341,   536,   557,   151,   565,   165,   558,   569,   574,   571,
-    -157,   138,   464,   576,   578,   579,   582,   164,    37,   584,
-     593,   118,   166,   161,   118,   484,   170,   113,   151,   597,
-     598,   599,    47,    48,     9,  -158,   600,   482,   481,    51,
-     601,   606,   485,   483,   605,   602,   225,   604,   608,   610,
-      37,   617,   629,   631,   644,   632,   319,   645,   439,   113,
-     651,   652,    79,   115,    47,    48,     9,   653,   350,   226,
-     661,    51,   654,   655,    66,   281,    32,   107,   225,   244,
-     630,    64,   345,    10,    11,   282,   658,   581,   591,   345,
-     364,   592,   371,   124,   118,   115,   405,   345,   372,   285,
-     506,   226,   494,   477,    91,   244,    79,   291,   353,   575,
-     444,   445,   564,    64,   178,    10,    11,   282,   181,   182,
-     183,   540,   640,   185,   186,   187,   188,   637,   190,   191,
-     192,   193,   194,   195,   196,   197,   198,   151,   293,   294,
-     295,   296,   560,   297,   298,   299,     0,   300,   301,   302,
-     303,   304,   305,   306,   307,   308,   309,   310,   311,   312,
-     313,     0,   161,     0,   320,   352,   323,     0,     0,     0,
-     138,   138,   334,     0,     0,     0,     0,    79,     0,     0,
-     227,   233,   234,     0,     0,     0,     0,     0,   345,     0,
-       0,     0,     0,     0,   544,   345,     0,   345,   455,     0,
-       0,   335,     0,   262,     0,    37,   345,     0,   345,   350,
-     336,   277,     0,     0,   113,   337,   338,   339,   283,    47,
-      48,     9,   340,     0,     0,     0,    51,     0,   244,   341,
-     479,     0,     0,   114,     0,   491,     0,     0,   244,     0,
-     112,   292,     0,   138,     0,     0,   342,     0,   112,     0,
-     115,     0,   112,   138,     0,   147,   116,   151,   343,     0,
-       0,     0,     0,     0,   344,     0,     0,    11,    64,     0,
-      10,    11,   151,     0,     0,     0,   422,     0,     0,     0,
-     161,     0,     0,     0,     0,     0,   422,     0,     0,     0,
-       0,     0,   362,    79,    79,     0,     0,   345,     0,     0,
-       0,   350,   543,     0,   550,   345,     0,     0,   370,   455,
-       0,     0,   345,     0,     0,   455,     0,     0,   563,   350,
-       0,     0,     0,     0,     0,     0,     0,     0,    79,   138,
-     138,     0,     0,   244,     0,     0,     0,     0,   398,     0,
-       0,   178,     0,     0,     0,   345,     0,     0,   544,   345,
-     409,   186,     0,   415,   416,   190,   191,   192,   193,   194,
-     195,   196,   197,   198,     0,     0,     0,     0,   138,     0,
-       0,     0,     0,   176,  -276,     0,     0,     0,     0,     0,
-       0,     0,   138,     0,     0,     0,     0,     0,     0,     0,
-     161,     0,     0,     0,     0,   170,     0,     0,     0,   345,
-       0,   345,   177,   178,     0,   179,   180,   181,   182,   183,
-       0,   184,   185,   186,   187,   188,   189,   190,   191,   192,
-     193,   194,   195,   196,   197,   198,   244,   409,     0,     0,
-       0,     0,    79,     0,  -276,     0,   567,   568,     0,   151,
-       0,     0,     0,     0,  -276,     0,     0,     0,     0,     0,
-       0,     0,     0,   496,   350,     0,   543,     0,     0,   161,
-     550,   455,     0,     0,     0,   350,   350,     0,     0,     0,
-       0,     0,     0,   227,   516,     0,     0,     0,     0,   422,
-       0,     0,     0,     0,     0,     0,   422,   589,   422,    -2,
+     121,   120,   162,   274,   175,   123,   122,   322,   491,   325,
+     361,   280,   165,   543,   276,   237,   104,   574,   558,   174,
+     242,   237,   379,   439,   164,   227,   233,   234,   261,   166,
+     108,   237,   436,   110,   460,   142,   110,   378,   429,   208,
+     101,   388,   132,   139,  -184,   505,  -268,     5,   263,   134,
+     396,  -268,   369,   511,   392,   394,   278,   118,   403,    27,
+    -216,  -180,   405,   284,   431,     4,   383,   205,  -183,   441,
+     438,    27,   420,   207,     7,   442,  -184,   229,   229,   229,
+       9,   135,   232,   232,   232,  -180,   293,  -237,    15,   102,
+     206,   229,     9,  -180,  -216,   393,   232,   659,    18,   209,
+     229,  -268,   430,   461,   622,   232,   223,  -268,   229,   210,
+     175,   165,   370,   232,    19,   229,   103,   564,  -182,    29,
+     232,   241,   210,   164,   134,   291,  -216,    28,   166,    10,
+      11,    29,   637,   259,   118,   118,   118,   363,   229,   268,
+     499,    10,    11,   232,   327,   500,  -237,   382,   118,   384,
+     540,   165,  -237,   441,   372,    27,   135,   118,   454,   490,
+     582,   623,   383,   164,    20,   118,   638,    26,   166,    23,
+     643,   495,   118,   529,   658,   531,     9,   644,   645,     9,
+     504,   200,   506,   213,   400,   201,   664,   229,   665,   229,
+      33,   454,   232,   202,   232,   118,   411,   391,    11,   417,
+     418,   501,   333,   334,    93,   455,   229,   106,   229,   359,
+     539,   232,     9,   232,   229,    29,   611,   585,   137,   232,
+     519,   624,   625,   109,   589,    10,    11,   526,    10,    11,
+     172,   626,   199,   628,   629,  -154,   229,  -267,   455,     9,
+     536,   232,  -267,   203,   118,   568,   118,   456,   413,   412,
+     499,   229,   229,   415,   414,   500,   232,   232,   641,   237,
+     433,    10,    11,   118,   478,   118,   572,   515,     9,   237,
+     165,   118,   513,   411,   492,   275,   406,   204,  -183,   261,
+      11,   465,   164,  -178,   347,     9,   421,   166,    10,    11,
+     357,   358,  -267,   118,  -182,   668,   466,   125,  -267,  -179,
+     498,   131,   126,   587,   279,   118,   126,  -178,   118,   118,
+     216,   630,     9,   596,    94,  -178,   256,    10,    11,   597,
+     227,   518,    95,  -179,   220,   229,    96,   221,   486,   224,
+     232,  -179,   235,   652,    10,    11,    97,    98,   229,   256,
+     484,   483,   251,   232,   252,   487,   485,   128,   229,   627,
+     256,   257,   229,   232,     9,   210,   523,   232,   287,   620,
+     258,    10,    11,   333,   334,    10,    11,   264,   265,    99,
+     441,   532,   229,   229,   266,   288,   598,   232,   232,   265,
+     441,   165,   118,   267,   259,   266,   617,   355,    10,    11,
+     290,   289,   268,   164,   635,   118,   510,   118,   166,    10,
+      11,   636,   517,    10,    11,   118,   356,   211,   211,   118,
+     211,   211,   360,   362,   364,   453,   525,   367,   215,     9,
+     217,   219,   371,   464,   486,     9,   375,   377,   381,   118,
+     118,   383,    12,   385,   588,   387,   484,   483,     9,   395,
+     486,   487,   485,   229,   389,   397,   402,    32,   232,    79,
+     165,   404,   484,   483,   144,    32,   408,   487,   485,   237,
+     148,   416,   164,   112,   618,  -177,   112,   166,    10,    11,
+     129,   419,   112,   173,    10,    11,   422,   448,   435,     9,
+     147,   151,   449,   451,   450,   452,   229,    10,    11,  -177,
+     462,   232,   473,   118,   151,   467,   470,  -177,   471,   256,
+     118,   472,   512,   153,   154,   155,   156,   157,   158,   118,
+     167,   168,   474,   489,   319,   541,   494,   382,  -181,   497,
+     507,   548,   551,   523,   556,   346,   667,   486,    10,    11,
+     509,   346,   346,   561,   257,   563,   229,   178,   514,   484,
+     483,   232,  -181,   118,   487,   485,   516,   186,    10,    11,
+    -181,   190,   524,   342,   237,   245,   195,   196,   197,   198,
+     528,   530,   437,   112,   533,    35,   534,   532,   535,   112,
+      37,   147,   537,   538,   557,   151,   559,   165,   567,   113,
+     576,   560,   466,   571,    47,    48,     9,   573,   578,   164,
+     580,    51,   581,   118,   166,   584,   118,   486,   586,   595,
+     151,   599,   336,   600,  -158,   601,  -159,   153,   157,   484,
+     483,   337,   602,   603,   487,   485,   338,   339,   340,   607,
+     604,    61,   606,   341,   605,   608,   610,   612,   320,   619,
+     342,   631,   609,    64,    79,    10,    11,   633,   634,   646,
+     351,   647,   441,   654,   653,   655,   656,   343,    32,   346,
+     657,   245,   663,   176,  -277,   107,   346,    66,   660,   344,
+     632,   583,   365,   593,   346,   345,   118,   594,    11,   373,
+     407,   124,   354,   374,   508,   548,   640,   496,   245,    79,
+      91,   479,   177,   178,   286,   179,   180,   181,   182,   183,
+     577,   184,   185,   186,   187,   188,   189,   190,   191,   192,
+     193,   194,   195,   196,   197,   198,   336,   446,   566,   642,
+     151,   138,   542,   639,  -277,   337,   447,   562,     0,     0,
+     338,   339,   340,   161,  -277,     0,   170,   341,   353,     0,
+       0,     0,     0,     0,   443,     0,     0,     0,     0,     0,
+      35,     0,     0,     0,     0,    37,     0,     0,   169,     0,
+      79,   343,     0,     0,   113,     0,   346,   444,     0,    47,
+      48,     9,   546,   346,     0,   346,    51,     0,     0,   345,
+       0,   457,    11,    55,   346,     0,   346,     0,     0,     0,
+       0,     0,   351,     0,     0,     0,    56,    57,     0,    58,
+      59,     0,     0,    60,     0,     0,    61,     0,     0,     0,
+       0,     0,   245,     0,   481,     0,    62,    63,    64,   493,
+      10,    11,   245,     0,   112,     0,     0,     0,     0,     0,
+       0,     0,   112,     0,     0,     0,   112,     0,     0,   147,
+       0,   151,     0,     0,     0,     0,     0,     0,   294,   295,
+     296,   297,     0,   298,   299,   300,   151,   301,   302,   303,
+     304,   305,   306,   307,   308,   309,   310,   311,   312,   313,
+     314,     0,   161,     0,   321,   346,   324,    79,    79,     0,
+     138,   138,   335,   346,     0,   351,   545,     0,   552,     0,
+     346,     0,     0,   457,     0,    35,     0,     0,     0,   457,
+      37,     0,   565,   351,     0,     0,     0,     0,   366,   113,
+       0,     0,    79,     0,    47,    48,     9,   245,   236,     0,
+       0,    51,     0,   346,     0,     0,   546,   346,    55,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,    56,    57,     0,    58,    59,     0,     0,    60,     0,
+       0,    61,     0,     0,   138,     0,     0,     0,     0,     0,
+       0,    62,    63,    64,   138,    10,    11,    37,     0,     0,
+       0,     0,     0,     0,     0,     0,   113,   346,     0,   346,
+       0,    47,    48,     9,     0,     0,     0,   424,    51,     0,
+       0,   161,    37,     0,     0,   225,     0,   424,     0,     0,
+       0,   113,     0,     0,     0,     0,    47,    48,     9,     0,
+     245,     0,   115,    51,     0,     0,    79,     0,   226,     0,
+     114,     0,     0,   151,   282,     0,     0,     0,     0,     0,
+      64,     0,    10,    11,   283,     0,     0,   115,   351,     0,
+     545,   138,   138,   116,   552,   457,     0,     0,     0,   351,
+     351,     0,     0,     0,     0,    64,     0,    10,    11,    -2,
       34,     0,    35,     0,     0,    36,     0,    37,    38,    39,
        0,     0,    40,     0,    41,    42,    43,    44,    45,    46,
-       0,    47,    48,     9,     0,     0,    49,    50,    51,    52,
-      53,    54,     0,     0,     0,    55,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,    56,    57,
+     138,    47,    48,     9,     0,     0,    49,    50,    51,    52,
+      53,    54,     0,     0,   138,    55,     0,     0,     0,     0,
+       0,     0,   161,     0,     0,     0,     0,   170,    56,    57,
        0,    58,    59,     0,     0,    60,     0,     0,    61,     0,
-       0,   -24,     0,     0,     0,     0,   170,     0,    62,    63,
-      64,     0,    10,    11,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,   648,   649,     0,   161,   586,     0,     0,
-       0,   325,     0,    35,     0,   422,    36,  -251,    37,    38,
-      39,     0,  -251,    40,     0,    41,    42,   113,    44,    45,
-      46,     0,    47,    48,     9,     0,     0,    49,    50,    51,
-      52,    53,    54,     0,     0,     0,    55,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,     0,    56,
-      57,     0,    58,    59,     0,     0,    60,     0,     0,    61,
-       0,     0,  -251,     0,     0,     0,     0,   326,  -251,    62,
-      63,    64,     0,    10,    11,   325,     0,    35,     0,     0,
-      36,     0,    37,    38,    39,     0,     0,    40,     0,    41,
-      42,   113,    44,    45,    46,     0,    47,    48,     9,     0,
-       0,    49,    50,    51,    52,    53,    54,     0,     0,     0,
-      55,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,    56,    57,     0,    58,    59,     0,     0,
-      60,     0,    35,    61,     0,     0,  -251,    37,     0,     0,
-     169,   326,  -251,    62,    63,    64,   113,    10,    11,     0,
-       0,    47,    48,     9,     0,     0,     0,     0,    51,     0,
-       0,     0,     0,     0,     0,    55,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,    35,     0,     0,    56,    57,
-      37,    58,    59,     0,     0,    60,     0,     0,    61,   113,
-       0,     0,     0,     0,    47,    48,     9,     0,    62,    63,
-      64,    51,    10,    11,     0,     0,     0,     0,   159,     0,
+       0,   -24,     0,     0,   178,     0,     0,     0,    62,    63,
+      64,     0,    10,    11,   186,     0,     0,     0,   190,   191,
+     192,   193,   194,   195,   196,   197,   198,     0,   569,   570,
+       0,     0,     0,     0,     0,     0,     0,     0,   326,     0,
+      35,     0,     0,    36,  -252,    37,    38,    39,     0,  -252,
+      40,   161,    41,    42,   113,    44,    45,    46,     0,    47,
+      48,     9,     0,     0,    49,    50,    51,    52,    53,    54,
+       0,   424,     0,    55,     0,     0,     0,     0,   424,   591,
+     424,     0,     0,     0,     0,     0,    56,    57,     0,    58,
+      59,     0,     0,    60,     0,     0,    61,     0,     0,  -252,
+       0,     0,     0,     0,   327,  -252,    62,    63,    64,     0,
+      10,    11,     0,     0,     0,     0,   326,     0,    35,     0,
+       0,    36,     0,    37,    38,    39,     0,     0,    40,     0,
+      41,    42,   113,    44,    45,    46,     0,    47,    48,     9,
+       0,     0,    49,    50,    51,    52,    53,    54,   170,     0,
+       0,    55,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,    56,    57,     0,    58,    59,     0,
+       0,    60,     0,     0,    61,   650,   651,  -252,   161,     0,
+       0,     0,   327,  -252,    62,    63,    64,   424,    10,    11,
+      35,     0,     0,     0,     0,    37,     0,     0,     0,     0,
+       0,     0,     0,     0,   113,     0,   336,     0,     0,    47,
+      48,     9,     0,     0,     0,   337,    51,     0,     0,     0,
+     338,   339,   340,   159,     0,     0,     0,   341,     0,     0,
+       0,     0,     0,     0,   342,     0,    56,    57,     0,    58,
+     160,     0,     0,    60,     0,    35,    61,   316,     0,     0,
+      37,   343,     0,     0,     0,     0,    62,    63,    64,   113,
+      10,    11,     0,     0,    47,    48,     9,     0,     0,   345,
+       0,    51,    11,     0,     0,     0,     0,     0,    55,     0,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,    56,    57,     0,    58,   160,     0,     0,    60,     0,
-      35,    61,   315,     0,     0,    37,     0,     0,     0,     0,
+       0,    56,    57,     0,    58,    59,     0,     0,    60,     0,
+      35,    61,     0,     0,     0,    37,     0,     0,     0,   423,
        0,    62,    63,    64,   113,    10,    11,     0,     0,    47,
-      48,     9,     0,     0,     0,     0,    51,     0,     0,     0,
-       0,     0,     0,    55,     0,     0,     0,     0,     0,     0,
+      48,     9,     0,     0,     0,     0,    51,     0,   432,     0,
+       0,     0,     0,   159,     0,     0,     0,     0,     0,     0,
        0,     0,     0,     0,     0,     0,    56,    57,     0,    58,
-      59,     0,     0,    60,     0,    35,    61,     0,     0,     0,
-      37,     0,     0,     0,   421,     0,    62,    63,    64,   113,
-      10,    11,     0,     0,    47,    48,     9,     0,     0,     0,
-       0,    51,     0,   430,     0,     0,     0,     0,   159,     0,
+     160,     0,     0,    60,     0,    35,    61,     0,     0,     0,
+      37,     0,     0,     0,     0,     0,    62,    63,    64,   113,
+      10,    11,     0,     0,    47,    48,     9,     0,   476,     0,
+       0,    51,     0,     0,     0,     0,     0,     0,    55,     0,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,    56,    57,     0,    58,   160,     0,     0,    60,     0,
+       0,    56,    57,     0,    58,    59,     0,     0,    60,     0,
       35,    61,     0,     0,     0,    37,     0,     0,     0,     0,
        0,    62,    63,    64,   113,    10,    11,     0,     0,    47,
-      48,     9,     0,   474,     0,     0,    51,     0,     0,     0,
+      48,     9,     0,   477,     0,     0,    51,     0,     0,     0,
        0,     0,     0,    55,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,    56,    57,     0,    58,
-      59,     0,     0,    60,     0,    35,    61,     0,     0,     0,
-      37,     0,     0,     0,     0,     0,    62,    63,    64,   113,
-      10,    11,     0,     0,    47,    48,     9,     0,   475,     0,
-       0,    51,     0,     0,     0,     0,     0,     0,    55,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,    35,     0,
-       0,    56,    57,    37,    58,    59,     0,     0,    60,     0,
-       0,    61,   113,     0,     0,     0,     0,    47,    48,     9,
-       0,    62,    63,    64,    51,    10,    11,     0,     0,     0,
+       0,     0,     0,    35,     0,     0,    56,    57,    37,    58,
+      59,     0,     0,    60,     0,     0,    61,   113,     0,     0,
+       0,     0,    47,    48,     9,     0,    62,    63,    64,    51,
+      10,    11,     0,     0,     0,     0,    55,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,    56,
+      57,     0,    58,    59,     0,     0,    60,     0,    35,    61,
+       0,     0,     0,    37,     0,     0,     0,   590,     0,    62,
+      63,    64,   113,    10,    11,     0,     0,    47,    48,     9,
+       0,     0,     0,     0,    51,     0,     0,     0,     0,     0,
        0,    55,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,    56,    57,     0,    58,    59,     0,
-       0,    60,     0,    35,    61,     0,     0,     0,    37,     0,
-       0,     0,   588,     0,    62,    63,    64,   113,    10,    11,
-       0,     0,    47,    48,     9,     0,     0,     0,     0,    51,
-       0,     0,     0,     0,     0,     0,    55,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,    35,     0,     0,    56,
-      57,    37,    58,    59,     0,     0,    60,     0,     0,    61,
-     113,     0,     0,     0,     0,    47,    48,     9,     0,    62,
-      63,    64,    51,    10,    11,     0,     0,     0,     0,   159,
-       0,     0,     0,     0,     0,     0,     0,     0,     0,    35,
-       0,     0,    56,    57,   284,    58,   160,     0,     0,    60,
-       0,     0,    61,   113,     0,     0,     0,     0,    47,    48,
-       9,     0,    62,    63,    64,    51,    10,    11,     0,     0,
-       0,     0,    55,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,    56,    57,    37,    58,    59,
-       0,     0,    60,     0,     0,    61,   113,     0,     0,     0,
-       0,    47,    48,     9,     0,    62,    63,    64,    51,    10,
-      11,     0,     0,    37,     0,   225,   242,     0,     0,     0,
-       0,    37,   113,     0,     0,     0,     0,    47,    48,     9,
-     113,     0,   115,     0,    51,    47,    48,     9,   226,     0,
-       0,   225,    51,     0,     0,     0,    37,     0,     0,   225,
-      64,     0,    10,    11,   397,   113,     0,     0,   115,     0,
-      47,    48,     9,     0,   226,     0,   115,    51,     0,     0,
-       0,     0,   226,     0,   407,     0,    64,     0,    10,    11,
-      37,     0,     0,     0,    64,     0,    10,    11,     0,   113,
-       0,   115,     0,     0,    47,    48,     9,   408,     0,     0,
-       0,    51,     0,     0,     0,   284,     0,     0,   225,    64,
-       0,    10,    11,   335,   113,     0,     0,     0,     0,    47,
-      48,     9,   336,     0,     0,   115,    51,   337,   338,   339,
-       0,   478,     0,   225,   340,     0,     0,     0,     0,   335,
-       0,   441,   461,    64,     0,    10,    11,     0,   336,     0,
-     115,     0,     0,   337,   338,   339,   226,     0,   342,     0,
-     340,     0,     0,     0,   442,     0,   335,   341,    64,     0,
-      10,    11,     0,     0,     0,   336,   344,     0,     0,    11,
-     337,   338,   542,     0,   342,     0,     0,   340,     0,     0,
-       0,     0,   335,     0,   341,     0,     0,     0,     0,     0,
-     335,   336,   344,     0,     0,    11,   337,   338,   339,   336,
-       0,   342,     0,   340,   337,   338,   339,     0,     0,     0,
-     341,   340,     0,     0,     0,     0,     0,     0,   341,   344,
-       0,    10,    11,     0,     0,     0,     0,   342,     0,     0,
-       0,     0,     0,   611,     0,   342,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,   344,     0,     0,    11,     0,
-       0,     0,     0,   344,   177,   178,    11,   179,     0,   181,
+       0,    35,     0,     0,    56,    57,    37,    58,    59,     0,
+       0,    60,     0,     0,    61,   113,     0,     0,     0,     0,
+      47,    48,     9,     0,    62,    63,    64,    51,    10,    11,
+       0,     0,     0,     0,   159,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,    35,     0,     0,    56,    57,   285,
+      58,   160,     0,     0,    60,     0,     0,    61,   113,     0,
+       0,     0,     0,    47,    48,     9,     0,    62,    63,    64,
+      51,    10,    11,     0,     0,     0,     0,    55,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+      56,    57,    37,    58,    59,     0,     0,    60,     0,     0,
+      61,   113,     0,     0,     0,     0,    47,    48,     9,     0,
+      62,    63,    64,    51,    10,    11,     0,    37,     0,     0,
+     225,     0,     0,     0,     0,    37,   113,     0,   243,     0,
+       0,    47,    48,     9,   113,     0,     0,   115,    51,    47,
+      48,     9,     0,   226,     0,   225,    51,     0,     0,   292,
+       0,    37,     0,   225,     0,    64,     0,    10,    11,   283,
+     113,     0,   115,     0,     0,    47,    48,     9,   226,     0,
+     115,     0,    51,     0,     0,     0,   226,     0,    37,   225,
+      64,     0,    10,    11,   399,     0,     0,   113,    64,     0,
+      10,    11,    47,    48,     9,     0,   115,     0,     0,    51,
+       0,     0,   226,     0,    37,     0,   409,     0,     0,     0,
+       0,     0,   285,   113,    64,     0,    10,    11,    47,    48,
+       9,   113,     0,   115,     0,    51,    47,    48,     9,   410,
+       0,     0,   225,    51,     0,     0,     0,   336,     0,     0,
+     225,    64,     0,    10,    11,   336,   337,     0,   463,   115,
+       0,   338,   339,   544,   337,   480,     0,   115,   341,   338,
+     339,   340,     0,   226,     0,   342,   341,    64,     0,    10,
+      11,   336,     0,   342,     0,    64,     0,    10,    11,     0,
+     337,     0,   343,     0,     0,   338,   339,   340,     0,     0,
+     343,     0,   341,     0,     0,     0,     0,     0,     0,   342,
+     345,     0,    10,    11,     0,     0,     0,     0,   345,   178,
+       0,    11,     0,   181,   182,   183,   343,     0,   185,   186,
+     187,   188,   613,   190,   191,   192,   193,   194,   195,   196,
+     197,   198,     0,     0,   345,   177,   178,    11,   179,     0,
+     181,   182,   183,     0,     0,   185,   186,   187,   188,   189,
+     190,   191,   192,   193,   194,   195,   196,   197,   198,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,   177,   178,
+       0,   179,     0,   181,   182,   183,     0,   437,   185,   186,
+     187,   188,   189,   190,   191,   192,   193,   194,   195,   196,
+     197,   198,     0,     0,     0,     0,     0,     0,   177,   178,
+       0,   179,     0,   181,   182,   183,     0,   434,   185,   186,
+     187,   188,   189,   190,   191,   192,   193,   194,   195,   196,
+     197,   198,   177,   178,     0,   179,     0,   181,   182,   183,
+       0,   527,   185,   186,   187,   188,   189,   190,   191,   192,
+     193,   194,   195,   196,   197,   198,   177,   178,     0,   179,
+       0,   181,   182,   183,     0,   661,   185,   186,   187,   188,
+     189,   190,   191,   192,   193,   194,   195,   196,   197,   198,
+     177,   178,     0,   179,     0,   181,   182,   183,     0,   662,
+     185,   186,   187,   188,   189,   190,   191,   192,   193,   194,
+     195,   196,   197,   198,   177,   178,     0,     0,     0,   181,
      182,   183,     0,     0,   185,   186,   187,   188,   189,   190,
-     191,   192,   193,   194,   195,   196,   197,   198,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,   177,   178,     0,
-     179,     0,   181,   182,   183,     0,   435,   185,   186,   187,
-     188,   189,   190,   191,   192,   193,   194,   195,   196,   197,
-     198,     0,     0,     0,     0,     0,     0,   177,   178,     0,
-     179,     0,   181,   182,   183,     0,   432,   185,   186,   187,
-     188,   189,   190,   191,   192,   193,   194,   195,   196,   197,
-     198,   177,   178,     0,   179,     0,   181,   182,   183,     0,
-     525,   185,   186,   187,   188,   189,   190,   191,   192,   193,
-     194,   195,   196,   197,   198,   177,   178,     0,   179,     0,
-     181,   182,   183,     0,   659,   185,   186,   187,   188,   189,
-     190,   191,   192,   193,   194,   195,   196,   197,   198,   177,
-     178,     0,   179,     0,   181,   182,   183,     0,   660,   185,
-     186,   187,   188,   189,   190,   191,   192,   193,   194,   195,
-     196,   197,   198,   177,   178,     0,     0,     0,   181,   182,
-     183,     0,     0,   185,   186,   187,   188,   189,   190,   191,
-     192,   193,   194,   195,   196,   197,   198,   177,   178,     0,
-       0,     0,   181,   182,   183,     0,     0,   185,   186,   187,
-     188,     0,   190,   191,   192,   193,   194,   195,   196,   197,
-     198
+     191,   192,   193,   194,   195,   196,   197,   198,   177,   178,
+       0,     0,     0,   181,   182,   183,     0,     0,   185,   186,
+     187,   188,     0,   190,   191,   192,   193,   194,   195,   196,
+     197,   198
 };
 
 static const yytype_int16 yycheck[] =
 {
-      37,    37,    61,   143,    67,    37,    37,   202,   324,   251,
-     378,   205,    61,    28,   487,   127,   127,   136,   259,   224,
-     144,   133,   322,   148,    61,   454,   446,   268,    31,    61,
-       3,   143,   317,   264,   265,   276,   212,     5,   323,   280,
-      67,    36,   218,   219,    39,   250,    24,    59,     0,   290,
-      45,     1,     5,    25,     3,     1,    20,    37,    35,     3,
-      25,    24,    74,    11,     3,    55,    56,    57,    58,    59,
-      60,     7,    62,    63,    62,    24,    12,   114,   115,   116,
-      24,    62,   114,   115,   116,    35,    62,    68,     7,    35,
-      67,   128,    68,    12,     5,    73,   128,    65,    66,    72,
-     137,   574,     3,    67,   107,   137,    21,    75,   145,    59,
-     173,   160,    65,   145,    63,   152,    60,    67,    51,    63,
-     152,    67,    75,   160,    73,    74,    62,    75,   160,    73,
-      74,    24,    68,    63,   114,   115,   116,   256,   175,   439,
-     425,   136,   427,   175,    62,   390,   173,   142,   128,    68,
-      83,   200,     3,   398,    65,    49,    89,   137,   389,     3,
-     391,    62,    63,   200,    75,   145,   342,    68,   200,   159,
-     160,   644,   152,    24,   350,    24,    24,   606,   383,   599,
-      24,     7,    66,   598,    62,    60,    12,   224,    72,   226,
-     610,   611,   224,     7,   226,   175,   438,    24,    12,    50,
-      75,   517,     3,    62,    53,   242,   221,   244,   524,    68,
-     242,    59,   244,   250,     3,    59,    71,   462,   250,    63,
-     414,    62,    73,    74,    67,    73,    74,   421,     3,    73,
-      74,   473,    59,   127,    66,   272,    62,   652,   433,   654,
-     272,    66,    68,    59,   224,    24,   226,   284,   284,    24,
-     287,   288,   284,   284,    68,   287,   288,   369,   369,   318,
-     505,    24,   242,    59,   244,   441,   385,   379,   379,   318,
-     250,   447,   448,   478,   450,    50,   400,   402,    59,   520,
-      59,   318,    24,   459,    59,   461,   318,    40,    35,    68,
-      53,    44,   272,    24,    73,    74,    59,   665,    73,    74,
-      62,    74,    62,    64,   284,    68,    68,   287,   288,    59,
-      73,    74,    59,    24,   208,   209,   561,   633,    24,    40,
-      67,    59,    63,    44,   361,    35,   375,    67,    24,   361,
-      75,    73,    74,   578,   579,   577,   373,     9,   375,   375,
-      60,   373,    53,   375,   375,    17,   383,    72,    59,    21,
-     387,   383,    59,    59,   417,   387,    35,    72,   603,    31,
-      32,    59,    73,    74,    60,    63,   571,    73,    74,   428,
-     407,   408,     3,    71,   550,   407,   408,    73,    74,   428,
-      59,   361,   558,    24,    35,    35,    60,   281,    67,    35,
-     385,   428,    64,   373,   588,   375,   428,   291,   393,   594,
-       8,    60,   397,   383,    62,    35,    35,   387,    59,    59,
-      75,    94,    95,    59,    97,    98,    67,    67,    59,    62,
-      60,    67,   471,    24,    59,   601,   602,   407,   408,    59,
-       5,    65,    73,    74,   471,   471,    24,    67,   487,   471,
-     471,   478,    62,    62,    24,    20,   478,    22,   497,    72,
-     487,   487,    24,    28,    24,   487,   487,   569,   569,     3,
-     497,    36,     3,    62,    39,   497,    62,     8,    43,    62,
-      45,    59,    67,   367,   368,    65,    17,    66,    53,    54,
-      60,    22,    23,    24,   521,    73,    74,    59,    29,   521,
-      60,   471,    67,    73,    74,    34,    24,    95,   478,    97,
-      98,    73,    74,    73,    74,    44,    59,   487,    67,    48,
-      71,    67,   406,     8,    53,    54,    55,    56,    59,    65,
-      62,   584,    62,    60,   664,   574,   420,    62,    62,   212,
-      71,    59,    73,    74,   571,   218,   219,   574,   574,   571,
-      60,   521,   574,   574,    60,    73,    74,    60,    63,    68,
-      60,    68,   664,   128,    35,    60,    60,    60,    60,    68,
-      60,   136,    60,    75,    75,   624,    60,   142,     3,   144,
-      36,    68,    62,   148,    60,   624,    72,    62,    60,    59,
-      59,    49,    75,    66,    60,    60,    60,   624,     8,    62,
-      60,   571,   624,    61,   574,   644,    64,    17,   173,    60,
-      60,    59,    22,    23,    24,    59,    68,   644,   644,    29,
-      62,    49,   644,   644,    62,    72,    36,    68,    62,    59,
-       8,    60,    68,    60,    60,    68,   201,    14,    62,    17,
-      72,    60,   207,    53,    22,    23,    24,    60,   213,    59,
-      68,    29,    60,    60,    22,    65,   221,    31,    36,   224,
-     584,    71,   335,    73,    74,    75,   645,   510,   526,   342,
-     235,   526,   244,    39,   644,    53,   282,   350,   244,   160,
-     393,    59,   385,   373,    22,   250,   251,    65,   214,   497,
-     335,   335,   464,    71,    34,    73,    74,    75,    38,    39,
-      40,   442,   605,    43,    44,    45,    46,   601,    48,    49,
-      50,    51,    52,    53,    54,    55,    56,   282,   176,   177,
-     178,   179,   460,   181,   182,   183,    -1,   185,   186,   187,
+      37,    37,    61,   143,    67,    37,    37,   202,   380,   205,
+     224,   148,    61,   448,   144,   127,    28,   489,   456,    67,
+     127,   133,   252,   325,    61,   114,   115,   116,   136,    61,
+      31,   143,   323,    36,     3,    51,    39,   251,    11,     5,
+      24,   260,    45,    49,    35,   392,     7,    25,   137,    35,
+     269,    12,     5,   400,   265,   266,   145,    37,   277,     3,
+       1,    35,   281,   152,   318,     0,    24,    83,    59,    62,
+     324,     3,   291,    89,    25,    68,    67,   114,   115,   116,
+      24,    67,   114,   115,   116,    59,   175,     3,    24,    73,
+       1,   128,    24,    67,    35,    53,   128,    20,     3,    65,
+     137,    62,    75,    72,   576,   137,   107,    68,   145,    75,
+     173,   160,    65,   145,    62,   152,    60,   464,    59,    63,
+     152,   127,    75,   160,    35,   173,    67,    59,   160,    73,
+      74,    63,   600,   136,   114,   115,   116,   226,   175,   142,
+       7,    73,    74,   175,    67,    12,    62,    63,   128,   257,
+     441,   200,    68,    62,   243,     3,    67,   137,     3,    68,
+     507,     5,    24,   200,    21,   145,   601,    63,   200,    24,
+     608,   385,   152,   427,   646,   429,    24,   612,   613,    24,
+     391,    59,   393,    59,   273,    63,   654,   224,   656,   226,
+      62,     3,   224,    71,   226,   175,   285,    59,    74,   288,
+     289,    68,   208,   209,    62,    50,   243,     3,   245,   221,
+     440,   243,    24,   245,   251,    63,   563,   519,    71,   251,
+     416,    65,    66,     3,   526,    73,    74,   423,    73,    74,
+      62,    75,    67,   580,   581,    66,   273,     7,    50,    24,
+     435,   273,    12,    66,   224,   475,   226,    59,   285,   285,
+       7,   288,   289,   285,   285,    12,   288,   289,   605,   371,
+     319,    73,    74,   243,   371,   245,   480,   404,    24,   381,
+     319,   251,   402,   362,   381,    60,   282,    59,    59,   387,
+      74,    60,   319,    35,   212,    24,   292,   319,    73,    74,
+     218,   219,    62,   273,    59,   667,    75,    40,    68,    35,
+     389,    44,    40,   522,    60,   285,    44,    59,   288,   289,
+      24,    68,    24,    66,     9,    67,    24,    73,    74,    72,
+     409,   410,    17,    59,    64,   362,    21,    62,   377,    59,
+     362,    67,    63,   635,    73,    74,    31,    32,   375,    24,
+     377,   377,    59,   375,    67,   377,   377,    59,   385,   579,
+      24,    59,   389,   385,    24,    75,   419,   389,    60,   573,
+      68,    73,    74,   369,   370,    73,    74,    35,    53,    64,
+      62,   430,   409,   410,    59,    72,    68,   409,   410,    53,
+      62,   430,   362,    68,   387,    59,    68,    59,    73,    74,
+      60,    72,   395,   430,   590,   375,   399,   377,   430,    73,
+      74,   596,   408,    73,    74,   385,     3,    94,    95,   389,
+      97,    98,    60,     8,    60,   343,   422,    35,    95,    24,
+      97,    98,    62,   351,   473,    24,    75,    60,    62,   409,
+     410,    24,     5,    59,   523,    62,   473,   473,    24,    62,
+     489,   473,   473,   480,    72,     3,    62,    20,   480,    22,
+     499,    62,   489,   489,    59,    28,    65,   489,   489,   571,
+      59,    67,   499,    36,   571,    35,    39,   499,    73,    74,
+      43,    62,    45,    59,    73,    74,    65,    59,    66,    24,
+      53,    54,    67,    67,    71,     8,   523,    73,    74,    59,
+      65,   523,    60,   473,    67,    62,    62,    67,    62,    24,
+     480,    62,    35,    55,    56,    57,    58,    59,    60,   489,
+      62,    63,    60,    60,    59,   443,    60,    63,    35,    68,
+      60,   449,   450,   586,   452,   212,   666,   576,    73,    74,
+      68,   218,   219,   461,    59,   463,   573,    34,    60,   576,
+     576,   573,    59,   523,   576,   576,    60,    44,    73,    74,
+      67,    48,    60,    36,   666,   128,    53,    54,    55,    56,
+      75,    68,    75,   136,    60,     3,    60,   626,    60,   142,
+       8,   144,    60,    68,     3,   148,    62,   626,    60,    17,
+      60,    72,    75,    62,    22,    23,    24,    59,    66,   626,
+      60,    29,    60,   573,   626,    60,   576,   646,    62,    60,
+     173,    60,     8,    60,    59,    59,    59,   159,   160,   646,
+     646,    17,    68,    62,   646,   646,    22,    23,    24,    62,
+      72,    59,    68,    29,   552,    49,    62,    59,   201,    60,
+      36,    68,   560,    71,   207,    73,    74,    60,    68,    60,
+     213,    14,    62,    60,    72,    60,    60,    53,   221,   336,
+      60,   224,    68,     4,     5,    31,   343,    22,   647,    65,
+     586,   512,   235,   528,   351,    71,   646,   528,    74,   245,
+     283,    39,   214,   245,   395,   603,   604,   387,   251,   252,
+      22,   375,    33,    34,   160,    36,    37,    38,    39,    40,
+     499,    42,    43,    44,    45,    46,    47,    48,    49,    50,
+      51,    52,    53,    54,    55,    56,     8,   336,   466,   607,
+     283,    49,   444,   603,    65,    17,   336,   462,    -1,    -1,
+      22,    23,    24,    61,    75,    -1,    64,    29,   213,    -1,
+      -1,    -1,    -1,    -1,    36,    -1,    -1,    -1,    -1,    -1,
+       3,    -1,    -1,    -1,    -1,     8,    -1,    -1,    11,    -1,
+     323,    53,    -1,    -1,    17,    -1,   443,    59,    -1,    22,
+      23,    24,   449,   450,    -1,   452,    29,    -1,    -1,    71,
+      -1,   344,    74,    36,   461,    -1,   463,    -1,    -1,    -1,
+      -1,    -1,   355,    -1,    -1,    -1,    49,    50,    -1,    52,
+      53,    -1,    -1,    56,    -1,    -1,    59,    -1,    -1,    -1,
+      -1,    -1,   375,    -1,   377,    -1,    69,    70,    71,   382,
+      73,    74,   385,    -1,   387,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,   395,    -1,    -1,    -1,   399,    -1,    -1,   402,
+      -1,   404,    -1,    -1,    -1,    -1,    -1,    -1,   176,   177,
+     178,   179,    -1,   181,   182,   183,   419,   185,   186,   187,
      188,   189,   190,   191,   192,   193,   194,   195,   196,   197,
-     198,    -1,   200,    -1,   202,   213,   204,    -1,    -1,    -1,
-     208,   209,   210,    -1,    -1,    -1,    -1,   322,    -1,    -1,
-     114,   115,   116,    -1,    -1,    -1,    -1,    -1,   441,    -1,
-      -1,    -1,    -1,    -1,   447,   448,    -1,   450,   343,    -1,
-      -1,     8,    -1,   137,    -1,     8,   459,    -1,   461,   354,
-      17,   145,    -1,    -1,    17,    22,    23,    24,   152,    22,
-      23,    24,    29,    -1,    -1,    -1,    29,    -1,   373,    36,
-     375,    -1,    -1,    36,    -1,   380,    -1,    -1,   383,    -1,
-     385,   175,    -1,   281,    -1,    -1,    53,    -1,   393,    -1,
-      53,    -1,   397,   291,    -1,   400,    59,   402,    65,    -1,
-      -1,    -1,    -1,    -1,    71,    -1,    -1,    74,    71,    -1,
-      73,    74,   417,    -1,    -1,    -1,   314,    -1,    -1,    -1,
-     318,    -1,    -1,    -1,    -1,    -1,   324,    -1,    -1,    -1,
-      -1,    -1,   226,   438,   439,    -1,    -1,   550,    -1,    -1,
-      -1,   446,   447,    -1,   449,   558,    -1,    -1,   242,   454,
-      -1,    -1,   565,    -1,    -1,   460,    -1,    -1,   463,   464,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,   473,   367,
-     368,    -1,    -1,   478,    -1,    -1,    -1,    -1,   272,    -1,
-      -1,    34,    -1,    -1,    -1,   598,    -1,    -1,   601,   602,
-     284,    44,    -1,   287,   288,    48,    49,    50,    51,    52,
-      53,    54,    55,    56,    -1,    -1,    -1,    -1,   406,    -1,
-      -1,    -1,    -1,     4,     5,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,   420,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-     428,    -1,    -1,    -1,    -1,   433,    -1,    -1,    -1,   652,
-      -1,   654,    33,    34,    -1,    36,    37,    38,    39,    40,
-      -1,    42,    43,    44,    45,    46,    47,    48,    49,    50,
-      51,    52,    53,    54,    55,    56,   571,   361,    -1,    -1,
-      -1,    -1,   577,    -1,    65,    -1,   474,   475,    -1,   584,
-      -1,    -1,    -1,    -1,    75,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,   387,   599,    -1,   601,    -1,    -1,   497,
-     605,   606,    -1,    -1,    -1,   610,   611,    -1,    -1,    -1,
-      -1,    -1,    -1,   407,   408,    -1,    -1,    -1,    -1,   517,
-      -1,    -1,    -1,    -1,    -1,    -1,   524,   525,   526,     0,
+     198,    -1,   200,    -1,   202,   552,   204,   440,   441,    -1,
+     208,   209,   210,   560,    -1,   448,   449,    -1,   451,    -1,
+     567,    -1,    -1,   456,    -1,     3,    -1,    -1,    -1,   462,
+       8,    -1,   465,   466,    -1,    -1,    -1,    -1,   236,    17,
+      -1,    -1,   475,    -1,    22,    23,    24,   480,    26,    -1,
+      -1,    29,    -1,   600,    -1,    -1,   603,   604,    36,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    49,    50,    -1,    52,    53,    -1,    -1,    56,    -1,
+      -1,    59,    -1,    -1,   282,    -1,    -1,    -1,    -1,    -1,
+      -1,    69,    70,    71,   292,    73,    74,     8,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    17,   654,    -1,   656,
+      -1,    22,    23,    24,    -1,    -1,    -1,   315,    29,    -1,
+      -1,   319,     8,    -1,    -1,    36,    -1,   325,    -1,    -1,
+      -1,    17,    -1,    -1,    -1,    -1,    22,    23,    24,    -1,
+     573,    -1,    53,    29,    -1,    -1,   579,    -1,    59,    -1,
+      36,    -1,    -1,   586,    65,    -1,    -1,    -1,    -1,    -1,
+      71,    -1,    73,    74,    75,    -1,    -1,    53,   601,    -1,
+     603,   369,   370,    59,   607,   608,    -1,    -1,    -1,   612,
+     613,    -1,    -1,    -1,    -1,    71,    -1,    73,    74,     0,
        1,    -1,     3,    -1,    -1,     6,    -1,     8,     9,    10,
       -1,    -1,    13,    -1,    15,    16,    17,    18,    19,    20,
-      -1,    22,    23,    24,    -1,    -1,    27,    28,    29,    30,
-      31,    32,    -1,    -1,    -1,    36,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    49,    50,
+     408,    22,    23,    24,    -1,    -1,    27,    28,    29,    30,
+      31,    32,    -1,    -1,   422,    36,    -1,    -1,    -1,    -1,
+      -1,    -1,   430,    -1,    -1,    -1,    -1,   435,    49,    50,
       -1,    52,    53,    -1,    -1,    56,    -1,    -1,    59,    -1,
-      -1,    62,    -1,    -1,    -1,    -1,   594,    -1,    69,    70,
-      71,    -1,    73,    74,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,   621,   622,    -1,   624,   521,    -1,    -1,
-      -1,     1,    -1,     3,    -1,   633,     6,     7,     8,     9,
-      10,    -1,    12,    13,    -1,    15,    16,    17,    18,    19,
-      20,    -1,    22,    23,    24,    -1,    -1,    27,    28,    29,
-      30,    31,    32,    -1,    -1,    -1,    36,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    49,
-      50,    -1,    52,    53,    -1,    -1,    56,    -1,    -1,    59,
-      -1,    -1,    62,    -1,    -1,    -1,    -1,    67,    68,    69,
-      70,    71,    -1,    73,    74,     1,    -1,     3,    -1,    -1,
-       6,    -1,     8,     9,    10,    -1,    -1,    13,    -1,    15,
-      16,    17,    18,    19,    20,    -1,    22,    23,    24,    -1,
-      -1,    27,    28,    29,    30,    31,    32,    -1,    -1,    -1,
-      36,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    49,    50,    -1,    52,    53,    -1,    -1,
-      56,    -1,     3,    59,    -1,    -1,    62,     8,    -1,    -1,
-      11,    67,    68,    69,    70,    71,    17,    73,    74,    -1,
-      -1,    22,    23,    24,    -1,    -1,    -1,    -1,    29,    -1,
-      -1,    -1,    -1,    -1,    -1,    36,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,     3,    -1,    -1,    49,    50,
-       8,    52,    53,    -1,    -1,    56,    -1,    -1,    59,    17,
-      -1,    -1,    -1,    -1,    22,    23,    24,    -1,    69,    70,
-      71,    29,    73,    74,    -1,    -1,    -1,    -1,    36,    -1,
+      -1,    62,    -1,    -1,    34,    -1,    -1,    -1,    69,    70,
+      71,    -1,    73,    74,    44,    -1,    -1,    -1,    48,    49,
+      50,    51,    52,    53,    54,    55,    56,    -1,   476,   477,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,     1,    -1,
+       3,    -1,    -1,     6,     7,     8,     9,    10,    -1,    12,
+      13,   499,    15,    16,    17,    18,    19,    20,    -1,    22,
+      23,    24,    -1,    -1,    27,    28,    29,    30,    31,    32,
+      -1,   519,    -1,    36,    -1,    -1,    -1,    -1,   526,   527,
+     528,    -1,    -1,    -1,    -1,    -1,    49,    50,    -1,    52,
+      53,    -1,    -1,    56,    -1,    -1,    59,    -1,    -1,    62,
+      -1,    -1,    -1,    -1,    67,    68,    69,    70,    71,    -1,
+      73,    74,    -1,    -1,    -1,    -1,     1,    -1,     3,    -1,
+      -1,     6,    -1,     8,     9,    10,    -1,    -1,    13,    -1,
+      15,    16,    17,    18,    19,    20,    -1,    22,    23,    24,
+      -1,    -1,    27,    28,    29,    30,    31,    32,   596,    -1,
+      -1,    36,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    49,    50,    -1,    52,    53,    -1,
+      -1,    56,    -1,    -1,    59,   623,   624,    62,   626,    -1,
+      -1,    -1,    67,    68,    69,    70,    71,   635,    73,    74,
+       3,    -1,    -1,    -1,    -1,     8,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    17,    -1,     8,    -1,    -1,    22,
+      23,    24,    -1,    -1,    -1,    17,    29,    -1,    -1,    -1,
+      22,    23,    24,    36,    -1,    -1,    -1,    29,    -1,    -1,
+      -1,    -1,    -1,    -1,    36,    -1,    49,    50,    -1,    52,
+      53,    -1,    -1,    56,    -1,     3,    59,    60,    -1,    -1,
+       8,    53,    -1,    -1,    -1,    -1,    69,    70,    71,    17,
+      73,    74,    -1,    -1,    22,    23,    24,    -1,    -1,    71,
+      -1,    29,    74,    -1,    -1,    -1,    -1,    -1,    36,    -1,
       -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
       -1,    49,    50,    -1,    52,    53,    -1,    -1,    56,    -1,
-       3,    59,    60,    -1,    -1,     8,    -1,    -1,    -1,    -1,
+       3,    59,    -1,    -1,    -1,     8,    -1,    -1,    -1,    67,
       -1,    69,    70,    71,    17,    73,    74,    -1,    -1,    22,
-      23,    24,    -1,    -1,    -1,    -1,    29,    -1,    -1,    -1,
+      23,    24,    -1,    -1,    -1,    -1,    29,    -1,    31,    -1,
       -1,    -1,    -1,    36,    -1,    -1,    -1,    -1,    -1,    -1,
       -1,    -1,    -1,    -1,    -1,    -1,    49,    50,    -1,    52,
       53,    -1,    -1,    56,    -1,     3,    59,    -1,    -1,    -1,
-       8,    -1,    -1,    -1,    67,    -1,    69,    70,    71,    17,
-      73,    74,    -1,    -1,    22,    23,    24,    -1,    -1,    -1,
-      -1,    29,    -1,    31,    -1,    -1,    -1,    -1,    36,    -1,
+       8,    -1,    -1,    -1,    -1,    -1,    69,    70,    71,    17,
+      73,    74,    -1,    -1,    22,    23,    24,    -1,    26,    -1,
+      -1,    29,    -1,    -1,    -1,    -1,    -1,    -1,    36,    -1,
       -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
       -1,    49,    50,    -1,    52,    53,    -1,    -1,    56,    -1,
        3,    59,    -1,    -1,    -1,     8,    -1,    -1,    -1,    -1,
       -1,    69,    70,    71,    17,    73,    74,    -1,    -1,    22,
       23,    24,    -1,    26,    -1,    -1,    29,    -1,    -1,    -1,
       -1,    -1,    -1,    36,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    49,    50,    -1,    52,
-      53,    -1,    -1,    56,    -1,     3,    59,    -1,    -1,    -1,
-       8,    -1,    -1,    -1,    -1,    -1,    69,    70,    71,    17,
-      73,    74,    -1,    -1,    22,    23,    24,    -1,    26,    -1,
-      -1,    29,    -1,    -1,    -1,    -1,    -1,    -1,    36,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,     3,    -1,
-      -1,    49,    50,     8,    52,    53,    -1,    -1,    56,    -1,
-      -1,    59,    17,    -1,    -1,    -1,    -1,    22,    23,    24,
-      -1,    69,    70,    71,    29,    73,    74,    -1,    -1,    -1,
+      -1,    -1,    -1,     3,    -1,    -1,    49,    50,     8,    52,
+      53,    -1,    -1,    56,    -1,    -1,    59,    17,    -1,    -1,
+      -1,    -1,    22,    23,    24,    -1,    69,    70,    71,    29,
+      73,    74,    -1,    -1,    -1,    -1,    36,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    49,
+      50,    -1,    52,    53,    -1,    -1,    56,    -1,     3,    59,
+      -1,    -1,    -1,     8,    -1,    -1,    -1,    67,    -1,    69,
+      70,    71,    17,    73,    74,    -1,    -1,    22,    23,    24,
+      -1,    -1,    -1,    -1,    29,    -1,    -1,    -1,    -1,    -1,
       -1,    36,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    49,    50,    -1,    52,    53,    -1,
-      -1,    56,    -1,     3,    59,    -1,    -1,    -1,     8,    -1,
-      -1,    -1,    67,    -1,    69,    70,    71,    17,    73,    74,
-      -1,    -1,    22,    23,    24,    -1,    -1,    -1,    -1,    29,
-      -1,    -1,    -1,    -1,    -1,    -1,    36,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,     3,    -1,    -1,    49,
-      50,     8,    52,    53,    -1,    -1,    56,    -1,    -1,    59,
-      17,    -1,    -1,    -1,    -1,    22,    23,    24,    -1,    69,
-      70,    71,    29,    73,    74,    -1,    -1,    -1,    -1,    36,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,     3,
-      -1,    -1,    49,    50,     8,    52,    53,    -1,    -1,    56,
-      -1,    -1,    59,    17,    -1,    -1,    -1,    -1,    22,    23,
-      24,    -1,    69,    70,    71,    29,    73,    74,    -1,    -1,
-      -1,    -1,    36,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    49,    50,     8,    52,    53,
-      -1,    -1,    56,    -1,    -1,    59,    17,    -1,    -1,    -1,
-      -1,    22,    23,    24,    -1,    69,    70,    71,    29,    73,
-      74,    -1,    -1,     8,    -1,    36,    11,    -1,    -1,    -1,
-      -1,     8,    17,    -1,    -1,    -1,    -1,    22,    23,    24,
-      17,    -1,    53,    -1,    29,    22,    23,    24,    59,    -1,
-      -1,    36,    29,    -1,    -1,    -1,     8,    -1,    -1,    36,
-      71,    -1,    73,    74,    75,    17,    -1,    -1,    53,    -1,
-      22,    23,    24,    -1,    59,    -1,    53,    29,    -1,    -1,
-      -1,    -1,    59,    -1,    36,    -1,    71,    -1,    73,    74,
-       8,    -1,    -1,    -1,    71,    -1,    73,    74,    -1,    17,
-      -1,    53,    -1,    -1,    22,    23,    24,    59,    -1,    -1,
-      -1,    29,    -1,    -1,    -1,     8,    -1,    -1,    36,    71,
-      -1,    73,    74,     8,    17,    -1,    -1,    -1,    -1,    22,
-      23,    24,    17,    -1,    -1,    53,    29,    22,    23,    24,
-      -1,    59,    -1,    36,    29,    -1,    -1,    -1,    -1,     8,
-      -1,    36,    11,    71,    -1,    73,    74,    -1,    17,    -1,
-      53,    -1,    -1,    22,    23,    24,    59,    -1,    53,    -1,
-      29,    -1,    -1,    -1,    59,    -1,     8,    36,    71,    -1,
-      73,    74,    -1,    -1,    -1,    17,    71,    -1,    -1,    74,
-      22,    23,    24,    -1,    53,    -1,    -1,    29,    -1,    -1,
-      -1,    -1,     8,    -1,    36,    -1,    -1,    -1,    -1,    -1,
-       8,    17,    71,    -1,    -1,    74,    22,    23,    24,    17,
-      -1,    53,    -1,    29,    22,    23,    24,    -1,    -1,    -1,
-      36,    29,    -1,    -1,    -1,    -1,    -1,    -1,    36,    71,
-      -1,    73,    74,    -1,    -1,    -1,    -1,    53,    -1,    -1,
-      -1,    -1,    -1,    59,    -1,    53,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    71,    -1,    -1,    74,    -1,
-      -1,    -1,    -1,    71,    33,    34,    74,    36,    -1,    38,
+      -1,     3,    -1,    -1,    49,    50,     8,    52,    53,    -1,
+      -1,    56,    -1,    -1,    59,    17,    -1,    -1,    -1,    -1,
+      22,    23,    24,    -1,    69,    70,    71,    29,    73,    74,
+      -1,    -1,    -1,    -1,    36,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,     3,    -1,    -1,    49,    50,     8,
+      52,    53,    -1,    -1,    56,    -1,    -1,    59,    17,    -1,
+      -1,    -1,    -1,    22,    23,    24,    -1,    69,    70,    71,
+      29,    73,    74,    -1,    -1,    -1,    -1,    36,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      49,    50,     8,    52,    53,    -1,    -1,    56,    -1,    -1,
+      59,    17,    -1,    -1,    -1,    -1,    22,    23,    24,    -1,
+      69,    70,    71,    29,    73,    74,    -1,     8,    -1,    -1,
+      36,    -1,    -1,    -1,    -1,     8,    17,    -1,    11,    -1,
+      -1,    22,    23,    24,    17,    -1,    -1,    53,    29,    22,
+      23,    24,    -1,    59,    -1,    36,    29,    -1,    -1,    65,
+      -1,     8,    -1,    36,    -1,    71,    -1,    73,    74,    75,
+      17,    -1,    53,    -1,    -1,    22,    23,    24,    59,    -1,
+      53,    -1,    29,    -1,    -1,    -1,    59,    -1,     8,    36,
+      71,    -1,    73,    74,    75,    -1,    -1,    17,    71,    -1,
+      73,    74,    22,    23,    24,    -1,    53,    -1,    -1,    29,
+      -1,    -1,    59,    -1,     8,    -1,    36,    -1,    -1,    -1,
+      -1,    -1,     8,    17,    71,    -1,    73,    74,    22,    23,
+      24,    17,    -1,    53,    -1,    29,    22,    23,    24,    59,
+      -1,    -1,    36,    29,    -1,    -1,    -1,     8,    -1,    -1,
+      36,    71,    -1,    73,    74,     8,    17,    -1,    11,    53,
+      -1,    22,    23,    24,    17,    59,    -1,    53,    29,    22,
+      23,    24,    -1,    59,    -1,    36,    29,    71,    -1,    73,
+      74,     8,    -1,    36,    -1,    71,    -1,    73,    74,    -1,
+      17,    -1,    53,    -1,    -1,    22,    23,    24,    -1,    -1,
+      53,    -1,    29,    -1,    -1,    -1,    -1,    -1,    -1,    36,
+      71,    -1,    73,    74,    -1,    -1,    -1,    -1,    71,    34,
+      -1,    74,    -1,    38,    39,    40,    53,    -1,    43,    44,
+      45,    46,    59,    48,    49,    50,    51,    52,    53,    54,
+      55,    56,    -1,    -1,    71,    33,    34,    74,    36,    -1,
+      38,    39,    40,    -1,    -1,    43,    44,    45,    46,    47,
+      48,    49,    50,    51,    52,    53,    54,    55,    56,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    33,    34,
+      -1,    36,    -1,    38,    39,    40,    -1,    75,    43,    44,
+      45,    46,    47,    48,    49,    50,    51,    52,    53,    54,
+      55,    56,    -1,    -1,    -1,    -1,    -1,    -1,    33,    34,
+      -1,    36,    -1,    38,    39,    40,    -1,    72,    43,    44,
+      45,    46,    47,    48,    49,    50,    51,    52,    53,    54,
+      55,    56,    33,    34,    -1,    36,    -1,    38,    39,    40,
+      -1,    66,    43,    44,    45,    46,    47,    48,    49,    50,
+      51,    52,    53,    54,    55,    56,    33,    34,    -1,    36,
+      -1,    38,    39,    40,    -1,    66,    43,    44,    45,    46,
+      47,    48,    49,    50,    51,    52,    53,    54,    55,    56,
+      33,    34,    -1,    36,    -1,    38,    39,    40,    -1,    66,
+      43,    44,    45,    46,    47,    48,    49,    50,    51,    52,
+      53,    54,    55,    56,    33,    34,    -1,    -1,    -1,    38,
       39,    40,    -1,    -1,    43,    44,    45,    46,    47,    48,
-      49,    50,    51,    52,    53,    54,    55,    56,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    33,    34,    -1,
-      36,    -1,    38,    39,    40,    -1,    75,    43,    44,    45,
-      46,    47,    48,    49,    50,    51,    52,    53,    54,    55,
-      56,    -1,    -1,    -1,    -1,    -1,    -1,    33,    34,    -1,
-      36,    -1,    38,    39,    40,    -1,    72,    43,    44,    45,
-      46,    47,    48,    49,    50,    51,    52,    53,    54,    55,
-      56,    33,    34,    -1,    36,    -1,    38,    39,    40,    -1,
-      66,    43,    44,    45,    46,    47,    48,    49,    50,    51,
-      52,    53,    54,    55,    56,    33,    34,    -1,    36,    -1,
-      38,    39,    40,    -1,    66,    43,    44,    45,    46,    47,
-      48,    49,    50,    51,    52,    53,    54,    55,    56,    33,
-      34,    -1,    36,    -1,    38,    39,    40,    -1,    66,    43,
-      44,    45,    46,    47,    48,    49,    50,    51,    52,    53,
-      54,    55,    56,    33,    34,    -1,    -1,    -1,    38,    39,
-      40,    -1,    -1,    43,    44,    45,    46,    47,    48,    49,
-      50,    51,    52,    53,    54,    55,    56,    33,    34,    -1,
-      -1,    -1,    38,    39,    40,    -1,    -1,    43,    44,    45,
-      46,    -1,    48,    49,    50,    51,    52,    53,    54,    55,
-      56
+      49,    50,    51,    52,    53,    54,    55,    56,    33,    34,
+      -1,    -1,    -1,    38,    39,    40,    -1,    -1,    43,    44,
+      45,    46,    -1,    48,    49,    50,    51,    52,    53,    54,
+      55,    56
 };
 
 /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
@@ -1528,50 +1514,50 @@ static const yytype_uint8 yystos[] =
       59,    63,    71,    66,    59,   137,     1,   137,     5,    65,
       75,   142,   200,    59,   160,   200,    24,   200,   201,   200,
       64,    62,   190,    88,    59,    36,    59,   146,   152,   153,
-     154,   155,   161,   146,   146,    63,    98,   107,   108,   109,
-     186,   194,    11,   136,   141,   145,   146,   177,   178,   179,
-      59,    67,   162,   112,   194,    24,    59,    68,   138,   171,
-     173,   175,   146,    35,    53,    59,    68,   138,   170,   172,
-     173,   174,   184,   112,    60,    97,   169,   146,    60,    93,
-     167,    65,    75,   146,     8,   147,    60,    72,    72,    60,
-      94,    65,   146,   126,   126,   126,   126,   126,   126,   126,
+     154,   155,   161,   146,   146,    63,    26,    98,   107,   108,
+     109,   186,   194,    11,   136,   141,   145,   146,   177,   178,
+     179,    59,    67,   162,   112,   194,    24,    59,    68,   138,
+     171,   173,   175,   146,    35,    53,    59,    68,   138,   170,
+     172,   173,   174,   184,   112,    60,    97,   169,   146,    60,
+      93,   167,    65,    75,   146,     8,   147,    60,    72,    72,
+      60,    94,    65,   146,   126,   126,   126,   126,   126,   126,
      126,   126,   126,   126,   126,   126,   126,   126,   126,   126,
-     126,   126,   126,   126,   130,    60,   135,   187,    59,   141,
-     126,   192,   182,   126,   130,     1,    67,    91,   100,   180,
-     181,   183,   186,   186,   126,     8,    17,    22,    23,    24,
-      29,    36,    53,    65,    71,   142,   202,   204,   205,   206,
-     141,   207,   215,   162,    59,     3,   202,   202,    83,    60,
-     179,     8,   146,    60,   141,    35,   105,     5,    65,    62,
-     146,   136,   145,    75,   191,    60,   179,   183,   115,    62,
-      63,    24,   173,    59,   176,    62,   190,    72,   104,    59,
-     174,    53,   174,    62,   190,     3,   198,    75,   146,   123,
-      62,   190,    62,   190,   186,   139,    65,    36,    59,   146,
-     152,   153,   154,   161,    67,   146,   146,    62,   190,   186,
-      65,    67,   126,   131,   132,   188,   189,    11,    75,   191,
-      31,   135,    72,    66,   180,    75,   191,   189,   101,    62,
-      68,    36,    59,   203,   204,   206,    59,    67,    71,    67,
-       8,   202,     3,    50,    59,   141,   212,   213,     3,    72,
-      65,    11,   202,    60,    75,    62,   195,   215,    62,    62,
-      62,    60,    60,   106,    26,    26,   194,   177,    59,   141,
-     151,   152,   153,   154,   155,   161,   163,    60,    68,   105,
-     194,   141,    60,   179,   175,    68,   146,     7,    12,    68,
-      99,   102,   174,   198,   174,    60,   172,    68,   138,   198,
-      35,    97,    60,    93,    60,   186,   146,   130,    94,    95,
-     168,   185,    60,   186,   130,    66,    75,   191,    68,   191,
-     135,    60,    60,    60,   192,    60,    68,   183,   180,   202,
-     205,   195,    24,   141,   142,   197,   202,   209,   217,   202,
-     141,   196,   208,   216,   202,     3,   212,    62,    72,   202,
-     213,   202,   198,   141,   207,    60,   183,   126,   126,    62,
-     179,    59,   163,   116,    60,   187,    66,   103,    60,    60,
-     198,   104,    60,   189,    62,   190,   146,   189,    67,   126,
-     133,   131,   132,    60,    66,    72,    68,    60,    60,    59,
-      68,    62,    72,   202,    68,    62,    49,   202,    62,   198,
-      59,    59,   202,   210,   211,    68,   194,    60,   179,   119,
-     163,     5,    65,    66,    75,   183,   198,   198,    68,    68,
-      95,    60,    68,   130,   192,   210,   195,   209,   202,   198,
-     208,   212,   195,   195,    60,    14,   117,   120,   126,   126,
-     189,    72,    60,    60,    60,    60,   163,    20,   100,    66,
-      66,    68,   210,   210,   118,   112,   105
+     126,   126,   126,   126,   126,   130,    60,   135,   187,    59,
+     141,   126,   192,   182,   126,   130,     1,    67,    91,   100,
+     180,   181,   183,   186,   186,   126,     8,    17,    22,    23,
+      24,    29,    36,    53,    65,    71,   142,   202,   204,   205,
+     206,   141,   207,   215,   162,    59,     3,   202,   202,    83,
+      60,   179,     8,   146,    60,   141,   126,    35,   105,     5,
+      65,    62,   146,   136,   145,    75,   191,    60,   179,   183,
+     115,    62,    63,    24,   173,    59,   176,    62,   190,    72,
+     104,    59,   174,    53,   174,    62,   190,     3,   198,    75,
+     146,   123,    62,   190,    62,   190,   186,   139,    65,    36,
+      59,   146,   152,   153,   154,   161,    67,   146,   146,    62,
+     190,   186,    65,    67,   126,   131,   132,   188,   189,    11,
+      75,   191,    31,   135,    72,    66,   180,    75,   191,   189,
+     101,    62,    68,    36,    59,   203,   204,   206,    59,    67,
+      71,    67,     8,   202,     3,    50,    59,   141,   212,   213,
+       3,    72,    65,    11,   202,    60,    75,    62,   195,   215,
+      62,    62,    62,    60,    60,   106,    26,    26,   194,   177,
+      59,   141,   151,   152,   153,   154,   155,   161,   163,    60,
+      68,   105,   194,   141,    60,   179,   175,    68,   146,     7,
+      12,    68,    99,   102,   174,   198,   174,    60,   172,    68,
+     138,   198,    35,    97,    60,    93,    60,   186,   146,   130,
+      94,    95,   168,   185,    60,   186,   130,    66,    75,   191,
+      68,   191,   135,    60,    60,    60,   192,    60,    68,   183,
+     180,   202,   205,   195,    24,   141,   142,   197,   202,   209,
+     217,   202,   141,   196,   208,   216,   202,     3,   212,    62,
+      72,   202,   213,   202,   198,   141,   207,    60,   183,   126,
+     126,    62,   179,    59,   163,   116,    60,   187,    66,   103,
+      60,    60,   198,   104,    60,   189,    62,   190,   146,   189,
+      67,   126,   133,   131,   132,    60,    66,    72,    68,    60,
+      60,    59,    68,    62,    72,   202,    68,    62,    49,   202,
+      62,   198,    59,    59,   202,   210,   211,    68,   194,    60,
+     179,   119,   163,     5,    65,    66,    75,   183,   198,   198,
+      68,    68,    95,    60,    68,   130,   192,   210,   195,   209,
+     202,   198,   208,   212,   195,   195,    60,    14,   117,   120,
+     126,   126,   189,    72,    60,    60,    60,    60,   163,    20,
+     100,    66,    66,    68,   210,   210,   118,   112,   105
 };
 
 #define yyerrok		(yyerrstatus = 0)
@@ -2795,20 +2781,22 @@ yyreduce:
 #line 461 "go.y"
     {
 		(yyval.node) = nod(OASOP, (yyvsp[(1) - (2)].node), nodintconst(1));
+		(yyval.node)->implicit = 1;
 		(yyval.node)->etype = OADD;
 	}
     break;
 
   case 55:
-#line 466 "go.y"
+#line 467 "go.y"
     {
 		(yyval.node) = nod(OASOP, (yyvsp[(1) - (2)].node), nodintconst(1));
+		(yyval.node)->implicit = 1;
 		(yyval.node)->etype = OSUB;
 	}
     break;
 
   case 56:
-#line 473 "go.y"
+#line 475 "go.y"
     {
 		Node *n, *nn;
 
@@ -2831,7 +2819,7 @@ yyreduce:
     break;
 
   case 57:
-#line 493 "go.y"
+#line 495 "go.y"
     {
 		Node *n;
 
@@ -2852,7 +2840,7 @@ yyreduce:
     break;
 
   case 58:
-#line 511 "go.y"
+#line 513 "go.y"
     {
 		// will be converted to OCASE
 		// right will point to next case
@@ -2864,7 +2852,7 @@ yyreduce:
     break;
 
   case 59:
-#line 520 "go.y"
+#line 522 "go.y"
     {
 		Node *n, *nn;
 
@@ -2883,14 +2871,14 @@ yyreduce:
     break;
 
   case 60:
-#line 538 "go.y"
+#line 540 "go.y"
     {
 		markdcl();
 	}
     break;
 
   case 61:
-#line 542 "go.y"
+#line 544 "go.y"
     {
 		if((yyvsp[(3) - (4)].list) == nil)
 			(yyval.node) = nod(OEMPTY, N, N);
@@ -2901,7 +2889,7 @@ yyreduce:
     break;
 
   case 62:
-#line 552 "go.y"
+#line 554 "go.y"
     {
 		// If the last token read by the lexer was consumed
 		// as part of the case, clear it (parser has cleared yychar).
@@ -2915,7 +2903,7 @@ yyreduce:
     break;
 
   case 63:
-#line 563 "go.y"
+#line 565 "go.y"
     {
 		int last;
 
@@ -2937,28 +2925,28 @@ yyreduce:
     break;
 
   case 64:
-#line 583 "go.y"
+#line 585 "go.y"
     {
 		(yyval.list) = nil;
 	}
     break;
 
   case 65:
-#line 587 "go.y"
+#line 589 "go.y"
     {
 		(yyval.list) = list((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].node));
 	}
     break;
 
   case 66:
-#line 593 "go.y"
+#line 595 "go.y"
     {
 		markdcl();
 	}
     break;
 
   case 67:
-#line 597 "go.y"
+#line 599 "go.y"
     {
 		(yyval.list) = (yyvsp[(3) - (4)].list);
 		popdcl();
@@ -2966,7 +2954,7 @@ yyreduce:
     break;
 
   case 68:
-#line 604 "go.y"
+#line 606 "go.y"
     {
 		(yyval.node) = nod(ORANGE, N, (yyvsp[(4) - (4)].node));
 		(yyval.node)->list = (yyvsp[(1) - (4)].list);
@@ -2975,7 +2963,7 @@ yyreduce:
     break;
 
   case 69:
-#line 610 "go.y"
+#line 612 "go.y"
     {
 		(yyval.node) = nod(ORANGE, N, (yyvsp[(4) - (4)].node));
 		(yyval.node)->list = (yyvsp[(1) - (4)].list);
@@ -2987,6 +2975,14 @@ yyreduce:
   case 70:
 #line 619 "go.y"
     {
+		(yyval.node) = nod(ORANGE, N, (yyvsp[(2) - (2)].node));
+		(yyval.node)->etype = 0; // := flag
+	}
+    break;
+
+  case 71:
+#line 626 "go.y"
+    {
 		// init ; test ; incr
 		if((yyvsp[(5) - (5)].node) != N && (yyvsp[(5) - (5)].node)->colas != 0)
 			yyerror("cannot declare in the for-increment");
@@ -2998,8 +2994,8 @@ yyreduce:
 	}
     break;
 
-  case 71:
-#line 630 "go.y"
+  case 72:
+#line 637 "go.y"
     {
 		// normal test
 		(yyval.node) = nod(OFOR, N, N);
@@ -3007,31 +3003,31 @@ yyreduce:
 	}
     break;
 
-  case 73:
-#line 639 "go.y"
+  case 74:
+#line 646 "go.y"
     {
 		(yyval.node) = (yyvsp[(1) - (2)].node);
 		(yyval.node)->nbody = concat((yyval.node)->nbody, (yyvsp[(2) - (2)].list));
 	}
     break;
 
-  case 74:
-#line 646 "go.y"
+  case 75:
+#line 653 "go.y"
     {
 		markdcl();
 	}
     break;
 
-  case 75:
-#line 650 "go.y"
+  case 76:
+#line 657 "go.y"
     {
 		(yyval.node) = (yyvsp[(3) - (3)].node);
 		popdcl();
 	}
     break;
 
-  case 76:
-#line 657 "go.y"
+  case 77:
+#line 664 "go.y"
     {
 		// test
 		(yyval.node) = nod(OIF, N, N);
@@ -3039,8 +3035,8 @@ yyreduce:
 	}
     break;
 
-  case 77:
-#line 663 "go.y"
+  case 78:
+#line 670 "go.y"
     {
 		// init ; test
 		(yyval.node) = nod(OIF, N, N);
@@ -3050,30 +3046,30 @@ yyreduce:
 	}
     break;
 
-  case 78:
-#line 674 "go.y"
+  case 79:
+#line 681 "go.y"
     {
 		markdcl();
 	}
     break;
 
-  case 79:
-#line 678 "go.y"
+  case 80:
+#line 685 "go.y"
     {
 		if((yyvsp[(3) - (3)].node)->ntest == N)
 			yyerror("missing condition in if statement");
 	}
     break;
 
-  case 80:
-#line 683 "go.y"
+  case 81:
+#line 690 "go.y"
     {
 		(yyvsp[(3) - (5)].node)->nbody = (yyvsp[(5) - (5)].list);
 	}
     break;
 
-  case 81:
-#line 687 "go.y"
+  case 82:
+#line 694 "go.y"
     {
 		Node *n;
 		NodeList *nn;
@@ -3090,15 +3086,15 @@ yyreduce:
 	}
     break;
 
-  case 82:
-#line 704 "go.y"
+  case 83:
+#line 711 "go.y"
     {
 		markdcl();
 	}
     break;
 
-  case 83:
-#line 708 "go.y"
+  case 84:
+#line 715 "go.y"
     {
 		if((yyvsp[(4) - (5)].node)->ntest == N)
 			yyerror("missing condition in if statement");
@@ -3107,29 +3103,29 @@ yyreduce:
 	}
     break;
 
-  case 84:
-#line 716 "go.y"
+  case 85:
+#line 723 "go.y"
     {
 		(yyval.list) = nil;
 	}
     break;
 
-  case 85:
-#line 720 "go.y"
+  case 86:
+#line 727 "go.y"
     {
 		(yyval.list) = concat((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].list));
 	}
     break;
 
-  case 86:
-#line 725 "go.y"
+  case 87:
+#line 732 "go.y"
     {
 		(yyval.list) = nil;
 	}
     break;
 
-  case 87:
-#line 729 "go.y"
+  case 88:
+#line 736 "go.y"
     {
 		NodeList *node;
 		
@@ -3140,15 +3136,15 @@ yyreduce:
 	}
     break;
 
-  case 88:
-#line 740 "go.y"
+  case 89:
+#line 747 "go.y"
     {
 		markdcl();
 	}
     break;
 
-  case 89:
-#line 744 "go.y"
+  case 90:
+#line 751 "go.y"
     {
 		Node *n;
 		n = (yyvsp[(3) - (3)].node)->ntest;
@@ -3158,8 +3154,8 @@ yyreduce:
 	}
     break;
 
-  case 90:
-#line 752 "go.y"
+  case 91:
+#line 759 "go.y"
     {
 		(yyval.node) = (yyvsp[(3) - (7)].node);
 		(yyval.node)->op = OSWITCH;
@@ -3169,15 +3165,15 @@ yyreduce:
 	}
     break;
 
-  case 91:
-#line 762 "go.y"
+  case 92:
+#line 769 "go.y"
     {
 		typesw = nod(OXXX, typesw, N);
 	}
     break;
 
-  case 92:
-#line 766 "go.y"
+  case 93:
+#line 773 "go.y"
     {
 		(yyval.node) = nod(OSELECT, N, N);
 		(yyval.node)->lineno = typesw->lineno;
@@ -3186,155 +3182,155 @@ yyreduce:
 	}
     break;
 
-  case 94:
-#line 779 "go.y"
+  case 95:
+#line 786 "go.y"
     {
 		(yyval.node) = nod(OOROR, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
 	}
     break;
 
-  case 95:
-#line 783 "go.y"
+  case 96:
+#line 790 "go.y"
     {
 		(yyval.node) = nod(OANDAND, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
 	}
     break;
 
-  case 96:
-#line 787 "go.y"
+  case 97:
+#line 794 "go.y"
     {
 		(yyval.node) = nod(OEQ, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
 	}
     break;
 
-  case 97:
-#line 791 "go.y"
+  case 98:
+#line 798 "go.y"
     {
 		(yyval.node) = nod(ONE, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
 	}
     break;
 
-  case 98:
-#line 795 "go.y"
+  case 99:
+#line 802 "go.y"
     {
 		(yyval.node) = nod(OLT, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
 	}
     break;
 
-  case 99:
-#line 799 "go.y"
+  case 100:
+#line 806 "go.y"
     {
 		(yyval.node) = nod(OLE, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
 	}
     break;
 
-  case 100:
-#line 803 "go.y"
+  case 101:
+#line 810 "go.y"
     {
 		(yyval.node) = nod(OGE, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
 	}
     break;
 
-  case 101:
-#line 807 "go.y"
+  case 102:
+#line 814 "go.y"
     {
 		(yyval.node) = nod(OGT, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
 	}
     break;
 
-  case 102:
-#line 811 "go.y"
+  case 103:
+#line 818 "go.y"
     {
 		(yyval.node) = nod(OADD, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
 	}
     break;
 
-  case 103:
-#line 815 "go.y"
+  case 104:
+#line 822 "go.y"
     {
 		(yyval.node) = nod(OSUB, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
 	}
     break;
 
-  case 104:
-#line 819 "go.y"
+  case 105:
+#line 826 "go.y"
     {
 		(yyval.node) = nod(OOR, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
 	}
     break;
 
-  case 105:
-#line 823 "go.y"
+  case 106:
+#line 830 "go.y"
     {
 		(yyval.node) = nod(OXOR, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
 	}
     break;
 
-  case 106:
-#line 827 "go.y"
+  case 107:
+#line 834 "go.y"
     {
 		(yyval.node) = nod(OMUL, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
 	}
     break;
 
-  case 107:
-#line 831 "go.y"
+  case 108:
+#line 838 "go.y"
     {
 		(yyval.node) = nod(ODIV, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
 	}
     break;
 
-  case 108:
-#line 835 "go.y"
+  case 109:
+#line 842 "go.y"
     {
 		(yyval.node) = nod(OMOD, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
 	}
     break;
 
-  case 109:
-#line 839 "go.y"
+  case 110:
+#line 846 "go.y"
     {
 		(yyval.node) = nod(OAND, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
 	}
     break;
 
-  case 110:
-#line 843 "go.y"
+  case 111:
+#line 850 "go.y"
     {
 		(yyval.node) = nod(OANDNOT, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
 	}
     break;
 
-  case 111:
-#line 847 "go.y"
+  case 112:
+#line 854 "go.y"
     {
 		(yyval.node) = nod(OLSH, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
 	}
     break;
 
-  case 112:
-#line 851 "go.y"
+  case 113:
+#line 858 "go.y"
     {
 		(yyval.node) = nod(ORSH, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
 	}
     break;
 
-  case 113:
-#line 856 "go.y"
+  case 114:
+#line 863 "go.y"
     {
 		(yyval.node) = nod(OSEND, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
 	}
     break;
 
-  case 115:
-#line 863 "go.y"
+  case 116:
+#line 870 "go.y"
     {
 		(yyval.node) = nod(OIND, (yyvsp[(2) - (2)].node), N);
 	}
     break;
 
-  case 116:
-#line 867 "go.y"
+  case 117:
+#line 874 "go.y"
     {
 		if((yyvsp[(2) - (2)].node)->op == OCOMPLIT) {
 			// Special case for &T{...}: turn into (*T){...}.
@@ -3347,66 +3343,66 @@ yyreduce:
 	}
     break;
 
-  case 117:
-#line 878 "go.y"
+  case 118:
+#line 885 "go.y"
     {
 		(yyval.node) = nod(OPLUS, (yyvsp[(2) - (2)].node), N);
 	}
     break;
 
-  case 118:
-#line 882 "go.y"
+  case 119:
+#line 889 "go.y"
     {
 		(yyval.node) = nod(OMINUS, (yyvsp[(2) - (2)].node), N);
 	}
     break;
 
-  case 119:
-#line 886 "go.y"
+  case 120:
+#line 893 "go.y"
     {
 		(yyval.node) = nod(ONOT, (yyvsp[(2) - (2)].node), N);
 	}
     break;
 
-  case 120:
-#line 890 "go.y"
+  case 121:
+#line 897 "go.y"
     {
 		yyerror("the bitwise complement operator is ^");
 		(yyval.node) = nod(OCOM, (yyvsp[(2) - (2)].node), N);
 	}
     break;
 
-  case 121:
-#line 895 "go.y"
+  case 122:
+#line 902 "go.y"
     {
 		(yyval.node) = nod(OCOM, (yyvsp[(2) - (2)].node), N);
 	}
     break;
 
-  case 122:
-#line 899 "go.y"
+  case 123:
+#line 906 "go.y"
     {
 		(yyval.node) = nod(ORECV, (yyvsp[(2) - (2)].node), N);
 	}
     break;
 
-  case 123:
-#line 909 "go.y"
+  case 124:
+#line 916 "go.y"
     {
 		(yyval.node) = nod(OCALL, (yyvsp[(1) - (3)].node), N);
 	}
     break;
 
-  case 124:
-#line 913 "go.y"
+  case 125:
+#line 920 "go.y"
     {
 		(yyval.node) = nod(OCALL, (yyvsp[(1) - (5)].node), N);
 		(yyval.node)->list = (yyvsp[(3) - (5)].list);
 	}
     break;
 
-  case 125:
-#line 918 "go.y"
+  case 126:
+#line 925 "go.y"
     {
 		(yyval.node) = nod(OCALL, (yyvsp[(1) - (6)].node), N);
 		(yyval.node)->list = (yyvsp[(3) - (6)].list);
@@ -3414,15 +3410,15 @@ yyreduce:
 	}
     break;
 
-  case 126:
-#line 926 "go.y"
+  case 127:
+#line 933 "go.y"
     {
 		(yyval.node) = nodlit((yyvsp[(1) - (1)].val));
 	}
     break;
 
-  case 128:
-#line 931 "go.y"
+  case 129:
+#line 938 "go.y"
     {
 		if((yyvsp[(1) - (3)].node)->op == OPACK) {
 			Sym *s;
@@ -3435,36 +3431,36 @@ yyreduce:
 	}
     break;
 
-  case 129:
-#line 942 "go.y"
+  case 130:
+#line 949 "go.y"
     {
 		(yyval.node) = nod(ODOTTYPE, (yyvsp[(1) - (5)].node), (yyvsp[(4) - (5)].node));
 	}
     break;
 
-  case 130:
-#line 946 "go.y"
+  case 131:
+#line 953 "go.y"
     {
 		(yyval.node) = nod(OTYPESW, N, (yyvsp[(1) - (5)].node));
 	}
     break;
 
-  case 131:
-#line 950 "go.y"
+  case 132:
+#line 957 "go.y"
     {
 		(yyval.node) = nod(OINDEX, (yyvsp[(1) - (4)].node), (yyvsp[(3) - (4)].node));
 	}
     break;
 
-  case 132:
-#line 954 "go.y"
+  case 133:
+#line 961 "go.y"
     {
 		(yyval.node) = nod(OSLICE, (yyvsp[(1) - (6)].node), nod(OKEY, (yyvsp[(3) - (6)].node), (yyvsp[(5) - (6)].node)));
 	}
     break;
 
-  case 133:
-#line 958 "go.y"
+  case 134:
+#line 965 "go.y"
     {
 		if((yyvsp[(5) - (8)].node) == N)
 			yyerror("middle index required in 3-index slice");
@@ -3474,8 +3470,8 @@ yyreduce:
 	}
     break;
 
-  case 135:
-#line 967 "go.y"
+  case 136:
+#line 974 "go.y"
     {
 		// conversion
 		(yyval.node) = nod(OCALL, (yyvsp[(1) - (5)].node), N);
@@ -3483,8 +3479,8 @@ yyreduce:
 	}
     break;
 
-  case 136:
-#line 973 "go.y"
+  case 137:
+#line 980 "go.y"
     {
 		(yyval.node) = (yyvsp[(3) - (5)].node);
 		(yyval.node)->right = (yyvsp[(1) - (5)].node);
@@ -3493,8 +3489,8 @@ yyreduce:
 	}
     break;
 
-  case 137:
-#line 980 "go.y"
+  case 138:
+#line 987 "go.y"
     {
 		(yyval.node) = (yyvsp[(3) - (5)].node);
 		(yyval.node)->right = (yyvsp[(1) - (5)].node);
@@ -3502,8 +3498,8 @@ yyreduce:
 	}
     break;
 
-  case 138:
-#line 986 "go.y"
+  case 139:
+#line 993 "go.y"
     {
 		yyerror("cannot parenthesize type in composite literal");
 		(yyval.node) = (yyvsp[(5) - (7)].node);
@@ -3512,8 +3508,8 @@ yyreduce:
 	}
     break;
 
-  case 140:
-#line 995 "go.y"
+  case 141:
+#line 1002 "go.y"
     {
 		// composite expression.
 		// make node early so we get the right line number.
@@ -3521,15 +3517,15 @@ yyreduce:
 	}
     break;
 
-  case 141:
-#line 1003 "go.y"
+  case 142:
+#line 1010 "go.y"
     {
 		(yyval.node) = nod(OKEY, (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
 	}
     break;
 
-  case 142:
-#line 1009 "go.y"
+  case 143:
+#line 1016 "go.y"
     {
 		// These nodes do not carry line numbers.
 		// Since a composite literal commonly spans several lines,
@@ -3548,24 +3544,24 @@ yyreduce:
 	}
     break;
 
-  case 143:
-#line 1026 "go.y"
+  case 144:
+#line 1033 "go.y"
     {
 		(yyval.node) = (yyvsp[(2) - (4)].node);
 		(yyval.node)->list = (yyvsp[(3) - (4)].list);
 	}
     break;
 
-  case 145:
-#line 1034 "go.y"
+  case 146:
+#line 1041 "go.y"
     {
 		(yyval.node) = (yyvsp[(2) - (4)].node);
 		(yyval.node)->list = (yyvsp[(3) - (4)].list);
 	}
     break;
 
-  case 147:
-#line 1042 "go.y"
+  case 148:
+#line 1049 "go.y"
     {
 		(yyval.node) = (yyvsp[(2) - (3)].node);
 		
@@ -3584,22 +3580,22 @@ yyreduce:
 	}
     break;
 
-  case 151:
-#line 1068 "go.y"
+  case 152:
+#line 1075 "go.y"
     {
 		(yyval.i) = LBODY;
 	}
     break;
 
-  case 152:
-#line 1072 "go.y"
+  case 153:
+#line 1079 "go.y"
     {
 		(yyval.i) = '{';
 	}
     break;
 
-  case 153:
-#line 1083 "go.y"
+  case 154:
+#line 1090 "go.y"
     {
 		if((yyvsp[(1) - (1)].sym) == S)
 			(yyval.node) = N;
@@ -3608,22 +3604,22 @@ yyreduce:
 	}
     break;
 
-  case 154:
-#line 1092 "go.y"
+  case 155:
+#line 1099 "go.y"
     {
 		(yyval.node) = dclname((yyvsp[(1) - (1)].sym));
 	}
     break;
 
-  case 155:
-#line 1097 "go.y"
+  case 156:
+#line 1104 "go.y"
     {
 		(yyval.node) = N;
 	}
     break;
 
-  case 157:
-#line 1104 "go.y"
+  case 158:
+#line 1111 "go.y"
     {
 		(yyval.sym) = (yyvsp[(1) - (1)].sym);
 		// during imports, unqualified non-exported identifiers are from builtinpkg
@@ -3632,15 +3628,15 @@ yyreduce:
 	}
     break;
 
-  case 159:
-#line 1112 "go.y"
+  case 160:
+#line 1119 "go.y"
     {
 		(yyval.sym) = S;
 	}
     break;
 
-  case 160:
-#line 1118 "go.y"
+  case 161:
+#line 1125 "go.y"
     {
 		Pkg *p;
 
@@ -3655,8 +3651,8 @@ yyreduce:
 	}
     break;
 
-  case 161:
-#line 1131 "go.y"
+  case 162:
+#line 1138 "go.y"
     {
 		Pkg *p;
 
@@ -3671,8 +3667,8 @@ yyreduce:
 	}
     break;
 
-  case 162:
-#line 1146 "go.y"
+  case 163:
+#line 1153 "go.y"
     {
 		(yyval.node) = oldname((yyvsp[(1) - (1)].sym));
 		if((yyval.node)->pack != N)
@@ -3680,44 +3676,44 @@ yyreduce:
 	}
     break;
 
-  case 164:
-#line 1166 "go.y"
+  case 165:
+#line 1173 "go.y"
     {
 		yyerror("final argument in variadic function missing type");
 		(yyval.node) = nod(ODDD, typenod(typ(TINTER)), N);
 	}
     break;
 
-  case 165:
-#line 1171 "go.y"
+  case 166:
+#line 1178 "go.y"
     {
 		(yyval.node) = nod(ODDD, (yyvsp[(2) - (2)].node), N);
 	}
     break;
 
-  case 171:
-#line 1182 "go.y"
+  case 172:
+#line 1189 "go.y"
     {
-		(yyval.node) = nod(OTPAREN, (yyvsp[(2) - (3)].node), N);
+		(yyval.node) = (yyvsp[(2) - (3)].node);
 	}
     break;
 
-  case 175:
-#line 1191 "go.y"
+  case 176:
+#line 1198 "go.y"
     {
 		(yyval.node) = nod(OIND, (yyvsp[(2) - (2)].node), N);
 	}
     break;
 
-  case 180:
-#line 1201 "go.y"
+  case 181:
+#line 1208 "go.y"
     {
-		(yyval.node) = nod(OTPAREN, (yyvsp[(2) - (3)].node), N);
+		(yyval.node) = (yyvsp[(2) - (3)].node);
 	}
     break;
 
-  case 190:
-#line 1222 "go.y"
+  case 191:
+#line 1229 "go.y"
     {
 		if((yyvsp[(1) - (3)].node)->op == OPACK) {
 			Sym *s;
@@ -3730,61 +3726,61 @@ yyreduce:
 	}
     break;
 
-  case 191:
-#line 1235 "go.y"
+  case 192:
+#line 1242 "go.y"
     {
 		(yyval.node) = nod(OTARRAY, (yyvsp[(2) - (4)].node), (yyvsp[(4) - (4)].node));
 	}
     break;
 
-  case 192:
-#line 1239 "go.y"
+  case 193:
+#line 1246 "go.y"
     {
 		// array literal of nelem
 		(yyval.node) = nod(OTARRAY, nod(ODDD, N, N), (yyvsp[(4) - (4)].node));
 	}
     break;
 
-  case 193:
-#line 1244 "go.y"
+  case 194:
+#line 1251 "go.y"
     {
 		(yyval.node) = nod(OTCHAN, (yyvsp[(2) - (2)].node), N);
 		(yyval.node)->etype = Cboth;
 	}
     break;
 
-  case 194:
-#line 1249 "go.y"
+  case 195:
+#line 1256 "go.y"
     {
 		(yyval.node) = nod(OTCHAN, (yyvsp[(3) - (3)].node), N);
 		(yyval.node)->etype = Csend;
 	}
     break;
 
-  case 195:
-#line 1254 "go.y"
+  case 196:
+#line 1261 "go.y"
     {
 		(yyval.node) = nod(OTMAP, (yyvsp[(3) - (5)].node), (yyvsp[(5) - (5)].node));
 	}
     break;
 
-  case 198:
-#line 1262 "go.y"
+  case 199:
+#line 1269 "go.y"
     {
 		(yyval.node) = nod(OIND, (yyvsp[(2) - (2)].node), N);
 	}
     break;
 
-  case 199:
-#line 1268 "go.y"
+  case 200:
+#line 1275 "go.y"
     {
 		(yyval.node) = nod(OTCHAN, (yyvsp[(3) - (3)].node), N);
 		(yyval.node)->etype = Crecv;
 	}
     break;
 
-  case 200:
-#line 1275 "go.y"
+  case 201:
+#line 1282 "go.y"
     {
 		(yyval.node) = nod(OTSTRUCT, N, N);
 		(yyval.node)->list = (yyvsp[(3) - (5)].list);
@@ -3792,16 +3788,16 @@ yyreduce:
 	}
     break;
 
-  case 201:
-#line 1281 "go.y"
+  case 202:
+#line 1288 "go.y"
     {
 		(yyval.node) = nod(OTSTRUCT, N, N);
 		fixlbrace((yyvsp[(2) - (3)].i));
 	}
     break;
 
-  case 202:
-#line 1288 "go.y"
+  case 203:
+#line 1295 "go.y"
     {
 		(yyval.node) = nod(OTINTER, N, N);
 		(yyval.node)->list = (yyvsp[(3) - (5)].list);
@@ -3809,16 +3805,16 @@ yyreduce:
 	}
     break;
 
-  case 203:
-#line 1294 "go.y"
+  case 204:
+#line 1301 "go.y"
     {
 		(yyval.node) = nod(OTINTER, N, N);
 		fixlbrace((yyvsp[(2) - (3)].i));
 	}
     break;
 
-  case 204:
-#line 1305 "go.y"
+  case 205:
+#line 1312 "go.y"
     {
 		(yyval.node) = (yyvsp[(2) - (3)].node);
 		if((yyval.node) == N)
@@ -3828,12 +3824,13 @@ yyreduce:
 		(yyval.node)->nbody = (yyvsp[(3) - (3)].list);
 		(yyval.node)->endlineno = lineno;
 		(yyval.node)->noescape = noescape;
+		(yyval.node)->nosplit = nosplit;
 		funcbody((yyval.node));
 	}
     break;
 
-  case 205:
-#line 1319 "go.y"
+  case 206:
+#line 1327 "go.y"
     {
 		Node *t;
 
@@ -3864,8 +3861,8 @@ yyreduce:
 	}
     break;
 
-  case 206:
-#line 1348 "go.y"
+  case 207:
+#line 1356 "go.y"
     {
 		Node *rcvr, *t;
 
@@ -3886,8 +3883,6 @@ yyreduce:
 			yyerror("bad receiver in method");
 			break;
 		}
-		if(rcvr->right->op == OTPAREN || (rcvr->right->op == OIND && rcvr->right->left->op == OTPAREN))
-			yyerror("cannot parenthesize receiver type");
 
 		t = nod(OTFUNC, rcvr, N);
 		t->list = (yyvsp[(6) - (8)].list);
@@ -3905,8 +3900,8 @@ yyreduce:
 	}
     break;
 
-  case 207:
-#line 1388 "go.y"
+  case 208:
+#line 1394 "go.y"
     {
 		Sym *s;
 		Type *t;
@@ -3933,8 +3928,8 @@ yyreduce:
 	}
     break;
 
-  case 208:
-#line 1413 "go.y"
+  case 209:
+#line 1419 "go.y"
     {
 		(yyval.node) = methodname1(newname((yyvsp[(4) - (8)].sym)), (yyvsp[(2) - (8)].list)->n->right); 
 		(yyval.node)->type = functype((yyvsp[(2) - (8)].list)->n, (yyvsp[(6) - (8)].list), (yyvsp[(8) - (8)].list));
@@ -3952,8 +3947,8 @@ yyreduce:
 	}
     break;
 
-  case 209:
-#line 1431 "go.y"
+  case 210:
+#line 1437 "go.y"
     {
 		(yyvsp[(3) - (5)].list) = checkarglist((yyvsp[(3) - (5)].list), 1);
 		(yyval.node) = nod(OTFUNC, N, N);
@@ -3962,15 +3957,15 @@ yyreduce:
 	}
     break;
 
-  case 210:
-#line 1439 "go.y"
+  case 211:
+#line 1445 "go.y"
     {
 		(yyval.list) = nil;
 	}
     break;
 
-  case 211:
-#line 1443 "go.y"
+  case 212:
+#line 1449 "go.y"
     {
 		(yyval.list) = (yyvsp[(2) - (3)].list);
 		if((yyval.list) == nil)
@@ -3978,119 +3973,120 @@ yyreduce:
 	}
     break;
 
-  case 212:
-#line 1451 "go.y"
+  case 213:
+#line 1457 "go.y"
     {
 		(yyval.list) = nil;
 	}
     break;
 
-  case 213:
-#line 1455 "go.y"
+  case 214:
+#line 1461 "go.y"
     {
 		(yyval.list) = list1(nod(ODCLFIELD, N, (yyvsp[(1) - (1)].node)));
 	}
     break;
 
-  case 214:
-#line 1459 "go.y"
+  case 215:
+#line 1465 "go.y"
     {
 		(yyvsp[(2) - (3)].list) = checkarglist((yyvsp[(2) - (3)].list), 0);
 		(yyval.list) = (yyvsp[(2) - (3)].list);
 	}
     break;
 
-  case 215:
-#line 1466 "go.y"
+  case 216:
+#line 1472 "go.y"
     {
 		closurehdr((yyvsp[(1) - (1)].node));
 	}
     break;
 
-  case 216:
-#line 1472 "go.y"
+  case 217:
+#line 1478 "go.y"
     {
 		(yyval.node) = closurebody((yyvsp[(3) - (4)].list));
 		fixlbrace((yyvsp[(2) - (4)].i));
 	}
     break;
 
-  case 217:
-#line 1477 "go.y"
+  case 218:
+#line 1483 "go.y"
     {
 		(yyval.node) = closurebody(nil);
 	}
     break;
 
-  case 218:
-#line 1488 "go.y"
+  case 219:
+#line 1494 "go.y"
     {
 		(yyval.list) = nil;
 	}
     break;
 
-  case 219:
-#line 1492 "go.y"
+  case 220:
+#line 1498 "go.y"
     {
 		(yyval.list) = concat((yyvsp[(1) - (3)].list), (yyvsp[(2) - (3)].list));
 		if(nsyntaxerrors == 0)
 			testdclstack();
 		nointerface = 0;
 		noescape = 0;
+		nosplit = 0;
 	}
     break;
 
-  case 221:
-#line 1503 "go.y"
+  case 222:
+#line 1510 "go.y"
     {
 		(yyval.list) = concat((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list));
 	}
     break;
 
-  case 223:
-#line 1510 "go.y"
+  case 224:
+#line 1517 "go.y"
     {
 		(yyval.list) = concat((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list));
 	}
     break;
 
-  case 224:
-#line 1516 "go.y"
+  case 225:
+#line 1523 "go.y"
     {
 		(yyval.list) = list1((yyvsp[(1) - (1)].node));
 	}
     break;
 
-  case 225:
-#line 1520 "go.y"
+  case 226:
+#line 1527 "go.y"
     {
 		(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
 	}
     break;
 
-  case 227:
-#line 1527 "go.y"
+  case 228:
+#line 1534 "go.y"
     {
 		(yyval.list) = concat((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list));
 	}
     break;
 
-  case 228:
-#line 1533 "go.y"
+  case 229:
+#line 1540 "go.y"
     {
 		(yyval.list) = list1((yyvsp[(1) - (1)].node));
 	}
     break;
 
-  case 229:
-#line 1537 "go.y"
+  case 230:
+#line 1544 "go.y"
     {
 		(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
 	}
     break;
 
-  case 230:
-#line 1543 "go.y"
+  case 231:
+#line 1550 "go.y"
     {
 		NodeList *l;
 
@@ -4115,16 +4111,16 @@ yyreduce:
 	}
     break;
 
-  case 231:
-#line 1566 "go.y"
+  case 232:
+#line 1573 "go.y"
     {
 		(yyvsp[(1) - (2)].node)->val = (yyvsp[(2) - (2)].val);
 		(yyval.list) = list1((yyvsp[(1) - (2)].node));
 	}
     break;
 
-  case 232:
-#line 1571 "go.y"
+  case 233:
+#line 1578 "go.y"
     {
 		(yyvsp[(2) - (4)].node)->val = (yyvsp[(4) - (4)].val);
 		(yyval.list) = list1((yyvsp[(2) - (4)].node));
@@ -4132,8 +4128,8 @@ yyreduce:
 	}
     break;
 
-  case 233:
-#line 1577 "go.y"
+  case 234:
+#line 1584 "go.y"
     {
 		(yyvsp[(2) - (3)].node)->right = nod(OIND, (yyvsp[(2) - (3)].node)->right, N);
 		(yyvsp[(2) - (3)].node)->val = (yyvsp[(3) - (3)].val);
@@ -4141,8 +4137,8 @@ yyreduce:
 	}
     break;
 
-  case 234:
-#line 1583 "go.y"
+  case 235:
+#line 1590 "go.y"
     {
 		(yyvsp[(3) - (5)].node)->right = nod(OIND, (yyvsp[(3) - (5)].node)->right, N);
 		(yyvsp[(3) - (5)].node)->val = (yyvsp[(5) - (5)].val);
@@ -4151,8 +4147,8 @@ yyreduce:
 	}
     break;
 
-  case 235:
-#line 1590 "go.y"
+  case 236:
+#line 1597 "go.y"
     {
 		(yyvsp[(3) - (5)].node)->right = nod(OIND, (yyvsp[(3) - (5)].node)->right, N);
 		(yyvsp[(3) - (5)].node)->val = (yyvsp[(5) - (5)].val);
@@ -4161,8 +4157,8 @@ yyreduce:
 	}
     break;
 
-  case 236:
-#line 1599 "go.y"
+  case 237:
+#line 1606 "go.y"
     {
 		Node *n;
 
@@ -4173,8 +4169,8 @@ yyreduce:
 	}
     break;
 
-  case 237:
-#line 1608 "go.y"
+  case 238:
+#line 1615 "go.y"
     {
 		Pkg *pkg;
 
@@ -4189,38 +4185,38 @@ yyreduce:
 	}
     break;
 
-  case 238:
-#line 1623 "go.y"
+  case 239:
+#line 1630 "go.y"
     {
 		(yyval.node) = embedded((yyvsp[(1) - (1)].sym), localpkg);
 	}
     break;
 
-  case 239:
-#line 1629 "go.y"
+  case 240:
+#line 1636 "go.y"
     {
 		(yyval.node) = nod(ODCLFIELD, (yyvsp[(1) - (2)].node), (yyvsp[(2) - (2)].node));
 		ifacedcl((yyval.node));
 	}
     break;
 
-  case 240:
-#line 1634 "go.y"
+  case 241:
+#line 1641 "go.y"
     {
 		(yyval.node) = nod(ODCLFIELD, N, oldname((yyvsp[(1) - (1)].sym)));
 	}
     break;
 
-  case 241:
-#line 1638 "go.y"
+  case 242:
+#line 1645 "go.y"
     {
 		(yyval.node) = nod(ODCLFIELD, N, oldname((yyvsp[(2) - (3)].sym)));
 		yyerror("cannot parenthesize embedded type");
 	}
     break;
 
-  case 242:
-#line 1645 "go.y"
+  case 243:
+#line 1652 "go.y"
     {
 		// without func keyword
 		(yyvsp[(2) - (4)].list) = checkarglist((yyvsp[(2) - (4)].list), 1);
@@ -4230,8 +4226,8 @@ yyreduce:
 	}
     break;
 
-  case 244:
-#line 1659 "go.y"
+  case 245:
+#line 1666 "go.y"
     {
 		(yyval.node) = nod(ONONAME, N, N);
 		(yyval.node)->sym = (yyvsp[(1) - (2)].sym);
@@ -4239,8 +4235,8 @@ yyreduce:
 	}
     break;
 
-  case 245:
-#line 1665 "go.y"
+  case 246:
+#line 1672 "go.y"
     {
 		(yyval.node) = nod(ONONAME, N, N);
 		(yyval.node)->sym = (yyvsp[(1) - (2)].sym);
@@ -4248,65 +4244,65 @@ yyreduce:
 	}
     break;
 
-  case 247:
-#line 1674 "go.y"
+  case 248:
+#line 1681 "go.y"
     {
 		(yyval.list) = list1((yyvsp[(1) - (1)].node));
 	}
     break;
 
-  case 248:
-#line 1678 "go.y"
+  case 249:
+#line 1685 "go.y"
     {
 		(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
 	}
     break;
 
-  case 249:
-#line 1683 "go.y"
+  case 250:
+#line 1690 "go.y"
     {
 		(yyval.list) = nil;
 	}
     break;
 
-  case 250:
-#line 1687 "go.y"
+  case 251:
+#line 1694 "go.y"
     {
 		(yyval.list) = (yyvsp[(1) - (2)].list);
 	}
     break;
 
-  case 251:
-#line 1695 "go.y"
+  case 252:
+#line 1702 "go.y"
     {
 		(yyval.node) = N;
 	}
     break;
 
-  case 253:
-#line 1700 "go.y"
+  case 254:
+#line 1707 "go.y"
     {
 		(yyval.node) = liststmt((yyvsp[(1) - (1)].list));
 	}
     break;
 
-  case 255:
-#line 1705 "go.y"
+  case 256:
+#line 1712 "go.y"
     {
 		(yyval.node) = N;
 	}
     break;
 
-  case 261:
-#line 1716 "go.y"
+  case 262:
+#line 1723 "go.y"
     {
 		(yyvsp[(1) - (2)].node) = nod(OLABEL, (yyvsp[(1) - (2)].node), N);
 		(yyvsp[(1) - (2)].node)->sym = dclstack;  // context, for goto restrictions
 	}
     break;
 
-  case 262:
-#line 1721 "go.y"
+  case 263:
+#line 1728 "go.y"
     {
 		NodeList *l;
 
@@ -4318,8 +4314,8 @@ yyreduce:
 	}
     break;
 
-  case 263:
-#line 1731 "go.y"
+  case 264:
+#line 1738 "go.y"
     {
 		// will be converted to OFALL
 		(yyval.node) = nod(OXFALL, N, N);
@@ -4327,44 +4323,44 @@ yyreduce:
 	}
     break;
 
-  case 264:
-#line 1737 "go.y"
+  case 265:
+#line 1744 "go.y"
     {
 		(yyval.node) = nod(OBREAK, (yyvsp[(2) - (2)].node), N);
 	}
     break;
 
-  case 265:
-#line 1741 "go.y"
+  case 266:
+#line 1748 "go.y"
     {
 		(yyval.node) = nod(OCONTINUE, (yyvsp[(2) - (2)].node), N);
 	}
     break;
 
-  case 266:
-#line 1745 "go.y"
+  case 267:
+#line 1752 "go.y"
     {
 		(yyval.node) = nod(OPROC, (yyvsp[(2) - (2)].node), N);
 	}
     break;
 
-  case 267:
-#line 1749 "go.y"
+  case 268:
+#line 1756 "go.y"
     {
 		(yyval.node) = nod(ODEFER, (yyvsp[(2) - (2)].node), N);
 	}
     break;
 
-  case 268:
-#line 1753 "go.y"
+  case 269:
+#line 1760 "go.y"
     {
 		(yyval.node) = nod(OGOTO, (yyvsp[(2) - (2)].node), N);
 		(yyval.node)->sym = dclstack;  // context, for goto restrictions
 	}
     break;
 
-  case 269:
-#line 1758 "go.y"
+  case 270:
+#line 1765 "go.y"
     {
 		(yyval.node) = nod(ORETURN, N, N);
 		(yyval.node)->list = (yyvsp[(2) - (2)].list);
@@ -4383,8 +4379,8 @@ yyreduce:
 	}
     break;
 
-  case 270:
-#line 1777 "go.y"
+  case 271:
+#line 1784 "go.y"
     {
 		(yyval.list) = nil;
 		if((yyvsp[(1) - (1)].node) != N)
@@ -4392,8 +4388,8 @@ yyreduce:
 	}
     break;
 
-  case 271:
-#line 1783 "go.y"
+  case 272:
+#line 1790 "go.y"
     {
 		(yyval.list) = (yyvsp[(1) - (3)].list);
 		if((yyvsp[(3) - (3)].node) != N)
@@ -4401,190 +4397,190 @@ yyreduce:
 	}
     break;
 
-  case 272:
-#line 1791 "go.y"
+  case 273:
+#line 1798 "go.y"
     {
 		(yyval.list) = list1((yyvsp[(1) - (1)].node));
 	}
     break;
 
-  case 273:
-#line 1795 "go.y"
+  case 274:
+#line 1802 "go.y"
     {
 		(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
 	}
     break;
 
-  case 274:
-#line 1801 "go.y"
+  case 275:
+#line 1808 "go.y"
     {
 		(yyval.list) = list1((yyvsp[(1) - (1)].node));
 	}
     break;
 
-  case 275:
-#line 1805 "go.y"
+  case 276:
+#line 1812 "go.y"
     {
 		(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
 	}
     break;
 
-  case 276:
-#line 1811 "go.y"
+  case 277:
+#line 1818 "go.y"
     {
 		(yyval.list) = list1((yyvsp[(1) - (1)].node));
 	}
     break;
 
-  case 277:
-#line 1815 "go.y"
+  case 278:
+#line 1822 "go.y"
     {
 		(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
 	}
     break;
 
-  case 278:
-#line 1821 "go.y"
+  case 279:
+#line 1828 "go.y"
     {
 		(yyval.list) = list1((yyvsp[(1) - (1)].node));
 	}
     break;
 
-  case 279:
-#line 1825 "go.y"
+  case 280:
+#line 1832 "go.y"
     {
 		(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
 	}
     break;
 
-  case 280:
-#line 1834 "go.y"
+  case 281:
+#line 1841 "go.y"
     {
 		(yyval.list) = list1((yyvsp[(1) - (1)].node));
 	}
     break;
 
-  case 281:
-#line 1838 "go.y"
+  case 282:
+#line 1845 "go.y"
     {
 		(yyval.list) = list1((yyvsp[(1) - (1)].node));
 	}
     break;
 
-  case 282:
-#line 1842 "go.y"
+  case 283:
+#line 1849 "go.y"
     {
 		(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
 	}
     break;
 
-  case 283:
-#line 1846 "go.y"
+  case 284:
+#line 1853 "go.y"
     {
 		(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
 	}
     break;
 
-  case 284:
-#line 1851 "go.y"
+  case 285:
+#line 1858 "go.y"
     {
 		(yyval.list) = nil;
 	}
     break;
 
-  case 285:
-#line 1855 "go.y"
+  case 286:
+#line 1862 "go.y"
     {
 		(yyval.list) = (yyvsp[(1) - (2)].list);
 	}
     break;
 
-  case 290:
-#line 1869 "go.y"
+  case 291:
+#line 1876 "go.y"
     {
 		(yyval.node) = N;
 	}
     break;
 
-  case 292:
-#line 1875 "go.y"
+  case 293:
+#line 1882 "go.y"
     {
 		(yyval.list) = nil;
 	}
     break;
 
-  case 294:
-#line 1881 "go.y"
+  case 295:
+#line 1888 "go.y"
     {
 		(yyval.node) = N;
 	}
     break;
 
-  case 296:
-#line 1887 "go.y"
+  case 297:
+#line 1894 "go.y"
     {
 		(yyval.list) = nil;
 	}
     break;
 
-  case 298:
-#line 1893 "go.y"
+  case 299:
+#line 1900 "go.y"
     {
 		(yyval.list) = nil;
 	}
     break;
 
-  case 300:
-#line 1899 "go.y"
+  case 301:
+#line 1906 "go.y"
     {
 		(yyval.list) = nil;
 	}
     break;
 
-  case 302:
-#line 1905 "go.y"
+  case 303:
+#line 1912 "go.y"
     {
 		(yyval.val).ctype = CTxxx;
 	}
     break;
 
-  case 304:
-#line 1915 "go.y"
+  case 305:
+#line 1922 "go.y"
     {
 		importimport((yyvsp[(2) - (4)].sym), (yyvsp[(3) - (4)].val).u.sval);
 	}
     break;
 
-  case 305:
-#line 1919 "go.y"
+  case 306:
+#line 1926 "go.y"
     {
 		importvar((yyvsp[(2) - (4)].sym), (yyvsp[(3) - (4)].type));
 	}
     break;
 
-  case 306:
-#line 1923 "go.y"
+  case 307:
+#line 1930 "go.y"
     {
 		importconst((yyvsp[(2) - (5)].sym), types[TIDEAL], (yyvsp[(4) - (5)].node));
 	}
     break;
 
-  case 307:
-#line 1927 "go.y"
+  case 308:
+#line 1934 "go.y"
     {
 		importconst((yyvsp[(2) - (6)].sym), (yyvsp[(3) - (6)].type), (yyvsp[(5) - (6)].node));
 	}
     break;
 
-  case 308:
-#line 1931 "go.y"
+  case 309:
+#line 1938 "go.y"
     {
 		importtype((yyvsp[(2) - (4)].type), (yyvsp[(3) - (4)].type));
 	}
     break;
 
-  case 309:
-#line 1935 "go.y"
+  case 310:
+#line 1942 "go.y"
     {
 		if((yyvsp[(2) - (4)].node) == N) {
 			dclcontext = PEXTERN;  // since we skip the funcbody below
@@ -4604,31 +4600,31 @@ yyreduce:
 	}
     break;
 
-  case 310:
-#line 1955 "go.y"
+  case 311:
+#line 1962 "go.y"
     {
 		(yyval.sym) = (yyvsp[(1) - (1)].sym);
 		structpkg = (yyval.sym)->pkg;
 	}
     break;
 
-  case 311:
-#line 1962 "go.y"
+  case 312:
+#line 1969 "go.y"
     {
 		(yyval.type) = pkgtype((yyvsp[(1) - (1)].sym));
 		importsym((yyvsp[(1) - (1)].sym), OTYPE);
 	}
     break;
 
-  case 317:
-#line 1982 "go.y"
+  case 318:
+#line 1989 "go.y"
     {
 		(yyval.type) = pkgtype((yyvsp[(1) - (1)].sym));
 	}
     break;
 
-  case 318:
-#line 1986 "go.y"
+  case 319:
+#line 1993 "go.y"
     {
 		// predefined name like uint8
 		(yyvsp[(1) - (1)].sym) = pkglookup((yyvsp[(1) - (1)].sym)->name, builtinpkg);
@@ -4640,50 +4636,50 @@ yyreduce:
 	}
     break;
 
-  case 319:
-#line 1996 "go.y"
+  case 320:
+#line 2003 "go.y"
     {
 		(yyval.type) = aindex(N, (yyvsp[(3) - (3)].type));
 	}
     break;
 
-  case 320:
-#line 2000 "go.y"
+  case 321:
+#line 2007 "go.y"
     {
 		(yyval.type) = aindex(nodlit((yyvsp[(2) - (4)].val)), (yyvsp[(4) - (4)].type));
 	}
     break;
 
-  case 321:
-#line 2004 "go.y"
+  case 322:
+#line 2011 "go.y"
     {
 		(yyval.type) = maptype((yyvsp[(3) - (5)].type), (yyvsp[(5) - (5)].type));
 	}
     break;
 
-  case 322:
-#line 2008 "go.y"
+  case 323:
+#line 2015 "go.y"
     {
 		(yyval.type) = tostruct((yyvsp[(3) - (4)].list));
 	}
     break;
 
-  case 323:
-#line 2012 "go.y"
+  case 324:
+#line 2019 "go.y"
     {
 		(yyval.type) = tointerface((yyvsp[(3) - (4)].list));
 	}
     break;
 
-  case 324:
-#line 2016 "go.y"
+  case 325:
+#line 2023 "go.y"
     {
 		(yyval.type) = ptrto((yyvsp[(2) - (2)].type));
 	}
     break;
 
-  case 325:
-#line 2020 "go.y"
+  case 326:
+#line 2027 "go.y"
     {
 		(yyval.type) = typ(TCHAN);
 		(yyval.type)->type = (yyvsp[(2) - (2)].type);
@@ -4691,8 +4687,8 @@ yyreduce:
 	}
     break;
 
-  case 326:
-#line 2026 "go.y"
+  case 327:
+#line 2033 "go.y"
     {
 		(yyval.type) = typ(TCHAN);
 		(yyval.type)->type = (yyvsp[(3) - (4)].type);
@@ -4700,8 +4696,8 @@ yyreduce:
 	}
     break;
 
-  case 327:
-#line 2032 "go.y"
+  case 328:
+#line 2039 "go.y"
     {
 		(yyval.type) = typ(TCHAN);
 		(yyval.type)->type = (yyvsp[(3) - (3)].type);
@@ -4709,8 +4705,8 @@ yyreduce:
 	}
     break;
 
-  case 328:
-#line 2040 "go.y"
+  case 329:
+#line 2047 "go.y"
     {
 		(yyval.type) = typ(TCHAN);
 		(yyval.type)->type = (yyvsp[(3) - (3)].type);
@@ -4718,15 +4714,15 @@ yyreduce:
 	}
     break;
 
-  case 329:
-#line 2048 "go.y"
+  case 330:
+#line 2055 "go.y"
     {
 		(yyval.type) = functype(nil, (yyvsp[(3) - (5)].list), (yyvsp[(5) - (5)].list));
 	}
     break;
 
-  case 330:
-#line 2054 "go.y"
+  case 331:
+#line 2061 "go.y"
     {
 		(yyval.node) = nod(ODCLFIELD, N, typenod((yyvsp[(2) - (3)].type)));
 		if((yyvsp[(1) - (3)].sym))
@@ -4735,8 +4731,8 @@ yyreduce:
 	}
     break;
 
-  case 331:
-#line 2061 "go.y"
+  case 332:
+#line 2068 "go.y"
     {
 		Type *t;
 	
@@ -4752,8 +4748,8 @@ yyreduce:
 	}
     break;
 
-  case 332:
-#line 2077 "go.y"
+  case 333:
+#line 2084 "go.y"
     {
 		Sym *s;
 		Pkg *p;
@@ -4775,50 +4771,50 @@ yyreduce:
 	}
     break;
 
-  case 333:
-#line 2099 "go.y"
+  case 334:
+#line 2106 "go.y"
     {
 		(yyval.node) = nod(ODCLFIELD, newname((yyvsp[(1) - (5)].sym)), typenod(functype(fakethis(), (yyvsp[(3) - (5)].list), (yyvsp[(5) - (5)].list))));
 	}
     break;
 
-  case 334:
-#line 2103 "go.y"
+  case 335:
+#line 2110 "go.y"
     {
 		(yyval.node) = nod(ODCLFIELD, N, typenod((yyvsp[(1) - (1)].type)));
 	}
     break;
 
-  case 335:
-#line 2108 "go.y"
+  case 336:
+#line 2115 "go.y"
     {
 		(yyval.list) = nil;
 	}
     break;
 
-  case 337:
-#line 2115 "go.y"
+  case 338:
+#line 2122 "go.y"
     {
 		(yyval.list) = (yyvsp[(2) - (3)].list);
 	}
     break;
 
-  case 338:
-#line 2119 "go.y"
+  case 339:
+#line 2126 "go.y"
     {
 		(yyval.list) = list1(nod(ODCLFIELD, N, typenod((yyvsp[(1) - (1)].type))));
 	}
     break;
 
-  case 339:
-#line 2129 "go.y"
+  case 340:
+#line 2136 "go.y"
     {
 		(yyval.node) = nodlit((yyvsp[(1) - (1)].val));
 	}
     break;
 
-  case 340:
-#line 2133 "go.y"
+  case 341:
+#line 2140 "go.y"
     {
 		(yyval.node) = nodlit((yyvsp[(2) - (2)].val));
 		switch((yyval.node)->val.ctype){
@@ -4839,8 +4835,8 @@ yyreduce:
 	}
     break;
 
-  case 341:
-#line 2152 "go.y"
+  case 342:
+#line 2159 "go.y"
     {
 		(yyval.node) = oldname(pkglookup((yyvsp[(1) - (1)].sym)->name, builtinpkg));
 		if((yyval.node)->op != OLITERAL)
@@ -4848,8 +4844,8 @@ yyreduce:
 	}
     break;
 
-  case 343:
-#line 2161 "go.y"
+  case 344:
+#line 2168 "go.y"
     {
 		if((yyvsp[(2) - (5)].node)->val.ctype == CTRUNE && (yyvsp[(4) - (5)].node)->val.ctype == CTINT) {
 			(yyval.node) = (yyvsp[(2) - (5)].node);
@@ -4862,43 +4858,43 @@ yyreduce:
 	}
     break;
 
-  case 346:
-#line 2177 "go.y"
+  case 347:
+#line 2184 "go.y"
     {
 		(yyval.list) = list1((yyvsp[(1) - (1)].node));
 	}
     break;
 
-  case 347:
-#line 2181 "go.y"
+  case 348:
+#line 2188 "go.y"
     {
 		(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
 	}
     break;
 
-  case 348:
-#line 2187 "go.y"
+  case 349:
+#line 2194 "go.y"
     {
 		(yyval.list) = list1((yyvsp[(1) - (1)].node));
 	}
     break;
 
-  case 349:
-#line 2191 "go.y"
+  case 350:
+#line 2198 "go.y"
     {
 		(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
 	}
     break;
 
-  case 350:
-#line 2197 "go.y"
+  case 351:
+#line 2204 "go.y"
     {
 		(yyval.list) = list1((yyvsp[(1) - (1)].node));
 	}
     break;
 
-  case 351:
-#line 2201 "go.y"
+  case 352:
+#line 2208 "go.y"
     {
 		(yyval.list) = list((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node));
 	}
@@ -4906,7 +4902,7 @@ yyreduce:
 
 
 /* Line 1267 of yacc.c.  */
-#line 4911 "y.tab.c"
+#line 4907 "y.tab.c"
       default: break;
     }
   YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
@@ -5120,7 +5116,7 @@ yyreturn:
 }
 
 
-#line 2205 "go.y"
+#line 2212 "go.y"
 
 
 static void
diff --git a/src/cmd/gc/yerr.h b/src/cmd/gc/yerr.h
index 1526d82..d0dd639 100644
--- a/src/cmd/gc/yerr.h
+++ b/src/cmd/gc/yerr.h
@@ -14,66 +14,66 @@ static struct {
 	// is converted by bisonerrors into the yystate and yychar caused
 	// by that token list.
 
-	222, ',',
-	"unexpected comma during import block",
+	{222, ',',
+	"unexpected comma during import block"},
 
-	32, ';',
-	"missing import path; require quoted string",
+	{32, ';',
+	"missing import path; require quoted string"},
 
-	378, ';',
-	"missing { after if clause",
+	{380, ';',
+	"missing { after if clause"},
 
-	399, ';',
-	"missing { after switch clause",
+	{401, ';',
+	"missing { after switch clause"},
 
-	238, ';',
-	"missing { after for clause",
+	{239, ';',
+	"missing { after for clause"},
 
-	476, LBODY,
-	"missing { after for clause",
+	{478, LBODY,
+	"missing { after for clause"},
 
-	22, '{',
-	"unexpected semicolon or newline before {",
+	{22, '{',
+	"unexpected semicolon or newline before {"},
 
-	145, ';',
-	"unexpected semicolon or newline in type declaration",
+	{145, ';',
+	"unexpected semicolon or newline in type declaration"},
 
-	37, '}',
-	"unexpected } in channel type",
+	{37, '}',
+	"unexpected } in channel type"},
 	
-	37, ')',
-	"unexpected ) in channel type",
+	{37, ')',
+	"unexpected ) in channel type"},
 	
-	37, ',',
-	"unexpected comma in channel type",
+	{37, ',',
+	"unexpected comma in channel type"},
 
-	439, LELSE,
-	"unexpected semicolon or newline before else",
+	{441, LELSE,
+	"unexpected semicolon or newline before else"},
 
-	258, ',',
-	"name list not allowed in interface type",
+	{259, ',',
+	"name list not allowed in interface type"},
 
-	238, LVAR,
-	"var declaration not allowed in for initializer",
+	{239, LVAR,
+	"var declaration not allowed in for initializer"},
 
-	65, '{',
-	"unexpected { at end of statement",
+	{65, '{',
+	"unexpected { at end of statement"},
 
-	377, '{',
-	"unexpected { at end of statement",
+	{379, '{',
+	"unexpected { at end of statement"},
 	
-	126, ';',
-	"argument to go/defer must be function call",
+	{126, ';',
+	"argument to go/defer must be function call"},
 	
-	426, ';',
-	"need trailing comma before newline in composite literal",
+	{428, ';',
+	"need trailing comma before newline in composite literal"},
 	
-	437, ';',
-	"need trailing comma before newline in composite literal",
+	{439, ';',
+	"need trailing comma before newline in composite literal"},
 	
-	113, LNAME,
-	"nested func not allowed",
+	{113, LNAME,
+	"nested func not allowed"},
 
-	645, ';',
-	"else must be followed by if or statement block"
+	{647, ';',
+	"else must be followed by if or statement block"}
 };
diff --git a/src/cmd/go/build.go b/src/cmd/go/build.go
index 3645f1c..1dd4314 100644
--- a/src/cmd/go/build.go
+++ b/src/cmd/go/build.go
@@ -57,6 +57,7 @@ and test commands:
 
 	-a
 		force rebuilding of packages that are already up-to-date.
+		In Go releases, does not apply to the standard library.
 	-n
 		print the commands but do not run them.
 	-p n
@@ -64,7 +65,7 @@ and test commands:
 		The default is the number of CPUs available.
 	-race
 		enable data race detection.
-		Supported only on linux/amd64, darwin/amd64 and windows/amd64.
+		Supported only on linux/amd64, freebsd/amd64, darwin/amd64 and windows/amd64.
 	-v
 		print the names of packages as they are compiled.
 	-work
@@ -284,23 +285,26 @@ func runBuild(cmd *Command, args []string) {
 		}
 	}
 
+	depMode := modeBuild
+	if buildI {
+		depMode = modeInstall
+	}
+
 	if *buildO != "" {
 		if len(pkgs) > 1 {
 			fatalf("go build: cannot use -o with multiple packages")
+		} else if len(pkgs) == 0 {
+			fatalf("no packages to build")
 		}
 		p := pkgs[0]
 		p.target = "" // must build - not up to date
-		a := b.action(modeInstall, modeBuild, p)
+		a := b.action(modeInstall, depMode, p)
 		a.target = *buildO
 		b.do(a)
 		return
 	}
 
 	a := &action{}
-	depMode := modeBuild
-	if buildI {
-		depMode = modeInstall
-	}
 	for _, p := range packages(args) {
 		a.deps = append(a.deps, b.action(modeBuild, depMode, p))
 	}
@@ -431,12 +435,11 @@ const (
 )
 
 var (
-	goroot       = filepath.Clean(runtime.GOROOT())
-	gobin        = os.Getenv("GOBIN")
-	gorootBin    = filepath.Join(goroot, "bin")
-	gorootSrcPkg = filepath.Join(goroot, "src/pkg")
-	gorootPkg    = filepath.Join(goroot, "pkg")
-	gorootSrc    = filepath.Join(goroot, "src")
+	goroot    = filepath.Clean(runtime.GOROOT())
+	gobin     = os.Getenv("GOBIN")
+	gorootBin = filepath.Join(goroot, "bin")
+	gorootPkg = filepath.Join(goroot, "pkg")
+	gorootSrc = filepath.Join(goroot, "src")
 )
 
 func (b *builder) init() {
@@ -503,8 +506,13 @@ func goFilesPackage(gofiles []string) *Package {
 	}
 	ctxt.ReadDir = func(string) ([]os.FileInfo, error) { return dirent, nil }
 
-	if !filepath.IsAbs(dir) {
-		dir = filepath.Join(cwd, dir)
+	var err error
+	if dir == "" {
+		dir = cwd
+	}
+	dir, err = filepath.Abs(dir)
+	if err != nil {
+		fatalf("%s", err)
 	}
 
 	bp, err := ctxt.ImportDir(dir, 0)
@@ -823,12 +831,17 @@ func (b *builder) build(a *action) (err error) {
 		}
 	}
 
-	var gofiles, cfiles, sfiles, objects, cgoObjects []string
+	var gofiles, cfiles, sfiles, objects, cgoObjects, pcCFLAGS, pcLDFLAGS []string
 
 	gofiles = append(gofiles, a.p.GoFiles...)
 	cfiles = append(cfiles, a.p.CFiles...)
 	sfiles = append(sfiles, a.p.SFiles...)
 
+	if a.p.usesCgo() || a.p.usesSwig() {
+		if pcCFLAGS, pcLDFLAGS, err = b.getPkgConfigFlags(a.p); err != nil {
+			return
+		}
+	}
 	// Run cgo.
 	if a.p.usesCgo() {
 		// In a package using cgo, cgo compiles the C, C++ and assembly files with gcc.
@@ -859,7 +872,7 @@ func (b *builder) build(a *action) (err error) {
 		if a.cgo != nil && a.cgo.target != "" {
 			cgoExe = a.cgo.target
 		}
-		outGo, outObj, err := b.cgo(a.p, cgoExe, obj, gccfiles, a.p.CXXFiles, a.p.MFiles)
+		outGo, outObj, err := b.cgo(a.p, cgoExe, obj, pcCFLAGS, pcLDFLAGS, gccfiles, a.p.CXXFiles, a.p.MFiles)
 		if err != nil {
 			return err
 		}
@@ -872,9 +885,18 @@ func (b *builder) build(a *action) (err error) {
 		// In a package using SWIG, any .c or .s files are
 		// compiled with gcc.
 		gccfiles := append(cfiles, sfiles...)
+		cxxfiles, mfiles := a.p.CXXFiles, a.p.MFiles
 		cfiles = nil
 		sfiles = nil
-		outGo, outObj, err := b.swig(a.p, obj, gccfiles, a.p.CXXFiles, a.p.MFiles)
+
+		// Don't build c/c++ files twice if cgo is enabled (mainly for pkg-config).
+		if a.p.usesCgo() {
+			cxxfiles = nil
+			gccfiles = nil
+			mfiles = nil
+		}
+
+		outGo, outObj, err := b.swig(a.p, obj, pcCFLAGS, gccfiles, cxxfiles, mfiles)
 		if err != nil {
 			return err
 		}
@@ -883,7 +905,7 @@ func (b *builder) build(a *action) (err error) {
 	}
 
 	if len(gofiles) == 0 {
-		return &build.NoGoError{a.p.Dir}
+		return &build.NoGoError{Dir: a.p.Dir}
 	}
 
 	// If we're doing coverage, preprocess the .go files and put them in the work directory
@@ -1018,6 +1040,34 @@ func (b *builder) build(a *action) (err error) {
 	return nil
 }
 
+// Calls pkg-config if needed and returns the cflags/ldflags needed to build the package.
+func (b *builder) getPkgConfigFlags(p *Package) (cflags, ldflags []string, err error) {
+	if pkgs := p.CgoPkgConfig; len(pkgs) > 0 {
+		var out []byte
+		out, err = b.runOut(p.Dir, p.ImportPath, nil, "pkg-config", "--cflags", pkgs)
+		if err != nil {
+			b.showOutput(p.Dir, "pkg-config --cflags "+strings.Join(pkgs, " "), string(out))
+			b.print(err.Error() + "\n")
+			err = errPrintedOutput
+			return
+		}
+		if len(out) > 0 {
+			cflags = strings.Fields(string(out))
+		}
+		out, err = b.runOut(p.Dir, p.ImportPath, nil, "pkg-config", "--libs", pkgs)
+		if err != nil {
+			b.showOutput(p.Dir, "pkg-config --libs "+strings.Join(pkgs, " "), string(out))
+			b.print(err.Error() + "\n")
+			err = errPrintedOutput
+			return
+		}
+		if len(out) > 0 {
+			ldflags = strings.Fields(string(out))
+		}
+	}
+	return
+}
+
 // install is the action for installing a single package or executable.
 func (b *builder) install(a *action) (err error) {
 	defer func() {
@@ -1253,7 +1303,7 @@ func (b *builder) showcmd(dir string, format string, args ...interface{}) {
 // the source directory for the package that has failed to build.
 // showOutput rewrites mentions of dir with a relative path to dir
 // when the relative path is shorter.  This is usually more pleasant.
-// For example, if fmt doesn't compile and we are in src/pkg/html,
+// For example, if fmt doesn't compile and we are in src/html,
 // the output is
 //
 //	$ go build
@@ -1265,7 +1315,7 @@ func (b *builder) showcmd(dir string, format string, args ...interface{}) {
 //
 //	$ go build
 //	# fmt
-//	/usr/gopher/go/src/pkg/fmt/print.go:1090: undefined: asdf
+//	/usr/gopher/go/src/fmt/print.go:1090: undefined: asdf
 //	$
 //
 // showOutput also replaces references to the work directory with $WORK.
@@ -1425,6 +1475,14 @@ func (b *builder) runOut(dir string, desc string, env []string, cmdargs ...inter
 			continue
 		}
 
+		// err can be something like 'exit status 1'.
+		// Add information about what program was running.
+		// Note that if buf.Bytes() is non-empty, the caller usually
+		// shows buf.Bytes() and does not print err at all, so the
+		// prefix here does not make most output any more verbose.
+		if err != nil {
+			err = errors.New(cmdline[0] + ": " + err.Error())
+		}
 		return buf.Bytes(), err
 	}
 }
@@ -1587,7 +1645,7 @@ func (gcToolchain) gc(b *builder, p *Package, archive, obj string, importArgs []
 	extFiles := len(p.CgoFiles) + len(p.CFiles) + len(p.CXXFiles) + len(p.MFiles) + len(p.SFiles) + len(p.SysoFiles) + len(p.SwigFiles) + len(p.SwigCXXFiles)
 	if p.Standard {
 		switch p.ImportPath {
-		case "os", "runtime/pprof", "sync", "time":
+		case "bytes", "net", "os", "runtime/pprof", "sync", "time":
 			extFiles++
 		}
 	}
@@ -1611,8 +1669,10 @@ func (gcToolchain) gc(b *builder, p *Package, archive, obj string, importArgs []
 }
 
 func (gcToolchain) asm(b *builder, p *Package, obj, ofile, sfile string) error {
+	// Add -I pkg/GOOS_GOARCH so #include "textflag.h" works in .s files.
+	inc := filepath.Join(goroot, "pkg", fmt.Sprintf("%s_%s", goos, goarch))
 	sfile = mkAbs(p.Dir, sfile)
-	return b.run(p.Dir, p.ImportPath, nil, tool(archChar+"a"), "-trimpath", b.work, "-I", obj, "-o", ofile, "-D", "GOOS_"+goos, "-D", "GOARCH_"+goarch, sfile)
+	return b.run(p.Dir, p.ImportPath, nil, tool(archChar+"a"), "-trimpath", b.work, "-I", obj, "-I", inc, "-o", ofile, "-D", "GOOS_"+goos, "-D", "GOARCH_"+goarch, sfile)
 }
 
 func (gcToolchain) pkgpath(basedir string, p *Package) string {
@@ -1706,7 +1766,7 @@ func packInternal(b *builder, afile string, ofiles []string) error {
 
 func (gcToolchain) ld(b *builder, p *Package, out string, allactions []*action, mainpkg string, ofiles []string) error {
 	importArgs := b.includeArgs("-L", allactions)
-	cxx := false
+	cxx := len(p.CXXFiles) > 0
 	for _, a := range allactions {
 		if a.p != nil && len(a.p.CXXFiles) > 0 {
 			cxx = true
@@ -1766,14 +1826,30 @@ func (gcToolchain) ld(b *builder, p *Package, out string, allactions []*action,
 func (gcToolchain) cc(b *builder, p *Package, objdir, ofile, cfile string) error {
 	inc := filepath.Join(goroot, "pkg", fmt.Sprintf("%s_%s", goos, goarch))
 	cfile = mkAbs(p.Dir, cfile)
-	args := stringList(tool(archChar+"c"), "-F", "-V", "-w", "-trimpath", b.work, "-I", objdir, "-I", inc, "-o", ofile, buildCcflags, "-D", "GOOS_"+goos, "-D", "GOARCH_"+goarch, cfile)
+	warn := []string{"-w"}
+	if p.usesSwig() {
+		// When using SWIG, this compiler is only used to
+		// compile the C files generated by SWIG.
+		// We don't want warnings.
+		// See issue 9065 for details.
+		warn = nil
+	}
+	args := stringList(tool(archChar+"c"), "-F", "-V", warn, "-trimpath", b.work, "-I", objdir, "-I", inc, "-o", ofile, buildCcflags, "-D", "GOOS_"+goos, "-D", "GOARCH_"+goarch, cfile)
 	return b.run(p.Dir, p.ImportPath, nil, args)
 }
 
 // The Gccgo toolchain.
 type gccgoToolchain struct{}
 
-var gccgoBin, _ = exec.LookPath("gccgo")
+var gccgoName, gccgoBin string
+
+func init() {
+	gccgoName = os.Getenv("GCCGO")
+	if gccgoName == "" {
+		gccgoName = "gccgo"
+	}
+	gccgoBin, _ = exec.LookPath(gccgoName)
+}
 
 func (gccgoToolchain) compiler() string {
 	return gccgoBin
@@ -1784,7 +1860,7 @@ func (gccgoToolchain) linker() string {
 }
 
 func (gccgoToolchain) gc(b *builder, p *Package, archive, obj string, importArgs []string, gofiles []string) (ofile string, output []byte, err error) {
-	out := p.Name + ".o"
+	out := "_go_.o"
 	ofile = obj + out
 	gcargs := []string{"-g"}
 	gcargs = append(gcargs, b.gccArchArgs()...)
@@ -1794,7 +1870,7 @@ func (gccgoToolchain) gc(b *builder, p *Package, archive, obj string, importArgs
 	if p.localPrefix != "" {
 		gcargs = append(gcargs, "-fgo-relative-import-path="+p.localPrefix)
 	}
-	args := stringList("gccgo", importArgs, "-c", gcargs, "-o", ofile, buildGccgoflags)
+	args := stringList(gccgoName, importArgs, "-c", gcargs, "-o", ofile, buildGccgoflags)
 	for _, f := range gofiles {
 		args = append(args, mkAbs(p.Dir, f))
 	}
@@ -1810,7 +1886,7 @@ func (gccgoToolchain) asm(b *builder, p *Package, obj, ofile, sfile string) erro
 		defs = append(defs, `-D`, `GOPKGPATH="`+pkgpath+`"`)
 	}
 	defs = append(defs, b.gccArchArgs()...)
-	return b.run(p.Dir, p.ImportPath, nil, "gccgo", "-I", obj, "-o", ofile, defs, sfile)
+	return b.run(p.Dir, p.ImportPath, nil, gccgoName, "-I", obj, "-o", ofile, defs, sfile)
 }
 
 func (gccgoToolchain) pkgpath(basedir string, p *Package) string {
@@ -1836,8 +1912,8 @@ func (tools gccgoToolchain) ld(b *builder, p *Package, out string, allactions []
 	ldflags := b.gccArchArgs()
 	cgoldflags := []string{}
 	usesCgo := false
-	cxx := false
-	objc := false
+	cxx := len(p.CXXFiles) > 0
+	objc := len(p.MFiles) > 0
 
 	// Prefer the output of an install action to the output of a build action,
 	// because the install action will delete the output of the build action.
@@ -1877,6 +1953,7 @@ func (tools gccgoToolchain) ld(b *builder, p *Package, out string, allactions []
 	}
 	ldflags = append(ldflags, afiles...)
 	ldflags = append(ldflags, cgoldflags...)
+	ldflags = append(ldflags, envList("CGO_LDFLAGS", "")...)
 	ldflags = append(ldflags, p.CgoLDFLAGS...)
 	if usesCgo && goos == "linux" {
 		ldflags = append(ldflags, "-Wl,-E")
@@ -1887,7 +1964,7 @@ func (tools gccgoToolchain) ld(b *builder, p *Package, out string, allactions []
 	if objc {
 		ldflags = append(ldflags, "-lobjc")
 	}
-	return b.run(".", p.ImportPath, nil, "gccgo", "-o", out, ofiles, "-Wl,-(", ldflags, "-Wl,-)", buildGccgoflags)
+	return b.run(".", p.ImportPath, nil, gccgoName, "-o", out, ofiles, "-Wl,-(", ldflags, "-Wl,-)", buildGccgoflags)
 }
 
 func (gccgoToolchain) cc(b *builder, p *Package, objdir, ofile, cfile string) error {
@@ -1898,8 +1975,7 @@ func (gccgoToolchain) cc(b *builder, p *Package, objdir, ofile, cfile string) er
 	if pkgpath := gccgoCleanPkgpath(p); pkgpath != "" {
 		defs = append(defs, `-D`, `GOPKGPATH="`+pkgpath+`"`)
 	}
-	// TODO: Support using clang here (during gccgo build)?
-	return b.run(p.Dir, p.ImportPath, nil, "gcc", "-Wall", "-g",
+	return b.run(p.Dir, p.ImportPath, nil, envList("CC", defaultCC), "-Wall", "-g",
 		"-I", objdir, "-I", inc, "-o", ofile, defs, "-c", cfile)
 }
 
@@ -1950,9 +2026,9 @@ func (b *builder) libgcc(p *Package) (string, error) {
 		return "$LIBGCC", nil
 	}
 
-	// clang might not be able to find libgcc, and in that case,
+	// The compiler might not be able to find libgcc, and in that case,
 	// it will simply return "libgcc.a", which is of no use to us.
-	if strings.Contains(gccCmd[0], "clang") && !filepath.IsAbs(string(f)) {
+	if !filepath.IsAbs(string(f)) {
 		return "", nil
 	}
 
@@ -2090,36 +2166,16 @@ var (
 	cgoLibGccFileOnce sync.Once
 )
 
-func (b *builder) cgo(p *Package, cgoExe, obj string, gccfiles, gxxfiles, mfiles []string) (outGo, outObj []string, err error) {
+func (b *builder) cgo(p *Package, cgoExe, obj string, pcCFLAGS, pcLDFLAGS, gccfiles, gxxfiles, mfiles []string) (outGo, outObj []string, err error) {
 	cgoCPPFLAGS, cgoCFLAGS, cgoCXXFLAGS, cgoLDFLAGS := b.cflags(p, true)
 	_, cgoexeCFLAGS, _, _ := b.cflags(p, false)
-
+	cgoCPPFLAGS = append(cgoCPPFLAGS, pcCFLAGS...)
+	cgoLDFLAGS = append(cgoLDFLAGS, pcLDFLAGS...)
 	// If we are compiling Objective-C code, then we need to link against libobjc
 	if len(mfiles) > 0 {
 		cgoLDFLAGS = append(cgoLDFLAGS, "-lobjc")
 	}
 
-	if pkgs := p.CgoPkgConfig; len(pkgs) > 0 {
-		out, err := b.runOut(p.Dir, p.ImportPath, nil, "pkg-config", "--cflags", pkgs)
-		if err != nil {
-			b.showOutput(p.Dir, "pkg-config --cflags "+strings.Join(pkgs, " "), string(out))
-			b.print(err.Error() + "\n")
-			return nil, nil, errPrintedOutput
-		}
-		if len(out) > 0 {
-			cgoCPPFLAGS = append(cgoCPPFLAGS, strings.Fields(string(out))...)
-		}
-		out, err = b.runOut(p.Dir, p.ImportPath, nil, "pkg-config", "--libs", pkgs)
-		if err != nil {
-			b.showOutput(p.Dir, "pkg-config --libs "+strings.Join(pkgs, " "), string(out))
-			b.print(err.Error() + "\n")
-			return nil, nil, errPrintedOutput
-		}
-		if len(out) > 0 {
-			cgoLDFLAGS = append(cgoLDFLAGS, strings.Fields(string(out))...)
-		}
-	}
-
 	// Allows including _cgo_export.h from .[ch] files in the package.
 	cgoCPPFLAGS = append(cgoCPPFLAGS, "-I", obj)
 
@@ -2196,6 +2252,14 @@ func (b *builder) cgo(p *Package, cgoExe, obj string, gccfiles, gxxfiles, mfiles
 			strings.HasSuffix(f, ".so"),
 			strings.HasSuffix(f, ".dll"):
 			continue
+		// Remove any -fsanitize=foo flags.
+		// Otherwise the compiler driver thinks that we are doing final link
+		// and links sanitizer runtime into the object file. But we are not doing
+		// the final link, we will link the resulting object file again. And
+		// so the program ends up with two copies of sanitizer runtime.
+		// See issue 8788 for details.
+		case strings.HasPrefix(f, "-fsanitize="):
+			continue
 		default:
 			bareLDFLAGS = append(bareLDFLAGS, f)
 		}
@@ -2262,13 +2326,14 @@ func (b *builder) cgo(p *Package, cgoExe, obj string, gccfiles, gxxfiles, mfiles
 
 	linkobj = append(linkobj, p.SysoFiles...)
 	dynobj := obj + "_cgo_.o"
-	if goarch == "arm" && goos == "linux" { // we need to use -pie for Linux/ARM to get accurate imported sym
+	pie := goarch == "arm" && (goos == "linux" || goos == "android")
+	if pie { // we need to use -pie for Linux/ARM to get accurate imported sym
 		cgoLDFLAGS = append(cgoLDFLAGS, "-pie")
 	}
 	if err := b.gccld(p, dynobj, cgoLDFLAGS, linkobj); err != nil {
 		return nil, nil, err
 	}
-	if goarch == "arm" && goos == "linux" { // but we don't need -pie for normal cgo programs
+	if pie { // but we don't need -pie for normal cgo programs
 		cgoLDFLAGS = cgoLDFLAGS[0 : len(cgoLDFLAGS)-1]
 	}
 
@@ -2302,7 +2367,23 @@ func (b *builder) cgo(p *Package, cgoExe, obj string, gccfiles, gxxfiles, mfiles
 			nonGccObjs = append(nonGccObjs, f)
 		}
 	}
-	if err := b.gccld(p, ofile, stringList(bareLDFLAGS, "-Wl,-r", "-nostdlib", staticLibs), gccObjs); err != nil {
+	ldflags := stringList(bareLDFLAGS, "-Wl,-r", "-nostdlib", staticLibs)
+
+	// Some systems, such as Ubuntu, always add --build-id to
+	// every link, but we don't want a build ID since we are
+	// producing an object file.  On some of those system a plain
+	// -r (not -Wl,-r) will turn off --build-id, but clang 3.0
+	// doesn't support a plain -r.  I don't know how to turn off
+	// --build-id when using clang other than passing a trailing
+	// --build-id=none.  So that is what we do, but only on
+	// systems likely to support it, which is to say, systems that
+	// normally use gold or the GNU linker.
+	switch goos {
+	case "android", "dragonfly", "linux", "netbsd":
+		ldflags = append(ldflags, "-Wl,--build-id=none")
+	}
+
+	if err := b.gccld(p, ofile, ldflags, gccObjs); err != nil {
 		return nil, nil, err
 	}
 
@@ -2317,7 +2398,7 @@ func (b *builder) cgo(p *Package, cgoExe, obj string, gccfiles, gxxfiles, mfiles
 // Run SWIG on all SWIG input files.
 // TODO: Don't build a shared library, once SWIG emits the necessary
 // pragmas for external linking.
-func (b *builder) swig(p *Package, obj string, gccfiles, gxxfiles, mfiles []string) (outGo, outObj []string, err error) {
+func (b *builder) swig(p *Package, obj string, pcCFLAGS, gccfiles, gxxfiles, mfiles []string) (outGo, outObj []string, err error) {
 	cgoCPPFLAGS, cgoCFLAGS, cgoCXXFLAGS, _ := b.cflags(p, true)
 	cflags := stringList(cgoCPPFLAGS, cgoCFLAGS)
 	cxxflags := stringList(cgoCPPFLAGS, cgoCXXFLAGS)
@@ -2358,7 +2439,7 @@ func (b *builder) swig(p *Package, obj string, gccfiles, gxxfiles, mfiles []stri
 	}
 
 	for _, f := range p.SwigFiles {
-		goFile, objFile, gccObjFile, err := b.swigOne(p, f, obj, false, intgosize)
+		goFile, objFile, gccObjFile, err := b.swigOne(p, f, obj, pcCFLAGS, false, intgosize)
 		if err != nil {
 			return nil, nil, err
 		}
@@ -2373,7 +2454,7 @@ func (b *builder) swig(p *Package, obj string, gccfiles, gxxfiles, mfiles []stri
 		}
 	}
 	for _, f := range p.SwigCXXFiles {
-		goFile, objFile, gccObjFile, err := b.swigOne(p, f, obj, true, intgosize)
+		goFile, objFile, gccObjFile, err := b.swigOne(p, f, obj, pcCFLAGS, true, intgosize)
 		if err != nil {
 			return nil, nil, err
 		}
@@ -2452,13 +2533,13 @@ func (b *builder) swigIntSize(obj string) (intsize string, err error) {
 }
 
 // Run SWIG on one SWIG input file.
-func (b *builder) swigOne(p *Package, file, obj string, cxx bool, intgosize string) (outGo, outObj, objGccObj string, err error) {
+func (b *builder) swigOne(p *Package, file, obj string, pcCFLAGS []string, cxx bool, intgosize string) (outGo, outObj, objGccObj string, err error) {
 	cgoCPPFLAGS, cgoCFLAGS, cgoCXXFLAGS, _ := b.cflags(p, true)
 	var cflags []string
 	if cxx {
-		cflags = stringList(cgoCPPFLAGS, cgoCXXFLAGS)
+		cflags = stringList(cgoCPPFLAGS, pcCFLAGS, cgoCXXFLAGS)
 	} else {
-		cflags = stringList(cgoCPPFLAGS, cgoCFLAGS)
+		cflags = stringList(cgoCPPFLAGS, pcCFLAGS, cgoCFLAGS)
 	}
 
 	n := 5 // length of ".swig"
@@ -2484,6 +2565,13 @@ func (b *builder) swigOne(p *Package, file, obj string, cxx bool, intgosize stri
 		"-o", obj + gccBase + gccExt,
 		"-outdir", obj,
 	}
+
+	for _, f := range cflags {
+		if len(f) > 3 && f[:2] == "-I" {
+			args = append(args, f)
+		}
+	}
+
 	if gccgo {
 		args = append(args, "-gccgo")
 		if pkgpath := gccgoPkgpath(p); pkgpath != "" {
@@ -2556,8 +2644,8 @@ func raceInit() {
 	if !buildRace {
 		return
 	}
-	if goarch != "amd64" || goos != "linux" && goos != "darwin" && goos != "windows" {
-		fmt.Fprintf(os.Stderr, "go %s: -race is only supported on linux/amd64, darwin/amd64 and windows/amd64\n", flag.Args()[0])
+	if goarch != "amd64" || goos != "linux" && goos != "freebsd" && goos != "darwin" && goos != "windows" {
+		fmt.Fprintf(os.Stderr, "go %s: -race is only supported on linux/amd64, freebsd/amd64, darwin/amd64 and windows/amd64\n", flag.Args()[0])
 		os.Exit(2)
 	}
 	buildGcflags = append(buildGcflags, "-race")
diff --git a/src/cmd/go/doc.go b/src/cmd/go/doc.go
index 9840804..d0d8a8a 100644
--- a/src/cmd/go/doc.go
+++ b/src/cmd/go/doc.go
@@ -19,6 +19,7 @@ The commands are:
     env         print Go environment information
     fix         run go tool fix on packages
     fmt         run gofmt on package sources
+    generate    generate Go files by processing source
     get         download and install packages and dependencies
     install     compile and install packages and dependencies
     list        list packages
@@ -75,6 +76,7 @@ and test commands:
 
 	-a
 		force rebuilding of packages that are already up-to-date.
+		In Go releases, does not apply to the standard library.
 	-n
 		print the commands but do not run them.
 	-p n
@@ -82,7 +84,7 @@ and test commands:
 		The default is the number of CPUs available.
 	-race
 		enable data race detection.
-		Supported only on linux/amd64, darwin/amd64 and windows/amd64.
+		Supported only on linux/amd64, freebsd/amd64, darwin/amd64 and windows/amd64.
 	-v
 		print the names of packages as they are compiled.
 	-work
@@ -219,11 +221,110 @@ To run gofmt with specific options, run gofmt itself.
 See also: go fix, go vet.
 
 
+Generate Go files by processing source
+
+Usage:
+
+	go generate [-run regexp] [file.go... | packages]
+
+Generate runs commands described by directives within existing
+files. Those commands can run any process but the intent is to
+create or update Go source files, for instance by running yacc.
+
+Go generate is never run automatically by go build, go get, go test,
+and so on. It must be run explicitly.
+
+Go generate scans the file for directives, which are lines of
+the form,
+
+	//go:generate command argument...
+
+(note: no leading spaces and no space in "//go") where command
+is the generator to be run, corresponding to an executable file
+that can be run locally. It must either be in the shell path
+(gofmt), a fully qualified path (/usr/you/bin/mytool), or a
+command alias, described below.
+
+Note that go generate does not parse the file, so lines that look
+like directives in comments or multiline strings will be treated
+as directives.
+
+The arguments to the directive are space-separated tokens or
+double-quoted strings passed to the generator as individual
+arguments when it is run.
+
+Quoted strings use Go syntax and are evaluated before execution; a
+quoted string appears as a single argument to the generator.
+
+Go generate sets several variables when it runs the generator:
+
+	$GOARCH
+		The execution architecture (arm, amd64, etc.)
+	$GOOS
+		The execution operating system (linux, windows, etc.)
+	$GOFILE
+		The base name of the file.
+	$GOPACKAGE
+		The name of the package of the file containing the directive.
+
+Other than variable substitution and quoted-string evaluation, no
+special processing such as "globbing" is performed on the command
+line.
+
+As a last step before running the command, any invocations of any
+environment variables with alphanumeric names, such as $GOFILE or
+$HOME, are expanded throughout the command line. The syntax for
+variable expansion is $NAME on all operating systems.  Due to the
+order of evaluation, variables are expanded even inside quoted
+strings. If the variable NAME is not set, $NAME expands to the
+empty string.
+
+A directive of the form,
+
+	//go:generate -command xxx args...
+
+specifies, for the remainder of this source file only, that the
+string xxx represents the command identified by the arguments. This
+can be used to create aliases or to handle multiword generators.
+For example,
+
+	//go:generate -command yacc go tool yacc
+
+specifies that the command "yacc" represents the generator
+"go tool yacc".
+
+Generate processes packages in the order given on the command line,
+one at a time. If the command line lists .go files, they are treated
+as a single package. Within a package, generate processes the
+source files in a package in file name order, one at a time. Within
+a source file, generate runs generators in the order they appear
+in the file, one at a time.
+
+If any generator returns an error exit status, "go generate" skips
+all further processing for that package.
+
+The generator is run in the package's source directory.
+
+Go generate accepts one specific flag:
+
+	-run=""
+		if non-empty, specifies a regular expression to
+		select directives whose command matches the expression.
+
+It also accepts the standard build flags -v, -n, and -x.
+The -v flag prints the names of packages and files as they are
+processed.
+The -n flag prints commands that would be executed.
+The -x flag prints commands as they are executed.
+
+For more about specifying packages, see 'go help packages'.
+
+
 Download and install packages and dependencies
 
 Usage:
 
-	go get [-d] [-fix] [-t] [-u] [build flags] [packages]
+	go get [-d] [-f] [-fix] [-t] [-u] [build flags] [packages]
 
 Get downloads and installs the packages named by the import paths,
 along with their dependencies.
@@ -231,6 +332,11 @@ along with their dependencies.
 The -d flag instructs get to stop after downloading the packages; that is,
 it instructs get not to install the packages.
 
+The -f flag, valid only when -u is set, forces get -u not to verify that
+each package has been checked out from the source control repository
+implied by its import path. This can be useful if the source is a local fork
+of the original.
+
 The -fix flag instructs get to run the fix tool on the downloaded packages
 before resolving dependencies or building the code.
 
@@ -291,28 +397,29 @@ syntax of package template.  The default output is equivalent to -f
 '{{.ImportPath}}'. The struct being passed to the template is:
 
     type Package struct {
-        Dir        string // directory containing package sources
-        ImportPath string // import path of package in dir
-        Name       string // package name
-        Doc        string // package documentation string
-        Target     string // install path
-        Goroot     bool   // is this package in the Go root?
-        Standard   bool   // is this package part of the standard Go library?
-        Stale      bool   // would 'go install' do anything for this package?
-        Root       string // Go root or Go path dir containing this package
+        Dir           string // directory containing package sources
+        ImportPath    string // import path of package in dir
+        ImportComment string // path in import comment on package statement
+        Name          string // package name
+        Doc           string // package documentation string
+        Target        string // install path
+        Goroot        bool   // is this package in the Go root?
+        Standard      bool   // is this package part of the standard Go library?
+        Stale         bool   // would 'go install' do anything for this package?
+        Root          string // Go root or Go path dir containing this package
 
         // Source files
-        GoFiles  []string       // .go source files (excluding CgoFiles, TestGoFiles, XTestGoFiles)
-        CgoFiles []string       // .go sources files that import "C"
+        GoFiles        []string // .go source files (excluding CgoFiles, TestGoFiles, XTestGoFiles)
+        CgoFiles       []string // .go sources files that import "C"
         IgnoredGoFiles []string // .go sources ignored due to build constraints
-        CFiles   []string       // .c source files
-        CXXFiles []string       // .cc, .cxx and .cpp source files
-        MFiles   []string       // .m source files
-        HFiles   []string       // .h, .hh, .hpp and .hxx source files
-        SFiles   []string       // .s source files
-        SwigFiles []string      // .swig files
-        SwigCXXFiles []string   // .swigcxx files
-        SysoFiles []string      // .syso object files to add to archive
+        CFiles         []string // .c source files
+        CXXFiles       []string // .cc, .cxx and .cpp source files
+        MFiles         []string // .m source files
+        HFiles         []string // .h, .hh, .hpp and .hxx source files
+        SFiles         []string // .s source files
+        SwigFiles      []string // .swig files
+        SwigCXXFiles   []string // .swigcxx files
+        SysoFiles      []string // .syso object files to add to archive
 
         // Cgo directives
         CgoCFLAGS    []string // cgo: flags for C compiler
@@ -431,16 +538,23 @@ non-test installation.
 
 In addition to the build flags, the flags handled by 'go test' itself are:
 
-	-c  Compile the test binary to pkg.test but do not run it.
-	    (Where pkg is the last element of the package's import path.)
+	-c
+		Compile the test binary to pkg.test but do not run it
+		(where pkg is the last element of the package's import path).
+		The file name can be changed with the -o flag.
+
+	-exec xprog
+	    Run the test binary using xprog. The behavior is the same as
+	    in 'go run'. See 'go help run' for details.
 
 	-i
 	    Install packages that are dependencies of the test.
 	    Do not run the test.
 
-	-exec xprog
-	    Run the test binary using xprog. The behavior is the same as
-	    in 'go run'. See 'go help run' for details.
+	-o file
+		Compile the test binary to the named file.
+		The test still runs (unless -c or -i is specified).
+
 
 The test binary also accepts flags that control execution of the test; these
 flags are also accessible by 'go test'.  See 'go help testflag' for details.
@@ -488,7 +602,7 @@ Usage:
 
 Vet runs the Go vet command on the packages named by the import paths.
 
-For more about vet, see 'godoc code.google.com/p/go.tools/cmd/vet'.
+For more about vet, see 'godoc golang.org/x/tools/cmd/vet'.
 For more about specifying packages, see 'go help packages'.
 
 To run the vet tool with specific options, run 'go tool vet'.
@@ -681,6 +795,11 @@ A few common code hosting sites have special syntax:
 		import "launchpad.net/~user/project/branch"
 		import "launchpad.net/~user/project/branch/sub/directory"
 
+	IBM DevOps Services (Git)
+
+		import "hub.jazz.net/git/user/project"
+		import "hub.jazz.net/git/user/project/sub/directory"
+
 For code hosted on other servers, import paths may either be qualified
 with the version control type, or the go tool can dynamically fetch
 the import path over https/http and discover where the code resides
@@ -756,7 +875,26 @@ listed in the GOPATH environment variable (see 'go help gopath').
 
 The go command attempts to download the version of the
 package appropriate for the Go release being used.
-Run 'go help install' for more.
+Run 'go help get' for more.
+
+Import path checking
+
+When the custom import path feature described above redirects to a
+known code hosting site, each of the resulting packages has two possible
+import paths, using the custom domain or the known hosting site.
+
+A package statement is said to have an "import comment" if it is immediately
+followed (before the next newline) by a comment of one of these two forms:
+
+	package math // import "path"
+	package math /* import "path" * /
+
+The go command will refuse to install a package with an import comment
+unless it is being referred to by that import path. In this way, import comments
+let package authors make sure the custom import path is used and not a
+direct path to the underlying code hosting site.
+
+See https://golang.org/s/go14customimport for details.
 
 
 Description of package lists
@@ -812,7 +950,8 @@ single directory, the command is applied to a single synthesized
 package made up of exactly those files, ignoring any build constraints
 in those files and ignoring any other files in the directory.
 
-File names that begin with "." or "_" are ignored by the go tool.
+Directory and file names that begin with "." or "_" are ignored
+by the go tool, as are directories named "testdata".
 
 
 Description of testing flags
@@ -844,6 +983,7 @@ control the execution of any test:
 	-blockprofile block.out
 	    Write a goroutine blocking profile to the specified file
 	    when all tests are complete.
+	    Writes test binary as -c would.
 
 	-blockprofilerate n
 	    Control the detail provided in goroutine blocking profiles by
@@ -875,8 +1015,7 @@ control the execution of any test:
 	    Sets -cover.
 
 	-coverprofile cover.out
-	    Write a coverage profile to the specified file after all tests
-	    have passed.
+	    Write a coverage profile to the file after all tests have passed.
 	    Sets -cover.
 
 	-cpu 1,2,4
@@ -886,10 +1025,11 @@ control the execution of any test:
 
 	-cpuprofile cpu.out
 	    Write a CPU profile to the specified file before exiting.
+	    Writes test binary as -c would.
 
 	-memprofile mem.out
-	    Write a memory profile to the specified file after all tests
-	    have passed.
+	    Write a memory profile to the file after all tests have passed.
+	    Writes test binary as -c would.
 
 	-memprofilerate n
 	    Enable more precise (and expensive) memory profiles by setting
diff --git a/src/cmd/go/generate.go b/src/cmd/go/generate.go
new file mode 100644
index 0000000..baf4d2b
--- /dev/null
+++ b/src/cmd/go/generate.go
@@ -0,0 +1,398 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"bufio"
+	"bytes"
+	"fmt"
+	"io"
+	"log"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"runtime"
+	"strconv"
+	"strings"
+	"unicode"
+	"unicode/utf8"
+)
+
+var cmdGenerate = &Command{
+	Run:       runGenerate,
+	UsageLine: "generate [-run regexp] [file.go... | packages]",
+	Short:     "generate Go files by processing source",
+	Long: `
+Generate runs commands described by directives within existing
+files. Those commands can run any process but the intent is to
+create or update Go source files, for instance by running yacc.
+
+Go generate is never run automatically by go build, go get, go test,
+and so on. It must be run explicitly.
+
+Go generate scans the file for directives, which are lines of
+the form,
+
+	//go:generate command argument...
+
+(note: no leading spaces and no space in "//go") where command
+is the generator to be run, corresponding to an executable file
+that can be run locally. It must either be in the shell path
+(gofmt), a fully qualified path (/usr/you/bin/mytool), or a
+command alias, described below.
+
+Note that go generate does not parse the file, so lines that look
+like directives in comments or multiline strings will be treated
+as directives.
+
+The arguments to the directive are space-separated tokens or
+double-quoted strings passed to the generator as individual
+arguments when it is run.
+
+Quoted strings use Go syntax and are evaluated before execution; a
+quoted string appears as a single argument to the generator.
+
+Go generate sets several variables when it runs the generator:
+
+	$GOARCH
+		The execution architecture (arm, amd64, etc.)
+	$GOOS
+		The execution operating system (linux, windows, etc.)
+	$GOFILE
+		The base name of the file.
+	$GOPACKAGE
+		The name of the package of the file containing the directive.
+
+Other than variable substitution and quoted-string evaluation, no
+special processing such as "globbing" is performed on the command
+line.
+
+As a last step before running the command, any invocations of any
+environment variables with alphanumeric names, such as $GOFILE or
+$HOME, are expanded throughout the command line. The syntax for
+variable expansion is $NAME on all operating systems.  Due to the
+order of evaluation, variables are expanded even inside quoted
+strings. If the variable NAME is not set, $NAME expands to the
+empty string.
+
+A directive of the form,
+
+	//go:generate -command xxx args...
+
+specifies, for the remainder of this source file only, that the
+string xxx represents the command identified by the arguments. This
+can be used to create aliases or to handle multiword generators.
+For example,
+
+	//go:generate -command yacc go tool yacc
+
+specifies that the command "yacc" represents the generator
+"go tool yacc".
+
+Generate processes packages in the order given on the command line,
+one at a time. If the command line lists .go files, they are treated
+as a single package. Within a package, generate processes the
+source files in a package in file name order, one at a time. Within
+a source file, generate runs generators in the order they appear
+in the file, one at a time.
+
+If any generator returns an error exit status, "go generate" skips
+all further processing for that package.
+
+The generator is run in the package's source directory.
+
+Go generate accepts one specific flag:
+
+	-run=""
+		if non-empty, specifies a regular expression to
+		select directives whose command matches the expression.
+
+It also accepts the standard build flags -v, -n, and -x.
+The -v flag prints the names of packages and files as they are
+processed.
+The -n flag prints commands that would be executed.
+The -x flag prints commands as they are executed.
+
+For more about specifying packages, see 'go help packages'.
+	`,
+}
+
+var generateRunFlag string // generate -run flag
+
+func init() {
+	addBuildFlags(cmdGenerate)
+	cmdGenerate.Flag.StringVar(&generateRunFlag, "run", "", "")
+}
+
+func runGenerate(cmd *Command, args []string) {
+	// Even if the arguments are .go files, this loop suffices.
+	for _, pkg := range packages(args) {
+		for _, file := range pkg.gofiles {
+			if !generate(pkg.Name, file) {
+				break
+			}
+		}
+	}
+}
+
+// generate runs the generation directives for a single file.
+func generate(pkg, absFile string) bool {
+	fd, err := os.Open(absFile)
+	if err != nil {
+		log.Fatalf("generate: %s", err)
+	}
+	defer fd.Close()
+	g := &Generator{
+		r:        fd,
+		path:     absFile,
+		pkg:      pkg,
+		commands: make(map[string][]string),
+	}
+	return g.run()
+}
+
+// A Generator represents the state of a single Go source file
+// being scanned for generator commands.
+type Generator struct {
+	r        io.Reader
+	path     string // full rooted path name.
+	dir      string // full rooted directory of file.
+	file     string // base name of file.
+	pkg      string
+	commands map[string][]string
+	lineNum  int
+}
+
+// run runs the generators in the current file.
+func (g *Generator) run() (ok bool) {
+	// Processing below here calls g.errorf on failure, which does panic(stop).
+	// If we encounter an error, we abort the package.
+	defer func() {
+		e := recover()
+		if e != nil {
+			ok = false
+			if e != stop {
+				panic(e)
+			}
+			setExitStatus(1)
+		}
+	}()
+	g.dir, g.file = filepath.Split(g.path)
+	g.dir = filepath.Clean(g.dir) // No final separator please.
+	if buildV {
+		fmt.Fprintf(os.Stderr, "%s\n", shortPath(g.path))
+	}
+
+	// Scan for lines that start "//go:generate".
+	// Can't use bufio.Scanner because it can't handle long lines,
+	// which are likely to appear when using generate.
+	input := bufio.NewReader(g.r)
+	var err error
+	// One line per loop.
+	for {
+		g.lineNum++ // 1-indexed.
+		var buf []byte
+		buf, err = input.ReadSlice('\n')
+		if err == bufio.ErrBufferFull {
+			// Line too long - consume and ignore.
+			if isGoGenerate(buf) {
+				g.errorf("directive too long")
+			}
+			for err == bufio.ErrBufferFull {
+				_, err = input.ReadSlice('\n')
+			}
+			if err != nil {
+				break
+			}
+			continue
+		}
+
+		if err != nil {
+			// Check for marker at EOF without final \n.
+			if err == io.EOF && isGoGenerate(buf) {
+				err = io.ErrUnexpectedEOF
+			}
+			break
+		}
+
+		if !isGoGenerate(buf) {
+			continue
+		}
+
+		words := g.split(string(buf))
+		if len(words) == 0 {
+			g.errorf("no arguments to directive")
+		}
+		if words[0] == "-command" {
+			g.setShorthand(words)
+			continue
+		}
+		// Run the command line.
+		if buildN || buildX {
+			fmt.Fprintf(os.Stderr, "%s\n", strings.Join(words, " "))
+		}
+		if buildN {
+			continue
+		}
+		g.exec(words)
+	}
+	if err != nil && err != io.EOF {
+		g.errorf("error reading %s: %s", shortPath(g.path), err)
+	}
+	return true
+}
+
+func isGoGenerate(buf []byte) bool {
+	return bytes.HasPrefix(buf, []byte("//go:generate ")) || bytes.HasPrefix(buf, []byte("//go:generate\t"))
+}
+
+// split breaks the line into words, evaluating quoted
+// strings and evaluating environment variables.
+// The initial //go:generate element is present in line.
+func (g *Generator) split(line string) []string {
+	// Parse line, obeying quoted strings.
+	var words []string
+	line = line[len("//go:generate ") : len(line)-1] // Drop preamble and final newline.
+	// One (possibly quoted) word per iteration.
+Words:
+	for {
+		line = strings.TrimLeft(line, " \t")
+		if len(line) == 0 {
+			break
+		}
+		if line[0] == '"' {
+			for i := 1; i < len(line); i++ {
+				c := line[i] // Only looking for ASCII so this is OK.
+				switch c {
+				case '\\':
+					if i+1 == len(line) {
+						g.errorf("bad backslash")
+					}
+					i++ // Absorb next byte (If it's a multibyte we'll get an error in Unquote).
+				case '"':
+					word, err := strconv.Unquote(line[0 : i+1])
+					if err != nil {
+						g.errorf("bad quoted string")
+					}
+					words = append(words, word)
+					line = line[i+1:]
+					// Check the next character is space or end of line.
+					if len(line) > 0 && line[0] != ' ' && line[0] != '\t' {
+						g.errorf("expect space after quoted argument")
+					}
+					continue Words
+				}
+			}
+			g.errorf("mismatched quoted string")
+		}
+		i := strings.IndexAny(line, " \t")
+		if i < 0 {
+			i = len(line)
+		}
+		words = append(words, line[0:i])
+		line = line[i:]
+	}
+	// Substitute command if required.
+	if len(words) > 0 && g.commands[words[0]] != nil {
+		// Replace 0th word by command substitution.
+		words = append(g.commands[words[0]], words[1:]...)
+	}
+	// Substitute environment variables.
+	for i, word := range words {
+		words[i] = g.expandEnv(word)
+	}
+	return words
+}
+
+var stop = fmt.Errorf("error in generation")
+
+// errorf logs an error message prefixed with the file and line number.
+// It then exits the program (with exit status 1) because generation stops
+// at the first error.
+func (g *Generator) errorf(format string, args ...interface{}) {
+	fmt.Fprintf(os.Stderr, "%s:%d: %s\n", shortPath(g.path), g.lineNum,
+		fmt.Sprintf(format, args...))
+	panic(stop)
+}
+
+// expandEnv expands any $XXX invocations in word.
+func (g *Generator) expandEnv(word string) string {
+	if !strings.ContainsRune(word, '$') {
+		return word
+	}
+	var buf bytes.Buffer
+	var w int
+	var r rune
+	for i := 0; i < len(word); i += w {
+		r, w = utf8.DecodeRuneInString(word[i:])
+		if r != '$' {
+			buf.WriteRune(r)
+			continue
+		}
+		w += g.identLength(word[i+w:])
+		envVar := word[i+1 : i+w]
+		var sub string
+		switch envVar {
+		case "GOARCH":
+			sub = runtime.GOARCH
+		case "GOOS":
+			sub = runtime.GOOS
+		case "GOFILE":
+			sub = g.file
+		case "GOPACKAGE":
+			sub = g.pkg
+		default:
+			sub = os.Getenv(envVar)
+		}
+		buf.WriteString(sub)
+	}
+	return buf.String()
+}
+
+// identLength returns the length of the identifier beginning the string.
+func (g *Generator) identLength(word string) int {
+	for i, r := range word {
+		if r == '_' || unicode.IsLetter(r) || unicode.IsDigit(r) {
+			continue
+		}
+		return i
+	}
+	return len(word)
+}
+
+// setShorthand installs a new shorthand as defined by a -command directive.
+func (g *Generator) setShorthand(words []string) {
+	// Create command shorthand.
+	if len(words) == 1 {
+		g.errorf("no command specified for -command")
+	}
+	command := words[1]
+	if g.commands[command] != nil {
+		g.errorf("command %q defined multiply defined", command)
+	}
+	g.commands[command] = words[2:len(words):len(words)] // force later append to make copy
+}
+
+// exec runs the command specified by the argument. The first word is
+// the command name itself.
+func (g *Generator) exec(words []string) {
+	cmd := exec.Command(words[0], words[1:]...)
+	// Standard in and out of generator should be the usual.
+	cmd.Stdout = os.Stdout
+	cmd.Stderr = os.Stderr
+	// Run the command in the package directory.
+	cmd.Dir = g.dir
+	env := []string{
+		"GOARCH=" + runtime.GOARCH,
+		"GOOS=" + runtime.GOOS,
+		"GOFILE=" + g.file,
+		"GOPACKAGE=" + g.pkg,
+	}
+	cmd.Env = mergeEnvLists(env, os.Environ())
+	err := cmd.Run()
+	if err != nil {
+		g.errorf("running %q: %s", words[0], err)
+	}
+}
diff --git a/src/cmd/go/generate_test.go b/src/cmd/go/generate_test.go
new file mode 100644
index 0000000..660ebab
--- /dev/null
+++ b/src/cmd/go/generate_test.go
@@ -0,0 +1,48 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"reflect"
+	"runtime"
+	"testing"
+)
+
+type splitTest struct {
+	in  string
+	out []string
+}
+
+var splitTests = []splitTest{
+	{"", nil},
+	{"x", []string{"x"}},
+	{" a b\tc ", []string{"a", "b", "c"}},
+	{` " a " `, []string{" a "}},
+	{"$GOARCH", []string{runtime.GOARCH}},
+	{"$GOOS", []string{runtime.GOOS}},
+	{"$GOFILE", []string{"proc.go"}},
+	{"$GOPACKAGE", []string{"sys"}},
+	{"a $XXNOTDEFINEDXX b", []string{"a", "", "b"}},
+	{"/$XXNOTDEFINED/", []string{"//"}},
+	{"yacc -o $GOARCH/yacc_$GOFILE", []string{"go", "tool", "yacc", "-o", runtime.GOARCH + "/yacc_proc.go"}},
+}
+
+func TestGenerateCommandParse(t *testing.T) {
+	g := &Generator{
+		r:        nil, // Unused here.
+		path:     "/usr/ken/sys/proc.go",
+		dir:      "/usr/ken/sys",
+		file:     "proc.go",
+		pkg:      "sys",
+		commands: make(map[string][]string),
+	}
+	g.setShorthand([]string{"-command", "yacc", "go", "tool", "yacc"})
+	for _, test := range splitTests {
+		got := g.split("//go:generate " + test.in + "\n")
+		if !reflect.DeepEqual(got, test.out) {
+			t.Errorf("split(%q): got %q expected %q", test.in, got, test.out)
+		}
+	}
+}
diff --git a/src/cmd/go/get.go b/src/cmd/go/get.go
index e708fcf..86e1697 100644
--- a/src/cmd/go/get.go
+++ b/src/cmd/go/get.go
@@ -16,7 +16,7 @@ import (
 )
 
 var cmdGet = &Command{
-	UsageLine: "get [-d] [-fix] [-t] [-u] [build flags] [packages]",
+	UsageLine: "get [-d] [-f] [-fix] [-t] [-u] [build flags] [packages]",
 	Short:     "download and install packages and dependencies",
 	Long: `
 Get downloads and installs the packages named by the import paths,
@@ -25,6 +25,11 @@ along with their dependencies.
 The -d flag instructs get to stop after downloading the packages; that is,
 it instructs get not to install the packages.
 
+The -f flag, valid only when -u is set, forces get -u not to verify that
+each package has been checked out from the source control repository
+implied by its import path. This can be useful if the source is a local fork
+of the original.
+
 The -fix flag instructs get to run the fix tool on the downloaded packages
 before resolving dependencies or building the code.
 
@@ -53,6 +58,7 @@ See also: go build, go install, go clean.
 }
 
 var getD = cmdGet.Flag.Bool("d", false, "")
+var getF = cmdGet.Flag.Bool("f", false, "")
 var getT = cmdGet.Flag.Bool("t", false, "")
 var getU = cmdGet.Flag.Bool("u", false, "")
 var getFix = cmdGet.Flag.Bool("fix", false, "")
@@ -63,6 +69,10 @@ func init() {
 }
 
 func runGet(cmd *Command, args []string) {
+	if *getF && !*getU {
+		fatalf("go get: cannot use -f flag without -u")
+	}
+
 	// Phase 1.  Download/update.
 	var stk importStack
 	for _, arg := range downloadPaths(args) {
@@ -151,7 +161,9 @@ func download(arg string, stk *importStack, getTestDeps bool) {
 	}
 
 	// Only process each package once.
-	if downloadCache[arg] {
+	// (Unless we're fetching test dependencies for this package,
+	// in which case we want to process it again.)
+	if downloadCache[arg] && !getTestDeps {
 		return
 	}
 	downloadCache[arg] = true
@@ -264,6 +276,25 @@ func downloadPackage(p *Package) error {
 			return err
 		}
 		repo = "<local>" // should be unused; make distinctive
+
+		// Double-check where it came from.
+		if *getU && vcs.remoteRepo != nil && !*getF {
+			dir := filepath.Join(p.build.SrcRoot, rootPath)
+			if remote, err := vcs.remoteRepo(vcs, dir); err == nil {
+				if rr, err := repoRootForImportPath(p.ImportPath); err == nil {
+					repo := rr.repo
+					if rr.vcs.resolveRepo != nil {
+						resolved, err := rr.vcs.resolveRepo(rr.vcs, dir, repo)
+						if err == nil {
+							repo = resolved
+						}
+					}
+					if remote != repo {
+						return fmt.Errorf("%s is from %s, should be from %s", dir, remote, repo)
+					}
+				}
+			}
+		}
 	} else {
 		// Analyze the import path to determine the version control system,
 		// repository, and the import path for the root of the repository.
diff --git a/src/cmd/go/go_windows_test.go b/src/cmd/go/go_windows_test.go
new file mode 100644
index 0000000..53d695c
--- /dev/null
+++ b/src/cmd/go/go_windows_test.go
@@ -0,0 +1,55 @@
+// 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 (
+	"io/ioutil"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"strings"
+	"testing"
+)
+
+func TestAbsolutePath(t *testing.T) {
+	tmp, err := ioutil.TempDir("", "TestAbsolutePath")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.RemoveAll(tmp)
+
+	file := filepath.Join(tmp, "a.go")
+	err = ioutil.WriteFile(file, []byte{}, 0644)
+	if err != nil {
+		t.Fatal(err)
+	}
+	dir := filepath.Join(tmp, "dir")
+	err = os.Mkdir(dir, 0777)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	wd, err := os.Getwd()
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.Chdir(wd)
+
+	// Chdir so current directory and a.go reside on the same drive.
+	err = os.Chdir(dir)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	noVolume := file[len(filepath.VolumeName(file)):]
+	wrongPath := filepath.Join(dir, noVolume)
+	output, err := exec.Command("go", "build", noVolume).CombinedOutput()
+	if err == nil {
+		t.Fatal("build should fail")
+	}
+	if strings.Contains(string(output), wrongPath) {
+		t.Fatalf("wrong output found: %v %v", err, string(output))
+	}
+}
diff --git a/src/cmd/go/help.go b/src/cmd/go/help.go
index 40da7e1..c590fdb 100644
--- a/src/cmd/go/help.go
+++ b/src/cmd/go/help.go
@@ -81,7 +81,8 @@ single directory, the command is applied to a single synthesized
 package made up of exactly those files, ignoring any build constraints
 in those files and ignoring any other files in the directory.
 
-File names that begin with "." or "_" are ignored by the go tool.
+Directory and file names that begin with "." or "_" are ignored
+by the go tool, as are directories named "testdata".
 	`,
 }
 
@@ -154,6 +155,11 @@ A few common code hosting sites have special syntax:
 		import "launchpad.net/~user/project/branch"
 		import "launchpad.net/~user/project/branch/sub/directory"
 
+	IBM DevOps Services (Git)
+
+		import "hub.jazz.net/git/user/project"
+		import "hub.jazz.net/git/user/project/sub/directory"
+
 For code hosted on other servers, import paths may either be qualified
 with the version control type, or the go tool can dynamically fetch
 the import path over https/http and discover where the code resides
@@ -229,7 +235,26 @@ listed in the GOPATH environment variable (see 'go help gopath').
 
 The go command attempts to download the version of the
 package appropriate for the Go release being used.
-Run 'go help install' for more.
+Run 'go help get' for more.
+
+Import path checking
+
+When the custom import path feature described above redirects to a
+known code hosting site, each of the resulting packages has two possible
+import paths, using the custom domain or the known hosting site.
+
+A package statement is said to have an "import comment" if it is immediately
+followed (before the next newline) by a comment of one of these two forms:
+
+	package math // import "path"
+	package math /* import "path" */
+
+The go command will refuse to install a package with an import comment
+unless it is being referred to by that import path. In this way, import comments
+let package authors make sure the custom import path is used and not a
+direct path to the underlying code hosting site.
+
+See https://golang.org/s/go14customimport for details.
 	`,
 }
 
diff --git a/src/cmd/go/list.go b/src/cmd/go/list.go
index 0ead435..fbf9616 100644
--- a/src/cmd/go/list.go
+++ b/src/cmd/go/list.go
@@ -30,28 +30,29 @@ syntax of package template.  The default output is equivalent to -f
 '{{.ImportPath}}'. The struct being passed to the template is:
 
     type Package struct {
-        Dir        string // directory containing package sources
-        ImportPath string // import path of package in dir
-        Name       string // package name
-        Doc        string // package documentation string
-        Target     string // install path
-        Goroot     bool   // is this package in the Go root?
-        Standard   bool   // is this package part of the standard Go library?
-        Stale      bool   // would 'go install' do anything for this package?
-        Root       string // Go root or Go path dir containing this package
+        Dir           string // directory containing package sources
+        ImportPath    string // import path of package in dir
+        ImportComment string // path in import comment on package statement
+        Name          string // package name
+        Doc           string // package documentation string
+        Target        string // install path
+        Goroot        bool   // is this package in the Go root?
+        Standard      bool   // is this package part of the standard Go library?
+        Stale         bool   // would 'go install' do anything for this package?
+        Root          string // Go root or Go path dir containing this package
 
         // Source files
-        GoFiles  []string       // .go source files (excluding CgoFiles, TestGoFiles, XTestGoFiles)
-        CgoFiles []string       // .go sources files that import "C"
+        GoFiles        []string // .go source files (excluding CgoFiles, TestGoFiles, XTestGoFiles)
+        CgoFiles       []string // .go sources files that import "C"
         IgnoredGoFiles []string // .go sources ignored due to build constraints
-        CFiles   []string       // .c source files
-        CXXFiles []string       // .cc, .cxx and .cpp source files
-        MFiles   []string       // .m source files
-        HFiles   []string       // .h, .hh, .hpp and .hxx source files
-        SFiles   []string       // .s source files
-        SwigFiles []string      // .swig files
-        SwigCXXFiles []string   // .swigcxx files
-        SysoFiles []string      // .syso object files to add to archive
+        CFiles         []string // .c source files
+        CXXFiles       []string // .cc, .cxx and .cpp source files
+        MFiles         []string // .m source files
+        HFiles         []string // .h, .hh, .hpp and .hxx source files
+        SFiles         []string // .s source files
+        SwigFiles      []string // .swig files
+        SwigCXXFiles   []string // .swigcxx files
+        SysoFiles      []string // .syso object files to add to archive
 
         // Cgo directives
         CgoCFLAGS    []string // cgo: flags for C compiler
diff --git a/src/cmd/go/main.go b/src/cmd/go/main.go
index 5b1194a..9691f39 100644
--- a/src/cmd/go/main.go
+++ b/src/cmd/go/main.go
@@ -79,6 +79,7 @@ var commands = []*Command{
 	cmdEnv,
 	cmdFix,
 	cmdFmt,
+	cmdGenerate,
 	cmdGet,
 	cmdInstall,
 	cmdList,
@@ -536,7 +537,7 @@ func matchPackages(pattern string) []string {
 	})
 
 	for _, src := range buildContext.SrcDirs() {
-		if pattern == "std" && src != gorootSrcPkg {
+		if pattern == "std" && src != gorootSrc {
 			continue
 		}
 		src = filepath.Clean(src) + string(filepath.Separator)
@@ -618,7 +619,7 @@ func matchPackagesInFS(pattern string) []string {
 			// The initial case is not Cleaned, though, so we do this explicitly.
 			//
 			// This converts a path like "./io/" to "io". Without this step, running
-			// "cd $GOROOT/src/pkg; go list ./io/..." would incorrectly skip the io
+			// "cd $GOROOT/src; go list ./io/..." would incorrectly skip the io
 			// package, because prepending the prefix "./" to the unclean path would
 			// result in "././io", and match("././io") returns false.
 			path = filepath.Clean(path)
diff --git a/src/cmd/go/mkdoc.sh b/src/cmd/go/mkdoc.sh
index 12fd7ba..e15e880 100755
--- a/src/cmd/go/mkdoc.sh
+++ b/src/cmd/go/mkdoc.sh
@@ -4,6 +4,6 @@
 # license that can be found in the LICENSE file.
 
 go install # So the next line will produce updated documentation.
-go help documentation > doc.go
+go help documentation | sed 's; \*/; * /;' >doc.go
 gofmt -w doc.go
 
diff --git a/src/cmd/go/pkg.go b/src/cmd/go/pkg.go
index d45df26..b71feb7 100644
--- a/src/cmd/go/pkg.go
+++ b/src/cmd/go/pkg.go
@@ -14,6 +14,7 @@ import (
 	"os"
 	pathpkg "path"
 	"path/filepath"
+	"runtime"
 	"sort"
 	"strings"
 	"time"
@@ -25,16 +26,17 @@ type Package struct {
 	// Note: These fields are part of the go command's public API.
 	// See list.go.  It is okay to add fields, but not to change or
 	// remove existing ones.  Keep in sync with list.go
-	Dir         string `json:",omitempty"` // directory containing package sources
-	ImportPath  string `json:",omitempty"` // import path of package in dir
-	Name        string `json:",omitempty"` // package name
-	Doc         string `json:",omitempty"` // package documentation string
-	Target      string `json:",omitempty"` // install path
-	Goroot      bool   `json:",omitempty"` // is this package found in the Go root?
-	Standard    bool   `json:",omitempty"` // is this package part of the standard Go library?
-	Stale       bool   `json:",omitempty"` // would 'go install' do anything for this package?
-	Root        string `json:",omitempty"` // Go root or Go path dir containing this package
-	ConflictDir string `json:",omitempty"` // Dir is hidden by this other directory
+	Dir           string `json:",omitempty"` // directory containing package sources
+	ImportPath    string `json:",omitempty"` // import path of package in dir
+	ImportComment string `json:",omitempty"` // path in import comment on package statement
+	Name          string `json:",omitempty"` // package name
+	Doc           string `json:",omitempty"` // package documentation string
+	Target        string `json:",omitempty"` // install path
+	Goroot        bool   `json:",omitempty"` // is this package found in the Go root?
+	Standard      bool   `json:",omitempty"` // is this package part of the standard Go library?
+	Stale         bool   `json:",omitempty"` // would 'go install' do anything for this package?
+	Root          string `json:",omitempty"` // Go root or Go path dir containing this package
+	ConflictDir   string `json:",omitempty"` // Dir is hidden by this other directory
 
 	// Source files
 	GoFiles        []string `json:",omitempty"` // .go source files (excluding CgoFiles, TestGoFiles, XTestGoFiles)
@@ -103,6 +105,7 @@ func (p *Package) copyBuild(pp *build.Package) {
 
 	p.Dir = pp.Dir
 	p.ImportPath = pp.ImportPath
+	p.ImportComment = pp.ImportComment
 	p.Name = pp.Name
 	p.Doc = pp.Doc
 	p.Root = pp.Root
@@ -218,7 +221,7 @@ func dirToImportPath(dir string) string {
 }
 
 func makeImportValid(r rune) rune {
-	// Should match Go spec, compilers, and ../../pkg/go/parser/parser.go:/isValidImport.
+	// Should match Go spec, compilers, and ../../go/parser/parser.go:/isValidImport.
 	const illegalChars = `!"#$%&'()*,:;<=>?[\]^{|}` + "`\uFFFD"
 	if !unicode.IsGraphic(r) || unicode.IsSpace(r) || strings.ContainsRune(illegalChars, r) {
 		return '_'
@@ -244,6 +247,9 @@ func loadImport(path string, srcDir string, stk *importStack, importPos []token.
 		importPath = dirToImportPath(filepath.Join(srcDir, path))
 	}
 	if p := packageCache[importPath]; p != nil {
+		if perr := disallowInternal(srcDir, p, stk); perr != p {
+			return perr
+		}
 		return reusePackage(p, stk)
 	}
 
@@ -258,11 +264,14 @@ func loadImport(path string, srcDir string, stk *importStack, importPos []token.
 	//
 	// TODO: After Go 1, decide when to pass build.AllowBinary here.
 	// See issue 3268 for mistakes to avoid.
-	bp, err := buildContext.Import(path, srcDir, 0)
+	bp, err := buildContext.Import(path, srcDir, build.ImportComment)
 	bp.ImportPath = importPath
 	if gobin != "" {
 		bp.BinDir = gobin
 	}
+	if err == nil && !isLocal && bp.ImportComment != "" && bp.ImportComment != path {
+		err = fmt.Errorf("code in directory %s expects import %q", bp.Dir, bp.ImportComment)
+	}
 	p.load(stk, bp, err)
 	if p.Error != nil && len(importPos) > 0 {
 		pos := importPos[0]
@@ -270,6 +279,10 @@ func loadImport(path string, srcDir string, stk *importStack, importPos []token.
 		p.Error.Pos = pos.String()
 	}
 
+	if perr := disallowInternal(srcDir, p, stk); perr != p {
+		return perr
+	}
+
 	return p
 }
 
@@ -298,12 +311,82 @@ func reusePackage(p *Package, stk *importStack) *Package {
 	return p
 }
 
+// disallowInternal checks that srcDir is allowed to import p.
+// If the import is allowed, disallowInternal returns the original package p.
+// If not, it returns a new package containing just an appropriate error.
+func disallowInternal(srcDir string, p *Package, stk *importStack) *Package {
+	// golang.org/s/go14internal:
+	// An import of a path containing the element “internal”
+	// is disallowed if the importing code is outside the tree
+	// rooted at the parent of the “internal” directory.
+	//
+	// ... For Go 1.4, we will implement the rule first for $GOROOT, but not $GOPATH.
+
+	// Only applies to $GOROOT.
+	if !p.Standard {
+		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
+	// import. Anything listed on the command line is fine.
+	if len(*stk) == 1 {
+		return p
+	}
+
+	// Check for "internal" element: four cases depending on begin of string and/or end of string.
+	i, ok := findInternal(p.ImportPath)
+	if !ok {
+		return p
+	}
+
+	// Internal is present.
+	// Map import path back to directory corresponding to parent of internal.
+	if i > 0 {
+		i-- // rewind over slash in ".../internal"
+	}
+	parent := p.Dir[:i+len(p.Dir)-len(p.ImportPath)]
+	if hasPathPrefix(filepath.ToSlash(srcDir), filepath.ToSlash(parent)) {
+		return p
+	}
+
+	// Internal is present, and srcDir is outside parent's tree. Not allowed.
+	perr := *p
+	perr.Error = &PackageError{
+		ImportStack: stk.copy(),
+		Err:         "use of internal package not allowed",
+	}
+	perr.Incomplete = true
+	return &perr
+}
+
+// findInternal looks for the final "internal" path element in the given import path.
+// If there isn't one, findInternal returns ok=false.
+// Otherwise, findInternal returns ok=true and the index of the "internal".
+func findInternal(path string) (index int, ok bool) {
+	// Four cases, depending on internal at start/end of string or not.
+	// The order matters: we must return the index of the final element,
+	// because the final one produces the most restrictive requirement
+	// on the importer.
+	switch {
+	case strings.HasSuffix(path, "/internal"):
+		return len(path) - len("internal"), true
+	case strings.Contains(path, "/internal/"):
+		return strings.LastIndex(path, "/internal/") + 1, true
+	case path == "internal", strings.HasPrefix(path, "internal/"):
+		return 0, true
+	}
+	return 0, false
+}
+
 type targetDir int
 
 const (
-	toRoot targetDir = iota // to bin dir inside package root (default)
-	toTool                  // GOROOT/pkg/tool
-	toBin                   // GOROOT/bin
+	toRoot    targetDir = iota // to bin dir inside package root (default)
+	toTool                     // GOROOT/pkg/tool
+	toBin                      // GOROOT/bin
+	stalePath                  // the old import path; fail to build
 )
 
 // goTools is a map of Go program import path to install target directory.
@@ -316,10 +399,14 @@ var goTools = map[string]targetDir{
 	"cmd/nm":                               toTool,
 	"cmd/objdump":                          toTool,
 	"cmd/pack":                             toTool,
+	"cmd/pprof":                            toTool,
 	"cmd/yacc":                             toTool,
-	"code.google.com/p/go.tools/cmd/cover": toTool,
-	"code.google.com/p/go.tools/cmd/godoc": toBin,
-	"code.google.com/p/go.tools/cmd/vet":   toTool,
+	"golang.org/x/tools/cmd/cover":         toTool,
+	"golang.org/x/tools/cmd/godoc":         toBin,
+	"golang.org/x/tools/cmd/vet":           toTool,
+	"code.google.com/p/go.tools/cmd/cover": stalePath,
+	"code.google.com/p/go.tools/cmd/godoc": stalePath,
+	"code.google.com/p/go.tools/cmd/vet":   stalePath,
 }
 
 // expandScanner expands a scanner.List error into all the errors in the list.
@@ -380,6 +467,13 @@ func (p *Package) load(stk *importStack, bp *build.Package, err error) *Package
 	}
 
 	if p.Name == "main" {
+		// Report an error when the old code.google.com/p/go.tools paths are used.
+		if goTools[p.ImportPath] == stalePath {
+			newPath := strings.Replace(p.ImportPath, "code.google.com/p/go.", "golang.org/x/", 1)
+			e := fmt.Sprintf("the %v command has moved; use %v instead.", p.ImportPath, newPath)
+			p.Error = &PackageError{Err: e}
+			return p
+		}
 		_, elem := filepath.Split(p.Dir)
 		full := buildContext.GOOS + "_" + buildContext.GOARCH + "/" + elem
 		if buildContext.GOOS != toolGOOS || buildContext.GOARCH != toolGOARCH {
@@ -482,7 +576,7 @@ func (p *Package) load(stk *importStack, bp *build.Package, err error) *Package
 
 	// Build list of imported packages and full dependency list.
 	imports := make([]*Package, 0, len(p.Imports))
-	deps := make(map[string]bool)
+	deps := make(map[string]*Package)
 	for i, path := range importPaths {
 		if path == "C" {
 			continue
@@ -502,10 +596,10 @@ func (p *Package) load(stk *importStack, bp *build.Package, err error) *Package
 			path = p1.ImportPath
 			importPaths[i] = path
 		}
-		deps[path] = true
+		deps[path] = p1
 		imports = append(imports, p1)
-		for _, dep := range p1.Deps {
-			deps[dep] = true
+		for _, dep := range p1.deps {
+			deps[dep.ImportPath] = dep
 		}
 		if p1.Incomplete {
 			p.Incomplete = true
@@ -519,7 +613,7 @@ func (p *Package) load(stk *importStack, bp *build.Package, err error) *Package
 	}
 	sort.Strings(p.Deps)
 	for _, dep := range p.Deps {
-		p1 := packageCache[dep]
+		p1 := deps[dep]
 		if p1 == nil {
 			panic("impossible: missing entry in package cache for " + dep + " imported by " + p.ImportPath)
 		}
@@ -535,6 +629,16 @@ func (p *Package) load(stk *importStack, bp *build.Package, err error) *Package
 	}
 	p.Target = p.target
 
+	// Check for C code compiled with Plan 9 C compiler.
+	// No longer allowed except in runtime and runtime/cgo, for now.
+	if len(p.CFiles) > 0 && !p.usesCgo() && (!p.Standard || p.ImportPath != "runtime") {
+		p.Error = &PackageError{
+			ImportStack: stk.copy(),
+			Err:         fmt.Sprintf("C source files not allowed when not using cgo: %s", strings.Join(p.CFiles, " ")),
+		}
+		return p
+	}
+
 	// In the absence of errors lower in the dependency tree,
 	// check for case-insensitive collisions of import paths.
 	if len(p.DepsErrors) == 0 {
@@ -596,6 +700,12 @@ func computeStale(pkgs ...*Package) {
 	}
 }
 
+// The runtime version string takes one of two forms:
+// "go1.X[.Y]" for Go releases, and "devel +hash" at tip.
+// Determine whether we are in a released copy by
+// inspecting the version.
+var isGoRelease = strings.HasPrefix(runtime.Version(), "go1")
+
 // isStale reports whether package p needs to be rebuilt.
 func isStale(p *Package, topRoot map[string]bool) bool {
 	if p.Standard && (p.ImportPath == "unsafe" || buildContext.Compiler == "gccgo") {
@@ -616,7 +726,16 @@ func isStale(p *Package, topRoot map[string]bool) bool {
 		return false
 	}
 
-	if buildA || p.target == "" || p.Stale {
+	// If we are running a release copy of Go, do not rebuild the standard packages.
+	// They may not be writable anyway, but they are certainly not changing.
+	// This makes 'go build -a' skip the standard packages when using an official release.
+	// See issue 4106 and issue 8290.
+	pkgBuildA := buildA
+	if p.Standard && isGoRelease {
+		pkgBuildA = false
+	}
+
+	if pkgBuildA || p.target == "" || p.Stale {
 		return true
 	}
 
@@ -704,24 +823,13 @@ func loadPackage(arg string, stk *importStack) *Package {
 			arg = sub
 		}
 	}
-	if strings.HasPrefix(arg, "cmd/") {
+	if strings.HasPrefix(arg, "cmd/") && !strings.Contains(arg[4:], "/") {
 		if p := cmdCache[arg]; p != nil {
 			return p
 		}
 		stk.push(arg)
 		defer stk.pop()
 
-		if strings.Contains(arg[4:], "/") {
-			p := &Package{
-				Error: &PackageError{
-					ImportStack: stk.copy(),
-					Err:         fmt.Sprintf("invalid import path: cmd/... is reserved for Go commands"),
-					hard:        true,
-				},
-			}
-			return p
-		}
-
 		bp, err := buildContext.ImportDir(filepath.Join(gorootSrc, arg), 0)
 		bp.ImportPath = arg
 		bp.Goroot = true
diff --git a/src/cmd/go/test.bash b/src/cmd/go/test.bash
index 0060ce2..e0f066f 100755
--- a/src/cmd/go/test.bash
+++ b/src/cmd/go/test.bash
@@ -4,18 +4,22 @@
 # license that can be found in the LICENSE file.
 
 set -e
-go build -o testgo
+go build -tags testgo -o testgo
 go() {
 	echo TEST ERROR: ran go, not testgo: go "$@" >&2
 	exit 2
 }
 
 started=false
+testdesc=""
+nl="
+"
 TEST() {
 	if $started; then
 		stop
 	fi
 	echo TEST: "$@"
+	testdesc="$@"
 	started=true
 	ok=true
 }
@@ -29,6 +33,7 @@ stop() {
 		echo PASS
 	else
 		echo FAIL
+		testfail="$testfail	$testdesc$nl"
 		allok=false
 	fi
 }
@@ -55,12 +60,63 @@ if ! grep -q "^$fn:" $d/err.out; then
 fi
 rm -r $d
 
+TEST 'program name in crash messages'
+linker=$(./testgo env GOCHAR)l
+d=$(TMPDIR=/var/tmp mktemp -d -t testgoXXX)
+./testgo build -ldflags -crash_for_testing $(./testgo env GOROOT)/test/helloworld.go 2>$d/err.out || true
+if ! grep -q "/tool/.*/$linker" $d/err.out; then
+	echo "missing linker name in error message"
+	cat $d/err.out
+	ok=false
+fi
+rm -r $d
+
+TEST broken tests without Test functions all fail
+d=$(mktemp -d -t testgoXXX)
+./testgo test ./testdata/src/badtest/... >$d/err 2>&1 || true
+if grep -q '^ok' $d/err; then
+	echo test passed unexpectedly:
+	grep '^ok' $d/err
+	ok=false
+elif ! grep -q 'FAIL.*badtest/badexec' $d/err || ! grep -q 'FAIL.*badtest/badsyntax' $d/err || ! grep -q 'FAIL.*badtest/badvar' $d/err; then
+	echo test did not run everything
+	cat $d/err
+	ok=false
+fi
+rm -rf $d
+
+TEST 'go build -a in dev branch'
+./testgo install math || ok=false # should be up to date already but just in case
+d=$(TMPDIR=/var/tmp mktemp -d -t testgoXXX)
+if ! TESTGO_IS_GO_RELEASE=0 ./testgo build -v -a math 2>$d/err.out; then
+	cat $d/err.out
+	ok=false
+elif ! grep -q runtime $d/err.out; then
+	echo "testgo build -a math in dev branch DID NOT build runtime, but should have"
+	cat $d/err.out
+	ok=false
+fi
+rm -r $d
+
+TEST 'go build -a in release branch'
+./testgo install math || ok=false # should be up to date already but just in case
+d=$(TMPDIR=/var/tmp mktemp -d -t testgoXXX)
+if ! TESTGO_IS_GO_RELEASE=1 ./testgo build -v -a math 2>$d/err.out; then
+	cat $d/err.out
+	ok=false
+elif grep -q runtime $d/err.out; then
+	echo "testgo build -a math in dev branch DID build runtime, but should NOT have"
+	cat $d/err.out
+	ok=false
+fi
+rm -r $d
+
 # Test local (./) imports.
 testlocal() {
 	local="$1"
 	TEST local imports $2 '(easy)'
-	./testgo build -o hello "testdata/$local/easy.go"
-	./hello >hello.out
+	./testgo build -o hello "testdata/$local/easy.go" || ok=false
+	./hello >hello.out || ok=false
 	if ! grep -q '^easysub\.Hello' hello.out; then
 		echo "testdata/$local/easy.go did not generate expected output"
 		cat hello.out
@@ -68,8 +124,8 @@ testlocal() {
 	fi
 	
 	TEST local imports $2 '(easysub)'
-	./testgo build -o hello "testdata/$local/easysub/main.go"
-	./hello >hello.out
+	./testgo build -o hello "testdata/$local/easysub/main.go" || ok=false
+	./hello >hello.out || ok=false
 	if ! grep -q '^easysub\.Hello' hello.out; then
 		echo "testdata/$local/easysub/main.go did not generate expected output"
 		cat hello.out
@@ -77,8 +133,8 @@ testlocal() {
 	fi
 	
 	TEST local imports $2 '(hard)'
-	./testgo build -o hello "testdata/$local/hard.go"
-	./hello >hello.out
+	./testgo build -o hello "testdata/$local/hard.go" || ok=false
+	./hello >hello.out || ok=false
 	if ! grep -q '^sub\.Hello' hello.out || ! grep -q '^subsub\.Hello' hello.out ; then
 		echo "testdata/$local/hard.go did not generate expected output"
 		cat hello.out
@@ -105,6 +161,132 @@ cp -R testdata/local "testdata/$bad"
 testlocal "$bad" 'with bad characters in path'
 rm -rf "testdata/$bad"
 
+TEST 'internal packages in $GOROOT are respected'
+if ./testgo build -v ./testdata/testinternal >testdata/std.out 2>&1; then
+	echo "go build ./testdata/testinternal succeeded incorrectly"
+	ok=false
+elif ! grep 'use of internal package not allowed' testdata/std.out >/dev/null; then
+	echo "wrong error message for testdata/testinternal"
+	cat std.out
+	ok=false
+fi
+
+TEST 'internal packages outside $GOROOT are not respected'
+if ! ./testgo build -v ./testdata/testinternal2; then
+	echo "go build ./testdata/testinternal2 failed"
+	ok=false
+fi
+
+# Test that 'go get -u' reports moved packages.
+testmove() {
+	vcs=$1
+	url=$2
+	base=$3
+	config=$4
+
+	TEST go get -u notices $vcs package that moved
+	d=$(mktemp -d -t testgoXXX)
+	mkdir -p $d/src
+	if ! GOPATH=$d ./testgo get -d $url; then
+		echo 'go get -d $url failed'
+		ok=false
+	elif ! GOPATH=$d ./testgo get -d -u $url; then
+		echo 'go get -d -u $url failed'
+		ok=false
+	else
+		set +e
+		case "$vcs" in
+		svn)
+			# SVN doesn't believe in text files so we can't just edit the config.
+			# Check out a different repo into the wrong place.
+			rm -rf $d/src/code.google.com/p/rsc-svn
+			GOPATH=$d ./testgo get -d -u code.google.com/p/rsc-svn2/trunk
+			mv $d/src/code.google.com/p/rsc-svn2 $d/src/code.google.com/p/rsc-svn
+			;;
+		*)
+			echo '1,$s;'"$base"';'"$base"'XXX;
+w
+q' | ed $d/src/$config >/dev/null 2>&1
+		esac
+		set -e
+
+		if GOPATH=$d ./testgo get -d -u $url 2>$d/err; then
+			echo "go get -d -u $url succeeded with wrong remote repo"
+			cat $d/err
+			ok=false
+		elif ! grep 'should be from' $d/err >/dev/null; then
+			echo "go get -d -u $url failed for wrong reason"
+			cat $d/err
+			ok=false
+		fi
+		
+		if GOPATH=$d ./testgo get -d -f -u $url 2>$d/err; then
+			echo "go get -d -u $url succeeded with wrong remote repo"
+			cat $d/err
+			ok=false
+		elif ! egrep -i 'validating server certificate|not found' $d/err >/dev/null; then
+			echo "go get -d -f -u $url failed for wrong reason"
+			cat $d/err
+			ok=false
+		fi
+	fi
+	rm -rf $d
+}
+
+testmove hg rsc.io/x86/x86asm x86 rsc.io/x86/.hg/hgrc
+testmove git rsc.io/pdf pdf rsc.io/pdf/.git/config
+testmove svn code.google.com/p/rsc-svn/trunk - -
+
+export GOPATH=$(pwd)/testdata/importcom
+TEST 'import comment - match'
+if ! ./testgo build ./testdata/importcom/works.go; then
+	echo 'go build ./testdata/importcom/works.go failed'
+	ok=false
+fi
+TEST 'import comment - mismatch'
+if ./testgo build ./testdata/importcom/wrongplace.go 2>testdata/err; then
+	echo 'go build ./testdata/importcom/wrongplace.go suceeded'
+	ok=false
+elif ! grep 'wrongplace expects import "my/x"' testdata/err >/dev/null; then
+	echo 'go build did not mention incorrect import:'
+	cat testdata/err
+	ok=false
+fi
+TEST 'import comment - syntax error'
+if ./testgo build ./testdata/importcom/bad.go 2>testdata/err; then
+	echo 'go build ./testdata/importcom/bad.go suceeded'
+	ok=false
+elif ! grep 'cannot parse import comment' testdata/err >/dev/null; then
+	echo 'go build did not mention syntax error:'
+	cat testdata/err
+	ok=false
+fi
+TEST 'import comment - conflict'
+if ./testgo build ./testdata/importcom/conflict.go 2>testdata/err; then
+	echo 'go build ./testdata/importcom/conflict.go suceeded'
+	ok=false
+elif ! grep 'found import comments' testdata/err >/dev/null; then
+	echo 'go build did not mention comment conflict:'
+	cat testdata/err
+	ok=false
+fi
+rm -f ./testdata/err
+unset GOPATH
+
+export GOPATH=$(pwd)/testdata/src
+TEST disallowed C source files
+export GOPATH=$(pwd)/testdata
+if ./testgo build badc 2>testdata/err; then
+	echo 'go build badc succeeded'
+	ok=false
+elif ! grep 'C source files not allowed' testdata/err >/dev/null; then
+	echo 'go test did not say C source files not allowed:'
+	cat testdata/err
+	ok=false
+fi
+rm -f ./testdata/err
+unset GOPATH
+
 TEST error message for syntax error in test go file says FAIL
 export GOPATH=$(pwd)/testdata
 if ./testgo test syntaxerror 2>testdata/err; then
@@ -251,20 +433,20 @@ TEST godoc installs into GOBIN
 d=$(mktemp -d -t testgoXXX)
 export GOPATH=$d
 mkdir $d/gobin
-GOBIN=$d/gobin ./testgo get code.google.com/p/go.tools/cmd/godoc
+GOBIN=$d/gobin ./testgo get golang.org/x/tools/cmd/godoc || ok=false
 if [ ! -x $d/gobin/godoc ]; then
 	echo did not install godoc to '$GOBIN'
-	GOBIN=$d/gobin ./testgo list -f 'Target: {{.Target}}' code.google.com/p/go.tools/cmd/godoc
+	GOBIN=$d/gobin ./testgo list -f 'Target: {{.Target}}' golang.org/x/tools/cmd/godoc || true
 	ok=false
 fi
 
 TEST godoc installs into GOROOT
 GOROOT=$(./testgo env GOROOT)
 rm -f $GOROOT/bin/godoc
-./testgo install code.google.com/p/go.tools/cmd/godoc
+./testgo install golang.org/x/tools/cmd/godoc || ok=false
 if [ ! -x $GOROOT/bin/godoc ]; then
 	echo did not install godoc to '$GOROOT/bin'
-	./testgo list -f 'Target: {{.Target}}' code.google.com/p/go.tools/cmd/godoc
+	./testgo list -f 'Target: {{.Target}}' golang.org/x/tools/cmd/godoc || true
 	ok=false
 fi
 
@@ -272,36 +454,36 @@ TEST cmd/fix installs into tool
 GOOS=$(./testgo env GOOS)
 GOARCH=$(./testgo env GOARCH)
 rm -f $GOROOT/pkg/tool/${GOOS}_${GOARCH}/fix
-./testgo install cmd/fix
+./testgo install cmd/fix || ok=false
 if [ ! -x $GOROOT/pkg/tool/${GOOS}_${GOARCH}/fix ]; then
 	echo 'did not install cmd/fix to $GOROOT/pkg/tool'
-	GOBIN=$d/gobin ./testgo list -f 'Target: {{.Target}}' cmd/fix
+	GOBIN=$d/gobin ./testgo list -f 'Target: {{.Target}}' cmd/fix || true
 	ok=false
 fi
 rm -f $GOROOT/pkg/tool/${GOOS}_${GOARCH}/fix
-GOBIN=$d/gobin ./testgo install cmd/fix
+GOBIN=$d/gobin ./testgo install cmd/fix || ok=false
 if [ ! -x $GOROOT/pkg/tool/${GOOS}_${GOARCH}/fix ]; then
 	echo 'did not install cmd/fix to $GOROOT/pkg/tool with $GOBIN set'
-	GOBIN=$d/gobin ./testgo list -f 'Target: {{.Target}}' cmd/fix
+	GOBIN=$d/gobin ./testgo list -f 'Target: {{.Target}}' cmd/fix || true
 	ok=false
 fi
 
 TEST gopath program installs into GOBIN
 mkdir $d/src/progname
 echo 'package main; func main() {}' >$d/src/progname/p.go
-GOBIN=$d/gobin ./testgo install progname
+GOBIN=$d/gobin ./testgo install progname || ok=false
 if [ ! -x $d/gobin/progname ]; then
 	echo 'did not install progname to $GOBIN/progname'
-	./testgo list -f 'Target: {{.Target}}' cmd/api
+	./testgo list -f 'Target: {{.Target}}' cmd/api || true
 	ok=false
 fi
 rm -f $d/gobin/progname $d/bin/progname
 
 TEST gopath program installs into GOPATH/bin
-./testgo install progname
+./testgo install progname || ok=false
 if [ ! -x $d/bin/progname ]; then
 	echo 'did not install progname to $GOPATH/bin/progname'
-	./testgo list -f 'Target: {{.Target}}' progname
+	./testgo list -f 'Target: {{.Target}}' progname || true
 	ok=false
 fi
 
@@ -330,7 +512,7 @@ fi
 
 # ensure that output of 'go list' is consistent between runs
 TEST go list is consistent
-./testgo list std > test_std.list
+./testgo list std > test_std.list || ok=false
 if ! ./testgo list std | cmp -s test_std.list - ; then
 	echo "go list std ordering is inconsistent"
 	ok=false
@@ -378,9 +560,9 @@ fi
 # Test that without GOPATH set, go get should fail
 TEST without GOPATH, go get fails
 d=$(mktemp -d -t testgoXXX)
-mkdir -p $d/src/pkg
-if GOPATH= GOROOT=$d ./testgo get -d code.google.com/p/go.codereview/cmd/hgpatch ; then 
-	echo 'go get code.google.com/p/go.codereview/cmd/hgpatch should not succeed with $GOPATH unset'
+mkdir -p $d/src
+if GOPATH= GOROOT=$d ./testgo get -d golang.org/x/codereview/cmd/hgpatch ; then 
+	echo 'go get golang.org/x/codereview/cmd/hgpatch should not succeed with $GOPATH unset'
 	ok=false
 fi	
 rm -rf $d
@@ -388,9 +570,9 @@ rm -rf $d
 # Test that with GOPATH=$GOROOT, go get should fail
 TEST with GOPATH=GOROOT, go get fails
 d=$(mktemp -d -t testgoXXX)
-mkdir -p $d/src/pkg
-if GOPATH=$d GOROOT=$d ./testgo get -d code.google.com/p/go.codereview/cmd/hgpatch ; then
-        echo 'go get code.google.com/p/go.codereview/cmd/hgpatch should not succeed with GOPATH=$GOROOT'
+mkdir -p $d/src
+if GOPATH=$d GOROOT=$d ./testgo get -d golang.org/x/codereview/cmd/hgpatch ; then
+        echo 'go get golang.org/x/codereview/cmd/hgpatch should not succeed with GOPATH=$GOROOT'
         ok=false
 fi
 rm -rf $d
@@ -404,7 +586,7 @@ func main() {
 	println(extern)
 }
 EOF
-./testgo run -ldflags '-X main.extern "hello world"' $d/main.go 2>hello.out
+./testgo run -ldflags '-X main.extern "hello world"' $d/main.go 2>hello.out || ok=false
 if ! grep -q '^hello world' hello.out; then
 	echo "ldflags -X main.extern 'hello world' failed. Output:"
 	cat hello.out
@@ -420,6 +602,30 @@ if [ ! -x strings.test ]; then
 fi
 rm -f strings.prof strings.test
 
+TEST go test -cpuprofile -o controls binary location
+./testgo test -cpuprofile strings.prof -o mystrings.test strings || ok=false
+if [ ! -x mystrings.test ]; then
+	echo "go test -cpuprofile -o mystrings.test did not create mystrings.test"
+	ok=false
+fi
+rm -f strings.prof mystrings.test
+
+TEST go test -c -o controls binary location
+./testgo test -c -o mystrings.test strings || ok=false
+if [ ! -x mystrings.test ]; then
+	echo "go test -c -o mystrings.test did not create mystrings.test"
+	ok=false
+fi
+rm -f mystrings.test
+
+TEST go test -o writes binary
+./testgo test -o mystrings.test strings || ok=false
+if [ ! -x mystrings.test ]; then
+	echo "go test -o mystrings.test did not create mystrings.test"
+	ok=false
+fi
+rm -f mystrings.test
+
 TEST symlinks do not confuse go list '(issue 4568)'
 old=$(pwd)
 tmp=$(cd /tmp && pwd -P)
@@ -522,37 +728,56 @@ elif ! grep "case-insensitive file name collision" $d/out >/dev/null; then
 fi
 
 TEST go get cover
-./testgo get code.google.com/p/go.tools/cmd/cover || ok=false
+./testgo get golang.org/x/tools/cmd/cover || ok=false
 
 unset GOPATH
 rm -rf $d
 
+TEST go get -t "code.google.com/p/go-get-issue-8181/{a,b}"
+d=$(TMPDIR=/var/tmp mktemp -d -t testgoXXX)
+export GOPATH=$d
+if ./testgo get -t code.google.com/p/go-get-issue-8181/{a,b}; then
+	./testgo list ... | grep go.tools/godoc > /dev/null || ok=false
+else
+	ok=false
+fi
+unset GOPATH
+rm -rf $d
+
 TEST shadowing logic
 export GOPATH=$(pwd)/testdata/shadow/root1:$(pwd)/testdata/shadow/root2
 
 # The math in root1 is not "math" because the standard math is.
+set +e
 cdir=$(./testgo list -f '({{.ImportPath}}) ({{.ConflictDir}})' ./testdata/shadow/root1/src/math)
-if [ "$cdir" != "(_$(pwd)/testdata/shadow/root1/src/math) ($GOROOT/src/pkg/math)" ]; then
+set -e
+if [ "$cdir" != "(_$(pwd)/testdata/shadow/root1/src/math) ($GOROOT/src/math)" ]; then
 	echo shadowed math is not shadowed: "$cdir"
 	ok=false
 fi
 
 # The foo in root1 is "foo".
+set +e
 cdir=$(./testgo list -f '({{.ImportPath}}) ({{.ConflictDir}})' ./testdata/shadow/root1/src/foo)
+set -e
 if [ "$cdir" != "(foo) ()" ]; then
 	echo unshadowed foo is shadowed: "$cdir"
 	ok=false
 fi
 
 # The foo in root2 is not "foo" because the foo in root1 got there first.
+set +e
 cdir=$(./testgo list -f '({{.ImportPath}}) ({{.ConflictDir}})' ./testdata/shadow/root2/src/foo)
+set -e
 if [ "$cdir" != "(_$(pwd)/testdata/shadow/root2/src/foo) ($(pwd)/testdata/shadow/root1/src/foo)" ]; then
 	echo shadowed foo is not shadowed: "$cdir"
 	ok=false
 fi
 
 # The error for go install should mention the conflicting directory.
-err=$(! ./testgo install ./testdata/shadow/root2/src/foo 2>&1)
+set +e
+err=$(./testgo install ./testdata/shadow/root2/src/foo 2>&1)
+set -e
 if [ "$err" != "go install: no install location for $(pwd)/testdata/shadow/root2/src/foo: hidden by $(pwd)/testdata/shadow/root1/src/foo" ]; then
 	echo wrong shadowed install error: "$err"
 	ok=false
@@ -741,30 +966,46 @@ echo '
 package foo
 func F() {}
 ' >$d/src/x/y/foo/foo.go
+checkbar() {
+	desc="$1"
+	sleep 1
+	touch $d/src/x/y/foo/foo.go
+	if ! ./testgo build -v -i x/y/bar &> $d/err; then
+		echo build -i "$1" failed
+		cat $d/err
+		ok=false
+	elif ! grep x/y/foo $d/err >/dev/null; then
+		echo first build -i "$1" did not build x/y/foo
+		cat $d/err
+		ok=false
+	fi
+	if ! ./testgo build -v -i x/y/bar &> $d/err; then
+		echo second build -i "$1" failed
+		cat $d/err
+		ok=false
+	elif grep x/y/foo $d/err >/dev/null; then
+		echo second build -i "$1" built x/y/foo
+		cat $d/err
+		ok=false
+	fi
+}
+
 echo '
 package bar
 import "x/y/foo"
 func F() { foo.F() }
 ' >$d/src/x/y/bar/bar.go
-if ! ./testgo build -v -i x/y/bar &> $d/err; then
-	echo build -i failed
-	cat $d/err
-	ok=false
-elif ! grep x/y/foo $d/err >/dev/null; then
-	echo first build -i did not build x/y/foo
-	cat $d/err
-	ok=false
-fi
-if ! ./testgo build -v -i x/y/bar &> $d/err; then
-	echo second build -i failed
-	cat $d/err
-	ok=false
-elif grep x/y/foo $d/err >/dev/null; then
-	echo second build -i built x/y/foo
-	cat $d/err
-	ok=false
-fi
-rm -rf $d
+checkbar pkg
+
+TEST build -i installs dependencies for command
+echo '
+package main
+import "x/y/foo"
+func main() { foo.F() }
+' >$d/src/x/y/bar/bar.go
+checkbar cmd
+
+rm -rf $d bar
 unset GOPATH
 
 TEST 'go build in test-only directory fails with a good error'
@@ -799,13 +1040,74 @@ fi
 
 TEST 'go test xtestonly works'
 export GOPATH=$(pwd)/testdata
-./testgo clean -i xtestonly
+./testgo clean -i xtestonly || ok=false
 if ! ./testgo test xtestonly >/dev/null; then
 	echo "go test xtestonly failed"
 	ok=false
 fi
 unset GOPATH
 
+TEST 'go test builds an xtest containing only non-runnable examples'
+if ! ./testgo test -v ./testdata/norunexample > testdata/std.out; then
+	echo "go test ./testdata/norunexample failed"
+	ok=false
+elif ! grep 'File with non-runnable example was built.' testdata/std.out > /dev/null; then
+	echo "file with non-runnable example was not built"
+	ok=false
+fi
+
+TEST 'go generate handles simple command'
+if ! ./testgo generate ./testdata/generate/test1.go > testdata/std.out; then
+	echo "go test ./testdata/generate/test1.go failed to run"
+	ok=false
+elif ! grep 'Success' testdata/std.out > /dev/null; then
+	echo "go test ./testdata/generate/test1.go generated wrong output"
+	ok=false
+fi
+
+TEST 'go generate handles command alias'
+if ! ./testgo generate ./testdata/generate/test2.go > testdata/std.out; then
+	echo "go test ./testdata/generate/test2.go failed to run"
+	ok=false
+elif ! grep 'Now is the time for all good men' testdata/std.out > /dev/null; then
+	echo "go test ./testdata/generate/test2.go generated wrong output"
+	ok=false
+fi
+
+TEST 'go generate variable substitution'
+if ! ./testgo generate ./testdata/generate/test3.go > testdata/std.out; then
+	echo "go test ./testdata/generate/test3.go failed to run"
+	ok=false
+elif ! grep "$GOARCH test3.go p xyzp/test3.go/123" testdata/std.out > /dev/null; then
+	echo "go test ./testdata/generate/test3.go generated wrong output"
+	ok=false
+fi
+
+TEST go get works with vanity wildcards
+d=$(mktemp -d -t testgoXXX)
+export GOPATH=$d
+if ! ./testgo get -u rsc.io/pdf/...; then
+	ok=false
+elif [ ! -x $d/bin/pdfpasswd ]; then
+	echo did not build rsc.io/pdf/pdfpasswd
+	ok=false
+fi
+unset GOPATH
+rm -rf $d
+
+TEST go vet with external tests
+d=$(mktemp -d -t testgoXXX)
+export GOPATH=$(pwd)/testdata
+if ./testgo vet vetpkg >$d/err 2>&1; then
+	echo "go vet vetpkg passes incorrectly"
+	ok=false
+elif ! grep -q 'missing argument for Printf' $d/err; then
+	echo "go vet vetpkg did not find missing argument for Printf"
+	cat $d/err
+	ok=false
+fi
+unset GOPATH
+rm -rf $d
 
 # clean up
 if $started; then stop; fi
@@ -815,6 +1117,7 @@ rm -f testgo
 if $allok; then
 	echo PASS
 else
-	echo FAIL
+	echo FAIL:
+	echo "$testfail"
 	exit 1
 fi
diff --git a/src/cmd/go/test.go b/src/cmd/go/test.go
index 5935c98..c81e406 100644
--- a/src/cmd/go/test.go
+++ b/src/cmd/go/test.go
@@ -6,6 +6,7 @@ package main
 
 import (
 	"bytes"
+	"errors"
 	"fmt"
 	"go/ast"
 	"go/build"
@@ -48,7 +49,7 @@ It prints a summary of the test results in the format:
 followed by detailed output for each failed package.
 
 'Go test' recompiles each package along with any files with names matching
-the file pattern "*_test.go". 
+the file pattern "*_test.go".
 Files whose names begin with "_" (including "_test.go") or "." are ignored.
 These additional files can contain test functions, benchmark functions, and
 example functions.  See 'go help testfunc' for more.
@@ -65,16 +66,23 @@ non-test installation.
 
 In addition to the build flags, the flags handled by 'go test' itself are:
 
-	-c  Compile the test binary to pkg.test but do not run it.
-	    (Where pkg is the last element of the package's import path.)
+	-c
+		Compile the test binary to pkg.test but do not run it
+		(where pkg is the last element of the package's import path).
+		The file name can be changed with the -o flag.
+
+	-exec xprog
+	    Run the test binary using xprog. The behavior is the same as
+	    in 'go run'. See 'go help run' for details.
 
 	-i
 	    Install packages that are dependencies of the test.
 	    Do not run the test.
 
-	-exec xprog
-	    Run the test binary using xprog. The behavior is the same as
-	    in 'go run'. See 'go help run' for details.
+	-o file
+		Compile the test binary to the named file.
+		The test still runs (unless -c or -i is specified).
+
 
 The test binary also accepts flags that control execution of the test; these
 flags are also accessible by 'go test'.  See 'go help testflag' for details.
@@ -122,6 +130,7 @@ control the execution of any test:
 	-blockprofile block.out
 	    Write a goroutine blocking profile to the specified file
 	    when all tests are complete.
+	    Writes test binary as -c would.
 
 	-blockprofilerate n
 	    Control the detail provided in goroutine blocking profiles by
@@ -153,8 +162,7 @@ control the execution of any test:
 	    Sets -cover.
 
 	-coverprofile cover.out
-	    Write a coverage profile to the specified file after all tests
-	    have passed.
+	    Write a coverage profile to the file after all tests have passed.
 	    Sets -cover.
 
 	-cpu 1,2,4
@@ -164,10 +172,11 @@ control the execution of any test:
 
 	-cpuprofile cpu.out
 	    Write a CPU profile to the specified file before exiting.
+	    Writes test binary as -c would.
 
 	-memprofile mem.out
-	    Write a memory profile to the specified file after all tests
-	    have passed.
+	    Write a memory profile to the file after all tests have passed.
+	    Writes test binary as -c would.
 
 	-memprofilerate n
 	    Enable more precise (and expensive) memory profiles by setting
@@ -274,10 +283,10 @@ var (
 	testCoverMode    string     // -covermode flag
 	testCoverPaths   []string   // -coverpkg flag
 	testCoverPkgs    []*Package // -coverpkg flag
+	testO            string     // -o flag
 	testProfile      bool       // some profiling flag
 	testNeedBinary   bool       // profile needs to keep binary around
 	testV            bool       // -v flag
-	testFiles        []string   // -file flag(s)  TODO: not respected
 	testTimeout      string     // -timeout flag
 	testArgs         []string
 	testBench        bool
@@ -291,6 +300,7 @@ var testMainDeps = map[string]bool{
 	// Dependencies for testmain.
 	"testing": true,
 	"regexp":  true,
+	"os":      true,
 }
 
 func runTest(cmd *Command, args []string) {
@@ -308,6 +318,9 @@ func runTest(cmd *Command, args []string) {
 	if testC && len(pkgs) != 1 {
 		fatalf("cannot use -c flag with multiple packages")
 	}
+	if testO != "" && len(pkgs) != 1 {
+		fatalf("cannot use -o flag with multiple packages")
+	}
 	if testProfile && len(pkgs) != 1 {
 		fatalf("cannot use test profile flag with multiple packages")
 	}
@@ -522,6 +535,13 @@ func contains(x []string, s string) bool {
 	return false
 }
 
+var windowsBadWords = []string{
+	"install",
+	"patch",
+	"setup",
+	"update",
+}
+
 func (b *builder) test(p *Package) (buildAction, runAction, printAction *action, err error) {
 	if len(p.TestGoFiles)+len(p.XTestGoFiles) == 0 {
 		build := b.action(modeBuild, modeBuild, p)
@@ -687,7 +707,7 @@ func (b *builder) test(p *Package) (buildAction, runAction, printAction *action,
 		omitDWARF:  !testC && !testNeedBinary,
 	}
 
-	// The generated main also imports testing and regexp.
+	// The generated main also imports testing, regexp, and os.
 	stk.push("testmain")
 	for dep := range testMainDeps {
 		if dep == ptest.ImportPath {
@@ -723,11 +743,13 @@ func (b *builder) test(p *Package) (buildAction, runAction, printAction *action,
 	if err != nil {
 		return nil, nil, nil, err
 	}
-	if t.NeedTest || ptest.coverMode != "" {
+	if len(ptest.GoFiles) > 0 {
 		pmain.imports = append(pmain.imports, ptest)
+		t.ImportTest = true
 	}
-	if t.NeedXtest {
+	if pxtest != nil {
 		pmain.imports = append(pmain.imports, pxtest)
+		t.ImportXtest = true
 	}
 
 	if ptest != p && localCover {
@@ -779,17 +801,54 @@ func (b *builder) test(p *Package) (buildAction, runAction, printAction *action,
 	a.objdir = testDir + string(filepath.Separator)
 	a.objpkg = filepath.Join(testDir, "main.a")
 	a.target = filepath.Join(testDir, testBinary) + exeSuffix
-	pmainAction := a
+	if goos == "windows" {
+		// There are many reserved words on Windows that,
+		// if used in the name of an executable, cause Windows
+		// to try to ask for extra permissions.
+		// The word list includes setup, install, update, and patch,
+		// but it does not appear to be defined anywhere.
+		// We have run into this trying to run the
+		// go.codereview/patch tests.
+		// For package names containing those words, use test.test.exe
+		// instead of pkgname.test.exe.
+		// Note that this file name is only used in the Go command's
+		// temporary directory. If the -c or other flags are
+		// given, the code below will still use pkgname.test.exe.
+		// There are two user-visible effects of this change.
+		// First, you can actually run 'go test' in directories that
+		// have names that Windows thinks are installer-like,
+		// without getting a dialog box asking for more permissions.
+		// Second, in the Windows process listing during go test,
+		// the test shows up as test.test.exe, not pkgname.test.exe.
+		// That second one is a drawback, but it seems a small
+		// price to pay for the test running at all.
+		// If maintaining the list of bad words is too onerous,
+		// we could just do this always on Windows.
+		for _, bad := range windowsBadWords {
+			if strings.Contains(testBinary, bad) {
+				a.target = filepath.Join(testDir, "test.test") + exeSuffix
+				break
+			}
+		}
+	}
+	buildAction = a
 
 	if testC || testNeedBinary {
 		// -c or profiling flag: create action to copy binary to ./test.out.
-		runAction = &action{
+		target := filepath.Join(cwd, testBinary+exeSuffix)
+		if testO != "" {
+			target = testO
+			if !filepath.IsAbs(target) {
+				target = filepath.Join(cwd, target)
+			}
+		}
+		buildAction = &action{
 			f:      (*builder).install,
-			deps:   []*action{pmainAction},
+			deps:   []*action{buildAction},
 			p:      pmain,
-			target: filepath.Join(cwd, testBinary+exeSuffix),
+			target: target,
 		}
-		pmainAction = runAction // in case we are running the test
+		runAction = buildAction // make sure runAction != nil even if not running test
 	}
 	if testC {
 		printAction = &action{p: p, deps: []*action{runAction}} // nop
@@ -797,7 +856,7 @@ func (b *builder) test(p *Package) (buildAction, runAction, printAction *action,
 		// run test
 		runAction = &action{
 			f:          (*builder).runTest,
-			deps:       []*action{pmainAction},
+			deps:       []*action{buildAction},
 			p:          p,
 			ignoreFail: true,
 		}
@@ -813,7 +872,7 @@ func (b *builder) test(p *Package) (buildAction, runAction, printAction *action,
 		}
 	}
 
-	return pmainAction, runAction, printAction, nil
+	return buildAction, runAction, printAction, nil
 }
 
 func testImportStack(top string, p *Package, target string) []string {
@@ -1057,6 +1116,31 @@ func (b *builder) notest(a *action) error {
 	return nil
 }
 
+// isTestMain tells whether fn is a TestMain(m *testing.M) function.
+func isTestMain(fn *ast.FuncDecl) bool {
+	if fn.Name.String() != "TestMain" ||
+		fn.Type.Results != nil && len(fn.Type.Results.List) > 0 ||
+		fn.Type.Params == nil ||
+		len(fn.Type.Params.List) != 1 ||
+		len(fn.Type.Params.List[0].Names) > 1 {
+		return false
+	}
+	ptr, ok := fn.Type.Params.List[0].Type.(*ast.StarExpr)
+	if !ok {
+		return false
+	}
+	// We can't easily check that the type is *testing.M
+	// because we don't know how testing has been imported,
+	// but at least check that it's *M or *something.M.
+	if name, ok := ptr.X.(*ast.Ident); ok && name.Name == "M" {
+		return true
+	}
+	if sel, ok := ptr.X.(*ast.SelectorExpr); ok && sel.Sel.Name == "M" {
+		return true
+	}
+	return false
+}
+
 // isTest tells whether name looks like a test (or benchmark, according to prefix).
 // It is a Test (say) if there is a character after Test that is not a lower-case letter.
 // We don't want TesticularCancer.
@@ -1082,12 +1166,12 @@ func loadTestFuncs(ptest *Package) (*testFuncs, error) {
 		Package: ptest,
 	}
 	for _, file := range ptest.TestGoFiles {
-		if err := t.load(filepath.Join(ptest.Dir, file), "_test", &t.NeedTest); err != nil {
+		if err := t.load(filepath.Join(ptest.Dir, file), "_test", &t.ImportTest, &t.NeedTest); err != nil {
 			return nil, err
 		}
 	}
 	for _, file := range ptest.XTestGoFiles {
-		if err := t.load(filepath.Join(ptest.Dir, file), "_xtest", &t.NeedXtest); err != nil {
+		if err := t.load(filepath.Join(ptest.Dir, file), "_xtest", &t.ImportXtest, &t.NeedXtest); err != nil {
 			return nil, err
 		}
 	}
@@ -1110,13 +1194,16 @@ func writeTestmain(out string, t *testFuncs) error {
 }
 
 type testFuncs struct {
-	Tests      []testFunc
-	Benchmarks []testFunc
-	Examples   []testFunc
-	Package    *Package
-	NeedTest   bool
-	NeedXtest  bool
-	Cover      []coverInfo
+	Tests       []testFunc
+	Benchmarks  []testFunc
+	Examples    []testFunc
+	TestMain    *testFunc
+	Package     *Package
+	ImportTest  bool
+	NeedTest    bool
+	ImportXtest bool
+	NeedXtest   bool
+	Cover       []coverInfo
 }
 
 func (t *testFuncs) CoverMode() string {
@@ -1151,7 +1238,7 @@ type testFunc struct {
 
 var testFileSet = token.NewFileSet()
 
-func (t *testFuncs) load(filename, pkg string, seen *bool) error {
+func (t *testFuncs) load(filename, pkg string, doImport, seen *bool) error {
 	f, err := parser.ParseFile(testFileSet, filename, nil, parser.ParseComments)
 	if err != nil {
 		return expandScanner(err)
@@ -1166,17 +1253,24 @@ func (t *testFuncs) load(filename, pkg string, seen *bool) error {
 		}
 		name := n.Name.String()
 		switch {
+		case isTestMain(n):
+			if t.TestMain != nil {
+				return errors.New("multiple definitions of TestMain")
+			}
+			t.TestMain = &testFunc{pkg, name, ""}
+			*doImport, *seen = true, true
 		case isTest(name, "Test"):
 			t.Tests = append(t.Tests, testFunc{pkg, name, ""})
-			*seen = true
+			*doImport, *seen = true, true
 		case isTest(name, "Benchmark"):
 			t.Benchmarks = append(t.Benchmarks, testFunc{pkg, name, ""})
-			*seen = true
+			*doImport, *seen = true, true
 		}
 	}
 	ex := doc.Examples(f)
 	sort.Sort(byOrder(ex))
 	for _, e := range ex {
+		*doImport = true // import test file whether executed or not
 		if e.Output == "" && !e.EmptyOutput {
 			// Don't run examples with no output.
 			continue
@@ -1197,14 +1291,17 @@ var testmainTmpl = template.Must(template.New("main").Parse(`
 package main
 
 import (
+{{if not .TestMain}}
+	"os"
+{{end}}
 	"regexp"
 	"testing"
 
-{{if .NeedTest}}
-	_test {{.Package.ImportPath | printf "%q"}}
+{{if .ImportTest}}
+	{{if .NeedTest}}_test{{else}}_{{end}} {{.Package.ImportPath | printf "%q"}}
 {{end}}
-{{if .NeedXtest}}
-	_xtest {{.Package.ImportPath | printf "%s_test" | printf "%q"}}
+{{if .ImportXtest}}
+	{{if .NeedXtest}}_xtest{{else}}_{{end}} {{.Package.ImportPath | printf "%s_test" | printf "%q"}}
 {{end}}
 {{range $i, $p := .Cover}}
 	_cover{{$i}} {{$p.Package.ImportPath | printf "%q"}}
@@ -1291,7 +1388,12 @@ func main() {
 		CoveredPackages: {{printf "%q" .Covered}},
 	})
 {{end}}
-	testing.Main(matchString, tests, benchmarks, examples)
+	m := testing.MainStart(matchString, tests, benchmarks, examples)
+{{with .TestMain}}
+	{{.Package}}.{{.Name}}(m)
+{{else}}
+	os.Exit(m.Run())
+{{end}}
 }
 
 `))
diff --git a/src/cmd/go/testdata/generate/test1.go b/src/cmd/go/testdata/generate/test1.go
new file mode 100644
index 0000000..1f05734
--- /dev/null
+++ b/src/cmd/go/testdata/generate/test1.go
@@ -0,0 +1,13 @@
+// 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.
+
+// Simple test for go generate.
+
+// We include a build tag that go generate should ignore.
+
+// +build ignore
+
+//go:generate echo Success
+
+package p
diff --git a/src/cmd/go/testdata/generate/test2.go b/src/cmd/go/testdata/generate/test2.go
new file mode 100644
index 0000000..ef1a3d9
--- /dev/null
+++ b/src/cmd/go/testdata/generate/test2.go
@@ -0,0 +1,10 @@
+// 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 that go generate handles command aliases.
+
+//go:generate -command run echo Now is the time
+//go:generate run for all good men
+
+package p
diff --git a/src/cmd/go/testdata/generate/test3.go b/src/cmd/go/testdata/generate/test3.go
new file mode 100644
index 0000000..41ffb7e
--- /dev/null
+++ b/src/cmd/go/testdata/generate/test3.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.
+
+// Test go generate variable substitution.
+
+//go:generate echo $GOARCH $GOFILE $GOPACKAGE xyz$GOPACKAGE/$GOFILE/123
+
+package p
diff --git a/src/cmd/go/testdata/importcom/bad.go b/src/cmd/go/testdata/importcom/bad.go
new file mode 100644
index 0000000..e104c2e
--- /dev/null
+++ b/src/cmd/go/testdata/importcom/bad.go
@@ -0,0 +1,3 @@
+package p
+
+import "bad"
diff --git a/src/cmd/go/testdata/importcom/conflict.go b/src/cmd/go/testdata/importcom/conflict.go
new file mode 100644
index 0000000..995556c
--- /dev/null
+++ b/src/cmd/go/testdata/importcom/conflict.go
@@ -0,0 +1,3 @@
+package p
+
+import "conflict"
diff --git a/src/cmd/go/testdata/importcom/src/bad/bad.go b/src/cmd/go/testdata/importcom/src/bad/bad.go
new file mode 100644
index 0000000..bc51fd3
--- /dev/null
+++ b/src/cmd/go/testdata/importcom/src/bad/bad.go
@@ -0,0 +1 @@
+package bad // import
diff --git a/src/cmd/go/testdata/importcom/src/conflict/a.go b/src/cmd/go/testdata/importcom/src/conflict/a.go
new file mode 100644
index 0000000..2d67703
--- /dev/null
+++ b/src/cmd/go/testdata/importcom/src/conflict/a.go
@@ -0,0 +1 @@
+package conflict // import "a"
diff --git a/src/cmd/go/testdata/importcom/src/conflict/b.go b/src/cmd/go/testdata/importcom/src/conflict/b.go
new file mode 100644
index 0000000..8fcfb3c
--- /dev/null
+++ b/src/cmd/go/testdata/importcom/src/conflict/b.go
@@ -0,0 +1 @@
+package conflict /* import "b" */
diff --git a/src/cmd/go/testdata/importcom/src/works/x/x.go b/src/cmd/go/testdata/importcom/src/works/x/x.go
new file mode 100644
index 0000000..044c6ec
--- /dev/null
+++ b/src/cmd/go/testdata/importcom/src/works/x/x.go
@@ -0,0 +1 @@
+package x // import "works/x"
diff --git a/src/cmd/go/testdata/importcom/src/works/x/x1.go b/src/cmd/go/testdata/importcom/src/works/x/x1.go
new file mode 100644
index 0000000..2449b29
--- /dev/null
+++ b/src/cmd/go/testdata/importcom/src/works/x/x1.go
@@ -0,0 +1 @@
+package x // important! not an import comment
diff --git a/src/cmd/go/testdata/importcom/src/wrongplace/x.go b/src/cmd/go/testdata/importcom/src/wrongplace/x.go
new file mode 100644
index 0000000..b89849d
--- /dev/null
+++ b/src/cmd/go/testdata/importcom/src/wrongplace/x.go
@@ -0,0 +1 @@
+package x // import "my/x"
diff --git a/src/cmd/go/testdata/importcom/works.go b/src/cmd/go/testdata/importcom/works.go
new file mode 100644
index 0000000..31b55d0
--- /dev/null
+++ b/src/cmd/go/testdata/importcom/works.go
@@ -0,0 +1,3 @@
+package p
+
+import _ "works/x"
diff --git a/src/cmd/go/testdata/importcom/wrongplace.go b/src/cmd/go/testdata/importcom/wrongplace.go
new file mode 100644
index 0000000..e2535e0
--- /dev/null
+++ b/src/cmd/go/testdata/importcom/wrongplace.go
@@ -0,0 +1,3 @@
+package p
+
+import "wrongplace"
diff --git a/src/cmd/go/testdata/norunexample/example_test.go b/src/cmd/go/testdata/norunexample/example_test.go
new file mode 100644
index 0000000..e158305
--- /dev/null
+++ b/src/cmd/go/testdata/norunexample/example_test.go
@@ -0,0 +1,11 @@
+package pkg_test
+
+import "os"
+
+func init() {
+	os.Stdout.Write([]byte("File with non-runnable example was built.\n"))
+}
+
+func Example_test() {
+	// This test will not be run, it has no "Output:" comment.
+}
diff --git a/src/cmd/go/testdata/norunexample/test_test.go b/src/cmd/go/testdata/norunexample/test_test.go
new file mode 100644
index 0000000..d2e9198
--- /dev/null
+++ b/src/cmd/go/testdata/norunexample/test_test.go
@@ -0,0 +1,10 @@
+package pkg
+
+import (
+	"os"
+	"testing"
+)
+
+func TestBuilt(t *testing.T) {
+	os.Stdout.Write([]byte("A normal test was executed.\n"))
+}
diff --git a/src/cmd/go/testdata/src/badc/x.c b/src/cmd/go/testdata/src/badc/x.c
new file mode 100644
index 0000000..f6cbf69
--- /dev/null
+++ b/src/cmd/go/testdata/src/badc/x.c
@@ -0,0 +1 @@
+// C code!
diff --git a/src/cmd/go/testdata/src/badc/x.go b/src/cmd/go/testdata/src/badc/x.go
new file mode 100644
index 0000000..bfa1de2
--- /dev/null
+++ b/src/cmd/go/testdata/src/badc/x.go
@@ -0,0 +1 @@
+package badc
diff --git a/src/cmd/go/testdata/src/badtest/badexec/x_test.go b/src/cmd/go/testdata/src/badtest/badexec/x_test.go
new file mode 100644
index 0000000..12f5051
--- /dev/null
+++ b/src/cmd/go/testdata/src/badtest/badexec/x_test.go
@@ -0,0 +1,5 @@
+package badexec
+
+func init() {
+	panic("badexec")
+}
diff --git a/src/cmd/go/testdata/src/badtest/badsyntax/x.go b/src/cmd/go/testdata/src/badtest/badsyntax/x.go
new file mode 100644
index 0000000..c8a5407
--- /dev/null
+++ b/src/cmd/go/testdata/src/badtest/badsyntax/x.go
@@ -0,0 +1 @@
+package badsyntax
diff --git a/src/cmd/go/testdata/src/badtest/badsyntax/x_test.go b/src/cmd/go/testdata/src/badtest/badsyntax/x_test.go
new file mode 100644
index 0000000..5be1074
--- /dev/null
+++ b/src/cmd/go/testdata/src/badtest/badsyntax/x_test.go
@@ -0,0 +1,3 @@
+package badsyntax
+
+func func func func func!
diff --git a/src/cmd/go/testdata/src/badtest/badvar/x.go b/src/cmd/go/testdata/src/badtest/badvar/x.go
new file mode 100644
index 0000000..fdd46c4
--- /dev/null
+++ b/src/cmd/go/testdata/src/badtest/badvar/x.go
@@ -0,0 +1 @@
+package badvar
diff --git a/src/cmd/go/testdata/src/badtest/badvar/x_test.go b/src/cmd/go/testdata/src/badtest/badvar/x_test.go
new file mode 100644
index 0000000..c67df01
--- /dev/null
+++ b/src/cmd/go/testdata/src/badtest/badvar/x_test.go
@@ -0,0 +1,5 @@
+package badvar_test
+
+func f() {
+	_ = notdefined
+}
diff --git a/src/cmd/go/testdata/src/vetpkg/a_test.go b/src/cmd/go/testdata/src/vetpkg/a_test.go
new file mode 100644
index 0000000..9b64e8e
--- /dev/null
+++ b/src/cmd/go/testdata/src/vetpkg/a_test.go
@@ -0,0 +1 @@
+package p_test
diff --git a/src/cmd/go/testdata/src/vetpkg/b.go b/src/cmd/go/testdata/src/vetpkg/b.go
new file mode 100644
index 0000000..99e18f6
--- /dev/null
+++ b/src/cmd/go/testdata/src/vetpkg/b.go
@@ -0,0 +1,7 @@
+package p
+
+import "fmt"
+
+func f() {
+	fmt.Printf("%d")
+}
diff --git a/src/cmd/go/testdata/testinternal/p.go b/src/cmd/go/testdata/testinternal/p.go
new file mode 100644
index 0000000..e3558a5
--- /dev/null
+++ b/src/cmd/go/testdata/testinternal/p.go
@@ -0,0 +1,3 @@
+package p
+
+import _ "net/http/internal"
diff --git a/src/cmd/go/testdata/testinternal2/p.go b/src/cmd/go/testdata/testinternal2/p.go
new file mode 100644
index 0000000..c594f5c
--- /dev/null
+++ b/src/cmd/go/testdata/testinternal2/p.go
@@ -0,0 +1,3 @@
+package p
+
+import _ "./x/y/z/internal/w"
diff --git a/src/cmd/go/testdata/testinternal2/x/y/z/internal/w/w.go b/src/cmd/go/testdata/testinternal2/x/y/z/internal/w/w.go
new file mode 100644
index 0000000..a796c0b
--- /dev/null
+++ b/src/cmd/go/testdata/testinternal2/x/y/z/internal/w/w.go
@@ -0,0 +1 @@
+package w
diff --git a/src/cmd/go/testflag.go b/src/cmd/go/testflag.go
index 73f311e..6da74b9 100644
--- a/src/cmd/go/testflag.go
+++ b/src/cmd/go/testflag.go
@@ -65,9 +65,9 @@ type testFlagSpec struct {
 var testFlagDefn = []*testFlagSpec{
 	// local.
 	{name: "c", boolVar: &testC},
-	{name: "file", multiOK: true},
 	{name: "cover", boolVar: &testCover},
 	{name: "coverpkg"},
+	{name: "o"},
 
 	// build flags.
 	{name: "a", boolVar: &buildA},
@@ -153,6 +153,9 @@ func testFlags(args []string) (packageNames, passToTest []string) {
 		// bool flags.
 		case "a", "c", "i", "n", "x", "v", "race", "cover", "work":
 			setBoolFlag(f.boolVar, value)
+		case "o":
+			testO = value
+			testNeedBinary = true
 		case "p":
 			setIntFlag(&buildP, value)
 		case "exec":
@@ -184,8 +187,6 @@ func testFlags(args []string) (packageNames, passToTest []string) {
 			buildContext.BuildTags = strings.Fields(value)
 		case "compiler":
 			buildCompiler{}.Set(value)
-		case "file":
-			testFiles = append(testFiles, value)
 		case "bench":
 			// record that we saw the flag; don't care about the value
 			testBench = true
diff --git a/src/cmd/go/testgo.go b/src/cmd/go/testgo.go
new file mode 100644
index 0000000..01923f7
--- /dev/null
+++ b/src/cmd/go/testgo.go
@@ -0,0 +1,21 @@
+// 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 file contains extra hooks for testing the go command.
+// It is compiled into the Go binary only when building the
+// test copy; it does not get compiled into the standard go
+// command, so these testing hooks are not present in the
+// go command that everyone uses.
+
+// +build testgo
+
+package main
+
+import "os"
+
+func init() {
+	if v := os.Getenv("TESTGO_IS_GO_RELEASE"); v != "" {
+		isGoRelease = v == "1"
+	}
+}
diff --git a/src/cmd/go/tool.go b/src/cmd/go/tool.go
index 6d26f7a..3f11c3e 100644
--- a/src/cmd/go/tool.go
+++ b/src/cmd/go/tool.go
@@ -47,13 +47,13 @@ const toolWindowsExtension = ".exe"
 
 func tool(toolName string) string {
 	toolPath := filepath.Join(toolDir, toolName)
-	if toolIsWindows && toolName != "pprof" {
+	if toolIsWindows {
 		toolPath += toolWindowsExtension
 	}
 	// Give a nice message if there is no tool with that name.
 	if _, err := os.Stat(toolPath); err != nil {
 		if isInGoToolsRepo(toolName) {
-			fmt.Fprintf(os.Stderr, "go tool: no such tool %q; to install:\n\tgo get code.google.com/p/go.tools/cmd/%s\n", toolName, toolName)
+			fmt.Fprintf(os.Stderr, "go tool: no such tool %q; to install:\n\tgo get golang.org/x/tools/cmd/%s\n", toolName, toolName)
 		} else {
 			fmt.Fprintf(os.Stderr, "go tool: no such tool %q\n", toolName)
 		}
@@ -91,16 +91,6 @@ func runTool(cmd *Command, args []string) {
 	if toolPath == "" {
 		return
 	}
-	if toolIsWindows && toolName == "pprof" {
-		args = append([]string{"perl", toolPath}, args[1:]...)
-		var err error
-		toolPath, err = exec.LookPath("perl")
-		if err != nil {
-			fmt.Fprintf(os.Stderr, "go tool: perl not found\n")
-			setExitStatus(3)
-			return
-		}
-	}
 	if toolN {
 		fmt.Printf("%s %s\n", toolPath, strings.Join(args[1:], " "))
 		return
diff --git a/src/cmd/go/vcs.go b/src/cmd/go/vcs.go
index 8f0bae0..1cac613 100644
--- a/src/cmd/go/vcs.go
+++ b/src/cmd/go/vcs.go
@@ -33,6 +33,9 @@ type vcsCmd struct {
 
 	scheme  []string
 	pingCmd string
+
+	remoteRepo  func(v *vcsCmd, rootDir string) (remoteRepo string, err error)
+	resolveRepo func(v *vcsCmd, rootDir, remoteRepo string) (realRepo string, err error)
 }
 
 // A tagCmd describes a command to list available tags
@@ -81,8 +84,17 @@ var vcsHg = &vcsCmd{
 	tagSyncCmd:     "update -r {tag}",
 	tagSyncDefault: "update default",
 
-	scheme:  []string{"https", "http", "ssh"},
-	pingCmd: "identify {scheme}://{repo}",
+	scheme:     []string{"https", "http", "ssh"},
+	pingCmd:    "identify {scheme}://{repo}",
+	remoteRepo: hgRemoteRepo,
+}
+
+func hgRemoteRepo(vcsHg *vcsCmd, rootDir string) (remoteRepo string, err error) {
+	out, err := vcsHg.runOutput(rootDir, "paths default")
+	if err != nil {
+		return "", err
+	}
+	return strings.TrimSpace(string(out)), nil
 }
 
 // vcsGit describes how to use Git.
@@ -104,8 +116,38 @@ var vcsGit = &vcsCmd{
 	tagSyncCmd:     "checkout {tag}",
 	tagSyncDefault: "checkout master",
 
-	scheme:  []string{"git", "https", "http", "git+ssh"},
-	pingCmd: "ls-remote {scheme}://{repo}",
+	scheme:     []string{"git", "https", "http", "git+ssh"},
+	pingCmd:    "ls-remote {scheme}://{repo}",
+	remoteRepo: gitRemoteRepo,
+}
+
+func gitRemoteRepo(vcsGit *vcsCmd, rootDir string) (remoteRepo string, err error) {
+	outb, err := vcsGit.runOutput(rootDir, "remote -v")
+	if err != nil {
+		return "", err
+	}
+	out := string(outb)
+
+	// Expect:
+	// origin	https://github.com/rsc/pdf (fetch)
+	// origin	https://github.com/rsc/pdf (push)
+	// use first line only.
+
+	if !strings.HasPrefix(out, "origin\t") {
+		return "", fmt.Errorf("unable to parse output of git remote -v")
+	}
+	out = strings.TrimPrefix(out, "origin\t")
+	i := strings.Index(out, "\n")
+	if i < 0 {
+		return "", fmt.Errorf("unable to parse output of git remote -v")
+	}
+	out = out[:i]
+	i = strings.LastIndex(out, " ")
+	if i < 0 {
+		return "", fmt.Errorf("unable to parse output of git remote -v")
+	}
+	out = out[:i]
+	return strings.TrimSpace(string(out)), nil
 }
 
 // vcsBzr describes how to use Bazaar.
@@ -123,8 +165,51 @@ var vcsBzr = &vcsCmd{
 	tagSyncCmd:     "update -r {tag}",
 	tagSyncDefault: "update -r revno:-1",
 
-	scheme:  []string{"https", "http", "bzr", "bzr+ssh"},
-	pingCmd: "info {scheme}://{repo}",
+	scheme:      []string{"https", "http", "bzr", "bzr+ssh"},
+	pingCmd:     "info {scheme}://{repo}",
+	remoteRepo:  bzrRemoteRepo,
+	resolveRepo: bzrResolveRepo,
+}
+
+func bzrRemoteRepo(vcsBzr *vcsCmd, rootDir string) (remoteRepo string, err error) {
+	outb, err := vcsBzr.runOutput(rootDir, "config parent_location")
+	if err != nil {
+		return "", err
+	}
+	return strings.TrimSpace(string(outb)), nil
+}
+
+func bzrResolveRepo(vcsBzr *vcsCmd, rootDir, remoteRepo string) (realRepo string, err error) {
+	outb, err := vcsBzr.runOutput(rootDir, "info "+remoteRepo)
+	if err != nil {
+		return "", err
+	}
+	out := string(outb)
+
+	// Expect:
+	// ...
+	//   (branch root|repository branch): <URL>
+	// ...
+
+	found := false
+	for _, prefix := range []string{"\n  branch root: ", "\n  repository branch: "} {
+		i := strings.Index(out, prefix)
+		if i >= 0 {
+			out = out[i+len(prefix):]
+			found = true
+			break
+		}
+	}
+	if !found {
+		return "", fmt.Errorf("unable to parse output of bzr info")
+	}
+
+	i := strings.Index(out, "\n")
+	if i < 0 {
+		return "", fmt.Errorf("unable to parse output of bzr info")
+	}
+	out = out[:i]
+	return strings.TrimSpace(string(out)), nil
 }
 
 // vcsSvn describes how to use Subversion.
@@ -138,8 +223,34 @@ var vcsSvn = &vcsCmd{
 	// There is no tag command in subversion.
 	// The branch information is all in the path names.
 
-	scheme:  []string{"https", "http", "svn", "svn+ssh"},
-	pingCmd: "info {scheme}://{repo}",
+	scheme:     []string{"https", "http", "svn", "svn+ssh"},
+	pingCmd:    "info {scheme}://{repo}",
+	remoteRepo: svnRemoteRepo,
+}
+
+func svnRemoteRepo(vcsSvn *vcsCmd, rootDir string) (remoteRepo string, err error) {
+	outb, err := vcsSvn.runOutput(rootDir, "info")
+	if err != nil {
+		return "", err
+	}
+	out := string(outb)
+
+	// Expect:
+	// ...
+	// Repository Root: <URL>
+	// ...
+
+	i := strings.Index(out, "\nRepository Root: ")
+	if i < 0 {
+		return "", fmt.Errorf("unable to parse output of svn info")
+	}
+	out = out[i+len("\nRepository Root: "):]
+	i = strings.Index(out, "\n")
+	if i < 0 {
+		return "", fmt.Errorf("unable to parse output of svn info")
+	}
+	out = out[:i]
+	return strings.TrimSpace(string(out)), nil
 }
 
 func (v *vcsCmd) String() string {
@@ -361,7 +472,14 @@ var httpPrefixRE = regexp.MustCompile(`^https?:`)
 func repoRootForImportPath(importPath string) (*repoRoot, error) {
 	rr, err := repoRootForImportPathStatic(importPath, "")
 	if err == errUnknownSite {
-		rr, err = repoRootForImportDynamic(importPath)
+		// If there are wildcards, look up the thing before the wildcard,
+		// hoping it applies to the wildcarded parts too.
+		// This makes 'go get rsc.io/pdf/...' work in a fresh GOPATH.
+		lookup := strings.TrimSuffix(importPath, "/...")
+		if i := strings.Index(lookup, "/.../"); i >= 0 {
+			lookup = lookup[:i]
+		}
+		rr, err = repoRootForImportDynamic(lookup)
 
 		// repoRootForImportDynamic returns error detail
 		// that is irrelevant if the user didn't intend to use a
@@ -465,11 +583,11 @@ func repoRootForImportPathStatic(importPath, scheme string) (*repoRoot, error) {
 func repoRootForImportDynamic(importPath string) (*repoRoot, error) {
 	slash := strings.Index(importPath, "/")
 	if slash < 0 {
-		return nil, errors.New("import path doesn't contain a slash")
+		return nil, errors.New("import path does not contain a slash")
 	}
 	host := importPath[:slash]
 	if !strings.Contains(host, ".") {
-		return nil, errors.New("import path doesn't contain a hostname")
+		return nil, errors.New("import path does not begin with hostname")
 	}
 	urlStr, body, err := httpsOrHTTP(importPath)
 	if err != nil {
@@ -613,6 +731,15 @@ var vcsPaths = []*vcsPath{
 		check:  launchpadVCS,
 	},
 
+	// IBM DevOps Services (JazzHub)
+	{
+		prefix: "hub.jazz.net/git",
+		re:     `^(?P<root>hub.jazz.net/git/[a-z0-9]+/[A-Za-z0-9_.\-]+)(/[A-Za-z0-9_.\-]+)*$`,
+		vcs:    "git",
+		repo:   "https://{root}",
+		check:  noVCSSuffix,
+	},
+
 	// General syntax for any server.
 	{
 		re:   `^(?P<root>(?P<repo>([a-z0-9.\-]+\.)+[a-z0-9.\-]+(:[0-9]+)?/[A-Za-z0-9_.\-/]*?)\.(?P<vcs>bzr|git|hg|svn))(/[A-Za-z0-9_.\-]+)*$`,
diff --git a/src/cmd/go/vcs_test.go b/src/cmd/go/vcs_test.go
new file mode 100644
index 0000000..14d681b
--- /dev/null
+++ b/src/cmd/go/vcs_test.go
@@ -0,0 +1,124 @@
+// 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 (
+	"runtime"
+	"testing"
+)
+
+// Test that RepoRootForImportPath creates the correct RepoRoot for a given importPath.
+// TODO(cmang): Add tests for SVN and BZR.
+func TestRepoRootForImportPath(t *testing.T) {
+	if testing.Short() {
+		t.Skip("skipping test to avoid external network")
+	}
+	switch runtime.GOOS {
+	case "nacl", "android":
+		t.Skipf("no networking available on %s", runtime.GOOS)
+	}
+	tests := []struct {
+		path string
+		want *repoRoot
+	}{
+		{
+			"code.google.com/p/go",
+			&repoRoot{
+				vcs:  vcsHg,
+				repo: "https://code.google.com/p/go",
+			},
+		},
+		/*{
+		        "code.google.com/r/go",
+		        &repoRoot{
+		                vcs:  vcsHg,
+		                repo: "https://code.google.com/r/go",
+		        },
+		},*/
+		{
+			"github.com/golang/groupcache",
+			&repoRoot{
+				vcs:  vcsGit,
+				repo: "https://github.com/golang/groupcache",
+			},
+		},
+		// IBM DevOps Services tests
+		{
+			"hub.jazz.net/git/user1/pkgname",
+			&repoRoot{
+				vcs:  vcsGit,
+				repo: "https://hub.jazz.net/git/user1/pkgname",
+			},
+		},
+		{
+			"hub.jazz.net/git/user1/pkgname/submodule/submodule/submodule",
+			&repoRoot{
+				vcs:  vcsGit,
+				repo: "https://hub.jazz.net/git/user1/pkgname",
+			},
+		},
+		{
+			"hub.jazz.net",
+			nil,
+		},
+		{
+			"hub2.jazz.net",
+			nil,
+		},
+		{
+			"hub.jazz.net/someotherprefix",
+			nil,
+		},
+		{
+			"hub.jazz.net/someotherprefix/user1/pkgname",
+			nil,
+		},
+		// Spaces are not valid in user names or package names
+		{
+			"hub.jazz.net/git/User 1/pkgname",
+			nil,
+		},
+		{
+			"hub.jazz.net/git/user1/pkg name",
+			nil,
+		},
+		// Dots are not valid in user names
+		{
+			"hub.jazz.net/git/user.1/pkgname",
+			nil,
+		},
+		{
+			"hub.jazz.net/git/user/pkg.name",
+			&repoRoot{
+				vcs:  vcsGit,
+				repo: "https://hub.jazz.net/git/user/pkg.name",
+			},
+		},
+		// User names cannot have uppercase letters
+		{
+			"hub.jazz.net/git/USER/pkgname",
+			nil,
+		},
+	}
+
+	for _, test := range tests {
+		got, err := repoRootForImportPath(test.path)
+		want := test.want
+
+		if want == nil {
+			if err == nil {
+				t.Errorf("RepoRootForImport(%q): Error expected but not received", test.path)
+			}
+			continue
+		}
+		if err != nil {
+			t.Errorf("RepoRootForImport(%q): %v", test.path, err)
+			continue
+		}
+		if got.vcs.name != want.vcs.name || got.repo != want.repo {
+			t.Errorf("RepoRootForImport(%q) = VCS(%s) Repo(%s), want VCS(%s) Repo(%s)", test.path, got.vcs, got.repo, want.vcs, want.repo)
+		}
+	}
+}
diff --git a/src/cmd/go/vet.go b/src/cmd/go/vet.go
index ffb4318..02ff54b 100644
--- a/src/cmd/go/vet.go
+++ b/src/cmd/go/vet.go
@@ -4,6 +4,8 @@
 
 package main
 
+import "path/filepath"
+
 func init() {
 	addBuildFlagsNX(cmdVet)
 }
@@ -15,7 +17,7 @@ var cmdVet = &Command{
 	Long: `
 Vet runs the Go vet command on the packages named by the import paths.
 
-For more about vet, see 'godoc code.google.com/p/go.tools/cmd/vet'.
+For more about vet, see 'godoc golang.org/x/tools/cmd/vet'.
 For more about specifying packages, see 'go help packages'.
 
 To run the vet tool with specific options, run 'go tool vet'.
@@ -28,10 +30,21 @@ See also: go fmt, go fix.
 }
 
 func runVet(cmd *Command, args []string) {
-	for _, pkg := range packages(args) {
-		// Use pkg.gofiles instead of pkg.Dir so that
-		// the command only applies to this package,
-		// not to packages in subdirectories.
-		run(tool("vet"), relPaths(stringList(pkg.gofiles, pkg.sfiles)))
+	for _, p := range packages(args) {
+		// Vet expects to be given a set of files all from the same package.
+		// Run once for package p and once for package p_test.
+		if len(p.GoFiles)+len(p.CgoFiles)+len(p.TestGoFiles) > 0 {
+			runVetFiles(p, stringList(p.GoFiles, p.CgoFiles, p.TestGoFiles, p.SFiles))
+		}
+		if len(p.XTestGoFiles) > 0 {
+			runVetFiles(p, stringList(p.XTestGoFiles))
+		}
+	}
+}
+
+func runVetFiles(p *Package, files []string) {
+	for i := range files {
+		files[i] = filepath.Join(p.Dir, files[i])
 	}
+	run(tool("vet"), relPaths(files))
 }
diff --git a/src/cmd/gofmt/doc.go b/src/cmd/gofmt/doc.go
index 8f73ef5..3fc0439 100644
--- a/src/cmd/gofmt/doc.go
+++ b/src/cmd/gofmt/doc.go
@@ -67,7 +67,7 @@ To remove the parentheses:
 
 To convert the package tree from explicit slice upper bounds to implicit ones:
 
-	gofmt -r 'α[β:len(α)] -> α[β:]' -w $GOROOT/src/pkg
+	gofmt -r 'α[β:len(α)] -> α[β:]' -w $GOROOT/src
 
 The simplify command
 
diff --git a/src/cmd/gofmt/gofmt.go b/src/cmd/gofmt/gofmt.go
index 576cae5..81da21f 100644
--- a/src/cmd/gofmt/gofmt.go
+++ b/src/cmd/gofmt/gofmt.go
@@ -87,13 +87,13 @@ func processFile(filename string, in io.Reader, out io.Writer, stdin bool) error
 		return err
 	}
 
-	file, adjust, err := parse(fileSet, filename, src, stdin)
+	file, sourceAdj, indentAdj, err := parse(fileSet, filename, src, stdin)
 	if err != nil {
 		return err
 	}
 
 	if rewrite != nil {
-		if adjust == nil {
+		if sourceAdj == nil {
 			file = rewrite(file)
 		} else {
 			fmt.Fprintf(os.Stderr, "warning: rewrite ignored for incomplete programs\n")
@@ -106,15 +106,10 @@ func processFile(filename string, in io.Reader, out io.Writer, stdin bool) error
 		simplify(file)
 	}
 
-	var buf bytes.Buffer
-	err = (&printer.Config{Mode: printerMode, Tabwidth: tabWidth}).Fprint(&buf, fileSet, file)
+	res, err := format(fileSet, file, sourceAdj, indentAdj, src, printer.Config{Mode: printerMode, Tabwidth: tabWidth})
 	if err != nil {
 		return err
 	}
-	res := buf.Bytes()
-	if adjust != nil {
-		res = adjust(src, res)
-	}
 
 	if !bytes.Equal(src, res) {
 		// formatting has changed
@@ -122,7 +117,7 @@ func processFile(filename string, in io.Reader, out io.Writer, stdin bool) error
 			fmt.Fprintln(out, filename)
 		}
 		if *write {
-			err = ioutil.WriteFile(filename, res, 0)
+			err = ioutil.WriteFile(filename, res, 0644)
 			if err != nil {
 				return err
 			}
@@ -186,6 +181,11 @@ func gofmtMain() {
 	initRewrite()
 
 	if flag.NArg() == 0 {
+		if *write {
+			fmt.Fprintln(os.Stderr, "error: cannot use -w with standard input")
+			exitCode = 2
+			return
+		}
 		if err := processFile("<standard input>", os.Stdin, os.Stdout, true); err != nil {
 			report(err)
 		}
@@ -235,19 +235,29 @@ func diff(b1, b2 []byte) (data []byte, err error) {
 
 }
 
-// parse parses src, which was read from filename,
-// as a Go source file or statement list.
-func parse(fset *token.FileSet, filename string, src []byte, stdin bool) (*ast.File, func(orig, src []byte) []byte, error) {
+// ----------------------------------------------------------------------------
+// Support functions
+//
+// The functions parse, format, and isSpace below are identical to the
+// respective functions in src/go/format/format.go - keep them in sync!
+//
+// TODO(gri) Factor out this functionality, eventually.
+
+// parse parses src, which was read from the named file,
+// as a Go source file, declaration, or statement list.
+func parse(fset *token.FileSet, filename string, src []byte, fragmentOk bool) (
+	file *ast.File,
+	sourceAdj func(src []byte, indent int) []byte,
+	indentAdj int,
+	err error,
+) {
 	// Try as whole source file.
-	file, err := parser.ParseFile(fset, filename, src, parserMode)
-	if err == nil {
-		return file, nil, nil
-	}
-	// If the error is that the source file didn't begin with a
-	// package line and this is standard input, fall through to
+	file, err = parser.ParseFile(fset, filename, src, parserMode)
+	// If there's no error, return.  If the error is that the source file didn't begin with a
+	// package line and source fragments are ok, fall through to
 	// try as a source fragment.  Stop and return on any other error.
-	if !stdin || !strings.Contains(err.Error(), "expected 'package'") {
-		return nil, nil, err
+	if err == nil || !fragmentOk || !strings.Contains(err.Error(), "expected 'package'") {
+		return
 	}
 
 	// If this is a declaration list, make it a source file
@@ -257,19 +267,19 @@ func parse(fset *token.FileSet, filename string, src []byte, stdin bool) (*ast.F
 	psrc := append([]byte("package p;"), src...)
 	file, err = parser.ParseFile(fset, filename, psrc, parserMode)
 	if err == nil {
-		adjust := func(orig, src []byte) []byte {
+		sourceAdj = func(src []byte, indent int) []byte {
 			// Remove the package clause.
 			// Gofmt has turned the ; into a \n.
-			src = src[len("package p\n"):]
-			return matchSpace(orig, src)
+			src = src[indent+len("package p\n"):]
+			return bytes.TrimSpace(src)
 		}
-		return file, adjust, nil
+		return
 	}
 	// If the error is that the source file didn't begin with a
 	// declaration, fall through to try as a statement list.
 	// Stop and return on any other error.
 	if !strings.Contains(err.Error(), "expected declaration") {
-		return nil, nil, err
+		return
 	}
 
 	// If this is a statement list, make it a source file
@@ -277,68 +287,101 @@ func parse(fset *token.FileSet, filename string, src []byte, stdin bool) (*ast.F
 	// into a function body.  This handles expressions too.
 	// Insert using a ;, not a newline, so that the line numbers
 	// in fsrc match the ones in src.
-	fsrc := append(append([]byte("package p; func _() {"), src...), '}')
+	fsrc := append(append([]byte("package p; func _() {"), src...), '\n', '}')
 	file, err = parser.ParseFile(fset, filename, fsrc, parserMode)
 	if err == nil {
-		adjust := func(orig, src []byte) []byte {
+		sourceAdj = func(src []byte, indent int) []byte {
+			// Cap adjusted indent to zero.
+			if indent < 0 {
+				indent = 0
+			}
 			// Remove the wrapping.
 			// Gofmt has turned the ; into a \n\n.
-			src = src[len("package p\n\nfunc _() {"):]
-			src = src[:len(src)-len("}\n")]
-			// Gofmt has also indented the function body one level.
-			// Remove that indent.
-			src = bytes.Replace(src, []byte("\n\t"), []byte("\n"), -1)
-			return matchSpace(orig, src)
+			// There will be two non-blank lines with indent, hence 2*indent.
+			src = src[2*indent+len("package p\n\nfunc _() {"):]
+			src = src[:len(src)-(indent+len("\n}\n"))]
+			return bytes.TrimSpace(src)
 		}
-		return file, adjust, nil
+		// Gofmt has also indented the function body one level.
+		// Adjust that with indentAdj.
+		indentAdj = -1
 	}
 
-	// Failed, and out of options.
-	return nil, nil, err
+	// Succeeded, or out of options.
+	return
 }
 
-func cutSpace(b []byte) (before, middle, after []byte) {
-	i := 0
-	for i < len(b) && (b[i] == ' ' || b[i] == '\t' || b[i] == '\n') {
-		i++
-	}
-	j := len(b)
-	for j > 0 && (b[j-1] == ' ' || b[j-1] == '\t' || b[j-1] == '\n') {
-		j--
-	}
-	if i <= j {
-		return b[:i], b[i:j], b[j:]
+// format formats the given package file originally obtained from src
+// and adjusts the result based on the original source via sourceAdj
+// and indentAdj.
+func format(
+	fset *token.FileSet,
+	file *ast.File,
+	sourceAdj func(src []byte, indent int) []byte,
+	indentAdj int,
+	src []byte,
+	cfg printer.Config,
+) ([]byte, error) {
+	if sourceAdj == nil {
+		// Complete source file.
+		var buf bytes.Buffer
+		err := cfg.Fprint(&buf, fset, file)
+		if err != nil {
+			return nil, err
+		}
+		return buf.Bytes(), nil
 	}
-	return nil, nil, b[j:]
-}
 
-// matchSpace reformats src to use the same space context as orig.
-// 1) If orig begins with blank lines, matchSpace inserts them at the beginning of src.
-// 2) matchSpace copies the indentation of the first non-blank line in orig
-//    to every non-blank line in src.
-// 3) matchSpace copies the trailing space from orig and uses it in place
-//   of src's trailing space.
-func matchSpace(orig []byte, src []byte) []byte {
-	before, _, after := cutSpace(orig)
-	i := bytes.LastIndex(before, []byte{'\n'})
-	before, indent := before[:i+1], before[i+1:]
-
-	_, src, _ = cutSpace(src)
-
-	var b bytes.Buffer
-	b.Write(before)
-	for len(src) > 0 {
-		line := src
-		if i := bytes.IndexByte(line, '\n'); i >= 0 {
-			line, src = line[:i+1], line[i+1:]
-		} else {
-			src = nil
+	// Partial source file.
+	// Determine and prepend leading space.
+	i, j := 0, 0
+	for j < len(src) && isSpace(src[j]) {
+		if src[j] == '\n' {
+			i = j + 1 // byte offset of last line in leading space
 		}
-		if len(line) > 0 && line[0] != '\n' { // not blank
-			b.Write(indent)
+		j++
+	}
+	var res []byte
+	res = append(res, src[:i]...)
+
+	// Determine and prepend indentation of first code line.
+	// Spaces are ignored unless there are no tabs,
+	// in which case spaces count as one tab.
+	indent := 0
+	hasSpace := false
+	for _, b := range src[i:j] {
+		switch b {
+		case ' ':
+			hasSpace = true
+		case '\t':
+			indent++
 		}
-		b.Write(line)
 	}
-	b.Write(after)
-	return b.Bytes()
+	if indent == 0 && hasSpace {
+		indent = 1
+	}
+	for i := 0; i < indent; i++ {
+		res = append(res, '\t')
+	}
+
+	// Format the source.
+	// Write it without any leading and trailing space.
+	cfg.Indent = indent + indentAdj
+	var buf bytes.Buffer
+	err := cfg.Fprint(&buf, fset, file)
+	if err != nil {
+		return nil, err
+	}
+	res = append(res, sourceAdj(buf.Bytes(), cfg.Indent)...)
+
+	// Determine and append trailing space.
+	i = len(src)
+	for i > 0 && isSpace(src[i-1]) {
+		i--
+	}
+	return append(res, src[i:]...), nil
+}
+
+func isSpace(b byte) bool {
+	return b == ' ' || b == '\t' || b == '\n' || b == '\r'
 }
diff --git a/src/cmd/gofmt/gofmt_test.go b/src/cmd/gofmt/gofmt_test.go
index b9335b8..d1edb7b 100644
--- a/src/cmd/gofmt/gofmt_test.go
+++ b/src/cmd/gofmt/gofmt_test.go
@@ -6,18 +6,60 @@ package main
 
 import (
 	"bytes"
+	"flag"
 	"io/ioutil"
+	"os"
 	"path/filepath"
 	"strings"
 	"testing"
+	"text/scanner"
 )
 
-func runTest(t *testing.T, in, out, flags string) {
+var update = flag.Bool("update", false, "update .golden files")
+
+// gofmtFlags looks for a comment of the form
+//
+//	//gofmt flags
+//
+// within the first maxLines lines of the given file,
+// and returns the flags string, if any. Otherwise it
+// returns the empty string.
+func gofmtFlags(filename string, maxLines int) string {
+	f, err := os.Open(filename)
+	if err != nil {
+		return "" // ignore errors - they will be found later
+	}
+	defer f.Close()
+
+	// initialize scanner
+	var s scanner.Scanner
+	s.Init(f)
+	s.Error = func(*scanner.Scanner, string) {}       // ignore errors
+	s.Mode = scanner.GoTokens &^ scanner.SkipComments // want comments
+
+	// look for //gofmt comment
+	for s.Line <= maxLines {
+		switch s.Scan() {
+		case scanner.Comment:
+			const prefix = "//gofmt "
+			if t := s.TokenText(); strings.HasPrefix(t, prefix) {
+				return strings.TrimSpace(t[len(prefix):])
+			}
+		case scanner.EOF:
+			return ""
+		}
+
+	}
+
+	return ""
+}
+
+func runTest(t *testing.T, in, out string) {
 	// process flags
 	*simplifyAST = false
 	*rewriteRule = ""
 	stdin := false
-	for _, flag := range strings.Split(flags, " ") {
+	for _, flag := range strings.Split(gofmtFlags(in, 20), " ") {
 		elts := strings.SplitN(flag, "=", 2)
 		name := elts[0]
 		value := ""
@@ -56,6 +98,17 @@ func runTest(t *testing.T, in, out, flags string) {
 	}
 
 	if got := buf.Bytes(); !bytes.Equal(got, expected) {
+		if *update {
+			if in != out {
+				if err := ioutil.WriteFile(out, got, 0666); err != nil {
+					t.Error(err)
+				}
+				return
+			}
+			// in == out: don't accidentally destroy input
+			t.Errorf("WARNING: -update did not rewrite input file %s", in)
+		}
+
 		t.Errorf("(gofmt %s) != %s (see %s.gofmt)", in, out, in)
 		d, err := diff(expected, got)
 		if err == nil {
@@ -67,51 +120,37 @@ func runTest(t *testing.T, in, out, flags string) {
 	}
 }
 
-var tests = []struct {
-	in, flags string
-}{
-	{"gofmt.go", ""},
-	{"gofmt_test.go", ""},
-	{"testdata/composites.input", "-s"},
-	{"testdata/slices1.input", "-s"},
-	{"testdata/slices2.input", "-s"},
-	{"testdata/old.input", ""},
-	{"testdata/rewrite1.input", "-r=Foo->Bar"},
-	{"testdata/rewrite2.input", "-r=int->bool"},
-	{"testdata/rewrite3.input", "-r=x->x"},
-	{"testdata/rewrite4.input", "-r=(x)->x"},
-	{"testdata/rewrite5.input", "-r=x+x->2*x"},
-	{"testdata/rewrite6.input", "-r=fun(x)->Fun(x)"},
-	{"testdata/rewrite7.input", "-r=fun(x...)->Fun(x)"},
-	{"testdata/rewrite8.input", "-r=interface{}->int"},
-	{"testdata/stdin*.input", "-stdin"},
-	{"testdata/comments.input", ""},
-	{"testdata/import.input", ""},
-	{"testdata/crlf.input", ""},       // test case for issue 3961; see also TestCRLF
-	{"testdata/typeswitch.input", ""}, // test case for issue 4470
-}
-
+// TestRewrite processes testdata/*.input files and compares them to the
+// corresponding testdata/*.golden files. The gofmt flags used to process
+// a file must be provided via a comment of the form
+//
+//	//gofmt flags
+//
+// in the processed file within the first 20 lines, if any.
 func TestRewrite(t *testing.T) {
-	for _, test := range tests {
-		match, err := filepath.Glob(test.in)
-		if err != nil {
-			t.Error(err)
-			continue
+	// determine input files
+	match, err := filepath.Glob("testdata/*.input")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	// add larger examples
+	match = append(match, "gofmt.go", "gofmt_test.go")
+
+	for _, in := range match {
+		out := in // for files where input and output are identical
+		if strings.HasSuffix(in, ".input") {
+			out = in[:len(in)-len(".input")] + ".golden"
 		}
-		for _, in := range match {
-			out := in
-			if strings.HasSuffix(in, ".input") {
-				out = in[:len(in)-len(".input")] + ".golden"
-			}
-			runTest(t, in, out, test.flags)
-			if in != out {
-				// Check idempotence.
-				runTest(t, out, out, test.flags)
-			}
+		runTest(t, in, out)
+		if in != out {
+			// Check idempotence.
+			runTest(t, out, out)
 		}
 	}
 }
 
+// Test case for issue 3961.
 func TestCRLF(t *testing.T) {
 	const input = "testdata/crlf.input"   // must contain CR/LF's
 	const golden = "testdata/crlf.golden" // must not contain any CR's
diff --git a/src/cmd/gofmt/long_test.go b/src/cmd/gofmt/long_test.go
index 108278b..237b860 100644
--- a/src/cmd/gofmt/long_test.go
+++ b/src/cmd/gofmt/long_test.go
@@ -32,7 +32,7 @@ var (
 )
 
 func gofmt(fset *token.FileSet, filename string, src *bytes.Buffer) error {
-	f, _, err := parse(fset, filename, src.Bytes(), false)
+	f, _, _, err := parse(fset, filename, src.Bytes(), false)
 	if err != nil {
 		return err
 	}
@@ -60,7 +60,7 @@ func testFile(t *testing.T, b1, b2 *bytes.Buffer, filename string) {
 
 	// exclude files w/ syntax errors (typically test cases)
 	fset := token.NewFileSet()
-	if _, _, err = parse(fset, filename, b1.Bytes(), false); err != nil {
+	if _, _, _, err = parse(fset, filename, b1.Bytes(), false); err != nil {
 		if *verbose {
 			fmt.Fprintf(os.Stderr, "ignoring %s\n", err)
 		}
diff --git a/src/cmd/gofmt/rewrite.go b/src/cmd/gofmt/rewrite.go
index fb6c6fc..d267cfc 100644
--- a/src/cmd/gofmt/rewrite.go
+++ b/src/cmd/gofmt/rewrite.go
@@ -226,9 +226,6 @@ func match(m map[string]reflect.Value, pattern, val reflect.Value) bool {
 		return true
 
 	case reflect.Struct:
-		if p.NumField() != v.NumField() {
-			return false
-		}
 		for i := 0; i < p.NumField(); i++ {
 			if !match(m, p.Field(i), v.Field(i)) {
 				return false
diff --git a/src/cmd/gofmt/simplify.go b/src/cmd/gofmt/simplify.go
index 45d000d..69f7bf2 100644
--- a/src/cmd/gofmt/simplify.go
+++ b/src/cmd/gofmt/simplify.go
@@ -68,9 +68,10 @@ func (s *simplifier) Visit(node ast.Node) ast.Visitor {
 		// a slice expression of the form: s[a:len(s)]
 		// can be simplified to: s[a:]
 		// if s is "simple enough" (for now we only accept identifiers)
-		if s.hasDotImport {
-			// if dot imports are present, we cannot be certain that an
-			// unresolved "len" identifier refers to the predefined len()
+		if n.Max != nil || s.hasDotImport {
+			// - 3-index slices always require the 2nd and 3rd index
+			// - if dot imports are present, we cannot be certain that an
+			//   unresolved "len" identifier refers to the predefined len()
 			break
 		}
 		if s, _ := n.X.(*ast.Ident); s != nil && s.Obj != nil {
@@ -96,16 +97,26 @@ func (s *simplifier) Visit(node ast.Node) ast.Visitor {
 		//       x, y := b[:n], b[n:]
 
 	case *ast.RangeStmt:
-		// a range of the form: for x, _ = range v {...}
+		// - a range of the form: for x, _ = range v {...}
 		// can be simplified to: for x = range v {...}
-		if ident, _ := n.Value.(*ast.Ident); ident != nil && ident.Name == "_" {
+		// - a range of the form: for _ = range v {...}
+		// can be simplified to: for range v {...}
+		if isBlank(n.Value) {
 			n.Value = nil
 		}
+		if isBlank(n.Key) && n.Value == nil {
+			n.Key = nil
+		}
 	}
 
 	return s
 }
 
+func isBlank(x ast.Expr) bool {
+	ident, ok := x.(*ast.Ident)
+	return ok && ident.Name == "_"
+}
+
 func simplify(f *ast.File) {
 	var s simplifier
 
@@ -117,5 +128,34 @@ func simplify(f *ast.File) {
 		}
 	}
 
+	// remove empty declarations such as "const ()", etc
+	removeEmptyDeclGroups(f)
+
 	ast.Walk(&s, f)
 }
+
+func removeEmptyDeclGroups(f *ast.File) {
+	i := 0
+	for _, d := range f.Decls {
+		if g, ok := d.(*ast.GenDecl); !ok || !isEmpty(f, g) {
+			f.Decls[i] = d
+			i++
+		}
+	}
+	f.Decls = f.Decls[:i]
+}
+
+func isEmpty(f *ast.File, g *ast.GenDecl) bool {
+	if g.Doc != nil || g.Specs != nil {
+		return false
+	}
+
+	for _, c := range f.Comments {
+		// if there is a comment in the declaration, it is not considered empty
+		if g.Pos() <= c.Pos() && c.End() <= g.End() {
+			return false
+		}
+	}
+
+	return true
+}
diff --git a/src/cmd/gofmt/testdata/composites.golden b/src/cmd/gofmt/testdata/composites.golden
index b2825e7..fc9c98e 100644
--- a/src/cmd/gofmt/testdata/composites.golden
+++ b/src/cmd/gofmt/testdata/composites.golden
@@ -1,3 +1,5 @@
+//gofmt -s
+
 package P
 
 type T struct {
diff --git a/src/cmd/gofmt/testdata/composites.input b/src/cmd/gofmt/testdata/composites.input
index 7210daf..fc7598a 100644
--- a/src/cmd/gofmt/testdata/composites.input
+++ b/src/cmd/gofmt/testdata/composites.input
@@ -1,3 +1,5 @@
+//gofmt -s
+
 package P
 
 type T struct {
diff --git a/src/cmd/gofmt/testdata/crlf.golden b/src/cmd/gofmt/testdata/crlf.golden
index 57679f7..193dbac 100644
--- a/src/cmd/gofmt/testdata/crlf.golden
+++ b/src/cmd/gofmt/testdata/crlf.golden
@@ -2,6 +2,7 @@
 	Source containing CR/LF line endings.
 	The gofmt'ed output must only have LF
 	line endings.
+	Test case for issue 3961.
 */
 package main
 
diff --git a/src/cmd/gofmt/testdata/crlf.input b/src/cmd/gofmt/testdata/crlf.input
index 61a1aa0..ae7e14d 100644
--- a/src/cmd/gofmt/testdata/crlf.input
+++ b/src/cmd/gofmt/testdata/crlf.input
@@ -2,6 +2,7 @@
 	Source containing CR/LF line endings.
 	The gofmt'ed output must only have LF
 	line endings.
+	Test case for issue 3961.
 */
 package main
 
diff --git a/src/cmd/gofmt/testdata/emptydecl.golden b/src/cmd/gofmt/testdata/emptydecl.golden
new file mode 100644
index 0000000..33d6435
--- /dev/null
+++ b/src/cmd/gofmt/testdata/emptydecl.golden
@@ -0,0 +1,14 @@
+//gofmt -s
+
+// Test case for issue 7631.
+
+package main
+
+// Keep this declaration
+var ()
+
+const (
+// Keep this declaration
+)
+
+func main() {}
diff --git a/src/cmd/gofmt/testdata/emptydecl.input b/src/cmd/gofmt/testdata/emptydecl.input
new file mode 100644
index 0000000..4948a61
--- /dev/null
+++ b/src/cmd/gofmt/testdata/emptydecl.input
@@ -0,0 +1,16 @@
+//gofmt -s
+
+// Test case for issue 7631.
+
+package main
+
+// Keep this declaration
+var ()
+
+const (
+// Keep this declaration
+)
+
+type ()
+
+func main() {}
\ No newline at end of file
diff --git a/src/cmd/gofmt/testdata/ranges.golden b/src/cmd/gofmt/testdata/ranges.golden
new file mode 100644
index 0000000..506b3a0
--- /dev/null
+++ b/src/cmd/gofmt/testdata/ranges.golden
@@ -0,0 +1,30 @@
+//gofmt -s
+
+// Test cases for range simplification.
+package p
+
+func _() {
+	for a, b = range x {
+	}
+	for a = range x {
+	}
+	for _, b = range x {
+	}
+	for range x {
+	}
+
+	for a = range x {
+	}
+	for range x {
+	}
+
+	for a, b := range x {
+	}
+	for a := range x {
+	}
+	for _, b := range x {
+	}
+
+	for a := range x {
+	}
+}
diff --git a/src/cmd/gofmt/testdata/ranges.input b/src/cmd/gofmt/testdata/ranges.input
new file mode 100644
index 0000000..df5f833
--- /dev/null
+++ b/src/cmd/gofmt/testdata/ranges.input
@@ -0,0 +1,20 @@
+//gofmt -s
+
+// Test cases for range simplification.
+package p
+
+func _() {
+	for a, b = range x {}
+	for a, _ = range x {}
+	for _, b = range x {}
+	for _, _ = range x {}
+
+	for a = range x {}
+	for _ = range x {}
+
+	for a, b := range x {}
+	for a, _ := range x {}
+	for _, b := range x {}
+
+	for a := range x {}
+}
diff --git a/src/cmd/gofmt/testdata/rewrite1.golden b/src/cmd/gofmt/testdata/rewrite1.golden
index d9beb37..3ee5373 100644
--- a/src/cmd/gofmt/testdata/rewrite1.golden
+++ b/src/cmd/gofmt/testdata/rewrite1.golden
@@ -1,3 +1,5 @@
+//gofmt -r=Foo->Bar
+
 // Copyright 2011 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
diff --git a/src/cmd/gofmt/testdata/rewrite1.input b/src/cmd/gofmt/testdata/rewrite1.input
index bdb8943..a84c8f7 100644
--- a/src/cmd/gofmt/testdata/rewrite1.input
+++ b/src/cmd/gofmt/testdata/rewrite1.input
@@ -1,3 +1,5 @@
+//gofmt -r=Foo->Bar
+
 // Copyright 2011 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
diff --git a/src/cmd/gofmt/testdata/rewrite2.golden b/src/cmd/gofmt/testdata/rewrite2.golden
index 64c67ff..f980e03 100644
--- a/src/cmd/gofmt/testdata/rewrite2.golden
+++ b/src/cmd/gofmt/testdata/rewrite2.golden
@@ -1,3 +1,5 @@
+//gofmt -r=int->bool
+
 // Copyright 2011 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
diff --git a/src/cmd/gofmt/testdata/rewrite2.input b/src/cmd/gofmt/testdata/rewrite2.input
index 2117144..489be4e 100644
--- a/src/cmd/gofmt/testdata/rewrite2.input
+++ b/src/cmd/gofmt/testdata/rewrite2.input
@@ -1,3 +1,5 @@
+//gofmt -r=int->bool
+
 // Copyright 2011 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
diff --git a/src/cmd/gofmt/testdata/rewrite3.golden b/src/cmd/gofmt/testdata/rewrite3.golden
index 0d16d16..261a220 100644
--- a/src/cmd/gofmt/testdata/rewrite3.golden
+++ b/src/cmd/gofmt/testdata/rewrite3.golden
@@ -1,3 +1,5 @@
+//gofmt -r=x->x
+
 // Copyright 2011 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
diff --git a/src/cmd/gofmt/testdata/rewrite3.input b/src/cmd/gofmt/testdata/rewrite3.input
index 0d16d16..261a220 100644
--- a/src/cmd/gofmt/testdata/rewrite3.input
+++ b/src/cmd/gofmt/testdata/rewrite3.input
@@ -1,3 +1,5 @@
+//gofmt -r=x->x
+
 // Copyright 2011 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
diff --git a/src/cmd/gofmt/testdata/rewrite4.golden b/src/cmd/gofmt/testdata/rewrite4.golden
index 8dfc81a..b05547b 100644
--- a/src/cmd/gofmt/testdata/rewrite4.golden
+++ b/src/cmd/gofmt/testdata/rewrite4.golden
@@ -1,3 +1,5 @@
+//gofmt -r=(x)->x
+
 // Copyright 2012 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
diff --git a/src/cmd/gofmt/testdata/rewrite4.input b/src/cmd/gofmt/testdata/rewrite4.input
index 164cc04..0817099 100644
--- a/src/cmd/gofmt/testdata/rewrite4.input
+++ b/src/cmd/gofmt/testdata/rewrite4.input
@@ -1,3 +1,5 @@
+//gofmt -r=(x)->x
+
 // Copyright 2012 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
diff --git a/src/cmd/gofmt/testdata/rewrite5.golden b/src/cmd/gofmt/testdata/rewrite5.golden
index 5a448a6..9beb34a 100644
--- a/src/cmd/gofmt/testdata/rewrite5.golden
+++ b/src/cmd/gofmt/testdata/rewrite5.golden
@@ -1,3 +1,5 @@
+//gofmt -r=x+x->2*x
+
 // Copyright 2011 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
diff --git a/src/cmd/gofmt/testdata/rewrite5.input b/src/cmd/gofmt/testdata/rewrite5.input
index 0d759e6..d7a6122 100644
--- a/src/cmd/gofmt/testdata/rewrite5.input
+++ b/src/cmd/gofmt/testdata/rewrite5.input
@@ -1,3 +1,5 @@
+//gofmt -r=x+x->2*x
+
 // Copyright 2011 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
diff --git a/src/cmd/gofmt/testdata/rewrite6.golden b/src/cmd/gofmt/testdata/rewrite6.golden
index e565dbd..48ec9aa 100644
--- a/src/cmd/gofmt/testdata/rewrite6.golden
+++ b/src/cmd/gofmt/testdata/rewrite6.golden
@@ -1,3 +1,5 @@
+//gofmt -r=fun(x)->Fun(x)
+
 // Copyright 2013 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
diff --git a/src/cmd/gofmt/testdata/rewrite6.input b/src/cmd/gofmt/testdata/rewrite6.input
index 8c088b3..b085a84 100644
--- a/src/cmd/gofmt/testdata/rewrite6.input
+++ b/src/cmd/gofmt/testdata/rewrite6.input
@@ -1,3 +1,5 @@
+//gofmt -r=fun(x)->Fun(x)
+
 // Copyright 2013 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
diff --git a/src/cmd/gofmt/testdata/rewrite7.golden b/src/cmd/gofmt/testdata/rewrite7.golden
index 29babad..8386a0b 100644
--- a/src/cmd/gofmt/testdata/rewrite7.golden
+++ b/src/cmd/gofmt/testdata/rewrite7.golden
@@ -1,3 +1,5 @@
+//gofmt -r=fun(x...)->Fun(x)
+
 // Copyright 2013 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
diff --git a/src/cmd/gofmt/testdata/rewrite7.input b/src/cmd/gofmt/testdata/rewrite7.input
index 073e2a3..c198470 100644
--- a/src/cmd/gofmt/testdata/rewrite7.input
+++ b/src/cmd/gofmt/testdata/rewrite7.input
@@ -1,3 +1,5 @@
+//gofmt -r=fun(x...)->Fun(x)
+
 // Copyright 2013 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
diff --git a/src/cmd/gofmt/testdata/rewrite8.golden b/src/cmd/gofmt/testdata/rewrite8.golden
index cfc452b..62f0419 100644
--- a/src/cmd/gofmt/testdata/rewrite8.golden
+++ b/src/cmd/gofmt/testdata/rewrite8.golden
@@ -1,3 +1,5 @@
+//gofmt -r=interface{}->int
+
 // Copyright 2013 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
diff --git a/src/cmd/gofmt/testdata/rewrite8.input b/src/cmd/gofmt/testdata/rewrite8.input
index 235efa9..7964c5c 100644
--- a/src/cmd/gofmt/testdata/rewrite8.input
+++ b/src/cmd/gofmt/testdata/rewrite8.input
@@ -1,3 +1,5 @@
+//gofmt -r=interface{}->int
+
 // Copyright 2013 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
diff --git a/src/cmd/gofmt/testdata/slices1.golden b/src/cmd/gofmt/testdata/slices1.golden
index 61e074f..04bc16f 100644
--- a/src/cmd/gofmt/testdata/slices1.golden
+++ b/src/cmd/gofmt/testdata/slices1.golden
@@ -1,3 +1,5 @@
+//gofmt -s
+
 // Test cases for slice expression simplification.
 package p
 
@@ -15,6 +17,7 @@ var (
 	_ = a[3:(len(a))]
 	_ = a[len(a) : len(a)-1]
 	_ = a[0:len(b)]
+	_ = a[2:len(a):len(a)]
 
 	_ = a[:]
 	_ = a[:10]
@@ -22,6 +25,7 @@ var (
 	_ = a[:(len(a))]
 	_ = a[:len(a)-1]
 	_ = a[:len(b)]
+	_ = a[:len(a):len(a)]
 
 	_ = s[0:]
 	_ = s[1:10]
@@ -29,6 +33,7 @@ var (
 	_ = s[3:(len(s))]
 	_ = s[len(a) : len(s)-1]
 	_ = s[0:len(b)]
+	_ = s[2:len(s):len(s)]
 
 	_ = s[:]
 	_ = s[:10]
@@ -36,6 +41,7 @@ var (
 	_ = s[:(len(s))]
 	_ = s[:len(s)-1]
 	_ = s[:len(b)]
+	_ = s[:len(s):len(s)]
 
 	_ = t.s[0:]
 	_ = t.s[1:10]
@@ -43,6 +49,7 @@ var (
 	_ = t.s[3:(len(t.s))]
 	_ = t.s[len(a) : len(t.s)-1]
 	_ = t.s[0:len(b)]
+	_ = t.s[2:len(t.s):len(t.s)]
 
 	_ = t.s[:]
 	_ = t.s[:10]
@@ -50,6 +57,7 @@ var (
 	_ = t.s[:(len(t.s))]
 	_ = t.s[:len(t.s)-1]
 	_ = t.s[:len(b)]
+	_ = t.s[:len(t.s):len(t.s)]
 )
 
 func _() {
diff --git a/src/cmd/gofmt/testdata/slices1.input b/src/cmd/gofmt/testdata/slices1.input
index 4d2cbff..1f25c43 100644
--- a/src/cmd/gofmt/testdata/slices1.input
+++ b/src/cmd/gofmt/testdata/slices1.input
@@ -1,3 +1,5 @@
+//gofmt -s
+
 // Test cases for slice expression simplification.
 package p
 
@@ -15,6 +17,7 @@ var (
 	_ = a[3:(len(a))]
 	_ = a[len(a) : len(a)-1]
 	_ = a[0:len(b)]
+	_ = a[2:len(a):len(a)]
 
 	_ = a[:]
 	_ = a[:10]
@@ -22,6 +25,7 @@ var (
 	_ = a[:(len(a))]
 	_ = a[:len(a)-1]
 	_ = a[:len(b)]
+	_ = a[:len(a):len(a)]
 
 	_ = s[0:]
 	_ = s[1:10]
@@ -29,6 +33,7 @@ var (
 	_ = s[3:(len(s))]
 	_ = s[len(a) : len(s)-1]
 	_ = s[0:len(b)]
+	_ = s[2:len(s):len(s)]
 
 	_ = s[:]
 	_ = s[:10]
@@ -36,6 +41,7 @@ var (
 	_ = s[:(len(s))]
 	_ = s[:len(s)-1]
 	_ = s[:len(b)]
+	_ = s[:len(s):len(s)]
 
 	_ = t.s[0:]
 	_ = t.s[1:10]
@@ -43,6 +49,7 @@ var (
 	_ = t.s[3:(len(t.s))]
 	_ = t.s[len(a) : len(t.s)-1]
 	_ = t.s[0:len(b)]
+	_ = t.s[2:len(t.s):len(t.s)]
 
 	_ = t.s[:]
 	_ = t.s[:10]
@@ -50,6 +57,7 @@ var (
 	_ = t.s[:(len(t.s))]
 	_ = t.s[:len(t.s)-1]
 	_ = t.s[:len(b)]
+	_ = t.s[:len(t.s):len(t.s)]
 )
 
 func _() {
diff --git a/src/cmd/gofmt/testdata/slices2.golden b/src/cmd/gofmt/testdata/slices2.golden
index 433788e..ab65700 100644
--- a/src/cmd/gofmt/testdata/slices2.golden
+++ b/src/cmd/gofmt/testdata/slices2.golden
@@ -1,3 +1,5 @@
+//gofmt -s
+
 // Test cases for slice expression simplification.
 // Because of a dot import, these slices must remain untouched.
 package p
diff --git a/src/cmd/gofmt/testdata/slices2.input b/src/cmd/gofmt/testdata/slices2.input
index 433788e..ab65700 100644
--- a/src/cmd/gofmt/testdata/slices2.input
+++ b/src/cmd/gofmt/testdata/slices2.input
@@ -1,3 +1,5 @@
+//gofmt -s
+
 // Test cases for slice expression simplification.
 // Because of a dot import, these slices must remain untouched.
 package p
diff --git a/src/cmd/gofmt/testdata/stdin1.golden b/src/cmd/gofmt/testdata/stdin1.golden
index ff8b0b7..9e4dcd2 100644
--- a/src/cmd/gofmt/testdata/stdin1.golden
+++ b/src/cmd/gofmt/testdata/stdin1.golden
@@ -1,3 +1,5 @@
+	//gofmt -stdin
+
 	if x {
 		y
 	}
diff --git a/src/cmd/gofmt/testdata/stdin1.golden.gofmt b/src/cmd/gofmt/testdata/stdin1.golden.gofmt
deleted file mode 100644
index 1f88887..0000000
--- a/src/cmd/gofmt/testdata/stdin1.golden.gofmt
+++ /dev/null
@@ -1,3 +0,0 @@
-	if x {
-	y
-}
diff --git a/src/cmd/gofmt/testdata/stdin1.input b/src/cmd/gofmt/testdata/stdin1.input
index ff8b0b7..9e4dcd2 100644
--- a/src/cmd/gofmt/testdata/stdin1.input
+++ b/src/cmd/gofmt/testdata/stdin1.input
@@ -1,3 +1,5 @@
+	//gofmt -stdin
+
 	if x {
 		y
 	}
diff --git a/src/cmd/gofmt/testdata/stdin1.input.gofmt b/src/cmd/gofmt/testdata/stdin1.input.gofmt
deleted file mode 100644
index 1f88887..0000000
--- a/src/cmd/gofmt/testdata/stdin1.input.gofmt
+++ /dev/null
@@ -1,3 +0,0 @@
-	if x {
-	y
-}
diff --git a/src/cmd/gofmt/testdata/stdin2.golden b/src/cmd/gofmt/testdata/stdin2.golden
index 7eb1b54..57df355 100644
--- a/src/cmd/gofmt/testdata/stdin2.golden
+++ b/src/cmd/gofmt/testdata/stdin2.golden
@@ -1,4 +1,4 @@
-
+//gofmt -stdin
 
 var x int
 
diff --git a/src/cmd/gofmt/testdata/stdin2.golden.gofmt b/src/cmd/gofmt/testdata/stdin2.golden.gofmt
deleted file mode 100644
index 85e8003..0000000
--- a/src/cmd/gofmt/testdata/stdin2.golden.gofmt
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-var x int
-
-func f() {
-	y := z
-}
-
-
diff --git a/src/cmd/gofmt/testdata/stdin2.input b/src/cmd/gofmt/testdata/stdin2.input
index 99defd2..69d6bdd 100644
--- a/src/cmd/gofmt/testdata/stdin2.input
+++ b/src/cmd/gofmt/testdata/stdin2.input
@@ -1,4 +1,4 @@
-
+//gofmt -stdin
 
 var x int
 
diff --git a/src/cmd/gofmt/testdata/stdin2.input.gofmt b/src/cmd/gofmt/testdata/stdin2.input.gofmt
deleted file mode 100644
index 7eb1b54..0000000
--- a/src/cmd/gofmt/testdata/stdin2.input.gofmt
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-var x int
-
-func f() {
-	y := z
-	/* this is a comment */
-	// this is a comment too
-}
-
-
diff --git a/src/cmd/gofmt/testdata/stdin3.golden b/src/cmd/gofmt/testdata/stdin3.golden
index 1bf2f5a..d6da0e4 100644
--- a/src/cmd/gofmt/testdata/stdin3.golden
+++ b/src/cmd/gofmt/testdata/stdin3.golden
@@ -1,3 +1,4 @@
+		//gofmt -stdin
 
 		/* note: no newline at end of file */
 		for i := 0; i < 10; i++ {
diff --git a/src/cmd/gofmt/testdata/stdin3.golden.gofmt b/src/cmd/gofmt/testdata/stdin3.golden.gofmt
deleted file mode 100644
index b4d1d46..0000000
--- a/src/cmd/gofmt/testdata/stdin3.golden.gofmt
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-		/* note: no newline at end of file */
-		for i := 0; i < 10; i++ {
-			s += i
-		}
-	
\ No newline at end of file
diff --git a/src/cmd/gofmt/testdata/stdin3.input b/src/cmd/gofmt/testdata/stdin3.input
index d963bd0..ab46c10 100644
--- a/src/cmd/gofmt/testdata/stdin3.input
+++ b/src/cmd/gofmt/testdata/stdin3.input
@@ -1,3 +1,4 @@
+		//gofmt -stdin
 
 		/* note: no newline at end of file */
 		for i := 0; i < 10; i++ { s += i }
diff --git a/src/cmd/gofmt/testdata/stdin3.input.gofmt b/src/cmd/gofmt/testdata/stdin3.input.gofmt
deleted file mode 100644
index b4d1d46..0000000
--- a/src/cmd/gofmt/testdata/stdin3.input.gofmt
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-		/* note: no newline at end of file */
-		for i := 0; i < 10; i++ {
-			s += i
-		}
-	
\ No newline at end of file
diff --git a/src/cmd/gofmt/testdata/stdin4.golden b/src/cmd/gofmt/testdata/stdin4.golden
index 5f73435..0c7acac 100644
--- a/src/cmd/gofmt/testdata/stdin4.golden
+++ b/src/cmd/gofmt/testdata/stdin4.golden
@@ -1,3 +1,5 @@
+	//gofmt -stdin
+
 	// comment
 
 	i := 0
diff --git a/src/cmd/gofmt/testdata/stdin4.golden.gofmt b/src/cmd/gofmt/testdata/stdin4.golden.gofmt
deleted file mode 100644
index 5f73435..0000000
--- a/src/cmd/gofmt/testdata/stdin4.golden.gofmt
+++ /dev/null
@@ -1,3 +0,0 @@
-	// comment
-
-	i := 0
diff --git a/src/cmd/gofmt/testdata/stdin4.input b/src/cmd/gofmt/testdata/stdin4.input
index f02a54f..1fc73f3 100644
--- a/src/cmd/gofmt/testdata/stdin4.input
+++ b/src/cmd/gofmt/testdata/stdin4.input
@@ -1,3 +1,5 @@
+	//gofmt -stdin
+
 	// comment
 	
 	i := 0
diff --git a/src/cmd/gofmt/testdata/stdin4.input.gofmt b/src/cmd/gofmt/testdata/stdin4.input.gofmt
deleted file mode 100644
index 5f73435..0000000
--- a/src/cmd/gofmt/testdata/stdin4.input.gofmt
+++ /dev/null
@@ -1,3 +0,0 @@
-	// comment
-
-	i := 0
diff --git a/src/cmd/gofmt/testdata/stdin5.golden b/src/cmd/gofmt/testdata/stdin5.golden
new file mode 100644
index 0000000..31ce6b2
--- /dev/null
+++ b/src/cmd/gofmt/testdata/stdin5.golden
@@ -0,0 +1,3 @@
+//gofmt -stdin
+
+i := 5 // Line comment without newline.
\ No newline at end of file
diff --git a/src/cmd/gofmt/testdata/stdin5.input b/src/cmd/gofmt/testdata/stdin5.input
new file mode 100644
index 0000000..0a7c97d
--- /dev/null
+++ b/src/cmd/gofmt/testdata/stdin5.input
@@ -0,0 +1,3 @@
+//gofmt -stdin
+
+i  :=5// Line comment without newline.
\ No newline at end of file
diff --git a/src/cmd/gofmt/testdata/stdin6.golden b/src/cmd/gofmt/testdata/stdin6.golden
new file mode 100644
index 0000000..ffcea80
--- /dev/null
+++ b/src/cmd/gofmt/testdata/stdin6.golden
@@ -0,0 +1,19 @@
+	//gofmt -stdin
+
+	if err != nil {
+		source := strings.NewReader(`line 1.
+line 2.
+`)
+		return source
+	}
+
+	f := func(hat, tail string) {
+
+		fmt.Println(hat+`
+foo
+
+
+`+tail,
+			"more",
+			"and more")
+	}
diff --git a/src/cmd/gofmt/testdata/stdin6.input b/src/cmd/gofmt/testdata/stdin6.input
new file mode 100644
index 0000000..7833002
--- /dev/null
+++ b/src/cmd/gofmt/testdata/stdin6.input
@@ -0,0 +1,21 @@
+	//gofmt -stdin
+
+	if err != nil {
+		source := strings.NewReader(`line 1.
+line 2.
+`)
+		return source
+	}
+
+	f:=func(  hat, tail string){
+
+
+
+		   fmt.  Println  (   hat+   `
+foo
+
+
+`+ tail  ,
+ "more" ,
+		"and more"   )
+	}
diff --git a/src/cmd/gofmt/testdata/stdin7.golden b/src/cmd/gofmt/testdata/stdin7.golden
new file mode 100644
index 0000000..bbac713
--- /dev/null
+++ b/src/cmd/gofmt/testdata/stdin7.golden
@@ -0,0 +1,19 @@
+															//gofmt -stdin
+
+															if err != nil {
+																source := strings.NewReader(`line 1.
+line 2.
+`)
+																return source
+															}
+
+															f := func(hat, tail string) {
+
+																fmt.Println(hat+`
+		foo
+
+
+	`+tail,
+																	"more",
+																	"and more")
+															}
diff --git a/src/cmd/gofmt/testdata/stdin7.input b/src/cmd/gofmt/testdata/stdin7.input
new file mode 100644
index 0000000..fd772a3
--- /dev/null
+++ b/src/cmd/gofmt/testdata/stdin7.input
@@ -0,0 +1,21 @@
+															//gofmt -stdin
+
+															if err != nil {
+								source := strings.NewReader(`line 1.
+line 2.
+`)
+								return source
+							}
+
+							f:=func(  hat, tail string){
+
+
+
+								   fmt.  Println  (   hat+   `
+		foo
+
+
+	`+ tail  ,
+						 "more" ,
+								"and more"   )
+							}
diff --git a/src/cmd/internal/goobj/read.go b/src/cmd/internal/goobj/read.go
new file mode 100644
index 0000000..79a83e5
--- /dev/null
+++ b/src/cmd/internal/goobj/read.go
@@ -0,0 +1,666 @@
+// Copyright 2013 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package goobj implements reading of Go object files and archives.
+//
+// TODO(rsc): Decide where this package should live. (golang.org/issue/6932)
+// TODO(rsc): Decide the appropriate integer types for various fields.
+// TODO(rsc): Write tests. (File format still up in the air a little.)
+package goobj
+
+import (
+	"bufio"
+	"bytes"
+	"errors"
+	"fmt"
+	"io"
+	"strconv"
+	"strings"
+)
+
+// A SymKind describes the kind of memory represented by a symbol.
+type SymKind int
+
+// This list is taken from include/link.h.
+
+// Defined SymKind values.
+// TODO(rsc): Give idiomatic Go names.
+// TODO(rsc): Reduce the number of symbol types in the object files.
+const (
+	_ SymKind = iota
+
+	// readonly, executable
+	STEXT
+	SELFRXSECT
+
+	// readonly, non-executable
+	STYPE
+	SSTRING
+	SGOSTRING
+	SGOFUNC
+	SRODATA
+	SFUNCTAB
+	STYPELINK
+	SSYMTAB // TODO: move to unmapped section
+	SPCLNTAB
+	SELFROSECT
+
+	// writable, non-executable
+	SMACHOPLT
+	SELFSECT
+	SMACHO // Mach-O __nl_symbol_ptr
+	SMACHOGOT
+	SNOPTRDATA
+	SINITARR
+	SDATA
+	SWINDOWS
+	SBSS
+	SNOPTRBSS
+	STLSBSS
+
+	// not mapped
+	SXREF
+	SMACHOSYMSTR
+	SMACHOSYMTAB
+	SMACHOINDIRECTPLT
+	SMACHOINDIRECTGOT
+	SFILE
+	SFILEPATH
+	SCONST
+	SDYNIMPORT
+	SHOSTOBJ
+)
+
+var symKindStrings = []string{
+	SBSS:              "SBSS",
+	SCONST:            "SCONST",
+	SDATA:             "SDATA",
+	SDYNIMPORT:        "SDYNIMPORT",
+	SELFROSECT:        "SELFROSECT",
+	SELFRXSECT:        "SELFRXSECT",
+	SELFSECT:          "SELFSECT",
+	SFILE:             "SFILE",
+	SFILEPATH:         "SFILEPATH",
+	SFUNCTAB:          "SFUNCTAB",
+	SGOFUNC:           "SGOFUNC",
+	SGOSTRING:         "SGOSTRING",
+	SHOSTOBJ:          "SHOSTOBJ",
+	SINITARR:          "SINITARR",
+	SMACHO:            "SMACHO",
+	SMACHOGOT:         "SMACHOGOT",
+	SMACHOINDIRECTGOT: "SMACHOINDIRECTGOT",
+	SMACHOINDIRECTPLT: "SMACHOINDIRECTPLT",
+	SMACHOPLT:         "SMACHOPLT",
+	SMACHOSYMSTR:      "SMACHOSYMSTR",
+	SMACHOSYMTAB:      "SMACHOSYMTAB",
+	SNOPTRBSS:         "SNOPTRBSS",
+	SNOPTRDATA:        "SNOPTRDATA",
+	SPCLNTAB:          "SPCLNTAB",
+	SRODATA:           "SRODATA",
+	SSTRING:           "SSTRING",
+	SSYMTAB:           "SSYMTAB",
+	STEXT:             "STEXT",
+	STLSBSS:           "STLSBSS",
+	STYPE:             "STYPE",
+	STYPELINK:         "STYPELINK",
+	SWINDOWS:          "SWINDOWS",
+	SXREF:             "SXREF",
+}
+
+func (k SymKind) String() string {
+	if k < 0 || int(k) >= len(symKindStrings) {
+		return fmt.Sprintf("SymKind(%d)", k)
+	}
+	return symKindStrings[k]
+}
+
+// A Sym is a named symbol in an object file.
+type Sym struct {
+	SymID         // symbol identifier (name and version)
+	Kind  SymKind // kind of symbol
+	DupOK bool    // are duplicate definitions okay?
+	Size  int     // size of corresponding data
+	Type  SymID   // symbol for Go type information
+	Data  Data    // memory image of symbol
+	Reloc []Reloc // relocations to apply to Data
+	Func  *Func   // additional data for functions
+}
+
+// A SymID - the combination of Name and Version - uniquely identifies
+// a symbol within a package.
+type SymID struct {
+	// Name is the name of a symbol.
+	Name string
+
+	// Version is zero for symbols with global visibility.
+	// Symbols with only file visibility (such as file-level static
+	// declarations in C) have a non-zero version distinguishing
+	// a symbol in one file from a symbol of the same name
+	// in another file
+	Version int
+}
+
+func (s SymID) String() string {
+	if s.Version == 0 {
+		return s.Name
+	}
+	return fmt.Sprintf("%s<%d>", s.Name, s.Version)
+}
+
+// A Data is a reference to data stored in an object file.
+// It records the offset and size of the data, so that a client can
+// read the data only if necessary.
+type Data struct {
+	Offset int64
+	Size   int64
+}
+
+// A Reloc describes a relocation applied to a memory image to refer
+// to an address within a particular symbol.
+type Reloc struct {
+	// The bytes at [Offset, Offset+Size) within the memory image
+	// should be updated to refer to the address Add bytes after the start
+	// of the symbol Sym.
+	Offset int
+	Size   int
+	Sym    SymID
+	Add    int
+
+	// The Type records the form of address expected in the bytes
+	// described by the previous fields: absolute, PC-relative, and so on.
+	// TODO(rsc): The interpretation of Type is not exposed by this package.
+	Type int
+}
+
+// A Var describes a variable in a function stack frame: a declared
+// local variable, an input argument, or an output result.
+type Var struct {
+	// The combination of Name, Kind, and Offset uniquely
+	// identifies a variable in a function stack frame.
+	// Using fewer of these - in particular, using only Name - does not.
+	Name   string // Name of variable.
+	Kind   int    // TODO(rsc): Define meaning.
+	Offset int    // Frame offset. TODO(rsc): Define meaning.
+
+	Type SymID // Go type for variable.
+}
+
+// Func contains additional per-symbol information specific to functions.
+type Func struct {
+	Args     int        // size in bytes of argument frame: inputs and outputs
+	Frame    int        // size in bytes of local variable frame
+	Leaf     bool       // function omits save of link register (ARM)
+	NoSplit  bool       // function omits stack split prologue
+	Var      []Var      // detail about local variables
+	PCSP     Data       // PC → SP offset map
+	PCFile   Data       // PC → file number map (index into File)
+	PCLine   Data       // PC → line number map
+	PCData   []Data     // PC → runtime support data map
+	FuncData []FuncData // non-PC-specific runtime support data
+	File     []string   // paths indexed by PCFile
+}
+
+// TODO: Add PCData []byte and PCDataIter (similar to liblink).
+
+// A FuncData is a single function-specific data value.
+type FuncData struct {
+	Sym    SymID // symbol holding data
+	Offset int64 // offset into symbol for funcdata pointer
+}
+
+// A Package is a parsed Go object file or archive defining a Go package.
+type Package struct {
+	ImportPath string   // import path denoting this package
+	Imports    []string // packages imported by this package
+	Syms       []*Sym   // symbols defined by this package
+	MaxVersion int      // maximum Version in any SymID in Syms
+}
+
+var (
+	archiveHeader = []byte("!<arch>\n")
+	archiveMagic  = []byte("`\n")
+	goobjHeader   = []byte("go objec") // truncated to size of archiveHeader
+
+	errCorruptArchive   = errors.New("corrupt archive")
+	errTruncatedArchive = errors.New("truncated archive")
+	errNotArchive       = errors.New("unrecognized archive format")
+
+	errCorruptObject   = errors.New("corrupt object file")
+	errTruncatedObject = errors.New("truncated object file")
+	errNotObject       = errors.New("unrecognized object file format")
+)
+
+// An objReader is an object file reader.
+type objReader struct {
+	p         *Package
+	b         *bufio.Reader
+	f         io.ReadSeeker
+	err       error
+	offset    int64
+	limit     int64
+	tmp       [256]byte
+	pkg       string
+	pkgprefix string
+}
+
+// importPathToPrefix returns the prefix that will be used in the
+// final symbol table for the given import path.
+// We escape '%', '"', all control characters and non-ASCII bytes,
+// and any '.' after the final slash.
+//
+// See ../../../cmd/ld/lib.c:/^pathtoprefix and
+// ../../../cmd/gc/subr.c:/^pathtoprefix.
+func importPathToPrefix(s string) string {
+	// find index of last slash, if any, or else -1.
+	// used for determining whether an index is after the last slash.
+	slash := strings.LastIndex(s, "/")
+
+	// check for chars that need escaping
+	n := 0
+	for r := 0; r < len(s); r++ {
+		if c := s[r]; c <= ' ' || (c == '.' && r > slash) || c == '%' || c == '"' || c >= 0x7F {
+			n++
+		}
+	}
+
+	// quick exit
+	if n == 0 {
+		return s
+	}
+
+	// escape
+	const hex = "0123456789abcdef"
+	p := make([]byte, 0, len(s)+2*n)
+	for r := 0; r < len(s); r++ {
+		if c := s[r]; c <= ' ' || (c == '.' && r > slash) || c == '%' || c == '"' || c >= 0x7F {
+			p = append(p, '%', hex[c>>4], hex[c&0xF])
+		} else {
+			p = append(p, c)
+		}
+	}
+
+	return string(p)
+}
+
+// init initializes r to read package p from f.
+func (r *objReader) init(f io.ReadSeeker, p *Package) {
+	r.f = f
+	r.p = p
+	r.offset, _ = f.Seek(0, 1)
+	r.limit, _ = f.Seek(0, 2)
+	f.Seek(r.offset, 0)
+	r.b = bufio.NewReader(f)
+	r.pkgprefix = importPathToPrefix(p.ImportPath) + "."
+}
+
+// error records that an error occurred.
+// It returns only the first error, so that an error
+// caused by an earlier error does not discard information
+// about the earlier error.
+func (r *objReader) error(err error) error {
+	if r.err == nil {
+		if err == io.EOF {
+			err = io.ErrUnexpectedEOF
+		}
+		r.err = err
+	}
+	// panic("corrupt") // useful for debugging
+	return r.err
+}
+
+// readByte reads and returns a byte from the input file.
+// On I/O error or EOF, it records the error but returns byte 0.
+// A sequence of 0 bytes will eventually terminate any
+// parsing state in the object file. In particular, it ends the
+// reading of a varint.
+func (r *objReader) readByte() byte {
+	if r.err != nil {
+		return 0
+	}
+	if r.offset >= r.limit {
+		r.error(io.ErrUnexpectedEOF)
+		return 0
+	}
+	b, err := r.b.ReadByte()
+	if err != nil {
+		if err == io.EOF {
+			err = io.ErrUnexpectedEOF
+		}
+		r.error(err)
+		b = 0
+	} else {
+		r.offset++
+	}
+	return b
+}
+
+// read reads exactly len(b) bytes from the input file.
+// If an error occurs, read returns the error but also
+// records it, so it is safe for callers to ignore the result
+// as long as delaying the report is not a problem.
+func (r *objReader) readFull(b []byte) error {
+	if r.err != nil {
+		return r.err
+	}
+	if r.offset+int64(len(b)) > r.limit {
+		return r.error(io.ErrUnexpectedEOF)
+	}
+	n, err := io.ReadFull(r.b, b)
+	r.offset += int64(n)
+	if err != nil {
+		return r.error(err)
+	}
+	return nil
+}
+
+// readInt reads a zigzag varint from the input file.
+func (r *objReader) readInt() int {
+	var u uint64
+
+	for shift := uint(0); ; shift += 7 {
+		if shift >= 64 {
+			r.error(errCorruptObject)
+			return 0
+		}
+		c := r.readByte()
+		u |= uint64(c&0x7F) << shift
+		if c&0x80 == 0 {
+			break
+		}
+	}
+
+	v := int64(u>>1) ^ (int64(u) << 63 >> 63)
+	if int64(int(v)) != v {
+		r.error(errCorruptObject) // TODO
+		return 0
+	}
+	return int(v)
+}
+
+// readString reads a length-delimited string from the input file.
+func (r *objReader) readString() string {
+	n := r.readInt()
+	buf := make([]byte, n)
+	r.readFull(buf)
+	return string(buf)
+}
+
+// readSymID reads a SymID from the input file.
+func (r *objReader) readSymID() SymID {
+	name, vers := r.readString(), r.readInt()
+
+	// In a symbol name in an object file, "". denotes the
+	// prefix for the package in which the object file has been found.
+	// Expand it.
+	name = strings.Replace(name, `"".`, r.pkgprefix, -1)
+
+	// An individual object file only records version 0 (extern) or 1 (static).
+	// To make static symbols unique across all files being read, we
+	// replace version 1 with the version corresponding to the current
+	// file number. The number is incremented on each call to parseObject.
+	if vers != 0 {
+		vers = r.p.MaxVersion
+	}
+
+	return SymID{name, vers}
+}
+
+// readData reads a data reference from the input file.
+func (r *objReader) readData() Data {
+	n := r.readInt()
+	d := Data{Offset: r.offset, Size: int64(n)}
+	r.skip(int64(n))
+	return d
+}
+
+// skip skips n bytes in the input.
+func (r *objReader) skip(n int64) {
+	if n < 0 {
+		r.error(fmt.Errorf("debug/goobj: internal error: misuse of skip"))
+	}
+	if n < int64(len(r.tmp)) {
+		// Since the data is so small, a just reading from the buffered
+		// reader is better than flushing the buffer and seeking.
+		r.readFull(r.tmp[:n])
+	} else if n <= int64(r.b.Buffered()) {
+		// Even though the data is not small, it has already been read.
+		// Advance the buffer instead of seeking.
+		for n > int64(len(r.tmp)) {
+			r.readFull(r.tmp[:])
+			n -= int64(len(r.tmp))
+		}
+		r.readFull(r.tmp[:n])
+	} else {
+		// Seek, giving up buffered data.
+		_, err := r.f.Seek(r.offset+n, 0)
+		if err != nil {
+			r.error(err)
+		}
+		r.offset += n
+		r.b.Reset(r.f)
+	}
+}
+
+// Parse parses an object file or archive from r,
+// assuming that its import path is pkgpath.
+func Parse(r io.ReadSeeker, pkgpath string) (*Package, error) {
+	if pkgpath == "" {
+		pkgpath = `""`
+	}
+	p := new(Package)
+	p.ImportPath = pkgpath
+
+	var rd objReader
+	rd.init(r, p)
+	err := rd.readFull(rd.tmp[:8])
+	if err != nil {
+		if err == io.EOF {
+			err = io.ErrUnexpectedEOF
+		}
+		return nil, err
+	}
+
+	switch {
+	default:
+		return nil, errNotObject
+
+	case bytes.Equal(rd.tmp[:8], archiveHeader):
+		if err := rd.parseArchive(); err != nil {
+			return nil, err
+		}
+	case bytes.Equal(rd.tmp[:8], goobjHeader):
+		if err := rd.parseObject(goobjHeader); err != nil {
+			return nil, err
+		}
+	}
+
+	return p, nil
+}
+
+// trimSpace removes trailing spaces from b and returns the corresponding string.
+// This effectively parses the form used in archive headers.
+func trimSpace(b []byte) string {
+	return string(bytes.TrimRight(b, " "))
+}
+
+// parseArchive parses a Unix archive of Go object files.
+// TODO(rsc): Need to skip non-Go object files.
+// TODO(rsc): Maybe record table of contents in r.p so that
+// linker can avoid having code to parse archives too.
+func (r *objReader) parseArchive() error {
+	for r.offset < r.limit {
+		if err := r.readFull(r.tmp[:60]); err != nil {
+			return err
+		}
+		data := r.tmp[:60]
+
+		// Each file is preceded by this text header (slice indices in first column):
+		//	 0:16	name
+		//	16:28 date
+		//	28:34 uid
+		//	34:40 gid
+		//	40:48 mode
+		//	48:58 size
+		//	58:60 magic - `\n
+		// We only care about name, size, and magic.
+		// The fields are space-padded on the right.
+		// The size is in decimal.
+		// The file data - size bytes - follows the header.
+		// Headers are 2-byte aligned, so if size is odd, an extra padding
+		// byte sits between the file data and the next header.
+		// The file data that follows is padded to an even number of bytes:
+		// if size is odd, an extra padding byte is inserted betw the next header.
+		if len(data) < 60 {
+			return errTruncatedArchive
+		}
+		if !bytes.Equal(data[58:60], archiveMagic) {
+			return errCorruptArchive
+		}
+		name := trimSpace(data[0:16])
+		size, err := strconv.ParseInt(trimSpace(data[48:58]), 10, 64)
+		if err != nil {
+			return errCorruptArchive
+		}
+		data = data[60:]
+		fsize := size + size&1
+		if fsize < 0 || fsize < size {
+			return errCorruptArchive
+		}
+		switch name {
+		case "__.SYMDEF", "__.GOSYMDEF", "__.PKGDEF":
+			r.skip(size)
+		default:
+			oldLimit := r.limit
+			r.limit = r.offset + size
+			if err := r.parseObject(nil); err != nil {
+				return fmt.Errorf("parsing archive member %q: %v", name, err)
+			}
+			r.skip(r.limit - r.offset)
+			r.limit = oldLimit
+		}
+		if size&1 != 0 {
+			r.skip(1)
+		}
+	}
+	return nil
+}
+
+// parseObject parses a single Go object file.
+// The prefix is the bytes already read from the file,
+// typically in order to detect that this is an object file.
+// The object file consists of a textual header ending in "\n!\n"
+// and then the part we want to parse begins.
+// The format of that part is defined in a comment at the top
+// of src/liblink/objfile.c.
+func (r *objReader) parseObject(prefix []byte) error {
+	// TODO(rsc): Maybe use prefix and the initial input to
+	// record the header line from the file, which would
+	// give the architecture and other version information.
+
+	r.p.MaxVersion++
+	var c1, c2, c3 byte
+	for {
+		c1, c2, c3 = c2, c3, r.readByte()
+		if c3 == 0 { // NUL or EOF, either is bad
+			return errCorruptObject
+		}
+		if c1 == '\n' && c2 == '!' && c3 == '\n' {
+			break
+		}
+	}
+
+	r.readFull(r.tmp[:8])
+	if !bytes.Equal(r.tmp[:8], []byte("\x00\x00go13ld")) {
+		return r.error(errCorruptObject)
+	}
+
+	b := r.readByte()
+	if b != 1 {
+		return r.error(errCorruptObject)
+	}
+
+	// Direct package dependencies.
+	for {
+		s := r.readString()
+		if s == "" {
+			break
+		}
+		r.p.Imports = append(r.p.Imports, s)
+	}
+
+	// Symbols.
+	for {
+		if b := r.readByte(); b != 0xfe {
+			if b != 0xff {
+				return r.error(errCorruptObject)
+			}
+			break
+		}
+
+		typ := r.readInt()
+		s := &Sym{SymID: r.readSymID()}
+		r.p.Syms = append(r.p.Syms, s)
+		s.Kind = SymKind(typ)
+		flags := r.readInt()
+		s.DupOK = flags&1 != 0
+		s.Size = r.readInt()
+		s.Type = r.readSymID()
+		s.Data = r.readData()
+		s.Reloc = make([]Reloc, r.readInt())
+		for i := range s.Reloc {
+			rel := &s.Reloc[i]
+			rel.Offset = r.readInt()
+			rel.Size = r.readInt()
+			rel.Type = r.readInt()
+			rel.Add = r.readInt()
+			r.readInt() // Xadd - ignored
+			rel.Sym = r.readSymID()
+			r.readSymID() // Xsym - ignored
+		}
+
+		if s.Kind == STEXT {
+			f := new(Func)
+			s.Func = f
+			f.Args = r.readInt()
+			f.Frame = r.readInt()
+			flags := r.readInt()
+			f.Leaf = flags&1 != 0
+			f.NoSplit = r.readInt() != 0
+			f.Var = make([]Var, r.readInt())
+			for i := range f.Var {
+				v := &f.Var[i]
+				v.Name = r.readSymID().Name
+				v.Offset = r.readInt()
+				v.Kind = r.readInt()
+				v.Type = r.readSymID()
+			}
+
+			f.PCSP = r.readData()
+			f.PCFile = r.readData()
+			f.PCLine = r.readData()
+			f.PCData = make([]Data, r.readInt())
+			for i := range f.PCData {
+				f.PCData[i] = r.readData()
+			}
+			f.FuncData = make([]FuncData, r.readInt())
+			for i := range f.FuncData {
+				f.FuncData[i].Sym = r.readSymID()
+			}
+			for i := range f.FuncData {
+				f.FuncData[i].Offset = int64(r.readInt()) // TODO
+			}
+			f.File = make([]string, r.readInt())
+			for i := range f.File {
+				f.File[i] = r.readSymID().Name
+			}
+		}
+	}
+
+	r.readFull(r.tmp[:7])
+	if !bytes.Equal(r.tmp[:7], []byte("\xffgo13ld")) {
+		return r.error(errCorruptObject)
+	}
+
+	return nil
+}
diff --git a/src/cmd/internal/goobj/read_test.go b/src/cmd/internal/goobj/read_test.go
new file mode 100644
index 0000000..cc991e5
--- /dev/null
+++ b/src/cmd/internal/goobj/read_test.go
@@ -0,0 +1,28 @@
+// Copyright 2013 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package goobj
+
+import "testing"
+
+var importPathToPrefixTests = []struct {
+	in  string
+	out string
+}{
+	{"runtime", "runtime"},
+	{"sync/atomic", "sync/atomic"},
+	{"golang.org/x/tools/godoc", "golang.org/x/tools/godoc"},
+	{"foo.bar/baz.quux", "foo.bar/baz%2equux"},
+	{"", ""},
+	{"%foo%bar", "%25foo%25bar"},
+	{"\x01\x00\x7F☺", "%01%00%7f%e2%98%ba"},
+}
+
+func TestImportPathToPrefix(t *testing.T) {
+	for _, tt := range importPathToPrefixTests {
+		if out := importPathToPrefix(tt.in); out != tt.out {
+			t.Errorf("importPathToPrefix(%q) = %q, want %q", tt.in, out, tt.out)
+		}
+	}
+}
diff --git a/src/cmd/internal/objfile/disasm.go b/src/cmd/internal/objfile/disasm.go
new file mode 100644
index 0000000..1a339c3
--- /dev/null
+++ b/src/cmd/internal/objfile/disasm.go
@@ -0,0 +1,248 @@
+// 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 objfile
+
+import (
+	"bufio"
+	"debug/gosym"
+	"encoding/binary"
+	"fmt"
+	"io"
+	"regexp"
+	"sort"
+	"strings"
+	"text/tabwriter"
+
+	"cmd/internal/rsc.io/arm/armasm"
+	"cmd/internal/rsc.io/x86/x86asm"
+)
+
+// Disasm is a disassembler for a given File.
+type Disasm struct {
+	syms      []Sym            //symbols in file, sorted by address
+	pcln      *gosym.Table     // pcln table
+	text      []byte           // bytes of text segment (actual instructions)
+	textStart uint64           // start PC of text
+	textEnd   uint64           // end PC of text
+	goarch    string           // GOARCH string
+	disasm    disasmFunc       // disassembler function for goarch
+	byteOrder binary.ByteOrder // byte order for goarch
+}
+
+// Disasm returns a disassembler for the file f.
+func (f *File) Disasm() (*Disasm, error) {
+	syms, err := f.Symbols()
+	if err != nil {
+		return nil, err
+	}
+
+	pcln, err := f.PCLineTable()
+	if err != nil {
+		return nil, err
+	}
+
+	textStart, textBytes, err := f.Text()
+	if err != nil {
+		return nil, err
+	}
+
+	goarch := f.GOARCH()
+	disasm := disasms[goarch]
+	byteOrder := byteOrders[goarch]
+	if disasm == nil || byteOrder == nil {
+		return nil, fmt.Errorf("unsupported architecture")
+	}
+
+	// Filter out section symbols, overwriting syms in place.
+	keep := syms[:0]
+	for _, sym := range syms {
+		switch sym.Name {
+		case "runtime.text", "text", "_text", "runtime.etext", "etext", "_etext":
+			// drop
+		default:
+			keep = append(keep, sym)
+		}
+	}
+	syms = keep
+	d := &Disasm{
+		syms:      syms,
+		pcln:      pcln,
+		text:      textBytes,
+		textStart: textStart,
+		textEnd:   textStart + uint64(len(textBytes)),
+		goarch:    goarch,
+		disasm:    disasm,
+		byteOrder: byteOrder,
+	}
+
+	return d, nil
+}
+
+// lookup finds the symbol name containing addr.
+func (d *Disasm) lookup(addr uint64) (name string, base uint64) {
+	i := sort.Search(len(d.syms), func(i int) bool { return addr < d.syms[i].Addr })
+	if i > 0 {
+		s := d.syms[i-1]
+		if s.Addr != 0 && s.Addr <= addr && addr < s.Addr+uint64(s.Size) {
+			return s.Name, s.Addr
+		}
+	}
+	return "", 0
+}
+
+// base returns the final element in the path.
+// It works on both Windows and Unix paths,
+// regardless of host operating system.
+func base(path string) string {
+	path = path[strings.LastIndex(path, "/")+1:]
+	path = path[strings.LastIndex(path, `\`)+1:]
+	return path
+}
+
+// Print prints a disassembly of the file to w.
+// If filter is non-nil, the disassembly only includes functions with names matching filter.
+// The disassembly only includes functions that overlap the range [start, end).
+func (d *Disasm) Print(w io.Writer, filter *regexp.Regexp, start, end uint64) {
+	if start < d.textStart {
+		start = d.textStart
+	}
+	if end > d.textEnd {
+		end = d.textEnd
+	}
+	printed := false
+	bw := bufio.NewWriter(w)
+	for _, sym := range d.syms {
+		symStart := sym.Addr
+		symEnd := sym.Addr + uint64(sym.Size)
+		if sym.Code != 'T' && sym.Code != 't' ||
+			symStart < d.textStart ||
+			symEnd <= start || end <= symStart ||
+			filter != nil && !filter.MatchString(sym.Name) {
+			continue
+		}
+		if printed {
+			fmt.Fprintf(bw, "\n")
+		}
+		printed = true
+
+		file, _, _ := d.pcln.PCToLine(sym.Addr)
+		fmt.Fprintf(bw, "TEXT %s(SB) %s\n", sym.Name, file)
+
+		tw := tabwriter.NewWriter(bw, 1, 8, 1, '\t', 0)
+		if symEnd > end {
+			symEnd = end
+		}
+		code := d.text[:end-d.textStart]
+		d.Decode(symStart, symEnd, func(pc, size uint64, file string, line int, text string) {
+			i := pc - d.textStart
+			fmt.Fprintf(tw, "\t%s:%d\t%#x\t", base(file), line, pc)
+			if size%4 != 0 || d.goarch == "386" || d.goarch == "amd64" {
+				// Print instruction as bytes.
+				fmt.Fprintf(tw, "%x", code[i:i+size])
+			} else {
+				// Print instruction as 32-bit words.
+				for j := uint64(0); j < size; j += 4 {
+					if j > 0 {
+						fmt.Fprintf(tw, " ")
+					}
+					fmt.Fprintf(tw, "%08x", d.byteOrder.Uint32(code[i+j:]))
+				}
+			}
+			fmt.Fprintf(tw, "\t%s\n", text)
+		})
+		tw.Flush()
+	}
+	bw.Flush()
+}
+
+// Decode disassembles the text segment range [start, end), calling f for each instruction.
+func (d *Disasm) Decode(start, end uint64, f func(pc, size uint64, file string, line int, text string)) {
+	if start < d.textStart {
+		start = d.textStart
+	}
+	if end > d.textEnd {
+		end = d.textEnd
+	}
+	code := d.text[:end-d.textStart]
+	lookup := d.lookup
+	for pc := start; pc < end; {
+		i := pc - d.textStart
+		text, size := d.disasm(code[i:], pc, lookup)
+		file, line, _ := d.pcln.PCToLine(pc)
+		f(pc, uint64(size), file, line, text)
+		pc += uint64(size)
+	}
+}
+
+type lookupFunc func(addr uint64) (sym string, base uint64)
+type disasmFunc func(code []byte, pc uint64, lookup lookupFunc) (text string, size int)
+
+func disasm_386(code []byte, pc uint64, lookup lookupFunc) (string, int) {
+	return disasm_x86(code, pc, lookup, 32)
+}
+
+func disasm_amd64(code []byte, pc uint64, lookup lookupFunc) (string, int) {
+	return disasm_x86(code, pc, lookup, 64)
+}
+
+func disasm_x86(code []byte, pc uint64, lookup lookupFunc, arch int) (string, int) {
+	inst, err := x86asm.Decode(code, 64)
+	var text string
+	size := inst.Len
+	if err != nil || size == 0 || inst.Op == 0 {
+		size = 1
+		text = "?"
+	} else {
+		text = x86asm.Plan9Syntax(inst, pc, lookup)
+	}
+	return text, size
+}
+
+type textReader struct {
+	code []byte
+	pc   uint64
+}
+
+func (r textReader) ReadAt(data []byte, off int64) (n int, err error) {
+	if off < 0 || uint64(off) < r.pc {
+		return 0, io.EOF
+	}
+	d := uint64(off) - r.pc
+	if d >= uint64(len(r.code)) {
+		return 0, io.EOF
+	}
+	n = copy(data, r.code[d:])
+	if n < len(data) {
+		err = io.ErrUnexpectedEOF
+	}
+	return
+}
+
+func disasm_arm(code []byte, pc uint64, lookup lookupFunc) (string, int) {
+	inst, err := armasm.Decode(code, armasm.ModeARM)
+	var text string
+	size := inst.Len
+	if err != nil || size == 0 || inst.Op == 0 {
+		size = 4
+		text = "?"
+	} else {
+		text = armasm.Plan9Syntax(inst, pc, lookup, textReader{code, pc})
+	}
+	return text, size
+}
+
+var disasms = map[string]disasmFunc{
+	"386":   disasm_386,
+	"amd64": disasm_amd64,
+	"arm":   disasm_arm,
+}
+
+var byteOrders = map[string]binary.ByteOrder{
+	"386":       binary.LittleEndian,
+	"amd64":     binary.LittleEndian,
+	"arm":       binary.LittleEndian,
+	"power64":   binary.BigEndian,
+	"power64le": binary.LittleEndian,
+}
diff --git a/src/cmd/internal/objfile/elf.go b/src/cmd/internal/objfile/elf.go
new file mode 100644
index 0000000..17755b8
--- /dev/null
+++ b/src/cmd/internal/objfile/elf.go
@@ -0,0 +1,104 @@
+// Copyright 2013 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Parsing of ELF executables (Linux, FreeBSD, and so on).
+
+package objfile
+
+import (
+	"debug/elf"
+	"fmt"
+	"os"
+)
+
+type elfFile struct {
+	elf *elf.File
+}
+
+func openElf(r *os.File) (rawFile, error) {
+	f, err := elf.NewFile(r)
+	if err != nil {
+		return nil, err
+	}
+	return &elfFile{f}, nil
+}
+
+func (f *elfFile) symbols() ([]Sym, error) {
+	elfSyms, err := f.elf.Symbols()
+	if err != nil {
+		return nil, err
+	}
+
+	var syms []Sym
+	for _, s := range elfSyms {
+		sym := Sym{Addr: s.Value, Name: s.Name, Size: int64(s.Size), Code: '?'}
+		switch s.Section {
+		case elf.SHN_UNDEF:
+			sym.Code = 'U'
+		case elf.SHN_COMMON:
+			sym.Code = 'B'
+		default:
+			i := int(s.Section)
+			if i < 0 || i >= len(f.elf.Sections) {
+				break
+			}
+			sect := f.elf.Sections[i]
+			switch sect.Flags & (elf.SHF_WRITE | elf.SHF_ALLOC | elf.SHF_EXECINSTR) {
+			case elf.SHF_ALLOC | elf.SHF_EXECINSTR:
+				sym.Code = 'T'
+			case elf.SHF_ALLOC:
+				sym.Code = 'R'
+			case elf.SHF_ALLOC | elf.SHF_WRITE:
+				sym.Code = 'D'
+			}
+		}
+		if elf.ST_BIND(s.Info) == elf.STB_LOCAL {
+			sym.Code += 'a' - 'A'
+		}
+		syms = append(syms, sym)
+	}
+
+	return syms, nil
+}
+
+func (f *elfFile) pcln() (textStart uint64, symtab, pclntab []byte, err error) {
+	if sect := f.elf.Section(".text"); sect != nil {
+		textStart = sect.Addr
+	}
+	if sect := f.elf.Section(".gosymtab"); sect != nil {
+		if symtab, err = sect.Data(); err != nil {
+			return 0, nil, nil, err
+		}
+	}
+	if sect := f.elf.Section(".gopclntab"); sect != nil {
+		if pclntab, err = sect.Data(); err != nil {
+			return 0, nil, nil, err
+		}
+	}
+	return textStart, symtab, pclntab, nil
+}
+
+func (f *elfFile) text() (textStart uint64, text []byte, err error) {
+	sect := f.elf.Section(".text")
+	if sect == nil {
+		return 0, nil, fmt.Errorf("text section not found")
+	}
+	textStart = sect.Addr
+	text, err = sect.Data()
+	return
+}
+
+func (f *elfFile) goarch() string {
+	switch f.elf.Machine {
+	case elf.EM_386:
+		return "386"
+	case elf.EM_X86_64:
+		return "amd64"
+	case elf.EM_ARM:
+		return "arm"
+	case elf.EM_PPC64:
+		return "power64"
+	}
+	return ""
+}
diff --git a/src/cmd/internal/objfile/goobj.go b/src/cmd/internal/objfile/goobj.go
new file mode 100644
index 0000000..6b1607a
--- /dev/null
+++ b/src/cmd/internal/objfile/goobj.go
@@ -0,0 +1,93 @@
+// Copyright 2013 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Parsing of Go intermediate object files and archives.
+
+package objfile
+
+import (
+	"cmd/internal/goobj"
+	"fmt"
+	"os"
+)
+
+type goobjFile struct {
+	goobj *goobj.Package
+}
+
+func openGoobj(r *os.File) (rawFile, error) {
+	f, err := goobj.Parse(r, `""`)
+	if err != nil {
+		return nil, err
+	}
+	return &goobjFile{f}, nil
+}
+
+func goobjName(id goobj.SymID) string {
+	if id.Version == 0 {
+		return id.Name
+	}
+	return fmt.Sprintf("%s<%d>", id.Name, id.Version)
+}
+
+func (f *goobjFile) symbols() ([]Sym, error) {
+	seen := make(map[goobj.SymID]bool)
+
+	var syms []Sym
+	for _, s := range f.goobj.Syms {
+		seen[s.SymID] = true
+		sym := Sym{Addr: uint64(s.Data.Offset), Name: goobjName(s.SymID), Size: int64(s.Size), Type: s.Type.Name, Code: '?'}
+		switch s.Kind {
+		case goobj.STEXT, goobj.SELFRXSECT:
+			sym.Code = 'T'
+		case goobj.STYPE, goobj.SSTRING, goobj.SGOSTRING, goobj.SGOFUNC, goobj.SRODATA, goobj.SFUNCTAB, goobj.STYPELINK, goobj.SSYMTAB, goobj.SPCLNTAB, goobj.SELFROSECT:
+			sym.Code = 'R'
+		case goobj.SMACHOPLT, goobj.SELFSECT, goobj.SMACHO, goobj.SMACHOGOT, goobj.SNOPTRDATA, goobj.SINITARR, goobj.SDATA, goobj.SWINDOWS:
+			sym.Code = 'D'
+		case goobj.SBSS, goobj.SNOPTRBSS, goobj.STLSBSS:
+			sym.Code = 'B'
+		case goobj.SXREF, goobj.SMACHOSYMSTR, goobj.SMACHOSYMTAB, goobj.SMACHOINDIRECTPLT, goobj.SMACHOINDIRECTGOT, goobj.SFILE, goobj.SFILEPATH, goobj.SCONST, goobj.SDYNIMPORT, goobj.SHOSTOBJ:
+			sym.Code = 'X' // should not see
+		}
+		if s.Version != 0 {
+			sym.Code += 'a' - 'A'
+		}
+		syms = append(syms, sym)
+	}
+
+	for _, s := range f.goobj.Syms {
+		for _, r := range s.Reloc {
+			if !seen[r.Sym] {
+				seen[r.Sym] = true
+				sym := Sym{Name: goobjName(r.Sym), Code: 'U'}
+				if s.Version != 0 {
+					// should not happen but handle anyway
+					sym.Code = 'u'
+				}
+				syms = append(syms, sym)
+			}
+		}
+	}
+
+	return syms, nil
+}
+
+// pcln does not make sense for Go object files, because each
+// symbol has its own individual pcln table, so there is no global
+// space of addresses to map.
+func (f *goobjFile) pcln() (textStart uint64, symtab, pclntab []byte, err error) {
+	return 0, nil, nil, fmt.Errorf("pcln not available in go object file")
+}
+
+// text does not make sense for Go object files, because
+// each function has a separate section.
+func (f *goobjFile) text() (textStart uint64, text []byte, err error) {
+	return 0, nil, fmt.Errorf("text not available in go object file")
+}
+
+// goarch makes sense but is not exposed in debug/goobj's API,
+// and we don't need it yet for any users of internal/objfile.
+func (f *goobjFile) goarch() string {
+	return "GOARCH unimplemented for debug/goobj files"
+}
diff --git a/src/cmd/internal/objfile/macho.go b/src/cmd/internal/objfile/macho.go
new file mode 100644
index 0000000..7dd84a3
--- /dev/null
+++ b/src/cmd/internal/objfile/macho.go
@@ -0,0 +1,116 @@
+// Copyright 2013 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Parsing of Mach-O executables (OS X).
+
+package objfile
+
+import (
+	"debug/macho"
+	"fmt"
+	"os"
+	"sort"
+)
+
+type machoFile struct {
+	macho *macho.File
+}
+
+func openMacho(r *os.File) (rawFile, error) {
+	f, err := macho.NewFile(r)
+	if err != nil {
+		return nil, err
+	}
+	return &machoFile{f}, nil
+}
+
+func (f *machoFile) symbols() ([]Sym, error) {
+	if f.macho.Symtab == nil {
+		return nil, fmt.Errorf("missing symbol table")
+	}
+
+	// Build sorted list of addresses of all symbols.
+	// We infer the size of a symbol by looking at where the next symbol begins.
+	var addrs []uint64
+	for _, s := range f.macho.Symtab.Syms {
+		addrs = append(addrs, s.Value)
+	}
+	sort.Sort(uint64s(addrs))
+
+	var syms []Sym
+	for _, s := range f.macho.Symtab.Syms {
+		sym := Sym{Name: s.Name, Addr: s.Value, Code: '?'}
+		i := sort.Search(len(addrs), func(x int) bool { return addrs[x] > s.Value })
+		if i < len(addrs) {
+			sym.Size = int64(addrs[i] - s.Value)
+		}
+		if s.Sect == 0 {
+			sym.Code = 'U'
+		} else if int(s.Sect) <= len(f.macho.Sections) {
+			sect := f.macho.Sections[s.Sect-1]
+			switch sect.Seg {
+			case "__TEXT":
+				sym.Code = 'R'
+			case "__DATA":
+				sym.Code = 'D'
+			}
+			switch sect.Seg + " " + sect.Name {
+			case "__TEXT __text":
+				sym.Code = 'T'
+			case "__DATA __bss", "__DATA __noptrbss":
+				sym.Code = 'B'
+			}
+		}
+		syms = append(syms, sym)
+	}
+
+	return syms, nil
+}
+
+func (f *machoFile) pcln() (textStart uint64, symtab, pclntab []byte, err error) {
+	if sect := f.macho.Section("__text"); sect != nil {
+		textStart = sect.Addr
+	}
+	if sect := f.macho.Section("__gosymtab"); sect != nil {
+		if symtab, err = sect.Data(); err != nil {
+			return 0, nil, nil, err
+		}
+	}
+	if sect := f.macho.Section("__gopclntab"); sect != nil {
+		if pclntab, err = sect.Data(); err != nil {
+			return 0, nil, nil, err
+		}
+	}
+	return textStart, symtab, pclntab, nil
+}
+
+func (f *machoFile) text() (textStart uint64, text []byte, err error) {
+	sect := f.macho.Section("__text")
+	if sect == nil {
+		return 0, nil, fmt.Errorf("text section not found")
+	}
+	textStart = sect.Addr
+	text, err = sect.Data()
+	return
+}
+
+func (f *machoFile) goarch() string {
+	switch f.macho.Cpu {
+	case macho.Cpu386:
+		return "386"
+	case macho.CpuAmd64:
+		return "amd64"
+	case macho.CpuArm:
+		return "arm"
+	case macho.CpuPpc64:
+		return "power64"
+	}
+	return ""
+}
+
+type uint64s []uint64
+
+func (x uint64s) Len() int           { return len(x) }
+func (x uint64s) Swap(i, j int)      { x[i], x[j] = x[j], x[i] }
+func (x uint64s) Less(i, j int) bool { return x[i] < x[j] }
diff --git a/src/cmd/internal/objfile/objfile.go b/src/cmd/internal/objfile/objfile.go
new file mode 100644
index 0000000..9227ef3
--- /dev/null
+++ b/src/cmd/internal/objfile/objfile.go
@@ -0,0 +1,94 @@
+// 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 objfile implements portable access to OS-specific executable files.
+package objfile
+
+import (
+	"debug/gosym"
+	"fmt"
+	"os"
+	"sort"
+)
+
+type rawFile interface {
+	symbols() (syms []Sym, err error)
+	pcln() (textStart uint64, symtab, pclntab []byte, err error)
+	text() (textStart uint64, text []byte, err error)
+	goarch() string
+}
+
+// A File is an opened executable file.
+type File struct {
+	r   *os.File
+	raw rawFile
+}
+
+// A Sym is a symbol defined in an executable file.
+type Sym struct {
+	Name string // symbol name
+	Addr uint64 // virtual address of symbol
+	Size int64  // size in bytes
+	Code rune   // nm code (T for text, D for data, and so on)
+	Type string // XXX?
+}
+
+var openers = []func(*os.File) (rawFile, error){
+	openElf,
+	openGoobj,
+	openMacho,
+	openPE,
+	openPlan9,
+}
+
+// Open opens the named file.
+// The caller must call f.Close when the file is no longer needed.
+func Open(name string) (*File, error) {
+	r, err := os.Open(name)
+	if err != nil {
+		return nil, err
+	}
+	for _, try := range openers {
+		if raw, err := try(r); err == nil {
+			return &File{r, raw}, nil
+		}
+	}
+	r.Close()
+	return nil, fmt.Errorf("open %s: unrecognized object file", name)
+}
+
+func (f *File) Close() error {
+	return f.r.Close()
+}
+
+func (f *File) Symbols() ([]Sym, error) {
+	syms, err := f.raw.symbols()
+	if err != nil {
+		return nil, err
+	}
+	sort.Sort(byAddr(syms))
+	return syms, nil
+}
+
+type byAddr []Sym
+
+func (x byAddr) Less(i, j int) bool { return x[i].Addr < x[j].Addr }
+func (x byAddr) Len() int           { return len(x) }
+func (x byAddr) Swap(i, j int)      { x[i], x[j] = x[j], x[i] }
+
+func (f *File) PCLineTable() (*gosym.Table, error) {
+	textStart, symtab, pclntab, err := f.raw.pcln()
+	if err != nil {
+		return nil, err
+	}
+	return gosym.NewTable(symtab, gosym.NewLineTable(pclntab, textStart))
+}
+
+func (f *File) Text() (uint64, []byte, error) {
+	return f.raw.text()
+}
+
+func (f *File) GOARCH() string {
+	return f.raw.goarch()
+}
diff --git a/src/cmd/internal/objfile/pe.go b/src/cmd/internal/objfile/pe.go
new file mode 100644
index 0000000..67e59c2
--- /dev/null
+++ b/src/cmd/internal/objfile/pe.go
@@ -0,0 +1,201 @@
+// Copyright 2013 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Parsing of PE executables (Microsoft Windows).
+
+package objfile
+
+import (
+	"debug/pe"
+	"fmt"
+	"os"
+	"sort"
+)
+
+type peFile struct {
+	pe *pe.File
+}
+
+func openPE(r *os.File) (rawFile, error) {
+	f, err := pe.NewFile(r)
+	if err != nil {
+		return nil, err
+	}
+	switch f.OptionalHeader.(type) {
+	case *pe.OptionalHeader32, *pe.OptionalHeader64:
+		// ok
+	default:
+		return nil, fmt.Errorf("unrecognized PE format")
+	}
+	return &peFile{f}, nil
+}
+
+func (f *peFile) symbols() ([]Sym, error) {
+	// Build sorted list of addresses of all symbols.
+	// We infer the size of a symbol by looking at where the next symbol begins.
+	var addrs []uint64
+
+	var imageBase uint64
+	switch oh := f.pe.OptionalHeader.(type) {
+	case *pe.OptionalHeader32:
+		imageBase = uint64(oh.ImageBase)
+	case *pe.OptionalHeader64:
+		imageBase = oh.ImageBase
+	}
+
+	var syms []Sym
+	for _, s := range f.pe.Symbols {
+		const (
+			N_UNDEF = 0  // An undefined (extern) symbol
+			N_ABS   = -1 // An absolute symbol (e_value is a constant, not an address)
+			N_DEBUG = -2 // A debugging symbol
+		)
+		sym := Sym{Name: s.Name, Addr: uint64(s.Value), Code: '?'}
+		switch s.SectionNumber {
+		case N_UNDEF:
+			sym.Code = 'U'
+		case N_ABS:
+			sym.Code = 'C'
+		case N_DEBUG:
+			sym.Code = '?'
+		default:
+			if s.SectionNumber < 0 || len(f.pe.Sections) < int(s.SectionNumber) {
+				return nil, fmt.Errorf("invalid section number in symbol table")
+			}
+			sect := f.pe.Sections[s.SectionNumber-1]
+			const (
+				text  = 0x20
+				data  = 0x40
+				bss   = 0x80
+				permX = 0x20000000
+				permR = 0x40000000
+				permW = 0x80000000
+			)
+			ch := sect.Characteristics
+			switch {
+			case ch&text != 0:
+				sym.Code = 'T'
+			case ch&data != 0:
+				if ch&permW == 0 {
+					sym.Code = 'R'
+				} else {
+					sym.Code = 'D'
+				}
+			case ch&bss != 0:
+				sym.Code = 'B'
+			}
+			sym.Addr += imageBase + uint64(sect.VirtualAddress)
+		}
+		syms = append(syms, sym)
+		addrs = append(addrs, sym.Addr)
+	}
+
+	sort.Sort(uint64s(addrs))
+	for i := range syms {
+		j := sort.Search(len(addrs), func(x int) bool { return addrs[x] > syms[i].Addr })
+		if j < len(addrs) {
+			syms[i].Size = int64(addrs[j] - syms[i].Addr)
+		}
+	}
+
+	return syms, nil
+}
+
+func (f *peFile) pcln() (textStart uint64, symtab, pclntab []byte, err error) {
+	var imageBase uint64
+	switch oh := f.pe.OptionalHeader.(type) {
+	case *pe.OptionalHeader32:
+		imageBase = uint64(oh.ImageBase)
+	case *pe.OptionalHeader64:
+		imageBase = oh.ImageBase
+	default:
+		return 0, nil, nil, fmt.Errorf("pe file format not recognized")
+	}
+	if sect := f.pe.Section(".text"); sect != nil {
+		textStart = imageBase + uint64(sect.VirtualAddress)
+	}
+	if pclntab, err = loadPETable(f.pe, "runtime.pclntab", "runtime.epclntab"); err != nil {
+		// We didn't find the symbols, so look for the names used in 1.3 and earlier.
+		// TODO: Remove code looking for the old symbols when we no longer care about 1.3.
+		var err2 error
+		if pclntab, err2 = loadPETable(f.pe, "pclntab", "epclntab"); err2 != nil {
+			return 0, nil, nil, err
+		}
+	}
+	if symtab, err = loadPETable(f.pe, "runtime.symtab", "runtime.esymtab"); err != nil {
+		// Same as above.
+		var err2 error
+		if symtab, err2 = loadPETable(f.pe, "symtab", "esymtab"); err2 != nil {
+			return 0, nil, nil, err
+		}
+	}
+	return textStart, symtab, pclntab, nil
+}
+
+func (f *peFile) text() (textStart uint64, text []byte, err error) {
+	var imageBase uint64
+	switch oh := f.pe.OptionalHeader.(type) {
+	case *pe.OptionalHeader32:
+		imageBase = uint64(oh.ImageBase)
+	case *pe.OptionalHeader64:
+		imageBase = oh.ImageBase
+	default:
+		return 0, nil, fmt.Errorf("pe file format not recognized")
+	}
+	sect := f.pe.Section(".text")
+	if sect == nil {
+		return 0, nil, fmt.Errorf("text section not found")
+	}
+	textStart = imageBase + uint64(sect.VirtualAddress)
+	text, err = sect.Data()
+	return
+}
+
+func findPESymbol(f *pe.File, name string) (*pe.Symbol, error) {
+	for _, s := range f.Symbols {
+		if s.Name != name {
+			continue
+		}
+		if s.SectionNumber <= 0 {
+			return nil, fmt.Errorf("symbol %s: invalid section number %d", name, s.SectionNumber)
+		}
+		if len(f.Sections) < int(s.SectionNumber) {
+			return nil, fmt.Errorf("symbol %s: section number %d is larger than max %d", name, s.SectionNumber, len(f.Sections))
+		}
+		return s, nil
+	}
+	return nil, fmt.Errorf("no %s symbol found", name)
+}
+
+func loadPETable(f *pe.File, sname, ename string) ([]byte, error) {
+	ssym, err := findPESymbol(f, sname)
+	if err != nil {
+		return nil, err
+	}
+	esym, err := findPESymbol(f, ename)
+	if err != nil {
+		return nil, err
+	}
+	if ssym.SectionNumber != esym.SectionNumber {
+		return nil, fmt.Errorf("%s and %s symbols must be in the same section", sname, ename)
+	}
+	sect := f.Sections[ssym.SectionNumber-1]
+	data, err := sect.Data()
+	if err != nil {
+		return nil, err
+	}
+	return data[ssym.Value:esym.Value], nil
+}
+
+func (f *peFile) goarch() string {
+	// Not sure how to get the info we want from PE header.
+	// Look in symbol table for telltale rt0 symbol.
+	if _, err := findPESymbol(f.pe, "_rt0_386_windows"); err == nil {
+		return "386"
+	}
+	if _, err := findPESymbol(f.pe, "_rt0_amd64_windows"); err == nil {
+		return "amd64"
+	}
+	return ""
+}
diff --git a/src/cmd/internal/objfile/plan9obj.go b/src/cmd/internal/objfile/plan9obj.go
new file mode 100644
index 0000000..eb6cba5
--- /dev/null
+++ b/src/cmd/internal/objfile/plan9obj.go
@@ -0,0 +1,146 @@
+// 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.
+
+// Parsing of Plan 9 a.out executables.
+
+package objfile
+
+import (
+	"debug/plan9obj"
+	"fmt"
+	"os"
+	"sort"
+)
+
+var validSymType = map[rune]bool{
+	'T': true,
+	't': true,
+	'D': true,
+	'd': true,
+	'B': true,
+	'b': true,
+}
+
+type plan9File struct {
+	plan9 *plan9obj.File
+}
+
+func openPlan9(r *os.File) (rawFile, error) {
+	f, err := plan9obj.NewFile(r)
+	if err != nil {
+		return nil, err
+	}
+	return &plan9File{f}, nil
+}
+
+func (f *plan9File) symbols() ([]Sym, error) {
+	plan9Syms, err := f.plan9.Symbols()
+	if err != nil {
+		return nil, err
+	}
+
+	// Build sorted list of addresses of all symbols.
+	// We infer the size of a symbol by looking at where the next symbol begins.
+	var addrs []uint64
+	for _, s := range plan9Syms {
+		if !validSymType[s.Type] {
+			continue
+		}
+		addrs = append(addrs, s.Value)
+	}
+	sort.Sort(uint64s(addrs))
+
+	var syms []Sym
+
+	for _, s := range plan9Syms {
+		if !validSymType[s.Type] {
+			continue
+		}
+		sym := Sym{Addr: s.Value, Name: s.Name, Code: rune(s.Type)}
+		i := sort.Search(len(addrs), func(x int) bool { return addrs[x] > s.Value })
+		if i < len(addrs) {
+			sym.Size = int64(addrs[i] - s.Value)
+		}
+		syms = append(syms, sym)
+	}
+
+	return syms, nil
+}
+
+func (f *plan9File) pcln() (textStart uint64, symtab, pclntab []byte, err error) {
+	textStart = f.plan9.LoadAddress + f.plan9.HdrSize
+	if pclntab, err = loadPlan9Table(f.plan9, "runtime.pclntab", "runtime.epclntab"); err != nil {
+		// We didn't find the symbols, so look for the names used in 1.3 and earlier.
+		// TODO: Remove code looking for the old symbols when we no longer care about 1.3.
+		var err2 error
+		if pclntab, err2 = loadPlan9Table(f.plan9, "pclntab", "epclntab"); err2 != nil {
+			return 0, nil, nil, err
+		}
+	}
+	if symtab, err = loadPlan9Table(f.plan9, "runtime.symtab", "runtime.esymtab"); err != nil {
+		// Same as above.
+		var err2 error
+		if symtab, err2 = loadPlan9Table(f.plan9, "symtab", "esymtab"); err2 != nil {
+			return 0, nil, nil, err
+		}
+	}
+	return textStart, symtab, pclntab, nil
+}
+
+func (f *plan9File) text() (textStart uint64, text []byte, err error) {
+	sect := f.plan9.Section("text")
+	if sect == nil {
+		return 0, nil, fmt.Errorf("text section not found")
+	}
+	textStart = f.plan9.LoadAddress + f.plan9.HdrSize
+	text, err = sect.Data()
+	return
+}
+
+func findPlan9Symbol(f *plan9obj.File, name string) (*plan9obj.Sym, error) {
+	syms, err := f.Symbols()
+	if err != nil {
+		return nil, err
+	}
+	for _, s := range syms {
+		if s.Name != name {
+			continue
+		}
+		return &s, nil
+	}
+	return nil, fmt.Errorf("no %s symbol found", name)
+}
+
+func loadPlan9Table(f *plan9obj.File, sname, ename string) ([]byte, error) {
+	ssym, err := findPlan9Symbol(f, sname)
+	if err != nil {
+		return nil, err
+	}
+	esym, err := findPlan9Symbol(f, ename)
+	if err != nil {
+		return nil, err
+	}
+	sect := f.Section("text")
+	if sect == nil {
+		return nil, err
+	}
+	data, err := sect.Data()
+	if err != nil {
+		return nil, err
+	}
+	textStart := f.LoadAddress + f.HdrSize
+	return data[ssym.Value-textStart : esym.Value-textStart], nil
+}
+
+func (f *plan9File) goarch() string {
+	switch f.plan9.Magic {
+	case plan9obj.Magic386:
+		return "386"
+	case plan9obj.MagicAMD64:
+		return "amd64"
+	case plan9obj.MagicARM:
+		return "arm"
+	}
+	return ""
+}
diff --git a/src/cmd/internal/rsc.io/arm/armasm/Makefile b/src/cmd/internal/rsc.io/arm/armasm/Makefile
new file mode 100644
index 0000000..a3f5700
--- /dev/null
+++ b/src/cmd/internal/rsc.io/arm/armasm/Makefile
@@ -0,0 +1,2 @@
+tables.go: ../armmap/map.go ../arm.csv 
+	go run ../armmap/map.go -fmt=decoder ../arm.csv >_tables.go && gofmt _tables.go >tables.go && rm _tables.go
diff --git a/src/cmd/internal/rsc.io/arm/armasm/decode.go b/src/cmd/internal/rsc.io/arm/armasm/decode.go
new file mode 100644
index 0000000..6b4d738
--- /dev/null
+++ b/src/cmd/internal/rsc.io/arm/armasm/decode.go
@@ -0,0 +1,567 @@
+// 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 armasm
+
+import (
+	"encoding/binary"
+	"fmt"
+)
+
+// An instFormat describes the format of an instruction encoding.
+// An instruction with 32-bit value x matches the format if x&mask == value
+// and the condition matches.
+// The condition matches if x>>28 == 0xF && value>>28==0xF
+// or if x>>28 != 0xF and value>>28 == 0.
+// If x matches the format, then the rest of the fields describe how to interpret x.
+// The opBits describe bits that should be extracted from x and added to the opcode.
+// For example opBits = 0x1234 means that the value
+//	(2 bits at offset 1) followed by (4 bits at offset 3)
+// should be added to op.
+// Finally the args describe how to decode the instruction arguments.
+// args is stored as a fixed-size array; if there are fewer than len(args) arguments,
+// args[i] == 0 marks the end of the argument list.
+type instFormat struct {
+	mask     uint32
+	value    uint32
+	priority int8
+	op       Op
+	opBits   uint64
+	args     instArgs
+}
+
+type instArgs [4]instArg
+
+var (
+	errMode    = fmt.Errorf("unsupported execution mode")
+	errShort   = fmt.Errorf("truncated instruction")
+	errUnknown = fmt.Errorf("unknown instruction")
+)
+
+var decoderCover []bool
+
+// Decode decodes the leading bytes in src as a single instruction.
+func Decode(src []byte, mode Mode) (inst Inst, err error) {
+	if mode != ModeARM {
+		return Inst{}, errMode
+	}
+	if len(src) < 4 {
+		return Inst{}, errShort
+	}
+
+	if decoderCover == nil {
+		decoderCover = make([]bool, len(instFormats))
+	}
+
+	x := binary.LittleEndian.Uint32(src)
+
+	// The instFormat table contains both conditional and unconditional instructions.
+	// Considering only the top 4 bits, the conditional instructions use mask=0, value=0,
+	// while the unconditional instructions use mask=f, value=f.
+	// Prepare a version of x with the condition cleared to 0 in conditional instructions
+	// and then assume mask=f during matching.
+	const condMask = 0xf0000000
+	xNoCond := x
+	if x&condMask != condMask {
+		xNoCond &^= condMask
+	}
+	var priority int8
+Search:
+	for i := range instFormats {
+		f := &instFormats[i]
+		if xNoCond&(f.mask|condMask) != f.value || f.priority <= priority {
+			continue
+		}
+		delta := uint32(0)
+		deltaShift := uint(0)
+		for opBits := f.opBits; opBits != 0; opBits >>= 16 {
+			n := uint(opBits & 0xFF)
+			off := uint((opBits >> 8) & 0xFF)
+			delta |= (x >> off) & (1<<n - 1) << deltaShift
+			deltaShift += n
+		}
+		op := f.op + Op(delta)
+
+		// Special case: BKPT encodes with condition but cannot have one.
+		if op&^15 == BKPT_EQ && op != BKPT {
+			continue Search
+		}
+
+		var args Args
+		for j, aop := range f.args {
+			if aop == 0 {
+				break
+			}
+			arg := decodeArg(aop, x)
+			if arg == nil { // cannot decode argument
+				continue Search
+			}
+			args[j] = arg
+		}
+
+		decoderCover[i] = true
+
+		inst = Inst{
+			Op:   op,
+			Args: args,
+			Enc:  x,
+			Len:  4,
+		}
+		priority = f.priority
+		continue Search
+	}
+	if inst.Op != 0 {
+		return inst, nil
+	}
+	return Inst{}, errUnknown
+}
+
+// An instArg describes the encoding of a single argument.
+// In the names used for arguments, _p_ means +, _m_ means -,
+// _pm_ means ± (usually keyed by the U bit).
+// The _W suffix indicates a general addressing mode based on the P and W bits.
+// The _offset and _postindex suffixes force the given addressing mode.
+// The rest should be somewhat self-explanatory, at least given
+// the decodeArg function.
+type instArg uint8
+
+const (
+	_ instArg = iota
+	arg_APSR
+	arg_FPSCR
+	arg_Dn_half
+	arg_R1_0
+	arg_R1_12
+	arg_R2_0
+	arg_R2_12
+	arg_R_0
+	arg_R_12
+	arg_R_12_nzcv
+	arg_R_16
+	arg_R_16_WB
+	arg_R_8
+	arg_R_rotate
+	arg_R_shift_R
+	arg_R_shift_imm
+	arg_SP
+	arg_Sd
+	arg_Sd_Dd
+	arg_Dd_Sd
+	arg_Sm
+	arg_Sm_Dm
+	arg_Sn
+	arg_Sn_Dn
+	arg_const
+	arg_endian
+	arg_fbits
+	arg_fp_0
+	arg_imm24
+	arg_imm5
+	arg_imm5_32
+	arg_imm5_nz
+	arg_imm_12at8_4at0
+	arg_imm_4at16_12at0
+	arg_imm_vfp
+	arg_label24
+	arg_label24H
+	arg_label_m_12
+	arg_label_p_12
+	arg_label_pm_12
+	arg_label_pm_4_4
+	arg_lsb_width
+	arg_mem_R
+	arg_mem_R_pm_R_W
+	arg_mem_R_pm_R_postindex
+	arg_mem_R_pm_R_shift_imm_W
+	arg_mem_R_pm_R_shift_imm_offset
+	arg_mem_R_pm_R_shift_imm_postindex
+	arg_mem_R_pm_imm12_W
+	arg_mem_R_pm_imm12_offset
+	arg_mem_R_pm_imm12_postindex
+	arg_mem_R_pm_imm8_W
+	arg_mem_R_pm_imm8_postindex
+	arg_mem_R_pm_imm8at0_offset
+	arg_option
+	arg_registers
+	arg_registers1
+	arg_registers2
+	arg_satimm4
+	arg_satimm5
+	arg_satimm4m1
+	arg_satimm5m1
+	arg_widthm1
+)
+
+// decodeArg decodes the arg described by aop from the instruction bits x.
+// It returns nil if x cannot be decoded according to aop.
+func decodeArg(aop instArg, x uint32) Arg {
+	switch aop {
+	default:
+		return nil
+
+	case arg_APSR:
+		return APSR
+	case arg_FPSCR:
+		return FPSCR
+
+	case arg_R_0:
+		return Reg(x & (1<<4 - 1))
+	case arg_R_8:
+		return Reg((x >> 8) & (1<<4 - 1))
+	case arg_R_12:
+		return Reg((x >> 12) & (1<<4 - 1))
+	case arg_R_16:
+		return Reg((x >> 16) & (1<<4 - 1))
+
+	case arg_R_12_nzcv:
+		r := Reg((x >> 12) & (1<<4 - 1))
+		if r == R15 {
+			return APSR_nzcv
+		}
+		return r
+
+	case arg_R_16_WB:
+		mode := AddrLDM
+		if (x>>21)&1 != 0 {
+			mode = AddrLDM_WB
+		}
+		return Mem{Base: Reg((x >> 16) & (1<<4 - 1)), Mode: mode}
+
+	case arg_R_rotate:
+		Rm := Reg(x & (1<<4 - 1))
+		typ, count := decodeShift(x)
+		// ROR #0 here means ROR #0, but decodeShift rewrites to RRX #1.
+		if typ == RotateRightExt {
+			return Reg(Rm)
+		}
+		return RegShift{Rm, typ, uint8(count)}
+
+	case arg_R_shift_R:
+		Rm := Reg(x & (1<<4 - 1))
+		Rs := Reg((x >> 8) & (1<<4 - 1))
+		typ := Shift((x >> 5) & (1<<2 - 1))
+		return RegShiftReg{Rm, typ, Rs}
+
+	case arg_R_shift_imm:
+		Rm := Reg(x & (1<<4 - 1))
+		typ, count := decodeShift(x)
+		if typ == ShiftLeft && count == 0 {
+			return Reg(Rm)
+		}
+		return RegShift{Rm, typ, uint8(count)}
+
+	case arg_R1_0:
+		return Reg((x & (1<<4 - 1)))
+	case arg_R1_12:
+		return Reg(((x >> 12) & (1<<4 - 1)))
+	case arg_R2_0:
+		return Reg((x & (1<<4 - 1)) | 1)
+	case arg_R2_12:
+		return Reg(((x >> 12) & (1<<4 - 1)) | 1)
+
+	case arg_SP:
+		return SP
+
+	case arg_Sd_Dd:
+		v := (x >> 12) & (1<<4 - 1)
+		vx := (x >> 22) & 1
+		sz := (x >> 8) & 1
+		if sz != 0 {
+			return D0 + Reg(vx<<4+v)
+		} else {
+			return S0 + Reg(v<<1+vx)
+		}
+
+	case arg_Dd_Sd:
+		return decodeArg(arg_Sd_Dd, x^(1<<8))
+
+	case arg_Sd:
+		v := (x >> 12) & (1<<4 - 1)
+		vx := (x >> 22) & 1
+		return S0 + Reg(v<<1+vx)
+
+	case arg_Sm_Dm:
+		v := (x >> 0) & (1<<4 - 1)
+		vx := (x >> 5) & 1
+		sz := (x >> 8) & 1
+		if sz != 0 {
+			return D0 + Reg(vx<<4+v)
+		} else {
+			return S0 + Reg(v<<1+vx)
+		}
+
+	case arg_Sm:
+		v := (x >> 0) & (1<<4 - 1)
+		vx := (x >> 5) & 1
+		return S0 + Reg(v<<1+vx)
+
+	case arg_Dn_half:
+		v := (x >> 16) & (1<<4 - 1)
+		vx := (x >> 7) & 1
+		return RegX{D0 + Reg(vx<<4+v), int((x >> 21) & 1)}
+
+	case arg_Sn_Dn:
+		v := (x >> 16) & (1<<4 - 1)
+		vx := (x >> 7) & 1
+		sz := (x >> 8) & 1
+		if sz != 0 {
+			return D0 + Reg(vx<<4+v)
+		} else {
+			return S0 + Reg(v<<1+vx)
+		}
+
+	case arg_Sn:
+		v := (x >> 16) & (1<<4 - 1)
+		vx := (x >> 7) & 1
+		return S0 + Reg(v<<1+vx)
+
+	case arg_const:
+		v := x & (1<<8 - 1)
+		rot := (x >> 8) & (1<<4 - 1) * 2
+		if rot > 0 && v&3 == 0 {
+			// could rotate less
+			return ImmAlt{uint8(v), uint8(rot)}
+		}
+		if rot >= 24 && ((v<<(32-rot))&0xFF)>>(32-rot) == v {
+			// could wrap around to rot==0.
+			return ImmAlt{uint8(v), uint8(rot)}
+		}
+		return Imm(v>>rot | v<<(32-rot))
+
+	case arg_endian:
+		return Endian((x >> 9) & 1)
+
+	case arg_fbits:
+		return Imm((16 << ((x >> 7) & 1)) - ((x&(1<<4-1))<<1 | (x>>5)&1))
+
+	case arg_fp_0:
+		return Imm(0)
+
+	case arg_imm24:
+		return Imm(x & (1<<24 - 1))
+
+	case arg_imm5:
+		return Imm((x >> 7) & (1<<5 - 1))
+
+	case arg_imm5_32:
+		x = (x >> 7) & (1<<5 - 1)
+		if x == 0 {
+			x = 32
+		}
+		return Imm(x)
+
+	case arg_imm5_nz:
+		x = (x >> 7) & (1<<5 - 1)
+		if x == 0 {
+			return nil
+		}
+		return Imm(x)
+
+	case arg_imm_4at16_12at0:
+		return Imm((x>>16)&(1<<4-1)<<12 | x&(1<<12-1))
+
+	case arg_imm_12at8_4at0:
+		return Imm((x>>8)&(1<<12-1)<<4 | x&(1<<4-1))
+
+	case arg_imm_vfp:
+		x = (x>>16)&(1<<4-1)<<4 | x&(1<<4-1)
+		return Imm(x)
+
+	case arg_label24:
+		imm := (x & (1<<24 - 1)) << 2
+		return PCRel(int32(imm<<6) >> 6)
+
+	case arg_label24H:
+		h := (x >> 24) & 1
+		imm := (x&(1<<24-1))<<2 | h<<1
+		return PCRel(int32(imm<<6) >> 6)
+
+	case arg_label_m_12:
+		d := int32(x & (1<<12 - 1))
+		return Mem{Base: PC, Mode: AddrOffset, Offset: int16(-d)}
+
+	case arg_label_p_12:
+		d := int32(x & (1<<12 - 1))
+		return Mem{Base: PC, Mode: AddrOffset, Offset: int16(d)}
+
+	case arg_label_pm_12:
+		d := int32(x & (1<<12 - 1))
+		u := (x >> 23) & 1
+		if u == 0 {
+			d = -d
+		}
+		return Mem{Base: PC, Mode: AddrOffset, Offset: int16(d)}
+
+	case arg_label_pm_4_4:
+		d := int32((x>>8)&(1<<4-1)<<4 | x&(1<<4-1))
+		u := (x >> 23) & 1
+		if u == 0 {
+			d = -d
+		}
+		return PCRel(d)
+
+	case arg_lsb_width:
+		lsb := (x >> 7) & (1<<5 - 1)
+		msb := (x >> 16) & (1<<5 - 1)
+		if msb < lsb || msb >= 32 {
+			return nil
+		}
+		return Imm(msb + 1 - lsb)
+
+	case arg_mem_R:
+		Rn := Reg((x >> 16) & (1<<4 - 1))
+		return Mem{Base: Rn, Mode: AddrOffset}
+
+	case arg_mem_R_pm_R_postindex:
+		// Treat [<Rn>],+/-<Rm> like [<Rn>,+/-<Rm>{,<shift>}]{!}
+		// by forcing shift bits to <<0 and P=0, W=0 (postindex=true).
+		return decodeArg(arg_mem_R_pm_R_shift_imm_W, x&^((1<<7-1)<<5|1<<24|1<<21))
+
+	case arg_mem_R_pm_R_W:
+		// Treat [<Rn>,+/-<Rm>]{!} like [<Rn>,+/-<Rm>{,<shift>}]{!}
+		// by forcing shift bits to <<0.
+		return decodeArg(arg_mem_R_pm_R_shift_imm_W, x&^((1<<7-1)<<5))
+
+	case arg_mem_R_pm_R_shift_imm_offset:
+		// Treat [<Rn>],+/-<Rm>{,<shift>} like [<Rn>,+/-<Rm>{,<shift>}]{!}
+		// by forcing P=1, W=0 (index=false, wback=false).
+		return decodeArg(arg_mem_R_pm_R_shift_imm_W, x&^(1<<21)|1<<24)
+
+	case arg_mem_R_pm_R_shift_imm_postindex:
+		// Treat [<Rn>],+/-<Rm>{,<shift>} like [<Rn>,+/-<Rm>{,<shift>}]{!}
+		// by forcing P=0, W=0 (postindex=true).
+		return decodeArg(arg_mem_R_pm_R_shift_imm_W, x&^(1<<24|1<<21))
+
+	case arg_mem_R_pm_R_shift_imm_W:
+		Rn := Reg((x >> 16) & (1<<4 - 1))
+		Rm := Reg(x & (1<<4 - 1))
+		typ, count := decodeShift(x)
+		u := (x >> 23) & 1
+		w := (x >> 21) & 1
+		p := (x >> 24) & 1
+		if p == 0 && w == 1 {
+			return nil
+		}
+		sign := int8(+1)
+		if u == 0 {
+			sign = -1
+		}
+		mode := AddrMode(uint8(p<<1) | uint8(w^1))
+		return Mem{Base: Rn, Mode: mode, Sign: sign, Index: Rm, Shift: typ, Count: count}
+
+	case arg_mem_R_pm_imm12_offset:
+		// Treat [<Rn>,#+/-<imm12>] like [<Rn>{,#+/-<imm12>}]{!}
+		// by forcing P=1, W=0 (index=false, wback=false).
+		return decodeArg(arg_mem_R_pm_imm12_W, x&^(1<<21)|1<<24)
+
+	case arg_mem_R_pm_imm12_postindex:
+		// Treat [<Rn>],#+/-<imm12> like [<Rn>{,#+/-<imm12>}]{!}
+		// by forcing P=0, W=0 (postindex=true).
+		return decodeArg(arg_mem_R_pm_imm12_W, x&^(1<<24|1<<21))
+
+	case arg_mem_R_pm_imm12_W:
+		Rn := Reg((x >> 16) & (1<<4 - 1))
+		u := (x >> 23) & 1
+		w := (x >> 21) & 1
+		p := (x >> 24) & 1
+		if p == 0 && w == 1 {
+			return nil
+		}
+		sign := int8(+1)
+		if u == 0 {
+			sign = -1
+		}
+		imm := int16(x & (1<<12 - 1))
+		mode := AddrMode(uint8(p<<1) | uint8(w^1))
+		return Mem{Base: Rn, Mode: mode, Offset: int16(sign) * imm}
+
+	case arg_mem_R_pm_imm8_postindex:
+		// Treat [<Rn>],#+/-<imm8> like [<Rn>{,#+/-<imm8>}]{!}
+		// by forcing P=0, W=0 (postindex=true).
+		return decodeArg(arg_mem_R_pm_imm8_W, x&^(1<<24|1<<21))
+
+	case arg_mem_R_pm_imm8_W:
+		Rn := Reg((x >> 16) & (1<<4 - 1))
+		u := (x >> 23) & 1
+		w := (x >> 21) & 1
+		p := (x >> 24) & 1
+		if p == 0 && w == 1 {
+			return nil
+		}
+		sign := int8(+1)
+		if u == 0 {
+			sign = -1
+		}
+		imm := int16((x>>8)&(1<<4-1)<<4 | x&(1<<4-1))
+		mode := AddrMode(uint8(p<<1) | uint8(w^1))
+		return Mem{Base: Rn, Mode: mode, Offset: int16(sign) * imm}
+
+	case arg_mem_R_pm_imm8at0_offset:
+		Rn := Reg((x >> 16) & (1<<4 - 1))
+		u := (x >> 23) & 1
+		sign := int8(+1)
+		if u == 0 {
+			sign = -1
+		}
+		imm := int16(x&(1<<8-1)) << 2
+		return Mem{Base: Rn, Mode: AddrOffset, Offset: int16(sign) * imm}
+
+	case arg_option:
+		return Imm(x & (1<<4 - 1))
+
+	case arg_registers:
+		return RegList(x & (1<<16 - 1))
+
+	case arg_registers2:
+		x &= 1<<16 - 1
+		n := 0
+		for i := 0; i < 16; i++ {
+			if x>>uint(i)&1 != 0 {
+				n++
+			}
+		}
+		if n < 2 {
+			return nil
+		}
+		return RegList(x)
+
+	case arg_registers1:
+		Rt := (x >> 12) & (1<<4 - 1)
+		return RegList(1 << Rt)
+
+	case arg_satimm4:
+		return Imm((x >> 16) & (1<<4 - 1))
+
+	case arg_satimm5:
+		return Imm((x >> 16) & (1<<5 - 1))
+
+	case arg_satimm4m1:
+		return Imm((x>>16)&(1<<4-1) + 1)
+
+	case arg_satimm5m1:
+		return Imm((x>>16)&(1<<5-1) + 1)
+
+	case arg_widthm1:
+		return Imm((x>>16)&(1<<5-1) + 1)
+
+	}
+}
+
+// decodeShift decodes the shift-by-immediate encoded in x.
+func decodeShift(x uint32) (Shift, uint8) {
+	count := (x >> 7) & (1<<5 - 1)
+	typ := Shift((x >> 5) & (1<<2 - 1))
+	switch typ {
+	case ShiftRight, ShiftRightSigned:
+		if count == 0 {
+			count = 32
+		}
+	case RotateRight:
+		if count == 0 {
+			typ = RotateRightExt
+			count = 1
+		}
+	}
+	return typ, uint8(count)
+}
diff --git a/src/cmd/internal/rsc.io/arm/armasm/decode_test.go b/src/cmd/internal/rsc.io/arm/armasm/decode_test.go
new file mode 100644
index 0000000..25a345a
--- /dev/null
+++ b/src/cmd/internal/rsc.io/arm/armasm/decode_test.go
@@ -0,0 +1,69 @@
+// 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 armasm
+
+import (
+	"encoding/hex"
+	"io/ioutil"
+	"strconv"
+	"strings"
+	"testing"
+)
+
+func TestDecode(t *testing.T) {
+	data, err := ioutil.ReadFile("testdata/decode.txt")
+	if err != nil {
+		t.Fatal(err)
+	}
+	all := string(data)
+	for strings.Contains(all, "\t\t") {
+		all = strings.Replace(all, "\t\t", "\t", -1)
+	}
+	for _, line := range strings.Split(all, "\n") {
+		line = strings.TrimSpace(line)
+		if line == "" || strings.HasPrefix(line, "#") {
+			continue
+		}
+		f := strings.SplitN(line, "\t", 4)
+		i := strings.Index(f[0], "|")
+		if i < 0 {
+			t.Errorf("parsing %q: missing | separator", f[0])
+			continue
+		}
+		if i%2 != 0 {
+			t.Errorf("parsing %q: misaligned | separator", f[0])
+		}
+		size := i / 2
+		code, err := hex.DecodeString(f[0][:i] + f[0][i+1:])
+		if err != nil {
+			t.Errorf("parsing %q: %v", f[0], err)
+			continue
+		}
+		mode, err := strconv.Atoi(f[1])
+		if err != nil {
+			t.Errorf("invalid mode %q in: %s", f[1], line)
+			continue
+		}
+		syntax, asm := f[2], f[3]
+		inst, err := Decode(code, Mode(mode))
+		var out string
+		if err != nil {
+			out = "error: " + err.Error()
+		} else {
+			switch syntax {
+			case "gnu":
+				out = GNUSyntax(inst)
+			case "plan9":
+				out = Plan9Syntax(inst, 0, nil, nil)
+			default:
+				t.Errorf("unknown syntax %q", syntax)
+				continue
+			}
+		}
+		if out != asm || inst.Len != size {
+			t.Errorf("Decode(%s) [%s] = %s, %d, want %s, %d", f[0], syntax, out, inst.Len, asm, size)
+		}
+	}
+}
diff --git a/src/cmd/internal/rsc.io/arm/armasm/ext_test.go b/src/cmd/internal/rsc.io/arm/armasm/ext_test.go
new file mode 100644
index 0000000..b0bd855
--- /dev/null
+++ b/src/cmd/internal/rsc.io/arm/armasm/ext_test.go
@@ -0,0 +1,614 @@
+// 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.
+
+// Support for testing against external disassembler program.
+// Copied and simplified from rsc.io/x86/x86asm/ext_test.go.
+
+package armasm
+
+import (
+	"bufio"
+	"bytes"
+	"encoding/hex"
+	"flag"
+	"fmt"
+	"io/ioutil"
+	"log"
+	"math/rand"
+	"os"
+	"os/exec"
+	"regexp"
+	"runtime"
+	"strings"
+	"testing"
+	"time"
+)
+
+var (
+	printTests = flag.Bool("printtests", false, "print test cases that exercise new code paths")
+	dumpTest   = flag.Bool("dump", false, "dump all encodings")
+	mismatch   = flag.Bool("mismatch", false, "log allowed mismatches")
+	longTest   = flag.Bool("long", false, "long test")
+	keep       = flag.Bool("keep", false, "keep object files around")
+	debug      = false
+)
+
+// A ExtInst represents a single decoded instruction parsed
+// from an external disassembler's output.
+type ExtInst struct {
+	addr uint32
+	enc  [4]byte
+	nenc int
+	text string
+}
+
+func (r ExtInst) String() string {
+	return fmt.Sprintf("%#x: % x: %s", r.addr, r.enc, r.text)
+}
+
+// An ExtDis is a connection between an external disassembler and a test.
+type ExtDis struct {
+	Arch     Mode
+	Dec      chan ExtInst
+	File     *os.File
+	Size     int
+	KeepFile bool
+	Cmd      *exec.Cmd
+}
+
+// Run runs the given command - the external disassembler - and returns
+// a buffered reader of its standard output.
+func (ext *ExtDis) Run(cmd ...string) (*bufio.Reader, error) {
+	if *keep {
+		log.Printf("%s\n", strings.Join(cmd, " "))
+	}
+	ext.Cmd = exec.Command(cmd[0], cmd[1:]...)
+	out, err := ext.Cmd.StdoutPipe()
+	if err != nil {
+		return nil, fmt.Errorf("stdoutpipe: %v", err)
+	}
+	if err := ext.Cmd.Start(); err != nil {
+		return nil, fmt.Errorf("exec: %v", err)
+	}
+
+	b := bufio.NewReaderSize(out, 1<<20)
+	return b, nil
+}
+
+// Wait waits for the command started with Run to exit.
+func (ext *ExtDis) Wait() error {
+	return ext.Cmd.Wait()
+}
+
+// testExtDis tests a set of byte sequences against an external disassembler.
+// The disassembler is expected to produce the given syntax and be run
+// in the given architecture mode (16, 32, or 64-bit).
+// The extdis function must start the external disassembler
+// and then parse its output, sending the parsed instructions on ext.Dec.
+// The generate function calls its argument f once for each byte sequence
+// to be tested. The generate function itself will be called twice, and it must
+// make the same sequence of calls to f each time.
+// When a disassembly does not match the internal decoding,
+// allowedMismatch determines whether this mismatch should be
+// allowed, or else considered an error.
+func testExtDis(
+	t *testing.T,
+	syntax string,
+	arch Mode,
+	extdis func(ext *ExtDis) error,
+	generate func(f func([]byte)),
+	allowedMismatch func(text string, size int, inst *Inst, dec ExtInst) bool,
+) {
+	start := time.Now()
+	ext := &ExtDis{
+		Dec:  make(chan ExtInst),
+		Arch: arch,
+	}
+	errc := make(chan error)
+
+	// First pass: write instructions to input file for external disassembler.
+	file, f, size, err := writeInst(generate)
+	if err != nil {
+		t.Fatal(err)
+	}
+	ext.Size = size
+	ext.File = f
+	defer func() {
+		f.Close()
+		if !*keep {
+			os.Remove(file)
+		}
+	}()
+
+	// Second pass: compare disassembly against our decodings.
+	var (
+		totalTests  = 0
+		totalSkips  = 0
+		totalErrors = 0
+
+		errors = make([]string, 0, 100) // sampled errors, at most cap
+	)
+	go func() {
+		errc <- extdis(ext)
+	}()
+	generate(func(enc []byte) {
+		dec, ok := <-ext.Dec
+		if !ok {
+			t.Errorf("decoding stream ended early")
+			return
+		}
+		inst, text := disasm(syntax, arch, pad(enc))
+		totalTests++
+		if *dumpTest {
+			fmt.Printf("%x -> %s [%d]\n", enc[:len(enc)], dec.text, dec.nenc)
+		}
+		if text != dec.text || inst.Len != dec.nenc {
+			suffix := ""
+			if allowedMismatch(text, size, &inst, dec) {
+				totalSkips++
+				if !*mismatch {
+					return
+				}
+				suffix += " (allowed mismatch)"
+			}
+			totalErrors++
+			if len(errors) >= cap(errors) {
+				j := rand.Intn(totalErrors)
+				if j >= cap(errors) {
+					return
+				}
+				errors = append(errors[:j], errors[j+1:]...)
+			}
+			errors = append(errors, fmt.Sprintf("decode(%x) = %q, %d, want %q, %d%s", enc, text, inst.Len, dec.text, dec.nenc, suffix))
+		}
+	})
+
+	if *mismatch {
+		totalErrors -= totalSkips
+	}
+
+	for _, b := range errors {
+		t.Log(b)
+	}
+
+	if totalErrors > 0 {
+		t.Fail()
+	}
+	t.Logf("%d test cases, %d expected mismatches, %d failures; %.0f cases/second", totalTests, totalSkips, totalErrors, float64(totalTests)/time.Since(start).Seconds())
+
+	if err := <-errc; err != nil {
+		t.Fatal("external disassembler: %v", err)
+	}
+
+}
+
+const start = 0x8000 // start address of text
+
+// writeInst writes the generated byte sequences to a new file
+// starting at offset start. That file is intended to be the input to
+// the external disassembler.
+func writeInst(generate func(func([]byte))) (file string, f *os.File, size int, err error) {
+	f, err = ioutil.TempFile("", "armasm")
+	if err != nil {
+		return
+	}
+
+	file = f.Name()
+
+	f.Seek(start, 0)
+	w := bufio.NewWriter(f)
+	defer w.Flush()
+	size = 0
+	generate(func(x []byte) {
+		if len(x) > 4 {
+			x = x[:4]
+		}
+		if debug {
+			fmt.Printf("%#x: %x%x\n", start+size, x, zeros[len(x):])
+		}
+		w.Write(x)
+		w.Write(zeros[len(x):])
+		size += len(zeros)
+	})
+	return file, f, size, nil
+}
+
+var zeros = []byte{0, 0, 0, 0}
+
+// pad pads the code sequenc with pops.
+func pad(enc []byte) []byte {
+	if len(enc) < 4 {
+		enc = append(enc[:len(enc):len(enc)], zeros[:4-len(enc)]...)
+	}
+	return enc
+}
+
+// disasm returns the decoded instruction and text
+// for the given source bytes, using the given syntax and mode.
+func disasm(syntax string, mode Mode, src []byte) (inst Inst, text string) {
+	// If printTests is set, we record the coverage value
+	// before and after, and we write out the inputs for which
+	// coverage went up, in the format expected in testdata/decode.text.
+	// This produces a fairly small set of test cases that exercise nearly
+	// all the code.
+	var cover float64
+	if *printTests {
+		cover -= coverage()
+	}
+
+	inst, err := Decode(src, mode)
+	if err != nil {
+		text = "error: " + err.Error()
+	} else {
+		text = inst.String()
+		switch syntax {
+		//case "arm":
+		//	text = ARMSyntax(inst)
+		case "gnu":
+			text = GNUSyntax(inst)
+		//case "plan9":
+		//	text = Plan9Syntax(inst, 0, nil)
+		default:
+			text = "error: unknown syntax " + syntax
+		}
+	}
+
+	if *printTests {
+		cover += coverage()
+		if cover > 0 {
+			max := len(src)
+			if max > 4 && inst.Len <= 4 {
+				max = 4
+			}
+			fmt.Printf("%x|%x\t%d\t%s\t%s\n", src[:inst.Len], src[inst.Len:max], mode, syntax, text)
+		}
+	}
+
+	return
+}
+
+// coverage returns a floating point number denoting the
+// test coverage until now. The number increases when new code paths are exercised,
+// both in the Go program and in the decoder byte code.
+func coverage() float64 {
+	/*
+		testing.Coverage is not in the main distribution.
+		The implementation, which must go in package testing, is:
+
+		// Coverage reports the current code coverage as a fraction in the range [0, 1].
+		func Coverage() float64 {
+			var n, d int64
+			for _, counters := range cover.Counters {
+				for _, c := range counters {
+					if c > 0 {
+						n++
+					}
+					d++
+				}
+			}
+			if d == 0 {
+				return 0
+			}
+			return float64(n) / float64(d)
+		}
+	*/
+
+	var f float64
+	f += testing.Coverage()
+	f += decodeCoverage()
+	return f
+}
+
+func decodeCoverage() float64 {
+	n := 0
+	for _, t := range decoderCover {
+		if t {
+			n++
+		}
+	}
+	return float64(1+n) / float64(1+len(decoderCover))
+}
+
+// Helpers for writing disassembler output parsers.
+
+// hasPrefix reports whether any of the space-separated words in the text s
+// begins with any of the given prefixes.
+func hasPrefix(s string, prefixes ...string) bool {
+	for _, prefix := range prefixes {
+		for s := s; s != ""; {
+			if strings.HasPrefix(s, prefix) {
+				return true
+			}
+			i := strings.Index(s, " ")
+			if i < 0 {
+				break
+			}
+			s = s[i+1:]
+		}
+	}
+	return false
+}
+
+// contains reports whether the text s contains any of the given substrings.
+func contains(s string, substrings ...string) bool {
+	for _, sub := range substrings {
+		if strings.Contains(s, sub) {
+			return true
+		}
+	}
+	return false
+}
+
+// isHex reports whether b is a hexadecimal character (0-9A-Fa-f).
+func isHex(b byte) bool { return b == '0' || unhex[b] > 0 }
+
+// parseHex parses the hexadecimal byte dump in hex,
+// appending the parsed bytes to raw and returning the updated slice.
+// The returned bool signals whether any invalid hex was found.
+// Spaces and tabs between bytes are okay but any other non-hex is not.
+func parseHex(hex []byte, raw []byte) ([]byte, bool) {
+	hex = trimSpace(hex)
+	for j := 0; j < len(hex); {
+		for hex[j] == ' ' || hex[j] == '\t' {
+			j++
+		}
+		if j >= len(hex) {
+			break
+		}
+		if j+2 > len(hex) || !isHex(hex[j]) || !isHex(hex[j+1]) {
+			return nil, false
+		}
+		raw = append(raw, unhex[hex[j]]<<4|unhex[hex[j+1]])
+		j += 2
+	}
+	return raw, true
+}
+
+var unhex = [256]byte{
+	'0': 0,
+	'1': 1,
+	'2': 2,
+	'3': 3,
+	'4': 4,
+	'5': 5,
+	'6': 6,
+	'7': 7,
+	'8': 8,
+	'9': 9,
+	'A': 10,
+	'B': 11,
+	'C': 12,
+	'D': 13,
+	'E': 14,
+	'F': 15,
+	'a': 10,
+	'b': 11,
+	'c': 12,
+	'd': 13,
+	'e': 14,
+	'f': 15,
+}
+
+// index is like bytes.Index(s, []byte(t)) but avoids the allocation.
+func index(s []byte, t string) int {
+	i := 0
+	for {
+		j := bytes.IndexByte(s[i:], t[0])
+		if j < 0 {
+			return -1
+		}
+		i = i + j
+		if i+len(t) > len(s) {
+			return -1
+		}
+		for k := 1; k < len(t); k++ {
+			if s[i+k] != t[k] {
+				goto nomatch
+			}
+		}
+		return i
+	nomatch:
+		i++
+	}
+}
+
+// fixSpace rewrites runs of spaces, tabs, and newline characters into single spaces in s.
+// If s must be rewritten, it is rewritten in place.
+func fixSpace(s []byte) []byte {
+	s = trimSpace(s)
+	for i := 0; i < len(s); i++ {
+		if s[i] == '\t' || s[i] == '\n' || i > 0 && s[i] == ' ' && s[i-1] == ' ' {
+			goto Fix
+		}
+	}
+	return s
+
+Fix:
+	b := s
+	w := 0
+	for i := 0; i < len(s); i++ {
+		c := s[i]
+		if c == '\t' || c == '\n' {
+			c = ' '
+		}
+		if c == ' ' && w > 0 && b[w-1] == ' ' {
+			continue
+		}
+		b[w] = c
+		w++
+	}
+	if w > 0 && b[w-1] == ' ' {
+		w--
+	}
+	return b[:w]
+}
+
+// trimSpace trims leading and trailing space from s, returning a subslice of s.
+func trimSpace(s []byte) []byte {
+	j := len(s)
+	for j > 0 && (s[j-1] == ' ' || s[j-1] == '\t' || s[j-1] == '\n') {
+		j--
+	}
+	i := 0
+	for i < j && (s[i] == ' ' || s[i] == '\t') {
+		i++
+	}
+	return s[i:j]
+}
+
+// pcrel matches instructions using relative addressing mode.
+var (
+	pcrel = regexp.MustCompile(`^((?:.* )?(?:b|bl)x?(?:eq|ne|cs|cc|mi|pl|vs|vc|hi|ls|ge|lt|gt|le)?) 0x([0-9a-f]+)$`)
+)
+
+// Generators.
+//
+// The test cases are described as functions that invoke a callback repeatedly,
+// with a new input sequence each time. These helpers make writing those
+// a little easier.
+
+// condCases generates conditional instructions.
+func condCases(t *testing.T) func(func([]byte)) {
+	return func(try func([]byte)) {
+		// All the strides are relatively prime to 2 and therefore to 2²⁸,
+		// so we will not repeat any instructions until we have tried all 2²⁸.
+		// Using a stride other than 1 is meant to visit the instructions in a
+		// pseudorandom order, which gives better variety in the set of
+		// test cases chosen by -printtests.
+		stride := uint32(10007)
+		n := 1 << 28 / 7
+		if testing.Short() {
+			stride = 100003
+			n = 1 << 28 / 1001
+		} else if *longTest {
+			stride = 200000033
+			n = 1 << 28
+		}
+		x := uint32(0)
+		for i := 0; i < n; i++ {
+			enc := (x%15)<<28 | x&(1<<28-1)
+			try([]byte{byte(enc), byte(enc >> 8), byte(enc >> 16), byte(enc >> 24)})
+			x += stride
+		}
+	}
+}
+
+// uncondCases generates unconditional instructions.
+func uncondCases(t *testing.T) func(func([]byte)) {
+	return func(try func([]byte)) {
+		condCases(t)(func(enc []byte) {
+			enc[3] |= 0xF0
+			try(enc)
+		})
+	}
+}
+
+func countBits(x uint32) int {
+	n := 0
+	for ; x != 0; x >>= 1 {
+		n += int(x & 1)
+	}
+	return n
+}
+
+func expandBits(x, m uint32) uint32 {
+	var out uint32
+	for i := uint(0); i < 32; i++ {
+		out >>= 1
+		if m&1 != 0 {
+			out |= (x & 1) << 31
+			x >>= 1
+		}
+		m >>= 1
+	}
+	return out
+}
+
+func tryCondMask(mask, val uint32, try func([]byte)) {
+	n := countBits(^mask)
+	bits := uint32(0)
+	for i := 0; i < 1<<uint(n); i++ {
+		bits += 848251 // arbitrary prime
+		x := val | expandBits(bits, ^mask) | uint32(i)%15<<28
+		try([]byte{byte(x), byte(x >> 8), byte(x >> 16), byte(x >> 24)})
+	}
+}
+
+// vfpCases generates VFP instructions.
+func vfpCases(t *testing.T) func(func([]byte)) {
+	const (
+		vfpmask uint32 = 0xFF00FE10
+		vfp     uint32 = 0x0E009A00
+	)
+	return func(try func([]byte)) {
+		tryCondMask(0xff00fe10, 0x0e009a00, try) // standard VFP instruction space
+		tryCondMask(0xffc00f7f, 0x0e000b10, try) // VFP MOV core reg to/from float64 half
+		tryCondMask(0xffe00f7f, 0x0e000a10, try) // VFP MOV core reg to/from float32
+		tryCondMask(0xffef0fff, 0x0ee10a10, try) // VFP MOV core reg to/from cond codes
+	}
+}
+
+// hexCases generates the cases written in hexadecimal in the encoded string.
+// Spaces in 'encoded' separate entire test cases, not individual bytes.
+func hexCases(t *testing.T, encoded string) func(func([]byte)) {
+	return func(try func([]byte)) {
+		for _, x := range strings.Fields(encoded) {
+			src, err := hex.DecodeString(x)
+			if err != nil {
+				t.Errorf("parsing %q: %v", x, err)
+			}
+			try(src)
+		}
+	}
+}
+
+// testdataCases generates the test cases recorded in testdata/decode.txt.
+// It only uses the inputs; it ignores the answers recorded in that file.
+func testdataCases(t *testing.T) func(func([]byte)) {
+	var codes [][]byte
+	data, err := ioutil.ReadFile("testdata/decode.txt")
+	if err != nil {
+		t.Fatal(err)
+	}
+	for _, line := range strings.Split(string(data), "\n") {
+		line = strings.TrimSpace(line)
+		if line == "" || strings.HasPrefix(line, "#") {
+			continue
+		}
+		f := strings.Fields(line)[0]
+		i := strings.Index(f, "|")
+		if i < 0 {
+			t.Errorf("parsing %q: missing | separator", f)
+			continue
+		}
+		if i%2 != 0 {
+			t.Errorf("parsing %q: misaligned | separator", f)
+		}
+		code, err := hex.DecodeString(f[:i] + f[i+1:])
+		if err != nil {
+			t.Errorf("parsing %q: %v", f, err)
+			continue
+		}
+		codes = append(codes, code)
+	}
+
+	return func(try func([]byte)) {
+		for _, code := range codes {
+			try(code)
+		}
+	}
+}
+
+func caller(skip int) string {
+	pc, _, _, _ := runtime.Caller(skip)
+	f := runtime.FuncForPC(pc)
+	name := "?"
+	if f != nil {
+		name = f.Name()
+		if i := strings.LastIndex(name, "."); i >= 0 {
+			name = name[i+1:]
+		}
+	}
+	return name
+}
diff --git a/src/cmd/internal/rsc.io/arm/armasm/gnu.go b/src/cmd/internal/rsc.io/arm/armasm/gnu.go
new file mode 100644
index 0000000..1a97a5a
--- /dev/null
+++ b/src/cmd/internal/rsc.io/arm/armasm/gnu.go
@@ -0,0 +1,164 @@
+// 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 armasm
+
+import (
+	"bytes"
+	"fmt"
+	"strings"
+)
+
+var saveDot = strings.NewReplacer(
+	".F16", "_dot_F16",
+	".F32", "_dot_F32",
+	".F64", "_dot_F64",
+	".S32", "_dot_S32",
+	".U32", "_dot_U32",
+	".FXS", "_dot_S",
+	".FXU", "_dot_U",
+	".32", "_dot_32",
+)
+
+// GNUSyntax returns the GNU assembler syntax for the instruction, as defined by GNU binutils.
+// This form typically matches the syntax defined in the ARM Reference Manual.
+func GNUSyntax(inst Inst) string {
+	var buf bytes.Buffer
+	op := inst.Op.String()
+	op = saveDot.Replace(op)
+	op = strings.Replace(op, ".", "", -1)
+	op = strings.Replace(op, "_dot_", ".", -1)
+	op = strings.ToLower(op)
+	buf.WriteString(op)
+	sep := " "
+	for i, arg := range inst.Args {
+		if arg == nil {
+			break
+		}
+		text := gnuArg(&inst, i, arg)
+		if text == "" {
+			continue
+		}
+		buf.WriteString(sep)
+		sep = ", "
+		buf.WriteString(text)
+	}
+	return buf.String()
+}
+
+func gnuArg(inst *Inst, argIndex int, arg Arg) string {
+	switch inst.Op &^ 15 {
+	case LDRD_EQ, LDREXD_EQ, STRD_EQ:
+		if argIndex == 1 {
+			// second argument in consecutive pair not printed
+			return ""
+		}
+	case STREXD_EQ:
+		if argIndex == 2 {
+			// second argument in consecutive pair not printed
+			return ""
+		}
+	}
+
+	switch arg := arg.(type) {
+	case Imm:
+		switch inst.Op &^ 15 {
+		case BKPT_EQ:
+			return fmt.Sprintf("%#04x", uint32(arg))
+		case SVC_EQ:
+			return fmt.Sprintf("%#08x", uint32(arg))
+		}
+		return fmt.Sprintf("#%d", int32(arg))
+
+	case ImmAlt:
+		return fmt.Sprintf("#%d, %d", arg.Val, arg.Rot)
+
+	case Mem:
+		R := gnuArg(inst, -1, arg.Base)
+		X := ""
+		if arg.Sign != 0 {
+			X = ""
+			if arg.Sign < 0 {
+				X = "-"
+			}
+			X += gnuArg(inst, -1, arg.Index)
+			if arg.Shift == ShiftLeft && arg.Count == 0 {
+				// nothing
+			} else if arg.Shift == RotateRightExt {
+				X += ", rrx"
+			} else {
+				X += fmt.Sprintf(", %s #%d", strings.ToLower(arg.Shift.String()), arg.Count)
+			}
+		} else {
+			X = fmt.Sprintf("#%d", arg.Offset)
+		}
+
+		switch arg.Mode {
+		case AddrOffset:
+			if X == "#0" {
+				return fmt.Sprintf("[%s]", R)
+			}
+			return fmt.Sprintf("[%s, %s]", R, X)
+		case AddrPreIndex:
+			return fmt.Sprintf("[%s, %s]!", R, X)
+		case AddrPostIndex:
+			return fmt.Sprintf("[%s], %s", R, X)
+		case AddrLDM:
+			if X == "#0" {
+				return R
+			}
+		case AddrLDM_WB:
+			if X == "#0" {
+				return R + "!"
+			}
+		}
+		return fmt.Sprintf("[%s Mode(%d) %s]", R, int(arg.Mode), X)
+
+	case PCRel:
+		return fmt.Sprintf(".%+#x", int32(arg)+4)
+
+	case Reg:
+		switch inst.Op &^ 15 {
+		case LDREX_EQ:
+			if argIndex == 0 {
+				return fmt.Sprintf("r%d", int32(arg))
+			}
+		}
+		switch arg {
+		case R10:
+			return "sl"
+		case R11:
+			return "fp"
+		case R12:
+			return "ip"
+		}
+
+	case RegList:
+		var buf bytes.Buffer
+		fmt.Fprintf(&buf, "{")
+		sep := ""
+		for i := 0; i < 16; i++ {
+			if arg&(1<<uint(i)) != 0 {
+				fmt.Fprintf(&buf, "%s%s", sep, gnuArg(inst, -1, Reg(i)))
+				sep = ", "
+			}
+		}
+		fmt.Fprintf(&buf, "}")
+		return buf.String()
+
+	case RegShift:
+		if arg.Shift == ShiftLeft && arg.Count == 0 {
+			return gnuArg(inst, -1, arg.Reg)
+		}
+		if arg.Shift == RotateRightExt {
+			return gnuArg(inst, -1, arg.Reg) + ", rrx"
+		}
+		return fmt.Sprintf("%s, %s #%d", gnuArg(inst, -1, arg.Reg), strings.ToLower(arg.Shift.String()), arg.Count)
+
+	case RegShiftReg:
+		return fmt.Sprintf("%s, %s %s", gnuArg(inst, -1, arg.Reg), strings.ToLower(arg.Shift.String()), gnuArg(inst, -1, arg.RegCount))
+
+	}
+	return strings.ToLower(arg.String())
+}
diff --git a/src/cmd/internal/rsc.io/arm/armasm/inst.go b/src/cmd/internal/rsc.io/arm/armasm/inst.go
new file mode 100644
index 0000000..60d633b
--- /dev/null
+++ b/src/cmd/internal/rsc.io/arm/armasm/inst.go
@@ -0,0 +1,438 @@
+// 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 armasm
+
+import (
+	"bytes"
+	"fmt"
+)
+
+// A Mode is an instruction execution mode.
+type Mode int
+
+const (
+	_ Mode = iota
+	ModeARM
+	ModeThumb
+)
+
+func (m Mode) String() string {
+	switch m {
+	case ModeARM:
+		return "ARM"
+	case ModeThumb:
+		return "Thumb"
+	}
+	return fmt.Sprintf("Mode(%d)", int(m))
+}
+
+// An Op is an ARM opcode.
+type Op uint16
+
+// NOTE: The actual Op values are defined in tables.go.
+// They are chosen to simplify instruction decoding and
+// are not a dense packing from 0 to N, although the
+// density is high, probably at least 90%.
+
+func (op Op) String() string {
+	if op >= Op(len(opstr)) || opstr[op] == "" {
+		return fmt.Sprintf("Op(%d)", int(op))
+	}
+	return opstr[op]
+}
+
+// An Inst is a single instruction.
+type Inst struct {
+	Op   Op     // Opcode mnemonic
+	Enc  uint32 // Raw encoding bits.
+	Len  int    // Length of encoding in bytes.
+	Args Args   // Instruction arguments, in ARM manual order.
+}
+
+func (i Inst) String() string {
+	var buf bytes.Buffer
+	buf.WriteString(i.Op.String())
+	for j, arg := range i.Args {
+		if arg == nil {
+			break
+		}
+		if j == 0 {
+			buf.WriteString(" ")
+		} else {
+			buf.WriteString(", ")
+		}
+		buf.WriteString(arg.String())
+	}
+	return buf.String()
+}
+
+// An Args holds the instruction arguments.
+// If an instruction has fewer than 4 arguments,
+// the final elements in the array are nil.
+type Args [4]Arg
+
+// An Arg is a single instruction argument, one of these types:
+// Endian, Imm, Mem, PCRel, Reg, RegList, RegShift, RegShiftReg.
+type Arg interface {
+	IsArg()
+	String() string
+}
+
+type Float32Imm float32
+
+func (Float32Imm) IsArg() {}
+
+func (f Float32Imm) String() string {
+	return fmt.Sprintf("#%v", float32(f))
+}
+
+type Float64Imm float32
+
+func (Float64Imm) IsArg() {}
+
+func (f Float64Imm) String() string {
+	return fmt.Sprintf("#%v", float64(f))
+}
+
+// An Imm is an integer constant.
+type Imm uint32
+
+func (Imm) IsArg() {}
+
+func (i Imm) String() string {
+	return fmt.Sprintf("#%#x", uint32(i))
+}
+
+// A ImmAlt is an alternate encoding of an integer constant.
+type ImmAlt struct {
+	Val uint8
+	Rot uint8
+}
+
+func (ImmAlt) IsArg() {}
+
+func (i ImmAlt) Imm() Imm {
+	v := uint32(i.Val)
+	r := uint(i.Rot)
+	return Imm(v>>r | v<<(32-r))
+}
+
+func (i ImmAlt) String() string {
+	return fmt.Sprintf("#%#x, %d", i.Val, i.Rot)
+}
+
+// A Label is a text (code) address.
+type Label uint32
+
+func (Label) IsArg() {}
+
+func (i Label) String() string {
+	return fmt.Sprintf("%#x", uint32(i))
+}
+
+// A Reg is a single register.
+// The zero value denotes R0, not the absence of a register.
+type Reg uint8
+
+const (
+	R0 Reg = iota
+	R1
+	R2
+	R3
+	R4
+	R5
+	R6
+	R7
+	R8
+	R9
+	R10
+	R11
+	R12
+	R13
+	R14
+	R15
+
+	S0
+	S1
+	S2
+	S3
+	S4
+	S5
+	S6
+	S7
+	S8
+	S9
+	S10
+	S11
+	S12
+	S13
+	S14
+	S15
+	S16
+	S17
+	S18
+	S19
+	S20
+	S21
+	S22
+	S23
+	S24
+	S25
+	S26
+	S27
+	S28
+	S29
+	S30
+	S31
+
+	D0
+	D1
+	D2
+	D3
+	D4
+	D5
+	D6
+	D7
+	D8
+	D9
+	D10
+	D11
+	D12
+	D13
+	D14
+	D15
+	D16
+	D17
+	D18
+	D19
+	D20
+	D21
+	D22
+	D23
+	D24
+	D25
+	D26
+	D27
+	D28
+	D29
+	D30
+	D31
+
+	APSR
+	APSR_nzcv
+	FPSCR
+
+	SP = R13
+	LR = R14
+	PC = R15
+)
+
+func (Reg) IsArg() {}
+
+func (r Reg) String() string {
+	switch r {
+	case APSR:
+		return "APSR"
+	case APSR_nzcv:
+		return "APSR_nzcv"
+	case FPSCR:
+		return "FPSCR"
+	case SP:
+		return "SP"
+	case PC:
+		return "PC"
+	case LR:
+		return "LR"
+	}
+	if R0 <= r && r <= R15 {
+		return fmt.Sprintf("R%d", int(r-R0))
+	}
+	if S0 <= r && r <= S31 {
+		return fmt.Sprintf("S%d", int(r-S0))
+	}
+	if D0 <= r && r <= D31 {
+		return fmt.Sprintf("D%d", int(r-D0))
+	}
+	return fmt.Sprintf("Reg(%d)", int(r))
+}
+
+// A RegX represents a fraction of a multi-value register.
+// The Index field specifies the index number,
+// but the size of the fraction is not specified.
+// It must be inferred from the instruction and the register type.
+// For example, in a VMOV instruction, RegX{D5, 1} represents
+// the top 32 bits of the 64-bit D5 register.
+type RegX struct {
+	Reg   Reg
+	Index int
+}
+
+func (RegX) IsArg() {}
+
+func (r RegX) String() string {
+	return fmt.Sprintf("%s[%d]", r.Reg, r.Index)
+}
+
+// A RegList is a register list.
+// Bits at indexes x = 0 through 15 indicate whether the corresponding Rx register is in the list.
+type RegList uint16
+
+func (RegList) IsArg() {}
+
+func (r RegList) String() string {
+	var buf bytes.Buffer
+	fmt.Fprintf(&buf, "{")
+	sep := ""
+	for i := 0; i < 16; i++ {
+		if r&(1<<uint(i)) != 0 {
+			fmt.Fprintf(&buf, "%s%s", sep, Reg(i).String())
+			sep = ","
+		}
+	}
+	fmt.Fprintf(&buf, "}")
+	return buf.String()
+}
+
+// An Endian is the argument to the SETEND instruction.
+type Endian uint8
+
+const (
+	LittleEndian Endian = 0
+	BigEndian    Endian = 1
+)
+
+func (Endian) IsArg() {}
+
+func (e Endian) String() string {
+	if e != 0 {
+		return "BE"
+	}
+	return "LE"
+}
+
+// A Shift describes an ARM shift operation.
+type Shift uint8
+
+const (
+	ShiftLeft        Shift = 0 // left shift
+	ShiftRight       Shift = 1 // logical (unsigned) right shift
+	ShiftRightSigned Shift = 2 // arithmetic (signed) right shift
+	RotateRight      Shift = 3 // right rotate
+	RotateRightExt   Shift = 4 // right rotate through carry (Count will always be 1)
+)
+
+var shiftName = [...]string{
+	"LSL", "LSR", "ASR", "ROR", "RRX",
+}
+
+func (s Shift) String() string {
+	if s < 5 {
+		return shiftName[s]
+	}
+	return fmt.Sprintf("Shift(%d)", int(s))
+}
+
+// A RegShift is a register shifted by a constant.
+type RegShift struct {
+	Reg   Reg
+	Shift Shift
+	Count uint8
+}
+
+func (RegShift) IsArg() {}
+
+func (r RegShift) String() string {
+	return fmt.Sprintf("%s %s #%d", r.Reg, r.Shift, r.Count)
+}
+
+// A RegShiftReg is a register shifted by a register.
+type RegShiftReg struct {
+	Reg      Reg
+	Shift    Shift
+	RegCount Reg
+}
+
+func (RegShiftReg) IsArg() {}
+
+func (r RegShiftReg) String() string {
+	return fmt.Sprintf("%s %s %s", r.Reg, r.Shift, r.RegCount)
+}
+
+// A PCRel describes a memory address (usually a code label)
+// as a distance relative to the program counter.
+// TODO(rsc): Define which program counter (PC+4? PC+8? PC?).
+type PCRel int32
+
+func (PCRel) IsArg() {}
+
+func (r PCRel) String() string {
+	return fmt.Sprintf("PC%+#x", int32(r))
+}
+
+// An AddrMode is an ARM addressing mode.
+type AddrMode uint8
+
+const (
+	_             AddrMode = iota
+	AddrPostIndex          // [R], X – use address R, set R = R + X
+	AddrPreIndex           // [R, X]! – use address R + X, set R = R + X
+	AddrOffset             // [R, X] – use address R + X
+	AddrLDM                // R – [R] but formats as R, for LDM/STM only
+	AddrLDM_WB             // R! - [R], X where X is instruction-specific amount, for LDM/STM only
+)
+
+// A Mem is a memory reference made up of a base R and index expression X.
+// The effective memory address is R or R+X depending on AddrMode.
+// The index expression is X = Sign*(Index Shift Count) + Offset,
+// but in any instruction either Sign = 0 or Offset = 0.
+type Mem struct {
+	Base   Reg
+	Mode   AddrMode
+	Sign   int8
+	Index  Reg
+	Shift  Shift
+	Count  uint8
+	Offset int16
+}
+
+func (Mem) IsArg() {}
+
+func (m Mem) String() string {
+	R := m.Base.String()
+	X := ""
+	if m.Sign != 0 {
+		X = "+"
+		if m.Sign < 0 {
+			X = "-"
+		}
+		X += m.Index.String()
+		if m.Shift != ShiftLeft || m.Count != 0 {
+			X += fmt.Sprintf(", %s #%d", m.Shift, m.Count)
+		}
+	} else {
+		X = fmt.Sprintf("#%d", m.Offset)
+	}
+
+	switch m.Mode {
+	case AddrOffset:
+		if X == "#0" {
+			return fmt.Sprintf("[%s]", R)
+		}
+		return fmt.Sprintf("[%s, %s]", R, X)
+	case AddrPreIndex:
+		return fmt.Sprintf("[%s, %s]!", R, X)
+	case AddrPostIndex:
+		return fmt.Sprintf("[%s], %s", R, X)
+	case AddrLDM:
+		if X == "#0" {
+			return R
+		}
+	case AddrLDM_WB:
+		if X == "#0" {
+			return R + "!"
+		}
+	}
+	return fmt.Sprintf("[%s Mode(%d) %s]", R, int(m.Mode), X)
+}
diff --git a/src/cmd/internal/rsc.io/arm/armasm/objdump_test.go b/src/cmd/internal/rsc.io/arm/armasm/objdump_test.go
new file mode 100644
index 0000000..00a00e7
--- /dev/null
+++ b/src/cmd/internal/rsc.io/arm/armasm/objdump_test.go
@@ -0,0 +1,258 @@
+// 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 armasm
+
+import (
+	"encoding/binary"
+	"strings"
+	"testing"
+)
+
+func TestObjdumpARMTestdata(t *testing.T) { testObjdumpARM(t, testdataCases(t)) }
+func TestObjdumpARMManual(t *testing.T)   { testObjdumpARM(t, hexCases(t, objdumpManualTests)) }
+func TestObjdumpARMCond(t *testing.T)     { testObjdumpARM(t, condCases(t)) }
+func TestObjdumpARMUncond(t *testing.T)   { testObjdumpARM(t, uncondCases(t)) }
+func TestObjdumpARMVFP(t *testing.T)      { testObjdumpARM(t, vfpCases(t)) }
+
+// objdumpManualTests holds test cases that will be run by TestObjdumpARMManual.
+// If you are debugging a few cases that turned up in a longer run, it can be useful
+// to list them here and then use -run=Manual, particularly with tracing enabled.
+// Note that these are byte sequences, so they must be reversed from the usual
+// word presentation.
+var objdumpManualTests = `
+00000000
+`
+
+// allowedMismatchObjdump reports whether the mismatch between text and dec
+// should be allowed by the test.
+func allowedMismatchObjdump(text string, size int, inst *Inst, dec ExtInst) bool {
+	if hasPrefix(text, "error:") {
+		if hasPrefix(dec.text, unsupported...) || strings.Contains(dec.text, "invalid:") || strings.HasSuffix(dec.text, "^") || strings.Contains(dec.text, "f16.f64") || strings.Contains(dec.text, "f64.f16") {
+			return true
+		}
+		// word 4320F02C: libopcodes says 'nopmi {44}'.
+		if hasPrefix(dec.text, "nop") && strings.Contains(dec.text, "{") {
+			return true
+		}
+	}
+
+	if hasPrefix(dec.text, "error:") && text == "undef" && inst.Enc == 0xf7fabcfd {
+		return true
+	}
+
+	// word 00f02053: libopcodes says 'noppl {0}'.
+	if hasPrefix(dec.text, "nop") && hasPrefix(text, "nop") && dec.text == text+" {0}" {
+		return true
+	}
+
+	// word F57FF04F. we say 'dsb #15', libopcodes says 'dsb sy'.
+	if hasPrefix(text, "dsb") && hasPrefix(dec.text, "dsb") {
+		return true
+	}
+	// word F57FF06F. we say 'isb #15', libopcodes says 'isb sy'.
+	if hasPrefix(text, "isb") && hasPrefix(dec.text, "isb") {
+		return true
+	}
+	// word F57FF053. we say 'dmb #3', libopcodes says 'dmb osh'.
+	if hasPrefix(text, "dmb") && hasPrefix(dec.text, "dmb") {
+		return true
+	}
+
+	// word 992D0000. push/stmdb with no registers (undefined).
+	// we say 'stmdbls sp!, {}', libopcodes says 'pushls {}'.
+	if hasPrefix(text, "stmdb") && hasPrefix(dec.text, "push") && strings.Contains(text, "{}") && strings.Contains(dec.text, "{}") {
+		return true
+	}
+
+	// word 28BD0000. pop/ldm with no registers (undefined).
+	// we say 'ldmcs sp!, {}', libopcodes says 'popcs {}'.
+	if hasPrefix(text, "ldm") && hasPrefix(dec.text, "pop") && strings.Contains(text, "{}") && strings.Contains(dec.text, "{}") {
+		return true
+	}
+
+	// word 014640F0.
+	// libopcodes emits #-0 for negative zero; we don't.
+	if strings.Replace(dec.text, "#-0", "#0", -1) == text || strings.Replace(dec.text, ", #-0", "", -1) == text {
+		return true
+	}
+
+	// word 91EF90F0. we say 'strdls r9, [pc, #0]!' but libopcodes says 'strdls r9, [pc]'.
+	// word D16F60F0. we say 'strdle r6, [pc, #0]!' but libopcodes says 'strdle r6, [pc, #-0]'.
+	if strings.Replace(text, ", #0]!", "]", -1) == strings.Replace(dec.text, ", #-0]", "]", -1) {
+		return true
+	}
+
+	// word 510F4000. we say apsr, libopcodes says CPSR.
+	if strings.Replace(dec.text, "CPSR", "apsr", -1) == text {
+		return true
+	}
+
+	// word 06A4B059.
+	// for ssat and usat, libopcodes decodes asr #0 as asr #0 but the manual seems to say it should be asr #32.
+	// There is never an asr #0.
+	if strings.Replace(dec.text, ", asr #0", ", asr #32", -1) == text {
+		return true
+	}
+
+	if len(dec.enc) >= 4 {
+		raw := binary.LittleEndian.Uint32(dec.enc[:4])
+
+		// word 21FFF0B5.
+		// the manual is clear that this is pre-indexed mode (with !) but libopcodes generates post-index (without !).
+		if raw&0x01200000 == 0x01200000 && strings.Replace(text, "!", "", -1) == dec.text {
+			return true
+		}
+
+		// word C100543E: libopcodes says tst, but no evidence for that.
+		if strings.HasPrefix(dec.text, "tst") && raw&0x0ff00000 != 0x03100000 && raw&0x0ff00000 != 0x01100000 {
+			return true
+		}
+
+		// word C3203CE8: libopcodes says teq, but no evidence for that.
+		if strings.HasPrefix(dec.text, "teq") && raw&0x0ff00000 != 0x03300000 && raw&0x0ff00000 != 0x01300000 {
+			return true
+		}
+
+		// word D14C552E: libopcodes says cmp but no evidence for that.
+		if strings.HasPrefix(dec.text, "cmp") && raw&0x0ff00000 != 0x03500000 && raw&0x0ff00000 != 0x01500000 {
+			return true
+		}
+
+		// word 2166AA4A: libopcodes says cmn but no evidence for that.
+		if strings.HasPrefix(dec.text, "cmn") && raw&0x0ff00000 != 0x03700000 && raw&0x0ff00000 != 0x01700000 {
+			return true
+		}
+
+		// word E70AEEEF: libopcodes says str but no evidence for that.
+		if strings.HasPrefix(dec.text, "str") && len(dec.text) >= 5 && (dec.text[3] == ' ' || dec.text[5] == ' ') && raw&0x0e500018 != 0x06000000 && raw&0x0e500000 != 0x0400000 {
+			return true
+		}
+
+		// word B0AF48F4: libopcodes says strd but P=0,W=1 which is unpredictable.
+		if hasPrefix(dec.text, "ldr", "str") && raw&0x01200000 == 0x00200000 {
+			return true
+		}
+
+		// word B6CC1C76: libopcodes inexplicably says 'uxtab16lt r1, ip, r6, ROR #24' instead of 'uxtab16lt r1, ip, r6, ror #24'
+		if strings.ToLower(dec.text) == text {
+			return true
+		}
+
+		// word F410FDA1: libopcodes says PLDW but the manual is clear that PLDW is F5/F7, not F4.
+		// word F7D0FB17: libopcodes says PLDW but the manual is clear that PLDW has 0x10 clear
+		if hasPrefix(dec.text, "pld") && raw&0xfd000010 != 0xf5000000 {
+			return true
+		}
+
+		// word F650FE14: libopcodes says PLI but the manual is clear that PLI has 0x10 clear
+		if hasPrefix(dec.text, "pli") && raw&0xff000010 != 0xf6000000 {
+			return true
+		}
+	}
+
+	return false
+}
+
+// Instructions known to libopcodes (or xed) but not to us.
+// Most of these are floating point coprocessor instructions.
+var unsupported = strings.Fields(`
+	abs
+	acs
+	adf
+	aes
+	asn
+	atn
+	cdp
+	cf
+	cmf
+	cnf
+	cos
+	cps
+	crc32
+	dvf
+	eret
+	exp
+	fadd
+	fcmp
+	fcpy
+	fcvt
+	fdiv
+	fdv
+	fix
+	fld
+	flt
+	fmac
+	fmd
+	fml
+	fmr
+	fms
+	fmul
+	fmx
+	fneg
+	fnm
+	frd
+	fsit
+	fsq
+	fst
+	fsu
+	fto
+	fui
+	hlt
+	hvc
+	lda
+	ldc
+	ldf
+	lfm
+	lgn
+	log
+	mar
+	mcr
+	mcrr
+	mia
+	mnf
+	mra
+	mrc
+	mrrc
+	mrs
+	msr
+	msr
+	muf
+	mvf
+	nrm
+	pol
+	pow
+	rdf
+	rfc
+	rfe
+	rfs
+	rmf
+	rnd
+	rpw
+	rsf
+	sdiv
+	sev
+	sfm
+	sha1
+	sha256
+	sin
+	smc
+	sqt
+	srs
+	stc
+	stf
+	stl
+	suf
+	tan
+	udf
+	udiv
+	urd
+	vfma
+	vfms
+	vfnma
+	vfnms
+	vrint
+	wfc
+	wfs
+`)
diff --git a/src/cmd/internal/rsc.io/arm/armasm/objdumpext_test.go b/src/cmd/internal/rsc.io/arm/armasm/objdumpext_test.go
new file mode 100644
index 0000000..d88c67f
--- /dev/null
+++ b/src/cmd/internal/rsc.io/arm/armasm/objdumpext_test.go
@@ -0,0 +1,260 @@
+// 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.
+
+// Copied and simplified from rsc.io/x86/x86asm/objdumpext_test.go.
+
+package armasm
+
+import (
+	"bytes"
+	"debug/elf"
+	"encoding/binary"
+	"fmt"
+	"io"
+	"log"
+	"os"
+	"strconv"
+	"strings"
+	"testing"
+)
+
+const objdumpPath = "/usr/local/bin/arm-linux-elf-objdump"
+
+func testObjdumpARM(t *testing.T, generate func(func([]byte))) {
+	testObjdumpArch(t, generate, ModeARM)
+}
+
+func testObjdumpArch(t *testing.T, generate func(func([]byte)), arch Mode) {
+	if testing.Short() {
+		t.Skip("skipping objdump test in short mode")
+	}
+
+	if _, err := os.Stat(objdumpPath); err != nil {
+		t.Fatal(err)
+	}
+
+	testExtDis(t, "gnu", arch, objdump, generate, allowedMismatchObjdump)
+}
+
+func objdump(ext *ExtDis) error {
+	// File already written with instructions; add ELF header.
+	if ext.Arch == ModeARM {
+		if err := writeELF32(ext.File, ext.Size); err != nil {
+			return err
+		}
+	} else {
+		panic("unknown arch")
+	}
+
+	b, err := ext.Run(objdumpPath, "-d", "-z", ext.File.Name())
+	if err != nil {
+		return err
+	}
+
+	var (
+		nmatch  int
+		reading bool
+		next    uint32 = start
+		addr    uint32
+		encbuf  [4]byte
+		enc     []byte
+		text    string
+	)
+	flush := func() {
+		if addr == next {
+			if m := pcrel.FindStringSubmatch(text); m != nil {
+				targ, _ := strconv.ParseUint(m[2], 16, 64)
+				text = fmt.Sprintf("%s .%+#x", m[1], int32(uint32(targ)-addr-uint32(len(enc))))
+			}
+			if strings.HasPrefix(text, "stmia") {
+				text = "stm" + text[5:]
+			}
+			if strings.HasPrefix(text, "stmfd") {
+				text = "stmdb" + text[5:]
+			}
+			if strings.HasPrefix(text, "ldmfd") {
+				text = "ldm" + text[5:]
+			}
+			text = strings.Replace(text, "#0.0", "#0", -1)
+			if text == "undefined" && len(enc) == 4 {
+				text = "error: unknown instruction"
+				enc = nil
+			}
+			if len(enc) == 4 {
+				// prints as word but we want to record bytes
+				enc[0], enc[3] = enc[3], enc[0]
+				enc[1], enc[2] = enc[2], enc[1]
+			}
+			ext.Dec <- ExtInst{addr, encbuf, len(enc), text}
+			encbuf = [4]byte{}
+			enc = nil
+			next += 4
+		}
+	}
+	var textangle = []byte("<.text>:")
+	for {
+		line, err := b.ReadSlice('\n')
+		if err != nil {
+			if err == io.EOF {
+				break
+			}
+			return fmt.Errorf("reading objdump output: %v", err)
+		}
+		if bytes.Contains(line, textangle) {
+			reading = true
+			continue
+		}
+		if !reading {
+			continue
+		}
+		if debug {
+			os.Stdout.Write(line)
+		}
+		if enc1 := parseContinuation(line, encbuf[:len(enc)]); enc1 != nil {
+			enc = enc1
+			continue
+		}
+		flush()
+		nmatch++
+		addr, enc, text = parseLine(line, encbuf[:0])
+		if addr > next {
+			return fmt.Errorf("address out of sync expected <= %#x at %q in:\n%s", next, line, line)
+		}
+	}
+	flush()
+	if next != start+uint32(ext.Size) {
+		return fmt.Errorf("not enough results found [%d %d]", next, start+ext.Size)
+	}
+	if err := ext.Wait(); err != nil {
+		return fmt.Errorf("exec: %v", err)
+	}
+
+	return nil
+}
+
+var (
+	undefined      = []byte("<UNDEFINED>")
+	unpredictable  = []byte("<UNPREDICTABLE>")
+	illegalShifter = []byte("<illegal shifter operand>")
+)
+
+func parseLine(line []byte, encstart []byte) (addr uint32, enc []byte, text string) {
+	oline := line
+	i := index(line, ":\t")
+	if i < 0 {
+		log.Fatalf("cannot parse disassembly: %q", oline)
+	}
+	x, err := strconv.ParseUint(string(trimSpace(line[:i])), 16, 32)
+	if err != nil {
+		log.Fatalf("cannot parse disassembly: %q", oline)
+	}
+	addr = uint32(x)
+	line = line[i+2:]
+	i = bytes.IndexByte(line, '\t')
+	if i < 0 {
+		log.Fatalf("cannot parse disassembly: %q", oline)
+	}
+	enc, ok := parseHex(line[:i], encstart)
+	if !ok {
+		log.Fatalf("cannot parse disassembly: %q", oline)
+	}
+	line = trimSpace(line[i:])
+	if bytes.Contains(line, undefined) {
+		text = "undefined"
+		return
+	}
+	if bytes.Contains(line, illegalShifter) {
+		text = "undefined"
+		return
+	}
+	if false && bytes.Contains(line, unpredictable) {
+		text = "unpredictable"
+		return
+	}
+	if i := bytes.IndexByte(line, ';'); i >= 0 {
+		line = trimSpace(line[:i])
+	}
+	text = string(fixSpace(line))
+	return
+}
+
+func parseContinuation(line []byte, enc []byte) []byte {
+	i := index(line, ":\t")
+	if i < 0 {
+		return nil
+	}
+	line = line[i+1:]
+	enc, _ = parseHex(line, enc)
+	return enc
+}
+
+// writeELF32 writes an ELF32 header to the file,
+// describing a text segment that starts at start
+// and extends for size bytes.
+func writeELF32(f *os.File, size int) error {
+	f.Seek(0, 0)
+	var hdr elf.Header32
+	var prog elf.Prog32
+	var sect elf.Section32
+	var buf bytes.Buffer
+	binary.Write(&buf, binary.LittleEndian, &hdr)
+	off1 := buf.Len()
+	binary.Write(&buf, binary.LittleEndian, &prog)
+	off2 := buf.Len()
+	binary.Write(&buf, binary.LittleEndian, &sect)
+	off3 := buf.Len()
+	buf.Reset()
+	data := byte(elf.ELFDATA2LSB)
+	hdr = elf.Header32{
+		Ident:     [16]byte{0x7F, 'E', 'L', 'F', 1, data, 1},
+		Type:      2,
+		Machine:   uint16(elf.EM_ARM),
+		Version:   1,
+		Entry:     start,
+		Phoff:     uint32(off1),
+		Shoff:     uint32(off2),
+		Flags:     0x05000002,
+		Ehsize:    uint16(off1),
+		Phentsize: uint16(off2 - off1),
+		Phnum:     1,
+		Shentsize: uint16(off3 - off2),
+		Shnum:     3,
+		Shstrndx:  2,
+	}
+	binary.Write(&buf, binary.LittleEndian, &hdr)
+	prog = elf.Prog32{
+		Type:   1,
+		Off:    start,
+		Vaddr:  start,
+		Paddr:  start,
+		Filesz: uint32(size),
+		Memsz:  uint32(size),
+		Flags:  5,
+		Align:  start,
+	}
+	binary.Write(&buf, binary.LittleEndian, &prog)
+	binary.Write(&buf, binary.LittleEndian, &sect) // NULL section
+	sect = elf.Section32{
+		Name:      1,
+		Type:      uint32(elf.SHT_PROGBITS),
+		Addr:      start,
+		Off:       start,
+		Size:      uint32(size),
+		Flags:     uint32(elf.SHF_ALLOC | elf.SHF_EXECINSTR),
+		Addralign: 4,
+	}
+	binary.Write(&buf, binary.LittleEndian, &sect) // .text
+	sect = elf.Section32{
+		Name:      uint32(len("\x00.text\x00")),
+		Type:      uint32(elf.SHT_STRTAB),
+		Addr:      0,
+		Off:       uint32(off2 + (off3-off2)*3),
+		Size:      uint32(len("\x00.text\x00.shstrtab\x00")),
+		Addralign: 1,
+	}
+	binary.Write(&buf, binary.LittleEndian, &sect)
+	buf.WriteString("\x00.text\x00.shstrtab\x00")
+	f.Write(buf.Bytes())
+	return nil
+}
diff --git a/src/cmd/internal/rsc.io/arm/armasm/plan9x.go b/src/cmd/internal/rsc.io/arm/armasm/plan9x.go
new file mode 100644
index 0000000..952c519
--- /dev/null
+++ b/src/cmd/internal/rsc.io/arm/armasm/plan9x.go
@@ -0,0 +1,211 @@
+// 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 armasm
+
+import (
+	"bytes"
+	"encoding/binary"
+	"fmt"
+	"io"
+	"strings"
+)
+
+// Plan9Syntax returns the Go assembler syntax for the instruction.
+// The syntax was originally defined by Plan 9.
+// The pc is the program counter of the instruction, used for expanding
+// PC-relative addresses into absolute ones.
+// The symname function queries the symbol table for the program
+// being disassembled. Given a target address it returns the name and base
+// address of the symbol containing the target, if any; otherwise it returns "", 0.
+// The reader r should read from the text segment using text addresses
+// as offsets; it is used to display pc-relative loads as constant loads.
+func Plan9Syntax(inst Inst, pc uint64, symname func(uint64) (string, uint64), text io.ReaderAt) string {
+	if symname == nil {
+		symname = func(uint64) (string, uint64) { return "", 0 }
+	}
+
+	var args []string
+	for _, a := range inst.Args {
+		if a == nil {
+			break
+		}
+		args = append(args, plan9Arg(&inst, pc, symname, a))
+	}
+
+	op := inst.Op.String()
+
+	switch inst.Op &^ 15 {
+	case LDR_EQ, LDRB_EQ, LDRH_EQ:
+		// Check for RET
+		reg, _ := inst.Args[0].(Reg)
+		mem, _ := inst.Args[1].(Mem)
+		if inst.Op&^15 == LDR_EQ && reg == R15 && mem.Base == SP && mem.Sign == 0 && mem.Mode == AddrPostIndex {
+			return fmt.Sprintf("RET%s #%d", op[3:], mem.Offset)
+		}
+
+		// Check for PC-relative load.
+		if mem.Base == PC && mem.Sign == 0 && mem.Mode == AddrOffset && text != nil {
+			addr := uint32(pc) + 8 + uint32(mem.Offset)
+			buf := make([]byte, 4)
+			switch inst.Op &^ 15 {
+			case LDRB_EQ:
+				if _, err := text.ReadAt(buf[:1], int64(addr)); err != nil {
+					break
+				}
+				args[1] = fmt.Sprintf("$%#x", buf[0])
+
+			case LDRH_EQ:
+				if _, err := text.ReadAt(buf[:2], int64(addr)); err != nil {
+					break
+				}
+				args[1] = fmt.Sprintf("$%#x", binary.LittleEndian.Uint16(buf))
+
+			case LDR_EQ:
+				if _, err := text.ReadAt(buf, int64(addr)); err != nil {
+					break
+				}
+				x := binary.LittleEndian.Uint32(buf)
+				if s, base := symname(uint64(x)); s != "" && uint64(x) == base {
+					args[1] = fmt.Sprintf("$%s(SB)", s)
+				} else {
+					args[1] = fmt.Sprintf("$%#x", x)
+				}
+			}
+		}
+	}
+
+	// Move addressing mode into opcode suffix.
+	suffix := ""
+	switch inst.Op &^ 15 {
+	case LDR_EQ, LDRB_EQ, LDRH_EQ, STR_EQ, STRB_EQ, STRH_EQ:
+		mem, _ := inst.Args[1].(Mem)
+		switch mem.Mode {
+		case AddrOffset, AddrLDM:
+			// no suffix
+		case AddrPreIndex, AddrLDM_WB:
+			suffix = ".W"
+		case AddrPostIndex:
+			suffix = ".P"
+		}
+		off := ""
+		if mem.Offset != 0 {
+			off = fmt.Sprintf("%#x", mem.Offset)
+		}
+		base := fmt.Sprintf("(R%d)", int(mem.Base))
+		index := ""
+		if mem.Sign != 0 {
+			sign := ""
+			if mem.Sign < 0 {
+				sign = ""
+			}
+			shift := ""
+			if mem.Count != 0 {
+				shift = fmt.Sprintf("%s%d", plan9Shift[mem.Shift], mem.Count)
+			}
+			index = fmt.Sprintf("(%sR%d%s)", sign, int(mem.Index), shift)
+		}
+		args[1] = off + base + index
+	}
+
+	// Reverse args, placing dest last.
+	for i, j := 0, len(args)-1; i < j; i, j = i+1, j-1 {
+		args[i], args[j] = args[j], args[i]
+	}
+
+	switch inst.Op &^ 15 {
+	case MOV_EQ:
+		op = "MOVW" + op[3:]
+
+	case LDR_EQ:
+		op = "MOVW" + op[3:] + suffix
+	case LDRB_EQ:
+		op = "MOVB" + op[4:] + suffix
+	case LDRH_EQ:
+		op = "MOVH" + op[4:] + suffix
+
+	case STR_EQ:
+		op = "MOVW" + op[3:] + suffix
+		args[0], args[1] = args[1], args[0]
+	case STRB_EQ:
+		op = "MOVB" + op[4:] + suffix
+		args[0], args[1] = args[1], args[0]
+	case STRH_EQ:
+		op = "MOVH" + op[4:] + suffix
+		args[0], args[1] = args[1], args[0]
+	}
+
+	if args != nil {
+		op += " " + strings.Join(args, ", ")
+	}
+
+	return op
+}
+
+// assembler syntax for the various shifts.
+// @x> is a lie; the assembler uses @> 0
+// instead of @x> 1, but i wanted to be clear that it
+// was a different operation (rotate right extended, not rotate right).
+var plan9Shift = []string{"<<", ">>", "->", "@>", "@x>"}
+
+func plan9Arg(inst *Inst, pc uint64, symname func(uint64) (string, uint64), arg Arg) string {
+	switch a := arg.(type) {
+	case Endian:
+
+	case Imm:
+		return fmt.Sprintf("$%d", int(a))
+
+	case Mem:
+
+	case PCRel:
+		addr := uint32(pc) + 8 + uint32(a)
+		if s, base := symname(uint64(addr)); s != "" && uint64(addr) == base {
+			return fmt.Sprintf("%s(SB)", s)
+		}
+		return fmt.Sprintf("%#x", addr)
+
+	case Reg:
+		if a < 16 {
+			return fmt.Sprintf("R%d", int(a))
+		}
+
+	case RegList:
+		var buf bytes.Buffer
+		start := -2
+		end := -2
+		fmt.Fprintf(&buf, "[")
+		flush := func() {
+			if start >= 0 {
+				if buf.Len() > 1 {
+					fmt.Fprintf(&buf, ",")
+				}
+				if start == end {
+					fmt.Fprintf(&buf, "R%d", start)
+				} else {
+					fmt.Fprintf(&buf, "R%d-R%d", start, end)
+				}
+			}
+		}
+		for i := 0; i < 16; i++ {
+			if a&(1<<uint(i)) != 0 {
+				if i == end+1 {
+					end++
+					continue
+				}
+				start = i
+				end = i
+			}
+		}
+		flush()
+		fmt.Fprintf(&buf, "]")
+		return buf.String()
+
+	case RegShift:
+		return fmt.Sprintf("R%d%s$%d", int(a.Reg), plan9Shift[a.Shift], int(a.Count))
+
+	case RegShiftReg:
+		return fmt.Sprintf("R%d%sR%d", int(a.Reg), plan9Shift[a.Shift], int(a.RegCount))
+	}
+	return strings.ToUpper(arg.String())
+}
diff --git a/src/cmd/internal/rsc.io/arm/armasm/tables.go b/src/cmd/internal/rsc.io/arm/armasm/tables.go
new file mode 100644
index 0000000..58f51fe
--- /dev/null
+++ b/src/cmd/internal/rsc.io/arm/armasm/tables.go
@@ -0,0 +1,9448 @@
+package armasm
+
+const (
+	_ Op = iota
+	_
+	_
+	_
+	_
+	_
+	_
+	_
+	_
+	_
+	_
+	_
+	_
+	_
+	_
+	_
+	ADC_EQ
+	ADC_NE
+	ADC_CS
+	ADC_CC
+	ADC_MI
+	ADC_PL
+	ADC_VS
+	ADC_VC
+	ADC_HI
+	ADC_LS
+	ADC_GE
+	ADC_LT
+	ADC_GT
+	ADC_LE
+	ADC
+	ADC_ZZ
+	ADC_S_EQ
+	ADC_S_NE
+	ADC_S_CS
+	ADC_S_CC
+	ADC_S_MI
+	ADC_S_PL
+	ADC_S_VS
+	ADC_S_VC
+	ADC_S_HI
+	ADC_S_LS
+	ADC_S_GE
+	ADC_S_LT
+	ADC_S_GT
+	ADC_S_LE
+	ADC_S
+	ADC_S_ZZ
+	ADD_EQ
+	ADD_NE
+	ADD_CS
+	ADD_CC
+	ADD_MI
+	ADD_PL
+	ADD_VS
+	ADD_VC
+	ADD_HI
+	ADD_LS
+	ADD_GE
+	ADD_LT
+	ADD_GT
+	ADD_LE
+	ADD
+	ADD_ZZ
+	ADD_S_EQ
+	ADD_S_NE
+	ADD_S_CS
+	ADD_S_CC
+	ADD_S_MI
+	ADD_S_PL
+	ADD_S_VS
+	ADD_S_VC
+	ADD_S_HI
+	ADD_S_LS
+	ADD_S_GE
+	ADD_S_LT
+	ADD_S_GT
+	ADD_S_LE
+	ADD_S
+	ADD_S_ZZ
+	AND_EQ
+	AND_NE
+	AND_CS
+	AND_CC
+	AND_MI
+	AND_PL
+	AND_VS
+	AND_VC
+	AND_HI
+	AND_LS
+	AND_GE
+	AND_LT
+	AND_GT
+	AND_LE
+	AND
+	AND_ZZ
+	AND_S_EQ
+	AND_S_NE
+	AND_S_CS
+	AND_S_CC
+	AND_S_MI
+	AND_S_PL
+	AND_S_VS
+	AND_S_VC
+	AND_S_HI
+	AND_S_LS
+	AND_S_GE
+	AND_S_LT
+	AND_S_GT
+	AND_S_LE
+	AND_S
+	AND_S_ZZ
+	ASR_EQ
+	ASR_NE
+	ASR_CS
+	ASR_CC
+	ASR_MI
+	ASR_PL
+	ASR_VS
+	ASR_VC
+	ASR_HI
+	ASR_LS
+	ASR_GE
+	ASR_LT
+	ASR_GT
+	ASR_LE
+	ASR
+	ASR_ZZ
+	ASR_S_EQ
+	ASR_S_NE
+	ASR_S_CS
+	ASR_S_CC
+	ASR_S_MI
+	ASR_S_PL
+	ASR_S_VS
+	ASR_S_VC
+	ASR_S_HI
+	ASR_S_LS
+	ASR_S_GE
+	ASR_S_LT
+	ASR_S_GT
+	ASR_S_LE
+	ASR_S
+	ASR_S_ZZ
+	B_EQ
+	B_NE
+	B_CS
+	B_CC
+	B_MI
+	B_PL
+	B_VS
+	B_VC
+	B_HI
+	B_LS
+	B_GE
+	B_LT
+	B_GT
+	B_LE
+	B
+	B_ZZ
+	BFC_EQ
+	BFC_NE
+	BFC_CS
+	BFC_CC
+	BFC_MI
+	BFC_PL
+	BFC_VS
+	BFC_VC
+	BFC_HI
+	BFC_LS
+	BFC_GE
+	BFC_LT
+	BFC_GT
+	BFC_LE
+	BFC
+	BFC_ZZ
+	BFI_EQ
+	BFI_NE
+	BFI_CS
+	BFI_CC
+	BFI_MI
+	BFI_PL
+	BFI_VS
+	BFI_VC
+	BFI_HI
+	BFI_LS
+	BFI_GE
+	BFI_LT
+	BFI_GT
+	BFI_LE
+	BFI
+	BFI_ZZ
+	BIC_EQ
+	BIC_NE
+	BIC_CS
+	BIC_CC
+	BIC_MI
+	BIC_PL
+	BIC_VS
+	BIC_VC
+	BIC_HI
+	BIC_LS
+	BIC_GE
+	BIC_LT
+	BIC_GT
+	BIC_LE
+	BIC
+	BIC_ZZ
+	BIC_S_EQ
+	BIC_S_NE
+	BIC_S_CS
+	BIC_S_CC
+	BIC_S_MI
+	BIC_S_PL
+	BIC_S_VS
+	BIC_S_VC
+	BIC_S_HI
+	BIC_S_LS
+	BIC_S_GE
+	BIC_S_LT
+	BIC_S_GT
+	BIC_S_LE
+	BIC_S
+	BIC_S_ZZ
+	BKPT_EQ
+	BKPT_NE
+	BKPT_CS
+	BKPT_CC
+	BKPT_MI
+	BKPT_PL
+	BKPT_VS
+	BKPT_VC
+	BKPT_HI
+	BKPT_LS
+	BKPT_GE
+	BKPT_LT
+	BKPT_GT
+	BKPT_LE
+	BKPT
+	BKPT_ZZ
+	BL_EQ
+	BL_NE
+	BL_CS
+	BL_CC
+	BL_MI
+	BL_PL
+	BL_VS
+	BL_VC
+	BL_HI
+	BL_LS
+	BL_GE
+	BL_LT
+	BL_GT
+	BL_LE
+	BL
+	BL_ZZ
+	BLX_EQ
+	BLX_NE
+	BLX_CS
+	BLX_CC
+	BLX_MI
+	BLX_PL
+	BLX_VS
+	BLX_VC
+	BLX_HI
+	BLX_LS
+	BLX_GE
+	BLX_LT
+	BLX_GT
+	BLX_LE
+	BLX
+	BLX_ZZ
+	BX_EQ
+	BX_NE
+	BX_CS
+	BX_CC
+	BX_MI
+	BX_PL
+	BX_VS
+	BX_VC
+	BX_HI
+	BX_LS
+	BX_GE
+	BX_LT
+	BX_GT
+	BX_LE
+	BX
+	BX_ZZ
+	BXJ_EQ
+	BXJ_NE
+	BXJ_CS
+	BXJ_CC
+	BXJ_MI
+	BXJ_PL
+	BXJ_VS
+	BXJ_VC
+	BXJ_HI
+	BXJ_LS
+	BXJ_GE
+	BXJ_LT
+	BXJ_GT
+	BXJ_LE
+	BXJ
+	BXJ_ZZ
+	CLREX
+	_
+	_
+	_
+	_
+	_
+	_
+	_
+	_
+	_
+	_
+	_
+	_
+	_
+	_
+	_
+	CLZ_EQ
+	CLZ_NE
+	CLZ_CS
+	CLZ_CC
+	CLZ_MI
+	CLZ_PL
+	CLZ_VS
+	CLZ_VC
+	CLZ_HI
+	CLZ_LS
+	CLZ_GE
+	CLZ_LT
+	CLZ_GT
+	CLZ_LE
+	CLZ
+	CLZ_ZZ
+	CMN_EQ
+	CMN_NE
+	CMN_CS
+	CMN_CC
+	CMN_MI
+	CMN_PL
+	CMN_VS
+	CMN_VC
+	CMN_HI
+	CMN_LS
+	CMN_GE
+	CMN_LT
+	CMN_GT
+	CMN_LE
+	CMN
+	CMN_ZZ
+	CMP_EQ
+	CMP_NE
+	CMP_CS
+	CMP_CC
+	CMP_MI
+	CMP_PL
+	CMP_VS
+	CMP_VC
+	CMP_HI
+	CMP_LS
+	CMP_GE
+	CMP_LT
+	CMP_GT
+	CMP_LE
+	CMP
+	CMP_ZZ
+	DBG_EQ
+	DBG_NE
+	DBG_CS
+	DBG_CC
+	DBG_MI
+	DBG_PL
+	DBG_VS
+	DBG_VC
+	DBG_HI
+	DBG_LS
+	DBG_GE
+	DBG_LT
+	DBG_GT
+	DBG_LE
+	DBG
+	DBG_ZZ
+	DMB
+	DSB
+	_
+	_
+	_
+	_
+	_
+	_
+	_
+	_
+	_
+	_
+	_
+	_
+	_
+	_
+	EOR_EQ
+	EOR_NE
+	EOR_CS
+	EOR_CC
+	EOR_MI
+	EOR_PL
+	EOR_VS
+	EOR_VC
+	EOR_HI
+	EOR_LS
+	EOR_GE
+	EOR_LT
+	EOR_GT
+	EOR_LE
+	EOR
+	EOR_ZZ
+	EOR_S_EQ
+	EOR_S_NE
+	EOR_S_CS
+	EOR_S_CC
+	EOR_S_MI
+	EOR_S_PL
+	EOR_S_VS
+	EOR_S_VC
+	EOR_S_HI
+	EOR_S_LS
+	EOR_S_GE
+	EOR_S_LT
+	EOR_S_GT
+	EOR_S_LE
+	EOR_S
+	EOR_S_ZZ
+	ISB
+	_
+	_
+	_
+	_
+	_
+	_
+	_
+	_
+	_
+	_
+	_
+	_
+	_
+	_
+	_
+	LDM_EQ
+	LDM_NE
+	LDM_CS
+	LDM_CC
+	LDM_MI
+	LDM_PL
+	LDM_VS
+	LDM_VC
+	LDM_HI
+	LDM_LS
+	LDM_GE
+	LDM_LT
+	LDM_GT
+	LDM_LE
+	LDM
+	LDM_ZZ
+	LDMDA_EQ
+	LDMDA_NE
+	LDMDA_CS
+	LDMDA_CC
+	LDMDA_MI
+	LDMDA_PL
+	LDMDA_VS
+	LDMDA_VC
+	LDMDA_HI
+	LDMDA_LS
+	LDMDA_GE
+	LDMDA_LT
+	LDMDA_GT
+	LDMDA_LE
+	LDMDA
+	LDMDA_ZZ
+	LDMDB_EQ
+	LDMDB_NE
+	LDMDB_CS
+	LDMDB_CC
+	LDMDB_MI
+	LDMDB_PL
+	LDMDB_VS
+	LDMDB_VC
+	LDMDB_HI
+	LDMDB_LS
+	LDMDB_GE
+	LDMDB_LT
+	LDMDB_GT
+	LDMDB_LE
+	LDMDB
+	LDMDB_ZZ
+	LDMIB_EQ
+	LDMIB_NE
+	LDMIB_CS
+	LDMIB_CC
+	LDMIB_MI
+	LDMIB_PL
+	LDMIB_VS
+	LDMIB_VC
+	LDMIB_HI
+	LDMIB_LS
+	LDMIB_GE
+	LDMIB_LT
+	LDMIB_GT
+	LDMIB_LE
+	LDMIB
+	LDMIB_ZZ
+	LDR_EQ
+	LDR_NE
+	LDR_CS
+	LDR_CC
+	LDR_MI
+	LDR_PL
+	LDR_VS
+	LDR_VC
+	LDR_HI
+	LDR_LS
+	LDR_GE
+	LDR_LT
+	LDR_GT
+	LDR_LE
+	LDR
+	LDR_ZZ
+	LDRB_EQ
+	LDRB_NE
+	LDRB_CS
+	LDRB_CC
+	LDRB_MI
+	LDRB_PL
+	LDRB_VS
+	LDRB_VC
+	LDRB_HI
+	LDRB_LS
+	LDRB_GE
+	LDRB_LT
+	LDRB_GT
+	LDRB_LE
+	LDRB
+	LDRB_ZZ
+	LDRBT_EQ
+	LDRBT_NE
+	LDRBT_CS
+	LDRBT_CC
+	LDRBT_MI
+	LDRBT_PL
+	LDRBT_VS
+	LDRBT_VC
+	LDRBT_HI
+	LDRBT_LS
+	LDRBT_GE
+	LDRBT_LT
+	LDRBT_GT
+	LDRBT_LE
+	LDRBT
+	LDRBT_ZZ
+	LDRD_EQ
+	LDRD_NE
+	LDRD_CS
+	LDRD_CC
+	LDRD_MI
+	LDRD_PL
+	LDRD_VS
+	LDRD_VC
+	LDRD_HI
+	LDRD_LS
+	LDRD_GE
+	LDRD_LT
+	LDRD_GT
+	LDRD_LE
+	LDRD
+	LDRD_ZZ
+	LDREX_EQ
+	LDREX_NE
+	LDREX_CS
+	LDREX_CC
+	LDREX_MI
+	LDREX_PL
+	LDREX_VS
+	LDREX_VC
+	LDREX_HI
+	LDREX_LS
+	LDREX_GE
+	LDREX_LT
+	LDREX_GT
+	LDREX_LE
+	LDREX
+	LDREX_ZZ
+	LDREXB_EQ
+	LDREXB_NE
+	LDREXB_CS
+	LDREXB_CC
+	LDREXB_MI
+	LDREXB_PL
+	LDREXB_VS
+	LDREXB_VC
+	LDREXB_HI
+	LDREXB_LS
+	LDREXB_GE
+	LDREXB_LT
+	LDREXB_GT
+	LDREXB_LE
+	LDREXB
+	LDREXB_ZZ
+	LDREXD_EQ
+	LDREXD_NE
+	LDREXD_CS
+	LDREXD_CC
+	LDREXD_MI
+	LDREXD_PL
+	LDREXD_VS
+	LDREXD_VC
+	LDREXD_HI
+	LDREXD_LS
+	LDREXD_GE
+	LDREXD_LT
+	LDREXD_GT
+	LDREXD_LE
+	LDREXD
+	LDREXD_ZZ
+	LDREXH_EQ
+	LDREXH_NE
+	LDREXH_CS
+	LDREXH_CC
+	LDREXH_MI
+	LDREXH_PL
+	LDREXH_VS
+	LDREXH_VC
+	LDREXH_HI
+	LDREXH_LS
+	LDREXH_GE
+	LDREXH_LT
+	LDREXH_GT
+	LDREXH_LE
+	LDREXH
+	LDREXH_ZZ
+	LDRH_EQ
+	LDRH_NE
+	LDRH_CS
+	LDRH_CC
+	LDRH_MI
+	LDRH_PL
+	LDRH_VS
+	LDRH_VC
+	LDRH_HI
+	LDRH_LS
+	LDRH_GE
+	LDRH_LT
+	LDRH_GT
+	LDRH_LE
+	LDRH
+	LDRH_ZZ
+	LDRHT_EQ
+	LDRHT_NE
+	LDRHT_CS
+	LDRHT_CC
+	LDRHT_MI
+	LDRHT_PL
+	LDRHT_VS
+	LDRHT_VC
+	LDRHT_HI
+	LDRHT_LS
+	LDRHT_GE
+	LDRHT_LT
+	LDRHT_GT
+	LDRHT_LE
+	LDRHT
+	LDRHT_ZZ
+	LDRSB_EQ
+	LDRSB_NE
+	LDRSB_CS
+	LDRSB_CC
+	LDRSB_MI
+	LDRSB_PL
+	LDRSB_VS
+	LDRSB_VC
+	LDRSB_HI
+	LDRSB_LS
+	LDRSB_GE
+	LDRSB_LT
+	LDRSB_GT
+	LDRSB_LE
+	LDRSB
+	LDRSB_ZZ
+	LDRSBT_EQ
+	LDRSBT_NE
+	LDRSBT_CS
+	LDRSBT_CC
+	LDRSBT_MI
+	LDRSBT_PL
+	LDRSBT_VS
+	LDRSBT_VC
+	LDRSBT_HI
+	LDRSBT_LS
+	LDRSBT_GE
+	LDRSBT_LT
+	LDRSBT_GT
+	LDRSBT_LE
+	LDRSBT
+	LDRSBT_ZZ
+	LDRSH_EQ
+	LDRSH_NE
+	LDRSH_CS
+	LDRSH_CC
+	LDRSH_MI
+	LDRSH_PL
+	LDRSH_VS
+	LDRSH_VC
+	LDRSH_HI
+	LDRSH_LS
+	LDRSH_GE
+	LDRSH_LT
+	LDRSH_GT
+	LDRSH_LE
+	LDRSH
+	LDRSH_ZZ
+	LDRSHT_EQ
+	LDRSHT_NE
+	LDRSHT_CS
+	LDRSHT_CC
+	LDRSHT_MI
+	LDRSHT_PL
+	LDRSHT_VS
+	LDRSHT_VC
+	LDRSHT_HI
+	LDRSHT_LS
+	LDRSHT_GE
+	LDRSHT_LT
+	LDRSHT_GT
+	LDRSHT_LE
+	LDRSHT
+	LDRSHT_ZZ
+	LDRT_EQ
+	LDRT_NE
+	LDRT_CS
+	LDRT_CC
+	LDRT_MI
+	LDRT_PL
+	LDRT_VS
+	LDRT_VC
+	LDRT_HI
+	LDRT_LS
+	LDRT_GE
+	LDRT_LT
+	LDRT_GT
+	LDRT_LE
+	LDRT
+	LDRT_ZZ
+	LSL_EQ
+	LSL_NE
+	LSL_CS
+	LSL_CC
+	LSL_MI
+	LSL_PL
+	LSL_VS
+	LSL_VC
+	LSL_HI
+	LSL_LS
+	LSL_GE
+	LSL_LT
+	LSL_GT
+	LSL_LE
+	LSL
+	LSL_ZZ
+	LSL_S_EQ
+	LSL_S_NE
+	LSL_S_CS
+	LSL_S_CC
+	LSL_S_MI
+	LSL_S_PL
+	LSL_S_VS
+	LSL_S_VC
+	LSL_S_HI
+	LSL_S_LS
+	LSL_S_GE
+	LSL_S_LT
+	LSL_S_GT
+	LSL_S_LE
+	LSL_S
+	LSL_S_ZZ
+	LSR_EQ
+	LSR_NE
+	LSR_CS
+	LSR_CC
+	LSR_MI
+	LSR_PL
+	LSR_VS
+	LSR_VC
+	LSR_HI
+	LSR_LS
+	LSR_GE
+	LSR_LT
+	LSR_GT
+	LSR_LE
+	LSR
+	LSR_ZZ
+	LSR_S_EQ
+	LSR_S_NE
+	LSR_S_CS
+	LSR_S_CC
+	LSR_S_MI
+	LSR_S_PL
+	LSR_S_VS
+	LSR_S_VC
+	LSR_S_HI
+	LSR_S_LS
+	LSR_S_GE
+	LSR_S_LT
+	LSR_S_GT
+	LSR_S_LE
+	LSR_S
+	LSR_S_ZZ
+	MLA_EQ
+	MLA_NE
+	MLA_CS
+	MLA_CC
+	MLA_MI
+	MLA_PL
+	MLA_VS
+	MLA_VC
+	MLA_HI
+	MLA_LS
+	MLA_GE
+	MLA_LT
+	MLA_GT
+	MLA_LE
+	MLA
+	MLA_ZZ
+	MLA_S_EQ
+	MLA_S_NE
+	MLA_S_CS
+	MLA_S_CC
+	MLA_S_MI
+	MLA_S_PL
+	MLA_S_VS
+	MLA_S_VC
+	MLA_S_HI
+	MLA_S_LS
+	MLA_S_GE
+	MLA_S_LT
+	MLA_S_GT
+	MLA_S_LE
+	MLA_S
+	MLA_S_ZZ
+	MLS_EQ
+	MLS_NE
+	MLS_CS
+	MLS_CC
+	MLS_MI
+	MLS_PL
+	MLS_VS
+	MLS_VC
+	MLS_HI
+	MLS_LS
+	MLS_GE
+	MLS_LT
+	MLS_GT
+	MLS_LE
+	MLS
+	MLS_ZZ
+	MOV_EQ
+	MOV_NE
+	MOV_CS
+	MOV_CC
+	MOV_MI
+	MOV_PL
+	MOV_VS
+	MOV_VC
+	MOV_HI
+	MOV_LS
+	MOV_GE
+	MOV_LT
+	MOV_GT
+	MOV_LE
+	MOV
+	MOV_ZZ
+	MOV_S_EQ
+	MOV_S_NE
+	MOV_S_CS
+	MOV_S_CC
+	MOV_S_MI
+	MOV_S_PL
+	MOV_S_VS
+	MOV_S_VC
+	MOV_S_HI
+	MOV_S_LS
+	MOV_S_GE
+	MOV_S_LT
+	MOV_S_GT
+	MOV_S_LE
+	MOV_S
+	MOV_S_ZZ
+	MOVT_EQ
+	MOVT_NE
+	MOVT_CS
+	MOVT_CC
+	MOVT_MI
+	MOVT_PL
+	MOVT_VS
+	MOVT_VC
+	MOVT_HI
+	MOVT_LS
+	MOVT_GE
+	MOVT_LT
+	MOVT_GT
+	MOVT_LE
+	MOVT
+	MOVT_ZZ
+	MOVW_EQ
+	MOVW_NE
+	MOVW_CS
+	MOVW_CC
+	MOVW_MI
+	MOVW_PL
+	MOVW_VS
+	MOVW_VC
+	MOVW_HI
+	MOVW_LS
+	MOVW_GE
+	MOVW_LT
+	MOVW_GT
+	MOVW_LE
+	MOVW
+	MOVW_ZZ
+	MRS_EQ
+	MRS_NE
+	MRS_CS
+	MRS_CC
+	MRS_MI
+	MRS_PL
+	MRS_VS
+	MRS_VC
+	MRS_HI
+	MRS_LS
+	MRS_GE
+	MRS_LT
+	MRS_GT
+	MRS_LE
+	MRS
+	MRS_ZZ
+	MUL_EQ
+	MUL_NE
+	MUL_CS
+	MUL_CC
+	MUL_MI
+	MUL_PL
+	MUL_VS
+	MUL_VC
+	MUL_HI
+	MUL_LS
+	MUL_GE
+	MUL_LT
+	MUL_GT
+	MUL_LE
+	MUL
+	MUL_ZZ
+	MUL_S_EQ
+	MUL_S_NE
+	MUL_S_CS
+	MUL_S_CC
+	MUL_S_MI
+	MUL_S_PL
+	MUL_S_VS
+	MUL_S_VC
+	MUL_S_HI
+	MUL_S_LS
+	MUL_S_GE
+	MUL_S_LT
+	MUL_S_GT
+	MUL_S_LE
+	MUL_S
+	MUL_S_ZZ
+	MVN_EQ
+	MVN_NE
+	MVN_CS
+	MVN_CC
+	MVN_MI
+	MVN_PL
+	MVN_VS
+	MVN_VC
+	MVN_HI
+	MVN_LS
+	MVN_GE
+	MVN_LT
+	MVN_GT
+	MVN_LE
+	MVN
+	MVN_ZZ
+	MVN_S_EQ
+	MVN_S_NE
+	MVN_S_CS
+	MVN_S_CC
+	MVN_S_MI
+	MVN_S_PL
+	MVN_S_VS
+	MVN_S_VC
+	MVN_S_HI
+	MVN_S_LS
+	MVN_S_GE
+	MVN_S_LT
+	MVN_S_GT
+	MVN_S_LE
+	MVN_S
+	MVN_S_ZZ
+	NOP_EQ
+	NOP_NE
+	NOP_CS
+	NOP_CC
+	NOP_MI
+	NOP_PL
+	NOP_VS
+	NOP_VC
+	NOP_HI
+	NOP_LS
+	NOP_GE
+	NOP_LT
+	NOP_GT
+	NOP_LE
+	NOP
+	NOP_ZZ
+	ORR_EQ
+	ORR_NE
+	ORR_CS
+	ORR_CC
+	ORR_MI
+	ORR_PL
+	ORR_VS
+	ORR_VC
+	ORR_HI
+	ORR_LS
+	ORR_GE
+	ORR_LT
+	ORR_GT
+	ORR_LE
+	ORR
+	ORR_ZZ
+	ORR_S_EQ
+	ORR_S_NE
+	ORR_S_CS
+	ORR_S_CC
+	ORR_S_MI
+	ORR_S_PL
+	ORR_S_VS
+	ORR_S_VC
+	ORR_S_HI
+	ORR_S_LS
+	ORR_S_GE
+	ORR_S_LT
+	ORR_S_GT
+	ORR_S_LE
+	ORR_S
+	ORR_S_ZZ
+	PKHBT_EQ
+	PKHBT_NE
+	PKHBT_CS
+	PKHBT_CC
+	PKHBT_MI
+	PKHBT_PL
+	PKHBT_VS
+	PKHBT_VC
+	PKHBT_HI
+	PKHBT_LS
+	PKHBT_GE
+	PKHBT_LT
+	PKHBT_GT
+	PKHBT_LE
+	PKHBT
+	PKHBT_ZZ
+	PKHTB_EQ
+	PKHTB_NE
+	PKHTB_CS
+	PKHTB_CC
+	PKHTB_MI
+	PKHTB_PL
+	PKHTB_VS
+	PKHTB_VC
+	PKHTB_HI
+	PKHTB_LS
+	PKHTB_GE
+	PKHTB_LT
+	PKHTB_GT
+	PKHTB_LE
+	PKHTB
+	PKHTB_ZZ
+	PLD_W
+	PLD
+	PLI
+	_
+	_
+	_
+	_
+	_
+	_
+	_
+	_
+	_
+	_
+	_
+	_
+	_
+	POP_EQ
+	POP_NE
+	POP_CS
+	POP_CC
+	POP_MI
+	POP_PL
+	POP_VS
+	POP_VC
+	POP_HI
+	POP_LS
+	POP_GE
+	POP_LT
+	POP_GT
+	POP_LE
+	POP
+	POP_ZZ
+	PUSH_EQ
+	PUSH_NE
+	PUSH_CS
+	PUSH_CC
+	PUSH_MI
+	PUSH_PL
+	PUSH_VS
+	PUSH_VC
+	PUSH_HI
+	PUSH_LS
+	PUSH_GE
+	PUSH_LT
+	PUSH_GT
+	PUSH_LE
+	PUSH
+	PUSH_ZZ
+	QADD_EQ
+	QADD_NE
+	QADD_CS
+	QADD_CC
+	QADD_MI
+	QADD_PL
+	QADD_VS
+	QADD_VC
+	QADD_HI
+	QADD_LS
+	QADD_GE
+	QADD_LT
+	QADD_GT
+	QADD_LE
+	QADD
+	QADD_ZZ
+	QADD16_EQ
+	QADD16_NE
+	QADD16_CS
+	QADD16_CC
+	QADD16_MI
+	QADD16_PL
+	QADD16_VS
+	QADD16_VC
+	QADD16_HI
+	QADD16_LS
+	QADD16_GE
+	QADD16_LT
+	QADD16_GT
+	QADD16_LE
+	QADD16
+	QADD16_ZZ
+	QADD8_EQ
+	QADD8_NE
+	QADD8_CS
+	QADD8_CC
+	QADD8_MI
+	QADD8_PL
+	QADD8_VS
+	QADD8_VC
+	QADD8_HI
+	QADD8_LS
+	QADD8_GE
+	QADD8_LT
+	QADD8_GT
+	QADD8_LE
+	QADD8
+	QADD8_ZZ
+	QASX_EQ
+	QASX_NE
+	QASX_CS
+	QASX_CC
+	QASX_MI
+	QASX_PL
+	QASX_VS
+	QASX_VC
+	QASX_HI
+	QASX_LS
+	QASX_GE
+	QASX_LT
+	QASX_GT
+	QASX_LE
+	QASX
+	QASX_ZZ
+	QDADD_EQ
+	QDADD_NE
+	QDADD_CS
+	QDADD_CC
+	QDADD_MI
+	QDADD_PL
+	QDADD_VS
+	QDADD_VC
+	QDADD_HI
+	QDADD_LS
+	QDADD_GE
+	QDADD_LT
+	QDADD_GT
+	QDADD_LE
+	QDADD
+	QDADD_ZZ
+	QDSUB_EQ
+	QDSUB_NE
+	QDSUB_CS
+	QDSUB_CC
+	QDSUB_MI
+	QDSUB_PL
+	QDSUB_VS
+	QDSUB_VC
+	QDSUB_HI
+	QDSUB_LS
+	QDSUB_GE
+	QDSUB_LT
+	QDSUB_GT
+	QDSUB_LE
+	QDSUB
+	QDSUB_ZZ
+	QSAX_EQ
+	QSAX_NE
+	QSAX_CS
+	QSAX_CC
+	QSAX_MI
+	QSAX_PL
+	QSAX_VS
+	QSAX_VC
+	QSAX_HI
+	QSAX_LS
+	QSAX_GE
+	QSAX_LT
+	QSAX_GT
+	QSAX_LE
+	QSAX
+	QSAX_ZZ
+	QSUB_EQ
+	QSUB_NE
+	QSUB_CS
+	QSUB_CC
+	QSUB_MI
+	QSUB_PL
+	QSUB_VS
+	QSUB_VC
+	QSUB_HI
+	QSUB_LS
+	QSUB_GE
+	QSUB_LT
+	QSUB_GT
+	QSUB_LE
+	QSUB
+	QSUB_ZZ
+	QSUB16_EQ
+	QSUB16_NE
+	QSUB16_CS
+	QSUB16_CC
+	QSUB16_MI
+	QSUB16_PL
+	QSUB16_VS
+	QSUB16_VC
+	QSUB16_HI
+	QSUB16_LS
+	QSUB16_GE
+	QSUB16_LT
+	QSUB16_GT
+	QSUB16_LE
+	QSUB16
+	QSUB16_ZZ
+	QSUB8_EQ
+	QSUB8_NE
+	QSUB8_CS
+	QSUB8_CC
+	QSUB8_MI
+	QSUB8_PL
+	QSUB8_VS
+	QSUB8_VC
+	QSUB8_HI
+	QSUB8_LS
+	QSUB8_GE
+	QSUB8_LT
+	QSUB8_GT
+	QSUB8_LE
+	QSUB8
+	QSUB8_ZZ
+	RBIT_EQ
+	RBIT_NE
+	RBIT_CS
+	RBIT_CC
+	RBIT_MI
+	RBIT_PL
+	RBIT_VS
+	RBIT_VC
+	RBIT_HI
+	RBIT_LS
+	RBIT_GE
+	RBIT_LT
+	RBIT_GT
+	RBIT_LE
+	RBIT
+	RBIT_ZZ
+	REV_EQ
+	REV_NE
+	REV_CS
+	REV_CC
+	REV_MI
+	REV_PL
+	REV_VS
+	REV_VC
+	REV_HI
+	REV_LS
+	REV_GE
+	REV_LT
+	REV_GT
+	REV_LE
+	REV
+	REV_ZZ
+	REV16_EQ
+	REV16_NE
+	REV16_CS
+	REV16_CC
+	REV16_MI
+	REV16_PL
+	REV16_VS
+	REV16_VC
+	REV16_HI
+	REV16_LS
+	REV16_GE
+	REV16_LT
+	REV16_GT
+	REV16_LE
+	REV16
+	REV16_ZZ
+	REVSH_EQ
+	REVSH_NE
+	REVSH_CS
+	REVSH_CC
+	REVSH_MI
+	REVSH_PL
+	REVSH_VS
+	REVSH_VC
+	REVSH_HI
+	REVSH_LS
+	REVSH_GE
+	REVSH_LT
+	REVSH_GT
+	REVSH_LE
+	REVSH
+	REVSH_ZZ
+	ROR_EQ
+	ROR_NE
+	ROR_CS
+	ROR_CC
+	ROR_MI
+	ROR_PL
+	ROR_VS
+	ROR_VC
+	ROR_HI
+	ROR_LS
+	ROR_GE
+	ROR_LT
+	ROR_GT
+	ROR_LE
+	ROR
+	ROR_ZZ
+	ROR_S_EQ
+	ROR_S_NE
+	ROR_S_CS
+	ROR_S_CC
+	ROR_S_MI
+	ROR_S_PL
+	ROR_S_VS
+	ROR_S_VC
+	ROR_S_HI
+	ROR_S_LS
+	ROR_S_GE
+	ROR_S_LT
+	ROR_S_GT
+	ROR_S_LE
+	ROR_S
+	ROR_S_ZZ
+	RRX_EQ
+	RRX_NE
+	RRX_CS
+	RRX_CC
+	RRX_MI
+	RRX_PL
+	RRX_VS
+	RRX_VC
+	RRX_HI
+	RRX_LS
+	RRX_GE
+	RRX_LT
+	RRX_GT
+	RRX_LE
+	RRX
+	RRX_ZZ
+	RRX_S_EQ
+	RRX_S_NE
+	RRX_S_CS
+	RRX_S_CC
+	RRX_S_MI
+	RRX_S_PL
+	RRX_S_VS
+	RRX_S_VC
+	RRX_S_HI
+	RRX_S_LS
+	RRX_S_GE
+	RRX_S_LT
+	RRX_S_GT
+	RRX_S_LE
+	RRX_S
+	RRX_S_ZZ
+	RSB_EQ
+	RSB_NE
+	RSB_CS
+	RSB_CC
+	RSB_MI
+	RSB_PL
+	RSB_VS
+	RSB_VC
+	RSB_HI
+	RSB_LS
+	RSB_GE
+	RSB_LT
+	RSB_GT
+	RSB_LE
+	RSB
+	RSB_ZZ
+	RSB_S_EQ
+	RSB_S_NE
+	RSB_S_CS
+	RSB_S_CC
+	RSB_S_MI
+	RSB_S_PL
+	RSB_S_VS
+	RSB_S_VC
+	RSB_S_HI
+	RSB_S_LS
+	RSB_S_GE
+	RSB_S_LT
+	RSB_S_GT
+	RSB_S_LE
+	RSB_S
+	RSB_S_ZZ
+	RSC_EQ
+	RSC_NE
+	RSC_CS
+	RSC_CC
+	RSC_MI
+	RSC_PL
+	RSC_VS
+	RSC_VC
+	RSC_HI
+	RSC_LS
+	RSC_GE
+	RSC_LT
+	RSC_GT
+	RSC_LE
+	RSC
+	RSC_ZZ
+	RSC_S_EQ
+	RSC_S_NE
+	RSC_S_CS
+	RSC_S_CC
+	RSC_S_MI
+	RSC_S_PL
+	RSC_S_VS
+	RSC_S_VC
+	RSC_S_HI
+	RSC_S_LS
+	RSC_S_GE
+	RSC_S_LT
+	RSC_S_GT
+	RSC_S_LE
+	RSC_S
+	RSC_S_ZZ
+	SADD16_EQ
+	SADD16_NE
+	SADD16_CS
+	SADD16_CC
+	SADD16_MI
+	SADD16_PL
+	SADD16_VS
+	SADD16_VC
+	SADD16_HI
+	SADD16_LS
+	SADD16_GE
+	SADD16_LT
+	SADD16_GT
+	SADD16_LE
+	SADD16
+	SADD16_ZZ
+	SADD8_EQ
+	SADD8_NE
+	SADD8_CS
+	SADD8_CC
+	SADD8_MI
+	SADD8_PL
+	SADD8_VS
+	SADD8_VC
+	SADD8_HI
+	SADD8_LS
+	SADD8_GE
+	SADD8_LT
+	SADD8_GT
+	SADD8_LE
+	SADD8
+	SADD8_ZZ
+	SASX_EQ
+	SASX_NE
+	SASX_CS
+	SASX_CC
+	SASX_MI
+	SASX_PL
+	SASX_VS
+	SASX_VC
+	SASX_HI
+	SASX_LS
+	SASX_GE
+	SASX_LT
+	SASX_GT
+	SASX_LE
+	SASX
+	SASX_ZZ
+	SBC_EQ
+	SBC_NE
+	SBC_CS
+	SBC_CC
+	SBC_MI
+	SBC_PL
+	SBC_VS
+	SBC_VC
+	SBC_HI
+	SBC_LS
+	SBC_GE
+	SBC_LT
+	SBC_GT
+	SBC_LE
+	SBC
+	SBC_ZZ
+	SBC_S_EQ
+	SBC_S_NE
+	SBC_S_CS
+	SBC_S_CC
+	SBC_S_MI
+	SBC_S_PL
+	SBC_S_VS
+	SBC_S_VC
+	SBC_S_HI
+	SBC_S_LS
+	SBC_S_GE
+	SBC_S_LT
+	SBC_S_GT
+	SBC_S_LE
+	SBC_S
+	SBC_S_ZZ
+	SBFX_EQ
+	SBFX_NE
+	SBFX_CS
+	SBFX_CC
+	SBFX_MI
+	SBFX_PL
+	SBFX_VS
+	SBFX_VC
+	SBFX_HI
+	SBFX_LS
+	SBFX_GE
+	SBFX_LT
+	SBFX_GT
+	SBFX_LE
+	SBFX
+	SBFX_ZZ
+	SEL_EQ
+	SEL_NE
+	SEL_CS
+	SEL_CC
+	SEL_MI
+	SEL_PL
+	SEL_VS
+	SEL_VC
+	SEL_HI
+	SEL_LS
+	SEL_GE
+	SEL_LT
+	SEL_GT
+	SEL_LE
+	SEL
+	SEL_ZZ
+	SETEND
+	_
+	_
+	_
+	_
+	_
+	_
+	_
+	_
+	_
+	_
+	_
+	_
+	_
+	_
+	_
+	SEV_EQ
+	SEV_NE
+	SEV_CS
+	SEV_CC
+	SEV_MI
+	SEV_PL
+	SEV_VS
+	SEV_VC
+	SEV_HI
+	SEV_LS
+	SEV_GE
+	SEV_LT
+	SEV_GT
+	SEV_LE
+	SEV
+	SEV_ZZ
+	SHADD16_EQ
+	SHADD16_NE
+	SHADD16_CS
+	SHADD16_CC
+	SHADD16_MI
+	SHADD16_PL
+	SHADD16_VS
+	SHADD16_VC
+	SHADD16_HI
+	SHADD16_LS
+	SHADD16_GE
+	SHADD16_LT
+	SHADD16_GT
+	SHADD16_LE
+	SHADD16
+	SHADD16_ZZ
+	SHADD8_EQ
+	SHADD8_NE
+	SHADD8_CS
+	SHADD8_CC
+	SHADD8_MI
+	SHADD8_PL
+	SHADD8_VS
+	SHADD8_VC
+	SHADD8_HI
+	SHADD8_LS
+	SHADD8_GE
+	SHADD8_LT
+	SHADD8_GT
+	SHADD8_LE
+	SHADD8
+	SHADD8_ZZ
+	SHASX_EQ
+	SHASX_NE
+	SHASX_CS
+	SHASX_CC
+	SHASX_MI
+	SHASX_PL
+	SHASX_VS
+	SHASX_VC
+	SHASX_HI
+	SHASX_LS
+	SHASX_GE
+	SHASX_LT
+	SHASX_GT
+	SHASX_LE
+	SHASX
+	SHASX_ZZ
+	SHSAX_EQ
+	SHSAX_NE
+	SHSAX_CS
+	SHSAX_CC
+	SHSAX_MI
+	SHSAX_PL
+	SHSAX_VS
+	SHSAX_VC
+	SHSAX_HI
+	SHSAX_LS
+	SHSAX_GE
+	SHSAX_LT
+	SHSAX_GT
+	SHSAX_LE
+	SHSAX
+	SHSAX_ZZ
+	SHSUB16_EQ
+	SHSUB16_NE
+	SHSUB16_CS
+	SHSUB16_CC
+	SHSUB16_MI
+	SHSUB16_PL
+	SHSUB16_VS
+	SHSUB16_VC
+	SHSUB16_HI
+	SHSUB16_LS
+	SHSUB16_GE
+	SHSUB16_LT
+	SHSUB16_GT
+	SHSUB16_LE
+	SHSUB16
+	SHSUB16_ZZ
+	SHSUB8_EQ
+	SHSUB8_NE
+	SHSUB8_CS
+	SHSUB8_CC
+	SHSUB8_MI
+	SHSUB8_PL
+	SHSUB8_VS
+	SHSUB8_VC
+	SHSUB8_HI
+	SHSUB8_LS
+	SHSUB8_GE
+	SHSUB8_LT
+	SHSUB8_GT
+	SHSUB8_LE
+	SHSUB8
+	SHSUB8_ZZ
+	SMLABB_EQ
+	SMLABB_NE
+	SMLABB_CS
+	SMLABB_CC
+	SMLABB_MI
+	SMLABB_PL
+	SMLABB_VS
+	SMLABB_VC
+	SMLABB_HI
+	SMLABB_LS
+	SMLABB_GE
+	SMLABB_LT
+	SMLABB_GT
+	SMLABB_LE
+	SMLABB
+	SMLABB_ZZ
+	SMLABT_EQ
+	SMLABT_NE
+	SMLABT_CS
+	SMLABT_CC
+	SMLABT_MI
+	SMLABT_PL
+	SMLABT_VS
+	SMLABT_VC
+	SMLABT_HI
+	SMLABT_LS
+	SMLABT_GE
+	SMLABT_LT
+	SMLABT_GT
+	SMLABT_LE
+	SMLABT
+	SMLABT_ZZ
+	SMLATB_EQ
+	SMLATB_NE
+	SMLATB_CS
+	SMLATB_CC
+	SMLATB_MI
+	SMLATB_PL
+	SMLATB_VS
+	SMLATB_VC
+	SMLATB_HI
+	SMLATB_LS
+	SMLATB_GE
+	SMLATB_LT
+	SMLATB_GT
+	SMLATB_LE
+	SMLATB
+	SMLATB_ZZ
+	SMLATT_EQ
+	SMLATT_NE
+	SMLATT_CS
+	SMLATT_CC
+	SMLATT_MI
+	SMLATT_PL
+	SMLATT_VS
+	SMLATT_VC
+	SMLATT_HI
+	SMLATT_LS
+	SMLATT_GE
+	SMLATT_LT
+	SMLATT_GT
+	SMLATT_LE
+	SMLATT
+	SMLATT_ZZ
+	SMLAD_EQ
+	SMLAD_NE
+	SMLAD_CS
+	SMLAD_CC
+	SMLAD_MI
+	SMLAD_PL
+	SMLAD_VS
+	SMLAD_VC
+	SMLAD_HI
+	SMLAD_LS
+	SMLAD_GE
+	SMLAD_LT
+	SMLAD_GT
+	SMLAD_LE
+	SMLAD
+	SMLAD_ZZ
+	SMLAD_X_EQ
+	SMLAD_X_NE
+	SMLAD_X_CS
+	SMLAD_X_CC
+	SMLAD_X_MI
+	SMLAD_X_PL
+	SMLAD_X_VS
+	SMLAD_X_VC
+	SMLAD_X_HI
+	SMLAD_X_LS
+	SMLAD_X_GE
+	SMLAD_X_LT
+	SMLAD_X_GT
+	SMLAD_X_LE
+	SMLAD_X
+	SMLAD_X_ZZ
+	SMLAL_EQ
+	SMLAL_NE
+	SMLAL_CS
+	SMLAL_CC
+	SMLAL_MI
+	SMLAL_PL
+	SMLAL_VS
+	SMLAL_VC
+	SMLAL_HI
+	SMLAL_LS
+	SMLAL_GE
+	SMLAL_LT
+	SMLAL_GT
+	SMLAL_LE
+	SMLAL
+	SMLAL_ZZ
+	SMLAL_S_EQ
+	SMLAL_S_NE
+	SMLAL_S_CS
+	SMLAL_S_CC
+	SMLAL_S_MI
+	SMLAL_S_PL
+	SMLAL_S_VS
+	SMLAL_S_VC
+	SMLAL_S_HI
+	SMLAL_S_LS
+	SMLAL_S_GE
+	SMLAL_S_LT
+	SMLAL_S_GT
+	SMLAL_S_LE
+	SMLAL_S
+	SMLAL_S_ZZ
+	SMLALBB_EQ
+	SMLALBB_NE
+	SMLALBB_CS
+	SMLALBB_CC
+	SMLALBB_MI
+	SMLALBB_PL
+	SMLALBB_VS
+	SMLALBB_VC
+	SMLALBB_HI
+	SMLALBB_LS
+	SMLALBB_GE
+	SMLALBB_LT
+	SMLALBB_GT
+	SMLALBB_LE
+	SMLALBB
+	SMLALBB_ZZ
+	SMLALBT_EQ
+	SMLALBT_NE
+	SMLALBT_CS
+	SMLALBT_CC
+	SMLALBT_MI
+	SMLALBT_PL
+	SMLALBT_VS
+	SMLALBT_VC
+	SMLALBT_HI
+	SMLALBT_LS
+	SMLALBT_GE
+	SMLALBT_LT
+	SMLALBT_GT
+	SMLALBT_LE
+	SMLALBT
+	SMLALBT_ZZ
+	SMLALTB_EQ
+	SMLALTB_NE
+	SMLALTB_CS
+	SMLALTB_CC
+	SMLALTB_MI
+	SMLALTB_PL
+	SMLALTB_VS
+	SMLALTB_VC
+	SMLALTB_HI
+	SMLALTB_LS
+	SMLALTB_GE
+	SMLALTB_LT
+	SMLALTB_GT
+	SMLALTB_LE
+	SMLALTB
+	SMLALTB_ZZ
+	SMLALTT_EQ
+	SMLALTT_NE
+	SMLALTT_CS
+	SMLALTT_CC
+	SMLALTT_MI
+	SMLALTT_PL
+	SMLALTT_VS
+	SMLALTT_VC
+	SMLALTT_HI
+	SMLALTT_LS
+	SMLALTT_GE
+	SMLALTT_LT
+	SMLALTT_GT
+	SMLALTT_LE
+	SMLALTT
+	SMLALTT_ZZ
+	SMLALD_EQ
+	SMLALD_NE
+	SMLALD_CS
+	SMLALD_CC
+	SMLALD_MI
+	SMLALD_PL
+	SMLALD_VS
+	SMLALD_VC
+	SMLALD_HI
+	SMLALD_LS
+	SMLALD_GE
+	SMLALD_LT
+	SMLALD_GT
+	SMLALD_LE
+	SMLALD
+	SMLALD_ZZ
+	SMLALD_X_EQ
+	SMLALD_X_NE
+	SMLALD_X_CS
+	SMLALD_X_CC
+	SMLALD_X_MI
+	SMLALD_X_PL
+	SMLALD_X_VS
+	SMLALD_X_VC
+	SMLALD_X_HI
+	SMLALD_X_LS
+	SMLALD_X_GE
+	SMLALD_X_LT
+	SMLALD_X_GT
+	SMLALD_X_LE
+	SMLALD_X
+	SMLALD_X_ZZ
+	SMLAWB_EQ
+	SMLAWB_NE
+	SMLAWB_CS
+	SMLAWB_CC
+	SMLAWB_MI
+	SMLAWB_PL
+	SMLAWB_VS
+	SMLAWB_VC
+	SMLAWB_HI
+	SMLAWB_LS
+	SMLAWB_GE
+	SMLAWB_LT
+	SMLAWB_GT
+	SMLAWB_LE
+	SMLAWB
+	SMLAWB_ZZ
+	SMLAWT_EQ
+	SMLAWT_NE
+	SMLAWT_CS
+	SMLAWT_CC
+	SMLAWT_MI
+	SMLAWT_PL
+	SMLAWT_VS
+	SMLAWT_VC
+	SMLAWT_HI
+	SMLAWT_LS
+	SMLAWT_GE
+	SMLAWT_LT
+	SMLAWT_GT
+	SMLAWT_LE
+	SMLAWT
+	SMLAWT_ZZ
+	SMLSD_EQ
+	SMLSD_NE
+	SMLSD_CS
+	SMLSD_CC
+	SMLSD_MI
+	SMLSD_PL
+	SMLSD_VS
+	SMLSD_VC
+	SMLSD_HI
+	SMLSD_LS
+	SMLSD_GE
+	SMLSD_LT
+	SMLSD_GT
+	SMLSD_LE
+	SMLSD
+	SMLSD_ZZ
+	SMLSD_X_EQ
+	SMLSD_X_NE
+	SMLSD_X_CS
+	SMLSD_X_CC
+	SMLSD_X_MI
+	SMLSD_X_PL
+	SMLSD_X_VS
+	SMLSD_X_VC
+	SMLSD_X_HI
+	SMLSD_X_LS
+	SMLSD_X_GE
+	SMLSD_X_LT
+	SMLSD_X_GT
+	SMLSD_X_LE
+	SMLSD_X
+	SMLSD_X_ZZ
+	SMLSLD_EQ
+	SMLSLD_NE
+	SMLSLD_CS
+	SMLSLD_CC
+	SMLSLD_MI
+	SMLSLD_PL
+	SMLSLD_VS
+	SMLSLD_VC
+	SMLSLD_HI
+	SMLSLD_LS
+	SMLSLD_GE
+	SMLSLD_LT
+	SMLSLD_GT
+	SMLSLD_LE
+	SMLSLD
+	SMLSLD_ZZ
+	SMLSLD_X_EQ
+	SMLSLD_X_NE
+	SMLSLD_X_CS
+	SMLSLD_X_CC
+	SMLSLD_X_MI
+	SMLSLD_X_PL
+	SMLSLD_X_VS
+	SMLSLD_X_VC
+	SMLSLD_X_HI
+	SMLSLD_X_LS
+	SMLSLD_X_GE
+	SMLSLD_X_LT
+	SMLSLD_X_GT
+	SMLSLD_X_LE
+	SMLSLD_X
+	SMLSLD_X_ZZ
+	SMMLA_EQ
+	SMMLA_NE
+	SMMLA_CS
+	SMMLA_CC
+	SMMLA_MI
+	SMMLA_PL
+	SMMLA_VS
+	SMMLA_VC
+	SMMLA_HI
+	SMMLA_LS
+	SMMLA_GE
+	SMMLA_LT
+	SMMLA_GT
+	SMMLA_LE
+	SMMLA
+	SMMLA_ZZ
+	SMMLA_R_EQ
+	SMMLA_R_NE
+	SMMLA_R_CS
+	SMMLA_R_CC
+	SMMLA_R_MI
+	SMMLA_R_PL
+	SMMLA_R_VS
+	SMMLA_R_VC
+	SMMLA_R_HI
+	SMMLA_R_LS
+	SMMLA_R_GE
+	SMMLA_R_LT
+	SMMLA_R_GT
+	SMMLA_R_LE
+	SMMLA_R
+	SMMLA_R_ZZ
+	SMMLS_EQ
+	SMMLS_NE
+	SMMLS_CS
+	SMMLS_CC
+	SMMLS_MI
+	SMMLS_PL
+	SMMLS_VS
+	SMMLS_VC
+	SMMLS_HI
+	SMMLS_LS
+	SMMLS_GE
+	SMMLS_LT
+	SMMLS_GT
+	SMMLS_LE
+	SMMLS
+	SMMLS_ZZ
+	SMMLS_R_EQ
+	SMMLS_R_NE
+	SMMLS_R_CS
+	SMMLS_R_CC
+	SMMLS_R_MI
+	SMMLS_R_PL
+	SMMLS_R_VS
+	SMMLS_R_VC
+	SMMLS_R_HI
+	SMMLS_R_LS
+	SMMLS_R_GE
+	SMMLS_R_LT
+	SMMLS_R_GT
+	SMMLS_R_LE
+	SMMLS_R
+	SMMLS_R_ZZ
+	SMMUL_EQ
+	SMMUL_NE
+	SMMUL_CS
+	SMMUL_CC
+	SMMUL_MI
+	SMMUL_PL
+	SMMUL_VS
+	SMMUL_VC
+	SMMUL_HI
+	SMMUL_LS
+	SMMUL_GE
+	SMMUL_LT
+	SMMUL_GT
+	SMMUL_LE
+	SMMUL
+	SMMUL_ZZ
+	SMMUL_R_EQ
+	SMMUL_R_NE
+	SMMUL_R_CS
+	SMMUL_R_CC
+	SMMUL_R_MI
+	SMMUL_R_PL
+	SMMUL_R_VS
+	SMMUL_R_VC
+	SMMUL_R_HI
+	SMMUL_R_LS
+	SMMUL_R_GE
+	SMMUL_R_LT
+	SMMUL_R_GT
+	SMMUL_R_LE
+	SMMUL_R
+	SMMUL_R_ZZ
+	SMUAD_EQ
+	SMUAD_NE
+	SMUAD_CS
+	SMUAD_CC
+	SMUAD_MI
+	SMUAD_PL
+	SMUAD_VS
+	SMUAD_VC
+	SMUAD_HI
+	SMUAD_LS
+	SMUAD_GE
+	SMUAD_LT
+	SMUAD_GT
+	SMUAD_LE
+	SMUAD
+	SMUAD_ZZ
+	SMUAD_X_EQ
+	SMUAD_X_NE
+	SMUAD_X_CS
+	SMUAD_X_CC
+	SMUAD_X_MI
+	SMUAD_X_PL
+	SMUAD_X_VS
+	SMUAD_X_VC
+	SMUAD_X_HI
+	SMUAD_X_LS
+	SMUAD_X_GE
+	SMUAD_X_LT
+	SMUAD_X_GT
+	SMUAD_X_LE
+	SMUAD_X
+	SMUAD_X_ZZ
+	SMULBB_EQ
+	SMULBB_NE
+	SMULBB_CS
+	SMULBB_CC
+	SMULBB_MI
+	SMULBB_PL
+	SMULBB_VS
+	SMULBB_VC
+	SMULBB_HI
+	SMULBB_LS
+	SMULBB_GE
+	SMULBB_LT
+	SMULBB_GT
+	SMULBB_LE
+	SMULBB
+	SMULBB_ZZ
+	SMULBT_EQ
+	SMULBT_NE
+	SMULBT_CS
+	SMULBT_CC
+	SMULBT_MI
+	SMULBT_PL
+	SMULBT_VS
+	SMULBT_VC
+	SMULBT_HI
+	SMULBT_LS
+	SMULBT_GE
+	SMULBT_LT
+	SMULBT_GT
+	SMULBT_LE
+	SMULBT
+	SMULBT_ZZ
+	SMULTB_EQ
+	SMULTB_NE
+	SMULTB_CS
+	SMULTB_CC
+	SMULTB_MI
+	SMULTB_PL
+	SMULTB_VS
+	SMULTB_VC
+	SMULTB_HI
+	SMULTB_LS
+	SMULTB_GE
+	SMULTB_LT
+	SMULTB_GT
+	SMULTB_LE
+	SMULTB
+	SMULTB_ZZ
+	SMULTT_EQ
+	SMULTT_NE
+	SMULTT_CS
+	SMULTT_CC
+	SMULTT_MI
+	SMULTT_PL
+	SMULTT_VS
+	SMULTT_VC
+	SMULTT_HI
+	SMULTT_LS
+	SMULTT_GE
+	SMULTT_LT
+	SMULTT_GT
+	SMULTT_LE
+	SMULTT
+	SMULTT_ZZ
+	SMULL_EQ
+	SMULL_NE
+	SMULL_CS
+	SMULL_CC
+	SMULL_MI
+	SMULL_PL
+	SMULL_VS
+	SMULL_VC
+	SMULL_HI
+	SMULL_LS
+	SMULL_GE
+	SMULL_LT
+	SMULL_GT
+	SMULL_LE
+	SMULL
+	SMULL_ZZ
+	SMULL_S_EQ
+	SMULL_S_NE
+	SMULL_S_CS
+	SMULL_S_CC
+	SMULL_S_MI
+	SMULL_S_PL
+	SMULL_S_VS
+	SMULL_S_VC
+	SMULL_S_HI
+	SMULL_S_LS
+	SMULL_S_GE
+	SMULL_S_LT
+	SMULL_S_GT
+	SMULL_S_LE
+	SMULL_S
+	SMULL_S_ZZ
+	SMULWB_EQ
+	SMULWB_NE
+	SMULWB_CS
+	SMULWB_CC
+	SMULWB_MI
+	SMULWB_PL
+	SMULWB_VS
+	SMULWB_VC
+	SMULWB_HI
+	SMULWB_LS
+	SMULWB_GE
+	SMULWB_LT
+	SMULWB_GT
+	SMULWB_LE
+	SMULWB
+	SMULWB_ZZ
+	SMULWT_EQ
+	SMULWT_NE
+	SMULWT_CS
+	SMULWT_CC
+	SMULWT_MI
+	SMULWT_PL
+	SMULWT_VS
+	SMULWT_VC
+	SMULWT_HI
+	SMULWT_LS
+	SMULWT_GE
+	SMULWT_LT
+	SMULWT_GT
+	SMULWT_LE
+	SMULWT
+	SMULWT_ZZ
+	SMUSD_EQ
+	SMUSD_NE
+	SMUSD_CS
+	SMUSD_CC
+	SMUSD_MI
+	SMUSD_PL
+	SMUSD_VS
+	SMUSD_VC
+	SMUSD_HI
+	SMUSD_LS
+	SMUSD_GE
+	SMUSD_LT
+	SMUSD_GT
+	SMUSD_LE
+	SMUSD
+	SMUSD_ZZ
+	SMUSD_X_EQ
+	SMUSD_X_NE
+	SMUSD_X_CS
+	SMUSD_X_CC
+	SMUSD_X_MI
+	SMUSD_X_PL
+	SMUSD_X_VS
+	SMUSD_X_VC
+	SMUSD_X_HI
+	SMUSD_X_LS
+	SMUSD_X_GE
+	SMUSD_X_LT
+	SMUSD_X_GT
+	SMUSD_X_LE
+	SMUSD_X
+	SMUSD_X_ZZ
+	SSAT_EQ
+	SSAT_NE
+	SSAT_CS
+	SSAT_CC
+	SSAT_MI
+	SSAT_PL
+	SSAT_VS
+	SSAT_VC
+	SSAT_HI
+	SSAT_LS
+	SSAT_GE
+	SSAT_LT
+	SSAT_GT
+	SSAT_LE
+	SSAT
+	SSAT_ZZ
+	SSAT16_EQ
+	SSAT16_NE
+	SSAT16_CS
+	SSAT16_CC
+	SSAT16_MI
+	SSAT16_PL
+	SSAT16_VS
+	SSAT16_VC
+	SSAT16_HI
+	SSAT16_LS
+	SSAT16_GE
+	SSAT16_LT
+	SSAT16_GT
+	SSAT16_LE
+	SSAT16
+	SSAT16_ZZ
+	SSAX_EQ
+	SSAX_NE
+	SSAX_CS
+	SSAX_CC
+	SSAX_MI
+	SSAX_PL
+	SSAX_VS
+	SSAX_VC
+	SSAX_HI
+	SSAX_LS
+	SSAX_GE
+	SSAX_LT
+	SSAX_GT
+	SSAX_LE
+	SSAX
+	SSAX_ZZ
+	SSUB16_EQ
+	SSUB16_NE
+	SSUB16_CS
+	SSUB16_CC
+	SSUB16_MI
+	SSUB16_PL
+	SSUB16_VS
+	SSUB16_VC
+	SSUB16_HI
+	SSUB16_LS
+	SSUB16_GE
+	SSUB16_LT
+	SSUB16_GT
+	SSUB16_LE
+	SSUB16
+	SSUB16_ZZ
+	SSUB8_EQ
+	SSUB8_NE
+	SSUB8_CS
+	SSUB8_CC
+	SSUB8_MI
+	SSUB8_PL
+	SSUB8_VS
+	SSUB8_VC
+	SSUB8_HI
+	SSUB8_LS
+	SSUB8_GE
+	SSUB8_LT
+	SSUB8_GT
+	SSUB8_LE
+	SSUB8
+	SSUB8_ZZ
+	STM_EQ
+	STM_NE
+	STM_CS
+	STM_CC
+	STM_MI
+	STM_PL
+	STM_VS
+	STM_VC
+	STM_HI
+	STM_LS
+	STM_GE
+	STM_LT
+	STM_GT
+	STM_LE
+	STM
+	STM_ZZ
+	STMDA_EQ
+	STMDA_NE
+	STMDA_CS
+	STMDA_CC
+	STMDA_MI
+	STMDA_PL
+	STMDA_VS
+	STMDA_VC
+	STMDA_HI
+	STMDA_LS
+	STMDA_GE
+	STMDA_LT
+	STMDA_GT
+	STMDA_LE
+	STMDA
+	STMDA_ZZ
+	STMDB_EQ
+	STMDB_NE
+	STMDB_CS
+	STMDB_CC
+	STMDB_MI
+	STMDB_PL
+	STMDB_VS
+	STMDB_VC
+	STMDB_HI
+	STMDB_LS
+	STMDB_GE
+	STMDB_LT
+	STMDB_GT
+	STMDB_LE
+	STMDB
+	STMDB_ZZ
+	STMIB_EQ
+	STMIB_NE
+	STMIB_CS
+	STMIB_CC
+	STMIB_MI
+	STMIB_PL
+	STMIB_VS
+	STMIB_VC
+	STMIB_HI
+	STMIB_LS
+	STMIB_GE
+	STMIB_LT
+	STMIB_GT
+	STMIB_LE
+	STMIB
+	STMIB_ZZ
+	STR_EQ
+	STR_NE
+	STR_CS
+	STR_CC
+	STR_MI
+	STR_PL
+	STR_VS
+	STR_VC
+	STR_HI
+	STR_LS
+	STR_GE
+	STR_LT
+	STR_GT
+	STR_LE
+	STR
+	STR_ZZ
+	STRB_EQ
+	STRB_NE
+	STRB_CS
+	STRB_CC
+	STRB_MI
+	STRB_PL
+	STRB_VS
+	STRB_VC
+	STRB_HI
+	STRB_LS
+	STRB_GE
+	STRB_LT
+	STRB_GT
+	STRB_LE
+	STRB
+	STRB_ZZ
+	STRBT_EQ
+	STRBT_NE
+	STRBT_CS
+	STRBT_CC
+	STRBT_MI
+	STRBT_PL
+	STRBT_VS
+	STRBT_VC
+	STRBT_HI
+	STRBT_LS
+	STRBT_GE
+	STRBT_LT
+	STRBT_GT
+	STRBT_LE
+	STRBT
+	STRBT_ZZ
+	STRD_EQ
+	STRD_NE
+	STRD_CS
+	STRD_CC
+	STRD_MI
+	STRD_PL
+	STRD_VS
+	STRD_VC
+	STRD_HI
+	STRD_LS
+	STRD_GE
+	STRD_LT
+	STRD_GT
+	STRD_LE
+	STRD
+	STRD_ZZ
+	STREX_EQ
+	STREX_NE
+	STREX_CS
+	STREX_CC
+	STREX_MI
+	STREX_PL
+	STREX_VS
+	STREX_VC
+	STREX_HI
+	STREX_LS
+	STREX_GE
+	STREX_LT
+	STREX_GT
+	STREX_LE
+	STREX
+	STREX_ZZ
+	STREXB_EQ
+	STREXB_NE
+	STREXB_CS
+	STREXB_CC
+	STREXB_MI
+	STREXB_PL
+	STREXB_VS
+	STREXB_VC
+	STREXB_HI
+	STREXB_LS
+	STREXB_GE
+	STREXB_LT
+	STREXB_GT
+	STREXB_LE
+	STREXB
+	STREXB_ZZ
+	STREXD_EQ
+	STREXD_NE
+	STREXD_CS
+	STREXD_CC
+	STREXD_MI
+	STREXD_PL
+	STREXD_VS
+	STREXD_VC
+	STREXD_HI
+	STREXD_LS
+	STREXD_GE
+	STREXD_LT
+	STREXD_GT
+	STREXD_LE
+	STREXD
+	STREXD_ZZ
+	STREXH_EQ
+	STREXH_NE
+	STREXH_CS
+	STREXH_CC
+	STREXH_MI
+	STREXH_PL
+	STREXH_VS
+	STREXH_VC
+	STREXH_HI
+	STREXH_LS
+	STREXH_GE
+	STREXH_LT
+	STREXH_GT
+	STREXH_LE
+	STREXH
+	STREXH_ZZ
+	STRH_EQ
+	STRH_NE
+	STRH_CS
+	STRH_CC
+	STRH_MI
+	STRH_PL
+	STRH_VS
+	STRH_VC
+	STRH_HI
+	STRH_LS
+	STRH_GE
+	STRH_LT
+	STRH_GT
+	STRH_LE
+	STRH
+	STRH_ZZ
+	STRHT_EQ
+	STRHT_NE
+	STRHT_CS
+	STRHT_CC
+	STRHT_MI
+	STRHT_PL
+	STRHT_VS
+	STRHT_VC
+	STRHT_HI
+	STRHT_LS
+	STRHT_GE
+	STRHT_LT
+	STRHT_GT
+	STRHT_LE
+	STRHT
+	STRHT_ZZ
+	STRT_EQ
+	STRT_NE
+	STRT_CS
+	STRT_CC
+	STRT_MI
+	STRT_PL
+	STRT_VS
+	STRT_VC
+	STRT_HI
+	STRT_LS
+	STRT_GE
+	STRT_LT
+	STRT_GT
+	STRT_LE
+	STRT
+	STRT_ZZ
+	SUB_EQ
+	SUB_NE
+	SUB_CS
+	SUB_CC
+	SUB_MI
+	SUB_PL
+	SUB_VS
+	SUB_VC
+	SUB_HI
+	SUB_LS
+	SUB_GE
+	SUB_LT
+	SUB_GT
+	SUB_LE
+	SUB
+	SUB_ZZ
+	SUB_S_EQ
+	SUB_S_NE
+	SUB_S_CS
+	SUB_S_CC
+	SUB_S_MI
+	SUB_S_PL
+	SUB_S_VS
+	SUB_S_VC
+	SUB_S_HI
+	SUB_S_LS
+	SUB_S_GE
+	SUB_S_LT
+	SUB_S_GT
+	SUB_S_LE
+	SUB_S
+	SUB_S_ZZ
+	SVC_EQ
+	SVC_NE
+	SVC_CS
+	SVC_CC
+	SVC_MI
+	SVC_PL
+	SVC_VS
+	SVC_VC
+	SVC_HI
+	SVC_LS
+	SVC_GE
+	SVC_LT
+	SVC_GT
+	SVC_LE
+	SVC
+	SVC_ZZ
+	SWP_EQ
+	SWP_NE
+	SWP_CS
+	SWP_CC
+	SWP_MI
+	SWP_PL
+	SWP_VS
+	SWP_VC
+	SWP_HI
+	SWP_LS
+	SWP_GE
+	SWP_LT
+	SWP_GT
+	SWP_LE
+	SWP
+	SWP_ZZ
+	SWP_B_EQ
+	SWP_B_NE
+	SWP_B_CS
+	SWP_B_CC
+	SWP_B_MI
+	SWP_B_PL
+	SWP_B_VS
+	SWP_B_VC
+	SWP_B_HI
+	SWP_B_LS
+	SWP_B_GE
+	SWP_B_LT
+	SWP_B_GT
+	SWP_B_LE
+	SWP_B
+	SWP_B_ZZ
+	SXTAB_EQ
+	SXTAB_NE
+	SXTAB_CS
+	SXTAB_CC
+	SXTAB_MI
+	SXTAB_PL
+	SXTAB_VS
+	SXTAB_VC
+	SXTAB_HI
+	SXTAB_LS
+	SXTAB_GE
+	SXTAB_LT
+	SXTAB_GT
+	SXTAB_LE
+	SXTAB
+	SXTAB_ZZ
+	SXTAB16_EQ
+	SXTAB16_NE
+	SXTAB16_CS
+	SXTAB16_CC
+	SXTAB16_MI
+	SXTAB16_PL
+	SXTAB16_VS
+	SXTAB16_VC
+	SXTAB16_HI
+	SXTAB16_LS
+	SXTAB16_GE
+	SXTAB16_LT
+	SXTAB16_GT
+	SXTAB16_LE
+	SXTAB16
+	SXTAB16_ZZ
+	SXTAH_EQ
+	SXTAH_NE
+	SXTAH_CS
+	SXTAH_CC
+	SXTAH_MI
+	SXTAH_PL
+	SXTAH_VS
+	SXTAH_VC
+	SXTAH_HI
+	SXTAH_LS
+	SXTAH_GE
+	SXTAH_LT
+	SXTAH_GT
+	SXTAH_LE
+	SXTAH
+	SXTAH_ZZ
+	SXTB_EQ
+	SXTB_NE
+	SXTB_CS
+	SXTB_CC
+	SXTB_MI
+	SXTB_PL
+	SXTB_VS
+	SXTB_VC
+	SXTB_HI
+	SXTB_LS
+	SXTB_GE
+	SXTB_LT
+	SXTB_GT
+	SXTB_LE
+	SXTB
+	SXTB_ZZ
+	SXTB16_EQ
+	SXTB16_NE
+	SXTB16_CS
+	SXTB16_CC
+	SXTB16_MI
+	SXTB16_PL
+	SXTB16_VS
+	SXTB16_VC
+	SXTB16_HI
+	SXTB16_LS
+	SXTB16_GE
+	SXTB16_LT
+	SXTB16_GT
+	SXTB16_LE
+	SXTB16
+	SXTB16_ZZ
+	SXTH_EQ
+	SXTH_NE
+	SXTH_CS
+	SXTH_CC
+	SXTH_MI
+	SXTH_PL
+	SXTH_VS
+	SXTH_VC
+	SXTH_HI
+	SXTH_LS
+	SXTH_GE
+	SXTH_LT
+	SXTH_GT
+	SXTH_LE
+	SXTH
+	SXTH_ZZ
+	TEQ_EQ
+	TEQ_NE
+	TEQ_CS
+	TEQ_CC
+	TEQ_MI
+	TEQ_PL
+	TEQ_VS
+	TEQ_VC
+	TEQ_HI
+	TEQ_LS
+	TEQ_GE
+	TEQ_LT
+	TEQ_GT
+	TEQ_LE
+	TEQ
+	TEQ_ZZ
+	TST_EQ
+	TST_NE
+	TST_CS
+	TST_CC
+	TST_MI
+	TST_PL
+	TST_VS
+	TST_VC
+	TST_HI
+	TST_LS
+	TST_GE
+	TST_LT
+	TST_GT
+	TST_LE
+	TST
+	TST_ZZ
+	UADD16_EQ
+	UADD16_NE
+	UADD16_CS
+	UADD16_CC
+	UADD16_MI
+	UADD16_PL
+	UADD16_VS
+	UADD16_VC
+	UADD16_HI
+	UADD16_LS
+	UADD16_GE
+	UADD16_LT
+	UADD16_GT
+	UADD16_LE
+	UADD16
+	UADD16_ZZ
+	UADD8_EQ
+	UADD8_NE
+	UADD8_CS
+	UADD8_CC
+	UADD8_MI
+	UADD8_PL
+	UADD8_VS
+	UADD8_VC
+	UADD8_HI
+	UADD8_LS
+	UADD8_GE
+	UADD8_LT
+	UADD8_GT
+	UADD8_LE
+	UADD8
+	UADD8_ZZ
+	UASX_EQ
+	UASX_NE
+	UASX_CS
+	UASX_CC
+	UASX_MI
+	UASX_PL
+	UASX_VS
+	UASX_VC
+	UASX_HI
+	UASX_LS
+	UASX_GE
+	UASX_LT
+	UASX_GT
+	UASX_LE
+	UASX
+	UASX_ZZ
+	UBFX_EQ
+	UBFX_NE
+	UBFX_CS
+	UBFX_CC
+	UBFX_MI
+	UBFX_PL
+	UBFX_VS
+	UBFX_VC
+	UBFX_HI
+	UBFX_LS
+	UBFX_GE
+	UBFX_LT
+	UBFX_GT
+	UBFX_LE
+	UBFX
+	UBFX_ZZ
+	UHADD16_EQ
+	UHADD16_NE
+	UHADD16_CS
+	UHADD16_CC
+	UHADD16_MI
+	UHADD16_PL
+	UHADD16_VS
+	UHADD16_VC
+	UHADD16_HI
+	UHADD16_LS
+	UHADD16_GE
+	UHADD16_LT
+	UHADD16_GT
+	UHADD16_LE
+	UHADD16
+	UHADD16_ZZ
+	UHADD8_EQ
+	UHADD8_NE
+	UHADD8_CS
+	UHADD8_CC
+	UHADD8_MI
+	UHADD8_PL
+	UHADD8_VS
+	UHADD8_VC
+	UHADD8_HI
+	UHADD8_LS
+	UHADD8_GE
+	UHADD8_LT
+	UHADD8_GT
+	UHADD8_LE
+	UHADD8
+	UHADD8_ZZ
+	UHASX_EQ
+	UHASX_NE
+	UHASX_CS
+	UHASX_CC
+	UHASX_MI
+	UHASX_PL
+	UHASX_VS
+	UHASX_VC
+	UHASX_HI
+	UHASX_LS
+	UHASX_GE
+	UHASX_LT
+	UHASX_GT
+	UHASX_LE
+	UHASX
+	UHASX_ZZ
+	UHSAX_EQ
+	UHSAX_NE
+	UHSAX_CS
+	UHSAX_CC
+	UHSAX_MI
+	UHSAX_PL
+	UHSAX_VS
+	UHSAX_VC
+	UHSAX_HI
+	UHSAX_LS
+	UHSAX_GE
+	UHSAX_LT
+	UHSAX_GT
+	UHSAX_LE
+	UHSAX
+	UHSAX_ZZ
+	UHSUB16_EQ
+	UHSUB16_NE
+	UHSUB16_CS
+	UHSUB16_CC
+	UHSUB16_MI
+	UHSUB16_PL
+	UHSUB16_VS
+	UHSUB16_VC
+	UHSUB16_HI
+	UHSUB16_LS
+	UHSUB16_GE
+	UHSUB16_LT
+	UHSUB16_GT
+	UHSUB16_LE
+	UHSUB16
+	UHSUB16_ZZ
+	UHSUB8_EQ
+	UHSUB8_NE
+	UHSUB8_CS
+	UHSUB8_CC
+	UHSUB8_MI
+	UHSUB8_PL
+	UHSUB8_VS
+	UHSUB8_VC
+	UHSUB8_HI
+	UHSUB8_LS
+	UHSUB8_GE
+	UHSUB8_LT
+	UHSUB8_GT
+	UHSUB8_LE
+	UHSUB8
+	UHSUB8_ZZ
+	UMAAL_EQ
+	UMAAL_NE
+	UMAAL_CS
+	UMAAL_CC
+	UMAAL_MI
+	UMAAL_PL
+	UMAAL_VS
+	UMAAL_VC
+	UMAAL_HI
+	UMAAL_LS
+	UMAAL_GE
+	UMAAL_LT
+	UMAAL_GT
+	UMAAL_LE
+	UMAAL
+	UMAAL_ZZ
+	UMLAL_EQ
+	UMLAL_NE
+	UMLAL_CS
+	UMLAL_CC
+	UMLAL_MI
+	UMLAL_PL
+	UMLAL_VS
+	UMLAL_VC
+	UMLAL_HI
+	UMLAL_LS
+	UMLAL_GE
+	UMLAL_LT
+	UMLAL_GT
+	UMLAL_LE
+	UMLAL
+	UMLAL_ZZ
+	UMLAL_S_EQ
+	UMLAL_S_NE
+	UMLAL_S_CS
+	UMLAL_S_CC
+	UMLAL_S_MI
+	UMLAL_S_PL
+	UMLAL_S_VS
+	UMLAL_S_VC
+	UMLAL_S_HI
+	UMLAL_S_LS
+	UMLAL_S_GE
+	UMLAL_S_LT
+	UMLAL_S_GT
+	UMLAL_S_LE
+	UMLAL_S
+	UMLAL_S_ZZ
+	UMULL_EQ
+	UMULL_NE
+	UMULL_CS
+	UMULL_CC
+	UMULL_MI
+	UMULL_PL
+	UMULL_VS
+	UMULL_VC
+	UMULL_HI
+	UMULL_LS
+	UMULL_GE
+	UMULL_LT
+	UMULL_GT
+	UMULL_LE
+	UMULL
+	UMULL_ZZ
+	UMULL_S_EQ
+	UMULL_S_NE
+	UMULL_S_CS
+	UMULL_S_CC
+	UMULL_S_MI
+	UMULL_S_PL
+	UMULL_S_VS
+	UMULL_S_VC
+	UMULL_S_HI
+	UMULL_S_LS
+	UMULL_S_GE
+	UMULL_S_LT
+	UMULL_S_GT
+	UMULL_S_LE
+	UMULL_S
+	UMULL_S_ZZ
+	UNDEF
+	_
+	_
+	_
+	_
+	_
+	_
+	_
+	_
+	_
+	_
+	_
+	_
+	_
+	_
+	_
+	UQADD16_EQ
+	UQADD16_NE
+	UQADD16_CS
+	UQADD16_CC
+	UQADD16_MI
+	UQADD16_PL
+	UQADD16_VS
+	UQADD16_VC
+	UQADD16_HI
+	UQADD16_LS
+	UQADD16_GE
+	UQADD16_LT
+	UQADD16_GT
+	UQADD16_LE
+	UQADD16
+	UQADD16_ZZ
+	UQADD8_EQ
+	UQADD8_NE
+	UQADD8_CS
+	UQADD8_CC
+	UQADD8_MI
+	UQADD8_PL
+	UQADD8_VS
+	UQADD8_VC
+	UQADD8_HI
+	UQADD8_LS
+	UQADD8_GE
+	UQADD8_LT
+	UQADD8_GT
+	UQADD8_LE
+	UQADD8
+	UQADD8_ZZ
+	UQASX_EQ
+	UQASX_NE
+	UQASX_CS
+	UQASX_CC
+	UQASX_MI
+	UQASX_PL
+	UQASX_VS
+	UQASX_VC
+	UQASX_HI
+	UQASX_LS
+	UQASX_GE
+	UQASX_LT
+	UQASX_GT
+	UQASX_LE
+	UQASX
+	UQASX_ZZ
+	UQSAX_EQ
+	UQSAX_NE
+	UQSAX_CS
+	UQSAX_CC
+	UQSAX_MI
+	UQSAX_PL
+	UQSAX_VS
+	UQSAX_VC
+	UQSAX_HI
+	UQSAX_LS
+	UQSAX_GE
+	UQSAX_LT
+	UQSAX_GT
+	UQSAX_LE
+	UQSAX
+	UQSAX_ZZ
+	UQSUB16_EQ
+	UQSUB16_NE
+	UQSUB16_CS
+	UQSUB16_CC
+	UQSUB16_MI
+	UQSUB16_PL
+	UQSUB16_VS
+	UQSUB16_VC
+	UQSUB16_HI
+	UQSUB16_LS
+	UQSUB16_GE
+	UQSUB16_LT
+	UQSUB16_GT
+	UQSUB16_LE
+	UQSUB16
+	UQSUB16_ZZ
+	UQSUB8_EQ
+	UQSUB8_NE
+	UQSUB8_CS
+	UQSUB8_CC
+	UQSUB8_MI
+	UQSUB8_PL
+	UQSUB8_VS
+	UQSUB8_VC
+	UQSUB8_HI
+	UQSUB8_LS
+	UQSUB8_GE
+	UQSUB8_LT
+	UQSUB8_GT
+	UQSUB8_LE
+	UQSUB8
+	UQSUB8_ZZ
+	USAD8_EQ
+	USAD8_NE
+	USAD8_CS
+	USAD8_CC
+	USAD8_MI
+	USAD8_PL
+	USAD8_VS
+	USAD8_VC
+	USAD8_HI
+	USAD8_LS
+	USAD8_GE
+	USAD8_LT
+	USAD8_GT
+	USAD8_LE
+	USAD8
+	USAD8_ZZ
+	USADA8_EQ
+	USADA8_NE
+	USADA8_CS
+	USADA8_CC
+	USADA8_MI
+	USADA8_PL
+	USADA8_VS
+	USADA8_VC
+	USADA8_HI
+	USADA8_LS
+	USADA8_GE
+	USADA8_LT
+	USADA8_GT
+	USADA8_LE
+	USADA8
+	USADA8_ZZ
+	USAT_EQ
+	USAT_NE
+	USAT_CS
+	USAT_CC
+	USAT_MI
+	USAT_PL
+	USAT_VS
+	USAT_VC
+	USAT_HI
+	USAT_LS
+	USAT_GE
+	USAT_LT
+	USAT_GT
+	USAT_LE
+	USAT
+	USAT_ZZ
+	USAT16_EQ
+	USAT16_NE
+	USAT16_CS
+	USAT16_CC
+	USAT16_MI
+	USAT16_PL
+	USAT16_VS
+	USAT16_VC
+	USAT16_HI
+	USAT16_LS
+	USAT16_GE
+	USAT16_LT
+	USAT16_GT
+	USAT16_LE
+	USAT16
+	USAT16_ZZ
+	USAX_EQ
+	USAX_NE
+	USAX_CS
+	USAX_CC
+	USAX_MI
+	USAX_PL
+	USAX_VS
+	USAX_VC
+	USAX_HI
+	USAX_LS
+	USAX_GE
+	USAX_LT
+	USAX_GT
+	USAX_LE
+	USAX
+	USAX_ZZ
+	USUB16_EQ
+	USUB16_NE
+	USUB16_CS
+	USUB16_CC
+	USUB16_MI
+	USUB16_PL
+	USUB16_VS
+	USUB16_VC
+	USUB16_HI
+	USUB16_LS
+	USUB16_GE
+	USUB16_LT
+	USUB16_GT
+	USUB16_LE
+	USUB16
+	USUB16_ZZ
+	USUB8_EQ
+	USUB8_NE
+	USUB8_CS
+	USUB8_CC
+	USUB8_MI
+	USUB8_PL
+	USUB8_VS
+	USUB8_VC
+	USUB8_HI
+	USUB8_LS
+	USUB8_GE
+	USUB8_LT
+	USUB8_GT
+	USUB8_LE
+	USUB8
+	USUB8_ZZ
+	UXTAB_EQ
+	UXTAB_NE
+	UXTAB_CS
+	UXTAB_CC
+	UXTAB_MI
+	UXTAB_PL
+	UXTAB_VS
+	UXTAB_VC
+	UXTAB_HI
+	UXTAB_LS
+	UXTAB_GE
+	UXTAB_LT
+	UXTAB_GT
+	UXTAB_LE
+	UXTAB
+	UXTAB_ZZ
+	UXTAB16_EQ
+	UXTAB16_NE
+	UXTAB16_CS
+	UXTAB16_CC
+	UXTAB16_MI
+	UXTAB16_PL
+	UXTAB16_VS
+	UXTAB16_VC
+	UXTAB16_HI
+	UXTAB16_LS
+	UXTAB16_GE
+	UXTAB16_LT
+	UXTAB16_GT
+	UXTAB16_LE
+	UXTAB16
+	UXTAB16_ZZ
+	UXTAH_EQ
+	UXTAH_NE
+	UXTAH_CS
+	UXTAH_CC
+	UXTAH_MI
+	UXTAH_PL
+	UXTAH_VS
+	UXTAH_VC
+	UXTAH_HI
+	UXTAH_LS
+	UXTAH_GE
+	UXTAH_LT
+	UXTAH_GT
+	UXTAH_LE
+	UXTAH
+	UXTAH_ZZ
+	UXTB_EQ
+	UXTB_NE
+	UXTB_CS
+	UXTB_CC
+	UXTB_MI
+	UXTB_PL
+	UXTB_VS
+	UXTB_VC
+	UXTB_HI
+	UXTB_LS
+	UXTB_GE
+	UXTB_LT
+	UXTB_GT
+	UXTB_LE
+	UXTB
+	UXTB_ZZ
+	UXTB16_EQ
+	UXTB16_NE
+	UXTB16_CS
+	UXTB16_CC
+	UXTB16_MI
+	UXTB16_PL
+	UXTB16_VS
+	UXTB16_VC
+	UXTB16_HI
+	UXTB16_LS
+	UXTB16_GE
+	UXTB16_LT
+	UXTB16_GT
+	UXTB16_LE
+	UXTB16
+	UXTB16_ZZ
+	UXTH_EQ
+	UXTH_NE
+	UXTH_CS
+	UXTH_CC
+	UXTH_MI
+	UXTH_PL
+	UXTH_VS
+	UXTH_VC
+	UXTH_HI
+	UXTH_LS
+	UXTH_GE
+	UXTH_LT
+	UXTH_GT
+	UXTH_LE
+	UXTH
+	UXTH_ZZ
+	VABS_EQ_F32
+	VABS_NE_F32
+	VABS_CS_F32
+	VABS_CC_F32
+	VABS_MI_F32
+	VABS_PL_F32
+	VABS_VS_F32
+	VABS_VC_F32
+	VABS_HI_F32
+	VABS_LS_F32
+	VABS_GE_F32
+	VABS_LT_F32
+	VABS_GT_F32
+	VABS_LE_F32
+	VABS_F32
+	VABS_ZZ_F32
+	VABS_EQ_F64
+	VABS_NE_F64
+	VABS_CS_F64
+	VABS_CC_F64
+	VABS_MI_F64
+	VABS_PL_F64
+	VABS_VS_F64
+	VABS_VC_F64
+	VABS_HI_F64
+	VABS_LS_F64
+	VABS_GE_F64
+	VABS_LT_F64
+	VABS_GT_F64
+	VABS_LE_F64
+	VABS_F64
+	VABS_ZZ_F64
+	VADD_EQ_F32
+	VADD_NE_F32
+	VADD_CS_F32
+	VADD_CC_F32
+	VADD_MI_F32
+	VADD_PL_F32
+	VADD_VS_F32
+	VADD_VC_F32
+	VADD_HI_F32
+	VADD_LS_F32
+	VADD_GE_F32
+	VADD_LT_F32
+	VADD_GT_F32
+	VADD_LE_F32
+	VADD_F32
+	VADD_ZZ_F32
+	VADD_EQ_F64
+	VADD_NE_F64
+	VADD_CS_F64
+	VADD_CC_F64
+	VADD_MI_F64
+	VADD_PL_F64
+	VADD_VS_F64
+	VADD_VC_F64
+	VADD_HI_F64
+	VADD_LS_F64
+	VADD_GE_F64
+	VADD_LT_F64
+	VADD_GT_F64
+	VADD_LE_F64
+	VADD_F64
+	VADD_ZZ_F64
+	VCMP_EQ_F32
+	VCMP_NE_F32
+	VCMP_CS_F32
+	VCMP_CC_F32
+	VCMP_MI_F32
+	VCMP_PL_F32
+	VCMP_VS_F32
+	VCMP_VC_F32
+	VCMP_HI_F32
+	VCMP_LS_F32
+	VCMP_GE_F32
+	VCMP_LT_F32
+	VCMP_GT_F32
+	VCMP_LE_F32
+	VCMP_F32
+	VCMP_ZZ_F32
+	VCMP_EQ_F64
+	VCMP_NE_F64
+	VCMP_CS_F64
+	VCMP_CC_F64
+	VCMP_MI_F64
+	VCMP_PL_F64
+	VCMP_VS_F64
+	VCMP_VC_F64
+	VCMP_HI_F64
+	VCMP_LS_F64
+	VCMP_GE_F64
+	VCMP_LT_F64
+	VCMP_GT_F64
+	VCMP_LE_F64
+	VCMP_F64
+	VCMP_ZZ_F64
+	VCMP_E_EQ_F32
+	VCMP_E_NE_F32
+	VCMP_E_CS_F32
+	VCMP_E_CC_F32
+	VCMP_E_MI_F32
+	VCMP_E_PL_F32
+	VCMP_E_VS_F32
+	VCMP_E_VC_F32
+	VCMP_E_HI_F32
+	VCMP_E_LS_F32
+	VCMP_E_GE_F32
+	VCMP_E_LT_F32
+	VCMP_E_GT_F32
+	VCMP_E_LE_F32
+	VCMP_E_F32
+	VCMP_E_ZZ_F32
+	VCMP_E_EQ_F64
+	VCMP_E_NE_F64
+	VCMP_E_CS_F64
+	VCMP_E_CC_F64
+	VCMP_E_MI_F64
+	VCMP_E_PL_F64
+	VCMP_E_VS_F64
+	VCMP_E_VC_F64
+	VCMP_E_HI_F64
+	VCMP_E_LS_F64
+	VCMP_E_GE_F64
+	VCMP_E_LT_F64
+	VCMP_E_GT_F64
+	VCMP_E_LE_F64
+	VCMP_E_F64
+	VCMP_E_ZZ_F64
+	VCVT_EQ_F32_FXS16
+	VCVT_NE_F32_FXS16
+	VCVT_CS_F32_FXS16
+	VCVT_CC_F32_FXS16
+	VCVT_MI_F32_FXS16
+	VCVT_PL_F32_FXS16
+	VCVT_VS_F32_FXS16
+	VCVT_VC_F32_FXS16
+	VCVT_HI_F32_FXS16
+	VCVT_LS_F32_FXS16
+	VCVT_GE_F32_FXS16
+	VCVT_LT_F32_FXS16
+	VCVT_GT_F32_FXS16
+	VCVT_LE_F32_FXS16
+	VCVT_F32_FXS16
+	VCVT_ZZ_F32_FXS16
+	VCVT_EQ_F32_FXS32
+	VCVT_NE_F32_FXS32
+	VCVT_CS_F32_FXS32
+	VCVT_CC_F32_FXS32
+	VCVT_MI_F32_FXS32
+	VCVT_PL_F32_FXS32
+	VCVT_VS_F32_FXS32
+	VCVT_VC_F32_FXS32
+	VCVT_HI_F32_FXS32
+	VCVT_LS_F32_FXS32
+	VCVT_GE_F32_FXS32
+	VCVT_LT_F32_FXS32
+	VCVT_GT_F32_FXS32
+	VCVT_LE_F32_FXS32
+	VCVT_F32_FXS32
+	VCVT_ZZ_F32_FXS32
+	VCVT_EQ_F32_FXU16
+	VCVT_NE_F32_FXU16
+	VCVT_CS_F32_FXU16
+	VCVT_CC_F32_FXU16
+	VCVT_MI_F32_FXU16
+	VCVT_PL_F32_FXU16
+	VCVT_VS_F32_FXU16
+	VCVT_VC_F32_FXU16
+	VCVT_HI_F32_FXU16
+	VCVT_LS_F32_FXU16
+	VCVT_GE_F32_FXU16
+	VCVT_LT_F32_FXU16
+	VCVT_GT_F32_FXU16
+	VCVT_LE_F32_FXU16
+	VCVT_F32_FXU16
+	VCVT_ZZ_F32_FXU16
+	VCVT_EQ_F32_FXU32
+	VCVT_NE_F32_FXU32
+	VCVT_CS_F32_FXU32
+	VCVT_CC_F32_FXU32
+	VCVT_MI_F32_FXU32
+	VCVT_PL_F32_FXU32
+	VCVT_VS_F32_FXU32
+	VCVT_VC_F32_FXU32
+	VCVT_HI_F32_FXU32
+	VCVT_LS_F32_FXU32
+	VCVT_GE_F32_FXU32
+	VCVT_LT_F32_FXU32
+	VCVT_GT_F32_FXU32
+	VCVT_LE_F32_FXU32
+	VCVT_F32_FXU32
+	VCVT_ZZ_F32_FXU32
+	VCVT_EQ_F64_FXS16
+	VCVT_NE_F64_FXS16
+	VCVT_CS_F64_FXS16
+	VCVT_CC_F64_FXS16
+	VCVT_MI_F64_FXS16
+	VCVT_PL_F64_FXS16
+	VCVT_VS_F64_FXS16
+	VCVT_VC_F64_FXS16
+	VCVT_HI_F64_FXS16
+	VCVT_LS_F64_FXS16
+	VCVT_GE_F64_FXS16
+	VCVT_LT_F64_FXS16
+	VCVT_GT_F64_FXS16
+	VCVT_LE_F64_FXS16
+	VCVT_F64_FXS16
+	VCVT_ZZ_F64_FXS16
+	VCVT_EQ_F64_FXS32
+	VCVT_NE_F64_FXS32
+	VCVT_CS_F64_FXS32
+	VCVT_CC_F64_FXS32
+	VCVT_MI_F64_FXS32
+	VCVT_PL_F64_FXS32
+	VCVT_VS_F64_FXS32
+	VCVT_VC_F64_FXS32
+	VCVT_HI_F64_FXS32
+	VCVT_LS_F64_FXS32
+	VCVT_GE_F64_FXS32
+	VCVT_LT_F64_FXS32
+	VCVT_GT_F64_FXS32
+	VCVT_LE_F64_FXS32
+	VCVT_F64_FXS32
+	VCVT_ZZ_F64_FXS32
+	VCVT_EQ_F64_FXU16
+	VCVT_NE_F64_FXU16
+	VCVT_CS_F64_FXU16
+	VCVT_CC_F64_FXU16
+	VCVT_MI_F64_FXU16
+	VCVT_PL_F64_FXU16
+	VCVT_VS_F64_FXU16
+	VCVT_VC_F64_FXU16
+	VCVT_HI_F64_FXU16
+	VCVT_LS_F64_FXU16
+	VCVT_GE_F64_FXU16
+	VCVT_LT_F64_FXU16
+	VCVT_GT_F64_FXU16
+	VCVT_LE_F64_FXU16
+	VCVT_F64_FXU16
+	VCVT_ZZ_F64_FXU16
+	VCVT_EQ_F64_FXU32
+	VCVT_NE_F64_FXU32
+	VCVT_CS_F64_FXU32
+	VCVT_CC_F64_FXU32
+	VCVT_MI_F64_FXU32
+	VCVT_PL_F64_FXU32
+	VCVT_VS_F64_FXU32
+	VCVT_VC_F64_FXU32
+	VCVT_HI_F64_FXU32
+	VCVT_LS_F64_FXU32
+	VCVT_GE_F64_FXU32
+	VCVT_LT_F64_FXU32
+	VCVT_GT_F64_FXU32
+	VCVT_LE_F64_FXU32
+	VCVT_F64_FXU32
+	VCVT_ZZ_F64_FXU32
+	VCVT_EQ_F32_U32
+	VCVT_NE_F32_U32
+	VCVT_CS_F32_U32
+	VCVT_CC_F32_U32
+	VCVT_MI_F32_U32
+	VCVT_PL_F32_U32
+	VCVT_VS_F32_U32
+	VCVT_VC_F32_U32
+	VCVT_HI_F32_U32
+	VCVT_LS_F32_U32
+	VCVT_GE_F32_U32
+	VCVT_LT_F32_U32
+	VCVT_GT_F32_U32
+	VCVT_LE_F32_U32
+	VCVT_F32_U32
+	VCVT_ZZ_F32_U32
+	VCVT_EQ_F32_S32
+	VCVT_NE_F32_S32
+	VCVT_CS_F32_S32
+	VCVT_CC_F32_S32
+	VCVT_MI_F32_S32
+	VCVT_PL_F32_S32
+	VCVT_VS_F32_S32
+	VCVT_VC_F32_S32
+	VCVT_HI_F32_S32
+	VCVT_LS_F32_S32
+	VCVT_GE_F32_S32
+	VCVT_LT_F32_S32
+	VCVT_GT_F32_S32
+	VCVT_LE_F32_S32
+	VCVT_F32_S32
+	VCVT_ZZ_F32_S32
+	VCVT_EQ_F64_U32
+	VCVT_NE_F64_U32
+	VCVT_CS_F64_U32
+	VCVT_CC_F64_U32
+	VCVT_MI_F64_U32
+	VCVT_PL_F64_U32
+	VCVT_VS_F64_U32
+	VCVT_VC_F64_U32
+	VCVT_HI_F64_U32
+	VCVT_LS_F64_U32
+	VCVT_GE_F64_U32
+	VCVT_LT_F64_U32
+	VCVT_GT_F64_U32
+	VCVT_LE_F64_U32
+	VCVT_F64_U32
+	VCVT_ZZ_F64_U32
+	VCVT_EQ_F64_S32
+	VCVT_NE_F64_S32
+	VCVT_CS_F64_S32
+	VCVT_CC_F64_S32
+	VCVT_MI_F64_S32
+	VCVT_PL_F64_S32
+	VCVT_VS_F64_S32
+	VCVT_VC_F64_S32
+	VCVT_HI_F64_S32
+	VCVT_LS_F64_S32
+	VCVT_GE_F64_S32
+	VCVT_LT_F64_S32
+	VCVT_GT_F64_S32
+	VCVT_LE_F64_S32
+	VCVT_F64_S32
+	VCVT_ZZ_F64_S32
+	VCVT_EQ_F64_F32
+	VCVT_NE_F64_F32
+	VCVT_CS_F64_F32
+	VCVT_CC_F64_F32
+	VCVT_MI_F64_F32
+	VCVT_PL_F64_F32
+	VCVT_VS_F64_F32
+	VCVT_VC_F64_F32
+	VCVT_HI_F64_F32
+	VCVT_LS_F64_F32
+	VCVT_GE_F64_F32
+	VCVT_LT_F64_F32
+	VCVT_GT_F64_F32
+	VCVT_LE_F64_F32
+	VCVT_F64_F32
+	VCVT_ZZ_F64_F32
+	VCVT_EQ_F32_F64
+	VCVT_NE_F32_F64
+	VCVT_CS_F32_F64
+	VCVT_CC_F32_F64
+	VCVT_MI_F32_F64
+	VCVT_PL_F32_F64
+	VCVT_VS_F32_F64
+	VCVT_VC_F32_F64
+	VCVT_HI_F32_F64
+	VCVT_LS_F32_F64
+	VCVT_GE_F32_F64
+	VCVT_LT_F32_F64
+	VCVT_GT_F32_F64
+	VCVT_LE_F32_F64
+	VCVT_F32_F64
+	VCVT_ZZ_F32_F64
+	VCVT_EQ_FXS16_F32
+	VCVT_NE_FXS16_F32
+	VCVT_CS_FXS16_F32
+	VCVT_CC_FXS16_F32
+	VCVT_MI_FXS16_F32
+	VCVT_PL_FXS16_F32
+	VCVT_VS_FXS16_F32
+	VCVT_VC_FXS16_F32
+	VCVT_HI_FXS16_F32
+	VCVT_LS_FXS16_F32
+	VCVT_GE_FXS16_F32
+	VCVT_LT_FXS16_F32
+	VCVT_GT_FXS16_F32
+	VCVT_LE_FXS16_F32
+	VCVT_FXS16_F32
+	VCVT_ZZ_FXS16_F32
+	VCVT_EQ_FXS16_F64
+	VCVT_NE_FXS16_F64
+	VCVT_CS_FXS16_F64
+	VCVT_CC_FXS16_F64
+	VCVT_MI_FXS16_F64
+	VCVT_PL_FXS16_F64
+	VCVT_VS_FXS16_F64
+	VCVT_VC_FXS16_F64
+	VCVT_HI_FXS16_F64
+	VCVT_LS_FXS16_F64
+	VCVT_GE_FXS16_F64
+	VCVT_LT_FXS16_F64
+	VCVT_GT_FXS16_F64
+	VCVT_LE_FXS16_F64
+	VCVT_FXS16_F64
+	VCVT_ZZ_FXS16_F64
+	VCVT_EQ_FXS32_F32
+	VCVT_NE_FXS32_F32
+	VCVT_CS_FXS32_F32
+	VCVT_CC_FXS32_F32
+	VCVT_MI_FXS32_F32
+	VCVT_PL_FXS32_F32
+	VCVT_VS_FXS32_F32
+	VCVT_VC_FXS32_F32
+	VCVT_HI_FXS32_F32
+	VCVT_LS_FXS32_F32
+	VCVT_GE_FXS32_F32
+	VCVT_LT_FXS32_F32
+	VCVT_GT_FXS32_F32
+	VCVT_LE_FXS32_F32
+	VCVT_FXS32_F32
+	VCVT_ZZ_FXS32_F32
+	VCVT_EQ_FXS32_F64
+	VCVT_NE_FXS32_F64
+	VCVT_CS_FXS32_F64
+	VCVT_CC_FXS32_F64
+	VCVT_MI_FXS32_F64
+	VCVT_PL_FXS32_F64
+	VCVT_VS_FXS32_F64
+	VCVT_VC_FXS32_F64
+	VCVT_HI_FXS32_F64
+	VCVT_LS_FXS32_F64
+	VCVT_GE_FXS32_F64
+	VCVT_LT_FXS32_F64
+	VCVT_GT_FXS32_F64
+	VCVT_LE_FXS32_F64
+	VCVT_FXS32_F64
+	VCVT_ZZ_FXS32_F64
+	VCVT_EQ_FXU16_F32
+	VCVT_NE_FXU16_F32
+	VCVT_CS_FXU16_F32
+	VCVT_CC_FXU16_F32
+	VCVT_MI_FXU16_F32
+	VCVT_PL_FXU16_F32
+	VCVT_VS_FXU16_F32
+	VCVT_VC_FXU16_F32
+	VCVT_HI_FXU16_F32
+	VCVT_LS_FXU16_F32
+	VCVT_GE_FXU16_F32
+	VCVT_LT_FXU16_F32
+	VCVT_GT_FXU16_F32
+	VCVT_LE_FXU16_F32
+	VCVT_FXU16_F32
+	VCVT_ZZ_FXU16_F32
+	VCVT_EQ_FXU16_F64
+	VCVT_NE_FXU16_F64
+	VCVT_CS_FXU16_F64
+	VCVT_CC_FXU16_F64
+	VCVT_MI_FXU16_F64
+	VCVT_PL_FXU16_F64
+	VCVT_VS_FXU16_F64
+	VCVT_VC_FXU16_F64
+	VCVT_HI_FXU16_F64
+	VCVT_LS_FXU16_F64
+	VCVT_GE_FXU16_F64
+	VCVT_LT_FXU16_F64
+	VCVT_GT_FXU16_F64
+	VCVT_LE_FXU16_F64
+	VCVT_FXU16_F64
+	VCVT_ZZ_FXU16_F64
+	VCVT_EQ_FXU32_F32
+	VCVT_NE_FXU32_F32
+	VCVT_CS_FXU32_F32
+	VCVT_CC_FXU32_F32
+	VCVT_MI_FXU32_F32
+	VCVT_PL_FXU32_F32
+	VCVT_VS_FXU32_F32
+	VCVT_VC_FXU32_F32
+	VCVT_HI_FXU32_F32
+	VCVT_LS_FXU32_F32
+	VCVT_GE_FXU32_F32
+	VCVT_LT_FXU32_F32
+	VCVT_GT_FXU32_F32
+	VCVT_LE_FXU32_F32
+	VCVT_FXU32_F32
+	VCVT_ZZ_FXU32_F32
+	VCVT_EQ_FXU32_F64
+	VCVT_NE_FXU32_F64
+	VCVT_CS_FXU32_F64
+	VCVT_CC_FXU32_F64
+	VCVT_MI_FXU32_F64
+	VCVT_PL_FXU32_F64
+	VCVT_VS_FXU32_F64
+	VCVT_VC_FXU32_F64
+	VCVT_HI_FXU32_F64
+	VCVT_LS_FXU32_F64
+	VCVT_GE_FXU32_F64
+	VCVT_LT_FXU32_F64
+	VCVT_GT_FXU32_F64
+	VCVT_LE_FXU32_F64
+	VCVT_FXU32_F64
+	VCVT_ZZ_FXU32_F64
+	VCVTB_EQ_F32_F16
+	VCVTB_NE_F32_F16
+	VCVTB_CS_F32_F16
+	VCVTB_CC_F32_F16
+	VCVTB_MI_F32_F16
+	VCVTB_PL_F32_F16
+	VCVTB_VS_F32_F16
+	VCVTB_VC_F32_F16
+	VCVTB_HI_F32_F16
+	VCVTB_LS_F32_F16
+	VCVTB_GE_F32_F16
+	VCVTB_LT_F32_F16
+	VCVTB_GT_F32_F16
+	VCVTB_LE_F32_F16
+	VCVTB_F32_F16
+	VCVTB_ZZ_F32_F16
+	VCVTB_EQ_F16_F32
+	VCVTB_NE_F16_F32
+	VCVTB_CS_F16_F32
+	VCVTB_CC_F16_F32
+	VCVTB_MI_F16_F32
+	VCVTB_PL_F16_F32
+	VCVTB_VS_F16_F32
+	VCVTB_VC_F16_F32
+	VCVTB_HI_F16_F32
+	VCVTB_LS_F16_F32
+	VCVTB_GE_F16_F32
+	VCVTB_LT_F16_F32
+	VCVTB_GT_F16_F32
+	VCVTB_LE_F16_F32
+	VCVTB_F16_F32
+	VCVTB_ZZ_F16_F32
+	VCVTT_EQ_F32_F16
+	VCVTT_NE_F32_F16
+	VCVTT_CS_F32_F16
+	VCVTT_CC_F32_F16
+	VCVTT_MI_F32_F16
+	VCVTT_PL_F32_F16
+	VCVTT_VS_F32_F16
+	VCVTT_VC_F32_F16
+	VCVTT_HI_F32_F16
+	VCVTT_LS_F32_F16
+	VCVTT_GE_F32_F16
+	VCVTT_LT_F32_F16
+	VCVTT_GT_F32_F16
+	VCVTT_LE_F32_F16
+	VCVTT_F32_F16
+	VCVTT_ZZ_F32_F16
+	VCVTT_EQ_F16_F32
+	VCVTT_NE_F16_F32
+	VCVTT_CS_F16_F32
+	VCVTT_CC_F16_F32
+	VCVTT_MI_F16_F32
+	VCVTT_PL_F16_F32
+	VCVTT_VS_F16_F32
+	VCVTT_VC_F16_F32
+	VCVTT_HI_F16_F32
+	VCVTT_LS_F16_F32
+	VCVTT_GE_F16_F32
+	VCVTT_LT_F16_F32
+	VCVTT_GT_F16_F32
+	VCVTT_LE_F16_F32
+	VCVTT_F16_F32
+	VCVTT_ZZ_F16_F32
+	VCVTR_EQ_U32_F32
+	VCVTR_NE_U32_F32
+	VCVTR_CS_U32_F32
+	VCVTR_CC_U32_F32
+	VCVTR_MI_U32_F32
+	VCVTR_PL_U32_F32
+	VCVTR_VS_U32_F32
+	VCVTR_VC_U32_F32
+	VCVTR_HI_U32_F32
+	VCVTR_LS_U32_F32
+	VCVTR_GE_U32_F32
+	VCVTR_LT_U32_F32
+	VCVTR_GT_U32_F32
+	VCVTR_LE_U32_F32
+	VCVTR_U32_F32
+	VCVTR_ZZ_U32_F32
+	VCVTR_EQ_U32_F64
+	VCVTR_NE_U32_F64
+	VCVTR_CS_U32_F64
+	VCVTR_CC_U32_F64
+	VCVTR_MI_U32_F64
+	VCVTR_PL_U32_F64
+	VCVTR_VS_U32_F64
+	VCVTR_VC_U32_F64
+	VCVTR_HI_U32_F64
+	VCVTR_LS_U32_F64
+	VCVTR_GE_U32_F64
+	VCVTR_LT_U32_F64
+	VCVTR_GT_U32_F64
+	VCVTR_LE_U32_F64
+	VCVTR_U32_F64
+	VCVTR_ZZ_U32_F64
+	VCVTR_EQ_S32_F32
+	VCVTR_NE_S32_F32
+	VCVTR_CS_S32_F32
+	VCVTR_CC_S32_F32
+	VCVTR_MI_S32_F32
+	VCVTR_PL_S32_F32
+	VCVTR_VS_S32_F32
+	VCVTR_VC_S32_F32
+	VCVTR_HI_S32_F32
+	VCVTR_LS_S32_F32
+	VCVTR_GE_S32_F32
+	VCVTR_LT_S32_F32
+	VCVTR_GT_S32_F32
+	VCVTR_LE_S32_F32
+	VCVTR_S32_F32
+	VCVTR_ZZ_S32_F32
+	VCVTR_EQ_S32_F64
+	VCVTR_NE_S32_F64
+	VCVTR_CS_S32_F64
+	VCVTR_CC_S32_F64
+	VCVTR_MI_S32_F64
+	VCVTR_PL_S32_F64
+	VCVTR_VS_S32_F64
+	VCVTR_VC_S32_F64
+	VCVTR_HI_S32_F64
+	VCVTR_LS_S32_F64
+	VCVTR_GE_S32_F64
+	VCVTR_LT_S32_F64
+	VCVTR_GT_S32_F64
+	VCVTR_LE_S32_F64
+	VCVTR_S32_F64
+	VCVTR_ZZ_S32_F64
+	VCVT_EQ_U32_F32
+	VCVT_NE_U32_F32
+	VCVT_CS_U32_F32
+	VCVT_CC_U32_F32
+	VCVT_MI_U32_F32
+	VCVT_PL_U32_F32
+	VCVT_VS_U32_F32
+	VCVT_VC_U32_F32
+	VCVT_HI_U32_F32
+	VCVT_LS_U32_F32
+	VCVT_GE_U32_F32
+	VCVT_LT_U32_F32
+	VCVT_GT_U32_F32
+	VCVT_LE_U32_F32
+	VCVT_U32_F32
+	VCVT_ZZ_U32_F32
+	VCVT_EQ_U32_F64
+	VCVT_NE_U32_F64
+	VCVT_CS_U32_F64
+	VCVT_CC_U32_F64
+	VCVT_MI_U32_F64
+	VCVT_PL_U32_F64
+	VCVT_VS_U32_F64
+	VCVT_VC_U32_F64
+	VCVT_HI_U32_F64
+	VCVT_LS_U32_F64
+	VCVT_GE_U32_F64
+	VCVT_LT_U32_F64
+	VCVT_GT_U32_F64
+	VCVT_LE_U32_F64
+	VCVT_U32_F64
+	VCVT_ZZ_U32_F64
+	VCVT_EQ_S32_F32
+	VCVT_NE_S32_F32
+	VCVT_CS_S32_F32
+	VCVT_CC_S32_F32
+	VCVT_MI_S32_F32
+	VCVT_PL_S32_F32
+	VCVT_VS_S32_F32
+	VCVT_VC_S32_F32
+	VCVT_HI_S32_F32
+	VCVT_LS_S32_F32
+	VCVT_GE_S32_F32
+	VCVT_LT_S32_F32
+	VCVT_GT_S32_F32
+	VCVT_LE_S32_F32
+	VCVT_S32_F32
+	VCVT_ZZ_S32_F32
+	VCVT_EQ_S32_F64
+	VCVT_NE_S32_F64
+	VCVT_CS_S32_F64
+	VCVT_CC_S32_F64
+	VCVT_MI_S32_F64
+	VCVT_PL_S32_F64
+	VCVT_VS_S32_F64
+	VCVT_VC_S32_F64
+	VCVT_HI_S32_F64
+	VCVT_LS_S32_F64
+	VCVT_GE_S32_F64
+	VCVT_LT_S32_F64
+	VCVT_GT_S32_F64
+	VCVT_LE_S32_F64
+	VCVT_S32_F64
+	VCVT_ZZ_S32_F64
+	VDIV_EQ_F32
+	VDIV_NE_F32
+	VDIV_CS_F32
+	VDIV_CC_F32
+	VDIV_MI_F32
+	VDIV_PL_F32
+	VDIV_VS_F32
+	VDIV_VC_F32
+	VDIV_HI_F32
+	VDIV_LS_F32
+	VDIV_GE_F32
+	VDIV_LT_F32
+	VDIV_GT_F32
+	VDIV_LE_F32
+	VDIV_F32
+	VDIV_ZZ_F32
+	VDIV_EQ_F64
+	VDIV_NE_F64
+	VDIV_CS_F64
+	VDIV_CC_F64
+	VDIV_MI_F64
+	VDIV_PL_F64
+	VDIV_VS_F64
+	VDIV_VC_F64
+	VDIV_HI_F64
+	VDIV_LS_F64
+	VDIV_GE_F64
+	VDIV_LT_F64
+	VDIV_GT_F64
+	VDIV_LE_F64
+	VDIV_F64
+	VDIV_ZZ_F64
+	VLDR_EQ
+	VLDR_NE
+	VLDR_CS
+	VLDR_CC
+	VLDR_MI
+	VLDR_PL
+	VLDR_VS
+	VLDR_VC
+	VLDR_HI
+	VLDR_LS
+	VLDR_GE
+	VLDR_LT
+	VLDR_GT
+	VLDR_LE
+	VLDR
+	VLDR_ZZ
+	VMLA_EQ_F32
+	VMLA_NE_F32
+	VMLA_CS_F32
+	VMLA_CC_F32
+	VMLA_MI_F32
+	VMLA_PL_F32
+	VMLA_VS_F32
+	VMLA_VC_F32
+	VMLA_HI_F32
+	VMLA_LS_F32
+	VMLA_GE_F32
+	VMLA_LT_F32
+	VMLA_GT_F32
+	VMLA_LE_F32
+	VMLA_F32
+	VMLA_ZZ_F32
+	VMLA_EQ_F64
+	VMLA_NE_F64
+	VMLA_CS_F64
+	VMLA_CC_F64
+	VMLA_MI_F64
+	VMLA_PL_F64
+	VMLA_VS_F64
+	VMLA_VC_F64
+	VMLA_HI_F64
+	VMLA_LS_F64
+	VMLA_GE_F64
+	VMLA_LT_F64
+	VMLA_GT_F64
+	VMLA_LE_F64
+	VMLA_F64
+	VMLA_ZZ_F64
+	VMLS_EQ_F32
+	VMLS_NE_F32
+	VMLS_CS_F32
+	VMLS_CC_F32
+	VMLS_MI_F32
+	VMLS_PL_F32
+	VMLS_VS_F32
+	VMLS_VC_F32
+	VMLS_HI_F32
+	VMLS_LS_F32
+	VMLS_GE_F32
+	VMLS_LT_F32
+	VMLS_GT_F32
+	VMLS_LE_F32
+	VMLS_F32
+	VMLS_ZZ_F32
+	VMLS_EQ_F64
+	VMLS_NE_F64
+	VMLS_CS_F64
+	VMLS_CC_F64
+	VMLS_MI_F64
+	VMLS_PL_F64
+	VMLS_VS_F64
+	VMLS_VC_F64
+	VMLS_HI_F64
+	VMLS_LS_F64
+	VMLS_GE_F64
+	VMLS_LT_F64
+	VMLS_GT_F64
+	VMLS_LE_F64
+	VMLS_F64
+	VMLS_ZZ_F64
+	VMOV_EQ
+	VMOV_NE
+	VMOV_CS
+	VMOV_CC
+	VMOV_MI
+	VMOV_PL
+	VMOV_VS
+	VMOV_VC
+	VMOV_HI
+	VMOV_LS
+	VMOV_GE
+	VMOV_LT
+	VMOV_GT
+	VMOV_LE
+	VMOV
+	VMOV_ZZ
+	VMOV_EQ_32
+	VMOV_NE_32
+	VMOV_CS_32
+	VMOV_CC_32
+	VMOV_MI_32
+	VMOV_PL_32
+	VMOV_VS_32
+	VMOV_VC_32
+	VMOV_HI_32
+	VMOV_LS_32
+	VMOV_GE_32
+	VMOV_LT_32
+	VMOV_GT_32
+	VMOV_LE_32
+	VMOV_32
+	VMOV_ZZ_32
+	VMOV_EQ_F32
+	VMOV_NE_F32
+	VMOV_CS_F32
+	VMOV_CC_F32
+	VMOV_MI_F32
+	VMOV_PL_F32
+	VMOV_VS_F32
+	VMOV_VC_F32
+	VMOV_HI_F32
+	VMOV_LS_F32
+	VMOV_GE_F32
+	VMOV_LT_F32
+	VMOV_GT_F32
+	VMOV_LE_F32
+	VMOV_F32
+	VMOV_ZZ_F32
+	VMOV_EQ_F64
+	VMOV_NE_F64
+	VMOV_CS_F64
+	VMOV_CC_F64
+	VMOV_MI_F64
+	VMOV_PL_F64
+	VMOV_VS_F64
+	VMOV_VC_F64
+	VMOV_HI_F64
+	VMOV_LS_F64
+	VMOV_GE_F64
+	VMOV_LT_F64
+	VMOV_GT_F64
+	VMOV_LE_F64
+	VMOV_F64
+	VMOV_ZZ_F64
+	VMRS_EQ
+	VMRS_NE
+	VMRS_CS
+	VMRS_CC
+	VMRS_MI
+	VMRS_PL
+	VMRS_VS
+	VMRS_VC
+	VMRS_HI
+	VMRS_LS
+	VMRS_GE
+	VMRS_LT
+	VMRS_GT
+	VMRS_LE
+	VMRS
+	VMRS_ZZ
+	VMSR_EQ
+	VMSR_NE
+	VMSR_CS
+	VMSR_CC
+	VMSR_MI
+	VMSR_PL
+	VMSR_VS
+	VMSR_VC
+	VMSR_HI
+	VMSR_LS
+	VMSR_GE
+	VMSR_LT
+	VMSR_GT
+	VMSR_LE
+	VMSR
+	VMSR_ZZ
+	VMUL_EQ_F32
+	VMUL_NE_F32
+	VMUL_CS_F32
+	VMUL_CC_F32
+	VMUL_MI_F32
+	VMUL_PL_F32
+	VMUL_VS_F32
+	VMUL_VC_F32
+	VMUL_HI_F32
+	VMUL_LS_F32
+	VMUL_GE_F32
+	VMUL_LT_F32
+	VMUL_GT_F32
+	VMUL_LE_F32
+	VMUL_F32
+	VMUL_ZZ_F32
+	VMUL_EQ_F64
+	VMUL_NE_F64
+	VMUL_CS_F64
+	VMUL_CC_F64
+	VMUL_MI_F64
+	VMUL_PL_F64
+	VMUL_VS_F64
+	VMUL_VC_F64
+	VMUL_HI_F64
+	VMUL_LS_F64
+	VMUL_GE_F64
+	VMUL_LT_F64
+	VMUL_GT_F64
+	VMUL_LE_F64
+	VMUL_F64
+	VMUL_ZZ_F64
+	VNEG_EQ_F32
+	VNEG_NE_F32
+	VNEG_CS_F32
+	VNEG_CC_F32
+	VNEG_MI_F32
+	VNEG_PL_F32
+	VNEG_VS_F32
+	VNEG_VC_F32
+	VNEG_HI_F32
+	VNEG_LS_F32
+	VNEG_GE_F32
+	VNEG_LT_F32
+	VNEG_GT_F32
+	VNEG_LE_F32
+	VNEG_F32
+	VNEG_ZZ_F32
+	VNEG_EQ_F64
+	VNEG_NE_F64
+	VNEG_CS_F64
+	VNEG_CC_F64
+	VNEG_MI_F64
+	VNEG_PL_F64
+	VNEG_VS_F64
+	VNEG_VC_F64
+	VNEG_HI_F64
+	VNEG_LS_F64
+	VNEG_GE_F64
+	VNEG_LT_F64
+	VNEG_GT_F64
+	VNEG_LE_F64
+	VNEG_F64
+	VNEG_ZZ_F64
+	VNMLS_EQ_F32
+	VNMLS_NE_F32
+	VNMLS_CS_F32
+	VNMLS_CC_F32
+	VNMLS_MI_F32
+	VNMLS_PL_F32
+	VNMLS_VS_F32
+	VNMLS_VC_F32
+	VNMLS_HI_F32
+	VNMLS_LS_F32
+	VNMLS_GE_F32
+	VNMLS_LT_F32
+	VNMLS_GT_F32
+	VNMLS_LE_F32
+	VNMLS_F32
+	VNMLS_ZZ_F32
+	VNMLS_EQ_F64
+	VNMLS_NE_F64
+	VNMLS_CS_F64
+	VNMLS_CC_F64
+	VNMLS_MI_F64
+	VNMLS_PL_F64
+	VNMLS_VS_F64
+	VNMLS_VC_F64
+	VNMLS_HI_F64
+	VNMLS_LS_F64
+	VNMLS_GE_F64
+	VNMLS_LT_F64
+	VNMLS_GT_F64
+	VNMLS_LE_F64
+	VNMLS_F64
+	VNMLS_ZZ_F64
+	VNMLA_EQ_F32
+	VNMLA_NE_F32
+	VNMLA_CS_F32
+	VNMLA_CC_F32
+	VNMLA_MI_F32
+	VNMLA_PL_F32
+	VNMLA_VS_F32
+	VNMLA_VC_F32
+	VNMLA_HI_F32
+	VNMLA_LS_F32
+	VNMLA_GE_F32
+	VNMLA_LT_F32
+	VNMLA_GT_F32
+	VNMLA_LE_F32
+	VNMLA_F32
+	VNMLA_ZZ_F32
+	VNMLA_EQ_F64
+	VNMLA_NE_F64
+	VNMLA_CS_F64
+	VNMLA_CC_F64
+	VNMLA_MI_F64
+	VNMLA_PL_F64
+	VNMLA_VS_F64
+	VNMLA_VC_F64
+	VNMLA_HI_F64
+	VNMLA_LS_F64
+	VNMLA_GE_F64
+	VNMLA_LT_F64
+	VNMLA_GT_F64
+	VNMLA_LE_F64
+	VNMLA_F64
+	VNMLA_ZZ_F64
+	VNMUL_EQ_F32
+	VNMUL_NE_F32
+	VNMUL_CS_F32
+	VNMUL_CC_F32
+	VNMUL_MI_F32
+	VNMUL_PL_F32
+	VNMUL_VS_F32
+	VNMUL_VC_F32
+	VNMUL_HI_F32
+	VNMUL_LS_F32
+	VNMUL_GE_F32
+	VNMUL_LT_F32
+	VNMUL_GT_F32
+	VNMUL_LE_F32
+	VNMUL_F32
+	VNMUL_ZZ_F32
+	VNMUL_EQ_F64
+	VNMUL_NE_F64
+	VNMUL_CS_F64
+	VNMUL_CC_F64
+	VNMUL_MI_F64
+	VNMUL_PL_F64
+	VNMUL_VS_F64
+	VNMUL_VC_F64
+	VNMUL_HI_F64
+	VNMUL_LS_F64
+	VNMUL_GE_F64
+	VNMUL_LT_F64
+	VNMUL_GT_F64
+	VNMUL_LE_F64
+	VNMUL_F64
+	VNMUL_ZZ_F64
+	VSQRT_EQ_F32
+	VSQRT_NE_F32
+	VSQRT_CS_F32
+	VSQRT_CC_F32
+	VSQRT_MI_F32
+	VSQRT_PL_F32
+	VSQRT_VS_F32
+	VSQRT_VC_F32
+	VSQRT_HI_F32
+	VSQRT_LS_F32
+	VSQRT_GE_F32
+	VSQRT_LT_F32
+	VSQRT_GT_F32
+	VSQRT_LE_F32
+	VSQRT_F32
+	VSQRT_ZZ_F32
+	VSQRT_EQ_F64
+	VSQRT_NE_F64
+	VSQRT_CS_F64
+	VSQRT_CC_F64
+	VSQRT_MI_F64
+	VSQRT_PL_F64
+	VSQRT_VS_F64
+	VSQRT_VC_F64
+	VSQRT_HI_F64
+	VSQRT_LS_F64
+	VSQRT_GE_F64
+	VSQRT_LT_F64
+	VSQRT_GT_F64
+	VSQRT_LE_F64
+	VSQRT_F64
+	VSQRT_ZZ_F64
+	VSTR_EQ
+	VSTR_NE
+	VSTR_CS
+	VSTR_CC
+	VSTR_MI
+	VSTR_PL
+	VSTR_VS
+	VSTR_VC
+	VSTR_HI
+	VSTR_LS
+	VSTR_GE
+	VSTR_LT
+	VSTR_GT
+	VSTR_LE
+	VSTR
+	VSTR_ZZ
+	VSUB_EQ_F32
+	VSUB_NE_F32
+	VSUB_CS_F32
+	VSUB_CC_F32
+	VSUB_MI_F32
+	VSUB_PL_F32
+	VSUB_VS_F32
+	VSUB_VC_F32
+	VSUB_HI_F32
+	VSUB_LS_F32
+	VSUB_GE_F32
+	VSUB_LT_F32
+	VSUB_GT_F32
+	VSUB_LE_F32
+	VSUB_F32
+	VSUB_ZZ_F32
+	VSUB_EQ_F64
+	VSUB_NE_F64
+	VSUB_CS_F64
+	VSUB_CC_F64
+	VSUB_MI_F64
+	VSUB_PL_F64
+	VSUB_VS_F64
+	VSUB_VC_F64
+	VSUB_HI_F64
+	VSUB_LS_F64
+	VSUB_GE_F64
+	VSUB_LT_F64
+	VSUB_GT_F64
+	VSUB_LE_F64
+	VSUB_F64
+	VSUB_ZZ_F64
+	WFE_EQ
+	WFE_NE
+	WFE_CS
+	WFE_CC
+	WFE_MI
+	WFE_PL
+	WFE_VS
+	WFE_VC
+	WFE_HI
+	WFE_LS
+	WFE_GE
+	WFE_LT
+	WFE_GT
+	WFE_LE
+	WFE
+	WFE_ZZ
+	WFI_EQ
+	WFI_NE
+	WFI_CS
+	WFI_CC
+	WFI_MI
+	WFI_PL
+	WFI_VS
+	WFI_VC
+	WFI_HI
+	WFI_LS
+	WFI_GE
+	WFI_LT
+	WFI_GT
+	WFI_LE
+	WFI
+	WFI_ZZ
+	YIELD_EQ
+	YIELD_NE
+	YIELD_CS
+	YIELD_CC
+	YIELD_MI
+	YIELD_PL
+	YIELD_VS
+	YIELD_VC
+	YIELD_HI
+	YIELD_LS
+	YIELD_GE
+	YIELD_LT
+	YIELD_GT
+	YIELD_LE
+	YIELD
+	YIELD_ZZ
+)
+
+var opstr = [...]string{
+	ADC_EQ:            "ADC.EQ",
+	ADC_NE:            "ADC.NE",
+	ADC_CS:            "ADC.CS",
+	ADC_CC:            "ADC.CC",
+	ADC_MI:            "ADC.MI",
+	ADC_PL:            "ADC.PL",
+	ADC_VS:            "ADC.VS",
+	ADC_VC:            "ADC.VC",
+	ADC_HI:            "ADC.HI",
+	ADC_LS:            "ADC.LS",
+	ADC_GE:            "ADC.GE",
+	ADC_LT:            "ADC.LT",
+	ADC_GT:            "ADC.GT",
+	ADC_LE:            "ADC.LE",
+	ADC:               "ADC",
+	ADC_ZZ:            "ADC.ZZ",
+	ADC_S_EQ:          "ADC.S.EQ",
+	ADC_S_NE:          "ADC.S.NE",
+	ADC_S_CS:          "ADC.S.CS",
+	ADC_S_CC:          "ADC.S.CC",
+	ADC_S_MI:          "ADC.S.MI",
+	ADC_S_PL:          "ADC.S.PL",
+	ADC_S_VS:          "ADC.S.VS",
+	ADC_S_VC:          "ADC.S.VC",
+	ADC_S_HI:          "ADC.S.HI",
+	ADC_S_LS:          "ADC.S.LS",
+	ADC_S_GE:          "ADC.S.GE",
+	ADC_S_LT:          "ADC.S.LT",
+	ADC_S_GT:          "ADC.S.GT",
+	ADC_S_LE:          "ADC.S.LE",
+	ADC_S:             "ADC.S",
+	ADC_S_ZZ:          "ADC.S.ZZ",
+	ADD_EQ:            "ADD.EQ",
+	ADD_NE:            "ADD.NE",
+	ADD_CS:            "ADD.CS",
+	ADD_CC:            "ADD.CC",
+	ADD_MI:            "ADD.MI",
+	ADD_PL:            "ADD.PL",
+	ADD_VS:            "ADD.VS",
+	ADD_VC:            "ADD.VC",
+	ADD_HI:            "ADD.HI",
+	ADD_LS:            "ADD.LS",
+	ADD_GE:            "ADD.GE",
+	ADD_LT:            "ADD.LT",
+	ADD_GT:            "ADD.GT",
+	ADD_LE:            "ADD.LE",
+	ADD:               "ADD",
+	ADD_ZZ:            "ADD.ZZ",
+	ADD_S_EQ:          "ADD.S.EQ",
+	ADD_S_NE:          "ADD.S.NE",
+	ADD_S_CS:          "ADD.S.CS",
+	ADD_S_CC:          "ADD.S.CC",
+	ADD_S_MI:          "ADD.S.MI",
+	ADD_S_PL:          "ADD.S.PL",
+	ADD_S_VS:          "ADD.S.VS",
+	ADD_S_VC:          "ADD.S.VC",
+	ADD_S_HI:          "ADD.S.HI",
+	ADD_S_LS:          "ADD.S.LS",
+	ADD_S_GE:          "ADD.S.GE",
+	ADD_S_LT:          "ADD.S.LT",
+	ADD_S_GT:          "ADD.S.GT",
+	ADD_S_LE:          "ADD.S.LE",
+	ADD_S:             "ADD.S",
+	ADD_S_ZZ:          "ADD.S.ZZ",
+	AND_EQ:            "AND.EQ",
+	AND_NE:            "AND.NE",
+	AND_CS:            "AND.CS",
+	AND_CC:            "AND.CC",
+	AND_MI:            "AND.MI",
+	AND_PL:            "AND.PL",
+	AND_VS:            "AND.VS",
+	AND_VC:            "AND.VC",
+	AND_HI:            "AND.HI",
+	AND_LS:            "AND.LS",
+	AND_GE:            "AND.GE",
+	AND_LT:            "AND.LT",
+	AND_GT:            "AND.GT",
+	AND_LE:            "AND.LE",
+	AND:               "AND",
+	AND_ZZ:            "AND.ZZ",
+	AND_S_EQ:          "AND.S.EQ",
+	AND_S_NE:          "AND.S.NE",
+	AND_S_CS:          "AND.S.CS",
+	AND_S_CC:          "AND.S.CC",
+	AND_S_MI:          "AND.S.MI",
+	AND_S_PL:          "AND.S.PL",
+	AND_S_VS:          "AND.S.VS",
+	AND_S_VC:          "AND.S.VC",
+	AND_S_HI:          "AND.S.HI",
+	AND_S_LS:          "AND.S.LS",
+	AND_S_GE:          "AND.S.GE",
+	AND_S_LT:          "AND.S.LT",
+	AND_S_GT:          "AND.S.GT",
+	AND_S_LE:          "AND.S.LE",
+	AND_S:             "AND.S",
+	AND_S_ZZ:          "AND.S.ZZ",
+	ASR_EQ:            "ASR.EQ",
+	ASR_NE:            "ASR.NE",
+	ASR_CS:            "ASR.CS",
+	ASR_CC:            "ASR.CC",
+	ASR_MI:            "ASR.MI",
+	ASR_PL:            "ASR.PL",
+	ASR_VS:            "ASR.VS",
+	ASR_VC:            "ASR.VC",
+	ASR_HI:            "ASR.HI",
+	ASR_LS:            "ASR.LS",
+	ASR_GE:            "ASR.GE",
+	ASR_LT:            "ASR.LT",
+	ASR_GT:            "ASR.GT",
+	ASR_LE:            "ASR.LE",
+	ASR:               "ASR",
+	ASR_ZZ:            "ASR.ZZ",
+	ASR_S_EQ:          "ASR.S.EQ",
+	ASR_S_NE:          "ASR.S.NE",
+	ASR_S_CS:          "ASR.S.CS",
+	ASR_S_CC:          "ASR.S.CC",
+	ASR_S_MI:          "ASR.S.MI",
+	ASR_S_PL:          "ASR.S.PL",
+	ASR_S_VS:          "ASR.S.VS",
+	ASR_S_VC:          "ASR.S.VC",
+	ASR_S_HI:          "ASR.S.HI",
+	ASR_S_LS:          "ASR.S.LS",
+	ASR_S_GE:          "ASR.S.GE",
+	ASR_S_LT:          "ASR.S.LT",
+	ASR_S_GT:          "ASR.S.GT",
+	ASR_S_LE:          "ASR.S.LE",
+	ASR_S:             "ASR.S",
+	ASR_S_ZZ:          "ASR.S.ZZ",
+	B_EQ:              "B.EQ",
+	B_NE:              "B.NE",
+	B_CS:              "B.CS",
+	B_CC:              "B.CC",
+	B_MI:              "B.MI",
+	B_PL:              "B.PL",
+	B_VS:              "B.VS",
+	B_VC:              "B.VC",
+	B_HI:              "B.HI",
+	B_LS:              "B.LS",
+	B_GE:              "B.GE",
+	B_LT:              "B.LT",
+	B_GT:              "B.GT",
+	B_LE:              "B.LE",
+	B:                 "B",
+	B_ZZ:              "B.ZZ",
+	BFC_EQ:            "BFC.EQ",
+	BFC_NE:            "BFC.NE",
+	BFC_CS:            "BFC.CS",
+	BFC_CC:            "BFC.CC",
+	BFC_MI:            "BFC.MI",
+	BFC_PL:            "BFC.PL",
+	BFC_VS:            "BFC.VS",
+	BFC_VC:            "BFC.VC",
+	BFC_HI:            "BFC.HI",
+	BFC_LS:            "BFC.LS",
+	BFC_GE:            "BFC.GE",
+	BFC_LT:            "BFC.LT",
+	BFC_GT:            "BFC.GT",
+	BFC_LE:            "BFC.LE",
+	BFC:               "BFC",
+	BFC_ZZ:            "BFC.ZZ",
+	BFI_EQ:            "BFI.EQ",
+	BFI_NE:            "BFI.NE",
+	BFI_CS:            "BFI.CS",
+	BFI_CC:            "BFI.CC",
+	BFI_MI:            "BFI.MI",
+	BFI_PL:            "BFI.PL",
+	BFI_VS:            "BFI.VS",
+	BFI_VC:            "BFI.VC",
+	BFI_HI:            "BFI.HI",
+	BFI_LS:            "BFI.LS",
+	BFI_GE:            "BFI.GE",
+	BFI_LT:            "BFI.LT",
+	BFI_GT:            "BFI.GT",
+	BFI_LE:            "BFI.LE",
+	BFI:               "BFI",
+	BFI_ZZ:            "BFI.ZZ",
+	BIC_EQ:            "BIC.EQ",
+	BIC_NE:            "BIC.NE",
+	BIC_CS:            "BIC.CS",
+	BIC_CC:            "BIC.CC",
+	BIC_MI:            "BIC.MI",
+	BIC_PL:            "BIC.PL",
+	BIC_VS:            "BIC.VS",
+	BIC_VC:            "BIC.VC",
+	BIC_HI:            "BIC.HI",
+	BIC_LS:            "BIC.LS",
+	BIC_GE:            "BIC.GE",
+	BIC_LT:            "BIC.LT",
+	BIC_GT:            "BIC.GT",
+	BIC_LE:            "BIC.LE",
+	BIC:               "BIC",
+	BIC_ZZ:            "BIC.ZZ",
+	BIC_S_EQ:          "BIC.S.EQ",
+	BIC_S_NE:          "BIC.S.NE",
+	BIC_S_CS:          "BIC.S.CS",
+	BIC_S_CC:          "BIC.S.CC",
+	BIC_S_MI:          "BIC.S.MI",
+	BIC_S_PL:          "BIC.S.PL",
+	BIC_S_VS:          "BIC.S.VS",
+	BIC_S_VC:          "BIC.S.VC",
+	BIC_S_HI:          "BIC.S.HI",
+	BIC_S_LS:          "BIC.S.LS",
+	BIC_S_GE:          "BIC.S.GE",
+	BIC_S_LT:          "BIC.S.LT",
+	BIC_S_GT:          "BIC.S.GT",
+	BIC_S_LE:          "BIC.S.LE",
+	BIC_S:             "BIC.S",
+	BIC_S_ZZ:          "BIC.S.ZZ",
+	BKPT_EQ:           "BKPT.EQ",
+	BKPT_NE:           "BKPT.NE",
+	BKPT_CS:           "BKPT.CS",
+	BKPT_CC:           "BKPT.CC",
+	BKPT_MI:           "BKPT.MI",
+	BKPT_PL:           "BKPT.PL",
+	BKPT_VS:           "BKPT.VS",
+	BKPT_VC:           "BKPT.VC",
+	BKPT_HI:           "BKPT.HI",
+	BKPT_LS:           "BKPT.LS",
+	BKPT_GE:           "BKPT.GE",
+	BKPT_LT:           "BKPT.LT",
+	BKPT_GT:           "BKPT.GT",
+	BKPT_LE:           "BKPT.LE",
+	BKPT:              "BKPT",
+	BKPT_ZZ:           "BKPT.ZZ",
+	BL_EQ:             "BL.EQ",
+	BL_NE:             "BL.NE",
+	BL_CS:             "BL.CS",
+	BL_CC:             "BL.CC",
+	BL_MI:             "BL.MI",
+	BL_PL:             "BL.PL",
+	BL_VS:             "BL.VS",
+	BL_VC:             "BL.VC",
+	BL_HI:             "BL.HI",
+	BL_LS:             "BL.LS",
+	BL_GE:             "BL.GE",
+	BL_LT:             "BL.LT",
+	BL_GT:             "BL.GT",
+	BL_LE:             "BL.LE",
+	BL:                "BL",
+	BL_ZZ:             "BL.ZZ",
+	BLX_EQ:            "BLX.EQ",
+	BLX_NE:            "BLX.NE",
+	BLX_CS:            "BLX.CS",
+	BLX_CC:            "BLX.CC",
+	BLX_MI:            "BLX.MI",
+	BLX_PL:            "BLX.PL",
+	BLX_VS:            "BLX.VS",
+	BLX_VC:            "BLX.VC",
+	BLX_HI:            "BLX.HI",
+	BLX_LS:            "BLX.LS",
+	BLX_GE:            "BLX.GE",
+	BLX_LT:            "BLX.LT",
+	BLX_GT:            "BLX.GT",
+	BLX_LE:            "BLX.LE",
+	BLX:               "BLX",
+	BLX_ZZ:            "BLX.ZZ",
+	BX_EQ:             "BX.EQ",
+	BX_NE:             "BX.NE",
+	BX_CS:             "BX.CS",
+	BX_CC:             "BX.CC",
+	BX_MI:             "BX.MI",
+	BX_PL:             "BX.PL",
+	BX_VS:             "BX.VS",
+	BX_VC:             "BX.VC",
+	BX_HI:             "BX.HI",
+	BX_LS:             "BX.LS",
+	BX_GE:             "BX.GE",
+	BX_LT:             "BX.LT",
+	BX_GT:             "BX.GT",
+	BX_LE:             "BX.LE",
+	BX:                "BX",
+	BX_ZZ:             "BX.ZZ",
+	BXJ_EQ:            "BXJ.EQ",
+	BXJ_NE:            "BXJ.NE",
+	BXJ_CS:            "BXJ.CS",
+	BXJ_CC:            "BXJ.CC",
+	BXJ_MI:            "BXJ.MI",
+	BXJ_PL:            "BXJ.PL",
+	BXJ_VS:            "BXJ.VS",
+	BXJ_VC:            "BXJ.VC",
+	BXJ_HI:            "BXJ.HI",
+	BXJ_LS:            "BXJ.LS",
+	BXJ_GE:            "BXJ.GE",
+	BXJ_LT:            "BXJ.LT",
+	BXJ_GT:            "BXJ.GT",
+	BXJ_LE:            "BXJ.LE",
+	BXJ:               "BXJ",
+	BXJ_ZZ:            "BXJ.ZZ",
+	CLREX:             "CLREX",
+	CLZ_EQ:            "CLZ.EQ",
+	CLZ_NE:            "CLZ.NE",
+	CLZ_CS:            "CLZ.CS",
+	CLZ_CC:            "CLZ.CC",
+	CLZ_MI:            "CLZ.MI",
+	CLZ_PL:            "CLZ.PL",
+	CLZ_VS:            "CLZ.VS",
+	CLZ_VC:            "CLZ.VC",
+	CLZ_HI:            "CLZ.HI",
+	CLZ_LS:            "CLZ.LS",
+	CLZ_GE:            "CLZ.GE",
+	CLZ_LT:            "CLZ.LT",
+	CLZ_GT:            "CLZ.GT",
+	CLZ_LE:            "CLZ.LE",
+	CLZ:               "CLZ",
+	CLZ_ZZ:            "CLZ.ZZ",
+	CMN_EQ:            "CMN.EQ",
+	CMN_NE:            "CMN.NE",
+	CMN_CS:            "CMN.CS",
+	CMN_CC:            "CMN.CC",
+	CMN_MI:            "CMN.MI",
+	CMN_PL:            "CMN.PL",
+	CMN_VS:            "CMN.VS",
+	CMN_VC:            "CMN.VC",
+	CMN_HI:            "CMN.HI",
+	CMN_LS:            "CMN.LS",
+	CMN_GE:            "CMN.GE",
+	CMN_LT:            "CMN.LT",
+	CMN_GT:            "CMN.GT",
+	CMN_LE:            "CMN.LE",
+	CMN:               "CMN",
+	CMN_ZZ:            "CMN.ZZ",
+	CMP_EQ:            "CMP.EQ",
+	CMP_NE:            "CMP.NE",
+	CMP_CS:            "CMP.CS",
+	CMP_CC:            "CMP.CC",
+	CMP_MI:            "CMP.MI",
+	CMP_PL:            "CMP.PL",
+	CMP_VS:            "CMP.VS",
+	CMP_VC:            "CMP.VC",
+	CMP_HI:            "CMP.HI",
+	CMP_LS:            "CMP.LS",
+	CMP_GE:            "CMP.GE",
+	CMP_LT:            "CMP.LT",
+	CMP_GT:            "CMP.GT",
+	CMP_LE:            "CMP.LE",
+	CMP:               "CMP",
+	CMP_ZZ:            "CMP.ZZ",
+	DBG_EQ:            "DBG.EQ",
+	DBG_NE:            "DBG.NE",
+	DBG_CS:            "DBG.CS",
+	DBG_CC:            "DBG.CC",
+	DBG_MI:            "DBG.MI",
+	DBG_PL:            "DBG.PL",
+	DBG_VS:            "DBG.VS",
+	DBG_VC:            "DBG.VC",
+	DBG_HI:            "DBG.HI",
+	DBG_LS:            "DBG.LS",
+	DBG_GE:            "DBG.GE",
+	DBG_LT:            "DBG.LT",
+	DBG_GT:            "DBG.GT",
+	DBG_LE:            "DBG.LE",
+	DBG:               "DBG",
+	DBG_ZZ:            "DBG.ZZ",
+	DMB:               "DMB",
+	DSB:               "DSB",
+	EOR_EQ:            "EOR.EQ",
+	EOR_NE:            "EOR.NE",
+	EOR_CS:            "EOR.CS",
+	EOR_CC:            "EOR.CC",
+	EOR_MI:            "EOR.MI",
+	EOR_PL:            "EOR.PL",
+	EOR_VS:            "EOR.VS",
+	EOR_VC:            "EOR.VC",
+	EOR_HI:            "EOR.HI",
+	EOR_LS:            "EOR.LS",
+	EOR_GE:            "EOR.GE",
+	EOR_LT:            "EOR.LT",
+	EOR_GT:            "EOR.GT",
+	EOR_LE:            "EOR.LE",
+	EOR:               "EOR",
+	EOR_ZZ:            "EOR.ZZ",
+	EOR_S_EQ:          "EOR.S.EQ",
+	EOR_S_NE:          "EOR.S.NE",
+	EOR_S_CS:          "EOR.S.CS",
+	EOR_S_CC:          "EOR.S.CC",
+	EOR_S_MI:          "EOR.S.MI",
+	EOR_S_PL:          "EOR.S.PL",
+	EOR_S_VS:          "EOR.S.VS",
+	EOR_S_VC:          "EOR.S.VC",
+	EOR_S_HI:          "EOR.S.HI",
+	EOR_S_LS:          "EOR.S.LS",
+	EOR_S_GE:          "EOR.S.GE",
+	EOR_S_LT:          "EOR.S.LT",
+	EOR_S_GT:          "EOR.S.GT",
+	EOR_S_LE:          "EOR.S.LE",
+	EOR_S:             "EOR.S",
+	EOR_S_ZZ:          "EOR.S.ZZ",
+	ISB:               "ISB",
+	LDM_EQ:            "LDM.EQ",
+	LDM_NE:            "LDM.NE",
+	LDM_CS:            "LDM.CS",
+	LDM_CC:            "LDM.CC",
+	LDM_MI:            "LDM.MI",
+	LDM_PL:            "LDM.PL",
+	LDM_VS:            "LDM.VS",
+	LDM_VC:            "LDM.VC",
+	LDM_HI:            "LDM.HI",
+	LDM_LS:            "LDM.LS",
+	LDM_GE:            "LDM.GE",
+	LDM_LT:            "LDM.LT",
+	LDM_GT:            "LDM.GT",
+	LDM_LE:            "LDM.LE",
+	LDM:               "LDM",
+	LDM_ZZ:            "LDM.ZZ",
+	LDMDA_EQ:          "LDMDA.EQ",
+	LDMDA_NE:          "LDMDA.NE",
+	LDMDA_CS:          "LDMDA.CS",
+	LDMDA_CC:          "LDMDA.CC",
+	LDMDA_MI:          "LDMDA.MI",
+	LDMDA_PL:          "LDMDA.PL",
+	LDMDA_VS:          "LDMDA.VS",
+	LDMDA_VC:          "LDMDA.VC",
+	LDMDA_HI:          "LDMDA.HI",
+	LDMDA_LS:          "LDMDA.LS",
+	LDMDA_GE:          "LDMDA.GE",
+	LDMDA_LT:          "LDMDA.LT",
+	LDMDA_GT:          "LDMDA.GT",
+	LDMDA_LE:          "LDMDA.LE",
+	LDMDA:             "LDMDA",
+	LDMDA_ZZ:          "LDMDA.ZZ",
+	LDMDB_EQ:          "LDMDB.EQ",
+	LDMDB_NE:          "LDMDB.NE",
+	LDMDB_CS:          "LDMDB.CS",
+	LDMDB_CC:          "LDMDB.CC",
+	LDMDB_MI:          "LDMDB.MI",
+	LDMDB_PL:          "LDMDB.PL",
+	LDMDB_VS:          "LDMDB.VS",
+	LDMDB_VC:          "LDMDB.VC",
+	LDMDB_HI:          "LDMDB.HI",
+	LDMDB_LS:          "LDMDB.LS",
+	LDMDB_GE:          "LDMDB.GE",
+	LDMDB_LT:          "LDMDB.LT",
+	LDMDB_GT:          "LDMDB.GT",
+	LDMDB_LE:          "LDMDB.LE",
+	LDMDB:             "LDMDB",
+	LDMDB_ZZ:          "LDMDB.ZZ",
+	LDMIB_EQ:          "LDMIB.EQ",
+	LDMIB_NE:          "LDMIB.NE",
+	LDMIB_CS:          "LDMIB.CS",
+	LDMIB_CC:          "LDMIB.CC",
+	LDMIB_MI:          "LDMIB.MI",
+	LDMIB_PL:          "LDMIB.PL",
+	LDMIB_VS:          "LDMIB.VS",
+	LDMIB_VC:          "LDMIB.VC",
+	LDMIB_HI:          "LDMIB.HI",
+	LDMIB_LS:          "LDMIB.LS",
+	LDMIB_GE:          "LDMIB.GE",
+	LDMIB_LT:          "LDMIB.LT",
+	LDMIB_GT:          "LDMIB.GT",
+	LDMIB_LE:          "LDMIB.LE",
+	LDMIB:             "LDMIB",
+	LDMIB_ZZ:          "LDMIB.ZZ",
+	LDR_EQ:            "LDR.EQ",
+	LDR_NE:            "LDR.NE",
+	LDR_CS:            "LDR.CS",
+	LDR_CC:            "LDR.CC",
+	LDR_MI:            "LDR.MI",
+	LDR_PL:            "LDR.PL",
+	LDR_VS:            "LDR.VS",
+	LDR_VC:            "LDR.VC",
+	LDR_HI:            "LDR.HI",
+	LDR_LS:            "LDR.LS",
+	LDR_GE:            "LDR.GE",
+	LDR_LT:            "LDR.LT",
+	LDR_GT:            "LDR.GT",
+	LDR_LE:            "LDR.LE",
+	LDR:               "LDR",
+	LDR_ZZ:            "LDR.ZZ",
+	LDRB_EQ:           "LDRB.EQ",
+	LDRB_NE:           "LDRB.NE",
+	LDRB_CS:           "LDRB.CS",
+	LDRB_CC:           "LDRB.CC",
+	LDRB_MI:           "LDRB.MI",
+	LDRB_PL:           "LDRB.PL",
+	LDRB_VS:           "LDRB.VS",
+	LDRB_VC:           "LDRB.VC",
+	LDRB_HI:           "LDRB.HI",
+	LDRB_LS:           "LDRB.LS",
+	LDRB_GE:           "LDRB.GE",
+	LDRB_LT:           "LDRB.LT",
+	LDRB_GT:           "LDRB.GT",
+	LDRB_LE:           "LDRB.LE",
+	LDRB:              "LDRB",
+	LDRB_ZZ:           "LDRB.ZZ",
+	LDRBT_EQ:          "LDRBT.EQ",
+	LDRBT_NE:          "LDRBT.NE",
+	LDRBT_CS:          "LDRBT.CS",
+	LDRBT_CC:          "LDRBT.CC",
+	LDRBT_MI:          "LDRBT.MI",
+	LDRBT_PL:          "LDRBT.PL",
+	LDRBT_VS:          "LDRBT.VS",
+	LDRBT_VC:          "LDRBT.VC",
+	LDRBT_HI:          "LDRBT.HI",
+	LDRBT_LS:          "LDRBT.LS",
+	LDRBT_GE:          "LDRBT.GE",
+	LDRBT_LT:          "LDRBT.LT",
+	LDRBT_GT:          "LDRBT.GT",
+	LDRBT_LE:          "LDRBT.LE",
+	LDRBT:             "LDRBT",
+	LDRBT_ZZ:          "LDRBT.ZZ",
+	LDRD_EQ:           "LDRD.EQ",
+	LDRD_NE:           "LDRD.NE",
+	LDRD_CS:           "LDRD.CS",
+	LDRD_CC:           "LDRD.CC",
+	LDRD_MI:           "LDRD.MI",
+	LDRD_PL:           "LDRD.PL",
+	LDRD_VS:           "LDRD.VS",
+	LDRD_VC:           "LDRD.VC",
+	LDRD_HI:           "LDRD.HI",
+	LDRD_LS:           "LDRD.LS",
+	LDRD_GE:           "LDRD.GE",
+	LDRD_LT:           "LDRD.LT",
+	LDRD_GT:           "LDRD.GT",
+	LDRD_LE:           "LDRD.LE",
+	LDRD:              "LDRD",
+	LDRD_ZZ:           "LDRD.ZZ",
+	LDREX_EQ:          "LDREX.EQ",
+	LDREX_NE:          "LDREX.NE",
+	LDREX_CS:          "LDREX.CS",
+	LDREX_CC:          "LDREX.CC",
+	LDREX_MI:          "LDREX.MI",
+	LDREX_PL:          "LDREX.PL",
+	LDREX_VS:          "LDREX.VS",
+	LDREX_VC:          "LDREX.VC",
+	LDREX_HI:          "LDREX.HI",
+	LDREX_LS:          "LDREX.LS",
+	LDREX_GE:          "LDREX.GE",
+	LDREX_LT:          "LDREX.LT",
+	LDREX_GT:          "LDREX.GT",
+	LDREX_LE:          "LDREX.LE",
+	LDREX:             "LDREX",
+	LDREX_ZZ:          "LDREX.ZZ",
+	LDREXB_EQ:         "LDREXB.EQ",
+	LDREXB_NE:         "LDREXB.NE",
+	LDREXB_CS:         "LDREXB.CS",
+	LDREXB_CC:         "LDREXB.CC",
+	LDREXB_MI:         "LDREXB.MI",
+	LDREXB_PL:         "LDREXB.PL",
+	LDREXB_VS:         "LDREXB.VS",
+	LDREXB_VC:         "LDREXB.VC",
+	LDREXB_HI:         "LDREXB.HI",
+	LDREXB_LS:         "LDREXB.LS",
+	LDREXB_GE:         "LDREXB.GE",
+	LDREXB_LT:         "LDREXB.LT",
+	LDREXB_GT:         "LDREXB.GT",
+	LDREXB_LE:         "LDREXB.LE",
+	LDREXB:            "LDREXB",
+	LDREXB_ZZ:         "LDREXB.ZZ",
+	LDREXD_EQ:         "LDREXD.EQ",
+	LDREXD_NE:         "LDREXD.NE",
+	LDREXD_CS:         "LDREXD.CS",
+	LDREXD_CC:         "LDREXD.CC",
+	LDREXD_MI:         "LDREXD.MI",
+	LDREXD_PL:         "LDREXD.PL",
+	LDREXD_VS:         "LDREXD.VS",
+	LDREXD_VC:         "LDREXD.VC",
+	LDREXD_HI:         "LDREXD.HI",
+	LDREXD_LS:         "LDREXD.LS",
+	LDREXD_GE:         "LDREXD.GE",
+	LDREXD_LT:         "LDREXD.LT",
+	LDREXD_GT:         "LDREXD.GT",
+	LDREXD_LE:         "LDREXD.LE",
+	LDREXD:            "LDREXD",
+	LDREXD_ZZ:         "LDREXD.ZZ",
+	LDREXH_EQ:         "LDREXH.EQ",
+	LDREXH_NE:         "LDREXH.NE",
+	LDREXH_CS:         "LDREXH.CS",
+	LDREXH_CC:         "LDREXH.CC",
+	LDREXH_MI:         "LDREXH.MI",
+	LDREXH_PL:         "LDREXH.PL",
+	LDREXH_VS:         "LDREXH.VS",
+	LDREXH_VC:         "LDREXH.VC",
+	LDREXH_HI:         "LDREXH.HI",
+	LDREXH_LS:         "LDREXH.LS",
+	LDREXH_GE:         "LDREXH.GE",
+	LDREXH_LT:         "LDREXH.LT",
+	LDREXH_GT:         "LDREXH.GT",
+	LDREXH_LE:         "LDREXH.LE",
+	LDREXH:            "LDREXH",
+	LDREXH_ZZ:         "LDREXH.ZZ",
+	LDRH_EQ:           "LDRH.EQ",
+	LDRH_NE:           "LDRH.NE",
+	LDRH_CS:           "LDRH.CS",
+	LDRH_CC:           "LDRH.CC",
+	LDRH_MI:           "LDRH.MI",
+	LDRH_PL:           "LDRH.PL",
+	LDRH_VS:           "LDRH.VS",
+	LDRH_VC:           "LDRH.VC",
+	LDRH_HI:           "LDRH.HI",
+	LDRH_LS:           "LDRH.LS",
+	LDRH_GE:           "LDRH.GE",
+	LDRH_LT:           "LDRH.LT",
+	LDRH_GT:           "LDRH.GT",
+	LDRH_LE:           "LDRH.LE",
+	LDRH:              "LDRH",
+	LDRH_ZZ:           "LDRH.ZZ",
+	LDRHT_EQ:          "LDRHT.EQ",
+	LDRHT_NE:          "LDRHT.NE",
+	LDRHT_CS:          "LDRHT.CS",
+	LDRHT_CC:          "LDRHT.CC",
+	LDRHT_MI:          "LDRHT.MI",
+	LDRHT_PL:          "LDRHT.PL",
+	LDRHT_VS:          "LDRHT.VS",
+	LDRHT_VC:          "LDRHT.VC",
+	LDRHT_HI:          "LDRHT.HI",
+	LDRHT_LS:          "LDRHT.LS",
+	LDRHT_GE:          "LDRHT.GE",
+	LDRHT_LT:          "LDRHT.LT",
+	LDRHT_GT:          "LDRHT.GT",
+	LDRHT_LE:          "LDRHT.LE",
+	LDRHT:             "LDRHT",
+	LDRHT_ZZ:          "LDRHT.ZZ",
+	LDRSB_EQ:          "LDRSB.EQ",
+	LDRSB_NE:          "LDRSB.NE",
+	LDRSB_CS:          "LDRSB.CS",
+	LDRSB_CC:          "LDRSB.CC",
+	LDRSB_MI:          "LDRSB.MI",
+	LDRSB_PL:          "LDRSB.PL",
+	LDRSB_VS:          "LDRSB.VS",
+	LDRSB_VC:          "LDRSB.VC",
+	LDRSB_HI:          "LDRSB.HI",
+	LDRSB_LS:          "LDRSB.LS",
+	LDRSB_GE:          "LDRSB.GE",
+	LDRSB_LT:          "LDRSB.LT",
+	LDRSB_GT:          "LDRSB.GT",
+	LDRSB_LE:          "LDRSB.LE",
+	LDRSB:             "LDRSB",
+	LDRSB_ZZ:          "LDRSB.ZZ",
+	LDRSBT_EQ:         "LDRSBT.EQ",
+	LDRSBT_NE:         "LDRSBT.NE",
+	LDRSBT_CS:         "LDRSBT.CS",
+	LDRSBT_CC:         "LDRSBT.CC",
+	LDRSBT_MI:         "LDRSBT.MI",
+	LDRSBT_PL:         "LDRSBT.PL",
+	LDRSBT_VS:         "LDRSBT.VS",
+	LDRSBT_VC:         "LDRSBT.VC",
+	LDRSBT_HI:         "LDRSBT.HI",
+	LDRSBT_LS:         "LDRSBT.LS",
+	LDRSBT_GE:         "LDRSBT.GE",
+	LDRSBT_LT:         "LDRSBT.LT",
+	LDRSBT_GT:         "LDRSBT.GT",
+	LDRSBT_LE:         "LDRSBT.LE",
+	LDRSBT:            "LDRSBT",
+	LDRSBT_ZZ:         "LDRSBT.ZZ",
+	LDRSH_EQ:          "LDRSH.EQ",
+	LDRSH_NE:          "LDRSH.NE",
+	LDRSH_CS:          "LDRSH.CS",
+	LDRSH_CC:          "LDRSH.CC",
+	LDRSH_MI:          "LDRSH.MI",
+	LDRSH_PL:          "LDRSH.PL",
+	LDRSH_VS:          "LDRSH.VS",
+	LDRSH_VC:          "LDRSH.VC",
+	LDRSH_HI:          "LDRSH.HI",
+	LDRSH_LS:          "LDRSH.LS",
+	LDRSH_GE:          "LDRSH.GE",
+	LDRSH_LT:          "LDRSH.LT",
+	LDRSH_GT:          "LDRSH.GT",
+	LDRSH_LE:          "LDRSH.LE",
+	LDRSH:             "LDRSH",
+	LDRSH_ZZ:          "LDRSH.ZZ",
+	LDRSHT_EQ:         "LDRSHT.EQ",
+	LDRSHT_NE:         "LDRSHT.NE",
+	LDRSHT_CS:         "LDRSHT.CS",
+	LDRSHT_CC:         "LDRSHT.CC",
+	LDRSHT_MI:         "LDRSHT.MI",
+	LDRSHT_PL:         "LDRSHT.PL",
+	LDRSHT_VS:         "LDRSHT.VS",
+	LDRSHT_VC:         "LDRSHT.VC",
+	LDRSHT_HI:         "LDRSHT.HI",
+	LDRSHT_LS:         "LDRSHT.LS",
+	LDRSHT_GE:         "LDRSHT.GE",
+	LDRSHT_LT:         "LDRSHT.LT",
+	LDRSHT_GT:         "LDRSHT.GT",
+	LDRSHT_LE:         "LDRSHT.LE",
+	LDRSHT:            "LDRSHT",
+	LDRSHT_ZZ:         "LDRSHT.ZZ",
+	LDRT_EQ:           "LDRT.EQ",
+	LDRT_NE:           "LDRT.NE",
+	LDRT_CS:           "LDRT.CS",
+	LDRT_CC:           "LDRT.CC",
+	LDRT_MI:           "LDRT.MI",
+	LDRT_PL:           "LDRT.PL",
+	LDRT_VS:           "LDRT.VS",
+	LDRT_VC:           "LDRT.VC",
+	LDRT_HI:           "LDRT.HI",
+	LDRT_LS:           "LDRT.LS",
+	LDRT_GE:           "LDRT.GE",
+	LDRT_LT:           "LDRT.LT",
+	LDRT_GT:           "LDRT.GT",
+	LDRT_LE:           "LDRT.LE",
+	LDRT:              "LDRT",
+	LDRT_ZZ:           "LDRT.ZZ",
+	LSL_EQ:            "LSL.EQ",
+	LSL_NE:            "LSL.NE",
+	LSL_CS:            "LSL.CS",
+	LSL_CC:            "LSL.CC",
+	LSL_MI:            "LSL.MI",
+	LSL_PL:            "LSL.PL",
+	LSL_VS:            "LSL.VS",
+	LSL_VC:            "LSL.VC",
+	LSL_HI:            "LSL.HI",
+	LSL_LS:            "LSL.LS",
+	LSL_GE:            "LSL.GE",
+	LSL_LT:            "LSL.LT",
+	LSL_GT:            "LSL.GT",
+	LSL_LE:            "LSL.LE",
+	LSL:               "LSL",
+	LSL_ZZ:            "LSL.ZZ",
+	LSL_S_EQ:          "LSL.S.EQ",
+	LSL_S_NE:          "LSL.S.NE",
+	LSL_S_CS:          "LSL.S.CS",
+	LSL_S_CC:          "LSL.S.CC",
+	LSL_S_MI:          "LSL.S.MI",
+	LSL_S_PL:          "LSL.S.PL",
+	LSL_S_VS:          "LSL.S.VS",
+	LSL_S_VC:          "LSL.S.VC",
+	LSL_S_HI:          "LSL.S.HI",
+	LSL_S_LS:          "LSL.S.LS",
+	LSL_S_GE:          "LSL.S.GE",
+	LSL_S_LT:          "LSL.S.LT",
+	LSL_S_GT:          "LSL.S.GT",
+	LSL_S_LE:          "LSL.S.LE",
+	LSL_S:             "LSL.S",
+	LSL_S_ZZ:          "LSL.S.ZZ",
+	LSR_EQ:            "LSR.EQ",
+	LSR_NE:            "LSR.NE",
+	LSR_CS:            "LSR.CS",
+	LSR_CC:            "LSR.CC",
+	LSR_MI:            "LSR.MI",
+	LSR_PL:            "LSR.PL",
+	LSR_VS:            "LSR.VS",
+	LSR_VC:            "LSR.VC",
+	LSR_HI:            "LSR.HI",
+	LSR_LS:            "LSR.LS",
+	LSR_GE:            "LSR.GE",
+	LSR_LT:            "LSR.LT",
+	LSR_GT:            "LSR.GT",
+	LSR_LE:            "LSR.LE",
+	LSR:               "LSR",
+	LSR_ZZ:            "LSR.ZZ",
+	LSR_S_EQ:          "LSR.S.EQ",
+	LSR_S_NE:          "LSR.S.NE",
+	LSR_S_CS:          "LSR.S.CS",
+	LSR_S_CC:          "LSR.S.CC",
+	LSR_S_MI:          "LSR.S.MI",
+	LSR_S_PL:          "LSR.S.PL",
+	LSR_S_VS:          "LSR.S.VS",
+	LSR_S_VC:          "LSR.S.VC",
+	LSR_S_HI:          "LSR.S.HI",
+	LSR_S_LS:          "LSR.S.LS",
+	LSR_S_GE:          "LSR.S.GE",
+	LSR_S_LT:          "LSR.S.LT",
+	LSR_S_GT:          "LSR.S.GT",
+	LSR_S_LE:          "LSR.S.LE",
+	LSR_S:             "LSR.S",
+	LSR_S_ZZ:          "LSR.S.ZZ",
+	MLA_EQ:            "MLA.EQ",
+	MLA_NE:            "MLA.NE",
+	MLA_CS:            "MLA.CS",
+	MLA_CC:            "MLA.CC",
+	MLA_MI:            "MLA.MI",
+	MLA_PL:            "MLA.PL",
+	MLA_VS:            "MLA.VS",
+	MLA_VC:            "MLA.VC",
+	MLA_HI:            "MLA.HI",
+	MLA_LS:            "MLA.LS",
+	MLA_GE:            "MLA.GE",
+	MLA_LT:            "MLA.LT",
+	MLA_GT:            "MLA.GT",
+	MLA_LE:            "MLA.LE",
+	MLA:               "MLA",
+	MLA_ZZ:            "MLA.ZZ",
+	MLA_S_EQ:          "MLA.S.EQ",
+	MLA_S_NE:          "MLA.S.NE",
+	MLA_S_CS:          "MLA.S.CS",
+	MLA_S_CC:          "MLA.S.CC",
+	MLA_S_MI:          "MLA.S.MI",
+	MLA_S_PL:          "MLA.S.PL",
+	MLA_S_VS:          "MLA.S.VS",
+	MLA_S_VC:          "MLA.S.VC",
+	MLA_S_HI:          "MLA.S.HI",
+	MLA_S_LS:          "MLA.S.LS",
+	MLA_S_GE:          "MLA.S.GE",
+	MLA_S_LT:          "MLA.S.LT",
+	MLA_S_GT:          "MLA.S.GT",
+	MLA_S_LE:          "MLA.S.LE",
+	MLA_S:             "MLA.S",
+	MLA_S_ZZ:          "MLA.S.ZZ",
+	MLS_EQ:            "MLS.EQ",
+	MLS_NE:            "MLS.NE",
+	MLS_CS:            "MLS.CS",
+	MLS_CC:            "MLS.CC",
+	MLS_MI:            "MLS.MI",
+	MLS_PL:            "MLS.PL",
+	MLS_VS:            "MLS.VS",
+	MLS_VC:            "MLS.VC",
+	MLS_HI:            "MLS.HI",
+	MLS_LS:            "MLS.LS",
+	MLS_GE:            "MLS.GE",
+	MLS_LT:            "MLS.LT",
+	MLS_GT:            "MLS.GT",
+	MLS_LE:            "MLS.LE",
+	MLS:               "MLS",
+	MLS_ZZ:            "MLS.ZZ",
+	MOV_EQ:            "MOV.EQ",
+	MOV_NE:            "MOV.NE",
+	MOV_CS:            "MOV.CS",
+	MOV_CC:            "MOV.CC",
+	MOV_MI:            "MOV.MI",
+	MOV_PL:            "MOV.PL",
+	MOV_VS:            "MOV.VS",
+	MOV_VC:            "MOV.VC",
+	MOV_HI:            "MOV.HI",
+	MOV_LS:            "MOV.LS",
+	MOV_GE:            "MOV.GE",
+	MOV_LT:            "MOV.LT",
+	MOV_GT:            "MOV.GT",
+	MOV_LE:            "MOV.LE",
+	MOV:               "MOV",
+	MOV_ZZ:            "MOV.ZZ",
+	MOV_S_EQ:          "MOV.S.EQ",
+	MOV_S_NE:          "MOV.S.NE",
+	MOV_S_CS:          "MOV.S.CS",
+	MOV_S_CC:          "MOV.S.CC",
+	MOV_S_MI:          "MOV.S.MI",
+	MOV_S_PL:          "MOV.S.PL",
+	MOV_S_VS:          "MOV.S.VS",
+	MOV_S_VC:          "MOV.S.VC",
+	MOV_S_HI:          "MOV.S.HI",
+	MOV_S_LS:          "MOV.S.LS",
+	MOV_S_GE:          "MOV.S.GE",
+	MOV_S_LT:          "MOV.S.LT",
+	MOV_S_GT:          "MOV.S.GT",
+	MOV_S_LE:          "MOV.S.LE",
+	MOV_S:             "MOV.S",
+	MOV_S_ZZ:          "MOV.S.ZZ",
+	MOVT_EQ:           "MOVT.EQ",
+	MOVT_NE:           "MOVT.NE",
+	MOVT_CS:           "MOVT.CS",
+	MOVT_CC:           "MOVT.CC",
+	MOVT_MI:           "MOVT.MI",
+	MOVT_PL:           "MOVT.PL",
+	MOVT_VS:           "MOVT.VS",
+	MOVT_VC:           "MOVT.VC",
+	MOVT_HI:           "MOVT.HI",
+	MOVT_LS:           "MOVT.LS",
+	MOVT_GE:           "MOVT.GE",
+	MOVT_LT:           "MOVT.LT",
+	MOVT_GT:           "MOVT.GT",
+	MOVT_LE:           "MOVT.LE",
+	MOVT:              "MOVT",
+	MOVT_ZZ:           "MOVT.ZZ",
+	MOVW_EQ:           "MOVW.EQ",
+	MOVW_NE:           "MOVW.NE",
+	MOVW_CS:           "MOVW.CS",
+	MOVW_CC:           "MOVW.CC",
+	MOVW_MI:           "MOVW.MI",
+	MOVW_PL:           "MOVW.PL",
+	MOVW_VS:           "MOVW.VS",
+	MOVW_VC:           "MOVW.VC",
+	MOVW_HI:           "MOVW.HI",
+	MOVW_LS:           "MOVW.LS",
+	MOVW_GE:           "MOVW.GE",
+	MOVW_LT:           "MOVW.LT",
+	MOVW_GT:           "MOVW.GT",
+	MOVW_LE:           "MOVW.LE",
+	MOVW:              "MOVW",
+	MOVW_ZZ:           "MOVW.ZZ",
+	MRS_EQ:            "MRS.EQ",
+	MRS_NE:            "MRS.NE",
+	MRS_CS:            "MRS.CS",
+	MRS_CC:            "MRS.CC",
+	MRS_MI:            "MRS.MI",
+	MRS_PL:            "MRS.PL",
+	MRS_VS:            "MRS.VS",
+	MRS_VC:            "MRS.VC",
+	MRS_HI:            "MRS.HI",
+	MRS_LS:            "MRS.LS",
+	MRS_GE:            "MRS.GE",
+	MRS_LT:            "MRS.LT",
+	MRS_GT:            "MRS.GT",
+	MRS_LE:            "MRS.LE",
+	MRS:               "MRS",
+	MRS_ZZ:            "MRS.ZZ",
+	MUL_EQ:            "MUL.EQ",
+	MUL_NE:            "MUL.NE",
+	MUL_CS:            "MUL.CS",
+	MUL_CC:            "MUL.CC",
+	MUL_MI:            "MUL.MI",
+	MUL_PL:            "MUL.PL",
+	MUL_VS:            "MUL.VS",
+	MUL_VC:            "MUL.VC",
+	MUL_HI:            "MUL.HI",
+	MUL_LS:            "MUL.LS",
+	MUL_GE:            "MUL.GE",
+	MUL_LT:            "MUL.LT",
+	MUL_GT:            "MUL.GT",
+	MUL_LE:            "MUL.LE",
+	MUL:               "MUL",
+	MUL_ZZ:            "MUL.ZZ",
+	MUL_S_EQ:          "MUL.S.EQ",
+	MUL_S_NE:          "MUL.S.NE",
+	MUL_S_CS:          "MUL.S.CS",
+	MUL_S_CC:          "MUL.S.CC",
+	MUL_S_MI:          "MUL.S.MI",
+	MUL_S_PL:          "MUL.S.PL",
+	MUL_S_VS:          "MUL.S.VS",
+	MUL_S_VC:          "MUL.S.VC",
+	MUL_S_HI:          "MUL.S.HI",
+	MUL_S_LS:          "MUL.S.LS",
+	MUL_S_GE:          "MUL.S.GE",
+	MUL_S_LT:          "MUL.S.LT",
+	MUL_S_GT:          "MUL.S.GT",
+	MUL_S_LE:          "MUL.S.LE",
+	MUL_S:             "MUL.S",
+	MUL_S_ZZ:          "MUL.S.ZZ",
+	MVN_EQ:            "MVN.EQ",
+	MVN_NE:            "MVN.NE",
+	MVN_CS:            "MVN.CS",
+	MVN_CC:            "MVN.CC",
+	MVN_MI:            "MVN.MI",
+	MVN_PL:            "MVN.PL",
+	MVN_VS:            "MVN.VS",
+	MVN_VC:            "MVN.VC",
+	MVN_HI:            "MVN.HI",
+	MVN_LS:            "MVN.LS",
+	MVN_GE:            "MVN.GE",
+	MVN_LT:            "MVN.LT",
+	MVN_GT:            "MVN.GT",
+	MVN_LE:            "MVN.LE",
+	MVN:               "MVN",
+	MVN_ZZ:            "MVN.ZZ",
+	MVN_S_EQ:          "MVN.S.EQ",
+	MVN_S_NE:          "MVN.S.NE",
+	MVN_S_CS:          "MVN.S.CS",
+	MVN_S_CC:          "MVN.S.CC",
+	MVN_S_MI:          "MVN.S.MI",
+	MVN_S_PL:          "MVN.S.PL",
+	MVN_S_VS:          "MVN.S.VS",
+	MVN_S_VC:          "MVN.S.VC",
+	MVN_S_HI:          "MVN.S.HI",
+	MVN_S_LS:          "MVN.S.LS",
+	MVN_S_GE:          "MVN.S.GE",
+	MVN_S_LT:          "MVN.S.LT",
+	MVN_S_GT:          "MVN.S.GT",
+	MVN_S_LE:          "MVN.S.LE",
+	MVN_S:             "MVN.S",
+	MVN_S_ZZ:          "MVN.S.ZZ",
+	NOP_EQ:            "NOP.EQ",
+	NOP_NE:            "NOP.NE",
+	NOP_CS:            "NOP.CS",
+	NOP_CC:            "NOP.CC",
+	NOP_MI:            "NOP.MI",
+	NOP_PL:            "NOP.PL",
+	NOP_VS:            "NOP.VS",
+	NOP_VC:            "NOP.VC",
+	NOP_HI:            "NOP.HI",
+	NOP_LS:            "NOP.LS",
+	NOP_GE:            "NOP.GE",
+	NOP_LT:            "NOP.LT",
+	NOP_GT:            "NOP.GT",
+	NOP_LE:            "NOP.LE",
+	NOP:               "NOP",
+	NOP_ZZ:            "NOP.ZZ",
+	ORR_EQ:            "ORR.EQ",
+	ORR_NE:            "ORR.NE",
+	ORR_CS:            "ORR.CS",
+	ORR_CC:            "ORR.CC",
+	ORR_MI:            "ORR.MI",
+	ORR_PL:            "ORR.PL",
+	ORR_VS:            "ORR.VS",
+	ORR_VC:            "ORR.VC",
+	ORR_HI:            "ORR.HI",
+	ORR_LS:            "ORR.LS",
+	ORR_GE:            "ORR.GE",
+	ORR_LT:            "ORR.LT",
+	ORR_GT:            "ORR.GT",
+	ORR_LE:            "ORR.LE",
+	ORR:               "ORR",
+	ORR_ZZ:            "ORR.ZZ",
+	ORR_S_EQ:          "ORR.S.EQ",
+	ORR_S_NE:          "ORR.S.NE",
+	ORR_S_CS:          "ORR.S.CS",
+	ORR_S_CC:          "ORR.S.CC",
+	ORR_S_MI:          "ORR.S.MI",
+	ORR_S_PL:          "ORR.S.PL",
+	ORR_S_VS:          "ORR.S.VS",
+	ORR_S_VC:          "ORR.S.VC",
+	ORR_S_HI:          "ORR.S.HI",
+	ORR_S_LS:          "ORR.S.LS",
+	ORR_S_GE:          "ORR.S.GE",
+	ORR_S_LT:          "ORR.S.LT",
+	ORR_S_GT:          "ORR.S.GT",
+	ORR_S_LE:          "ORR.S.LE",
+	ORR_S:             "ORR.S",
+	ORR_S_ZZ:          "ORR.S.ZZ",
+	PKHBT_EQ:          "PKHBT.EQ",
+	PKHBT_NE:          "PKHBT.NE",
+	PKHBT_CS:          "PKHBT.CS",
+	PKHBT_CC:          "PKHBT.CC",
+	PKHBT_MI:          "PKHBT.MI",
+	PKHBT_PL:          "PKHBT.PL",
+	PKHBT_VS:          "PKHBT.VS",
+	PKHBT_VC:          "PKHBT.VC",
+	PKHBT_HI:          "PKHBT.HI",
+	PKHBT_LS:          "PKHBT.LS",
+	PKHBT_GE:          "PKHBT.GE",
+	PKHBT_LT:          "PKHBT.LT",
+	PKHBT_GT:          "PKHBT.GT",
+	PKHBT_LE:          "PKHBT.LE",
+	PKHBT:             "PKHBT",
+	PKHBT_ZZ:          "PKHBT.ZZ",
+	PKHTB_EQ:          "PKHTB.EQ",
+	PKHTB_NE:          "PKHTB.NE",
+	PKHTB_CS:          "PKHTB.CS",
+	PKHTB_CC:          "PKHTB.CC",
+	PKHTB_MI:          "PKHTB.MI",
+	PKHTB_PL:          "PKHTB.PL",
+	PKHTB_VS:          "PKHTB.VS",
+	PKHTB_VC:          "PKHTB.VC",
+	PKHTB_HI:          "PKHTB.HI",
+	PKHTB_LS:          "PKHTB.LS",
+	PKHTB_GE:          "PKHTB.GE",
+	PKHTB_LT:          "PKHTB.LT",
+	PKHTB_GT:          "PKHTB.GT",
+	PKHTB_LE:          "PKHTB.LE",
+	PKHTB:             "PKHTB",
+	PKHTB_ZZ:          "PKHTB.ZZ",
+	PLD_W:             "PLD.W",
+	PLD:               "PLD",
+	PLI:               "PLI",
+	POP_EQ:            "POP.EQ",
+	POP_NE:            "POP.NE",
+	POP_CS:            "POP.CS",
+	POP_CC:            "POP.CC",
+	POP_MI:            "POP.MI",
+	POP_PL:            "POP.PL",
+	POP_VS:            "POP.VS",
+	POP_VC:            "POP.VC",
+	POP_HI:            "POP.HI",
+	POP_LS:            "POP.LS",
+	POP_GE:            "POP.GE",
+	POP_LT:            "POP.LT",
+	POP_GT:            "POP.GT",
+	POP_LE:            "POP.LE",
+	POP:               "POP",
+	POP_ZZ:            "POP.ZZ",
+	PUSH_EQ:           "PUSH.EQ",
+	PUSH_NE:           "PUSH.NE",
+	PUSH_CS:           "PUSH.CS",
+	PUSH_CC:           "PUSH.CC",
+	PUSH_MI:           "PUSH.MI",
+	PUSH_PL:           "PUSH.PL",
+	PUSH_VS:           "PUSH.VS",
+	PUSH_VC:           "PUSH.VC",
+	PUSH_HI:           "PUSH.HI",
+	PUSH_LS:           "PUSH.LS",
+	PUSH_GE:           "PUSH.GE",
+	PUSH_LT:           "PUSH.LT",
+	PUSH_GT:           "PUSH.GT",
+	PUSH_LE:           "PUSH.LE",
+	PUSH:              "PUSH",
+	PUSH_ZZ:           "PUSH.ZZ",
+	QADD_EQ:           "QADD.EQ",
+	QADD_NE:           "QADD.NE",
+	QADD_CS:           "QADD.CS",
+	QADD_CC:           "QADD.CC",
+	QADD_MI:           "QADD.MI",
+	QADD_PL:           "QADD.PL",
+	QADD_VS:           "QADD.VS",
+	QADD_VC:           "QADD.VC",
+	QADD_HI:           "QADD.HI",
+	QADD_LS:           "QADD.LS",
+	QADD_GE:           "QADD.GE",
+	QADD_LT:           "QADD.LT",
+	QADD_GT:           "QADD.GT",
+	QADD_LE:           "QADD.LE",
+	QADD:              "QADD",
+	QADD_ZZ:           "QADD.ZZ",
+	QADD16_EQ:         "QADD16.EQ",
+	QADD16_NE:         "QADD16.NE",
+	QADD16_CS:         "QADD16.CS",
+	QADD16_CC:         "QADD16.CC",
+	QADD16_MI:         "QADD16.MI",
+	QADD16_PL:         "QADD16.PL",
+	QADD16_VS:         "QADD16.VS",
+	QADD16_VC:         "QADD16.VC",
+	QADD16_HI:         "QADD16.HI",
+	QADD16_LS:         "QADD16.LS",
+	QADD16_GE:         "QADD16.GE",
+	QADD16_LT:         "QADD16.LT",
+	QADD16_GT:         "QADD16.GT",
+	QADD16_LE:         "QADD16.LE",
+	QADD16:            "QADD16",
+	QADD16_ZZ:         "QADD16.ZZ",
+	QADD8_EQ:          "QADD8.EQ",
+	QADD8_NE:          "QADD8.NE",
+	QADD8_CS:          "QADD8.CS",
+	QADD8_CC:          "QADD8.CC",
+	QADD8_MI:          "QADD8.MI",
+	QADD8_PL:          "QADD8.PL",
+	QADD8_VS:          "QADD8.VS",
+	QADD8_VC:          "QADD8.VC",
+	QADD8_HI:          "QADD8.HI",
+	QADD8_LS:          "QADD8.LS",
+	QADD8_GE:          "QADD8.GE",
+	QADD8_LT:          "QADD8.LT",
+	QADD8_GT:          "QADD8.GT",
+	QADD8_LE:          "QADD8.LE",
+	QADD8:             "QADD8",
+	QADD8_ZZ:          "QADD8.ZZ",
+	QASX_EQ:           "QASX.EQ",
+	QASX_NE:           "QASX.NE",
+	QASX_CS:           "QASX.CS",
+	QASX_CC:           "QASX.CC",
+	QASX_MI:           "QASX.MI",
+	QASX_PL:           "QASX.PL",
+	QASX_VS:           "QASX.VS",
+	QASX_VC:           "QASX.VC",
+	QASX_HI:           "QASX.HI",
+	QASX_LS:           "QASX.LS",
+	QASX_GE:           "QASX.GE",
+	QASX_LT:           "QASX.LT",
+	QASX_GT:           "QASX.GT",
+	QASX_LE:           "QASX.LE",
+	QASX:              "QASX",
+	QASX_ZZ:           "QASX.ZZ",
+	QDADD_EQ:          "QDADD.EQ",
+	QDADD_NE:          "QDADD.NE",
+	QDADD_CS:          "QDADD.CS",
+	QDADD_CC:          "QDADD.CC",
+	QDADD_MI:          "QDADD.MI",
+	QDADD_PL:          "QDADD.PL",
+	QDADD_VS:          "QDADD.VS",
+	QDADD_VC:          "QDADD.VC",
+	QDADD_HI:          "QDADD.HI",
+	QDADD_LS:          "QDADD.LS",
+	QDADD_GE:          "QDADD.GE",
+	QDADD_LT:          "QDADD.LT",
+	QDADD_GT:          "QDADD.GT",
+	QDADD_LE:          "QDADD.LE",
+	QDADD:             "QDADD",
+	QDADD_ZZ:          "QDADD.ZZ",
+	QDSUB_EQ:          "QDSUB.EQ",
+	QDSUB_NE:          "QDSUB.NE",
+	QDSUB_CS:          "QDSUB.CS",
+	QDSUB_CC:          "QDSUB.CC",
+	QDSUB_MI:          "QDSUB.MI",
+	QDSUB_PL:          "QDSUB.PL",
+	QDSUB_VS:          "QDSUB.VS",
+	QDSUB_VC:          "QDSUB.VC",
+	QDSUB_HI:          "QDSUB.HI",
+	QDSUB_LS:          "QDSUB.LS",
+	QDSUB_GE:          "QDSUB.GE",
+	QDSUB_LT:          "QDSUB.LT",
+	QDSUB_GT:          "QDSUB.GT",
+	QDSUB_LE:          "QDSUB.LE",
+	QDSUB:             "QDSUB",
+	QDSUB_ZZ:          "QDSUB.ZZ",
+	QSAX_EQ:           "QSAX.EQ",
+	QSAX_NE:           "QSAX.NE",
+	QSAX_CS:           "QSAX.CS",
+	QSAX_CC:           "QSAX.CC",
+	QSAX_MI:           "QSAX.MI",
+	QSAX_PL:           "QSAX.PL",
+	QSAX_VS:           "QSAX.VS",
+	QSAX_VC:           "QSAX.VC",
+	QSAX_HI:           "QSAX.HI",
+	QSAX_LS:           "QSAX.LS",
+	QSAX_GE:           "QSAX.GE",
+	QSAX_LT:           "QSAX.LT",
+	QSAX_GT:           "QSAX.GT",
+	QSAX_LE:           "QSAX.LE",
+	QSAX:              "QSAX",
+	QSAX_ZZ:           "QSAX.ZZ",
+	QSUB_EQ:           "QSUB.EQ",
+	QSUB_NE:           "QSUB.NE",
+	QSUB_CS:           "QSUB.CS",
+	QSUB_CC:           "QSUB.CC",
+	QSUB_MI:           "QSUB.MI",
+	QSUB_PL:           "QSUB.PL",
+	QSUB_VS:           "QSUB.VS",
+	QSUB_VC:           "QSUB.VC",
+	QSUB_HI:           "QSUB.HI",
+	QSUB_LS:           "QSUB.LS",
+	QSUB_GE:           "QSUB.GE",
+	QSUB_LT:           "QSUB.LT",
+	QSUB_GT:           "QSUB.GT",
+	QSUB_LE:           "QSUB.LE",
+	QSUB:              "QSUB",
+	QSUB_ZZ:           "QSUB.ZZ",
+	QSUB16_EQ:         "QSUB16.EQ",
+	QSUB16_NE:         "QSUB16.NE",
+	QSUB16_CS:         "QSUB16.CS",
+	QSUB16_CC:         "QSUB16.CC",
+	QSUB16_MI:         "QSUB16.MI",
+	QSUB16_PL:         "QSUB16.PL",
+	QSUB16_VS:         "QSUB16.VS",
+	QSUB16_VC:         "QSUB16.VC",
+	QSUB16_HI:         "QSUB16.HI",
+	QSUB16_LS:         "QSUB16.LS",
+	QSUB16_GE:         "QSUB16.GE",
+	QSUB16_LT:         "QSUB16.LT",
+	QSUB16_GT:         "QSUB16.GT",
+	QSUB16_LE:         "QSUB16.LE",
+	QSUB16:            "QSUB16",
+	QSUB16_ZZ:         "QSUB16.ZZ",
+	QSUB8_EQ:          "QSUB8.EQ",
+	QSUB8_NE:          "QSUB8.NE",
+	QSUB8_CS:          "QSUB8.CS",
+	QSUB8_CC:          "QSUB8.CC",
+	QSUB8_MI:          "QSUB8.MI",
+	QSUB8_PL:          "QSUB8.PL",
+	QSUB8_VS:          "QSUB8.VS",
+	QSUB8_VC:          "QSUB8.VC",
+	QSUB8_HI:          "QSUB8.HI",
+	QSUB8_LS:          "QSUB8.LS",
+	QSUB8_GE:          "QSUB8.GE",
+	QSUB8_LT:          "QSUB8.LT",
+	QSUB8_GT:          "QSUB8.GT",
+	QSUB8_LE:          "QSUB8.LE",
+	QSUB8:             "QSUB8",
+	QSUB8_ZZ:          "QSUB8.ZZ",
+	RBIT_EQ:           "RBIT.EQ",
+	RBIT_NE:           "RBIT.NE",
+	RBIT_CS:           "RBIT.CS",
+	RBIT_CC:           "RBIT.CC",
+	RBIT_MI:           "RBIT.MI",
+	RBIT_PL:           "RBIT.PL",
+	RBIT_VS:           "RBIT.VS",
+	RBIT_VC:           "RBIT.VC",
+	RBIT_HI:           "RBIT.HI",
+	RBIT_LS:           "RBIT.LS",
+	RBIT_GE:           "RBIT.GE",
+	RBIT_LT:           "RBIT.LT",
+	RBIT_GT:           "RBIT.GT",
+	RBIT_LE:           "RBIT.LE",
+	RBIT:              "RBIT",
+	RBIT_ZZ:           "RBIT.ZZ",
+	REV_EQ:            "REV.EQ",
+	REV_NE:            "REV.NE",
+	REV_CS:            "REV.CS",
+	REV_CC:            "REV.CC",
+	REV_MI:            "REV.MI",
+	REV_PL:            "REV.PL",
+	REV_VS:            "REV.VS",
+	REV_VC:            "REV.VC",
+	REV_HI:            "REV.HI",
+	REV_LS:            "REV.LS",
+	REV_GE:            "REV.GE",
+	REV_LT:            "REV.LT",
+	REV_GT:            "REV.GT",
+	REV_LE:            "REV.LE",
+	REV:               "REV",
+	REV_ZZ:            "REV.ZZ",
+	REV16_EQ:          "REV16.EQ",
+	REV16_NE:          "REV16.NE",
+	REV16_CS:          "REV16.CS",
+	REV16_CC:          "REV16.CC",
+	REV16_MI:          "REV16.MI",
+	REV16_PL:          "REV16.PL",
+	REV16_VS:          "REV16.VS",
+	REV16_VC:          "REV16.VC",
+	REV16_HI:          "REV16.HI",
+	REV16_LS:          "REV16.LS",
+	REV16_GE:          "REV16.GE",
+	REV16_LT:          "REV16.LT",
+	REV16_GT:          "REV16.GT",
+	REV16_LE:          "REV16.LE",
+	REV16:             "REV16",
+	REV16_ZZ:          "REV16.ZZ",
+	REVSH_EQ:          "REVSH.EQ",
+	REVSH_NE:          "REVSH.NE",
+	REVSH_CS:          "REVSH.CS",
+	REVSH_CC:          "REVSH.CC",
+	REVSH_MI:          "REVSH.MI",
+	REVSH_PL:          "REVSH.PL",
+	REVSH_VS:          "REVSH.VS",
+	REVSH_VC:          "REVSH.VC",
+	REVSH_HI:          "REVSH.HI",
+	REVSH_LS:          "REVSH.LS",
+	REVSH_GE:          "REVSH.GE",
+	REVSH_LT:          "REVSH.LT",
+	REVSH_GT:          "REVSH.GT",
+	REVSH_LE:          "REVSH.LE",
+	REVSH:             "REVSH",
+	REVSH_ZZ:          "REVSH.ZZ",
+	ROR_EQ:            "ROR.EQ",
+	ROR_NE:            "ROR.NE",
+	ROR_CS:            "ROR.CS",
+	ROR_CC:            "ROR.CC",
+	ROR_MI:            "ROR.MI",
+	ROR_PL:            "ROR.PL",
+	ROR_VS:            "ROR.VS",
+	ROR_VC:            "ROR.VC",
+	ROR_HI:            "ROR.HI",
+	ROR_LS:            "ROR.LS",
+	ROR_GE:            "ROR.GE",
+	ROR_LT:            "ROR.LT",
+	ROR_GT:            "ROR.GT",
+	ROR_LE:            "ROR.LE",
+	ROR:               "ROR",
+	ROR_ZZ:            "ROR.ZZ",
+	ROR_S_EQ:          "ROR.S.EQ",
+	ROR_S_NE:          "ROR.S.NE",
+	ROR_S_CS:          "ROR.S.CS",
+	ROR_S_CC:          "ROR.S.CC",
+	ROR_S_MI:          "ROR.S.MI",
+	ROR_S_PL:          "ROR.S.PL",
+	ROR_S_VS:          "ROR.S.VS",
+	ROR_S_VC:          "ROR.S.VC",
+	ROR_S_HI:          "ROR.S.HI",
+	ROR_S_LS:          "ROR.S.LS",
+	ROR_S_GE:          "ROR.S.GE",
+	ROR_S_LT:          "ROR.S.LT",
+	ROR_S_GT:          "ROR.S.GT",
+	ROR_S_LE:          "ROR.S.LE",
+	ROR_S:             "ROR.S",
+	ROR_S_ZZ:          "ROR.S.ZZ",
+	RRX_EQ:            "RRX.EQ",
+	RRX_NE:            "RRX.NE",
+	RRX_CS:            "RRX.CS",
+	RRX_CC:            "RRX.CC",
+	RRX_MI:            "RRX.MI",
+	RRX_PL:            "RRX.PL",
+	RRX_VS:            "RRX.VS",
+	RRX_VC:            "RRX.VC",
+	RRX_HI:            "RRX.HI",
+	RRX_LS:            "RRX.LS",
+	RRX_GE:            "RRX.GE",
+	RRX_LT:            "RRX.LT",
+	RRX_GT:            "RRX.GT",
+	RRX_LE:            "RRX.LE",
+	RRX:               "RRX",
+	RRX_ZZ:            "RRX.ZZ",
+	RRX_S_EQ:          "RRX.S.EQ",
+	RRX_S_NE:          "RRX.S.NE",
+	RRX_S_CS:          "RRX.S.CS",
+	RRX_S_CC:          "RRX.S.CC",
+	RRX_S_MI:          "RRX.S.MI",
+	RRX_S_PL:          "RRX.S.PL",
+	RRX_S_VS:          "RRX.S.VS",
+	RRX_S_VC:          "RRX.S.VC",
+	RRX_S_HI:          "RRX.S.HI",
+	RRX_S_LS:          "RRX.S.LS",
+	RRX_S_GE:          "RRX.S.GE",
+	RRX_S_LT:          "RRX.S.LT",
+	RRX_S_GT:          "RRX.S.GT",
+	RRX_S_LE:          "RRX.S.LE",
+	RRX_S:             "RRX.S",
+	RRX_S_ZZ:          "RRX.S.ZZ",
+	RSB_EQ:            "RSB.EQ",
+	RSB_NE:            "RSB.NE",
+	RSB_CS:            "RSB.CS",
+	RSB_CC:            "RSB.CC",
+	RSB_MI:            "RSB.MI",
+	RSB_PL:            "RSB.PL",
+	RSB_VS:            "RSB.VS",
+	RSB_VC:            "RSB.VC",
+	RSB_HI:            "RSB.HI",
+	RSB_LS:            "RSB.LS",
+	RSB_GE:            "RSB.GE",
+	RSB_LT:            "RSB.LT",
+	RSB_GT:            "RSB.GT",
+	RSB_LE:            "RSB.LE",
+	RSB:               "RSB",
+	RSB_ZZ:            "RSB.ZZ",
+	RSB_S_EQ:          "RSB.S.EQ",
+	RSB_S_NE:          "RSB.S.NE",
+	RSB_S_CS:          "RSB.S.CS",
+	RSB_S_CC:          "RSB.S.CC",
+	RSB_S_MI:          "RSB.S.MI",
+	RSB_S_PL:          "RSB.S.PL",
+	RSB_S_VS:          "RSB.S.VS",
+	RSB_S_VC:          "RSB.S.VC",
+	RSB_S_HI:          "RSB.S.HI",
+	RSB_S_LS:          "RSB.S.LS",
+	RSB_S_GE:          "RSB.S.GE",
+	RSB_S_LT:          "RSB.S.LT",
+	RSB_S_GT:          "RSB.S.GT",
+	RSB_S_LE:          "RSB.S.LE",
+	RSB_S:             "RSB.S",
+	RSB_S_ZZ:          "RSB.S.ZZ",
+	RSC_EQ:            "RSC.EQ",
+	RSC_NE:            "RSC.NE",
+	RSC_CS:            "RSC.CS",
+	RSC_CC:            "RSC.CC",
+	RSC_MI:            "RSC.MI",
+	RSC_PL:            "RSC.PL",
+	RSC_VS:            "RSC.VS",
+	RSC_VC:            "RSC.VC",
+	RSC_HI:            "RSC.HI",
+	RSC_LS:            "RSC.LS",
+	RSC_GE:            "RSC.GE",
+	RSC_LT:            "RSC.LT",
+	RSC_GT:            "RSC.GT",
+	RSC_LE:            "RSC.LE",
+	RSC:               "RSC",
+	RSC_ZZ:            "RSC.ZZ",
+	RSC_S_EQ:          "RSC.S.EQ",
+	RSC_S_NE:          "RSC.S.NE",
+	RSC_S_CS:          "RSC.S.CS",
+	RSC_S_CC:          "RSC.S.CC",
+	RSC_S_MI:          "RSC.S.MI",
+	RSC_S_PL:          "RSC.S.PL",
+	RSC_S_VS:          "RSC.S.VS",
+	RSC_S_VC:          "RSC.S.VC",
+	RSC_S_HI:          "RSC.S.HI",
+	RSC_S_LS:          "RSC.S.LS",
+	RSC_S_GE:          "RSC.S.GE",
+	RSC_S_LT:          "RSC.S.LT",
+	RSC_S_GT:          "RSC.S.GT",
+	RSC_S_LE:          "RSC.S.LE",
+	RSC_S:             "RSC.S",
+	RSC_S_ZZ:          "RSC.S.ZZ",
+	SADD16_EQ:         "SADD16.EQ",
+	SADD16_NE:         "SADD16.NE",
+	SADD16_CS:         "SADD16.CS",
+	SADD16_CC:         "SADD16.CC",
+	SADD16_MI:         "SADD16.MI",
+	SADD16_PL:         "SADD16.PL",
+	SADD16_VS:         "SADD16.VS",
+	SADD16_VC:         "SADD16.VC",
+	SADD16_HI:         "SADD16.HI",
+	SADD16_LS:         "SADD16.LS",
+	SADD16_GE:         "SADD16.GE",
+	SADD16_LT:         "SADD16.LT",
+	SADD16_GT:         "SADD16.GT",
+	SADD16_LE:         "SADD16.LE",
+	SADD16:            "SADD16",
+	SADD16_ZZ:         "SADD16.ZZ",
+	SADD8_EQ:          "SADD8.EQ",
+	SADD8_NE:          "SADD8.NE",
+	SADD8_CS:          "SADD8.CS",
+	SADD8_CC:          "SADD8.CC",
+	SADD8_MI:          "SADD8.MI",
+	SADD8_PL:          "SADD8.PL",
+	SADD8_VS:          "SADD8.VS",
+	SADD8_VC:          "SADD8.VC",
+	SADD8_HI:          "SADD8.HI",
+	SADD8_LS:          "SADD8.LS",
+	SADD8_GE:          "SADD8.GE",
+	SADD8_LT:          "SADD8.LT",
+	SADD8_GT:          "SADD8.GT",
+	SADD8_LE:          "SADD8.LE",
+	SADD8:             "SADD8",
+	SADD8_ZZ:          "SADD8.ZZ",
+	SASX_EQ:           "SASX.EQ",
+	SASX_NE:           "SASX.NE",
+	SASX_CS:           "SASX.CS",
+	SASX_CC:           "SASX.CC",
+	SASX_MI:           "SASX.MI",
+	SASX_PL:           "SASX.PL",
+	SASX_VS:           "SASX.VS",
+	SASX_VC:           "SASX.VC",
+	SASX_HI:           "SASX.HI",
+	SASX_LS:           "SASX.LS",
+	SASX_GE:           "SASX.GE",
+	SASX_LT:           "SASX.LT",
+	SASX_GT:           "SASX.GT",
+	SASX_LE:           "SASX.LE",
+	SASX:              "SASX",
+	SASX_ZZ:           "SASX.ZZ",
+	SBC_EQ:            "SBC.EQ",
+	SBC_NE:            "SBC.NE",
+	SBC_CS:            "SBC.CS",
+	SBC_CC:            "SBC.CC",
+	SBC_MI:            "SBC.MI",
+	SBC_PL:            "SBC.PL",
+	SBC_VS:            "SBC.VS",
+	SBC_VC:            "SBC.VC",
+	SBC_HI:            "SBC.HI",
+	SBC_LS:            "SBC.LS",
+	SBC_GE:            "SBC.GE",
+	SBC_LT:            "SBC.LT",
+	SBC_GT:            "SBC.GT",
+	SBC_LE:            "SBC.LE",
+	SBC:               "SBC",
+	SBC_ZZ:            "SBC.ZZ",
+	SBC_S_EQ:          "SBC.S.EQ",
+	SBC_S_NE:          "SBC.S.NE",
+	SBC_S_CS:          "SBC.S.CS",
+	SBC_S_CC:          "SBC.S.CC",
+	SBC_S_MI:          "SBC.S.MI",
+	SBC_S_PL:          "SBC.S.PL",
+	SBC_S_VS:          "SBC.S.VS",
+	SBC_S_VC:          "SBC.S.VC",
+	SBC_S_HI:          "SBC.S.HI",
+	SBC_S_LS:          "SBC.S.LS",
+	SBC_S_GE:          "SBC.S.GE",
+	SBC_S_LT:          "SBC.S.LT",
+	SBC_S_GT:          "SBC.S.GT",
+	SBC_S_LE:          "SBC.S.LE",
+	SBC_S:             "SBC.S",
+	SBC_S_ZZ:          "SBC.S.ZZ",
+	SBFX_EQ:           "SBFX.EQ",
+	SBFX_NE:           "SBFX.NE",
+	SBFX_CS:           "SBFX.CS",
+	SBFX_CC:           "SBFX.CC",
+	SBFX_MI:           "SBFX.MI",
+	SBFX_PL:           "SBFX.PL",
+	SBFX_VS:           "SBFX.VS",
+	SBFX_VC:           "SBFX.VC",
+	SBFX_HI:           "SBFX.HI",
+	SBFX_LS:           "SBFX.LS",
+	SBFX_GE:           "SBFX.GE",
+	SBFX_LT:           "SBFX.LT",
+	SBFX_GT:           "SBFX.GT",
+	SBFX_LE:           "SBFX.LE",
+	SBFX:              "SBFX",
+	SBFX_ZZ:           "SBFX.ZZ",
+	SEL_EQ:            "SEL.EQ",
+	SEL_NE:            "SEL.NE",
+	SEL_CS:            "SEL.CS",
+	SEL_CC:            "SEL.CC",
+	SEL_MI:            "SEL.MI",
+	SEL_PL:            "SEL.PL",
+	SEL_VS:            "SEL.VS",
+	SEL_VC:            "SEL.VC",
+	SEL_HI:            "SEL.HI",
+	SEL_LS:            "SEL.LS",
+	SEL_GE:            "SEL.GE",
+	SEL_LT:            "SEL.LT",
+	SEL_GT:            "SEL.GT",
+	SEL_LE:            "SEL.LE",
+	SEL:               "SEL",
+	SEL_ZZ:            "SEL.ZZ",
+	SETEND:            "SETEND",
+	SEV_EQ:            "SEV.EQ",
+	SEV_NE:            "SEV.NE",
+	SEV_CS:            "SEV.CS",
+	SEV_CC:            "SEV.CC",
+	SEV_MI:            "SEV.MI",
+	SEV_PL:            "SEV.PL",
+	SEV_VS:            "SEV.VS",
+	SEV_VC:            "SEV.VC",
+	SEV_HI:            "SEV.HI",
+	SEV_LS:            "SEV.LS",
+	SEV_GE:            "SEV.GE",
+	SEV_LT:            "SEV.LT",
+	SEV_GT:            "SEV.GT",
+	SEV_LE:            "SEV.LE",
+	SEV:               "SEV",
+	SEV_ZZ:            "SEV.ZZ",
+	SHADD16_EQ:        "SHADD16.EQ",
+	SHADD16_NE:        "SHADD16.NE",
+	SHADD16_CS:        "SHADD16.CS",
+	SHADD16_CC:        "SHADD16.CC",
+	SHADD16_MI:        "SHADD16.MI",
+	SHADD16_PL:        "SHADD16.PL",
+	SHADD16_VS:        "SHADD16.VS",
+	SHADD16_VC:        "SHADD16.VC",
+	SHADD16_HI:        "SHADD16.HI",
+	SHADD16_LS:        "SHADD16.LS",
+	SHADD16_GE:        "SHADD16.GE",
+	SHADD16_LT:        "SHADD16.LT",
+	SHADD16_GT:        "SHADD16.GT",
+	SHADD16_LE:        "SHADD16.LE",
+	SHADD16:           "SHADD16",
+	SHADD16_ZZ:        "SHADD16.ZZ",
+	SHADD8_EQ:         "SHADD8.EQ",
+	SHADD8_NE:         "SHADD8.NE",
+	SHADD8_CS:         "SHADD8.CS",
+	SHADD8_CC:         "SHADD8.CC",
+	SHADD8_MI:         "SHADD8.MI",
+	SHADD8_PL:         "SHADD8.PL",
+	SHADD8_VS:         "SHADD8.VS",
+	SHADD8_VC:         "SHADD8.VC",
+	SHADD8_HI:         "SHADD8.HI",
+	SHADD8_LS:         "SHADD8.LS",
+	SHADD8_GE:         "SHADD8.GE",
+	SHADD8_LT:         "SHADD8.LT",
+	SHADD8_GT:         "SHADD8.GT",
+	SHADD8_LE:         "SHADD8.LE",
+	SHADD8:            "SHADD8",
+	SHADD8_ZZ:         "SHADD8.ZZ",
+	SHASX_EQ:          "SHASX.EQ",
+	SHASX_NE:          "SHASX.NE",
+	SHASX_CS:          "SHASX.CS",
+	SHASX_CC:          "SHASX.CC",
+	SHASX_MI:          "SHASX.MI",
+	SHASX_PL:          "SHASX.PL",
+	SHASX_VS:          "SHASX.VS",
+	SHASX_VC:          "SHASX.VC",
+	SHASX_HI:          "SHASX.HI",
+	SHASX_LS:          "SHASX.LS",
+	SHASX_GE:          "SHASX.GE",
+	SHASX_LT:          "SHASX.LT",
+	SHASX_GT:          "SHASX.GT",
+	SHASX_LE:          "SHASX.LE",
+	SHASX:             "SHASX",
+	SHASX_ZZ:          "SHASX.ZZ",
+	SHSAX_EQ:          "SHSAX.EQ",
+	SHSAX_NE:          "SHSAX.NE",
+	SHSAX_CS:          "SHSAX.CS",
+	SHSAX_CC:          "SHSAX.CC",
+	SHSAX_MI:          "SHSAX.MI",
+	SHSAX_PL:          "SHSAX.PL",
+	SHSAX_VS:          "SHSAX.VS",
+	SHSAX_VC:          "SHSAX.VC",
+	SHSAX_HI:          "SHSAX.HI",
+	SHSAX_LS:          "SHSAX.LS",
+	SHSAX_GE:          "SHSAX.GE",
+	SHSAX_LT:          "SHSAX.LT",
+	SHSAX_GT:          "SHSAX.GT",
+	SHSAX_LE:          "SHSAX.LE",
+	SHSAX:             "SHSAX",
+	SHSAX_ZZ:          "SHSAX.ZZ",
+	SHSUB16_EQ:        "SHSUB16.EQ",
+	SHSUB16_NE:        "SHSUB16.NE",
+	SHSUB16_CS:        "SHSUB16.CS",
+	SHSUB16_CC:        "SHSUB16.CC",
+	SHSUB16_MI:        "SHSUB16.MI",
+	SHSUB16_PL:        "SHSUB16.PL",
+	SHSUB16_VS:        "SHSUB16.VS",
+	SHSUB16_VC:        "SHSUB16.VC",
+	SHSUB16_HI:        "SHSUB16.HI",
+	SHSUB16_LS:        "SHSUB16.LS",
+	SHSUB16_GE:        "SHSUB16.GE",
+	SHSUB16_LT:        "SHSUB16.LT",
+	SHSUB16_GT:        "SHSUB16.GT",
+	SHSUB16_LE:        "SHSUB16.LE",
+	SHSUB16:           "SHSUB16",
+	SHSUB16_ZZ:        "SHSUB16.ZZ",
+	SHSUB8_EQ:         "SHSUB8.EQ",
+	SHSUB8_NE:         "SHSUB8.NE",
+	SHSUB8_CS:         "SHSUB8.CS",
+	SHSUB8_CC:         "SHSUB8.CC",
+	SHSUB8_MI:         "SHSUB8.MI",
+	SHSUB8_PL:         "SHSUB8.PL",
+	SHSUB8_VS:         "SHSUB8.VS",
+	SHSUB8_VC:         "SHSUB8.VC",
+	SHSUB8_HI:         "SHSUB8.HI",
+	SHSUB8_LS:         "SHSUB8.LS",
+	SHSUB8_GE:         "SHSUB8.GE",
+	SHSUB8_LT:         "SHSUB8.LT",
+	SHSUB8_GT:         "SHSUB8.GT",
+	SHSUB8_LE:         "SHSUB8.LE",
+	SHSUB8:            "SHSUB8",
+	SHSUB8_ZZ:         "SHSUB8.ZZ",
+	SMLABB_EQ:         "SMLABB.EQ",
+	SMLABB_NE:         "SMLABB.NE",
+	SMLABB_CS:         "SMLABB.CS",
+	SMLABB_CC:         "SMLABB.CC",
+	SMLABB_MI:         "SMLABB.MI",
+	SMLABB_PL:         "SMLABB.PL",
+	SMLABB_VS:         "SMLABB.VS",
+	SMLABB_VC:         "SMLABB.VC",
+	SMLABB_HI:         "SMLABB.HI",
+	SMLABB_LS:         "SMLABB.LS",
+	SMLABB_GE:         "SMLABB.GE",
+	SMLABB_LT:         "SMLABB.LT",
+	SMLABB_GT:         "SMLABB.GT",
+	SMLABB_LE:         "SMLABB.LE",
+	SMLABB:            "SMLABB",
+	SMLABB_ZZ:         "SMLABB.ZZ",
+	SMLABT_EQ:         "SMLABT.EQ",
+	SMLABT_NE:         "SMLABT.NE",
+	SMLABT_CS:         "SMLABT.CS",
+	SMLABT_CC:         "SMLABT.CC",
+	SMLABT_MI:         "SMLABT.MI",
+	SMLABT_PL:         "SMLABT.PL",
+	SMLABT_VS:         "SMLABT.VS",
+	SMLABT_VC:         "SMLABT.VC",
+	SMLABT_HI:         "SMLABT.HI",
+	SMLABT_LS:         "SMLABT.LS",
+	SMLABT_GE:         "SMLABT.GE",
+	SMLABT_LT:         "SMLABT.LT",
+	SMLABT_GT:         "SMLABT.GT",
+	SMLABT_LE:         "SMLABT.LE",
+	SMLABT:            "SMLABT",
+	SMLABT_ZZ:         "SMLABT.ZZ",
+	SMLATB_EQ:         "SMLATB.EQ",
+	SMLATB_NE:         "SMLATB.NE",
+	SMLATB_CS:         "SMLATB.CS",
+	SMLATB_CC:         "SMLATB.CC",
+	SMLATB_MI:         "SMLATB.MI",
+	SMLATB_PL:         "SMLATB.PL",
+	SMLATB_VS:         "SMLATB.VS",
+	SMLATB_VC:         "SMLATB.VC",
+	SMLATB_HI:         "SMLATB.HI",
+	SMLATB_LS:         "SMLATB.LS",
+	SMLATB_GE:         "SMLATB.GE",
+	SMLATB_LT:         "SMLATB.LT",
+	SMLATB_GT:         "SMLATB.GT",
+	SMLATB_LE:         "SMLATB.LE",
+	SMLATB:            "SMLATB",
+	SMLATB_ZZ:         "SMLATB.ZZ",
+	SMLATT_EQ:         "SMLATT.EQ",
+	SMLATT_NE:         "SMLATT.NE",
+	SMLATT_CS:         "SMLATT.CS",
+	SMLATT_CC:         "SMLATT.CC",
+	SMLATT_MI:         "SMLATT.MI",
+	SMLATT_PL:         "SMLATT.PL",
+	SMLATT_VS:         "SMLATT.VS",
+	SMLATT_VC:         "SMLATT.VC",
+	SMLATT_HI:         "SMLATT.HI",
+	SMLATT_LS:         "SMLATT.LS",
+	SMLATT_GE:         "SMLATT.GE",
+	SMLATT_LT:         "SMLATT.LT",
+	SMLATT_GT:         "SMLATT.GT",
+	SMLATT_LE:         "SMLATT.LE",
+	SMLATT:            "SMLATT",
+	SMLATT_ZZ:         "SMLATT.ZZ",
+	SMLAD_EQ:          "SMLAD.EQ",
+	SMLAD_NE:          "SMLAD.NE",
+	SMLAD_CS:          "SMLAD.CS",
+	SMLAD_CC:          "SMLAD.CC",
+	SMLAD_MI:          "SMLAD.MI",
+	SMLAD_PL:          "SMLAD.PL",
+	SMLAD_VS:          "SMLAD.VS",
+	SMLAD_VC:          "SMLAD.VC",
+	SMLAD_HI:          "SMLAD.HI",
+	SMLAD_LS:          "SMLAD.LS",
+	SMLAD_GE:          "SMLAD.GE",
+	SMLAD_LT:          "SMLAD.LT",
+	SMLAD_GT:          "SMLAD.GT",
+	SMLAD_LE:          "SMLAD.LE",
+	SMLAD:             "SMLAD",
+	SMLAD_ZZ:          "SMLAD.ZZ",
+	SMLAD_X_EQ:        "SMLAD.X.EQ",
+	SMLAD_X_NE:        "SMLAD.X.NE",
+	SMLAD_X_CS:        "SMLAD.X.CS",
+	SMLAD_X_CC:        "SMLAD.X.CC",
+	SMLAD_X_MI:        "SMLAD.X.MI",
+	SMLAD_X_PL:        "SMLAD.X.PL",
+	SMLAD_X_VS:        "SMLAD.X.VS",
+	SMLAD_X_VC:        "SMLAD.X.VC",
+	SMLAD_X_HI:        "SMLAD.X.HI",
+	SMLAD_X_LS:        "SMLAD.X.LS",
+	SMLAD_X_GE:        "SMLAD.X.GE",
+	SMLAD_X_LT:        "SMLAD.X.LT",
+	SMLAD_X_GT:        "SMLAD.X.GT",
+	SMLAD_X_LE:        "SMLAD.X.LE",
+	SMLAD_X:           "SMLAD.X",
+	SMLAD_X_ZZ:        "SMLAD.X.ZZ",
+	SMLAL_EQ:          "SMLAL.EQ",
+	SMLAL_NE:          "SMLAL.NE",
+	SMLAL_CS:          "SMLAL.CS",
+	SMLAL_CC:          "SMLAL.CC",
+	SMLAL_MI:          "SMLAL.MI",
+	SMLAL_PL:          "SMLAL.PL",
+	SMLAL_VS:          "SMLAL.VS",
+	SMLAL_VC:          "SMLAL.VC",
+	SMLAL_HI:          "SMLAL.HI",
+	SMLAL_LS:          "SMLAL.LS",
+	SMLAL_GE:          "SMLAL.GE",
+	SMLAL_LT:          "SMLAL.LT",
+	SMLAL_GT:          "SMLAL.GT",
+	SMLAL_LE:          "SMLAL.LE",
+	SMLAL:             "SMLAL",
+	SMLAL_ZZ:          "SMLAL.ZZ",
+	SMLAL_S_EQ:        "SMLAL.S.EQ",
+	SMLAL_S_NE:        "SMLAL.S.NE",
+	SMLAL_S_CS:        "SMLAL.S.CS",
+	SMLAL_S_CC:        "SMLAL.S.CC",
+	SMLAL_S_MI:        "SMLAL.S.MI",
+	SMLAL_S_PL:        "SMLAL.S.PL",
+	SMLAL_S_VS:        "SMLAL.S.VS",
+	SMLAL_S_VC:        "SMLAL.S.VC",
+	SMLAL_S_HI:        "SMLAL.S.HI",
+	SMLAL_S_LS:        "SMLAL.S.LS",
+	SMLAL_S_GE:        "SMLAL.S.GE",
+	SMLAL_S_LT:        "SMLAL.S.LT",
+	SMLAL_S_GT:        "SMLAL.S.GT",
+	SMLAL_S_LE:        "SMLAL.S.LE",
+	SMLAL_S:           "SMLAL.S",
+	SMLAL_S_ZZ:        "SMLAL.S.ZZ",
+	SMLALBB_EQ:        "SMLALBB.EQ",
+	SMLALBB_NE:        "SMLALBB.NE",
+	SMLALBB_CS:        "SMLALBB.CS",
+	SMLALBB_CC:        "SMLALBB.CC",
+	SMLALBB_MI:        "SMLALBB.MI",
+	SMLALBB_PL:        "SMLALBB.PL",
+	SMLALBB_VS:        "SMLALBB.VS",
+	SMLALBB_VC:        "SMLALBB.VC",
+	SMLALBB_HI:        "SMLALBB.HI",
+	SMLALBB_LS:        "SMLALBB.LS",
+	SMLALBB_GE:        "SMLALBB.GE",
+	SMLALBB_LT:        "SMLALBB.LT",
+	SMLALBB_GT:        "SMLALBB.GT",
+	SMLALBB_LE:        "SMLALBB.LE",
+	SMLALBB:           "SMLALBB",
+	SMLALBB_ZZ:        "SMLALBB.ZZ",
+	SMLALBT_EQ:        "SMLALBT.EQ",
+	SMLALBT_NE:        "SMLALBT.NE",
+	SMLALBT_CS:        "SMLALBT.CS",
+	SMLALBT_CC:        "SMLALBT.CC",
+	SMLALBT_MI:        "SMLALBT.MI",
+	SMLALBT_PL:        "SMLALBT.PL",
+	SMLALBT_VS:        "SMLALBT.VS",
+	SMLALBT_VC:        "SMLALBT.VC",
+	SMLALBT_HI:        "SMLALBT.HI",
+	SMLALBT_LS:        "SMLALBT.LS",
+	SMLALBT_GE:        "SMLALBT.GE",
+	SMLALBT_LT:        "SMLALBT.LT",
+	SMLALBT_GT:        "SMLALBT.GT",
+	SMLALBT_LE:        "SMLALBT.LE",
+	SMLALBT:           "SMLALBT",
+	SMLALBT_ZZ:        "SMLALBT.ZZ",
+	SMLALTB_EQ:        "SMLALTB.EQ",
+	SMLALTB_NE:        "SMLALTB.NE",
+	SMLALTB_CS:        "SMLALTB.CS",
+	SMLALTB_CC:        "SMLALTB.CC",
+	SMLALTB_MI:        "SMLALTB.MI",
+	SMLALTB_PL:        "SMLALTB.PL",
+	SMLALTB_VS:        "SMLALTB.VS",
+	SMLALTB_VC:        "SMLALTB.VC",
+	SMLALTB_HI:        "SMLALTB.HI",
+	SMLALTB_LS:        "SMLALTB.LS",
+	SMLALTB_GE:        "SMLALTB.GE",
+	SMLALTB_LT:        "SMLALTB.LT",
+	SMLALTB_GT:        "SMLALTB.GT",
+	SMLALTB_LE:        "SMLALTB.LE",
+	SMLALTB:           "SMLALTB",
+	SMLALTB_ZZ:        "SMLALTB.ZZ",
+	SMLALTT_EQ:        "SMLALTT.EQ",
+	SMLALTT_NE:        "SMLALTT.NE",
+	SMLALTT_CS:        "SMLALTT.CS",
+	SMLALTT_CC:        "SMLALTT.CC",
+	SMLALTT_MI:        "SMLALTT.MI",
+	SMLALTT_PL:        "SMLALTT.PL",
+	SMLALTT_VS:        "SMLALTT.VS",
+	SMLALTT_VC:        "SMLALTT.VC",
+	SMLALTT_HI:        "SMLALTT.HI",
+	SMLALTT_LS:        "SMLALTT.LS",
+	SMLALTT_GE:        "SMLALTT.GE",
+	SMLALTT_LT:        "SMLALTT.LT",
+	SMLALTT_GT:        "SMLALTT.GT",
+	SMLALTT_LE:        "SMLALTT.LE",
+	SMLALTT:           "SMLALTT",
+	SMLALTT_ZZ:        "SMLALTT.ZZ",
+	SMLALD_EQ:         "SMLALD.EQ",
+	SMLALD_NE:         "SMLALD.NE",
+	SMLALD_CS:         "SMLALD.CS",
+	SMLALD_CC:         "SMLALD.CC",
+	SMLALD_MI:         "SMLALD.MI",
+	SMLALD_PL:         "SMLALD.PL",
+	SMLALD_VS:         "SMLALD.VS",
+	SMLALD_VC:         "SMLALD.VC",
+	SMLALD_HI:         "SMLALD.HI",
+	SMLALD_LS:         "SMLALD.LS",
+	SMLALD_GE:         "SMLALD.GE",
+	SMLALD_LT:         "SMLALD.LT",
+	SMLALD_GT:         "SMLALD.GT",
+	SMLALD_LE:         "SMLALD.LE",
+	SMLALD:            "SMLALD",
+	SMLALD_ZZ:         "SMLALD.ZZ",
+	SMLALD_X_EQ:       "SMLALD.X.EQ",
+	SMLALD_X_NE:       "SMLALD.X.NE",
+	SMLALD_X_CS:       "SMLALD.X.CS",
+	SMLALD_X_CC:       "SMLALD.X.CC",
+	SMLALD_X_MI:       "SMLALD.X.MI",
+	SMLALD_X_PL:       "SMLALD.X.PL",
+	SMLALD_X_VS:       "SMLALD.X.VS",
+	SMLALD_X_VC:       "SMLALD.X.VC",
+	SMLALD_X_HI:       "SMLALD.X.HI",
+	SMLALD_X_LS:       "SMLALD.X.LS",
+	SMLALD_X_GE:       "SMLALD.X.GE",
+	SMLALD_X_LT:       "SMLALD.X.LT",
+	SMLALD_X_GT:       "SMLALD.X.GT",
+	SMLALD_X_LE:       "SMLALD.X.LE",
+	SMLALD_X:          "SMLALD.X",
+	SMLALD_X_ZZ:       "SMLALD.X.ZZ",
+	SMLAWB_EQ:         "SMLAWB.EQ",
+	SMLAWB_NE:         "SMLAWB.NE",
+	SMLAWB_CS:         "SMLAWB.CS",
+	SMLAWB_CC:         "SMLAWB.CC",
+	SMLAWB_MI:         "SMLAWB.MI",
+	SMLAWB_PL:         "SMLAWB.PL",
+	SMLAWB_VS:         "SMLAWB.VS",
+	SMLAWB_VC:         "SMLAWB.VC",
+	SMLAWB_HI:         "SMLAWB.HI",
+	SMLAWB_LS:         "SMLAWB.LS",
+	SMLAWB_GE:         "SMLAWB.GE",
+	SMLAWB_LT:         "SMLAWB.LT",
+	SMLAWB_GT:         "SMLAWB.GT",
+	SMLAWB_LE:         "SMLAWB.LE",
+	SMLAWB:            "SMLAWB",
+	SMLAWB_ZZ:         "SMLAWB.ZZ",
+	SMLAWT_EQ:         "SMLAWT.EQ",
+	SMLAWT_NE:         "SMLAWT.NE",
+	SMLAWT_CS:         "SMLAWT.CS",
+	SMLAWT_CC:         "SMLAWT.CC",
+	SMLAWT_MI:         "SMLAWT.MI",
+	SMLAWT_PL:         "SMLAWT.PL",
+	SMLAWT_VS:         "SMLAWT.VS",
+	SMLAWT_VC:         "SMLAWT.VC",
+	SMLAWT_HI:         "SMLAWT.HI",
+	SMLAWT_LS:         "SMLAWT.LS",
+	SMLAWT_GE:         "SMLAWT.GE",
+	SMLAWT_LT:         "SMLAWT.LT",
+	SMLAWT_GT:         "SMLAWT.GT",
+	SMLAWT_LE:         "SMLAWT.LE",
+	SMLAWT:            "SMLAWT",
+	SMLAWT_ZZ:         "SMLAWT.ZZ",
+	SMLSD_EQ:          "SMLSD.EQ",
+	SMLSD_NE:          "SMLSD.NE",
+	SMLSD_CS:          "SMLSD.CS",
+	SMLSD_CC:          "SMLSD.CC",
+	SMLSD_MI:          "SMLSD.MI",
+	SMLSD_PL:          "SMLSD.PL",
+	SMLSD_VS:          "SMLSD.VS",
+	SMLSD_VC:          "SMLSD.VC",
+	SMLSD_HI:          "SMLSD.HI",
+	SMLSD_LS:          "SMLSD.LS",
+	SMLSD_GE:          "SMLSD.GE",
+	SMLSD_LT:          "SMLSD.LT",
+	SMLSD_GT:          "SMLSD.GT",
+	SMLSD_LE:          "SMLSD.LE",
+	SMLSD:             "SMLSD",
+	SMLSD_ZZ:          "SMLSD.ZZ",
+	SMLSD_X_EQ:        "SMLSD.X.EQ",
+	SMLSD_X_NE:        "SMLSD.X.NE",
+	SMLSD_X_CS:        "SMLSD.X.CS",
+	SMLSD_X_CC:        "SMLSD.X.CC",
+	SMLSD_X_MI:        "SMLSD.X.MI",
+	SMLSD_X_PL:        "SMLSD.X.PL",
+	SMLSD_X_VS:        "SMLSD.X.VS",
+	SMLSD_X_VC:        "SMLSD.X.VC",
+	SMLSD_X_HI:        "SMLSD.X.HI",
+	SMLSD_X_LS:        "SMLSD.X.LS",
+	SMLSD_X_GE:        "SMLSD.X.GE",
+	SMLSD_X_LT:        "SMLSD.X.LT",
+	SMLSD_X_GT:        "SMLSD.X.GT",
+	SMLSD_X_LE:        "SMLSD.X.LE",
+	SMLSD_X:           "SMLSD.X",
+	SMLSD_X_ZZ:        "SMLSD.X.ZZ",
+	SMLSLD_EQ:         "SMLSLD.EQ",
+	SMLSLD_NE:         "SMLSLD.NE",
+	SMLSLD_CS:         "SMLSLD.CS",
+	SMLSLD_CC:         "SMLSLD.CC",
+	SMLSLD_MI:         "SMLSLD.MI",
+	SMLSLD_PL:         "SMLSLD.PL",
+	SMLSLD_VS:         "SMLSLD.VS",
+	SMLSLD_VC:         "SMLSLD.VC",
+	SMLSLD_HI:         "SMLSLD.HI",
+	SMLSLD_LS:         "SMLSLD.LS",
+	SMLSLD_GE:         "SMLSLD.GE",
+	SMLSLD_LT:         "SMLSLD.LT",
+	SMLSLD_GT:         "SMLSLD.GT",
+	SMLSLD_LE:         "SMLSLD.LE",
+	SMLSLD:            "SMLSLD",
+	SMLSLD_ZZ:         "SMLSLD.ZZ",
+	SMLSLD_X_EQ:       "SMLSLD.X.EQ",
+	SMLSLD_X_NE:       "SMLSLD.X.NE",
+	SMLSLD_X_CS:       "SMLSLD.X.CS",
+	SMLSLD_X_CC:       "SMLSLD.X.CC",
+	SMLSLD_X_MI:       "SMLSLD.X.MI",
+	SMLSLD_X_PL:       "SMLSLD.X.PL",
+	SMLSLD_X_VS:       "SMLSLD.X.VS",
+	SMLSLD_X_VC:       "SMLSLD.X.VC",
+	SMLSLD_X_HI:       "SMLSLD.X.HI",
+	SMLSLD_X_LS:       "SMLSLD.X.LS",
+	SMLSLD_X_GE:       "SMLSLD.X.GE",
+	SMLSLD_X_LT:       "SMLSLD.X.LT",
+	SMLSLD_X_GT:       "SMLSLD.X.GT",
+	SMLSLD_X_LE:       "SMLSLD.X.LE",
+	SMLSLD_X:          "SMLSLD.X",
+	SMLSLD_X_ZZ:       "SMLSLD.X.ZZ",
+	SMMLA_EQ:          "SMMLA.EQ",
+	SMMLA_NE:          "SMMLA.NE",
+	SMMLA_CS:          "SMMLA.CS",
+	SMMLA_CC:          "SMMLA.CC",
+	SMMLA_MI:          "SMMLA.MI",
+	SMMLA_PL:          "SMMLA.PL",
+	SMMLA_VS:          "SMMLA.VS",
+	SMMLA_VC:          "SMMLA.VC",
+	SMMLA_HI:          "SMMLA.HI",
+	SMMLA_LS:          "SMMLA.LS",
+	SMMLA_GE:          "SMMLA.GE",
+	SMMLA_LT:          "SMMLA.LT",
+	SMMLA_GT:          "SMMLA.GT",
+	SMMLA_LE:          "SMMLA.LE",
+	SMMLA:             "SMMLA",
+	SMMLA_ZZ:          "SMMLA.ZZ",
+	SMMLA_R_EQ:        "SMMLA.R.EQ",
+	SMMLA_R_NE:        "SMMLA.R.NE",
+	SMMLA_R_CS:        "SMMLA.R.CS",
+	SMMLA_R_CC:        "SMMLA.R.CC",
+	SMMLA_R_MI:        "SMMLA.R.MI",
+	SMMLA_R_PL:        "SMMLA.R.PL",
+	SMMLA_R_VS:        "SMMLA.R.VS",
+	SMMLA_R_VC:        "SMMLA.R.VC",
+	SMMLA_R_HI:        "SMMLA.R.HI",
+	SMMLA_R_LS:        "SMMLA.R.LS",
+	SMMLA_R_GE:        "SMMLA.R.GE",
+	SMMLA_R_LT:        "SMMLA.R.LT",
+	SMMLA_R_GT:        "SMMLA.R.GT",
+	SMMLA_R_LE:        "SMMLA.R.LE",
+	SMMLA_R:           "SMMLA.R",
+	SMMLA_R_ZZ:        "SMMLA.R.ZZ",
+	SMMLS_EQ:          "SMMLS.EQ",
+	SMMLS_NE:          "SMMLS.NE",
+	SMMLS_CS:          "SMMLS.CS",
+	SMMLS_CC:          "SMMLS.CC",
+	SMMLS_MI:          "SMMLS.MI",
+	SMMLS_PL:          "SMMLS.PL",
+	SMMLS_VS:          "SMMLS.VS",
+	SMMLS_VC:          "SMMLS.VC",
+	SMMLS_HI:          "SMMLS.HI",
+	SMMLS_LS:          "SMMLS.LS",
+	SMMLS_GE:          "SMMLS.GE",
+	SMMLS_LT:          "SMMLS.LT",
+	SMMLS_GT:          "SMMLS.GT",
+	SMMLS_LE:          "SMMLS.LE",
+	SMMLS:             "SMMLS",
+	SMMLS_ZZ:          "SMMLS.ZZ",
+	SMMLS_R_EQ:        "SMMLS.R.EQ",
+	SMMLS_R_NE:        "SMMLS.R.NE",
+	SMMLS_R_CS:        "SMMLS.R.CS",
+	SMMLS_R_CC:        "SMMLS.R.CC",
+	SMMLS_R_MI:        "SMMLS.R.MI",
+	SMMLS_R_PL:        "SMMLS.R.PL",
+	SMMLS_R_VS:        "SMMLS.R.VS",
+	SMMLS_R_VC:        "SMMLS.R.VC",
+	SMMLS_R_HI:        "SMMLS.R.HI",
+	SMMLS_R_LS:        "SMMLS.R.LS",
+	SMMLS_R_GE:        "SMMLS.R.GE",
+	SMMLS_R_LT:        "SMMLS.R.LT",
+	SMMLS_R_GT:        "SMMLS.R.GT",
+	SMMLS_R_LE:        "SMMLS.R.LE",
+	SMMLS_R:           "SMMLS.R",
+	SMMLS_R_ZZ:        "SMMLS.R.ZZ",
+	SMMUL_EQ:          "SMMUL.EQ",
+	SMMUL_NE:          "SMMUL.NE",
+	SMMUL_CS:          "SMMUL.CS",
+	SMMUL_CC:          "SMMUL.CC",
+	SMMUL_MI:          "SMMUL.MI",
+	SMMUL_PL:          "SMMUL.PL",
+	SMMUL_VS:          "SMMUL.VS",
+	SMMUL_VC:          "SMMUL.VC",
+	SMMUL_HI:          "SMMUL.HI",
+	SMMUL_LS:          "SMMUL.LS",
+	SMMUL_GE:          "SMMUL.GE",
+	SMMUL_LT:          "SMMUL.LT",
+	SMMUL_GT:          "SMMUL.GT",
+	SMMUL_LE:          "SMMUL.LE",
+	SMMUL:             "SMMUL",
+	SMMUL_ZZ:          "SMMUL.ZZ",
+	SMMUL_R_EQ:        "SMMUL.R.EQ",
+	SMMUL_R_NE:        "SMMUL.R.NE",
+	SMMUL_R_CS:        "SMMUL.R.CS",
+	SMMUL_R_CC:        "SMMUL.R.CC",
+	SMMUL_R_MI:        "SMMUL.R.MI",
+	SMMUL_R_PL:        "SMMUL.R.PL",
+	SMMUL_R_VS:        "SMMUL.R.VS",
+	SMMUL_R_VC:        "SMMUL.R.VC",
+	SMMUL_R_HI:        "SMMUL.R.HI",
+	SMMUL_R_LS:        "SMMUL.R.LS",
+	SMMUL_R_GE:        "SMMUL.R.GE",
+	SMMUL_R_LT:        "SMMUL.R.LT",
+	SMMUL_R_GT:        "SMMUL.R.GT",
+	SMMUL_R_LE:        "SMMUL.R.LE",
+	SMMUL_R:           "SMMUL.R",
+	SMMUL_R_ZZ:        "SMMUL.R.ZZ",
+	SMUAD_EQ:          "SMUAD.EQ",
+	SMUAD_NE:          "SMUAD.NE",
+	SMUAD_CS:          "SMUAD.CS",
+	SMUAD_CC:          "SMUAD.CC",
+	SMUAD_MI:          "SMUAD.MI",
+	SMUAD_PL:          "SMUAD.PL",
+	SMUAD_VS:          "SMUAD.VS",
+	SMUAD_VC:          "SMUAD.VC",
+	SMUAD_HI:          "SMUAD.HI",
+	SMUAD_LS:          "SMUAD.LS",
+	SMUAD_GE:          "SMUAD.GE",
+	SMUAD_LT:          "SMUAD.LT",
+	SMUAD_GT:          "SMUAD.GT",
+	SMUAD_LE:          "SMUAD.LE",
+	SMUAD:             "SMUAD",
+	SMUAD_ZZ:          "SMUAD.ZZ",
+	SMUAD_X_EQ:        "SMUAD.X.EQ",
+	SMUAD_X_NE:        "SMUAD.X.NE",
+	SMUAD_X_CS:        "SMUAD.X.CS",
+	SMUAD_X_CC:        "SMUAD.X.CC",
+	SMUAD_X_MI:        "SMUAD.X.MI",
+	SMUAD_X_PL:        "SMUAD.X.PL",
+	SMUAD_X_VS:        "SMUAD.X.VS",
+	SMUAD_X_VC:        "SMUAD.X.VC",
+	SMUAD_X_HI:        "SMUAD.X.HI",
+	SMUAD_X_LS:        "SMUAD.X.LS",
+	SMUAD_X_GE:        "SMUAD.X.GE",
+	SMUAD_X_LT:        "SMUAD.X.LT",
+	SMUAD_X_GT:        "SMUAD.X.GT",
+	SMUAD_X_LE:        "SMUAD.X.LE",
+	SMUAD_X:           "SMUAD.X",
+	SMUAD_X_ZZ:        "SMUAD.X.ZZ",
+	SMULBB_EQ:         "SMULBB.EQ",
+	SMULBB_NE:         "SMULBB.NE",
+	SMULBB_CS:         "SMULBB.CS",
+	SMULBB_CC:         "SMULBB.CC",
+	SMULBB_MI:         "SMULBB.MI",
+	SMULBB_PL:         "SMULBB.PL",
+	SMULBB_VS:         "SMULBB.VS",
+	SMULBB_VC:         "SMULBB.VC",
+	SMULBB_HI:         "SMULBB.HI",
+	SMULBB_LS:         "SMULBB.LS",
+	SMULBB_GE:         "SMULBB.GE",
+	SMULBB_LT:         "SMULBB.LT",
+	SMULBB_GT:         "SMULBB.GT",
+	SMULBB_LE:         "SMULBB.LE",
+	SMULBB:            "SMULBB",
+	SMULBB_ZZ:         "SMULBB.ZZ",
+	SMULBT_EQ:         "SMULBT.EQ",
+	SMULBT_NE:         "SMULBT.NE",
+	SMULBT_CS:         "SMULBT.CS",
+	SMULBT_CC:         "SMULBT.CC",
+	SMULBT_MI:         "SMULBT.MI",
+	SMULBT_PL:         "SMULBT.PL",
+	SMULBT_VS:         "SMULBT.VS",
+	SMULBT_VC:         "SMULBT.VC",
+	SMULBT_HI:         "SMULBT.HI",
+	SMULBT_LS:         "SMULBT.LS",
+	SMULBT_GE:         "SMULBT.GE",
+	SMULBT_LT:         "SMULBT.LT",
+	SMULBT_GT:         "SMULBT.GT",
+	SMULBT_LE:         "SMULBT.LE",
+	SMULBT:            "SMULBT",
+	SMULBT_ZZ:         "SMULBT.ZZ",
+	SMULTB_EQ:         "SMULTB.EQ",
+	SMULTB_NE:         "SMULTB.NE",
+	SMULTB_CS:         "SMULTB.CS",
+	SMULTB_CC:         "SMULTB.CC",
+	SMULTB_MI:         "SMULTB.MI",
+	SMULTB_PL:         "SMULTB.PL",
+	SMULTB_VS:         "SMULTB.VS",
+	SMULTB_VC:         "SMULTB.VC",
+	SMULTB_HI:         "SMULTB.HI",
+	SMULTB_LS:         "SMULTB.LS",
+	SMULTB_GE:         "SMULTB.GE",
+	SMULTB_LT:         "SMULTB.LT",
+	SMULTB_GT:         "SMULTB.GT",
+	SMULTB_LE:         "SMULTB.LE",
+	SMULTB:            "SMULTB",
+	SMULTB_ZZ:         "SMULTB.ZZ",
+	SMULTT_EQ:         "SMULTT.EQ",
+	SMULTT_NE:         "SMULTT.NE",
+	SMULTT_CS:         "SMULTT.CS",
+	SMULTT_CC:         "SMULTT.CC",
+	SMULTT_MI:         "SMULTT.MI",
+	SMULTT_PL:         "SMULTT.PL",
+	SMULTT_VS:         "SMULTT.VS",
+	SMULTT_VC:         "SMULTT.VC",
+	SMULTT_HI:         "SMULTT.HI",
+	SMULTT_LS:         "SMULTT.LS",
+	SMULTT_GE:         "SMULTT.GE",
+	SMULTT_LT:         "SMULTT.LT",
+	SMULTT_GT:         "SMULTT.GT",
+	SMULTT_LE:         "SMULTT.LE",
+	SMULTT:            "SMULTT",
+	SMULTT_ZZ:         "SMULTT.ZZ",
+	SMULL_EQ:          "SMULL.EQ",
+	SMULL_NE:          "SMULL.NE",
+	SMULL_CS:          "SMULL.CS",
+	SMULL_CC:          "SMULL.CC",
+	SMULL_MI:          "SMULL.MI",
+	SMULL_PL:          "SMULL.PL",
+	SMULL_VS:          "SMULL.VS",
+	SMULL_VC:          "SMULL.VC",
+	SMULL_HI:          "SMULL.HI",
+	SMULL_LS:          "SMULL.LS",
+	SMULL_GE:          "SMULL.GE",
+	SMULL_LT:          "SMULL.LT",
+	SMULL_GT:          "SMULL.GT",
+	SMULL_LE:          "SMULL.LE",
+	SMULL:             "SMULL",
+	SMULL_ZZ:          "SMULL.ZZ",
+	SMULL_S_EQ:        "SMULL.S.EQ",
+	SMULL_S_NE:        "SMULL.S.NE",
+	SMULL_S_CS:        "SMULL.S.CS",
+	SMULL_S_CC:        "SMULL.S.CC",
+	SMULL_S_MI:        "SMULL.S.MI",
+	SMULL_S_PL:        "SMULL.S.PL",
+	SMULL_S_VS:        "SMULL.S.VS",
+	SMULL_S_VC:        "SMULL.S.VC",
+	SMULL_S_HI:        "SMULL.S.HI",
+	SMULL_S_LS:        "SMULL.S.LS",
+	SMULL_S_GE:        "SMULL.S.GE",
+	SMULL_S_LT:        "SMULL.S.LT",
+	SMULL_S_GT:        "SMULL.S.GT",
+	SMULL_S_LE:        "SMULL.S.LE",
+	SMULL_S:           "SMULL.S",
+	SMULL_S_ZZ:        "SMULL.S.ZZ",
+	SMULWB_EQ:         "SMULWB.EQ",
+	SMULWB_NE:         "SMULWB.NE",
+	SMULWB_CS:         "SMULWB.CS",
+	SMULWB_CC:         "SMULWB.CC",
+	SMULWB_MI:         "SMULWB.MI",
+	SMULWB_PL:         "SMULWB.PL",
+	SMULWB_VS:         "SMULWB.VS",
+	SMULWB_VC:         "SMULWB.VC",
+	SMULWB_HI:         "SMULWB.HI",
+	SMULWB_LS:         "SMULWB.LS",
+	SMULWB_GE:         "SMULWB.GE",
+	SMULWB_LT:         "SMULWB.LT",
+	SMULWB_GT:         "SMULWB.GT",
+	SMULWB_LE:         "SMULWB.LE",
+	SMULWB:            "SMULWB",
+	SMULWB_ZZ:         "SMULWB.ZZ",
+	SMULWT_EQ:         "SMULWT.EQ",
+	SMULWT_NE:         "SMULWT.NE",
+	SMULWT_CS:         "SMULWT.CS",
+	SMULWT_CC:         "SMULWT.CC",
+	SMULWT_MI:         "SMULWT.MI",
+	SMULWT_PL:         "SMULWT.PL",
+	SMULWT_VS:         "SMULWT.VS",
+	SMULWT_VC:         "SMULWT.VC",
+	SMULWT_HI:         "SMULWT.HI",
+	SMULWT_LS:         "SMULWT.LS",
+	SMULWT_GE:         "SMULWT.GE",
+	SMULWT_LT:         "SMULWT.LT",
+	SMULWT_GT:         "SMULWT.GT",
+	SMULWT_LE:         "SMULWT.LE",
+	SMULWT:            "SMULWT",
+	SMULWT_ZZ:         "SMULWT.ZZ",
+	SMUSD_EQ:          "SMUSD.EQ",
+	SMUSD_NE:          "SMUSD.NE",
+	SMUSD_CS:          "SMUSD.CS",
+	SMUSD_CC:          "SMUSD.CC",
+	SMUSD_MI:          "SMUSD.MI",
+	SMUSD_PL:          "SMUSD.PL",
+	SMUSD_VS:          "SMUSD.VS",
+	SMUSD_VC:          "SMUSD.VC",
+	SMUSD_HI:          "SMUSD.HI",
+	SMUSD_LS:          "SMUSD.LS",
+	SMUSD_GE:          "SMUSD.GE",
+	SMUSD_LT:          "SMUSD.LT",
+	SMUSD_GT:          "SMUSD.GT",
+	SMUSD_LE:          "SMUSD.LE",
+	SMUSD:             "SMUSD",
+	SMUSD_ZZ:          "SMUSD.ZZ",
+	SMUSD_X_EQ:        "SMUSD.X.EQ",
+	SMUSD_X_NE:        "SMUSD.X.NE",
+	SMUSD_X_CS:        "SMUSD.X.CS",
+	SMUSD_X_CC:        "SMUSD.X.CC",
+	SMUSD_X_MI:        "SMUSD.X.MI",
+	SMUSD_X_PL:        "SMUSD.X.PL",
+	SMUSD_X_VS:        "SMUSD.X.VS",
+	SMUSD_X_VC:        "SMUSD.X.VC",
+	SMUSD_X_HI:        "SMUSD.X.HI",
+	SMUSD_X_LS:        "SMUSD.X.LS",
+	SMUSD_X_GE:        "SMUSD.X.GE",
+	SMUSD_X_LT:        "SMUSD.X.LT",
+	SMUSD_X_GT:        "SMUSD.X.GT",
+	SMUSD_X_LE:        "SMUSD.X.LE",
+	SMUSD_X:           "SMUSD.X",
+	SMUSD_X_ZZ:        "SMUSD.X.ZZ",
+	SSAT_EQ:           "SSAT.EQ",
+	SSAT_NE:           "SSAT.NE",
+	SSAT_CS:           "SSAT.CS",
+	SSAT_CC:           "SSAT.CC",
+	SSAT_MI:           "SSAT.MI",
+	SSAT_PL:           "SSAT.PL",
+	SSAT_VS:           "SSAT.VS",
+	SSAT_VC:           "SSAT.VC",
+	SSAT_HI:           "SSAT.HI",
+	SSAT_LS:           "SSAT.LS",
+	SSAT_GE:           "SSAT.GE",
+	SSAT_LT:           "SSAT.LT",
+	SSAT_GT:           "SSAT.GT",
+	SSAT_LE:           "SSAT.LE",
+	SSAT:              "SSAT",
+	SSAT_ZZ:           "SSAT.ZZ",
+	SSAT16_EQ:         "SSAT16.EQ",
+	SSAT16_NE:         "SSAT16.NE",
+	SSAT16_CS:         "SSAT16.CS",
+	SSAT16_CC:         "SSAT16.CC",
+	SSAT16_MI:         "SSAT16.MI",
+	SSAT16_PL:         "SSAT16.PL",
+	SSAT16_VS:         "SSAT16.VS",
+	SSAT16_VC:         "SSAT16.VC",
+	SSAT16_HI:         "SSAT16.HI",
+	SSAT16_LS:         "SSAT16.LS",
+	SSAT16_GE:         "SSAT16.GE",
+	SSAT16_LT:         "SSAT16.LT",
+	SSAT16_GT:         "SSAT16.GT",
+	SSAT16_LE:         "SSAT16.LE",
+	SSAT16:            "SSAT16",
+	SSAT16_ZZ:         "SSAT16.ZZ",
+	SSAX_EQ:           "SSAX.EQ",
+	SSAX_NE:           "SSAX.NE",
+	SSAX_CS:           "SSAX.CS",
+	SSAX_CC:           "SSAX.CC",
+	SSAX_MI:           "SSAX.MI",
+	SSAX_PL:           "SSAX.PL",
+	SSAX_VS:           "SSAX.VS",
+	SSAX_VC:           "SSAX.VC",
+	SSAX_HI:           "SSAX.HI",
+	SSAX_LS:           "SSAX.LS",
+	SSAX_GE:           "SSAX.GE",
+	SSAX_LT:           "SSAX.LT",
+	SSAX_GT:           "SSAX.GT",
+	SSAX_LE:           "SSAX.LE",
+	SSAX:              "SSAX",
+	SSAX_ZZ:           "SSAX.ZZ",
+	SSUB16_EQ:         "SSUB16.EQ",
+	SSUB16_NE:         "SSUB16.NE",
+	SSUB16_CS:         "SSUB16.CS",
+	SSUB16_CC:         "SSUB16.CC",
+	SSUB16_MI:         "SSUB16.MI",
+	SSUB16_PL:         "SSUB16.PL",
+	SSUB16_VS:         "SSUB16.VS",
+	SSUB16_VC:         "SSUB16.VC",
+	SSUB16_HI:         "SSUB16.HI",
+	SSUB16_LS:         "SSUB16.LS",
+	SSUB16_GE:         "SSUB16.GE",
+	SSUB16_LT:         "SSUB16.LT",
+	SSUB16_GT:         "SSUB16.GT",
+	SSUB16_LE:         "SSUB16.LE",
+	SSUB16:            "SSUB16",
+	SSUB16_ZZ:         "SSUB16.ZZ",
+	SSUB8_EQ:          "SSUB8.EQ",
+	SSUB8_NE:          "SSUB8.NE",
+	SSUB8_CS:          "SSUB8.CS",
+	SSUB8_CC:          "SSUB8.CC",
+	SSUB8_MI:          "SSUB8.MI",
+	SSUB8_PL:          "SSUB8.PL",
+	SSUB8_VS:          "SSUB8.VS",
+	SSUB8_VC:          "SSUB8.VC",
+	SSUB8_HI:          "SSUB8.HI",
+	SSUB8_LS:          "SSUB8.LS",
+	SSUB8_GE:          "SSUB8.GE",
+	SSUB8_LT:          "SSUB8.LT",
+	SSUB8_GT:          "SSUB8.GT",
+	SSUB8_LE:          "SSUB8.LE",
+	SSUB8:             "SSUB8",
+	SSUB8_ZZ:          "SSUB8.ZZ",
+	STM_EQ:            "STM.EQ",
+	STM_NE:            "STM.NE",
+	STM_CS:            "STM.CS",
+	STM_CC:            "STM.CC",
+	STM_MI:            "STM.MI",
+	STM_PL:            "STM.PL",
+	STM_VS:            "STM.VS",
+	STM_VC:            "STM.VC",
+	STM_HI:            "STM.HI",
+	STM_LS:            "STM.LS",
+	STM_GE:            "STM.GE",
+	STM_LT:            "STM.LT",
+	STM_GT:            "STM.GT",
+	STM_LE:            "STM.LE",
+	STM:               "STM",
+	STM_ZZ:            "STM.ZZ",
+	STMDA_EQ:          "STMDA.EQ",
+	STMDA_NE:          "STMDA.NE",
+	STMDA_CS:          "STMDA.CS",
+	STMDA_CC:          "STMDA.CC",
+	STMDA_MI:          "STMDA.MI",
+	STMDA_PL:          "STMDA.PL",
+	STMDA_VS:          "STMDA.VS",
+	STMDA_VC:          "STMDA.VC",
+	STMDA_HI:          "STMDA.HI",
+	STMDA_LS:          "STMDA.LS",
+	STMDA_GE:          "STMDA.GE",
+	STMDA_LT:          "STMDA.LT",
+	STMDA_GT:          "STMDA.GT",
+	STMDA_LE:          "STMDA.LE",
+	STMDA:             "STMDA",
+	STMDA_ZZ:          "STMDA.ZZ",
+	STMDB_EQ:          "STMDB.EQ",
+	STMDB_NE:          "STMDB.NE",
+	STMDB_CS:          "STMDB.CS",
+	STMDB_CC:          "STMDB.CC",
+	STMDB_MI:          "STMDB.MI",
+	STMDB_PL:          "STMDB.PL",
+	STMDB_VS:          "STMDB.VS",
+	STMDB_VC:          "STMDB.VC",
+	STMDB_HI:          "STMDB.HI",
+	STMDB_LS:          "STMDB.LS",
+	STMDB_GE:          "STMDB.GE",
+	STMDB_LT:          "STMDB.LT",
+	STMDB_GT:          "STMDB.GT",
+	STMDB_LE:          "STMDB.LE",
+	STMDB:             "STMDB",
+	STMDB_ZZ:          "STMDB.ZZ",
+	STMIB_EQ:          "STMIB.EQ",
+	STMIB_NE:          "STMIB.NE",
+	STMIB_CS:          "STMIB.CS",
+	STMIB_CC:          "STMIB.CC",
+	STMIB_MI:          "STMIB.MI",
+	STMIB_PL:          "STMIB.PL",
+	STMIB_VS:          "STMIB.VS",
+	STMIB_VC:          "STMIB.VC",
+	STMIB_HI:          "STMIB.HI",
+	STMIB_LS:          "STMIB.LS",
+	STMIB_GE:          "STMIB.GE",
+	STMIB_LT:          "STMIB.LT",
+	STMIB_GT:          "STMIB.GT",
+	STMIB_LE:          "STMIB.LE",
+	STMIB:             "STMIB",
+	STMIB_ZZ:          "STMIB.ZZ",
+	STR_EQ:            "STR.EQ",
+	STR_NE:            "STR.NE",
+	STR_CS:            "STR.CS",
+	STR_CC:            "STR.CC",
+	STR_MI:            "STR.MI",
+	STR_PL:            "STR.PL",
+	STR_VS:            "STR.VS",
+	STR_VC:            "STR.VC",
+	STR_HI:            "STR.HI",
+	STR_LS:            "STR.LS",
+	STR_GE:            "STR.GE",
+	STR_LT:            "STR.LT",
+	STR_GT:            "STR.GT",
+	STR_LE:            "STR.LE",
+	STR:               "STR",
+	STR_ZZ:            "STR.ZZ",
+	STRB_EQ:           "STRB.EQ",
+	STRB_NE:           "STRB.NE",
+	STRB_CS:           "STRB.CS",
+	STRB_CC:           "STRB.CC",
+	STRB_MI:           "STRB.MI",
+	STRB_PL:           "STRB.PL",
+	STRB_VS:           "STRB.VS",
+	STRB_VC:           "STRB.VC",
+	STRB_HI:           "STRB.HI",
+	STRB_LS:           "STRB.LS",
+	STRB_GE:           "STRB.GE",
+	STRB_LT:           "STRB.LT",
+	STRB_GT:           "STRB.GT",
+	STRB_LE:           "STRB.LE",
+	STRB:              "STRB",
+	STRB_ZZ:           "STRB.ZZ",
+	STRBT_EQ:          "STRBT.EQ",
+	STRBT_NE:          "STRBT.NE",
+	STRBT_CS:          "STRBT.CS",
+	STRBT_CC:          "STRBT.CC",
+	STRBT_MI:          "STRBT.MI",
+	STRBT_PL:          "STRBT.PL",
+	STRBT_VS:          "STRBT.VS",
+	STRBT_VC:          "STRBT.VC",
+	STRBT_HI:          "STRBT.HI",
+	STRBT_LS:          "STRBT.LS",
+	STRBT_GE:          "STRBT.GE",
+	STRBT_LT:          "STRBT.LT",
+	STRBT_GT:          "STRBT.GT",
+	STRBT_LE:          "STRBT.LE",
+	STRBT:             "STRBT",
+	STRBT_ZZ:          "STRBT.ZZ",
+	STRD_EQ:           "STRD.EQ",
+	STRD_NE:           "STRD.NE",
+	STRD_CS:           "STRD.CS",
+	STRD_CC:           "STRD.CC",
+	STRD_MI:           "STRD.MI",
+	STRD_PL:           "STRD.PL",
+	STRD_VS:           "STRD.VS",
+	STRD_VC:           "STRD.VC",
+	STRD_HI:           "STRD.HI",
+	STRD_LS:           "STRD.LS",
+	STRD_GE:           "STRD.GE",
+	STRD_LT:           "STRD.LT",
+	STRD_GT:           "STRD.GT",
+	STRD_LE:           "STRD.LE",
+	STRD:              "STRD",
+	STRD_ZZ:           "STRD.ZZ",
+	STREX_EQ:          "STREX.EQ",
+	STREX_NE:          "STREX.NE",
+	STREX_CS:          "STREX.CS",
+	STREX_CC:          "STREX.CC",
+	STREX_MI:          "STREX.MI",
+	STREX_PL:          "STREX.PL",
+	STREX_VS:          "STREX.VS",
+	STREX_VC:          "STREX.VC",
+	STREX_HI:          "STREX.HI",
+	STREX_LS:          "STREX.LS",
+	STREX_GE:          "STREX.GE",
+	STREX_LT:          "STREX.LT",
+	STREX_GT:          "STREX.GT",
+	STREX_LE:          "STREX.LE",
+	STREX:             "STREX",
+	STREX_ZZ:          "STREX.ZZ",
+	STREXB_EQ:         "STREXB.EQ",
+	STREXB_NE:         "STREXB.NE",
+	STREXB_CS:         "STREXB.CS",
+	STREXB_CC:         "STREXB.CC",
+	STREXB_MI:         "STREXB.MI",
+	STREXB_PL:         "STREXB.PL",
+	STREXB_VS:         "STREXB.VS",
+	STREXB_VC:         "STREXB.VC",
+	STREXB_HI:         "STREXB.HI",
+	STREXB_LS:         "STREXB.LS",
+	STREXB_GE:         "STREXB.GE",
+	STREXB_LT:         "STREXB.LT",
+	STREXB_GT:         "STREXB.GT",
+	STREXB_LE:         "STREXB.LE",
+	STREXB:            "STREXB",
+	STREXB_ZZ:         "STREXB.ZZ",
+	STREXD_EQ:         "STREXD.EQ",
+	STREXD_NE:         "STREXD.NE",
+	STREXD_CS:         "STREXD.CS",
+	STREXD_CC:         "STREXD.CC",
+	STREXD_MI:         "STREXD.MI",
+	STREXD_PL:         "STREXD.PL",
+	STREXD_VS:         "STREXD.VS",
+	STREXD_VC:         "STREXD.VC",
+	STREXD_HI:         "STREXD.HI",
+	STREXD_LS:         "STREXD.LS",
+	STREXD_GE:         "STREXD.GE",
+	STREXD_LT:         "STREXD.LT",
+	STREXD_GT:         "STREXD.GT",
+	STREXD_LE:         "STREXD.LE",
+	STREXD:            "STREXD",
+	STREXD_ZZ:         "STREXD.ZZ",
+	STREXH_EQ:         "STREXH.EQ",
+	STREXH_NE:         "STREXH.NE",
+	STREXH_CS:         "STREXH.CS",
+	STREXH_CC:         "STREXH.CC",
+	STREXH_MI:         "STREXH.MI",
+	STREXH_PL:         "STREXH.PL",
+	STREXH_VS:         "STREXH.VS",
+	STREXH_VC:         "STREXH.VC",
+	STREXH_HI:         "STREXH.HI",
+	STREXH_LS:         "STREXH.LS",
+	STREXH_GE:         "STREXH.GE",
+	STREXH_LT:         "STREXH.LT",
+	STREXH_GT:         "STREXH.GT",
+	STREXH_LE:         "STREXH.LE",
+	STREXH:            "STREXH",
+	STREXH_ZZ:         "STREXH.ZZ",
+	STRH_EQ:           "STRH.EQ",
+	STRH_NE:           "STRH.NE",
+	STRH_CS:           "STRH.CS",
+	STRH_CC:           "STRH.CC",
+	STRH_MI:           "STRH.MI",
+	STRH_PL:           "STRH.PL",
+	STRH_VS:           "STRH.VS",
+	STRH_VC:           "STRH.VC",
+	STRH_HI:           "STRH.HI",
+	STRH_LS:           "STRH.LS",
+	STRH_GE:           "STRH.GE",
+	STRH_LT:           "STRH.LT",
+	STRH_GT:           "STRH.GT",
+	STRH_LE:           "STRH.LE",
+	STRH:              "STRH",
+	STRH_ZZ:           "STRH.ZZ",
+	STRHT_EQ:          "STRHT.EQ",
+	STRHT_NE:          "STRHT.NE",
+	STRHT_CS:          "STRHT.CS",
+	STRHT_CC:          "STRHT.CC",
+	STRHT_MI:          "STRHT.MI",
+	STRHT_PL:          "STRHT.PL",
+	STRHT_VS:          "STRHT.VS",
+	STRHT_VC:          "STRHT.VC",
+	STRHT_HI:          "STRHT.HI",
+	STRHT_LS:          "STRHT.LS",
+	STRHT_GE:          "STRHT.GE",
+	STRHT_LT:          "STRHT.LT",
+	STRHT_GT:          "STRHT.GT",
+	STRHT_LE:          "STRHT.LE",
+	STRHT:             "STRHT",
+	STRHT_ZZ:          "STRHT.ZZ",
+	STRT_EQ:           "STRT.EQ",
+	STRT_NE:           "STRT.NE",
+	STRT_CS:           "STRT.CS",
+	STRT_CC:           "STRT.CC",
+	STRT_MI:           "STRT.MI",
+	STRT_PL:           "STRT.PL",
+	STRT_VS:           "STRT.VS",
+	STRT_VC:           "STRT.VC",
+	STRT_HI:           "STRT.HI",
+	STRT_LS:           "STRT.LS",
+	STRT_GE:           "STRT.GE",
+	STRT_LT:           "STRT.LT",
+	STRT_GT:           "STRT.GT",
+	STRT_LE:           "STRT.LE",
+	STRT:              "STRT",
+	STRT_ZZ:           "STRT.ZZ",
+	SUB_EQ:            "SUB.EQ",
+	SUB_NE:            "SUB.NE",
+	SUB_CS:            "SUB.CS",
+	SUB_CC:            "SUB.CC",
+	SUB_MI:            "SUB.MI",
+	SUB_PL:            "SUB.PL",
+	SUB_VS:            "SUB.VS",
+	SUB_VC:            "SUB.VC",
+	SUB_HI:            "SUB.HI",
+	SUB_LS:            "SUB.LS",
+	SUB_GE:            "SUB.GE",
+	SUB_LT:            "SUB.LT",
+	SUB_GT:            "SUB.GT",
+	SUB_LE:            "SUB.LE",
+	SUB:               "SUB",
+	SUB_ZZ:            "SUB.ZZ",
+	SUB_S_EQ:          "SUB.S.EQ",
+	SUB_S_NE:          "SUB.S.NE",
+	SUB_S_CS:          "SUB.S.CS",
+	SUB_S_CC:          "SUB.S.CC",
+	SUB_S_MI:          "SUB.S.MI",
+	SUB_S_PL:          "SUB.S.PL",
+	SUB_S_VS:          "SUB.S.VS",
+	SUB_S_VC:          "SUB.S.VC",
+	SUB_S_HI:          "SUB.S.HI",
+	SUB_S_LS:          "SUB.S.LS",
+	SUB_S_GE:          "SUB.S.GE",
+	SUB_S_LT:          "SUB.S.LT",
+	SUB_S_GT:          "SUB.S.GT",
+	SUB_S_LE:          "SUB.S.LE",
+	SUB_S:             "SUB.S",
+	SUB_S_ZZ:          "SUB.S.ZZ",
+	SVC_EQ:            "SVC.EQ",
+	SVC_NE:            "SVC.NE",
+	SVC_CS:            "SVC.CS",
+	SVC_CC:            "SVC.CC",
+	SVC_MI:            "SVC.MI",
+	SVC_PL:            "SVC.PL",
+	SVC_VS:            "SVC.VS",
+	SVC_VC:            "SVC.VC",
+	SVC_HI:            "SVC.HI",
+	SVC_LS:            "SVC.LS",
+	SVC_GE:            "SVC.GE",
+	SVC_LT:            "SVC.LT",
+	SVC_GT:            "SVC.GT",
+	SVC_LE:            "SVC.LE",
+	SVC:               "SVC",
+	SVC_ZZ:            "SVC.ZZ",
+	SWP_EQ:            "SWP.EQ",
+	SWP_NE:            "SWP.NE",
+	SWP_CS:            "SWP.CS",
+	SWP_CC:            "SWP.CC",
+	SWP_MI:            "SWP.MI",
+	SWP_PL:            "SWP.PL",
+	SWP_VS:            "SWP.VS",
+	SWP_VC:            "SWP.VC",
+	SWP_HI:            "SWP.HI",
+	SWP_LS:            "SWP.LS",
+	SWP_GE:            "SWP.GE",
+	SWP_LT:            "SWP.LT",
+	SWP_GT:            "SWP.GT",
+	SWP_LE:            "SWP.LE",
+	SWP:               "SWP",
+	SWP_ZZ:            "SWP.ZZ",
+	SWP_B_EQ:          "SWP.B.EQ",
+	SWP_B_NE:          "SWP.B.NE",
+	SWP_B_CS:          "SWP.B.CS",
+	SWP_B_CC:          "SWP.B.CC",
+	SWP_B_MI:          "SWP.B.MI",
+	SWP_B_PL:          "SWP.B.PL",
+	SWP_B_VS:          "SWP.B.VS",
+	SWP_B_VC:          "SWP.B.VC",
+	SWP_B_HI:          "SWP.B.HI",
+	SWP_B_LS:          "SWP.B.LS",
+	SWP_B_GE:          "SWP.B.GE",
+	SWP_B_LT:          "SWP.B.LT",
+	SWP_B_GT:          "SWP.B.GT",
+	SWP_B_LE:          "SWP.B.LE",
+	SWP_B:             "SWP.B",
+	SWP_B_ZZ:          "SWP.B.ZZ",
+	SXTAB_EQ:          "SXTAB.EQ",
+	SXTAB_NE:          "SXTAB.NE",
+	SXTAB_CS:          "SXTAB.CS",
+	SXTAB_CC:          "SXTAB.CC",
+	SXTAB_MI:          "SXTAB.MI",
+	SXTAB_PL:          "SXTAB.PL",
+	SXTAB_VS:          "SXTAB.VS",
+	SXTAB_VC:          "SXTAB.VC",
+	SXTAB_HI:          "SXTAB.HI",
+	SXTAB_LS:          "SXTAB.LS",
+	SXTAB_GE:          "SXTAB.GE",
+	SXTAB_LT:          "SXTAB.LT",
+	SXTAB_GT:          "SXTAB.GT",
+	SXTAB_LE:          "SXTAB.LE",
+	SXTAB:             "SXTAB",
+	SXTAB_ZZ:          "SXTAB.ZZ",
+	SXTAB16_EQ:        "SXTAB16.EQ",
+	SXTAB16_NE:        "SXTAB16.NE",
+	SXTAB16_CS:        "SXTAB16.CS",
+	SXTAB16_CC:        "SXTAB16.CC",
+	SXTAB16_MI:        "SXTAB16.MI",
+	SXTAB16_PL:        "SXTAB16.PL",
+	SXTAB16_VS:        "SXTAB16.VS",
+	SXTAB16_VC:        "SXTAB16.VC",
+	SXTAB16_HI:        "SXTAB16.HI",
+	SXTAB16_LS:        "SXTAB16.LS",
+	SXTAB16_GE:        "SXTAB16.GE",
+	SXTAB16_LT:        "SXTAB16.LT",
+	SXTAB16_GT:        "SXTAB16.GT",
+	SXTAB16_LE:        "SXTAB16.LE",
+	SXTAB16:           "SXTAB16",
+	SXTAB16_ZZ:        "SXTAB16.ZZ",
+	SXTAH_EQ:          "SXTAH.EQ",
+	SXTAH_NE:          "SXTAH.NE",
+	SXTAH_CS:          "SXTAH.CS",
+	SXTAH_CC:          "SXTAH.CC",
+	SXTAH_MI:          "SXTAH.MI",
+	SXTAH_PL:          "SXTAH.PL",
+	SXTAH_VS:          "SXTAH.VS",
+	SXTAH_VC:          "SXTAH.VC",
+	SXTAH_HI:          "SXTAH.HI",
+	SXTAH_LS:          "SXTAH.LS",
+	SXTAH_GE:          "SXTAH.GE",
+	SXTAH_LT:          "SXTAH.LT",
+	SXTAH_GT:          "SXTAH.GT",
+	SXTAH_LE:          "SXTAH.LE",
+	SXTAH:             "SXTAH",
+	SXTAH_ZZ:          "SXTAH.ZZ",
+	SXTB_EQ:           "SXTB.EQ",
+	SXTB_NE:           "SXTB.NE",
+	SXTB_CS:           "SXTB.CS",
+	SXTB_CC:           "SXTB.CC",
+	SXTB_MI:           "SXTB.MI",
+	SXTB_PL:           "SXTB.PL",
+	SXTB_VS:           "SXTB.VS",
+	SXTB_VC:           "SXTB.VC",
+	SXTB_HI:           "SXTB.HI",
+	SXTB_LS:           "SXTB.LS",
+	SXTB_GE:           "SXTB.GE",
+	SXTB_LT:           "SXTB.LT",
+	SXTB_GT:           "SXTB.GT",
+	SXTB_LE:           "SXTB.LE",
+	SXTB:              "SXTB",
+	SXTB_ZZ:           "SXTB.ZZ",
+	SXTB16_EQ:         "SXTB16.EQ",
+	SXTB16_NE:         "SXTB16.NE",
+	SXTB16_CS:         "SXTB16.CS",
+	SXTB16_CC:         "SXTB16.CC",
+	SXTB16_MI:         "SXTB16.MI",
+	SXTB16_PL:         "SXTB16.PL",
+	SXTB16_VS:         "SXTB16.VS",
+	SXTB16_VC:         "SXTB16.VC",
+	SXTB16_HI:         "SXTB16.HI",
+	SXTB16_LS:         "SXTB16.LS",
+	SXTB16_GE:         "SXTB16.GE",
+	SXTB16_LT:         "SXTB16.LT",
+	SXTB16_GT:         "SXTB16.GT",
+	SXTB16_LE:         "SXTB16.LE",
+	SXTB16:            "SXTB16",
+	SXTB16_ZZ:         "SXTB16.ZZ",
+	SXTH_EQ:           "SXTH.EQ",
+	SXTH_NE:           "SXTH.NE",
+	SXTH_CS:           "SXTH.CS",
+	SXTH_CC:           "SXTH.CC",
+	SXTH_MI:           "SXTH.MI",
+	SXTH_PL:           "SXTH.PL",
+	SXTH_VS:           "SXTH.VS",
+	SXTH_VC:           "SXTH.VC",
+	SXTH_HI:           "SXTH.HI",
+	SXTH_LS:           "SXTH.LS",
+	SXTH_GE:           "SXTH.GE",
+	SXTH_LT:           "SXTH.LT",
+	SXTH_GT:           "SXTH.GT",
+	SXTH_LE:           "SXTH.LE",
+	SXTH:              "SXTH",
+	SXTH_ZZ:           "SXTH.ZZ",
+	TEQ_EQ:            "TEQ.EQ",
+	TEQ_NE:            "TEQ.NE",
+	TEQ_CS:            "TEQ.CS",
+	TEQ_CC:            "TEQ.CC",
+	TEQ_MI:            "TEQ.MI",
+	TEQ_PL:            "TEQ.PL",
+	TEQ_VS:            "TEQ.VS",
+	TEQ_VC:            "TEQ.VC",
+	TEQ_HI:            "TEQ.HI",
+	TEQ_LS:            "TEQ.LS",
+	TEQ_GE:            "TEQ.GE",
+	TEQ_LT:            "TEQ.LT",
+	TEQ_GT:            "TEQ.GT",
+	TEQ_LE:            "TEQ.LE",
+	TEQ:               "TEQ",
+	TEQ_ZZ:            "TEQ.ZZ",
+	TST_EQ:            "TST.EQ",
+	TST_NE:            "TST.NE",
+	TST_CS:            "TST.CS",
+	TST_CC:            "TST.CC",
+	TST_MI:            "TST.MI",
+	TST_PL:            "TST.PL",
+	TST_VS:            "TST.VS",
+	TST_VC:            "TST.VC",
+	TST_HI:            "TST.HI",
+	TST_LS:            "TST.LS",
+	TST_GE:            "TST.GE",
+	TST_LT:            "TST.LT",
+	TST_GT:            "TST.GT",
+	TST_LE:            "TST.LE",
+	TST:               "TST",
+	TST_ZZ:            "TST.ZZ",
+	UADD16_EQ:         "UADD16.EQ",
+	UADD16_NE:         "UADD16.NE",
+	UADD16_CS:         "UADD16.CS",
+	UADD16_CC:         "UADD16.CC",
+	UADD16_MI:         "UADD16.MI",
+	UADD16_PL:         "UADD16.PL",
+	UADD16_VS:         "UADD16.VS",
+	UADD16_VC:         "UADD16.VC",
+	UADD16_HI:         "UADD16.HI",
+	UADD16_LS:         "UADD16.LS",
+	UADD16_GE:         "UADD16.GE",
+	UADD16_LT:         "UADD16.LT",
+	UADD16_GT:         "UADD16.GT",
+	UADD16_LE:         "UADD16.LE",
+	UADD16:            "UADD16",
+	UADD16_ZZ:         "UADD16.ZZ",
+	UADD8_EQ:          "UADD8.EQ",
+	UADD8_NE:          "UADD8.NE",
+	UADD8_CS:          "UADD8.CS",
+	UADD8_CC:          "UADD8.CC",
+	UADD8_MI:          "UADD8.MI",
+	UADD8_PL:          "UADD8.PL",
+	UADD8_VS:          "UADD8.VS",
+	UADD8_VC:          "UADD8.VC",
+	UADD8_HI:          "UADD8.HI",
+	UADD8_LS:          "UADD8.LS",
+	UADD8_GE:          "UADD8.GE",
+	UADD8_LT:          "UADD8.LT",
+	UADD8_GT:          "UADD8.GT",
+	UADD8_LE:          "UADD8.LE",
+	UADD8:             "UADD8",
+	UADD8_ZZ:          "UADD8.ZZ",
+	UASX_EQ:           "UASX.EQ",
+	UASX_NE:           "UASX.NE",
+	UASX_CS:           "UASX.CS",
+	UASX_CC:           "UASX.CC",
+	UASX_MI:           "UASX.MI",
+	UASX_PL:           "UASX.PL",
+	UASX_VS:           "UASX.VS",
+	UASX_VC:           "UASX.VC",
+	UASX_HI:           "UASX.HI",
+	UASX_LS:           "UASX.LS",
+	UASX_GE:           "UASX.GE",
+	UASX_LT:           "UASX.LT",
+	UASX_GT:           "UASX.GT",
+	UASX_LE:           "UASX.LE",
+	UASX:              "UASX",
+	UASX_ZZ:           "UASX.ZZ",
+	UBFX_EQ:           "UBFX.EQ",
+	UBFX_NE:           "UBFX.NE",
+	UBFX_CS:           "UBFX.CS",
+	UBFX_CC:           "UBFX.CC",
+	UBFX_MI:           "UBFX.MI",
+	UBFX_PL:           "UBFX.PL",
+	UBFX_VS:           "UBFX.VS",
+	UBFX_VC:           "UBFX.VC",
+	UBFX_HI:           "UBFX.HI",
+	UBFX_LS:           "UBFX.LS",
+	UBFX_GE:           "UBFX.GE",
+	UBFX_LT:           "UBFX.LT",
+	UBFX_GT:           "UBFX.GT",
+	UBFX_LE:           "UBFX.LE",
+	UBFX:              "UBFX",
+	UBFX_ZZ:           "UBFX.ZZ",
+	UHADD16_EQ:        "UHADD16.EQ",
+	UHADD16_NE:        "UHADD16.NE",
+	UHADD16_CS:        "UHADD16.CS",
+	UHADD16_CC:        "UHADD16.CC",
+	UHADD16_MI:        "UHADD16.MI",
+	UHADD16_PL:        "UHADD16.PL",
+	UHADD16_VS:        "UHADD16.VS",
+	UHADD16_VC:        "UHADD16.VC",
+	UHADD16_HI:        "UHADD16.HI",
+	UHADD16_LS:        "UHADD16.LS",
+	UHADD16_GE:        "UHADD16.GE",
+	UHADD16_LT:        "UHADD16.LT",
+	UHADD16_GT:        "UHADD16.GT",
+	UHADD16_LE:        "UHADD16.LE",
+	UHADD16:           "UHADD16",
+	UHADD16_ZZ:        "UHADD16.ZZ",
+	UHADD8_EQ:         "UHADD8.EQ",
+	UHADD8_NE:         "UHADD8.NE",
+	UHADD8_CS:         "UHADD8.CS",
+	UHADD8_CC:         "UHADD8.CC",
+	UHADD8_MI:         "UHADD8.MI",
+	UHADD8_PL:         "UHADD8.PL",
+	UHADD8_VS:         "UHADD8.VS",
+	UHADD8_VC:         "UHADD8.VC",
+	UHADD8_HI:         "UHADD8.HI",
+	UHADD8_LS:         "UHADD8.LS",
+	UHADD8_GE:         "UHADD8.GE",
+	UHADD8_LT:         "UHADD8.LT",
+	UHADD8_GT:         "UHADD8.GT",
+	UHADD8_LE:         "UHADD8.LE",
+	UHADD8:            "UHADD8",
+	UHADD8_ZZ:         "UHADD8.ZZ",
+	UHASX_EQ:          "UHASX.EQ",
+	UHASX_NE:          "UHASX.NE",
+	UHASX_CS:          "UHASX.CS",
+	UHASX_CC:          "UHASX.CC",
+	UHASX_MI:          "UHASX.MI",
+	UHASX_PL:          "UHASX.PL",
+	UHASX_VS:          "UHASX.VS",
+	UHASX_VC:          "UHASX.VC",
+	UHASX_HI:          "UHASX.HI",
+	UHASX_LS:          "UHASX.LS",
+	UHASX_GE:          "UHASX.GE",
+	UHASX_LT:          "UHASX.LT",
+	UHASX_GT:          "UHASX.GT",
+	UHASX_LE:          "UHASX.LE",
+	UHASX:             "UHASX",
+	UHASX_ZZ:          "UHASX.ZZ",
+	UHSAX_EQ:          "UHSAX.EQ",
+	UHSAX_NE:          "UHSAX.NE",
+	UHSAX_CS:          "UHSAX.CS",
+	UHSAX_CC:          "UHSAX.CC",
+	UHSAX_MI:          "UHSAX.MI",
+	UHSAX_PL:          "UHSAX.PL",
+	UHSAX_VS:          "UHSAX.VS",
+	UHSAX_VC:          "UHSAX.VC",
+	UHSAX_HI:          "UHSAX.HI",
+	UHSAX_LS:          "UHSAX.LS",
+	UHSAX_GE:          "UHSAX.GE",
+	UHSAX_LT:          "UHSAX.LT",
+	UHSAX_GT:          "UHSAX.GT",
+	UHSAX_LE:          "UHSAX.LE",
+	UHSAX:             "UHSAX",
+	UHSAX_ZZ:          "UHSAX.ZZ",
+	UHSUB16_EQ:        "UHSUB16.EQ",
+	UHSUB16_NE:        "UHSUB16.NE",
+	UHSUB16_CS:        "UHSUB16.CS",
+	UHSUB16_CC:        "UHSUB16.CC",
+	UHSUB16_MI:        "UHSUB16.MI",
+	UHSUB16_PL:        "UHSUB16.PL",
+	UHSUB16_VS:        "UHSUB16.VS",
+	UHSUB16_VC:        "UHSUB16.VC",
+	UHSUB16_HI:        "UHSUB16.HI",
+	UHSUB16_LS:        "UHSUB16.LS",
+	UHSUB16_GE:        "UHSUB16.GE",
+	UHSUB16_LT:        "UHSUB16.LT",
+	UHSUB16_GT:        "UHSUB16.GT",
+	UHSUB16_LE:        "UHSUB16.LE",
+	UHSUB16:           "UHSUB16",
+	UHSUB16_ZZ:        "UHSUB16.ZZ",
+	UHSUB8_EQ:         "UHSUB8.EQ",
+	UHSUB8_NE:         "UHSUB8.NE",
+	UHSUB8_CS:         "UHSUB8.CS",
+	UHSUB8_CC:         "UHSUB8.CC",
+	UHSUB8_MI:         "UHSUB8.MI",
+	UHSUB8_PL:         "UHSUB8.PL",
+	UHSUB8_VS:         "UHSUB8.VS",
+	UHSUB8_VC:         "UHSUB8.VC",
+	UHSUB8_HI:         "UHSUB8.HI",
+	UHSUB8_LS:         "UHSUB8.LS",
+	UHSUB8_GE:         "UHSUB8.GE",
+	UHSUB8_LT:         "UHSUB8.LT",
+	UHSUB8_GT:         "UHSUB8.GT",
+	UHSUB8_LE:         "UHSUB8.LE",
+	UHSUB8:            "UHSUB8",
+	UHSUB8_ZZ:         "UHSUB8.ZZ",
+	UMAAL_EQ:          "UMAAL.EQ",
+	UMAAL_NE:          "UMAAL.NE",
+	UMAAL_CS:          "UMAAL.CS",
+	UMAAL_CC:          "UMAAL.CC",
+	UMAAL_MI:          "UMAAL.MI",
+	UMAAL_PL:          "UMAAL.PL",
+	UMAAL_VS:          "UMAAL.VS",
+	UMAAL_VC:          "UMAAL.VC",
+	UMAAL_HI:          "UMAAL.HI",
+	UMAAL_LS:          "UMAAL.LS",
+	UMAAL_GE:          "UMAAL.GE",
+	UMAAL_LT:          "UMAAL.LT",
+	UMAAL_GT:          "UMAAL.GT",
+	UMAAL_LE:          "UMAAL.LE",
+	UMAAL:             "UMAAL",
+	UMAAL_ZZ:          "UMAAL.ZZ",
+	UMLAL_EQ:          "UMLAL.EQ",
+	UMLAL_NE:          "UMLAL.NE",
+	UMLAL_CS:          "UMLAL.CS",
+	UMLAL_CC:          "UMLAL.CC",
+	UMLAL_MI:          "UMLAL.MI",
+	UMLAL_PL:          "UMLAL.PL",
+	UMLAL_VS:          "UMLAL.VS",
+	UMLAL_VC:          "UMLAL.VC",
+	UMLAL_HI:          "UMLAL.HI",
+	UMLAL_LS:          "UMLAL.LS",
+	UMLAL_GE:          "UMLAL.GE",
+	UMLAL_LT:          "UMLAL.LT",
+	UMLAL_GT:          "UMLAL.GT",
+	UMLAL_LE:          "UMLAL.LE",
+	UMLAL:             "UMLAL",
+	UMLAL_ZZ:          "UMLAL.ZZ",
+	UMLAL_S_EQ:        "UMLAL.S.EQ",
+	UMLAL_S_NE:        "UMLAL.S.NE",
+	UMLAL_S_CS:        "UMLAL.S.CS",
+	UMLAL_S_CC:        "UMLAL.S.CC",
+	UMLAL_S_MI:        "UMLAL.S.MI",
+	UMLAL_S_PL:        "UMLAL.S.PL",
+	UMLAL_S_VS:        "UMLAL.S.VS",
+	UMLAL_S_VC:        "UMLAL.S.VC",
+	UMLAL_S_HI:        "UMLAL.S.HI",
+	UMLAL_S_LS:        "UMLAL.S.LS",
+	UMLAL_S_GE:        "UMLAL.S.GE",
+	UMLAL_S_LT:        "UMLAL.S.LT",
+	UMLAL_S_GT:        "UMLAL.S.GT",
+	UMLAL_S_LE:        "UMLAL.S.LE",
+	UMLAL_S:           "UMLAL.S",
+	UMLAL_S_ZZ:        "UMLAL.S.ZZ",
+	UMULL_EQ:          "UMULL.EQ",
+	UMULL_NE:          "UMULL.NE",
+	UMULL_CS:          "UMULL.CS",
+	UMULL_CC:          "UMULL.CC",
+	UMULL_MI:          "UMULL.MI",
+	UMULL_PL:          "UMULL.PL",
+	UMULL_VS:          "UMULL.VS",
+	UMULL_VC:          "UMULL.VC",
+	UMULL_HI:          "UMULL.HI",
+	UMULL_LS:          "UMULL.LS",
+	UMULL_GE:          "UMULL.GE",
+	UMULL_LT:          "UMULL.LT",
+	UMULL_GT:          "UMULL.GT",
+	UMULL_LE:          "UMULL.LE",
+	UMULL:             "UMULL",
+	UMULL_ZZ:          "UMULL.ZZ",
+	UMULL_S_EQ:        "UMULL.S.EQ",
+	UMULL_S_NE:        "UMULL.S.NE",
+	UMULL_S_CS:        "UMULL.S.CS",
+	UMULL_S_CC:        "UMULL.S.CC",
+	UMULL_S_MI:        "UMULL.S.MI",
+	UMULL_S_PL:        "UMULL.S.PL",
+	UMULL_S_VS:        "UMULL.S.VS",
+	UMULL_S_VC:        "UMULL.S.VC",
+	UMULL_S_HI:        "UMULL.S.HI",
+	UMULL_S_LS:        "UMULL.S.LS",
+	UMULL_S_GE:        "UMULL.S.GE",
+	UMULL_S_LT:        "UMULL.S.LT",
+	UMULL_S_GT:        "UMULL.S.GT",
+	UMULL_S_LE:        "UMULL.S.LE",
+	UMULL_S:           "UMULL.S",
+	UMULL_S_ZZ:        "UMULL.S.ZZ",
+	UNDEF:             "UNDEF",
+	UQADD16_EQ:        "UQADD16.EQ",
+	UQADD16_NE:        "UQADD16.NE",
+	UQADD16_CS:        "UQADD16.CS",
+	UQADD16_CC:        "UQADD16.CC",
+	UQADD16_MI:        "UQADD16.MI",
+	UQADD16_PL:        "UQADD16.PL",
+	UQADD16_VS:        "UQADD16.VS",
+	UQADD16_VC:        "UQADD16.VC",
+	UQADD16_HI:        "UQADD16.HI",
+	UQADD16_LS:        "UQADD16.LS",
+	UQADD16_GE:        "UQADD16.GE",
+	UQADD16_LT:        "UQADD16.LT",
+	UQADD16_GT:        "UQADD16.GT",
+	UQADD16_LE:        "UQADD16.LE",
+	UQADD16:           "UQADD16",
+	UQADD16_ZZ:        "UQADD16.ZZ",
+	UQADD8_EQ:         "UQADD8.EQ",
+	UQADD8_NE:         "UQADD8.NE",
+	UQADD8_CS:         "UQADD8.CS",
+	UQADD8_CC:         "UQADD8.CC",
+	UQADD8_MI:         "UQADD8.MI",
+	UQADD8_PL:         "UQADD8.PL",
+	UQADD8_VS:         "UQADD8.VS",
+	UQADD8_VC:         "UQADD8.VC",
+	UQADD8_HI:         "UQADD8.HI",
+	UQADD8_LS:         "UQADD8.LS",
+	UQADD8_GE:         "UQADD8.GE",
+	UQADD8_LT:         "UQADD8.LT",
+	UQADD8_GT:         "UQADD8.GT",
+	UQADD8_LE:         "UQADD8.LE",
+	UQADD8:            "UQADD8",
+	UQADD8_ZZ:         "UQADD8.ZZ",
+	UQASX_EQ:          "UQASX.EQ",
+	UQASX_NE:          "UQASX.NE",
+	UQASX_CS:          "UQASX.CS",
+	UQASX_CC:          "UQASX.CC",
+	UQASX_MI:          "UQASX.MI",
+	UQASX_PL:          "UQASX.PL",
+	UQASX_VS:          "UQASX.VS",
+	UQASX_VC:          "UQASX.VC",
+	UQASX_HI:          "UQASX.HI",
+	UQASX_LS:          "UQASX.LS",
+	UQASX_GE:          "UQASX.GE",
+	UQASX_LT:          "UQASX.LT",
+	UQASX_GT:          "UQASX.GT",
+	UQASX_LE:          "UQASX.LE",
+	UQASX:             "UQASX",
+	UQASX_ZZ:          "UQASX.ZZ",
+	UQSAX_EQ:          "UQSAX.EQ",
+	UQSAX_NE:          "UQSAX.NE",
+	UQSAX_CS:          "UQSAX.CS",
+	UQSAX_CC:          "UQSAX.CC",
+	UQSAX_MI:          "UQSAX.MI",
+	UQSAX_PL:          "UQSAX.PL",
+	UQSAX_VS:          "UQSAX.VS",
+	UQSAX_VC:          "UQSAX.VC",
+	UQSAX_HI:          "UQSAX.HI",
+	UQSAX_LS:          "UQSAX.LS",
+	UQSAX_GE:          "UQSAX.GE",
+	UQSAX_LT:          "UQSAX.LT",
+	UQSAX_GT:          "UQSAX.GT",
+	UQSAX_LE:          "UQSAX.LE",
+	UQSAX:             "UQSAX",
+	UQSAX_ZZ:          "UQSAX.ZZ",
+	UQSUB16_EQ:        "UQSUB16.EQ",
+	UQSUB16_NE:        "UQSUB16.NE",
+	UQSUB16_CS:        "UQSUB16.CS",
+	UQSUB16_CC:        "UQSUB16.CC",
+	UQSUB16_MI:        "UQSUB16.MI",
+	UQSUB16_PL:        "UQSUB16.PL",
+	UQSUB16_VS:        "UQSUB16.VS",
+	UQSUB16_VC:        "UQSUB16.VC",
+	UQSUB16_HI:        "UQSUB16.HI",
+	UQSUB16_LS:        "UQSUB16.LS",
+	UQSUB16_GE:        "UQSUB16.GE",
+	UQSUB16_LT:        "UQSUB16.LT",
+	UQSUB16_GT:        "UQSUB16.GT",
+	UQSUB16_LE:        "UQSUB16.LE",
+	UQSUB16:           "UQSUB16",
+	UQSUB16_ZZ:        "UQSUB16.ZZ",
+	UQSUB8_EQ:         "UQSUB8.EQ",
+	UQSUB8_NE:         "UQSUB8.NE",
+	UQSUB8_CS:         "UQSUB8.CS",
+	UQSUB8_CC:         "UQSUB8.CC",
+	UQSUB8_MI:         "UQSUB8.MI",
+	UQSUB8_PL:         "UQSUB8.PL",
+	UQSUB8_VS:         "UQSUB8.VS",
+	UQSUB8_VC:         "UQSUB8.VC",
+	UQSUB8_HI:         "UQSUB8.HI",
+	UQSUB8_LS:         "UQSUB8.LS",
+	UQSUB8_GE:         "UQSUB8.GE",
+	UQSUB8_LT:         "UQSUB8.LT",
+	UQSUB8_GT:         "UQSUB8.GT",
+	UQSUB8_LE:         "UQSUB8.LE",
+	UQSUB8:            "UQSUB8",
+	UQSUB8_ZZ:         "UQSUB8.ZZ",
+	USAD8_EQ:          "USAD8.EQ",
+	USAD8_NE:          "USAD8.NE",
+	USAD8_CS:          "USAD8.CS",
+	USAD8_CC:          "USAD8.CC",
+	USAD8_MI:          "USAD8.MI",
+	USAD8_PL:          "USAD8.PL",
+	USAD8_VS:          "USAD8.VS",
+	USAD8_VC:          "USAD8.VC",
+	USAD8_HI:          "USAD8.HI",
+	USAD8_LS:          "USAD8.LS",
+	USAD8_GE:          "USAD8.GE",
+	USAD8_LT:          "USAD8.LT",
+	USAD8_GT:          "USAD8.GT",
+	USAD8_LE:          "USAD8.LE",
+	USAD8:             "USAD8",
+	USAD8_ZZ:          "USAD8.ZZ",
+	USADA8_EQ:         "USADA8.EQ",
+	USADA8_NE:         "USADA8.NE",
+	USADA8_CS:         "USADA8.CS",
+	USADA8_CC:         "USADA8.CC",
+	USADA8_MI:         "USADA8.MI",
+	USADA8_PL:         "USADA8.PL",
+	USADA8_VS:         "USADA8.VS",
+	USADA8_VC:         "USADA8.VC",
+	USADA8_HI:         "USADA8.HI",
+	USADA8_LS:         "USADA8.LS",
+	USADA8_GE:         "USADA8.GE",
+	USADA8_LT:         "USADA8.LT",
+	USADA8_GT:         "USADA8.GT",
+	USADA8_LE:         "USADA8.LE",
+	USADA8:            "USADA8",
+	USADA8_ZZ:         "USADA8.ZZ",
+	USAT_EQ:           "USAT.EQ",
+	USAT_NE:           "USAT.NE",
+	USAT_CS:           "USAT.CS",
+	USAT_CC:           "USAT.CC",
+	USAT_MI:           "USAT.MI",
+	USAT_PL:           "USAT.PL",
+	USAT_VS:           "USAT.VS",
+	USAT_VC:           "USAT.VC",
+	USAT_HI:           "USAT.HI",
+	USAT_LS:           "USAT.LS",
+	USAT_GE:           "USAT.GE",
+	USAT_LT:           "USAT.LT",
+	USAT_GT:           "USAT.GT",
+	USAT_LE:           "USAT.LE",
+	USAT:              "USAT",
+	USAT_ZZ:           "USAT.ZZ",
+	USAT16_EQ:         "USAT16.EQ",
+	USAT16_NE:         "USAT16.NE",
+	USAT16_CS:         "USAT16.CS",
+	USAT16_CC:         "USAT16.CC",
+	USAT16_MI:         "USAT16.MI",
+	USAT16_PL:         "USAT16.PL",
+	USAT16_VS:         "USAT16.VS",
+	USAT16_VC:         "USAT16.VC",
+	USAT16_HI:         "USAT16.HI",
+	USAT16_LS:         "USAT16.LS",
+	USAT16_GE:         "USAT16.GE",
+	USAT16_LT:         "USAT16.LT",
+	USAT16_GT:         "USAT16.GT",
+	USAT16_LE:         "USAT16.LE",
+	USAT16:            "USAT16",
+	USAT16_ZZ:         "USAT16.ZZ",
+	USAX_EQ:           "USAX.EQ",
+	USAX_NE:           "USAX.NE",
+	USAX_CS:           "USAX.CS",
+	USAX_CC:           "USAX.CC",
+	USAX_MI:           "USAX.MI",
+	USAX_PL:           "USAX.PL",
+	USAX_VS:           "USAX.VS",
+	USAX_VC:           "USAX.VC",
+	USAX_HI:           "USAX.HI",
+	USAX_LS:           "USAX.LS",
+	USAX_GE:           "USAX.GE",
+	USAX_LT:           "USAX.LT",
+	USAX_GT:           "USAX.GT",
+	USAX_LE:           "USAX.LE",
+	USAX:              "USAX",
+	USAX_ZZ:           "USAX.ZZ",
+	USUB16_EQ:         "USUB16.EQ",
+	USUB16_NE:         "USUB16.NE",
+	USUB16_CS:         "USUB16.CS",
+	USUB16_CC:         "USUB16.CC",
+	USUB16_MI:         "USUB16.MI",
+	USUB16_PL:         "USUB16.PL",
+	USUB16_VS:         "USUB16.VS",
+	USUB16_VC:         "USUB16.VC",
+	USUB16_HI:         "USUB16.HI",
+	USUB16_LS:         "USUB16.LS",
+	USUB16_GE:         "USUB16.GE",
+	USUB16_LT:         "USUB16.LT",
+	USUB16_GT:         "USUB16.GT",
+	USUB16_LE:         "USUB16.LE",
+	USUB16:            "USUB16",
+	USUB16_ZZ:         "USUB16.ZZ",
+	USUB8_EQ:          "USUB8.EQ",
+	USUB8_NE:          "USUB8.NE",
+	USUB8_CS:          "USUB8.CS",
+	USUB8_CC:          "USUB8.CC",
+	USUB8_MI:          "USUB8.MI",
+	USUB8_PL:          "USUB8.PL",
+	USUB8_VS:          "USUB8.VS",
+	USUB8_VC:          "USUB8.VC",
+	USUB8_HI:          "USUB8.HI",
+	USUB8_LS:          "USUB8.LS",
+	USUB8_GE:          "USUB8.GE",
+	USUB8_LT:          "USUB8.LT",
+	USUB8_GT:          "USUB8.GT",
+	USUB8_LE:          "USUB8.LE",
+	USUB8:             "USUB8",
+	USUB8_ZZ:          "USUB8.ZZ",
+	UXTAB_EQ:          "UXTAB.EQ",
+	UXTAB_NE:          "UXTAB.NE",
+	UXTAB_CS:          "UXTAB.CS",
+	UXTAB_CC:          "UXTAB.CC",
+	UXTAB_MI:          "UXTAB.MI",
+	UXTAB_PL:          "UXTAB.PL",
+	UXTAB_VS:          "UXTAB.VS",
+	UXTAB_VC:          "UXTAB.VC",
+	UXTAB_HI:          "UXTAB.HI",
+	UXTAB_LS:          "UXTAB.LS",
+	UXTAB_GE:          "UXTAB.GE",
+	UXTAB_LT:          "UXTAB.LT",
+	UXTAB_GT:          "UXTAB.GT",
+	UXTAB_LE:          "UXTAB.LE",
+	UXTAB:             "UXTAB",
+	UXTAB_ZZ:          "UXTAB.ZZ",
+	UXTAB16_EQ:        "UXTAB16.EQ",
+	UXTAB16_NE:        "UXTAB16.NE",
+	UXTAB16_CS:        "UXTAB16.CS",
+	UXTAB16_CC:        "UXTAB16.CC",
+	UXTAB16_MI:        "UXTAB16.MI",
+	UXTAB16_PL:        "UXTAB16.PL",
+	UXTAB16_VS:        "UXTAB16.VS",
+	UXTAB16_VC:        "UXTAB16.VC",
+	UXTAB16_HI:        "UXTAB16.HI",
+	UXTAB16_LS:        "UXTAB16.LS",
+	UXTAB16_GE:        "UXTAB16.GE",
+	UXTAB16_LT:        "UXTAB16.LT",
+	UXTAB16_GT:        "UXTAB16.GT",
+	UXTAB16_LE:        "UXTAB16.LE",
+	UXTAB16:           "UXTAB16",
+	UXTAB16_ZZ:        "UXTAB16.ZZ",
+	UXTAH_EQ:          "UXTAH.EQ",
+	UXTAH_NE:          "UXTAH.NE",
+	UXTAH_CS:          "UXTAH.CS",
+	UXTAH_CC:          "UXTAH.CC",
+	UXTAH_MI:          "UXTAH.MI",
+	UXTAH_PL:          "UXTAH.PL",
+	UXTAH_VS:          "UXTAH.VS",
+	UXTAH_VC:          "UXTAH.VC",
+	UXTAH_HI:          "UXTAH.HI",
+	UXTAH_LS:          "UXTAH.LS",
+	UXTAH_GE:          "UXTAH.GE",
+	UXTAH_LT:          "UXTAH.LT",
+	UXTAH_GT:          "UXTAH.GT",
+	UXTAH_LE:          "UXTAH.LE",
+	UXTAH:             "UXTAH",
+	UXTAH_ZZ:          "UXTAH.ZZ",
+	UXTB_EQ:           "UXTB.EQ",
+	UXTB_NE:           "UXTB.NE",
+	UXTB_CS:           "UXTB.CS",
+	UXTB_CC:           "UXTB.CC",
+	UXTB_MI:           "UXTB.MI",
+	UXTB_PL:           "UXTB.PL",
+	UXTB_VS:           "UXTB.VS",
+	UXTB_VC:           "UXTB.VC",
+	UXTB_HI:           "UXTB.HI",
+	UXTB_LS:           "UXTB.LS",
+	UXTB_GE:           "UXTB.GE",
+	UXTB_LT:           "UXTB.LT",
+	UXTB_GT:           "UXTB.GT",
+	UXTB_LE:           "UXTB.LE",
+	UXTB:              "UXTB",
+	UXTB_ZZ:           "UXTB.ZZ",
+	UXTB16_EQ:         "UXTB16.EQ",
+	UXTB16_NE:         "UXTB16.NE",
+	UXTB16_CS:         "UXTB16.CS",
+	UXTB16_CC:         "UXTB16.CC",
+	UXTB16_MI:         "UXTB16.MI",
+	UXTB16_PL:         "UXTB16.PL",
+	UXTB16_VS:         "UXTB16.VS",
+	UXTB16_VC:         "UXTB16.VC",
+	UXTB16_HI:         "UXTB16.HI",
+	UXTB16_LS:         "UXTB16.LS",
+	UXTB16_GE:         "UXTB16.GE",
+	UXTB16_LT:         "UXTB16.LT",
+	UXTB16_GT:         "UXTB16.GT",
+	UXTB16_LE:         "UXTB16.LE",
+	UXTB16:            "UXTB16",
+	UXTB16_ZZ:         "UXTB16.ZZ",
+	UXTH_EQ:           "UXTH.EQ",
+	UXTH_NE:           "UXTH.NE",
+	UXTH_CS:           "UXTH.CS",
+	UXTH_CC:           "UXTH.CC",
+	UXTH_MI:           "UXTH.MI",
+	UXTH_PL:           "UXTH.PL",
+	UXTH_VS:           "UXTH.VS",
+	UXTH_VC:           "UXTH.VC",
+	UXTH_HI:           "UXTH.HI",
+	UXTH_LS:           "UXTH.LS",
+	UXTH_GE:           "UXTH.GE",
+	UXTH_LT:           "UXTH.LT",
+	UXTH_GT:           "UXTH.GT",
+	UXTH_LE:           "UXTH.LE",
+	UXTH:              "UXTH",
+	UXTH_ZZ:           "UXTH.ZZ",
+	VABS_EQ_F32:       "VABS.EQ.F32",
+	VABS_NE_F32:       "VABS.NE.F32",
+	VABS_CS_F32:       "VABS.CS.F32",
+	VABS_CC_F32:       "VABS.CC.F32",
+	VABS_MI_F32:       "VABS.MI.F32",
+	VABS_PL_F32:       "VABS.PL.F32",
+	VABS_VS_F32:       "VABS.VS.F32",
+	VABS_VC_F32:       "VABS.VC.F32",
+	VABS_HI_F32:       "VABS.HI.F32",
+	VABS_LS_F32:       "VABS.LS.F32",
+	VABS_GE_F32:       "VABS.GE.F32",
+	VABS_LT_F32:       "VABS.LT.F32",
+	VABS_GT_F32:       "VABS.GT.F32",
+	VABS_LE_F32:       "VABS.LE.F32",
+	VABS_F32:          "VABS.F32",
+	VABS_ZZ_F32:       "VABS.ZZ.F32",
+	VABS_EQ_F64:       "VABS.EQ.F64",
+	VABS_NE_F64:       "VABS.NE.F64",
+	VABS_CS_F64:       "VABS.CS.F64",
+	VABS_CC_F64:       "VABS.CC.F64",
+	VABS_MI_F64:       "VABS.MI.F64",
+	VABS_PL_F64:       "VABS.PL.F64",
+	VABS_VS_F64:       "VABS.VS.F64",
+	VABS_VC_F64:       "VABS.VC.F64",
+	VABS_HI_F64:       "VABS.HI.F64",
+	VABS_LS_F64:       "VABS.LS.F64",
+	VABS_GE_F64:       "VABS.GE.F64",
+	VABS_LT_F64:       "VABS.LT.F64",
+	VABS_GT_F64:       "VABS.GT.F64",
+	VABS_LE_F64:       "VABS.LE.F64",
+	VABS_F64:          "VABS.F64",
+	VABS_ZZ_F64:       "VABS.ZZ.F64",
+	VADD_EQ_F32:       "VADD.EQ.F32",
+	VADD_NE_F32:       "VADD.NE.F32",
+	VADD_CS_F32:       "VADD.CS.F32",
+	VADD_CC_F32:       "VADD.CC.F32",
+	VADD_MI_F32:       "VADD.MI.F32",
+	VADD_PL_F32:       "VADD.PL.F32",
+	VADD_VS_F32:       "VADD.VS.F32",
+	VADD_VC_F32:       "VADD.VC.F32",
+	VADD_HI_F32:       "VADD.HI.F32",
+	VADD_LS_F32:       "VADD.LS.F32",
+	VADD_GE_F32:       "VADD.GE.F32",
+	VADD_LT_F32:       "VADD.LT.F32",
+	VADD_GT_F32:       "VADD.GT.F32",
+	VADD_LE_F32:       "VADD.LE.F32",
+	VADD_F32:          "VADD.F32",
+	VADD_ZZ_F32:       "VADD.ZZ.F32",
+	VADD_EQ_F64:       "VADD.EQ.F64",
+	VADD_NE_F64:       "VADD.NE.F64",
+	VADD_CS_F64:       "VADD.CS.F64",
+	VADD_CC_F64:       "VADD.CC.F64",
+	VADD_MI_F64:       "VADD.MI.F64",
+	VADD_PL_F64:       "VADD.PL.F64",
+	VADD_VS_F64:       "VADD.VS.F64",
+	VADD_VC_F64:       "VADD.VC.F64",
+	VADD_HI_F64:       "VADD.HI.F64",
+	VADD_LS_F64:       "VADD.LS.F64",
+	VADD_GE_F64:       "VADD.GE.F64",
+	VADD_LT_F64:       "VADD.LT.F64",
+	VADD_GT_F64:       "VADD.GT.F64",
+	VADD_LE_F64:       "VADD.LE.F64",
+	VADD_F64:          "VADD.F64",
+	VADD_ZZ_F64:       "VADD.ZZ.F64",
+	VCMP_EQ_F32:       "VCMP.EQ.F32",
+	VCMP_NE_F32:       "VCMP.NE.F32",
+	VCMP_CS_F32:       "VCMP.CS.F32",
+	VCMP_CC_F32:       "VCMP.CC.F32",
+	VCMP_MI_F32:       "VCMP.MI.F32",
+	VCMP_PL_F32:       "VCMP.PL.F32",
+	VCMP_VS_F32:       "VCMP.VS.F32",
+	VCMP_VC_F32:       "VCMP.VC.F32",
+	VCMP_HI_F32:       "VCMP.HI.F32",
+	VCMP_LS_F32:       "VCMP.LS.F32",
+	VCMP_GE_F32:       "VCMP.GE.F32",
+	VCMP_LT_F32:       "VCMP.LT.F32",
+	VCMP_GT_F32:       "VCMP.GT.F32",
+	VCMP_LE_F32:       "VCMP.LE.F32",
+	VCMP_F32:          "VCMP.F32",
+	VCMP_ZZ_F32:       "VCMP.ZZ.F32",
+	VCMP_EQ_F64:       "VCMP.EQ.F64",
+	VCMP_NE_F64:       "VCMP.NE.F64",
+	VCMP_CS_F64:       "VCMP.CS.F64",
+	VCMP_CC_F64:       "VCMP.CC.F64",
+	VCMP_MI_F64:       "VCMP.MI.F64",
+	VCMP_PL_F64:       "VCMP.PL.F64",
+	VCMP_VS_F64:       "VCMP.VS.F64",
+	VCMP_VC_F64:       "VCMP.VC.F64",
+	VCMP_HI_F64:       "VCMP.HI.F64",
+	VCMP_LS_F64:       "VCMP.LS.F64",
+	VCMP_GE_F64:       "VCMP.GE.F64",
+	VCMP_LT_F64:       "VCMP.LT.F64",
+	VCMP_GT_F64:       "VCMP.GT.F64",
+	VCMP_LE_F64:       "VCMP.LE.F64",
+	VCMP_F64:          "VCMP.F64",
+	VCMP_ZZ_F64:       "VCMP.ZZ.F64",
+	VCMP_E_EQ_F32:     "VCMP.E.EQ.F32",
+	VCMP_E_NE_F32:     "VCMP.E.NE.F32",
+	VCMP_E_CS_F32:     "VCMP.E.CS.F32",
+	VCMP_E_CC_F32:     "VCMP.E.CC.F32",
+	VCMP_E_MI_F32:     "VCMP.E.MI.F32",
+	VCMP_E_PL_F32:     "VCMP.E.PL.F32",
+	VCMP_E_VS_F32:     "VCMP.E.VS.F32",
+	VCMP_E_VC_F32:     "VCMP.E.VC.F32",
+	VCMP_E_HI_F32:     "VCMP.E.HI.F32",
+	VCMP_E_LS_F32:     "VCMP.E.LS.F32",
+	VCMP_E_GE_F32:     "VCMP.E.GE.F32",
+	VCMP_E_LT_F32:     "VCMP.E.LT.F32",
+	VCMP_E_GT_F32:     "VCMP.E.GT.F32",
+	VCMP_E_LE_F32:     "VCMP.E.LE.F32",
+	VCMP_E_F32:        "VCMP.E.F32",
+	VCMP_E_ZZ_F32:     "VCMP.E.ZZ.F32",
+	VCMP_E_EQ_F64:     "VCMP.E.EQ.F64",
+	VCMP_E_NE_F64:     "VCMP.E.NE.F64",
+	VCMP_E_CS_F64:     "VCMP.E.CS.F64",
+	VCMP_E_CC_F64:     "VCMP.E.CC.F64",
+	VCMP_E_MI_F64:     "VCMP.E.MI.F64",
+	VCMP_E_PL_F64:     "VCMP.E.PL.F64",
+	VCMP_E_VS_F64:     "VCMP.E.VS.F64",
+	VCMP_E_VC_F64:     "VCMP.E.VC.F64",
+	VCMP_E_HI_F64:     "VCMP.E.HI.F64",
+	VCMP_E_LS_F64:     "VCMP.E.LS.F64",
+	VCMP_E_GE_F64:     "VCMP.E.GE.F64",
+	VCMP_E_LT_F64:     "VCMP.E.LT.F64",
+	VCMP_E_GT_F64:     "VCMP.E.GT.F64",
+	VCMP_E_LE_F64:     "VCMP.E.LE.F64",
+	VCMP_E_F64:        "VCMP.E.F64",
+	VCMP_E_ZZ_F64:     "VCMP.E.ZZ.F64",
+	VCVT_EQ_F32_FXS16: "VCVT.EQ.F32.FXS16",
+	VCVT_NE_F32_FXS16: "VCVT.NE.F32.FXS16",
+	VCVT_CS_F32_FXS16: "VCVT.CS.F32.FXS16",
+	VCVT_CC_F32_FXS16: "VCVT.CC.F32.FXS16",
+	VCVT_MI_F32_FXS16: "VCVT.MI.F32.FXS16",
+	VCVT_PL_F32_FXS16: "VCVT.PL.F32.FXS16",
+	VCVT_VS_F32_FXS16: "VCVT.VS.F32.FXS16",
+	VCVT_VC_F32_FXS16: "VCVT.VC.F32.FXS16",
+	VCVT_HI_F32_FXS16: "VCVT.HI.F32.FXS16",
+	VCVT_LS_F32_FXS16: "VCVT.LS.F32.FXS16",
+	VCVT_GE_F32_FXS16: "VCVT.GE.F32.FXS16",
+	VCVT_LT_F32_FXS16: "VCVT.LT.F32.FXS16",
+	VCVT_GT_F32_FXS16: "VCVT.GT.F32.FXS16",
+	VCVT_LE_F32_FXS16: "VCVT.LE.F32.FXS16",
+	VCVT_F32_FXS16:    "VCVT.F32.FXS16",
+	VCVT_ZZ_F32_FXS16: "VCVT.ZZ.F32.FXS16",
+	VCVT_EQ_F32_FXS32: "VCVT.EQ.F32.FXS32",
+	VCVT_NE_F32_FXS32: "VCVT.NE.F32.FXS32",
+	VCVT_CS_F32_FXS32: "VCVT.CS.F32.FXS32",
+	VCVT_CC_F32_FXS32: "VCVT.CC.F32.FXS32",
+	VCVT_MI_F32_FXS32: "VCVT.MI.F32.FXS32",
+	VCVT_PL_F32_FXS32: "VCVT.PL.F32.FXS32",
+	VCVT_VS_F32_FXS32: "VCVT.VS.F32.FXS32",
+	VCVT_VC_F32_FXS32: "VCVT.VC.F32.FXS32",
+	VCVT_HI_F32_FXS32: "VCVT.HI.F32.FXS32",
+	VCVT_LS_F32_FXS32: "VCVT.LS.F32.FXS32",
+	VCVT_GE_F32_FXS32: "VCVT.GE.F32.FXS32",
+	VCVT_LT_F32_FXS32: "VCVT.LT.F32.FXS32",
+	VCVT_GT_F32_FXS32: "VCVT.GT.F32.FXS32",
+	VCVT_LE_F32_FXS32: "VCVT.LE.F32.FXS32",
+	VCVT_F32_FXS32:    "VCVT.F32.FXS32",
+	VCVT_ZZ_F32_FXS32: "VCVT.ZZ.F32.FXS32",
+	VCVT_EQ_F32_FXU16: "VCVT.EQ.F32.FXU16",
+	VCVT_NE_F32_FXU16: "VCVT.NE.F32.FXU16",
+	VCVT_CS_F32_FXU16: "VCVT.CS.F32.FXU16",
+	VCVT_CC_F32_FXU16: "VCVT.CC.F32.FXU16",
+	VCVT_MI_F32_FXU16: "VCVT.MI.F32.FXU16",
+	VCVT_PL_F32_FXU16: "VCVT.PL.F32.FXU16",
+	VCVT_VS_F32_FXU16: "VCVT.VS.F32.FXU16",
+	VCVT_VC_F32_FXU16: "VCVT.VC.F32.FXU16",
+	VCVT_HI_F32_FXU16: "VCVT.HI.F32.FXU16",
+	VCVT_LS_F32_FXU16: "VCVT.LS.F32.FXU16",
+	VCVT_GE_F32_FXU16: "VCVT.GE.F32.FXU16",
+	VCVT_LT_F32_FXU16: "VCVT.LT.F32.FXU16",
+	VCVT_GT_F32_FXU16: "VCVT.GT.F32.FXU16",
+	VCVT_LE_F32_FXU16: "VCVT.LE.F32.FXU16",
+	VCVT_F32_FXU16:    "VCVT.F32.FXU16",
+	VCVT_ZZ_F32_FXU16: "VCVT.ZZ.F32.FXU16",
+	VCVT_EQ_F32_FXU32: "VCVT.EQ.F32.FXU32",
+	VCVT_NE_F32_FXU32: "VCVT.NE.F32.FXU32",
+	VCVT_CS_F32_FXU32: "VCVT.CS.F32.FXU32",
+	VCVT_CC_F32_FXU32: "VCVT.CC.F32.FXU32",
+	VCVT_MI_F32_FXU32: "VCVT.MI.F32.FXU32",
+	VCVT_PL_F32_FXU32: "VCVT.PL.F32.FXU32",
+	VCVT_VS_F32_FXU32: "VCVT.VS.F32.FXU32",
+	VCVT_VC_F32_FXU32: "VCVT.VC.F32.FXU32",
+	VCVT_HI_F32_FXU32: "VCVT.HI.F32.FXU32",
+	VCVT_LS_F32_FXU32: "VCVT.LS.F32.FXU32",
+	VCVT_GE_F32_FXU32: "VCVT.GE.F32.FXU32",
+	VCVT_LT_F32_FXU32: "VCVT.LT.F32.FXU32",
+	VCVT_GT_F32_FXU32: "VCVT.GT.F32.FXU32",
+	VCVT_LE_F32_FXU32: "VCVT.LE.F32.FXU32",
+	VCVT_F32_FXU32:    "VCVT.F32.FXU32",
+	VCVT_ZZ_F32_FXU32: "VCVT.ZZ.F32.FXU32",
+	VCVT_EQ_F64_FXS16: "VCVT.EQ.F64.FXS16",
+	VCVT_NE_F64_FXS16: "VCVT.NE.F64.FXS16",
+	VCVT_CS_F64_FXS16: "VCVT.CS.F64.FXS16",
+	VCVT_CC_F64_FXS16: "VCVT.CC.F64.FXS16",
+	VCVT_MI_F64_FXS16: "VCVT.MI.F64.FXS16",
+	VCVT_PL_F64_FXS16: "VCVT.PL.F64.FXS16",
+	VCVT_VS_F64_FXS16: "VCVT.VS.F64.FXS16",
+	VCVT_VC_F64_FXS16: "VCVT.VC.F64.FXS16",
+	VCVT_HI_F64_FXS16: "VCVT.HI.F64.FXS16",
+	VCVT_LS_F64_FXS16: "VCVT.LS.F64.FXS16",
+	VCVT_GE_F64_FXS16: "VCVT.GE.F64.FXS16",
+	VCVT_LT_F64_FXS16: "VCVT.LT.F64.FXS16",
+	VCVT_GT_F64_FXS16: "VCVT.GT.F64.FXS16",
+	VCVT_LE_F64_FXS16: "VCVT.LE.F64.FXS16",
+	VCVT_F64_FXS16:    "VCVT.F64.FXS16",
+	VCVT_ZZ_F64_FXS16: "VCVT.ZZ.F64.FXS16",
+	VCVT_EQ_F64_FXS32: "VCVT.EQ.F64.FXS32",
+	VCVT_NE_F64_FXS32: "VCVT.NE.F64.FXS32",
+	VCVT_CS_F64_FXS32: "VCVT.CS.F64.FXS32",
+	VCVT_CC_F64_FXS32: "VCVT.CC.F64.FXS32",
+	VCVT_MI_F64_FXS32: "VCVT.MI.F64.FXS32",
+	VCVT_PL_F64_FXS32: "VCVT.PL.F64.FXS32",
+	VCVT_VS_F64_FXS32: "VCVT.VS.F64.FXS32",
+	VCVT_VC_F64_FXS32: "VCVT.VC.F64.FXS32",
+	VCVT_HI_F64_FXS32: "VCVT.HI.F64.FXS32",
+	VCVT_LS_F64_FXS32: "VCVT.LS.F64.FXS32",
+	VCVT_GE_F64_FXS32: "VCVT.GE.F64.FXS32",
+	VCVT_LT_F64_FXS32: "VCVT.LT.F64.FXS32",
+	VCVT_GT_F64_FXS32: "VCVT.GT.F64.FXS32",
+	VCVT_LE_F64_FXS32: "VCVT.LE.F64.FXS32",
+	VCVT_F64_FXS32:    "VCVT.F64.FXS32",
+	VCVT_ZZ_F64_FXS32: "VCVT.ZZ.F64.FXS32",
+	VCVT_EQ_F64_FXU16: "VCVT.EQ.F64.FXU16",
+	VCVT_NE_F64_FXU16: "VCVT.NE.F64.FXU16",
+	VCVT_CS_F64_FXU16: "VCVT.CS.F64.FXU16",
+	VCVT_CC_F64_FXU16: "VCVT.CC.F64.FXU16",
+	VCVT_MI_F64_FXU16: "VCVT.MI.F64.FXU16",
+	VCVT_PL_F64_FXU16: "VCVT.PL.F64.FXU16",
+	VCVT_VS_F64_FXU16: "VCVT.VS.F64.FXU16",
+	VCVT_VC_F64_FXU16: "VCVT.VC.F64.FXU16",
+	VCVT_HI_F64_FXU16: "VCVT.HI.F64.FXU16",
+	VCVT_LS_F64_FXU16: "VCVT.LS.F64.FXU16",
+	VCVT_GE_F64_FXU16: "VCVT.GE.F64.FXU16",
+	VCVT_LT_F64_FXU16: "VCVT.LT.F64.FXU16",
+	VCVT_GT_F64_FXU16: "VCVT.GT.F64.FXU16",
+	VCVT_LE_F64_FXU16: "VCVT.LE.F64.FXU16",
+	VCVT_F64_FXU16:    "VCVT.F64.FXU16",
+	VCVT_ZZ_F64_FXU16: "VCVT.ZZ.F64.FXU16",
+	VCVT_EQ_F64_FXU32: "VCVT.EQ.F64.FXU32",
+	VCVT_NE_F64_FXU32: "VCVT.NE.F64.FXU32",
+	VCVT_CS_F64_FXU32: "VCVT.CS.F64.FXU32",
+	VCVT_CC_F64_FXU32: "VCVT.CC.F64.FXU32",
+	VCVT_MI_F64_FXU32: "VCVT.MI.F64.FXU32",
+	VCVT_PL_F64_FXU32: "VCVT.PL.F64.FXU32",
+	VCVT_VS_F64_FXU32: "VCVT.VS.F64.FXU32",
+	VCVT_VC_F64_FXU32: "VCVT.VC.F64.FXU32",
+	VCVT_HI_F64_FXU32: "VCVT.HI.F64.FXU32",
+	VCVT_LS_F64_FXU32: "VCVT.LS.F64.FXU32",
+	VCVT_GE_F64_FXU32: "VCVT.GE.F64.FXU32",
+	VCVT_LT_F64_FXU32: "VCVT.LT.F64.FXU32",
+	VCVT_GT_F64_FXU32: "VCVT.GT.F64.FXU32",
+	VCVT_LE_F64_FXU32: "VCVT.LE.F64.FXU32",
+	VCVT_F64_FXU32:    "VCVT.F64.FXU32",
+	VCVT_ZZ_F64_FXU32: "VCVT.ZZ.F64.FXU32",
+	VCVT_EQ_F32_U32:   "VCVT.EQ.F32.U32",
+	VCVT_NE_F32_U32:   "VCVT.NE.F32.U32",
+	VCVT_CS_F32_U32:   "VCVT.CS.F32.U32",
+	VCVT_CC_F32_U32:   "VCVT.CC.F32.U32",
+	VCVT_MI_F32_U32:   "VCVT.MI.F32.U32",
+	VCVT_PL_F32_U32:   "VCVT.PL.F32.U32",
+	VCVT_VS_F32_U32:   "VCVT.VS.F32.U32",
+	VCVT_VC_F32_U32:   "VCVT.VC.F32.U32",
+	VCVT_HI_F32_U32:   "VCVT.HI.F32.U32",
+	VCVT_LS_F32_U32:   "VCVT.LS.F32.U32",
+	VCVT_GE_F32_U32:   "VCVT.GE.F32.U32",
+	VCVT_LT_F32_U32:   "VCVT.LT.F32.U32",
+	VCVT_GT_F32_U32:   "VCVT.GT.F32.U32",
+	VCVT_LE_F32_U32:   "VCVT.LE.F32.U32",
+	VCVT_F32_U32:      "VCVT.F32.U32",
+	VCVT_ZZ_F32_U32:   "VCVT.ZZ.F32.U32",
+	VCVT_EQ_F32_S32:   "VCVT.EQ.F32.S32",
+	VCVT_NE_F32_S32:   "VCVT.NE.F32.S32",
+	VCVT_CS_F32_S32:   "VCVT.CS.F32.S32",
+	VCVT_CC_F32_S32:   "VCVT.CC.F32.S32",
+	VCVT_MI_F32_S32:   "VCVT.MI.F32.S32",
+	VCVT_PL_F32_S32:   "VCVT.PL.F32.S32",
+	VCVT_VS_F32_S32:   "VCVT.VS.F32.S32",
+	VCVT_VC_F32_S32:   "VCVT.VC.F32.S32",
+	VCVT_HI_F32_S32:   "VCVT.HI.F32.S32",
+	VCVT_LS_F32_S32:   "VCVT.LS.F32.S32",
+	VCVT_GE_F32_S32:   "VCVT.GE.F32.S32",
+	VCVT_LT_F32_S32:   "VCVT.LT.F32.S32",
+	VCVT_GT_F32_S32:   "VCVT.GT.F32.S32",
+	VCVT_LE_F32_S32:   "VCVT.LE.F32.S32",
+	VCVT_F32_S32:      "VCVT.F32.S32",
+	VCVT_ZZ_F32_S32:   "VCVT.ZZ.F32.S32",
+	VCVT_EQ_F64_U32:   "VCVT.EQ.F64.U32",
+	VCVT_NE_F64_U32:   "VCVT.NE.F64.U32",
+	VCVT_CS_F64_U32:   "VCVT.CS.F64.U32",
+	VCVT_CC_F64_U32:   "VCVT.CC.F64.U32",
+	VCVT_MI_F64_U32:   "VCVT.MI.F64.U32",
+	VCVT_PL_F64_U32:   "VCVT.PL.F64.U32",
+	VCVT_VS_F64_U32:   "VCVT.VS.F64.U32",
+	VCVT_VC_F64_U32:   "VCVT.VC.F64.U32",
+	VCVT_HI_F64_U32:   "VCVT.HI.F64.U32",
+	VCVT_LS_F64_U32:   "VCVT.LS.F64.U32",
+	VCVT_GE_F64_U32:   "VCVT.GE.F64.U32",
+	VCVT_LT_F64_U32:   "VCVT.LT.F64.U32",
+	VCVT_GT_F64_U32:   "VCVT.GT.F64.U32",
+	VCVT_LE_F64_U32:   "VCVT.LE.F64.U32",
+	VCVT_F64_U32:      "VCVT.F64.U32",
+	VCVT_ZZ_F64_U32:   "VCVT.ZZ.F64.U32",
+	VCVT_EQ_F64_S32:   "VCVT.EQ.F64.S32",
+	VCVT_NE_F64_S32:   "VCVT.NE.F64.S32",
+	VCVT_CS_F64_S32:   "VCVT.CS.F64.S32",
+	VCVT_CC_F64_S32:   "VCVT.CC.F64.S32",
+	VCVT_MI_F64_S32:   "VCVT.MI.F64.S32",
+	VCVT_PL_F64_S32:   "VCVT.PL.F64.S32",
+	VCVT_VS_F64_S32:   "VCVT.VS.F64.S32",
+	VCVT_VC_F64_S32:   "VCVT.VC.F64.S32",
+	VCVT_HI_F64_S32:   "VCVT.HI.F64.S32",
+	VCVT_LS_F64_S32:   "VCVT.LS.F64.S32",
+	VCVT_GE_F64_S32:   "VCVT.GE.F64.S32",
+	VCVT_LT_F64_S32:   "VCVT.LT.F64.S32",
+	VCVT_GT_F64_S32:   "VCVT.GT.F64.S32",
+	VCVT_LE_F64_S32:   "VCVT.LE.F64.S32",
+	VCVT_F64_S32:      "VCVT.F64.S32",
+	VCVT_ZZ_F64_S32:   "VCVT.ZZ.F64.S32",
+	VCVT_EQ_F64_F32:   "VCVT.EQ.F64.F32",
+	VCVT_NE_F64_F32:   "VCVT.NE.F64.F32",
+	VCVT_CS_F64_F32:   "VCVT.CS.F64.F32",
+	VCVT_CC_F64_F32:   "VCVT.CC.F64.F32",
+	VCVT_MI_F64_F32:   "VCVT.MI.F64.F32",
+	VCVT_PL_F64_F32:   "VCVT.PL.F64.F32",
+	VCVT_VS_F64_F32:   "VCVT.VS.F64.F32",
+	VCVT_VC_F64_F32:   "VCVT.VC.F64.F32",
+	VCVT_HI_F64_F32:   "VCVT.HI.F64.F32",
+	VCVT_LS_F64_F32:   "VCVT.LS.F64.F32",
+	VCVT_GE_F64_F32:   "VCVT.GE.F64.F32",
+	VCVT_LT_F64_F32:   "VCVT.LT.F64.F32",
+	VCVT_GT_F64_F32:   "VCVT.GT.F64.F32",
+	VCVT_LE_F64_F32:   "VCVT.LE.F64.F32",
+	VCVT_F64_F32:      "VCVT.F64.F32",
+	VCVT_ZZ_F64_F32:   "VCVT.ZZ.F64.F32",
+	VCVT_EQ_F32_F64:   "VCVT.EQ.F32.F64",
+	VCVT_NE_F32_F64:   "VCVT.NE.F32.F64",
+	VCVT_CS_F32_F64:   "VCVT.CS.F32.F64",
+	VCVT_CC_F32_F64:   "VCVT.CC.F32.F64",
+	VCVT_MI_F32_F64:   "VCVT.MI.F32.F64",
+	VCVT_PL_F32_F64:   "VCVT.PL.F32.F64",
+	VCVT_VS_F32_F64:   "VCVT.VS.F32.F64",
+	VCVT_VC_F32_F64:   "VCVT.VC.F32.F64",
+	VCVT_HI_F32_F64:   "VCVT.HI.F32.F64",
+	VCVT_LS_F32_F64:   "VCVT.LS.F32.F64",
+	VCVT_GE_F32_F64:   "VCVT.GE.F32.F64",
+	VCVT_LT_F32_F64:   "VCVT.LT.F32.F64",
+	VCVT_GT_F32_F64:   "VCVT.GT.F32.F64",
+	VCVT_LE_F32_F64:   "VCVT.LE.F32.F64",
+	VCVT_F32_F64:      "VCVT.F32.F64",
+	VCVT_ZZ_F32_F64:   "VCVT.ZZ.F32.F64",
+	VCVT_EQ_FXS16_F32: "VCVT.EQ.FXS16.F32",
+	VCVT_NE_FXS16_F32: "VCVT.NE.FXS16.F32",
+	VCVT_CS_FXS16_F32: "VCVT.CS.FXS16.F32",
+	VCVT_CC_FXS16_F32: "VCVT.CC.FXS16.F32",
+	VCVT_MI_FXS16_F32: "VCVT.MI.FXS16.F32",
+	VCVT_PL_FXS16_F32: "VCVT.PL.FXS16.F32",
+	VCVT_VS_FXS16_F32: "VCVT.VS.FXS16.F32",
+	VCVT_VC_FXS16_F32: "VCVT.VC.FXS16.F32",
+	VCVT_HI_FXS16_F32: "VCVT.HI.FXS16.F32",
+	VCVT_LS_FXS16_F32: "VCVT.LS.FXS16.F32",
+	VCVT_GE_FXS16_F32: "VCVT.GE.FXS16.F32",
+	VCVT_LT_FXS16_F32: "VCVT.LT.FXS16.F32",
+	VCVT_GT_FXS16_F32: "VCVT.GT.FXS16.F32",
+	VCVT_LE_FXS16_F32: "VCVT.LE.FXS16.F32",
+	VCVT_FXS16_F32:    "VCVT.FXS16.F32",
+	VCVT_ZZ_FXS16_F32: "VCVT.ZZ.FXS16.F32",
+	VCVT_EQ_FXS16_F64: "VCVT.EQ.FXS16.F64",
+	VCVT_NE_FXS16_F64: "VCVT.NE.FXS16.F64",
+	VCVT_CS_FXS16_F64: "VCVT.CS.FXS16.F64",
+	VCVT_CC_FXS16_F64: "VCVT.CC.FXS16.F64",
+	VCVT_MI_FXS16_F64: "VCVT.MI.FXS16.F64",
+	VCVT_PL_FXS16_F64: "VCVT.PL.FXS16.F64",
+	VCVT_VS_FXS16_F64: "VCVT.VS.FXS16.F64",
+	VCVT_VC_FXS16_F64: "VCVT.VC.FXS16.F64",
+	VCVT_HI_FXS16_F64: "VCVT.HI.FXS16.F64",
+	VCVT_LS_FXS16_F64: "VCVT.LS.FXS16.F64",
+	VCVT_GE_FXS16_F64: "VCVT.GE.FXS16.F64",
+	VCVT_LT_FXS16_F64: "VCVT.LT.FXS16.F64",
+	VCVT_GT_FXS16_F64: "VCVT.GT.FXS16.F64",
+	VCVT_LE_FXS16_F64: "VCVT.LE.FXS16.F64",
+	VCVT_FXS16_F64:    "VCVT.FXS16.F64",
+	VCVT_ZZ_FXS16_F64: "VCVT.ZZ.FXS16.F64",
+	VCVT_EQ_FXS32_F32: "VCVT.EQ.FXS32.F32",
+	VCVT_NE_FXS32_F32: "VCVT.NE.FXS32.F32",
+	VCVT_CS_FXS32_F32: "VCVT.CS.FXS32.F32",
+	VCVT_CC_FXS32_F32: "VCVT.CC.FXS32.F32",
+	VCVT_MI_FXS32_F32: "VCVT.MI.FXS32.F32",
+	VCVT_PL_FXS32_F32: "VCVT.PL.FXS32.F32",
+	VCVT_VS_FXS32_F32: "VCVT.VS.FXS32.F32",
+	VCVT_VC_FXS32_F32: "VCVT.VC.FXS32.F32",
+	VCVT_HI_FXS32_F32: "VCVT.HI.FXS32.F32",
+	VCVT_LS_FXS32_F32: "VCVT.LS.FXS32.F32",
+	VCVT_GE_FXS32_F32: "VCVT.GE.FXS32.F32",
+	VCVT_LT_FXS32_F32: "VCVT.LT.FXS32.F32",
+	VCVT_GT_FXS32_F32: "VCVT.GT.FXS32.F32",
+	VCVT_LE_FXS32_F32: "VCVT.LE.FXS32.F32",
+	VCVT_FXS32_F32:    "VCVT.FXS32.F32",
+	VCVT_ZZ_FXS32_F32: "VCVT.ZZ.FXS32.F32",
+	VCVT_EQ_FXS32_F64: "VCVT.EQ.FXS32.F64",
+	VCVT_NE_FXS32_F64: "VCVT.NE.FXS32.F64",
+	VCVT_CS_FXS32_F64: "VCVT.CS.FXS32.F64",
+	VCVT_CC_FXS32_F64: "VCVT.CC.FXS32.F64",
+	VCVT_MI_FXS32_F64: "VCVT.MI.FXS32.F64",
+	VCVT_PL_FXS32_F64: "VCVT.PL.FXS32.F64",
+	VCVT_VS_FXS32_F64: "VCVT.VS.FXS32.F64",
+	VCVT_VC_FXS32_F64: "VCVT.VC.FXS32.F64",
+	VCVT_HI_FXS32_F64: "VCVT.HI.FXS32.F64",
+	VCVT_LS_FXS32_F64: "VCVT.LS.FXS32.F64",
+	VCVT_GE_FXS32_F64: "VCVT.GE.FXS32.F64",
+	VCVT_LT_FXS32_F64: "VCVT.LT.FXS32.F64",
+	VCVT_GT_FXS32_F64: "VCVT.GT.FXS32.F64",
+	VCVT_LE_FXS32_F64: "VCVT.LE.FXS32.F64",
+	VCVT_FXS32_F64:    "VCVT.FXS32.F64",
+	VCVT_ZZ_FXS32_F64: "VCVT.ZZ.FXS32.F64",
+	VCVT_EQ_FXU16_F32: "VCVT.EQ.FXU16.F32",
+	VCVT_NE_FXU16_F32: "VCVT.NE.FXU16.F32",
+	VCVT_CS_FXU16_F32: "VCVT.CS.FXU16.F32",
+	VCVT_CC_FXU16_F32: "VCVT.CC.FXU16.F32",
+	VCVT_MI_FXU16_F32: "VCVT.MI.FXU16.F32",
+	VCVT_PL_FXU16_F32: "VCVT.PL.FXU16.F32",
+	VCVT_VS_FXU16_F32: "VCVT.VS.FXU16.F32",
+	VCVT_VC_FXU16_F32: "VCVT.VC.FXU16.F32",
+	VCVT_HI_FXU16_F32: "VCVT.HI.FXU16.F32",
+	VCVT_LS_FXU16_F32: "VCVT.LS.FXU16.F32",
+	VCVT_GE_FXU16_F32: "VCVT.GE.FXU16.F32",
+	VCVT_LT_FXU16_F32: "VCVT.LT.FXU16.F32",
+	VCVT_GT_FXU16_F32: "VCVT.GT.FXU16.F32",
+	VCVT_LE_FXU16_F32: "VCVT.LE.FXU16.F32",
+	VCVT_FXU16_F32:    "VCVT.FXU16.F32",
+	VCVT_ZZ_FXU16_F32: "VCVT.ZZ.FXU16.F32",
+	VCVT_EQ_FXU16_F64: "VCVT.EQ.FXU16.F64",
+	VCVT_NE_FXU16_F64: "VCVT.NE.FXU16.F64",
+	VCVT_CS_FXU16_F64: "VCVT.CS.FXU16.F64",
+	VCVT_CC_FXU16_F64: "VCVT.CC.FXU16.F64",
+	VCVT_MI_FXU16_F64: "VCVT.MI.FXU16.F64",
+	VCVT_PL_FXU16_F64: "VCVT.PL.FXU16.F64",
+	VCVT_VS_FXU16_F64: "VCVT.VS.FXU16.F64",
+	VCVT_VC_FXU16_F64: "VCVT.VC.FXU16.F64",
+	VCVT_HI_FXU16_F64: "VCVT.HI.FXU16.F64",
+	VCVT_LS_FXU16_F64: "VCVT.LS.FXU16.F64",
+	VCVT_GE_FXU16_F64: "VCVT.GE.FXU16.F64",
+	VCVT_LT_FXU16_F64: "VCVT.LT.FXU16.F64",
+	VCVT_GT_FXU16_F64: "VCVT.GT.FXU16.F64",
+	VCVT_LE_FXU16_F64: "VCVT.LE.FXU16.F64",
+	VCVT_FXU16_F64:    "VCVT.FXU16.F64",
+	VCVT_ZZ_FXU16_F64: "VCVT.ZZ.FXU16.F64",
+	VCVT_EQ_FXU32_F32: "VCVT.EQ.FXU32.F32",
+	VCVT_NE_FXU32_F32: "VCVT.NE.FXU32.F32",
+	VCVT_CS_FXU32_F32: "VCVT.CS.FXU32.F32",
+	VCVT_CC_FXU32_F32: "VCVT.CC.FXU32.F32",
+	VCVT_MI_FXU32_F32: "VCVT.MI.FXU32.F32",
+	VCVT_PL_FXU32_F32: "VCVT.PL.FXU32.F32",
+	VCVT_VS_FXU32_F32: "VCVT.VS.FXU32.F32",
+	VCVT_VC_FXU32_F32: "VCVT.VC.FXU32.F32",
+	VCVT_HI_FXU32_F32: "VCVT.HI.FXU32.F32",
+	VCVT_LS_FXU32_F32: "VCVT.LS.FXU32.F32",
+	VCVT_GE_FXU32_F32: "VCVT.GE.FXU32.F32",
+	VCVT_LT_FXU32_F32: "VCVT.LT.FXU32.F32",
+	VCVT_GT_FXU32_F32: "VCVT.GT.FXU32.F32",
+	VCVT_LE_FXU32_F32: "VCVT.LE.FXU32.F32",
+	VCVT_FXU32_F32:    "VCVT.FXU32.F32",
+	VCVT_ZZ_FXU32_F32: "VCVT.ZZ.FXU32.F32",
+	VCVT_EQ_FXU32_F64: "VCVT.EQ.FXU32.F64",
+	VCVT_NE_FXU32_F64: "VCVT.NE.FXU32.F64",
+	VCVT_CS_FXU32_F64: "VCVT.CS.FXU32.F64",
+	VCVT_CC_FXU32_F64: "VCVT.CC.FXU32.F64",
+	VCVT_MI_FXU32_F64: "VCVT.MI.FXU32.F64",
+	VCVT_PL_FXU32_F64: "VCVT.PL.FXU32.F64",
+	VCVT_VS_FXU32_F64: "VCVT.VS.FXU32.F64",
+	VCVT_VC_FXU32_F64: "VCVT.VC.FXU32.F64",
+	VCVT_HI_FXU32_F64: "VCVT.HI.FXU32.F64",
+	VCVT_LS_FXU32_F64: "VCVT.LS.FXU32.F64",
+	VCVT_GE_FXU32_F64: "VCVT.GE.FXU32.F64",
+	VCVT_LT_FXU32_F64: "VCVT.LT.FXU32.F64",
+	VCVT_GT_FXU32_F64: "VCVT.GT.FXU32.F64",
+	VCVT_LE_FXU32_F64: "VCVT.LE.FXU32.F64",
+	VCVT_FXU32_F64:    "VCVT.FXU32.F64",
+	VCVT_ZZ_FXU32_F64: "VCVT.ZZ.FXU32.F64",
+	VCVTB_EQ_F32_F16:  "VCVTB.EQ.F32.F16",
+	VCVTB_NE_F32_F16:  "VCVTB.NE.F32.F16",
+	VCVTB_CS_F32_F16:  "VCVTB.CS.F32.F16",
+	VCVTB_CC_F32_F16:  "VCVTB.CC.F32.F16",
+	VCVTB_MI_F32_F16:  "VCVTB.MI.F32.F16",
+	VCVTB_PL_F32_F16:  "VCVTB.PL.F32.F16",
+	VCVTB_VS_F32_F16:  "VCVTB.VS.F32.F16",
+	VCVTB_VC_F32_F16:  "VCVTB.VC.F32.F16",
+	VCVTB_HI_F32_F16:  "VCVTB.HI.F32.F16",
+	VCVTB_LS_F32_F16:  "VCVTB.LS.F32.F16",
+	VCVTB_GE_F32_F16:  "VCVTB.GE.F32.F16",
+	VCVTB_LT_F32_F16:  "VCVTB.LT.F32.F16",
+	VCVTB_GT_F32_F16:  "VCVTB.GT.F32.F16",
+	VCVTB_LE_F32_F16:  "VCVTB.LE.F32.F16",
+	VCVTB_F32_F16:     "VCVTB.F32.F16",
+	VCVTB_ZZ_F32_F16:  "VCVTB.ZZ.F32.F16",
+	VCVTB_EQ_F16_F32:  "VCVTB.EQ.F16.F32",
+	VCVTB_NE_F16_F32:  "VCVTB.NE.F16.F32",
+	VCVTB_CS_F16_F32:  "VCVTB.CS.F16.F32",
+	VCVTB_CC_F16_F32:  "VCVTB.CC.F16.F32",
+	VCVTB_MI_F16_F32:  "VCVTB.MI.F16.F32",
+	VCVTB_PL_F16_F32:  "VCVTB.PL.F16.F32",
+	VCVTB_VS_F16_F32:  "VCVTB.VS.F16.F32",
+	VCVTB_VC_F16_F32:  "VCVTB.VC.F16.F32",
+	VCVTB_HI_F16_F32:  "VCVTB.HI.F16.F32",
+	VCVTB_LS_F16_F32:  "VCVTB.LS.F16.F32",
+	VCVTB_GE_F16_F32:  "VCVTB.GE.F16.F32",
+	VCVTB_LT_F16_F32:  "VCVTB.LT.F16.F32",
+	VCVTB_GT_F16_F32:  "VCVTB.GT.F16.F32",
+	VCVTB_LE_F16_F32:  "VCVTB.LE.F16.F32",
+	VCVTB_F16_F32:     "VCVTB.F16.F32",
+	VCVTB_ZZ_F16_F32:  "VCVTB.ZZ.F16.F32",
+	VCVTT_EQ_F32_F16:  "VCVTT.EQ.F32.F16",
+	VCVTT_NE_F32_F16:  "VCVTT.NE.F32.F16",
+	VCVTT_CS_F32_F16:  "VCVTT.CS.F32.F16",
+	VCVTT_CC_F32_F16:  "VCVTT.CC.F32.F16",
+	VCVTT_MI_F32_F16:  "VCVTT.MI.F32.F16",
+	VCVTT_PL_F32_F16:  "VCVTT.PL.F32.F16",
+	VCVTT_VS_F32_F16:  "VCVTT.VS.F32.F16",
+	VCVTT_VC_F32_F16:  "VCVTT.VC.F32.F16",
+	VCVTT_HI_F32_F16:  "VCVTT.HI.F32.F16",
+	VCVTT_LS_F32_F16:  "VCVTT.LS.F32.F16",
+	VCVTT_GE_F32_F16:  "VCVTT.GE.F32.F16",
+	VCVTT_LT_F32_F16:  "VCVTT.LT.F32.F16",
+	VCVTT_GT_F32_F16:  "VCVTT.GT.F32.F16",
+	VCVTT_LE_F32_F16:  "VCVTT.LE.F32.F16",
+	VCVTT_F32_F16:     "VCVTT.F32.F16",
+	VCVTT_ZZ_F32_F16:  "VCVTT.ZZ.F32.F16",
+	VCVTT_EQ_F16_F32:  "VCVTT.EQ.F16.F32",
+	VCVTT_NE_F16_F32:  "VCVTT.NE.F16.F32",
+	VCVTT_CS_F16_F32:  "VCVTT.CS.F16.F32",
+	VCVTT_CC_F16_F32:  "VCVTT.CC.F16.F32",
+	VCVTT_MI_F16_F32:  "VCVTT.MI.F16.F32",
+	VCVTT_PL_F16_F32:  "VCVTT.PL.F16.F32",
+	VCVTT_VS_F16_F32:  "VCVTT.VS.F16.F32",
+	VCVTT_VC_F16_F32:  "VCVTT.VC.F16.F32",
+	VCVTT_HI_F16_F32:  "VCVTT.HI.F16.F32",
+	VCVTT_LS_F16_F32:  "VCVTT.LS.F16.F32",
+	VCVTT_GE_F16_F32:  "VCVTT.GE.F16.F32",
+	VCVTT_LT_F16_F32:  "VCVTT.LT.F16.F32",
+	VCVTT_GT_F16_F32:  "VCVTT.GT.F16.F32",
+	VCVTT_LE_F16_F32:  "VCVTT.LE.F16.F32",
+	VCVTT_F16_F32:     "VCVTT.F16.F32",
+	VCVTT_ZZ_F16_F32:  "VCVTT.ZZ.F16.F32",
+	VCVTR_EQ_U32_F32:  "VCVTR.EQ.U32.F32",
+	VCVTR_NE_U32_F32:  "VCVTR.NE.U32.F32",
+	VCVTR_CS_U32_F32:  "VCVTR.CS.U32.F32",
+	VCVTR_CC_U32_F32:  "VCVTR.CC.U32.F32",
+	VCVTR_MI_U32_F32:  "VCVTR.MI.U32.F32",
+	VCVTR_PL_U32_F32:  "VCVTR.PL.U32.F32",
+	VCVTR_VS_U32_F32:  "VCVTR.VS.U32.F32",
+	VCVTR_VC_U32_F32:  "VCVTR.VC.U32.F32",
+	VCVTR_HI_U32_F32:  "VCVTR.HI.U32.F32",
+	VCVTR_LS_U32_F32:  "VCVTR.LS.U32.F32",
+	VCVTR_GE_U32_F32:  "VCVTR.GE.U32.F32",
+	VCVTR_LT_U32_F32:  "VCVTR.LT.U32.F32",
+	VCVTR_GT_U32_F32:  "VCVTR.GT.U32.F32",
+	VCVTR_LE_U32_F32:  "VCVTR.LE.U32.F32",
+	VCVTR_U32_F32:     "VCVTR.U32.F32",
+	VCVTR_ZZ_U32_F32:  "VCVTR.ZZ.U32.F32",
+	VCVTR_EQ_U32_F64:  "VCVTR.EQ.U32.F64",
+	VCVTR_NE_U32_F64:  "VCVTR.NE.U32.F64",
+	VCVTR_CS_U32_F64:  "VCVTR.CS.U32.F64",
+	VCVTR_CC_U32_F64:  "VCVTR.CC.U32.F64",
+	VCVTR_MI_U32_F64:  "VCVTR.MI.U32.F64",
+	VCVTR_PL_U32_F64:  "VCVTR.PL.U32.F64",
+	VCVTR_VS_U32_F64:  "VCVTR.VS.U32.F64",
+	VCVTR_VC_U32_F64:  "VCVTR.VC.U32.F64",
+	VCVTR_HI_U32_F64:  "VCVTR.HI.U32.F64",
+	VCVTR_LS_U32_F64:  "VCVTR.LS.U32.F64",
+	VCVTR_GE_U32_F64:  "VCVTR.GE.U32.F64",
+	VCVTR_LT_U32_F64:  "VCVTR.LT.U32.F64",
+	VCVTR_GT_U32_F64:  "VCVTR.GT.U32.F64",
+	VCVTR_LE_U32_F64:  "VCVTR.LE.U32.F64",
+	VCVTR_U32_F64:     "VCVTR.U32.F64",
+	VCVTR_ZZ_U32_F64:  "VCVTR.ZZ.U32.F64",
+	VCVTR_EQ_S32_F32:  "VCVTR.EQ.S32.F32",
+	VCVTR_NE_S32_F32:  "VCVTR.NE.S32.F32",
+	VCVTR_CS_S32_F32:  "VCVTR.CS.S32.F32",
+	VCVTR_CC_S32_F32:  "VCVTR.CC.S32.F32",
+	VCVTR_MI_S32_F32:  "VCVTR.MI.S32.F32",
+	VCVTR_PL_S32_F32:  "VCVTR.PL.S32.F32",
+	VCVTR_VS_S32_F32:  "VCVTR.VS.S32.F32",
+	VCVTR_VC_S32_F32:  "VCVTR.VC.S32.F32",
+	VCVTR_HI_S32_F32:  "VCVTR.HI.S32.F32",
+	VCVTR_LS_S32_F32:  "VCVTR.LS.S32.F32",
+	VCVTR_GE_S32_F32:  "VCVTR.GE.S32.F32",
+	VCVTR_LT_S32_F32:  "VCVTR.LT.S32.F32",
+	VCVTR_GT_S32_F32:  "VCVTR.GT.S32.F32",
+	VCVTR_LE_S32_F32:  "VCVTR.LE.S32.F32",
+	VCVTR_S32_F32:     "VCVTR.S32.F32",
+	VCVTR_ZZ_S32_F32:  "VCVTR.ZZ.S32.F32",
+	VCVTR_EQ_S32_F64:  "VCVTR.EQ.S32.F64",
+	VCVTR_NE_S32_F64:  "VCVTR.NE.S32.F64",
+	VCVTR_CS_S32_F64:  "VCVTR.CS.S32.F64",
+	VCVTR_CC_S32_F64:  "VCVTR.CC.S32.F64",
+	VCVTR_MI_S32_F64:  "VCVTR.MI.S32.F64",
+	VCVTR_PL_S32_F64:  "VCVTR.PL.S32.F64",
+	VCVTR_VS_S32_F64:  "VCVTR.VS.S32.F64",
+	VCVTR_VC_S32_F64:  "VCVTR.VC.S32.F64",
+	VCVTR_HI_S32_F64:  "VCVTR.HI.S32.F64",
+	VCVTR_LS_S32_F64:  "VCVTR.LS.S32.F64",
+	VCVTR_GE_S32_F64:  "VCVTR.GE.S32.F64",
+	VCVTR_LT_S32_F64:  "VCVTR.LT.S32.F64",
+	VCVTR_GT_S32_F64:  "VCVTR.GT.S32.F64",
+	VCVTR_LE_S32_F64:  "VCVTR.LE.S32.F64",
+	VCVTR_S32_F64:     "VCVTR.S32.F64",
+	VCVTR_ZZ_S32_F64:  "VCVTR.ZZ.S32.F64",
+	VCVT_EQ_U32_F32:   "VCVT.EQ.U32.F32",
+	VCVT_NE_U32_F32:   "VCVT.NE.U32.F32",
+	VCVT_CS_U32_F32:   "VCVT.CS.U32.F32",
+	VCVT_CC_U32_F32:   "VCVT.CC.U32.F32",
+	VCVT_MI_U32_F32:   "VCVT.MI.U32.F32",
+	VCVT_PL_U32_F32:   "VCVT.PL.U32.F32",
+	VCVT_VS_U32_F32:   "VCVT.VS.U32.F32",
+	VCVT_VC_U32_F32:   "VCVT.VC.U32.F32",
+	VCVT_HI_U32_F32:   "VCVT.HI.U32.F32",
+	VCVT_LS_U32_F32:   "VCVT.LS.U32.F32",
+	VCVT_GE_U32_F32:   "VCVT.GE.U32.F32",
+	VCVT_LT_U32_F32:   "VCVT.LT.U32.F32",
+	VCVT_GT_U32_F32:   "VCVT.GT.U32.F32",
+	VCVT_LE_U32_F32:   "VCVT.LE.U32.F32",
+	VCVT_U32_F32:      "VCVT.U32.F32",
+	VCVT_ZZ_U32_F32:   "VCVT.ZZ.U32.F32",
+	VCVT_EQ_U32_F64:   "VCVT.EQ.U32.F64",
+	VCVT_NE_U32_F64:   "VCVT.NE.U32.F64",
+	VCVT_CS_U32_F64:   "VCVT.CS.U32.F64",
+	VCVT_CC_U32_F64:   "VCVT.CC.U32.F64",
+	VCVT_MI_U32_F64:   "VCVT.MI.U32.F64",
+	VCVT_PL_U32_F64:   "VCVT.PL.U32.F64",
+	VCVT_VS_U32_F64:   "VCVT.VS.U32.F64",
+	VCVT_VC_U32_F64:   "VCVT.VC.U32.F64",
+	VCVT_HI_U32_F64:   "VCVT.HI.U32.F64",
+	VCVT_LS_U32_F64:   "VCVT.LS.U32.F64",
+	VCVT_GE_U32_F64:   "VCVT.GE.U32.F64",
+	VCVT_LT_U32_F64:   "VCVT.LT.U32.F64",
+	VCVT_GT_U32_F64:   "VCVT.GT.U32.F64",
+	VCVT_LE_U32_F64:   "VCVT.LE.U32.F64",
+	VCVT_U32_F64:      "VCVT.U32.F64",
+	VCVT_ZZ_U32_F64:   "VCVT.ZZ.U32.F64",
+	VCVT_EQ_S32_F32:   "VCVT.EQ.S32.F32",
+	VCVT_NE_S32_F32:   "VCVT.NE.S32.F32",
+	VCVT_CS_S32_F32:   "VCVT.CS.S32.F32",
+	VCVT_CC_S32_F32:   "VCVT.CC.S32.F32",
+	VCVT_MI_S32_F32:   "VCVT.MI.S32.F32",
+	VCVT_PL_S32_F32:   "VCVT.PL.S32.F32",
+	VCVT_VS_S32_F32:   "VCVT.VS.S32.F32",
+	VCVT_VC_S32_F32:   "VCVT.VC.S32.F32",
+	VCVT_HI_S32_F32:   "VCVT.HI.S32.F32",
+	VCVT_LS_S32_F32:   "VCVT.LS.S32.F32",
+	VCVT_GE_S32_F32:   "VCVT.GE.S32.F32",
+	VCVT_LT_S32_F32:   "VCVT.LT.S32.F32",
+	VCVT_GT_S32_F32:   "VCVT.GT.S32.F32",
+	VCVT_LE_S32_F32:   "VCVT.LE.S32.F32",
+	VCVT_S32_F32:      "VCVT.S32.F32",
+	VCVT_ZZ_S32_F32:   "VCVT.ZZ.S32.F32",
+	VCVT_EQ_S32_F64:   "VCVT.EQ.S32.F64",
+	VCVT_NE_S32_F64:   "VCVT.NE.S32.F64",
+	VCVT_CS_S32_F64:   "VCVT.CS.S32.F64",
+	VCVT_CC_S32_F64:   "VCVT.CC.S32.F64",
+	VCVT_MI_S32_F64:   "VCVT.MI.S32.F64",
+	VCVT_PL_S32_F64:   "VCVT.PL.S32.F64",
+	VCVT_VS_S32_F64:   "VCVT.VS.S32.F64",
+	VCVT_VC_S32_F64:   "VCVT.VC.S32.F64",
+	VCVT_HI_S32_F64:   "VCVT.HI.S32.F64",
+	VCVT_LS_S32_F64:   "VCVT.LS.S32.F64",
+	VCVT_GE_S32_F64:   "VCVT.GE.S32.F64",
+	VCVT_LT_S32_F64:   "VCVT.LT.S32.F64",
+	VCVT_GT_S32_F64:   "VCVT.GT.S32.F64",
+	VCVT_LE_S32_F64:   "VCVT.LE.S32.F64",
+	VCVT_S32_F64:      "VCVT.S32.F64",
+	VCVT_ZZ_S32_F64:   "VCVT.ZZ.S32.F64",
+	VDIV_EQ_F32:       "VDIV.EQ.F32",
+	VDIV_NE_F32:       "VDIV.NE.F32",
+	VDIV_CS_F32:       "VDIV.CS.F32",
+	VDIV_CC_F32:       "VDIV.CC.F32",
+	VDIV_MI_F32:       "VDIV.MI.F32",
+	VDIV_PL_F32:       "VDIV.PL.F32",
+	VDIV_VS_F32:       "VDIV.VS.F32",
+	VDIV_VC_F32:       "VDIV.VC.F32",
+	VDIV_HI_F32:       "VDIV.HI.F32",
+	VDIV_LS_F32:       "VDIV.LS.F32",
+	VDIV_GE_F32:       "VDIV.GE.F32",
+	VDIV_LT_F32:       "VDIV.LT.F32",
+	VDIV_GT_F32:       "VDIV.GT.F32",
+	VDIV_LE_F32:       "VDIV.LE.F32",
+	VDIV_F32:          "VDIV.F32",
+	VDIV_ZZ_F32:       "VDIV.ZZ.F32",
+	VDIV_EQ_F64:       "VDIV.EQ.F64",
+	VDIV_NE_F64:       "VDIV.NE.F64",
+	VDIV_CS_F64:       "VDIV.CS.F64",
+	VDIV_CC_F64:       "VDIV.CC.F64",
+	VDIV_MI_F64:       "VDIV.MI.F64",
+	VDIV_PL_F64:       "VDIV.PL.F64",
+	VDIV_VS_F64:       "VDIV.VS.F64",
+	VDIV_VC_F64:       "VDIV.VC.F64",
+	VDIV_HI_F64:       "VDIV.HI.F64",
+	VDIV_LS_F64:       "VDIV.LS.F64",
+	VDIV_GE_F64:       "VDIV.GE.F64",
+	VDIV_LT_F64:       "VDIV.LT.F64",
+	VDIV_GT_F64:       "VDIV.GT.F64",
+	VDIV_LE_F64:       "VDIV.LE.F64",
+	VDIV_F64:          "VDIV.F64",
+	VDIV_ZZ_F64:       "VDIV.ZZ.F64",
+	VLDR_EQ:           "VLDR.EQ",
+	VLDR_NE:           "VLDR.NE",
+	VLDR_CS:           "VLDR.CS",
+	VLDR_CC:           "VLDR.CC",
+	VLDR_MI:           "VLDR.MI",
+	VLDR_PL:           "VLDR.PL",
+	VLDR_VS:           "VLDR.VS",
+	VLDR_VC:           "VLDR.VC",
+	VLDR_HI:           "VLDR.HI",
+	VLDR_LS:           "VLDR.LS",
+	VLDR_GE:           "VLDR.GE",
+	VLDR_LT:           "VLDR.LT",
+	VLDR_GT:           "VLDR.GT",
+	VLDR_LE:           "VLDR.LE",
+	VLDR:              "VLDR",
+	VLDR_ZZ:           "VLDR.ZZ",
+	VMLA_EQ_F32:       "VMLA.EQ.F32",
+	VMLA_NE_F32:       "VMLA.NE.F32",
+	VMLA_CS_F32:       "VMLA.CS.F32",
+	VMLA_CC_F32:       "VMLA.CC.F32",
+	VMLA_MI_F32:       "VMLA.MI.F32",
+	VMLA_PL_F32:       "VMLA.PL.F32",
+	VMLA_VS_F32:       "VMLA.VS.F32",
+	VMLA_VC_F32:       "VMLA.VC.F32",
+	VMLA_HI_F32:       "VMLA.HI.F32",
+	VMLA_LS_F32:       "VMLA.LS.F32",
+	VMLA_GE_F32:       "VMLA.GE.F32",
+	VMLA_LT_F32:       "VMLA.LT.F32",
+	VMLA_GT_F32:       "VMLA.GT.F32",
+	VMLA_LE_F32:       "VMLA.LE.F32",
+	VMLA_F32:          "VMLA.F32",
+	VMLA_ZZ_F32:       "VMLA.ZZ.F32",
+	VMLA_EQ_F64:       "VMLA.EQ.F64",
+	VMLA_NE_F64:       "VMLA.NE.F64",
+	VMLA_CS_F64:       "VMLA.CS.F64",
+	VMLA_CC_F64:       "VMLA.CC.F64",
+	VMLA_MI_F64:       "VMLA.MI.F64",
+	VMLA_PL_F64:       "VMLA.PL.F64",
+	VMLA_VS_F64:       "VMLA.VS.F64",
+	VMLA_VC_F64:       "VMLA.VC.F64",
+	VMLA_HI_F64:       "VMLA.HI.F64",
+	VMLA_LS_F64:       "VMLA.LS.F64",
+	VMLA_GE_F64:       "VMLA.GE.F64",
+	VMLA_LT_F64:       "VMLA.LT.F64",
+	VMLA_GT_F64:       "VMLA.GT.F64",
+	VMLA_LE_F64:       "VMLA.LE.F64",
+	VMLA_F64:          "VMLA.F64",
+	VMLA_ZZ_F64:       "VMLA.ZZ.F64",
+	VMLS_EQ_F32:       "VMLS.EQ.F32",
+	VMLS_NE_F32:       "VMLS.NE.F32",
+	VMLS_CS_F32:       "VMLS.CS.F32",
+	VMLS_CC_F32:       "VMLS.CC.F32",
+	VMLS_MI_F32:       "VMLS.MI.F32",
+	VMLS_PL_F32:       "VMLS.PL.F32",
+	VMLS_VS_F32:       "VMLS.VS.F32",
+	VMLS_VC_F32:       "VMLS.VC.F32",
+	VMLS_HI_F32:       "VMLS.HI.F32",
+	VMLS_LS_F32:       "VMLS.LS.F32",
+	VMLS_GE_F32:       "VMLS.GE.F32",
+	VMLS_LT_F32:       "VMLS.LT.F32",
+	VMLS_GT_F32:       "VMLS.GT.F32",
+	VMLS_LE_F32:       "VMLS.LE.F32",
+	VMLS_F32:          "VMLS.F32",
+	VMLS_ZZ_F32:       "VMLS.ZZ.F32",
+	VMLS_EQ_F64:       "VMLS.EQ.F64",
+	VMLS_NE_F64:       "VMLS.NE.F64",
+	VMLS_CS_F64:       "VMLS.CS.F64",
+	VMLS_CC_F64:       "VMLS.CC.F64",
+	VMLS_MI_F64:       "VMLS.MI.F64",
+	VMLS_PL_F64:       "VMLS.PL.F64",
+	VMLS_VS_F64:       "VMLS.VS.F64",
+	VMLS_VC_F64:       "VMLS.VC.F64",
+	VMLS_HI_F64:       "VMLS.HI.F64",
+	VMLS_LS_F64:       "VMLS.LS.F64",
+	VMLS_GE_F64:       "VMLS.GE.F64",
+	VMLS_LT_F64:       "VMLS.LT.F64",
+	VMLS_GT_F64:       "VMLS.GT.F64",
+	VMLS_LE_F64:       "VMLS.LE.F64",
+	VMLS_F64:          "VMLS.F64",
+	VMLS_ZZ_F64:       "VMLS.ZZ.F64",
+	VMOV_EQ:           "VMOV.EQ",
+	VMOV_NE:           "VMOV.NE",
+	VMOV_CS:           "VMOV.CS",
+	VMOV_CC:           "VMOV.CC",
+	VMOV_MI:           "VMOV.MI",
+	VMOV_PL:           "VMOV.PL",
+	VMOV_VS:           "VMOV.VS",
+	VMOV_VC:           "VMOV.VC",
+	VMOV_HI:           "VMOV.HI",
+	VMOV_LS:           "VMOV.LS",
+	VMOV_GE:           "VMOV.GE",
+	VMOV_LT:           "VMOV.LT",
+	VMOV_GT:           "VMOV.GT",
+	VMOV_LE:           "VMOV.LE",
+	VMOV:              "VMOV",
+	VMOV_ZZ:           "VMOV.ZZ",
+	VMOV_EQ_32:        "VMOV.EQ.32",
+	VMOV_NE_32:        "VMOV.NE.32",
+	VMOV_CS_32:        "VMOV.CS.32",
+	VMOV_CC_32:        "VMOV.CC.32",
+	VMOV_MI_32:        "VMOV.MI.32",
+	VMOV_PL_32:        "VMOV.PL.32",
+	VMOV_VS_32:        "VMOV.VS.32",
+	VMOV_VC_32:        "VMOV.VC.32",
+	VMOV_HI_32:        "VMOV.HI.32",
+	VMOV_LS_32:        "VMOV.LS.32",
+	VMOV_GE_32:        "VMOV.GE.32",
+	VMOV_LT_32:        "VMOV.LT.32",
+	VMOV_GT_32:        "VMOV.GT.32",
+	VMOV_LE_32:        "VMOV.LE.32",
+	VMOV_32:           "VMOV.32",
+	VMOV_ZZ_32:        "VMOV.ZZ.32",
+	VMOV_EQ_F32:       "VMOV.EQ.F32",
+	VMOV_NE_F32:       "VMOV.NE.F32",
+	VMOV_CS_F32:       "VMOV.CS.F32",
+	VMOV_CC_F32:       "VMOV.CC.F32",
+	VMOV_MI_F32:       "VMOV.MI.F32",
+	VMOV_PL_F32:       "VMOV.PL.F32",
+	VMOV_VS_F32:       "VMOV.VS.F32",
+	VMOV_VC_F32:       "VMOV.VC.F32",
+	VMOV_HI_F32:       "VMOV.HI.F32",
+	VMOV_LS_F32:       "VMOV.LS.F32",
+	VMOV_GE_F32:       "VMOV.GE.F32",
+	VMOV_LT_F32:       "VMOV.LT.F32",
+	VMOV_GT_F32:       "VMOV.GT.F32",
+	VMOV_LE_F32:       "VMOV.LE.F32",
+	VMOV_F32:          "VMOV.F32",
+	VMOV_ZZ_F32:       "VMOV.ZZ.F32",
+	VMOV_EQ_F64:       "VMOV.EQ.F64",
+	VMOV_NE_F64:       "VMOV.NE.F64",
+	VMOV_CS_F64:       "VMOV.CS.F64",
+	VMOV_CC_F64:       "VMOV.CC.F64",
+	VMOV_MI_F64:       "VMOV.MI.F64",
+	VMOV_PL_F64:       "VMOV.PL.F64",
+	VMOV_VS_F64:       "VMOV.VS.F64",
+	VMOV_VC_F64:       "VMOV.VC.F64",
+	VMOV_HI_F64:       "VMOV.HI.F64",
+	VMOV_LS_F64:       "VMOV.LS.F64",
+	VMOV_GE_F64:       "VMOV.GE.F64",
+	VMOV_LT_F64:       "VMOV.LT.F64",
+	VMOV_GT_F64:       "VMOV.GT.F64",
+	VMOV_LE_F64:       "VMOV.LE.F64",
+	VMOV_F64:          "VMOV.F64",
+	VMOV_ZZ_F64:       "VMOV.ZZ.F64",
+	VMRS_EQ:           "VMRS.EQ",
+	VMRS_NE:           "VMRS.NE",
+	VMRS_CS:           "VMRS.CS",
+	VMRS_CC:           "VMRS.CC",
+	VMRS_MI:           "VMRS.MI",
+	VMRS_PL:           "VMRS.PL",
+	VMRS_VS:           "VMRS.VS",
+	VMRS_VC:           "VMRS.VC",
+	VMRS_HI:           "VMRS.HI",
+	VMRS_LS:           "VMRS.LS",
+	VMRS_GE:           "VMRS.GE",
+	VMRS_LT:           "VMRS.LT",
+	VMRS_GT:           "VMRS.GT",
+	VMRS_LE:           "VMRS.LE",
+	VMRS:              "VMRS",
+	VMRS_ZZ:           "VMRS.ZZ",
+	VMSR_EQ:           "VMSR.EQ",
+	VMSR_NE:           "VMSR.NE",
+	VMSR_CS:           "VMSR.CS",
+	VMSR_CC:           "VMSR.CC",
+	VMSR_MI:           "VMSR.MI",
+	VMSR_PL:           "VMSR.PL",
+	VMSR_VS:           "VMSR.VS",
+	VMSR_VC:           "VMSR.VC",
+	VMSR_HI:           "VMSR.HI",
+	VMSR_LS:           "VMSR.LS",
+	VMSR_GE:           "VMSR.GE",
+	VMSR_LT:           "VMSR.LT",
+	VMSR_GT:           "VMSR.GT",
+	VMSR_LE:           "VMSR.LE",
+	VMSR:              "VMSR",
+	VMSR_ZZ:           "VMSR.ZZ",
+	VMUL_EQ_F32:       "VMUL.EQ.F32",
+	VMUL_NE_F32:       "VMUL.NE.F32",
+	VMUL_CS_F32:       "VMUL.CS.F32",
+	VMUL_CC_F32:       "VMUL.CC.F32",
+	VMUL_MI_F32:       "VMUL.MI.F32",
+	VMUL_PL_F32:       "VMUL.PL.F32",
+	VMUL_VS_F32:       "VMUL.VS.F32",
+	VMUL_VC_F32:       "VMUL.VC.F32",
+	VMUL_HI_F32:       "VMUL.HI.F32",
+	VMUL_LS_F32:       "VMUL.LS.F32",
+	VMUL_GE_F32:       "VMUL.GE.F32",
+	VMUL_LT_F32:       "VMUL.LT.F32",
+	VMUL_GT_F32:       "VMUL.GT.F32",
+	VMUL_LE_F32:       "VMUL.LE.F32",
+	VMUL_F32:          "VMUL.F32",
+	VMUL_ZZ_F32:       "VMUL.ZZ.F32",
+	VMUL_EQ_F64:       "VMUL.EQ.F64",
+	VMUL_NE_F64:       "VMUL.NE.F64",
+	VMUL_CS_F64:       "VMUL.CS.F64",
+	VMUL_CC_F64:       "VMUL.CC.F64",
+	VMUL_MI_F64:       "VMUL.MI.F64",
+	VMUL_PL_F64:       "VMUL.PL.F64",
+	VMUL_VS_F64:       "VMUL.VS.F64",
+	VMUL_VC_F64:       "VMUL.VC.F64",
+	VMUL_HI_F64:       "VMUL.HI.F64",
+	VMUL_LS_F64:       "VMUL.LS.F64",
+	VMUL_GE_F64:       "VMUL.GE.F64",
+	VMUL_LT_F64:       "VMUL.LT.F64",
+	VMUL_GT_F64:       "VMUL.GT.F64",
+	VMUL_LE_F64:       "VMUL.LE.F64",
+	VMUL_F64:          "VMUL.F64",
+	VMUL_ZZ_F64:       "VMUL.ZZ.F64",
+	VNEG_EQ_F32:       "VNEG.EQ.F32",
+	VNEG_NE_F32:       "VNEG.NE.F32",
+	VNEG_CS_F32:       "VNEG.CS.F32",
+	VNEG_CC_F32:       "VNEG.CC.F32",
+	VNEG_MI_F32:       "VNEG.MI.F32",
+	VNEG_PL_F32:       "VNEG.PL.F32",
+	VNEG_VS_F32:       "VNEG.VS.F32",
+	VNEG_VC_F32:       "VNEG.VC.F32",
+	VNEG_HI_F32:       "VNEG.HI.F32",
+	VNEG_LS_F32:       "VNEG.LS.F32",
+	VNEG_GE_F32:       "VNEG.GE.F32",
+	VNEG_LT_F32:       "VNEG.LT.F32",
+	VNEG_GT_F32:       "VNEG.GT.F32",
+	VNEG_LE_F32:       "VNEG.LE.F32",
+	VNEG_F32:          "VNEG.F32",
+	VNEG_ZZ_F32:       "VNEG.ZZ.F32",
+	VNEG_EQ_F64:       "VNEG.EQ.F64",
+	VNEG_NE_F64:       "VNEG.NE.F64",
+	VNEG_CS_F64:       "VNEG.CS.F64",
+	VNEG_CC_F64:       "VNEG.CC.F64",
+	VNEG_MI_F64:       "VNEG.MI.F64",
+	VNEG_PL_F64:       "VNEG.PL.F64",
+	VNEG_VS_F64:       "VNEG.VS.F64",
+	VNEG_VC_F64:       "VNEG.VC.F64",
+	VNEG_HI_F64:       "VNEG.HI.F64",
+	VNEG_LS_F64:       "VNEG.LS.F64",
+	VNEG_GE_F64:       "VNEG.GE.F64",
+	VNEG_LT_F64:       "VNEG.LT.F64",
+	VNEG_GT_F64:       "VNEG.GT.F64",
+	VNEG_LE_F64:       "VNEG.LE.F64",
+	VNEG_F64:          "VNEG.F64",
+	VNEG_ZZ_F64:       "VNEG.ZZ.F64",
+	VNMLS_EQ_F32:      "VNMLS.EQ.F32",
+	VNMLS_NE_F32:      "VNMLS.NE.F32",
+	VNMLS_CS_F32:      "VNMLS.CS.F32",
+	VNMLS_CC_F32:      "VNMLS.CC.F32",
+	VNMLS_MI_F32:      "VNMLS.MI.F32",
+	VNMLS_PL_F32:      "VNMLS.PL.F32",
+	VNMLS_VS_F32:      "VNMLS.VS.F32",
+	VNMLS_VC_F32:      "VNMLS.VC.F32",
+	VNMLS_HI_F32:      "VNMLS.HI.F32",
+	VNMLS_LS_F32:      "VNMLS.LS.F32",
+	VNMLS_GE_F32:      "VNMLS.GE.F32",
+	VNMLS_LT_F32:      "VNMLS.LT.F32",
+	VNMLS_GT_F32:      "VNMLS.GT.F32",
+	VNMLS_LE_F32:      "VNMLS.LE.F32",
+	VNMLS_F32:         "VNMLS.F32",
+	VNMLS_ZZ_F32:      "VNMLS.ZZ.F32",
+	VNMLS_EQ_F64:      "VNMLS.EQ.F64",
+	VNMLS_NE_F64:      "VNMLS.NE.F64",
+	VNMLS_CS_F64:      "VNMLS.CS.F64",
+	VNMLS_CC_F64:      "VNMLS.CC.F64",
+	VNMLS_MI_F64:      "VNMLS.MI.F64",
+	VNMLS_PL_F64:      "VNMLS.PL.F64",
+	VNMLS_VS_F64:      "VNMLS.VS.F64",
+	VNMLS_VC_F64:      "VNMLS.VC.F64",
+	VNMLS_HI_F64:      "VNMLS.HI.F64",
+	VNMLS_LS_F64:      "VNMLS.LS.F64",
+	VNMLS_GE_F64:      "VNMLS.GE.F64",
+	VNMLS_LT_F64:      "VNMLS.LT.F64",
+	VNMLS_GT_F64:      "VNMLS.GT.F64",
+	VNMLS_LE_F64:      "VNMLS.LE.F64",
+	VNMLS_F64:         "VNMLS.F64",
+	VNMLS_ZZ_F64:      "VNMLS.ZZ.F64",
+	VNMLA_EQ_F32:      "VNMLA.EQ.F32",
+	VNMLA_NE_F32:      "VNMLA.NE.F32",
+	VNMLA_CS_F32:      "VNMLA.CS.F32",
+	VNMLA_CC_F32:      "VNMLA.CC.F32",
+	VNMLA_MI_F32:      "VNMLA.MI.F32",
+	VNMLA_PL_F32:      "VNMLA.PL.F32",
+	VNMLA_VS_F32:      "VNMLA.VS.F32",
+	VNMLA_VC_F32:      "VNMLA.VC.F32",
+	VNMLA_HI_F32:      "VNMLA.HI.F32",
+	VNMLA_LS_F32:      "VNMLA.LS.F32",
+	VNMLA_GE_F32:      "VNMLA.GE.F32",
+	VNMLA_LT_F32:      "VNMLA.LT.F32",
+	VNMLA_GT_F32:      "VNMLA.GT.F32",
+	VNMLA_LE_F32:      "VNMLA.LE.F32",
+	VNMLA_F32:         "VNMLA.F32",
+	VNMLA_ZZ_F32:      "VNMLA.ZZ.F32",
+	VNMLA_EQ_F64:      "VNMLA.EQ.F64",
+	VNMLA_NE_F64:      "VNMLA.NE.F64",
+	VNMLA_CS_F64:      "VNMLA.CS.F64",
+	VNMLA_CC_F64:      "VNMLA.CC.F64",
+	VNMLA_MI_F64:      "VNMLA.MI.F64",
+	VNMLA_PL_F64:      "VNMLA.PL.F64",
+	VNMLA_VS_F64:      "VNMLA.VS.F64",
+	VNMLA_VC_F64:      "VNMLA.VC.F64",
+	VNMLA_HI_F64:      "VNMLA.HI.F64",
+	VNMLA_LS_F64:      "VNMLA.LS.F64",
+	VNMLA_GE_F64:      "VNMLA.GE.F64",
+	VNMLA_LT_F64:      "VNMLA.LT.F64",
+	VNMLA_GT_F64:      "VNMLA.GT.F64",
+	VNMLA_LE_F64:      "VNMLA.LE.F64",
+	VNMLA_F64:         "VNMLA.F64",
+	VNMLA_ZZ_F64:      "VNMLA.ZZ.F64",
+	VNMUL_EQ_F32:      "VNMUL.EQ.F32",
+	VNMUL_NE_F32:      "VNMUL.NE.F32",
+	VNMUL_CS_F32:      "VNMUL.CS.F32",
+	VNMUL_CC_F32:      "VNMUL.CC.F32",
+	VNMUL_MI_F32:      "VNMUL.MI.F32",
+	VNMUL_PL_F32:      "VNMUL.PL.F32",
+	VNMUL_VS_F32:      "VNMUL.VS.F32",
+	VNMUL_VC_F32:      "VNMUL.VC.F32",
+	VNMUL_HI_F32:      "VNMUL.HI.F32",
+	VNMUL_LS_F32:      "VNMUL.LS.F32",
+	VNMUL_GE_F32:      "VNMUL.GE.F32",
+	VNMUL_LT_F32:      "VNMUL.LT.F32",
+	VNMUL_GT_F32:      "VNMUL.GT.F32",
+	VNMUL_LE_F32:      "VNMUL.LE.F32",
+	VNMUL_F32:         "VNMUL.F32",
+	VNMUL_ZZ_F32:      "VNMUL.ZZ.F32",
+	VNMUL_EQ_F64:      "VNMUL.EQ.F64",
+	VNMUL_NE_F64:      "VNMUL.NE.F64",
+	VNMUL_CS_F64:      "VNMUL.CS.F64",
+	VNMUL_CC_F64:      "VNMUL.CC.F64",
+	VNMUL_MI_F64:      "VNMUL.MI.F64",
+	VNMUL_PL_F64:      "VNMUL.PL.F64",
+	VNMUL_VS_F64:      "VNMUL.VS.F64",
+	VNMUL_VC_F64:      "VNMUL.VC.F64",
+	VNMUL_HI_F64:      "VNMUL.HI.F64",
+	VNMUL_LS_F64:      "VNMUL.LS.F64",
+	VNMUL_GE_F64:      "VNMUL.GE.F64",
+	VNMUL_LT_F64:      "VNMUL.LT.F64",
+	VNMUL_GT_F64:      "VNMUL.GT.F64",
+	VNMUL_LE_F64:      "VNMUL.LE.F64",
+	VNMUL_F64:         "VNMUL.F64",
+	VNMUL_ZZ_F64:      "VNMUL.ZZ.F64",
+	VSQRT_EQ_F32:      "VSQRT.EQ.F32",
+	VSQRT_NE_F32:      "VSQRT.NE.F32",
+	VSQRT_CS_F32:      "VSQRT.CS.F32",
+	VSQRT_CC_F32:      "VSQRT.CC.F32",
+	VSQRT_MI_F32:      "VSQRT.MI.F32",
+	VSQRT_PL_F32:      "VSQRT.PL.F32",
+	VSQRT_VS_F32:      "VSQRT.VS.F32",
+	VSQRT_VC_F32:      "VSQRT.VC.F32",
+	VSQRT_HI_F32:      "VSQRT.HI.F32",
+	VSQRT_LS_F32:      "VSQRT.LS.F32",
+	VSQRT_GE_F32:      "VSQRT.GE.F32",
+	VSQRT_LT_F32:      "VSQRT.LT.F32",
+	VSQRT_GT_F32:      "VSQRT.GT.F32",
+	VSQRT_LE_F32:      "VSQRT.LE.F32",
+	VSQRT_F32:         "VSQRT.F32",
+	VSQRT_ZZ_F32:      "VSQRT.ZZ.F32",
+	VSQRT_EQ_F64:      "VSQRT.EQ.F64",
+	VSQRT_NE_F64:      "VSQRT.NE.F64",
+	VSQRT_CS_F64:      "VSQRT.CS.F64",
+	VSQRT_CC_F64:      "VSQRT.CC.F64",
+	VSQRT_MI_F64:      "VSQRT.MI.F64",
+	VSQRT_PL_F64:      "VSQRT.PL.F64",
+	VSQRT_VS_F64:      "VSQRT.VS.F64",
+	VSQRT_VC_F64:      "VSQRT.VC.F64",
+	VSQRT_HI_F64:      "VSQRT.HI.F64",
+	VSQRT_LS_F64:      "VSQRT.LS.F64",
+	VSQRT_GE_F64:      "VSQRT.GE.F64",
+	VSQRT_LT_F64:      "VSQRT.LT.F64",
+	VSQRT_GT_F64:      "VSQRT.GT.F64",
+	VSQRT_LE_F64:      "VSQRT.LE.F64",
+	VSQRT_F64:         "VSQRT.F64",
+	VSQRT_ZZ_F64:      "VSQRT.ZZ.F64",
+	VSTR_EQ:           "VSTR.EQ",
+	VSTR_NE:           "VSTR.NE",
+	VSTR_CS:           "VSTR.CS",
+	VSTR_CC:           "VSTR.CC",
+	VSTR_MI:           "VSTR.MI",
+	VSTR_PL:           "VSTR.PL",
+	VSTR_VS:           "VSTR.VS",
+	VSTR_VC:           "VSTR.VC",
+	VSTR_HI:           "VSTR.HI",
+	VSTR_LS:           "VSTR.LS",
+	VSTR_GE:           "VSTR.GE",
+	VSTR_LT:           "VSTR.LT",
+	VSTR_GT:           "VSTR.GT",
+	VSTR_LE:           "VSTR.LE",
+	VSTR:              "VSTR",
+	VSTR_ZZ:           "VSTR.ZZ",
+	VSUB_EQ_F32:       "VSUB.EQ.F32",
+	VSUB_NE_F32:       "VSUB.NE.F32",
+	VSUB_CS_F32:       "VSUB.CS.F32",
+	VSUB_CC_F32:       "VSUB.CC.F32",
+	VSUB_MI_F32:       "VSUB.MI.F32",
+	VSUB_PL_F32:       "VSUB.PL.F32",
+	VSUB_VS_F32:       "VSUB.VS.F32",
+	VSUB_VC_F32:       "VSUB.VC.F32",
+	VSUB_HI_F32:       "VSUB.HI.F32",
+	VSUB_LS_F32:       "VSUB.LS.F32",
+	VSUB_GE_F32:       "VSUB.GE.F32",
+	VSUB_LT_F32:       "VSUB.LT.F32",
+	VSUB_GT_F32:       "VSUB.GT.F32",
+	VSUB_LE_F32:       "VSUB.LE.F32",
+	VSUB_F32:          "VSUB.F32",
+	VSUB_ZZ_F32:       "VSUB.ZZ.F32",
+	VSUB_EQ_F64:       "VSUB.EQ.F64",
+	VSUB_NE_F64:       "VSUB.NE.F64",
+	VSUB_CS_F64:       "VSUB.CS.F64",
+	VSUB_CC_F64:       "VSUB.CC.F64",
+	VSUB_MI_F64:       "VSUB.MI.F64",
+	VSUB_PL_F64:       "VSUB.PL.F64",
+	VSUB_VS_F64:       "VSUB.VS.F64",
+	VSUB_VC_F64:       "VSUB.VC.F64",
+	VSUB_HI_F64:       "VSUB.HI.F64",
+	VSUB_LS_F64:       "VSUB.LS.F64",
+	VSUB_GE_F64:       "VSUB.GE.F64",
+	VSUB_LT_F64:       "VSUB.LT.F64",
+	VSUB_GT_F64:       "VSUB.GT.F64",
+	VSUB_LE_F64:       "VSUB.LE.F64",
+	VSUB_F64:          "VSUB.F64",
+	VSUB_ZZ_F64:       "VSUB.ZZ.F64",
+	WFE_EQ:            "WFE.EQ",
+	WFE_NE:            "WFE.NE",
+	WFE_CS:            "WFE.CS",
+	WFE_CC:            "WFE.CC",
+	WFE_MI:            "WFE.MI",
+	WFE_PL:            "WFE.PL",
+	WFE_VS:            "WFE.VS",
+	WFE_VC:            "WFE.VC",
+	WFE_HI:            "WFE.HI",
+	WFE_LS:            "WFE.LS",
+	WFE_GE:            "WFE.GE",
+	WFE_LT:            "WFE.LT",
+	WFE_GT:            "WFE.GT",
+	WFE_LE:            "WFE.LE",
+	WFE:               "WFE",
+	WFE_ZZ:            "WFE.ZZ",
+	WFI_EQ:            "WFI.EQ",
+	WFI_NE:            "WFI.NE",
+	WFI_CS:            "WFI.CS",
+	WFI_CC:            "WFI.CC",
+	WFI_MI:            "WFI.MI",
+	WFI_PL:            "WFI.PL",
+	WFI_VS:            "WFI.VS",
+	WFI_VC:            "WFI.VC",
+	WFI_HI:            "WFI.HI",
+	WFI_LS:            "WFI.LS",
+	WFI_GE:            "WFI.GE",
+	WFI_LT:            "WFI.LT",
+	WFI_GT:            "WFI.GT",
+	WFI_LE:            "WFI.LE",
+	WFI:               "WFI",
+	WFI_ZZ:            "WFI.ZZ",
+	YIELD_EQ:          "YIELD.EQ",
+	YIELD_NE:          "YIELD.NE",
+	YIELD_CS:          "YIELD.CS",
+	YIELD_CC:          "YIELD.CC",
+	YIELD_MI:          "YIELD.MI",
+	YIELD_PL:          "YIELD.PL",
+	YIELD_VS:          "YIELD.VS",
+	YIELD_VC:          "YIELD.VC",
+	YIELD_HI:          "YIELD.HI",
+	YIELD_LS:          "YIELD.LS",
+	YIELD_GE:          "YIELD.GE",
+	YIELD_LT:          "YIELD.LT",
+	YIELD_GT:          "YIELD.GT",
+	YIELD_LE:          "YIELD.LE",
+	YIELD:             "YIELD",
+	YIELD_ZZ:          "YIELD.ZZ",
+}
+
+var instFormats = [...]instFormat{
+	{0x0fe00000, 0x02a00000, 2, ADC_EQ, 0x14011c04, instArgs{arg_R_12, arg_R_16, arg_const}},                      // ADC{S}<c> <Rd>,<Rn>,#<const> cond:4|0|0|1|0|1|0|1|S|Rn:4|Rd:4|imm12:12
+	{0x0fe00090, 0x00a00010, 4, ADC_EQ, 0x14011c04, instArgs{arg_R_12, arg_R_16, arg_R_shift_R}},                  // ADC{S}<c> <Rd>,<Rn>,<Rm>,<type> <Rs> cond:4|0|0|0|0|1|0|1|S|Rn:4|Rd:4|Rs:4|0|type:2|1|Rm:4
+	{0x0fe00010, 0x00a00000, 2, ADC_EQ, 0x14011c04, instArgs{arg_R_12, arg_R_16, arg_R_shift_imm}},                // ADC{S}<c> <Rd>,<Rn>,<Rm>{,<shift>} cond:4|0|0|0|0|1|0|1|S|Rn:4|Rd:4|imm5:5|type:2|0|Rm:4
+	{0x0fe00000, 0x02800000, 2, ADD_EQ, 0x14011c04, instArgs{arg_R_12, arg_R_16, arg_const}},                      // ADD{S}<c> <Rd>,<Rn>,#<const> cond:4|0|0|1|0|1|0|0|S|Rn:4|Rd:4|imm12:12
+	{0x0fe00090, 0x00800010, 4, ADD_EQ, 0x14011c04, instArgs{arg_R_12, arg_R_16, arg_R_shift_R}},                  // ADD{S}<c> <Rd>,<Rn>,<Rm>,<type> <Rs> cond:4|0|0|0|0|1|0|0|S|Rn:4|Rd:4|Rs:4|0|type:2|1|Rm:4
+	{0x0fe00010, 0x00800000, 2, ADD_EQ, 0x14011c04, instArgs{arg_R_12, arg_R_16, arg_R_shift_imm}},                // ADD{S}<c> <Rd>,<Rn>,<Rm>{,<shift>} cond:4|0|0|0|0|1|0|0|S|Rn:4|Rd:4|imm5:5|type:2|0|Rm:4
+	{0x0fef0000, 0x028d0000, 2, ADD_EQ, 0x14011c04, instArgs{arg_R_12, arg_SP, arg_const}},                        // ADD{S}<c> <Rd>,SP,#<const> cond:4|0|0|1|0|1|0|0|S|1|1|0|1|Rd:4|imm12:12
+	{0x0fef0010, 0x008d0000, 2, ADD_EQ, 0x14011c04, instArgs{arg_R_12, arg_SP, arg_R_shift_imm}},                  // ADD{S}<c> <Rd>,SP,<Rm>{,<shift>} cond:4|0|0|0|0|1|0|0|S|1|1|0|1|Rd:4|imm5:5|type:2|0|Rm:4
+	{0x0fe00000, 0x02000000, 2, AND_EQ, 0x14011c04, instArgs{arg_R_12, arg_R_16, arg_const}},                      // AND{S}<c> <Rd>,<Rn>,#<const> cond:4|0|0|1|0|0|0|0|S|Rn:4|Rd:4|imm12:12
+	{0x0fe00090, 0x00000010, 4, AND_EQ, 0x14011c04, instArgs{arg_R_12, arg_R_16, arg_R_shift_R}},                  // AND{S}<c> <Rd>,<Rn>,<Rm>,<type> <Rs> cond:4|0|0|0|0|0|0|0|S|Rn:4|Rd:4|Rs:4|0|type:2|1|Rm:4
+	{0x0fe00010, 0x00000000, 2, AND_EQ, 0x14011c04, instArgs{arg_R_12, arg_R_16, arg_R_shift_imm}},                // AND{S}<c> <Rd>,<Rn>,<Rm>{,<shift>} cond:4|0|0|0|0|0|0|0|S|Rn:4|Rd:4|imm5:5|type:2|0|Rm:4
+	{0x0fef0070, 0x01a00040, 4, ASR_EQ, 0x14011c04, instArgs{arg_R_12, arg_R_0, arg_imm5_32}},                     // ASR{S}<c> <Rd>,<Rm>,#<imm5_32> cond:4|0|0|0|1|1|0|1|S|0|0|0|0|Rd:4|imm5:5|1|0|0|Rm:4
+	{0x0fef00f0, 0x01a00050, 4, ASR_EQ, 0x14011c04, instArgs{arg_R_12, arg_R_0, arg_R_8}},                         // ASR{S}<c> <Rd>,<Rn>,<Rm> cond:4|0|0|0|1|1|0|1|S|0|0|0|0|Rd:4|Rm:4|0|1|0|1|Rn:4
+	{0x0f000000, 0x0a000000, 4, B_EQ, 0x1c04, instArgs{arg_label24}},                                              // B<c> <label24> cond:4|1|0|1|0|imm24:24
+	{0x0fe0007f, 0x07c0001f, 4, BFC_EQ, 0x1c04, instArgs{arg_R_12, arg_imm5, arg_lsb_width}},                      // BFC<c> <Rd>,#<lsb>,#<width> cond:4|0|1|1|1|1|1|0|msb:5|Rd:4|lsb:5|0|0|1|1|1|1|1
+	{0x0fe00070, 0x07c00010, 2, BFI_EQ, 0x1c04, instArgs{arg_R_12, arg_R_0, arg_imm5, arg_lsb_width}},             // BFI<c> <Rd>,<Rn>,#<lsb>,#<width> cond:4|0|1|1|1|1|1|0|msb:5|Rd:4|lsb:5|0|0|1|Rn:4
+	{0x0fe00000, 0x03c00000, 2, BIC_EQ, 0x14011c04, instArgs{arg_R_12, arg_R_16, arg_const}},                      // BIC{S}<c> <Rd>,<Rn>,#<const> cond:4|0|0|1|1|1|1|0|S|Rn:4|Rd:4|imm12:12
+	{0x0fe00090, 0x01c00010, 4, BIC_EQ, 0x14011c04, instArgs{arg_R_12, arg_R_16, arg_R_shift_R}},                  // BIC{S}<c> <Rd>,<Rn>,<Rm>,<type> <Rs> cond:4|0|0|0|1|1|1|0|S|Rn:4|Rd:4|Rs:4|0|type:2|1|Rm:4
+	{0x0fe00010, 0x01c00000, 2, BIC_EQ, 0x14011c04, instArgs{arg_R_12, arg_R_16, arg_R_shift_imm}},                // BIC{S}<c> <Rd>,<Rn>,<Rm>{,<shift>} cond:4|0|0|0|1|1|1|0|S|Rn:4|Rd:4|imm5:5|type:2|0|Rm:4
+	{0x0ff000f0, 0x01200070, 4, BKPT_EQ, 0x1c04, instArgs{arg_imm_12at8_4at0}},                                    // BKPT<c> #<imm12+4> cond:4|0|0|0|1|0|0|1|0|imm12:12|0|1|1|1|imm4:4
+	{0x0f000000, 0x0b000000, 4, BL_EQ, 0x1c04, instArgs{arg_label24}},                                             // BL<c> <label24> cond:4|1|0|1|1|imm24:24
+	{0xfe000000, 0xfa000000, 4, BLX, 0x0, instArgs{arg_label24H}},                                                 // BLX <label24H> 1|1|1|1|1|0|1|H|imm24:24
+	{0x0ffffff0, 0x012fff30, 4, BLX_EQ, 0x1c04, instArgs{arg_R_0}},                                                // BLX<c> <Rm> cond:4|0|0|0|1|0|0|1|0|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|0|0|1|1|Rm:4
+	{0x0ff000f0, 0x012fff30, 3, BLX_EQ, 0x1c04, instArgs{arg_R_0}},                                                // BLX<c> <Rm> cond:4|0|0|0|1|0|0|1|0|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|0|0|1|1|Rm:4
+	{0x0ffffff0, 0x012fff10, 4, BX_EQ, 0x1c04, instArgs{arg_R_0}},                                                 // BX<c> <Rm> cond:4|0|0|0|1|0|0|1|0|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|0|0|0|1|Rm:4
+	{0x0ff000f0, 0x012fff10, 3, BX_EQ, 0x1c04, instArgs{arg_R_0}},                                                 // BX<c> <Rm> cond:4|0|0|0|1|0|0|1|0|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|0|0|0|1|Rm:4
+	{0x0ffffff0, 0x012fff20, 4, BXJ_EQ, 0x1c04, instArgs{arg_R_0}},                                                // BXJ<c> <Rm> cond:4|0|0|0|1|0|0|1|0|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|0|0|1|0|Rm:4
+	{0x0ff000f0, 0x012fff20, 3, BXJ_EQ, 0x1c04, instArgs{arg_R_0}},                                                // BXJ<c> <Rm> cond:4|0|0|0|1|0|0|1|0|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|0|0|1|0|Rm:4
+	{0xffffffff, 0xf57ff01f, 4, CLREX, 0x0, instArgs{}},                                                           // CLREX 1|1|1|1|0|1|0|1|0|1|1|1|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(0)|(0)|(0)|(0)|0|0|0|1|(1)|(1)|(1)|(1)
+	{0xfff000f0, 0xf57ff01f, 3, CLREX, 0x0, instArgs{}},                                                           // CLREX 1|1|1|1|0|1|0|1|0|1|1|1|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(0)|(0)|(0)|(0)|0|0|0|1|(1)|(1)|(1)|(1)
+	{0x0fff0ff0, 0x016f0f10, 4, CLZ_EQ, 0x1c04, instArgs{arg_R_12, arg_R_0}},                                      // CLZ<c> <Rd>,<Rm> cond:4|0|0|0|1|0|1|1|0|(1)|(1)|(1)|(1)|Rd:4|(1)|(1)|(1)|(1)|0|0|0|1|Rm:4
+	{0x0ff000f0, 0x016f0f10, 3, CLZ_EQ, 0x1c04, instArgs{arg_R_12, arg_R_0}},                                      // CLZ<c> <Rd>,<Rm> cond:4|0|0|0|1|0|1|1|0|(1)|(1)|(1)|(1)|Rd:4|(1)|(1)|(1)|(1)|0|0|0|1|Rm:4
+	{0x0ff0f000, 0x03700000, 4, CMN_EQ, 0x1c04, instArgs{arg_R_16, arg_const}},                                    // CMN<c> <Rn>,#<const> cond:4|0|0|1|1|0|1|1|1|Rn:4|(0)|(0)|(0)|(0)|imm12:12
+	{0x0ff00000, 0x03700000, 3, CMN_EQ, 0x1c04, instArgs{arg_R_16, arg_const}},                                    // CMN<c> <Rn>,#<const> cond:4|0|0|1|1|0|1|1|1|Rn:4|(0)|(0)|(0)|(0)|imm12:12
+	{0x0ff0f090, 0x01700010, 4, CMN_EQ, 0x1c04, instArgs{arg_R_16, arg_R_shift_R}},                                // CMN<c> <Rn>,<Rm>,<type> <Rs> cond:4|0|0|0|1|0|1|1|1|Rn:4|(0)|(0)|(0)|(0)|Rs:4|0|type:2|1|Rm:4
+	{0x0ff00090, 0x01700010, 3, CMN_EQ, 0x1c04, instArgs{arg_R_16, arg_R_shift_R}},                                // CMN<c> <Rn>,<Rm>,<type> <Rs> cond:4|0|0|0|1|0|1|1|1|Rn:4|(0)|(0)|(0)|(0)|Rs:4|0|type:2|1|Rm:4
+	{0x0ff0f010, 0x01700000, 4, CMN_EQ, 0x1c04, instArgs{arg_R_16, arg_R_shift_imm}},                              // CMN<c> <Rn>,<Rm>{,<shift>} cond:4|0|0|0|1|0|1|1|1|Rn:4|(0)|(0)|(0)|(0)|imm5:5|type:2|0|Rm:4
+	{0x0ff00010, 0x01700000, 3, CMN_EQ, 0x1c04, instArgs{arg_R_16, arg_R_shift_imm}},                              // CMN<c> <Rn>,<Rm>{,<shift>} cond:4|0|0|0|1|0|1|1|1|Rn:4|(0)|(0)|(0)|(0)|imm5:5|type:2|0|Rm:4
+	{0x0ff0f000, 0x03500000, 4, CMP_EQ, 0x1c04, instArgs{arg_R_16, arg_const}},                                    // CMP<c> <Rn>,#<const> cond:4|0|0|1|1|0|1|0|1|Rn:4|(0)|(0)|(0)|(0)|imm12:12
+	{0x0ff00000, 0x03500000, 3, CMP_EQ, 0x1c04, instArgs{arg_R_16, arg_const}},                                    // CMP<c> <Rn>,#<const> cond:4|0|0|1|1|0|1|0|1|Rn:4|(0)|(0)|(0)|(0)|imm12:12
+	{0x0ff0f090, 0x01500010, 4, CMP_EQ, 0x1c04, instArgs{arg_R_16, arg_R_shift_R}},                                // CMP<c> <Rn>,<Rm>,<type> <Rs> cond:4|0|0|0|1|0|1|0|1|Rn:4|(0)|(0)|(0)|(0)|Rs:4|0|type:2|1|Rm:4
+	{0x0ff00090, 0x01500010, 3, CMP_EQ, 0x1c04, instArgs{arg_R_16, arg_R_shift_R}},                                // CMP<c> <Rn>,<Rm>,<type> <Rs> cond:4|0|0|0|1|0|1|0|1|Rn:4|(0)|(0)|(0)|(0)|Rs:4|0|type:2|1|Rm:4
+	{0x0ff0f010, 0x01500000, 4, CMP_EQ, 0x1c04, instArgs{arg_R_16, arg_R_shift_imm}},                              // CMP<c> <Rn>,<Rm>{,<shift>} cond:4|0|0|0|1|0|1|0|1|Rn:4|(0)|(0)|(0)|(0)|imm5:5|type:2|0|Rm:4
+	{0x0ff00010, 0x01500000, 3, CMP_EQ, 0x1c04, instArgs{arg_R_16, arg_R_shift_imm}},                              // CMP<c> <Rn>,<Rm>{,<shift>} cond:4|0|0|0|1|0|1|0|1|Rn:4|(0)|(0)|(0)|(0)|imm5:5|type:2|0|Rm:4
+	{0x0ffffff0, 0x0320f0f0, 4, DBG_EQ, 0x1c04, instArgs{arg_option}},                                             // DBG<c> #<option> cond:4|0|0|1|1|0|0|1|0|0|0|0|0|(1)|(1)|(1)|(1)|(0)|(0)|(0)|(0)|1|1|1|1|option:4
+	{0x0fff00f0, 0x0320f0f0, 3, DBG_EQ, 0x1c04, instArgs{arg_option}},                                             // DBG<c> #<option> cond:4|0|0|1|1|0|0|1|0|0|0|0|0|(1)|(1)|(1)|(1)|(0)|(0)|(0)|(0)|1|1|1|1|option:4
+	{0xfffffff0, 0xf57ff050, 4, DMB, 0x0, instArgs{arg_option}},                                                   // DMB #<option> 1|1|1|1|0|1|0|1|0|1|1|1|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(0)|(0)|(0)|(0)|0|1|0|1|option:4
+	{0xfff000f0, 0xf57ff050, 3, DMB, 0x0, instArgs{arg_option}},                                                   // DMB #<option> 1|1|1|1|0|1|0|1|0|1|1|1|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(0)|(0)|(0)|(0)|0|1|0|1|option:4
+	{0xfffffff0, 0xf57ff040, 4, DSB, 0x0, instArgs{arg_option}},                                                   // DSB #<option> 1|1|1|1|0|1|0|1|0|1|1|1|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(0)|(0)|(0)|(0)|0|1|0|0|option:4
+	{0xfff000f0, 0xf57ff040, 3, DSB, 0x0, instArgs{arg_option}},                                                   // DSB #<option> 1|1|1|1|0|1|0|1|0|1|1|1|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(0)|(0)|(0)|(0)|0|1|0|0|option:4
+	{0x0fe00000, 0x02200000, 2, EOR_EQ, 0x14011c04, instArgs{arg_R_12, arg_R_16, arg_const}},                      // EOR{S}<c> <Rd>,<Rn>,#<const> cond:4|0|0|1|0|0|0|1|S|Rn:4|Rd:4|imm12:12
+	{0x0fe00090, 0x00200010, 4, EOR_EQ, 0x14011c04, instArgs{arg_R_12, arg_R_16, arg_R_shift_R}},                  // EOR{S}<c> <Rd>,<Rn>,<Rm>,<type> <Rs> cond:4|0|0|0|0|0|0|1|S|Rn:4|Rd:4|Rs:4|0|type:2|1|Rm:4
+	{0x0fe00010, 0x00200000, 2, EOR_EQ, 0x14011c04, instArgs{arg_R_12, arg_R_16, arg_R_shift_imm}},                // EOR{S}<c> <Rd>,<Rn>,<Rm>{,<shift>} cond:4|0|0|0|0|0|0|1|S|Rn:4|Rd:4|imm5:5|type:2|0|Rm:4
+	{0xfffffff0, 0xf57ff060, 4, ISB, 0x0, instArgs{arg_option}},                                                   // ISB #<option> 1|1|1|1|0|1|0|1|0|1|1|1|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(0)|(0)|(0)|(0)|0|1|1|0|option:4
+	{0xfff000f0, 0xf57ff060, 3, ISB, 0x0, instArgs{arg_option}},                                                   // ISB #<option> 1|1|1|1|0|1|0|1|0|1|1|1|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(0)|(0)|(0)|(0)|0|1|1|0|option:4
+	{0x0fd00000, 0x08900000, 2, LDM_EQ, 0x1c04, instArgs{arg_R_16_WB, arg_registers}},                             // LDM<c> <Rn>{!},<registers> cond:4|1|0|0|0|1|0|W|1|Rn:4|register_list:16
+	{0x0fd00000, 0x08100000, 4, LDMDA_EQ, 0x1c04, instArgs{arg_R_16_WB, arg_registers}},                           // LDMDA<c> <Rn>{!},<registers> cond:4|1|0|0|0|0|0|W|1|Rn:4|register_list:16
+	{0x0fd00000, 0x09100000, 4, LDMDB_EQ, 0x1c04, instArgs{arg_R_16_WB, arg_registers}},                           // LDMDB<c> <Rn>{!},<registers> cond:4|1|0|0|1|0|0|W|1|Rn:4|register_list:16
+	{0x0fd00000, 0x09900000, 4, LDMIB_EQ, 0x1c04, instArgs{arg_R_16_WB, arg_registers}},                           // LDMIB<c> <Rn>{!},<registers> cond:4|1|0|0|1|1|0|W|1|Rn:4|register_list:16
+	{0x0f7f0000, 0x051f0000, 4, LDR_EQ, 0x1c04, instArgs{arg_R_12, arg_label_pm_12}},                              // LDR<c> <Rt>,<label+/-12> cond:4|0|1|0|(1)|U|0|(0)|1|1|1|1|1|Rt:4|imm12:12
+	{0x0e5f0000, 0x051f0000, 3, LDR_EQ, 0x1c04, instArgs{arg_R_12, arg_label_pm_12}},                              // LDR<c> <Rt>,<label+/-12> cond:4|0|1|0|(1)|U|0|(0)|1|1|1|1|1|Rt:4|imm12:12
+	{0x0e500010, 0x06100000, 2, LDR_EQ, 0x1c04, instArgs{arg_R_12, arg_mem_R_pm_R_shift_imm_W}},                   // LDR<c> <Rt>,[<Rn>,+/-<Rm>{, <shift>}]{!} cond:4|0|1|1|P|U|0|W|1|Rn:4|Rt:4|imm5:5|type:2|0|Rm:4
+	{0x0e500000, 0x04100000, 2, LDR_EQ, 0x1c04, instArgs{arg_R_12, arg_mem_R_pm_imm12_W}},                         // LDR<c> <Rt>,[<Rn>{,#+/-<imm12>}]{!} cond:4|0|1|0|P|U|0|W|1|Rn:4|Rt:4|imm12:12
+	{0x0f7f0000, 0x055f0000, 4, LDRB_EQ, 0x1c04, instArgs{arg_R_12, arg_label_pm_12}},                             // LDRB<c> <Rt>,<label+/-12> cond:4|0|1|0|(1)|U|1|(0)|1|1|1|1|1|Rt:4|imm12:12
+	{0x0e5f0000, 0x055f0000, 3, LDRB_EQ, 0x1c04, instArgs{arg_R_12, arg_label_pm_12}},                             // LDRB<c> <Rt>,<label+/-12> cond:4|0|1|0|(1)|U|1|(0)|1|1|1|1|1|Rt:4|imm12:12
+	{0x0e500010, 0x06500000, 2, LDRB_EQ, 0x1c04, instArgs{arg_R_12, arg_mem_R_pm_R_shift_imm_W}},                  // LDRB<c> <Rt>,[<Rn>,+/-<Rm>{, <shift>}]{!} cond:4|0|1|1|P|U|1|W|1|Rn:4|Rt:4|imm5:5|type:2|0|Rm:4
+	{0x0e500000, 0x04500000, 2, LDRB_EQ, 0x1c04, instArgs{arg_R_12, arg_mem_R_pm_imm12_W}},                        // LDRB<c> <Rt>,[<Rn>{,#+/-<imm12>}]{!} cond:4|0|1|0|P|U|1|W|1|Rn:4|Rt:4|imm12:12
+	{0x0f700000, 0x04700000, 4, LDRBT_EQ, 0x1c04, instArgs{arg_R_12, arg_mem_R_pm_imm12_postindex}},               // LDRBT<c> <Rt>,[<Rn>],#+/-<imm12> cond:4|0|1|0|0|U|1|1|1|Rn:4|Rt:4|imm12:12
+	{0x0f700010, 0x06700000, 4, LDRBT_EQ, 0x1c04, instArgs{arg_R_12, arg_mem_R_pm_R_shift_imm_postindex}},         // LDRBT<c> <Rt>,[<Rn>],+/-<Rm>{, <shift>} cond:4|0|1|1|0|U|1|1|1|Rn:4|Rt:4|imm5:5|type:2|0|Rm:4
+	{0x0e500ff0, 0x000000d0, 4, LDRD_EQ, 0x1c04, instArgs{arg_R1_12, arg_R2_12, arg_mem_R_pm_R_W}},                // LDRD<c> <Rt1>,<Rt2>,[<Rn>,+/-<Rm>]{!} cond:4|0|0|0|P|U|0|W|0|Rn:4|Rt:4|(0)|(0)|(0)|(0)|1|1|0|1|Rm:4
+	{0x0e5000f0, 0x000000d0, 3, LDRD_EQ, 0x1c04, instArgs{arg_R1_12, arg_R2_12, arg_mem_R_pm_R_W}},                // LDRD<c> <Rt1>,<Rt2>,[<Rn>,+/-<Rm>]{!} cond:4|0|0|0|P|U|0|W|0|Rn:4|Rt:4|(0)|(0)|(0)|(0)|1|1|0|1|Rm:4
+	{0x0e5000f0, 0x004000d0, 2, LDRD_EQ, 0x1c04, instArgs{arg_R1_12, arg_R2_12, arg_mem_R_pm_imm8_W}},             // LDRD<c> <Rt1>,<Rt2>,[<Rn>{,#+/-<imm8>}]{!} cond:4|0|0|0|P|U|1|W|0|Rn:4|Rt:4|imm4H:4|1|1|0|1|imm4L:4
+	{0x0ff00fff, 0x01900f9f, 4, LDREX_EQ, 0x1c04, instArgs{arg_R_12, arg_mem_R}},                                  // LDREX<c> <Rt>,[<Rn>] cond:4|0|0|0|1|1|0|0|1|Rn:4|Rt:4|(1)|(1)|(1)|(1)|1|0|0|1|(1)|(1)|(1)|(1)
+	{0x0ff000f0, 0x01900f9f, 3, LDREX_EQ, 0x1c04, instArgs{arg_R_12, arg_mem_R}},                                  // LDREX<c> <Rt>,[<Rn>] cond:4|0|0|0|1|1|0|0|1|Rn:4|Rt:4|(1)|(1)|(1)|(1)|1|0|0|1|(1)|(1)|(1)|(1)
+	{0x0ff00fff, 0x01d00f9f, 4, LDREXB_EQ, 0x1c04, instArgs{arg_R_12, arg_mem_R}},                                 // LDREXB<c> <Rt>, [<Rn>] cond:4|0|0|0|1|1|1|0|1|Rn:4|Rt:4|(1)|(1)|(1)|(1)|1|0|0|1|(1)|(1)|(1)|(1)
+	{0x0ff000f0, 0x01d00f9f, 3, LDREXB_EQ, 0x1c04, instArgs{arg_R_12, arg_mem_R}},                                 // LDREXB<c> <Rt>, [<Rn>] cond:4|0|0|0|1|1|1|0|1|Rn:4|Rt:4|(1)|(1)|(1)|(1)|1|0|0|1|(1)|(1)|(1)|(1)
+	{0x0ff00fff, 0x01b00f9f, 4, LDREXD_EQ, 0x1c04, instArgs{arg_R1_12, arg_R2_12, arg_mem_R}},                     // LDREXD<c> <Rt1>,<Rt2>,[<Rn>] cond:4|0|0|0|1|1|0|1|1|Rn:4|Rt:4|(1)|(1)|(1)|(1)|1|0|0|1|(1)|(1)|(1)|(1)
+	{0x0ff000f0, 0x01b00f9f, 3, LDREXD_EQ, 0x1c04, instArgs{arg_R1_12, arg_R2_12, arg_mem_R}},                     // LDREXD<c> <Rt1>,<Rt2>,[<Rn>] cond:4|0|0|0|1|1|0|1|1|Rn:4|Rt:4|(1)|(1)|(1)|(1)|1|0|0|1|(1)|(1)|(1)|(1)
+	{0x0ff00fff, 0x01f00f9f, 4, LDREXH_EQ, 0x1c04, instArgs{arg_R_12, arg_mem_R}},                                 // LDREXH<c> <Rt>, [<Rn>] cond:4|0|0|0|1|1|1|1|1|Rn:4|Rt:4|(1)|(1)|(1)|(1)|1|0|0|1|(1)|(1)|(1)|(1)
+	{0x0ff000f0, 0x01f00f9f, 3, LDREXH_EQ, 0x1c04, instArgs{arg_R_12, arg_mem_R}},                                 // LDREXH<c> <Rt>, [<Rn>] cond:4|0|0|0|1|1|1|1|1|Rn:4|Rt:4|(1)|(1)|(1)|(1)|1|0|0|1|(1)|(1)|(1)|(1)
+	{0x0e500ff0, 0x001000b0, 2, LDRH_EQ, 0x1c04, instArgs{arg_R_12, arg_mem_R_pm_R_W}},                            // LDRH<c> <Rt>,[<Rn>,+/-<Rm>]{!} cond:4|0|0|0|P|U|0|W|1|Rn:4|Rt:4|0|0|0|0|1|0|1|1|Rm:4
+	{0x0e5000f0, 0x005000b0, 2, LDRH_EQ, 0x1c04, instArgs{arg_R_12, arg_mem_R_pm_imm8_W}},                         // LDRH<c> <Rt>,[<Rn>{,#+/-<imm8>}]{!} cond:4|0|0|0|P|U|1|W|1|Rn:4|Rt:4|imm4H:4|1|0|1|1|imm4L:4
+	{0x0f7000f0, 0x007000b0, 4, LDRHT_EQ, 0x1c04, instArgs{arg_R_12, arg_mem_R_pm_imm8_postindex}},                // LDRHT<c> <Rt>, [<Rn>] {,#+/-<imm8>} cond:4|0|0|0|0|U|1|1|1|Rn:4|Rt:4|imm4H:4|1|0|1|1|imm4L:4
+	{0x0f700ff0, 0x003000b0, 4, LDRHT_EQ, 0x1c04, instArgs{arg_R_12, arg_mem_R_pm_R_postindex}},                   // LDRHT<c> <Rt>, [<Rn>], +/-<Rm> cond:4|0|0|0|0|U|0|1|1|Rn:4|Rt:4|0|0|0|0|1|0|1|1|Rm:4
+	{0x0e500ff0, 0x001000d0, 2, LDRSB_EQ, 0x1c04, instArgs{arg_R_12, arg_mem_R_pm_R_W}},                           // LDRSB<c> <Rt>,[<Rn>,+/-<Rm>]{!} cond:4|0|0|0|P|U|0|W|1|Rn:4|Rt:4|0|0|0|0|1|1|0|1|Rm:4
+	{0x0e5000f0, 0x005000d0, 2, LDRSB_EQ, 0x1c04, instArgs{arg_R_12, arg_mem_R_pm_imm8_W}},                        // LDRSB<c> <Rt>,[<Rn>{,#+/-<imm8>}]{!} cond:4|0|0|0|P|U|1|W|1|Rn:4|Rt:4|imm4H:4|1|1|0|1|imm4L:4
+	{0x0f7000f0, 0x007000d0, 4, LDRSBT_EQ, 0x1c04, instArgs{arg_R_12, arg_mem_R_pm_imm8_postindex}},               // LDRSBT<c> <Rt>, [<Rn>] {,#+/-<imm8>} cond:4|0|0|0|0|U|1|1|1|Rn:4|Rt:4|imm4H:4|1|1|0|1|imm4L:4
+	{0x0f700ff0, 0x003000d0, 4, LDRSBT_EQ, 0x1c04, instArgs{arg_R_12, arg_mem_R_pm_R_postindex}},                  // LDRSBT<c> <Rt>, [<Rn>], +/-<Rm> cond:4|0|0|0|0|U|0|1|1|Rn:4|Rt:4|0|0|0|0|1|1|0|1|Rm:4
+	{0x0e500ff0, 0x001000f0, 2, LDRSH_EQ, 0x1c04, instArgs{arg_R_12, arg_mem_R_pm_R_W}},                           // LDRSH<c> <Rt>,[<Rn>,+/-<Rm>]{!} cond:4|0|0|0|P|U|0|W|1|Rn:4|Rt:4|0|0|0|0|1|1|1|1|Rm:4
+	{0x0e5000f0, 0x005000f0, 2, LDRSH_EQ, 0x1c04, instArgs{arg_R_12, arg_mem_R_pm_imm8_W}},                        // LDRSH<c> <Rt>,[<Rn>{,#+/-<imm8>}]{!} cond:4|0|0|0|P|U|1|W|1|Rn:4|Rt:4|imm4H:4|1|1|1|1|imm4L:4
+	{0x0f7000f0, 0x007000f0, 4, LDRSHT_EQ, 0x1c04, instArgs{arg_R_12, arg_mem_R_pm_imm8_postindex}},               // LDRSHT<c> <Rt>, [<Rn>] {,#+/-<imm8>} cond:4|0|0|0|0|U|1|1|1|Rn:4|Rt:4|imm4H:4|1|1|1|1|imm4L:4
+	{0x0f700ff0, 0x003000f0, 4, LDRSHT_EQ, 0x1c04, instArgs{arg_R_12, arg_mem_R_pm_R_postindex}},                  // LDRSHT<c> <Rt>, [<Rn>], +/-<Rm> cond:4|0|0|0|0|U|0|1|1|Rn:4|Rt:4|0|0|0|0|1|1|1|1|Rm:4
+	{0x0f700000, 0x04300000, 4, LDRT_EQ, 0x1c04, instArgs{arg_R_12, arg_mem_R_pm_imm12_postindex}},                // LDRT<c> <Rt>, [<Rn>] {,#+/-<imm12>} cond:4|0|1|0|0|U|0|1|1|Rn:4|Rt:4|imm12:12
+	{0x0f700010, 0x06300000, 4, LDRT_EQ, 0x1c04, instArgs{arg_R_12, arg_mem_R_pm_R_shift_imm_postindex}},          // LDRT<c> <Rt>,[<Rn>],+/-<Rm>{, <shift>} cond:4|0|1|1|0|U|0|1|1|Rn:4|Rt:4|imm5:5|type:2|0|Rm:4
+	{0x0fef0070, 0x01a00000, 2, LSL_EQ, 0x14011c04, instArgs{arg_R_12, arg_R_0, arg_imm5_nz}},                     // LSL{S}<c> <Rd>,<Rm>,#<imm5_nz> cond:4|0|0|0|1|1|0|1|S|0|0|0|0|Rd:4|imm5:5|0|0|0|Rm:4
+	{0x0fef00f0, 0x01a00010, 4, LSL_EQ, 0x14011c04, instArgs{arg_R_12, arg_R_0, arg_R_8}},                         // LSL{S}<c> <Rd>,<Rn>,<Rm> cond:4|0|0|0|1|1|0|1|S|0|0|0|0|Rd:4|Rm:4|0|0|0|1|Rn:4
+	{0x0fef0070, 0x01a00020, 4, LSR_EQ, 0x14011c04, instArgs{arg_R_12, arg_R_0, arg_imm5_32}},                     // LSR{S}<c> <Rd>,<Rm>,#<imm5_32> cond:4|0|0|0|1|1|0|1|S|0|0|0|0|Rd:4|imm5:5|0|1|0|Rm:4
+	{0x0fef00f0, 0x01a00030, 4, LSR_EQ, 0x14011c04, instArgs{arg_R_12, arg_R_0, arg_R_8}},                         // LSR{S}<c> <Rd>,<Rn>,<Rm> cond:4|0|0|0|1|1|0|1|S|0|0|0|0|Rd:4|Rm:4|0|0|1|1|Rn:4
+	{0x0fe000f0, 0x00200090, 4, MLA_EQ, 0x14011c04, instArgs{arg_R_16, arg_R_0, arg_R_8, arg_R_12}},               // MLA{S}<c> <Rd>,<Rn>,<Rm>,<Ra> cond:4|0|0|0|0|0|0|1|S|Rd:4|Ra:4|Rm:4|1|0|0|1|Rn:4
+	{0x0ff000f0, 0x00600090, 4, MLS_EQ, 0x1c04, instArgs{arg_R_16, arg_R_0, arg_R_8, arg_R_12}},                   // MLS<c> <Rd>,<Rn>,<Rm>,<Ra> cond:4|0|0|0|0|0|1|1|0|Rd:4|Ra:4|Rm:4|1|0|0|1|Rn:4
+	{0x0ff00000, 0x03400000, 4, MOVT_EQ, 0x1c04, instArgs{arg_R_12, arg_imm_4at16_12at0}},                         // MOVT<c> <Rd>,#<imm12+4> cond:4|0|0|1|1|0|1|0|0|imm4:4|Rd:4|imm12:12
+	{0x0ff00000, 0x03000000, 4, MOVW_EQ, 0x1c04, instArgs{arg_R_12, arg_imm_4at16_12at0}},                         // MOVW<c> <Rd>,#<imm12+4> cond:4|0|0|1|1|0|0|0|0|imm4:4|Rd:4|imm12:12
+	{0x0fef0000, 0x03a00000, 2, MOV_EQ, 0x14011c04, instArgs{arg_R_12, arg_const}},                                // MOV{S}<c> <Rd>,#<const> cond:4|0|0|1|1|1|0|1|S|0|0|0|0|Rd:4|imm12:12
+	{0x0fef0ff0, 0x01a00000, 2, MOV_EQ, 0x14011c04, instArgs{arg_R_12, arg_R_0}},                                  // MOV{S}<c> <Rd>,<Rm> cond:4|0|0|0|1|1|0|1|S|0|0|0|0|Rd:4|0|0|0|0|0|0|0|0|Rm:4
+	{0x0fff0fff, 0x010f0000, 4, MRS_EQ, 0x1c04, instArgs{arg_R_12, arg_APSR}},                                     // MRS<c> <Rd>,APSR cond:4|0|0|0|1|0|0|0|0|(1)|(1)|(1)|(1)|Rd:4|(0)|(0)|(0)|(0)|0|0|0|0|(0)|(0)|(0)|(0)
+	{0x0ff000f0, 0x010f0000, 3, MRS_EQ, 0x1c04, instArgs{arg_R_12, arg_APSR}},                                     // MRS<c> <Rd>,APSR cond:4|0|0|0|1|0|0|0|0|(1)|(1)|(1)|(1)|Rd:4|(0)|(0)|(0)|(0)|0|0|0|0|(0)|(0)|(0)|(0)
+	{0x0fe0f0f0, 0x00000090, 4, MUL_EQ, 0x14011c04, instArgs{arg_R_16, arg_R_0, arg_R_8}},                         // MUL{S}<c> <Rd>,<Rn>,<Rm> cond:4|0|0|0|0|0|0|0|S|Rd:4|(0)|(0)|(0)|(0)|Rm:4|1|0|0|1|Rn:4
+	{0x0fe000f0, 0x00000090, 3, MUL_EQ, 0x14011c04, instArgs{arg_R_16, arg_R_0, arg_R_8}},                         // MUL{S}<c> <Rd>,<Rn>,<Rm> cond:4|0|0|0|0|0|0|0|S|Rd:4|(0)|(0)|(0)|(0)|Rm:4|1|0|0|1|Rn:4
+	{0x0fef0000, 0x03e00000, 2, MVN_EQ, 0x14011c04, instArgs{arg_R_12, arg_const}},                                // MVN{S}<c> <Rd>,#<const> cond:4|0|0|1|1|1|1|1|S|(0)|(0)|(0)|(0)|Rd:4|imm12:12
+	{0x0fe00000, 0x03e00000, 1, MVN_EQ, 0x14011c04, instArgs{arg_R_12, arg_const}},                                // MVN{S}<c> <Rd>,#<const> cond:4|0|0|1|1|1|1|1|S|(0)|(0)|(0)|(0)|Rd:4|imm12:12
+	{0x0fef0090, 0x01e00010, 4, MVN_EQ, 0x14011c04, instArgs{arg_R_12, arg_R_shift_R}},                            // MVN{S}<c> <Rd>,<Rm>,<type> <Rs> cond:4|0|0|0|1|1|1|1|S|(0)|(0)|(0)|(0)|Rd:4|Rs:4|0|type:2|1|Rm:4
+	{0x0fe00090, 0x01e00010, 3, MVN_EQ, 0x14011c04, instArgs{arg_R_12, arg_R_shift_R}},                            // MVN{S}<c> <Rd>,<Rm>,<type> <Rs> cond:4|0|0|0|1|1|1|1|S|(0)|(0)|(0)|(0)|Rd:4|Rs:4|0|type:2|1|Rm:4
+	{0x0fef0010, 0x01e00000, 2, MVN_EQ, 0x14011c04, instArgs{arg_R_12, arg_R_shift_imm}},                          // MVN{S}<c> <Rd>,<Rm>{,<shift>} cond:4|0|0|0|1|1|1|1|S|(0)|(0)|(0)|(0)|Rd:4|imm5:5|type:2|0|Rm:4
+	{0x0fe00010, 0x01e00000, 1, MVN_EQ, 0x14011c04, instArgs{arg_R_12, arg_R_shift_imm}},                          // MVN{S}<c> <Rd>,<Rm>{,<shift>} cond:4|0|0|0|1|1|1|1|S|(0)|(0)|(0)|(0)|Rd:4|imm5:5|type:2|0|Rm:4
+	{0x0fffffff, 0x0320f000, 4, NOP_EQ, 0x1c04, instArgs{}},                                                       // NOP<c> cond:4|0|0|1|1|0|0|1|0|0|0|0|0|(1)|(1)|(1)|(1)|(0)|(0)|(0)|(0)|0|0|0|0|0|0|0|0
+	{0x0fff00ff, 0x0320f000, 3, NOP_EQ, 0x1c04, instArgs{}},                                                       // NOP<c> cond:4|0|0|1|1|0|0|1|0|0|0|0|0|(1)|(1)|(1)|(1)|(0)|(0)|(0)|(0)|0|0|0|0|0|0|0|0
+	{0x0fe00000, 0x03800000, 2, ORR_EQ, 0x14011c04, instArgs{arg_R_12, arg_R_16, arg_const}},                      // ORR{S}<c> <Rd>,<Rn>,#<const> cond:4|0|0|1|1|1|0|0|S|Rn:4|Rd:4|imm12:12
+	{0x0fe00090, 0x01800010, 4, ORR_EQ, 0x14011c04, instArgs{arg_R_12, arg_R_16, arg_R_shift_R}},                  // ORR{S}<c> <Rd>,<Rn>,<Rm>,<type> <Rs> cond:4|0|0|0|1|1|0|0|S|Rn:4|Rd:4|Rs:4|0|type:2|1|Rm:4
+	{0x0fe00010, 0x01800000, 2, ORR_EQ, 0x14011c04, instArgs{arg_R_12, arg_R_16, arg_R_shift_imm}},                // ORR{S}<c> <Rd>,<Rn>,<Rm>{,<shift>} cond:4|0|0|0|1|1|0|0|S|Rn:4|Rd:4|imm5:5|type:2|0|Rm:4
+	{0x0ff00030, 0x06800010, 4, PKHBT_EQ, 0x6011c04, instArgs{arg_R_12, arg_R_16, arg_R_shift_imm}},               // PKH<BT,TB><c> <Rd>,<Rn>,<Rm>{,LSL #<imm5>} cond:4|0|1|1|0|1|0|0|0|Rn:4|Rd:4|imm5:5|tb|0|1|Rm:4
+	{0xff7ff000, 0xf55ff000, 4, PLD, 0x0, instArgs{arg_label_pm_12}},                                              // PLD <label+/-12> 1|1|1|1|0|1|0|1|U|(1)|0|1|1|1|1|1|(1)|(1)|(1)|(1)|imm12:12
+	{0xff3f0000, 0xf55ff000, 3, PLD, 0x0, instArgs{arg_label_pm_12}},                                              // PLD <label+/-12> 1|1|1|1|0|1|0|1|U|(1)|0|1|1|1|1|1|(1)|(1)|(1)|(1)|imm12:12
+	{0xff30f000, 0xf510f000, 2, PLD_W, 0x1601, instArgs{arg_mem_R_pm_imm12_offset}},                               // PLD{W} [<Rn>,#+/-<imm12>] 1|1|1|1|0|1|0|1|U|R|0|1|Rn:4|(1)|(1)|(1)|(1)|imm12:12
+	{0xff300000, 0xf510f000, 1, PLD_W, 0x1601, instArgs{arg_mem_R_pm_imm12_offset}},                               // PLD{W} [<Rn>,#+/-<imm12>] 1|1|1|1|0|1|0|1|U|R|0|1|Rn:4|(1)|(1)|(1)|(1)|imm12:12
+	{0xff30f010, 0xf710f000, 4, PLD_W, 0x1601, instArgs{arg_mem_R_pm_R_shift_imm_offset}},                         // PLD{W} [<Rn>,+/-<Rm>{, <shift>}] 1|1|1|1|0|1|1|1|U|R|0|1|Rn:4|(1)|(1)|(1)|(1)|imm5:5|type:2|0|Rm:4
+	{0xff300010, 0xf710f000, 3, PLD_W, 0x1601, instArgs{arg_mem_R_pm_R_shift_imm_offset}},                         // PLD{W} [<Rn>,+/-<Rm>{, <shift>}] 1|1|1|1|0|1|1|1|U|R|0|1|Rn:4|(1)|(1)|(1)|(1)|imm5:5|type:2|0|Rm:4
+	{0xff70f000, 0xf450f000, 4, PLI, 0x0, instArgs{arg_mem_R_pm_imm12_offset}},                                    // PLI [<Rn>,#+/-<imm12>] 1|1|1|1|0|1|0|0|U|1|0|1|Rn:4|(1)|(1)|(1)|(1)|imm12:12
+	{0xff700000, 0xf450f000, 3, PLI, 0x0, instArgs{arg_mem_R_pm_imm12_offset}},                                    // PLI [<Rn>,#+/-<imm12>] 1|1|1|1|0|1|0|0|U|1|0|1|Rn:4|(1)|(1)|(1)|(1)|imm12:12
+	{0xff70f010, 0xf650f000, 4, PLI, 0x0, instArgs{arg_mem_R_pm_R_shift_imm_offset}},                              // PLI [<Rn>,+/-<Rm>{, <shift>}] 1|1|1|1|0|1|1|0|U|1|0|1|Rn:4|(1)|(1)|(1)|(1)|imm5:5|type:2|0|Rm:4
+	{0xff700010, 0xf650f000, 3, PLI, 0x0, instArgs{arg_mem_R_pm_R_shift_imm_offset}},                              // PLI [<Rn>,+/-<Rm>{, <shift>}] 1|1|1|1|0|1|1|0|U|1|0|1|Rn:4|(1)|(1)|(1)|(1)|imm5:5|type:2|0|Rm:4
+	{0x0fff0000, 0x08bd0000, 4, POP_EQ, 0x1c04, instArgs{arg_registers2}},                                         // POP<c> <registers2> cond:4|1|0|0|0|1|0|1|1|1|1|0|1|register_list:16
+	{0x0fff0fff, 0x049d0004, 4, POP_EQ, 0x1c04, instArgs{arg_registers1}},                                         // POP<c> <registers1> cond:4|0|1|0|0|1|0|0|1|1|1|0|1|Rt:4|0|0|0|0|0|0|0|0|0|1|0|0
+	{0x0fff0000, 0x092d0000, 4, PUSH_EQ, 0x1c04, instArgs{arg_registers2}},                                        // PUSH<c> <registers2> cond:4|1|0|0|1|0|0|1|0|1|1|0|1|register_list:16
+	{0x0fff0fff, 0x052d0004, 4, PUSH_EQ, 0x1c04, instArgs{arg_registers1}},                                        // PUSH<c> <registers1> cond:4|0|1|0|1|0|0|1|0|1|1|0|1|Rt:4|0|0|0|0|0|0|0|0|0|1|0|0
+	{0x0ff00ff0, 0x06200f10, 4, QADD16_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0}},                         // QADD16<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|1|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|0|0|1|Rm:4
+	{0x0ff000f0, 0x06200f10, 3, QADD16_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0}},                         // QADD16<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|1|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|0|0|1|Rm:4
+	{0x0ff00ff0, 0x06200f90, 4, QADD8_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0}},                          // QADD8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|1|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|0|0|1|Rm:4
+	{0x0ff000f0, 0x06200f90, 3, QADD8_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0}},                          // QADD8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|1|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|0|0|1|Rm:4
+	{0x0ff00ff0, 0x01000050, 4, QADD_EQ, 0x1c04, instArgs{arg_R_12, arg_R_0, arg_R_16}},                           // QADD<c> <Rd>,<Rm>,<Rn> cond:4|0|0|0|1|0|0|0|0|Rn:4|Rd:4|(0)|(0)|(0)|(0)|0|1|0|1|Rm:4
+	{0x0ff000f0, 0x01000050, 3, QADD_EQ, 0x1c04, instArgs{arg_R_12, arg_R_0, arg_R_16}},                           // QADD<c> <Rd>,<Rm>,<Rn> cond:4|0|0|0|1|0|0|0|0|Rn:4|Rd:4|(0)|(0)|(0)|(0)|0|1|0|1|Rm:4
+	{0x0ff00ff0, 0x06200f30, 4, QASX_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0}},                           // QASX<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|1|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|0|1|1|Rm:4
+	{0x0ff000f0, 0x06200f30, 3, QASX_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0}},                           // QASX<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|1|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|0|1|1|Rm:4
+	{0x0ff00ff0, 0x01400050, 4, QDADD_EQ, 0x1c04, instArgs{arg_R_12, arg_R_0, arg_R_16}},                          // QDADD<c> <Rd>,<Rm>,<Rn> cond:4|0|0|0|1|0|1|0|0|Rn:4|Rd:4|(0)|(0)|(0)|(0)|0|1|0|1|Rm:4
+	{0x0ff000f0, 0x01400050, 3, QDADD_EQ, 0x1c04, instArgs{arg_R_12, arg_R_0, arg_R_16}},                          // QDADD<c> <Rd>,<Rm>,<Rn> cond:4|0|0|0|1|0|1|0|0|Rn:4|Rd:4|(0)|(0)|(0)|(0)|0|1|0|1|Rm:4
+	{0x0ff00ff0, 0x01600050, 4, QDSUB_EQ, 0x1c04, instArgs{arg_R_12, arg_R_0, arg_R_16}},                          // QDSUB<c> <Rd>,<Rm>,<Rn> cond:4|0|0|0|1|0|1|1|0|Rn:4|Rd:4|0|0|0|0|0|1|0|1|Rm:4
+	{0x0ff00ff0, 0x06200f50, 4, QSAX_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0}},                           // QSAX<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|1|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|1|0|1|Rm:4
+	{0x0ff000f0, 0x06200f50, 3, QSAX_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0}},                           // QSAX<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|1|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|1|0|1|Rm:4
+	{0x0ff00ff0, 0x06200f70, 4, QSUB16_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0}},                         // QSUB16<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|1|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|1|1|1|Rm:4
+	{0x0ff000f0, 0x06200f70, 3, QSUB16_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0}},                         // QSUB16<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|1|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|1|1|1|Rm:4
+	{0x0ff00ff0, 0x06200ff0, 4, QSUB8_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0}},                          // QSUB8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|1|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|1|1|1|Rm:4
+	{0x0ff000f0, 0x06200ff0, 3, QSUB8_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0}},                          // QSUB8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|1|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|1|1|1|Rm:4
+	{0x0ff00ff0, 0x01200050, 4, QSUB_EQ, 0x1c04, instArgs{arg_R_12, arg_R_0, arg_R_16}},                           // QSUB<c> <Rd>,<Rm>,<Rn> cond:4|0|0|0|1|0|0|1|0|Rn:4|Rd:4|0|0|0|0|0|1|0|1|Rm:4
+	{0x0fff0ff0, 0x06ff0f30, 4, RBIT_EQ, 0x1c04, instArgs{arg_R_12, arg_R_0}},                                     // RBIT<c> <Rd>,<Rm> cond:4|0|1|1|0|1|1|1|1|(1)|(1)|(1)|(1)|Rd:4|(1)|(1)|(1)|(1)|0|0|1|1|Rm:4
+	{0x0ff000f0, 0x06ff0f30, 3, RBIT_EQ, 0x1c04, instArgs{arg_R_12, arg_R_0}},                                     // RBIT<c> <Rd>,<Rm> cond:4|0|1|1|0|1|1|1|1|(1)|(1)|(1)|(1)|Rd:4|(1)|(1)|(1)|(1)|0|0|1|1|Rm:4
+	{0x0fff0ff0, 0x06bf0fb0, 4, REV16_EQ, 0x1c04, instArgs{arg_R_12, arg_R_0}},                                    // REV16<c> <Rd>,<Rm> cond:4|0|1|1|0|1|0|1|1|(1)|(1)|(1)|(1)|Rd:4|(1)|(1)|(1)|(1)|1|0|1|1|Rm:4
+	{0x0ff000f0, 0x06bf0fb0, 3, REV16_EQ, 0x1c04, instArgs{arg_R_12, arg_R_0}},                                    // REV16<c> <Rd>,<Rm> cond:4|0|1|1|0|1|0|1|1|(1)|(1)|(1)|(1)|Rd:4|(1)|(1)|(1)|(1)|1|0|1|1|Rm:4
+	{0x0fff0ff0, 0x06bf0f30, 4, REV_EQ, 0x1c04, instArgs{arg_R_12, arg_R_0}},                                      // REV<c> <Rd>,<Rm> cond:4|0|1|1|0|1|0|1|1|(1)|(1)|(1)|(1)|Rd:4|(1)|(1)|(1)|(1)|0|0|1|1|Rm:4
+	{0x0ff000f0, 0x06bf0f30, 3, REV_EQ, 0x1c04, instArgs{arg_R_12, arg_R_0}},                                      // REV<c> <Rd>,<Rm> cond:4|0|1|1|0|1|0|1|1|(1)|(1)|(1)|(1)|Rd:4|(1)|(1)|(1)|(1)|0|0|1|1|Rm:4
+	{0x0fff0ff0, 0x06ff0fb0, 4, REVSH_EQ, 0x1c04, instArgs{arg_R_12, arg_R_0}},                                    // REVSH<c> <Rd>,<Rm> cond:4|0|1|1|0|1|1|1|1|(1)|(1)|(1)|(1)|Rd:4|(1)|(1)|(1)|(1)|1|0|1|1|Rm:4
+	{0x0ff000f0, 0x06ff0fb0, 3, REVSH_EQ, 0x1c04, instArgs{arg_R_12, arg_R_0}},                                    // REVSH<c> <Rd>,<Rm> cond:4|0|1|1|0|1|1|1|1|(1)|(1)|(1)|(1)|Rd:4|(1)|(1)|(1)|(1)|1|0|1|1|Rm:4
+	{0x0fef0070, 0x01a00060, 2, ROR_EQ, 0x14011c04, instArgs{arg_R_12, arg_R_0, arg_imm5}},                        // ROR{S}<c> <Rd>,<Rm>,#<imm5> cond:4|0|0|0|1|1|0|1|S|0|0|0|0|Rd:4|imm5:5|1|1|0|Rm:4
+	{0x0fef00f0, 0x01a00070, 4, ROR_EQ, 0x14011c04, instArgs{arg_R_12, arg_R_0, arg_R_8}},                         // ROR{S}<c> <Rd>,<Rn>,<Rm> cond:4|0|0|0|1|1|0|1|S|0|0|0|0|Rd:4|Rm:4|0|1|1|1|Rn:4
+	{0x0fef0ff0, 0x01a00060, 4, RRX_EQ, 0x14011c04, instArgs{arg_R_12, arg_R_0}},                                  // RRX{S}<c> <Rd>,<Rm> cond:4|0|0|0|1|1|0|1|S|0|0|0|0|Rd:4|0|0|0|0|0|1|1|0|Rm:4
+	{0x0fe00000, 0x02600000, 2, RSB_EQ, 0x14011c04, instArgs{arg_R_12, arg_R_16, arg_const}},                      // RSB{S}<c> <Rd>,<Rn>,#<const> cond:4|0|0|1|0|0|1|1|S|Rn:4|Rd:4|imm12:12
+	{0x0fe00090, 0x00600010, 4, RSB_EQ, 0x14011c04, instArgs{arg_R_12, arg_R_16, arg_R_shift_R}},                  // RSB{S}<c> <Rd>,<Rn>,<Rm>,<type> <Rs> cond:4|0|0|0|0|0|1|1|S|Rn:4|Rd:4|Rs:4|0|type:2|1|Rm:4
+	{0x0fe00010, 0x00600000, 2, RSB_EQ, 0x14011c04, instArgs{arg_R_12, arg_R_16, arg_R_shift_imm}},                // RSB{S}<c> <Rd>,<Rn>,<Rm>{,<shift>} cond:4|0|0|0|0|0|1|1|S|Rn:4|Rd:4|imm5:5|type:2|0|Rm:4
+	{0x0fe00000, 0x02e00000, 2, RSC_EQ, 0x14011c04, instArgs{arg_R_12, arg_R_16, arg_const}},                      // RSC{S}<c> <Rd>,<Rn>,#<const> cond:4|0|0|1|0|1|1|1|S|Rn:4|Rd:4|imm12:12
+	{0x0fe00090, 0x00e00010, 4, RSC_EQ, 0x14011c04, instArgs{arg_R_12, arg_R_16, arg_R_shift_R}},                  // RSC{S}<c> <Rd>,<Rn>,<Rm>,<type> <Rs> cond:4|0|0|0|0|1|1|1|S|Rn:4|Rd:4|Rs:4|0|type:2|1|Rm:4
+	{0x0fe00010, 0x00e00000, 2, RSC_EQ, 0x14011c04, instArgs{arg_R_12, arg_R_16, arg_R_shift_imm}},                // RSC{S}<c> <Rd>,<Rn>,<Rm>{,<shift>} cond:4|0|0|0|0|1|1|1|S|Rn:4|Rd:4|imm5:5|type:2|0|Rm:4
+	{0x0ff00ff0, 0x06100f10, 4, SADD16_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0}},                         // SADD16<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|0|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|0|0|1|Rm:4
+	{0x0ff000f0, 0x06100f10, 3, SADD16_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0}},                         // SADD16<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|0|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|0|0|1|Rm:4
+	{0x0ff00ff0, 0x06100f90, 4, SADD8_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0}},                          // SADD8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|0|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|0|0|1|Rm:4
+	{0x0ff000f0, 0x06100f90, 3, SADD8_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0}},                          // SADD8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|0|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|0|0|1|Rm:4
+	{0x0ff00ff0, 0x06100f30, 4, SASX_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0}},                           // SASX<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|0|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|0|1|1|Rm:4
+	{0x0ff000f0, 0x06100f30, 3, SASX_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0}},                           // SASX<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|0|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|0|1|1|Rm:4
+	{0x0fe00000, 0x02c00000, 2, SBC_EQ, 0x14011c04, instArgs{arg_R_12, arg_R_16, arg_const}},                      // SBC{S}<c> <Rd>,<Rn>,#<const> cond:4|0|0|1|0|1|1|0|S|Rn:4|Rd:4|imm12:12
+	{0x0fe00090, 0x00c00010, 4, SBC_EQ, 0x14011c04, instArgs{arg_R_12, arg_R_16, arg_R_shift_R}},                  // SBC{S}<c> <Rd>,<Rn>,<Rm>,<type> <Rs> cond:4|0|0|0|0|1|1|0|S|Rn:4|Rd:4|Rs:4|0|type:2|1|Rm:4
+	{0x0fe00010, 0x00c00000, 2, SBC_EQ, 0x14011c04, instArgs{arg_R_12, arg_R_16, arg_R_shift_imm}},                // SBC{S}<c> <Rd>,<Rn>,<Rm>{,<shift>} cond:4|0|0|0|0|1|1|0|S|Rn:4|Rd:4|imm5:5|type:2|0|Rm:4
+	{0x0fe00070, 0x07a00050, 4, SBFX_EQ, 0x1c04, instArgs{arg_R_12, arg_R_0, arg_imm5, arg_widthm1}},              // SBFX<c> <Rd>,<Rn>,#<lsb>,#<widthm1> cond:4|0|1|1|1|1|0|1|widthm1:5|Rd:4|lsb:5|1|0|1|Rn:4
+	{0x0ff00ff0, 0x06800fb0, 4, SEL_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0}},                            // SEL<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|1|0|0|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|0|1|1|Rm:4
+	{0x0ff000f0, 0x06800fb0, 3, SEL_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0}},                            // SEL<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|1|0|0|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|0|1|1|Rm:4
+	{0xfffffdff, 0xf1010000, 4, SETEND, 0x0, instArgs{arg_endian}},                                                // SETEND <endian_specifier> 1|1|1|1|0|0|0|1|0|0|0|0|0|0|0|1|0|0|0|0|0|0|E|(0)|(0)|(0)|(0)|(0)|(0)|(0)|(0)|(0)
+	{0xfffffc00, 0xf1010000, 3, SETEND, 0x0, instArgs{arg_endian}},                                                // SETEND <endian_specifier> 1|1|1|1|0|0|0|1|0|0|0|0|0|0|0|1|0|0|0|0|0|0|E|(0)|(0)|(0)|(0)|(0)|(0)|(0)|(0)|(0)
+	{0x0fffffff, 0x0320f004, 4, SEV_EQ, 0x1c04, instArgs{}},                                                       // SEV<c> cond:4|0|0|1|1|0|0|1|0|0|0|0|0|(1)|(1)|(1)|(1)|(0)|(0)|(0)|(0)|0|0|0|0|0|1|0|0
+	{0x0fff00ff, 0x0320f004, 3, SEV_EQ, 0x1c04, instArgs{}},                                                       // SEV<c> cond:4|0|0|1|1|0|0|1|0|0|0|0|0|(1)|(1)|(1)|(1)|(0)|(0)|(0)|(0)|0|0|0|0|0|1|0|0
+	{0x0ff00ff0, 0x06300f10, 4, SHADD16_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0}},                        // SHADD16<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|1|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|0|0|1|Rm:4
+	{0x0ff000f0, 0x06300f10, 3, SHADD16_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0}},                        // SHADD16<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|1|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|0|0|1|Rm:4
+	{0x0ff00ff0, 0x06300f90, 4, SHADD8_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0}},                         // SHADD8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|1|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|0|0|1|Rm:4
+	{0x0ff000f0, 0x06300f90, 3, SHADD8_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0}},                         // SHADD8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|1|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|0|0|1|Rm:4
+	{0x0ff00ff0, 0x06300f30, 4, SHASX_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0}},                          // SHASX<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|1|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|0|1|1|Rm:4
+	{0x0ff000f0, 0x06300f30, 3, SHASX_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0}},                          // SHASX<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|1|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|0|1|1|Rm:4
+	{0x0ff00ff0, 0x06300f50, 4, SHSAX_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0}},                          // SHSAX<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|1|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|1|0|1|Rm:4
+	{0x0ff000f0, 0x06300f50, 3, SHSAX_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0}},                          // SHSAX<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|1|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|1|0|1|Rm:4
+	{0x0ff00ff0, 0x06300f70, 4, SHSUB16_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0}},                        // SHSUB16<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|1|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|1|1|1|Rm:4
+	{0x0ff000f0, 0x06300f70, 3, SHSUB16_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0}},                        // SHSUB16<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|1|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|1|1|1|Rm:4
+	{0x0ff00ff0, 0x06300ff0, 4, SHSUB8_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0}},                         // SHSUB8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|1|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|1|1|1|Rm:4
+	{0x0ff000f0, 0x06300ff0, 3, SHSUB8_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0}},                         // SHSUB8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|1|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|1|1|1|Rm:4
+	{0x0ff00090, 0x01000080, 4, SMLABB_EQ, 0x50106011c04, instArgs{arg_R_16, arg_R_0, arg_R_8, arg_R_12}},         // SMLA<x><y><c> <Rd>,<Rn>,<Rm>,<Ra> cond:4|0|0|0|1|0|0|0|0|Rd:4|Ra:4|Rm:4|1|M|N|0|Rn:4
+	{0x0ff000d0, 0x07000010, 2, SMLAD_EQ, 0x5011c04, instArgs{arg_R_16, arg_R_0, arg_R_8, arg_R_12}},              // SMLAD{X}<c> <Rd>,<Rn>,<Rm>,<Ra> cond:4|0|1|1|1|0|0|0|0|Rd:4|Ra:4|Rm:4|0|0|M|1|Rn:4
+	{0x0ff00090, 0x01400080, 4, SMLALBB_EQ, 0x50106011c04, instArgs{arg_R_12, arg_R_16, arg_R_0, arg_R_8}},        // SMLAL<x><y><c> <RdLo>,<RdHi>,<Rn>,<Rm> cond:4|0|0|0|1|0|1|0|0|RdHi:4|RdLo:4|Rm:4|1|M|N|0|Rn:4
+	{0x0ff000d0, 0x07400010, 4, SMLALD_EQ, 0x5011c04, instArgs{arg_R_12, arg_R_16, arg_R_0, arg_R_8}},             // SMLALD{X}<c> <RdLo>,<RdHi>,<Rn>,<Rm> cond:4|0|1|1|1|0|1|0|0|RdHi:4|RdLo:4|Rm:4|0|0|M|1|Rn:4
+	{0x0fe000f0, 0x00e00090, 4, SMLAL_EQ, 0x14011c04, instArgs{arg_R_12, arg_R_16, arg_R_0, arg_R_8}},             // SMLAL{S}<c> <RdLo>,<RdHi>,<Rn>,<Rm> cond:4|0|0|0|0|1|1|1|S|RdHi:4|RdLo:4|Rm:4|1|0|0|1|Rn:4
+	{0x0ff000b0, 0x01200080, 4, SMLAWB_EQ, 0x6011c04, instArgs{arg_R_16, arg_R_0, arg_R_8, arg_R_12}},             // SMLAW<y><c> <Rd>,<Rn>,<Rm>,<Ra> cond:4|0|0|0|1|0|0|1|0|Rd:4|Ra:4|Rm:4|1|M|0|0|Rn:4
+	{0x0ff000d0, 0x07000050, 2, SMLSD_EQ, 0x5011c04, instArgs{arg_R_16, arg_R_0, arg_R_8, arg_R_12}},              // SMLSD{X}<c> <Rd>,<Rn>,<Rm>,<Ra> cond:4|0|1|1|1|0|0|0|0|Rd:4|Ra:4|Rm:4|0|1|M|1|Rn:4
+	{0x0ff000d0, 0x07400050, 4, SMLSLD_EQ, 0x5011c04, instArgs{arg_R_12, arg_R_16, arg_R_0, arg_R_8}},             // SMLSLD{X}<c> <RdLo>,<RdHi>,<Rn>,<Rm> cond:4|0|1|1|1|0|1|0|0|RdHi:4|RdLo:4|Rm:4|0|1|M|1|Rn:4
+	{0x0ff000d0, 0x07500010, 2, SMMLA_EQ, 0x5011c04, instArgs{arg_R_16, arg_R_0, arg_R_8, arg_R_12}},              // SMMLA{R}<c> <Rd>,<Rn>,<Rm>,<Ra> cond:4|0|1|1|1|0|1|0|1|Rd:4|Ra:4|Rm:4|0|0|R|1|Rn:4
+	{0x0ff000d0, 0x075000d0, 4, SMMLS_EQ, 0x5011c04, instArgs{arg_R_16, arg_R_0, arg_R_8, arg_R_12}},              // SMMLS{R}<c> <Rd>,<Rn>,<Rm>,<Ra> cond:4|0|1|1|1|0|1|0|1|Rd:4|Ra:4|Rm:4|1|1|R|1|Rn:4
+	{0x0ff0f0d0, 0x0750f010, 4, SMMUL_EQ, 0x5011c04, instArgs{arg_R_16, arg_R_0, arg_R_8}},                        // SMMUL{R}<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|1|0|1|0|1|Rd:4|1|1|1|1|Rm:4|0|0|R|1|Rn:4
+	{0x0ff0f0d0, 0x0700f010, 4, SMUAD_EQ, 0x5011c04, instArgs{arg_R_16, arg_R_0, arg_R_8}},                        // SMUAD{X}<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|1|0|0|0|0|Rd:4|1|1|1|1|Rm:4|0|0|M|1|Rn:4
+	{0x0ff0f090, 0x01600080, 4, SMULBB_EQ, 0x50106011c04, instArgs{arg_R_16, arg_R_0, arg_R_8}},                   // SMUL<x><y><c> <Rd>,<Rn>,<Rm> cond:4|0|0|0|1|0|1|1|0|Rd:4|0|0|0|0|Rm:4|1|M|N|0|Rn:4
+	{0x0fe000f0, 0x00c00090, 4, SMULL_EQ, 0x14011c04, instArgs{arg_R_12, arg_R_16, arg_R_0, arg_R_8}},             // SMULL{S}<c> <RdLo>,<RdHi>,<Rn>,<Rm> cond:4|0|0|0|0|1|1|0|S|RdHi:4|RdLo:4|Rm:4|1|0|0|1|Rn:4
+	{0x0ff0f0b0, 0x012000a0, 4, SMULWB_EQ, 0x6011c04, instArgs{arg_R_16, arg_R_0, arg_R_8}},                       // SMULW<y><c> <Rd>,<Rn>,<Rm> cond:4|0|0|0|1|0|0|1|0|Rd:4|0|0|0|0|Rm:4|1|M|1|0|Rn:4
+	{0x0ff0f0d0, 0x0700f050, 4, SMUSD_EQ, 0x5011c04, instArgs{arg_R_16, arg_R_0, arg_R_8}},                        // SMUSD{X}<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|1|0|0|0|0|Rd:4|1|1|1|1|Rm:4|0|1|M|1|Rn:4
+	{0x0ff00ff0, 0x06a00f30, 4, SSAT16_EQ, 0x1c04, instArgs{arg_R_12, arg_satimm4m1, arg_R_0}},                    // SSAT16<c> <Rd>,#<sat_imm4m1>,<Rn> cond:4|0|1|1|0|1|0|1|0|sat_imm:4|Rd:4|(1)|(1)|(1)|(1)|0|0|1|1|Rn:4
+	{0x0ff000f0, 0x06a00f30, 3, SSAT16_EQ, 0x1c04, instArgs{arg_R_12, arg_satimm4m1, arg_R_0}},                    // SSAT16<c> <Rd>,#<sat_imm4m1>,<Rn> cond:4|0|1|1|0|1|0|1|0|sat_imm:4|Rd:4|(1)|(1)|(1)|(1)|0|0|1|1|Rn:4
+	{0x0fe00030, 0x06a00010, 4, SSAT_EQ, 0x1c04, instArgs{arg_R_12, arg_satimm5m1, arg_R_shift_imm}},              // SSAT<c> <Rd>,#<sat_imm5m1>,<Rn>{,<shift>} cond:4|0|1|1|0|1|0|1|sat_imm:5|Rd:4|imm5:5|sh|0|1|Rn:4
+	{0x0ff00ff0, 0x06100f50, 4, SSAX_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0}},                           // SSAX<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|0|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|1|0|1|Rm:4
+	{0x0ff000f0, 0x06100f50, 3, SSAX_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0}},                           // SSAX<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|0|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|1|0|1|Rm:4
+	{0x0ff00ff0, 0x06100f70, 4, SSUB16_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0}},                         // SSUB16<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|0|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|1|1|1|Rm:4
+	{0x0ff000f0, 0x06100f70, 3, SSUB16_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0}},                         // SSUB16<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|0|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|1|1|1|Rm:4
+	{0x0ff00ff0, 0x06100ff0, 4, SSUB8_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0}},                          // SSUB8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|0|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|1|1|1|Rm:4
+	{0x0ff000f0, 0x06100ff0, 3, SSUB8_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0}},                          // SSUB8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|0|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|1|1|1|Rm:4
+	{0x0fd00000, 0x08800000, 4, STM_EQ, 0x1c04, instArgs{arg_R_16_WB, arg_registers}},                             // STM<c> <Rn>{!},<registers> cond:4|1|0|0|0|1|0|W|0|Rn:4|register_list:16
+	{0x0fd00000, 0x08000000, 4, STMDA_EQ, 0x1c04, instArgs{arg_R_16_WB, arg_registers}},                           // STMDA<c> <Rn>{!},<registers> cond:4|1|0|0|0|0|0|W|0|Rn:4|register_list:16
+	{0x0fd00000, 0x09000000, 2, STMDB_EQ, 0x1c04, instArgs{arg_R_16_WB, arg_registers}},                           // STMDB<c> <Rn>{!},<registers> cond:4|1|0|0|1|0|0|W|0|Rn:4|register_list:16
+	{0x0fd00000, 0x09800000, 4, STMIB_EQ, 0x1c04, instArgs{arg_R_16_WB, arg_registers}},                           // STMIB<c> <Rn>{!},<registers> cond:4|1|0|0|1|1|0|W|0|Rn:4|register_list:16
+	{0x0e500018, 0x06000000, 2, STR_EQ, 0x1c04, instArgs{arg_R_12, arg_mem_R_pm_R_shift_imm_W}},                   // STR<c> <Rt>,[<Rn>,+/-<Rm>{, <shift>}]{!} cond:4|0|1|1|P|U|0|W|0|Rn:4|Rt:4|imm5:5|type:2|0|Rm:4
+	{0x0e500000, 0x04000000, 2, STR_EQ, 0x1c04, instArgs{arg_R_12, arg_mem_R_pm_imm12_W}},                         // STR<c> <Rt>,[<Rn>{,#+/-<imm12>}]{!} cond:4|0|1|0|P|U|0|W|0|Rn:4|Rt:4|imm12:12
+	{0x0e500010, 0x06400000, 2, STRB_EQ, 0x1c04, instArgs{arg_R_12, arg_mem_R_pm_R_shift_imm_W}},                  // STRB<c> <Rt>,[<Rn>,+/-<Rm>{, <shift>}]{!} cond:4|0|1|1|P|U|1|W|0|Rn:4|Rt:4|imm5:5|type:2|0|Rm:4
+	{0x0e500000, 0x04400000, 2, STRB_EQ, 0x1c04, instArgs{arg_R_12, arg_mem_R_pm_imm12_W}},                        // STRB<c> <Rt>,[<Rn>{,#+/-<imm12>}]{!} cond:4|0|1|0|P|U|1|W|0|Rn:4|Rt:4|imm12:12
+	{0x0f700000, 0x04600000, 4, STRBT_EQ, 0x1c04, instArgs{arg_R_12, arg_mem_R_pm_imm12_postindex}},               // STRBT<c> <Rt>,[<Rn>],#+/-<imm12> cond:4|0|1|0|0|U|1|1|0|Rn:4|Rt:4|imm12:12
+	{0x0f700010, 0x06600000, 4, STRBT_EQ, 0x1c04, instArgs{arg_R_12, arg_mem_R_pm_R_shift_imm_postindex}},         // STRBT<c> <Rt>,[<Rn>],+/-<Rm>{, <shift>} cond:4|0|1|1|0|U|1|1|0|Rn:4|Rt:4|imm5:5|type:2|0|Rm:4
+	{0x0e500ff0, 0x000000f0, 4, STRD_EQ, 0x1c04, instArgs{arg_R1_12, arg_R2_12, arg_mem_R_pm_R_W}},                // STRD<c> <Rt1>,<Rt2>,[<Rn>,+/-<Rm>]{!} cond:4|0|0|0|P|U|0|W|0|Rn:4|Rt:4|(0)|(0)|(0)|(0)|1|1|1|1|Rm:4
+	{0x0e5000f0, 0x000000f0, 3, STRD_EQ, 0x1c04, instArgs{arg_R1_12, arg_R2_12, arg_mem_R_pm_R_W}},                // STRD<c> <Rt1>,<Rt2>,[<Rn>,+/-<Rm>]{!} cond:4|0|0|0|P|U|0|W|0|Rn:4|Rt:4|(0)|(0)|(0)|(0)|1|1|1|1|Rm:4
+	{0x0e5000f0, 0x004000f0, 4, STRD_EQ, 0x1c04, instArgs{arg_R1_12, arg_R2_12, arg_mem_R_pm_imm8_W}},             // STRD<c> <Rt1>,<Rt2>,[<Rn>{,#+/-<imm8>}]{!} cond:4|0|0|0|P|U|1|W|0|Rn:4|Rt:4|imm4H:4|1|1|1|1|imm4L:4
+	{0x0ff00ff0, 0x01800f90, 4, STREX_EQ, 0x1c04, instArgs{arg_R_12, arg_R_0, arg_mem_R}},                         // STREX<c> <Rd>,<Rt>,[<Rn>] cond:4|0|0|0|1|1|0|0|0|Rn:4|Rd:4|1|1|1|1|1|0|0|1|Rt:4
+	{0x0ff00ff0, 0x01c00f90, 4, STREXB_EQ, 0x1c04, instArgs{arg_R_12, arg_R_0, arg_mem_R}},                        // STREXB<c> <Rd>,<Rt>,[<Rn>] cond:4|0|0|0|1|1|1|0|0|Rn:4|Rd:4|1|1|1|1|1|0|0|1|Rt:4
+	{0x0ff00ff0, 0x01a00f90, 4, STREXD_EQ, 0x1c04, instArgs{arg_R_12, arg_R1_0, arg_R2_0, arg_mem_R}},             // STREXD<c> <Rd>,<Rt1>,<Rt2>,[<Rn>] cond:4|0|0|0|1|1|0|1|0|Rn:4|Rd:4|1|1|1|1|1|0|0|1|Rt:4
+	{0x0ff00ff0, 0x01e00f90, 4, STREXH_EQ, 0x1c04, instArgs{arg_R_12, arg_R_0, arg_mem_R}},                        // STREXH<c> <Rd>,<Rt>,[<Rn>] cond:4|0|0|0|1|1|1|1|0|Rn:4|Rd:4|1|1|1|1|1|0|0|1|Rt:4
+	{0x0e500ff0, 0x000000b0, 2, STRH_EQ, 0x1c04, instArgs{arg_R_12, arg_mem_R_pm_R_W}},                            // STRH<c> <Rt>,[<Rn>,+/-<Rm>]{!} cond:4|0|0|0|P|U|0|W|0|Rn:4|Rt:4|0|0|0|0|1|0|1|1|Rm:4
+	{0x0e5000f0, 0x004000b0, 2, STRH_EQ, 0x1c04, instArgs{arg_R_12, arg_mem_R_pm_imm8_W}},                         // STRH<c> <Rt>,[<Rn>{,#+/-<imm8>}]{!} cond:4|0|0|0|P|U|1|W|0|Rn:4|Rt:4|imm4H:4|1|0|1|1|imm4L:4
+	{0x0f7000f0, 0x006000b0, 4, STRHT_EQ, 0x1c04, instArgs{arg_R_12, arg_mem_R_pm_imm8_postindex}},                // STRHT<c> <Rt>, [<Rn>] {,#+/-<imm8>} cond:4|0|0|0|0|U|1|1|0|Rn:4|Rt:4|imm4H:4|1|0|1|1|imm4L:4
+	{0x0f700ff0, 0x002000b0, 4, STRHT_EQ, 0x1c04, instArgs{arg_R_12, arg_mem_R_pm_R_postindex}},                   // STRHT<c> <Rt>, [<Rn>], +/-<Rm> cond:4|0|0|0|0|U|0|1|0|Rn:4|Rt:4|0|0|0|0|1|0|1|1|Rm:4
+	{0x0f700000, 0x04200000, 4, STRT_EQ, 0x1c04, instArgs{arg_R_12, arg_mem_R_pm_imm12_postindex}},                // STRT<c> <Rt>, [<Rn>] {,#+/-<imm12>} cond:4|0|1|0|0|U|0|1|0|Rn:4|Rt:4|imm12:12
+	{0x0f700010, 0x06200000, 4, STRT_EQ, 0x1c04, instArgs{arg_R_12, arg_mem_R_pm_R_shift_imm_postindex}},          // STRT<c> <Rt>,[<Rn>],+/-<Rm>{, <shift>} cond:4|0|1|1|0|U|0|1|0|Rn:4|Rt:4|imm5:5|type:2|0|Rm:4
+	{0x0fe00000, 0x02400000, 2, SUB_EQ, 0x14011c04, instArgs{arg_R_12, arg_R_16, arg_const}},                      // SUB{S}<c> <Rd>,<Rn>,#<const> cond:4|0|0|1|0|0|1|0|S|Rn:4|Rd:4|imm12:12
+	{0x0fe00090, 0x00400010, 4, SUB_EQ, 0x14011c04, instArgs{arg_R_12, arg_R_16, arg_R_shift_R}},                  // SUB{S}<c> <Rd>,<Rn>,<Rm>,<type> <Rs> cond:4|0|0|0|0|0|1|0|S|Rn:4|Rd:4|Rs:4|0|type:2|1|Rm:4
+	{0x0fe00010, 0x00400000, 2, SUB_EQ, 0x14011c04, instArgs{arg_R_12, arg_R_16, arg_R_shift_imm}},                // SUB{S}<c> <Rd>,<Rn>,<Rm>{,<shift>} cond:4|0|0|0|0|0|1|0|S|Rn:4|Rd:4|imm5:5|type:2|0|Rm:4
+	{0x0fef0000, 0x024d0000, 2, SUB_EQ, 0x14011c04, instArgs{arg_R_12, arg_SP, arg_const}},                        // SUB{S}<c> <Rd>,SP,#<const> cond:4|0|0|1|0|0|1|0|S|1|1|0|1|Rd:4|imm12:12
+	{0x0fef0010, 0x004d0000, 2, SUB_EQ, 0x14011c04, instArgs{arg_R_12, arg_SP, arg_R_shift_imm}},                  // SUB{S}<c> <Rd>,SP,<Rm>{,<shift>} cond:4|0|0|0|0|0|1|0|S|1|1|0|1|Rd:4|imm5:5|type:2|0|Rm:4
+	{0x0f000000, 0x0f000000, 4, SVC_EQ, 0x1c04, instArgs{arg_imm24}},                                              // SVC<c> #<imm24> cond:4|1|1|1|1|imm24:24
+	{0x0fb00ff0, 0x01000090, 4, SWP_EQ, 0x16011c04, instArgs{arg_R_12, arg_R_0, arg_mem_R}},                       // SWP{B}<c> <Rt>,<Rm>,[<Rn>] cond:4|0|0|0|1|0|B|0|0|Rn:4|Rt:4|0|0|0|0|1|0|0|1|Rm:4
+	{0x0ff003f0, 0x06800070, 2, SXTAB16_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_rotate}},                   // SXTAB16<c> <Rd>,<Rn>,<Rm>{,<rotation>} cond:4|0|1|1|0|1|0|0|0|Rn:4|Rd:4|rotate:2|0|0|0|1|1|1|Rm:4
+	{0x0ff003f0, 0x06a00070, 2, SXTAB_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_rotate}},                     // SXTAB<c> <Rd>,<Rn>,<Rm>{,<rotation>} cond:4|0|1|1|0|1|0|1|0|Rn:4|Rd:4|rotate:2|0|0|0|1|1|1|Rm:4
+	{0x0ff003f0, 0x06b00070, 2, SXTAH_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_rotate}},                     // SXTAH<c> <Rd>,<Rn>,<Rm>{,<rotation>} cond:4|0|1|1|0|1|0|1|1|Rn:4|Rd:4|rotate:2|0|0|0|1|1|1|Rm:4
+	{0x0fff03f0, 0x068f0070, 4, SXTB16_EQ, 0x1c04, instArgs{arg_R_12, arg_R_rotate}},                              // SXTB16<c> <Rd>,<Rm>{,<rotation>} cond:4|0|1|1|0|1|0|0|0|1|1|1|1|Rd:4|rotate:2|0|0|0|1|1|1|Rm:4
+	{0x0fff03f0, 0x06af0070, 4, SXTB_EQ, 0x1c04, instArgs{arg_R_12, arg_R_rotate}},                                // SXTB<c> <Rd>,<Rm>{,<rotation>} cond:4|0|1|1|0|1|0|1|0|1|1|1|1|Rd:4|rotate:2|0|0|0|1|1|1|Rm:4
+	{0x0fff03f0, 0x06bf0070, 4, SXTH_EQ, 0x1c04, instArgs{arg_R_12, arg_R_rotate}},                                // SXTH<c> <Rd>,<Rm>{,<rotation>} cond:4|0|1|1|0|1|0|1|1|1|1|1|1|Rd:4|rotate:2|0|0|0|1|1|1|Rm:4
+	{0x0ff0f000, 0x03300000, 4, TEQ_EQ, 0x1c04, instArgs{arg_R_16, arg_const}},                                    // TEQ<c> <Rn>,#<const> cond:4|0|0|1|1|0|0|1|1|Rn:4|(0)|(0)|(0)|(0)|imm12:12
+	{0x0ff00000, 0x03300000, 3, TEQ_EQ, 0x1c04, instArgs{arg_R_16, arg_const}},                                    // TEQ<c> <Rn>,#<const> cond:4|0|0|1|1|0|0|1|1|Rn:4|(0)|(0)|(0)|(0)|imm12:12
+	{0x0ff0f090, 0x01300010, 4, TEQ_EQ, 0x1c04, instArgs{arg_R_16, arg_R_shift_R}},                                // TEQ<c> <Rn>,<Rm>,<type> <Rs> cond:4|0|0|0|1|0|0|1|1|Rn:4|(0)|(0)|(0)|(0)|Rs:4|0|type:2|1|Rm:4
+	{0x0ff00090, 0x01300010, 3, TEQ_EQ, 0x1c04, instArgs{arg_R_16, arg_R_shift_R}},                                // TEQ<c> <Rn>,<Rm>,<type> <Rs> cond:4|0|0|0|1|0|0|1|1|Rn:4|(0)|(0)|(0)|(0)|Rs:4|0|type:2|1|Rm:4
+	{0x0ff0f010, 0x01300000, 4, TEQ_EQ, 0x1c04, instArgs{arg_R_16, arg_R_shift_imm}},                              // TEQ<c> <Rn>,<Rm>{,<shift>} cond:4|0|0|0|1|0|0|1|1|Rn:4|(0)|(0)|(0)|(0)|imm5:5|type:2|0|Rm:4
+	{0x0ff00010, 0x01300000, 3, TEQ_EQ, 0x1c04, instArgs{arg_R_16, arg_R_shift_imm}},                              // TEQ<c> <Rn>,<Rm>{,<shift>} cond:4|0|0|0|1|0|0|1|1|Rn:4|(0)|(0)|(0)|(0)|imm5:5|type:2|0|Rm:4
+	{0x0ff0f000, 0x03100000, 4, TST_EQ, 0x1c04, instArgs{arg_R_16, arg_const}},                                    // TST<c> <Rn>,#<const> cond:4|0|0|1|1|0|0|0|1|Rn:4|(0)|(0)|(0)|(0)|imm12:12
+	{0x0ff00000, 0x03100000, 3, TST_EQ, 0x1c04, instArgs{arg_R_16, arg_const}},                                    // TST<c> <Rn>,#<const> cond:4|0|0|1|1|0|0|0|1|Rn:4|(0)|(0)|(0)|(0)|imm12:12
+	{0x0ff0f090, 0x01100010, 4, TST_EQ, 0x1c04, instArgs{arg_R_16, arg_R_shift_R}},                                // TST<c> <Rn>,<Rm>,<type> <Rs> cond:4|0|0|0|1|0|0|0|1|Rn:4|(0)|(0)|(0)|(0)|Rs:4|0|type:2|1|Rm:4
+	{0x0ff00090, 0x01100010, 3, TST_EQ, 0x1c04, instArgs{arg_R_16, arg_R_shift_R}},                                // TST<c> <Rn>,<Rm>,<type> <Rs> cond:4|0|0|0|1|0|0|0|1|Rn:4|(0)|(0)|(0)|(0)|Rs:4|0|type:2|1|Rm:4
+	{0x0ff0f010, 0x01100000, 4, TST_EQ, 0x1c04, instArgs{arg_R_16, arg_R_shift_imm}},                              // TST<c> <Rn>,<Rm>{,<shift>} cond:4|0|0|0|1|0|0|0|1|Rn:4|(0)|(0)|(0)|(0)|imm5:5|type:2|0|Rm:4
+	{0x0ff00010, 0x01100000, 3, TST_EQ, 0x1c04, instArgs{arg_R_16, arg_R_shift_imm}},                              // TST<c> <Rn>,<Rm>{,<shift>} cond:4|0|0|0|1|0|0|0|1|Rn:4|(0)|(0)|(0)|(0)|imm5:5|type:2|0|Rm:4
+	{0x0ff00ff0, 0x06500f10, 4, UADD16_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0}},                         // UADD16<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|0|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|0|0|1|Rm:4
+	{0x0ff000f0, 0x06500f10, 3, UADD16_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0}},                         // UADD16<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|0|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|0|0|1|Rm:4
+	{0x0ff00ff0, 0x06500f90, 4, UADD8_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0}},                          // UADD8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|0|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|0|0|1|Rm:4
+	{0x0ff000f0, 0x06500f90, 3, UADD8_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0}},                          // UADD8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|0|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|0|0|1|Rm:4
+	{0x0ff00ff0, 0x06500f30, 4, UASX_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0}},                           // UASX<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|0|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|0|1|1|Rm:4
+	{0x0ff000f0, 0x06500f30, 3, UASX_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0}},                           // UASX<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|0|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|0|1|1|Rm:4
+	{0x0fe00070, 0x07e00050, 4, UBFX_EQ, 0x1c04, instArgs{arg_R_12, arg_R_0, arg_imm5, arg_widthm1}},              // UBFX<c> <Rd>,<Rn>,#<lsb>,#<widthm1> cond:4|0|1|1|1|1|1|1|widthm1:5|Rd:4|lsb:5|1|0|1|Rn:4
+	{0x0ff00ff0, 0x06700f10, 4, UHADD16_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0}},                        // UHADD16<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|1|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|0|0|1|Rm:4
+	{0x0ff000f0, 0x06700f10, 3, UHADD16_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0}},                        // UHADD16<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|1|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|0|0|1|Rm:4
+	{0x0ff00ff0, 0x06700f90, 4, UHADD8_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0}},                         // UHADD8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|1|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|0|0|1|Rm:4
+	{0x0ff000f0, 0x06700f90, 3, UHADD8_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0}},                         // UHADD8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|1|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|0|0|1|Rm:4
+	{0x0ff00ff0, 0x06700f30, 4, UHASX_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0}},                          // UHASX<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|1|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|0|1|1|Rm:4
+	{0x0ff000f0, 0x06700f30, 3, UHASX_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0}},                          // UHASX<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|1|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|0|1|1|Rm:4
+	{0x0ff00ff0, 0x06700f50, 4, UHSAX_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0}},                          // UHSAX<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|1|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|1|0|1|Rm:4
+	{0x0ff000f0, 0x06700f50, 3, UHSAX_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0}},                          // UHSAX<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|1|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|1|0|1|Rm:4
+	{0x0ff00ff0, 0x06700f70, 4, UHSUB16_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0}},                        // UHSUB16<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|1|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|1|1|1|Rm:4
+	{0x0ff000f0, 0x06700f70, 3, UHSUB16_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0}},                        // UHSUB16<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|1|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|1|1|1|Rm:4
+	{0x0ff00ff0, 0x06700ff0, 4, UHSUB8_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0}},                         // UHSUB8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|1|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|1|1|1|Rm:4
+	{0x0ff000f0, 0x06700ff0, 3, UHSUB8_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0}},                         // UHSUB8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|1|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|1|1|1|Rm:4
+	{0x0ff000f0, 0x00400090, 4, UMAAL_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0, arg_R_8}},                 // UMAAL<c> <RdLo>,<RdHi>,<Rn>,<Rm> cond:4|0|0|0|0|0|1|0|0|RdHi:4|RdLo:4|Rm:4|1|0|0|1|Rn:4
+	{0x0fe000f0, 0x00a00090, 4, UMLAL_EQ, 0x14011c04, instArgs{arg_R_12, arg_R_16, arg_R_0, arg_R_8}},             // UMLAL{S}<c> <RdLo>,<RdHi>,<Rn>,<Rm> cond:4|0|0|0|0|1|0|1|S|RdHi:4|RdLo:4|Rm:4|1|0|0|1|Rn:4
+	{0x0fe000f0, 0x00800090, 4, UMULL_EQ, 0x14011c04, instArgs{arg_R_12, arg_R_16, arg_R_0, arg_R_8}},             // UMULL{S}<c> <RdLo>,<RdHi>,<Rn>,<Rm> cond:4|0|0|0|0|1|0|0|S|RdHi:4|RdLo:4|Rm:4|1|0|0|1|Rn:4
+	{0x0ff00ff0, 0x06600f10, 4, UQADD16_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0}},                        // UQADD16<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|1|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|0|0|1|Rm:4
+	{0x0ff000f0, 0x06600f10, 3, UQADD16_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0}},                        // UQADD16<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|1|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|0|0|1|Rm:4
+	{0x0ff00ff0, 0x06600f90, 4, UQADD8_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0}},                         // UQADD8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|1|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|0|0|1|Rm:4
+	{0x0ff000f0, 0x06600f90, 3, UQADD8_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0}},                         // UQADD8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|1|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|0|0|1|Rm:4
+	{0x0ff00ff0, 0x06600f30, 4, UQASX_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0}},                          // UQASX<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|1|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|0|1|1|Rm:4
+	{0x0ff000f0, 0x06600f30, 3, UQASX_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0}},                          // UQASX<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|1|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|0|1|1|Rm:4
+	{0x0ff00ff0, 0x06600f50, 4, UQSAX_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0}},                          // UQSAX<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|1|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|1|0|1|Rm:4
+	{0x0ff000f0, 0x06600f50, 3, UQSAX_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0}},                          // UQSAX<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|1|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|1|0|1|Rm:4
+	{0x0ff00ff0, 0x06600f70, 4, UQSUB16_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0}},                        // UQSUB16<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|1|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|1|1|1|Rm:4
+	{0x0ff000f0, 0x06600f70, 3, UQSUB16_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0}},                        // UQSUB16<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|1|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|1|1|1|Rm:4
+	{0x0ff00ff0, 0x06600ff0, 4, UQSUB8_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0}},                         // UQSUB8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|1|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|1|1|1|Rm:4
+	{0x0ff000f0, 0x06600ff0, 3, UQSUB8_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0}},                         // UQSUB8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|1|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|1|1|1|Rm:4
+	{0x0ff0f0f0, 0x0780f010, 4, USAD8_EQ, 0x1c04, instArgs{arg_R_16, arg_R_0, arg_R_8}},                           // USAD8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|1|1|0|0|0|Rd:4|1|1|1|1|Rm:4|0|0|0|1|Rn:4
+	{0x0ff000f0, 0x07800010, 2, USADA8_EQ, 0x1c04, instArgs{arg_R_16, arg_R_0, arg_R_8, arg_R_12}},                // USADA8<c> <Rd>,<Rn>,<Rm>,<Ra> cond:4|0|1|1|1|1|0|0|0|Rd:4|Ra:4|Rm:4|0|0|0|1|Rn:4
+	{0x0ff00ff0, 0x06e00f30, 4, USAT16_EQ, 0x1c04, instArgs{arg_R_12, arg_satimm4, arg_R_0}},                      // USAT16<c> <Rd>,#<sat_imm4>,<Rn> cond:4|0|1|1|0|1|1|1|0|sat_imm:4|Rd:4|(1)|(1)|(1)|(1)|0|0|1|1|Rn:4
+	{0x0ff000f0, 0x06e00f30, 3, USAT16_EQ, 0x1c04, instArgs{arg_R_12, arg_satimm4, arg_R_0}},                      // USAT16<c> <Rd>,#<sat_imm4>,<Rn> cond:4|0|1|1|0|1|1|1|0|sat_imm:4|Rd:4|(1)|(1)|(1)|(1)|0|0|1|1|Rn:4
+	{0x0fe00030, 0x06e00010, 4, USAT_EQ, 0x1c04, instArgs{arg_R_12, arg_satimm5, arg_R_shift_imm}},                // USAT<c> <Rd>,#<sat_imm5>,<Rn>{,<shift>} cond:4|0|1|1|0|1|1|1|sat_imm:5|Rd:4|imm5:5|sh|0|1|Rn:4
+	{0x0ff00ff0, 0x06500f50, 4, USAX_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0}},                           // USAX<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|0|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|1|0|1|Rm:4
+	{0x0ff000f0, 0x06500f50, 3, USAX_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0}},                           // USAX<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|0|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|1|0|1|Rm:4
+	{0x0ff00ff0, 0x06500f70, 4, USUB16_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0}},                         // USUB16<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|0|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|1|1|1|Rm:4
+	{0x0ff000f0, 0x06500f70, 3, USUB16_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0}},                         // USUB16<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|0|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|1|1|1|Rm:4
+	{0x0ff00ff0, 0x06500ff0, 4, USUB8_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0}},                          // USUB8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|0|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|1|1|1|Rm:4
+	{0x0ff000f0, 0x06500ff0, 3, USUB8_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_0}},                          // USUB8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|0|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|1|1|1|Rm:4
+	{0x0ff003f0, 0x06c00070, 2, UXTAB16_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_rotate}},                   // UXTAB16<c> <Rd>,<Rn>,<Rm>{,<rotation>} cond:4|0|1|1|0|1|1|0|0|Rn:4|Rd:4|rotate:2|0|0|0|1|1|1|Rm:4
+	{0x0ff003f0, 0x06e00070, 2, UXTAB_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_rotate}},                     // UXTAB<c> <Rd>,<Rn>,<Rm>{,<rotation>} cond:4|0|1|1|0|1|1|1|0|Rn:4|Rd:4|rotate:2|0|0|0|1|1|1|Rm:4
+	{0x0ff003f0, 0x06f00070, 2, UXTAH_EQ, 0x1c04, instArgs{arg_R_12, arg_R_16, arg_R_rotate}},                     // UXTAH<c> <Rd>,<Rn>,<Rm>{,<rotation>} cond:4|0|1|1|0|1|1|1|1|Rn:4|Rd:4|rotate:2|0|0|0|1|1|1|Rm:4
+	{0x0fff03f0, 0x06cf0070, 4, UXTB16_EQ, 0x1c04, instArgs{arg_R_12, arg_R_rotate}},                              // UXTB16<c> <Rd>,<Rm>{,<rotation>} cond:4|0|1|1|0|1|1|0|0|1|1|1|1|Rd:4|rotate:2|0|0|0|1|1|1|Rm:4
+	{0x0fff03f0, 0x06ef0070, 4, UXTB_EQ, 0x1c04, instArgs{arg_R_12, arg_R_rotate}},                                // UXTB<c> <Rd>,<Rm>{,<rotation>} cond:4|0|1|1|0|1|1|1|0|1|1|1|1|Rd:4|rotate:2|0|0|0|1|1|1|Rm:4
+	{0x0fff03f0, 0x06ff0070, 4, UXTH_EQ, 0x1c04, instArgs{arg_R_12, arg_R_rotate}},                                // UXTH<c> <Rd>,<Rm>{,<rotation>} cond:4|0|1|1|0|1|1|1|1|1|1|1|1|Rd:4|rotate:2|0|0|0|1|1|1|Rm:4
+	{0x0fb00e10, 0x0e000a00, 4, VMLA_EQ_F32, 0x60108011c04, instArgs{arg_Sd_Dd, arg_Sn_Dn, arg_Sm_Dm}},            // V<MLA,MLS><c>.F<32,64> <Sd,Dd>, <Sn,Dn>, <Sm,Dm> cond:4|1|1|1|0|0|D|0|0|Vn:4|Vd:4|1|0|1|sz|N|op|M|0|Vm:4
+	{0x0fbf0ed0, 0x0eb00ac0, 4, VABS_EQ_F32, 0x8011c04, instArgs{arg_Sd_Dd, arg_Sm_Dm}},                           // VABS<c>.F<32,64> <Sd,Dd>, <Sm,Dm> cond:4|1|1|1|0|1|D|1|1|0|0|0|0|Vd:4|1|0|1|sz|1|1|M|0|Vm:4
+	{0x0fb00e50, 0x0e300a00, 4, VADD_EQ_F32, 0x8011c04, instArgs{arg_Sd_Dd, arg_Sn_Dn, arg_Sm_Dm}},                // VADD<c>.F<32,64> <Sd,Dd>, <Sn,Dn>, <Sm,Dm> cond:4|1|1|1|0|0|D|1|1|Vn:4|Vd:4|1|0|1|sz|N|0|M|0|Vm:4
+	{0x0fbf0e7f, 0x0eb50a40, 4, VCMP_EQ_F32, 0x70108011c04, instArgs{arg_Sd_Dd, arg_fp_0}},                        // VCMP{E}<c>.F<32,64> <Sd,Dd>, #0.0 cond:4|1|1|1|0|1|D|1|1|0|1|0|1|Vd:4|1|0|1|sz|E|1|0|0|(0)|(0)|(0)|(0)
+	{0x0fbf0e70, 0x0eb50a40, 3, VCMP_EQ_F32, 0x70108011c04, instArgs{arg_Sd_Dd, arg_fp_0}},                        // VCMP{E}<c>.F<32,64> <Sd,Dd>, #0.0 cond:4|1|1|1|0|1|D|1|1|0|1|0|1|Vd:4|1|0|1|sz|E|1|0|0|(0)|(0)|(0)|(0)
+	{0x0fbf0e50, 0x0eb40a40, 4, VCMP_EQ_F32, 0x70108011c04, instArgs{arg_Sd_Dd, arg_Sm_Dm}},                       // VCMP{E}<c>.F<32,64> <Sd,Dd>, <Sm,Dm> cond:4|1|1|1|0|1|D|1|1|0|1|0|0|Vd:4|1|0|1|sz|E|1|M|0|Vm:4
+	{0x0fbe0e50, 0x0eba0a40, 4, VCVT_EQ_F32_FXS16, 0x801100107011c04, instArgs{arg_Sd_Dd, arg_Sd_Dd, arg_fbits}},  // VCVT<c>.F<32,64>.FX<S,U><16,32> <Sd,Dd>, <Sd,Dd>, #<fbits> cond:4|1|1|1|0|1|D|1|1|1|0|1|U|Vd:4|1|0|1|sz|sx|1|i|0|imm4:4
+	{0x0fbe0e50, 0x0ebe0a40, 4, VCVT_EQ_FXS16_F32, 0x1001070108011c04, instArgs{arg_Sd_Dd, arg_Sd_Dd, arg_fbits}}, // VCVT<c>.FX<S,U><16,32>.F<32,64> <Sd,Dd>, <Sd,Dd>, #<fbits> cond:4|1|1|1|0|1|D|1|1|1|1|1|U|Vd:4|1|0|1|sz|sx|1|i|0|imm4:4
+	{0x0fbf0ed0, 0x0eb70ac0, 4, VCVT_EQ_F64_F32, 0x8011c04, instArgs{arg_Dd_Sd, arg_Sm_Dm}},                       // VCVT<c>.<F64.F32,F32.F64> <Dd,Sd>, <Sm,Dm> cond:4|1|1|1|0|1|D|1|1|0|1|1|1|Vd:4|1|0|1|sz|1|1|M|0|Vm:4
+	{0x0fbe0f50, 0x0eb20a40, 4, VCVTB_EQ_F32_F16, 0x70110011c04, instArgs{arg_Sd, arg_Sm}},                        // VCVT<B,T><c>.<F32.F16,F16.F32> <Sd>, <Sm> cond:4|1|1|1|0|1|D|1|1|0|0|1|op|Vd:4|1|0|1|0|T|1|M|0|Vm:4
+	{0x0fbf0e50, 0x0eb80a40, 4, VCVT_EQ_F32_U32, 0x80107011c04, instArgs{arg_Sd_Dd, arg_Sm}},                      // VCVT<c>.F<32,64>.<U,S>32 <Sd,Dd>, <Sm> cond:4|1|1|1|0|1|D|1|1|1|0|0|0|Vd:4|1|0|1|sz|op|1|M|0|Vm:4
+	{0x0fbe0e50, 0x0ebc0a40, 4, VCVTR_EQ_U32_F32, 0x701100108011c04, instArgs{arg_Sd, arg_Sm_Dm}},                 // VCVT<R,><c>.<U,S>32.F<32,64> <Sd>, <Sm,Dm> cond:4|1|1|1|0|1|D|1|1|1|1|0|signed|Vd:4|1|0|1|sz|op|1|M|0|Vm:4
+	{0x0fb00e50, 0x0e800a00, 4, VDIV_EQ_F32, 0x8011c04, instArgs{arg_Sd_Dd, arg_Sn_Dn, arg_Sm_Dm}},                // VDIV<c>.F<32,64> <Sd,Dd>, <Sn,Dn>, <Sm,Dm> cond:4|1|1|1|0|1|D|0|0|Vn:4|Vd:4|1|0|1|sz|N|0|M|0|Vm:4
+	{0x0f300e00, 0x0d100a00, 4, VLDR_EQ, 0x1c04, instArgs{arg_Sd_Dd, arg_mem_R_pm_imm8at0_offset}},                // VLDR<c> <Sd,Dd>, [<Rn>{,#+/-<imm8>}] cond:4|1|1|0|1|U|D|0|1|Rn:4|Vd:4|1|0|1|sz|imm8:8
+	{0x0ff00f7f, 0x0e000a10, 4, VMOV_EQ, 0x1c04, instArgs{arg_Sn, arg_R_12}},                                      // VMOV<c> <Sn>, <Rt> cond:4|1|1|1|0|0|0|0|0|Vn:4|Rt:4|1|0|1|0|N|0|0|1|0|0|0|0
+	{0x0ff00f7f, 0x0e100a10, 4, VMOV_EQ, 0x1c04, instArgs{arg_R_12, arg_Sn}},                                      // VMOV<c> <Rt>, <Sn> cond:4|1|1|1|0|0|0|0|1|Vn:4|Rt:4|1|0|1|0|N|0|0|1|0|0|0|0
+	{0x0fd00f7f, 0x0e100b10, 4, VMOV_EQ_32, 0x1c04, instArgs{arg_R_12, arg_Dn_half}},                              // VMOV<c>.32 <Rt>, <Dn[x]> cond:4|1|1|1|0|0|0|opc1|1|Vn:4|Rt:4|1|0|1|1|N|0|0|1|0|0|0|0
+	{0x0fd00f7f, 0x0e000b10, 4, VMOV_EQ_32, 0x1c04, instArgs{arg_Dn_half, arg_R_12}},                              // VMOV<c>.32 <Dd[x]>, <Rt> cond:4|1|1|1|0|0|0|opc1|0|Vd:4|Rt:4|1|0|1|1|D|0|0|1|0|0|0|0
+	{0x0fb00ef0, 0x0eb00a00, 4, VMOV_EQ_F32, 0x8011c04, instArgs{arg_Sd_Dd, arg_imm_vfp}},                         // VMOV<c>.F<32,64> <Sd,Dd>, #<imm_vfp> cond:4|1|1|1|0|1|D|1|1|imm4H:4|Vd:4|1|0|1|sz|0|0|0|0|imm4L:4
+	{0x0fbf0ed0, 0x0eb00a40, 4, VMOV_EQ_F32, 0x8011c04, instArgs{arg_Sd_Dd, arg_Sm_Dm}},                           // VMOV<c>.F<32,64> <Sd,Dd>, <Sm,Dm> cond:4|1|1|1|0|1|D|1|1|0|0|0|0|Vd:4|1|0|1|sz|0|1|M|0|Vm:4
+	{0x0fff0fff, 0x0ef10a10, 4, VMRS_EQ, 0x1c04, instArgs{arg_R_12_nzcv, arg_FPSCR}},                              // VMRS<c> <Rt_nzcv>, FPSCR cond:4|1|1|1|0|1|1|1|1|0|0|0|1|Rt:4|1|0|1|0|0|0|0|1|0|0|0|0
+	{0x0fff0fff, 0x0ee10a10, 4, VMSR_EQ, 0x1c04, instArgs{arg_FPSCR, arg_R_12}},                                   // VMSR<c> FPSCR, <Rt> cond:4|1|1|1|0|1|1|1|0|0|0|0|1|Rt:4|1|0|1|0|0|0|0|1|0|0|0|0
+	{0x0fb00e50, 0x0e200a00, 4, VMUL_EQ_F32, 0x8011c04, instArgs{arg_Sd_Dd, arg_Sn_Dn, arg_Sm_Dm}},                // VMUL<c>.F<32,64> <Sd,Dd>, <Sn,Dn>, <Sm,Dm> cond:4|1|1|1|0|0|D|1|0|Vn:4|Vd:4|1|0|1|sz|N|0|M|0|Vm:4
+	{0x0fbf0ed0, 0x0eb10a40, 4, VNEG_EQ_F32, 0x8011c04, instArgs{arg_Sd_Dd, arg_Sm_Dm}},                           // VNEG<c>.F<32,64> <Sd,Dd>, <Sm,Dm> cond:4|1|1|1|0|1|D|1|1|0|0|0|1|Vd:4|1|0|1|sz|0|1|M|0|Vm:4
+	{0x0fb00e10, 0x0e100a00, 4, VNMLS_EQ_F32, 0x60108011c04, instArgs{arg_Sd_Dd, arg_Sn_Dn, arg_Sm_Dm}},           // VN<MLS,MLA><c>.F<32,64> <Sd,Dd>, <Sn,Dn>, <Sm,Dm> cond:4|1|1|1|0|0|D|0|1|Vn:4|Vd:4|1|0|1|sz|N|op|M|0|Vm:4
+	{0x0fb00e50, 0x0e200a40, 4, VNMUL_EQ_F32, 0x8011c04, instArgs{arg_Sd_Dd, arg_Sn_Dn, arg_Sm_Dm}},               // VNMUL<c>.F<32,64> <Sd,Dd>, <Sn,Dn>, <Sm,Dm> cond:4|1|1|1|0|0|D|1|0|Vn:4|Vd:4|1|0|1|sz|N|1|M|0|Vm:4
+	{0x0fbf0ed0, 0x0eb10ac0, 4, VSQRT_EQ_F32, 0x8011c04, instArgs{arg_Sd_Dd, arg_Sm_Dm}},                          // VSQRT<c>.F<32,64> <Sd,Dd>, <Sm,Dm> cond:4|1|1|1|0|1|D|1|1|0|0|0|1|Vd:4|1|0|1|sz|1|1|M|0|Vm:4
+	{0x0f300e00, 0x0d000a00, 4, VSTR_EQ, 0x1c04, instArgs{arg_Sd_Dd, arg_mem_R_pm_imm8at0_offset}},                // VSTR<c> <Sd,Dd>, [<Rn>{,#+/-<imm8>}] cond:4|1|1|0|1|U|D|0|0|Rn:4|Vd:4|1|0|1|sz|imm8:8
+	{0x0fb00e50, 0x0e300a40, 4, VSUB_EQ_F32, 0x8011c04, instArgs{arg_Sd_Dd, arg_Sn_Dn, arg_Sm_Dm}},                // VSUB<c>.F<32,64> <Sd,Dd>, <Sn,Dn>, <Sm,Dm> cond:4|1|1|1|0|0|D|1|1|Vn:4|Vd:4|1|0|1|sz|N|1|M|0|Vm:4
+	{0x0fffffff, 0x0320f002, 4, WFE_EQ, 0x1c04, instArgs{}},                                                       // WFE<c> cond:4|0|0|1|1|0|0|1|0|0|0|0|0|(1)|(1)|(1)|(1)|(0)|(0)|(0)|(0)|0|0|0|0|0|0|1|0
+	{0x0fff00ff, 0x0320f002, 3, WFE_EQ, 0x1c04, instArgs{}},                                                       // WFE<c> cond:4|0|0|1|1|0|0|1|0|0|0|0|0|(1)|(1)|(1)|(1)|(0)|(0)|(0)|(0)|0|0|0|0|0|0|1|0
+	{0x0fffffff, 0x0320f003, 4, WFI_EQ, 0x1c04, instArgs{}},                                                       // WFI<c> cond:4|0|0|1|1|0|0|1|0|0|0|0|0|(1)|(1)|(1)|(1)|(0)|(0)|(0)|(0)|0|0|0|0|0|0|1|1
+	{0x0fff00ff, 0x0320f003, 3, WFI_EQ, 0x1c04, instArgs{}},                                                       // WFI<c> cond:4|0|0|1|1|0|0|1|0|0|0|0|0|(1)|(1)|(1)|(1)|(0)|(0)|(0)|(0)|0|0|0|0|0|0|1|1
+	{0x0fffffff, 0x0320f001, 4, YIELD_EQ, 0x1c04, instArgs{}},                                                     // YIELD<c> cond:4|0|0|1|1|0|0|1|0|0|0|0|0|(1)|(1)|(1)|(1)|(0)|(0)|(0)|(0)|0|0|0|0|0|0|0|1
+	{0x0fff00ff, 0x0320f001, 3, YIELD_EQ, 0x1c04, instArgs{}},                                                     // YIELD<c> cond:4|0|0|1|1|0|0|1|0|0|0|0|0|(1)|(1)|(1)|(1)|(0)|(0)|(0)|(0)|0|0|0|0|0|0|0|1
+	{0xffffffff, 0xf7fabcfd, 4, UNDEF, 0x0, instArgs{}},                                                           // UNDEF 1|1|1|1|0|1|1|1|1|1|1|1|1|0|1|0|1|0|1|1|1|1|0|0|1|1|1|1|1|1|0|1
+}
diff --git a/src/cmd/internal/rsc.io/arm/armasm/testdata/Makefile b/src/cmd/internal/rsc.io/arm/armasm/testdata/Makefile
new file mode 100644
index 0000000..1adab68
--- /dev/null
+++ b/src/cmd/internal/rsc.io/arm/armasm/testdata/Makefile
@@ -0,0 +1,5 @@
+newdecode.txt:
+	cd ..; go test -cover -run 'ObjdumpARMCond' -v -timeout 10h -printtests -long 2>&1 | tee log
+	cd ..; go test -cover -run 'ObjdumpARMUncond' -v -timeout 10h -printtests -long 2>&1 | tee -a log
+	egrep '	(gnu|plan9)	' ../log |sort >newdecode.txt
+
diff --git a/src/cmd/internal/rsc.io/arm/armasm/testdata/decode.txt b/src/cmd/internal/rsc.io/arm/armasm/testdata/decode.txt
new file mode 100644
index 0000000..cc1ea0a
--- /dev/null
+++ b/src/cmd/internal/rsc.io/arm/armasm/testdata/decode.txt
@@ -0,0 +1,306 @@
+000001f1|	1	gnu	setend le
+00100f61|	1	gnu	mrsvs r1, apsr
+00f02053|	1	gnu	noppl
+00f0d4f4|	1	gnu	pli [r4]
+01f020d3|	1	gnu	yieldle
+02002d59|	1	gnu	stmdbpl sp!, {r1}
+021da9d8|	1	gnu	stmle r9!, {r1, r8, sl, fp, ip}
+02c0b071|	1	gnu	movsvc ip, r2
+02f02073|	1	gnu	wfevc
+03f02013|	1	gnu	wfine
+03f05df7|	1	gnu	pld [sp, -r3]
+04009d34|	1	gnu	popcc {r0}
+043a52b1|	1	gnu	cmplt r2, r4, lsl #20
+04402de5|	1	gnu	push {r4}
+045b148d|	1	gnu	vldrhi d5, [r4, #-16]
+04f02093|	1	gnu	sevls
+0793eab0|	1	gnu	rsclt r9, sl, r7, lsl #6
+079bfb9e|	1	gnu	vmovls.f64 d25, #183
+0a4fc9d3|	1	gnu	bicle r4, r9, #10, 30
+0bac7ab6|	1	gnu	ldrbtlt sl, [sl], -fp, lsl #24
+0c2aee44|	1	gnu	strbtmi r2, [lr], #2572
+0c4bb000|	1	gnu	adcseq r4, r0, ip, lsl #22
+0e26d561|	1	gnu	bicsvs r2, r5, lr, lsl #12
+0f0fa011|	1	gnu	lslne r0, pc, #30
+0fa448e0|	1	gnu	sub sl, r8, pc, lsl #8
+101af1de|	1	gnu	vmrsle r1, fpscr
+108a0cee|	1	gnu	vmov s24, r8
+108a1dae|	1	gnu	vmovge r8, s26
+108ae14e|	1	gnu	vmsrmi fpscr, r8
+10faf1ae|	1	gnu	vmrsge apsr_nzcv, fpscr
+10fb052e|	1	gnu	vmovcs.32 d5[0], pc
+11c902b7|	1	gnu	smladlt r2, r1, r9, ip
+11ef5b16|	1	gnu	uadd16ne lr, fp, r1
+12fa87a7|	1	gnu	usad8ge r7, r2, sl
+135f2956|	1	gnu	qadd16pl r5, r9, r3
+13de9aa1|	1	gnu	orrsge sp, sl, r3, lsl lr
+145c0e40|	1	gnu	andmi r5, lr, r4, lsl ip
+150f7fd6|	1	gnu	uhadd16le r0, pc, r5
+15b9bf12|	1	gnu	adcsne fp, pc, #344064
+16373391|	1	gnu	teqls r3, r6, lsl r7
+19ef1966|	1	gnu	sadd16vs lr, r9, r9
+1ab0b091|	1	gnu	lslsls fp, sl, r0
+1b9f6fe6|	1	gnu	uqadd16 r9, pc, fp
+1bb58557|	1	gnu	usada8pl r5, fp, r5, fp
+1beff8e0|	1	gnu	rscs lr, r8, fp, lsl pc
+1caff0e6|	1	gnu	usat sl, #16, ip, lsl #30
+1d0f3d36|	1	gnu	shadd16cc r0, sp, sp
+1dca1d52|	1	gnu	andspl ip, sp, #118784
+1e4891d0|	1	gnu	addsle r4, r1, lr, lsl r8
+1f0889e6|	1	gnu	pkhbt r0, r9, pc, lsl #16
+1f1f6fe1|	1	gnu	clz r1, pc
+1f26d157|	1	gnu	bfcpl r2, #12, #6
+1ff07ff5|	1	gnu	clrex
+1fff2fd1|	1	gnu	bxle pc
+20f153f6|	1	gnu	pli [r3, -r0, lsr #2]
+21047013|	1	gnu	cmnne r0, #553648128
+21c2eb8b|	1	gnu	blhi .-0x50f778
+21c2ebfb|	1	gnu	blx .-0x50f776
+21fa62ee|	1	gnu	vmul.f32 s31, s4, s3
+23005720|	1	gnu	subscs r0, r7, r3, lsr #32
+236a303e|	1	gnu	vaddcc.f32 s12, s0, s7
+23f055f6|	1	gnu	pli [r5, -r3, lsr #32]
+2430a031|	1	gnu	lsrcc r3, r4, #32
+245d0803|	1	gnu	movweq r5, #36132
+251a86be|	1	gnu	vdivlt.f32 s2, s12, s11
+25db7b81|	1	gnu	cmnhi fp, r5, lsr #22
+26bc3553|	1	gnu	teqpl r5, #9728
+277c2d69|	1	gnu	pushvs {r0, r1, r2, r5, sl, fp, ip, sp, lr}
+29fc1cf5|	1	gnu	pldw [ip, #-3113]
+29ff2fc1|	1	gnu	bxjgt r9
+2decd9c0|	1	gnu	sbcsgt lr, r9, sp, lsr #24
+30fa5e47|	1	gnu	smmulrmi lr, r0, sl
+316f64d6|	1	gnu	uqasxle r6, r4, r1
+323f5da6|	1	gnu	uasxge r3, sp, r2
+327fe5e6|	1	gnu	usat16 r7, #5, r2
+330151e3|	1	gnu	cmp r1, #-1073741812
+34af2ae6|	1	gnu	qasx sl, sl, r4
+35fd3710|	1	gnu	eorsne pc, r7, r5, lsr sp
+36def1c1|	1	gnu	mvnsgt sp, r6, lsr lr
+3801b061|	1	gnu	lsrsvs r0, r8, r1
+38985477|	1	gnu	smmlarvc r4, r8, r8, r9
+3a2fbfa6|	1	gnu	revge r2, sl
+3a3f1b06|	1	gnu	sasxeq r3, fp, sl
+3a7fa346|	1	gnu	ssat16mi r7, #4, sl
+3a943b94|	1	gnu	ldrtls r9, [fp], #-1082
+3bf505e7|	1	gnu	smuadx r5, fp, r5
+3cef7086|	1	gnu	uhasxhi lr, r0, ip
+3e5f3ec6|	1	gnu	shasxgt r5, lr, lr
+3f4fff86|	1	gnu	rbithi r4, pc
+3faf4717|	1	gnu	smlaldxne sl, r7, pc, pc
+3fff2fc1|	1	gnu	blxgt pc
+402bbf7e|	1	gnu	vcvtvc.u16.f64 d2, d2, #16
+403ab5de|	1	gnu	vcmple.f32 s6, #0
+40eb363e|	1	gnu	vsubcc.f64 d14, d6, d0
+420f73d1|	1	gnu	cmnle r3, r2, asr #30
+424a648e|	1	gnu	vnmulhi.f32 s9, s8, s4
+4284d717|	1	gnu	ldrbne r8, [r7, r2, asr #8]
+42a599c3|	1	gnu	orrsgt sl, r9, #276824064
+42abf0be|	1	gnu	vmovlt.f64 d26, d2
+446ea031|	1	gnu	asrcc r6, r4, #28
+4a953557|	1	gnu	ldrpl r9, [r5, -sl, asr #10]!
+4ab6f712|	1	gnu	rscsne fp, r7, #77594624
+4af07ff5|	1	gnu	dsb #10
+4df6def4|	1	gnu	pli [lr, #1613]
+4efbf52e|	1	gnu	vcmpcs.f64 d31, #0
+50aaac79|	1	gnu	stmibvc ip!, {r4, r6, r9, fp, sp, pc}
+50caf011|	1	gnu	mvnsne ip, r0, asr sl
+50f04961|	1	gnu	qdaddvs pc, r0, r9
+51282008|	1	gnu	stmdaeq r0!, {r0, r4, r6, fp, sp}
+52bf6576|	1	gnu	uqsaxvc fp, r5, r2
+5345c9d0|	1	gnu	sbcle r4, r9, r3, asr r5
+538f5e46|	1	gnu	usaxmi r8, lr, r3
+54106d31|	1	gnu	qdsubcc r1, r4, sp
+56e0e557|	1	gnu	ubfxpl lr, r6, #0, #6
+57073d11|	1	gnu	teqne sp, r7, asr r7
+58bb0aa9|	1	gnu	stmdbge sl, {r3, r4, r6, r8, r9, fp, ip, sp, pc}
+58f007b1|	1	gnu	qaddlt pc, r8, r7
+59fd0e77|	1	gnu	smusdvc lr, r9, sp
+5ab7f1c5|	1	gnu	ldrbgt fp, [r1, #1882]!
+5abf23c6|	1	gnu	qsaxgt fp, r3, sl
+5b8f1c96|	1	gnu	ssaxls r8, ip, fp
+5b98ab97|	1	gnu	sbfxls r9, fp, #16, #12
+5bc9b041|	1	gnu	asrsmi ip, fp, r9
+5bf07ff5|	1	gnu	dmb #11
+5c102b81|	1	gnu	qsubhi r1, ip, fp
+5caa49e1|	1	gnu	qdadd sl, ip, r9
+5d3f7226|	1	gnu	uhsaxcs r3, r2, sp
+5db55470|	1	gnu	subsvc fp, r4, sp, asr r5
+5ef14387|	1	gnu	smlsldhi pc, r3, lr, r1
+5f540a11|	1	gnu	qaddne r5, pc, sl
+5f9079d1|	1	gnu	cmnle r9, pc, asr r0
+5faf3f66|	1	gnu	shsaxvs sl, pc, pc
+605071d7|	1	gnu	ldrble r5, [r1, -r0, rrx]!
+614adc76|	1	gnu	ldrbvc r4, [ip], r1, ror #20
+616b9e42|	1	gnu	addsmi r6, lr, #99328
+62c84f15|	1	gnu	strbne ip, [pc, #-2146]
+62f051f7|	1	gnu	pld [r1, -r2, rrx]
+6346c393|	1	gnu	bicls r4, r3, #103809024
+654abbae|	1	gnu	vcvtge.f32.u16 s8, s8, #5
+65a5f0e3|	1	gnu	mvns sl, #423624704
+65f796f7|	1	gnu	pldw [r6, r5, ror #14]
+670bb12e|	1	gnu	vnegcs.f64 d0, d23
+67903731|	1	gnu	teqcc r7, r7, rrx
+68ddc637|	1	gnu	strbcc sp, [r6, r8, ror #26]
+695b3ab6|	1	gnu	ldrtlt r5, [sl], -r9, ror #22
+697cfc71|	1	gnu	mvnsvc r7, r9, ror #24
+6a0ab3ee|	1	gnu	vcvtb.f16.f32 s0, s21
+6ad9ad54|	1	gnu	strtpl sp, [sp], #2410
+6af07ff5|	1	gnu	isb #10
+6afa6f10|	1	gnu	rsbne pc, pc, sl, ror #20
+6d5b19ee|	1	gnu	vnmla.f64 d5, d9, d29
+6d60b071|	1	gnu	rrxsvc r6, sp
+6df754f7|	1	gnu	pld [r4, -sp, ror #14]
+70065821|	1	gnu	cmpcs r8, r0, ror r6
+7050ed86|	1	gnu	uxtabhi r5, sp, r0
+715f1186|	1	gnu	ssub16hi r5, r1, r1
+716c9805|	1	gnu	ldreq r6, [r8, #3185]
+718d5ab1|	1	gnu	cmplt sl, r1, ror sp
+71c8cfb6|	1	gnu	uxtb16lt ip, r1, ror #16
+7294af06|	1	gnu	sxtbeq r9, r2, ror #8
+72c0bac6|	1	gnu	sxtahgt ip, sl, r2
+730f6716|	1	gnu	uqsub16ne r0, r7, r3
+73608f46|	1	gnu	sxtb16mi r6, r3
+73687f22|	1	gnu	rsbscs r6, pc, #7536640
+74308816|	1	gnu	sxtab16ne r3, r8, r4
+757f3456|	1	gnu	shsub16pl r7, r4, r5
+77788016|	1	gnu	sxtab16ne r7, r0, r7, ror #16
+78061671|	1	gnu	tstvc r6, r8, ror r6
+780a2fe1|	1	gnu	bkpt 0xf0a8
+7850abd6|	1	gnu	sxtable r5, fp, r8
+792cef26|	1	gnu	uxtbcs r2, r9, ror #24
+799eb8e0|	1	gnu	adcs r9, r8, r9, ror lr
+799f5726|	1	gnu	usub16cs r9, r7, r9
+79d0bf16|	1	gnu	sxthne sp, r9
+7a037ba1|	1	gnu	cmnge fp, sl, ror r3
+7b0f2566|	1	gnu	qsub16vs r0, r5, fp
+7b79dd51|	1	gnu	bicspl r7, sp, fp, ror r9
+7b9a9f1d|	1	gnu	vldrne s18, [pc, #492]
+7c70cea6|	1	gnu	uxtab16ge r7, lr, ip
+7d48f966|	1	gnu	uxtahvs r4, r9, sp, ror #16
+7d5c13a1|	1	gnu	tstge r3, sp, ror ip
+7e0001f1|	1	gnu	setend le
+7e1c0ba7|	1	gnu	smlsdxge fp, lr, ip, r1
+7e567e40|	1	gnu	rsbsmi r5, lr, lr, ror r6
+7e8f73b6|	1	gnu	uhsub16lt r8, r3, lr
+7ef0ffd6|	1	gnu	uxthle pc, lr
+7faaa011|	1	gnu	rorne sl, pc, sl
+81f19af7|	1	gnu	pldw [sl, r1, lsl #3]
+82033901|	1	gnu	teqeq r9, r2, lsl #7
+82f316f5|	1	gnu	pldw [r6, #-898]
+830201f1|	1	gnu	setend be
+838a3b91|	1	gnu	teqls fp, r3, lsl #21
+8408af2f|	1	gnu	svccs 0x00af0884
+884201d1|	1	gnu	smlabble r1, r8, r2, r4
+8aa12e31|	1	gnu	smlawbcc lr, sl, r1, sl
+8b9b99c0|	1	gnu	addsgt r9, r9, fp, lsl #23
+8c005c81|	1	gnu	cmphi ip, ip, lsl #1
+8fb429c6|	1	gnu	strtgt fp, [r9], -pc, lsl #9
+907b1f9e|	1	gnu	vmovls.32 r7, d31[0]
+91975f25|	1	gnu	ldrbcs r9, [pc, #-1937]
+91b010e3|	1	gnu	tst r0, #145
+927facb1|	1	gnu	strexdlt r7, r2, [ip]
+92904c91|	1	gnu	swpbls r9, r2, [ip]
+92af1226|	1	gnu	sadd8cs sl, r2, r2
+92b28c70|	1	gnu	umullvc fp, ip, r2, r2
+945f68a6|	1	gnu	uqadd8ge r5, r8, r4
+950b2560|	1	gnu	mlavs r5, r5, fp, r0
+969fcf71|	1	gnu	strexbvc r9, r6, [pc]
+96cf35e6|	1	gnu	shadd8 ip, r5, r6
+98060eb0|	1	gnu	mullt lr, r8, r6
+9843fb93|	1	gnu	mvnsls r4, #152, 6
+9a3fe2b0|	1	gnu	smlallt r3, r2, sl, pc
+9aef58b6|	1	gnu	uadd8lt lr, r8, sl
+9afcdff5|	1	gnu	pld [pc, #3226]
+9c221810|	1	gnu	mulsne r8, ip, r2
+9c3bc9dd|	1	gnu	vstrle d19, [r9, #624]
+9c5f2606|	1	gnu	qadd8eq r5, r6, ip
+9d87dac0|	1	gnu	smullsgt r8, sl, sp, r7
+9e0f7c86|	1	gnu	uhadd8hi r0, ip, lr
+9e814560|	1	gnu	umaalvs r8, r5, lr, r1
+9e9f8dc1|	1	gnu	strexgt r9, lr, [sp]
+9ec3c9d7|	1	gnu	bfile ip, lr, #7, #3
+9ed26d90|	1	gnu	mlsls sp, lr, r2, sp
+9f7fd9c1|	1	gnu	ldrexbgt r7, [r9]
+9f7fea91|	1	gnu	strexhls r7, pc, [sl]
+9f9f9921|	1	gnu	ldrexcs r9, [r9]
+9faffd21|	1	gnu	ldrexhcs sl, [sp]
+9fcfbd61|	1	gnu	ldrexdvs ip, [sp]
+9ff7a710|	1	gnu	umlalne pc, r7, pc, r7
+a05459d3|	1	gnu	cmple r9, #160, 8
+a3062be1|	1	gnu	smulwb fp, r3, r6
+a68a92b1|	1	gnu	orrslt r8, r2, r6, lsr #21
+abff55f6|	1	gnu	pli [r5, -fp, lsr #31]
+addbf8ea|	1	gnu	b .-0x1c9148
+ae79b021|	1	gnu	lsrscs r7, lr, #19
+b590a3b1|	1	gnu	strhlt r9, [r3, r5]!
+b5b2e390|	1	gnu	strhtls fp, [r3], #37
+b6ac4e30|	1	gnu	strhcc sl, [lr], #-198
+b73fff86|	1	gnu	revshhi r3, r7
+b75fbfc6|	1	gnu	rev16gt r5, r7
+b80b7c80|	1	gnu	ldrhthi r0, [ip], #-184
+b82035e0|	1	gnu	ldrht r2, [r5], -r8
+b8877391|	1	gnu	ldrhls r8, [r3, #-120]!
+b9703e41|	1	gnu	ldrhmi r7, [lr, -r9]!
+b9cf8c16|	1	gnu	selne ip, ip, r9
+bd81bd58|	1	gnu	poppl {r0, r2, r3, r4, r5, r7, r8, pc}
+bdfdb469|	1	gnu	ldmibvs r4!, {r0, r2, r3, r4, r5, r7, r8, sl, fp, ip, sp, lr, pc}
+beb02500|	1	gnu	strhteq fp, [r5], -lr
+bf1a5e42|	1	gnu	subsmi r1, lr, #782336
+c19a4d5e|	1	gnu	vmlspl.f32 s19, s27, s2
+c1aab15e|	1	gnu	vsqrtpl.f32 s20, s2
+c354b003|	1	gnu	movseq r5, #-1023410176
+c4091dc1|	1	gnu	tstgt sp, r4, asr #19
+c50e13a9|	1	gnu	ldmdbge r3, {r0, r2, r6, r7, r9, sl, fp}
+c68c8637|	1	gnu	strcc r8, [r6, r6, asr #25]
+c6ad48e3|	1	gnu	movt sl, #36294
+c6f65ff5|	1	gnu	pld [pc, #-1734]
+c8a92f10|	1	gnu	eorne sl, pc, r8, asr #19
+c9016b61|	1	gnu	smulbtvs fp, r9, r1
+cadbf49e|	1	gnu	vcmpels.f64 d29, d10
+ce9de476|	1	gnu	strbtvc r9, [r4], lr, asr #27
+cf3c1ab1|	1	gnu	tstlt sl, pc, asr #25
+d355aab6|	1	gnu	ssatlt r5, #11, r3, asr #11
+d4f4df10|	1	gnu	ldrsbne pc, [pc], #68
+d6530d61|	1	gnu	ldrdvs r5, [sp, -r6]
+d74d7800|	1	gnu	ldrsbteq r4, [r8], #-215
+d9703680|	1	gnu	ldrsbthi r7, [r6], -r9
+dbe003c0|	1	gnu	ldrdgt lr, [r3], -fp
+dc709561|	1	gnu	ldrsbvs r7, [r5, ip]
+dcc3b9c8|	1	gnu	ldmgt r9!, {r2, r3, r4, r6, r7, r8, r9, lr, pc}
+debfa0e5|	1	gnu	str fp, [r0, #4062]!
+dee062a1|	1	gnu	ldrdge lr, [r2, #-14]!
+dfa05ab7|	1	gnu	smmlslt sl, pc, r0, sl
+e02ef011|	1	gnu	mvnsne r2, r0, ror #29
+e4d41718|	1	gnu	ldmdane r7, {r2, r5, r6, r7, sl, ip, lr, pc}
+e6d0fe34|	1	gnu	ldrbtcc sp, [lr], #230
+e73bf7be|	1	gnu	vcvtlt.f32.f64 s7, d23
+e74e72b3|	1	gnu	cmnlt r2, #3696
+e80bf07e|	1	gnu	vabsvc.f64 d16, d24
+e9b5b001|	1	gnu	rorseq fp, r9, #11
+ea7bbdbe|	1	gnu	vcvtlt.s32.f64 s14, d26
+ec063813|	1	gnu	teqne r8, #236, 12
+ec0e49e1|	1	gnu	smlaltt r0, r9, ip, lr
+ee4ab85e|	1	gnu	vcvtpl.f32.s32 s8, s29
+ef461f25|	1	gnu	ldrcs r4, [pc, #-1775]
+ef5fd002|	1	gnu	sbcseq r5, r0, #956
+f4cf1d36|	1	gnu	ssub8cc ip, sp, r4
+f67f73b6|	1	gnu	uhsub8lt r7, r3, r6
+f6e09ca0|	1	gnu	ldrshge lr, [ip], r6
+f7702e32|	1	gnu	eorcc r7, lr, #247
+fa4dcf20|	1	gnu	strdcs r4, [pc], #218
+fac03720|	1	gnu	ldrshtcs ip, [r7], -sl
+fc0f64c6|	1	gnu	uqsub8gt r0, r4, ip
+fc28f481|	1	gnu	ldrshhi r2, [r4, #140]!
+fc300560|	1	gnu	strdvs r3, [r5], -ip
+fcacfc70|	1	gnu	ldrshtvc sl, [ip], #204
+fdbcfaf7|	1	gnu	undef
+fddf5c86|	1	gnu	usub8hi sp, ip, sp
+fdf02013|	1	gnu	dbgne #13
+fe0319e3|	1	gnu	tst r9, #-134217725
+fe7f3116|	1	gnu	shsub8ne r7, r1, lr
+ff4f2ac6|	1	gnu	qsub8gt r4, sl, pc
+ff818c71|	1	gnu	strdvc r8, [ip, pc]
+|6b5721d3	1	gnu	error: unknown instruction
+|76452001	1	gnu	error: unknown instruction
+|97acd647	1	gnu	error: unknown instruction
diff --git a/src/cmd/internal/rsc.io/x86/x86asm/Makefile b/src/cmd/internal/rsc.io/x86/x86asm/Makefile
new file mode 100644
index 0000000..9eb4557
--- /dev/null
+++ b/src/cmd/internal/rsc.io/x86/x86asm/Makefile
@@ -0,0 +1,3 @@
+tables.go: ../x86map/map.go ../x86.csv 
+	go run ../x86map/map.go -fmt=decoder ../x86.csv >_tables.go && gofmt _tables.go >tables.go && rm _tables.go
+
diff --git a/src/cmd/internal/rsc.io/x86/x86asm/decode.go b/src/cmd/internal/rsc.io/x86/x86asm/decode.go
new file mode 100644
index 0000000..91e8876
--- /dev/null
+++ b/src/cmd/internal/rsc.io/x86/x86asm/decode.go
@@ -0,0 +1,1616 @@
+// 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.
+
+// Table-driven decoding of x86 instructions.
+
+package x86asm
+
+import (
+	"encoding/binary"
+	"errors"
+	"fmt"
+	"runtime"
+)
+
+// Set trace to true to cause the decoder to print the PC sequence
+// of the executed instruction codes. This is typically only useful
+// when you are running a test of a single input case.
+const trace = false
+
+// A decodeOp is a single instruction in the decoder bytecode program.
+//
+// The decodeOps correspond to consuming and conditionally branching
+// on input bytes, consuming additional fields, and then interpreting
+// consumed data as instruction arguments. The names of the xRead and xArg
+// operations are taken from the Intel manual conventions, for example
+// Volume 2, Section 3.1.1, page 487 of
+// http://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-manual-325462.pdf
+//
+// The actual decoding program is generated by ../x86map.
+//
+// TODO(rsc): We may be able to merge various of the memory operands
+// since we don't care about, say, the distinction between m80dec and m80bcd.
+// Similarly, mm and mm1 have identical meaning, as do xmm and xmm1.
+
+type decodeOp uint16
+
+const (
+	xFail  decodeOp = iota // invalid instruction (return)
+	xMatch                 // completed match
+	xJump                  // jump to pc
+
+	xCondByte     // switch on instruction byte value
+	xCondSlashR   // read and switch on instruction /r value
+	xCondPrefix   // switch on presence of instruction prefix
+	xCondIs64     // switch on 64-bit processor mode
+	xCondDataSize // switch on operand size
+	xCondAddrSize // switch on address size
+	xCondIsMem    // switch on memory vs register argument
+
+	xSetOp // set instruction opcode
+
+	xReadSlashR // read /r
+	xReadIb     // read ib
+	xReadIw     // read iw
+	xReadId     // read id
+	xReadIo     // read io
+	xReadCb     // read cb
+	xReadCw     // read cw
+	xReadCd     // read cd
+	xReadCp     // read cp
+	xReadCm     // read cm
+
+	xArg1            // arg 1
+	xArg3            // arg 3
+	xArgAL           // arg AL
+	xArgAX           // arg AX
+	xArgCL           // arg CL
+	xArgCR0dashCR7   // arg CR0-CR7
+	xArgCS           // arg CS
+	xArgDR0dashDR7   // arg DR0-DR7
+	xArgDS           // arg DS
+	xArgDX           // arg DX
+	xArgEAX          // arg EAX
+	xArgEDX          // arg EDX
+	xArgES           // arg ES
+	xArgFS           // arg FS
+	xArgGS           // arg GS
+	xArgImm16        // arg imm16
+	xArgImm32        // arg imm32
+	xArgImm64        // arg imm64
+	xArgImm8         // arg imm8
+	xArgImm8u        // arg imm8 but record as unsigned
+	xArgImm16u       // arg imm8 but record as unsigned
+	xArgM            // arg m
+	xArgM128         // arg m128
+	xArgM1428byte    // arg m14/28byte
+	xArgM16          // arg m16
+	xArgM16and16     // arg m16&16
+	xArgM16and32     // arg m16&32
+	xArgM16and64     // arg m16&64
+	xArgM16colon16   // arg m16:16
+	xArgM16colon32   // arg m16:32
+	xArgM16colon64   // arg m16:64
+	xArgM16int       // arg m16int
+	xArgM2byte       // arg m2byte
+	xArgM32          // arg m32
+	xArgM32and32     // arg m32&32
+	xArgM32fp        // arg m32fp
+	xArgM32int       // arg m32int
+	xArgM512byte     // arg m512byte
+	xArgM64          // arg m64
+	xArgM64fp        // arg m64fp
+	xArgM64int       // arg m64int
+	xArgM8           // arg m8
+	xArgM80bcd       // arg m80bcd
+	xArgM80dec       // arg m80dec
+	xArgM80fp        // arg m80fp
+	xArgM94108byte   // arg m94/108byte
+	xArgMm           // arg mm
+	xArgMm1          // arg mm1
+	xArgMm2          // arg mm2
+	xArgMm2M64       // arg mm2/m64
+	xArgMmM32        // arg mm/m32
+	xArgMmM64        // arg mm/m64
+	xArgMem          // arg mem
+	xArgMoffs16      // arg moffs16
+	xArgMoffs32      // arg moffs32
+	xArgMoffs64      // arg moffs64
+	xArgMoffs8       // arg moffs8
+	xArgPtr16colon16 // arg ptr16:16
+	xArgPtr16colon32 // arg ptr16:32
+	xArgR16          // arg r16
+	xArgR16op        // arg r16 with +rw in opcode
+	xArgR32          // arg r32
+	xArgR32M16       // arg r32/m16
+	xArgR32M8        // arg r32/m8
+	xArgR32op        // arg r32 with +rd in opcode
+	xArgR64          // arg r64
+	xArgR64M16       // arg r64/m16
+	xArgR64op        // arg r64 with +rd in opcode
+	xArgR8           // arg r8
+	xArgR8op         // arg r8 with +rb in opcode
+	xArgRAX          // arg RAX
+	xArgRDX          // arg RDX
+	xArgRM           // arg r/m
+	xArgRM16         // arg r/m16
+	xArgRM32         // arg r/m32
+	xArgRM64         // arg r/m64
+	xArgRM8          // arg r/m8
+	xArgReg          // arg reg
+	xArgRegM16       // arg reg/m16
+	xArgRegM32       // arg reg/m32
+	xArgRegM8        // arg reg/m8
+	xArgRel16        // arg rel16
+	xArgRel32        // arg rel32
+	xArgRel8         // arg rel8
+	xArgSS           // arg SS
+	xArgST           // arg ST, aka ST(0)
+	xArgSTi          // arg ST(i) with +i in opcode
+	xArgSreg         // arg Sreg
+	xArgTR0dashTR7   // arg TR0-TR7
+	xArgXmm          // arg xmm
+	xArgXMM0         // arg <XMM0>
+	xArgXmm1         // arg xmm1
+	xArgXmm2         // arg xmm2
+	xArgXmm2M128     // arg xmm2/m128
+	xArgXmm2M16      // arg xmm2/m16
+	xArgXmm2M32      // arg xmm2/m32
+	xArgXmm2M64      // arg xmm2/m64
+	xArgXmmM128      // arg xmm/m128
+	xArgXmmM32       // arg xmm/m32
+	xArgXmmM64       // arg xmm/m64
+	xArgRmf16        // arg r/m16 but force mod=3
+	xArgRmf32        // arg r/m32 but force mod=3
+	xArgRmf64        // arg r/m64 but force mod=3
+)
+
+// instPrefix returns an Inst describing just one prefix byte.
+// It is only used if there is a prefix followed by an unintelligible
+// or invalid instruction byte sequence.
+func instPrefix(b byte, mode int) (Inst, error) {
+	// When tracing it is useful to see what called instPrefix to report an error.
+	if trace {
+		_, file, line, _ := runtime.Caller(1)
+		fmt.Printf("%s:%d\n", file, line)
+	}
+	p := Prefix(b)
+	switch p {
+	case PrefixDataSize:
+		if mode == 16 {
+			p = PrefixData32
+		} else {
+			p = PrefixData16
+		}
+	case PrefixAddrSize:
+		if mode == 32 {
+			p = PrefixAddr16
+		} else {
+			p = PrefixAddr32
+		}
+	}
+	// Note: using composite literal with Prefix key confuses 'bundle' tool.
+	inst := Inst{Len: 1}
+	inst.Prefix = Prefixes{p}
+	return inst, nil
+}
+
+// truncated reports a truncated instruction.
+// For now we use instPrefix but perhaps later we will return
+// a specific error here.
+func truncated(src []byte, mode int) (Inst, error) {
+	//	return Inst{}, len(src), ErrTruncated
+	return instPrefix(src[0], mode) // too long
+}
+
+// These are the errors returned by Decode.
+var (
+	ErrInvalidMode  = errors.New("invalid x86 mode in Decode")
+	ErrTruncated    = errors.New("truncated instruction")
+	ErrUnrecognized = errors.New("unrecognized instruction")
+)
+
+// decoderCover records coverage information for which parts
+// of the byte code have been executed.
+// TODO(rsc): This is for testing. Only use this if a flag is given.
+var decoderCover []bool
+
+// Decode decodes the leading bytes in src as a single instruction.
+// The mode arguments specifies the assumed processor mode:
+// 16, 32, or 64 for 16-, 32-, and 64-bit execution modes.
+func Decode(src []byte, mode int) (inst Inst, err error) {
+	return decode1(src, mode, false)
+}
+
+// decode1 is the implementation of Decode but takes an extra
+// gnuCompat flag to cause it to change its behavior to mimic
+// bugs (or at least unique features) of GNU libopcodes as used
+// by objdump. We don't believe that logic is the right thing to do
+// in general, but when testing against libopcodes it simplifies the
+// comparison if we adjust a few small pieces of logic.
+// The affected logic is in the conditional branch for "mandatory" prefixes,
+// case xCondPrefix.
+func decode1(src []byte, mode int, gnuCompat bool) (Inst, error) {
+	switch mode {
+	case 16, 32, 64:
+		// ok
+		// TODO(rsc): 64-bit mode not tested, probably not working.
+	default:
+		return Inst{}, ErrInvalidMode
+	}
+
+	// Maximum instruction size is 15 bytes.
+	// If we need to read more, return 'truncated instruction.
+	if len(src) > 15 {
+		src = src[:15]
+	}
+
+	var (
+		// prefix decoding information
+		pos           = 0    // position reading src
+		nprefix       = 0    // number of prefixes
+		lockIndex     = -1   // index of LOCK prefix in src and inst.Prefix
+		repIndex      = -1   // index of REP/REPN prefix in src and inst.Prefix
+		segIndex      = -1   // index of Group 2 prefix in src and inst.Prefix
+		dataSizeIndex = -1   // index of Group 3 prefix in src and inst.Prefix
+		addrSizeIndex = -1   // index of Group 4 prefix in src and inst.Prefix
+		rex           Prefix // rex byte if present (or 0)
+		rexUsed       Prefix // bits used in rex byte
+		rexIndex      = -1   // index of rex byte
+
+		addrMode = mode // address mode (width in bits)
+		dataMode = mode // operand mode (width in bits)
+
+		// decoded ModR/M fields
+		haveModrm bool
+		modrm     int
+		mod       int
+		regop     int
+		rm        int
+
+		// if ModR/M is memory reference, Mem form
+		mem     Mem
+		haveMem bool
+
+		// decoded SIB fields
+		haveSIB bool
+		sib     int
+		scale   int
+		index   int
+		base    int
+
+		// decoded immediate values
+		imm  int64
+		imm8 int8
+		immc int64
+
+		// output
+		opshift int
+		inst    Inst
+		narg    int // number of arguments written to inst
+	)
+
+	if mode == 64 {
+		dataMode = 32
+	}
+
+	// Prefixes are certainly the most complex and underspecified part of
+	// decoding x86 instructions. Although the manuals say things like
+	// up to four prefixes, one from each group, nearly everyone seems to
+	// agree that in practice as many prefixes as possible, including multiple
+	// from a particular group or repetitions of a given prefix, can be used on
+	// an instruction, provided the total instruction length including prefixes
+	// does not exceed the agreed-upon maximum of 15 bytes.
+	// Everyone also agrees that if one of these prefixes is the LOCK prefix
+	// and the instruction is not one of the instructions that can be used with
+	// the LOCK prefix or if the destination is not a memory operand,
+	// then the instruction is invalid and produces the #UD exception.
+	// However, that is the end of any semblance of agreement.
+	//
+	// What happens if prefixes are given that conflict with other prefixes?
+	// For example, the memory segment overrides CS, DS, ES, FS, GS, SS
+	// conflict with each other: only one segment can be in effect.
+	// Disassemblers seem to agree that later prefixes take priority over
+	// earlier ones. I have not taken the time to write assembly programs
+	// to check to see if the hardware agrees.
+	//
+	// What happens if prefixes are given that have no meaning for the
+	// specific instruction to which they are attached? It depends.
+	// If they really have no meaning, they are ignored. However, a future
+	// processor may assign a different meaning. As a disassembler, we
+	// don't really know whether we're seeing a meaningless prefix or one
+	// whose meaning we simply haven't been told yet.
+	//
+	// Combining the two questions, what happens when conflicting
+	// extension prefixes are given? No one seems to know for sure.
+	// For example, MOVQ is 66 0F D6 /r, MOVDQ2Q is F2 0F D6 /r,
+	// and MOVQ2DQ is F3 0F D6 /r. What is '66 F2 F3 0F D6 /r'?
+	// Which prefix wins? See the xCondPrefix prefix for more.
+	//
+	// Writing assembly test cases to divine which interpretation the
+	// CPU uses might clarify the situation, but more likely it would
+	// make the situation even less clear.
+
+	// Read non-REX prefixes.
+ReadPrefixes:
+	for ; pos < len(src); pos++ {
+		p := Prefix(src[pos])
+		switch p {
+		default:
+			nprefix = pos
+			break ReadPrefixes
+
+		// Group 1 - lock and repeat prefixes
+		// According to Intel, there should only be one from this set,
+		// but according to AMD both can be present.
+		case 0xF0:
+			if lockIndex >= 0 {
+				inst.Prefix[lockIndex] |= PrefixIgnored
+			}
+			lockIndex = pos
+		case 0xF2, 0xF3:
+			if repIndex >= 0 {
+				inst.Prefix[repIndex] |= PrefixIgnored
+			}
+			repIndex = pos
+
+		// Group 2 - segment override / branch hints
+		case 0x26, 0x2E, 0x36, 0x3E:
+			if mode == 64 {
+				p |= PrefixIgnored
+				break
+			}
+			fallthrough
+		case 0x64, 0x65:
+			if segIndex >= 0 {
+				inst.Prefix[segIndex] |= PrefixIgnored
+			}
+			segIndex = pos
+
+		// Group 3 - operand size override
+		case 0x66:
+			if mode == 16 {
+				dataMode = 32
+				p = PrefixData32
+			} else {
+				dataMode = 16
+				p = PrefixData16
+			}
+			if dataSizeIndex >= 0 {
+				inst.Prefix[dataSizeIndex] |= PrefixIgnored
+			}
+			dataSizeIndex = pos
+
+		// Group 4 - address size override
+		case 0x67:
+			if mode == 32 {
+				addrMode = 16
+				p = PrefixAddr16
+			} else {
+				addrMode = 32
+				p = PrefixAddr32
+			}
+			if addrSizeIndex >= 0 {
+				inst.Prefix[addrSizeIndex] |= PrefixIgnored
+			}
+			addrSizeIndex = pos
+		}
+
+		if pos >= len(inst.Prefix) {
+			return instPrefix(src[0], mode) // too long
+		}
+
+		inst.Prefix[pos] = p
+	}
+
+	// Read REX prefix.
+	if pos < len(src) && mode == 64 && Prefix(src[pos]).IsREX() {
+		rex = Prefix(src[pos])
+		rexIndex = pos
+		if pos >= len(inst.Prefix) {
+			return instPrefix(src[0], mode) // too long
+		}
+		inst.Prefix[pos] = rex
+		pos++
+		if rex&PrefixREXW != 0 {
+			dataMode = 64
+			if dataSizeIndex >= 0 {
+				inst.Prefix[dataSizeIndex] |= PrefixIgnored
+			}
+		}
+	}
+
+	// Decode instruction stream, interpreting decoding instructions.
+	// opshift gives the shift to use when saving the next
+	// opcode byte into inst.Opcode.
+	opshift = 24
+	if decoderCover == nil {
+		decoderCover = make([]bool, len(decoder))
+	}
+
+	// Decode loop, executing decoder program.
+	var oldPC, prevPC int
+Decode:
+	for pc := 1; ; { // TODO uint
+		oldPC = prevPC
+		prevPC = pc
+		if trace {
+			println("run", pc)
+		}
+		x := decoder[pc]
+		decoderCover[pc] = true
+		pc++
+
+		// Read and decode ModR/M if needed by opcode.
+		switch decodeOp(x) {
+		case xCondSlashR, xReadSlashR:
+			if haveModrm {
+				return Inst{Len: pos}, errInternal
+			}
+			haveModrm = true
+			if pos >= len(src) {
+				return truncated(src, mode)
+			}
+			modrm = int(src[pos])
+			pos++
+			if opshift >= 0 {
+				inst.Opcode |= uint32(modrm) << uint(opshift)
+				opshift -= 8
+			}
+			mod = modrm >> 6
+			regop = (modrm >> 3) & 07
+			rm = modrm & 07
+			if rex&PrefixREXR != 0 {
+				rexUsed |= PrefixREXR
+				regop |= 8
+			}
+			if addrMode == 16 {
+				// 16-bit modrm form
+				if mod != 3 {
+					haveMem = true
+					mem = addr16[rm]
+					if rm == 6 && mod == 0 {
+						mem.Base = 0
+					}
+
+					// Consume disp16 if present.
+					if mod == 0 && rm == 6 || mod == 2 {
+						if pos+2 > len(src) {
+							return truncated(src, mode)
+						}
+						mem.Disp = int64(binary.LittleEndian.Uint16(src[pos:]))
+						pos += 2
+					}
+
+					// Consume disp8 if present.
+					if mod == 1 {
+						if pos >= len(src) {
+							return truncated(src, mode)
+						}
+						mem.Disp = int64(int8(src[pos]))
+						pos++
+					}
+				}
+			} else {
+				haveMem = mod != 3
+
+				// 32-bit or 64-bit form
+				// Consume SIB encoding if present.
+				if rm == 4 && mod != 3 {
+					haveSIB = true
+					if pos >= len(src) {
+						return truncated(src, mode)
+					}
+					sib = int(src[pos])
+					pos++
+					if opshift >= 0 {
+						inst.Opcode |= uint32(sib) << uint(opshift)
+						opshift -= 8
+					}
+					scale = sib >> 6
+					index = (sib >> 3) & 07
+					base = sib & 07
+					if rex&PrefixREXB != 0 {
+						rexUsed |= PrefixREXB
+						base |= 8
+					}
+					if rex&PrefixREXX != 0 {
+						rexUsed |= PrefixREXX
+						index |= 8
+					}
+
+					mem.Scale = 1 << uint(scale)
+					if index == 4 {
+						// no mem.Index
+					} else {
+						mem.Index = baseRegForBits(addrMode) + Reg(index)
+					}
+					if base&7 == 5 && mod == 0 {
+						// no mem.Base
+					} else {
+						mem.Base = baseRegForBits(addrMode) + Reg(base)
+					}
+				} else {
+					if rex&PrefixREXB != 0 {
+						rexUsed |= PrefixREXB
+						rm |= 8
+					}
+					if mod == 0 && rm&7 == 5 || rm&7 == 4 {
+						// base omitted
+					} else if mod != 3 {
+						mem.Base = baseRegForBits(addrMode) + Reg(rm)
+					}
+				}
+
+				// Consume disp32 if present.
+				if mod == 0 && (rm&7 == 5 || haveSIB && base&7 == 5) || mod == 2 {
+					if pos+4 > len(src) {
+						return truncated(src, mode)
+					}
+					mem.Disp = int64(binary.LittleEndian.Uint32(src[pos:]))
+					pos += 4
+				}
+
+				// Consume disp8 if present.
+				if mod == 1 {
+					if pos >= len(src) {
+						return truncated(src, mode)
+					}
+					mem.Disp = int64(int8(src[pos]))
+					pos++
+				}
+
+				// In 64-bit, mod=0 rm=5 is PC-relative instead of just disp.
+				// See Vol 2A. Table 2-7.
+				if mode == 64 && mod == 0 && rm&7 == 5 {
+					if addrMode == 32 {
+						mem.Base = EIP
+					} else {
+						mem.Base = RIP
+					}
+				}
+			}
+
+			if segIndex >= 0 {
+				mem.Segment = prefixToSegment(inst.Prefix[segIndex])
+			}
+		}
+
+		// Execute single opcode.
+		switch decodeOp(x) {
+		default:
+			println("bad op", x, "at", pc-1, "from", oldPC)
+			return Inst{Len: pos}, errInternal
+
+		case xFail:
+			inst.Op = 0
+			break Decode
+
+		case xMatch:
+			break Decode
+
+		case xJump:
+			pc = int(decoder[pc])
+
+		// Conditional branches.
+
+		case xCondByte:
+			if pos >= len(src) {
+				return truncated(src, mode)
+			}
+			b := src[pos]
+			n := int(decoder[pc])
+			pc++
+			for i := 0; i < n; i++ {
+				xb, xpc := decoder[pc], int(decoder[pc+1])
+				pc += 2
+				if b == byte(xb) {
+					pc = xpc
+					pos++
+					if opshift >= 0 {
+						inst.Opcode |= uint32(b) << uint(opshift)
+						opshift -= 8
+					}
+					continue Decode
+				}
+			}
+			// xCondByte is the only conditional with a fall through,
+			// so that it can be used to pick off special cases before
+			// an xCondSlash. If the fallthrough instruction is xFail,
+			// advance the position so that the decoded instruction
+			// size includes the byte we just compared against.
+			if decodeOp(decoder[pc]) == xJump {
+				pc = int(decoder[pc+1])
+			}
+			if decodeOp(decoder[pc]) == xFail {
+				pos++
+			}
+
+		case xCondIs64:
+			if mode == 64 {
+				pc = int(decoder[pc+1])
+			} else {
+				pc = int(decoder[pc])
+			}
+
+		case xCondIsMem:
+			mem := haveMem
+			if !haveModrm {
+				if pos >= len(src) {
+					return instPrefix(src[0], mode) // too long
+				}
+				mem = src[pos]>>6 != 3
+			}
+			if mem {
+				pc = int(decoder[pc+1])
+			} else {
+				pc = int(decoder[pc])
+			}
+
+		case xCondDataSize:
+			switch dataMode {
+			case 16:
+				if dataSizeIndex >= 0 {
+					inst.Prefix[dataSizeIndex] |= PrefixImplicit
+				}
+				pc = int(decoder[pc])
+			case 32:
+				if dataSizeIndex >= 0 {
+					inst.Prefix[dataSizeIndex] |= PrefixImplicit
+				}
+				pc = int(decoder[pc+1])
+			case 64:
+				rexUsed |= PrefixREXW
+				pc = int(decoder[pc+2])
+			}
+
+		case xCondAddrSize:
+			switch addrMode {
+			case 16:
+				if addrSizeIndex >= 0 {
+					inst.Prefix[addrSizeIndex] |= PrefixImplicit
+				}
+				pc = int(decoder[pc])
+			case 32:
+				if addrSizeIndex >= 0 {
+					inst.Prefix[addrSizeIndex] |= PrefixImplicit
+				}
+				pc = int(decoder[pc+1])
+			case 64:
+				pc = int(decoder[pc+2])
+			}
+
+		case xCondPrefix:
+			// Conditional branch based on presence or absence of prefixes.
+			// The conflict cases here are completely undocumented and
+			// differ significantly between GNU libopcodes and Intel xed.
+			// I have not written assembly code to divine what various CPUs
+			// do, but it wouldn't surprise me if they are not consistent either.
+			//
+			// The basic idea is to switch on the presence of a prefix, so that
+			// for example:
+			//
+			//	xCondPrefix, 4
+			//	0xF3, 123,
+			//	0xF2, 234,
+			//	0x66, 345,
+			//	0, 456
+			//
+			// branch to 123 if the F3 prefix is present, 234 if the F2 prefix
+			// is present, 66 if the 345 prefix is present, and 456 otherwise.
+			// The prefixes are given in descending order so that the 0 will be last.
+			//
+			// It is unclear what should happen if multiple conditions are
+			// satisfied: what if F2 and F3 are both present, or if 66 and F2
+			// are present, or if all three are present? The one chosen becomes
+			// part of the opcode and the others do not. Perhaps the answer
+			// depends on the specific opcodes in question.
+			//
+			// The only clear example is that CRC32 is F2 0F 38 F1 /r, and
+			// it comes in 16-bit and 32-bit forms based on the 66 prefix,
+			// so 66 F2 0F 38 F1 /r should be treated as F2 taking priority,
+			// with the 66 being only an operand size override, and probably
+			// F2 66 0F 38 F1 /r should be treated the same.
+			// Perhaps that rule is specific to the case of CRC32, since no
+			// 66 0F 38 F1 instruction is defined (today) (that we know of).
+			// However, both libopcodes and xed seem to generalize this
+			// example and choose F2/F3 in preference to 66, and we
+			// do the same.
+			//
+			// Next, what if both F2 and F3 are present? Which wins?
+			// The Intel xed rule, and ours, is that the one that occurs last wins.
+			// The GNU libopcodes rule, which we implement only in gnuCompat mode,
+			// is that F3 beats F2 unless F3 has no special meaning, in which
+			// case F3 can be a modified on an F2 special meaning.
+			//
+			// Concretely,
+			//	66 0F D6 /r is MOVQ
+			//	F2 0F D6 /r is MOVDQ2Q
+			//	F3 0F D6 /r is MOVQ2DQ.
+			//
+			//	F2 66 0F D6 /r is 66 + MOVDQ2Q always.
+			//	66 F2 0F D6 /r is 66 + MOVDQ2Q always.
+			//	F3 66 0F D6 /r is 66 + MOVQ2DQ always.
+			//	66 F3 0F D6 /r is 66 + MOVQ2DQ always.
+			//	F2 F3 0F D6 /r is F2 + MOVQ2DQ always.
+			//	F3 F2 0F D6 /r is F3 + MOVQ2DQ in Intel xed, but F2 + MOVQ2DQ in GNU libopcodes.
+			//	Adding 66 anywhere in the prefix section of the
+			//	last two cases does not change the outcome.
+			//
+			// Finally, what if there is a variant in which 66 is a mandatory
+			// prefix rather than an operand size override, but we know of
+			// no corresponding F2/F3 form, and we see both F2/F3 and 66.
+			// Does F2/F3 still take priority, so that the result is an unknown
+			// instruction, or does the 66 take priority, so that the extended
+			// 66 instruction should be interpreted as having a REP/REPN prefix?
+			// Intel xed does the former and GNU libopcodes does the latter.
+			// We side with Intel xed, unless we are trying to match libopcodes
+			// more closely during the comparison-based test suite.
+			//
+			// In 64-bit mode REX.W is another valid prefix to test for, but
+			// there is less ambiguity about that. When present, REX.W is
+			// always the first entry in the table.
+			n := int(decoder[pc])
+			pc++
+			sawF3 := false
+			for j := 0; j < n; j++ {
+				prefix := Prefix(decoder[pc+2*j])
+				if prefix.IsREX() {
+					rexUsed |= prefix
+					if rex&prefix == prefix {
+						pc = int(decoder[pc+2*j+1])
+						continue Decode
+					}
+					continue
+				}
+				ok := false
+				if prefix == 0 {
+					ok = true
+				} else if prefix.IsREX() {
+					rexUsed |= prefix
+					if rex&prefix == prefix {
+						ok = true
+					}
+				} else {
+					if prefix == 0xF3 {
+						sawF3 = true
+					}
+					switch prefix {
+					case PrefixLOCK:
+						if lockIndex >= 0 {
+							inst.Prefix[lockIndex] |= PrefixImplicit
+							ok = true
+						}
+					case PrefixREP, PrefixREPN:
+						if repIndex >= 0 && inst.Prefix[repIndex]&0xFF == prefix {
+							inst.Prefix[repIndex] |= PrefixImplicit
+							ok = true
+						}
+						if gnuCompat && !ok && prefix == 0xF3 && repIndex >= 0 && (j+1 >= n || decoder[pc+2*(j+1)] != 0xF2) {
+							// Check to see if earlier prefix F3 is present.
+							for i := repIndex - 1; i >= 0; i-- {
+								if inst.Prefix[i]&0xFF == prefix {
+									inst.Prefix[i] |= PrefixImplicit
+									ok = true
+								}
+							}
+						}
+						if gnuCompat && !ok && prefix == 0xF2 && repIndex >= 0 && !sawF3 && inst.Prefix[repIndex]&0xFF == 0xF3 {
+							// Check to see if earlier prefix F2 is present.
+							for i := repIndex - 1; i >= 0; i-- {
+								if inst.Prefix[i]&0xFF == prefix {
+									inst.Prefix[i] |= PrefixImplicit
+									ok = true
+								}
+							}
+						}
+					case PrefixCS, PrefixDS, PrefixES, PrefixFS, PrefixGS, PrefixSS:
+						if segIndex >= 0 && inst.Prefix[segIndex]&0xFF == prefix {
+							inst.Prefix[segIndex] |= PrefixImplicit
+							ok = true
+						}
+					case PrefixDataSize:
+						// Looking for 66 mandatory prefix.
+						// The F2/F3 mandatory prefixes take priority when both are present.
+						// If we got this far in the xCondPrefix table and an F2/F3 is present,
+						// it means the table didn't have any entry for that prefix. But if 66 has
+						// special meaning, perhaps F2/F3 have special meaning that we don't know.
+						// Intel xed works this way, treating the F2/F3 as inhibiting the 66.
+						// GNU libopcodes allows the 66 to match. We do what Intel xed does
+						// except in gnuCompat mode.
+						if repIndex >= 0 && !gnuCompat {
+							inst.Op = 0
+							break Decode
+						}
+						if dataSizeIndex >= 0 {
+							inst.Prefix[dataSizeIndex] |= PrefixImplicit
+							ok = true
+						}
+					case PrefixAddrSize:
+						if addrSizeIndex >= 0 {
+							inst.Prefix[addrSizeIndex] |= PrefixImplicit
+							ok = true
+						}
+					}
+				}
+				if ok {
+					pc = int(decoder[pc+2*j+1])
+					continue Decode
+				}
+			}
+			inst.Op = 0
+			break Decode
+
+		case xCondSlashR:
+			pc = int(decoder[pc+regop&7])
+
+		// Input.
+
+		case xReadSlashR:
+			// done above
+
+		case xReadIb:
+			if pos >= len(src) {
+				return truncated(src, mode)
+			}
+			imm8 = int8(src[pos])
+			pos++
+
+		case xReadIw:
+			if pos+2 > len(src) {
+				return truncated(src, mode)
+			}
+			imm = int64(binary.LittleEndian.Uint16(src[pos:]))
+			pos += 2
+
+		case xReadId:
+			if pos+4 > len(src) {
+				return truncated(src, mode)
+			}
+			imm = int64(binary.LittleEndian.Uint32(src[pos:]))
+			pos += 4
+
+		case xReadIo:
+			if pos+8 > len(src) {
+				return truncated(src, mode)
+			}
+			imm = int64(binary.LittleEndian.Uint64(src[pos:]))
+			pos += 8
+
+		case xReadCb:
+			if pos >= len(src) {
+				return truncated(src, mode)
+			}
+			immc = int64(src[pos])
+			pos++
+
+		case xReadCw:
+			if pos+2 > len(src) {
+				return truncated(src, mode)
+			}
+			immc = int64(binary.LittleEndian.Uint16(src[pos:]))
+			pos += 2
+
+		case xReadCm:
+			if addrMode == 16 {
+				if pos+2 > len(src) {
+					return truncated(src, mode)
+				}
+				immc = int64(binary.LittleEndian.Uint16(src[pos:]))
+				pos += 2
+			} else if addrMode == 32 {
+				if pos+4 > len(src) {
+					return truncated(src, mode)
+				}
+				immc = int64(binary.LittleEndian.Uint32(src[pos:]))
+				pos += 4
+			} else {
+				if pos+8 > len(src) {
+					return truncated(src, mode)
+				}
+				immc = int64(binary.LittleEndian.Uint64(src[pos:]))
+				pos += 8
+			}
+		case xReadCd:
+			if pos+4 > len(src) {
+				return truncated(src, mode)
+			}
+			immc = int64(binary.LittleEndian.Uint32(src[pos:]))
+			pos += 4
+
+		case xReadCp:
+			if pos+6 > len(src) {
+				return truncated(src, mode)
+			}
+			w := binary.LittleEndian.Uint32(src[pos:])
+			w2 := binary.LittleEndian.Uint16(src[pos+4:])
+			immc = int64(w2)<<32 | int64(w)
+			pos += 6
+
+		// Output.
+
+		case xSetOp:
+			inst.Op = Op(decoder[pc])
+			pc++
+
+		case xArg1,
+			xArg3,
+			xArgAL,
+			xArgAX,
+			xArgCL,
+			xArgCS,
+			xArgDS,
+			xArgDX,
+			xArgEAX,
+			xArgEDX,
+			xArgES,
+			xArgFS,
+			xArgGS,
+			xArgRAX,
+			xArgRDX,
+			xArgSS,
+			xArgST,
+			xArgXMM0:
+			inst.Args[narg] = fixedArg[x]
+			narg++
+
+		case xArgImm8:
+			inst.Args[narg] = Imm(imm8)
+			narg++
+
+		case xArgImm8u:
+			inst.Args[narg] = Imm(uint8(imm8))
+			narg++
+
+		case xArgImm16:
+			inst.Args[narg] = Imm(int16(imm))
+			narg++
+
+		case xArgImm16u:
+			inst.Args[narg] = Imm(uint16(imm))
+			narg++
+
+		case xArgImm32:
+			inst.Args[narg] = Imm(int32(imm))
+			narg++
+
+		case xArgImm64:
+			inst.Args[narg] = Imm(imm)
+			narg++
+
+		case xArgM,
+			xArgM128,
+			xArgM1428byte,
+			xArgM16,
+			xArgM16and16,
+			xArgM16and32,
+			xArgM16and64,
+			xArgM16colon16,
+			xArgM16colon32,
+			xArgM16colon64,
+			xArgM16int,
+			xArgM2byte,
+			xArgM32,
+			xArgM32and32,
+			xArgM32fp,
+			xArgM32int,
+			xArgM512byte,
+			xArgM64,
+			xArgM64fp,
+			xArgM64int,
+			xArgM8,
+			xArgM80bcd,
+			xArgM80dec,
+			xArgM80fp,
+			xArgM94108byte,
+			xArgMem:
+			if !haveMem {
+				inst.Op = 0
+				break Decode
+			}
+			inst.Args[narg] = mem
+			inst.MemBytes = int(memBytes[decodeOp(x)])
+			narg++
+
+		case xArgPtr16colon16:
+			inst.Args[narg] = Imm(immc >> 16)
+			inst.Args[narg+1] = Imm(immc & (1<<16 - 1))
+			narg += 2
+
+		case xArgPtr16colon32:
+			inst.Args[narg] = Imm(immc >> 32)
+			inst.Args[narg+1] = Imm(immc & (1<<32 - 1))
+			narg += 2
+
+		case xArgMoffs8, xArgMoffs16, xArgMoffs32, xArgMoffs64:
+			// TODO(rsc): Can address be 64 bits?
+			mem = Mem{Disp: int64(immc)}
+			if segIndex >= 0 {
+				mem.Segment = prefixToSegment(inst.Prefix[segIndex])
+				inst.Prefix[segIndex] |= PrefixImplicit
+			}
+			inst.Args[narg] = mem
+			inst.MemBytes = int(memBytes[decodeOp(x)])
+			narg++
+
+		case xArgR8, xArgR16, xArgR32, xArgR64, xArgXmm, xArgXmm1, xArgDR0dashDR7:
+			base := baseReg[x]
+			index := Reg(regop)
+			if rex != 0 && base == AL && index >= 4 {
+				rexUsed |= PrefixREX
+				index -= 4
+				base = SPB
+			}
+			inst.Args[narg] = base + index
+			narg++
+
+		case xArgMm, xArgMm1, xArgTR0dashTR7:
+			inst.Args[narg] = baseReg[x] + Reg(regop&7)
+			narg++
+
+		case xArgCR0dashCR7:
+			// AMD documents an extension that the LOCK prefix
+			// can be used in place of a REX prefix in order to access
+			// CR8 from 32-bit mode. The LOCK prefix is allowed in
+			// all modes, provided the corresponding CPUID bit is set.
+			if lockIndex >= 0 {
+				inst.Prefix[lockIndex] |= PrefixImplicit
+				regop += 8
+			}
+			inst.Args[narg] = CR0 + Reg(regop)
+			narg++
+
+		case xArgSreg:
+			regop &= 7
+			if regop >= 6 {
+				inst.Op = 0
+				break Decode
+			}
+			inst.Args[narg] = ES + Reg(regop)
+			narg++
+
+		case xArgRmf16, xArgRmf32, xArgRmf64:
+			base := baseReg[x]
+			index := Reg(modrm & 07)
+			if rex&PrefixREXB != 0 {
+				rexUsed |= PrefixREXB
+				index += 8
+			}
+			inst.Args[narg] = base + index
+			narg++
+
+		case xArgR8op, xArgR16op, xArgR32op, xArgR64op, xArgSTi:
+			n := inst.Opcode >> uint(opshift+8) & 07
+			base := baseReg[x]
+			index := Reg(n)
+			if rex&PrefixREXB != 0 && decodeOp(x) != xArgSTi {
+				rexUsed |= PrefixREXB
+				index += 8
+			}
+			if rex != 0 && base == AL && index >= 4 {
+				rexUsed |= PrefixREX
+				index -= 4
+				base = SPB
+			}
+			inst.Args[narg] = base + index
+			narg++
+
+		case xArgRM8, xArgRM16, xArgRM32, xArgRM64, xArgR32M16, xArgR32M8, xArgR64M16,
+			xArgMmM32, xArgMmM64, xArgMm2M64,
+			xArgXmm2M16, xArgXmm2M32, xArgXmm2M64, xArgXmmM64, xArgXmmM128, xArgXmmM32, xArgXmm2M128:
+			if haveMem {
+				inst.Args[narg] = mem
+				inst.MemBytes = int(memBytes[decodeOp(x)])
+			} else {
+				base := baseReg[x]
+				index := Reg(rm)
+				switch decodeOp(x) {
+				case xArgMmM32, xArgMmM64, xArgMm2M64:
+					// There are only 8 MMX registers, so these ignore the REX.X bit.
+					index &= 7
+				case xArgRM8:
+					if rex != 0 && index >= 4 {
+						rexUsed |= PrefixREX
+						index -= 4
+						base = SPB
+					}
+				}
+				inst.Args[narg] = base + index
+			}
+			narg++
+
+		case xArgMm2: // register only; TODO(rsc): Handle with tag modrm_regonly tag
+			if haveMem {
+				inst.Op = 0
+				break Decode
+			}
+			inst.Args[narg] = baseReg[x] + Reg(rm&7)
+			narg++
+
+		case xArgXmm2: // register only; TODO(rsc): Handle with tag modrm_regonly tag
+			if haveMem {
+				inst.Op = 0
+				break Decode
+			}
+			inst.Args[narg] = baseReg[x] + Reg(rm)
+			narg++
+
+		case xArgRel8:
+			inst.Args[narg] = Rel(int8(immc))
+			narg++
+
+		case xArgRel16:
+			inst.Args[narg] = Rel(int16(immc))
+			narg++
+
+		case xArgRel32:
+			inst.Args[narg] = Rel(int32(immc))
+			narg++
+		}
+	}
+
+	if inst.Op == 0 {
+		// Invalid instruction.
+		if nprefix > 0 {
+			return instPrefix(src[0], mode) // invalid instruction
+		}
+		return Inst{Len: pos}, ErrUnrecognized
+	}
+
+	// Matched! Hooray!
+
+	// 90 decodes as XCHG EAX, EAX but is NOP.
+	// 66 90 decodes as XCHG AX, AX and is NOP too.
+	// 48 90 decodes as XCHG RAX, RAX and is NOP too.
+	// 43 90 decodes as XCHG R8D, EAX and is *not* NOP.
+	// F3 90 decodes as REP XCHG EAX, EAX but is PAUSE.
+	// It's all too special to handle in the decoding tables, at least for now.
+	if inst.Op == XCHG && inst.Opcode>>24 == 0x90 {
+		if inst.Args[0] == RAX || inst.Args[0] == EAX || inst.Args[0] == AX {
+			inst.Op = NOP
+			if dataSizeIndex >= 0 {
+				inst.Prefix[dataSizeIndex] &^= PrefixImplicit
+			}
+			inst.Args[0] = nil
+			inst.Args[1] = nil
+		}
+		if repIndex >= 0 && inst.Prefix[repIndex] == 0xF3 {
+			inst.Prefix[repIndex] |= PrefixImplicit
+			inst.Op = PAUSE
+			inst.Args[0] = nil
+			inst.Args[1] = nil
+		} else if gnuCompat {
+			for i := nprefix - 1; i >= 0; i-- {
+				if inst.Prefix[i]&0xFF == 0xF3 {
+					inst.Prefix[i] |= PrefixImplicit
+					inst.Op = PAUSE
+					inst.Args[0] = nil
+					inst.Args[1] = nil
+					break
+				}
+			}
+		}
+	}
+
+	// defaultSeg returns the default segment for an implicit
+	// memory reference: the final override if present, or else DS.
+	defaultSeg := func() Reg {
+		if segIndex >= 0 {
+			inst.Prefix[segIndex] |= PrefixImplicit
+			return prefixToSegment(inst.Prefix[segIndex])
+		}
+		return DS
+	}
+
+	// Add implicit arguments not present in the tables.
+	// Normally we shy away from making implicit arguments explicit,
+	// following the Intel manuals, but adding the arguments seems
+	// the best way to express the effect of the segment override prefixes.
+	// TODO(rsc): Perhaps add these to the tables and
+	// create bytecode instructions for them.
+	usedAddrSize := false
+	switch inst.Op {
+	case INSB, INSW, INSD:
+		inst.Args[0] = Mem{Segment: ES, Base: baseRegForBits(addrMode) + DI - AX}
+		inst.Args[1] = DX
+		usedAddrSize = true
+
+	case OUTSB, OUTSW, OUTSD:
+		inst.Args[0] = DX
+		inst.Args[1] = Mem{Segment: defaultSeg(), Base: baseRegForBits(addrMode) + SI - AX}
+		usedAddrSize = true
+
+	case MOVSB, MOVSW, MOVSD, MOVSQ:
+		inst.Args[0] = Mem{Segment: ES, Base: baseRegForBits(addrMode) + DI - AX}
+		inst.Args[1] = Mem{Segment: defaultSeg(), Base: baseRegForBits(addrMode) + SI - AX}
+		usedAddrSize = true
+
+	case CMPSB, CMPSW, CMPSD, CMPSQ:
+		inst.Args[0] = Mem{Segment: defaultSeg(), Base: baseRegForBits(addrMode) + SI - AX}
+		inst.Args[1] = Mem{Segment: ES, Base: baseRegForBits(addrMode) + DI - AX}
+		usedAddrSize = true
+
+	case LODSB, LODSW, LODSD, LODSQ:
+		switch inst.Op {
+		case LODSB:
+			inst.Args[0] = AL
+		case LODSW:
+			inst.Args[0] = AX
+		case LODSD:
+			inst.Args[0] = EAX
+		case LODSQ:
+			inst.Args[0] = RAX
+		}
+		inst.Args[1] = Mem{Segment: defaultSeg(), Base: baseRegForBits(addrMode) + SI - AX}
+		usedAddrSize = true
+
+	case STOSB, STOSW, STOSD, STOSQ:
+		inst.Args[0] = Mem{Segment: ES, Base: baseRegForBits(addrMode) + DI - AX}
+		switch inst.Op {
+		case STOSB:
+			inst.Args[1] = AL
+		case STOSW:
+			inst.Args[1] = AX
+		case STOSD:
+			inst.Args[1] = EAX
+		case STOSQ:
+			inst.Args[1] = RAX
+		}
+		usedAddrSize = true
+
+	case SCASB, SCASW, SCASD, SCASQ:
+		inst.Args[1] = Mem{Segment: ES, Base: baseRegForBits(addrMode) + DI - AX}
+		switch inst.Op {
+		case SCASB:
+			inst.Args[0] = AL
+		case SCASW:
+			inst.Args[0] = AX
+		case SCASD:
+			inst.Args[0] = EAX
+		case SCASQ:
+			inst.Args[0] = RAX
+		}
+		usedAddrSize = true
+
+	case XLATB:
+		inst.Args[0] = Mem{Segment: defaultSeg(), Base: baseRegForBits(addrMode) + BX - AX}
+		usedAddrSize = true
+	}
+
+	// If we used the address size annotation to construct the
+	// argument list, mark that prefix as implicit: it doesn't need
+	// to be shown when printing the instruction.
+	if haveMem || usedAddrSize {
+		if addrSizeIndex >= 0 {
+			inst.Prefix[addrSizeIndex] |= PrefixImplicit
+		}
+	}
+
+	// Similarly, if there's some memory operand, the segment
+	// will be shown there and doesn't need to be shown as an
+	// explicit prefix.
+	if haveMem {
+		if segIndex >= 0 {
+			inst.Prefix[segIndex] |= PrefixImplicit
+		}
+	}
+
+	// Branch predict prefixes are overloaded segment prefixes,
+	// since segment prefixes don't make sense on conditional jumps.
+	// Rewrite final instance to prediction prefix.
+	// The set of instructions to which the prefixes apply (other then the
+	// Jcc conditional jumps) is not 100% clear from the manuals, but
+	// the disassemblers seem to agree about the LOOP and JCXZ instructions,
+	// so we'll follow along.
+	// TODO(rsc): Perhaps this instruction class should be derived from the CSV.
+	if isCondJmp[inst.Op] || isLoop[inst.Op] || inst.Op == JCXZ || inst.Op == JECXZ || inst.Op == JRCXZ {
+	PredictLoop:
+		for i := nprefix - 1; i >= 0; i-- {
+			p := inst.Prefix[i]
+			switch p & 0xFF {
+			case PrefixCS:
+				inst.Prefix[i] = PrefixPN
+				break PredictLoop
+			case PrefixDS:
+				inst.Prefix[i] = PrefixPT
+				break PredictLoop
+			}
+		}
+	}
+
+	// The BND prefix is part of the Intel Memory Protection Extensions (MPX).
+	// A REPN applied to certain control transfers is a BND prefix to bound
+	// the range of possible destinations. There's surprisingly little documentation
+	// about this, so we just do what libopcodes and xed agree on.
+	// In particular, it's unclear why a REPN applied to LOOP or JCXZ instructions
+	// does not turn into a BND.
+	// TODO(rsc): Perhaps this instruction class should be derived from the CSV.
+	if isCondJmp[inst.Op] || inst.Op == JMP || inst.Op == CALL || inst.Op == RET {
+		for i := nprefix - 1; i >= 0; i-- {
+			p := inst.Prefix[i]
+			if p&^PrefixIgnored == PrefixREPN {
+				inst.Prefix[i] = PrefixBND
+				break
+			}
+		}
+	}
+
+	// The LOCK prefix only applies to certain instructions, and then only
+	// to instances of the instruction with a memory destination.
+	// Other uses of LOCK are invalid and cause a processor exception,
+	// in contrast to the "just ignore it" spirit applied to all other prefixes.
+	// Mark invalid lock prefixes.
+	hasLock := false
+	if lockIndex >= 0 && inst.Prefix[lockIndex]&PrefixImplicit == 0 {
+		switch inst.Op {
+		// TODO(rsc): Perhaps this instruction class should be derived from the CSV.
+		case ADD, ADC, AND, BTC, BTR, BTS, CMPXCHG, CMPXCHG8B, CMPXCHG16B, DEC, INC, NEG, NOT, OR, SBB, SUB, XOR, XADD, XCHG:
+			if isMem(inst.Args[0]) {
+				hasLock = true
+				break
+			}
+			fallthrough
+		default:
+			inst.Prefix[lockIndex] |= PrefixInvalid
+		}
+	}
+
+	// In certain cases, all of which require a memory destination,
+	// the REPN and REP prefixes are interpreted as XACQUIRE and XRELEASE
+	// from the Intel Transactional Synchroniation Extensions (TSX).
+	//
+	// The specific rules are:
+	// (1) Any instruction with a valid LOCK prefix can have XACQUIRE or XRELEASE.
+	// (2) Any XCHG, which always has an implicit LOCK, can have XACQUIRE or XRELEASE.
+	// (3) Any 0x88-, 0x89-, 0xC6-, or 0xC7-opcode MOV can have XRELEASE.
+	if isMem(inst.Args[0]) {
+		if inst.Op == XCHG {
+			hasLock = true
+		}
+
+		for i := len(inst.Prefix) - 1; i >= 0; i-- {
+			p := inst.Prefix[i] &^ PrefixIgnored
+			switch p {
+			case PrefixREPN:
+				if hasLock {
+					inst.Prefix[i] = inst.Prefix[i]&PrefixIgnored | PrefixXACQUIRE
+				}
+
+			case PrefixREP:
+				if hasLock {
+					inst.Prefix[i] = inst.Prefix[i]&PrefixIgnored | PrefixXRELEASE
+				}
+
+				if inst.Op == MOV {
+					op := (inst.Opcode >> 24) &^ 1
+					if op == 0x88 || op == 0xC6 {
+						inst.Prefix[i] = inst.Prefix[i]&PrefixIgnored | PrefixXRELEASE
+					}
+				}
+			}
+		}
+	}
+
+	// If REP is used on a non-REP-able instruction, mark the prefix as ignored.
+	if repIndex >= 0 {
+		switch inst.Prefix[repIndex] {
+		case PrefixREP, PrefixREPN:
+			switch inst.Op {
+			// According to the manuals, the REP/REPE prefix applies to all of these,
+			// while the REPN applies only to some of them. However, both libopcodes
+			// and xed show both prefixes explicitly for all instructions, so we do the same.
+			// TODO(rsc): Perhaps this instruction class should be derived from the CSV.
+			case INSB, INSW, INSD,
+				MOVSB, MOVSW, MOVSD, MOVSQ,
+				OUTSB, OUTSW, OUTSD,
+				LODSB, LODSW, LODSD, LODSQ,
+				CMPSB, CMPSW, CMPSD, CMPSQ,
+				SCASB, SCASW, SCASD, SCASQ,
+				STOSB, STOSW, STOSD, STOSQ:
+				// ok
+			default:
+				inst.Prefix[repIndex] |= PrefixIgnored
+			}
+		}
+	}
+
+	// If REX was present, mark implicit if all the 1 bits were consumed.
+	if rexIndex >= 0 {
+		if rexUsed != 0 {
+			rexUsed |= PrefixREX
+		}
+		if rex&^rexUsed == 0 {
+			inst.Prefix[rexIndex] |= PrefixImplicit
+		}
+	}
+
+	inst.DataSize = dataMode
+	inst.AddrSize = addrMode
+	inst.Mode = mode
+	inst.Len = pos
+	return inst, nil
+}
+
+var errInternal = errors.New("internal error")
+
+// addr16 records the eight 16-bit addressing modes.
+var addr16 = [8]Mem{
+	{Base: BX, Scale: 1, Index: SI},
+	{Base: BX, Scale: 1, Index: DI},
+	{Base: BP, Scale: 1, Index: SI},
+	{Base: BP, Scale: 1, Index: DI},
+	{Base: SI},
+	{Base: DI},
+	{Base: BP},
+	{Base: BX},
+}
+
+// baseReg returns the base register for a given register size in bits.
+func baseRegForBits(bits int) Reg {
+	switch bits {
+	case 8:
+		return AL
+	case 16:
+		return AX
+	case 32:
+		return EAX
+	case 64:
+		return RAX
+	}
+	return 0
+}
+
+// baseReg records the base register for argument types that specify
+// a range of registers indexed by op, regop, or rm.
+var baseReg = [...]Reg{
+	xArgDR0dashDR7: DR0,
+	xArgMm1:        M0,
+	xArgMm2:        M0,
+	xArgMm2M64:     M0,
+	xArgMm:         M0,
+	xArgMmM32:      M0,
+	xArgMmM64:      M0,
+	xArgR16:        AX,
+	xArgR16op:      AX,
+	xArgR32:        EAX,
+	xArgR32M16:     EAX,
+	xArgR32M8:      EAX,
+	xArgR32op:      EAX,
+	xArgR64:        RAX,
+	xArgR64M16:     RAX,
+	xArgR64op:      RAX,
+	xArgR8:         AL,
+	xArgR8op:       AL,
+	xArgRM16:       AX,
+	xArgRM32:       EAX,
+	xArgRM64:       RAX,
+	xArgRM8:        AL,
+	xArgRmf16:      AX,
+	xArgRmf32:      EAX,
+	xArgRmf64:      RAX,
+	xArgSTi:        F0,
+	xArgTR0dashTR7: TR0,
+	xArgXmm1:       X0,
+	xArgXmm2:       X0,
+	xArgXmm2M128:   X0,
+	xArgXmm2M16:    X0,
+	xArgXmm2M32:    X0,
+	xArgXmm2M64:    X0,
+	xArgXmm:        X0,
+	xArgXmmM128:    X0,
+	xArgXmmM32:     X0,
+	xArgXmmM64:     X0,
+}
+
+// prefixToSegment returns the segment register
+// corresponding to a particular segment prefix.
+func prefixToSegment(p Prefix) Reg {
+	switch p &^ PrefixImplicit {
+	case PrefixCS:
+		return CS
+	case PrefixDS:
+		return DS
+	case PrefixES:
+		return ES
+	case PrefixFS:
+		return FS
+	case PrefixGS:
+		return GS
+	case PrefixSS:
+		return SS
+	}
+	return 0
+}
+
+// fixedArg records the fixed arguments corresponding to the given bytecodes.
+var fixedArg = [...]Arg{
+	xArg1:    Imm(1),
+	xArg3:    Imm(3),
+	xArgAL:   AL,
+	xArgAX:   AX,
+	xArgDX:   DX,
+	xArgEAX:  EAX,
+	xArgEDX:  EDX,
+	xArgRAX:  RAX,
+	xArgRDX:  RDX,
+	xArgCL:   CL,
+	xArgCS:   CS,
+	xArgDS:   DS,
+	xArgES:   ES,
+	xArgFS:   FS,
+	xArgGS:   GS,
+	xArgSS:   SS,
+	xArgST:   F0,
+	xArgXMM0: X0,
+}
+
+// memBytes records the size of the memory pointed at
+// by a memory argument of the given form.
+var memBytes = [...]int8{
+	xArgM128:       128 / 8,
+	xArgM16:        16 / 8,
+	xArgM16and16:   (16 + 16) / 8,
+	xArgM16colon16: (16 + 16) / 8,
+	xArgM16colon32: (16 + 32) / 8,
+	xArgM16int:     16 / 8,
+	xArgM2byte:     2,
+	xArgM32:        32 / 8,
+	xArgM32and32:   (32 + 32) / 8,
+	xArgM32fp:      32 / 8,
+	xArgM32int:     32 / 8,
+	xArgM64:        64 / 8,
+	xArgM64fp:      64 / 8,
+	xArgM64int:     64 / 8,
+	xArgMm2M64:     64 / 8,
+	xArgMmM32:      32 / 8,
+	xArgMmM64:      64 / 8,
+	xArgMoffs16:    16 / 8,
+	xArgMoffs32:    32 / 8,
+	xArgMoffs64:    64 / 8,
+	xArgMoffs8:     8 / 8,
+	xArgR32M16:     16 / 8,
+	xArgR32M8:      8 / 8,
+	xArgR64M16:     16 / 8,
+	xArgRM16:       16 / 8,
+	xArgRM32:       32 / 8,
+	xArgRM64:       64 / 8,
+	xArgRM8:        8 / 8,
+	xArgXmm2M128:   128 / 8,
+	xArgXmm2M16:    16 / 8,
+	xArgXmm2M32:    32 / 8,
+	xArgXmm2M64:    64 / 8,
+	xArgXmm:        128 / 8,
+	xArgXmmM128:    128 / 8,
+	xArgXmmM32:     32 / 8,
+	xArgXmmM64:     64 / 8,
+}
+
+// isCondJmp records the conditional jumps.
+var isCondJmp = [maxOp + 1]bool{
+	JA:  true,
+	JAE: true,
+	JB:  true,
+	JBE: true,
+	JE:  true,
+	JG:  true,
+	JGE: true,
+	JL:  true,
+	JLE: true,
+	JNE: true,
+	JNO: true,
+	JNP: true,
+	JNS: true,
+	JO:  true,
+	JP:  true,
+	JS:  true,
+}
+
+// isLoop records the loop operators.
+var isLoop = [maxOp + 1]bool{
+	LOOP:   true,
+	LOOPE:  true,
+	LOOPNE: true,
+	JECXZ:  true,
+	JRCXZ:  true,
+}
diff --git a/src/cmd/internal/rsc.io/x86/x86asm/decode_test.go b/src/cmd/internal/rsc.io/x86/x86asm/decode_test.go
new file mode 100644
index 0000000..fb28458
--- /dev/null
+++ b/src/cmd/internal/rsc.io/x86/x86asm/decode_test.go
@@ -0,0 +1,71 @@
+// 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 x86asm
+
+import (
+	"encoding/hex"
+	"io/ioutil"
+	"strconv"
+	"strings"
+	"testing"
+)
+
+func TestDecode(t *testing.T) {
+	data, err := ioutil.ReadFile("testdata/decode.txt")
+	if err != nil {
+		t.Fatal(err)
+	}
+	all := string(data)
+	for strings.Contains(all, "\t\t") {
+		all = strings.Replace(all, "\t\t", "\t", -1)
+	}
+	for _, line := range strings.Split(all, "\n") {
+		line = strings.TrimSpace(line)
+		if line == "" || strings.HasPrefix(line, "#") {
+			continue
+		}
+		f := strings.SplitN(line, "\t", 4)
+		i := strings.Index(f[0], "|")
+		if i < 0 {
+			t.Errorf("parsing %q: missing | separator", f[0])
+			continue
+		}
+		if i%2 != 0 {
+			t.Errorf("parsing %q: misaligned | separator", f[0])
+		}
+		size := i / 2
+		code, err := hex.DecodeString(f[0][:i] + f[0][i+1:])
+		if err != nil {
+			t.Errorf("parsing %q: %v", f[0], err)
+			continue
+		}
+		mode, err := strconv.Atoi(f[1])
+		if err != nil {
+			t.Errorf("invalid mode %q in: %s", f[1], line)
+			continue
+		}
+		syntax, asm := f[2], f[3]
+		inst, err := Decode(code, mode)
+		var out string
+		if err != nil {
+			out = "error: " + err.Error()
+		} else {
+			switch syntax {
+			case "gnu":
+				out = GNUSyntax(inst)
+			case "intel":
+				out = IntelSyntax(inst)
+			case "plan9":
+				out = Plan9Syntax(inst, 0, nil)
+			default:
+				t.Errorf("unknown syntax %q", syntax)
+				continue
+			}
+		}
+		if out != asm || inst.Len != size {
+			t.Errorf("Decode(%s) [%s] = %s, %d, want %s, %d", f[0], syntax, out, inst.Len, asm, size)
+		}
+	}
+}
diff --git a/src/cmd/internal/rsc.io/x86/x86asm/ext_test.go b/src/cmd/internal/rsc.io/x86/x86asm/ext_test.go
new file mode 100644
index 0000000..f65d6b2
--- /dev/null
+++ b/src/cmd/internal/rsc.io/x86/x86asm/ext_test.go
@@ -0,0 +1,811 @@
+// 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.
+
+// Support for testing against external disassembler program.
+
+package x86asm
+
+import (
+	"bufio"
+	"bytes"
+	"encoding/hex"
+	"flag"
+	"fmt"
+	"io/ioutil"
+	"log"
+	"math/rand"
+	"os"
+	"os/exec"
+	"regexp"
+	"runtime"
+	"strings"
+	"testing"
+	"time"
+)
+
+var (
+	printTests = flag.Bool("printtests", false, "print test cases that exercise new code paths")
+	dumpTest   = flag.Bool("dump", false, "dump all encodings")
+	mismatch   = flag.Bool("mismatch", false, "log allowed mismatches")
+	longTest   = flag.Bool("long", false, "long test")
+	keep       = flag.Bool("keep", false, "keep object files around")
+	debug      = false
+)
+
+// A ExtInst represents a single decoded instruction parsed
+// from an external disassembler's output.
+type ExtInst struct {
+	addr uint32
+	enc  [32]byte
+	nenc int
+	text string
+}
+
+func (r ExtInst) String() string {
+	return fmt.Sprintf("%#x: % x: %s", r.addr, r.enc, r.text)
+}
+
+// An ExtDis is a connection between an external disassembler and a test.
+type ExtDis struct {
+	Arch     int
+	Dec      chan ExtInst
+	File     *os.File
+	Size     int
+	KeepFile bool
+	Cmd      *exec.Cmd
+}
+
+// Run runs the given command - the external disassembler - and returns
+// a buffered reader of its standard output.
+func (ext *ExtDis) Run(cmd ...string) (*bufio.Reader, error) {
+	if *keep {
+		log.Printf("%s\n", strings.Join(cmd, " "))
+	}
+	ext.Cmd = exec.Command(cmd[0], cmd[1:]...)
+	out, err := ext.Cmd.StdoutPipe()
+	if err != nil {
+		return nil, fmt.Errorf("stdoutpipe: %v", err)
+	}
+	if err := ext.Cmd.Start(); err != nil {
+		return nil, fmt.Errorf("exec: %v", err)
+	}
+
+	b := bufio.NewReaderSize(out, 1<<20)
+	return b, nil
+}
+
+// Wait waits for the command started with Run to exit.
+func (ext *ExtDis) Wait() error {
+	return ext.Cmd.Wait()
+}
+
+// testExtDis tests a set of byte sequences against an external disassembler.
+// The disassembler is expected to produce the given syntax and be run
+// in the given architecture mode (16, 32, or 64-bit).
+// The extdis function must start the external disassembler
+// and then parse its output, sending the parsed instructions on ext.Dec.
+// The generate function calls its argument f once for each byte sequence
+// to be tested. The generate function itself will be called twice, and it must
+// make the same sequence of calls to f each time.
+// When a disassembly does not match the internal decoding,
+// allowedMismatch determines whether this mismatch should be
+// allowed, or else considered an error.
+func testExtDis(
+	t *testing.T,
+	syntax string,
+	arch int,
+	extdis func(ext *ExtDis) error,
+	generate func(f func([]byte)),
+	allowedMismatch func(text string, size int, inst *Inst, dec ExtInst) bool,
+) {
+	start := time.Now()
+	ext := &ExtDis{
+		Dec:  make(chan ExtInst),
+		Arch: arch,
+	}
+	errc := make(chan error)
+
+	// First pass: write instructions to input file for external disassembler.
+	file, f, size, err := writeInst(generate)
+	if err != nil {
+		t.Fatal(err)
+	}
+	ext.Size = size
+	ext.File = f
+	defer func() {
+		f.Close()
+		if !*keep {
+			os.Remove(file)
+		}
+	}()
+
+	// Second pass: compare disassembly against our decodings.
+	var (
+		totalTests  = 0
+		totalSkips  = 0
+		totalErrors = 0
+
+		errors = make([]string, 0, 100) // sampled errors, at most cap
+	)
+	go func() {
+		errc <- extdis(ext)
+	}()
+	generate(func(enc []byte) {
+		dec, ok := <-ext.Dec
+		if !ok {
+			t.Errorf("decoding stream ended early")
+			return
+		}
+		inst, text := disasm(syntax, arch, pad(enc))
+		totalTests++
+		if *dumpTest {
+			fmt.Printf("%x -> %s [%d]\n", enc[:len(enc)], dec.text, dec.nenc)
+		}
+		if text != dec.text || inst.Len != dec.nenc {
+			suffix := ""
+			if allowedMismatch(text, size, &inst, dec) {
+				totalSkips++
+				if !*mismatch {
+					return
+				}
+				suffix += " (allowed mismatch)"
+			}
+			totalErrors++
+			if len(errors) >= cap(errors) {
+				j := rand.Intn(totalErrors)
+				if j >= cap(errors) {
+					return
+				}
+				errors = append(errors[:j], errors[j+1:]...)
+			}
+			errors = append(errors, fmt.Sprintf("decode(%x) = %q, %d, want %q, %d%s", enc, text, inst.Len, dec.text, dec.nenc, suffix))
+		}
+	})
+
+	if *mismatch {
+		totalErrors -= totalSkips
+	}
+
+	for _, b := range errors {
+		t.Log(b)
+	}
+
+	if totalErrors > 0 {
+		t.Fail()
+	}
+	t.Logf("%d test cases, %d expected mismatches, %d failures; %.0f cases/second", totalTests, totalSkips, totalErrors, float64(totalTests)/time.Since(start).Seconds())
+
+	if err := <-errc; err != nil {
+		t.Fatal("external disassembler: %v", err)
+	}
+
+}
+
+const start = 0x8000 // start address of text
+
+// writeInst writes the generated byte sequences to a new file
+// starting at offset start. That file is intended to be the input to
+// the external disassembler.
+func writeInst(generate func(func([]byte))) (file string, f *os.File, size int, err error) {
+	f, err = ioutil.TempFile("", "x86map")
+	if err != nil {
+		return
+	}
+
+	file = f.Name()
+
+	f.Seek(start, 0)
+	w := bufio.NewWriter(f)
+	defer w.Flush()
+	size = 0
+	generate(func(x []byte) {
+		if len(x) > 16 {
+			x = x[:16]
+		}
+		if debug {
+			fmt.Printf("%#x: %x%x\n", start+size, x, pops[len(x):])
+		}
+		w.Write(x)
+		w.Write(pops[len(x):])
+		size += len(pops)
+	})
+	return file, f, size, nil
+}
+
+// 0x5F is a single-byte pop instruction.
+// We pad the bytes we want decoded with enough 0x5Fs
+// that no matter what state the instruction stream is in
+// after reading our bytes, the pops will get us back to
+// a forced instruction boundary.
+var pops = []byte{
+	0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f,
+	0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f,
+	0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f,
+	0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f,
+}
+
+// pad pads the code sequenc with pops.
+func pad(enc []byte) []byte {
+	return append(enc[:len(enc):len(enc)], pops...)
+}
+
+// disasm returns the decoded instruction and text
+// for the given source bytes, using the given syntax and mode.
+func disasm(syntax string, mode int, src []byte) (inst Inst, text string) {
+	// If printTests is set, we record the coverage value
+	// before and after, and we write out the inputs for which
+	// coverage went up, in the format expected in testdata/decode.text.
+	// This produces a fairly small set of test cases that exercise nearly
+	// all the code.
+	var cover float64
+	if *printTests {
+		cover -= coverage()
+	}
+
+	inst, err := decode1(src, mode, syntax == "gnu")
+	if err != nil {
+		text = "error: " + err.Error()
+	} else {
+		switch syntax {
+		case "gnu":
+			text = GNUSyntax(inst)
+		case "intel":
+			text = IntelSyntax(inst)
+		case "plan9":
+			text = Plan9Syntax(inst, 0, nil)
+		default:
+			text = "error: unknown syntax " + syntax
+		}
+	}
+
+	if *printTests {
+		cover += coverage()
+		if cover > 0 {
+			max := len(src)
+			if max > 16 && inst.Len <= 16 {
+				max = 16
+			}
+			fmt.Printf("%x|%x\t%d\t%s\t%s\n", src[:inst.Len], src[inst.Len:max], mode, syntax, text)
+		}
+	}
+
+	return
+}
+
+// coverage returns a floating point number denoting the
+// test coverage until now. The number increases when new code paths are exercised,
+// both in the Go program and in the decoder byte code.
+func coverage() float64 {
+	/*
+		testing.Coverage is not in the main distribution.
+		The implementation, which must go in package testing, is:
+
+		// Coverage reports the current code coverage as a fraction in the range [0, 1].
+		func Coverage() float64 {
+			var n, d int64
+			for _, counters := range cover.Counters {
+				for _, c := range counters {
+					if c > 0 {
+						n++
+					}
+					d++
+				}
+			}
+			if d == 0 {
+				return 0
+			}
+			return float64(n) / float64(d)
+		}
+	*/
+
+	var f float64
+	// f += testing.Coverage()
+	f += decodeCoverage()
+	return f
+}
+
+func decodeCoverage() float64 {
+	n := 0
+	for _, t := range decoderCover {
+		if t {
+			n++
+		}
+	}
+	return float64(1+n) / float64(1+len(decoderCover))
+}
+
+// Helpers for writing disassembler output parsers.
+
+// isPrefix reports whether text is the name of an instruction prefix.
+func isPrefix(text string) bool {
+	return prefixByte[text] > 0
+}
+
+// prefixByte maps instruction prefix text to actual prefix byte values.
+var prefixByte = map[string]byte{
+	"es":       0x26,
+	"cs":       0x2e,
+	"ss":       0x36,
+	"ds":       0x3e,
+	"fs":       0x64,
+	"gs":       0x65,
+	"data16":   0x66,
+	"addr16":   0x67,
+	"lock":     0xf0,
+	"repn":     0xf2,
+	"repne":    0xf2,
+	"rep":      0xf3,
+	"repe":     0xf3,
+	"xacquire": 0xf2,
+	"xrelease": 0xf3,
+	"bnd":      0xf2,
+	"addr32":   0x66,
+	"data32":   0x67,
+}
+
+// hasPrefix reports whether any of the space-separated words in the text s
+// begins with any of the given prefixes.
+func hasPrefix(s string, prefixes ...string) bool {
+	for _, prefix := range prefixes {
+		for s := s; s != ""; {
+			if strings.HasPrefix(s, prefix) {
+				return true
+			}
+			i := strings.Index(s, " ")
+			if i < 0 {
+				break
+			}
+			s = s[i+1:]
+		}
+	}
+	return false
+}
+
+// contains reports whether the text s contains any of the given substrings.
+func contains(s string, substrings ...string) bool {
+	for _, sub := range substrings {
+		if strings.Contains(s, sub) {
+			return true
+		}
+	}
+	return false
+}
+
+// isHex reports whether b is a hexadecimal character (0-9A-Fa-f).
+func isHex(b byte) bool { return b == '0' || unhex[b] > 0 }
+
+// parseHex parses the hexadecimal byte dump in hex,
+// appending the parsed bytes to raw and returning the updated slice.
+// The returned bool signals whether any invalid hex was found.
+// Spaces and tabs between bytes are okay but any other non-hex is not.
+func parseHex(hex []byte, raw []byte) ([]byte, bool) {
+	hex = trimSpace(hex)
+	for j := 0; j < len(hex); {
+		for hex[j] == ' ' || hex[j] == '\t' {
+			j++
+		}
+		if j >= len(hex) {
+			break
+		}
+		if j+2 > len(hex) || !isHex(hex[j]) || !isHex(hex[j+1]) {
+			return nil, false
+		}
+		raw = append(raw, unhex[hex[j]]<<4|unhex[hex[j+1]])
+		j += 2
+	}
+	return raw, true
+}
+
+var unhex = [256]byte{
+	'0': 0,
+	'1': 1,
+	'2': 2,
+	'3': 3,
+	'4': 4,
+	'5': 5,
+	'6': 6,
+	'7': 7,
+	'8': 8,
+	'9': 9,
+	'A': 10,
+	'B': 11,
+	'C': 12,
+	'D': 13,
+	'E': 14,
+	'F': 15,
+	'a': 10,
+	'b': 11,
+	'c': 12,
+	'd': 13,
+	'e': 14,
+	'f': 15,
+}
+
+// index is like bytes.Index(s, []byte(t)) but avoids the allocation.
+func index(s []byte, t string) int {
+	i := 0
+	for {
+		j := bytes.IndexByte(s[i:], t[0])
+		if j < 0 {
+			return -1
+		}
+		i = i + j
+		if i+len(t) > len(s) {
+			return -1
+		}
+		for k := 1; k < len(t); k++ {
+			if s[i+k] != t[k] {
+				goto nomatch
+			}
+		}
+		return i
+	nomatch:
+		i++
+	}
+}
+
+// fixSpace rewrites runs of spaces, tabs, and newline characters into single spaces in s.
+// If s must be rewritten, it is rewritten in place.
+func fixSpace(s []byte) []byte {
+	s = trimSpace(s)
+	for i := 0; i < len(s); i++ {
+		if s[i] == '\t' || s[i] == '\n' || i > 0 && s[i] == ' ' && s[i-1] == ' ' {
+			goto Fix
+		}
+	}
+	return s
+
+Fix:
+	b := s
+	w := 0
+	for i := 0; i < len(s); i++ {
+		c := s[i]
+		if c == '\t' || c == '\n' {
+			c = ' '
+		}
+		if c == ' ' && w > 0 && b[w-1] == ' ' {
+			continue
+		}
+		b[w] = c
+		w++
+	}
+	if w > 0 && b[w-1] == ' ' {
+		w--
+	}
+	return b[:w]
+}
+
+// trimSpace trims leading and trailing space from s, returning a subslice of s.
+func trimSpace(s []byte) []byte {
+	j := len(s)
+	for j > 0 && (s[j-1] == ' ' || s[j-1] == '\t' || s[j-1] == '\n') {
+		j--
+	}
+	i := 0
+	for i < j && (s[i] == ' ' || s[i] == '\t') {
+		i++
+	}
+	return s[i:j]
+}
+
+// pcrel and pcrelw match instructions using relative addressing mode.
+var (
+	pcrel  = regexp.MustCompile(`^((?:.* )?(?:j[a-z]+|call|ljmp|loopn?e?w?|xbegin)q?(?:,p[nt])?) 0x([0-9a-f]+)$`)
+	pcrelw = regexp.MustCompile(`^((?:.* )?(?:callw|jmpw|xbeginw|ljmpw)(?:,p[nt])?) 0x([0-9a-f]+)$`)
+)
+
+// Generators.
+//
+// The test cases are described as functions that invoke a callback repeatedly,
+// with a new input sequence each time. These helpers make writing those
+// a little easier.
+
+// hexCases generates the cases written in hexadecimal in the encoded string.
+// Spaces in 'encoded' separate entire test cases, not individual bytes.
+func hexCases(t *testing.T, encoded string) func(func([]byte)) {
+	return func(try func([]byte)) {
+		for _, x := range strings.Fields(encoded) {
+			src, err := hex.DecodeString(x)
+			if err != nil {
+				t.Errorf("parsing %q: %v", x, err)
+			}
+			try(src)
+		}
+	}
+}
+
+// testdataCases generates the test cases recorded in testdata/decode.txt.
+// It only uses the inputs; it ignores the answers recorded in that file.
+func testdataCases(t *testing.T) func(func([]byte)) {
+	var codes [][]byte
+	data, err := ioutil.ReadFile("testdata/decode.txt")
+	if err != nil {
+		t.Fatal(err)
+	}
+	for _, line := range strings.Split(string(data), "\n") {
+		line = strings.TrimSpace(line)
+		if line == "" || strings.HasPrefix(line, "#") {
+			continue
+		}
+		f := strings.Fields(line)[0]
+		i := strings.Index(f, "|")
+		if i < 0 {
+			t.Errorf("parsing %q: missing | separator", f)
+			continue
+		}
+		if i%2 != 0 {
+			t.Errorf("parsing %q: misaligned | separator", f)
+		}
+		code, err := hex.DecodeString(f[:i] + f[i+1:])
+		if err != nil {
+			t.Errorf("parsing %q: %v", f, err)
+			continue
+		}
+		codes = append(codes, code)
+	}
+
+	return func(try func([]byte)) {
+		for _, code := range codes {
+			try(code)
+		}
+	}
+}
+
+// manyPrefixes generates all possible 2⁹ combinations of nine chosen prefixes.
+// The relative ordering of the prefixes within the combinations varies deterministically.
+func manyPrefixes(try func([]byte)) {
+	var prefixBytes = []byte{0x66, 0x67, 0xF0, 0xF2, 0xF3, 0x3E, 0x36, 0x66, 0x67}
+	var enc []byte
+	for i := 0; i < 1<<uint(len(prefixBytes)); i++ {
+		enc = enc[:0]
+		for j, p := range prefixBytes {
+			if i&(1<<uint(j)) != 0 {
+				enc = append(enc, p)
+			}
+		}
+		if len(enc) > 0 {
+			k := i % len(enc)
+			enc[0], enc[k] = enc[k], enc[0]
+		}
+		try(enc)
+	}
+}
+
+// basicPrefixes geneartes 8 different possible prefix cases: no prefix
+// and then one each of seven different prefix bytes.
+func basicPrefixes(try func([]byte)) {
+	try(nil)
+	for _, b := range []byte{0x66, 0x67, 0xF0, 0xF2, 0xF3, 0x3E, 0x36} {
+		try([]byte{b})
+	}
+}
+
+func rexPrefixes(try func([]byte)) {
+	try(nil)
+	for _, b := range []byte{0x40, 0x48, 0x43, 0x4C} {
+		try([]byte{b})
+	}
+}
+
+// concat takes two generators and returns a generator for the
+// cross product of the two, concatenating the results from each.
+func concat(gen1, gen2 func(func([]byte))) func(func([]byte)) {
+	return func(try func([]byte)) {
+		gen1(func(enc1 []byte) {
+			gen2(func(enc2 []byte) {
+				try(append(enc1[:len(enc1):len(enc1)], enc2...))
+			})
+		})
+	}
+}
+
+// concat3 takes three generators and returns a generator for the
+// cross product of the three, concatenating the results from each.
+func concat3(gen1, gen2, gen3 func(func([]byte))) func(func([]byte)) {
+	return func(try func([]byte)) {
+		gen1(func(enc1 []byte) {
+			gen2(func(enc2 []byte) {
+				gen3(func(enc3 []byte) {
+					try(append(append(enc1[:len(enc1):len(enc1)], enc2...), enc3...))
+				})
+			})
+		})
+	}
+}
+
+// concat4 takes four generators and returns a generator for the
+// cross product of the four, concatenating the results from each.
+func concat4(gen1, gen2, gen3, gen4 func(func([]byte))) func(func([]byte)) {
+	return func(try func([]byte)) {
+		gen1(func(enc1 []byte) {
+			gen2(func(enc2 []byte) {
+				gen3(func(enc3 []byte) {
+					gen4(func(enc4 []byte) {
+						try(append(append(append(enc1[:len(enc1):len(enc1)], enc2...), enc3...), enc4...))
+					})
+				})
+			})
+		})
+	}
+}
+
+// filter generates the sequences from gen that satisfy ok.
+func filter(gen func(func([]byte)), ok func([]byte) bool) func(func([]byte)) {
+	return func(try func([]byte)) {
+		gen(func(enc []byte) {
+			if ok(enc) {
+				try(enc)
+			}
+		})
+	}
+}
+
+// enum8bit generates all possible 1-byte sequences, followed by distinctive padding.
+func enum8bit(try func([]byte)) {
+	for i := 0; i < 1<<8; i++ {
+		try([]byte{byte(i), 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88})
+	}
+}
+
+// enum8bit generates all possible 2-byte sequences, followed by distinctive padding.
+func enum16bit(try func([]byte)) {
+	for i := 0; i < 1<<16; i++ {
+		try([]byte{byte(i), byte(i >> 8), 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88})
+	}
+}
+
+// enum24bit generates all possible 3-byte sequences, followed by distinctive padding.
+func enum24bit(try func([]byte)) {
+	for i := 0; i < 1<<24; i++ {
+		try([]byte{byte(i), byte(i >> 8), byte(i >> 16), 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88})
+	}
+}
+
+// enumModRM generates all possible modrm bytes and, for modrm values that indicate
+// a following sib byte, all possible modrm, sib combinations.
+func enumModRM(try func([]byte)) {
+	for i := 0; i < 256; i++ {
+		if (i>>3)&07 == 04 && i>>6 != 3 { // has sib
+			for j := 0; j < 256; j++ {
+				try([]byte{0, byte(i), byte(j), 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}) // byte encodings
+				try([]byte{1, byte(i), byte(j), 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}) // word encodings
+			}
+		} else {
+			try([]byte{0, byte(i), 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}) // byte encodings
+			try([]byte{1, byte(i), 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}) // word encodings
+		}
+	}
+}
+
+// fixed generates the single case b.
+// It's mainly useful to prepare an argument for concat or concat3.
+func fixed(b ...byte) func(func([]byte)) {
+	return func(try func([]byte)) {
+		try(b)
+	}
+}
+
+// testBasic runs the given test function with cases all using opcode as the initial opcode bytes.
+// It runs three phases:
+//
+// First, zero-or-one prefixes followed by opcode followed by all possible 1-byte values.
+// If in -short mode, that's all.
+//
+// Second, zero-or-one prefixes followed by opcode followed by all possible 2-byte values.
+// If not in -long mode, that's all. This phase and the next run in parallel with other tests
+// (using t.Parallel).
+//
+// Finally, opcode followed by all possible 3-byte values. The test can take a very long time
+// and prints progress messages to package log.
+func testBasic(t *testing.T, testfn func(*testing.T, func(func([]byte))), opcode ...byte) {
+	testfn(t, concat3(basicPrefixes, fixed(opcode...), enum8bit))
+	if testing.Short() {
+		return
+	}
+
+	t.Parallel()
+	testfn(t, concat3(basicPrefixes, fixed(opcode...), enum16bit))
+	if !*longTest {
+		return
+	}
+
+	name := caller(2)
+	op1 := make([]byte, len(opcode)+1)
+	copy(op1, opcode)
+	for i := 0; i < 256; i++ {
+		log.Printf("%s 24-bit: %d/256\n", name, i)
+		op1[len(opcode)] = byte(i)
+		testfn(t, concat(fixed(op1...), enum16bit))
+	}
+}
+
+func testBasicREX(t *testing.T, testfn func(*testing.T, func(func([]byte))), opcode ...byte) {
+	testfn(t, filter(concat4(basicPrefixes, rexPrefixes, fixed(opcode...), enum8bit), isValidREX))
+	if testing.Short() {
+		return
+	}
+
+	t.Parallel()
+	testfn(t, filter(concat4(basicPrefixes, rexPrefixes, fixed(opcode...), enum16bit), isValidREX))
+	if !*longTest {
+		return
+	}
+
+	name := caller(2)
+	op1 := make([]byte, len(opcode)+1)
+	copy(op1, opcode)
+	for i := 0; i < 256; i++ {
+		log.Printf("%s 24-bit: %d/256\n", name, i)
+		op1[len(opcode)] = byte(i)
+		testfn(t, filter(concat3(rexPrefixes, fixed(op1...), enum16bit), isValidREX))
+	}
+}
+
+// testPrefix runs the given test function for all many prefix possibilities
+// followed by all possible 1-byte sequences.
+//
+// If in -long mode, it then runs a test of all the prefix possibilities followed
+// by all possible 2-byte sequences.
+func testPrefix(t *testing.T, testfn func(*testing.T, func(func([]byte)))) {
+	t.Parallel()
+	testfn(t, concat(manyPrefixes, enum8bit))
+	if testing.Short() || !*longTest {
+		return
+	}
+
+	name := caller(2)
+	for i := 0; i < 256; i++ {
+		log.Printf("%s 16-bit: %d/256\n", name, i)
+		testfn(t, concat3(manyPrefixes, fixed(byte(i)), enum8bit))
+	}
+}
+
+func testPrefixREX(t *testing.T, testfn func(*testing.T, func(func([]byte)))) {
+	t.Parallel()
+	testfn(t, filter(concat3(manyPrefixes, rexPrefixes, enum8bit), isValidREX))
+	if testing.Short() || !*longTest {
+		return
+	}
+
+	name := caller(2)
+	for i := 0; i < 256; i++ {
+		log.Printf("%s 16-bit: %d/256\n", name, i)
+		testfn(t, filter(concat4(manyPrefixes, rexPrefixes, fixed(byte(i)), enum8bit), isValidREX))
+	}
+}
+
+func caller(skip int) string {
+	pc, _, _, _ := runtime.Caller(skip)
+	f := runtime.FuncForPC(pc)
+	name := "?"
+	if f != nil {
+		name = f.Name()
+		if i := strings.LastIndex(name, "."); i >= 0 {
+			name = name[i+1:]
+		}
+	}
+	return name
+}
+
+func isValidREX(x []byte) bool {
+	i := 0
+	for i < len(x) && isPrefixByte(x[i]) {
+		i++
+	}
+	if i < len(x) && Prefix(x[i]).IsREX() {
+		i++
+		if i < len(x) {
+			return !isPrefixByte(x[i]) && !Prefix(x[i]).IsREX()
+		}
+	}
+	return true
+}
+
+func isPrefixByte(b byte) bool {
+	switch b {
+	case 0x26, 0x2E, 0x36, 0x3E, 0x64, 0x65, 0x66, 0x67, 0xF0, 0xF2, 0xF3:
+		return true
+	}
+	return false
+}
diff --git a/src/cmd/internal/rsc.io/x86/x86asm/gnu.go b/src/cmd/internal/rsc.io/x86/x86asm/gnu.go
new file mode 100644
index 0000000..e2ff801
--- /dev/null
+++ b/src/cmd/internal/rsc.io/x86/x86asm/gnu.go
@@ -0,0 +1,926 @@
+// 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 x86asm
+
+import (
+	"fmt"
+	"strings"
+)
+
+// GNUSyntax returns the GNU assembler syntax for the instruction, as defined by GNU binutils.
+// This general form is often called ``AT&T syntax'' as a reference to AT&T System V Unix.
+func GNUSyntax(inst Inst) string {
+	// Rewrite instruction to mimic GNU peculiarities.
+	// Note that inst has been passed by value and contains
+	// no pointers, so any changes we make here are local
+	// and will not propagate back out to the caller.
+
+	// Adjust opcode [sic].
+	switch inst.Op {
+	case FDIV, FDIVR, FSUB, FSUBR, FDIVP, FDIVRP, FSUBP, FSUBRP:
+		// DC E0, DC F0: libopcodes swaps FSUBR/FSUB and FDIVR/FDIV, at least
+		// if you believe the Intel manual is correct (the encoding is irregular as given;
+		// libopcodes uses the more regular expected encoding).
+		// TODO(rsc): Test to ensure Intel manuals are correct and report to libopcodes maintainers?
+		// NOTE: iant thinks this is deliberate, but we can't find the history.
+		_, reg1 := inst.Args[0].(Reg)
+		_, reg2 := inst.Args[1].(Reg)
+		if reg1 && reg2 && (inst.Opcode>>24 == 0xDC || inst.Opcode>>24 == 0xDE) {
+			switch inst.Op {
+			case FDIV:
+				inst.Op = FDIVR
+			case FDIVR:
+				inst.Op = FDIV
+			case FSUB:
+				inst.Op = FSUBR
+			case FSUBR:
+				inst.Op = FSUB
+			case FDIVP:
+				inst.Op = FDIVRP
+			case FDIVRP:
+				inst.Op = FDIVP
+			case FSUBP:
+				inst.Op = FSUBRP
+			case FSUBRP:
+				inst.Op = FSUBP
+			}
+		}
+
+	case MOVNTSD:
+		// MOVNTSD is F2 0F 2B /r.
+		// MOVNTSS is F3 0F 2B /r (supposedly; not in manuals).
+		// Usually inner prefixes win for display,
+		// so that F3 F2 0F 2B 11 is REP MOVNTSD
+		// and F2 F3 0F 2B 11 is REPN MOVNTSS.
+		// Libopcodes always prefers MOVNTSS regardless of prefix order.
+		if countPrefix(&inst, 0xF3) > 0 {
+			found := false
+			for i := len(inst.Prefix) - 1; i >= 0; i-- {
+				switch inst.Prefix[i] & 0xFF {
+				case 0xF3:
+					if !found {
+						found = true
+						inst.Prefix[i] |= PrefixImplicit
+					}
+				case 0xF2:
+					inst.Prefix[i] &^= PrefixImplicit
+				}
+			}
+			inst.Op = MOVNTSS
+		}
+	}
+
+	// Add implicit arguments.
+	switch inst.Op {
+	case MONITOR:
+		inst.Args[0] = EDX
+		inst.Args[1] = ECX
+		inst.Args[2] = EAX
+		if inst.AddrSize == 16 {
+			inst.Args[2] = AX
+		}
+
+	case MWAIT:
+		if inst.Mode == 64 {
+			inst.Args[0] = RCX
+			inst.Args[1] = RAX
+		} else {
+			inst.Args[0] = ECX
+			inst.Args[1] = EAX
+		}
+	}
+
+	// Adjust which prefixes will be displayed.
+	// The rule is to display all the prefixes not implied by
+	// the usual instruction display, that is, all the prefixes
+	// except the ones with PrefixImplicit set.
+	// However, of course, there are exceptions to the rule.
+	switch inst.Op {
+	case CRC32:
+		// CRC32 has a mandatory F2 prefix.
+		// If there are multiple F2s and no F3s, the extra F2s do not print.
+		// (And Decode has already marked them implicit.)
+		// However, if there is an F3 anywhere, then the extra F2s do print.
+		// If there are multiple F2 prefixes *and* an (ignored) F3,
+		// then libopcodes prints the extra F2s as REPNs.
+		if countPrefix(&inst, 0xF2) > 1 {
+			unmarkImplicit(&inst, 0xF2)
+			markLastImplicit(&inst, 0xF2)
+		}
+
+		// An unused data size override should probably be shown,
+		// to distinguish DATA16 CRC32B from plain CRC32B,
+		// but libopcodes always treats the final override as implicit
+		// and the others as explicit.
+		unmarkImplicit(&inst, PrefixDataSize)
+		markLastImplicit(&inst, PrefixDataSize)
+
+	case CVTSI2SD, CVTSI2SS:
+		if !isMem(inst.Args[1]) {
+			markLastImplicit(&inst, PrefixDataSize)
+		}
+
+	case CVTSD2SI, CVTSS2SI, CVTTSD2SI, CVTTSS2SI,
+		ENTER, FLDENV, FNSAVE, FNSTENV, FRSTOR, LGDT, LIDT, LRET,
+		POP, PUSH, RET, SGDT, SIDT, SYSRET, XBEGIN:
+		markLastImplicit(&inst, PrefixDataSize)
+
+	case LOOP, LOOPE, LOOPNE, MONITOR:
+		markLastImplicit(&inst, PrefixAddrSize)
+
+	case MOV:
+		// The 16-bit and 32-bit forms of MOV Sreg, dst and MOV src, Sreg
+		// cannot be distinguished when src or dst refers to memory, because
+		// Sreg is always a 16-bit value, even when we're doing a 32-bit
+		// instruction. Because the instruction tables distinguished these two,
+		// any operand size prefix has been marked as used (to decide which
+		// branch to take). Unmark it, so that it will show up in disassembly,
+		// so that the reader can tell the size of memory operand.
+		// up with the same arguments
+		dst, _ := inst.Args[0].(Reg)
+		src, _ := inst.Args[1].(Reg)
+		if ES <= src && src <= GS && isMem(inst.Args[0]) || ES <= dst && dst <= GS && isMem(inst.Args[1]) {
+			unmarkImplicit(&inst, PrefixDataSize)
+		}
+
+	case MOVDQU:
+		if countPrefix(&inst, 0xF3) > 1 {
+			unmarkImplicit(&inst, 0xF3)
+			markLastImplicit(&inst, 0xF3)
+		}
+
+	case MOVQ2DQ:
+		markLastImplicit(&inst, PrefixDataSize)
+
+	case SLDT, SMSW, STR, FXRSTOR, XRSTOR, XSAVE, XSAVEOPT, CMPXCHG8B:
+		if isMem(inst.Args[0]) {
+			unmarkImplicit(&inst, PrefixDataSize)
+		}
+
+	case SYSEXIT:
+		unmarkImplicit(&inst, PrefixDataSize)
+	}
+
+	if isCondJmp[inst.Op] || isLoop[inst.Op] || inst.Op == JCXZ || inst.Op == JECXZ || inst.Op == JRCXZ {
+		if countPrefix(&inst, PrefixCS) > 0 && countPrefix(&inst, PrefixDS) > 0 {
+			for i, p := range inst.Prefix {
+				switch p & 0xFFF {
+				case PrefixPN, PrefixPT:
+					inst.Prefix[i] &= 0xF0FF // cut interpretation bits, producing original segment prefix
+				}
+			}
+		}
+	}
+
+	// XACQUIRE/XRELEASE adjustment.
+	if inst.Op == MOV {
+		// MOV into memory is a candidate for turning REP into XRELEASE.
+		// However, if the REP is followed by a REPN, that REPN blocks the
+		// conversion.
+		haveREPN := false
+		for i := len(inst.Prefix) - 1; i >= 0; i-- {
+			switch inst.Prefix[i] &^ PrefixIgnored {
+			case PrefixREPN:
+				haveREPN = true
+			case PrefixXRELEASE:
+				if haveREPN {
+					inst.Prefix[i] = PrefixREP
+				}
+			}
+		}
+	}
+
+	// We only format the final F2/F3 as XRELEASE/XACQUIRE.
+	haveXA := false
+	haveXR := false
+	for i := len(inst.Prefix) - 1; i >= 0; i-- {
+		switch inst.Prefix[i] &^ PrefixIgnored {
+		case PrefixXRELEASE:
+			if !haveXR {
+				haveXR = true
+			} else {
+				inst.Prefix[i] = PrefixREP
+			}
+
+		case PrefixXACQUIRE:
+			if !haveXA {
+				haveXA = true
+			} else {
+				inst.Prefix[i] = PrefixREPN
+			}
+		}
+	}
+
+	// Determine opcode.
+	op := strings.ToLower(inst.Op.String())
+	if alt := gnuOp[inst.Op]; alt != "" {
+		op = alt
+	}
+
+	// Determine opcode suffix.
+	// Libopcodes omits the suffix if the width of the operation
+	// can be inferred from a register arguments. For example,
+	// add $1, %ebx has no suffix because you can tell from the
+	// 32-bit register destination that it is a 32-bit add,
+	// but in addl $1, (%ebx), the destination is memory, so the
+	// size is not evident without the l suffix.
+	needSuffix := true
+SuffixLoop:
+	for i, a := range inst.Args {
+		if a == nil {
+			break
+		}
+		switch a := a.(type) {
+		case Reg:
+			switch inst.Op {
+			case MOVSX, MOVZX:
+				continue
+
+			case SHL, SHR, RCL, RCR, ROL, ROR, SAR:
+				if i == 1 {
+					// shift count does not tell us operand size
+					continue
+				}
+
+			case CRC32:
+				// The source argument does tell us operand size,
+				// but libopcodes still always puts a suffix on crc32.
+				continue
+
+			case PUSH, POP:
+				// Even though segment registers are 16-bit, push and pop
+				// can save/restore them from 32-bit slots, so they
+				// do not imply operand size.
+				if ES <= a && a <= GS {
+					continue
+				}
+
+			case CVTSI2SD, CVTSI2SS:
+				// The integer register argument takes priority.
+				if X0 <= a && a <= X15 {
+					continue
+				}
+			}
+
+			if AL <= a && a <= R15 || ES <= a && a <= GS || X0 <= a && a <= X15 || M0 <= a && a <= M7 {
+				needSuffix = false
+				break SuffixLoop
+			}
+		}
+	}
+
+	if needSuffix {
+		switch inst.Op {
+		case CMPXCHG8B, FLDCW, FNSTCW, FNSTSW, LDMXCSR, LLDT, LMSW, LTR, PCLMULQDQ,
+			SETA, SETAE, SETB, SETBE, SETE, SETG, SETGE, SETL, SETLE, SETNE, SETNO, SETNP, SETNS, SETO, SETP, SETS,
+			SLDT, SMSW, STMXCSR, STR, VERR, VERW:
+			// For various reasons, libopcodes emits no suffix for these instructions.
+
+		case CRC32:
+			op += byteSizeSuffix(argBytes(&inst, inst.Args[1]))
+
+		case LGDT, LIDT, SGDT, SIDT:
+			op += byteSizeSuffix(inst.DataSize / 8)
+
+		case MOVZX, MOVSX:
+			// Integer size conversions get two suffixes.
+			op = op[:4] + byteSizeSuffix(argBytes(&inst, inst.Args[1])) + byteSizeSuffix(argBytes(&inst, inst.Args[0]))
+
+		case LOOP, LOOPE, LOOPNE:
+			// Add w suffix to indicate use of CX register instead of ECX.
+			if inst.AddrSize == 16 {
+				op += "w"
+			}
+
+		case CALL, ENTER, JMP, LCALL, LEAVE, LJMP, LRET, RET, SYSRET, XBEGIN:
+			// Add w suffix to indicate use of 16-bit target.
+			// Exclude JMP rel8.
+			if inst.Opcode>>24 == 0xEB {
+				break
+			}
+			if inst.DataSize == 16 && inst.Mode != 16 {
+				markLastImplicit(&inst, PrefixDataSize)
+				op += "w"
+			} else if inst.Mode == 64 {
+				op += "q"
+			}
+
+		case FRSTOR, FNSAVE, FNSTENV, FLDENV:
+			// Add s suffix to indicate shortened FPU state (I guess).
+			if inst.DataSize == 16 {
+				op += "s"
+			}
+
+		case PUSH, POP:
+			if markLastImplicit(&inst, PrefixDataSize) {
+				op += byteSizeSuffix(inst.DataSize / 8)
+			} else if inst.Mode == 64 {
+				op += "q"
+			} else {
+				op += byteSizeSuffix(inst.MemBytes)
+			}
+
+		default:
+			if isFloat(inst.Op) {
+				// I can't explain any of this, but it's what libopcodes does.
+				switch inst.MemBytes {
+				default:
+					if (inst.Op == FLD || inst.Op == FSTP) && isMem(inst.Args[0]) {
+						op += "t"
+					}
+				case 4:
+					if isFloatInt(inst.Op) {
+						op += "l"
+					} else {
+						op += "s"
+					}
+				case 8:
+					if isFloatInt(inst.Op) {
+						op += "ll"
+					} else {
+						op += "l"
+					}
+				}
+				break
+			}
+
+			op += byteSizeSuffix(inst.MemBytes)
+		}
+	}
+
+	// Adjust special case opcodes.
+	switch inst.Op {
+	case 0:
+		if inst.Prefix[0] != 0 {
+			return strings.ToLower(inst.Prefix[0].String())
+		}
+
+	case INT:
+		if inst.Opcode>>24 == 0xCC {
+			inst.Args[0] = nil
+			op = "int3"
+		}
+
+	case CMPPS, CMPPD, CMPSD_XMM, CMPSS:
+		imm, ok := inst.Args[2].(Imm)
+		if ok && 0 <= imm && imm < 8 {
+			inst.Args[2] = nil
+			op = cmppsOps[imm] + op[3:]
+		}
+
+	case PCLMULQDQ:
+		imm, ok := inst.Args[2].(Imm)
+		if ok && imm&^0x11 == 0 {
+			inst.Args[2] = nil
+			op = pclmulqOps[(imm&0x10)>>3|(imm&1)]
+		}
+
+	case XLATB:
+		if markLastImplicit(&inst, PrefixAddrSize) {
+			op = "xlat" // not xlatb
+		}
+	}
+
+	// Build list of argument strings.
+	var (
+		usedPrefixes bool     // segment prefixes consumed by Mem formatting
+		args         []string // formatted arguments
+	)
+	for i, a := range inst.Args {
+		if a == nil {
+			break
+		}
+		switch inst.Op {
+		case MOVSB, MOVSW, MOVSD, MOVSQ, OUTSB, OUTSW, OUTSD:
+			if i == 0 {
+				usedPrefixes = true // disable use of prefixes for first argument
+			} else {
+				usedPrefixes = false
+			}
+		}
+		if a == Imm(1) && (inst.Opcode>>24)&^1 == 0xD0 {
+			continue
+		}
+		args = append(args, gnuArg(&inst, a, &usedPrefixes))
+	}
+
+	// The default is to print the arguments in reverse Intel order.
+	// A few instructions inhibit this behavior.
+	switch inst.Op {
+	case BOUND, LCALL, ENTER, LJMP:
+		// no reverse
+	default:
+		// reverse args
+		for i, j := 0, len(args)-1; i < j; i, j = i+1, j-1 {
+			args[i], args[j] = args[j], args[i]
+		}
+	}
+
+	// Build prefix string.
+	// Must be after argument formatting, which can turn off segment prefixes.
+	var (
+		prefix       = "" // output string
+		numAddr      = 0
+		numData      = 0
+		implicitData = false
+	)
+	for _, p := range inst.Prefix {
+		if p&0xFF == PrefixDataSize && p&PrefixImplicit != 0 {
+			implicitData = true
+		}
+	}
+	for _, p := range inst.Prefix {
+		if p == 0 {
+			break
+		}
+		if p&PrefixImplicit != 0 {
+			continue
+		}
+		switch p &^ (PrefixIgnored | PrefixInvalid) {
+		default:
+			if p.IsREX() {
+				if p&0xFF == PrefixREX {
+					prefix += "rex "
+				} else {
+					prefix += "rex." + p.String()[4:] + " "
+				}
+				break
+			}
+			prefix += strings.ToLower(p.String()) + " "
+
+		case PrefixPN:
+			op += ",pn"
+			continue
+
+		case PrefixPT:
+			op += ",pt"
+			continue
+
+		case PrefixAddrSize, PrefixAddr16, PrefixAddr32:
+			// For unknown reasons, if the addr16 prefix is repeated,
+			// libopcodes displays all but the last as addr32, even though
+			// the addressing form used in a memory reference is clearly
+			// still 16-bit.
+			n := 32
+			if inst.Mode == 32 {
+				n = 16
+			}
+			numAddr++
+			if countPrefix(&inst, PrefixAddrSize) > numAddr {
+				n = inst.Mode
+			}
+			prefix += fmt.Sprintf("addr%d ", n)
+			continue
+
+		case PrefixData16, PrefixData32:
+			if implicitData && countPrefix(&inst, PrefixDataSize) > 1 {
+				// Similar to the addr32 logic above, but it only kicks in
+				// when something used the data size prefix (one is implicit).
+				n := 16
+				if inst.Mode == 16 {
+					n = 32
+				}
+				numData++
+				if countPrefix(&inst, PrefixDataSize) > numData {
+					if inst.Mode == 16 {
+						n = 16
+					} else {
+						n = 32
+					}
+				}
+				prefix += fmt.Sprintf("data%d ", n)
+				continue
+			}
+			prefix += strings.ToLower(p.String()) + " "
+		}
+	}
+
+	// Finally! Put it all together.
+	text := prefix + op
+	if args != nil {
+		text += " "
+		// Indirect call/jmp gets a star to distinguish from direct jump address.
+		if (inst.Op == CALL || inst.Op == JMP || inst.Op == LJMP || inst.Op == LCALL) && (isMem(inst.Args[0]) || isReg(inst.Args[0])) {
+			text += "*"
+		}
+		text += strings.Join(args, ",")
+	}
+	return text
+}
+
+// gnuArg returns the GNU syntax for the argument x from the instruction inst.
+// If *usedPrefixes is false and x is a Mem, then the formatting
+// includes any segment prefixes and sets *usedPrefixes to true.
+func gnuArg(inst *Inst, x Arg, usedPrefixes *bool) string {
+	if x == nil {
+		return "<nil>"
+	}
+	switch x := x.(type) {
+	case Reg:
+		switch inst.Op {
+		case CVTSI2SS, CVTSI2SD, CVTSS2SI, CVTSD2SI, CVTTSD2SI, CVTTSS2SI:
+			if inst.DataSize == 16 && EAX <= x && x <= R15L {
+				x -= EAX - AX
+			}
+
+		case IN, INSB, INSW, INSD, OUT, OUTSB, OUTSW, OUTSD:
+			// DX is the port, but libopcodes prints it as if it were a memory reference.
+			if x == DX {
+				return "(%dx)"
+			}
+		}
+		return gccRegName[x]
+	case Mem:
+		seg := ""
+		var haveCS, haveDS, haveES, haveFS, haveGS, haveSS bool
+		switch x.Segment {
+		case CS:
+			haveCS = true
+		case DS:
+			haveDS = true
+		case ES:
+			haveES = true
+		case FS:
+			haveFS = true
+		case GS:
+			haveGS = true
+		case SS:
+			haveSS = true
+		}
+		switch inst.Op {
+		case INSB, INSW, INSD, STOSB, STOSW, STOSD, STOSQ, SCASB, SCASW, SCASD, SCASQ:
+			// These do not accept segment prefixes, at least in the GNU rendering.
+		default:
+			if *usedPrefixes {
+				break
+			}
+			for i := len(inst.Prefix) - 1; i >= 0; i-- {
+				p := inst.Prefix[i] &^ PrefixIgnored
+				if p == 0 {
+					continue
+				}
+				switch p {
+				case PrefixCS:
+					if !haveCS {
+						haveCS = true
+						inst.Prefix[i] |= PrefixImplicit
+					}
+				case PrefixDS:
+					if !haveDS {
+						haveDS = true
+						inst.Prefix[i] |= PrefixImplicit
+					}
+				case PrefixES:
+					if !haveES {
+						haveES = true
+						inst.Prefix[i] |= PrefixImplicit
+					}
+				case PrefixFS:
+					if !haveFS {
+						haveFS = true
+						inst.Prefix[i] |= PrefixImplicit
+					}
+				case PrefixGS:
+					if !haveGS {
+						haveGS = true
+						inst.Prefix[i] |= PrefixImplicit
+					}
+				case PrefixSS:
+					if !haveSS {
+						haveSS = true
+						inst.Prefix[i] |= PrefixImplicit
+					}
+				}
+			}
+			*usedPrefixes = true
+		}
+		if haveCS {
+			seg += "%cs:"
+		}
+		if haveDS {
+			seg += "%ds:"
+		}
+		if haveSS {
+			seg += "%ss:"
+		}
+		if haveES {
+			seg += "%es:"
+		}
+		if haveFS {
+			seg += "%fs:"
+		}
+		if haveGS {
+			seg += "%gs:"
+		}
+		disp := ""
+		if x.Disp != 0 {
+			disp = fmt.Sprintf("%#x", x.Disp)
+		}
+		if x.Scale == 0 || x.Index == 0 && x.Scale == 1 && (x.Base == ESP || x.Base == RSP || x.Base == 0 && inst.Mode == 64) {
+			if x.Base == 0 {
+				return seg + disp
+			}
+			return fmt.Sprintf("%s%s(%s)", seg, disp, gccRegName[x.Base])
+		}
+		base := gccRegName[x.Base]
+		if x.Base == 0 {
+			base = ""
+		}
+		index := gccRegName[x.Index]
+		if x.Index == 0 {
+			if inst.AddrSize == 64 {
+				index = "%riz"
+			} else {
+				index = "%eiz"
+			}
+		}
+		if AX <= x.Base && x.Base <= DI {
+			// 16-bit addressing - no scale
+			return fmt.Sprintf("%s%s(%s,%s)", seg, disp, base, index)
+		}
+		return fmt.Sprintf("%s%s(%s,%s,%d)", seg, disp, base, index, x.Scale)
+	case Rel:
+		return fmt.Sprintf(".%+#x", int32(x))
+	case Imm:
+		if inst.Mode == 32 {
+			return fmt.Sprintf("$%#x", uint32(x))
+		}
+		return fmt.Sprintf("$%#x", int64(x))
+	}
+	return x.String()
+}
+
+var gccRegName = [...]string{
+	0:    "REG0",
+	AL:   "%al",
+	CL:   "%cl",
+	BL:   "%bl",
+	DL:   "%dl",
+	AH:   "%ah",
+	CH:   "%ch",
+	BH:   "%bh",
+	DH:   "%dh",
+	SPB:  "%spl",
+	BPB:  "%bpl",
+	SIB:  "%sil",
+	DIB:  "%dil",
+	R8B:  "%r8b",
+	R9B:  "%r9b",
+	R10B: "%r10b",
+	R11B: "%r11b",
+	R12B: "%r12b",
+	R13B: "%r13b",
+	R14B: "%r14b",
+	R15B: "%r15b",
+	AX:   "%ax",
+	CX:   "%cx",
+	BX:   "%bx",
+	DX:   "%dx",
+	SP:   "%sp",
+	BP:   "%bp",
+	SI:   "%si",
+	DI:   "%di",
+	R8W:  "%r8w",
+	R9W:  "%r9w",
+	R10W: "%r10w",
+	R11W: "%r11w",
+	R12W: "%r12w",
+	R13W: "%r13w",
+	R14W: "%r14w",
+	R15W: "%r15w",
+	EAX:  "%eax",
+	ECX:  "%ecx",
+	EDX:  "%edx",
+	EBX:  "%ebx",
+	ESP:  "%esp",
+	EBP:  "%ebp",
+	ESI:  "%esi",
+	EDI:  "%edi",
+	R8L:  "%r8d",
+	R9L:  "%r9d",
+	R10L: "%r10d",
+	R11L: "%r11d",
+	R12L: "%r12d",
+	R13L: "%r13d",
+	R14L: "%r14d",
+	R15L: "%r15d",
+	RAX:  "%rax",
+	RCX:  "%rcx",
+	RDX:  "%rdx",
+	RBX:  "%rbx",
+	RSP:  "%rsp",
+	RBP:  "%rbp",
+	RSI:  "%rsi",
+	RDI:  "%rdi",
+	R8:   "%r8",
+	R9:   "%r9",
+	R10:  "%r10",
+	R11:  "%r11",
+	R12:  "%r12",
+	R13:  "%r13",
+	R14:  "%r14",
+	R15:  "%r15",
+	IP:   "%ip",
+	EIP:  "%eip",
+	RIP:  "%rip",
+	F0:   "%st",
+	F1:   "%st(1)",
+	F2:   "%st(2)",
+	F3:   "%st(3)",
+	F4:   "%st(4)",
+	F5:   "%st(5)",
+	F6:   "%st(6)",
+	F7:   "%st(7)",
+	M0:   "%mm0",
+	M1:   "%mm1",
+	M2:   "%mm2",
+	M3:   "%mm3",
+	M4:   "%mm4",
+	M5:   "%mm5",
+	M6:   "%mm6",
+	M7:   "%mm7",
+	X0:   "%xmm0",
+	X1:   "%xmm1",
+	X2:   "%xmm2",
+	X3:   "%xmm3",
+	X4:   "%xmm4",
+	X5:   "%xmm5",
+	X6:   "%xmm6",
+	X7:   "%xmm7",
+	X8:   "%xmm8",
+	X9:   "%xmm9",
+	X10:  "%xmm10",
+	X11:  "%xmm11",
+	X12:  "%xmm12",
+	X13:  "%xmm13",
+	X14:  "%xmm14",
+	X15:  "%xmm15",
+	CS:   "%cs",
+	SS:   "%ss",
+	DS:   "%ds",
+	ES:   "%es",
+	FS:   "%fs",
+	GS:   "%gs",
+	GDTR: "%gdtr",
+	IDTR: "%idtr",
+	LDTR: "%ldtr",
+	MSW:  "%msw",
+	TASK: "%task",
+	CR0:  "%cr0",
+	CR1:  "%cr1",
+	CR2:  "%cr2",
+	CR3:  "%cr3",
+	CR4:  "%cr4",
+	CR5:  "%cr5",
+	CR6:  "%cr6",
+	CR7:  "%cr7",
+	CR8:  "%cr8",
+	CR9:  "%cr9",
+	CR10: "%cr10",
+	CR11: "%cr11",
+	CR12: "%cr12",
+	CR13: "%cr13",
+	CR14: "%cr14",
+	CR15: "%cr15",
+	DR0:  "%db0",
+	DR1:  "%db1",
+	DR2:  "%db2",
+	DR3:  "%db3",
+	DR4:  "%db4",
+	DR5:  "%db5",
+	DR6:  "%db6",
+	DR7:  "%db7",
+	TR0:  "%tr0",
+	TR1:  "%tr1",
+	TR2:  "%tr2",
+	TR3:  "%tr3",
+	TR4:  "%tr4",
+	TR5:  "%tr5",
+	TR6:  "%tr6",
+	TR7:  "%tr7",
+}
+
+var gnuOp = map[Op]string{
+	CBW:       "cbtw",
+	CDQ:       "cltd",
+	CMPSD:     "cmpsl",
+	CMPSD_XMM: "cmpsd",
+	CWD:       "cwtd",
+	CWDE:      "cwtl",
+	CQO:       "cqto",
+	INSD:      "insl",
+	IRET:      "iretw",
+	IRETD:     "iret",
+	IRETQ:     "iretq",
+	LODSB:     "lods",
+	LODSD:     "lods",
+	LODSQ:     "lods",
+	LODSW:     "lods",
+	MOVSD:     "movsl",
+	MOVSD_XMM: "movsd",
+	OUTSD:     "outsl",
+	POPA:      "popaw",
+	POPAD:     "popa",
+	POPF:      "popfw",
+	POPFD:     "popf",
+	PUSHA:     "pushaw",
+	PUSHAD:    "pusha",
+	PUSHF:     "pushfw",
+	PUSHFD:    "pushf",
+	SCASB:     "scas",
+	SCASD:     "scas",
+	SCASQ:     "scas",
+	SCASW:     "scas",
+	STOSB:     "stos",
+	STOSD:     "stos",
+	STOSQ:     "stos",
+	STOSW:     "stos",
+	XLATB:     "xlat",
+}
+
+var cmppsOps = []string{
+	"cmpeq",
+	"cmplt",
+	"cmple",
+	"cmpunord",
+	"cmpneq",
+	"cmpnlt",
+	"cmpnle",
+	"cmpord",
+}
+
+var pclmulqOps = []string{
+	"pclmullqlqdq",
+	"pclmulhqlqdq",
+	"pclmullqhqdq",
+	"pclmulhqhqdq",
+}
+
+func countPrefix(inst *Inst, target Prefix) int {
+	n := 0
+	for _, p := range inst.Prefix {
+		if p&0xFF == target&0xFF {
+			n++
+		}
+	}
+	return n
+}
+
+func markLastImplicit(inst *Inst, prefix Prefix) bool {
+	for i := len(inst.Prefix) - 1; i >= 0; i-- {
+		p := inst.Prefix[i]
+		if p&0xFF == prefix {
+			inst.Prefix[i] |= PrefixImplicit
+			return true
+		}
+	}
+	return false
+}
+
+func unmarkImplicit(inst *Inst, prefix Prefix) {
+	for i := len(inst.Prefix) - 1; i >= 0; i-- {
+		p := inst.Prefix[i]
+		if p&0xFF == prefix {
+			inst.Prefix[i] &^= PrefixImplicit
+		}
+	}
+}
+
+func byteSizeSuffix(b int) string {
+	switch b {
+	case 1:
+		return "b"
+	case 2:
+		return "w"
+	case 4:
+		return "l"
+	case 8:
+		return "q"
+	}
+	return ""
+}
+
+func argBytes(inst *Inst, arg Arg) int {
+	if isMem(arg) {
+		return inst.MemBytes
+	}
+	return regBytes(arg)
+}
+
+func isFloat(op Op) bool {
+	switch op {
+	case FADD, FCOM, FCOMP, FDIV, FDIVR, FIADD, FICOM, FICOMP, FIDIV, FIDIVR, FILD, FIMUL, FIST, FISTP, FISTTP, FISUB, FISUBR, FLD, FMUL, FST, FSTP, FSUB, FSUBR:
+		return true
+	}
+	return false
+}
+
+func isFloatInt(op Op) bool {
+	switch op {
+	case FIADD, FICOM, FICOMP, FIDIV, FIDIVR, FILD, FIMUL, FIST, FISTP, FISTTP, FISUB, FISUBR:
+		return true
+	}
+	return false
+}
diff --git a/src/cmd/internal/rsc.io/x86/x86asm/inst.go b/src/cmd/internal/rsc.io/x86/x86asm/inst.go
new file mode 100644
index 0000000..d4c1b6c
--- /dev/null
+++ b/src/cmd/internal/rsc.io/x86/x86asm/inst.go
@@ -0,0 +1,641 @@
+// 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 x86asm implements decoding of x86 machine code.
+package x86asm
+
+import (
+	"bytes"
+	"fmt"
+)
+
+// An Inst is a single instruction.
+type Inst struct {
+	Prefix   Prefixes // Prefixes applied to the instruction.
+	Op       Op       // Opcode mnemonic
+	Opcode   uint32   // Encoded opcode bits, left aligned (first byte is Opcode>>24, etc)
+	Args     Args     // Instruction arguments, in Intel order
+	Mode     int      // processor mode in bits: 16, 32, or 64
+	AddrSize int      // address size in bits: 16, 32, or 64
+	DataSize int      // operand size in bits: 16, 32, or 64
+	MemBytes int      // size of memory argument in bytes: 1, 2, 4, 8, 16, and so on.
+	Len      int      // length of encoded instruction in bytes
+}
+
+// Prefixes is an array of prefixes associated with a single instruction.
+// The prefixes are listed in the same order as found in the instruction:
+// each prefix byte corresponds to one slot in the array. The first zero
+// in the array marks the end of the prefixes.
+type Prefixes [14]Prefix
+
+// A Prefix represents an Intel instruction prefix.
+// The low 8 bits are the actual prefix byte encoding,
+// and the top 8 bits contain distinguishing bits and metadata.
+type Prefix uint16
+
+const (
+	// Metadata about the role of a prefix in an instruction.
+	PrefixImplicit Prefix = 0x8000 // prefix is implied by instruction text
+	PrefixIgnored  Prefix = 0x4000 // prefix is ignored: either irrelevant or overridden by a later prefix
+	PrefixInvalid  Prefix = 0x2000 // prefix makes entire instruction invalid (bad LOCK)
+
+	// Memory segment overrides.
+	PrefixES Prefix = 0x26 // ES segment override
+	PrefixCS Prefix = 0x2E // CS segment override
+	PrefixSS Prefix = 0x36 // SS segment override
+	PrefixDS Prefix = 0x3E // DS segment override
+	PrefixFS Prefix = 0x64 // FS segment override
+	PrefixGS Prefix = 0x65 // GS segment override
+
+	// Branch prediction.
+	PrefixPN Prefix = 0x12E // predict not taken (conditional branch only)
+	PrefixPT Prefix = 0x13E // predict taken (conditional branch only)
+
+	// Size attributes.
+	PrefixDataSize Prefix = 0x66 // operand size override
+	PrefixData16   Prefix = 0x166
+	PrefixData32   Prefix = 0x266
+	PrefixAddrSize Prefix = 0x67 // address size override
+	PrefixAddr16   Prefix = 0x167
+	PrefixAddr32   Prefix = 0x267
+
+	// One of a kind.
+	PrefixLOCK     Prefix = 0xF0 // lock
+	PrefixREPN     Prefix = 0xF2 // repeat not zero
+	PrefixXACQUIRE Prefix = 0x1F2
+	PrefixBND      Prefix = 0x2F2
+	PrefixREP      Prefix = 0xF3 // repeat
+	PrefixXRELEASE Prefix = 0x1F3
+
+	// The REX prefixes must be in the range [PrefixREX, PrefixREX+0x10).
+	// the other bits are set or not according to the intended use.
+	PrefixREX  Prefix = 0x40 // REX 64-bit extension prefix
+	PrefixREXW Prefix = 0x08 // extension bit W (64-bit instruction width)
+	PrefixREXR Prefix = 0x04 // extension bit R (r field in modrm)
+	PrefixREXX Prefix = 0x02 // extension bit X (index field in sib)
+	PrefixREXB Prefix = 0x01 // extension bit B (r/m field in modrm or base field in sib)
+)
+
+// IsREX reports whether p is a REX prefix byte.
+func (p Prefix) IsREX() bool {
+	return p&0xF0 == PrefixREX
+}
+
+func (p Prefix) String() string {
+	p &^= PrefixImplicit | PrefixIgnored | PrefixInvalid
+	if s := prefixNames[p]; s != "" {
+		return s
+	}
+
+	if p.IsREX() {
+		s := "REX."
+		if p&PrefixREXW != 0 {
+			s += "W"
+		}
+		if p&PrefixREXR != 0 {
+			s += "R"
+		}
+		if p&PrefixREXX != 0 {
+			s += "X"
+		}
+		if p&PrefixREXB != 0 {
+			s += "B"
+		}
+		return s
+	}
+
+	return fmt.Sprintf("Prefix(%#x)", int(p))
+}
+
+// An Op is an x86 opcode.
+type Op uint32
+
+func (op Op) String() string {
+	i := int(op)
+	if i < 0 || i >= len(opNames) || opNames[i] == "" {
+		return fmt.Sprintf("Op(%d)", i)
+	}
+	return opNames[i]
+}
+
+// An Args holds the instruction arguments.
+// If an instruction has fewer than 4 arguments,
+// the final elements in the array are nil.
+type Args [4]Arg
+
+// An Arg is a single instruction argument,
+// one of these types: Reg, Mem, Imm, Rel.
+type Arg interface {
+	String() string
+	isArg()
+}
+
+// Note that the implements of Arg that follow are all sized
+// so that on a 64-bit machine the data can be inlined in
+// the interface value instead of requiring an allocation.
+
+// A Reg is a single register.
+// The zero Reg value has no name but indicates ``no register.''
+type Reg uint8
+
+const (
+	_ Reg = iota
+
+	// 8-bit
+	AL
+	CL
+	DL
+	BL
+	AH
+	CH
+	DH
+	BH
+	SPB
+	BPB
+	SIB
+	DIB
+	R8B
+	R9B
+	R10B
+	R11B
+	R12B
+	R13B
+	R14B
+	R15B
+
+	// 16-bit
+	AX
+	CX
+	DX
+	BX
+	SP
+	BP
+	SI
+	DI
+	R8W
+	R9W
+	R10W
+	R11W
+	R12W
+	R13W
+	R14W
+	R15W
+
+	// 32-bit
+	EAX
+	ECX
+	EDX
+	EBX
+	ESP
+	EBP
+	ESI
+	EDI
+	R8L
+	R9L
+	R10L
+	R11L
+	R12L
+	R13L
+	R14L
+	R15L
+
+	// 64-bit
+	RAX
+	RCX
+	RDX
+	RBX
+	RSP
+	RBP
+	RSI
+	RDI
+	R8
+	R9
+	R10
+	R11
+	R12
+	R13
+	R14
+	R15
+
+	// Instruction pointer.
+	IP  // 16-bit
+	EIP // 32-bit
+	RIP // 64-bit
+
+	// 387 floating point registers.
+	F0
+	F1
+	F2
+	F3
+	F4
+	F5
+	F6
+	F7
+
+	// MMX registers.
+	M0
+	M1
+	M2
+	M3
+	M4
+	M5
+	M6
+	M7
+
+	// XMM registers.
+	X0
+	X1
+	X2
+	X3
+	X4
+	X5
+	X6
+	X7
+	X8
+	X9
+	X10
+	X11
+	X12
+	X13
+	X14
+	X15
+
+	// Segment registers.
+	ES
+	CS
+	SS
+	DS
+	FS
+	GS
+
+	// System registers.
+	GDTR
+	IDTR
+	LDTR
+	MSW
+	TASK
+
+	// Control registers.
+	CR0
+	CR1
+	CR2
+	CR3
+	CR4
+	CR5
+	CR6
+	CR7
+	CR8
+	CR9
+	CR10
+	CR11
+	CR12
+	CR13
+	CR14
+	CR15
+
+	// Debug registers.
+	DR0
+	DR1
+	DR2
+	DR3
+	DR4
+	DR5
+	DR6
+	DR7
+	DR8
+	DR9
+	DR10
+	DR11
+	DR12
+	DR13
+	DR14
+	DR15
+
+	// Task registers.
+	TR0
+	TR1
+	TR2
+	TR3
+	TR4
+	TR5
+	TR6
+	TR7
+)
+
+const regMax = TR7
+
+func (Reg) isArg() {}
+
+func (r Reg) String() string {
+	i := int(r)
+	if i < 0 || i >= len(regNames) || regNames[i] == "" {
+		return fmt.Sprintf("Reg(%d)", i)
+	}
+	return regNames[i]
+}
+
+// A Mem is a memory reference.
+// The general form is Segment:[Base+Scale*Index+Disp].
+type Mem struct {
+	Segment Reg
+	Base    Reg
+	Scale   uint8
+	Index   Reg
+	Disp    int64
+}
+
+func (Mem) isArg() {}
+
+func (m Mem) String() string {
+	var base, plus, scale, index, disp string
+
+	if m.Base != 0 {
+		base = m.Base.String()
+	}
+	if m.Scale != 0 {
+		if m.Base != 0 {
+			plus = "+"
+		}
+		if m.Scale > 1 {
+			scale = fmt.Sprintf("%d*", m.Scale)
+		}
+		index = m.Index.String()
+	}
+	if m.Disp != 0 || m.Base == 0 && m.Scale == 0 {
+		disp = fmt.Sprintf("%+#x", m.Disp)
+	}
+	return "[" + base + plus + scale + index + disp + "]"
+}
+
+// A Rel is an offset relative to the current instruction pointer.
+type Rel int32
+
+func (Rel) isArg() {}
+
+func (r Rel) String() string {
+	return fmt.Sprintf(".%+d", r)
+}
+
+// An Imm is an integer constant.
+type Imm int64
+
+func (Imm) isArg() {}
+
+func (i Imm) String() string {
+	return fmt.Sprintf("%#x", int64(i))
+}
+
+func (i Inst) String() string {
+	var buf bytes.Buffer
+	for _, p := range i.Prefix {
+		if p == 0 {
+			break
+		}
+		if p&PrefixImplicit != 0 {
+			continue
+		}
+		fmt.Fprintf(&buf, "%v ", p)
+	}
+	fmt.Fprintf(&buf, "%v", i.Op)
+	sep := " "
+	for _, v := range i.Args {
+		if v == nil {
+			break
+		}
+		fmt.Fprintf(&buf, "%s%v", sep, v)
+		sep = ", "
+	}
+	return buf.String()
+}
+
+func isReg(a Arg) bool {
+	_, ok := a.(Reg)
+	return ok
+}
+
+func isSegReg(a Arg) bool {
+	r, ok := a.(Reg)
+	return ok && ES <= r && r <= GS
+}
+
+func isMem(a Arg) bool {
+	_, ok := a.(Mem)
+	return ok
+}
+
+func isImm(a Arg) bool {
+	_, ok := a.(Imm)
+	return ok
+}
+
+func regBytes(a Arg) int {
+	r, ok := a.(Reg)
+	if !ok {
+		return 0
+	}
+	if AL <= r && r <= R15B {
+		return 1
+	}
+	if AX <= r && r <= R15W {
+		return 2
+	}
+	if EAX <= r && r <= R15L {
+		return 4
+	}
+	if RAX <= r && r <= R15 {
+		return 8
+	}
+	return 0
+}
+
+func isSegment(p Prefix) bool {
+	switch p {
+	case PrefixCS, PrefixDS, PrefixES, PrefixFS, PrefixGS, PrefixSS:
+		return true
+	}
+	return false
+}
+
+// The Op definitions and string list are in tables.go.
+
+var prefixNames = map[Prefix]string{
+	PrefixCS:       "CS",
+	PrefixDS:       "DS",
+	PrefixES:       "ES",
+	PrefixFS:       "FS",
+	PrefixGS:       "GS",
+	PrefixSS:       "SS",
+	PrefixLOCK:     "LOCK",
+	PrefixREP:      "REP",
+	PrefixREPN:     "REPN",
+	PrefixAddrSize: "ADDRSIZE",
+	PrefixDataSize: "DATASIZE",
+	PrefixAddr16:   "ADDR16",
+	PrefixData16:   "DATA16",
+	PrefixAddr32:   "ADDR32",
+	PrefixData32:   "DATA32",
+	PrefixBND:      "BND",
+	PrefixXACQUIRE: "XACQUIRE",
+	PrefixXRELEASE: "XRELEASE",
+	PrefixREX:      "REX",
+	PrefixPT:       "PT",
+	PrefixPN:       "PN",
+}
+
+var regNames = [...]string{
+	AL:   "AL",
+	CL:   "CL",
+	BL:   "BL",
+	DL:   "DL",
+	AH:   "AH",
+	CH:   "CH",
+	BH:   "BH",
+	DH:   "DH",
+	SPB:  "SPB",
+	BPB:  "BPB",
+	SIB:  "SIB",
+	DIB:  "DIB",
+	R8B:  "R8B",
+	R9B:  "R9B",
+	R10B: "R10B",
+	R11B: "R11B",
+	R12B: "R12B",
+	R13B: "R13B",
+	R14B: "R14B",
+	R15B: "R15B",
+	AX:   "AX",
+	CX:   "CX",
+	BX:   "BX",
+	DX:   "DX",
+	SP:   "SP",
+	BP:   "BP",
+	SI:   "SI",
+	DI:   "DI",
+	R8W:  "R8W",
+	R9W:  "R9W",
+	R10W: "R10W",
+	R11W: "R11W",
+	R12W: "R12W",
+	R13W: "R13W",
+	R14W: "R14W",
+	R15W: "R15W",
+	EAX:  "EAX",
+	ECX:  "ECX",
+	EDX:  "EDX",
+	EBX:  "EBX",
+	ESP:  "ESP",
+	EBP:  "EBP",
+	ESI:  "ESI",
+	EDI:  "EDI",
+	R8L:  "R8L",
+	R9L:  "R9L",
+	R10L: "R10L",
+	R11L: "R11L",
+	R12L: "R12L",
+	R13L: "R13L",
+	R14L: "R14L",
+	R15L: "R15L",
+	RAX:  "RAX",
+	RCX:  "RCX",
+	RDX:  "RDX",
+	RBX:  "RBX",
+	RSP:  "RSP",
+	RBP:  "RBP",
+	RSI:  "RSI",
+	RDI:  "RDI",
+	R8:   "R8",
+	R9:   "R9",
+	R10:  "R10",
+	R11:  "R11",
+	R12:  "R12",
+	R13:  "R13",
+	R14:  "R14",
+	R15:  "R15",
+	IP:   "IP",
+	EIP:  "EIP",
+	RIP:  "RIP",
+	F0:   "F0",
+	F1:   "F1",
+	F2:   "F2",
+	F3:   "F3",
+	F4:   "F4",
+	F5:   "F5",
+	F6:   "F6",
+	F7:   "F7",
+	M0:   "M0",
+	M1:   "M1",
+	M2:   "M2",
+	M3:   "M3",
+	M4:   "M4",
+	M5:   "M5",
+	M6:   "M6",
+	M7:   "M7",
+	X0:   "X0",
+	X1:   "X1",
+	X2:   "X2",
+	X3:   "X3",
+	X4:   "X4",
+	X5:   "X5",
+	X6:   "X6",
+	X7:   "X7",
+	X8:   "X8",
+	X9:   "X9",
+	X10:  "X10",
+	X11:  "X11",
+	X12:  "X12",
+	X13:  "X13",
+	X14:  "X14",
+	X15:  "X15",
+	CS:   "CS",
+	SS:   "SS",
+	DS:   "DS",
+	ES:   "ES",
+	FS:   "FS",
+	GS:   "GS",
+	GDTR: "GDTR",
+	IDTR: "IDTR",
+	LDTR: "LDTR",
+	MSW:  "MSW",
+	TASK: "TASK",
+	CR0:  "CR0",
+	CR1:  "CR1",
+	CR2:  "CR2",
+	CR3:  "CR3",
+	CR4:  "CR4",
+	CR5:  "CR5",
+	CR6:  "CR6",
+	CR7:  "CR7",
+	CR8:  "CR8",
+	CR9:  "CR9",
+	CR10: "CR10",
+	CR11: "CR11",
+	CR12: "CR12",
+	CR13: "CR13",
+	CR14: "CR14",
+	CR15: "CR15",
+	DR0:  "DR0",
+	DR1:  "DR1",
+	DR2:  "DR2",
+	DR3:  "DR3",
+	DR4:  "DR4",
+	DR5:  "DR5",
+	DR6:  "DR6",
+	DR7:  "DR7",
+	DR8:  "DR8",
+	DR9:  "DR9",
+	DR10: "DR10",
+	DR11: "DR11",
+	DR12: "DR12",
+	DR13: "DR13",
+	DR14: "DR14",
+	DR15: "DR15",
+	TR0:  "TR0",
+	TR1:  "TR1",
+	TR2:  "TR2",
+	TR3:  "TR3",
+	TR4:  "TR4",
+	TR5:  "TR5",
+	TR6:  "TR6",
+	TR7:  "TR7",
+}
diff --git a/src/cmd/internal/rsc.io/x86/x86asm/inst_test.go b/src/cmd/internal/rsc.io/x86/x86asm/inst_test.go
new file mode 100644
index 0000000..23ac523
--- /dev/null
+++ b/src/cmd/internal/rsc.io/x86/x86asm/inst_test.go
@@ -0,0 +1,20 @@
+// 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 x86asm
+
+import (
+	"strings"
+	"testing"
+)
+
+func TestRegString(t *testing.T) {
+	for r := Reg(1); r <= regMax; r++ {
+		if regNames[r] == "" {
+			t.Errorf("regNames[%d] is missing", int(r))
+		} else if s := r.String(); strings.Contains(s, "Reg(") {
+			t.Errorf("Reg(%d).String() = %s, want proper name", int(r), s)
+		}
+	}
+}
diff --git a/src/cmd/internal/rsc.io/x86/x86asm/intel.go b/src/cmd/internal/rsc.io/x86/x86asm/intel.go
new file mode 100644
index 0000000..90af9dd
--- /dev/null
+++ b/src/cmd/internal/rsc.io/x86/x86asm/intel.go
@@ -0,0 +1,518 @@
+// 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 x86asm
+
+import (
+	"fmt"
+	"strings"
+)
+
+// IntelSyntax returns the Intel assembler syntax for the instruction, as defined by Intel's XED tool.
+func IntelSyntax(inst Inst) string {
+	var iargs []Arg
+	for _, a := range inst.Args {
+		if a == nil {
+			break
+		}
+		iargs = append(iargs, a)
+	}
+
+	switch inst.Op {
+	case INSB, INSD, INSW, OUTSB, OUTSD, OUTSW, LOOPNE, JCXZ, JECXZ, JRCXZ, LOOP, LOOPE, MOV, XLATB:
+		if inst.Op == MOV && (inst.Opcode>>16)&0xFFFC != 0x0F20 {
+			break
+		}
+		for i, p := range inst.Prefix {
+			if p&0xFF == PrefixAddrSize {
+				inst.Prefix[i] &^= PrefixImplicit
+			}
+		}
+	}
+
+	switch inst.Op {
+	case MOV:
+		dst, _ := inst.Args[0].(Reg)
+		src, _ := inst.Args[1].(Reg)
+		if ES <= dst && dst <= GS && EAX <= src && src <= R15L {
+			src -= EAX - AX
+			iargs[1] = src
+		}
+		if ES <= dst && dst <= GS && RAX <= src && src <= R15 {
+			src -= RAX - AX
+			iargs[1] = src
+		}
+
+		if inst.Opcode>>24&^3 == 0xA0 {
+			for i, p := range inst.Prefix {
+				if p&0xFF == PrefixAddrSize {
+					inst.Prefix[i] |= PrefixImplicit
+				}
+			}
+		}
+	}
+
+	switch inst.Op {
+	case AAM, AAD:
+		if imm, ok := iargs[0].(Imm); ok {
+			if inst.DataSize == 32 {
+				iargs[0] = Imm(uint32(int8(imm)))
+			} else if inst.DataSize == 16 {
+				iargs[0] = Imm(uint16(int8(imm)))
+			}
+		}
+
+	case PUSH:
+		if imm, ok := iargs[0].(Imm); ok {
+			iargs[0] = Imm(uint32(imm))
+		}
+	}
+
+	for _, p := range inst.Prefix {
+		if p&PrefixImplicit != 0 {
+			for j, pj := range inst.Prefix {
+				if pj&0xFF == p&0xFF {
+					inst.Prefix[j] |= PrefixImplicit
+				}
+			}
+		}
+	}
+
+	if inst.Op != 0 {
+		for i, p := range inst.Prefix {
+			switch p &^ PrefixIgnored {
+			case PrefixData16, PrefixData32, PrefixCS, PrefixDS, PrefixES, PrefixSS:
+				inst.Prefix[i] |= PrefixImplicit
+			}
+			if p.IsREX() {
+				inst.Prefix[i] |= PrefixImplicit
+			}
+		}
+	}
+
+	if isLoop[inst.Op] || inst.Op == JCXZ || inst.Op == JECXZ || inst.Op == JRCXZ {
+		for i, p := range inst.Prefix {
+			if p == PrefixPT || p == PrefixPN {
+				inst.Prefix[i] |= PrefixImplicit
+			}
+		}
+	}
+
+	switch inst.Op {
+	case AAA, AAS, CBW, CDQE, CLC, CLD, CLI, CLTS, CMC, CPUID, CQO, CWD, DAA, DAS,
+		FDECSTP, FINCSTP, FNCLEX, FNINIT, FNOP, FWAIT, HLT,
+		ICEBP, INSB, INSD, INSW, INT, INTO, INVD, IRET, IRETQ,
+		LAHF, LEAVE, LRET, MONITOR, MWAIT, NOP, OUTSB, OUTSD, OUTSW,
+		PAUSE, POPA, POPF, POPFQ, PUSHA, PUSHF, PUSHFQ,
+		RDMSR, RDPMC, RDTSC, RDTSCP, RET, RSM,
+		SAHF, STC, STD, STI, SYSENTER, SYSEXIT, SYSRET,
+		UD2, WBINVD, WRMSR, XEND, XLATB, XTEST:
+
+		if inst.Op == NOP && inst.Opcode>>24 != 0x90 {
+			break
+		}
+		if inst.Op == RET && inst.Opcode>>24 != 0xC3 {
+			break
+		}
+		if inst.Op == INT && inst.Opcode>>24 != 0xCC {
+			break
+		}
+		if inst.Op == LRET && inst.Opcode>>24 != 0xcb {
+			break
+		}
+		for i, p := range inst.Prefix {
+			if p&0xFF == PrefixDataSize {
+				inst.Prefix[i] &^= PrefixImplicit | PrefixIgnored
+			}
+		}
+
+	case 0:
+		// ok
+	}
+
+	switch inst.Op {
+	case INSB, INSD, INSW, OUTSB, OUTSD, OUTSW, MONITOR, MWAIT, XLATB:
+		iargs = nil
+
+	case STOSB, STOSW, STOSD, STOSQ:
+		iargs = iargs[:1]
+
+	case LODSB, LODSW, LODSD, LODSQ, SCASB, SCASW, SCASD, SCASQ:
+		iargs = iargs[1:]
+	}
+
+	const (
+		haveData16 = 1 << iota
+		haveData32
+		haveAddr16
+		haveAddr32
+		haveXacquire
+		haveXrelease
+		haveLock
+		haveHintTaken
+		haveHintNotTaken
+		haveBnd
+	)
+	var prefixBits uint32
+	prefix := ""
+	for _, p := range inst.Prefix {
+		if p == 0 {
+			break
+		}
+		if p&0xFF == 0xF3 {
+			prefixBits &^= haveBnd
+		}
+		if p&(PrefixImplicit|PrefixIgnored) != 0 {
+			continue
+		}
+		switch p {
+		default:
+			prefix += strings.ToLower(p.String()) + " "
+		case PrefixCS, PrefixDS, PrefixES, PrefixFS, PrefixGS, PrefixSS:
+			if inst.Op == 0 {
+				prefix += strings.ToLower(p.String()) + " "
+			}
+		case PrefixREPN:
+			prefix += "repne "
+		case PrefixLOCK:
+			prefixBits |= haveLock
+		case PrefixData16, PrefixDataSize:
+			prefixBits |= haveData16
+		case PrefixData32:
+			prefixBits |= haveData32
+		case PrefixAddrSize, PrefixAddr16:
+			prefixBits |= haveAddr16
+		case PrefixAddr32:
+			prefixBits |= haveAddr32
+		case PrefixXACQUIRE:
+			prefixBits |= haveXacquire
+		case PrefixXRELEASE:
+			prefixBits |= haveXrelease
+		case PrefixPT:
+			prefixBits |= haveHintTaken
+		case PrefixPN:
+			prefixBits |= haveHintNotTaken
+		case PrefixBND:
+			prefixBits |= haveBnd
+		}
+	}
+	switch inst.Op {
+	case JMP:
+		if inst.Opcode>>24 == 0xEB {
+			prefixBits &^= haveBnd
+		}
+	case RET, LRET:
+		prefixBits &^= haveData16 | haveData32
+	}
+
+	if prefixBits&haveXacquire != 0 {
+		prefix += "xacquire "
+	}
+	if prefixBits&haveXrelease != 0 {
+		prefix += "xrelease "
+	}
+	if prefixBits&haveLock != 0 {
+		prefix += "lock "
+	}
+	if prefixBits&haveBnd != 0 {
+		prefix += "bnd "
+	}
+	if prefixBits&haveHintTaken != 0 {
+		prefix += "hint-taken "
+	}
+	if prefixBits&haveHintNotTaken != 0 {
+		prefix += "hint-not-taken "
+	}
+	if prefixBits&haveAddr16 != 0 {
+		prefix += "addr16 "
+	}
+	if prefixBits&haveAddr32 != 0 {
+		prefix += "addr32 "
+	}
+	if prefixBits&haveData16 != 0 {
+		prefix += "data16 "
+	}
+	if prefixBits&haveData32 != 0 {
+		prefix += "data32 "
+	}
+
+	if inst.Op == 0 {
+		if prefix == "" {
+			return "<no instruction>"
+		}
+		return prefix[:len(prefix)-1]
+	}
+
+	var args []string
+	for _, a := range iargs {
+		if a == nil {
+			break
+		}
+		args = append(args, intelArg(&inst, a))
+	}
+
+	var op string
+	switch inst.Op {
+	case NOP:
+		if inst.Opcode>>24 == 0x0F {
+			if inst.DataSize == 16 {
+				args = append(args, "ax")
+			} else {
+				args = append(args, "eax")
+			}
+		}
+
+	case BLENDVPD, BLENDVPS, PBLENDVB:
+		args = args[:2]
+
+	case INT:
+		if inst.Opcode>>24 == 0xCC {
+			args = nil
+			op = "int3"
+		}
+
+	case LCALL, LJMP:
+		if len(args) == 2 {
+			args[0], args[1] = args[1], args[0]
+		}
+
+	case FCHS, FABS, FTST, FLDPI, FLDL2E, FLDLG2, F2XM1, FXAM, FLD1, FLDL2T, FSQRT, FRNDINT, FCOS, FSIN:
+		if len(args) == 0 {
+			args = append(args, "st0")
+		}
+
+	case FPTAN, FSINCOS, FUCOMPP, FCOMPP, FYL2X, FPATAN, FXTRACT, FPREM1, FPREM, FYL2XP1, FSCALE:
+		if len(args) == 0 {
+			args = []string{"st0", "st1"}
+		}
+
+	case FST, FSTP, FISTTP, FIST, FISTP, FBSTP:
+		if len(args) == 1 {
+			args = append(args, "st0")
+		}
+
+	case FLD, FXCH, FCOM, FCOMP, FIADD, FIMUL, FICOM, FICOMP, FISUBR, FIDIV, FUCOM, FUCOMP, FILD, FBLD, FADD, FMUL, FSUB, FSUBR, FISUB, FDIV, FDIVR, FIDIVR:
+		if len(args) == 1 {
+			args = []string{"st0", args[0]}
+		}
+
+	case MASKMOVDQU, MASKMOVQ, XLATB, OUTSB, OUTSW, OUTSD:
+	FixSegment:
+		for i := len(inst.Prefix) - 1; i >= 0; i-- {
+			p := inst.Prefix[i] & 0xFF
+			switch p {
+			case PrefixCS, PrefixES, PrefixFS, PrefixGS, PrefixSS:
+				if inst.Mode != 64 || p == PrefixFS || p == PrefixGS {
+					args = append(args, strings.ToLower((inst.Prefix[i] & 0xFF).String()))
+					break FixSegment
+				}
+			case PrefixDS:
+				if inst.Mode != 64 {
+					break FixSegment
+				}
+			}
+		}
+	}
+
+	if op == "" {
+		op = intelOp[inst.Op]
+	}
+	if op == "" {
+		op = strings.ToLower(inst.Op.String())
+	}
+	if args != nil {
+		op += " " + strings.Join(args, ", ")
+	}
+	return prefix + op
+}
+
+func intelArg(inst *Inst, arg Arg) string {
+	switch a := arg.(type) {
+	case Imm:
+		if inst.Mode == 32 {
+			return fmt.Sprintf("%#x", uint32(a))
+		}
+		if Imm(int32(a)) == a {
+			return fmt.Sprintf("%#x", int64(a))
+		}
+		return fmt.Sprintf("%#x", uint64(a))
+	case Mem:
+		if a.Base == EIP {
+			a.Base = RIP
+		}
+		prefix := ""
+		switch inst.MemBytes {
+		case 1:
+			prefix = "byte "
+		case 2:
+			prefix = "word "
+		case 4:
+			prefix = "dword "
+		case 8:
+			prefix = "qword "
+		case 16:
+			prefix = "xmmword "
+		}
+		switch inst.Op {
+		case INVLPG:
+			prefix = "byte "
+		case STOSB, MOVSB, CMPSB, LODSB, SCASB:
+			prefix = "byte "
+		case STOSW, MOVSW, CMPSW, LODSW, SCASW:
+			prefix = "word "
+		case STOSD, MOVSD, CMPSD, LODSD, SCASD:
+			prefix = "dword "
+		case STOSQ, MOVSQ, CMPSQ, LODSQ, SCASQ:
+			prefix = "qword "
+		case LAR:
+			prefix = "word "
+		case BOUND:
+			if inst.Mode == 32 {
+				prefix = "qword "
+			} else {
+				prefix = "dword "
+			}
+		case PREFETCHW, PREFETCHNTA, PREFETCHT0, PREFETCHT1, PREFETCHT2, CLFLUSH:
+			prefix = "zmmword "
+		}
+		switch inst.Op {
+		case MOVSB, MOVSW, MOVSD, MOVSQ, CMPSB, CMPSW, CMPSD, CMPSQ, STOSB, STOSW, STOSD, STOSQ, SCASB, SCASW, SCASD, SCASQ, LODSB, LODSW, LODSD, LODSQ:
+			switch a.Base {
+			case DI, EDI, RDI:
+				if a.Segment == ES {
+					a.Segment = 0
+				}
+			case SI, ESI, RSI:
+				if a.Segment == DS {
+					a.Segment = 0
+				}
+			}
+		case LEA:
+			a.Segment = 0
+		default:
+			switch a.Base {
+			case SP, ESP, RSP, BP, EBP, RBP:
+				if a.Segment == SS {
+					a.Segment = 0
+				}
+			default:
+				if a.Segment == DS {
+					a.Segment = 0
+				}
+			}
+		}
+
+		if inst.Mode == 64 && a.Segment != FS && a.Segment != GS {
+			a.Segment = 0
+		}
+
+		prefix += "ptr "
+		if a.Segment != 0 {
+			prefix += strings.ToLower(a.Segment.String()) + ":"
+		}
+		prefix += "["
+		if a.Base != 0 {
+			prefix += intelArg(inst, a.Base)
+		}
+		if a.Scale != 0 && a.Index != 0 {
+			if a.Base != 0 {
+				prefix += "+"
+			}
+			prefix += fmt.Sprintf("%s*%d", intelArg(inst, a.Index), a.Scale)
+		}
+		if a.Disp != 0 {
+			if prefix[len(prefix)-1] == '[' && (a.Disp >= 0 || int64(int32(a.Disp)) != a.Disp) {
+				prefix += fmt.Sprintf("%#x", uint64(a.Disp))
+			} else {
+				prefix += fmt.Sprintf("%+#x", a.Disp)
+			}
+		}
+		prefix += "]"
+		return prefix
+	case Rel:
+		return fmt.Sprintf(".%+#x", int64(a))
+	case Reg:
+		if int(a) < len(intelReg) && intelReg[a] != "" {
+			return intelReg[a]
+		}
+	}
+	return strings.ToLower(arg.String())
+}
+
+var intelOp = map[Op]string{
+	JAE:       "jnb",
+	JA:        "jnbe",
+	JGE:       "jnl",
+	JNE:       "jnz",
+	JG:        "jnle",
+	JE:        "jz",
+	SETAE:     "setnb",
+	SETA:      "setnbe",
+	SETGE:     "setnl",
+	SETNE:     "setnz",
+	SETG:      "setnle",
+	SETE:      "setz",
+	CMOVAE:    "cmovnb",
+	CMOVA:     "cmovnbe",
+	CMOVGE:    "cmovnl",
+	CMOVNE:    "cmovnz",
+	CMOVG:     "cmovnle",
+	CMOVE:     "cmovz",
+	LCALL:     "call far",
+	LJMP:      "jmp far",
+	LRET:      "ret far",
+	ICEBP:     "int1",
+	MOVSD_XMM: "movsd",
+	XLATB:     "xlat",
+}
+
+var intelReg = [...]string{
+	F0:  "st0",
+	F1:  "st1",
+	F2:  "st2",
+	F3:  "st3",
+	F4:  "st4",
+	F5:  "st5",
+	F6:  "st6",
+	F7:  "st7",
+	M0:  "mmx0",
+	M1:  "mmx1",
+	M2:  "mmx2",
+	M3:  "mmx3",
+	M4:  "mmx4",
+	M5:  "mmx5",
+	M6:  "mmx6",
+	M7:  "mmx7",
+	X0:  "xmm0",
+	X1:  "xmm1",
+	X2:  "xmm2",
+	X3:  "xmm3",
+	X4:  "xmm4",
+	X5:  "xmm5",
+	X6:  "xmm6",
+	X7:  "xmm7",
+	X8:  "xmm8",
+	X9:  "xmm9",
+	X10: "xmm10",
+	X11: "xmm11",
+	X12: "xmm12",
+	X13: "xmm13",
+	X14: "xmm14",
+	X15: "xmm15",
+
+	// TODO: Maybe the constants are named wrong.
+	SPB: "spl",
+	BPB: "bpl",
+	SIB: "sil",
+	DIB: "dil",
+
+	R8L:  "r8d",
+	R9L:  "r9d",
+	R10L: "r10d",
+	R11L: "r11d",
+	R12L: "r12d",
+	R13L: "r13d",
+	R14L: "r14d",
+	R15L: "r15d",
+}
diff --git a/src/cmd/internal/rsc.io/x86/x86asm/objdump_test.go b/src/cmd/internal/rsc.io/x86/x86asm/objdump_test.go
new file mode 100644
index 0000000..6f72605
--- /dev/null
+++ b/src/cmd/internal/rsc.io/x86/x86asm/objdump_test.go
@@ -0,0 +1,383 @@
+// 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 x86asm
+
+import (
+	"bytes"
+	"strings"
+	"testing"
+)
+
+func TestObjdump32Manual(t *testing.T)   { testObjdump32(t, hexCases(t, objdumpManualTests)) }
+func TestObjdump32Testdata(t *testing.T) { testObjdump32(t, concat(basicPrefixes, testdataCases(t))) }
+func TestObjdump32ModRM(t *testing.T)    { testObjdump32(t, concat(basicPrefixes, enumModRM)) }
+func TestObjdump32OneByte(t *testing.T)  { testBasic(t, testObjdump32) }
+func TestObjdump320F(t *testing.T)       { testBasic(t, testObjdump32, 0x0F) }
+func TestObjdump320F38(t *testing.T)     { testBasic(t, testObjdump32, 0x0F, 0x38) }
+func TestObjdump320F3A(t *testing.T)     { testBasic(t, testObjdump32, 0x0F, 0x3A) }
+func TestObjdump32Prefix(t *testing.T)   { testPrefix(t, testObjdump32) }
+
+func TestObjdump64Manual(t *testing.T)   { testObjdump64(t, hexCases(t, objdumpManualTests)) }
+func TestObjdump64Testdata(t *testing.T) { testObjdump64(t, concat(basicPrefixes, testdataCases(t))) }
+func TestObjdump64ModRM(t *testing.T)    { testObjdump64(t, concat(basicPrefixes, enumModRM)) }
+func TestObjdump64OneByte(t *testing.T)  { testBasic(t, testObjdump64) }
+func TestObjdump640F(t *testing.T)       { testBasic(t, testObjdump64, 0x0F) }
+func TestObjdump640F38(t *testing.T)     { testBasic(t, testObjdump64, 0x0F, 0x38) }
+func TestObjdump640F3A(t *testing.T)     { testBasic(t, testObjdump64, 0x0F, 0x3A) }
+func TestObjdump64Prefix(t *testing.T)   { testPrefix(t, testObjdump64) }
+
+func TestObjdump64REXTestdata(t *testing.T) {
+	testObjdump64(t, filter(concat3(basicPrefixes, rexPrefixes, testdataCases(t)), isValidREX))
+}
+func TestObjdump64REXModRM(t *testing.T) {
+	testObjdump64(t, concat3(basicPrefixes, rexPrefixes, enumModRM))
+}
+func TestObjdump64REXOneByte(t *testing.T) { testBasicREX(t, testObjdump64) }
+func TestObjdump64REX0F(t *testing.T)      { testBasicREX(t, testObjdump64, 0x0F) }
+func TestObjdump64REX0F38(t *testing.T)    { testBasicREX(t, testObjdump64, 0x0F, 0x38) }
+func TestObjdump64REX0F3A(t *testing.T)    { testBasicREX(t, testObjdump64, 0x0F, 0x3A) }
+func TestObjdump64REXPrefix(t *testing.T)  { testPrefixREX(t, testObjdump64) }
+
+// objdumpManualTests holds test cases that will be run by TestObjdumpManual.
+// If you are debugging a few cases that turned up in a longer run, it can be useful
+// to list them here and then use -run=ObjdumpManual, particularly with tracing enabled.
+var objdumpManualTests = `
+F390
+`
+
+// allowedMismatchObjdump reports whether the mismatch between text and dec
+// should be allowed by the test.
+func allowedMismatchObjdump(text string, size int, inst *Inst, dec ExtInst) bool {
+	if size == 15 && dec.nenc == 15 && contains(text, "truncated") && contains(dec.text, "(bad)") {
+		return true
+	}
+
+	if i := strings.LastIndex(dec.text, " "); isPrefix(dec.text[i+1:]) && size == 1 && isPrefix(text) {
+		return true
+	}
+
+	if size == dec.nenc && contains(dec.text, "movupd") && contains(dec.text, "data32") {
+		s := strings.Replace(dec.text, "data32 ", "", -1)
+		if text == s {
+			return true
+		}
+	}
+
+	// Simplify our invalid instruction text.
+	if text == "error: unrecognized instruction" {
+		text = "BAD"
+	}
+
+	// Invalid instructions for which libopcodes prints %? register.
+	// FF E8 11 22 33 44:
+	// Invalid instructions for which libopcodes prints "internal disassembler error".
+	// Invalid instructions for which libopcodes prints 8087 only (e.g., DB E0)
+	// or prints 287 only (e.g., DB E4).
+	if contains(dec.text, "%?", "<internal disassembler error>", "(8087 only)", "(287 only)") {
+		dec.text = "(bad)"
+	}
+
+	// 0F 19 11, 0F 1C 11, 0F 1D 11, 0F 1E 11, 0F 1F 11: libopcodes says nop,
+	// but the Intel manuals say that the only NOP there is 0F 1F /0.
+	// Perhaps libopcodes is reporting an older encoding.
+	i := bytes.IndexByte(dec.enc[:], 0x0F)
+	if contains(dec.text, "nop") && i >= 0 && i+2 < len(dec.enc) && dec.enc[i+1]&^7 == 0x18 && (dec.enc[i+1] != 0x1F || (dec.enc[i+2]>>3)&7 != 0) {
+		dec.text = "(bad)"
+	}
+
+	// Any invalid instruction.
+	if text == "BAD" && contains(dec.text, "(bad)") {
+		return true
+	}
+
+	// Instructions libopcodes knows but we do not (e.g., 0F 19 11).
+	if (text == "BAD" || size == 1 && isPrefix(text)) && hasPrefix(dec.text, unsupported...) {
+		return true
+	}
+
+	// Instructions we know but libopcodes does not (e.g., 0F D0 11).
+	if (contains(dec.text, "(bad)") || dec.nenc == 1 && isPrefix(dec.text)) && hasPrefix(text, libopcodesUnsupported...) {
+		return true
+	}
+
+	// Libopcodes rejects F2 90 as NOP. Not sure why.
+	if (contains(dec.text, "(bad)") || dec.nenc == 1 && isPrefix(dec.text)) && inst.Opcode>>24 == 0x90 && countPrefix(inst, 0xF2) > 0 {
+		return true
+	}
+
+	// 0F 20 11, 0F 21 11, 0F 22 11, 0F 23 11, 0F 24 11:
+	// Moves into and out of some control registers seem to be unsupported by libopcodes.
+	// TODO(rsc): Are they invalid somehow?
+	if (contains(dec.text, "(bad)") || dec.nenc == 1 && isPrefix(dec.text)) && contains(text, "%cr", "%db", "%tr") {
+		return true
+	}
+
+	if contains(dec.text, "fwait") && dec.nenc == 1 && dec.enc[0] != 0x9B {
+		return true
+	}
+
+	// 9B D9 11: libopcodes reports FSTSW instead of FWAIT + FNSTSW.
+	// This is correct in that FSTSW is a pseudo-op for the pair, but it really
+	// is a pair of instructions: execution can stop between them.
+	// Our decoder chooses to separate them.
+	if (text == "fwait" || strings.HasSuffix(text, " fwait")) && dec.nenc >= len(strings.Fields(text)) && dec.enc[len(strings.Fields(text))-1] == 0x9B {
+		return true
+	}
+
+	// 0F 18 77 11:
+	// Invalid instructions for which libopcodes prints "nop/reserved".
+	// Perhaps libopcodes is reporting an older encoding.
+	if text == "BAD" && contains(dec.text, "nop/reserved") {
+		return true
+	}
+
+	// 0F C7 B0 11 22 33 44: libopcodes says vmptrld 0x44332211(%eax); we say rdrand %eax.
+	// TODO(rsc): Fix, since we are probably wrong, but we don't have vmptrld in the manual.
+	if contains(text, "rdrand") && contains(dec.text, "vmptrld", "vmxon", "vmclear") {
+		return true
+	}
+
+	// DD C8: libopcodes says FNOP but the Intel manual is clear FNOP is only D9 D0.
+	// Perhaps libopcodes is reporting an older encoding.
+	if text == "BAD" && contains(dec.text, "fnop") && (dec.enc[0] != 0xD9 || dec.enc[1] != 0xD0) {
+		return true
+	}
+
+	// 66 90: libopcodes says xchg %ax,%ax; we say 'data16 nop'.
+	// The 16-bit swap will preserve the high bits of the register,
+	// so they are the same.
+	if contains(text, "nop") && contains(dec.text, "xchg %ax,%ax") {
+		return true
+	}
+
+	// If there are multiple prefixes, allow libopcodes to use an alternate name.
+	if size == 1 && dec.nenc == 1 && prefixByte[text] > 0 && prefixByte[text] == prefixByte[dec.text] {
+		return true
+	}
+
+	// 26 9B: libopcodes reports "fwait"/1, ignoring segment prefix.
+	// https://sourceware.org/bugzilla/show_bug.cgi?id=16891
+	// F0 82: Decode="lock"/1 but libopcodes="lock (bad)"/2.
+	if size == 1 && dec.nenc >= 1 && prefixByte[text] == dec.enc[0] && contains(dec.text, "(bad)", "fwait", "fnop") {
+		return true
+	}
+
+	// libopcodes interprets 660f801122 as taking a rel16 but
+	// truncating the address at 16 bits. Not sure what is correct.
+	if contains(text, ".+0x2211", ".+0x11") && contains(dec.text, " .-") {
+		return true
+	}
+
+	// 66 F3 0F D6 C5, 66 F2 0F D6 C0: libopcodes reports use of XMM register instead of MMX register,
+	// but only when the instruction has a 66 prefix. Maybe they know something we don't.
+	if countPrefix(inst, 0x66) > 0 && contains(dec.text, "movdq2q", "movq2dq") && !contains(dec.text, "%mm") {
+		return true
+	}
+
+	// 0F 01 F8, 0F 05, 0F 07: these are 64-bit instructions but libopcodes accepts them.
+	if (text == "BAD" || size == 1 && isPrefix(text)) && contains(dec.text, "swapgs", "syscall", "sysret", "rdfsbase", "rdgsbase", "wrfsbase", "wrgsbase") {
+		return true
+	}
+
+	return false
+}
+
+// Instructions known to libopcodes (or xed) but not to us.
+// Most of these come from supplementary manuals of one form or another.
+var unsupported = strings.Fields(`
+	bndc
+	bndl
+	bndm
+	bnds
+	clac
+	clgi
+	femms
+	fldln
+	fldz
+	getsec
+	invlpga
+	kmov
+	montmul
+	pavg
+	pf2i
+	pfacc
+	pfadd
+	pfcmp
+	pfmax
+	pfmin
+	pfmul
+	pfna
+	pfpnac
+	pfrc
+	pfrs
+	pfsub
+	phadd
+	phsub
+	pi2f
+	pmulhr
+	prefetch
+	pswap
+	ptest
+	rdseed
+	sha1
+	sha256
+	skinit
+	stac
+	stgi
+	vadd
+	vand
+	vcmp
+	vcomis
+	vcvt
+	vcvt
+	vdiv
+	vhadd
+	vhsub
+	vld
+	vmax
+	vmcall
+	vmfunc
+	vmin
+	vmlaunch
+	vmload
+	vmmcall
+	vmov
+	vmov
+	vmov
+	vmptrld
+	vmptrst
+	vmread
+	vmresume
+	vmrun
+	vmsave
+	vmul
+	vmwrite
+	vmxoff
+	vor
+	vpack
+	vpadd
+	vpand
+	vpavg
+	vpcmp
+	vpcmp
+	vpins
+	vpmadd
+	vpmax
+	vpmin
+	vpmul
+	vpmul
+	vpor
+	vpsad
+	vpshuf
+	vpsll
+	vpsra
+	vpsrad
+	vpsrl
+	vpsub
+	vpunp
+	vpxor
+	vrcp
+	vrsqrt
+	vshuf
+	vsqrt
+	vsub
+	vucomis
+	vunp
+	vxor
+	vzero
+	xcrypt
+	xsha1
+	xsha256
+	xstore-rng
+	insertq
+	extrq
+	vmclear
+	invvpid
+	adox
+	vmxon
+	invept
+	adcx
+	vmclear
+	prefetchwt1
+	enclu
+	encls
+	salc
+	fstpnce
+	fdisi8087_nop
+	fsetpm287_nop
+	feni8087_nop
+	syscall
+	sysret
+`)
+
+// Instructions known to us but not to libopcodes (at least in binutils 2.24).
+var libopcodesUnsupported = strings.Fields(`
+	addsubps
+	aes
+	blend
+	cvttpd2dq
+	dpp
+	extract
+	haddps
+	hsubps
+	insert
+	invpcid
+	lddqu
+	movmsk
+	movnt
+	movq2dq
+	mps
+	pack
+	pblend
+	pclmul
+	pcmp
+	pext
+	phmin
+	pins
+	pmax
+	pmin
+	pmov
+	pmovmsk
+	pmul
+	popcnt
+	pslld
+	psllq
+	psllw
+	psrad
+	psraw
+	psrl
+	ptest
+	punpck
+	round
+	xrstor
+	xsavec
+	xsaves
+	comis
+	ucomis
+	movhps
+	movntps
+	rsqrt
+	rcpp
+	puncpck
+	bsf
+	movq2dq
+	cvttpd2dq
+	movq
+	hsubpd
+	movdqa
+	movhpd
+	addsubpd
+	movd
+	haddpd
+	cvtps2dq
+	bsr
+	cvtdq2ps
+	rdrand
+	maskmov
+	movq2dq
+	movlhps
+	movbe
+	movlpd
+`)
diff --git a/src/cmd/internal/rsc.io/x86/x86asm/objdumpext_test.go b/src/cmd/internal/rsc.io/x86/x86asm/objdumpext_test.go
new file mode 100644
index 0000000..37a5513
--- /dev/null
+++ b/src/cmd/internal/rsc.io/x86/x86asm/objdumpext_test.go
@@ -0,0 +1,314 @@
+// 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 x86asm
+
+import (
+	"bytes"
+	"debug/elf"
+	"encoding/binary"
+	"fmt"
+	"io"
+	"log"
+	"os"
+	"strconv"
+	"strings"
+	"testing"
+)
+
+// Apologies for the proprietary path, but we need objdump 2.24 + some committed patches that will land in 2.25.
+const objdumpPath = "/Users/rsc/bin/objdump2"
+
+func testObjdump32(t *testing.T, generate func(func([]byte))) {
+	testObjdumpArch(t, generate, 32)
+}
+
+func testObjdump64(t *testing.T, generate func(func([]byte))) {
+	testObjdumpArch(t, generate, 64)
+}
+
+func testObjdumpArch(t *testing.T, generate func(func([]byte)), arch int) {
+	if testing.Short() {
+		t.Skip("skipping objdump test in short mode")
+	}
+
+	if _, err := os.Stat(objdumpPath); err != nil {
+		t.Fatal(err)
+	}
+
+	testExtDis(t, "gnu", arch, objdump, generate, allowedMismatchObjdump)
+}
+
+func objdump(ext *ExtDis) error {
+	// File already written with instructions; add ELF header.
+	if ext.Arch == 32 {
+		if err := writeELF32(ext.File, ext.Size); err != nil {
+			return err
+		}
+	} else {
+		if err := writeELF64(ext.File, ext.Size); err != nil {
+			return err
+		}
+	}
+
+	b, err := ext.Run(objdumpPath, "-d", "-z", ext.File.Name())
+	if err != nil {
+		return err
+	}
+
+	var (
+		nmatch  int
+		reading bool
+		next    uint32 = start
+		addr    uint32
+		encbuf  [32]byte
+		enc     []byte
+		text    string
+	)
+	flush := func() {
+		if addr == next {
+			switch text {
+			case "repz":
+				text = "rep"
+			case "repnz":
+				text = "repn"
+			default:
+				text = strings.Replace(text, "repz ", "rep ", -1)
+				text = strings.Replace(text, "repnz ", "repn ", -1)
+			}
+			if m := pcrelw.FindStringSubmatch(text); m != nil {
+				targ, _ := strconv.ParseUint(m[2], 16, 64)
+				text = fmt.Sprintf("%s .%+#x", m[1], int16(uint32(targ)-uint32(uint16(addr))-uint32(len(enc))))
+			}
+			if m := pcrel.FindStringSubmatch(text); m != nil {
+				targ, _ := strconv.ParseUint(m[2], 16, 64)
+				text = fmt.Sprintf("%s .%+#x", m[1], int32(uint32(targ)-addr-uint32(len(enc))))
+			}
+			text = strings.Replace(text, "0x0(", "(", -1)
+			text = strings.Replace(text, "%st(0)", "%st", -1)
+
+			ext.Dec <- ExtInst{addr, encbuf, len(enc), text}
+			encbuf = [32]byte{}
+			enc = nil
+			next += 32
+		}
+	}
+	var textangle = []byte("<.text>:")
+	for {
+		line, err := b.ReadSlice('\n')
+		if err != nil {
+			if err == io.EOF {
+				break
+			}
+			return fmt.Errorf("reading objdump output: %v", err)
+		}
+		if bytes.Contains(line, textangle) {
+			reading = true
+			continue
+		}
+		if !reading {
+			continue
+		}
+		if debug {
+			os.Stdout.Write(line)
+		}
+		if enc1 := parseContinuation(line, encbuf[:len(enc)]); enc1 != nil {
+			enc = enc1
+			continue
+		}
+		flush()
+		nmatch++
+		addr, enc, text = parseLine(line, encbuf[:0])
+		if addr > next {
+			return fmt.Errorf("address out of sync expected <= %#x at %q in:\n%s", next, line, line)
+		}
+	}
+	flush()
+	if next != start+uint32(ext.Size) {
+		return fmt.Errorf("not enough results found [%d %d]", next, start+ext.Size)
+	}
+	if err := ext.Wait(); err != nil {
+		return fmt.Errorf("exec: %v", err)
+	}
+
+	return nil
+}
+
+func parseLine(line []byte, encstart []byte) (addr uint32, enc []byte, text string) {
+	oline := line
+	i := index(line, ":\t")
+	if i < 0 {
+		log.Fatalf("cannot parse disassembly: %q", oline)
+	}
+	x, err := strconv.ParseUint(string(trimSpace(line[:i])), 16, 32)
+	if err != nil {
+		log.Fatalf("cannot parse disassembly: %q", oline)
+	}
+	addr = uint32(x)
+	line = line[i+2:]
+	i = bytes.IndexByte(line, '\t')
+	if i < 0 {
+		log.Fatalf("cannot parse disassembly: %q", oline)
+	}
+	enc, ok := parseHex(line[:i], encstart)
+	if !ok {
+		log.Fatalf("cannot parse disassembly: %q", oline)
+	}
+	line = trimSpace(line[i:])
+	if i := bytes.IndexByte(line, '#'); i >= 0 {
+		line = trimSpace(line[:i])
+	}
+	text = string(fixSpace(line))
+	return
+}
+
+func parseContinuation(line []byte, enc []byte) []byte {
+	i := index(line, ":\t")
+	if i < 0 {
+		return nil
+	}
+	line = line[i+1:]
+	enc, _ = parseHex(line, enc)
+	return enc
+}
+
+// writeELF32 writes an ELF32 header to the file,
+// describing a text segment that starts at start
+// and extends for size bytes.
+func writeELF32(f *os.File, size int) error {
+	f.Seek(0, 0)
+	var hdr elf.Header32
+	var prog elf.Prog32
+	var sect elf.Section32
+	var buf bytes.Buffer
+	binary.Write(&buf, binary.LittleEndian, &hdr)
+	off1 := buf.Len()
+	binary.Write(&buf, binary.LittleEndian, &prog)
+	off2 := buf.Len()
+	binary.Write(&buf, binary.LittleEndian, &sect)
+	off3 := buf.Len()
+	buf.Reset()
+	data := byte(elf.ELFDATA2LSB)
+	hdr = elf.Header32{
+		Ident:     [16]byte{0x7F, 'E', 'L', 'F', 1, data, 1},
+		Type:      2,
+		Machine:   uint16(elf.EM_386),
+		Version:   1,
+		Entry:     start,
+		Phoff:     uint32(off1),
+		Shoff:     uint32(off2),
+		Flags:     0x05000002,
+		Ehsize:    uint16(off1),
+		Phentsize: uint16(off2 - off1),
+		Phnum:     1,
+		Shentsize: uint16(off3 - off2),
+		Shnum:     3,
+		Shstrndx:  2,
+	}
+	binary.Write(&buf, binary.LittleEndian, &hdr)
+	prog = elf.Prog32{
+		Type:   1,
+		Off:    start,
+		Vaddr:  start,
+		Paddr:  start,
+		Filesz: uint32(size),
+		Memsz:  uint32(size),
+		Flags:  5,
+		Align:  start,
+	}
+	binary.Write(&buf, binary.LittleEndian, &prog)
+	binary.Write(&buf, binary.LittleEndian, &sect) // NULL section
+	sect = elf.Section32{
+		Name:      1,
+		Type:      uint32(elf.SHT_PROGBITS),
+		Addr:      start,
+		Off:       start,
+		Size:      uint32(size),
+		Flags:     uint32(elf.SHF_ALLOC | elf.SHF_EXECINSTR),
+		Addralign: 4,
+	}
+	binary.Write(&buf, binary.LittleEndian, &sect) // .text
+	sect = elf.Section32{
+		Name:      uint32(len("\x00.text\x00")),
+		Type:      uint32(elf.SHT_STRTAB),
+		Addr:      0,
+		Off:       uint32(off2 + (off3-off2)*3),
+		Size:      uint32(len("\x00.text\x00.shstrtab\x00")),
+		Addralign: 1,
+	}
+	binary.Write(&buf, binary.LittleEndian, &sect)
+	buf.WriteString("\x00.text\x00.shstrtab\x00")
+	f.Write(buf.Bytes())
+	return nil
+}
+
+// writeELF64 writes an ELF64 header to the file,
+// describing a text segment that starts at start
+// and extends for size bytes.
+func writeELF64(f *os.File, size int) error {
+	f.Seek(0, 0)
+	var hdr elf.Header64
+	var prog elf.Prog64
+	var sect elf.Section64
+	var buf bytes.Buffer
+	binary.Write(&buf, binary.LittleEndian, &hdr)
+	off1 := buf.Len()
+	binary.Write(&buf, binary.LittleEndian, &prog)
+	off2 := buf.Len()
+	binary.Write(&buf, binary.LittleEndian, &sect)
+	off3 := buf.Len()
+	buf.Reset()
+	data := byte(elf.ELFDATA2LSB)
+	hdr = elf.Header64{
+		Ident:     [16]byte{0x7F, 'E', 'L', 'F', 2, data, 1},
+		Type:      2,
+		Machine:   uint16(elf.EM_X86_64),
+		Version:   1,
+		Entry:     start,
+		Phoff:     uint64(off1),
+		Shoff:     uint64(off2),
+		Flags:     0x05000002,
+		Ehsize:    uint16(off1),
+		Phentsize: uint16(off2 - off1),
+		Phnum:     1,
+		Shentsize: uint16(off3 - off2),
+		Shnum:     3,
+		Shstrndx:  2,
+	}
+	binary.Write(&buf, binary.LittleEndian, &hdr)
+	prog = elf.Prog64{
+		Type:   1,
+		Off:    start,
+		Vaddr:  start,
+		Paddr:  start,
+		Filesz: uint64(size),
+		Memsz:  uint64(size),
+		Flags:  5,
+		Align:  start,
+	}
+	binary.Write(&buf, binary.LittleEndian, &prog)
+	binary.Write(&buf, binary.LittleEndian, &sect) // NULL section
+	sect = elf.Section64{
+		Name:      1,
+		Type:      uint32(elf.SHT_PROGBITS),
+		Addr:      start,
+		Off:       start,
+		Size:      uint64(size),
+		Flags:     uint64(elf.SHF_ALLOC | elf.SHF_EXECINSTR),
+		Addralign: 4,
+	}
+	binary.Write(&buf, binary.LittleEndian, &sect) // .text
+	sect = elf.Section64{
+		Name:      uint32(len("\x00.text\x00")),
+		Type:      uint32(elf.SHT_STRTAB),
+		Addr:      0,
+		Off:       uint64(off2 + (off3-off2)*3),
+		Size:      uint64(len("\x00.text\x00.shstrtab\x00")),
+		Addralign: 1,
+	}
+	binary.Write(&buf, binary.LittleEndian, &sect)
+	buf.WriteString("\x00.text\x00.shstrtab\x00")
+	f.Write(buf.Bytes())
+	return nil
+}
diff --git a/src/cmd/internal/rsc.io/x86/x86asm/plan9ext_test.go b/src/cmd/internal/rsc.io/x86/x86asm/plan9ext_test.go
new file mode 100644
index 0000000..21f5bfd
--- /dev/null
+++ b/src/cmd/internal/rsc.io/x86/x86asm/plan9ext_test.go
@@ -0,0 +1,120 @@
+// 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 x86asm
+
+import (
+	"bytes"
+	"fmt"
+	"io"
+	"log"
+	"os"
+	"strconv"
+	"testing"
+)
+
+const plan9Path = "testdata/libmach8db"
+
+func testPlan9Arch(t *testing.T, arch int, generate func(func([]byte))) {
+	if testing.Short() {
+		t.Skip("skipping libmach test in short mode")
+	}
+
+	if _, err := os.Stat(plan9Path); err != nil {
+		t.Fatal(err)
+	}
+
+	testExtDis(t, "plan9", arch, plan9, generate, allowedMismatchPlan9)
+}
+
+func testPlan932(t *testing.T, generate func(func([]byte))) {
+	testPlan9Arch(t, 32, generate)
+}
+
+func testPlan964(t *testing.T, generate func(func([]byte))) {
+	testPlan9Arch(t, 64, generate)
+}
+
+func plan9(ext *ExtDis) error {
+	flag := "-8"
+	if ext.Arch == 64 {
+		flag = "-6"
+	}
+	b, err := ext.Run(plan9Path, flag, ext.File.Name())
+	if err != nil {
+		return err
+	}
+
+	nmatch := 0
+	next := uint32(start)
+	var (
+		addr   uint32
+		encbuf [32]byte
+		enc    []byte
+		text   string
+	)
+
+	for {
+		line, err := b.ReadSlice('\n')
+		if err != nil {
+			if err == io.EOF {
+				break
+			}
+			return fmt.Errorf("reading libmach8db output: %v", err)
+		}
+		if debug {
+			os.Stdout.Write(line)
+		}
+		nmatch++
+		addr, enc, text = parseLinePlan9(line, encbuf[:0])
+		if addr > next {
+			return fmt.Errorf("address out of sync expected <= %#x at %q in:\n%s", next, line, line)
+		}
+		if addr < next {
+			continue
+		}
+		if m := pcrelw.FindStringSubmatch(text); m != nil {
+			targ, _ := strconv.ParseUint(m[2], 16, 64)
+			text = fmt.Sprintf("%s .%+#x", m[1], int16(uint32(targ)-uint32(uint16(addr))-uint32(len(enc))))
+		}
+		if m := pcrel.FindStringSubmatch(text); m != nil {
+			targ, _ := strconv.ParseUint(m[2], 16, 64)
+			text = fmt.Sprintf("%s .%+#x", m[1], int32(uint32(targ)-addr-uint32(len(enc))))
+		}
+		ext.Dec <- ExtInst{addr, encbuf, len(enc), text}
+		encbuf = [32]byte{}
+		enc = nil
+		next += 32
+	}
+	if next != start+uint32(ext.Size) {
+		return fmt.Errorf("not enough results found [%d %d]", next, start+ext.Size)
+	}
+	if err := ext.Wait(); err != nil {
+		return fmt.Errorf("exec: %v", err)
+	}
+
+	return nil
+}
+
+func parseLinePlan9(line []byte, encstart []byte) (addr uint32, enc []byte, text string) {
+	i := bytes.IndexByte(line, ' ')
+	if i < 0 || line[0] != '0' || line[1] != 'x' {
+		log.Fatalf("cannot parse disassembly: %q", line)
+	}
+	j := bytes.IndexByte(line[i+1:], ' ')
+	if j < 0 {
+		log.Fatalf("cannot parse disassembly: %q", line)
+	}
+	j += i + 1
+	x, err := strconv.ParseUint(string(trimSpace(line[2:i])), 16, 32)
+	if err != nil {
+		log.Fatalf("cannot parse disassembly: %q", line)
+	}
+	addr = uint32(x)
+	enc, ok := parseHex(line[i+1:j], encstart)
+	if !ok {
+		log.Fatalf("cannot parse disassembly: %q", line)
+	}
+	return addr, enc, string(fixSpace(line[j+1:]))
+}
diff --git a/src/cmd/internal/rsc.io/x86/x86asm/plan9x.go b/src/cmd/internal/rsc.io/x86/x86asm/plan9x.go
new file mode 100644
index 0000000..5a0bd87
--- /dev/null
+++ b/src/cmd/internal/rsc.io/x86/x86asm/plan9x.go
@@ -0,0 +1,346 @@
+// 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 x86asm
+
+import (
+	"fmt"
+	"strings"
+)
+
+// Plan9Syntax returns the Go assembler syntax for the instruction.
+// The syntax was originally defined by Plan 9.
+// The pc is the program counter of the instruction, used for expanding
+// PC-relative addresses into absolute ones.
+// The symname function queries the symbol table for the program
+// being disassembled. Given a target address it returns the name and base
+// address of the symbol containing the target, if any; otherwise it returns "", 0.
+func Plan9Syntax(inst Inst, pc uint64, symname func(uint64) (string, uint64)) string {
+	if symname == nil {
+		symname = func(uint64) (string, uint64) { return "", 0 }
+	}
+	var args []string
+	for i := len(inst.Args) - 1; i >= 0; i-- {
+		a := inst.Args[i]
+		if a == nil {
+			continue
+		}
+		args = append(args, plan9Arg(&inst, pc, symname, a))
+	}
+
+	var last Prefix
+	for _, p := range inst.Prefix {
+		if p == 0 || p.IsREX() {
+			break
+		}
+		last = p
+	}
+
+	prefix := ""
+	switch last & 0xFF {
+	case 0, 0x66, 0x67:
+		// ignore
+	case PrefixREPN:
+		prefix += "REPNE "
+	default:
+		prefix += last.String() + " "
+	}
+
+	op := inst.Op.String()
+	if plan9Suffix[inst.Op] {
+		switch inst.DataSize {
+		case 8:
+			op += "B"
+		case 16:
+			op += "W"
+		case 32:
+			op += "L"
+		case 64:
+			op += "Q"
+		}
+	}
+
+	if args != nil {
+		op += " " + strings.Join(args, ", ")
+	}
+
+	return prefix + op
+}
+
+func plan9Arg(inst *Inst, pc uint64, symname func(uint64) (string, uint64), arg Arg) string {
+	switch a := arg.(type) {
+	case Reg:
+		return plan9Reg[a]
+	case Rel:
+		if pc == 0 {
+			break
+		}
+		// If the absolute address is the start of a symbol, use the name.
+		// Otherwise use the raw address, so that things like relative
+		// jumps show up as JMP 0x123 instead of JMP f+10(SB).
+		// It is usually easier to search for 0x123 than to do the mental
+		// arithmetic to find f+10.
+		addr := pc + uint64(inst.Len) + uint64(a)
+		if s, base := symname(addr); s != "" && addr == base {
+			return fmt.Sprintf("%s(SB)", s)
+		}
+		return fmt.Sprintf("%#x", addr)
+
+	case Imm:
+		if s, base := symname(uint64(a)); s != "" {
+			suffix := ""
+			if uint64(a) != base {
+				suffix = fmt.Sprintf("%+d", uint64(a)-base)
+			}
+			return fmt.Sprintf("$%s%s(SB)", s, suffix)
+		}
+		if inst.Mode == 32 {
+			return fmt.Sprintf("$%#x", uint32(a))
+		}
+		if Imm(int32(a)) == a {
+			return fmt.Sprintf("$%#x", int64(a))
+		}
+		return fmt.Sprintf("$%#x", uint64(a))
+	case Mem:
+		if a.Segment == 0 && a.Disp != 0 && a.Base == 0 && (a.Index == 0 || a.Scale == 0) {
+			if s, base := symname(uint64(a.Disp)); s != "" {
+				suffix := ""
+				if uint64(a.Disp) != base {
+					suffix = fmt.Sprintf("%+d", uint64(a.Disp)-base)
+				}
+				return fmt.Sprintf("%s%s(SB)", s, suffix)
+			}
+		}
+		s := ""
+		if a.Segment != 0 {
+			s += fmt.Sprintf("%s:", plan9Reg[a.Segment])
+		}
+		if a.Disp != 0 {
+			s += fmt.Sprintf("%#x", a.Disp)
+		} else {
+			s += "0"
+		}
+		if a.Base != 0 {
+			s += fmt.Sprintf("(%s)", plan9Reg[a.Base])
+		}
+		if a.Index != 0 && a.Scale != 0 {
+			s += fmt.Sprintf("(%s*%d)", plan9Reg[a.Index], a.Scale)
+		}
+		return s
+	}
+	return arg.String()
+}
+
+var plan9Suffix = [maxOp + 1]bool{
+	ADC:       true,
+	ADD:       true,
+	AND:       true,
+	BSF:       true,
+	BSR:       true,
+	BT:        true,
+	BTC:       true,
+	BTR:       true,
+	BTS:       true,
+	CMP:       true,
+	CMPXCHG:   true,
+	CVTSI2SD:  true,
+	CVTSI2SS:  true,
+	CVTSD2SI:  true,
+	CVTSS2SI:  true,
+	CVTTSD2SI: true,
+	CVTTSS2SI: true,
+	DEC:       true,
+	DIV:       true,
+	FLDENV:    true,
+	FRSTOR:    true,
+	IDIV:      true,
+	IMUL:      true,
+	IN:        true,
+	INC:       true,
+	LEA:       true,
+	MOV:       true,
+	MOVNTI:    true,
+	MUL:       true,
+	NEG:       true,
+	NOP:       true,
+	NOT:       true,
+	OR:        true,
+	OUT:       true,
+	POP:       true,
+	POPA:      true,
+	PUSH:      true,
+	PUSHA:     true,
+	RCL:       true,
+	RCR:       true,
+	ROL:       true,
+	ROR:       true,
+	SAR:       true,
+	SBB:       true,
+	SHL:       true,
+	SHLD:      true,
+	SHR:       true,
+	SHRD:      true,
+	SUB:       true,
+	TEST:      true,
+	XADD:      true,
+	XCHG:      true,
+	XOR:       true,
+}
+
+var plan9Reg = [...]string{
+	AL:   "AL",
+	CL:   "CL",
+	BL:   "BL",
+	DL:   "DL",
+	AH:   "AH",
+	CH:   "CH",
+	BH:   "BH",
+	DH:   "DH",
+	SPB:  "SP",
+	BPB:  "BP",
+	SIB:  "SI",
+	DIB:  "DI",
+	R8B:  "R8",
+	R9B:  "R9",
+	R10B: "R10",
+	R11B: "R11",
+	R12B: "R12",
+	R13B: "R13",
+	R14B: "R14",
+	R15B: "R15",
+	AX:   "AX",
+	CX:   "CX",
+	BX:   "BX",
+	DX:   "DX",
+	SP:   "SP",
+	BP:   "BP",
+	SI:   "SI",
+	DI:   "DI",
+	R8W:  "R8",
+	R9W:  "R9",
+	R10W: "R10",
+	R11W: "R11",
+	R12W: "R12",
+	R13W: "R13",
+	R14W: "R14",
+	R15W: "R15",
+	EAX:  "AX",
+	ECX:  "CX",
+	EDX:  "DX",
+	EBX:  "BX",
+	ESP:  "SP",
+	EBP:  "BP",
+	ESI:  "SI",
+	EDI:  "DI",
+	R8L:  "R8",
+	R9L:  "R9",
+	R10L: "R10",
+	R11L: "R11",
+	R12L: "R12",
+	R13L: "R13",
+	R14L: "R14",
+	R15L: "R15",
+	RAX:  "AX",
+	RCX:  "CX",
+	RDX:  "DX",
+	RBX:  "BX",
+	RSP:  "SP",
+	RBP:  "BP",
+	RSI:  "SI",
+	RDI:  "DI",
+	R8:   "R8",
+	R9:   "R9",
+	R10:  "R10",
+	R11:  "R11",
+	R12:  "R12",
+	R13:  "R13",
+	R14:  "R14",
+	R15:  "R15",
+	IP:   "IP",
+	EIP:  "IP",
+	RIP:  "IP",
+	F0:   "F0",
+	F1:   "F1",
+	F2:   "F2",
+	F3:   "F3",
+	F4:   "F4",
+	F5:   "F5",
+	F6:   "F6",
+	F7:   "F7",
+	M0:   "M0",
+	M1:   "M1",
+	M2:   "M2",
+	M3:   "M3",
+	M4:   "M4",
+	M5:   "M5",
+	M6:   "M6",
+	M7:   "M7",
+	X0:   "X0",
+	X1:   "X1",
+	X2:   "X2",
+	X3:   "X3",
+	X4:   "X4",
+	X5:   "X5",
+	X6:   "X6",
+	X7:   "X7",
+	X8:   "X8",
+	X9:   "X9",
+	X10:  "X10",
+	X11:  "X11",
+	X12:  "X12",
+	X13:  "X13",
+	X14:  "X14",
+	X15:  "X15",
+	CS:   "CS",
+	SS:   "SS",
+	DS:   "DS",
+	ES:   "ES",
+	FS:   "FS",
+	GS:   "GS",
+	GDTR: "GDTR",
+	IDTR: "IDTR",
+	LDTR: "LDTR",
+	MSW:  "MSW",
+	TASK: "TASK",
+	CR0:  "CR0",
+	CR1:  "CR1",
+	CR2:  "CR2",
+	CR3:  "CR3",
+	CR4:  "CR4",
+	CR5:  "CR5",
+	CR6:  "CR6",
+	CR7:  "CR7",
+	CR8:  "CR8",
+	CR9:  "CR9",
+	CR10: "CR10",
+	CR11: "CR11",
+	CR12: "CR12",
+	CR13: "CR13",
+	CR14: "CR14",
+	CR15: "CR15",
+	DR0:  "DR0",
+	DR1:  "DR1",
+	DR2:  "DR2",
+	DR3:  "DR3",
+	DR4:  "DR4",
+	DR5:  "DR5",
+	DR6:  "DR6",
+	DR7:  "DR7",
+	DR8:  "DR8",
+	DR9:  "DR9",
+	DR10: "DR10",
+	DR11: "DR11",
+	DR12: "DR12",
+	DR13: "DR13",
+	DR14: "DR14",
+	DR15: "DR15",
+	TR0:  "TR0",
+	TR1:  "TR1",
+	TR2:  "TR2",
+	TR3:  "TR3",
+	TR4:  "TR4",
+	TR5:  "TR5",
+	TR6:  "TR6",
+	TR7:  "TR7",
+}
diff --git a/src/cmd/internal/rsc.io/x86/x86asm/plan9x_test.go b/src/cmd/internal/rsc.io/x86/x86asm/plan9x_test.go
new file mode 100644
index 0000000..f2ea28c
--- /dev/null
+++ b/src/cmd/internal/rsc.io/x86/x86asm/plan9x_test.go
@@ -0,0 +1,54 @@
+// 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 x86asm
+
+import (
+	"strings"
+	"testing"
+)
+
+func TestPlan932Manual(t *testing.T)   { testPlan932(t, hexCases(t, plan9ManualTests)) }
+func TestPlan932Testdata(t *testing.T) { testPlan932(t, concat(basicPrefixes, testdataCases(t))) }
+func TestPlan932ModRM(t *testing.T)    { testPlan932(t, concat(basicPrefixes, enumModRM)) }
+func TestPlan932OneByte(t *testing.T)  { testBasic(t, testPlan932) }
+func TestPlan9320F(t *testing.T)       { testBasic(t, testPlan932, 0x0F) }
+func TestPlan9320F38(t *testing.T)     { testBasic(t, testPlan932, 0x0F, 0x38) }
+func TestPlan9320F3A(t *testing.T)     { testBasic(t, testPlan932, 0x0F, 0x3A) }
+func TestPlan932Prefix(t *testing.T)   { testPrefix(t, testPlan932) }
+
+func TestPlan964Manual(t *testing.T)   { testPlan964(t, hexCases(t, plan9ManualTests)) }
+func TestPlan964Testdata(t *testing.T) { testPlan964(t, concat(basicPrefixes, testdataCases(t))) }
+func TestPlan964ModRM(t *testing.T)    { testPlan964(t, concat(basicPrefixes, enumModRM)) }
+func TestPlan964OneByte(t *testing.T)  { testBasic(t, testPlan964) }
+func TestPlan9640F(t *testing.T)       { testBasic(t, testPlan964, 0x0F) }
+func TestPlan9640F38(t *testing.T)     { testBasic(t, testPlan964, 0x0F, 0x38) }
+func TestPlan9640F3A(t *testing.T)     { testBasic(t, testPlan964, 0x0F, 0x3A) }
+func TestPlan964Prefix(t *testing.T)   { testPrefix(t, testPlan964) }
+
+func TestPlan964REXTestdata(t *testing.T) {
+	testPlan964(t, filter(concat3(basicPrefixes, rexPrefixes, testdataCases(t)), isValidREX))
+}
+func TestPlan964REXModRM(t *testing.T)   { testPlan964(t, concat3(basicPrefixes, rexPrefixes, enumModRM)) }
+func TestPlan964REXOneByte(t *testing.T) { testBasicREX(t, testPlan964) }
+func TestPlan964REX0F(t *testing.T)      { testBasicREX(t, testPlan964, 0x0F) }
+func TestPlan964REX0F38(t *testing.T)    { testBasicREX(t, testPlan964, 0x0F, 0x38) }
+func TestPlan964REX0F3A(t *testing.T)    { testBasicREX(t, testPlan964, 0x0F, 0x3A) }
+func TestPlan964REXPrefix(t *testing.T)  { testPrefixREX(t, testPlan964) }
+
+// plan9ManualTests holds test cases that will be run by TestPlan9Manual32 and TestPlan9Manual64.
+// If you are debugging a few cases that turned up in a longer run, it can be useful
+// to list them here and then use -run=Plan9Manual, particularly with tracing enabled.
+var plan9ManualTests = `
+`
+
+// allowedMismatchPlan9 reports whether the mismatch between text and dec
+// should be allowed by the test.
+func allowedMismatchPlan9(text string, size int, inst *Inst, dec ExtInst) bool {
+	return false
+}
+
+// Instructions known to us but not to plan9.
+var plan9Unsupported = strings.Fields(`
+`)
diff --git a/src/cmd/internal/rsc.io/x86/x86asm/tables.go b/src/cmd/internal/rsc.io/x86/x86asm/tables.go
new file mode 100644
index 0000000..3d08d5e
--- /dev/null
+++ b/src/cmd/internal/rsc.io/x86/x86asm/tables.go
@@ -0,0 +1,9760 @@
+// DO NOT EDIT
+// generated by: x86map -fmt=decoder ../x86.csv
+
+package x86asm
+
+var decoder = [...]uint16{
+	uint16(xFail),
+	/*1*/ uint16(xCondByte), 243,
+	0x00, 490,
+	0x01, 496,
+	0x02, 525,
+	0x03, 531,
+	0x04, 560,
+	0x05, 566,
+	0x06, 595,
+	0x07, 602,
+	0x08, 609,
+	0x09, 615,
+	0x0A, 644,
+	0x0B, 650,
+	0x0C, 679,
+	0x0D, 685,
+	0x0E, 714,
+	0x0F, 721,
+	0x10, 8026,
+	0x11, 8032,
+	0x12, 8061,
+	0x13, 8067,
+	0x14, 8096,
+	0x15, 8102,
+	0x16, 8131,
+	0x17, 8138,
+	0x18, 8145,
+	0x19, 8151,
+	0x1A, 8180,
+	0x1B, 8186,
+	0x1C, 8215,
+	0x1D, 8221,
+	0x1E, 8250,
+	0x1F, 8257,
+	0x20, 8264,
+	0x21, 8270,
+	0x22, 8299,
+	0x23, 8305,
+	0x24, 8334,
+	0x25, 8340,
+	0x27, 8369,
+	0x28, 8375,
+	0x29, 8381,
+	0x2A, 8410,
+	0x2B, 8416,
+	0x2C, 8445,
+	0x2D, 8451,
+	0x2F, 8480,
+	0x30, 8486,
+	0x31, 8492,
+	0x32, 8521,
+	0x33, 8527,
+	0x34, 8556,
+	0x35, 8562,
+	0x37, 8591,
+	0x38, 8597,
+	0x39, 8603,
+	0x3A, 8632,
+	0x3B, 8638,
+	0x3C, 8667,
+	0x3D, 8673,
+	0x3F, 8702,
+	0x40, 8708,
+	0x41, 8708,
+	0x42, 8708,
+	0x43, 8708,
+	0x44, 8708,
+	0x45, 8708,
+	0x46, 8708,
+	0x47, 8708,
+	0x48, 8723,
+	0x49, 8723,
+	0x4a, 8723,
+	0x4b, 8723,
+	0x4c, 8723,
+	0x4d, 8723,
+	0x4e, 8723,
+	0x4f, 8723,
+	0x50, 8738,
+	0x51, 8738,
+	0x52, 8738,
+	0x53, 8738,
+	0x54, 8738,
+	0x55, 8738,
+	0x56, 8738,
+	0x57, 8738,
+	0x58, 8765,
+	0x59, 8765,
+	0x5a, 8765,
+	0x5b, 8765,
+	0x5c, 8765,
+	0x5d, 8765,
+	0x5e, 8765,
+	0x5f, 8765,
+	0x60, 8792,
+	0x61, 8805,
+	0x62, 8818,
+	0x63, 8837,
+	0x68, 8868,
+	0x69, 8887,
+	0x6A, 8922,
+	0x6B, 8927,
+	0x6C, 8962,
+	0x6D, 8965,
+	0x6E, 8978,
+	0x6F, 8981,
+	0x70, 8994,
+	0x71, 8999,
+	0x72, 9004,
+	0x73, 9009,
+	0x74, 9014,
+	0x75, 9019,
+	0x76, 9024,
+	0x77, 9029,
+	0x78, 9034,
+	0x79, 9039,
+	0x7A, 9044,
+	0x7B, 9049,
+	0x7C, 9054,
+	0x7D, 9059,
+	0x7E, 9064,
+	0x7F, 9069,
+	0x80, 9074,
+	0x81, 9131,
+	0x83, 9372,
+	0x84, 9613,
+	0x85, 9619,
+	0x86, 9648,
+	0x87, 9654,
+	0x88, 9683,
+	0x89, 9689,
+	0x8A, 9711,
+	0x8B, 9717,
+	0x8C, 9739,
+	0x8D, 9768,
+	0x8E, 9797,
+	0x8F, 9826,
+	0x90, 9862,
+	0x91, 9862,
+	0x92, 9862,
+	0x93, 9862,
+	0x94, 9862,
+	0x95, 9862,
+	0x96, 9862,
+	0x97, 9862,
+	0x98, 9888,
+	0x99, 9908,
+	0x9A, 9928,
+	0x9B, 9945,
+	0x9C, 9948,
+	0x9D, 9971,
+	0x9E, 9994,
+	0x9F, 9997,
+	0xA0, 10000,
+	0xA1, 10019,
+	0xA2, 10041,
+	0xA3, 10060,
+	0xA4, 10082,
+	0xA5, 10085,
+	0xA6, 10105,
+	0xA7, 10108,
+	0xA8, 10128,
+	0xA9, 10134,
+	0xAA, 10163,
+	0xAB, 10166,
+	0xAC, 10186,
+	0xAD, 10189,
+	0xAE, 10209,
+	0xAF, 10212,
+	0xb0, 10232,
+	0xb1, 10232,
+	0xb2, 10232,
+	0xb3, 10232,
+	0xb4, 10232,
+	0xb5, 10232,
+	0xb6, 10232,
+	0xb7, 10232,
+	0xb8, 10238,
+	0xb9, 10238,
+	0xba, 10238,
+	0xbb, 10238,
+	0xbc, 10238,
+	0xbd, 10238,
+	0xbe, 10238,
+	0xbf, 10238,
+	0xC0, 10267,
+	0xC1, 10318,
+	0xC2, 10516,
+	0xC3, 10521,
+	0xC4, 10524,
+	0xC5, 10543,
+	0xC6, 10562,
+	0xC7, 10586,
+	0xC8, 10647,
+	0xC9, 10654,
+	0xCA, 10677,
+	0xCB, 10682,
+	0xCC, 10685,
+	0xCD, 10689,
+	0xCE, 10694,
+	0xCF, 10700,
+	0xD0, 10720,
+	0xD1, 10764,
+	0xD2, 10955,
+	0xD3, 10999,
+	0xD4, 11190,
+	0xD5, 11198,
+	0xD7, 11206,
+	0xD8, 11219,
+	0xD9, 11428,
+	0xDA, 11637,
+	0xDB, 11769,
+	0xDC, 11940,
+	0xDD, 12109,
+	0xDE, 12248,
+	0xDF, 12422,
+	0xE0, 12533,
+	0xE1, 12538,
+	0xE2, 12543,
+	0xE3, 12548,
+	0xE4, 12574,
+	0xE5, 12580,
+	0xE6, 12602,
+	0xE7, 12608,
+	0xE8, 12630,
+	0xE9, 12661,
+	0xEA, 12692,
+	0xEB, 12709,
+	0xEC, 12714,
+	0xED, 12719,
+	0xEE, 12738,
+	0xEF, 12743,
+	0xF1, 12762,
+	0xF4, 12765,
+	0xF5, 12768,
+	0xF6, 12771,
+	0xF7, 12810,
+	0xF8, 12986,
+	0xF9, 12989,
+	0xFA, 12992,
+	0xFB, 12995,
+	0xFC, 12998,
+	0xFD, 13001,
+	0xFE, 13004,
+	0xFF, 13021,
+	uint16(xFail),
+	/*490*/ uint16(xSetOp), uint16(ADD),
+	/*492*/ uint16(xReadSlashR),
+	/*493*/ uint16(xArgRM8),
+	/*494*/ uint16(xArgR8),
+	/*495*/ uint16(xMatch),
+	/*496*/ uint16(xCondIs64), 499, 515,
+	/*499*/ uint16(xCondDataSize), 503, 509, 0,
+	/*503*/ uint16(xSetOp), uint16(ADD),
+	/*505*/ uint16(xReadSlashR),
+	/*506*/ uint16(xArgRM16),
+	/*507*/ uint16(xArgR16),
+	/*508*/ uint16(xMatch),
+	/*509*/ uint16(xSetOp), uint16(ADD),
+	/*511*/ uint16(xReadSlashR),
+	/*512*/ uint16(xArgRM32),
+	/*513*/ uint16(xArgR32),
+	/*514*/ uint16(xMatch),
+	/*515*/ uint16(xCondDataSize), 503, 509, 519,
+	/*519*/ uint16(xSetOp), uint16(ADD),
+	/*521*/ uint16(xReadSlashR),
+	/*522*/ uint16(xArgRM64),
+	/*523*/ uint16(xArgR64),
+	/*524*/ uint16(xMatch),
+	/*525*/ uint16(xSetOp), uint16(ADD),
+	/*527*/ uint16(xReadSlashR),
+	/*528*/ uint16(xArgR8),
+	/*529*/ uint16(xArgRM8),
+	/*530*/ uint16(xMatch),
+	/*531*/ uint16(xCondIs64), 534, 550,
+	/*534*/ uint16(xCondDataSize), 538, 544, 0,
+	/*538*/ uint16(xSetOp), uint16(ADD),
+	/*540*/ uint16(xReadSlashR),
+	/*541*/ uint16(xArgR16),
+	/*542*/ uint16(xArgRM16),
+	/*543*/ uint16(xMatch),
+	/*544*/ uint16(xSetOp), uint16(ADD),
+	/*546*/ uint16(xReadSlashR),
+	/*547*/ uint16(xArgR32),
+	/*548*/ uint16(xArgRM32),
+	/*549*/ uint16(xMatch),
+	/*550*/ uint16(xCondDataSize), 538, 544, 554,
+	/*554*/ uint16(xSetOp), uint16(ADD),
+	/*556*/ uint16(xReadSlashR),
+	/*557*/ uint16(xArgR64),
+	/*558*/ uint16(xArgRM64),
+	/*559*/ uint16(xMatch),
+	/*560*/ uint16(xSetOp), uint16(ADD),
+	/*562*/ uint16(xReadIb),
+	/*563*/ uint16(xArgAL),
+	/*564*/ uint16(xArgImm8u),
+	/*565*/ uint16(xMatch),
+	/*566*/ uint16(xCondIs64), 569, 585,
+	/*569*/ uint16(xCondDataSize), 573, 579, 0,
+	/*573*/ uint16(xSetOp), uint16(ADD),
+	/*575*/ uint16(xReadIw),
+	/*576*/ uint16(xArgAX),
+	/*577*/ uint16(xArgImm16),
+	/*578*/ uint16(xMatch),
+	/*579*/ uint16(xSetOp), uint16(ADD),
+	/*581*/ uint16(xReadId),
+	/*582*/ uint16(xArgEAX),
+	/*583*/ uint16(xArgImm32),
+	/*584*/ uint16(xMatch),
+	/*585*/ uint16(xCondDataSize), 573, 579, 589,
+	/*589*/ uint16(xSetOp), uint16(ADD),
+	/*591*/ uint16(xReadId),
+	/*592*/ uint16(xArgRAX),
+	/*593*/ uint16(xArgImm32),
+	/*594*/ uint16(xMatch),
+	/*595*/ uint16(xCondIs64), 598, 0,
+	/*598*/ uint16(xSetOp), uint16(PUSH),
+	/*600*/ uint16(xArgES),
+	/*601*/ uint16(xMatch),
+	/*602*/ uint16(xCondIs64), 605, 0,
+	/*605*/ uint16(xSetOp), uint16(POP),
+	/*607*/ uint16(xArgES),
+	/*608*/ uint16(xMatch),
+	/*609*/ uint16(xSetOp), uint16(OR),
+	/*611*/ uint16(xReadSlashR),
+	/*612*/ uint16(xArgRM8),
+	/*613*/ uint16(xArgR8),
+	/*614*/ uint16(xMatch),
+	/*615*/ uint16(xCondIs64), 618, 634,
+	/*618*/ uint16(xCondDataSize), 622, 628, 0,
+	/*622*/ uint16(xSetOp), uint16(OR),
+	/*624*/ uint16(xReadSlashR),
+	/*625*/ uint16(xArgRM16),
+	/*626*/ uint16(xArgR16),
+	/*627*/ uint16(xMatch),
+	/*628*/ uint16(xSetOp), uint16(OR),
+	/*630*/ uint16(xReadSlashR),
+	/*631*/ uint16(xArgRM32),
+	/*632*/ uint16(xArgR32),
+	/*633*/ uint16(xMatch),
+	/*634*/ uint16(xCondDataSize), 622, 628, 638,
+	/*638*/ uint16(xSetOp), uint16(OR),
+	/*640*/ uint16(xReadSlashR),
+	/*641*/ uint16(xArgRM64),
+	/*642*/ uint16(xArgR64),
+	/*643*/ uint16(xMatch),
+	/*644*/ uint16(xSetOp), uint16(OR),
+	/*646*/ uint16(xReadSlashR),
+	/*647*/ uint16(xArgR8),
+	/*648*/ uint16(xArgRM8),
+	/*649*/ uint16(xMatch),
+	/*650*/ uint16(xCondIs64), 653, 669,
+	/*653*/ uint16(xCondDataSize), 657, 663, 0,
+	/*657*/ uint16(xSetOp), uint16(OR),
+	/*659*/ uint16(xReadSlashR),
+	/*660*/ uint16(xArgR16),
+	/*661*/ uint16(xArgRM16),
+	/*662*/ uint16(xMatch),
+	/*663*/ uint16(xSetOp), uint16(OR),
+	/*665*/ uint16(xReadSlashR),
+	/*666*/ uint16(xArgR32),
+	/*667*/ uint16(xArgRM32),
+	/*668*/ uint16(xMatch),
+	/*669*/ uint16(xCondDataSize), 657, 663, 673,
+	/*673*/ uint16(xSetOp), uint16(OR),
+	/*675*/ uint16(xReadSlashR),
+	/*676*/ uint16(xArgR64),
+	/*677*/ uint16(xArgRM64),
+	/*678*/ uint16(xMatch),
+	/*679*/ uint16(xSetOp), uint16(OR),
+	/*681*/ uint16(xReadIb),
+	/*682*/ uint16(xArgAL),
+	/*683*/ uint16(xArgImm8u),
+	/*684*/ uint16(xMatch),
+	/*685*/ uint16(xCondIs64), 688, 704,
+	/*688*/ uint16(xCondDataSize), 692, 698, 0,
+	/*692*/ uint16(xSetOp), uint16(OR),
+	/*694*/ uint16(xReadIw),
+	/*695*/ uint16(xArgAX),
+	/*696*/ uint16(xArgImm16),
+	/*697*/ uint16(xMatch),
+	/*698*/ uint16(xSetOp), uint16(OR),
+	/*700*/ uint16(xReadId),
+	/*701*/ uint16(xArgEAX),
+	/*702*/ uint16(xArgImm32),
+	/*703*/ uint16(xMatch),
+	/*704*/ uint16(xCondDataSize), 692, 698, 708,
+	/*708*/ uint16(xSetOp), uint16(OR),
+	/*710*/ uint16(xReadId),
+	/*711*/ uint16(xArgRAX),
+	/*712*/ uint16(xArgImm32),
+	/*713*/ uint16(xMatch),
+	/*714*/ uint16(xCondIs64), 717, 0,
+	/*717*/ uint16(xSetOp), uint16(PUSH),
+	/*719*/ uint16(xArgCS),
+	/*720*/ uint16(xMatch),
+	/*721*/ uint16(xCondByte), 228,
+	0x00, 1180,
+	0x01, 1237,
+	0x02, 1345,
+	0x03, 1367,
+	0x05, 1389,
+	0x06, 1395,
+	0x07, 1398,
+	0x08, 1404,
+	0x09, 1407,
+	0x0B, 1410,
+	0x0D, 1413,
+	0x10, 1426,
+	0x11, 1460,
+	0x12, 1494,
+	0x13, 1537,
+	0x14, 1555,
+	0x15, 1573,
+	0x16, 1591,
+	0x17, 1626,
+	0x18, 1644,
+	0x1F, 1669,
+	0x20, 1690,
+	0x21, 1705,
+	0x22, 1720,
+	0x23, 1735,
+	0x24, 1750,
+	0x26, 1765,
+	0x28, 1780,
+	0x29, 1798,
+	0x2A, 1816,
+	0x2B, 1903,
+	0x2C, 1937,
+	0x2D, 2024,
+	0x2E, 2111,
+	0x2F, 2129,
+	0x30, 2147,
+	0x31, 2150,
+	0x32, 2153,
+	0x33, 2156,
+	0x34, 2159,
+	0x35, 2162,
+	0x38, 2172,
+	0x3A, 3073,
+	0x40, 3484,
+	0x41, 3513,
+	0x42, 3542,
+	0x43, 3571,
+	0x44, 3600,
+	0x45, 3629,
+	0x46, 3658,
+	0x47, 3687,
+	0x48, 3716,
+	0x49, 3745,
+	0x4A, 3774,
+	0x4B, 3803,
+	0x4C, 3832,
+	0x4D, 3861,
+	0x4E, 3890,
+	0x4F, 3919,
+	0x50, 3948,
+	0x51, 3966,
+	0x52, 4000,
+	0x53, 4018,
+	0x54, 4036,
+	0x55, 4054,
+	0x56, 4072,
+	0x57, 4090,
+	0x58, 4108,
+	0x59, 4142,
+	0x5A, 4176,
+	0x5B, 4210,
+	0x5C, 4236,
+	0x5D, 4270,
+	0x5E, 4304,
+	0x5F, 4338,
+	0x60, 4372,
+	0x61, 4390,
+	0x62, 4408,
+	0x63, 4426,
+	0x64, 4444,
+	0x65, 4462,
+	0x66, 4480,
+	0x67, 4498,
+	0x68, 4516,
+	0x69, 4534,
+	0x6A, 4552,
+	0x6B, 4570,
+	0x6C, 4588,
+	0x6D, 4598,
+	0x6E, 4608,
+	0x6F, 4675,
+	0x70, 4701,
+	0x71, 4743,
+	0x72, 4806,
+	0x73, 4869,
+	0x74, 4934,
+	0x75, 4952,
+	0x76, 4970,
+	0x77, 4988,
+	0x7C, 4991,
+	0x7D, 5009,
+	0x7E, 5027,
+	0x7F, 5104,
+	0x80, 5130,
+	0x81, 5161,
+	0x82, 5192,
+	0x83, 5223,
+	0x84, 5254,
+	0x85, 5285,
+	0x86, 5316,
+	0x87, 5347,
+	0x88, 5378,
+	0x89, 5409,
+	0x8A, 5440,
+	0x8B, 5471,
+	0x8C, 5502,
+	0x8D, 5533,
+	0x8E, 5564,
+	0x8F, 5595,
+	0x90, 5626,
+	0x91, 5631,
+	0x92, 5636,
+	0x93, 5641,
+	0x94, 5646,
+	0x95, 5651,
+	0x96, 5656,
+	0x97, 5661,
+	0x98, 5666,
+	0x99, 5671,
+	0x9A, 5676,
+	0x9B, 5681,
+	0x9C, 5686,
+	0x9D, 5691,
+	0x9E, 5696,
+	0x9F, 5701,
+	0xA0, 5706,
+	0xA1, 5710,
+	0xA2, 5737,
+	0xA3, 5740,
+	0xA4, 5769,
+	0xA5, 5804,
+	0xA8, 5836,
+	0xA9, 5840,
+	0xAA, 5867,
+	0xAB, 5870,
+	0xAC, 5899,
+	0xAD, 5934,
+	0xAE, 5966,
+	0xAF, 6224,
+	0xB0, 6253,
+	0xB1, 6259,
+	0xB2, 6288,
+	0xB3, 6317,
+	0xB4, 6346,
+	0xB5, 6375,
+	0xB6, 6404,
+	0xB7, 6433,
+	0xB8, 6462,
+	0xB9, 6499,
+	0xBA, 6502,
+	0xBB, 6627,
+	0xBC, 6656,
+	0xBD, 6723,
+	0xBE, 6790,
+	0xBF, 6819,
+	0xC0, 6848,
+	0xC1, 6854,
+	0xC2, 6883,
+	0xC3, 6925,
+	0xC4, 6954,
+	0xC5, 6976,
+	0xC6, 6998,
+	0xC7, 7020,
+	0xc8, 7149,
+	0xc9, 7149,
+	0xca, 7149,
+	0xcb, 7149,
+	0xcc, 7149,
+	0xcd, 7149,
+	0xce, 7149,
+	0xcf, 7149,
+	0xD0, 7172,
+	0xD1, 7190,
+	0xD2, 7208,
+	0xD3, 7226,
+	0xD4, 7244,
+	0xD5, 7262,
+	0xD6, 7280,
+	0xD7, 7306,
+	0xD8, 7324,
+	0xD9, 7342,
+	0xDA, 7360,
+	0xDB, 7378,
+	0xDC, 7396,
+	0xDD, 7414,
+	0xDE, 7432,
+	0xDF, 7450,
+	0xE0, 7468,
+	0xE1, 7486,
+	0xE2, 7504,
+	0xE3, 7522,
+	0xE4, 7540,
+	0xE5, 7558,
+	0xE6, 7576,
+	0xE7, 7602,
+	0xE8, 7620,
+	0xE9, 7638,
+	0xEA, 7656,
+	0xEB, 7674,
+	0xEC, 7692,
+	0xED, 7710,
+	0xEE, 7728,
+	0xEF, 7746,
+	0xF0, 7764,
+	0xF1, 7774,
+	0xF2, 7792,
+	0xF3, 7810,
+	0xF4, 7828,
+	0xF5, 7846,
+	0xF6, 7864,
+	0xF7, 7882,
+	0xF8, 7900,
+	0xF9, 7918,
+	0xFA, 7936,
+	0xFB, 7954,
+	0xFC, 7972,
+	0xFD, 7990,
+	0xFE, 8008,
+	uint16(xFail),
+	/*1180*/ uint16(xCondSlashR),
+	1189, // 0
+	1205, // 1
+	1221, // 2
+	1225, // 3
+	1229, // 4
+	1233, // 5
+	0,    // 6
+	0,    // 7
+	/*1189*/ uint16(xCondDataSize), 1193, 1197, 1201,
+	/*1193*/ uint16(xSetOp), uint16(SLDT),
+	/*1195*/ uint16(xArgRM16),
+	/*1196*/ uint16(xMatch),
+	/*1197*/ uint16(xSetOp), uint16(SLDT),
+	/*1199*/ uint16(xArgR32M16),
+	/*1200*/ uint16(xMatch),
+	/*1201*/ uint16(xSetOp), uint16(SLDT),
+	/*1203*/ uint16(xArgR64M16),
+	/*1204*/ uint16(xMatch),
+	/*1205*/ uint16(xCondDataSize), 1209, 1213, 1217,
+	/*1209*/ uint16(xSetOp), uint16(STR),
+	/*1211*/ uint16(xArgRM16),
+	/*1212*/ uint16(xMatch),
+	/*1213*/ uint16(xSetOp), uint16(STR),
+	/*1215*/ uint16(xArgR32M16),
+	/*1216*/ uint16(xMatch),
+	/*1217*/ uint16(xSetOp), uint16(STR),
+	/*1219*/ uint16(xArgR64M16),
+	/*1220*/ uint16(xMatch),
+	/*1221*/ uint16(xSetOp), uint16(LLDT),
+	/*1223*/ uint16(xArgRM16),
+	/*1224*/ uint16(xMatch),
+	/*1225*/ uint16(xSetOp), uint16(LTR),
+	/*1227*/ uint16(xArgRM16),
+	/*1228*/ uint16(xMatch),
+	/*1229*/ uint16(xSetOp), uint16(VERR),
+	/*1231*/ uint16(xArgRM16),
+	/*1232*/ uint16(xMatch),
+	/*1233*/ uint16(xSetOp), uint16(VERW),
+	/*1235*/ uint16(xArgRM16),
+	/*1236*/ uint16(xMatch),
+	/*1237*/ uint16(xCondByte), 8,
+	0xC8, 1318,
+	0xC9, 1321,
+	0xD0, 1324,
+	0xD1, 1327,
+	0xD5, 1330,
+	0xD6, 1333,
+	0xF8, 1336,
+	0xF9, 1342,
+	/*1255*/ uint16(xCondSlashR),
+	1264, // 0
+	1268, // 1
+	1272, // 2
+	1283, // 3
+	1294, // 4
+	0,    // 5
+	1310, // 6
+	1314, // 7
+	/*1264*/ uint16(xSetOp), uint16(SGDT),
+	/*1266*/ uint16(xArgM),
+	/*1267*/ uint16(xMatch),
+	/*1268*/ uint16(xSetOp), uint16(SIDT),
+	/*1270*/ uint16(xArgM),
+	/*1271*/ uint16(xMatch),
+	/*1272*/ uint16(xCondIs64), 1275, 1279,
+	/*1275*/ uint16(xSetOp), uint16(LGDT),
+	/*1277*/ uint16(xArgM16and32),
+	/*1278*/ uint16(xMatch),
+	/*1279*/ uint16(xSetOp), uint16(LGDT),
+	/*1281*/ uint16(xArgM16and64),
+	/*1282*/ uint16(xMatch),
+	/*1283*/ uint16(xCondIs64), 1286, 1290,
+	/*1286*/ uint16(xSetOp), uint16(LIDT),
+	/*1288*/ uint16(xArgM16and32),
+	/*1289*/ uint16(xMatch),
+	/*1290*/ uint16(xSetOp), uint16(LIDT),
+	/*1292*/ uint16(xArgM16and64),
+	/*1293*/ uint16(xMatch),
+	/*1294*/ uint16(xCondDataSize), 1298, 1302, 1306,
+	/*1298*/ uint16(xSetOp), uint16(SMSW),
+	/*1300*/ uint16(xArgRM16),
+	/*1301*/ uint16(xMatch),
+	/*1302*/ uint16(xSetOp), uint16(SMSW),
+	/*1304*/ uint16(xArgR32M16),
+	/*1305*/ uint16(xMatch),
+	/*1306*/ uint16(xSetOp), uint16(SMSW),
+	/*1308*/ uint16(xArgR64M16),
+	/*1309*/ uint16(xMatch),
+	/*1310*/ uint16(xSetOp), uint16(LMSW),
+	/*1312*/ uint16(xArgRM16),
+	/*1313*/ uint16(xMatch),
+	/*1314*/ uint16(xSetOp), uint16(INVLPG),
+	/*1316*/ uint16(xArgM),
+	/*1317*/ uint16(xMatch),
+	/*1318*/ uint16(xSetOp), uint16(MONITOR),
+	/*1320*/ uint16(xMatch),
+	/*1321*/ uint16(xSetOp), uint16(MWAIT),
+	/*1323*/ uint16(xMatch),
+	/*1324*/ uint16(xSetOp), uint16(XGETBV),
+	/*1326*/ uint16(xMatch),
+	/*1327*/ uint16(xSetOp), uint16(XSETBV),
+	/*1329*/ uint16(xMatch),
+	/*1330*/ uint16(xSetOp), uint16(XEND),
+	/*1332*/ uint16(xMatch),
+	/*1333*/ uint16(xSetOp), uint16(XTEST),
+	/*1335*/ uint16(xMatch),
+	/*1336*/ uint16(xCondIs64), 0, 1339,
+	/*1339*/ uint16(xSetOp), uint16(SWAPGS),
+	/*1341*/ uint16(xMatch),
+	/*1342*/ uint16(xSetOp), uint16(RDTSCP),
+	/*1344*/ uint16(xMatch),
+	/*1345*/ uint16(xCondDataSize), 1349, 1355, 1361,
+	/*1349*/ uint16(xSetOp), uint16(LAR),
+	/*1351*/ uint16(xReadSlashR),
+	/*1352*/ uint16(xArgR16),
+	/*1353*/ uint16(xArgRM16),
+	/*1354*/ uint16(xMatch),
+	/*1355*/ uint16(xSetOp), uint16(LAR),
+	/*1357*/ uint16(xReadSlashR),
+	/*1358*/ uint16(xArgR32),
+	/*1359*/ uint16(xArgR32M16),
+	/*1360*/ uint16(xMatch),
+	/*1361*/ uint16(xSetOp), uint16(LAR),
+	/*1363*/ uint16(xReadSlashR),
+	/*1364*/ uint16(xArgR64),
+	/*1365*/ uint16(xArgR64M16),
+	/*1366*/ uint16(xMatch),
+	/*1367*/ uint16(xCondDataSize), 1371, 1377, 1383,
+	/*1371*/ uint16(xSetOp), uint16(LSL),
+	/*1373*/ uint16(xReadSlashR),
+	/*1374*/ uint16(xArgR16),
+	/*1375*/ uint16(xArgRM16),
+	/*1376*/ uint16(xMatch),
+	/*1377*/ uint16(xSetOp), uint16(LSL),
+	/*1379*/ uint16(xReadSlashR),
+	/*1380*/ uint16(xArgR32),
+	/*1381*/ uint16(xArgR32M16),
+	/*1382*/ uint16(xMatch),
+	/*1383*/ uint16(xSetOp), uint16(LSL),
+	/*1385*/ uint16(xReadSlashR),
+	/*1386*/ uint16(xArgR64),
+	/*1387*/ uint16(xArgR32M16),
+	/*1388*/ uint16(xMatch),
+	/*1389*/ uint16(xCondIs64), 0, 1392,
+	/*1392*/ uint16(xSetOp), uint16(SYSCALL),
+	/*1394*/ uint16(xMatch),
+	/*1395*/ uint16(xSetOp), uint16(CLTS),
+	/*1397*/ uint16(xMatch),
+	/*1398*/ uint16(xCondIs64), 0, 1401,
+	/*1401*/ uint16(xSetOp), uint16(SYSRET),
+	/*1403*/ uint16(xMatch),
+	/*1404*/ uint16(xSetOp), uint16(INVD),
+	/*1406*/ uint16(xMatch),
+	/*1407*/ uint16(xSetOp), uint16(WBINVD),
+	/*1409*/ uint16(xMatch),
+	/*1410*/ uint16(xSetOp), uint16(UD2),
+	/*1412*/ uint16(xMatch),
+	/*1413*/ uint16(xCondSlashR),
+	0,    // 0
+	1422, // 1
+	0,    // 2
+	0,    // 3
+	0,    // 4
+	0,    // 5
+	0,    // 6
+	0,    // 7
+	/*1422*/ uint16(xSetOp), uint16(PREFETCHW),
+	/*1424*/ uint16(xArgM8),
+	/*1425*/ uint16(xMatch),
+	/*1426*/ uint16(xCondPrefix), 4,
+	0xF3, 1454,
+	0xF2, 1448,
+	0x66, 1442,
+	0x0, 1436,
+	/*1436*/ uint16(xSetOp), uint16(MOVUPS),
+	/*1438*/ uint16(xReadSlashR),
+	/*1439*/ uint16(xArgXmm1),
+	/*1440*/ uint16(xArgXmm2M128),
+	/*1441*/ uint16(xMatch),
+	/*1442*/ uint16(xSetOp), uint16(MOVUPD),
+	/*1444*/ uint16(xReadSlashR),
+	/*1445*/ uint16(xArgXmm1),
+	/*1446*/ uint16(xArgXmm2M128),
+	/*1447*/ uint16(xMatch),
+	/*1448*/ uint16(xSetOp), uint16(MOVSD_XMM),
+	/*1450*/ uint16(xReadSlashR),
+	/*1451*/ uint16(xArgXmm1),
+	/*1452*/ uint16(xArgXmm2M64),
+	/*1453*/ uint16(xMatch),
+	/*1454*/ uint16(xSetOp), uint16(MOVSS),
+	/*1456*/ uint16(xReadSlashR),
+	/*1457*/ uint16(xArgXmm1),
+	/*1458*/ uint16(xArgXmm2M32),
+	/*1459*/ uint16(xMatch),
+	/*1460*/ uint16(xCondPrefix), 4,
+	0xF3, 1488,
+	0xF2, 1482,
+	0x66, 1476,
+	0x0, 1470,
+	/*1470*/ uint16(xSetOp), uint16(MOVUPS),
+	/*1472*/ uint16(xReadSlashR),
+	/*1473*/ uint16(xArgXmm2M128),
+	/*1474*/ uint16(xArgXmm1),
+	/*1475*/ uint16(xMatch),
+	/*1476*/ uint16(xSetOp), uint16(MOVUPD),
+	/*1478*/ uint16(xReadSlashR),
+	/*1479*/ uint16(xArgXmm2M128),
+	/*1480*/ uint16(xArgXmm),
+	/*1481*/ uint16(xMatch),
+	/*1482*/ uint16(xSetOp), uint16(MOVSD_XMM),
+	/*1484*/ uint16(xReadSlashR),
+	/*1485*/ uint16(xArgXmm2M64),
+	/*1486*/ uint16(xArgXmm1),
+	/*1487*/ uint16(xMatch),
+	/*1488*/ uint16(xSetOp), uint16(MOVSS),
+	/*1490*/ uint16(xReadSlashR),
+	/*1491*/ uint16(xArgXmm2M32),
+	/*1492*/ uint16(xArgXmm),
+	/*1493*/ uint16(xMatch),
+	/*1494*/ uint16(xCondPrefix), 4,
+	0xF3, 1531,
+	0xF2, 1525,
+	0x66, 1519,
+	0x0, 1504,
+	/*1504*/ uint16(xCondIsMem), 1507, 1513,
+	/*1507*/ uint16(xSetOp), uint16(MOVHLPS),
+	/*1509*/ uint16(xReadSlashR),
+	/*1510*/ uint16(xArgXmm1),
+	/*1511*/ uint16(xArgXmm2),
+	/*1512*/ uint16(xMatch),
+	/*1513*/ uint16(xSetOp), uint16(MOVLPS),
+	/*1515*/ uint16(xReadSlashR),
+	/*1516*/ uint16(xArgXmm),
+	/*1517*/ uint16(xArgM64),
+	/*1518*/ uint16(xMatch),
+	/*1519*/ uint16(xSetOp), uint16(MOVLPD),
+	/*1521*/ uint16(xReadSlashR),
+	/*1522*/ uint16(xArgXmm),
+	/*1523*/ uint16(xArgXmm2M64),
+	/*1524*/ uint16(xMatch),
+	/*1525*/ uint16(xSetOp), uint16(MOVDDUP),
+	/*1527*/ uint16(xReadSlashR),
+	/*1528*/ uint16(xArgXmm1),
+	/*1529*/ uint16(xArgXmm2M64),
+	/*1530*/ uint16(xMatch),
+	/*1531*/ uint16(xSetOp), uint16(MOVSLDUP),
+	/*1533*/ uint16(xReadSlashR),
+	/*1534*/ uint16(xArgXmm1),
+	/*1535*/ uint16(xArgXmm2M128),
+	/*1536*/ uint16(xMatch),
+	/*1537*/ uint16(xCondPrefix), 2,
+	0x66, 1549,
+	0x0, 1543,
+	/*1543*/ uint16(xSetOp), uint16(MOVLPS),
+	/*1545*/ uint16(xReadSlashR),
+	/*1546*/ uint16(xArgM64),
+	/*1547*/ uint16(xArgXmm),
+	/*1548*/ uint16(xMatch),
+	/*1549*/ uint16(xSetOp), uint16(MOVLPD),
+	/*1551*/ uint16(xReadSlashR),
+	/*1552*/ uint16(xArgXmm2M64),
+	/*1553*/ uint16(xArgXmm),
+	/*1554*/ uint16(xMatch),
+	/*1555*/ uint16(xCondPrefix), 2,
+	0x66, 1567,
+	0x0, 1561,
+	/*1561*/ uint16(xSetOp), uint16(UNPCKLPS),
+	/*1563*/ uint16(xReadSlashR),
+	/*1564*/ uint16(xArgXmm1),
+	/*1565*/ uint16(xArgXmm2M128),
+	/*1566*/ uint16(xMatch),
+	/*1567*/ uint16(xSetOp), uint16(UNPCKLPD),
+	/*1569*/ uint16(xReadSlashR),
+	/*1570*/ uint16(xArgXmm1),
+	/*1571*/ uint16(xArgXmm2M128),
+	/*1572*/ uint16(xMatch),
+	/*1573*/ uint16(xCondPrefix), 2,
+	0x66, 1585,
+	0x0, 1579,
+	/*1579*/ uint16(xSetOp), uint16(UNPCKHPS),
+	/*1581*/ uint16(xReadSlashR),
+	/*1582*/ uint16(xArgXmm1),
+	/*1583*/ uint16(xArgXmm2M128),
+	/*1584*/ uint16(xMatch),
+	/*1585*/ uint16(xSetOp), uint16(UNPCKHPD),
+	/*1587*/ uint16(xReadSlashR),
+	/*1588*/ uint16(xArgXmm1),
+	/*1589*/ uint16(xArgXmm2M128),
+	/*1590*/ uint16(xMatch),
+	/*1591*/ uint16(xCondPrefix), 3,
+	0xF3, 1620,
+	0x66, 1614,
+	0x0, 1599,
+	/*1599*/ uint16(xCondIsMem), 1602, 1608,
+	/*1602*/ uint16(xSetOp), uint16(MOVLHPS),
+	/*1604*/ uint16(xReadSlashR),
+	/*1605*/ uint16(xArgXmm1),
+	/*1606*/ uint16(xArgXmm2),
+	/*1607*/ uint16(xMatch),
+	/*1608*/ uint16(xSetOp), uint16(MOVHPS),
+	/*1610*/ uint16(xReadSlashR),
+	/*1611*/ uint16(xArgXmm),
+	/*1612*/ uint16(xArgM64),
+	/*1613*/ uint16(xMatch),
+	/*1614*/ uint16(xSetOp), uint16(MOVHPD),
+	/*1616*/ uint16(xReadSlashR),
+	/*1617*/ uint16(xArgXmm),
+	/*1618*/ uint16(xArgXmm2M64),
+	/*1619*/ uint16(xMatch),
+	/*1620*/ uint16(xSetOp), uint16(MOVSHDUP),
+	/*1622*/ uint16(xReadSlashR),
+	/*1623*/ uint16(xArgXmm1),
+	/*1624*/ uint16(xArgXmm2M128),
+	/*1625*/ uint16(xMatch),
+	/*1626*/ uint16(xCondPrefix), 2,
+	0x66, 1638,
+	0x0, 1632,
+	/*1632*/ uint16(xSetOp), uint16(MOVHPS),
+	/*1634*/ uint16(xReadSlashR),
+	/*1635*/ uint16(xArgM64),
+	/*1636*/ uint16(xArgXmm),
+	/*1637*/ uint16(xMatch),
+	/*1638*/ uint16(xSetOp), uint16(MOVHPD),
+	/*1640*/ uint16(xReadSlashR),
+	/*1641*/ uint16(xArgXmm2M64),
+	/*1642*/ uint16(xArgXmm),
+	/*1643*/ uint16(xMatch),
+	/*1644*/ uint16(xCondSlashR),
+	1653, // 0
+	1657, // 1
+	1661, // 2
+	1665, // 3
+	0,    // 4
+	0,    // 5
+	0,    // 6
+	0,    // 7
+	/*1653*/ uint16(xSetOp), uint16(PREFETCHNTA),
+	/*1655*/ uint16(xArgM8),
+	/*1656*/ uint16(xMatch),
+	/*1657*/ uint16(xSetOp), uint16(PREFETCHT0),
+	/*1659*/ uint16(xArgM8),
+	/*1660*/ uint16(xMatch),
+	/*1661*/ uint16(xSetOp), uint16(PREFETCHT1),
+	/*1663*/ uint16(xArgM8),
+	/*1664*/ uint16(xMatch),
+	/*1665*/ uint16(xSetOp), uint16(PREFETCHT2),
+	/*1667*/ uint16(xArgM8),
+	/*1668*/ uint16(xMatch),
+	/*1669*/ uint16(xCondSlashR),
+	1678, // 0
+	0,    // 1
+	0,    // 2
+	0,    // 3
+	0,    // 4
+	0,    // 5
+	0,    // 6
+	0,    // 7
+	/*1678*/ uint16(xCondDataSize), 1682, 1686, 0,
+	/*1682*/ uint16(xSetOp), uint16(NOP),
+	/*1684*/ uint16(xArgRM16),
+	/*1685*/ uint16(xMatch),
+	/*1686*/ uint16(xSetOp), uint16(NOP),
+	/*1688*/ uint16(xArgRM32),
+	/*1689*/ uint16(xMatch),
+	/*1690*/ uint16(xCondIs64), 1693, 1699,
+	/*1693*/ uint16(xSetOp), uint16(MOV),
+	/*1695*/ uint16(xReadSlashR),
+	/*1696*/ uint16(xArgRmf32),
+	/*1697*/ uint16(xArgCR0dashCR7),
+	/*1698*/ uint16(xMatch),
+	/*1699*/ uint16(xSetOp), uint16(MOV),
+	/*1701*/ uint16(xReadSlashR),
+	/*1702*/ uint16(xArgRmf64),
+	/*1703*/ uint16(xArgCR0dashCR7),
+	/*1704*/ uint16(xMatch),
+	/*1705*/ uint16(xCondIs64), 1708, 1714,
+	/*1708*/ uint16(xSetOp), uint16(MOV),
+	/*1710*/ uint16(xReadSlashR),
+	/*1711*/ uint16(xArgRmf32),
+	/*1712*/ uint16(xArgDR0dashDR7),
+	/*1713*/ uint16(xMatch),
+	/*1714*/ uint16(xSetOp), uint16(MOV),
+	/*1716*/ uint16(xReadSlashR),
+	/*1717*/ uint16(xArgRmf64),
+	/*1718*/ uint16(xArgDR0dashDR7),
+	/*1719*/ uint16(xMatch),
+	/*1720*/ uint16(xCondIs64), 1723, 1729,
+	/*1723*/ uint16(xSetOp), uint16(MOV),
+	/*1725*/ uint16(xReadSlashR),
+	/*1726*/ uint16(xArgCR0dashCR7),
+	/*1727*/ uint16(xArgRmf32),
+	/*1728*/ uint16(xMatch),
+	/*1729*/ uint16(xSetOp), uint16(MOV),
+	/*1731*/ uint16(xReadSlashR),
+	/*1732*/ uint16(xArgCR0dashCR7),
+	/*1733*/ uint16(xArgRmf64),
+	/*1734*/ uint16(xMatch),
+	/*1735*/ uint16(xCondIs64), 1738, 1744,
+	/*1738*/ uint16(xSetOp), uint16(MOV),
+	/*1740*/ uint16(xReadSlashR),
+	/*1741*/ uint16(xArgDR0dashDR7),
+	/*1742*/ uint16(xArgRmf32),
+	/*1743*/ uint16(xMatch),
+	/*1744*/ uint16(xSetOp), uint16(MOV),
+	/*1746*/ uint16(xReadSlashR),
+	/*1747*/ uint16(xArgDR0dashDR7),
+	/*1748*/ uint16(xArgRmf64),
+	/*1749*/ uint16(xMatch),
+	/*1750*/ uint16(xCondIs64), 1753, 1759,
+	/*1753*/ uint16(xSetOp), uint16(MOV),
+	/*1755*/ uint16(xReadSlashR),
+	/*1756*/ uint16(xArgRmf32),
+	/*1757*/ uint16(xArgTR0dashTR7),
+	/*1758*/ uint16(xMatch),
+	/*1759*/ uint16(xSetOp), uint16(MOV),
+	/*1761*/ uint16(xReadSlashR),
+	/*1762*/ uint16(xArgRmf64),
+	/*1763*/ uint16(xArgTR0dashTR7),
+	/*1764*/ uint16(xMatch),
+	/*1765*/ uint16(xCondIs64), 1768, 1774,
+	/*1768*/ uint16(xSetOp), uint16(MOV),
+	/*1770*/ uint16(xReadSlashR),
+	/*1771*/ uint16(xArgTR0dashTR7),
+	/*1772*/ uint16(xArgRmf32),
+	/*1773*/ uint16(xMatch),
+	/*1774*/ uint16(xSetOp), uint16(MOV),
+	/*1776*/ uint16(xReadSlashR),
+	/*1777*/ uint16(xArgTR0dashTR7),
+	/*1778*/ uint16(xArgRmf64),
+	/*1779*/ uint16(xMatch),
+	/*1780*/ uint16(xCondPrefix), 2,
+	0x66, 1792,
+	0x0, 1786,
+	/*1786*/ uint16(xSetOp), uint16(MOVAPS),
+	/*1788*/ uint16(xReadSlashR),
+	/*1789*/ uint16(xArgXmm1),
+	/*1790*/ uint16(xArgXmm2M128),
+	/*1791*/ uint16(xMatch),
+	/*1792*/ uint16(xSetOp), uint16(MOVAPD),
+	/*1794*/ uint16(xReadSlashR),
+	/*1795*/ uint16(xArgXmm1),
+	/*1796*/ uint16(xArgXmm2M128),
+	/*1797*/ uint16(xMatch),
+	/*1798*/ uint16(xCondPrefix), 2,
+	0x66, 1810,
+	0x0, 1804,
+	/*1804*/ uint16(xSetOp), uint16(MOVAPS),
+	/*1806*/ uint16(xReadSlashR),
+	/*1807*/ uint16(xArgXmm2M128),
+	/*1808*/ uint16(xArgXmm1),
+	/*1809*/ uint16(xMatch),
+	/*1810*/ uint16(xSetOp), uint16(MOVAPD),
+	/*1812*/ uint16(xReadSlashR),
+	/*1813*/ uint16(xArgXmm2M128),
+	/*1814*/ uint16(xArgXmm1),
+	/*1815*/ uint16(xMatch),
+	/*1816*/ uint16(xCondIs64), 1819, 1873,
+	/*1819*/ uint16(xCondPrefix), 4,
+	0xF3, 1857,
+	0xF2, 1841,
+	0x66, 1835,
+	0x0, 1829,
+	/*1829*/ uint16(xSetOp), uint16(CVTPI2PS),
+	/*1831*/ uint16(xReadSlashR),
+	/*1832*/ uint16(xArgXmm),
+	/*1833*/ uint16(xArgMmM64),
+	/*1834*/ uint16(xMatch),
+	/*1835*/ uint16(xSetOp), uint16(CVTPI2PD),
+	/*1837*/ uint16(xReadSlashR),
+	/*1838*/ uint16(xArgXmm),
+	/*1839*/ uint16(xArgMmM64),
+	/*1840*/ uint16(xMatch),
+	/*1841*/ uint16(xCondDataSize), 1845, 1851, 0,
+	/*1845*/ uint16(xSetOp), uint16(CVTSI2SD),
+	/*1847*/ uint16(xReadSlashR),
+	/*1848*/ uint16(xArgXmm),
+	/*1849*/ uint16(xArgRM32),
+	/*1850*/ uint16(xMatch),
+	/*1851*/ uint16(xSetOp), uint16(CVTSI2SD),
+	/*1853*/ uint16(xReadSlashR),
+	/*1854*/ uint16(xArgXmm),
+	/*1855*/ uint16(xArgRM32),
+	/*1856*/ uint16(xMatch),
+	/*1857*/ uint16(xCondDataSize), 1861, 1867, 0,
+	/*1861*/ uint16(xSetOp), uint16(CVTSI2SS),
+	/*1863*/ uint16(xReadSlashR),
+	/*1864*/ uint16(xArgXmm),
+	/*1865*/ uint16(xArgRM32),
+	/*1866*/ uint16(xMatch),
+	/*1867*/ uint16(xSetOp), uint16(CVTSI2SS),
+	/*1869*/ uint16(xReadSlashR),
+	/*1870*/ uint16(xArgXmm),
+	/*1871*/ uint16(xArgRM32),
+	/*1872*/ uint16(xMatch),
+	/*1873*/ uint16(xCondPrefix), 4,
+	0xF3, 1893,
+	0xF2, 1883,
+	0x66, 1835,
+	0x0, 1829,
+	/*1883*/ uint16(xCondDataSize), 1845, 1851, 1887,
+	/*1887*/ uint16(xSetOp), uint16(CVTSI2SD),
+	/*1889*/ uint16(xReadSlashR),
+	/*1890*/ uint16(xArgXmm),
+	/*1891*/ uint16(xArgRM64),
+	/*1892*/ uint16(xMatch),
+	/*1893*/ uint16(xCondDataSize), 1861, 1867, 1897,
+	/*1897*/ uint16(xSetOp), uint16(CVTSI2SS),
+	/*1899*/ uint16(xReadSlashR),
+	/*1900*/ uint16(xArgXmm),
+	/*1901*/ uint16(xArgRM64),
+	/*1902*/ uint16(xMatch),
+	/*1903*/ uint16(xCondPrefix), 4,
+	0xF3, 1931,
+	0xF2, 1925,
+	0x66, 1919,
+	0x0, 1913,
+	/*1913*/ uint16(xSetOp), uint16(MOVNTPS),
+	/*1915*/ uint16(xReadSlashR),
+	/*1916*/ uint16(xArgM128),
+	/*1917*/ uint16(xArgXmm),
+	/*1918*/ uint16(xMatch),
+	/*1919*/ uint16(xSetOp), uint16(MOVNTPD),
+	/*1921*/ uint16(xReadSlashR),
+	/*1922*/ uint16(xArgM128),
+	/*1923*/ uint16(xArgXmm),
+	/*1924*/ uint16(xMatch),
+	/*1925*/ uint16(xSetOp), uint16(MOVNTSD),
+	/*1927*/ uint16(xReadSlashR),
+	/*1928*/ uint16(xArgM64),
+	/*1929*/ uint16(xArgXmm),
+	/*1930*/ uint16(xMatch),
+	/*1931*/ uint16(xSetOp), uint16(MOVNTSS),
+	/*1933*/ uint16(xReadSlashR),
+	/*1934*/ uint16(xArgM32),
+	/*1935*/ uint16(xArgXmm),
+	/*1936*/ uint16(xMatch),
+	/*1937*/ uint16(xCondIs64), 1940, 1994,
+	/*1940*/ uint16(xCondPrefix), 4,
+	0xF3, 1978,
+	0xF2, 1962,
+	0x66, 1956,
+	0x0, 1950,
+	/*1950*/ uint16(xSetOp), uint16(CVTTPS2PI),
+	/*1952*/ uint16(xReadSlashR),
+	/*1953*/ uint16(xArgMm),
+	/*1954*/ uint16(xArgXmmM64),
+	/*1955*/ uint16(xMatch),
+	/*1956*/ uint16(xSetOp), uint16(CVTTPD2PI),
+	/*1958*/ uint16(xReadSlashR),
+	/*1959*/ uint16(xArgMm),
+	/*1960*/ uint16(xArgXmmM128),
+	/*1961*/ uint16(xMatch),
+	/*1962*/ uint16(xCondDataSize), 1966, 1972, 0,
+	/*1966*/ uint16(xSetOp), uint16(CVTTSD2SI),
+	/*1968*/ uint16(xReadSlashR),
+	/*1969*/ uint16(xArgR32),
+	/*1970*/ uint16(xArgXmmM64),
+	/*1971*/ uint16(xMatch),
+	/*1972*/ uint16(xSetOp), uint16(CVTTSD2SI),
+	/*1974*/ uint16(xReadSlashR),
+	/*1975*/ uint16(xArgR32),
+	/*1976*/ uint16(xArgXmmM64),
+	/*1977*/ uint16(xMatch),
+	/*1978*/ uint16(xCondDataSize), 1982, 1988, 0,
+	/*1982*/ uint16(xSetOp), uint16(CVTTSS2SI),
+	/*1984*/ uint16(xReadSlashR),
+	/*1985*/ uint16(xArgR32),
+	/*1986*/ uint16(xArgXmmM32),
+	/*1987*/ uint16(xMatch),
+	/*1988*/ uint16(xSetOp), uint16(CVTTSS2SI),
+	/*1990*/ uint16(xReadSlashR),
+	/*1991*/ uint16(xArgR32),
+	/*1992*/ uint16(xArgXmmM32),
+	/*1993*/ uint16(xMatch),
+	/*1994*/ uint16(xCondPrefix), 4,
+	0xF3, 2014,
+	0xF2, 2004,
+	0x66, 1956,
+	0x0, 1950,
+	/*2004*/ uint16(xCondDataSize), 1966, 1972, 2008,
+	/*2008*/ uint16(xSetOp), uint16(CVTTSD2SI),
+	/*2010*/ uint16(xReadSlashR),
+	/*2011*/ uint16(xArgR64),
+	/*2012*/ uint16(xArgXmmM64),
+	/*2013*/ uint16(xMatch),
+	/*2014*/ uint16(xCondDataSize), 1982, 1988, 2018,
+	/*2018*/ uint16(xSetOp), uint16(CVTTSS2SI),
+	/*2020*/ uint16(xReadSlashR),
+	/*2021*/ uint16(xArgR64),
+	/*2022*/ uint16(xArgXmmM32),
+	/*2023*/ uint16(xMatch),
+	/*2024*/ uint16(xCondIs64), 2027, 2081,
+	/*2027*/ uint16(xCondPrefix), 4,
+	0xF3, 2065,
+	0xF2, 2049,
+	0x66, 2043,
+	0x0, 2037,
+	/*2037*/ uint16(xSetOp), uint16(CVTPS2PI),
+	/*2039*/ uint16(xReadSlashR),
+	/*2040*/ uint16(xArgMm),
+	/*2041*/ uint16(xArgXmmM64),
+	/*2042*/ uint16(xMatch),
+	/*2043*/ uint16(xSetOp), uint16(CVTPD2PI),
+	/*2045*/ uint16(xReadSlashR),
+	/*2046*/ uint16(xArgMm),
+	/*2047*/ uint16(xArgXmmM128),
+	/*2048*/ uint16(xMatch),
+	/*2049*/ uint16(xCondDataSize), 2053, 2059, 0,
+	/*2053*/ uint16(xSetOp), uint16(CVTSD2SI),
+	/*2055*/ uint16(xReadSlashR),
+	/*2056*/ uint16(xArgR32),
+	/*2057*/ uint16(xArgXmmM64),
+	/*2058*/ uint16(xMatch),
+	/*2059*/ uint16(xSetOp), uint16(CVTSD2SI),
+	/*2061*/ uint16(xReadSlashR),
+	/*2062*/ uint16(xArgR32),
+	/*2063*/ uint16(xArgXmmM64),
+	/*2064*/ uint16(xMatch),
+	/*2065*/ uint16(xCondDataSize), 2069, 2075, 0,
+	/*2069*/ uint16(xSetOp), uint16(CVTSS2SI),
+	/*2071*/ uint16(xReadSlashR),
+	/*2072*/ uint16(xArgR32),
+	/*2073*/ uint16(xArgXmmM32),
+	/*2074*/ uint16(xMatch),
+	/*2075*/ uint16(xSetOp), uint16(CVTSS2SI),
+	/*2077*/ uint16(xReadSlashR),
+	/*2078*/ uint16(xArgR32),
+	/*2079*/ uint16(xArgXmmM32),
+	/*2080*/ uint16(xMatch),
+	/*2081*/ uint16(xCondPrefix), 4,
+	0xF3, 2101,
+	0xF2, 2091,
+	0x66, 2043,
+	0x0, 2037,
+	/*2091*/ uint16(xCondDataSize), 2053, 2059, 2095,
+	/*2095*/ uint16(xSetOp), uint16(CVTSD2SI),
+	/*2097*/ uint16(xReadSlashR),
+	/*2098*/ uint16(xArgR64),
+	/*2099*/ uint16(xArgXmmM64),
+	/*2100*/ uint16(xMatch),
+	/*2101*/ uint16(xCondDataSize), 2069, 2075, 2105,
+	/*2105*/ uint16(xSetOp), uint16(CVTSS2SI),
+	/*2107*/ uint16(xReadSlashR),
+	/*2108*/ uint16(xArgR64),
+	/*2109*/ uint16(xArgXmmM32),
+	/*2110*/ uint16(xMatch),
+	/*2111*/ uint16(xCondPrefix), 2,
+	0x66, 2123,
+	0x0, 2117,
+	/*2117*/ uint16(xSetOp), uint16(UCOMISS),
+	/*2119*/ uint16(xReadSlashR),
+	/*2120*/ uint16(xArgXmm1),
+	/*2121*/ uint16(xArgXmm2M32),
+	/*2122*/ uint16(xMatch),
+	/*2123*/ uint16(xSetOp), uint16(UCOMISD),
+	/*2125*/ uint16(xReadSlashR),
+	/*2126*/ uint16(xArgXmm1),
+	/*2127*/ uint16(xArgXmm2M64),
+	/*2128*/ uint16(xMatch),
+	/*2129*/ uint16(xCondPrefix), 2,
+	0x66, 2141,
+	0x0, 2135,
+	/*2135*/ uint16(xSetOp), uint16(COMISS),
+	/*2137*/ uint16(xReadSlashR),
+	/*2138*/ uint16(xArgXmm1),
+	/*2139*/ uint16(xArgXmm2M32),
+	/*2140*/ uint16(xMatch),
+	/*2141*/ uint16(xSetOp), uint16(COMISD),
+	/*2143*/ uint16(xReadSlashR),
+	/*2144*/ uint16(xArgXmm1),
+	/*2145*/ uint16(xArgXmm2M64),
+	/*2146*/ uint16(xMatch),
+	/*2147*/ uint16(xSetOp), uint16(WRMSR),
+	/*2149*/ uint16(xMatch),
+	/*2150*/ uint16(xSetOp), uint16(RDTSC),
+	/*2152*/ uint16(xMatch),
+	/*2153*/ uint16(xSetOp), uint16(RDMSR),
+	/*2155*/ uint16(xMatch),
+	/*2156*/ uint16(xSetOp), uint16(RDPMC),
+	/*2158*/ uint16(xMatch),
+	/*2159*/ uint16(xSetOp), uint16(SYSENTER),
+	/*2161*/ uint16(xMatch),
+	/*2162*/ uint16(xCondDataSize), 2166, 2166, 2169,
+	/*2166*/ uint16(xSetOp), uint16(SYSEXIT),
+	/*2168*/ uint16(xMatch),
+	/*2169*/ uint16(xSetOp), uint16(SYSEXIT),
+	/*2171*/ uint16(xMatch),
+	/*2172*/ uint16(xCondByte), 54,
+	0x00, 2283,
+	0x01, 2301,
+	0x02, 2319,
+	0x03, 2337,
+	0x04, 2355,
+	0x05, 2373,
+	0x06, 2391,
+	0x07, 2409,
+	0x08, 2427,
+	0x09, 2445,
+	0x0A, 2463,
+	0x0B, 2481,
+	0x10, 2499,
+	0x14, 2510,
+	0x15, 2521,
+	0x17, 2532,
+	0x1C, 2542,
+	0x1D, 2560,
+	0x1E, 2578,
+	0x20, 2596,
+	0x21, 2606,
+	0x22, 2616,
+	0x23, 2626,
+	0x24, 2636,
+	0x25, 2646,
+	0x28, 2656,
+	0x29, 2666,
+	0x2A, 2676,
+	0x2B, 2686,
+	0x30, 2696,
+	0x31, 2706,
+	0x32, 2716,
+	0x33, 2726,
+	0x34, 2736,
+	0x35, 2746,
+	0x37, 2756,
+	0x38, 2766,
+	0x39, 2776,
+	0x3A, 2786,
+	0x3B, 2796,
+	0x3C, 2806,
+	0x3D, 2816,
+	0x3E, 2826,
+	0x3F, 2836,
+	0x40, 2846,
+	0x41, 2856,
+	0x82, 2866,
+	0xDB, 2889,
+	0xDC, 2899,
+	0xDD, 2909,
+	0xDE, 2919,
+	0xDF, 2929,
+	0xF0, 2939,
+	0xF1, 3006,
+	uint16(xFail),
+	/*2283*/ uint16(xCondPrefix), 2,
+	0x66, 2295,
+	0x0, 2289,
+	/*2289*/ uint16(xSetOp), uint16(PSHUFB),
+	/*2291*/ uint16(xReadSlashR),
+	/*2292*/ uint16(xArgMm1),
+	/*2293*/ uint16(xArgMm2M64),
+	/*2294*/ uint16(xMatch),
+	/*2295*/ uint16(xSetOp), uint16(PSHUFB),
+	/*2297*/ uint16(xReadSlashR),
+	/*2298*/ uint16(xArgXmm1),
+	/*2299*/ uint16(xArgXmm2M128),
+	/*2300*/ uint16(xMatch),
+	/*2301*/ uint16(xCondPrefix), 2,
+	0x66, 2313,
+	0x0, 2307,
+	/*2307*/ uint16(xSetOp), uint16(PHADDW),
+	/*2309*/ uint16(xReadSlashR),
+	/*2310*/ uint16(xArgMm1),
+	/*2311*/ uint16(xArgMm2M64),
+	/*2312*/ uint16(xMatch),
+	/*2313*/ uint16(xSetOp), uint16(PHADDW),
+	/*2315*/ uint16(xReadSlashR),
+	/*2316*/ uint16(xArgXmm1),
+	/*2317*/ uint16(xArgXmm2M128),
+	/*2318*/ uint16(xMatch),
+	/*2319*/ uint16(xCondPrefix), 2,
+	0x66, 2331,
+	0x0, 2325,
+	/*2325*/ uint16(xSetOp), uint16(PHADDD),
+	/*2327*/ uint16(xReadSlashR),
+	/*2328*/ uint16(xArgMm1),
+	/*2329*/ uint16(xArgMm2M64),
+	/*2330*/ uint16(xMatch),
+	/*2331*/ uint16(xSetOp), uint16(PHADDD),
+	/*2333*/ uint16(xReadSlashR),
+	/*2334*/ uint16(xArgXmm1),
+	/*2335*/ uint16(xArgXmm2M128),
+	/*2336*/ uint16(xMatch),
+	/*2337*/ uint16(xCondPrefix), 2,
+	0x66, 2349,
+	0x0, 2343,
+	/*2343*/ uint16(xSetOp), uint16(PHADDSW),
+	/*2345*/ uint16(xReadSlashR),
+	/*2346*/ uint16(xArgMm1),
+	/*2347*/ uint16(xArgMm2M64),
+	/*2348*/ uint16(xMatch),
+	/*2349*/ uint16(xSetOp), uint16(PHADDSW),
+	/*2351*/ uint16(xReadSlashR),
+	/*2352*/ uint16(xArgXmm1),
+	/*2353*/ uint16(xArgXmm2M128),
+	/*2354*/ uint16(xMatch),
+	/*2355*/ uint16(xCondPrefix), 2,
+	0x66, 2367,
+	0x0, 2361,
+	/*2361*/ uint16(xSetOp), uint16(PMADDUBSW),
+	/*2363*/ uint16(xReadSlashR),
+	/*2364*/ uint16(xArgMm1),
+	/*2365*/ uint16(xArgMm2M64),
+	/*2366*/ uint16(xMatch),
+	/*2367*/ uint16(xSetOp), uint16(PMADDUBSW),
+	/*2369*/ uint16(xReadSlashR),
+	/*2370*/ uint16(xArgXmm1),
+	/*2371*/ uint16(xArgXmm2M128),
+	/*2372*/ uint16(xMatch),
+	/*2373*/ uint16(xCondPrefix), 2,
+	0x66, 2385,
+	0x0, 2379,
+	/*2379*/ uint16(xSetOp), uint16(PHSUBW),
+	/*2381*/ uint16(xReadSlashR),
+	/*2382*/ uint16(xArgMm1),
+	/*2383*/ uint16(xArgMm2M64),
+	/*2384*/ uint16(xMatch),
+	/*2385*/ uint16(xSetOp), uint16(PHSUBW),
+	/*2387*/ uint16(xReadSlashR),
+	/*2388*/ uint16(xArgXmm1),
+	/*2389*/ uint16(xArgXmm2M128),
+	/*2390*/ uint16(xMatch),
+	/*2391*/ uint16(xCondPrefix), 2,
+	0x66, 2403,
+	0x0, 2397,
+	/*2397*/ uint16(xSetOp), uint16(PHSUBD),
+	/*2399*/ uint16(xReadSlashR),
+	/*2400*/ uint16(xArgMm1),
+	/*2401*/ uint16(xArgMm2M64),
+	/*2402*/ uint16(xMatch),
+	/*2403*/ uint16(xSetOp), uint16(PHSUBD),
+	/*2405*/ uint16(xReadSlashR),
+	/*2406*/ uint16(xArgXmm1),
+	/*2407*/ uint16(xArgXmm2M128),
+	/*2408*/ uint16(xMatch),
+	/*2409*/ uint16(xCondPrefix), 2,
+	0x66, 2421,
+	0x0, 2415,
+	/*2415*/ uint16(xSetOp), uint16(PHSUBSW),
+	/*2417*/ uint16(xReadSlashR),
+	/*2418*/ uint16(xArgMm1),
+	/*2419*/ uint16(xArgMm2M64),
+	/*2420*/ uint16(xMatch),
+	/*2421*/ uint16(xSetOp), uint16(PHSUBSW),
+	/*2423*/ uint16(xReadSlashR),
+	/*2424*/ uint16(xArgXmm1),
+	/*2425*/ uint16(xArgXmm2M128),
+	/*2426*/ uint16(xMatch),
+	/*2427*/ uint16(xCondPrefix), 2,
+	0x66, 2439,
+	0x0, 2433,
+	/*2433*/ uint16(xSetOp), uint16(PSIGNB),
+	/*2435*/ uint16(xReadSlashR),
+	/*2436*/ uint16(xArgMm1),
+	/*2437*/ uint16(xArgMm2M64),
+	/*2438*/ uint16(xMatch),
+	/*2439*/ uint16(xSetOp), uint16(PSIGNB),
+	/*2441*/ uint16(xReadSlashR),
+	/*2442*/ uint16(xArgXmm1),
+	/*2443*/ uint16(xArgXmm2M128),
+	/*2444*/ uint16(xMatch),
+	/*2445*/ uint16(xCondPrefix), 2,
+	0x66, 2457,
+	0x0, 2451,
+	/*2451*/ uint16(xSetOp), uint16(PSIGNW),
+	/*2453*/ uint16(xReadSlashR),
+	/*2454*/ uint16(xArgMm1),
+	/*2455*/ uint16(xArgMm2M64),
+	/*2456*/ uint16(xMatch),
+	/*2457*/ uint16(xSetOp), uint16(PSIGNW),
+	/*2459*/ uint16(xReadSlashR),
+	/*2460*/ uint16(xArgXmm1),
+	/*2461*/ uint16(xArgXmm2M128),
+	/*2462*/ uint16(xMatch),
+	/*2463*/ uint16(xCondPrefix), 2,
+	0x66, 2475,
+	0x0, 2469,
+	/*2469*/ uint16(xSetOp), uint16(PSIGND),
+	/*2471*/ uint16(xReadSlashR),
+	/*2472*/ uint16(xArgMm1),
+	/*2473*/ uint16(xArgMm2M64),
+	/*2474*/ uint16(xMatch),
+	/*2475*/ uint16(xSetOp), uint16(PSIGND),
+	/*2477*/ uint16(xReadSlashR),
+	/*2478*/ uint16(xArgXmm1),
+	/*2479*/ uint16(xArgXmm2M128),
+	/*2480*/ uint16(xMatch),
+	/*2481*/ uint16(xCondPrefix), 2,
+	0x66, 2493,
+	0x0, 2487,
+	/*2487*/ uint16(xSetOp), uint16(PMULHRSW),
+	/*2489*/ uint16(xReadSlashR),
+	/*2490*/ uint16(xArgMm1),
+	/*2491*/ uint16(xArgMm2M64),
+	/*2492*/ uint16(xMatch),
+	/*2493*/ uint16(xSetOp), uint16(PMULHRSW),
+	/*2495*/ uint16(xReadSlashR),
+	/*2496*/ uint16(xArgXmm1),
+	/*2497*/ uint16(xArgXmm2M128),
+	/*2498*/ uint16(xMatch),
+	/*2499*/ uint16(xCondPrefix), 1,
+	0x66, 2503,
+	/*2503*/ uint16(xSetOp), uint16(PBLENDVB),
+	/*2505*/ uint16(xReadSlashR),
+	/*2506*/ uint16(xArgXmm1),
+	/*2507*/ uint16(xArgXmm2M128),
+	/*2508*/ uint16(xArgXMM0),
+	/*2509*/ uint16(xMatch),
+	/*2510*/ uint16(xCondPrefix), 1,
+	0x66, 2514,
+	/*2514*/ uint16(xSetOp), uint16(BLENDVPS),
+	/*2516*/ uint16(xReadSlashR),
+	/*2517*/ uint16(xArgXmm1),
+	/*2518*/ uint16(xArgXmm2M128),
+	/*2519*/ uint16(xArgXMM0),
+	/*2520*/ uint16(xMatch),
+	/*2521*/ uint16(xCondPrefix), 1,
+	0x66, 2525,
+	/*2525*/ uint16(xSetOp), uint16(BLENDVPD),
+	/*2527*/ uint16(xReadSlashR),
+	/*2528*/ uint16(xArgXmm1),
+	/*2529*/ uint16(xArgXmm2M128),
+	/*2530*/ uint16(xArgXMM0),
+	/*2531*/ uint16(xMatch),
+	/*2532*/ uint16(xCondPrefix), 1,
+	0x66, 2536,
+	/*2536*/ uint16(xSetOp), uint16(PTEST),
+	/*2538*/ uint16(xReadSlashR),
+	/*2539*/ uint16(xArgXmm1),
+	/*2540*/ uint16(xArgXmm2M128),
+	/*2541*/ uint16(xMatch),
+	/*2542*/ uint16(xCondPrefix), 2,
+	0x66, 2554,
+	0x0, 2548,
+	/*2548*/ uint16(xSetOp), uint16(PABSB),
+	/*2550*/ uint16(xReadSlashR),
+	/*2551*/ uint16(xArgMm1),
+	/*2552*/ uint16(xArgMm2M64),
+	/*2553*/ uint16(xMatch),
+	/*2554*/ uint16(xSetOp), uint16(PABSB),
+	/*2556*/ uint16(xReadSlashR),
+	/*2557*/ uint16(xArgXmm1),
+	/*2558*/ uint16(xArgXmm2M128),
+	/*2559*/ uint16(xMatch),
+	/*2560*/ uint16(xCondPrefix), 2,
+	0x66, 2572,
+	0x0, 2566,
+	/*2566*/ uint16(xSetOp), uint16(PABSW),
+	/*2568*/ uint16(xReadSlashR),
+	/*2569*/ uint16(xArgMm1),
+	/*2570*/ uint16(xArgMm2M64),
+	/*2571*/ uint16(xMatch),
+	/*2572*/ uint16(xSetOp), uint16(PABSW),
+	/*2574*/ uint16(xReadSlashR),
+	/*2575*/ uint16(xArgXmm1),
+	/*2576*/ uint16(xArgXmm2M128),
+	/*2577*/ uint16(xMatch),
+	/*2578*/ uint16(xCondPrefix), 2,
+	0x66, 2590,
+	0x0, 2584,
+	/*2584*/ uint16(xSetOp), uint16(PABSD),
+	/*2586*/ uint16(xReadSlashR),
+	/*2587*/ uint16(xArgMm1),
+	/*2588*/ uint16(xArgMm2M64),
+	/*2589*/ uint16(xMatch),
+	/*2590*/ uint16(xSetOp), uint16(PABSD),
+	/*2592*/ uint16(xReadSlashR),
+	/*2593*/ uint16(xArgXmm1),
+	/*2594*/ uint16(xArgXmm2M128),
+	/*2595*/ uint16(xMatch),
+	/*2596*/ uint16(xCondPrefix), 1,
+	0x66, 2600,
+	/*2600*/ uint16(xSetOp), uint16(PMOVSXBW),
+	/*2602*/ uint16(xReadSlashR),
+	/*2603*/ uint16(xArgXmm1),
+	/*2604*/ uint16(xArgXmm2M64),
+	/*2605*/ uint16(xMatch),
+	/*2606*/ uint16(xCondPrefix), 1,
+	0x66, 2610,
+	/*2610*/ uint16(xSetOp), uint16(PMOVSXBD),
+	/*2612*/ uint16(xReadSlashR),
+	/*2613*/ uint16(xArgXmm1),
+	/*2614*/ uint16(xArgXmm2M32),
+	/*2615*/ uint16(xMatch),
+	/*2616*/ uint16(xCondPrefix), 1,
+	0x66, 2620,
+	/*2620*/ uint16(xSetOp), uint16(PMOVSXBQ),
+	/*2622*/ uint16(xReadSlashR),
+	/*2623*/ uint16(xArgXmm1),
+	/*2624*/ uint16(xArgXmm2M16),
+	/*2625*/ uint16(xMatch),
+	/*2626*/ uint16(xCondPrefix), 1,
+	0x66, 2630,
+	/*2630*/ uint16(xSetOp), uint16(PMOVSXWD),
+	/*2632*/ uint16(xReadSlashR),
+	/*2633*/ uint16(xArgXmm1),
+	/*2634*/ uint16(xArgXmm2M64),
+	/*2635*/ uint16(xMatch),
+	/*2636*/ uint16(xCondPrefix), 1,
+	0x66, 2640,
+	/*2640*/ uint16(xSetOp), uint16(PMOVSXWQ),
+	/*2642*/ uint16(xReadSlashR),
+	/*2643*/ uint16(xArgXmm1),
+	/*2644*/ uint16(xArgXmm2M32),
+	/*2645*/ uint16(xMatch),
+	/*2646*/ uint16(xCondPrefix), 1,
+	0x66, 2650,
+	/*2650*/ uint16(xSetOp), uint16(PMOVSXDQ),
+	/*2652*/ uint16(xReadSlashR),
+	/*2653*/ uint16(xArgXmm1),
+	/*2654*/ uint16(xArgXmm2M64),
+	/*2655*/ uint16(xMatch),
+	/*2656*/ uint16(xCondPrefix), 1,
+	0x66, 2660,
+	/*2660*/ uint16(xSetOp), uint16(PMULDQ),
+	/*2662*/ uint16(xReadSlashR),
+	/*2663*/ uint16(xArgXmm1),
+	/*2664*/ uint16(xArgXmm2M128),
+	/*2665*/ uint16(xMatch),
+	/*2666*/ uint16(xCondPrefix), 1,
+	0x66, 2670,
+	/*2670*/ uint16(xSetOp), uint16(PCMPEQQ),
+	/*2672*/ uint16(xReadSlashR),
+	/*2673*/ uint16(xArgXmm1),
+	/*2674*/ uint16(xArgXmm2M128),
+	/*2675*/ uint16(xMatch),
+	/*2676*/ uint16(xCondPrefix), 1,
+	0x66, 2680,
+	/*2680*/ uint16(xSetOp), uint16(MOVNTDQA),
+	/*2682*/ uint16(xReadSlashR),
+	/*2683*/ uint16(xArgXmm1),
+	/*2684*/ uint16(xArgM128),
+	/*2685*/ uint16(xMatch),
+	/*2686*/ uint16(xCondPrefix), 1,
+	0x66, 2690,
+	/*2690*/ uint16(xSetOp), uint16(PACKUSDW),
+	/*2692*/ uint16(xReadSlashR),
+	/*2693*/ uint16(xArgXmm1),
+	/*2694*/ uint16(xArgXmm2M128),
+	/*2695*/ uint16(xMatch),
+	/*2696*/ uint16(xCondPrefix), 1,
+	0x66, 2700,
+	/*2700*/ uint16(xSetOp), uint16(PMOVZXBW),
+	/*2702*/ uint16(xReadSlashR),
+	/*2703*/ uint16(xArgXmm1),
+	/*2704*/ uint16(xArgXmm2M64),
+	/*2705*/ uint16(xMatch),
+	/*2706*/ uint16(xCondPrefix), 1,
+	0x66, 2710,
+	/*2710*/ uint16(xSetOp), uint16(PMOVZXBD),
+	/*2712*/ uint16(xReadSlashR),
+	/*2713*/ uint16(xArgXmm1),
+	/*2714*/ uint16(xArgXmm2M32),
+	/*2715*/ uint16(xMatch),
+	/*2716*/ uint16(xCondPrefix), 1,
+	0x66, 2720,
+	/*2720*/ uint16(xSetOp), uint16(PMOVZXBQ),
+	/*2722*/ uint16(xReadSlashR),
+	/*2723*/ uint16(xArgXmm1),
+	/*2724*/ uint16(xArgXmm2M16),
+	/*2725*/ uint16(xMatch),
+	/*2726*/ uint16(xCondPrefix), 1,
+	0x66, 2730,
+	/*2730*/ uint16(xSetOp), uint16(PMOVZXWD),
+	/*2732*/ uint16(xReadSlashR),
+	/*2733*/ uint16(xArgXmm1),
+	/*2734*/ uint16(xArgXmm2M64),
+	/*2735*/ uint16(xMatch),
+	/*2736*/ uint16(xCondPrefix), 1,
+	0x66, 2740,
+	/*2740*/ uint16(xSetOp), uint16(PMOVZXWQ),
+	/*2742*/ uint16(xReadSlashR),
+	/*2743*/ uint16(xArgXmm1),
+	/*2744*/ uint16(xArgXmm2M32),
+	/*2745*/ uint16(xMatch),
+	/*2746*/ uint16(xCondPrefix), 1,
+	0x66, 2750,
+	/*2750*/ uint16(xSetOp), uint16(PMOVZXDQ),
+	/*2752*/ uint16(xReadSlashR),
+	/*2753*/ uint16(xArgXmm1),
+	/*2754*/ uint16(xArgXmm2M64),
+	/*2755*/ uint16(xMatch),
+	/*2756*/ uint16(xCondPrefix), 1,
+	0x66, 2760,
+	/*2760*/ uint16(xSetOp), uint16(PCMPGTQ),
+	/*2762*/ uint16(xReadSlashR),
+	/*2763*/ uint16(xArgXmm1),
+	/*2764*/ uint16(xArgXmm2M128),
+	/*2765*/ uint16(xMatch),
+	/*2766*/ uint16(xCondPrefix), 1,
+	0x66, 2770,
+	/*2770*/ uint16(xSetOp), uint16(PMINSB),
+	/*2772*/ uint16(xReadSlashR),
+	/*2773*/ uint16(xArgXmm1),
+	/*2774*/ uint16(xArgXmm2M128),
+	/*2775*/ uint16(xMatch),
+	/*2776*/ uint16(xCondPrefix), 1,
+	0x66, 2780,
+	/*2780*/ uint16(xSetOp), uint16(PMINSD),
+	/*2782*/ uint16(xReadSlashR),
+	/*2783*/ uint16(xArgXmm1),
+	/*2784*/ uint16(xArgXmm2M128),
+	/*2785*/ uint16(xMatch),
+	/*2786*/ uint16(xCondPrefix), 1,
+	0x66, 2790,
+	/*2790*/ uint16(xSetOp), uint16(PMINUW),
+	/*2792*/ uint16(xReadSlashR),
+	/*2793*/ uint16(xArgXmm1),
+	/*2794*/ uint16(xArgXmm2M128),
+	/*2795*/ uint16(xMatch),
+	/*2796*/ uint16(xCondPrefix), 1,
+	0x66, 2800,
+	/*2800*/ uint16(xSetOp), uint16(PMINUD),
+	/*2802*/ uint16(xReadSlashR),
+	/*2803*/ uint16(xArgXmm1),
+	/*2804*/ uint16(xArgXmm2M128),
+	/*2805*/ uint16(xMatch),
+	/*2806*/ uint16(xCondPrefix), 1,
+	0x66, 2810,
+	/*2810*/ uint16(xSetOp), uint16(PMAXSB),
+	/*2812*/ uint16(xReadSlashR),
+	/*2813*/ uint16(xArgXmm1),
+	/*2814*/ uint16(xArgXmm2M128),
+	/*2815*/ uint16(xMatch),
+	/*2816*/ uint16(xCondPrefix), 1,
+	0x66, 2820,
+	/*2820*/ uint16(xSetOp), uint16(PMAXSD),
+	/*2822*/ uint16(xReadSlashR),
+	/*2823*/ uint16(xArgXmm1),
+	/*2824*/ uint16(xArgXmm2M128),
+	/*2825*/ uint16(xMatch),
+	/*2826*/ uint16(xCondPrefix), 1,
+	0x66, 2830,
+	/*2830*/ uint16(xSetOp), uint16(PMAXUW),
+	/*2832*/ uint16(xReadSlashR),
+	/*2833*/ uint16(xArgXmm1),
+	/*2834*/ uint16(xArgXmm2M128),
+	/*2835*/ uint16(xMatch),
+	/*2836*/ uint16(xCondPrefix), 1,
+	0x66, 2840,
+	/*2840*/ uint16(xSetOp), uint16(PMAXUD),
+	/*2842*/ uint16(xReadSlashR),
+	/*2843*/ uint16(xArgXmm1),
+	/*2844*/ uint16(xArgXmm2M128),
+	/*2845*/ uint16(xMatch),
+	/*2846*/ uint16(xCondPrefix), 1,
+	0x66, 2850,
+	/*2850*/ uint16(xSetOp), uint16(PMULLD),
+	/*2852*/ uint16(xReadSlashR),
+	/*2853*/ uint16(xArgXmm1),
+	/*2854*/ uint16(xArgXmm2M128),
+	/*2855*/ uint16(xMatch),
+	/*2856*/ uint16(xCondPrefix), 1,
+	0x66, 2860,
+	/*2860*/ uint16(xSetOp), uint16(PHMINPOSUW),
+	/*2862*/ uint16(xReadSlashR),
+	/*2863*/ uint16(xArgXmm1),
+	/*2864*/ uint16(xArgXmm2M128),
+	/*2865*/ uint16(xMatch),
+	/*2866*/ uint16(xCondIs64), 2869, 2879,
+	/*2869*/ uint16(xCondPrefix), 1,
+	0x66, 2873,
+	/*2873*/ uint16(xSetOp), uint16(INVPCID),
+	/*2875*/ uint16(xReadSlashR),
+	/*2876*/ uint16(xArgR32),
+	/*2877*/ uint16(xArgM128),
+	/*2878*/ uint16(xMatch),
+	/*2879*/ uint16(xCondPrefix), 1,
+	0x66, 2883,
+	/*2883*/ uint16(xSetOp), uint16(INVPCID),
+	/*2885*/ uint16(xReadSlashR),
+	/*2886*/ uint16(xArgR64),
+	/*2887*/ uint16(xArgM128),
+	/*2888*/ uint16(xMatch),
+	/*2889*/ uint16(xCondPrefix), 1,
+	0x66, 2893,
+	/*2893*/ uint16(xSetOp), uint16(AESIMC),
+	/*2895*/ uint16(xReadSlashR),
+	/*2896*/ uint16(xArgXmm1),
+	/*2897*/ uint16(xArgXmm2M128),
+	/*2898*/ uint16(xMatch),
+	/*2899*/ uint16(xCondPrefix), 1,
+	0x66, 2903,
+	/*2903*/ uint16(xSetOp), uint16(AESENC),
+	/*2905*/ uint16(xReadSlashR),
+	/*2906*/ uint16(xArgXmm1),
+	/*2907*/ uint16(xArgXmm2M128),
+	/*2908*/ uint16(xMatch),
+	/*2909*/ uint16(xCondPrefix), 1,
+	0x66, 2913,
+	/*2913*/ uint16(xSetOp), uint16(AESENCLAST),
+	/*2915*/ uint16(xReadSlashR),
+	/*2916*/ uint16(xArgXmm1),
+	/*2917*/ uint16(xArgXmm2M128),
+	/*2918*/ uint16(xMatch),
+	/*2919*/ uint16(xCondPrefix), 1,
+	0x66, 2923,
+	/*2923*/ uint16(xSetOp), uint16(AESDEC),
+	/*2925*/ uint16(xReadSlashR),
+	/*2926*/ uint16(xArgXmm1),
+	/*2927*/ uint16(xArgXmm2M128),
+	/*2928*/ uint16(xMatch),
+	/*2929*/ uint16(xCondPrefix), 1,
+	0x66, 2933,
+	/*2933*/ uint16(xSetOp), uint16(AESDECLAST),
+	/*2935*/ uint16(xReadSlashR),
+	/*2936*/ uint16(xArgXmm1),
+	/*2937*/ uint16(xArgXmm2M128),
+	/*2938*/ uint16(xMatch),
+	/*2939*/ uint16(xCondIs64), 2942, 2980,
+	/*2942*/ uint16(xCondPrefix), 2,
+	0xF2, 2964,
+	0x0, 2948,
+	/*2948*/ uint16(xCondDataSize), 2952, 2958, 0,
+	/*2952*/ uint16(xSetOp), uint16(MOVBE),
+	/*2954*/ uint16(xReadSlashR),
+	/*2955*/ uint16(xArgR16),
+	/*2956*/ uint16(xArgM16),
+	/*2957*/ uint16(xMatch),
+	/*2958*/ uint16(xSetOp), uint16(MOVBE),
+	/*2960*/ uint16(xReadSlashR),
+	/*2961*/ uint16(xArgR32),
+	/*2962*/ uint16(xArgM32),
+	/*2963*/ uint16(xMatch),
+	/*2964*/ uint16(xCondDataSize), 2968, 2974, 0,
+	/*2968*/ uint16(xSetOp), uint16(CRC32),
+	/*2970*/ uint16(xReadSlashR),
+	/*2971*/ uint16(xArgR32),
+	/*2972*/ uint16(xArgRM8),
+	/*2973*/ uint16(xMatch),
+	/*2974*/ uint16(xSetOp), uint16(CRC32),
+	/*2976*/ uint16(xReadSlashR),
+	/*2977*/ uint16(xArgR32),
+	/*2978*/ uint16(xArgRM8),
+	/*2979*/ uint16(xMatch),
+	/*2980*/ uint16(xCondPrefix), 2,
+	0xF2, 2996,
+	0x0, 2986,
+	/*2986*/ uint16(xCondDataSize), 2952, 2958, 2990,
+	/*2990*/ uint16(xSetOp), uint16(MOVBE),
+	/*2992*/ uint16(xReadSlashR),
+	/*2993*/ uint16(xArgR64),
+	/*2994*/ uint16(xArgM64),
+	/*2995*/ uint16(xMatch),
+	/*2996*/ uint16(xCondDataSize), 2968, 2974, 3000,
+	/*3000*/ uint16(xSetOp), uint16(CRC32),
+	/*3002*/ uint16(xReadSlashR),
+	/*3003*/ uint16(xArgR64),
+	/*3004*/ uint16(xArgRM8),
+	/*3005*/ uint16(xMatch),
+	/*3006*/ uint16(xCondIs64), 3009, 3047,
+	/*3009*/ uint16(xCondPrefix), 2,
+	0xF2, 3031,
+	0x0, 3015,
+	/*3015*/ uint16(xCondDataSize), 3019, 3025, 0,
+	/*3019*/ uint16(xSetOp), uint16(MOVBE),
+	/*3021*/ uint16(xReadSlashR),
+	/*3022*/ uint16(xArgM16),
+	/*3023*/ uint16(xArgR16),
+	/*3024*/ uint16(xMatch),
+	/*3025*/ uint16(xSetOp), uint16(MOVBE),
+	/*3027*/ uint16(xReadSlashR),
+	/*3028*/ uint16(xArgM32),
+	/*3029*/ uint16(xArgR32),
+	/*3030*/ uint16(xMatch),
+	/*3031*/ uint16(xCondDataSize), 3035, 3041, 0,
+	/*3035*/ uint16(xSetOp), uint16(CRC32),
+	/*3037*/ uint16(xReadSlashR),
+	/*3038*/ uint16(xArgR32),
+	/*3039*/ uint16(xArgRM16),
+	/*3040*/ uint16(xMatch),
+	/*3041*/ uint16(xSetOp), uint16(CRC32),
+	/*3043*/ uint16(xReadSlashR),
+	/*3044*/ uint16(xArgR32),
+	/*3045*/ uint16(xArgRM32),
+	/*3046*/ uint16(xMatch),
+	/*3047*/ uint16(xCondPrefix), 2,
+	0xF2, 3063,
+	0x0, 3053,
+	/*3053*/ uint16(xCondDataSize), 3019, 3025, 3057,
+	/*3057*/ uint16(xSetOp), uint16(MOVBE),
+	/*3059*/ uint16(xReadSlashR),
+	/*3060*/ uint16(xArgM64),
+	/*3061*/ uint16(xArgR64),
+	/*3062*/ uint16(xMatch),
+	/*3063*/ uint16(xCondDataSize), 3035, 3041, 3067,
+	/*3067*/ uint16(xSetOp), uint16(CRC32),
+	/*3069*/ uint16(xReadSlashR),
+	/*3070*/ uint16(xArgR64),
+	/*3071*/ uint16(xArgRM64),
+	/*3072*/ uint16(xMatch),
+	/*3073*/ uint16(xCondByte), 24,
+	0x08, 3124,
+	0x09, 3136,
+	0x0A, 3148,
+	0x0B, 3160,
+	0x0C, 3172,
+	0x0D, 3184,
+	0x0E, 3196,
+	0x0F, 3208,
+	0x14, 3230,
+	0x15, 3242,
+	0x16, 3254,
+	0x17, 3297,
+	0x20, 3309,
+	0x21, 3321,
+	0x22, 3333,
+	0x40, 3376,
+	0x41, 3388,
+	0x42, 3400,
+	0x44, 3412,
+	0x60, 3424,
+	0x61, 3436,
+	0x62, 3448,
+	0x63, 3460,
+	0xDF, 3472,
+	uint16(xFail),
+	/*3124*/ uint16(xCondPrefix), 1,
+	0x66, 3128,
+	/*3128*/ uint16(xSetOp), uint16(ROUNDPS),
+	/*3130*/ uint16(xReadSlashR),
+	/*3131*/ uint16(xReadIb),
+	/*3132*/ uint16(xArgXmm1),
+	/*3133*/ uint16(xArgXmm2M128),
+	/*3134*/ uint16(xArgImm8u),
+	/*3135*/ uint16(xMatch),
+	/*3136*/ uint16(xCondPrefix), 1,
+	0x66, 3140,
+	/*3140*/ uint16(xSetOp), uint16(ROUNDPD),
+	/*3142*/ uint16(xReadSlashR),
+	/*3143*/ uint16(xReadIb),
+	/*3144*/ uint16(xArgXmm1),
+	/*3145*/ uint16(xArgXmm2M128),
+	/*3146*/ uint16(xArgImm8u),
+	/*3147*/ uint16(xMatch),
+	/*3148*/ uint16(xCondPrefix), 1,
+	0x66, 3152,
+	/*3152*/ uint16(xSetOp), uint16(ROUNDSS),
+	/*3154*/ uint16(xReadSlashR),
+	/*3155*/ uint16(xReadIb),
+	/*3156*/ uint16(xArgXmm1),
+	/*3157*/ uint16(xArgXmm2M32),
+	/*3158*/ uint16(xArgImm8u),
+	/*3159*/ uint16(xMatch),
+	/*3160*/ uint16(xCondPrefix), 1,
+	0x66, 3164,
+	/*3164*/ uint16(xSetOp), uint16(ROUNDSD),
+	/*3166*/ uint16(xReadSlashR),
+	/*3167*/ uint16(xReadIb),
+	/*3168*/ uint16(xArgXmm1),
+	/*3169*/ uint16(xArgXmm2M64),
+	/*3170*/ uint16(xArgImm8u),
+	/*3171*/ uint16(xMatch),
+	/*3172*/ uint16(xCondPrefix), 1,
+	0x66, 3176,
+	/*3176*/ uint16(xSetOp), uint16(BLENDPS),
+	/*3178*/ uint16(xReadSlashR),
+	/*3179*/ uint16(xReadIb),
+	/*3180*/ uint16(xArgXmm1),
+	/*3181*/ uint16(xArgXmm2M128),
+	/*3182*/ uint16(xArgImm8u),
+	/*3183*/ uint16(xMatch),
+	/*3184*/ uint16(xCondPrefix), 1,
+	0x66, 3188,
+	/*3188*/ uint16(xSetOp), uint16(BLENDPD),
+	/*3190*/ uint16(xReadSlashR),
+	/*3191*/ uint16(xReadIb),
+	/*3192*/ uint16(xArgXmm1),
+	/*3193*/ uint16(xArgXmm2M128),
+	/*3194*/ uint16(xArgImm8u),
+	/*3195*/ uint16(xMatch),
+	/*3196*/ uint16(xCondPrefix), 1,
+	0x66, 3200,
+	/*3200*/ uint16(xSetOp), uint16(PBLENDW),
+	/*3202*/ uint16(xReadSlashR),
+	/*3203*/ uint16(xReadIb),
+	/*3204*/ uint16(xArgXmm1),
+	/*3205*/ uint16(xArgXmm2M128),
+	/*3206*/ uint16(xArgImm8u),
+	/*3207*/ uint16(xMatch),
+	/*3208*/ uint16(xCondPrefix), 2,
+	0x66, 3222,
+	0x0, 3214,
+	/*3214*/ uint16(xSetOp), uint16(PALIGNR),
+	/*3216*/ uint16(xReadSlashR),
+	/*3217*/ uint16(xReadIb),
+	/*3218*/ uint16(xArgMm1),
+	/*3219*/ uint16(xArgMm2M64),
+	/*3220*/ uint16(xArgImm8u),
+	/*3221*/ uint16(xMatch),
+	/*3222*/ uint16(xSetOp), uint16(PALIGNR),
+	/*3224*/ uint16(xReadSlashR),
+	/*3225*/ uint16(xReadIb),
+	/*3226*/ uint16(xArgXmm1),
+	/*3227*/ uint16(xArgXmm2M128),
+	/*3228*/ uint16(xArgImm8u),
+	/*3229*/ uint16(xMatch),
+	/*3230*/ uint16(xCondPrefix), 1,
+	0x66, 3234,
+	/*3234*/ uint16(xSetOp), uint16(PEXTRB),
+	/*3236*/ uint16(xReadSlashR),
+	/*3237*/ uint16(xReadIb),
+	/*3238*/ uint16(xArgR32M8),
+	/*3239*/ uint16(xArgXmm1),
+	/*3240*/ uint16(xArgImm8u),
+	/*3241*/ uint16(xMatch),
+	/*3242*/ uint16(xCondPrefix), 1,
+	0x66, 3246,
+	/*3246*/ uint16(xSetOp), uint16(PEXTRW),
+	/*3248*/ uint16(xReadSlashR),
+	/*3249*/ uint16(xReadIb),
+	/*3250*/ uint16(xArgR32M16),
+	/*3251*/ uint16(xArgXmm1),
+	/*3252*/ uint16(xArgImm8u),
+	/*3253*/ uint16(xMatch),
+	/*3254*/ uint16(xCondIs64), 3257, 3281,
+	/*3257*/ uint16(xCondPrefix), 1,
+	0x66, 3261,
+	/*3261*/ uint16(xCondDataSize), 3265, 3273, 0,
+	/*3265*/ uint16(xSetOp), uint16(PEXTRD),
+	/*3267*/ uint16(xReadSlashR),
+	/*3268*/ uint16(xReadIb),
+	/*3269*/ uint16(xArgRM32),
+	/*3270*/ uint16(xArgXmm1),
+	/*3271*/ uint16(xArgImm8u),
+	/*3272*/ uint16(xMatch),
+	/*3273*/ uint16(xSetOp), uint16(PEXTRD),
+	/*3275*/ uint16(xReadSlashR),
+	/*3276*/ uint16(xReadIb),
+	/*3277*/ uint16(xArgRM32),
+	/*3278*/ uint16(xArgXmm1),
+	/*3279*/ uint16(xArgImm8u),
+	/*3280*/ uint16(xMatch),
+	/*3281*/ uint16(xCondPrefix), 1,
+	0x66, 3285,
+	/*3285*/ uint16(xCondDataSize), 3265, 3273, 3289,
+	/*3289*/ uint16(xSetOp), uint16(PEXTRQ),
+	/*3291*/ uint16(xReadSlashR),
+	/*3292*/ uint16(xReadIb),
+	/*3293*/ uint16(xArgRM64),
+	/*3294*/ uint16(xArgXmm1),
+	/*3295*/ uint16(xArgImm8u),
+	/*3296*/ uint16(xMatch),
+	/*3297*/ uint16(xCondPrefix), 1,
+	0x66, 3301,
+	/*3301*/ uint16(xSetOp), uint16(EXTRACTPS),
+	/*3303*/ uint16(xReadSlashR),
+	/*3304*/ uint16(xReadIb),
+	/*3305*/ uint16(xArgRM32),
+	/*3306*/ uint16(xArgXmm1),
+	/*3307*/ uint16(xArgImm8u),
+	/*3308*/ uint16(xMatch),
+	/*3309*/ uint16(xCondPrefix), 1,
+	0x66, 3313,
+	/*3313*/ uint16(xSetOp), uint16(PINSRB),
+	/*3315*/ uint16(xReadSlashR),
+	/*3316*/ uint16(xReadIb),
+	/*3317*/ uint16(xArgXmm1),
+	/*3318*/ uint16(xArgR32M8),
+	/*3319*/ uint16(xArgImm8u),
+	/*3320*/ uint16(xMatch),
+	/*3321*/ uint16(xCondPrefix), 1,
+	0x66, 3325,
+	/*3325*/ uint16(xSetOp), uint16(INSERTPS),
+	/*3327*/ uint16(xReadSlashR),
+	/*3328*/ uint16(xReadIb),
+	/*3329*/ uint16(xArgXmm1),
+	/*3330*/ uint16(xArgXmm2M32),
+	/*3331*/ uint16(xArgImm8u),
+	/*3332*/ uint16(xMatch),
+	/*3333*/ uint16(xCondIs64), 3336, 3360,
+	/*3336*/ uint16(xCondPrefix), 1,
+	0x66, 3340,
+	/*3340*/ uint16(xCondDataSize), 3344, 3352, 0,
+	/*3344*/ uint16(xSetOp), uint16(PINSRD),
+	/*3346*/ uint16(xReadSlashR),
+	/*3347*/ uint16(xReadIb),
+	/*3348*/ uint16(xArgXmm1),
+	/*3349*/ uint16(xArgRM32),
+	/*3350*/ uint16(xArgImm8u),
+	/*3351*/ uint16(xMatch),
+	/*3352*/ uint16(xSetOp), uint16(PINSRD),
+	/*3354*/ uint16(xReadSlashR),
+	/*3355*/ uint16(xReadIb),
+	/*3356*/ uint16(xArgXmm1),
+	/*3357*/ uint16(xArgRM32),
+	/*3358*/ uint16(xArgImm8u),
+	/*3359*/ uint16(xMatch),
+	/*3360*/ uint16(xCondPrefix), 1,
+	0x66, 3364,
+	/*3364*/ uint16(xCondDataSize), 3344, 3352, 3368,
+	/*3368*/ uint16(xSetOp), uint16(PINSRQ),
+	/*3370*/ uint16(xReadSlashR),
+	/*3371*/ uint16(xReadIb),
+	/*3372*/ uint16(xArgXmm1),
+	/*3373*/ uint16(xArgRM64),
+	/*3374*/ uint16(xArgImm8u),
+	/*3375*/ uint16(xMatch),
+	/*3376*/ uint16(xCondPrefix), 1,
+	0x66, 3380,
+	/*3380*/ uint16(xSetOp), uint16(DPPS),
+	/*3382*/ uint16(xReadSlashR),
+	/*3383*/ uint16(xReadIb),
+	/*3384*/ uint16(xArgXmm1),
+	/*3385*/ uint16(xArgXmm2M128),
+	/*3386*/ uint16(xArgImm8u),
+	/*3387*/ uint16(xMatch),
+	/*3388*/ uint16(xCondPrefix), 1,
+	0x66, 3392,
+	/*3392*/ uint16(xSetOp), uint16(DPPD),
+	/*3394*/ uint16(xReadSlashR),
+	/*3395*/ uint16(xReadIb),
+	/*3396*/ uint16(xArgXmm1),
+	/*3397*/ uint16(xArgXmm2M128),
+	/*3398*/ uint16(xArgImm8u),
+	/*3399*/ uint16(xMatch),
+	/*3400*/ uint16(xCondPrefix), 1,
+	0x66, 3404,
+	/*3404*/ uint16(xSetOp), uint16(MPSADBW),
+	/*3406*/ uint16(xReadSlashR),
+	/*3407*/ uint16(xReadIb),
+	/*3408*/ uint16(xArgXmm1),
+	/*3409*/ uint16(xArgXmm2M128),
+	/*3410*/ uint16(xArgImm8u),
+	/*3411*/ uint16(xMatch),
+	/*3412*/ uint16(xCondPrefix), 1,
+	0x66, 3416,
+	/*3416*/ uint16(xSetOp), uint16(PCLMULQDQ),
+	/*3418*/ uint16(xReadSlashR),
+	/*3419*/ uint16(xReadIb),
+	/*3420*/ uint16(xArgXmm1),
+	/*3421*/ uint16(xArgXmm2M128),
+	/*3422*/ uint16(xArgImm8u),
+	/*3423*/ uint16(xMatch),
+	/*3424*/ uint16(xCondPrefix), 1,
+	0x66, 3428,
+	/*3428*/ uint16(xSetOp), uint16(PCMPESTRM),
+	/*3430*/ uint16(xReadSlashR),
+	/*3431*/ uint16(xReadIb),
+	/*3432*/ uint16(xArgXmm1),
+	/*3433*/ uint16(xArgXmm2M128),
+	/*3434*/ uint16(xArgImm8u),
+	/*3435*/ uint16(xMatch),
+	/*3436*/ uint16(xCondPrefix), 1,
+	0x66, 3440,
+	/*3440*/ uint16(xSetOp), uint16(PCMPESTRI),
+	/*3442*/ uint16(xReadSlashR),
+	/*3443*/ uint16(xReadIb),
+	/*3444*/ uint16(xArgXmm1),
+	/*3445*/ uint16(xArgXmm2M128),
+	/*3446*/ uint16(xArgImm8u),
+	/*3447*/ uint16(xMatch),
+	/*3448*/ uint16(xCondPrefix), 1,
+	0x66, 3452,
+	/*3452*/ uint16(xSetOp), uint16(PCMPISTRM),
+	/*3454*/ uint16(xReadSlashR),
+	/*3455*/ uint16(xReadIb),
+	/*3456*/ uint16(xArgXmm1),
+	/*3457*/ uint16(xArgXmm2M128),
+	/*3458*/ uint16(xArgImm8u),
+	/*3459*/ uint16(xMatch),
+	/*3460*/ uint16(xCondPrefix), 1,
+	0x66, 3464,
+	/*3464*/ uint16(xSetOp), uint16(PCMPISTRI),
+	/*3466*/ uint16(xReadSlashR),
+	/*3467*/ uint16(xReadIb),
+	/*3468*/ uint16(xArgXmm1),
+	/*3469*/ uint16(xArgXmm2M128),
+	/*3470*/ uint16(xArgImm8u),
+	/*3471*/ uint16(xMatch),
+	/*3472*/ uint16(xCondPrefix), 1,
+	0x66, 3476,
+	/*3476*/ uint16(xSetOp), uint16(AESKEYGENASSIST),
+	/*3478*/ uint16(xReadSlashR),
+	/*3479*/ uint16(xReadIb),
+	/*3480*/ uint16(xArgXmm1),
+	/*3481*/ uint16(xArgXmm2M128),
+	/*3482*/ uint16(xArgImm8u),
+	/*3483*/ uint16(xMatch),
+	/*3484*/ uint16(xCondIs64), 3487, 3503,
+	/*3487*/ uint16(xCondDataSize), 3491, 3497, 0,
+	/*3491*/ uint16(xSetOp), uint16(CMOVO),
+	/*3493*/ uint16(xReadSlashR),
+	/*3494*/ uint16(xArgR16),
+	/*3495*/ uint16(xArgRM16),
+	/*3496*/ uint16(xMatch),
+	/*3497*/ uint16(xSetOp), uint16(CMOVO),
+	/*3499*/ uint16(xReadSlashR),
+	/*3500*/ uint16(xArgR32),
+	/*3501*/ uint16(xArgRM32),
+	/*3502*/ uint16(xMatch),
+	/*3503*/ uint16(xCondDataSize), 3491, 3497, 3507,
+	/*3507*/ uint16(xSetOp), uint16(CMOVO),
+	/*3509*/ uint16(xReadSlashR),
+	/*3510*/ uint16(xArgR64),
+	/*3511*/ uint16(xArgRM64),
+	/*3512*/ uint16(xMatch),
+	/*3513*/ uint16(xCondIs64), 3516, 3532,
+	/*3516*/ uint16(xCondDataSize), 3520, 3526, 0,
+	/*3520*/ uint16(xSetOp), uint16(CMOVNO),
+	/*3522*/ uint16(xReadSlashR),
+	/*3523*/ uint16(xArgR16),
+	/*3524*/ uint16(xArgRM16),
+	/*3525*/ uint16(xMatch),
+	/*3526*/ uint16(xSetOp), uint16(CMOVNO),
+	/*3528*/ uint16(xReadSlashR),
+	/*3529*/ uint16(xArgR32),
+	/*3530*/ uint16(xArgRM32),
+	/*3531*/ uint16(xMatch),
+	/*3532*/ uint16(xCondDataSize), 3520, 3526, 3536,
+	/*3536*/ uint16(xSetOp), uint16(CMOVNO),
+	/*3538*/ uint16(xReadSlashR),
+	/*3539*/ uint16(xArgR64),
+	/*3540*/ uint16(xArgRM64),
+	/*3541*/ uint16(xMatch),
+	/*3542*/ uint16(xCondIs64), 3545, 3561,
+	/*3545*/ uint16(xCondDataSize), 3549, 3555, 0,
+	/*3549*/ uint16(xSetOp), uint16(CMOVB),
+	/*3551*/ uint16(xReadSlashR),
+	/*3552*/ uint16(xArgR16),
+	/*3553*/ uint16(xArgRM16),
+	/*3554*/ uint16(xMatch),
+	/*3555*/ uint16(xSetOp), uint16(CMOVB),
+	/*3557*/ uint16(xReadSlashR),
+	/*3558*/ uint16(xArgR32),
+	/*3559*/ uint16(xArgRM32),
+	/*3560*/ uint16(xMatch),
+	/*3561*/ uint16(xCondDataSize), 3549, 3555, 3565,
+	/*3565*/ uint16(xSetOp), uint16(CMOVB),
+	/*3567*/ uint16(xReadSlashR),
+	/*3568*/ uint16(xArgR64),
+	/*3569*/ uint16(xArgRM64),
+	/*3570*/ uint16(xMatch),
+	/*3571*/ uint16(xCondIs64), 3574, 3590,
+	/*3574*/ uint16(xCondDataSize), 3578, 3584, 0,
+	/*3578*/ uint16(xSetOp), uint16(CMOVAE),
+	/*3580*/ uint16(xReadSlashR),
+	/*3581*/ uint16(xArgR16),
+	/*3582*/ uint16(xArgRM16),
+	/*3583*/ uint16(xMatch),
+	/*3584*/ uint16(xSetOp), uint16(CMOVAE),
+	/*3586*/ uint16(xReadSlashR),
+	/*3587*/ uint16(xArgR32),
+	/*3588*/ uint16(xArgRM32),
+	/*3589*/ uint16(xMatch),
+	/*3590*/ uint16(xCondDataSize), 3578, 3584, 3594,
+	/*3594*/ uint16(xSetOp), uint16(CMOVAE),
+	/*3596*/ uint16(xReadSlashR),
+	/*3597*/ uint16(xArgR64),
+	/*3598*/ uint16(xArgRM64),
+	/*3599*/ uint16(xMatch),
+	/*3600*/ uint16(xCondIs64), 3603, 3619,
+	/*3603*/ uint16(xCondDataSize), 3607, 3613, 0,
+	/*3607*/ uint16(xSetOp), uint16(CMOVE),
+	/*3609*/ uint16(xReadSlashR),
+	/*3610*/ uint16(xArgR16),
+	/*3611*/ uint16(xArgRM16),
+	/*3612*/ uint16(xMatch),
+	/*3613*/ uint16(xSetOp), uint16(CMOVE),
+	/*3615*/ uint16(xReadSlashR),
+	/*3616*/ uint16(xArgR32),
+	/*3617*/ uint16(xArgRM32),
+	/*3618*/ uint16(xMatch),
+	/*3619*/ uint16(xCondDataSize), 3607, 3613, 3623,
+	/*3623*/ uint16(xSetOp), uint16(CMOVE),
+	/*3625*/ uint16(xReadSlashR),
+	/*3626*/ uint16(xArgR64),
+	/*3627*/ uint16(xArgRM64),
+	/*3628*/ uint16(xMatch),
+	/*3629*/ uint16(xCondIs64), 3632, 3648,
+	/*3632*/ uint16(xCondDataSize), 3636, 3642, 0,
+	/*3636*/ uint16(xSetOp), uint16(CMOVNE),
+	/*3638*/ uint16(xReadSlashR),
+	/*3639*/ uint16(xArgR16),
+	/*3640*/ uint16(xArgRM16),
+	/*3641*/ uint16(xMatch),
+	/*3642*/ uint16(xSetOp), uint16(CMOVNE),
+	/*3644*/ uint16(xReadSlashR),
+	/*3645*/ uint16(xArgR32),
+	/*3646*/ uint16(xArgRM32),
+	/*3647*/ uint16(xMatch),
+	/*3648*/ uint16(xCondDataSize), 3636, 3642, 3652,
+	/*3652*/ uint16(xSetOp), uint16(CMOVNE),
+	/*3654*/ uint16(xReadSlashR),
+	/*3655*/ uint16(xArgR64),
+	/*3656*/ uint16(xArgRM64),
+	/*3657*/ uint16(xMatch),
+	/*3658*/ uint16(xCondIs64), 3661, 3677,
+	/*3661*/ uint16(xCondDataSize), 3665, 3671, 0,
+	/*3665*/ uint16(xSetOp), uint16(CMOVBE),
+	/*3667*/ uint16(xReadSlashR),
+	/*3668*/ uint16(xArgR16),
+	/*3669*/ uint16(xArgRM16),
+	/*3670*/ uint16(xMatch),
+	/*3671*/ uint16(xSetOp), uint16(CMOVBE),
+	/*3673*/ uint16(xReadSlashR),
+	/*3674*/ uint16(xArgR32),
+	/*3675*/ uint16(xArgRM32),
+	/*3676*/ uint16(xMatch),
+	/*3677*/ uint16(xCondDataSize), 3665, 3671, 3681,
+	/*3681*/ uint16(xSetOp), uint16(CMOVBE),
+	/*3683*/ uint16(xReadSlashR),
+	/*3684*/ uint16(xArgR64),
+	/*3685*/ uint16(xArgRM64),
+	/*3686*/ uint16(xMatch),
+	/*3687*/ uint16(xCondIs64), 3690, 3706,
+	/*3690*/ uint16(xCondDataSize), 3694, 3700, 0,
+	/*3694*/ uint16(xSetOp), uint16(CMOVA),
+	/*3696*/ uint16(xReadSlashR),
+	/*3697*/ uint16(xArgR16),
+	/*3698*/ uint16(xArgRM16),
+	/*3699*/ uint16(xMatch),
+	/*3700*/ uint16(xSetOp), uint16(CMOVA),
+	/*3702*/ uint16(xReadSlashR),
+	/*3703*/ uint16(xArgR32),
+	/*3704*/ uint16(xArgRM32),
+	/*3705*/ uint16(xMatch),
+	/*3706*/ uint16(xCondDataSize), 3694, 3700, 3710,
+	/*3710*/ uint16(xSetOp), uint16(CMOVA),
+	/*3712*/ uint16(xReadSlashR),
+	/*3713*/ uint16(xArgR64),
+	/*3714*/ uint16(xArgRM64),
+	/*3715*/ uint16(xMatch),
+	/*3716*/ uint16(xCondIs64), 3719, 3735,
+	/*3719*/ uint16(xCondDataSize), 3723, 3729, 0,
+	/*3723*/ uint16(xSetOp), uint16(CMOVS),
+	/*3725*/ uint16(xReadSlashR),
+	/*3726*/ uint16(xArgR16),
+	/*3727*/ uint16(xArgRM16),
+	/*3728*/ uint16(xMatch),
+	/*3729*/ uint16(xSetOp), uint16(CMOVS),
+	/*3731*/ uint16(xReadSlashR),
+	/*3732*/ uint16(xArgR32),
+	/*3733*/ uint16(xArgRM32),
+	/*3734*/ uint16(xMatch),
+	/*3735*/ uint16(xCondDataSize), 3723, 3729, 3739,
+	/*3739*/ uint16(xSetOp), uint16(CMOVS),
+	/*3741*/ uint16(xReadSlashR),
+	/*3742*/ uint16(xArgR64),
+	/*3743*/ uint16(xArgRM64),
+	/*3744*/ uint16(xMatch),
+	/*3745*/ uint16(xCondIs64), 3748, 3764,
+	/*3748*/ uint16(xCondDataSize), 3752, 3758, 0,
+	/*3752*/ uint16(xSetOp), uint16(CMOVNS),
+	/*3754*/ uint16(xReadSlashR),
+	/*3755*/ uint16(xArgR16),
+	/*3756*/ uint16(xArgRM16),
+	/*3757*/ uint16(xMatch),
+	/*3758*/ uint16(xSetOp), uint16(CMOVNS),
+	/*3760*/ uint16(xReadSlashR),
+	/*3761*/ uint16(xArgR32),
+	/*3762*/ uint16(xArgRM32),
+	/*3763*/ uint16(xMatch),
+	/*3764*/ uint16(xCondDataSize), 3752, 3758, 3768,
+	/*3768*/ uint16(xSetOp), uint16(CMOVNS),
+	/*3770*/ uint16(xReadSlashR),
+	/*3771*/ uint16(xArgR64),
+	/*3772*/ uint16(xArgRM64),
+	/*3773*/ uint16(xMatch),
+	/*3774*/ uint16(xCondIs64), 3777, 3793,
+	/*3777*/ uint16(xCondDataSize), 3781, 3787, 0,
+	/*3781*/ uint16(xSetOp), uint16(CMOVP),
+	/*3783*/ uint16(xReadSlashR),
+	/*3784*/ uint16(xArgR16),
+	/*3785*/ uint16(xArgRM16),
+	/*3786*/ uint16(xMatch),
+	/*3787*/ uint16(xSetOp), uint16(CMOVP),
+	/*3789*/ uint16(xReadSlashR),
+	/*3790*/ uint16(xArgR32),
+	/*3791*/ uint16(xArgRM32),
+	/*3792*/ uint16(xMatch),
+	/*3793*/ uint16(xCondDataSize), 3781, 3787, 3797,
+	/*3797*/ uint16(xSetOp), uint16(CMOVP),
+	/*3799*/ uint16(xReadSlashR),
+	/*3800*/ uint16(xArgR64),
+	/*3801*/ uint16(xArgRM64),
+	/*3802*/ uint16(xMatch),
+	/*3803*/ uint16(xCondIs64), 3806, 3822,
+	/*3806*/ uint16(xCondDataSize), 3810, 3816, 0,
+	/*3810*/ uint16(xSetOp), uint16(CMOVNP),
+	/*3812*/ uint16(xReadSlashR),
+	/*3813*/ uint16(xArgR16),
+	/*3814*/ uint16(xArgRM16),
+	/*3815*/ uint16(xMatch),
+	/*3816*/ uint16(xSetOp), uint16(CMOVNP),
+	/*3818*/ uint16(xReadSlashR),
+	/*3819*/ uint16(xArgR32),
+	/*3820*/ uint16(xArgRM32),
+	/*3821*/ uint16(xMatch),
+	/*3822*/ uint16(xCondDataSize), 3810, 3816, 3826,
+	/*3826*/ uint16(xSetOp), uint16(CMOVNP),
+	/*3828*/ uint16(xReadSlashR),
+	/*3829*/ uint16(xArgR64),
+	/*3830*/ uint16(xArgRM64),
+	/*3831*/ uint16(xMatch),
+	/*3832*/ uint16(xCondIs64), 3835, 3851,
+	/*3835*/ uint16(xCondDataSize), 3839, 3845, 0,
+	/*3839*/ uint16(xSetOp), uint16(CMOVL),
+	/*3841*/ uint16(xReadSlashR),
+	/*3842*/ uint16(xArgR16),
+	/*3843*/ uint16(xArgRM16),
+	/*3844*/ uint16(xMatch),
+	/*3845*/ uint16(xSetOp), uint16(CMOVL),
+	/*3847*/ uint16(xReadSlashR),
+	/*3848*/ uint16(xArgR32),
+	/*3849*/ uint16(xArgRM32),
+	/*3850*/ uint16(xMatch),
+	/*3851*/ uint16(xCondDataSize), 3839, 3845, 3855,
+	/*3855*/ uint16(xSetOp), uint16(CMOVL),
+	/*3857*/ uint16(xReadSlashR),
+	/*3858*/ uint16(xArgR64),
+	/*3859*/ uint16(xArgRM64),
+	/*3860*/ uint16(xMatch),
+	/*3861*/ uint16(xCondIs64), 3864, 3880,
+	/*3864*/ uint16(xCondDataSize), 3868, 3874, 0,
+	/*3868*/ uint16(xSetOp), uint16(CMOVGE),
+	/*3870*/ uint16(xReadSlashR),
+	/*3871*/ uint16(xArgR16),
+	/*3872*/ uint16(xArgRM16),
+	/*3873*/ uint16(xMatch),
+	/*3874*/ uint16(xSetOp), uint16(CMOVGE),
+	/*3876*/ uint16(xReadSlashR),
+	/*3877*/ uint16(xArgR32),
+	/*3878*/ uint16(xArgRM32),
+	/*3879*/ uint16(xMatch),
+	/*3880*/ uint16(xCondDataSize), 3868, 3874, 3884,
+	/*3884*/ uint16(xSetOp), uint16(CMOVGE),
+	/*3886*/ uint16(xReadSlashR),
+	/*3887*/ uint16(xArgR64),
+	/*3888*/ uint16(xArgRM64),
+	/*3889*/ uint16(xMatch),
+	/*3890*/ uint16(xCondIs64), 3893, 3909,
+	/*3893*/ uint16(xCondDataSize), 3897, 3903, 0,
+	/*3897*/ uint16(xSetOp), uint16(CMOVLE),
+	/*3899*/ uint16(xReadSlashR),
+	/*3900*/ uint16(xArgR16),
+	/*3901*/ uint16(xArgRM16),
+	/*3902*/ uint16(xMatch),
+	/*3903*/ uint16(xSetOp), uint16(CMOVLE),
+	/*3905*/ uint16(xReadSlashR),
+	/*3906*/ uint16(xArgR32),
+	/*3907*/ uint16(xArgRM32),
+	/*3908*/ uint16(xMatch),
+	/*3909*/ uint16(xCondDataSize), 3897, 3903, 3913,
+	/*3913*/ uint16(xSetOp), uint16(CMOVLE),
+	/*3915*/ uint16(xReadSlashR),
+	/*3916*/ uint16(xArgR64),
+	/*3917*/ uint16(xArgRM64),
+	/*3918*/ uint16(xMatch),
+	/*3919*/ uint16(xCondIs64), 3922, 3938,
+	/*3922*/ uint16(xCondDataSize), 3926, 3932, 0,
+	/*3926*/ uint16(xSetOp), uint16(CMOVG),
+	/*3928*/ uint16(xReadSlashR),
+	/*3929*/ uint16(xArgR16),
+	/*3930*/ uint16(xArgRM16),
+	/*3931*/ uint16(xMatch),
+	/*3932*/ uint16(xSetOp), uint16(CMOVG),
+	/*3934*/ uint16(xReadSlashR),
+	/*3935*/ uint16(xArgR32),
+	/*3936*/ uint16(xArgRM32),
+	/*3937*/ uint16(xMatch),
+	/*3938*/ uint16(xCondDataSize), 3926, 3932, 3942,
+	/*3942*/ uint16(xSetOp), uint16(CMOVG),
+	/*3944*/ uint16(xReadSlashR),
+	/*3945*/ uint16(xArgR64),
+	/*3946*/ uint16(xArgRM64),
+	/*3947*/ uint16(xMatch),
+	/*3948*/ uint16(xCondPrefix), 2,
+	0x66, 3960,
+	0x0, 3954,
+	/*3954*/ uint16(xSetOp), uint16(MOVMSKPS),
+	/*3956*/ uint16(xReadSlashR),
+	/*3957*/ uint16(xArgR32),
+	/*3958*/ uint16(xArgXmm2),
+	/*3959*/ uint16(xMatch),
+	/*3960*/ uint16(xSetOp), uint16(MOVMSKPD),
+	/*3962*/ uint16(xReadSlashR),
+	/*3963*/ uint16(xArgR32),
+	/*3964*/ uint16(xArgXmm2),
+	/*3965*/ uint16(xMatch),
+	/*3966*/ uint16(xCondPrefix), 4,
+	0xF3, 3994,
+	0xF2, 3988,
+	0x66, 3982,
+	0x0, 3976,
+	/*3976*/ uint16(xSetOp), uint16(SQRTPS),
+	/*3978*/ uint16(xReadSlashR),
+	/*3979*/ uint16(xArgXmm1),
+	/*3980*/ uint16(xArgXmm2M128),
+	/*3981*/ uint16(xMatch),
+	/*3982*/ uint16(xSetOp), uint16(SQRTPD),
+	/*3984*/ uint16(xReadSlashR),
+	/*3985*/ uint16(xArgXmm1),
+	/*3986*/ uint16(xArgXmm2M128),
+	/*3987*/ uint16(xMatch),
+	/*3988*/ uint16(xSetOp), uint16(SQRTSD),
+	/*3990*/ uint16(xReadSlashR),
+	/*3991*/ uint16(xArgXmm1),
+	/*3992*/ uint16(xArgXmm2M64),
+	/*3993*/ uint16(xMatch),
+	/*3994*/ uint16(xSetOp), uint16(SQRTSS),
+	/*3996*/ uint16(xReadSlashR),
+	/*3997*/ uint16(xArgXmm1),
+	/*3998*/ uint16(xArgXmm2M32),
+	/*3999*/ uint16(xMatch),
+	/*4000*/ uint16(xCondPrefix), 2,
+	0xF3, 4012,
+	0x0, 4006,
+	/*4006*/ uint16(xSetOp), uint16(RSQRTPS),
+	/*4008*/ uint16(xReadSlashR),
+	/*4009*/ uint16(xArgXmm1),
+	/*4010*/ uint16(xArgXmm2M128),
+	/*4011*/ uint16(xMatch),
+	/*4012*/ uint16(xSetOp), uint16(RSQRTSS),
+	/*4014*/ uint16(xReadSlashR),
+	/*4015*/ uint16(xArgXmm1),
+	/*4016*/ uint16(xArgXmm2M32),
+	/*4017*/ uint16(xMatch),
+	/*4018*/ uint16(xCondPrefix), 2,
+	0xF3, 4030,
+	0x0, 4024,
+	/*4024*/ uint16(xSetOp), uint16(RCPPS),
+	/*4026*/ uint16(xReadSlashR),
+	/*4027*/ uint16(xArgXmm1),
+	/*4028*/ uint16(xArgXmm2M128),
+	/*4029*/ uint16(xMatch),
+	/*4030*/ uint16(xSetOp), uint16(RCPSS),
+	/*4032*/ uint16(xReadSlashR),
+	/*4033*/ uint16(xArgXmm1),
+	/*4034*/ uint16(xArgXmm2M32),
+	/*4035*/ uint16(xMatch),
+	/*4036*/ uint16(xCondPrefix), 2,
+	0x66, 4048,
+	0x0, 4042,
+	/*4042*/ uint16(xSetOp), uint16(ANDPS),
+	/*4044*/ uint16(xReadSlashR),
+	/*4045*/ uint16(xArgXmm1),
+	/*4046*/ uint16(xArgXmm2M128),
+	/*4047*/ uint16(xMatch),
+	/*4048*/ uint16(xSetOp), uint16(ANDPD),
+	/*4050*/ uint16(xReadSlashR),
+	/*4051*/ uint16(xArgXmm1),
+	/*4052*/ uint16(xArgXmm2M128),
+	/*4053*/ uint16(xMatch),
+	/*4054*/ uint16(xCondPrefix), 2,
+	0x66, 4066,
+	0x0, 4060,
+	/*4060*/ uint16(xSetOp), uint16(ANDNPS),
+	/*4062*/ uint16(xReadSlashR),
+	/*4063*/ uint16(xArgXmm1),
+	/*4064*/ uint16(xArgXmm2M128),
+	/*4065*/ uint16(xMatch),
+	/*4066*/ uint16(xSetOp), uint16(ANDNPD),
+	/*4068*/ uint16(xReadSlashR),
+	/*4069*/ uint16(xArgXmm1),
+	/*4070*/ uint16(xArgXmm2M128),
+	/*4071*/ uint16(xMatch),
+	/*4072*/ uint16(xCondPrefix), 2,
+	0x66, 4084,
+	0x0, 4078,
+	/*4078*/ uint16(xSetOp), uint16(ORPS),
+	/*4080*/ uint16(xReadSlashR),
+	/*4081*/ uint16(xArgXmm1),
+	/*4082*/ uint16(xArgXmm2M128),
+	/*4083*/ uint16(xMatch),
+	/*4084*/ uint16(xSetOp), uint16(ORPD),
+	/*4086*/ uint16(xReadSlashR),
+	/*4087*/ uint16(xArgXmm1),
+	/*4088*/ uint16(xArgXmm2M128),
+	/*4089*/ uint16(xMatch),
+	/*4090*/ uint16(xCondPrefix), 2,
+	0x66, 4102,
+	0x0, 4096,
+	/*4096*/ uint16(xSetOp), uint16(XORPS),
+	/*4098*/ uint16(xReadSlashR),
+	/*4099*/ uint16(xArgXmm1),
+	/*4100*/ uint16(xArgXmm2M128),
+	/*4101*/ uint16(xMatch),
+	/*4102*/ uint16(xSetOp), uint16(XORPD),
+	/*4104*/ uint16(xReadSlashR),
+	/*4105*/ uint16(xArgXmm1),
+	/*4106*/ uint16(xArgXmm2M128),
+	/*4107*/ uint16(xMatch),
+	/*4108*/ uint16(xCondPrefix), 4,
+	0xF3, 4136,
+	0xF2, 4130,
+	0x66, 4124,
+	0x0, 4118,
+	/*4118*/ uint16(xSetOp), uint16(ADDPS),
+	/*4120*/ uint16(xReadSlashR),
+	/*4121*/ uint16(xArgXmm1),
+	/*4122*/ uint16(xArgXmm2M128),
+	/*4123*/ uint16(xMatch),
+	/*4124*/ uint16(xSetOp), uint16(ADDPD),
+	/*4126*/ uint16(xReadSlashR),
+	/*4127*/ uint16(xArgXmm1),
+	/*4128*/ uint16(xArgXmm2M128),
+	/*4129*/ uint16(xMatch),
+	/*4130*/ uint16(xSetOp), uint16(ADDSD),
+	/*4132*/ uint16(xReadSlashR),
+	/*4133*/ uint16(xArgXmm1),
+	/*4134*/ uint16(xArgXmm2M64),
+	/*4135*/ uint16(xMatch),
+	/*4136*/ uint16(xSetOp), uint16(ADDSS),
+	/*4138*/ uint16(xReadSlashR),
+	/*4139*/ uint16(xArgXmm1),
+	/*4140*/ uint16(xArgXmm2M32),
+	/*4141*/ uint16(xMatch),
+	/*4142*/ uint16(xCondPrefix), 4,
+	0xF3, 4170,
+	0xF2, 4164,
+	0x66, 4158,
+	0x0, 4152,
+	/*4152*/ uint16(xSetOp), uint16(MULPS),
+	/*4154*/ uint16(xReadSlashR),
+	/*4155*/ uint16(xArgXmm1),
+	/*4156*/ uint16(xArgXmm2M128),
+	/*4157*/ uint16(xMatch),
+	/*4158*/ uint16(xSetOp), uint16(MULPD),
+	/*4160*/ uint16(xReadSlashR),
+	/*4161*/ uint16(xArgXmm1),
+	/*4162*/ uint16(xArgXmm2M128),
+	/*4163*/ uint16(xMatch),
+	/*4164*/ uint16(xSetOp), uint16(MULSD),
+	/*4166*/ uint16(xReadSlashR),
+	/*4167*/ uint16(xArgXmm1),
+	/*4168*/ uint16(xArgXmm2M64),
+	/*4169*/ uint16(xMatch),
+	/*4170*/ uint16(xSetOp), uint16(MULSS),
+	/*4172*/ uint16(xReadSlashR),
+	/*4173*/ uint16(xArgXmm1),
+	/*4174*/ uint16(xArgXmm2M32),
+	/*4175*/ uint16(xMatch),
+	/*4176*/ uint16(xCondPrefix), 4,
+	0xF3, 4204,
+	0xF2, 4198,
+	0x66, 4192,
+	0x0, 4186,
+	/*4186*/ uint16(xSetOp), uint16(CVTPS2PD),
+	/*4188*/ uint16(xReadSlashR),
+	/*4189*/ uint16(xArgXmm1),
+	/*4190*/ uint16(xArgXmm2M64),
+	/*4191*/ uint16(xMatch),
+	/*4192*/ uint16(xSetOp), uint16(CVTPD2PS),
+	/*4194*/ uint16(xReadSlashR),
+	/*4195*/ uint16(xArgXmm1),
+	/*4196*/ uint16(xArgXmm2M128),
+	/*4197*/ uint16(xMatch),
+	/*4198*/ uint16(xSetOp), uint16(CVTSD2SS),
+	/*4200*/ uint16(xReadSlashR),
+	/*4201*/ uint16(xArgXmm1),
+	/*4202*/ uint16(xArgXmm2M64),
+	/*4203*/ uint16(xMatch),
+	/*4204*/ uint16(xSetOp), uint16(CVTSS2SD),
+	/*4206*/ uint16(xReadSlashR),
+	/*4207*/ uint16(xArgXmm1),
+	/*4208*/ uint16(xArgXmm2M32),
+	/*4209*/ uint16(xMatch),
+	/*4210*/ uint16(xCondPrefix), 3,
+	0xF3, 4230,
+	0x66, 4224,
+	0x0, 4218,
+	/*4218*/ uint16(xSetOp), uint16(CVTDQ2PS),
+	/*4220*/ uint16(xReadSlashR),
+	/*4221*/ uint16(xArgXmm1),
+	/*4222*/ uint16(xArgXmm2M128),
+	/*4223*/ uint16(xMatch),
+	/*4224*/ uint16(xSetOp), uint16(CVTPS2DQ),
+	/*4226*/ uint16(xReadSlashR),
+	/*4227*/ uint16(xArgXmm1),
+	/*4228*/ uint16(xArgXmm2M128),
+	/*4229*/ uint16(xMatch),
+	/*4230*/ uint16(xSetOp), uint16(CVTTPS2DQ),
+	/*4232*/ uint16(xReadSlashR),
+	/*4233*/ uint16(xArgXmm1),
+	/*4234*/ uint16(xArgXmm2M128),
+	/*4235*/ uint16(xMatch),
+	/*4236*/ uint16(xCondPrefix), 4,
+	0xF3, 4264,
+	0xF2, 4258,
+	0x66, 4252,
+	0x0, 4246,
+	/*4246*/ uint16(xSetOp), uint16(SUBPS),
+	/*4248*/ uint16(xReadSlashR),
+	/*4249*/ uint16(xArgXmm1),
+	/*4250*/ uint16(xArgXmm2M128),
+	/*4251*/ uint16(xMatch),
+	/*4252*/ uint16(xSetOp), uint16(SUBPD),
+	/*4254*/ uint16(xReadSlashR),
+	/*4255*/ uint16(xArgXmm1),
+	/*4256*/ uint16(xArgXmm2M128),
+	/*4257*/ uint16(xMatch),
+	/*4258*/ uint16(xSetOp), uint16(SUBSD),
+	/*4260*/ uint16(xReadSlashR),
+	/*4261*/ uint16(xArgXmm1),
+	/*4262*/ uint16(xArgXmm2M64),
+	/*4263*/ uint16(xMatch),
+	/*4264*/ uint16(xSetOp), uint16(SUBSS),
+	/*4266*/ uint16(xReadSlashR),
+	/*4267*/ uint16(xArgXmm1),
+	/*4268*/ uint16(xArgXmm2M32),
+	/*4269*/ uint16(xMatch),
+	/*4270*/ uint16(xCondPrefix), 4,
+	0xF3, 4298,
+	0xF2, 4292,
+	0x66, 4286,
+	0x0, 4280,
+	/*4280*/ uint16(xSetOp), uint16(MINPS),
+	/*4282*/ uint16(xReadSlashR),
+	/*4283*/ uint16(xArgXmm1),
+	/*4284*/ uint16(xArgXmm2M128),
+	/*4285*/ uint16(xMatch),
+	/*4286*/ uint16(xSetOp), uint16(MINPD),
+	/*4288*/ uint16(xReadSlashR),
+	/*4289*/ uint16(xArgXmm1),
+	/*4290*/ uint16(xArgXmm2M128),
+	/*4291*/ uint16(xMatch),
+	/*4292*/ uint16(xSetOp), uint16(MINSD),
+	/*4294*/ uint16(xReadSlashR),
+	/*4295*/ uint16(xArgXmm1),
+	/*4296*/ uint16(xArgXmm2M64),
+	/*4297*/ uint16(xMatch),
+	/*4298*/ uint16(xSetOp), uint16(MINSS),
+	/*4300*/ uint16(xReadSlashR),
+	/*4301*/ uint16(xArgXmm1),
+	/*4302*/ uint16(xArgXmm2M32),
+	/*4303*/ uint16(xMatch),
+	/*4304*/ uint16(xCondPrefix), 4,
+	0xF3, 4332,
+	0xF2, 4326,
+	0x66, 4320,
+	0x0, 4314,
+	/*4314*/ uint16(xSetOp), uint16(DIVPS),
+	/*4316*/ uint16(xReadSlashR),
+	/*4317*/ uint16(xArgXmm1),
+	/*4318*/ uint16(xArgXmm2M128),
+	/*4319*/ uint16(xMatch),
+	/*4320*/ uint16(xSetOp), uint16(DIVPD),
+	/*4322*/ uint16(xReadSlashR),
+	/*4323*/ uint16(xArgXmm1),
+	/*4324*/ uint16(xArgXmm2M128),
+	/*4325*/ uint16(xMatch),
+	/*4326*/ uint16(xSetOp), uint16(DIVSD),
+	/*4328*/ uint16(xReadSlashR),
+	/*4329*/ uint16(xArgXmm1),
+	/*4330*/ uint16(xArgXmm2M64),
+	/*4331*/ uint16(xMatch),
+	/*4332*/ uint16(xSetOp), uint16(DIVSS),
+	/*4334*/ uint16(xReadSlashR),
+	/*4335*/ uint16(xArgXmm1),
+	/*4336*/ uint16(xArgXmm2M32),
+	/*4337*/ uint16(xMatch),
+	/*4338*/ uint16(xCondPrefix), 4,
+	0xF3, 4366,
+	0xF2, 4360,
+	0x66, 4354,
+	0x0, 4348,
+	/*4348*/ uint16(xSetOp), uint16(MAXPS),
+	/*4350*/ uint16(xReadSlashR),
+	/*4351*/ uint16(xArgXmm1),
+	/*4352*/ uint16(xArgXmm2M128),
+	/*4353*/ uint16(xMatch),
+	/*4354*/ uint16(xSetOp), uint16(MAXPD),
+	/*4356*/ uint16(xReadSlashR),
+	/*4357*/ uint16(xArgXmm1),
+	/*4358*/ uint16(xArgXmm2M128),
+	/*4359*/ uint16(xMatch),
+	/*4360*/ uint16(xSetOp), uint16(MAXSD),
+	/*4362*/ uint16(xReadSlashR),
+	/*4363*/ uint16(xArgXmm1),
+	/*4364*/ uint16(xArgXmm2M64),
+	/*4365*/ uint16(xMatch),
+	/*4366*/ uint16(xSetOp), uint16(MAXSS),
+	/*4368*/ uint16(xReadSlashR),
+	/*4369*/ uint16(xArgXmm1),
+	/*4370*/ uint16(xArgXmm2M32),
+	/*4371*/ uint16(xMatch),
+	/*4372*/ uint16(xCondPrefix), 2,
+	0x66, 4384,
+	0x0, 4378,
+	/*4378*/ uint16(xSetOp), uint16(PUNPCKLBW),
+	/*4380*/ uint16(xReadSlashR),
+	/*4381*/ uint16(xArgMm),
+	/*4382*/ uint16(xArgMmM32),
+	/*4383*/ uint16(xMatch),
+	/*4384*/ uint16(xSetOp), uint16(PUNPCKLBW),
+	/*4386*/ uint16(xReadSlashR),
+	/*4387*/ uint16(xArgXmm1),
+	/*4388*/ uint16(xArgXmm2M128),
+	/*4389*/ uint16(xMatch),
+	/*4390*/ uint16(xCondPrefix), 2,
+	0x66, 4402,
+	0x0, 4396,
+	/*4396*/ uint16(xSetOp), uint16(PUNPCKLWD),
+	/*4398*/ uint16(xReadSlashR),
+	/*4399*/ uint16(xArgMm),
+	/*4400*/ uint16(xArgMmM32),
+	/*4401*/ uint16(xMatch),
+	/*4402*/ uint16(xSetOp), uint16(PUNPCKLWD),
+	/*4404*/ uint16(xReadSlashR),
+	/*4405*/ uint16(xArgXmm1),
+	/*4406*/ uint16(xArgXmm2M128),
+	/*4407*/ uint16(xMatch),
+	/*4408*/ uint16(xCondPrefix), 2,
+	0x66, 4420,
+	0x0, 4414,
+	/*4414*/ uint16(xSetOp), uint16(PUNPCKLDQ),
+	/*4416*/ uint16(xReadSlashR),
+	/*4417*/ uint16(xArgMm),
+	/*4418*/ uint16(xArgMmM32),
+	/*4419*/ uint16(xMatch),
+	/*4420*/ uint16(xSetOp), uint16(PUNPCKLDQ),
+	/*4422*/ uint16(xReadSlashR),
+	/*4423*/ uint16(xArgXmm1),
+	/*4424*/ uint16(xArgXmm2M128),
+	/*4425*/ uint16(xMatch),
+	/*4426*/ uint16(xCondPrefix), 2,
+	0x66, 4438,
+	0x0, 4432,
+	/*4432*/ uint16(xSetOp), uint16(PACKSSWB),
+	/*4434*/ uint16(xReadSlashR),
+	/*4435*/ uint16(xArgMm1),
+	/*4436*/ uint16(xArgMm2M64),
+	/*4437*/ uint16(xMatch),
+	/*4438*/ uint16(xSetOp), uint16(PACKSSWB),
+	/*4440*/ uint16(xReadSlashR),
+	/*4441*/ uint16(xArgXmm1),
+	/*4442*/ uint16(xArgXmm2M128),
+	/*4443*/ uint16(xMatch),
+	/*4444*/ uint16(xCondPrefix), 2,
+	0x66, 4456,
+	0x0, 4450,
+	/*4450*/ uint16(xSetOp), uint16(PCMPGTB),
+	/*4452*/ uint16(xReadSlashR),
+	/*4453*/ uint16(xArgMm),
+	/*4454*/ uint16(xArgMmM64),
+	/*4455*/ uint16(xMatch),
+	/*4456*/ uint16(xSetOp), uint16(PCMPGTB),
+	/*4458*/ uint16(xReadSlashR),
+	/*4459*/ uint16(xArgXmm1),
+	/*4460*/ uint16(xArgXmm2M128),
+	/*4461*/ uint16(xMatch),
+	/*4462*/ uint16(xCondPrefix), 2,
+	0x66, 4474,
+	0x0, 4468,
+	/*4468*/ uint16(xSetOp), uint16(PCMPGTW),
+	/*4470*/ uint16(xReadSlashR),
+	/*4471*/ uint16(xArgMm),
+	/*4472*/ uint16(xArgMmM64),
+	/*4473*/ uint16(xMatch),
+	/*4474*/ uint16(xSetOp), uint16(PCMPGTW),
+	/*4476*/ uint16(xReadSlashR),
+	/*4477*/ uint16(xArgXmm1),
+	/*4478*/ uint16(xArgXmm2M128),
+	/*4479*/ uint16(xMatch),
+	/*4480*/ uint16(xCondPrefix), 2,
+	0x66, 4492,
+	0x0, 4486,
+	/*4486*/ uint16(xSetOp), uint16(PCMPGTD),
+	/*4488*/ uint16(xReadSlashR),
+	/*4489*/ uint16(xArgMm),
+	/*4490*/ uint16(xArgMmM64),
+	/*4491*/ uint16(xMatch),
+	/*4492*/ uint16(xSetOp), uint16(PCMPGTD),
+	/*4494*/ uint16(xReadSlashR),
+	/*4495*/ uint16(xArgXmm1),
+	/*4496*/ uint16(xArgXmm2M128),
+	/*4497*/ uint16(xMatch),
+	/*4498*/ uint16(xCondPrefix), 2,
+	0x66, 4510,
+	0x0, 4504,
+	/*4504*/ uint16(xSetOp), uint16(PACKUSWB),
+	/*4506*/ uint16(xReadSlashR),
+	/*4507*/ uint16(xArgMm),
+	/*4508*/ uint16(xArgMmM64),
+	/*4509*/ uint16(xMatch),
+	/*4510*/ uint16(xSetOp), uint16(PACKUSWB),
+	/*4512*/ uint16(xReadSlashR),
+	/*4513*/ uint16(xArgXmm1),
+	/*4514*/ uint16(xArgXmm2M128),
+	/*4515*/ uint16(xMatch),
+	/*4516*/ uint16(xCondPrefix), 2,
+	0x66, 4528,
+	0x0, 4522,
+	/*4522*/ uint16(xSetOp), uint16(PUNPCKHBW),
+	/*4524*/ uint16(xReadSlashR),
+	/*4525*/ uint16(xArgMm),
+	/*4526*/ uint16(xArgMmM64),
+	/*4527*/ uint16(xMatch),
+	/*4528*/ uint16(xSetOp), uint16(PUNPCKHBW),
+	/*4530*/ uint16(xReadSlashR),
+	/*4531*/ uint16(xArgXmm1),
+	/*4532*/ uint16(xArgXmm2M128),
+	/*4533*/ uint16(xMatch),
+	/*4534*/ uint16(xCondPrefix), 2,
+	0x66, 4546,
+	0x0, 4540,
+	/*4540*/ uint16(xSetOp), uint16(PUNPCKHWD),
+	/*4542*/ uint16(xReadSlashR),
+	/*4543*/ uint16(xArgMm),
+	/*4544*/ uint16(xArgMmM64),
+	/*4545*/ uint16(xMatch),
+	/*4546*/ uint16(xSetOp), uint16(PUNPCKHWD),
+	/*4548*/ uint16(xReadSlashR),
+	/*4549*/ uint16(xArgXmm1),
+	/*4550*/ uint16(xArgXmm2M128),
+	/*4551*/ uint16(xMatch),
+	/*4552*/ uint16(xCondPrefix), 2,
+	0x66, 4564,
+	0x0, 4558,
+	/*4558*/ uint16(xSetOp), uint16(PUNPCKHDQ),
+	/*4560*/ uint16(xReadSlashR),
+	/*4561*/ uint16(xArgMm),
+	/*4562*/ uint16(xArgMmM64),
+	/*4563*/ uint16(xMatch),
+	/*4564*/ uint16(xSetOp), uint16(PUNPCKHDQ),
+	/*4566*/ uint16(xReadSlashR),
+	/*4567*/ uint16(xArgXmm1),
+	/*4568*/ uint16(xArgXmm2M128),
+	/*4569*/ uint16(xMatch),
+	/*4570*/ uint16(xCondPrefix), 2,
+	0x66, 4582,
+	0x0, 4576,
+	/*4576*/ uint16(xSetOp), uint16(PACKSSDW),
+	/*4578*/ uint16(xReadSlashR),
+	/*4579*/ uint16(xArgMm1),
+	/*4580*/ uint16(xArgMm2M64),
+	/*4581*/ uint16(xMatch),
+	/*4582*/ uint16(xSetOp), uint16(PACKSSDW),
+	/*4584*/ uint16(xReadSlashR),
+	/*4585*/ uint16(xArgXmm1),
+	/*4586*/ uint16(xArgXmm2M128),
+	/*4587*/ uint16(xMatch),
+	/*4588*/ uint16(xCondPrefix), 1,
+	0x66, 4592,
+	/*4592*/ uint16(xSetOp), uint16(PUNPCKLQDQ),
+	/*4594*/ uint16(xReadSlashR),
+	/*4595*/ uint16(xArgXmm1),
+	/*4596*/ uint16(xArgXmm2M128),
+	/*4597*/ uint16(xMatch),
+	/*4598*/ uint16(xCondPrefix), 1,
+	0x66, 4602,
+	/*4602*/ uint16(xSetOp), uint16(PUNPCKHQDQ),
+	/*4604*/ uint16(xReadSlashR),
+	/*4605*/ uint16(xArgXmm1),
+	/*4606*/ uint16(xArgXmm2M128),
+	/*4607*/ uint16(xMatch),
+	/*4608*/ uint16(xCondIs64), 4611, 4649,
+	/*4611*/ uint16(xCondPrefix), 2,
+	0x66, 4633,
+	0x0, 4617,
+	/*4617*/ uint16(xCondDataSize), 4621, 4627, 0,
+	/*4621*/ uint16(xSetOp), uint16(MOVD),
+	/*4623*/ uint16(xReadSlashR),
+	/*4624*/ uint16(xArgMm),
+	/*4625*/ uint16(xArgRM32),
+	/*4626*/ uint16(xMatch),
+	/*4627*/ uint16(xSetOp), uint16(MOVD),
+	/*4629*/ uint16(xReadSlashR),
+	/*4630*/ uint16(xArgMm),
+	/*4631*/ uint16(xArgRM32),
+	/*4632*/ uint16(xMatch),
+	/*4633*/ uint16(xCondDataSize), 4637, 4643, 0,
+	/*4637*/ uint16(xSetOp), uint16(MOVD),
+	/*4639*/ uint16(xReadSlashR),
+	/*4640*/ uint16(xArgXmm),
+	/*4641*/ uint16(xArgRM32),
+	/*4642*/ uint16(xMatch),
+	/*4643*/ uint16(xSetOp), uint16(MOVD),
+	/*4645*/ uint16(xReadSlashR),
+	/*4646*/ uint16(xArgXmm),
+	/*4647*/ uint16(xArgRM32),
+	/*4648*/ uint16(xMatch),
+	/*4649*/ uint16(xCondPrefix), 2,
+	0x66, 4665,
+	0x0, 4655,
+	/*4655*/ uint16(xCondDataSize), 4621, 4627, 4659,
+	/*4659*/ uint16(xSetOp), uint16(MOVQ),
+	/*4661*/ uint16(xReadSlashR),
+	/*4662*/ uint16(xArgMm),
+	/*4663*/ uint16(xArgRM64),
+	/*4664*/ uint16(xMatch),
+	/*4665*/ uint16(xCondDataSize), 4637, 4643, 4669,
+	/*4669*/ uint16(xSetOp), uint16(MOVQ),
+	/*4671*/ uint16(xReadSlashR),
+	/*4672*/ uint16(xArgXmm),
+	/*4673*/ uint16(xArgRM64),
+	/*4674*/ uint16(xMatch),
+	/*4675*/ uint16(xCondPrefix), 3,
+	0xF3, 4695,
+	0x66, 4689,
+	0x0, 4683,
+	/*4683*/ uint16(xSetOp), uint16(MOVQ),
+	/*4685*/ uint16(xReadSlashR),
+	/*4686*/ uint16(xArgMm),
+	/*4687*/ uint16(xArgMmM64),
+	/*4688*/ uint16(xMatch),
+	/*4689*/ uint16(xSetOp), uint16(MOVDQA),
+	/*4691*/ uint16(xReadSlashR),
+	/*4692*/ uint16(xArgXmm1),
+	/*4693*/ uint16(xArgXmm2M128),
+	/*4694*/ uint16(xMatch),
+	/*4695*/ uint16(xSetOp), uint16(MOVDQU),
+	/*4697*/ uint16(xReadSlashR),
+	/*4698*/ uint16(xArgXmm1),
+	/*4699*/ uint16(xArgXmm2M128),
+	/*4700*/ uint16(xMatch),
+	/*4701*/ uint16(xCondPrefix), 4,
+	0xF3, 4735,
+	0xF2, 4727,
+	0x66, 4719,
+	0x0, 4711,
+	/*4711*/ uint16(xSetOp), uint16(PSHUFW),
+	/*4713*/ uint16(xReadSlashR),
+	/*4714*/ uint16(xReadIb),
+	/*4715*/ uint16(xArgMm1),
+	/*4716*/ uint16(xArgMm2M64),
+	/*4717*/ uint16(xArgImm8u),
+	/*4718*/ uint16(xMatch),
+	/*4719*/ uint16(xSetOp), uint16(PSHUFD),
+	/*4721*/ uint16(xReadSlashR),
+	/*4722*/ uint16(xReadIb),
+	/*4723*/ uint16(xArgXmm1),
+	/*4724*/ uint16(xArgXmm2M128),
+	/*4725*/ uint16(xArgImm8u),
+	/*4726*/ uint16(xMatch),
+	/*4727*/ uint16(xSetOp), uint16(PSHUFLW),
+	/*4729*/ uint16(xReadSlashR),
+	/*4730*/ uint16(xReadIb),
+	/*4731*/ uint16(xArgXmm1),
+	/*4732*/ uint16(xArgXmm2M128),
+	/*4733*/ uint16(xArgImm8u),
+	/*4734*/ uint16(xMatch),
+	/*4735*/ uint16(xSetOp), uint16(PSHUFHW),
+	/*4737*/ uint16(xReadSlashR),
+	/*4738*/ uint16(xReadIb),
+	/*4739*/ uint16(xArgXmm1),
+	/*4740*/ uint16(xArgXmm2M128),
+	/*4741*/ uint16(xArgImm8u),
+	/*4742*/ uint16(xMatch),
+	/*4743*/ uint16(xCondSlashR),
+	0,    // 0
+	0,    // 1
+	4752, // 2
+	0,    // 3
+	4770, // 4
+	0,    // 5
+	4788, // 6
+	0,    // 7
+	/*4752*/ uint16(xCondPrefix), 2,
+	0x66, 4764,
+	0x0, 4758,
+	/*4758*/ uint16(xSetOp), uint16(PSRLW),
+	/*4760*/ uint16(xReadIb),
+	/*4761*/ uint16(xArgMm2),
+	/*4762*/ uint16(xArgImm8u),
+	/*4763*/ uint16(xMatch),
+	/*4764*/ uint16(xSetOp), uint16(PSRLW),
+	/*4766*/ uint16(xReadIb),
+	/*4767*/ uint16(xArgXmm2),
+	/*4768*/ uint16(xArgImm8u),
+	/*4769*/ uint16(xMatch),
+	/*4770*/ uint16(xCondPrefix), 2,
+	0x66, 4782,
+	0x0, 4776,
+	/*4776*/ uint16(xSetOp), uint16(PSRAW),
+	/*4778*/ uint16(xReadIb),
+	/*4779*/ uint16(xArgMm2),
+	/*4780*/ uint16(xArgImm8u),
+	/*4781*/ uint16(xMatch),
+	/*4782*/ uint16(xSetOp), uint16(PSRAW),
+	/*4784*/ uint16(xReadIb),
+	/*4785*/ uint16(xArgXmm2),
+	/*4786*/ uint16(xArgImm8u),
+	/*4787*/ uint16(xMatch),
+	/*4788*/ uint16(xCondPrefix), 2,
+	0x66, 4800,
+	0x0, 4794,
+	/*4794*/ uint16(xSetOp), uint16(PSLLW),
+	/*4796*/ uint16(xReadIb),
+	/*4797*/ uint16(xArgMm2),
+	/*4798*/ uint16(xArgImm8u),
+	/*4799*/ uint16(xMatch),
+	/*4800*/ uint16(xSetOp), uint16(PSLLW),
+	/*4802*/ uint16(xReadIb),
+	/*4803*/ uint16(xArgXmm2),
+	/*4804*/ uint16(xArgImm8u),
+	/*4805*/ uint16(xMatch),
+	/*4806*/ uint16(xCondSlashR),
+	0,    // 0
+	0,    // 1
+	4815, // 2
+	0,    // 3
+	4833, // 4
+	0,    // 5
+	4851, // 6
+	0,    // 7
+	/*4815*/ uint16(xCondPrefix), 2,
+	0x66, 4827,
+	0x0, 4821,
+	/*4821*/ uint16(xSetOp), uint16(PSRLD),
+	/*4823*/ uint16(xReadIb),
+	/*4824*/ uint16(xArgMm2),
+	/*4825*/ uint16(xArgImm8u),
+	/*4826*/ uint16(xMatch),
+	/*4827*/ uint16(xSetOp), uint16(PSRLD),
+	/*4829*/ uint16(xReadIb),
+	/*4830*/ uint16(xArgXmm2),
+	/*4831*/ uint16(xArgImm8u),
+	/*4832*/ uint16(xMatch),
+	/*4833*/ uint16(xCondPrefix), 2,
+	0x66, 4845,
+	0x0, 4839,
+	/*4839*/ uint16(xSetOp), uint16(PSRAD),
+	/*4841*/ uint16(xReadIb),
+	/*4842*/ uint16(xArgMm2),
+	/*4843*/ uint16(xArgImm8u),
+	/*4844*/ uint16(xMatch),
+	/*4845*/ uint16(xSetOp), uint16(PSRAD),
+	/*4847*/ uint16(xReadIb),
+	/*4848*/ uint16(xArgXmm2),
+	/*4849*/ uint16(xArgImm8u),
+	/*4850*/ uint16(xMatch),
+	/*4851*/ uint16(xCondPrefix), 2,
+	0x66, 4863,
+	0x0, 4857,
+	/*4857*/ uint16(xSetOp), uint16(PSLLD),
+	/*4859*/ uint16(xReadIb),
+	/*4860*/ uint16(xArgMm2),
+	/*4861*/ uint16(xArgImm8u),
+	/*4862*/ uint16(xMatch),
+	/*4863*/ uint16(xSetOp), uint16(PSLLD),
+	/*4865*/ uint16(xReadIb),
+	/*4866*/ uint16(xArgXmm2),
+	/*4867*/ uint16(xArgImm8u),
+	/*4868*/ uint16(xMatch),
+	/*4869*/ uint16(xCondSlashR),
+	0,    // 0
+	0,    // 1
+	4878, // 2
+	4896, // 3
+	0,    // 4
+	0,    // 5
+	4906, // 6
+	4924, // 7
+	/*4878*/ uint16(xCondPrefix), 2,
+	0x66, 4890,
+	0x0, 4884,
+	/*4884*/ uint16(xSetOp), uint16(PSRLQ),
+	/*4886*/ uint16(xReadIb),
+	/*4887*/ uint16(xArgMm2),
+	/*4888*/ uint16(xArgImm8u),
+	/*4889*/ uint16(xMatch),
+	/*4890*/ uint16(xSetOp), uint16(PSRLQ),
+	/*4892*/ uint16(xReadIb),
+	/*4893*/ uint16(xArgXmm2),
+	/*4894*/ uint16(xArgImm8u),
+	/*4895*/ uint16(xMatch),
+	/*4896*/ uint16(xCondPrefix), 1,
+	0x66, 4900,
+	/*4900*/ uint16(xSetOp), uint16(PSRLDQ),
+	/*4902*/ uint16(xReadIb),
+	/*4903*/ uint16(xArgXmm2),
+	/*4904*/ uint16(xArgImm8u),
+	/*4905*/ uint16(xMatch),
+	/*4906*/ uint16(xCondPrefix), 2,
+	0x66, 4918,
+	0x0, 4912,
+	/*4912*/ uint16(xSetOp), uint16(PSLLQ),
+	/*4914*/ uint16(xReadIb),
+	/*4915*/ uint16(xArgMm2),
+	/*4916*/ uint16(xArgImm8u),
+	/*4917*/ uint16(xMatch),
+	/*4918*/ uint16(xSetOp), uint16(PSLLQ),
+	/*4920*/ uint16(xReadIb),
+	/*4921*/ uint16(xArgXmm2),
+	/*4922*/ uint16(xArgImm8u),
+	/*4923*/ uint16(xMatch),
+	/*4924*/ uint16(xCondPrefix), 1,
+	0x66, 4928,
+	/*4928*/ uint16(xSetOp), uint16(PSLLDQ),
+	/*4930*/ uint16(xReadIb),
+	/*4931*/ uint16(xArgXmm2),
+	/*4932*/ uint16(xArgImm8u),
+	/*4933*/ uint16(xMatch),
+	/*4934*/ uint16(xCondPrefix), 2,
+	0x66, 4946,
+	0x0, 4940,
+	/*4940*/ uint16(xSetOp), uint16(PCMPEQB),
+	/*4942*/ uint16(xReadSlashR),
+	/*4943*/ uint16(xArgMm),
+	/*4944*/ uint16(xArgMmM64),
+	/*4945*/ uint16(xMatch),
+	/*4946*/ uint16(xSetOp), uint16(PCMPEQB),
+	/*4948*/ uint16(xReadSlashR),
+	/*4949*/ uint16(xArgXmm1),
+	/*4950*/ uint16(xArgXmm2M128),
+	/*4951*/ uint16(xMatch),
+	/*4952*/ uint16(xCondPrefix), 2,
+	0x66, 4964,
+	0x0, 4958,
+	/*4958*/ uint16(xSetOp), uint16(PCMPEQW),
+	/*4960*/ uint16(xReadSlashR),
+	/*4961*/ uint16(xArgMm),
+	/*4962*/ uint16(xArgMmM64),
+	/*4963*/ uint16(xMatch),
+	/*4964*/ uint16(xSetOp), uint16(PCMPEQW),
+	/*4966*/ uint16(xReadSlashR),
+	/*4967*/ uint16(xArgXmm1),
+	/*4968*/ uint16(xArgXmm2M128),
+	/*4969*/ uint16(xMatch),
+	/*4970*/ uint16(xCondPrefix), 2,
+	0x66, 4982,
+	0x0, 4976,
+	/*4976*/ uint16(xSetOp), uint16(PCMPEQD),
+	/*4978*/ uint16(xReadSlashR),
+	/*4979*/ uint16(xArgMm),
+	/*4980*/ uint16(xArgMmM64),
+	/*4981*/ uint16(xMatch),
+	/*4982*/ uint16(xSetOp), uint16(PCMPEQD),
+	/*4984*/ uint16(xReadSlashR),
+	/*4985*/ uint16(xArgXmm1),
+	/*4986*/ uint16(xArgXmm2M128),
+	/*4987*/ uint16(xMatch),
+	/*4988*/ uint16(xSetOp), uint16(EMMS),
+	/*4990*/ uint16(xMatch),
+	/*4991*/ uint16(xCondPrefix), 2,
+	0xF2, 5003,
+	0x66, 4997,
+	/*4997*/ uint16(xSetOp), uint16(HADDPD),
+	/*4999*/ uint16(xReadSlashR),
+	/*5000*/ uint16(xArgXmm1),
+	/*5001*/ uint16(xArgXmm2M128),
+	/*5002*/ uint16(xMatch),
+	/*5003*/ uint16(xSetOp), uint16(HADDPS),
+	/*5005*/ uint16(xReadSlashR),
+	/*5006*/ uint16(xArgXmm1),
+	/*5007*/ uint16(xArgXmm2M128),
+	/*5008*/ uint16(xMatch),
+	/*5009*/ uint16(xCondPrefix), 2,
+	0xF2, 5021,
+	0x66, 5015,
+	/*5015*/ uint16(xSetOp), uint16(HSUBPD),
+	/*5017*/ uint16(xReadSlashR),
+	/*5018*/ uint16(xArgXmm1),
+	/*5019*/ uint16(xArgXmm2M128),
+	/*5020*/ uint16(xMatch),
+	/*5021*/ uint16(xSetOp), uint16(HSUBPS),
+	/*5023*/ uint16(xReadSlashR),
+	/*5024*/ uint16(xArgXmm1),
+	/*5025*/ uint16(xArgXmm2M128),
+	/*5026*/ uint16(xMatch),
+	/*5027*/ uint16(xCondIs64), 5030, 5076,
+	/*5030*/ uint16(xCondPrefix), 3,
+	0xF3, 5070,
+	0x66, 5054,
+	0x0, 5038,
+	/*5038*/ uint16(xCondDataSize), 5042, 5048, 0,
+	/*5042*/ uint16(xSetOp), uint16(MOVD),
+	/*5044*/ uint16(xReadSlashR),
+	/*5045*/ uint16(xArgRM32),
+	/*5046*/ uint16(xArgMm),
+	/*5047*/ uint16(xMatch),
+	/*5048*/ uint16(xSetOp), uint16(MOVD),
+	/*5050*/ uint16(xReadSlashR),
+	/*5051*/ uint16(xArgRM32),
+	/*5052*/ uint16(xArgMm),
+	/*5053*/ uint16(xMatch),
+	/*5054*/ uint16(xCondDataSize), 5058, 5064, 0,
+	/*5058*/ uint16(xSetOp), uint16(MOVD),
+	/*5060*/ uint16(xReadSlashR),
+	/*5061*/ uint16(xArgRM32),
+	/*5062*/ uint16(xArgXmm),
+	/*5063*/ uint16(xMatch),
+	/*5064*/ uint16(xSetOp), uint16(MOVD),
+	/*5066*/ uint16(xReadSlashR),
+	/*5067*/ uint16(xArgRM32),
+	/*5068*/ uint16(xArgXmm),
+	/*5069*/ uint16(xMatch),
+	/*5070*/ uint16(xSetOp), uint16(MOVQ),
+	/*5072*/ uint16(xReadSlashR),
+	/*5073*/ uint16(xArgXmm1),
+	/*5074*/ uint16(xArgXmm2M64),
+	/*5075*/ uint16(xMatch),
+	/*5076*/ uint16(xCondPrefix), 3,
+	0xF3, 5070,
+	0x66, 5094,
+	0x0, 5084,
+	/*5084*/ uint16(xCondDataSize), 5042, 5048, 5088,
+	/*5088*/ uint16(xSetOp), uint16(MOVQ),
+	/*5090*/ uint16(xReadSlashR),
+	/*5091*/ uint16(xArgRM64),
+	/*5092*/ uint16(xArgMm),
+	/*5093*/ uint16(xMatch),
+	/*5094*/ uint16(xCondDataSize), 5058, 5064, 5098,
+	/*5098*/ uint16(xSetOp), uint16(MOVQ),
+	/*5100*/ uint16(xReadSlashR),
+	/*5101*/ uint16(xArgRM64),
+	/*5102*/ uint16(xArgXmm),
+	/*5103*/ uint16(xMatch),
+	/*5104*/ uint16(xCondPrefix), 3,
+	0xF3, 5124,
+	0x66, 5118,
+	0x0, 5112,
+	/*5112*/ uint16(xSetOp), uint16(MOVQ),
+	/*5114*/ uint16(xReadSlashR),
+	/*5115*/ uint16(xArgMmM64),
+	/*5116*/ uint16(xArgMm),
+	/*5117*/ uint16(xMatch),
+	/*5118*/ uint16(xSetOp), uint16(MOVDQA),
+	/*5120*/ uint16(xReadSlashR),
+	/*5121*/ uint16(xArgXmm2M128),
+	/*5122*/ uint16(xArgXmm1),
+	/*5123*/ uint16(xMatch),
+	/*5124*/ uint16(xSetOp), uint16(MOVDQU),
+	/*5126*/ uint16(xReadSlashR),
+	/*5127*/ uint16(xArgXmm2M128),
+	/*5128*/ uint16(xArgXmm1),
+	/*5129*/ uint16(xMatch),
+	/*5130*/ uint16(xCondIs64), 5133, 5147,
+	/*5133*/ uint16(xCondDataSize), 5137, 5142, 0,
+	/*5137*/ uint16(xSetOp), uint16(JO),
+	/*5139*/ uint16(xReadCw),
+	/*5140*/ uint16(xArgRel16),
+	/*5141*/ uint16(xMatch),
+	/*5142*/ uint16(xSetOp), uint16(JO),
+	/*5144*/ uint16(xReadCd),
+	/*5145*/ uint16(xArgRel32),
+	/*5146*/ uint16(xMatch),
+	/*5147*/ uint16(xCondDataSize), 5151, 5142, 5156,
+	/*5151*/ uint16(xSetOp), uint16(JO),
+	/*5153*/ uint16(xReadCd),
+	/*5154*/ uint16(xArgRel32),
+	/*5155*/ uint16(xMatch),
+	/*5156*/ uint16(xSetOp), uint16(JO),
+	/*5158*/ uint16(xReadCd),
+	/*5159*/ uint16(xArgRel32),
+	/*5160*/ uint16(xMatch),
+	/*5161*/ uint16(xCondIs64), 5164, 5178,
+	/*5164*/ uint16(xCondDataSize), 5168, 5173, 0,
+	/*5168*/ uint16(xSetOp), uint16(JNO),
+	/*5170*/ uint16(xReadCw),
+	/*5171*/ uint16(xArgRel16),
+	/*5172*/ uint16(xMatch),
+	/*5173*/ uint16(xSetOp), uint16(JNO),
+	/*5175*/ uint16(xReadCd),
+	/*5176*/ uint16(xArgRel32),
+	/*5177*/ uint16(xMatch),
+	/*5178*/ uint16(xCondDataSize), 5182, 5173, 5187,
+	/*5182*/ uint16(xSetOp), uint16(JNO),
+	/*5184*/ uint16(xReadCd),
+	/*5185*/ uint16(xArgRel32),
+	/*5186*/ uint16(xMatch),
+	/*5187*/ uint16(xSetOp), uint16(JNO),
+	/*5189*/ uint16(xReadCd),
+	/*5190*/ uint16(xArgRel32),
+	/*5191*/ uint16(xMatch),
+	/*5192*/ uint16(xCondIs64), 5195, 5209,
+	/*5195*/ uint16(xCondDataSize), 5199, 5204, 0,
+	/*5199*/ uint16(xSetOp), uint16(JB),
+	/*5201*/ uint16(xReadCw),
+	/*5202*/ uint16(xArgRel16),
+	/*5203*/ uint16(xMatch),
+	/*5204*/ uint16(xSetOp), uint16(JB),
+	/*5206*/ uint16(xReadCd),
+	/*5207*/ uint16(xArgRel32),
+	/*5208*/ uint16(xMatch),
+	/*5209*/ uint16(xCondDataSize), 5213, 5204, 5218,
+	/*5213*/ uint16(xSetOp), uint16(JB),
+	/*5215*/ uint16(xReadCd),
+	/*5216*/ uint16(xArgRel32),
+	/*5217*/ uint16(xMatch),
+	/*5218*/ uint16(xSetOp), uint16(JB),
+	/*5220*/ uint16(xReadCd),
+	/*5221*/ uint16(xArgRel32),
+	/*5222*/ uint16(xMatch),
+	/*5223*/ uint16(xCondIs64), 5226, 5240,
+	/*5226*/ uint16(xCondDataSize), 5230, 5235, 0,
+	/*5230*/ uint16(xSetOp), uint16(JAE),
+	/*5232*/ uint16(xReadCw),
+	/*5233*/ uint16(xArgRel16),
+	/*5234*/ uint16(xMatch),
+	/*5235*/ uint16(xSetOp), uint16(JAE),
+	/*5237*/ uint16(xReadCd),
+	/*5238*/ uint16(xArgRel32),
+	/*5239*/ uint16(xMatch),
+	/*5240*/ uint16(xCondDataSize), 5244, 5235, 5249,
+	/*5244*/ uint16(xSetOp), uint16(JAE),
+	/*5246*/ uint16(xReadCd),
+	/*5247*/ uint16(xArgRel32),
+	/*5248*/ uint16(xMatch),
+	/*5249*/ uint16(xSetOp), uint16(JAE),
+	/*5251*/ uint16(xReadCd),
+	/*5252*/ uint16(xArgRel32),
+	/*5253*/ uint16(xMatch),
+	/*5254*/ uint16(xCondIs64), 5257, 5271,
+	/*5257*/ uint16(xCondDataSize), 5261, 5266, 0,
+	/*5261*/ uint16(xSetOp), uint16(JE),
+	/*5263*/ uint16(xReadCw),
+	/*5264*/ uint16(xArgRel16),
+	/*5265*/ uint16(xMatch),
+	/*5266*/ uint16(xSetOp), uint16(JE),
+	/*5268*/ uint16(xReadCd),
+	/*5269*/ uint16(xArgRel32),
+	/*5270*/ uint16(xMatch),
+	/*5271*/ uint16(xCondDataSize), 5275, 5266, 5280,
+	/*5275*/ uint16(xSetOp), uint16(JE),
+	/*5277*/ uint16(xReadCd),
+	/*5278*/ uint16(xArgRel32),
+	/*5279*/ uint16(xMatch),
+	/*5280*/ uint16(xSetOp), uint16(JE),
+	/*5282*/ uint16(xReadCd),
+	/*5283*/ uint16(xArgRel32),
+	/*5284*/ uint16(xMatch),
+	/*5285*/ uint16(xCondIs64), 5288, 5302,
+	/*5288*/ uint16(xCondDataSize), 5292, 5297, 0,
+	/*5292*/ uint16(xSetOp), uint16(JNE),
+	/*5294*/ uint16(xReadCw),
+	/*5295*/ uint16(xArgRel16),
+	/*5296*/ uint16(xMatch),
+	/*5297*/ uint16(xSetOp), uint16(JNE),
+	/*5299*/ uint16(xReadCd),
+	/*5300*/ uint16(xArgRel32),
+	/*5301*/ uint16(xMatch),
+	/*5302*/ uint16(xCondDataSize), 5306, 5297, 5311,
+	/*5306*/ uint16(xSetOp), uint16(JNE),
+	/*5308*/ uint16(xReadCd),
+	/*5309*/ uint16(xArgRel32),
+	/*5310*/ uint16(xMatch),
+	/*5311*/ uint16(xSetOp), uint16(JNE),
+	/*5313*/ uint16(xReadCd),
+	/*5314*/ uint16(xArgRel32),
+	/*5315*/ uint16(xMatch),
+	/*5316*/ uint16(xCondIs64), 5319, 5333,
+	/*5319*/ uint16(xCondDataSize), 5323, 5328, 0,
+	/*5323*/ uint16(xSetOp), uint16(JBE),
+	/*5325*/ uint16(xReadCw),
+	/*5326*/ uint16(xArgRel16),
+	/*5327*/ uint16(xMatch),
+	/*5328*/ uint16(xSetOp), uint16(JBE),
+	/*5330*/ uint16(xReadCd),
+	/*5331*/ uint16(xArgRel32),
+	/*5332*/ uint16(xMatch),
+	/*5333*/ uint16(xCondDataSize), 5337, 5328, 5342,
+	/*5337*/ uint16(xSetOp), uint16(JBE),
+	/*5339*/ uint16(xReadCd),
+	/*5340*/ uint16(xArgRel32),
+	/*5341*/ uint16(xMatch),
+	/*5342*/ uint16(xSetOp), uint16(JBE),
+	/*5344*/ uint16(xReadCd),
+	/*5345*/ uint16(xArgRel32),
+	/*5346*/ uint16(xMatch),
+	/*5347*/ uint16(xCondIs64), 5350, 5364,
+	/*5350*/ uint16(xCondDataSize), 5354, 5359, 0,
+	/*5354*/ uint16(xSetOp), uint16(JA),
+	/*5356*/ uint16(xReadCw),
+	/*5357*/ uint16(xArgRel16),
+	/*5358*/ uint16(xMatch),
+	/*5359*/ uint16(xSetOp), uint16(JA),
+	/*5361*/ uint16(xReadCd),
+	/*5362*/ uint16(xArgRel32),
+	/*5363*/ uint16(xMatch),
+	/*5364*/ uint16(xCondDataSize), 5368, 5359, 5373,
+	/*5368*/ uint16(xSetOp), uint16(JA),
+	/*5370*/ uint16(xReadCd),
+	/*5371*/ uint16(xArgRel32),
+	/*5372*/ uint16(xMatch),
+	/*5373*/ uint16(xSetOp), uint16(JA),
+	/*5375*/ uint16(xReadCd),
+	/*5376*/ uint16(xArgRel32),
+	/*5377*/ uint16(xMatch),
+	/*5378*/ uint16(xCondIs64), 5381, 5395,
+	/*5381*/ uint16(xCondDataSize), 5385, 5390, 0,
+	/*5385*/ uint16(xSetOp), uint16(JS),
+	/*5387*/ uint16(xReadCw),
+	/*5388*/ uint16(xArgRel16),
+	/*5389*/ uint16(xMatch),
+	/*5390*/ uint16(xSetOp), uint16(JS),
+	/*5392*/ uint16(xReadCd),
+	/*5393*/ uint16(xArgRel32),
+	/*5394*/ uint16(xMatch),
+	/*5395*/ uint16(xCondDataSize), 5399, 5390, 5404,
+	/*5399*/ uint16(xSetOp), uint16(JS),
+	/*5401*/ uint16(xReadCd),
+	/*5402*/ uint16(xArgRel32),
+	/*5403*/ uint16(xMatch),
+	/*5404*/ uint16(xSetOp), uint16(JS),
+	/*5406*/ uint16(xReadCd),
+	/*5407*/ uint16(xArgRel32),
+	/*5408*/ uint16(xMatch),
+	/*5409*/ uint16(xCondIs64), 5412, 5426,
+	/*5412*/ uint16(xCondDataSize), 5416, 5421, 0,
+	/*5416*/ uint16(xSetOp), uint16(JNS),
+	/*5418*/ uint16(xReadCw),
+	/*5419*/ uint16(xArgRel16),
+	/*5420*/ uint16(xMatch),
+	/*5421*/ uint16(xSetOp), uint16(JNS),
+	/*5423*/ uint16(xReadCd),
+	/*5424*/ uint16(xArgRel32),
+	/*5425*/ uint16(xMatch),
+	/*5426*/ uint16(xCondDataSize), 5430, 5421, 5435,
+	/*5430*/ uint16(xSetOp), uint16(JNS),
+	/*5432*/ uint16(xReadCd),
+	/*5433*/ uint16(xArgRel32),
+	/*5434*/ uint16(xMatch),
+	/*5435*/ uint16(xSetOp), uint16(JNS),
+	/*5437*/ uint16(xReadCd),
+	/*5438*/ uint16(xArgRel32),
+	/*5439*/ uint16(xMatch),
+	/*5440*/ uint16(xCondIs64), 5443, 5457,
+	/*5443*/ uint16(xCondDataSize), 5447, 5452, 0,
+	/*5447*/ uint16(xSetOp), uint16(JP),
+	/*5449*/ uint16(xReadCw),
+	/*5450*/ uint16(xArgRel16),
+	/*5451*/ uint16(xMatch),
+	/*5452*/ uint16(xSetOp), uint16(JP),
+	/*5454*/ uint16(xReadCd),
+	/*5455*/ uint16(xArgRel32),
+	/*5456*/ uint16(xMatch),
+	/*5457*/ uint16(xCondDataSize), 5461, 5452, 5466,
+	/*5461*/ uint16(xSetOp), uint16(JP),
+	/*5463*/ uint16(xReadCd),
+	/*5464*/ uint16(xArgRel32),
+	/*5465*/ uint16(xMatch),
+	/*5466*/ uint16(xSetOp), uint16(JP),
+	/*5468*/ uint16(xReadCd),
+	/*5469*/ uint16(xArgRel32),
+	/*5470*/ uint16(xMatch),
+	/*5471*/ uint16(xCondIs64), 5474, 5488,
+	/*5474*/ uint16(xCondDataSize), 5478, 5483, 0,
+	/*5478*/ uint16(xSetOp), uint16(JNP),
+	/*5480*/ uint16(xReadCw),
+	/*5481*/ uint16(xArgRel16),
+	/*5482*/ uint16(xMatch),
+	/*5483*/ uint16(xSetOp), uint16(JNP),
+	/*5485*/ uint16(xReadCd),
+	/*5486*/ uint16(xArgRel32),
+	/*5487*/ uint16(xMatch),
+	/*5488*/ uint16(xCondDataSize), 5492, 5483, 5497,
+	/*5492*/ uint16(xSetOp), uint16(JNP),
+	/*5494*/ uint16(xReadCd),
+	/*5495*/ uint16(xArgRel32),
+	/*5496*/ uint16(xMatch),
+	/*5497*/ uint16(xSetOp), uint16(JNP),
+	/*5499*/ uint16(xReadCd),
+	/*5500*/ uint16(xArgRel32),
+	/*5501*/ uint16(xMatch),
+	/*5502*/ uint16(xCondIs64), 5505, 5519,
+	/*5505*/ uint16(xCondDataSize), 5509, 5514, 0,
+	/*5509*/ uint16(xSetOp), uint16(JL),
+	/*5511*/ uint16(xReadCw),
+	/*5512*/ uint16(xArgRel16),
+	/*5513*/ uint16(xMatch),
+	/*5514*/ uint16(xSetOp), uint16(JL),
+	/*5516*/ uint16(xReadCd),
+	/*5517*/ uint16(xArgRel32),
+	/*5518*/ uint16(xMatch),
+	/*5519*/ uint16(xCondDataSize), 5523, 5514, 5528,
+	/*5523*/ uint16(xSetOp), uint16(JL),
+	/*5525*/ uint16(xReadCd),
+	/*5526*/ uint16(xArgRel32),
+	/*5527*/ uint16(xMatch),
+	/*5528*/ uint16(xSetOp), uint16(JL),
+	/*5530*/ uint16(xReadCd),
+	/*5531*/ uint16(xArgRel32),
+	/*5532*/ uint16(xMatch),
+	/*5533*/ uint16(xCondIs64), 5536, 5550,
+	/*5536*/ uint16(xCondDataSize), 5540, 5545, 0,
+	/*5540*/ uint16(xSetOp), uint16(JGE),
+	/*5542*/ uint16(xReadCw),
+	/*5543*/ uint16(xArgRel16),
+	/*5544*/ uint16(xMatch),
+	/*5545*/ uint16(xSetOp), uint16(JGE),
+	/*5547*/ uint16(xReadCd),
+	/*5548*/ uint16(xArgRel32),
+	/*5549*/ uint16(xMatch),
+	/*5550*/ uint16(xCondDataSize), 5554, 5545, 5559,
+	/*5554*/ uint16(xSetOp), uint16(JGE),
+	/*5556*/ uint16(xReadCd),
+	/*5557*/ uint16(xArgRel32),
+	/*5558*/ uint16(xMatch),
+	/*5559*/ uint16(xSetOp), uint16(JGE),
+	/*5561*/ uint16(xReadCd),
+	/*5562*/ uint16(xArgRel32),
+	/*5563*/ uint16(xMatch),
+	/*5564*/ uint16(xCondIs64), 5567, 5581,
+	/*5567*/ uint16(xCondDataSize), 5571, 5576, 0,
+	/*5571*/ uint16(xSetOp), uint16(JLE),
+	/*5573*/ uint16(xReadCw),
+	/*5574*/ uint16(xArgRel16),
+	/*5575*/ uint16(xMatch),
+	/*5576*/ uint16(xSetOp), uint16(JLE),
+	/*5578*/ uint16(xReadCd),
+	/*5579*/ uint16(xArgRel32),
+	/*5580*/ uint16(xMatch),
+	/*5581*/ uint16(xCondDataSize), 5585, 5576, 5590,
+	/*5585*/ uint16(xSetOp), uint16(JLE),
+	/*5587*/ uint16(xReadCd),
+	/*5588*/ uint16(xArgRel32),
+	/*5589*/ uint16(xMatch),
+	/*5590*/ uint16(xSetOp), uint16(JLE),
+	/*5592*/ uint16(xReadCd),
+	/*5593*/ uint16(xArgRel32),
+	/*5594*/ uint16(xMatch),
+	/*5595*/ uint16(xCondIs64), 5598, 5612,
+	/*5598*/ uint16(xCondDataSize), 5602, 5607, 0,
+	/*5602*/ uint16(xSetOp), uint16(JG),
+	/*5604*/ uint16(xReadCw),
+	/*5605*/ uint16(xArgRel16),
+	/*5606*/ uint16(xMatch),
+	/*5607*/ uint16(xSetOp), uint16(JG),
+	/*5609*/ uint16(xReadCd),
+	/*5610*/ uint16(xArgRel32),
+	/*5611*/ uint16(xMatch),
+	/*5612*/ uint16(xCondDataSize), 5616, 5607, 5621,
+	/*5616*/ uint16(xSetOp), uint16(JG),
+	/*5618*/ uint16(xReadCd),
+	/*5619*/ uint16(xArgRel32),
+	/*5620*/ uint16(xMatch),
+	/*5621*/ uint16(xSetOp), uint16(JG),
+	/*5623*/ uint16(xReadCd),
+	/*5624*/ uint16(xArgRel32),
+	/*5625*/ uint16(xMatch),
+	/*5626*/ uint16(xSetOp), uint16(SETO),
+	/*5628*/ uint16(xReadSlashR),
+	/*5629*/ uint16(xArgRM8),
+	/*5630*/ uint16(xMatch),
+	/*5631*/ uint16(xSetOp), uint16(SETNO),
+	/*5633*/ uint16(xReadSlashR),
+	/*5634*/ uint16(xArgRM8),
+	/*5635*/ uint16(xMatch),
+	/*5636*/ uint16(xSetOp), uint16(SETB),
+	/*5638*/ uint16(xReadSlashR),
+	/*5639*/ uint16(xArgRM8),
+	/*5640*/ uint16(xMatch),
+	/*5641*/ uint16(xSetOp), uint16(SETAE),
+	/*5643*/ uint16(xReadSlashR),
+	/*5644*/ uint16(xArgRM8),
+	/*5645*/ uint16(xMatch),
+	/*5646*/ uint16(xSetOp), uint16(SETE),
+	/*5648*/ uint16(xReadSlashR),
+	/*5649*/ uint16(xArgRM8),
+	/*5650*/ uint16(xMatch),
+	/*5651*/ uint16(xSetOp), uint16(SETNE),
+	/*5653*/ uint16(xReadSlashR),
+	/*5654*/ uint16(xArgRM8),
+	/*5655*/ uint16(xMatch),
+	/*5656*/ uint16(xSetOp), uint16(SETBE),
+	/*5658*/ uint16(xReadSlashR),
+	/*5659*/ uint16(xArgRM8),
+	/*5660*/ uint16(xMatch),
+	/*5661*/ uint16(xSetOp), uint16(SETA),
+	/*5663*/ uint16(xReadSlashR),
+	/*5664*/ uint16(xArgRM8),
+	/*5665*/ uint16(xMatch),
+	/*5666*/ uint16(xSetOp), uint16(SETS),
+	/*5668*/ uint16(xReadSlashR),
+	/*5669*/ uint16(xArgRM8),
+	/*5670*/ uint16(xMatch),
+	/*5671*/ uint16(xSetOp), uint16(SETNS),
+	/*5673*/ uint16(xReadSlashR),
+	/*5674*/ uint16(xArgRM8),
+	/*5675*/ uint16(xMatch),
+	/*5676*/ uint16(xSetOp), uint16(SETP),
+	/*5678*/ uint16(xReadSlashR),
+	/*5679*/ uint16(xArgRM8),
+	/*5680*/ uint16(xMatch),
+	/*5681*/ uint16(xSetOp), uint16(SETNP),
+	/*5683*/ uint16(xReadSlashR),
+	/*5684*/ uint16(xArgRM8),
+	/*5685*/ uint16(xMatch),
+	/*5686*/ uint16(xSetOp), uint16(SETL),
+	/*5688*/ uint16(xReadSlashR),
+	/*5689*/ uint16(xArgRM8),
+	/*5690*/ uint16(xMatch),
+	/*5691*/ uint16(xSetOp), uint16(SETGE),
+	/*5693*/ uint16(xReadSlashR),
+	/*5694*/ uint16(xArgRM8),
+	/*5695*/ uint16(xMatch),
+	/*5696*/ uint16(xSetOp), uint16(SETLE),
+	/*5698*/ uint16(xReadSlashR),
+	/*5699*/ uint16(xArgRM8),
+	/*5700*/ uint16(xMatch),
+	/*5701*/ uint16(xSetOp), uint16(SETG),
+	/*5703*/ uint16(xReadSlashR),
+	/*5704*/ uint16(xArgRM8),
+	/*5705*/ uint16(xMatch),
+	/*5706*/ uint16(xSetOp), uint16(PUSH),
+	/*5708*/ uint16(xArgFS),
+	/*5709*/ uint16(xMatch),
+	/*5710*/ uint16(xCondIs64), 5713, 5725,
+	/*5713*/ uint16(xCondDataSize), 5717, 5721, 0,
+	/*5717*/ uint16(xSetOp), uint16(POP),
+	/*5719*/ uint16(xArgFS),
+	/*5720*/ uint16(xMatch),
+	/*5721*/ uint16(xSetOp), uint16(POP),
+	/*5723*/ uint16(xArgFS),
+	/*5724*/ uint16(xMatch),
+	/*5725*/ uint16(xCondDataSize), 5717, 5729, 5733,
+	/*5729*/ uint16(xSetOp), uint16(POP),
+	/*5731*/ uint16(xArgFS),
+	/*5732*/ uint16(xMatch),
+	/*5733*/ uint16(xSetOp), uint16(POP),
+	/*5735*/ uint16(xArgFS),
+	/*5736*/ uint16(xMatch),
+	/*5737*/ uint16(xSetOp), uint16(CPUID),
+	/*5739*/ uint16(xMatch),
+	/*5740*/ uint16(xCondIs64), 5743, 5759,
+	/*5743*/ uint16(xCondDataSize), 5747, 5753, 0,
+	/*5747*/ uint16(xSetOp), uint16(BT),
+	/*5749*/ uint16(xReadSlashR),
+	/*5750*/ uint16(xArgRM16),
+	/*5751*/ uint16(xArgR16),
+	/*5752*/ uint16(xMatch),
+	/*5753*/ uint16(xSetOp), uint16(BT),
+	/*5755*/ uint16(xReadSlashR),
+	/*5756*/ uint16(xArgRM32),
+	/*5757*/ uint16(xArgR32),
+	/*5758*/ uint16(xMatch),
+	/*5759*/ uint16(xCondDataSize), 5747, 5753, 5763,
+	/*5763*/ uint16(xSetOp), uint16(BT),
+	/*5765*/ uint16(xReadSlashR),
+	/*5766*/ uint16(xArgRM64),
+	/*5767*/ uint16(xArgR64),
+	/*5768*/ uint16(xMatch),
+	/*5769*/ uint16(xCondIs64), 5772, 5792,
+	/*5772*/ uint16(xCondDataSize), 5776, 5784, 0,
+	/*5776*/ uint16(xSetOp), uint16(SHLD),
+	/*5778*/ uint16(xReadSlashR),
+	/*5779*/ uint16(xReadIb),
+	/*5780*/ uint16(xArgRM16),
+	/*5781*/ uint16(xArgR16),
+	/*5782*/ uint16(xArgImm8u),
+	/*5783*/ uint16(xMatch),
+	/*5784*/ uint16(xSetOp), uint16(SHLD),
+	/*5786*/ uint16(xReadSlashR),
+	/*5787*/ uint16(xReadIb),
+	/*5788*/ uint16(xArgRM32),
+	/*5789*/ uint16(xArgR32),
+	/*5790*/ uint16(xArgImm8u),
+	/*5791*/ uint16(xMatch),
+	/*5792*/ uint16(xCondDataSize), 5776, 5784, 5796,
+	/*5796*/ uint16(xSetOp), uint16(SHLD),
+	/*5798*/ uint16(xReadSlashR),
+	/*5799*/ uint16(xReadIb),
+	/*5800*/ uint16(xArgRM64),
+	/*5801*/ uint16(xArgR64),
+	/*5802*/ uint16(xArgImm8u),
+	/*5803*/ uint16(xMatch),
+	/*5804*/ uint16(xCondIs64), 5807, 5825,
+	/*5807*/ uint16(xCondDataSize), 5811, 5818, 0,
+	/*5811*/ uint16(xSetOp), uint16(SHLD),
+	/*5813*/ uint16(xReadSlashR),
+	/*5814*/ uint16(xArgRM16),
+	/*5815*/ uint16(xArgR16),
+	/*5816*/ uint16(xArgCL),
+	/*5817*/ uint16(xMatch),
+	/*5818*/ uint16(xSetOp), uint16(SHLD),
+	/*5820*/ uint16(xReadSlashR),
+	/*5821*/ uint16(xArgRM32),
+	/*5822*/ uint16(xArgR32),
+	/*5823*/ uint16(xArgCL),
+	/*5824*/ uint16(xMatch),
+	/*5825*/ uint16(xCondDataSize), 5811, 5818, 5829,
+	/*5829*/ uint16(xSetOp), uint16(SHLD),
+	/*5831*/ uint16(xReadSlashR),
+	/*5832*/ uint16(xArgRM64),
+	/*5833*/ uint16(xArgR64),
+	/*5834*/ uint16(xArgCL),
+	/*5835*/ uint16(xMatch),
+	/*5836*/ uint16(xSetOp), uint16(PUSH),
+	/*5838*/ uint16(xArgGS),
+	/*5839*/ uint16(xMatch),
+	/*5840*/ uint16(xCondIs64), 5843, 5855,
+	/*5843*/ uint16(xCondDataSize), 5847, 5851, 0,
+	/*5847*/ uint16(xSetOp), uint16(POP),
+	/*5849*/ uint16(xArgGS),
+	/*5850*/ uint16(xMatch),
+	/*5851*/ uint16(xSetOp), uint16(POP),
+	/*5853*/ uint16(xArgGS),
+	/*5854*/ uint16(xMatch),
+	/*5855*/ uint16(xCondDataSize), 5847, 5859, 5863,
+	/*5859*/ uint16(xSetOp), uint16(POP),
+	/*5861*/ uint16(xArgGS),
+	/*5862*/ uint16(xMatch),
+	/*5863*/ uint16(xSetOp), uint16(POP),
+	/*5865*/ uint16(xArgGS),
+	/*5866*/ uint16(xMatch),
+	/*5867*/ uint16(xSetOp), uint16(RSM),
+	/*5869*/ uint16(xMatch),
+	/*5870*/ uint16(xCondIs64), 5873, 5889,
+	/*5873*/ uint16(xCondDataSize), 5877, 5883, 0,
+	/*5877*/ uint16(xSetOp), uint16(BTS),
+	/*5879*/ uint16(xReadSlashR),
+	/*5880*/ uint16(xArgRM16),
+	/*5881*/ uint16(xArgR16),
+	/*5882*/ uint16(xMatch),
+	/*5883*/ uint16(xSetOp), uint16(BTS),
+	/*5885*/ uint16(xReadSlashR),
+	/*5886*/ uint16(xArgRM32),
+	/*5887*/ uint16(xArgR32),
+	/*5888*/ uint16(xMatch),
+	/*5889*/ uint16(xCondDataSize), 5877, 5883, 5893,
+	/*5893*/ uint16(xSetOp), uint16(BTS),
+	/*5895*/ uint16(xReadSlashR),
+	/*5896*/ uint16(xArgRM64),
+	/*5897*/ uint16(xArgR64),
+	/*5898*/ uint16(xMatch),
+	/*5899*/ uint16(xCondIs64), 5902, 5922,
+	/*5902*/ uint16(xCondDataSize), 5906, 5914, 0,
+	/*5906*/ uint16(xSetOp), uint16(SHRD),
+	/*5908*/ uint16(xReadSlashR),
+	/*5909*/ uint16(xReadIb),
+	/*5910*/ uint16(xArgRM16),
+	/*5911*/ uint16(xArgR16),
+	/*5912*/ uint16(xArgImm8u),
+	/*5913*/ uint16(xMatch),
+	/*5914*/ uint16(xSetOp), uint16(SHRD),
+	/*5916*/ uint16(xReadSlashR),
+	/*5917*/ uint16(xReadIb),
+	/*5918*/ uint16(xArgRM32),
+	/*5919*/ uint16(xArgR32),
+	/*5920*/ uint16(xArgImm8u),
+	/*5921*/ uint16(xMatch),
+	/*5922*/ uint16(xCondDataSize), 5906, 5914, 5926,
+	/*5926*/ uint16(xSetOp), uint16(SHRD),
+	/*5928*/ uint16(xReadSlashR),
+	/*5929*/ uint16(xReadIb),
+	/*5930*/ uint16(xArgRM64),
+	/*5931*/ uint16(xArgR64),
+	/*5932*/ uint16(xArgImm8u),
+	/*5933*/ uint16(xMatch),
+	/*5934*/ uint16(xCondIs64), 5937, 5955,
+	/*5937*/ uint16(xCondDataSize), 5941, 5948, 0,
+	/*5941*/ uint16(xSetOp), uint16(SHRD),
+	/*5943*/ uint16(xReadSlashR),
+	/*5944*/ uint16(xArgRM16),
+	/*5945*/ uint16(xArgR16),
+	/*5946*/ uint16(xArgCL),
+	/*5947*/ uint16(xMatch),
+	/*5948*/ uint16(xSetOp), uint16(SHRD),
+	/*5950*/ uint16(xReadSlashR),
+	/*5951*/ uint16(xArgRM32),
+	/*5952*/ uint16(xArgR32),
+	/*5953*/ uint16(xArgCL),
+	/*5954*/ uint16(xMatch),
+	/*5955*/ uint16(xCondDataSize), 5941, 5948, 5959,
+	/*5959*/ uint16(xSetOp), uint16(SHRD),
+	/*5961*/ uint16(xReadSlashR),
+	/*5962*/ uint16(xArgRM64),
+	/*5963*/ uint16(xArgR64),
+	/*5964*/ uint16(xArgCL),
+	/*5965*/ uint16(xMatch),
+	/*5966*/ uint16(xCondByte), 3,
+	0xE8, 6215,
+	0xF0, 6218,
+	0xF8, 6221,
+	/*5974*/ uint16(xCondSlashR),
+	5983, // 0
+	6037, // 1
+	6091, // 2
+	6120, // 3
+	6149, // 4
+	6172, // 5
+	6195, // 6
+	6211, // 7
+	/*5983*/ uint16(xCondIs64), 5986, 5998,
+	/*5986*/ uint16(xCondDataSize), 5990, 5994, 0,
+	/*5990*/ uint16(xSetOp), uint16(FXSAVE),
+	/*5992*/ uint16(xArgM512byte),
+	/*5993*/ uint16(xMatch),
+	/*5994*/ uint16(xSetOp), uint16(FXSAVE),
+	/*5996*/ uint16(xArgM512byte),
+	/*5997*/ uint16(xMatch),
+	/*5998*/ uint16(xCondPrefix), 2,
+	0xF3, 6012,
+	0x0, 6004,
+	/*6004*/ uint16(xCondDataSize), 5990, 5994, 6008,
+	/*6008*/ uint16(xSetOp), uint16(FXSAVE64),
+	/*6010*/ uint16(xArgM512byte),
+	/*6011*/ uint16(xMatch),
+	/*6012*/ uint16(xCondDataSize), 6016, 6023, 6030,
+	/*6016*/ uint16(xCondIsMem), 6019, 0,
+	/*6019*/ uint16(xSetOp), uint16(RDFSBASE),
+	/*6021*/ uint16(xArgRM32),
+	/*6022*/ uint16(xMatch),
+	/*6023*/ uint16(xCondIsMem), 6026, 0,
+	/*6026*/ uint16(xSetOp), uint16(RDFSBASE),
+	/*6028*/ uint16(xArgRM32),
+	/*6029*/ uint16(xMatch),
+	/*6030*/ uint16(xCondIsMem), 6033, 0,
+	/*6033*/ uint16(xSetOp), uint16(RDFSBASE),
+	/*6035*/ uint16(xArgRM64),
+	/*6036*/ uint16(xMatch),
+	/*6037*/ uint16(xCondIs64), 6040, 6052,
+	/*6040*/ uint16(xCondDataSize), 6044, 6048, 0,
+	/*6044*/ uint16(xSetOp), uint16(FXRSTOR),
+	/*6046*/ uint16(xArgM512byte),
+	/*6047*/ uint16(xMatch),
+	/*6048*/ uint16(xSetOp), uint16(FXRSTOR),
+	/*6050*/ uint16(xArgM512byte),
+	/*6051*/ uint16(xMatch),
+	/*6052*/ uint16(xCondPrefix), 2,
+	0xF3, 6066,
+	0x0, 6058,
+	/*6058*/ uint16(xCondDataSize), 6044, 6048, 6062,
+	/*6062*/ uint16(xSetOp), uint16(FXRSTOR64),
+	/*6064*/ uint16(xArgM512byte),
+	/*6065*/ uint16(xMatch),
+	/*6066*/ uint16(xCondDataSize), 6070, 6077, 6084,
+	/*6070*/ uint16(xCondIsMem), 6073, 0,
+	/*6073*/ uint16(xSetOp), uint16(RDGSBASE),
+	/*6075*/ uint16(xArgRM32),
+	/*6076*/ uint16(xMatch),
+	/*6077*/ uint16(xCondIsMem), 6080, 0,
+	/*6080*/ uint16(xSetOp), uint16(RDGSBASE),
+	/*6082*/ uint16(xArgRM32),
+	/*6083*/ uint16(xMatch),
+	/*6084*/ uint16(xCondIsMem), 6087, 0,
+	/*6087*/ uint16(xSetOp), uint16(RDGSBASE),
+	/*6089*/ uint16(xArgRM64),
+	/*6090*/ uint16(xMatch),
+	/*6091*/ uint16(xCondIs64), 6094, 6098,
+	/*6094*/ uint16(xSetOp), uint16(LDMXCSR),
+	/*6096*/ uint16(xArgM32),
+	/*6097*/ uint16(xMatch),
+	/*6098*/ uint16(xCondPrefix), 2,
+	0xF3, 6104,
+	0x0, 6094,
+	/*6104*/ uint16(xCondDataSize), 6108, 6112, 6116,
+	/*6108*/ uint16(xSetOp), uint16(WRFSBASE),
+	/*6110*/ uint16(xArgRM32),
+	/*6111*/ uint16(xMatch),
+	/*6112*/ uint16(xSetOp), uint16(WRFSBASE),
+	/*6114*/ uint16(xArgRM32),
+	/*6115*/ uint16(xMatch),
+	/*6116*/ uint16(xSetOp), uint16(WRFSBASE),
+	/*6118*/ uint16(xArgRM64),
+	/*6119*/ uint16(xMatch),
+	/*6120*/ uint16(xCondIs64), 6123, 6127,
+	/*6123*/ uint16(xSetOp), uint16(STMXCSR),
+	/*6125*/ uint16(xArgM32),
+	/*6126*/ uint16(xMatch),
+	/*6127*/ uint16(xCondPrefix), 2,
+	0xF3, 6133,
+	0x0, 6123,
+	/*6133*/ uint16(xCondDataSize), 6137, 6141, 6145,
+	/*6137*/ uint16(xSetOp), uint16(WRGSBASE),
+	/*6139*/ uint16(xArgRM32),
+	/*6140*/ uint16(xMatch),
+	/*6141*/ uint16(xSetOp), uint16(WRGSBASE),
+	/*6143*/ uint16(xArgRM32),
+	/*6144*/ uint16(xMatch),
+	/*6145*/ uint16(xSetOp), uint16(WRGSBASE),
+	/*6147*/ uint16(xArgRM64),
+	/*6148*/ uint16(xMatch),
+	/*6149*/ uint16(xCondIs64), 6152, 6164,
+	/*6152*/ uint16(xCondDataSize), 6156, 6160, 0,
+	/*6156*/ uint16(xSetOp), uint16(XSAVE),
+	/*6158*/ uint16(xArgMem),
+	/*6159*/ uint16(xMatch),
+	/*6160*/ uint16(xSetOp), uint16(XSAVE),
+	/*6162*/ uint16(xArgMem),
+	/*6163*/ uint16(xMatch),
+	/*6164*/ uint16(xCondDataSize), 6156, 6160, 6168,
+	/*6168*/ uint16(xSetOp), uint16(XSAVE64),
+	/*6170*/ uint16(xArgMem),
+	/*6171*/ uint16(xMatch),
+	/*6172*/ uint16(xCondIs64), 6175, 6187,
+	/*6175*/ uint16(xCondDataSize), 6179, 6183, 0,
+	/*6179*/ uint16(xSetOp), uint16(XRSTOR),
+	/*6181*/ uint16(xArgMem),
+	/*6182*/ uint16(xMatch),
+	/*6183*/ uint16(xSetOp), uint16(XRSTOR),
+	/*6185*/ uint16(xArgMem),
+	/*6186*/ uint16(xMatch),
+	/*6187*/ uint16(xCondDataSize), 6179, 6183, 6191,
+	/*6191*/ uint16(xSetOp), uint16(XRSTOR64),
+	/*6193*/ uint16(xArgMem),
+	/*6194*/ uint16(xMatch),
+	/*6195*/ uint16(xCondDataSize), 6199, 6203, 6207,
+	/*6199*/ uint16(xSetOp), uint16(XSAVEOPT),
+	/*6201*/ uint16(xArgMem),
+	/*6202*/ uint16(xMatch),
+	/*6203*/ uint16(xSetOp), uint16(XSAVEOPT),
+	/*6205*/ uint16(xArgMem),
+	/*6206*/ uint16(xMatch),
+	/*6207*/ uint16(xSetOp), uint16(XSAVEOPT64),
+	/*6209*/ uint16(xArgMem),
+	/*6210*/ uint16(xMatch),
+	/*6211*/ uint16(xSetOp), uint16(CLFLUSH),
+	/*6213*/ uint16(xArgM8),
+	/*6214*/ uint16(xMatch),
+	/*6215*/ uint16(xSetOp), uint16(LFENCE),
+	/*6217*/ uint16(xMatch),
+	/*6218*/ uint16(xSetOp), uint16(MFENCE),
+	/*6220*/ uint16(xMatch),
+	/*6221*/ uint16(xSetOp), uint16(SFENCE),
+	/*6223*/ uint16(xMatch),
+	/*6224*/ uint16(xCondIs64), 6227, 6243,
+	/*6227*/ uint16(xCondDataSize), 6231, 6237, 0,
+	/*6231*/ uint16(xSetOp), uint16(IMUL),
+	/*6233*/ uint16(xReadSlashR),
+	/*6234*/ uint16(xArgR16),
+	/*6235*/ uint16(xArgRM16),
+	/*6236*/ uint16(xMatch),
+	/*6237*/ uint16(xSetOp), uint16(IMUL),
+	/*6239*/ uint16(xReadSlashR),
+	/*6240*/ uint16(xArgR32),
+	/*6241*/ uint16(xArgRM32),
+	/*6242*/ uint16(xMatch),
+	/*6243*/ uint16(xCondDataSize), 6231, 6237, 6247,
+	/*6247*/ uint16(xSetOp), uint16(IMUL),
+	/*6249*/ uint16(xReadSlashR),
+	/*6250*/ uint16(xArgR64),
+	/*6251*/ uint16(xArgRM64),
+	/*6252*/ uint16(xMatch),
+	/*6253*/ uint16(xSetOp), uint16(CMPXCHG),
+	/*6255*/ uint16(xReadSlashR),
+	/*6256*/ uint16(xArgRM8),
+	/*6257*/ uint16(xArgR8),
+	/*6258*/ uint16(xMatch),
+	/*6259*/ uint16(xCondIs64), 6262, 6278,
+	/*6262*/ uint16(xCondDataSize), 6266, 6272, 0,
+	/*6266*/ uint16(xSetOp), uint16(CMPXCHG),
+	/*6268*/ uint16(xReadSlashR),
+	/*6269*/ uint16(xArgRM16),
+	/*6270*/ uint16(xArgR16),
+	/*6271*/ uint16(xMatch),
+	/*6272*/ uint16(xSetOp), uint16(CMPXCHG),
+	/*6274*/ uint16(xReadSlashR),
+	/*6275*/ uint16(xArgRM32),
+	/*6276*/ uint16(xArgR32),
+	/*6277*/ uint16(xMatch),
+	/*6278*/ uint16(xCondDataSize), 6266, 6272, 6282,
+	/*6282*/ uint16(xSetOp), uint16(CMPXCHG),
+	/*6284*/ uint16(xReadSlashR),
+	/*6285*/ uint16(xArgRM64),
+	/*6286*/ uint16(xArgR64),
+	/*6287*/ uint16(xMatch),
+	/*6288*/ uint16(xCondIs64), 6291, 6307,
+	/*6291*/ uint16(xCondDataSize), 6295, 6301, 0,
+	/*6295*/ uint16(xSetOp), uint16(LSS),
+	/*6297*/ uint16(xReadSlashR),
+	/*6298*/ uint16(xArgR16),
+	/*6299*/ uint16(xArgM16colon16),
+	/*6300*/ uint16(xMatch),
+	/*6301*/ uint16(xSetOp), uint16(LSS),
+	/*6303*/ uint16(xReadSlashR),
+	/*6304*/ uint16(xArgR32),
+	/*6305*/ uint16(xArgM16colon32),
+	/*6306*/ uint16(xMatch),
+	/*6307*/ uint16(xCondDataSize), 6295, 6301, 6311,
+	/*6311*/ uint16(xSetOp), uint16(LSS),
+	/*6313*/ uint16(xReadSlashR),
+	/*6314*/ uint16(xArgR64),
+	/*6315*/ uint16(xArgM16colon64),
+	/*6316*/ uint16(xMatch),
+	/*6317*/ uint16(xCondIs64), 6320, 6336,
+	/*6320*/ uint16(xCondDataSize), 6324, 6330, 0,
+	/*6324*/ uint16(xSetOp), uint16(BTR),
+	/*6326*/ uint16(xReadSlashR),
+	/*6327*/ uint16(xArgRM16),
+	/*6328*/ uint16(xArgR16),
+	/*6329*/ uint16(xMatch),
+	/*6330*/ uint16(xSetOp), uint16(BTR),
+	/*6332*/ uint16(xReadSlashR),
+	/*6333*/ uint16(xArgRM32),
+	/*6334*/ uint16(xArgR32),
+	/*6335*/ uint16(xMatch),
+	/*6336*/ uint16(xCondDataSize), 6324, 6330, 6340,
+	/*6340*/ uint16(xSetOp), uint16(BTR),
+	/*6342*/ uint16(xReadSlashR),
+	/*6343*/ uint16(xArgRM64),
+	/*6344*/ uint16(xArgR64),
+	/*6345*/ uint16(xMatch),
+	/*6346*/ uint16(xCondIs64), 6349, 6365,
+	/*6349*/ uint16(xCondDataSize), 6353, 6359, 0,
+	/*6353*/ uint16(xSetOp), uint16(LFS),
+	/*6355*/ uint16(xReadSlashR),
+	/*6356*/ uint16(xArgR16),
+	/*6357*/ uint16(xArgM16colon16),
+	/*6358*/ uint16(xMatch),
+	/*6359*/ uint16(xSetOp), uint16(LFS),
+	/*6361*/ uint16(xReadSlashR),
+	/*6362*/ uint16(xArgR32),
+	/*6363*/ uint16(xArgM16colon32),
+	/*6364*/ uint16(xMatch),
+	/*6365*/ uint16(xCondDataSize), 6353, 6359, 6369,
+	/*6369*/ uint16(xSetOp), uint16(LFS),
+	/*6371*/ uint16(xReadSlashR),
+	/*6372*/ uint16(xArgR64),
+	/*6373*/ uint16(xArgM16colon64),
+	/*6374*/ uint16(xMatch),
+	/*6375*/ uint16(xCondIs64), 6378, 6394,
+	/*6378*/ uint16(xCondDataSize), 6382, 6388, 0,
+	/*6382*/ uint16(xSetOp), uint16(LGS),
+	/*6384*/ uint16(xReadSlashR),
+	/*6385*/ uint16(xArgR16),
+	/*6386*/ uint16(xArgM16colon16),
+	/*6387*/ uint16(xMatch),
+	/*6388*/ uint16(xSetOp), uint16(LGS),
+	/*6390*/ uint16(xReadSlashR),
+	/*6391*/ uint16(xArgR32),
+	/*6392*/ uint16(xArgM16colon32),
+	/*6393*/ uint16(xMatch),
+	/*6394*/ uint16(xCondDataSize), 6382, 6388, 6398,
+	/*6398*/ uint16(xSetOp), uint16(LGS),
+	/*6400*/ uint16(xReadSlashR),
+	/*6401*/ uint16(xArgR64),
+	/*6402*/ uint16(xArgM16colon64),
+	/*6403*/ uint16(xMatch),
+	/*6404*/ uint16(xCondIs64), 6407, 6423,
+	/*6407*/ uint16(xCondDataSize), 6411, 6417, 0,
+	/*6411*/ uint16(xSetOp), uint16(MOVZX),
+	/*6413*/ uint16(xReadSlashR),
+	/*6414*/ uint16(xArgR16),
+	/*6415*/ uint16(xArgRM8),
+	/*6416*/ uint16(xMatch),
+	/*6417*/ uint16(xSetOp), uint16(MOVZX),
+	/*6419*/ uint16(xReadSlashR),
+	/*6420*/ uint16(xArgR32),
+	/*6421*/ uint16(xArgRM8),
+	/*6422*/ uint16(xMatch),
+	/*6423*/ uint16(xCondDataSize), 6411, 6417, 6427,
+	/*6427*/ uint16(xSetOp), uint16(MOVZX),
+	/*6429*/ uint16(xReadSlashR),
+	/*6430*/ uint16(xArgR64),
+	/*6431*/ uint16(xArgRM8),
+	/*6432*/ uint16(xMatch),
+	/*6433*/ uint16(xCondIs64), 6436, 6452,
+	/*6436*/ uint16(xCondDataSize), 6440, 6446, 0,
+	/*6440*/ uint16(xSetOp), uint16(MOVZX),
+	/*6442*/ uint16(xReadSlashR),
+	/*6443*/ uint16(xArgR16),
+	/*6444*/ uint16(xArgRM16),
+	/*6445*/ uint16(xMatch),
+	/*6446*/ uint16(xSetOp), uint16(MOVZX),
+	/*6448*/ uint16(xReadSlashR),
+	/*6449*/ uint16(xArgR32),
+	/*6450*/ uint16(xArgRM16),
+	/*6451*/ uint16(xMatch),
+	/*6452*/ uint16(xCondDataSize), 6440, 6446, 6456,
+	/*6456*/ uint16(xSetOp), uint16(MOVZX),
+	/*6458*/ uint16(xReadSlashR),
+	/*6459*/ uint16(xArgR64),
+	/*6460*/ uint16(xArgRM16),
+	/*6461*/ uint16(xMatch),
+	/*6462*/ uint16(xCondIs64), 6465, 6485,
+	/*6465*/ uint16(xCondPrefix), 1,
+	0xF3, 6469,
+	/*6469*/ uint16(xCondDataSize), 6473, 6479, 0,
+	/*6473*/ uint16(xSetOp), uint16(POPCNT),
+	/*6475*/ uint16(xReadSlashR),
+	/*6476*/ uint16(xArgR16),
+	/*6477*/ uint16(xArgRM16),
+	/*6478*/ uint16(xMatch),
+	/*6479*/ uint16(xSetOp), uint16(POPCNT),
+	/*6481*/ uint16(xReadSlashR),
+	/*6482*/ uint16(xArgR32),
+	/*6483*/ uint16(xArgRM32),
+	/*6484*/ uint16(xMatch),
+	/*6485*/ uint16(xCondPrefix), 1,
+	0xF3, 6489,
+	/*6489*/ uint16(xCondDataSize), 6473, 6479, 6493,
+	/*6493*/ uint16(xSetOp), uint16(POPCNT),
+	/*6495*/ uint16(xReadSlashR),
+	/*6496*/ uint16(xArgR64),
+	/*6497*/ uint16(xArgRM64),
+	/*6498*/ uint16(xMatch),
+	/*6499*/ uint16(xSetOp), uint16(UD1),
+	/*6501*/ uint16(xMatch),
+	/*6502*/ uint16(xCondSlashR),
+	0,    // 0
+	0,    // 1
+	0,    // 2
+	0,    // 3
+	6511, // 4
+	6540, // 5
+	6569, // 6
+	6598, // 7
+	/*6511*/ uint16(xCondIs64), 6514, 6530,
+	/*6514*/ uint16(xCondDataSize), 6518, 6524, 0,
+	/*6518*/ uint16(xSetOp), uint16(BT),
+	/*6520*/ uint16(xReadIb),
+	/*6521*/ uint16(xArgRM16),
+	/*6522*/ uint16(xArgImm8u),
+	/*6523*/ uint16(xMatch),
+	/*6524*/ uint16(xSetOp), uint16(BT),
+	/*6526*/ uint16(xReadIb),
+	/*6527*/ uint16(xArgRM32),
+	/*6528*/ uint16(xArgImm8u),
+	/*6529*/ uint16(xMatch),
+	/*6530*/ uint16(xCondDataSize), 6518, 6524, 6534,
+	/*6534*/ uint16(xSetOp), uint16(BT),
+	/*6536*/ uint16(xReadIb),
+	/*6537*/ uint16(xArgRM64),
+	/*6538*/ uint16(xArgImm8u),
+	/*6539*/ uint16(xMatch),
+	/*6540*/ uint16(xCondIs64), 6543, 6559,
+	/*6543*/ uint16(xCondDataSize), 6547, 6553, 0,
+	/*6547*/ uint16(xSetOp), uint16(BTS),
+	/*6549*/ uint16(xReadIb),
+	/*6550*/ uint16(xArgRM16),
+	/*6551*/ uint16(xArgImm8u),
+	/*6552*/ uint16(xMatch),
+	/*6553*/ uint16(xSetOp), uint16(BTS),
+	/*6555*/ uint16(xReadIb),
+	/*6556*/ uint16(xArgRM32),
+	/*6557*/ uint16(xArgImm8u),
+	/*6558*/ uint16(xMatch),
+	/*6559*/ uint16(xCondDataSize), 6547, 6553, 6563,
+	/*6563*/ uint16(xSetOp), uint16(BTS),
+	/*6565*/ uint16(xReadIb),
+	/*6566*/ uint16(xArgRM64),
+	/*6567*/ uint16(xArgImm8u),
+	/*6568*/ uint16(xMatch),
+	/*6569*/ uint16(xCondIs64), 6572, 6588,
+	/*6572*/ uint16(xCondDataSize), 6576, 6582, 0,
+	/*6576*/ uint16(xSetOp), uint16(BTR),
+	/*6578*/ uint16(xReadIb),
+	/*6579*/ uint16(xArgRM16),
+	/*6580*/ uint16(xArgImm8u),
+	/*6581*/ uint16(xMatch),
+	/*6582*/ uint16(xSetOp), uint16(BTR),
+	/*6584*/ uint16(xReadIb),
+	/*6585*/ uint16(xArgRM32),
+	/*6586*/ uint16(xArgImm8u),
+	/*6587*/ uint16(xMatch),
+	/*6588*/ uint16(xCondDataSize), 6576, 6582, 6592,
+	/*6592*/ uint16(xSetOp), uint16(BTR),
+	/*6594*/ uint16(xReadIb),
+	/*6595*/ uint16(xArgRM64),
+	/*6596*/ uint16(xArgImm8u),
+	/*6597*/ uint16(xMatch),
+	/*6598*/ uint16(xCondIs64), 6601, 6617,
+	/*6601*/ uint16(xCondDataSize), 6605, 6611, 0,
+	/*6605*/ uint16(xSetOp), uint16(BTC),
+	/*6607*/ uint16(xReadIb),
+	/*6608*/ uint16(xArgRM16),
+	/*6609*/ uint16(xArgImm8u),
+	/*6610*/ uint16(xMatch),
+	/*6611*/ uint16(xSetOp), uint16(BTC),
+	/*6613*/ uint16(xReadIb),
+	/*6614*/ uint16(xArgRM32),
+	/*6615*/ uint16(xArgImm8u),
+	/*6616*/ uint16(xMatch),
+	/*6617*/ uint16(xCondDataSize), 6605, 6611, 6621,
+	/*6621*/ uint16(xSetOp), uint16(BTC),
+	/*6623*/ uint16(xReadIb),
+	/*6624*/ uint16(xArgRM64),
+	/*6625*/ uint16(xArgImm8u),
+	/*6626*/ uint16(xMatch),
+	/*6627*/ uint16(xCondIs64), 6630, 6646,
+	/*6630*/ uint16(xCondDataSize), 6634, 6640, 0,
+	/*6634*/ uint16(xSetOp), uint16(BTC),
+	/*6636*/ uint16(xReadSlashR),
+	/*6637*/ uint16(xArgRM16),
+	/*6638*/ uint16(xArgR16),
+	/*6639*/ uint16(xMatch),
+	/*6640*/ uint16(xSetOp), uint16(BTC),
+	/*6642*/ uint16(xReadSlashR),
+	/*6643*/ uint16(xArgRM32),
+	/*6644*/ uint16(xArgR32),
+	/*6645*/ uint16(xMatch),
+	/*6646*/ uint16(xCondDataSize), 6634, 6640, 6650,
+	/*6650*/ uint16(xSetOp), uint16(BTC),
+	/*6652*/ uint16(xReadSlashR),
+	/*6653*/ uint16(xArgRM64),
+	/*6654*/ uint16(xArgR64),
+	/*6655*/ uint16(xMatch),
+	/*6656*/ uint16(xCondIs64), 6659, 6697,
+	/*6659*/ uint16(xCondPrefix), 2,
+	0xF3, 6681,
+	0x0, 6665,
+	/*6665*/ uint16(xCondDataSize), 6669, 6675, 0,
+	/*6669*/ uint16(xSetOp), uint16(BSF),
+	/*6671*/ uint16(xReadSlashR),
+	/*6672*/ uint16(xArgR16),
+	/*6673*/ uint16(xArgRM16),
+	/*6674*/ uint16(xMatch),
+	/*6675*/ uint16(xSetOp), uint16(BSF),
+	/*6677*/ uint16(xReadSlashR),
+	/*6678*/ uint16(xArgR32),
+	/*6679*/ uint16(xArgRM32),
+	/*6680*/ uint16(xMatch),
+	/*6681*/ uint16(xCondDataSize), 6685, 6691, 0,
+	/*6685*/ uint16(xSetOp), uint16(TZCNT),
+	/*6687*/ uint16(xReadSlashR),
+	/*6688*/ uint16(xArgR16),
+	/*6689*/ uint16(xArgRM16),
+	/*6690*/ uint16(xMatch),
+	/*6691*/ uint16(xSetOp), uint16(TZCNT),
+	/*6693*/ uint16(xReadSlashR),
+	/*6694*/ uint16(xArgR32),
+	/*6695*/ uint16(xArgRM32),
+	/*6696*/ uint16(xMatch),
+	/*6697*/ uint16(xCondPrefix), 2,
+	0xF3, 6713,
+	0x0, 6703,
+	/*6703*/ uint16(xCondDataSize), 6669, 6675, 6707,
+	/*6707*/ uint16(xSetOp), uint16(BSF),
+	/*6709*/ uint16(xReadSlashR),
+	/*6710*/ uint16(xArgR64),
+	/*6711*/ uint16(xArgRM64),
+	/*6712*/ uint16(xMatch),
+	/*6713*/ uint16(xCondDataSize), 6685, 6691, 6717,
+	/*6717*/ uint16(xSetOp), uint16(TZCNT),
+	/*6719*/ uint16(xReadSlashR),
+	/*6720*/ uint16(xArgR64),
+	/*6721*/ uint16(xArgRM64),
+	/*6722*/ uint16(xMatch),
+	/*6723*/ uint16(xCondIs64), 6726, 6764,
+	/*6726*/ uint16(xCondPrefix), 2,
+	0xF3, 6748,
+	0x0, 6732,
+	/*6732*/ uint16(xCondDataSize), 6736, 6742, 0,
+	/*6736*/ uint16(xSetOp), uint16(BSR),
+	/*6738*/ uint16(xReadSlashR),
+	/*6739*/ uint16(xArgR16),
+	/*6740*/ uint16(xArgRM16),
+	/*6741*/ uint16(xMatch),
+	/*6742*/ uint16(xSetOp), uint16(BSR),
+	/*6744*/ uint16(xReadSlashR),
+	/*6745*/ uint16(xArgR32),
+	/*6746*/ uint16(xArgRM32),
+	/*6747*/ uint16(xMatch),
+	/*6748*/ uint16(xCondDataSize), 6752, 6758, 0,
+	/*6752*/ uint16(xSetOp), uint16(LZCNT),
+	/*6754*/ uint16(xReadSlashR),
+	/*6755*/ uint16(xArgR16),
+	/*6756*/ uint16(xArgRM16),
+	/*6757*/ uint16(xMatch),
+	/*6758*/ uint16(xSetOp), uint16(LZCNT),
+	/*6760*/ uint16(xReadSlashR),
+	/*6761*/ uint16(xArgR32),
+	/*6762*/ uint16(xArgRM32),
+	/*6763*/ uint16(xMatch),
+	/*6764*/ uint16(xCondPrefix), 2,
+	0xF3, 6780,
+	0x0, 6770,
+	/*6770*/ uint16(xCondDataSize), 6736, 6742, 6774,
+	/*6774*/ uint16(xSetOp), uint16(BSR),
+	/*6776*/ uint16(xReadSlashR),
+	/*6777*/ uint16(xArgR64),
+	/*6778*/ uint16(xArgRM64),
+	/*6779*/ uint16(xMatch),
+	/*6780*/ uint16(xCondDataSize), 6752, 6758, 6784,
+	/*6784*/ uint16(xSetOp), uint16(LZCNT),
+	/*6786*/ uint16(xReadSlashR),
+	/*6787*/ uint16(xArgR64),
+	/*6788*/ uint16(xArgRM64),
+	/*6789*/ uint16(xMatch),
+	/*6790*/ uint16(xCondIs64), 6793, 6809,
+	/*6793*/ uint16(xCondDataSize), 6797, 6803, 0,
+	/*6797*/ uint16(xSetOp), uint16(MOVSX),
+	/*6799*/ uint16(xReadSlashR),
+	/*6800*/ uint16(xArgR16),
+	/*6801*/ uint16(xArgRM8),
+	/*6802*/ uint16(xMatch),
+	/*6803*/ uint16(xSetOp), uint16(MOVSX),
+	/*6805*/ uint16(xReadSlashR),
+	/*6806*/ uint16(xArgR32),
+	/*6807*/ uint16(xArgRM8),
+	/*6808*/ uint16(xMatch),
+	/*6809*/ uint16(xCondDataSize), 6797, 6803, 6813,
+	/*6813*/ uint16(xSetOp), uint16(MOVSX),
+	/*6815*/ uint16(xReadSlashR),
+	/*6816*/ uint16(xArgR64),
+	/*6817*/ uint16(xArgRM8),
+	/*6818*/ uint16(xMatch),
+	/*6819*/ uint16(xCondIs64), 6822, 6838,
+	/*6822*/ uint16(xCondDataSize), 6826, 6832, 0,
+	/*6826*/ uint16(xSetOp), uint16(MOVSX),
+	/*6828*/ uint16(xReadSlashR),
+	/*6829*/ uint16(xArgR16),
+	/*6830*/ uint16(xArgRM16),
+	/*6831*/ uint16(xMatch),
+	/*6832*/ uint16(xSetOp), uint16(MOVSX),
+	/*6834*/ uint16(xReadSlashR),
+	/*6835*/ uint16(xArgR32),
+	/*6836*/ uint16(xArgRM16),
+	/*6837*/ uint16(xMatch),
+	/*6838*/ uint16(xCondDataSize), 6826, 6832, 6842,
+	/*6842*/ uint16(xSetOp), uint16(MOVSX),
+	/*6844*/ uint16(xReadSlashR),
+	/*6845*/ uint16(xArgR64),
+	/*6846*/ uint16(xArgRM16),
+	/*6847*/ uint16(xMatch),
+	/*6848*/ uint16(xSetOp), uint16(XADD),
+	/*6850*/ uint16(xReadSlashR),
+	/*6851*/ uint16(xArgRM8),
+	/*6852*/ uint16(xArgR8),
+	/*6853*/ uint16(xMatch),
+	/*6854*/ uint16(xCondIs64), 6857, 6873,
+	/*6857*/ uint16(xCondDataSize), 6861, 6867, 0,
+	/*6861*/ uint16(xSetOp), uint16(XADD),
+	/*6863*/ uint16(xReadSlashR),
+	/*6864*/ uint16(xArgRM16),
+	/*6865*/ uint16(xArgR16),
+	/*6866*/ uint16(xMatch),
+	/*6867*/ uint16(xSetOp), uint16(XADD),
+	/*6869*/ uint16(xReadSlashR),
+	/*6870*/ uint16(xArgRM32),
+	/*6871*/ uint16(xArgR32),
+	/*6872*/ uint16(xMatch),
+	/*6873*/ uint16(xCondDataSize), 6861, 6867, 6877,
+	/*6877*/ uint16(xSetOp), uint16(XADD),
+	/*6879*/ uint16(xReadSlashR),
+	/*6880*/ uint16(xArgRM64),
+	/*6881*/ uint16(xArgR64),
+	/*6882*/ uint16(xMatch),
+	/*6883*/ uint16(xCondPrefix), 4,
+	0xF3, 6917,
+	0xF2, 6909,
+	0x66, 6901,
+	0x0, 6893,
+	/*6893*/ uint16(xSetOp), uint16(CMPPS),
+	/*6895*/ uint16(xReadSlashR),
+	/*6896*/ uint16(xReadIb),
+	/*6897*/ uint16(xArgXmm1),
+	/*6898*/ uint16(xArgXmm2M128),
+	/*6899*/ uint16(xArgImm8u),
+	/*6900*/ uint16(xMatch),
+	/*6901*/ uint16(xSetOp), uint16(CMPPD),
+	/*6903*/ uint16(xReadSlashR),
+	/*6904*/ uint16(xReadIb),
+	/*6905*/ uint16(xArgXmm1),
+	/*6906*/ uint16(xArgXmm2M128),
+	/*6907*/ uint16(xArgImm8u),
+	/*6908*/ uint16(xMatch),
+	/*6909*/ uint16(xSetOp), uint16(CMPSD_XMM),
+	/*6911*/ uint16(xReadSlashR),
+	/*6912*/ uint16(xReadIb),
+	/*6913*/ uint16(xArgXmm1),
+	/*6914*/ uint16(xArgXmm2M64),
+	/*6915*/ uint16(xArgImm8u),
+	/*6916*/ uint16(xMatch),
+	/*6917*/ uint16(xSetOp), uint16(CMPSS),
+	/*6919*/ uint16(xReadSlashR),
+	/*6920*/ uint16(xReadIb),
+	/*6921*/ uint16(xArgXmm1),
+	/*6922*/ uint16(xArgXmm2M32),
+	/*6923*/ uint16(xArgImm8u),
+	/*6924*/ uint16(xMatch),
+	/*6925*/ uint16(xCondIs64), 6928, 6944,
+	/*6928*/ uint16(xCondDataSize), 6932, 6938, 0,
+	/*6932*/ uint16(xSetOp), uint16(MOVNTI),
+	/*6934*/ uint16(xReadSlashR),
+	/*6935*/ uint16(xArgM32),
+	/*6936*/ uint16(xArgR32),
+	/*6937*/ uint16(xMatch),
+	/*6938*/ uint16(xSetOp), uint16(MOVNTI),
+	/*6940*/ uint16(xReadSlashR),
+	/*6941*/ uint16(xArgM32),
+	/*6942*/ uint16(xArgR32),
+	/*6943*/ uint16(xMatch),
+	/*6944*/ uint16(xCondDataSize), 6932, 6938, 6948,
+	/*6948*/ uint16(xSetOp), uint16(MOVNTI),
+	/*6950*/ uint16(xReadSlashR),
+	/*6951*/ uint16(xArgM64),
+	/*6952*/ uint16(xArgR64),
+	/*6953*/ uint16(xMatch),
+	/*6954*/ uint16(xCondPrefix), 2,
+	0x66, 6968,
+	0x0, 6960,
+	/*6960*/ uint16(xSetOp), uint16(PINSRW),
+	/*6962*/ uint16(xReadSlashR),
+	/*6963*/ uint16(xReadIb),
+	/*6964*/ uint16(xArgMm),
+	/*6965*/ uint16(xArgR32M16),
+	/*6966*/ uint16(xArgImm8u),
+	/*6967*/ uint16(xMatch),
+	/*6968*/ uint16(xSetOp), uint16(PINSRW),
+	/*6970*/ uint16(xReadSlashR),
+	/*6971*/ uint16(xReadIb),
+	/*6972*/ uint16(xArgXmm),
+	/*6973*/ uint16(xArgR32M16),
+	/*6974*/ uint16(xArgImm8u),
+	/*6975*/ uint16(xMatch),
+	/*6976*/ uint16(xCondPrefix), 2,
+	0x66, 6990,
+	0x0, 6982,
+	/*6982*/ uint16(xSetOp), uint16(PEXTRW),
+	/*6984*/ uint16(xReadSlashR),
+	/*6985*/ uint16(xReadIb),
+	/*6986*/ uint16(xArgR32),
+	/*6987*/ uint16(xArgMm2),
+	/*6988*/ uint16(xArgImm8u),
+	/*6989*/ uint16(xMatch),
+	/*6990*/ uint16(xSetOp), uint16(PEXTRW),
+	/*6992*/ uint16(xReadSlashR),
+	/*6993*/ uint16(xReadIb),
+	/*6994*/ uint16(xArgR32),
+	/*6995*/ uint16(xArgXmm2),
+	/*6996*/ uint16(xArgImm8u),
+	/*6997*/ uint16(xMatch),
+	/*6998*/ uint16(xCondPrefix), 2,
+	0x66, 7012,
+	0x0, 7004,
+	/*7004*/ uint16(xSetOp), uint16(SHUFPS),
+	/*7006*/ uint16(xReadSlashR),
+	/*7007*/ uint16(xReadIb),
+	/*7008*/ uint16(xArgXmm1),
+	/*7009*/ uint16(xArgXmm2M128),
+	/*7010*/ uint16(xArgImm8u),
+	/*7011*/ uint16(xMatch),
+	/*7012*/ uint16(xSetOp), uint16(SHUFPD),
+	/*7014*/ uint16(xReadSlashR),
+	/*7015*/ uint16(xReadIb),
+	/*7016*/ uint16(xArgXmm1),
+	/*7017*/ uint16(xArgXmm2M128),
+	/*7018*/ uint16(xArgImm8u),
+	/*7019*/ uint16(xMatch),
+	/*7020*/ uint16(xCondSlashR),
+	0,    // 0
+	7029, // 1
+	0,    // 2
+	7052, // 3
+	7075, // 4
+	7098, // 5
+	7121, // 6
+	0,    // 7
+	/*7029*/ uint16(xCondIs64), 7032, 7044,
+	/*7032*/ uint16(xCondDataSize), 7036, 7040, 0,
+	/*7036*/ uint16(xSetOp), uint16(CMPXCHG8B),
+	/*7038*/ uint16(xArgM64),
+	/*7039*/ uint16(xMatch),
+	/*7040*/ uint16(xSetOp), uint16(CMPXCHG8B),
+	/*7042*/ uint16(xArgM64),
+	/*7043*/ uint16(xMatch),
+	/*7044*/ uint16(xCondDataSize), 7036, 7040, 7048,
+	/*7048*/ uint16(xSetOp), uint16(CMPXCHG16B),
+	/*7050*/ uint16(xArgM128),
+	/*7051*/ uint16(xMatch),
+	/*7052*/ uint16(xCondIs64), 7055, 7067,
+	/*7055*/ uint16(xCondDataSize), 7059, 7063, 0,
+	/*7059*/ uint16(xSetOp), uint16(XRSTORS),
+	/*7061*/ uint16(xArgMem),
+	/*7062*/ uint16(xMatch),
+	/*7063*/ uint16(xSetOp), uint16(XRSTORS),
+	/*7065*/ uint16(xArgMem),
+	/*7066*/ uint16(xMatch),
+	/*7067*/ uint16(xCondDataSize), 7059, 7063, 7071,
+	/*7071*/ uint16(xSetOp), uint16(XRSTORS64),
+	/*7073*/ uint16(xArgMem),
+	/*7074*/ uint16(xMatch),
+	/*7075*/ uint16(xCondIs64), 7078, 7090,
+	/*7078*/ uint16(xCondDataSize), 7082, 7086, 0,
+	/*7082*/ uint16(xSetOp), uint16(XSAVEC),
+	/*7084*/ uint16(xArgMem),
+	/*7085*/ uint16(xMatch),
+	/*7086*/ uint16(xSetOp), uint16(XSAVEC),
+	/*7088*/ uint16(xArgMem),
+	/*7089*/ uint16(xMatch),
+	/*7090*/ uint16(xCondDataSize), 7082, 7086, 7094,
+	/*7094*/ uint16(xSetOp), uint16(XSAVEC64),
+	/*7096*/ uint16(xArgMem),
+	/*7097*/ uint16(xMatch),
+	/*7098*/ uint16(xCondIs64), 7101, 7113,
+	/*7101*/ uint16(xCondDataSize), 7105, 7109, 0,
+	/*7105*/ uint16(xSetOp), uint16(XSAVES),
+	/*7107*/ uint16(xArgMem),
+	/*7108*/ uint16(xMatch),
+	/*7109*/ uint16(xSetOp), uint16(XSAVES),
+	/*7111*/ uint16(xArgMem),
+	/*7112*/ uint16(xMatch),
+	/*7113*/ uint16(xCondDataSize), 7105, 7109, 7117,
+	/*7117*/ uint16(xSetOp), uint16(XSAVES64),
+	/*7119*/ uint16(xArgMem),
+	/*7120*/ uint16(xMatch),
+	/*7121*/ uint16(xCondIs64), 7124, 7142,
+	/*7124*/ uint16(xCondDataSize), 7128, 7135, 0,
+	/*7128*/ uint16(xCondIsMem), 7131, 0,
+	/*7131*/ uint16(xSetOp), uint16(RDRAND),
+	/*7133*/ uint16(xArgRmf16),
+	/*7134*/ uint16(xMatch),
+	/*7135*/ uint16(xCondIsMem), 7138, 0,
+	/*7138*/ uint16(xSetOp), uint16(RDRAND),
+	/*7140*/ uint16(xArgRmf32),
+	/*7141*/ uint16(xMatch),
+	/*7142*/ uint16(xCondDataSize), 7128, 7135, 7146,
+	/*7146*/ uint16(xSetOp), uint16(RDRAND),
+	/*7148*/ uint16(xMatch),
+	/*7149*/ uint16(xCondIs64), 7152, 7164,
+	/*7152*/ uint16(xCondDataSize), 7156, 7160, 0,
+	/*7156*/ uint16(xSetOp), uint16(BSWAP),
+	/*7158*/ uint16(xArgR16op),
+	/*7159*/ uint16(xMatch),
+	/*7160*/ uint16(xSetOp), uint16(BSWAP),
+	/*7162*/ uint16(xArgR32op),
+	/*7163*/ uint16(xMatch),
+	/*7164*/ uint16(xCondDataSize), 7156, 7160, 7168,
+	/*7168*/ uint16(xSetOp), uint16(BSWAP),
+	/*7170*/ uint16(xArgR64op),
+	/*7171*/ uint16(xMatch),
+	/*7172*/ uint16(xCondPrefix), 2,
+	0xF2, 7184,
+	0x66, 7178,
+	/*7178*/ uint16(xSetOp), uint16(ADDSUBPD),
+	/*7180*/ uint16(xReadSlashR),
+	/*7181*/ uint16(xArgXmm1),
+	/*7182*/ uint16(xArgXmm2M128),
+	/*7183*/ uint16(xMatch),
+	/*7184*/ uint16(xSetOp), uint16(ADDSUBPS),
+	/*7186*/ uint16(xReadSlashR),
+	/*7187*/ uint16(xArgXmm1),
+	/*7188*/ uint16(xArgXmm2M128),
+	/*7189*/ uint16(xMatch),
+	/*7190*/ uint16(xCondPrefix), 2,
+	0x66, 7202,
+	0x0, 7196,
+	/*7196*/ uint16(xSetOp), uint16(PSRLW),
+	/*7198*/ uint16(xReadSlashR),
+	/*7199*/ uint16(xArgMm),
+	/*7200*/ uint16(xArgMmM64),
+	/*7201*/ uint16(xMatch),
+	/*7202*/ uint16(xSetOp), uint16(PSRLW),
+	/*7204*/ uint16(xReadSlashR),
+	/*7205*/ uint16(xArgXmm1),
+	/*7206*/ uint16(xArgXmm2M128),
+	/*7207*/ uint16(xMatch),
+	/*7208*/ uint16(xCondPrefix), 2,
+	0x66, 7220,
+	0x0, 7214,
+	/*7214*/ uint16(xSetOp), uint16(PSRLD),
+	/*7216*/ uint16(xReadSlashR),
+	/*7217*/ uint16(xArgMm),
+	/*7218*/ uint16(xArgMmM64),
+	/*7219*/ uint16(xMatch),
+	/*7220*/ uint16(xSetOp), uint16(PSRLD),
+	/*7222*/ uint16(xReadSlashR),
+	/*7223*/ uint16(xArgXmm1),
+	/*7224*/ uint16(xArgXmm2M128),
+	/*7225*/ uint16(xMatch),
+	/*7226*/ uint16(xCondPrefix), 2,
+	0x66, 7238,
+	0x0, 7232,
+	/*7232*/ uint16(xSetOp), uint16(PSRLQ),
+	/*7234*/ uint16(xReadSlashR),
+	/*7235*/ uint16(xArgMm),
+	/*7236*/ uint16(xArgMmM64),
+	/*7237*/ uint16(xMatch),
+	/*7238*/ uint16(xSetOp), uint16(PSRLQ),
+	/*7240*/ uint16(xReadSlashR),
+	/*7241*/ uint16(xArgXmm1),
+	/*7242*/ uint16(xArgXmm2M128),
+	/*7243*/ uint16(xMatch),
+	/*7244*/ uint16(xCondPrefix), 2,
+	0x66, 7256,
+	0x0, 7250,
+	/*7250*/ uint16(xSetOp), uint16(PADDQ),
+	/*7252*/ uint16(xReadSlashR),
+	/*7253*/ uint16(xArgMm1),
+	/*7254*/ uint16(xArgMm2M64),
+	/*7255*/ uint16(xMatch),
+	/*7256*/ uint16(xSetOp), uint16(PADDQ),
+	/*7258*/ uint16(xReadSlashR),
+	/*7259*/ uint16(xArgXmm1),
+	/*7260*/ uint16(xArgXmm2M128),
+	/*7261*/ uint16(xMatch),
+	/*7262*/ uint16(xCondPrefix), 2,
+	0x66, 7274,
+	0x0, 7268,
+	/*7268*/ uint16(xSetOp), uint16(PMULLW),
+	/*7270*/ uint16(xReadSlashR),
+	/*7271*/ uint16(xArgMm),
+	/*7272*/ uint16(xArgMmM64),
+	/*7273*/ uint16(xMatch),
+	/*7274*/ uint16(xSetOp), uint16(PMULLW),
+	/*7276*/ uint16(xReadSlashR),
+	/*7277*/ uint16(xArgXmm1),
+	/*7278*/ uint16(xArgXmm2M128),
+	/*7279*/ uint16(xMatch),
+	/*7280*/ uint16(xCondPrefix), 3,
+	0xF3, 7300,
+	0xF2, 7294,
+	0x66, 7288,
+	/*7288*/ uint16(xSetOp), uint16(MOVQ),
+	/*7290*/ uint16(xReadSlashR),
+	/*7291*/ uint16(xArgXmm2M64),
+	/*7292*/ uint16(xArgXmm1),
+	/*7293*/ uint16(xMatch),
+	/*7294*/ uint16(xSetOp), uint16(MOVDQ2Q),
+	/*7296*/ uint16(xReadSlashR),
+	/*7297*/ uint16(xArgMm),
+	/*7298*/ uint16(xArgXmm2),
+	/*7299*/ uint16(xMatch),
+	/*7300*/ uint16(xSetOp), uint16(MOVQ2DQ),
+	/*7302*/ uint16(xReadSlashR),
+	/*7303*/ uint16(xArgXmm1),
+	/*7304*/ uint16(xArgMm2),
+	/*7305*/ uint16(xMatch),
+	/*7306*/ uint16(xCondPrefix), 2,
+	0x66, 7318,
+	0x0, 7312,
+	/*7312*/ uint16(xSetOp), uint16(PMOVMSKB),
+	/*7314*/ uint16(xReadSlashR),
+	/*7315*/ uint16(xArgR32),
+	/*7316*/ uint16(xArgMm2),
+	/*7317*/ uint16(xMatch),
+	/*7318*/ uint16(xSetOp), uint16(PMOVMSKB),
+	/*7320*/ uint16(xReadSlashR),
+	/*7321*/ uint16(xArgR32),
+	/*7322*/ uint16(xArgXmm2),
+	/*7323*/ uint16(xMatch),
+	/*7324*/ uint16(xCondPrefix), 2,
+	0x66, 7336,
+	0x0, 7330,
+	/*7330*/ uint16(xSetOp), uint16(PSUBUSB),
+	/*7332*/ uint16(xReadSlashR),
+	/*7333*/ uint16(xArgMm),
+	/*7334*/ uint16(xArgMmM64),
+	/*7335*/ uint16(xMatch),
+	/*7336*/ uint16(xSetOp), uint16(PSUBUSB),
+	/*7338*/ uint16(xReadSlashR),
+	/*7339*/ uint16(xArgXmm1),
+	/*7340*/ uint16(xArgXmm2M128),
+	/*7341*/ uint16(xMatch),
+	/*7342*/ uint16(xCondPrefix), 2,
+	0x66, 7354,
+	0x0, 7348,
+	/*7348*/ uint16(xSetOp), uint16(PSUBUSW),
+	/*7350*/ uint16(xReadSlashR),
+	/*7351*/ uint16(xArgMm),
+	/*7352*/ uint16(xArgMmM64),
+	/*7353*/ uint16(xMatch),
+	/*7354*/ uint16(xSetOp), uint16(PSUBUSW),
+	/*7356*/ uint16(xReadSlashR),
+	/*7357*/ uint16(xArgXmm1),
+	/*7358*/ uint16(xArgXmm2M128),
+	/*7359*/ uint16(xMatch),
+	/*7360*/ uint16(xCondPrefix), 2,
+	0x66, 7372,
+	0x0, 7366,
+	/*7366*/ uint16(xSetOp), uint16(PMINUB),
+	/*7368*/ uint16(xReadSlashR),
+	/*7369*/ uint16(xArgMm1),
+	/*7370*/ uint16(xArgMm2M64),
+	/*7371*/ uint16(xMatch),
+	/*7372*/ uint16(xSetOp), uint16(PMINUB),
+	/*7374*/ uint16(xReadSlashR),
+	/*7375*/ uint16(xArgXmm1),
+	/*7376*/ uint16(xArgXmm2M128),
+	/*7377*/ uint16(xMatch),
+	/*7378*/ uint16(xCondPrefix), 2,
+	0x66, 7390,
+	0x0, 7384,
+	/*7384*/ uint16(xSetOp), uint16(PAND),
+	/*7386*/ uint16(xReadSlashR),
+	/*7387*/ uint16(xArgMm),
+	/*7388*/ uint16(xArgMmM64),
+	/*7389*/ uint16(xMatch),
+	/*7390*/ uint16(xSetOp), uint16(PAND),
+	/*7392*/ uint16(xReadSlashR),
+	/*7393*/ uint16(xArgXmm1),
+	/*7394*/ uint16(xArgXmm2M128),
+	/*7395*/ uint16(xMatch),
+	/*7396*/ uint16(xCondPrefix), 2,
+	0x66, 7408,
+	0x0, 7402,
+	/*7402*/ uint16(xSetOp), uint16(PADDUSB),
+	/*7404*/ uint16(xReadSlashR),
+	/*7405*/ uint16(xArgMm),
+	/*7406*/ uint16(xArgMmM64),
+	/*7407*/ uint16(xMatch),
+	/*7408*/ uint16(xSetOp), uint16(PADDUSB),
+	/*7410*/ uint16(xReadSlashR),
+	/*7411*/ uint16(xArgXmm1),
+	/*7412*/ uint16(xArgXmm2M128),
+	/*7413*/ uint16(xMatch),
+	/*7414*/ uint16(xCondPrefix), 2,
+	0x66, 7426,
+	0x0, 7420,
+	/*7420*/ uint16(xSetOp), uint16(PADDUSW),
+	/*7422*/ uint16(xReadSlashR),
+	/*7423*/ uint16(xArgMm),
+	/*7424*/ uint16(xArgMmM64),
+	/*7425*/ uint16(xMatch),
+	/*7426*/ uint16(xSetOp), uint16(PADDUSW),
+	/*7428*/ uint16(xReadSlashR),
+	/*7429*/ uint16(xArgXmm1),
+	/*7430*/ uint16(xArgXmm2M128),
+	/*7431*/ uint16(xMatch),
+	/*7432*/ uint16(xCondPrefix), 2,
+	0x66, 7444,
+	0x0, 7438,
+	/*7438*/ uint16(xSetOp), uint16(PMAXUB),
+	/*7440*/ uint16(xReadSlashR),
+	/*7441*/ uint16(xArgMm1),
+	/*7442*/ uint16(xArgMm2M64),
+	/*7443*/ uint16(xMatch),
+	/*7444*/ uint16(xSetOp), uint16(PMAXUB),
+	/*7446*/ uint16(xReadSlashR),
+	/*7447*/ uint16(xArgXmm1),
+	/*7448*/ uint16(xArgXmm2M128),
+	/*7449*/ uint16(xMatch),
+	/*7450*/ uint16(xCondPrefix), 2,
+	0x66, 7462,
+	0x0, 7456,
+	/*7456*/ uint16(xSetOp), uint16(PANDN),
+	/*7458*/ uint16(xReadSlashR),
+	/*7459*/ uint16(xArgMm),
+	/*7460*/ uint16(xArgMmM64),
+	/*7461*/ uint16(xMatch),
+	/*7462*/ uint16(xSetOp), uint16(PANDN),
+	/*7464*/ uint16(xReadSlashR),
+	/*7465*/ uint16(xArgXmm1),
+	/*7466*/ uint16(xArgXmm2M128),
+	/*7467*/ uint16(xMatch),
+	/*7468*/ uint16(xCondPrefix), 2,
+	0x66, 7480,
+	0x0, 7474,
+	/*7474*/ uint16(xSetOp), uint16(PAVGB),
+	/*7476*/ uint16(xReadSlashR),
+	/*7477*/ uint16(xArgMm1),
+	/*7478*/ uint16(xArgMm2M64),
+	/*7479*/ uint16(xMatch),
+	/*7480*/ uint16(xSetOp), uint16(PAVGB),
+	/*7482*/ uint16(xReadSlashR),
+	/*7483*/ uint16(xArgXmm1),
+	/*7484*/ uint16(xArgXmm2M128),
+	/*7485*/ uint16(xMatch),
+	/*7486*/ uint16(xCondPrefix), 2,
+	0x66, 7498,
+	0x0, 7492,
+	/*7492*/ uint16(xSetOp), uint16(PSRAW),
+	/*7494*/ uint16(xReadSlashR),
+	/*7495*/ uint16(xArgMm),
+	/*7496*/ uint16(xArgMmM64),
+	/*7497*/ uint16(xMatch),
+	/*7498*/ uint16(xSetOp), uint16(PSRAW),
+	/*7500*/ uint16(xReadSlashR),
+	/*7501*/ uint16(xArgXmm1),
+	/*7502*/ uint16(xArgXmm2M128),
+	/*7503*/ uint16(xMatch),
+	/*7504*/ uint16(xCondPrefix), 2,
+	0x66, 7516,
+	0x0, 7510,
+	/*7510*/ uint16(xSetOp), uint16(PSRAD),
+	/*7512*/ uint16(xReadSlashR),
+	/*7513*/ uint16(xArgMm),
+	/*7514*/ uint16(xArgMmM64),
+	/*7515*/ uint16(xMatch),
+	/*7516*/ uint16(xSetOp), uint16(PSRAD),
+	/*7518*/ uint16(xReadSlashR),
+	/*7519*/ uint16(xArgXmm1),
+	/*7520*/ uint16(xArgXmm2M128),
+	/*7521*/ uint16(xMatch),
+	/*7522*/ uint16(xCondPrefix), 2,
+	0x66, 7534,
+	0x0, 7528,
+	/*7528*/ uint16(xSetOp), uint16(PAVGW),
+	/*7530*/ uint16(xReadSlashR),
+	/*7531*/ uint16(xArgMm1),
+	/*7532*/ uint16(xArgMm2M64),
+	/*7533*/ uint16(xMatch),
+	/*7534*/ uint16(xSetOp), uint16(PAVGW),
+	/*7536*/ uint16(xReadSlashR),
+	/*7537*/ uint16(xArgXmm1),
+	/*7538*/ uint16(xArgXmm2M128),
+	/*7539*/ uint16(xMatch),
+	/*7540*/ uint16(xCondPrefix), 2,
+	0x66, 7552,
+	0x0, 7546,
+	/*7546*/ uint16(xSetOp), uint16(PMULHUW),
+	/*7548*/ uint16(xReadSlashR),
+	/*7549*/ uint16(xArgMm1),
+	/*7550*/ uint16(xArgMm2M64),
+	/*7551*/ uint16(xMatch),
+	/*7552*/ uint16(xSetOp), uint16(PMULHUW),
+	/*7554*/ uint16(xReadSlashR),
+	/*7555*/ uint16(xArgXmm1),
+	/*7556*/ uint16(xArgXmm2M128),
+	/*7557*/ uint16(xMatch),
+	/*7558*/ uint16(xCondPrefix), 2,
+	0x66, 7570,
+	0x0, 7564,
+	/*7564*/ uint16(xSetOp), uint16(PMULHW),
+	/*7566*/ uint16(xReadSlashR),
+	/*7567*/ uint16(xArgMm),
+	/*7568*/ uint16(xArgMmM64),
+	/*7569*/ uint16(xMatch),
+	/*7570*/ uint16(xSetOp), uint16(PMULHW),
+	/*7572*/ uint16(xReadSlashR),
+	/*7573*/ uint16(xArgXmm1),
+	/*7574*/ uint16(xArgXmm2M128),
+	/*7575*/ uint16(xMatch),
+	/*7576*/ uint16(xCondPrefix), 3,
+	0xF3, 7596,
+	0xF2, 7590,
+	0x66, 7584,
+	/*7584*/ uint16(xSetOp), uint16(CVTTPD2DQ),
+	/*7586*/ uint16(xReadSlashR),
+	/*7587*/ uint16(xArgXmm1),
+	/*7588*/ uint16(xArgXmm2M128),
+	/*7589*/ uint16(xMatch),
+	/*7590*/ uint16(xSetOp), uint16(CVTPD2DQ),
+	/*7592*/ uint16(xReadSlashR),
+	/*7593*/ uint16(xArgXmm1),
+	/*7594*/ uint16(xArgXmm2M128),
+	/*7595*/ uint16(xMatch),
+	/*7596*/ uint16(xSetOp), uint16(CVTDQ2PD),
+	/*7598*/ uint16(xReadSlashR),
+	/*7599*/ uint16(xArgXmm1),
+	/*7600*/ uint16(xArgXmm2M64),
+	/*7601*/ uint16(xMatch),
+	/*7602*/ uint16(xCondPrefix), 2,
+	0x66, 7614,
+	0x0, 7608,
+	/*7608*/ uint16(xSetOp), uint16(MOVNTQ),
+	/*7610*/ uint16(xReadSlashR),
+	/*7611*/ uint16(xArgM64),
+	/*7612*/ uint16(xArgMm),
+	/*7613*/ uint16(xMatch),
+	/*7614*/ uint16(xSetOp), uint16(MOVNTDQ),
+	/*7616*/ uint16(xReadSlashR),
+	/*7617*/ uint16(xArgM128),
+	/*7618*/ uint16(xArgXmm),
+	/*7619*/ uint16(xMatch),
+	/*7620*/ uint16(xCondPrefix), 2,
+	0x66, 7632,
+	0x0, 7626,
+	/*7626*/ uint16(xSetOp), uint16(PSUBSB),
+	/*7628*/ uint16(xReadSlashR),
+	/*7629*/ uint16(xArgMm),
+	/*7630*/ uint16(xArgMmM64),
+	/*7631*/ uint16(xMatch),
+	/*7632*/ uint16(xSetOp), uint16(PSUBSB),
+	/*7634*/ uint16(xReadSlashR),
+	/*7635*/ uint16(xArgXmm1),
+	/*7636*/ uint16(xArgXmm2M128),
+	/*7637*/ uint16(xMatch),
+	/*7638*/ uint16(xCondPrefix), 2,
+	0x66, 7650,
+	0x0, 7644,
+	/*7644*/ uint16(xSetOp), uint16(PSUBSW),
+	/*7646*/ uint16(xReadSlashR),
+	/*7647*/ uint16(xArgMm),
+	/*7648*/ uint16(xArgMmM64),
+	/*7649*/ uint16(xMatch),
+	/*7650*/ uint16(xSetOp), uint16(PSUBSW),
+	/*7652*/ uint16(xReadSlashR),
+	/*7653*/ uint16(xArgXmm1),
+	/*7654*/ uint16(xArgXmm2M128),
+	/*7655*/ uint16(xMatch),
+	/*7656*/ uint16(xCondPrefix), 2,
+	0x66, 7668,
+	0x0, 7662,
+	/*7662*/ uint16(xSetOp), uint16(PMINSW),
+	/*7664*/ uint16(xReadSlashR),
+	/*7665*/ uint16(xArgMm1),
+	/*7666*/ uint16(xArgMm2M64),
+	/*7667*/ uint16(xMatch),
+	/*7668*/ uint16(xSetOp), uint16(PMINSW),
+	/*7670*/ uint16(xReadSlashR),
+	/*7671*/ uint16(xArgXmm1),
+	/*7672*/ uint16(xArgXmm2M128),
+	/*7673*/ uint16(xMatch),
+	/*7674*/ uint16(xCondPrefix), 2,
+	0x66, 7686,
+	0x0, 7680,
+	/*7680*/ uint16(xSetOp), uint16(POR),
+	/*7682*/ uint16(xReadSlashR),
+	/*7683*/ uint16(xArgMm),
+	/*7684*/ uint16(xArgMmM64),
+	/*7685*/ uint16(xMatch),
+	/*7686*/ uint16(xSetOp), uint16(POR),
+	/*7688*/ uint16(xReadSlashR),
+	/*7689*/ uint16(xArgXmm1),
+	/*7690*/ uint16(xArgXmm2M128),
+	/*7691*/ uint16(xMatch),
+	/*7692*/ uint16(xCondPrefix), 2,
+	0x66, 7704,
+	0x0, 7698,
+	/*7698*/ uint16(xSetOp), uint16(PADDSB),
+	/*7700*/ uint16(xReadSlashR),
+	/*7701*/ uint16(xArgMm),
+	/*7702*/ uint16(xArgMmM64),
+	/*7703*/ uint16(xMatch),
+	/*7704*/ uint16(xSetOp), uint16(PADDSB),
+	/*7706*/ uint16(xReadSlashR),
+	/*7707*/ uint16(xArgXmm1),
+	/*7708*/ uint16(xArgXmm2M128),
+	/*7709*/ uint16(xMatch),
+	/*7710*/ uint16(xCondPrefix), 2,
+	0x66, 7722,
+	0x0, 7716,
+	/*7716*/ uint16(xSetOp), uint16(PADDSW),
+	/*7718*/ uint16(xReadSlashR),
+	/*7719*/ uint16(xArgMm),
+	/*7720*/ uint16(xArgMmM64),
+	/*7721*/ uint16(xMatch),
+	/*7722*/ uint16(xSetOp), uint16(PADDSW),
+	/*7724*/ uint16(xReadSlashR),
+	/*7725*/ uint16(xArgXmm1),
+	/*7726*/ uint16(xArgXmm2M128),
+	/*7727*/ uint16(xMatch),
+	/*7728*/ uint16(xCondPrefix), 2,
+	0x66, 7740,
+	0x0, 7734,
+	/*7734*/ uint16(xSetOp), uint16(PMAXSW),
+	/*7736*/ uint16(xReadSlashR),
+	/*7737*/ uint16(xArgMm1),
+	/*7738*/ uint16(xArgMm2M64),
+	/*7739*/ uint16(xMatch),
+	/*7740*/ uint16(xSetOp), uint16(PMAXSW),
+	/*7742*/ uint16(xReadSlashR),
+	/*7743*/ uint16(xArgXmm1),
+	/*7744*/ uint16(xArgXmm2M128),
+	/*7745*/ uint16(xMatch),
+	/*7746*/ uint16(xCondPrefix), 2,
+	0x66, 7758,
+	0x0, 7752,
+	/*7752*/ uint16(xSetOp), uint16(PXOR),
+	/*7754*/ uint16(xReadSlashR),
+	/*7755*/ uint16(xArgMm),
+	/*7756*/ uint16(xArgMmM64),
+	/*7757*/ uint16(xMatch),
+	/*7758*/ uint16(xSetOp), uint16(PXOR),
+	/*7760*/ uint16(xReadSlashR),
+	/*7761*/ uint16(xArgXmm1),
+	/*7762*/ uint16(xArgXmm2M128),
+	/*7763*/ uint16(xMatch),
+	/*7764*/ uint16(xCondPrefix), 1,
+	0xF2, 7768,
+	/*7768*/ uint16(xSetOp), uint16(LDDQU),
+	/*7770*/ uint16(xReadSlashR),
+	/*7771*/ uint16(xArgXmm1),
+	/*7772*/ uint16(xArgM128),
+	/*7773*/ uint16(xMatch),
+	/*7774*/ uint16(xCondPrefix), 2,
+	0x66, 7786,
+	0x0, 7780,
+	/*7780*/ uint16(xSetOp), uint16(PSLLW),
+	/*7782*/ uint16(xReadSlashR),
+	/*7783*/ uint16(xArgMm),
+	/*7784*/ uint16(xArgMmM64),
+	/*7785*/ uint16(xMatch),
+	/*7786*/ uint16(xSetOp), uint16(PSLLW),
+	/*7788*/ uint16(xReadSlashR),
+	/*7789*/ uint16(xArgXmm1),
+	/*7790*/ uint16(xArgXmm2M128),
+	/*7791*/ uint16(xMatch),
+	/*7792*/ uint16(xCondPrefix), 2,
+	0x66, 7804,
+	0x0, 7798,
+	/*7798*/ uint16(xSetOp), uint16(PSLLD),
+	/*7800*/ uint16(xReadSlashR),
+	/*7801*/ uint16(xArgMm),
+	/*7802*/ uint16(xArgMmM64),
+	/*7803*/ uint16(xMatch),
+	/*7804*/ uint16(xSetOp), uint16(PSLLD),
+	/*7806*/ uint16(xReadSlashR),
+	/*7807*/ uint16(xArgXmm1),
+	/*7808*/ uint16(xArgXmm2M128),
+	/*7809*/ uint16(xMatch),
+	/*7810*/ uint16(xCondPrefix), 2,
+	0x66, 7822,
+	0x0, 7816,
+	/*7816*/ uint16(xSetOp), uint16(PSLLQ),
+	/*7818*/ uint16(xReadSlashR),
+	/*7819*/ uint16(xArgMm),
+	/*7820*/ uint16(xArgMmM64),
+	/*7821*/ uint16(xMatch),
+	/*7822*/ uint16(xSetOp), uint16(PSLLQ),
+	/*7824*/ uint16(xReadSlashR),
+	/*7825*/ uint16(xArgXmm1),
+	/*7826*/ uint16(xArgXmm2M128),
+	/*7827*/ uint16(xMatch),
+	/*7828*/ uint16(xCondPrefix), 2,
+	0x66, 7840,
+	0x0, 7834,
+	/*7834*/ uint16(xSetOp), uint16(PMULUDQ),
+	/*7836*/ uint16(xReadSlashR),
+	/*7837*/ uint16(xArgMm1),
+	/*7838*/ uint16(xArgMm2M64),
+	/*7839*/ uint16(xMatch),
+	/*7840*/ uint16(xSetOp), uint16(PMULUDQ),
+	/*7842*/ uint16(xReadSlashR),
+	/*7843*/ uint16(xArgXmm1),
+	/*7844*/ uint16(xArgXmm2M128),
+	/*7845*/ uint16(xMatch),
+	/*7846*/ uint16(xCondPrefix), 2,
+	0x66, 7858,
+	0x0, 7852,
+	/*7852*/ uint16(xSetOp), uint16(PMADDWD),
+	/*7854*/ uint16(xReadSlashR),
+	/*7855*/ uint16(xArgMm),
+	/*7856*/ uint16(xArgMmM64),
+	/*7857*/ uint16(xMatch),
+	/*7858*/ uint16(xSetOp), uint16(PMADDWD),
+	/*7860*/ uint16(xReadSlashR),
+	/*7861*/ uint16(xArgXmm1),
+	/*7862*/ uint16(xArgXmm2M128),
+	/*7863*/ uint16(xMatch),
+	/*7864*/ uint16(xCondPrefix), 2,
+	0x66, 7876,
+	0x0, 7870,
+	/*7870*/ uint16(xSetOp), uint16(PSADBW),
+	/*7872*/ uint16(xReadSlashR),
+	/*7873*/ uint16(xArgMm1),
+	/*7874*/ uint16(xArgMm2M64),
+	/*7875*/ uint16(xMatch),
+	/*7876*/ uint16(xSetOp), uint16(PSADBW),
+	/*7878*/ uint16(xReadSlashR),
+	/*7879*/ uint16(xArgXmm1),
+	/*7880*/ uint16(xArgXmm2M128),
+	/*7881*/ uint16(xMatch),
+	/*7882*/ uint16(xCondPrefix), 2,
+	0x66, 7894,
+	0x0, 7888,
+	/*7888*/ uint16(xSetOp), uint16(MASKMOVQ),
+	/*7890*/ uint16(xReadSlashR),
+	/*7891*/ uint16(xArgMm1),
+	/*7892*/ uint16(xArgMm2),
+	/*7893*/ uint16(xMatch),
+	/*7894*/ uint16(xSetOp), uint16(MASKMOVDQU),
+	/*7896*/ uint16(xReadSlashR),
+	/*7897*/ uint16(xArgXmm1),
+	/*7898*/ uint16(xArgXmm2),
+	/*7899*/ uint16(xMatch),
+	/*7900*/ uint16(xCondPrefix), 2,
+	0x66, 7912,
+	0x0, 7906,
+	/*7906*/ uint16(xSetOp), uint16(PSUBB),
+	/*7908*/ uint16(xReadSlashR),
+	/*7909*/ uint16(xArgMm),
+	/*7910*/ uint16(xArgMmM64),
+	/*7911*/ uint16(xMatch),
+	/*7912*/ uint16(xSetOp), uint16(PSUBB),
+	/*7914*/ uint16(xReadSlashR),
+	/*7915*/ uint16(xArgXmm1),
+	/*7916*/ uint16(xArgXmm2M128),
+	/*7917*/ uint16(xMatch),
+	/*7918*/ uint16(xCondPrefix), 2,
+	0x66, 7930,
+	0x0, 7924,
+	/*7924*/ uint16(xSetOp), uint16(PSUBW),
+	/*7926*/ uint16(xReadSlashR),
+	/*7927*/ uint16(xArgMm),
+	/*7928*/ uint16(xArgMmM64),
+	/*7929*/ uint16(xMatch),
+	/*7930*/ uint16(xSetOp), uint16(PSUBW),
+	/*7932*/ uint16(xReadSlashR),
+	/*7933*/ uint16(xArgXmm1),
+	/*7934*/ uint16(xArgXmm2M128),
+	/*7935*/ uint16(xMatch),
+	/*7936*/ uint16(xCondPrefix), 2,
+	0x66, 7948,
+	0x0, 7942,
+	/*7942*/ uint16(xSetOp), uint16(PSUBD),
+	/*7944*/ uint16(xReadSlashR),
+	/*7945*/ uint16(xArgMm),
+	/*7946*/ uint16(xArgMmM64),
+	/*7947*/ uint16(xMatch),
+	/*7948*/ uint16(xSetOp), uint16(PSUBD),
+	/*7950*/ uint16(xReadSlashR),
+	/*7951*/ uint16(xArgXmm1),
+	/*7952*/ uint16(xArgXmm2M128),
+	/*7953*/ uint16(xMatch),
+	/*7954*/ uint16(xCondPrefix), 2,
+	0x66, 7966,
+	0x0, 7960,
+	/*7960*/ uint16(xSetOp), uint16(PSUBQ),
+	/*7962*/ uint16(xReadSlashR),
+	/*7963*/ uint16(xArgMm1),
+	/*7964*/ uint16(xArgMm2M64),
+	/*7965*/ uint16(xMatch),
+	/*7966*/ uint16(xSetOp), uint16(PSUBQ),
+	/*7968*/ uint16(xReadSlashR),
+	/*7969*/ uint16(xArgXmm1),
+	/*7970*/ uint16(xArgXmm2M128),
+	/*7971*/ uint16(xMatch),
+	/*7972*/ uint16(xCondPrefix), 2,
+	0x66, 7984,
+	0x0, 7978,
+	/*7978*/ uint16(xSetOp), uint16(PADDB),
+	/*7980*/ uint16(xReadSlashR),
+	/*7981*/ uint16(xArgMm),
+	/*7982*/ uint16(xArgMmM64),
+	/*7983*/ uint16(xMatch),
+	/*7984*/ uint16(xSetOp), uint16(PADDB),
+	/*7986*/ uint16(xReadSlashR),
+	/*7987*/ uint16(xArgXmm1),
+	/*7988*/ uint16(xArgXmm2M128),
+	/*7989*/ uint16(xMatch),
+	/*7990*/ uint16(xCondPrefix), 2,
+	0x66, 8002,
+	0x0, 7996,
+	/*7996*/ uint16(xSetOp), uint16(PADDW),
+	/*7998*/ uint16(xReadSlashR),
+	/*7999*/ uint16(xArgMm),
+	/*8000*/ uint16(xArgMmM64),
+	/*8001*/ uint16(xMatch),
+	/*8002*/ uint16(xSetOp), uint16(PADDW),
+	/*8004*/ uint16(xReadSlashR),
+	/*8005*/ uint16(xArgXmm1),
+	/*8006*/ uint16(xArgXmm2M128),
+	/*8007*/ uint16(xMatch),
+	/*8008*/ uint16(xCondPrefix), 2,
+	0x66, 8020,
+	0x0, 8014,
+	/*8014*/ uint16(xSetOp), uint16(PADDD),
+	/*8016*/ uint16(xReadSlashR),
+	/*8017*/ uint16(xArgMm),
+	/*8018*/ uint16(xArgMmM64),
+	/*8019*/ uint16(xMatch),
+	/*8020*/ uint16(xSetOp), uint16(PADDD),
+	/*8022*/ uint16(xReadSlashR),
+	/*8023*/ uint16(xArgXmm1),
+	/*8024*/ uint16(xArgXmm2M128),
+	/*8025*/ uint16(xMatch),
+	/*8026*/ uint16(xSetOp), uint16(ADC),
+	/*8028*/ uint16(xReadSlashR),
+	/*8029*/ uint16(xArgRM8),
+	/*8030*/ uint16(xArgR8),
+	/*8031*/ uint16(xMatch),
+	/*8032*/ uint16(xCondIs64), 8035, 8051,
+	/*8035*/ uint16(xCondDataSize), 8039, 8045, 0,
+	/*8039*/ uint16(xSetOp), uint16(ADC),
+	/*8041*/ uint16(xReadSlashR),
+	/*8042*/ uint16(xArgRM16),
+	/*8043*/ uint16(xArgR16),
+	/*8044*/ uint16(xMatch),
+	/*8045*/ uint16(xSetOp), uint16(ADC),
+	/*8047*/ uint16(xReadSlashR),
+	/*8048*/ uint16(xArgRM32),
+	/*8049*/ uint16(xArgR32),
+	/*8050*/ uint16(xMatch),
+	/*8051*/ uint16(xCondDataSize), 8039, 8045, 8055,
+	/*8055*/ uint16(xSetOp), uint16(ADC),
+	/*8057*/ uint16(xReadSlashR),
+	/*8058*/ uint16(xArgRM64),
+	/*8059*/ uint16(xArgR64),
+	/*8060*/ uint16(xMatch),
+	/*8061*/ uint16(xSetOp), uint16(ADC),
+	/*8063*/ uint16(xReadSlashR),
+	/*8064*/ uint16(xArgR8),
+	/*8065*/ uint16(xArgRM8),
+	/*8066*/ uint16(xMatch),
+	/*8067*/ uint16(xCondIs64), 8070, 8086,
+	/*8070*/ uint16(xCondDataSize), 8074, 8080, 0,
+	/*8074*/ uint16(xSetOp), uint16(ADC),
+	/*8076*/ uint16(xReadSlashR),
+	/*8077*/ uint16(xArgR16),
+	/*8078*/ uint16(xArgRM16),
+	/*8079*/ uint16(xMatch),
+	/*8080*/ uint16(xSetOp), uint16(ADC),
+	/*8082*/ uint16(xReadSlashR),
+	/*8083*/ uint16(xArgR32),
+	/*8084*/ uint16(xArgRM32),
+	/*8085*/ uint16(xMatch),
+	/*8086*/ uint16(xCondDataSize), 8074, 8080, 8090,
+	/*8090*/ uint16(xSetOp), uint16(ADC),
+	/*8092*/ uint16(xReadSlashR),
+	/*8093*/ uint16(xArgR64),
+	/*8094*/ uint16(xArgRM64),
+	/*8095*/ uint16(xMatch),
+	/*8096*/ uint16(xSetOp), uint16(ADC),
+	/*8098*/ uint16(xReadIb),
+	/*8099*/ uint16(xArgAL),
+	/*8100*/ uint16(xArgImm8u),
+	/*8101*/ uint16(xMatch),
+	/*8102*/ uint16(xCondIs64), 8105, 8121,
+	/*8105*/ uint16(xCondDataSize), 8109, 8115, 0,
+	/*8109*/ uint16(xSetOp), uint16(ADC),
+	/*8111*/ uint16(xReadIw),
+	/*8112*/ uint16(xArgAX),
+	/*8113*/ uint16(xArgImm16),
+	/*8114*/ uint16(xMatch),
+	/*8115*/ uint16(xSetOp), uint16(ADC),
+	/*8117*/ uint16(xReadId),
+	/*8118*/ uint16(xArgEAX),
+	/*8119*/ uint16(xArgImm32),
+	/*8120*/ uint16(xMatch),
+	/*8121*/ uint16(xCondDataSize), 8109, 8115, 8125,
+	/*8125*/ uint16(xSetOp), uint16(ADC),
+	/*8127*/ uint16(xReadId),
+	/*8128*/ uint16(xArgRAX),
+	/*8129*/ uint16(xArgImm32),
+	/*8130*/ uint16(xMatch),
+	/*8131*/ uint16(xCondIs64), 8134, 0,
+	/*8134*/ uint16(xSetOp), uint16(PUSH),
+	/*8136*/ uint16(xArgSS),
+	/*8137*/ uint16(xMatch),
+	/*8138*/ uint16(xCondIs64), 8141, 0,
+	/*8141*/ uint16(xSetOp), uint16(POP),
+	/*8143*/ uint16(xArgSS),
+	/*8144*/ uint16(xMatch),
+	/*8145*/ uint16(xSetOp), uint16(SBB),
+	/*8147*/ uint16(xReadSlashR),
+	/*8148*/ uint16(xArgRM8),
+	/*8149*/ uint16(xArgR8),
+	/*8150*/ uint16(xMatch),
+	/*8151*/ uint16(xCondIs64), 8154, 8170,
+	/*8154*/ uint16(xCondDataSize), 8158, 8164, 0,
+	/*8158*/ uint16(xSetOp), uint16(SBB),
+	/*8160*/ uint16(xReadSlashR),
+	/*8161*/ uint16(xArgRM16),
+	/*8162*/ uint16(xArgR16),
+	/*8163*/ uint16(xMatch),
+	/*8164*/ uint16(xSetOp), uint16(SBB),
+	/*8166*/ uint16(xReadSlashR),
+	/*8167*/ uint16(xArgRM32),
+	/*8168*/ uint16(xArgR32),
+	/*8169*/ uint16(xMatch),
+	/*8170*/ uint16(xCondDataSize), 8158, 8164, 8174,
+	/*8174*/ uint16(xSetOp), uint16(SBB),
+	/*8176*/ uint16(xReadSlashR),
+	/*8177*/ uint16(xArgRM64),
+	/*8178*/ uint16(xArgR64),
+	/*8179*/ uint16(xMatch),
+	/*8180*/ uint16(xSetOp), uint16(SBB),
+	/*8182*/ uint16(xReadSlashR),
+	/*8183*/ uint16(xArgR8),
+	/*8184*/ uint16(xArgRM8),
+	/*8185*/ uint16(xMatch),
+	/*8186*/ uint16(xCondIs64), 8189, 8205,
+	/*8189*/ uint16(xCondDataSize), 8193, 8199, 0,
+	/*8193*/ uint16(xSetOp), uint16(SBB),
+	/*8195*/ uint16(xReadSlashR),
+	/*8196*/ uint16(xArgR16),
+	/*8197*/ uint16(xArgRM16),
+	/*8198*/ uint16(xMatch),
+	/*8199*/ uint16(xSetOp), uint16(SBB),
+	/*8201*/ uint16(xReadSlashR),
+	/*8202*/ uint16(xArgR32),
+	/*8203*/ uint16(xArgRM32),
+	/*8204*/ uint16(xMatch),
+	/*8205*/ uint16(xCondDataSize), 8193, 8199, 8209,
+	/*8209*/ uint16(xSetOp), uint16(SBB),
+	/*8211*/ uint16(xReadSlashR),
+	/*8212*/ uint16(xArgR64),
+	/*8213*/ uint16(xArgRM64),
+	/*8214*/ uint16(xMatch),
+	/*8215*/ uint16(xSetOp), uint16(SBB),
+	/*8217*/ uint16(xReadIb),
+	/*8218*/ uint16(xArgAL),
+	/*8219*/ uint16(xArgImm8u),
+	/*8220*/ uint16(xMatch),
+	/*8221*/ uint16(xCondIs64), 8224, 8240,
+	/*8224*/ uint16(xCondDataSize), 8228, 8234, 0,
+	/*8228*/ uint16(xSetOp), uint16(SBB),
+	/*8230*/ uint16(xReadIw),
+	/*8231*/ uint16(xArgAX),
+	/*8232*/ uint16(xArgImm16),
+	/*8233*/ uint16(xMatch),
+	/*8234*/ uint16(xSetOp), uint16(SBB),
+	/*8236*/ uint16(xReadId),
+	/*8237*/ uint16(xArgEAX),
+	/*8238*/ uint16(xArgImm32),
+	/*8239*/ uint16(xMatch),
+	/*8240*/ uint16(xCondDataSize), 8228, 8234, 8244,
+	/*8244*/ uint16(xSetOp), uint16(SBB),
+	/*8246*/ uint16(xReadId),
+	/*8247*/ uint16(xArgRAX),
+	/*8248*/ uint16(xArgImm32),
+	/*8249*/ uint16(xMatch),
+	/*8250*/ uint16(xCondIs64), 8253, 0,
+	/*8253*/ uint16(xSetOp), uint16(PUSH),
+	/*8255*/ uint16(xArgDS),
+	/*8256*/ uint16(xMatch),
+	/*8257*/ uint16(xCondIs64), 8260, 0,
+	/*8260*/ uint16(xSetOp), uint16(POP),
+	/*8262*/ uint16(xArgDS),
+	/*8263*/ uint16(xMatch),
+	/*8264*/ uint16(xSetOp), uint16(AND),
+	/*8266*/ uint16(xReadSlashR),
+	/*8267*/ uint16(xArgRM8),
+	/*8268*/ uint16(xArgR8),
+	/*8269*/ uint16(xMatch),
+	/*8270*/ uint16(xCondIs64), 8273, 8289,
+	/*8273*/ uint16(xCondDataSize), 8277, 8283, 0,
+	/*8277*/ uint16(xSetOp), uint16(AND),
+	/*8279*/ uint16(xReadSlashR),
+	/*8280*/ uint16(xArgRM16),
+	/*8281*/ uint16(xArgR16),
+	/*8282*/ uint16(xMatch),
+	/*8283*/ uint16(xSetOp), uint16(AND),
+	/*8285*/ uint16(xReadSlashR),
+	/*8286*/ uint16(xArgRM32),
+	/*8287*/ uint16(xArgR32),
+	/*8288*/ uint16(xMatch),
+	/*8289*/ uint16(xCondDataSize), 8277, 8283, 8293,
+	/*8293*/ uint16(xSetOp), uint16(AND),
+	/*8295*/ uint16(xReadSlashR),
+	/*8296*/ uint16(xArgRM64),
+	/*8297*/ uint16(xArgR64),
+	/*8298*/ uint16(xMatch),
+	/*8299*/ uint16(xSetOp), uint16(AND),
+	/*8301*/ uint16(xReadSlashR),
+	/*8302*/ uint16(xArgR8),
+	/*8303*/ uint16(xArgRM8),
+	/*8304*/ uint16(xMatch),
+	/*8305*/ uint16(xCondIs64), 8308, 8324,
+	/*8308*/ uint16(xCondDataSize), 8312, 8318, 0,
+	/*8312*/ uint16(xSetOp), uint16(AND),
+	/*8314*/ uint16(xReadSlashR),
+	/*8315*/ uint16(xArgR16),
+	/*8316*/ uint16(xArgRM16),
+	/*8317*/ uint16(xMatch),
+	/*8318*/ uint16(xSetOp), uint16(AND),
+	/*8320*/ uint16(xReadSlashR),
+	/*8321*/ uint16(xArgR32),
+	/*8322*/ uint16(xArgRM32),
+	/*8323*/ uint16(xMatch),
+	/*8324*/ uint16(xCondDataSize), 8312, 8318, 8328,
+	/*8328*/ uint16(xSetOp), uint16(AND),
+	/*8330*/ uint16(xReadSlashR),
+	/*8331*/ uint16(xArgR64),
+	/*8332*/ uint16(xArgRM64),
+	/*8333*/ uint16(xMatch),
+	/*8334*/ uint16(xSetOp), uint16(AND),
+	/*8336*/ uint16(xReadIb),
+	/*8337*/ uint16(xArgAL),
+	/*8338*/ uint16(xArgImm8u),
+	/*8339*/ uint16(xMatch),
+	/*8340*/ uint16(xCondIs64), 8343, 8359,
+	/*8343*/ uint16(xCondDataSize), 8347, 8353, 0,
+	/*8347*/ uint16(xSetOp), uint16(AND),
+	/*8349*/ uint16(xReadIw),
+	/*8350*/ uint16(xArgAX),
+	/*8351*/ uint16(xArgImm16),
+	/*8352*/ uint16(xMatch),
+	/*8353*/ uint16(xSetOp), uint16(AND),
+	/*8355*/ uint16(xReadId),
+	/*8356*/ uint16(xArgEAX),
+	/*8357*/ uint16(xArgImm32),
+	/*8358*/ uint16(xMatch),
+	/*8359*/ uint16(xCondDataSize), 8347, 8353, 8363,
+	/*8363*/ uint16(xSetOp), uint16(AND),
+	/*8365*/ uint16(xReadId),
+	/*8366*/ uint16(xArgRAX),
+	/*8367*/ uint16(xArgImm32),
+	/*8368*/ uint16(xMatch),
+	/*8369*/ uint16(xCondIs64), 8372, 0,
+	/*8372*/ uint16(xSetOp), uint16(DAA),
+	/*8374*/ uint16(xMatch),
+	/*8375*/ uint16(xSetOp), uint16(SUB),
+	/*8377*/ uint16(xReadSlashR),
+	/*8378*/ uint16(xArgRM8),
+	/*8379*/ uint16(xArgR8),
+	/*8380*/ uint16(xMatch),
+	/*8381*/ uint16(xCondIs64), 8384, 8400,
+	/*8384*/ uint16(xCondDataSize), 8388, 8394, 0,
+	/*8388*/ uint16(xSetOp), uint16(SUB),
+	/*8390*/ uint16(xReadSlashR),
+	/*8391*/ uint16(xArgRM16),
+	/*8392*/ uint16(xArgR16),
+	/*8393*/ uint16(xMatch),
+	/*8394*/ uint16(xSetOp), uint16(SUB),
+	/*8396*/ uint16(xReadSlashR),
+	/*8397*/ uint16(xArgRM32),
+	/*8398*/ uint16(xArgR32),
+	/*8399*/ uint16(xMatch),
+	/*8400*/ uint16(xCondDataSize), 8388, 8394, 8404,
+	/*8404*/ uint16(xSetOp), uint16(SUB),
+	/*8406*/ uint16(xReadSlashR),
+	/*8407*/ uint16(xArgRM64),
+	/*8408*/ uint16(xArgR64),
+	/*8409*/ uint16(xMatch),
+	/*8410*/ uint16(xSetOp), uint16(SUB),
+	/*8412*/ uint16(xReadSlashR),
+	/*8413*/ uint16(xArgR8),
+	/*8414*/ uint16(xArgRM8),
+	/*8415*/ uint16(xMatch),
+	/*8416*/ uint16(xCondIs64), 8419, 8435,
+	/*8419*/ uint16(xCondDataSize), 8423, 8429, 0,
+	/*8423*/ uint16(xSetOp), uint16(SUB),
+	/*8425*/ uint16(xReadSlashR),
+	/*8426*/ uint16(xArgR16),
+	/*8427*/ uint16(xArgRM16),
+	/*8428*/ uint16(xMatch),
+	/*8429*/ uint16(xSetOp), uint16(SUB),
+	/*8431*/ uint16(xReadSlashR),
+	/*8432*/ uint16(xArgR32),
+	/*8433*/ uint16(xArgRM32),
+	/*8434*/ uint16(xMatch),
+	/*8435*/ uint16(xCondDataSize), 8423, 8429, 8439,
+	/*8439*/ uint16(xSetOp), uint16(SUB),
+	/*8441*/ uint16(xReadSlashR),
+	/*8442*/ uint16(xArgR64),
+	/*8443*/ uint16(xArgRM64),
+	/*8444*/ uint16(xMatch),
+	/*8445*/ uint16(xSetOp), uint16(SUB),
+	/*8447*/ uint16(xReadIb),
+	/*8448*/ uint16(xArgAL),
+	/*8449*/ uint16(xArgImm8u),
+	/*8450*/ uint16(xMatch),
+	/*8451*/ uint16(xCondIs64), 8454, 8470,
+	/*8454*/ uint16(xCondDataSize), 8458, 8464, 0,
+	/*8458*/ uint16(xSetOp), uint16(SUB),
+	/*8460*/ uint16(xReadIw),
+	/*8461*/ uint16(xArgAX),
+	/*8462*/ uint16(xArgImm16),
+	/*8463*/ uint16(xMatch),
+	/*8464*/ uint16(xSetOp), uint16(SUB),
+	/*8466*/ uint16(xReadId),
+	/*8467*/ uint16(xArgEAX),
+	/*8468*/ uint16(xArgImm32),
+	/*8469*/ uint16(xMatch),
+	/*8470*/ uint16(xCondDataSize), 8458, 8464, 8474,
+	/*8474*/ uint16(xSetOp), uint16(SUB),
+	/*8476*/ uint16(xReadId),
+	/*8477*/ uint16(xArgRAX),
+	/*8478*/ uint16(xArgImm32),
+	/*8479*/ uint16(xMatch),
+	/*8480*/ uint16(xCondIs64), 8483, 0,
+	/*8483*/ uint16(xSetOp), uint16(DAS),
+	/*8485*/ uint16(xMatch),
+	/*8486*/ uint16(xSetOp), uint16(XOR),
+	/*8488*/ uint16(xReadSlashR),
+	/*8489*/ uint16(xArgRM8),
+	/*8490*/ uint16(xArgR8),
+	/*8491*/ uint16(xMatch),
+	/*8492*/ uint16(xCondIs64), 8495, 8511,
+	/*8495*/ uint16(xCondDataSize), 8499, 8505, 0,
+	/*8499*/ uint16(xSetOp), uint16(XOR),
+	/*8501*/ uint16(xReadSlashR),
+	/*8502*/ uint16(xArgRM16),
+	/*8503*/ uint16(xArgR16),
+	/*8504*/ uint16(xMatch),
+	/*8505*/ uint16(xSetOp), uint16(XOR),
+	/*8507*/ uint16(xReadSlashR),
+	/*8508*/ uint16(xArgRM32),
+	/*8509*/ uint16(xArgR32),
+	/*8510*/ uint16(xMatch),
+	/*8511*/ uint16(xCondDataSize), 8499, 8505, 8515,
+	/*8515*/ uint16(xSetOp), uint16(XOR),
+	/*8517*/ uint16(xReadSlashR),
+	/*8518*/ uint16(xArgRM64),
+	/*8519*/ uint16(xArgR64),
+	/*8520*/ uint16(xMatch),
+	/*8521*/ uint16(xSetOp), uint16(XOR),
+	/*8523*/ uint16(xReadSlashR),
+	/*8524*/ uint16(xArgR8),
+	/*8525*/ uint16(xArgRM8),
+	/*8526*/ uint16(xMatch),
+	/*8527*/ uint16(xCondIs64), 8530, 8546,
+	/*8530*/ uint16(xCondDataSize), 8534, 8540, 0,
+	/*8534*/ uint16(xSetOp), uint16(XOR),
+	/*8536*/ uint16(xReadSlashR),
+	/*8537*/ uint16(xArgR16),
+	/*8538*/ uint16(xArgRM16),
+	/*8539*/ uint16(xMatch),
+	/*8540*/ uint16(xSetOp), uint16(XOR),
+	/*8542*/ uint16(xReadSlashR),
+	/*8543*/ uint16(xArgR32),
+	/*8544*/ uint16(xArgRM32),
+	/*8545*/ uint16(xMatch),
+	/*8546*/ uint16(xCondDataSize), 8534, 8540, 8550,
+	/*8550*/ uint16(xSetOp), uint16(XOR),
+	/*8552*/ uint16(xReadSlashR),
+	/*8553*/ uint16(xArgR64),
+	/*8554*/ uint16(xArgRM64),
+	/*8555*/ uint16(xMatch),
+	/*8556*/ uint16(xSetOp), uint16(XOR),
+	/*8558*/ uint16(xReadIb),
+	/*8559*/ uint16(xArgAL),
+	/*8560*/ uint16(xArgImm8u),
+	/*8561*/ uint16(xMatch),
+	/*8562*/ uint16(xCondIs64), 8565, 8581,
+	/*8565*/ uint16(xCondDataSize), 8569, 8575, 0,
+	/*8569*/ uint16(xSetOp), uint16(XOR),
+	/*8571*/ uint16(xReadIw),
+	/*8572*/ uint16(xArgAX),
+	/*8573*/ uint16(xArgImm16),
+	/*8574*/ uint16(xMatch),
+	/*8575*/ uint16(xSetOp), uint16(XOR),
+	/*8577*/ uint16(xReadId),
+	/*8578*/ uint16(xArgEAX),
+	/*8579*/ uint16(xArgImm32),
+	/*8580*/ uint16(xMatch),
+	/*8581*/ uint16(xCondDataSize), 8569, 8575, 8585,
+	/*8585*/ uint16(xSetOp), uint16(XOR),
+	/*8587*/ uint16(xReadId),
+	/*8588*/ uint16(xArgRAX),
+	/*8589*/ uint16(xArgImm32),
+	/*8590*/ uint16(xMatch),
+	/*8591*/ uint16(xCondIs64), 8594, 0,
+	/*8594*/ uint16(xSetOp), uint16(AAA),
+	/*8596*/ uint16(xMatch),
+	/*8597*/ uint16(xSetOp), uint16(CMP),
+	/*8599*/ uint16(xReadSlashR),
+	/*8600*/ uint16(xArgRM8),
+	/*8601*/ uint16(xArgR8),
+	/*8602*/ uint16(xMatch),
+	/*8603*/ uint16(xCondIs64), 8606, 8622,
+	/*8606*/ uint16(xCondDataSize), 8610, 8616, 0,
+	/*8610*/ uint16(xSetOp), uint16(CMP),
+	/*8612*/ uint16(xReadSlashR),
+	/*8613*/ uint16(xArgRM16),
+	/*8614*/ uint16(xArgR16),
+	/*8615*/ uint16(xMatch),
+	/*8616*/ uint16(xSetOp), uint16(CMP),
+	/*8618*/ uint16(xReadSlashR),
+	/*8619*/ uint16(xArgRM32),
+	/*8620*/ uint16(xArgR32),
+	/*8621*/ uint16(xMatch),
+	/*8622*/ uint16(xCondDataSize), 8610, 8616, 8626,
+	/*8626*/ uint16(xSetOp), uint16(CMP),
+	/*8628*/ uint16(xReadSlashR),
+	/*8629*/ uint16(xArgRM64),
+	/*8630*/ uint16(xArgR64),
+	/*8631*/ uint16(xMatch),
+	/*8632*/ uint16(xSetOp), uint16(CMP),
+	/*8634*/ uint16(xReadSlashR),
+	/*8635*/ uint16(xArgR8),
+	/*8636*/ uint16(xArgRM8),
+	/*8637*/ uint16(xMatch),
+	/*8638*/ uint16(xCondIs64), 8641, 8657,
+	/*8641*/ uint16(xCondDataSize), 8645, 8651, 0,
+	/*8645*/ uint16(xSetOp), uint16(CMP),
+	/*8647*/ uint16(xReadSlashR),
+	/*8648*/ uint16(xArgR16),
+	/*8649*/ uint16(xArgRM16),
+	/*8650*/ uint16(xMatch),
+	/*8651*/ uint16(xSetOp), uint16(CMP),
+	/*8653*/ uint16(xReadSlashR),
+	/*8654*/ uint16(xArgR32),
+	/*8655*/ uint16(xArgRM32),
+	/*8656*/ uint16(xMatch),
+	/*8657*/ uint16(xCondDataSize), 8645, 8651, 8661,
+	/*8661*/ uint16(xSetOp), uint16(CMP),
+	/*8663*/ uint16(xReadSlashR),
+	/*8664*/ uint16(xArgR64),
+	/*8665*/ uint16(xArgRM64),
+	/*8666*/ uint16(xMatch),
+	/*8667*/ uint16(xSetOp), uint16(CMP),
+	/*8669*/ uint16(xReadIb),
+	/*8670*/ uint16(xArgAL),
+	/*8671*/ uint16(xArgImm8u),
+	/*8672*/ uint16(xMatch),
+	/*8673*/ uint16(xCondIs64), 8676, 8692,
+	/*8676*/ uint16(xCondDataSize), 8680, 8686, 0,
+	/*8680*/ uint16(xSetOp), uint16(CMP),
+	/*8682*/ uint16(xReadIw),
+	/*8683*/ uint16(xArgAX),
+	/*8684*/ uint16(xArgImm16),
+	/*8685*/ uint16(xMatch),
+	/*8686*/ uint16(xSetOp), uint16(CMP),
+	/*8688*/ uint16(xReadId),
+	/*8689*/ uint16(xArgEAX),
+	/*8690*/ uint16(xArgImm32),
+	/*8691*/ uint16(xMatch),
+	/*8692*/ uint16(xCondDataSize), 8680, 8686, 8696,
+	/*8696*/ uint16(xSetOp), uint16(CMP),
+	/*8698*/ uint16(xReadId),
+	/*8699*/ uint16(xArgRAX),
+	/*8700*/ uint16(xArgImm32),
+	/*8701*/ uint16(xMatch),
+	/*8702*/ uint16(xCondIs64), 8705, 0,
+	/*8705*/ uint16(xSetOp), uint16(AAS),
+	/*8707*/ uint16(xMatch),
+	/*8708*/ uint16(xCondIs64), 8711, 0,
+	/*8711*/ uint16(xCondDataSize), 8715, 8719, 0,
+	/*8715*/ uint16(xSetOp), uint16(INC),
+	/*8717*/ uint16(xArgR16op),
+	/*8718*/ uint16(xMatch),
+	/*8719*/ uint16(xSetOp), uint16(INC),
+	/*8721*/ uint16(xArgR32op),
+	/*8722*/ uint16(xMatch),
+	/*8723*/ uint16(xCondIs64), 8726, 0,
+	/*8726*/ uint16(xCondDataSize), 8730, 8734, 0,
+	/*8730*/ uint16(xSetOp), uint16(DEC),
+	/*8732*/ uint16(xArgR16op),
+	/*8733*/ uint16(xMatch),
+	/*8734*/ uint16(xSetOp), uint16(DEC),
+	/*8736*/ uint16(xArgR32op),
+	/*8737*/ uint16(xMatch),
+	/*8738*/ uint16(xCondIs64), 8741, 8753,
+	/*8741*/ uint16(xCondDataSize), 8745, 8749, 0,
+	/*8745*/ uint16(xSetOp), uint16(PUSH),
+	/*8747*/ uint16(xArgR16op),
+	/*8748*/ uint16(xMatch),
+	/*8749*/ uint16(xSetOp), uint16(PUSH),
+	/*8751*/ uint16(xArgR32op),
+	/*8752*/ uint16(xMatch),
+	/*8753*/ uint16(xCondDataSize), 8745, 8757, 8761,
+	/*8757*/ uint16(xSetOp), uint16(PUSH),
+	/*8759*/ uint16(xArgR64op),
+	/*8760*/ uint16(xMatch),
+	/*8761*/ uint16(xSetOp), uint16(PUSH),
+	/*8763*/ uint16(xArgR64op),
+	/*8764*/ uint16(xMatch),
+	/*8765*/ uint16(xCondIs64), 8768, 8780,
+	/*8768*/ uint16(xCondDataSize), 8772, 8776, 0,
+	/*8772*/ uint16(xSetOp), uint16(POP),
+	/*8774*/ uint16(xArgR16op),
+	/*8775*/ uint16(xMatch),
+	/*8776*/ uint16(xSetOp), uint16(POP),
+	/*8778*/ uint16(xArgR32op),
+	/*8779*/ uint16(xMatch),
+	/*8780*/ uint16(xCondDataSize), 8772, 8784, 8788,
+	/*8784*/ uint16(xSetOp), uint16(POP),
+	/*8786*/ uint16(xArgR64op),
+	/*8787*/ uint16(xMatch),
+	/*8788*/ uint16(xSetOp), uint16(POP),
+	/*8790*/ uint16(xArgR64op),
+	/*8791*/ uint16(xMatch),
+	/*8792*/ uint16(xCondIs64), 8795, 0,
+	/*8795*/ uint16(xCondDataSize), 8799, 8802, 0,
+	/*8799*/ uint16(xSetOp), uint16(PUSHA),
+	/*8801*/ uint16(xMatch),
+	/*8802*/ uint16(xSetOp), uint16(PUSHAD),
+	/*8804*/ uint16(xMatch),
+	/*8805*/ uint16(xCondIs64), 8808, 0,
+	/*8808*/ uint16(xCondDataSize), 8812, 8815, 0,
+	/*8812*/ uint16(xSetOp), uint16(POPA),
+	/*8814*/ uint16(xMatch),
+	/*8815*/ uint16(xSetOp), uint16(POPAD),
+	/*8817*/ uint16(xMatch),
+	/*8818*/ uint16(xCondIs64), 8821, 0,
+	/*8821*/ uint16(xCondDataSize), 8825, 8831, 0,
+	/*8825*/ uint16(xSetOp), uint16(BOUND),
+	/*8827*/ uint16(xReadSlashR),
+	/*8828*/ uint16(xArgR16),
+	/*8829*/ uint16(xArgM16and16),
+	/*8830*/ uint16(xMatch),
+	/*8831*/ uint16(xSetOp), uint16(BOUND),
+	/*8833*/ uint16(xReadSlashR),
+	/*8834*/ uint16(xArgR32),
+	/*8835*/ uint16(xArgM32and32),
+	/*8836*/ uint16(xMatch),
+	/*8837*/ uint16(xCondIs64), 8840, 8846,
+	/*8840*/ uint16(xSetOp), uint16(ARPL),
+	/*8842*/ uint16(xReadSlashR),
+	/*8843*/ uint16(xArgRM16),
+	/*8844*/ uint16(xArgR16),
+	/*8845*/ uint16(xMatch),
+	/*8846*/ uint16(xCondDataSize), 8850, 8856, 8862,
+	/*8850*/ uint16(xSetOp), uint16(MOVSXD),
+	/*8852*/ uint16(xReadSlashR),
+	/*8853*/ uint16(xArgR16),
+	/*8854*/ uint16(xArgRM32),
+	/*8855*/ uint16(xMatch),
+	/*8856*/ uint16(xSetOp), uint16(MOVSXD),
+	/*8858*/ uint16(xReadSlashR),
+	/*8859*/ uint16(xArgR32),
+	/*8860*/ uint16(xArgRM32),
+	/*8861*/ uint16(xMatch),
+	/*8862*/ uint16(xSetOp), uint16(MOVSXD),
+	/*8864*/ uint16(xReadSlashR),
+	/*8865*/ uint16(xArgR64),
+	/*8866*/ uint16(xArgRM32),
+	/*8867*/ uint16(xMatch),
+	/*8868*/ uint16(xCondDataSize), 8872, 8877, 8882,
+	/*8872*/ uint16(xSetOp), uint16(PUSH),
+	/*8874*/ uint16(xReadIw),
+	/*8875*/ uint16(xArgImm16),
+	/*8876*/ uint16(xMatch),
+	/*8877*/ uint16(xSetOp), uint16(PUSH),
+	/*8879*/ uint16(xReadId),
+	/*8880*/ uint16(xArgImm32),
+	/*8881*/ uint16(xMatch),
+	/*8882*/ uint16(xSetOp), uint16(PUSH),
+	/*8884*/ uint16(xReadId),
+	/*8885*/ uint16(xArgImm32),
+	/*8886*/ uint16(xMatch),
+	/*8887*/ uint16(xCondIs64), 8890, 8910,
+	/*8890*/ uint16(xCondDataSize), 8894, 8902, 0,
+	/*8894*/ uint16(xSetOp), uint16(IMUL),
+	/*8896*/ uint16(xReadSlashR),
+	/*8897*/ uint16(xReadIw),
+	/*8898*/ uint16(xArgR16),
+	/*8899*/ uint16(xArgRM16),
+	/*8900*/ uint16(xArgImm16),
+	/*8901*/ uint16(xMatch),
+	/*8902*/ uint16(xSetOp), uint16(IMUL),
+	/*8904*/ uint16(xReadSlashR),
+	/*8905*/ uint16(xReadId),
+	/*8906*/ uint16(xArgR32),
+	/*8907*/ uint16(xArgRM32),
+	/*8908*/ uint16(xArgImm32),
+	/*8909*/ uint16(xMatch),
+	/*8910*/ uint16(xCondDataSize), 8894, 8902, 8914,
+	/*8914*/ uint16(xSetOp), uint16(IMUL),
+	/*8916*/ uint16(xReadSlashR),
+	/*8917*/ uint16(xReadId),
+	/*8918*/ uint16(xArgR64),
+	/*8919*/ uint16(xArgRM64),
+	/*8920*/ uint16(xArgImm32),
+	/*8921*/ uint16(xMatch),
+	/*8922*/ uint16(xSetOp), uint16(PUSH),
+	/*8924*/ uint16(xReadIb),
+	/*8925*/ uint16(xArgImm8),
+	/*8926*/ uint16(xMatch),
+	/*8927*/ uint16(xCondIs64), 8930, 8950,
+	/*8930*/ uint16(xCondDataSize), 8934, 8942, 0,
+	/*8934*/ uint16(xSetOp), uint16(IMUL),
+	/*8936*/ uint16(xReadSlashR),
+	/*8937*/ uint16(xReadIb),
+	/*8938*/ uint16(xArgR16),
+	/*8939*/ uint16(xArgRM16),
+	/*8940*/ uint16(xArgImm8),
+	/*8941*/ uint16(xMatch),
+	/*8942*/ uint16(xSetOp), uint16(IMUL),
+	/*8944*/ uint16(xReadSlashR),
+	/*8945*/ uint16(xReadIb),
+	/*8946*/ uint16(xArgR32),
+	/*8947*/ uint16(xArgRM32),
+	/*8948*/ uint16(xArgImm8),
+	/*8949*/ uint16(xMatch),
+	/*8950*/ uint16(xCondDataSize), 8934, 8942, 8954,
+	/*8954*/ uint16(xSetOp), uint16(IMUL),
+	/*8956*/ uint16(xReadSlashR),
+	/*8957*/ uint16(xReadIb),
+	/*8958*/ uint16(xArgR64),
+	/*8959*/ uint16(xArgRM64),
+	/*8960*/ uint16(xArgImm8),
+	/*8961*/ uint16(xMatch),
+	/*8962*/ uint16(xSetOp), uint16(INSB),
+	/*8964*/ uint16(xMatch),
+	/*8965*/ uint16(xCondDataSize), 8969, 8972, 8975,
+	/*8969*/ uint16(xSetOp), uint16(INSW),
+	/*8971*/ uint16(xMatch),
+	/*8972*/ uint16(xSetOp), uint16(INSD),
+	/*8974*/ uint16(xMatch),
+	/*8975*/ uint16(xSetOp), uint16(INSD),
+	/*8977*/ uint16(xMatch),
+	/*8978*/ uint16(xSetOp), uint16(OUTSB),
+	/*8980*/ uint16(xMatch),
+	/*8981*/ uint16(xCondDataSize), 8985, 8988, 8991,
+	/*8985*/ uint16(xSetOp), uint16(OUTSW),
+	/*8987*/ uint16(xMatch),
+	/*8988*/ uint16(xSetOp), uint16(OUTSD),
+	/*8990*/ uint16(xMatch),
+	/*8991*/ uint16(xSetOp), uint16(OUTSD),
+	/*8993*/ uint16(xMatch),
+	/*8994*/ uint16(xSetOp), uint16(JO),
+	/*8996*/ uint16(xReadCb),
+	/*8997*/ uint16(xArgRel8),
+	/*8998*/ uint16(xMatch),
+	/*8999*/ uint16(xSetOp), uint16(JNO),
+	/*9001*/ uint16(xReadCb),
+	/*9002*/ uint16(xArgRel8),
+	/*9003*/ uint16(xMatch),
+	/*9004*/ uint16(xSetOp), uint16(JB),
+	/*9006*/ uint16(xReadCb),
+	/*9007*/ uint16(xArgRel8),
+	/*9008*/ uint16(xMatch),
+	/*9009*/ uint16(xSetOp), uint16(JAE),
+	/*9011*/ uint16(xReadCb),
+	/*9012*/ uint16(xArgRel8),
+	/*9013*/ uint16(xMatch),
+	/*9014*/ uint16(xSetOp), uint16(JE),
+	/*9016*/ uint16(xReadCb),
+	/*9017*/ uint16(xArgRel8),
+	/*9018*/ uint16(xMatch),
+	/*9019*/ uint16(xSetOp), uint16(JNE),
+	/*9021*/ uint16(xReadCb),
+	/*9022*/ uint16(xArgRel8),
+	/*9023*/ uint16(xMatch),
+	/*9024*/ uint16(xSetOp), uint16(JBE),
+	/*9026*/ uint16(xReadCb),
+	/*9027*/ uint16(xArgRel8),
+	/*9028*/ uint16(xMatch),
+	/*9029*/ uint16(xSetOp), uint16(JA),
+	/*9031*/ uint16(xReadCb),
+	/*9032*/ uint16(xArgRel8),
+	/*9033*/ uint16(xMatch),
+	/*9034*/ uint16(xSetOp), uint16(JS),
+	/*9036*/ uint16(xReadCb),
+	/*9037*/ uint16(xArgRel8),
+	/*9038*/ uint16(xMatch),
+	/*9039*/ uint16(xSetOp), uint16(JNS),
+	/*9041*/ uint16(xReadCb),
+	/*9042*/ uint16(xArgRel8),
+	/*9043*/ uint16(xMatch),
+	/*9044*/ uint16(xSetOp), uint16(JP),
+	/*9046*/ uint16(xReadCb),
+	/*9047*/ uint16(xArgRel8),
+	/*9048*/ uint16(xMatch),
+	/*9049*/ uint16(xSetOp), uint16(JNP),
+	/*9051*/ uint16(xReadCb),
+	/*9052*/ uint16(xArgRel8),
+	/*9053*/ uint16(xMatch),
+	/*9054*/ uint16(xSetOp), uint16(JL),
+	/*9056*/ uint16(xReadCb),
+	/*9057*/ uint16(xArgRel8),
+	/*9058*/ uint16(xMatch),
+	/*9059*/ uint16(xSetOp), uint16(JGE),
+	/*9061*/ uint16(xReadCb),
+	/*9062*/ uint16(xArgRel8),
+	/*9063*/ uint16(xMatch),
+	/*9064*/ uint16(xSetOp), uint16(JLE),
+	/*9066*/ uint16(xReadCb),
+	/*9067*/ uint16(xArgRel8),
+	/*9068*/ uint16(xMatch),
+	/*9069*/ uint16(xSetOp), uint16(JG),
+	/*9071*/ uint16(xReadCb),
+	/*9072*/ uint16(xArgRel8),
+	/*9073*/ uint16(xMatch),
+	/*9074*/ uint16(xCondSlashR),
+	9083, // 0
+	9089, // 1
+	9095, // 2
+	9101, // 3
+	9107, // 4
+	9113, // 5
+	9119, // 6
+	9125, // 7
+	/*9083*/ uint16(xSetOp), uint16(ADD),
+	/*9085*/ uint16(xReadIb),
+	/*9086*/ uint16(xArgRM8),
+	/*9087*/ uint16(xArgImm8u),
+	/*9088*/ uint16(xMatch),
+	/*9089*/ uint16(xSetOp), uint16(OR),
+	/*9091*/ uint16(xReadIb),
+	/*9092*/ uint16(xArgRM8),
+	/*9093*/ uint16(xArgImm8u),
+	/*9094*/ uint16(xMatch),
+	/*9095*/ uint16(xSetOp), uint16(ADC),
+	/*9097*/ uint16(xReadIb),
+	/*9098*/ uint16(xArgRM8),
+	/*9099*/ uint16(xArgImm8u),
+	/*9100*/ uint16(xMatch),
+	/*9101*/ uint16(xSetOp), uint16(SBB),
+	/*9103*/ uint16(xReadIb),
+	/*9104*/ uint16(xArgRM8),
+	/*9105*/ uint16(xArgImm8u),
+	/*9106*/ uint16(xMatch),
+	/*9107*/ uint16(xSetOp), uint16(AND),
+	/*9109*/ uint16(xReadIb),
+	/*9110*/ uint16(xArgRM8),
+	/*9111*/ uint16(xArgImm8u),
+	/*9112*/ uint16(xMatch),
+	/*9113*/ uint16(xSetOp), uint16(SUB),
+	/*9115*/ uint16(xReadIb),
+	/*9116*/ uint16(xArgRM8),
+	/*9117*/ uint16(xArgImm8u),
+	/*9118*/ uint16(xMatch),
+	/*9119*/ uint16(xSetOp), uint16(XOR),
+	/*9121*/ uint16(xReadIb),
+	/*9122*/ uint16(xArgRM8),
+	/*9123*/ uint16(xArgImm8u),
+	/*9124*/ uint16(xMatch),
+	/*9125*/ uint16(xSetOp), uint16(CMP),
+	/*9127*/ uint16(xReadIb),
+	/*9128*/ uint16(xArgRM8),
+	/*9129*/ uint16(xArgImm8u),
+	/*9130*/ uint16(xMatch),
+	/*9131*/ uint16(xCondSlashR),
+	9140, // 0
+	9169, // 1
+	9198, // 2
+	9227, // 3
+	9256, // 4
+	9285, // 5
+	9314, // 6
+	9343, // 7
+	/*9140*/ uint16(xCondIs64), 9143, 9159,
+	/*9143*/ uint16(xCondDataSize), 9147, 9153, 0,
+	/*9147*/ uint16(xSetOp), uint16(ADD),
+	/*9149*/ uint16(xReadIw),
+	/*9150*/ uint16(xArgRM16),
+	/*9151*/ uint16(xArgImm16),
+	/*9152*/ uint16(xMatch),
+	/*9153*/ uint16(xSetOp), uint16(ADD),
+	/*9155*/ uint16(xReadId),
+	/*9156*/ uint16(xArgRM32),
+	/*9157*/ uint16(xArgImm32),
+	/*9158*/ uint16(xMatch),
+	/*9159*/ uint16(xCondDataSize), 9147, 9153, 9163,
+	/*9163*/ uint16(xSetOp), uint16(ADD),
+	/*9165*/ uint16(xReadId),
+	/*9166*/ uint16(xArgRM64),
+	/*9167*/ uint16(xArgImm32),
+	/*9168*/ uint16(xMatch),
+	/*9169*/ uint16(xCondIs64), 9172, 9188,
+	/*9172*/ uint16(xCondDataSize), 9176, 9182, 0,
+	/*9176*/ uint16(xSetOp), uint16(OR),
+	/*9178*/ uint16(xReadIw),
+	/*9179*/ uint16(xArgRM16),
+	/*9180*/ uint16(xArgImm16),
+	/*9181*/ uint16(xMatch),
+	/*9182*/ uint16(xSetOp), uint16(OR),
+	/*9184*/ uint16(xReadId),
+	/*9185*/ uint16(xArgRM32),
+	/*9186*/ uint16(xArgImm32),
+	/*9187*/ uint16(xMatch),
+	/*9188*/ uint16(xCondDataSize), 9176, 9182, 9192,
+	/*9192*/ uint16(xSetOp), uint16(OR),
+	/*9194*/ uint16(xReadId),
+	/*9195*/ uint16(xArgRM64),
+	/*9196*/ uint16(xArgImm32),
+	/*9197*/ uint16(xMatch),
+	/*9198*/ uint16(xCondIs64), 9201, 9217,
+	/*9201*/ uint16(xCondDataSize), 9205, 9211, 0,
+	/*9205*/ uint16(xSetOp), uint16(ADC),
+	/*9207*/ uint16(xReadIw),
+	/*9208*/ uint16(xArgRM16),
+	/*9209*/ uint16(xArgImm16),
+	/*9210*/ uint16(xMatch),
+	/*9211*/ uint16(xSetOp), uint16(ADC),
+	/*9213*/ uint16(xReadId),
+	/*9214*/ uint16(xArgRM32),
+	/*9215*/ uint16(xArgImm32),
+	/*9216*/ uint16(xMatch),
+	/*9217*/ uint16(xCondDataSize), 9205, 9211, 9221,
+	/*9221*/ uint16(xSetOp), uint16(ADC),
+	/*9223*/ uint16(xReadId),
+	/*9224*/ uint16(xArgRM64),
+	/*9225*/ uint16(xArgImm32),
+	/*9226*/ uint16(xMatch),
+	/*9227*/ uint16(xCondIs64), 9230, 9246,
+	/*9230*/ uint16(xCondDataSize), 9234, 9240, 0,
+	/*9234*/ uint16(xSetOp), uint16(SBB),
+	/*9236*/ uint16(xReadIw),
+	/*9237*/ uint16(xArgRM16),
+	/*9238*/ uint16(xArgImm16),
+	/*9239*/ uint16(xMatch),
+	/*9240*/ uint16(xSetOp), uint16(SBB),
+	/*9242*/ uint16(xReadId),
+	/*9243*/ uint16(xArgRM32),
+	/*9244*/ uint16(xArgImm32),
+	/*9245*/ uint16(xMatch),
+	/*9246*/ uint16(xCondDataSize), 9234, 9240, 9250,
+	/*9250*/ uint16(xSetOp), uint16(SBB),
+	/*9252*/ uint16(xReadId),
+	/*9253*/ uint16(xArgRM64),
+	/*9254*/ uint16(xArgImm32),
+	/*9255*/ uint16(xMatch),
+	/*9256*/ uint16(xCondIs64), 9259, 9275,
+	/*9259*/ uint16(xCondDataSize), 9263, 9269, 0,
+	/*9263*/ uint16(xSetOp), uint16(AND),
+	/*9265*/ uint16(xReadIw),
+	/*9266*/ uint16(xArgRM16),
+	/*9267*/ uint16(xArgImm16),
+	/*9268*/ uint16(xMatch),
+	/*9269*/ uint16(xSetOp), uint16(AND),
+	/*9271*/ uint16(xReadId),
+	/*9272*/ uint16(xArgRM32),
+	/*9273*/ uint16(xArgImm32),
+	/*9274*/ uint16(xMatch),
+	/*9275*/ uint16(xCondDataSize), 9263, 9269, 9279,
+	/*9279*/ uint16(xSetOp), uint16(AND),
+	/*9281*/ uint16(xReadId),
+	/*9282*/ uint16(xArgRM64),
+	/*9283*/ uint16(xArgImm32),
+	/*9284*/ uint16(xMatch),
+	/*9285*/ uint16(xCondIs64), 9288, 9304,
+	/*9288*/ uint16(xCondDataSize), 9292, 9298, 0,
+	/*9292*/ uint16(xSetOp), uint16(SUB),
+	/*9294*/ uint16(xReadIw),
+	/*9295*/ uint16(xArgRM16),
+	/*9296*/ uint16(xArgImm16),
+	/*9297*/ uint16(xMatch),
+	/*9298*/ uint16(xSetOp), uint16(SUB),
+	/*9300*/ uint16(xReadId),
+	/*9301*/ uint16(xArgRM32),
+	/*9302*/ uint16(xArgImm32),
+	/*9303*/ uint16(xMatch),
+	/*9304*/ uint16(xCondDataSize), 9292, 9298, 9308,
+	/*9308*/ uint16(xSetOp), uint16(SUB),
+	/*9310*/ uint16(xReadId),
+	/*9311*/ uint16(xArgRM64),
+	/*9312*/ uint16(xArgImm32),
+	/*9313*/ uint16(xMatch),
+	/*9314*/ uint16(xCondIs64), 9317, 9333,
+	/*9317*/ uint16(xCondDataSize), 9321, 9327, 0,
+	/*9321*/ uint16(xSetOp), uint16(XOR),
+	/*9323*/ uint16(xReadIw),
+	/*9324*/ uint16(xArgRM16),
+	/*9325*/ uint16(xArgImm16),
+	/*9326*/ uint16(xMatch),
+	/*9327*/ uint16(xSetOp), uint16(XOR),
+	/*9329*/ uint16(xReadId),
+	/*9330*/ uint16(xArgRM32),
+	/*9331*/ uint16(xArgImm32),
+	/*9332*/ uint16(xMatch),
+	/*9333*/ uint16(xCondDataSize), 9321, 9327, 9337,
+	/*9337*/ uint16(xSetOp), uint16(XOR),
+	/*9339*/ uint16(xReadId),
+	/*9340*/ uint16(xArgRM64),
+	/*9341*/ uint16(xArgImm32),
+	/*9342*/ uint16(xMatch),
+	/*9343*/ uint16(xCondIs64), 9346, 9362,
+	/*9346*/ uint16(xCondDataSize), 9350, 9356, 0,
+	/*9350*/ uint16(xSetOp), uint16(CMP),
+	/*9352*/ uint16(xReadIw),
+	/*9353*/ uint16(xArgRM16),
+	/*9354*/ uint16(xArgImm16),
+	/*9355*/ uint16(xMatch),
+	/*9356*/ uint16(xSetOp), uint16(CMP),
+	/*9358*/ uint16(xReadId),
+	/*9359*/ uint16(xArgRM32),
+	/*9360*/ uint16(xArgImm32),
+	/*9361*/ uint16(xMatch),
+	/*9362*/ uint16(xCondDataSize), 9350, 9356, 9366,
+	/*9366*/ uint16(xSetOp), uint16(CMP),
+	/*9368*/ uint16(xReadId),
+	/*9369*/ uint16(xArgRM64),
+	/*9370*/ uint16(xArgImm32),
+	/*9371*/ uint16(xMatch),
+	/*9372*/ uint16(xCondSlashR),
+	9381, // 0
+	9410, // 1
+	9439, // 2
+	9468, // 3
+	9497, // 4
+	9526, // 5
+	9555, // 6
+	9584, // 7
+	/*9381*/ uint16(xCondIs64), 9384, 9400,
+	/*9384*/ uint16(xCondDataSize), 9388, 9394, 0,
+	/*9388*/ uint16(xSetOp), uint16(ADD),
+	/*9390*/ uint16(xReadIb),
+	/*9391*/ uint16(xArgRM16),
+	/*9392*/ uint16(xArgImm8),
+	/*9393*/ uint16(xMatch),
+	/*9394*/ uint16(xSetOp), uint16(ADD),
+	/*9396*/ uint16(xReadIb),
+	/*9397*/ uint16(xArgRM32),
+	/*9398*/ uint16(xArgImm8),
+	/*9399*/ uint16(xMatch),
+	/*9400*/ uint16(xCondDataSize), 9388, 9394, 9404,
+	/*9404*/ uint16(xSetOp), uint16(ADD),
+	/*9406*/ uint16(xReadIb),
+	/*9407*/ uint16(xArgRM64),
+	/*9408*/ uint16(xArgImm8),
+	/*9409*/ uint16(xMatch),
+	/*9410*/ uint16(xCondIs64), 9413, 9429,
+	/*9413*/ uint16(xCondDataSize), 9417, 9423, 0,
+	/*9417*/ uint16(xSetOp), uint16(OR),
+	/*9419*/ uint16(xReadIb),
+	/*9420*/ uint16(xArgRM16),
+	/*9421*/ uint16(xArgImm8),
+	/*9422*/ uint16(xMatch),
+	/*9423*/ uint16(xSetOp), uint16(OR),
+	/*9425*/ uint16(xReadIb),
+	/*9426*/ uint16(xArgRM32),
+	/*9427*/ uint16(xArgImm8),
+	/*9428*/ uint16(xMatch),
+	/*9429*/ uint16(xCondDataSize), 9417, 9423, 9433,
+	/*9433*/ uint16(xSetOp), uint16(OR),
+	/*9435*/ uint16(xReadIb),
+	/*9436*/ uint16(xArgRM64),
+	/*9437*/ uint16(xArgImm8),
+	/*9438*/ uint16(xMatch),
+	/*9439*/ uint16(xCondIs64), 9442, 9458,
+	/*9442*/ uint16(xCondDataSize), 9446, 9452, 0,
+	/*9446*/ uint16(xSetOp), uint16(ADC),
+	/*9448*/ uint16(xReadIb),
+	/*9449*/ uint16(xArgRM16),
+	/*9450*/ uint16(xArgImm8),
+	/*9451*/ uint16(xMatch),
+	/*9452*/ uint16(xSetOp), uint16(ADC),
+	/*9454*/ uint16(xReadIb),
+	/*9455*/ uint16(xArgRM32),
+	/*9456*/ uint16(xArgImm8),
+	/*9457*/ uint16(xMatch),
+	/*9458*/ uint16(xCondDataSize), 9446, 9452, 9462,
+	/*9462*/ uint16(xSetOp), uint16(ADC),
+	/*9464*/ uint16(xReadIb),
+	/*9465*/ uint16(xArgRM64),
+	/*9466*/ uint16(xArgImm8),
+	/*9467*/ uint16(xMatch),
+	/*9468*/ uint16(xCondIs64), 9471, 9487,
+	/*9471*/ uint16(xCondDataSize), 9475, 9481, 0,
+	/*9475*/ uint16(xSetOp), uint16(SBB),
+	/*9477*/ uint16(xReadIb),
+	/*9478*/ uint16(xArgRM16),
+	/*9479*/ uint16(xArgImm8),
+	/*9480*/ uint16(xMatch),
+	/*9481*/ uint16(xSetOp), uint16(SBB),
+	/*9483*/ uint16(xReadIb),
+	/*9484*/ uint16(xArgRM32),
+	/*9485*/ uint16(xArgImm8),
+	/*9486*/ uint16(xMatch),
+	/*9487*/ uint16(xCondDataSize), 9475, 9481, 9491,
+	/*9491*/ uint16(xSetOp), uint16(SBB),
+	/*9493*/ uint16(xReadIb),
+	/*9494*/ uint16(xArgRM64),
+	/*9495*/ uint16(xArgImm8),
+	/*9496*/ uint16(xMatch),
+	/*9497*/ uint16(xCondIs64), 9500, 9516,
+	/*9500*/ uint16(xCondDataSize), 9504, 9510, 0,
+	/*9504*/ uint16(xSetOp), uint16(AND),
+	/*9506*/ uint16(xReadIb),
+	/*9507*/ uint16(xArgRM16),
+	/*9508*/ uint16(xArgImm8),
+	/*9509*/ uint16(xMatch),
+	/*9510*/ uint16(xSetOp), uint16(AND),
+	/*9512*/ uint16(xReadIb),
+	/*9513*/ uint16(xArgRM32),
+	/*9514*/ uint16(xArgImm8),
+	/*9515*/ uint16(xMatch),
+	/*9516*/ uint16(xCondDataSize), 9504, 9510, 9520,
+	/*9520*/ uint16(xSetOp), uint16(AND),
+	/*9522*/ uint16(xReadIb),
+	/*9523*/ uint16(xArgRM64),
+	/*9524*/ uint16(xArgImm8),
+	/*9525*/ uint16(xMatch),
+	/*9526*/ uint16(xCondIs64), 9529, 9545,
+	/*9529*/ uint16(xCondDataSize), 9533, 9539, 0,
+	/*9533*/ uint16(xSetOp), uint16(SUB),
+	/*9535*/ uint16(xReadIb),
+	/*9536*/ uint16(xArgRM16),
+	/*9537*/ uint16(xArgImm8),
+	/*9538*/ uint16(xMatch),
+	/*9539*/ uint16(xSetOp), uint16(SUB),
+	/*9541*/ uint16(xReadIb),
+	/*9542*/ uint16(xArgRM32),
+	/*9543*/ uint16(xArgImm8),
+	/*9544*/ uint16(xMatch),
+	/*9545*/ uint16(xCondDataSize), 9533, 9539, 9549,
+	/*9549*/ uint16(xSetOp), uint16(SUB),
+	/*9551*/ uint16(xReadIb),
+	/*9552*/ uint16(xArgRM64),
+	/*9553*/ uint16(xArgImm8),
+	/*9554*/ uint16(xMatch),
+	/*9555*/ uint16(xCondIs64), 9558, 9574,
+	/*9558*/ uint16(xCondDataSize), 9562, 9568, 0,
+	/*9562*/ uint16(xSetOp), uint16(XOR),
+	/*9564*/ uint16(xReadIb),
+	/*9565*/ uint16(xArgRM16),
+	/*9566*/ uint16(xArgImm8),
+	/*9567*/ uint16(xMatch),
+	/*9568*/ uint16(xSetOp), uint16(XOR),
+	/*9570*/ uint16(xReadIb),
+	/*9571*/ uint16(xArgRM32),
+	/*9572*/ uint16(xArgImm8),
+	/*9573*/ uint16(xMatch),
+	/*9574*/ uint16(xCondDataSize), 9562, 9568, 9578,
+	/*9578*/ uint16(xSetOp), uint16(XOR),
+	/*9580*/ uint16(xReadIb),
+	/*9581*/ uint16(xArgRM64),
+	/*9582*/ uint16(xArgImm8),
+	/*9583*/ uint16(xMatch),
+	/*9584*/ uint16(xCondIs64), 9587, 9603,
+	/*9587*/ uint16(xCondDataSize), 9591, 9597, 0,
+	/*9591*/ uint16(xSetOp), uint16(CMP),
+	/*9593*/ uint16(xReadIb),
+	/*9594*/ uint16(xArgRM16),
+	/*9595*/ uint16(xArgImm8),
+	/*9596*/ uint16(xMatch),
+	/*9597*/ uint16(xSetOp), uint16(CMP),
+	/*9599*/ uint16(xReadIb),
+	/*9600*/ uint16(xArgRM32),
+	/*9601*/ uint16(xArgImm8),
+	/*9602*/ uint16(xMatch),
+	/*9603*/ uint16(xCondDataSize), 9591, 9597, 9607,
+	/*9607*/ uint16(xSetOp), uint16(CMP),
+	/*9609*/ uint16(xReadIb),
+	/*9610*/ uint16(xArgRM64),
+	/*9611*/ uint16(xArgImm8),
+	/*9612*/ uint16(xMatch),
+	/*9613*/ uint16(xSetOp), uint16(TEST),
+	/*9615*/ uint16(xReadSlashR),
+	/*9616*/ uint16(xArgRM8),
+	/*9617*/ uint16(xArgR8),
+	/*9618*/ uint16(xMatch),
+	/*9619*/ uint16(xCondIs64), 9622, 9638,
+	/*9622*/ uint16(xCondDataSize), 9626, 9632, 0,
+	/*9626*/ uint16(xSetOp), uint16(TEST),
+	/*9628*/ uint16(xReadSlashR),
+	/*9629*/ uint16(xArgRM16),
+	/*9630*/ uint16(xArgR16),
+	/*9631*/ uint16(xMatch),
+	/*9632*/ uint16(xSetOp), uint16(TEST),
+	/*9634*/ uint16(xReadSlashR),
+	/*9635*/ uint16(xArgRM32),
+	/*9636*/ uint16(xArgR32),
+	/*9637*/ uint16(xMatch),
+	/*9638*/ uint16(xCondDataSize), 9626, 9632, 9642,
+	/*9642*/ uint16(xSetOp), uint16(TEST),
+	/*9644*/ uint16(xReadSlashR),
+	/*9645*/ uint16(xArgRM64),
+	/*9646*/ uint16(xArgR64),
+	/*9647*/ uint16(xMatch),
+	/*9648*/ uint16(xSetOp), uint16(XCHG),
+	/*9650*/ uint16(xReadSlashR),
+	/*9651*/ uint16(xArgRM8),
+	/*9652*/ uint16(xArgR8),
+	/*9653*/ uint16(xMatch),
+	/*9654*/ uint16(xCondIs64), 9657, 9673,
+	/*9657*/ uint16(xCondDataSize), 9661, 9667, 0,
+	/*9661*/ uint16(xSetOp), uint16(XCHG),
+	/*9663*/ uint16(xReadSlashR),
+	/*9664*/ uint16(xArgRM16),
+	/*9665*/ uint16(xArgR16),
+	/*9666*/ uint16(xMatch),
+	/*9667*/ uint16(xSetOp), uint16(XCHG),
+	/*9669*/ uint16(xReadSlashR),
+	/*9670*/ uint16(xArgRM32),
+	/*9671*/ uint16(xArgR32),
+	/*9672*/ uint16(xMatch),
+	/*9673*/ uint16(xCondDataSize), 9661, 9667, 9677,
+	/*9677*/ uint16(xSetOp), uint16(XCHG),
+	/*9679*/ uint16(xReadSlashR),
+	/*9680*/ uint16(xArgRM64),
+	/*9681*/ uint16(xArgR64),
+	/*9682*/ uint16(xMatch),
+	/*9683*/ uint16(xSetOp), uint16(MOV),
+	/*9685*/ uint16(xReadSlashR),
+	/*9686*/ uint16(xArgRM8),
+	/*9687*/ uint16(xArgR8),
+	/*9688*/ uint16(xMatch),
+	/*9689*/ uint16(xCondDataSize), 9693, 9699, 9705,
+	/*9693*/ uint16(xSetOp), uint16(MOV),
+	/*9695*/ uint16(xReadSlashR),
+	/*9696*/ uint16(xArgRM16),
+	/*9697*/ uint16(xArgR16),
+	/*9698*/ uint16(xMatch),
+	/*9699*/ uint16(xSetOp), uint16(MOV),
+	/*9701*/ uint16(xReadSlashR),
+	/*9702*/ uint16(xArgRM32),
+	/*9703*/ uint16(xArgR32),
+	/*9704*/ uint16(xMatch),
+	/*9705*/ uint16(xSetOp), uint16(MOV),
+	/*9707*/ uint16(xReadSlashR),
+	/*9708*/ uint16(xArgRM64),
+	/*9709*/ uint16(xArgR64),
+	/*9710*/ uint16(xMatch),
+	/*9711*/ uint16(xSetOp), uint16(MOV),
+	/*9713*/ uint16(xReadSlashR),
+	/*9714*/ uint16(xArgR8),
+	/*9715*/ uint16(xArgRM8),
+	/*9716*/ uint16(xMatch),
+	/*9717*/ uint16(xCondDataSize), 9721, 9727, 9733,
+	/*9721*/ uint16(xSetOp), uint16(MOV),
+	/*9723*/ uint16(xReadSlashR),
+	/*9724*/ uint16(xArgR16),
+	/*9725*/ uint16(xArgRM16),
+	/*9726*/ uint16(xMatch),
+	/*9727*/ uint16(xSetOp), uint16(MOV),
+	/*9729*/ uint16(xReadSlashR),
+	/*9730*/ uint16(xArgR32),
+	/*9731*/ uint16(xArgRM32),
+	/*9732*/ uint16(xMatch),
+	/*9733*/ uint16(xSetOp), uint16(MOV),
+	/*9735*/ uint16(xReadSlashR),
+	/*9736*/ uint16(xArgR64),
+	/*9737*/ uint16(xArgRM64),
+	/*9738*/ uint16(xMatch),
+	/*9739*/ uint16(xCondIs64), 9742, 9758,
+	/*9742*/ uint16(xCondDataSize), 9746, 9752, 0,
+	/*9746*/ uint16(xSetOp), uint16(MOV),
+	/*9748*/ uint16(xReadSlashR),
+	/*9749*/ uint16(xArgRM16),
+	/*9750*/ uint16(xArgSreg),
+	/*9751*/ uint16(xMatch),
+	/*9752*/ uint16(xSetOp), uint16(MOV),
+	/*9754*/ uint16(xReadSlashR),
+	/*9755*/ uint16(xArgR32M16),
+	/*9756*/ uint16(xArgSreg),
+	/*9757*/ uint16(xMatch),
+	/*9758*/ uint16(xCondDataSize), 9746, 9752, 9762,
+	/*9762*/ uint16(xSetOp), uint16(MOV),
+	/*9764*/ uint16(xReadSlashR),
+	/*9765*/ uint16(xArgR64M16),
+	/*9766*/ uint16(xArgSreg),
+	/*9767*/ uint16(xMatch),
+	/*9768*/ uint16(xCondIs64), 9771, 9787,
+	/*9771*/ uint16(xCondDataSize), 9775, 9781, 0,
+	/*9775*/ uint16(xSetOp), uint16(LEA),
+	/*9777*/ uint16(xReadSlashR),
+	/*9778*/ uint16(xArgR16),
+	/*9779*/ uint16(xArgM),
+	/*9780*/ uint16(xMatch),
+	/*9781*/ uint16(xSetOp), uint16(LEA),
+	/*9783*/ uint16(xReadSlashR),
+	/*9784*/ uint16(xArgR32),
+	/*9785*/ uint16(xArgM),
+	/*9786*/ uint16(xMatch),
+	/*9787*/ uint16(xCondDataSize), 9775, 9781, 9791,
+	/*9791*/ uint16(xSetOp), uint16(LEA),
+	/*9793*/ uint16(xReadSlashR),
+	/*9794*/ uint16(xArgR64),
+	/*9795*/ uint16(xArgM),
+	/*9796*/ uint16(xMatch),
+	/*9797*/ uint16(xCondIs64), 9800, 9816,
+	/*9800*/ uint16(xCondDataSize), 9804, 9810, 0,
+	/*9804*/ uint16(xSetOp), uint16(MOV),
+	/*9806*/ uint16(xReadSlashR),
+	/*9807*/ uint16(xArgSreg),
+	/*9808*/ uint16(xArgRM16),
+	/*9809*/ uint16(xMatch),
+	/*9810*/ uint16(xSetOp), uint16(MOV),
+	/*9812*/ uint16(xReadSlashR),
+	/*9813*/ uint16(xArgSreg),
+	/*9814*/ uint16(xArgR32M16),
+	/*9815*/ uint16(xMatch),
+	/*9816*/ uint16(xCondDataSize), 9804, 9810, 9820,
+	/*9820*/ uint16(xSetOp), uint16(MOV),
+	/*9822*/ uint16(xReadSlashR),
+	/*9823*/ uint16(xArgSreg),
+	/*9824*/ uint16(xArgR64M16),
+	/*9825*/ uint16(xMatch),
+	/*9826*/ uint16(xCondSlashR),
+	9835, // 0
+	0,    // 1
+	0,    // 2
+	0,    // 3
+	0,    // 4
+	0,    // 5
+	0,    // 6
+	0,    // 7
+	/*9835*/ uint16(xCondIs64), 9838, 9850,
+	/*9838*/ uint16(xCondDataSize), 9842, 9846, 0,
+	/*9842*/ uint16(xSetOp), uint16(POP),
+	/*9844*/ uint16(xArgRM16),
+	/*9845*/ uint16(xMatch),
+	/*9846*/ uint16(xSetOp), uint16(POP),
+	/*9848*/ uint16(xArgRM32),
+	/*9849*/ uint16(xMatch),
+	/*9850*/ uint16(xCondDataSize), 9842, 9854, 9858,
+	/*9854*/ uint16(xSetOp), uint16(POP),
+	/*9856*/ uint16(xArgRM64),
+	/*9857*/ uint16(xMatch),
+	/*9858*/ uint16(xSetOp), uint16(POP),
+	/*9860*/ uint16(xArgRM64),
+	/*9861*/ uint16(xMatch),
+	/*9862*/ uint16(xCondIs64), 9865, 9879,
+	/*9865*/ uint16(xCondDataSize), 9869, 9874, 0,
+	/*9869*/ uint16(xSetOp), uint16(XCHG),
+	/*9871*/ uint16(xArgR16op),
+	/*9872*/ uint16(xArgAX),
+	/*9873*/ uint16(xMatch),
+	/*9874*/ uint16(xSetOp), uint16(XCHG),
+	/*9876*/ uint16(xArgR32op),
+	/*9877*/ uint16(xArgEAX),
+	/*9878*/ uint16(xMatch),
+	/*9879*/ uint16(xCondDataSize), 9869, 9874, 9883,
+	/*9883*/ uint16(xSetOp), uint16(XCHG),
+	/*9885*/ uint16(xArgR64op),
+	/*9886*/ uint16(xArgRAX),
+	/*9887*/ uint16(xMatch),
+	/*9888*/ uint16(xCondIs64), 9891, 9901,
+	/*9891*/ uint16(xCondDataSize), 9895, 9898, 0,
+	/*9895*/ uint16(xSetOp), uint16(CBW),
+	/*9897*/ uint16(xMatch),
+	/*9898*/ uint16(xSetOp), uint16(CWDE),
+	/*9900*/ uint16(xMatch),
+	/*9901*/ uint16(xCondDataSize), 9895, 9898, 9905,
+	/*9905*/ uint16(xSetOp), uint16(CDQE),
+	/*9907*/ uint16(xMatch),
+	/*9908*/ uint16(xCondIs64), 9911, 9921,
+	/*9911*/ uint16(xCondDataSize), 9915, 9918, 0,
+	/*9915*/ uint16(xSetOp), uint16(CWD),
+	/*9917*/ uint16(xMatch),
+	/*9918*/ uint16(xSetOp), uint16(CDQ),
+	/*9920*/ uint16(xMatch),
+	/*9921*/ uint16(xCondDataSize), 9915, 9918, 9925,
+	/*9925*/ uint16(xSetOp), uint16(CQO),
+	/*9927*/ uint16(xMatch),
+	/*9928*/ uint16(xCondIs64), 9931, 0,
+	/*9931*/ uint16(xCondDataSize), 9935, 9940, 0,
+	/*9935*/ uint16(xSetOp), uint16(LCALL),
+	/*9937*/ uint16(xReadCd),
+	/*9938*/ uint16(xArgPtr16colon16),
+	/*9939*/ uint16(xMatch),
+	/*9940*/ uint16(xSetOp), uint16(LCALL),
+	/*9942*/ uint16(xReadCp),
+	/*9943*/ uint16(xArgPtr16colon32),
+	/*9944*/ uint16(xMatch),
+	/*9945*/ uint16(xSetOp), uint16(FWAIT),
+	/*9947*/ uint16(xMatch),
+	/*9948*/ uint16(xCondIs64), 9951, 9961,
+	/*9951*/ uint16(xCondDataSize), 9955, 9958, 0,
+	/*9955*/ uint16(xSetOp), uint16(PUSHF),
+	/*9957*/ uint16(xMatch),
+	/*9958*/ uint16(xSetOp), uint16(PUSHFD),
+	/*9960*/ uint16(xMatch),
+	/*9961*/ uint16(xCondDataSize), 9955, 9965, 9968,
+	/*9965*/ uint16(xSetOp), uint16(PUSHFQ),
+	/*9967*/ uint16(xMatch),
+	/*9968*/ uint16(xSetOp), uint16(PUSHFQ),
+	/*9970*/ uint16(xMatch),
+	/*9971*/ uint16(xCondIs64), 9974, 9984,
+	/*9974*/ uint16(xCondDataSize), 9978, 9981, 0,
+	/*9978*/ uint16(xSetOp), uint16(POPF),
+	/*9980*/ uint16(xMatch),
+	/*9981*/ uint16(xSetOp), uint16(POPFD),
+	/*9983*/ uint16(xMatch),
+	/*9984*/ uint16(xCondDataSize), 9978, 9988, 9991,
+	/*9988*/ uint16(xSetOp), uint16(POPFQ),
+	/*9990*/ uint16(xMatch),
+	/*9991*/ uint16(xSetOp), uint16(POPFQ),
+	/*9993*/ uint16(xMatch),
+	/*9994*/ uint16(xSetOp), uint16(SAHF),
+	/*9996*/ uint16(xMatch),
+	/*9997*/ uint16(xSetOp), uint16(LAHF),
+	/*9999*/ uint16(xMatch),
+	/*10000*/ uint16(xCondIs64), 10003, 10009,
+	/*10003*/ uint16(xSetOp), uint16(MOV),
+	/*10005*/ uint16(xReadCm),
+	/*10006*/ uint16(xArgAL),
+	/*10007*/ uint16(xArgMoffs8),
+	/*10008*/ uint16(xMatch),
+	/*10009*/ uint16(xCondDataSize), 10003, 10003, 10013,
+	/*10013*/ uint16(xSetOp), uint16(MOV),
+	/*10015*/ uint16(xReadCm),
+	/*10016*/ uint16(xArgAL),
+	/*10017*/ uint16(xArgMoffs8),
+	/*10018*/ uint16(xMatch),
+	/*10019*/ uint16(xCondDataSize), 10023, 10029, 10035,
+	/*10023*/ uint16(xSetOp), uint16(MOV),
+	/*10025*/ uint16(xReadCm),
+	/*10026*/ uint16(xArgAX),
+	/*10027*/ uint16(xArgMoffs16),
+	/*10028*/ uint16(xMatch),
+	/*10029*/ uint16(xSetOp), uint16(MOV),
+	/*10031*/ uint16(xReadCm),
+	/*10032*/ uint16(xArgEAX),
+	/*10033*/ uint16(xArgMoffs32),
+	/*10034*/ uint16(xMatch),
+	/*10035*/ uint16(xSetOp), uint16(MOV),
+	/*10037*/ uint16(xReadCm),
+	/*10038*/ uint16(xArgRAX),
+	/*10039*/ uint16(xArgMoffs64),
+	/*10040*/ uint16(xMatch),
+	/*10041*/ uint16(xCondIs64), 10044, 10050,
+	/*10044*/ uint16(xSetOp), uint16(MOV),
+	/*10046*/ uint16(xReadCm),
+	/*10047*/ uint16(xArgMoffs8),
+	/*10048*/ uint16(xArgAL),
+	/*10049*/ uint16(xMatch),
+	/*10050*/ uint16(xCondDataSize), 10044, 10044, 10054,
+	/*10054*/ uint16(xSetOp), uint16(MOV),
+	/*10056*/ uint16(xReadCm),
+	/*10057*/ uint16(xArgMoffs8),
+	/*10058*/ uint16(xArgAL),
+	/*10059*/ uint16(xMatch),
+	/*10060*/ uint16(xCondDataSize), 10064, 10070, 10076,
+	/*10064*/ uint16(xSetOp), uint16(MOV),
+	/*10066*/ uint16(xReadCm),
+	/*10067*/ uint16(xArgMoffs16),
+	/*10068*/ uint16(xArgAX),
+	/*10069*/ uint16(xMatch),
+	/*10070*/ uint16(xSetOp), uint16(MOV),
+	/*10072*/ uint16(xReadCm),
+	/*10073*/ uint16(xArgMoffs32),
+	/*10074*/ uint16(xArgEAX),
+	/*10075*/ uint16(xMatch),
+	/*10076*/ uint16(xSetOp), uint16(MOV),
+	/*10078*/ uint16(xReadCm),
+	/*10079*/ uint16(xArgMoffs64),
+	/*10080*/ uint16(xArgRAX),
+	/*10081*/ uint16(xMatch),
+	/*10082*/ uint16(xSetOp), uint16(MOVSB),
+	/*10084*/ uint16(xMatch),
+	/*10085*/ uint16(xCondIs64), 10088, 10098,
+	/*10088*/ uint16(xCondDataSize), 10092, 10095, 0,
+	/*10092*/ uint16(xSetOp), uint16(MOVSW),
+	/*10094*/ uint16(xMatch),
+	/*10095*/ uint16(xSetOp), uint16(MOVSD),
+	/*10097*/ uint16(xMatch),
+	/*10098*/ uint16(xCondDataSize), 10092, 10095, 10102,
+	/*10102*/ uint16(xSetOp), uint16(MOVSQ),
+	/*10104*/ uint16(xMatch),
+	/*10105*/ uint16(xSetOp), uint16(CMPSB),
+	/*10107*/ uint16(xMatch),
+	/*10108*/ uint16(xCondIs64), 10111, 10121,
+	/*10111*/ uint16(xCondDataSize), 10115, 10118, 0,
+	/*10115*/ uint16(xSetOp), uint16(CMPSW),
+	/*10117*/ uint16(xMatch),
+	/*10118*/ uint16(xSetOp), uint16(CMPSD),
+	/*10120*/ uint16(xMatch),
+	/*10121*/ uint16(xCondDataSize), 10115, 10118, 10125,
+	/*10125*/ uint16(xSetOp), uint16(CMPSQ),
+	/*10127*/ uint16(xMatch),
+	/*10128*/ uint16(xSetOp), uint16(TEST),
+	/*10130*/ uint16(xReadIb),
+	/*10131*/ uint16(xArgAL),
+	/*10132*/ uint16(xArgImm8u),
+	/*10133*/ uint16(xMatch),
+	/*10134*/ uint16(xCondIs64), 10137, 10153,
+	/*10137*/ uint16(xCondDataSize), 10141, 10147, 0,
+	/*10141*/ uint16(xSetOp), uint16(TEST),
+	/*10143*/ uint16(xReadIw),
+	/*10144*/ uint16(xArgAX),
+	/*10145*/ uint16(xArgImm16),
+	/*10146*/ uint16(xMatch),
+	/*10147*/ uint16(xSetOp), uint16(TEST),
+	/*10149*/ uint16(xReadId),
+	/*10150*/ uint16(xArgEAX),
+	/*10151*/ uint16(xArgImm32),
+	/*10152*/ uint16(xMatch),
+	/*10153*/ uint16(xCondDataSize), 10141, 10147, 10157,
+	/*10157*/ uint16(xSetOp), uint16(TEST),
+	/*10159*/ uint16(xReadId),
+	/*10160*/ uint16(xArgRAX),
+	/*10161*/ uint16(xArgImm32),
+	/*10162*/ uint16(xMatch),
+	/*10163*/ uint16(xSetOp), uint16(STOSB),
+	/*10165*/ uint16(xMatch),
+	/*10166*/ uint16(xCondIs64), 10169, 10179,
+	/*10169*/ uint16(xCondDataSize), 10173, 10176, 0,
+	/*10173*/ uint16(xSetOp), uint16(STOSW),
+	/*10175*/ uint16(xMatch),
+	/*10176*/ uint16(xSetOp), uint16(STOSD),
+	/*10178*/ uint16(xMatch),
+	/*10179*/ uint16(xCondDataSize), 10173, 10176, 10183,
+	/*10183*/ uint16(xSetOp), uint16(STOSQ),
+	/*10185*/ uint16(xMatch),
+	/*10186*/ uint16(xSetOp), uint16(LODSB),
+	/*10188*/ uint16(xMatch),
+	/*10189*/ uint16(xCondIs64), 10192, 10202,
+	/*10192*/ uint16(xCondDataSize), 10196, 10199, 0,
+	/*10196*/ uint16(xSetOp), uint16(LODSW),
+	/*10198*/ uint16(xMatch),
+	/*10199*/ uint16(xSetOp), uint16(LODSD),
+	/*10201*/ uint16(xMatch),
+	/*10202*/ uint16(xCondDataSize), 10196, 10199, 10206,
+	/*10206*/ uint16(xSetOp), uint16(LODSQ),
+	/*10208*/ uint16(xMatch),
+	/*10209*/ uint16(xSetOp), uint16(SCASB),
+	/*10211*/ uint16(xMatch),
+	/*10212*/ uint16(xCondIs64), 10215, 10225,
+	/*10215*/ uint16(xCondDataSize), 10219, 10222, 0,
+	/*10219*/ uint16(xSetOp), uint16(SCASW),
+	/*10221*/ uint16(xMatch),
+	/*10222*/ uint16(xSetOp), uint16(SCASD),
+	/*10224*/ uint16(xMatch),
+	/*10225*/ uint16(xCondDataSize), 10219, 10222, 10229,
+	/*10229*/ uint16(xSetOp), uint16(SCASQ),
+	/*10231*/ uint16(xMatch),
+	/*10232*/ uint16(xSetOp), uint16(MOV),
+	/*10234*/ uint16(xReadIb),
+	/*10235*/ uint16(xArgR8op),
+	/*10236*/ uint16(xArgImm8u),
+	/*10237*/ uint16(xMatch),
+	/*10238*/ uint16(xCondIs64), 10241, 10257,
+	/*10241*/ uint16(xCondDataSize), 10245, 10251, 0,
+	/*10245*/ uint16(xSetOp), uint16(MOV),
+	/*10247*/ uint16(xReadIw),
+	/*10248*/ uint16(xArgR16op),
+	/*10249*/ uint16(xArgImm16),
+	/*10250*/ uint16(xMatch),
+	/*10251*/ uint16(xSetOp), uint16(MOV),
+	/*10253*/ uint16(xReadId),
+	/*10254*/ uint16(xArgR32op),
+	/*10255*/ uint16(xArgImm32),
+	/*10256*/ uint16(xMatch),
+	/*10257*/ uint16(xCondDataSize), 10245, 10251, 10261,
+	/*10261*/ uint16(xSetOp), uint16(MOV),
+	/*10263*/ uint16(xReadIo),
+	/*10264*/ uint16(xArgR64op),
+	/*10265*/ uint16(xArgImm64),
+	/*10266*/ uint16(xMatch),
+	/*10267*/ uint16(xCondSlashR),
+	10276, // 0
+	10282, // 1
+	10288, // 2
+	10294, // 3
+	10300, // 4
+	10306, // 5
+	0,     // 6
+	10312, // 7
+	/*10276*/ uint16(xSetOp), uint16(ROL),
+	/*10278*/ uint16(xReadIb),
+	/*10279*/ uint16(xArgRM8),
+	/*10280*/ uint16(xArgImm8u),
+	/*10281*/ uint16(xMatch),
+	/*10282*/ uint16(xSetOp), uint16(ROR),
+	/*10284*/ uint16(xReadIb),
+	/*10285*/ uint16(xArgRM8),
+	/*10286*/ uint16(xArgImm8u),
+	/*10287*/ uint16(xMatch),
+	/*10288*/ uint16(xSetOp), uint16(RCL),
+	/*10290*/ uint16(xReadIb),
+	/*10291*/ uint16(xArgRM8),
+	/*10292*/ uint16(xArgImm8u),
+	/*10293*/ uint16(xMatch),
+	/*10294*/ uint16(xSetOp), uint16(RCR),
+	/*10296*/ uint16(xReadIb),
+	/*10297*/ uint16(xArgRM8),
+	/*10298*/ uint16(xArgImm8u),
+	/*10299*/ uint16(xMatch),
+	/*10300*/ uint16(xSetOp), uint16(SHL),
+	/*10302*/ uint16(xReadIb),
+	/*10303*/ uint16(xArgRM8),
+	/*10304*/ uint16(xArgImm8u),
+	/*10305*/ uint16(xMatch),
+	/*10306*/ uint16(xSetOp), uint16(SHR),
+	/*10308*/ uint16(xReadIb),
+	/*10309*/ uint16(xArgRM8),
+	/*10310*/ uint16(xArgImm8u),
+	/*10311*/ uint16(xMatch),
+	/*10312*/ uint16(xSetOp), uint16(SAR),
+	/*10314*/ uint16(xReadIb),
+	/*10315*/ uint16(xArgRM8),
+	/*10316*/ uint16(xArgImm8u),
+	/*10317*/ uint16(xMatch),
+	/*10318*/ uint16(xCondSlashR),
+	10327, // 0
+	10349, // 1
+	10371, // 2
+	10400, // 3
+	10429, // 4
+	10458, // 5
+	0,     // 6
+	10487, // 7
+	/*10327*/ uint16(xCondDataSize), 10331, 10337, 10343,
+	/*10331*/ uint16(xSetOp), uint16(ROL),
+	/*10333*/ uint16(xReadIb),
+	/*10334*/ uint16(xArgRM16),
+	/*10335*/ uint16(xArgImm8u),
+	/*10336*/ uint16(xMatch),
+	/*10337*/ uint16(xSetOp), uint16(ROL),
+	/*10339*/ uint16(xReadIb),
+	/*10340*/ uint16(xArgRM32),
+	/*10341*/ uint16(xArgImm8u),
+	/*10342*/ uint16(xMatch),
+	/*10343*/ uint16(xSetOp), uint16(ROL),
+	/*10345*/ uint16(xReadIb),
+	/*10346*/ uint16(xArgRM64),
+	/*10347*/ uint16(xArgImm8u),
+	/*10348*/ uint16(xMatch),
+	/*10349*/ uint16(xCondDataSize), 10353, 10359, 10365,
+	/*10353*/ uint16(xSetOp), uint16(ROR),
+	/*10355*/ uint16(xReadIb),
+	/*10356*/ uint16(xArgRM16),
+	/*10357*/ uint16(xArgImm8u),
+	/*10358*/ uint16(xMatch),
+	/*10359*/ uint16(xSetOp), uint16(ROR),
+	/*10361*/ uint16(xReadIb),
+	/*10362*/ uint16(xArgRM32),
+	/*10363*/ uint16(xArgImm8u),
+	/*10364*/ uint16(xMatch),
+	/*10365*/ uint16(xSetOp), uint16(ROR),
+	/*10367*/ uint16(xReadIb),
+	/*10368*/ uint16(xArgRM64),
+	/*10369*/ uint16(xArgImm8u),
+	/*10370*/ uint16(xMatch),
+	/*10371*/ uint16(xCondIs64), 10374, 10390,
+	/*10374*/ uint16(xCondDataSize), 10378, 10384, 0,
+	/*10378*/ uint16(xSetOp), uint16(RCL),
+	/*10380*/ uint16(xReadIb),
+	/*10381*/ uint16(xArgRM16),
+	/*10382*/ uint16(xArgImm8u),
+	/*10383*/ uint16(xMatch),
+	/*10384*/ uint16(xSetOp), uint16(RCL),
+	/*10386*/ uint16(xReadIb),
+	/*10387*/ uint16(xArgRM32),
+	/*10388*/ uint16(xArgImm8u),
+	/*10389*/ uint16(xMatch),
+	/*10390*/ uint16(xCondDataSize), 10378, 10384, 10394,
+	/*10394*/ uint16(xSetOp), uint16(RCL),
+	/*10396*/ uint16(xReadIb),
+	/*10397*/ uint16(xArgRM64),
+	/*10398*/ uint16(xArgImm8u),
+	/*10399*/ uint16(xMatch),
+	/*10400*/ uint16(xCondIs64), 10403, 10419,
+	/*10403*/ uint16(xCondDataSize), 10407, 10413, 0,
+	/*10407*/ uint16(xSetOp), uint16(RCR),
+	/*10409*/ uint16(xReadIb),
+	/*10410*/ uint16(xArgRM16),
+	/*10411*/ uint16(xArgImm8u),
+	/*10412*/ uint16(xMatch),
+	/*10413*/ uint16(xSetOp), uint16(RCR),
+	/*10415*/ uint16(xReadIb),
+	/*10416*/ uint16(xArgRM32),
+	/*10417*/ uint16(xArgImm8u),
+	/*10418*/ uint16(xMatch),
+	/*10419*/ uint16(xCondDataSize), 10407, 10413, 10423,
+	/*10423*/ uint16(xSetOp), uint16(RCR),
+	/*10425*/ uint16(xReadIb),
+	/*10426*/ uint16(xArgRM64),
+	/*10427*/ uint16(xArgImm8u),
+	/*10428*/ uint16(xMatch),
+	/*10429*/ uint16(xCondIs64), 10432, 10448,
+	/*10432*/ uint16(xCondDataSize), 10436, 10442, 0,
+	/*10436*/ uint16(xSetOp), uint16(SHL),
+	/*10438*/ uint16(xReadIb),
+	/*10439*/ uint16(xArgRM16),
+	/*10440*/ uint16(xArgImm8u),
+	/*10441*/ uint16(xMatch),
+	/*10442*/ uint16(xSetOp), uint16(SHL),
+	/*10444*/ uint16(xReadIb),
+	/*10445*/ uint16(xArgRM32),
+	/*10446*/ uint16(xArgImm8u),
+	/*10447*/ uint16(xMatch),
+	/*10448*/ uint16(xCondDataSize), 10436, 10442, 10452,
+	/*10452*/ uint16(xSetOp), uint16(SHL),
+	/*10454*/ uint16(xReadIb),
+	/*10455*/ uint16(xArgRM64),
+	/*10456*/ uint16(xArgImm8u),
+	/*10457*/ uint16(xMatch),
+	/*10458*/ uint16(xCondIs64), 10461, 10477,
+	/*10461*/ uint16(xCondDataSize), 10465, 10471, 0,
+	/*10465*/ uint16(xSetOp), uint16(SHR),
+	/*10467*/ uint16(xReadIb),
+	/*10468*/ uint16(xArgRM16),
+	/*10469*/ uint16(xArgImm8u),
+	/*10470*/ uint16(xMatch),
+	/*10471*/ uint16(xSetOp), uint16(SHR),
+	/*10473*/ uint16(xReadIb),
+	/*10474*/ uint16(xArgRM32),
+	/*10475*/ uint16(xArgImm8u),
+	/*10476*/ uint16(xMatch),
+	/*10477*/ uint16(xCondDataSize), 10465, 10471, 10481,
+	/*10481*/ uint16(xSetOp), uint16(SHR),
+	/*10483*/ uint16(xReadIb),
+	/*10484*/ uint16(xArgRM64),
+	/*10485*/ uint16(xArgImm8u),
+	/*10486*/ uint16(xMatch),
+	/*10487*/ uint16(xCondIs64), 10490, 10506,
+	/*10490*/ uint16(xCondDataSize), 10494, 10500, 0,
+	/*10494*/ uint16(xSetOp), uint16(SAR),
+	/*10496*/ uint16(xReadIb),
+	/*10497*/ uint16(xArgRM16),
+	/*10498*/ uint16(xArgImm8u),
+	/*10499*/ uint16(xMatch),
+	/*10500*/ uint16(xSetOp), uint16(SAR),
+	/*10502*/ uint16(xReadIb),
+	/*10503*/ uint16(xArgRM32),
+	/*10504*/ uint16(xArgImm8u),
+	/*10505*/ uint16(xMatch),
+	/*10506*/ uint16(xCondDataSize), 10494, 10500, 10510,
+	/*10510*/ uint16(xSetOp), uint16(SAR),
+	/*10512*/ uint16(xReadIb),
+	/*10513*/ uint16(xArgRM64),
+	/*10514*/ uint16(xArgImm8u),
+	/*10515*/ uint16(xMatch),
+	/*10516*/ uint16(xSetOp), uint16(RET),
+	/*10518*/ uint16(xReadIw),
+	/*10519*/ uint16(xArgImm16u),
+	/*10520*/ uint16(xMatch),
+	/*10521*/ uint16(xSetOp), uint16(RET),
+	/*10523*/ uint16(xMatch),
+	/*10524*/ uint16(xCondIs64), 10527, 0,
+	/*10527*/ uint16(xCondDataSize), 10531, 10537, 0,
+	/*10531*/ uint16(xSetOp), uint16(LES),
+	/*10533*/ uint16(xReadSlashR),
+	/*10534*/ uint16(xArgR16),
+	/*10535*/ uint16(xArgM16colon16),
+	/*10536*/ uint16(xMatch),
+	/*10537*/ uint16(xSetOp), uint16(LES),
+	/*10539*/ uint16(xReadSlashR),
+	/*10540*/ uint16(xArgR32),
+	/*10541*/ uint16(xArgM16colon32),
+	/*10542*/ uint16(xMatch),
+	/*10543*/ uint16(xCondIs64), 10546, 0,
+	/*10546*/ uint16(xCondDataSize), 10550, 10556, 0,
+	/*10550*/ uint16(xSetOp), uint16(LDS),
+	/*10552*/ uint16(xReadSlashR),
+	/*10553*/ uint16(xArgR16),
+	/*10554*/ uint16(xArgM16colon16),
+	/*10555*/ uint16(xMatch),
+	/*10556*/ uint16(xSetOp), uint16(LDS),
+	/*10558*/ uint16(xReadSlashR),
+	/*10559*/ uint16(xArgR32),
+	/*10560*/ uint16(xArgM16colon32),
+	/*10561*/ uint16(xMatch),
+	/*10562*/ uint16(xCondByte), 1,
+	0xF8, 10581,
+	/*10566*/ uint16(xCondSlashR),
+	10575, // 0
+	0,     // 1
+	0,     // 2
+	0,     // 3
+	0,     // 4
+	0,     // 5
+	0,     // 6
+	0,     // 7
+	/*10575*/ uint16(xSetOp), uint16(MOV),
+	/*10577*/ uint16(xReadIb),
+	/*10578*/ uint16(xArgRM8),
+	/*10579*/ uint16(xArgImm8u),
+	/*10580*/ uint16(xMatch),
+	/*10581*/ uint16(xSetOp), uint16(XABORT),
+	/*10583*/ uint16(xReadIb),
+	/*10584*/ uint16(xArgImm8u),
+	/*10585*/ uint16(xMatch),
+	/*10586*/ uint16(xCondByte), 1,
+	0xF8, 10628,
+	/*10590*/ uint16(xCondSlashR),
+	10599, // 0
+	0,     // 1
+	0,     // 2
+	0,     // 3
+	0,     // 4
+	0,     // 5
+	0,     // 6
+	0,     // 7
+	/*10599*/ uint16(xCondIs64), 10602, 10618,
+	/*10602*/ uint16(xCondDataSize), 10606, 10612, 0,
+	/*10606*/ uint16(xSetOp), uint16(MOV),
+	/*10608*/ uint16(xReadIw),
+	/*10609*/ uint16(xArgRM16),
+	/*10610*/ uint16(xArgImm16),
+	/*10611*/ uint16(xMatch),
+	/*10612*/ uint16(xSetOp), uint16(MOV),
+	/*10614*/ uint16(xReadId),
+	/*10615*/ uint16(xArgRM32),
+	/*10616*/ uint16(xArgImm32),
+	/*10617*/ uint16(xMatch),
+	/*10618*/ uint16(xCondDataSize), 10606, 10612, 10622,
+	/*10622*/ uint16(xSetOp), uint16(MOV),
+	/*10624*/ uint16(xReadId),
+	/*10625*/ uint16(xArgRM64),
+	/*10626*/ uint16(xArgImm32),
+	/*10627*/ uint16(xMatch),
+	/*10628*/ uint16(xCondDataSize), 10632, 10637, 10642,
+	/*10632*/ uint16(xSetOp), uint16(XBEGIN),
+	/*10634*/ uint16(xReadCw),
+	/*10635*/ uint16(xArgRel16),
+	/*10636*/ uint16(xMatch),
+	/*10637*/ uint16(xSetOp), uint16(XBEGIN),
+	/*10639*/ uint16(xReadCd),
+	/*10640*/ uint16(xArgRel32),
+	/*10641*/ uint16(xMatch),
+	/*10642*/ uint16(xSetOp), uint16(XBEGIN),
+	/*10644*/ uint16(xReadCd),
+	/*10645*/ uint16(xArgRel32),
+	/*10646*/ uint16(xMatch),
+	/*10647*/ uint16(xSetOp), uint16(ENTER),
+	/*10649*/ uint16(xReadIw),
+	/*10650*/ uint16(xReadIb),
+	/*10651*/ uint16(xArgImm16u),
+	/*10652*/ uint16(xArgImm8u),
+	/*10653*/ uint16(xMatch),
+	/*10654*/ uint16(xCondIs64), 10657, 10667,
+	/*10657*/ uint16(xCondDataSize), 10661, 10664, 0,
+	/*10661*/ uint16(xSetOp), uint16(LEAVE),
+	/*10663*/ uint16(xMatch),
+	/*10664*/ uint16(xSetOp), uint16(LEAVE),
+	/*10666*/ uint16(xMatch),
+	/*10667*/ uint16(xCondDataSize), 10661, 10671, 10674,
+	/*10671*/ uint16(xSetOp), uint16(LEAVE),
+	/*10673*/ uint16(xMatch),
+	/*10674*/ uint16(xSetOp), uint16(LEAVE),
+	/*10676*/ uint16(xMatch),
+	/*10677*/ uint16(xSetOp), uint16(LRET),
+	/*10679*/ uint16(xReadIw),
+	/*10680*/ uint16(xArgImm16u),
+	/*10681*/ uint16(xMatch),
+	/*10682*/ uint16(xSetOp), uint16(LRET),
+	/*10684*/ uint16(xMatch),
+	/*10685*/ uint16(xSetOp), uint16(INT),
+	/*10687*/ uint16(xArg3),
+	/*10688*/ uint16(xMatch),
+	/*10689*/ uint16(xSetOp), uint16(INT),
+	/*10691*/ uint16(xReadIb),
+	/*10692*/ uint16(xArgImm8u),
+	/*10693*/ uint16(xMatch),
+	/*10694*/ uint16(xCondIs64), 10697, 0,
+	/*10697*/ uint16(xSetOp), uint16(INTO),
+	/*10699*/ uint16(xMatch),
+	/*10700*/ uint16(xCondIs64), 10703, 10713,
+	/*10703*/ uint16(xCondDataSize), 10707, 10710, 0,
+	/*10707*/ uint16(xSetOp), uint16(IRET),
+	/*10709*/ uint16(xMatch),
+	/*10710*/ uint16(xSetOp), uint16(IRETD),
+	/*10712*/ uint16(xMatch),
+	/*10713*/ uint16(xCondDataSize), 10707, 10710, 10717,
+	/*10717*/ uint16(xSetOp), uint16(IRETQ),
+	/*10719*/ uint16(xMatch),
+	/*10720*/ uint16(xCondSlashR),
+	10729, // 0
+	10734, // 1
+	10739, // 2
+	10744, // 3
+	10749, // 4
+	10754, // 5
+	0,     // 6
+	10759, // 7
+	/*10729*/ uint16(xSetOp), uint16(ROL),
+	/*10731*/ uint16(xArgRM8),
+	/*10732*/ uint16(xArg1),
+	/*10733*/ uint16(xMatch),
+	/*10734*/ uint16(xSetOp), uint16(ROR),
+	/*10736*/ uint16(xArgRM8),
+	/*10737*/ uint16(xArg1),
+	/*10738*/ uint16(xMatch),
+	/*10739*/ uint16(xSetOp), uint16(RCL),
+	/*10741*/ uint16(xArgRM8),
+	/*10742*/ uint16(xArg1),
+	/*10743*/ uint16(xMatch),
+	/*10744*/ uint16(xSetOp), uint16(RCR),
+	/*10746*/ uint16(xArgRM8),
+	/*10747*/ uint16(xArg1),
+	/*10748*/ uint16(xMatch),
+	/*10749*/ uint16(xSetOp), uint16(SHL),
+	/*10751*/ uint16(xArgRM8),
+	/*10752*/ uint16(xArg1),
+	/*10753*/ uint16(xMatch),
+	/*10754*/ uint16(xSetOp), uint16(SHR),
+	/*10756*/ uint16(xArgRM8),
+	/*10757*/ uint16(xArg1),
+	/*10758*/ uint16(xMatch),
+	/*10759*/ uint16(xSetOp), uint16(SAR),
+	/*10761*/ uint16(xArgRM8),
+	/*10762*/ uint16(xArg1),
+	/*10763*/ uint16(xMatch),
+	/*10764*/ uint16(xCondSlashR),
+	10773, // 0
+	10799, // 1
+	10825, // 2
+	10851, // 3
+	10877, // 4
+	10903, // 5
+	0,     // 6
+	10929, // 7
+	/*10773*/ uint16(xCondIs64), 10776, 10790,
+	/*10776*/ uint16(xCondDataSize), 10780, 10785, 0,
+	/*10780*/ uint16(xSetOp), uint16(ROL),
+	/*10782*/ uint16(xArgRM16),
+	/*10783*/ uint16(xArg1),
+	/*10784*/ uint16(xMatch),
+	/*10785*/ uint16(xSetOp), uint16(ROL),
+	/*10787*/ uint16(xArgRM32),
+	/*10788*/ uint16(xArg1),
+	/*10789*/ uint16(xMatch),
+	/*10790*/ uint16(xCondDataSize), 10780, 10785, 10794,
+	/*10794*/ uint16(xSetOp), uint16(ROL),
+	/*10796*/ uint16(xArgRM64),
+	/*10797*/ uint16(xArg1),
+	/*10798*/ uint16(xMatch),
+	/*10799*/ uint16(xCondIs64), 10802, 10816,
+	/*10802*/ uint16(xCondDataSize), 10806, 10811, 0,
+	/*10806*/ uint16(xSetOp), uint16(ROR),
+	/*10808*/ uint16(xArgRM16),
+	/*10809*/ uint16(xArg1),
+	/*10810*/ uint16(xMatch),
+	/*10811*/ uint16(xSetOp), uint16(ROR),
+	/*10813*/ uint16(xArgRM32),
+	/*10814*/ uint16(xArg1),
+	/*10815*/ uint16(xMatch),
+	/*10816*/ uint16(xCondDataSize), 10806, 10811, 10820,
+	/*10820*/ uint16(xSetOp), uint16(ROR),
+	/*10822*/ uint16(xArgRM64),
+	/*10823*/ uint16(xArg1),
+	/*10824*/ uint16(xMatch),
+	/*10825*/ uint16(xCondIs64), 10828, 10842,
+	/*10828*/ uint16(xCondDataSize), 10832, 10837, 0,
+	/*10832*/ uint16(xSetOp), uint16(RCL),
+	/*10834*/ uint16(xArgRM16),
+	/*10835*/ uint16(xArg1),
+	/*10836*/ uint16(xMatch),
+	/*10837*/ uint16(xSetOp), uint16(RCL),
+	/*10839*/ uint16(xArgRM32),
+	/*10840*/ uint16(xArg1),
+	/*10841*/ uint16(xMatch),
+	/*10842*/ uint16(xCondDataSize), 10832, 10837, 10846,
+	/*10846*/ uint16(xSetOp), uint16(RCL),
+	/*10848*/ uint16(xArgRM64),
+	/*10849*/ uint16(xArg1),
+	/*10850*/ uint16(xMatch),
+	/*10851*/ uint16(xCondIs64), 10854, 10868,
+	/*10854*/ uint16(xCondDataSize), 10858, 10863, 0,
+	/*10858*/ uint16(xSetOp), uint16(RCR),
+	/*10860*/ uint16(xArgRM16),
+	/*10861*/ uint16(xArg1),
+	/*10862*/ uint16(xMatch),
+	/*10863*/ uint16(xSetOp), uint16(RCR),
+	/*10865*/ uint16(xArgRM32),
+	/*10866*/ uint16(xArg1),
+	/*10867*/ uint16(xMatch),
+	/*10868*/ uint16(xCondDataSize), 10858, 10863, 10872,
+	/*10872*/ uint16(xSetOp), uint16(RCR),
+	/*10874*/ uint16(xArgRM64),
+	/*10875*/ uint16(xArg1),
+	/*10876*/ uint16(xMatch),
+	/*10877*/ uint16(xCondIs64), 10880, 10894,
+	/*10880*/ uint16(xCondDataSize), 10884, 10889, 0,
+	/*10884*/ uint16(xSetOp), uint16(SHL),
+	/*10886*/ uint16(xArgRM16),
+	/*10887*/ uint16(xArg1),
+	/*10888*/ uint16(xMatch),
+	/*10889*/ uint16(xSetOp), uint16(SHL),
+	/*10891*/ uint16(xArgRM32),
+	/*10892*/ uint16(xArg1),
+	/*10893*/ uint16(xMatch),
+	/*10894*/ uint16(xCondDataSize), 10884, 10889, 10898,
+	/*10898*/ uint16(xSetOp), uint16(SHL),
+	/*10900*/ uint16(xArgRM64),
+	/*10901*/ uint16(xArg1),
+	/*10902*/ uint16(xMatch),
+	/*10903*/ uint16(xCondIs64), 10906, 10920,
+	/*10906*/ uint16(xCondDataSize), 10910, 10915, 0,
+	/*10910*/ uint16(xSetOp), uint16(SHR),
+	/*10912*/ uint16(xArgRM16),
+	/*10913*/ uint16(xArg1),
+	/*10914*/ uint16(xMatch),
+	/*10915*/ uint16(xSetOp), uint16(SHR),
+	/*10917*/ uint16(xArgRM32),
+	/*10918*/ uint16(xArg1),
+	/*10919*/ uint16(xMatch),
+	/*10920*/ uint16(xCondDataSize), 10910, 10915, 10924,
+	/*10924*/ uint16(xSetOp), uint16(SHR),
+	/*10926*/ uint16(xArgRM64),
+	/*10927*/ uint16(xArg1),
+	/*10928*/ uint16(xMatch),
+	/*10929*/ uint16(xCondIs64), 10932, 10946,
+	/*10932*/ uint16(xCondDataSize), 10936, 10941, 0,
+	/*10936*/ uint16(xSetOp), uint16(SAR),
+	/*10938*/ uint16(xArgRM16),
+	/*10939*/ uint16(xArg1),
+	/*10940*/ uint16(xMatch),
+	/*10941*/ uint16(xSetOp), uint16(SAR),
+	/*10943*/ uint16(xArgRM32),
+	/*10944*/ uint16(xArg1),
+	/*10945*/ uint16(xMatch),
+	/*10946*/ uint16(xCondDataSize), 10936, 10941, 10950,
+	/*10950*/ uint16(xSetOp), uint16(SAR),
+	/*10952*/ uint16(xArgRM64),
+	/*10953*/ uint16(xArg1),
+	/*10954*/ uint16(xMatch),
+	/*10955*/ uint16(xCondSlashR),
+	10964, // 0
+	10969, // 1
+	10974, // 2
+	10979, // 3
+	10984, // 4
+	10989, // 5
+	0,     // 6
+	10994, // 7
+	/*10964*/ uint16(xSetOp), uint16(ROL),
+	/*10966*/ uint16(xArgRM8),
+	/*10967*/ uint16(xArgCL),
+	/*10968*/ uint16(xMatch),
+	/*10969*/ uint16(xSetOp), uint16(ROR),
+	/*10971*/ uint16(xArgRM8),
+	/*10972*/ uint16(xArgCL),
+	/*10973*/ uint16(xMatch),
+	/*10974*/ uint16(xSetOp), uint16(RCL),
+	/*10976*/ uint16(xArgRM8),
+	/*10977*/ uint16(xArgCL),
+	/*10978*/ uint16(xMatch),
+	/*10979*/ uint16(xSetOp), uint16(RCR),
+	/*10981*/ uint16(xArgRM8),
+	/*10982*/ uint16(xArgCL),
+	/*10983*/ uint16(xMatch),
+	/*10984*/ uint16(xSetOp), uint16(SHL),
+	/*10986*/ uint16(xArgRM8),
+	/*10987*/ uint16(xArgCL),
+	/*10988*/ uint16(xMatch),
+	/*10989*/ uint16(xSetOp), uint16(SHR),
+	/*10991*/ uint16(xArgRM8),
+	/*10992*/ uint16(xArgCL),
+	/*10993*/ uint16(xMatch),
+	/*10994*/ uint16(xSetOp), uint16(SAR),
+	/*10996*/ uint16(xArgRM8),
+	/*10997*/ uint16(xArgCL),
+	/*10998*/ uint16(xMatch),
+	/*10999*/ uint16(xCondSlashR),
+	11008, // 0
+	11034, // 1
+	11060, // 2
+	11086, // 3
+	11112, // 4
+	11138, // 5
+	0,     // 6
+	11164, // 7
+	/*11008*/ uint16(xCondIs64), 11011, 11025,
+	/*11011*/ uint16(xCondDataSize), 11015, 11020, 0,
+	/*11015*/ uint16(xSetOp), uint16(ROL),
+	/*11017*/ uint16(xArgRM16),
+	/*11018*/ uint16(xArgCL),
+	/*11019*/ uint16(xMatch),
+	/*11020*/ uint16(xSetOp), uint16(ROL),
+	/*11022*/ uint16(xArgRM32),
+	/*11023*/ uint16(xArgCL),
+	/*11024*/ uint16(xMatch),
+	/*11025*/ uint16(xCondDataSize), 11015, 11020, 11029,
+	/*11029*/ uint16(xSetOp), uint16(ROL),
+	/*11031*/ uint16(xArgRM64),
+	/*11032*/ uint16(xArgCL),
+	/*11033*/ uint16(xMatch),
+	/*11034*/ uint16(xCondIs64), 11037, 11051,
+	/*11037*/ uint16(xCondDataSize), 11041, 11046, 0,
+	/*11041*/ uint16(xSetOp), uint16(ROR),
+	/*11043*/ uint16(xArgRM16),
+	/*11044*/ uint16(xArgCL),
+	/*11045*/ uint16(xMatch),
+	/*11046*/ uint16(xSetOp), uint16(ROR),
+	/*11048*/ uint16(xArgRM32),
+	/*11049*/ uint16(xArgCL),
+	/*11050*/ uint16(xMatch),
+	/*11051*/ uint16(xCondDataSize), 11041, 11046, 11055,
+	/*11055*/ uint16(xSetOp), uint16(ROR),
+	/*11057*/ uint16(xArgRM64),
+	/*11058*/ uint16(xArgCL),
+	/*11059*/ uint16(xMatch),
+	/*11060*/ uint16(xCondIs64), 11063, 11077,
+	/*11063*/ uint16(xCondDataSize), 11067, 11072, 0,
+	/*11067*/ uint16(xSetOp), uint16(RCL),
+	/*11069*/ uint16(xArgRM16),
+	/*11070*/ uint16(xArgCL),
+	/*11071*/ uint16(xMatch),
+	/*11072*/ uint16(xSetOp), uint16(RCL),
+	/*11074*/ uint16(xArgRM32),
+	/*11075*/ uint16(xArgCL),
+	/*11076*/ uint16(xMatch),
+	/*11077*/ uint16(xCondDataSize), 11067, 11072, 11081,
+	/*11081*/ uint16(xSetOp), uint16(RCL),
+	/*11083*/ uint16(xArgRM64),
+	/*11084*/ uint16(xArgCL),
+	/*11085*/ uint16(xMatch),
+	/*11086*/ uint16(xCondIs64), 11089, 11103,
+	/*11089*/ uint16(xCondDataSize), 11093, 11098, 0,
+	/*11093*/ uint16(xSetOp), uint16(RCR),
+	/*11095*/ uint16(xArgRM16),
+	/*11096*/ uint16(xArgCL),
+	/*11097*/ uint16(xMatch),
+	/*11098*/ uint16(xSetOp), uint16(RCR),
+	/*11100*/ uint16(xArgRM32),
+	/*11101*/ uint16(xArgCL),
+	/*11102*/ uint16(xMatch),
+	/*11103*/ uint16(xCondDataSize), 11093, 11098, 11107,
+	/*11107*/ uint16(xSetOp), uint16(RCR),
+	/*11109*/ uint16(xArgRM64),
+	/*11110*/ uint16(xArgCL),
+	/*11111*/ uint16(xMatch),
+	/*11112*/ uint16(xCondIs64), 11115, 11129,
+	/*11115*/ uint16(xCondDataSize), 11119, 11124, 0,
+	/*11119*/ uint16(xSetOp), uint16(SHL),
+	/*11121*/ uint16(xArgRM16),
+	/*11122*/ uint16(xArgCL),
+	/*11123*/ uint16(xMatch),
+	/*11124*/ uint16(xSetOp), uint16(SHL),
+	/*11126*/ uint16(xArgRM32),
+	/*11127*/ uint16(xArgCL),
+	/*11128*/ uint16(xMatch),
+	/*11129*/ uint16(xCondDataSize), 11119, 11124, 11133,
+	/*11133*/ uint16(xSetOp), uint16(SHL),
+	/*11135*/ uint16(xArgRM64),
+	/*11136*/ uint16(xArgCL),
+	/*11137*/ uint16(xMatch),
+	/*11138*/ uint16(xCondIs64), 11141, 11155,
+	/*11141*/ uint16(xCondDataSize), 11145, 11150, 0,
+	/*11145*/ uint16(xSetOp), uint16(SHR),
+	/*11147*/ uint16(xArgRM16),
+	/*11148*/ uint16(xArgCL),
+	/*11149*/ uint16(xMatch),
+	/*11150*/ uint16(xSetOp), uint16(SHR),
+	/*11152*/ uint16(xArgRM32),
+	/*11153*/ uint16(xArgCL),
+	/*11154*/ uint16(xMatch),
+	/*11155*/ uint16(xCondDataSize), 11145, 11150, 11159,
+	/*11159*/ uint16(xSetOp), uint16(SHR),
+	/*11161*/ uint16(xArgRM64),
+	/*11162*/ uint16(xArgCL),
+	/*11163*/ uint16(xMatch),
+	/*11164*/ uint16(xCondIs64), 11167, 11181,
+	/*11167*/ uint16(xCondDataSize), 11171, 11176, 0,
+	/*11171*/ uint16(xSetOp), uint16(SAR),
+	/*11173*/ uint16(xArgRM16),
+	/*11174*/ uint16(xArgCL),
+	/*11175*/ uint16(xMatch),
+	/*11176*/ uint16(xSetOp), uint16(SAR),
+	/*11178*/ uint16(xArgRM32),
+	/*11179*/ uint16(xArgCL),
+	/*11180*/ uint16(xMatch),
+	/*11181*/ uint16(xCondDataSize), 11171, 11176, 11185,
+	/*11185*/ uint16(xSetOp), uint16(SAR),
+	/*11187*/ uint16(xArgRM64),
+	/*11188*/ uint16(xArgCL),
+	/*11189*/ uint16(xMatch),
+	/*11190*/ uint16(xCondIs64), 11193, 0,
+	/*11193*/ uint16(xSetOp), uint16(AAM),
+	/*11195*/ uint16(xReadIb),
+	/*11196*/ uint16(xArgImm8u),
+	/*11197*/ uint16(xMatch),
+	/*11198*/ uint16(xCondIs64), 11201, 0,
+	/*11201*/ uint16(xSetOp), uint16(AAD),
+	/*11203*/ uint16(xReadIb),
+	/*11204*/ uint16(xArgImm8u),
+	/*11205*/ uint16(xMatch),
+	/*11206*/ uint16(xCondIs64), 11209, 11212,
+	/*11209*/ uint16(xSetOp), uint16(XLATB),
+	/*11211*/ uint16(xMatch),
+	/*11212*/ uint16(xCondDataSize), 11209, 11209, 11216,
+	/*11216*/ uint16(xSetOp), uint16(XLATB),
+	/*11218*/ uint16(xMatch),
+	/*11219*/ uint16(xCondByte), 64,
+	0xc0, 11390,
+	0xc1, 11390,
+	0xc2, 11390,
+	0xc3, 11390,
+	0xc4, 11390,
+	0xc5, 11390,
+	0xc6, 11390,
+	0xc7, 11390,
+	0xc8, 11395,
+	0xc9, 11395,
+	0xca, 11395,
+	0xcb, 11395,
+	0xcc, 11395,
+	0xcd, 11395,
+	0xce, 11395,
+	0xcf, 11395,
+	0xd0, 11400,
+	0xd1, 11400,
+	0xd2, 11400,
+	0xd3, 11400,
+	0xd4, 11400,
+	0xd5, 11400,
+	0xd6, 11400,
+	0xd7, 11400,
+	0xd8, 11404,
+	0xd9, 11404,
+	0xda, 11404,
+	0xdb, 11404,
+	0xdc, 11404,
+	0xdd, 11404,
+	0xde, 11404,
+	0xdf, 11404,
+	0xe0, 11408,
+	0xe1, 11408,
+	0xe2, 11408,
+	0xe3, 11408,
+	0xe4, 11408,
+	0xe5, 11408,
+	0xe6, 11408,
+	0xe7, 11408,
+	0xe8, 11413,
+	0xe9, 11413,
+	0xea, 11413,
+	0xeb, 11413,
+	0xec, 11413,
+	0xed, 11413,
+	0xee, 11413,
+	0xef, 11413,
+	0xf0, 11418,
+	0xf1, 11418,
+	0xf2, 11418,
+	0xf3, 11418,
+	0xf4, 11418,
+	0xf5, 11418,
+	0xf6, 11418,
+	0xf7, 11418,
+	0xf8, 11423,
+	0xf9, 11423,
+	0xfa, 11423,
+	0xfb, 11423,
+	0xfc, 11423,
+	0xfd, 11423,
+	0xfe, 11423,
+	0xff, 11423,
+	/*11349*/ uint16(xCondSlashR),
+	11358, // 0
+	11362, // 1
+	11366, // 2
+	11370, // 3
+	11374, // 4
+	11378, // 5
+	11382, // 6
+	11386, // 7
+	/*11358*/ uint16(xSetOp), uint16(FADD),
+	/*11360*/ uint16(xArgM32fp),
+	/*11361*/ uint16(xMatch),
+	/*11362*/ uint16(xSetOp), uint16(FMUL),
+	/*11364*/ uint16(xArgM32fp),
+	/*11365*/ uint16(xMatch),
+	/*11366*/ uint16(xSetOp), uint16(FCOM),
+	/*11368*/ uint16(xArgM32fp),
+	/*11369*/ uint16(xMatch),
+	/*11370*/ uint16(xSetOp), uint16(FCOMP),
+	/*11372*/ uint16(xArgM32fp),
+	/*11373*/ uint16(xMatch),
+	/*11374*/ uint16(xSetOp), uint16(FSUB),
+	/*11376*/ uint16(xArgM32fp),
+	/*11377*/ uint16(xMatch),
+	/*11378*/ uint16(xSetOp), uint16(FSUBR),
+	/*11380*/ uint16(xArgM32fp),
+	/*11381*/ uint16(xMatch),
+	/*11382*/ uint16(xSetOp), uint16(FDIV),
+	/*11384*/ uint16(xArgM32fp),
+	/*11385*/ uint16(xMatch),
+	/*11386*/ uint16(xSetOp), uint16(FDIVR),
+	/*11388*/ uint16(xArgM32fp),
+	/*11389*/ uint16(xMatch),
+	/*11390*/ uint16(xSetOp), uint16(FADD),
+	/*11392*/ uint16(xArgST),
+	/*11393*/ uint16(xArgSTi),
+	/*11394*/ uint16(xMatch),
+	/*11395*/ uint16(xSetOp), uint16(FMUL),
+	/*11397*/ uint16(xArgST),
+	/*11398*/ uint16(xArgSTi),
+	/*11399*/ uint16(xMatch),
+	/*11400*/ uint16(xSetOp), uint16(FCOM),
+	/*11402*/ uint16(xArgSTi),
+	/*11403*/ uint16(xMatch),
+	/*11404*/ uint16(xSetOp), uint16(FCOMP),
+	/*11406*/ uint16(xArgSTi),
+	/*11407*/ uint16(xMatch),
+	/*11408*/ uint16(xSetOp), uint16(FSUB),
+	/*11410*/ uint16(xArgST),
+	/*11411*/ uint16(xArgSTi),
+	/*11412*/ uint16(xMatch),
+	/*11413*/ uint16(xSetOp), uint16(FSUBR),
+	/*11415*/ uint16(xArgST),
+	/*11416*/ uint16(xArgSTi),
+	/*11417*/ uint16(xMatch),
+	/*11418*/ uint16(xSetOp), uint16(FDIV),
+	/*11420*/ uint16(xArgST),
+	/*11421*/ uint16(xArgSTi),
+	/*11422*/ uint16(xMatch),
+	/*11423*/ uint16(xSetOp), uint16(FDIVR),
+	/*11425*/ uint16(xArgST),
+	/*11426*/ uint16(xArgSTi),
+	/*11427*/ uint16(xMatch),
+	/*11428*/ uint16(xCondByte), 42,
+	0xc0, 11551,
+	0xc1, 11551,
+	0xc2, 11551,
+	0xc3, 11551,
+	0xc4, 11551,
+	0xc5, 11551,
+	0xc6, 11551,
+	0xc7, 11551,
+	0xc8, 11555,
+	0xc9, 11555,
+	0xca, 11555,
+	0xcb, 11555,
+	0xcc, 11555,
+	0xcd, 11555,
+	0xce, 11555,
+	0xcf, 11555,
+	0xD0, 11559,
+	0xE0, 11562,
+	0xE1, 11565,
+	0xE4, 11568,
+	0xE5, 11571,
+	0xE8, 11574,
+	0xE9, 11577,
+	0xEA, 11580,
+	0xEB, 11583,
+	0xEC, 11586,
+	0xF0, 11589,
+	0xF1, 11592,
+	0xF2, 11595,
+	0xF3, 11598,
+	0xF4, 11601,
+	0xF5, 11604,
+	0xF6, 11607,
+	0xF7, 11610,
+	0xF8, 11613,
+	0xF9, 11616,
+	0xFA, 11619,
+	0xFB, 11622,
+	0xFC, 11625,
+	0xFD, 11628,
+	0xFE, 11631,
+	0xFF, 11634,
+	/*11514*/ uint16(xCondSlashR),
+	11523, // 0
+	0,     // 1
+	11527, // 2
+	11531, // 3
+	11535, // 4
+	11539, // 5
+	11543, // 6
+	11547, // 7
+	/*11523*/ uint16(xSetOp), uint16(FLD),
+	/*11525*/ uint16(xArgM32fp),
+	/*11526*/ uint16(xMatch),
+	/*11527*/ uint16(xSetOp), uint16(FST),
+	/*11529*/ uint16(xArgM32fp),
+	/*11530*/ uint16(xMatch),
+	/*11531*/ uint16(xSetOp), uint16(FSTP),
+	/*11533*/ uint16(xArgM32fp),
+	/*11534*/ uint16(xMatch),
+	/*11535*/ uint16(xSetOp), uint16(FLDENV),
+	/*11537*/ uint16(xArgM1428byte),
+	/*11538*/ uint16(xMatch),
+	/*11539*/ uint16(xSetOp), uint16(FLDCW),
+	/*11541*/ uint16(xArgM2byte),
+	/*11542*/ uint16(xMatch),
+	/*11543*/ uint16(xSetOp), uint16(FNSTENV),
+	/*11545*/ uint16(xArgM1428byte),
+	/*11546*/ uint16(xMatch),
+	/*11547*/ uint16(xSetOp), uint16(FNSTCW),
+	/*11549*/ uint16(xArgM2byte),
+	/*11550*/ uint16(xMatch),
+	/*11551*/ uint16(xSetOp), uint16(FLD),
+	/*11553*/ uint16(xArgSTi),
+	/*11554*/ uint16(xMatch),
+	/*11555*/ uint16(xSetOp), uint16(FXCH),
+	/*11557*/ uint16(xArgSTi),
+	/*11558*/ uint16(xMatch),
+	/*11559*/ uint16(xSetOp), uint16(FNOP),
+	/*11561*/ uint16(xMatch),
+	/*11562*/ uint16(xSetOp), uint16(FCHS),
+	/*11564*/ uint16(xMatch),
+	/*11565*/ uint16(xSetOp), uint16(FABS),
+	/*11567*/ uint16(xMatch),
+	/*11568*/ uint16(xSetOp), uint16(FTST),
+	/*11570*/ uint16(xMatch),
+	/*11571*/ uint16(xSetOp), uint16(FXAM),
+	/*11573*/ uint16(xMatch),
+	/*11574*/ uint16(xSetOp), uint16(FLD1),
+	/*11576*/ uint16(xMatch),
+	/*11577*/ uint16(xSetOp), uint16(FLDL2T),
+	/*11579*/ uint16(xMatch),
+	/*11580*/ uint16(xSetOp), uint16(FLDL2E),
+	/*11582*/ uint16(xMatch),
+	/*11583*/ uint16(xSetOp), uint16(FLDPI),
+	/*11585*/ uint16(xMatch),
+	/*11586*/ uint16(xSetOp), uint16(FLDLG2),
+	/*11588*/ uint16(xMatch),
+	/*11589*/ uint16(xSetOp), uint16(F2XM1),
+	/*11591*/ uint16(xMatch),
+	/*11592*/ uint16(xSetOp), uint16(FYL2X),
+	/*11594*/ uint16(xMatch),
+	/*11595*/ uint16(xSetOp), uint16(FPTAN),
+	/*11597*/ uint16(xMatch),
+	/*11598*/ uint16(xSetOp), uint16(FPATAN),
+	/*11600*/ uint16(xMatch),
+	/*11601*/ uint16(xSetOp), uint16(FXTRACT),
+	/*11603*/ uint16(xMatch),
+	/*11604*/ uint16(xSetOp), uint16(FPREM1),
+	/*11606*/ uint16(xMatch),
+	/*11607*/ uint16(xSetOp), uint16(FDECSTP),
+	/*11609*/ uint16(xMatch),
+	/*11610*/ uint16(xSetOp), uint16(FINCSTP),
+	/*11612*/ uint16(xMatch),
+	/*11613*/ uint16(xSetOp), uint16(FPREM),
+	/*11615*/ uint16(xMatch),
+	/*11616*/ uint16(xSetOp), uint16(FYL2XP1),
+	/*11618*/ uint16(xMatch),
+	/*11619*/ uint16(xSetOp), uint16(FSQRT),
+	/*11621*/ uint16(xMatch),
+	/*11622*/ uint16(xSetOp), uint16(FSINCOS),
+	/*11624*/ uint16(xMatch),
+	/*11625*/ uint16(xSetOp), uint16(FRNDINT),
+	/*11627*/ uint16(xMatch),
+	/*11628*/ uint16(xSetOp), uint16(FSCALE),
+	/*11630*/ uint16(xMatch),
+	/*11631*/ uint16(xSetOp), uint16(FSIN),
+	/*11633*/ uint16(xMatch),
+	/*11634*/ uint16(xSetOp), uint16(FCOS),
+	/*11636*/ uint16(xMatch),
+	/*11637*/ uint16(xCondByte), 33,
+	0xc0, 11746,
+	0xc1, 11746,
+	0xc2, 11746,
+	0xc3, 11746,
+	0xc4, 11746,
+	0xc5, 11746,
+	0xc6, 11746,
+	0xc7, 11746,
+	0xc8, 11751,
+	0xc9, 11751,
+	0xca, 11751,
+	0xcb, 11751,
+	0xcc, 11751,
+	0xcd, 11751,
+	0xce, 11751,
+	0xcf, 11751,
+	0xd0, 11756,
+	0xd1, 11756,
+	0xd2, 11756,
+	0xd3, 11756,
+	0xd4, 11756,
+	0xd5, 11756,
+	0xd6, 11756,
+	0xd7, 11756,
+	0xd8, 11761,
+	0xd9, 11761,
+	0xda, 11761,
+	0xdb, 11761,
+	0xdc, 11761,
+	0xdd, 11761,
+	0xde, 11761,
+	0xdf, 11761,
+	0xE9, 11766,
+	/*11705*/ uint16(xCondSlashR),
+	11714, // 0
+	11718, // 1
+	11722, // 2
+	11726, // 3
+	11730, // 4
+	11734, // 5
+	11738, // 6
+	11742, // 7
+	/*11714*/ uint16(xSetOp), uint16(FIADD),
+	/*11716*/ uint16(xArgM32int),
+	/*11717*/ uint16(xMatch),
+	/*11718*/ uint16(xSetOp), uint16(FIMUL),
+	/*11720*/ uint16(xArgM32int),
+	/*11721*/ uint16(xMatch),
+	/*11722*/ uint16(xSetOp), uint16(FICOM),
+	/*11724*/ uint16(xArgM32int),
+	/*11725*/ uint16(xMatch),
+	/*11726*/ uint16(xSetOp), uint16(FICOMP),
+	/*11728*/ uint16(xArgM32int),
+	/*11729*/ uint16(xMatch),
+	/*11730*/ uint16(xSetOp), uint16(FISUB),
+	/*11732*/ uint16(xArgM32int),
+	/*11733*/ uint16(xMatch),
+	/*11734*/ uint16(xSetOp), uint16(FISUBR),
+	/*11736*/ uint16(xArgM32int),
+	/*11737*/ uint16(xMatch),
+	/*11738*/ uint16(xSetOp), uint16(FIDIV),
+	/*11740*/ uint16(xArgM32int),
+	/*11741*/ uint16(xMatch),
+	/*11742*/ uint16(xSetOp), uint16(FIDIVR),
+	/*11744*/ uint16(xArgM32int),
+	/*11745*/ uint16(xMatch),
+	/*11746*/ uint16(xSetOp), uint16(FCMOVB),
+	/*11748*/ uint16(xArgST),
+	/*11749*/ uint16(xArgSTi),
+	/*11750*/ uint16(xMatch),
+	/*11751*/ uint16(xSetOp), uint16(FCMOVE),
+	/*11753*/ uint16(xArgST),
+	/*11754*/ uint16(xArgSTi),
+	/*11755*/ uint16(xMatch),
+	/*11756*/ uint16(xSetOp), uint16(FCMOVBE),
+	/*11758*/ uint16(xArgST),
+	/*11759*/ uint16(xArgSTi),
+	/*11760*/ uint16(xMatch),
+	/*11761*/ uint16(xSetOp), uint16(FCMOVU),
+	/*11763*/ uint16(xArgST),
+	/*11764*/ uint16(xArgSTi),
+	/*11765*/ uint16(xMatch),
+	/*11766*/ uint16(xSetOp), uint16(FUCOMPP),
+	/*11768*/ uint16(xMatch),
+	/*11769*/ uint16(xCondByte), 50,
+	0xc0, 11904,
+	0xc1, 11904,
+	0xc2, 11904,
+	0xc3, 11904,
+	0xc4, 11904,
+	0xc5, 11904,
+	0xc6, 11904,
+	0xc7, 11904,
+	0xc8, 11909,
+	0xc9, 11909,
+	0xca, 11909,
+	0xcb, 11909,
+	0xcc, 11909,
+	0xcd, 11909,
+	0xce, 11909,
+	0xcf, 11909,
+	0xd0, 11914,
+	0xd1, 11914,
+	0xd2, 11914,
+	0xd3, 11914,
+	0xd4, 11914,
+	0xd5, 11914,
+	0xd6, 11914,
+	0xd7, 11914,
+	0xd8, 11919,
+	0xd9, 11919,
+	0xda, 11919,
+	0xdb, 11919,
+	0xdc, 11919,
+	0xdd, 11919,
+	0xde, 11919,
+	0xdf, 11919,
+	0xE2, 11924,
+	0xE3, 11927,
+	0xe8, 11930,
+	0xe9, 11930,
+	0xea, 11930,
+	0xeb, 11930,
+	0xec, 11930,
+	0xed, 11930,
+	0xee, 11930,
+	0xef, 11930,
+	0xf0, 11935,
+	0xf1, 11935,
+	0xf2, 11935,
+	0xf3, 11935,
+	0xf4, 11935,
+	0xf5, 11935,
+	0xf6, 11935,
+	0xf7, 11935,
+	/*11871*/ uint16(xCondSlashR),
+	11880, // 0
+	11884, // 1
+	11888, // 2
+	11892, // 3
+	0,     // 4
+	11896, // 5
+	0,     // 6
+	11900, // 7
+	/*11880*/ uint16(xSetOp), uint16(FILD),
+	/*11882*/ uint16(xArgM32int),
+	/*11883*/ uint16(xMatch),
+	/*11884*/ uint16(xSetOp), uint16(FISTTP),
+	/*11886*/ uint16(xArgM32int),
+	/*11887*/ uint16(xMatch),
+	/*11888*/ uint16(xSetOp), uint16(FIST),
+	/*11890*/ uint16(xArgM32int),
+	/*11891*/ uint16(xMatch),
+	/*11892*/ uint16(xSetOp), uint16(FISTP),
+	/*11894*/ uint16(xArgM32int),
+	/*11895*/ uint16(xMatch),
+	/*11896*/ uint16(xSetOp), uint16(FLD),
+	/*11898*/ uint16(xArgM80fp),
+	/*11899*/ uint16(xMatch),
+	/*11900*/ uint16(xSetOp), uint16(FSTP),
+	/*11902*/ uint16(xArgM80fp),
+	/*11903*/ uint16(xMatch),
+	/*11904*/ uint16(xSetOp), uint16(FCMOVNB),
+	/*11906*/ uint16(xArgST),
+	/*11907*/ uint16(xArgSTi),
+	/*11908*/ uint16(xMatch),
+	/*11909*/ uint16(xSetOp), uint16(FCMOVNE),
+	/*11911*/ uint16(xArgST),
+	/*11912*/ uint16(xArgSTi),
+	/*11913*/ uint16(xMatch),
+	/*11914*/ uint16(xSetOp), uint16(FCMOVNBE),
+	/*11916*/ uint16(xArgST),
+	/*11917*/ uint16(xArgSTi),
+	/*11918*/ uint16(xMatch),
+	/*11919*/ uint16(xSetOp), uint16(FCMOVNU),
+	/*11921*/ uint16(xArgST),
+	/*11922*/ uint16(xArgSTi),
+	/*11923*/ uint16(xMatch),
+	/*11924*/ uint16(xSetOp), uint16(FNCLEX),
+	/*11926*/ uint16(xMatch),
+	/*11927*/ uint16(xSetOp), uint16(FNINIT),
+	/*11929*/ uint16(xMatch),
+	/*11930*/ uint16(xSetOp), uint16(FUCOMI),
+	/*11932*/ uint16(xArgST),
+	/*11933*/ uint16(xArgSTi),
+	/*11934*/ uint16(xMatch),
+	/*11935*/ uint16(xSetOp), uint16(FCOMI),
+	/*11937*/ uint16(xArgST),
+	/*11938*/ uint16(xArgSTi),
+	/*11939*/ uint16(xMatch),
+	/*11940*/ uint16(xCondByte), 48,
+	0xc0, 12079,
+	0xc1, 12079,
+	0xc2, 12079,
+	0xc3, 12079,
+	0xc4, 12079,
+	0xc5, 12079,
+	0xc6, 12079,
+	0xc7, 12079,
+	0xc8, 12084,
+	0xc9, 12084,
+	0xca, 12084,
+	0xcb, 12084,
+	0xcc, 12084,
+	0xcd, 12084,
+	0xce, 12084,
+	0xcf, 12084,
+	0xe0, 12089,
+	0xe1, 12089,
+	0xe2, 12089,
+	0xe3, 12089,
+	0xe4, 12089,
+	0xe5, 12089,
+	0xe6, 12089,
+	0xe7, 12089,
+	0xe8, 12094,
+	0xe9, 12094,
+	0xea, 12094,
+	0xeb, 12094,
+	0xec, 12094,
+	0xed, 12094,
+	0xee, 12094,
+	0xef, 12094,
+	0xf0, 12099,
+	0xf1, 12099,
+	0xf2, 12099,
+	0xf3, 12099,
+	0xf4, 12099,
+	0xf5, 12099,
+	0xf6, 12099,
+	0xf7, 12099,
+	0xf8, 12104,
+	0xf9, 12104,
+	0xfa, 12104,
+	0xfb, 12104,
+	0xfc, 12104,
+	0xfd, 12104,
+	0xfe, 12104,
+	0xff, 12104,
+	/*12038*/ uint16(xCondSlashR),
+	12047, // 0
+	12051, // 1
+	12055, // 2
+	12059, // 3
+	12063, // 4
+	12067, // 5
+	12071, // 6
+	12075, // 7
+	/*12047*/ uint16(xSetOp), uint16(FADD),
+	/*12049*/ uint16(xArgM64fp),
+	/*12050*/ uint16(xMatch),
+	/*12051*/ uint16(xSetOp), uint16(FMUL),
+	/*12053*/ uint16(xArgM64fp),
+	/*12054*/ uint16(xMatch),
+	/*12055*/ uint16(xSetOp), uint16(FCOM),
+	/*12057*/ uint16(xArgM64fp),
+	/*12058*/ uint16(xMatch),
+	/*12059*/ uint16(xSetOp), uint16(FCOMP),
+	/*12061*/ uint16(xArgM64fp),
+	/*12062*/ uint16(xMatch),
+	/*12063*/ uint16(xSetOp), uint16(FSUB),
+	/*12065*/ uint16(xArgM64fp),
+	/*12066*/ uint16(xMatch),
+	/*12067*/ uint16(xSetOp), uint16(FSUBR),
+	/*12069*/ uint16(xArgM64fp),
+	/*12070*/ uint16(xMatch),
+	/*12071*/ uint16(xSetOp), uint16(FDIV),
+	/*12073*/ uint16(xArgM64fp),
+	/*12074*/ uint16(xMatch),
+	/*12075*/ uint16(xSetOp), uint16(FDIVR),
+	/*12077*/ uint16(xArgM64fp),
+	/*12078*/ uint16(xMatch),
+	/*12079*/ uint16(xSetOp), uint16(FADD),
+	/*12081*/ uint16(xArgSTi),
+	/*12082*/ uint16(xArgST),
+	/*12083*/ uint16(xMatch),
+	/*12084*/ uint16(xSetOp), uint16(FMUL),
+	/*12086*/ uint16(xArgSTi),
+	/*12087*/ uint16(xArgST),
+	/*12088*/ uint16(xMatch),
+	/*12089*/ uint16(xSetOp), uint16(FSUBR),
+	/*12091*/ uint16(xArgSTi),
+	/*12092*/ uint16(xArgST),
+	/*12093*/ uint16(xMatch),
+	/*12094*/ uint16(xSetOp), uint16(FSUB),
+	/*12096*/ uint16(xArgSTi),
+	/*12097*/ uint16(xArgST),
+	/*12098*/ uint16(xMatch),
+	/*12099*/ uint16(xSetOp), uint16(FDIVR),
+	/*12101*/ uint16(xArgSTi),
+	/*12102*/ uint16(xArgST),
+	/*12103*/ uint16(xMatch),
+	/*12104*/ uint16(xSetOp), uint16(FDIV),
+	/*12106*/ uint16(xArgSTi),
+	/*12107*/ uint16(xArgST),
+	/*12108*/ uint16(xMatch),
+	/*12109*/ uint16(xCondByte), 40,
+	0xc0, 12228,
+	0xc1, 12228,
+	0xc2, 12228,
+	0xc3, 12228,
+	0xc4, 12228,
+	0xc5, 12228,
+	0xc6, 12228,
+	0xc7, 12228,
+	0xd0, 12232,
+	0xd1, 12232,
+	0xd2, 12232,
+	0xd3, 12232,
+	0xd4, 12232,
+	0xd5, 12232,
+	0xd6, 12232,
+	0xd7, 12232,
+	0xd8, 12236,
+	0xd9, 12236,
+	0xda, 12236,
+	0xdb, 12236,
+	0xdc, 12236,
+	0xdd, 12236,
+	0xde, 12236,
+	0xdf, 12236,
+	0xe0, 12240,
+	0xe1, 12240,
+	0xe2, 12240,
+	0xe3, 12240,
+	0xe4, 12240,
+	0xe5, 12240,
+	0xe6, 12240,
+	0xe7, 12240,
+	0xe8, 12244,
+	0xe9, 12244,
+	0xea, 12244,
+	0xeb, 12244,
+	0xec, 12244,
+	0xed, 12244,
+	0xee, 12244,
+	0xef, 12244,
+	/*12191*/ uint16(xCondSlashR),
+	12200, // 0
+	12204, // 1
+	12208, // 2
+	12212, // 3
+	12216, // 4
+	0,     // 5
+	12220, // 6
+	12224, // 7
+	/*12200*/ uint16(xSetOp), uint16(FLD),
+	/*12202*/ uint16(xArgM64fp),
+	/*12203*/ uint16(xMatch),
+	/*12204*/ uint16(xSetOp), uint16(FISTTP),
+	/*12206*/ uint16(xArgM64int),
+	/*12207*/ uint16(xMatch),
+	/*12208*/ uint16(xSetOp), uint16(FST),
+	/*12210*/ uint16(xArgM64fp),
+	/*12211*/ uint16(xMatch),
+	/*12212*/ uint16(xSetOp), uint16(FSTP),
+	/*12214*/ uint16(xArgM64fp),
+	/*12215*/ uint16(xMatch),
+	/*12216*/ uint16(xSetOp), uint16(FRSTOR),
+	/*12218*/ uint16(xArgM94108byte),
+	/*12219*/ uint16(xMatch),
+	/*12220*/ uint16(xSetOp), uint16(FNSAVE),
+	/*12222*/ uint16(xArgM94108byte),
+	/*12223*/ uint16(xMatch),
+	/*12224*/ uint16(xSetOp), uint16(FNSTSW),
+	/*12226*/ uint16(xArgM2byte),
+	/*12227*/ uint16(xMatch),
+	/*12228*/ uint16(xSetOp), uint16(FFREE),
+	/*12230*/ uint16(xArgSTi),
+	/*12231*/ uint16(xMatch),
+	/*12232*/ uint16(xSetOp), uint16(FST),
+	/*12234*/ uint16(xArgSTi),
+	/*12235*/ uint16(xMatch),
+	/*12236*/ uint16(xSetOp), uint16(FSTP),
+	/*12238*/ uint16(xArgSTi),
+	/*12239*/ uint16(xMatch),
+	/*12240*/ uint16(xSetOp), uint16(FUCOM),
+	/*12242*/ uint16(xArgSTi),
+	/*12243*/ uint16(xMatch),
+	/*12244*/ uint16(xSetOp), uint16(FUCOMP),
+	/*12246*/ uint16(xArgSTi),
+	/*12247*/ uint16(xMatch),
+	/*12248*/ uint16(xCondByte), 49,
+	0xc0, 12389,
+	0xc1, 12389,
+	0xc2, 12389,
+	0xc3, 12389,
+	0xc4, 12389,
+	0xc5, 12389,
+	0xc6, 12389,
+	0xc7, 12389,
+	0xc8, 12394,
+	0xc9, 12394,
+	0xca, 12394,
+	0xcb, 12394,
+	0xcc, 12394,
+	0xcd, 12394,
+	0xce, 12394,
+	0xcf, 12394,
+	0xD9, 12399,
+	0xe0, 12402,
+	0xe1, 12402,
+	0xe2, 12402,
+	0xe3, 12402,
+	0xe4, 12402,
+	0xe5, 12402,
+	0xe6, 12402,
+	0xe7, 12402,
+	0xe8, 12407,
+	0xe9, 12407,
+	0xea, 12407,
+	0xeb, 12407,
+	0xec, 12407,
+	0xed, 12407,
+	0xee, 12407,
+	0xef, 12407,
+	0xf0, 12412,
+	0xf1, 12412,
+	0xf2, 12412,
+	0xf3, 12412,
+	0xf4, 12412,
+	0xf5, 12412,
+	0xf6, 12412,
+	0xf7, 12412,
+	0xf8, 12417,
+	0xf9, 12417,
+	0xfa, 12417,
+	0xfb, 12417,
+	0xfc, 12417,
+	0xfd, 12417,
+	0xfe, 12417,
+	0xff, 12417,
+	/*12348*/ uint16(xCondSlashR),
+	12357, // 0
+	12361, // 1
+	12365, // 2
+	12369, // 3
+	12373, // 4
+	12377, // 5
+	12381, // 6
+	12385, // 7
+	/*12357*/ uint16(xSetOp), uint16(FIADD),
+	/*12359*/ uint16(xArgM16int),
+	/*12360*/ uint16(xMatch),
+	/*12361*/ uint16(xSetOp), uint16(FIMUL),
+	/*12363*/ uint16(xArgM16int),
+	/*12364*/ uint16(xMatch),
+	/*12365*/ uint16(xSetOp), uint16(FICOM),
+	/*12367*/ uint16(xArgM16int),
+	/*12368*/ uint16(xMatch),
+	/*12369*/ uint16(xSetOp), uint16(FICOMP),
+	/*12371*/ uint16(xArgM16int),
+	/*12372*/ uint16(xMatch),
+	/*12373*/ uint16(xSetOp), uint16(FISUB),
+	/*12375*/ uint16(xArgM16int),
+	/*12376*/ uint16(xMatch),
+	/*12377*/ uint16(xSetOp), uint16(FISUBR),
+	/*12379*/ uint16(xArgM16int),
+	/*12380*/ uint16(xMatch),
+	/*12381*/ uint16(xSetOp), uint16(FIDIV),
+	/*12383*/ uint16(xArgM16int),
+	/*12384*/ uint16(xMatch),
+	/*12385*/ uint16(xSetOp), uint16(FIDIVR),
+	/*12387*/ uint16(xArgM16int),
+	/*12388*/ uint16(xMatch),
+	/*12389*/ uint16(xSetOp), uint16(FADDP),
+	/*12391*/ uint16(xArgSTi),
+	/*12392*/ uint16(xArgST),
+	/*12393*/ uint16(xMatch),
+	/*12394*/ uint16(xSetOp), uint16(FMULP),
+	/*12396*/ uint16(xArgSTi),
+	/*12397*/ uint16(xArgST),
+	/*12398*/ uint16(xMatch),
+	/*12399*/ uint16(xSetOp), uint16(FCOMPP),
+	/*12401*/ uint16(xMatch),
+	/*12402*/ uint16(xSetOp), uint16(FSUBRP),
+	/*12404*/ uint16(xArgSTi),
+	/*12405*/ uint16(xArgST),
+	/*12406*/ uint16(xMatch),
+	/*12407*/ uint16(xSetOp), uint16(FSUBP),
+	/*12409*/ uint16(xArgSTi),
+	/*12410*/ uint16(xArgST),
+	/*12411*/ uint16(xMatch),
+	/*12412*/ uint16(xSetOp), uint16(FDIVRP),
+	/*12414*/ uint16(xArgSTi),
+	/*12415*/ uint16(xArgST),
+	/*12416*/ uint16(xMatch),
+	/*12417*/ uint16(xSetOp), uint16(FDIVP),
+	/*12419*/ uint16(xArgSTi),
+	/*12420*/ uint16(xArgST),
+	/*12421*/ uint16(xMatch),
+	/*12422*/ uint16(xCondByte), 25,
+	0xc0, 12515,
+	0xc1, 12515,
+	0xc2, 12515,
+	0xc3, 12515,
+	0xc4, 12515,
+	0xc5, 12515,
+	0xc6, 12515,
+	0xc7, 12515,
+	0xE0, 12519,
+	0xe8, 12523,
+	0xe9, 12523,
+	0xea, 12523,
+	0xeb, 12523,
+	0xec, 12523,
+	0xed, 12523,
+	0xee, 12523,
+	0xef, 12523,
+	0xf0, 12528,
+	0xf1, 12528,
+	0xf2, 12528,
+	0xf3, 12528,
+	0xf4, 12528,
+	0xf5, 12528,
+	0xf6, 12528,
+	0xf7, 12528,
+	/*12474*/ uint16(xCondSlashR),
+	12483, // 0
+	12487, // 1
+	12491, // 2
+	12495, // 3
+	12499, // 4
+	12503, // 5
+	12507, // 6
+	12511, // 7
+	/*12483*/ uint16(xSetOp), uint16(FILD),
+	/*12485*/ uint16(xArgM16int),
+	/*12486*/ uint16(xMatch),
+	/*12487*/ uint16(xSetOp), uint16(FISTTP),
+	/*12489*/ uint16(xArgM16int),
+	/*12490*/ uint16(xMatch),
+	/*12491*/ uint16(xSetOp), uint16(FIST),
+	/*12493*/ uint16(xArgM16int),
+	/*12494*/ uint16(xMatch),
+	/*12495*/ uint16(xSetOp), uint16(FISTP),
+	/*12497*/ uint16(xArgM16int),
+	/*12498*/ uint16(xMatch),
+	/*12499*/ uint16(xSetOp), uint16(FBLD),
+	/*12501*/ uint16(xArgM80dec),
+	/*12502*/ uint16(xMatch),
+	/*12503*/ uint16(xSetOp), uint16(FILD),
+	/*12505*/ uint16(xArgM64int),
+	/*12506*/ uint16(xMatch),
+	/*12507*/ uint16(xSetOp), uint16(FBSTP),
+	/*12509*/ uint16(xArgM80bcd),
+	/*12510*/ uint16(xMatch),
+	/*12511*/ uint16(xSetOp), uint16(FISTP),
+	/*12513*/ uint16(xArgM64int),
+	/*12514*/ uint16(xMatch),
+	/*12515*/ uint16(xSetOp), uint16(FFREEP),
+	/*12517*/ uint16(xArgSTi),
+	/*12518*/ uint16(xMatch),
+	/*12519*/ uint16(xSetOp), uint16(FNSTSW),
+	/*12521*/ uint16(xArgAX),
+	/*12522*/ uint16(xMatch),
+	/*12523*/ uint16(xSetOp), uint16(FUCOMIP),
+	/*12525*/ uint16(xArgST),
+	/*12526*/ uint16(xArgSTi),
+	/*12527*/ uint16(xMatch),
+	/*12528*/ uint16(xSetOp), uint16(FCOMIP),
+	/*12530*/ uint16(xArgST),
+	/*12531*/ uint16(xArgSTi),
+	/*12532*/ uint16(xMatch),
+	/*12533*/ uint16(xSetOp), uint16(LOOPNE),
+	/*12535*/ uint16(xReadCb),
+	/*12536*/ uint16(xArgRel8),
+	/*12537*/ uint16(xMatch),
+	/*12538*/ uint16(xSetOp), uint16(LOOPE),
+	/*12540*/ uint16(xReadCb),
+	/*12541*/ uint16(xArgRel8),
+	/*12542*/ uint16(xMatch),
+	/*12543*/ uint16(xSetOp), uint16(LOOP),
+	/*12545*/ uint16(xReadCb),
+	/*12546*/ uint16(xArgRel8),
+	/*12547*/ uint16(xMatch),
+	/*12548*/ uint16(xCondIs64), 12551, 12565,
+	/*12551*/ uint16(xCondAddrSize), 12555, 12560, 0,
+	/*12555*/ uint16(xSetOp), uint16(JCXZ),
+	/*12557*/ uint16(xReadCb),
+	/*12558*/ uint16(xArgRel8),
+	/*12559*/ uint16(xMatch),
+	/*12560*/ uint16(xSetOp), uint16(JECXZ),
+	/*12562*/ uint16(xReadCb),
+	/*12563*/ uint16(xArgRel8),
+	/*12564*/ uint16(xMatch),
+	/*12565*/ uint16(xCondAddrSize), 0, 12560, 12569,
+	/*12569*/ uint16(xSetOp), uint16(JRCXZ),
+	/*12571*/ uint16(xReadCb),
+	/*12572*/ uint16(xArgRel8),
+	/*12573*/ uint16(xMatch),
+	/*12574*/ uint16(xSetOp), uint16(IN),
+	/*12576*/ uint16(xReadIb),
+	/*12577*/ uint16(xArgAL),
+	/*12578*/ uint16(xArgImm8u),
+	/*12579*/ uint16(xMatch),
+	/*12580*/ uint16(xCondDataSize), 12584, 12590, 12596,
+	/*12584*/ uint16(xSetOp), uint16(IN),
+	/*12586*/ uint16(xReadIb),
+	/*12587*/ uint16(xArgAX),
+	/*12588*/ uint16(xArgImm8u),
+	/*12589*/ uint16(xMatch),
+	/*12590*/ uint16(xSetOp), uint16(IN),
+	/*12592*/ uint16(xReadIb),
+	/*12593*/ uint16(xArgEAX),
+	/*12594*/ uint16(xArgImm8u),
+	/*12595*/ uint16(xMatch),
+	/*12596*/ uint16(xSetOp), uint16(IN),
+	/*12598*/ uint16(xReadIb),
+	/*12599*/ uint16(xArgEAX),
+	/*12600*/ uint16(xArgImm8u),
+	/*12601*/ uint16(xMatch),
+	/*12602*/ uint16(xSetOp), uint16(OUT),
+	/*12604*/ uint16(xReadIb),
+	/*12605*/ uint16(xArgImm8u),
+	/*12606*/ uint16(xArgAL),
+	/*12607*/ uint16(xMatch),
+	/*12608*/ uint16(xCondDataSize), 12612, 12618, 12624,
+	/*12612*/ uint16(xSetOp), uint16(OUT),
+	/*12614*/ uint16(xReadIb),
+	/*12615*/ uint16(xArgImm8u),
+	/*12616*/ uint16(xArgAX),
+	/*12617*/ uint16(xMatch),
+	/*12618*/ uint16(xSetOp), uint16(OUT),
+	/*12620*/ uint16(xReadIb),
+	/*12621*/ uint16(xArgImm8u),
+	/*12622*/ uint16(xArgEAX),
+	/*12623*/ uint16(xMatch),
+	/*12624*/ uint16(xSetOp), uint16(OUT),
+	/*12626*/ uint16(xReadIb),
+	/*12627*/ uint16(xArgImm8u),
+	/*12628*/ uint16(xArgEAX),
+	/*12629*/ uint16(xMatch),
+	/*12630*/ uint16(xCondIs64), 12633, 12647,
+	/*12633*/ uint16(xCondDataSize), 12637, 12642, 0,
+	/*12637*/ uint16(xSetOp), uint16(CALL),
+	/*12639*/ uint16(xReadCw),
+	/*12640*/ uint16(xArgRel16),
+	/*12641*/ uint16(xMatch),
+	/*12642*/ uint16(xSetOp), uint16(CALL),
+	/*12644*/ uint16(xReadCd),
+	/*12645*/ uint16(xArgRel32),
+	/*12646*/ uint16(xMatch),
+	/*12647*/ uint16(xCondDataSize), 12651, 12642, 12656,
+	/*12651*/ uint16(xSetOp), uint16(CALL),
+	/*12653*/ uint16(xReadCd),
+	/*12654*/ uint16(xArgRel32),
+	/*12655*/ uint16(xMatch),
+	/*12656*/ uint16(xSetOp), uint16(CALL),
+	/*12658*/ uint16(xReadCd),
+	/*12659*/ uint16(xArgRel32),
+	/*12660*/ uint16(xMatch),
+	/*12661*/ uint16(xCondIs64), 12664, 12678,
+	/*12664*/ uint16(xCondDataSize), 12668, 12673, 0,
+	/*12668*/ uint16(xSetOp), uint16(JMP),
+	/*12670*/ uint16(xReadCw),
+	/*12671*/ uint16(xArgRel16),
+	/*12672*/ uint16(xMatch),
+	/*12673*/ uint16(xSetOp), uint16(JMP),
+	/*12675*/ uint16(xReadCd),
+	/*12676*/ uint16(xArgRel32),
+	/*12677*/ uint16(xMatch),
+	/*12678*/ uint16(xCondDataSize), 12682, 12673, 12687,
+	/*12682*/ uint16(xSetOp), uint16(JMP),
+	/*12684*/ uint16(xReadCd),
+	/*12685*/ uint16(xArgRel32),
+	/*12686*/ uint16(xMatch),
+	/*12687*/ uint16(xSetOp), uint16(JMP),
+	/*12689*/ uint16(xReadCd),
+	/*12690*/ uint16(xArgRel32),
+	/*12691*/ uint16(xMatch),
+	/*12692*/ uint16(xCondIs64), 12695, 0,
+	/*12695*/ uint16(xCondDataSize), 12699, 12704, 0,
+	/*12699*/ uint16(xSetOp), uint16(LJMP),
+	/*12701*/ uint16(xReadCd),
+	/*12702*/ uint16(xArgPtr16colon16),
+	/*12703*/ uint16(xMatch),
+	/*12704*/ uint16(xSetOp), uint16(LJMP),
+	/*12706*/ uint16(xReadCp),
+	/*12707*/ uint16(xArgPtr16colon32),
+	/*12708*/ uint16(xMatch),
+	/*12709*/ uint16(xSetOp), uint16(JMP),
+	/*12711*/ uint16(xReadCb),
+	/*12712*/ uint16(xArgRel8),
+	/*12713*/ uint16(xMatch),
+	/*12714*/ uint16(xSetOp), uint16(IN),
+	/*12716*/ uint16(xArgAL),
+	/*12717*/ uint16(xArgDX),
+	/*12718*/ uint16(xMatch),
+	/*12719*/ uint16(xCondDataSize), 12723, 12728, 12733,
+	/*12723*/ uint16(xSetOp), uint16(IN),
+	/*12725*/ uint16(xArgAX),
+	/*12726*/ uint16(xArgDX),
+	/*12727*/ uint16(xMatch),
+	/*12728*/ uint16(xSetOp), uint16(IN),
+	/*12730*/ uint16(xArgEAX),
+	/*12731*/ uint16(xArgDX),
+	/*12732*/ uint16(xMatch),
+	/*12733*/ uint16(xSetOp), uint16(IN),
+	/*12735*/ uint16(xArgEAX),
+	/*12736*/ uint16(xArgDX),
+	/*12737*/ uint16(xMatch),
+	/*12738*/ uint16(xSetOp), uint16(OUT),
+	/*12740*/ uint16(xArgDX),
+	/*12741*/ uint16(xArgAL),
+	/*12742*/ uint16(xMatch),
+	/*12743*/ uint16(xCondDataSize), 12747, 12752, 12757,
+	/*12747*/ uint16(xSetOp), uint16(OUT),
+	/*12749*/ uint16(xArgDX),
+	/*12750*/ uint16(xArgAX),
+	/*12751*/ uint16(xMatch),
+	/*12752*/ uint16(xSetOp), uint16(OUT),
+	/*12754*/ uint16(xArgDX),
+	/*12755*/ uint16(xArgEAX),
+	/*12756*/ uint16(xMatch),
+	/*12757*/ uint16(xSetOp), uint16(OUT),
+	/*12759*/ uint16(xArgDX),
+	/*12760*/ uint16(xArgEAX),
+	/*12761*/ uint16(xMatch),
+	/*12762*/ uint16(xSetOp), uint16(ICEBP),
+	/*12764*/ uint16(xMatch),
+	/*12765*/ uint16(xSetOp), uint16(HLT),
+	/*12767*/ uint16(xMatch),
+	/*12768*/ uint16(xSetOp), uint16(CMC),
+	/*12770*/ uint16(xMatch),
+	/*12771*/ uint16(xCondSlashR),
+	12780, // 0
+	0,     // 1
+	12786, // 2
+	12790, // 3
+	12794, // 4
+	12798, // 5
+	12802, // 6
+	12806, // 7
+	/*12780*/ uint16(xSetOp), uint16(TEST),
+	/*12782*/ uint16(xReadIb),
+	/*12783*/ uint16(xArgRM8),
+	/*12784*/ uint16(xArgImm8u),
+	/*12785*/ uint16(xMatch),
+	/*12786*/ uint16(xSetOp), uint16(NOT),
+	/*12788*/ uint16(xArgRM8),
+	/*12789*/ uint16(xMatch),
+	/*12790*/ uint16(xSetOp), uint16(NEG),
+	/*12792*/ uint16(xArgRM8),
+	/*12793*/ uint16(xMatch),
+	/*12794*/ uint16(xSetOp), uint16(MUL),
+	/*12796*/ uint16(xArgRM8),
+	/*12797*/ uint16(xMatch),
+	/*12798*/ uint16(xSetOp), uint16(IMUL),
+	/*12800*/ uint16(xArgRM8),
+	/*12801*/ uint16(xMatch),
+	/*12802*/ uint16(xSetOp), uint16(DIV),
+	/*12804*/ uint16(xArgRM8),
+	/*12805*/ uint16(xMatch),
+	/*12806*/ uint16(xSetOp), uint16(IDIV),
+	/*12808*/ uint16(xArgRM8),
+	/*12809*/ uint16(xMatch),
+	/*12810*/ uint16(xCondSlashR),
+	12819, // 0
+	0,     // 1
+	12848, // 2
+	12871, // 3
+	12894, // 4
+	12917, // 5
+	12940, // 6
+	12963, // 7
+	/*12819*/ uint16(xCondIs64), 12822, 12838,
+	/*12822*/ uint16(xCondDataSize), 12826, 12832, 0,
+	/*12826*/ uint16(xSetOp), uint16(TEST),
+	/*12828*/ uint16(xReadIw),
+	/*12829*/ uint16(xArgRM16),
+	/*12830*/ uint16(xArgImm16),
+	/*12831*/ uint16(xMatch),
+	/*12832*/ uint16(xSetOp), uint16(TEST),
+	/*12834*/ uint16(xReadId),
+	/*12835*/ uint16(xArgRM32),
+	/*12836*/ uint16(xArgImm32),
+	/*12837*/ uint16(xMatch),
+	/*12838*/ uint16(xCondDataSize), 12826, 12832, 12842,
+	/*12842*/ uint16(xSetOp), uint16(TEST),
+	/*12844*/ uint16(xReadId),
+	/*12845*/ uint16(xArgRM64),
+	/*12846*/ uint16(xArgImm32),
+	/*12847*/ uint16(xMatch),
+	/*12848*/ uint16(xCondIs64), 12851, 12863,
+	/*12851*/ uint16(xCondDataSize), 12855, 12859, 0,
+	/*12855*/ uint16(xSetOp), uint16(NOT),
+	/*12857*/ uint16(xArgRM16),
+	/*12858*/ uint16(xMatch),
+	/*12859*/ uint16(xSetOp), uint16(NOT),
+	/*12861*/ uint16(xArgRM32),
+	/*12862*/ uint16(xMatch),
+	/*12863*/ uint16(xCondDataSize), 12855, 12859, 12867,
+	/*12867*/ uint16(xSetOp), uint16(NOT),
+	/*12869*/ uint16(xArgRM64),
+	/*12870*/ uint16(xMatch),
+	/*12871*/ uint16(xCondIs64), 12874, 12886,
+	/*12874*/ uint16(xCondDataSize), 12878, 12882, 0,
+	/*12878*/ uint16(xSetOp), uint16(NEG),
+	/*12880*/ uint16(xArgRM16),
+	/*12881*/ uint16(xMatch),
+	/*12882*/ uint16(xSetOp), uint16(NEG),
+	/*12884*/ uint16(xArgRM32),
+	/*12885*/ uint16(xMatch),
+	/*12886*/ uint16(xCondDataSize), 12878, 12882, 12890,
+	/*12890*/ uint16(xSetOp), uint16(NEG),
+	/*12892*/ uint16(xArgRM64),
+	/*12893*/ uint16(xMatch),
+	/*12894*/ uint16(xCondIs64), 12897, 12909,
+	/*12897*/ uint16(xCondDataSize), 12901, 12905, 0,
+	/*12901*/ uint16(xSetOp), uint16(MUL),
+	/*12903*/ uint16(xArgRM16),
+	/*12904*/ uint16(xMatch),
+	/*12905*/ uint16(xSetOp), uint16(MUL),
+	/*12907*/ uint16(xArgRM32),
+	/*12908*/ uint16(xMatch),
+	/*12909*/ uint16(xCondDataSize), 12901, 12905, 12913,
+	/*12913*/ uint16(xSetOp), uint16(MUL),
+	/*12915*/ uint16(xArgRM64),
+	/*12916*/ uint16(xMatch),
+	/*12917*/ uint16(xCondIs64), 12920, 12932,
+	/*12920*/ uint16(xCondDataSize), 12924, 12928, 0,
+	/*12924*/ uint16(xSetOp), uint16(IMUL),
+	/*12926*/ uint16(xArgRM16),
+	/*12927*/ uint16(xMatch),
+	/*12928*/ uint16(xSetOp), uint16(IMUL),
+	/*12930*/ uint16(xArgRM32),
+	/*12931*/ uint16(xMatch),
+	/*12932*/ uint16(xCondDataSize), 12924, 12928, 12936,
+	/*12936*/ uint16(xSetOp), uint16(IMUL),
+	/*12938*/ uint16(xArgRM64),
+	/*12939*/ uint16(xMatch),
+	/*12940*/ uint16(xCondIs64), 12943, 12955,
+	/*12943*/ uint16(xCondDataSize), 12947, 12951, 0,
+	/*12947*/ uint16(xSetOp), uint16(DIV),
+	/*12949*/ uint16(xArgRM16),
+	/*12950*/ uint16(xMatch),
+	/*12951*/ uint16(xSetOp), uint16(DIV),
+	/*12953*/ uint16(xArgRM32),
+	/*12954*/ uint16(xMatch),
+	/*12955*/ uint16(xCondDataSize), 12947, 12951, 12959,
+	/*12959*/ uint16(xSetOp), uint16(DIV),
+	/*12961*/ uint16(xArgRM64),
+	/*12962*/ uint16(xMatch),
+	/*12963*/ uint16(xCondIs64), 12966, 12978,
+	/*12966*/ uint16(xCondDataSize), 12970, 12974, 0,
+	/*12970*/ uint16(xSetOp), uint16(IDIV),
+	/*12972*/ uint16(xArgRM16),
+	/*12973*/ uint16(xMatch),
+	/*12974*/ uint16(xSetOp), uint16(IDIV),
+	/*12976*/ uint16(xArgRM32),
+	/*12977*/ uint16(xMatch),
+	/*12978*/ uint16(xCondDataSize), 12970, 12974, 12982,
+	/*12982*/ uint16(xSetOp), uint16(IDIV),
+	/*12984*/ uint16(xArgRM64),
+	/*12985*/ uint16(xMatch),
+	/*12986*/ uint16(xSetOp), uint16(CLC),
+	/*12988*/ uint16(xMatch),
+	/*12989*/ uint16(xSetOp), uint16(STC),
+	/*12991*/ uint16(xMatch),
+	/*12992*/ uint16(xSetOp), uint16(CLI),
+	/*12994*/ uint16(xMatch),
+	/*12995*/ uint16(xSetOp), uint16(STI),
+	/*12997*/ uint16(xMatch),
+	/*12998*/ uint16(xSetOp), uint16(CLD),
+	/*13000*/ uint16(xMatch),
+	/*13001*/ uint16(xSetOp), uint16(STD),
+	/*13003*/ uint16(xMatch),
+	/*13004*/ uint16(xCondSlashR),
+	13013, // 0
+	13017, // 1
+	0,     // 2
+	0,     // 3
+	0,     // 4
+	0,     // 5
+	0,     // 6
+	0,     // 7
+	/*13013*/ uint16(xSetOp), uint16(INC),
+	/*13015*/ uint16(xArgRM8),
+	/*13016*/ uint16(xMatch),
+	/*13017*/ uint16(xSetOp), uint16(DEC),
+	/*13019*/ uint16(xArgRM8),
+	/*13020*/ uint16(xMatch),
+	/*13021*/ uint16(xCondSlashR),
+	13030, // 0
+	13053, // 1
+	13076, // 2
+	13095, // 3
+	13118, // 4
+	13137, // 5
+	13160, // 6
+	0,     // 7
+	/*13030*/ uint16(xCondIs64), 13033, 13045,
+	/*13033*/ uint16(xCondDataSize), 13037, 13041, 0,
+	/*13037*/ uint16(xSetOp), uint16(INC),
+	/*13039*/ uint16(xArgRM16),
+	/*13040*/ uint16(xMatch),
+	/*13041*/ uint16(xSetOp), uint16(INC),
+	/*13043*/ uint16(xArgRM32),
+	/*13044*/ uint16(xMatch),
+	/*13045*/ uint16(xCondDataSize), 13037, 13041, 13049,
+	/*13049*/ uint16(xSetOp), uint16(INC),
+	/*13051*/ uint16(xArgRM64),
+	/*13052*/ uint16(xMatch),
+	/*13053*/ uint16(xCondIs64), 13056, 13068,
+	/*13056*/ uint16(xCondDataSize), 13060, 13064, 0,
+	/*13060*/ uint16(xSetOp), uint16(DEC),
+	/*13062*/ uint16(xArgRM16),
+	/*13063*/ uint16(xMatch),
+	/*13064*/ uint16(xSetOp), uint16(DEC),
+	/*13066*/ uint16(xArgRM32),
+	/*13067*/ uint16(xMatch),
+	/*13068*/ uint16(xCondDataSize), 13060, 13064, 13072,
+	/*13072*/ uint16(xSetOp), uint16(DEC),
+	/*13074*/ uint16(xArgRM64),
+	/*13075*/ uint16(xMatch),
+	/*13076*/ uint16(xCondIs64), 13079, 13091,
+	/*13079*/ uint16(xCondDataSize), 13083, 13087, 0,
+	/*13083*/ uint16(xSetOp), uint16(CALL),
+	/*13085*/ uint16(xArgRM16),
+	/*13086*/ uint16(xMatch),
+	/*13087*/ uint16(xSetOp), uint16(CALL),
+	/*13089*/ uint16(xArgRM32),
+	/*13090*/ uint16(xMatch),
+	/*13091*/ uint16(xSetOp), uint16(CALL),
+	/*13093*/ uint16(xArgRM64),
+	/*13094*/ uint16(xMatch),
+	/*13095*/ uint16(xCondIs64), 13098, 13110,
+	/*13098*/ uint16(xCondDataSize), 13102, 13106, 0,
+	/*13102*/ uint16(xSetOp), uint16(LCALL),
+	/*13104*/ uint16(xArgM16colon16),
+	/*13105*/ uint16(xMatch),
+	/*13106*/ uint16(xSetOp), uint16(LCALL),
+	/*13108*/ uint16(xArgM16colon32),
+	/*13109*/ uint16(xMatch),
+	/*13110*/ uint16(xCondDataSize), 13102, 13106, 13114,
+	/*13114*/ uint16(xSetOp), uint16(LCALL),
+	/*13116*/ uint16(xArgM16colon64),
+	/*13117*/ uint16(xMatch),
+	/*13118*/ uint16(xCondIs64), 13121, 13133,
+	/*13121*/ uint16(xCondDataSize), 13125, 13129, 0,
+	/*13125*/ uint16(xSetOp), uint16(JMP),
+	/*13127*/ uint16(xArgRM16),
+	/*13128*/ uint16(xMatch),
+	/*13129*/ uint16(xSetOp), uint16(JMP),
+	/*13131*/ uint16(xArgRM32),
+	/*13132*/ uint16(xMatch),
+	/*13133*/ uint16(xSetOp), uint16(JMP),
+	/*13135*/ uint16(xArgRM64),
+	/*13136*/ uint16(xMatch),
+	/*13137*/ uint16(xCondIs64), 13140, 13152,
+	/*13140*/ uint16(xCondDataSize), 13144, 13148, 0,
+	/*13144*/ uint16(xSetOp), uint16(LJMP),
+	/*13146*/ uint16(xArgM16colon16),
+	/*13147*/ uint16(xMatch),
+	/*13148*/ uint16(xSetOp), uint16(LJMP),
+	/*13150*/ uint16(xArgM16colon32),
+	/*13151*/ uint16(xMatch),
+	/*13152*/ uint16(xCondDataSize), 13144, 13148, 13156,
+	/*13156*/ uint16(xSetOp), uint16(LJMP),
+	/*13158*/ uint16(xArgM16colon64),
+	/*13159*/ uint16(xMatch),
+	/*13160*/ uint16(xCondIs64), 13163, 13175,
+	/*13163*/ uint16(xCondDataSize), 13167, 13171, 0,
+	/*13167*/ uint16(xSetOp), uint16(PUSH),
+	/*13169*/ uint16(xArgRM16),
+	/*13170*/ uint16(xMatch),
+	/*13171*/ uint16(xSetOp), uint16(PUSH),
+	/*13173*/ uint16(xArgRM32),
+	/*13174*/ uint16(xMatch),
+	/*13175*/ uint16(xCondDataSize), 13167, 13179, 13183,
+	/*13179*/ uint16(xSetOp), uint16(PUSH),
+	/*13181*/ uint16(xArgRM64),
+	/*13182*/ uint16(xMatch),
+	/*13183*/ uint16(xSetOp), uint16(PUSH),
+	/*13185*/ uint16(xArgRM64),
+	/*13186*/ uint16(xMatch),
+}
+
+const (
+	_ Op = iota
+
+	AAA
+	AAD
+	AAM
+	AAS
+	ADC
+	ADD
+	ADDPD
+	ADDPS
+	ADDSD
+	ADDSS
+	ADDSUBPD
+	ADDSUBPS
+	AESDEC
+	AESDECLAST
+	AESENC
+	AESENCLAST
+	AESIMC
+	AESKEYGENASSIST
+	AND
+	ANDNPD
+	ANDNPS
+	ANDPD
+	ANDPS
+	ARPL
+	BLENDPD
+	BLENDPS
+	BLENDVPD
+	BLENDVPS
+	BOUND
+	BSF
+	BSR
+	BSWAP
+	BT
+	BTC
+	BTR
+	BTS
+	CALL
+	CBW
+	CDQ
+	CDQE
+	CLC
+	CLD
+	CLFLUSH
+	CLI
+	CLTS
+	CMC
+	CMOVA
+	CMOVAE
+	CMOVB
+	CMOVBE
+	CMOVE
+	CMOVG
+	CMOVGE
+	CMOVL
+	CMOVLE
+	CMOVNE
+	CMOVNO
+	CMOVNP
+	CMOVNS
+	CMOVO
+	CMOVP
+	CMOVS
+	CMP
+	CMPPD
+	CMPPS
+	CMPSB
+	CMPSD
+	CMPSD_XMM
+	CMPSQ
+	CMPSS
+	CMPSW
+	CMPXCHG
+	CMPXCHG16B
+	CMPXCHG8B
+	COMISD
+	COMISS
+	CPUID
+	CQO
+	CRC32
+	CVTDQ2PD
+	CVTDQ2PS
+	CVTPD2DQ
+	CVTPD2PI
+	CVTPD2PS
+	CVTPI2PD
+	CVTPI2PS
+	CVTPS2DQ
+	CVTPS2PD
+	CVTPS2PI
+	CVTSD2SI
+	CVTSD2SS
+	CVTSI2SD
+	CVTSI2SS
+	CVTSS2SD
+	CVTSS2SI
+	CVTTPD2DQ
+	CVTTPD2PI
+	CVTTPS2DQ
+	CVTTPS2PI
+	CVTTSD2SI
+	CVTTSS2SI
+	CWD
+	CWDE
+	DAA
+	DAS
+	DEC
+	DIV
+	DIVPD
+	DIVPS
+	DIVSD
+	DIVSS
+	DPPD
+	DPPS
+	EMMS
+	ENTER
+	EXTRACTPS
+	F2XM1
+	FABS
+	FADD
+	FADDP
+	FBLD
+	FBSTP
+	FCHS
+	FCMOVB
+	FCMOVBE
+	FCMOVE
+	FCMOVNB
+	FCMOVNBE
+	FCMOVNE
+	FCMOVNU
+	FCMOVU
+	FCOM
+	FCOMI
+	FCOMIP
+	FCOMP
+	FCOMPP
+	FCOS
+	FDECSTP
+	FDIV
+	FDIVP
+	FDIVR
+	FDIVRP
+	FFREE
+	FFREEP
+	FIADD
+	FICOM
+	FICOMP
+	FIDIV
+	FIDIVR
+	FILD
+	FIMUL
+	FINCSTP
+	FIST
+	FISTP
+	FISTTP
+	FISUB
+	FISUBR
+	FLD
+	FLD1
+	FLDCW
+	FLDENV
+	FLDL2E
+	FLDL2T
+	FLDLG2
+	FLDPI
+	FMUL
+	FMULP
+	FNCLEX
+	FNINIT
+	FNOP
+	FNSAVE
+	FNSTCW
+	FNSTENV
+	FNSTSW
+	FPATAN
+	FPREM
+	FPREM1
+	FPTAN
+	FRNDINT
+	FRSTOR
+	FSCALE
+	FSIN
+	FSINCOS
+	FSQRT
+	FST
+	FSTP
+	FSUB
+	FSUBP
+	FSUBR
+	FSUBRP
+	FTST
+	FUCOM
+	FUCOMI
+	FUCOMIP
+	FUCOMP
+	FUCOMPP
+	FWAIT
+	FXAM
+	FXCH
+	FXRSTOR
+	FXRSTOR64
+	FXSAVE
+	FXSAVE64
+	FXTRACT
+	FYL2X
+	FYL2XP1
+	HADDPD
+	HADDPS
+	HLT
+	HSUBPD
+	HSUBPS
+	ICEBP
+	IDIV
+	IMUL
+	IN
+	INC
+	INSB
+	INSD
+	INSERTPS
+	INSW
+	INT
+	INTO
+	INVD
+	INVLPG
+	INVPCID
+	IRET
+	IRETD
+	IRETQ
+	JA
+	JAE
+	JB
+	JBE
+	JCXZ
+	JE
+	JECXZ
+	JG
+	JGE
+	JL
+	JLE
+	JMP
+	JNE
+	JNO
+	JNP
+	JNS
+	JO
+	JP
+	JRCXZ
+	JS
+	LAHF
+	LAR
+	LCALL
+	LDDQU
+	LDMXCSR
+	LDS
+	LEA
+	LEAVE
+	LES
+	LFENCE
+	LFS
+	LGDT
+	LGS
+	LIDT
+	LJMP
+	LLDT
+	LMSW
+	LODSB
+	LODSD
+	LODSQ
+	LODSW
+	LOOP
+	LOOPE
+	LOOPNE
+	LRET
+	LSL
+	LSS
+	LTR
+	LZCNT
+	MASKMOVDQU
+	MASKMOVQ
+	MAXPD
+	MAXPS
+	MAXSD
+	MAXSS
+	MFENCE
+	MINPD
+	MINPS
+	MINSD
+	MINSS
+	MONITOR
+	MOV
+	MOVAPD
+	MOVAPS
+	MOVBE
+	MOVD
+	MOVDDUP
+	MOVDQ2Q
+	MOVDQA
+	MOVDQU
+	MOVHLPS
+	MOVHPD
+	MOVHPS
+	MOVLHPS
+	MOVLPD
+	MOVLPS
+	MOVMSKPD
+	MOVMSKPS
+	MOVNTDQ
+	MOVNTDQA
+	MOVNTI
+	MOVNTPD
+	MOVNTPS
+	MOVNTQ
+	MOVNTSD
+	MOVNTSS
+	MOVQ
+	MOVQ2DQ
+	MOVSB
+	MOVSD
+	MOVSD_XMM
+	MOVSHDUP
+	MOVSLDUP
+	MOVSQ
+	MOVSS
+	MOVSW
+	MOVSX
+	MOVSXD
+	MOVUPD
+	MOVUPS
+	MOVZX
+	MPSADBW
+	MUL
+	MULPD
+	MULPS
+	MULSD
+	MULSS
+	MWAIT
+	NEG
+	NOP
+	NOT
+	OR
+	ORPD
+	ORPS
+	OUT
+	OUTSB
+	OUTSD
+	OUTSW
+	PABSB
+	PABSD
+	PABSW
+	PACKSSDW
+	PACKSSWB
+	PACKUSDW
+	PACKUSWB
+	PADDB
+	PADDD
+	PADDQ
+	PADDSB
+	PADDSW
+	PADDUSB
+	PADDUSW
+	PADDW
+	PALIGNR
+	PAND
+	PANDN
+	PAUSE
+	PAVGB
+	PAVGW
+	PBLENDVB
+	PBLENDW
+	PCLMULQDQ
+	PCMPEQB
+	PCMPEQD
+	PCMPEQQ
+	PCMPEQW
+	PCMPESTRI
+	PCMPESTRM
+	PCMPGTB
+	PCMPGTD
+	PCMPGTQ
+	PCMPGTW
+	PCMPISTRI
+	PCMPISTRM
+	PEXTRB
+	PEXTRD
+	PEXTRQ
+	PEXTRW
+	PHADDD
+	PHADDSW
+	PHADDW
+	PHMINPOSUW
+	PHSUBD
+	PHSUBSW
+	PHSUBW
+	PINSRB
+	PINSRD
+	PINSRQ
+	PINSRW
+	PMADDUBSW
+	PMADDWD
+	PMAXSB
+	PMAXSD
+	PMAXSW
+	PMAXUB
+	PMAXUD
+	PMAXUW
+	PMINSB
+	PMINSD
+	PMINSW
+	PMINUB
+	PMINUD
+	PMINUW
+	PMOVMSKB
+	PMOVSXBD
+	PMOVSXBQ
+	PMOVSXBW
+	PMOVSXDQ
+	PMOVSXWD
+	PMOVSXWQ
+	PMOVZXBD
+	PMOVZXBQ
+	PMOVZXBW
+	PMOVZXDQ
+	PMOVZXWD
+	PMOVZXWQ
+	PMULDQ
+	PMULHRSW
+	PMULHUW
+	PMULHW
+	PMULLD
+	PMULLW
+	PMULUDQ
+	POP
+	POPA
+	POPAD
+	POPCNT
+	POPF
+	POPFD
+	POPFQ
+	POR
+	PREFETCHNTA
+	PREFETCHT0
+	PREFETCHT1
+	PREFETCHT2
+	PREFETCHW
+	PSADBW
+	PSHUFB
+	PSHUFD
+	PSHUFHW
+	PSHUFLW
+	PSHUFW
+	PSIGNB
+	PSIGND
+	PSIGNW
+	PSLLD
+	PSLLDQ
+	PSLLQ
+	PSLLW
+	PSRAD
+	PSRAW
+	PSRLD
+	PSRLDQ
+	PSRLQ
+	PSRLW
+	PSUBB
+	PSUBD
+	PSUBQ
+	PSUBSB
+	PSUBSW
+	PSUBUSB
+	PSUBUSW
+	PSUBW
+	PTEST
+	PUNPCKHBW
+	PUNPCKHDQ
+	PUNPCKHQDQ
+	PUNPCKHWD
+	PUNPCKLBW
+	PUNPCKLDQ
+	PUNPCKLQDQ
+	PUNPCKLWD
+	PUSH
+	PUSHA
+	PUSHAD
+	PUSHF
+	PUSHFD
+	PUSHFQ
+	PXOR
+	RCL
+	RCPPS
+	RCPSS
+	RCR
+	RDFSBASE
+	RDGSBASE
+	RDMSR
+	RDPMC
+	RDRAND
+	RDTSC
+	RDTSCP
+	RET
+	ROL
+	ROR
+	ROUNDPD
+	ROUNDPS
+	ROUNDSD
+	ROUNDSS
+	RSM
+	RSQRTPS
+	RSQRTSS
+	SAHF
+	SAR
+	SBB
+	SCASB
+	SCASD
+	SCASQ
+	SCASW
+	SETA
+	SETAE
+	SETB
+	SETBE
+	SETE
+	SETG
+	SETGE
+	SETL
+	SETLE
+	SETNE
+	SETNO
+	SETNP
+	SETNS
+	SETO
+	SETP
+	SETS
+	SFENCE
+	SGDT
+	SHL
+	SHLD
+	SHR
+	SHRD
+	SHUFPD
+	SHUFPS
+	SIDT
+	SLDT
+	SMSW
+	SQRTPD
+	SQRTPS
+	SQRTSD
+	SQRTSS
+	STC
+	STD
+	STI
+	STMXCSR
+	STOSB
+	STOSD
+	STOSQ
+	STOSW
+	STR
+	SUB
+	SUBPD
+	SUBPS
+	SUBSD
+	SUBSS
+	SWAPGS
+	SYSCALL
+	SYSENTER
+	SYSEXIT
+	SYSRET
+	TEST
+	TZCNT
+	UCOMISD
+	UCOMISS
+	UD1
+	UD2
+	UNPCKHPD
+	UNPCKHPS
+	UNPCKLPD
+	UNPCKLPS
+	VERR
+	VERW
+	WBINVD
+	WRFSBASE
+	WRGSBASE
+	WRMSR
+	XABORT
+	XADD
+	XBEGIN
+	XCHG
+	XEND
+	XGETBV
+	XLATB
+	XOR
+	XORPD
+	XORPS
+	XRSTOR
+	XRSTOR64
+	XRSTORS
+	XRSTORS64
+	XSAVE
+	XSAVE64
+	XSAVEC
+	XSAVEC64
+	XSAVEOPT
+	XSAVEOPT64
+	XSAVES
+	XSAVES64
+	XSETBV
+	XTEST
+)
+
+const maxOp = XTEST
+
+var opNames = [...]string{
+	AAA:             "AAA",
+	AAD:             "AAD",
+	AAM:             "AAM",
+	AAS:             "AAS",
+	ADC:             "ADC",
+	ADD:             "ADD",
+	ADDPD:           "ADDPD",
+	ADDPS:           "ADDPS",
+	ADDSD:           "ADDSD",
+	ADDSS:           "ADDSS",
+	ADDSUBPD:        "ADDSUBPD",
+	ADDSUBPS:        "ADDSUBPS",
+	AESDEC:          "AESDEC",
+	AESDECLAST:      "AESDECLAST",
+	AESENC:          "AESENC",
+	AESENCLAST:      "AESENCLAST",
+	AESIMC:          "AESIMC",
+	AESKEYGENASSIST: "AESKEYGENASSIST",
+	AND:             "AND",
+	ANDNPD:          "ANDNPD",
+	ANDNPS:          "ANDNPS",
+	ANDPD:           "ANDPD",
+	ANDPS:           "ANDPS",
+	ARPL:            "ARPL",
+	BLENDPD:         "BLENDPD",
+	BLENDPS:         "BLENDPS",
+	BLENDVPD:        "BLENDVPD",
+	BLENDVPS:        "BLENDVPS",
+	BOUND:           "BOUND",
+	BSF:             "BSF",
+	BSR:             "BSR",
+	BSWAP:           "BSWAP",
+	BT:              "BT",
+	BTC:             "BTC",
+	BTR:             "BTR",
+	BTS:             "BTS",
+	CALL:            "CALL",
+	CBW:             "CBW",
+	CDQ:             "CDQ",
+	CDQE:            "CDQE",
+	CLC:             "CLC",
+	CLD:             "CLD",
+	CLFLUSH:         "CLFLUSH",
+	CLI:             "CLI",
+	CLTS:            "CLTS",
+	CMC:             "CMC",
+	CMOVA:           "CMOVA",
+	CMOVAE:          "CMOVAE",
+	CMOVB:           "CMOVB",
+	CMOVBE:          "CMOVBE",
+	CMOVE:           "CMOVE",
+	CMOVG:           "CMOVG",
+	CMOVGE:          "CMOVGE",
+	CMOVL:           "CMOVL",
+	CMOVLE:          "CMOVLE",
+	CMOVNE:          "CMOVNE",
+	CMOVNO:          "CMOVNO",
+	CMOVNP:          "CMOVNP",
+	CMOVNS:          "CMOVNS",
+	CMOVO:           "CMOVO",
+	CMOVP:           "CMOVP",
+	CMOVS:           "CMOVS",
+	CMP:             "CMP",
+	CMPPD:           "CMPPD",
+	CMPPS:           "CMPPS",
+	CMPSB:           "CMPSB",
+	CMPSD:           "CMPSD",
+	CMPSD_XMM:       "CMPSD_XMM",
+	CMPSQ:           "CMPSQ",
+	CMPSS:           "CMPSS",
+	CMPSW:           "CMPSW",
+	CMPXCHG:         "CMPXCHG",
+	CMPXCHG16B:      "CMPXCHG16B",
+	CMPXCHG8B:       "CMPXCHG8B",
+	COMISD:          "COMISD",
+	COMISS:          "COMISS",
+	CPUID:           "CPUID",
+	CQO:             "CQO",
+	CRC32:           "CRC32",
+	CVTDQ2PD:        "CVTDQ2PD",
+	CVTDQ2PS:        "CVTDQ2PS",
+	CVTPD2DQ:        "CVTPD2DQ",
+	CVTPD2PI:        "CVTPD2PI",
+	CVTPD2PS:        "CVTPD2PS",
+	CVTPI2PD:        "CVTPI2PD",
+	CVTPI2PS:        "CVTPI2PS",
+	CVTPS2DQ:        "CVTPS2DQ",
+	CVTPS2PD:        "CVTPS2PD",
+	CVTPS2PI:        "CVTPS2PI",
+	CVTSD2SI:        "CVTSD2SI",
+	CVTSD2SS:        "CVTSD2SS",
+	CVTSI2SD:        "CVTSI2SD",
+	CVTSI2SS:        "CVTSI2SS",
+	CVTSS2SD:        "CVTSS2SD",
+	CVTSS2SI:        "CVTSS2SI",
+	CVTTPD2DQ:       "CVTTPD2DQ",
+	CVTTPD2PI:       "CVTTPD2PI",
+	CVTTPS2DQ:       "CVTTPS2DQ",
+	CVTTPS2PI:       "CVTTPS2PI",
+	CVTTSD2SI:       "CVTTSD2SI",
+	CVTTSS2SI:       "CVTTSS2SI",
+	CWD:             "CWD",
+	CWDE:            "CWDE",
+	DAA:             "DAA",
+	DAS:             "DAS",
+	DEC:             "DEC",
+	DIV:             "DIV",
+	DIVPD:           "DIVPD",
+	DIVPS:           "DIVPS",
+	DIVSD:           "DIVSD",
+	DIVSS:           "DIVSS",
+	DPPD:            "DPPD",
+	DPPS:            "DPPS",
+	EMMS:            "EMMS",
+	ENTER:           "ENTER",
+	EXTRACTPS:       "EXTRACTPS",
+	F2XM1:           "F2XM1",
+	FABS:            "FABS",
+	FADD:            "FADD",
+	FADDP:           "FADDP",
+	FBLD:            "FBLD",
+	FBSTP:           "FBSTP",
+	FCHS:            "FCHS",
+	FCMOVB:          "FCMOVB",
+	FCMOVBE:         "FCMOVBE",
+	FCMOVE:          "FCMOVE",
+	FCMOVNB:         "FCMOVNB",
+	FCMOVNBE:        "FCMOVNBE",
+	FCMOVNE:         "FCMOVNE",
+	FCMOVNU:         "FCMOVNU",
+	FCMOVU:          "FCMOVU",
+	FCOM:            "FCOM",
+	FCOMI:           "FCOMI",
+	FCOMIP:          "FCOMIP",
+	FCOMP:           "FCOMP",
+	FCOMPP:          "FCOMPP",
+	FCOS:            "FCOS",
+	FDECSTP:         "FDECSTP",
+	FDIV:            "FDIV",
+	FDIVP:           "FDIVP",
+	FDIVR:           "FDIVR",
+	FDIVRP:          "FDIVRP",
+	FFREE:           "FFREE",
+	FFREEP:          "FFREEP",
+	FIADD:           "FIADD",
+	FICOM:           "FICOM",
+	FICOMP:          "FICOMP",
+	FIDIV:           "FIDIV",
+	FIDIVR:          "FIDIVR",
+	FILD:            "FILD",
+	FIMUL:           "FIMUL",
+	FINCSTP:         "FINCSTP",
+	FIST:            "FIST",
+	FISTP:           "FISTP",
+	FISTTP:          "FISTTP",
+	FISUB:           "FISUB",
+	FISUBR:          "FISUBR",
+	FLD:             "FLD",
+	FLD1:            "FLD1",
+	FLDCW:           "FLDCW",
+	FLDENV:          "FLDENV",
+	FLDL2E:          "FLDL2E",
+	FLDL2T:          "FLDL2T",
+	FLDLG2:          "FLDLG2",
+	FLDPI:           "FLDPI",
+	FMUL:            "FMUL",
+	FMULP:           "FMULP",
+	FNCLEX:          "FNCLEX",
+	FNINIT:          "FNINIT",
+	FNOP:            "FNOP",
+	FNSAVE:          "FNSAVE",
+	FNSTCW:          "FNSTCW",
+	FNSTENV:         "FNSTENV",
+	FNSTSW:          "FNSTSW",
+	FPATAN:          "FPATAN",
+	FPREM:           "FPREM",
+	FPREM1:          "FPREM1",
+	FPTAN:           "FPTAN",
+	FRNDINT:         "FRNDINT",
+	FRSTOR:          "FRSTOR",
+	FSCALE:          "FSCALE",
+	FSIN:            "FSIN",
+	FSINCOS:         "FSINCOS",
+	FSQRT:           "FSQRT",
+	FST:             "FST",
+	FSTP:            "FSTP",
+	FSUB:            "FSUB",
+	FSUBP:           "FSUBP",
+	FSUBR:           "FSUBR",
+	FSUBRP:          "FSUBRP",
+	FTST:            "FTST",
+	FUCOM:           "FUCOM",
+	FUCOMI:          "FUCOMI",
+	FUCOMIP:         "FUCOMIP",
+	FUCOMP:          "FUCOMP",
+	FUCOMPP:         "FUCOMPP",
+	FWAIT:           "FWAIT",
+	FXAM:            "FXAM",
+	FXCH:            "FXCH",
+	FXRSTOR:         "FXRSTOR",
+	FXRSTOR64:       "FXRSTOR64",
+	FXSAVE:          "FXSAVE",
+	FXSAVE64:        "FXSAVE64",
+	FXTRACT:         "FXTRACT",
+	FYL2X:           "FYL2X",
+	FYL2XP1:         "FYL2XP1",
+	HADDPD:          "HADDPD",
+	HADDPS:          "HADDPS",
+	HLT:             "HLT",
+	HSUBPD:          "HSUBPD",
+	HSUBPS:          "HSUBPS",
+	ICEBP:           "ICEBP",
+	IDIV:            "IDIV",
+	IMUL:            "IMUL",
+	IN:              "IN",
+	INC:             "INC",
+	INSB:            "INSB",
+	INSD:            "INSD",
+	INSERTPS:        "INSERTPS",
+	INSW:            "INSW",
+	INT:             "INT",
+	INTO:            "INTO",
+	INVD:            "INVD",
+	INVLPG:          "INVLPG",
+	INVPCID:         "INVPCID",
+	IRET:            "IRET",
+	IRETD:           "IRETD",
+	IRETQ:           "IRETQ",
+	JA:              "JA",
+	JAE:             "JAE",
+	JB:              "JB",
+	JBE:             "JBE",
+	JCXZ:            "JCXZ",
+	JE:              "JE",
+	JECXZ:           "JECXZ",
+	JG:              "JG",
+	JGE:             "JGE",
+	JL:              "JL",
+	JLE:             "JLE",
+	JMP:             "JMP",
+	JNE:             "JNE",
+	JNO:             "JNO",
+	JNP:             "JNP",
+	JNS:             "JNS",
+	JO:              "JO",
+	JP:              "JP",
+	JRCXZ:           "JRCXZ",
+	JS:              "JS",
+	LAHF:            "LAHF",
+	LAR:             "LAR",
+	LCALL:           "LCALL",
+	LDDQU:           "LDDQU",
+	LDMXCSR:         "LDMXCSR",
+	LDS:             "LDS",
+	LEA:             "LEA",
+	LEAVE:           "LEAVE",
+	LES:             "LES",
+	LFENCE:          "LFENCE",
+	LFS:             "LFS",
+	LGDT:            "LGDT",
+	LGS:             "LGS",
+	LIDT:            "LIDT",
+	LJMP:            "LJMP",
+	LLDT:            "LLDT",
+	LMSW:            "LMSW",
+	LODSB:           "LODSB",
+	LODSD:           "LODSD",
+	LODSQ:           "LODSQ",
+	LODSW:           "LODSW",
+	LOOP:            "LOOP",
+	LOOPE:           "LOOPE",
+	LOOPNE:          "LOOPNE",
+	LRET:            "LRET",
+	LSL:             "LSL",
+	LSS:             "LSS",
+	LTR:             "LTR",
+	LZCNT:           "LZCNT",
+	MASKMOVDQU:      "MASKMOVDQU",
+	MASKMOVQ:        "MASKMOVQ",
+	MAXPD:           "MAXPD",
+	MAXPS:           "MAXPS",
+	MAXSD:           "MAXSD",
+	MAXSS:           "MAXSS",
+	MFENCE:          "MFENCE",
+	MINPD:           "MINPD",
+	MINPS:           "MINPS",
+	MINSD:           "MINSD",
+	MINSS:           "MINSS",
+	MONITOR:         "MONITOR",
+	MOV:             "MOV",
+	MOVAPD:          "MOVAPD",
+	MOVAPS:          "MOVAPS",
+	MOVBE:           "MOVBE",
+	MOVD:            "MOVD",
+	MOVDDUP:         "MOVDDUP",
+	MOVDQ2Q:         "MOVDQ2Q",
+	MOVDQA:          "MOVDQA",
+	MOVDQU:          "MOVDQU",
+	MOVHLPS:         "MOVHLPS",
+	MOVHPD:          "MOVHPD",
+	MOVHPS:          "MOVHPS",
+	MOVLHPS:         "MOVLHPS",
+	MOVLPD:          "MOVLPD",
+	MOVLPS:          "MOVLPS",
+	MOVMSKPD:        "MOVMSKPD",
+	MOVMSKPS:        "MOVMSKPS",
+	MOVNTDQ:         "MOVNTDQ",
+	MOVNTDQA:        "MOVNTDQA",
+	MOVNTI:          "MOVNTI",
+	MOVNTPD:         "MOVNTPD",
+	MOVNTPS:         "MOVNTPS",
+	MOVNTQ:          "MOVNTQ",
+	MOVNTSD:         "MOVNTSD",
+	MOVNTSS:         "MOVNTSS",
+	MOVQ:            "MOVQ",
+	MOVQ2DQ:         "MOVQ2DQ",
+	MOVSB:           "MOVSB",
+	MOVSD:           "MOVSD",
+	MOVSD_XMM:       "MOVSD_XMM",
+	MOVSHDUP:        "MOVSHDUP",
+	MOVSLDUP:        "MOVSLDUP",
+	MOVSQ:           "MOVSQ",
+	MOVSS:           "MOVSS",
+	MOVSW:           "MOVSW",
+	MOVSX:           "MOVSX",
+	MOVSXD:          "MOVSXD",
+	MOVUPD:          "MOVUPD",
+	MOVUPS:          "MOVUPS",
+	MOVZX:           "MOVZX",
+	MPSADBW:         "MPSADBW",
+	MUL:             "MUL",
+	MULPD:           "MULPD",
+	MULPS:           "MULPS",
+	MULSD:           "MULSD",
+	MULSS:           "MULSS",
+	MWAIT:           "MWAIT",
+	NEG:             "NEG",
+	NOP:             "NOP",
+	NOT:             "NOT",
+	OR:              "OR",
+	ORPD:            "ORPD",
+	ORPS:            "ORPS",
+	OUT:             "OUT",
+	OUTSB:           "OUTSB",
+	OUTSD:           "OUTSD",
+	OUTSW:           "OUTSW",
+	PABSB:           "PABSB",
+	PABSD:           "PABSD",
+	PABSW:           "PABSW",
+	PACKSSDW:        "PACKSSDW",
+	PACKSSWB:        "PACKSSWB",
+	PACKUSDW:        "PACKUSDW",
+	PACKUSWB:        "PACKUSWB",
+	PADDB:           "PADDB",
+	PADDD:           "PADDD",
+	PADDQ:           "PADDQ",
+	PADDSB:          "PADDSB",
+	PADDSW:          "PADDSW",
+	PADDUSB:         "PADDUSB",
+	PADDUSW:         "PADDUSW",
+	PADDW:           "PADDW",
+	PALIGNR:         "PALIGNR",
+	PAND:            "PAND",
+	PANDN:           "PANDN",
+	PAUSE:           "PAUSE",
+	PAVGB:           "PAVGB",
+	PAVGW:           "PAVGW",
+	PBLENDVB:        "PBLENDVB",
+	PBLENDW:         "PBLENDW",
+	PCLMULQDQ:       "PCLMULQDQ",
+	PCMPEQB:         "PCMPEQB",
+	PCMPEQD:         "PCMPEQD",
+	PCMPEQQ:         "PCMPEQQ",
+	PCMPEQW:         "PCMPEQW",
+	PCMPESTRI:       "PCMPESTRI",
+	PCMPESTRM:       "PCMPESTRM",
+	PCMPGTB:         "PCMPGTB",
+	PCMPGTD:         "PCMPGTD",
+	PCMPGTQ:         "PCMPGTQ",
+	PCMPGTW:         "PCMPGTW",
+	PCMPISTRI:       "PCMPISTRI",
+	PCMPISTRM:       "PCMPISTRM",
+	PEXTRB:          "PEXTRB",
+	PEXTRD:          "PEXTRD",
+	PEXTRQ:          "PEXTRQ",
+	PEXTRW:          "PEXTRW",
+	PHADDD:          "PHADDD",
+	PHADDSW:         "PHADDSW",
+	PHADDW:          "PHADDW",
+	PHMINPOSUW:      "PHMINPOSUW",
+	PHSUBD:          "PHSUBD",
+	PHSUBSW:         "PHSUBSW",
+	PHSUBW:          "PHSUBW",
+	PINSRB:          "PINSRB",
+	PINSRD:          "PINSRD",
+	PINSRQ:          "PINSRQ",
+	PINSRW:          "PINSRW",
+	PMADDUBSW:       "PMADDUBSW",
+	PMADDWD:         "PMADDWD",
+	PMAXSB:          "PMAXSB",
+	PMAXSD:          "PMAXSD",
+	PMAXSW:          "PMAXSW",
+	PMAXUB:          "PMAXUB",
+	PMAXUD:          "PMAXUD",
+	PMAXUW:          "PMAXUW",
+	PMINSB:          "PMINSB",
+	PMINSD:          "PMINSD",
+	PMINSW:          "PMINSW",
+	PMINUB:          "PMINUB",
+	PMINUD:          "PMINUD",
+	PMINUW:          "PMINUW",
+	PMOVMSKB:        "PMOVMSKB",
+	PMOVSXBD:        "PMOVSXBD",
+	PMOVSXBQ:        "PMOVSXBQ",
+	PMOVSXBW:        "PMOVSXBW",
+	PMOVSXDQ:        "PMOVSXDQ",
+	PMOVSXWD:        "PMOVSXWD",
+	PMOVSXWQ:        "PMOVSXWQ",
+	PMOVZXBD:        "PMOVZXBD",
+	PMOVZXBQ:        "PMOVZXBQ",
+	PMOVZXBW:        "PMOVZXBW",
+	PMOVZXDQ:        "PMOVZXDQ",
+	PMOVZXWD:        "PMOVZXWD",
+	PMOVZXWQ:        "PMOVZXWQ",
+	PMULDQ:          "PMULDQ",
+	PMULHRSW:        "PMULHRSW",
+	PMULHUW:         "PMULHUW",
+	PMULHW:          "PMULHW",
+	PMULLD:          "PMULLD",
+	PMULLW:          "PMULLW",
+	PMULUDQ:         "PMULUDQ",
+	POP:             "POP",
+	POPA:            "POPA",
+	POPAD:           "POPAD",
+	POPCNT:          "POPCNT",
+	POPF:            "POPF",
+	POPFD:           "POPFD",
+	POPFQ:           "POPFQ",
+	POR:             "POR",
+	PREFETCHNTA:     "PREFETCHNTA",
+	PREFETCHT0:      "PREFETCHT0",
+	PREFETCHT1:      "PREFETCHT1",
+	PREFETCHT2:      "PREFETCHT2",
+	PREFETCHW:       "PREFETCHW",
+	PSADBW:          "PSADBW",
+	PSHUFB:          "PSHUFB",
+	PSHUFD:          "PSHUFD",
+	PSHUFHW:         "PSHUFHW",
+	PSHUFLW:         "PSHUFLW",
+	PSHUFW:          "PSHUFW",
+	PSIGNB:          "PSIGNB",
+	PSIGND:          "PSIGND",
+	PSIGNW:          "PSIGNW",
+	PSLLD:           "PSLLD",
+	PSLLDQ:          "PSLLDQ",
+	PSLLQ:           "PSLLQ",
+	PSLLW:           "PSLLW",
+	PSRAD:           "PSRAD",
+	PSRAW:           "PSRAW",
+	PSRLD:           "PSRLD",
+	PSRLDQ:          "PSRLDQ",
+	PSRLQ:           "PSRLQ",
+	PSRLW:           "PSRLW",
+	PSUBB:           "PSUBB",
+	PSUBD:           "PSUBD",
+	PSUBQ:           "PSUBQ",
+	PSUBSB:          "PSUBSB",
+	PSUBSW:          "PSUBSW",
+	PSUBUSB:         "PSUBUSB",
+	PSUBUSW:         "PSUBUSW",
+	PSUBW:           "PSUBW",
+	PTEST:           "PTEST",
+	PUNPCKHBW:       "PUNPCKHBW",
+	PUNPCKHDQ:       "PUNPCKHDQ",
+	PUNPCKHQDQ:      "PUNPCKHQDQ",
+	PUNPCKHWD:       "PUNPCKHWD",
+	PUNPCKLBW:       "PUNPCKLBW",
+	PUNPCKLDQ:       "PUNPCKLDQ",
+	PUNPCKLQDQ:      "PUNPCKLQDQ",
+	PUNPCKLWD:       "PUNPCKLWD",
+	PUSH:            "PUSH",
+	PUSHA:           "PUSHA",
+	PUSHAD:          "PUSHAD",
+	PUSHF:           "PUSHF",
+	PUSHFD:          "PUSHFD",
+	PUSHFQ:          "PUSHFQ",
+	PXOR:            "PXOR",
+	RCL:             "RCL",
+	RCPPS:           "RCPPS",
+	RCPSS:           "RCPSS",
+	RCR:             "RCR",
+	RDFSBASE:        "RDFSBASE",
+	RDGSBASE:        "RDGSBASE",
+	RDMSR:           "RDMSR",
+	RDPMC:           "RDPMC",
+	RDRAND:          "RDRAND",
+	RDTSC:           "RDTSC",
+	RDTSCP:          "RDTSCP",
+	RET:             "RET",
+	ROL:             "ROL",
+	ROR:             "ROR",
+	ROUNDPD:         "ROUNDPD",
+	ROUNDPS:         "ROUNDPS",
+	ROUNDSD:         "ROUNDSD",
+	ROUNDSS:         "ROUNDSS",
+	RSM:             "RSM",
+	RSQRTPS:         "RSQRTPS",
+	RSQRTSS:         "RSQRTSS",
+	SAHF:            "SAHF",
+	SAR:             "SAR",
+	SBB:             "SBB",
+	SCASB:           "SCASB",
+	SCASD:           "SCASD",
+	SCASQ:           "SCASQ",
+	SCASW:           "SCASW",
+	SETA:            "SETA",
+	SETAE:           "SETAE",
+	SETB:            "SETB",
+	SETBE:           "SETBE",
+	SETE:            "SETE",
+	SETG:            "SETG",
+	SETGE:           "SETGE",
+	SETL:            "SETL",
+	SETLE:           "SETLE",
+	SETNE:           "SETNE",
+	SETNO:           "SETNO",
+	SETNP:           "SETNP",
+	SETNS:           "SETNS",
+	SETO:            "SETO",
+	SETP:            "SETP",
+	SETS:            "SETS",
+	SFENCE:          "SFENCE",
+	SGDT:            "SGDT",
+	SHL:             "SHL",
+	SHLD:            "SHLD",
+	SHR:             "SHR",
+	SHRD:            "SHRD",
+	SHUFPD:          "SHUFPD",
+	SHUFPS:          "SHUFPS",
+	SIDT:            "SIDT",
+	SLDT:            "SLDT",
+	SMSW:            "SMSW",
+	SQRTPD:          "SQRTPD",
+	SQRTPS:          "SQRTPS",
+	SQRTSD:          "SQRTSD",
+	SQRTSS:          "SQRTSS",
+	STC:             "STC",
+	STD:             "STD",
+	STI:             "STI",
+	STMXCSR:         "STMXCSR",
+	STOSB:           "STOSB",
+	STOSD:           "STOSD",
+	STOSQ:           "STOSQ",
+	STOSW:           "STOSW",
+	STR:             "STR",
+	SUB:             "SUB",
+	SUBPD:           "SUBPD",
+	SUBPS:           "SUBPS",
+	SUBSD:           "SUBSD",
+	SUBSS:           "SUBSS",
+	SWAPGS:          "SWAPGS",
+	SYSCALL:         "SYSCALL",
+	SYSENTER:        "SYSENTER",
+	SYSEXIT:         "SYSEXIT",
+	SYSRET:          "SYSRET",
+	TEST:            "TEST",
+	TZCNT:           "TZCNT",
+	UCOMISD:         "UCOMISD",
+	UCOMISS:         "UCOMISS",
+	UD1:             "UD1",
+	UD2:             "UD2",
+	UNPCKHPD:        "UNPCKHPD",
+	UNPCKHPS:        "UNPCKHPS",
+	UNPCKLPD:        "UNPCKLPD",
+	UNPCKLPS:        "UNPCKLPS",
+	VERR:            "VERR",
+	VERW:            "VERW",
+	WBINVD:          "WBINVD",
+	WRFSBASE:        "WRFSBASE",
+	WRGSBASE:        "WRGSBASE",
+	WRMSR:           "WRMSR",
+	XABORT:          "XABORT",
+	XADD:            "XADD",
+	XBEGIN:          "XBEGIN",
+	XCHG:            "XCHG",
+	XEND:            "XEND",
+	XGETBV:          "XGETBV",
+	XLATB:           "XLATB",
+	XOR:             "XOR",
+	XORPD:           "XORPD",
+	XORPS:           "XORPS",
+	XRSTOR:          "XRSTOR",
+	XRSTOR64:        "XRSTOR64",
+	XRSTORS:         "XRSTORS",
+	XRSTORS64:       "XRSTORS64",
+	XSAVE:           "XSAVE",
+	XSAVE64:         "XSAVE64",
+	XSAVEC:          "XSAVEC",
+	XSAVEC64:        "XSAVEC64",
+	XSAVEOPT:        "XSAVEOPT",
+	XSAVEOPT64:      "XSAVEOPT64",
+	XSAVES:          "XSAVES",
+	XSAVES64:        "XSAVES64",
+	XSETBV:          "XSETBV",
+	XTEST:           "XTEST",
+}
diff --git a/src/cmd/internal/rsc.io/x86/x86asm/testdata/Makefile b/src/cmd/internal/rsc.io/x86/x86asm/testdata/Makefile
new file mode 100644
index 0000000..9cb4412
--- /dev/null
+++ b/src/cmd/internal/rsc.io/x86/x86asm/testdata/Makefile
@@ -0,0 +1,12 @@
+libmach8db: libmach8db.c
+	9c libmach8db.c && 9l -o libmach8db libmach8db.o; rm libmach8db.o
+
+newdecode.txt:
+	cd ..; go test -cover -run 'Objdump.*32' -v -timeout 10h -printtests 2>&1 | tee log
+	cd ..; go test -cover -run 'Objdump.*64' -v -timeout 10h -printtests 2>&1 | tee -a log
+	cd ..; go test -cover -run 'Xed.*32' -v -timeout 10h -printtests 2>&1 | tee -a log
+	cd ..; go test -cover -run 'Xed.*64' -v -timeout 10h -printtests 2>&1 | tee -a log
+	cd ..; go test -cover -run 'Plan9.*32' -v -timeout 10h -printtests 2>&1 | tee -a log
+	cd ..; go test -cover -run 'Plan9.*64' -v -timeout 10h -printtests 2>&1 | tee -a log
+	egrep '	(gnu|intel|plan9)	' ../log |sort >newdecode.txt
+
diff --git a/src/cmd/internal/rsc.io/x86/x86asm/testdata/decode.txt b/src/cmd/internal/rsc.io/x86/x86asm/testdata/decode.txt
new file mode 100644
index 0000000..a899d75
--- /dev/null
+++ b/src/cmd/internal/rsc.io/x86/x86asm/testdata/decode.txt
@@ -0,0 +1,6731 @@
+000511223344|556677885f5f5f5f5f5f	32	intel	add byte ptr [0x44332211], al
+000511223344|556677885f5f5f5f5f5f	64	gnu	add %al,0x44332211(%rip)
+000511223344|556677885f5f5f5f5f5f	64	intel	add byte ptr [rip+0x44332211], al
+0100|11223344556677885f5f5f5f5f5f	32	intel	add dword ptr [eax], eax
+0100|11223344556677885f5f5f5f5f5f	32	plan9	ADDL AX, 0(AX)
+0100|11223344556677885f5f5f5f5f5f	64	gnu	add %eax,(%rax)
+0100|11223344556677885f5f5f5f5f5f	64	intel	add dword ptr [rax], eax
+0100|11223344556677885f5f5f5f5f5f	64	plan9	ADDL AX, 0(AX)
+0211|223344556677885f5f5f5f5f5f5f	32	intel	add dl, byte ptr [ecx]
+0211|223344556677885f5f5f5f5f5f5f	32	plan9	ADDL 0(CX), DL
+0211|223344556677885f5f5f5f5f5f5f	64	gnu	add (%rcx),%dl
+0211|223344556677885f5f5f5f5f5f5f	64	intel	add dl, byte ptr [rcx]
+0211|223344556677885f5f5f5f5f5f5f	64	plan9	ADDL 0(CX), DL
+0311|223344556677885f5f5f5f5f5f5f	32	intel	add edx, dword ptr [ecx]
+0311|223344556677885f5f5f5f5f5f5f	32	plan9	ADDL 0(CX), DX
+0311|223344556677885f5f5f5f5f5f5f	64	gnu	add (%rcx),%edx
+0311|223344556677885f5f5f5f5f5f5f	64	intel	add edx, dword ptr [rcx]
+0311|223344556677885f5f5f5f5f5f5f	64	plan9	ADDL 0(CX), DX
+0411|223344556677885f5f5f5f5f5f5f	32	intel	add al, 0x11
+0411|223344556677885f5f5f5f5f5f5f	32	plan9	ADDL $0x11, AL
+0411|223344556677885f5f5f5f5f5f5f	64	gnu	add $0x11,%al
+0411|223344556677885f5f5f5f5f5f5f	64	intel	add al, 0x11
+0411|223344556677885f5f5f5f5f5f5f	64	plan9	ADDL $0x11, AL
+0511223344|556677885f5f5f5f5f5f5f	32	intel	add eax, 0x44332211
+0511223344|556677885f5f5f5f5f5f5f	32	plan9	ADDL $0x44332211, AX
+0511223344|556677885f5f5f5f5f5f5f	64	gnu	add $0x44332211,%eax
+0511223344|556677885f5f5f5f5f5f5f	64	intel	add eax, 0x44332211
+0511223344|556677885f5f5f5f5f5f5f	64	plan9	ADDL $0x44332211, AX
+06|11223344556677885f5f5f5f5f5f5f	32	intel	push es
+06|11223344556677885f5f5f5f5f5f5f	32	plan9	PUSHL ES
+06|11223344556677885f5f5f5f5f5f5f	64	gnu	error: unrecognized instruction
+06|11223344556677885f5f5f5f5f5f5f	64	intel	error: unrecognized instruction
+06|11223344556677885f5f5f5f5f5f5f	64	plan9	error: unrecognized instruction
+07|11223344556677885f5f5f5f5f5f5f	32	intel	pop es
+07|11223344556677885f5f5f5f5f5f5f	32	plan9	POPL ES
+07|11223344556677885f5f5f5f5f5f5f	64	gnu	error: unrecognized instruction
+07|11223344556677885f5f5f5f5f5f5f	64	intel	error: unrecognized instruction
+07|11223344556677885f5f5f5f5f5f5f	64	plan9	error: unrecognized instruction
+0811|223344556677885f5f5f5f5f5f5f	32	intel	or byte ptr [ecx], dl
+0811|223344556677885f5f5f5f5f5f5f	32	plan9	ORL DL, 0(CX)
+0811|223344556677885f5f5f5f5f5f5f	64	gnu	or %dl,(%rcx)
+0811|223344556677885f5f5f5f5f5f5f	64	intel	or byte ptr [rcx], dl
+0811|223344556677885f5f5f5f5f5f5f	64	plan9	ORL DL, 0(CX)
+0911|223344556677885f5f5f5f5f5f5f	32	intel	or dword ptr [ecx], edx
+0911|223344556677885f5f5f5f5f5f5f	32	plan9	ORL DX, 0(CX)
+0911|223344556677885f5f5f5f5f5f5f	64	gnu	or %edx,(%rcx)
+0911|223344556677885f5f5f5f5f5f5f	64	intel	or dword ptr [rcx], edx
+0911|223344556677885f5f5f5f5f5f5f	64	plan9	ORL DX, 0(CX)
+0a11|223344556677885f5f5f5f5f5f5f	32	intel	or dl, byte ptr [ecx]
+0a11|223344556677885f5f5f5f5f5f5f	32	plan9	ORL 0(CX), DL
+0a11|223344556677885f5f5f5f5f5f5f	64	gnu	or (%rcx),%dl
+0a11|223344556677885f5f5f5f5f5f5f	64	intel	or dl, byte ptr [rcx]
+0a11|223344556677885f5f5f5f5f5f5f	64	plan9	ORL 0(CX), DL
+0b11|223344556677885f5f5f5f5f5f5f	32	intel	or edx, dword ptr [ecx]
+0b11|223344556677885f5f5f5f5f5f5f	32	plan9	ORL 0(CX), DX
+0b11|223344556677885f5f5f5f5f5f5f	64	gnu	or (%rcx),%edx
+0b11|223344556677885f5f5f5f5f5f5f	64	intel	or edx, dword ptr [rcx]
+0b11|223344556677885f5f5f5f5f5f5f	64	plan9	ORL 0(CX), DX
+0c11|223344556677885f5f5f5f5f5f5f	32	intel	or al, 0x11
+0c11|223344556677885f5f5f5f5f5f5f	32	plan9	ORL $0x11, AL
+0c11|223344556677885f5f5f5f5f5f5f	64	gnu	or $0x11,%al
+0c11|223344556677885f5f5f5f5f5f5f	64	intel	or al, 0x11
+0c11|223344556677885f5f5f5f5f5f5f	64	plan9	ORL $0x11, AL
+0d11223344|556677885f5f5f5f5f5f5f	32	intel	or eax, 0x44332211
+0d11223344|556677885f5f5f5f5f5f5f	32	plan9	ORL $0x44332211, AX
+0d11223344|556677885f5f5f5f5f5f5f	64	gnu	or $0x44332211,%eax
+0d11223344|556677885f5f5f5f5f5f5f	64	intel	or eax, 0x44332211
+0d11223344|556677885f5f5f5f5f5f5f	64	plan9	ORL $0x44332211, AX
+0e|11223344556677885f5f5f5f5f5f5f	32	intel	push cs
+0e|11223344556677885f5f5f5f5f5f5f	32	plan9	PUSHL CS
+0e|11223344556677885f5f5f5f5f5f5f	64	gnu	error: unrecognized instruction
+0e|11223344556677885f5f5f5f5f5f5f	64	intel	error: unrecognized instruction
+0e|11223344556677885f5f5f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f0000|11223344556677885f5f5f5f5f	32	intel	sldt word ptr [eax]
+0f0000|11223344556677885f5f5f5f5f	32	plan9	SLDT 0(AX)
+0f0000|11223344556677885f5f5f5f5f	64	gnu	sldt (%rax)
+0f0000|11223344556677885f5f5f5f5f	64	intel	sldt word ptr [rax]
+0f0000|11223344556677885f5f5f5f5f	64	plan9	SLDT 0(AX)
+0f0008|11223344556677885f5f5f5f5f	32	intel	str word ptr [eax]
+0f0008|11223344556677885f5f5f5f5f	32	plan9	STR 0(AX)
+0f0008|11223344556677885f5f5f5f5f	64	gnu	str (%rax)
+0f0008|11223344556677885f5f5f5f5f	64	intel	str word ptr [rax]
+0f0008|11223344556677885f5f5f5f5f	64	plan9	STR 0(AX)
+0f0011|223344556677885f5f5f5f5f5f	32	intel	lldt word ptr [ecx]
+0f0011|223344556677885f5f5f5f5f5f	32	plan9	LLDT 0(CX)
+0f0011|223344556677885f5f5f5f5f5f	64	gnu	lldt (%rcx)
+0f0011|223344556677885f5f5f5f5f5f	64	intel	lldt word ptr [rcx]
+0f0011|223344556677885f5f5f5f5f5f	64	plan9	LLDT 0(CX)
+0f0018|11223344556677885f5f5f5f5f	32	intel	ltr word ptr [eax]
+0f0018|11223344556677885f5f5f5f5f	32	plan9	LTR 0(AX)
+0f0018|11223344556677885f5f5f5f5f	64	gnu	ltr (%rax)
+0f0018|11223344556677885f5f5f5f5f	64	intel	ltr word ptr [rax]
+0f0018|11223344556677885f5f5f5f5f	64	plan9	LTR 0(AX)
+0f0020|11223344556677885f5f5f5f5f	32	intel	verr word ptr [eax]
+0f0020|11223344556677885f5f5f5f5f	32	plan9	VERR 0(AX)
+0f0020|11223344556677885f5f5f5f5f	64	gnu	verr (%rax)
+0f0020|11223344556677885f5f5f5f5f	64	intel	verr word ptr [rax]
+0f0020|11223344556677885f5f5f5f5f	64	plan9	VERR 0(AX)
+0f0028|11223344556677885f5f5f5f5f	32	intel	verw word ptr [eax]
+0f0028|11223344556677885f5f5f5f5f	32	plan9	VERW 0(AX)
+0f0028|11223344556677885f5f5f5f5f	64	gnu	verw (%rax)
+0f0028|11223344556677885f5f5f5f5f	64	intel	verw word ptr [rax]
+0f0028|11223344556677885f5f5f5f5f	64	plan9	VERW 0(AX)
+0f0030|11223344556677885f5f5f5f5f	32	intel	error: unrecognized instruction
+0f0030|11223344556677885f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f0100|11223344556677885f5f5f5f5f	32	intel	sgdt ptr [eax]
+0f0100|11223344556677885f5f5f5f5f	32	plan9	SGDT 0(AX)
+0f0100|11223344556677885f5f5f5f5f	64	gnu	sgdtl (%rax)
+0f0100|11223344556677885f5f5f5f5f	64	intel	sgdt ptr [rax]
+0f0100|11223344556677885f5f5f5f5f	64	plan9	SGDT 0(AX)
+0f0108|11223344556677885f5f5f5f5f	32	intel	sidt ptr [eax]
+0f0108|11223344556677885f5f5f5f5f	32	plan9	SIDT 0(AX)
+0f0108|11223344556677885f5f5f5f5f	64	gnu	sidtl (%rax)
+0f0108|11223344556677885f5f5f5f5f	64	intel	sidt ptr [rax]
+0f0108|11223344556677885f5f5f5f5f	64	plan9	SIDT 0(AX)
+0f0111|223344556677885f5f5f5f5f5f	32	intel	lgdt ptr [ecx]
+0f0111|223344556677885f5f5f5f5f5f	32	plan9	LGDT 0(CX)
+0f0111|223344556677885f5f5f5f5f5f	64	gnu	lgdtl (%rcx)
+0f0111|223344556677885f5f5f5f5f5f	64	intel	lgdt ptr [rcx]
+0f0111|223344556677885f5f5f5f5f5f	64	plan9	LGDT 0(CX)
+0f0118|11223344556677885f5f5f5f5f	32	intel	lidt ptr [eax]
+0f0118|11223344556677885f5f5f5f5f	32	plan9	LIDT 0(AX)
+0f0118|11223344556677885f5f5f5f5f	64	gnu	lidtl (%rax)
+0f0118|11223344556677885f5f5f5f5f	64	intel	lidt ptr [rax]
+0f0118|11223344556677885f5f5f5f5f	64	plan9	LIDT 0(AX)
+0f0120|11223344556677885f5f5f5f5f	32	intel	smsw word ptr [eax]
+0f0120|11223344556677885f5f5f5f5f	32	plan9	SMSW 0(AX)
+0f0120|11223344556677885f5f5f5f5f	64	gnu	smsw (%rax)
+0f0120|11223344556677885f5f5f5f5f	64	intel	smsw word ptr [rax]
+0f0120|11223344556677885f5f5f5f5f	64	plan9	SMSW 0(AX)
+0f0130|11223344556677885f5f5f5f5f	32	intel	lmsw word ptr [eax]
+0f0130|11223344556677885f5f5f5f5f	32	plan9	LMSW 0(AX)
+0f0130|11223344556677885f5f5f5f5f	64	gnu	lmsw (%rax)
+0f0130|11223344556677885f5f5f5f5f	64	intel	lmsw word ptr [rax]
+0f0130|11223344556677885f5f5f5f5f	64	plan9	LMSW 0(AX)
+0f0138|11223344556677885f5f5f5f5f	32	intel	invlpg byte ptr [eax]
+0f0138|11223344556677885f5f5f5f5f	32	plan9	INVLPG 0(AX)
+0f0138|11223344556677885f5f5f5f5f	64	gnu	invlpg (%rax)
+0f0138|11223344556677885f5f5f5f5f	64	intel	invlpg byte ptr [rax]
+0f0138|11223344556677885f5f5f5f5f	64	plan9	INVLPG 0(AX)
+0f01c8|11223344556677885f5f5f5f5f	32	intel	monitor
+0f01c8|11223344556677885f5f5f5f5f	32	plan9	MONITOR
+0f01c8|11223344556677885f5f5f5f5f	64	gnu	monitor %eax,%ecx,%edx
+0f01c8|11223344556677885f5f5f5f5f	64	intel	monitor
+0f01c8|11223344556677885f5f5f5f5f	64	plan9	MONITOR
+0f01c9|11223344556677885f5f5f5f5f	32	intel	mwait
+0f01c9|11223344556677885f5f5f5f5f	32	plan9	MWAIT
+0f01c9|11223344556677885f5f5f5f5f	64	gnu	mwait %rax,%rcx
+0f01c9|11223344556677885f5f5f5f5f	64	intel	mwait
+0f01c9|11223344556677885f5f5f5f5f	64	plan9	MWAIT
+0f01d0|11223344556677885f5f5f5f5f	32	intel	xgetbv
+0f01d0|11223344556677885f5f5f5f5f	32	plan9	XGETBV
+0f01d0|11223344556677885f5f5f5f5f	64	gnu	xgetbv
+0f01d0|11223344556677885f5f5f5f5f	64	intel	xgetbv
+0f01d0|11223344556677885f5f5f5f5f	64	plan9	XGETBV
+0f01d1|11223344556677885f5f5f5f5f	32	intel	xsetbv
+0f01d1|11223344556677885f5f5f5f5f	32	plan9	XSETBV
+0f01d1|11223344556677885f5f5f5f5f	64	gnu	xsetbv
+0f01d1|11223344556677885f5f5f5f5f	64	intel	xsetbv
+0f01d1|11223344556677885f5f5f5f5f	64	plan9	XSETBV
+0f01d5|11223344556677885f5f5f5f5f	32	intel	xend
+0f01d5|11223344556677885f5f5f5f5f	32	plan9	XEND
+0f01d5|11223344556677885f5f5f5f5f	64	gnu	xend
+0f01d5|11223344556677885f5f5f5f5f	64	intel	xend
+0f01d5|11223344556677885f5f5f5f5f	64	plan9	XEND
+0f01d6|11223344556677885f5f5f5f5f	32	intel	xtest
+0f01d6|11223344556677885f5f5f5f5f	32	plan9	XTEST
+0f01d6|11223344556677885f5f5f5f5f	64	gnu	xtest
+0f01d6|11223344556677885f5f5f5f5f	64	intel	xtest
+0f01d6|11223344556677885f5f5f5f5f	64	plan9	XTEST
+0f01f8|11223344556677885f5f5f5f5f	32	intel	error: unrecognized instruction
+0f01f8|11223344556677885f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f01f8|11223344556677885f5f5f5f5f	64	gnu	swapgs
+0f01f8|11223344556677885f5f5f5f5f	64	intel	swapgs
+0f01f8|11223344556677885f5f5f5f5f	64	plan9	SWAPGS
+0f01f9|11223344556677885f5f5f5f5f	32	intel	rdtscp
+0f01f9|11223344556677885f5f5f5f5f	32	plan9	RDTSCP
+0f01f9|11223344556677885f5f5f5f5f	64	gnu	rdtscp
+0f01f9|11223344556677885f5f5f5f5f	64	intel	rdtscp
+0f01f9|11223344556677885f5f5f5f5f	64	plan9	RDTSCP
+0f0211|223344556677885f5f5f5f5f5f	32	intel	lar edx, word ptr [ecx]
+0f0211|223344556677885f5f5f5f5f5f	32	plan9	LAR 0(CX), DX
+0f0211|223344556677885f5f5f5f5f5f	64	gnu	lar (%rcx),%edx
+0f0211|223344556677885f5f5f5f5f5f	64	intel	lar edx, word ptr [rcx]
+0f0211|223344556677885f5f5f5f5f5f	64	plan9	LAR 0(CX), DX
+0f0311|223344556677885f5f5f5f5f5f	32	intel	lsl edx, word ptr [ecx]
+0f0311|223344556677885f5f5f5f5f5f	32	plan9	LSL 0(CX), DX
+0f0311|223344556677885f5f5f5f5f5f	64	gnu	lsl (%rcx),%edx
+0f0311|223344556677885f5f5f5f5f5f	64	intel	lsl edx, word ptr [rcx]
+0f0311|223344556677885f5f5f5f5f5f	64	plan9	LSL 0(CX), DX
+0f04|11223344556677885f5f5f5f5f5f	32	intel	error: unrecognized instruction
+0f04|11223344556677885f5f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f04|11223344556677885f5f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f04|11223344556677885f5f5f5f5f5f	64	intel	error: unrecognized instruction
+0f04|11223344556677885f5f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f05|11223344556677885f5f5f5f5f5f	32	intel	error: unrecognized instruction
+0f05|11223344556677885f5f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f05|11223344556677885f5f5f5f5f5f	64	gnu	syscall
+0f05|11223344556677885f5f5f5f5f5f	64	intel	syscall
+0f05|11223344556677885f5f5f5f5f5f	64	plan9	SYSCALL
+0f06|11223344556677885f5f5f5f5f5f	32	intel	clts
+0f06|11223344556677885f5f5f5f5f5f	32	plan9	CLTS
+0f06|11223344556677885f5f5f5f5f5f	64	gnu	clts
+0f06|11223344556677885f5f5f5f5f5f	64	intel	clts
+0f06|11223344556677885f5f5f5f5f5f	64	plan9	CLTS
+0f07|11223344556677885f5f5f5f5f5f	32	intel	error: unrecognized instruction
+0f07|11223344556677885f5f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f07|11223344556677885f5f5f5f5f5f	64	gnu	sysretq
+0f07|11223344556677885f5f5f5f5f5f	64	intel	sysret
+0f07|11223344556677885f5f5f5f5f5f	64	plan9	SYSRET
+0f08|11223344556677885f5f5f5f5f5f	32	intel	invd
+0f08|11223344556677885f5f5f5f5f5f	32	plan9	INVD
+0f08|11223344556677885f5f5f5f5f5f	64	gnu	invd
+0f08|11223344556677885f5f5f5f5f5f	64	intel	invd
+0f08|11223344556677885f5f5f5f5f5f	64	plan9	INVD
+0f09|11223344556677885f5f5f5f5f5f	32	intel	wbinvd
+0f09|11223344556677885f5f5f5f5f5f	32	plan9	WBINVD
+0f09|11223344556677885f5f5f5f5f5f	64	gnu	wbinvd
+0f09|11223344556677885f5f5f5f5f5f	64	intel	wbinvd
+0f09|11223344556677885f5f5f5f5f5f	64	plan9	WBINVD
+0f0b|11223344556677885f5f5f5f5f5f	32	intel	ud2
+0f0b|11223344556677885f5f5f5f5f5f	32	plan9	UD2
+0f0b|11223344556677885f5f5f5f5f5f	64	gnu	ud2
+0f0b|11223344556677885f5f5f5f5f5f	64	intel	ud2
+0f0b|11223344556677885f5f5f5f5f5f	64	plan9	UD2
+0f0d08|11223344556677885f5f5f5f5f	32	intel	prefetchw zmmword ptr [eax]
+0f0d08|11223344556677885f5f5f5f5f	32	plan9	PREFETCHW 0(AX)
+0f0d08|11223344556677885f5f5f5f5f	64	gnu	prefetchw (%rax)
+0f0d08|11223344556677885f5f5f5f5f	64	intel	prefetchw zmmword ptr [rax]
+0f0d08|11223344556677885f5f5f5f5f	64	plan9	PREFETCHW 0(AX)
+0f1011|223344556677885f5f5f5f5f5f	32	intel	movups xmm2, xmmword ptr [ecx]
+0f1011|223344556677885f5f5f5f5f5f	32	plan9	MOVUPS 0(CX), X2
+0f1011|223344556677885f5f5f5f5f5f	64	gnu	movups (%rcx),%xmm2
+0f1011|223344556677885f5f5f5f5f5f	64	intel	movups xmm2, xmmword ptr [rcx]
+0f1011|223344556677885f5f5f5f5f5f	64	plan9	MOVUPS 0(CX), X2
+0f1122|3344556677885f5f5f5f5f5f5f	32	intel	movups xmmword ptr [edx], xmm4
+0f1122|3344556677885f5f5f5f5f5f5f	32	plan9	MOVUPS X4, 0(DX)
+0f1122|3344556677885f5f5f5f5f5f5f	64	gnu	movups %xmm4,(%rdx)
+0f1122|3344556677885f5f5f5f5f5f5f	64	intel	movups xmmword ptr [rdx], xmm4
+0f1122|3344556677885f5f5f5f5f5f5f	64	plan9	MOVUPS X4, 0(DX)
+0f1211|223344556677885f5f5f5f5f5f	32	intel	movlps xmm2, qword ptr [ecx]
+0f1211|223344556677885f5f5f5f5f5f	32	plan9	MOVLPS 0(CX), X2
+0f1211|223344556677885f5f5f5f5f5f	64	gnu	movlps (%rcx),%xmm2
+0f1211|223344556677885f5f5f5f5f5f	64	intel	movlps xmm2, qword ptr [rcx]
+0f1211|223344556677885f5f5f5f5f5f	64	plan9	MOVLPS 0(CX), X2
+0f12c0|11223344556677885f5f5f5f5f	32	intel	movhlps xmm0, xmm0
+0f12c0|11223344556677885f5f5f5f5f	32	plan9	MOVHLPS X0, X0
+0f12c0|11223344556677885f5f5f5f5f	64	gnu	movhlps %xmm0,%xmm0
+0f12c0|11223344556677885f5f5f5f5f	64	intel	movhlps xmm0, xmm0
+0f12c0|11223344556677885f5f5f5f5f	64	plan9	MOVHLPS X0, X0
+0f1311|223344556677885f5f5f5f5f5f	32	intel	movlps qword ptr [ecx], xmm2
+0f1311|223344556677885f5f5f5f5f5f	32	plan9	MOVLPS X2, 0(CX)
+0f1311|223344556677885f5f5f5f5f5f	64	gnu	movlps %xmm2,(%rcx)
+0f1311|223344556677885f5f5f5f5f5f	64	intel	movlps qword ptr [rcx], xmm2
+0f1311|223344556677885f5f5f5f5f5f	64	plan9	MOVLPS X2, 0(CX)
+0f1411|223344556677885f5f5f5f5f5f	32	intel	unpcklps xmm2, xmmword ptr [ecx]
+0f1411|223344556677885f5f5f5f5f5f	32	plan9	UNPCKLPS 0(CX), X2
+0f1411|223344556677885f5f5f5f5f5f	64	gnu	unpcklps (%rcx),%xmm2
+0f1411|223344556677885f5f5f5f5f5f	64	intel	unpcklps xmm2, xmmword ptr [rcx]
+0f1411|223344556677885f5f5f5f5f5f	64	plan9	UNPCKLPS 0(CX), X2
+0f1511|223344556677885f5f5f5f5f5f	32	intel	unpckhps xmm2, xmmword ptr [ecx]
+0f1511|223344556677885f5f5f5f5f5f	32	plan9	UNPCKHPS 0(CX), X2
+0f1511|223344556677885f5f5f5f5f5f	64	gnu	unpckhps (%rcx),%xmm2
+0f1511|223344556677885f5f5f5f5f5f	64	intel	unpckhps xmm2, xmmword ptr [rcx]
+0f1511|223344556677885f5f5f5f5f5f	64	plan9	UNPCKHPS 0(CX), X2
+0f1611|223344556677885f5f5f5f5f5f	32	intel	movhps xmm2, qword ptr [ecx]
+0f1611|223344556677885f5f5f5f5f5f	32	plan9	MOVHPS 0(CX), X2
+0f1611|223344556677885f5f5f5f5f5f	64	gnu	movhps (%rcx),%xmm2
+0f1611|223344556677885f5f5f5f5f5f	64	intel	movhps xmm2, qword ptr [rcx]
+0f1611|223344556677885f5f5f5f5f5f	64	plan9	MOVHPS 0(CX), X2
+0f16c0|11223344556677885f5f5f5f5f	32	intel	movlhps xmm0, xmm0
+0f16c0|11223344556677885f5f5f5f5f	32	plan9	MOVLHPS X0, X0
+0f16c0|11223344556677885f5f5f5f5f	64	gnu	movlhps %xmm0,%xmm0
+0f16c0|11223344556677885f5f5f5f5f	64	intel	movlhps xmm0, xmm0
+0f16c0|11223344556677885f5f5f5f5f	64	plan9	MOVLHPS X0, X0
+0f1711|223344556677885f5f5f5f5f5f	32	intel	movhps qword ptr [ecx], xmm2
+0f1711|223344556677885f5f5f5f5f5f	32	plan9	MOVHPS X2, 0(CX)
+0f1711|223344556677885f5f5f5f5f5f	64	gnu	movhps %xmm2,(%rcx)
+0f1711|223344556677885f5f5f5f5f5f	64	intel	movhps qword ptr [rcx], xmm2
+0f1711|223344556677885f5f5f5f5f5f	64	plan9	MOVHPS X2, 0(CX)
+0f1800|11223344556677885f5f5f5f5f	32	intel	prefetchnta zmmword ptr [eax]
+0f1800|11223344556677885f5f5f5f5f	32	plan9	PREFETCHNTA 0(AX)
+0f1800|11223344556677885f5f5f5f5f	64	gnu	prefetchnta (%rax)
+0f1800|11223344556677885f5f5f5f5f	64	intel	prefetchnta zmmword ptr [rax]
+0f1800|11223344556677885f5f5f5f5f	64	plan9	PREFETCHNTA 0(AX)
+0f1808|11223344556677885f5f5f5f5f	32	intel	prefetcht0 zmmword ptr [eax]
+0f1808|11223344556677885f5f5f5f5f	32	plan9	PREFETCHT0 0(AX)
+0f1808|11223344556677885f5f5f5f5f	64	gnu	prefetcht0 (%rax)
+0f1808|11223344556677885f5f5f5f5f	64	intel	prefetcht0 zmmword ptr [rax]
+0f1808|11223344556677885f5f5f5f5f	64	plan9	PREFETCHT0 0(AX)
+0f1811|223344556677885f5f5f5f5f5f	32	intel	prefetcht1 zmmword ptr [ecx]
+0f1811|223344556677885f5f5f5f5f5f	32	plan9	PREFETCHT1 0(CX)
+0f1811|223344556677885f5f5f5f5f5f	64	gnu	prefetcht1 (%rcx)
+0f1811|223344556677885f5f5f5f5f5f	64	intel	prefetcht1 zmmword ptr [rcx]
+0f1811|223344556677885f5f5f5f5f5f	64	plan9	PREFETCHT1 0(CX)
+0f1818|11223344556677885f5f5f5f5f	32	intel	prefetcht2 zmmword ptr [eax]
+0f1818|11223344556677885f5f5f5f5f	32	plan9	PREFETCHT2 0(AX)
+0f1818|11223344556677885f5f5f5f5f	64	gnu	prefetcht2 (%rax)
+0f1818|11223344556677885f5f5f5f5f	64	intel	prefetcht2 zmmword ptr [rax]
+0f1818|11223344556677885f5f5f5f5f	64	plan9	PREFETCHT2 0(AX)
+0f1f00|11223344556677885f5f5f5f5f	32	intel	nop dword ptr [eax], eax
+0f1f00|11223344556677885f5f5f5f5f	32	plan9	NOPL 0(AX)
+0f1f00|11223344556677885f5f5f5f5f	64	gnu	nopl (%rax)
+0f1f00|11223344556677885f5f5f5f5f	64	intel	nop dword ptr [rax], eax
+0f1f00|11223344556677885f5f5f5f5f	64	plan9	NOPL 0(AX)
+0f2011|223344556677885f5f5f5f5f5f	32	intel	mov ecx, cr2
+0f2011|223344556677885f5f5f5f5f5f	32	plan9	MOVL CR2, CX
+0f2011|223344556677885f5f5f5f5f5f	64	gnu	mov %cr2,%rcx
+0f2011|223344556677885f5f5f5f5f5f	64	intel	mov rcx, cr2
+0f2011|223344556677885f5f5f5f5f5f	64	plan9	MOVL CR2, CX
+0f2111|223344556677885f5f5f5f5f5f	32	intel	mov ecx, dr2
+0f2111|223344556677885f5f5f5f5f5f	32	plan9	MOVL DR2, CX
+0f2111|223344556677885f5f5f5f5f5f	64	gnu	mov %db2,%rcx
+0f2111|223344556677885f5f5f5f5f5f	64	intel	mov rcx, dr2
+0f2111|223344556677885f5f5f5f5f5f	64	plan9	MOVL DR2, CX
+0f2211|223344556677885f5f5f5f5f5f	32	intel	mov cr2, ecx
+0f2211|223344556677885f5f5f5f5f5f	32	plan9	MOVL CX, CR2
+0f2211|223344556677885f5f5f5f5f5f	64	gnu	mov %rcx,%cr2
+0f2211|223344556677885f5f5f5f5f5f	64	intel	mov cr2, rcx
+0f2211|223344556677885f5f5f5f5f5f	64	plan9	MOVL CX, CR2
+0f2311|223344556677885f5f5f5f5f5f	32	intel	mov dr2, ecx
+0f2311|223344556677885f5f5f5f5f5f	32	plan9	MOVL CX, DR2
+0f2311|223344556677885f5f5f5f5f5f	64	gnu	mov %rcx,%db2
+0f2311|223344556677885f5f5f5f5f5f	64	intel	mov dr2, rcx
+0f2311|223344556677885f5f5f5f5f5f	64	plan9	MOVL CX, DR2
+0f2411|223344556677885f5f5f5f5f5f	32	intel	mov ecx, tr2
+0f2411|223344556677885f5f5f5f5f5f	32	plan9	MOVL TR2, CX
+0f2411|223344556677885f5f5f5f5f5f	64	gnu	mov %tr2,%rcx
+0f2411|223344556677885f5f5f5f5f5f	64	intel	mov rcx, tr2
+0f2411|223344556677885f5f5f5f5f5f	64	plan9	MOVL TR2, CX
+0f2611|223344556677885f5f5f5f5f5f	32	intel	mov tr2, ecx
+0f2611|223344556677885f5f5f5f5f5f	32	plan9	MOVL CX, TR2
+0f2611|223344556677885f5f5f5f5f5f	64	gnu	mov %rcx,%tr2
+0f2611|223344556677885f5f5f5f5f5f	64	intel	mov tr2, rcx
+0f2611|223344556677885f5f5f5f5f5f	64	plan9	MOVL CX, TR2
+0f2811|223344556677885f5f5f5f5f5f	32	intel	movaps xmm2, xmmword ptr [ecx]
+0f2811|223344556677885f5f5f5f5f5f	32	plan9	MOVAPS 0(CX), X2
+0f2811|223344556677885f5f5f5f5f5f	64	gnu	movaps (%rcx),%xmm2
+0f2811|223344556677885f5f5f5f5f5f	64	intel	movaps xmm2, xmmword ptr [rcx]
+0f2811|223344556677885f5f5f5f5f5f	64	plan9	MOVAPS 0(CX), X2
+0f2911|223344556677885f5f5f5f5f5f	32	intel	movaps xmmword ptr [ecx], xmm2
+0f2911|223344556677885f5f5f5f5f5f	32	plan9	MOVAPS X2, 0(CX)
+0f2911|223344556677885f5f5f5f5f5f	64	gnu	movaps %xmm2,(%rcx)
+0f2911|223344556677885f5f5f5f5f5f	64	intel	movaps xmmword ptr [rcx], xmm2
+0f2911|223344556677885f5f5f5f5f5f	64	plan9	MOVAPS X2, 0(CX)
+0f2a11|223344556677885f5f5f5f5f5f	32	intel	cvtpi2ps xmm2, qword ptr [ecx]
+0f2a11|223344556677885f5f5f5f5f5f	32	plan9	CVTPI2PS 0(CX), X2
+0f2a11|223344556677885f5f5f5f5f5f	64	gnu	cvtpi2ps (%rcx),%xmm2
+0f2a11|223344556677885f5f5f5f5f5f	64	intel	cvtpi2ps xmm2, qword ptr [rcx]
+0f2a11|223344556677885f5f5f5f5f5f	64	plan9	CVTPI2PS 0(CX), X2
+0f2b11|223344556677885f5f5f5f5f5f	32	intel	movntps xmmword ptr [ecx], xmm2
+0f2b11|223344556677885f5f5f5f5f5f	32	plan9	MOVNTPS X2, 0(CX)
+0f2b11|223344556677885f5f5f5f5f5f	64	gnu	movntps %xmm2,(%rcx)
+0f2b11|223344556677885f5f5f5f5f5f	64	intel	movntps xmmword ptr [rcx], xmm2
+0f2b11|223344556677885f5f5f5f5f5f	64	plan9	MOVNTPS X2, 0(CX)
+0f2c11|223344556677885f5f5f5f5f5f	32	intel	cvttps2pi mmx2, qword ptr [ecx]
+0f2c11|223344556677885f5f5f5f5f5f	32	plan9	CVTTPS2PI 0(CX), M2
+0f2c11|223344556677885f5f5f5f5f5f	64	gnu	cvttps2pi (%rcx),%mm2
+0f2c11|223344556677885f5f5f5f5f5f	64	intel	cvttps2pi mmx2, qword ptr [rcx]
+0f2c11|223344556677885f5f5f5f5f5f	64	plan9	CVTTPS2PI 0(CX), M2
+0f2d11|223344556677885f5f5f5f5f5f	32	intel	cvtps2pi mmx2, qword ptr [ecx]
+0f2d11|223344556677885f5f5f5f5f5f	32	plan9	CVTPS2PI 0(CX), M2
+0f2d11|223344556677885f5f5f5f5f5f	64	gnu	cvtps2pi (%rcx),%mm2
+0f2d11|223344556677885f5f5f5f5f5f	64	intel	cvtps2pi mmx2, qword ptr [rcx]
+0f2d11|223344556677885f5f5f5f5f5f	64	plan9	CVTPS2PI 0(CX), M2
+0f2e11|223344556677885f5f5f5f5f5f	32	intel	ucomiss xmm2, dword ptr [ecx]
+0f2e11|223344556677885f5f5f5f5f5f	32	plan9	UCOMISS 0(CX), X2
+0f2e11|223344556677885f5f5f5f5f5f	64	gnu	ucomiss (%rcx),%xmm2
+0f2e11|223344556677885f5f5f5f5f5f	64	intel	ucomiss xmm2, dword ptr [rcx]
+0f2e11|223344556677885f5f5f5f5f5f	64	plan9	UCOMISS 0(CX), X2
+0f2f11|223344556677885f5f5f5f5f5f	32	intel	comiss xmm2, dword ptr [ecx]
+0f2f11|223344556677885f5f5f5f5f5f	32	plan9	COMISS 0(CX), X2
+0f2f11|223344556677885f5f5f5f5f5f	64	gnu	comiss (%rcx),%xmm2
+0f2f11|223344556677885f5f5f5f5f5f	64	intel	comiss xmm2, dword ptr [rcx]
+0f2f11|223344556677885f5f5f5f5f5f	64	plan9	COMISS 0(CX), X2
+0f30|11223344556677885f5f5f5f5f5f	32	intel	wrmsr
+0f30|11223344556677885f5f5f5f5f5f	32	plan9	WRMSR
+0f30|11223344556677885f5f5f5f5f5f	64	gnu	wrmsr
+0f30|11223344556677885f5f5f5f5f5f	64	intel	wrmsr
+0f30|11223344556677885f5f5f5f5f5f	64	plan9	WRMSR
+0f31|11223344556677885f5f5f5f5f5f	32	intel	rdtsc
+0f31|11223344556677885f5f5f5f5f5f	32	plan9	RDTSC
+0f31|11223344556677885f5f5f5f5f5f	64	gnu	rdtsc
+0f31|11223344556677885f5f5f5f5f5f	64	intel	rdtsc
+0f31|11223344556677885f5f5f5f5f5f	64	plan9	RDTSC
+0f32|11223344556677885f5f5f5f5f5f	32	intel	rdmsr
+0f32|11223344556677885f5f5f5f5f5f	32	plan9	RDMSR
+0f32|11223344556677885f5f5f5f5f5f	64	gnu	rdmsr
+0f32|11223344556677885f5f5f5f5f5f	64	intel	rdmsr
+0f32|11223344556677885f5f5f5f5f5f	64	plan9	RDMSR
+0f33|11223344556677885f5f5f5f5f5f	32	intel	rdpmc
+0f33|11223344556677885f5f5f5f5f5f	32	plan9	RDPMC
+0f33|11223344556677885f5f5f5f5f5f	64	gnu	rdpmc
+0f33|11223344556677885f5f5f5f5f5f	64	intel	rdpmc
+0f33|11223344556677885f5f5f5f5f5f	64	plan9	RDPMC
+0f34|11223344556677885f5f5f5f5f5f	32	intel	sysenter
+0f34|11223344556677885f5f5f5f5f5f	32	plan9	SYSENTER
+0f34|11223344556677885f5f5f5f5f5f	64	gnu	sysenter
+0f34|11223344556677885f5f5f5f5f5f	64	intel	sysenter
+0f34|11223344556677885f5f5f5f5f5f	64	plan9	SYSENTER
+0f35|11223344556677885f5f5f5f5f5f	32	intel	sysexit
+0f35|11223344556677885f5f5f5f5f5f	32	plan9	SYSEXIT
+0f35|11223344556677885f5f5f5f5f5f	64	gnu	sysexit
+0f35|11223344556677885f5f5f5f5f5f	64	intel	sysexit
+0f35|11223344556677885f5f5f5f5f5f	64	plan9	SYSEXIT
+0f380011|223344556677885f5f5f5f5f	32	intel	pshufb mmx2, qword ptr [ecx]
+0f380011|223344556677885f5f5f5f5f	32	plan9	PSHUFB 0(CX), M2
+0f380011|223344556677885f5f5f5f5f	64	gnu	pshufb (%rcx),%mm2
+0f380011|223344556677885f5f5f5f5f	64	intel	pshufb mmx2, qword ptr [rcx]
+0f380011|223344556677885f5f5f5f5f	64	plan9	PSHUFB 0(CX), M2
+0f380111|223344556677885f5f5f5f5f	32	intel	phaddw mmx2, qword ptr [ecx]
+0f380111|223344556677885f5f5f5f5f	32	plan9	PHADDW 0(CX), M2
+0f380111|223344556677885f5f5f5f5f	64	gnu	phaddw (%rcx),%mm2
+0f380111|223344556677885f5f5f5f5f	64	intel	phaddw mmx2, qword ptr [rcx]
+0f380111|223344556677885f5f5f5f5f	64	plan9	PHADDW 0(CX), M2
+0f380211|223344556677885f5f5f5f5f	32	intel	phaddd mmx2, qword ptr [ecx]
+0f380211|223344556677885f5f5f5f5f	32	plan9	PHADDD 0(CX), M2
+0f380211|223344556677885f5f5f5f5f	64	gnu	phaddd (%rcx),%mm2
+0f380211|223344556677885f5f5f5f5f	64	intel	phaddd mmx2, qword ptr [rcx]
+0f380211|223344556677885f5f5f5f5f	64	plan9	PHADDD 0(CX), M2
+0f380311|223344556677885f5f5f5f5f	32	intel	phaddsw mmx2, qword ptr [ecx]
+0f380311|223344556677885f5f5f5f5f	32	plan9	PHADDSW 0(CX), M2
+0f380311|223344556677885f5f5f5f5f	64	gnu	phaddsw (%rcx),%mm2
+0f380311|223344556677885f5f5f5f5f	64	intel	phaddsw mmx2, qword ptr [rcx]
+0f380311|223344556677885f5f5f5f5f	64	plan9	PHADDSW 0(CX), M2
+0f380411|223344556677885f5f5f5f5f	32	intel	pmaddubsw mmx2, qword ptr [ecx]
+0f380411|223344556677885f5f5f5f5f	32	plan9	PMADDUBSW 0(CX), M2
+0f380411|223344556677885f5f5f5f5f	64	gnu	pmaddubsw (%rcx),%mm2
+0f380411|223344556677885f5f5f5f5f	64	intel	pmaddubsw mmx2, qword ptr [rcx]
+0f380411|223344556677885f5f5f5f5f	64	plan9	PMADDUBSW 0(CX), M2
+0f380511|223344556677885f5f5f5f5f	32	intel	phsubw mmx2, qword ptr [ecx]
+0f380511|223344556677885f5f5f5f5f	32	plan9	PHSUBW 0(CX), M2
+0f380511|223344556677885f5f5f5f5f	64	gnu	phsubw (%rcx),%mm2
+0f380511|223344556677885f5f5f5f5f	64	intel	phsubw mmx2, qword ptr [rcx]
+0f380511|223344556677885f5f5f5f5f	64	plan9	PHSUBW 0(CX), M2
+0f380611|223344556677885f5f5f5f5f	32	intel	phsubd mmx2, qword ptr [ecx]
+0f380611|223344556677885f5f5f5f5f	32	plan9	PHSUBD 0(CX), M2
+0f380611|223344556677885f5f5f5f5f	64	gnu	phsubd (%rcx),%mm2
+0f380611|223344556677885f5f5f5f5f	64	intel	phsubd mmx2, qword ptr [rcx]
+0f380611|223344556677885f5f5f5f5f	64	plan9	PHSUBD 0(CX), M2
+0f380711|223344556677885f5f5f5f5f	32	intel	phsubsw mmx2, qword ptr [ecx]
+0f380711|223344556677885f5f5f5f5f	32	plan9	PHSUBSW 0(CX), M2
+0f380711|223344556677885f5f5f5f5f	64	gnu	phsubsw (%rcx),%mm2
+0f380711|223344556677885f5f5f5f5f	64	intel	phsubsw mmx2, qword ptr [rcx]
+0f380711|223344556677885f5f5f5f5f	64	plan9	PHSUBSW 0(CX), M2
+0f380811|223344556677885f5f5f5f5f	32	intel	psignb mmx2, qword ptr [ecx]
+0f380811|223344556677885f5f5f5f5f	32	plan9	PSIGNB 0(CX), M2
+0f380811|223344556677885f5f5f5f5f	64	gnu	psignb (%rcx),%mm2
+0f380811|223344556677885f5f5f5f5f	64	intel	psignb mmx2, qword ptr [rcx]
+0f380811|223344556677885f5f5f5f5f	64	plan9	PSIGNB 0(CX), M2
+0f380911|223344556677885f5f5f5f5f	32	intel	psignw mmx2, qword ptr [ecx]
+0f380911|223344556677885f5f5f5f5f	32	plan9	PSIGNW 0(CX), M2
+0f380911|223344556677885f5f5f5f5f	64	gnu	psignw (%rcx),%mm2
+0f380911|223344556677885f5f5f5f5f	64	intel	psignw mmx2, qword ptr [rcx]
+0f380911|223344556677885f5f5f5f5f	64	plan9	PSIGNW 0(CX), M2
+0f380a11|223344556677885f5f5f5f5f	32	intel	psignd mmx2, qword ptr [ecx]
+0f380a11|223344556677885f5f5f5f5f	32	plan9	PSIGND 0(CX), M2
+0f380a11|223344556677885f5f5f5f5f	64	gnu	psignd (%rcx),%mm2
+0f380a11|223344556677885f5f5f5f5f	64	intel	psignd mmx2, qword ptr [rcx]
+0f380a11|223344556677885f5f5f5f5f	64	plan9	PSIGND 0(CX), M2
+0f380b11|223344556677885f5f5f5f5f	32	intel	pmulhrsw mmx2, qword ptr [ecx]
+0f380b11|223344556677885f5f5f5f5f	32	plan9	PMULHRSW 0(CX), M2
+0f380b11|223344556677885f5f5f5f5f	64	gnu	pmulhrsw (%rcx),%mm2
+0f380b11|223344556677885f5f5f5f5f	64	intel	pmulhrsw mmx2, qword ptr [rcx]
+0f380b11|223344556677885f5f5f5f5f	64	plan9	PMULHRSW 0(CX), M2
+0f3810|11223344556677885f5f5f5f5f	32	intel	error: unrecognized instruction
+0f3810|11223344556677885f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f3810|11223344556677885f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f3810|11223344556677885f5f5f5f5f	64	intel	error: unrecognized instruction
+0f3810|11223344556677885f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f3811|223344556677885f5f5f5f5f5f	32	intel	error: unrecognized instruction
+0f3811|223344556677885f5f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f3811|223344556677885f5f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f3811|223344556677885f5f5f5f5f5f	64	intel	error: unrecognized instruction
+0f3811|223344556677885f5f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f3814|11223344556677885f5f5f5f5f	32	intel	error: unrecognized instruction
+0f3814|11223344556677885f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f3814|11223344556677885f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f3814|11223344556677885f5f5f5f5f	64	intel	error: unrecognized instruction
+0f3814|11223344556677885f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f3815|11223344556677885f5f5f5f5f	32	intel	error: unrecognized instruction
+0f3815|11223344556677885f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f3815|11223344556677885f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f3815|11223344556677885f5f5f5f5f	64	intel	error: unrecognized instruction
+0f3815|11223344556677885f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f3817|11223344556677885f5f5f5f5f	32	intel	error: unrecognized instruction
+0f3817|11223344556677885f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f3817|11223344556677885f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f3817|11223344556677885f5f5f5f5f	64	intel	error: unrecognized instruction
+0f3817|11223344556677885f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f381c11|223344556677885f5f5f5f5f	32	intel	pabsb mmx2, qword ptr [ecx]
+0f381c11|223344556677885f5f5f5f5f	32	plan9	PABSB 0(CX), M2
+0f381c11|223344556677885f5f5f5f5f	64	gnu	pabsb (%rcx),%mm2
+0f381c11|223344556677885f5f5f5f5f	64	intel	pabsb mmx2, qword ptr [rcx]
+0f381c11|223344556677885f5f5f5f5f	64	plan9	PABSB 0(CX), M2
+0f381d11|223344556677885f5f5f5f5f	32	intel	pabsw mmx2, qword ptr [ecx]
+0f381d11|223344556677885f5f5f5f5f	32	plan9	PABSW 0(CX), M2
+0f381d11|223344556677885f5f5f5f5f	64	gnu	pabsw (%rcx),%mm2
+0f381d11|223344556677885f5f5f5f5f	64	intel	pabsw mmx2, qword ptr [rcx]
+0f381d11|223344556677885f5f5f5f5f	64	plan9	PABSW 0(CX), M2
+0f381e11|223344556677885f5f5f5f5f	32	intel	pabsd mmx2, qword ptr [ecx]
+0f381e11|223344556677885f5f5f5f5f	32	plan9	PABSD 0(CX), M2
+0f381e11|223344556677885f5f5f5f5f	64	gnu	pabsd (%rcx),%mm2
+0f381e11|223344556677885f5f5f5f5f	64	intel	pabsd mmx2, qword ptr [rcx]
+0f381e11|223344556677885f5f5f5f5f	64	plan9	PABSD 0(CX), M2
+0f3820|11223344556677885f5f5f5f5f	32	intel	error: unrecognized instruction
+0f3820|11223344556677885f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f3820|11223344556677885f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f3820|11223344556677885f5f5f5f5f	64	intel	error: unrecognized instruction
+0f3820|11223344556677885f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f3821|11223344556677885f5f5f5f5f	32	intel	error: unrecognized instruction
+0f3821|11223344556677885f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f3821|11223344556677885f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f3821|11223344556677885f5f5f5f5f	64	intel	error: unrecognized instruction
+0f3821|11223344556677885f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f3822|11223344556677885f5f5f5f5f	32	intel	error: unrecognized instruction
+0f3822|11223344556677885f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f3822|11223344556677885f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f3822|11223344556677885f5f5f5f5f	64	intel	error: unrecognized instruction
+0f3822|11223344556677885f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f3823|11223344556677885f5f5f5f5f	32	intel	error: unrecognized instruction
+0f3823|11223344556677885f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f3823|11223344556677885f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f3823|11223344556677885f5f5f5f5f	64	intel	error: unrecognized instruction
+0f3823|11223344556677885f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f3824|11223344556677885f5f5f5f5f	32	intel	error: unrecognized instruction
+0f3824|11223344556677885f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f3824|11223344556677885f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f3824|11223344556677885f5f5f5f5f	64	intel	error: unrecognized instruction
+0f3824|11223344556677885f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f3825|11223344556677885f5f5f5f5f	32	intel	error: unrecognized instruction
+0f3825|11223344556677885f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f3825|11223344556677885f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f3825|11223344556677885f5f5f5f5f	64	intel	error: unrecognized instruction
+0f3825|11223344556677885f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f3828|11223344556677885f5f5f5f5f	32	intel	error: unrecognized instruction
+0f3828|11223344556677885f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f3828|11223344556677885f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f3828|11223344556677885f5f5f5f5f	64	intel	error: unrecognized instruction
+0f3828|11223344556677885f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f3829|11223344556677885f5f5f5f5f	32	intel	error: unrecognized instruction
+0f3829|11223344556677885f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f3829|11223344556677885f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f3829|11223344556677885f5f5f5f5f	64	intel	error: unrecognized instruction
+0f3829|11223344556677885f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f382a|11223344556677885f5f5f5f5f	32	intel	error: unrecognized instruction
+0f382a|11223344556677885f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f382a|11223344556677885f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f382a|11223344556677885f5f5f5f5f	64	intel	error: unrecognized instruction
+0f382a|11223344556677885f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f382b|11223344556677885f5f5f5f5f	32	intel	error: unrecognized instruction
+0f382b|11223344556677885f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f382b|11223344556677885f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f382b|11223344556677885f5f5f5f5f	64	intel	error: unrecognized instruction
+0f382b|11223344556677885f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f3830|11223344556677885f5f5f5f5f	32	intel	error: unrecognized instruction
+0f3830|11223344556677885f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f3830|11223344556677885f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f3830|11223344556677885f5f5f5f5f	64	intel	error: unrecognized instruction
+0f3830|11223344556677885f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f3831|11223344556677885f5f5f5f5f	32	intel	error: unrecognized instruction
+0f3831|11223344556677885f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f3831|11223344556677885f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f3831|11223344556677885f5f5f5f5f	64	intel	error: unrecognized instruction
+0f3831|11223344556677885f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f3832|11223344556677885f5f5f5f5f	32	intel	error: unrecognized instruction
+0f3832|11223344556677885f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f3832|11223344556677885f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f3832|11223344556677885f5f5f5f5f	64	intel	error: unrecognized instruction
+0f3832|11223344556677885f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f3833|11223344556677885f5f5f5f5f	32	intel	error: unrecognized instruction
+0f3833|11223344556677885f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f3833|11223344556677885f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f3833|11223344556677885f5f5f5f5f	64	intel	error: unrecognized instruction
+0f3833|11223344556677885f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f3834|11223344556677885f5f5f5f5f	32	intel	error: unrecognized instruction
+0f3834|11223344556677885f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f3834|11223344556677885f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f3834|11223344556677885f5f5f5f5f	64	intel	error: unrecognized instruction
+0f3834|11223344556677885f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f3835|11223344556677885f5f5f5f5f	32	intel	error: unrecognized instruction
+0f3835|11223344556677885f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f3835|11223344556677885f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f3835|11223344556677885f5f5f5f5f	64	intel	error: unrecognized instruction
+0f3835|11223344556677885f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f3837|11223344556677885f5f5f5f5f	32	intel	error: unrecognized instruction
+0f3837|11223344556677885f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f3837|11223344556677885f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f3837|11223344556677885f5f5f5f5f	64	intel	error: unrecognized instruction
+0f3837|11223344556677885f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f3838|11223344556677885f5f5f5f5f	32	intel	error: unrecognized instruction
+0f3838|11223344556677885f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f3838|11223344556677885f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f3838|11223344556677885f5f5f5f5f	64	intel	error: unrecognized instruction
+0f3838|11223344556677885f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f3839|11223344556677885f5f5f5f5f	32	intel	error: unrecognized instruction
+0f3839|11223344556677885f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f3839|11223344556677885f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f3839|11223344556677885f5f5f5f5f	64	intel	error: unrecognized instruction
+0f3839|11223344556677885f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f383a|11223344556677885f5f5f5f5f	32	intel	error: unrecognized instruction
+0f383a|11223344556677885f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f383a|11223344556677885f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f383a|11223344556677885f5f5f5f5f	64	intel	error: unrecognized instruction
+0f383a|11223344556677885f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f383b|11223344556677885f5f5f5f5f	32	intel	error: unrecognized instruction
+0f383b|11223344556677885f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f383b|11223344556677885f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f383b|11223344556677885f5f5f5f5f	64	intel	error: unrecognized instruction
+0f383b|11223344556677885f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f383c|11223344556677885f5f5f5f5f	32	intel	error: unrecognized instruction
+0f383c|11223344556677885f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f383c|11223344556677885f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f383c|11223344556677885f5f5f5f5f	64	intel	error: unrecognized instruction
+0f383c|11223344556677885f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f383d|11223344556677885f5f5f5f5f	32	intel	error: unrecognized instruction
+0f383d|11223344556677885f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f383d|11223344556677885f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f383d|11223344556677885f5f5f5f5f	64	intel	error: unrecognized instruction
+0f383d|11223344556677885f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f383e|11223344556677885f5f5f5f5f	32	intel	error: unrecognized instruction
+0f383e|11223344556677885f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f383e|11223344556677885f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f383e|11223344556677885f5f5f5f5f	64	intel	error: unrecognized instruction
+0f383e|11223344556677885f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f383f|11223344556677885f5f5f5f5f	32	intel	error: unrecognized instruction
+0f383f|11223344556677885f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f383f|11223344556677885f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f383f|11223344556677885f5f5f5f5f	64	intel	error: unrecognized instruction
+0f383f|11223344556677885f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f3840|11223344556677885f5f5f5f5f	32	intel	error: unrecognized instruction
+0f3840|11223344556677885f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f3840|11223344556677885f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f3840|11223344556677885f5f5f5f5f	64	intel	error: unrecognized instruction
+0f3840|11223344556677885f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f3841|11223344556677885f5f5f5f5f	32	intel	error: unrecognized instruction
+0f3841|11223344556677885f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f3841|11223344556677885f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f3841|11223344556677885f5f5f5f5f	64	intel	error: unrecognized instruction
+0f3841|11223344556677885f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f3882|11223344556677885f5f5f5f5f	32	intel	error: unrecognized instruction
+0f3882|11223344556677885f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f3882|11223344556677885f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f3882|11223344556677885f5f5f5f5f	64	intel	error: unrecognized instruction
+0f3882|11223344556677885f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f38db|11223344556677885f5f5f5f5f	32	intel	error: unrecognized instruction
+0f38db|11223344556677885f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f38db|11223344556677885f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f38db|11223344556677885f5f5f5f5f	64	intel	error: unrecognized instruction
+0f38db|11223344556677885f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f38dc|11223344556677885f5f5f5f5f	32	intel	error: unrecognized instruction
+0f38dc|11223344556677885f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f38dc|11223344556677885f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f38dc|11223344556677885f5f5f5f5f	64	intel	error: unrecognized instruction
+0f38dc|11223344556677885f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f38dd|11223344556677885f5f5f5f5f	32	intel	error: unrecognized instruction
+0f38dd|11223344556677885f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f38dd|11223344556677885f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f38dd|11223344556677885f5f5f5f5f	64	intel	error: unrecognized instruction
+0f38dd|11223344556677885f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f38de|11223344556677885f5f5f5f5f	32	intel	error: unrecognized instruction
+0f38de|11223344556677885f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f38de|11223344556677885f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f38de|11223344556677885f5f5f5f5f	64	intel	error: unrecognized instruction
+0f38de|11223344556677885f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f38df|11223344556677885f5f5f5f5f	32	intel	error: unrecognized instruction
+0f38df|11223344556677885f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f38df|11223344556677885f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f38df|11223344556677885f5f5f5f5f	64	intel	error: unrecognized instruction
+0f38df|11223344556677885f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f38f011|223344556677885f5f5f5f5f	32	intel	movbe edx, dword ptr [ecx]
+0f38f011|223344556677885f5f5f5f5f	32	plan9	MOVBE 0(CX), DX
+0f38f011|223344556677885f5f5f5f5f	64	gnu	movbe (%rcx),%edx
+0f38f011|223344556677885f5f5f5f5f	64	intel	movbe edx, dword ptr [rcx]
+0f38f011|223344556677885f5f5f5f5f	64	plan9	MOVBE 0(CX), DX
+0f38f111|223344556677885f5f5f5f5f	32	intel	movbe dword ptr [ecx], edx
+0f38f111|223344556677885f5f5f5f5f	32	plan9	MOVBE DX, 0(CX)
+0f38f111|223344556677885f5f5f5f5f	64	gnu	movbe %edx,(%rcx)
+0f38f111|223344556677885f5f5f5f5f	64	intel	movbe dword ptr [rcx], edx
+0f38f111|223344556677885f5f5f5f5f	64	plan9	MOVBE DX, 0(CX)
+0f3a08|11223344556677885f5f5f5f5f	32	intel	error: unrecognized instruction
+0f3a08|11223344556677885f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f3a08|11223344556677885f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f3a08|11223344556677885f5f5f5f5f	64	intel	error: unrecognized instruction
+0f3a08|11223344556677885f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f3a09|11223344556677885f5f5f5f5f	32	intel	error: unrecognized instruction
+0f3a09|11223344556677885f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f3a09|11223344556677885f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f3a09|11223344556677885f5f5f5f5f	64	intel	error: unrecognized instruction
+0f3a09|11223344556677885f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f3a0a|11223344556677885f5f5f5f5f	32	intel	error: unrecognized instruction
+0f3a0a|11223344556677885f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f3a0a|11223344556677885f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f3a0a|11223344556677885f5f5f5f5f	64	intel	error: unrecognized instruction
+0f3a0a|11223344556677885f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f3a0b|11223344556677885f5f5f5f5f	32	intel	error: unrecognized instruction
+0f3a0b|11223344556677885f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f3a0b|11223344556677885f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f3a0b|11223344556677885f5f5f5f5f	64	intel	error: unrecognized instruction
+0f3a0b|11223344556677885f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f3a0c|11223344556677885f5f5f5f5f	32	intel	error: unrecognized instruction
+0f3a0c|11223344556677885f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f3a0c|11223344556677885f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f3a0c|11223344556677885f5f5f5f5f	64	intel	error: unrecognized instruction
+0f3a0c|11223344556677885f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f3a0d|11223344556677885f5f5f5f5f	32	intel	error: unrecognized instruction
+0f3a0d|11223344556677885f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f3a0d|11223344556677885f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f3a0d|11223344556677885f5f5f5f5f	64	intel	error: unrecognized instruction
+0f3a0d|11223344556677885f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f3a0e|11223344556677885f5f5f5f5f	32	intel	error: unrecognized instruction
+0f3a0e|11223344556677885f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f3a0e|11223344556677885f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f3a0e|11223344556677885f5f5f5f5f	64	intel	error: unrecognized instruction
+0f3a0e|11223344556677885f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f3a0f1122|3344556677885f5f5f5f5f	32	intel	palignr mmx2, qword ptr [ecx], 0x22
+0f3a0f1122|3344556677885f5f5f5f5f	32	plan9	PALIGNR $0x22, 0(CX), M2
+0f3a0f1122|3344556677885f5f5f5f5f	64	gnu	palignr $0x22,(%rcx),%mm2
+0f3a0f1122|3344556677885f5f5f5f5f	64	intel	palignr mmx2, qword ptr [rcx], 0x22
+0f3a0f1122|3344556677885f5f5f5f5f	64	plan9	PALIGNR $0x22, 0(CX), M2
+0f3a11|223344556677885f5f5f5f5f5f	32	intel	error: unrecognized instruction
+0f3a11|223344556677885f5f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f3a11|223344556677885f5f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f3a11|223344556677885f5f5f5f5f5f	64	intel	error: unrecognized instruction
+0f3a11|223344556677885f5f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f3a14|11223344556677885f5f5f5f5f	32	intel	error: unrecognized instruction
+0f3a14|11223344556677885f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f3a14|11223344556677885f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f3a14|11223344556677885f5f5f5f5f	64	intel	error: unrecognized instruction
+0f3a14|11223344556677885f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f3a15|11223344556677885f5f5f5f5f	32	intel	error: unrecognized instruction
+0f3a15|11223344556677885f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f3a15|11223344556677885f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f3a15|11223344556677885f5f5f5f5f	64	intel	error: unrecognized instruction
+0f3a15|11223344556677885f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f3a16|11223344556677885f5f5f5f5f	32	intel	error: unrecognized instruction
+0f3a16|11223344556677885f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f3a16|11223344556677885f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f3a16|11223344556677885f5f5f5f5f	64	intel	error: unrecognized instruction
+0f3a16|11223344556677885f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f3a17|11223344556677885f5f5f5f5f	32	intel	error: unrecognized instruction
+0f3a17|11223344556677885f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f3a17|11223344556677885f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f3a17|11223344556677885f5f5f5f5f	64	intel	error: unrecognized instruction
+0f3a17|11223344556677885f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f3a20|11223344556677885f5f5f5f5f	32	intel	error: unrecognized instruction
+0f3a20|11223344556677885f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f3a20|11223344556677885f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f3a20|11223344556677885f5f5f5f5f	64	intel	error: unrecognized instruction
+0f3a20|11223344556677885f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f3a21|11223344556677885f5f5f5f5f	32	intel	error: unrecognized instruction
+0f3a21|11223344556677885f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f3a21|11223344556677885f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f3a21|11223344556677885f5f5f5f5f	64	intel	error: unrecognized instruction
+0f3a21|11223344556677885f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f3a22|11223344556677885f5f5f5f5f	32	intel	error: unrecognized instruction
+0f3a22|11223344556677885f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f3a22|11223344556677885f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f3a22|11223344556677885f5f5f5f5f	64	intel	error: unrecognized instruction
+0f3a22|11223344556677885f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f3a40|11223344556677885f5f5f5f5f	32	intel	error: unrecognized instruction
+0f3a40|11223344556677885f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f3a40|11223344556677885f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f3a40|11223344556677885f5f5f5f5f	64	intel	error: unrecognized instruction
+0f3a40|11223344556677885f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f3a41|11223344556677885f5f5f5f5f	32	intel	error: unrecognized instruction
+0f3a41|11223344556677885f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f3a41|11223344556677885f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f3a41|11223344556677885f5f5f5f5f	64	intel	error: unrecognized instruction
+0f3a41|11223344556677885f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f3a42|11223344556677885f5f5f5f5f	32	intel	error: unrecognized instruction
+0f3a42|11223344556677885f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f3a42|11223344556677885f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f3a42|11223344556677885f5f5f5f5f	64	intel	error: unrecognized instruction
+0f3a42|11223344556677885f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f3a44|11223344556677885f5f5f5f5f	32	intel	error: unrecognized instruction
+0f3a44|11223344556677885f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f3a44|11223344556677885f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f3a44|11223344556677885f5f5f5f5f	64	intel	error: unrecognized instruction
+0f3a44|11223344556677885f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f3a60|11223344556677885f5f5f5f5f	32	intel	error: unrecognized instruction
+0f3a60|11223344556677885f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f3a60|11223344556677885f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f3a60|11223344556677885f5f5f5f5f	64	intel	error: unrecognized instruction
+0f3a60|11223344556677885f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f3a61|11223344556677885f5f5f5f5f	32	intel	error: unrecognized instruction
+0f3a61|11223344556677885f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f3a61|11223344556677885f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f3a61|11223344556677885f5f5f5f5f	64	intel	error: unrecognized instruction
+0f3a61|11223344556677885f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f3a62|11223344556677885f5f5f5f5f	32	intel	error: unrecognized instruction
+0f3a62|11223344556677885f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f3a62|11223344556677885f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f3a62|11223344556677885f5f5f5f5f	64	intel	error: unrecognized instruction
+0f3a62|11223344556677885f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f3a63|11223344556677885f5f5f5f5f	32	intel	error: unrecognized instruction
+0f3a63|11223344556677885f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f3a63|11223344556677885f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f3a63|11223344556677885f5f5f5f5f	64	intel	error: unrecognized instruction
+0f3a63|11223344556677885f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f3adf|11223344556677885f5f5f5f5f	32	intel	error: unrecognized instruction
+0f3adf|11223344556677885f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f3adf|11223344556677885f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f3adf|11223344556677885f5f5f5f5f	64	intel	error: unrecognized instruction
+0f3adf|11223344556677885f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f4011|223344556677885f5f5f5f5f5f	32	intel	cmovo edx, dword ptr [ecx]
+0f4011|223344556677885f5f5f5f5f5f	32	plan9	CMOVO 0(CX), DX
+0f4011|223344556677885f5f5f5f5f5f	64	gnu	cmovo (%rcx),%edx
+0f4011|223344556677885f5f5f5f5f5f	64	intel	cmovo edx, dword ptr [rcx]
+0f4011|223344556677885f5f5f5f5f5f	64	plan9	CMOVO 0(CX), DX
+0f4111|223344556677885f5f5f5f5f5f	32	intel	cmovno edx, dword ptr [ecx]
+0f4111|223344556677885f5f5f5f5f5f	32	plan9	CMOVNO 0(CX), DX
+0f4111|223344556677885f5f5f5f5f5f	64	gnu	cmovno (%rcx),%edx
+0f4111|223344556677885f5f5f5f5f5f	64	intel	cmovno edx, dword ptr [rcx]
+0f4111|223344556677885f5f5f5f5f5f	64	plan9	CMOVNO 0(CX), DX
+0f4211|223344556677885f5f5f5f5f5f	32	intel	cmovb edx, dword ptr [ecx]
+0f4211|223344556677885f5f5f5f5f5f	32	plan9	CMOVB 0(CX), DX
+0f4211|223344556677885f5f5f5f5f5f	64	gnu	cmovb (%rcx),%edx
+0f4211|223344556677885f5f5f5f5f5f	64	intel	cmovb edx, dword ptr [rcx]
+0f4211|223344556677885f5f5f5f5f5f	64	plan9	CMOVB 0(CX), DX
+0f4311|223344556677885f5f5f5f5f5f	32	intel	cmovnb edx, dword ptr [ecx]
+0f4311|223344556677885f5f5f5f5f5f	32	plan9	CMOVAE 0(CX), DX
+0f4311|223344556677885f5f5f5f5f5f	64	gnu	cmovae (%rcx),%edx
+0f4311|223344556677885f5f5f5f5f5f	64	intel	cmovnb edx, dword ptr [rcx]
+0f4311|223344556677885f5f5f5f5f5f	64	plan9	CMOVAE 0(CX), DX
+0f4411|223344556677885f5f5f5f5f5f	32	intel	cmovz edx, dword ptr [ecx]
+0f4411|223344556677885f5f5f5f5f5f	32	plan9	CMOVE 0(CX), DX
+0f4411|223344556677885f5f5f5f5f5f	64	gnu	cmove (%rcx),%edx
+0f4411|223344556677885f5f5f5f5f5f	64	intel	cmovz edx, dword ptr [rcx]
+0f4411|223344556677885f5f5f5f5f5f	64	plan9	CMOVE 0(CX), DX
+0f4511|223344556677885f5f5f5f5f5f	32	intel	cmovnz edx, dword ptr [ecx]
+0f4511|223344556677885f5f5f5f5f5f	32	plan9	CMOVNE 0(CX), DX
+0f4511|223344556677885f5f5f5f5f5f	64	gnu	cmovne (%rcx),%edx
+0f4511|223344556677885f5f5f5f5f5f	64	intel	cmovnz edx, dword ptr [rcx]
+0f4511|223344556677885f5f5f5f5f5f	64	plan9	CMOVNE 0(CX), DX
+0f4611|223344556677885f5f5f5f5f5f	32	intel	cmovbe edx, dword ptr [ecx]
+0f4611|223344556677885f5f5f5f5f5f	32	plan9	CMOVBE 0(CX), DX
+0f4611|223344556677885f5f5f5f5f5f	64	gnu	cmovbe (%rcx),%edx
+0f4611|223344556677885f5f5f5f5f5f	64	intel	cmovbe edx, dword ptr [rcx]
+0f4611|223344556677885f5f5f5f5f5f	64	plan9	CMOVBE 0(CX), DX
+0f4711|223344556677885f5f5f5f5f5f	32	intel	cmovnbe edx, dword ptr [ecx]
+0f4711|223344556677885f5f5f5f5f5f	32	plan9	CMOVA 0(CX), DX
+0f4711|223344556677885f5f5f5f5f5f	64	gnu	cmova (%rcx),%edx
+0f4711|223344556677885f5f5f5f5f5f	64	intel	cmovnbe edx, dword ptr [rcx]
+0f4711|223344556677885f5f5f5f5f5f	64	plan9	CMOVA 0(CX), DX
+0f4811|223344556677885f5f5f5f5f5f	32	intel	cmovs edx, dword ptr [ecx]
+0f4811|223344556677885f5f5f5f5f5f	32	plan9	CMOVS 0(CX), DX
+0f4811|223344556677885f5f5f5f5f5f	64	gnu	cmovs (%rcx),%edx
+0f4811|223344556677885f5f5f5f5f5f	64	intel	cmovs edx, dword ptr [rcx]
+0f4811|223344556677885f5f5f5f5f5f	64	plan9	CMOVS 0(CX), DX
+0f4911|223344556677885f5f5f5f5f5f	32	intel	cmovns edx, dword ptr [ecx]
+0f4911|223344556677885f5f5f5f5f5f	32	plan9	CMOVNS 0(CX), DX
+0f4911|223344556677885f5f5f5f5f5f	64	gnu	cmovns (%rcx),%edx
+0f4911|223344556677885f5f5f5f5f5f	64	intel	cmovns edx, dword ptr [rcx]
+0f4911|223344556677885f5f5f5f5f5f	64	plan9	CMOVNS 0(CX), DX
+0f4a11|223344556677885f5f5f5f5f5f	32	intel	cmovp edx, dword ptr [ecx]
+0f4a11|223344556677885f5f5f5f5f5f	32	plan9	CMOVP 0(CX), DX
+0f4a11|223344556677885f5f5f5f5f5f	64	gnu	cmovp (%rcx),%edx
+0f4a11|223344556677885f5f5f5f5f5f	64	intel	cmovp edx, dword ptr [rcx]
+0f4a11|223344556677885f5f5f5f5f5f	64	plan9	CMOVP 0(CX), DX
+0f4b11|223344556677885f5f5f5f5f5f	32	intel	cmovnp edx, dword ptr [ecx]
+0f4b11|223344556677885f5f5f5f5f5f	32	plan9	CMOVNP 0(CX), DX
+0f4b11|223344556677885f5f5f5f5f5f	64	gnu	cmovnp (%rcx),%edx
+0f4b11|223344556677885f5f5f5f5f5f	64	intel	cmovnp edx, dword ptr [rcx]
+0f4b11|223344556677885f5f5f5f5f5f	64	plan9	CMOVNP 0(CX), DX
+0f4c11|223344556677885f5f5f5f5f5f	32	intel	cmovl edx, dword ptr [ecx]
+0f4c11|223344556677885f5f5f5f5f5f	32	plan9	CMOVL 0(CX), DX
+0f4c11|223344556677885f5f5f5f5f5f	64	gnu	cmovl (%rcx),%edx
+0f4c11|223344556677885f5f5f5f5f5f	64	intel	cmovl edx, dword ptr [rcx]
+0f4c11|223344556677885f5f5f5f5f5f	64	plan9	CMOVL 0(CX), DX
+0f4d11|223344556677885f5f5f5f5f5f	32	intel	cmovnl edx, dword ptr [ecx]
+0f4d11|223344556677885f5f5f5f5f5f	32	plan9	CMOVGE 0(CX), DX
+0f4d11|223344556677885f5f5f5f5f5f	64	gnu	cmovge (%rcx),%edx
+0f4d11|223344556677885f5f5f5f5f5f	64	intel	cmovnl edx, dword ptr [rcx]
+0f4d11|223344556677885f5f5f5f5f5f	64	plan9	CMOVGE 0(CX), DX
+0f4e11|223344556677885f5f5f5f5f5f	32	intel	cmovle edx, dword ptr [ecx]
+0f4e11|223344556677885f5f5f5f5f5f	32	plan9	CMOVLE 0(CX), DX
+0f4e11|223344556677885f5f5f5f5f5f	64	gnu	cmovle (%rcx),%edx
+0f4e11|223344556677885f5f5f5f5f5f	64	intel	cmovle edx, dword ptr [rcx]
+0f4e11|223344556677885f5f5f5f5f5f	64	plan9	CMOVLE 0(CX), DX
+0f4f11|223344556677885f5f5f5f5f5f	32	intel	cmovnle edx, dword ptr [ecx]
+0f4f11|223344556677885f5f5f5f5f5f	32	plan9	CMOVG 0(CX), DX
+0f4f11|223344556677885f5f5f5f5f5f	64	gnu	cmovg (%rcx),%edx
+0f4f11|223344556677885f5f5f5f5f5f	64	intel	cmovnle edx, dword ptr [rcx]
+0f4f11|223344556677885f5f5f5f5f5f	64	plan9	CMOVG 0(CX), DX
+0f5011|223344556677885f5f5f5f5f5f	32	intel	error: unrecognized instruction
+0f5011|223344556677885f5f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f5011|223344556677885f5f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f5011|223344556677885f5f5f5f5f5f	64	intel	error: unrecognized instruction
+0f5011|223344556677885f5f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f50c0|11223344556677885f5f5f5f5f	32	intel	movmskps eax, xmm0
+0f50c0|11223344556677885f5f5f5f5f	32	plan9	MOVMSKPS X0, AX
+0f50c0|11223344556677885f5f5f5f5f	64	gnu	movmskps %xmm0,%eax
+0f50c0|11223344556677885f5f5f5f5f	64	intel	movmskps eax, xmm0
+0f50c0|11223344556677885f5f5f5f5f	64	plan9	MOVMSKPS X0, AX
+0f5111|223344556677885f5f5f5f5f5f	32	intel	sqrtps xmm2, xmmword ptr [ecx]
+0f5111|223344556677885f5f5f5f5f5f	32	plan9	SQRTPS 0(CX), X2
+0f5111|223344556677885f5f5f5f5f5f	64	gnu	sqrtps (%rcx),%xmm2
+0f5111|223344556677885f5f5f5f5f5f	64	intel	sqrtps xmm2, xmmword ptr [rcx]
+0f5111|223344556677885f5f5f5f5f5f	64	plan9	SQRTPS 0(CX), X2
+0f5211|223344556677885f5f5f5f5f5f	32	intel	rsqrtps xmm2, xmmword ptr [ecx]
+0f5211|223344556677885f5f5f5f5f5f	32	plan9	RSQRTPS 0(CX), X2
+0f5211|223344556677885f5f5f5f5f5f	64	gnu	rsqrtps (%rcx),%xmm2
+0f5211|223344556677885f5f5f5f5f5f	64	intel	rsqrtps xmm2, xmmword ptr [rcx]
+0f5211|223344556677885f5f5f5f5f5f	64	plan9	RSQRTPS 0(CX), X2
+0f5311|223344556677885f5f5f5f5f5f	32	intel	rcpps xmm2, xmmword ptr [ecx]
+0f5311|223344556677885f5f5f5f5f5f	32	plan9	RCPPS 0(CX), X2
+0f5311|223344556677885f5f5f5f5f5f	64	gnu	rcpps (%rcx),%xmm2
+0f5311|223344556677885f5f5f5f5f5f	64	intel	rcpps xmm2, xmmword ptr [rcx]
+0f5311|223344556677885f5f5f5f5f5f	64	plan9	RCPPS 0(CX), X2
+0f5411|223344556677885f5f5f5f5f5f	32	intel	andps xmm2, xmmword ptr [ecx]
+0f5411|223344556677885f5f5f5f5f5f	32	plan9	ANDPS 0(CX), X2
+0f5411|223344556677885f5f5f5f5f5f	64	gnu	andps (%rcx),%xmm2
+0f5411|223344556677885f5f5f5f5f5f	64	intel	andps xmm2, xmmword ptr [rcx]
+0f5411|223344556677885f5f5f5f5f5f	64	plan9	ANDPS 0(CX), X2
+0f5511|223344556677885f5f5f5f5f5f	32	intel	andnps xmm2, xmmword ptr [ecx]
+0f5511|223344556677885f5f5f5f5f5f	32	plan9	ANDNPS 0(CX), X2
+0f5511|223344556677885f5f5f5f5f5f	64	gnu	andnps (%rcx),%xmm2
+0f5511|223344556677885f5f5f5f5f5f	64	intel	andnps xmm2, xmmword ptr [rcx]
+0f5511|223344556677885f5f5f5f5f5f	64	plan9	ANDNPS 0(CX), X2
+0f5611|223344556677885f5f5f5f5f5f	32	intel	orps xmm2, xmmword ptr [ecx]
+0f5611|223344556677885f5f5f5f5f5f	32	plan9	ORPS 0(CX), X2
+0f5611|223344556677885f5f5f5f5f5f	64	gnu	orps (%rcx),%xmm2
+0f5611|223344556677885f5f5f5f5f5f	64	intel	orps xmm2, xmmword ptr [rcx]
+0f5611|223344556677885f5f5f5f5f5f	64	plan9	ORPS 0(CX), X2
+0f5711|223344556677885f5f5f5f5f5f	32	intel	xorps xmm2, xmmword ptr [ecx]
+0f5711|223344556677885f5f5f5f5f5f	32	plan9	XORPS 0(CX), X2
+0f5711|223344556677885f5f5f5f5f5f	64	gnu	xorps (%rcx),%xmm2
+0f5711|223344556677885f5f5f5f5f5f	64	intel	xorps xmm2, xmmword ptr [rcx]
+0f5711|223344556677885f5f5f5f5f5f	64	plan9	XORPS 0(CX), X2
+0f5811|223344556677885f5f5f5f5f5f	32	intel	addps xmm2, xmmword ptr [ecx]
+0f5811|223344556677885f5f5f5f5f5f	32	plan9	ADDPS 0(CX), X2
+0f5811|223344556677885f5f5f5f5f5f	64	gnu	addps (%rcx),%xmm2
+0f5811|223344556677885f5f5f5f5f5f	64	intel	addps xmm2, xmmword ptr [rcx]
+0f5811|223344556677885f5f5f5f5f5f	64	plan9	ADDPS 0(CX), X2
+0f5911|223344556677885f5f5f5f5f5f	32	intel	mulps xmm2, xmmword ptr [ecx]
+0f5911|223344556677885f5f5f5f5f5f	32	plan9	MULPS 0(CX), X2
+0f5911|223344556677885f5f5f5f5f5f	64	gnu	mulps (%rcx),%xmm2
+0f5911|223344556677885f5f5f5f5f5f	64	intel	mulps xmm2, xmmword ptr [rcx]
+0f5911|223344556677885f5f5f5f5f5f	64	plan9	MULPS 0(CX), X2
+0f5a11|223344556677885f5f5f5f5f5f	32	intel	cvtps2pd xmm2, qword ptr [ecx]
+0f5a11|223344556677885f5f5f5f5f5f	32	plan9	CVTPS2PD 0(CX), X2
+0f5a11|223344556677885f5f5f5f5f5f	64	gnu	cvtps2pd (%rcx),%xmm2
+0f5a11|223344556677885f5f5f5f5f5f	64	intel	cvtps2pd xmm2, qword ptr [rcx]
+0f5a11|223344556677885f5f5f5f5f5f	64	plan9	CVTPS2PD 0(CX), X2
+0f5b11|223344556677885f5f5f5f5f5f	32	intel	cvtdq2ps xmm2, xmmword ptr [ecx]
+0f5b11|223344556677885f5f5f5f5f5f	32	plan9	CVTDQ2PS 0(CX), X2
+0f5b11|223344556677885f5f5f5f5f5f	64	gnu	cvtdq2ps (%rcx),%xmm2
+0f5b11|223344556677885f5f5f5f5f5f	64	intel	cvtdq2ps xmm2, xmmword ptr [rcx]
+0f5b11|223344556677885f5f5f5f5f5f	64	plan9	CVTDQ2PS 0(CX), X2
+0f5c11|223344556677885f5f5f5f5f5f	32	intel	subps xmm2, xmmword ptr [ecx]
+0f5c11|223344556677885f5f5f5f5f5f	32	plan9	SUBPS 0(CX), X2
+0f5c11|223344556677885f5f5f5f5f5f	64	gnu	subps (%rcx),%xmm2
+0f5c11|223344556677885f5f5f5f5f5f	64	intel	subps xmm2, xmmword ptr [rcx]
+0f5c11|223344556677885f5f5f5f5f5f	64	plan9	SUBPS 0(CX), X2
+0f5d11|223344556677885f5f5f5f5f5f	32	intel	minps xmm2, xmmword ptr [ecx]
+0f5d11|223344556677885f5f5f5f5f5f	32	plan9	MINPS 0(CX), X2
+0f5d11|223344556677885f5f5f5f5f5f	64	gnu	minps (%rcx),%xmm2
+0f5d11|223344556677885f5f5f5f5f5f	64	intel	minps xmm2, xmmword ptr [rcx]
+0f5d11|223344556677885f5f5f5f5f5f	64	plan9	MINPS 0(CX), X2
+0f5e11|223344556677885f5f5f5f5f5f	32	intel	divps xmm2, xmmword ptr [ecx]
+0f5e11|223344556677885f5f5f5f5f5f	32	plan9	DIVPS 0(CX), X2
+0f5e11|223344556677885f5f5f5f5f5f	64	gnu	divps (%rcx),%xmm2
+0f5e11|223344556677885f5f5f5f5f5f	64	intel	divps xmm2, xmmword ptr [rcx]
+0f5e11|223344556677885f5f5f5f5f5f	64	plan9	DIVPS 0(CX), X2
+0f5f11|223344556677885f5f5f5f5f5f	32	intel	maxps xmm2, xmmword ptr [ecx]
+0f5f11|223344556677885f5f5f5f5f5f	32	plan9	MAXPS 0(CX), X2
+0f5f11|223344556677885f5f5f5f5f5f	64	gnu	maxps (%rcx),%xmm2
+0f5f11|223344556677885f5f5f5f5f5f	64	intel	maxps xmm2, xmmword ptr [rcx]
+0f5f11|223344556677885f5f5f5f5f5f	64	plan9	MAXPS 0(CX), X2
+0f6011|223344556677885f5f5f5f5f5f	32	intel	punpcklbw mmx2, dword ptr [ecx]
+0f6011|223344556677885f5f5f5f5f5f	32	plan9	PUNPCKLBW 0(CX), M2
+0f6011|223344556677885f5f5f5f5f5f	64	gnu	punpcklbw (%rcx),%mm2
+0f6011|223344556677885f5f5f5f5f5f	64	intel	punpcklbw mmx2, dword ptr [rcx]
+0f6011|223344556677885f5f5f5f5f5f	64	plan9	PUNPCKLBW 0(CX), M2
+0f6111|223344556677885f5f5f5f5f5f	32	intel	punpcklwd mmx2, dword ptr [ecx]
+0f6111|223344556677885f5f5f5f5f5f	32	plan9	PUNPCKLWD 0(CX), M2
+0f6111|223344556677885f5f5f5f5f5f	64	gnu	punpcklwd (%rcx),%mm2
+0f6111|223344556677885f5f5f5f5f5f	64	intel	punpcklwd mmx2, dword ptr [rcx]
+0f6111|223344556677885f5f5f5f5f5f	64	plan9	PUNPCKLWD 0(CX), M2
+0f6211|223344556677885f5f5f5f5f5f	32	intel	punpckldq mmx2, dword ptr [ecx]
+0f6211|223344556677885f5f5f5f5f5f	32	plan9	PUNPCKLDQ 0(CX), M2
+0f6211|223344556677885f5f5f5f5f5f	64	gnu	punpckldq (%rcx),%mm2
+0f6211|223344556677885f5f5f5f5f5f	64	intel	punpckldq mmx2, dword ptr [rcx]
+0f6211|223344556677885f5f5f5f5f5f	64	plan9	PUNPCKLDQ 0(CX), M2
+0f6311|223344556677885f5f5f5f5f5f	32	intel	packsswb mmx2, qword ptr [ecx]
+0f6311|223344556677885f5f5f5f5f5f	32	plan9	PACKSSWB 0(CX), M2
+0f6311|223344556677885f5f5f5f5f5f	64	gnu	packsswb (%rcx),%mm2
+0f6311|223344556677885f5f5f5f5f5f	64	intel	packsswb mmx2, qword ptr [rcx]
+0f6311|223344556677885f5f5f5f5f5f	64	plan9	PACKSSWB 0(CX), M2
+0f6411|223344556677885f5f5f5f5f5f	32	intel	pcmpgtb mmx2, qword ptr [ecx]
+0f6411|223344556677885f5f5f5f5f5f	32	plan9	PCMPGTB 0(CX), M2
+0f6411|223344556677885f5f5f5f5f5f	64	gnu	pcmpgtb (%rcx),%mm2
+0f6411|223344556677885f5f5f5f5f5f	64	intel	pcmpgtb mmx2, qword ptr [rcx]
+0f6411|223344556677885f5f5f5f5f5f	64	plan9	PCMPGTB 0(CX), M2
+0f6511|223344556677885f5f5f5f5f5f	32	intel	pcmpgtw mmx2, qword ptr [ecx]
+0f6511|223344556677885f5f5f5f5f5f	32	plan9	PCMPGTW 0(CX), M2
+0f6511|223344556677885f5f5f5f5f5f	64	gnu	pcmpgtw (%rcx),%mm2
+0f6511|223344556677885f5f5f5f5f5f	64	intel	pcmpgtw mmx2, qword ptr [rcx]
+0f6511|223344556677885f5f5f5f5f5f	64	plan9	PCMPGTW 0(CX), M2
+0f6611|223344556677885f5f5f5f5f5f	32	intel	pcmpgtd mmx2, qword ptr [ecx]
+0f6611|223344556677885f5f5f5f5f5f	32	plan9	PCMPGTD 0(CX), M2
+0f6611|223344556677885f5f5f5f5f5f	64	gnu	pcmpgtd (%rcx),%mm2
+0f6611|223344556677885f5f5f5f5f5f	64	intel	pcmpgtd mmx2, qword ptr [rcx]
+0f6611|223344556677885f5f5f5f5f5f	64	plan9	PCMPGTD 0(CX), M2
+0f6711|223344556677885f5f5f5f5f5f	32	intel	packuswb mmx2, qword ptr [ecx]
+0f6711|223344556677885f5f5f5f5f5f	32	plan9	PACKUSWB 0(CX), M2
+0f6711|223344556677885f5f5f5f5f5f	64	gnu	packuswb (%rcx),%mm2
+0f6711|223344556677885f5f5f5f5f5f	64	intel	packuswb mmx2, qword ptr [rcx]
+0f6711|223344556677885f5f5f5f5f5f	64	plan9	PACKUSWB 0(CX), M2
+0f6811|223344556677885f5f5f5f5f5f	32	intel	punpckhbw mmx2, qword ptr [ecx]
+0f6811|223344556677885f5f5f5f5f5f	32	plan9	PUNPCKHBW 0(CX), M2
+0f6811|223344556677885f5f5f5f5f5f	64	gnu	punpckhbw (%rcx),%mm2
+0f6811|223344556677885f5f5f5f5f5f	64	intel	punpckhbw mmx2, qword ptr [rcx]
+0f6811|223344556677885f5f5f5f5f5f	64	plan9	PUNPCKHBW 0(CX), M2
+0f6911|223344556677885f5f5f5f5f5f	32	intel	punpckhwd mmx2, qword ptr [ecx]
+0f6911|223344556677885f5f5f5f5f5f	32	plan9	PUNPCKHWD 0(CX), M2
+0f6911|223344556677885f5f5f5f5f5f	64	gnu	punpckhwd (%rcx),%mm2
+0f6911|223344556677885f5f5f5f5f5f	64	intel	punpckhwd mmx2, qword ptr [rcx]
+0f6911|223344556677885f5f5f5f5f5f	64	plan9	PUNPCKHWD 0(CX), M2
+0f6a11|223344556677885f5f5f5f5f5f	32	intel	punpckhdq mmx2, qword ptr [ecx]
+0f6a11|223344556677885f5f5f5f5f5f	32	plan9	PUNPCKHDQ 0(CX), M2
+0f6a11|223344556677885f5f5f5f5f5f	64	gnu	punpckhdq (%rcx),%mm2
+0f6a11|223344556677885f5f5f5f5f5f	64	intel	punpckhdq mmx2, qword ptr [rcx]
+0f6a11|223344556677885f5f5f5f5f5f	64	plan9	PUNPCKHDQ 0(CX), M2
+0f6b11|223344556677885f5f5f5f5f5f	32	intel	packssdw mmx2, qword ptr [ecx]
+0f6b11|223344556677885f5f5f5f5f5f	32	plan9	PACKSSDW 0(CX), M2
+0f6b11|223344556677885f5f5f5f5f5f	64	gnu	packssdw (%rcx),%mm2
+0f6b11|223344556677885f5f5f5f5f5f	64	intel	packssdw mmx2, qword ptr [rcx]
+0f6b11|223344556677885f5f5f5f5f5f	64	plan9	PACKSSDW 0(CX), M2
+0f6c|11223344556677885f5f5f5f5f5f	32	intel	error: unrecognized instruction
+0f6c|11223344556677885f5f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f6c|11223344556677885f5f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f6c|11223344556677885f5f5f5f5f5f	64	intel	error: unrecognized instruction
+0f6c|11223344556677885f5f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f6d|11223344556677885f5f5f5f5f5f	32	intel	error: unrecognized instruction
+0f6d|11223344556677885f5f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f6d|11223344556677885f5f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f6d|11223344556677885f5f5f5f5f5f	64	intel	error: unrecognized instruction
+0f6d|11223344556677885f5f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f6e11|223344556677885f5f5f5f5f5f	32	intel	movd mmx2, dword ptr [ecx]
+0f6e11|223344556677885f5f5f5f5f5f	32	plan9	MOVD 0(CX), M2
+0f6e11|223344556677885f5f5f5f5f5f	64	gnu	movd (%rcx),%mm2
+0f6e11|223344556677885f5f5f5f5f5f	64	intel	movd mmx2, dword ptr [rcx]
+0f6e11|223344556677885f5f5f5f5f5f	64	plan9	MOVD 0(CX), M2
+0f6f11|223344556677885f5f5f5f5f5f	32	intel	movq mmx2, qword ptr [ecx]
+0f6f11|223344556677885f5f5f5f5f5f	32	plan9	MOVQ 0(CX), M2
+0f6f11|223344556677885f5f5f5f5f5f	64	gnu	movq (%rcx),%mm2
+0f6f11|223344556677885f5f5f5f5f5f	64	intel	movq mmx2, qword ptr [rcx]
+0f6f11|223344556677885f5f5f5f5f5f	64	plan9	MOVQ 0(CX), M2
+0f701122|3344556677885f5f5f5f5f5f	32	intel	pshufw mmx2, qword ptr [ecx], 0x22
+0f701122|3344556677885f5f5f5f5f5f	32	plan9	PSHUFW $0x22, 0(CX), M2
+0f701122|3344556677885f5f5f5f5f5f	64	gnu	pshufw $0x22,(%rcx),%mm2
+0f701122|3344556677885f5f5f5f5f5f	64	intel	pshufw mmx2, qword ptr [rcx], 0x22
+0f701122|3344556677885f5f5f5f5f5f	64	plan9	PSHUFW $0x22, 0(CX), M2
+0f7100|11223344556677885f5f5f5f5f	32	intel	error: unrecognized instruction
+0f7100|11223344556677885f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f7100|11223344556677885f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f7100|11223344556677885f5f5f5f5f	64	intel	error: unrecognized instruction
+0f7100|11223344556677885f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f711122|3344556677885f5f5f5f5f5f	32	intel	error: unrecognized instruction
+0f711122|3344556677885f5f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f711122|3344556677885f5f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f711122|3344556677885f5f5f5f5f5f	64	intel	error: unrecognized instruction
+0f711122|3344556677885f5f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f712011|223344556677885f5f5f5f5f	32	intel	error: unrecognized instruction
+0f712011|223344556677885f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f712011|223344556677885f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f712011|223344556677885f5f5f5f5f	64	intel	error: unrecognized instruction
+0f712011|223344556677885f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f713011|223344556677885f5f5f5f5f	32	intel	error: unrecognized instruction
+0f713011|223344556677885f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f713011|223344556677885f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f713011|223344556677885f5f5f5f5f	64	intel	error: unrecognized instruction
+0f713011|223344556677885f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f71d011|223344556677885f5f5f5f5f	32	intel	psrlw mmx0, 0x11
+0f71d011|223344556677885f5f5f5f5f	32	plan9	PSRLW $0x11, M0
+0f71d011|223344556677885f5f5f5f5f	64	gnu	psrlw $0x11,%mm0
+0f71d011|223344556677885f5f5f5f5f	64	intel	psrlw mmx0, 0x11
+0f71d011|223344556677885f5f5f5f5f	64	plan9	PSRLW $0x11, M0
+0f71e011|223344556677885f5f5f5f5f	32	intel	psraw mmx0, 0x11
+0f71e011|223344556677885f5f5f5f5f	32	plan9	PSRAW $0x11, M0
+0f71e011|223344556677885f5f5f5f5f	64	gnu	psraw $0x11,%mm0
+0f71e011|223344556677885f5f5f5f5f	64	intel	psraw mmx0, 0x11
+0f71e011|223344556677885f5f5f5f5f	64	plan9	PSRAW $0x11, M0
+0f71f011|223344556677885f5f5f5f5f	32	intel	psllw mmx0, 0x11
+0f71f011|223344556677885f5f5f5f5f	32	plan9	PSLLW $0x11, M0
+0f71f011|223344556677885f5f5f5f5f	64	gnu	psllw $0x11,%mm0
+0f71f011|223344556677885f5f5f5f5f	64	intel	psllw mmx0, 0x11
+0f71f011|223344556677885f5f5f5f5f	64	plan9	PSLLW $0x11, M0
+0f7200|11223344556677885f5f5f5f5f	32	intel	error: unrecognized instruction
+0f7200|11223344556677885f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f7200|11223344556677885f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f7200|11223344556677885f5f5f5f5f	64	intel	error: unrecognized instruction
+0f7200|11223344556677885f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f721122|3344556677885f5f5f5f5f5f	32	intel	error: unrecognized instruction
+0f721122|3344556677885f5f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f721122|3344556677885f5f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f721122|3344556677885f5f5f5f5f5f	64	intel	error: unrecognized instruction
+0f721122|3344556677885f5f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f722011|223344556677885f5f5f5f5f	32	intel	error: unrecognized instruction
+0f722011|223344556677885f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f722011|223344556677885f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f722011|223344556677885f5f5f5f5f	64	intel	error: unrecognized instruction
+0f722011|223344556677885f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f723011|223344556677885f5f5f5f5f	32	intel	error: unrecognized instruction
+0f723011|223344556677885f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f723011|223344556677885f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f723011|223344556677885f5f5f5f5f	64	intel	error: unrecognized instruction
+0f723011|223344556677885f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f72d011|223344556677885f5f5f5f5f	32	intel	psrld mmx0, 0x11
+0f72d011|223344556677885f5f5f5f5f	32	plan9	PSRLD $0x11, M0
+0f72d011|223344556677885f5f5f5f5f	64	gnu	psrld $0x11,%mm0
+0f72d011|223344556677885f5f5f5f5f	64	intel	psrld mmx0, 0x11
+0f72d011|223344556677885f5f5f5f5f	64	plan9	PSRLD $0x11, M0
+0f72e011|223344556677885f5f5f5f5f	32	intel	psrad mmx0, 0x11
+0f72e011|223344556677885f5f5f5f5f	32	plan9	PSRAD $0x11, M0
+0f72e011|223344556677885f5f5f5f5f	64	gnu	psrad $0x11,%mm0
+0f72e011|223344556677885f5f5f5f5f	64	intel	psrad mmx0, 0x11
+0f72e011|223344556677885f5f5f5f5f	64	plan9	PSRAD $0x11, M0
+0f72f011|223344556677885f5f5f5f5f	32	intel	pslld mmx0, 0x11
+0f72f011|223344556677885f5f5f5f5f	32	plan9	PSLLD $0x11, M0
+0f72f011|223344556677885f5f5f5f5f	64	gnu	pslld $0x11,%mm0
+0f72f011|223344556677885f5f5f5f5f	64	intel	pslld mmx0, 0x11
+0f72f011|223344556677885f5f5f5f5f	64	plan9	PSLLD $0x11, M0
+0f7300|11223344556677885f5f5f5f5f	32	intel	error: unrecognized instruction
+0f7300|11223344556677885f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f7300|11223344556677885f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f7300|11223344556677885f5f5f5f5f	64	intel	error: unrecognized instruction
+0f7300|11223344556677885f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f731122|3344556677885f5f5f5f5f5f	32	intel	error: unrecognized instruction
+0f731122|3344556677885f5f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f731122|3344556677885f5f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f731122|3344556677885f5f5f5f5f5f	64	intel	error: unrecognized instruction
+0f731122|3344556677885f5f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f7318|11223344556677885f5f5f5f5f	32	intel	error: unrecognized instruction
+0f7318|11223344556677885f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f7318|11223344556677885f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f7318|11223344556677885f5f5f5f5f	64	intel	error: unrecognized instruction
+0f7318|11223344556677885f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f733011|223344556677885f5f5f5f5f	32	intel	error: unrecognized instruction
+0f733011|223344556677885f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f733011|223344556677885f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f733011|223344556677885f5f5f5f5f	64	intel	error: unrecognized instruction
+0f733011|223344556677885f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f7338|11223344556677885f5f5f5f5f	32	intel	error: unrecognized instruction
+0f7338|11223344556677885f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f7338|11223344556677885f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f7338|11223344556677885f5f5f5f5f	64	intel	error: unrecognized instruction
+0f7338|11223344556677885f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f73d011|223344556677885f5f5f5f5f	32	intel	psrlq mmx0, 0x11
+0f73d011|223344556677885f5f5f5f5f	32	plan9	PSRLQ $0x11, M0
+0f73d011|223344556677885f5f5f5f5f	64	gnu	psrlq $0x11,%mm0
+0f73d011|223344556677885f5f5f5f5f	64	intel	psrlq mmx0, 0x11
+0f73d011|223344556677885f5f5f5f5f	64	plan9	PSRLQ $0x11, M0
+0f73f011|223344556677885f5f5f5f5f	32	intel	psllq mmx0, 0x11
+0f73f011|223344556677885f5f5f5f5f	32	plan9	PSLLQ $0x11, M0
+0f73f011|223344556677885f5f5f5f5f	64	gnu	psllq $0x11,%mm0
+0f73f011|223344556677885f5f5f5f5f	64	intel	psllq mmx0, 0x11
+0f73f011|223344556677885f5f5f5f5f	64	plan9	PSLLQ $0x11, M0
+0f7411|223344556677885f5f5f5f5f5f	32	intel	pcmpeqb mmx2, qword ptr [ecx]
+0f7411|223344556677885f5f5f5f5f5f	32	plan9	PCMPEQB 0(CX), M2
+0f7411|223344556677885f5f5f5f5f5f	64	gnu	pcmpeqb (%rcx),%mm2
+0f7411|223344556677885f5f5f5f5f5f	64	intel	pcmpeqb mmx2, qword ptr [rcx]
+0f7411|223344556677885f5f5f5f5f5f	64	plan9	PCMPEQB 0(CX), M2
+0f7511|223344556677885f5f5f5f5f5f	32	intel	pcmpeqw mmx2, qword ptr [ecx]
+0f7511|223344556677885f5f5f5f5f5f	32	plan9	PCMPEQW 0(CX), M2
+0f7511|223344556677885f5f5f5f5f5f	64	gnu	pcmpeqw (%rcx),%mm2
+0f7511|223344556677885f5f5f5f5f5f	64	intel	pcmpeqw mmx2, qword ptr [rcx]
+0f7511|223344556677885f5f5f5f5f5f	64	plan9	PCMPEQW 0(CX), M2
+0f7611|223344556677885f5f5f5f5f5f	32	intel	pcmpeqd mmx2, qword ptr [ecx]
+0f7611|223344556677885f5f5f5f5f5f	32	plan9	PCMPEQD 0(CX), M2
+0f7611|223344556677885f5f5f5f5f5f	64	gnu	pcmpeqd (%rcx),%mm2
+0f7611|223344556677885f5f5f5f5f5f	64	intel	pcmpeqd mmx2, qword ptr [rcx]
+0f7611|223344556677885f5f5f5f5f5f	64	plan9	PCMPEQD 0(CX), M2
+0f77|11223344556677885f5f5f5f5f5f	32	intel	emms
+0f77|11223344556677885f5f5f5f5f5f	32	plan9	EMMS
+0f77|11223344556677885f5f5f5f5f5f	64	gnu	emms
+0f77|11223344556677885f5f5f5f5f5f	64	intel	emms
+0f77|11223344556677885f5f5f5f5f5f	64	plan9	EMMS
+0f7c|11223344556677885f5f5f5f5f5f	32	intel	error: unrecognized instruction
+0f7c|11223344556677885f5f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f7c|11223344556677885f5f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f7c|11223344556677885f5f5f5f5f5f	64	intel	error: unrecognized instruction
+0f7c|11223344556677885f5f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f7d|11223344556677885f5f5f5f5f5f	32	intel	error: unrecognized instruction
+0f7d|11223344556677885f5f5f5f5f5f	32	plan9	error: unrecognized instruction
+0f7d|11223344556677885f5f5f5f5f5f	64	gnu	error: unrecognized instruction
+0f7d|11223344556677885f5f5f5f5f5f	64	intel	error: unrecognized instruction
+0f7d|11223344556677885f5f5f5f5f5f	64	plan9	error: unrecognized instruction
+0f7e11|223344556677885f5f5f5f5f5f	32	intel	movd dword ptr [ecx], mmx2
+0f7e11|223344556677885f5f5f5f5f5f	32	plan9	MOVD M2, 0(CX)
+0f7e11|223344556677885f5f5f5f5f5f	64	gnu	movd %mm2,(%rcx)
+0f7e11|223344556677885f5f5f5f5f5f	64	intel	movd dword ptr [rcx], mmx2
+0f7e11|223344556677885f5f5f5f5f5f	64	plan9	MOVD M2, 0(CX)
+0f7f11|223344556677885f5f5f5f5f5f	32	intel	movq qword ptr [ecx], mmx2
+0f7f11|223344556677885f5f5f5f5f5f	32	plan9	MOVQ M2, 0(CX)
+0f7f11|223344556677885f5f5f5f5f5f	64	gnu	movq %mm2,(%rcx)
+0f7f11|223344556677885f5f5f5f5f5f	64	intel	movq qword ptr [rcx], mmx2
+0f7f11|223344556677885f5f5f5f5f5f	64	plan9	MOVQ M2, 0(CX)
+0f8011223344|556677885f5f5f5f5f5f	32	intel	jo .+0x44332211
+0f8011223344|556677885f5f5f5f5f5f	32	plan9	JO .+1144201745
+0f8011223344|556677885f5f5f5f5f5f	64	gnu	jo .+0x44332211
+0f8011223344|556677885f5f5f5f5f5f	64	intel	jo .+0x44332211
+0f8011223344|556677885f5f5f5f5f5f	64	plan9	JO .+1144201745
+0f8111223344|556677885f5f5f5f5f5f	32	intel	jno .+0x44332211
+0f8111223344|556677885f5f5f5f5f5f	32	plan9	JNO .+1144201745
+0f8111223344|556677885f5f5f5f5f5f	64	gnu	jno .+0x44332211
+0f8111223344|556677885f5f5f5f5f5f	64	intel	jno .+0x44332211
+0f8111223344|556677885f5f5f5f5f5f	64	plan9	JNO .+1144201745
+0f8211223344|556677885f5f5f5f5f5f	32	intel	jb .+0x44332211
+0f8211223344|556677885f5f5f5f5f5f	32	plan9	JB .+1144201745
+0f8211223344|556677885f5f5f5f5f5f	64	gnu	jb .+0x44332211
+0f8211223344|556677885f5f5f5f5f5f	64	intel	jb .+0x44332211
+0f8211223344|556677885f5f5f5f5f5f	64	plan9	JB .+1144201745
+0f8311223344|556677885f5f5f5f5f5f	32	intel	jnb .+0x44332211
+0f8311223344|556677885f5f5f5f5f5f	32	plan9	JAE .+1144201745
+0f8311223344|556677885f5f5f5f5f5f	64	gnu	jae .+0x44332211
+0f8311223344|556677885f5f5f5f5f5f	64	intel	jnb .+0x44332211
+0f8311223344|556677885f5f5f5f5f5f	64	plan9	JAE .+1144201745
+0f8411223344|556677885f5f5f5f5f5f	32	intel	jz .+0x44332211
+0f8411223344|556677885f5f5f5f5f5f	32	plan9	JE .+1144201745
+0f8411223344|556677885f5f5f5f5f5f	64	gnu	je .+0x44332211
+0f8411223344|556677885f5f5f5f5f5f	64	intel	jz .+0x44332211
+0f8411223344|556677885f5f5f5f5f5f	64	plan9	JE .+1144201745
+0f8511223344|556677885f5f5f5f5f5f	32	intel	jnz .+0x44332211
+0f8511223344|556677885f5f5f5f5f5f	32	plan9	JNE .+1144201745
+0f8511223344|556677885f5f5f5f5f5f	64	gnu	jne .+0x44332211
+0f8511223344|556677885f5f5f5f5f5f	64	intel	jnz .+0x44332211
+0f8511223344|556677885f5f5f5f5f5f	64	plan9	JNE .+1144201745
+0f8611223344|556677885f5f5f5f5f5f	32	intel	jbe .+0x44332211
+0f8611223344|556677885f5f5f5f5f5f	32	plan9	JBE .+1144201745
+0f8611223344|556677885f5f5f5f5f5f	64	gnu	jbe .+0x44332211
+0f8611223344|556677885f5f5f5f5f5f	64	intel	jbe .+0x44332211
+0f8611223344|556677885f5f5f5f5f5f	64	plan9	JBE .+1144201745
+0f8711223344|556677885f5f5f5f5f5f	32	intel	jnbe .+0x44332211
+0f8711223344|556677885f5f5f5f5f5f	32	plan9	JA .+1144201745
+0f8711223344|556677885f5f5f5f5f5f	64	gnu	ja .+0x44332211
+0f8711223344|556677885f5f5f5f5f5f	64	intel	jnbe .+0x44332211
+0f8711223344|556677885f5f5f5f5f5f	64	plan9	JA .+1144201745
+0f8811223344|556677885f5f5f5f5f5f	32	intel	js .+0x44332211
+0f8811223344|556677885f5f5f5f5f5f	32	plan9	JS .+1144201745
+0f8811223344|556677885f5f5f5f5f5f	64	gnu	js .+0x44332211
+0f8811223344|556677885f5f5f5f5f5f	64	intel	js .+0x44332211
+0f8811223344|556677885f5f5f5f5f5f	64	plan9	JS .+1144201745
+0f8911223344|556677885f5f5f5f5f5f	32	intel	jns .+0x44332211
+0f8911223344|556677885f5f5f5f5f5f	32	plan9	JNS .+1144201745
+0f8911223344|556677885f5f5f5f5f5f	64	gnu	jns .+0x44332211
+0f8911223344|556677885f5f5f5f5f5f	64	intel	jns .+0x44332211
+0f8911223344|556677885f5f5f5f5f5f	64	plan9	JNS .+1144201745
+0f8a11223344|556677885f5f5f5f5f5f	32	intel	jp .+0x44332211
+0f8a11223344|556677885f5f5f5f5f5f	32	plan9	JP .+1144201745
+0f8a11223344|556677885f5f5f5f5f5f	64	gnu	jp .+0x44332211
+0f8a11223344|556677885f5f5f5f5f5f	64	intel	jp .+0x44332211
+0f8a11223344|556677885f5f5f5f5f5f	64	plan9	JP .+1144201745
+0f8b11223344|556677885f5f5f5f5f5f	32	intel	jnp .+0x44332211
+0f8b11223344|556677885f5f5f5f5f5f	32	plan9	JNP .+1144201745
+0f8b11223344|556677885f5f5f5f5f5f	64	gnu	jnp .+0x44332211
+0f8b11223344|556677885f5f5f5f5f5f	64	intel	jnp .+0x44332211
+0f8b11223344|556677885f5f5f5f5f5f	64	plan9	JNP .+1144201745
+0f8c11223344|556677885f5f5f5f5f5f	32	intel	jl .+0x44332211
+0f8c11223344|556677885f5f5f5f5f5f	32	plan9	JL .+1144201745
+0f8c11223344|556677885f5f5f5f5f5f	64	gnu	jl .+0x44332211
+0f8c11223344|556677885f5f5f5f5f5f	64	intel	jl .+0x44332211
+0f8c11223344|556677885f5f5f5f5f5f	64	plan9	JL .+1144201745
+0f8d11223344|556677885f5f5f5f5f5f	32	intel	jnl .+0x44332211
+0f8d11223344|556677885f5f5f5f5f5f	32	plan9	JGE .+1144201745
+0f8d11223344|556677885f5f5f5f5f5f	64	gnu	jge .+0x44332211
+0f8d11223344|556677885f5f5f5f5f5f	64	intel	jnl .+0x44332211
+0f8d11223344|556677885f5f5f5f5f5f	64	plan9	JGE .+1144201745
+0f8e11223344|556677885f5f5f5f5f5f	32	intel	jle .+0x44332211
+0f8e11223344|556677885f5f5f5f5f5f	32	plan9	JLE .+1144201745
+0f8e11223344|556677885f5f5f5f5f5f	64	gnu	jle .+0x44332211
+0f8e11223344|556677885f5f5f5f5f5f	64	intel	jle .+0x44332211
+0f8e11223344|556677885f5f5f5f5f5f	64	plan9	JLE .+1144201745
+0f8f11223344|556677885f5f5f5f5f5f	32	intel	jnle .+0x44332211
+0f8f11223344|556677885f5f5f5f5f5f	32	plan9	JG .+1144201745
+0f8f11223344|556677885f5f5f5f5f5f	64	gnu	jg .+0x44332211
+0f8f11223344|556677885f5f5f5f5f5f	64	intel	jnle .+0x44332211
+0f8f11223344|556677885f5f5f5f5f5f	64	plan9	JG .+1144201745
+0f9011|223344556677885f5f5f5f5f5f	32	intel	seto byte ptr [ecx]
+0f9011|223344556677885f5f5f5f5f5f	32	plan9	SETO 0(CX)
+0f9011|223344556677885f5f5f5f5f5f	64	gnu	seto (%rcx)
+0f9011|223344556677885f5f5f5f5f5f	64	intel	seto byte ptr [rcx]
+0f9011|223344556677885f5f5f5f5f5f	64	plan9	SETO 0(CX)
+0f9111|223344556677885f5f5f5f5f5f	32	intel	setno byte ptr [ecx]
+0f9111|223344556677885f5f5f5f5f5f	32	plan9	SETNO 0(CX)
+0f9111|223344556677885f5f5f5f5f5f	64	gnu	setno (%rcx)
+0f9111|223344556677885f5f5f5f5f5f	64	intel	setno byte ptr [rcx]
+0f9111|223344556677885f5f5f5f5f5f	64	plan9	SETNO 0(CX)
+0f9211|223344556677885f5f5f5f5f5f	32	intel	setb byte ptr [ecx]
+0f9211|223344556677885f5f5f5f5f5f	32	plan9	SETB 0(CX)
+0f9211|223344556677885f5f5f5f5f5f	64	gnu	setb (%rcx)
+0f9211|223344556677885f5f5f5f5f5f	64	intel	setb byte ptr [rcx]
+0f9211|223344556677885f5f5f5f5f5f	64	plan9	SETB 0(CX)
+0f9311|223344556677885f5f5f5f5f5f	32	intel	setnb byte ptr [ecx]
+0f9311|223344556677885f5f5f5f5f5f	32	plan9	SETAE 0(CX)
+0f9311|223344556677885f5f5f5f5f5f	64	gnu	setae (%rcx)
+0f9311|223344556677885f5f5f5f5f5f	64	intel	setnb byte ptr [rcx]
+0f9311|223344556677885f5f5f5f5f5f	64	plan9	SETAE 0(CX)
+0f9411|223344556677885f5f5f5f5f5f	32	intel	setz byte ptr [ecx]
+0f9411|223344556677885f5f5f5f5f5f	32	plan9	SETE 0(CX)
+0f9411|223344556677885f5f5f5f5f5f	64	gnu	sete (%rcx)
+0f9411|223344556677885f5f5f5f5f5f	64	intel	setz byte ptr [rcx]
+0f9411|223344556677885f5f5f5f5f5f	64	plan9	SETE 0(CX)
+0f9511|223344556677885f5f5f5f5f5f	32	intel	setnz byte ptr [ecx]
+0f9511|223344556677885f5f5f5f5f5f	32	plan9	SETNE 0(CX)
+0f9511|223344556677885f5f5f5f5f5f	64	gnu	setne (%rcx)
+0f9511|223344556677885f5f5f5f5f5f	64	intel	setnz byte ptr [rcx]
+0f9511|223344556677885f5f5f5f5f5f	64	plan9	SETNE 0(CX)
+0f9611|223344556677885f5f5f5f5f5f	32	intel	setbe byte ptr [ecx]
+0f9611|223344556677885f5f5f5f5f5f	32	plan9	SETBE 0(CX)
+0f9611|223344556677885f5f5f5f5f5f	64	gnu	setbe (%rcx)
+0f9611|223344556677885f5f5f5f5f5f	64	intel	setbe byte ptr [rcx]
+0f9611|223344556677885f5f5f5f5f5f	64	plan9	SETBE 0(CX)
+0f9711|223344556677885f5f5f5f5f5f	32	intel	setnbe byte ptr [ecx]
+0f9711|223344556677885f5f5f5f5f5f	32	plan9	SETA 0(CX)
+0f9711|223344556677885f5f5f5f5f5f	64	gnu	seta (%rcx)
+0f9711|223344556677885f5f5f5f5f5f	64	intel	setnbe byte ptr [rcx]
+0f9711|223344556677885f5f5f5f5f5f	64	plan9	SETA 0(CX)
+0f9811|223344556677885f5f5f5f5f5f	32	intel	sets byte ptr [ecx]
+0f9811|223344556677885f5f5f5f5f5f	32	plan9	SETS 0(CX)
+0f9811|223344556677885f5f5f5f5f5f	64	gnu	sets (%rcx)
+0f9811|223344556677885f5f5f5f5f5f	64	intel	sets byte ptr [rcx]
+0f9811|223344556677885f5f5f5f5f5f	64	plan9	SETS 0(CX)
+0f9911|223344556677885f5f5f5f5f5f	32	intel	setns byte ptr [ecx]
+0f9911|223344556677885f5f5f5f5f5f	32	plan9	SETNS 0(CX)
+0f9911|223344556677885f5f5f5f5f5f	64	gnu	setns (%rcx)
+0f9911|223344556677885f5f5f5f5f5f	64	intel	setns byte ptr [rcx]
+0f9911|223344556677885f5f5f5f5f5f	64	plan9	SETNS 0(CX)
+0f9a11|223344556677885f5f5f5f5f5f	32	intel	setp byte ptr [ecx]
+0f9a11|223344556677885f5f5f5f5f5f	32	plan9	SETP 0(CX)
+0f9a11|223344556677885f5f5f5f5f5f	64	gnu	setp (%rcx)
+0f9a11|223344556677885f5f5f5f5f5f	64	intel	setp byte ptr [rcx]
+0f9a11|223344556677885f5f5f5f5f5f	64	plan9	SETP 0(CX)
+0f9b11|223344556677885f5f5f5f5f5f	32	intel	setnp byte ptr [ecx]
+0f9b11|223344556677885f5f5f5f5f5f	32	plan9	SETNP 0(CX)
+0f9b11|223344556677885f5f5f5f5f5f	64	gnu	setnp (%rcx)
+0f9b11|223344556677885f5f5f5f5f5f	64	intel	setnp byte ptr [rcx]
+0f9b11|223344556677885f5f5f5f5f5f	64	plan9	SETNP 0(CX)
+0f9c11|223344556677885f5f5f5f5f5f	32	intel	setl byte ptr [ecx]
+0f9c11|223344556677885f5f5f5f5f5f	32	plan9	SETL 0(CX)
+0f9c11|223344556677885f5f5f5f5f5f	64	gnu	setl (%rcx)
+0f9c11|223344556677885f5f5f5f5f5f	64	intel	setl byte ptr [rcx]
+0f9c11|223344556677885f5f5f5f5f5f	64	plan9	SETL 0(CX)
+0f9d11|223344556677885f5f5f5f5f5f	32	intel	setnl byte ptr [ecx]
+0f9d11|223344556677885f5f5f5f5f5f	32	plan9	SETGE 0(CX)
+0f9d11|223344556677885f5f5f5f5f5f	64	gnu	setge (%rcx)
+0f9d11|223344556677885f5f5f5f5f5f	64	intel	setnl byte ptr [rcx]
+0f9d11|223344556677885f5f5f5f5f5f	64	plan9	SETGE 0(CX)
+0f9e11|223344556677885f5f5f5f5f5f	32	intel	setle byte ptr [ecx]
+0f9e11|223344556677885f5f5f5f5f5f	32	plan9	SETLE 0(CX)
+0f9e11|223344556677885f5f5f5f5f5f	64	gnu	setle (%rcx)
+0f9e11|223344556677885f5f5f5f5f5f	64	intel	setle byte ptr [rcx]
+0f9e11|223344556677885f5f5f5f5f5f	64	plan9	SETLE 0(CX)
+0f9f11|223344556677885f5f5f5f5f5f	32	intel	setnle byte ptr [ecx]
+0f9f11|223344556677885f5f5f5f5f5f	32	plan9	SETG 0(CX)
+0f9f11|223344556677885f5f5f5f5f5f	64	gnu	setg (%rcx)
+0f9f11|223344556677885f5f5f5f5f5f	64	intel	setnle byte ptr [rcx]
+0f9f11|223344556677885f5f5f5f5f5f	64	plan9	SETG 0(CX)
+0fa0|11223344556677885f5f5f5f5f5f	32	intel	push fs
+0fa0|11223344556677885f5f5f5f5f5f	32	plan9	PUSHL FS
+0fa0|11223344556677885f5f5f5f5f5f	64	gnu	pushq %fs
+0fa0|11223344556677885f5f5f5f5f5f	64	intel	push fs
+0fa0|11223344556677885f5f5f5f5f5f	64	plan9	PUSHL FS
+0fa1|11223344556677885f5f5f5f5f5f	32	intel	pop fs
+0fa1|11223344556677885f5f5f5f5f5f	32	plan9	POPL FS
+0fa1|11223344556677885f5f5f5f5f5f	64	gnu	popq %fs
+0fa1|11223344556677885f5f5f5f5f5f	64	intel	pop fs
+0fa1|11223344556677885f5f5f5f5f5f	64	plan9	POPL FS
+0fa2|11223344556677885f5f5f5f5f5f	32	intel	cpuid
+0fa2|11223344556677885f5f5f5f5f5f	32	plan9	CPUID
+0fa2|11223344556677885f5f5f5f5f5f	64	gnu	cpuid
+0fa2|11223344556677885f5f5f5f5f5f	64	intel	cpuid
+0fa2|11223344556677885f5f5f5f5f5f	64	plan9	CPUID
+0fa311|223344556677885f5f5f5f5f5f	32	intel	bt dword ptr [ecx], edx
+0fa311|223344556677885f5f5f5f5f5f	32	plan9	BTL DX, 0(CX)
+0fa311|223344556677885f5f5f5f5f5f	64	gnu	bt %edx,(%rcx)
+0fa311|223344556677885f5f5f5f5f5f	64	intel	bt dword ptr [rcx], edx
+0fa311|223344556677885f5f5f5f5f5f	64	plan9	BTL DX, 0(CX)
+0fa41122|3344556677885f5f5f5f5f5f	32	intel	shld dword ptr [ecx], edx, 0x22
+0fa41122|3344556677885f5f5f5f5f5f	32	plan9	SHLDL $0x22, DX, 0(CX)
+0fa41122|3344556677885f5f5f5f5f5f	64	gnu	shld $0x22,%edx,(%rcx)
+0fa41122|3344556677885f5f5f5f5f5f	64	intel	shld dword ptr [rcx], edx, 0x22
+0fa41122|3344556677885f5f5f5f5f5f	64	plan9	SHLDL $0x22, DX, 0(CX)
+0fa511|223344556677885f5f5f5f5f5f	32	intel	shld dword ptr [ecx], edx, cl
+0fa511|223344556677885f5f5f5f5f5f	32	plan9	SHLDL CL, DX, 0(CX)
+0fa511|223344556677885f5f5f5f5f5f	64	gnu	shld %cl,%edx,(%rcx)
+0fa511|223344556677885f5f5f5f5f5f	64	intel	shld dword ptr [rcx], edx, cl
+0fa511|223344556677885f5f5f5f5f5f	64	plan9	SHLDL CL, DX, 0(CX)
+0fa8|11223344556677885f5f5f5f5f5f	32	intel	push gs
+0fa8|11223344556677885f5f5f5f5f5f	32	plan9	PUSHL GS
+0fa8|11223344556677885f5f5f5f5f5f	64	gnu	pushq %gs
+0fa8|11223344556677885f5f5f5f5f5f	64	intel	push gs
+0fa8|11223344556677885f5f5f5f5f5f	64	plan9	PUSHL GS
+0fa9|11223344556677885f5f5f5f5f5f	32	intel	pop gs
+0fa9|11223344556677885f5f5f5f5f5f	32	plan9	POPL GS
+0fa9|11223344556677885f5f5f5f5f5f	64	gnu	popq %gs
+0fa9|11223344556677885f5f5f5f5f5f	64	intel	pop gs
+0fa9|11223344556677885f5f5f5f5f5f	64	plan9	POPL GS
+0faa|11223344556677885f5f5f5f5f5f	32	intel	rsm
+0faa|11223344556677885f5f5f5f5f5f	32	plan9	RSM
+0faa|11223344556677885f5f5f5f5f5f	64	gnu	rsm
+0faa|11223344556677885f5f5f5f5f5f	64	intel	rsm
+0faa|11223344556677885f5f5f5f5f5f	64	plan9	RSM
+0fab11|223344556677885f5f5f5f5f5f	32	intel	bts dword ptr [ecx], edx
+0fab11|223344556677885f5f5f5f5f5f	32	plan9	BTSL DX, 0(CX)
+0fab11|223344556677885f5f5f5f5f5f	64	gnu	bts %edx,(%rcx)
+0fab11|223344556677885f5f5f5f5f5f	64	intel	bts dword ptr [rcx], edx
+0fab11|223344556677885f5f5f5f5f5f	64	plan9	BTSL DX, 0(CX)
+0fac1122|3344556677885f5f5f5f5f5f	32	intel	shrd dword ptr [ecx], edx, 0x22
+0fac1122|3344556677885f5f5f5f5f5f	32	plan9	SHRDL $0x22, DX, 0(CX)
+0fac1122|3344556677885f5f5f5f5f5f	64	gnu	shrd $0x22,%edx,(%rcx)
+0fac1122|3344556677885f5f5f5f5f5f	64	intel	shrd dword ptr [rcx], edx, 0x22
+0fac1122|3344556677885f5f5f5f5f5f	64	plan9	SHRDL $0x22, DX, 0(CX)
+0fad11|223344556677885f5f5f5f5f5f	32	intel	shrd dword ptr [ecx], edx, cl
+0fad11|223344556677885f5f5f5f5f5f	32	plan9	SHRDL CL, DX, 0(CX)
+0fad11|223344556677885f5f5f5f5f5f	64	gnu	shrd %cl,%edx,(%rcx)
+0fad11|223344556677885f5f5f5f5f5f	64	intel	shrd dword ptr [rcx], edx, cl
+0fad11|223344556677885f5f5f5f5f5f	64	plan9	SHRDL CL, DX, 0(CX)
+0fae00|11223344556677885f5f5f5f5f	32	intel	fxsave ptr [eax]
+0fae00|11223344556677885f5f5f5f5f	32	plan9	FXSAVE 0(AX)
+0fae00|11223344556677885f5f5f5f5f	64	gnu	fxsave (%rax)
+0fae00|11223344556677885f5f5f5f5f	64	intel	fxsave ptr [rax]
+0fae00|11223344556677885f5f5f5f5f	64	plan9	FXSAVE 0(AX)
+0fae08|11223344556677885f5f5f5f5f	32	intel	fxrstor ptr [eax]
+0fae08|11223344556677885f5f5f5f5f	32	plan9	FXRSTOR 0(AX)
+0fae08|11223344556677885f5f5f5f5f	64	gnu	fxrstor (%rax)
+0fae08|11223344556677885f5f5f5f5f	64	intel	fxrstor ptr [rax]
+0fae08|11223344556677885f5f5f5f5f	64	plan9	FXRSTOR 0(AX)
+0fae11|223344556677885f5f5f5f5f5f	32	intel	ldmxcsr dword ptr [ecx]
+0fae11|223344556677885f5f5f5f5f5f	32	plan9	LDMXCSR 0(CX)
+0fae11|223344556677885f5f5f5f5f5f	64	gnu	ldmxcsr (%rcx)
+0fae11|223344556677885f5f5f5f5f5f	64	intel	ldmxcsr dword ptr [rcx]
+0fae11|223344556677885f5f5f5f5f5f	64	plan9	LDMXCSR 0(CX)
+0fae18|11223344556677885f5f5f5f5f	32	intel	stmxcsr dword ptr [eax]
+0fae18|11223344556677885f5f5f5f5f	32	plan9	STMXCSR 0(AX)
+0fae18|11223344556677885f5f5f5f5f	64	gnu	stmxcsr (%rax)
+0fae18|11223344556677885f5f5f5f5f	64	intel	stmxcsr dword ptr [rax]
+0fae18|11223344556677885f5f5f5f5f	64	plan9	STMXCSR 0(AX)
+0fae20|11223344556677885f5f5f5f5f	32	intel	xsave ptr [eax]
+0fae20|11223344556677885f5f5f5f5f	32	plan9	XSAVE 0(AX)
+0fae20|11223344556677885f5f5f5f5f	64	gnu	xsave (%rax)
+0fae20|11223344556677885f5f5f5f5f	64	intel	xsave ptr [rax]
+0fae20|11223344556677885f5f5f5f5f	64	plan9	XSAVE 0(AX)
+0fae28|11223344556677885f5f5f5f5f	32	intel	xrstor ptr [eax]
+0fae28|11223344556677885f5f5f5f5f	32	plan9	XRSTOR 0(AX)
+0fae28|11223344556677885f5f5f5f5f	64	gnu	xrstor (%rax)
+0fae28|11223344556677885f5f5f5f5f	64	intel	xrstor ptr [rax]
+0fae28|11223344556677885f5f5f5f5f	64	plan9	XRSTOR 0(AX)
+0fae30|11223344556677885f5f5f5f5f	32	intel	xsaveopt ptr [eax]
+0fae30|11223344556677885f5f5f5f5f	32	plan9	XSAVEOPT 0(AX)
+0fae30|11223344556677885f5f5f5f5f	64	gnu	xsaveopt (%rax)
+0fae30|11223344556677885f5f5f5f5f	64	intel	xsaveopt ptr [rax]
+0fae30|11223344556677885f5f5f5f5f	64	plan9	XSAVEOPT 0(AX)
+0fae38|11223344556677885f5f5f5f5f	32	intel	clflush zmmword ptr [eax]
+0fae38|11223344556677885f5f5f5f5f	32	plan9	CLFLUSH 0(AX)
+0fae38|11223344556677885f5f5f5f5f	64	gnu	clflush (%rax)
+0fae38|11223344556677885f5f5f5f5f	64	intel	clflush zmmword ptr [rax]
+0fae38|11223344556677885f5f5f5f5f	64	plan9	CLFLUSH 0(AX)
+0faee8|11223344556677885f5f5f5f5f	32	intel	lfence
+0faee8|11223344556677885f5f5f5f5f	32	plan9	LFENCE
+0faee8|11223344556677885f5f5f5f5f	64	gnu	lfence
+0faee8|11223344556677885f5f5f5f5f	64	intel	lfence
+0faee8|11223344556677885f5f5f5f5f	64	plan9	LFENCE
+0faef0|11223344556677885f5f5f5f5f	32	intel	mfence
+0faef0|11223344556677885f5f5f5f5f	32	plan9	MFENCE
+0faef0|11223344556677885f5f5f5f5f	64	gnu	mfence
+0faef0|11223344556677885f5f5f5f5f	64	intel	mfence
+0faef0|11223344556677885f5f5f5f5f	64	plan9	MFENCE
+0faef8|11223344556677885f5f5f5f5f	32	intel	sfence
+0faef8|11223344556677885f5f5f5f5f	32	plan9	SFENCE
+0faef8|11223344556677885f5f5f5f5f	64	gnu	sfence
+0faef8|11223344556677885f5f5f5f5f	64	intel	sfence
+0faef8|11223344556677885f5f5f5f5f	64	plan9	SFENCE
+0faf11|223344556677885f5f5f5f5f5f	32	intel	imul edx, dword ptr [ecx]
+0faf11|223344556677885f5f5f5f5f5f	32	plan9	IMULL 0(CX), DX
+0faf11|223344556677885f5f5f5f5f5f	64	gnu	imul (%rcx),%edx
+0faf11|223344556677885f5f5f5f5f5f	64	intel	imul edx, dword ptr [rcx]
+0faf11|223344556677885f5f5f5f5f5f	64	plan9	IMULL 0(CX), DX
+0fb011|223344556677885f5f5f5f5f5f	32	intel	cmpxchg byte ptr [ecx], dl
+0fb011|223344556677885f5f5f5f5f5f	32	plan9	CMPXCHGL DL, 0(CX)
+0fb011|223344556677885f5f5f5f5f5f	64	gnu	cmpxchg %dl,(%rcx)
+0fb011|223344556677885f5f5f5f5f5f	64	intel	cmpxchg byte ptr [rcx], dl
+0fb011|223344556677885f5f5f5f5f5f	64	plan9	CMPXCHGL DL, 0(CX)
+0fb111|223344556677885f5f5f5f5f5f	32	intel	cmpxchg dword ptr [ecx], edx
+0fb111|223344556677885f5f5f5f5f5f	32	plan9	CMPXCHGL DX, 0(CX)
+0fb111|223344556677885f5f5f5f5f5f	64	gnu	cmpxchg %edx,(%rcx)
+0fb111|223344556677885f5f5f5f5f5f	64	intel	cmpxchg dword ptr [rcx], edx
+0fb111|223344556677885f5f5f5f5f5f	64	plan9	CMPXCHGL DX, 0(CX)
+0fb211|223344556677885f5f5f5f5f5f	32	intel	lss edx, ptr [ecx]
+0fb211|223344556677885f5f5f5f5f5f	32	plan9	LSS 0(CX), DX
+0fb211|223344556677885f5f5f5f5f5f	64	gnu	lss (%rcx),%edx
+0fb211|223344556677885f5f5f5f5f5f	64	intel	lss edx, ptr [rcx]
+0fb211|223344556677885f5f5f5f5f5f	64	plan9	LSS 0(CX), DX
+0fb311|223344556677885f5f5f5f5f5f	32	intel	btr dword ptr [ecx], edx
+0fb311|223344556677885f5f5f5f5f5f	32	plan9	BTRL DX, 0(CX)
+0fb311|223344556677885f5f5f5f5f5f	64	gnu	btr %edx,(%rcx)
+0fb311|223344556677885f5f5f5f5f5f	64	intel	btr dword ptr [rcx], edx
+0fb311|223344556677885f5f5f5f5f5f	64	plan9	BTRL DX, 0(CX)
+0fb411|223344556677885f5f5f5f5f5f	32	intel	lfs edx, ptr [ecx]
+0fb411|223344556677885f5f5f5f5f5f	32	plan9	LFS 0(CX), DX
+0fb411|223344556677885f5f5f5f5f5f	64	gnu	lfs (%rcx),%edx
+0fb411|223344556677885f5f5f5f5f5f	64	intel	lfs edx, ptr [rcx]
+0fb411|223344556677885f5f5f5f5f5f	64	plan9	LFS 0(CX), DX
+0fb511|223344556677885f5f5f5f5f5f	32	intel	lgs edx, ptr [ecx]
+0fb511|223344556677885f5f5f5f5f5f	32	plan9	LGS 0(CX), DX
+0fb511|223344556677885f5f5f5f5f5f	64	gnu	lgs (%rcx),%edx
+0fb511|223344556677885f5f5f5f5f5f	64	intel	lgs edx, ptr [rcx]
+0fb511|223344556677885f5f5f5f5f5f	64	plan9	LGS 0(CX), DX
+0fb611|223344556677885f5f5f5f5f5f	32	intel	movzx edx, byte ptr [ecx]
+0fb611|223344556677885f5f5f5f5f5f	32	plan9	MOVZX 0(CX), DX
+0fb611|223344556677885f5f5f5f5f5f	64	gnu	movzbl (%rcx),%edx
+0fb611|223344556677885f5f5f5f5f5f	64	intel	movzx edx, byte ptr [rcx]
+0fb611|223344556677885f5f5f5f5f5f	64	plan9	MOVZX 0(CX), DX
+0fb711|223344556677885f5f5f5f5f5f	32	intel	movzx edx, word ptr [ecx]
+0fb711|223344556677885f5f5f5f5f5f	32	plan9	MOVZX 0(CX), DX
+0fb711|223344556677885f5f5f5f5f5f	64	gnu	movzwl (%rcx),%edx
+0fb711|223344556677885f5f5f5f5f5f	64	intel	movzx edx, word ptr [rcx]
+0fb711|223344556677885f5f5f5f5f5f	64	plan9	MOVZX 0(CX), DX
+0fb8|11223344556677885f5f5f5f5f5f	32	intel	error: unrecognized instruction
+0fb8|11223344556677885f5f5f5f5f5f	32	plan9	error: unrecognized instruction
+0fb8|11223344556677885f5f5f5f5f5f	64	gnu	error: unrecognized instruction
+0fb8|11223344556677885f5f5f5f5f5f	64	intel	error: unrecognized instruction
+0fb8|11223344556677885f5f5f5f5f5f	64	plan9	error: unrecognized instruction
+0fb9|11223344556677885f5f5f5f5f5f	32	intel	ud1
+0fb9|11223344556677885f5f5f5f5f5f	32	plan9	UD1
+0fb9|11223344556677885f5f5f5f5f5f	64	gnu	ud1
+0fb9|11223344556677885f5f5f5f5f5f	64	intel	ud1
+0fb9|11223344556677885f5f5f5f5f5f	64	plan9	UD1
+0fba11|223344556677885f5f5f5f5f5f	32	intel	error: unrecognized instruction
+0fba11|223344556677885f5f5f5f5f5f	32	plan9	error: unrecognized instruction
+0fba11|223344556677885f5f5f5f5f5f	64	gnu	error: unrecognized instruction
+0fba11|223344556677885f5f5f5f5f5f	64	intel	error: unrecognized instruction
+0fba11|223344556677885f5f5f5f5f5f	64	plan9	error: unrecognized instruction
+0fba2011|223344556677885f5f5f5f5f	32	intel	bt dword ptr [eax], 0x11
+0fba2011|223344556677885f5f5f5f5f	32	plan9	BTL $0x11, 0(AX)
+0fba2011|223344556677885f5f5f5f5f	64	gnu	btl $0x11,(%rax)
+0fba2011|223344556677885f5f5f5f5f	64	intel	bt dword ptr [rax], 0x11
+0fba2011|223344556677885f5f5f5f5f	64	plan9	BTL $0x11, 0(AX)
+0fba2811|223344556677885f5f5f5f5f	32	intel	bts dword ptr [eax], 0x11
+0fba2811|223344556677885f5f5f5f5f	32	plan9	BTSL $0x11, 0(AX)
+0fba2811|223344556677885f5f5f5f5f	64	gnu	btsl $0x11,(%rax)
+0fba2811|223344556677885f5f5f5f5f	64	intel	bts dword ptr [rax], 0x11
+0fba2811|223344556677885f5f5f5f5f	64	plan9	BTSL $0x11, 0(AX)
+0fba3011|223344556677885f5f5f5f5f	32	intel	btr dword ptr [eax], 0x11
+0fba3011|223344556677885f5f5f5f5f	32	plan9	BTRL $0x11, 0(AX)
+0fba3011|223344556677885f5f5f5f5f	64	gnu	btrl $0x11,(%rax)
+0fba3011|223344556677885f5f5f5f5f	64	intel	btr dword ptr [rax], 0x11
+0fba3011|223344556677885f5f5f5f5f	64	plan9	BTRL $0x11, 0(AX)
+0fba3811|223344556677885f5f5f5f5f	32	intel	btc dword ptr [eax], 0x11
+0fba3811|223344556677885f5f5f5f5f	32	plan9	BTCL $0x11, 0(AX)
+0fba3811|223344556677885f5f5f5f5f	64	gnu	btcl $0x11,(%rax)
+0fba3811|223344556677885f5f5f5f5f	64	intel	btc dword ptr [rax], 0x11
+0fba3811|223344556677885f5f5f5f5f	64	plan9	BTCL $0x11, 0(AX)
+0fbb11|223344556677885f5f5f5f5f5f	32	intel	btc dword ptr [ecx], edx
+0fbb11|223344556677885f5f5f5f5f5f	32	plan9	BTCL DX, 0(CX)
+0fbb11|223344556677885f5f5f5f5f5f	64	gnu	btc %edx,(%rcx)
+0fbb11|223344556677885f5f5f5f5f5f	64	intel	btc dword ptr [rcx], edx
+0fbb11|223344556677885f5f5f5f5f5f	64	plan9	BTCL DX, 0(CX)
+0fbc11|223344556677885f5f5f5f5f5f	32	intel	bsf edx, dword ptr [ecx]
+0fbc11|223344556677885f5f5f5f5f5f	32	plan9	BSFL 0(CX), DX
+0fbc11|223344556677885f5f5f5f5f5f	64	gnu	bsf (%rcx),%edx
+0fbc11|223344556677885f5f5f5f5f5f	64	intel	bsf edx, dword ptr [rcx]
+0fbc11|223344556677885f5f5f5f5f5f	64	plan9	BSFL 0(CX), DX
+0fbd11|223344556677885f5f5f5f5f5f	32	intel	bsr edx, dword ptr [ecx]
+0fbd11|223344556677885f5f5f5f5f5f	32	plan9	BSRL 0(CX), DX
+0fbd11|223344556677885f5f5f5f5f5f	64	gnu	bsr (%rcx),%edx
+0fbd11|223344556677885f5f5f5f5f5f	64	intel	bsr edx, dword ptr [rcx]
+0fbd11|223344556677885f5f5f5f5f5f	64	plan9	BSRL 0(CX), DX
+0fbe11|223344556677885f5f5f5f5f5f	32	intel	movsx edx, byte ptr [ecx]
+0fbe11|223344556677885f5f5f5f5f5f	32	plan9	MOVSX 0(CX), DX
+0fbe11|223344556677885f5f5f5f5f5f	64	gnu	movsbl (%rcx),%edx
+0fbe11|223344556677885f5f5f5f5f5f	64	intel	movsx edx, byte ptr [rcx]
+0fbe11|223344556677885f5f5f5f5f5f	64	plan9	MOVSX 0(CX), DX
+0fbf11|223344556677885f5f5f5f5f5f	32	intel	movsx edx, word ptr [ecx]
+0fbf11|223344556677885f5f5f5f5f5f	32	plan9	MOVSX 0(CX), DX
+0fbf11|223344556677885f5f5f5f5f5f	64	gnu	movswl (%rcx),%edx
+0fbf11|223344556677885f5f5f5f5f5f	64	intel	movsx edx, word ptr [rcx]
+0fbf11|223344556677885f5f5f5f5f5f	64	plan9	MOVSX 0(CX), DX
+0fc011|223344556677885f5f5f5f5f5f	32	intel	xadd byte ptr [ecx], dl
+0fc011|223344556677885f5f5f5f5f5f	32	plan9	XADDL DL, 0(CX)
+0fc011|223344556677885f5f5f5f5f5f	64	gnu	xadd %dl,(%rcx)
+0fc011|223344556677885f5f5f5f5f5f	64	intel	xadd byte ptr [rcx], dl
+0fc011|223344556677885f5f5f5f5f5f	64	plan9	XADDL DL, 0(CX)
+0fc111|223344556677885f5f5f5f5f5f	32	intel	xadd dword ptr [ecx], edx
+0fc111|223344556677885f5f5f5f5f5f	32	plan9	XADDL DX, 0(CX)
+0fc111|223344556677885f5f5f5f5f5f	64	gnu	xadd %edx,(%rcx)
+0fc111|223344556677885f5f5f5f5f5f	64	intel	xadd dword ptr [rcx], edx
+0fc111|223344556677885f5f5f5f5f5f	64	plan9	XADDL DX, 0(CX)
+0fc20000|11223344556677885f5f5f5f	32	intel	cmpps xmm0, xmmword ptr [eax], 0x0
+0fc20000|11223344556677885f5f5f5f	32	plan9	CMPPS $0x0, 0(AX), X0
+0fc20000|11223344556677885f5f5f5f	64	gnu	cmpeqps (%rax),%xmm0
+0fc20000|11223344556677885f5f5f5f	64	intel	cmpps xmm0, xmmword ptr [rax], 0x0
+0fc20000|11223344556677885f5f5f5f	64	plan9	CMPPS $0x0, 0(AX), X0
+0fc311|223344556677885f5f5f5f5f5f	32	intel	movnti dword ptr [ecx], edx
+0fc311|223344556677885f5f5f5f5f5f	32	plan9	MOVNTIL DX, 0(CX)
+0fc311|223344556677885f5f5f5f5f5f	64	gnu	movnti %edx,(%rcx)
+0fc311|223344556677885f5f5f5f5f5f	64	intel	movnti dword ptr [rcx], edx
+0fc311|223344556677885f5f5f5f5f5f	64	plan9	MOVNTIL DX, 0(CX)
+0fc41122|3344556677885f5f5f5f5f5f	32	intel	pinsrw mmx2, word ptr [ecx], 0x22
+0fc41122|3344556677885f5f5f5f5f5f	32	plan9	PINSRW $0x22, 0(CX), M2
+0fc41122|3344556677885f5f5f5f5f5f	64	gnu	pinsrw $0x22,(%rcx),%mm2
+0fc41122|3344556677885f5f5f5f5f5f	64	intel	pinsrw mmx2, word ptr [rcx], 0x22
+0fc41122|3344556677885f5f5f5f5f5f	64	plan9	PINSRW $0x22, 0(CX), M2
+0fc51122|3344556677885f5f5f5f5f5f	32	intel	error: unrecognized instruction
+0fc51122|3344556677885f5f5f5f5f5f	32	plan9	error: unrecognized instruction
+0fc51122|3344556677885f5f5f5f5f5f	64	gnu	error: unrecognized instruction
+0fc51122|3344556677885f5f5f5f5f5f	64	intel	error: unrecognized instruction
+0fc51122|3344556677885f5f5f5f5f5f	64	plan9	error: unrecognized instruction
+0fc5c011|223344556677885f5f5f5f5f	32	intel	pextrw eax, mmx0, 0x11
+0fc5c011|223344556677885f5f5f5f5f	32	plan9	PEXTRW $0x11, M0, AX
+0fc5c011|223344556677885f5f5f5f5f	64	gnu	pextrw $0x11,%mm0,%eax
+0fc5c011|223344556677885f5f5f5f5f	64	intel	pextrw eax, mmx0, 0x11
+0fc5c011|223344556677885f5f5f5f5f	64	plan9	PEXTRW $0x11, M0, AX
+0fc61122|3344556677885f5f5f5f5f5f	32	intel	shufps xmm2, xmmword ptr [ecx], 0x22
+0fc61122|3344556677885f5f5f5f5f5f	32	plan9	SHUFPS $0x22, 0(CX), X2
+0fc61122|3344556677885f5f5f5f5f5f	64	gnu	shufps $0x22,(%rcx),%xmm2
+0fc61122|3344556677885f5f5f5f5f5f	64	intel	shufps xmm2, xmmword ptr [rcx], 0x22
+0fc61122|3344556677885f5f5f5f5f5f	64	plan9	SHUFPS $0x22, 0(CX), X2
+0fc708|11223344556677885f5f5f5f5f	32	intel	cmpxchg8b qword ptr [eax]
+0fc708|11223344556677885f5f5f5f5f	32	plan9	CMPXCHG8B 0(AX)
+0fc708|11223344556677885f5f5f5f5f	64	gnu	cmpxchg8b (%rax)
+0fc708|11223344556677885f5f5f5f5f	64	intel	cmpxchg8b qword ptr [rax]
+0fc708|11223344556677885f5f5f5f5f	64	plan9	CMPXCHG8B 0(AX)
+0fc718|11223344556677885f5f5f5f5f	32	intel	xrstors ptr [eax]
+0fc718|11223344556677885f5f5f5f5f	32	plan9	XRSTORS 0(AX)
+0fc718|11223344556677885f5f5f5f5f	64	gnu	xrstors (%rax)
+0fc718|11223344556677885f5f5f5f5f	64	intel	xrstors ptr [rax]
+0fc718|11223344556677885f5f5f5f5f	64	plan9	XRSTORS 0(AX)
+0fc720|11223344556677885f5f5f5f5f	32	intel	xsavec ptr [eax]
+0fc720|11223344556677885f5f5f5f5f	32	plan9	XSAVEC 0(AX)
+0fc720|11223344556677885f5f5f5f5f	64	gnu	xsavec (%rax)
+0fc720|11223344556677885f5f5f5f5f	64	intel	xsavec ptr [rax]
+0fc720|11223344556677885f5f5f5f5f	64	plan9	XSAVEC 0(AX)
+0fc728|11223344556677885f5f5f5f5f	32	intel	xsaves ptr [eax]
+0fc728|11223344556677885f5f5f5f5f	32	plan9	XSAVES 0(AX)
+0fc728|11223344556677885f5f5f5f5f	64	gnu	xsaves (%rax)
+0fc728|11223344556677885f5f5f5f5f	64	intel	xsaves ptr [rax]
+0fc728|11223344556677885f5f5f5f5f	64	plan9	XSAVES 0(AX)
+0fc730|11223344556677885f5f5f5f5f	32	intel	error: unrecognized instruction
+0fc730|11223344556677885f5f5f5f5f	32	plan9	error: unrecognized instruction
+0fc730|11223344556677885f5f5f5f5f	64	gnu	error: unrecognized instruction
+0fc730|11223344556677885f5f5f5f5f	64	intel	error: unrecognized instruction
+0fc730|11223344556677885f5f5f5f5f	64	plan9	error: unrecognized instruction
+0fc7f0|11223344556677885f5f5f5f5f	32	intel	rdrand eax
+0fc7f0|11223344556677885f5f5f5f5f	32	plan9	RDRAND AX
+0fc7f0|11223344556677885f5f5f5f5f	64	gnu	rdrand %eax
+0fc7f0|11223344556677885f5f5f5f5f	64	intel	rdrand eax
+0fc7f0|11223344556677885f5f5f5f5f	64	plan9	RDRAND AX
+0fc8|11223344556677885f5f5f5f5f5f	32	intel	bswap eax
+0fc8|11223344556677885f5f5f5f5f5f	32	plan9	BSWAP AX
+0fc8|11223344556677885f5f5f5f5f5f	64	gnu	bswap %eax
+0fc8|11223344556677885f5f5f5f5f5f	64	intel	bswap eax
+0fc8|11223344556677885f5f5f5f5f5f	64	plan9	BSWAP AX
+0fd0|11223344556677885f5f5f5f5f5f	32	intel	error: unrecognized instruction
+0fd0|11223344556677885f5f5f5f5f5f	32	plan9	error: unrecognized instruction
+0fd0|11223344556677885f5f5f5f5f5f	64	gnu	error: unrecognized instruction
+0fd0|11223344556677885f5f5f5f5f5f	64	intel	error: unrecognized instruction
+0fd0|11223344556677885f5f5f5f5f5f	64	plan9	error: unrecognized instruction
+0fd111|223344556677885f5f5f5f5f5f	32	intel	psrlw mmx2, qword ptr [ecx]
+0fd111|223344556677885f5f5f5f5f5f	32	plan9	PSRLW 0(CX), M2
+0fd111|223344556677885f5f5f5f5f5f	64	gnu	psrlw (%rcx),%mm2
+0fd111|223344556677885f5f5f5f5f5f	64	intel	psrlw mmx2, qword ptr [rcx]
+0fd111|223344556677885f5f5f5f5f5f	64	plan9	PSRLW 0(CX), M2
+0fd211|223344556677885f5f5f5f5f5f	32	intel	psrld mmx2, qword ptr [ecx]
+0fd211|223344556677885f5f5f5f5f5f	32	plan9	PSRLD 0(CX), M2
+0fd211|223344556677885f5f5f5f5f5f	64	gnu	psrld (%rcx),%mm2
+0fd211|223344556677885f5f5f5f5f5f	64	intel	psrld mmx2, qword ptr [rcx]
+0fd211|223344556677885f5f5f5f5f5f	64	plan9	PSRLD 0(CX), M2
+0fd311|223344556677885f5f5f5f5f5f	32	intel	psrlq mmx2, qword ptr [ecx]
+0fd311|223344556677885f5f5f5f5f5f	32	plan9	PSRLQ 0(CX), M2
+0fd311|223344556677885f5f5f5f5f5f	64	gnu	psrlq (%rcx),%mm2
+0fd311|223344556677885f5f5f5f5f5f	64	intel	psrlq mmx2, qword ptr [rcx]
+0fd311|223344556677885f5f5f5f5f5f	64	plan9	PSRLQ 0(CX), M2
+0fd411|223344556677885f5f5f5f5f5f	32	intel	paddq mmx2, qword ptr [ecx]
+0fd411|223344556677885f5f5f5f5f5f	32	plan9	PADDQ 0(CX), M2
+0fd411|223344556677885f5f5f5f5f5f	64	gnu	paddq (%rcx),%mm2
+0fd411|223344556677885f5f5f5f5f5f	64	intel	paddq mmx2, qword ptr [rcx]
+0fd411|223344556677885f5f5f5f5f5f	64	plan9	PADDQ 0(CX), M2
+0fd511|223344556677885f5f5f5f5f5f	32	intel	pmullw mmx2, qword ptr [ecx]
+0fd511|223344556677885f5f5f5f5f5f	32	plan9	PMULLW 0(CX), M2
+0fd511|223344556677885f5f5f5f5f5f	64	gnu	pmullw (%rcx),%mm2
+0fd511|223344556677885f5f5f5f5f5f	64	intel	pmullw mmx2, qword ptr [rcx]
+0fd511|223344556677885f5f5f5f5f5f	64	plan9	PMULLW 0(CX), M2
+0fd6|11223344556677885f5f5f5f5f5f	32	intel	error: unrecognized instruction
+0fd6|11223344556677885f5f5f5f5f5f	32	plan9	error: unrecognized instruction
+0fd6|11223344556677885f5f5f5f5f5f	64	gnu	error: unrecognized instruction
+0fd6|11223344556677885f5f5f5f5f5f	64	intel	error: unrecognized instruction
+0fd6|11223344556677885f5f5f5f5f5f	64	plan9	error: unrecognized instruction
+0fd711|223344556677885f5f5f5f5f5f	32	intel	error: unrecognized instruction
+0fd711|223344556677885f5f5f5f5f5f	32	plan9	error: unrecognized instruction
+0fd711|223344556677885f5f5f5f5f5f	64	gnu	error: unrecognized instruction
+0fd711|223344556677885f5f5f5f5f5f	64	intel	error: unrecognized instruction
+0fd711|223344556677885f5f5f5f5f5f	64	plan9	error: unrecognized instruction
+0fd7c0|11223344556677885f5f5f5f5f	32	intel	pmovmskb eax, mmx0
+0fd7c0|11223344556677885f5f5f5f5f	32	plan9	PMOVMSKB M0, AX
+0fd7c0|11223344556677885f5f5f5f5f	64	gnu	pmovmskb %mm0,%eax
+0fd7c0|11223344556677885f5f5f5f5f	64	intel	pmovmskb eax, mmx0
+0fd7c0|11223344556677885f5f5f5f5f	64	plan9	PMOVMSKB M0, AX
+0fd811|223344556677885f5f5f5f5f5f	32	intel	psubusb mmx2, qword ptr [ecx]
+0fd811|223344556677885f5f5f5f5f5f	32	plan9	PSUBUSB 0(CX), M2
+0fd811|223344556677885f5f5f5f5f5f	64	gnu	psubusb (%rcx),%mm2
+0fd811|223344556677885f5f5f5f5f5f	64	intel	psubusb mmx2, qword ptr [rcx]
+0fd811|223344556677885f5f5f5f5f5f	64	plan9	PSUBUSB 0(CX), M2
+0fd911|223344556677885f5f5f5f5f5f	32	intel	psubusw mmx2, qword ptr [ecx]
+0fd911|223344556677885f5f5f5f5f5f	32	plan9	PSUBUSW 0(CX), M2
+0fd911|223344556677885f5f5f5f5f5f	64	gnu	psubusw (%rcx),%mm2
+0fd911|223344556677885f5f5f5f5f5f	64	intel	psubusw mmx2, qword ptr [rcx]
+0fd911|223344556677885f5f5f5f5f5f	64	plan9	PSUBUSW 0(CX), M2
+0fda11|223344556677885f5f5f5f5f5f	32	intel	pminub mmx2, qword ptr [ecx]
+0fda11|223344556677885f5f5f5f5f5f	32	plan9	PMINUB 0(CX), M2
+0fda11|223344556677885f5f5f5f5f5f	64	gnu	pminub (%rcx),%mm2
+0fda11|223344556677885f5f5f5f5f5f	64	intel	pminub mmx2, qword ptr [rcx]
+0fda11|223344556677885f5f5f5f5f5f	64	plan9	PMINUB 0(CX), M2
+0fdb11|223344556677885f5f5f5f5f5f	32	intel	pand mmx2, qword ptr [ecx]
+0fdb11|223344556677885f5f5f5f5f5f	32	plan9	PAND 0(CX), M2
+0fdb11|223344556677885f5f5f5f5f5f	64	gnu	pand (%rcx),%mm2
+0fdb11|223344556677885f5f5f5f5f5f	64	intel	pand mmx2, qword ptr [rcx]
+0fdb11|223344556677885f5f5f5f5f5f	64	plan9	PAND 0(CX), M2
+0fdc11|223344556677885f5f5f5f5f5f	32	intel	paddusb mmx2, qword ptr [ecx]
+0fdc11|223344556677885f5f5f5f5f5f	32	plan9	PADDUSB 0(CX), M2
+0fdc11|223344556677885f5f5f5f5f5f	64	gnu	paddusb (%rcx),%mm2
+0fdc11|223344556677885f5f5f5f5f5f	64	intel	paddusb mmx2, qword ptr [rcx]
+0fdc11|223344556677885f5f5f5f5f5f	64	plan9	PADDUSB 0(CX), M2
+0fdd11|223344556677885f5f5f5f5f5f	32	intel	paddusw mmx2, qword ptr [ecx]
+0fdd11|223344556677885f5f5f5f5f5f	32	plan9	PADDUSW 0(CX), M2
+0fdd11|223344556677885f5f5f5f5f5f	64	gnu	paddusw (%rcx),%mm2
+0fdd11|223344556677885f5f5f5f5f5f	64	intel	paddusw mmx2, qword ptr [rcx]
+0fdd11|223344556677885f5f5f5f5f5f	64	plan9	PADDUSW 0(CX), M2
+0fde11|223344556677885f5f5f5f5f5f	32	intel	pmaxub mmx2, qword ptr [ecx]
+0fde11|223344556677885f5f5f5f5f5f	32	plan9	PMAXUB 0(CX), M2
+0fde11|223344556677885f5f5f5f5f5f	64	gnu	pmaxub (%rcx),%mm2
+0fde11|223344556677885f5f5f5f5f5f	64	intel	pmaxub mmx2, qword ptr [rcx]
+0fde11|223344556677885f5f5f5f5f5f	64	plan9	PMAXUB 0(CX), M2
+0fdf11|223344556677885f5f5f5f5f5f	32	intel	pandn mmx2, qword ptr [ecx]
+0fdf11|223344556677885f5f5f5f5f5f	32	plan9	PANDN 0(CX), M2
+0fdf11|223344556677885f5f5f5f5f5f	64	gnu	pandn (%rcx),%mm2
+0fdf11|223344556677885f5f5f5f5f5f	64	intel	pandn mmx2, qword ptr [rcx]
+0fdf11|223344556677885f5f5f5f5f5f	64	plan9	PANDN 0(CX), M2
+0fe011|223344556677885f5f5f5f5f5f	32	intel	pavgb mmx2, qword ptr [ecx]
+0fe011|223344556677885f5f5f5f5f5f	32	plan9	PAVGB 0(CX), M2
+0fe011|223344556677885f5f5f5f5f5f	64	gnu	pavgb (%rcx),%mm2
+0fe011|223344556677885f5f5f5f5f5f	64	intel	pavgb mmx2, qword ptr [rcx]
+0fe011|223344556677885f5f5f5f5f5f	64	plan9	PAVGB 0(CX), M2
+0fe111|223344556677885f5f5f5f5f5f	32	intel	psraw mmx2, qword ptr [ecx]
+0fe111|223344556677885f5f5f5f5f5f	32	plan9	PSRAW 0(CX), M2
+0fe111|223344556677885f5f5f5f5f5f	64	gnu	psraw (%rcx),%mm2
+0fe111|223344556677885f5f5f5f5f5f	64	intel	psraw mmx2, qword ptr [rcx]
+0fe111|223344556677885f5f5f5f5f5f	64	plan9	PSRAW 0(CX), M2
+0fe211|223344556677885f5f5f5f5f5f	32	intel	psrad mmx2, qword ptr [ecx]
+0fe211|223344556677885f5f5f5f5f5f	32	plan9	PSRAD 0(CX), M2
+0fe211|223344556677885f5f5f5f5f5f	64	gnu	psrad (%rcx),%mm2
+0fe211|223344556677885f5f5f5f5f5f	64	intel	psrad mmx2, qword ptr [rcx]
+0fe211|223344556677885f5f5f5f5f5f	64	plan9	PSRAD 0(CX), M2
+0fe311|223344556677885f5f5f5f5f5f	32	intel	pavgw mmx2, qword ptr [ecx]
+0fe311|223344556677885f5f5f5f5f5f	32	plan9	PAVGW 0(CX), M2
+0fe311|223344556677885f5f5f5f5f5f	64	gnu	pavgw (%rcx),%mm2
+0fe311|223344556677885f5f5f5f5f5f	64	intel	pavgw mmx2, qword ptr [rcx]
+0fe311|223344556677885f5f5f5f5f5f	64	plan9	PAVGW 0(CX), M2
+0fe411|223344556677885f5f5f5f5f5f	32	intel	pmulhuw mmx2, qword ptr [ecx]
+0fe411|223344556677885f5f5f5f5f5f	32	plan9	PMULHUW 0(CX), M2
+0fe411|223344556677885f5f5f5f5f5f	64	gnu	pmulhuw (%rcx),%mm2
+0fe411|223344556677885f5f5f5f5f5f	64	intel	pmulhuw mmx2, qword ptr [rcx]
+0fe411|223344556677885f5f5f5f5f5f	64	plan9	PMULHUW 0(CX), M2
+0fe511|223344556677885f5f5f5f5f5f	32	intel	pmulhw mmx2, qword ptr [ecx]
+0fe511|223344556677885f5f5f5f5f5f	32	plan9	PMULHW 0(CX), M2
+0fe511|223344556677885f5f5f5f5f5f	64	gnu	pmulhw (%rcx),%mm2
+0fe511|223344556677885f5f5f5f5f5f	64	intel	pmulhw mmx2, qword ptr [rcx]
+0fe511|223344556677885f5f5f5f5f5f	64	plan9	PMULHW 0(CX), M2
+0fe6|11223344556677885f5f5f5f5f5f	32	intel	error: unrecognized instruction
+0fe6|11223344556677885f5f5f5f5f5f	32	plan9	error: unrecognized instruction
+0fe6|11223344556677885f5f5f5f5f5f	64	gnu	error: unrecognized instruction
+0fe6|11223344556677885f5f5f5f5f5f	64	intel	error: unrecognized instruction
+0fe6|11223344556677885f5f5f5f5f5f	64	plan9	error: unrecognized instruction
+0fe711|223344556677885f5f5f5f5f5f	32	intel	movntq qword ptr [ecx], mmx2
+0fe711|223344556677885f5f5f5f5f5f	32	plan9	MOVNTQ M2, 0(CX)
+0fe711|223344556677885f5f5f5f5f5f	64	gnu	movntq %mm2,(%rcx)
+0fe711|223344556677885f5f5f5f5f5f	64	intel	movntq qword ptr [rcx], mmx2
+0fe711|223344556677885f5f5f5f5f5f	64	plan9	MOVNTQ M2, 0(CX)
+0fe811|223344556677885f5f5f5f5f5f	32	intel	psubsb mmx2, qword ptr [ecx]
+0fe811|223344556677885f5f5f5f5f5f	32	plan9	PSUBSB 0(CX), M2
+0fe811|223344556677885f5f5f5f5f5f	64	gnu	psubsb (%rcx),%mm2
+0fe811|223344556677885f5f5f5f5f5f	64	intel	psubsb mmx2, qword ptr [rcx]
+0fe811|223344556677885f5f5f5f5f5f	64	plan9	PSUBSB 0(CX), M2
+0fe911|223344556677885f5f5f5f5f5f	32	intel	psubsw mmx2, qword ptr [ecx]
+0fe911|223344556677885f5f5f5f5f5f	32	plan9	PSUBSW 0(CX), M2
+0fe911|223344556677885f5f5f5f5f5f	64	gnu	psubsw (%rcx),%mm2
+0fe911|223344556677885f5f5f5f5f5f	64	intel	psubsw mmx2, qword ptr [rcx]
+0fe911|223344556677885f5f5f5f5f5f	64	plan9	PSUBSW 0(CX), M2
+0fea11|223344556677885f5f5f5f5f5f	32	intel	pminsw mmx2, qword ptr [ecx]
+0fea11|223344556677885f5f5f5f5f5f	32	plan9	PMINSW 0(CX), M2
+0fea11|223344556677885f5f5f5f5f5f	64	gnu	pminsw (%rcx),%mm2
+0fea11|223344556677885f5f5f5f5f5f	64	intel	pminsw mmx2, qword ptr [rcx]
+0fea11|223344556677885f5f5f5f5f5f	64	plan9	PMINSW 0(CX), M2
+0feb11|223344556677885f5f5f5f5f5f	32	intel	por mmx2, qword ptr [ecx]
+0feb11|223344556677885f5f5f5f5f5f	32	plan9	POR 0(CX), M2
+0feb11|223344556677885f5f5f5f5f5f	64	gnu	por (%rcx),%mm2
+0feb11|223344556677885f5f5f5f5f5f	64	intel	por mmx2, qword ptr [rcx]
+0feb11|223344556677885f5f5f5f5f5f	64	plan9	POR 0(CX), M2
+0fec11|223344556677885f5f5f5f5f5f	32	intel	paddsb mmx2, qword ptr [ecx]
+0fec11|223344556677885f5f5f5f5f5f	32	plan9	PADDSB 0(CX), M2
+0fec11|223344556677885f5f5f5f5f5f	64	gnu	paddsb (%rcx),%mm2
+0fec11|223344556677885f5f5f5f5f5f	64	intel	paddsb mmx2, qword ptr [rcx]
+0fec11|223344556677885f5f5f5f5f5f	64	plan9	PADDSB 0(CX), M2
+0fed11|223344556677885f5f5f5f5f5f	32	intel	paddsw mmx2, qword ptr [ecx]
+0fed11|223344556677885f5f5f5f5f5f	32	plan9	PADDSW 0(CX), M2
+0fed11|223344556677885f5f5f5f5f5f	64	gnu	paddsw (%rcx),%mm2
+0fed11|223344556677885f5f5f5f5f5f	64	intel	paddsw mmx2, qword ptr [rcx]
+0fed11|223344556677885f5f5f5f5f5f	64	plan9	PADDSW 0(CX), M2
+0fee11|223344556677885f5f5f5f5f5f	32	intel	pmaxsw mmx2, qword ptr [ecx]
+0fee11|223344556677885f5f5f5f5f5f	32	plan9	PMAXSW 0(CX), M2
+0fee11|223344556677885f5f5f5f5f5f	64	gnu	pmaxsw (%rcx),%mm2
+0fee11|223344556677885f5f5f5f5f5f	64	intel	pmaxsw mmx2, qword ptr [rcx]
+0fee11|223344556677885f5f5f5f5f5f	64	plan9	PMAXSW 0(CX), M2
+0fef11|223344556677885f5f5f5f5f5f	32	intel	pxor mmx2, qword ptr [ecx]
+0fef11|223344556677885f5f5f5f5f5f	32	plan9	PXOR 0(CX), M2
+0fef11|223344556677885f5f5f5f5f5f	64	gnu	pxor (%rcx),%mm2
+0fef11|223344556677885f5f5f5f5f5f	64	intel	pxor mmx2, qword ptr [rcx]
+0fef11|223344556677885f5f5f5f5f5f	64	plan9	PXOR 0(CX), M2
+0ff0|11223344556677885f5f5f5f5f5f	32	intel	error: unrecognized instruction
+0ff0|11223344556677885f5f5f5f5f5f	32	plan9	error: unrecognized instruction
+0ff0|11223344556677885f5f5f5f5f5f	64	gnu	error: unrecognized instruction
+0ff0|11223344556677885f5f5f5f5f5f	64	intel	error: unrecognized instruction
+0ff0|11223344556677885f5f5f5f5f5f	64	plan9	error: unrecognized instruction
+0ff111|223344556677885f5f5f5f5f5f	32	intel	psllw mmx2, qword ptr [ecx]
+0ff111|223344556677885f5f5f5f5f5f	32	plan9	PSLLW 0(CX), M2
+0ff111|223344556677885f5f5f5f5f5f	64	gnu	psllw (%rcx),%mm2
+0ff111|223344556677885f5f5f5f5f5f	64	intel	psllw mmx2, qword ptr [rcx]
+0ff111|223344556677885f5f5f5f5f5f	64	plan9	PSLLW 0(CX), M2
+0ff211|223344556677885f5f5f5f5f5f	32	intel	pslld mmx2, qword ptr [ecx]
+0ff211|223344556677885f5f5f5f5f5f	32	plan9	PSLLD 0(CX), M2
+0ff211|223344556677885f5f5f5f5f5f	64	gnu	pslld (%rcx),%mm2
+0ff211|223344556677885f5f5f5f5f5f	64	intel	pslld mmx2, qword ptr [rcx]
+0ff211|223344556677885f5f5f5f5f5f	64	plan9	PSLLD 0(CX), M2
+0ff311|223344556677885f5f5f5f5f5f	32	intel	psllq mmx2, qword ptr [ecx]
+0ff311|223344556677885f5f5f5f5f5f	32	plan9	PSLLQ 0(CX), M2
+0ff311|223344556677885f5f5f5f5f5f	64	gnu	psllq (%rcx),%mm2
+0ff311|223344556677885f5f5f5f5f5f	64	intel	psllq mmx2, qword ptr [rcx]
+0ff311|223344556677885f5f5f5f5f5f	64	plan9	PSLLQ 0(CX), M2
+0ff411|223344556677885f5f5f5f5f5f	32	intel	pmuludq mmx2, qword ptr [ecx]
+0ff411|223344556677885f5f5f5f5f5f	32	plan9	PMULUDQ 0(CX), M2
+0ff411|223344556677885f5f5f5f5f5f	64	gnu	pmuludq (%rcx),%mm2
+0ff411|223344556677885f5f5f5f5f5f	64	intel	pmuludq mmx2, qword ptr [rcx]
+0ff411|223344556677885f5f5f5f5f5f	64	plan9	PMULUDQ 0(CX), M2
+0ff511|223344556677885f5f5f5f5f5f	32	intel	pmaddwd mmx2, qword ptr [ecx]
+0ff511|223344556677885f5f5f5f5f5f	32	plan9	PMADDWD 0(CX), M2
+0ff511|223344556677885f5f5f5f5f5f	64	gnu	pmaddwd (%rcx),%mm2
+0ff511|223344556677885f5f5f5f5f5f	64	intel	pmaddwd mmx2, qword ptr [rcx]
+0ff511|223344556677885f5f5f5f5f5f	64	plan9	PMADDWD 0(CX), M2
+0ff611|223344556677885f5f5f5f5f5f	32	intel	psadbw mmx2, qword ptr [ecx]
+0ff611|223344556677885f5f5f5f5f5f	32	plan9	PSADBW 0(CX), M2
+0ff611|223344556677885f5f5f5f5f5f	64	gnu	psadbw (%rcx),%mm2
+0ff611|223344556677885f5f5f5f5f5f	64	intel	psadbw mmx2, qword ptr [rcx]
+0ff611|223344556677885f5f5f5f5f5f	64	plan9	PSADBW 0(CX), M2
+0ff711|223344556677885f5f5f5f5f5f	32	intel	error: unrecognized instruction
+0ff711|223344556677885f5f5f5f5f5f	32	plan9	error: unrecognized instruction
+0ff711|223344556677885f5f5f5f5f5f	64	gnu	error: unrecognized instruction
+0ff711|223344556677885f5f5f5f5f5f	64	intel	error: unrecognized instruction
+0ff711|223344556677885f5f5f5f5f5f	64	plan9	error: unrecognized instruction
+0ff7c0|11223344556677885f5f5f5f5f	32	intel	maskmovq mmx0, mmx0
+0ff7c0|11223344556677885f5f5f5f5f	32	plan9	MASKMOVQ M0, M0
+0ff7c0|11223344556677885f5f5f5f5f	64	gnu	maskmovq %mm0,%mm0
+0ff7c0|11223344556677885f5f5f5f5f	64	intel	maskmovq mmx0, mmx0
+0ff7c0|11223344556677885f5f5f5f5f	64	plan9	MASKMOVQ M0, M0
+0ff811|223344556677885f5f5f5f5f5f	32	intel	psubb mmx2, qword ptr [ecx]
+0ff811|223344556677885f5f5f5f5f5f	32	plan9	PSUBB 0(CX), M2
+0ff811|223344556677885f5f5f5f5f5f	64	gnu	psubb (%rcx),%mm2
+0ff811|223344556677885f5f5f5f5f5f	64	intel	psubb mmx2, qword ptr [rcx]
+0ff811|223344556677885f5f5f5f5f5f	64	plan9	PSUBB 0(CX), M2
+0ff911|223344556677885f5f5f5f5f5f	32	intel	psubw mmx2, qword ptr [ecx]
+0ff911|223344556677885f5f5f5f5f5f	32	plan9	PSUBW 0(CX), M2
+0ff911|223344556677885f5f5f5f5f5f	64	gnu	psubw (%rcx),%mm2
+0ff911|223344556677885f5f5f5f5f5f	64	intel	psubw mmx2, qword ptr [rcx]
+0ff911|223344556677885f5f5f5f5f5f	64	plan9	PSUBW 0(CX), M2
+0ffa11|223344556677885f5f5f5f5f5f	32	intel	psubd mmx2, qword ptr [ecx]
+0ffa11|223344556677885f5f5f5f5f5f	32	plan9	PSUBD 0(CX), M2
+0ffa11|223344556677885f5f5f5f5f5f	64	gnu	psubd (%rcx),%mm2
+0ffa11|223344556677885f5f5f5f5f5f	64	intel	psubd mmx2, qword ptr [rcx]
+0ffa11|223344556677885f5f5f5f5f5f	64	plan9	PSUBD 0(CX), M2
+0ffb11|223344556677885f5f5f5f5f5f	32	intel	psubq mmx2, qword ptr [ecx]
+0ffb11|223344556677885f5f5f5f5f5f	32	plan9	PSUBQ 0(CX), M2
+0ffb11|223344556677885f5f5f5f5f5f	64	gnu	psubq (%rcx),%mm2
+0ffb11|223344556677885f5f5f5f5f5f	64	intel	psubq mmx2, qword ptr [rcx]
+0ffb11|223344556677885f5f5f5f5f5f	64	plan9	PSUBQ 0(CX), M2
+0ffc11|223344556677885f5f5f5f5f5f	32	intel	paddb mmx2, qword ptr [ecx]
+0ffc11|223344556677885f5f5f5f5f5f	32	plan9	PADDB 0(CX), M2
+0ffc11|223344556677885f5f5f5f5f5f	64	gnu	paddb (%rcx),%mm2
+0ffc11|223344556677885f5f5f5f5f5f	64	intel	paddb mmx2, qword ptr [rcx]
+0ffc11|223344556677885f5f5f5f5f5f	64	plan9	PADDB 0(CX), M2
+0ffd11|223344556677885f5f5f5f5f5f	32	intel	paddw mmx2, qword ptr [ecx]
+0ffd11|223344556677885f5f5f5f5f5f	32	plan9	PADDW 0(CX), M2
+0ffd11|223344556677885f5f5f5f5f5f	64	gnu	paddw (%rcx),%mm2
+0ffd11|223344556677885f5f5f5f5f5f	64	intel	paddw mmx2, qword ptr [rcx]
+0ffd11|223344556677885f5f5f5f5f5f	64	plan9	PADDW 0(CX), M2
+0ffe11|223344556677885f5f5f5f5f5f	32	intel	paddd mmx2, qword ptr [ecx]
+0ffe11|223344556677885f5f5f5f5f5f	32	plan9	PADDD 0(CX), M2
+0ffe11|223344556677885f5f5f5f5f5f	64	gnu	paddd (%rcx),%mm2
+0ffe11|223344556677885f5f5f5f5f5f	64	intel	paddd mmx2, qword ptr [rcx]
+0ffe11|223344556677885f5f5f5f5f5f	64	plan9	PADDD 0(CX), M2
+1011|223344556677885f5f5f5f5f5f5f	32	intel	adc byte ptr [ecx], dl
+1011|223344556677885f5f5f5f5f5f5f	32	plan9	ADCL DL, 0(CX)
+1011|223344556677885f5f5f5f5f5f5f	64	gnu	adc %dl,(%rcx)
+1011|223344556677885f5f5f5f5f5f5f	64	intel	adc byte ptr [rcx], dl
+1011|223344556677885f5f5f5f5f5f5f	64	plan9	ADCL DL, 0(CX)
+1111|223344556677885f5f5f5f5f5f5f	32	intel	adc dword ptr [ecx], edx
+1111|223344556677885f5f5f5f5f5f5f	32	plan9	ADCL DX, 0(CX)
+1111|223344556677885f5f5f5f5f5f5f	64	gnu	adc %edx,(%rcx)
+1111|223344556677885f5f5f5f5f5f5f	64	intel	adc dword ptr [rcx], edx
+1111|223344556677885f5f5f5f5f5f5f	64	plan9	ADCL DX, 0(CX)
+1211|223344556677885f5f5f5f5f5f5f	32	intel	adc dl, byte ptr [ecx]
+1211|223344556677885f5f5f5f5f5f5f	32	plan9	ADCL 0(CX), DL
+1211|223344556677885f5f5f5f5f5f5f	64	gnu	adc (%rcx),%dl
+1211|223344556677885f5f5f5f5f5f5f	64	intel	adc dl, byte ptr [rcx]
+1211|223344556677885f5f5f5f5f5f5f	64	plan9	ADCL 0(CX), DL
+1311|223344556677885f5f5f5f5f5f5f	32	intel	adc edx, dword ptr [ecx]
+1311|223344556677885f5f5f5f5f5f5f	32	plan9	ADCL 0(CX), DX
+1311|223344556677885f5f5f5f5f5f5f	64	gnu	adc (%rcx),%edx
+1311|223344556677885f5f5f5f5f5f5f	64	intel	adc edx, dword ptr [rcx]
+1311|223344556677885f5f5f5f5f5f5f	64	plan9	ADCL 0(CX), DX
+1411|223344556677885f5f5f5f5f5f5f	32	intel	adc al, 0x11
+1411|223344556677885f5f5f5f5f5f5f	32	plan9	ADCL $0x11, AL
+1411|223344556677885f5f5f5f5f5f5f	64	gnu	adc $0x11,%al
+1411|223344556677885f5f5f5f5f5f5f	64	intel	adc al, 0x11
+1411|223344556677885f5f5f5f5f5f5f	64	plan9	ADCL $0x11, AL
+1511223344|556677885f5f5f5f5f5f5f	32	intel	adc eax, 0x44332211
+1511223344|556677885f5f5f5f5f5f5f	32	plan9	ADCL $0x44332211, AX
+1511223344|556677885f5f5f5f5f5f5f	64	gnu	adc $0x44332211,%eax
+1511223344|556677885f5f5f5f5f5f5f	64	intel	adc eax, 0x44332211
+1511223344|556677885f5f5f5f5f5f5f	64	plan9	ADCL $0x44332211, AX
+16|11223344556677885f5f5f5f5f5f5f	32	intel	push ss
+16|11223344556677885f5f5f5f5f5f5f	32	plan9	PUSHL SS
+16|11223344556677885f5f5f5f5f5f5f	64	gnu	error: unrecognized instruction
+16|11223344556677885f5f5f5f5f5f5f	64	intel	error: unrecognized instruction
+16|11223344556677885f5f5f5f5f5f5f	64	plan9	error: unrecognized instruction
+17|11223344556677885f5f5f5f5f5f5f	32	intel	pop ss
+17|11223344556677885f5f5f5f5f5f5f	32	plan9	POPL SS
+17|11223344556677885f5f5f5f5f5f5f	64	gnu	error: unrecognized instruction
+17|11223344556677885f5f5f5f5f5f5f	64	intel	error: unrecognized instruction
+17|11223344556677885f5f5f5f5f5f5f	64	plan9	error: unrecognized instruction
+1811|223344556677885f5f5f5f5f5f5f	32	intel	sbb byte ptr [ecx], dl
+1811|223344556677885f5f5f5f5f5f5f	32	plan9	SBBL DL, 0(CX)
+1811|223344556677885f5f5f5f5f5f5f	64	gnu	sbb %dl,(%rcx)
+1811|223344556677885f5f5f5f5f5f5f	64	intel	sbb byte ptr [rcx], dl
+1811|223344556677885f5f5f5f5f5f5f	64	plan9	SBBL DL, 0(CX)
+1911|223344556677885f5f5f5f5f5f5f	32	intel	sbb dword ptr [ecx], edx
+1911|223344556677885f5f5f5f5f5f5f	32	plan9	SBBL DX, 0(CX)
+1911|223344556677885f5f5f5f5f5f5f	64	gnu	sbb %edx,(%rcx)
+1911|223344556677885f5f5f5f5f5f5f	64	intel	sbb dword ptr [rcx], edx
+1911|223344556677885f5f5f5f5f5f5f	64	plan9	SBBL DX, 0(CX)
+1a11|223344556677885f5f5f5f5f5f5f	32	intel	sbb dl, byte ptr [ecx]
+1a11|223344556677885f5f5f5f5f5f5f	32	plan9	SBBL 0(CX), DL
+1a11|223344556677885f5f5f5f5f5f5f	64	gnu	sbb (%rcx),%dl
+1a11|223344556677885f5f5f5f5f5f5f	64	intel	sbb dl, byte ptr [rcx]
+1a11|223344556677885f5f5f5f5f5f5f	64	plan9	SBBL 0(CX), DL
+1b11|223344556677885f5f5f5f5f5f5f	32	intel	sbb edx, dword ptr [ecx]
+1b11|223344556677885f5f5f5f5f5f5f	32	plan9	SBBL 0(CX), DX
+1b11|223344556677885f5f5f5f5f5f5f	64	gnu	sbb (%rcx),%edx
+1b11|223344556677885f5f5f5f5f5f5f	64	intel	sbb edx, dword ptr [rcx]
+1b11|223344556677885f5f5f5f5f5f5f	64	plan9	SBBL 0(CX), DX
+1c11|223344556677885f5f5f5f5f5f5f	32	intel	sbb al, 0x11
+1c11|223344556677885f5f5f5f5f5f5f	32	plan9	SBBL $0x11, AL
+1c11|223344556677885f5f5f5f5f5f5f	64	gnu	sbb $0x11,%al
+1c11|223344556677885f5f5f5f5f5f5f	64	intel	sbb al, 0x11
+1c11|223344556677885f5f5f5f5f5f5f	64	plan9	SBBL $0x11, AL
+1d11223344|556677885f5f5f5f5f5f5f	32	intel	sbb eax, 0x44332211
+1d11223344|556677885f5f5f5f5f5f5f	32	plan9	SBBL $0x44332211, AX
+1d11223344|556677885f5f5f5f5f5f5f	64	gnu	sbb $0x44332211,%eax
+1d11223344|556677885f5f5f5f5f5f5f	64	intel	sbb eax, 0x44332211
+1d11223344|556677885f5f5f5f5f5f5f	64	plan9	SBBL $0x44332211, AX
+1e|11223344556677885f5f5f5f5f5f5f	32	intel	push ds
+1e|11223344556677885f5f5f5f5f5f5f	32	plan9	PUSHL DS
+1e|11223344556677885f5f5f5f5f5f5f	64	gnu	error: unrecognized instruction
+1e|11223344556677885f5f5f5f5f5f5f	64	intel	error: unrecognized instruction
+1e|11223344556677885f5f5f5f5f5f5f	64	plan9	error: unrecognized instruction
+1f|11223344556677885f5f5f5f5f5f5f	32	intel	pop ds
+1f|11223344556677885f5f5f5f5f5f5f	32	plan9	POPL DS
+1f|11223344556677885f5f5f5f5f5f5f	64	gnu	error: unrecognized instruction
+1f|11223344556677885f5f5f5f5f5f5f	64	intel	error: unrecognized instruction
+1f|11223344556677885f5f5f5f5f5f5f	64	plan9	error: unrecognized instruction
+2011|223344556677885f5f5f5f5f5f5f	32	intel	and byte ptr [ecx], dl
+2011|223344556677885f5f5f5f5f5f5f	32	plan9	ANDL DL, 0(CX)
+2011|223344556677885f5f5f5f5f5f5f	64	gnu	and %dl,(%rcx)
+2011|223344556677885f5f5f5f5f5f5f	64	intel	and byte ptr [rcx], dl
+2011|223344556677885f5f5f5f5f5f5f	64	plan9	ANDL DL, 0(CX)
+2111|223344556677885f5f5f5f5f5f5f	32	intel	and dword ptr [ecx], edx
+2111|223344556677885f5f5f5f5f5f5f	32	plan9	ANDL DX, 0(CX)
+2111|223344556677885f5f5f5f5f5f5f	64	gnu	and %edx,(%rcx)
+2111|223344556677885f5f5f5f5f5f5f	64	intel	and dword ptr [rcx], edx
+2111|223344556677885f5f5f5f5f5f5f	64	plan9	ANDL DX, 0(CX)
+2211|223344556677885f5f5f5f5f5f5f	32	intel	and dl, byte ptr [ecx]
+2211|223344556677885f5f5f5f5f5f5f	32	plan9	ANDL 0(CX), DL
+2211|223344556677885f5f5f5f5f5f5f	64	gnu	and (%rcx),%dl
+2211|223344556677885f5f5f5f5f5f5f	64	intel	and dl, byte ptr [rcx]
+2211|223344556677885f5f5f5f5f5f5f	64	plan9	ANDL 0(CX), DL
+2311|223344556677885f5f5f5f5f5f5f	32	intel	and edx, dword ptr [ecx]
+2311|223344556677885f5f5f5f5f5f5f	32	plan9	ANDL 0(CX), DX
+2311|223344556677885f5f5f5f5f5f5f	64	gnu	and (%rcx),%edx
+2311|223344556677885f5f5f5f5f5f5f	64	intel	and edx, dword ptr [rcx]
+2311|223344556677885f5f5f5f5f5f5f	64	plan9	ANDL 0(CX), DX
+2411|223344556677885f5f5f5f5f5f5f	32	intel	and al, 0x11
+2411|223344556677885f5f5f5f5f5f5f	32	plan9	ANDL $0x11, AL
+2411|223344556677885f5f5f5f5f5f5f	64	gnu	and $0x11,%al
+2411|223344556677885f5f5f5f5f5f5f	64	intel	and al, 0x11
+2411|223344556677885f5f5f5f5f5f5f	64	plan9	ANDL $0x11, AL
+2511223344|556677885f5f5f5f5f5f5f	32	intel	and eax, 0x44332211
+2511223344|556677885f5f5f5f5f5f5f	32	plan9	ANDL $0x44332211, AX
+2511223344|556677885f5f5f5f5f5f5f	64	gnu	and $0x44332211,%eax
+2511223344|556677885f5f5f5f5f5f5f	64	intel	and eax, 0x44332211
+2511223344|556677885f5f5f5f5f5f5f	64	plan9	ANDL $0x44332211, AX
+266e|11223344556677885f5f5f5f5f5f	32	intel	outsb es
+266e|11223344556677885f5f5f5f5f5f	32	plan9	ES OUTSB ES:0(SI), DX
+266e|11223344556677885f5f5f5f5f5f	64	gnu	outsb %ds:%es:(%rsi),(%dx)
+266e|11223344556677885f5f5f5f5f5f	64	intel	outsb
+266e|11223344556677885f5f5f5f5f5f	64	plan9	ES OUTSB DS:0(SI), DX
+267011|223344556677885f5f5f5f5f5f	32	intel	jo .+0x11
+267011|223344556677885f5f5f5f5f5f	32	plan9	ES JO .+17
+267011|223344556677885f5f5f5f5f5f	64	gnu	es jo .+0x11
+267011|223344556677885f5f5f5f5f5f	64	intel	jo .+0x11
+267011|223344556677885f5f5f5f5f5f	64	plan9	ES JO .+17
+26a01122334455667788|5f5f5f5f5f5f	64	gnu	mov %es:-0x778899aabbccddef,%al
+26a01122334455667788|5f5f5f5f5f5f	64	intel	mov al, byte ptr [0x8877665544332211]
+26a01122334455667788|5f5f5f5f5f5f	64	plan9	ES MOVL -0x778899aabbccddef, AL
+26a011223344|556677885f5f5f5f5f5f	32	intel	mov al, byte ptr es:[0x44332211]
+26a011223344|556677885f5f5f5f5f5f	32	plan9	ES MOVL ES:0x44332211, AL
+26|8211223344556677885f5f5f5f5f5f	32	intel	es
+26|8211223344556677885f5f5f5f5f5f	32	plan9	ES Op(0)
+26|8211223344556677885f5f5f5f5f5f	64	gnu	es
+26|8211223344556677885f5f5f5f5f5f	64	intel	es
+26|8211223344556677885f5f5f5f5f5f	64	plan9	ES Op(0)
+27|11223344556677885f5f5f5f5f5f5f	32	intel	daa
+27|11223344556677885f5f5f5f5f5f5f	32	plan9	DAA
+27|11223344556677885f5f5f5f5f5f5f	64	gnu	error: unrecognized instruction
+27|11223344556677885f5f5f5f5f5f5f	64	intel	error: unrecognized instruction
+27|11223344556677885f5f5f5f5f5f5f	64	plan9	error: unrecognized instruction
+2811|223344556677885f5f5f5f5f5f5f	32	intel	sub byte ptr [ecx], dl
+2811|223344556677885f5f5f5f5f5f5f	32	plan9	SUBL DL, 0(CX)
+2811|223344556677885f5f5f5f5f5f5f	64	gnu	sub %dl,(%rcx)
+2811|223344556677885f5f5f5f5f5f5f	64	intel	sub byte ptr [rcx], dl
+2811|223344556677885f5f5f5f5f5f5f	64	plan9	SUBL DL, 0(CX)
+2911|223344556677885f5f5f5f5f5f5f	32	intel	sub dword ptr [ecx], edx
+2911|223344556677885f5f5f5f5f5f5f	32	plan9	SUBL DX, 0(CX)
+2911|223344556677885f5f5f5f5f5f5f	64	gnu	sub %edx,(%rcx)
+2911|223344556677885f5f5f5f5f5f5f	64	intel	sub dword ptr [rcx], edx
+2911|223344556677885f5f5f5f5f5f5f	64	plan9	SUBL DX, 0(CX)
+2a11|223344556677885f5f5f5f5f5f5f	32	intel	sub dl, byte ptr [ecx]
+2a11|223344556677885f5f5f5f5f5f5f	32	plan9	SUBL 0(CX), DL
+2a11|223344556677885f5f5f5f5f5f5f	64	gnu	sub (%rcx),%dl
+2a11|223344556677885f5f5f5f5f5f5f	64	intel	sub dl, byte ptr [rcx]
+2a11|223344556677885f5f5f5f5f5f5f	64	plan9	SUBL 0(CX), DL
+2b11|223344556677885f5f5f5f5f5f5f	32	intel	sub edx, dword ptr [ecx]
+2b11|223344556677885f5f5f5f5f5f5f	32	plan9	SUBL 0(CX), DX
+2b11|223344556677885f5f5f5f5f5f5f	64	gnu	sub (%rcx),%edx
+2b11|223344556677885f5f5f5f5f5f5f	64	intel	sub edx, dword ptr [rcx]
+2b11|223344556677885f5f5f5f5f5f5f	64	plan9	SUBL 0(CX), DX
+2c11|223344556677885f5f5f5f5f5f5f	32	intel	sub al, 0x11
+2c11|223344556677885f5f5f5f5f5f5f	32	plan9	SUBL $0x11, AL
+2c11|223344556677885f5f5f5f5f5f5f	64	gnu	sub $0x11,%al
+2c11|223344556677885f5f5f5f5f5f5f	64	intel	sub al, 0x11
+2c11|223344556677885f5f5f5f5f5f5f	64	plan9	SUBL $0x11, AL
+2d11223344|556677885f5f5f5f5f5f5f	32	intel	sub eax, 0x44332211
+2d11223344|556677885f5f5f5f5f5f5f	32	plan9	SUBL $0x44332211, AX
+2d11223344|556677885f5f5f5f5f5f5f	64	gnu	sub $0x44332211,%eax
+2d11223344|556677885f5f5f5f5f5f5f	64	intel	sub eax, 0x44332211
+2d11223344|556677885f5f5f5f5f5f5f	64	plan9	SUBL $0x44332211, AX
+2f|11223344556677885f5f5f5f5f5f5f	32	intel	das
+2f|11223344556677885f5f5f5f5f5f5f	32	plan9	DAS
+2f|11223344556677885f5f5f5f5f5f5f	64	gnu	error: unrecognized instruction
+2f|11223344556677885f5f5f5f5f5f5f	64	intel	error: unrecognized instruction
+2f|11223344556677885f5f5f5f5f5f5f	64	plan9	error: unrecognized instruction
+3011|223344556677885f5f5f5f5f5f5f	32	intel	xor byte ptr [ecx], dl
+3011|223344556677885f5f5f5f5f5f5f	32	plan9	XORL DL, 0(CX)
+3011|223344556677885f5f5f5f5f5f5f	64	gnu	xor %dl,(%rcx)
+3011|223344556677885f5f5f5f5f5f5f	64	intel	xor byte ptr [rcx], dl
+3011|223344556677885f5f5f5f5f5f5f	64	plan9	XORL DL, 0(CX)
+3111|223344556677885f5f5f5f5f5f5f	32	intel	xor dword ptr [ecx], edx
+3111|223344556677885f5f5f5f5f5f5f	32	plan9	XORL DX, 0(CX)
+3111|223344556677885f5f5f5f5f5f5f	64	gnu	xor %edx,(%rcx)
+3111|223344556677885f5f5f5f5f5f5f	64	intel	xor dword ptr [rcx], edx
+3111|223344556677885f5f5f5f5f5f5f	64	plan9	XORL DX, 0(CX)
+3211|223344556677885f5f5f5f5f5f5f	32	intel	xor dl, byte ptr [ecx]
+3211|223344556677885f5f5f5f5f5f5f	32	plan9	XORL 0(CX), DL
+3211|223344556677885f5f5f5f5f5f5f	64	gnu	xor (%rcx),%dl
+3211|223344556677885f5f5f5f5f5f5f	64	intel	xor dl, byte ptr [rcx]
+3211|223344556677885f5f5f5f5f5f5f	64	plan9	XORL 0(CX), DL
+3311|223344556677885f5f5f5f5f5f5f	32	intel	xor edx, dword ptr [ecx]
+3311|223344556677885f5f5f5f5f5f5f	32	plan9	XORL 0(CX), DX
+3311|223344556677885f5f5f5f5f5f5f	64	gnu	xor (%rcx),%edx
+3311|223344556677885f5f5f5f5f5f5f	64	intel	xor edx, dword ptr [rcx]
+3311|223344556677885f5f5f5f5f5f5f	64	plan9	XORL 0(CX), DX
+3411|223344556677885f5f5f5f5f5f5f	32	intel	xor al, 0x11
+3411|223344556677885f5f5f5f5f5f5f	32	plan9	XORL $0x11, AL
+3411|223344556677885f5f5f5f5f5f5f	64	gnu	xor $0x11,%al
+3411|223344556677885f5f5f5f5f5f5f	64	intel	xor al, 0x11
+3411|223344556677885f5f5f5f5f5f5f	64	plan9	XORL $0x11, AL
+3511223344|556677885f5f5f5f5f5f5f	32	intel	xor eax, 0x44332211
+3511223344|556677885f5f5f5f5f5f5f	32	plan9	XORL $0x44332211, AX
+3511223344|556677885f5f5f5f5f5f5f	64	gnu	xor $0x44332211,%eax
+3511223344|556677885f5f5f5f5f5f5f	64	intel	xor eax, 0x44332211
+3511223344|556677885f5f5f5f5f5f5f	64	plan9	XORL $0x44332211, AX
+3667f3660f2ac0|11223344556677885f	32	intel	addr16 cvtsi2ss xmm0, eax
+3667f3660f2ac0|11223344556677885f	32	plan9	CVTSI2SSW AX, X0
+3667f3660f2ac0|11223344556677885f	64	gnu	ss addr32 cvtsi2ss %ax,%xmm0
+3667f3660f2ac0|11223344556677885f	64	intel	addr32 cvtsi2ss xmm0, eax
+3667f3660f2ac0|11223344556677885f	64	plan9	CVTSI2SSW AX, X0
+36|67f3660ff7c011223344556677885f	64	gnu	ss
+36|f0f2f33e66f066f2f33e3666818411	32	intel	ss
+36|f0f2f33e66f066f2f33e3666818411	32	plan9	SS Op(0)
+36|f0f2f33e66f066f2f33e3666818411	64	gnu	ss
+36|f0f2f33e66f066f2f33e3666818411	64	intel	ss
+36|f0f2f33e66f066f2f33e3666818411	64	plan9	SS Op(0)
+36|f2f33ef0f78411223344556677885f	32	intel	ss
+36|f2f33ef0f78411223344556677885f	32	plan9	SS Op(0)
+36|f2f33ef0f78411223344556677885f	64	gnu	ss
+36|f2f33ef0f78411223344556677885f	64	intel	ss
+36|f2f33ef0f78411223344556677885f	64	plan9	SS Op(0)
+37|11223344556677885f5f5f5f5f5f5f	32	intel	aaa
+37|11223344556677885f5f5f5f5f5f5f	32	plan9	AAA
+37|11223344556677885f5f5f5f5f5f5f	64	gnu	error: unrecognized instruction
+37|11223344556677885f5f5f5f5f5f5f	64	intel	error: unrecognized instruction
+37|11223344556677885f5f5f5f5f5f5f	64	plan9	error: unrecognized instruction
+3811|223344556677885f5f5f5f5f5f5f	32	intel	cmp byte ptr [ecx], dl
+3811|223344556677885f5f5f5f5f5f5f	32	plan9	CMPL DL, 0(CX)
+3811|223344556677885f5f5f5f5f5f5f	64	gnu	cmp %dl,(%rcx)
+3811|223344556677885f5f5f5f5f5f5f	64	intel	cmp byte ptr [rcx], dl
+3811|223344556677885f5f5f5f5f5f5f	64	plan9	CMPL DL, 0(CX)
+3911|223344556677885f5f5f5f5f5f5f	32	intel	cmp dword ptr [ecx], edx
+3911|223344556677885f5f5f5f5f5f5f	32	plan9	CMPL DX, 0(CX)
+3911|223344556677885f5f5f5f5f5f5f	64	gnu	cmp %edx,(%rcx)
+3911|223344556677885f5f5f5f5f5f5f	64	intel	cmp dword ptr [rcx], edx
+3911|223344556677885f5f5f5f5f5f5f	64	plan9	CMPL DX, 0(CX)
+3a11|223344556677885f5f5f5f5f5f5f	32	intel	cmp dl, byte ptr [ecx]
+3a11|223344556677885f5f5f5f5f5f5f	32	plan9	CMPL 0(CX), DL
+3a11|223344556677885f5f5f5f5f5f5f	64	gnu	cmp (%rcx),%dl
+3a11|223344556677885f5f5f5f5f5f5f	64	intel	cmp dl, byte ptr [rcx]
+3a11|223344556677885f5f5f5f5f5f5f	64	plan9	CMPL 0(CX), DL
+3b11|223344556677885f5f5f5f5f5f5f	32	intel	cmp edx, dword ptr [ecx]
+3b11|223344556677885f5f5f5f5f5f5f	32	plan9	CMPL 0(CX), DX
+3b11|223344556677885f5f5f5f5f5f5f	64	gnu	cmp (%rcx),%edx
+3b11|223344556677885f5f5f5f5f5f5f	64	intel	cmp edx, dword ptr [rcx]
+3b11|223344556677885f5f5f5f5f5f5f	64	plan9	CMPL 0(CX), DX
+3c11|223344556677885f5f5f5f5f5f5f	32	intel	cmp al, 0x11
+3c11|223344556677885f5f5f5f5f5f5f	32	plan9	CMPL $0x11, AL
+3c11|223344556677885f5f5f5f5f5f5f	64	gnu	cmp $0x11,%al
+3c11|223344556677885f5f5f5f5f5f5f	64	intel	cmp al, 0x11
+3c11|223344556677885f5f5f5f5f5f5f	64	plan9	CMPL $0x11, AL
+3d11223344|556677885f5f5f5f5f5f5f	32	intel	cmp eax, 0x44332211
+3d11223344|556677885f5f5f5f5f5f5f	32	plan9	CMPL $0x44332211, AX
+3d11223344|556677885f5f5f5f5f5f5f	64	gnu	cmp $0x44332211,%eax
+3d11223344|556677885f5f5f5f5f5f5f	64	intel	cmp eax, 0x44332211
+3d11223344|556677885f5f5f5f5f5f5f	64	plan9	CMPL $0x44332211, AX
+3e67e011|223344556677885f5f5f5f5f	32	intel	addr16 loopne .+0x11
+3e67e011|223344556677885f5f5f5f5f	32	plan9	LOOPNE .+17
+3e67e011|223344556677885f5f5f5f5f	64	gnu	loopne,pt .+0x11
+3e67e011|223344556677885f5f5f5f5f	64	intel	addr32 loopne .+0x11
+3e67e011|223344556677885f5f5f5f5f	64	plan9	LOOPNE .+17
+3ef367660f38f011|223344556677885f	32	intel	movbe dx, word ptr [bx+di*1]
+3ef367660f38f011|223344556677885f	32	plan9	MOVBE DS:0(BX)(DI*1), DX
+3ef367660f38f011|223344556677885f	64	gnu	rep movbe %ds:(%ecx),%dx
+3ef367660f38f011|223344556677885f	64	intel	movbe dx, word ptr [ecx]
+3ef367660f38f011|223344556677885f	64	plan9	MOVBE 0(CX), DX
+3f|11223344556677885f5f5f5f5f5f5f	32	intel	aas
+3f|11223344556677885f5f5f5f5f5f5f	32	plan9	AAS
+3f|11223344556677885f5f5f5f5f5f5f	64	gnu	error: unrecognized instruction
+3f|11223344556677885f5f5f5f5f5f5f	64	intel	error: unrecognized instruction
+3f|11223344556677885f5f5f5f5f5f5f	64	plan9	error: unrecognized instruction
+4040|11223344556677885f5f5f5f5f5f	64	gnu	error: unrecognized instruction
+4040|11223344556677885f5f5f5f5f5f	64	intel	error: unrecognized instruction
+4040|11223344556677885f5f5f5f5f5f	64	plan9	error: unrecognized instruction
+4048|11223344556677885f5f5f5f5f5f	64	gnu	error: unrecognized instruction
+4048|11223344556677885f5f5f5f5f5f	64	intel	error: unrecognized instruction
+4048|11223344556677885f5f5f5f5f5f	64	plan9	error: unrecognized instruction
+40|11223344556677885f5f5f5f5f5f5f	32	intel	inc eax
+40|11223344556677885f5f5f5f5f5f5f	32	plan9	INCL AX
+480100|11223344556677885f5f5f5f5f	64	gnu	add %rax,(%rax)
+480100|11223344556677885f5f5f5f5f	64	intel	add qword ptr [rax], rax
+480100|11223344556677885f5f5f5f5f	64	plan9	ADDQ AX, 0(AX)
+480311|223344556677885f5f5f5f5f5f	64	gnu	add (%rcx),%rdx
+480311|223344556677885f5f5f5f5f5f	64	intel	add rdx, qword ptr [rcx]
+480311|223344556677885f5f5f5f5f5f	64	plan9	ADDQ 0(CX), DX
+480511223344|556677885f5f5f5f5f5f	64	gnu	add $0x44332211,%rax
+480511223344|556677885f5f5f5f5f5f	64	intel	add rax, 0x44332211
+480511223344|556677885f5f5f5f5f5f	64	plan9	ADDQ $0x44332211, AX
+480911|223344556677885f5f5f5f5f5f	64	gnu	or %rdx,(%rcx)
+480911|223344556677885f5f5f5f5f5f	64	intel	or qword ptr [rcx], rdx
+480911|223344556677885f5f5f5f5f5f	64	plan9	ORQ DX, 0(CX)
+480b11|223344556677885f5f5f5f5f5f	64	gnu	or (%rcx),%rdx
+480b11|223344556677885f5f5f5f5f5f	64	intel	or rdx, qword ptr [rcx]
+480b11|223344556677885f5f5f5f5f5f	64	plan9	ORQ 0(CX), DX
+480d11223344|556677885f5f5f5f5f5f	64	gnu	or $0x44332211,%rax
+480d11223344|556677885f5f5f5f5f5f	64	intel	or rax, 0x44332211
+480d11223344|556677885f5f5f5f5f5f	64	plan9	ORQ $0x44332211, AX
+480f0000|11223344556677885f5f5f5f	64	gnu	sldt (%rax)
+480f0000|11223344556677885f5f5f5f	64	intel	sldt word ptr [rax]
+480f0000|11223344556677885f5f5f5f	64	plan9	SLDT 0(AX)
+480f0008|11223344556677885f5f5f5f	64	gnu	str (%rax)
+480f0008|11223344556677885f5f5f5f	64	intel	str word ptr [rax]
+480f0008|11223344556677885f5f5f5f	64	plan9	STR 0(AX)
+480f0120|11223344556677885f5f5f5f	64	gnu	smsw (%rax)
+480f0120|11223344556677885f5f5f5f	64	intel	smsw word ptr [rax]
+480f0120|11223344556677885f5f5f5f	64	plan9	SMSW 0(AX)
+480f0211|223344556677885f5f5f5f5f	64	gnu	lar (%rcx),%rdx
+480f0211|223344556677885f5f5f5f5f	64	intel	lar rdx, word ptr [rcx]
+480f0211|223344556677885f5f5f5f5f	64	plan9	LAR 0(CX), DX
+480f0311|223344556677885f5f5f5f5f	64	gnu	lsl (%rcx),%rdx
+480f0311|223344556677885f5f5f5f5f	64	intel	lsl rdx, word ptr [rcx]
+480f0311|223344556677885f5f5f5f5f	64	plan9	LSL 0(CX), DX
+480f35|11223344556677885f5f5f5f5f	64	gnu	sysexit
+480f35|11223344556677885f5f5f5f5f	64	intel	sysexit
+480f35|11223344556677885f5f5f5f5f	64	plan9	SYSEXIT
+480f38f011|223344556677885f5f5f5f	64	gnu	movbe (%rcx),%rdx
+480f38f011|223344556677885f5f5f5f	64	intel	movbe rdx, qword ptr [rcx]
+480f38f011|223344556677885f5f5f5f	64	plan9	MOVBE 0(CX), DX
+480f38f111|223344556677885f5f5f5f	64	gnu	movbe %rdx,(%rcx)
+480f38f111|223344556677885f5f5f5f	64	intel	movbe qword ptr [rcx], rdx
+480f38f111|223344556677885f5f5f5f	64	plan9	MOVBE DX, 0(CX)
+480f4011|223344556677885f5f5f5f5f	64	gnu	cmovo (%rcx),%rdx
+480f4011|223344556677885f5f5f5f5f	64	intel	cmovo rdx, qword ptr [rcx]
+480f4011|223344556677885f5f5f5f5f	64	plan9	CMOVO 0(CX), DX
+480f4111|223344556677885f5f5f5f5f	64	gnu	cmovno (%rcx),%rdx
+480f4111|223344556677885f5f5f5f5f	64	intel	cmovno rdx, qword ptr [rcx]
+480f4111|223344556677885f5f5f5f5f	64	plan9	CMOVNO 0(CX), DX
+480f4211|223344556677885f5f5f5f5f	64	gnu	cmovb (%rcx),%rdx
+480f4211|223344556677885f5f5f5f5f	64	intel	cmovb rdx, qword ptr [rcx]
+480f4211|223344556677885f5f5f5f5f	64	plan9	CMOVB 0(CX), DX
+480f4311|223344556677885f5f5f5f5f	64	gnu	cmovae (%rcx),%rdx
+480f4311|223344556677885f5f5f5f5f	64	intel	cmovnb rdx, qword ptr [rcx]
+480f4311|223344556677885f5f5f5f5f	64	plan9	CMOVAE 0(CX), DX
+480f4411|223344556677885f5f5f5f5f	64	gnu	cmove (%rcx),%rdx
+480f4411|223344556677885f5f5f5f5f	64	intel	cmovz rdx, qword ptr [rcx]
+480f4411|223344556677885f5f5f5f5f	64	plan9	CMOVE 0(CX), DX
+480f4511|223344556677885f5f5f5f5f	64	gnu	cmovne (%rcx),%rdx
+480f4511|223344556677885f5f5f5f5f	64	intel	cmovnz rdx, qword ptr [rcx]
+480f4511|223344556677885f5f5f5f5f	64	plan9	CMOVNE 0(CX), DX
+480f4611|223344556677885f5f5f5f5f	64	gnu	cmovbe (%rcx),%rdx
+480f4611|223344556677885f5f5f5f5f	64	intel	cmovbe rdx, qword ptr [rcx]
+480f4611|223344556677885f5f5f5f5f	64	plan9	CMOVBE 0(CX), DX
+480f4711|223344556677885f5f5f5f5f	64	gnu	cmova (%rcx),%rdx
+480f4711|223344556677885f5f5f5f5f	64	intel	cmovnbe rdx, qword ptr [rcx]
+480f4711|223344556677885f5f5f5f5f	64	plan9	CMOVA 0(CX), DX
+480f4811|223344556677885f5f5f5f5f	64	gnu	cmovs (%rcx),%rdx
+480f4811|223344556677885f5f5f5f5f	64	intel	cmovs rdx, qword ptr [rcx]
+480f4811|223344556677885f5f5f5f5f	64	plan9	CMOVS 0(CX), DX
+480f4911|223344556677885f5f5f5f5f	64	gnu	cmovns (%rcx),%rdx
+480f4911|223344556677885f5f5f5f5f	64	intel	cmovns rdx, qword ptr [rcx]
+480f4911|223344556677885f5f5f5f5f	64	plan9	CMOVNS 0(CX), DX
+480f4a11|223344556677885f5f5f5f5f	64	gnu	cmovp (%rcx),%rdx
+480f4a11|223344556677885f5f5f5f5f	64	intel	cmovp rdx, qword ptr [rcx]
+480f4a11|223344556677885f5f5f5f5f	64	plan9	CMOVP 0(CX), DX
+480f4b11|223344556677885f5f5f5f5f	64	gnu	cmovnp (%rcx),%rdx
+480f4b11|223344556677885f5f5f5f5f	64	intel	cmovnp rdx, qword ptr [rcx]
+480f4b11|223344556677885f5f5f5f5f	64	plan9	CMOVNP 0(CX), DX
+480f4c11|223344556677885f5f5f5f5f	64	gnu	cmovl (%rcx),%rdx
+480f4c11|223344556677885f5f5f5f5f	64	intel	cmovl rdx, qword ptr [rcx]
+480f4c11|223344556677885f5f5f5f5f	64	plan9	CMOVL 0(CX), DX
+480f4d11|223344556677885f5f5f5f5f	64	gnu	cmovge (%rcx),%rdx
+480f4d11|223344556677885f5f5f5f5f	64	intel	cmovnl rdx, qword ptr [rcx]
+480f4d11|223344556677885f5f5f5f5f	64	plan9	CMOVGE 0(CX), DX
+480f4e11|223344556677885f5f5f5f5f	64	gnu	cmovle (%rcx),%rdx
+480f4e11|223344556677885f5f5f5f5f	64	intel	cmovle rdx, qword ptr [rcx]
+480f4e11|223344556677885f5f5f5f5f	64	plan9	CMOVLE 0(CX), DX
+480f4f11|223344556677885f5f5f5f5f	64	gnu	cmovg (%rcx),%rdx
+480f4f11|223344556677885f5f5f5f5f	64	intel	cmovnle rdx, qword ptr [rcx]
+480f4f11|223344556677885f5f5f5f5f	64	plan9	CMOVG 0(CX), DX
+480f6e11|223344556677885f5f5f5f5f	64	gnu	movq (%rcx),%mm2
+480f6e11|223344556677885f5f5f5f5f	64	intel	movq mmx2, qword ptr [rcx]
+480f6e11|223344556677885f5f5f5f5f	64	plan9	MOVQ 0(CX), M2
+480f7e11|223344556677885f5f5f5f5f	64	gnu	movq %mm2,(%rcx)
+480f7e11|223344556677885f5f5f5f5f	64	intel	movq qword ptr [rcx], mmx2
+480f7e11|223344556677885f5f5f5f5f	64	plan9	MOVQ M2, 0(CX)
+480f8011223344|556677885f5f5f5f5f	64	gnu	jo .+0x44332211
+480f8011223344|556677885f5f5f5f5f	64	intel	jo .+0x44332211
+480f8011223344|556677885f5f5f5f5f	64	plan9	JO .+1144201745
+480f8111223344|556677885f5f5f5f5f	64	gnu	jno .+0x44332211
+480f8111223344|556677885f5f5f5f5f	64	intel	jno .+0x44332211
+480f8111223344|556677885f5f5f5f5f	64	plan9	JNO .+1144201745
+480f8211223344|556677885f5f5f5f5f	64	gnu	jb .+0x44332211
+480f8211223344|556677885f5f5f5f5f	64	intel	jb .+0x44332211
+480f8211223344|556677885f5f5f5f5f	64	plan9	JB .+1144201745
+480f8311223344|556677885f5f5f5f5f	64	gnu	jae .+0x44332211
+480f8311223344|556677885f5f5f5f5f	64	intel	jnb .+0x44332211
+480f8311223344|556677885f5f5f5f5f	64	plan9	JAE .+1144201745
+480f8411223344|556677885f5f5f5f5f	64	gnu	je .+0x44332211
+480f8411223344|556677885f5f5f5f5f	64	intel	jz .+0x44332211
+480f8411223344|556677885f5f5f5f5f	64	plan9	JE .+1144201745
+480f8511223344|556677885f5f5f5f5f	64	gnu	jne .+0x44332211
+480f8511223344|556677885f5f5f5f5f	64	intel	jnz .+0x44332211
+480f8511223344|556677885f5f5f5f5f	64	plan9	JNE .+1144201745
+480f8611223344|556677885f5f5f5f5f	64	gnu	jbe .+0x44332211
+480f8611223344|556677885f5f5f5f5f	64	intel	jbe .+0x44332211
+480f8611223344|556677885f5f5f5f5f	64	plan9	JBE .+1144201745
+480f8711223344|556677885f5f5f5f5f	64	gnu	ja .+0x44332211
+480f8711223344|556677885f5f5f5f5f	64	intel	jnbe .+0x44332211
+480f8711223344|556677885f5f5f5f5f	64	plan9	JA .+1144201745
+480f8811223344|556677885f5f5f5f5f	64	gnu	js .+0x44332211
+480f8811223344|556677885f5f5f5f5f	64	intel	js .+0x44332211
+480f8811223344|556677885f5f5f5f5f	64	plan9	JS .+1144201745
+480f8911223344|556677885f5f5f5f5f	64	gnu	jns .+0x44332211
+480f8911223344|556677885f5f5f5f5f	64	intel	jns .+0x44332211
+480f8911223344|556677885f5f5f5f5f	64	plan9	JNS .+1144201745
+480f8a11223344|556677885f5f5f5f5f	64	gnu	jp .+0x44332211
+480f8a11223344|556677885f5f5f5f5f	64	intel	jp .+0x44332211
+480f8a11223344|556677885f5f5f5f5f	64	plan9	JP .+1144201745
+480f8b11223344|556677885f5f5f5f5f	64	gnu	jnp .+0x44332211
+480f8b11223344|556677885f5f5f5f5f	64	intel	jnp .+0x44332211
+480f8b11223344|556677885f5f5f5f5f	64	plan9	JNP .+1144201745
+480f8c11223344|556677885f5f5f5f5f	64	gnu	jl .+0x44332211
+480f8c11223344|556677885f5f5f5f5f	64	intel	jl .+0x44332211
+480f8c11223344|556677885f5f5f5f5f	64	plan9	JL .+1144201745
+480f8d11223344|556677885f5f5f5f5f	64	gnu	jge .+0x44332211
+480f8d11223344|556677885f5f5f5f5f	64	intel	jnl .+0x44332211
+480f8d11223344|556677885f5f5f5f5f	64	plan9	JGE .+1144201745
+480f8e11223344|556677885f5f5f5f5f	64	gnu	jle .+0x44332211
+480f8e11223344|556677885f5f5f5f5f	64	intel	jle .+0x44332211
+480f8e11223344|556677885f5f5f5f5f	64	plan9	JLE .+1144201745
+480f8f11223344|556677885f5f5f5f5f	64	gnu	jg .+0x44332211
+480f8f11223344|556677885f5f5f5f5f	64	intel	jnle .+0x44332211
+480f8f11223344|556677885f5f5f5f5f	64	plan9	JG .+1144201745
+480fa1|11223344556677885f5f5f5f5f	64	gnu	popq %fs
+480fa1|11223344556677885f5f5f5f5f	64	intel	pop fs
+480fa1|11223344556677885f5f5f5f5f	64	plan9	POPQ FS
+480fa311|223344556677885f5f5f5f5f	64	gnu	bt %rdx,(%rcx)
+480fa311|223344556677885f5f5f5f5f	64	intel	bt qword ptr [rcx], rdx
+480fa311|223344556677885f5f5f5f5f	64	plan9	BTQ DX, 0(CX)
+480fa41122|3344556677885f5f5f5f5f	64	gnu	shld $0x22,%rdx,(%rcx)
+480fa41122|3344556677885f5f5f5f5f	64	intel	shld qword ptr [rcx], rdx, 0x22
+480fa41122|3344556677885f5f5f5f5f	64	plan9	SHLDQ $0x22, DX, 0(CX)
+480fa511|223344556677885f5f5f5f5f	64	gnu	shld %cl,%rdx,(%rcx)
+480fa511|223344556677885f5f5f5f5f	64	intel	shld qword ptr [rcx], rdx, cl
+480fa511|223344556677885f5f5f5f5f	64	plan9	SHLDQ CL, DX, 0(CX)
+480fa9|11223344556677885f5f5f5f5f	64	gnu	popq %gs
+480fa9|11223344556677885f5f5f5f5f	64	intel	pop gs
+480fa9|11223344556677885f5f5f5f5f	64	plan9	POPQ GS
+480fab11|223344556677885f5f5f5f5f	64	gnu	bts %rdx,(%rcx)
+480fab11|223344556677885f5f5f5f5f	64	intel	bts qword ptr [rcx], rdx
+480fab11|223344556677885f5f5f5f5f	64	plan9	BTSQ DX, 0(CX)
+480fac1122|3344556677885f5f5f5f5f	64	gnu	shrd $0x22,%rdx,(%rcx)
+480fac1122|3344556677885f5f5f5f5f	64	intel	shrd qword ptr [rcx], rdx, 0x22
+480fac1122|3344556677885f5f5f5f5f	64	plan9	SHRDQ $0x22, DX, 0(CX)
+480fad11|223344556677885f5f5f5f5f	64	gnu	shrd %cl,%rdx,(%rcx)
+480fad11|223344556677885f5f5f5f5f	64	intel	shrd qword ptr [rcx], rdx, cl
+480fad11|223344556677885f5f5f5f5f	64	plan9	SHRDQ CL, DX, 0(CX)
+480fae00|11223344556677885f5f5f5f	64	gnu	fxsave64 (%rax)
+480fae00|11223344556677885f5f5f5f	64	intel	fxsave64 ptr [rax]
+480fae00|11223344556677885f5f5f5f	64	plan9	FXSAVE64 0(AX)
+480fae08|11223344556677885f5f5f5f	64	gnu	fxrstor64 (%rax)
+480fae08|11223344556677885f5f5f5f	64	intel	fxrstor64 ptr [rax]
+480fae08|11223344556677885f5f5f5f	64	plan9	FXRSTOR64 0(AX)
+480fae20|11223344556677885f5f5f5f	64	gnu	xsave64 (%rax)
+480fae20|11223344556677885f5f5f5f	64	intel	xsave64 ptr [rax]
+480fae20|11223344556677885f5f5f5f	64	plan9	XSAVE64 0(AX)
+480fae28|11223344556677885f5f5f5f	64	gnu	xrstor64 (%rax)
+480fae28|11223344556677885f5f5f5f	64	intel	xrstor64 ptr [rax]
+480fae28|11223344556677885f5f5f5f	64	plan9	XRSTOR64 0(AX)
+480fae30|11223344556677885f5f5f5f	64	gnu	xsaveopt64 (%rax)
+480fae30|11223344556677885f5f5f5f	64	intel	xsaveopt64 ptr [rax]
+480fae30|11223344556677885f5f5f5f	64	plan9	XSAVEOPT64 0(AX)
+480faf11|223344556677885f5f5f5f5f	64	gnu	imul (%rcx),%rdx
+480faf11|223344556677885f5f5f5f5f	64	intel	imul rdx, qword ptr [rcx]
+480faf11|223344556677885f5f5f5f5f	64	plan9	IMULQ 0(CX), DX
+480fb111|223344556677885f5f5f5f5f	64	gnu	cmpxchg %rdx,(%rcx)
+480fb111|223344556677885f5f5f5f5f	64	intel	cmpxchg qword ptr [rcx], rdx
+480fb111|223344556677885f5f5f5f5f	64	plan9	CMPXCHGQ DX, 0(CX)
+480fb211|223344556677885f5f5f5f5f	64	gnu	lss (%rcx),%rdx
+480fb211|223344556677885f5f5f5f5f	64	intel	lss rdx, ptr [rcx]
+480fb211|223344556677885f5f5f5f5f	64	plan9	LSS 0(CX), DX
+480fb311|223344556677885f5f5f5f5f	64	gnu	btr %rdx,(%rcx)
+480fb311|223344556677885f5f5f5f5f	64	intel	btr qword ptr [rcx], rdx
+480fb311|223344556677885f5f5f5f5f	64	plan9	BTRQ DX, 0(CX)
+480fb411|223344556677885f5f5f5f5f	64	gnu	lfs (%rcx),%rdx
+480fb411|223344556677885f5f5f5f5f	64	intel	lfs rdx, ptr [rcx]
+480fb411|223344556677885f5f5f5f5f	64	plan9	LFS 0(CX), DX
+480fb511|223344556677885f5f5f5f5f	64	gnu	lgs (%rcx),%rdx
+480fb511|223344556677885f5f5f5f5f	64	intel	lgs rdx, ptr [rcx]
+480fb511|223344556677885f5f5f5f5f	64	plan9	LGS 0(CX), DX
+480fb611|223344556677885f5f5f5f5f	64	gnu	movzbq (%rcx),%rdx
+480fb611|223344556677885f5f5f5f5f	64	intel	movzx rdx, byte ptr [rcx]
+480fb611|223344556677885f5f5f5f5f	64	plan9	MOVZX 0(CX), DX
+480fb711|223344556677885f5f5f5f5f	64	gnu	movzwq (%rcx),%rdx
+480fb711|223344556677885f5f5f5f5f	64	intel	movzx rdx, word ptr [rcx]
+480fb711|223344556677885f5f5f5f5f	64	plan9	MOVZX 0(CX), DX
+480fba2011|223344556677885f5f5f5f	64	gnu	btq $0x11,(%rax)
+480fba2011|223344556677885f5f5f5f	64	intel	bt qword ptr [rax], 0x11
+480fba2011|223344556677885f5f5f5f	64	plan9	BTQ $0x11, 0(AX)
+480fba2811|223344556677885f5f5f5f	64	gnu	btsq $0x11,(%rax)
+480fba2811|223344556677885f5f5f5f	64	intel	bts qword ptr [rax], 0x11
+480fba2811|223344556677885f5f5f5f	64	plan9	BTSQ $0x11, 0(AX)
+480fba3011|223344556677885f5f5f5f	64	gnu	btrq $0x11,(%rax)
+480fba3011|223344556677885f5f5f5f	64	intel	btr qword ptr [rax], 0x11
+480fba3011|223344556677885f5f5f5f	64	plan9	BTRQ $0x11, 0(AX)
+480fba3811|223344556677885f5f5f5f	64	gnu	btcq $0x11,(%rax)
+480fba3811|223344556677885f5f5f5f	64	intel	btc qword ptr [rax], 0x11
+480fba3811|223344556677885f5f5f5f	64	plan9	BTCQ $0x11, 0(AX)
+480fbb11|223344556677885f5f5f5f5f	64	gnu	btc %rdx,(%rcx)
+480fbb11|223344556677885f5f5f5f5f	64	intel	btc qword ptr [rcx], rdx
+480fbb11|223344556677885f5f5f5f5f	64	plan9	BTCQ DX, 0(CX)
+480fbc11|223344556677885f5f5f5f5f	64	gnu	bsf (%rcx),%rdx
+480fbc11|223344556677885f5f5f5f5f	64	intel	bsf rdx, qword ptr [rcx]
+480fbc11|223344556677885f5f5f5f5f	64	plan9	BSFQ 0(CX), DX
+480fbd11|223344556677885f5f5f5f5f	64	gnu	bsr (%rcx),%rdx
+480fbd11|223344556677885f5f5f5f5f	64	intel	bsr rdx, qword ptr [rcx]
+480fbd11|223344556677885f5f5f5f5f	64	plan9	BSRQ 0(CX), DX
+480fbe11|223344556677885f5f5f5f5f	64	gnu	movsbq (%rcx),%rdx
+480fbe11|223344556677885f5f5f5f5f	64	intel	movsx rdx, byte ptr [rcx]
+480fbe11|223344556677885f5f5f5f5f	64	plan9	MOVSX 0(CX), DX
+480fbf11|223344556677885f5f5f5f5f	64	gnu	movswq (%rcx),%rdx
+480fbf11|223344556677885f5f5f5f5f	64	intel	movsx rdx, word ptr [rcx]
+480fbf11|223344556677885f5f5f5f5f	64	plan9	MOVSX 0(CX), DX
+480fc111|223344556677885f5f5f5f5f	64	gnu	xadd %rdx,(%rcx)
+480fc111|223344556677885f5f5f5f5f	64	intel	xadd qword ptr [rcx], rdx
+480fc111|223344556677885f5f5f5f5f	64	plan9	XADDQ DX, 0(CX)
+480fc311|223344556677885f5f5f5f5f	64	gnu	movnti %rdx,(%rcx)
+480fc311|223344556677885f5f5f5f5f	64	intel	movnti qword ptr [rcx], rdx
+480fc311|223344556677885f5f5f5f5f	64	plan9	MOVNTIQ DX, 0(CX)
+480fc708|11223344556677885f5f5f5f	64	gnu	cmpxchg16b (%rax)
+480fc708|11223344556677885f5f5f5f	64	intel	cmpxchg16b xmmword ptr [rax]
+480fc708|11223344556677885f5f5f5f	64	plan9	CMPXCHG16B 0(AX)
+480fc718|11223344556677885f5f5f5f	64	gnu	xrstors64 (%rax)
+480fc718|11223344556677885f5f5f5f	64	intel	xrstors64 ptr [rax]
+480fc718|11223344556677885f5f5f5f	64	plan9	XRSTORS64 0(AX)
+480fc720|11223344556677885f5f5f5f	64	gnu	xsavec64 (%rax)
+480fc720|11223344556677885f5f5f5f	64	intel	xsavec64 ptr [rax]
+480fc720|11223344556677885f5f5f5f	64	plan9	XSAVEC64 0(AX)
+480fc728|11223344556677885f5f5f5f	64	gnu	xsaves64 (%rax)
+480fc728|11223344556677885f5f5f5f	64	intel	xsaves64 ptr [rax]
+480fc728|11223344556677885f5f5f5f	64	plan9	XSAVES64 0(AX)
+480fc730|11223344556677885f5f5f5f	64	gnu	rdrand
+480fc730|11223344556677885f5f5f5f	64	intel	rdrand
+480fc730|11223344556677885f5f5f5f	64	plan9	RDRAND
+480fc8|11223344556677885f5f5f5f5f	64	gnu	bswap %rax
+480fc8|11223344556677885f5f5f5f5f	64	intel	bswap rax
+480fc8|11223344556677885f5f5f5f5f	64	plan9	BSWAP AX
+481122|3344556677885f5f5f5f5f5f5f	64	gnu	adc %rsp,(%rdx)
+481122|3344556677885f5f5f5f5f5f5f	64	intel	adc qword ptr [rdx], rsp
+481122|3344556677885f5f5f5f5f5f5f	64	plan9	ADCQ SP, 0(DX)
+481311|223344556677885f5f5f5f5f5f	64	gnu	adc (%rcx),%rdx
+481311|223344556677885f5f5f5f5f5f	64	intel	adc rdx, qword ptr [rcx]
+481311|223344556677885f5f5f5f5f5f	64	plan9	ADCQ 0(CX), DX
+481511223344|556677885f5f5f5f5f5f	64	gnu	adc $0x44332211,%rax
+481511223344|556677885f5f5f5f5f5f	64	intel	adc rax, 0x44332211
+481511223344|556677885f5f5f5f5f5f	64	plan9	ADCQ $0x44332211, AX
+481911|223344556677885f5f5f5f5f5f	64	gnu	sbb %rdx,(%rcx)
+481911|223344556677885f5f5f5f5f5f	64	intel	sbb qword ptr [rcx], rdx
+481911|223344556677885f5f5f5f5f5f	64	plan9	SBBQ DX, 0(CX)
+481b11|223344556677885f5f5f5f5f5f	64	gnu	sbb (%rcx),%rdx
+481b11|223344556677885f5f5f5f5f5f	64	intel	sbb rdx, qword ptr [rcx]
+481b11|223344556677885f5f5f5f5f5f	64	plan9	SBBQ 0(CX), DX
+481d11223344|556677885f5f5f5f5f5f	64	gnu	sbb $0x44332211,%rax
+481d11223344|556677885f5f5f5f5f5f	64	intel	sbb rax, 0x44332211
+481d11223344|556677885f5f5f5f5f5f	64	plan9	SBBQ $0x44332211, AX
+482111|223344556677885f5f5f5f5f5f	64	gnu	and %rdx,(%rcx)
+482111|223344556677885f5f5f5f5f5f	64	intel	and qword ptr [rcx], rdx
+482111|223344556677885f5f5f5f5f5f	64	plan9	ANDQ DX, 0(CX)
+482311|223344556677885f5f5f5f5f5f	64	gnu	and (%rcx),%rdx
+482311|223344556677885f5f5f5f5f5f	64	intel	and rdx, qword ptr [rcx]
+482311|223344556677885f5f5f5f5f5f	64	plan9	ANDQ 0(CX), DX
+482511223344|556677885f5f5f5f5f5f	64	gnu	and $0x44332211,%rax
+482511223344|556677885f5f5f5f5f5f	64	intel	and rax, 0x44332211
+482511223344|556677885f5f5f5f5f5f	64	plan9	ANDQ $0x44332211, AX
+482911|223344556677885f5f5f5f5f5f	64	gnu	sub %rdx,(%rcx)
+482911|223344556677885f5f5f5f5f5f	64	intel	sub qword ptr [rcx], rdx
+482911|223344556677885f5f5f5f5f5f	64	plan9	SUBQ DX, 0(CX)
+482b11|223344556677885f5f5f5f5f5f	64	gnu	sub (%rcx),%rdx
+482b11|223344556677885f5f5f5f5f5f	64	intel	sub rdx, qword ptr [rcx]
+482b11|223344556677885f5f5f5f5f5f	64	plan9	SUBQ 0(CX), DX
+482d11223344|556677885f5f5f5f5f5f	64	gnu	sub $0x44332211,%rax
+482d11223344|556677885f5f5f5f5f5f	64	intel	sub rax, 0x44332211
+482d11223344|556677885f5f5f5f5f5f	64	plan9	SUBQ $0x44332211, AX
+483111|223344556677885f5f5f5f5f5f	64	gnu	xor %rdx,(%rcx)
+483111|223344556677885f5f5f5f5f5f	64	intel	xor qword ptr [rcx], rdx
+483111|223344556677885f5f5f5f5f5f	64	plan9	XORQ DX, 0(CX)
+483311|223344556677885f5f5f5f5f5f	64	gnu	xor (%rcx),%rdx
+483311|223344556677885f5f5f5f5f5f	64	intel	xor rdx, qword ptr [rcx]
+483311|223344556677885f5f5f5f5f5f	64	plan9	XORQ 0(CX), DX
+483511223344|556677885f5f5f5f5f5f	64	gnu	xor $0x44332211,%rax
+483511223344|556677885f5f5f5f5f5f	64	intel	xor rax, 0x44332211
+483511223344|556677885f5f5f5f5f5f	64	plan9	XORQ $0x44332211, AX
+483911|223344556677885f5f5f5f5f5f	64	gnu	cmp %rdx,(%rcx)
+483911|223344556677885f5f5f5f5f5f	64	intel	cmp qword ptr [rcx], rdx
+483911|223344556677885f5f5f5f5f5f	64	plan9	CMPQ DX, 0(CX)
+483b11|223344556677885f5f5f5f5f5f	64	gnu	cmp (%rcx),%rdx
+483b11|223344556677885f5f5f5f5f5f	64	intel	cmp rdx, qword ptr [rcx]
+483b11|223344556677885f5f5f5f5f5f	64	plan9	CMPQ 0(CX), DX
+483d11223344|556677885f5f5f5f5f5f	64	gnu	cmp $0x44332211,%rax
+483d11223344|556677885f5f5f5f5f5f	64	intel	cmp rax, 0x44332211
+483d11223344|556677885f5f5f5f5f5f	64	plan9	CMPQ $0x44332211, AX
+4850|11223344556677885f5f5f5f5f5f	64	gnu	push %rax
+4850|11223344556677885f5f5f5f5f5f	64	intel	push rax
+4850|11223344556677885f5f5f5f5f5f	64	plan9	PUSHQ AX
+4858|11223344556677885f5f5f5f5f5f	64	gnu	pop %rax
+4858|11223344556677885f5f5f5f5f5f	64	intel	pop rax
+4858|11223344556677885f5f5f5f5f5f	64	plan9	POPQ AX
+486311|223344556677885f5f5f5f5f5f	64	gnu	movsxd (%rcx),%rdx
+486311|223344556677885f5f5f5f5f5f	64	intel	movsxd rdx, dword ptr [rcx]
+486311|223344556677885f5f5f5f5f5f	64	plan9	MOVSXD 0(CX), DX
+486811223344|556677885f5f5f5f5f5f	64	gnu	pushq $0x44332211
+486811223344|556677885f5f5f5f5f5f	64	intel	push 0x44332211
+486811223344|556677885f5f5f5f5f5f	64	plan9	PUSHQ $0x44332211
+48691122334455|6677885f5f5f5f5f5f	64	gnu	imul $0x55443322,(%rcx),%rdx
+48691122334455|6677885f5f5f5f5f5f	64	intel	imul rdx, qword ptr [rcx], 0x55443322
+48691122334455|6677885f5f5f5f5f5f	64	plan9	IMULQ $0x55443322, 0(CX), DX
+486b1122|3344556677885f5f5f5f5f5f	64	gnu	imul $0x22,(%rcx),%rdx
+486b1122|3344556677885f5f5f5f5f5f	64	intel	imul rdx, qword ptr [rcx], 0x22
+486b1122|3344556677885f5f5f5f5f5f	64	plan9	IMULQ $0x22, 0(CX), DX
+486d|11223344556677885f5f5f5f5f5f	64	gnu	insl (%dx),%es:(%rdi)
+486d|11223344556677885f5f5f5f5f5f	64	intel	insd
+486d|11223344556677885f5f5f5f5f5f	64	plan9	INSD DX, ES:0(DI)
+486f|11223344556677885f5f5f5f5f5f	64	gnu	outsl %ds:(%rsi),(%dx)
+486f|11223344556677885f5f5f5f5f5f	64	intel	outsd
+486f|11223344556677885f5f5f5f5f5f	64	plan9	OUTSD DS:0(SI), DX
+48810011223344|556677885f5f5f5f5f	64	gnu	addq $0x44332211,(%rax)
+48810011223344|556677885f5f5f5f5f	64	intel	add qword ptr [rax], 0x44332211
+48810011223344|556677885f5f5f5f5f	64	plan9	ADDQ $0x44332211, 0(AX)
+48810811223344|556677885f5f5f5f5f	64	gnu	orq $0x44332211,(%rax)
+48810811223344|556677885f5f5f5f5f	64	intel	or qword ptr [rax], 0x44332211
+48810811223344|556677885f5f5f5f5f	64	plan9	ORQ $0x44332211, 0(AX)
+48811122334455|6677885f5f5f5f5f5f	64	gnu	adcq $0x55443322,(%rcx)
+48811122334455|6677885f5f5f5f5f5f	64	intel	adc qword ptr [rcx], 0x55443322
+48811122334455|6677885f5f5f5f5f5f	64	plan9	ADCQ $0x55443322, 0(CX)
+48811811223344|556677885f5f5f5f5f	64	gnu	sbbq $0x44332211,(%rax)
+48811811223344|556677885f5f5f5f5f	64	intel	sbb qword ptr [rax], 0x44332211
+48811811223344|556677885f5f5f5f5f	64	plan9	SBBQ $0x44332211, 0(AX)
+48812011223344|556677885f5f5f5f5f	64	gnu	andq $0x44332211,(%rax)
+48812011223344|556677885f5f5f5f5f	64	intel	and qword ptr [rax], 0x44332211
+48812011223344|556677885f5f5f5f5f	64	plan9	ANDQ $0x44332211, 0(AX)
+48812811223344|556677885f5f5f5f5f	64	gnu	subq $0x44332211,(%rax)
+48812811223344|556677885f5f5f5f5f	64	intel	sub qword ptr [rax], 0x44332211
+48812811223344|556677885f5f5f5f5f	64	plan9	SUBQ $0x44332211, 0(AX)
+48813011223344|556677885f5f5f5f5f	64	gnu	xorq $0x44332211,(%rax)
+48813011223344|556677885f5f5f5f5f	64	intel	xor qword ptr [rax], 0x44332211
+48813011223344|556677885f5f5f5f5f	64	plan9	XORQ $0x44332211, 0(AX)
+48813811223344|556677885f5f5f5f5f	64	gnu	cmpq $0x44332211,(%rax)
+48813811223344|556677885f5f5f5f5f	64	intel	cmp qword ptr [rax], 0x44332211
+48813811223344|556677885f5f5f5f5f	64	plan9	CMPQ $0x44332211, 0(AX)
+48830011|223344556677885f5f5f5f5f	64	gnu	addq $0x11,(%rax)
+48830011|223344556677885f5f5f5f5f	64	intel	add qword ptr [rax], 0x11
+48830011|223344556677885f5f5f5f5f	64	plan9	ADDQ $0x11, 0(AX)
+48830811|223344556677885f5f5f5f5f	64	gnu	orq $0x11,(%rax)
+48830811|223344556677885f5f5f5f5f	64	intel	or qword ptr [rax], 0x11
+48830811|223344556677885f5f5f5f5f	64	plan9	ORQ $0x11, 0(AX)
+48831122|3344556677885f5f5f5f5f5f	64	gnu	adcq $0x22,(%rcx)
+48831122|3344556677885f5f5f5f5f5f	64	intel	adc qword ptr [rcx], 0x22
+48831122|3344556677885f5f5f5f5f5f	64	plan9	ADCQ $0x22, 0(CX)
+48831811|223344556677885f5f5f5f5f	64	gnu	sbbq $0x11,(%rax)
+48831811|223344556677885f5f5f5f5f	64	intel	sbb qword ptr [rax], 0x11
+48831811|223344556677885f5f5f5f5f	64	plan9	SBBQ $0x11, 0(AX)
+48832011|223344556677885f5f5f5f5f	64	gnu	andq $0x11,(%rax)
+48832011|223344556677885f5f5f5f5f	64	intel	and qword ptr [rax], 0x11
+48832011|223344556677885f5f5f5f5f	64	plan9	ANDQ $0x11, 0(AX)
+48832811|223344556677885f5f5f5f5f	64	gnu	subq $0x11,(%rax)
+48832811|223344556677885f5f5f5f5f	64	intel	sub qword ptr [rax], 0x11
+48832811|223344556677885f5f5f5f5f	64	plan9	SUBQ $0x11, 0(AX)
+48833011|223344556677885f5f5f5f5f	64	gnu	xorq $0x11,(%rax)
+48833011|223344556677885f5f5f5f5f	64	intel	xor qword ptr [rax], 0x11
+48833011|223344556677885f5f5f5f5f	64	plan9	XORQ $0x11, 0(AX)
+48833811|223344556677885f5f5f5f5f	64	gnu	cmpq $0x11,(%rax)
+48833811|223344556677885f5f5f5f5f	64	intel	cmp qword ptr [rax], 0x11
+48833811|223344556677885f5f5f5f5f	64	plan9	CMPQ $0x11, 0(AX)
+488511|223344556677885f5f5f5f5f5f	64	gnu	test %rdx,(%rcx)
+488511|223344556677885f5f5f5f5f5f	64	intel	test qword ptr [rcx], rdx
+488511|223344556677885f5f5f5f5f5f	64	plan9	TESTQ DX, 0(CX)
+488711|223344556677885f5f5f5f5f5f	64	gnu	xchg %rdx,(%rcx)
+488711|223344556677885f5f5f5f5f5f	64	intel	xchg qword ptr [rcx], rdx
+488711|223344556677885f5f5f5f5f5f	64	plan9	XCHGQ DX, 0(CX)
+488911|223344556677885f5f5f5f5f5f	64	gnu	mov %rdx,(%rcx)
+488911|223344556677885f5f5f5f5f5f	64	intel	mov qword ptr [rcx], rdx
+488911|223344556677885f5f5f5f5f5f	64	plan9	MOVQ DX, 0(CX)
+488b11|223344556677885f5f5f5f5f5f	64	gnu	mov (%rcx),%rdx
+488b11|223344556677885f5f5f5f5f5f	64	intel	mov rdx, qword ptr [rcx]
+488b11|223344556677885f5f5f5f5f5f	64	plan9	MOVQ 0(CX), DX
+488c11|223344556677885f5f5f5f5f5f	64	gnu	mov %ss,(%rcx)
+488c11|223344556677885f5f5f5f5f5f	64	intel	mov word ptr [rcx], ss
+488c11|223344556677885f5f5f5f5f5f	64	plan9	MOVQ SS, 0(CX)
+488d11|223344556677885f5f5f5f5f5f	64	gnu	lea (%rcx),%rdx
+488d11|223344556677885f5f5f5f5f5f	64	intel	lea rdx, ptr [rcx]
+488d11|223344556677885f5f5f5f5f5f	64	plan9	LEAQ 0(CX), DX
+488e11|223344556677885f5f5f5f5f5f	64	gnu	mov (%rcx),%ss
+488e11|223344556677885f5f5f5f5f5f	64	intel	mov ss, word ptr [rcx]
+488e11|223344556677885f5f5f5f5f5f	64	plan9	MOVQ 0(CX), SS
+488f00|11223344556677885f5f5f5f5f	64	gnu	popq (%rax)
+488f00|11223344556677885f5f5f5f5f	64	intel	pop qword ptr [rax]
+488f00|11223344556677885f5f5f5f5f	64	plan9	POPQ 0(AX)
+4891|11223344556677885f5f5f5f5f5f	64	gnu	xchg %rax,%rcx
+4891|11223344556677885f5f5f5f5f5f	64	intel	xchg rcx, rax
+4891|11223344556677885f5f5f5f5f5f	64	plan9	XCHGQ AX, CX
+4898|11223344556677885f5f5f5f5f5f	64	gnu	cdqe
+4898|11223344556677885f5f5f5f5f5f	64	intel	cdqe
+4898|11223344556677885f5f5f5f5f5f	64	plan9	CDQE
+4899|11223344556677885f5f5f5f5f5f	64	gnu	cqto
+4899|11223344556677885f5f5f5f5f5f	64	intel	cqo
+4899|11223344556677885f5f5f5f5f5f	64	plan9	CQO
+489c|11223344556677885f5f5f5f5f5f	64	gnu	pushfq
+489c|11223344556677885f5f5f5f5f5f	64	intel	pushfq
+489c|11223344556677885f5f5f5f5f5f	64	plan9	PUSHFQ
+489d|11223344556677885f5f5f5f5f5f	64	gnu	popfq
+489d|11223344556677885f5f5f5f5f5f	64	intel	popfq
+489d|11223344556677885f5f5f5f5f5f	64	plan9	POPFQ
+48a01122334455667788|5f5f5f5f5f5f	64	gnu	mov -0x778899aabbccddef,%al
+48a01122334455667788|5f5f5f5f5f5f	64	intel	mov al, byte ptr [0x8877665544332211]
+48a01122334455667788|5f5f5f5f5f5f	64	plan9	MOVQ -0x778899aabbccddef, AL
+48a11122334455667788|5f5f5f5f5f5f	64	gnu	mov -0x778899aabbccddef,%rax
+48a11122334455667788|5f5f5f5f5f5f	64	intel	mov rax, qword ptr [0x8877665544332211]
+48a11122334455667788|5f5f5f5f5f5f	64	plan9	MOVQ -0x778899aabbccddef, AX
+48a21122334455667788|5f5f5f5f5f5f	64	gnu	mov %al,-0x778899aabbccddef
+48a21122334455667788|5f5f5f5f5f5f	64	intel	mov byte ptr [0x8877665544332211], al
+48a21122334455667788|5f5f5f5f5f5f	64	plan9	MOVQ AL, -0x778899aabbccddef
+48a31122334455667788|5f5f5f5f5f5f	64	gnu	mov %rax,-0x778899aabbccddef
+48a31122334455667788|5f5f5f5f5f5f	64	intel	mov qword ptr [0x8877665544332211], rax
+48a31122334455667788|5f5f5f5f5f5f	64	plan9	MOVQ AX, -0x778899aabbccddef
+48a5|11223344556677885f5f5f5f5f5f	64	gnu	movsq %ds:(%rsi),%es:(%rdi)
+48a5|11223344556677885f5f5f5f5f5f	64	intel	movsq qword ptr [rdi], qword ptr [rsi]
+48a5|11223344556677885f5f5f5f5f5f	64	plan9	MOVSQ DS:0(SI), ES:0(DI)
+48a7|11223344556677885f5f5f5f5f5f	64	gnu	cmpsq %es:(%rdi),%ds:(%rsi)
+48a7|11223344556677885f5f5f5f5f5f	64	intel	cmpsq qword ptr [rsi], qword ptr [rdi]
+48a7|11223344556677885f5f5f5f5f5f	64	plan9	CMPSQ ES:0(DI), DS:0(SI)
+48a911223344|556677885f5f5f5f5f5f	64	gnu	test $0x44332211,%rax
+48a911223344|556677885f5f5f5f5f5f	64	intel	test rax, 0x44332211
+48a911223344|556677885f5f5f5f5f5f	64	plan9	TESTQ $0x44332211, AX
+48ab|11223344556677885f5f5f5f5f5f	64	gnu	stos %rax,%es:(%rdi)
+48ab|11223344556677885f5f5f5f5f5f	64	intel	stosq qword ptr [rdi]
+48ab|11223344556677885f5f5f5f5f5f	64	plan9	STOSQ AX, ES:0(DI)
+48ad|11223344556677885f5f5f5f5f5f	64	gnu	lods %ds:(%rsi),%rax
+48ad|11223344556677885f5f5f5f5f5f	64	intel	lodsq qword ptr [rsi]
+48ad|11223344556677885f5f5f5f5f5f	64	plan9	LODSQ DS:0(SI), AX
+48af|11223344556677885f5f5f5f5f5f	64	gnu	scas %es:(%rdi),%rax
+48af|11223344556677885f5f5f5f5f5f	64	intel	scasq qword ptr [rdi]
+48af|11223344556677885f5f5f5f5f5f	64	plan9	SCASQ ES:0(DI), AX
+48b81122334455667788|5f5f5f5f5f5f	64	gnu	mov $-0x778899aabbccddef,%rax
+48b81122334455667788|5f5f5f5f5f5f	64	intel	mov rax, 0x8877665544332211
+48b81122334455667788|5f5f5f5f5f5f	64	plan9	MOVQ $0x8877665544332211, AX
+48c10011|223344556677885f5f5f5f5f	64	gnu	rolq $0x11,(%rax)
+48c10011|223344556677885f5f5f5f5f	64	intel	rol qword ptr [rax], 0x11
+48c10011|223344556677885f5f5f5f5f	64	plan9	ROLQ $0x11, 0(AX)
+48c10811|223344556677885f5f5f5f5f	64	gnu	rorq $0x11,(%rax)
+48c10811|223344556677885f5f5f5f5f	64	intel	ror qword ptr [rax], 0x11
+48c10811|223344556677885f5f5f5f5f	64	plan9	RORQ $0x11, 0(AX)
+48c11122|3344556677885f5f5f5f5f5f	64	gnu	rclq $0x22,(%rcx)
+48c11122|3344556677885f5f5f5f5f5f	64	intel	rcl qword ptr [rcx], 0x22
+48c11122|3344556677885f5f5f5f5f5f	64	plan9	RCLQ $0x22, 0(CX)
+48c11811|223344556677885f5f5f5f5f	64	gnu	rcrq $0x11,(%rax)
+48c11811|223344556677885f5f5f5f5f	64	intel	rcr qword ptr [rax], 0x11
+48c11811|223344556677885f5f5f5f5f	64	plan9	RCRQ $0x11, 0(AX)
+48c12011|223344556677885f5f5f5f5f	64	gnu	shlq $0x11,(%rax)
+48c12011|223344556677885f5f5f5f5f	64	intel	shl qword ptr [rax], 0x11
+48c12011|223344556677885f5f5f5f5f	64	plan9	SHLQ $0x11, 0(AX)
+48c12811|223344556677885f5f5f5f5f	64	gnu	shrq $0x11,(%rax)
+48c12811|223344556677885f5f5f5f5f	64	intel	shr qword ptr [rax], 0x11
+48c12811|223344556677885f5f5f5f5f	64	plan9	SHRQ $0x11, 0(AX)
+48c13811|223344556677885f5f5f5f5f	64	gnu	sarq $0x11,(%rax)
+48c13811|223344556677885f5f5f5f5f	64	intel	sar qword ptr [rax], 0x11
+48c13811|223344556677885f5f5f5f5f	64	plan9	SARQ $0x11, 0(AX)
+48c70011223344|556677885f5f5f5f5f	64	gnu	movq $0x44332211,(%rax)
+48c70011223344|556677885f5f5f5f5f	64	intel	mov qword ptr [rax], 0x44332211
+48c70011223344|556677885f5f5f5f5f	64	plan9	MOVQ $0x44332211, 0(AX)
+48c7f811223344|556677885f5f5f5f5f	64	gnu	xbeginq .+0x44332211
+48c7f811223344|556677885f5f5f5f5f	64	intel	xbegin .+0x44332211
+48c7f811223344|556677885f5f5f5f5f	64	plan9	XBEGIN .+1144201745
+48c9|11223344556677885f5f5f5f5f5f	64	gnu	leaveq
+48c9|11223344556677885f5f5f5f5f5f	64	intel	leave
+48c9|11223344556677885f5f5f5f5f5f	64	plan9	LEAVE
+48cf|11223344556677885f5f5f5f5f5f	64	gnu	iretq
+48cf|11223344556677885f5f5f5f5f5f	64	intel	iretq
+48cf|11223344556677885f5f5f5f5f5f	64	plan9	IRETQ
+48d100|11223344556677885f5f5f5f5f	64	gnu	rolq (%rax)
+48d100|11223344556677885f5f5f5f5f	64	intel	rol qword ptr [rax], 0x1
+48d100|11223344556677885f5f5f5f5f	64	plan9	ROLQ $0x1, 0(AX)
+48d108|11223344556677885f5f5f5f5f	64	gnu	rorq (%rax)
+48d108|11223344556677885f5f5f5f5f	64	intel	ror qword ptr [rax], 0x1
+48d108|11223344556677885f5f5f5f5f	64	plan9	RORQ $0x1, 0(AX)
+48d111|223344556677885f5f5f5f5f5f	64	gnu	rclq (%rcx)
+48d111|223344556677885f5f5f5f5f5f	64	intel	rcl qword ptr [rcx], 0x1
+48d111|223344556677885f5f5f5f5f5f	64	plan9	RCLQ $0x1, 0(CX)
+48d118|11223344556677885f5f5f5f5f	64	gnu	rcrq (%rax)
+48d118|11223344556677885f5f5f5f5f	64	intel	rcr qword ptr [rax], 0x1
+48d118|11223344556677885f5f5f5f5f	64	plan9	RCRQ $0x1, 0(AX)
+48d120|11223344556677885f5f5f5f5f	64	gnu	shlq (%rax)
+48d120|11223344556677885f5f5f5f5f	64	intel	shl qword ptr [rax], 0x1
+48d120|11223344556677885f5f5f5f5f	64	plan9	SHLQ $0x1, 0(AX)
+48d128|11223344556677885f5f5f5f5f	64	gnu	shrq (%rax)
+48d128|11223344556677885f5f5f5f5f	64	intel	shr qword ptr [rax], 0x1
+48d128|11223344556677885f5f5f5f5f	64	plan9	SHRQ $0x1, 0(AX)
+48d138|11223344556677885f5f5f5f5f	64	gnu	sarq (%rax)
+48d138|11223344556677885f5f5f5f5f	64	intel	sar qword ptr [rax], 0x1
+48d138|11223344556677885f5f5f5f5f	64	plan9	SARQ $0x1, 0(AX)
+48d300|11223344556677885f5f5f5f5f	64	gnu	rolq %cl,(%rax)
+48d300|11223344556677885f5f5f5f5f	64	intel	rol qword ptr [rax], cl
+48d300|11223344556677885f5f5f5f5f	64	plan9	ROLQ CL, 0(AX)
+48d308|11223344556677885f5f5f5f5f	64	gnu	rorq %cl,(%rax)
+48d308|11223344556677885f5f5f5f5f	64	intel	ror qword ptr [rax], cl
+48d308|11223344556677885f5f5f5f5f	64	plan9	RORQ CL, 0(AX)
+48d311|223344556677885f5f5f5f5f5f	64	gnu	rclq %cl,(%rcx)
+48d311|223344556677885f5f5f5f5f5f	64	intel	rcl qword ptr [rcx], cl
+48d311|223344556677885f5f5f5f5f5f	64	plan9	RCLQ CL, 0(CX)
+48d318|11223344556677885f5f5f5f5f	64	gnu	rcrq %cl,(%rax)
+48d318|11223344556677885f5f5f5f5f	64	intel	rcr qword ptr [rax], cl
+48d318|11223344556677885f5f5f5f5f	64	plan9	RCRQ CL, 0(AX)
+48d320|11223344556677885f5f5f5f5f	64	gnu	shlq %cl,(%rax)
+48d320|11223344556677885f5f5f5f5f	64	intel	shl qword ptr [rax], cl
+48d320|11223344556677885f5f5f5f5f	64	plan9	SHLQ CL, 0(AX)
+48d328|11223344556677885f5f5f5f5f	64	gnu	shrq %cl,(%rax)
+48d328|11223344556677885f5f5f5f5f	64	intel	shr qword ptr [rax], cl
+48d328|11223344556677885f5f5f5f5f	64	plan9	SHRQ CL, 0(AX)
+48d338|11223344556677885f5f5f5f5f	64	gnu	sarq %cl,(%rax)
+48d338|11223344556677885f5f5f5f5f	64	intel	sar qword ptr [rax], cl
+48d338|11223344556677885f5f5f5f5f	64	plan9	SARQ CL, 0(AX)
+48d7|11223344556677885f5f5f5f5f5f	64	gnu	xlat %ds:(%rbx)
+48d7|11223344556677885f5f5f5f5f5f	64	intel	xlat
+48d7|11223344556677885f5f5f5f5f5f	64	plan9	XLATB DS:0(BX)
+48e511|223344556677885f5f5f5f5f5f	64	gnu	in $0x11,%eax
+48e511|223344556677885f5f5f5f5f5f	64	intel	in eax, 0x11
+48e511|223344556677885f5f5f5f5f5f	64	plan9	INQ $0x11, AX
+48e711|223344556677885f5f5f5f5f5f	64	gnu	out %eax,$0x11
+48e711|223344556677885f5f5f5f5f5f	64	intel	out 0x11, eax
+48e711|223344556677885f5f5f5f5f5f	64	plan9	OUTQ AX, $0x11
+48e811223344|556677885f5f5f5f5f5f	64	gnu	callq .+0x44332211
+48e811223344|556677885f5f5f5f5f5f	64	intel	call .+0x44332211
+48e811223344|556677885f5f5f5f5f5f	64	plan9	CALL .+1144201745
+48e911223344|556677885f5f5f5f5f5f	64	gnu	jmpq .+0x44332211
+48e911223344|556677885f5f5f5f5f5f	64	intel	jmp .+0x44332211
+48e911223344|556677885f5f5f5f5f5f	64	plan9	JMP .+1144201745
+48ed|11223344556677885f5f5f5f5f5f	64	gnu	in (%dx),%eax
+48ed|11223344556677885f5f5f5f5f5f	64	intel	in eax, dx
+48ed|11223344556677885f5f5f5f5f5f	64	plan9	INQ DX, AX
+48ef|11223344556677885f5f5f5f5f5f	64	gnu	out %eax,(%dx)
+48ef|11223344556677885f5f5f5f5f5f	64	intel	out dx, eax
+48ef|11223344556677885f5f5f5f5f5f	64	plan9	OUTQ AX, DX
+48f70011223344|556677885f5f5f5f5f	64	gnu	testq $0x44332211,(%rax)
+48f70011223344|556677885f5f5f5f5f	64	intel	test qword ptr [rax], 0x44332211
+48f70011223344|556677885f5f5f5f5f	64	plan9	TESTQ $0x44332211, 0(AX)
+48f711|223344556677885f5f5f5f5f5f	64	gnu	notq (%rcx)
+48f711|223344556677885f5f5f5f5f5f	64	intel	not qword ptr [rcx]
+48f711|223344556677885f5f5f5f5f5f	64	plan9	NOTQ 0(CX)
+48f718|11223344556677885f5f5f5f5f	64	gnu	negq (%rax)
+48f718|11223344556677885f5f5f5f5f	64	intel	neg qword ptr [rax]
+48f718|11223344556677885f5f5f5f5f	64	plan9	NEGQ 0(AX)
+48f720|11223344556677885f5f5f5f5f	64	gnu	mulq (%rax)
+48f720|11223344556677885f5f5f5f5f	64	intel	mul qword ptr [rax]
+48f720|11223344556677885f5f5f5f5f	64	plan9	MULQ 0(AX)
+48f728|11223344556677885f5f5f5f5f	64	gnu	imulq (%rax)
+48f728|11223344556677885f5f5f5f5f	64	intel	imul qword ptr [rax]
+48f728|11223344556677885f5f5f5f5f	64	plan9	IMULQ 0(AX)
+48f730|11223344556677885f5f5f5f5f	64	gnu	divq (%rax)
+48f730|11223344556677885f5f5f5f5f	64	intel	div qword ptr [rax]
+48f730|11223344556677885f5f5f5f5f	64	plan9	DIVQ 0(AX)
+48f738|11223344556677885f5f5f5f5f	64	gnu	idivq (%rax)
+48f738|11223344556677885f5f5f5f5f	64	intel	idiv qword ptr [rax]
+48f738|11223344556677885f5f5f5f5f	64	plan9	IDIVQ 0(AX)
+48ff00|11223344556677885f5f5f5f5f	64	gnu	incq (%rax)
+48ff00|11223344556677885f5f5f5f5f	64	intel	inc qword ptr [rax]
+48ff00|11223344556677885f5f5f5f5f	64	plan9	INCQ 0(AX)
+48ff08|11223344556677885f5f5f5f5f	64	gnu	decq (%rax)
+48ff08|11223344556677885f5f5f5f5f	64	intel	dec qword ptr [rax]
+48ff08|11223344556677885f5f5f5f5f	64	plan9	DECQ 0(AX)
+48ff18|11223344556677885f5f5f5f5f	64	gnu	lcallq *(%rax)
+48ff18|11223344556677885f5f5f5f5f	64	intel	call far ptr [rax]
+48ff18|11223344556677885f5f5f5f5f	64	plan9	LCALL 0(AX)
+48ff28|11223344556677885f5f5f5f5f	64	gnu	ljmpq *(%rax)
+48ff28|11223344556677885f5f5f5f5f	64	intel	jmp far ptr [rax]
+48ff28|11223344556677885f5f5f5f5f	64	plan9	LJMP 0(AX)
+48ff30|11223344556677885f5f5f5f5f	64	gnu	pushq (%rax)
+48ff30|11223344556677885f5f5f5f5f	64	intel	push qword ptr [rax]
+48ff30|11223344556677885f5f5f5f5f	64	plan9	PUSHQ 0(AX)
+48|010011223344556677885f5f5f5f5f	32	intel	dec eax
+48|010011223344556677885f5f5f5f5f	32	plan9	DECL AX
+50|11223344556677885f5f5f5f5f5f5f	32	intel	push eax
+50|11223344556677885f5f5f5f5f5f5f	32	plan9	PUSHL AX
+50|11223344556677885f5f5f5f5f5f5f	64	gnu	push %rax
+50|11223344556677885f5f5f5f5f5f5f	64	intel	push rax
+50|11223344556677885f5f5f5f5f5f5f	64	plan9	PUSHL AX
+58|11223344556677885f5f5f5f5f5f5f	32	intel	pop eax
+58|11223344556677885f5f5f5f5f5f5f	32	plan9	POPL AX
+58|11223344556677885f5f5f5f5f5f5f	64	gnu	pop %rax
+58|11223344556677885f5f5f5f5f5f5f	64	intel	pop rax
+58|11223344556677885f5f5f5f5f5f5f	64	plan9	POPL AX
+60|11223344556677885f5f5f5f5f5f5f	32	intel	pushad
+60|11223344556677885f5f5f5f5f5f5f	32	plan9	PUSHAD
+60|11223344556677885f5f5f5f5f5f5f	64	gnu	error: unrecognized instruction
+60|11223344556677885f5f5f5f5f5f5f	64	intel	error: unrecognized instruction
+60|11223344556677885f5f5f5f5f5f5f	64	plan9	error: unrecognized instruction
+61|11223344556677885f5f5f5f5f5f5f	32	intel	popad
+61|11223344556677885f5f5f5f5f5f5f	32	plan9	POPAD
+61|11223344556677885f5f5f5f5f5f5f	64	gnu	error: unrecognized instruction
+61|11223344556677885f5f5f5f5f5f5f	64	intel	error: unrecognized instruction
+61|11223344556677885f5f5f5f5f5f5f	64	plan9	error: unrecognized instruction
+6211|223344556677885f5f5f5f5f5f5f	32	intel	bound edx, qword ptr [ecx]
+6211|223344556677885f5f5f5f5f5f5f	32	plan9	BOUND 0(CX), DX
+62|11223344556677885f5f5f5f5f5f5f	64	gnu	error: unrecognized instruction
+62|11223344556677885f5f5f5f5f5f5f	64	intel	error: unrecognized instruction
+62|11223344556677885f5f5f5f5f5f5f	64	plan9	error: unrecognized instruction
+6311|223344556677885f5f5f5f5f5f5f	32	intel	arpl word ptr [ecx], dx
+6311|223344556677885f5f5f5f5f5f5f	32	plan9	ARPL DX, 0(CX)
+6311|223344556677885f5f5f5f5f5f5f	64	gnu	movsxd (%rcx),%edx
+6311|223344556677885f5f5f5f5f5f5f	64	intel	movsxd edx, dword ptr [rcx]
+6311|223344556677885f5f5f5f5f5f5f	64	plan9	MOVSXD 0(CX), DX
+660111|223344556677885f5f5f5f5f5f	32	intel	add word ptr [ecx], dx
+660111|223344556677885f5f5f5f5f5f	32	plan9	ADDW DX, 0(CX)
+660111|223344556677885f5f5f5f5f5f	64	gnu	add %dx,(%rcx)
+660111|223344556677885f5f5f5f5f5f	64	intel	add word ptr [rcx], dx
+660111|223344556677885f5f5f5f5f5f	64	plan9	ADDW DX, 0(CX)
+660311|223344556677885f5f5f5f5f5f	32	intel	add dx, word ptr [ecx]
+660311|223344556677885f5f5f5f5f5f	32	plan9	ADDW 0(CX), DX
+660311|223344556677885f5f5f5f5f5f	64	gnu	add (%rcx),%dx
+660311|223344556677885f5f5f5f5f5f	64	intel	add dx, word ptr [rcx]
+660311|223344556677885f5f5f5f5f5f	64	plan9	ADDW 0(CX), DX
+66051122|3344556677885f5f5f5f5f5f	32	intel	add ax, 0x2211
+66051122|3344556677885f5f5f5f5f5f	32	plan9	ADDW $0x2211, AX
+66051122|3344556677885f5f5f5f5f5f	64	gnu	add $0x2211,%ax
+66051122|3344556677885f5f5f5f5f5f	64	intel	add ax, 0x2211
+66051122|3344556677885f5f5f5f5f5f	64	plan9	ADDW $0x2211, AX
+660911|223344556677885f5f5f5f5f5f	32	intel	or word ptr [ecx], dx
+660911|223344556677885f5f5f5f5f5f	32	plan9	ORW DX, 0(CX)
+660911|223344556677885f5f5f5f5f5f	64	gnu	or %dx,(%rcx)
+660911|223344556677885f5f5f5f5f5f	64	intel	or word ptr [rcx], dx
+660911|223344556677885f5f5f5f5f5f	64	plan9	ORW DX, 0(CX)
+660b11|223344556677885f5f5f5f5f5f	32	intel	or dx, word ptr [ecx]
+660b11|223344556677885f5f5f5f5f5f	32	plan9	ORW 0(CX), DX
+660b11|223344556677885f5f5f5f5f5f	64	gnu	or (%rcx),%dx
+660b11|223344556677885f5f5f5f5f5f	64	intel	or dx, word ptr [rcx]
+660b11|223344556677885f5f5f5f5f5f	64	plan9	ORW 0(CX), DX
+660d1122|3344556677885f5f5f5f5f5f	32	intel	or ax, 0x2211
+660d1122|3344556677885f5f5f5f5f5f	32	plan9	ORW $0x2211, AX
+660d1122|3344556677885f5f5f5f5f5f	64	gnu	or $0x2211,%ax
+660d1122|3344556677885f5f5f5f5f5f	64	intel	or ax, 0x2211
+660d1122|3344556677885f5f5f5f5f5f	64	plan9	ORW $0x2211, AX
+660f0000|11223344556677885f5f5f5f	32	intel	sldt word ptr [eax]
+660f0000|11223344556677885f5f5f5f	32	plan9	SLDT 0(AX)
+660f0000|11223344556677885f5f5f5f	64	gnu	data16 sldt (%rax)
+660f0000|11223344556677885f5f5f5f	64	intel	sldt word ptr [rax]
+660f0000|11223344556677885f5f5f5f	64	plan9	SLDT 0(AX)
+660f0008|11223344556677885f5f5f5f	32	intel	str word ptr [eax]
+660f0008|11223344556677885f5f5f5f	32	plan9	STR 0(AX)
+660f0008|11223344556677885f5f5f5f	64	gnu	data16 str (%rax)
+660f0008|11223344556677885f5f5f5f	64	intel	str word ptr [rax]
+660f0008|11223344556677885f5f5f5f	64	plan9	STR 0(AX)
+660f01a611223344|556677885f5f5f5f	32	intel	smsw word ptr [esi+0x44332211]
+660f01a611223344|556677885f5f5f5f	32	plan9	SMSW 0x44332211(SI)
+660f01a611223344|556677885f5f5f5f	64	gnu	data16 smsw 0x44332211(%rsi)
+660f01a611223344|556677885f5f5f5f	64	intel	smsw word ptr [rsi+0x44332211]
+660f01a611223344|556677885f5f5f5f	64	plan9	SMSW 0x44332211(SI)
+660f0211|223344556677885f5f5f5f5f	32	intel	lar dx, word ptr [ecx]
+660f0211|223344556677885f5f5f5f5f	32	plan9	LAR 0(CX), DX
+660f0211|223344556677885f5f5f5f5f	64	gnu	lar (%rcx),%dx
+660f0211|223344556677885f5f5f5f5f	64	intel	lar dx, word ptr [rcx]
+660f0211|223344556677885f5f5f5f5f	64	plan9	LAR 0(CX), DX
+660f0311|223344556677885f5f5f5f5f	32	intel	lsl dx, word ptr [ecx]
+660f0311|223344556677885f5f5f5f5f	32	plan9	LSL 0(CX), DX
+660f0311|223344556677885f5f5f5f5f	64	gnu	lsl (%rcx),%dx
+660f0311|223344556677885f5f5f5f5f	64	intel	lsl dx, word ptr [rcx]
+660f0311|223344556677885f5f5f5f5f	64	plan9	LSL 0(CX), DX
+660f1011|223344556677885f5f5f5f5f	32	intel	movupd xmm2, xmmword ptr [ecx]
+660f1011|223344556677885f5f5f5f5f	32	plan9	MOVUPD 0(CX), X2
+660f1011|223344556677885f5f5f5f5f	64	gnu	movupd (%rcx),%xmm2
+660f1011|223344556677885f5f5f5f5f	64	intel	movupd xmm2, xmmword ptr [rcx]
+660f1011|223344556677885f5f5f5f5f	64	plan9	MOVUPD 0(CX), X2
+660f1122|3344556677885f5f5f5f5f5f	32	intel	movupd xmmword ptr [edx], xmm4
+660f1122|3344556677885f5f5f5f5f5f	32	plan9	MOVUPD X4, 0(DX)
+660f1122|3344556677885f5f5f5f5f5f	64	gnu	movupd %xmm4,(%rdx)
+660f1122|3344556677885f5f5f5f5f5f	64	intel	movupd xmmword ptr [rdx], xmm4
+660f1122|3344556677885f5f5f5f5f5f	64	plan9	MOVUPD X4, 0(DX)
+660f1211|223344556677885f5f5f5f5f	32	intel	movlpd xmm2, qword ptr [ecx]
+660f1211|223344556677885f5f5f5f5f	32	plan9	MOVLPD 0(CX), X2
+660f1211|223344556677885f5f5f5f5f	64	gnu	movlpd (%rcx),%xmm2
+660f1211|223344556677885f5f5f5f5f	64	intel	movlpd xmm2, qword ptr [rcx]
+660f1211|223344556677885f5f5f5f5f	64	plan9	MOVLPD 0(CX), X2
+660f1311|223344556677885f5f5f5f5f	32	intel	movlpd qword ptr [ecx], xmm2
+660f1311|223344556677885f5f5f5f5f	32	plan9	MOVLPD X2, 0(CX)
+660f1311|223344556677885f5f5f5f5f	64	gnu	movlpd %xmm2,(%rcx)
+660f1311|223344556677885f5f5f5f5f	64	intel	movlpd qword ptr [rcx], xmm2
+660f1311|223344556677885f5f5f5f5f	64	plan9	MOVLPD X2, 0(CX)
+660f1411|223344556677885f5f5f5f5f	32	intel	unpcklpd xmm2, xmmword ptr [ecx]
+660f1411|223344556677885f5f5f5f5f	32	plan9	UNPCKLPD 0(CX), X2
+660f1411|223344556677885f5f5f5f5f	64	gnu	unpcklpd (%rcx),%xmm2
+660f1411|223344556677885f5f5f5f5f	64	intel	unpcklpd xmm2, xmmword ptr [rcx]
+660f1411|223344556677885f5f5f5f5f	64	plan9	UNPCKLPD 0(CX), X2
+660f1511|223344556677885f5f5f5f5f	32	intel	unpckhpd xmm2, xmmword ptr [ecx]
+660f1511|223344556677885f5f5f5f5f	32	plan9	UNPCKHPD 0(CX), X2
+660f1511|223344556677885f5f5f5f5f	64	gnu	unpckhpd (%rcx),%xmm2
+660f1511|223344556677885f5f5f5f5f	64	intel	unpckhpd xmm2, xmmword ptr [rcx]
+660f1511|223344556677885f5f5f5f5f	64	plan9	UNPCKHPD 0(CX), X2
+660f1611|223344556677885f5f5f5f5f	32	intel	movhpd xmm2, qword ptr [ecx]
+660f1611|223344556677885f5f5f5f5f	32	plan9	MOVHPD 0(CX), X2
+660f1611|223344556677885f5f5f5f5f	64	gnu	movhpd (%rcx),%xmm2
+660f1611|223344556677885f5f5f5f5f	64	intel	movhpd xmm2, qword ptr [rcx]
+660f1611|223344556677885f5f5f5f5f	64	plan9	MOVHPD 0(CX), X2
+660f1711|223344556677885f5f5f5f5f	32	intel	movhpd qword ptr [ecx], xmm2
+660f1711|223344556677885f5f5f5f5f	32	plan9	MOVHPD X2, 0(CX)
+660f1711|223344556677885f5f5f5f5f	64	gnu	movhpd %xmm2,(%rcx)
+660f1711|223344556677885f5f5f5f5f	64	intel	movhpd qword ptr [rcx], xmm2
+660f1711|223344556677885f5f5f5f5f	64	plan9	MOVHPD X2, 0(CX)
+660f1f00|11223344556677885f5f5f5f	32	intel	nop word ptr [eax], ax
+660f1f00|11223344556677885f5f5f5f	32	plan9	NOPW 0(AX)
+660f1f00|11223344556677885f5f5f5f	64	gnu	nopw (%rax)
+660f1f00|11223344556677885f5f5f5f	64	intel	nop word ptr [rax], ax
+660f1f00|11223344556677885f5f5f5f	64	plan9	NOPW 0(AX)
+660f2811|223344556677885f5f5f5f5f	32	intel	movapd xmm2, xmmword ptr [ecx]
+660f2811|223344556677885f5f5f5f5f	32	plan9	MOVAPD 0(CX), X2
+660f2811|223344556677885f5f5f5f5f	64	gnu	movapd (%rcx),%xmm2
+660f2811|223344556677885f5f5f5f5f	64	intel	movapd xmm2, xmmword ptr [rcx]
+660f2811|223344556677885f5f5f5f5f	64	plan9	MOVAPD 0(CX), X2
+660f2911|223344556677885f5f5f5f5f	32	intel	movapd xmmword ptr [ecx], xmm2
+660f2911|223344556677885f5f5f5f5f	32	plan9	MOVAPD X2, 0(CX)
+660f2911|223344556677885f5f5f5f5f	64	gnu	movapd %xmm2,(%rcx)
+660f2911|223344556677885f5f5f5f5f	64	intel	movapd xmmword ptr [rcx], xmm2
+660f2911|223344556677885f5f5f5f5f	64	plan9	MOVAPD X2, 0(CX)
+660f2a11|223344556677885f5f5f5f5f	32	intel	cvtpi2pd xmm2, qword ptr [ecx]
+660f2a11|223344556677885f5f5f5f5f	32	plan9	CVTPI2PD 0(CX), X2
+660f2a11|223344556677885f5f5f5f5f	64	gnu	cvtpi2pd (%rcx),%xmm2
+660f2a11|223344556677885f5f5f5f5f	64	intel	cvtpi2pd xmm2, qword ptr [rcx]
+660f2a11|223344556677885f5f5f5f5f	64	plan9	CVTPI2PD 0(CX), X2
+660f2b11|223344556677885f5f5f5f5f	32	intel	movntpd xmmword ptr [ecx], xmm2
+660f2b11|223344556677885f5f5f5f5f	32	plan9	MOVNTPD X2, 0(CX)
+660f2b11|223344556677885f5f5f5f5f	64	gnu	movntpd %xmm2,(%rcx)
+660f2b11|223344556677885f5f5f5f5f	64	intel	movntpd xmmword ptr [rcx], xmm2
+660f2b11|223344556677885f5f5f5f5f	64	plan9	MOVNTPD X2, 0(CX)
+660f2c11|223344556677885f5f5f5f5f	32	intel	cvttpd2pi mmx2, xmmword ptr [ecx]
+660f2c11|223344556677885f5f5f5f5f	32	plan9	CVTTPD2PI 0(CX), M2
+660f2c11|223344556677885f5f5f5f5f	64	gnu	cvttpd2pi (%rcx),%mm2
+660f2c11|223344556677885f5f5f5f5f	64	intel	cvttpd2pi mmx2, xmmword ptr [rcx]
+660f2c11|223344556677885f5f5f5f5f	64	plan9	CVTTPD2PI 0(CX), M2
+660f2d11|223344556677885f5f5f5f5f	32	intel	cvtpd2pi mmx2, xmmword ptr [ecx]
+660f2d11|223344556677885f5f5f5f5f	32	plan9	CVTPD2PI 0(CX), M2
+660f2d11|223344556677885f5f5f5f5f	64	gnu	cvtpd2pi (%rcx),%mm2
+660f2d11|223344556677885f5f5f5f5f	64	intel	cvtpd2pi mmx2, xmmword ptr [rcx]
+660f2d11|223344556677885f5f5f5f5f	64	plan9	CVTPD2PI 0(CX), M2
+660f2e11|223344556677885f5f5f5f5f	32	intel	ucomisd xmm2, qword ptr [ecx]
+660f2e11|223344556677885f5f5f5f5f	32	plan9	UCOMISD 0(CX), X2
+660f2e11|223344556677885f5f5f5f5f	64	gnu	ucomisd (%rcx),%xmm2
+660f2e11|223344556677885f5f5f5f5f	64	intel	ucomisd xmm2, qword ptr [rcx]
+660f2e11|223344556677885f5f5f5f5f	64	plan9	UCOMISD 0(CX), X2
+660f2f11|223344556677885f5f5f5f5f	32	intel	comisd xmm2, qword ptr [ecx]
+660f2f11|223344556677885f5f5f5f5f	32	plan9	COMISD 0(CX), X2
+660f2f11|223344556677885f5f5f5f5f	64	gnu	comisd (%rcx),%xmm2
+660f2f11|223344556677885f5f5f5f5f	64	intel	comisd xmm2, qword ptr [rcx]
+660f2f11|223344556677885f5f5f5f5f	64	plan9	COMISD 0(CX), X2
+660f380011|223344556677885f5f5f5f	32	intel	pshufb xmm2, xmmword ptr [ecx]
+660f380011|223344556677885f5f5f5f	32	plan9	PSHUFB 0(CX), X2
+660f380011|223344556677885f5f5f5f	64	gnu	pshufb (%rcx),%xmm2
+660f380011|223344556677885f5f5f5f	64	intel	pshufb xmm2, xmmword ptr [rcx]
+660f380011|223344556677885f5f5f5f	64	plan9	PSHUFB 0(CX), X2
+660f380111|223344556677885f5f5f5f	32	intel	phaddw xmm2, xmmword ptr [ecx]
+660f380111|223344556677885f5f5f5f	32	plan9	PHADDW 0(CX), X2
+660f380111|223344556677885f5f5f5f	64	gnu	phaddw (%rcx),%xmm2
+660f380111|223344556677885f5f5f5f	64	intel	phaddw xmm2, xmmword ptr [rcx]
+660f380111|223344556677885f5f5f5f	64	plan9	PHADDW 0(CX), X2
+660f380211|223344556677885f5f5f5f	32	intel	phaddd xmm2, xmmword ptr [ecx]
+660f380211|223344556677885f5f5f5f	32	plan9	PHADDD 0(CX), X2
+660f380211|223344556677885f5f5f5f	64	gnu	phaddd (%rcx),%xmm2
+660f380211|223344556677885f5f5f5f	64	intel	phaddd xmm2, xmmword ptr [rcx]
+660f380211|223344556677885f5f5f5f	64	plan9	PHADDD 0(CX), X2
+660f380311|223344556677885f5f5f5f	32	intel	phaddsw xmm2, xmmword ptr [ecx]
+660f380311|223344556677885f5f5f5f	32	plan9	PHADDSW 0(CX), X2
+660f380311|223344556677885f5f5f5f	64	gnu	phaddsw (%rcx),%xmm2
+660f380311|223344556677885f5f5f5f	64	intel	phaddsw xmm2, xmmword ptr [rcx]
+660f380311|223344556677885f5f5f5f	64	plan9	PHADDSW 0(CX), X2
+660f380411|223344556677885f5f5f5f	32	intel	pmaddubsw xmm2, xmmword ptr [ecx]
+660f380411|223344556677885f5f5f5f	32	plan9	PMADDUBSW 0(CX), X2
+660f380411|223344556677885f5f5f5f	64	gnu	pmaddubsw (%rcx),%xmm2
+660f380411|223344556677885f5f5f5f	64	intel	pmaddubsw xmm2, xmmword ptr [rcx]
+660f380411|223344556677885f5f5f5f	64	plan9	PMADDUBSW 0(CX), X2
+660f380511|223344556677885f5f5f5f	32	intel	phsubw xmm2, xmmword ptr [ecx]
+660f380511|223344556677885f5f5f5f	32	plan9	PHSUBW 0(CX), X2
+660f380511|223344556677885f5f5f5f	64	gnu	phsubw (%rcx),%xmm2
+660f380511|223344556677885f5f5f5f	64	intel	phsubw xmm2, xmmword ptr [rcx]
+660f380511|223344556677885f5f5f5f	64	plan9	PHSUBW 0(CX), X2
+660f380611|223344556677885f5f5f5f	32	intel	phsubd xmm2, xmmword ptr [ecx]
+660f380611|223344556677885f5f5f5f	32	plan9	PHSUBD 0(CX), X2
+660f380611|223344556677885f5f5f5f	64	gnu	phsubd (%rcx),%xmm2
+660f380611|223344556677885f5f5f5f	64	intel	phsubd xmm2, xmmword ptr [rcx]
+660f380611|223344556677885f5f5f5f	64	plan9	PHSUBD 0(CX), X2
+660f380711|223344556677885f5f5f5f	32	intel	phsubsw xmm2, xmmword ptr [ecx]
+660f380711|223344556677885f5f5f5f	32	plan9	PHSUBSW 0(CX), X2
+660f380711|223344556677885f5f5f5f	64	gnu	phsubsw (%rcx),%xmm2
+660f380711|223344556677885f5f5f5f	64	intel	phsubsw xmm2, xmmword ptr [rcx]
+660f380711|223344556677885f5f5f5f	64	plan9	PHSUBSW 0(CX), X2
+660f380811|223344556677885f5f5f5f	32	intel	psignb xmm2, xmmword ptr [ecx]
+660f380811|223344556677885f5f5f5f	32	plan9	PSIGNB 0(CX), X2
+660f380811|223344556677885f5f5f5f	64	gnu	psignb (%rcx),%xmm2
+660f380811|223344556677885f5f5f5f	64	intel	psignb xmm2, xmmword ptr [rcx]
+660f380811|223344556677885f5f5f5f	64	plan9	PSIGNB 0(CX), X2
+660f380911|223344556677885f5f5f5f	32	intel	psignw xmm2, xmmword ptr [ecx]
+660f380911|223344556677885f5f5f5f	32	plan9	PSIGNW 0(CX), X2
+660f380911|223344556677885f5f5f5f	64	gnu	psignw (%rcx),%xmm2
+660f380911|223344556677885f5f5f5f	64	intel	psignw xmm2, xmmword ptr [rcx]
+660f380911|223344556677885f5f5f5f	64	plan9	PSIGNW 0(CX), X2
+660f380a11|223344556677885f5f5f5f	32	intel	psignd xmm2, xmmword ptr [ecx]
+660f380a11|223344556677885f5f5f5f	32	plan9	PSIGND 0(CX), X2
+660f380a11|223344556677885f5f5f5f	64	gnu	psignd (%rcx),%xmm2
+660f380a11|223344556677885f5f5f5f	64	intel	psignd xmm2, xmmword ptr [rcx]
+660f380a11|223344556677885f5f5f5f	64	plan9	PSIGND 0(CX), X2
+660f380b11|223344556677885f5f5f5f	32	intel	pmulhrsw xmm2, xmmword ptr [ecx]
+660f380b11|223344556677885f5f5f5f	32	plan9	PMULHRSW 0(CX), X2
+660f380b11|223344556677885f5f5f5f	64	gnu	pmulhrsw (%rcx),%xmm2
+660f380b11|223344556677885f5f5f5f	64	intel	pmulhrsw xmm2, xmmword ptr [rcx]
+660f380b11|223344556677885f5f5f5f	64	plan9	PMULHRSW 0(CX), X2
+660f381011|223344556677885f5f5f5f	32	intel	pblendvb xmm2, xmmword ptr [ecx]
+660f381011|223344556677885f5f5f5f	32	plan9	PBLENDVB X0, 0(CX), X2
+660f381011|223344556677885f5f5f5f	64	gnu	pblendvb %xmm0,(%rcx),%xmm2
+660f381011|223344556677885f5f5f5f	64	intel	pblendvb xmm2, xmmword ptr [rcx]
+660f381011|223344556677885f5f5f5f	64	plan9	PBLENDVB X0, 0(CX), X2
+660f381411|223344556677885f5f5f5f	32	intel	blendvps xmm2, xmmword ptr [ecx]
+660f381411|223344556677885f5f5f5f	32	plan9	BLENDVPS X0, 0(CX), X2
+660f381411|223344556677885f5f5f5f	64	gnu	blendvps %xmm0,(%rcx),%xmm2
+660f381411|223344556677885f5f5f5f	64	intel	blendvps xmm2, xmmword ptr [rcx]
+660f381411|223344556677885f5f5f5f	64	plan9	BLENDVPS X0, 0(CX), X2
+660f381511|223344556677885f5f5f5f	32	intel	blendvpd xmm2, xmmword ptr [ecx]
+660f381511|223344556677885f5f5f5f	32	plan9	BLENDVPD X0, 0(CX), X2
+660f381511|223344556677885f5f5f5f	64	gnu	blendvpd %xmm0,(%rcx),%xmm2
+660f381511|223344556677885f5f5f5f	64	intel	blendvpd xmm2, xmmword ptr [rcx]
+660f381511|223344556677885f5f5f5f	64	plan9	BLENDVPD X0, 0(CX), X2
+660f381711|223344556677885f5f5f5f	32	intel	ptest xmm2, xmmword ptr [ecx]
+660f381711|223344556677885f5f5f5f	32	plan9	PTEST 0(CX), X2
+660f381711|223344556677885f5f5f5f	64	gnu	ptest (%rcx),%xmm2
+660f381711|223344556677885f5f5f5f	64	intel	ptest xmm2, xmmword ptr [rcx]
+660f381711|223344556677885f5f5f5f	64	plan9	PTEST 0(CX), X2
+660f381c11|223344556677885f5f5f5f	32	intel	pabsb xmm2, xmmword ptr [ecx]
+660f381c11|223344556677885f5f5f5f	32	plan9	PABSB 0(CX), X2
+660f381c11|223344556677885f5f5f5f	64	gnu	pabsb (%rcx),%xmm2
+660f381c11|223344556677885f5f5f5f	64	intel	pabsb xmm2, xmmword ptr [rcx]
+660f381c11|223344556677885f5f5f5f	64	plan9	PABSB 0(CX), X2
+660f381d11|223344556677885f5f5f5f	32	intel	pabsw xmm2, xmmword ptr [ecx]
+660f381d11|223344556677885f5f5f5f	32	plan9	PABSW 0(CX), X2
+660f381d11|223344556677885f5f5f5f	64	gnu	pabsw (%rcx),%xmm2
+660f381d11|223344556677885f5f5f5f	64	intel	pabsw xmm2, xmmword ptr [rcx]
+660f381d11|223344556677885f5f5f5f	64	plan9	PABSW 0(CX), X2
+660f381e11|223344556677885f5f5f5f	32	intel	pabsd xmm2, xmmword ptr [ecx]
+660f381e11|223344556677885f5f5f5f	32	plan9	PABSD 0(CX), X2
+660f381e11|223344556677885f5f5f5f	64	gnu	pabsd (%rcx),%xmm2
+660f381e11|223344556677885f5f5f5f	64	intel	pabsd xmm2, xmmword ptr [rcx]
+660f381e11|223344556677885f5f5f5f	64	plan9	PABSD 0(CX), X2
+660f382011|223344556677885f5f5f5f	32	intel	pmovsxbw xmm2, qword ptr [ecx]
+660f382011|223344556677885f5f5f5f	32	plan9	PMOVSXBW 0(CX), X2
+660f382011|223344556677885f5f5f5f	64	gnu	pmovsxbw (%rcx),%xmm2
+660f382011|223344556677885f5f5f5f	64	intel	pmovsxbw xmm2, qword ptr [rcx]
+660f382011|223344556677885f5f5f5f	64	plan9	PMOVSXBW 0(CX), X2
+660f382111|223344556677885f5f5f5f	32	intel	pmovsxbd xmm2, dword ptr [ecx]
+660f382111|223344556677885f5f5f5f	32	plan9	PMOVSXBD 0(CX), X2
+660f382111|223344556677885f5f5f5f	64	gnu	pmovsxbd (%rcx),%xmm2
+660f382111|223344556677885f5f5f5f	64	intel	pmovsxbd xmm2, dword ptr [rcx]
+660f382111|223344556677885f5f5f5f	64	plan9	PMOVSXBD 0(CX), X2
+660f382211|223344556677885f5f5f5f	32	intel	pmovsxbq xmm2, word ptr [ecx]
+660f382211|223344556677885f5f5f5f	32	plan9	PMOVSXBQ 0(CX), X2
+660f382211|223344556677885f5f5f5f	64	gnu	pmovsxbq (%rcx),%xmm2
+660f382211|223344556677885f5f5f5f	64	intel	pmovsxbq xmm2, word ptr [rcx]
+660f382211|223344556677885f5f5f5f	64	plan9	PMOVSXBQ 0(CX), X2
+660f382311|223344556677885f5f5f5f	32	intel	pmovsxwd xmm2, qword ptr [ecx]
+660f382311|223344556677885f5f5f5f	32	plan9	PMOVSXWD 0(CX), X2
+660f382311|223344556677885f5f5f5f	64	gnu	pmovsxwd (%rcx),%xmm2
+660f382311|223344556677885f5f5f5f	64	intel	pmovsxwd xmm2, qword ptr [rcx]
+660f382311|223344556677885f5f5f5f	64	plan9	PMOVSXWD 0(CX), X2
+660f382411|223344556677885f5f5f5f	32	intel	pmovsxwq xmm2, dword ptr [ecx]
+660f382411|223344556677885f5f5f5f	32	plan9	PMOVSXWQ 0(CX), X2
+660f382411|223344556677885f5f5f5f	64	gnu	pmovsxwq (%rcx),%xmm2
+660f382411|223344556677885f5f5f5f	64	intel	pmovsxwq xmm2, dword ptr [rcx]
+660f382411|223344556677885f5f5f5f	64	plan9	PMOVSXWQ 0(CX), X2
+660f382511|223344556677885f5f5f5f	32	intel	pmovsxdq xmm2, qword ptr [ecx]
+660f382511|223344556677885f5f5f5f	32	plan9	PMOVSXDQ 0(CX), X2
+660f382511|223344556677885f5f5f5f	64	gnu	pmovsxdq (%rcx),%xmm2
+660f382511|223344556677885f5f5f5f	64	intel	pmovsxdq xmm2, qword ptr [rcx]
+660f382511|223344556677885f5f5f5f	64	plan9	PMOVSXDQ 0(CX), X2
+660f382811|223344556677885f5f5f5f	32	intel	pmuldq xmm2, xmmword ptr [ecx]
+660f382811|223344556677885f5f5f5f	32	plan9	PMULDQ 0(CX), X2
+660f382811|223344556677885f5f5f5f	64	gnu	pmuldq (%rcx),%xmm2
+660f382811|223344556677885f5f5f5f	64	intel	pmuldq xmm2, xmmword ptr [rcx]
+660f382811|223344556677885f5f5f5f	64	plan9	PMULDQ 0(CX), X2
+660f382911|223344556677885f5f5f5f	32	intel	pcmpeqq xmm2, xmmword ptr [ecx]
+660f382911|223344556677885f5f5f5f	32	plan9	PCMPEQQ 0(CX), X2
+660f382911|223344556677885f5f5f5f	64	gnu	pcmpeqq (%rcx),%xmm2
+660f382911|223344556677885f5f5f5f	64	intel	pcmpeqq xmm2, xmmword ptr [rcx]
+660f382911|223344556677885f5f5f5f	64	plan9	PCMPEQQ 0(CX), X2
+660f382a11|223344556677885f5f5f5f	32	intel	movntdqa xmm2, xmmword ptr [ecx]
+660f382a11|223344556677885f5f5f5f	32	plan9	MOVNTDQA 0(CX), X2
+660f382a11|223344556677885f5f5f5f	64	gnu	movntdqa (%rcx),%xmm2
+660f382a11|223344556677885f5f5f5f	64	intel	movntdqa xmm2, xmmword ptr [rcx]
+660f382a11|223344556677885f5f5f5f	64	plan9	MOVNTDQA 0(CX), X2
+660f382b11|223344556677885f5f5f5f	32	intel	packusdw xmm2, xmmword ptr [ecx]
+660f382b11|223344556677885f5f5f5f	32	plan9	PACKUSDW 0(CX), X2
+660f382b11|223344556677885f5f5f5f	64	gnu	packusdw (%rcx),%xmm2
+660f382b11|223344556677885f5f5f5f	64	intel	packusdw xmm2, xmmword ptr [rcx]
+660f382b11|223344556677885f5f5f5f	64	plan9	PACKUSDW 0(CX), X2
+660f383011|223344556677885f5f5f5f	32	intel	pmovzxbw xmm2, qword ptr [ecx]
+660f383011|223344556677885f5f5f5f	32	plan9	PMOVZXBW 0(CX), X2
+660f383011|223344556677885f5f5f5f	64	gnu	pmovzxbw (%rcx),%xmm2
+660f383011|223344556677885f5f5f5f	64	intel	pmovzxbw xmm2, qword ptr [rcx]
+660f383011|223344556677885f5f5f5f	64	plan9	PMOVZXBW 0(CX), X2
+660f383111|223344556677885f5f5f5f	32	intel	pmovzxbd xmm2, dword ptr [ecx]
+660f383111|223344556677885f5f5f5f	32	plan9	PMOVZXBD 0(CX), X2
+660f383111|223344556677885f5f5f5f	64	gnu	pmovzxbd (%rcx),%xmm2
+660f383111|223344556677885f5f5f5f	64	intel	pmovzxbd xmm2, dword ptr [rcx]
+660f383111|223344556677885f5f5f5f	64	plan9	PMOVZXBD 0(CX), X2
+660f383211|223344556677885f5f5f5f	32	intel	pmovzxbq xmm2, word ptr [ecx]
+660f383211|223344556677885f5f5f5f	32	plan9	PMOVZXBQ 0(CX), X2
+660f383211|223344556677885f5f5f5f	64	gnu	pmovzxbq (%rcx),%xmm2
+660f383211|223344556677885f5f5f5f	64	intel	pmovzxbq xmm2, word ptr [rcx]
+660f383211|223344556677885f5f5f5f	64	plan9	PMOVZXBQ 0(CX), X2
+660f383311|223344556677885f5f5f5f	32	intel	pmovzxwd xmm2, qword ptr [ecx]
+660f383311|223344556677885f5f5f5f	32	plan9	PMOVZXWD 0(CX), X2
+660f383311|223344556677885f5f5f5f	64	gnu	pmovzxwd (%rcx),%xmm2
+660f383311|223344556677885f5f5f5f	64	intel	pmovzxwd xmm2, qword ptr [rcx]
+660f383311|223344556677885f5f5f5f	64	plan9	PMOVZXWD 0(CX), X2
+660f383411|223344556677885f5f5f5f	32	intel	pmovzxwq xmm2, dword ptr [ecx]
+660f383411|223344556677885f5f5f5f	32	plan9	PMOVZXWQ 0(CX), X2
+660f383411|223344556677885f5f5f5f	64	gnu	pmovzxwq (%rcx),%xmm2
+660f383411|223344556677885f5f5f5f	64	intel	pmovzxwq xmm2, dword ptr [rcx]
+660f383411|223344556677885f5f5f5f	64	plan9	PMOVZXWQ 0(CX), X2
+660f383511|223344556677885f5f5f5f	32	intel	pmovzxdq xmm2, qword ptr [ecx]
+660f383511|223344556677885f5f5f5f	32	plan9	PMOVZXDQ 0(CX), X2
+660f383511|223344556677885f5f5f5f	64	gnu	pmovzxdq (%rcx),%xmm2
+660f383511|223344556677885f5f5f5f	64	intel	pmovzxdq xmm2, qword ptr [rcx]
+660f383511|223344556677885f5f5f5f	64	plan9	PMOVZXDQ 0(CX), X2
+660f383711|223344556677885f5f5f5f	32	intel	pcmpgtq xmm2, xmmword ptr [ecx]
+660f383711|223344556677885f5f5f5f	32	plan9	PCMPGTQ 0(CX), X2
+660f383711|223344556677885f5f5f5f	64	gnu	pcmpgtq (%rcx),%xmm2
+660f383711|223344556677885f5f5f5f	64	intel	pcmpgtq xmm2, xmmword ptr [rcx]
+660f383711|223344556677885f5f5f5f	64	plan9	PCMPGTQ 0(CX), X2
+660f383811|223344556677885f5f5f5f	32	intel	pminsb xmm2, xmmword ptr [ecx]
+660f383811|223344556677885f5f5f5f	32	plan9	PMINSB 0(CX), X2
+660f383811|223344556677885f5f5f5f	64	gnu	pminsb (%rcx),%xmm2
+660f383811|223344556677885f5f5f5f	64	intel	pminsb xmm2, xmmword ptr [rcx]
+660f383811|223344556677885f5f5f5f	64	plan9	PMINSB 0(CX), X2
+660f383911|223344556677885f5f5f5f	32	intel	pminsd xmm2, xmmword ptr [ecx]
+660f383911|223344556677885f5f5f5f	32	plan9	PMINSD 0(CX), X2
+660f383911|223344556677885f5f5f5f	64	gnu	pminsd (%rcx),%xmm2
+660f383911|223344556677885f5f5f5f	64	intel	pminsd xmm2, xmmword ptr [rcx]
+660f383911|223344556677885f5f5f5f	64	plan9	PMINSD 0(CX), X2
+660f383a11|223344556677885f5f5f5f	32	intel	pminuw xmm2, xmmword ptr [ecx]
+660f383a11|223344556677885f5f5f5f	32	plan9	PMINUW 0(CX), X2
+660f383a11|223344556677885f5f5f5f	64	gnu	pminuw (%rcx),%xmm2
+660f383a11|223344556677885f5f5f5f	64	intel	pminuw xmm2, xmmword ptr [rcx]
+660f383a11|223344556677885f5f5f5f	64	plan9	PMINUW 0(CX), X2
+660f383b11|223344556677885f5f5f5f	32	intel	pminud xmm2, xmmword ptr [ecx]
+660f383b11|223344556677885f5f5f5f	32	plan9	PMINUD 0(CX), X2
+660f383b11|223344556677885f5f5f5f	64	gnu	pminud (%rcx),%xmm2
+660f383b11|223344556677885f5f5f5f	64	intel	pminud xmm2, xmmword ptr [rcx]
+660f383b11|223344556677885f5f5f5f	64	plan9	PMINUD 0(CX), X2
+660f383c11|223344556677885f5f5f5f	32	intel	pmaxsb xmm2, xmmword ptr [ecx]
+660f383c11|223344556677885f5f5f5f	32	plan9	PMAXSB 0(CX), X2
+660f383c11|223344556677885f5f5f5f	64	gnu	pmaxsb (%rcx),%xmm2
+660f383c11|223344556677885f5f5f5f	64	intel	pmaxsb xmm2, xmmword ptr [rcx]
+660f383c11|223344556677885f5f5f5f	64	plan9	PMAXSB 0(CX), X2
+660f383d11|223344556677885f5f5f5f	32	intel	pmaxsd xmm2, xmmword ptr [ecx]
+660f383d11|223344556677885f5f5f5f	32	plan9	PMAXSD 0(CX), X2
+660f383d11|223344556677885f5f5f5f	64	gnu	pmaxsd (%rcx),%xmm2
+660f383d11|223344556677885f5f5f5f	64	intel	pmaxsd xmm2, xmmword ptr [rcx]
+660f383d11|223344556677885f5f5f5f	64	plan9	PMAXSD 0(CX), X2
+660f383e11|223344556677885f5f5f5f	32	intel	pmaxuw xmm2, xmmword ptr [ecx]
+660f383e11|223344556677885f5f5f5f	32	plan9	PMAXUW 0(CX), X2
+660f383e11|223344556677885f5f5f5f	64	gnu	pmaxuw (%rcx),%xmm2
+660f383e11|223344556677885f5f5f5f	64	intel	pmaxuw xmm2, xmmword ptr [rcx]
+660f383e11|223344556677885f5f5f5f	64	plan9	PMAXUW 0(CX), X2
+660f383f11|223344556677885f5f5f5f	32	intel	pmaxud xmm2, xmmword ptr [ecx]
+660f383f11|223344556677885f5f5f5f	32	plan9	PMAXUD 0(CX), X2
+660f383f11|223344556677885f5f5f5f	64	gnu	pmaxud (%rcx),%xmm2
+660f383f11|223344556677885f5f5f5f	64	intel	pmaxud xmm2, xmmword ptr [rcx]
+660f383f11|223344556677885f5f5f5f	64	plan9	PMAXUD 0(CX), X2
+660f384011|223344556677885f5f5f5f	32	intel	pmulld xmm2, xmmword ptr [ecx]
+660f384011|223344556677885f5f5f5f	32	plan9	PMULLD 0(CX), X2
+660f384011|223344556677885f5f5f5f	64	gnu	pmulld (%rcx),%xmm2
+660f384011|223344556677885f5f5f5f	64	intel	pmulld xmm2, xmmword ptr [rcx]
+660f384011|223344556677885f5f5f5f	64	plan9	PMULLD 0(CX), X2
+660f384111|223344556677885f5f5f5f	32	intel	phminposuw xmm2, xmmword ptr [ecx]
+660f384111|223344556677885f5f5f5f	32	plan9	PHMINPOSUW 0(CX), X2
+660f384111|223344556677885f5f5f5f	64	gnu	phminposuw (%rcx),%xmm2
+660f384111|223344556677885f5f5f5f	64	intel	phminposuw xmm2, xmmword ptr [rcx]
+660f384111|223344556677885f5f5f5f	64	plan9	PHMINPOSUW 0(CX), X2
+660f388211|223344556677885f5f5f5f	32	intel	invpcid edx, xmmword ptr [ecx]
+660f388211|223344556677885f5f5f5f	32	plan9	INVPCID 0(CX), DX
+660f388211|223344556677885f5f5f5f	64	gnu	invpcid (%rcx),%rdx
+660f388211|223344556677885f5f5f5f	64	intel	invpcid rdx, xmmword ptr [rcx]
+660f388211|223344556677885f5f5f5f	64	plan9	INVPCID 0(CX), DX
+660f38db11|223344556677885f5f5f5f	32	intel	aesimc xmm2, xmmword ptr [ecx]
+660f38db11|223344556677885f5f5f5f	32	plan9	AESIMC 0(CX), X2
+660f38db11|223344556677885f5f5f5f	64	gnu	aesimc (%rcx),%xmm2
+660f38db11|223344556677885f5f5f5f	64	intel	aesimc xmm2, xmmword ptr [rcx]
+660f38db11|223344556677885f5f5f5f	64	plan9	AESIMC 0(CX), X2
+660f38dc11|223344556677885f5f5f5f	32	intel	aesenc xmm2, xmmword ptr [ecx]
+660f38dc11|223344556677885f5f5f5f	32	plan9	AESENC 0(CX), X2
+660f38dc11|223344556677885f5f5f5f	64	gnu	aesenc (%rcx),%xmm2
+660f38dc11|223344556677885f5f5f5f	64	intel	aesenc xmm2, xmmword ptr [rcx]
+660f38dc11|223344556677885f5f5f5f	64	plan9	AESENC 0(CX), X2
+660f38dd11|223344556677885f5f5f5f	32	intel	aesenclast xmm2, xmmword ptr [ecx]
+660f38dd11|223344556677885f5f5f5f	32	plan9	AESENCLAST 0(CX), X2
+660f38dd11|223344556677885f5f5f5f	64	gnu	aesenclast (%rcx),%xmm2
+660f38dd11|223344556677885f5f5f5f	64	intel	aesenclast xmm2, xmmword ptr [rcx]
+660f38dd11|223344556677885f5f5f5f	64	plan9	AESENCLAST 0(CX), X2
+660f38de11|223344556677885f5f5f5f	32	intel	aesdec xmm2, xmmword ptr [ecx]
+660f38de11|223344556677885f5f5f5f	32	plan9	AESDEC 0(CX), X2
+660f38de11|223344556677885f5f5f5f	64	gnu	aesdec (%rcx),%xmm2
+660f38de11|223344556677885f5f5f5f	64	intel	aesdec xmm2, xmmword ptr [rcx]
+660f38de11|223344556677885f5f5f5f	64	plan9	AESDEC 0(CX), X2
+660f38df11|223344556677885f5f5f5f	32	intel	aesdeclast xmm2, xmmword ptr [ecx]
+660f38df11|223344556677885f5f5f5f	32	plan9	AESDECLAST 0(CX), X2
+660f38df11|223344556677885f5f5f5f	64	gnu	aesdeclast (%rcx),%xmm2
+660f38df11|223344556677885f5f5f5f	64	intel	aesdeclast xmm2, xmmword ptr [rcx]
+660f38df11|223344556677885f5f5f5f	64	plan9	AESDECLAST 0(CX), X2
+660f3a081122|3344556677885f5f5f5f	32	intel	roundps xmm2, xmmword ptr [ecx], 0x22
+660f3a081122|3344556677885f5f5f5f	32	plan9	ROUNDPS $0x22, 0(CX), X2
+660f3a081122|3344556677885f5f5f5f	64	gnu	roundps $0x22,(%rcx),%xmm2
+660f3a081122|3344556677885f5f5f5f	64	intel	roundps xmm2, xmmword ptr [rcx], 0x22
+660f3a081122|3344556677885f5f5f5f	64	plan9	ROUNDPS $0x22, 0(CX), X2
+660f3a091122|3344556677885f5f5f5f	32	intel	roundpd xmm2, xmmword ptr [ecx], 0x22
+660f3a091122|3344556677885f5f5f5f	32	plan9	ROUNDPD $0x22, 0(CX), X2
+660f3a091122|3344556677885f5f5f5f	64	gnu	roundpd $0x22,(%rcx),%xmm2
+660f3a091122|3344556677885f5f5f5f	64	intel	roundpd xmm2, xmmword ptr [rcx], 0x22
+660f3a091122|3344556677885f5f5f5f	64	plan9	ROUNDPD $0x22, 0(CX), X2
+660f3a0a1122|3344556677885f5f5f5f	32	intel	roundss xmm2, dword ptr [ecx], 0x22
+660f3a0a1122|3344556677885f5f5f5f	32	plan9	ROUNDSS $0x22, 0(CX), X2
+660f3a0a1122|3344556677885f5f5f5f	64	gnu	roundss $0x22,(%rcx),%xmm2
+660f3a0a1122|3344556677885f5f5f5f	64	intel	roundss xmm2, dword ptr [rcx], 0x22
+660f3a0a1122|3344556677885f5f5f5f	64	plan9	ROUNDSS $0x22, 0(CX), X2
+660f3a0b1122|3344556677885f5f5f5f	32	intel	roundsd xmm2, qword ptr [ecx], 0x22
+660f3a0b1122|3344556677885f5f5f5f	32	plan9	ROUNDSD $0x22, 0(CX), X2
+660f3a0b1122|3344556677885f5f5f5f	64	gnu	roundsd $0x22,(%rcx),%xmm2
+660f3a0b1122|3344556677885f5f5f5f	64	intel	roundsd xmm2, qword ptr [rcx], 0x22
+660f3a0b1122|3344556677885f5f5f5f	64	plan9	ROUNDSD $0x22, 0(CX), X2
+660f3a0c1122|3344556677885f5f5f5f	32	intel	blendps xmm2, xmmword ptr [ecx], 0x22
+660f3a0c1122|3344556677885f5f5f5f	32	plan9	BLENDPS $0x22, 0(CX), X2
+660f3a0c1122|3344556677885f5f5f5f	64	gnu	blendps $0x22,(%rcx),%xmm2
+660f3a0c1122|3344556677885f5f5f5f	64	intel	blendps xmm2, xmmword ptr [rcx], 0x22
+660f3a0c1122|3344556677885f5f5f5f	64	plan9	BLENDPS $0x22, 0(CX), X2
+660f3a0d1122|3344556677885f5f5f5f	32	intel	blendpd xmm2, xmmword ptr [ecx], 0x22
+660f3a0d1122|3344556677885f5f5f5f	32	plan9	BLENDPD $0x22, 0(CX), X2
+660f3a0d1122|3344556677885f5f5f5f	64	gnu	blendpd $0x22,(%rcx),%xmm2
+660f3a0d1122|3344556677885f5f5f5f	64	intel	blendpd xmm2, xmmword ptr [rcx], 0x22
+660f3a0d1122|3344556677885f5f5f5f	64	plan9	BLENDPD $0x22, 0(CX), X2
+660f3a0e1122|3344556677885f5f5f5f	32	intel	pblendw xmm2, xmmword ptr [ecx], 0x22
+660f3a0e1122|3344556677885f5f5f5f	32	plan9	PBLENDW $0x22, 0(CX), X2
+660f3a0e1122|3344556677885f5f5f5f	64	gnu	pblendw $0x22,(%rcx),%xmm2
+660f3a0e1122|3344556677885f5f5f5f	64	intel	pblendw xmm2, xmmword ptr [rcx], 0x22
+660f3a0e1122|3344556677885f5f5f5f	64	plan9	PBLENDW $0x22, 0(CX), X2
+660f3a0f1122|3344556677885f5f5f5f	32	intel	palignr xmm2, xmmword ptr [ecx], 0x22
+660f3a0f1122|3344556677885f5f5f5f	32	plan9	PALIGNR $0x22, 0(CX), X2
+660f3a0f1122|3344556677885f5f5f5f	64	gnu	palignr $0x22,(%rcx),%xmm2
+660f3a0f1122|3344556677885f5f5f5f	64	intel	palignr xmm2, xmmword ptr [rcx], 0x22
+660f3a0f1122|3344556677885f5f5f5f	64	plan9	PALIGNR $0x22, 0(CX), X2
+660f3a141122|3344556677885f5f5f5f	32	intel	pextrb byte ptr [ecx], xmm2, 0x22
+660f3a141122|3344556677885f5f5f5f	32	plan9	PEXTRB $0x22, X2, 0(CX)
+660f3a141122|3344556677885f5f5f5f	64	gnu	pextrb $0x22,%xmm2,(%rcx)
+660f3a141122|3344556677885f5f5f5f	64	intel	pextrb byte ptr [rcx], xmm2, 0x22
+660f3a141122|3344556677885f5f5f5f	64	plan9	PEXTRB $0x22, X2, 0(CX)
+660f3a151122|3344556677885f5f5f5f	32	intel	pextrw word ptr [ecx], xmm2, 0x22
+660f3a151122|3344556677885f5f5f5f	32	plan9	PEXTRW $0x22, X2, 0(CX)
+660f3a151122|3344556677885f5f5f5f	64	gnu	pextrw $0x22,%xmm2,(%rcx)
+660f3a151122|3344556677885f5f5f5f	64	intel	pextrw word ptr [rcx], xmm2, 0x22
+660f3a151122|3344556677885f5f5f5f	64	plan9	PEXTRW $0x22, X2, 0(CX)
+660f3a161122|3344556677885f5f5f5f	32	intel	pextrd dword ptr [ecx], xmm2, 0x22
+660f3a161122|3344556677885f5f5f5f	32	plan9	PEXTRD $0x22, X2, 0(CX)
+660f3a161122|3344556677885f5f5f5f	64	gnu	pextrd $0x22,%xmm2,(%rcx)
+660f3a161122|3344556677885f5f5f5f	64	intel	pextrd dword ptr [rcx], xmm2, 0x22
+660f3a161122|3344556677885f5f5f5f	64	plan9	PEXTRD $0x22, X2, 0(CX)
+660f3a171122|3344556677885f5f5f5f	32	intel	extractps dword ptr [ecx], xmm2, 0x22
+660f3a171122|3344556677885f5f5f5f	32	plan9	EXTRACTPS $0x22, X2, 0(CX)
+660f3a171122|3344556677885f5f5f5f	64	gnu	extractps $0x22,%xmm2,(%rcx)
+660f3a171122|3344556677885f5f5f5f	64	intel	extractps dword ptr [rcx], xmm2, 0x22
+660f3a171122|3344556677885f5f5f5f	64	plan9	EXTRACTPS $0x22, X2, 0(CX)
+660f3a201122|3344556677885f5f5f5f	32	intel	pinsrb xmm2, byte ptr [ecx], 0x22
+660f3a201122|3344556677885f5f5f5f	32	plan9	PINSRB $0x22, 0(CX), X2
+660f3a201122|3344556677885f5f5f5f	64	gnu	pinsrb $0x22,(%rcx),%xmm2
+660f3a201122|3344556677885f5f5f5f	64	intel	pinsrb xmm2, byte ptr [rcx], 0x22
+660f3a201122|3344556677885f5f5f5f	64	plan9	PINSRB $0x22, 0(CX), X2
+660f3a211122|3344556677885f5f5f5f	32	intel	insertps xmm2, dword ptr [ecx], 0x22
+660f3a211122|3344556677885f5f5f5f	32	plan9	INSERTPS $0x22, 0(CX), X2
+660f3a211122|3344556677885f5f5f5f	64	gnu	insertps $0x22,(%rcx),%xmm2
+660f3a211122|3344556677885f5f5f5f	64	intel	insertps xmm2, dword ptr [rcx], 0x22
+660f3a211122|3344556677885f5f5f5f	64	plan9	INSERTPS $0x22, 0(CX), X2
+660f3a221122|3344556677885f5f5f5f	32	intel	pinsrd xmm2, dword ptr [ecx], 0x22
+660f3a221122|3344556677885f5f5f5f	32	plan9	PINSRD $0x22, 0(CX), X2
+660f3a221122|3344556677885f5f5f5f	64	gnu	pinsrd $0x22,(%rcx),%xmm2
+660f3a221122|3344556677885f5f5f5f	64	intel	pinsrd xmm2, dword ptr [rcx], 0x22
+660f3a221122|3344556677885f5f5f5f	64	plan9	PINSRD $0x22, 0(CX), X2
+660f3a401122|3344556677885f5f5f5f	32	intel	dpps xmm2, xmmword ptr [ecx], 0x22
+660f3a401122|3344556677885f5f5f5f	32	plan9	DPPS $0x22, 0(CX), X2
+660f3a401122|3344556677885f5f5f5f	64	gnu	dpps $0x22,(%rcx),%xmm2
+660f3a401122|3344556677885f5f5f5f	64	intel	dpps xmm2, xmmword ptr [rcx], 0x22
+660f3a401122|3344556677885f5f5f5f	64	plan9	DPPS $0x22, 0(CX), X2
+660f3a411122|3344556677885f5f5f5f	32	intel	dppd xmm2, xmmword ptr [ecx], 0x22
+660f3a411122|3344556677885f5f5f5f	32	plan9	DPPD $0x22, 0(CX), X2
+660f3a411122|3344556677885f5f5f5f	64	gnu	dppd $0x22,(%rcx),%xmm2
+660f3a411122|3344556677885f5f5f5f	64	intel	dppd xmm2, xmmword ptr [rcx], 0x22
+660f3a411122|3344556677885f5f5f5f	64	plan9	DPPD $0x22, 0(CX), X2
+660f3a421122|3344556677885f5f5f5f	32	intel	mpsadbw xmm2, xmmword ptr [ecx], 0x22
+660f3a421122|3344556677885f5f5f5f	32	plan9	MPSADBW $0x22, 0(CX), X2
+660f3a421122|3344556677885f5f5f5f	64	gnu	mpsadbw $0x22,(%rcx),%xmm2
+660f3a421122|3344556677885f5f5f5f	64	intel	mpsadbw xmm2, xmmword ptr [rcx], 0x22
+660f3a421122|3344556677885f5f5f5f	64	plan9	MPSADBW $0x22, 0(CX), X2
+660f3a441122|3344556677885f5f5f5f	32	intel	pclmulqdq xmm2, xmmword ptr [ecx], 0x22
+660f3a441122|3344556677885f5f5f5f	32	plan9	PCLMULQDQ $0x22, 0(CX), X2
+660f3a441122|3344556677885f5f5f5f	64	gnu	pclmulqdq $0x22,(%rcx),%xmm2
+660f3a441122|3344556677885f5f5f5f	64	intel	pclmulqdq xmm2, xmmword ptr [rcx], 0x22
+660f3a441122|3344556677885f5f5f5f	64	plan9	PCLMULQDQ $0x22, 0(CX), X2
+660f3a601122|3344556677885f5f5f5f	32	intel	pcmpestrm xmm2, xmmword ptr [ecx], 0x22
+660f3a601122|3344556677885f5f5f5f	32	plan9	PCMPESTRM $0x22, 0(CX), X2
+660f3a601122|3344556677885f5f5f5f	64	gnu	pcmpestrm $0x22,(%rcx),%xmm2
+660f3a601122|3344556677885f5f5f5f	64	intel	pcmpestrm xmm2, xmmword ptr [rcx], 0x22
+660f3a601122|3344556677885f5f5f5f	64	plan9	PCMPESTRM $0x22, 0(CX), X2
+660f3a611122|3344556677885f5f5f5f	32	intel	pcmpestri xmm2, xmmword ptr [ecx], 0x22
+660f3a611122|3344556677885f5f5f5f	32	plan9	PCMPESTRI $0x22, 0(CX), X2
+660f3a611122|3344556677885f5f5f5f	64	gnu	pcmpestri $0x22,(%rcx),%xmm2
+660f3a611122|3344556677885f5f5f5f	64	intel	pcmpestri xmm2, xmmword ptr [rcx], 0x22
+660f3a611122|3344556677885f5f5f5f	64	plan9	PCMPESTRI $0x22, 0(CX), X2
+660f3a621122|3344556677885f5f5f5f	32	intel	pcmpistrm xmm2, xmmword ptr [ecx], 0x22
+660f3a621122|3344556677885f5f5f5f	32	plan9	PCMPISTRM $0x22, 0(CX), X2
+660f3a621122|3344556677885f5f5f5f	64	gnu	pcmpistrm $0x22,(%rcx),%xmm2
+660f3a621122|3344556677885f5f5f5f	64	intel	pcmpistrm xmm2, xmmword ptr [rcx], 0x22
+660f3a621122|3344556677885f5f5f5f	64	plan9	PCMPISTRM $0x22, 0(CX), X2
+660f3a631122|3344556677885f5f5f5f	32	intel	pcmpistri xmm2, xmmword ptr [ecx], 0x22
+660f3a631122|3344556677885f5f5f5f	32	plan9	PCMPISTRI $0x22, 0(CX), X2
+660f3a631122|3344556677885f5f5f5f	64	gnu	pcmpistri $0x22,(%rcx),%xmm2
+660f3a631122|3344556677885f5f5f5f	64	intel	pcmpistri xmm2, xmmword ptr [rcx], 0x22
+660f3a631122|3344556677885f5f5f5f	64	plan9	PCMPISTRI $0x22, 0(CX), X2
+660f3adf1122|3344556677885f5f5f5f	32	intel	aeskeygenassist xmm2, xmmword ptr [ecx], 0x22
+660f3adf1122|3344556677885f5f5f5f	32	plan9	AESKEYGENASSIST $0x22, 0(CX), X2
+660f3adf1122|3344556677885f5f5f5f	64	gnu	aeskeygenassist $0x22,(%rcx),%xmm2
+660f3adf1122|3344556677885f5f5f5f	64	intel	aeskeygenassist xmm2, xmmword ptr [rcx], 0x22
+660f3adf1122|3344556677885f5f5f5f	64	plan9	AESKEYGENASSIST $0x22, 0(CX), X2
+660f4011|223344556677885f5f5f5f5f	32	intel	cmovo dx, word ptr [ecx]
+660f4011|223344556677885f5f5f5f5f	32	plan9	CMOVO 0(CX), DX
+660f4011|223344556677885f5f5f5f5f	64	gnu	cmovo (%rcx),%dx
+660f4011|223344556677885f5f5f5f5f	64	intel	cmovo dx, word ptr [rcx]
+660f4011|223344556677885f5f5f5f5f	64	plan9	CMOVO 0(CX), DX
+660f4111|223344556677885f5f5f5f5f	32	intel	cmovno dx, word ptr [ecx]
+660f4111|223344556677885f5f5f5f5f	32	plan9	CMOVNO 0(CX), DX
+660f4111|223344556677885f5f5f5f5f	64	gnu	cmovno (%rcx),%dx
+660f4111|223344556677885f5f5f5f5f	64	intel	cmovno dx, word ptr [rcx]
+660f4111|223344556677885f5f5f5f5f	64	plan9	CMOVNO 0(CX), DX
+660f4211|223344556677885f5f5f5f5f	32	intel	cmovb dx, word ptr [ecx]
+660f4211|223344556677885f5f5f5f5f	32	plan9	CMOVB 0(CX), DX
+660f4211|223344556677885f5f5f5f5f	64	gnu	cmovb (%rcx),%dx
+660f4211|223344556677885f5f5f5f5f	64	intel	cmovb dx, word ptr [rcx]
+660f4211|223344556677885f5f5f5f5f	64	plan9	CMOVB 0(CX), DX
+660f4311|223344556677885f5f5f5f5f	32	intel	cmovnb dx, word ptr [ecx]
+660f4311|223344556677885f5f5f5f5f	32	plan9	CMOVAE 0(CX), DX
+660f4311|223344556677885f5f5f5f5f	64	gnu	cmovae (%rcx),%dx
+660f4311|223344556677885f5f5f5f5f	64	intel	cmovnb dx, word ptr [rcx]
+660f4311|223344556677885f5f5f5f5f	64	plan9	CMOVAE 0(CX), DX
+660f4411|223344556677885f5f5f5f5f	32	intel	cmovz dx, word ptr [ecx]
+660f4411|223344556677885f5f5f5f5f	32	plan9	CMOVE 0(CX), DX
+660f4411|223344556677885f5f5f5f5f	64	gnu	cmove (%rcx),%dx
+660f4411|223344556677885f5f5f5f5f	64	intel	cmovz dx, word ptr [rcx]
+660f4411|223344556677885f5f5f5f5f	64	plan9	CMOVE 0(CX), DX
+660f4511|223344556677885f5f5f5f5f	32	intel	cmovnz dx, word ptr [ecx]
+660f4511|223344556677885f5f5f5f5f	32	plan9	CMOVNE 0(CX), DX
+660f4511|223344556677885f5f5f5f5f	64	gnu	cmovne (%rcx),%dx
+660f4511|223344556677885f5f5f5f5f	64	intel	cmovnz dx, word ptr [rcx]
+660f4511|223344556677885f5f5f5f5f	64	plan9	CMOVNE 0(CX), DX
+660f4611|223344556677885f5f5f5f5f	32	intel	cmovbe dx, word ptr [ecx]
+660f4611|223344556677885f5f5f5f5f	32	plan9	CMOVBE 0(CX), DX
+660f4611|223344556677885f5f5f5f5f	64	gnu	cmovbe (%rcx),%dx
+660f4611|223344556677885f5f5f5f5f	64	intel	cmovbe dx, word ptr [rcx]
+660f4611|223344556677885f5f5f5f5f	64	plan9	CMOVBE 0(CX), DX
+660f4711|223344556677885f5f5f5f5f	32	intel	cmovnbe dx, word ptr [ecx]
+660f4711|223344556677885f5f5f5f5f	32	plan9	CMOVA 0(CX), DX
+660f4711|223344556677885f5f5f5f5f	64	gnu	cmova (%rcx),%dx
+660f4711|223344556677885f5f5f5f5f	64	intel	cmovnbe dx, word ptr [rcx]
+660f4711|223344556677885f5f5f5f5f	64	plan9	CMOVA 0(CX), DX
+660f4811|223344556677885f5f5f5f5f	32	intel	cmovs dx, word ptr [ecx]
+660f4811|223344556677885f5f5f5f5f	32	plan9	CMOVS 0(CX), DX
+660f4811|223344556677885f5f5f5f5f	64	gnu	cmovs (%rcx),%dx
+660f4811|223344556677885f5f5f5f5f	64	intel	cmovs dx, word ptr [rcx]
+660f4811|223344556677885f5f5f5f5f	64	plan9	CMOVS 0(CX), DX
+660f4911|223344556677885f5f5f5f5f	32	intel	cmovns dx, word ptr [ecx]
+660f4911|223344556677885f5f5f5f5f	32	plan9	CMOVNS 0(CX), DX
+660f4911|223344556677885f5f5f5f5f	64	gnu	cmovns (%rcx),%dx
+660f4911|223344556677885f5f5f5f5f	64	intel	cmovns dx, word ptr [rcx]
+660f4911|223344556677885f5f5f5f5f	64	plan9	CMOVNS 0(CX), DX
+660f4a11|223344556677885f5f5f5f5f	32	intel	cmovp dx, word ptr [ecx]
+660f4a11|223344556677885f5f5f5f5f	32	plan9	CMOVP 0(CX), DX
+660f4a11|223344556677885f5f5f5f5f	64	gnu	cmovp (%rcx),%dx
+660f4a11|223344556677885f5f5f5f5f	64	intel	cmovp dx, word ptr [rcx]
+660f4a11|223344556677885f5f5f5f5f	64	plan9	CMOVP 0(CX), DX
+660f4b11|223344556677885f5f5f5f5f	32	intel	cmovnp dx, word ptr [ecx]
+660f4b11|223344556677885f5f5f5f5f	32	plan9	CMOVNP 0(CX), DX
+660f4b11|223344556677885f5f5f5f5f	64	gnu	cmovnp (%rcx),%dx
+660f4b11|223344556677885f5f5f5f5f	64	intel	cmovnp dx, word ptr [rcx]
+660f4b11|223344556677885f5f5f5f5f	64	plan9	CMOVNP 0(CX), DX
+660f4c11|223344556677885f5f5f5f5f	32	intel	cmovl dx, word ptr [ecx]
+660f4c11|223344556677885f5f5f5f5f	32	plan9	CMOVL 0(CX), DX
+660f4c11|223344556677885f5f5f5f5f	64	gnu	cmovl (%rcx),%dx
+660f4c11|223344556677885f5f5f5f5f	64	intel	cmovl dx, word ptr [rcx]
+660f4c11|223344556677885f5f5f5f5f	64	plan9	CMOVL 0(CX), DX
+660f4d11|223344556677885f5f5f5f5f	32	intel	cmovnl dx, word ptr [ecx]
+660f4d11|223344556677885f5f5f5f5f	32	plan9	CMOVGE 0(CX), DX
+660f4d11|223344556677885f5f5f5f5f	64	gnu	cmovge (%rcx),%dx
+660f4d11|223344556677885f5f5f5f5f	64	intel	cmovnl dx, word ptr [rcx]
+660f4d11|223344556677885f5f5f5f5f	64	plan9	CMOVGE 0(CX), DX
+660f4e11|223344556677885f5f5f5f5f	32	intel	cmovle dx, word ptr [ecx]
+660f4e11|223344556677885f5f5f5f5f	32	plan9	CMOVLE 0(CX), DX
+660f4e11|223344556677885f5f5f5f5f	64	gnu	cmovle (%rcx),%dx
+660f4e11|223344556677885f5f5f5f5f	64	intel	cmovle dx, word ptr [rcx]
+660f4e11|223344556677885f5f5f5f5f	64	plan9	CMOVLE 0(CX), DX
+660f4f11|223344556677885f5f5f5f5f	32	intel	cmovnle dx, word ptr [ecx]
+660f4f11|223344556677885f5f5f5f5f	32	plan9	CMOVG 0(CX), DX
+660f4f11|223344556677885f5f5f5f5f	64	gnu	cmovg (%rcx),%dx
+660f4f11|223344556677885f5f5f5f5f	64	intel	cmovnle dx, word ptr [rcx]
+660f4f11|223344556677885f5f5f5f5f	64	plan9	CMOVG 0(CX), DX
+660f50c0|11223344556677885f5f5f5f	32	intel	movmskpd eax, xmm0
+660f50c0|11223344556677885f5f5f5f	32	plan9	MOVMSKPD X0, AX
+660f50c0|11223344556677885f5f5f5f	64	gnu	movmskpd %xmm0,%eax
+660f50c0|11223344556677885f5f5f5f	64	intel	movmskpd eax, xmm0
+660f50c0|11223344556677885f5f5f5f	64	plan9	MOVMSKPD X0, AX
+660f5111|223344556677885f5f5f5f5f	32	intel	sqrtpd xmm2, xmmword ptr [ecx]
+660f5111|223344556677885f5f5f5f5f	32	plan9	SQRTPD 0(CX), X2
+660f5111|223344556677885f5f5f5f5f	64	gnu	sqrtpd (%rcx),%xmm2
+660f5111|223344556677885f5f5f5f5f	64	intel	sqrtpd xmm2, xmmword ptr [rcx]
+660f5111|223344556677885f5f5f5f5f	64	plan9	SQRTPD 0(CX), X2
+660f5411|223344556677885f5f5f5f5f	32	intel	andpd xmm2, xmmword ptr [ecx]
+660f5411|223344556677885f5f5f5f5f	32	plan9	ANDPD 0(CX), X2
+660f5411|223344556677885f5f5f5f5f	64	gnu	andpd (%rcx),%xmm2
+660f5411|223344556677885f5f5f5f5f	64	intel	andpd xmm2, xmmword ptr [rcx]
+660f5411|223344556677885f5f5f5f5f	64	plan9	ANDPD 0(CX), X2
+660f5511|223344556677885f5f5f5f5f	32	intel	andnpd xmm2, xmmword ptr [ecx]
+660f5511|223344556677885f5f5f5f5f	32	plan9	ANDNPD 0(CX), X2
+660f5511|223344556677885f5f5f5f5f	64	gnu	andnpd (%rcx),%xmm2
+660f5511|223344556677885f5f5f5f5f	64	intel	andnpd xmm2, xmmword ptr [rcx]
+660f5511|223344556677885f5f5f5f5f	64	plan9	ANDNPD 0(CX), X2
+660f5611|223344556677885f5f5f5f5f	32	intel	orpd xmm2, xmmword ptr [ecx]
+660f5611|223344556677885f5f5f5f5f	32	plan9	ORPD 0(CX), X2
+660f5611|223344556677885f5f5f5f5f	64	gnu	orpd (%rcx),%xmm2
+660f5611|223344556677885f5f5f5f5f	64	intel	orpd xmm2, xmmword ptr [rcx]
+660f5611|223344556677885f5f5f5f5f	64	plan9	ORPD 0(CX), X2
+660f5711|223344556677885f5f5f5f5f	32	intel	xorpd xmm2, xmmword ptr [ecx]
+660f5711|223344556677885f5f5f5f5f	32	plan9	XORPD 0(CX), X2
+660f5711|223344556677885f5f5f5f5f	64	gnu	xorpd (%rcx),%xmm2
+660f5711|223344556677885f5f5f5f5f	64	intel	xorpd xmm2, xmmword ptr [rcx]
+660f5711|223344556677885f5f5f5f5f	64	plan9	XORPD 0(CX), X2
+660f5811|223344556677885f5f5f5f5f	32	intel	addpd xmm2, xmmword ptr [ecx]
+660f5811|223344556677885f5f5f5f5f	32	plan9	ADDPD 0(CX), X2
+660f5811|223344556677885f5f5f5f5f	64	gnu	addpd (%rcx),%xmm2
+660f5811|223344556677885f5f5f5f5f	64	intel	addpd xmm2, xmmword ptr [rcx]
+660f5811|223344556677885f5f5f5f5f	64	plan9	ADDPD 0(CX), X2
+660f5911|223344556677885f5f5f5f5f	32	intel	mulpd xmm2, xmmword ptr [ecx]
+660f5911|223344556677885f5f5f5f5f	32	plan9	MULPD 0(CX), X2
+660f5911|223344556677885f5f5f5f5f	64	gnu	mulpd (%rcx),%xmm2
+660f5911|223344556677885f5f5f5f5f	64	intel	mulpd xmm2, xmmword ptr [rcx]
+660f5911|223344556677885f5f5f5f5f	64	plan9	MULPD 0(CX), X2
+660f5a11|223344556677885f5f5f5f5f	32	intel	cvtpd2ps xmm2, xmmword ptr [ecx]
+660f5a11|223344556677885f5f5f5f5f	32	plan9	CVTPD2PS 0(CX), X2
+660f5a11|223344556677885f5f5f5f5f	64	gnu	cvtpd2ps (%rcx),%xmm2
+660f5a11|223344556677885f5f5f5f5f	64	intel	cvtpd2ps xmm2, xmmword ptr [rcx]
+660f5a11|223344556677885f5f5f5f5f	64	plan9	CVTPD2PS 0(CX), X2
+660f5b11|223344556677885f5f5f5f5f	32	intel	cvtps2dq xmm2, xmmword ptr [ecx]
+660f5b11|223344556677885f5f5f5f5f	32	plan9	CVTPS2DQ 0(CX), X2
+660f5b11|223344556677885f5f5f5f5f	64	gnu	cvtps2dq (%rcx),%xmm2
+660f5b11|223344556677885f5f5f5f5f	64	intel	cvtps2dq xmm2, xmmword ptr [rcx]
+660f5b11|223344556677885f5f5f5f5f	64	plan9	CVTPS2DQ 0(CX), X2
+660f5c11|223344556677885f5f5f5f5f	32	intel	subpd xmm2, xmmword ptr [ecx]
+660f5c11|223344556677885f5f5f5f5f	32	plan9	SUBPD 0(CX), X2
+660f5c11|223344556677885f5f5f5f5f	64	gnu	subpd (%rcx),%xmm2
+660f5c11|223344556677885f5f5f5f5f	64	intel	subpd xmm2, xmmword ptr [rcx]
+660f5c11|223344556677885f5f5f5f5f	64	plan9	SUBPD 0(CX), X2
+660f5d11|223344556677885f5f5f5f5f	32	intel	minpd xmm2, xmmword ptr [ecx]
+660f5d11|223344556677885f5f5f5f5f	32	plan9	MINPD 0(CX), X2
+660f5d11|223344556677885f5f5f5f5f	64	gnu	minpd (%rcx),%xmm2
+660f5d11|223344556677885f5f5f5f5f	64	intel	minpd xmm2, xmmword ptr [rcx]
+660f5d11|223344556677885f5f5f5f5f	64	plan9	MINPD 0(CX), X2
+660f5e11|223344556677885f5f5f5f5f	32	intel	divpd xmm2, xmmword ptr [ecx]
+660f5e11|223344556677885f5f5f5f5f	32	plan9	DIVPD 0(CX), X2
+660f5e11|223344556677885f5f5f5f5f	64	gnu	divpd (%rcx),%xmm2
+660f5e11|223344556677885f5f5f5f5f	64	intel	divpd xmm2, xmmword ptr [rcx]
+660f5e11|223344556677885f5f5f5f5f	64	plan9	DIVPD 0(CX), X2
+660f5f11|223344556677885f5f5f5f5f	32	intel	maxpd xmm2, xmmword ptr [ecx]
+660f5f11|223344556677885f5f5f5f5f	32	plan9	MAXPD 0(CX), X2
+660f5f11|223344556677885f5f5f5f5f	64	gnu	maxpd (%rcx),%xmm2
+660f5f11|223344556677885f5f5f5f5f	64	intel	maxpd xmm2, xmmword ptr [rcx]
+660f5f11|223344556677885f5f5f5f5f	64	plan9	MAXPD 0(CX), X2
+660f6011|223344556677885f5f5f5f5f	32	intel	punpcklbw xmm2, xmmword ptr [ecx]
+660f6011|223344556677885f5f5f5f5f	32	plan9	PUNPCKLBW 0(CX), X2
+660f6011|223344556677885f5f5f5f5f	64	gnu	punpcklbw (%rcx),%xmm2
+660f6011|223344556677885f5f5f5f5f	64	intel	punpcklbw xmm2, xmmword ptr [rcx]
+660f6011|223344556677885f5f5f5f5f	64	plan9	PUNPCKLBW 0(CX), X2
+660f6111|223344556677885f5f5f5f5f	32	intel	punpcklwd xmm2, xmmword ptr [ecx]
+660f6111|223344556677885f5f5f5f5f	32	plan9	PUNPCKLWD 0(CX), X2
+660f6111|223344556677885f5f5f5f5f	64	gnu	punpcklwd (%rcx),%xmm2
+660f6111|223344556677885f5f5f5f5f	64	intel	punpcklwd xmm2, xmmword ptr [rcx]
+660f6111|223344556677885f5f5f5f5f	64	plan9	PUNPCKLWD 0(CX), X2
+660f6211|223344556677885f5f5f5f5f	32	intel	punpckldq xmm2, xmmword ptr [ecx]
+660f6211|223344556677885f5f5f5f5f	32	plan9	PUNPCKLDQ 0(CX), X2
+660f6211|223344556677885f5f5f5f5f	64	gnu	punpckldq (%rcx),%xmm2
+660f6211|223344556677885f5f5f5f5f	64	intel	punpckldq xmm2, xmmword ptr [rcx]
+660f6211|223344556677885f5f5f5f5f	64	plan9	PUNPCKLDQ 0(CX), X2
+660f6311|223344556677885f5f5f5f5f	32	intel	packsswb xmm2, xmmword ptr [ecx]
+660f6311|223344556677885f5f5f5f5f	32	plan9	PACKSSWB 0(CX), X2
+660f6311|223344556677885f5f5f5f5f	64	gnu	packsswb (%rcx),%xmm2
+660f6311|223344556677885f5f5f5f5f	64	intel	packsswb xmm2, xmmword ptr [rcx]
+660f6311|223344556677885f5f5f5f5f	64	plan9	PACKSSWB 0(CX), X2
+660f6411|223344556677885f5f5f5f5f	32	intel	pcmpgtb xmm2, xmmword ptr [ecx]
+660f6411|223344556677885f5f5f5f5f	32	plan9	PCMPGTB 0(CX), X2
+660f6411|223344556677885f5f5f5f5f	64	gnu	pcmpgtb (%rcx),%xmm2
+660f6411|223344556677885f5f5f5f5f	64	intel	pcmpgtb xmm2, xmmword ptr [rcx]
+660f6411|223344556677885f5f5f5f5f	64	plan9	PCMPGTB 0(CX), X2
+660f6511|223344556677885f5f5f5f5f	32	intel	pcmpgtw xmm2, xmmword ptr [ecx]
+660f6511|223344556677885f5f5f5f5f	32	plan9	PCMPGTW 0(CX), X2
+660f6511|223344556677885f5f5f5f5f	64	gnu	pcmpgtw (%rcx),%xmm2
+660f6511|223344556677885f5f5f5f5f	64	intel	pcmpgtw xmm2, xmmword ptr [rcx]
+660f6511|223344556677885f5f5f5f5f	64	plan9	PCMPGTW 0(CX), X2
+660f6611|223344556677885f5f5f5f5f	32	intel	pcmpgtd xmm2, xmmword ptr [ecx]
+660f6611|223344556677885f5f5f5f5f	32	plan9	PCMPGTD 0(CX), X2
+660f6611|223344556677885f5f5f5f5f	64	gnu	pcmpgtd (%rcx),%xmm2
+660f6611|223344556677885f5f5f5f5f	64	intel	pcmpgtd xmm2, xmmword ptr [rcx]
+660f6611|223344556677885f5f5f5f5f	64	plan9	PCMPGTD 0(CX), X2
+660f6711|223344556677885f5f5f5f5f	32	intel	packuswb xmm2, xmmword ptr [ecx]
+660f6711|223344556677885f5f5f5f5f	32	plan9	PACKUSWB 0(CX), X2
+660f6711|223344556677885f5f5f5f5f	64	gnu	packuswb (%rcx),%xmm2
+660f6711|223344556677885f5f5f5f5f	64	intel	packuswb xmm2, xmmword ptr [rcx]
+660f6711|223344556677885f5f5f5f5f	64	plan9	PACKUSWB 0(CX), X2
+660f6811|223344556677885f5f5f5f5f	32	intel	punpckhbw xmm2, xmmword ptr [ecx]
+660f6811|223344556677885f5f5f5f5f	32	plan9	PUNPCKHBW 0(CX), X2
+660f6811|223344556677885f5f5f5f5f	64	gnu	punpckhbw (%rcx),%xmm2
+660f6811|223344556677885f5f5f5f5f	64	intel	punpckhbw xmm2, xmmword ptr [rcx]
+660f6811|223344556677885f5f5f5f5f	64	plan9	PUNPCKHBW 0(CX), X2
+660f6911|223344556677885f5f5f5f5f	32	intel	punpckhwd xmm2, xmmword ptr [ecx]
+660f6911|223344556677885f5f5f5f5f	32	plan9	PUNPCKHWD 0(CX), X2
+660f6911|223344556677885f5f5f5f5f	64	gnu	punpckhwd (%rcx),%xmm2
+660f6911|223344556677885f5f5f5f5f	64	intel	punpckhwd xmm2, xmmword ptr [rcx]
+660f6911|223344556677885f5f5f5f5f	64	plan9	PUNPCKHWD 0(CX), X2
+660f6a11|223344556677885f5f5f5f5f	32	intel	punpckhdq xmm2, xmmword ptr [ecx]
+660f6a11|223344556677885f5f5f5f5f	32	plan9	PUNPCKHDQ 0(CX), X2
+660f6a11|223344556677885f5f5f5f5f	64	gnu	punpckhdq (%rcx),%xmm2
+660f6a11|223344556677885f5f5f5f5f	64	intel	punpckhdq xmm2, xmmword ptr [rcx]
+660f6a11|223344556677885f5f5f5f5f	64	plan9	PUNPCKHDQ 0(CX), X2
+660f6b11|223344556677885f5f5f5f5f	32	intel	packssdw xmm2, xmmword ptr [ecx]
+660f6b11|223344556677885f5f5f5f5f	32	plan9	PACKSSDW 0(CX), X2
+660f6b11|223344556677885f5f5f5f5f	64	gnu	packssdw (%rcx),%xmm2
+660f6b11|223344556677885f5f5f5f5f	64	intel	packssdw xmm2, xmmword ptr [rcx]
+660f6b11|223344556677885f5f5f5f5f	64	plan9	PACKSSDW 0(CX), X2
+660f6c11|223344556677885f5f5f5f5f	32	intel	punpcklqdq xmm2, xmmword ptr [ecx]
+660f6c11|223344556677885f5f5f5f5f	32	plan9	PUNPCKLQDQ 0(CX), X2
+660f6c11|223344556677885f5f5f5f5f	64	gnu	punpcklqdq (%rcx),%xmm2
+660f6c11|223344556677885f5f5f5f5f	64	intel	punpcklqdq xmm2, xmmword ptr [rcx]
+660f6c11|223344556677885f5f5f5f5f	64	plan9	PUNPCKLQDQ 0(CX), X2
+660f6d11|223344556677885f5f5f5f5f	32	intel	punpckhqdq xmm2, xmmword ptr [ecx]
+660f6d11|223344556677885f5f5f5f5f	32	plan9	PUNPCKHQDQ 0(CX), X2
+660f6d11|223344556677885f5f5f5f5f	64	gnu	punpckhqdq (%rcx),%xmm2
+660f6d11|223344556677885f5f5f5f5f	64	intel	punpckhqdq xmm2, xmmword ptr [rcx]
+660f6d11|223344556677885f5f5f5f5f	64	plan9	PUNPCKHQDQ 0(CX), X2
+660f6e11|223344556677885f5f5f5f5f	32	intel	movd xmm2, dword ptr [ecx]
+660f6e11|223344556677885f5f5f5f5f	32	plan9	MOVD 0(CX), X2
+660f6e11|223344556677885f5f5f5f5f	64	gnu	movd (%rcx),%xmm2
+660f6e11|223344556677885f5f5f5f5f	64	intel	movd xmm2, dword ptr [rcx]
+660f6e11|223344556677885f5f5f5f5f	64	plan9	MOVD 0(CX), X2
+660f6f11|223344556677885f5f5f5f5f	32	intel	movdqa xmm2, xmmword ptr [ecx]
+660f6f11|223344556677885f5f5f5f5f	32	plan9	MOVDQA 0(CX), X2
+660f6f11|223344556677885f5f5f5f5f	64	gnu	movdqa (%rcx),%xmm2
+660f6f11|223344556677885f5f5f5f5f	64	intel	movdqa xmm2, xmmword ptr [rcx]
+660f6f11|223344556677885f5f5f5f5f	64	plan9	MOVDQA 0(CX), X2
+660f701122|3344556677885f5f5f5f5f	32	intel	pshufd xmm2, xmmword ptr [ecx], 0x22
+660f701122|3344556677885f5f5f5f5f	32	plan9	PSHUFD $0x22, 0(CX), X2
+660f701122|3344556677885f5f5f5f5f	64	gnu	pshufd $0x22,(%rcx),%xmm2
+660f701122|3344556677885f5f5f5f5f	64	intel	pshufd xmm2, xmmword ptr [rcx], 0x22
+660f701122|3344556677885f5f5f5f5f	64	plan9	PSHUFD $0x22, 0(CX), X2
+660f71d011|223344556677885f5f5f5f	32	intel	psrlw xmm0, 0x11
+660f71d011|223344556677885f5f5f5f	32	plan9	PSRLW $0x11, X0
+660f71d011|223344556677885f5f5f5f	64	gnu	psrlw $0x11,%xmm0
+660f71d011|223344556677885f5f5f5f	64	intel	psrlw xmm0, 0x11
+660f71d011|223344556677885f5f5f5f	64	plan9	PSRLW $0x11, X0
+660f71e011|223344556677885f5f5f5f	32	intel	psraw xmm0, 0x11
+660f71e011|223344556677885f5f5f5f	32	plan9	PSRAW $0x11, X0
+660f71e011|223344556677885f5f5f5f	64	gnu	psraw $0x11,%xmm0
+660f71e011|223344556677885f5f5f5f	64	intel	psraw xmm0, 0x11
+660f71e011|223344556677885f5f5f5f	64	plan9	PSRAW $0x11, X0
+660f71f011|223344556677885f5f5f5f	32	intel	psllw xmm0, 0x11
+660f71f011|223344556677885f5f5f5f	32	plan9	PSLLW $0x11, X0
+660f71f011|223344556677885f5f5f5f	64	gnu	psllw $0x11,%xmm0
+660f71f011|223344556677885f5f5f5f	64	intel	psllw xmm0, 0x11
+660f71f011|223344556677885f5f5f5f	64	plan9	PSLLW $0x11, X0
+660f72d011|223344556677885f5f5f5f	32	intel	psrld xmm0, 0x11
+660f72d011|223344556677885f5f5f5f	32	plan9	PSRLD $0x11, X0
+660f72d011|223344556677885f5f5f5f	64	gnu	psrld $0x11,%xmm0
+660f72d011|223344556677885f5f5f5f	64	intel	psrld xmm0, 0x11
+660f72d011|223344556677885f5f5f5f	64	plan9	PSRLD $0x11, X0
+660f72e011|223344556677885f5f5f5f	32	intel	psrad xmm0, 0x11
+660f72e011|223344556677885f5f5f5f	32	plan9	PSRAD $0x11, X0
+660f72e011|223344556677885f5f5f5f	64	gnu	psrad $0x11,%xmm0
+660f72e011|223344556677885f5f5f5f	64	intel	psrad xmm0, 0x11
+660f72e011|223344556677885f5f5f5f	64	plan9	PSRAD $0x11, X0
+660f72f011|223344556677885f5f5f5f	32	intel	pslld xmm0, 0x11
+660f72f011|223344556677885f5f5f5f	32	plan9	PSLLD $0x11, X0
+660f72f011|223344556677885f5f5f5f	64	gnu	pslld $0x11,%xmm0
+660f72f011|223344556677885f5f5f5f	64	intel	pslld xmm0, 0x11
+660f72f011|223344556677885f5f5f5f	64	plan9	PSLLD $0x11, X0
+660f73d011|223344556677885f5f5f5f	32	intel	psrlq xmm0, 0x11
+660f73d011|223344556677885f5f5f5f	32	plan9	PSRLQ $0x11, X0
+660f73d011|223344556677885f5f5f5f	64	gnu	psrlq $0x11,%xmm0
+660f73d011|223344556677885f5f5f5f	64	intel	psrlq xmm0, 0x11
+660f73d011|223344556677885f5f5f5f	64	plan9	PSRLQ $0x11, X0
+660f73d811|223344556677885f5f5f5f	32	intel	psrldq xmm0, 0x11
+660f73d811|223344556677885f5f5f5f	32	plan9	PSRLDQ $0x11, X0
+660f73d811|223344556677885f5f5f5f	64	gnu	psrldq $0x11,%xmm0
+660f73d811|223344556677885f5f5f5f	64	intel	psrldq xmm0, 0x11
+660f73d811|223344556677885f5f5f5f	64	plan9	PSRLDQ $0x11, X0
+660f73f011|223344556677885f5f5f5f	32	intel	psllq xmm0, 0x11
+660f73f011|223344556677885f5f5f5f	32	plan9	PSLLQ $0x11, X0
+660f73f011|223344556677885f5f5f5f	64	gnu	psllq $0x11,%xmm0
+660f73f011|223344556677885f5f5f5f	64	intel	psllq xmm0, 0x11
+660f73f011|223344556677885f5f5f5f	64	plan9	PSLLQ $0x11, X0
+660f73f811|223344556677885f5f5f5f	32	intel	pslldq xmm0, 0x11
+660f73f811|223344556677885f5f5f5f	32	plan9	PSLLDQ $0x11, X0
+660f73f811|223344556677885f5f5f5f	64	gnu	pslldq $0x11,%xmm0
+660f73f811|223344556677885f5f5f5f	64	intel	pslldq xmm0, 0x11
+660f73f811|223344556677885f5f5f5f	64	plan9	PSLLDQ $0x11, X0
+660f7411|223344556677885f5f5f5f5f	32	intel	pcmpeqb xmm2, xmmword ptr [ecx]
+660f7411|223344556677885f5f5f5f5f	32	plan9	PCMPEQB 0(CX), X2
+660f7411|223344556677885f5f5f5f5f	64	gnu	pcmpeqb (%rcx),%xmm2
+660f7411|223344556677885f5f5f5f5f	64	intel	pcmpeqb xmm2, xmmword ptr [rcx]
+660f7411|223344556677885f5f5f5f5f	64	plan9	PCMPEQB 0(CX), X2
+660f7511|223344556677885f5f5f5f5f	32	intel	pcmpeqw xmm2, xmmword ptr [ecx]
+660f7511|223344556677885f5f5f5f5f	32	plan9	PCMPEQW 0(CX), X2
+660f7511|223344556677885f5f5f5f5f	64	gnu	pcmpeqw (%rcx),%xmm2
+660f7511|223344556677885f5f5f5f5f	64	intel	pcmpeqw xmm2, xmmword ptr [rcx]
+660f7511|223344556677885f5f5f5f5f	64	plan9	PCMPEQW 0(CX), X2
+660f7611|223344556677885f5f5f5f5f	32	intel	pcmpeqd xmm2, xmmword ptr [ecx]
+660f7611|223344556677885f5f5f5f5f	32	plan9	PCMPEQD 0(CX), X2
+660f7611|223344556677885f5f5f5f5f	64	gnu	pcmpeqd (%rcx),%xmm2
+660f7611|223344556677885f5f5f5f5f	64	intel	pcmpeqd xmm2, xmmword ptr [rcx]
+660f7611|223344556677885f5f5f5f5f	64	plan9	PCMPEQD 0(CX), X2
+660f7c11|223344556677885f5f5f5f5f	32	intel	haddpd xmm2, xmmword ptr [ecx]
+660f7c11|223344556677885f5f5f5f5f	32	plan9	HADDPD 0(CX), X2
+660f7c11|223344556677885f5f5f5f5f	64	gnu	haddpd (%rcx),%xmm2
+660f7c11|223344556677885f5f5f5f5f	64	intel	haddpd xmm2, xmmword ptr [rcx]
+660f7c11|223344556677885f5f5f5f5f	64	plan9	HADDPD 0(CX), X2
+660f7d11|223344556677885f5f5f5f5f	32	intel	hsubpd xmm2, xmmword ptr [ecx]
+660f7d11|223344556677885f5f5f5f5f	32	plan9	HSUBPD 0(CX), X2
+660f7d11|223344556677885f5f5f5f5f	64	gnu	hsubpd (%rcx),%xmm2
+660f7d11|223344556677885f5f5f5f5f	64	intel	hsubpd xmm2, xmmword ptr [rcx]
+660f7d11|223344556677885f5f5f5f5f	64	plan9	HSUBPD 0(CX), X2
+660f7e11|223344556677885f5f5f5f5f	32	intel	movd dword ptr [ecx], xmm2
+660f7e11|223344556677885f5f5f5f5f	32	plan9	MOVD X2, 0(CX)
+660f7e11|223344556677885f5f5f5f5f	64	gnu	movd %xmm2,(%rcx)
+660f7e11|223344556677885f5f5f5f5f	64	intel	movd dword ptr [rcx], xmm2
+660f7e11|223344556677885f5f5f5f5f	64	plan9	MOVD X2, 0(CX)
+660f7f11|223344556677885f5f5f5f5f	32	intel	movdqa xmmword ptr [ecx], xmm2
+660f7f11|223344556677885f5f5f5f5f	32	plan9	MOVDQA X2, 0(CX)
+660f7f11|223344556677885f5f5f5f5f	64	gnu	movdqa %xmm2,(%rcx)
+660f7f11|223344556677885f5f5f5f5f	64	intel	movdqa xmmword ptr [rcx], xmm2
+660f7f11|223344556677885f5f5f5f5f	64	plan9	MOVDQA X2, 0(CX)
+660f8011223344|556677885f5f5f5f5f	64	gnu	jo .+0x44332211
+660f8011223344|556677885f5f5f5f5f	64	intel	jo .+0x44332211
+660f8011223344|556677885f5f5f5f5f	64	plan9	JO .+1144201745
+660f801122|3344556677885f5f5f5f5f	32	intel	jo .+0x2211
+660f801122|3344556677885f5f5f5f5f	32	plan9	JO .+8721
+660f8111223344|556677885f5f5f5f5f	64	gnu	jno .+0x44332211
+660f8111223344|556677885f5f5f5f5f	64	intel	jno .+0x44332211
+660f8111223344|556677885f5f5f5f5f	64	plan9	JNO .+1144201745
+660f811122|3344556677885f5f5f5f5f	32	intel	jno .+0x2211
+660f811122|3344556677885f5f5f5f5f	32	plan9	JNO .+8721
+660f8211223344|556677885f5f5f5f5f	64	gnu	jb .+0x44332211
+660f8211223344|556677885f5f5f5f5f	64	intel	jb .+0x44332211
+660f8211223344|556677885f5f5f5f5f	64	plan9	JB .+1144201745
+660f821122|3344556677885f5f5f5f5f	32	intel	jb .+0x2211
+660f821122|3344556677885f5f5f5f5f	32	plan9	JB .+8721
+660f8311223344|556677885f5f5f5f5f	64	gnu	jae .+0x44332211
+660f8311223344|556677885f5f5f5f5f	64	intel	jnb .+0x44332211
+660f8311223344|556677885f5f5f5f5f	64	plan9	JAE .+1144201745
+660f831122|3344556677885f5f5f5f5f	32	intel	jnb .+0x2211
+660f831122|3344556677885f5f5f5f5f	32	plan9	JAE .+8721
+660f8411223344|556677885f5f5f5f5f	64	gnu	je .+0x44332211
+660f8411223344|556677885f5f5f5f5f	64	intel	jz .+0x44332211
+660f8411223344|556677885f5f5f5f5f	64	plan9	JE .+1144201745
+660f841122|3344556677885f5f5f5f5f	32	intel	jz .+0x2211
+660f841122|3344556677885f5f5f5f5f	32	plan9	JE .+8721
+660f8511223344|556677885f5f5f5f5f	64	gnu	jne .+0x44332211
+660f8511223344|556677885f5f5f5f5f	64	intel	jnz .+0x44332211
+660f8511223344|556677885f5f5f5f5f	64	plan9	JNE .+1144201745
+660f851122|3344556677885f5f5f5f5f	32	intel	jnz .+0x2211
+660f851122|3344556677885f5f5f5f5f	32	plan9	JNE .+8721
+660f8611223344|556677885f5f5f5f5f	64	gnu	jbe .+0x44332211
+660f8611223344|556677885f5f5f5f5f	64	intel	jbe .+0x44332211
+660f8611223344|556677885f5f5f5f5f	64	plan9	JBE .+1144201745
+660f861122|3344556677885f5f5f5f5f	32	intel	jbe .+0x2211
+660f861122|3344556677885f5f5f5f5f	32	plan9	JBE .+8721
+660f8711223344|556677885f5f5f5f5f	64	gnu	ja .+0x44332211
+660f8711223344|556677885f5f5f5f5f	64	intel	jnbe .+0x44332211
+660f8711223344|556677885f5f5f5f5f	64	plan9	JA .+1144201745
+660f871122|3344556677885f5f5f5f5f	32	intel	jnbe .+0x2211
+660f871122|3344556677885f5f5f5f5f	32	plan9	JA .+8721
+660f8811223344|556677885f5f5f5f5f	64	gnu	js .+0x44332211
+660f8811223344|556677885f5f5f5f5f	64	intel	js .+0x44332211
+660f8811223344|556677885f5f5f5f5f	64	plan9	JS .+1144201745
+660f881122|3344556677885f5f5f5f5f	32	intel	js .+0x2211
+660f881122|3344556677885f5f5f5f5f	32	plan9	JS .+8721
+660f8911223344|556677885f5f5f5f5f	64	gnu	jns .+0x44332211
+660f8911223344|556677885f5f5f5f5f	64	intel	jns .+0x44332211
+660f8911223344|556677885f5f5f5f5f	64	plan9	JNS .+1144201745
+660f891122|3344556677885f5f5f5f5f	32	intel	jns .+0x2211
+660f891122|3344556677885f5f5f5f5f	32	plan9	JNS .+8721
+660f8a11223344|556677885f5f5f5f5f	64	gnu	jp .+0x44332211
+660f8a11223344|556677885f5f5f5f5f	64	intel	jp .+0x44332211
+660f8a11223344|556677885f5f5f5f5f	64	plan9	JP .+1144201745
+660f8a1122|3344556677885f5f5f5f5f	32	intel	jp .+0x2211
+660f8a1122|3344556677885f5f5f5f5f	32	plan9	JP .+8721
+660f8b11223344|556677885f5f5f5f5f	64	gnu	jnp .+0x44332211
+660f8b11223344|556677885f5f5f5f5f	64	intel	jnp .+0x44332211
+660f8b11223344|556677885f5f5f5f5f	64	plan9	JNP .+1144201745
+660f8b1122|3344556677885f5f5f5f5f	32	intel	jnp .+0x2211
+660f8b1122|3344556677885f5f5f5f5f	32	plan9	JNP .+8721
+660f8c11223344|556677885f5f5f5f5f	64	gnu	jl .+0x44332211
+660f8c11223344|556677885f5f5f5f5f	64	intel	jl .+0x44332211
+660f8c11223344|556677885f5f5f5f5f	64	plan9	JL .+1144201745
+660f8c1122|3344556677885f5f5f5f5f	32	intel	jl .+0x2211
+660f8c1122|3344556677885f5f5f5f5f	32	plan9	JL .+8721
+660f8d11223344|556677885f5f5f5f5f	64	gnu	jge .+0x44332211
+660f8d11223344|556677885f5f5f5f5f	64	intel	jnl .+0x44332211
+660f8d11223344|556677885f5f5f5f5f	64	plan9	JGE .+1144201745
+660f8d1122|3344556677885f5f5f5f5f	32	intel	jnl .+0x2211
+660f8d1122|3344556677885f5f5f5f5f	32	plan9	JGE .+8721
+660f8e11223344|556677885f5f5f5f5f	64	gnu	jle .+0x44332211
+660f8e11223344|556677885f5f5f5f5f	64	intel	jle .+0x44332211
+660f8e11223344|556677885f5f5f5f5f	64	plan9	JLE .+1144201745
+660f8e1122|3344556677885f5f5f5f5f	32	intel	jle .+0x2211
+660f8e1122|3344556677885f5f5f5f5f	32	plan9	JLE .+8721
+660f8f11223344|556677885f5f5f5f5f	64	gnu	jg .+0x44332211
+660f8f11223344|556677885f5f5f5f5f	64	intel	jnle .+0x44332211
+660f8f11223344|556677885f5f5f5f5f	64	plan9	JG .+1144201745
+660f8f1122|3344556677885f5f5f5f5f	32	intel	jnle .+0x2211
+660f8f1122|3344556677885f5f5f5f5f	32	plan9	JG .+8721
+660fa1|11223344556677885f5f5f5f5f	32	intel	pop fs
+660fa1|11223344556677885f5f5f5f5f	32	plan9	POPW FS
+660fa1|11223344556677885f5f5f5f5f	64	gnu	popw %fs
+660fa1|11223344556677885f5f5f5f5f	64	intel	pop fs
+660fa1|11223344556677885f5f5f5f5f	64	plan9	POPW FS
+660fa311|223344556677885f5f5f5f5f	32	intel	bt word ptr [ecx], dx
+660fa311|223344556677885f5f5f5f5f	32	plan9	BTW DX, 0(CX)
+660fa311|223344556677885f5f5f5f5f	64	gnu	bt %dx,(%rcx)
+660fa311|223344556677885f5f5f5f5f	64	intel	bt word ptr [rcx], dx
+660fa311|223344556677885f5f5f5f5f	64	plan9	BTW DX, 0(CX)
+660fa41122|3344556677885f5f5f5f5f	32	intel	shld word ptr [ecx], dx, 0x22
+660fa41122|3344556677885f5f5f5f5f	32	plan9	SHLDW $0x22, DX, 0(CX)
+660fa41122|3344556677885f5f5f5f5f	64	gnu	shld $0x22,%dx,(%rcx)
+660fa41122|3344556677885f5f5f5f5f	64	intel	shld word ptr [rcx], dx, 0x22
+660fa41122|3344556677885f5f5f5f5f	64	plan9	SHLDW $0x22, DX, 0(CX)
+660fa511|223344556677885f5f5f5f5f	32	intel	shld word ptr [ecx], dx, cl
+660fa511|223344556677885f5f5f5f5f	32	plan9	SHLDW CL, DX, 0(CX)
+660fa511|223344556677885f5f5f5f5f	64	gnu	shld %cl,%dx,(%rcx)
+660fa511|223344556677885f5f5f5f5f	64	intel	shld word ptr [rcx], dx, cl
+660fa511|223344556677885f5f5f5f5f	64	plan9	SHLDW CL, DX, 0(CX)
+660fa9|11223344556677885f5f5f5f5f	32	intel	pop gs
+660fa9|11223344556677885f5f5f5f5f	32	plan9	POPW GS
+660fa9|11223344556677885f5f5f5f5f	64	gnu	popw %gs
+660fa9|11223344556677885f5f5f5f5f	64	intel	pop gs
+660fa9|11223344556677885f5f5f5f5f	64	plan9	POPW GS
+660fab11|223344556677885f5f5f5f5f	32	intel	bts word ptr [ecx], dx
+660fab11|223344556677885f5f5f5f5f	32	plan9	BTSW DX, 0(CX)
+660fab11|223344556677885f5f5f5f5f	64	gnu	bts %dx,(%rcx)
+660fab11|223344556677885f5f5f5f5f	64	intel	bts word ptr [rcx], dx
+660fab11|223344556677885f5f5f5f5f	64	plan9	BTSW DX, 0(CX)
+660fac1122|3344556677885f5f5f5f5f	32	intel	shrd word ptr [ecx], dx, 0x22
+660fac1122|3344556677885f5f5f5f5f	32	plan9	SHRDW $0x22, DX, 0(CX)
+660fac1122|3344556677885f5f5f5f5f	64	gnu	shrd $0x22,%dx,(%rcx)
+660fac1122|3344556677885f5f5f5f5f	64	intel	shrd word ptr [rcx], dx, 0x22
+660fac1122|3344556677885f5f5f5f5f	64	plan9	SHRDW $0x22, DX, 0(CX)
+660fad11|223344556677885f5f5f5f5f	32	intel	shrd word ptr [ecx], dx, cl
+660fad11|223344556677885f5f5f5f5f	32	plan9	SHRDW CL, DX, 0(CX)
+660fad11|223344556677885f5f5f5f5f	64	gnu	shrd %cl,%dx,(%rcx)
+660fad11|223344556677885f5f5f5f5f	64	intel	shrd word ptr [rcx], dx, cl
+660fad11|223344556677885f5f5f5f5f	64	plan9	SHRDW CL, DX, 0(CX)
+660fae00|11223344556677885f5f5f5f	32	intel	fxsave ptr [eax]
+660fae00|11223344556677885f5f5f5f	32	plan9	FXSAVE 0(AX)
+660fae00|11223344556677885f5f5f5f	64	gnu	fxsave (%rax)
+660fae00|11223344556677885f5f5f5f	64	intel	fxsave ptr [rax]
+660fae00|11223344556677885f5f5f5f	64	plan9	FXSAVE 0(AX)
+660fae08|11223344556677885f5f5f5f	32	intel	fxrstor ptr [eax]
+660fae08|11223344556677885f5f5f5f	32	plan9	FXRSTOR 0(AX)
+660fae08|11223344556677885f5f5f5f	64	gnu	data16 fxrstor (%rax)
+660fae08|11223344556677885f5f5f5f	64	intel	fxrstor ptr [rax]
+660fae08|11223344556677885f5f5f5f	64	plan9	FXRSTOR 0(AX)
+660fae20|11223344556677885f5f5f5f	32	intel	xsave ptr [eax]
+660fae20|11223344556677885f5f5f5f	32	plan9	XSAVE 0(AX)
+660fae20|11223344556677885f5f5f5f	64	gnu	data16 xsave (%rax)
+660fae20|11223344556677885f5f5f5f	64	intel	xsave ptr [rax]
+660fae20|11223344556677885f5f5f5f	64	plan9	XSAVE 0(AX)
+660fae28|11223344556677885f5f5f5f	32	intel	xrstor ptr [eax]
+660fae28|11223344556677885f5f5f5f	32	plan9	XRSTOR 0(AX)
+660fae28|11223344556677885f5f5f5f	64	gnu	data16 xrstor (%rax)
+660fae28|11223344556677885f5f5f5f	64	intel	xrstor ptr [rax]
+660fae28|11223344556677885f5f5f5f	64	plan9	XRSTOR 0(AX)
+660fae30|11223344556677885f5f5f5f	32	intel	xsaveopt ptr [eax]
+660fae30|11223344556677885f5f5f5f	32	plan9	XSAVEOPT 0(AX)
+660fae30|11223344556677885f5f5f5f	64	gnu	data16 xsaveopt (%rax)
+660fae30|11223344556677885f5f5f5f	64	intel	xsaveopt ptr [rax]
+660fae30|11223344556677885f5f5f5f	64	plan9	XSAVEOPT 0(AX)
+660faf11|223344556677885f5f5f5f5f	32	intel	imul dx, word ptr [ecx]
+660faf11|223344556677885f5f5f5f5f	32	plan9	IMULW 0(CX), DX
+660faf11|223344556677885f5f5f5f5f	64	gnu	imul (%rcx),%dx
+660faf11|223344556677885f5f5f5f5f	64	intel	imul dx, word ptr [rcx]
+660faf11|223344556677885f5f5f5f5f	64	plan9	IMULW 0(CX), DX
+660fb111|223344556677885f5f5f5f5f	32	intel	cmpxchg word ptr [ecx], dx
+660fb111|223344556677885f5f5f5f5f	32	plan9	CMPXCHGW DX, 0(CX)
+660fb111|223344556677885f5f5f5f5f	64	gnu	cmpxchg %dx,(%rcx)
+660fb111|223344556677885f5f5f5f5f	64	intel	cmpxchg word ptr [rcx], dx
+660fb111|223344556677885f5f5f5f5f	64	plan9	CMPXCHGW DX, 0(CX)
+660fb211|223344556677885f5f5f5f5f	32	intel	lss dx, dword ptr [ecx]
+660fb211|223344556677885f5f5f5f5f	32	plan9	LSS 0(CX), DX
+660fb211|223344556677885f5f5f5f5f	64	gnu	lss (%rcx),%dx
+660fb211|223344556677885f5f5f5f5f	64	intel	lss dx, dword ptr [rcx]
+660fb211|223344556677885f5f5f5f5f	64	plan9	LSS 0(CX), DX
+660fb311|223344556677885f5f5f5f5f	32	intel	btr word ptr [ecx], dx
+660fb311|223344556677885f5f5f5f5f	32	plan9	BTRW DX, 0(CX)
+660fb311|223344556677885f5f5f5f5f	64	gnu	btr %dx,(%rcx)
+660fb311|223344556677885f5f5f5f5f	64	intel	btr word ptr [rcx], dx
+660fb311|223344556677885f5f5f5f5f	64	plan9	BTRW DX, 0(CX)
+660fb411|223344556677885f5f5f5f5f	32	intel	lfs dx, dword ptr [ecx]
+660fb411|223344556677885f5f5f5f5f	32	plan9	LFS 0(CX), DX
+660fb411|223344556677885f5f5f5f5f	64	gnu	lfs (%rcx),%dx
+660fb411|223344556677885f5f5f5f5f	64	intel	lfs dx, dword ptr [rcx]
+660fb411|223344556677885f5f5f5f5f	64	plan9	LFS 0(CX), DX
+660fb511|223344556677885f5f5f5f5f	32	intel	lgs dx, dword ptr [ecx]
+660fb511|223344556677885f5f5f5f5f	32	plan9	LGS 0(CX), DX
+660fb511|223344556677885f5f5f5f5f	64	gnu	lgs (%rcx),%dx
+660fb511|223344556677885f5f5f5f5f	64	intel	lgs dx, dword ptr [rcx]
+660fb511|223344556677885f5f5f5f5f	64	plan9	LGS 0(CX), DX
+660fb611|223344556677885f5f5f5f5f	32	intel	movzx dx, byte ptr [ecx]
+660fb611|223344556677885f5f5f5f5f	32	plan9	MOVZX 0(CX), DX
+660fb611|223344556677885f5f5f5f5f	64	gnu	movzbw (%rcx),%dx
+660fb611|223344556677885f5f5f5f5f	64	intel	movzx dx, byte ptr [rcx]
+660fb611|223344556677885f5f5f5f5f	64	plan9	MOVZX 0(CX), DX
+660fb711|223344556677885f5f5f5f5f	32	intel	movzx dx, word ptr [ecx]
+660fb711|223344556677885f5f5f5f5f	32	plan9	MOVZX 0(CX), DX
+660fb711|223344556677885f5f5f5f5f	64	gnu	movzww (%rcx),%dx
+660fb711|223344556677885f5f5f5f5f	64	intel	movzx dx, word ptr [rcx]
+660fb711|223344556677885f5f5f5f5f	64	plan9	MOVZX 0(CX), DX
+660fba2011|223344556677885f5f5f5f	32	intel	bt word ptr [eax], 0x11
+660fba2011|223344556677885f5f5f5f	32	plan9	BTW $0x11, 0(AX)
+660fba2011|223344556677885f5f5f5f	64	gnu	btw $0x11,(%rax)
+660fba2011|223344556677885f5f5f5f	64	intel	bt word ptr [rax], 0x11
+660fba2011|223344556677885f5f5f5f	64	plan9	BTW $0x11, 0(AX)
+660fba2811|223344556677885f5f5f5f	32	intel	bts word ptr [eax], 0x11
+660fba2811|223344556677885f5f5f5f	32	plan9	BTSW $0x11, 0(AX)
+660fba2811|223344556677885f5f5f5f	64	gnu	btsw $0x11,(%rax)
+660fba2811|223344556677885f5f5f5f	64	intel	bts word ptr [rax], 0x11
+660fba2811|223344556677885f5f5f5f	64	plan9	BTSW $0x11, 0(AX)
+660fba3011|223344556677885f5f5f5f	32	intel	btr word ptr [eax], 0x11
+660fba3011|223344556677885f5f5f5f	32	plan9	BTRW $0x11, 0(AX)
+660fba3011|223344556677885f5f5f5f	64	gnu	btrw $0x11,(%rax)
+660fba3011|223344556677885f5f5f5f	64	intel	btr word ptr [rax], 0x11
+660fba3011|223344556677885f5f5f5f	64	plan9	BTRW $0x11, 0(AX)
+660fba3811|223344556677885f5f5f5f	32	intel	btc word ptr [eax], 0x11
+660fba3811|223344556677885f5f5f5f	32	plan9	BTCW $0x11, 0(AX)
+660fba3811|223344556677885f5f5f5f	64	gnu	btcw $0x11,(%rax)
+660fba3811|223344556677885f5f5f5f	64	intel	btc word ptr [rax], 0x11
+660fba3811|223344556677885f5f5f5f	64	plan9	BTCW $0x11, 0(AX)
+660fbb11|223344556677885f5f5f5f5f	32	intel	btc word ptr [ecx], dx
+660fbb11|223344556677885f5f5f5f5f	32	plan9	BTCW DX, 0(CX)
+660fbb11|223344556677885f5f5f5f5f	64	gnu	btc %dx,(%rcx)
+660fbb11|223344556677885f5f5f5f5f	64	intel	btc word ptr [rcx], dx
+660fbb11|223344556677885f5f5f5f5f	64	plan9	BTCW DX, 0(CX)
+660fbc11|223344556677885f5f5f5f5f	32	intel	bsf dx, word ptr [ecx]
+660fbc11|223344556677885f5f5f5f5f	32	plan9	BSFW 0(CX), DX
+660fbc11|223344556677885f5f5f5f5f	64	gnu	bsf (%rcx),%dx
+660fbc11|223344556677885f5f5f5f5f	64	intel	bsf dx, word ptr [rcx]
+660fbc11|223344556677885f5f5f5f5f	64	plan9	BSFW 0(CX), DX
+660fbd11|223344556677885f5f5f5f5f	32	intel	bsr dx, word ptr [ecx]
+660fbd11|223344556677885f5f5f5f5f	32	plan9	BSRW 0(CX), DX
+660fbd11|223344556677885f5f5f5f5f	64	gnu	bsr (%rcx),%dx
+660fbd11|223344556677885f5f5f5f5f	64	intel	bsr dx, word ptr [rcx]
+660fbd11|223344556677885f5f5f5f5f	64	plan9	BSRW 0(CX), DX
+660fbe11|223344556677885f5f5f5f5f	32	intel	movsx dx, byte ptr [ecx]
+660fbe11|223344556677885f5f5f5f5f	32	plan9	MOVSX 0(CX), DX
+660fbe11|223344556677885f5f5f5f5f	64	gnu	movsbw (%rcx),%dx
+660fbe11|223344556677885f5f5f5f5f	64	intel	movsx dx, byte ptr [rcx]
+660fbe11|223344556677885f5f5f5f5f	64	plan9	MOVSX 0(CX), DX
+660fbf11|223344556677885f5f5f5f5f	32	intel	movsx dx, word ptr [ecx]
+660fbf11|223344556677885f5f5f5f5f	32	plan9	MOVSX 0(CX), DX
+660fbf11|223344556677885f5f5f5f5f	64	gnu	movsww (%rcx),%dx
+660fbf11|223344556677885f5f5f5f5f	64	intel	movsx dx, word ptr [rcx]
+660fbf11|223344556677885f5f5f5f5f	64	plan9	MOVSX 0(CX), DX
+660fc111|223344556677885f5f5f5f5f	32	intel	xadd word ptr [ecx], dx
+660fc111|223344556677885f5f5f5f5f	32	plan9	XADDW DX, 0(CX)
+660fc111|223344556677885f5f5f5f5f	64	gnu	xadd %dx,(%rcx)
+660fc111|223344556677885f5f5f5f5f	64	intel	xadd word ptr [rcx], dx
+660fc111|223344556677885f5f5f5f5f	64	plan9	XADDW DX, 0(CX)
+660fc21122|3344556677885f5f5f5f5f	32	intel	cmppd xmm2, xmmword ptr [ecx], 0x22
+660fc21122|3344556677885f5f5f5f5f	32	plan9	CMPPD $0x22, 0(CX), X2
+660fc21122|3344556677885f5f5f5f5f	64	gnu	cmppd $0x22,(%rcx),%xmm2
+660fc21122|3344556677885f5f5f5f5f	64	intel	cmppd xmm2, xmmword ptr [rcx], 0x22
+660fc21122|3344556677885f5f5f5f5f	64	plan9	CMPPD $0x22, 0(CX), X2
+660fc311|223344556677885f5f5f5f5f	32	intel	movnti dword ptr [ecx], edx
+660fc311|223344556677885f5f5f5f5f	32	plan9	MOVNTIW DX, 0(CX)
+660fc311|223344556677885f5f5f5f5f	64	gnu	movnti %edx,(%rcx)
+660fc311|223344556677885f5f5f5f5f	64	intel	movnti dword ptr [rcx], edx
+660fc311|223344556677885f5f5f5f5f	64	plan9	MOVNTIW DX, 0(CX)
+660fc41122|3344556677885f5f5f5f5f	32	intel	pinsrw xmm2, word ptr [ecx], 0x22
+660fc41122|3344556677885f5f5f5f5f	32	plan9	PINSRW $0x22, 0(CX), X2
+660fc41122|3344556677885f5f5f5f5f	64	gnu	pinsrw $0x22,(%rcx),%xmm2
+660fc41122|3344556677885f5f5f5f5f	64	intel	pinsrw xmm2, word ptr [rcx], 0x22
+660fc41122|3344556677885f5f5f5f5f	64	plan9	PINSRW $0x22, 0(CX), X2
+660fc5c011|223344556677885f5f5f5f	32	intel	pextrw eax, xmm0, 0x11
+660fc5c011|223344556677885f5f5f5f	32	plan9	PEXTRW $0x11, X0, AX
+660fc5c011|223344556677885f5f5f5f	64	gnu	pextrw $0x11,%xmm0,%eax
+660fc5c011|223344556677885f5f5f5f	64	intel	pextrw eax, xmm0, 0x11
+660fc5c011|223344556677885f5f5f5f	64	plan9	PEXTRW $0x11, X0, AX
+660fc61122|3344556677885f5f5f5f5f	32	intel	shufpd xmm2, xmmword ptr [ecx], 0x22
+660fc61122|3344556677885f5f5f5f5f	32	plan9	SHUFPD $0x22, 0(CX), X2
+660fc61122|3344556677885f5f5f5f5f	64	gnu	shufpd $0x22,(%rcx),%xmm2
+660fc61122|3344556677885f5f5f5f5f	64	intel	shufpd xmm2, xmmword ptr [rcx], 0x22
+660fc61122|3344556677885f5f5f5f5f	64	plan9	SHUFPD $0x22, 0(CX), X2
+660fc708|11223344556677885f5f5f5f	32	intel	cmpxchg8b qword ptr [eax]
+660fc708|11223344556677885f5f5f5f	32	plan9	CMPXCHG8B 0(AX)
+660fc708|11223344556677885f5f5f5f	64	gnu	data16 cmpxchg8b (%rax)
+660fc708|11223344556677885f5f5f5f	64	intel	cmpxchg8b qword ptr [rax]
+660fc708|11223344556677885f5f5f5f	64	plan9	CMPXCHG8B 0(AX)
+660fc718|11223344556677885f5f5f5f	32	intel	xrstors ptr [eax]
+660fc718|11223344556677885f5f5f5f	32	plan9	XRSTORS 0(AX)
+660fc718|11223344556677885f5f5f5f	64	gnu	xrstors (%rax)
+660fc718|11223344556677885f5f5f5f	64	intel	xrstors ptr [rax]
+660fc718|11223344556677885f5f5f5f	64	plan9	XRSTORS 0(AX)
+660fc720|11223344556677885f5f5f5f	32	intel	xsavec ptr [eax]
+660fc720|11223344556677885f5f5f5f	32	plan9	XSAVEC 0(AX)
+660fc720|11223344556677885f5f5f5f	64	gnu	xsavec (%rax)
+660fc720|11223344556677885f5f5f5f	64	intel	xsavec ptr [rax]
+660fc720|11223344556677885f5f5f5f	64	plan9	XSAVEC 0(AX)
+660fc728|11223344556677885f5f5f5f	32	intel	xsaves ptr [eax]
+660fc728|11223344556677885f5f5f5f	32	plan9	XSAVES 0(AX)
+660fc728|11223344556677885f5f5f5f	64	gnu	xsaves (%rax)
+660fc728|11223344556677885f5f5f5f	64	intel	xsaves ptr [rax]
+660fc728|11223344556677885f5f5f5f	64	plan9	XSAVES 0(AX)
+660fc7f2|11223344556677885f5f5f5f	32	intel	rdrand dx
+660fc7f2|11223344556677885f5f5f5f	32	plan9	RDRAND DX
+660fc7f2|11223344556677885f5f5f5f	64	gnu	rdrand %dx
+660fc7f2|11223344556677885f5f5f5f	64	intel	rdrand dx
+660fc7f2|11223344556677885f5f5f5f	64	plan9	RDRAND DX
+660fc8|11223344556677885f5f5f5f5f	32	intel	bswap ax
+660fc8|11223344556677885f5f5f5f5f	32	plan9	BSWAP AX
+660fc8|11223344556677885f5f5f5f5f	64	gnu	bswap %ax
+660fc8|11223344556677885f5f5f5f5f	64	intel	bswap ax
+660fc8|11223344556677885f5f5f5f5f	64	plan9	BSWAP AX
+660fd011|223344556677885f5f5f5f5f	32	intel	addsubpd xmm2, xmmword ptr [ecx]
+660fd011|223344556677885f5f5f5f5f	32	plan9	ADDSUBPD 0(CX), X2
+660fd011|223344556677885f5f5f5f5f	64	gnu	addsubpd (%rcx),%xmm2
+660fd011|223344556677885f5f5f5f5f	64	intel	addsubpd xmm2, xmmword ptr [rcx]
+660fd011|223344556677885f5f5f5f5f	64	plan9	ADDSUBPD 0(CX), X2
+660fd111|223344556677885f5f5f5f5f	32	intel	psrlw xmm2, xmmword ptr [ecx]
+660fd111|223344556677885f5f5f5f5f	32	plan9	PSRLW 0(CX), X2
+660fd111|223344556677885f5f5f5f5f	64	gnu	psrlw (%rcx),%xmm2
+660fd111|223344556677885f5f5f5f5f	64	intel	psrlw xmm2, xmmword ptr [rcx]
+660fd111|223344556677885f5f5f5f5f	64	plan9	PSRLW 0(CX), X2
+660fd211|223344556677885f5f5f5f5f	32	intel	psrld xmm2, xmmword ptr [ecx]
+660fd211|223344556677885f5f5f5f5f	32	plan9	PSRLD 0(CX), X2
+660fd211|223344556677885f5f5f5f5f	64	gnu	psrld (%rcx),%xmm2
+660fd211|223344556677885f5f5f5f5f	64	intel	psrld xmm2, xmmword ptr [rcx]
+660fd211|223344556677885f5f5f5f5f	64	plan9	PSRLD 0(CX), X2
+660fd311|223344556677885f5f5f5f5f	32	intel	psrlq xmm2, xmmword ptr [ecx]
+660fd311|223344556677885f5f5f5f5f	32	plan9	PSRLQ 0(CX), X2
+660fd311|223344556677885f5f5f5f5f	64	gnu	psrlq (%rcx),%xmm2
+660fd311|223344556677885f5f5f5f5f	64	intel	psrlq xmm2, xmmword ptr [rcx]
+660fd311|223344556677885f5f5f5f5f	64	plan9	PSRLQ 0(CX), X2
+660fd411|223344556677885f5f5f5f5f	32	intel	paddq xmm2, xmmword ptr [ecx]
+660fd411|223344556677885f5f5f5f5f	32	plan9	PADDQ 0(CX), X2
+660fd411|223344556677885f5f5f5f5f	64	gnu	paddq (%rcx),%xmm2
+660fd411|223344556677885f5f5f5f5f	64	intel	paddq xmm2, xmmword ptr [rcx]
+660fd411|223344556677885f5f5f5f5f	64	plan9	PADDQ 0(CX), X2
+660fd511|223344556677885f5f5f5f5f	32	intel	pmullw xmm2, xmmword ptr [ecx]
+660fd511|223344556677885f5f5f5f5f	32	plan9	PMULLW 0(CX), X2
+660fd511|223344556677885f5f5f5f5f	64	gnu	pmullw (%rcx),%xmm2
+660fd511|223344556677885f5f5f5f5f	64	intel	pmullw xmm2, xmmword ptr [rcx]
+660fd511|223344556677885f5f5f5f5f	64	plan9	PMULLW 0(CX), X2
+660fd611|223344556677885f5f5f5f5f	32	intel	movq qword ptr [ecx], xmm2
+660fd611|223344556677885f5f5f5f5f	32	plan9	MOVQ X2, 0(CX)
+660fd611|223344556677885f5f5f5f5f	64	gnu	movq %xmm2,(%rcx)
+660fd611|223344556677885f5f5f5f5f	64	intel	movq qword ptr [rcx], xmm2
+660fd611|223344556677885f5f5f5f5f	64	plan9	MOVQ X2, 0(CX)
+660fd7c0|11223344556677885f5f5f5f	32	intel	pmovmskb eax, xmm0
+660fd7c0|11223344556677885f5f5f5f	32	plan9	PMOVMSKB X0, AX
+660fd7c0|11223344556677885f5f5f5f	64	gnu	pmovmskb %xmm0,%eax
+660fd7c0|11223344556677885f5f5f5f	64	intel	pmovmskb eax, xmm0
+660fd7c0|11223344556677885f5f5f5f	64	plan9	PMOVMSKB X0, AX
+660fd811|223344556677885f5f5f5f5f	32	intel	psubusb xmm2, xmmword ptr [ecx]
+660fd811|223344556677885f5f5f5f5f	32	plan9	PSUBUSB 0(CX), X2
+660fd811|223344556677885f5f5f5f5f	64	gnu	psubusb (%rcx),%xmm2
+660fd811|223344556677885f5f5f5f5f	64	intel	psubusb xmm2, xmmword ptr [rcx]
+660fd811|223344556677885f5f5f5f5f	64	plan9	PSUBUSB 0(CX), X2
+660fd911|223344556677885f5f5f5f5f	32	intel	psubusw xmm2, xmmword ptr [ecx]
+660fd911|223344556677885f5f5f5f5f	32	plan9	PSUBUSW 0(CX), X2
+660fd911|223344556677885f5f5f5f5f	64	gnu	psubusw (%rcx),%xmm2
+660fd911|223344556677885f5f5f5f5f	64	intel	psubusw xmm2, xmmword ptr [rcx]
+660fd911|223344556677885f5f5f5f5f	64	plan9	PSUBUSW 0(CX), X2
+660fda11|223344556677885f5f5f5f5f	32	intel	pminub xmm2, xmmword ptr [ecx]
+660fda11|223344556677885f5f5f5f5f	32	plan9	PMINUB 0(CX), X2
+660fda11|223344556677885f5f5f5f5f	64	gnu	pminub (%rcx),%xmm2
+660fda11|223344556677885f5f5f5f5f	64	intel	pminub xmm2, xmmword ptr [rcx]
+660fda11|223344556677885f5f5f5f5f	64	plan9	PMINUB 0(CX), X2
+660fdb11|223344556677885f5f5f5f5f	32	intel	pand xmm2, xmmword ptr [ecx]
+660fdb11|223344556677885f5f5f5f5f	32	plan9	PAND 0(CX), X2
+660fdb11|223344556677885f5f5f5f5f	64	gnu	pand (%rcx),%xmm2
+660fdb11|223344556677885f5f5f5f5f	64	intel	pand xmm2, xmmword ptr [rcx]
+660fdb11|223344556677885f5f5f5f5f	64	plan9	PAND 0(CX), X2
+660fdc11|223344556677885f5f5f5f5f	32	intel	paddusb xmm2, xmmword ptr [ecx]
+660fdc11|223344556677885f5f5f5f5f	32	plan9	PADDUSB 0(CX), X2
+660fdc11|223344556677885f5f5f5f5f	64	gnu	paddusb (%rcx),%xmm2
+660fdc11|223344556677885f5f5f5f5f	64	intel	paddusb xmm2, xmmword ptr [rcx]
+660fdc11|223344556677885f5f5f5f5f	64	plan9	PADDUSB 0(CX), X2
+660fdd11|223344556677885f5f5f5f5f	32	intel	paddusw xmm2, xmmword ptr [ecx]
+660fdd11|223344556677885f5f5f5f5f	32	plan9	PADDUSW 0(CX), X2
+660fdd11|223344556677885f5f5f5f5f	64	gnu	paddusw (%rcx),%xmm2
+660fdd11|223344556677885f5f5f5f5f	64	intel	paddusw xmm2, xmmword ptr [rcx]
+660fdd11|223344556677885f5f5f5f5f	64	plan9	PADDUSW 0(CX), X2
+660fde11|223344556677885f5f5f5f5f	32	intel	pmaxub xmm2, xmmword ptr [ecx]
+660fde11|223344556677885f5f5f5f5f	32	plan9	PMAXUB 0(CX), X2
+660fde11|223344556677885f5f5f5f5f	64	gnu	pmaxub (%rcx),%xmm2
+660fde11|223344556677885f5f5f5f5f	64	intel	pmaxub xmm2, xmmword ptr [rcx]
+660fde11|223344556677885f5f5f5f5f	64	plan9	PMAXUB 0(CX), X2
+660fdf11|223344556677885f5f5f5f5f	32	intel	pandn xmm2, xmmword ptr [ecx]
+660fdf11|223344556677885f5f5f5f5f	32	plan9	PANDN 0(CX), X2
+660fdf11|223344556677885f5f5f5f5f	64	gnu	pandn (%rcx),%xmm2
+660fdf11|223344556677885f5f5f5f5f	64	intel	pandn xmm2, xmmword ptr [rcx]
+660fdf11|223344556677885f5f5f5f5f	64	plan9	PANDN 0(CX), X2
+660fe011|223344556677885f5f5f5f5f	32	intel	pavgb xmm2, xmmword ptr [ecx]
+660fe011|223344556677885f5f5f5f5f	32	plan9	PAVGB 0(CX), X2
+660fe011|223344556677885f5f5f5f5f	64	gnu	pavgb (%rcx),%xmm2
+660fe011|223344556677885f5f5f5f5f	64	intel	pavgb xmm2, xmmword ptr [rcx]
+660fe011|223344556677885f5f5f5f5f	64	plan9	PAVGB 0(CX), X2
+660fe111|223344556677885f5f5f5f5f	32	intel	psraw xmm2, xmmword ptr [ecx]
+660fe111|223344556677885f5f5f5f5f	32	plan9	PSRAW 0(CX), X2
+660fe111|223344556677885f5f5f5f5f	64	gnu	psraw (%rcx),%xmm2
+660fe111|223344556677885f5f5f5f5f	64	intel	psraw xmm2, xmmword ptr [rcx]
+660fe111|223344556677885f5f5f5f5f	64	plan9	PSRAW 0(CX), X2
+660fe211|223344556677885f5f5f5f5f	32	intel	psrad xmm2, xmmword ptr [ecx]
+660fe211|223344556677885f5f5f5f5f	32	plan9	PSRAD 0(CX), X2
+660fe211|223344556677885f5f5f5f5f	64	gnu	psrad (%rcx),%xmm2
+660fe211|223344556677885f5f5f5f5f	64	intel	psrad xmm2, xmmword ptr [rcx]
+660fe211|223344556677885f5f5f5f5f	64	plan9	PSRAD 0(CX), X2
+660fe311|223344556677885f5f5f5f5f	32	intel	pavgw xmm2, xmmword ptr [ecx]
+660fe311|223344556677885f5f5f5f5f	32	plan9	PAVGW 0(CX), X2
+660fe311|223344556677885f5f5f5f5f	64	gnu	pavgw (%rcx),%xmm2
+660fe311|223344556677885f5f5f5f5f	64	intel	pavgw xmm2, xmmword ptr [rcx]
+660fe311|223344556677885f5f5f5f5f	64	plan9	PAVGW 0(CX), X2
+660fe411|223344556677885f5f5f5f5f	32	intel	pmulhuw xmm2, xmmword ptr [ecx]
+660fe411|223344556677885f5f5f5f5f	32	plan9	PMULHUW 0(CX), X2
+660fe411|223344556677885f5f5f5f5f	64	gnu	pmulhuw (%rcx),%xmm2
+660fe411|223344556677885f5f5f5f5f	64	intel	pmulhuw xmm2, xmmword ptr [rcx]
+660fe411|223344556677885f5f5f5f5f	64	plan9	PMULHUW 0(CX), X2
+660fe511|223344556677885f5f5f5f5f	32	intel	pmulhw xmm2, xmmword ptr [ecx]
+660fe511|223344556677885f5f5f5f5f	32	plan9	PMULHW 0(CX), X2
+660fe511|223344556677885f5f5f5f5f	64	gnu	pmulhw (%rcx),%xmm2
+660fe511|223344556677885f5f5f5f5f	64	intel	pmulhw xmm2, xmmword ptr [rcx]
+660fe511|223344556677885f5f5f5f5f	64	plan9	PMULHW 0(CX), X2
+660fe611|223344556677885f5f5f5f5f	32	intel	cvttpd2dq xmm2, xmmword ptr [ecx]
+660fe611|223344556677885f5f5f5f5f	32	plan9	CVTTPD2DQ 0(CX), X2
+660fe611|223344556677885f5f5f5f5f	64	gnu	cvttpd2dq (%rcx),%xmm2
+660fe611|223344556677885f5f5f5f5f	64	intel	cvttpd2dq xmm2, xmmword ptr [rcx]
+660fe611|223344556677885f5f5f5f5f	64	plan9	CVTTPD2DQ 0(CX), X2
+660fe711|223344556677885f5f5f5f5f	32	intel	movntdq xmmword ptr [ecx], xmm2
+660fe711|223344556677885f5f5f5f5f	32	plan9	MOVNTDQ X2, 0(CX)
+660fe711|223344556677885f5f5f5f5f	64	gnu	movntdq %xmm2,(%rcx)
+660fe711|223344556677885f5f5f5f5f	64	intel	movntdq xmmword ptr [rcx], xmm2
+660fe711|223344556677885f5f5f5f5f	64	plan9	MOVNTDQ X2, 0(CX)
+660fe811|223344556677885f5f5f5f5f	32	intel	psubsb xmm2, xmmword ptr [ecx]
+660fe811|223344556677885f5f5f5f5f	32	plan9	PSUBSB 0(CX), X2
+660fe811|223344556677885f5f5f5f5f	64	gnu	psubsb (%rcx),%xmm2
+660fe811|223344556677885f5f5f5f5f	64	intel	psubsb xmm2, xmmword ptr [rcx]
+660fe811|223344556677885f5f5f5f5f	64	plan9	PSUBSB 0(CX), X2
+660fe911|223344556677885f5f5f5f5f	32	intel	psubsw xmm2, xmmword ptr [ecx]
+660fe911|223344556677885f5f5f5f5f	32	plan9	PSUBSW 0(CX), X2
+660fe911|223344556677885f5f5f5f5f	64	gnu	psubsw (%rcx),%xmm2
+660fe911|223344556677885f5f5f5f5f	64	intel	psubsw xmm2, xmmword ptr [rcx]
+660fe911|223344556677885f5f5f5f5f	64	plan9	PSUBSW 0(CX), X2
+660fea11|223344556677885f5f5f5f5f	32	intel	pminsw xmm2, xmmword ptr [ecx]
+660fea11|223344556677885f5f5f5f5f	32	plan9	PMINSW 0(CX), X2
+660fea11|223344556677885f5f5f5f5f	64	gnu	pminsw (%rcx),%xmm2
+660fea11|223344556677885f5f5f5f5f	64	intel	pminsw xmm2, xmmword ptr [rcx]
+660fea11|223344556677885f5f5f5f5f	64	plan9	PMINSW 0(CX), X2
+660feb11|223344556677885f5f5f5f5f	32	intel	por xmm2, xmmword ptr [ecx]
+660feb11|223344556677885f5f5f5f5f	32	plan9	POR 0(CX), X2
+660feb11|223344556677885f5f5f5f5f	64	gnu	por (%rcx),%xmm2
+660feb11|223344556677885f5f5f5f5f	64	intel	por xmm2, xmmword ptr [rcx]
+660feb11|223344556677885f5f5f5f5f	64	plan9	POR 0(CX), X2
+660fec11|223344556677885f5f5f5f5f	32	intel	paddsb xmm2, xmmword ptr [ecx]
+660fec11|223344556677885f5f5f5f5f	32	plan9	PADDSB 0(CX), X2
+660fec11|223344556677885f5f5f5f5f	64	gnu	paddsb (%rcx),%xmm2
+660fec11|223344556677885f5f5f5f5f	64	intel	paddsb xmm2, xmmword ptr [rcx]
+660fec11|223344556677885f5f5f5f5f	64	plan9	PADDSB 0(CX), X2
+660fed11|223344556677885f5f5f5f5f	32	intel	paddsw xmm2, xmmword ptr [ecx]
+660fed11|223344556677885f5f5f5f5f	32	plan9	PADDSW 0(CX), X2
+660fed11|223344556677885f5f5f5f5f	64	gnu	paddsw (%rcx),%xmm2
+660fed11|223344556677885f5f5f5f5f	64	intel	paddsw xmm2, xmmword ptr [rcx]
+660fed11|223344556677885f5f5f5f5f	64	plan9	PADDSW 0(CX), X2
+660fee11|223344556677885f5f5f5f5f	32	intel	pmaxsw xmm2, xmmword ptr [ecx]
+660fee11|223344556677885f5f5f5f5f	32	plan9	PMAXSW 0(CX), X2
+660fee11|223344556677885f5f5f5f5f	64	gnu	pmaxsw (%rcx),%xmm2
+660fee11|223344556677885f5f5f5f5f	64	intel	pmaxsw xmm2, xmmword ptr [rcx]
+660fee11|223344556677885f5f5f5f5f	64	plan9	PMAXSW 0(CX), X2
+660fef11|223344556677885f5f5f5f5f	32	intel	pxor xmm2, xmmword ptr [ecx]
+660fef11|223344556677885f5f5f5f5f	32	plan9	PXOR 0(CX), X2
+660fef11|223344556677885f5f5f5f5f	64	gnu	pxor (%rcx),%xmm2
+660fef11|223344556677885f5f5f5f5f	64	intel	pxor xmm2, xmmword ptr [rcx]
+660fef11|223344556677885f5f5f5f5f	64	plan9	PXOR 0(CX), X2
+660ff111|223344556677885f5f5f5f5f	32	intel	psllw xmm2, xmmword ptr [ecx]
+660ff111|223344556677885f5f5f5f5f	32	plan9	PSLLW 0(CX), X2
+660ff111|223344556677885f5f5f5f5f	64	gnu	psllw (%rcx),%xmm2
+660ff111|223344556677885f5f5f5f5f	64	intel	psllw xmm2, xmmword ptr [rcx]
+660ff111|223344556677885f5f5f5f5f	64	plan9	PSLLW 0(CX), X2
+660ff211|223344556677885f5f5f5f5f	32	intel	pslld xmm2, xmmword ptr [ecx]
+660ff211|223344556677885f5f5f5f5f	32	plan9	PSLLD 0(CX), X2
+660ff211|223344556677885f5f5f5f5f	64	gnu	pslld (%rcx),%xmm2
+660ff211|223344556677885f5f5f5f5f	64	intel	pslld xmm2, xmmword ptr [rcx]
+660ff211|223344556677885f5f5f5f5f	64	plan9	PSLLD 0(CX), X2
+660ff311|223344556677885f5f5f5f5f	32	intel	psllq xmm2, xmmword ptr [ecx]
+660ff311|223344556677885f5f5f5f5f	32	plan9	PSLLQ 0(CX), X2
+660ff311|223344556677885f5f5f5f5f	64	gnu	psllq (%rcx),%xmm2
+660ff311|223344556677885f5f5f5f5f	64	intel	psllq xmm2, xmmword ptr [rcx]
+660ff311|223344556677885f5f5f5f5f	64	plan9	PSLLQ 0(CX), X2
+660ff411|223344556677885f5f5f5f5f	32	intel	pmuludq xmm2, xmmword ptr [ecx]
+660ff411|223344556677885f5f5f5f5f	32	plan9	PMULUDQ 0(CX), X2
+660ff411|223344556677885f5f5f5f5f	64	gnu	pmuludq (%rcx),%xmm2
+660ff411|223344556677885f5f5f5f5f	64	intel	pmuludq xmm2, xmmword ptr [rcx]
+660ff411|223344556677885f5f5f5f5f	64	plan9	PMULUDQ 0(CX), X2
+660ff511|223344556677885f5f5f5f5f	32	intel	pmaddwd xmm2, xmmword ptr [ecx]
+660ff511|223344556677885f5f5f5f5f	32	plan9	PMADDWD 0(CX), X2
+660ff511|223344556677885f5f5f5f5f	64	gnu	pmaddwd (%rcx),%xmm2
+660ff511|223344556677885f5f5f5f5f	64	intel	pmaddwd xmm2, xmmword ptr [rcx]
+660ff511|223344556677885f5f5f5f5f	64	plan9	PMADDWD 0(CX), X2
+660ff611|223344556677885f5f5f5f5f	32	intel	psadbw xmm2, xmmword ptr [ecx]
+660ff611|223344556677885f5f5f5f5f	32	plan9	PSADBW 0(CX), X2
+660ff611|223344556677885f5f5f5f5f	64	gnu	psadbw (%rcx),%xmm2
+660ff611|223344556677885f5f5f5f5f	64	intel	psadbw xmm2, xmmword ptr [rcx]
+660ff611|223344556677885f5f5f5f5f	64	plan9	PSADBW 0(CX), X2
+660ff7c0|11223344556677885f5f5f5f	32	intel	maskmovdqu xmm0, xmm0
+660ff7c0|11223344556677885f5f5f5f	32	plan9	MASKMOVDQU X0, X0
+660ff7c0|11223344556677885f5f5f5f	64	intel	maskmovdqu xmm0, xmm0
+660ff7c0|11223344556677885f5f5f5f	64	plan9	MASKMOVDQU X0, X0
+660ff811|223344556677885f5f5f5f5f	32	intel	psubb xmm2, xmmword ptr [ecx]
+660ff811|223344556677885f5f5f5f5f	32	plan9	PSUBB 0(CX), X2
+660ff811|223344556677885f5f5f5f5f	64	gnu	psubb (%rcx),%xmm2
+660ff811|223344556677885f5f5f5f5f	64	intel	psubb xmm2, xmmword ptr [rcx]
+660ff811|223344556677885f5f5f5f5f	64	plan9	PSUBB 0(CX), X2
+660ff911|223344556677885f5f5f5f5f	32	intel	psubw xmm2, xmmword ptr [ecx]
+660ff911|223344556677885f5f5f5f5f	32	plan9	PSUBW 0(CX), X2
+660ff911|223344556677885f5f5f5f5f	64	gnu	psubw (%rcx),%xmm2
+660ff911|223344556677885f5f5f5f5f	64	intel	psubw xmm2, xmmword ptr [rcx]
+660ff911|223344556677885f5f5f5f5f	64	plan9	PSUBW 0(CX), X2
+660ffa11|223344556677885f5f5f5f5f	32	intel	psubd xmm2, xmmword ptr [ecx]
+660ffa11|223344556677885f5f5f5f5f	32	plan9	PSUBD 0(CX), X2
+660ffa11|223344556677885f5f5f5f5f	64	gnu	psubd (%rcx),%xmm2
+660ffa11|223344556677885f5f5f5f5f	64	intel	psubd xmm2, xmmword ptr [rcx]
+660ffa11|223344556677885f5f5f5f5f	64	plan9	PSUBD 0(CX), X2
+660ffb11|223344556677885f5f5f5f5f	32	intel	psubq xmm2, xmmword ptr [ecx]
+660ffb11|223344556677885f5f5f5f5f	32	plan9	PSUBQ 0(CX), X2
+660ffb11|223344556677885f5f5f5f5f	64	gnu	psubq (%rcx),%xmm2
+660ffb11|223344556677885f5f5f5f5f	64	intel	psubq xmm2, xmmword ptr [rcx]
+660ffb11|223344556677885f5f5f5f5f	64	plan9	PSUBQ 0(CX), X2
+660ffc11|223344556677885f5f5f5f5f	32	intel	paddb xmm2, xmmword ptr [ecx]
+660ffc11|223344556677885f5f5f5f5f	32	plan9	PADDB 0(CX), X2
+660ffc11|223344556677885f5f5f5f5f	64	gnu	paddb (%rcx),%xmm2
+660ffc11|223344556677885f5f5f5f5f	64	intel	paddb xmm2, xmmword ptr [rcx]
+660ffc11|223344556677885f5f5f5f5f	64	plan9	PADDB 0(CX), X2
+660ffd11|223344556677885f5f5f5f5f	32	intel	paddw xmm2, xmmword ptr [ecx]
+660ffd11|223344556677885f5f5f5f5f	32	plan9	PADDW 0(CX), X2
+660ffd11|223344556677885f5f5f5f5f	64	gnu	paddw (%rcx),%xmm2
+660ffd11|223344556677885f5f5f5f5f	64	intel	paddw xmm2, xmmword ptr [rcx]
+660ffd11|223344556677885f5f5f5f5f	64	plan9	PADDW 0(CX), X2
+660ffe11|223344556677885f5f5f5f5f	32	intel	paddd xmm2, xmmword ptr [ecx]
+660ffe11|223344556677885f5f5f5f5f	32	plan9	PADDD 0(CX), X2
+660ffe11|223344556677885f5f5f5f5f	64	gnu	paddd (%rcx),%xmm2
+660ffe11|223344556677885f5f5f5f5f	64	intel	paddd xmm2, xmmword ptr [rcx]
+660ffe11|223344556677885f5f5f5f5f	64	plan9	PADDD 0(CX), X2
+661122|3344556677885f5f5f5f5f5f5f	32	intel	adc word ptr [edx], sp
+661122|3344556677885f5f5f5f5f5f5f	32	plan9	ADCW SP, 0(DX)
+661122|3344556677885f5f5f5f5f5f5f	64	gnu	adc %sp,(%rdx)
+661122|3344556677885f5f5f5f5f5f5f	64	intel	adc word ptr [rdx], sp
+661122|3344556677885f5f5f5f5f5f5f	64	plan9	ADCW SP, 0(DX)
+661311|223344556677885f5f5f5f5f5f	32	intel	adc dx, word ptr [ecx]
+661311|223344556677885f5f5f5f5f5f	32	plan9	ADCW 0(CX), DX
+661311|223344556677885f5f5f5f5f5f	64	gnu	adc (%rcx),%dx
+661311|223344556677885f5f5f5f5f5f	64	intel	adc dx, word ptr [rcx]
+661311|223344556677885f5f5f5f5f5f	64	plan9	ADCW 0(CX), DX
+66151122|3344556677885f5f5f5f5f5f	32	intel	adc ax, 0x2211
+66151122|3344556677885f5f5f5f5f5f	32	plan9	ADCW $0x2211, AX
+66151122|3344556677885f5f5f5f5f5f	64	gnu	adc $0x2211,%ax
+66151122|3344556677885f5f5f5f5f5f	64	intel	adc ax, 0x2211
+66151122|3344556677885f5f5f5f5f5f	64	plan9	ADCW $0x2211, AX
+661911|223344556677885f5f5f5f5f5f	32	intel	sbb word ptr [ecx], dx
+661911|223344556677885f5f5f5f5f5f	32	plan9	SBBW DX, 0(CX)
+661911|223344556677885f5f5f5f5f5f	64	gnu	sbb %dx,(%rcx)
+661911|223344556677885f5f5f5f5f5f	64	intel	sbb word ptr [rcx], dx
+661911|223344556677885f5f5f5f5f5f	64	plan9	SBBW DX, 0(CX)
+661b11|223344556677885f5f5f5f5f5f	32	intel	sbb dx, word ptr [ecx]
+661b11|223344556677885f5f5f5f5f5f	32	plan9	SBBW 0(CX), DX
+661b11|223344556677885f5f5f5f5f5f	64	gnu	sbb (%rcx),%dx
+661b11|223344556677885f5f5f5f5f5f	64	intel	sbb dx, word ptr [rcx]
+661b11|223344556677885f5f5f5f5f5f	64	plan9	SBBW 0(CX), DX
+661d1122|3344556677885f5f5f5f5f5f	32	intel	sbb ax, 0x2211
+661d1122|3344556677885f5f5f5f5f5f	32	plan9	SBBW $0x2211, AX
+661d1122|3344556677885f5f5f5f5f5f	64	gnu	sbb $0x2211,%ax
+661d1122|3344556677885f5f5f5f5f5f	64	intel	sbb ax, 0x2211
+661d1122|3344556677885f5f5f5f5f5f	64	plan9	SBBW $0x2211, AX
+662111|223344556677885f5f5f5f5f5f	32	intel	and word ptr [ecx], dx
+662111|223344556677885f5f5f5f5f5f	32	plan9	ANDW DX, 0(CX)
+662111|223344556677885f5f5f5f5f5f	64	gnu	and %dx,(%rcx)
+662111|223344556677885f5f5f5f5f5f	64	intel	and word ptr [rcx], dx
+662111|223344556677885f5f5f5f5f5f	64	plan9	ANDW DX, 0(CX)
+662311|223344556677885f5f5f5f5f5f	32	intel	and dx, word ptr [ecx]
+662311|223344556677885f5f5f5f5f5f	32	plan9	ANDW 0(CX), DX
+662311|223344556677885f5f5f5f5f5f	64	gnu	and (%rcx),%dx
+662311|223344556677885f5f5f5f5f5f	64	intel	and dx, word ptr [rcx]
+662311|223344556677885f5f5f5f5f5f	64	plan9	ANDW 0(CX), DX
+66251122|3344556677885f5f5f5f5f5f	32	intel	and ax, 0x2211
+66251122|3344556677885f5f5f5f5f5f	32	plan9	ANDW $0x2211, AX
+66251122|3344556677885f5f5f5f5f5f	64	gnu	and $0x2211,%ax
+66251122|3344556677885f5f5f5f5f5f	64	intel	and ax, 0x2211
+66251122|3344556677885f5f5f5f5f5f	64	plan9	ANDW $0x2211, AX
+662911|223344556677885f5f5f5f5f5f	32	intel	sub word ptr [ecx], dx
+662911|223344556677885f5f5f5f5f5f	32	plan9	SUBW DX, 0(CX)
+662911|223344556677885f5f5f5f5f5f	64	gnu	sub %dx,(%rcx)
+662911|223344556677885f5f5f5f5f5f	64	intel	sub word ptr [rcx], dx
+662911|223344556677885f5f5f5f5f5f	64	plan9	SUBW DX, 0(CX)
+662b11|223344556677885f5f5f5f5f5f	32	intel	sub dx, word ptr [ecx]
+662b11|223344556677885f5f5f5f5f5f	32	plan9	SUBW 0(CX), DX
+662b11|223344556677885f5f5f5f5f5f	64	gnu	sub (%rcx),%dx
+662b11|223344556677885f5f5f5f5f5f	64	intel	sub dx, word ptr [rcx]
+662b11|223344556677885f5f5f5f5f5f	64	plan9	SUBW 0(CX), DX
+662d1122|3344556677885f5f5f5f5f5f	32	intel	sub ax, 0x2211
+662d1122|3344556677885f5f5f5f5f5f	32	plan9	SUBW $0x2211, AX
+662d1122|3344556677885f5f5f5f5f5f	64	gnu	sub $0x2211,%ax
+662d1122|3344556677885f5f5f5f5f5f	64	intel	sub ax, 0x2211
+662d1122|3344556677885f5f5f5f5f5f	64	plan9	SUBW $0x2211, AX
+663111|223344556677885f5f5f5f5f5f	32	intel	xor word ptr [ecx], dx
+663111|223344556677885f5f5f5f5f5f	32	plan9	XORW DX, 0(CX)
+663111|223344556677885f5f5f5f5f5f	64	gnu	xor %dx,(%rcx)
+663111|223344556677885f5f5f5f5f5f	64	intel	xor word ptr [rcx], dx
+663111|223344556677885f5f5f5f5f5f	64	plan9	XORW DX, 0(CX)
+663311|223344556677885f5f5f5f5f5f	32	intel	xor dx, word ptr [ecx]
+663311|223344556677885f5f5f5f5f5f	32	plan9	XORW 0(CX), DX
+663311|223344556677885f5f5f5f5f5f	64	gnu	xor (%rcx),%dx
+663311|223344556677885f5f5f5f5f5f	64	intel	xor dx, word ptr [rcx]
+663311|223344556677885f5f5f5f5f5f	64	plan9	XORW 0(CX), DX
+66351122|3344556677885f5f5f5f5f5f	32	intel	xor ax, 0x2211
+66351122|3344556677885f5f5f5f5f5f	32	plan9	XORW $0x2211, AX
+66351122|3344556677885f5f5f5f5f5f	64	gnu	xor $0x2211,%ax
+66351122|3344556677885f5f5f5f5f5f	64	intel	xor ax, 0x2211
+66351122|3344556677885f5f5f5f5f5f	64	plan9	XORW $0x2211, AX
+663911|223344556677885f5f5f5f5f5f	32	intel	cmp word ptr [ecx], dx
+663911|223344556677885f5f5f5f5f5f	32	plan9	CMPW DX, 0(CX)
+663911|223344556677885f5f5f5f5f5f	64	gnu	cmp %dx,(%rcx)
+663911|223344556677885f5f5f5f5f5f	64	intel	cmp word ptr [rcx], dx
+663911|223344556677885f5f5f5f5f5f	64	plan9	CMPW DX, 0(CX)
+663b11|223344556677885f5f5f5f5f5f	32	intel	cmp dx, word ptr [ecx]
+663b11|223344556677885f5f5f5f5f5f	32	plan9	CMPW 0(CX), DX
+663b11|223344556677885f5f5f5f5f5f	64	gnu	cmp (%rcx),%dx
+663b11|223344556677885f5f5f5f5f5f	64	intel	cmp dx, word ptr [rcx]
+663b11|223344556677885f5f5f5f5f5f	64	plan9	CMPW 0(CX), DX
+663d1122|3344556677885f5f5f5f5f5f	32	intel	cmp ax, 0x2211
+663d1122|3344556677885f5f5f5f5f5f	32	plan9	CMPW $0x2211, AX
+663d1122|3344556677885f5f5f5f5f5f	64	gnu	cmp $0x2211,%ax
+663d1122|3344556677885f5f5f5f5f5f	64	intel	cmp ax, 0x2211
+663d1122|3344556677885f5f5f5f5f5f	64	plan9	CMPW $0x2211, AX
+6640|11223344556677885f5f5f5f5f5f	32	intel	inc ax
+6640|11223344556677885f5f5f5f5f5f	32	plan9	INCW AX
+66480f3a161122|3344556677885f5f5f	64	gnu	pextrq $0x22,%xmm2,(%rcx)
+66480f3a161122|3344556677885f5f5f	64	intel	pextrq qword ptr [rcx], xmm2, 0x22
+66480f3a161122|3344556677885f5f5f	64	plan9	PEXTRQ $0x22, X2, 0(CX)
+66480f3a221122|3344556677885f5f5f	64	gnu	pinsrq $0x22,(%rcx),%xmm2
+66480f3a221122|3344556677885f5f5f	64	intel	pinsrq xmm2, qword ptr [rcx], 0x22
+66480f3a221122|3344556677885f5f5f	64	plan9	PINSRQ $0x22, 0(CX), X2
+66480f6e11|223344556677885f5f5f5f	64	gnu	movq (%rcx),%xmm2
+66480f6e11|223344556677885f5f5f5f	64	intel	movq xmm2, qword ptr [rcx]
+66480f6e11|223344556677885f5f5f5f	64	plan9	MOVQ 0(CX), X2
+66480f7e11|223344556677885f5f5f5f	64	gnu	movq %xmm2,(%rcx)
+66480f7e11|223344556677885f5f5f5f	64	intel	movq qword ptr [rcx], xmm2
+66480f7e11|223344556677885f5f5f5f	64	plan9	MOVQ X2, 0(CX)
+6648|0f3a1611223344556677885f5f5f	32	intel	dec ax
+6648|0f3a1611223344556677885f5f5f	32	plan9	DECW AX
+6650|11223344556677885f5f5f5f5f5f	32	intel	push ax
+6650|11223344556677885f5f5f5f5f5f	32	plan9	PUSHW AX
+6650|11223344556677885f5f5f5f5f5f	64	gnu	push %ax
+6650|11223344556677885f5f5f5f5f5f	64	intel	push ax
+6650|11223344556677885f5f5f5f5f5f	64	plan9	PUSHW AX
+6658|11223344556677885f5f5f5f5f5f	32	intel	pop ax
+6658|11223344556677885f5f5f5f5f5f	32	plan9	POPW AX
+6658|11223344556677885f5f5f5f5f5f	64	gnu	pop %ax
+6658|11223344556677885f5f5f5f5f5f	64	intel	pop ax
+6658|11223344556677885f5f5f5f5f5f	64	plan9	POPW AX
+6660|11223344556677885f5f5f5f5f5f	32	intel	data16 pusha
+6660|11223344556677885f5f5f5f5f5f	32	plan9	PUSHAW
+6661|11223344556677885f5f5f5f5f5f	32	intel	data16 popa
+6661|11223344556677885f5f5f5f5f5f	32	plan9	POPAW
+666211|223344556677885f5f5f5f5f5f	32	intel	bound dx, qword ptr [ecx]
+666211|223344556677885f5f5f5f5f5f	32	plan9	BOUND 0(CX), DX
+666311|223344556677885f5f5f5f5f5f	64	gnu	movsxd (%rcx),%dx
+666311|223344556677885f5f5f5f5f5f	64	intel	movsxd dx, dword ptr [rcx]
+666311|223344556677885f5f5f5f5f5f	64	plan9	MOVSXD 0(CX), DX
+66681122|3344556677885f5f5f5f5f5f	32	intel	push 0x2211
+66681122|3344556677885f5f5f5f5f5f	32	plan9	PUSHW $0x2211
+66681122|3344556677885f5f5f5f5f5f	64	gnu	pushw $0x2211
+66681122|3344556677885f5f5f5f5f5f	64	intel	push 0x2211
+66681122|3344556677885f5f5f5f5f5f	64	plan9	PUSHW $0x2211
+6669112233|44556677885f5f5f5f5f5f	32	intel	imul dx, word ptr [ecx], 0x3322
+6669112233|44556677885f5f5f5f5f5f	32	plan9	IMULW $0x3322, 0(CX), DX
+6669112233|44556677885f5f5f5f5f5f	64	gnu	imul $0x3322,(%rcx),%dx
+6669112233|44556677885f5f5f5f5f5f	64	intel	imul dx, word ptr [rcx], 0x3322
+6669112233|44556677885f5f5f5f5f5f	64	plan9	IMULW $0x3322, 0(CX), DX
+666b1122|3344556677885f5f5f5f5f5f	32	intel	imul dx, word ptr [ecx], 0x22
+666b1122|3344556677885f5f5f5f5f5f	32	plan9	IMULW $0x22, 0(CX), DX
+666b1122|3344556677885f5f5f5f5f5f	64	gnu	imul $0x22,(%rcx),%dx
+666b1122|3344556677885f5f5f5f5f5f	64	intel	imul dx, word ptr [rcx], 0x22
+666b1122|3344556677885f5f5f5f5f5f	64	plan9	IMULW $0x22, 0(CX), DX
+666d|11223344556677885f5f5f5f5f5f	32	intel	data16 insw
+666d|11223344556677885f5f5f5f5f5f	32	plan9	INSW DX, ES:0(DI)
+666d|11223344556677885f5f5f5f5f5f	64	gnu	insw (%dx),%es:(%rdi)
+666d|11223344556677885f5f5f5f5f5f	64	intel	data16 insw
+666d|11223344556677885f5f5f5f5f5f	64	plan9	INSW DX, ES:0(DI)
+666f|11223344556677885f5f5f5f5f5f	32	intel	data16 outsw
+666f|11223344556677885f5f5f5f5f5f	32	plan9	OUTSW DS:0(SI), DX
+666f|11223344556677885f5f5f5f5f5f	64	gnu	outsw %ds:(%rsi),(%dx)
+666f|11223344556677885f5f5f5f5f5f	64	intel	data16 outsw
+666f|11223344556677885f5f5f5f5f5f	64	plan9	OUTSW DS:0(SI), DX
+6681001122|3344556677885f5f5f5f5f	32	intel	add word ptr [eax], 0x2211
+6681001122|3344556677885f5f5f5f5f	32	plan9	ADDW $0x2211, 0(AX)
+6681001122|3344556677885f5f5f5f5f	64	gnu	addw $0x2211,(%rax)
+6681001122|3344556677885f5f5f5f5f	64	intel	add word ptr [rax], 0x2211
+6681001122|3344556677885f5f5f5f5f	64	plan9	ADDW $0x2211, 0(AX)
+6681081122|3344556677885f5f5f5f5f	32	intel	or word ptr [eax], 0x2211
+6681081122|3344556677885f5f5f5f5f	32	plan9	ORW $0x2211, 0(AX)
+6681081122|3344556677885f5f5f5f5f	64	gnu	orw $0x2211,(%rax)
+6681081122|3344556677885f5f5f5f5f	64	intel	or word ptr [rax], 0x2211
+6681081122|3344556677885f5f5f5f5f	64	plan9	ORW $0x2211, 0(AX)
+6681112233|44556677885f5f5f5f5f5f	32	intel	adc word ptr [ecx], 0x3322
+6681112233|44556677885f5f5f5f5f5f	32	plan9	ADCW $0x3322, 0(CX)
+6681112233|44556677885f5f5f5f5f5f	64	gnu	adcw $0x3322,(%rcx)
+6681112233|44556677885f5f5f5f5f5f	64	intel	adc word ptr [rcx], 0x3322
+6681112233|44556677885f5f5f5f5f5f	64	plan9	ADCW $0x3322, 0(CX)
+6681181122|3344556677885f5f5f5f5f	32	intel	sbb word ptr [eax], 0x2211
+6681181122|3344556677885f5f5f5f5f	32	plan9	SBBW $0x2211, 0(AX)
+6681181122|3344556677885f5f5f5f5f	64	gnu	sbbw $0x2211,(%rax)
+6681181122|3344556677885f5f5f5f5f	64	intel	sbb word ptr [rax], 0x2211
+6681181122|3344556677885f5f5f5f5f	64	plan9	SBBW $0x2211, 0(AX)
+6681201122|3344556677885f5f5f5f5f	32	intel	and word ptr [eax], 0x2211
+6681201122|3344556677885f5f5f5f5f	32	plan9	ANDW $0x2211, 0(AX)
+6681201122|3344556677885f5f5f5f5f	64	gnu	andw $0x2211,(%rax)
+6681201122|3344556677885f5f5f5f5f	64	intel	and word ptr [rax], 0x2211
+6681201122|3344556677885f5f5f5f5f	64	plan9	ANDW $0x2211, 0(AX)
+6681281122|3344556677885f5f5f5f5f	32	intel	sub word ptr [eax], 0x2211
+6681281122|3344556677885f5f5f5f5f	32	plan9	SUBW $0x2211, 0(AX)
+6681281122|3344556677885f5f5f5f5f	64	gnu	subw $0x2211,(%rax)
+6681281122|3344556677885f5f5f5f5f	64	intel	sub word ptr [rax], 0x2211
+6681281122|3344556677885f5f5f5f5f	64	plan9	SUBW $0x2211, 0(AX)
+6681301122|3344556677885f5f5f5f5f	32	intel	xor word ptr [eax], 0x2211
+6681301122|3344556677885f5f5f5f5f	32	plan9	XORW $0x2211, 0(AX)
+6681301122|3344556677885f5f5f5f5f	64	gnu	xorw $0x2211,(%rax)
+6681301122|3344556677885f5f5f5f5f	64	intel	xor word ptr [rax], 0x2211
+6681301122|3344556677885f5f5f5f5f	64	plan9	XORW $0x2211, 0(AX)
+6681381122|3344556677885f5f5f5f5f	32	intel	cmp word ptr [eax], 0x2211
+6681381122|3344556677885f5f5f5f5f	32	plan9	CMPW $0x2211, 0(AX)
+6681381122|3344556677885f5f5f5f5f	64	gnu	cmpw $0x2211,(%rax)
+6681381122|3344556677885f5f5f5f5f	64	intel	cmp word ptr [rax], 0x2211
+6681381122|3344556677885f5f5f5f5f	64	plan9	CMPW $0x2211, 0(AX)
+66830011|223344556677885f5f5f5f5f	32	intel	add word ptr [eax], 0x11
+66830011|223344556677885f5f5f5f5f	32	plan9	ADDW $0x11, 0(AX)
+66830011|223344556677885f5f5f5f5f	64	gnu	addw $0x11,(%rax)
+66830011|223344556677885f5f5f5f5f	64	intel	add word ptr [rax], 0x11
+66830011|223344556677885f5f5f5f5f	64	plan9	ADDW $0x11, 0(AX)
+66830811|223344556677885f5f5f5f5f	32	intel	or word ptr [eax], 0x11
+66830811|223344556677885f5f5f5f5f	32	plan9	ORW $0x11, 0(AX)
+66830811|223344556677885f5f5f5f5f	64	gnu	orw $0x11,(%rax)
+66830811|223344556677885f5f5f5f5f	64	intel	or word ptr [rax], 0x11
+66830811|223344556677885f5f5f5f5f	64	plan9	ORW $0x11, 0(AX)
+66831122|3344556677885f5f5f5f5f5f	32	intel	adc word ptr [ecx], 0x22
+66831122|3344556677885f5f5f5f5f5f	32	plan9	ADCW $0x22, 0(CX)
+66831122|3344556677885f5f5f5f5f5f	64	gnu	adcw $0x22,(%rcx)
+66831122|3344556677885f5f5f5f5f5f	64	intel	adc word ptr [rcx], 0x22
+66831122|3344556677885f5f5f5f5f5f	64	plan9	ADCW $0x22, 0(CX)
+66831811|223344556677885f5f5f5f5f	32	intel	sbb word ptr [eax], 0x11
+66831811|223344556677885f5f5f5f5f	32	plan9	SBBW $0x11, 0(AX)
+66831811|223344556677885f5f5f5f5f	64	gnu	sbbw $0x11,(%rax)
+66831811|223344556677885f5f5f5f5f	64	intel	sbb word ptr [rax], 0x11
+66831811|223344556677885f5f5f5f5f	64	plan9	SBBW $0x11, 0(AX)
+66832011|223344556677885f5f5f5f5f	32	intel	and word ptr [eax], 0x11
+66832011|223344556677885f5f5f5f5f	32	plan9	ANDW $0x11, 0(AX)
+66832011|223344556677885f5f5f5f5f	64	gnu	andw $0x11,(%rax)
+66832011|223344556677885f5f5f5f5f	64	intel	and word ptr [rax], 0x11
+66832011|223344556677885f5f5f5f5f	64	plan9	ANDW $0x11, 0(AX)
+66832811|223344556677885f5f5f5f5f	32	intel	sub word ptr [eax], 0x11
+66832811|223344556677885f5f5f5f5f	32	plan9	SUBW $0x11, 0(AX)
+66832811|223344556677885f5f5f5f5f	64	gnu	subw $0x11,(%rax)
+66832811|223344556677885f5f5f5f5f	64	intel	sub word ptr [rax], 0x11
+66832811|223344556677885f5f5f5f5f	64	plan9	SUBW $0x11, 0(AX)
+66833011|223344556677885f5f5f5f5f	32	intel	xor word ptr [eax], 0x11
+66833011|223344556677885f5f5f5f5f	32	plan9	XORW $0x11, 0(AX)
+66833011|223344556677885f5f5f5f5f	64	gnu	xorw $0x11,(%rax)
+66833011|223344556677885f5f5f5f5f	64	intel	xor word ptr [rax], 0x11
+66833011|223344556677885f5f5f5f5f	64	plan9	XORW $0x11, 0(AX)
+66833811|223344556677885f5f5f5f5f	32	intel	cmp word ptr [eax], 0x11
+66833811|223344556677885f5f5f5f5f	32	plan9	CMPW $0x11, 0(AX)
+66833811|223344556677885f5f5f5f5f	64	gnu	cmpw $0x11,(%rax)
+66833811|223344556677885f5f5f5f5f	64	intel	cmp word ptr [rax], 0x11
+66833811|223344556677885f5f5f5f5f	64	plan9	CMPW $0x11, 0(AX)
+668511|223344556677885f5f5f5f5f5f	32	intel	test word ptr [ecx], dx
+668511|223344556677885f5f5f5f5f5f	32	plan9	TESTW DX, 0(CX)
+668511|223344556677885f5f5f5f5f5f	64	gnu	test %dx,(%rcx)
+668511|223344556677885f5f5f5f5f5f	64	intel	test word ptr [rcx], dx
+668511|223344556677885f5f5f5f5f5f	64	plan9	TESTW DX, 0(CX)
+668711|223344556677885f5f5f5f5f5f	32	intel	xchg word ptr [ecx], dx
+668711|223344556677885f5f5f5f5f5f	32	plan9	XCHGW DX, 0(CX)
+668711|223344556677885f5f5f5f5f5f	64	gnu	xchg %dx,(%rcx)
+668711|223344556677885f5f5f5f5f5f	64	intel	xchg word ptr [rcx], dx
+668711|223344556677885f5f5f5f5f5f	64	plan9	XCHGW DX, 0(CX)
+668911|223344556677885f5f5f5f5f5f	32	intel	mov word ptr [ecx], dx
+668911|223344556677885f5f5f5f5f5f	32	plan9	MOVW DX, 0(CX)
+668911|223344556677885f5f5f5f5f5f	64	gnu	mov %dx,(%rcx)
+668911|223344556677885f5f5f5f5f5f	64	intel	mov word ptr [rcx], dx
+668911|223344556677885f5f5f5f5f5f	64	plan9	MOVW DX, 0(CX)
+668b11|223344556677885f5f5f5f5f5f	32	intel	mov dx, word ptr [ecx]
+668b11|223344556677885f5f5f5f5f5f	32	plan9	MOVW 0(CX), DX
+668b11|223344556677885f5f5f5f5f5f	64	gnu	mov (%rcx),%dx
+668b11|223344556677885f5f5f5f5f5f	64	intel	mov dx, word ptr [rcx]
+668b11|223344556677885f5f5f5f5f5f	64	plan9	MOVW 0(CX), DX
+668c11|223344556677885f5f5f5f5f5f	32	intel	mov word ptr [ecx], ss
+668c11|223344556677885f5f5f5f5f5f	32	plan9	MOVW SS, 0(CX)
+668c11|223344556677885f5f5f5f5f5f	64	gnu	data16 mov %ss,(%rcx)
+668c11|223344556677885f5f5f5f5f5f	64	intel	mov word ptr [rcx], ss
+668c11|223344556677885f5f5f5f5f5f	64	plan9	MOVW SS, 0(CX)
+668d11|223344556677885f5f5f5f5f5f	32	intel	lea dx, ptr [ecx]
+668d11|223344556677885f5f5f5f5f5f	32	plan9	LEAW 0(CX), DX
+668d11|223344556677885f5f5f5f5f5f	64	gnu	lea (%rcx),%dx
+668d11|223344556677885f5f5f5f5f5f	64	intel	lea dx, ptr [rcx]
+668d11|223344556677885f5f5f5f5f5f	64	plan9	LEAW 0(CX), DX
+668ec0|11223344556677885f5f5f5f5f	32	intel	mov es, ax
+668ec0|11223344556677885f5f5f5f5f	32	plan9	MOVW AX, ES
+668ec0|11223344556677885f5f5f5f5f	64	gnu	mov %ax,%es
+668ec0|11223344556677885f5f5f5f5f	64	intel	mov es, ax
+668ec0|11223344556677885f5f5f5f5f	64	plan9	MOVW AX, ES
+668f00|11223344556677885f5f5f5f5f	32	intel	pop word ptr [eax]
+668f00|11223344556677885f5f5f5f5f	32	plan9	POPW 0(AX)
+668f00|11223344556677885f5f5f5f5f	64	gnu	popw (%rax)
+668f00|11223344556677885f5f5f5f5f	64	intel	pop word ptr [rax]
+668f00|11223344556677885f5f5f5f5f	64	plan9	POPW 0(AX)
+6690|11223344556677885f5f5f5f5f5f	32	plan9	NOPW
+6690|11223344556677885f5f5f5f5f5f	64	gnu	data16 nop
+6690|11223344556677885f5f5f5f5f5f	64	plan9	NOPW
+6698|11223344556677885f5f5f5f5f5f	32	intel	data16 cbw
+6698|11223344556677885f5f5f5f5f5f	32	plan9	CBW
+6698|11223344556677885f5f5f5f5f5f	64	gnu	cbtw
+6698|11223344556677885f5f5f5f5f5f	64	intel	data16 cbw
+6698|11223344556677885f5f5f5f5f5f	64	plan9	CBW
+6699|11223344556677885f5f5f5f5f5f	32	intel	data16 cwd
+6699|11223344556677885f5f5f5f5f5f	32	plan9	CWD
+6699|11223344556677885f5f5f5f5f5f	64	gnu	cwtd
+6699|11223344556677885f5f5f5f5f5f	64	intel	data16 cwd
+6699|11223344556677885f5f5f5f5f5f	64	plan9	CWD
+669a11223344|556677885f5f5f5f5f5f	32	intel	call far 0x2211, 0x4433
+669a11223344|556677885f5f5f5f5f5f	32	plan9	LCALL $0x2211, $0x4433
+669c|11223344556677885f5f5f5f5f5f	32	intel	data16 pushf
+669c|11223344556677885f5f5f5f5f5f	32	plan9	PUSHF
+669c|11223344556677885f5f5f5f5f5f	64	gnu	pushfw
+669c|11223344556677885f5f5f5f5f5f	64	intel	data16 pushf
+669c|11223344556677885f5f5f5f5f5f	64	plan9	PUSHF
+669d|11223344556677885f5f5f5f5f5f	32	intel	data16 popf
+669d|11223344556677885f5f5f5f5f5f	32	plan9	POPF
+669d|11223344556677885f5f5f5f5f5f	64	gnu	popfw
+669d|11223344556677885f5f5f5f5f5f	64	intel	data16 popf
+669d|11223344556677885f5f5f5f5f5f	64	plan9	POPF
+66a11122334455667788|5f5f5f5f5f5f	64	gnu	mov -0x778899aabbccddef,%ax
+66a11122334455667788|5f5f5f5f5f5f	64	intel	mov ax, word ptr [0x8877665544332211]
+66a11122334455667788|5f5f5f5f5f5f	64	plan9	MOVW -0x778899aabbccddef, AX
+66a111223344|556677885f5f5f5f5f5f	32	intel	mov ax, word ptr [0x44332211]
+66a111223344|556677885f5f5f5f5f5f	32	plan9	MOVW 0x44332211, AX
+66a31122334455667788|5f5f5f5f5f5f	64	gnu	mov %ax,-0x778899aabbccddef
+66a31122334455667788|5f5f5f5f5f5f	64	intel	mov word ptr [0x8877665544332211], ax
+66a31122334455667788|5f5f5f5f5f5f	64	plan9	MOVW AX, -0x778899aabbccddef
+66a311223344|556677885f5f5f5f5f5f	32	intel	mov word ptr [0x44332211], ax
+66a311223344|556677885f5f5f5f5f5f	32	plan9	MOVW AX, 0x44332211
+66a5|11223344556677885f5f5f5f5f5f	32	intel	movsw word ptr [edi], word ptr [esi]
+66a5|11223344556677885f5f5f5f5f5f	32	plan9	MOVSW DS:0(SI), ES:0(DI)
+66a5|11223344556677885f5f5f5f5f5f	64	gnu	movsw %ds:(%rsi),%es:(%rdi)
+66a5|11223344556677885f5f5f5f5f5f	64	intel	movsw word ptr [rdi], word ptr [rsi]
+66a5|11223344556677885f5f5f5f5f5f	64	plan9	MOVSW DS:0(SI), ES:0(DI)
+66a7|11223344556677885f5f5f5f5f5f	32	intel	cmpsw word ptr [esi], word ptr [edi]
+66a7|11223344556677885f5f5f5f5f5f	32	plan9	CMPSW ES:0(DI), DS:0(SI)
+66a7|11223344556677885f5f5f5f5f5f	64	gnu	cmpsw %es:(%rdi),%ds:(%rsi)
+66a7|11223344556677885f5f5f5f5f5f	64	intel	cmpsw word ptr [rsi], word ptr [rdi]
+66a7|11223344556677885f5f5f5f5f5f	64	plan9	CMPSW ES:0(DI), DS:0(SI)
+66a91122|3344556677885f5f5f5f5f5f	32	intel	test ax, 0x2211
+66a91122|3344556677885f5f5f5f5f5f	32	plan9	TESTW $0x2211, AX
+66a91122|3344556677885f5f5f5f5f5f	64	gnu	test $0x2211,%ax
+66a91122|3344556677885f5f5f5f5f5f	64	intel	test ax, 0x2211
+66a91122|3344556677885f5f5f5f5f5f	64	plan9	TESTW $0x2211, AX
+66ab|11223344556677885f5f5f5f5f5f	32	intel	stosw word ptr [edi]
+66ab|11223344556677885f5f5f5f5f5f	32	plan9	STOSW AX, ES:0(DI)
+66ab|11223344556677885f5f5f5f5f5f	64	gnu	stos %ax,%es:(%rdi)
+66ab|11223344556677885f5f5f5f5f5f	64	intel	stosw word ptr [rdi]
+66ab|11223344556677885f5f5f5f5f5f	64	plan9	STOSW AX, ES:0(DI)
+66ad|11223344556677885f5f5f5f5f5f	32	intel	lodsw word ptr [esi]
+66ad|11223344556677885f5f5f5f5f5f	32	plan9	LODSW DS:0(SI), AX
+66ad|11223344556677885f5f5f5f5f5f	64	gnu	lods %ds:(%rsi),%ax
+66ad|11223344556677885f5f5f5f5f5f	64	intel	lodsw word ptr [rsi]
+66ad|11223344556677885f5f5f5f5f5f	64	plan9	LODSW DS:0(SI), AX
+66af|11223344556677885f5f5f5f5f5f	32	intel	scasw word ptr [edi]
+66af|11223344556677885f5f5f5f5f5f	32	plan9	SCASW ES:0(DI), AX
+66af|11223344556677885f5f5f5f5f5f	64	gnu	scas %es:(%rdi),%ax
+66af|11223344556677885f5f5f5f5f5f	64	intel	scasw word ptr [rdi]
+66af|11223344556677885f5f5f5f5f5f	64	plan9	SCASW ES:0(DI), AX
+66b81122|3344556677885f5f5f5f5f5f	32	intel	mov ax, 0x2211
+66b81122|3344556677885f5f5f5f5f5f	32	plan9	MOVW $0x2211, AX
+66b81122|3344556677885f5f5f5f5f5f	64	gnu	mov $0x2211,%ax
+66b81122|3344556677885f5f5f5f5f5f	64	intel	mov ax, 0x2211
+66b81122|3344556677885f5f5f5f5f5f	64	plan9	MOVW $0x2211, AX
+66c10011|223344556677885f5f5f5f5f	32	intel	rol word ptr [eax], 0x11
+66c10011|223344556677885f5f5f5f5f	32	plan9	ROLW $0x11, 0(AX)
+66c10011|223344556677885f5f5f5f5f	64	gnu	rolw $0x11,(%rax)
+66c10011|223344556677885f5f5f5f5f	64	intel	rol word ptr [rax], 0x11
+66c10011|223344556677885f5f5f5f5f	64	plan9	ROLW $0x11, 0(AX)
+66c10811|223344556677885f5f5f5f5f	32	intel	ror word ptr [eax], 0x11
+66c10811|223344556677885f5f5f5f5f	32	plan9	RORW $0x11, 0(AX)
+66c10811|223344556677885f5f5f5f5f	64	gnu	rorw $0x11,(%rax)
+66c10811|223344556677885f5f5f5f5f	64	intel	ror word ptr [rax], 0x11
+66c10811|223344556677885f5f5f5f5f	64	plan9	RORW $0x11, 0(AX)
+66c11122|3344556677885f5f5f5f5f5f	32	intel	rcl word ptr [ecx], 0x22
+66c11122|3344556677885f5f5f5f5f5f	32	plan9	RCLW $0x22, 0(CX)
+66c11122|3344556677885f5f5f5f5f5f	64	gnu	rclw $0x22,(%rcx)
+66c11122|3344556677885f5f5f5f5f5f	64	intel	rcl word ptr [rcx], 0x22
+66c11122|3344556677885f5f5f5f5f5f	64	plan9	RCLW $0x22, 0(CX)
+66c11811|223344556677885f5f5f5f5f	32	intel	rcr word ptr [eax], 0x11
+66c11811|223344556677885f5f5f5f5f	32	plan9	RCRW $0x11, 0(AX)
+66c11811|223344556677885f5f5f5f5f	64	gnu	rcrw $0x11,(%rax)
+66c11811|223344556677885f5f5f5f5f	64	intel	rcr word ptr [rax], 0x11
+66c11811|223344556677885f5f5f5f5f	64	plan9	RCRW $0x11, 0(AX)
+66c12011|223344556677885f5f5f5f5f	32	intel	shl word ptr [eax], 0x11
+66c12011|223344556677885f5f5f5f5f	32	plan9	SHLW $0x11, 0(AX)
+66c12011|223344556677885f5f5f5f5f	64	gnu	shlw $0x11,(%rax)
+66c12011|223344556677885f5f5f5f5f	64	intel	shl word ptr [rax], 0x11
+66c12011|223344556677885f5f5f5f5f	64	plan9	SHLW $0x11, 0(AX)
+66c12811|223344556677885f5f5f5f5f	32	intel	shr word ptr [eax], 0x11
+66c12811|223344556677885f5f5f5f5f	32	plan9	SHRW $0x11, 0(AX)
+66c12811|223344556677885f5f5f5f5f	64	gnu	shrw $0x11,(%rax)
+66c12811|223344556677885f5f5f5f5f	64	intel	shr word ptr [rax], 0x11
+66c12811|223344556677885f5f5f5f5f	64	plan9	SHRW $0x11, 0(AX)
+66c13811|223344556677885f5f5f5f5f	32	intel	sar word ptr [eax], 0x11
+66c13811|223344556677885f5f5f5f5f	32	plan9	SARW $0x11, 0(AX)
+66c13811|223344556677885f5f5f5f5f	64	gnu	sarw $0x11,(%rax)
+66c13811|223344556677885f5f5f5f5f	64	intel	sar word ptr [rax], 0x11
+66c13811|223344556677885f5f5f5f5f	64	plan9	SARW $0x11, 0(AX)
+66c21122|3344556677885f5f5f5f5f5f	32	intel	ret 0x2211
+66c21122|3344556677885f5f5f5f5f5f	32	plan9	RET $0x2211
+66c21122|3344556677885f5f5f5f5f5f	64	gnu	retw $0x2211
+66c21122|3344556677885f5f5f5f5f5f	64	intel	ret 0x2211
+66c21122|3344556677885f5f5f5f5f5f	64	plan9	RET $0x2211
+66c411|223344556677885f5f5f5f5f5f	32	intel	les dx, dword ptr [ecx]
+66c411|223344556677885f5f5f5f5f5f	32	plan9	LES 0(CX), DX
+66c511|223344556677885f5f5f5f5f5f	32	intel	lds dx, dword ptr [ecx]
+66c511|223344556677885f5f5f5f5f5f	32	plan9	LDS 0(CX), DX
+66c7001122|3344556677885f5f5f5f5f	32	intel	mov word ptr [eax], 0x2211
+66c7001122|3344556677885f5f5f5f5f	32	plan9	MOVW $0x2211, 0(AX)
+66c7001122|3344556677885f5f5f5f5f	64	gnu	movw $0x2211,(%rax)
+66c7001122|3344556677885f5f5f5f5f	64	intel	mov word ptr [rax], 0x2211
+66c7001122|3344556677885f5f5f5f5f	64	plan9	MOVW $0x2211, 0(AX)
+66c7f81122|3344556677885f5f5f5f5f	32	intel	xbegin .+0x2211
+66c7f81122|3344556677885f5f5f5f5f	32	plan9	XBEGIN .+8721
+66c7f81122|3344556677885f5f5f5f5f	64	gnu	xbeginw .+0x2211
+66c7f81122|3344556677885f5f5f5f5f	64	intel	xbegin .+0x2211
+66c7f81122|3344556677885f5f5f5f5f	64	plan9	XBEGIN .+8721
+66c9|11223344556677885f5f5f5f5f5f	32	intel	data16 leave
+66c9|11223344556677885f5f5f5f5f5f	32	plan9	LEAVE
+66c9|11223344556677885f5f5f5f5f5f	64	gnu	leavew
+66c9|11223344556677885f5f5f5f5f5f	64	intel	data16 leave
+66c9|11223344556677885f5f5f5f5f5f	64	plan9	LEAVE
+66cf|11223344556677885f5f5f5f5f5f	32	intel	data16 iret
+66cf|11223344556677885f5f5f5f5f5f	32	plan9	IRET
+66cf|11223344556677885f5f5f5f5f5f	64	gnu	iretw
+66cf|11223344556677885f5f5f5f5f5f	64	intel	data16 iret
+66cf|11223344556677885f5f5f5f5f5f	64	plan9	IRET
+66d100|11223344556677885f5f5f5f5f	32	intel	rol word ptr [eax], 0x1
+66d100|11223344556677885f5f5f5f5f	32	plan9	ROLW $0x1, 0(AX)
+66d100|11223344556677885f5f5f5f5f	64	gnu	rolw (%rax)
+66d100|11223344556677885f5f5f5f5f	64	intel	rol word ptr [rax], 0x1
+66d100|11223344556677885f5f5f5f5f	64	plan9	ROLW $0x1, 0(AX)
+66d108|11223344556677885f5f5f5f5f	32	intel	ror word ptr [eax], 0x1
+66d108|11223344556677885f5f5f5f5f	32	plan9	RORW $0x1, 0(AX)
+66d108|11223344556677885f5f5f5f5f	64	gnu	rorw (%rax)
+66d108|11223344556677885f5f5f5f5f	64	intel	ror word ptr [rax], 0x1
+66d108|11223344556677885f5f5f5f5f	64	plan9	RORW $0x1, 0(AX)
+66d111|223344556677885f5f5f5f5f5f	32	intel	rcl word ptr [ecx], 0x1
+66d111|223344556677885f5f5f5f5f5f	32	plan9	RCLW $0x1, 0(CX)
+66d111|223344556677885f5f5f5f5f5f	64	gnu	rclw (%rcx)
+66d111|223344556677885f5f5f5f5f5f	64	intel	rcl word ptr [rcx], 0x1
+66d111|223344556677885f5f5f5f5f5f	64	plan9	RCLW $0x1, 0(CX)
+66d118|11223344556677885f5f5f5f5f	32	intel	rcr word ptr [eax], 0x1
+66d118|11223344556677885f5f5f5f5f	32	plan9	RCRW $0x1, 0(AX)
+66d118|11223344556677885f5f5f5f5f	64	gnu	rcrw (%rax)
+66d118|11223344556677885f5f5f5f5f	64	intel	rcr word ptr [rax], 0x1
+66d118|11223344556677885f5f5f5f5f	64	plan9	RCRW $0x1, 0(AX)
+66d120|11223344556677885f5f5f5f5f	32	intel	shl word ptr [eax], 0x1
+66d120|11223344556677885f5f5f5f5f	32	plan9	SHLW $0x1, 0(AX)
+66d120|11223344556677885f5f5f5f5f	64	gnu	shlw (%rax)
+66d120|11223344556677885f5f5f5f5f	64	intel	shl word ptr [rax], 0x1
+66d120|11223344556677885f5f5f5f5f	64	plan9	SHLW $0x1, 0(AX)
+66d128|11223344556677885f5f5f5f5f	32	intel	shr word ptr [eax], 0x1
+66d128|11223344556677885f5f5f5f5f	32	plan9	SHRW $0x1, 0(AX)
+66d128|11223344556677885f5f5f5f5f	64	gnu	shrw (%rax)
+66d128|11223344556677885f5f5f5f5f	64	intel	shr word ptr [rax], 0x1
+66d128|11223344556677885f5f5f5f5f	64	plan9	SHRW $0x1, 0(AX)
+66d138|11223344556677885f5f5f5f5f	32	intel	sar word ptr [eax], 0x1
+66d138|11223344556677885f5f5f5f5f	32	plan9	SARW $0x1, 0(AX)
+66d138|11223344556677885f5f5f5f5f	64	gnu	sarw (%rax)
+66d138|11223344556677885f5f5f5f5f	64	intel	sar word ptr [rax], 0x1
+66d138|11223344556677885f5f5f5f5f	64	plan9	SARW $0x1, 0(AX)
+66d300|11223344556677885f5f5f5f5f	32	intel	rol word ptr [eax], cl
+66d300|11223344556677885f5f5f5f5f	32	plan9	ROLW CL, 0(AX)
+66d300|11223344556677885f5f5f5f5f	64	gnu	rolw %cl,(%rax)
+66d300|11223344556677885f5f5f5f5f	64	intel	rol word ptr [rax], cl
+66d300|11223344556677885f5f5f5f5f	64	plan9	ROLW CL, 0(AX)
+66d308|11223344556677885f5f5f5f5f	32	intel	ror word ptr [eax], cl
+66d308|11223344556677885f5f5f5f5f	32	plan9	RORW CL, 0(AX)
+66d308|11223344556677885f5f5f5f5f	64	gnu	rorw %cl,(%rax)
+66d308|11223344556677885f5f5f5f5f	64	intel	ror word ptr [rax], cl
+66d308|11223344556677885f5f5f5f5f	64	plan9	RORW CL, 0(AX)
+66d311|223344556677885f5f5f5f5f5f	32	intel	rcl word ptr [ecx], cl
+66d311|223344556677885f5f5f5f5f5f	32	plan9	RCLW CL, 0(CX)
+66d311|223344556677885f5f5f5f5f5f	64	gnu	rclw %cl,(%rcx)
+66d311|223344556677885f5f5f5f5f5f	64	intel	rcl word ptr [rcx], cl
+66d311|223344556677885f5f5f5f5f5f	64	plan9	RCLW CL, 0(CX)
+66d318|11223344556677885f5f5f5f5f	32	intel	rcr word ptr [eax], cl
+66d318|11223344556677885f5f5f5f5f	32	plan9	RCRW CL, 0(AX)
+66d318|11223344556677885f5f5f5f5f	64	gnu	rcrw %cl,(%rax)
+66d318|11223344556677885f5f5f5f5f	64	intel	rcr word ptr [rax], cl
+66d318|11223344556677885f5f5f5f5f	64	plan9	RCRW CL, 0(AX)
+66d320|11223344556677885f5f5f5f5f	32	intel	shl word ptr [eax], cl
+66d320|11223344556677885f5f5f5f5f	32	plan9	SHLW CL, 0(AX)
+66d320|11223344556677885f5f5f5f5f	64	gnu	shlw %cl,(%rax)
+66d320|11223344556677885f5f5f5f5f	64	intel	shl word ptr [rax], cl
+66d320|11223344556677885f5f5f5f5f	64	plan9	SHLW CL, 0(AX)
+66d328|11223344556677885f5f5f5f5f	32	intel	shr word ptr [eax], cl
+66d328|11223344556677885f5f5f5f5f	32	plan9	SHRW CL, 0(AX)
+66d328|11223344556677885f5f5f5f5f	64	gnu	shrw %cl,(%rax)
+66d328|11223344556677885f5f5f5f5f	64	intel	shr word ptr [rax], cl
+66d328|11223344556677885f5f5f5f5f	64	plan9	SHRW CL, 0(AX)
+66d338|11223344556677885f5f5f5f5f	32	intel	sar word ptr [eax], cl
+66d338|11223344556677885f5f5f5f5f	32	plan9	SARW CL, 0(AX)
+66d338|11223344556677885f5f5f5f5f	64	gnu	sarw %cl,(%rax)
+66d338|11223344556677885f5f5f5f5f	64	intel	sar word ptr [rax], cl
+66d338|11223344556677885f5f5f5f5f	64	plan9	SARW CL, 0(AX)
+66d411|223344556677885f5f5f5f5f5f	32	intel	aam 0x11
+66d411|223344556677885f5f5f5f5f5f	32	plan9	AAM $0x11
+66d920|11223344556677885f5f5f5f5f	32	intel	fldenv ptr [eax]
+66d920|11223344556677885f5f5f5f5f	32	plan9	FLDENVW 0(AX)
+66d920|11223344556677885f5f5f5f5f	64	gnu	fldenvs (%rax)
+66d920|11223344556677885f5f5f5f5f	64	intel	fldenv ptr [rax]
+66d920|11223344556677885f5f5f5f5f	64	plan9	FLDENVW 0(AX)
+66e511|223344556677885f5f5f5f5f5f	32	intel	in ax, 0x11
+66e511|223344556677885f5f5f5f5f5f	32	plan9	INW $0x11, AX
+66e511|223344556677885f5f5f5f5f5f	64	gnu	in $0x11,%ax
+66e511|223344556677885f5f5f5f5f5f	64	intel	in ax, 0x11
+66e511|223344556677885f5f5f5f5f5f	64	plan9	INW $0x11, AX
+66e711|223344556677885f5f5f5f5f5f	32	intel	out 0x11, ax
+66e711|223344556677885f5f5f5f5f5f	32	plan9	OUTW AX, $0x11
+66e711|223344556677885f5f5f5f5f5f	64	gnu	out %ax,$0x11
+66e711|223344556677885f5f5f5f5f5f	64	intel	out 0x11, ax
+66e711|223344556677885f5f5f5f5f5f	64	plan9	OUTW AX, $0x11
+66e811223344|556677885f5f5f5f5f5f	64	gnu	callw .+0x44332211
+66e811223344|556677885f5f5f5f5f5f	64	intel	call .+0x44332211
+66e811223344|556677885f5f5f5f5f5f	64	plan9	CALL .+1144201745
+66e81122|3344556677885f5f5f5f5f5f	32	intel	call .+0x2211
+66e81122|3344556677885f5f5f5f5f5f	32	plan9	CALL .+8721
+66e911223344|556677885f5f5f5f5f5f	64	gnu	jmpw .+0x44332211
+66e911223344|556677885f5f5f5f5f5f	64	intel	jmp .+0x44332211
+66e911223344|556677885f5f5f5f5f5f	64	plan9	JMP .+1144201745
+66e91122|3344556677885f5f5f5f5f5f	32	intel	jmp .+0x2211
+66e91122|3344556677885f5f5f5f5f5f	32	plan9	JMP .+8721
+66ea11223344|556677885f5f5f5f5f5f	32	intel	jmp far 0x2211, 0x4433
+66ea11223344|556677885f5f5f5f5f5f	32	plan9	LJMP $0x2211, $0x4433
+66ed|11223344556677885f5f5f5f5f5f	32	intel	in ax, dx
+66ed|11223344556677885f5f5f5f5f5f	32	plan9	INW DX, AX
+66ed|11223344556677885f5f5f5f5f5f	64	gnu	in (%dx),%ax
+66ed|11223344556677885f5f5f5f5f5f	64	intel	in ax, dx
+66ed|11223344556677885f5f5f5f5f5f	64	plan9	INW DX, AX
+66ef|11223344556677885f5f5f5f5f5f	32	intel	out dx, ax
+66ef|11223344556677885f5f5f5f5f5f	32	plan9	OUTW AX, DX
+66ef|11223344556677885f5f5f5f5f5f	64	gnu	out %ax,(%dx)
+66ef|11223344556677885f5f5f5f5f5f	64	intel	out dx, ax
+66ef|11223344556677885f5f5f5f5f5f	64	plan9	OUTW AX, DX
+66f20f2a11|223344556677885f5f5f5f	32	intel	cvtsi2sd xmm2, dword ptr [ecx]
+66f20f2a11|223344556677885f5f5f5f	32	plan9	REPNE CVTSI2SDW 0(CX), X2
+66f20f2a11|223344556677885f5f5f5f	64	gnu	cvtsi2sdl (%rcx),%xmm2
+66f20f2a11|223344556677885f5f5f5f	64	intel	cvtsi2sd xmm2, dword ptr [rcx]
+66f20f2a11|223344556677885f5f5f5f	64	plan9	REPNE CVTSI2SDW 0(CX), X2
+66f20f2c11|223344556677885f5f5f5f	32	intel	cvttsd2si edx, qword ptr [ecx]
+66f20f2c11|223344556677885f5f5f5f	32	plan9	REPNE CVTTSD2SIW 0(CX), DX
+66f20f2c11|223344556677885f5f5f5f	64	gnu	cvttsd2si (%rcx),%dx
+66f20f2c11|223344556677885f5f5f5f	64	intel	cvttsd2si edx, qword ptr [rcx]
+66f20f2c11|223344556677885f5f5f5f	64	plan9	REPNE CVTTSD2SIW 0(CX), DX
+66f20f2d11|223344556677885f5f5f5f	32	intel	cvtsd2si edx, qword ptr [ecx]
+66f20f2d11|223344556677885f5f5f5f	32	plan9	REPNE CVTSD2SIW 0(CX), DX
+66f20f2d11|223344556677885f5f5f5f	64	gnu	cvtsd2si (%rcx),%dx
+66f20f2d11|223344556677885f5f5f5f	64	intel	cvtsd2si edx, qword ptr [rcx]
+66f20f2d11|223344556677885f5f5f5f	64	plan9	REPNE CVTSD2SIW 0(CX), DX
+66f20f38f011|223344556677885f5f5f	32	intel	crc32 edx, byte ptr [ecx]
+66f20f38f011|223344556677885f5f5f	32	plan9	REPNE CRC32 0(CX), DX
+66f20f38f011|223344556677885f5f5f	64	gnu	crc32b (%rcx),%edx
+66f20f38f011|223344556677885f5f5f	64	intel	crc32 edx, byte ptr [rcx]
+66f20f38f011|223344556677885f5f5f	64	plan9	REPNE CRC32 0(CX), DX
+66f30f2c11|223344556677885f5f5f5f	32	intel	cvttss2si edx, dword ptr [ecx]
+66f30f2c11|223344556677885f5f5f5f	32	plan9	REP CVTTSS2SIW 0(CX), DX
+66f30f2c11|223344556677885f5f5f5f	64	gnu	cvttss2si (%rcx),%dx
+66f30f2c11|223344556677885f5f5f5f	64	intel	cvttss2si edx, dword ptr [rcx]
+66f30f2c11|223344556677885f5f5f5f	64	plan9	REP CVTTSS2SIW 0(CX), DX
+66f30f2d11|223344556677885f5f5f5f	32	intel	cvtss2si edx, dword ptr [ecx]
+66f30f2d11|223344556677885f5f5f5f	32	plan9	REP CVTSS2SIW 0(CX), DX
+66f30f2d11|223344556677885f5f5f5f	64	gnu	cvtss2si (%rcx),%dx
+66f30f2d11|223344556677885f5f5f5f	64	intel	cvtss2si edx, dword ptr [rcx]
+66f30f2d11|223344556677885f5f5f5f	64	plan9	REP CVTSS2SIW 0(CX), DX
+66f30fae11|223344556677885f5f5f5f	64	gnu	wrfsbasel (%rcx)
+66f30fae11|223344556677885f5f5f5f	64	intel	wrfsbase dword ptr [rcx]
+66f30fae11|223344556677885f5f5f5f	64	plan9	REP WRFSBASE 0(CX)
+66f30fae18|11223344556677885f5f5f	64	gnu	wrgsbasel (%rax)
+66f30fae18|11223344556677885f5f5f	64	intel	wrgsbase dword ptr [rax]
+66f30fae18|11223344556677885f5f5f	64	plan9	REP WRGSBASE 0(AX)
+66f30faec0|11223344556677885f5f5f	64	gnu	rdfsbase %eax
+66f30faec0|11223344556677885f5f5f	64	intel	rdfsbase eax
+66f30faec0|11223344556677885f5f5f	64	plan9	REP RDFSBASE AX
+66f30faec8|11223344556677885f5f5f	64	gnu	rdgsbase %eax
+66f30faec8|11223344556677885f5f5f	64	intel	rdgsbase eax
+66f30faec8|11223344556677885f5f5f	64	plan9	REP RDGSBASE AX
+66f30fd6c5|11223344556677885f5f5f	32	intel	movq2dq xmm0, mmx5
+66f30fd6c5|11223344556677885f5f5f	32	plan9	REP MOVQ2DQ M5, X0
+66f30fd6c5|11223344556677885f5f5f	64	gnu	movq2dq %mm5,%xmm0
+66f30fd6c5|11223344556677885f5f5f	64	intel	movq2dq xmm0, mmx5
+66f30fd6c5|11223344556677885f5f5f	64	plan9	REP MOVQ2DQ M5, X0
+66f7001122|3344556677885f5f5f5f5f	32	intel	test word ptr [eax], 0x2211
+66f7001122|3344556677885f5f5f5f5f	32	plan9	TESTW $0x2211, 0(AX)
+66f7001122|3344556677885f5f5f5f5f	64	gnu	testw $0x2211,(%rax)
+66f7001122|3344556677885f5f5f5f5f	64	intel	test word ptr [rax], 0x2211
+66f7001122|3344556677885f5f5f5f5f	64	plan9	TESTW $0x2211, 0(AX)
+66f711|223344556677885f5f5f5f5f5f	32	intel	not word ptr [ecx]
+66f711|223344556677885f5f5f5f5f5f	32	plan9	NOTW 0(CX)
+66f711|223344556677885f5f5f5f5f5f	64	gnu	notw (%rcx)
+66f711|223344556677885f5f5f5f5f5f	64	intel	not word ptr [rcx]
+66f711|223344556677885f5f5f5f5f5f	64	plan9	NOTW 0(CX)
+66f718|11223344556677885f5f5f5f5f	32	intel	neg word ptr [eax]
+66f718|11223344556677885f5f5f5f5f	32	plan9	NEGW 0(AX)
+66f718|11223344556677885f5f5f5f5f	64	gnu	negw (%rax)
+66f718|11223344556677885f5f5f5f5f	64	intel	neg word ptr [rax]
+66f718|11223344556677885f5f5f5f5f	64	plan9	NEGW 0(AX)
+66f720|11223344556677885f5f5f5f5f	32	intel	mul word ptr [eax]
+66f720|11223344556677885f5f5f5f5f	32	plan9	MULW 0(AX)
+66f720|11223344556677885f5f5f5f5f	64	gnu	mulw (%rax)
+66f720|11223344556677885f5f5f5f5f	64	intel	mul word ptr [rax]
+66f720|11223344556677885f5f5f5f5f	64	plan9	MULW 0(AX)
+66f728|11223344556677885f5f5f5f5f	32	intel	imul word ptr [eax]
+66f728|11223344556677885f5f5f5f5f	32	plan9	IMULW 0(AX)
+66f728|11223344556677885f5f5f5f5f	64	gnu	imulw (%rax)
+66f728|11223344556677885f5f5f5f5f	64	intel	imul word ptr [rax]
+66f728|11223344556677885f5f5f5f5f	64	plan9	IMULW 0(AX)
+66f730|11223344556677885f5f5f5f5f	32	intel	div word ptr [eax]
+66f730|11223344556677885f5f5f5f5f	32	plan9	DIVW 0(AX)
+66f730|11223344556677885f5f5f5f5f	64	gnu	divw (%rax)
+66f730|11223344556677885f5f5f5f5f	64	intel	div word ptr [rax]
+66f730|11223344556677885f5f5f5f5f	64	plan9	DIVW 0(AX)
+66f738|11223344556677885f5f5f5f5f	32	intel	idiv word ptr [eax]
+66f738|11223344556677885f5f5f5f5f	32	plan9	IDIVW 0(AX)
+66f738|11223344556677885f5f5f5f5f	64	gnu	idivw (%rax)
+66f738|11223344556677885f5f5f5f5f	64	intel	idiv word ptr [rax]
+66f738|11223344556677885f5f5f5f5f	64	plan9	IDIVW 0(AX)
+66ff00|11223344556677885f5f5f5f5f	32	intel	inc word ptr [eax]
+66ff00|11223344556677885f5f5f5f5f	32	plan9	INCW 0(AX)
+66ff00|11223344556677885f5f5f5f5f	64	gnu	incw (%rax)
+66ff00|11223344556677885f5f5f5f5f	64	intel	inc word ptr [rax]
+66ff00|11223344556677885f5f5f5f5f	64	plan9	INCW 0(AX)
+66ff08|11223344556677885f5f5f5f5f	32	intel	dec word ptr [eax]
+66ff08|11223344556677885f5f5f5f5f	32	plan9	DECW 0(AX)
+66ff08|11223344556677885f5f5f5f5f	64	gnu	decw (%rax)
+66ff08|11223344556677885f5f5f5f5f	64	intel	dec word ptr [rax]
+66ff08|11223344556677885f5f5f5f5f	64	plan9	DECW 0(AX)
+66ff11|223344556677885f5f5f5f5f5f	32	intel	call word ptr [ecx]
+66ff11|223344556677885f5f5f5f5f5f	32	plan9	CALL 0(CX)
+66ff11|223344556677885f5f5f5f5f5f	64	gnu	callw *(%rcx)
+66ff11|223344556677885f5f5f5f5f5f	64	intel	call qword ptr [rcx]
+66ff11|223344556677885f5f5f5f5f5f	64	plan9	CALL 0(CX)
+66ff18|11223344556677885f5f5f5f5f	32	intel	call far dword ptr [eax]
+66ff18|11223344556677885f5f5f5f5f	32	plan9	LCALL 0(AX)
+66ff18|11223344556677885f5f5f5f5f	64	gnu	lcallw *(%rax)
+66ff18|11223344556677885f5f5f5f5f	64	intel	call far dword ptr [rax]
+66ff18|11223344556677885f5f5f5f5f	64	plan9	LCALL 0(AX)
+66ff20|11223344556677885f5f5f5f5f	32	intel	jmp word ptr [eax]
+66ff20|11223344556677885f5f5f5f5f	32	plan9	JMP 0(AX)
+66ff20|11223344556677885f5f5f5f5f	64	gnu	jmpw *(%rax)
+66ff20|11223344556677885f5f5f5f5f	64	intel	jmp qword ptr [rax]
+66ff20|11223344556677885f5f5f5f5f	64	plan9	JMP 0(AX)
+66ff28|11223344556677885f5f5f5f5f	32	intel	jmp far dword ptr [eax]
+66ff28|11223344556677885f5f5f5f5f	32	plan9	LJMP 0(AX)
+66ff28|11223344556677885f5f5f5f5f	64	gnu	ljmpw *(%rax)
+66ff28|11223344556677885f5f5f5f5f	64	intel	jmp far dword ptr [rax]
+66ff28|11223344556677885f5f5f5f5f	64	plan9	LJMP 0(AX)
+66ff30|11223344556677885f5f5f5f5f	32	intel	push word ptr [eax]
+66ff30|11223344556677885f5f5f5f5f	32	plan9	PUSHW 0(AX)
+66ff30|11223344556677885f5f5f5f5f	64	gnu	pushw (%rax)
+66ff30|11223344556677885f5f5f5f5f	64	intel	push word ptr [rax]
+66ff30|11223344556677885f5f5f5f5f	64	plan9	PUSHW 0(AX)
+66|9a11223344556677885f5f5f5f5f5f	64	gnu	data16
+66|9a11223344556677885f5f5f5f5f5f	64	intel	data16
+66|9a11223344556677885f5f5f5f5f5f	64	plan9	Op(0)
+66|c411223344556677885f5f5f5f5f5f	64	gnu	data16
+66|c411223344556677885f5f5f5f5f5f	64	intel	data16
+66|c411223344556677885f5f5f5f5f5f	64	plan9	Op(0)
+66|c511223344556677885f5f5f5f5f5f	64	gnu	data16
+66|c511223344556677885f5f5f5f5f5f	64	intel	data16
+66|c511223344556677885f5f5f5f5f5f	64	plan9	Op(0)
+66|d411223344556677885f5f5f5f5f5f	64	gnu	data16
+66|d411223344556677885f5f5f5f5f5f	64	intel	data16
+66|d411223344556677885f5f5f5f5f5f	64	plan9	Op(0)
+66|ea11223344556677885f5f5f5f5f5f	64	gnu	data16
+66|ea11223344556677885f5f5f5f5f5f	64	intel	data16
+66|ea11223344556677885f5f5f5f5f5f	64	plan9	Op(0)
+676c|11223344556677885f5f5f5f5f5f	32	intel	addr16 insb
+676c|11223344556677885f5f5f5f5f5f	32	plan9	INSB DX, ES:0(DI)
+676c|11223344556677885f5f5f5f5f5f	64	gnu	insb (%dx),%es:(%edi)
+676c|11223344556677885f5f5f5f5f5f	64	intel	addr32 insb
+676c|11223344556677885f5f5f5f5f5f	64	plan9	INSB DX, ES:0(DI)
+67d7|11223344556677885f5f5f5f5f5f	32	intel	addr16 xlat
+67d7|11223344556677885f5f5f5f5f5f	32	plan9	XLATB DS:0(BX)
+67d7|11223344556677885f5f5f5f5f5f	64	gnu	xlat %ds:(%ebx)
+67d7|11223344556677885f5f5f5f5f5f	64	intel	addr32 xlat
+67d7|11223344556677885f5f5f5f5f5f	64	plan9	XLATB DS:0(BX)
+67e311|223344556677885f5f5f5f5f5f	32	intel	addr16 jcxz .+0x11
+67e311|223344556677885f5f5f5f5f5f	32	plan9	JCXZ .+17
+67e311|223344556677885f5f5f5f5f5f	64	gnu	jecxz .+0x11
+67e311|223344556677885f5f5f5f5f5f	64	intel	addr32 jecxz .+0x11
+67e311|223344556677885f5f5f5f5f5f	64	plan9	JECXZ .+17
+6811223344|556677885f5f5f5f5f5f5f	32	intel	push 0x44332211
+6811223344|556677885f5f5f5f5f5f5f	32	plan9	PUSHL $0x44332211
+6811223344|556677885f5f5f5f5f5f5f	64	gnu	pushq $0x44332211
+6811223344|556677885f5f5f5f5f5f5f	64	intel	push 0x44332211
+6811223344|556677885f5f5f5f5f5f5f	64	plan9	PUSHL $0x44332211
+691122334455|6677885f5f5f5f5f5f5f	32	intel	imul edx, dword ptr [ecx], 0x55443322
+691122334455|6677885f5f5f5f5f5f5f	32	plan9	IMULL $0x55443322, 0(CX), DX
+691122334455|6677885f5f5f5f5f5f5f	64	gnu	imul $0x55443322,(%rcx),%edx
+691122334455|6677885f5f5f5f5f5f5f	64	intel	imul edx, dword ptr [rcx], 0x55443322
+691122334455|6677885f5f5f5f5f5f5f	64	plan9	IMULL $0x55443322, 0(CX), DX
+6a11|223344556677885f5f5f5f5f5f5f	32	intel	push 0x11
+6a11|223344556677885f5f5f5f5f5f5f	32	plan9	PUSHL $0x11
+6a11|223344556677885f5f5f5f5f5f5f	64	gnu	pushq $0x11
+6a11|223344556677885f5f5f5f5f5f5f	64	intel	push 0x11
+6a11|223344556677885f5f5f5f5f5f5f	64	plan9	PUSHL $0x11
+6b1122|3344556677885f5f5f5f5f5f5f	32	intel	imul edx, dword ptr [ecx], 0x22
+6b1122|3344556677885f5f5f5f5f5f5f	32	plan9	IMULL $0x22, 0(CX), DX
+6b1122|3344556677885f5f5f5f5f5f5f	64	gnu	imul $0x22,(%rcx),%edx
+6b1122|3344556677885f5f5f5f5f5f5f	64	intel	imul edx, dword ptr [rcx], 0x22
+6b1122|3344556677885f5f5f5f5f5f5f	64	plan9	IMULL $0x22, 0(CX), DX
+6d|11223344556677885f5f5f5f5f5f5f	32	intel	insd
+6d|11223344556677885f5f5f5f5f5f5f	32	plan9	INSD DX, ES:0(DI)
+6d|11223344556677885f5f5f5f5f5f5f	64	gnu	insl (%dx),%es:(%rdi)
+6d|11223344556677885f5f5f5f5f5f5f	64	intel	insd
+6d|11223344556677885f5f5f5f5f5f5f	64	plan9	INSD DX, ES:0(DI)
+6f|11223344556677885f5f5f5f5f5f5f	32	intel	outsd
+6f|11223344556677885f5f5f5f5f5f5f	32	plan9	OUTSD DS:0(SI), DX
+6f|11223344556677885f5f5f5f5f5f5f	64	gnu	outsl %ds:(%rsi),(%dx)
+6f|11223344556677885f5f5f5f5f5f5f	64	intel	outsd
+6f|11223344556677885f5f5f5f5f5f5f	64	plan9	OUTSD DS:0(SI), DX
+7111|223344556677885f5f5f5f5f5f5f	32	intel	jno .+0x11
+7111|223344556677885f5f5f5f5f5f5f	32	plan9	JNO .+17
+7111|223344556677885f5f5f5f5f5f5f	64	gnu	jno .+0x11
+7111|223344556677885f5f5f5f5f5f5f	64	intel	jno .+0x11
+7111|223344556677885f5f5f5f5f5f5f	64	plan9	JNO .+17
+7211|223344556677885f5f5f5f5f5f5f	32	intel	jb .+0x11
+7211|223344556677885f5f5f5f5f5f5f	32	plan9	JB .+17
+7211|223344556677885f5f5f5f5f5f5f	64	gnu	jb .+0x11
+7211|223344556677885f5f5f5f5f5f5f	64	intel	jb .+0x11
+7211|223344556677885f5f5f5f5f5f5f	64	plan9	JB .+17
+7311|223344556677885f5f5f5f5f5f5f	32	intel	jnb .+0x11
+7311|223344556677885f5f5f5f5f5f5f	32	plan9	JAE .+17
+7311|223344556677885f5f5f5f5f5f5f	64	gnu	jae .+0x11
+7311|223344556677885f5f5f5f5f5f5f	64	intel	jnb .+0x11
+7311|223344556677885f5f5f5f5f5f5f	64	plan9	JAE .+17
+7411|223344556677885f5f5f5f5f5f5f	32	intel	jz .+0x11
+7411|223344556677885f5f5f5f5f5f5f	32	plan9	JE .+17
+7411|223344556677885f5f5f5f5f5f5f	64	gnu	je .+0x11
+7411|223344556677885f5f5f5f5f5f5f	64	intel	jz .+0x11
+7411|223344556677885f5f5f5f5f5f5f	64	plan9	JE .+17
+7511|223344556677885f5f5f5f5f5f5f	32	intel	jnz .+0x11
+7511|223344556677885f5f5f5f5f5f5f	32	plan9	JNE .+17
+7511|223344556677885f5f5f5f5f5f5f	64	gnu	jne .+0x11
+7511|223344556677885f5f5f5f5f5f5f	64	intel	jnz .+0x11
+7511|223344556677885f5f5f5f5f5f5f	64	plan9	JNE .+17
+7611|223344556677885f5f5f5f5f5f5f	32	intel	jbe .+0x11
+7611|223344556677885f5f5f5f5f5f5f	32	plan9	JBE .+17
+7611|223344556677885f5f5f5f5f5f5f	64	gnu	jbe .+0x11
+7611|223344556677885f5f5f5f5f5f5f	64	intel	jbe .+0x11
+7611|223344556677885f5f5f5f5f5f5f	64	plan9	JBE .+17
+7711|223344556677885f5f5f5f5f5f5f	32	intel	jnbe .+0x11
+7711|223344556677885f5f5f5f5f5f5f	32	plan9	JA .+17
+7711|223344556677885f5f5f5f5f5f5f	64	gnu	ja .+0x11
+7711|223344556677885f5f5f5f5f5f5f	64	intel	jnbe .+0x11
+7711|223344556677885f5f5f5f5f5f5f	64	plan9	JA .+17
+7811|223344556677885f5f5f5f5f5f5f	32	intel	js .+0x11
+7811|223344556677885f5f5f5f5f5f5f	32	plan9	JS .+17
+7811|223344556677885f5f5f5f5f5f5f	64	gnu	js .+0x11
+7811|223344556677885f5f5f5f5f5f5f	64	intel	js .+0x11
+7811|223344556677885f5f5f5f5f5f5f	64	plan9	JS .+17
+7911|223344556677885f5f5f5f5f5f5f	32	intel	jns .+0x11
+7911|223344556677885f5f5f5f5f5f5f	32	plan9	JNS .+17
+7911|223344556677885f5f5f5f5f5f5f	64	gnu	jns .+0x11
+7911|223344556677885f5f5f5f5f5f5f	64	intel	jns .+0x11
+7911|223344556677885f5f5f5f5f5f5f	64	plan9	JNS .+17
+7a11|223344556677885f5f5f5f5f5f5f	32	intel	jp .+0x11
+7a11|223344556677885f5f5f5f5f5f5f	32	plan9	JP .+17
+7a11|223344556677885f5f5f5f5f5f5f	64	gnu	jp .+0x11
+7a11|223344556677885f5f5f5f5f5f5f	64	intel	jp .+0x11
+7a11|223344556677885f5f5f5f5f5f5f	64	plan9	JP .+17
+7b11|223344556677885f5f5f5f5f5f5f	32	intel	jnp .+0x11
+7b11|223344556677885f5f5f5f5f5f5f	32	plan9	JNP .+17
+7b11|223344556677885f5f5f5f5f5f5f	64	gnu	jnp .+0x11
+7b11|223344556677885f5f5f5f5f5f5f	64	intel	jnp .+0x11
+7b11|223344556677885f5f5f5f5f5f5f	64	plan9	JNP .+17
+7c11|223344556677885f5f5f5f5f5f5f	32	intel	jl .+0x11
+7c11|223344556677885f5f5f5f5f5f5f	32	plan9	JL .+17
+7c11|223344556677885f5f5f5f5f5f5f	64	gnu	jl .+0x11
+7c11|223344556677885f5f5f5f5f5f5f	64	intel	jl .+0x11
+7c11|223344556677885f5f5f5f5f5f5f	64	plan9	JL .+17
+7d11|223344556677885f5f5f5f5f5f5f	32	intel	jnl .+0x11
+7d11|223344556677885f5f5f5f5f5f5f	32	plan9	JGE .+17
+7d11|223344556677885f5f5f5f5f5f5f	64	gnu	jge .+0x11
+7d11|223344556677885f5f5f5f5f5f5f	64	intel	jnl .+0x11
+7d11|223344556677885f5f5f5f5f5f5f	64	plan9	JGE .+17
+7e11|223344556677885f5f5f5f5f5f5f	32	intel	jle .+0x11
+7e11|223344556677885f5f5f5f5f5f5f	32	plan9	JLE .+17
+7e11|223344556677885f5f5f5f5f5f5f	64	gnu	jle .+0x11
+7e11|223344556677885f5f5f5f5f5f5f	64	intel	jle .+0x11
+7e11|223344556677885f5f5f5f5f5f5f	64	plan9	JLE .+17
+7f11|223344556677885f5f5f5f5f5f5f	32	intel	jnle .+0x11
+7f11|223344556677885f5f5f5f5f5f5f	32	plan9	JG .+17
+7f11|223344556677885f5f5f5f5f5f5f	64	gnu	jg .+0x11
+7f11|223344556677885f5f5f5f5f5f5f	64	intel	jnle .+0x11
+7f11|223344556677885f5f5f5f5f5f5f	64	plan9	JG .+17
+800011|223344556677885f5f5f5f5f5f	32	intel	add byte ptr [eax], 0x11
+800011|223344556677885f5f5f5f5f5f	32	plan9	ADDL $0x11, 0(AX)
+800011|223344556677885f5f5f5f5f5f	64	gnu	addb $0x11,(%rax)
+800011|223344556677885f5f5f5f5f5f	64	intel	add byte ptr [rax], 0x11
+800011|223344556677885f5f5f5f5f5f	64	plan9	ADDL $0x11, 0(AX)
+800811|223344556677885f5f5f5f5f5f	32	intel	or byte ptr [eax], 0x11
+800811|223344556677885f5f5f5f5f5f	32	plan9	ORL $0x11, 0(AX)
+800811|223344556677885f5f5f5f5f5f	64	gnu	orb $0x11,(%rax)
+800811|223344556677885f5f5f5f5f5f	64	intel	or byte ptr [rax], 0x11
+800811|223344556677885f5f5f5f5f5f	64	plan9	ORL $0x11, 0(AX)
+801122|3344556677885f5f5f5f5f5f5f	32	intel	adc byte ptr [ecx], 0x22
+801122|3344556677885f5f5f5f5f5f5f	32	plan9	ADCL $0x22, 0(CX)
+801122|3344556677885f5f5f5f5f5f5f	64	gnu	adcb $0x22,(%rcx)
+801122|3344556677885f5f5f5f5f5f5f	64	intel	adc byte ptr [rcx], 0x22
+801122|3344556677885f5f5f5f5f5f5f	64	plan9	ADCL $0x22, 0(CX)
+801811|223344556677885f5f5f5f5f5f	32	intel	sbb byte ptr [eax], 0x11
+801811|223344556677885f5f5f5f5f5f	32	plan9	SBBL $0x11, 0(AX)
+801811|223344556677885f5f5f5f5f5f	64	gnu	sbbb $0x11,(%rax)
+801811|223344556677885f5f5f5f5f5f	64	intel	sbb byte ptr [rax], 0x11
+801811|223344556677885f5f5f5f5f5f	64	plan9	SBBL $0x11, 0(AX)
+802011|223344556677885f5f5f5f5f5f	32	intel	and byte ptr [eax], 0x11
+802011|223344556677885f5f5f5f5f5f	32	plan9	ANDL $0x11, 0(AX)
+802011|223344556677885f5f5f5f5f5f	64	gnu	andb $0x11,(%rax)
+802011|223344556677885f5f5f5f5f5f	64	intel	and byte ptr [rax], 0x11
+802011|223344556677885f5f5f5f5f5f	64	plan9	ANDL $0x11, 0(AX)
+802811|223344556677885f5f5f5f5f5f	32	intel	sub byte ptr [eax], 0x11
+802811|223344556677885f5f5f5f5f5f	32	plan9	SUBL $0x11, 0(AX)
+802811|223344556677885f5f5f5f5f5f	64	gnu	subb $0x11,(%rax)
+802811|223344556677885f5f5f5f5f5f	64	intel	sub byte ptr [rax], 0x11
+802811|223344556677885f5f5f5f5f5f	64	plan9	SUBL $0x11, 0(AX)
+803011|223344556677885f5f5f5f5f5f	32	intel	xor byte ptr [eax], 0x11
+803011|223344556677885f5f5f5f5f5f	32	plan9	XORL $0x11, 0(AX)
+803011|223344556677885f5f5f5f5f5f	64	gnu	xorb $0x11,(%rax)
+803011|223344556677885f5f5f5f5f5f	64	intel	xor byte ptr [rax], 0x11
+803011|223344556677885f5f5f5f5f5f	64	plan9	XORL $0x11, 0(AX)
+803811|223344556677885f5f5f5f5f5f	32	intel	cmp byte ptr [eax], 0x11
+803811|223344556677885f5f5f5f5f5f	32	plan9	CMPL $0x11, 0(AX)
+803811|223344556677885f5f5f5f5f5f	64	gnu	cmpb $0x11,(%rax)
+803811|223344556677885f5f5f5f5f5f	64	intel	cmp byte ptr [rax], 0x11
+803811|223344556677885f5f5f5f5f5f	64	plan9	CMPL $0x11, 0(AX)
+810011223344|556677885f5f5f5f5f5f	32	intel	add dword ptr [eax], 0x44332211
+810011223344|556677885f5f5f5f5f5f	32	plan9	ADDL $0x44332211, 0(AX)
+810011223344|556677885f5f5f5f5f5f	64	gnu	addl $0x44332211,(%rax)
+810011223344|556677885f5f5f5f5f5f	64	intel	add dword ptr [rax], 0x44332211
+810011223344|556677885f5f5f5f5f5f	64	plan9	ADDL $0x44332211, 0(AX)
+810811223344|556677885f5f5f5f5f5f	32	intel	or dword ptr [eax], 0x44332211
+810811223344|556677885f5f5f5f5f5f	32	plan9	ORL $0x44332211, 0(AX)
+810811223344|556677885f5f5f5f5f5f	64	gnu	orl $0x44332211,(%rax)
+810811223344|556677885f5f5f5f5f5f	64	intel	or dword ptr [rax], 0x44332211
+810811223344|556677885f5f5f5f5f5f	64	plan9	ORL $0x44332211, 0(AX)
+811122334455|6677885f5f5f5f5f5f5f	32	intel	adc dword ptr [ecx], 0x55443322
+811122334455|6677885f5f5f5f5f5f5f	32	plan9	ADCL $0x55443322, 0(CX)
+811122334455|6677885f5f5f5f5f5f5f	64	gnu	adcl $0x55443322,(%rcx)
+811122334455|6677885f5f5f5f5f5f5f	64	intel	adc dword ptr [rcx], 0x55443322
+811122334455|6677885f5f5f5f5f5f5f	64	plan9	ADCL $0x55443322, 0(CX)
+811811223344|556677885f5f5f5f5f5f	32	intel	sbb dword ptr [eax], 0x44332211
+811811223344|556677885f5f5f5f5f5f	32	plan9	SBBL $0x44332211, 0(AX)
+811811223344|556677885f5f5f5f5f5f	64	gnu	sbbl $0x44332211,(%rax)
+811811223344|556677885f5f5f5f5f5f	64	intel	sbb dword ptr [rax], 0x44332211
+811811223344|556677885f5f5f5f5f5f	64	plan9	SBBL $0x44332211, 0(AX)
+812011223344|556677885f5f5f5f5f5f	32	intel	and dword ptr [eax], 0x44332211
+812011223344|556677885f5f5f5f5f5f	32	plan9	ANDL $0x44332211, 0(AX)
+812011223344|556677885f5f5f5f5f5f	64	gnu	andl $0x44332211,(%rax)
+812011223344|556677885f5f5f5f5f5f	64	intel	and dword ptr [rax], 0x44332211
+812011223344|556677885f5f5f5f5f5f	64	plan9	ANDL $0x44332211, 0(AX)
+812811223344|556677885f5f5f5f5f5f	32	intel	sub dword ptr [eax], 0x44332211
+812811223344|556677885f5f5f5f5f5f	32	plan9	SUBL $0x44332211, 0(AX)
+812811223344|556677885f5f5f5f5f5f	64	gnu	subl $0x44332211,(%rax)
+812811223344|556677885f5f5f5f5f5f	64	intel	sub dword ptr [rax], 0x44332211
+812811223344|556677885f5f5f5f5f5f	64	plan9	SUBL $0x44332211, 0(AX)
+813011223344|556677885f5f5f5f5f5f	32	intel	xor dword ptr [eax], 0x44332211
+813011223344|556677885f5f5f5f5f5f	32	plan9	XORL $0x44332211, 0(AX)
+813011223344|556677885f5f5f5f5f5f	64	gnu	xorl $0x44332211,(%rax)
+813011223344|556677885f5f5f5f5f5f	64	intel	xor dword ptr [rax], 0x44332211
+813011223344|556677885f5f5f5f5f5f	64	plan9	XORL $0x44332211, 0(AX)
+813811223344|556677885f5f5f5f5f5f	32	intel	cmp dword ptr [eax], 0x44332211
+813811223344|556677885f5f5f5f5f5f	32	plan9	CMPL $0x44332211, 0(AX)
+813811223344|556677885f5f5f5f5f5f	64	gnu	cmpl $0x44332211,(%rax)
+813811223344|556677885f5f5f5f5f5f	64	intel	cmp dword ptr [rax], 0x44332211
+813811223344|556677885f5f5f5f5f5f	64	plan9	CMPL $0x44332211, 0(AX)
+830011|223344556677885f5f5f5f5f5f	32	intel	add dword ptr [eax], 0x11
+830011|223344556677885f5f5f5f5f5f	32	plan9	ADDL $0x11, 0(AX)
+830011|223344556677885f5f5f5f5f5f	64	gnu	addl $0x11,(%rax)
+830011|223344556677885f5f5f5f5f5f	64	intel	add dword ptr [rax], 0x11
+830011|223344556677885f5f5f5f5f5f	64	plan9	ADDL $0x11, 0(AX)
+830811|223344556677885f5f5f5f5f5f	32	intel	or dword ptr [eax], 0x11
+830811|223344556677885f5f5f5f5f5f	32	plan9	ORL $0x11, 0(AX)
+830811|223344556677885f5f5f5f5f5f	64	gnu	orl $0x11,(%rax)
+830811|223344556677885f5f5f5f5f5f	64	intel	or dword ptr [rax], 0x11
+830811|223344556677885f5f5f5f5f5f	64	plan9	ORL $0x11, 0(AX)
+831122|3344556677885f5f5f5f5f5f5f	32	intel	adc dword ptr [ecx], 0x22
+831122|3344556677885f5f5f5f5f5f5f	32	plan9	ADCL $0x22, 0(CX)
+831122|3344556677885f5f5f5f5f5f5f	64	gnu	adcl $0x22,(%rcx)
+831122|3344556677885f5f5f5f5f5f5f	64	intel	adc dword ptr [rcx], 0x22
+831122|3344556677885f5f5f5f5f5f5f	64	plan9	ADCL $0x22, 0(CX)
+831811|223344556677885f5f5f5f5f5f	32	intel	sbb dword ptr [eax], 0x11
+831811|223344556677885f5f5f5f5f5f	32	plan9	SBBL $0x11, 0(AX)
+831811|223344556677885f5f5f5f5f5f	64	gnu	sbbl $0x11,(%rax)
+831811|223344556677885f5f5f5f5f5f	64	intel	sbb dword ptr [rax], 0x11
+831811|223344556677885f5f5f5f5f5f	64	plan9	SBBL $0x11, 0(AX)
+832011|223344556677885f5f5f5f5f5f	32	intel	and dword ptr [eax], 0x11
+832011|223344556677885f5f5f5f5f5f	32	plan9	ANDL $0x11, 0(AX)
+832011|223344556677885f5f5f5f5f5f	64	gnu	andl $0x11,(%rax)
+832011|223344556677885f5f5f5f5f5f	64	intel	and dword ptr [rax], 0x11
+832011|223344556677885f5f5f5f5f5f	64	plan9	ANDL $0x11, 0(AX)
+832811|223344556677885f5f5f5f5f5f	32	intel	sub dword ptr [eax], 0x11
+832811|223344556677885f5f5f5f5f5f	32	plan9	SUBL $0x11, 0(AX)
+832811|223344556677885f5f5f5f5f5f	64	gnu	subl $0x11,(%rax)
+832811|223344556677885f5f5f5f5f5f	64	intel	sub dword ptr [rax], 0x11
+832811|223344556677885f5f5f5f5f5f	64	plan9	SUBL $0x11, 0(AX)
+833011|223344556677885f5f5f5f5f5f	32	intel	xor dword ptr [eax], 0x11
+833011|223344556677885f5f5f5f5f5f	32	plan9	XORL $0x11, 0(AX)
+833011|223344556677885f5f5f5f5f5f	64	gnu	xorl $0x11,(%rax)
+833011|223344556677885f5f5f5f5f5f	64	intel	xor dword ptr [rax], 0x11
+833011|223344556677885f5f5f5f5f5f	64	plan9	XORL $0x11, 0(AX)
+833811|223344556677885f5f5f5f5f5f	32	intel	cmp dword ptr [eax], 0x11
+833811|223344556677885f5f5f5f5f5f	32	plan9	CMPL $0x11, 0(AX)
+833811|223344556677885f5f5f5f5f5f	64	gnu	cmpl $0x11,(%rax)
+833811|223344556677885f5f5f5f5f5f	64	intel	cmp dword ptr [rax], 0x11
+833811|223344556677885f5f5f5f5f5f	64	plan9	CMPL $0x11, 0(AX)
+8411|223344556677885f5f5f5f5f5f5f	32	intel	test byte ptr [ecx], dl
+8411|223344556677885f5f5f5f5f5f5f	32	plan9	TESTL DL, 0(CX)
+8411|223344556677885f5f5f5f5f5f5f	64	gnu	test %dl,(%rcx)
+8411|223344556677885f5f5f5f5f5f5f	64	intel	test byte ptr [rcx], dl
+8411|223344556677885f5f5f5f5f5f5f	64	plan9	TESTL DL, 0(CX)
+8511|223344556677885f5f5f5f5f5f5f	32	intel	test dword ptr [ecx], edx
+8511|223344556677885f5f5f5f5f5f5f	32	plan9	TESTL DX, 0(CX)
+8511|223344556677885f5f5f5f5f5f5f	64	gnu	test %edx,(%rcx)
+8511|223344556677885f5f5f5f5f5f5f	64	intel	test dword ptr [rcx], edx
+8511|223344556677885f5f5f5f5f5f5f	64	plan9	TESTL DX, 0(CX)
+8611|223344556677885f5f5f5f5f5f5f	32	intel	xchg byte ptr [ecx], dl
+8611|223344556677885f5f5f5f5f5f5f	32	plan9	XCHGL DL, 0(CX)
+8611|223344556677885f5f5f5f5f5f5f	64	gnu	xchg %dl,(%rcx)
+8611|223344556677885f5f5f5f5f5f5f	64	intel	xchg byte ptr [rcx], dl
+8611|223344556677885f5f5f5f5f5f5f	64	plan9	XCHGL DL, 0(CX)
+8711|223344556677885f5f5f5f5f5f5f	32	intel	xchg dword ptr [ecx], edx
+8711|223344556677885f5f5f5f5f5f5f	32	plan9	XCHGL DX, 0(CX)
+8711|223344556677885f5f5f5f5f5f5f	64	gnu	xchg %edx,(%rcx)
+8711|223344556677885f5f5f5f5f5f5f	64	intel	xchg dword ptr [rcx], edx
+8711|223344556677885f5f5f5f5f5f5f	64	plan9	XCHGL DX, 0(CX)
+8811|223344556677885f5f5f5f5f5f5f	32	intel	mov byte ptr [ecx], dl
+8811|223344556677885f5f5f5f5f5f5f	32	plan9	MOVL DL, 0(CX)
+8811|223344556677885f5f5f5f5f5f5f	64	gnu	mov %dl,(%rcx)
+8811|223344556677885f5f5f5f5f5f5f	64	intel	mov byte ptr [rcx], dl
+8811|223344556677885f5f5f5f5f5f5f	64	plan9	MOVL DL, 0(CX)
+8911|223344556677885f5f5f5f5f5f5f	32	intel	mov dword ptr [ecx], edx
+8911|223344556677885f5f5f5f5f5f5f	32	plan9	MOVL DX, 0(CX)
+8911|223344556677885f5f5f5f5f5f5f	64	gnu	mov %edx,(%rcx)
+8911|223344556677885f5f5f5f5f5f5f	64	intel	mov dword ptr [rcx], edx
+8911|223344556677885f5f5f5f5f5f5f	64	plan9	MOVL DX, 0(CX)
+8a11|223344556677885f5f5f5f5f5f5f	32	intel	mov dl, byte ptr [ecx]
+8a11|223344556677885f5f5f5f5f5f5f	32	plan9	MOVL 0(CX), DL
+8a11|223344556677885f5f5f5f5f5f5f	64	gnu	mov (%rcx),%dl
+8a11|223344556677885f5f5f5f5f5f5f	64	intel	mov dl, byte ptr [rcx]
+8a11|223344556677885f5f5f5f5f5f5f	64	plan9	MOVL 0(CX), DL
+8b11|223344556677885f5f5f5f5f5f5f	32	intel	mov edx, dword ptr [ecx]
+8b11|223344556677885f5f5f5f5f5f5f	32	plan9	MOVL 0(CX), DX
+8b11|223344556677885f5f5f5f5f5f5f	64	gnu	mov (%rcx),%edx
+8b11|223344556677885f5f5f5f5f5f5f	64	intel	mov edx, dword ptr [rcx]
+8b11|223344556677885f5f5f5f5f5f5f	64	plan9	MOVL 0(CX), DX
+8c11|223344556677885f5f5f5f5f5f5f	32	intel	mov word ptr [ecx], ss
+8c11|223344556677885f5f5f5f5f5f5f	32	plan9	MOVL SS, 0(CX)
+8c11|223344556677885f5f5f5f5f5f5f	64	gnu	mov %ss,(%rcx)
+8c11|223344556677885f5f5f5f5f5f5f	64	intel	mov word ptr [rcx], ss
+8c11|223344556677885f5f5f5f5f5f5f	64	plan9	MOVL SS, 0(CX)
+8d11|223344556677885f5f5f5f5f5f5f	32	intel	lea edx, ptr [ecx]
+8d11|223344556677885f5f5f5f5f5f5f	32	plan9	LEAL 0(CX), DX
+8d11|223344556677885f5f5f5f5f5f5f	64	gnu	lea (%rcx),%edx
+8d11|223344556677885f5f5f5f5f5f5f	64	intel	lea edx, ptr [rcx]
+8d11|223344556677885f5f5f5f5f5f5f	64	plan9	LEAL 0(CX), DX
+8e11|223344556677885f5f5f5f5f5f5f	32	intel	mov ss, word ptr [ecx]
+8e11|223344556677885f5f5f5f5f5f5f	32	plan9	MOVL 0(CX), SS
+8e11|223344556677885f5f5f5f5f5f5f	64	gnu	mov (%rcx),%ss
+8e11|223344556677885f5f5f5f5f5f5f	64	intel	mov ss, word ptr [rcx]
+8e11|223344556677885f5f5f5f5f5f5f	64	plan9	MOVL 0(CX), SS
+8f00|11223344556677885f5f5f5f5f5f	32	intel	pop dword ptr [eax]
+8f00|11223344556677885f5f5f5f5f5f	32	plan9	POPL 0(AX)
+8f00|11223344556677885f5f5f5f5f5f	64	gnu	popq (%rax)
+8f00|11223344556677885f5f5f5f5f5f	64	intel	pop qword ptr [rax]
+8f00|11223344556677885f5f5f5f5f5f	64	plan9	POPL 0(AX)
+91|11223344556677885f5f5f5f5f5f5f	32	intel	xchg ecx, eax
+91|11223344556677885f5f5f5f5f5f5f	32	plan9	XCHGL AX, CX
+91|11223344556677885f5f5f5f5f5f5f	64	intel	xchg ecx, eax
+91|11223344556677885f5f5f5f5f5f5f	64	plan9	XCHGL AX, CX
+98|11223344556677885f5f5f5f5f5f5f	32	intel	cwde
+98|11223344556677885f5f5f5f5f5f5f	32	plan9	CWDE
+98|11223344556677885f5f5f5f5f5f5f	64	gnu	cwtl
+98|11223344556677885f5f5f5f5f5f5f	64	intel	cwde
+98|11223344556677885f5f5f5f5f5f5f	64	plan9	CWDE
+99|11223344556677885f5f5f5f5f5f5f	32	intel	cdq
+99|11223344556677885f5f5f5f5f5f5f	32	plan9	CDQ
+99|11223344556677885f5f5f5f5f5f5f	64	gnu	cltd
+99|11223344556677885f5f5f5f5f5f5f	64	intel	cdq
+99|11223344556677885f5f5f5f5f5f5f	64	plan9	CDQ
+9a112233445566|77885f5f5f5f5f5f5f	32	intel	call far 0x44332211, 0x6655
+9a112233445566|77885f5f5f5f5f5f5f	32	plan9	LCALL $0x44332211, $0x6655
+9b|11223344556677885f5f5f5f5f5f5f	32	intel	fwait
+9b|11223344556677885f5f5f5f5f5f5f	32	plan9	FWAIT
+9b|11223344556677885f5f5f5f5f5f5f	64	gnu	fwait
+9b|11223344556677885f5f5f5f5f5f5f	64	intel	fwait
+9b|11223344556677885f5f5f5f5f5f5f	64	plan9	FWAIT
+9c|11223344556677885f5f5f5f5f5f5f	32	intel	pushfd
+9c|11223344556677885f5f5f5f5f5f5f	32	plan9	PUSHFD
+9c|11223344556677885f5f5f5f5f5f5f	64	gnu	pushfq
+9c|11223344556677885f5f5f5f5f5f5f	64	intel	pushfq
+9c|11223344556677885f5f5f5f5f5f5f	64	plan9	PUSHFQ
+9d|11223344556677885f5f5f5f5f5f5f	32	intel	popfd
+9d|11223344556677885f5f5f5f5f5f5f	32	plan9	POPFD
+9d|11223344556677885f5f5f5f5f5f5f	64	gnu	popfq
+9d|11223344556677885f5f5f5f5f5f5f	64	intel	popfq
+9d|11223344556677885f5f5f5f5f5f5f	64	plan9	POPFQ
+9e|11223344556677885f5f5f5f5f5f5f	32	intel	sahf
+9e|11223344556677885f5f5f5f5f5f5f	32	plan9	SAHF
+9e|11223344556677885f5f5f5f5f5f5f	64	gnu	sahf
+9e|11223344556677885f5f5f5f5f5f5f	64	intel	sahf
+9e|11223344556677885f5f5f5f5f5f5f	64	plan9	SAHF
+9f|11223344556677885f5f5f5f5f5f5f	32	intel	lahf
+9f|11223344556677885f5f5f5f5f5f5f	32	plan9	LAHF
+9f|11223344556677885f5f5f5f5f5f5f	64	gnu	lahf
+9f|11223344556677885f5f5f5f5f5f5f	64	intel	lahf
+9f|11223344556677885f5f5f5f5f5f5f	64	plan9	LAHF
+a11122334455667788|5f5f5f5f5f5f5f	64	gnu	mov -0x778899aabbccddef,%eax
+a11122334455667788|5f5f5f5f5f5f5f	64	intel	mov eax, dword ptr [0x8877665544332211]
+a11122334455667788|5f5f5f5f5f5f5f	64	plan9	MOVL -0x778899aabbccddef, AX
+a111223344|556677885f5f5f5f5f5f5f	32	intel	mov eax, dword ptr [0x44332211]
+a111223344|556677885f5f5f5f5f5f5f	32	plan9	MOVL 0x44332211, AX
+a21122334455667788|5f5f5f5f5f5f5f	64	gnu	mov %al,-0x778899aabbccddef
+a21122334455667788|5f5f5f5f5f5f5f	64	intel	mov byte ptr [0x8877665544332211], al
+a21122334455667788|5f5f5f5f5f5f5f	64	plan9	MOVL AL, -0x778899aabbccddef
+a211223344|556677885f5f5f5f5f5f5f	32	intel	mov byte ptr [0x44332211], al
+a211223344|556677885f5f5f5f5f5f5f	32	plan9	MOVL AL, 0x44332211
+a31122334455667788|5f5f5f5f5f5f5f	64	gnu	mov %eax,-0x778899aabbccddef
+a31122334455667788|5f5f5f5f5f5f5f	64	intel	mov dword ptr [0x8877665544332211], eax
+a31122334455667788|5f5f5f5f5f5f5f	64	plan9	MOVL AX, -0x778899aabbccddef
+a311223344|556677885f5f5f5f5f5f5f	32	intel	mov dword ptr [0x44332211], eax
+a311223344|556677885f5f5f5f5f5f5f	32	plan9	MOVL AX, 0x44332211
+a4|11223344556677885f5f5f5f5f5f5f	32	intel	movsb byte ptr [edi], byte ptr [esi]
+a4|11223344556677885f5f5f5f5f5f5f	32	plan9	MOVSB DS:0(SI), ES:0(DI)
+a4|11223344556677885f5f5f5f5f5f5f	64	gnu	movsb %ds:(%rsi),%es:(%rdi)
+a4|11223344556677885f5f5f5f5f5f5f	64	intel	movsb byte ptr [rdi], byte ptr [rsi]
+a4|11223344556677885f5f5f5f5f5f5f	64	plan9	MOVSB DS:0(SI), ES:0(DI)
+a5|11223344556677885f5f5f5f5f5f5f	32	intel	movsd dword ptr [edi], dword ptr [esi]
+a5|11223344556677885f5f5f5f5f5f5f	32	plan9	MOVSD DS:0(SI), ES:0(DI)
+a5|11223344556677885f5f5f5f5f5f5f	64	gnu	movsl %ds:(%rsi),%es:(%rdi)
+a5|11223344556677885f5f5f5f5f5f5f	64	intel	movsd dword ptr [rdi], dword ptr [rsi]
+a5|11223344556677885f5f5f5f5f5f5f	64	plan9	MOVSD DS:0(SI), ES:0(DI)
+a6|11223344556677885f5f5f5f5f5f5f	32	intel	cmpsb byte ptr [esi], byte ptr [edi]
+a6|11223344556677885f5f5f5f5f5f5f	32	plan9	CMPSB ES:0(DI), DS:0(SI)
+a6|11223344556677885f5f5f5f5f5f5f	64	gnu	cmpsb %es:(%rdi),%ds:(%rsi)
+a6|11223344556677885f5f5f5f5f5f5f	64	intel	cmpsb byte ptr [rsi], byte ptr [rdi]
+a6|11223344556677885f5f5f5f5f5f5f	64	plan9	CMPSB ES:0(DI), DS:0(SI)
+a7|11223344556677885f5f5f5f5f5f5f	32	intel	cmpsd dword ptr [esi], dword ptr [edi]
+a7|11223344556677885f5f5f5f5f5f5f	32	plan9	CMPSD ES:0(DI), DS:0(SI)
+a7|11223344556677885f5f5f5f5f5f5f	64	gnu	cmpsl %es:(%rdi),%ds:(%rsi)
+a7|11223344556677885f5f5f5f5f5f5f	64	intel	cmpsd dword ptr [rsi], dword ptr [rdi]
+a7|11223344556677885f5f5f5f5f5f5f	64	plan9	CMPSD ES:0(DI), DS:0(SI)
+a811|223344556677885f5f5f5f5f5f5f	32	intel	test al, 0x11
+a811|223344556677885f5f5f5f5f5f5f	32	plan9	TESTL $0x11, AL
+a811|223344556677885f5f5f5f5f5f5f	64	gnu	test $0x11,%al
+a811|223344556677885f5f5f5f5f5f5f	64	intel	test al, 0x11
+a811|223344556677885f5f5f5f5f5f5f	64	plan9	TESTL $0x11, AL
+a911223344|556677885f5f5f5f5f5f5f	32	intel	test eax, 0x44332211
+a911223344|556677885f5f5f5f5f5f5f	32	plan9	TESTL $0x44332211, AX
+a911223344|556677885f5f5f5f5f5f5f	64	gnu	test $0x44332211,%eax
+a911223344|556677885f5f5f5f5f5f5f	64	intel	test eax, 0x44332211
+a911223344|556677885f5f5f5f5f5f5f	64	plan9	TESTL $0x44332211, AX
+aa|11223344556677885f5f5f5f5f5f5f	32	intel	stosb byte ptr [edi]
+aa|11223344556677885f5f5f5f5f5f5f	32	plan9	STOSB AL, ES:0(DI)
+aa|11223344556677885f5f5f5f5f5f5f	64	gnu	stos %al,%es:(%rdi)
+aa|11223344556677885f5f5f5f5f5f5f	64	intel	stosb byte ptr [rdi]
+aa|11223344556677885f5f5f5f5f5f5f	64	plan9	STOSB AL, ES:0(DI)
+ab|11223344556677885f5f5f5f5f5f5f	32	intel	stosd dword ptr [edi]
+ab|11223344556677885f5f5f5f5f5f5f	32	plan9	STOSD AX, ES:0(DI)
+ab|11223344556677885f5f5f5f5f5f5f	64	gnu	stos %eax,%es:(%rdi)
+ab|11223344556677885f5f5f5f5f5f5f	64	intel	stosd dword ptr [rdi]
+ab|11223344556677885f5f5f5f5f5f5f	64	plan9	STOSD AX, ES:0(DI)
+ac|11223344556677885f5f5f5f5f5f5f	32	intel	lodsb byte ptr [esi]
+ac|11223344556677885f5f5f5f5f5f5f	32	plan9	LODSB DS:0(SI), AL
+ac|11223344556677885f5f5f5f5f5f5f	64	gnu	lods %ds:(%rsi),%al
+ac|11223344556677885f5f5f5f5f5f5f	64	intel	lodsb byte ptr [rsi]
+ac|11223344556677885f5f5f5f5f5f5f	64	plan9	LODSB DS:0(SI), AL
+ad|11223344556677885f5f5f5f5f5f5f	32	intel	lodsd dword ptr [esi]
+ad|11223344556677885f5f5f5f5f5f5f	32	plan9	LODSD DS:0(SI), AX
+ad|11223344556677885f5f5f5f5f5f5f	64	gnu	lods %ds:(%rsi),%eax
+ad|11223344556677885f5f5f5f5f5f5f	64	intel	lodsd dword ptr [rsi]
+ad|11223344556677885f5f5f5f5f5f5f	64	plan9	LODSD DS:0(SI), AX
+ae|11223344556677885f5f5f5f5f5f5f	32	intel	scasb byte ptr [edi]
+ae|11223344556677885f5f5f5f5f5f5f	32	plan9	SCASB ES:0(DI), AL
+ae|11223344556677885f5f5f5f5f5f5f	64	gnu	scas %es:(%rdi),%al
+ae|11223344556677885f5f5f5f5f5f5f	64	intel	scasb byte ptr [rdi]
+ae|11223344556677885f5f5f5f5f5f5f	64	plan9	SCASB ES:0(DI), AL
+af|11223344556677885f5f5f5f5f5f5f	32	intel	scasd dword ptr [edi]
+af|11223344556677885f5f5f5f5f5f5f	32	plan9	SCASD ES:0(DI), AX
+af|11223344556677885f5f5f5f5f5f5f	64	gnu	scas %es:(%rdi),%eax
+af|11223344556677885f5f5f5f5f5f5f	64	intel	scasd dword ptr [rdi]
+af|11223344556677885f5f5f5f5f5f5f	64	plan9	SCASD ES:0(DI), AX
+b011|223344556677885f5f5f5f5f5f5f	32	intel	mov al, 0x11
+b011|223344556677885f5f5f5f5f5f5f	32	plan9	MOVL $0x11, AL
+b011|223344556677885f5f5f5f5f5f5f	64	gnu	mov $0x11,%al
+b011|223344556677885f5f5f5f5f5f5f	64	intel	mov al, 0x11
+b011|223344556677885f5f5f5f5f5f5f	64	plan9	MOVL $0x11, AL
+b811223344|556677885f5f5f5f5f5f5f	32	intel	mov eax, 0x44332211
+b811223344|556677885f5f5f5f5f5f5f	32	plan9	MOVL $0x44332211, AX
+b811223344|556677885f5f5f5f5f5f5f	64	gnu	mov $0x44332211,%eax
+b811223344|556677885f5f5f5f5f5f5f	64	intel	mov eax, 0x44332211
+b811223344|556677885f5f5f5f5f5f5f	64	plan9	MOVL $0x44332211, AX
+c00011|223344556677885f5f5f5f5f5f	32	intel	rol byte ptr [eax], 0x11
+c00011|223344556677885f5f5f5f5f5f	32	plan9	ROLL $0x11, 0(AX)
+c00011|223344556677885f5f5f5f5f5f	64	gnu	rolb $0x11,(%rax)
+c00011|223344556677885f5f5f5f5f5f	64	intel	rol byte ptr [rax], 0x11
+c00011|223344556677885f5f5f5f5f5f	64	plan9	ROLL $0x11, 0(AX)
+c00811|223344556677885f5f5f5f5f5f	32	intel	ror byte ptr [eax], 0x11
+c00811|223344556677885f5f5f5f5f5f	32	plan9	RORL $0x11, 0(AX)
+c00811|223344556677885f5f5f5f5f5f	64	gnu	rorb $0x11,(%rax)
+c00811|223344556677885f5f5f5f5f5f	64	intel	ror byte ptr [rax], 0x11
+c00811|223344556677885f5f5f5f5f5f	64	plan9	RORL $0x11, 0(AX)
+c01122|3344556677885f5f5f5f5f5f5f	32	intel	rcl byte ptr [ecx], 0x22
+c01122|3344556677885f5f5f5f5f5f5f	32	plan9	RCLL $0x22, 0(CX)
+c01122|3344556677885f5f5f5f5f5f5f	64	gnu	rclb $0x22,(%rcx)
+c01122|3344556677885f5f5f5f5f5f5f	64	intel	rcl byte ptr [rcx], 0x22
+c01122|3344556677885f5f5f5f5f5f5f	64	plan9	RCLL $0x22, 0(CX)
+c01811|223344556677885f5f5f5f5f5f	32	intel	rcr byte ptr [eax], 0x11
+c01811|223344556677885f5f5f5f5f5f	32	plan9	RCRL $0x11, 0(AX)
+c01811|223344556677885f5f5f5f5f5f	64	gnu	rcrb $0x11,(%rax)
+c01811|223344556677885f5f5f5f5f5f	64	intel	rcr byte ptr [rax], 0x11
+c01811|223344556677885f5f5f5f5f5f	64	plan9	RCRL $0x11, 0(AX)
+c02011|223344556677885f5f5f5f5f5f	32	intel	shl byte ptr [eax], 0x11
+c02011|223344556677885f5f5f5f5f5f	32	plan9	SHLL $0x11, 0(AX)
+c02011|223344556677885f5f5f5f5f5f	64	gnu	shlb $0x11,(%rax)
+c02011|223344556677885f5f5f5f5f5f	64	intel	shl byte ptr [rax], 0x11
+c02011|223344556677885f5f5f5f5f5f	64	plan9	SHLL $0x11, 0(AX)
+c02811|223344556677885f5f5f5f5f5f	32	intel	shr byte ptr [eax], 0x11
+c02811|223344556677885f5f5f5f5f5f	32	plan9	SHRL $0x11, 0(AX)
+c02811|223344556677885f5f5f5f5f5f	64	gnu	shrb $0x11,(%rax)
+c02811|223344556677885f5f5f5f5f5f	64	intel	shr byte ptr [rax], 0x11
+c02811|223344556677885f5f5f5f5f5f	64	plan9	SHRL $0x11, 0(AX)
+c03811|223344556677885f5f5f5f5f5f	32	intel	sar byte ptr [eax], 0x11
+c03811|223344556677885f5f5f5f5f5f	32	plan9	SARL $0x11, 0(AX)
+c03811|223344556677885f5f5f5f5f5f	64	gnu	sarb $0x11,(%rax)
+c03811|223344556677885f5f5f5f5f5f	64	intel	sar byte ptr [rax], 0x11
+c03811|223344556677885f5f5f5f5f5f	64	plan9	SARL $0x11, 0(AX)
+c10011|223344556677885f5f5f5f5f5f	32	intel	rol dword ptr [eax], 0x11
+c10011|223344556677885f5f5f5f5f5f	32	plan9	ROLL $0x11, 0(AX)
+c10011|223344556677885f5f5f5f5f5f	64	gnu	roll $0x11,(%rax)
+c10011|223344556677885f5f5f5f5f5f	64	intel	rol dword ptr [rax], 0x11
+c10011|223344556677885f5f5f5f5f5f	64	plan9	ROLL $0x11, 0(AX)
+c10811|223344556677885f5f5f5f5f5f	32	intel	ror dword ptr [eax], 0x11
+c10811|223344556677885f5f5f5f5f5f	32	plan9	RORL $0x11, 0(AX)
+c10811|223344556677885f5f5f5f5f5f	64	gnu	rorl $0x11,(%rax)
+c10811|223344556677885f5f5f5f5f5f	64	intel	ror dword ptr [rax], 0x11
+c10811|223344556677885f5f5f5f5f5f	64	plan9	RORL $0x11, 0(AX)
+c11122|3344556677885f5f5f5f5f5f5f	32	intel	rcl dword ptr [ecx], 0x22
+c11122|3344556677885f5f5f5f5f5f5f	32	plan9	RCLL $0x22, 0(CX)
+c11122|3344556677885f5f5f5f5f5f5f	64	gnu	rcll $0x22,(%rcx)
+c11122|3344556677885f5f5f5f5f5f5f	64	intel	rcl dword ptr [rcx], 0x22
+c11122|3344556677885f5f5f5f5f5f5f	64	plan9	RCLL $0x22, 0(CX)
+c11811|223344556677885f5f5f5f5f5f	32	intel	rcr dword ptr [eax], 0x11
+c11811|223344556677885f5f5f5f5f5f	32	plan9	RCRL $0x11, 0(AX)
+c11811|223344556677885f5f5f5f5f5f	64	gnu	rcrl $0x11,(%rax)
+c11811|223344556677885f5f5f5f5f5f	64	intel	rcr dword ptr [rax], 0x11
+c11811|223344556677885f5f5f5f5f5f	64	plan9	RCRL $0x11, 0(AX)
+c12011|223344556677885f5f5f5f5f5f	32	intel	shl dword ptr [eax], 0x11
+c12011|223344556677885f5f5f5f5f5f	32	plan9	SHLL $0x11, 0(AX)
+c12011|223344556677885f5f5f5f5f5f	64	gnu	shll $0x11,(%rax)
+c12011|223344556677885f5f5f5f5f5f	64	intel	shl dword ptr [rax], 0x11
+c12011|223344556677885f5f5f5f5f5f	64	plan9	SHLL $0x11, 0(AX)
+c12811|223344556677885f5f5f5f5f5f	32	intel	shr dword ptr [eax], 0x11
+c12811|223344556677885f5f5f5f5f5f	32	plan9	SHRL $0x11, 0(AX)
+c12811|223344556677885f5f5f5f5f5f	64	gnu	shrl $0x11,(%rax)
+c12811|223344556677885f5f5f5f5f5f	64	intel	shr dword ptr [rax], 0x11
+c12811|223344556677885f5f5f5f5f5f	64	plan9	SHRL $0x11, 0(AX)
+c13811|223344556677885f5f5f5f5f5f	32	intel	sar dword ptr [eax], 0x11
+c13811|223344556677885f5f5f5f5f5f	32	plan9	SARL $0x11, 0(AX)
+c13811|223344556677885f5f5f5f5f5f	64	gnu	sarl $0x11,(%rax)
+c13811|223344556677885f5f5f5f5f5f	64	intel	sar dword ptr [rax], 0x11
+c13811|223344556677885f5f5f5f5f5f	64	plan9	SARL $0x11, 0(AX)
+c3|11223344556677885f5f5f5f5f5f5f	32	intel	ret
+c3|11223344556677885f5f5f5f5f5f5f	32	plan9	RET
+c3|11223344556677885f5f5f5f5f5f5f	64	gnu	retq
+c3|11223344556677885f5f5f5f5f5f5f	64	intel	ret
+c3|11223344556677885f5f5f5f5f5f5f	64	plan9	RET
+c411|223344556677885f5f5f5f5f5f5f	32	intel	les edx, ptr [ecx]
+c411|223344556677885f5f5f5f5f5f5f	32	plan9	LES 0(CX), DX
+c511|223344556677885f5f5f5f5f5f5f	32	intel	lds edx, ptr [ecx]
+c511|223344556677885f5f5f5f5f5f5f	32	plan9	LDS 0(CX), DX
+c60011|223344556677885f5f5f5f5f5f	32	intel	mov byte ptr [eax], 0x11
+c60011|223344556677885f5f5f5f5f5f	32	plan9	MOVL $0x11, 0(AX)
+c60011|223344556677885f5f5f5f5f5f	64	gnu	movb $0x11,(%rax)
+c60011|223344556677885f5f5f5f5f5f	64	intel	mov byte ptr [rax], 0x11
+c60011|223344556677885f5f5f5f5f5f	64	plan9	MOVL $0x11, 0(AX)
+c6f811|223344556677885f5f5f5f5f5f	32	intel	xabort 0x11
+c6f811|223344556677885f5f5f5f5f5f	32	plan9	XABORT $0x11
+c6f811|223344556677885f5f5f5f5f5f	64	gnu	xabort $0x11
+c6f811|223344556677885f5f5f5f5f5f	64	intel	xabort 0x11
+c6f811|223344556677885f5f5f5f5f5f	64	plan9	XABORT $0x11
+c70011223344|556677885f5f5f5f5f5f	32	intel	mov dword ptr [eax], 0x44332211
+c70011223344|556677885f5f5f5f5f5f	32	plan9	MOVL $0x44332211, 0(AX)
+c70011223344|556677885f5f5f5f5f5f	64	gnu	movl $0x44332211,(%rax)
+c70011223344|556677885f5f5f5f5f5f	64	intel	mov dword ptr [rax], 0x44332211
+c70011223344|556677885f5f5f5f5f5f	64	plan9	MOVL $0x44332211, 0(AX)
+c7f811223344|556677885f5f5f5f5f5f	32	intel	xbegin .+0x44332211
+c7f811223344|556677885f5f5f5f5f5f	32	plan9	XBEGIN .+1144201745
+c7f811223344|556677885f5f5f5f5f5f	64	gnu	xbeginq .+0x44332211
+c7f811223344|556677885f5f5f5f5f5f	64	intel	xbegin .+0x44332211
+c7f811223344|556677885f5f5f5f5f5f	64	plan9	XBEGIN .+1144201745
+c8112233|44556677885f5f5f5f5f5f5f	32	intel	enter 0x2211, 0x33
+c8112233|44556677885f5f5f5f5f5f5f	32	plan9	ENTER $0x33, $0x2211
+c8112233|44556677885f5f5f5f5f5f5f	64	gnu	enterq $0x2211,$0x33
+c8112233|44556677885f5f5f5f5f5f5f	64	intel	enter 0x2211, 0x33
+c8112233|44556677885f5f5f5f5f5f5f	64	plan9	ENTER $0x33, $0x2211
+c9|11223344556677885f5f5f5f5f5f5f	32	intel	leave
+c9|11223344556677885f5f5f5f5f5f5f	32	plan9	LEAVE
+c9|11223344556677885f5f5f5f5f5f5f	64	gnu	leaveq
+c9|11223344556677885f5f5f5f5f5f5f	64	intel	leave
+c9|11223344556677885f5f5f5f5f5f5f	64	plan9	LEAVE
+ca1122|3344556677885f5f5f5f5f5f5f	32	intel	ret far 0x2211
+ca1122|3344556677885f5f5f5f5f5f5f	32	plan9	LRET $0x2211
+ca1122|3344556677885f5f5f5f5f5f5f	64	gnu	lretq $0x2211
+ca1122|3344556677885f5f5f5f5f5f5f	64	intel	ret far 0x2211
+ca1122|3344556677885f5f5f5f5f5f5f	64	plan9	LRET $0x2211
+cb|11223344556677885f5f5f5f5f5f5f	32	intel	ret far
+cb|11223344556677885f5f5f5f5f5f5f	32	plan9	LRET
+cb|11223344556677885f5f5f5f5f5f5f	64	gnu	lretq
+cb|11223344556677885f5f5f5f5f5f5f	64	intel	ret far
+cb|11223344556677885f5f5f5f5f5f5f	64	plan9	LRET
+cc|11223344556677885f5f5f5f5f5f5f	32	intel	int3
+cc|11223344556677885f5f5f5f5f5f5f	32	plan9	INT $0x3
+cc|11223344556677885f5f5f5f5f5f5f	64	gnu	int3
+cc|11223344556677885f5f5f5f5f5f5f	64	intel	int3
+cc|11223344556677885f5f5f5f5f5f5f	64	plan9	INT $0x3
+cd11|223344556677885f5f5f5f5f5f5f	32	intel	int 0x11
+cd11|223344556677885f5f5f5f5f5f5f	32	plan9	INT $0x11
+cd11|223344556677885f5f5f5f5f5f5f	64	gnu	int $0x11
+cd11|223344556677885f5f5f5f5f5f5f	64	intel	int 0x11
+cd11|223344556677885f5f5f5f5f5f5f	64	plan9	INT $0x11
+ce|11223344556677885f5f5f5f5f5f5f	32	intel	into
+ce|11223344556677885f5f5f5f5f5f5f	32	plan9	INTO
+ce|11223344556677885f5f5f5f5f5f5f	64	gnu	error: unrecognized instruction
+ce|11223344556677885f5f5f5f5f5f5f	64	intel	error: unrecognized instruction
+ce|11223344556677885f5f5f5f5f5f5f	64	plan9	error: unrecognized instruction
+cf|11223344556677885f5f5f5f5f5f5f	32	intel	iretd
+cf|11223344556677885f5f5f5f5f5f5f	32	plan9	IRETD
+cf|11223344556677885f5f5f5f5f5f5f	64	gnu	iret
+cf|11223344556677885f5f5f5f5f5f5f	64	intel	iretd
+cf|11223344556677885f5f5f5f5f5f5f	64	plan9	IRETD
+d000|11223344556677885f5f5f5f5f5f	32	intel	rol byte ptr [eax], 0x1
+d000|11223344556677885f5f5f5f5f5f	32	plan9	ROLL $0x1, 0(AX)
+d000|11223344556677885f5f5f5f5f5f	64	gnu	rolb (%rax)
+d000|11223344556677885f5f5f5f5f5f	64	intel	rol byte ptr [rax], 0x1
+d000|11223344556677885f5f5f5f5f5f	64	plan9	ROLL $0x1, 0(AX)
+d008|11223344556677885f5f5f5f5f5f	32	intel	ror byte ptr [eax], 0x1
+d008|11223344556677885f5f5f5f5f5f	32	plan9	RORL $0x1, 0(AX)
+d008|11223344556677885f5f5f5f5f5f	64	gnu	rorb (%rax)
+d008|11223344556677885f5f5f5f5f5f	64	intel	ror byte ptr [rax], 0x1
+d008|11223344556677885f5f5f5f5f5f	64	plan9	RORL $0x1, 0(AX)
+d011|223344556677885f5f5f5f5f5f5f	32	intel	rcl byte ptr [ecx], 0x1
+d011|223344556677885f5f5f5f5f5f5f	32	plan9	RCLL $0x1, 0(CX)
+d011|223344556677885f5f5f5f5f5f5f	64	gnu	rclb (%rcx)
+d011|223344556677885f5f5f5f5f5f5f	64	intel	rcl byte ptr [rcx], 0x1
+d011|223344556677885f5f5f5f5f5f5f	64	plan9	RCLL $0x1, 0(CX)
+d018|11223344556677885f5f5f5f5f5f	32	intel	rcr byte ptr [eax], 0x1
+d018|11223344556677885f5f5f5f5f5f	32	plan9	RCRL $0x1, 0(AX)
+d018|11223344556677885f5f5f5f5f5f	64	gnu	rcrb (%rax)
+d018|11223344556677885f5f5f5f5f5f	64	intel	rcr byte ptr [rax], 0x1
+d018|11223344556677885f5f5f5f5f5f	64	plan9	RCRL $0x1, 0(AX)
+d020|11223344556677885f5f5f5f5f5f	32	intel	shl byte ptr [eax], 0x1
+d020|11223344556677885f5f5f5f5f5f	32	plan9	SHLL $0x1, 0(AX)
+d020|11223344556677885f5f5f5f5f5f	64	gnu	shlb (%rax)
+d020|11223344556677885f5f5f5f5f5f	64	intel	shl byte ptr [rax], 0x1
+d020|11223344556677885f5f5f5f5f5f	64	plan9	SHLL $0x1, 0(AX)
+d028|11223344556677885f5f5f5f5f5f	32	intel	shr byte ptr [eax], 0x1
+d028|11223344556677885f5f5f5f5f5f	32	plan9	SHRL $0x1, 0(AX)
+d028|11223344556677885f5f5f5f5f5f	64	gnu	shrb (%rax)
+d028|11223344556677885f5f5f5f5f5f	64	intel	shr byte ptr [rax], 0x1
+d028|11223344556677885f5f5f5f5f5f	64	plan9	SHRL $0x1, 0(AX)
+d038|11223344556677885f5f5f5f5f5f	32	intel	sar byte ptr [eax], 0x1
+d038|11223344556677885f5f5f5f5f5f	32	plan9	SARL $0x1, 0(AX)
+d038|11223344556677885f5f5f5f5f5f	64	gnu	sarb (%rax)
+d038|11223344556677885f5f5f5f5f5f	64	intel	sar byte ptr [rax], 0x1
+d038|11223344556677885f5f5f5f5f5f	64	plan9	SARL $0x1, 0(AX)
+d100|11223344556677885f5f5f5f5f5f	32	intel	rol dword ptr [eax], 0x1
+d100|11223344556677885f5f5f5f5f5f	32	plan9	ROLL $0x1, 0(AX)
+d100|11223344556677885f5f5f5f5f5f	64	gnu	roll (%rax)
+d100|11223344556677885f5f5f5f5f5f	64	intel	rol dword ptr [rax], 0x1
+d100|11223344556677885f5f5f5f5f5f	64	plan9	ROLL $0x1, 0(AX)
+d108|11223344556677885f5f5f5f5f5f	32	intel	ror dword ptr [eax], 0x1
+d108|11223344556677885f5f5f5f5f5f	32	plan9	RORL $0x1, 0(AX)
+d108|11223344556677885f5f5f5f5f5f	64	gnu	rorl (%rax)
+d108|11223344556677885f5f5f5f5f5f	64	intel	ror dword ptr [rax], 0x1
+d108|11223344556677885f5f5f5f5f5f	64	plan9	RORL $0x1, 0(AX)
+d111|223344556677885f5f5f5f5f5f5f	32	intel	rcl dword ptr [ecx], 0x1
+d111|223344556677885f5f5f5f5f5f5f	32	plan9	RCLL $0x1, 0(CX)
+d111|223344556677885f5f5f5f5f5f5f	64	gnu	rcll (%rcx)
+d111|223344556677885f5f5f5f5f5f5f	64	intel	rcl dword ptr [rcx], 0x1
+d111|223344556677885f5f5f5f5f5f5f	64	plan9	RCLL $0x1, 0(CX)
+d118|11223344556677885f5f5f5f5f5f	32	intel	rcr dword ptr [eax], 0x1
+d118|11223344556677885f5f5f5f5f5f	32	plan9	RCRL $0x1, 0(AX)
+d118|11223344556677885f5f5f5f5f5f	64	gnu	rcrl (%rax)
+d118|11223344556677885f5f5f5f5f5f	64	intel	rcr dword ptr [rax], 0x1
+d118|11223344556677885f5f5f5f5f5f	64	plan9	RCRL $0x1, 0(AX)
+d120|11223344556677885f5f5f5f5f5f	32	intel	shl dword ptr [eax], 0x1
+d120|11223344556677885f5f5f5f5f5f	32	plan9	SHLL $0x1, 0(AX)
+d120|11223344556677885f5f5f5f5f5f	64	gnu	shll (%rax)
+d120|11223344556677885f5f5f5f5f5f	64	intel	shl dword ptr [rax], 0x1
+d120|11223344556677885f5f5f5f5f5f	64	plan9	SHLL $0x1, 0(AX)
+d128|11223344556677885f5f5f5f5f5f	32	intel	shr dword ptr [eax], 0x1
+d128|11223344556677885f5f5f5f5f5f	32	plan9	SHRL $0x1, 0(AX)
+d128|11223344556677885f5f5f5f5f5f	64	gnu	shrl (%rax)
+d128|11223344556677885f5f5f5f5f5f	64	intel	shr dword ptr [rax], 0x1
+d128|11223344556677885f5f5f5f5f5f	64	plan9	SHRL $0x1, 0(AX)
+d138|11223344556677885f5f5f5f5f5f	32	intel	sar dword ptr [eax], 0x1
+d138|11223344556677885f5f5f5f5f5f	32	plan9	SARL $0x1, 0(AX)
+d138|11223344556677885f5f5f5f5f5f	64	gnu	sarl (%rax)
+d138|11223344556677885f5f5f5f5f5f	64	intel	sar dword ptr [rax], 0x1
+d138|11223344556677885f5f5f5f5f5f	64	plan9	SARL $0x1, 0(AX)
+d200|11223344556677885f5f5f5f5f5f	32	intel	rol byte ptr [eax], cl
+d200|11223344556677885f5f5f5f5f5f	32	plan9	ROLL CL, 0(AX)
+d200|11223344556677885f5f5f5f5f5f	64	gnu	rolb %cl,(%rax)
+d200|11223344556677885f5f5f5f5f5f	64	intel	rol byte ptr [rax], cl
+d200|11223344556677885f5f5f5f5f5f	64	plan9	ROLL CL, 0(AX)
+d208|11223344556677885f5f5f5f5f5f	32	intel	ror byte ptr [eax], cl
+d208|11223344556677885f5f5f5f5f5f	32	plan9	RORL CL, 0(AX)
+d208|11223344556677885f5f5f5f5f5f	64	gnu	rorb %cl,(%rax)
+d208|11223344556677885f5f5f5f5f5f	64	intel	ror byte ptr [rax], cl
+d208|11223344556677885f5f5f5f5f5f	64	plan9	RORL CL, 0(AX)
+d211|223344556677885f5f5f5f5f5f5f	32	intel	rcl byte ptr [ecx], cl
+d211|223344556677885f5f5f5f5f5f5f	32	plan9	RCLL CL, 0(CX)
+d211|223344556677885f5f5f5f5f5f5f	64	gnu	rclb %cl,(%rcx)
+d211|223344556677885f5f5f5f5f5f5f	64	intel	rcl byte ptr [rcx], cl
+d211|223344556677885f5f5f5f5f5f5f	64	plan9	RCLL CL, 0(CX)
+d218|11223344556677885f5f5f5f5f5f	32	intel	rcr byte ptr [eax], cl
+d218|11223344556677885f5f5f5f5f5f	32	plan9	RCRL CL, 0(AX)
+d218|11223344556677885f5f5f5f5f5f	64	gnu	rcrb %cl,(%rax)
+d218|11223344556677885f5f5f5f5f5f	64	intel	rcr byte ptr [rax], cl
+d218|11223344556677885f5f5f5f5f5f	64	plan9	RCRL CL, 0(AX)
+d220|11223344556677885f5f5f5f5f5f	32	intel	shl byte ptr [eax], cl
+d220|11223344556677885f5f5f5f5f5f	32	plan9	SHLL CL, 0(AX)
+d220|11223344556677885f5f5f5f5f5f	64	gnu	shlb %cl,(%rax)
+d220|11223344556677885f5f5f5f5f5f	64	intel	shl byte ptr [rax], cl
+d220|11223344556677885f5f5f5f5f5f	64	plan9	SHLL CL, 0(AX)
+d228|11223344556677885f5f5f5f5f5f	32	intel	shr byte ptr [eax], cl
+d228|11223344556677885f5f5f5f5f5f	32	plan9	SHRL CL, 0(AX)
+d228|11223344556677885f5f5f5f5f5f	64	gnu	shrb %cl,(%rax)
+d228|11223344556677885f5f5f5f5f5f	64	intel	shr byte ptr [rax], cl
+d228|11223344556677885f5f5f5f5f5f	64	plan9	SHRL CL, 0(AX)
+d238|11223344556677885f5f5f5f5f5f	32	intel	sar byte ptr [eax], cl
+d238|11223344556677885f5f5f5f5f5f	32	plan9	SARL CL, 0(AX)
+d238|11223344556677885f5f5f5f5f5f	64	gnu	sarb %cl,(%rax)
+d238|11223344556677885f5f5f5f5f5f	64	intel	sar byte ptr [rax], cl
+d238|11223344556677885f5f5f5f5f5f	64	plan9	SARL CL, 0(AX)
+d300|11223344556677885f5f5f5f5f5f	32	intel	rol dword ptr [eax], cl
+d300|11223344556677885f5f5f5f5f5f	32	plan9	ROLL CL, 0(AX)
+d300|11223344556677885f5f5f5f5f5f	64	gnu	roll %cl,(%rax)
+d300|11223344556677885f5f5f5f5f5f	64	intel	rol dword ptr [rax], cl
+d300|11223344556677885f5f5f5f5f5f	64	plan9	ROLL CL, 0(AX)
+d308|11223344556677885f5f5f5f5f5f	32	intel	ror dword ptr [eax], cl
+d308|11223344556677885f5f5f5f5f5f	32	plan9	RORL CL, 0(AX)
+d308|11223344556677885f5f5f5f5f5f	64	gnu	rorl %cl,(%rax)
+d308|11223344556677885f5f5f5f5f5f	64	intel	ror dword ptr [rax], cl
+d308|11223344556677885f5f5f5f5f5f	64	plan9	RORL CL, 0(AX)
+d311|223344556677885f5f5f5f5f5f5f	32	intel	rcl dword ptr [ecx], cl
+d311|223344556677885f5f5f5f5f5f5f	32	plan9	RCLL CL, 0(CX)
+d311|223344556677885f5f5f5f5f5f5f	64	gnu	rcll %cl,(%rcx)
+d311|223344556677885f5f5f5f5f5f5f	64	intel	rcl dword ptr [rcx], cl
+d311|223344556677885f5f5f5f5f5f5f	64	plan9	RCLL CL, 0(CX)
+d318|11223344556677885f5f5f5f5f5f	32	intel	rcr dword ptr [eax], cl
+d318|11223344556677885f5f5f5f5f5f	32	plan9	RCRL CL, 0(AX)
+d318|11223344556677885f5f5f5f5f5f	64	gnu	rcrl %cl,(%rax)
+d318|11223344556677885f5f5f5f5f5f	64	intel	rcr dword ptr [rax], cl
+d318|11223344556677885f5f5f5f5f5f	64	plan9	RCRL CL, 0(AX)
+d320|11223344556677885f5f5f5f5f5f	32	intel	shl dword ptr [eax], cl
+d320|11223344556677885f5f5f5f5f5f	32	plan9	SHLL CL, 0(AX)
+d320|11223344556677885f5f5f5f5f5f	64	gnu	shll %cl,(%rax)
+d320|11223344556677885f5f5f5f5f5f	64	intel	shl dword ptr [rax], cl
+d320|11223344556677885f5f5f5f5f5f	64	plan9	SHLL CL, 0(AX)
+d328|11223344556677885f5f5f5f5f5f	32	intel	shr dword ptr [eax], cl
+d328|11223344556677885f5f5f5f5f5f	32	plan9	SHRL CL, 0(AX)
+d328|11223344556677885f5f5f5f5f5f	64	gnu	shrl %cl,(%rax)
+d328|11223344556677885f5f5f5f5f5f	64	intel	shr dword ptr [rax], cl
+d328|11223344556677885f5f5f5f5f5f	64	plan9	SHRL CL, 0(AX)
+d338|11223344556677885f5f5f5f5f5f	32	intel	sar dword ptr [eax], cl
+d338|11223344556677885f5f5f5f5f5f	32	plan9	SARL CL, 0(AX)
+d338|11223344556677885f5f5f5f5f5f	64	gnu	sarl %cl,(%rax)
+d338|11223344556677885f5f5f5f5f5f	64	intel	sar dword ptr [rax], cl
+d338|11223344556677885f5f5f5f5f5f	64	plan9	SARL CL, 0(AX)
+d511|223344556677885f5f5f5f5f5f5f	32	intel	aad 0x11
+d511|223344556677885f5f5f5f5f5f5f	32	plan9	AAD $0x11
+d5|11223344556677885f5f5f5f5f5f5f	64	gnu	error: unrecognized instruction
+d5|11223344556677885f5f5f5f5f5f5f	64	intel	error: unrecognized instruction
+d5|11223344556677885f5f5f5f5f5f5f	64	plan9	error: unrecognized instruction
+d800|11223344556677885f5f5f5f5f5f	32	intel	fadd st0, dword ptr [eax]
+d800|11223344556677885f5f5f5f5f5f	32	plan9	FADD 0(AX)
+d800|11223344556677885f5f5f5f5f5f	64	gnu	fadds (%rax)
+d800|11223344556677885f5f5f5f5f5f	64	intel	fadd st0, dword ptr [rax]
+d800|11223344556677885f5f5f5f5f5f	64	plan9	FADD 0(AX)
+d808|11223344556677885f5f5f5f5f5f	32	intel	fmul st0, dword ptr [eax]
+d808|11223344556677885f5f5f5f5f5f	32	plan9	FMUL 0(AX)
+d808|11223344556677885f5f5f5f5f5f	64	gnu	fmuls (%rax)
+d808|11223344556677885f5f5f5f5f5f	64	intel	fmul st0, dword ptr [rax]
+d808|11223344556677885f5f5f5f5f5f	64	plan9	FMUL 0(AX)
+d811|223344556677885f5f5f5f5f5f5f	32	intel	fcom st0, dword ptr [ecx]
+d811|223344556677885f5f5f5f5f5f5f	32	plan9	FCOM 0(CX)
+d811|223344556677885f5f5f5f5f5f5f	64	gnu	fcoms (%rcx)
+d811|223344556677885f5f5f5f5f5f5f	64	intel	fcom st0, dword ptr [rcx]
+d811|223344556677885f5f5f5f5f5f5f	64	plan9	FCOM 0(CX)
+d818|11223344556677885f5f5f5f5f5f	32	intel	fcomp st0, dword ptr [eax]
+d818|11223344556677885f5f5f5f5f5f	32	plan9	FCOMP 0(AX)
+d818|11223344556677885f5f5f5f5f5f	64	gnu	fcomps (%rax)
+d818|11223344556677885f5f5f5f5f5f	64	intel	fcomp st0, dword ptr [rax]
+d818|11223344556677885f5f5f5f5f5f	64	plan9	FCOMP 0(AX)
+d820|11223344556677885f5f5f5f5f5f	32	intel	fsub st0, dword ptr [eax]
+d820|11223344556677885f5f5f5f5f5f	32	plan9	FSUB 0(AX)
+d820|11223344556677885f5f5f5f5f5f	64	gnu	fsubs (%rax)
+d820|11223344556677885f5f5f5f5f5f	64	intel	fsub st0, dword ptr [rax]
+d820|11223344556677885f5f5f5f5f5f	64	plan9	FSUB 0(AX)
+d828|11223344556677885f5f5f5f5f5f	32	intel	fsubr st0, dword ptr [eax]
+d828|11223344556677885f5f5f5f5f5f	32	plan9	FSUBR 0(AX)
+d828|11223344556677885f5f5f5f5f5f	64	gnu	fsubrs (%rax)
+d828|11223344556677885f5f5f5f5f5f	64	intel	fsubr st0, dword ptr [rax]
+d828|11223344556677885f5f5f5f5f5f	64	plan9	FSUBR 0(AX)
+d830|11223344556677885f5f5f5f5f5f	32	intel	fdiv st0, dword ptr [eax]
+d830|11223344556677885f5f5f5f5f5f	32	plan9	FDIV 0(AX)
+d830|11223344556677885f5f5f5f5f5f	64	gnu	fdivs (%rax)
+d830|11223344556677885f5f5f5f5f5f	64	intel	fdiv st0, dword ptr [rax]
+d830|11223344556677885f5f5f5f5f5f	64	plan9	FDIV 0(AX)
+d838|11223344556677885f5f5f5f5f5f	32	intel	fdivr st0, dword ptr [eax]
+d838|11223344556677885f5f5f5f5f5f	32	plan9	FDIVR 0(AX)
+d838|11223344556677885f5f5f5f5f5f	64	gnu	fdivrs (%rax)
+d838|11223344556677885f5f5f5f5f5f	64	intel	fdivr st0, dword ptr [rax]
+d838|11223344556677885f5f5f5f5f5f	64	plan9	FDIVR 0(AX)
+d8c0|11223344556677885f5f5f5f5f5f	32	intel	fadd st0, st0
+d8c0|11223344556677885f5f5f5f5f5f	32	plan9	FADD F0, F0
+d8c0|11223344556677885f5f5f5f5f5f	64	gnu	fadd %st,%st
+d8c0|11223344556677885f5f5f5f5f5f	64	intel	fadd st0, st0
+d8c0|11223344556677885f5f5f5f5f5f	64	plan9	FADD F0, F0
+d8c8|11223344556677885f5f5f5f5f5f	32	intel	fmul st0, st0
+d8c8|11223344556677885f5f5f5f5f5f	32	plan9	FMUL F0, F0
+d8c8|11223344556677885f5f5f5f5f5f	64	gnu	fmul %st,%st
+d8c8|11223344556677885f5f5f5f5f5f	64	intel	fmul st0, st0
+d8c8|11223344556677885f5f5f5f5f5f	64	plan9	FMUL F0, F0
+d8d0|11223344556677885f5f5f5f5f5f	32	intel	fcom st0, st0
+d8d0|11223344556677885f5f5f5f5f5f	32	plan9	FCOM F0
+d8d0|11223344556677885f5f5f5f5f5f	64	gnu	fcom %st
+d8d0|11223344556677885f5f5f5f5f5f	64	intel	fcom st0, st0
+d8d0|11223344556677885f5f5f5f5f5f	64	plan9	FCOM F0
+d8d8|11223344556677885f5f5f5f5f5f	32	intel	fcomp st0, st0
+d8d8|11223344556677885f5f5f5f5f5f	32	plan9	FCOMP F0
+d8d8|11223344556677885f5f5f5f5f5f	64	gnu	fcomp %st
+d8d8|11223344556677885f5f5f5f5f5f	64	intel	fcomp st0, st0
+d8d8|11223344556677885f5f5f5f5f5f	64	plan9	FCOMP F0
+d8e0|11223344556677885f5f5f5f5f5f	32	intel	fsub st0, st0
+d8e0|11223344556677885f5f5f5f5f5f	32	plan9	FSUB F0, F0
+d8e0|11223344556677885f5f5f5f5f5f	64	gnu	fsub %st,%st
+d8e0|11223344556677885f5f5f5f5f5f	64	intel	fsub st0, st0
+d8e0|11223344556677885f5f5f5f5f5f	64	plan9	FSUB F0, F0
+d8e8|11223344556677885f5f5f5f5f5f	32	intel	fsubr st0, st0
+d8e8|11223344556677885f5f5f5f5f5f	32	plan9	FSUBR F0, F0
+d8e8|11223344556677885f5f5f5f5f5f	64	gnu	fsubr %st,%st
+d8e8|11223344556677885f5f5f5f5f5f	64	intel	fsubr st0, st0
+d8e8|11223344556677885f5f5f5f5f5f	64	plan9	FSUBR F0, F0
+d8f0|11223344556677885f5f5f5f5f5f	32	intel	fdiv st0, st0
+d8f0|11223344556677885f5f5f5f5f5f	32	plan9	FDIV F0, F0
+d8f0|11223344556677885f5f5f5f5f5f	64	gnu	fdiv %st,%st
+d8f0|11223344556677885f5f5f5f5f5f	64	intel	fdiv st0, st0
+d8f0|11223344556677885f5f5f5f5f5f	64	plan9	FDIV F0, F0
+d8f8|11223344556677885f5f5f5f5f5f	32	intel	fdivr st0, st0
+d8f8|11223344556677885f5f5f5f5f5f	32	plan9	FDIVR F0, F0
+d8f8|11223344556677885f5f5f5f5f5f	64	gnu	fdivr %st,%st
+d8f8|11223344556677885f5f5f5f5f5f	64	intel	fdivr st0, st0
+d8f8|11223344556677885f5f5f5f5f5f	64	plan9	FDIVR F0, F0
+d900|11223344556677885f5f5f5f5f5f	32	intel	fld st0, dword ptr [eax]
+d900|11223344556677885f5f5f5f5f5f	32	plan9	FLD 0(AX)
+d900|11223344556677885f5f5f5f5f5f	64	gnu	flds (%rax)
+d900|11223344556677885f5f5f5f5f5f	64	intel	fld st0, dword ptr [rax]
+d900|11223344556677885f5f5f5f5f5f	64	plan9	FLD 0(AX)
+d911|223344556677885f5f5f5f5f5f5f	32	intel	fst dword ptr [ecx], st0
+d911|223344556677885f5f5f5f5f5f5f	32	plan9	FST 0(CX)
+d911|223344556677885f5f5f5f5f5f5f	64	gnu	fsts (%rcx)
+d911|223344556677885f5f5f5f5f5f5f	64	intel	fst dword ptr [rcx], st0
+d911|223344556677885f5f5f5f5f5f5f	64	plan9	FST 0(CX)
+d918|11223344556677885f5f5f5f5f5f	32	intel	fstp dword ptr [eax], st0
+d918|11223344556677885f5f5f5f5f5f	32	plan9	FSTP 0(AX)
+d918|11223344556677885f5f5f5f5f5f	64	gnu	fstps (%rax)
+d918|11223344556677885f5f5f5f5f5f	64	intel	fstp dword ptr [rax], st0
+d918|11223344556677885f5f5f5f5f5f	64	plan9	FSTP 0(AX)
+d928|11223344556677885f5f5f5f5f5f	32	intel	fldcw word ptr [eax]
+d928|11223344556677885f5f5f5f5f5f	32	plan9	FLDCW 0(AX)
+d928|11223344556677885f5f5f5f5f5f	64	gnu	fldcw (%rax)
+d928|11223344556677885f5f5f5f5f5f	64	intel	fldcw word ptr [rax]
+d928|11223344556677885f5f5f5f5f5f	64	plan9	FLDCW 0(AX)
+d930|11223344556677885f5f5f5f5f5f	32	intel	fnstenv ptr [eax]
+d930|11223344556677885f5f5f5f5f5f	32	plan9	FNSTENV 0(AX)
+d930|11223344556677885f5f5f5f5f5f	64	gnu	fnstenv (%rax)
+d930|11223344556677885f5f5f5f5f5f	64	intel	fnstenv ptr [rax]
+d930|11223344556677885f5f5f5f5f5f	64	plan9	FNSTENV 0(AX)
+d938|11223344556677885f5f5f5f5f5f	32	intel	fnstcw word ptr [eax]
+d938|11223344556677885f5f5f5f5f5f	32	plan9	FNSTCW 0(AX)
+d938|11223344556677885f5f5f5f5f5f	64	gnu	fnstcw (%rax)
+d938|11223344556677885f5f5f5f5f5f	64	intel	fnstcw word ptr [rax]
+d938|11223344556677885f5f5f5f5f5f	64	plan9	FNSTCW 0(AX)
+d9c0|11223344556677885f5f5f5f5f5f	32	intel	fld st0, st0
+d9c0|11223344556677885f5f5f5f5f5f	32	plan9	FLD F0
+d9c0|11223344556677885f5f5f5f5f5f	64	gnu	fld %st
+d9c0|11223344556677885f5f5f5f5f5f	64	intel	fld st0, st0
+d9c0|11223344556677885f5f5f5f5f5f	64	plan9	FLD F0
+d9c8|11223344556677885f5f5f5f5f5f	32	intel	fxch st0, st0
+d9c8|11223344556677885f5f5f5f5f5f	32	plan9	FXCH F0
+d9c8|11223344556677885f5f5f5f5f5f	64	gnu	fxch %st
+d9c8|11223344556677885f5f5f5f5f5f	64	intel	fxch st0, st0
+d9c8|11223344556677885f5f5f5f5f5f	64	plan9	FXCH F0
+d9d0|11223344556677885f5f5f5f5f5f	32	intel	fnop
+d9d0|11223344556677885f5f5f5f5f5f	32	plan9	FNOP
+d9d0|11223344556677885f5f5f5f5f5f	64	gnu	fnop
+d9d0|11223344556677885f5f5f5f5f5f	64	intel	fnop
+d9d0|11223344556677885f5f5f5f5f5f	64	plan9	FNOP
+d9e0|11223344556677885f5f5f5f5f5f	32	intel	fchs st0
+d9e0|11223344556677885f5f5f5f5f5f	32	plan9	FCHS
+d9e0|11223344556677885f5f5f5f5f5f	64	gnu	fchs
+d9e0|11223344556677885f5f5f5f5f5f	64	intel	fchs st0
+d9e0|11223344556677885f5f5f5f5f5f	64	plan9	FCHS
+d9e1|11223344556677885f5f5f5f5f5f	32	intel	fabs st0
+d9e1|11223344556677885f5f5f5f5f5f	32	plan9	FABS
+d9e1|11223344556677885f5f5f5f5f5f	64	gnu	fabs
+d9e1|11223344556677885f5f5f5f5f5f	64	intel	fabs st0
+d9e1|11223344556677885f5f5f5f5f5f	64	plan9	FABS
+d9e4|11223344556677885f5f5f5f5f5f	32	intel	ftst st0
+d9e4|11223344556677885f5f5f5f5f5f	32	plan9	FTST
+d9e4|11223344556677885f5f5f5f5f5f	64	gnu	ftst
+d9e4|11223344556677885f5f5f5f5f5f	64	intel	ftst st0
+d9e4|11223344556677885f5f5f5f5f5f	64	plan9	FTST
+d9e5|11223344556677885f5f5f5f5f5f	32	intel	fxam st0
+d9e5|11223344556677885f5f5f5f5f5f	32	plan9	FXAM
+d9e5|11223344556677885f5f5f5f5f5f	64	gnu	fxam
+d9e5|11223344556677885f5f5f5f5f5f	64	intel	fxam st0
+d9e5|11223344556677885f5f5f5f5f5f	64	plan9	FXAM
+d9e8|11223344556677885f5f5f5f5f5f	32	intel	fld1 st0
+d9e8|11223344556677885f5f5f5f5f5f	32	plan9	FLD1
+d9e8|11223344556677885f5f5f5f5f5f	64	gnu	fld1
+d9e8|11223344556677885f5f5f5f5f5f	64	intel	fld1 st0
+d9e8|11223344556677885f5f5f5f5f5f	64	plan9	FLD1
+d9e9|11223344556677885f5f5f5f5f5f	32	intel	fldl2t st0
+d9e9|11223344556677885f5f5f5f5f5f	32	plan9	FLDL2T
+d9e9|11223344556677885f5f5f5f5f5f	64	gnu	fldl2t
+d9e9|11223344556677885f5f5f5f5f5f	64	intel	fldl2t st0
+d9e9|11223344556677885f5f5f5f5f5f	64	plan9	FLDL2T
+d9ea|11223344556677885f5f5f5f5f5f	32	intel	fldl2e st0
+d9ea|11223344556677885f5f5f5f5f5f	32	plan9	FLDL2E
+d9ea|11223344556677885f5f5f5f5f5f	64	gnu	fldl2e
+d9ea|11223344556677885f5f5f5f5f5f	64	intel	fldl2e st0
+d9ea|11223344556677885f5f5f5f5f5f	64	plan9	FLDL2E
+d9eb|11223344556677885f5f5f5f5f5f	32	intel	fldpi st0
+d9eb|11223344556677885f5f5f5f5f5f	32	plan9	FLDPI
+d9eb|11223344556677885f5f5f5f5f5f	64	gnu	fldpi
+d9eb|11223344556677885f5f5f5f5f5f	64	intel	fldpi st0
+d9eb|11223344556677885f5f5f5f5f5f	64	plan9	FLDPI
+d9ec|11223344556677885f5f5f5f5f5f	32	intel	fldlg2 st0
+d9ec|11223344556677885f5f5f5f5f5f	32	plan9	FLDLG2
+d9ec|11223344556677885f5f5f5f5f5f	64	gnu	fldlg2
+d9ec|11223344556677885f5f5f5f5f5f	64	intel	fldlg2 st0
+d9ec|11223344556677885f5f5f5f5f5f	64	plan9	FLDLG2
+d9f0|11223344556677885f5f5f5f5f5f	32	intel	f2xm1 st0
+d9f0|11223344556677885f5f5f5f5f5f	32	plan9	F2XM1
+d9f0|11223344556677885f5f5f5f5f5f	64	gnu	f2xm1
+d9f0|11223344556677885f5f5f5f5f5f	64	intel	f2xm1 st0
+d9f0|11223344556677885f5f5f5f5f5f	64	plan9	F2XM1
+d9f1|11223344556677885f5f5f5f5f5f	32	intel	fyl2x st0, st1
+d9f1|11223344556677885f5f5f5f5f5f	32	plan9	FYL2X
+d9f1|11223344556677885f5f5f5f5f5f	64	gnu	fyl2x
+d9f1|11223344556677885f5f5f5f5f5f	64	intel	fyl2x st0, st1
+d9f1|11223344556677885f5f5f5f5f5f	64	plan9	FYL2X
+d9f2|11223344556677885f5f5f5f5f5f	32	intel	fptan st0, st1
+d9f2|11223344556677885f5f5f5f5f5f	32	plan9	FPTAN
+d9f2|11223344556677885f5f5f5f5f5f	64	gnu	fptan
+d9f2|11223344556677885f5f5f5f5f5f	64	intel	fptan st0, st1
+d9f2|11223344556677885f5f5f5f5f5f	64	plan9	FPTAN
+d9f3|11223344556677885f5f5f5f5f5f	32	intel	fpatan st0, st1
+d9f3|11223344556677885f5f5f5f5f5f	32	plan9	FPATAN
+d9f3|11223344556677885f5f5f5f5f5f	64	gnu	fpatan
+d9f3|11223344556677885f5f5f5f5f5f	64	intel	fpatan st0, st1
+d9f3|11223344556677885f5f5f5f5f5f	64	plan9	FPATAN
+d9f4|11223344556677885f5f5f5f5f5f	32	intel	fxtract st0, st1
+d9f4|11223344556677885f5f5f5f5f5f	32	plan9	FXTRACT
+d9f4|11223344556677885f5f5f5f5f5f	64	gnu	fxtract
+d9f4|11223344556677885f5f5f5f5f5f	64	intel	fxtract st0, st1
+d9f4|11223344556677885f5f5f5f5f5f	64	plan9	FXTRACT
+d9f5|11223344556677885f5f5f5f5f5f	32	intel	fprem1 st0, st1
+d9f5|11223344556677885f5f5f5f5f5f	32	plan9	FPREM1
+d9f5|11223344556677885f5f5f5f5f5f	64	gnu	fprem1
+d9f5|11223344556677885f5f5f5f5f5f	64	intel	fprem1 st0, st1
+d9f5|11223344556677885f5f5f5f5f5f	64	plan9	FPREM1
+d9f6|11223344556677885f5f5f5f5f5f	32	intel	fdecstp
+d9f6|11223344556677885f5f5f5f5f5f	32	plan9	FDECSTP
+d9f6|11223344556677885f5f5f5f5f5f	64	gnu	fdecstp
+d9f6|11223344556677885f5f5f5f5f5f	64	intel	fdecstp
+d9f6|11223344556677885f5f5f5f5f5f	64	plan9	FDECSTP
+d9f7|11223344556677885f5f5f5f5f5f	32	intel	fincstp
+d9f7|11223344556677885f5f5f5f5f5f	32	plan9	FINCSTP
+d9f7|11223344556677885f5f5f5f5f5f	64	gnu	fincstp
+d9f7|11223344556677885f5f5f5f5f5f	64	intel	fincstp
+d9f7|11223344556677885f5f5f5f5f5f	64	plan9	FINCSTP
+d9f8|11223344556677885f5f5f5f5f5f	32	intel	fprem st0, st1
+d9f8|11223344556677885f5f5f5f5f5f	32	plan9	FPREM
+d9f8|11223344556677885f5f5f5f5f5f	64	gnu	fprem
+d9f8|11223344556677885f5f5f5f5f5f	64	intel	fprem st0, st1
+d9f8|11223344556677885f5f5f5f5f5f	64	plan9	FPREM
+d9f9|11223344556677885f5f5f5f5f5f	32	intel	fyl2xp1 st0, st1
+d9f9|11223344556677885f5f5f5f5f5f	32	plan9	FYL2XP1
+d9f9|11223344556677885f5f5f5f5f5f	64	gnu	fyl2xp1
+d9f9|11223344556677885f5f5f5f5f5f	64	intel	fyl2xp1 st0, st1
+d9f9|11223344556677885f5f5f5f5f5f	64	plan9	FYL2XP1
+d9fa|11223344556677885f5f5f5f5f5f	32	intel	fsqrt st0
+d9fa|11223344556677885f5f5f5f5f5f	32	plan9	FSQRT
+d9fa|11223344556677885f5f5f5f5f5f	64	gnu	fsqrt
+d9fa|11223344556677885f5f5f5f5f5f	64	intel	fsqrt st0
+d9fa|11223344556677885f5f5f5f5f5f	64	plan9	FSQRT
+d9fb|11223344556677885f5f5f5f5f5f	32	intel	fsincos st0, st1
+d9fb|11223344556677885f5f5f5f5f5f	32	plan9	FSINCOS
+d9fb|11223344556677885f5f5f5f5f5f	64	gnu	fsincos
+d9fb|11223344556677885f5f5f5f5f5f	64	intel	fsincos st0, st1
+d9fb|11223344556677885f5f5f5f5f5f	64	plan9	FSINCOS
+d9fc|11223344556677885f5f5f5f5f5f	32	intel	frndint st0
+d9fc|11223344556677885f5f5f5f5f5f	32	plan9	FRNDINT
+d9fc|11223344556677885f5f5f5f5f5f	64	gnu	frndint
+d9fc|11223344556677885f5f5f5f5f5f	64	intel	frndint st0
+d9fc|11223344556677885f5f5f5f5f5f	64	plan9	FRNDINT
+d9fd|11223344556677885f5f5f5f5f5f	32	intel	fscale st0, st1
+d9fd|11223344556677885f5f5f5f5f5f	32	plan9	FSCALE
+d9fd|11223344556677885f5f5f5f5f5f	64	gnu	fscale
+d9fd|11223344556677885f5f5f5f5f5f	64	intel	fscale st0, st1
+d9fd|11223344556677885f5f5f5f5f5f	64	plan9	FSCALE
+d9fe|11223344556677885f5f5f5f5f5f	32	intel	fsin st0
+d9fe|11223344556677885f5f5f5f5f5f	32	plan9	FSIN
+d9fe|11223344556677885f5f5f5f5f5f	64	gnu	fsin
+d9fe|11223344556677885f5f5f5f5f5f	64	intel	fsin st0
+d9fe|11223344556677885f5f5f5f5f5f	64	plan9	FSIN
+d9ff|11223344556677885f5f5f5f5f5f	32	intel	fcos st0
+d9ff|11223344556677885f5f5f5f5f5f	32	plan9	FCOS
+d9ff|11223344556677885f5f5f5f5f5f	64	gnu	fcos
+d9ff|11223344556677885f5f5f5f5f5f	64	intel	fcos st0
+d9ff|11223344556677885f5f5f5f5f5f	64	plan9	FCOS
+da00|11223344556677885f5f5f5f5f5f	32	intel	fiadd st0, dword ptr [eax]
+da00|11223344556677885f5f5f5f5f5f	32	plan9	FIADD 0(AX)
+da00|11223344556677885f5f5f5f5f5f	64	gnu	fiaddl (%rax)
+da00|11223344556677885f5f5f5f5f5f	64	intel	fiadd st0, dword ptr [rax]
+da00|11223344556677885f5f5f5f5f5f	64	plan9	FIADD 0(AX)
+da08|11223344556677885f5f5f5f5f5f	32	intel	fimul st0, dword ptr [eax]
+da08|11223344556677885f5f5f5f5f5f	32	plan9	FIMUL 0(AX)
+da08|11223344556677885f5f5f5f5f5f	64	gnu	fimull (%rax)
+da08|11223344556677885f5f5f5f5f5f	64	intel	fimul st0, dword ptr [rax]
+da08|11223344556677885f5f5f5f5f5f	64	plan9	FIMUL 0(AX)
+da11|223344556677885f5f5f5f5f5f5f	32	intel	ficom st0, dword ptr [ecx]
+da11|223344556677885f5f5f5f5f5f5f	32	plan9	FICOM 0(CX)
+da11|223344556677885f5f5f5f5f5f5f	64	gnu	ficoml (%rcx)
+da11|223344556677885f5f5f5f5f5f5f	64	intel	ficom st0, dword ptr [rcx]
+da11|223344556677885f5f5f5f5f5f5f	64	plan9	FICOM 0(CX)
+da18|11223344556677885f5f5f5f5f5f	32	intel	ficomp st0, dword ptr [eax]
+da18|11223344556677885f5f5f5f5f5f	32	plan9	FICOMP 0(AX)
+da18|11223344556677885f5f5f5f5f5f	64	gnu	ficompl (%rax)
+da18|11223344556677885f5f5f5f5f5f	64	intel	ficomp st0, dword ptr [rax]
+da18|11223344556677885f5f5f5f5f5f	64	plan9	FICOMP 0(AX)
+da20|11223344556677885f5f5f5f5f5f	32	intel	fisub st0, dword ptr [eax]
+da20|11223344556677885f5f5f5f5f5f	32	plan9	FISUB 0(AX)
+da20|11223344556677885f5f5f5f5f5f	64	gnu	fisubl (%rax)
+da20|11223344556677885f5f5f5f5f5f	64	intel	fisub st0, dword ptr [rax]
+da20|11223344556677885f5f5f5f5f5f	64	plan9	FISUB 0(AX)
+da28|11223344556677885f5f5f5f5f5f	32	intel	fisubr st0, dword ptr [eax]
+da28|11223344556677885f5f5f5f5f5f	32	plan9	FISUBR 0(AX)
+da28|11223344556677885f5f5f5f5f5f	64	gnu	fisubrl (%rax)
+da28|11223344556677885f5f5f5f5f5f	64	intel	fisubr st0, dword ptr [rax]
+da28|11223344556677885f5f5f5f5f5f	64	plan9	FISUBR 0(AX)
+da30|11223344556677885f5f5f5f5f5f	32	intel	fidiv st0, dword ptr [eax]
+da30|11223344556677885f5f5f5f5f5f	32	plan9	FIDIV 0(AX)
+da30|11223344556677885f5f5f5f5f5f	64	gnu	fidivl (%rax)
+da30|11223344556677885f5f5f5f5f5f	64	intel	fidiv st0, dword ptr [rax]
+da30|11223344556677885f5f5f5f5f5f	64	plan9	FIDIV 0(AX)
+da38|11223344556677885f5f5f5f5f5f	32	intel	fidivr st0, dword ptr [eax]
+da38|11223344556677885f5f5f5f5f5f	32	plan9	FIDIVR 0(AX)
+da38|11223344556677885f5f5f5f5f5f	64	gnu	fidivrl (%rax)
+da38|11223344556677885f5f5f5f5f5f	64	intel	fidivr st0, dword ptr [rax]
+da38|11223344556677885f5f5f5f5f5f	64	plan9	FIDIVR 0(AX)
+dac0|11223344556677885f5f5f5f5f5f	32	intel	fcmovb st0, st0
+dac0|11223344556677885f5f5f5f5f5f	32	plan9	FCMOVB F0, F0
+dac0|11223344556677885f5f5f5f5f5f	64	gnu	fcmovb %st,%st
+dac0|11223344556677885f5f5f5f5f5f	64	intel	fcmovb st0, st0
+dac0|11223344556677885f5f5f5f5f5f	64	plan9	FCMOVB F0, F0
+dac8|11223344556677885f5f5f5f5f5f	32	intel	fcmove st0, st0
+dac8|11223344556677885f5f5f5f5f5f	32	plan9	FCMOVE F0, F0
+dac8|11223344556677885f5f5f5f5f5f	64	gnu	fcmove %st,%st
+dac8|11223344556677885f5f5f5f5f5f	64	intel	fcmove st0, st0
+dac8|11223344556677885f5f5f5f5f5f	64	plan9	FCMOVE F0, F0
+dad0|11223344556677885f5f5f5f5f5f	32	intel	fcmovbe st0, st0
+dad0|11223344556677885f5f5f5f5f5f	32	plan9	FCMOVBE F0, F0
+dad0|11223344556677885f5f5f5f5f5f	64	gnu	fcmovbe %st,%st
+dad0|11223344556677885f5f5f5f5f5f	64	intel	fcmovbe st0, st0
+dad0|11223344556677885f5f5f5f5f5f	64	plan9	FCMOVBE F0, F0
+dad8|11223344556677885f5f5f5f5f5f	32	intel	fcmovu st0, st0
+dad8|11223344556677885f5f5f5f5f5f	32	plan9	FCMOVU F0, F0
+dad8|11223344556677885f5f5f5f5f5f	64	gnu	fcmovu %st,%st
+dad8|11223344556677885f5f5f5f5f5f	64	intel	fcmovu st0, st0
+dad8|11223344556677885f5f5f5f5f5f	64	plan9	FCMOVU F0, F0
+dae9|11223344556677885f5f5f5f5f5f	32	intel	fucompp st0, st1
+dae9|11223344556677885f5f5f5f5f5f	32	plan9	FUCOMPP
+dae9|11223344556677885f5f5f5f5f5f	64	gnu	fucompp
+dae9|11223344556677885f5f5f5f5f5f	64	intel	fucompp st0, st1
+dae9|11223344556677885f5f5f5f5f5f	64	plan9	FUCOMPP
+db00|11223344556677885f5f5f5f5f5f	32	intel	fild st0, dword ptr [eax]
+db00|11223344556677885f5f5f5f5f5f	32	plan9	FILD 0(AX)
+db00|11223344556677885f5f5f5f5f5f	64	gnu	fildl (%rax)
+db00|11223344556677885f5f5f5f5f5f	64	intel	fild st0, dword ptr [rax]
+db00|11223344556677885f5f5f5f5f5f	64	plan9	FILD 0(AX)
+db08|11223344556677885f5f5f5f5f5f	32	intel	fisttp dword ptr [eax], st0
+db08|11223344556677885f5f5f5f5f5f	32	plan9	FISTTP 0(AX)
+db08|11223344556677885f5f5f5f5f5f	64	gnu	fisttpl (%rax)
+db08|11223344556677885f5f5f5f5f5f	64	intel	fisttp dword ptr [rax], st0
+db08|11223344556677885f5f5f5f5f5f	64	plan9	FISTTP 0(AX)
+db11|223344556677885f5f5f5f5f5f5f	32	intel	fist dword ptr [ecx], st0
+db11|223344556677885f5f5f5f5f5f5f	32	plan9	FIST 0(CX)
+db11|223344556677885f5f5f5f5f5f5f	64	gnu	fistl (%rcx)
+db11|223344556677885f5f5f5f5f5f5f	64	intel	fist dword ptr [rcx], st0
+db11|223344556677885f5f5f5f5f5f5f	64	plan9	FIST 0(CX)
+db18|11223344556677885f5f5f5f5f5f	32	intel	fistp dword ptr [eax], st0
+db18|11223344556677885f5f5f5f5f5f	32	plan9	FISTP 0(AX)
+db18|11223344556677885f5f5f5f5f5f	64	gnu	fistpl (%rax)
+db18|11223344556677885f5f5f5f5f5f	64	intel	fistp dword ptr [rax], st0
+db18|11223344556677885f5f5f5f5f5f	64	plan9	FISTP 0(AX)
+db28|11223344556677885f5f5f5f5f5f	32	intel	fld st0, ptr [eax]
+db28|11223344556677885f5f5f5f5f5f	32	plan9	FLD 0(AX)
+db28|11223344556677885f5f5f5f5f5f	64	gnu	fldt (%rax)
+db28|11223344556677885f5f5f5f5f5f	64	intel	fld st0, ptr [rax]
+db28|11223344556677885f5f5f5f5f5f	64	plan9	FLD 0(AX)
+db38|11223344556677885f5f5f5f5f5f	32	intel	fstp ptr [eax], st0
+db38|11223344556677885f5f5f5f5f5f	32	plan9	FSTP 0(AX)
+db38|11223344556677885f5f5f5f5f5f	64	gnu	fstpt (%rax)
+db38|11223344556677885f5f5f5f5f5f	64	intel	fstp ptr [rax], st0
+db38|11223344556677885f5f5f5f5f5f	64	plan9	FSTP 0(AX)
+dbc0|11223344556677885f5f5f5f5f5f	32	intel	fcmovnb st0, st0
+dbc0|11223344556677885f5f5f5f5f5f	32	plan9	FCMOVNB F0, F0
+dbc0|11223344556677885f5f5f5f5f5f	64	gnu	fcmovnb %st,%st
+dbc0|11223344556677885f5f5f5f5f5f	64	intel	fcmovnb st0, st0
+dbc0|11223344556677885f5f5f5f5f5f	64	plan9	FCMOVNB F0, F0
+dbc8|11223344556677885f5f5f5f5f5f	32	intel	fcmovne st0, st0
+dbc8|11223344556677885f5f5f5f5f5f	32	plan9	FCMOVNE F0, F0
+dbc8|11223344556677885f5f5f5f5f5f	64	gnu	fcmovne %st,%st
+dbc8|11223344556677885f5f5f5f5f5f	64	intel	fcmovne st0, st0
+dbc8|11223344556677885f5f5f5f5f5f	64	plan9	FCMOVNE F0, F0
+dbd0|11223344556677885f5f5f5f5f5f	32	intel	fcmovnbe st0, st0
+dbd0|11223344556677885f5f5f5f5f5f	32	plan9	FCMOVNBE F0, F0
+dbd0|11223344556677885f5f5f5f5f5f	64	gnu	fcmovnbe %st,%st
+dbd0|11223344556677885f5f5f5f5f5f	64	intel	fcmovnbe st0, st0
+dbd0|11223344556677885f5f5f5f5f5f	64	plan9	FCMOVNBE F0, F0
+dbd8|11223344556677885f5f5f5f5f5f	32	intel	fcmovnu st0, st0
+dbd8|11223344556677885f5f5f5f5f5f	32	plan9	FCMOVNU F0, F0
+dbd8|11223344556677885f5f5f5f5f5f	64	gnu	fcmovnu %st,%st
+dbd8|11223344556677885f5f5f5f5f5f	64	intel	fcmovnu st0, st0
+dbd8|11223344556677885f5f5f5f5f5f	64	plan9	FCMOVNU F0, F0
+dbe2|11223344556677885f5f5f5f5f5f	32	intel	fnclex
+dbe2|11223344556677885f5f5f5f5f5f	32	plan9	FNCLEX
+dbe2|11223344556677885f5f5f5f5f5f	64	gnu	fnclex
+dbe2|11223344556677885f5f5f5f5f5f	64	intel	fnclex
+dbe2|11223344556677885f5f5f5f5f5f	64	plan9	FNCLEX
+dbe3|11223344556677885f5f5f5f5f5f	32	intel	fninit
+dbe3|11223344556677885f5f5f5f5f5f	32	plan9	FNINIT
+dbe3|11223344556677885f5f5f5f5f5f	64	gnu	fninit
+dbe3|11223344556677885f5f5f5f5f5f	64	intel	fninit
+dbe3|11223344556677885f5f5f5f5f5f	64	plan9	FNINIT
+dbe8|11223344556677885f5f5f5f5f5f	32	intel	fucomi st0, st0
+dbe8|11223344556677885f5f5f5f5f5f	32	plan9	FUCOMI F0, F0
+dbe8|11223344556677885f5f5f5f5f5f	64	gnu	fucomi %st,%st
+dbe8|11223344556677885f5f5f5f5f5f	64	intel	fucomi st0, st0
+dbe8|11223344556677885f5f5f5f5f5f	64	plan9	FUCOMI F0, F0
+dbf0|11223344556677885f5f5f5f5f5f	32	intel	fcomi st0, st0
+dbf0|11223344556677885f5f5f5f5f5f	32	plan9	FCOMI F0, F0
+dbf0|11223344556677885f5f5f5f5f5f	64	gnu	fcomi %st,%st
+dbf0|11223344556677885f5f5f5f5f5f	64	intel	fcomi st0, st0
+dbf0|11223344556677885f5f5f5f5f5f	64	plan9	FCOMI F0, F0
+dc00|11223344556677885f5f5f5f5f5f	32	intel	fadd st0, qword ptr [eax]
+dc00|11223344556677885f5f5f5f5f5f	32	plan9	FADD 0(AX)
+dc00|11223344556677885f5f5f5f5f5f	64	gnu	faddl (%rax)
+dc00|11223344556677885f5f5f5f5f5f	64	intel	fadd st0, qword ptr [rax]
+dc00|11223344556677885f5f5f5f5f5f	64	plan9	FADD 0(AX)
+dc08|11223344556677885f5f5f5f5f5f	32	intel	fmul st0, qword ptr [eax]
+dc08|11223344556677885f5f5f5f5f5f	32	plan9	FMUL 0(AX)
+dc08|11223344556677885f5f5f5f5f5f	64	gnu	fmull (%rax)
+dc08|11223344556677885f5f5f5f5f5f	64	intel	fmul st0, qword ptr [rax]
+dc08|11223344556677885f5f5f5f5f5f	64	plan9	FMUL 0(AX)
+dc11|223344556677885f5f5f5f5f5f5f	32	intel	fcom st0, qword ptr [ecx]
+dc11|223344556677885f5f5f5f5f5f5f	32	plan9	FCOM 0(CX)
+dc11|223344556677885f5f5f5f5f5f5f	64	gnu	fcoml (%rcx)
+dc11|223344556677885f5f5f5f5f5f5f	64	intel	fcom st0, qword ptr [rcx]
+dc11|223344556677885f5f5f5f5f5f5f	64	plan9	FCOM 0(CX)
+dc18|11223344556677885f5f5f5f5f5f	32	intel	fcomp st0, qword ptr [eax]
+dc18|11223344556677885f5f5f5f5f5f	32	plan9	FCOMP 0(AX)
+dc18|11223344556677885f5f5f5f5f5f	64	gnu	fcompl (%rax)
+dc18|11223344556677885f5f5f5f5f5f	64	intel	fcomp st0, qword ptr [rax]
+dc18|11223344556677885f5f5f5f5f5f	64	plan9	FCOMP 0(AX)
+dc20|11223344556677885f5f5f5f5f5f	32	intel	fsub st0, qword ptr [eax]
+dc20|11223344556677885f5f5f5f5f5f	32	plan9	FSUB 0(AX)
+dc20|11223344556677885f5f5f5f5f5f	64	gnu	fsubl (%rax)
+dc20|11223344556677885f5f5f5f5f5f	64	intel	fsub st0, qword ptr [rax]
+dc20|11223344556677885f5f5f5f5f5f	64	plan9	FSUB 0(AX)
+dc28|11223344556677885f5f5f5f5f5f	32	intel	fsubr st0, qword ptr [eax]
+dc28|11223344556677885f5f5f5f5f5f	32	plan9	FSUBR 0(AX)
+dc28|11223344556677885f5f5f5f5f5f	64	gnu	fsubrl (%rax)
+dc28|11223344556677885f5f5f5f5f5f	64	intel	fsubr st0, qword ptr [rax]
+dc28|11223344556677885f5f5f5f5f5f	64	plan9	FSUBR 0(AX)
+dc30|11223344556677885f5f5f5f5f5f	32	intel	fdiv st0, qword ptr [eax]
+dc30|11223344556677885f5f5f5f5f5f	32	plan9	FDIV 0(AX)
+dc30|11223344556677885f5f5f5f5f5f	64	gnu	fdivl (%rax)
+dc30|11223344556677885f5f5f5f5f5f	64	intel	fdiv st0, qword ptr [rax]
+dc30|11223344556677885f5f5f5f5f5f	64	plan9	FDIV 0(AX)
+dc38|11223344556677885f5f5f5f5f5f	32	intel	fdivr st0, qword ptr [eax]
+dc38|11223344556677885f5f5f5f5f5f	32	plan9	FDIVR 0(AX)
+dc38|11223344556677885f5f5f5f5f5f	64	gnu	fdivrl (%rax)
+dc38|11223344556677885f5f5f5f5f5f	64	intel	fdivr st0, qword ptr [rax]
+dc38|11223344556677885f5f5f5f5f5f	64	plan9	FDIVR 0(AX)
+dcc0|11223344556677885f5f5f5f5f5f	32	intel	fadd st0, st0
+dcc0|11223344556677885f5f5f5f5f5f	32	plan9	FADD F0, F0
+dcc0|11223344556677885f5f5f5f5f5f	64	gnu	fadd %st,%st
+dcc0|11223344556677885f5f5f5f5f5f	64	intel	fadd st0, st0
+dcc0|11223344556677885f5f5f5f5f5f	64	plan9	FADD F0, F0
+dcc8|11223344556677885f5f5f5f5f5f	32	intel	fmul st0, st0
+dcc8|11223344556677885f5f5f5f5f5f	32	plan9	FMUL F0, F0
+dcc8|11223344556677885f5f5f5f5f5f	64	gnu	fmul %st,%st
+dcc8|11223344556677885f5f5f5f5f5f	64	intel	fmul st0, st0
+dcc8|11223344556677885f5f5f5f5f5f	64	plan9	FMUL F0, F0
+dce0|11223344556677885f5f5f5f5f5f	32	intel	fsubr st0, st0
+dce0|11223344556677885f5f5f5f5f5f	32	plan9	FSUBR F0, F0
+dce0|11223344556677885f5f5f5f5f5f	64	gnu	fsub %st,%st
+dce0|11223344556677885f5f5f5f5f5f	64	intel	fsubr st0, st0
+dce0|11223344556677885f5f5f5f5f5f	64	plan9	FSUBR F0, F0
+dce8|11223344556677885f5f5f5f5f5f	32	intel	fsub st0, st0
+dce8|11223344556677885f5f5f5f5f5f	32	plan9	FSUB F0, F0
+dce8|11223344556677885f5f5f5f5f5f	64	gnu	fsubr %st,%st
+dce8|11223344556677885f5f5f5f5f5f	64	intel	fsub st0, st0
+dce8|11223344556677885f5f5f5f5f5f	64	plan9	FSUB F0, F0
+dcf0|11223344556677885f5f5f5f5f5f	32	intel	fdivr st0, st0
+dcf0|11223344556677885f5f5f5f5f5f	32	plan9	FDIVR F0, F0
+dcf0|11223344556677885f5f5f5f5f5f	64	gnu	fdiv %st,%st
+dcf0|11223344556677885f5f5f5f5f5f	64	intel	fdivr st0, st0
+dcf0|11223344556677885f5f5f5f5f5f	64	plan9	FDIVR F0, F0
+dcf8|11223344556677885f5f5f5f5f5f	32	intel	fdiv st0, st0
+dcf8|11223344556677885f5f5f5f5f5f	32	plan9	FDIV F0, F0
+dcf8|11223344556677885f5f5f5f5f5f	64	gnu	fdivr %st,%st
+dcf8|11223344556677885f5f5f5f5f5f	64	intel	fdiv st0, st0
+dcf8|11223344556677885f5f5f5f5f5f	64	plan9	FDIV F0, F0
+dd00|11223344556677885f5f5f5f5f5f	32	intel	fld st0, qword ptr [eax]
+dd00|11223344556677885f5f5f5f5f5f	32	plan9	FLD 0(AX)
+dd00|11223344556677885f5f5f5f5f5f	64	gnu	fldl (%rax)
+dd00|11223344556677885f5f5f5f5f5f	64	intel	fld st0, qword ptr [rax]
+dd00|11223344556677885f5f5f5f5f5f	64	plan9	FLD 0(AX)
+dd08|11223344556677885f5f5f5f5f5f	32	intel	fisttp qword ptr [eax], st0
+dd08|11223344556677885f5f5f5f5f5f	32	plan9	FISTTP 0(AX)
+dd08|11223344556677885f5f5f5f5f5f	64	gnu	fisttpll (%rax)
+dd08|11223344556677885f5f5f5f5f5f	64	intel	fisttp qword ptr [rax], st0
+dd08|11223344556677885f5f5f5f5f5f	64	plan9	FISTTP 0(AX)
+dd11|223344556677885f5f5f5f5f5f5f	32	intel	fst qword ptr [ecx], st0
+dd11|223344556677885f5f5f5f5f5f5f	32	plan9	FST 0(CX)
+dd11|223344556677885f5f5f5f5f5f5f	64	gnu	fstl (%rcx)
+dd11|223344556677885f5f5f5f5f5f5f	64	intel	fst qword ptr [rcx], st0
+dd11|223344556677885f5f5f5f5f5f5f	64	plan9	FST 0(CX)
+dd18|11223344556677885f5f5f5f5f5f	32	intel	fstp qword ptr [eax], st0
+dd18|11223344556677885f5f5f5f5f5f	32	plan9	FSTP 0(AX)
+dd18|11223344556677885f5f5f5f5f5f	64	gnu	fstpl (%rax)
+dd18|11223344556677885f5f5f5f5f5f	64	intel	fstp qword ptr [rax], st0
+dd18|11223344556677885f5f5f5f5f5f	64	plan9	FSTP 0(AX)
+dd20|11223344556677885f5f5f5f5f5f	32	intel	frstor ptr [eax]
+dd20|11223344556677885f5f5f5f5f5f	32	plan9	FRSTORL 0(AX)
+dd20|11223344556677885f5f5f5f5f5f	64	gnu	frstor (%rax)
+dd20|11223344556677885f5f5f5f5f5f	64	intel	frstor ptr [rax]
+dd20|11223344556677885f5f5f5f5f5f	64	plan9	FRSTORL 0(AX)
+dd30|11223344556677885f5f5f5f5f5f	32	intel	fnsave ptr [eax]
+dd30|11223344556677885f5f5f5f5f5f	32	plan9	FNSAVE 0(AX)
+dd30|11223344556677885f5f5f5f5f5f	64	gnu	fnsave (%rax)
+dd30|11223344556677885f5f5f5f5f5f	64	intel	fnsave ptr [rax]
+dd30|11223344556677885f5f5f5f5f5f	64	plan9	FNSAVE 0(AX)
+dd38|11223344556677885f5f5f5f5f5f	32	intel	fnstsw word ptr [eax]
+dd38|11223344556677885f5f5f5f5f5f	32	plan9	FNSTSW 0(AX)
+dd38|11223344556677885f5f5f5f5f5f	64	gnu	fnstsw (%rax)
+dd38|11223344556677885f5f5f5f5f5f	64	intel	fnstsw word ptr [rax]
+dd38|11223344556677885f5f5f5f5f5f	64	plan9	FNSTSW 0(AX)
+ddc0|11223344556677885f5f5f5f5f5f	32	intel	ffree st0
+ddc0|11223344556677885f5f5f5f5f5f	32	plan9	FFREE F0
+ddc0|11223344556677885f5f5f5f5f5f	64	gnu	ffree %st
+ddc0|11223344556677885f5f5f5f5f5f	64	intel	ffree st0
+ddc0|11223344556677885f5f5f5f5f5f	64	plan9	FFREE F0
+ddd0|11223344556677885f5f5f5f5f5f	32	intel	fst st0, st0
+ddd0|11223344556677885f5f5f5f5f5f	32	plan9	FST F0
+ddd0|11223344556677885f5f5f5f5f5f	64	gnu	fst %st
+ddd0|11223344556677885f5f5f5f5f5f	64	intel	fst st0, st0
+ddd0|11223344556677885f5f5f5f5f5f	64	plan9	FST F0
+ddd8|11223344556677885f5f5f5f5f5f	32	intel	fstp st0, st0
+ddd8|11223344556677885f5f5f5f5f5f	32	plan9	FSTP F0
+ddd8|11223344556677885f5f5f5f5f5f	64	gnu	fstp %st
+ddd8|11223344556677885f5f5f5f5f5f	64	intel	fstp st0, st0
+ddd8|11223344556677885f5f5f5f5f5f	64	plan9	FSTP F0
+dde0|11223344556677885f5f5f5f5f5f	32	intel	fucom st0, st0
+dde0|11223344556677885f5f5f5f5f5f	32	plan9	FUCOM F0
+dde0|11223344556677885f5f5f5f5f5f	64	gnu	fucom %st
+dde0|11223344556677885f5f5f5f5f5f	64	intel	fucom st0, st0
+dde0|11223344556677885f5f5f5f5f5f	64	plan9	FUCOM F0
+dde8|11223344556677885f5f5f5f5f5f	32	intel	fucomp st0, st0
+dde8|11223344556677885f5f5f5f5f5f	32	plan9	FUCOMP F0
+dde8|11223344556677885f5f5f5f5f5f	64	gnu	fucomp %st
+dde8|11223344556677885f5f5f5f5f5f	64	intel	fucomp st0, st0
+dde8|11223344556677885f5f5f5f5f5f	64	plan9	FUCOMP F0
+de00|11223344556677885f5f5f5f5f5f	32	intel	fiadd st0, word ptr [eax]
+de00|11223344556677885f5f5f5f5f5f	32	plan9	FIADD 0(AX)
+de00|11223344556677885f5f5f5f5f5f	64	gnu	fiadd (%rax)
+de00|11223344556677885f5f5f5f5f5f	64	intel	fiadd st0, word ptr [rax]
+de00|11223344556677885f5f5f5f5f5f	64	plan9	FIADD 0(AX)
+de08|11223344556677885f5f5f5f5f5f	32	intel	fimul st0, word ptr [eax]
+de08|11223344556677885f5f5f5f5f5f	32	plan9	FIMUL 0(AX)
+de08|11223344556677885f5f5f5f5f5f	64	gnu	fimul (%rax)
+de08|11223344556677885f5f5f5f5f5f	64	intel	fimul st0, word ptr [rax]
+de08|11223344556677885f5f5f5f5f5f	64	plan9	FIMUL 0(AX)
+de11|223344556677885f5f5f5f5f5f5f	32	intel	ficom st0, word ptr [ecx]
+de11|223344556677885f5f5f5f5f5f5f	32	plan9	FICOM 0(CX)
+de11|223344556677885f5f5f5f5f5f5f	64	gnu	ficom (%rcx)
+de11|223344556677885f5f5f5f5f5f5f	64	intel	ficom st0, word ptr [rcx]
+de11|223344556677885f5f5f5f5f5f5f	64	plan9	FICOM 0(CX)
+de18|11223344556677885f5f5f5f5f5f	32	intel	ficomp st0, word ptr [eax]
+de18|11223344556677885f5f5f5f5f5f	32	plan9	FICOMP 0(AX)
+de18|11223344556677885f5f5f5f5f5f	64	gnu	ficomp (%rax)
+de18|11223344556677885f5f5f5f5f5f	64	intel	ficomp st0, word ptr [rax]
+de18|11223344556677885f5f5f5f5f5f	64	plan9	FICOMP 0(AX)
+de20|11223344556677885f5f5f5f5f5f	32	intel	fisub st0, word ptr [eax]
+de20|11223344556677885f5f5f5f5f5f	32	plan9	FISUB 0(AX)
+de20|11223344556677885f5f5f5f5f5f	64	gnu	fisub (%rax)
+de20|11223344556677885f5f5f5f5f5f	64	intel	fisub st0, word ptr [rax]
+de20|11223344556677885f5f5f5f5f5f	64	plan9	FISUB 0(AX)
+de28|11223344556677885f5f5f5f5f5f	32	intel	fisubr st0, word ptr [eax]
+de28|11223344556677885f5f5f5f5f5f	32	plan9	FISUBR 0(AX)
+de28|11223344556677885f5f5f5f5f5f	64	gnu	fisubr (%rax)
+de28|11223344556677885f5f5f5f5f5f	64	intel	fisubr st0, word ptr [rax]
+de28|11223344556677885f5f5f5f5f5f	64	plan9	FISUBR 0(AX)
+de30|11223344556677885f5f5f5f5f5f	32	intel	fidiv st0, word ptr [eax]
+de30|11223344556677885f5f5f5f5f5f	32	plan9	FIDIV 0(AX)
+de30|11223344556677885f5f5f5f5f5f	64	gnu	fidiv (%rax)
+de30|11223344556677885f5f5f5f5f5f	64	intel	fidiv st0, word ptr [rax]
+de30|11223344556677885f5f5f5f5f5f	64	plan9	FIDIV 0(AX)
+de38|11223344556677885f5f5f5f5f5f	32	intel	fidivr st0, word ptr [eax]
+de38|11223344556677885f5f5f5f5f5f	32	plan9	FIDIVR 0(AX)
+de38|11223344556677885f5f5f5f5f5f	64	gnu	fidivr (%rax)
+de38|11223344556677885f5f5f5f5f5f	64	intel	fidivr st0, word ptr [rax]
+de38|11223344556677885f5f5f5f5f5f	64	plan9	FIDIVR 0(AX)
+dec0|11223344556677885f5f5f5f5f5f	32	intel	faddp st0, st0
+dec0|11223344556677885f5f5f5f5f5f	32	plan9	FADDP F0, F0
+dec0|11223344556677885f5f5f5f5f5f	64	gnu	faddp %st,%st
+dec0|11223344556677885f5f5f5f5f5f	64	intel	faddp st0, st0
+dec0|11223344556677885f5f5f5f5f5f	64	plan9	FADDP F0, F0
+dec8|11223344556677885f5f5f5f5f5f	32	intel	fmulp st0, st0
+dec8|11223344556677885f5f5f5f5f5f	32	plan9	FMULP F0, F0
+dec8|11223344556677885f5f5f5f5f5f	64	gnu	fmulp %st,%st
+dec8|11223344556677885f5f5f5f5f5f	64	intel	fmulp st0, st0
+dec8|11223344556677885f5f5f5f5f5f	64	plan9	FMULP F0, F0
+ded9|11223344556677885f5f5f5f5f5f	32	intel	fcompp st0, st1
+ded9|11223344556677885f5f5f5f5f5f	32	plan9	FCOMPP
+ded9|11223344556677885f5f5f5f5f5f	64	gnu	fcompp
+ded9|11223344556677885f5f5f5f5f5f	64	intel	fcompp st0, st1
+ded9|11223344556677885f5f5f5f5f5f	64	plan9	FCOMPP
+dee0|11223344556677885f5f5f5f5f5f	32	intel	fsubrp st0, st0
+dee0|11223344556677885f5f5f5f5f5f	32	plan9	FSUBRP F0, F0
+dee0|11223344556677885f5f5f5f5f5f	64	gnu	fsubp %st,%st
+dee0|11223344556677885f5f5f5f5f5f	64	intel	fsubrp st0, st0
+dee0|11223344556677885f5f5f5f5f5f	64	plan9	FSUBRP F0, F0
+dee8|11223344556677885f5f5f5f5f5f	32	intel	fsubp st0, st0
+dee8|11223344556677885f5f5f5f5f5f	32	plan9	FSUBP F0, F0
+dee8|11223344556677885f5f5f5f5f5f	64	gnu	fsubrp %st,%st
+dee8|11223344556677885f5f5f5f5f5f	64	intel	fsubp st0, st0
+dee8|11223344556677885f5f5f5f5f5f	64	plan9	FSUBP F0, F0
+def0|11223344556677885f5f5f5f5f5f	32	intel	fdivrp st0, st0
+def0|11223344556677885f5f5f5f5f5f	32	plan9	FDIVRP F0, F0
+def0|11223344556677885f5f5f5f5f5f	64	gnu	fdivp %st,%st
+def0|11223344556677885f5f5f5f5f5f	64	intel	fdivrp st0, st0
+def0|11223344556677885f5f5f5f5f5f	64	plan9	FDIVRP F0, F0
+def8|11223344556677885f5f5f5f5f5f	32	intel	fdivp st0, st0
+def8|11223344556677885f5f5f5f5f5f	32	plan9	FDIVP F0, F0
+def8|11223344556677885f5f5f5f5f5f	64	gnu	fdivrp %st,%st
+def8|11223344556677885f5f5f5f5f5f	64	intel	fdivp st0, st0
+def8|11223344556677885f5f5f5f5f5f	64	plan9	FDIVP F0, F0
+df00|11223344556677885f5f5f5f5f5f	32	intel	fild st0, word ptr [eax]
+df00|11223344556677885f5f5f5f5f5f	32	plan9	FILD 0(AX)
+df00|11223344556677885f5f5f5f5f5f	64	gnu	fild (%rax)
+df00|11223344556677885f5f5f5f5f5f	64	intel	fild st0, word ptr [rax]
+df00|11223344556677885f5f5f5f5f5f	64	plan9	FILD 0(AX)
+df08|11223344556677885f5f5f5f5f5f	32	intel	fisttp word ptr [eax], st0
+df08|11223344556677885f5f5f5f5f5f	32	plan9	FISTTP 0(AX)
+df08|11223344556677885f5f5f5f5f5f	64	gnu	fisttp (%rax)
+df08|11223344556677885f5f5f5f5f5f	64	intel	fisttp word ptr [rax], st0
+df08|11223344556677885f5f5f5f5f5f	64	plan9	FISTTP 0(AX)
+df11|223344556677885f5f5f5f5f5f5f	32	intel	fist word ptr [ecx], st0
+df11|223344556677885f5f5f5f5f5f5f	32	plan9	FIST 0(CX)
+df11|223344556677885f5f5f5f5f5f5f	64	gnu	fist (%rcx)
+df11|223344556677885f5f5f5f5f5f5f	64	intel	fist word ptr [rcx], st0
+df11|223344556677885f5f5f5f5f5f5f	64	plan9	FIST 0(CX)
+df18|11223344556677885f5f5f5f5f5f	32	intel	fistp word ptr [eax], st0
+df18|11223344556677885f5f5f5f5f5f	32	plan9	FISTP 0(AX)
+df18|11223344556677885f5f5f5f5f5f	64	gnu	fistp (%rax)
+df18|11223344556677885f5f5f5f5f5f	64	intel	fistp word ptr [rax], st0
+df18|11223344556677885f5f5f5f5f5f	64	plan9	FISTP 0(AX)
+df20|11223344556677885f5f5f5f5f5f	32	intel	fbld st0, ptr [eax]
+df20|11223344556677885f5f5f5f5f5f	32	plan9	FBLD 0(AX)
+df20|11223344556677885f5f5f5f5f5f	64	gnu	fbld (%rax)
+df20|11223344556677885f5f5f5f5f5f	64	intel	fbld st0, ptr [rax]
+df20|11223344556677885f5f5f5f5f5f	64	plan9	FBLD 0(AX)
+df28|11223344556677885f5f5f5f5f5f	32	intel	fild st0, qword ptr [eax]
+df28|11223344556677885f5f5f5f5f5f	32	plan9	FILD 0(AX)
+df28|11223344556677885f5f5f5f5f5f	64	gnu	fildll (%rax)
+df28|11223344556677885f5f5f5f5f5f	64	intel	fild st0, qword ptr [rax]
+df28|11223344556677885f5f5f5f5f5f	64	plan9	FILD 0(AX)
+df30|11223344556677885f5f5f5f5f5f	32	intel	fbstp ptr [eax], st0
+df30|11223344556677885f5f5f5f5f5f	32	plan9	FBSTP 0(AX)
+df30|11223344556677885f5f5f5f5f5f	64	gnu	fbstp (%rax)
+df30|11223344556677885f5f5f5f5f5f	64	intel	fbstp ptr [rax], st0
+df30|11223344556677885f5f5f5f5f5f	64	plan9	FBSTP 0(AX)
+df38|11223344556677885f5f5f5f5f5f	32	intel	fistp qword ptr [eax], st0
+df38|11223344556677885f5f5f5f5f5f	32	plan9	FISTP 0(AX)
+df38|11223344556677885f5f5f5f5f5f	64	gnu	fistpll (%rax)
+df38|11223344556677885f5f5f5f5f5f	64	intel	fistp qword ptr [rax], st0
+df38|11223344556677885f5f5f5f5f5f	64	plan9	FISTP 0(AX)
+dfc0|11223344556677885f5f5f5f5f5f	32	intel	ffreep st0
+dfc0|11223344556677885f5f5f5f5f5f	32	plan9	FFREEP F0
+dfc0|11223344556677885f5f5f5f5f5f	64	gnu	ffreep %st
+dfc0|11223344556677885f5f5f5f5f5f	64	intel	ffreep st0
+dfc0|11223344556677885f5f5f5f5f5f	64	plan9	FFREEP F0
+dfe0|11223344556677885f5f5f5f5f5f	32	intel	fnstsw ax
+dfe0|11223344556677885f5f5f5f5f5f	32	plan9	FNSTSW AX
+dfe0|11223344556677885f5f5f5f5f5f	64	gnu	fnstsw %ax
+dfe0|11223344556677885f5f5f5f5f5f	64	intel	fnstsw ax
+dfe0|11223344556677885f5f5f5f5f5f	64	plan9	FNSTSW AX
+dfe8|11223344556677885f5f5f5f5f5f	32	intel	fucomip st0, st0
+dfe8|11223344556677885f5f5f5f5f5f	32	plan9	FUCOMIP F0, F0
+dfe8|11223344556677885f5f5f5f5f5f	64	gnu	fucomip %st,%st
+dfe8|11223344556677885f5f5f5f5f5f	64	intel	fucomip st0, st0
+dfe8|11223344556677885f5f5f5f5f5f	64	plan9	FUCOMIP F0, F0
+dff0|11223344556677885f5f5f5f5f5f	32	intel	fcomip st0, st0
+dff0|11223344556677885f5f5f5f5f5f	32	plan9	FCOMIP F0, F0
+dff0|11223344556677885f5f5f5f5f5f	64	gnu	fcomip %st,%st
+dff0|11223344556677885f5f5f5f5f5f	64	intel	fcomip st0, st0
+dff0|11223344556677885f5f5f5f5f5f	64	plan9	FCOMIP F0, F0
+e111|223344556677885f5f5f5f5f5f5f	32	intel	loope .+0x11
+e111|223344556677885f5f5f5f5f5f5f	32	plan9	LOOPE .+17
+e111|223344556677885f5f5f5f5f5f5f	64	gnu	loope .+0x11
+e111|223344556677885f5f5f5f5f5f5f	64	intel	loope .+0x11
+e111|223344556677885f5f5f5f5f5f5f	64	plan9	LOOPE .+17
+e211|223344556677885f5f5f5f5f5f5f	32	intel	loop .+0x11
+e211|223344556677885f5f5f5f5f5f5f	32	plan9	LOOP .+17
+e211|223344556677885f5f5f5f5f5f5f	64	gnu	loop .+0x11
+e211|223344556677885f5f5f5f5f5f5f	64	intel	loop .+0x11
+e211|223344556677885f5f5f5f5f5f5f	64	plan9	LOOP .+17
+e311|223344556677885f5f5f5f5f5f5f	32	intel	jecxz .+0x11
+e311|223344556677885f5f5f5f5f5f5f	32	plan9	JECXZ .+17
+e311|223344556677885f5f5f5f5f5f5f	64	gnu	jrcxz .+0x11
+e311|223344556677885f5f5f5f5f5f5f	64	intel	jrcxz .+0x11
+e311|223344556677885f5f5f5f5f5f5f	64	plan9	JRCXZ .+17
+e411|223344556677885f5f5f5f5f5f5f	32	intel	in al, 0x11
+e411|223344556677885f5f5f5f5f5f5f	32	plan9	INL $0x11, AL
+e411|223344556677885f5f5f5f5f5f5f	64	gnu	in $0x11,%al
+e411|223344556677885f5f5f5f5f5f5f	64	intel	in al, 0x11
+e411|223344556677885f5f5f5f5f5f5f	64	plan9	INL $0x11, AL
+e511|223344556677885f5f5f5f5f5f5f	32	intel	in eax, 0x11
+e511|223344556677885f5f5f5f5f5f5f	32	plan9	INL $0x11, AX
+e511|223344556677885f5f5f5f5f5f5f	64	gnu	in $0x11,%eax
+e511|223344556677885f5f5f5f5f5f5f	64	intel	in eax, 0x11
+e511|223344556677885f5f5f5f5f5f5f	64	plan9	INL $0x11, AX
+e611|223344556677885f5f5f5f5f5f5f	32	intel	out 0x11, al
+e611|223344556677885f5f5f5f5f5f5f	32	plan9	OUTL AL, $0x11
+e611|223344556677885f5f5f5f5f5f5f	64	gnu	out %al,$0x11
+e611|223344556677885f5f5f5f5f5f5f	64	intel	out 0x11, al
+e611|223344556677885f5f5f5f5f5f5f	64	plan9	OUTL AL, $0x11
+e711|223344556677885f5f5f5f5f5f5f	32	intel	out 0x11, eax
+e711|223344556677885f5f5f5f5f5f5f	32	plan9	OUTL AX, $0x11
+e711|223344556677885f5f5f5f5f5f5f	64	gnu	out %eax,$0x11
+e711|223344556677885f5f5f5f5f5f5f	64	intel	out 0x11, eax
+e711|223344556677885f5f5f5f5f5f5f	64	plan9	OUTL AX, $0x11
+e811223344|556677885f5f5f5f5f5f5f	32	intel	call .+0x44332211
+e811223344|556677885f5f5f5f5f5f5f	32	plan9	CALL .+1144201745
+e811223344|556677885f5f5f5f5f5f5f	64	gnu	callq .+0x44332211
+e811223344|556677885f5f5f5f5f5f5f	64	intel	call .+0x44332211
+e811223344|556677885f5f5f5f5f5f5f	64	plan9	CALL .+1144201745
+e911223344|556677885f5f5f5f5f5f5f	32	intel	jmp .+0x44332211
+e911223344|556677885f5f5f5f5f5f5f	32	plan9	JMP .+1144201745
+e911223344|556677885f5f5f5f5f5f5f	64	gnu	jmpq .+0x44332211
+e911223344|556677885f5f5f5f5f5f5f	64	intel	jmp .+0x44332211
+e911223344|556677885f5f5f5f5f5f5f	64	plan9	JMP .+1144201745
+ea112233445566|77885f5f5f5f5f5f5f	32	intel	jmp far 0x44332211, 0x6655
+ea112233445566|77885f5f5f5f5f5f5f	32	plan9	LJMP $0x44332211, $0x6655
+eb11|223344556677885f5f5f5f5f5f5f	32	intel	jmp .+0x11
+eb11|223344556677885f5f5f5f5f5f5f	32	plan9	JMP .+17
+eb11|223344556677885f5f5f5f5f5f5f	64	gnu	jmp .+0x11
+eb11|223344556677885f5f5f5f5f5f5f	64	intel	jmp .+0x11
+eb11|223344556677885f5f5f5f5f5f5f	64	plan9	JMP .+17
+ec|11223344556677885f5f5f5f5f5f5f	32	intel	in al, dx
+ec|11223344556677885f5f5f5f5f5f5f	32	plan9	INL DX, AL
+ec|11223344556677885f5f5f5f5f5f5f	64	gnu	in (%dx),%al
+ec|11223344556677885f5f5f5f5f5f5f	64	intel	in al, dx
+ec|11223344556677885f5f5f5f5f5f5f	64	plan9	INL DX, AL
+ed|11223344556677885f5f5f5f5f5f5f	32	intel	in eax, dx
+ed|11223344556677885f5f5f5f5f5f5f	32	plan9	INL DX, AX
+ed|11223344556677885f5f5f5f5f5f5f	64	gnu	in (%dx),%eax
+ed|11223344556677885f5f5f5f5f5f5f	64	intel	in eax, dx
+ed|11223344556677885f5f5f5f5f5f5f	64	plan9	INL DX, AX
+ee|11223344556677885f5f5f5f5f5f5f	32	intel	out dx, al
+ee|11223344556677885f5f5f5f5f5f5f	32	plan9	OUTL AL, DX
+ee|11223344556677885f5f5f5f5f5f5f	64	gnu	out %al,(%dx)
+ee|11223344556677885f5f5f5f5f5f5f	64	intel	out dx, al
+ee|11223344556677885f5f5f5f5f5f5f	64	plan9	OUTL AL, DX
+ef|11223344556677885f5f5f5f5f5f5f	32	intel	out dx, eax
+ef|11223344556677885f5f5f5f5f5f5f	32	plan9	OUTL AX, DX
+ef|11223344556677885f5f5f5f5f5f5f	64	gnu	out %eax,(%dx)
+ef|11223344556677885f5f5f5f5f5f5f	64	intel	out dx, eax
+ef|11223344556677885f5f5f5f5f5f5f	64	plan9	OUTL AX, DX
+f1|11223344556677885f5f5f5f5f5f5f	32	intel	int1
+f1|11223344556677885f5f5f5f5f5f5f	32	plan9	ICEBP
+f1|11223344556677885f5f5f5f5f5f5f	64	gnu	icebp
+f1|11223344556677885f5f5f5f5f5f5f	64	intel	int1
+f1|11223344556677885f5f5f5f5f5f5f	64	plan9	ICEBP
+f20f1011|223344556677885f5f5f5f5f	32	intel	movsd xmm2, qword ptr [ecx]
+f20f1011|223344556677885f5f5f5f5f	32	plan9	REPNE MOVSD_XMM 0(CX), X2
+f20f1011|223344556677885f5f5f5f5f	64	gnu	movsd (%rcx),%xmm2
+f20f1011|223344556677885f5f5f5f5f	64	intel	movsd xmm2, qword ptr [rcx]
+f20f1011|223344556677885f5f5f5f5f	64	plan9	REPNE MOVSD_XMM 0(CX), X2
+f20f1122|3344556677885f5f5f5f5f5f	32	intel	movsd qword ptr [edx], xmm4
+f20f1122|3344556677885f5f5f5f5f5f	32	plan9	REPNE MOVSD_XMM X4, 0(DX)
+f20f1122|3344556677885f5f5f5f5f5f	64	gnu	movsd %xmm4,(%rdx)
+f20f1122|3344556677885f5f5f5f5f5f	64	intel	movsd qword ptr [rdx], xmm4
+f20f1122|3344556677885f5f5f5f5f5f	64	plan9	REPNE MOVSD_XMM X4, 0(DX)
+f20f1211|223344556677885f5f5f5f5f	32	intel	movddup xmm2, qword ptr [ecx]
+f20f1211|223344556677885f5f5f5f5f	32	plan9	REPNE MOVDDUP 0(CX), X2
+f20f1211|223344556677885f5f5f5f5f	64	gnu	movddup (%rcx),%xmm2
+f20f1211|223344556677885f5f5f5f5f	64	intel	movddup xmm2, qword ptr [rcx]
+f20f1211|223344556677885f5f5f5f5f	64	plan9	REPNE MOVDDUP 0(CX), X2
+f20f2a11|223344556677885f5f5f5f5f	32	intel	cvtsi2sd xmm2, dword ptr [ecx]
+f20f2a11|223344556677885f5f5f5f5f	32	plan9	REPNE CVTSI2SDL 0(CX), X2
+f20f2a11|223344556677885f5f5f5f5f	64	gnu	cvtsi2sdl (%rcx),%xmm2
+f20f2a11|223344556677885f5f5f5f5f	64	intel	cvtsi2sd xmm2, dword ptr [rcx]
+f20f2a11|223344556677885f5f5f5f5f	64	plan9	REPNE CVTSI2SDL 0(CX), X2
+f20f2c11|223344556677885f5f5f5f5f	32	intel	cvttsd2si edx, qword ptr [ecx]
+f20f2c11|223344556677885f5f5f5f5f	32	plan9	REPNE CVTTSD2SIL 0(CX), DX
+f20f2c11|223344556677885f5f5f5f5f	64	gnu	cvttsd2si (%rcx),%edx
+f20f2c11|223344556677885f5f5f5f5f	64	intel	cvttsd2si edx, qword ptr [rcx]
+f20f2c11|223344556677885f5f5f5f5f	64	plan9	REPNE CVTTSD2SIL 0(CX), DX
+f20f2d11|223344556677885f5f5f5f5f	32	intel	cvtsd2si edx, qword ptr [ecx]
+f20f2d11|223344556677885f5f5f5f5f	32	plan9	REPNE CVTSD2SIL 0(CX), DX
+f20f2d11|223344556677885f5f5f5f5f	64	gnu	cvtsd2si (%rcx),%edx
+f20f2d11|223344556677885f5f5f5f5f	64	intel	cvtsd2si edx, qword ptr [rcx]
+f20f2d11|223344556677885f5f5f5f5f	64	plan9	REPNE CVTSD2SIL 0(CX), DX
+f20f38f011|223344556677885f5f5f5f	32	intel	crc32 edx, byte ptr [ecx]
+f20f38f011|223344556677885f5f5f5f	32	plan9	REPNE CRC32 0(CX), DX
+f20f38f011|223344556677885f5f5f5f	64	gnu	crc32b (%rcx),%edx
+f20f38f011|223344556677885f5f5f5f	64	intel	crc32 edx, byte ptr [rcx]
+f20f38f011|223344556677885f5f5f5f	64	plan9	REPNE CRC32 0(CX), DX
+f20f38f111|223344556677885f5f5f5f	32	intel	crc32 edx, dword ptr [ecx]
+f20f38f111|223344556677885f5f5f5f	32	plan9	REPNE CRC32 0(CX), DX
+f20f38f111|223344556677885f5f5f5f	64	gnu	crc32l (%rcx),%edx
+f20f38f111|223344556677885f5f5f5f	64	intel	crc32 edx, dword ptr [rcx]
+f20f38f111|223344556677885f5f5f5f	64	plan9	REPNE CRC32 0(CX), DX
+f20f5111|223344556677885f5f5f5f5f	32	intel	sqrtsd xmm2, qword ptr [ecx]
+f20f5111|223344556677885f5f5f5f5f	32	plan9	REPNE SQRTSD 0(CX), X2
+f20f5111|223344556677885f5f5f5f5f	64	gnu	sqrtsd (%rcx),%xmm2
+f20f5111|223344556677885f5f5f5f5f	64	intel	sqrtsd xmm2, qword ptr [rcx]
+f20f5111|223344556677885f5f5f5f5f	64	plan9	REPNE SQRTSD 0(CX), X2
+f20f5811|223344556677885f5f5f5f5f	32	intel	addsd xmm2, qword ptr [ecx]
+f20f5811|223344556677885f5f5f5f5f	32	plan9	REPNE ADDSD 0(CX), X2
+f20f5811|223344556677885f5f5f5f5f	64	gnu	addsd (%rcx),%xmm2
+f20f5811|223344556677885f5f5f5f5f	64	intel	addsd xmm2, qword ptr [rcx]
+f20f5811|223344556677885f5f5f5f5f	64	plan9	REPNE ADDSD 0(CX), X2
+f20f5911|223344556677885f5f5f5f5f	32	intel	mulsd xmm2, qword ptr [ecx]
+f20f5911|223344556677885f5f5f5f5f	32	plan9	REPNE MULSD 0(CX), X2
+f20f5911|223344556677885f5f5f5f5f	64	gnu	mulsd (%rcx),%xmm2
+f20f5911|223344556677885f5f5f5f5f	64	intel	mulsd xmm2, qword ptr [rcx]
+f20f5911|223344556677885f5f5f5f5f	64	plan9	REPNE MULSD 0(CX), X2
+f20f5a11|223344556677885f5f5f5f5f	32	intel	cvtsd2ss xmm2, qword ptr [ecx]
+f20f5a11|223344556677885f5f5f5f5f	32	plan9	REPNE CVTSD2SS 0(CX), X2
+f20f5a11|223344556677885f5f5f5f5f	64	gnu	cvtsd2ss (%rcx),%xmm2
+f20f5a11|223344556677885f5f5f5f5f	64	intel	cvtsd2ss xmm2, qword ptr [rcx]
+f20f5a11|223344556677885f5f5f5f5f	64	plan9	REPNE CVTSD2SS 0(CX), X2
+f20f5c11|223344556677885f5f5f5f5f	32	intel	subsd xmm2, qword ptr [ecx]
+f20f5c11|223344556677885f5f5f5f5f	32	plan9	REPNE SUBSD 0(CX), X2
+f20f5c11|223344556677885f5f5f5f5f	64	gnu	subsd (%rcx),%xmm2
+f20f5c11|223344556677885f5f5f5f5f	64	intel	subsd xmm2, qword ptr [rcx]
+f20f5c11|223344556677885f5f5f5f5f	64	plan9	REPNE SUBSD 0(CX), X2
+f20f5d11|223344556677885f5f5f5f5f	32	intel	minsd xmm2, qword ptr [ecx]
+f20f5d11|223344556677885f5f5f5f5f	32	plan9	REPNE MINSD 0(CX), X2
+f20f5d11|223344556677885f5f5f5f5f	64	gnu	minsd (%rcx),%xmm2
+f20f5d11|223344556677885f5f5f5f5f	64	intel	minsd xmm2, qword ptr [rcx]
+f20f5d11|223344556677885f5f5f5f5f	64	plan9	REPNE MINSD 0(CX), X2
+f20f5e11|223344556677885f5f5f5f5f	32	intel	divsd xmm2, qword ptr [ecx]
+f20f5e11|223344556677885f5f5f5f5f	32	plan9	REPNE DIVSD 0(CX), X2
+f20f5e11|223344556677885f5f5f5f5f	64	gnu	divsd (%rcx),%xmm2
+f20f5e11|223344556677885f5f5f5f5f	64	intel	divsd xmm2, qword ptr [rcx]
+f20f5e11|223344556677885f5f5f5f5f	64	plan9	REPNE DIVSD 0(CX), X2
+f20f5f11|223344556677885f5f5f5f5f	32	intel	maxsd xmm2, qword ptr [ecx]
+f20f5f11|223344556677885f5f5f5f5f	32	plan9	REPNE MAXSD 0(CX), X2
+f20f5f11|223344556677885f5f5f5f5f	64	gnu	maxsd (%rcx),%xmm2
+f20f5f11|223344556677885f5f5f5f5f	64	intel	maxsd xmm2, qword ptr [rcx]
+f20f5f11|223344556677885f5f5f5f5f	64	plan9	REPNE MAXSD 0(CX), X2
+f20f701122|3344556677885f5f5f5f5f	32	intel	pshuflw xmm2, xmmword ptr [ecx], 0x22
+f20f701122|3344556677885f5f5f5f5f	32	plan9	REPNE PSHUFLW $0x22, 0(CX), X2
+f20f701122|3344556677885f5f5f5f5f	64	gnu	pshuflw $0x22,(%rcx),%xmm2
+f20f701122|3344556677885f5f5f5f5f	64	intel	pshuflw xmm2, xmmword ptr [rcx], 0x22
+f20f701122|3344556677885f5f5f5f5f	64	plan9	REPNE PSHUFLW $0x22, 0(CX), X2
+f20f7c11|223344556677885f5f5f5f5f	32	intel	haddps xmm2, xmmword ptr [ecx]
+f20f7c11|223344556677885f5f5f5f5f	32	plan9	REPNE HADDPS 0(CX), X2
+f20f7c11|223344556677885f5f5f5f5f	64	gnu	haddps (%rcx),%xmm2
+f20f7c11|223344556677885f5f5f5f5f	64	intel	haddps xmm2, xmmword ptr [rcx]
+f20f7c11|223344556677885f5f5f5f5f	64	plan9	REPNE HADDPS 0(CX), X2
+f20f7d11|223344556677885f5f5f5f5f	32	intel	hsubps xmm2, xmmword ptr [ecx]
+f20f7d11|223344556677885f5f5f5f5f	32	plan9	REPNE HSUBPS 0(CX), X2
+f20f7d11|223344556677885f5f5f5f5f	64	gnu	hsubps (%rcx),%xmm2
+f20f7d11|223344556677885f5f5f5f5f	64	intel	hsubps xmm2, xmmword ptr [rcx]
+f20f7d11|223344556677885f5f5f5f5f	64	plan9	REPNE HSUBPS 0(CX), X2
+f20fc21122|3344556677885f5f5f5f5f	32	intel	cmpsd_xmm xmm2, qword ptr [ecx], 0x22
+f20fc21122|3344556677885f5f5f5f5f	32	plan9	REPNE CMPSD_XMM $0x22, 0(CX), X2
+f20fc21122|3344556677885f5f5f5f5f	64	gnu	cmpsd $0x22,(%rcx),%xmm2
+f20fc21122|3344556677885f5f5f5f5f	64	intel	cmpsd_xmm xmm2, qword ptr [rcx], 0x22
+f20fc21122|3344556677885f5f5f5f5f	64	plan9	REPNE CMPSD_XMM $0x22, 0(CX), X2
+f20fd011|223344556677885f5f5f5f5f	32	intel	addsubps xmm2, xmmword ptr [ecx]
+f20fd011|223344556677885f5f5f5f5f	32	plan9	REPNE ADDSUBPS 0(CX), X2
+f20fd011|223344556677885f5f5f5f5f	64	gnu	addsubps (%rcx),%xmm2
+f20fd011|223344556677885f5f5f5f5f	64	intel	addsubps xmm2, xmmword ptr [rcx]
+f20fd011|223344556677885f5f5f5f5f	64	plan9	REPNE ADDSUBPS 0(CX), X2
+f20fd6c0|11223344556677885f5f5f5f	32	intel	movdq2q mmx0, xmm0
+f20fd6c0|11223344556677885f5f5f5f	32	plan9	REPNE MOVDQ2Q X0, M0
+f20fd6c0|11223344556677885f5f5f5f	64	gnu	movdq2q %xmm0,%mm0
+f20fd6c0|11223344556677885f5f5f5f	64	intel	movdq2q mmx0, xmm0
+f20fd6c0|11223344556677885f5f5f5f	64	plan9	REPNE MOVDQ2Q X0, M0
+f20fe611|223344556677885f5f5f5f5f	32	intel	cvtpd2dq xmm2, xmmword ptr [ecx]
+f20fe611|223344556677885f5f5f5f5f	32	plan9	REPNE CVTPD2DQ 0(CX), X2
+f20fe611|223344556677885f5f5f5f5f	64	gnu	cvtpd2dq (%rcx),%xmm2
+f20fe611|223344556677885f5f5f5f5f	64	intel	cvtpd2dq xmm2, xmmword ptr [rcx]
+f20fe611|223344556677885f5f5f5f5f	64	plan9	REPNE CVTPD2DQ 0(CX), X2
+f20ff011|223344556677885f5f5f5f5f	32	intel	lddqu xmm2, xmmword ptr [ecx]
+f20ff011|223344556677885f5f5f5f5f	32	plan9	REPNE LDDQU 0(CX), X2
+f20ff011|223344556677885f5f5f5f5f	64	gnu	lddqu (%rcx),%xmm2
+f20ff011|223344556677885f5f5f5f5f	64	intel	lddqu xmm2, xmmword ptr [rcx]
+f20ff011|223344556677885f5f5f5f5f	64	plan9	REPNE LDDQU 0(CX), X2
+f2480f2a11|223344556677885f5f5f5f	64	gnu	cvtsi2sdq (%rcx),%xmm2
+f2480f2a11|223344556677885f5f5f5f	64	intel	cvtsi2sd xmm2, qword ptr [rcx]
+f2480f2a11|223344556677885f5f5f5f	64	plan9	REPNE CVTSI2SDQ 0(CX), X2
+f2480f2c11|223344556677885f5f5f5f	64	gnu	cvttsd2si (%rcx),%rdx
+f2480f2c11|223344556677885f5f5f5f	64	intel	cvttsd2si rdx, qword ptr [rcx]
+f2480f2c11|223344556677885f5f5f5f	64	plan9	REPNE CVTTSD2SIQ 0(CX), DX
+f2480f2d11|223344556677885f5f5f5f	64	gnu	cvtsd2si (%rcx),%rdx
+f2480f2d11|223344556677885f5f5f5f	64	intel	cvtsd2si rdx, qword ptr [rcx]
+f2480f2d11|223344556677885f5f5f5f	64	plan9	REPNE CVTSD2SIQ 0(CX), DX
+f2480f38f011|223344556677885f5f5f	64	gnu	crc32b (%rcx),%rdx
+f2480f38f011|223344556677885f5f5f	64	intel	crc32 rdx, byte ptr [rcx]
+f2480f38f011|223344556677885f5f5f	64	plan9	REPNE CRC32 0(CX), DX
+f2480f38f111|223344556677885f5f5f	64	gnu	crc32q (%rcx),%rdx
+f2480f38f111|223344556677885f5f5f	64	intel	crc32 rdx, qword ptr [rcx]
+f2480f38f111|223344556677885f5f5f	64	plan9	REPNE CRC32 0(CX), DX
+f267f0663e360f38f111|223344556677	32	intel	lock crc32 edx, word ptr ss:[bx+di*1]
+f267f0663e360f38f111|223344556677	32	plan9	SS CRC32 SS:0(BX)(DI*1), DX
+f267f0663e360f38f111|223344556677	64	gnu	lock crc32w %ds:%ss:(%ecx),%edx
+f267f0663e360f38f111|223344556677	64	intel	lock crc32 edx, word ptr [ecx]
+f267f0663e360f38f111|223344556677	64	plan9	SS CRC32 0(CX), DX
+f2f30f2b11|5f5f5f5f5f5f5f5f5f5f5f	32	intel	movntss dword ptr [ecx], xmm2
+f2f30f2b11|5f5f5f5f5f5f5f5f5f5f5f	32	plan9	REP MOVNTSS X2, 0(CX)
+f2f30f2b11|5f5f5f5f5f5f5f5f5f5f5f	64	gnu	repn movntss %xmm2,(%rcx)
+f2f30f2b11|5f5f5f5f5f5f5f5f5f5f5f	64	intel	movntss dword ptr [rcx], xmm2
+f2f30f2b11|5f5f5f5f5f5f5f5f5f5f5f	64	plan9	REP MOVNTSS X2, 0(CX)
+f30f1011|223344556677885f5f5f5f5f	32	intel	movss xmm2, dword ptr [ecx]
+f30f1011|223344556677885f5f5f5f5f	32	plan9	REP MOVSS 0(CX), X2
+f30f1011|223344556677885f5f5f5f5f	64	gnu	movss (%rcx),%xmm2
+f30f1011|223344556677885f5f5f5f5f	64	intel	movss xmm2, dword ptr [rcx]
+f30f1011|223344556677885f5f5f5f5f	64	plan9	REP MOVSS 0(CX), X2
+f30f1122|3344556677885f5f5f5f5f5f	32	intel	movss dword ptr [edx], xmm4
+f30f1122|3344556677885f5f5f5f5f5f	32	plan9	REP MOVSS X4, 0(DX)
+f30f1122|3344556677885f5f5f5f5f5f	64	gnu	movss %xmm4,(%rdx)
+f30f1122|3344556677885f5f5f5f5f5f	64	intel	movss dword ptr [rdx], xmm4
+f30f1122|3344556677885f5f5f5f5f5f	64	plan9	REP MOVSS X4, 0(DX)
+f30f1211|223344556677885f5f5f5f5f	32	intel	movsldup xmm2, xmmword ptr [ecx]
+f30f1211|223344556677885f5f5f5f5f	32	plan9	REP MOVSLDUP 0(CX), X2
+f30f1211|223344556677885f5f5f5f5f	64	gnu	movsldup (%rcx),%xmm2
+f30f1211|223344556677885f5f5f5f5f	64	intel	movsldup xmm2, xmmword ptr [rcx]
+f30f1211|223344556677885f5f5f5f5f	64	plan9	REP MOVSLDUP 0(CX), X2
+f30f1611|223344556677885f5f5f5f5f	32	intel	movshdup xmm2, xmmword ptr [ecx]
+f30f1611|223344556677885f5f5f5f5f	32	plan9	REP MOVSHDUP 0(CX), X2
+f30f1611|223344556677885f5f5f5f5f	64	gnu	movshdup (%rcx),%xmm2
+f30f1611|223344556677885f5f5f5f5f	64	intel	movshdup xmm2, xmmword ptr [rcx]
+f30f1611|223344556677885f5f5f5f5f	64	plan9	REP MOVSHDUP 0(CX), X2
+f30f2a11|223344556677885f5f5f5f5f	32	intel	cvtsi2ss xmm2, dword ptr [ecx]
+f30f2a11|223344556677885f5f5f5f5f	32	plan9	REP CVTSI2SSL 0(CX), X2
+f30f2a11|223344556677885f5f5f5f5f	64	gnu	cvtsi2ssl (%rcx),%xmm2
+f30f2a11|223344556677885f5f5f5f5f	64	intel	cvtsi2ss xmm2, dword ptr [rcx]
+f30f2a11|223344556677885f5f5f5f5f	64	plan9	REP CVTSI2SSL 0(CX), X2
+f30f2c11|223344556677885f5f5f5f5f	32	intel	cvttss2si edx, dword ptr [ecx]
+f30f2c11|223344556677885f5f5f5f5f	32	plan9	REP CVTTSS2SIL 0(CX), DX
+f30f2c11|223344556677885f5f5f5f5f	64	gnu	cvttss2si (%rcx),%edx
+f30f2c11|223344556677885f5f5f5f5f	64	intel	cvttss2si edx, dword ptr [rcx]
+f30f2c11|223344556677885f5f5f5f5f	64	plan9	REP CVTTSS2SIL 0(CX), DX
+f30f2d11|223344556677885f5f5f5f5f	32	intel	cvtss2si edx, dword ptr [ecx]
+f30f2d11|223344556677885f5f5f5f5f	32	plan9	REP CVTSS2SIL 0(CX), DX
+f30f2d11|223344556677885f5f5f5f5f	64	gnu	cvtss2si (%rcx),%edx
+f30f2d11|223344556677885f5f5f5f5f	64	intel	cvtss2si edx, dword ptr [rcx]
+f30f2d11|223344556677885f5f5f5f5f	64	plan9	REP CVTSS2SIL 0(CX), DX
+f30f5111|223344556677885f5f5f5f5f	32	intel	sqrtss xmm2, dword ptr [ecx]
+f30f5111|223344556677885f5f5f5f5f	32	plan9	REP SQRTSS 0(CX), X2
+f30f5111|223344556677885f5f5f5f5f	64	gnu	sqrtss (%rcx),%xmm2
+f30f5111|223344556677885f5f5f5f5f	64	intel	sqrtss xmm2, dword ptr [rcx]
+f30f5111|223344556677885f5f5f5f5f	64	plan9	REP SQRTSS 0(CX), X2
+f30f5211|223344556677885f5f5f5f5f	32	intel	rsqrtss xmm2, dword ptr [ecx]
+f30f5211|223344556677885f5f5f5f5f	32	plan9	REP RSQRTSS 0(CX), X2
+f30f5211|223344556677885f5f5f5f5f	64	gnu	rsqrtss (%rcx),%xmm2
+f30f5211|223344556677885f5f5f5f5f	64	intel	rsqrtss xmm2, dword ptr [rcx]
+f30f5211|223344556677885f5f5f5f5f	64	plan9	REP RSQRTSS 0(CX), X2
+f30f5311|223344556677885f5f5f5f5f	32	intel	rcpss xmm2, dword ptr [ecx]
+f30f5311|223344556677885f5f5f5f5f	32	plan9	REP RCPSS 0(CX), X2
+f30f5311|223344556677885f5f5f5f5f	64	gnu	rcpss (%rcx),%xmm2
+f30f5311|223344556677885f5f5f5f5f	64	intel	rcpss xmm2, dword ptr [rcx]
+f30f5311|223344556677885f5f5f5f5f	64	plan9	REP RCPSS 0(CX), X2
+f30f5811|223344556677885f5f5f5f5f	32	intel	addss xmm2, dword ptr [ecx]
+f30f5811|223344556677885f5f5f5f5f	32	plan9	REP ADDSS 0(CX), X2
+f30f5811|223344556677885f5f5f5f5f	64	gnu	addss (%rcx),%xmm2
+f30f5811|223344556677885f5f5f5f5f	64	intel	addss xmm2, dword ptr [rcx]
+f30f5811|223344556677885f5f5f5f5f	64	plan9	REP ADDSS 0(CX), X2
+f30f5911|223344556677885f5f5f5f5f	32	intel	mulss xmm2, dword ptr [ecx]
+f30f5911|223344556677885f5f5f5f5f	32	plan9	REP MULSS 0(CX), X2
+f30f5911|223344556677885f5f5f5f5f	64	gnu	mulss (%rcx),%xmm2
+f30f5911|223344556677885f5f5f5f5f	64	intel	mulss xmm2, dword ptr [rcx]
+f30f5911|223344556677885f5f5f5f5f	64	plan9	REP MULSS 0(CX), X2
+f30f5a11|223344556677885f5f5f5f5f	32	intel	cvtss2sd xmm2, dword ptr [ecx]
+f30f5a11|223344556677885f5f5f5f5f	32	plan9	REP CVTSS2SD 0(CX), X2
+f30f5a11|223344556677885f5f5f5f5f	64	gnu	cvtss2sd (%rcx),%xmm2
+f30f5a11|223344556677885f5f5f5f5f	64	intel	cvtss2sd xmm2, dword ptr [rcx]
+f30f5a11|223344556677885f5f5f5f5f	64	plan9	REP CVTSS2SD 0(CX), X2
+f30f5b11|223344556677885f5f5f5f5f	32	intel	cvttps2dq xmm2, xmmword ptr [ecx]
+f30f5b11|223344556677885f5f5f5f5f	32	plan9	REP CVTTPS2DQ 0(CX), X2
+f30f5b11|223344556677885f5f5f5f5f	64	gnu	cvttps2dq (%rcx),%xmm2
+f30f5b11|223344556677885f5f5f5f5f	64	intel	cvttps2dq xmm2, xmmword ptr [rcx]
+f30f5b11|223344556677885f5f5f5f5f	64	plan9	REP CVTTPS2DQ 0(CX), X2
+f30f5c11|223344556677885f5f5f5f5f	32	intel	subss xmm2, dword ptr [ecx]
+f30f5c11|223344556677885f5f5f5f5f	32	plan9	REP SUBSS 0(CX), X2
+f30f5c11|223344556677885f5f5f5f5f	64	gnu	subss (%rcx),%xmm2
+f30f5c11|223344556677885f5f5f5f5f	64	intel	subss xmm2, dword ptr [rcx]
+f30f5c11|223344556677885f5f5f5f5f	64	plan9	REP SUBSS 0(CX), X2
+f30f5d11|223344556677885f5f5f5f5f	32	intel	minss xmm2, dword ptr [ecx]
+f30f5d11|223344556677885f5f5f5f5f	32	plan9	REP MINSS 0(CX), X2
+f30f5d11|223344556677885f5f5f5f5f	64	gnu	minss (%rcx),%xmm2
+f30f5d11|223344556677885f5f5f5f5f	64	intel	minss xmm2, dword ptr [rcx]
+f30f5d11|223344556677885f5f5f5f5f	64	plan9	REP MINSS 0(CX), X2
+f30f5e11|223344556677885f5f5f5f5f	32	intel	divss xmm2, dword ptr [ecx]
+f30f5e11|223344556677885f5f5f5f5f	32	plan9	REP DIVSS 0(CX), X2
+f30f5e11|223344556677885f5f5f5f5f	64	gnu	divss (%rcx),%xmm2
+f30f5e11|223344556677885f5f5f5f5f	64	intel	divss xmm2, dword ptr [rcx]
+f30f5e11|223344556677885f5f5f5f5f	64	plan9	REP DIVSS 0(CX), X2
+f30f5f11|223344556677885f5f5f5f5f	32	intel	maxss xmm2, dword ptr [ecx]
+f30f5f11|223344556677885f5f5f5f5f	32	plan9	REP MAXSS 0(CX), X2
+f30f5f11|223344556677885f5f5f5f5f	64	gnu	maxss (%rcx),%xmm2
+f30f5f11|223344556677885f5f5f5f5f	64	intel	maxss xmm2, dword ptr [rcx]
+f30f5f11|223344556677885f5f5f5f5f	64	plan9	REP MAXSS 0(CX), X2
+f30f6f11|223344556677885f5f5f5f5f	32	intel	movdqu xmm2, xmmword ptr [ecx]
+f30f6f11|223344556677885f5f5f5f5f	32	plan9	REP MOVDQU 0(CX), X2
+f30f6f11|223344556677885f5f5f5f5f	64	gnu	movdqu (%rcx),%xmm2
+f30f6f11|223344556677885f5f5f5f5f	64	intel	movdqu xmm2, xmmword ptr [rcx]
+f30f6f11|223344556677885f5f5f5f5f	64	plan9	REP MOVDQU 0(CX), X2
+f30f701122|3344556677885f5f5f5f5f	32	intel	pshufhw xmm2, xmmword ptr [ecx], 0x22
+f30f701122|3344556677885f5f5f5f5f	32	plan9	REP PSHUFHW $0x22, 0(CX), X2
+f30f701122|3344556677885f5f5f5f5f	64	gnu	pshufhw $0x22,(%rcx),%xmm2
+f30f701122|3344556677885f5f5f5f5f	64	intel	pshufhw xmm2, xmmword ptr [rcx], 0x22
+f30f701122|3344556677885f5f5f5f5f	64	plan9	REP PSHUFHW $0x22, 0(CX), X2
+f30f7e11|223344556677885f5f5f5f5f	32	intel	movq xmm2, qword ptr [ecx]
+f30f7e11|223344556677885f5f5f5f5f	32	plan9	REP MOVQ 0(CX), X2
+f30f7e11|223344556677885f5f5f5f5f	64	gnu	movq (%rcx),%xmm2
+f30f7e11|223344556677885f5f5f5f5f	64	intel	movq xmm2, qword ptr [rcx]
+f30f7e11|223344556677885f5f5f5f5f	64	plan9	REP MOVQ 0(CX), X2
+f30f7f11|223344556677885f5f5f5f5f	32	intel	movdqu xmmword ptr [ecx], xmm2
+f30f7f11|223344556677885f5f5f5f5f	32	plan9	REP MOVDQU X2, 0(CX)
+f30f7f11|223344556677885f5f5f5f5f	64	gnu	movdqu %xmm2,(%rcx)
+f30f7f11|223344556677885f5f5f5f5f	64	intel	movdqu xmmword ptr [rcx], xmm2
+f30f7f11|223344556677885f5f5f5f5f	64	plan9	REP MOVDQU X2, 0(CX)
+f30fae11|223344556677885f5f5f5f5f	64	gnu	wrfsbasel (%rcx)
+f30fae11|223344556677885f5f5f5f5f	64	intel	wrfsbase dword ptr [rcx]
+f30fae11|223344556677885f5f5f5f5f	64	plan9	REP WRFSBASE 0(CX)
+f30fae18|11223344556677885f5f5f5f	64	gnu	wrgsbasel (%rax)
+f30fae18|11223344556677885f5f5f5f	64	intel	wrgsbase dword ptr [rax]
+f30fae18|11223344556677885f5f5f5f	64	plan9	REP WRGSBASE 0(AX)
+f30faec0|11223344556677885f5f5f5f	64	gnu	rdfsbase %eax
+f30faec0|11223344556677885f5f5f5f	64	intel	rdfsbase eax
+f30faec0|11223344556677885f5f5f5f	64	plan9	REP RDFSBASE AX
+f30faec8|11223344556677885f5f5f5f	64	gnu	rdgsbase %eax
+f30faec8|11223344556677885f5f5f5f	64	intel	rdgsbase eax
+f30faec8|11223344556677885f5f5f5f	64	plan9	REP RDGSBASE AX
+f30fb811|223344556677885f5f5f5f5f	32	intel	popcnt edx, dword ptr [ecx]
+f30fb811|223344556677885f5f5f5f5f	32	plan9	REP POPCNT 0(CX), DX
+f30fb811|223344556677885f5f5f5f5f	64	gnu	popcnt (%rcx),%edx
+f30fb811|223344556677885f5f5f5f5f	64	intel	popcnt edx, dword ptr [rcx]
+f30fb811|223344556677885f5f5f5f5f	64	plan9	REP POPCNT 0(CX), DX
+f30fbc11|223344556677885f5f5f5f5f	32	intel	tzcnt edx, dword ptr [ecx]
+f30fbc11|223344556677885f5f5f5f5f	32	plan9	REP TZCNT 0(CX), DX
+f30fbc11|223344556677885f5f5f5f5f	64	gnu	tzcnt (%rcx),%edx
+f30fbc11|223344556677885f5f5f5f5f	64	intel	tzcnt edx, dword ptr [rcx]
+f30fbc11|223344556677885f5f5f5f5f	64	plan9	REP TZCNT 0(CX), DX
+f30fbd11|223344556677885f5f5f5f5f	32	intel	lzcnt edx, dword ptr [ecx]
+f30fbd11|223344556677885f5f5f5f5f	32	plan9	REP LZCNT 0(CX), DX
+f30fbd11|223344556677885f5f5f5f5f	64	gnu	lzcnt (%rcx),%edx
+f30fbd11|223344556677885f5f5f5f5f	64	intel	lzcnt edx, dword ptr [rcx]
+f30fbd11|223344556677885f5f5f5f5f	64	plan9	REP LZCNT 0(CX), DX
+f30fc21122|3344556677885f5f5f5f5f	32	intel	cmpss xmm2, dword ptr [ecx], 0x22
+f30fc21122|3344556677885f5f5f5f5f	32	plan9	REP CMPSS $0x22, 0(CX), X2
+f30fc21122|3344556677885f5f5f5f5f	64	gnu	cmpss $0x22,(%rcx),%xmm2
+f30fc21122|3344556677885f5f5f5f5f	64	intel	cmpss xmm2, dword ptr [rcx], 0x22
+f30fc21122|3344556677885f5f5f5f5f	64	plan9	REP CMPSS $0x22, 0(CX), X2
+f30fe611|223344556677885f5f5f5f5f	32	intel	cvtdq2pd xmm2, qword ptr [ecx]
+f30fe611|223344556677885f5f5f5f5f	32	plan9	REP CVTDQ2PD 0(CX), X2
+f30fe611|223344556677885f5f5f5f5f	64	gnu	cvtdq2pd (%rcx),%xmm2
+f30fe611|223344556677885f5f5f5f5f	64	intel	cvtdq2pd xmm2, qword ptr [rcx]
+f30fe611|223344556677885f5f5f5f5f	64	plan9	REP CVTDQ2PD 0(CX), X2
+f3480f2a11|223344556677885f5f5f5f	64	gnu	cvtsi2ssq (%rcx),%xmm2
+f3480f2a11|223344556677885f5f5f5f	64	intel	cvtsi2ss xmm2, qword ptr [rcx]
+f3480f2a11|223344556677885f5f5f5f	64	plan9	REP CVTSI2SSQ 0(CX), X2
+f3480f2c11|223344556677885f5f5f5f	64	gnu	cvttss2si (%rcx),%rdx
+f3480f2c11|223344556677885f5f5f5f	64	intel	cvttss2si rdx, dword ptr [rcx]
+f3480f2c11|223344556677885f5f5f5f	64	plan9	REP CVTTSS2SIQ 0(CX), DX
+f3480f2d11|223344556677885f5f5f5f	64	gnu	cvtss2si (%rcx),%rdx
+f3480f2d11|223344556677885f5f5f5f	64	intel	cvtss2si rdx, dword ptr [rcx]
+f3480f2d11|223344556677885f5f5f5f	64	plan9	REP CVTSS2SIQ 0(CX), DX
+f3480fae11|223344556677885f5f5f5f	64	gnu	wrfsbaseq (%rcx)
+f3480fae11|223344556677885f5f5f5f	64	intel	wrfsbase qword ptr [rcx]
+f3480fae11|223344556677885f5f5f5f	64	plan9	REP WRFSBASE 0(CX)
+f3480fae18|11223344556677885f5f5f	64	gnu	wrgsbaseq (%rax)
+f3480fae18|11223344556677885f5f5f	64	intel	wrgsbase qword ptr [rax]
+f3480fae18|11223344556677885f5f5f	64	plan9	REP WRGSBASE 0(AX)
+f3480faec0|11223344556677885f5f5f	64	gnu	rdfsbase %rax
+f3480faec0|11223344556677885f5f5f	64	intel	rdfsbase rax
+f3480faec0|11223344556677885f5f5f	64	plan9	REP RDFSBASE AX
+f3480faec8|11223344556677885f5f5f	64	gnu	rdgsbase %rax
+f3480faec8|11223344556677885f5f5f	64	intel	rdgsbase rax
+f3480faec8|11223344556677885f5f5f	64	plan9	REP RDGSBASE AX
+f3480fb811|223344556677885f5f5f5f	64	gnu	popcnt (%rcx),%rdx
+f3480fb811|223344556677885f5f5f5f	64	intel	popcnt rdx, qword ptr [rcx]
+f3480fb811|223344556677885f5f5f5f	64	plan9	REP POPCNT 0(CX), DX
+f3480fbc11|223344556677885f5f5f5f	64	gnu	tzcnt (%rcx),%rdx
+f3480fbc11|223344556677885f5f5f5f	64	intel	tzcnt rdx, qword ptr [rcx]
+f3480fbc11|223344556677885f5f5f5f	64	plan9	REP TZCNT 0(CX), DX
+f3480fbd11|223344556677885f5f5f5f	64	gnu	lzcnt (%rcx),%rdx
+f3480fbd11|223344556677885f5f5f5f	64	intel	lzcnt rdx, qword ptr [rcx]
+f3480fbd11|223344556677885f5f5f5f	64	plan9	REP LZCNT 0(CX), DX
+f3660fb811|223344556677885f5f5f5f	32	intel	popcnt dx, word ptr [ecx]
+f3660fb811|223344556677885f5f5f5f	32	plan9	POPCNT 0(CX), DX
+f3660fb811|223344556677885f5f5f5f	64	gnu	popcnt (%rcx),%dx
+f3660fb811|223344556677885f5f5f5f	64	intel	popcnt dx, word ptr [rcx]
+f3660fb811|223344556677885f5f5f5f	64	plan9	POPCNT 0(CX), DX
+f3660fbc11|223344556677885f5f5f5f	32	intel	tzcnt dx, word ptr [ecx]
+f3660fbc11|223344556677885f5f5f5f	32	plan9	TZCNT 0(CX), DX
+f3660fbc11|223344556677885f5f5f5f	64	gnu	tzcnt (%rcx),%dx
+f3660fbc11|223344556677885f5f5f5f	64	intel	tzcnt dx, word ptr [rcx]
+f3660fbc11|223344556677885f5f5f5f	64	plan9	TZCNT 0(CX), DX
+f3660fbd11|223344556677885f5f5f5f	32	intel	lzcnt dx, word ptr [ecx]
+f3660fbd11|223344556677885f5f5f5f	32	plan9	LZCNT 0(CX), DX
+f3660fbd11|223344556677885f5f5f5f	64	gnu	lzcnt (%rcx),%dx
+f3660fbd11|223344556677885f5f5f5f	64	intel	lzcnt dx, word ptr [rcx]
+f3660fbd11|223344556677885f5f5f5f	64	plan9	LZCNT 0(CX), DX
+f3f0673e660f38f111|22334455667788	32	intel	lock movbe word ptr [bx+di*1], dx
+f3f0673e660f38f111|22334455667788	32	plan9	MOVBE DX, DS:0(BX)(DI*1)
+f3f0673e660f38f111|22334455667788	64	gnu	rep lock movbe %dx,%ds:(%ecx)
+f3f0673e660f38f111|22334455667788	64	intel	lock movbe word ptr [ecx], dx
+f3f0673e660f38f111|22334455667788	64	plan9	MOVBE DX, 0(CX)
+f3f20f2b11|5f5f5f5f5f5f5f5f5f5f5f	32	intel	movntsd qword ptr [ecx], xmm2
+f3f20f2b11|5f5f5f5f5f5f5f5f5f5f5f	32	plan9	REPNE MOVNTSD X2, 0(CX)
+f3f20f2b11|5f5f5f5f5f5f5f5f5f5f5f	64	gnu	repn movntss %xmm2,(%rcx)
+f3f20f2b11|5f5f5f5f5f5f5f5f5f5f5f	64	intel	movntsd qword ptr [rcx], xmm2
+f3f20f2b11|5f5f5f5f5f5f5f5f5f5f5f	64	plan9	REPNE MOVNTSD X2, 0(CX)
+f4|11223344556677885f5f5f5f5f5f5f	32	intel	hlt
+f4|11223344556677885f5f5f5f5f5f5f	32	plan9	HLT
+f4|11223344556677885f5f5f5f5f5f5f	64	gnu	hlt
+f4|11223344556677885f5f5f5f5f5f5f	64	intel	hlt
+f4|11223344556677885f5f5f5f5f5f5f	64	plan9	HLT
+f5|11223344556677885f5f5f5f5f5f5f	32	intel	cmc
+f5|11223344556677885f5f5f5f5f5f5f	32	plan9	CMC
+f5|11223344556677885f5f5f5f5f5f5f	64	gnu	cmc
+f5|11223344556677885f5f5f5f5f5f5f	64	intel	cmc
+f5|11223344556677885f5f5f5f5f5f5f	64	plan9	CMC
+f60011|223344556677885f5f5f5f5f5f	32	intel	test byte ptr [eax], 0x11
+f60011|223344556677885f5f5f5f5f5f	32	plan9	TESTL $0x11, 0(AX)
+f60011|223344556677885f5f5f5f5f5f	64	gnu	testb $0x11,(%rax)
+f60011|223344556677885f5f5f5f5f5f	64	intel	test byte ptr [rax], 0x11
+f60011|223344556677885f5f5f5f5f5f	64	plan9	TESTL $0x11, 0(AX)
+f611|223344556677885f5f5f5f5f5f5f	32	intel	not byte ptr [ecx]
+f611|223344556677885f5f5f5f5f5f5f	32	plan9	NOTL 0(CX)
+f611|223344556677885f5f5f5f5f5f5f	64	gnu	notb (%rcx)
+f611|223344556677885f5f5f5f5f5f5f	64	intel	not byte ptr [rcx]
+f611|223344556677885f5f5f5f5f5f5f	64	plan9	NOTL 0(CX)
+f618|11223344556677885f5f5f5f5f5f	32	intel	neg byte ptr [eax]
+f618|11223344556677885f5f5f5f5f5f	32	plan9	NEGL 0(AX)
+f618|11223344556677885f5f5f5f5f5f	64	gnu	negb (%rax)
+f618|11223344556677885f5f5f5f5f5f	64	intel	neg byte ptr [rax]
+f618|11223344556677885f5f5f5f5f5f	64	plan9	NEGL 0(AX)
+f620|11223344556677885f5f5f5f5f5f	32	intel	mul byte ptr [eax]
+f620|11223344556677885f5f5f5f5f5f	32	plan9	MULL 0(AX)
+f620|11223344556677885f5f5f5f5f5f	64	gnu	mulb (%rax)
+f620|11223344556677885f5f5f5f5f5f	64	intel	mul byte ptr [rax]
+f620|11223344556677885f5f5f5f5f5f	64	plan9	MULL 0(AX)
+f628|11223344556677885f5f5f5f5f5f	32	intel	imul byte ptr [eax]
+f628|11223344556677885f5f5f5f5f5f	32	plan9	IMULL 0(AX)
+f628|11223344556677885f5f5f5f5f5f	64	gnu	imulb (%rax)
+f628|11223344556677885f5f5f5f5f5f	64	intel	imul byte ptr [rax]
+f628|11223344556677885f5f5f5f5f5f	64	plan9	IMULL 0(AX)
+f630|11223344556677885f5f5f5f5f5f	32	intel	div byte ptr [eax]
+f630|11223344556677885f5f5f5f5f5f	32	plan9	DIVL 0(AX)
+f630|11223344556677885f5f5f5f5f5f	64	gnu	divb (%rax)
+f630|11223344556677885f5f5f5f5f5f	64	intel	div byte ptr [rax]
+f630|11223344556677885f5f5f5f5f5f	64	plan9	DIVL 0(AX)
+f638|11223344556677885f5f5f5f5f5f	32	intel	idiv byte ptr [eax]
+f638|11223344556677885f5f5f5f5f5f	32	plan9	IDIVL 0(AX)
+f638|11223344556677885f5f5f5f5f5f	64	gnu	idivb (%rax)
+f638|11223344556677885f5f5f5f5f5f	64	intel	idiv byte ptr [rax]
+f638|11223344556677885f5f5f5f5f5f	64	plan9	IDIVL 0(AX)
+f70011223344|556677885f5f5f5f5f5f	32	intel	test dword ptr [eax], 0x44332211
+f70011223344|556677885f5f5f5f5f5f	32	plan9	TESTL $0x44332211, 0(AX)
+f70011223344|556677885f5f5f5f5f5f	64	gnu	testl $0x44332211,(%rax)
+f70011223344|556677885f5f5f5f5f5f	64	intel	test dword ptr [rax], 0x44332211
+f70011223344|556677885f5f5f5f5f5f	64	plan9	TESTL $0x44332211, 0(AX)
+f711|223344556677885f5f5f5f5f5f5f	32	intel	not dword ptr [ecx]
+f711|223344556677885f5f5f5f5f5f5f	32	plan9	NOTL 0(CX)
+f711|223344556677885f5f5f5f5f5f5f	64	gnu	notl (%rcx)
+f711|223344556677885f5f5f5f5f5f5f	64	intel	not dword ptr [rcx]
+f711|223344556677885f5f5f5f5f5f5f	64	plan9	NOTL 0(CX)
+f718|11223344556677885f5f5f5f5f5f	32	intel	neg dword ptr [eax]
+f718|11223344556677885f5f5f5f5f5f	32	plan9	NEGL 0(AX)
+f718|11223344556677885f5f5f5f5f5f	64	gnu	negl (%rax)
+f718|11223344556677885f5f5f5f5f5f	64	intel	neg dword ptr [rax]
+f718|11223344556677885f5f5f5f5f5f	64	plan9	NEGL 0(AX)
+f720|11223344556677885f5f5f5f5f5f	32	intel	mul dword ptr [eax]
+f720|11223344556677885f5f5f5f5f5f	32	plan9	MULL 0(AX)
+f720|11223344556677885f5f5f5f5f5f	64	gnu	mull (%rax)
+f720|11223344556677885f5f5f5f5f5f	64	intel	mul dword ptr [rax]
+f720|11223344556677885f5f5f5f5f5f	64	plan9	MULL 0(AX)
+f728|11223344556677885f5f5f5f5f5f	32	intel	imul dword ptr [eax]
+f728|11223344556677885f5f5f5f5f5f	32	plan9	IMULL 0(AX)
+f728|11223344556677885f5f5f5f5f5f	64	gnu	imull (%rax)
+f728|11223344556677885f5f5f5f5f5f	64	intel	imul dword ptr [rax]
+f728|11223344556677885f5f5f5f5f5f	64	plan9	IMULL 0(AX)
+f730|11223344556677885f5f5f5f5f5f	32	intel	div dword ptr [eax]
+f730|11223344556677885f5f5f5f5f5f	32	plan9	DIVL 0(AX)
+f730|11223344556677885f5f5f5f5f5f	64	gnu	divl (%rax)
+f730|11223344556677885f5f5f5f5f5f	64	intel	div dword ptr [rax]
+f730|11223344556677885f5f5f5f5f5f	64	plan9	DIVL 0(AX)
+f738|11223344556677885f5f5f5f5f5f	32	intel	idiv dword ptr [eax]
+f738|11223344556677885f5f5f5f5f5f	32	plan9	IDIVL 0(AX)
+f738|11223344556677885f5f5f5f5f5f	64	gnu	idivl (%rax)
+f738|11223344556677885f5f5f5f5f5f	64	intel	idiv dword ptr [rax]
+f738|11223344556677885f5f5f5f5f5f	64	plan9	IDIVL 0(AX)
+f8|11223344556677885f5f5f5f5f5f5f	32	intel	clc
+f8|11223344556677885f5f5f5f5f5f5f	32	plan9	CLC
+f8|11223344556677885f5f5f5f5f5f5f	64	gnu	clc
+f8|11223344556677885f5f5f5f5f5f5f	64	intel	clc
+f8|11223344556677885f5f5f5f5f5f5f	64	plan9	CLC
+f9|11223344556677885f5f5f5f5f5f5f	32	intel	stc
+f9|11223344556677885f5f5f5f5f5f5f	32	plan9	STC
+f9|11223344556677885f5f5f5f5f5f5f	64	gnu	stc
+f9|11223344556677885f5f5f5f5f5f5f	64	intel	stc
+f9|11223344556677885f5f5f5f5f5f5f	64	plan9	STC
+fa|11223344556677885f5f5f5f5f5f5f	32	intel	cli
+fa|11223344556677885f5f5f5f5f5f5f	32	plan9	CLI
+fa|11223344556677885f5f5f5f5f5f5f	64	gnu	cli
+fa|11223344556677885f5f5f5f5f5f5f	64	intel	cli
+fa|11223344556677885f5f5f5f5f5f5f	64	plan9	CLI
+fb|11223344556677885f5f5f5f5f5f5f	32	intel	sti
+fb|11223344556677885f5f5f5f5f5f5f	32	plan9	STI
+fb|11223344556677885f5f5f5f5f5f5f	64	gnu	sti
+fb|11223344556677885f5f5f5f5f5f5f	64	intel	sti
+fb|11223344556677885f5f5f5f5f5f5f	64	plan9	STI
+fc|11223344556677885f5f5f5f5f5f5f	32	intel	cld
+fc|11223344556677885f5f5f5f5f5f5f	32	plan9	CLD
+fc|11223344556677885f5f5f5f5f5f5f	64	gnu	cld
+fc|11223344556677885f5f5f5f5f5f5f	64	intel	cld
+fc|11223344556677885f5f5f5f5f5f5f	64	plan9	CLD
+fd|11223344556677885f5f5f5f5f5f5f	32	intel	std
+fd|11223344556677885f5f5f5f5f5f5f	32	plan9	STD
+fd|11223344556677885f5f5f5f5f5f5f	64	gnu	std
+fd|11223344556677885f5f5f5f5f5f5f	64	intel	std
+fd|11223344556677885f5f5f5f5f5f5f	64	plan9	STD
+fe00|11223344556677885f5f5f5f5f5f	32	intel	inc byte ptr [eax]
+fe00|11223344556677885f5f5f5f5f5f	32	plan9	INCL 0(AX)
+fe00|11223344556677885f5f5f5f5f5f	64	gnu	incb (%rax)
+fe00|11223344556677885f5f5f5f5f5f	64	intel	inc byte ptr [rax]
+fe00|11223344556677885f5f5f5f5f5f	64	plan9	INCL 0(AX)
+fe08|11223344556677885f5f5f5f5f5f	32	intel	dec byte ptr [eax]
+fe08|11223344556677885f5f5f5f5f5f	32	plan9	DECL 0(AX)
+fe08|11223344556677885f5f5f5f5f5f	64	gnu	decb (%rax)
+fe08|11223344556677885f5f5f5f5f5f	64	intel	dec byte ptr [rax]
+fe08|11223344556677885f5f5f5f5f5f	64	plan9	DECL 0(AX)
+ff00|11223344556677885f5f5f5f5f5f	32	intel	inc dword ptr [eax]
+ff00|11223344556677885f5f5f5f5f5f	32	plan9	INCL 0(AX)
+ff00|11223344556677885f5f5f5f5f5f	64	gnu	incl (%rax)
+ff00|11223344556677885f5f5f5f5f5f	64	intel	inc dword ptr [rax]
+ff00|11223344556677885f5f5f5f5f5f	64	plan9	INCL 0(AX)
+ff08|11223344556677885f5f5f5f5f5f	32	intel	dec dword ptr [eax]
+ff08|11223344556677885f5f5f5f5f5f	32	plan9	DECL 0(AX)
+ff08|11223344556677885f5f5f5f5f5f	64	gnu	decl (%rax)
+ff08|11223344556677885f5f5f5f5f5f	64	intel	dec dword ptr [rax]
+ff08|11223344556677885f5f5f5f5f5f	64	plan9	DECL 0(AX)
+ff11|223344556677885f5f5f5f5f5f5f	32	intel	call dword ptr [ecx]
+ff11|223344556677885f5f5f5f5f5f5f	32	plan9	CALL 0(CX)
+ff18|11223344556677885f5f5f5f5f5f	32	intel	call far ptr [eax]
+ff18|11223344556677885f5f5f5f5f5f	32	plan9	LCALL 0(AX)
+ff18|11223344556677885f5f5f5f5f5f	64	gnu	lcallq *(%rax)
+ff18|11223344556677885f5f5f5f5f5f	64	intel	call far ptr [rax]
+ff18|11223344556677885f5f5f5f5f5f	64	plan9	LCALL 0(AX)
+ff20|11223344556677885f5f5f5f5f5f	32	intel	jmp dword ptr [eax]
+ff20|11223344556677885f5f5f5f5f5f	32	plan9	JMP 0(AX)
+ff28|11223344556677885f5f5f5f5f5f	32	intel	jmp far ptr [eax]
+ff28|11223344556677885f5f5f5f5f5f	32	plan9	LJMP 0(AX)
+ff28|11223344556677885f5f5f5f5f5f	64	gnu	ljmpq *(%rax)
+ff28|11223344556677885f5f5f5f5f5f	64	intel	jmp far ptr [rax]
+ff28|11223344556677885f5f5f5f5f5f	64	plan9	LJMP 0(AX)
+ff30|11223344556677885f5f5f5f5f5f	32	intel	push dword ptr [eax]
+ff30|11223344556677885f5f5f5f5f5f	32	plan9	PUSHL 0(AX)
+ff30|11223344556677885f5f5f5f5f5f	64	gnu	pushq (%rax)
+ff30|11223344556677885f5f5f5f5f5f	64	intel	push qword ptr [rax]
+ff30|11223344556677885f5f5f5f5f5f	64	plan9	PUSHL 0(AX)
diff --git a/src/cmd/internal/rsc.io/x86/x86asm/xed_test.go b/src/cmd/internal/rsc.io/x86/x86asm/xed_test.go
new file mode 100644
index 0000000..91cf822
--- /dev/null
+++ b/src/cmd/internal/rsc.io/x86/x86asm/xed_test.go
@@ -0,0 +1,211 @@
+// 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 x86asm
+
+import (
+	"bytes"
+	"strings"
+	"testing"
+)
+
+func TestXed32Manual(t *testing.T)   { testXed32(t, hexCases(t, xedManualTests)) }
+func TestXed32Testdata(t *testing.T) { testXed32(t, concat(basicPrefixes, testdataCases(t))) }
+func TestXed32ModRM(t *testing.T)    { testXed32(t, concat(basicPrefixes, enumModRM)) }
+func TestXed32OneByte(t *testing.T)  { testBasic(t, testXed32) }
+func TestXed320F(t *testing.T)       { testBasic(t, testXed32, 0x0F) }
+func TestXed320F38(t *testing.T)     { testBasic(t, testXed32, 0x0F, 0x38) }
+func TestXed320F3A(t *testing.T)     { testBasic(t, testXed32, 0x0F, 0x3A) }
+func TestXed32Prefix(t *testing.T)   { testPrefix(t, testXed32) }
+
+func TestXed64Manual(t *testing.T)   { testXed64(t, hexCases(t, xedManualTests)) }
+func TestXed64Testdata(t *testing.T) { testXed64(t, concat(basicPrefixes, testdataCases(t))) }
+func TestXed64ModRM(t *testing.T)    { testXed64(t, concat(basicPrefixes, enumModRM)) }
+func TestXed64OneByte(t *testing.T)  { testBasic(t, testXed64) }
+func TestXed640F(t *testing.T)       { testBasic(t, testXed64, 0x0F) }
+func TestXed640F38(t *testing.T)     { testBasic(t, testXed64, 0x0F, 0x38) }
+func TestXed640F3A(t *testing.T)     { testBasic(t, testXed64, 0x0F, 0x3A) }
+func TestXed64Prefix(t *testing.T)   { testPrefix(t, testXed64) }
+
+func TestXed64REXTestdata(t *testing.T) {
+	testXed64(t, filter(concat3(basicPrefixes, rexPrefixes, testdataCases(t)), isValidREX))
+}
+func TestXed64REXModRM(t *testing.T)   { testXed64(t, concat3(basicPrefixes, rexPrefixes, enumModRM)) }
+func TestXed64REXOneByte(t *testing.T) { testBasicREX(t, testXed64) }
+func TestXed64REX0F(t *testing.T)      { testBasicREX(t, testXed64, 0x0F) }
+func TestXed64REX0F38(t *testing.T)    { testBasicREX(t, testXed64, 0x0F, 0x38) }
+func TestXed64REX0F3A(t *testing.T)    { testBasicREX(t, testXed64, 0x0F, 0x3A) }
+func TestXed64REXPrefix(t *testing.T)  { testPrefixREX(t, testXed64) }
+
+// xedManualTests holds test cases that will be run by TestXedManual32 and TestXedManual64.
+// If you are debugging a few cases that turned up in a longer run, it can be useful
+// to list them here and then use -run=XedManual, particularly with tracing enabled.
+var xedManualTests = `
+6690
+`
+
+// allowedMismatchXed reports whether the mismatch between text and dec
+// should be allowed by the test.
+func allowedMismatchXed(text string, size int, inst *Inst, dec ExtInst) bool {
+	if (contains(text, "error:") || isPrefix(text) && size == 1) && contains(dec.text, "GENERAL_ERROR", "INSTR_TOO_LONG", "BAD_LOCK_PREFIX") {
+		return true
+	}
+
+	if contains(dec.text, "BAD_LOCK_PREFIX") && countExactPrefix(inst, PrefixLOCK|PrefixInvalid) > 0 {
+		return true
+	}
+
+	if contains(dec.text, "BAD_LOCK_PREFIX", "GENERAL_ERROR") && countExactPrefix(inst, PrefixLOCK|PrefixImplicit) > 0 {
+		return true
+	}
+
+	if text == "lock" && size == 1 && contains(dec.text, "BAD_LOCK_PREFIX") {
+		return true
+	}
+
+	// Instructions not known to us.
+	if (contains(text, "error:") || isPrefix(text) && size == 1) && contains(dec.text, unsupported...) {
+		return true
+	}
+
+	// Instructions not known to xed.
+	if contains(text, xedUnsupported...) && contains(dec.text, "ERROR") {
+		return true
+	}
+
+	if (contains(text, "error:") || isPrefix(text) && size == 1) && contains(dec.text, "shl ") && (inst.Opcode>>16)&0xEC38 == 0xC030 {
+		return true
+	}
+
+	// 82 11 22: xed says 'adc byte ptr [ecx], 0x22' but there is no justification in the manuals for that.
+	// C0 30 11: xed says 'shl byte ptr [eax], 0x11' but there is no justification in the manuals for that.
+	// F6 08 11: xed says 'test byte ptr [eax], 0x11' but there is no justification in the manuals for that.
+	if (contains(text, "error:") || isPrefix(text) && size == 1) && hasByte(dec.enc[:dec.nenc], 0x82, 0xC0, 0xC1, 0xD0, 0xD1, 0xD2, 0xD3, 0xF6, 0xF7) {
+		return true
+	}
+
+	// F3 11 22 and many others: xed allows and drops misused rep/repn prefix.
+	if (text == "rep" && dec.enc[0] == 0xF3 || (text == "repn" || text == "repne") && dec.enc[0] == 0xF2) && (!contains(dec.text, "ins", "outs", "movs", "lods", "cmps", "scas") || contains(dec.text, "xmm")) {
+		return true
+	}
+
+	// 0F C7 30: xed says vmptrld qword ptr [eax]; we say rdrand eax.
+	// TODO(rsc): Fix, since we are probably wrong, but we don't have vmptrld in the manual.
+	if contains(text, "rdrand") && contains(dec.text, "vmptrld", "vmxon", "vmclear") {
+		return true
+	}
+
+	// F3 0F AE 00: we say 'rdfsbase dword ptr [eax]' but RDFSBASE needs a register.
+	// Also, this is a 64-bit only instruction.
+	// TODO(rsc): Fix to reject this encoding.
+	if contains(text, "rdfsbase", "rdgsbase", "wrfsbase", "wrgsbase") && contains(dec.text, "ERROR") {
+		return true
+	}
+
+	// 0F 01 F8: we say swapgs but that's only valid in 64-bit mode.
+	// TODO(rsc): Fix.
+	if contains(text, "swapgs") {
+		return true
+	}
+
+	// 0F 24 11: 'mov ecx, tr2' except there is no TR2.
+	// Or maybe the MOV to TR registers doesn't use RMF.
+	if contains(text, "cr1", "cr5", "cr6", "cr7", "tr0", "tr1", "tr2", "tr3", "tr4", "tr5", "tr6", "tr7") && contains(dec.text, "ERROR") {
+		return true
+	}
+
+	// 0F 19 11, 0F 1C 11, 0F 1D 11, 0F 1E 11, 0F 1F 11: xed says nop,
+	// but the Intel manuals say that the only NOP there is 0F 1F /0.
+	// Perhaps xed is reporting an older encoding.
+	if (contains(text, "error:") || isPrefix(text) && size == 1) && contains(dec.text, "nop ") && (inst.Opcode>>8)&0xFFFF38 != 0x0F1F00 {
+		return true
+	}
+
+	// 66 0F AE 38: clflushopt but we only know clflush
+	if contains(text, "clflush") && contains(dec.text, "clflushopt") {
+		return true
+	}
+
+	// 0F 20 04 11: MOV SP, CR0 but has mod!=3 despite register argument.
+	// (This encoding ignores the mod bits.) The decoder sees the non-register
+	// mod and reads farther ahead to decode the memory reference that
+	// isn't really there, causing the size to be too large.
+	// TODO(rsc): Fix.
+	if text == dec.text && size > dec.nenc && contains(text, " cr", " dr", " tr") {
+		return true
+	}
+
+	// 0F AE E9: xed says lfence, which is wrong (only 0F AE E8 is lfence). And so on.
+	if contains(dec.text, "fence") && hasByte(dec.enc[:dec.nenc], 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF) {
+		return true
+	}
+
+	// DD C9, DF C9: xed says 'fxch st0, st1' but that instruction is D9 C9.
+	if (contains(text, "error:") || isPrefix(text) && size == 1) && contains(dec.text, "fxch ") && hasByte(dec.enc[:dec.nenc], 0xDD, 0xDF) {
+		return true
+	}
+
+	// DC D4: xed says 'fcom st0, st4' but that instruction is D8 D4.
+	if (contains(text, "error:") || isPrefix(text) && size == 1) && contains(dec.text, "fcom ") && hasByte(dec.enc[:dec.nenc], 0xD8, 0xDC) {
+		return true
+	}
+
+	// DE D4: xed says 'fcomp st0, st4' but that instruction is D8 D4.
+	if (contains(text, "error:") || isPrefix(text) && size == 1) && contains(dec.text, "fcomp ") && hasByte(dec.enc[:dec.nenc], 0xDC, 0xDE) {
+		return true
+	}
+
+	// DF D4: xed says 'fstp st4, st0' but that instruction is DD D4.
+	if (contains(text, "error:") || isPrefix(text) && size == 1) && contains(dec.text, "fstp ") && hasByte(dec.enc[:dec.nenc], 0xDF) {
+		return true
+	}
+
+	return false
+}
+
+func countExactPrefix(inst *Inst, target Prefix) int {
+	n := 0
+	for _, p := range inst.Prefix {
+		if p == target {
+			n++
+		}
+	}
+	return n
+}
+
+func hasByte(src []byte, target ...byte) bool {
+	for _, b := range target {
+		if bytes.IndexByte(src, b) >= 0 {
+			return true
+		}
+	}
+	return false
+}
+
+// Instructions known to us but not to xed.
+var xedUnsupported = strings.Fields(`
+	xrstor
+	xsave
+	xsave
+	ud1
+	xgetbv
+	xsetbv
+	fxsave
+	fxrstor
+	clflush
+	lfence
+	mfence
+	sfence
+	rsqrtps
+	rcpps
+	emms
+	ldmxcsr
+	stmxcsr
+	movhpd
+	movnti
+	rdrand
+	movbe
+	movlpd
+	sysret
+`)
diff --git a/src/cmd/internal/rsc.io/x86/x86asm/xedext_test.go b/src/cmd/internal/rsc.io/x86/x86asm/xedext_test.go
new file mode 100644
index 0000000..d7aa8e3
--- /dev/null
+++ b/src/cmd/internal/rsc.io/x86/x86asm/xedext_test.go
@@ -0,0 +1,206 @@
+package x86asm
+
+import (
+	"bytes"
+	"fmt"
+	"io"
+	"log"
+	"os"
+	"strconv"
+	"strings"
+	"testing"
+)
+
+// xed binary from Intel sde-external-6.22.0-2014-03-06.
+const xedPath = "/Users/rsc/bin/xed"
+
+func testXedArch(t *testing.T, arch int, generate func(func([]byte))) {
+	if testing.Short() {
+		t.Skip("skipping libmach test in short mode")
+	}
+
+	if _, err := os.Stat(xedPath); err != nil {
+		t.Fatal(err)
+	}
+
+	testExtDis(t, "intel", arch, xed, generate, allowedMismatchXed)
+}
+
+func testXed32(t *testing.T, generate func(func([]byte))) {
+	testXedArch(t, 32, generate)
+}
+
+func testXed64(t *testing.T, generate func(func([]byte))) {
+	testXedArch(t, 64, generate)
+}
+
+func xed(ext *ExtDis) error {
+	b, err := ext.Run(xedPath, fmt.Sprintf("-%d", ext.Arch), "-n", "1G", "-ir", ext.File.Name())
+	if err != nil {
+		return err
+	}
+
+	nmatch := 0
+	next := uint32(start)
+	var (
+		addr   uint32
+		encbuf [32]byte
+		enc    []byte
+		text   string
+	)
+
+	var xedEnd = []byte("# end of text section")
+	var xedEnd1 = []byte("# Errors")
+
+	eof := false
+	for {
+		line, err := b.ReadSlice('\n')
+		if err != nil {
+			if err == io.EOF {
+				break
+			}
+			return fmt.Errorf("reading objdump output: %v", err)
+		}
+		if debug {
+			os.Stdout.Write(line)
+		}
+		if bytes.HasPrefix(line, xedEnd) || bytes.HasPrefix(line, xedEnd1) {
+			eof = true
+		}
+		if eof {
+			continue
+		}
+		nmatch++
+		addr, enc, text = parseLineXed(line, encbuf[:0])
+		if addr > next {
+			return fmt.Errorf("address out of sync expected <= %#x at %q in:\n%s", next, line, line)
+		}
+		if addr < next {
+			continue
+		}
+		switch text {
+		case "repz":
+			text = "rep"
+		case "repnz":
+			text = "repn"
+		default:
+			text = strings.Replace(text, "repz ", "rep ", -1)
+			text = strings.Replace(text, "repnz ", "repn ", -1)
+		}
+		if m := pcrelw.FindStringSubmatch(text); m != nil {
+			targ, _ := strconv.ParseUint(m[2], 16, 64)
+			text = fmt.Sprintf("%s .%+#x", m[1], int16(uint32(targ)-uint32(uint16(addr))-uint32(len(enc))))
+		}
+		if m := pcrel.FindStringSubmatch(text); m != nil {
+			targ, _ := strconv.ParseUint(m[2], 16, 64)
+			text = fmt.Sprintf("%s .%+#x", m[1], int32(uint32(targ)-addr-uint32(len(enc))))
+		}
+		ext.Dec <- ExtInst{addr, encbuf, len(enc), text}
+		encbuf = [32]byte{}
+		enc = nil
+		next += 32
+	}
+	if next != start+uint32(ext.Size) {
+		return fmt.Errorf("not enough results found [%d %d]", next, start+ext.Size)
+	}
+	if err := ext.Wait(); err != nil {
+		return fmt.Errorf("exec: %v", err)
+	}
+
+	return nil
+}
+
+var (
+	xedInRaw    = []byte("In raw...")
+	xedDots     = []byte("...")
+	xdis        = []byte("XDIS ")
+	xedError    = []byte("ERROR: ")
+	xedNoDecode = []byte("Could not decode at offset: 0x")
+)
+
+func parseLineXed(line []byte, encstart []byte) (addr uint32, enc []byte, text string) {
+	oline := line
+	if bytes.HasPrefix(line, xedInRaw) || bytes.HasPrefix(line, xedDots) {
+		return 0, nil, ""
+	}
+	if bytes.HasPrefix(line, xedError) {
+		i := bytes.IndexByte(line[len(xedError):], ' ')
+		if i < 0 {
+			log.Fatalf("cannot parse error: %q", oline)
+		}
+		errstr := string(line[len(xedError):])
+		i = bytes.Index(line, xedNoDecode)
+		if i < 0 {
+			log.Fatalf("cannot parse error: %q", oline)
+		}
+		i += len(xedNoDecode)
+		j := bytes.IndexByte(line[i:], ' ')
+		if j < 0 {
+			log.Fatalf("cannot parse error: %q", oline)
+		}
+		x, err := strconv.ParseUint(string(trimSpace(line[i:i+j])), 16, 32)
+		if err != nil {
+			log.Fatalf("cannot parse disassembly: %q", oline)
+		}
+		addr = uint32(x)
+		return addr, nil, errstr
+	}
+
+	if !bytes.HasPrefix(line, xdis) {
+		log.Fatalf("cannot parse disassembly: %q", oline)
+	}
+
+	i := bytes.IndexByte(line, ':')
+	if i < 0 {
+		log.Fatalf("cannot parse disassembly: %q", oline)
+	}
+	x, err := strconv.ParseUint(string(trimSpace(line[len(xdis):i])), 16, 32)
+	if err != nil {
+		log.Fatalf("cannot parse disassembly: %q", oline)
+	}
+	addr = uint32(x)
+
+	// spaces
+	i++
+	for i < len(line) && line[i] == ' ' {
+		i++
+	}
+	// instruction class, spaces
+	for i < len(line) && line[i] != ' ' {
+		i++
+	}
+	for i < len(line) && line[i] == ' ' {
+		i++
+	}
+	// instruction set, spaces
+	for i < len(line) && line[i] != ' ' {
+		i++
+	}
+	for i < len(line) && line[i] == ' ' {
+		i++
+	}
+
+	// hex
+	hexStart := i
+	for i < len(line) && line[i] != ' ' {
+		i++
+	}
+	hexEnd := i
+	for i < len(line) && line[i] == ' ' {
+		i++
+	}
+
+	// text
+	textStart := i
+	for i < len(line) && line[i] != '\n' {
+		i++
+	}
+	textEnd := i
+
+	enc, ok := parseHex(line[hexStart:hexEnd], encstart)
+	if !ok {
+		log.Fatalf("cannot parse disassembly: %q", oline)
+	}
+
+	return addr, enc, string(fixSpace(line[textStart:textEnd]))
+}
diff --git a/src/cmd/ld/data.c b/src/cmd/ld/data.c
index 55d0207..6184754 100644
--- a/src/cmd/ld/data.c
+++ b/src/cmd/ld/data.c
@@ -35,7 +35,7 @@
 #include	"../ld/elf.h"
 #include	"../ld/macho.h"
 #include	"../ld/pe.h"
-#include	"../../pkg/runtime/mgc0.h"
+#include	"../../runtime/mgc0.h"
 
 void	dynreloc(void);
 
@@ -145,7 +145,7 @@ relocsym(LSym *s)
 			diag("%s: invalid relocation %d+%d not in [%d,%d)", s->name, off, siz, 0, s->np);
 			continue;
 		}
-		if(r->sym != S && (r->sym->type & SMASK == 0 || r->sym->type & SMASK == SXREF)) {
+		if(r->sym != S && ((r->sym->type & (SMASK | SHIDDEN)) == 0 || (r->sym->type & SMASK) == SXREF)) {
 			diag("%s: not defined", r->sym->name);
 			continue;
 		}
@@ -160,6 +160,10 @@ relocsym(LSym *s)
 		if(r->sym != S && r->sym->type != STLSBSS && !r->sym->reachable)
 			diag("unreachable sym in relocation: %s %s", s->name, r->sym->name);
 
+		// Android emulates runtime.tlsg as a regular variable.
+		if (r->type == R_TLS && strcmp(goos, "android") == 0)
+			r->type = R_ADDR;
+
 		switch(r->type) {
 		default:
 			o = 0;
@@ -186,8 +190,8 @@ relocsym(LSym *s)
 		case R_TLS_LE:
 			if(linkmode == LinkExternal && iself && HEADTYPE != Hopenbsd) {
 				r->done = 0;
-				r->sym = ctxt->gmsym;
-				r->xsym = ctxt->gmsym;
+				r->sym = ctxt->tlsg;
+				r->xsym = ctxt->tlsg;
 				r->xadd = r->add;
 				o = 0;
 				if(thechar != '6')
@@ -200,8 +204,8 @@ relocsym(LSym *s)
 		case R_TLS_IE:
 			if(linkmode == LinkExternal && iself && HEADTYPE != Hopenbsd) {
 				r->done = 0;
-				r->sym = ctxt->gmsym;
-				r->xsym = ctxt->gmsym;
+				r->sym = ctxt->tlsg;
+				r->xsym = ctxt->tlsg;
 				r->xadd = r->add;
 				o = 0;
 				if(thechar != '6')
@@ -277,9 +281,13 @@ relocsym(LSym *s)
 					if(thechar == '6')
 						o = 0;
 				} else if(HEADTYPE == Hdarwin) {
-					if(rs->type != SHOSTOBJ)
-						o += symaddr(rs) - rs->sect->vaddr;
-					o -= r->off; // WTF?
+					if(r->type == R_CALL) {
+						if(rs->type != SHOSTOBJ)
+							o += symaddr(rs) - rs->sect->vaddr;
+						o -= r->off; // relative to section offset, not symbol
+					} else {
+						o += r->siz;
+					}
 				} else {
 					diag("unhandled pcrel relocation for %s", headstring);
 				}
@@ -421,10 +429,10 @@ dynreloc(void)
 }
 
 static void
-blk(LSym *start, int32 addr, int32 size)
+blk(LSym *start, int64 addr, int64 size)
 {
 	LSym *sym;
-	int32 eaddr;
+	int64 eaddr;
 	uchar *p, *ep;
 
 	for(sym = start; sym != nil; sym = sym->next)
@@ -463,10 +471,10 @@ blk(LSym *start, int32 addr, int32 size)
 }
 
 void
-codeblk(int32 addr, int32 size)
+codeblk(int64 addr, int64 size)
 {
 	LSym *sym;
-	int32 eaddr, n;
+	int64 eaddr, n;
 	uchar *q;
 
 	if(debug['a'])
@@ -523,10 +531,10 @@ codeblk(int32 addr, int32 size)
 }
 
 void
-datblk(int32 addr, int32 size)
+datblk(int64 addr, int64 size)
 {
 	LSym *sym;
-	int32 i, eaddr;
+	int64 i, eaddr;
 	uchar *p, *ep;
 	char *typ, *rsname;
 	Reloc *r;
@@ -612,22 +620,26 @@ addstrdata(char *name, char *value)
 {
 	LSym *s, *sp;
 	char *p;
+	uchar reachable;
 
 	p = smprint("%s.str", name);
 	sp = linklookup(ctxt, p, 0);
 	free(p);
 	addstring(sp, value);
+	sp->type = SRODATA;
 
 	s = linklookup(ctxt, name, 0);
 	s->size = 0;
 	s->dupok = 1;
+	reachable = s->reachable;
 	addaddr(ctxt, s, sp);
-	adduint32(ctxt, s, strlen(value));
-	if(PtrSize == 8)
-		adduint32(ctxt, s, 0);  // round struct to pointer width
+	adduintxx(ctxt, s, strlen(value), PtrSize);
 
-	// in case reachability has already been computed
-	sp->reachable = s->reachable;
+	// addstring, addaddr, etc., mark the symbols as reachable.
+	// In this case that is not necessarily true, so stick to what
+	// we know before entering this function.
+	s->reachable = reachable;
+	sp->reachable = reachable;
 }
 
 vlong
@@ -702,31 +714,176 @@ maxalign(LSym *s, int type)
 	return max;
 }
 
+// Helper object for building GC type programs.
+typedef struct ProgGen ProgGen;
+struct ProgGen
+{
+	LSym*	s;
+	int32	datasize;
+	uint8	data[256/PointersPerByte];
+	vlong	pos;
+};
+
 static void
-gcaddsym(LSym *gc, LSym *s, vlong off)
+proggeninit(ProgGen *g, LSym *s)
 {
-	vlong a;
-	LSym *gotype;
+	g->s = s;
+	g->datasize = 0;
+	g->pos = 0;
+	memset(g->data, 0, sizeof(g->data));
+}
 
-	if(s->size < PtrSize)
+static void
+proggenemit(ProgGen *g, uint8 v)
+{
+	adduint8(ctxt, g->s, v);
+}
+
+// Writes insData block from g->data.
+static void
+proggendataflush(ProgGen *g)
+{
+	int32 i, s;
+
+	if(g->datasize == 0)
 		return;
-	if(strcmp(s->name, ".string") == 0)
+	proggenemit(g, insData);
+	proggenemit(g, g->datasize);
+	s = (g->datasize + PointersPerByte - 1)/PointersPerByte;
+	for(i = 0; i < s; i++)
+		proggenemit(g, g->data[i]);
+	g->datasize = 0;
+	memset(g->data, 0, sizeof(g->data));
+}
+
+static void
+proggendata(ProgGen *g, uint8 d)
+{
+	g->data[g->datasize/PointersPerByte] |= d << ((g->datasize%PointersPerByte)*BitsPerPointer);
+	g->datasize++;
+	if(g->datasize == 255)
+		proggendataflush(g);
+}
+
+// Skip v bytes due to alignment, etc.
+static void
+proggenskip(ProgGen *g, vlong off, vlong v)
+{
+	vlong i;
+
+	for(i = off; i < off+v; i++) {
+		if((i%PtrSize) == 0)
+			proggendata(g, BitsScalar);
+	}
+}
+
+// Emit insArray instruction.
+static void
+proggenarray(ProgGen *g, vlong len)
+{
+	int32 i;
+
+	proggendataflush(g);
+	proggenemit(g, insArray);
+	for(i = 0; i < PtrSize; i++, len >>= 8)
+		proggenemit(g, len);
+}
+
+static void
+proggenarrayend(ProgGen *g)
+{
+	proggendataflush(g);
+	proggenemit(g, insArrayEnd);
+}
+
+static void
+proggenfini(ProgGen *g, vlong size)
+{
+	proggenskip(g, g->pos, size - g->pos);
+	proggendataflush(g);
+	proggenemit(g, insEnd);
+}
+
+
+// This function generates GC pointer info for global variables.
+static void
+proggenaddsym(ProgGen *g, LSym *s)
+{
+	LSym *gcprog;
+	uint8 *mask;
+	vlong i, size;
+
+	if(s->size == 0)
 		return;
 
-	gotype = s->gotype;
-	if(gotype != nil) {
-		//print("gcaddsym:    %s    %d    %s\n", s->name, s->size, gotype->name);
-		adduintxx(ctxt, gc, GC_CALL, PtrSize);
-		adduintxx(ctxt, gc, off, PtrSize);
-		addpcrelplus(ctxt, gc, decodetype_gc(gotype), 3*PtrSize+4);
-		if(PtrSize == 8)
-			adduintxx(ctxt, gc, 0, 4);
-	} else {
-		//print("gcaddsym:    %s    %d    <unknown type>\n", s->name, s->size);
-		for(a = -off&(PtrSize-1); a+PtrSize<=s->size; a+=PtrSize) {
-			adduintxx(ctxt, gc, GC_APTR, PtrSize);
-			adduintxx(ctxt, gc, off+a, PtrSize);
+	// Skip alignment hole from the previous symbol.
+	proggenskip(g, g->pos, s->value - g->pos);
+	g->pos += s->value - g->pos;
+
+	// The test for names beginning with . here is meant
+	// to keep .dynamic and .dynsym from turning up as
+	// conservative symbols. They should be marked SELFSECT
+	// and not SDATA, but sometimes that doesn't happen.
+	// Leave debugging the SDATA issue for the Go rewrite.
+
+	if(s->gotype == nil && s->size >= PtrSize && s->name[0] != '.') {
+		// conservative scan
+		diag("missing Go type information for global symbol: %s size %d", s->name, (int)s->size);
+		if((s->size%PtrSize) || (g->pos%PtrSize))
+			diag("proggenaddsym: unaligned conservative symbol %s: size=%lld pos=%lld",
+				s->name, s->size, g->pos);
+		size = (s->size+PtrSize-1)/PtrSize*PtrSize;
+		if(size < 32*PtrSize) {
+			// Emit small symbols as data.
+			for(i = 0; i < size/PtrSize; i++)
+				proggendata(g, BitsPointer);
+		} else {
+			// Emit large symbols as array.
+			proggenarray(g, size/PtrSize);
+			proggendata(g, BitsPointer);
+			proggenarrayend(g);
+		}
+		g->pos = s->value + size;
+	} else if(s->gotype == nil || decodetype_noptr(s->gotype) || s->size < PtrSize || s->name[0] == '.') {
+		// no scan
+		if(s->size < 32*PtrSize) {
+			// Emit small symbols as data.
+			// This case also handles unaligned and tiny symbols, so tread carefully.
+			for(i = s->value; i < s->value+s->size; i++) {
+				if((i%PtrSize) == 0)
+					proggendata(g, BitsScalar);
+			}
+		} else {
+			// Emit large symbols as array.
+			if((s->size%PtrSize) || (g->pos%PtrSize))
+				diag("proggenaddsym: unaligned noscan symbol %s: size=%lld pos=%lld",
+					s->name, s->size, g->pos);
+			proggenarray(g, s->size/PtrSize);
+			proggendata(g, BitsScalar);
+			proggenarrayend(g);
 		}
+		g->pos = s->value + s->size;
+	} else if(decodetype_usegcprog(s->gotype)) {
+		// gc program, copy directly
+		proggendataflush(g);
+		gcprog = decodetype_gcprog(s->gotype);
+		size = decodetype_size(s->gotype);
+		if((size%PtrSize) || (g->pos%PtrSize))
+			diag("proggenaddsym: unaligned gcprog symbol %s: size=%lld pos=%lld",
+				s->name, s->size, g->pos);
+		for(i = 0; i < gcprog->np-1; i++)
+			proggenemit(g, gcprog->p[i]);
+		g->pos = s->value + size;
+	} else {
+		// gc mask, it's small so emit as data
+		mask = decodetype_gcmask(s->gotype);
+		size = decodetype_size(s->gotype);
+		if((size%PtrSize) || (g->pos%PtrSize))
+			diag("proggenaddsym: unaligned gcmask symbol %s: size=%lld pos=%lld",
+				s->name, s->size, g->pos);
+		for(i = 0; i < size; i += PtrSize)
+			proggendata(g, (mask[i/PtrSize/2]>>((i/PtrSize%2)*4+2))&BitsMask);
+		g->pos = s->value + size;
 	}
 }
 
@@ -751,19 +908,13 @@ dodata(void)
 	Section *sect;
 	Segment *segro;
 	LSym *s, *last, **l;
-	LSym *gcdata1, *gcbss1;
+	LSym *gcdata, *gcbss;
+	ProgGen gen;
 
 	if(debug['v'])
 		Bprint(&bso, "%5.2f dodata\n", cputime());
 	Bflush(&bso);
 
-	gcdata1 = linklookup(ctxt, "gcdata", 0);
-	gcbss1 = linklookup(ctxt, "gcbss", 0);
-
-	// size of .data and .bss section. the zero value is later replaced by the actual size of the section.
-	adduintxx(ctxt, gcdata1, 0, PtrSize);
-	adduintxx(ctxt, gcbss1, 0, PtrSize);
-
 	last = nil;
 	datap = nil;
 
@@ -847,8 +998,8 @@ dodata(void)
 	sect->align = maxalign(s, SINITARR-1);
 	datsize = rnd(datsize, sect->align);
 	sect->vaddr = datsize;
-	linklookup(ctxt, "noptrdata", 0)->sect = sect;
-	linklookup(ctxt, "enoptrdata", 0)->sect = sect;
+	linklookup(ctxt, "runtime.noptrdata", 0)->sect = sect;
+	linklookup(ctxt, "runtime.enoptrdata", 0)->sect = sect;
 	for(; s != nil && s->type < SINITARR; s = s->next) {
 		datsize = aligndatsize(datsize, s);
 		s->sect = sect;
@@ -878,8 +1029,10 @@ dodata(void)
 	sect->align = maxalign(s, SBSS-1);
 	datsize = rnd(datsize, sect->align);
 	sect->vaddr = datsize;
-	linklookup(ctxt, "data", 0)->sect = sect;
-	linklookup(ctxt, "edata", 0)->sect = sect;
+	linklookup(ctxt, "runtime.data", 0)->sect = sect;
+	linklookup(ctxt, "runtime.edata", 0)->sect = sect;
+	gcdata = linklookup(ctxt, "runtime.gcdata", 0);
+	proggeninit(&gen, gcdata);
 	for(; s != nil && s->type < SBSS; s = s->next) {
 		if(s->type == SINITARR) {
 			ctxt->cursym = s;
@@ -889,40 +1042,38 @@ dodata(void)
 		s->type = SDATA;
 		datsize = aligndatsize(datsize, s);
 		s->value = datsize - sect->vaddr;
-		gcaddsym(gcdata1, s, datsize - sect->vaddr);  // gc
+		proggenaddsym(&gen, s);  // gc
 		growdatsize(&datsize, s);
 	}
 	sect->len = datsize - sect->vaddr;
-
-	adduintxx(ctxt, gcdata1, GC_END, PtrSize);
-	setuintxx(ctxt, gcdata1, 0, sect->len, PtrSize);
+	proggenfini(&gen, sect->len);  // gc
 
 	/* bss */
 	sect = addsection(&segdata, ".bss", 06);
 	sect->align = maxalign(s, SNOPTRBSS-1);
 	datsize = rnd(datsize, sect->align);
 	sect->vaddr = datsize;
-	linklookup(ctxt, "bss", 0)->sect = sect;
-	linklookup(ctxt, "ebss", 0)->sect = sect;
+	linklookup(ctxt, "runtime.bss", 0)->sect = sect;
+	linklookup(ctxt, "runtime.ebss", 0)->sect = sect;
+	gcbss = linklookup(ctxt, "runtime.gcbss", 0);
+	proggeninit(&gen, gcbss);
 	for(; s != nil && s->type < SNOPTRBSS; s = s->next) {
 		s->sect = sect;
 		datsize = aligndatsize(datsize, s);
 		s->value = datsize - sect->vaddr;
-		gcaddsym(gcbss1, s, datsize - sect->vaddr);  // gc
+		proggenaddsym(&gen, s);  // gc
 		growdatsize(&datsize, s);
 	}
 	sect->len = datsize - sect->vaddr;
-
-	adduintxx(ctxt, gcbss1, GC_END, PtrSize);
-	setuintxx(ctxt, gcbss1, 0, sect->len, PtrSize);
+	proggenfini(&gen, sect->len);  // gc
 
 	/* pointer-free bss */
 	sect = addsection(&segdata, ".noptrbss", 06);
 	sect->align = maxalign(s, SNOPTRBSS);
 	datsize = rnd(datsize, sect->align);
 	sect->vaddr = datsize;
-	linklookup(ctxt, "noptrbss", 0)->sect = sect;
-	linklookup(ctxt, "enoptrbss", 0)->sect = sect;
+	linklookup(ctxt, "runtime.noptrbss", 0)->sect = sect;
+	linklookup(ctxt, "runtime.enoptrbss", 0)->sect = sect;
 	for(; s != nil && s->type == SNOPTRBSS; s = s->next) {
 		datsize = aligndatsize(datsize, s);
 		s->sect = sect;
@@ -930,7 +1081,7 @@ dodata(void)
 		growdatsize(&datsize, s);
 	}
 	sect->len = datsize - sect->vaddr;
-	linklookup(ctxt, "end", 0)->sect = sect;
+	linklookup(ctxt, "runtime.end", 0)->sect = sect;
 
 	// 6g uses 4-byte relocation offsets, so the entire segment must fit in 32 bits.
 	if(datsize != (uint32)datsize) {
@@ -951,9 +1102,9 @@ dodata(void)
 		sect->len = datsize;
 	} else {
 		// Might be internal linking but still using cgo.
-		// In that case, the only possible STLSBSS symbol is tlsgm.
+		// In that case, the only possible STLSBSS symbol is runtime.tlsg.
 		// Give it offset 0, because it's the only thing here.
-		if(s != nil && s->type == STLSBSS && strcmp(s->name, "runtime.tlsgm") == 0) {
+		if(s != nil && s->type == STLSBSS && strcmp(s->name, "runtime.tlsg") == 0) {
 			s->value = 0;
 			s = s->next;
 		}
@@ -1001,8 +1152,8 @@ dodata(void)
 	sect->align = maxalign(s, STYPELINK-1);
 	datsize = rnd(datsize, sect->align);
 	sect->vaddr = 0;
-	linklookup(ctxt, "rodata", 0)->sect = sect;
-	linklookup(ctxt, "erodata", 0)->sect = sect;
+	linklookup(ctxt, "runtime.rodata", 0)->sect = sect;
+	linklookup(ctxt, "runtime.erodata", 0)->sect = sect;
 	for(; s != nil && s->type < STYPELINK; s = s->next) {
 		datsize = aligndatsize(datsize, s);
 		s->sect = sect;
@@ -1017,8 +1168,8 @@ dodata(void)
 	sect->align = maxalign(s, STYPELINK);
 	datsize = rnd(datsize, sect->align);
 	sect->vaddr = datsize;
-	linklookup(ctxt, "typelink", 0)->sect = sect;
-	linklookup(ctxt, "etypelink", 0)->sect = sect;
+	linklookup(ctxt, "runtime.typelink", 0)->sect = sect;
+	linklookup(ctxt, "runtime.etypelink", 0)->sect = sect;
 	for(; s != nil && s->type == STYPELINK; s = s->next) {
 		datsize = aligndatsize(datsize, s);
 		s->sect = sect;
@@ -1033,8 +1184,8 @@ dodata(void)
 	sect->align = maxalign(s, SPCLNTAB-1);
 	datsize = rnd(datsize, sect->align);
 	sect->vaddr = datsize;
-	linklookup(ctxt, "symtab", 0)->sect = sect;
-	linklookup(ctxt, "esymtab", 0)->sect = sect;
+	linklookup(ctxt, "runtime.symtab", 0)->sect = sect;
+	linklookup(ctxt, "runtime.esymtab", 0)->sect = sect;
 	for(; s != nil && s->type < SPCLNTAB; s = s->next) {
 		datsize = aligndatsize(datsize, s);
 		s->sect = sect;
@@ -1049,8 +1200,8 @@ dodata(void)
 	sect->align = maxalign(s, SELFROSECT-1);
 	datsize = rnd(datsize, sect->align);
 	sect->vaddr = datsize;
-	linklookup(ctxt, "pclntab", 0)->sect = sect;
-	linklookup(ctxt, "epclntab", 0)->sect = sect;
+	linklookup(ctxt, "runtime.pclntab", 0)->sect = sect;
+	linklookup(ctxt, "runtime.epclntab", 0)->sect = sect;
 	for(; s != nil && s->type < SELFROSECT; s = s->next) {
 		datsize = aligndatsize(datsize, s);
 		s->sect = sect;
@@ -1103,8 +1254,8 @@ textaddress(void)
 	// and then letting threads copy down, but probably not worth it.
 	sect = segtext.sect;
 	sect->align = funcalign;
-	linklookup(ctxt, "text", 0)->sect = sect;
-	linklookup(ctxt, "etext", 0)->sect = sect;
+	linklookup(ctxt, "runtime.text", 0)->sect = sect;
+	linklookup(ctxt, "runtime.etext", 0)->sect = sect;
 	va = INITTEXT;
 	sect->vaddr = va;
 	for(sym = ctxt->textp; sym != nil; sym = sym->next) {
@@ -1215,32 +1366,32 @@ address(void)
 			sub->value += sym->value;
 	}
 
-	xdefine("text", STEXT, text->vaddr);
-	xdefine("etext", STEXT, text->vaddr + text->len);
-	xdefine("rodata", SRODATA, rodata->vaddr);
-	xdefine("erodata", SRODATA, rodata->vaddr + rodata->len);
-	xdefine("typelink", SRODATA, typelink->vaddr);
-	xdefine("etypelink", SRODATA, typelink->vaddr + typelink->len);
-
-	sym = linklookup(ctxt, "gcdata", 0);
-	xdefine("egcdata", SRODATA, symaddr(sym) + sym->size);
-	linklookup(ctxt, "egcdata", 0)->sect = sym->sect;
-
-	sym = linklookup(ctxt, "gcbss", 0);
-	xdefine("egcbss", SRODATA, symaddr(sym) + sym->size);
-	linklookup(ctxt, "egcbss", 0)->sect = sym->sect;
-
-	xdefine("symtab", SRODATA, symtab->vaddr);
-	xdefine("esymtab", SRODATA, symtab->vaddr + symtab->len);
-	xdefine("pclntab", SRODATA, pclntab->vaddr);
-	xdefine("epclntab", SRODATA, pclntab->vaddr + pclntab->len);
-	xdefine("noptrdata", SNOPTRDATA, noptr->vaddr);
-	xdefine("enoptrdata", SNOPTRDATA, noptr->vaddr + noptr->len);
-	xdefine("bss", SBSS, bss->vaddr);
-	xdefine("ebss", SBSS, bss->vaddr + bss->len);
-	xdefine("data", SDATA, data->vaddr);
-	xdefine("edata", SDATA, data->vaddr + data->len);
-	xdefine("noptrbss", SNOPTRBSS, noptrbss->vaddr);
-	xdefine("enoptrbss", SNOPTRBSS, noptrbss->vaddr + noptrbss->len);
-	xdefine("end", SBSS, segdata.vaddr + segdata.len);
+	xdefine("runtime.text", STEXT, text->vaddr);
+	xdefine("runtime.etext", STEXT, text->vaddr + text->len);
+	xdefine("runtime.rodata", SRODATA, rodata->vaddr);
+	xdefine("runtime.erodata", SRODATA, rodata->vaddr + rodata->len);
+	xdefine("runtime.typelink", SRODATA, typelink->vaddr);
+	xdefine("runtime.etypelink", SRODATA, typelink->vaddr + typelink->len);
+
+	sym = linklookup(ctxt, "runtime.gcdata", 0);
+	xdefine("runtime.egcdata", SRODATA, symaddr(sym) + sym->size);
+	linklookup(ctxt, "runtime.egcdata", 0)->sect = sym->sect;
+
+	sym = linklookup(ctxt, "runtime.gcbss", 0);
+	xdefine("runtime.egcbss", SRODATA, symaddr(sym) + sym->size);
+	linklookup(ctxt, "runtime.egcbss", 0)->sect = sym->sect;
+
+	xdefine("runtime.symtab", SRODATA, symtab->vaddr);
+	xdefine("runtime.esymtab", SRODATA, symtab->vaddr + symtab->len);
+	xdefine("runtime.pclntab", SRODATA, pclntab->vaddr);
+	xdefine("runtime.epclntab", SRODATA, pclntab->vaddr + pclntab->len);
+	xdefine("runtime.noptrdata", SNOPTRDATA, noptr->vaddr);
+	xdefine("runtime.enoptrdata", SNOPTRDATA, noptr->vaddr + noptr->len);
+	xdefine("runtime.bss", SBSS, bss->vaddr);
+	xdefine("runtime.ebss", SBSS, bss->vaddr + bss->len);
+	xdefine("runtime.data", SDATA, data->vaddr);
+	xdefine("runtime.edata", SDATA, data->vaddr + data->len);
+	xdefine("runtime.noptrbss", SNOPTRBSS, noptrbss->vaddr);
+	xdefine("runtime.enoptrbss", SNOPTRBSS, noptrbss->vaddr + noptrbss->len);
+	xdefine("runtime.end", SBSS, segdata.vaddr + segdata.len);
 }
diff --git a/src/cmd/ld/decodesym.c b/src/cmd/ld/decodesym.c
index da48d37..037263d 100644
--- a/src/cmd/ld/decodesym.c
+++ b/src/cmd/ld/decodesym.c
@@ -4,10 +4,10 @@
 
 #include	"l.h"
 #include	"lib.h"
-#include	"../../pkg/runtime/typekind.h"
+#include	"../../runtime/typekind.h"
 
 // Decoding the type.* symbols.	 This has to be in sync with
-// ../../pkg/runtime/type.go, or more specificaly, with what
+// ../../runtime/type.go, or more specificaly, with what
 // ../gc/reflect.c stuffs in these.
 
 static Reloc*
@@ -70,14 +70,28 @@ decode_inuxi(uchar* p, int sz)
 static int
 commonsize(void)
 {
-	return 7*PtrSize + 8;
+	return 8*PtrSize + 8;
 }
 
 // Type.commonType.kind
 uint8
 decodetype_kind(LSym *s)
 {
-	return s->p[1*PtrSize + 7] & ~KindNoPointers;	//  0x13 / 0x1f
+	return s->p[1*PtrSize + 7] & KindMask;	//  0x13 / 0x1f
+}
+
+// Type.commonType.kind
+uint8
+decodetype_noptr(LSym *s)
+{
+	return s->p[1*PtrSize + 7] & KindNoPointers;	//  0x13 / 0x1f
+}
+
+// Type.commonType.kind
+uint8
+decodetype_usegcprog(LSym *s)
+{
+	return s->p[1*PtrSize + 7] & KindGCProg;	//  0x13 / 0x1f
 }
 
 // Type.commonType.size
@@ -89,9 +103,18 @@ decodetype_size(LSym *s)
 
 // Type.commonType.gc
 LSym*
-decodetype_gc(LSym *s)
+decodetype_gcprog(LSym *s)
 {
-	return decode_reloc_sym(s, 1*PtrSize + 8 + 1*PtrSize);
+	return decode_reloc_sym(s, 1*PtrSize + 8 + 2*PtrSize);
+}
+
+uint8*
+decodetype_gcmask(LSym *s)
+{
+	LSym *mask;
+	
+	mask = decode_reloc_sym(s, 1*PtrSize + 8 + 1*PtrSize);
+	return mask->p;
 }
 
 // Type.ArrayType.elem and Type.SliceType.Elem
@@ -104,7 +127,7 @@ decodetype_arrayelem(LSym *s)
 vlong
 decodetype_arraylen(LSym *s)
 {
-	return decode_inuxi(s->p + commonsize()+PtrSize, PtrSize);
+	return decode_inuxi(s->p + commonsize()+2*PtrSize, PtrSize);
 }
 
 // Type.PtrType.elem
@@ -120,6 +143,7 @@ decodetype_mapkey(LSym *s)
 {
 	return decode_reloc_sym(s, commonsize());	// 0x1c / 0x30
 }
+
 LSym*
 decodetype_mapvalue(LSym *s)
 {
diff --git a/src/cmd/ld/doc.go b/src/cmd/ld/doc.go
index 8135bd5..5b5833d 100644
--- a/src/cmd/ld/doc.go
+++ b/src/cmd/ld/doc.go
@@ -63,9 +63,9 @@ Options new in this version:
 	-w
 		Omit the DWARF symbol table.
 	-X symbol value
-		Set the value of an otherwise uninitialized string variable.
-		The symbol name should be of the form importpath.name,
-		as displayed in the symbol table printed by "go tool nm".
+		Set the value of a string variable. The symbol name
+		should be of the form importpath.name, as displayed
+		in the symbol table printed by "go tool nm".
 	-race
 		Link with race detection libraries.
 	-B value
diff --git a/src/cmd/ld/dwarf.c b/src/cmd/ld/dwarf.c
index cc77b45..a3ba523 100644
--- a/src/cmd/ld/dwarf.c
+++ b/src/cmd/ld/dwarf.c
@@ -19,7 +19,7 @@
 #include	"../ld/elf.h"
 #include	"../ld/macho.h"
 #include	"../ld/pe.h"
-#include	"../../pkg/runtime/typekind.h"
+#include	"../../runtime/typekind.h"
 
 /*
  * Offsets and sizes of the debug_* sections in the cout file.
@@ -141,16 +141,22 @@ sleb128put(vlong v)
  * only a handful of them.  The DWARF spec places no restriction on
  * the ordering of attributes in the Abbrevs and DIEs, and we will
  * always write them out in the order of declaration in the abbrev.
- * This implementation relies on tag, attr < 127, so they serialize as
- * a char.  Higher numbered user-defined tags or attributes can be used
- * for storing internal data but won't be serialized.
  */
 typedef struct DWAttrForm DWAttrForm;
 struct DWAttrForm {
-	uint8 attr;
+	uint16 attr;
 	uint8 form;
 };
 
+// Go-specific type attributes.
+enum {
+	DW_AT_go_kind = 0x2900,
+	DW_AT_go_key = 0x2901,
+	DW_AT_go_elem = 0x2902,
+
+	DW_AT_internal_location = 253,	 // params and locals; not emitted
+};
+
 // Index into the abbrevs table below.
 // Keep in sync with ispubname() and ispubtype() below.
 // ispubtype considers >= NULLTYPE public
@@ -260,7 +266,7 @@ static struct DWAbbrev {
 		DW_TAG_subrange_type, DW_CHILDREN_no,
 		// No name!
 		DW_AT_type,	 DW_FORM_ref_addr,
-		DW_AT_upper_bound, DW_FORM_data1,
+		DW_AT_count, DW_FORM_udata,
 		0, 0
 	},
 
@@ -277,6 +283,7 @@ static struct DWAbbrev {
 		DW_AT_name,	 DW_FORM_string,
 		DW_AT_encoding,	 DW_FORM_data1,
 		DW_AT_byte_size, DW_FORM_data1,
+		DW_AT_go_kind, DW_FORM_data1,
 		0, 0
 	},
 	/* ARRAYTYPE */
@@ -286,6 +293,7 @@ static struct DWAbbrev {
 		DW_AT_name,	DW_FORM_string,
 		DW_AT_type,	DW_FORM_ref_addr,
 		DW_AT_byte_size, DW_FORM_udata,
+		DW_AT_go_kind, DW_FORM_data1,
 		0, 0
 	},
 
@@ -294,6 +302,8 @@ static struct DWAbbrev {
 		DW_TAG_typedef, DW_CHILDREN_no,
 		DW_AT_name,	DW_FORM_string,
 		DW_AT_type,	DW_FORM_ref_addr,
+		DW_AT_go_kind, DW_FORM_data1,
+		DW_AT_go_elem, DW_FORM_ref_addr,
 		0, 0
 	},
 
@@ -302,6 +312,7 @@ static struct DWAbbrev {
 		DW_TAG_subroutine_type, DW_CHILDREN_yes,
 		DW_AT_name,	DW_FORM_string,
 //		DW_AT_type,	DW_FORM_ref_addr,
+		DW_AT_go_kind, DW_FORM_data1,
 		0, 0
 	},
 
@@ -310,6 +321,7 @@ static struct DWAbbrev {
 		DW_TAG_typedef, DW_CHILDREN_yes,
 		DW_AT_name,	 DW_FORM_string,
 		DW_AT_type,	DW_FORM_ref_addr,
+		DW_AT_go_kind, DW_FORM_data1,
 		0, 0
 	},
 
@@ -318,6 +330,9 @@ static struct DWAbbrev {
 		DW_TAG_typedef, DW_CHILDREN_no,
 		DW_AT_name,	DW_FORM_string,
 		DW_AT_type,	DW_FORM_ref_addr,
+		DW_AT_go_kind, DW_FORM_data1,
+		DW_AT_go_key, DW_FORM_ref_addr,
+		DW_AT_go_elem, DW_FORM_ref_addr,
 		0, 0
 	},
 
@@ -326,6 +341,7 @@ static struct DWAbbrev {
 		DW_TAG_pointer_type, DW_CHILDREN_no,
 		DW_AT_name,	DW_FORM_string,
 		DW_AT_type,	DW_FORM_ref_addr,
+		DW_AT_go_kind, DW_FORM_data1,
 		0, 0
 	},
 	/* BARE_PTRTYPE */
@@ -340,6 +356,8 @@ static struct DWAbbrev {
 		DW_TAG_structure_type, DW_CHILDREN_yes,
 		DW_AT_name,	DW_FORM_string,
 		DW_AT_byte_size, DW_FORM_udata,
+		DW_AT_go_kind, DW_FORM_data1,
+		DW_AT_go_elem, DW_FORM_ref_addr,
 		0, 0
 	},
 
@@ -348,6 +366,7 @@ static struct DWAbbrev {
 		DW_TAG_structure_type, DW_CHILDREN_yes,
 		DW_AT_name,	DW_FORM_string,
 		DW_AT_byte_size, DW_FORM_udata,
+		DW_AT_go_kind, DW_FORM_data1,
 		0, 0
 	},
 
@@ -356,6 +375,7 @@ static struct DWAbbrev {
 		DW_TAG_structure_type, DW_CHILDREN_yes,
 		DW_AT_name,	DW_FORM_string,
 		DW_AT_byte_size, DW_FORM_udata,
+		DW_AT_go_kind, DW_FORM_data1,
 		0, 0
 	},
 
@@ -371,7 +391,8 @@ static struct DWAbbrev {
 static void
 writeabbrev(void)
 {
-	int i, n;
+	int i, j;
+	DWAttrForm *f;
 
 	abbrevo = cpos();
 	for (i = 1; i < DW_NABRV; i++) {
@@ -379,11 +400,13 @@ writeabbrev(void)
 		uleb128put(i);
 		uleb128put(abbrevs[i].tag);
 		cput(abbrevs[i].children);
-		// 0 is not a valid attr or form, and DWAbbrev.attr is
-		// 0-terminated, so we can treat it as a string
-		n = strlen((char*)abbrevs[i].attr) / 2;
-		strnput((char*)abbrevs[i].attr,
-			(n+1) * sizeof(DWAttrForm));
+		for(j=0; j<nelem(abbrevs[i].attr); j++) {
+			f = &abbrevs[i].attr[j];
+			uleb128put(f->attr);
+			uleb128put(f->form);
+			if(f->attr == 0)
+				break;
+		}
 	}
 	cput(0);
 	abbrevsize = cpos() - abbrevo;
@@ -417,7 +440,7 @@ hashstr(char* s)
 typedef struct DWAttr DWAttr;
 struct DWAttr {
 	DWAttr *link;
-	uint8 atr;  // DW_AT_
+	uint16 atr;  // DW_AT_
 	uint8 cls;  // DW_CLS_
 	vlong value;
 	char *data;
@@ -445,7 +468,7 @@ static DWDie dwtypes;
 static DWDie dwglobals;
 
 static DWAttr*
-newattr(DWDie *die, uint8 attr, int cls, vlong value, char *data)
+newattr(DWDie *die, uint16 attr, int cls, vlong value, char *data)
 {
 	DWAttr *a;
 
@@ -463,7 +486,7 @@ newattr(DWDie *die, uint8 attr, int cls, vlong value, char *data)
 // name. getattr moves the desired one to the front so
 // frequently searched ones are found faster.
 static DWAttr*
-getattr(DWDie *die, uint8 attr)
+getattr(DWDie *die, uint16 attr)
 {
 	DWAttr *a, *b;
 
@@ -622,7 +645,7 @@ adddwarfrel(LSym* sec, LSym* sym, vlong offsetbase, int siz, vlong addend)
 }
 
 static DWAttr*
-newrefattr(DWDie *die, uint8 attr, DWDie* ref)
+newrefattr(DWDie *die, uint16 attr, DWDie* ref)
 {
 	if (ref == nil)
 		return nil;
@@ -762,22 +785,22 @@ putattr(int abbrev, int form, int cls, vlong value, char *data)
 static void
 putattrs(int abbrev, DWAttr* attr)
 {
-	DWAttr *attrs[DW_AT_recursive + 1];
 	DWAttrForm* af;
-
-	memset(attrs, 0, sizeof attrs);
-	for( ; attr; attr = attr->link)
-		if (attr->atr < nelem(attrs))
-			attrs[attr->atr] = attr;
-
-	for(af = abbrevs[abbrev].attr; af->attr; af++)
-		if (attrs[af->attr])
-			putattr(abbrev, af->form,
-				attrs[af->attr]->cls,
-				attrs[af->attr]->value,
-				attrs[af->attr]->data);
-		else
-			putattr(abbrev, af->form, 0, 0, nil);
+	DWAttr *ap;
+
+	for(af = abbrevs[abbrev].attr; af->attr; af++) {
+		for(ap=attr; ap; ap=ap->link) {
+			if(ap->atr == af->attr) {
+				putattr(abbrev, af->form,
+					ap->cls,
+					ap->value,
+					ap->data);
+				goto done;
+			}
+		}
+		putattr(abbrev, af->form, 0, 0, nil);
+	done:;
+	}
 }
 
 static void putdie(DWDie* die);
@@ -835,11 +858,8 @@ newmemberoffsetattr(DWDie *die, int32 offs)
 	int i;
 
 	i = 0;
-	if (offs != 0) {
-		block[i++] = DW_OP_consts;
-		i += sleb128enc(offs, block+i);
-		block[i++] = DW_OP_plus;
-	}
+	block[i++] = DW_OP_plus_uconst;
+	i += uleb128enc(offs, block+i);
 	newattr(die, DW_AT_data_member_location, DW_CLS_BLOCK, i, mal(i));
 	memmove(die->attr->data, block, i);
 }
@@ -852,15 +872,6 @@ newabslocexprattr(DWDie *die, vlong addr, LSym *sym)
 	newattr(die, DW_AT_location, DW_CLS_ADDRESS, addr, (char*)sym);
 }
 
-
-// Fake attributes for slices, maps and channel
-enum {
-	DW_AT_internal_elem_type = 250,	 // channels and slices
-	DW_AT_internal_key_type = 251,	 // maps
-	DW_AT_internal_val_type = 252,	 // maps
-	DW_AT_internal_location = 253,	 // params and locals
-};
-
 static DWDie* defptrto(DWDie *dwtype);	// below
 
 // Lookup predefined types
@@ -981,7 +992,8 @@ defgotype(LSym *gotype)
 		s = decodetype_arrayelem(gotype);
 		newrefattr(die, DW_AT_type, defgotype(s));
 		fld = newdie(die, DW_ABRV_ARRAYRANGE, "range");
-		newattr(fld, DW_AT_upper_bound, DW_CLS_CONSTANT, decodetype_arraylen(gotype), 0);
+		// use actual length not upper bound; correct for 0-length arrays.
+		newattr(fld, DW_AT_count, DW_CLS_CONSTANT, decodetype_arraylen(gotype), 0);
 		newrefattr(fld, DW_AT_type, find_or_diag(&dwtypes, "uintptr"));
 		break;
 
@@ -989,7 +1001,7 @@ defgotype(LSym *gotype)
 		die = newdie(&dwtypes, DW_ABRV_CHANTYPE, name);
 		newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0);
 		s = decodetype_chanelem(gotype);
-		newrefattr(die, DW_AT_internal_elem_type, defgotype(s));
+		newrefattr(die, DW_AT_go_elem, defgotype(s));
 		break;
 
 	case KindFunc:
@@ -1027,9 +1039,9 @@ defgotype(LSym *gotype)
 	case KindMap:
 		die = newdie(&dwtypes, DW_ABRV_MAPTYPE, name);
 		s = decodetype_mapkey(gotype);
-		newrefattr(die, DW_AT_internal_key_type, defgotype(s));
+		newrefattr(die, DW_AT_go_key, defgotype(s));
 		s = decodetype_mapvalue(gotype);
-		newrefattr(die, DW_AT_internal_val_type, defgotype(s));
+		newrefattr(die, DW_AT_go_elem, defgotype(s));
 		break;
 
 	case KindPtr:
@@ -1044,7 +1056,7 @@ defgotype(LSym *gotype)
 		dotypedef(&dwtypes, name, die);
 		newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, bytesize, 0);
 		s = decodetype_arrayelem(gotype);
-		newrefattr(die, DW_AT_internal_elem_type, defgotype(s));
+		newrefattr(die, DW_AT_go_elem, defgotype(s));
 		break;
 
 	case KindString:
@@ -1076,7 +1088,9 @@ defgotype(LSym *gotype)
 		diag("dwarf: definition of unknown kind %d: %s", kind, gotype->name);
 		die = newdie(&dwtypes, DW_ABRV_TYPEDECL, name);
 		newrefattr(die, DW_AT_type, find_or_diag(&dwtypes, "<unspecified>"));
-	 }
+	}
+
+	newattr(die, DW_AT_go_kind, DW_CLS_CONSTANT, kind, 0);
 
 	return die;
 }
@@ -1171,7 +1185,7 @@ synthesizeslicetypes(DWDie *die)
 		if (die->abbrev != DW_ABRV_SLICETYPE)
 			continue;
 		copychildren(die, prototype);
-		elem = (DWDie*) getattr(die, DW_AT_internal_elem_type)->data;
+		elem = (DWDie*) getattr(die, DW_AT_go_elem)->data;
 		substitutetype(die, "array", defptrto(elem));
 	}
 }
@@ -1208,7 +1222,7 @@ synthesizemaptypes(DWDie *die)
 	DWAttr *a;
 
 	hash		= walktypedef(defgotype(lookup_or_diag("type.runtime.hmap")));
-	bucket		= walktypedef(defgotype(lookup_or_diag("type.runtime.bucket")));
+	bucket		= walktypedef(defgotype(lookup_or_diag("type.runtime.bmap")));
 
 	if (hash == nil)
 		return;
@@ -1217,8 +1231,8 @@ synthesizemaptypes(DWDie *die)
 		if (die->abbrev != DW_ABRV_MAPTYPE)
 			continue;
 
-		keytype = walktypedef((DWDie*) getattr(die, DW_AT_internal_key_type)->data);
-		valtype = walktypedef((DWDie*) getattr(die, DW_AT_internal_val_type)->data);
+		keytype = walktypedef((DWDie*) getattr(die, DW_AT_go_key)->data);
+		valtype = walktypedef((DWDie*) getattr(die, DW_AT_go_elem)->data);
 
 		// compute size info like hashmap.c does.
 		a = getattr(keytype, DW_AT_byte_size);
@@ -1243,7 +1257,7 @@ synthesizemaptypes(DWDie *die)
 		newattr(dwhk, DW_AT_byte_size, DW_CLS_CONSTANT, BucketSize * keysize, 0);
 		newrefattr(dwhk, DW_AT_type, indirect_key ? defptrto(keytype) : keytype);
 		fld = newdie(dwhk, DW_ABRV_ARRAYRANGE, "size");
-		newattr(fld, DW_AT_upper_bound, DW_CLS_CONSTANT, BucketSize, 0);
+		newattr(fld, DW_AT_count, DW_CLS_CONSTANT, BucketSize, 0);
 		newrefattr(fld, DW_AT_type, find_or_diag(&dwtypes, "uintptr"));
 		
 		// Construct type to represent an array of BucketSize values
@@ -1253,7 +1267,7 @@ synthesizemaptypes(DWDie *die)
 		newattr(dwhv, DW_AT_byte_size, DW_CLS_CONSTANT, BucketSize * valsize, 0);
 		newrefattr(dwhv, DW_AT_type, indirect_val ? defptrto(valtype) : valtype);
 		fld = newdie(dwhv, DW_ABRV_ARRAYRANGE, "size");
-		newattr(fld, DW_AT_upper_bound, DW_CLS_CONSTANT, BucketSize, 0);
+		newattr(fld, DW_AT_count, DW_CLS_CONSTANT, BucketSize, 0);
 		newrefattr(fld, DW_AT_type, find_or_diag(&dwtypes, "uintptr"));
 
 		// Construct bucket<K,V>
@@ -1309,7 +1323,7 @@ synthesizechantypes(DWDie *die)
 	for (; die != nil; die = die->link) {
 		if (die->abbrev != DW_ABRV_CHANTYPE)
 			continue;
-		elemtype = (DWDie*) getattr(die, DW_AT_internal_elem_type)->data;
+		elemtype = (DWDie*) getattr(die, DW_AT_go_elem)->data;
 		a = getattr(elemtype, DW_AT_byte_size);
 		elemsize = a ? a->value : PtrSize;
 
@@ -1696,6 +1710,9 @@ enum
 static void
 putpccfadelta(vlong deltapc, vlong cfa)
 {
+	cput(DW_CFA_def_cfa_offset_sf);
+	sleb128put(cfa / DATAALIGNMENTFACTOR);
+
 	if (deltapc < 0x40) {
 		cput(DW_CFA_advance_loc + deltapc);
 	} else if (deltapc < 0x100) {
@@ -1708,9 +1725,6 @@ putpccfadelta(vlong deltapc, vlong cfa)
 		cput(DW_CFA_advance_loc4);
 		LPUT(deltapc);
 	}
-
-	cput(DW_CFA_def_cfa_offset_sf);
-	sleb128put(cfa / DATAALIGNMENTFACTOR);
 }
 
 static void
@@ -1719,6 +1733,7 @@ writeframes(void)
 	LSym *s;
 	vlong fdeo, fdesize, pad;
 	Pciter pcsp;
+	uint32 nextpc;
 
 	if(framesec == S)
 		framesec = linklookup(ctxt, ".dwarfframe", 0);
@@ -1761,8 +1776,17 @@ writeframes(void)
 		addrput(0);	// initial location
 		addrput(0);	// address range
 
-		for(pciterinit(ctxt, &pcsp, &s->pcln->pcsp); !pcsp.done; pciternext(&pcsp))
-			putpccfadelta(pcsp.nextpc - pcsp.pc, PtrSize + pcsp.value);
+		for(pciterinit(ctxt, &pcsp, &s->pcln->pcsp); !pcsp.done; pciternext(&pcsp)) {
+			nextpc = pcsp.nextpc;
+			// pciterinit goes up to the end of the function,
+			// but DWARF expects us to stop just before the end.
+			if(nextpc == s->size) {
+				nextpc--;
+				if(nextpc < pcsp.pc)
+					continue;
+			}
+			putpccfadelta(nextpc - pcsp.pc, PtrSize + pcsp.value);
+		}
 
 		fdesize = cpos() - fdeo - 4;	// exclude the length field.
 		pad = rnd(fdesize, PtrSize) - fdesize;
@@ -2028,13 +2052,15 @@ dwarfemitdebugsections(void)
 	newdie(&dwtypes, DW_ABRV_NULLTYPE, "<unspecified>");
 	newdie(&dwtypes, DW_ABRV_NULLTYPE, "void");
 	newdie(&dwtypes, DW_ABRV_BARE_PTRTYPE, "unsafe.Pointer");
+
 	die = newdie(&dwtypes, DW_ABRV_BASETYPE, "uintptr");  // needed for array size
 	newattr(die, DW_AT_encoding,  DW_CLS_CONSTANT, DW_ATE_unsigned, 0);
 	newattr(die, DW_AT_byte_size, DW_CLS_CONSTANT, PtrSize, 0);
+	newattr(die, DW_AT_go_kind, DW_CLS_CONSTANT, KindUintptr, 0);
 
 	// Needed by the prettyprinter code for interface inspection.
-	defgotype(lookup_or_diag("type.runtime.rtype"));
-	defgotype(lookup_or_diag("type.runtime.interfaceType"));
+	defgotype(lookup_or_diag("type.runtime._type"));
+	defgotype(lookup_or_diag("type.runtime.interfacetype"));
 	defgotype(lookup_or_diag("type.runtime.itab"));
 
 	genasmsym(defdwsymb);
diff --git a/src/cmd/ld/elf.c b/src/cmd/ld/elf.c
index 0555cf4..3196961 100644
--- a/src/cmd/ld/elf.c
+++ b/src/cmd/ld/elf.c
@@ -776,7 +776,8 @@ elfshbits(Section *sect)
 	if(sect->rwx & 2)
 		sh->flags |= SHF_WRITE;
 	if(strcmp(sect->name, ".tbss") == 0) {
-		sh->flags |= SHF_TLS;
+		if(strcmp(goos, "android") != 0)
+			sh->flags |= SHF_TLS; // no TLS on android
 		sh->type = SHT_NOBITS;
 	}
 	if(linkmode != LinkExternal)
diff --git a/src/cmd/ld/ldelf.c b/src/cmd/ld/ldelf.c
index 1d7c4c1..b5d0819 100644
--- a/src/cmd/ld/ldelf.c
+++ b/src/cmd/ld/ldelf.c
@@ -539,7 +539,7 @@ ldelf(Biobuf *f, char *pkg, int64 len, char *pn)
 			s->type = SRODATA;
 			break;
 		case ElfSectFlagAlloc + ElfSectFlagWrite:
-			s->type = SDATA;
+			s->type = SNOPTRDATA;
 			break;
 		case ElfSectFlagAlloc + ElfSectFlagExec:
 			s->type = STEXT;
@@ -572,7 +572,7 @@ ldelf(Biobuf *f, char *pkg, int64 len, char *pn)
 			if(s->size < sym.size)
 				s->size = sym.size;
 			if(s->type == 0 || s->type == SXREF)
-				s->type = SBSS;
+				s->type = SNOPTRBSS;
 			continue;
 		}
 		if(sym.shndx >= obj->nsect || sym.shndx == 0)
@@ -582,6 +582,8 @@ ldelf(Biobuf *f, char *pkg, int64 len, char *pn)
 			continue;
 		sect = obj->sect+sym.shndx;
 		if(sect->sym == nil) {
+			if(strncmp(sym.name, ".Linfo_string", 13) == 0) // clang does this
+				continue;
 			diag("%s: sym#%d: ignoring %s in section %d (type %d)", pn, i, sym.name, sym.shndx, sym.type);
 			continue;
 		}
@@ -817,7 +819,7 @@ readsym(ElfObj *obj, int i, ElfSym *sym, int needSym)
 			}
 			break;
 		case ElfSymBindLocal:
-			if(!(thechar == '5' && (strcmp(sym->name, "$a") == 0 || strcmp(sym->name, "$d") == 0))) // binutils for arm generate these mapping symbols, ignore these
+			if(!(thechar == '5' && (strncmp(sym->name, "$a", 2) == 0 || strncmp(sym->name, "$d", 2) == 0))) // binutils for arm generate these mapping symbols, ignore these
 				if(needSym) {
 					// local names and hidden visiblity global names are unique
 					// and should only reference by its index, not name, so we
diff --git a/src/cmd/ld/ldmacho.c b/src/cmd/ld/ldmacho.c
index 413deda..71cfa63 100644
--- a/src/cmd/ld/ldmacho.c
+++ b/src/cmd/ld/ldmacho.c
@@ -589,10 +589,10 @@ ldmacho(Biobuf *f, char *pkg, int64 len, char *pn)
 				s->type = SRODATA;
 		} else {
 			if (strcmp(sect->name, "__bss") == 0) {
-				s->type = SBSS;
+				s->type = SNOPTRBSS;
 				s->np = 0;
 			} else
-				s->type = SDATA;
+				s->type = SNOPTRDATA;
 		}
 		sect->sym = s;
 	}
diff --git a/src/cmd/ld/ldpe.c b/src/cmd/ld/ldpe.c
index f6eda90..4f5e51f 100644
--- a/src/cmd/ld/ldpe.c
+++ b/src/cmd/ld/ldpe.c
@@ -128,6 +128,7 @@ struct PeObj {
 };
 
 static int map(PeObj *obj, PeSect *sect);
+static int issect(PeSym *s);
 static int readsym(PeObj *obj, int i, PeSym **sym);
 
 void
@@ -179,6 +180,15 @@ ldpe(Biobuf *f, char *pkg, int64 len, char *pn)
 	Bseek(f, base+obj->fh.PointerToSymbolTable+sizeof(symbuf)*obj->fh.NumberOfSymbols, 0);
 	if(Bread(f, obj->snames, l) != l)
 		goto bad;
+	// rewrite section names if they start with /
+	for(i=0; i < obj->fh.NumberOfSections; i++) {
+		if(obj->sect[i].name == nil)
+			continue;
+		if(obj->sect[i].name[0] != '/')
+			continue;
+		l = atoi(obj->sect[i].name + 1);
+		obj->sect[i].name = (char*)&obj->snames[l];
+	}
 	// read symbols
 	obj->pesym = mal(obj->fh.NumberOfSymbols*sizeof obj->pesym[0]);
 	obj->npesym = obj->fh.NumberOfSymbols;
@@ -230,10 +240,10 @@ ldpe(Biobuf *f, char *pkg, int64 len, char *pn)
 				s->type = SRODATA;
 				break;
 			case IMAGE_SCN_CNT_UNINITIALIZED_DATA|IMAGE_SCN_MEM_READ|IMAGE_SCN_MEM_WRITE: //.bss
-				s->type = SBSS;
+				s->type = SNOPTRBSS;
 				break;
 			case IMAGE_SCN_CNT_INITIALIZED_DATA|IMAGE_SCN_MEM_READ|IMAGE_SCN_MEM_WRITE: //.data
-				s->type = SDATA;
+				s->type = SNOPTRDATA;
 				break;
 			case IMAGE_SCN_CNT_CODE|IMAGE_SCN_MEM_EXECUTE|IMAGE_SCN_MEM_READ: //.text
 				s->type = STEXT;
@@ -309,8 +319,8 @@ ldpe(Biobuf *f, char *pkg, int64 len, char *pn)
 			// ld -r could generate multiple section symbols for the
 			// same section but with different values, we have to take
 			// that into account
-			if (obj->pesym[symindex].name[0] == '.')
-					rp->add += obj->pesym[symindex].value;
+			if(issect(&obj->pesym[symindex]))
+				rp->add += obj->pesym[symindex].value;
 		}
 		qsort(r, rsect->sh.NumberOfRelocations, sizeof r[0], rbyoff);
 		
@@ -318,12 +328,12 @@ ldpe(Biobuf *f, char *pkg, int64 len, char *pn)
 		s->r = r;
 		s->nr = rsect->sh.NumberOfRelocations;
 	}
-	
+
 	// enter sub-symbols into symbol table.
 	for(i=0; i<obj->npesym; i++) {
 		if(obj->pesym[i].name == 0)
 			continue;
-		if(obj->pesym[i].name[0] == '.') //skip section
+		if(issect(&obj->pesym[i]))
 			continue;
 		if(obj->pesym[i].sectnum > 0) {
 			sect = &obj->sect[obj->pesym[i].sectnum-1];
@@ -338,7 +348,7 @@ ldpe(Biobuf *f, char *pkg, int64 len, char *pn)
 			if(s->type == SDYNIMPORT)
 				s->plt = -2; // flag for dynimport in PE object files.
 			if (s->type == SXREF && sym->value > 0) {// global data
-				s->type = SDATA; 
+				s->type = SNOPTRDATA;
 				s->size = sym->value;
 			}
 			continue;
@@ -422,6 +432,12 @@ map(PeObj *obj, PeSect *sect)
 }
 
 static int
+issect(PeSym *s)
+{
+	return s->sclass == IMAGE_SYM_CLASS_STATIC && s->type == 0 && s->name[0] == '.';
+}
+
+static int
 readsym(PeObj *obj, int i, PeSym **y)
 {
 	LSym *s;
@@ -436,7 +452,7 @@ readsym(PeObj *obj, int i, PeSym **y)
 	sym = &obj->pesym[i];
 	*y = sym;
 	
-	if(sym->name[0] == '.') // .section
+	if(issect(sym))
 		name = obj->sect[sym->sectnum-1].sym->name;
 	else {
 		name = sym->name;
diff --git a/src/cmd/ld/lib.c b/src/cmd/ld/lib.c
index da6194e..f889aba 100644
--- a/src/cmd/ld/lib.c
+++ b/src/cmd/ld/lib.c
@@ -33,8 +33,8 @@
 #include	"lib.h"
 #include	"../ld/elf.h"
 #include	"../ld/dwarf.h"
-#include	"../../pkg/runtime/stack.h"
-#include	"../../pkg/runtime/funcdata.h"
+#include	"../../runtime/stack.h"
+#include	"../../runtime/funcdata.h"
 
 #include	<ar.h>
 #if !(defined(_WIN32) || defined(PLAN9))
@@ -144,6 +144,10 @@ libinit(void)
 void
 errorexit(void)
 {
+	if(cout >= 0) {
+		// For rmtemp run at atexit time on Windows.
+		close(cout);
+	}
 	if(nerrors) {
 		if(cout >= 0)
 			mayberemoveoutfile();
@@ -177,7 +181,7 @@ void
 loadlib(void)
 {
 	int i, w, x;
-	LSym *s, *gmsym;
+	LSym *s, *tlsg;
 	char* cgostrsym;
 
 	if(flag_shared) {
@@ -217,8 +221,12 @@ loadlib(void)
 		// Provided by the code that imports the package.
 		// Since we are simulating the import, we have to provide this string.
 		cgostrsym = "go.string.\"runtime/cgo\"";
-		if(linkrlookup(ctxt, cgostrsym, 0) == nil)
+		if(linkrlookup(ctxt, cgostrsym, 0) == nil) {
+			s = linklookup(ctxt, cgostrsym, 0);
+			s->type = SRODATA;
+			s->reachable = 1;
 			addstrdata(cgostrsym, "runtime/cgo");
+		}
 	}
 
 	if(linkmode == LinkAuto) {
@@ -226,6 +234,10 @@ loadlib(void)
 			linkmode = LinkExternal;
 		else
 			linkmode = LinkInternal;
+
+		// Force external linking for android.
+		if(strcmp(goos, "android") == 0)
+			linkmode = LinkExternal;
 	}
 
 	if(linkmode == LinkInternal) {
@@ -244,12 +256,12 @@ loadlib(void)
 			}
 	}
 	
-	gmsym = linklookup(ctxt, "runtime.tlsgm", 0);
-	gmsym->type = STLSBSS;
-	gmsym->size = 2*PtrSize;
-	gmsym->hide = 1;
-	gmsym->reachable = 1;
-	ctxt->gmsym = gmsym;
+	tlsg = linklookup(ctxt, "runtime.tlsg", 0);
+	tlsg->type = STLSBSS;
+	tlsg->size = PtrSize;
+	tlsg->hide = 1;
+	tlsg->reachable = 1;
+	ctxt->tlsg = tlsg;
 
 	// Now that we know the link mode, trim the dynexp list.
 	x = CgoExportDynamic;
@@ -895,7 +907,7 @@ unmal(void *v, uint32 n)
  * escaping are %, ., and ", but we escape all control characters too.
  *
  * If you edit this, edit ../gc/subr.c:/^pathtoprefix too.
- * If you edit this, edit ../../pkg/debug/goobj/read.go:/importPathToPrefix too.
+ * If you edit this, edit ../../debug/goobj/read.go:/importPathToPrefix too.
  */
 static char*
 pathtoprefix(char *s)
@@ -1345,10 +1357,10 @@ genasmsym(void (*put)(LSym*, char*, int, vlong, vlong, int, LSym*))
 
 	// These symbols won't show up in the first loop below because we
 	// skip STEXT symbols. Normal STEXT symbols are emitted by walking textp.
-	s = linklookup(ctxt, "text", 0);
+	s = linklookup(ctxt, "runtime.text", 0);
 	if(s->type == STEXT)
 		put(s, s->name, 'T', s->value, s->size, s->version, 0);
-	s = linklookup(ctxt, "etext", 0);
+	s = linklookup(ctxt, "runtime.etext", 0);
 	if(s->type == STEXT)
 		put(s, s->name, 'T', s->value, s->size, s->version, 0);
 
@@ -1550,3 +1562,56 @@ diag(char *fmt, ...)
 		errorexit();
 	}
 }
+
+void
+checkgo(void)
+{
+	LSym *s;
+	Reloc *r;
+	int i;
+	int changed;
+	
+	if(!debug['C'])
+		return;
+	
+	// TODO(rsc,khr): Eventually we want to get to no Go-called C functions at all,
+	// which would simplify this logic quite a bit.
+
+	// Mark every Go-called C function with cfunc=2, recursively.
+	do {
+		changed = 0;
+		for(s = ctxt->textp; s != nil; s = s->next) {
+			if(s->cfunc == 0 || (s->cfunc == 2 && s->nosplit)) {
+				for(i=0; i<s->nr; i++) {
+					r = &s->r[i];
+					if(r->sym == nil)
+						continue;
+					if((r->type == R_CALL || r->type == R_CALLARM) && r->sym->type == STEXT) {
+						if(r->sym->cfunc == 1) {
+							changed = 1;
+							r->sym->cfunc = 2;
+						}
+					}
+				}
+			}
+		}
+	}while(changed);
+
+	// Complain about Go-called C functions that can split the stack
+	// (that can be preempted for garbage collection or trigger a stack copy).
+	for(s = ctxt->textp; s != nil; s = s->next) {
+		if(s->cfunc == 0 || (s->cfunc == 2 && s->nosplit)) {
+			for(i=0; i<s->nr; i++) {
+				r = &s->r[i];
+				if(r->sym == nil)
+					continue;
+				if((r->type == R_CALL || r->type == R_CALLARM) && r->sym->type == STEXT) {
+					if(s->cfunc == 0 && r->sym->cfunc == 2 && !r->sym->nosplit)
+						print("Go %s calls C %s\n", s->name, r->sym->name);
+					else if(s->cfunc == 2 && s->nosplit && !r->sym->nosplit)
+						print("Go calls C %s calls %s\n", s->name, r->sym->name);
+				}
+			}
+		}
+	}
+}
diff --git a/src/cmd/ld/lib.h b/src/cmd/ld/lib.h
index 7267c63..067ffa0 100644
--- a/src/cmd/ld/lib.h
+++ b/src/cmd/ld/lib.h
@@ -33,6 +33,10 @@
 // A section further describes the pieces of that block for
 // use in debuggers and such.
 
+enum {
+	MAXIO		= 8192,
+};
+
 typedef struct Segment Segment;
 typedef struct Section Section;
 
@@ -179,12 +183,13 @@ uint16	be16(uchar *b);
 uint32	be32(uchar *b);
 uint64	be64(uchar *b);
 void	callgraph(void);
+void	checkgo(void);
 void	cflush(void);
-void	codeblk(int32 addr, int32 size);
+void	codeblk(int64 addr, int64 size);
 vlong	cpos(void);
 void	cseek(vlong p);
 void	cwrite(void *buf, int n);
-void	datblk(int32 addr, int32 size);
+void	datblk(int64 addr, int64 size);
 int	datcmp(LSym *s1, LSym *s2);
 vlong	datoff(vlong addr);
 void	deadcode(void);
@@ -196,9 +201,12 @@ int	decodetype_funcincount(LSym *s);
 LSym*	decodetype_funcintype(LSym *s, int i);
 int	decodetype_funcoutcount(LSym *s);
 LSym*	decodetype_funcouttype(LSym *s, int i);
-LSym*	decodetype_gc(LSym *s);
+LSym*	decodetype_gcprog(LSym *s);
+uint8*	decodetype_gcmask(LSym *s);
 vlong	decodetype_ifacemethodcount(LSym *s);
 uint8	decodetype_kind(LSym *s);
+uint8	decodetype_noptr(LSym *s);
+uint8	decodetype_usegcprog(LSym *s);
 LSym*	decodetype_mapkey(LSym *s);
 LSym*	decodetype_mapvalue(LSym *s);
 LSym*	decodetype_ptrelem(LSym *s);
diff --git a/src/cmd/ld/macho.c b/src/cmd/ld/macho.c
index 61306bb..fe7e10e 100644
--- a/src/cmd/ld/macho.c
+++ b/src/cmd/ld/macho.c
@@ -590,8 +590,7 @@ machosymtab(void)
 		if(strstr(s->extname, "·") == nil) {
 			addstring(symstr, s->extname);
 		} else {
-			p = s->extname;
-			while (*p++ != '\0') {
+			for(p = s->extname; *p; p++) {
 				if((uchar)*p == 0xc2 && (uchar)*(p+1) == 0xb7) {
 					adduint8(ctxt, symstr, '.');
 					p++;
diff --git a/src/cmd/ld/pass.c b/src/cmd/ld/pass.c
deleted file mode 100644
index 788b7c7..0000000
--- a/src/cmd/ld/pass.c
+++ /dev/null
@@ -1,104 +0,0 @@
-// Inferno utils/6l/pass.c
-// http://code.google.com/p/inferno-os/source/browse/utils/6l/pass.c
-//
-//	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//	Portions Copyright © 1995-1997 C H Forsyth (forsyth at terzarima.net)
-//	Portions Copyright © 1997-1999 Vita Nuova Limited
-//	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
-//	Portions Copyright © 2004,2006 Bruce Ellis
-//	Portions Copyright © 2005-2007 C H Forsyth (forsyth at terzarima.net)
-//	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
-//	Portions Copyright © 2009 The Go Authors.  All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-// Code and data passes.
-
-#include	"l.h"
-#include	"../ld/lib.h"
-#include "../../pkg/runtime/stack.h"
-
-void
-follow(void)
-{
-	LSym *s;
-
-	if(debug['v'])
-		Bprint(&bso, "%5.2f follow\n", cputime());
-	Bflush(&bso);
-	
-	for(s = ctxt->textp; s != nil; s = s->next)
-		ctxt->arch->follow(ctxt, s);
-}
-
-void
-patch(void)
-{
-	LSym *s;
-
-	if(debug['v'])
-		Bprint(&bso, "%5.2f mkfwd\n", cputime());
-	Bflush(&bso);
-	for(s = ctxt->textp; s != nil; s = s->next)
-		mkfwd(s);
-	if(debug['v'])
-		Bprint(&bso, "%5.2f patch\n", cputime());
-	Bflush(&bso);
-
-	if(flag_shared) {
-		s = linklookup(ctxt, "init_array", 0);
-		s->type = SINITARR;
-		s->reachable = 1;
-		s->hide = 1;
-		addaddr(ctxt, s, linklookup(ctxt, INITENTRY, 0));
-	}
-	
-	for(s = ctxt->textp; s != nil; s = s->next)
-		linkpatch(ctxt, s);
-}
-
-void
-dostkoff(void)
-{
-	LSym *s;
-
-	for(s = ctxt->textp; s != nil; s = s->next)
-		ctxt->arch->addstacksplit(ctxt, s);
-}
-
-void
-span(void)
-{
-	LSym *s;
-
-	if(debug['v'])
-		Bprint(&bso, "%5.2f span\n", cputime());
-
-	for(s = ctxt->textp; s != nil; s = s->next)
-		ctxt->arch->assemble(ctxt, s);
-}
-
-void
-pcln(void)
-{
-	LSym *s;
-
-	for(s = ctxt->textp; s != nil; s = s->next)
-		linkpcln(ctxt, s);
-}
diff --git a/src/cmd/ld/pcln.c b/src/cmd/ld/pcln.c
index 4c2ffa7..69671c0 100644
--- a/src/cmd/ld/pcln.c
+++ b/src/cmd/ld/pcln.c
@@ -4,7 +4,7 @@
 
 #include	"l.h"
 #include	"lib.h"
-#include	"../../pkg/runtime/funcdata.h"
+#include	"../../runtime/funcdata.h"
 
 static void
 addvarint(Pcdata *d, uint32 val)
@@ -90,7 +90,7 @@ renumberfiles(Link *ctxt, LSym **files, int nfiles, Pcdata *d)
 		}
 		dv = val - newval;
 		newval = val;
-		v = (uint32)(dv<<1) ^ (uint32)(int32)(dv>>31);
+		v = ((uint32)dv<<1) ^ (uint32)(int32)(dv>>31);
 		addvarint(&out, v);
 
 		// pc delta
@@ -119,7 +119,7 @@ pclntab(void)
 	static Pcln zpcln;
 	
 	funcdata_bytes = 0;
-	ftab = linklookup(ctxt, "pclntab", 0);
+	ftab = linklookup(ctxt, "runtime.pclntab", 0);
 	ftab->type = SPCLNTAB;
 	ftab->reachable = 1;
 
diff --git a/src/cmd/ld/pobj.c b/src/cmd/ld/pobj.c
index 819c379..63460df 100644
--- a/src/cmd/ld/pobj.c
+++ b/src/cmd/ld/pobj.c
@@ -45,6 +45,8 @@ char*	paramspace	= "FP";
 void
 main(int argc, char *argv[])
 {
+	int i;
+
 	linkarchinit();
 	ctxt = linknew(thelinkarch);
 	ctxt->thechar = thechar;
@@ -63,7 +65,13 @@ main(int argc, char *argv[])
 	INITRND = -1;
 	INITENTRY = 0;
 	linkmode = LinkAuto;
-	nuxiinit();
+	
+	// For testing behavior of go command when tools crash.
+	// Undocumented, not in standard flag parser to avoid
+	// exposing in usage message.
+	for(i=1; i<argc; i++)
+		if(strcmp(argv[i], "-crash_for_testing") == 0)
+			*(volatile int*)0 = 0;
 	
 	if(thechar == '5' && ctxt->goarm == 5)
 		debug['F'] = 1;
@@ -72,6 +80,7 @@ main(int argc, char *argv[])
 	if(thechar == '6')
 		flagcount("8", "assume 64-bit addresses", &debug['8']);
 	flagfn1("B", "info: define ELF NT_GNU_BUILD_ID note", addbuildinfo);
+	flagcount("C", "check Go calls to C code", &debug['C']);
 	flagint64("D", "addr: data address", &INITDAT);
 	flagstr("E", "sym: entry symbol", &INITENTRY);
 	if(thechar == '5')
@@ -96,11 +105,11 @@ main(int argc, char *argv[])
 	flagcount("a", "disassemble output", &debug['a']);
 	flagcount("c", "dump call graph", &debug['c']);
 	flagcount("d", "disable dynamic executable", &debug['d']);
-	flagstr("extld", "linker to run in external mode", &extld);
-	flagstr("extldflags", "flags for external linker", &extldflags);
+	flagstr("extld", "ld: linker to run in external mode", &extld);
+	flagstr("extldflags", "ldflags: flags for external linker", &extldflags);
 	flagcount("f", "ignore version mismatch", &debug['f']);
 	flagcount("g", "disable go package data checks", &debug['g']);
-	flagstr("installsuffix", "pkg directory suffix", &flag_installsuffix);
+	flagstr("installsuffix", "suffix: pkg directory suffix", &flag_installsuffix);
 	flagstr("k", "sym: set field tracking symbol", &tracksym);
 	flagfn1("linkmode", "mode: set link mode (internal, external, auto)", setlinkmode);
 	flagcount("n", "dump symbol table", &debug['n']);
@@ -110,7 +119,7 @@ main(int argc, char *argv[])
 	flagcount("s", "disable symbol table", &debug['s']);
 	if(thechar == '5' || thechar == '6')
 		flagcount("shared", "generate shared object (implies -linkmode external)", &flag_shared);
-	flagstr("tmpdir", "leave temporary files in this directory", &tmpdir);
+	flagstr("tmpdir", "dir: leave temporary files in this directory", &tmpdir);
 	flagcount("u", "reject unsafe packages", &debug['u']);
 	flagcount("v", "print link trace", &debug['v']);
 	flagcount("w", "disable DWARF generation", &debug['w']);
@@ -139,7 +148,7 @@ main(int argc, char *argv[])
 	if(HEADTYPE == -1)
 		HEADTYPE = headtype(goos);
 	ctxt->headtype = HEADTYPE;
-	if (headstring == nil)
+	if(headstring == nil)
 		headstring = headstr(HEADTYPE);
 
 	archinit();
@@ -163,6 +172,7 @@ main(int argc, char *argv[])
 		mark(linklookup(ctxt, "runtime.read_tls_fallback", 0));
 	}
 
+	checkgo();
 	deadcode();
 	callgraph();
 	paramspace = "SP";	/* (FP) now (SP) on output */
diff --git a/src/cmd/ld/symtab.c b/src/cmd/ld/symtab.c
index 6d321c0..156270c 100644
--- a/src/cmd/ld/symtab.c
+++ b/src/cmd/ld/symtab.c
@@ -198,13 +198,18 @@ asmelfsym(void)
 	genasmsym(putelfsym);
 	
 	if(linkmode == LinkExternal && HEADTYPE != Hopenbsd) {
-		s = linklookup(ctxt, "runtime.tlsgm", 0);
+		s = linklookup(ctxt, "runtime.tlsg", 0);
 		if(s->sect == nil) {
 			ctxt->cursym = nil;
 			diag("missing section for %s", s->name);
 			errorexit();
 		}
-		putelfsyment(putelfstr(s->name), 0, 2*PtrSize, (STB_LOCAL<<4)|STT_TLS, s->sect->elfsect->shnum, 0);
+		if (strcmp(goos, "android") == 0) {
+			// Android emulates runtime.tlsg as a regular variable.
+			putelfsyment(putelfstr(s->name), 0, s->size, (STB_LOCAL<<4)|STT_OBJECT, s->sect->elfsect->shnum, 0);
+		} else {
+			putelfsyment(putelfstr(s->name), 0, s->size, (STB_LOCAL<<4)|STT_TLS, s->sect->elfsect->shnum, 0);
+		}
 		s->elfsym = numelfsym++;
 	}
 
@@ -341,36 +346,36 @@ symtab(void)
 
 	// Define these so that they'll get put into the symbol table.
 	// data.c:/^address will provide the actual values.
-	xdefine("text", STEXT, 0);
-	xdefine("etext", STEXT, 0);
-	xdefine("typelink", SRODATA, 0);
-	xdefine("etypelink", SRODATA, 0);
-	xdefine("rodata", SRODATA, 0);
-	xdefine("erodata", SRODATA, 0);
-	xdefine("noptrdata", SNOPTRDATA, 0);
-	xdefine("enoptrdata", SNOPTRDATA, 0);
-	xdefine("data", SDATA, 0);
-	xdefine("edata", SDATA, 0);
-	xdefine("bss", SBSS, 0);
-	xdefine("ebss", SBSS, 0);
-	xdefine("noptrbss", SNOPTRBSS, 0);
-	xdefine("enoptrbss", SNOPTRBSS, 0);
-	xdefine("end", SBSS, 0);
-	xdefine("epclntab", SRODATA, 0);
-	xdefine("esymtab", SRODATA, 0);
+	xdefine("runtime.text", STEXT, 0);
+	xdefine("runtime.etext", STEXT, 0);
+	xdefine("runtime.typelink", SRODATA, 0);
+	xdefine("runtime.etypelink", SRODATA, 0);
+	xdefine("runtime.rodata", SRODATA, 0);
+	xdefine("runtime.erodata", SRODATA, 0);
+	xdefine("runtime.noptrdata", SNOPTRDATA, 0);
+	xdefine("runtime.enoptrdata", SNOPTRDATA, 0);
+	xdefine("runtime.data", SDATA, 0);
+	xdefine("runtime.edata", SDATA, 0);
+	xdefine("runtime.bss", SBSS, 0);
+	xdefine("runtime.ebss", SBSS, 0);
+	xdefine("runtime.noptrbss", SNOPTRBSS, 0);
+	xdefine("runtime.enoptrbss", SNOPTRBSS, 0);
+	xdefine("runtime.end", SBSS, 0);
+	xdefine("runtime.epclntab", SRODATA, 0);
+	xdefine("runtime.esymtab", SRODATA, 0);
 
 	// garbage collection symbols
-	s = linklookup(ctxt, "gcdata", 0);
+	s = linklookup(ctxt, "runtime.gcdata", 0);
 	s->type = SRODATA;
 	s->size = 0;
 	s->reachable = 1;
-	xdefine("egcdata", SRODATA, 0);
+	xdefine("runtime.egcdata", SRODATA, 0);
 
-	s = linklookup(ctxt, "gcbss", 0);
+	s = linklookup(ctxt, "runtime.gcbss", 0);
 	s->type = SRODATA;
 	s->size = 0;
 	s->reachable = 1;
-	xdefine("egcbss", SRODATA, 0);
+	xdefine("runtime.egcbss", SRODATA, 0);
 
 	// pseudo-symbols to mark locations of type, string, and go string data.
 	s = linklookup(ctxt, "type.*", 0);
@@ -391,9 +396,9 @@ symtab(void)
 	s->reachable = 1;
 	symgofunc = s;
 	
-	symtypelink = linklookup(ctxt, "typelink", 0);
+	symtypelink = linklookup(ctxt, "runtime.typelink", 0);
 
-	symt = linklookup(ctxt, "symtab", 0);
+	symt = linklookup(ctxt, "runtime.symtab", 0);
 	symt->type = SSYMTAB;
 	symt->size = 0;
 	symt->reachable = 1;
diff --git a/src/cmd/ld/textflag.h b/src/cmd/ld/textflag.h
index 2a76e76..0ee8b5f 100644
--- a/src/cmd/ld/textflag.h
+++ b/src/cmd/ld/textflag.h
@@ -21,3 +21,16 @@
 #define WRAPPER 32
 // This function uses its incoming context register.
 #define NEEDCTXT 64
+
+/*c2go
+enum
+{
+	NOPROF = 1,
+	DUPOK = 2,
+	NOSPLIT = 4,
+	RODATA = 8,
+	NOPTR = 16,
+	WRAPPER = 32,
+	NEEDCTXT = 64,
+};
+*/
diff --git a/src/cmd/nm/debug_goobj.go b/src/cmd/nm/debug_goobj.go
deleted file mode 100644
index 9a067e2..0000000
--- a/src/cmd/nm/debug_goobj.go
+++ /dev/null
@@ -1,670 +0,0 @@
-// DO NOT EDIT. Generated by code.google.com/p/rsc/cmd/bundle
-// bundle -p main -x goobj_ debug/goobj
-
-/* read.go */
-
-// Copyright 2013 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package goobj implements reading of Go object files and archives.
-//
-// TODO(rsc): Decide where this package should live. (golang.org/issue/6932)
-// TODO(rsc): Decide the appropriate integer types for various fields.
-// TODO(rsc): Write tests. (File format still up in the air a little.)
-
-package main
-
-import (
-	"bufio"
-	"bytes"
-	"errors"
-	"fmt"
-	"io"
-	"strconv"
-	"strings"
-)
-
-// A SymKind describes the kind of memory represented by a symbol.
-type goobj_SymKind int
-
-// This list is taken from include/link.h.
-
-// Defined SymKind values.
-// TODO(rsc): Give idiomatic Go names.
-// TODO(rsc): Reduce the number of symbol types in the object files.
-const (
-	_ goobj_SymKind = iota
-
-	// readonly, executable
-	goobj_STEXT
-	goobj_SELFRXSECT
-
-	// readonly, non-executable
-	goobj_STYPE
-	goobj_SSTRING
-	goobj_SGOSTRING
-	goobj_SGOFUNC
-	goobj_SRODATA
-	goobj_SFUNCTAB
-	goobj_STYPELINK
-	goobj_SSYMTAB // TODO: move to unmapped section
-	goobj_SPCLNTAB
-	goobj_SELFROSECT
-
-	// writable, non-executable
-	goobj_SMACHOPLT
-	goobj_SELFSECT
-	goobj_SMACHO // Mach-O __nl_symbol_ptr
-	goobj_SMACHOGOT
-	goobj_SNOPTRDATA
-	goobj_SINITARR
-	goobj_SDATA
-	goobj_SWINDOWS
-	goobj_SBSS
-	goobj_SNOPTRBSS
-	goobj_STLSBSS
-
-	// not mapped
-	goobj_SXREF
-	goobj_SMACHOSYMSTR
-	goobj_SMACHOSYMTAB
-	goobj_SMACHOINDIRECTPLT
-	goobj_SMACHOINDIRECTGOT
-	goobj_SFILE
-	goobj_SFILEPATH
-	goobj_SCONST
-	goobj_SDYNIMPORT
-	goobj_SHOSTOBJ
-)
-
-var goobj_symKindStrings = []string{
-	goobj_SBSS:              "SBSS",
-	goobj_SCONST:            "SCONST",
-	goobj_SDATA:             "SDATA",
-	goobj_SDYNIMPORT:        "SDYNIMPORT",
-	goobj_SELFROSECT:        "SELFROSECT",
-	goobj_SELFRXSECT:        "SELFRXSECT",
-	goobj_SELFSECT:          "SELFSECT",
-	goobj_SFILE:             "SFILE",
-	goobj_SFILEPATH:         "SFILEPATH",
-	goobj_SFUNCTAB:          "SFUNCTAB",
-	goobj_SGOFUNC:           "SGOFUNC",
-	goobj_SGOSTRING:         "SGOSTRING",
-	goobj_SHOSTOBJ:          "SHOSTOBJ",
-	goobj_SINITARR:          "SINITARR",
-	goobj_SMACHO:            "SMACHO",
-	goobj_SMACHOGOT:         "SMACHOGOT",
-	goobj_SMACHOINDIRECTGOT: "SMACHOINDIRECTGOT",
-	goobj_SMACHOINDIRECTPLT: "SMACHOINDIRECTPLT",
-	goobj_SMACHOPLT:         "SMACHOPLT",
-	goobj_SMACHOSYMSTR:      "SMACHOSYMSTR",
-	goobj_SMACHOSYMTAB:      "SMACHOSYMTAB",
-	goobj_SNOPTRBSS:         "SNOPTRBSS",
-	goobj_SNOPTRDATA:        "SNOPTRDATA",
-	goobj_SPCLNTAB:          "SPCLNTAB",
-	goobj_SRODATA:           "SRODATA",
-	goobj_SSTRING:           "SSTRING",
-	goobj_SSYMTAB:           "SSYMTAB",
-	goobj_STEXT:             "STEXT",
-	goobj_STLSBSS:           "STLSBSS",
-	goobj_STYPE:             "STYPE",
-	goobj_STYPELINK:         "STYPELINK",
-	goobj_SWINDOWS:          "SWINDOWS",
-	goobj_SXREF:             "SXREF",
-}
-
-func (k goobj_SymKind) String() string {
-	if k < 0 || int(k) >= len(goobj_symKindStrings) {
-		return fmt.Sprintf("SymKind(%d)", k)
-	}
-	return goobj_symKindStrings[k]
-}
-
-// A Sym is a named symbol in an object file.
-type goobj_Sym struct {
-	goobj_SymID               // symbol identifier (name and version)
-	Kind        goobj_SymKind // kind of symbol
-	DupOK       bool          // are duplicate definitions okay?
-	Size        int           // size of corresponding data
-	Type        goobj_SymID   // symbol for Go type information
-	Data        goobj_Data    // memory image of symbol
-	Reloc       []goobj_Reloc // relocations to apply to Data
-	Func        *goobj_Func   // additional data for functions
-}
-
-// A SymID - the combination of Name and Version - uniquely identifies
-// a symbol within a package.
-type goobj_SymID struct {
-	// Name is the name of a symbol.
-	Name string
-
-	// Version is zero for symbols with global visibility.
-	// Symbols with only file visibility (such as file-level static
-	// declarations in C) have a non-zero version distinguishing
-	// a symbol in one file from a symbol of the same name
-	// in another file
-	Version int
-}
-
-func (s goobj_SymID) String() string {
-	if s.Version == 0 {
-		return s.Name
-	}
-	return fmt.Sprintf("%s<%d>", s.Name, s.Version)
-}
-
-// A Data is a reference to data stored in an object file.
-// It records the offset and size of the data, so that a client can
-// read the data only if necessary.
-type goobj_Data struct {
-	Offset int64
-	Size   int64
-}
-
-// A Reloc describes a relocation applied to a memory image to refer
-// to an address within a particular symbol.
-type goobj_Reloc struct {
-	// The bytes at [Offset, Offset+Size) within the memory image
-	// should be updated to refer to the address Add bytes after the start
-	// of the symbol Sym.
-	Offset int
-	Size   int
-	Sym    goobj_SymID
-	Add    int
-
-	// The Type records the form of address expected in the bytes
-	// described by the previous fields: absolute, PC-relative, and so on.
-	// TODO(rsc): The interpretation of Type is not exposed by this package.
-	Type int
-}
-
-// A Var describes a variable in a function stack frame: a declared
-// local variable, an input argument, or an output result.
-type goobj_Var struct {
-	// The combination of Name, Kind, and Offset uniquely
-	// identifies a variable in a function stack frame.
-	// Using fewer of these - in particular, using only Name - does not.
-	Name   string // Name of variable.
-	Kind   int    // TODO(rsc): Define meaning.
-	Offset int    // Frame offset. TODO(rsc): Define meaning.
-
-	Type goobj_SymID // Go type for variable.
-}
-
-// Func contains additional per-symbol information specific to functions.
-type goobj_Func struct {
-	Args     int              // size in bytes of argument frame: inputs and outputs
-	Frame    int              // size in bytes of local variable frame
-	Leaf     bool             // function omits save of link register (ARM)
-	NoSplit  bool             // function omits stack split prologue
-	Var      []goobj_Var      // detail about local variables
-	PCSP     goobj_Data       // PC → SP offset map
-	PCFile   goobj_Data       // PC → file number map (index into File)
-	PCLine   goobj_Data       // PC → line number map
-	PCData   []goobj_Data     // PC → runtime support data map
-	FuncData []goobj_FuncData // non-PC-specific runtime support data
-	File     []string         // paths indexed by PCFile
-}
-
-// TODO: Add PCData []byte and PCDataIter (similar to liblink).
-
-// A FuncData is a single function-specific data value.
-type goobj_FuncData struct {
-	Sym    goobj_SymID // symbol holding data
-	Offset int64       // offset into symbol for funcdata pointer
-}
-
-// A Package is a parsed Go object file or archive defining a Go package.
-type goobj_Package struct {
-	ImportPath string       // import path denoting this package
-	Imports    []string     // packages imported by this package
-	Syms       []*goobj_Sym // symbols defined by this package
-	MaxVersion int          // maximum Version in any SymID in Syms
-}
-
-var (
-	goobj_archiveHeader = []byte("!<arch>\n")
-	goobj_archiveMagic  = []byte("`\n")
-	goobj_goobjHeader   = []byte("go objec") // truncated to size of archiveHeader
-
-	goobj_errCorruptArchive   = errors.New("corrupt archive")
-	goobj_errTruncatedArchive = errors.New("truncated archive")
-	goobj_errNotArchive       = errors.New("unrecognized archive format")
-
-	goobj_errCorruptObject   = errors.New("corrupt object file")
-	goobj_errTruncatedObject = errors.New("truncated object file")
-	goobj_errNotObject       = errors.New("unrecognized object file format")
-)
-
-// An objReader is an object file reader.
-type goobj_objReader struct {
-	p         *goobj_Package
-	b         *bufio.Reader
-	f         io.ReadSeeker
-	err       error
-	offset    int64
-	limit     int64
-	tmp       [256]byte
-	pkg       string
-	pkgprefix string
-}
-
-// importPathToPrefix returns the prefix that will be used in the
-// final symbol table for the given import path.
-// We escape '%', '"', all control characters and non-ASCII bytes,
-// and any '.' after the final slash.
-//
-// See ../../../cmd/ld/lib.c:/^pathtoprefix and
-// ../../../cmd/gc/subr.c:/^pathtoprefix.
-func goobj_importPathToPrefix(s string) string {
-	// find index of last slash, if any, or else -1.
-	// used for determining whether an index is after the last slash.
-	slash := strings.LastIndex(s, "/")
-
-	// check for chars that need escaping
-	n := 0
-	for r := 0; r < len(s); r++ {
-		if c := s[r]; c <= ' ' || (c == '.' && r > slash) || c == '%' || c == '"' || c >= 0x7F {
-			n++
-		}
-	}
-
-	// quick exit
-	if n == 0 {
-		return s
-	}
-
-	// escape
-	const hex = "0123456789abcdef"
-	p := make([]byte, 0, len(s)+2*n)
-	for r := 0; r < len(s); r++ {
-		if c := s[r]; c <= ' ' || (c == '.' && r > slash) || c == '%' || c == '"' || c >= 0x7F {
-			p = append(p, '%', hex[c>>4], hex[c&0xF])
-		} else {
-			p = append(p, c)
-		}
-	}
-
-	return string(p)
-}
-
-// init initializes r to read package p from f.
-func (r *goobj_objReader) init(f io.ReadSeeker, p *goobj_Package) {
-	r.f = f
-	r.p = p
-	r.offset, _ = f.Seek(0, 1)
-	r.limit, _ = f.Seek(0, 2)
-	f.Seek(r.offset, 0)
-	r.b = bufio.NewReader(f)
-	r.pkgprefix = goobj_importPathToPrefix(p.ImportPath) + "."
-}
-
-// error records that an error occurred.
-// It returns only the first error, so that an error
-// caused by an earlier error does not discard information
-// about the earlier error.
-func (r *goobj_objReader) error(err error) error {
-	if r.err == nil {
-		if err == io.EOF {
-			err = io.ErrUnexpectedEOF
-		}
-		r.err = err
-	}
-	// panic("corrupt") // useful for debugging
-	return r.err
-}
-
-// readByte reads and returns a byte from the input file.
-// On I/O error or EOF, it records the error but returns byte 0.
-// A sequence of 0 bytes will eventually terminate any
-// parsing state in the object file. In particular, it ends the
-// reading of a varint.
-func (r *goobj_objReader) readByte() byte {
-	if r.err != nil {
-		return 0
-	}
-	if r.offset >= r.limit {
-		r.error(io.ErrUnexpectedEOF)
-		return 0
-	}
-	b, err := r.b.ReadByte()
-	if err != nil {
-		if err == io.EOF {
-			err = io.ErrUnexpectedEOF
-		}
-		r.error(err)
-		b = 0
-	} else {
-		r.offset++
-	}
-	return b
-}
-
-// read reads exactly len(b) bytes from the input file.
-// If an error occurs, read returns the error but also
-// records it, so it is safe for callers to ignore the result
-// as long as delaying the report is not a problem.
-func (r *goobj_objReader) readFull(b []byte) error {
-	if r.err != nil {
-		return r.err
-	}
-	if r.offset+int64(len(b)) > r.limit {
-		return r.error(io.ErrUnexpectedEOF)
-	}
-	n, err := io.ReadFull(r.b, b)
-	r.offset += int64(n)
-	if err != nil {
-		return r.error(err)
-	}
-	return nil
-}
-
-// readInt reads a zigzag varint from the input file.
-func (r *goobj_objReader) readInt() int {
-	var u uint64
-
-	for shift := uint(0); ; shift += 7 {
-		if shift >= 64 {
-			r.error(goobj_errCorruptObject)
-			return 0
-		}
-		c := r.readByte()
-		u |= uint64(c&0x7F) << shift
-		if c&0x80 == 0 {
-			break
-		}
-	}
-
-	v := int64(u>>1) ^ (int64(u) << 63 >> 63)
-	if int64(int(v)) != v {
-		r.error(goobj_errCorruptObject) // TODO
-		return 0
-	}
-	return int(v)
-}
-
-// readString reads a length-delimited string from the input file.
-func (r *goobj_objReader) readString() string {
-	n := r.readInt()
-	buf := make([]byte, n)
-	r.readFull(buf)
-	return string(buf)
-}
-
-// readSymID reads a SymID from the input file.
-func (r *goobj_objReader) readSymID() goobj_SymID {
-	name, vers := r.readString(), r.readInt()
-
-	// In a symbol name in an object file, "". denotes the
-	// prefix for the package in which the object file has been found.
-	// Expand it.
-	name = strings.Replace(name, `"".`, r.pkgprefix, -1)
-
-	// An individual object file only records version 0 (extern) or 1 (static).
-	// To make static symbols unique across all files being read, we
-	// replace version 1 with the version corresponding to the current
-	// file number. The number is incremented on each call to parseObject.
-	if vers != 0 {
-		vers = r.p.MaxVersion
-	}
-
-	return goobj_SymID{name, vers}
-}
-
-// readData reads a data reference from the input file.
-func (r *goobj_objReader) readData() goobj_Data {
-	n := r.readInt()
-	d := goobj_Data{Offset: r.offset, Size: int64(n)}
-	r.skip(int64(n))
-	return d
-}
-
-// skip skips n bytes in the input.
-func (r *goobj_objReader) skip(n int64) {
-	if n < 0 {
-		r.error(fmt.Errorf("debug/goobj: internal error: misuse of skip"))
-	}
-	if n < int64(len(r.tmp)) {
-		// Since the data is so small, a just reading from the buffered
-		// reader is better than flushing the buffer and seeking.
-		r.readFull(r.tmp[:n])
-	} else if n <= int64(r.b.Buffered()) {
-		// Even though the data is not small, it has already been read.
-		// Advance the buffer instead of seeking.
-		for n > int64(len(r.tmp)) {
-			r.readFull(r.tmp[:])
-			n -= int64(len(r.tmp))
-		}
-		r.readFull(r.tmp[:n])
-	} else {
-		// Seek, giving up buffered data.
-		_, err := r.f.Seek(r.offset+n, 0)
-		if err != nil {
-			r.error(err)
-		}
-		r.offset += n
-		r.b.Reset(r.f)
-	}
-}
-
-// Parse parses an object file or archive from r,
-// assuming that its import path is pkgpath.
-func goobj_Parse(r io.ReadSeeker, pkgpath string) (*goobj_Package, error) {
-	if pkgpath == "" {
-		pkgpath = `""`
-	}
-	p := new(goobj_Package)
-	p.ImportPath = pkgpath
-
-	var rd goobj_objReader
-	rd.init(r, p)
-	err := rd.readFull(rd.tmp[:8])
-	if err != nil {
-		if err == io.EOF {
-			err = io.ErrUnexpectedEOF
-		}
-		return nil, err
-	}
-
-	switch {
-	default:
-		return nil, goobj_errNotObject
-
-	case bytes.Equal(rd.tmp[:8], goobj_archiveHeader):
-		if err := rd.parseArchive(); err != nil {
-			return nil, err
-		}
-	case bytes.Equal(rd.tmp[:8], goobj_goobjHeader):
-		if err := rd.parseObject(goobj_goobjHeader); err != nil {
-			return nil, err
-		}
-	}
-
-	return p, nil
-}
-
-// trimSpace removes trailing spaces from b and returns the corresponding string.
-// This effectively parses the form used in archive headers.
-func goobj_trimSpace(b []byte) string {
-	return string(bytes.TrimRight(b, " "))
-}
-
-// parseArchive parses a Unix archive of Go object files.
-// TODO(rsc): Need to skip non-Go object files.
-// TODO(rsc): Maybe record table of contents in r.p so that
-// linker can avoid having code to parse archives too.
-func (r *goobj_objReader) parseArchive() error {
-	for r.offset < r.limit {
-		if err := r.readFull(r.tmp[:60]); err != nil {
-			return err
-		}
-		data := r.tmp[:60]
-
-		// Each file is preceded by this text header (slice indices in first column):
-		//	 0:16	name
-		//	16:28 date
-		//	28:34 uid
-		//	34:40 gid
-		//	40:48 mode
-		//	48:58 size
-		//	58:60 magic - `\n
-		// We only care about name, size, and magic.
-		// The fields are space-padded on the right.
-		// The size is in decimal.
-		// The file data - size bytes - follows the header.
-		// Headers are 2-byte aligned, so if size is odd, an extra padding
-		// byte sits between the file data and the next header.
-		// The file data that follows is padded to an even number of bytes:
-		// if size is odd, an extra padding byte is inserted betw the next header.
-		if len(data) < 60 {
-			return goobj_errTruncatedArchive
-		}
-		if !bytes.Equal(data[58:60], goobj_archiveMagic) {
-			return goobj_errCorruptArchive
-		}
-		name := goobj_trimSpace(data[0:16])
-		size, err := strconv.ParseInt(goobj_trimSpace(data[48:58]), 10, 64)
-		if err != nil {
-			return goobj_errCorruptArchive
-		}
-		data = data[60:]
-		fsize := size + size&1
-		if fsize < 0 || fsize < size {
-			return goobj_errCorruptArchive
-		}
-		switch name {
-		case "__.SYMDEF", "__.GOSYMDEF", "__.PKGDEF":
-			r.skip(size)
-		default:
-			oldLimit := r.limit
-			r.limit = r.offset + size
-			if err := r.parseObject(nil); err != nil {
-				return fmt.Errorf("parsing archive member %q: %v", name, err)
-			}
-			r.skip(r.limit - r.offset)
-			r.limit = oldLimit
-		}
-		if size&1 != 0 {
-			r.skip(1)
-		}
-	}
-	return nil
-}
-
-// parseObject parses a single Go object file.
-// The prefix is the bytes already read from the file,
-// typically in order to detect that this is an object file.
-// The object file consists of a textual header ending in "\n!\n"
-// and then the part we want to parse begins.
-// The format of that part is defined in a comment at the top
-// of src/liblink/objfile.c.
-func (r *goobj_objReader) parseObject(prefix []byte) error {
-	// TODO(rsc): Maybe use prefix and the initial input to
-	// record the header line from the file, which would
-	// give the architecture and other version information.
-
-	r.p.MaxVersion++
-	var c1, c2, c3 byte
-	for {
-		c1, c2, c3 = c2, c3, r.readByte()
-		if c3 == 0 { // NUL or EOF, either is bad
-			return goobj_errCorruptObject
-		}
-		if c1 == '\n' && c2 == '!' && c3 == '\n' {
-			break
-		}
-	}
-
-	r.readFull(r.tmp[:8])
-	if !bytes.Equal(r.tmp[:8], []byte("\x00\x00go13ld")) {
-		return r.error(goobj_errCorruptObject)
-	}
-
-	b := r.readByte()
-	if b != 1 {
-		return r.error(goobj_errCorruptObject)
-	}
-
-	// Direct package dependencies.
-	for {
-		s := r.readString()
-		if s == "" {
-			break
-		}
-		r.p.Imports = append(r.p.Imports, s)
-	}
-
-	// Symbols.
-	for {
-		if b := r.readByte(); b != 0xfe {
-			if b != 0xff {
-				return r.error(goobj_errCorruptObject)
-			}
-			break
-		}
-
-		typ := r.readInt()
-		s := &goobj_Sym{goobj_SymID: r.readSymID()}
-		r.p.Syms = append(r.p.Syms, s)
-		s.Kind = goobj_SymKind(typ)
-		s.DupOK = r.readInt() != 0
-		s.Size = r.readInt()
-		s.Type = r.readSymID()
-		s.Data = r.readData()
-		s.Reloc = make([]goobj_Reloc, r.readInt())
-		for i := range s.Reloc {
-			rel := &s.Reloc[i]
-			rel.Offset = r.readInt()
-			rel.Size = r.readInt()
-			rel.Type = r.readInt()
-			rel.Add = r.readInt()
-			r.readInt() // Xadd - ignored
-			rel.Sym = r.readSymID()
-			r.readSymID() // Xsym - ignored
-		}
-
-		if s.Kind == goobj_STEXT {
-			f := new(goobj_Func)
-			s.Func = f
-			f.Args = r.readInt()
-			f.Frame = r.readInt()
-			f.Leaf = r.readInt() != 0
-			f.NoSplit = r.readInt() != 0
-			f.Var = make([]goobj_Var, r.readInt())
-			for i := range f.Var {
-				v := &f.Var[i]
-				v.Name = r.readSymID().Name
-				v.Offset = r.readInt()
-				v.Kind = r.readInt()
-				v.Type = r.readSymID()
-			}
-
-			f.PCSP = r.readData()
-			f.PCFile = r.readData()
-			f.PCLine = r.readData()
-			f.PCData = make([]goobj_Data, r.readInt())
-			for i := range f.PCData {
-				f.PCData[i] = r.readData()
-			}
-			f.FuncData = make([]goobj_FuncData, r.readInt())
-			for i := range f.FuncData {
-				f.FuncData[i].Sym = r.readSymID()
-			}
-			for i := range f.FuncData {
-				f.FuncData[i].Offset = int64(r.readInt()) // TODO
-			}
-			f.File = make([]string, r.readInt())
-			for i := range f.File {
-				f.File[i] = r.readSymID().Name
-			}
-		}
-	}
-
-	r.readFull(r.tmp[:7])
-	if !bytes.Equal(r.tmp[:7], []byte("\xffgo13ld")) {
-		return r.error(goobj_errCorruptObject)
-	}
-
-	return nil
-}
diff --git a/src/cmd/nm/elf.go b/src/cmd/nm/elf.go
deleted file mode 100644
index 5aaa194..0000000
--- a/src/cmd/nm/elf.go
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright 2013 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Parsing of ELF executables (Linux, FreeBSD, and so on).
-
-package main
-
-import (
-	"debug/elf"
-	"os"
-)
-
-func elfSymbols(f *os.File) []Sym {
-	p, err := elf.NewFile(f)
-	if err != nil {
-		errorf("parsing %s: %v", f.Name(), err)
-		return nil
-	}
-
-	elfSyms, err := p.Symbols()
-	if err != nil {
-		errorf("parsing %s: %v", f.Name(), err)
-		return nil
-	}
-
-	var syms []Sym
-	for _, s := range elfSyms {
-		sym := Sym{Addr: s.Value, Name: s.Name, Size: int64(s.Size), Code: '?'}
-		switch s.Section {
-		case elf.SHN_UNDEF:
-			sym.Code = 'U'
-		case elf.SHN_COMMON:
-			sym.Code = 'B'
-		default:
-			i := int(s.Section)
-			if i < 0 || i >= len(p.Sections) {
-				break
-			}
-			sect := p.Sections[i]
-			switch sect.Flags & (elf.SHF_WRITE | elf.SHF_ALLOC | elf.SHF_EXECINSTR) {
-			case elf.SHF_ALLOC | elf.SHF_EXECINSTR:
-				sym.Code = 'T'
-			case elf.SHF_ALLOC:
-				sym.Code = 'R'
-			case elf.SHF_ALLOC | elf.SHF_WRITE:
-				sym.Code = 'D'
-			}
-		}
-		if elf.ST_BIND(s.Info) == elf.STB_LOCAL {
-			sym.Code += 'a' - 'A'
-		}
-		syms = append(syms, sym)
-	}
-
-	return syms
-}
diff --git a/src/cmd/nm/goobj.go b/src/cmd/nm/goobj.go
deleted file mode 100644
index 5e0817d..0000000
--- a/src/cmd/nm/goobj.go
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright 2013 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Parsing of Go intermediate object files and archives.
-
-package main
-
-import (
-	"fmt"
-	"os"
-)
-
-func goobjName(id goobj_SymID) string {
-	if id.Version == 0 {
-		return id.Name
-	}
-	return fmt.Sprintf("%s<%d>", id.Name, id.Version)
-}
-
-func goobjSymbols(f *os.File) []Sym {
-	pkg, err := goobj_Parse(f, `""`)
-	if err != nil {
-		errorf("parsing %s: %v", f.Name(), err)
-		return nil
-	}
-
-	seen := make(map[goobj_SymID]bool)
-
-	var syms []Sym
-	for _, s := range pkg.Syms {
-		seen[s.goobj_SymID] = true
-		sym := Sym{Addr: uint64(s.Data.Offset), Name: goobjName(s.goobj_SymID), Size: int64(s.Size), Type: s.Type.Name, Code: '?'}
-		switch s.Kind {
-		case goobj_STEXT, goobj_SELFRXSECT:
-			sym.Code = 'T'
-		case goobj_STYPE, goobj_SSTRING, goobj_SGOSTRING, goobj_SGOFUNC, goobj_SRODATA, goobj_SFUNCTAB, goobj_STYPELINK, goobj_SSYMTAB, goobj_SPCLNTAB, goobj_SELFROSECT:
-			sym.Code = 'R'
-		case goobj_SMACHOPLT, goobj_SELFSECT, goobj_SMACHO, goobj_SMACHOGOT, goobj_SNOPTRDATA, goobj_SINITARR, goobj_SDATA, goobj_SWINDOWS:
-			sym.Code = 'D'
-		case goobj_SBSS, goobj_SNOPTRBSS, goobj_STLSBSS:
-			sym.Code = 'B'
-		case goobj_SXREF, goobj_SMACHOSYMSTR, goobj_SMACHOSYMTAB, goobj_SMACHOINDIRECTPLT, goobj_SMACHOINDIRECTGOT, goobj_SFILE, goobj_SFILEPATH, goobj_SCONST, goobj_SDYNIMPORT, goobj_SHOSTOBJ:
-			sym.Code = 'X' // should not see
-		}
-		if s.Version != 0 {
-			sym.Code += 'a' - 'A'
-		}
-		syms = append(syms, sym)
-	}
-
-	for _, s := range pkg.Syms {
-		for _, r := range s.Reloc {
-			if !seen[r.Sym] {
-				seen[r.Sym] = true
-				sym := Sym{Name: goobjName(r.Sym), Code: 'U'}
-				if s.Version != 0 {
-					// should not happen but handle anyway
-					sym.Code = 'u'
-				}
-				syms = append(syms, sym)
-			}
-		}
-	}
-
-	return syms
-}
diff --git a/src/cmd/nm/macho.go b/src/cmd/nm/macho.go
deleted file mode 100644
index c60bde5..0000000
--- a/src/cmd/nm/macho.go
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright 2013 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Parsing of Mach-O executables (OS X).
-
-package main
-
-import (
-	"debug/macho"
-	"os"
-	"sort"
-)
-
-func machoSymbols(f *os.File) []Sym {
-	p, err := macho.NewFile(f)
-	if err != nil {
-		errorf("parsing %s: %v", f.Name(), err)
-		return nil
-	}
-
-	if p.Symtab == nil {
-		errorf("%s: no symbol table", f.Name())
-		return nil
-	}
-
-	// Build sorted list of addresses of all symbols.
-	// We infer the size of a symbol by looking at where the next symbol begins.
-	var addrs []uint64
-	for _, s := range p.Symtab.Syms {
-		addrs = append(addrs, s.Value)
-	}
-	sort.Sort(uint64s(addrs))
-
-	var syms []Sym
-	for _, s := range p.Symtab.Syms {
-		sym := Sym{Name: s.Name, Addr: s.Value, Code: '?'}
-		i := sort.Search(len(addrs), func(x int) bool { return addrs[x] > s.Value })
-		if i < len(addrs) {
-			sym.Size = int64(addrs[i] - s.Value)
-		}
-		if s.Sect == 0 {
-			sym.Code = 'U'
-		} else if int(s.Sect) <= len(p.Sections) {
-			sect := p.Sections[s.Sect-1]
-			switch sect.Seg {
-			case "__TEXT":
-				sym.Code = 'R'
-			case "__DATA":
-				sym.Code = 'D'
-			}
-			switch sect.Seg + " " + sect.Name {
-			case "__TEXT __text":
-				sym.Code = 'T'
-			case "__DATA __bss", "__DATA __noptrbss":
-				sym.Code = 'B'
-			}
-		}
-		syms = append(syms, sym)
-	}
-
-	return syms
-}
-
-type uint64s []uint64
-
-func (x uint64s) Len() int           { return len(x) }
-func (x uint64s) Swap(i, j int)      { x[i], x[j] = x[j], x[i] }
-func (x uint64s) Less(i, j int) bool { return x[i] < x[j] }
diff --git a/src/cmd/nm/nm.go b/src/cmd/nm/nm.go
index a403618..3089e48 100644
--- a/src/cmd/nm/nm.go
+++ b/src/cmd/nm/nm.go
@@ -6,13 +6,13 @@ package main
 
 import (
 	"bufio"
-	"bytes"
 	"flag"
 	"fmt"
-	"io"
 	"log"
 	"os"
 	"sort"
+
+	"cmd/internal/objfile"
 )
 
 func usage() {
@@ -85,55 +85,22 @@ func errorf(format string, args ...interface{}) {
 	exitCode = 1
 }
 
-type Sym struct {
-	Addr uint64
-	Size int64
-	Code rune
-	Name string
-	Type string
-}
-
-var parsers = []struct {
-	prefix []byte
-	parse  func(*os.File) []Sym
-}{
-	{[]byte("!<arch>\n"), goobjSymbols},
-	{[]byte("go object "), goobjSymbols},
-	{[]byte("\x7FELF"), elfSymbols},
-	{[]byte("\xFE\xED\xFA\xCE"), machoSymbols},
-	{[]byte("\xFE\xED\xFA\xCF"), machoSymbols},
-	{[]byte("\xCE\xFA\xED\xFE"), machoSymbols},
-	{[]byte("\xCF\xFA\xED\xFE"), machoSymbols},
-	{[]byte("MZ"), peSymbols},
-	{[]byte("\x00\x00\x01\xEB"), plan9Symbols}, // 386
-	{[]byte("\x00\x00\x04\x07"), plan9Symbols}, // mips
-	{[]byte("\x00\x00\x06\x47"), plan9Symbols}, // arm
-	{[]byte("\x00\x00\x8A\x97"), plan9Symbols}, // amd64
-}
-
 func nm(file string) {
-	f, err := os.Open(file)
+	f, err := objfile.Open(file)
 	if err != nil {
 		errorf("%v", err)
 		return
 	}
 	defer f.Close()
 
-	buf := make([]byte, 16)
-	io.ReadFull(f, buf)
-	f.Seek(0, 0)
-
-	var syms []Sym
-	for _, p := range parsers {
-		if bytes.HasPrefix(buf, p.prefix) {
-			syms = p.parse(f)
-			goto HaveSyms
-		}
+	syms, err := f.Symbols()
+	if err != nil {
+		errorf("reading %s: %v", file, err)
+	}
+	if len(syms) == 0 {
+		errorf("reading %s: no symbols", file)
 	}
-	errorf("%v: unknown file format", file)
-	return
 
-HaveSyms:
 	switch *sortOrder {
 	case "address":
 		sort.Sort(byAddr(syms))
@@ -165,19 +132,19 @@ HaveSyms:
 	w.Flush()
 }
 
-type byAddr []Sym
+type byAddr []objfile.Sym
 
 func (x byAddr) Len() int           { return len(x) }
 func (x byAddr) Swap(i, j int)      { x[i], x[j] = x[j], x[i] }
 func (x byAddr) Less(i, j int) bool { return x[i].Addr < x[j].Addr }
 
-type byName []Sym
+type byName []objfile.Sym
 
 func (x byName) Len() int           { return len(x) }
 func (x byName) Swap(i, j int)      { x[i], x[j] = x[j], x[i] }
 func (x byName) Less(i, j int) bool { return x[i].Name < x[j].Name }
 
-type bySize []Sym
+type bySize []objfile.Sym
 
 func (x bySize) Len() int           { return len(x) }
 func (x bySize) Swap(i, j int)      { x[i], x[j] = x[j], x[i] }
diff --git a/src/cmd/nm/nm_test.go b/src/cmd/nm/nm_test.go
index f4e47a4..cb555d8 100644
--- a/src/cmd/nm/nm_test.go
+++ b/src/cmd/nm/nm_test.go
@@ -55,8 +55,9 @@ func checkSymbols(t *testing.T, nmoutput []byte) {
 }
 
 func TestNM(t *testing.T) {
-	if runtime.GOOS == "nacl" {
-		t.Skip("skipping on nacl")
+	switch runtime.GOOS {
+	case "android", "nacl":
+		t.Skipf("skipping on %s", runtime.GOOS)
 	}
 
 	tmpDir, err := ioutil.TempDir("", "TestNM")
@@ -76,17 +77,17 @@ func TestNM(t *testing.T) {
 		"elf/testdata/gcc-amd64-linux-exec",
 		"macho/testdata/gcc-386-darwin-exec",
 		"macho/testdata/gcc-amd64-darwin-exec",
-		"pe/testdata/gcc-amd64-mingw-exec",
+		// "pe/testdata/gcc-amd64-mingw-exec", // no symbols!
 		"pe/testdata/gcc-386-mingw-exec",
 		"plan9obj/testdata/amd64-plan9-exec",
 		"plan9obj/testdata/386-plan9-exec",
 	}
 	for _, f := range testfiles {
-		exepath := filepath.Join(runtime.GOROOT(), "src", "pkg", "debug", f)
+		exepath := filepath.Join(runtime.GOROOT(), "src", "debug", f)
 		cmd := exec.Command(testnmpath, exepath)
 		out, err := cmd.CombinedOutput()
 		if err != nil {
-			t.Fatalf("go tool nm %v: %v\n%s", exepath, err, string(out))
+			t.Errorf("go tool nm %v: %v\n%s", exepath, err, string(out))
 		}
 	}
 
diff --git a/src/cmd/nm/pe.go b/src/cmd/nm/pe.go
deleted file mode 100644
index 52d05e5..0000000
--- a/src/cmd/nm/pe.go
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright 2013 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Parsing of PE executables (Microsoft Windows).
-
-package main
-
-import (
-	"debug/pe"
-	"os"
-	"sort"
-)
-
-func peSymbols(f *os.File) []Sym {
-	p, err := pe.NewFile(f)
-	if err != nil {
-		errorf("parsing %s: %v", f.Name(), err)
-		return nil
-	}
-
-	// Build sorted list of addresses of all symbols.
-	// We infer the size of a symbol by looking at where the next symbol begins.
-	var addrs []uint64
-
-	var imageBase uint64
-	switch oh := p.OptionalHeader.(type) {
-	case *pe.OptionalHeader32:
-		imageBase = uint64(oh.ImageBase)
-	case *pe.OptionalHeader64:
-		imageBase = oh.ImageBase
-	default:
-		errorf("parsing %s: file format not recognized", f.Name())
-		return nil
-	}
-
-	var syms []Sym
-	for _, s := range p.Symbols {
-		const (
-			N_UNDEF = 0  // An undefined (extern) symbol
-			N_ABS   = -1 // An absolute symbol (e_value is a constant, not an address)
-			N_DEBUG = -2 // A debugging symbol
-		)
-		sym := Sym{Name: s.Name, Addr: uint64(s.Value), Code: '?'}
-		switch s.SectionNumber {
-		case N_UNDEF:
-			sym.Code = 'U'
-		case N_ABS:
-			sym.Code = 'C'
-		case N_DEBUG:
-			sym.Code = '?'
-		default:
-			if s.SectionNumber < 0 {
-				errorf("parsing %s: invalid section number %d", f.Name(), s.SectionNumber)
-				return nil
-			}
-			if len(p.Sections) < int(s.SectionNumber) {
-				errorf("parsing %s: section number %d is large then max %d", f.Name(), s.SectionNumber, len(p.Sections))
-				return nil
-			}
-			sect := p.Sections[s.SectionNumber-1]
-			const (
-				text  = 0x20
-				data  = 0x40
-				bss   = 0x80
-				permX = 0x20000000
-				permR = 0x40000000
-				permW = 0x80000000
-			)
-			ch := sect.Characteristics
-			switch {
-			case ch&text != 0:
-				sym.Code = 'T'
-			case ch&data != 0:
-				if ch&permW == 0 {
-					sym.Code = 'R'
-				} else {
-					sym.Code = 'D'
-				}
-			case ch&bss != 0:
-				sym.Code = 'B'
-			}
-			sym.Addr += imageBase + uint64(sect.VirtualAddress)
-		}
-		syms = append(syms, sym)
-		addrs = append(addrs, sym.Addr)
-	}
-
-	sort.Sort(uint64s(addrs))
-	for i := range syms {
-		j := sort.Search(len(addrs), func(x int) bool { return addrs[x] > syms[i].Addr })
-		if j < len(addrs) {
-			syms[i].Size = int64(addrs[j] - syms[i].Addr)
-		}
-	}
-
-	return syms
-}
diff --git a/src/cmd/nm/plan9obj.go b/src/cmd/nm/plan9obj.go
deleted file mode 100644
index 006c66e..0000000
--- a/src/cmd/nm/plan9obj.go
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright 2014 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Parsing of Plan 9 a.out executables.
-
-package main
-
-import (
-	"debug/plan9obj"
-	"os"
-	"sort"
-)
-
-func plan9Symbols(f *os.File) []Sym {
-	p, err := plan9obj.NewFile(f)
-	if err != nil {
-		errorf("parsing %s: %v", f.Name(), err)
-		return nil
-	}
-
-	plan9Syms, err := p.Symbols()
-	if err != nil {
-		errorf("parsing %s: %v", f.Name(), err)
-		return nil
-	}
-
-	// Build sorted list of addresses of all symbols.
-	// We infer the size of a symbol by looking at where the next symbol begins.
-	var addrs []uint64
-	for _, s := range plan9Syms {
-		addrs = append(addrs, s.Value)
-	}
-	sort.Sort(uint64s(addrs))
-
-	var syms []Sym
-
-	for _, s := range plan9Syms {
-		sym := Sym{Addr: s.Value, Name: s.Name, Code: rune(s.Type)}
-		i := sort.Search(len(addrs), func(x int) bool { return addrs[x] > s.Value })
-		if i < len(addrs) {
-			sym.Size = int64(addrs[i] - s.Value)
-		}
-		syms = append(syms, sym)
-	}
-
-	return syms
-}
diff --git a/src/cmd/objdump/Makefile b/src/cmd/objdump/Makefile
deleted file mode 100644
index 1b66c26..0000000
--- a/src/cmd/objdump/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-all: x86.go armasm.go
-
-x86.go: bundle
-	./bundle -p main -x x86_ rsc.io/x86/x86asm | gofmt >x86.go
-
-armasm.go: bundle
-	./bundle -p main -x arm_ rsc.io/arm/armasm | gofmt >armasm.go
-
-bundle:
-	go build -o bundle code.google.com/p/rsc/cmd/bundle
diff --git a/src/cmd/objdump/armasm.go b/src/cmd/objdump/armasm.go
deleted file mode 100644
index 764a368..0000000
--- a/src/cmd/objdump/armasm.go
+++ /dev/null
@@ -1,10821 +0,0 @@
-// DO NOT EDIT. Generated by code.google.com/p/rsc/cmd/bundle
-// bundle -p main -x arm_ rsc.io/arm/armasm
-
-/* decode.go */
-
-// 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"
-	"encoding/binary"
-	"fmt"
-	"io"
-	"strings"
-)
-
-// An instFormat describes the format of an instruction encoding.
-// An instruction with 32-bit value x matches the format if x&mask == value
-// and the condition matches.
-// The condition matches if x>>28 == 0xF && value>>28==0xF
-// or if x>>28 != 0xF and value>>28 == 0.
-// If x matches the format, then the rest of the fields describe how to interpret x.
-// The opBits describe bits that should be extracted from x and added to the opcode.
-// For example opBits = 0x1234 means that the value
-//	(2 bits at offset 1) followed by (4 bits at offset 3)
-// should be added to op.
-// Finally the args describe how to decode the instruction arguments.
-// args is stored as a fixed-size array; if there are fewer than len(args) arguments,
-// args[i] == 0 marks the end of the argument list.
-type arm_instFormat struct {
-	mask     uint32
-	value    uint32
-	priority int8
-	op       arm_Op
-	opBits   uint64
-	args     arm_instArgs
-}
-
-type arm_instArgs [4]arm_instArg
-
-var (
-	arm_errMode    = fmt.Errorf("unsupported execution mode")
-	arm_errShort   = fmt.Errorf("truncated instruction")
-	arm_errUnknown = fmt.Errorf("unknown instruction")
-)
-
-var arm_decoderCover []bool
-
-// Decode decodes the leading bytes in src as a single instruction.
-func arm_Decode(src []byte, mode arm_Mode) (inst arm_Inst, err error) {
-	if mode != arm_ModeARM {
-		return arm_Inst{}, arm_errMode
-	}
-	if len(src) < 4 {
-		return arm_Inst{}, arm_errShort
-	}
-
-	if arm_decoderCover == nil {
-		arm_decoderCover = make([]bool, len(arm_instFormats))
-	}
-
-	x := binary.LittleEndian.Uint32(src)
-
-	// The instFormat table contains both conditional and unconditional instructions.
-	// Considering only the top 4 bits, the conditional instructions use mask=0, value=0,
-	// while the unconditional instructions use mask=f, value=f.
-	// Prepare a version of x with the condition cleared to 0 in conditional instructions
-	// and then assume mask=f during matching.
-	const condMask = 0xf0000000
-	xNoCond := x
-	if x&condMask != condMask {
-		xNoCond &^= condMask
-	}
-	var priority int8
-Search:
-	for i := range arm_instFormats {
-		f := &arm_instFormats[i]
-		if xNoCond&(f.mask|condMask) != f.value || f.priority <= priority {
-			continue
-		}
-		delta := uint32(0)
-		deltaShift := uint(0)
-		for opBits := f.opBits; opBits != 0; opBits >>= 16 {
-			n := uint(opBits & 0xFF)
-			off := uint((opBits >> 8) & 0xFF)
-			delta |= (x >> off) & (1<<n - 1) << deltaShift
-			deltaShift += n
-		}
-		op := f.op + arm_Op(delta)
-
-		// Special case: BKPT encodes with condition but cannot have one.
-		if op&^15 == arm_BKPT_EQ && op != arm_BKPT {
-			continue Search
-		}
-
-		var args arm_Args
-		for j, aop := range f.args {
-			if aop == 0 {
-				break
-			}
-			arg := arm_decodeArg(aop, x)
-			if arg == nil { // cannot decode argument
-				continue Search
-			}
-			args[j] = arg
-		}
-
-		arm_decoderCover[i] = true
-
-		inst = arm_Inst{
-			Op:   op,
-			Args: args,
-			Enc:  x,
-			Len:  4,
-		}
-		priority = f.priority
-		continue Search
-	}
-	if inst.Op != 0 {
-		return inst, nil
-	}
-	return arm_Inst{}, arm_errUnknown
-}
-
-// An instArg describes the encoding of a single argument.
-// In the names used for arguments, _p_ means +, _m_ means -,
-// _pm_ means ± (usually keyed by the U bit).
-// The _W suffix indicates a general addressing mode based on the P and W bits.
-// The _offset and _postindex suffixes force the given addressing mode.
-// The rest should be somewhat self-explanatory, at least given
-// the decodeArg function.
-type arm_instArg uint8
-
-const (
-	_ arm_instArg = iota
-	arm_arg_APSR
-	arm_arg_FPSCR
-	arm_arg_Dn_half
-	arm_arg_R1_0
-	arm_arg_R1_12
-	arm_arg_R2_0
-	arm_arg_R2_12
-	arm_arg_R_0
-	arm_arg_R_12
-	arm_arg_R_12_nzcv
-	arm_arg_R_16
-	arm_arg_R_16_WB
-	arm_arg_R_8
-	arm_arg_R_rotate
-	arm_arg_R_shift_R
-	arm_arg_R_shift_imm
-	arm_arg_SP
-	arm_arg_Sd
-	arm_arg_Sd_Dd
-	arm_arg_Dd_Sd
-	arm_arg_Sm
-	arm_arg_Sm_Dm
-	arm_arg_Sn
-	arm_arg_Sn_Dn
-	arm_arg_const
-	arm_arg_endian
-	arm_arg_fbits
-	arm_arg_fp_0
-	arm_arg_imm24
-	arm_arg_imm5
-	arm_arg_imm5_32
-	arm_arg_imm5_nz
-	arm_arg_imm_12at8_4at0
-	arm_arg_imm_4at16_12at0
-	arm_arg_imm_vfp
-	arm_arg_label24
-	arm_arg_label24H
-	arm_arg_label_m_12
-	arm_arg_label_p_12
-	arm_arg_label_pm_12
-	arm_arg_label_pm_4_4
-	arm_arg_lsb_width
-	arm_arg_mem_R
-	arm_arg_mem_R_pm_R_W
-	arm_arg_mem_R_pm_R_postindex
-	arm_arg_mem_R_pm_R_shift_imm_W
-	arm_arg_mem_R_pm_R_shift_imm_offset
-	arm_arg_mem_R_pm_R_shift_imm_postindex
-	arm_arg_mem_R_pm_imm12_W
-	arm_arg_mem_R_pm_imm12_offset
-	arm_arg_mem_R_pm_imm12_postindex
-	arm_arg_mem_R_pm_imm8_W
-	arm_arg_mem_R_pm_imm8_postindex
-	arm_arg_mem_R_pm_imm8at0_offset
-	arm_arg_option
-	arm_arg_registers
-	arm_arg_registers1
-	arm_arg_registers2
-	arm_arg_satimm4
-	arm_arg_satimm5
-	arm_arg_satimm4m1
-	arm_arg_satimm5m1
-	arm_arg_widthm1
-)
-
-// decodeArg decodes the arg described by aop from the instruction bits x.
-// It returns nil if x cannot be decoded according to aop.
-func arm_decodeArg(aop arm_instArg, x uint32) arm_Arg {
-	switch aop {
-	default:
-		return nil
-
-	case arm_arg_APSR:
-		return arm_APSR
-	case arm_arg_FPSCR:
-		return arm_FPSCR
-
-	case arm_arg_R_0:
-		return arm_Reg(x & (1<<4 - 1))
-	case arm_arg_R_8:
-		return arm_Reg((x >> 8) & (1<<4 - 1))
-	case arm_arg_R_12:
-		return arm_Reg((x >> 12) & (1<<4 - 1))
-	case arm_arg_R_16:
-		return arm_Reg((x >> 16) & (1<<4 - 1))
-
-	case arm_arg_R_12_nzcv:
-		r := arm_Reg((x >> 12) & (1<<4 - 1))
-		if r == arm_R15 {
-			return arm_APSR_nzcv
-		}
-		return r
-
-	case arm_arg_R_16_WB:
-		mode := arm_AddrLDM
-		if (x>>21)&1 != 0 {
-			mode = arm_AddrLDM_WB
-		}
-		return arm_Mem{Base: arm_Reg((x >> 16) & (1<<4 - 1)), Mode: mode}
-
-	case arm_arg_R_rotate:
-		Rm := arm_Reg(x & (1<<4 - 1))
-		typ, count := arm_decodeShift(x)
-		// ROR #0 here means ROR #0, but decodeShift rewrites to RRX #1.
-		if typ == arm_RotateRightExt {
-			return arm_Reg(Rm)
-		}
-		return arm_RegShift{Rm, typ, uint8(count)}
-
-	case arm_arg_R_shift_R:
-		Rm := arm_Reg(x & (1<<4 - 1))
-		Rs := arm_Reg((x >> 8) & (1<<4 - 1))
-		typ := arm_Shift((x >> 5) & (1<<2 - 1))
-		return arm_RegShiftReg{Rm, typ, Rs}
-
-	case arm_arg_R_shift_imm:
-		Rm := arm_Reg(x & (1<<4 - 1))
-		typ, count := arm_decodeShift(x)
-		if typ == arm_ShiftLeft && count == 0 {
-			return arm_Reg(Rm)
-		}
-		return arm_RegShift{Rm, typ, uint8(count)}
-
-	case arm_arg_R1_0:
-		return arm_Reg((x & (1<<4 - 1)))
-	case arm_arg_R1_12:
-		return arm_Reg(((x >> 12) & (1<<4 - 1)))
-	case arm_arg_R2_0:
-		return arm_Reg((x & (1<<4 - 1)) | 1)
-	case arm_arg_R2_12:
-		return arm_Reg(((x >> 12) & (1<<4 - 1)) | 1)
-
-	case arm_arg_SP:
-		return arm_SP
-
-	case arm_arg_Sd_Dd:
-		v := (x >> 12) & (1<<4 - 1)
-		vx := (x >> 22) & 1
-		sz := (x >> 8) & 1
-		if sz != 0 {
-			return arm_D0 + arm_Reg(vx<<4+v)
-		} else {
-			return arm_S0 + arm_Reg(v<<1+vx)
-		}
-
-	case arm_arg_Dd_Sd:
-		return arm_decodeArg(arm_arg_Sd_Dd, x^(1<<8))
-
-	case arm_arg_Sd:
-		v := (x >> 12) & (1<<4 - 1)
-		vx := (x >> 22) & 1
-		return arm_S0 + arm_Reg(v<<1+vx)
-
-	case arm_arg_Sm_Dm:
-		v := (x >> 0) & (1<<4 - 1)
-		vx := (x >> 5) & 1
-		sz := (x >> 8) & 1
-		if sz != 0 {
-			return arm_D0 + arm_Reg(vx<<4+v)
-		} else {
-			return arm_S0 + arm_Reg(v<<1+vx)
-		}
-
-	case arm_arg_Sm:
-		v := (x >> 0) & (1<<4 - 1)
-		vx := (x >> 5) & 1
-		return arm_S0 + arm_Reg(v<<1+vx)
-
-	case arm_arg_Dn_half:
-		v := (x >> 16) & (1<<4 - 1)
-		vx := (x >> 7) & 1
-		return arm_RegX{arm_D0 + arm_Reg(vx<<4+v), int((x >> 21) & 1)}
-
-	case arm_arg_Sn_Dn:
-		v := (x >> 16) & (1<<4 - 1)
-		vx := (x >> 7) & 1
-		sz := (x >> 8) & 1
-		if sz != 0 {
-			return arm_D0 + arm_Reg(vx<<4+v)
-		} else {
-			return arm_S0 + arm_Reg(v<<1+vx)
-		}
-
-	case arm_arg_Sn:
-		v := (x >> 16) & (1<<4 - 1)
-		vx := (x >> 7) & 1
-		return arm_S0 + arm_Reg(v<<1+vx)
-
-	case arm_arg_const:
-		v := x & (1<<8 - 1)
-		rot := (x >> 8) & (1<<4 - 1) * 2
-		if rot > 0 && v&3 == 0 {
-			// could rotate less
-			return arm_ImmAlt{uint8(v), uint8(rot)}
-		}
-		if rot >= 24 && ((v<<(32-rot))&0xFF)>>(32-rot) == v {
-			// could wrap around to rot==0.
-			return arm_ImmAlt{uint8(v), uint8(rot)}
-		}
-		return arm_Imm(v>>rot | v<<(32-rot))
-
-	case arm_arg_endian:
-		return arm_Endian((x >> 9) & 1)
-
-	case arm_arg_fbits:
-		return arm_Imm((16 << ((x >> 7) & 1)) - ((x&(1<<4-1))<<1 | (x>>5)&1))
-
-	case arm_arg_fp_0:
-		return arm_Imm(0)
-
-	case arm_arg_imm24:
-		return arm_Imm(x & (1<<24 - 1))
-
-	case arm_arg_imm5:
-		return arm_Imm((x >> 7) & (1<<5 - 1))
-
-	case arm_arg_imm5_32:
-		x = (x >> 7) & (1<<5 - 1)
-		if x == 0 {
-			x = 32
-		}
-		return arm_Imm(x)
-
-	case arm_arg_imm5_nz:
-		x = (x >> 7) & (1<<5 - 1)
-		if x == 0 {
-			return nil
-		}
-		return arm_Imm(x)
-
-	case arm_arg_imm_4at16_12at0:
-		return arm_Imm((x>>16)&(1<<4-1)<<12 | x&(1<<12-1))
-
-	case arm_arg_imm_12at8_4at0:
-		return arm_Imm((x>>8)&(1<<12-1)<<4 | x&(1<<4-1))
-
-	case arm_arg_imm_vfp:
-		x = (x>>16)&(1<<4-1)<<4 | x&(1<<4-1)
-		return arm_Imm(x)
-
-	case arm_arg_label24:
-		imm := (x & (1<<24 - 1)) << 2
-		return arm_PCRel(int32(imm<<6) >> 6)
-
-	case arm_arg_label24H:
-		h := (x >> 24) & 1
-		imm := (x&(1<<24-1))<<2 | h<<1
-		return arm_PCRel(int32(imm<<6) >> 6)
-
-	case arm_arg_label_m_12:
-		d := int32(x & (1<<12 - 1))
-		return arm_Mem{Base: arm_PC, Mode: arm_AddrOffset, Offset: int16(-d)}
-
-	case arm_arg_label_p_12:
-		d := int32(x & (1<<12 - 1))
-		return arm_Mem{Base: arm_PC, Mode: arm_AddrOffset, Offset: int16(d)}
-
-	case arm_arg_label_pm_12:
-		d := int32(x & (1<<12 - 1))
-		u := (x >> 23) & 1
-		if u == 0 {
-			d = -d
-		}
-		return arm_Mem{Base: arm_PC, Mode: arm_AddrOffset, Offset: int16(d)}
-
-	case arm_arg_label_pm_4_4:
-		d := int32((x>>8)&(1<<4-1)<<4 | x&(1<<4-1))
-		u := (x >> 23) & 1
-		if u == 0 {
-			d = -d
-		}
-		return arm_PCRel(d)
-
-	case arm_arg_lsb_width:
-		lsb := (x >> 7) & (1<<5 - 1)
-		msb := (x >> 16) & (1<<5 - 1)
-		if msb < lsb || msb >= 32 {
-			return nil
-		}
-		return arm_Imm(msb + 1 - lsb)
-
-	case arm_arg_mem_R:
-		Rn := arm_Reg((x >> 16) & (1<<4 - 1))
-		return arm_Mem{Base: Rn, Mode: arm_AddrOffset}
-
-	case arm_arg_mem_R_pm_R_postindex:
-		// Treat [<Rn>],+/-<Rm> like [<Rn>,+/-<Rm>{,<shift>}]{!}
-		// by forcing shift bits to <<0 and P=0, W=0 (postindex=true).
-		return arm_decodeArg(arm_arg_mem_R_pm_R_shift_imm_W, x&^((1<<7-1)<<5|1<<24|1<<21))
-
-	case arm_arg_mem_R_pm_R_W:
-		// Treat [<Rn>,+/-<Rm>]{!} like [<Rn>,+/-<Rm>{,<shift>}]{!}
-		// by forcing shift bits to <<0.
-		return arm_decodeArg(arm_arg_mem_R_pm_R_shift_imm_W, x&^((1<<7-1)<<5))
-
-	case arm_arg_mem_R_pm_R_shift_imm_offset:
-		// Treat [<Rn>],+/-<Rm>{,<shift>} like [<Rn>,+/-<Rm>{,<shift>}]{!}
-		// by forcing P=1, W=0 (index=false, wback=false).
-		return arm_decodeArg(arm_arg_mem_R_pm_R_shift_imm_W, x&^(1<<21)|1<<24)
-
-	case arm_arg_mem_R_pm_R_shift_imm_postindex:
-		// Treat [<Rn>],+/-<Rm>{,<shift>} like [<Rn>,+/-<Rm>{,<shift>}]{!}
-		// by forcing P=0, W=0 (postindex=true).
-		return arm_decodeArg(arm_arg_mem_R_pm_R_shift_imm_W, x&^(1<<24|1<<21))
-
-	case arm_arg_mem_R_pm_R_shift_imm_W:
-		Rn := arm_Reg((x >> 16) & (1<<4 - 1))
-		Rm := arm_Reg(x & (1<<4 - 1))
-		typ, count := arm_decodeShift(x)
-		u := (x >> 23) & 1
-		w := (x >> 21) & 1
-		p := (x >> 24) & 1
-		if p == 0 && w == 1 {
-			return nil
-		}
-		sign := int8(+1)
-		if u == 0 {
-			sign = -1
-		}
-		mode := arm_AddrMode(uint8(p<<1) | uint8(w^1))
-		return arm_Mem{Base: Rn, Mode: mode, Sign: sign, Index: Rm, Shift: typ, Count: count}
-
-	case arm_arg_mem_R_pm_imm12_offset:
-		// Treat [<Rn>,#+/-<imm12>] like [<Rn>{,#+/-<imm12>}]{!}
-		// by forcing P=1, W=0 (index=false, wback=false).
-		return arm_decodeArg(arm_arg_mem_R_pm_imm12_W, x&^(1<<21)|1<<24)
-
-	case arm_arg_mem_R_pm_imm12_postindex:
-		// Treat [<Rn>],#+/-<imm12> like [<Rn>{,#+/-<imm12>}]{!}
-		// by forcing P=0, W=0 (postindex=true).
-		return arm_decodeArg(arm_arg_mem_R_pm_imm12_W, x&^(1<<24|1<<21))
-
-	case arm_arg_mem_R_pm_imm12_W:
-		Rn := arm_Reg((x >> 16) & (1<<4 - 1))
-		u := (x >> 23) & 1
-		w := (x >> 21) & 1
-		p := (x >> 24) & 1
-		if p == 0 && w == 1 {
-			return nil
-		}
-		sign := int8(+1)
-		if u == 0 {
-			sign = -1
-		}
-		imm := int16(x & (1<<12 - 1))
-		mode := arm_AddrMode(uint8(p<<1) | uint8(w^1))
-		return arm_Mem{Base: Rn, Mode: mode, Offset: int16(sign) * imm}
-
-	case arm_arg_mem_R_pm_imm8_postindex:
-		// Treat [<Rn>],#+/-<imm8> like [<Rn>{,#+/-<imm8>}]{!}
-		// by forcing P=0, W=0 (postindex=true).
-		return arm_decodeArg(arm_arg_mem_R_pm_imm8_W, x&^(1<<24|1<<21))
-
-	case arm_arg_mem_R_pm_imm8_W:
-		Rn := arm_Reg((x >> 16) & (1<<4 - 1))
-		u := (x >> 23) & 1
-		w := (x >> 21) & 1
-		p := (x >> 24) & 1
-		if p == 0 && w == 1 {
-			return nil
-		}
-		sign := int8(+1)
-		if u == 0 {
-			sign = -1
-		}
-		imm := int16((x>>8)&(1<<4-1)<<4 | x&(1<<4-1))
-		mode := arm_AddrMode(uint8(p<<1) | uint8(w^1))
-		return arm_Mem{Base: Rn, Mode: mode, Offset: int16(sign) * imm}
-
-	case arm_arg_mem_R_pm_imm8at0_offset:
-		Rn := arm_Reg((x >> 16) & (1<<4 - 1))
-		u := (x >> 23) & 1
-		sign := int8(+1)
-		if u == 0 {
-			sign = -1
-		}
-		imm := int16(x&(1<<8-1)) << 2
-		return arm_Mem{Base: Rn, Mode: arm_AddrOffset, Offset: int16(sign) * imm}
-
-	case arm_arg_option:
-		return arm_Imm(x & (1<<4 - 1))
-
-	case arm_arg_registers:
-		return arm_RegList(x & (1<<16 - 1))
-
-	case arm_arg_registers2:
-		x &= 1<<16 - 1
-		n := 0
-		for i := 0; i < 16; i++ {
-			if x>>uint(i)&1 != 0 {
-				n++
-			}
-		}
-		if n < 2 {
-			return nil
-		}
-		return arm_RegList(x)
-
-	case arm_arg_registers1:
-		Rt := (x >> 12) & (1<<4 - 1)
-		return arm_RegList(1 << Rt)
-
-	case arm_arg_satimm4:
-		return arm_Imm((x >> 16) & (1<<4 - 1))
-
-	case arm_arg_satimm5:
-		return arm_Imm((x >> 16) & (1<<5 - 1))
-
-	case arm_arg_satimm4m1:
-		return arm_Imm((x>>16)&(1<<4-1) + 1)
-
-	case arm_arg_satimm5m1:
-		return arm_Imm((x>>16)&(1<<5-1) + 1)
-
-	case arm_arg_widthm1:
-		return arm_Imm((x>>16)&(1<<5-1) + 1)
-
-	}
-}
-
-// decodeShift decodes the shift-by-immediate encoded in x.
-func arm_decodeShift(x uint32) (arm_Shift, uint8) {
-	count := (x >> 7) & (1<<5 - 1)
-	typ := arm_Shift((x >> 5) & (1<<2 - 1))
-	switch typ {
-	case arm_ShiftRight, arm_ShiftRightSigned:
-		if count == 0 {
-			count = 32
-		}
-	case arm_RotateRight:
-		if count == 0 {
-			typ = arm_RotateRightExt
-			count = 1
-		}
-	}
-	return typ, uint8(count)
-}
-
-/* gnu.go */
-
-// 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.
-
-var arm_saveDot = strings.NewReplacer(
-	".F16", "_dot_F16",
-	".F32", "_dot_F32",
-	".F64", "_dot_F64",
-	".S32", "_dot_S32",
-	".U32", "_dot_U32",
-	".FXS", "_dot_S",
-	".FXU", "_dot_U",
-	".32", "_dot_32",
-)
-
-// GNUSyntax returns the GNU assembler syntax for the instruction, as defined by GNU binutils.
-// This form typically matches the syntax defined in the ARM Reference Manual.
-func arm_GNUSyntax(inst arm_Inst) string {
-	var buf bytes.Buffer
-	op := inst.Op.String()
-	op = arm_saveDot.Replace(op)
-	op = strings.Replace(op, ".", "", -1)
-	op = strings.Replace(op, "_dot_", ".", -1)
-	op = strings.ToLower(op)
-	buf.WriteString(op)
-	sep := " "
-	for i, arg := range inst.Args {
-		if arg == nil {
-			break
-		}
-		text := arm_gnuArg(&inst, i, arg)
-		if text == "" {
-			continue
-		}
-		buf.WriteString(sep)
-		sep = ", "
-		buf.WriteString(text)
-	}
-	return buf.String()
-}
-
-func arm_gnuArg(inst *arm_Inst, argIndex int, arg arm_Arg) string {
-	switch inst.Op &^ 15 {
-	case arm_LDRD_EQ, arm_LDREXD_EQ, arm_STRD_EQ:
-		if argIndex == 1 {
-			// second argument in consecutive pair not printed
-			return ""
-		}
-	case arm_STREXD_EQ:
-		if argIndex == 2 {
-			// second argument in consecutive pair not printed
-			return ""
-		}
-	}
-
-	switch arg := arg.(type) {
-	case arm_Imm:
-		switch inst.Op &^ 15 {
-		case arm_BKPT_EQ:
-			return fmt.Sprintf("%#04x", uint32(arg))
-		case arm_SVC_EQ:
-			return fmt.Sprintf("%#08x", uint32(arg))
-		}
-		return fmt.Sprintf("#%d", int32(arg))
-
-	case arm_ImmAlt:
-		return fmt.Sprintf("#%d, %d", arg.Val, arg.Rot)
-
-	case arm_Mem:
-		R := arm_gnuArg(inst, -1, arg.Base)
-		X := ""
-		if arg.Sign != 0 {
-			X = ""
-			if arg.Sign < 0 {
-				X = "-"
-			}
-			X += arm_gnuArg(inst, -1, arg.Index)
-			if arg.Shift == arm_ShiftLeft && arg.Count == 0 {
-				// nothing
-			} else if arg.Shift == arm_RotateRightExt {
-				X += ", rrx"
-			} else {
-				X += fmt.Sprintf(", %s #%d", strings.ToLower(arg.Shift.String()), arg.Count)
-			}
-		} else {
-			X = fmt.Sprintf("#%d", arg.Offset)
-		}
-
-		switch arg.Mode {
-		case arm_AddrOffset:
-			if X == "#0" {
-				return fmt.Sprintf("[%s]", R)
-			}
-			return fmt.Sprintf("[%s, %s]", R, X)
-		case arm_AddrPreIndex:
-			return fmt.Sprintf("[%s, %s]!", R, X)
-		case arm_AddrPostIndex:
-			return fmt.Sprintf("[%s], %s", R, X)
-		case arm_AddrLDM:
-			if X == "#0" {
-				return R
-			}
-		case arm_AddrLDM_WB:
-			if X == "#0" {
-				return R + "!"
-			}
-		}
-		return fmt.Sprintf("[%s Mode(%d) %s]", R, int(arg.Mode), X)
-
-	case arm_PCRel:
-		return fmt.Sprintf(".%+#x", int32(arg)+4)
-
-	case arm_Reg:
-		switch inst.Op &^ 15 {
-		case arm_LDREX_EQ:
-			if argIndex == 0 {
-				return fmt.Sprintf("r%d", int32(arg))
-			}
-		}
-		switch arg {
-		case arm_R10:
-			return "sl"
-		case arm_R11:
-			return "fp"
-		case arm_R12:
-			return "ip"
-		}
-
-	case arm_RegList:
-		var buf bytes.Buffer
-		fmt.Fprintf(&buf, "{")
-		sep := ""
-		for i := 0; i < 16; i++ {
-			if arg&(1<<uint(i)) != 0 {
-				fmt.Fprintf(&buf, "%s%s", sep, arm_gnuArg(inst, -1, arm_Reg(i)))
-				sep = ", "
-			}
-		}
-		fmt.Fprintf(&buf, "}")
-		return buf.String()
-
-	case arm_RegShift:
-		if arg.Shift == arm_ShiftLeft && arg.Count == 0 {
-			return arm_gnuArg(inst, -1, arg.Reg)
-		}
-		if arg.Shift == arm_RotateRightExt {
-			return arm_gnuArg(inst, -1, arg.Reg) + ", rrx"
-		}
-		return fmt.Sprintf("%s, %s #%d", arm_gnuArg(inst, -1, arg.Reg), strings.ToLower(arg.Shift.String()), arg.Count)
-
-	case arm_RegShiftReg:
-		return fmt.Sprintf("%s, %s %s", arm_gnuArg(inst, -1, arg.Reg), strings.ToLower(arg.Shift.String()), arm_gnuArg(inst, -1, arg.RegCount))
-
-	}
-	return strings.ToLower(arg.String())
-}
-
-/* inst.go */
-
-// 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.
-
-// A Mode is an instruction execution mode.
-type arm_Mode int
-
-const (
-	_ arm_Mode = iota
-	arm_ModeARM
-	arm_ModeThumb
-)
-
-func (m arm_Mode) String() string {
-	switch m {
-	case arm_ModeARM:
-		return "ARM"
-	case arm_ModeThumb:
-		return "Thumb"
-	}
-	return fmt.Sprintf("Mode(%d)", int(m))
-}
-
-// An Op is an ARM opcode.
-type arm_Op uint16
-
-// NOTE: The actual Op values are defined in tables.go.
-// They are chosen to simplify instruction decoding and
-// are not a dense packing from 0 to N, although the
-// density is high, probably at least 90%.
-
-func (op arm_Op) String() string {
-	if op >= arm_Op(len(arm_opstr)) || arm_opstr[op] == "" {
-		return fmt.Sprintf("Op(%d)", int(op))
-	}
-	return arm_opstr[op]
-}
-
-// An Inst is a single instruction.
-type arm_Inst struct {
-	Op   arm_Op   // Opcode mnemonic
-	Enc  uint32   // Raw encoding bits.
-	Len  int      // Length of encoding in bytes.
-	Args arm_Args // Instruction arguments, in ARM manual order.
-}
-
-func (i arm_Inst) String() string {
-	var buf bytes.Buffer
-	buf.WriteString(i.Op.String())
-	for j, arg := range i.Args {
-		if arg == nil {
-			break
-		}
-		if j == 0 {
-			buf.WriteString(" ")
-		} else {
-			buf.WriteString(", ")
-		}
-		buf.WriteString(arg.String())
-	}
-	return buf.String()
-}
-
-// An Args holds the instruction arguments.
-// If an instruction has fewer than 4 arguments,
-// the final elements in the array are nil.
-type arm_Args [4]arm_Arg
-
-// An Arg is a single instruction argument, one of these types:
-// Endian, Imm, Mem, PCRel, Reg, RegList, RegShift, RegShiftReg.
-type arm_Arg interface {
-	IsArg()
-	String() string
-}
-
-type arm_Float32Imm float32
-
-func (arm_Float32Imm) IsArg() {}
-
-func (f arm_Float32Imm) String() string {
-	return fmt.Sprintf("#%v", float32(f))
-}
-
-type arm_Float64Imm float32
-
-func (arm_Float64Imm) IsArg() {}
-
-func (f arm_Float64Imm) String() string {
-	return fmt.Sprintf("#%v", float64(f))
-}
-
-// An Imm is an integer constant.
-type arm_Imm uint32
-
-func (arm_Imm) IsArg() {}
-
-func (i arm_Imm) String() string {
-	return fmt.Sprintf("#%#x", uint32(i))
-}
-
-// A ImmAlt is an alternate encoding of an integer constant.
-type arm_ImmAlt struct {
-	Val uint8
-	Rot uint8
-}
-
-func (arm_ImmAlt) IsArg() {}
-
-func (i arm_ImmAlt) Imm() arm_Imm {
-	v := uint32(i.Val)
-	r := uint(i.Rot)
-	return arm_Imm(v>>r | v<<(32-r))
-}
-
-func (i arm_ImmAlt) String() string {
-	return fmt.Sprintf("#%#x, %d", i.Val, i.Rot)
-}
-
-// A Label is a text (code) address.
-type arm_Label uint32
-
-func (arm_Label) IsArg() {}
-
-func (i arm_Label) String() string {
-	return fmt.Sprintf("%#x", uint32(i))
-}
-
-// A Reg is a single register.
-// The zero value denotes R0, not the absence of a register.
-type arm_Reg uint8
-
-const (
-	arm_R0 arm_Reg = iota
-	arm_R1
-	arm_R2
-	arm_R3
-	arm_R4
-	arm_R5
-	arm_R6
-	arm_R7
-	arm_R8
-	arm_R9
-	arm_R10
-	arm_R11
-	arm_R12
-	arm_R13
-	arm_R14
-	arm_R15
-
-	arm_S0
-	arm_S1
-	arm_S2
-	arm_S3
-	arm_S4
-	arm_S5
-	arm_S6
-	arm_S7
-	arm_S8
-	arm_S9
-	arm_S10
-	arm_S11
-	arm_S12
-	arm_S13
-	arm_S14
-	arm_S15
-	arm_S16
-	arm_S17
-	arm_S18
-	arm_S19
-	arm_S20
-	arm_S21
-	arm_S22
-	arm_S23
-	arm_S24
-	arm_S25
-	arm_S26
-	arm_S27
-	arm_S28
-	arm_S29
-	arm_S30
-	arm_S31
-
-	arm_D0
-	arm_D1
-	arm_D2
-	arm_D3
-	arm_D4
-	arm_D5
-	arm_D6
-	arm_D7
-	arm_D8
-	arm_D9
-	arm_D10
-	arm_D11
-	arm_D12
-	arm_D13
-	arm_D14
-	arm_D15
-	arm_D16
-	arm_D17
-	arm_D18
-	arm_D19
-	arm_D20
-	arm_D21
-	arm_D22
-	arm_D23
-	arm_D24
-	arm_D25
-	arm_D26
-	arm_D27
-	arm_D28
-	arm_D29
-	arm_D30
-	arm_D31
-
-	arm_APSR
-	arm_APSR_nzcv
-	arm_FPSCR
-
-	arm_SP = arm_R13
-	arm_LR = arm_R14
-	arm_PC = arm_R15
-)
-
-func (arm_Reg) IsArg() {}
-
-func (r arm_Reg) String() string {
-	switch r {
-	case arm_APSR:
-		return "APSR"
-	case arm_APSR_nzcv:
-		return "APSR_nzcv"
-	case arm_FPSCR:
-		return "FPSCR"
-	case arm_SP:
-		return "SP"
-	case arm_PC:
-		return "PC"
-	case arm_LR:
-		return "LR"
-	}
-	if arm_R0 <= r && r <= arm_R15 {
-		return fmt.Sprintf("R%d", int(r-arm_R0))
-	}
-	if arm_S0 <= r && r <= arm_S31 {
-		return fmt.Sprintf("S%d", int(r-arm_S0))
-	}
-	if arm_D0 <= r && r <= arm_D31 {
-		return fmt.Sprintf("D%d", int(r-arm_D0))
-	}
-	return fmt.Sprintf("Reg(%d)", int(r))
-}
-
-// A RegX represents a fraction of a multi-value register.
-// The Index field specifies the index number,
-// but the size of the fraction is not specified.
-// It must be inferred from the instruction and the register type.
-// For example, in a VMOV instruction, RegX{D5, 1} represents
-// the top 32 bits of the 64-bit D5 register.
-type arm_RegX struct {
-	Reg   arm_Reg
-	Index int
-}
-
-func (arm_RegX) IsArg() {}
-
-func (r arm_RegX) String() string {
-	return fmt.Sprintf("%s[%d]", r.Reg, r.Index)
-}
-
-// A RegList is a register list.
-// Bits at indexes x = 0 through 15 indicate whether the corresponding Rx register is in the list.
-type arm_RegList uint16
-
-func (arm_RegList) IsArg() {}
-
-func (r arm_RegList) String() string {
-	var buf bytes.Buffer
-	fmt.Fprintf(&buf, "{")
-	sep := ""
-	for i := 0; i < 16; i++ {
-		if r&(1<<uint(i)) != 0 {
-			fmt.Fprintf(&buf, "%s%s", sep, arm_Reg(i).String())
-			sep = ","
-		}
-	}
-	fmt.Fprintf(&buf, "}")
-	return buf.String()
-}
-
-// An Endian is the argument to the SETEND instruction.
-type arm_Endian uint8
-
-const (
-	arm_LittleEndian arm_Endian = 0
-	arm_BigEndian    arm_Endian = 1
-)
-
-func (arm_Endian) IsArg() {}
-
-func (e arm_Endian) String() string {
-	if e != 0 {
-		return "BE"
-	}
-	return "LE"
-}
-
-// A Shift describes an ARM shift operation.
-type arm_Shift uint8
-
-const (
-	arm_ShiftLeft        arm_Shift = 0 // left shift
-	arm_ShiftRight       arm_Shift = 1 // logical (unsigned) right shift
-	arm_ShiftRightSigned arm_Shift = 2 // arithmetic (signed) right shift
-	arm_RotateRight      arm_Shift = 3 // right rotate
-	arm_RotateRightExt   arm_Shift = 4 // right rotate through carry (Count will always be 1)
-)
-
-var arm_shiftName = [...]string{
-	"LSL", "LSR", "ASR", "ROR", "RRX",
-}
-
-func (s arm_Shift) String() string {
-	if s < 5 {
-		return arm_shiftName[s]
-	}
-	return fmt.Sprintf("Shift(%d)", int(s))
-}
-
-// A RegShift is a register shifted by a constant.
-type arm_RegShift struct {
-	Reg   arm_Reg
-	Shift arm_Shift
-	Count uint8
-}
-
-func (arm_RegShift) IsArg() {}
-
-func (r arm_RegShift) String() string {
-	return fmt.Sprintf("%s %s #%d", r.Reg, r.Shift, r.Count)
-}
-
-// A RegShiftReg is a register shifted by a register.
-type arm_RegShiftReg struct {
-	Reg      arm_Reg
-	Shift    arm_Shift
-	RegCount arm_Reg
-}
-
-func (arm_RegShiftReg) IsArg() {}
-
-func (r arm_RegShiftReg) String() string {
-	return fmt.Sprintf("%s %s %s", r.Reg, r.Shift, r.RegCount)
-}
-
-// A PCRel describes a memory address (usually a code label)
-// as a distance relative to the program counter.
-// TODO(rsc): Define which program counter (PC+4? PC+8? PC?).
-type arm_PCRel int32
-
-func (arm_PCRel) IsArg() {}
-
-func (r arm_PCRel) String() string {
-	return fmt.Sprintf("PC%+#x", int32(r))
-}
-
-// An AddrMode is an ARM addressing mode.
-type arm_AddrMode uint8
-
-const (
-	_                 arm_AddrMode = iota
-	arm_AddrPostIndex              // [R], X – use address R, set R = R + X
-	arm_AddrPreIndex               // [R, X]! – use address R + X, set R = R + X
-	arm_AddrOffset                 // [R, X] – use address R + X
-	arm_AddrLDM                    // R – [R] but formats as R, for LDM/STM only
-	arm_AddrLDM_WB                 // R! - [R], X where X is instruction-specific amount, for LDM/STM only
-)
-
-// A Mem is a memory reference made up of a base R and index expression X.
-// The effective memory address is R or R+X depending on AddrMode.
-// The index expression is X = Sign*(Index Shift Count) + Offset,
-// but in any instruction either Sign = 0 or Offset = 0.
-type arm_Mem struct {
-	Base   arm_Reg
-	Mode   arm_AddrMode
-	Sign   int8
-	Index  arm_Reg
-	Shift  arm_Shift
-	Count  uint8
-	Offset int16
-}
-
-func (arm_Mem) IsArg() {}
-
-func (m arm_Mem) String() string {
-	R := m.Base.String()
-	X := ""
-	if m.Sign != 0 {
-		X = "+"
-		if m.Sign < 0 {
-			X = "-"
-		}
-		X += m.Index.String()
-		if m.Shift != arm_ShiftLeft || m.Count != 0 {
-			X += fmt.Sprintf(", %s #%d", m.Shift, m.Count)
-		}
-	} else {
-		X = fmt.Sprintf("#%d", m.Offset)
-	}
-
-	switch m.Mode {
-	case arm_AddrOffset:
-		if X == "#0" {
-			return fmt.Sprintf("[%s]", R)
-		}
-		return fmt.Sprintf("[%s, %s]", R, X)
-	case arm_AddrPreIndex:
-		return fmt.Sprintf("[%s, %s]!", R, X)
-	case arm_AddrPostIndex:
-		return fmt.Sprintf("[%s], %s", R, X)
-	case arm_AddrLDM:
-		if X == "#0" {
-			return R
-		}
-	case arm_AddrLDM_WB:
-		if X == "#0" {
-			return R + "!"
-		}
-	}
-	return fmt.Sprintf("[%s Mode(%d) %s]", R, int(m.Mode), X)
-}
-
-/* plan9x.go */
-
-// 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.
-
-// plan9Syntax returns the Go assembler syntax for the instruction.
-// The syntax was originally defined by Plan 9.
-// The pc is the program counter of the instruction, used for expanding
-// PC-relative addresses into absolute ones.
-// The symname function queries the symbol table for the program
-// being disassembled. Given a target address it returns the name and base
-// address of the symbol containing the target, if any; otherwise it returns "", 0.
-// The reader r should read from the text segment using text addresses
-// as offsets; it is used to display pc-relative loads as constant loads.
-func arm_plan9Syntax(inst arm_Inst, pc uint64, symname func(uint64) (string, uint64), text io.ReaderAt) string {
-	if symname == nil {
-		symname = func(uint64) (string, uint64) { return "", 0 }
-	}
-
-	var args []string
-	for _, a := range inst.Args {
-		if a == nil {
-			break
-		}
-		args = append(args, arm_plan9Arg(&inst, pc, symname, a))
-	}
-
-	op := inst.Op.String()
-
-	switch inst.Op &^ 15 {
-	case arm_LDR_EQ, arm_LDRB_EQ, arm_LDRH_EQ:
-		// Check for RET
-		reg, _ := inst.Args[0].(arm_Reg)
-		mem, _ := inst.Args[1].(arm_Mem)
-		if inst.Op&^15 == arm_LDR_EQ && reg == arm_R15 && mem.Base == arm_SP && mem.Sign == 0 && mem.Mode == arm_AddrPostIndex {
-			return fmt.Sprintf("RET%s #%d", op[3:], mem.Offset)
-		}
-
-		// Check for PC-relative load.
-		if mem.Base == arm_PC && mem.Sign == 0 && mem.Mode == arm_AddrOffset && text != nil {
-			addr := uint32(pc) + 8 + uint32(mem.Offset)
-			buf := make([]byte, 4)
-			switch inst.Op &^ 15 {
-			case arm_LDRB_EQ:
-				if _, err := text.ReadAt(buf[:1], int64(addr)); err != nil {
-					break
-				}
-				args[1] = fmt.Sprintf("$%#x", buf[0])
-
-			case arm_LDRH_EQ:
-				if _, err := text.ReadAt(buf[:2], int64(addr)); err != nil {
-					break
-				}
-				args[1] = fmt.Sprintf("$%#x", binary.LittleEndian.Uint16(buf))
-
-			case arm_LDR_EQ:
-				if _, err := text.ReadAt(buf, int64(addr)); err != nil {
-					break
-				}
-				x := binary.LittleEndian.Uint32(buf)
-				if s, base := symname(uint64(x)); s != "" && uint64(x) == base {
-					args[1] = fmt.Sprintf("$%s(SB)", s)
-				} else {
-					args[1] = fmt.Sprintf("$%#x", x)
-				}
-			}
-		}
-	}
-
-	// Move addressing mode into opcode suffix.
-	suffix := ""
-	switch inst.Op &^ 15 {
-	case arm_LDR_EQ, arm_LDRB_EQ, arm_LDRH_EQ, arm_STR_EQ, arm_STRB_EQ, arm_STRH_EQ:
-		mem, _ := inst.Args[1].(arm_Mem)
-		switch mem.Mode {
-		case arm_AddrOffset, arm_AddrLDM:
-			// no suffix
-		case arm_AddrPreIndex, arm_AddrLDM_WB:
-			suffix = ".W"
-		case arm_AddrPostIndex:
-			suffix = ".P"
-		}
-		off := ""
-		if mem.Offset != 0 {
-			off = fmt.Sprintf("%#x", mem.Offset)
-		}
-		base := fmt.Sprintf("(R%d)", int(mem.Base))
-		index := ""
-		if mem.Sign != 0 {
-			sign := ""
-			if mem.Sign < 0 {
-				sign = ""
-			}
-			shift := ""
-			if mem.Count != 0 {
-				shift = fmt.Sprintf("%s%d", arm_plan9Shift[mem.Shift], mem.Count)
-			}
-			index = fmt.Sprintf("(%sR%d%s)", sign, int(mem.Index), shift)
-		}
-		args[1] = off + base + index
-	}
-
-	// Reverse args, placing dest last.
-	for i, j := 0, len(args)-1; i < j; i, j = i+1, j-1 {
-		args[i], args[j] = args[j], args[i]
-	}
-
-	switch inst.Op &^ 15 {
-	case arm_MOV_EQ:
-		op = "MOVW" + op[3:]
-
-	case arm_LDR_EQ:
-		op = "MOVW" + op[3:] + suffix
-	case arm_LDRB_EQ:
-		op = "MOVB" + op[4:] + suffix
-	case arm_LDRH_EQ:
-		op = "MOVH" + op[4:] + suffix
-
-	case arm_STR_EQ:
-		op = "MOVW" + op[3:] + suffix
-		args[0], args[1] = args[1], args[0]
-	case arm_STRB_EQ:
-		op = "MOVB" + op[4:] + suffix
-		args[0], args[1] = args[1], args[0]
-	case arm_STRH_EQ:
-		op = "MOVH" + op[4:] + suffix
-		args[0], args[1] = args[1], args[0]
-	}
-
-	if args != nil {
-		op += " " + strings.Join(args, ", ")
-	}
-
-	return op
-}
-
-// assembler syntax for the various shifts.
-// @x> is a lie; the assembler uses @> 0
-// instead of @x> 1, but i wanted to be clear that it
-// was a different operation (rotate right extended, not rotate right).
-var arm_plan9Shift = []string{"<<", ">>", "->", "@>", "@x>"}
-
-func arm_plan9Arg(inst *arm_Inst, pc uint64, symname func(uint64) (string, uint64), arg arm_Arg) string {
-	switch a := arg.(type) {
-	case arm_Endian:
-
-	case arm_Imm:
-		return fmt.Sprintf("$%d", int(a))
-
-	case arm_Mem:
-
-	case arm_PCRel:
-		addr := uint32(pc) + 8 + uint32(a)
-		if s, base := symname(uint64(addr)); s != "" && uint64(addr) == base {
-			return fmt.Sprintf("%s(SB)", s)
-		}
-		return fmt.Sprintf("%#x", addr)
-
-	case arm_Reg:
-		if a < 16 {
-			return fmt.Sprintf("R%d", int(a))
-		}
-
-	case arm_RegList:
-		var buf bytes.Buffer
-		start := -2
-		end := -2
-		fmt.Fprintf(&buf, "[")
-		flush := func() {
-			if start >= 0 {
-				if buf.Len() > 1 {
-					fmt.Fprintf(&buf, ",")
-				}
-				if start == end {
-					fmt.Fprintf(&buf, "R%d", start)
-				} else {
-					fmt.Fprintf(&buf, "R%d-R%d", start, end)
-				}
-			}
-		}
-		for i := 0; i < 16; i++ {
-			if a&(1<<uint(i)) != 0 {
-				if i == end+1 {
-					end++
-					continue
-				}
-				start = i
-				end = i
-			}
-		}
-		flush()
-		fmt.Fprintf(&buf, "]")
-		return buf.String()
-
-	case arm_RegShift:
-		return fmt.Sprintf("R%d%s$%d", int(a.Reg), arm_plan9Shift[a.Shift], int(a.Count))
-
-	case arm_RegShiftReg:
-		return fmt.Sprintf("R%d%sR%d", int(a.Reg), arm_plan9Shift[a.Shift], int(a.RegCount))
-	}
-	return strings.ToUpper(arg.String())
-}
-
-/* tables.go */
-
-const (
-	_ arm_Op = iota
-	_
-	_
-	_
-	_
-	_
-	_
-	_
-	_
-	_
-	_
-	_
-	_
-	_
-	_
-	_
-	arm_ADC_EQ
-	arm_ADC_NE
-	arm_ADC_CS
-	arm_ADC_CC
-	arm_ADC_MI
-	arm_ADC_PL
-	arm_ADC_VS
-	arm_ADC_VC
-	arm_ADC_HI
-	arm_ADC_LS
-	arm_ADC_GE
-	arm_ADC_LT
-	arm_ADC_GT
-	arm_ADC_LE
-	arm_ADC
-	arm_ADC_ZZ
-	arm_ADC_S_EQ
-	arm_ADC_S_NE
-	arm_ADC_S_CS
-	arm_ADC_S_CC
-	arm_ADC_S_MI
-	arm_ADC_S_PL
-	arm_ADC_S_VS
-	arm_ADC_S_VC
-	arm_ADC_S_HI
-	arm_ADC_S_LS
-	arm_ADC_S_GE
-	arm_ADC_S_LT
-	arm_ADC_S_GT
-	arm_ADC_S_LE
-	arm_ADC_S
-	arm_ADC_S_ZZ
-	arm_ADD_EQ
-	arm_ADD_NE
-	arm_ADD_CS
-	arm_ADD_CC
-	arm_ADD_MI
-	arm_ADD_PL
-	arm_ADD_VS
-	arm_ADD_VC
-	arm_ADD_HI
-	arm_ADD_LS
-	arm_ADD_GE
-	arm_ADD_LT
-	arm_ADD_GT
-	arm_ADD_LE
-	arm_ADD
-	arm_ADD_ZZ
-	arm_ADD_S_EQ
-	arm_ADD_S_NE
-	arm_ADD_S_CS
-	arm_ADD_S_CC
-	arm_ADD_S_MI
-	arm_ADD_S_PL
-	arm_ADD_S_VS
-	arm_ADD_S_VC
-	arm_ADD_S_HI
-	arm_ADD_S_LS
-	arm_ADD_S_GE
-	arm_ADD_S_LT
-	arm_ADD_S_GT
-	arm_ADD_S_LE
-	arm_ADD_S
-	arm_ADD_S_ZZ
-	arm_AND_EQ
-	arm_AND_NE
-	arm_AND_CS
-	arm_AND_CC
-	arm_AND_MI
-	arm_AND_PL
-	arm_AND_VS
-	arm_AND_VC
-	arm_AND_HI
-	arm_AND_LS
-	arm_AND_GE
-	arm_AND_LT
-	arm_AND_GT
-	arm_AND_LE
-	arm_AND
-	arm_AND_ZZ
-	arm_AND_S_EQ
-	arm_AND_S_NE
-	arm_AND_S_CS
-	arm_AND_S_CC
-	arm_AND_S_MI
-	arm_AND_S_PL
-	arm_AND_S_VS
-	arm_AND_S_VC
-	arm_AND_S_HI
-	arm_AND_S_LS
-	arm_AND_S_GE
-	arm_AND_S_LT
-	arm_AND_S_GT
-	arm_AND_S_LE
-	arm_AND_S
-	arm_AND_S_ZZ
-	arm_ASR_EQ
-	arm_ASR_NE
-	arm_ASR_CS
-	arm_ASR_CC
-	arm_ASR_MI
-	arm_ASR_PL
-	arm_ASR_VS
-	arm_ASR_VC
-	arm_ASR_HI
-	arm_ASR_LS
-	arm_ASR_GE
-	arm_ASR_LT
-	arm_ASR_GT
-	arm_ASR_LE
-	arm_ASR
-	arm_ASR_ZZ
-	arm_ASR_S_EQ
-	arm_ASR_S_NE
-	arm_ASR_S_CS
-	arm_ASR_S_CC
-	arm_ASR_S_MI
-	arm_ASR_S_PL
-	arm_ASR_S_VS
-	arm_ASR_S_VC
-	arm_ASR_S_HI
-	arm_ASR_S_LS
-	arm_ASR_S_GE
-	arm_ASR_S_LT
-	arm_ASR_S_GT
-	arm_ASR_S_LE
-	arm_ASR_S
-	arm_ASR_S_ZZ
-	arm_B_EQ
-	arm_B_NE
-	arm_B_CS
-	arm_B_CC
-	arm_B_MI
-	arm_B_PL
-	arm_B_VS
-	arm_B_VC
-	arm_B_HI
-	arm_B_LS
-	arm_B_GE
-	arm_B_LT
-	arm_B_GT
-	arm_B_LE
-	arm_B
-	arm_B_ZZ
-	arm_BFC_EQ
-	arm_BFC_NE
-	arm_BFC_CS
-	arm_BFC_CC
-	arm_BFC_MI
-	arm_BFC_PL
-	arm_BFC_VS
-	arm_BFC_VC
-	arm_BFC_HI
-	arm_BFC_LS
-	arm_BFC_GE
-	arm_BFC_LT
-	arm_BFC_GT
-	arm_BFC_LE
-	arm_BFC
-	arm_BFC_ZZ
-	arm_BFI_EQ
-	arm_BFI_NE
-	arm_BFI_CS
-	arm_BFI_CC
-	arm_BFI_MI
-	arm_BFI_PL
-	arm_BFI_VS
-	arm_BFI_VC
-	arm_BFI_HI
-	arm_BFI_LS
-	arm_BFI_GE
-	arm_BFI_LT
-	arm_BFI_GT
-	arm_BFI_LE
-	arm_BFI
-	arm_BFI_ZZ
-	arm_BIC_EQ
-	arm_BIC_NE
-	arm_BIC_CS
-	arm_BIC_CC
-	arm_BIC_MI
-	arm_BIC_PL
-	arm_BIC_VS
-	arm_BIC_VC
-	arm_BIC_HI
-	arm_BIC_LS
-	arm_BIC_GE
-	arm_BIC_LT
-	arm_BIC_GT
-	arm_BIC_LE
-	arm_BIC
-	arm_BIC_ZZ
-	arm_BIC_S_EQ
-	arm_BIC_S_NE
-	arm_BIC_S_CS
-	arm_BIC_S_CC
-	arm_BIC_S_MI
-	arm_BIC_S_PL
-	arm_BIC_S_VS
-	arm_BIC_S_VC
-	arm_BIC_S_HI
-	arm_BIC_S_LS
-	arm_BIC_S_GE
-	arm_BIC_S_LT
-	arm_BIC_S_GT
-	arm_BIC_S_LE
-	arm_BIC_S
-	arm_BIC_S_ZZ
-	arm_BKPT_EQ
-	arm_BKPT_NE
-	arm_BKPT_CS
-	arm_BKPT_CC
-	arm_BKPT_MI
-	arm_BKPT_PL
-	arm_BKPT_VS
-	arm_BKPT_VC
-	arm_BKPT_HI
-	arm_BKPT_LS
-	arm_BKPT_GE
-	arm_BKPT_LT
-	arm_BKPT_GT
-	arm_BKPT_LE
-	arm_BKPT
-	arm_BKPT_ZZ
-	arm_BL_EQ
-	arm_BL_NE
-	arm_BL_CS
-	arm_BL_CC
-	arm_BL_MI
-	arm_BL_PL
-	arm_BL_VS
-	arm_BL_VC
-	arm_BL_HI
-	arm_BL_LS
-	arm_BL_GE
-	arm_BL_LT
-	arm_BL_GT
-	arm_BL_LE
-	arm_BL
-	arm_BL_ZZ
-	arm_BLX_EQ
-	arm_BLX_NE
-	arm_BLX_CS
-	arm_BLX_CC
-	arm_BLX_MI
-	arm_BLX_PL
-	arm_BLX_VS
-	arm_BLX_VC
-	arm_BLX_HI
-	arm_BLX_LS
-	arm_BLX_GE
-	arm_BLX_LT
-	arm_BLX_GT
-	arm_BLX_LE
-	arm_BLX
-	arm_BLX_ZZ
-	arm_BX_EQ
-	arm_BX_NE
-	arm_BX_CS
-	arm_BX_CC
-	arm_BX_MI
-	arm_BX_PL
-	arm_BX_VS
-	arm_BX_VC
-	arm_BX_HI
-	arm_BX_LS
-	arm_BX_GE
-	arm_BX_LT
-	arm_BX_GT
-	arm_BX_LE
-	arm_BX
-	arm_BX_ZZ
-	arm_BXJ_EQ
-	arm_BXJ_NE
-	arm_BXJ_CS
-	arm_BXJ_CC
-	arm_BXJ_MI
-	arm_BXJ_PL
-	arm_BXJ_VS
-	arm_BXJ_VC
-	arm_BXJ_HI
-	arm_BXJ_LS
-	arm_BXJ_GE
-	arm_BXJ_LT
-	arm_BXJ_GT
-	arm_BXJ_LE
-	arm_BXJ
-	arm_BXJ_ZZ
-	arm_CLREX
-	_
-	_
-	_
-	_
-	_
-	_
-	_
-	_
-	_
-	_
-	_
-	_
-	_
-	_
-	_
-	arm_CLZ_EQ
-	arm_CLZ_NE
-	arm_CLZ_CS
-	arm_CLZ_CC
-	arm_CLZ_MI
-	arm_CLZ_PL
-	arm_CLZ_VS
-	arm_CLZ_VC
-	arm_CLZ_HI
-	arm_CLZ_LS
-	arm_CLZ_GE
-	arm_CLZ_LT
-	arm_CLZ_GT
-	arm_CLZ_LE
-	arm_CLZ
-	arm_CLZ_ZZ
-	arm_CMN_EQ
-	arm_CMN_NE
-	arm_CMN_CS
-	arm_CMN_CC
-	arm_CMN_MI
-	arm_CMN_PL
-	arm_CMN_VS
-	arm_CMN_VC
-	arm_CMN_HI
-	arm_CMN_LS
-	arm_CMN_GE
-	arm_CMN_LT
-	arm_CMN_GT
-	arm_CMN_LE
-	arm_CMN
-	arm_CMN_ZZ
-	arm_CMP_EQ
-	arm_CMP_NE
-	arm_CMP_CS
-	arm_CMP_CC
-	arm_CMP_MI
-	arm_CMP_PL
-	arm_CMP_VS
-	arm_CMP_VC
-	arm_CMP_HI
-	arm_CMP_LS
-	arm_CMP_GE
-	arm_CMP_LT
-	arm_CMP_GT
-	arm_CMP_LE
-	arm_CMP
-	arm_CMP_ZZ
-	arm_DBG_EQ
-	arm_DBG_NE
-	arm_DBG_CS
-	arm_DBG_CC
-	arm_DBG_MI
-	arm_DBG_PL
-	arm_DBG_VS
-	arm_DBG_VC
-	arm_DBG_HI
-	arm_DBG_LS
-	arm_DBG_GE
-	arm_DBG_LT
-	arm_DBG_GT
-	arm_DBG_LE
-	arm_DBG
-	arm_DBG_ZZ
-	arm_DMB
-	arm_DSB
-	_
-	_
-	_
-	_
-	_
-	_
-	_
-	_
-	_
-	_
-	_
-	_
-	_
-	_
-	arm_EOR_EQ
-	arm_EOR_NE
-	arm_EOR_CS
-	arm_EOR_CC
-	arm_EOR_MI
-	arm_EOR_PL
-	arm_EOR_VS
-	arm_EOR_VC
-	arm_EOR_HI
-	arm_EOR_LS
-	arm_EOR_GE
-	arm_EOR_LT
-	arm_EOR_GT
-	arm_EOR_LE
-	arm_EOR
-	arm_EOR_ZZ
-	arm_EOR_S_EQ
-	arm_EOR_S_NE
-	arm_EOR_S_CS
-	arm_EOR_S_CC
-	arm_EOR_S_MI
-	arm_EOR_S_PL
-	arm_EOR_S_VS
-	arm_EOR_S_VC
-	arm_EOR_S_HI
-	arm_EOR_S_LS
-	arm_EOR_S_GE
-	arm_EOR_S_LT
-	arm_EOR_S_GT
-	arm_EOR_S_LE
-	arm_EOR_S
-	arm_EOR_S_ZZ
-	arm_ISB
-	_
-	_
-	_
-	_
-	_
-	_
-	_
-	_
-	_
-	_
-	_
-	_
-	_
-	_
-	_
-	arm_LDM_EQ
-	arm_LDM_NE
-	arm_LDM_CS
-	arm_LDM_CC
-	arm_LDM_MI
-	arm_LDM_PL
-	arm_LDM_VS
-	arm_LDM_VC
-	arm_LDM_HI
-	arm_LDM_LS
-	arm_LDM_GE
-	arm_LDM_LT
-	arm_LDM_GT
-	arm_LDM_LE
-	arm_LDM
-	arm_LDM_ZZ
-	arm_LDMDA_EQ
-	arm_LDMDA_NE
-	arm_LDMDA_CS
-	arm_LDMDA_CC
-	arm_LDMDA_MI
-	arm_LDMDA_PL
-	arm_LDMDA_VS
-	arm_LDMDA_VC
-	arm_LDMDA_HI
-	arm_LDMDA_LS
-	arm_LDMDA_GE
-	arm_LDMDA_LT
-	arm_LDMDA_GT
-	arm_LDMDA_LE
-	arm_LDMDA
-	arm_LDMDA_ZZ
-	arm_LDMDB_EQ
-	arm_LDMDB_NE
-	arm_LDMDB_CS
-	arm_LDMDB_CC
-	arm_LDMDB_MI
-	arm_LDMDB_PL
-	arm_LDMDB_VS
-	arm_LDMDB_VC
-	arm_LDMDB_HI
-	arm_LDMDB_LS
-	arm_LDMDB_GE
-	arm_LDMDB_LT
-	arm_LDMDB_GT
-	arm_LDMDB_LE
-	arm_LDMDB
-	arm_LDMDB_ZZ
-	arm_LDMIB_EQ
-	arm_LDMIB_NE
-	arm_LDMIB_CS
-	arm_LDMIB_CC
-	arm_LDMIB_MI
-	arm_LDMIB_PL
-	arm_LDMIB_VS
-	arm_LDMIB_VC
-	arm_LDMIB_HI
-	arm_LDMIB_LS
-	arm_LDMIB_GE
-	arm_LDMIB_LT
-	arm_LDMIB_GT
-	arm_LDMIB_LE
-	arm_LDMIB
-	arm_LDMIB_ZZ
-	arm_LDR_EQ
-	arm_LDR_NE
-	arm_LDR_CS
-	arm_LDR_CC
-	arm_LDR_MI
-	arm_LDR_PL
-	arm_LDR_VS
-	arm_LDR_VC
-	arm_LDR_HI
-	arm_LDR_LS
-	arm_LDR_GE
-	arm_LDR_LT
-	arm_LDR_GT
-	arm_LDR_LE
-	arm_LDR
-	arm_LDR_ZZ
-	arm_LDRB_EQ
-	arm_LDRB_NE
-	arm_LDRB_CS
-	arm_LDRB_CC
-	arm_LDRB_MI
-	arm_LDRB_PL
-	arm_LDRB_VS
-	arm_LDRB_VC
-	arm_LDRB_HI
-	arm_LDRB_LS
-	arm_LDRB_GE
-	arm_LDRB_LT
-	arm_LDRB_GT
-	arm_LDRB_LE
-	arm_LDRB
-	arm_LDRB_ZZ
-	arm_LDRBT_EQ
-	arm_LDRBT_NE
-	arm_LDRBT_CS
-	arm_LDRBT_CC
-	arm_LDRBT_MI
-	arm_LDRBT_PL
-	arm_LDRBT_VS
-	arm_LDRBT_VC
-	arm_LDRBT_HI
-	arm_LDRBT_LS
-	arm_LDRBT_GE
-	arm_LDRBT_LT
-	arm_LDRBT_GT
-	arm_LDRBT_LE
-	arm_LDRBT
-	arm_LDRBT_ZZ
-	arm_LDRD_EQ
-	arm_LDRD_NE
-	arm_LDRD_CS
-	arm_LDRD_CC
-	arm_LDRD_MI
-	arm_LDRD_PL
-	arm_LDRD_VS
-	arm_LDRD_VC
-	arm_LDRD_HI
-	arm_LDRD_LS
-	arm_LDRD_GE
-	arm_LDRD_LT
-	arm_LDRD_GT
-	arm_LDRD_LE
-	arm_LDRD
-	arm_LDRD_ZZ
-	arm_LDREX_EQ
-	arm_LDREX_NE
-	arm_LDREX_CS
-	arm_LDREX_CC
-	arm_LDREX_MI
-	arm_LDREX_PL
-	arm_LDREX_VS
-	arm_LDREX_VC
-	arm_LDREX_HI
-	arm_LDREX_LS
-	arm_LDREX_GE
-	arm_LDREX_LT
-	arm_LDREX_GT
-	arm_LDREX_LE
-	arm_LDREX
-	arm_LDREX_ZZ
-	arm_LDREXB_EQ
-	arm_LDREXB_NE
-	arm_LDREXB_CS
-	arm_LDREXB_CC
-	arm_LDREXB_MI
-	arm_LDREXB_PL
-	arm_LDREXB_VS
-	arm_LDREXB_VC
-	arm_LDREXB_HI
-	arm_LDREXB_LS
-	arm_LDREXB_GE
-	arm_LDREXB_LT
-	arm_LDREXB_GT
-	arm_LDREXB_LE
-	arm_LDREXB
-	arm_LDREXB_ZZ
-	arm_LDREXD_EQ
-	arm_LDREXD_NE
-	arm_LDREXD_CS
-	arm_LDREXD_CC
-	arm_LDREXD_MI
-	arm_LDREXD_PL
-	arm_LDREXD_VS
-	arm_LDREXD_VC
-	arm_LDREXD_HI
-	arm_LDREXD_LS
-	arm_LDREXD_GE
-	arm_LDREXD_LT
-	arm_LDREXD_GT
-	arm_LDREXD_LE
-	arm_LDREXD
-	arm_LDREXD_ZZ
-	arm_LDREXH_EQ
-	arm_LDREXH_NE
-	arm_LDREXH_CS
-	arm_LDREXH_CC
-	arm_LDREXH_MI
-	arm_LDREXH_PL
-	arm_LDREXH_VS
-	arm_LDREXH_VC
-	arm_LDREXH_HI
-	arm_LDREXH_LS
-	arm_LDREXH_GE
-	arm_LDREXH_LT
-	arm_LDREXH_GT
-	arm_LDREXH_LE
-	arm_LDREXH
-	arm_LDREXH_ZZ
-	arm_LDRH_EQ
-	arm_LDRH_NE
-	arm_LDRH_CS
-	arm_LDRH_CC
-	arm_LDRH_MI
-	arm_LDRH_PL
-	arm_LDRH_VS
-	arm_LDRH_VC
-	arm_LDRH_HI
-	arm_LDRH_LS
-	arm_LDRH_GE
-	arm_LDRH_LT
-	arm_LDRH_GT
-	arm_LDRH_LE
-	arm_LDRH
-	arm_LDRH_ZZ
-	arm_LDRHT_EQ
-	arm_LDRHT_NE
-	arm_LDRHT_CS
-	arm_LDRHT_CC
-	arm_LDRHT_MI
-	arm_LDRHT_PL
-	arm_LDRHT_VS
-	arm_LDRHT_VC
-	arm_LDRHT_HI
-	arm_LDRHT_LS
-	arm_LDRHT_GE
-	arm_LDRHT_LT
-	arm_LDRHT_GT
-	arm_LDRHT_LE
-	arm_LDRHT
-	arm_LDRHT_ZZ
-	arm_LDRSB_EQ
-	arm_LDRSB_NE
-	arm_LDRSB_CS
-	arm_LDRSB_CC
-	arm_LDRSB_MI
-	arm_LDRSB_PL
-	arm_LDRSB_VS
-	arm_LDRSB_VC
-	arm_LDRSB_HI
-	arm_LDRSB_LS
-	arm_LDRSB_GE
-	arm_LDRSB_LT
-	arm_LDRSB_GT
-	arm_LDRSB_LE
-	arm_LDRSB
-	arm_LDRSB_ZZ
-	arm_LDRSBT_EQ
-	arm_LDRSBT_NE
-	arm_LDRSBT_CS
-	arm_LDRSBT_CC
-	arm_LDRSBT_MI
-	arm_LDRSBT_PL
-	arm_LDRSBT_VS
-	arm_LDRSBT_VC
-	arm_LDRSBT_HI
-	arm_LDRSBT_LS
-	arm_LDRSBT_GE
-	arm_LDRSBT_LT
-	arm_LDRSBT_GT
-	arm_LDRSBT_LE
-	arm_LDRSBT
-	arm_LDRSBT_ZZ
-	arm_LDRSH_EQ
-	arm_LDRSH_NE
-	arm_LDRSH_CS
-	arm_LDRSH_CC
-	arm_LDRSH_MI
-	arm_LDRSH_PL
-	arm_LDRSH_VS
-	arm_LDRSH_VC
-	arm_LDRSH_HI
-	arm_LDRSH_LS
-	arm_LDRSH_GE
-	arm_LDRSH_LT
-	arm_LDRSH_GT
-	arm_LDRSH_LE
-	arm_LDRSH
-	arm_LDRSH_ZZ
-	arm_LDRSHT_EQ
-	arm_LDRSHT_NE
-	arm_LDRSHT_CS
-	arm_LDRSHT_CC
-	arm_LDRSHT_MI
-	arm_LDRSHT_PL
-	arm_LDRSHT_VS
-	arm_LDRSHT_VC
-	arm_LDRSHT_HI
-	arm_LDRSHT_LS
-	arm_LDRSHT_GE
-	arm_LDRSHT_LT
-	arm_LDRSHT_GT
-	arm_LDRSHT_LE
-	arm_LDRSHT
-	arm_LDRSHT_ZZ
-	arm_LDRT_EQ
-	arm_LDRT_NE
-	arm_LDRT_CS
-	arm_LDRT_CC
-	arm_LDRT_MI
-	arm_LDRT_PL
-	arm_LDRT_VS
-	arm_LDRT_VC
-	arm_LDRT_HI
-	arm_LDRT_LS
-	arm_LDRT_GE
-	arm_LDRT_LT
-	arm_LDRT_GT
-	arm_LDRT_LE
-	arm_LDRT
-	arm_LDRT_ZZ
-	arm_LSL_EQ
-	arm_LSL_NE
-	arm_LSL_CS
-	arm_LSL_CC
-	arm_LSL_MI
-	arm_LSL_PL
-	arm_LSL_VS
-	arm_LSL_VC
-	arm_LSL_HI
-	arm_LSL_LS
-	arm_LSL_GE
-	arm_LSL_LT
-	arm_LSL_GT
-	arm_LSL_LE
-	arm_LSL
-	arm_LSL_ZZ
-	arm_LSL_S_EQ
-	arm_LSL_S_NE
-	arm_LSL_S_CS
-	arm_LSL_S_CC
-	arm_LSL_S_MI
-	arm_LSL_S_PL
-	arm_LSL_S_VS
-	arm_LSL_S_VC
-	arm_LSL_S_HI
-	arm_LSL_S_LS
-	arm_LSL_S_GE
-	arm_LSL_S_LT
-	arm_LSL_S_GT
-	arm_LSL_S_LE
-	arm_LSL_S
-	arm_LSL_S_ZZ
-	arm_LSR_EQ
-	arm_LSR_NE
-	arm_LSR_CS
-	arm_LSR_CC
-	arm_LSR_MI
-	arm_LSR_PL
-	arm_LSR_VS
-	arm_LSR_VC
-	arm_LSR_HI
-	arm_LSR_LS
-	arm_LSR_GE
-	arm_LSR_LT
-	arm_LSR_GT
-	arm_LSR_LE
-	arm_LSR
-	arm_LSR_ZZ
-	arm_LSR_S_EQ
-	arm_LSR_S_NE
-	arm_LSR_S_CS
-	arm_LSR_S_CC
-	arm_LSR_S_MI
-	arm_LSR_S_PL
-	arm_LSR_S_VS
-	arm_LSR_S_VC
-	arm_LSR_S_HI
-	arm_LSR_S_LS
-	arm_LSR_S_GE
-	arm_LSR_S_LT
-	arm_LSR_S_GT
-	arm_LSR_S_LE
-	arm_LSR_S
-	arm_LSR_S_ZZ
-	arm_MLA_EQ
-	arm_MLA_NE
-	arm_MLA_CS
-	arm_MLA_CC
-	arm_MLA_MI
-	arm_MLA_PL
-	arm_MLA_VS
-	arm_MLA_VC
-	arm_MLA_HI
-	arm_MLA_LS
-	arm_MLA_GE
-	arm_MLA_LT
-	arm_MLA_GT
-	arm_MLA_LE
-	arm_MLA
-	arm_MLA_ZZ
-	arm_MLA_S_EQ
-	arm_MLA_S_NE
-	arm_MLA_S_CS
-	arm_MLA_S_CC
-	arm_MLA_S_MI
-	arm_MLA_S_PL
-	arm_MLA_S_VS
-	arm_MLA_S_VC
-	arm_MLA_S_HI
-	arm_MLA_S_LS
-	arm_MLA_S_GE
-	arm_MLA_S_LT
-	arm_MLA_S_GT
-	arm_MLA_S_LE
-	arm_MLA_S
-	arm_MLA_S_ZZ
-	arm_MLS_EQ
-	arm_MLS_NE
-	arm_MLS_CS
-	arm_MLS_CC
-	arm_MLS_MI
-	arm_MLS_PL
-	arm_MLS_VS
-	arm_MLS_VC
-	arm_MLS_HI
-	arm_MLS_LS
-	arm_MLS_GE
-	arm_MLS_LT
-	arm_MLS_GT
-	arm_MLS_LE
-	arm_MLS
-	arm_MLS_ZZ
-	arm_MOV_EQ
-	arm_MOV_NE
-	arm_MOV_CS
-	arm_MOV_CC
-	arm_MOV_MI
-	arm_MOV_PL
-	arm_MOV_VS
-	arm_MOV_VC
-	arm_MOV_HI
-	arm_MOV_LS
-	arm_MOV_GE
-	arm_MOV_LT
-	arm_MOV_GT
-	arm_MOV_LE
-	arm_MOV
-	arm_MOV_ZZ
-	arm_MOV_S_EQ
-	arm_MOV_S_NE
-	arm_MOV_S_CS
-	arm_MOV_S_CC
-	arm_MOV_S_MI
-	arm_MOV_S_PL
-	arm_MOV_S_VS
-	arm_MOV_S_VC
-	arm_MOV_S_HI
-	arm_MOV_S_LS
-	arm_MOV_S_GE
-	arm_MOV_S_LT
-	arm_MOV_S_GT
-	arm_MOV_S_LE
-	arm_MOV_S
-	arm_MOV_S_ZZ
-	arm_MOVT_EQ
-	arm_MOVT_NE
-	arm_MOVT_CS
-	arm_MOVT_CC
-	arm_MOVT_MI
-	arm_MOVT_PL
-	arm_MOVT_VS
-	arm_MOVT_VC
-	arm_MOVT_HI
-	arm_MOVT_LS
-	arm_MOVT_GE
-	arm_MOVT_LT
-	arm_MOVT_GT
-	arm_MOVT_LE
-	arm_MOVT
-	arm_MOVT_ZZ
-	arm_MOVW_EQ
-	arm_MOVW_NE
-	arm_MOVW_CS
-	arm_MOVW_CC
-	arm_MOVW_MI
-	arm_MOVW_PL
-	arm_MOVW_VS
-	arm_MOVW_VC
-	arm_MOVW_HI
-	arm_MOVW_LS
-	arm_MOVW_GE
-	arm_MOVW_LT
-	arm_MOVW_GT
-	arm_MOVW_LE
-	arm_MOVW
-	arm_MOVW_ZZ
-	arm_MRS_EQ
-	arm_MRS_NE
-	arm_MRS_CS
-	arm_MRS_CC
-	arm_MRS_MI
-	arm_MRS_PL
-	arm_MRS_VS
-	arm_MRS_VC
-	arm_MRS_HI
-	arm_MRS_LS
-	arm_MRS_GE
-	arm_MRS_LT
-	arm_MRS_GT
-	arm_MRS_LE
-	arm_MRS
-	arm_MRS_ZZ
-	arm_MUL_EQ
-	arm_MUL_NE
-	arm_MUL_CS
-	arm_MUL_CC
-	arm_MUL_MI
-	arm_MUL_PL
-	arm_MUL_VS
-	arm_MUL_VC
-	arm_MUL_HI
-	arm_MUL_LS
-	arm_MUL_GE
-	arm_MUL_LT
-	arm_MUL_GT
-	arm_MUL_LE
-	arm_MUL
-	arm_MUL_ZZ
-	arm_MUL_S_EQ
-	arm_MUL_S_NE
-	arm_MUL_S_CS
-	arm_MUL_S_CC
-	arm_MUL_S_MI
-	arm_MUL_S_PL
-	arm_MUL_S_VS
-	arm_MUL_S_VC
-	arm_MUL_S_HI
-	arm_MUL_S_LS
-	arm_MUL_S_GE
-	arm_MUL_S_LT
-	arm_MUL_S_GT
-	arm_MUL_S_LE
-	arm_MUL_S
-	arm_MUL_S_ZZ
-	arm_MVN_EQ
-	arm_MVN_NE
-	arm_MVN_CS
-	arm_MVN_CC
-	arm_MVN_MI
-	arm_MVN_PL
-	arm_MVN_VS
-	arm_MVN_VC
-	arm_MVN_HI
-	arm_MVN_LS
-	arm_MVN_GE
-	arm_MVN_LT
-	arm_MVN_GT
-	arm_MVN_LE
-	arm_MVN
-	arm_MVN_ZZ
-	arm_MVN_S_EQ
-	arm_MVN_S_NE
-	arm_MVN_S_CS
-	arm_MVN_S_CC
-	arm_MVN_S_MI
-	arm_MVN_S_PL
-	arm_MVN_S_VS
-	arm_MVN_S_VC
-	arm_MVN_S_HI
-	arm_MVN_S_LS
-	arm_MVN_S_GE
-	arm_MVN_S_LT
-	arm_MVN_S_GT
-	arm_MVN_S_LE
-	arm_MVN_S
-	arm_MVN_S_ZZ
-	arm_NOP_EQ
-	arm_NOP_NE
-	arm_NOP_CS
-	arm_NOP_CC
-	arm_NOP_MI
-	arm_NOP_PL
-	arm_NOP_VS
-	arm_NOP_VC
-	arm_NOP_HI
-	arm_NOP_LS
-	arm_NOP_GE
-	arm_NOP_LT
-	arm_NOP_GT
-	arm_NOP_LE
-	arm_NOP
-	arm_NOP_ZZ
-	arm_ORR_EQ
-	arm_ORR_NE
-	arm_ORR_CS
-	arm_ORR_CC
-	arm_ORR_MI
-	arm_ORR_PL
-	arm_ORR_VS
-	arm_ORR_VC
-	arm_ORR_HI
-	arm_ORR_LS
-	arm_ORR_GE
-	arm_ORR_LT
-	arm_ORR_GT
-	arm_ORR_LE
-	arm_ORR
-	arm_ORR_ZZ
-	arm_ORR_S_EQ
-	arm_ORR_S_NE
-	arm_ORR_S_CS
-	arm_ORR_S_CC
-	arm_ORR_S_MI
-	arm_ORR_S_PL
-	arm_ORR_S_VS
-	arm_ORR_S_VC
-	arm_ORR_S_HI
-	arm_ORR_S_LS
-	arm_ORR_S_GE
-	arm_ORR_S_LT
-	arm_ORR_S_GT
-	arm_ORR_S_LE
-	arm_ORR_S
-	arm_ORR_S_ZZ
-	arm_PKHBT_EQ
-	arm_PKHBT_NE
-	arm_PKHBT_CS
-	arm_PKHBT_CC
-	arm_PKHBT_MI
-	arm_PKHBT_PL
-	arm_PKHBT_VS
-	arm_PKHBT_VC
-	arm_PKHBT_HI
-	arm_PKHBT_LS
-	arm_PKHBT_GE
-	arm_PKHBT_LT
-	arm_PKHBT_GT
-	arm_PKHBT_LE
-	arm_PKHBT
-	arm_PKHBT_ZZ
-	arm_PKHTB_EQ
-	arm_PKHTB_NE
-	arm_PKHTB_CS
-	arm_PKHTB_CC
-	arm_PKHTB_MI
-	arm_PKHTB_PL
-	arm_PKHTB_VS
-	arm_PKHTB_VC
-	arm_PKHTB_HI
-	arm_PKHTB_LS
-	arm_PKHTB_GE
-	arm_PKHTB_LT
-	arm_PKHTB_GT
-	arm_PKHTB_LE
-	arm_PKHTB
-	arm_PKHTB_ZZ
-	arm_PLD_W
-	arm_PLD
-	arm_PLI
-	_
-	_
-	_
-	_
-	_
-	_
-	_
-	_
-	_
-	_
-	_
-	_
-	_
-	arm_POP_EQ
-	arm_POP_NE
-	arm_POP_CS
-	arm_POP_CC
-	arm_POP_MI
-	arm_POP_PL
-	arm_POP_VS
-	arm_POP_VC
-	arm_POP_HI
-	arm_POP_LS
-	arm_POP_GE
-	arm_POP_LT
-	arm_POP_GT
-	arm_POP_LE
-	arm_POP
-	arm_POP_ZZ
-	arm_PUSH_EQ
-	arm_PUSH_NE
-	arm_PUSH_CS
-	arm_PUSH_CC
-	arm_PUSH_MI
-	arm_PUSH_PL
-	arm_PUSH_VS
-	arm_PUSH_VC
-	arm_PUSH_HI
-	arm_PUSH_LS
-	arm_PUSH_GE
-	arm_PUSH_LT
-	arm_PUSH_GT
-	arm_PUSH_LE
-	arm_PUSH
-	arm_PUSH_ZZ
-	arm_QADD_EQ
-	arm_QADD_NE
-	arm_QADD_CS
-	arm_QADD_CC
-	arm_QADD_MI
-	arm_QADD_PL
-	arm_QADD_VS
-	arm_QADD_VC
-	arm_QADD_HI
-	arm_QADD_LS
-	arm_QADD_GE
-	arm_QADD_LT
-	arm_QADD_GT
-	arm_QADD_LE
-	arm_QADD
-	arm_QADD_ZZ
-	arm_QADD16_EQ
-	arm_QADD16_NE
-	arm_QADD16_CS
-	arm_QADD16_CC
-	arm_QADD16_MI
-	arm_QADD16_PL
-	arm_QADD16_VS
-	arm_QADD16_VC
-	arm_QADD16_HI
-	arm_QADD16_LS
-	arm_QADD16_GE
-	arm_QADD16_LT
-	arm_QADD16_GT
-	arm_QADD16_LE
-	arm_QADD16
-	arm_QADD16_ZZ
-	arm_QADD8_EQ
-	arm_QADD8_NE
-	arm_QADD8_CS
-	arm_QADD8_CC
-	arm_QADD8_MI
-	arm_QADD8_PL
-	arm_QADD8_VS
-	arm_QADD8_VC
-	arm_QADD8_HI
-	arm_QADD8_LS
-	arm_QADD8_GE
-	arm_QADD8_LT
-	arm_QADD8_GT
-	arm_QADD8_LE
-	arm_QADD8
-	arm_QADD8_ZZ
-	arm_QASX_EQ
-	arm_QASX_NE
-	arm_QASX_CS
-	arm_QASX_CC
-	arm_QASX_MI
-	arm_QASX_PL
-	arm_QASX_VS
-	arm_QASX_VC
-	arm_QASX_HI
-	arm_QASX_LS
-	arm_QASX_GE
-	arm_QASX_LT
-	arm_QASX_GT
-	arm_QASX_LE
-	arm_QASX
-	arm_QASX_ZZ
-	arm_QDADD_EQ
-	arm_QDADD_NE
-	arm_QDADD_CS
-	arm_QDADD_CC
-	arm_QDADD_MI
-	arm_QDADD_PL
-	arm_QDADD_VS
-	arm_QDADD_VC
-	arm_QDADD_HI
-	arm_QDADD_LS
-	arm_QDADD_GE
-	arm_QDADD_LT
-	arm_QDADD_GT
-	arm_QDADD_LE
-	arm_QDADD
-	arm_QDADD_ZZ
-	arm_QDSUB_EQ
-	arm_QDSUB_NE
-	arm_QDSUB_CS
-	arm_QDSUB_CC
-	arm_QDSUB_MI
-	arm_QDSUB_PL
-	arm_QDSUB_VS
-	arm_QDSUB_VC
-	arm_QDSUB_HI
-	arm_QDSUB_LS
-	arm_QDSUB_GE
-	arm_QDSUB_LT
-	arm_QDSUB_GT
-	arm_QDSUB_LE
-	arm_QDSUB
-	arm_QDSUB_ZZ
-	arm_QSAX_EQ
-	arm_QSAX_NE
-	arm_QSAX_CS
-	arm_QSAX_CC
-	arm_QSAX_MI
-	arm_QSAX_PL
-	arm_QSAX_VS
-	arm_QSAX_VC
-	arm_QSAX_HI
-	arm_QSAX_LS
-	arm_QSAX_GE
-	arm_QSAX_LT
-	arm_QSAX_GT
-	arm_QSAX_LE
-	arm_QSAX
-	arm_QSAX_ZZ
-	arm_QSUB_EQ
-	arm_QSUB_NE
-	arm_QSUB_CS
-	arm_QSUB_CC
-	arm_QSUB_MI
-	arm_QSUB_PL
-	arm_QSUB_VS
-	arm_QSUB_VC
-	arm_QSUB_HI
-	arm_QSUB_LS
-	arm_QSUB_GE
-	arm_QSUB_LT
-	arm_QSUB_GT
-	arm_QSUB_LE
-	arm_QSUB
-	arm_QSUB_ZZ
-	arm_QSUB16_EQ
-	arm_QSUB16_NE
-	arm_QSUB16_CS
-	arm_QSUB16_CC
-	arm_QSUB16_MI
-	arm_QSUB16_PL
-	arm_QSUB16_VS
-	arm_QSUB16_VC
-	arm_QSUB16_HI
-	arm_QSUB16_LS
-	arm_QSUB16_GE
-	arm_QSUB16_LT
-	arm_QSUB16_GT
-	arm_QSUB16_LE
-	arm_QSUB16
-	arm_QSUB16_ZZ
-	arm_QSUB8_EQ
-	arm_QSUB8_NE
-	arm_QSUB8_CS
-	arm_QSUB8_CC
-	arm_QSUB8_MI
-	arm_QSUB8_PL
-	arm_QSUB8_VS
-	arm_QSUB8_VC
-	arm_QSUB8_HI
-	arm_QSUB8_LS
-	arm_QSUB8_GE
-	arm_QSUB8_LT
-	arm_QSUB8_GT
-	arm_QSUB8_LE
-	arm_QSUB8
-	arm_QSUB8_ZZ
-	arm_RBIT_EQ
-	arm_RBIT_NE
-	arm_RBIT_CS
-	arm_RBIT_CC
-	arm_RBIT_MI
-	arm_RBIT_PL
-	arm_RBIT_VS
-	arm_RBIT_VC
-	arm_RBIT_HI
-	arm_RBIT_LS
-	arm_RBIT_GE
-	arm_RBIT_LT
-	arm_RBIT_GT
-	arm_RBIT_LE
-	arm_RBIT
-	arm_RBIT_ZZ
-	arm_REV_EQ
-	arm_REV_NE
-	arm_REV_CS
-	arm_REV_CC
-	arm_REV_MI
-	arm_REV_PL
-	arm_REV_VS
-	arm_REV_VC
-	arm_REV_HI
-	arm_REV_LS
-	arm_REV_GE
-	arm_REV_LT
-	arm_REV_GT
-	arm_REV_LE
-	arm_REV
-	arm_REV_ZZ
-	arm_REV16_EQ
-	arm_REV16_NE
-	arm_REV16_CS
-	arm_REV16_CC
-	arm_REV16_MI
-	arm_REV16_PL
-	arm_REV16_VS
-	arm_REV16_VC
-	arm_REV16_HI
-	arm_REV16_LS
-	arm_REV16_GE
-	arm_REV16_LT
-	arm_REV16_GT
-	arm_REV16_LE
-	arm_REV16
-	arm_REV16_ZZ
-	arm_REVSH_EQ
-	arm_REVSH_NE
-	arm_REVSH_CS
-	arm_REVSH_CC
-	arm_REVSH_MI
-	arm_REVSH_PL
-	arm_REVSH_VS
-	arm_REVSH_VC
-	arm_REVSH_HI
-	arm_REVSH_LS
-	arm_REVSH_GE
-	arm_REVSH_LT
-	arm_REVSH_GT
-	arm_REVSH_LE
-	arm_REVSH
-	arm_REVSH_ZZ
-	arm_ROR_EQ
-	arm_ROR_NE
-	arm_ROR_CS
-	arm_ROR_CC
-	arm_ROR_MI
-	arm_ROR_PL
-	arm_ROR_VS
-	arm_ROR_VC
-	arm_ROR_HI
-	arm_ROR_LS
-	arm_ROR_GE
-	arm_ROR_LT
-	arm_ROR_GT
-	arm_ROR_LE
-	arm_ROR
-	arm_ROR_ZZ
-	arm_ROR_S_EQ
-	arm_ROR_S_NE
-	arm_ROR_S_CS
-	arm_ROR_S_CC
-	arm_ROR_S_MI
-	arm_ROR_S_PL
-	arm_ROR_S_VS
-	arm_ROR_S_VC
-	arm_ROR_S_HI
-	arm_ROR_S_LS
-	arm_ROR_S_GE
-	arm_ROR_S_LT
-	arm_ROR_S_GT
-	arm_ROR_S_LE
-	arm_ROR_S
-	arm_ROR_S_ZZ
-	arm_RRX_EQ
-	arm_RRX_NE
-	arm_RRX_CS
-	arm_RRX_CC
-	arm_RRX_MI
-	arm_RRX_PL
-	arm_RRX_VS
-	arm_RRX_VC
-	arm_RRX_HI
-	arm_RRX_LS
-	arm_RRX_GE
-	arm_RRX_LT
-	arm_RRX_GT
-	arm_RRX_LE
-	arm_RRX
-	arm_RRX_ZZ
-	arm_RRX_S_EQ
-	arm_RRX_S_NE
-	arm_RRX_S_CS
-	arm_RRX_S_CC
-	arm_RRX_S_MI
-	arm_RRX_S_PL
-	arm_RRX_S_VS
-	arm_RRX_S_VC
-	arm_RRX_S_HI
-	arm_RRX_S_LS
-	arm_RRX_S_GE
-	arm_RRX_S_LT
-	arm_RRX_S_GT
-	arm_RRX_S_LE
-	arm_RRX_S
-	arm_RRX_S_ZZ
-	arm_RSB_EQ
-	arm_RSB_NE
-	arm_RSB_CS
-	arm_RSB_CC
-	arm_RSB_MI
-	arm_RSB_PL
-	arm_RSB_VS
-	arm_RSB_VC
-	arm_RSB_HI
-	arm_RSB_LS
-	arm_RSB_GE
-	arm_RSB_LT
-	arm_RSB_GT
-	arm_RSB_LE
-	arm_RSB
-	arm_RSB_ZZ
-	arm_RSB_S_EQ
-	arm_RSB_S_NE
-	arm_RSB_S_CS
-	arm_RSB_S_CC
-	arm_RSB_S_MI
-	arm_RSB_S_PL
-	arm_RSB_S_VS
-	arm_RSB_S_VC
-	arm_RSB_S_HI
-	arm_RSB_S_LS
-	arm_RSB_S_GE
-	arm_RSB_S_LT
-	arm_RSB_S_GT
-	arm_RSB_S_LE
-	arm_RSB_S
-	arm_RSB_S_ZZ
-	arm_RSC_EQ
-	arm_RSC_NE
-	arm_RSC_CS
-	arm_RSC_CC
-	arm_RSC_MI
-	arm_RSC_PL
-	arm_RSC_VS
-	arm_RSC_VC
-	arm_RSC_HI
-	arm_RSC_LS
-	arm_RSC_GE
-	arm_RSC_LT
-	arm_RSC_GT
-	arm_RSC_LE
-	arm_RSC
-	arm_RSC_ZZ
-	arm_RSC_S_EQ
-	arm_RSC_S_NE
-	arm_RSC_S_CS
-	arm_RSC_S_CC
-	arm_RSC_S_MI
-	arm_RSC_S_PL
-	arm_RSC_S_VS
-	arm_RSC_S_VC
-	arm_RSC_S_HI
-	arm_RSC_S_LS
-	arm_RSC_S_GE
-	arm_RSC_S_LT
-	arm_RSC_S_GT
-	arm_RSC_S_LE
-	arm_RSC_S
-	arm_RSC_S_ZZ
-	arm_SADD16_EQ
-	arm_SADD16_NE
-	arm_SADD16_CS
-	arm_SADD16_CC
-	arm_SADD16_MI
-	arm_SADD16_PL
-	arm_SADD16_VS
-	arm_SADD16_VC
-	arm_SADD16_HI
-	arm_SADD16_LS
-	arm_SADD16_GE
-	arm_SADD16_LT
-	arm_SADD16_GT
-	arm_SADD16_LE
-	arm_SADD16
-	arm_SADD16_ZZ
-	arm_SADD8_EQ
-	arm_SADD8_NE
-	arm_SADD8_CS
-	arm_SADD8_CC
-	arm_SADD8_MI
-	arm_SADD8_PL
-	arm_SADD8_VS
-	arm_SADD8_VC
-	arm_SADD8_HI
-	arm_SADD8_LS
-	arm_SADD8_GE
-	arm_SADD8_LT
-	arm_SADD8_GT
-	arm_SADD8_LE
-	arm_SADD8
-	arm_SADD8_ZZ
-	arm_SASX_EQ
-	arm_SASX_NE
-	arm_SASX_CS
-	arm_SASX_CC
-	arm_SASX_MI
-	arm_SASX_PL
-	arm_SASX_VS
-	arm_SASX_VC
-	arm_SASX_HI
-	arm_SASX_LS
-	arm_SASX_GE
-	arm_SASX_LT
-	arm_SASX_GT
-	arm_SASX_LE
-	arm_SASX
-	arm_SASX_ZZ
-	arm_SBC_EQ
-	arm_SBC_NE
-	arm_SBC_CS
-	arm_SBC_CC
-	arm_SBC_MI
-	arm_SBC_PL
-	arm_SBC_VS
-	arm_SBC_VC
-	arm_SBC_HI
-	arm_SBC_LS
-	arm_SBC_GE
-	arm_SBC_LT
-	arm_SBC_GT
-	arm_SBC_LE
-	arm_SBC
-	arm_SBC_ZZ
-	arm_SBC_S_EQ
-	arm_SBC_S_NE
-	arm_SBC_S_CS
-	arm_SBC_S_CC
-	arm_SBC_S_MI
-	arm_SBC_S_PL
-	arm_SBC_S_VS
-	arm_SBC_S_VC
-	arm_SBC_S_HI
-	arm_SBC_S_LS
-	arm_SBC_S_GE
-	arm_SBC_S_LT
-	arm_SBC_S_GT
-	arm_SBC_S_LE
-	arm_SBC_S
-	arm_SBC_S_ZZ
-	arm_SBFX_EQ
-	arm_SBFX_NE
-	arm_SBFX_CS
-	arm_SBFX_CC
-	arm_SBFX_MI
-	arm_SBFX_PL
-	arm_SBFX_VS
-	arm_SBFX_VC
-	arm_SBFX_HI
-	arm_SBFX_LS
-	arm_SBFX_GE
-	arm_SBFX_LT
-	arm_SBFX_GT
-	arm_SBFX_LE
-	arm_SBFX
-	arm_SBFX_ZZ
-	arm_SEL_EQ
-	arm_SEL_NE
-	arm_SEL_CS
-	arm_SEL_CC
-	arm_SEL_MI
-	arm_SEL_PL
-	arm_SEL_VS
-	arm_SEL_VC
-	arm_SEL_HI
-	arm_SEL_LS
-	arm_SEL_GE
-	arm_SEL_LT
-	arm_SEL_GT
-	arm_SEL_LE
-	arm_SEL
-	arm_SEL_ZZ
-	arm_SETEND
-	_
-	_
-	_
-	_
-	_
-	_
-	_
-	_
-	_
-	_
-	_
-	_
-	_
-	_
-	_
-	arm_SEV_EQ
-	arm_SEV_NE
-	arm_SEV_CS
-	arm_SEV_CC
-	arm_SEV_MI
-	arm_SEV_PL
-	arm_SEV_VS
-	arm_SEV_VC
-	arm_SEV_HI
-	arm_SEV_LS
-	arm_SEV_GE
-	arm_SEV_LT
-	arm_SEV_GT
-	arm_SEV_LE
-	arm_SEV
-	arm_SEV_ZZ
-	arm_SHADD16_EQ
-	arm_SHADD16_NE
-	arm_SHADD16_CS
-	arm_SHADD16_CC
-	arm_SHADD16_MI
-	arm_SHADD16_PL
-	arm_SHADD16_VS
-	arm_SHADD16_VC
-	arm_SHADD16_HI
-	arm_SHADD16_LS
-	arm_SHADD16_GE
-	arm_SHADD16_LT
-	arm_SHADD16_GT
-	arm_SHADD16_LE
-	arm_SHADD16
-	arm_SHADD16_ZZ
-	arm_SHADD8_EQ
-	arm_SHADD8_NE
-	arm_SHADD8_CS
-	arm_SHADD8_CC
-	arm_SHADD8_MI
-	arm_SHADD8_PL
-	arm_SHADD8_VS
-	arm_SHADD8_VC
-	arm_SHADD8_HI
-	arm_SHADD8_LS
-	arm_SHADD8_GE
-	arm_SHADD8_LT
-	arm_SHADD8_GT
-	arm_SHADD8_LE
-	arm_SHADD8
-	arm_SHADD8_ZZ
-	arm_SHASX_EQ
-	arm_SHASX_NE
-	arm_SHASX_CS
-	arm_SHASX_CC
-	arm_SHASX_MI
-	arm_SHASX_PL
-	arm_SHASX_VS
-	arm_SHASX_VC
-	arm_SHASX_HI
-	arm_SHASX_LS
-	arm_SHASX_GE
-	arm_SHASX_LT
-	arm_SHASX_GT
-	arm_SHASX_LE
-	arm_SHASX
-	arm_SHASX_ZZ
-	arm_SHSAX_EQ
-	arm_SHSAX_NE
-	arm_SHSAX_CS
-	arm_SHSAX_CC
-	arm_SHSAX_MI
-	arm_SHSAX_PL
-	arm_SHSAX_VS
-	arm_SHSAX_VC
-	arm_SHSAX_HI
-	arm_SHSAX_LS
-	arm_SHSAX_GE
-	arm_SHSAX_LT
-	arm_SHSAX_GT
-	arm_SHSAX_LE
-	arm_SHSAX
-	arm_SHSAX_ZZ
-	arm_SHSUB16_EQ
-	arm_SHSUB16_NE
-	arm_SHSUB16_CS
-	arm_SHSUB16_CC
-	arm_SHSUB16_MI
-	arm_SHSUB16_PL
-	arm_SHSUB16_VS
-	arm_SHSUB16_VC
-	arm_SHSUB16_HI
-	arm_SHSUB16_LS
-	arm_SHSUB16_GE
-	arm_SHSUB16_LT
-	arm_SHSUB16_GT
-	arm_SHSUB16_LE
-	arm_SHSUB16
-	arm_SHSUB16_ZZ
-	arm_SHSUB8_EQ
-	arm_SHSUB8_NE
-	arm_SHSUB8_CS
-	arm_SHSUB8_CC
-	arm_SHSUB8_MI
-	arm_SHSUB8_PL
-	arm_SHSUB8_VS
-	arm_SHSUB8_VC
-	arm_SHSUB8_HI
-	arm_SHSUB8_LS
-	arm_SHSUB8_GE
-	arm_SHSUB8_LT
-	arm_SHSUB8_GT
-	arm_SHSUB8_LE
-	arm_SHSUB8
-	arm_SHSUB8_ZZ
-	arm_SMLABB_EQ
-	arm_SMLABB_NE
-	arm_SMLABB_CS
-	arm_SMLABB_CC
-	arm_SMLABB_MI
-	arm_SMLABB_PL
-	arm_SMLABB_VS
-	arm_SMLABB_VC
-	arm_SMLABB_HI
-	arm_SMLABB_LS
-	arm_SMLABB_GE
-	arm_SMLABB_LT
-	arm_SMLABB_GT
-	arm_SMLABB_LE
-	arm_SMLABB
-	arm_SMLABB_ZZ
-	arm_SMLABT_EQ
-	arm_SMLABT_NE
-	arm_SMLABT_CS
-	arm_SMLABT_CC
-	arm_SMLABT_MI
-	arm_SMLABT_PL
-	arm_SMLABT_VS
-	arm_SMLABT_VC
-	arm_SMLABT_HI
-	arm_SMLABT_LS
-	arm_SMLABT_GE
-	arm_SMLABT_LT
-	arm_SMLABT_GT
-	arm_SMLABT_LE
-	arm_SMLABT
-	arm_SMLABT_ZZ
-	arm_SMLATB_EQ
-	arm_SMLATB_NE
-	arm_SMLATB_CS
-	arm_SMLATB_CC
-	arm_SMLATB_MI
-	arm_SMLATB_PL
-	arm_SMLATB_VS
-	arm_SMLATB_VC
-	arm_SMLATB_HI
-	arm_SMLATB_LS
-	arm_SMLATB_GE
-	arm_SMLATB_LT
-	arm_SMLATB_GT
-	arm_SMLATB_LE
-	arm_SMLATB
-	arm_SMLATB_ZZ
-	arm_SMLATT_EQ
-	arm_SMLATT_NE
-	arm_SMLATT_CS
-	arm_SMLATT_CC
-	arm_SMLATT_MI
-	arm_SMLATT_PL
-	arm_SMLATT_VS
-	arm_SMLATT_VC
-	arm_SMLATT_HI
-	arm_SMLATT_LS
-	arm_SMLATT_GE
-	arm_SMLATT_LT
-	arm_SMLATT_GT
-	arm_SMLATT_LE
-	arm_SMLATT
-	arm_SMLATT_ZZ
-	arm_SMLAD_EQ
-	arm_SMLAD_NE
-	arm_SMLAD_CS
-	arm_SMLAD_CC
-	arm_SMLAD_MI
-	arm_SMLAD_PL
-	arm_SMLAD_VS
-	arm_SMLAD_VC
-	arm_SMLAD_HI
-	arm_SMLAD_LS
-	arm_SMLAD_GE
-	arm_SMLAD_LT
-	arm_SMLAD_GT
-	arm_SMLAD_LE
-	arm_SMLAD
-	arm_SMLAD_ZZ
-	arm_SMLAD_X_EQ
-	arm_SMLAD_X_NE
-	arm_SMLAD_X_CS
-	arm_SMLAD_X_CC
-	arm_SMLAD_X_MI
-	arm_SMLAD_X_PL
-	arm_SMLAD_X_VS
-	arm_SMLAD_X_VC
-	arm_SMLAD_X_HI
-	arm_SMLAD_X_LS
-	arm_SMLAD_X_GE
-	arm_SMLAD_X_LT
-	arm_SMLAD_X_GT
-	arm_SMLAD_X_LE
-	arm_SMLAD_X
-	arm_SMLAD_X_ZZ
-	arm_SMLAL_EQ
-	arm_SMLAL_NE
-	arm_SMLAL_CS
-	arm_SMLAL_CC
-	arm_SMLAL_MI
-	arm_SMLAL_PL
-	arm_SMLAL_VS
-	arm_SMLAL_VC
-	arm_SMLAL_HI
-	arm_SMLAL_LS
-	arm_SMLAL_GE
-	arm_SMLAL_LT
-	arm_SMLAL_GT
-	arm_SMLAL_LE
-	arm_SMLAL
-	arm_SMLAL_ZZ
-	arm_SMLAL_S_EQ
-	arm_SMLAL_S_NE
-	arm_SMLAL_S_CS
-	arm_SMLAL_S_CC
-	arm_SMLAL_S_MI
-	arm_SMLAL_S_PL
-	arm_SMLAL_S_VS
-	arm_SMLAL_S_VC
-	arm_SMLAL_S_HI
-	arm_SMLAL_S_LS
-	arm_SMLAL_S_GE
-	arm_SMLAL_S_LT
-	arm_SMLAL_S_GT
-	arm_SMLAL_S_LE
-	arm_SMLAL_S
-	arm_SMLAL_S_ZZ
-	arm_SMLALBB_EQ
-	arm_SMLALBB_NE
-	arm_SMLALBB_CS
-	arm_SMLALBB_CC
-	arm_SMLALBB_MI
-	arm_SMLALBB_PL
-	arm_SMLALBB_VS
-	arm_SMLALBB_VC
-	arm_SMLALBB_HI
-	arm_SMLALBB_LS
-	arm_SMLALBB_GE
-	arm_SMLALBB_LT
-	arm_SMLALBB_GT
-	arm_SMLALBB_LE
-	arm_SMLALBB
-	arm_SMLALBB_ZZ
-	arm_SMLALBT_EQ
-	arm_SMLALBT_NE
-	arm_SMLALBT_CS
-	arm_SMLALBT_CC
-	arm_SMLALBT_MI
-	arm_SMLALBT_PL
-	arm_SMLALBT_VS
-	arm_SMLALBT_VC
-	arm_SMLALBT_HI
-	arm_SMLALBT_LS
-	arm_SMLALBT_GE
-	arm_SMLALBT_LT
-	arm_SMLALBT_GT
-	arm_SMLALBT_LE
-	arm_SMLALBT
-	arm_SMLALBT_ZZ
-	arm_SMLALTB_EQ
-	arm_SMLALTB_NE
-	arm_SMLALTB_CS
-	arm_SMLALTB_CC
-	arm_SMLALTB_MI
-	arm_SMLALTB_PL
-	arm_SMLALTB_VS
-	arm_SMLALTB_VC
-	arm_SMLALTB_HI
-	arm_SMLALTB_LS
-	arm_SMLALTB_GE
-	arm_SMLALTB_LT
-	arm_SMLALTB_GT
-	arm_SMLALTB_LE
-	arm_SMLALTB
-	arm_SMLALTB_ZZ
-	arm_SMLALTT_EQ
-	arm_SMLALTT_NE
-	arm_SMLALTT_CS
-	arm_SMLALTT_CC
-	arm_SMLALTT_MI
-	arm_SMLALTT_PL
-	arm_SMLALTT_VS
-	arm_SMLALTT_VC
-	arm_SMLALTT_HI
-	arm_SMLALTT_LS
-	arm_SMLALTT_GE
-	arm_SMLALTT_LT
-	arm_SMLALTT_GT
-	arm_SMLALTT_LE
-	arm_SMLALTT
-	arm_SMLALTT_ZZ
-	arm_SMLALD_EQ
-	arm_SMLALD_NE
-	arm_SMLALD_CS
-	arm_SMLALD_CC
-	arm_SMLALD_MI
-	arm_SMLALD_PL
-	arm_SMLALD_VS
-	arm_SMLALD_VC
-	arm_SMLALD_HI
-	arm_SMLALD_LS
-	arm_SMLALD_GE
-	arm_SMLALD_LT
-	arm_SMLALD_GT
-	arm_SMLALD_LE
-	arm_SMLALD
-	arm_SMLALD_ZZ
-	arm_SMLALD_X_EQ
-	arm_SMLALD_X_NE
-	arm_SMLALD_X_CS
-	arm_SMLALD_X_CC
-	arm_SMLALD_X_MI
-	arm_SMLALD_X_PL
-	arm_SMLALD_X_VS
-	arm_SMLALD_X_VC
-	arm_SMLALD_X_HI
-	arm_SMLALD_X_LS
-	arm_SMLALD_X_GE
-	arm_SMLALD_X_LT
-	arm_SMLALD_X_GT
-	arm_SMLALD_X_LE
-	arm_SMLALD_X
-	arm_SMLALD_X_ZZ
-	arm_SMLAWB_EQ
-	arm_SMLAWB_NE
-	arm_SMLAWB_CS
-	arm_SMLAWB_CC
-	arm_SMLAWB_MI
-	arm_SMLAWB_PL
-	arm_SMLAWB_VS
-	arm_SMLAWB_VC
-	arm_SMLAWB_HI
-	arm_SMLAWB_LS
-	arm_SMLAWB_GE
-	arm_SMLAWB_LT
-	arm_SMLAWB_GT
-	arm_SMLAWB_LE
-	arm_SMLAWB
-	arm_SMLAWB_ZZ
-	arm_SMLAWT_EQ
-	arm_SMLAWT_NE
-	arm_SMLAWT_CS
-	arm_SMLAWT_CC
-	arm_SMLAWT_MI
-	arm_SMLAWT_PL
-	arm_SMLAWT_VS
-	arm_SMLAWT_VC
-	arm_SMLAWT_HI
-	arm_SMLAWT_LS
-	arm_SMLAWT_GE
-	arm_SMLAWT_LT
-	arm_SMLAWT_GT
-	arm_SMLAWT_LE
-	arm_SMLAWT
-	arm_SMLAWT_ZZ
-	arm_SMLSD_EQ
-	arm_SMLSD_NE
-	arm_SMLSD_CS
-	arm_SMLSD_CC
-	arm_SMLSD_MI
-	arm_SMLSD_PL
-	arm_SMLSD_VS
-	arm_SMLSD_VC
-	arm_SMLSD_HI
-	arm_SMLSD_LS
-	arm_SMLSD_GE
-	arm_SMLSD_LT
-	arm_SMLSD_GT
-	arm_SMLSD_LE
-	arm_SMLSD
-	arm_SMLSD_ZZ
-	arm_SMLSD_X_EQ
-	arm_SMLSD_X_NE
-	arm_SMLSD_X_CS
-	arm_SMLSD_X_CC
-	arm_SMLSD_X_MI
-	arm_SMLSD_X_PL
-	arm_SMLSD_X_VS
-	arm_SMLSD_X_VC
-	arm_SMLSD_X_HI
-	arm_SMLSD_X_LS
-	arm_SMLSD_X_GE
-	arm_SMLSD_X_LT
-	arm_SMLSD_X_GT
-	arm_SMLSD_X_LE
-	arm_SMLSD_X
-	arm_SMLSD_X_ZZ
-	arm_SMLSLD_EQ
-	arm_SMLSLD_NE
-	arm_SMLSLD_CS
-	arm_SMLSLD_CC
-	arm_SMLSLD_MI
-	arm_SMLSLD_PL
-	arm_SMLSLD_VS
-	arm_SMLSLD_VC
-	arm_SMLSLD_HI
-	arm_SMLSLD_LS
-	arm_SMLSLD_GE
-	arm_SMLSLD_LT
-	arm_SMLSLD_GT
-	arm_SMLSLD_LE
-	arm_SMLSLD
-	arm_SMLSLD_ZZ
-	arm_SMLSLD_X_EQ
-	arm_SMLSLD_X_NE
-	arm_SMLSLD_X_CS
-	arm_SMLSLD_X_CC
-	arm_SMLSLD_X_MI
-	arm_SMLSLD_X_PL
-	arm_SMLSLD_X_VS
-	arm_SMLSLD_X_VC
-	arm_SMLSLD_X_HI
-	arm_SMLSLD_X_LS
-	arm_SMLSLD_X_GE
-	arm_SMLSLD_X_LT
-	arm_SMLSLD_X_GT
-	arm_SMLSLD_X_LE
-	arm_SMLSLD_X
-	arm_SMLSLD_X_ZZ
-	arm_SMMLA_EQ
-	arm_SMMLA_NE
-	arm_SMMLA_CS
-	arm_SMMLA_CC
-	arm_SMMLA_MI
-	arm_SMMLA_PL
-	arm_SMMLA_VS
-	arm_SMMLA_VC
-	arm_SMMLA_HI
-	arm_SMMLA_LS
-	arm_SMMLA_GE
-	arm_SMMLA_LT
-	arm_SMMLA_GT
-	arm_SMMLA_LE
-	arm_SMMLA
-	arm_SMMLA_ZZ
-	arm_SMMLA_R_EQ
-	arm_SMMLA_R_NE
-	arm_SMMLA_R_CS
-	arm_SMMLA_R_CC
-	arm_SMMLA_R_MI
-	arm_SMMLA_R_PL
-	arm_SMMLA_R_VS
-	arm_SMMLA_R_VC
-	arm_SMMLA_R_HI
-	arm_SMMLA_R_LS
-	arm_SMMLA_R_GE
-	arm_SMMLA_R_LT
-	arm_SMMLA_R_GT
-	arm_SMMLA_R_LE
-	arm_SMMLA_R
-	arm_SMMLA_R_ZZ
-	arm_SMMLS_EQ
-	arm_SMMLS_NE
-	arm_SMMLS_CS
-	arm_SMMLS_CC
-	arm_SMMLS_MI
-	arm_SMMLS_PL
-	arm_SMMLS_VS
-	arm_SMMLS_VC
-	arm_SMMLS_HI
-	arm_SMMLS_LS
-	arm_SMMLS_GE
-	arm_SMMLS_LT
-	arm_SMMLS_GT
-	arm_SMMLS_LE
-	arm_SMMLS
-	arm_SMMLS_ZZ
-	arm_SMMLS_R_EQ
-	arm_SMMLS_R_NE
-	arm_SMMLS_R_CS
-	arm_SMMLS_R_CC
-	arm_SMMLS_R_MI
-	arm_SMMLS_R_PL
-	arm_SMMLS_R_VS
-	arm_SMMLS_R_VC
-	arm_SMMLS_R_HI
-	arm_SMMLS_R_LS
-	arm_SMMLS_R_GE
-	arm_SMMLS_R_LT
-	arm_SMMLS_R_GT
-	arm_SMMLS_R_LE
-	arm_SMMLS_R
-	arm_SMMLS_R_ZZ
-	arm_SMMUL_EQ
-	arm_SMMUL_NE
-	arm_SMMUL_CS
-	arm_SMMUL_CC
-	arm_SMMUL_MI
-	arm_SMMUL_PL
-	arm_SMMUL_VS
-	arm_SMMUL_VC
-	arm_SMMUL_HI
-	arm_SMMUL_LS
-	arm_SMMUL_GE
-	arm_SMMUL_LT
-	arm_SMMUL_GT
-	arm_SMMUL_LE
-	arm_SMMUL
-	arm_SMMUL_ZZ
-	arm_SMMUL_R_EQ
-	arm_SMMUL_R_NE
-	arm_SMMUL_R_CS
-	arm_SMMUL_R_CC
-	arm_SMMUL_R_MI
-	arm_SMMUL_R_PL
-	arm_SMMUL_R_VS
-	arm_SMMUL_R_VC
-	arm_SMMUL_R_HI
-	arm_SMMUL_R_LS
-	arm_SMMUL_R_GE
-	arm_SMMUL_R_LT
-	arm_SMMUL_R_GT
-	arm_SMMUL_R_LE
-	arm_SMMUL_R
-	arm_SMMUL_R_ZZ
-	arm_SMUAD_EQ
-	arm_SMUAD_NE
-	arm_SMUAD_CS
-	arm_SMUAD_CC
-	arm_SMUAD_MI
-	arm_SMUAD_PL
-	arm_SMUAD_VS
-	arm_SMUAD_VC
-	arm_SMUAD_HI
-	arm_SMUAD_LS
-	arm_SMUAD_GE
-	arm_SMUAD_LT
-	arm_SMUAD_GT
-	arm_SMUAD_LE
-	arm_SMUAD
-	arm_SMUAD_ZZ
-	arm_SMUAD_X_EQ
-	arm_SMUAD_X_NE
-	arm_SMUAD_X_CS
-	arm_SMUAD_X_CC
-	arm_SMUAD_X_MI
-	arm_SMUAD_X_PL
-	arm_SMUAD_X_VS
-	arm_SMUAD_X_VC
-	arm_SMUAD_X_HI
-	arm_SMUAD_X_LS
-	arm_SMUAD_X_GE
-	arm_SMUAD_X_LT
-	arm_SMUAD_X_GT
-	arm_SMUAD_X_LE
-	arm_SMUAD_X
-	arm_SMUAD_X_ZZ
-	arm_SMULBB_EQ
-	arm_SMULBB_NE
-	arm_SMULBB_CS
-	arm_SMULBB_CC
-	arm_SMULBB_MI
-	arm_SMULBB_PL
-	arm_SMULBB_VS
-	arm_SMULBB_VC
-	arm_SMULBB_HI
-	arm_SMULBB_LS
-	arm_SMULBB_GE
-	arm_SMULBB_LT
-	arm_SMULBB_GT
-	arm_SMULBB_LE
-	arm_SMULBB
-	arm_SMULBB_ZZ
-	arm_SMULBT_EQ
-	arm_SMULBT_NE
-	arm_SMULBT_CS
-	arm_SMULBT_CC
-	arm_SMULBT_MI
-	arm_SMULBT_PL
-	arm_SMULBT_VS
-	arm_SMULBT_VC
-	arm_SMULBT_HI
-	arm_SMULBT_LS
-	arm_SMULBT_GE
-	arm_SMULBT_LT
-	arm_SMULBT_GT
-	arm_SMULBT_LE
-	arm_SMULBT
-	arm_SMULBT_ZZ
-	arm_SMULTB_EQ
-	arm_SMULTB_NE
-	arm_SMULTB_CS
-	arm_SMULTB_CC
-	arm_SMULTB_MI
-	arm_SMULTB_PL
-	arm_SMULTB_VS
-	arm_SMULTB_VC
-	arm_SMULTB_HI
-	arm_SMULTB_LS
-	arm_SMULTB_GE
-	arm_SMULTB_LT
-	arm_SMULTB_GT
-	arm_SMULTB_LE
-	arm_SMULTB
-	arm_SMULTB_ZZ
-	arm_SMULTT_EQ
-	arm_SMULTT_NE
-	arm_SMULTT_CS
-	arm_SMULTT_CC
-	arm_SMULTT_MI
-	arm_SMULTT_PL
-	arm_SMULTT_VS
-	arm_SMULTT_VC
-	arm_SMULTT_HI
-	arm_SMULTT_LS
-	arm_SMULTT_GE
-	arm_SMULTT_LT
-	arm_SMULTT_GT
-	arm_SMULTT_LE
-	arm_SMULTT
-	arm_SMULTT_ZZ
-	arm_SMULL_EQ
-	arm_SMULL_NE
-	arm_SMULL_CS
-	arm_SMULL_CC
-	arm_SMULL_MI
-	arm_SMULL_PL
-	arm_SMULL_VS
-	arm_SMULL_VC
-	arm_SMULL_HI
-	arm_SMULL_LS
-	arm_SMULL_GE
-	arm_SMULL_LT
-	arm_SMULL_GT
-	arm_SMULL_LE
-	arm_SMULL
-	arm_SMULL_ZZ
-	arm_SMULL_S_EQ
-	arm_SMULL_S_NE
-	arm_SMULL_S_CS
-	arm_SMULL_S_CC
-	arm_SMULL_S_MI
-	arm_SMULL_S_PL
-	arm_SMULL_S_VS
-	arm_SMULL_S_VC
-	arm_SMULL_S_HI
-	arm_SMULL_S_LS
-	arm_SMULL_S_GE
-	arm_SMULL_S_LT
-	arm_SMULL_S_GT
-	arm_SMULL_S_LE
-	arm_SMULL_S
-	arm_SMULL_S_ZZ
-	arm_SMULWB_EQ
-	arm_SMULWB_NE
-	arm_SMULWB_CS
-	arm_SMULWB_CC
-	arm_SMULWB_MI
-	arm_SMULWB_PL
-	arm_SMULWB_VS
-	arm_SMULWB_VC
-	arm_SMULWB_HI
-	arm_SMULWB_LS
-	arm_SMULWB_GE
-	arm_SMULWB_LT
-	arm_SMULWB_GT
-	arm_SMULWB_LE
-	arm_SMULWB
-	arm_SMULWB_ZZ
-	arm_SMULWT_EQ
-	arm_SMULWT_NE
-	arm_SMULWT_CS
-	arm_SMULWT_CC
-	arm_SMULWT_MI
-	arm_SMULWT_PL
-	arm_SMULWT_VS
-	arm_SMULWT_VC
-	arm_SMULWT_HI
-	arm_SMULWT_LS
-	arm_SMULWT_GE
-	arm_SMULWT_LT
-	arm_SMULWT_GT
-	arm_SMULWT_LE
-	arm_SMULWT
-	arm_SMULWT_ZZ
-	arm_SMUSD_EQ
-	arm_SMUSD_NE
-	arm_SMUSD_CS
-	arm_SMUSD_CC
-	arm_SMUSD_MI
-	arm_SMUSD_PL
-	arm_SMUSD_VS
-	arm_SMUSD_VC
-	arm_SMUSD_HI
-	arm_SMUSD_LS
-	arm_SMUSD_GE
-	arm_SMUSD_LT
-	arm_SMUSD_GT
-	arm_SMUSD_LE
-	arm_SMUSD
-	arm_SMUSD_ZZ
-	arm_SMUSD_X_EQ
-	arm_SMUSD_X_NE
-	arm_SMUSD_X_CS
-	arm_SMUSD_X_CC
-	arm_SMUSD_X_MI
-	arm_SMUSD_X_PL
-	arm_SMUSD_X_VS
-	arm_SMUSD_X_VC
-	arm_SMUSD_X_HI
-	arm_SMUSD_X_LS
-	arm_SMUSD_X_GE
-	arm_SMUSD_X_LT
-	arm_SMUSD_X_GT
-	arm_SMUSD_X_LE
-	arm_SMUSD_X
-	arm_SMUSD_X_ZZ
-	arm_SSAT_EQ
-	arm_SSAT_NE
-	arm_SSAT_CS
-	arm_SSAT_CC
-	arm_SSAT_MI
-	arm_SSAT_PL
-	arm_SSAT_VS
-	arm_SSAT_VC
-	arm_SSAT_HI
-	arm_SSAT_LS
-	arm_SSAT_GE
-	arm_SSAT_LT
-	arm_SSAT_GT
-	arm_SSAT_LE
-	arm_SSAT
-	arm_SSAT_ZZ
-	arm_SSAT16_EQ
-	arm_SSAT16_NE
-	arm_SSAT16_CS
-	arm_SSAT16_CC
-	arm_SSAT16_MI
-	arm_SSAT16_PL
-	arm_SSAT16_VS
-	arm_SSAT16_VC
-	arm_SSAT16_HI
-	arm_SSAT16_LS
-	arm_SSAT16_GE
-	arm_SSAT16_LT
-	arm_SSAT16_GT
-	arm_SSAT16_LE
-	arm_SSAT16
-	arm_SSAT16_ZZ
-	arm_SSAX_EQ
-	arm_SSAX_NE
-	arm_SSAX_CS
-	arm_SSAX_CC
-	arm_SSAX_MI
-	arm_SSAX_PL
-	arm_SSAX_VS
-	arm_SSAX_VC
-	arm_SSAX_HI
-	arm_SSAX_LS
-	arm_SSAX_GE
-	arm_SSAX_LT
-	arm_SSAX_GT
-	arm_SSAX_LE
-	arm_SSAX
-	arm_SSAX_ZZ
-	arm_SSUB16_EQ
-	arm_SSUB16_NE
-	arm_SSUB16_CS
-	arm_SSUB16_CC
-	arm_SSUB16_MI
-	arm_SSUB16_PL
-	arm_SSUB16_VS
-	arm_SSUB16_VC
-	arm_SSUB16_HI
-	arm_SSUB16_LS
-	arm_SSUB16_GE
-	arm_SSUB16_LT
-	arm_SSUB16_GT
-	arm_SSUB16_LE
-	arm_SSUB16
-	arm_SSUB16_ZZ
-	arm_SSUB8_EQ
-	arm_SSUB8_NE
-	arm_SSUB8_CS
-	arm_SSUB8_CC
-	arm_SSUB8_MI
-	arm_SSUB8_PL
-	arm_SSUB8_VS
-	arm_SSUB8_VC
-	arm_SSUB8_HI
-	arm_SSUB8_LS
-	arm_SSUB8_GE
-	arm_SSUB8_LT
-	arm_SSUB8_GT
-	arm_SSUB8_LE
-	arm_SSUB8
-	arm_SSUB8_ZZ
-	arm_STM_EQ
-	arm_STM_NE
-	arm_STM_CS
-	arm_STM_CC
-	arm_STM_MI
-	arm_STM_PL
-	arm_STM_VS
-	arm_STM_VC
-	arm_STM_HI
-	arm_STM_LS
-	arm_STM_GE
-	arm_STM_LT
-	arm_STM_GT
-	arm_STM_LE
-	arm_STM
-	arm_STM_ZZ
-	arm_STMDA_EQ
-	arm_STMDA_NE
-	arm_STMDA_CS
-	arm_STMDA_CC
-	arm_STMDA_MI
-	arm_STMDA_PL
-	arm_STMDA_VS
-	arm_STMDA_VC
-	arm_STMDA_HI
-	arm_STMDA_LS
-	arm_STMDA_GE
-	arm_STMDA_LT
-	arm_STMDA_GT
-	arm_STMDA_LE
-	arm_STMDA
-	arm_STMDA_ZZ
-	arm_STMDB_EQ
-	arm_STMDB_NE
-	arm_STMDB_CS
-	arm_STMDB_CC
-	arm_STMDB_MI
-	arm_STMDB_PL
-	arm_STMDB_VS
-	arm_STMDB_VC
-	arm_STMDB_HI
-	arm_STMDB_LS
-	arm_STMDB_GE
-	arm_STMDB_LT
-	arm_STMDB_GT
-	arm_STMDB_LE
-	arm_STMDB
-	arm_STMDB_ZZ
-	arm_STMIB_EQ
-	arm_STMIB_NE
-	arm_STMIB_CS
-	arm_STMIB_CC
-	arm_STMIB_MI
-	arm_STMIB_PL
-	arm_STMIB_VS
-	arm_STMIB_VC
-	arm_STMIB_HI
-	arm_STMIB_LS
-	arm_STMIB_GE
-	arm_STMIB_LT
-	arm_STMIB_GT
-	arm_STMIB_LE
-	arm_STMIB
-	arm_STMIB_ZZ
-	arm_STR_EQ
-	arm_STR_NE
-	arm_STR_CS
-	arm_STR_CC
-	arm_STR_MI
-	arm_STR_PL
-	arm_STR_VS
-	arm_STR_VC
-	arm_STR_HI
-	arm_STR_LS
-	arm_STR_GE
-	arm_STR_LT
-	arm_STR_GT
-	arm_STR_LE
-	arm_STR
-	arm_STR_ZZ
-	arm_STRB_EQ
-	arm_STRB_NE
-	arm_STRB_CS
-	arm_STRB_CC
-	arm_STRB_MI
-	arm_STRB_PL
-	arm_STRB_VS
-	arm_STRB_VC
-	arm_STRB_HI
-	arm_STRB_LS
-	arm_STRB_GE
-	arm_STRB_LT
-	arm_STRB_GT
-	arm_STRB_LE
-	arm_STRB
-	arm_STRB_ZZ
-	arm_STRBT_EQ
-	arm_STRBT_NE
-	arm_STRBT_CS
-	arm_STRBT_CC
-	arm_STRBT_MI
-	arm_STRBT_PL
-	arm_STRBT_VS
-	arm_STRBT_VC
-	arm_STRBT_HI
-	arm_STRBT_LS
-	arm_STRBT_GE
-	arm_STRBT_LT
-	arm_STRBT_GT
-	arm_STRBT_LE
-	arm_STRBT
-	arm_STRBT_ZZ
-	arm_STRD_EQ
-	arm_STRD_NE
-	arm_STRD_CS
-	arm_STRD_CC
-	arm_STRD_MI
-	arm_STRD_PL
-	arm_STRD_VS
-	arm_STRD_VC
-	arm_STRD_HI
-	arm_STRD_LS
-	arm_STRD_GE
-	arm_STRD_LT
-	arm_STRD_GT
-	arm_STRD_LE
-	arm_STRD
-	arm_STRD_ZZ
-	arm_STREX_EQ
-	arm_STREX_NE
-	arm_STREX_CS
-	arm_STREX_CC
-	arm_STREX_MI
-	arm_STREX_PL
-	arm_STREX_VS
-	arm_STREX_VC
-	arm_STREX_HI
-	arm_STREX_LS
-	arm_STREX_GE
-	arm_STREX_LT
-	arm_STREX_GT
-	arm_STREX_LE
-	arm_STREX
-	arm_STREX_ZZ
-	arm_STREXB_EQ
-	arm_STREXB_NE
-	arm_STREXB_CS
-	arm_STREXB_CC
-	arm_STREXB_MI
-	arm_STREXB_PL
-	arm_STREXB_VS
-	arm_STREXB_VC
-	arm_STREXB_HI
-	arm_STREXB_LS
-	arm_STREXB_GE
-	arm_STREXB_LT
-	arm_STREXB_GT
-	arm_STREXB_LE
-	arm_STREXB
-	arm_STREXB_ZZ
-	arm_STREXD_EQ
-	arm_STREXD_NE
-	arm_STREXD_CS
-	arm_STREXD_CC
-	arm_STREXD_MI
-	arm_STREXD_PL
-	arm_STREXD_VS
-	arm_STREXD_VC
-	arm_STREXD_HI
-	arm_STREXD_LS
-	arm_STREXD_GE
-	arm_STREXD_LT
-	arm_STREXD_GT
-	arm_STREXD_LE
-	arm_STREXD
-	arm_STREXD_ZZ
-	arm_STREXH_EQ
-	arm_STREXH_NE
-	arm_STREXH_CS
-	arm_STREXH_CC
-	arm_STREXH_MI
-	arm_STREXH_PL
-	arm_STREXH_VS
-	arm_STREXH_VC
-	arm_STREXH_HI
-	arm_STREXH_LS
-	arm_STREXH_GE
-	arm_STREXH_LT
-	arm_STREXH_GT
-	arm_STREXH_LE
-	arm_STREXH
-	arm_STREXH_ZZ
-	arm_STRH_EQ
-	arm_STRH_NE
-	arm_STRH_CS
-	arm_STRH_CC
-	arm_STRH_MI
-	arm_STRH_PL
-	arm_STRH_VS
-	arm_STRH_VC
-	arm_STRH_HI
-	arm_STRH_LS
-	arm_STRH_GE
-	arm_STRH_LT
-	arm_STRH_GT
-	arm_STRH_LE
-	arm_STRH
-	arm_STRH_ZZ
-	arm_STRHT_EQ
-	arm_STRHT_NE
-	arm_STRHT_CS
-	arm_STRHT_CC
-	arm_STRHT_MI
-	arm_STRHT_PL
-	arm_STRHT_VS
-	arm_STRHT_VC
-	arm_STRHT_HI
-	arm_STRHT_LS
-	arm_STRHT_GE
-	arm_STRHT_LT
-	arm_STRHT_GT
-	arm_STRHT_LE
-	arm_STRHT
-	arm_STRHT_ZZ
-	arm_STRT_EQ
-	arm_STRT_NE
-	arm_STRT_CS
-	arm_STRT_CC
-	arm_STRT_MI
-	arm_STRT_PL
-	arm_STRT_VS
-	arm_STRT_VC
-	arm_STRT_HI
-	arm_STRT_LS
-	arm_STRT_GE
-	arm_STRT_LT
-	arm_STRT_GT
-	arm_STRT_LE
-	arm_STRT
-	arm_STRT_ZZ
-	arm_SUB_EQ
-	arm_SUB_NE
-	arm_SUB_CS
-	arm_SUB_CC
-	arm_SUB_MI
-	arm_SUB_PL
-	arm_SUB_VS
-	arm_SUB_VC
-	arm_SUB_HI
-	arm_SUB_LS
-	arm_SUB_GE
-	arm_SUB_LT
-	arm_SUB_GT
-	arm_SUB_LE
-	arm_SUB
-	arm_SUB_ZZ
-	arm_SUB_S_EQ
-	arm_SUB_S_NE
-	arm_SUB_S_CS
-	arm_SUB_S_CC
-	arm_SUB_S_MI
-	arm_SUB_S_PL
-	arm_SUB_S_VS
-	arm_SUB_S_VC
-	arm_SUB_S_HI
-	arm_SUB_S_LS
-	arm_SUB_S_GE
-	arm_SUB_S_LT
-	arm_SUB_S_GT
-	arm_SUB_S_LE
-	arm_SUB_S
-	arm_SUB_S_ZZ
-	arm_SVC_EQ
-	arm_SVC_NE
-	arm_SVC_CS
-	arm_SVC_CC
-	arm_SVC_MI
-	arm_SVC_PL
-	arm_SVC_VS
-	arm_SVC_VC
-	arm_SVC_HI
-	arm_SVC_LS
-	arm_SVC_GE
-	arm_SVC_LT
-	arm_SVC_GT
-	arm_SVC_LE
-	arm_SVC
-	arm_SVC_ZZ
-	arm_SWP_EQ
-	arm_SWP_NE
-	arm_SWP_CS
-	arm_SWP_CC
-	arm_SWP_MI
-	arm_SWP_PL
-	arm_SWP_VS
-	arm_SWP_VC
-	arm_SWP_HI
-	arm_SWP_LS
-	arm_SWP_GE
-	arm_SWP_LT
-	arm_SWP_GT
-	arm_SWP_LE
-	arm_SWP
-	arm_SWP_ZZ
-	arm_SWP_B_EQ
-	arm_SWP_B_NE
-	arm_SWP_B_CS
-	arm_SWP_B_CC
-	arm_SWP_B_MI
-	arm_SWP_B_PL
-	arm_SWP_B_VS
-	arm_SWP_B_VC
-	arm_SWP_B_HI
-	arm_SWP_B_LS
-	arm_SWP_B_GE
-	arm_SWP_B_LT
-	arm_SWP_B_GT
-	arm_SWP_B_LE
-	arm_SWP_B
-	arm_SWP_B_ZZ
-	arm_SXTAB_EQ
-	arm_SXTAB_NE
-	arm_SXTAB_CS
-	arm_SXTAB_CC
-	arm_SXTAB_MI
-	arm_SXTAB_PL
-	arm_SXTAB_VS
-	arm_SXTAB_VC
-	arm_SXTAB_HI
-	arm_SXTAB_LS
-	arm_SXTAB_GE
-	arm_SXTAB_LT
-	arm_SXTAB_GT
-	arm_SXTAB_LE
-	arm_SXTAB
-	arm_SXTAB_ZZ
-	arm_SXTAB16_EQ
-	arm_SXTAB16_NE
-	arm_SXTAB16_CS
-	arm_SXTAB16_CC
-	arm_SXTAB16_MI
-	arm_SXTAB16_PL
-	arm_SXTAB16_VS
-	arm_SXTAB16_VC
-	arm_SXTAB16_HI
-	arm_SXTAB16_LS
-	arm_SXTAB16_GE
-	arm_SXTAB16_LT
-	arm_SXTAB16_GT
-	arm_SXTAB16_LE
-	arm_SXTAB16
-	arm_SXTAB16_ZZ
-	arm_SXTAH_EQ
-	arm_SXTAH_NE
-	arm_SXTAH_CS
-	arm_SXTAH_CC
-	arm_SXTAH_MI
-	arm_SXTAH_PL
-	arm_SXTAH_VS
-	arm_SXTAH_VC
-	arm_SXTAH_HI
-	arm_SXTAH_LS
-	arm_SXTAH_GE
-	arm_SXTAH_LT
-	arm_SXTAH_GT
-	arm_SXTAH_LE
-	arm_SXTAH
-	arm_SXTAH_ZZ
-	arm_SXTB_EQ
-	arm_SXTB_NE
-	arm_SXTB_CS
-	arm_SXTB_CC
-	arm_SXTB_MI
-	arm_SXTB_PL
-	arm_SXTB_VS
-	arm_SXTB_VC
-	arm_SXTB_HI
-	arm_SXTB_LS
-	arm_SXTB_GE
-	arm_SXTB_LT
-	arm_SXTB_GT
-	arm_SXTB_LE
-	arm_SXTB
-	arm_SXTB_ZZ
-	arm_SXTB16_EQ
-	arm_SXTB16_NE
-	arm_SXTB16_CS
-	arm_SXTB16_CC
-	arm_SXTB16_MI
-	arm_SXTB16_PL
-	arm_SXTB16_VS
-	arm_SXTB16_VC
-	arm_SXTB16_HI
-	arm_SXTB16_LS
-	arm_SXTB16_GE
-	arm_SXTB16_LT
-	arm_SXTB16_GT
-	arm_SXTB16_LE
-	arm_SXTB16
-	arm_SXTB16_ZZ
-	arm_SXTH_EQ
-	arm_SXTH_NE
-	arm_SXTH_CS
-	arm_SXTH_CC
-	arm_SXTH_MI
-	arm_SXTH_PL
-	arm_SXTH_VS
-	arm_SXTH_VC
-	arm_SXTH_HI
-	arm_SXTH_LS
-	arm_SXTH_GE
-	arm_SXTH_LT
-	arm_SXTH_GT
-	arm_SXTH_LE
-	arm_SXTH
-	arm_SXTH_ZZ
-	arm_TEQ_EQ
-	arm_TEQ_NE
-	arm_TEQ_CS
-	arm_TEQ_CC
-	arm_TEQ_MI
-	arm_TEQ_PL
-	arm_TEQ_VS
-	arm_TEQ_VC
-	arm_TEQ_HI
-	arm_TEQ_LS
-	arm_TEQ_GE
-	arm_TEQ_LT
-	arm_TEQ_GT
-	arm_TEQ_LE
-	arm_TEQ
-	arm_TEQ_ZZ
-	arm_TST_EQ
-	arm_TST_NE
-	arm_TST_CS
-	arm_TST_CC
-	arm_TST_MI
-	arm_TST_PL
-	arm_TST_VS
-	arm_TST_VC
-	arm_TST_HI
-	arm_TST_LS
-	arm_TST_GE
-	arm_TST_LT
-	arm_TST_GT
-	arm_TST_LE
-	arm_TST
-	arm_TST_ZZ
-	arm_UADD16_EQ
-	arm_UADD16_NE
-	arm_UADD16_CS
-	arm_UADD16_CC
-	arm_UADD16_MI
-	arm_UADD16_PL
-	arm_UADD16_VS
-	arm_UADD16_VC
-	arm_UADD16_HI
-	arm_UADD16_LS
-	arm_UADD16_GE
-	arm_UADD16_LT
-	arm_UADD16_GT
-	arm_UADD16_LE
-	arm_UADD16
-	arm_UADD16_ZZ
-	arm_UADD8_EQ
-	arm_UADD8_NE
-	arm_UADD8_CS
-	arm_UADD8_CC
-	arm_UADD8_MI
-	arm_UADD8_PL
-	arm_UADD8_VS
-	arm_UADD8_VC
-	arm_UADD8_HI
-	arm_UADD8_LS
-	arm_UADD8_GE
-	arm_UADD8_LT
-	arm_UADD8_GT
-	arm_UADD8_LE
-	arm_UADD8
-	arm_UADD8_ZZ
-	arm_UASX_EQ
-	arm_UASX_NE
-	arm_UASX_CS
-	arm_UASX_CC
-	arm_UASX_MI
-	arm_UASX_PL
-	arm_UASX_VS
-	arm_UASX_VC
-	arm_UASX_HI
-	arm_UASX_LS
-	arm_UASX_GE
-	arm_UASX_LT
-	arm_UASX_GT
-	arm_UASX_LE
-	arm_UASX
-	arm_UASX_ZZ
-	arm_UBFX_EQ
-	arm_UBFX_NE
-	arm_UBFX_CS
-	arm_UBFX_CC
-	arm_UBFX_MI
-	arm_UBFX_PL
-	arm_UBFX_VS
-	arm_UBFX_VC
-	arm_UBFX_HI
-	arm_UBFX_LS
-	arm_UBFX_GE
-	arm_UBFX_LT
-	arm_UBFX_GT
-	arm_UBFX_LE
-	arm_UBFX
-	arm_UBFX_ZZ
-	arm_UHADD16_EQ
-	arm_UHADD16_NE
-	arm_UHADD16_CS
-	arm_UHADD16_CC
-	arm_UHADD16_MI
-	arm_UHADD16_PL
-	arm_UHADD16_VS
-	arm_UHADD16_VC
-	arm_UHADD16_HI
-	arm_UHADD16_LS
-	arm_UHADD16_GE
-	arm_UHADD16_LT
-	arm_UHADD16_GT
-	arm_UHADD16_LE
-	arm_UHADD16
-	arm_UHADD16_ZZ
-	arm_UHADD8_EQ
-	arm_UHADD8_NE
-	arm_UHADD8_CS
-	arm_UHADD8_CC
-	arm_UHADD8_MI
-	arm_UHADD8_PL
-	arm_UHADD8_VS
-	arm_UHADD8_VC
-	arm_UHADD8_HI
-	arm_UHADD8_LS
-	arm_UHADD8_GE
-	arm_UHADD8_LT
-	arm_UHADD8_GT
-	arm_UHADD8_LE
-	arm_UHADD8
-	arm_UHADD8_ZZ
-	arm_UHASX_EQ
-	arm_UHASX_NE
-	arm_UHASX_CS
-	arm_UHASX_CC
-	arm_UHASX_MI
-	arm_UHASX_PL
-	arm_UHASX_VS
-	arm_UHASX_VC
-	arm_UHASX_HI
-	arm_UHASX_LS
-	arm_UHASX_GE
-	arm_UHASX_LT
-	arm_UHASX_GT
-	arm_UHASX_LE
-	arm_UHASX
-	arm_UHASX_ZZ
-	arm_UHSAX_EQ
-	arm_UHSAX_NE
-	arm_UHSAX_CS
-	arm_UHSAX_CC
-	arm_UHSAX_MI
-	arm_UHSAX_PL
-	arm_UHSAX_VS
-	arm_UHSAX_VC
-	arm_UHSAX_HI
-	arm_UHSAX_LS
-	arm_UHSAX_GE
-	arm_UHSAX_LT
-	arm_UHSAX_GT
-	arm_UHSAX_LE
-	arm_UHSAX
-	arm_UHSAX_ZZ
-	arm_UHSUB16_EQ
-	arm_UHSUB16_NE
-	arm_UHSUB16_CS
-	arm_UHSUB16_CC
-	arm_UHSUB16_MI
-	arm_UHSUB16_PL
-	arm_UHSUB16_VS
-	arm_UHSUB16_VC
-	arm_UHSUB16_HI
-	arm_UHSUB16_LS
-	arm_UHSUB16_GE
-	arm_UHSUB16_LT
-	arm_UHSUB16_GT
-	arm_UHSUB16_LE
-	arm_UHSUB16
-	arm_UHSUB16_ZZ
-	arm_UHSUB8_EQ
-	arm_UHSUB8_NE
-	arm_UHSUB8_CS
-	arm_UHSUB8_CC
-	arm_UHSUB8_MI
-	arm_UHSUB8_PL
-	arm_UHSUB8_VS
-	arm_UHSUB8_VC
-	arm_UHSUB8_HI
-	arm_UHSUB8_LS
-	arm_UHSUB8_GE
-	arm_UHSUB8_LT
-	arm_UHSUB8_GT
-	arm_UHSUB8_LE
-	arm_UHSUB8
-	arm_UHSUB8_ZZ
-	arm_UMAAL_EQ
-	arm_UMAAL_NE
-	arm_UMAAL_CS
-	arm_UMAAL_CC
-	arm_UMAAL_MI
-	arm_UMAAL_PL
-	arm_UMAAL_VS
-	arm_UMAAL_VC
-	arm_UMAAL_HI
-	arm_UMAAL_LS
-	arm_UMAAL_GE
-	arm_UMAAL_LT
-	arm_UMAAL_GT
-	arm_UMAAL_LE
-	arm_UMAAL
-	arm_UMAAL_ZZ
-	arm_UMLAL_EQ
-	arm_UMLAL_NE
-	arm_UMLAL_CS
-	arm_UMLAL_CC
-	arm_UMLAL_MI
-	arm_UMLAL_PL
-	arm_UMLAL_VS
-	arm_UMLAL_VC
-	arm_UMLAL_HI
-	arm_UMLAL_LS
-	arm_UMLAL_GE
-	arm_UMLAL_LT
-	arm_UMLAL_GT
-	arm_UMLAL_LE
-	arm_UMLAL
-	arm_UMLAL_ZZ
-	arm_UMLAL_S_EQ
-	arm_UMLAL_S_NE
-	arm_UMLAL_S_CS
-	arm_UMLAL_S_CC
-	arm_UMLAL_S_MI
-	arm_UMLAL_S_PL
-	arm_UMLAL_S_VS
-	arm_UMLAL_S_VC
-	arm_UMLAL_S_HI
-	arm_UMLAL_S_LS
-	arm_UMLAL_S_GE
-	arm_UMLAL_S_LT
-	arm_UMLAL_S_GT
-	arm_UMLAL_S_LE
-	arm_UMLAL_S
-	arm_UMLAL_S_ZZ
-	arm_UMULL_EQ
-	arm_UMULL_NE
-	arm_UMULL_CS
-	arm_UMULL_CC
-	arm_UMULL_MI
-	arm_UMULL_PL
-	arm_UMULL_VS
-	arm_UMULL_VC
-	arm_UMULL_HI
-	arm_UMULL_LS
-	arm_UMULL_GE
-	arm_UMULL_LT
-	arm_UMULL_GT
-	arm_UMULL_LE
-	arm_UMULL
-	arm_UMULL_ZZ
-	arm_UMULL_S_EQ
-	arm_UMULL_S_NE
-	arm_UMULL_S_CS
-	arm_UMULL_S_CC
-	arm_UMULL_S_MI
-	arm_UMULL_S_PL
-	arm_UMULL_S_VS
-	arm_UMULL_S_VC
-	arm_UMULL_S_HI
-	arm_UMULL_S_LS
-	arm_UMULL_S_GE
-	arm_UMULL_S_LT
-	arm_UMULL_S_GT
-	arm_UMULL_S_LE
-	arm_UMULL_S
-	arm_UMULL_S_ZZ
-	arm_UNDEF
-	_
-	_
-	_
-	_
-	_
-	_
-	_
-	_
-	_
-	_
-	_
-	_
-	_
-	_
-	_
-	arm_UQADD16_EQ
-	arm_UQADD16_NE
-	arm_UQADD16_CS
-	arm_UQADD16_CC
-	arm_UQADD16_MI
-	arm_UQADD16_PL
-	arm_UQADD16_VS
-	arm_UQADD16_VC
-	arm_UQADD16_HI
-	arm_UQADD16_LS
-	arm_UQADD16_GE
-	arm_UQADD16_LT
-	arm_UQADD16_GT
-	arm_UQADD16_LE
-	arm_UQADD16
-	arm_UQADD16_ZZ
-	arm_UQADD8_EQ
-	arm_UQADD8_NE
-	arm_UQADD8_CS
-	arm_UQADD8_CC
-	arm_UQADD8_MI
-	arm_UQADD8_PL
-	arm_UQADD8_VS
-	arm_UQADD8_VC
-	arm_UQADD8_HI
-	arm_UQADD8_LS
-	arm_UQADD8_GE
-	arm_UQADD8_LT
-	arm_UQADD8_GT
-	arm_UQADD8_LE
-	arm_UQADD8
-	arm_UQADD8_ZZ
-	arm_UQASX_EQ
-	arm_UQASX_NE
-	arm_UQASX_CS
-	arm_UQASX_CC
-	arm_UQASX_MI
-	arm_UQASX_PL
-	arm_UQASX_VS
-	arm_UQASX_VC
-	arm_UQASX_HI
-	arm_UQASX_LS
-	arm_UQASX_GE
-	arm_UQASX_LT
-	arm_UQASX_GT
-	arm_UQASX_LE
-	arm_UQASX
-	arm_UQASX_ZZ
-	arm_UQSAX_EQ
-	arm_UQSAX_NE
-	arm_UQSAX_CS
-	arm_UQSAX_CC
-	arm_UQSAX_MI
-	arm_UQSAX_PL
-	arm_UQSAX_VS
-	arm_UQSAX_VC
-	arm_UQSAX_HI
-	arm_UQSAX_LS
-	arm_UQSAX_GE
-	arm_UQSAX_LT
-	arm_UQSAX_GT
-	arm_UQSAX_LE
-	arm_UQSAX
-	arm_UQSAX_ZZ
-	arm_UQSUB16_EQ
-	arm_UQSUB16_NE
-	arm_UQSUB16_CS
-	arm_UQSUB16_CC
-	arm_UQSUB16_MI
-	arm_UQSUB16_PL
-	arm_UQSUB16_VS
-	arm_UQSUB16_VC
-	arm_UQSUB16_HI
-	arm_UQSUB16_LS
-	arm_UQSUB16_GE
-	arm_UQSUB16_LT
-	arm_UQSUB16_GT
-	arm_UQSUB16_LE
-	arm_UQSUB16
-	arm_UQSUB16_ZZ
-	arm_UQSUB8_EQ
-	arm_UQSUB8_NE
-	arm_UQSUB8_CS
-	arm_UQSUB8_CC
-	arm_UQSUB8_MI
-	arm_UQSUB8_PL
-	arm_UQSUB8_VS
-	arm_UQSUB8_VC
-	arm_UQSUB8_HI
-	arm_UQSUB8_LS
-	arm_UQSUB8_GE
-	arm_UQSUB8_LT
-	arm_UQSUB8_GT
-	arm_UQSUB8_LE
-	arm_UQSUB8
-	arm_UQSUB8_ZZ
-	arm_USAD8_EQ
-	arm_USAD8_NE
-	arm_USAD8_CS
-	arm_USAD8_CC
-	arm_USAD8_MI
-	arm_USAD8_PL
-	arm_USAD8_VS
-	arm_USAD8_VC
-	arm_USAD8_HI
-	arm_USAD8_LS
-	arm_USAD8_GE
-	arm_USAD8_LT
-	arm_USAD8_GT
-	arm_USAD8_LE
-	arm_USAD8
-	arm_USAD8_ZZ
-	arm_USADA8_EQ
-	arm_USADA8_NE
-	arm_USADA8_CS
-	arm_USADA8_CC
-	arm_USADA8_MI
-	arm_USADA8_PL
-	arm_USADA8_VS
-	arm_USADA8_VC
-	arm_USADA8_HI
-	arm_USADA8_LS
-	arm_USADA8_GE
-	arm_USADA8_LT
-	arm_USADA8_GT
-	arm_USADA8_LE
-	arm_USADA8
-	arm_USADA8_ZZ
-	arm_USAT_EQ
-	arm_USAT_NE
-	arm_USAT_CS
-	arm_USAT_CC
-	arm_USAT_MI
-	arm_USAT_PL
-	arm_USAT_VS
-	arm_USAT_VC
-	arm_USAT_HI
-	arm_USAT_LS
-	arm_USAT_GE
-	arm_USAT_LT
-	arm_USAT_GT
-	arm_USAT_LE
-	arm_USAT
-	arm_USAT_ZZ
-	arm_USAT16_EQ
-	arm_USAT16_NE
-	arm_USAT16_CS
-	arm_USAT16_CC
-	arm_USAT16_MI
-	arm_USAT16_PL
-	arm_USAT16_VS
-	arm_USAT16_VC
-	arm_USAT16_HI
-	arm_USAT16_LS
-	arm_USAT16_GE
-	arm_USAT16_LT
-	arm_USAT16_GT
-	arm_USAT16_LE
-	arm_USAT16
-	arm_USAT16_ZZ
-	arm_USAX_EQ
-	arm_USAX_NE
-	arm_USAX_CS
-	arm_USAX_CC
-	arm_USAX_MI
-	arm_USAX_PL
-	arm_USAX_VS
-	arm_USAX_VC
-	arm_USAX_HI
-	arm_USAX_LS
-	arm_USAX_GE
-	arm_USAX_LT
-	arm_USAX_GT
-	arm_USAX_LE
-	arm_USAX
-	arm_USAX_ZZ
-	arm_USUB16_EQ
-	arm_USUB16_NE
-	arm_USUB16_CS
-	arm_USUB16_CC
-	arm_USUB16_MI
-	arm_USUB16_PL
-	arm_USUB16_VS
-	arm_USUB16_VC
-	arm_USUB16_HI
-	arm_USUB16_LS
-	arm_USUB16_GE
-	arm_USUB16_LT
-	arm_USUB16_GT
-	arm_USUB16_LE
-	arm_USUB16
-	arm_USUB16_ZZ
-	arm_USUB8_EQ
-	arm_USUB8_NE
-	arm_USUB8_CS
-	arm_USUB8_CC
-	arm_USUB8_MI
-	arm_USUB8_PL
-	arm_USUB8_VS
-	arm_USUB8_VC
-	arm_USUB8_HI
-	arm_USUB8_LS
-	arm_USUB8_GE
-	arm_USUB8_LT
-	arm_USUB8_GT
-	arm_USUB8_LE
-	arm_USUB8
-	arm_USUB8_ZZ
-	arm_UXTAB_EQ
-	arm_UXTAB_NE
-	arm_UXTAB_CS
-	arm_UXTAB_CC
-	arm_UXTAB_MI
-	arm_UXTAB_PL
-	arm_UXTAB_VS
-	arm_UXTAB_VC
-	arm_UXTAB_HI
-	arm_UXTAB_LS
-	arm_UXTAB_GE
-	arm_UXTAB_LT
-	arm_UXTAB_GT
-	arm_UXTAB_LE
-	arm_UXTAB
-	arm_UXTAB_ZZ
-	arm_UXTAB16_EQ
-	arm_UXTAB16_NE
-	arm_UXTAB16_CS
-	arm_UXTAB16_CC
-	arm_UXTAB16_MI
-	arm_UXTAB16_PL
-	arm_UXTAB16_VS
-	arm_UXTAB16_VC
-	arm_UXTAB16_HI
-	arm_UXTAB16_LS
-	arm_UXTAB16_GE
-	arm_UXTAB16_LT
-	arm_UXTAB16_GT
-	arm_UXTAB16_LE
-	arm_UXTAB16
-	arm_UXTAB16_ZZ
-	arm_UXTAH_EQ
-	arm_UXTAH_NE
-	arm_UXTAH_CS
-	arm_UXTAH_CC
-	arm_UXTAH_MI
-	arm_UXTAH_PL
-	arm_UXTAH_VS
-	arm_UXTAH_VC
-	arm_UXTAH_HI
-	arm_UXTAH_LS
-	arm_UXTAH_GE
-	arm_UXTAH_LT
-	arm_UXTAH_GT
-	arm_UXTAH_LE
-	arm_UXTAH
-	arm_UXTAH_ZZ
-	arm_UXTB_EQ
-	arm_UXTB_NE
-	arm_UXTB_CS
-	arm_UXTB_CC
-	arm_UXTB_MI
-	arm_UXTB_PL
-	arm_UXTB_VS
-	arm_UXTB_VC
-	arm_UXTB_HI
-	arm_UXTB_LS
-	arm_UXTB_GE
-	arm_UXTB_LT
-	arm_UXTB_GT
-	arm_UXTB_LE
-	arm_UXTB
-	arm_UXTB_ZZ
-	arm_UXTB16_EQ
-	arm_UXTB16_NE
-	arm_UXTB16_CS
-	arm_UXTB16_CC
-	arm_UXTB16_MI
-	arm_UXTB16_PL
-	arm_UXTB16_VS
-	arm_UXTB16_VC
-	arm_UXTB16_HI
-	arm_UXTB16_LS
-	arm_UXTB16_GE
-	arm_UXTB16_LT
-	arm_UXTB16_GT
-	arm_UXTB16_LE
-	arm_UXTB16
-	arm_UXTB16_ZZ
-	arm_UXTH_EQ
-	arm_UXTH_NE
-	arm_UXTH_CS
-	arm_UXTH_CC
-	arm_UXTH_MI
-	arm_UXTH_PL
-	arm_UXTH_VS
-	arm_UXTH_VC
-	arm_UXTH_HI
-	arm_UXTH_LS
-	arm_UXTH_GE
-	arm_UXTH_LT
-	arm_UXTH_GT
-	arm_UXTH_LE
-	arm_UXTH
-	arm_UXTH_ZZ
-	arm_VABS_EQ_F32
-	arm_VABS_NE_F32
-	arm_VABS_CS_F32
-	arm_VABS_CC_F32
-	arm_VABS_MI_F32
-	arm_VABS_PL_F32
-	arm_VABS_VS_F32
-	arm_VABS_VC_F32
-	arm_VABS_HI_F32
-	arm_VABS_LS_F32
-	arm_VABS_GE_F32
-	arm_VABS_LT_F32
-	arm_VABS_GT_F32
-	arm_VABS_LE_F32
-	arm_VABS_F32
-	arm_VABS_ZZ_F32
-	arm_VABS_EQ_F64
-	arm_VABS_NE_F64
-	arm_VABS_CS_F64
-	arm_VABS_CC_F64
-	arm_VABS_MI_F64
-	arm_VABS_PL_F64
-	arm_VABS_VS_F64
-	arm_VABS_VC_F64
-	arm_VABS_HI_F64
-	arm_VABS_LS_F64
-	arm_VABS_GE_F64
-	arm_VABS_LT_F64
-	arm_VABS_GT_F64
-	arm_VABS_LE_F64
-	arm_VABS_F64
-	arm_VABS_ZZ_F64
-	arm_VADD_EQ_F32
-	arm_VADD_NE_F32
-	arm_VADD_CS_F32
-	arm_VADD_CC_F32
-	arm_VADD_MI_F32
-	arm_VADD_PL_F32
-	arm_VADD_VS_F32
-	arm_VADD_VC_F32
-	arm_VADD_HI_F32
-	arm_VADD_LS_F32
-	arm_VADD_GE_F32
-	arm_VADD_LT_F32
-	arm_VADD_GT_F32
-	arm_VADD_LE_F32
-	arm_VADD_F32
-	arm_VADD_ZZ_F32
-	arm_VADD_EQ_F64
-	arm_VADD_NE_F64
-	arm_VADD_CS_F64
-	arm_VADD_CC_F64
-	arm_VADD_MI_F64
-	arm_VADD_PL_F64
-	arm_VADD_VS_F64
-	arm_VADD_VC_F64
-	arm_VADD_HI_F64
-	arm_VADD_LS_F64
-	arm_VADD_GE_F64
-	arm_VADD_LT_F64
-	arm_VADD_GT_F64
-	arm_VADD_LE_F64
-	arm_VADD_F64
-	arm_VADD_ZZ_F64
-	arm_VCMP_EQ_F32
-	arm_VCMP_NE_F32
-	arm_VCMP_CS_F32
-	arm_VCMP_CC_F32
-	arm_VCMP_MI_F32
-	arm_VCMP_PL_F32
-	arm_VCMP_VS_F32
-	arm_VCMP_VC_F32
-	arm_VCMP_HI_F32
-	arm_VCMP_LS_F32
-	arm_VCMP_GE_F32
-	arm_VCMP_LT_F32
-	arm_VCMP_GT_F32
-	arm_VCMP_LE_F32
-	arm_VCMP_F32
-	arm_VCMP_ZZ_F32
-	arm_VCMP_EQ_F64
-	arm_VCMP_NE_F64
-	arm_VCMP_CS_F64
-	arm_VCMP_CC_F64
-	arm_VCMP_MI_F64
-	arm_VCMP_PL_F64
-	arm_VCMP_VS_F64
-	arm_VCMP_VC_F64
-	arm_VCMP_HI_F64
-	arm_VCMP_LS_F64
-	arm_VCMP_GE_F64
-	arm_VCMP_LT_F64
-	arm_VCMP_GT_F64
-	arm_VCMP_LE_F64
-	arm_VCMP_F64
-	arm_VCMP_ZZ_F64
-	arm_VCMP_E_EQ_F32
-	arm_VCMP_E_NE_F32
-	arm_VCMP_E_CS_F32
-	arm_VCMP_E_CC_F32
-	arm_VCMP_E_MI_F32
-	arm_VCMP_E_PL_F32
-	arm_VCMP_E_VS_F32
-	arm_VCMP_E_VC_F32
-	arm_VCMP_E_HI_F32
-	arm_VCMP_E_LS_F32
-	arm_VCMP_E_GE_F32
-	arm_VCMP_E_LT_F32
-	arm_VCMP_E_GT_F32
-	arm_VCMP_E_LE_F32
-	arm_VCMP_E_F32
-	arm_VCMP_E_ZZ_F32
-	arm_VCMP_E_EQ_F64
-	arm_VCMP_E_NE_F64
-	arm_VCMP_E_CS_F64
-	arm_VCMP_E_CC_F64
-	arm_VCMP_E_MI_F64
-	arm_VCMP_E_PL_F64
-	arm_VCMP_E_VS_F64
-	arm_VCMP_E_VC_F64
-	arm_VCMP_E_HI_F64
-	arm_VCMP_E_LS_F64
-	arm_VCMP_E_GE_F64
-	arm_VCMP_E_LT_F64
-	arm_VCMP_E_GT_F64
-	arm_VCMP_E_LE_F64
-	arm_VCMP_E_F64
-	arm_VCMP_E_ZZ_F64
-	arm_VCVT_EQ_F32_FXS16
-	arm_VCVT_NE_F32_FXS16
-	arm_VCVT_CS_F32_FXS16
-	arm_VCVT_CC_F32_FXS16
-	arm_VCVT_MI_F32_FXS16
-	arm_VCVT_PL_F32_FXS16
-	arm_VCVT_VS_F32_FXS16
-	arm_VCVT_VC_F32_FXS16
-	arm_VCVT_HI_F32_FXS16
-	arm_VCVT_LS_F32_FXS16
-	arm_VCVT_GE_F32_FXS16
-	arm_VCVT_LT_F32_FXS16
-	arm_VCVT_GT_F32_FXS16
-	arm_VCVT_LE_F32_FXS16
-	arm_VCVT_F32_FXS16
-	arm_VCVT_ZZ_F32_FXS16
-	arm_VCVT_EQ_F32_FXS32
-	arm_VCVT_NE_F32_FXS32
-	arm_VCVT_CS_F32_FXS32
-	arm_VCVT_CC_F32_FXS32
-	arm_VCVT_MI_F32_FXS32
-	arm_VCVT_PL_F32_FXS32
-	arm_VCVT_VS_F32_FXS32
-	arm_VCVT_VC_F32_FXS32
-	arm_VCVT_HI_F32_FXS32
-	arm_VCVT_LS_F32_FXS32
-	arm_VCVT_GE_F32_FXS32
-	arm_VCVT_LT_F32_FXS32
-	arm_VCVT_GT_F32_FXS32
-	arm_VCVT_LE_F32_FXS32
-	arm_VCVT_F32_FXS32
-	arm_VCVT_ZZ_F32_FXS32
-	arm_VCVT_EQ_F32_FXU16
-	arm_VCVT_NE_F32_FXU16
-	arm_VCVT_CS_F32_FXU16
-	arm_VCVT_CC_F32_FXU16
-	arm_VCVT_MI_F32_FXU16
-	arm_VCVT_PL_F32_FXU16
-	arm_VCVT_VS_F32_FXU16
-	arm_VCVT_VC_F32_FXU16
-	arm_VCVT_HI_F32_FXU16
-	arm_VCVT_LS_F32_FXU16
-	arm_VCVT_GE_F32_FXU16
-	arm_VCVT_LT_F32_FXU16
-	arm_VCVT_GT_F32_FXU16
-	arm_VCVT_LE_F32_FXU16
-	arm_VCVT_F32_FXU16
-	arm_VCVT_ZZ_F32_FXU16
-	arm_VCVT_EQ_F32_FXU32
-	arm_VCVT_NE_F32_FXU32
-	arm_VCVT_CS_F32_FXU32
-	arm_VCVT_CC_F32_FXU32
-	arm_VCVT_MI_F32_FXU32
-	arm_VCVT_PL_F32_FXU32
-	arm_VCVT_VS_F32_FXU32
-	arm_VCVT_VC_F32_FXU32
-	arm_VCVT_HI_F32_FXU32
-	arm_VCVT_LS_F32_FXU32
-	arm_VCVT_GE_F32_FXU32
-	arm_VCVT_LT_F32_FXU32
-	arm_VCVT_GT_F32_FXU32
-	arm_VCVT_LE_F32_FXU32
-	arm_VCVT_F32_FXU32
-	arm_VCVT_ZZ_F32_FXU32
-	arm_VCVT_EQ_F64_FXS16
-	arm_VCVT_NE_F64_FXS16
-	arm_VCVT_CS_F64_FXS16
-	arm_VCVT_CC_F64_FXS16
-	arm_VCVT_MI_F64_FXS16
-	arm_VCVT_PL_F64_FXS16
-	arm_VCVT_VS_F64_FXS16
-	arm_VCVT_VC_F64_FXS16
-	arm_VCVT_HI_F64_FXS16
-	arm_VCVT_LS_F64_FXS16
-	arm_VCVT_GE_F64_FXS16
-	arm_VCVT_LT_F64_FXS16
-	arm_VCVT_GT_F64_FXS16
-	arm_VCVT_LE_F64_FXS16
-	arm_VCVT_F64_FXS16
-	arm_VCVT_ZZ_F64_FXS16
-	arm_VCVT_EQ_F64_FXS32
-	arm_VCVT_NE_F64_FXS32
-	arm_VCVT_CS_F64_FXS32
-	arm_VCVT_CC_F64_FXS32
-	arm_VCVT_MI_F64_FXS32
-	arm_VCVT_PL_F64_FXS32
-	arm_VCVT_VS_F64_FXS32
-	arm_VCVT_VC_F64_FXS32
-	arm_VCVT_HI_F64_FXS32
-	arm_VCVT_LS_F64_FXS32
-	arm_VCVT_GE_F64_FXS32
-	arm_VCVT_LT_F64_FXS32
-	arm_VCVT_GT_F64_FXS32
-	arm_VCVT_LE_F64_FXS32
-	arm_VCVT_F64_FXS32
-	arm_VCVT_ZZ_F64_FXS32
-	arm_VCVT_EQ_F64_FXU16
-	arm_VCVT_NE_F64_FXU16
-	arm_VCVT_CS_F64_FXU16
-	arm_VCVT_CC_F64_FXU16
-	arm_VCVT_MI_F64_FXU16
-	arm_VCVT_PL_F64_FXU16
-	arm_VCVT_VS_F64_FXU16
-	arm_VCVT_VC_F64_FXU16
-	arm_VCVT_HI_F64_FXU16
-	arm_VCVT_LS_F64_FXU16
-	arm_VCVT_GE_F64_FXU16
-	arm_VCVT_LT_F64_FXU16
-	arm_VCVT_GT_F64_FXU16
-	arm_VCVT_LE_F64_FXU16
-	arm_VCVT_F64_FXU16
-	arm_VCVT_ZZ_F64_FXU16
-	arm_VCVT_EQ_F64_FXU32
-	arm_VCVT_NE_F64_FXU32
-	arm_VCVT_CS_F64_FXU32
-	arm_VCVT_CC_F64_FXU32
-	arm_VCVT_MI_F64_FXU32
-	arm_VCVT_PL_F64_FXU32
-	arm_VCVT_VS_F64_FXU32
-	arm_VCVT_VC_F64_FXU32
-	arm_VCVT_HI_F64_FXU32
-	arm_VCVT_LS_F64_FXU32
-	arm_VCVT_GE_F64_FXU32
-	arm_VCVT_LT_F64_FXU32
-	arm_VCVT_GT_F64_FXU32
-	arm_VCVT_LE_F64_FXU32
-	arm_VCVT_F64_FXU32
-	arm_VCVT_ZZ_F64_FXU32
-	arm_VCVT_EQ_F32_U32
-	arm_VCVT_NE_F32_U32
-	arm_VCVT_CS_F32_U32
-	arm_VCVT_CC_F32_U32
-	arm_VCVT_MI_F32_U32
-	arm_VCVT_PL_F32_U32
-	arm_VCVT_VS_F32_U32
-	arm_VCVT_VC_F32_U32
-	arm_VCVT_HI_F32_U32
-	arm_VCVT_LS_F32_U32
-	arm_VCVT_GE_F32_U32
-	arm_VCVT_LT_F32_U32
-	arm_VCVT_GT_F32_U32
-	arm_VCVT_LE_F32_U32
-	arm_VCVT_F32_U32
-	arm_VCVT_ZZ_F32_U32
-	arm_VCVT_EQ_F32_S32
-	arm_VCVT_NE_F32_S32
-	arm_VCVT_CS_F32_S32
-	arm_VCVT_CC_F32_S32
-	arm_VCVT_MI_F32_S32
-	arm_VCVT_PL_F32_S32
-	arm_VCVT_VS_F32_S32
-	arm_VCVT_VC_F32_S32
-	arm_VCVT_HI_F32_S32
-	arm_VCVT_LS_F32_S32
-	arm_VCVT_GE_F32_S32
-	arm_VCVT_LT_F32_S32
-	arm_VCVT_GT_F32_S32
-	arm_VCVT_LE_F32_S32
-	arm_VCVT_F32_S32
-	arm_VCVT_ZZ_F32_S32
-	arm_VCVT_EQ_F64_U32
-	arm_VCVT_NE_F64_U32
-	arm_VCVT_CS_F64_U32
-	arm_VCVT_CC_F64_U32
-	arm_VCVT_MI_F64_U32
-	arm_VCVT_PL_F64_U32
-	arm_VCVT_VS_F64_U32
-	arm_VCVT_VC_F64_U32
-	arm_VCVT_HI_F64_U32
-	arm_VCVT_LS_F64_U32
-	arm_VCVT_GE_F64_U32
-	arm_VCVT_LT_F64_U32
-	arm_VCVT_GT_F64_U32
-	arm_VCVT_LE_F64_U32
-	arm_VCVT_F64_U32
-	arm_VCVT_ZZ_F64_U32
-	arm_VCVT_EQ_F64_S32
-	arm_VCVT_NE_F64_S32
-	arm_VCVT_CS_F64_S32
-	arm_VCVT_CC_F64_S32
-	arm_VCVT_MI_F64_S32
-	arm_VCVT_PL_F64_S32
-	arm_VCVT_VS_F64_S32
-	arm_VCVT_VC_F64_S32
-	arm_VCVT_HI_F64_S32
-	arm_VCVT_LS_F64_S32
-	arm_VCVT_GE_F64_S32
-	arm_VCVT_LT_F64_S32
-	arm_VCVT_GT_F64_S32
-	arm_VCVT_LE_F64_S32
-	arm_VCVT_F64_S32
-	arm_VCVT_ZZ_F64_S32
-	arm_VCVT_EQ_F64_F32
-	arm_VCVT_NE_F64_F32
-	arm_VCVT_CS_F64_F32
-	arm_VCVT_CC_F64_F32
-	arm_VCVT_MI_F64_F32
-	arm_VCVT_PL_F64_F32
-	arm_VCVT_VS_F64_F32
-	arm_VCVT_VC_F64_F32
-	arm_VCVT_HI_F64_F32
-	arm_VCVT_LS_F64_F32
-	arm_VCVT_GE_F64_F32
-	arm_VCVT_LT_F64_F32
-	arm_VCVT_GT_F64_F32
-	arm_VCVT_LE_F64_F32
-	arm_VCVT_F64_F32
-	arm_VCVT_ZZ_F64_F32
-	arm_VCVT_EQ_F32_F64
-	arm_VCVT_NE_F32_F64
-	arm_VCVT_CS_F32_F64
-	arm_VCVT_CC_F32_F64
-	arm_VCVT_MI_F32_F64
-	arm_VCVT_PL_F32_F64
-	arm_VCVT_VS_F32_F64
-	arm_VCVT_VC_F32_F64
-	arm_VCVT_HI_F32_F64
-	arm_VCVT_LS_F32_F64
-	arm_VCVT_GE_F32_F64
-	arm_VCVT_LT_F32_F64
-	arm_VCVT_GT_F32_F64
-	arm_VCVT_LE_F32_F64
-	arm_VCVT_F32_F64
-	arm_VCVT_ZZ_F32_F64
-	arm_VCVT_EQ_FXS16_F32
-	arm_VCVT_NE_FXS16_F32
-	arm_VCVT_CS_FXS16_F32
-	arm_VCVT_CC_FXS16_F32
-	arm_VCVT_MI_FXS16_F32
-	arm_VCVT_PL_FXS16_F32
-	arm_VCVT_VS_FXS16_F32
-	arm_VCVT_VC_FXS16_F32
-	arm_VCVT_HI_FXS16_F32
-	arm_VCVT_LS_FXS16_F32
-	arm_VCVT_GE_FXS16_F32
-	arm_VCVT_LT_FXS16_F32
-	arm_VCVT_GT_FXS16_F32
-	arm_VCVT_LE_FXS16_F32
-	arm_VCVT_FXS16_F32
-	arm_VCVT_ZZ_FXS16_F32
-	arm_VCVT_EQ_FXS16_F64
-	arm_VCVT_NE_FXS16_F64
-	arm_VCVT_CS_FXS16_F64
-	arm_VCVT_CC_FXS16_F64
-	arm_VCVT_MI_FXS16_F64
-	arm_VCVT_PL_FXS16_F64
-	arm_VCVT_VS_FXS16_F64
-	arm_VCVT_VC_FXS16_F64
-	arm_VCVT_HI_FXS16_F64
-	arm_VCVT_LS_FXS16_F64
-	arm_VCVT_GE_FXS16_F64
-	arm_VCVT_LT_FXS16_F64
-	arm_VCVT_GT_FXS16_F64
-	arm_VCVT_LE_FXS16_F64
-	arm_VCVT_FXS16_F64
-	arm_VCVT_ZZ_FXS16_F64
-	arm_VCVT_EQ_FXS32_F32
-	arm_VCVT_NE_FXS32_F32
-	arm_VCVT_CS_FXS32_F32
-	arm_VCVT_CC_FXS32_F32
-	arm_VCVT_MI_FXS32_F32
-	arm_VCVT_PL_FXS32_F32
-	arm_VCVT_VS_FXS32_F32
-	arm_VCVT_VC_FXS32_F32
-	arm_VCVT_HI_FXS32_F32
-	arm_VCVT_LS_FXS32_F32
-	arm_VCVT_GE_FXS32_F32
-	arm_VCVT_LT_FXS32_F32
-	arm_VCVT_GT_FXS32_F32
-	arm_VCVT_LE_FXS32_F32
-	arm_VCVT_FXS32_F32
-	arm_VCVT_ZZ_FXS32_F32
-	arm_VCVT_EQ_FXS32_F64
-	arm_VCVT_NE_FXS32_F64
-	arm_VCVT_CS_FXS32_F64
-	arm_VCVT_CC_FXS32_F64
-	arm_VCVT_MI_FXS32_F64
-	arm_VCVT_PL_FXS32_F64
-	arm_VCVT_VS_FXS32_F64
-	arm_VCVT_VC_FXS32_F64
-	arm_VCVT_HI_FXS32_F64
-	arm_VCVT_LS_FXS32_F64
-	arm_VCVT_GE_FXS32_F64
-	arm_VCVT_LT_FXS32_F64
-	arm_VCVT_GT_FXS32_F64
-	arm_VCVT_LE_FXS32_F64
-	arm_VCVT_FXS32_F64
-	arm_VCVT_ZZ_FXS32_F64
-	arm_VCVT_EQ_FXU16_F32
-	arm_VCVT_NE_FXU16_F32
-	arm_VCVT_CS_FXU16_F32
-	arm_VCVT_CC_FXU16_F32
-	arm_VCVT_MI_FXU16_F32
-	arm_VCVT_PL_FXU16_F32
-	arm_VCVT_VS_FXU16_F32
-	arm_VCVT_VC_FXU16_F32
-	arm_VCVT_HI_FXU16_F32
-	arm_VCVT_LS_FXU16_F32
-	arm_VCVT_GE_FXU16_F32
-	arm_VCVT_LT_FXU16_F32
-	arm_VCVT_GT_FXU16_F32
-	arm_VCVT_LE_FXU16_F32
-	arm_VCVT_FXU16_F32
-	arm_VCVT_ZZ_FXU16_F32
-	arm_VCVT_EQ_FXU16_F64
-	arm_VCVT_NE_FXU16_F64
-	arm_VCVT_CS_FXU16_F64
-	arm_VCVT_CC_FXU16_F64
-	arm_VCVT_MI_FXU16_F64
-	arm_VCVT_PL_FXU16_F64
-	arm_VCVT_VS_FXU16_F64
-	arm_VCVT_VC_FXU16_F64
-	arm_VCVT_HI_FXU16_F64
-	arm_VCVT_LS_FXU16_F64
-	arm_VCVT_GE_FXU16_F64
-	arm_VCVT_LT_FXU16_F64
-	arm_VCVT_GT_FXU16_F64
-	arm_VCVT_LE_FXU16_F64
-	arm_VCVT_FXU16_F64
-	arm_VCVT_ZZ_FXU16_F64
-	arm_VCVT_EQ_FXU32_F32
-	arm_VCVT_NE_FXU32_F32
-	arm_VCVT_CS_FXU32_F32
-	arm_VCVT_CC_FXU32_F32
-	arm_VCVT_MI_FXU32_F32
-	arm_VCVT_PL_FXU32_F32
-	arm_VCVT_VS_FXU32_F32
-	arm_VCVT_VC_FXU32_F32
-	arm_VCVT_HI_FXU32_F32
-	arm_VCVT_LS_FXU32_F32
-	arm_VCVT_GE_FXU32_F32
-	arm_VCVT_LT_FXU32_F32
-	arm_VCVT_GT_FXU32_F32
-	arm_VCVT_LE_FXU32_F32
-	arm_VCVT_FXU32_F32
-	arm_VCVT_ZZ_FXU32_F32
-	arm_VCVT_EQ_FXU32_F64
-	arm_VCVT_NE_FXU32_F64
-	arm_VCVT_CS_FXU32_F64
-	arm_VCVT_CC_FXU32_F64
-	arm_VCVT_MI_FXU32_F64
-	arm_VCVT_PL_FXU32_F64
-	arm_VCVT_VS_FXU32_F64
-	arm_VCVT_VC_FXU32_F64
-	arm_VCVT_HI_FXU32_F64
-	arm_VCVT_LS_FXU32_F64
-	arm_VCVT_GE_FXU32_F64
-	arm_VCVT_LT_FXU32_F64
-	arm_VCVT_GT_FXU32_F64
-	arm_VCVT_LE_FXU32_F64
-	arm_VCVT_FXU32_F64
-	arm_VCVT_ZZ_FXU32_F64
-	arm_VCVTB_EQ_F32_F16
-	arm_VCVTB_NE_F32_F16
-	arm_VCVTB_CS_F32_F16
-	arm_VCVTB_CC_F32_F16
-	arm_VCVTB_MI_F32_F16
-	arm_VCVTB_PL_F32_F16
-	arm_VCVTB_VS_F32_F16
-	arm_VCVTB_VC_F32_F16
-	arm_VCVTB_HI_F32_F16
-	arm_VCVTB_LS_F32_F16
-	arm_VCVTB_GE_F32_F16
-	arm_VCVTB_LT_F32_F16
-	arm_VCVTB_GT_F32_F16
-	arm_VCVTB_LE_F32_F16
-	arm_VCVTB_F32_F16
-	arm_VCVTB_ZZ_F32_F16
-	arm_VCVTB_EQ_F16_F32
-	arm_VCVTB_NE_F16_F32
-	arm_VCVTB_CS_F16_F32
-	arm_VCVTB_CC_F16_F32
-	arm_VCVTB_MI_F16_F32
-	arm_VCVTB_PL_F16_F32
-	arm_VCVTB_VS_F16_F32
-	arm_VCVTB_VC_F16_F32
-	arm_VCVTB_HI_F16_F32
-	arm_VCVTB_LS_F16_F32
-	arm_VCVTB_GE_F16_F32
-	arm_VCVTB_LT_F16_F32
-	arm_VCVTB_GT_F16_F32
-	arm_VCVTB_LE_F16_F32
-	arm_VCVTB_F16_F32
-	arm_VCVTB_ZZ_F16_F32
-	arm_VCVTT_EQ_F32_F16
-	arm_VCVTT_NE_F32_F16
-	arm_VCVTT_CS_F32_F16
-	arm_VCVTT_CC_F32_F16
-	arm_VCVTT_MI_F32_F16
-	arm_VCVTT_PL_F32_F16
-	arm_VCVTT_VS_F32_F16
-	arm_VCVTT_VC_F32_F16
-	arm_VCVTT_HI_F32_F16
-	arm_VCVTT_LS_F32_F16
-	arm_VCVTT_GE_F32_F16
-	arm_VCVTT_LT_F32_F16
-	arm_VCVTT_GT_F32_F16
-	arm_VCVTT_LE_F32_F16
-	arm_VCVTT_F32_F16
-	arm_VCVTT_ZZ_F32_F16
-	arm_VCVTT_EQ_F16_F32
-	arm_VCVTT_NE_F16_F32
-	arm_VCVTT_CS_F16_F32
-	arm_VCVTT_CC_F16_F32
-	arm_VCVTT_MI_F16_F32
-	arm_VCVTT_PL_F16_F32
-	arm_VCVTT_VS_F16_F32
-	arm_VCVTT_VC_F16_F32
-	arm_VCVTT_HI_F16_F32
-	arm_VCVTT_LS_F16_F32
-	arm_VCVTT_GE_F16_F32
-	arm_VCVTT_LT_F16_F32
-	arm_VCVTT_GT_F16_F32
-	arm_VCVTT_LE_F16_F32
-	arm_VCVTT_F16_F32
-	arm_VCVTT_ZZ_F16_F32
-	arm_VCVTR_EQ_U32_F32
-	arm_VCVTR_NE_U32_F32
-	arm_VCVTR_CS_U32_F32
-	arm_VCVTR_CC_U32_F32
-	arm_VCVTR_MI_U32_F32
-	arm_VCVTR_PL_U32_F32
-	arm_VCVTR_VS_U32_F32
-	arm_VCVTR_VC_U32_F32
-	arm_VCVTR_HI_U32_F32
-	arm_VCVTR_LS_U32_F32
-	arm_VCVTR_GE_U32_F32
-	arm_VCVTR_LT_U32_F32
-	arm_VCVTR_GT_U32_F32
-	arm_VCVTR_LE_U32_F32
-	arm_VCVTR_U32_F32
-	arm_VCVTR_ZZ_U32_F32
-	arm_VCVTR_EQ_U32_F64
-	arm_VCVTR_NE_U32_F64
-	arm_VCVTR_CS_U32_F64
-	arm_VCVTR_CC_U32_F64
-	arm_VCVTR_MI_U32_F64
-	arm_VCVTR_PL_U32_F64
-	arm_VCVTR_VS_U32_F64
-	arm_VCVTR_VC_U32_F64
-	arm_VCVTR_HI_U32_F64
-	arm_VCVTR_LS_U32_F64
-	arm_VCVTR_GE_U32_F64
-	arm_VCVTR_LT_U32_F64
-	arm_VCVTR_GT_U32_F64
-	arm_VCVTR_LE_U32_F64
-	arm_VCVTR_U32_F64
-	arm_VCVTR_ZZ_U32_F64
-	arm_VCVTR_EQ_S32_F32
-	arm_VCVTR_NE_S32_F32
-	arm_VCVTR_CS_S32_F32
-	arm_VCVTR_CC_S32_F32
-	arm_VCVTR_MI_S32_F32
-	arm_VCVTR_PL_S32_F32
-	arm_VCVTR_VS_S32_F32
-	arm_VCVTR_VC_S32_F32
-	arm_VCVTR_HI_S32_F32
-	arm_VCVTR_LS_S32_F32
-	arm_VCVTR_GE_S32_F32
-	arm_VCVTR_LT_S32_F32
-	arm_VCVTR_GT_S32_F32
-	arm_VCVTR_LE_S32_F32
-	arm_VCVTR_S32_F32
-	arm_VCVTR_ZZ_S32_F32
-	arm_VCVTR_EQ_S32_F64
-	arm_VCVTR_NE_S32_F64
-	arm_VCVTR_CS_S32_F64
-	arm_VCVTR_CC_S32_F64
-	arm_VCVTR_MI_S32_F64
-	arm_VCVTR_PL_S32_F64
-	arm_VCVTR_VS_S32_F64
-	arm_VCVTR_VC_S32_F64
-	arm_VCVTR_HI_S32_F64
-	arm_VCVTR_LS_S32_F64
-	arm_VCVTR_GE_S32_F64
-	arm_VCVTR_LT_S32_F64
-	arm_VCVTR_GT_S32_F64
-	arm_VCVTR_LE_S32_F64
-	arm_VCVTR_S32_F64
-	arm_VCVTR_ZZ_S32_F64
-	arm_VCVT_EQ_U32_F32
-	arm_VCVT_NE_U32_F32
-	arm_VCVT_CS_U32_F32
-	arm_VCVT_CC_U32_F32
-	arm_VCVT_MI_U32_F32
-	arm_VCVT_PL_U32_F32
-	arm_VCVT_VS_U32_F32
-	arm_VCVT_VC_U32_F32
-	arm_VCVT_HI_U32_F32
-	arm_VCVT_LS_U32_F32
-	arm_VCVT_GE_U32_F32
-	arm_VCVT_LT_U32_F32
-	arm_VCVT_GT_U32_F32
-	arm_VCVT_LE_U32_F32
-	arm_VCVT_U32_F32
-	arm_VCVT_ZZ_U32_F32
-	arm_VCVT_EQ_U32_F64
-	arm_VCVT_NE_U32_F64
-	arm_VCVT_CS_U32_F64
-	arm_VCVT_CC_U32_F64
-	arm_VCVT_MI_U32_F64
-	arm_VCVT_PL_U32_F64
-	arm_VCVT_VS_U32_F64
-	arm_VCVT_VC_U32_F64
-	arm_VCVT_HI_U32_F64
-	arm_VCVT_LS_U32_F64
-	arm_VCVT_GE_U32_F64
-	arm_VCVT_LT_U32_F64
-	arm_VCVT_GT_U32_F64
-	arm_VCVT_LE_U32_F64
-	arm_VCVT_U32_F64
-	arm_VCVT_ZZ_U32_F64
-	arm_VCVT_EQ_S32_F32
-	arm_VCVT_NE_S32_F32
-	arm_VCVT_CS_S32_F32
-	arm_VCVT_CC_S32_F32
-	arm_VCVT_MI_S32_F32
-	arm_VCVT_PL_S32_F32
-	arm_VCVT_VS_S32_F32
-	arm_VCVT_VC_S32_F32
-	arm_VCVT_HI_S32_F32
-	arm_VCVT_LS_S32_F32
-	arm_VCVT_GE_S32_F32
-	arm_VCVT_LT_S32_F32
-	arm_VCVT_GT_S32_F32
-	arm_VCVT_LE_S32_F32
-	arm_VCVT_S32_F32
-	arm_VCVT_ZZ_S32_F32
-	arm_VCVT_EQ_S32_F64
-	arm_VCVT_NE_S32_F64
-	arm_VCVT_CS_S32_F64
-	arm_VCVT_CC_S32_F64
-	arm_VCVT_MI_S32_F64
-	arm_VCVT_PL_S32_F64
-	arm_VCVT_VS_S32_F64
-	arm_VCVT_VC_S32_F64
-	arm_VCVT_HI_S32_F64
-	arm_VCVT_LS_S32_F64
-	arm_VCVT_GE_S32_F64
-	arm_VCVT_LT_S32_F64
-	arm_VCVT_GT_S32_F64
-	arm_VCVT_LE_S32_F64
-	arm_VCVT_S32_F64
-	arm_VCVT_ZZ_S32_F64
-	arm_VDIV_EQ_F32
-	arm_VDIV_NE_F32
-	arm_VDIV_CS_F32
-	arm_VDIV_CC_F32
-	arm_VDIV_MI_F32
-	arm_VDIV_PL_F32
-	arm_VDIV_VS_F32
-	arm_VDIV_VC_F32
-	arm_VDIV_HI_F32
-	arm_VDIV_LS_F32
-	arm_VDIV_GE_F32
-	arm_VDIV_LT_F32
-	arm_VDIV_GT_F32
-	arm_VDIV_LE_F32
-	arm_VDIV_F32
-	arm_VDIV_ZZ_F32
-	arm_VDIV_EQ_F64
-	arm_VDIV_NE_F64
-	arm_VDIV_CS_F64
-	arm_VDIV_CC_F64
-	arm_VDIV_MI_F64
-	arm_VDIV_PL_F64
-	arm_VDIV_VS_F64
-	arm_VDIV_VC_F64
-	arm_VDIV_HI_F64
-	arm_VDIV_LS_F64
-	arm_VDIV_GE_F64
-	arm_VDIV_LT_F64
-	arm_VDIV_GT_F64
-	arm_VDIV_LE_F64
-	arm_VDIV_F64
-	arm_VDIV_ZZ_F64
-	arm_VLDR_EQ
-	arm_VLDR_NE
-	arm_VLDR_CS
-	arm_VLDR_CC
-	arm_VLDR_MI
-	arm_VLDR_PL
-	arm_VLDR_VS
-	arm_VLDR_VC
-	arm_VLDR_HI
-	arm_VLDR_LS
-	arm_VLDR_GE
-	arm_VLDR_LT
-	arm_VLDR_GT
-	arm_VLDR_LE
-	arm_VLDR
-	arm_VLDR_ZZ
-	arm_VMLA_EQ_F32
-	arm_VMLA_NE_F32
-	arm_VMLA_CS_F32
-	arm_VMLA_CC_F32
-	arm_VMLA_MI_F32
-	arm_VMLA_PL_F32
-	arm_VMLA_VS_F32
-	arm_VMLA_VC_F32
-	arm_VMLA_HI_F32
-	arm_VMLA_LS_F32
-	arm_VMLA_GE_F32
-	arm_VMLA_LT_F32
-	arm_VMLA_GT_F32
-	arm_VMLA_LE_F32
-	arm_VMLA_F32
-	arm_VMLA_ZZ_F32
-	arm_VMLA_EQ_F64
-	arm_VMLA_NE_F64
-	arm_VMLA_CS_F64
-	arm_VMLA_CC_F64
-	arm_VMLA_MI_F64
-	arm_VMLA_PL_F64
-	arm_VMLA_VS_F64
-	arm_VMLA_VC_F64
-	arm_VMLA_HI_F64
-	arm_VMLA_LS_F64
-	arm_VMLA_GE_F64
-	arm_VMLA_LT_F64
-	arm_VMLA_GT_F64
-	arm_VMLA_LE_F64
-	arm_VMLA_F64
-	arm_VMLA_ZZ_F64
-	arm_VMLS_EQ_F32
-	arm_VMLS_NE_F32
-	arm_VMLS_CS_F32
-	arm_VMLS_CC_F32
-	arm_VMLS_MI_F32
-	arm_VMLS_PL_F32
-	arm_VMLS_VS_F32
-	arm_VMLS_VC_F32
-	arm_VMLS_HI_F32
-	arm_VMLS_LS_F32
-	arm_VMLS_GE_F32
-	arm_VMLS_LT_F32
-	arm_VMLS_GT_F32
-	arm_VMLS_LE_F32
-	arm_VMLS_F32
-	arm_VMLS_ZZ_F32
-	arm_VMLS_EQ_F64
-	arm_VMLS_NE_F64
-	arm_VMLS_CS_F64
-	arm_VMLS_CC_F64
-	arm_VMLS_MI_F64
-	arm_VMLS_PL_F64
-	arm_VMLS_VS_F64
-	arm_VMLS_VC_F64
-	arm_VMLS_HI_F64
-	arm_VMLS_LS_F64
-	arm_VMLS_GE_F64
-	arm_VMLS_LT_F64
-	arm_VMLS_GT_F64
-	arm_VMLS_LE_F64
-	arm_VMLS_F64
-	arm_VMLS_ZZ_F64
-	arm_VMOV_EQ
-	arm_VMOV_NE
-	arm_VMOV_CS
-	arm_VMOV_CC
-	arm_VMOV_MI
-	arm_VMOV_PL
-	arm_VMOV_VS
-	arm_VMOV_VC
-	arm_VMOV_HI
-	arm_VMOV_LS
-	arm_VMOV_GE
-	arm_VMOV_LT
-	arm_VMOV_GT
-	arm_VMOV_LE
-	arm_VMOV
-	arm_VMOV_ZZ
-	arm_VMOV_EQ_32
-	arm_VMOV_NE_32
-	arm_VMOV_CS_32
-	arm_VMOV_CC_32
-	arm_VMOV_MI_32
-	arm_VMOV_PL_32
-	arm_VMOV_VS_32
-	arm_VMOV_VC_32
-	arm_VMOV_HI_32
-	arm_VMOV_LS_32
-	arm_VMOV_GE_32
-	arm_VMOV_LT_32
-	arm_VMOV_GT_32
-	arm_VMOV_LE_32
-	arm_VMOV_32
-	arm_VMOV_ZZ_32
-	arm_VMOV_EQ_F32
-	arm_VMOV_NE_F32
-	arm_VMOV_CS_F32
-	arm_VMOV_CC_F32
-	arm_VMOV_MI_F32
-	arm_VMOV_PL_F32
-	arm_VMOV_VS_F32
-	arm_VMOV_VC_F32
-	arm_VMOV_HI_F32
-	arm_VMOV_LS_F32
-	arm_VMOV_GE_F32
-	arm_VMOV_LT_F32
-	arm_VMOV_GT_F32
-	arm_VMOV_LE_F32
-	arm_VMOV_F32
-	arm_VMOV_ZZ_F32
-	arm_VMOV_EQ_F64
-	arm_VMOV_NE_F64
-	arm_VMOV_CS_F64
-	arm_VMOV_CC_F64
-	arm_VMOV_MI_F64
-	arm_VMOV_PL_F64
-	arm_VMOV_VS_F64
-	arm_VMOV_VC_F64
-	arm_VMOV_HI_F64
-	arm_VMOV_LS_F64
-	arm_VMOV_GE_F64
-	arm_VMOV_LT_F64
-	arm_VMOV_GT_F64
-	arm_VMOV_LE_F64
-	arm_VMOV_F64
-	arm_VMOV_ZZ_F64
-	arm_VMRS_EQ
-	arm_VMRS_NE
-	arm_VMRS_CS
-	arm_VMRS_CC
-	arm_VMRS_MI
-	arm_VMRS_PL
-	arm_VMRS_VS
-	arm_VMRS_VC
-	arm_VMRS_HI
-	arm_VMRS_LS
-	arm_VMRS_GE
-	arm_VMRS_LT
-	arm_VMRS_GT
-	arm_VMRS_LE
-	arm_VMRS
-	arm_VMRS_ZZ
-	arm_VMSR_EQ
-	arm_VMSR_NE
-	arm_VMSR_CS
-	arm_VMSR_CC
-	arm_VMSR_MI
-	arm_VMSR_PL
-	arm_VMSR_VS
-	arm_VMSR_VC
-	arm_VMSR_HI
-	arm_VMSR_LS
-	arm_VMSR_GE
-	arm_VMSR_LT
-	arm_VMSR_GT
-	arm_VMSR_LE
-	arm_VMSR
-	arm_VMSR_ZZ
-	arm_VMUL_EQ_F32
-	arm_VMUL_NE_F32
-	arm_VMUL_CS_F32
-	arm_VMUL_CC_F32
-	arm_VMUL_MI_F32
-	arm_VMUL_PL_F32
-	arm_VMUL_VS_F32
-	arm_VMUL_VC_F32
-	arm_VMUL_HI_F32
-	arm_VMUL_LS_F32
-	arm_VMUL_GE_F32
-	arm_VMUL_LT_F32
-	arm_VMUL_GT_F32
-	arm_VMUL_LE_F32
-	arm_VMUL_F32
-	arm_VMUL_ZZ_F32
-	arm_VMUL_EQ_F64
-	arm_VMUL_NE_F64
-	arm_VMUL_CS_F64
-	arm_VMUL_CC_F64
-	arm_VMUL_MI_F64
-	arm_VMUL_PL_F64
-	arm_VMUL_VS_F64
-	arm_VMUL_VC_F64
-	arm_VMUL_HI_F64
-	arm_VMUL_LS_F64
-	arm_VMUL_GE_F64
-	arm_VMUL_LT_F64
-	arm_VMUL_GT_F64
-	arm_VMUL_LE_F64
-	arm_VMUL_F64
-	arm_VMUL_ZZ_F64
-	arm_VNEG_EQ_F32
-	arm_VNEG_NE_F32
-	arm_VNEG_CS_F32
-	arm_VNEG_CC_F32
-	arm_VNEG_MI_F32
-	arm_VNEG_PL_F32
-	arm_VNEG_VS_F32
-	arm_VNEG_VC_F32
-	arm_VNEG_HI_F32
-	arm_VNEG_LS_F32
-	arm_VNEG_GE_F32
-	arm_VNEG_LT_F32
-	arm_VNEG_GT_F32
-	arm_VNEG_LE_F32
-	arm_VNEG_F32
-	arm_VNEG_ZZ_F32
-	arm_VNEG_EQ_F64
-	arm_VNEG_NE_F64
-	arm_VNEG_CS_F64
-	arm_VNEG_CC_F64
-	arm_VNEG_MI_F64
-	arm_VNEG_PL_F64
-	arm_VNEG_VS_F64
-	arm_VNEG_VC_F64
-	arm_VNEG_HI_F64
-	arm_VNEG_LS_F64
-	arm_VNEG_GE_F64
-	arm_VNEG_LT_F64
-	arm_VNEG_GT_F64
-	arm_VNEG_LE_F64
-	arm_VNEG_F64
-	arm_VNEG_ZZ_F64
-	arm_VNMLS_EQ_F32
-	arm_VNMLS_NE_F32
-	arm_VNMLS_CS_F32
-	arm_VNMLS_CC_F32
-	arm_VNMLS_MI_F32
-	arm_VNMLS_PL_F32
-	arm_VNMLS_VS_F32
-	arm_VNMLS_VC_F32
-	arm_VNMLS_HI_F32
-	arm_VNMLS_LS_F32
-	arm_VNMLS_GE_F32
-	arm_VNMLS_LT_F32
-	arm_VNMLS_GT_F32
-	arm_VNMLS_LE_F32
-	arm_VNMLS_F32
-	arm_VNMLS_ZZ_F32
-	arm_VNMLS_EQ_F64
-	arm_VNMLS_NE_F64
-	arm_VNMLS_CS_F64
-	arm_VNMLS_CC_F64
-	arm_VNMLS_MI_F64
-	arm_VNMLS_PL_F64
-	arm_VNMLS_VS_F64
-	arm_VNMLS_VC_F64
-	arm_VNMLS_HI_F64
-	arm_VNMLS_LS_F64
-	arm_VNMLS_GE_F64
-	arm_VNMLS_LT_F64
-	arm_VNMLS_GT_F64
-	arm_VNMLS_LE_F64
-	arm_VNMLS_F64
-	arm_VNMLS_ZZ_F64
-	arm_VNMLA_EQ_F32
-	arm_VNMLA_NE_F32
-	arm_VNMLA_CS_F32
-	arm_VNMLA_CC_F32
-	arm_VNMLA_MI_F32
-	arm_VNMLA_PL_F32
-	arm_VNMLA_VS_F32
-	arm_VNMLA_VC_F32
-	arm_VNMLA_HI_F32
-	arm_VNMLA_LS_F32
-	arm_VNMLA_GE_F32
-	arm_VNMLA_LT_F32
-	arm_VNMLA_GT_F32
-	arm_VNMLA_LE_F32
-	arm_VNMLA_F32
-	arm_VNMLA_ZZ_F32
-	arm_VNMLA_EQ_F64
-	arm_VNMLA_NE_F64
-	arm_VNMLA_CS_F64
-	arm_VNMLA_CC_F64
-	arm_VNMLA_MI_F64
-	arm_VNMLA_PL_F64
-	arm_VNMLA_VS_F64
-	arm_VNMLA_VC_F64
-	arm_VNMLA_HI_F64
-	arm_VNMLA_LS_F64
-	arm_VNMLA_GE_F64
-	arm_VNMLA_LT_F64
-	arm_VNMLA_GT_F64
-	arm_VNMLA_LE_F64
-	arm_VNMLA_F64
-	arm_VNMLA_ZZ_F64
-	arm_VNMUL_EQ_F32
-	arm_VNMUL_NE_F32
-	arm_VNMUL_CS_F32
-	arm_VNMUL_CC_F32
-	arm_VNMUL_MI_F32
-	arm_VNMUL_PL_F32
-	arm_VNMUL_VS_F32
-	arm_VNMUL_VC_F32
-	arm_VNMUL_HI_F32
-	arm_VNMUL_LS_F32
-	arm_VNMUL_GE_F32
-	arm_VNMUL_LT_F32
-	arm_VNMUL_GT_F32
-	arm_VNMUL_LE_F32
-	arm_VNMUL_F32
-	arm_VNMUL_ZZ_F32
-	arm_VNMUL_EQ_F64
-	arm_VNMUL_NE_F64
-	arm_VNMUL_CS_F64
-	arm_VNMUL_CC_F64
-	arm_VNMUL_MI_F64
-	arm_VNMUL_PL_F64
-	arm_VNMUL_VS_F64
-	arm_VNMUL_VC_F64
-	arm_VNMUL_HI_F64
-	arm_VNMUL_LS_F64
-	arm_VNMUL_GE_F64
-	arm_VNMUL_LT_F64
-	arm_VNMUL_GT_F64
-	arm_VNMUL_LE_F64
-	arm_VNMUL_F64
-	arm_VNMUL_ZZ_F64
-	arm_VSQRT_EQ_F32
-	arm_VSQRT_NE_F32
-	arm_VSQRT_CS_F32
-	arm_VSQRT_CC_F32
-	arm_VSQRT_MI_F32
-	arm_VSQRT_PL_F32
-	arm_VSQRT_VS_F32
-	arm_VSQRT_VC_F32
-	arm_VSQRT_HI_F32
-	arm_VSQRT_LS_F32
-	arm_VSQRT_GE_F32
-	arm_VSQRT_LT_F32
-	arm_VSQRT_GT_F32
-	arm_VSQRT_LE_F32
-	arm_VSQRT_F32
-	arm_VSQRT_ZZ_F32
-	arm_VSQRT_EQ_F64
-	arm_VSQRT_NE_F64
-	arm_VSQRT_CS_F64
-	arm_VSQRT_CC_F64
-	arm_VSQRT_MI_F64
-	arm_VSQRT_PL_F64
-	arm_VSQRT_VS_F64
-	arm_VSQRT_VC_F64
-	arm_VSQRT_HI_F64
-	arm_VSQRT_LS_F64
-	arm_VSQRT_GE_F64
-	arm_VSQRT_LT_F64
-	arm_VSQRT_GT_F64
-	arm_VSQRT_LE_F64
-	arm_VSQRT_F64
-	arm_VSQRT_ZZ_F64
-	arm_VSTR_EQ
-	arm_VSTR_NE
-	arm_VSTR_CS
-	arm_VSTR_CC
-	arm_VSTR_MI
-	arm_VSTR_PL
-	arm_VSTR_VS
-	arm_VSTR_VC
-	arm_VSTR_HI
-	arm_VSTR_LS
-	arm_VSTR_GE
-	arm_VSTR_LT
-	arm_VSTR_GT
-	arm_VSTR_LE
-	arm_VSTR
-	arm_VSTR_ZZ
-	arm_VSUB_EQ_F32
-	arm_VSUB_NE_F32
-	arm_VSUB_CS_F32
-	arm_VSUB_CC_F32
-	arm_VSUB_MI_F32
-	arm_VSUB_PL_F32
-	arm_VSUB_VS_F32
-	arm_VSUB_VC_F32
-	arm_VSUB_HI_F32
-	arm_VSUB_LS_F32
-	arm_VSUB_GE_F32
-	arm_VSUB_LT_F32
-	arm_VSUB_GT_F32
-	arm_VSUB_LE_F32
-	arm_VSUB_F32
-	arm_VSUB_ZZ_F32
-	arm_VSUB_EQ_F64
-	arm_VSUB_NE_F64
-	arm_VSUB_CS_F64
-	arm_VSUB_CC_F64
-	arm_VSUB_MI_F64
-	arm_VSUB_PL_F64
-	arm_VSUB_VS_F64
-	arm_VSUB_VC_F64
-	arm_VSUB_HI_F64
-	arm_VSUB_LS_F64
-	arm_VSUB_GE_F64
-	arm_VSUB_LT_F64
-	arm_VSUB_GT_F64
-	arm_VSUB_LE_F64
-	arm_VSUB_F64
-	arm_VSUB_ZZ_F64
-	arm_WFE_EQ
-	arm_WFE_NE
-	arm_WFE_CS
-	arm_WFE_CC
-	arm_WFE_MI
-	arm_WFE_PL
-	arm_WFE_VS
-	arm_WFE_VC
-	arm_WFE_HI
-	arm_WFE_LS
-	arm_WFE_GE
-	arm_WFE_LT
-	arm_WFE_GT
-	arm_WFE_LE
-	arm_WFE
-	arm_WFE_ZZ
-	arm_WFI_EQ
-	arm_WFI_NE
-	arm_WFI_CS
-	arm_WFI_CC
-	arm_WFI_MI
-	arm_WFI_PL
-	arm_WFI_VS
-	arm_WFI_VC
-	arm_WFI_HI
-	arm_WFI_LS
-	arm_WFI_GE
-	arm_WFI_LT
-	arm_WFI_GT
-	arm_WFI_LE
-	arm_WFI
-	arm_WFI_ZZ
-	arm_YIELD_EQ
-	arm_YIELD_NE
-	arm_YIELD_CS
-	arm_YIELD_CC
-	arm_YIELD_MI
-	arm_YIELD_PL
-	arm_YIELD_VS
-	arm_YIELD_VC
-	arm_YIELD_HI
-	arm_YIELD_LS
-	arm_YIELD_GE
-	arm_YIELD_LT
-	arm_YIELD_GT
-	arm_YIELD_LE
-	arm_YIELD
-	arm_YIELD_ZZ
-)
-
-var arm_opstr = [...]string{
-	arm_ADC_EQ:            "ADC.EQ",
-	arm_ADC_NE:            "ADC.NE",
-	arm_ADC_CS:            "ADC.CS",
-	arm_ADC_CC:            "ADC.CC",
-	arm_ADC_MI:            "ADC.MI",
-	arm_ADC_PL:            "ADC.PL",
-	arm_ADC_VS:            "ADC.VS",
-	arm_ADC_VC:            "ADC.VC",
-	arm_ADC_HI:            "ADC.HI",
-	arm_ADC_LS:            "ADC.LS",
-	arm_ADC_GE:            "ADC.GE",
-	arm_ADC_LT:            "ADC.LT",
-	arm_ADC_GT:            "ADC.GT",
-	arm_ADC_LE:            "ADC.LE",
-	arm_ADC:               "ADC",
-	arm_ADC_ZZ:            "ADC.ZZ",
-	arm_ADC_S_EQ:          "ADC.S.EQ",
-	arm_ADC_S_NE:          "ADC.S.NE",
-	arm_ADC_S_CS:          "ADC.S.CS",
-	arm_ADC_S_CC:          "ADC.S.CC",
-	arm_ADC_S_MI:          "ADC.S.MI",
-	arm_ADC_S_PL:          "ADC.S.PL",
-	arm_ADC_S_VS:          "ADC.S.VS",
-	arm_ADC_S_VC:          "ADC.S.VC",
-	arm_ADC_S_HI:          "ADC.S.HI",
-	arm_ADC_S_LS:          "ADC.S.LS",
-	arm_ADC_S_GE:          "ADC.S.GE",
-	arm_ADC_S_LT:          "ADC.S.LT",
-	arm_ADC_S_GT:          "ADC.S.GT",
-	arm_ADC_S_LE:          "ADC.S.LE",
-	arm_ADC_S:             "ADC.S",
-	arm_ADC_S_ZZ:          "ADC.S.ZZ",
-	arm_ADD_EQ:            "ADD.EQ",
-	arm_ADD_NE:            "ADD.NE",
-	arm_ADD_CS:            "ADD.CS",
-	arm_ADD_CC:            "ADD.CC",
-	arm_ADD_MI:            "ADD.MI",
-	arm_ADD_PL:            "ADD.PL",
-	arm_ADD_VS:            "ADD.VS",
-	arm_ADD_VC:            "ADD.VC",
-	arm_ADD_HI:            "ADD.HI",
-	arm_ADD_LS:            "ADD.LS",
-	arm_ADD_GE:            "ADD.GE",
-	arm_ADD_LT:            "ADD.LT",
-	arm_ADD_GT:            "ADD.GT",
-	arm_ADD_LE:            "ADD.LE",
-	arm_ADD:               "ADD",
-	arm_ADD_ZZ:            "ADD.ZZ",
-	arm_ADD_S_EQ:          "ADD.S.EQ",
-	arm_ADD_S_NE:          "ADD.S.NE",
-	arm_ADD_S_CS:          "ADD.S.CS",
-	arm_ADD_S_CC:          "ADD.S.CC",
-	arm_ADD_S_MI:          "ADD.S.MI",
-	arm_ADD_S_PL:          "ADD.S.PL",
-	arm_ADD_S_VS:          "ADD.S.VS",
-	arm_ADD_S_VC:          "ADD.S.VC",
-	arm_ADD_S_HI:          "ADD.S.HI",
-	arm_ADD_S_LS:          "ADD.S.LS",
-	arm_ADD_S_GE:          "ADD.S.GE",
-	arm_ADD_S_LT:          "ADD.S.LT",
-	arm_ADD_S_GT:          "ADD.S.GT",
-	arm_ADD_S_LE:          "ADD.S.LE",
-	arm_ADD_S:             "ADD.S",
-	arm_ADD_S_ZZ:          "ADD.S.ZZ",
-	arm_AND_EQ:            "AND.EQ",
-	arm_AND_NE:            "AND.NE",
-	arm_AND_CS:            "AND.CS",
-	arm_AND_CC:            "AND.CC",
-	arm_AND_MI:            "AND.MI",
-	arm_AND_PL:            "AND.PL",
-	arm_AND_VS:            "AND.VS",
-	arm_AND_VC:            "AND.VC",
-	arm_AND_HI:            "AND.HI",
-	arm_AND_LS:            "AND.LS",
-	arm_AND_GE:            "AND.GE",
-	arm_AND_LT:            "AND.LT",
-	arm_AND_GT:            "AND.GT",
-	arm_AND_LE:            "AND.LE",
-	arm_AND:               "AND",
-	arm_AND_ZZ:            "AND.ZZ",
-	arm_AND_S_EQ:          "AND.S.EQ",
-	arm_AND_S_NE:          "AND.S.NE",
-	arm_AND_S_CS:          "AND.S.CS",
-	arm_AND_S_CC:          "AND.S.CC",
-	arm_AND_S_MI:          "AND.S.MI",
-	arm_AND_S_PL:          "AND.S.PL",
-	arm_AND_S_VS:          "AND.S.VS",
-	arm_AND_S_VC:          "AND.S.VC",
-	arm_AND_S_HI:          "AND.S.HI",
-	arm_AND_S_LS:          "AND.S.LS",
-	arm_AND_S_GE:          "AND.S.GE",
-	arm_AND_S_LT:          "AND.S.LT",
-	arm_AND_S_GT:          "AND.S.GT",
-	arm_AND_S_LE:          "AND.S.LE",
-	arm_AND_S:             "AND.S",
-	arm_AND_S_ZZ:          "AND.S.ZZ",
-	arm_ASR_EQ:            "ASR.EQ",
-	arm_ASR_NE:            "ASR.NE",
-	arm_ASR_CS:            "ASR.CS",
-	arm_ASR_CC:            "ASR.CC",
-	arm_ASR_MI:            "ASR.MI",
-	arm_ASR_PL:            "ASR.PL",
-	arm_ASR_VS:            "ASR.VS",
-	arm_ASR_VC:            "ASR.VC",
-	arm_ASR_HI:            "ASR.HI",
-	arm_ASR_LS:            "ASR.LS",
-	arm_ASR_GE:            "ASR.GE",
-	arm_ASR_LT:            "ASR.LT",
-	arm_ASR_GT:            "ASR.GT",
-	arm_ASR_LE:            "ASR.LE",
-	arm_ASR:               "ASR",
-	arm_ASR_ZZ:            "ASR.ZZ",
-	arm_ASR_S_EQ:          "ASR.S.EQ",
-	arm_ASR_S_NE:          "ASR.S.NE",
-	arm_ASR_S_CS:          "ASR.S.CS",
-	arm_ASR_S_CC:          "ASR.S.CC",
-	arm_ASR_S_MI:          "ASR.S.MI",
-	arm_ASR_S_PL:          "ASR.S.PL",
-	arm_ASR_S_VS:          "ASR.S.VS",
-	arm_ASR_S_VC:          "ASR.S.VC",
-	arm_ASR_S_HI:          "ASR.S.HI",
-	arm_ASR_S_LS:          "ASR.S.LS",
-	arm_ASR_S_GE:          "ASR.S.GE",
-	arm_ASR_S_LT:          "ASR.S.LT",
-	arm_ASR_S_GT:          "ASR.S.GT",
-	arm_ASR_S_LE:          "ASR.S.LE",
-	arm_ASR_S:             "ASR.S",
-	arm_ASR_S_ZZ:          "ASR.S.ZZ",
-	arm_B_EQ:              "B.EQ",
-	arm_B_NE:              "B.NE",
-	arm_B_CS:              "B.CS",
-	arm_B_CC:              "B.CC",
-	arm_B_MI:              "B.MI",
-	arm_B_PL:              "B.PL",
-	arm_B_VS:              "B.VS",
-	arm_B_VC:              "B.VC",
-	arm_B_HI:              "B.HI",
-	arm_B_LS:              "B.LS",
-	arm_B_GE:              "B.GE",
-	arm_B_LT:              "B.LT",
-	arm_B_GT:              "B.GT",
-	arm_B_LE:              "B.LE",
-	arm_B:                 "B",
-	arm_B_ZZ:              "B.ZZ",
-	arm_BFC_EQ:            "BFC.EQ",
-	arm_BFC_NE:            "BFC.NE",
-	arm_BFC_CS:            "BFC.CS",
-	arm_BFC_CC:            "BFC.CC",
-	arm_BFC_MI:            "BFC.MI",
-	arm_BFC_PL:            "BFC.PL",
-	arm_BFC_VS:            "BFC.VS",
-	arm_BFC_VC:            "BFC.VC",
-	arm_BFC_HI:            "BFC.HI",
-	arm_BFC_LS:            "BFC.LS",
-	arm_BFC_GE:            "BFC.GE",
-	arm_BFC_LT:            "BFC.LT",
-	arm_BFC_GT:            "BFC.GT",
-	arm_BFC_LE:            "BFC.LE",
-	arm_BFC:               "BFC",
-	arm_BFC_ZZ:            "BFC.ZZ",
-	arm_BFI_EQ:            "BFI.EQ",
-	arm_BFI_NE:            "BFI.NE",
-	arm_BFI_CS:            "BFI.CS",
-	arm_BFI_CC:            "BFI.CC",
-	arm_BFI_MI:            "BFI.MI",
-	arm_BFI_PL:            "BFI.PL",
-	arm_BFI_VS:            "BFI.VS",
-	arm_BFI_VC:            "BFI.VC",
-	arm_BFI_HI:            "BFI.HI",
-	arm_BFI_LS:            "BFI.LS",
-	arm_BFI_GE:            "BFI.GE",
-	arm_BFI_LT:            "BFI.LT",
-	arm_BFI_GT:            "BFI.GT",
-	arm_BFI_LE:            "BFI.LE",
-	arm_BFI:               "BFI",
-	arm_BFI_ZZ:            "BFI.ZZ",
-	arm_BIC_EQ:            "BIC.EQ",
-	arm_BIC_NE:            "BIC.NE",
-	arm_BIC_CS:            "BIC.CS",
-	arm_BIC_CC:            "BIC.CC",
-	arm_BIC_MI:            "BIC.MI",
-	arm_BIC_PL:            "BIC.PL",
-	arm_BIC_VS:            "BIC.VS",
-	arm_BIC_VC:            "BIC.VC",
-	arm_BIC_HI:            "BIC.HI",
-	arm_BIC_LS:            "BIC.LS",
-	arm_BIC_GE:            "BIC.GE",
-	arm_BIC_LT:            "BIC.LT",
-	arm_BIC_GT:            "BIC.GT",
-	arm_BIC_LE:            "BIC.LE",
-	arm_BIC:               "BIC",
-	arm_BIC_ZZ:            "BIC.ZZ",
-	arm_BIC_S_EQ:          "BIC.S.EQ",
-	arm_BIC_S_NE:          "BIC.S.NE",
-	arm_BIC_S_CS:          "BIC.S.CS",
-	arm_BIC_S_CC:          "BIC.S.CC",
-	arm_BIC_S_MI:          "BIC.S.MI",
-	arm_BIC_S_PL:          "BIC.S.PL",
-	arm_BIC_S_VS:          "BIC.S.VS",
-	arm_BIC_S_VC:          "BIC.S.VC",
-	arm_BIC_S_HI:          "BIC.S.HI",
-	arm_BIC_S_LS:          "BIC.S.LS",
-	arm_BIC_S_GE:          "BIC.S.GE",
-	arm_BIC_S_LT:          "BIC.S.LT",
-	arm_BIC_S_GT:          "BIC.S.GT",
-	arm_BIC_S_LE:          "BIC.S.LE",
-	arm_BIC_S:             "BIC.S",
-	arm_BIC_S_ZZ:          "BIC.S.ZZ",
-	arm_BKPT_EQ:           "BKPT.EQ",
-	arm_BKPT_NE:           "BKPT.NE",
-	arm_BKPT_CS:           "BKPT.CS",
-	arm_BKPT_CC:           "BKPT.CC",
-	arm_BKPT_MI:           "BKPT.MI",
-	arm_BKPT_PL:           "BKPT.PL",
-	arm_BKPT_VS:           "BKPT.VS",
-	arm_BKPT_VC:           "BKPT.VC",
-	arm_BKPT_HI:           "BKPT.HI",
-	arm_BKPT_LS:           "BKPT.LS",
-	arm_BKPT_GE:           "BKPT.GE",
-	arm_BKPT_LT:           "BKPT.LT",
-	arm_BKPT_GT:           "BKPT.GT",
-	arm_BKPT_LE:           "BKPT.LE",
-	arm_BKPT:              "BKPT",
-	arm_BKPT_ZZ:           "BKPT.ZZ",
-	arm_BL_EQ:             "BL.EQ",
-	arm_BL_NE:             "BL.NE",
-	arm_BL_CS:             "BL.CS",
-	arm_BL_CC:             "BL.CC",
-	arm_BL_MI:             "BL.MI",
-	arm_BL_PL:             "BL.PL",
-	arm_BL_VS:             "BL.VS",
-	arm_BL_VC:             "BL.VC",
-	arm_BL_HI:             "BL.HI",
-	arm_BL_LS:             "BL.LS",
-	arm_BL_GE:             "BL.GE",
-	arm_BL_LT:             "BL.LT",
-	arm_BL_GT:             "BL.GT",
-	arm_BL_LE:             "BL.LE",
-	arm_BL:                "BL",
-	arm_BL_ZZ:             "BL.ZZ",
-	arm_BLX_EQ:            "BLX.EQ",
-	arm_BLX_NE:            "BLX.NE",
-	arm_BLX_CS:            "BLX.CS",
-	arm_BLX_CC:            "BLX.CC",
-	arm_BLX_MI:            "BLX.MI",
-	arm_BLX_PL:            "BLX.PL",
-	arm_BLX_VS:            "BLX.VS",
-	arm_BLX_VC:            "BLX.VC",
-	arm_BLX_HI:            "BLX.HI",
-	arm_BLX_LS:            "BLX.LS",
-	arm_BLX_GE:            "BLX.GE",
-	arm_BLX_LT:            "BLX.LT",
-	arm_BLX_GT:            "BLX.GT",
-	arm_BLX_LE:            "BLX.LE",
-	arm_BLX:               "BLX",
-	arm_BLX_ZZ:            "BLX.ZZ",
-	arm_BX_EQ:             "BX.EQ",
-	arm_BX_NE:             "BX.NE",
-	arm_BX_CS:             "BX.CS",
-	arm_BX_CC:             "BX.CC",
-	arm_BX_MI:             "BX.MI",
-	arm_BX_PL:             "BX.PL",
-	arm_BX_VS:             "BX.VS",
-	arm_BX_VC:             "BX.VC",
-	arm_BX_HI:             "BX.HI",
-	arm_BX_LS:             "BX.LS",
-	arm_BX_GE:             "BX.GE",
-	arm_BX_LT:             "BX.LT",
-	arm_BX_GT:             "BX.GT",
-	arm_BX_LE:             "BX.LE",
-	arm_BX:                "BX",
-	arm_BX_ZZ:             "BX.ZZ",
-	arm_BXJ_EQ:            "BXJ.EQ",
-	arm_BXJ_NE:            "BXJ.NE",
-	arm_BXJ_CS:            "BXJ.CS",
-	arm_BXJ_CC:            "BXJ.CC",
-	arm_BXJ_MI:            "BXJ.MI",
-	arm_BXJ_PL:            "BXJ.PL",
-	arm_BXJ_VS:            "BXJ.VS",
-	arm_BXJ_VC:            "BXJ.VC",
-	arm_BXJ_HI:            "BXJ.HI",
-	arm_BXJ_LS:            "BXJ.LS",
-	arm_BXJ_GE:            "BXJ.GE",
-	arm_BXJ_LT:            "BXJ.LT",
-	arm_BXJ_GT:            "BXJ.GT",
-	arm_BXJ_LE:            "BXJ.LE",
-	arm_BXJ:               "BXJ",
-	arm_BXJ_ZZ:            "BXJ.ZZ",
-	arm_CLREX:             "CLREX",
-	arm_CLZ_EQ:            "CLZ.EQ",
-	arm_CLZ_NE:            "CLZ.NE",
-	arm_CLZ_CS:            "CLZ.CS",
-	arm_CLZ_CC:            "CLZ.CC",
-	arm_CLZ_MI:            "CLZ.MI",
-	arm_CLZ_PL:            "CLZ.PL",
-	arm_CLZ_VS:            "CLZ.VS",
-	arm_CLZ_VC:            "CLZ.VC",
-	arm_CLZ_HI:            "CLZ.HI",
-	arm_CLZ_LS:            "CLZ.LS",
-	arm_CLZ_GE:            "CLZ.GE",
-	arm_CLZ_LT:            "CLZ.LT",
-	arm_CLZ_GT:            "CLZ.GT",
-	arm_CLZ_LE:            "CLZ.LE",
-	arm_CLZ:               "CLZ",
-	arm_CLZ_ZZ:            "CLZ.ZZ",
-	arm_CMN_EQ:            "CMN.EQ",
-	arm_CMN_NE:            "CMN.NE",
-	arm_CMN_CS:            "CMN.CS",
-	arm_CMN_CC:            "CMN.CC",
-	arm_CMN_MI:            "CMN.MI",
-	arm_CMN_PL:            "CMN.PL",
-	arm_CMN_VS:            "CMN.VS",
-	arm_CMN_VC:            "CMN.VC",
-	arm_CMN_HI:            "CMN.HI",
-	arm_CMN_LS:            "CMN.LS",
-	arm_CMN_GE:            "CMN.GE",
-	arm_CMN_LT:            "CMN.LT",
-	arm_CMN_GT:            "CMN.GT",
-	arm_CMN_LE:            "CMN.LE",
-	arm_CMN:               "CMN",
-	arm_CMN_ZZ:            "CMN.ZZ",
-	arm_CMP_EQ:            "CMP.EQ",
-	arm_CMP_NE:            "CMP.NE",
-	arm_CMP_CS:            "CMP.CS",
-	arm_CMP_CC:            "CMP.CC",
-	arm_CMP_MI:            "CMP.MI",
-	arm_CMP_PL:            "CMP.PL",
-	arm_CMP_VS:            "CMP.VS",
-	arm_CMP_VC:            "CMP.VC",
-	arm_CMP_HI:            "CMP.HI",
-	arm_CMP_LS:            "CMP.LS",
-	arm_CMP_GE:            "CMP.GE",
-	arm_CMP_LT:            "CMP.LT",
-	arm_CMP_GT:            "CMP.GT",
-	arm_CMP_LE:            "CMP.LE",
-	arm_CMP:               "CMP",
-	arm_CMP_ZZ:            "CMP.ZZ",
-	arm_DBG_EQ:            "DBG.EQ",
-	arm_DBG_NE:            "DBG.NE",
-	arm_DBG_CS:            "DBG.CS",
-	arm_DBG_CC:            "DBG.CC",
-	arm_DBG_MI:            "DBG.MI",
-	arm_DBG_PL:            "DBG.PL",
-	arm_DBG_VS:            "DBG.VS",
-	arm_DBG_VC:            "DBG.VC",
-	arm_DBG_HI:            "DBG.HI",
-	arm_DBG_LS:            "DBG.LS",
-	arm_DBG_GE:            "DBG.GE",
-	arm_DBG_LT:            "DBG.LT",
-	arm_DBG_GT:            "DBG.GT",
-	arm_DBG_LE:            "DBG.LE",
-	arm_DBG:               "DBG",
-	arm_DBG_ZZ:            "DBG.ZZ",
-	arm_DMB:               "DMB",
-	arm_DSB:               "DSB",
-	arm_EOR_EQ:            "EOR.EQ",
-	arm_EOR_NE:            "EOR.NE",
-	arm_EOR_CS:            "EOR.CS",
-	arm_EOR_CC:            "EOR.CC",
-	arm_EOR_MI:            "EOR.MI",
-	arm_EOR_PL:            "EOR.PL",
-	arm_EOR_VS:            "EOR.VS",
-	arm_EOR_VC:            "EOR.VC",
-	arm_EOR_HI:            "EOR.HI",
-	arm_EOR_LS:            "EOR.LS",
-	arm_EOR_GE:            "EOR.GE",
-	arm_EOR_LT:            "EOR.LT",
-	arm_EOR_GT:            "EOR.GT",
-	arm_EOR_LE:            "EOR.LE",
-	arm_EOR:               "EOR",
-	arm_EOR_ZZ:            "EOR.ZZ",
-	arm_EOR_S_EQ:          "EOR.S.EQ",
-	arm_EOR_S_NE:          "EOR.S.NE",
-	arm_EOR_S_CS:          "EOR.S.CS",
-	arm_EOR_S_CC:          "EOR.S.CC",
-	arm_EOR_S_MI:          "EOR.S.MI",
-	arm_EOR_S_PL:          "EOR.S.PL",
-	arm_EOR_S_VS:          "EOR.S.VS",
-	arm_EOR_S_VC:          "EOR.S.VC",
-	arm_EOR_S_HI:          "EOR.S.HI",
-	arm_EOR_S_LS:          "EOR.S.LS",
-	arm_EOR_S_GE:          "EOR.S.GE",
-	arm_EOR_S_LT:          "EOR.S.LT",
-	arm_EOR_S_GT:          "EOR.S.GT",
-	arm_EOR_S_LE:          "EOR.S.LE",
-	arm_EOR_S:             "EOR.S",
-	arm_EOR_S_ZZ:          "EOR.S.ZZ",
-	arm_ISB:               "ISB",
-	arm_LDM_EQ:            "LDM.EQ",
-	arm_LDM_NE:            "LDM.NE",
-	arm_LDM_CS:            "LDM.CS",
-	arm_LDM_CC:            "LDM.CC",
-	arm_LDM_MI:            "LDM.MI",
-	arm_LDM_PL:            "LDM.PL",
-	arm_LDM_VS:            "LDM.VS",
-	arm_LDM_VC:            "LDM.VC",
-	arm_LDM_HI:            "LDM.HI",
-	arm_LDM_LS:            "LDM.LS",
-	arm_LDM_GE:            "LDM.GE",
-	arm_LDM_LT:            "LDM.LT",
-	arm_LDM_GT:            "LDM.GT",
-	arm_LDM_LE:            "LDM.LE",
-	arm_LDM:               "LDM",
-	arm_LDM_ZZ:            "LDM.ZZ",
-	arm_LDMDA_EQ:          "LDMDA.EQ",
-	arm_LDMDA_NE:          "LDMDA.NE",
-	arm_LDMDA_CS:          "LDMDA.CS",
-	arm_LDMDA_CC:          "LDMDA.CC",
-	arm_LDMDA_MI:          "LDMDA.MI",
-	arm_LDMDA_PL:          "LDMDA.PL",
-	arm_LDMDA_VS:          "LDMDA.VS",
-	arm_LDMDA_VC:          "LDMDA.VC",
-	arm_LDMDA_HI:          "LDMDA.HI",
-	arm_LDMDA_LS:          "LDMDA.LS",
-	arm_LDMDA_GE:          "LDMDA.GE",
-	arm_LDMDA_LT:          "LDMDA.LT",
-	arm_LDMDA_GT:          "LDMDA.GT",
-	arm_LDMDA_LE:          "LDMDA.LE",
-	arm_LDMDA:             "LDMDA",
-	arm_LDMDA_ZZ:          "LDMDA.ZZ",
-	arm_LDMDB_EQ:          "LDMDB.EQ",
-	arm_LDMDB_NE:          "LDMDB.NE",
-	arm_LDMDB_CS:          "LDMDB.CS",
-	arm_LDMDB_CC:          "LDMDB.CC",
-	arm_LDMDB_MI:          "LDMDB.MI",
-	arm_LDMDB_PL:          "LDMDB.PL",
-	arm_LDMDB_VS:          "LDMDB.VS",
-	arm_LDMDB_VC:          "LDMDB.VC",
-	arm_LDMDB_HI:          "LDMDB.HI",
-	arm_LDMDB_LS:          "LDMDB.LS",
-	arm_LDMDB_GE:          "LDMDB.GE",
-	arm_LDMDB_LT:          "LDMDB.LT",
-	arm_LDMDB_GT:          "LDMDB.GT",
-	arm_LDMDB_LE:          "LDMDB.LE",
-	arm_LDMDB:             "LDMDB",
-	arm_LDMDB_ZZ:          "LDMDB.ZZ",
-	arm_LDMIB_EQ:          "LDMIB.EQ",
-	arm_LDMIB_NE:          "LDMIB.NE",
-	arm_LDMIB_CS:          "LDMIB.CS",
-	arm_LDMIB_CC:          "LDMIB.CC",
-	arm_LDMIB_MI:          "LDMIB.MI",
-	arm_LDMIB_PL:          "LDMIB.PL",
-	arm_LDMIB_VS:          "LDMIB.VS",
-	arm_LDMIB_VC:          "LDMIB.VC",
-	arm_LDMIB_HI:          "LDMIB.HI",
-	arm_LDMIB_LS:          "LDMIB.LS",
-	arm_LDMIB_GE:          "LDMIB.GE",
-	arm_LDMIB_LT:          "LDMIB.LT",
-	arm_LDMIB_GT:          "LDMIB.GT",
-	arm_LDMIB_LE:          "LDMIB.LE",
-	arm_LDMIB:             "LDMIB",
-	arm_LDMIB_ZZ:          "LDMIB.ZZ",
-	arm_LDR_EQ:            "LDR.EQ",
-	arm_LDR_NE:            "LDR.NE",
-	arm_LDR_CS:            "LDR.CS",
-	arm_LDR_CC:            "LDR.CC",
-	arm_LDR_MI:            "LDR.MI",
-	arm_LDR_PL:            "LDR.PL",
-	arm_LDR_VS:            "LDR.VS",
-	arm_LDR_VC:            "LDR.VC",
-	arm_LDR_HI:            "LDR.HI",
-	arm_LDR_LS:            "LDR.LS",
-	arm_LDR_GE:            "LDR.GE",
-	arm_LDR_LT:            "LDR.LT",
-	arm_LDR_GT:            "LDR.GT",
-	arm_LDR_LE:            "LDR.LE",
-	arm_LDR:               "LDR",
-	arm_LDR_ZZ:            "LDR.ZZ",
-	arm_LDRB_EQ:           "LDRB.EQ",
-	arm_LDRB_NE:           "LDRB.NE",
-	arm_LDRB_CS:           "LDRB.CS",
-	arm_LDRB_CC:           "LDRB.CC",
-	arm_LDRB_MI:           "LDRB.MI",
-	arm_LDRB_PL:           "LDRB.PL",
-	arm_LDRB_VS:           "LDRB.VS",
-	arm_LDRB_VC:           "LDRB.VC",
-	arm_LDRB_HI:           "LDRB.HI",
-	arm_LDRB_LS:           "LDRB.LS",
-	arm_LDRB_GE:           "LDRB.GE",
-	arm_LDRB_LT:           "LDRB.LT",
-	arm_LDRB_GT:           "LDRB.GT",
-	arm_LDRB_LE:           "LDRB.LE",
-	arm_LDRB:              "LDRB",
-	arm_LDRB_ZZ:           "LDRB.ZZ",
-	arm_LDRBT_EQ:          "LDRBT.EQ",
-	arm_LDRBT_NE:          "LDRBT.NE",
-	arm_LDRBT_CS:          "LDRBT.CS",
-	arm_LDRBT_CC:          "LDRBT.CC",
-	arm_LDRBT_MI:          "LDRBT.MI",
-	arm_LDRBT_PL:          "LDRBT.PL",
-	arm_LDRBT_VS:          "LDRBT.VS",
-	arm_LDRBT_VC:          "LDRBT.VC",
-	arm_LDRBT_HI:          "LDRBT.HI",
-	arm_LDRBT_LS:          "LDRBT.LS",
-	arm_LDRBT_GE:          "LDRBT.GE",
-	arm_LDRBT_LT:          "LDRBT.LT",
-	arm_LDRBT_GT:          "LDRBT.GT",
-	arm_LDRBT_LE:          "LDRBT.LE",
-	arm_LDRBT:             "LDRBT",
-	arm_LDRBT_ZZ:          "LDRBT.ZZ",
-	arm_LDRD_EQ:           "LDRD.EQ",
-	arm_LDRD_NE:           "LDRD.NE",
-	arm_LDRD_CS:           "LDRD.CS",
-	arm_LDRD_CC:           "LDRD.CC",
-	arm_LDRD_MI:           "LDRD.MI",
-	arm_LDRD_PL:           "LDRD.PL",
-	arm_LDRD_VS:           "LDRD.VS",
-	arm_LDRD_VC:           "LDRD.VC",
-	arm_LDRD_HI:           "LDRD.HI",
-	arm_LDRD_LS:           "LDRD.LS",
-	arm_LDRD_GE:           "LDRD.GE",
-	arm_LDRD_LT:           "LDRD.LT",
-	arm_LDRD_GT:           "LDRD.GT",
-	arm_LDRD_LE:           "LDRD.LE",
-	arm_LDRD:              "LDRD",
-	arm_LDRD_ZZ:           "LDRD.ZZ",
-	arm_LDREX_EQ:          "LDREX.EQ",
-	arm_LDREX_NE:          "LDREX.NE",
-	arm_LDREX_CS:          "LDREX.CS",
-	arm_LDREX_CC:          "LDREX.CC",
-	arm_LDREX_MI:          "LDREX.MI",
-	arm_LDREX_PL:          "LDREX.PL",
-	arm_LDREX_VS:          "LDREX.VS",
-	arm_LDREX_VC:          "LDREX.VC",
-	arm_LDREX_HI:          "LDREX.HI",
-	arm_LDREX_LS:          "LDREX.LS",
-	arm_LDREX_GE:          "LDREX.GE",
-	arm_LDREX_LT:          "LDREX.LT",
-	arm_LDREX_GT:          "LDREX.GT",
-	arm_LDREX_LE:          "LDREX.LE",
-	arm_LDREX:             "LDREX",
-	arm_LDREX_ZZ:          "LDREX.ZZ",
-	arm_LDREXB_EQ:         "LDREXB.EQ",
-	arm_LDREXB_NE:         "LDREXB.NE",
-	arm_LDREXB_CS:         "LDREXB.CS",
-	arm_LDREXB_CC:         "LDREXB.CC",
-	arm_LDREXB_MI:         "LDREXB.MI",
-	arm_LDREXB_PL:         "LDREXB.PL",
-	arm_LDREXB_VS:         "LDREXB.VS",
-	arm_LDREXB_VC:         "LDREXB.VC",
-	arm_LDREXB_HI:         "LDREXB.HI",
-	arm_LDREXB_LS:         "LDREXB.LS",
-	arm_LDREXB_GE:         "LDREXB.GE",
-	arm_LDREXB_LT:         "LDREXB.LT",
-	arm_LDREXB_GT:         "LDREXB.GT",
-	arm_LDREXB_LE:         "LDREXB.LE",
-	arm_LDREXB:            "LDREXB",
-	arm_LDREXB_ZZ:         "LDREXB.ZZ",
-	arm_LDREXD_EQ:         "LDREXD.EQ",
-	arm_LDREXD_NE:         "LDREXD.NE",
-	arm_LDREXD_CS:         "LDREXD.CS",
-	arm_LDREXD_CC:         "LDREXD.CC",
-	arm_LDREXD_MI:         "LDREXD.MI",
-	arm_LDREXD_PL:         "LDREXD.PL",
-	arm_LDREXD_VS:         "LDREXD.VS",
-	arm_LDREXD_VC:         "LDREXD.VC",
-	arm_LDREXD_HI:         "LDREXD.HI",
-	arm_LDREXD_LS:         "LDREXD.LS",
-	arm_LDREXD_GE:         "LDREXD.GE",
-	arm_LDREXD_LT:         "LDREXD.LT",
-	arm_LDREXD_GT:         "LDREXD.GT",
-	arm_LDREXD_LE:         "LDREXD.LE",
-	arm_LDREXD:            "LDREXD",
-	arm_LDREXD_ZZ:         "LDREXD.ZZ",
-	arm_LDREXH_EQ:         "LDREXH.EQ",
-	arm_LDREXH_NE:         "LDREXH.NE",
-	arm_LDREXH_CS:         "LDREXH.CS",
-	arm_LDREXH_CC:         "LDREXH.CC",
-	arm_LDREXH_MI:         "LDREXH.MI",
-	arm_LDREXH_PL:         "LDREXH.PL",
-	arm_LDREXH_VS:         "LDREXH.VS",
-	arm_LDREXH_VC:         "LDREXH.VC",
-	arm_LDREXH_HI:         "LDREXH.HI",
-	arm_LDREXH_LS:         "LDREXH.LS",
-	arm_LDREXH_GE:         "LDREXH.GE",
-	arm_LDREXH_LT:         "LDREXH.LT",
-	arm_LDREXH_GT:         "LDREXH.GT",
-	arm_LDREXH_LE:         "LDREXH.LE",
-	arm_LDREXH:            "LDREXH",
-	arm_LDREXH_ZZ:         "LDREXH.ZZ",
-	arm_LDRH_EQ:           "LDRH.EQ",
-	arm_LDRH_NE:           "LDRH.NE",
-	arm_LDRH_CS:           "LDRH.CS",
-	arm_LDRH_CC:           "LDRH.CC",
-	arm_LDRH_MI:           "LDRH.MI",
-	arm_LDRH_PL:           "LDRH.PL",
-	arm_LDRH_VS:           "LDRH.VS",
-	arm_LDRH_VC:           "LDRH.VC",
-	arm_LDRH_HI:           "LDRH.HI",
-	arm_LDRH_LS:           "LDRH.LS",
-	arm_LDRH_GE:           "LDRH.GE",
-	arm_LDRH_LT:           "LDRH.LT",
-	arm_LDRH_GT:           "LDRH.GT",
-	arm_LDRH_LE:           "LDRH.LE",
-	arm_LDRH:              "LDRH",
-	arm_LDRH_ZZ:           "LDRH.ZZ",
-	arm_LDRHT_EQ:          "LDRHT.EQ",
-	arm_LDRHT_NE:          "LDRHT.NE",
-	arm_LDRHT_CS:          "LDRHT.CS",
-	arm_LDRHT_CC:          "LDRHT.CC",
-	arm_LDRHT_MI:          "LDRHT.MI",
-	arm_LDRHT_PL:          "LDRHT.PL",
-	arm_LDRHT_VS:          "LDRHT.VS",
-	arm_LDRHT_VC:          "LDRHT.VC",
-	arm_LDRHT_HI:          "LDRHT.HI",
-	arm_LDRHT_LS:          "LDRHT.LS",
-	arm_LDRHT_GE:          "LDRHT.GE",
-	arm_LDRHT_LT:          "LDRHT.LT",
-	arm_LDRHT_GT:          "LDRHT.GT",
-	arm_LDRHT_LE:          "LDRHT.LE",
-	arm_LDRHT:             "LDRHT",
-	arm_LDRHT_ZZ:          "LDRHT.ZZ",
-	arm_LDRSB_EQ:          "LDRSB.EQ",
-	arm_LDRSB_NE:          "LDRSB.NE",
-	arm_LDRSB_CS:          "LDRSB.CS",
-	arm_LDRSB_CC:          "LDRSB.CC",
-	arm_LDRSB_MI:          "LDRSB.MI",
-	arm_LDRSB_PL:          "LDRSB.PL",
-	arm_LDRSB_VS:          "LDRSB.VS",
-	arm_LDRSB_VC:          "LDRSB.VC",
-	arm_LDRSB_HI:          "LDRSB.HI",
-	arm_LDRSB_LS:          "LDRSB.LS",
-	arm_LDRSB_GE:          "LDRSB.GE",
-	arm_LDRSB_LT:          "LDRSB.LT",
-	arm_LDRSB_GT:          "LDRSB.GT",
-	arm_LDRSB_LE:          "LDRSB.LE",
-	arm_LDRSB:             "LDRSB",
-	arm_LDRSB_ZZ:          "LDRSB.ZZ",
-	arm_LDRSBT_EQ:         "LDRSBT.EQ",
-	arm_LDRSBT_NE:         "LDRSBT.NE",
-	arm_LDRSBT_CS:         "LDRSBT.CS",
-	arm_LDRSBT_CC:         "LDRSBT.CC",
-	arm_LDRSBT_MI:         "LDRSBT.MI",
-	arm_LDRSBT_PL:         "LDRSBT.PL",
-	arm_LDRSBT_VS:         "LDRSBT.VS",
-	arm_LDRSBT_VC:         "LDRSBT.VC",
-	arm_LDRSBT_HI:         "LDRSBT.HI",
-	arm_LDRSBT_LS:         "LDRSBT.LS",
-	arm_LDRSBT_GE:         "LDRSBT.GE",
-	arm_LDRSBT_LT:         "LDRSBT.LT",
-	arm_LDRSBT_GT:         "LDRSBT.GT",
-	arm_LDRSBT_LE:         "LDRSBT.LE",
-	arm_LDRSBT:            "LDRSBT",
-	arm_LDRSBT_ZZ:         "LDRSBT.ZZ",
-	arm_LDRSH_EQ:          "LDRSH.EQ",
-	arm_LDRSH_NE:          "LDRSH.NE",
-	arm_LDRSH_CS:          "LDRSH.CS",
-	arm_LDRSH_CC:          "LDRSH.CC",
-	arm_LDRSH_MI:          "LDRSH.MI",
-	arm_LDRSH_PL:          "LDRSH.PL",
-	arm_LDRSH_VS:          "LDRSH.VS",
-	arm_LDRSH_VC:          "LDRSH.VC",
-	arm_LDRSH_HI:          "LDRSH.HI",
-	arm_LDRSH_LS:          "LDRSH.LS",
-	arm_LDRSH_GE:          "LDRSH.GE",
-	arm_LDRSH_LT:          "LDRSH.LT",
-	arm_LDRSH_GT:          "LDRSH.GT",
-	arm_LDRSH_LE:          "LDRSH.LE",
-	arm_LDRSH:             "LDRSH",
-	arm_LDRSH_ZZ:          "LDRSH.ZZ",
-	arm_LDRSHT_EQ:         "LDRSHT.EQ",
-	arm_LDRSHT_NE:         "LDRSHT.NE",
-	arm_LDRSHT_CS:         "LDRSHT.CS",
-	arm_LDRSHT_CC:         "LDRSHT.CC",
-	arm_LDRSHT_MI:         "LDRSHT.MI",
-	arm_LDRSHT_PL:         "LDRSHT.PL",
-	arm_LDRSHT_VS:         "LDRSHT.VS",
-	arm_LDRSHT_VC:         "LDRSHT.VC",
-	arm_LDRSHT_HI:         "LDRSHT.HI",
-	arm_LDRSHT_LS:         "LDRSHT.LS",
-	arm_LDRSHT_GE:         "LDRSHT.GE",
-	arm_LDRSHT_LT:         "LDRSHT.LT",
-	arm_LDRSHT_GT:         "LDRSHT.GT",
-	arm_LDRSHT_LE:         "LDRSHT.LE",
-	arm_LDRSHT:            "LDRSHT",
-	arm_LDRSHT_ZZ:         "LDRSHT.ZZ",
-	arm_LDRT_EQ:           "LDRT.EQ",
-	arm_LDRT_NE:           "LDRT.NE",
-	arm_LDRT_CS:           "LDRT.CS",
-	arm_LDRT_CC:           "LDRT.CC",
-	arm_LDRT_MI:           "LDRT.MI",
-	arm_LDRT_PL:           "LDRT.PL",
-	arm_LDRT_VS:           "LDRT.VS",
-	arm_LDRT_VC:           "LDRT.VC",
-	arm_LDRT_HI:           "LDRT.HI",
-	arm_LDRT_LS:           "LDRT.LS",
-	arm_LDRT_GE:           "LDRT.GE",
-	arm_LDRT_LT:           "LDRT.LT",
-	arm_LDRT_GT:           "LDRT.GT",
-	arm_LDRT_LE:           "LDRT.LE",
-	arm_LDRT:              "LDRT",
-	arm_LDRT_ZZ:           "LDRT.ZZ",
-	arm_LSL_EQ:            "LSL.EQ",
-	arm_LSL_NE:            "LSL.NE",
-	arm_LSL_CS:            "LSL.CS",
-	arm_LSL_CC:            "LSL.CC",
-	arm_LSL_MI:            "LSL.MI",
-	arm_LSL_PL:            "LSL.PL",
-	arm_LSL_VS:            "LSL.VS",
-	arm_LSL_VC:            "LSL.VC",
-	arm_LSL_HI:            "LSL.HI",
-	arm_LSL_LS:            "LSL.LS",
-	arm_LSL_GE:            "LSL.GE",
-	arm_LSL_LT:            "LSL.LT",
-	arm_LSL_GT:            "LSL.GT",
-	arm_LSL_LE:            "LSL.LE",
-	arm_LSL:               "LSL",
-	arm_LSL_ZZ:            "LSL.ZZ",
-	arm_LSL_S_EQ:          "LSL.S.EQ",
-	arm_LSL_S_NE:          "LSL.S.NE",
-	arm_LSL_S_CS:          "LSL.S.CS",
-	arm_LSL_S_CC:          "LSL.S.CC",
-	arm_LSL_S_MI:          "LSL.S.MI",
-	arm_LSL_S_PL:          "LSL.S.PL",
-	arm_LSL_S_VS:          "LSL.S.VS",
-	arm_LSL_S_VC:          "LSL.S.VC",
-	arm_LSL_S_HI:          "LSL.S.HI",
-	arm_LSL_S_LS:          "LSL.S.LS",
-	arm_LSL_S_GE:          "LSL.S.GE",
-	arm_LSL_S_LT:          "LSL.S.LT",
-	arm_LSL_S_GT:          "LSL.S.GT",
-	arm_LSL_S_LE:          "LSL.S.LE",
-	arm_LSL_S:             "LSL.S",
-	arm_LSL_S_ZZ:          "LSL.S.ZZ",
-	arm_LSR_EQ:            "LSR.EQ",
-	arm_LSR_NE:            "LSR.NE",
-	arm_LSR_CS:            "LSR.CS",
-	arm_LSR_CC:            "LSR.CC",
-	arm_LSR_MI:            "LSR.MI",
-	arm_LSR_PL:            "LSR.PL",
-	arm_LSR_VS:            "LSR.VS",
-	arm_LSR_VC:            "LSR.VC",
-	arm_LSR_HI:            "LSR.HI",
-	arm_LSR_LS:            "LSR.LS",
-	arm_LSR_GE:            "LSR.GE",
-	arm_LSR_LT:            "LSR.LT",
-	arm_LSR_GT:            "LSR.GT",
-	arm_LSR_LE:            "LSR.LE",
-	arm_LSR:               "LSR",
-	arm_LSR_ZZ:            "LSR.ZZ",
-	arm_LSR_S_EQ:          "LSR.S.EQ",
-	arm_LSR_S_NE:          "LSR.S.NE",
-	arm_LSR_S_CS:          "LSR.S.CS",
-	arm_LSR_S_CC:          "LSR.S.CC",
-	arm_LSR_S_MI:          "LSR.S.MI",
-	arm_LSR_S_PL:          "LSR.S.PL",
-	arm_LSR_S_VS:          "LSR.S.VS",
-	arm_LSR_S_VC:          "LSR.S.VC",
-	arm_LSR_S_HI:          "LSR.S.HI",
-	arm_LSR_S_LS:          "LSR.S.LS",
-	arm_LSR_S_GE:          "LSR.S.GE",
-	arm_LSR_S_LT:          "LSR.S.LT",
-	arm_LSR_S_GT:          "LSR.S.GT",
-	arm_LSR_S_LE:          "LSR.S.LE",
-	arm_LSR_S:             "LSR.S",
-	arm_LSR_S_ZZ:          "LSR.S.ZZ",
-	arm_MLA_EQ:            "MLA.EQ",
-	arm_MLA_NE:            "MLA.NE",
-	arm_MLA_CS:            "MLA.CS",
-	arm_MLA_CC:            "MLA.CC",
-	arm_MLA_MI:            "MLA.MI",
-	arm_MLA_PL:            "MLA.PL",
-	arm_MLA_VS:            "MLA.VS",
-	arm_MLA_VC:            "MLA.VC",
-	arm_MLA_HI:            "MLA.HI",
-	arm_MLA_LS:            "MLA.LS",
-	arm_MLA_GE:            "MLA.GE",
-	arm_MLA_LT:            "MLA.LT",
-	arm_MLA_GT:            "MLA.GT",
-	arm_MLA_LE:            "MLA.LE",
-	arm_MLA:               "MLA",
-	arm_MLA_ZZ:            "MLA.ZZ",
-	arm_MLA_S_EQ:          "MLA.S.EQ",
-	arm_MLA_S_NE:          "MLA.S.NE",
-	arm_MLA_S_CS:          "MLA.S.CS",
-	arm_MLA_S_CC:          "MLA.S.CC",
-	arm_MLA_S_MI:          "MLA.S.MI",
-	arm_MLA_S_PL:          "MLA.S.PL",
-	arm_MLA_S_VS:          "MLA.S.VS",
-	arm_MLA_S_VC:          "MLA.S.VC",
-	arm_MLA_S_HI:          "MLA.S.HI",
-	arm_MLA_S_LS:          "MLA.S.LS",
-	arm_MLA_S_GE:          "MLA.S.GE",
-	arm_MLA_S_LT:          "MLA.S.LT",
-	arm_MLA_S_GT:          "MLA.S.GT",
-	arm_MLA_S_LE:          "MLA.S.LE",
-	arm_MLA_S:             "MLA.S",
-	arm_MLA_S_ZZ:          "MLA.S.ZZ",
-	arm_MLS_EQ:            "MLS.EQ",
-	arm_MLS_NE:            "MLS.NE",
-	arm_MLS_CS:            "MLS.CS",
-	arm_MLS_CC:            "MLS.CC",
-	arm_MLS_MI:            "MLS.MI",
-	arm_MLS_PL:            "MLS.PL",
-	arm_MLS_VS:            "MLS.VS",
-	arm_MLS_VC:            "MLS.VC",
-	arm_MLS_HI:            "MLS.HI",
-	arm_MLS_LS:            "MLS.LS",
-	arm_MLS_GE:            "MLS.GE",
-	arm_MLS_LT:            "MLS.LT",
-	arm_MLS_GT:            "MLS.GT",
-	arm_MLS_LE:            "MLS.LE",
-	arm_MLS:               "MLS",
-	arm_MLS_ZZ:            "MLS.ZZ",
-	arm_MOV_EQ:            "MOV.EQ",
-	arm_MOV_NE:            "MOV.NE",
-	arm_MOV_CS:            "MOV.CS",
-	arm_MOV_CC:            "MOV.CC",
-	arm_MOV_MI:            "MOV.MI",
-	arm_MOV_PL:            "MOV.PL",
-	arm_MOV_VS:            "MOV.VS",
-	arm_MOV_VC:            "MOV.VC",
-	arm_MOV_HI:            "MOV.HI",
-	arm_MOV_LS:            "MOV.LS",
-	arm_MOV_GE:            "MOV.GE",
-	arm_MOV_LT:            "MOV.LT",
-	arm_MOV_GT:            "MOV.GT",
-	arm_MOV_LE:            "MOV.LE",
-	arm_MOV:               "MOV",
-	arm_MOV_ZZ:            "MOV.ZZ",
-	arm_MOV_S_EQ:          "MOV.S.EQ",
-	arm_MOV_S_NE:          "MOV.S.NE",
-	arm_MOV_S_CS:          "MOV.S.CS",
-	arm_MOV_S_CC:          "MOV.S.CC",
-	arm_MOV_S_MI:          "MOV.S.MI",
-	arm_MOV_S_PL:          "MOV.S.PL",
-	arm_MOV_S_VS:          "MOV.S.VS",
-	arm_MOV_S_VC:          "MOV.S.VC",
-	arm_MOV_S_HI:          "MOV.S.HI",
-	arm_MOV_S_LS:          "MOV.S.LS",
-	arm_MOV_S_GE:          "MOV.S.GE",
-	arm_MOV_S_LT:          "MOV.S.LT",
-	arm_MOV_S_GT:          "MOV.S.GT",
-	arm_MOV_S_LE:          "MOV.S.LE",
-	arm_MOV_S:             "MOV.S",
-	arm_MOV_S_ZZ:          "MOV.S.ZZ",
-	arm_MOVT_EQ:           "MOVT.EQ",
-	arm_MOVT_NE:           "MOVT.NE",
-	arm_MOVT_CS:           "MOVT.CS",
-	arm_MOVT_CC:           "MOVT.CC",
-	arm_MOVT_MI:           "MOVT.MI",
-	arm_MOVT_PL:           "MOVT.PL",
-	arm_MOVT_VS:           "MOVT.VS",
-	arm_MOVT_VC:           "MOVT.VC",
-	arm_MOVT_HI:           "MOVT.HI",
-	arm_MOVT_LS:           "MOVT.LS",
-	arm_MOVT_GE:           "MOVT.GE",
-	arm_MOVT_LT:           "MOVT.LT",
-	arm_MOVT_GT:           "MOVT.GT",
-	arm_MOVT_LE:           "MOVT.LE",
-	arm_MOVT:              "MOVT",
-	arm_MOVT_ZZ:           "MOVT.ZZ",
-	arm_MOVW_EQ:           "MOVW.EQ",
-	arm_MOVW_NE:           "MOVW.NE",
-	arm_MOVW_CS:           "MOVW.CS",
-	arm_MOVW_CC:           "MOVW.CC",
-	arm_MOVW_MI:           "MOVW.MI",
-	arm_MOVW_PL:           "MOVW.PL",
-	arm_MOVW_VS:           "MOVW.VS",
-	arm_MOVW_VC:           "MOVW.VC",
-	arm_MOVW_HI:           "MOVW.HI",
-	arm_MOVW_LS:           "MOVW.LS",
-	arm_MOVW_GE:           "MOVW.GE",
-	arm_MOVW_LT:           "MOVW.LT",
-	arm_MOVW_GT:           "MOVW.GT",
-	arm_MOVW_LE:           "MOVW.LE",
-	arm_MOVW:              "MOVW",
-	arm_MOVW_ZZ:           "MOVW.ZZ",
-	arm_MRS_EQ:            "MRS.EQ",
-	arm_MRS_NE:            "MRS.NE",
-	arm_MRS_CS:            "MRS.CS",
-	arm_MRS_CC:            "MRS.CC",
-	arm_MRS_MI:            "MRS.MI",
-	arm_MRS_PL:            "MRS.PL",
-	arm_MRS_VS:            "MRS.VS",
-	arm_MRS_VC:            "MRS.VC",
-	arm_MRS_HI:            "MRS.HI",
-	arm_MRS_LS:            "MRS.LS",
-	arm_MRS_GE:            "MRS.GE",
-	arm_MRS_LT:            "MRS.LT",
-	arm_MRS_GT:            "MRS.GT",
-	arm_MRS_LE:            "MRS.LE",
-	arm_MRS:               "MRS",
-	arm_MRS_ZZ:            "MRS.ZZ",
-	arm_MUL_EQ:            "MUL.EQ",
-	arm_MUL_NE:            "MUL.NE",
-	arm_MUL_CS:            "MUL.CS",
-	arm_MUL_CC:            "MUL.CC",
-	arm_MUL_MI:            "MUL.MI",
-	arm_MUL_PL:            "MUL.PL",
-	arm_MUL_VS:            "MUL.VS",
-	arm_MUL_VC:            "MUL.VC",
-	arm_MUL_HI:            "MUL.HI",
-	arm_MUL_LS:            "MUL.LS",
-	arm_MUL_GE:            "MUL.GE",
-	arm_MUL_LT:            "MUL.LT",
-	arm_MUL_GT:            "MUL.GT",
-	arm_MUL_LE:            "MUL.LE",
-	arm_MUL:               "MUL",
-	arm_MUL_ZZ:            "MUL.ZZ",
-	arm_MUL_S_EQ:          "MUL.S.EQ",
-	arm_MUL_S_NE:          "MUL.S.NE",
-	arm_MUL_S_CS:          "MUL.S.CS",
-	arm_MUL_S_CC:          "MUL.S.CC",
-	arm_MUL_S_MI:          "MUL.S.MI",
-	arm_MUL_S_PL:          "MUL.S.PL",
-	arm_MUL_S_VS:          "MUL.S.VS",
-	arm_MUL_S_VC:          "MUL.S.VC",
-	arm_MUL_S_HI:          "MUL.S.HI",
-	arm_MUL_S_LS:          "MUL.S.LS",
-	arm_MUL_S_GE:          "MUL.S.GE",
-	arm_MUL_S_LT:          "MUL.S.LT",
-	arm_MUL_S_GT:          "MUL.S.GT",
-	arm_MUL_S_LE:          "MUL.S.LE",
-	arm_MUL_S:             "MUL.S",
-	arm_MUL_S_ZZ:          "MUL.S.ZZ",
-	arm_MVN_EQ:            "MVN.EQ",
-	arm_MVN_NE:            "MVN.NE",
-	arm_MVN_CS:            "MVN.CS",
-	arm_MVN_CC:            "MVN.CC",
-	arm_MVN_MI:            "MVN.MI",
-	arm_MVN_PL:            "MVN.PL",
-	arm_MVN_VS:            "MVN.VS",
-	arm_MVN_VC:            "MVN.VC",
-	arm_MVN_HI:            "MVN.HI",
-	arm_MVN_LS:            "MVN.LS",
-	arm_MVN_GE:            "MVN.GE",
-	arm_MVN_LT:            "MVN.LT",
-	arm_MVN_GT:            "MVN.GT",
-	arm_MVN_LE:            "MVN.LE",
-	arm_MVN:               "MVN",
-	arm_MVN_ZZ:            "MVN.ZZ",
-	arm_MVN_S_EQ:          "MVN.S.EQ",
-	arm_MVN_S_NE:          "MVN.S.NE",
-	arm_MVN_S_CS:          "MVN.S.CS",
-	arm_MVN_S_CC:          "MVN.S.CC",
-	arm_MVN_S_MI:          "MVN.S.MI",
-	arm_MVN_S_PL:          "MVN.S.PL",
-	arm_MVN_S_VS:          "MVN.S.VS",
-	arm_MVN_S_VC:          "MVN.S.VC",
-	arm_MVN_S_HI:          "MVN.S.HI",
-	arm_MVN_S_LS:          "MVN.S.LS",
-	arm_MVN_S_GE:          "MVN.S.GE",
-	arm_MVN_S_LT:          "MVN.S.LT",
-	arm_MVN_S_GT:          "MVN.S.GT",
-	arm_MVN_S_LE:          "MVN.S.LE",
-	arm_MVN_S:             "MVN.S",
-	arm_MVN_S_ZZ:          "MVN.S.ZZ",
-	arm_NOP_EQ:            "NOP.EQ",
-	arm_NOP_NE:            "NOP.NE",
-	arm_NOP_CS:            "NOP.CS",
-	arm_NOP_CC:            "NOP.CC",
-	arm_NOP_MI:            "NOP.MI",
-	arm_NOP_PL:            "NOP.PL",
-	arm_NOP_VS:            "NOP.VS",
-	arm_NOP_VC:            "NOP.VC",
-	arm_NOP_HI:            "NOP.HI",
-	arm_NOP_LS:            "NOP.LS",
-	arm_NOP_GE:            "NOP.GE",
-	arm_NOP_LT:            "NOP.LT",
-	arm_NOP_GT:            "NOP.GT",
-	arm_NOP_LE:            "NOP.LE",
-	arm_NOP:               "NOP",
-	arm_NOP_ZZ:            "NOP.ZZ",
-	arm_ORR_EQ:            "ORR.EQ",
-	arm_ORR_NE:            "ORR.NE",
-	arm_ORR_CS:            "ORR.CS",
-	arm_ORR_CC:            "ORR.CC",
-	arm_ORR_MI:            "ORR.MI",
-	arm_ORR_PL:            "ORR.PL",
-	arm_ORR_VS:            "ORR.VS",
-	arm_ORR_VC:            "ORR.VC",
-	arm_ORR_HI:            "ORR.HI",
-	arm_ORR_LS:            "ORR.LS",
-	arm_ORR_GE:            "ORR.GE",
-	arm_ORR_LT:            "ORR.LT",
-	arm_ORR_GT:            "ORR.GT",
-	arm_ORR_LE:            "ORR.LE",
-	arm_ORR:               "ORR",
-	arm_ORR_ZZ:            "ORR.ZZ",
-	arm_ORR_S_EQ:          "ORR.S.EQ",
-	arm_ORR_S_NE:          "ORR.S.NE",
-	arm_ORR_S_CS:          "ORR.S.CS",
-	arm_ORR_S_CC:          "ORR.S.CC",
-	arm_ORR_S_MI:          "ORR.S.MI",
-	arm_ORR_S_PL:          "ORR.S.PL",
-	arm_ORR_S_VS:          "ORR.S.VS",
-	arm_ORR_S_VC:          "ORR.S.VC",
-	arm_ORR_S_HI:          "ORR.S.HI",
-	arm_ORR_S_LS:          "ORR.S.LS",
-	arm_ORR_S_GE:          "ORR.S.GE",
-	arm_ORR_S_LT:          "ORR.S.LT",
-	arm_ORR_S_GT:          "ORR.S.GT",
-	arm_ORR_S_LE:          "ORR.S.LE",
-	arm_ORR_S:             "ORR.S",
-	arm_ORR_S_ZZ:          "ORR.S.ZZ",
-	arm_PKHBT_EQ:          "PKHBT.EQ",
-	arm_PKHBT_NE:          "PKHBT.NE",
-	arm_PKHBT_CS:          "PKHBT.CS",
-	arm_PKHBT_CC:          "PKHBT.CC",
-	arm_PKHBT_MI:          "PKHBT.MI",
-	arm_PKHBT_PL:          "PKHBT.PL",
-	arm_PKHBT_VS:          "PKHBT.VS",
-	arm_PKHBT_VC:          "PKHBT.VC",
-	arm_PKHBT_HI:          "PKHBT.HI",
-	arm_PKHBT_LS:          "PKHBT.LS",
-	arm_PKHBT_GE:          "PKHBT.GE",
-	arm_PKHBT_LT:          "PKHBT.LT",
-	arm_PKHBT_GT:          "PKHBT.GT",
-	arm_PKHBT_LE:          "PKHBT.LE",
-	arm_PKHBT:             "PKHBT",
-	arm_PKHBT_ZZ:          "PKHBT.ZZ",
-	arm_PKHTB_EQ:          "PKHTB.EQ",
-	arm_PKHTB_NE:          "PKHTB.NE",
-	arm_PKHTB_CS:          "PKHTB.CS",
-	arm_PKHTB_CC:          "PKHTB.CC",
-	arm_PKHTB_MI:          "PKHTB.MI",
-	arm_PKHTB_PL:          "PKHTB.PL",
-	arm_PKHTB_VS:          "PKHTB.VS",
-	arm_PKHTB_VC:          "PKHTB.VC",
-	arm_PKHTB_HI:          "PKHTB.HI",
-	arm_PKHTB_LS:          "PKHTB.LS",
-	arm_PKHTB_GE:          "PKHTB.GE",
-	arm_PKHTB_LT:          "PKHTB.LT",
-	arm_PKHTB_GT:          "PKHTB.GT",
-	arm_PKHTB_LE:          "PKHTB.LE",
-	arm_PKHTB:             "PKHTB",
-	arm_PKHTB_ZZ:          "PKHTB.ZZ",
-	arm_PLD_W:             "PLD.W",
-	arm_PLD:               "PLD",
-	arm_PLI:               "PLI",
-	arm_POP_EQ:            "POP.EQ",
-	arm_POP_NE:            "POP.NE",
-	arm_POP_CS:            "POP.CS",
-	arm_POP_CC:            "POP.CC",
-	arm_POP_MI:            "POP.MI",
-	arm_POP_PL:            "POP.PL",
-	arm_POP_VS:            "POP.VS",
-	arm_POP_VC:            "POP.VC",
-	arm_POP_HI:            "POP.HI",
-	arm_POP_LS:            "POP.LS",
-	arm_POP_GE:            "POP.GE",
-	arm_POP_LT:            "POP.LT",
-	arm_POP_GT:            "POP.GT",
-	arm_POP_LE:            "POP.LE",
-	arm_POP:               "POP",
-	arm_POP_ZZ:            "POP.ZZ",
-	arm_PUSH_EQ:           "PUSH.EQ",
-	arm_PUSH_NE:           "PUSH.NE",
-	arm_PUSH_CS:           "PUSH.CS",
-	arm_PUSH_CC:           "PUSH.CC",
-	arm_PUSH_MI:           "PUSH.MI",
-	arm_PUSH_PL:           "PUSH.PL",
-	arm_PUSH_VS:           "PUSH.VS",
-	arm_PUSH_VC:           "PUSH.VC",
-	arm_PUSH_HI:           "PUSH.HI",
-	arm_PUSH_LS:           "PUSH.LS",
-	arm_PUSH_GE:           "PUSH.GE",
-	arm_PUSH_LT:           "PUSH.LT",
-	arm_PUSH_GT:           "PUSH.GT",
-	arm_PUSH_LE:           "PUSH.LE",
-	arm_PUSH:              "PUSH",
-	arm_PUSH_ZZ:           "PUSH.ZZ",
-	arm_QADD_EQ:           "QADD.EQ",
-	arm_QADD_NE:           "QADD.NE",
-	arm_QADD_CS:           "QADD.CS",
-	arm_QADD_CC:           "QADD.CC",
-	arm_QADD_MI:           "QADD.MI",
-	arm_QADD_PL:           "QADD.PL",
-	arm_QADD_VS:           "QADD.VS",
-	arm_QADD_VC:           "QADD.VC",
-	arm_QADD_HI:           "QADD.HI",
-	arm_QADD_LS:           "QADD.LS",
-	arm_QADD_GE:           "QADD.GE",
-	arm_QADD_LT:           "QADD.LT",
-	arm_QADD_GT:           "QADD.GT",
-	arm_QADD_LE:           "QADD.LE",
-	arm_QADD:              "QADD",
-	arm_QADD_ZZ:           "QADD.ZZ",
-	arm_QADD16_EQ:         "QADD16.EQ",
-	arm_QADD16_NE:         "QADD16.NE",
-	arm_QADD16_CS:         "QADD16.CS",
-	arm_QADD16_CC:         "QADD16.CC",
-	arm_QADD16_MI:         "QADD16.MI",
-	arm_QADD16_PL:         "QADD16.PL",
-	arm_QADD16_VS:         "QADD16.VS",
-	arm_QADD16_VC:         "QADD16.VC",
-	arm_QADD16_HI:         "QADD16.HI",
-	arm_QADD16_LS:         "QADD16.LS",
-	arm_QADD16_GE:         "QADD16.GE",
-	arm_QADD16_LT:         "QADD16.LT",
-	arm_QADD16_GT:         "QADD16.GT",
-	arm_QADD16_LE:         "QADD16.LE",
-	arm_QADD16:            "QADD16",
-	arm_QADD16_ZZ:         "QADD16.ZZ",
-	arm_QADD8_EQ:          "QADD8.EQ",
-	arm_QADD8_NE:          "QADD8.NE",
-	arm_QADD8_CS:          "QADD8.CS",
-	arm_QADD8_CC:          "QADD8.CC",
-	arm_QADD8_MI:          "QADD8.MI",
-	arm_QADD8_PL:          "QADD8.PL",
-	arm_QADD8_VS:          "QADD8.VS",
-	arm_QADD8_VC:          "QADD8.VC",
-	arm_QADD8_HI:          "QADD8.HI",
-	arm_QADD8_LS:          "QADD8.LS",
-	arm_QADD8_GE:          "QADD8.GE",
-	arm_QADD8_LT:          "QADD8.LT",
-	arm_QADD8_GT:          "QADD8.GT",
-	arm_QADD8_LE:          "QADD8.LE",
-	arm_QADD8:             "QADD8",
-	arm_QADD8_ZZ:          "QADD8.ZZ",
-	arm_QASX_EQ:           "QASX.EQ",
-	arm_QASX_NE:           "QASX.NE",
-	arm_QASX_CS:           "QASX.CS",
-	arm_QASX_CC:           "QASX.CC",
-	arm_QASX_MI:           "QASX.MI",
-	arm_QASX_PL:           "QASX.PL",
-	arm_QASX_VS:           "QASX.VS",
-	arm_QASX_VC:           "QASX.VC",
-	arm_QASX_HI:           "QASX.HI",
-	arm_QASX_LS:           "QASX.LS",
-	arm_QASX_GE:           "QASX.GE",
-	arm_QASX_LT:           "QASX.LT",
-	arm_QASX_GT:           "QASX.GT",
-	arm_QASX_LE:           "QASX.LE",
-	arm_QASX:              "QASX",
-	arm_QASX_ZZ:           "QASX.ZZ",
-	arm_QDADD_EQ:          "QDADD.EQ",
-	arm_QDADD_NE:          "QDADD.NE",
-	arm_QDADD_CS:          "QDADD.CS",
-	arm_QDADD_CC:          "QDADD.CC",
-	arm_QDADD_MI:          "QDADD.MI",
-	arm_QDADD_PL:          "QDADD.PL",
-	arm_QDADD_VS:          "QDADD.VS",
-	arm_QDADD_VC:          "QDADD.VC",
-	arm_QDADD_HI:          "QDADD.HI",
-	arm_QDADD_LS:          "QDADD.LS",
-	arm_QDADD_GE:          "QDADD.GE",
-	arm_QDADD_LT:          "QDADD.LT",
-	arm_QDADD_GT:          "QDADD.GT",
-	arm_QDADD_LE:          "QDADD.LE",
-	arm_QDADD:             "QDADD",
-	arm_QDADD_ZZ:          "QDADD.ZZ",
-	arm_QDSUB_EQ:          "QDSUB.EQ",
-	arm_QDSUB_NE:          "QDSUB.NE",
-	arm_QDSUB_CS:          "QDSUB.CS",
-	arm_QDSUB_CC:          "QDSUB.CC",
-	arm_QDSUB_MI:          "QDSUB.MI",
-	arm_QDSUB_PL:          "QDSUB.PL",
-	arm_QDSUB_VS:          "QDSUB.VS",
-	arm_QDSUB_VC:          "QDSUB.VC",
-	arm_QDSUB_HI:          "QDSUB.HI",
-	arm_QDSUB_LS:          "QDSUB.LS",
-	arm_QDSUB_GE:          "QDSUB.GE",
-	arm_QDSUB_LT:          "QDSUB.LT",
-	arm_QDSUB_GT:          "QDSUB.GT",
-	arm_QDSUB_LE:          "QDSUB.LE",
-	arm_QDSUB:             "QDSUB",
-	arm_QDSUB_ZZ:          "QDSUB.ZZ",
-	arm_QSAX_EQ:           "QSAX.EQ",
-	arm_QSAX_NE:           "QSAX.NE",
-	arm_QSAX_CS:           "QSAX.CS",
-	arm_QSAX_CC:           "QSAX.CC",
-	arm_QSAX_MI:           "QSAX.MI",
-	arm_QSAX_PL:           "QSAX.PL",
-	arm_QSAX_VS:           "QSAX.VS",
-	arm_QSAX_VC:           "QSAX.VC",
-	arm_QSAX_HI:           "QSAX.HI",
-	arm_QSAX_LS:           "QSAX.LS",
-	arm_QSAX_GE:           "QSAX.GE",
-	arm_QSAX_LT:           "QSAX.LT",
-	arm_QSAX_GT:           "QSAX.GT",
-	arm_QSAX_LE:           "QSAX.LE",
-	arm_QSAX:              "QSAX",
-	arm_QSAX_ZZ:           "QSAX.ZZ",
-	arm_QSUB_EQ:           "QSUB.EQ",
-	arm_QSUB_NE:           "QSUB.NE",
-	arm_QSUB_CS:           "QSUB.CS",
-	arm_QSUB_CC:           "QSUB.CC",
-	arm_QSUB_MI:           "QSUB.MI",
-	arm_QSUB_PL:           "QSUB.PL",
-	arm_QSUB_VS:           "QSUB.VS",
-	arm_QSUB_VC:           "QSUB.VC",
-	arm_QSUB_HI:           "QSUB.HI",
-	arm_QSUB_LS:           "QSUB.LS",
-	arm_QSUB_GE:           "QSUB.GE",
-	arm_QSUB_LT:           "QSUB.LT",
-	arm_QSUB_GT:           "QSUB.GT",
-	arm_QSUB_LE:           "QSUB.LE",
-	arm_QSUB:              "QSUB",
-	arm_QSUB_ZZ:           "QSUB.ZZ",
-	arm_QSUB16_EQ:         "QSUB16.EQ",
-	arm_QSUB16_NE:         "QSUB16.NE",
-	arm_QSUB16_CS:         "QSUB16.CS",
-	arm_QSUB16_CC:         "QSUB16.CC",
-	arm_QSUB16_MI:         "QSUB16.MI",
-	arm_QSUB16_PL:         "QSUB16.PL",
-	arm_QSUB16_VS:         "QSUB16.VS",
-	arm_QSUB16_VC:         "QSUB16.VC",
-	arm_QSUB16_HI:         "QSUB16.HI",
-	arm_QSUB16_LS:         "QSUB16.LS",
-	arm_QSUB16_GE:         "QSUB16.GE",
-	arm_QSUB16_LT:         "QSUB16.LT",
-	arm_QSUB16_GT:         "QSUB16.GT",
-	arm_QSUB16_LE:         "QSUB16.LE",
-	arm_QSUB16:            "QSUB16",
-	arm_QSUB16_ZZ:         "QSUB16.ZZ",
-	arm_QSUB8_EQ:          "QSUB8.EQ",
-	arm_QSUB8_NE:          "QSUB8.NE",
-	arm_QSUB8_CS:          "QSUB8.CS",
-	arm_QSUB8_CC:          "QSUB8.CC",
-	arm_QSUB8_MI:          "QSUB8.MI",
-	arm_QSUB8_PL:          "QSUB8.PL",
-	arm_QSUB8_VS:          "QSUB8.VS",
-	arm_QSUB8_VC:          "QSUB8.VC",
-	arm_QSUB8_HI:          "QSUB8.HI",
-	arm_QSUB8_LS:          "QSUB8.LS",
-	arm_QSUB8_GE:          "QSUB8.GE",
-	arm_QSUB8_LT:          "QSUB8.LT",
-	arm_QSUB8_GT:          "QSUB8.GT",
-	arm_QSUB8_LE:          "QSUB8.LE",
-	arm_QSUB8:             "QSUB8",
-	arm_QSUB8_ZZ:          "QSUB8.ZZ",
-	arm_RBIT_EQ:           "RBIT.EQ",
-	arm_RBIT_NE:           "RBIT.NE",
-	arm_RBIT_CS:           "RBIT.CS",
-	arm_RBIT_CC:           "RBIT.CC",
-	arm_RBIT_MI:           "RBIT.MI",
-	arm_RBIT_PL:           "RBIT.PL",
-	arm_RBIT_VS:           "RBIT.VS",
-	arm_RBIT_VC:           "RBIT.VC",
-	arm_RBIT_HI:           "RBIT.HI",
-	arm_RBIT_LS:           "RBIT.LS",
-	arm_RBIT_GE:           "RBIT.GE",
-	arm_RBIT_LT:           "RBIT.LT",
-	arm_RBIT_GT:           "RBIT.GT",
-	arm_RBIT_LE:           "RBIT.LE",
-	arm_RBIT:              "RBIT",
-	arm_RBIT_ZZ:           "RBIT.ZZ",
-	arm_REV_EQ:            "REV.EQ",
-	arm_REV_NE:            "REV.NE",
-	arm_REV_CS:            "REV.CS",
-	arm_REV_CC:            "REV.CC",
-	arm_REV_MI:            "REV.MI",
-	arm_REV_PL:            "REV.PL",
-	arm_REV_VS:            "REV.VS",
-	arm_REV_VC:            "REV.VC",
-	arm_REV_HI:            "REV.HI",
-	arm_REV_LS:            "REV.LS",
-	arm_REV_GE:            "REV.GE",
-	arm_REV_LT:            "REV.LT",
-	arm_REV_GT:            "REV.GT",
-	arm_REV_LE:            "REV.LE",
-	arm_REV:               "REV",
-	arm_REV_ZZ:            "REV.ZZ",
-	arm_REV16_EQ:          "REV16.EQ",
-	arm_REV16_NE:          "REV16.NE",
-	arm_REV16_CS:          "REV16.CS",
-	arm_REV16_CC:          "REV16.CC",
-	arm_REV16_MI:          "REV16.MI",
-	arm_REV16_PL:          "REV16.PL",
-	arm_REV16_VS:          "REV16.VS",
-	arm_REV16_VC:          "REV16.VC",
-	arm_REV16_HI:          "REV16.HI",
-	arm_REV16_LS:          "REV16.LS",
-	arm_REV16_GE:          "REV16.GE",
-	arm_REV16_LT:          "REV16.LT",
-	arm_REV16_GT:          "REV16.GT",
-	arm_REV16_LE:          "REV16.LE",
-	arm_REV16:             "REV16",
-	arm_REV16_ZZ:          "REV16.ZZ",
-	arm_REVSH_EQ:          "REVSH.EQ",
-	arm_REVSH_NE:          "REVSH.NE",
-	arm_REVSH_CS:          "REVSH.CS",
-	arm_REVSH_CC:          "REVSH.CC",
-	arm_REVSH_MI:          "REVSH.MI",
-	arm_REVSH_PL:          "REVSH.PL",
-	arm_REVSH_VS:          "REVSH.VS",
-	arm_REVSH_VC:          "REVSH.VC",
-	arm_REVSH_HI:          "REVSH.HI",
-	arm_REVSH_LS:          "REVSH.LS",
-	arm_REVSH_GE:          "REVSH.GE",
-	arm_REVSH_LT:          "REVSH.LT",
-	arm_REVSH_GT:          "REVSH.GT",
-	arm_REVSH_LE:          "REVSH.LE",
-	arm_REVSH:             "REVSH",
-	arm_REVSH_ZZ:          "REVSH.ZZ",
-	arm_ROR_EQ:            "ROR.EQ",
-	arm_ROR_NE:            "ROR.NE",
-	arm_ROR_CS:            "ROR.CS",
-	arm_ROR_CC:            "ROR.CC",
-	arm_ROR_MI:            "ROR.MI",
-	arm_ROR_PL:            "ROR.PL",
-	arm_ROR_VS:            "ROR.VS",
-	arm_ROR_VC:            "ROR.VC",
-	arm_ROR_HI:            "ROR.HI",
-	arm_ROR_LS:            "ROR.LS",
-	arm_ROR_GE:            "ROR.GE",
-	arm_ROR_LT:            "ROR.LT",
-	arm_ROR_GT:            "ROR.GT",
-	arm_ROR_LE:            "ROR.LE",
-	arm_ROR:               "ROR",
-	arm_ROR_ZZ:            "ROR.ZZ",
-	arm_ROR_S_EQ:          "ROR.S.EQ",
-	arm_ROR_S_NE:          "ROR.S.NE",
-	arm_ROR_S_CS:          "ROR.S.CS",
-	arm_ROR_S_CC:          "ROR.S.CC",
-	arm_ROR_S_MI:          "ROR.S.MI",
-	arm_ROR_S_PL:          "ROR.S.PL",
-	arm_ROR_S_VS:          "ROR.S.VS",
-	arm_ROR_S_VC:          "ROR.S.VC",
-	arm_ROR_S_HI:          "ROR.S.HI",
-	arm_ROR_S_LS:          "ROR.S.LS",
-	arm_ROR_S_GE:          "ROR.S.GE",
-	arm_ROR_S_LT:          "ROR.S.LT",
-	arm_ROR_S_GT:          "ROR.S.GT",
-	arm_ROR_S_LE:          "ROR.S.LE",
-	arm_ROR_S:             "ROR.S",
-	arm_ROR_S_ZZ:          "ROR.S.ZZ",
-	arm_RRX_EQ:            "RRX.EQ",
-	arm_RRX_NE:            "RRX.NE",
-	arm_RRX_CS:            "RRX.CS",
-	arm_RRX_CC:            "RRX.CC",
-	arm_RRX_MI:            "RRX.MI",
-	arm_RRX_PL:            "RRX.PL",
-	arm_RRX_VS:            "RRX.VS",
-	arm_RRX_VC:            "RRX.VC",
-	arm_RRX_HI:            "RRX.HI",
-	arm_RRX_LS:            "RRX.LS",
-	arm_RRX_GE:            "RRX.GE",
-	arm_RRX_LT:            "RRX.LT",
-	arm_RRX_GT:            "RRX.GT",
-	arm_RRX_LE:            "RRX.LE",
-	arm_RRX:               "RRX",
-	arm_RRX_ZZ:            "RRX.ZZ",
-	arm_RRX_S_EQ:          "RRX.S.EQ",
-	arm_RRX_S_NE:          "RRX.S.NE",
-	arm_RRX_S_CS:          "RRX.S.CS",
-	arm_RRX_S_CC:          "RRX.S.CC",
-	arm_RRX_S_MI:          "RRX.S.MI",
-	arm_RRX_S_PL:          "RRX.S.PL",
-	arm_RRX_S_VS:          "RRX.S.VS",
-	arm_RRX_S_VC:          "RRX.S.VC",
-	arm_RRX_S_HI:          "RRX.S.HI",
-	arm_RRX_S_LS:          "RRX.S.LS",
-	arm_RRX_S_GE:          "RRX.S.GE",
-	arm_RRX_S_LT:          "RRX.S.LT",
-	arm_RRX_S_GT:          "RRX.S.GT",
-	arm_RRX_S_LE:          "RRX.S.LE",
-	arm_RRX_S:             "RRX.S",
-	arm_RRX_S_ZZ:          "RRX.S.ZZ",
-	arm_RSB_EQ:            "RSB.EQ",
-	arm_RSB_NE:            "RSB.NE",
-	arm_RSB_CS:            "RSB.CS",
-	arm_RSB_CC:            "RSB.CC",
-	arm_RSB_MI:            "RSB.MI",
-	arm_RSB_PL:            "RSB.PL",
-	arm_RSB_VS:            "RSB.VS",
-	arm_RSB_VC:            "RSB.VC",
-	arm_RSB_HI:            "RSB.HI",
-	arm_RSB_LS:            "RSB.LS",
-	arm_RSB_GE:            "RSB.GE",
-	arm_RSB_LT:            "RSB.LT",
-	arm_RSB_GT:            "RSB.GT",
-	arm_RSB_LE:            "RSB.LE",
-	arm_RSB:               "RSB",
-	arm_RSB_ZZ:            "RSB.ZZ",
-	arm_RSB_S_EQ:          "RSB.S.EQ",
-	arm_RSB_S_NE:          "RSB.S.NE",
-	arm_RSB_S_CS:          "RSB.S.CS",
-	arm_RSB_S_CC:          "RSB.S.CC",
-	arm_RSB_S_MI:          "RSB.S.MI",
-	arm_RSB_S_PL:          "RSB.S.PL",
-	arm_RSB_S_VS:          "RSB.S.VS",
-	arm_RSB_S_VC:          "RSB.S.VC",
-	arm_RSB_S_HI:          "RSB.S.HI",
-	arm_RSB_S_LS:          "RSB.S.LS",
-	arm_RSB_S_GE:          "RSB.S.GE",
-	arm_RSB_S_LT:          "RSB.S.LT",
-	arm_RSB_S_GT:          "RSB.S.GT",
-	arm_RSB_S_LE:          "RSB.S.LE",
-	arm_RSB_S:             "RSB.S",
-	arm_RSB_S_ZZ:          "RSB.S.ZZ",
-	arm_RSC_EQ:            "RSC.EQ",
-	arm_RSC_NE:            "RSC.NE",
-	arm_RSC_CS:            "RSC.CS",
-	arm_RSC_CC:            "RSC.CC",
-	arm_RSC_MI:            "RSC.MI",
-	arm_RSC_PL:            "RSC.PL",
-	arm_RSC_VS:            "RSC.VS",
-	arm_RSC_VC:            "RSC.VC",
-	arm_RSC_HI:            "RSC.HI",
-	arm_RSC_LS:            "RSC.LS",
-	arm_RSC_GE:            "RSC.GE",
-	arm_RSC_LT:            "RSC.LT",
-	arm_RSC_GT:            "RSC.GT",
-	arm_RSC_LE:            "RSC.LE",
-	arm_RSC:               "RSC",
-	arm_RSC_ZZ:            "RSC.ZZ",
-	arm_RSC_S_EQ:          "RSC.S.EQ",
-	arm_RSC_S_NE:          "RSC.S.NE",
-	arm_RSC_S_CS:          "RSC.S.CS",
-	arm_RSC_S_CC:          "RSC.S.CC",
-	arm_RSC_S_MI:          "RSC.S.MI",
-	arm_RSC_S_PL:          "RSC.S.PL",
-	arm_RSC_S_VS:          "RSC.S.VS",
-	arm_RSC_S_VC:          "RSC.S.VC",
-	arm_RSC_S_HI:          "RSC.S.HI",
-	arm_RSC_S_LS:          "RSC.S.LS",
-	arm_RSC_S_GE:          "RSC.S.GE",
-	arm_RSC_S_LT:          "RSC.S.LT",
-	arm_RSC_S_GT:          "RSC.S.GT",
-	arm_RSC_S_LE:          "RSC.S.LE",
-	arm_RSC_S:             "RSC.S",
-	arm_RSC_S_ZZ:          "RSC.S.ZZ",
-	arm_SADD16_EQ:         "SADD16.EQ",
-	arm_SADD16_NE:         "SADD16.NE",
-	arm_SADD16_CS:         "SADD16.CS",
-	arm_SADD16_CC:         "SADD16.CC",
-	arm_SADD16_MI:         "SADD16.MI",
-	arm_SADD16_PL:         "SADD16.PL",
-	arm_SADD16_VS:         "SADD16.VS",
-	arm_SADD16_VC:         "SADD16.VC",
-	arm_SADD16_HI:         "SADD16.HI",
-	arm_SADD16_LS:         "SADD16.LS",
-	arm_SADD16_GE:         "SADD16.GE",
-	arm_SADD16_LT:         "SADD16.LT",
-	arm_SADD16_GT:         "SADD16.GT",
-	arm_SADD16_LE:         "SADD16.LE",
-	arm_SADD16:            "SADD16",
-	arm_SADD16_ZZ:         "SADD16.ZZ",
-	arm_SADD8_EQ:          "SADD8.EQ",
-	arm_SADD8_NE:          "SADD8.NE",
-	arm_SADD8_CS:          "SADD8.CS",
-	arm_SADD8_CC:          "SADD8.CC",
-	arm_SADD8_MI:          "SADD8.MI",
-	arm_SADD8_PL:          "SADD8.PL",
-	arm_SADD8_VS:          "SADD8.VS",
-	arm_SADD8_VC:          "SADD8.VC",
-	arm_SADD8_HI:          "SADD8.HI",
-	arm_SADD8_LS:          "SADD8.LS",
-	arm_SADD8_GE:          "SADD8.GE",
-	arm_SADD8_LT:          "SADD8.LT",
-	arm_SADD8_GT:          "SADD8.GT",
-	arm_SADD8_LE:          "SADD8.LE",
-	arm_SADD8:             "SADD8",
-	arm_SADD8_ZZ:          "SADD8.ZZ",
-	arm_SASX_EQ:           "SASX.EQ",
-	arm_SASX_NE:           "SASX.NE",
-	arm_SASX_CS:           "SASX.CS",
-	arm_SASX_CC:           "SASX.CC",
-	arm_SASX_MI:           "SASX.MI",
-	arm_SASX_PL:           "SASX.PL",
-	arm_SASX_VS:           "SASX.VS",
-	arm_SASX_VC:           "SASX.VC",
-	arm_SASX_HI:           "SASX.HI",
-	arm_SASX_LS:           "SASX.LS",
-	arm_SASX_GE:           "SASX.GE",
-	arm_SASX_LT:           "SASX.LT",
-	arm_SASX_GT:           "SASX.GT",
-	arm_SASX_LE:           "SASX.LE",
-	arm_SASX:              "SASX",
-	arm_SASX_ZZ:           "SASX.ZZ",
-	arm_SBC_EQ:            "SBC.EQ",
-	arm_SBC_NE:            "SBC.NE",
-	arm_SBC_CS:            "SBC.CS",
-	arm_SBC_CC:            "SBC.CC",
-	arm_SBC_MI:            "SBC.MI",
-	arm_SBC_PL:            "SBC.PL",
-	arm_SBC_VS:            "SBC.VS",
-	arm_SBC_VC:            "SBC.VC",
-	arm_SBC_HI:            "SBC.HI",
-	arm_SBC_LS:            "SBC.LS",
-	arm_SBC_GE:            "SBC.GE",
-	arm_SBC_LT:            "SBC.LT",
-	arm_SBC_GT:            "SBC.GT",
-	arm_SBC_LE:            "SBC.LE",
-	arm_SBC:               "SBC",
-	arm_SBC_ZZ:            "SBC.ZZ",
-	arm_SBC_S_EQ:          "SBC.S.EQ",
-	arm_SBC_S_NE:          "SBC.S.NE",
-	arm_SBC_S_CS:          "SBC.S.CS",
-	arm_SBC_S_CC:          "SBC.S.CC",
-	arm_SBC_S_MI:          "SBC.S.MI",
-	arm_SBC_S_PL:          "SBC.S.PL",
-	arm_SBC_S_VS:          "SBC.S.VS",
-	arm_SBC_S_VC:          "SBC.S.VC",
-	arm_SBC_S_HI:          "SBC.S.HI",
-	arm_SBC_S_LS:          "SBC.S.LS",
-	arm_SBC_S_GE:          "SBC.S.GE",
-	arm_SBC_S_LT:          "SBC.S.LT",
-	arm_SBC_S_GT:          "SBC.S.GT",
-	arm_SBC_S_LE:          "SBC.S.LE",
-	arm_SBC_S:             "SBC.S",
-	arm_SBC_S_ZZ:          "SBC.S.ZZ",
-	arm_SBFX_EQ:           "SBFX.EQ",
-	arm_SBFX_NE:           "SBFX.NE",
-	arm_SBFX_CS:           "SBFX.CS",
-	arm_SBFX_CC:           "SBFX.CC",
-	arm_SBFX_MI:           "SBFX.MI",
-	arm_SBFX_PL:           "SBFX.PL",
-	arm_SBFX_VS:           "SBFX.VS",
-	arm_SBFX_VC:           "SBFX.VC",
-	arm_SBFX_HI:           "SBFX.HI",
-	arm_SBFX_LS:           "SBFX.LS",
-	arm_SBFX_GE:           "SBFX.GE",
-	arm_SBFX_LT:           "SBFX.LT",
-	arm_SBFX_GT:           "SBFX.GT",
-	arm_SBFX_LE:           "SBFX.LE",
-	arm_SBFX:              "SBFX",
-	arm_SBFX_ZZ:           "SBFX.ZZ",
-	arm_SEL_EQ:            "SEL.EQ",
-	arm_SEL_NE:            "SEL.NE",
-	arm_SEL_CS:            "SEL.CS",
-	arm_SEL_CC:            "SEL.CC",
-	arm_SEL_MI:            "SEL.MI",
-	arm_SEL_PL:            "SEL.PL",
-	arm_SEL_VS:            "SEL.VS",
-	arm_SEL_VC:            "SEL.VC",
-	arm_SEL_HI:            "SEL.HI",
-	arm_SEL_LS:            "SEL.LS",
-	arm_SEL_GE:            "SEL.GE",
-	arm_SEL_LT:            "SEL.LT",
-	arm_SEL_GT:            "SEL.GT",
-	arm_SEL_LE:            "SEL.LE",
-	arm_SEL:               "SEL",
-	arm_SEL_ZZ:            "SEL.ZZ",
-	arm_SETEND:            "SETEND",
-	arm_SEV_EQ:            "SEV.EQ",
-	arm_SEV_NE:            "SEV.NE",
-	arm_SEV_CS:            "SEV.CS",
-	arm_SEV_CC:            "SEV.CC",
-	arm_SEV_MI:            "SEV.MI",
-	arm_SEV_PL:            "SEV.PL",
-	arm_SEV_VS:            "SEV.VS",
-	arm_SEV_VC:            "SEV.VC",
-	arm_SEV_HI:            "SEV.HI",
-	arm_SEV_LS:            "SEV.LS",
-	arm_SEV_GE:            "SEV.GE",
-	arm_SEV_LT:            "SEV.LT",
-	arm_SEV_GT:            "SEV.GT",
-	arm_SEV_LE:            "SEV.LE",
-	arm_SEV:               "SEV",
-	arm_SEV_ZZ:            "SEV.ZZ",
-	arm_SHADD16_EQ:        "SHADD16.EQ",
-	arm_SHADD16_NE:        "SHADD16.NE",
-	arm_SHADD16_CS:        "SHADD16.CS",
-	arm_SHADD16_CC:        "SHADD16.CC",
-	arm_SHADD16_MI:        "SHADD16.MI",
-	arm_SHADD16_PL:        "SHADD16.PL",
-	arm_SHADD16_VS:        "SHADD16.VS",
-	arm_SHADD16_VC:        "SHADD16.VC",
-	arm_SHADD16_HI:        "SHADD16.HI",
-	arm_SHADD16_LS:        "SHADD16.LS",
-	arm_SHADD16_GE:        "SHADD16.GE",
-	arm_SHADD16_LT:        "SHADD16.LT",
-	arm_SHADD16_GT:        "SHADD16.GT",
-	arm_SHADD16_LE:        "SHADD16.LE",
-	arm_SHADD16:           "SHADD16",
-	arm_SHADD16_ZZ:        "SHADD16.ZZ",
-	arm_SHADD8_EQ:         "SHADD8.EQ",
-	arm_SHADD8_NE:         "SHADD8.NE",
-	arm_SHADD8_CS:         "SHADD8.CS",
-	arm_SHADD8_CC:         "SHADD8.CC",
-	arm_SHADD8_MI:         "SHADD8.MI",
-	arm_SHADD8_PL:         "SHADD8.PL",
-	arm_SHADD8_VS:         "SHADD8.VS",
-	arm_SHADD8_VC:         "SHADD8.VC",
-	arm_SHADD8_HI:         "SHADD8.HI",
-	arm_SHADD8_LS:         "SHADD8.LS",
-	arm_SHADD8_GE:         "SHADD8.GE",
-	arm_SHADD8_LT:         "SHADD8.LT",
-	arm_SHADD8_GT:         "SHADD8.GT",
-	arm_SHADD8_LE:         "SHADD8.LE",
-	arm_SHADD8:            "SHADD8",
-	arm_SHADD8_ZZ:         "SHADD8.ZZ",
-	arm_SHASX_EQ:          "SHASX.EQ",
-	arm_SHASX_NE:          "SHASX.NE",
-	arm_SHASX_CS:          "SHASX.CS",
-	arm_SHASX_CC:          "SHASX.CC",
-	arm_SHASX_MI:          "SHASX.MI",
-	arm_SHASX_PL:          "SHASX.PL",
-	arm_SHASX_VS:          "SHASX.VS",
-	arm_SHASX_VC:          "SHASX.VC",
-	arm_SHASX_HI:          "SHASX.HI",
-	arm_SHASX_LS:          "SHASX.LS",
-	arm_SHASX_GE:          "SHASX.GE",
-	arm_SHASX_LT:          "SHASX.LT",
-	arm_SHASX_GT:          "SHASX.GT",
-	arm_SHASX_LE:          "SHASX.LE",
-	arm_SHASX:             "SHASX",
-	arm_SHASX_ZZ:          "SHASX.ZZ",
-	arm_SHSAX_EQ:          "SHSAX.EQ",
-	arm_SHSAX_NE:          "SHSAX.NE",
-	arm_SHSAX_CS:          "SHSAX.CS",
-	arm_SHSAX_CC:          "SHSAX.CC",
-	arm_SHSAX_MI:          "SHSAX.MI",
-	arm_SHSAX_PL:          "SHSAX.PL",
-	arm_SHSAX_VS:          "SHSAX.VS",
-	arm_SHSAX_VC:          "SHSAX.VC",
-	arm_SHSAX_HI:          "SHSAX.HI",
-	arm_SHSAX_LS:          "SHSAX.LS",
-	arm_SHSAX_GE:          "SHSAX.GE",
-	arm_SHSAX_LT:          "SHSAX.LT",
-	arm_SHSAX_GT:          "SHSAX.GT",
-	arm_SHSAX_LE:          "SHSAX.LE",
-	arm_SHSAX:             "SHSAX",
-	arm_SHSAX_ZZ:          "SHSAX.ZZ",
-	arm_SHSUB16_EQ:        "SHSUB16.EQ",
-	arm_SHSUB16_NE:        "SHSUB16.NE",
-	arm_SHSUB16_CS:        "SHSUB16.CS",
-	arm_SHSUB16_CC:        "SHSUB16.CC",
-	arm_SHSUB16_MI:        "SHSUB16.MI",
-	arm_SHSUB16_PL:        "SHSUB16.PL",
-	arm_SHSUB16_VS:        "SHSUB16.VS",
-	arm_SHSUB16_VC:        "SHSUB16.VC",
-	arm_SHSUB16_HI:        "SHSUB16.HI",
-	arm_SHSUB16_LS:        "SHSUB16.LS",
-	arm_SHSUB16_GE:        "SHSUB16.GE",
-	arm_SHSUB16_LT:        "SHSUB16.LT",
-	arm_SHSUB16_GT:        "SHSUB16.GT",
-	arm_SHSUB16_LE:        "SHSUB16.LE",
-	arm_SHSUB16:           "SHSUB16",
-	arm_SHSUB16_ZZ:        "SHSUB16.ZZ",
-	arm_SHSUB8_EQ:         "SHSUB8.EQ",
-	arm_SHSUB8_NE:         "SHSUB8.NE",
-	arm_SHSUB8_CS:         "SHSUB8.CS",
-	arm_SHSUB8_CC:         "SHSUB8.CC",
-	arm_SHSUB8_MI:         "SHSUB8.MI",
-	arm_SHSUB8_PL:         "SHSUB8.PL",
-	arm_SHSUB8_VS:         "SHSUB8.VS",
-	arm_SHSUB8_VC:         "SHSUB8.VC",
-	arm_SHSUB8_HI:         "SHSUB8.HI",
-	arm_SHSUB8_LS:         "SHSUB8.LS",
-	arm_SHSUB8_GE:         "SHSUB8.GE",
-	arm_SHSUB8_LT:         "SHSUB8.LT",
-	arm_SHSUB8_GT:         "SHSUB8.GT",
-	arm_SHSUB8_LE:         "SHSUB8.LE",
-	arm_SHSUB8:            "SHSUB8",
-	arm_SHSUB8_ZZ:         "SHSUB8.ZZ",
-	arm_SMLABB_EQ:         "SMLABB.EQ",
-	arm_SMLABB_NE:         "SMLABB.NE",
-	arm_SMLABB_CS:         "SMLABB.CS",
-	arm_SMLABB_CC:         "SMLABB.CC",
-	arm_SMLABB_MI:         "SMLABB.MI",
-	arm_SMLABB_PL:         "SMLABB.PL",
-	arm_SMLABB_VS:         "SMLABB.VS",
-	arm_SMLABB_VC:         "SMLABB.VC",
-	arm_SMLABB_HI:         "SMLABB.HI",
-	arm_SMLABB_LS:         "SMLABB.LS",
-	arm_SMLABB_GE:         "SMLABB.GE",
-	arm_SMLABB_LT:         "SMLABB.LT",
-	arm_SMLABB_GT:         "SMLABB.GT",
-	arm_SMLABB_LE:         "SMLABB.LE",
-	arm_SMLABB:            "SMLABB",
-	arm_SMLABB_ZZ:         "SMLABB.ZZ",
-	arm_SMLABT_EQ:         "SMLABT.EQ",
-	arm_SMLABT_NE:         "SMLABT.NE",
-	arm_SMLABT_CS:         "SMLABT.CS",
-	arm_SMLABT_CC:         "SMLABT.CC",
-	arm_SMLABT_MI:         "SMLABT.MI",
-	arm_SMLABT_PL:         "SMLABT.PL",
-	arm_SMLABT_VS:         "SMLABT.VS",
-	arm_SMLABT_VC:         "SMLABT.VC",
-	arm_SMLABT_HI:         "SMLABT.HI",
-	arm_SMLABT_LS:         "SMLABT.LS",
-	arm_SMLABT_GE:         "SMLABT.GE",
-	arm_SMLABT_LT:         "SMLABT.LT",
-	arm_SMLABT_GT:         "SMLABT.GT",
-	arm_SMLABT_LE:         "SMLABT.LE",
-	arm_SMLABT:            "SMLABT",
-	arm_SMLABT_ZZ:         "SMLABT.ZZ",
-	arm_SMLATB_EQ:         "SMLATB.EQ",
-	arm_SMLATB_NE:         "SMLATB.NE",
-	arm_SMLATB_CS:         "SMLATB.CS",
-	arm_SMLATB_CC:         "SMLATB.CC",
-	arm_SMLATB_MI:         "SMLATB.MI",
-	arm_SMLATB_PL:         "SMLATB.PL",
-	arm_SMLATB_VS:         "SMLATB.VS",
-	arm_SMLATB_VC:         "SMLATB.VC",
-	arm_SMLATB_HI:         "SMLATB.HI",
-	arm_SMLATB_LS:         "SMLATB.LS",
-	arm_SMLATB_GE:         "SMLATB.GE",
-	arm_SMLATB_LT:         "SMLATB.LT",
-	arm_SMLATB_GT:         "SMLATB.GT",
-	arm_SMLATB_LE:         "SMLATB.LE",
-	arm_SMLATB:            "SMLATB",
-	arm_SMLATB_ZZ:         "SMLATB.ZZ",
-	arm_SMLATT_EQ:         "SMLATT.EQ",
-	arm_SMLATT_NE:         "SMLATT.NE",
-	arm_SMLATT_CS:         "SMLATT.CS",
-	arm_SMLATT_CC:         "SMLATT.CC",
-	arm_SMLATT_MI:         "SMLATT.MI",
-	arm_SMLATT_PL:         "SMLATT.PL",
-	arm_SMLATT_VS:         "SMLATT.VS",
-	arm_SMLATT_VC:         "SMLATT.VC",
-	arm_SMLATT_HI:         "SMLATT.HI",
-	arm_SMLATT_LS:         "SMLATT.LS",
-	arm_SMLATT_GE:         "SMLATT.GE",
-	arm_SMLATT_LT:         "SMLATT.LT",
-	arm_SMLATT_GT:         "SMLATT.GT",
-	arm_SMLATT_LE:         "SMLATT.LE",
-	arm_SMLATT:            "SMLATT",
-	arm_SMLATT_ZZ:         "SMLATT.ZZ",
-	arm_SMLAD_EQ:          "SMLAD.EQ",
-	arm_SMLAD_NE:          "SMLAD.NE",
-	arm_SMLAD_CS:          "SMLAD.CS",
-	arm_SMLAD_CC:          "SMLAD.CC",
-	arm_SMLAD_MI:          "SMLAD.MI",
-	arm_SMLAD_PL:          "SMLAD.PL",
-	arm_SMLAD_VS:          "SMLAD.VS",
-	arm_SMLAD_VC:          "SMLAD.VC",
-	arm_SMLAD_HI:          "SMLAD.HI",
-	arm_SMLAD_LS:          "SMLAD.LS",
-	arm_SMLAD_GE:          "SMLAD.GE",
-	arm_SMLAD_LT:          "SMLAD.LT",
-	arm_SMLAD_GT:          "SMLAD.GT",
-	arm_SMLAD_LE:          "SMLAD.LE",
-	arm_SMLAD:             "SMLAD",
-	arm_SMLAD_ZZ:          "SMLAD.ZZ",
-	arm_SMLAD_X_EQ:        "SMLAD.X.EQ",
-	arm_SMLAD_X_NE:        "SMLAD.X.NE",
-	arm_SMLAD_X_CS:        "SMLAD.X.CS",
-	arm_SMLAD_X_CC:        "SMLAD.X.CC",
-	arm_SMLAD_X_MI:        "SMLAD.X.MI",
-	arm_SMLAD_X_PL:        "SMLAD.X.PL",
-	arm_SMLAD_X_VS:        "SMLAD.X.VS",
-	arm_SMLAD_X_VC:        "SMLAD.X.VC",
-	arm_SMLAD_X_HI:        "SMLAD.X.HI",
-	arm_SMLAD_X_LS:        "SMLAD.X.LS",
-	arm_SMLAD_X_GE:        "SMLAD.X.GE",
-	arm_SMLAD_X_LT:        "SMLAD.X.LT",
-	arm_SMLAD_X_GT:        "SMLAD.X.GT",
-	arm_SMLAD_X_LE:        "SMLAD.X.LE",
-	arm_SMLAD_X:           "SMLAD.X",
-	arm_SMLAD_X_ZZ:        "SMLAD.X.ZZ",
-	arm_SMLAL_EQ:          "SMLAL.EQ",
-	arm_SMLAL_NE:          "SMLAL.NE",
-	arm_SMLAL_CS:          "SMLAL.CS",
-	arm_SMLAL_CC:          "SMLAL.CC",
-	arm_SMLAL_MI:          "SMLAL.MI",
-	arm_SMLAL_PL:          "SMLAL.PL",
-	arm_SMLAL_VS:          "SMLAL.VS",
-	arm_SMLAL_VC:          "SMLAL.VC",
-	arm_SMLAL_HI:          "SMLAL.HI",
-	arm_SMLAL_LS:          "SMLAL.LS",
-	arm_SMLAL_GE:          "SMLAL.GE",
-	arm_SMLAL_LT:          "SMLAL.LT",
-	arm_SMLAL_GT:          "SMLAL.GT",
-	arm_SMLAL_LE:          "SMLAL.LE",
-	arm_SMLAL:             "SMLAL",
-	arm_SMLAL_ZZ:          "SMLAL.ZZ",
-	arm_SMLAL_S_EQ:        "SMLAL.S.EQ",
-	arm_SMLAL_S_NE:        "SMLAL.S.NE",
-	arm_SMLAL_S_CS:        "SMLAL.S.CS",
-	arm_SMLAL_S_CC:        "SMLAL.S.CC",
-	arm_SMLAL_S_MI:        "SMLAL.S.MI",
-	arm_SMLAL_S_PL:        "SMLAL.S.PL",
-	arm_SMLAL_S_VS:        "SMLAL.S.VS",
-	arm_SMLAL_S_VC:        "SMLAL.S.VC",
-	arm_SMLAL_S_HI:        "SMLAL.S.HI",
-	arm_SMLAL_S_LS:        "SMLAL.S.LS",
-	arm_SMLAL_S_GE:        "SMLAL.S.GE",
-	arm_SMLAL_S_LT:        "SMLAL.S.LT",
-	arm_SMLAL_S_GT:        "SMLAL.S.GT",
-	arm_SMLAL_S_LE:        "SMLAL.S.LE",
-	arm_SMLAL_S:           "SMLAL.S",
-	arm_SMLAL_S_ZZ:        "SMLAL.S.ZZ",
-	arm_SMLALBB_EQ:        "SMLALBB.EQ",
-	arm_SMLALBB_NE:        "SMLALBB.NE",
-	arm_SMLALBB_CS:        "SMLALBB.CS",
-	arm_SMLALBB_CC:        "SMLALBB.CC",
-	arm_SMLALBB_MI:        "SMLALBB.MI",
-	arm_SMLALBB_PL:        "SMLALBB.PL",
-	arm_SMLALBB_VS:        "SMLALBB.VS",
-	arm_SMLALBB_VC:        "SMLALBB.VC",
-	arm_SMLALBB_HI:        "SMLALBB.HI",
-	arm_SMLALBB_LS:        "SMLALBB.LS",
-	arm_SMLALBB_GE:        "SMLALBB.GE",
-	arm_SMLALBB_LT:        "SMLALBB.LT",
-	arm_SMLALBB_GT:        "SMLALBB.GT",
-	arm_SMLALBB_LE:        "SMLALBB.LE",
-	arm_SMLALBB:           "SMLALBB",
-	arm_SMLALBB_ZZ:        "SMLALBB.ZZ",
-	arm_SMLALBT_EQ:        "SMLALBT.EQ",
-	arm_SMLALBT_NE:        "SMLALBT.NE",
-	arm_SMLALBT_CS:        "SMLALBT.CS",
-	arm_SMLALBT_CC:        "SMLALBT.CC",
-	arm_SMLALBT_MI:        "SMLALBT.MI",
-	arm_SMLALBT_PL:        "SMLALBT.PL",
-	arm_SMLALBT_VS:        "SMLALBT.VS",
-	arm_SMLALBT_VC:        "SMLALBT.VC",
-	arm_SMLALBT_HI:        "SMLALBT.HI",
-	arm_SMLALBT_LS:        "SMLALBT.LS",
-	arm_SMLALBT_GE:        "SMLALBT.GE",
-	arm_SMLALBT_LT:        "SMLALBT.LT",
-	arm_SMLALBT_GT:        "SMLALBT.GT",
-	arm_SMLALBT_LE:        "SMLALBT.LE",
-	arm_SMLALBT:           "SMLALBT",
-	arm_SMLALBT_ZZ:        "SMLALBT.ZZ",
-	arm_SMLALTB_EQ:        "SMLALTB.EQ",
-	arm_SMLALTB_NE:        "SMLALTB.NE",
-	arm_SMLALTB_CS:        "SMLALTB.CS",
-	arm_SMLALTB_CC:        "SMLALTB.CC",
-	arm_SMLALTB_MI:        "SMLALTB.MI",
-	arm_SMLALTB_PL:        "SMLALTB.PL",
-	arm_SMLALTB_VS:        "SMLALTB.VS",
-	arm_SMLALTB_VC:        "SMLALTB.VC",
-	arm_SMLALTB_HI:        "SMLALTB.HI",
-	arm_SMLALTB_LS:        "SMLALTB.LS",
-	arm_SMLALTB_GE:        "SMLALTB.GE",
-	arm_SMLALTB_LT:        "SMLALTB.LT",
-	arm_SMLALTB_GT:        "SMLALTB.GT",
-	arm_SMLALTB_LE:        "SMLALTB.LE",
-	arm_SMLALTB:           "SMLALTB",
-	arm_SMLALTB_ZZ:        "SMLALTB.ZZ",
-	arm_SMLALTT_EQ:        "SMLALTT.EQ",
-	arm_SMLALTT_NE:        "SMLALTT.NE",
-	arm_SMLALTT_CS:        "SMLALTT.CS",
-	arm_SMLALTT_CC:        "SMLALTT.CC",
-	arm_SMLALTT_MI:        "SMLALTT.MI",
-	arm_SMLALTT_PL:        "SMLALTT.PL",
-	arm_SMLALTT_VS:        "SMLALTT.VS",
-	arm_SMLALTT_VC:        "SMLALTT.VC",
-	arm_SMLALTT_HI:        "SMLALTT.HI",
-	arm_SMLALTT_LS:        "SMLALTT.LS",
-	arm_SMLALTT_GE:        "SMLALTT.GE",
-	arm_SMLALTT_LT:        "SMLALTT.LT",
-	arm_SMLALTT_GT:        "SMLALTT.GT",
-	arm_SMLALTT_LE:        "SMLALTT.LE",
-	arm_SMLALTT:           "SMLALTT",
-	arm_SMLALTT_ZZ:        "SMLALTT.ZZ",
-	arm_SMLALD_EQ:         "SMLALD.EQ",
-	arm_SMLALD_NE:         "SMLALD.NE",
-	arm_SMLALD_CS:         "SMLALD.CS",
-	arm_SMLALD_CC:         "SMLALD.CC",
-	arm_SMLALD_MI:         "SMLALD.MI",
-	arm_SMLALD_PL:         "SMLALD.PL",
-	arm_SMLALD_VS:         "SMLALD.VS",
-	arm_SMLALD_VC:         "SMLALD.VC",
-	arm_SMLALD_HI:         "SMLALD.HI",
-	arm_SMLALD_LS:         "SMLALD.LS",
-	arm_SMLALD_GE:         "SMLALD.GE",
-	arm_SMLALD_LT:         "SMLALD.LT",
-	arm_SMLALD_GT:         "SMLALD.GT",
-	arm_SMLALD_LE:         "SMLALD.LE",
-	arm_SMLALD:            "SMLALD",
-	arm_SMLALD_ZZ:         "SMLALD.ZZ",
-	arm_SMLALD_X_EQ:       "SMLALD.X.EQ",
-	arm_SMLALD_X_NE:       "SMLALD.X.NE",
-	arm_SMLALD_X_CS:       "SMLALD.X.CS",
-	arm_SMLALD_X_CC:       "SMLALD.X.CC",
-	arm_SMLALD_X_MI:       "SMLALD.X.MI",
-	arm_SMLALD_X_PL:       "SMLALD.X.PL",
-	arm_SMLALD_X_VS:       "SMLALD.X.VS",
-	arm_SMLALD_X_VC:       "SMLALD.X.VC",
-	arm_SMLALD_X_HI:       "SMLALD.X.HI",
-	arm_SMLALD_X_LS:       "SMLALD.X.LS",
-	arm_SMLALD_X_GE:       "SMLALD.X.GE",
-	arm_SMLALD_X_LT:       "SMLALD.X.LT",
-	arm_SMLALD_X_GT:       "SMLALD.X.GT",
-	arm_SMLALD_X_LE:       "SMLALD.X.LE",
-	arm_SMLALD_X:          "SMLALD.X",
-	arm_SMLALD_X_ZZ:       "SMLALD.X.ZZ",
-	arm_SMLAWB_EQ:         "SMLAWB.EQ",
-	arm_SMLAWB_NE:         "SMLAWB.NE",
-	arm_SMLAWB_CS:         "SMLAWB.CS",
-	arm_SMLAWB_CC:         "SMLAWB.CC",
-	arm_SMLAWB_MI:         "SMLAWB.MI",
-	arm_SMLAWB_PL:         "SMLAWB.PL",
-	arm_SMLAWB_VS:         "SMLAWB.VS",
-	arm_SMLAWB_VC:         "SMLAWB.VC",
-	arm_SMLAWB_HI:         "SMLAWB.HI",
-	arm_SMLAWB_LS:         "SMLAWB.LS",
-	arm_SMLAWB_GE:         "SMLAWB.GE",
-	arm_SMLAWB_LT:         "SMLAWB.LT",
-	arm_SMLAWB_GT:         "SMLAWB.GT",
-	arm_SMLAWB_LE:         "SMLAWB.LE",
-	arm_SMLAWB:            "SMLAWB",
-	arm_SMLAWB_ZZ:         "SMLAWB.ZZ",
-	arm_SMLAWT_EQ:         "SMLAWT.EQ",
-	arm_SMLAWT_NE:         "SMLAWT.NE",
-	arm_SMLAWT_CS:         "SMLAWT.CS",
-	arm_SMLAWT_CC:         "SMLAWT.CC",
-	arm_SMLAWT_MI:         "SMLAWT.MI",
-	arm_SMLAWT_PL:         "SMLAWT.PL",
-	arm_SMLAWT_VS:         "SMLAWT.VS",
-	arm_SMLAWT_VC:         "SMLAWT.VC",
-	arm_SMLAWT_HI:         "SMLAWT.HI",
-	arm_SMLAWT_LS:         "SMLAWT.LS",
-	arm_SMLAWT_GE:         "SMLAWT.GE",
-	arm_SMLAWT_LT:         "SMLAWT.LT",
-	arm_SMLAWT_GT:         "SMLAWT.GT",
-	arm_SMLAWT_LE:         "SMLAWT.LE",
-	arm_SMLAWT:            "SMLAWT",
-	arm_SMLAWT_ZZ:         "SMLAWT.ZZ",
-	arm_SMLSD_EQ:          "SMLSD.EQ",
-	arm_SMLSD_NE:          "SMLSD.NE",
-	arm_SMLSD_CS:          "SMLSD.CS",
-	arm_SMLSD_CC:          "SMLSD.CC",
-	arm_SMLSD_MI:          "SMLSD.MI",
-	arm_SMLSD_PL:          "SMLSD.PL",
-	arm_SMLSD_VS:          "SMLSD.VS",
-	arm_SMLSD_VC:          "SMLSD.VC",
-	arm_SMLSD_HI:          "SMLSD.HI",
-	arm_SMLSD_LS:          "SMLSD.LS",
-	arm_SMLSD_GE:          "SMLSD.GE",
-	arm_SMLSD_LT:          "SMLSD.LT",
-	arm_SMLSD_GT:          "SMLSD.GT",
-	arm_SMLSD_LE:          "SMLSD.LE",
-	arm_SMLSD:             "SMLSD",
-	arm_SMLSD_ZZ:          "SMLSD.ZZ",
-	arm_SMLSD_X_EQ:        "SMLSD.X.EQ",
-	arm_SMLSD_X_NE:        "SMLSD.X.NE",
-	arm_SMLSD_X_CS:        "SMLSD.X.CS",
-	arm_SMLSD_X_CC:        "SMLSD.X.CC",
-	arm_SMLSD_X_MI:        "SMLSD.X.MI",
-	arm_SMLSD_X_PL:        "SMLSD.X.PL",
-	arm_SMLSD_X_VS:        "SMLSD.X.VS",
-	arm_SMLSD_X_VC:        "SMLSD.X.VC",
-	arm_SMLSD_X_HI:        "SMLSD.X.HI",
-	arm_SMLSD_X_LS:        "SMLSD.X.LS",
-	arm_SMLSD_X_GE:        "SMLSD.X.GE",
-	arm_SMLSD_X_LT:        "SMLSD.X.LT",
-	arm_SMLSD_X_GT:        "SMLSD.X.GT",
-	arm_SMLSD_X_LE:        "SMLSD.X.LE",
-	arm_SMLSD_X:           "SMLSD.X",
-	arm_SMLSD_X_ZZ:        "SMLSD.X.ZZ",
-	arm_SMLSLD_EQ:         "SMLSLD.EQ",
-	arm_SMLSLD_NE:         "SMLSLD.NE",
-	arm_SMLSLD_CS:         "SMLSLD.CS",
-	arm_SMLSLD_CC:         "SMLSLD.CC",
-	arm_SMLSLD_MI:         "SMLSLD.MI",
-	arm_SMLSLD_PL:         "SMLSLD.PL",
-	arm_SMLSLD_VS:         "SMLSLD.VS",
-	arm_SMLSLD_VC:         "SMLSLD.VC",
-	arm_SMLSLD_HI:         "SMLSLD.HI",
-	arm_SMLSLD_LS:         "SMLSLD.LS",
-	arm_SMLSLD_GE:         "SMLSLD.GE",
-	arm_SMLSLD_LT:         "SMLSLD.LT",
-	arm_SMLSLD_GT:         "SMLSLD.GT",
-	arm_SMLSLD_LE:         "SMLSLD.LE",
-	arm_SMLSLD:            "SMLSLD",
-	arm_SMLSLD_ZZ:         "SMLSLD.ZZ",
-	arm_SMLSLD_X_EQ:       "SMLSLD.X.EQ",
-	arm_SMLSLD_X_NE:       "SMLSLD.X.NE",
-	arm_SMLSLD_X_CS:       "SMLSLD.X.CS",
-	arm_SMLSLD_X_CC:       "SMLSLD.X.CC",
-	arm_SMLSLD_X_MI:       "SMLSLD.X.MI",
-	arm_SMLSLD_X_PL:       "SMLSLD.X.PL",
-	arm_SMLSLD_X_VS:       "SMLSLD.X.VS",
-	arm_SMLSLD_X_VC:       "SMLSLD.X.VC",
-	arm_SMLSLD_X_HI:       "SMLSLD.X.HI",
-	arm_SMLSLD_X_LS:       "SMLSLD.X.LS",
-	arm_SMLSLD_X_GE:       "SMLSLD.X.GE",
-	arm_SMLSLD_X_LT:       "SMLSLD.X.LT",
-	arm_SMLSLD_X_GT:       "SMLSLD.X.GT",
-	arm_SMLSLD_X_LE:       "SMLSLD.X.LE",
-	arm_SMLSLD_X:          "SMLSLD.X",
-	arm_SMLSLD_X_ZZ:       "SMLSLD.X.ZZ",
-	arm_SMMLA_EQ:          "SMMLA.EQ",
-	arm_SMMLA_NE:          "SMMLA.NE",
-	arm_SMMLA_CS:          "SMMLA.CS",
-	arm_SMMLA_CC:          "SMMLA.CC",
-	arm_SMMLA_MI:          "SMMLA.MI",
-	arm_SMMLA_PL:          "SMMLA.PL",
-	arm_SMMLA_VS:          "SMMLA.VS",
-	arm_SMMLA_VC:          "SMMLA.VC",
-	arm_SMMLA_HI:          "SMMLA.HI",
-	arm_SMMLA_LS:          "SMMLA.LS",
-	arm_SMMLA_GE:          "SMMLA.GE",
-	arm_SMMLA_LT:          "SMMLA.LT",
-	arm_SMMLA_GT:          "SMMLA.GT",
-	arm_SMMLA_LE:          "SMMLA.LE",
-	arm_SMMLA:             "SMMLA",
-	arm_SMMLA_ZZ:          "SMMLA.ZZ",
-	arm_SMMLA_R_EQ:        "SMMLA.R.EQ",
-	arm_SMMLA_R_NE:        "SMMLA.R.NE",
-	arm_SMMLA_R_CS:        "SMMLA.R.CS",
-	arm_SMMLA_R_CC:        "SMMLA.R.CC",
-	arm_SMMLA_R_MI:        "SMMLA.R.MI",
-	arm_SMMLA_R_PL:        "SMMLA.R.PL",
-	arm_SMMLA_R_VS:        "SMMLA.R.VS",
-	arm_SMMLA_R_VC:        "SMMLA.R.VC",
-	arm_SMMLA_R_HI:        "SMMLA.R.HI",
-	arm_SMMLA_R_LS:        "SMMLA.R.LS",
-	arm_SMMLA_R_GE:        "SMMLA.R.GE",
-	arm_SMMLA_R_LT:        "SMMLA.R.LT",
-	arm_SMMLA_R_GT:        "SMMLA.R.GT",
-	arm_SMMLA_R_LE:        "SMMLA.R.LE",
-	arm_SMMLA_R:           "SMMLA.R",
-	arm_SMMLA_R_ZZ:        "SMMLA.R.ZZ",
-	arm_SMMLS_EQ:          "SMMLS.EQ",
-	arm_SMMLS_NE:          "SMMLS.NE",
-	arm_SMMLS_CS:          "SMMLS.CS",
-	arm_SMMLS_CC:          "SMMLS.CC",
-	arm_SMMLS_MI:          "SMMLS.MI",
-	arm_SMMLS_PL:          "SMMLS.PL",
-	arm_SMMLS_VS:          "SMMLS.VS",
-	arm_SMMLS_VC:          "SMMLS.VC",
-	arm_SMMLS_HI:          "SMMLS.HI",
-	arm_SMMLS_LS:          "SMMLS.LS",
-	arm_SMMLS_GE:          "SMMLS.GE",
-	arm_SMMLS_LT:          "SMMLS.LT",
-	arm_SMMLS_GT:          "SMMLS.GT",
-	arm_SMMLS_LE:          "SMMLS.LE",
-	arm_SMMLS:             "SMMLS",
-	arm_SMMLS_ZZ:          "SMMLS.ZZ",
-	arm_SMMLS_R_EQ:        "SMMLS.R.EQ",
-	arm_SMMLS_R_NE:        "SMMLS.R.NE",
-	arm_SMMLS_R_CS:        "SMMLS.R.CS",
-	arm_SMMLS_R_CC:        "SMMLS.R.CC",
-	arm_SMMLS_R_MI:        "SMMLS.R.MI",
-	arm_SMMLS_R_PL:        "SMMLS.R.PL",
-	arm_SMMLS_R_VS:        "SMMLS.R.VS",
-	arm_SMMLS_R_VC:        "SMMLS.R.VC",
-	arm_SMMLS_R_HI:        "SMMLS.R.HI",
-	arm_SMMLS_R_LS:        "SMMLS.R.LS",
-	arm_SMMLS_R_GE:        "SMMLS.R.GE",
-	arm_SMMLS_R_LT:        "SMMLS.R.LT",
-	arm_SMMLS_R_GT:        "SMMLS.R.GT",
-	arm_SMMLS_R_LE:        "SMMLS.R.LE",
-	arm_SMMLS_R:           "SMMLS.R",
-	arm_SMMLS_R_ZZ:        "SMMLS.R.ZZ",
-	arm_SMMUL_EQ:          "SMMUL.EQ",
-	arm_SMMUL_NE:          "SMMUL.NE",
-	arm_SMMUL_CS:          "SMMUL.CS",
-	arm_SMMUL_CC:          "SMMUL.CC",
-	arm_SMMUL_MI:          "SMMUL.MI",
-	arm_SMMUL_PL:          "SMMUL.PL",
-	arm_SMMUL_VS:          "SMMUL.VS",
-	arm_SMMUL_VC:          "SMMUL.VC",
-	arm_SMMUL_HI:          "SMMUL.HI",
-	arm_SMMUL_LS:          "SMMUL.LS",
-	arm_SMMUL_GE:          "SMMUL.GE",
-	arm_SMMUL_LT:          "SMMUL.LT",
-	arm_SMMUL_GT:          "SMMUL.GT",
-	arm_SMMUL_LE:          "SMMUL.LE",
-	arm_SMMUL:             "SMMUL",
-	arm_SMMUL_ZZ:          "SMMUL.ZZ",
-	arm_SMMUL_R_EQ:        "SMMUL.R.EQ",
-	arm_SMMUL_R_NE:        "SMMUL.R.NE",
-	arm_SMMUL_R_CS:        "SMMUL.R.CS",
-	arm_SMMUL_R_CC:        "SMMUL.R.CC",
-	arm_SMMUL_R_MI:        "SMMUL.R.MI",
-	arm_SMMUL_R_PL:        "SMMUL.R.PL",
-	arm_SMMUL_R_VS:        "SMMUL.R.VS",
-	arm_SMMUL_R_VC:        "SMMUL.R.VC",
-	arm_SMMUL_R_HI:        "SMMUL.R.HI",
-	arm_SMMUL_R_LS:        "SMMUL.R.LS",
-	arm_SMMUL_R_GE:        "SMMUL.R.GE",
-	arm_SMMUL_R_LT:        "SMMUL.R.LT",
-	arm_SMMUL_R_GT:        "SMMUL.R.GT",
-	arm_SMMUL_R_LE:        "SMMUL.R.LE",
-	arm_SMMUL_R:           "SMMUL.R",
-	arm_SMMUL_R_ZZ:        "SMMUL.R.ZZ",
-	arm_SMUAD_EQ:          "SMUAD.EQ",
-	arm_SMUAD_NE:          "SMUAD.NE",
-	arm_SMUAD_CS:          "SMUAD.CS",
-	arm_SMUAD_CC:          "SMUAD.CC",
-	arm_SMUAD_MI:          "SMUAD.MI",
-	arm_SMUAD_PL:          "SMUAD.PL",
-	arm_SMUAD_VS:          "SMUAD.VS",
-	arm_SMUAD_VC:          "SMUAD.VC",
-	arm_SMUAD_HI:          "SMUAD.HI",
-	arm_SMUAD_LS:          "SMUAD.LS",
-	arm_SMUAD_GE:          "SMUAD.GE",
-	arm_SMUAD_LT:          "SMUAD.LT",
-	arm_SMUAD_GT:          "SMUAD.GT",
-	arm_SMUAD_LE:          "SMUAD.LE",
-	arm_SMUAD:             "SMUAD",
-	arm_SMUAD_ZZ:          "SMUAD.ZZ",
-	arm_SMUAD_X_EQ:        "SMUAD.X.EQ",
-	arm_SMUAD_X_NE:        "SMUAD.X.NE",
-	arm_SMUAD_X_CS:        "SMUAD.X.CS",
-	arm_SMUAD_X_CC:        "SMUAD.X.CC",
-	arm_SMUAD_X_MI:        "SMUAD.X.MI",
-	arm_SMUAD_X_PL:        "SMUAD.X.PL",
-	arm_SMUAD_X_VS:        "SMUAD.X.VS",
-	arm_SMUAD_X_VC:        "SMUAD.X.VC",
-	arm_SMUAD_X_HI:        "SMUAD.X.HI",
-	arm_SMUAD_X_LS:        "SMUAD.X.LS",
-	arm_SMUAD_X_GE:        "SMUAD.X.GE",
-	arm_SMUAD_X_LT:        "SMUAD.X.LT",
-	arm_SMUAD_X_GT:        "SMUAD.X.GT",
-	arm_SMUAD_X_LE:        "SMUAD.X.LE",
-	arm_SMUAD_X:           "SMUAD.X",
-	arm_SMUAD_X_ZZ:        "SMUAD.X.ZZ",
-	arm_SMULBB_EQ:         "SMULBB.EQ",
-	arm_SMULBB_NE:         "SMULBB.NE",
-	arm_SMULBB_CS:         "SMULBB.CS",
-	arm_SMULBB_CC:         "SMULBB.CC",
-	arm_SMULBB_MI:         "SMULBB.MI",
-	arm_SMULBB_PL:         "SMULBB.PL",
-	arm_SMULBB_VS:         "SMULBB.VS",
-	arm_SMULBB_VC:         "SMULBB.VC",
-	arm_SMULBB_HI:         "SMULBB.HI",
-	arm_SMULBB_LS:         "SMULBB.LS",
-	arm_SMULBB_GE:         "SMULBB.GE",
-	arm_SMULBB_LT:         "SMULBB.LT",
-	arm_SMULBB_GT:         "SMULBB.GT",
-	arm_SMULBB_LE:         "SMULBB.LE",
-	arm_SMULBB:            "SMULBB",
-	arm_SMULBB_ZZ:         "SMULBB.ZZ",
-	arm_SMULBT_EQ:         "SMULBT.EQ",
-	arm_SMULBT_NE:         "SMULBT.NE",
-	arm_SMULBT_CS:         "SMULBT.CS",
-	arm_SMULBT_CC:         "SMULBT.CC",
-	arm_SMULBT_MI:         "SMULBT.MI",
-	arm_SMULBT_PL:         "SMULBT.PL",
-	arm_SMULBT_VS:         "SMULBT.VS",
-	arm_SMULBT_VC:         "SMULBT.VC",
-	arm_SMULBT_HI:         "SMULBT.HI",
-	arm_SMULBT_LS:         "SMULBT.LS",
-	arm_SMULBT_GE:         "SMULBT.GE",
-	arm_SMULBT_LT:         "SMULBT.LT",
-	arm_SMULBT_GT:         "SMULBT.GT",
-	arm_SMULBT_LE:         "SMULBT.LE",
-	arm_SMULBT:            "SMULBT",
-	arm_SMULBT_ZZ:         "SMULBT.ZZ",
-	arm_SMULTB_EQ:         "SMULTB.EQ",
-	arm_SMULTB_NE:         "SMULTB.NE",
-	arm_SMULTB_CS:         "SMULTB.CS",
-	arm_SMULTB_CC:         "SMULTB.CC",
-	arm_SMULTB_MI:         "SMULTB.MI",
-	arm_SMULTB_PL:         "SMULTB.PL",
-	arm_SMULTB_VS:         "SMULTB.VS",
-	arm_SMULTB_VC:         "SMULTB.VC",
-	arm_SMULTB_HI:         "SMULTB.HI",
-	arm_SMULTB_LS:         "SMULTB.LS",
-	arm_SMULTB_GE:         "SMULTB.GE",
-	arm_SMULTB_LT:         "SMULTB.LT",
-	arm_SMULTB_GT:         "SMULTB.GT",
-	arm_SMULTB_LE:         "SMULTB.LE",
-	arm_SMULTB:            "SMULTB",
-	arm_SMULTB_ZZ:         "SMULTB.ZZ",
-	arm_SMULTT_EQ:         "SMULTT.EQ",
-	arm_SMULTT_NE:         "SMULTT.NE",
-	arm_SMULTT_CS:         "SMULTT.CS",
-	arm_SMULTT_CC:         "SMULTT.CC",
-	arm_SMULTT_MI:         "SMULTT.MI",
-	arm_SMULTT_PL:         "SMULTT.PL",
-	arm_SMULTT_VS:         "SMULTT.VS",
-	arm_SMULTT_VC:         "SMULTT.VC",
-	arm_SMULTT_HI:         "SMULTT.HI",
-	arm_SMULTT_LS:         "SMULTT.LS",
-	arm_SMULTT_GE:         "SMULTT.GE",
-	arm_SMULTT_LT:         "SMULTT.LT",
-	arm_SMULTT_GT:         "SMULTT.GT",
-	arm_SMULTT_LE:         "SMULTT.LE",
-	arm_SMULTT:            "SMULTT",
-	arm_SMULTT_ZZ:         "SMULTT.ZZ",
-	arm_SMULL_EQ:          "SMULL.EQ",
-	arm_SMULL_NE:          "SMULL.NE",
-	arm_SMULL_CS:          "SMULL.CS",
-	arm_SMULL_CC:          "SMULL.CC",
-	arm_SMULL_MI:          "SMULL.MI",
-	arm_SMULL_PL:          "SMULL.PL",
-	arm_SMULL_VS:          "SMULL.VS",
-	arm_SMULL_VC:          "SMULL.VC",
-	arm_SMULL_HI:          "SMULL.HI",
-	arm_SMULL_LS:          "SMULL.LS",
-	arm_SMULL_GE:          "SMULL.GE",
-	arm_SMULL_LT:          "SMULL.LT",
-	arm_SMULL_GT:          "SMULL.GT",
-	arm_SMULL_LE:          "SMULL.LE",
-	arm_SMULL:             "SMULL",
-	arm_SMULL_ZZ:          "SMULL.ZZ",
-	arm_SMULL_S_EQ:        "SMULL.S.EQ",
-	arm_SMULL_S_NE:        "SMULL.S.NE",
-	arm_SMULL_S_CS:        "SMULL.S.CS",
-	arm_SMULL_S_CC:        "SMULL.S.CC",
-	arm_SMULL_S_MI:        "SMULL.S.MI",
-	arm_SMULL_S_PL:        "SMULL.S.PL",
-	arm_SMULL_S_VS:        "SMULL.S.VS",
-	arm_SMULL_S_VC:        "SMULL.S.VC",
-	arm_SMULL_S_HI:        "SMULL.S.HI",
-	arm_SMULL_S_LS:        "SMULL.S.LS",
-	arm_SMULL_S_GE:        "SMULL.S.GE",
-	arm_SMULL_S_LT:        "SMULL.S.LT",
-	arm_SMULL_S_GT:        "SMULL.S.GT",
-	arm_SMULL_S_LE:        "SMULL.S.LE",
-	arm_SMULL_S:           "SMULL.S",
-	arm_SMULL_S_ZZ:        "SMULL.S.ZZ",
-	arm_SMULWB_EQ:         "SMULWB.EQ",
-	arm_SMULWB_NE:         "SMULWB.NE",
-	arm_SMULWB_CS:         "SMULWB.CS",
-	arm_SMULWB_CC:         "SMULWB.CC",
-	arm_SMULWB_MI:         "SMULWB.MI",
-	arm_SMULWB_PL:         "SMULWB.PL",
-	arm_SMULWB_VS:         "SMULWB.VS",
-	arm_SMULWB_VC:         "SMULWB.VC",
-	arm_SMULWB_HI:         "SMULWB.HI",
-	arm_SMULWB_LS:         "SMULWB.LS",
-	arm_SMULWB_GE:         "SMULWB.GE",
-	arm_SMULWB_LT:         "SMULWB.LT",
-	arm_SMULWB_GT:         "SMULWB.GT",
-	arm_SMULWB_LE:         "SMULWB.LE",
-	arm_SMULWB:            "SMULWB",
-	arm_SMULWB_ZZ:         "SMULWB.ZZ",
-	arm_SMULWT_EQ:         "SMULWT.EQ",
-	arm_SMULWT_NE:         "SMULWT.NE",
-	arm_SMULWT_CS:         "SMULWT.CS",
-	arm_SMULWT_CC:         "SMULWT.CC",
-	arm_SMULWT_MI:         "SMULWT.MI",
-	arm_SMULWT_PL:         "SMULWT.PL",
-	arm_SMULWT_VS:         "SMULWT.VS",
-	arm_SMULWT_VC:         "SMULWT.VC",
-	arm_SMULWT_HI:         "SMULWT.HI",
-	arm_SMULWT_LS:         "SMULWT.LS",
-	arm_SMULWT_GE:         "SMULWT.GE",
-	arm_SMULWT_LT:         "SMULWT.LT",
-	arm_SMULWT_GT:         "SMULWT.GT",
-	arm_SMULWT_LE:         "SMULWT.LE",
-	arm_SMULWT:            "SMULWT",
-	arm_SMULWT_ZZ:         "SMULWT.ZZ",
-	arm_SMUSD_EQ:          "SMUSD.EQ",
-	arm_SMUSD_NE:          "SMUSD.NE",
-	arm_SMUSD_CS:          "SMUSD.CS",
-	arm_SMUSD_CC:          "SMUSD.CC",
-	arm_SMUSD_MI:          "SMUSD.MI",
-	arm_SMUSD_PL:          "SMUSD.PL",
-	arm_SMUSD_VS:          "SMUSD.VS",
-	arm_SMUSD_VC:          "SMUSD.VC",
-	arm_SMUSD_HI:          "SMUSD.HI",
-	arm_SMUSD_LS:          "SMUSD.LS",
-	arm_SMUSD_GE:          "SMUSD.GE",
-	arm_SMUSD_LT:          "SMUSD.LT",
-	arm_SMUSD_GT:          "SMUSD.GT",
-	arm_SMUSD_LE:          "SMUSD.LE",
-	arm_SMUSD:             "SMUSD",
-	arm_SMUSD_ZZ:          "SMUSD.ZZ",
-	arm_SMUSD_X_EQ:        "SMUSD.X.EQ",
-	arm_SMUSD_X_NE:        "SMUSD.X.NE",
-	arm_SMUSD_X_CS:        "SMUSD.X.CS",
-	arm_SMUSD_X_CC:        "SMUSD.X.CC",
-	arm_SMUSD_X_MI:        "SMUSD.X.MI",
-	arm_SMUSD_X_PL:        "SMUSD.X.PL",
-	arm_SMUSD_X_VS:        "SMUSD.X.VS",
-	arm_SMUSD_X_VC:        "SMUSD.X.VC",
-	arm_SMUSD_X_HI:        "SMUSD.X.HI",
-	arm_SMUSD_X_LS:        "SMUSD.X.LS",
-	arm_SMUSD_X_GE:        "SMUSD.X.GE",
-	arm_SMUSD_X_LT:        "SMUSD.X.LT",
-	arm_SMUSD_X_GT:        "SMUSD.X.GT",
-	arm_SMUSD_X_LE:        "SMUSD.X.LE",
-	arm_SMUSD_X:           "SMUSD.X",
-	arm_SMUSD_X_ZZ:        "SMUSD.X.ZZ",
-	arm_SSAT_EQ:           "SSAT.EQ",
-	arm_SSAT_NE:           "SSAT.NE",
-	arm_SSAT_CS:           "SSAT.CS",
-	arm_SSAT_CC:           "SSAT.CC",
-	arm_SSAT_MI:           "SSAT.MI",
-	arm_SSAT_PL:           "SSAT.PL",
-	arm_SSAT_VS:           "SSAT.VS",
-	arm_SSAT_VC:           "SSAT.VC",
-	arm_SSAT_HI:           "SSAT.HI",
-	arm_SSAT_LS:           "SSAT.LS",
-	arm_SSAT_GE:           "SSAT.GE",
-	arm_SSAT_LT:           "SSAT.LT",
-	arm_SSAT_GT:           "SSAT.GT",
-	arm_SSAT_LE:           "SSAT.LE",
-	arm_SSAT:              "SSAT",
-	arm_SSAT_ZZ:           "SSAT.ZZ",
-	arm_SSAT16_EQ:         "SSAT16.EQ",
-	arm_SSAT16_NE:         "SSAT16.NE",
-	arm_SSAT16_CS:         "SSAT16.CS",
-	arm_SSAT16_CC:         "SSAT16.CC",
-	arm_SSAT16_MI:         "SSAT16.MI",
-	arm_SSAT16_PL:         "SSAT16.PL",
-	arm_SSAT16_VS:         "SSAT16.VS",
-	arm_SSAT16_VC:         "SSAT16.VC",
-	arm_SSAT16_HI:         "SSAT16.HI",
-	arm_SSAT16_LS:         "SSAT16.LS",
-	arm_SSAT16_GE:         "SSAT16.GE",
-	arm_SSAT16_LT:         "SSAT16.LT",
-	arm_SSAT16_GT:         "SSAT16.GT",
-	arm_SSAT16_LE:         "SSAT16.LE",
-	arm_SSAT16:            "SSAT16",
-	arm_SSAT16_ZZ:         "SSAT16.ZZ",
-	arm_SSAX_EQ:           "SSAX.EQ",
-	arm_SSAX_NE:           "SSAX.NE",
-	arm_SSAX_CS:           "SSAX.CS",
-	arm_SSAX_CC:           "SSAX.CC",
-	arm_SSAX_MI:           "SSAX.MI",
-	arm_SSAX_PL:           "SSAX.PL",
-	arm_SSAX_VS:           "SSAX.VS",
-	arm_SSAX_VC:           "SSAX.VC",
-	arm_SSAX_HI:           "SSAX.HI",
-	arm_SSAX_LS:           "SSAX.LS",
-	arm_SSAX_GE:           "SSAX.GE",
-	arm_SSAX_LT:           "SSAX.LT",
-	arm_SSAX_GT:           "SSAX.GT",
-	arm_SSAX_LE:           "SSAX.LE",
-	arm_SSAX:              "SSAX",
-	arm_SSAX_ZZ:           "SSAX.ZZ",
-	arm_SSUB16_EQ:         "SSUB16.EQ",
-	arm_SSUB16_NE:         "SSUB16.NE",
-	arm_SSUB16_CS:         "SSUB16.CS",
-	arm_SSUB16_CC:         "SSUB16.CC",
-	arm_SSUB16_MI:         "SSUB16.MI",
-	arm_SSUB16_PL:         "SSUB16.PL",
-	arm_SSUB16_VS:         "SSUB16.VS",
-	arm_SSUB16_VC:         "SSUB16.VC",
-	arm_SSUB16_HI:         "SSUB16.HI",
-	arm_SSUB16_LS:         "SSUB16.LS",
-	arm_SSUB16_GE:         "SSUB16.GE",
-	arm_SSUB16_LT:         "SSUB16.LT",
-	arm_SSUB16_GT:         "SSUB16.GT",
-	arm_SSUB16_LE:         "SSUB16.LE",
-	arm_SSUB16:            "SSUB16",
-	arm_SSUB16_ZZ:         "SSUB16.ZZ",
-	arm_SSUB8_EQ:          "SSUB8.EQ",
-	arm_SSUB8_NE:          "SSUB8.NE",
-	arm_SSUB8_CS:          "SSUB8.CS",
-	arm_SSUB8_CC:          "SSUB8.CC",
-	arm_SSUB8_MI:          "SSUB8.MI",
-	arm_SSUB8_PL:          "SSUB8.PL",
-	arm_SSUB8_VS:          "SSUB8.VS",
-	arm_SSUB8_VC:          "SSUB8.VC",
-	arm_SSUB8_HI:          "SSUB8.HI",
-	arm_SSUB8_LS:          "SSUB8.LS",
-	arm_SSUB8_GE:          "SSUB8.GE",
-	arm_SSUB8_LT:          "SSUB8.LT",
-	arm_SSUB8_GT:          "SSUB8.GT",
-	arm_SSUB8_LE:          "SSUB8.LE",
-	arm_SSUB8:             "SSUB8",
-	arm_SSUB8_ZZ:          "SSUB8.ZZ",
-	arm_STM_EQ:            "STM.EQ",
-	arm_STM_NE:            "STM.NE",
-	arm_STM_CS:            "STM.CS",
-	arm_STM_CC:            "STM.CC",
-	arm_STM_MI:            "STM.MI",
-	arm_STM_PL:            "STM.PL",
-	arm_STM_VS:            "STM.VS",
-	arm_STM_VC:            "STM.VC",
-	arm_STM_HI:            "STM.HI",
-	arm_STM_LS:            "STM.LS",
-	arm_STM_GE:            "STM.GE",
-	arm_STM_LT:            "STM.LT",
-	arm_STM_GT:            "STM.GT",
-	arm_STM_LE:            "STM.LE",
-	arm_STM:               "STM",
-	arm_STM_ZZ:            "STM.ZZ",
-	arm_STMDA_EQ:          "STMDA.EQ",
-	arm_STMDA_NE:          "STMDA.NE",
-	arm_STMDA_CS:          "STMDA.CS",
-	arm_STMDA_CC:          "STMDA.CC",
-	arm_STMDA_MI:          "STMDA.MI",
-	arm_STMDA_PL:          "STMDA.PL",
-	arm_STMDA_VS:          "STMDA.VS",
-	arm_STMDA_VC:          "STMDA.VC",
-	arm_STMDA_HI:          "STMDA.HI",
-	arm_STMDA_LS:          "STMDA.LS",
-	arm_STMDA_GE:          "STMDA.GE",
-	arm_STMDA_LT:          "STMDA.LT",
-	arm_STMDA_GT:          "STMDA.GT",
-	arm_STMDA_LE:          "STMDA.LE",
-	arm_STMDA:             "STMDA",
-	arm_STMDA_ZZ:          "STMDA.ZZ",
-	arm_STMDB_EQ:          "STMDB.EQ",
-	arm_STMDB_NE:          "STMDB.NE",
-	arm_STMDB_CS:          "STMDB.CS",
-	arm_STMDB_CC:          "STMDB.CC",
-	arm_STMDB_MI:          "STMDB.MI",
-	arm_STMDB_PL:          "STMDB.PL",
-	arm_STMDB_VS:          "STMDB.VS",
-	arm_STMDB_VC:          "STMDB.VC",
-	arm_STMDB_HI:          "STMDB.HI",
-	arm_STMDB_LS:          "STMDB.LS",
-	arm_STMDB_GE:          "STMDB.GE",
-	arm_STMDB_LT:          "STMDB.LT",
-	arm_STMDB_GT:          "STMDB.GT",
-	arm_STMDB_LE:          "STMDB.LE",
-	arm_STMDB:             "STMDB",
-	arm_STMDB_ZZ:          "STMDB.ZZ",
-	arm_STMIB_EQ:          "STMIB.EQ",
-	arm_STMIB_NE:          "STMIB.NE",
-	arm_STMIB_CS:          "STMIB.CS",
-	arm_STMIB_CC:          "STMIB.CC",
-	arm_STMIB_MI:          "STMIB.MI",
-	arm_STMIB_PL:          "STMIB.PL",
-	arm_STMIB_VS:          "STMIB.VS",
-	arm_STMIB_VC:          "STMIB.VC",
-	arm_STMIB_HI:          "STMIB.HI",
-	arm_STMIB_LS:          "STMIB.LS",
-	arm_STMIB_GE:          "STMIB.GE",
-	arm_STMIB_LT:          "STMIB.LT",
-	arm_STMIB_GT:          "STMIB.GT",
-	arm_STMIB_LE:          "STMIB.LE",
-	arm_STMIB:             "STMIB",
-	arm_STMIB_ZZ:          "STMIB.ZZ",
-	arm_STR_EQ:            "STR.EQ",
-	arm_STR_NE:            "STR.NE",
-	arm_STR_CS:            "STR.CS",
-	arm_STR_CC:            "STR.CC",
-	arm_STR_MI:            "STR.MI",
-	arm_STR_PL:            "STR.PL",
-	arm_STR_VS:            "STR.VS",
-	arm_STR_VC:            "STR.VC",
-	arm_STR_HI:            "STR.HI",
-	arm_STR_LS:            "STR.LS",
-	arm_STR_GE:            "STR.GE",
-	arm_STR_LT:            "STR.LT",
-	arm_STR_GT:            "STR.GT",
-	arm_STR_LE:            "STR.LE",
-	arm_STR:               "STR",
-	arm_STR_ZZ:            "STR.ZZ",
-	arm_STRB_EQ:           "STRB.EQ",
-	arm_STRB_NE:           "STRB.NE",
-	arm_STRB_CS:           "STRB.CS",
-	arm_STRB_CC:           "STRB.CC",
-	arm_STRB_MI:           "STRB.MI",
-	arm_STRB_PL:           "STRB.PL",
-	arm_STRB_VS:           "STRB.VS",
-	arm_STRB_VC:           "STRB.VC",
-	arm_STRB_HI:           "STRB.HI",
-	arm_STRB_LS:           "STRB.LS",
-	arm_STRB_GE:           "STRB.GE",
-	arm_STRB_LT:           "STRB.LT",
-	arm_STRB_GT:           "STRB.GT",
-	arm_STRB_LE:           "STRB.LE",
-	arm_STRB:              "STRB",
-	arm_STRB_ZZ:           "STRB.ZZ",
-	arm_STRBT_EQ:          "STRBT.EQ",
-	arm_STRBT_NE:          "STRBT.NE",
-	arm_STRBT_CS:          "STRBT.CS",
-	arm_STRBT_CC:          "STRBT.CC",
-	arm_STRBT_MI:          "STRBT.MI",
-	arm_STRBT_PL:          "STRBT.PL",
-	arm_STRBT_VS:          "STRBT.VS",
-	arm_STRBT_VC:          "STRBT.VC",
-	arm_STRBT_HI:          "STRBT.HI",
-	arm_STRBT_LS:          "STRBT.LS",
-	arm_STRBT_GE:          "STRBT.GE",
-	arm_STRBT_LT:          "STRBT.LT",
-	arm_STRBT_GT:          "STRBT.GT",
-	arm_STRBT_LE:          "STRBT.LE",
-	arm_STRBT:             "STRBT",
-	arm_STRBT_ZZ:          "STRBT.ZZ",
-	arm_STRD_EQ:           "STRD.EQ",
-	arm_STRD_NE:           "STRD.NE",
-	arm_STRD_CS:           "STRD.CS",
-	arm_STRD_CC:           "STRD.CC",
-	arm_STRD_MI:           "STRD.MI",
-	arm_STRD_PL:           "STRD.PL",
-	arm_STRD_VS:           "STRD.VS",
-	arm_STRD_VC:           "STRD.VC",
-	arm_STRD_HI:           "STRD.HI",
-	arm_STRD_LS:           "STRD.LS",
-	arm_STRD_GE:           "STRD.GE",
-	arm_STRD_LT:           "STRD.LT",
-	arm_STRD_GT:           "STRD.GT",
-	arm_STRD_LE:           "STRD.LE",
-	arm_STRD:              "STRD",
-	arm_STRD_ZZ:           "STRD.ZZ",
-	arm_STREX_EQ:          "STREX.EQ",
-	arm_STREX_NE:          "STREX.NE",
-	arm_STREX_CS:          "STREX.CS",
-	arm_STREX_CC:          "STREX.CC",
-	arm_STREX_MI:          "STREX.MI",
-	arm_STREX_PL:          "STREX.PL",
-	arm_STREX_VS:          "STREX.VS",
-	arm_STREX_VC:          "STREX.VC",
-	arm_STREX_HI:          "STREX.HI",
-	arm_STREX_LS:          "STREX.LS",
-	arm_STREX_GE:          "STREX.GE",
-	arm_STREX_LT:          "STREX.LT",
-	arm_STREX_GT:          "STREX.GT",
-	arm_STREX_LE:          "STREX.LE",
-	arm_STREX:             "STREX",
-	arm_STREX_ZZ:          "STREX.ZZ",
-	arm_STREXB_EQ:         "STREXB.EQ",
-	arm_STREXB_NE:         "STREXB.NE",
-	arm_STREXB_CS:         "STREXB.CS",
-	arm_STREXB_CC:         "STREXB.CC",
-	arm_STREXB_MI:         "STREXB.MI",
-	arm_STREXB_PL:         "STREXB.PL",
-	arm_STREXB_VS:         "STREXB.VS",
-	arm_STREXB_VC:         "STREXB.VC",
-	arm_STREXB_HI:         "STREXB.HI",
-	arm_STREXB_LS:         "STREXB.LS",
-	arm_STREXB_GE:         "STREXB.GE",
-	arm_STREXB_LT:         "STREXB.LT",
-	arm_STREXB_GT:         "STREXB.GT",
-	arm_STREXB_LE:         "STREXB.LE",
-	arm_STREXB:            "STREXB",
-	arm_STREXB_ZZ:         "STREXB.ZZ",
-	arm_STREXD_EQ:         "STREXD.EQ",
-	arm_STREXD_NE:         "STREXD.NE",
-	arm_STREXD_CS:         "STREXD.CS",
-	arm_STREXD_CC:         "STREXD.CC",
-	arm_STREXD_MI:         "STREXD.MI",
-	arm_STREXD_PL:         "STREXD.PL",
-	arm_STREXD_VS:         "STREXD.VS",
-	arm_STREXD_VC:         "STREXD.VC",
-	arm_STREXD_HI:         "STREXD.HI",
-	arm_STREXD_LS:         "STREXD.LS",
-	arm_STREXD_GE:         "STREXD.GE",
-	arm_STREXD_LT:         "STREXD.LT",
-	arm_STREXD_GT:         "STREXD.GT",
-	arm_STREXD_LE:         "STREXD.LE",
-	arm_STREXD:            "STREXD",
-	arm_STREXD_ZZ:         "STREXD.ZZ",
-	arm_STREXH_EQ:         "STREXH.EQ",
-	arm_STREXH_NE:         "STREXH.NE",
-	arm_STREXH_CS:         "STREXH.CS",
-	arm_STREXH_CC:         "STREXH.CC",
-	arm_STREXH_MI:         "STREXH.MI",
-	arm_STREXH_PL:         "STREXH.PL",
-	arm_STREXH_VS:         "STREXH.VS",
-	arm_STREXH_VC:         "STREXH.VC",
-	arm_STREXH_HI:         "STREXH.HI",
-	arm_STREXH_LS:         "STREXH.LS",
-	arm_STREXH_GE:         "STREXH.GE",
-	arm_STREXH_LT:         "STREXH.LT",
-	arm_STREXH_GT:         "STREXH.GT",
-	arm_STREXH_LE:         "STREXH.LE",
-	arm_STREXH:            "STREXH",
-	arm_STREXH_ZZ:         "STREXH.ZZ",
-	arm_STRH_EQ:           "STRH.EQ",
-	arm_STRH_NE:           "STRH.NE",
-	arm_STRH_CS:           "STRH.CS",
-	arm_STRH_CC:           "STRH.CC",
-	arm_STRH_MI:           "STRH.MI",
-	arm_STRH_PL:           "STRH.PL",
-	arm_STRH_VS:           "STRH.VS",
-	arm_STRH_VC:           "STRH.VC",
-	arm_STRH_HI:           "STRH.HI",
-	arm_STRH_LS:           "STRH.LS",
-	arm_STRH_GE:           "STRH.GE",
-	arm_STRH_LT:           "STRH.LT",
-	arm_STRH_GT:           "STRH.GT",
-	arm_STRH_LE:           "STRH.LE",
-	arm_STRH:              "STRH",
-	arm_STRH_ZZ:           "STRH.ZZ",
-	arm_STRHT_EQ:          "STRHT.EQ",
-	arm_STRHT_NE:          "STRHT.NE",
-	arm_STRHT_CS:          "STRHT.CS",
-	arm_STRHT_CC:          "STRHT.CC",
-	arm_STRHT_MI:          "STRHT.MI",
-	arm_STRHT_PL:          "STRHT.PL",
-	arm_STRHT_VS:          "STRHT.VS",
-	arm_STRHT_VC:          "STRHT.VC",
-	arm_STRHT_HI:          "STRHT.HI",
-	arm_STRHT_LS:          "STRHT.LS",
-	arm_STRHT_GE:          "STRHT.GE",
-	arm_STRHT_LT:          "STRHT.LT",
-	arm_STRHT_GT:          "STRHT.GT",
-	arm_STRHT_LE:          "STRHT.LE",
-	arm_STRHT:             "STRHT",
-	arm_STRHT_ZZ:          "STRHT.ZZ",
-	arm_STRT_EQ:           "STRT.EQ",
-	arm_STRT_NE:           "STRT.NE",
-	arm_STRT_CS:           "STRT.CS",
-	arm_STRT_CC:           "STRT.CC",
-	arm_STRT_MI:           "STRT.MI",
-	arm_STRT_PL:           "STRT.PL",
-	arm_STRT_VS:           "STRT.VS",
-	arm_STRT_VC:           "STRT.VC",
-	arm_STRT_HI:           "STRT.HI",
-	arm_STRT_LS:           "STRT.LS",
-	arm_STRT_GE:           "STRT.GE",
-	arm_STRT_LT:           "STRT.LT",
-	arm_STRT_GT:           "STRT.GT",
-	arm_STRT_LE:           "STRT.LE",
-	arm_STRT:              "STRT",
-	arm_STRT_ZZ:           "STRT.ZZ",
-	arm_SUB_EQ:            "SUB.EQ",
-	arm_SUB_NE:            "SUB.NE",
-	arm_SUB_CS:            "SUB.CS",
-	arm_SUB_CC:            "SUB.CC",
-	arm_SUB_MI:            "SUB.MI",
-	arm_SUB_PL:            "SUB.PL",
-	arm_SUB_VS:            "SUB.VS",
-	arm_SUB_VC:            "SUB.VC",
-	arm_SUB_HI:            "SUB.HI",
-	arm_SUB_LS:            "SUB.LS",
-	arm_SUB_GE:            "SUB.GE",
-	arm_SUB_LT:            "SUB.LT",
-	arm_SUB_GT:            "SUB.GT",
-	arm_SUB_LE:            "SUB.LE",
-	arm_SUB:               "SUB",
-	arm_SUB_ZZ:            "SUB.ZZ",
-	arm_SUB_S_EQ:          "SUB.S.EQ",
-	arm_SUB_S_NE:          "SUB.S.NE",
-	arm_SUB_S_CS:          "SUB.S.CS",
-	arm_SUB_S_CC:          "SUB.S.CC",
-	arm_SUB_S_MI:          "SUB.S.MI",
-	arm_SUB_S_PL:          "SUB.S.PL",
-	arm_SUB_S_VS:          "SUB.S.VS",
-	arm_SUB_S_VC:          "SUB.S.VC",
-	arm_SUB_S_HI:          "SUB.S.HI",
-	arm_SUB_S_LS:          "SUB.S.LS",
-	arm_SUB_S_GE:          "SUB.S.GE",
-	arm_SUB_S_LT:          "SUB.S.LT",
-	arm_SUB_S_GT:          "SUB.S.GT",
-	arm_SUB_S_LE:          "SUB.S.LE",
-	arm_SUB_S:             "SUB.S",
-	arm_SUB_S_ZZ:          "SUB.S.ZZ",
-	arm_SVC_EQ:            "SVC.EQ",
-	arm_SVC_NE:            "SVC.NE",
-	arm_SVC_CS:            "SVC.CS",
-	arm_SVC_CC:            "SVC.CC",
-	arm_SVC_MI:            "SVC.MI",
-	arm_SVC_PL:            "SVC.PL",
-	arm_SVC_VS:            "SVC.VS",
-	arm_SVC_VC:            "SVC.VC",
-	arm_SVC_HI:            "SVC.HI",
-	arm_SVC_LS:            "SVC.LS",
-	arm_SVC_GE:            "SVC.GE",
-	arm_SVC_LT:            "SVC.LT",
-	arm_SVC_GT:            "SVC.GT",
-	arm_SVC_LE:            "SVC.LE",
-	arm_SVC:               "SVC",
-	arm_SVC_ZZ:            "SVC.ZZ",
-	arm_SWP_EQ:            "SWP.EQ",
-	arm_SWP_NE:            "SWP.NE",
-	arm_SWP_CS:            "SWP.CS",
-	arm_SWP_CC:            "SWP.CC",
-	arm_SWP_MI:            "SWP.MI",
-	arm_SWP_PL:            "SWP.PL",
-	arm_SWP_VS:            "SWP.VS",
-	arm_SWP_VC:            "SWP.VC",
-	arm_SWP_HI:            "SWP.HI",
-	arm_SWP_LS:            "SWP.LS",
-	arm_SWP_GE:            "SWP.GE",
-	arm_SWP_LT:            "SWP.LT",
-	arm_SWP_GT:            "SWP.GT",
-	arm_SWP_LE:            "SWP.LE",
-	arm_SWP:               "SWP",
-	arm_SWP_ZZ:            "SWP.ZZ",
-	arm_SWP_B_EQ:          "SWP.B.EQ",
-	arm_SWP_B_NE:          "SWP.B.NE",
-	arm_SWP_B_CS:          "SWP.B.CS",
-	arm_SWP_B_CC:          "SWP.B.CC",
-	arm_SWP_B_MI:          "SWP.B.MI",
-	arm_SWP_B_PL:          "SWP.B.PL",
-	arm_SWP_B_VS:          "SWP.B.VS",
-	arm_SWP_B_VC:          "SWP.B.VC",
-	arm_SWP_B_HI:          "SWP.B.HI",
-	arm_SWP_B_LS:          "SWP.B.LS",
-	arm_SWP_B_GE:          "SWP.B.GE",
-	arm_SWP_B_LT:          "SWP.B.LT",
-	arm_SWP_B_GT:          "SWP.B.GT",
-	arm_SWP_B_LE:          "SWP.B.LE",
-	arm_SWP_B:             "SWP.B",
-	arm_SWP_B_ZZ:          "SWP.B.ZZ",
-	arm_SXTAB_EQ:          "SXTAB.EQ",
-	arm_SXTAB_NE:          "SXTAB.NE",
-	arm_SXTAB_CS:          "SXTAB.CS",
-	arm_SXTAB_CC:          "SXTAB.CC",
-	arm_SXTAB_MI:          "SXTAB.MI",
-	arm_SXTAB_PL:          "SXTAB.PL",
-	arm_SXTAB_VS:          "SXTAB.VS",
-	arm_SXTAB_VC:          "SXTAB.VC",
-	arm_SXTAB_HI:          "SXTAB.HI",
-	arm_SXTAB_LS:          "SXTAB.LS",
-	arm_SXTAB_GE:          "SXTAB.GE",
-	arm_SXTAB_LT:          "SXTAB.LT",
-	arm_SXTAB_GT:          "SXTAB.GT",
-	arm_SXTAB_LE:          "SXTAB.LE",
-	arm_SXTAB:             "SXTAB",
-	arm_SXTAB_ZZ:          "SXTAB.ZZ",
-	arm_SXTAB16_EQ:        "SXTAB16.EQ",
-	arm_SXTAB16_NE:        "SXTAB16.NE",
-	arm_SXTAB16_CS:        "SXTAB16.CS",
-	arm_SXTAB16_CC:        "SXTAB16.CC",
-	arm_SXTAB16_MI:        "SXTAB16.MI",
-	arm_SXTAB16_PL:        "SXTAB16.PL",
-	arm_SXTAB16_VS:        "SXTAB16.VS",
-	arm_SXTAB16_VC:        "SXTAB16.VC",
-	arm_SXTAB16_HI:        "SXTAB16.HI",
-	arm_SXTAB16_LS:        "SXTAB16.LS",
-	arm_SXTAB16_GE:        "SXTAB16.GE",
-	arm_SXTAB16_LT:        "SXTAB16.LT",
-	arm_SXTAB16_GT:        "SXTAB16.GT",
-	arm_SXTAB16_LE:        "SXTAB16.LE",
-	arm_SXTAB16:           "SXTAB16",
-	arm_SXTAB16_ZZ:        "SXTAB16.ZZ",
-	arm_SXTAH_EQ:          "SXTAH.EQ",
-	arm_SXTAH_NE:          "SXTAH.NE",
-	arm_SXTAH_CS:          "SXTAH.CS",
-	arm_SXTAH_CC:          "SXTAH.CC",
-	arm_SXTAH_MI:          "SXTAH.MI",
-	arm_SXTAH_PL:          "SXTAH.PL",
-	arm_SXTAH_VS:          "SXTAH.VS",
-	arm_SXTAH_VC:          "SXTAH.VC",
-	arm_SXTAH_HI:          "SXTAH.HI",
-	arm_SXTAH_LS:          "SXTAH.LS",
-	arm_SXTAH_GE:          "SXTAH.GE",
-	arm_SXTAH_LT:          "SXTAH.LT",
-	arm_SXTAH_GT:          "SXTAH.GT",
-	arm_SXTAH_LE:          "SXTAH.LE",
-	arm_SXTAH:             "SXTAH",
-	arm_SXTAH_ZZ:          "SXTAH.ZZ",
-	arm_SXTB_EQ:           "SXTB.EQ",
-	arm_SXTB_NE:           "SXTB.NE",
-	arm_SXTB_CS:           "SXTB.CS",
-	arm_SXTB_CC:           "SXTB.CC",
-	arm_SXTB_MI:           "SXTB.MI",
-	arm_SXTB_PL:           "SXTB.PL",
-	arm_SXTB_VS:           "SXTB.VS",
-	arm_SXTB_VC:           "SXTB.VC",
-	arm_SXTB_HI:           "SXTB.HI",
-	arm_SXTB_LS:           "SXTB.LS",
-	arm_SXTB_GE:           "SXTB.GE",
-	arm_SXTB_LT:           "SXTB.LT",
-	arm_SXTB_GT:           "SXTB.GT",
-	arm_SXTB_LE:           "SXTB.LE",
-	arm_SXTB:              "SXTB",
-	arm_SXTB_ZZ:           "SXTB.ZZ",
-	arm_SXTB16_EQ:         "SXTB16.EQ",
-	arm_SXTB16_NE:         "SXTB16.NE",
-	arm_SXTB16_CS:         "SXTB16.CS",
-	arm_SXTB16_CC:         "SXTB16.CC",
-	arm_SXTB16_MI:         "SXTB16.MI",
-	arm_SXTB16_PL:         "SXTB16.PL",
-	arm_SXTB16_VS:         "SXTB16.VS",
-	arm_SXTB16_VC:         "SXTB16.VC",
-	arm_SXTB16_HI:         "SXTB16.HI",
-	arm_SXTB16_LS:         "SXTB16.LS",
-	arm_SXTB16_GE:         "SXTB16.GE",
-	arm_SXTB16_LT:         "SXTB16.LT",
-	arm_SXTB16_GT:         "SXTB16.GT",
-	arm_SXTB16_LE:         "SXTB16.LE",
-	arm_SXTB16:            "SXTB16",
-	arm_SXTB16_ZZ:         "SXTB16.ZZ",
-	arm_SXTH_EQ:           "SXTH.EQ",
-	arm_SXTH_NE:           "SXTH.NE",
-	arm_SXTH_CS:           "SXTH.CS",
-	arm_SXTH_CC:           "SXTH.CC",
-	arm_SXTH_MI:           "SXTH.MI",
-	arm_SXTH_PL:           "SXTH.PL",
-	arm_SXTH_VS:           "SXTH.VS",
-	arm_SXTH_VC:           "SXTH.VC",
-	arm_SXTH_HI:           "SXTH.HI",
-	arm_SXTH_LS:           "SXTH.LS",
-	arm_SXTH_GE:           "SXTH.GE",
-	arm_SXTH_LT:           "SXTH.LT",
-	arm_SXTH_GT:           "SXTH.GT",
-	arm_SXTH_LE:           "SXTH.LE",
-	arm_SXTH:              "SXTH",
-	arm_SXTH_ZZ:           "SXTH.ZZ",
-	arm_TEQ_EQ:            "TEQ.EQ",
-	arm_TEQ_NE:            "TEQ.NE",
-	arm_TEQ_CS:            "TEQ.CS",
-	arm_TEQ_CC:            "TEQ.CC",
-	arm_TEQ_MI:            "TEQ.MI",
-	arm_TEQ_PL:            "TEQ.PL",
-	arm_TEQ_VS:            "TEQ.VS",
-	arm_TEQ_VC:            "TEQ.VC",
-	arm_TEQ_HI:            "TEQ.HI",
-	arm_TEQ_LS:            "TEQ.LS",
-	arm_TEQ_GE:            "TEQ.GE",
-	arm_TEQ_LT:            "TEQ.LT",
-	arm_TEQ_GT:            "TEQ.GT",
-	arm_TEQ_LE:            "TEQ.LE",
-	arm_TEQ:               "TEQ",
-	arm_TEQ_ZZ:            "TEQ.ZZ",
-	arm_TST_EQ:            "TST.EQ",
-	arm_TST_NE:            "TST.NE",
-	arm_TST_CS:            "TST.CS",
-	arm_TST_CC:            "TST.CC",
-	arm_TST_MI:            "TST.MI",
-	arm_TST_PL:            "TST.PL",
-	arm_TST_VS:            "TST.VS",
-	arm_TST_VC:            "TST.VC",
-	arm_TST_HI:            "TST.HI",
-	arm_TST_LS:            "TST.LS",
-	arm_TST_GE:            "TST.GE",
-	arm_TST_LT:            "TST.LT",
-	arm_TST_GT:            "TST.GT",
-	arm_TST_LE:            "TST.LE",
-	arm_TST:               "TST",
-	arm_TST_ZZ:            "TST.ZZ",
-	arm_UADD16_EQ:         "UADD16.EQ",
-	arm_UADD16_NE:         "UADD16.NE",
-	arm_UADD16_CS:         "UADD16.CS",
-	arm_UADD16_CC:         "UADD16.CC",
-	arm_UADD16_MI:         "UADD16.MI",
-	arm_UADD16_PL:         "UADD16.PL",
-	arm_UADD16_VS:         "UADD16.VS",
-	arm_UADD16_VC:         "UADD16.VC",
-	arm_UADD16_HI:         "UADD16.HI",
-	arm_UADD16_LS:         "UADD16.LS",
-	arm_UADD16_GE:         "UADD16.GE",
-	arm_UADD16_LT:         "UADD16.LT",
-	arm_UADD16_GT:         "UADD16.GT",
-	arm_UADD16_LE:         "UADD16.LE",
-	arm_UADD16:            "UADD16",
-	arm_UADD16_ZZ:         "UADD16.ZZ",
-	arm_UADD8_EQ:          "UADD8.EQ",
-	arm_UADD8_NE:          "UADD8.NE",
-	arm_UADD8_CS:          "UADD8.CS",
-	arm_UADD8_CC:          "UADD8.CC",
-	arm_UADD8_MI:          "UADD8.MI",
-	arm_UADD8_PL:          "UADD8.PL",
-	arm_UADD8_VS:          "UADD8.VS",
-	arm_UADD8_VC:          "UADD8.VC",
-	arm_UADD8_HI:          "UADD8.HI",
-	arm_UADD8_LS:          "UADD8.LS",
-	arm_UADD8_GE:          "UADD8.GE",
-	arm_UADD8_LT:          "UADD8.LT",
-	arm_UADD8_GT:          "UADD8.GT",
-	arm_UADD8_LE:          "UADD8.LE",
-	arm_UADD8:             "UADD8",
-	arm_UADD8_ZZ:          "UADD8.ZZ",
-	arm_UASX_EQ:           "UASX.EQ",
-	arm_UASX_NE:           "UASX.NE",
-	arm_UASX_CS:           "UASX.CS",
-	arm_UASX_CC:           "UASX.CC",
-	arm_UASX_MI:           "UASX.MI",
-	arm_UASX_PL:           "UASX.PL",
-	arm_UASX_VS:           "UASX.VS",
-	arm_UASX_VC:           "UASX.VC",
-	arm_UASX_HI:           "UASX.HI",
-	arm_UASX_LS:           "UASX.LS",
-	arm_UASX_GE:           "UASX.GE",
-	arm_UASX_LT:           "UASX.LT",
-	arm_UASX_GT:           "UASX.GT",
-	arm_UASX_LE:           "UASX.LE",
-	arm_UASX:              "UASX",
-	arm_UASX_ZZ:           "UASX.ZZ",
-	arm_UBFX_EQ:           "UBFX.EQ",
-	arm_UBFX_NE:           "UBFX.NE",
-	arm_UBFX_CS:           "UBFX.CS",
-	arm_UBFX_CC:           "UBFX.CC",
-	arm_UBFX_MI:           "UBFX.MI",
-	arm_UBFX_PL:           "UBFX.PL",
-	arm_UBFX_VS:           "UBFX.VS",
-	arm_UBFX_VC:           "UBFX.VC",
-	arm_UBFX_HI:           "UBFX.HI",
-	arm_UBFX_LS:           "UBFX.LS",
-	arm_UBFX_GE:           "UBFX.GE",
-	arm_UBFX_LT:           "UBFX.LT",
-	arm_UBFX_GT:           "UBFX.GT",
-	arm_UBFX_LE:           "UBFX.LE",
-	arm_UBFX:              "UBFX",
-	arm_UBFX_ZZ:           "UBFX.ZZ",
-	arm_UHADD16_EQ:        "UHADD16.EQ",
-	arm_UHADD16_NE:        "UHADD16.NE",
-	arm_UHADD16_CS:        "UHADD16.CS",
-	arm_UHADD16_CC:        "UHADD16.CC",
-	arm_UHADD16_MI:        "UHADD16.MI",
-	arm_UHADD16_PL:        "UHADD16.PL",
-	arm_UHADD16_VS:        "UHADD16.VS",
-	arm_UHADD16_VC:        "UHADD16.VC",
-	arm_UHADD16_HI:        "UHADD16.HI",
-	arm_UHADD16_LS:        "UHADD16.LS",
-	arm_UHADD16_GE:        "UHADD16.GE",
-	arm_UHADD16_LT:        "UHADD16.LT",
-	arm_UHADD16_GT:        "UHADD16.GT",
-	arm_UHADD16_LE:        "UHADD16.LE",
-	arm_UHADD16:           "UHADD16",
-	arm_UHADD16_ZZ:        "UHADD16.ZZ",
-	arm_UHADD8_EQ:         "UHADD8.EQ",
-	arm_UHADD8_NE:         "UHADD8.NE",
-	arm_UHADD8_CS:         "UHADD8.CS",
-	arm_UHADD8_CC:         "UHADD8.CC",
-	arm_UHADD8_MI:         "UHADD8.MI",
-	arm_UHADD8_PL:         "UHADD8.PL",
-	arm_UHADD8_VS:         "UHADD8.VS",
-	arm_UHADD8_VC:         "UHADD8.VC",
-	arm_UHADD8_HI:         "UHADD8.HI",
-	arm_UHADD8_LS:         "UHADD8.LS",
-	arm_UHADD8_GE:         "UHADD8.GE",
-	arm_UHADD8_LT:         "UHADD8.LT",
-	arm_UHADD8_GT:         "UHADD8.GT",
-	arm_UHADD8_LE:         "UHADD8.LE",
-	arm_UHADD8:            "UHADD8",
-	arm_UHADD8_ZZ:         "UHADD8.ZZ",
-	arm_UHASX_EQ:          "UHASX.EQ",
-	arm_UHASX_NE:          "UHASX.NE",
-	arm_UHASX_CS:          "UHASX.CS",
-	arm_UHASX_CC:          "UHASX.CC",
-	arm_UHASX_MI:          "UHASX.MI",
-	arm_UHASX_PL:          "UHASX.PL",
-	arm_UHASX_VS:          "UHASX.VS",
-	arm_UHASX_VC:          "UHASX.VC",
-	arm_UHASX_HI:          "UHASX.HI",
-	arm_UHASX_LS:          "UHASX.LS",
-	arm_UHASX_GE:          "UHASX.GE",
-	arm_UHASX_LT:          "UHASX.LT",
-	arm_UHASX_GT:          "UHASX.GT",
-	arm_UHASX_LE:          "UHASX.LE",
-	arm_UHASX:             "UHASX",
-	arm_UHASX_ZZ:          "UHASX.ZZ",
-	arm_UHSAX_EQ:          "UHSAX.EQ",
-	arm_UHSAX_NE:          "UHSAX.NE",
-	arm_UHSAX_CS:          "UHSAX.CS",
-	arm_UHSAX_CC:          "UHSAX.CC",
-	arm_UHSAX_MI:          "UHSAX.MI",
-	arm_UHSAX_PL:          "UHSAX.PL",
-	arm_UHSAX_VS:          "UHSAX.VS",
-	arm_UHSAX_VC:          "UHSAX.VC",
-	arm_UHSAX_HI:          "UHSAX.HI",
-	arm_UHSAX_LS:          "UHSAX.LS",
-	arm_UHSAX_GE:          "UHSAX.GE",
-	arm_UHSAX_LT:          "UHSAX.LT",
-	arm_UHSAX_GT:          "UHSAX.GT",
-	arm_UHSAX_LE:          "UHSAX.LE",
-	arm_UHSAX:             "UHSAX",
-	arm_UHSAX_ZZ:          "UHSAX.ZZ",
-	arm_UHSUB16_EQ:        "UHSUB16.EQ",
-	arm_UHSUB16_NE:        "UHSUB16.NE",
-	arm_UHSUB16_CS:        "UHSUB16.CS",
-	arm_UHSUB16_CC:        "UHSUB16.CC",
-	arm_UHSUB16_MI:        "UHSUB16.MI",
-	arm_UHSUB16_PL:        "UHSUB16.PL",
-	arm_UHSUB16_VS:        "UHSUB16.VS",
-	arm_UHSUB16_VC:        "UHSUB16.VC",
-	arm_UHSUB16_HI:        "UHSUB16.HI",
-	arm_UHSUB16_LS:        "UHSUB16.LS",
-	arm_UHSUB16_GE:        "UHSUB16.GE",
-	arm_UHSUB16_LT:        "UHSUB16.LT",
-	arm_UHSUB16_GT:        "UHSUB16.GT",
-	arm_UHSUB16_LE:        "UHSUB16.LE",
-	arm_UHSUB16:           "UHSUB16",
-	arm_UHSUB16_ZZ:        "UHSUB16.ZZ",
-	arm_UHSUB8_EQ:         "UHSUB8.EQ",
-	arm_UHSUB8_NE:         "UHSUB8.NE",
-	arm_UHSUB8_CS:         "UHSUB8.CS",
-	arm_UHSUB8_CC:         "UHSUB8.CC",
-	arm_UHSUB8_MI:         "UHSUB8.MI",
-	arm_UHSUB8_PL:         "UHSUB8.PL",
-	arm_UHSUB8_VS:         "UHSUB8.VS",
-	arm_UHSUB8_VC:         "UHSUB8.VC",
-	arm_UHSUB8_HI:         "UHSUB8.HI",
-	arm_UHSUB8_LS:         "UHSUB8.LS",
-	arm_UHSUB8_GE:         "UHSUB8.GE",
-	arm_UHSUB8_LT:         "UHSUB8.LT",
-	arm_UHSUB8_GT:         "UHSUB8.GT",
-	arm_UHSUB8_LE:         "UHSUB8.LE",
-	arm_UHSUB8:            "UHSUB8",
-	arm_UHSUB8_ZZ:         "UHSUB8.ZZ",
-	arm_UMAAL_EQ:          "UMAAL.EQ",
-	arm_UMAAL_NE:          "UMAAL.NE",
-	arm_UMAAL_CS:          "UMAAL.CS",
-	arm_UMAAL_CC:          "UMAAL.CC",
-	arm_UMAAL_MI:          "UMAAL.MI",
-	arm_UMAAL_PL:          "UMAAL.PL",
-	arm_UMAAL_VS:          "UMAAL.VS",
-	arm_UMAAL_VC:          "UMAAL.VC",
-	arm_UMAAL_HI:          "UMAAL.HI",
-	arm_UMAAL_LS:          "UMAAL.LS",
-	arm_UMAAL_GE:          "UMAAL.GE",
-	arm_UMAAL_LT:          "UMAAL.LT",
-	arm_UMAAL_GT:          "UMAAL.GT",
-	arm_UMAAL_LE:          "UMAAL.LE",
-	arm_UMAAL:             "UMAAL",
-	arm_UMAAL_ZZ:          "UMAAL.ZZ",
-	arm_UMLAL_EQ:          "UMLAL.EQ",
-	arm_UMLAL_NE:          "UMLAL.NE",
-	arm_UMLAL_CS:          "UMLAL.CS",
-	arm_UMLAL_CC:          "UMLAL.CC",
-	arm_UMLAL_MI:          "UMLAL.MI",
-	arm_UMLAL_PL:          "UMLAL.PL",
-	arm_UMLAL_VS:          "UMLAL.VS",
-	arm_UMLAL_VC:          "UMLAL.VC",
-	arm_UMLAL_HI:          "UMLAL.HI",
-	arm_UMLAL_LS:          "UMLAL.LS",
-	arm_UMLAL_GE:          "UMLAL.GE",
-	arm_UMLAL_LT:          "UMLAL.LT",
-	arm_UMLAL_GT:          "UMLAL.GT",
-	arm_UMLAL_LE:          "UMLAL.LE",
-	arm_UMLAL:             "UMLAL",
-	arm_UMLAL_ZZ:          "UMLAL.ZZ",
-	arm_UMLAL_S_EQ:        "UMLAL.S.EQ",
-	arm_UMLAL_S_NE:        "UMLAL.S.NE",
-	arm_UMLAL_S_CS:        "UMLAL.S.CS",
-	arm_UMLAL_S_CC:        "UMLAL.S.CC",
-	arm_UMLAL_S_MI:        "UMLAL.S.MI",
-	arm_UMLAL_S_PL:        "UMLAL.S.PL",
-	arm_UMLAL_S_VS:        "UMLAL.S.VS",
-	arm_UMLAL_S_VC:        "UMLAL.S.VC",
-	arm_UMLAL_S_HI:        "UMLAL.S.HI",
-	arm_UMLAL_S_LS:        "UMLAL.S.LS",
-	arm_UMLAL_S_GE:        "UMLAL.S.GE",
-	arm_UMLAL_S_LT:        "UMLAL.S.LT",
-	arm_UMLAL_S_GT:        "UMLAL.S.GT",
-	arm_UMLAL_S_LE:        "UMLAL.S.LE",
-	arm_UMLAL_S:           "UMLAL.S",
-	arm_UMLAL_S_ZZ:        "UMLAL.S.ZZ",
-	arm_UMULL_EQ:          "UMULL.EQ",
-	arm_UMULL_NE:          "UMULL.NE",
-	arm_UMULL_CS:          "UMULL.CS",
-	arm_UMULL_CC:          "UMULL.CC",
-	arm_UMULL_MI:          "UMULL.MI",
-	arm_UMULL_PL:          "UMULL.PL",
-	arm_UMULL_VS:          "UMULL.VS",
-	arm_UMULL_VC:          "UMULL.VC",
-	arm_UMULL_HI:          "UMULL.HI",
-	arm_UMULL_LS:          "UMULL.LS",
-	arm_UMULL_GE:          "UMULL.GE",
-	arm_UMULL_LT:          "UMULL.LT",
-	arm_UMULL_GT:          "UMULL.GT",
-	arm_UMULL_LE:          "UMULL.LE",
-	arm_UMULL:             "UMULL",
-	arm_UMULL_ZZ:          "UMULL.ZZ",
-	arm_UMULL_S_EQ:        "UMULL.S.EQ",
-	arm_UMULL_S_NE:        "UMULL.S.NE",
-	arm_UMULL_S_CS:        "UMULL.S.CS",
-	arm_UMULL_S_CC:        "UMULL.S.CC",
-	arm_UMULL_S_MI:        "UMULL.S.MI",
-	arm_UMULL_S_PL:        "UMULL.S.PL",
-	arm_UMULL_S_VS:        "UMULL.S.VS",
-	arm_UMULL_S_VC:        "UMULL.S.VC",
-	arm_UMULL_S_HI:        "UMULL.S.HI",
-	arm_UMULL_S_LS:        "UMULL.S.LS",
-	arm_UMULL_S_GE:        "UMULL.S.GE",
-	arm_UMULL_S_LT:        "UMULL.S.LT",
-	arm_UMULL_S_GT:        "UMULL.S.GT",
-	arm_UMULL_S_LE:        "UMULL.S.LE",
-	arm_UMULL_S:           "UMULL.S",
-	arm_UMULL_S_ZZ:        "UMULL.S.ZZ",
-	arm_UNDEF:             "UNDEF",
-	arm_UQADD16_EQ:        "UQADD16.EQ",
-	arm_UQADD16_NE:        "UQADD16.NE",
-	arm_UQADD16_CS:        "UQADD16.CS",
-	arm_UQADD16_CC:        "UQADD16.CC",
-	arm_UQADD16_MI:        "UQADD16.MI",
-	arm_UQADD16_PL:        "UQADD16.PL",
-	arm_UQADD16_VS:        "UQADD16.VS",
-	arm_UQADD16_VC:        "UQADD16.VC",
-	arm_UQADD16_HI:        "UQADD16.HI",
-	arm_UQADD16_LS:        "UQADD16.LS",
-	arm_UQADD16_GE:        "UQADD16.GE",
-	arm_UQADD16_LT:        "UQADD16.LT",
-	arm_UQADD16_GT:        "UQADD16.GT",
-	arm_UQADD16_LE:        "UQADD16.LE",
-	arm_UQADD16:           "UQADD16",
-	arm_UQADD16_ZZ:        "UQADD16.ZZ",
-	arm_UQADD8_EQ:         "UQADD8.EQ",
-	arm_UQADD8_NE:         "UQADD8.NE",
-	arm_UQADD8_CS:         "UQADD8.CS",
-	arm_UQADD8_CC:         "UQADD8.CC",
-	arm_UQADD8_MI:         "UQADD8.MI",
-	arm_UQADD8_PL:         "UQADD8.PL",
-	arm_UQADD8_VS:         "UQADD8.VS",
-	arm_UQADD8_VC:         "UQADD8.VC",
-	arm_UQADD8_HI:         "UQADD8.HI",
-	arm_UQADD8_LS:         "UQADD8.LS",
-	arm_UQADD8_GE:         "UQADD8.GE",
-	arm_UQADD8_LT:         "UQADD8.LT",
-	arm_UQADD8_GT:         "UQADD8.GT",
-	arm_UQADD8_LE:         "UQADD8.LE",
-	arm_UQADD8:            "UQADD8",
-	arm_UQADD8_ZZ:         "UQADD8.ZZ",
-	arm_UQASX_EQ:          "UQASX.EQ",
-	arm_UQASX_NE:          "UQASX.NE",
-	arm_UQASX_CS:          "UQASX.CS",
-	arm_UQASX_CC:          "UQASX.CC",
-	arm_UQASX_MI:          "UQASX.MI",
-	arm_UQASX_PL:          "UQASX.PL",
-	arm_UQASX_VS:          "UQASX.VS",
-	arm_UQASX_VC:          "UQASX.VC",
-	arm_UQASX_HI:          "UQASX.HI",
-	arm_UQASX_LS:          "UQASX.LS",
-	arm_UQASX_GE:          "UQASX.GE",
-	arm_UQASX_LT:          "UQASX.LT",
-	arm_UQASX_GT:          "UQASX.GT",
-	arm_UQASX_LE:          "UQASX.LE",
-	arm_UQASX:             "UQASX",
-	arm_UQASX_ZZ:          "UQASX.ZZ",
-	arm_UQSAX_EQ:          "UQSAX.EQ",
-	arm_UQSAX_NE:          "UQSAX.NE",
-	arm_UQSAX_CS:          "UQSAX.CS",
-	arm_UQSAX_CC:          "UQSAX.CC",
-	arm_UQSAX_MI:          "UQSAX.MI",
-	arm_UQSAX_PL:          "UQSAX.PL",
-	arm_UQSAX_VS:          "UQSAX.VS",
-	arm_UQSAX_VC:          "UQSAX.VC",
-	arm_UQSAX_HI:          "UQSAX.HI",
-	arm_UQSAX_LS:          "UQSAX.LS",
-	arm_UQSAX_GE:          "UQSAX.GE",
-	arm_UQSAX_LT:          "UQSAX.LT",
-	arm_UQSAX_GT:          "UQSAX.GT",
-	arm_UQSAX_LE:          "UQSAX.LE",
-	arm_UQSAX:             "UQSAX",
-	arm_UQSAX_ZZ:          "UQSAX.ZZ",
-	arm_UQSUB16_EQ:        "UQSUB16.EQ",
-	arm_UQSUB16_NE:        "UQSUB16.NE",
-	arm_UQSUB16_CS:        "UQSUB16.CS",
-	arm_UQSUB16_CC:        "UQSUB16.CC",
-	arm_UQSUB16_MI:        "UQSUB16.MI",
-	arm_UQSUB16_PL:        "UQSUB16.PL",
-	arm_UQSUB16_VS:        "UQSUB16.VS",
-	arm_UQSUB16_VC:        "UQSUB16.VC",
-	arm_UQSUB16_HI:        "UQSUB16.HI",
-	arm_UQSUB16_LS:        "UQSUB16.LS",
-	arm_UQSUB16_GE:        "UQSUB16.GE",
-	arm_UQSUB16_LT:        "UQSUB16.LT",
-	arm_UQSUB16_GT:        "UQSUB16.GT",
-	arm_UQSUB16_LE:        "UQSUB16.LE",
-	arm_UQSUB16:           "UQSUB16",
-	arm_UQSUB16_ZZ:        "UQSUB16.ZZ",
-	arm_UQSUB8_EQ:         "UQSUB8.EQ",
-	arm_UQSUB8_NE:         "UQSUB8.NE",
-	arm_UQSUB8_CS:         "UQSUB8.CS",
-	arm_UQSUB8_CC:         "UQSUB8.CC",
-	arm_UQSUB8_MI:         "UQSUB8.MI",
-	arm_UQSUB8_PL:         "UQSUB8.PL",
-	arm_UQSUB8_VS:         "UQSUB8.VS",
-	arm_UQSUB8_VC:         "UQSUB8.VC",
-	arm_UQSUB8_HI:         "UQSUB8.HI",
-	arm_UQSUB8_LS:         "UQSUB8.LS",
-	arm_UQSUB8_GE:         "UQSUB8.GE",
-	arm_UQSUB8_LT:         "UQSUB8.LT",
-	arm_UQSUB8_GT:         "UQSUB8.GT",
-	arm_UQSUB8_LE:         "UQSUB8.LE",
-	arm_UQSUB8:            "UQSUB8",
-	arm_UQSUB8_ZZ:         "UQSUB8.ZZ",
-	arm_USAD8_EQ:          "USAD8.EQ",
-	arm_USAD8_NE:          "USAD8.NE",
-	arm_USAD8_CS:          "USAD8.CS",
-	arm_USAD8_CC:          "USAD8.CC",
-	arm_USAD8_MI:          "USAD8.MI",
-	arm_USAD8_PL:          "USAD8.PL",
-	arm_USAD8_VS:          "USAD8.VS",
-	arm_USAD8_VC:          "USAD8.VC",
-	arm_USAD8_HI:          "USAD8.HI",
-	arm_USAD8_LS:          "USAD8.LS",
-	arm_USAD8_GE:          "USAD8.GE",
-	arm_USAD8_LT:          "USAD8.LT",
-	arm_USAD8_GT:          "USAD8.GT",
-	arm_USAD8_LE:          "USAD8.LE",
-	arm_USAD8:             "USAD8",
-	arm_USAD8_ZZ:          "USAD8.ZZ",
-	arm_USADA8_EQ:         "USADA8.EQ",
-	arm_USADA8_NE:         "USADA8.NE",
-	arm_USADA8_CS:         "USADA8.CS",
-	arm_USADA8_CC:         "USADA8.CC",
-	arm_USADA8_MI:         "USADA8.MI",
-	arm_USADA8_PL:         "USADA8.PL",
-	arm_USADA8_VS:         "USADA8.VS",
-	arm_USADA8_VC:         "USADA8.VC",
-	arm_USADA8_HI:         "USADA8.HI",
-	arm_USADA8_LS:         "USADA8.LS",
-	arm_USADA8_GE:         "USADA8.GE",
-	arm_USADA8_LT:         "USADA8.LT",
-	arm_USADA8_GT:         "USADA8.GT",
-	arm_USADA8_LE:         "USADA8.LE",
-	arm_USADA8:            "USADA8",
-	arm_USADA8_ZZ:         "USADA8.ZZ",
-	arm_USAT_EQ:           "USAT.EQ",
-	arm_USAT_NE:           "USAT.NE",
-	arm_USAT_CS:           "USAT.CS",
-	arm_USAT_CC:           "USAT.CC",
-	arm_USAT_MI:           "USAT.MI",
-	arm_USAT_PL:           "USAT.PL",
-	arm_USAT_VS:           "USAT.VS",
-	arm_USAT_VC:           "USAT.VC",
-	arm_USAT_HI:           "USAT.HI",
-	arm_USAT_LS:           "USAT.LS",
-	arm_USAT_GE:           "USAT.GE",
-	arm_USAT_LT:           "USAT.LT",
-	arm_USAT_GT:           "USAT.GT",
-	arm_USAT_LE:           "USAT.LE",
-	arm_USAT:              "USAT",
-	arm_USAT_ZZ:           "USAT.ZZ",
-	arm_USAT16_EQ:         "USAT16.EQ",
-	arm_USAT16_NE:         "USAT16.NE",
-	arm_USAT16_CS:         "USAT16.CS",
-	arm_USAT16_CC:         "USAT16.CC",
-	arm_USAT16_MI:         "USAT16.MI",
-	arm_USAT16_PL:         "USAT16.PL",
-	arm_USAT16_VS:         "USAT16.VS",
-	arm_USAT16_VC:         "USAT16.VC",
-	arm_USAT16_HI:         "USAT16.HI",
-	arm_USAT16_LS:         "USAT16.LS",
-	arm_USAT16_GE:         "USAT16.GE",
-	arm_USAT16_LT:         "USAT16.LT",
-	arm_USAT16_GT:         "USAT16.GT",
-	arm_USAT16_LE:         "USAT16.LE",
-	arm_USAT16:            "USAT16",
-	arm_USAT16_ZZ:         "USAT16.ZZ",
-	arm_USAX_EQ:           "USAX.EQ",
-	arm_USAX_NE:           "USAX.NE",
-	arm_USAX_CS:           "USAX.CS",
-	arm_USAX_CC:           "USAX.CC",
-	arm_USAX_MI:           "USAX.MI",
-	arm_USAX_PL:           "USAX.PL",
-	arm_USAX_VS:           "USAX.VS",
-	arm_USAX_VC:           "USAX.VC",
-	arm_USAX_HI:           "USAX.HI",
-	arm_USAX_LS:           "USAX.LS",
-	arm_USAX_GE:           "USAX.GE",
-	arm_USAX_LT:           "USAX.LT",
-	arm_USAX_GT:           "USAX.GT",
-	arm_USAX_LE:           "USAX.LE",
-	arm_USAX:              "USAX",
-	arm_USAX_ZZ:           "USAX.ZZ",
-	arm_USUB16_EQ:         "USUB16.EQ",
-	arm_USUB16_NE:         "USUB16.NE",
-	arm_USUB16_CS:         "USUB16.CS",
-	arm_USUB16_CC:         "USUB16.CC",
-	arm_USUB16_MI:         "USUB16.MI",
-	arm_USUB16_PL:         "USUB16.PL",
-	arm_USUB16_VS:         "USUB16.VS",
-	arm_USUB16_VC:         "USUB16.VC",
-	arm_USUB16_HI:         "USUB16.HI",
-	arm_USUB16_LS:         "USUB16.LS",
-	arm_USUB16_GE:         "USUB16.GE",
-	arm_USUB16_LT:         "USUB16.LT",
-	arm_USUB16_GT:         "USUB16.GT",
-	arm_USUB16_LE:         "USUB16.LE",
-	arm_USUB16:            "USUB16",
-	arm_USUB16_ZZ:         "USUB16.ZZ",
-	arm_USUB8_EQ:          "USUB8.EQ",
-	arm_USUB8_NE:          "USUB8.NE",
-	arm_USUB8_CS:          "USUB8.CS",
-	arm_USUB8_CC:          "USUB8.CC",
-	arm_USUB8_MI:          "USUB8.MI",
-	arm_USUB8_PL:          "USUB8.PL",
-	arm_USUB8_VS:          "USUB8.VS",
-	arm_USUB8_VC:          "USUB8.VC",
-	arm_USUB8_HI:          "USUB8.HI",
-	arm_USUB8_LS:          "USUB8.LS",
-	arm_USUB8_GE:          "USUB8.GE",
-	arm_USUB8_LT:          "USUB8.LT",
-	arm_USUB8_GT:          "USUB8.GT",
-	arm_USUB8_LE:          "USUB8.LE",
-	arm_USUB8:             "USUB8",
-	arm_USUB8_ZZ:          "USUB8.ZZ",
-	arm_UXTAB_EQ:          "UXTAB.EQ",
-	arm_UXTAB_NE:          "UXTAB.NE",
-	arm_UXTAB_CS:          "UXTAB.CS",
-	arm_UXTAB_CC:          "UXTAB.CC",
-	arm_UXTAB_MI:          "UXTAB.MI",
-	arm_UXTAB_PL:          "UXTAB.PL",
-	arm_UXTAB_VS:          "UXTAB.VS",
-	arm_UXTAB_VC:          "UXTAB.VC",
-	arm_UXTAB_HI:          "UXTAB.HI",
-	arm_UXTAB_LS:          "UXTAB.LS",
-	arm_UXTAB_GE:          "UXTAB.GE",
-	arm_UXTAB_LT:          "UXTAB.LT",
-	arm_UXTAB_GT:          "UXTAB.GT",
-	arm_UXTAB_LE:          "UXTAB.LE",
-	arm_UXTAB:             "UXTAB",
-	arm_UXTAB_ZZ:          "UXTAB.ZZ",
-	arm_UXTAB16_EQ:        "UXTAB16.EQ",
-	arm_UXTAB16_NE:        "UXTAB16.NE",
-	arm_UXTAB16_CS:        "UXTAB16.CS",
-	arm_UXTAB16_CC:        "UXTAB16.CC",
-	arm_UXTAB16_MI:        "UXTAB16.MI",
-	arm_UXTAB16_PL:        "UXTAB16.PL",
-	arm_UXTAB16_VS:        "UXTAB16.VS",
-	arm_UXTAB16_VC:        "UXTAB16.VC",
-	arm_UXTAB16_HI:        "UXTAB16.HI",
-	arm_UXTAB16_LS:        "UXTAB16.LS",
-	arm_UXTAB16_GE:        "UXTAB16.GE",
-	arm_UXTAB16_LT:        "UXTAB16.LT",
-	arm_UXTAB16_GT:        "UXTAB16.GT",
-	arm_UXTAB16_LE:        "UXTAB16.LE",
-	arm_UXTAB16:           "UXTAB16",
-	arm_UXTAB16_ZZ:        "UXTAB16.ZZ",
-	arm_UXTAH_EQ:          "UXTAH.EQ",
-	arm_UXTAH_NE:          "UXTAH.NE",
-	arm_UXTAH_CS:          "UXTAH.CS",
-	arm_UXTAH_CC:          "UXTAH.CC",
-	arm_UXTAH_MI:          "UXTAH.MI",
-	arm_UXTAH_PL:          "UXTAH.PL",
-	arm_UXTAH_VS:          "UXTAH.VS",
-	arm_UXTAH_VC:          "UXTAH.VC",
-	arm_UXTAH_HI:          "UXTAH.HI",
-	arm_UXTAH_LS:          "UXTAH.LS",
-	arm_UXTAH_GE:          "UXTAH.GE",
-	arm_UXTAH_LT:          "UXTAH.LT",
-	arm_UXTAH_GT:          "UXTAH.GT",
-	arm_UXTAH_LE:          "UXTAH.LE",
-	arm_UXTAH:             "UXTAH",
-	arm_UXTAH_ZZ:          "UXTAH.ZZ",
-	arm_UXTB_EQ:           "UXTB.EQ",
-	arm_UXTB_NE:           "UXTB.NE",
-	arm_UXTB_CS:           "UXTB.CS",
-	arm_UXTB_CC:           "UXTB.CC",
-	arm_UXTB_MI:           "UXTB.MI",
-	arm_UXTB_PL:           "UXTB.PL",
-	arm_UXTB_VS:           "UXTB.VS",
-	arm_UXTB_VC:           "UXTB.VC",
-	arm_UXTB_HI:           "UXTB.HI",
-	arm_UXTB_LS:           "UXTB.LS",
-	arm_UXTB_GE:           "UXTB.GE",
-	arm_UXTB_LT:           "UXTB.LT",
-	arm_UXTB_GT:           "UXTB.GT",
-	arm_UXTB_LE:           "UXTB.LE",
-	arm_UXTB:              "UXTB",
-	arm_UXTB_ZZ:           "UXTB.ZZ",
-	arm_UXTB16_EQ:         "UXTB16.EQ",
-	arm_UXTB16_NE:         "UXTB16.NE",
-	arm_UXTB16_CS:         "UXTB16.CS",
-	arm_UXTB16_CC:         "UXTB16.CC",
-	arm_UXTB16_MI:         "UXTB16.MI",
-	arm_UXTB16_PL:         "UXTB16.PL",
-	arm_UXTB16_VS:         "UXTB16.VS",
-	arm_UXTB16_VC:         "UXTB16.VC",
-	arm_UXTB16_HI:         "UXTB16.HI",
-	arm_UXTB16_LS:         "UXTB16.LS",
-	arm_UXTB16_GE:         "UXTB16.GE",
-	arm_UXTB16_LT:         "UXTB16.LT",
-	arm_UXTB16_GT:         "UXTB16.GT",
-	arm_UXTB16_LE:         "UXTB16.LE",
-	arm_UXTB16:            "UXTB16",
-	arm_UXTB16_ZZ:         "UXTB16.ZZ",
-	arm_UXTH_EQ:           "UXTH.EQ",
-	arm_UXTH_NE:           "UXTH.NE",
-	arm_UXTH_CS:           "UXTH.CS",
-	arm_UXTH_CC:           "UXTH.CC",
-	arm_UXTH_MI:           "UXTH.MI",
-	arm_UXTH_PL:           "UXTH.PL",
-	arm_UXTH_VS:           "UXTH.VS",
-	arm_UXTH_VC:           "UXTH.VC",
-	arm_UXTH_HI:           "UXTH.HI",
-	arm_UXTH_LS:           "UXTH.LS",
-	arm_UXTH_GE:           "UXTH.GE",
-	arm_UXTH_LT:           "UXTH.LT",
-	arm_UXTH_GT:           "UXTH.GT",
-	arm_UXTH_LE:           "UXTH.LE",
-	arm_UXTH:              "UXTH",
-	arm_UXTH_ZZ:           "UXTH.ZZ",
-	arm_VABS_EQ_F32:       "VABS.EQ.F32",
-	arm_VABS_NE_F32:       "VABS.NE.F32",
-	arm_VABS_CS_F32:       "VABS.CS.F32",
-	arm_VABS_CC_F32:       "VABS.CC.F32",
-	arm_VABS_MI_F32:       "VABS.MI.F32",
-	arm_VABS_PL_F32:       "VABS.PL.F32",
-	arm_VABS_VS_F32:       "VABS.VS.F32",
-	arm_VABS_VC_F32:       "VABS.VC.F32",
-	arm_VABS_HI_F32:       "VABS.HI.F32",
-	arm_VABS_LS_F32:       "VABS.LS.F32",
-	arm_VABS_GE_F32:       "VABS.GE.F32",
-	arm_VABS_LT_F32:       "VABS.LT.F32",
-	arm_VABS_GT_F32:       "VABS.GT.F32",
-	arm_VABS_LE_F32:       "VABS.LE.F32",
-	arm_VABS_F32:          "VABS.F32",
-	arm_VABS_ZZ_F32:       "VABS.ZZ.F32",
-	arm_VABS_EQ_F64:       "VABS.EQ.F64",
-	arm_VABS_NE_F64:       "VABS.NE.F64",
-	arm_VABS_CS_F64:       "VABS.CS.F64",
-	arm_VABS_CC_F64:       "VABS.CC.F64",
-	arm_VABS_MI_F64:       "VABS.MI.F64",
-	arm_VABS_PL_F64:       "VABS.PL.F64",
-	arm_VABS_VS_F64:       "VABS.VS.F64",
-	arm_VABS_VC_F64:       "VABS.VC.F64",
-	arm_VABS_HI_F64:       "VABS.HI.F64",
-	arm_VABS_LS_F64:       "VABS.LS.F64",
-	arm_VABS_GE_F64:       "VABS.GE.F64",
-	arm_VABS_LT_F64:       "VABS.LT.F64",
-	arm_VABS_GT_F64:       "VABS.GT.F64",
-	arm_VABS_LE_F64:       "VABS.LE.F64",
-	arm_VABS_F64:          "VABS.F64",
-	arm_VABS_ZZ_F64:       "VABS.ZZ.F64",
-	arm_VADD_EQ_F32:       "VADD.EQ.F32",
-	arm_VADD_NE_F32:       "VADD.NE.F32",
-	arm_VADD_CS_F32:       "VADD.CS.F32",
-	arm_VADD_CC_F32:       "VADD.CC.F32",
-	arm_VADD_MI_F32:       "VADD.MI.F32",
-	arm_VADD_PL_F32:       "VADD.PL.F32",
-	arm_VADD_VS_F32:       "VADD.VS.F32",
-	arm_VADD_VC_F32:       "VADD.VC.F32",
-	arm_VADD_HI_F32:       "VADD.HI.F32",
-	arm_VADD_LS_F32:       "VADD.LS.F32",
-	arm_VADD_GE_F32:       "VADD.GE.F32",
-	arm_VADD_LT_F32:       "VADD.LT.F32",
-	arm_VADD_GT_F32:       "VADD.GT.F32",
-	arm_VADD_LE_F32:       "VADD.LE.F32",
-	arm_VADD_F32:          "VADD.F32",
-	arm_VADD_ZZ_F32:       "VADD.ZZ.F32",
-	arm_VADD_EQ_F64:       "VADD.EQ.F64",
-	arm_VADD_NE_F64:       "VADD.NE.F64",
-	arm_VADD_CS_F64:       "VADD.CS.F64",
-	arm_VADD_CC_F64:       "VADD.CC.F64",
-	arm_VADD_MI_F64:       "VADD.MI.F64",
-	arm_VADD_PL_F64:       "VADD.PL.F64",
-	arm_VADD_VS_F64:       "VADD.VS.F64",
-	arm_VADD_VC_F64:       "VADD.VC.F64",
-	arm_VADD_HI_F64:       "VADD.HI.F64",
-	arm_VADD_LS_F64:       "VADD.LS.F64",
-	arm_VADD_GE_F64:       "VADD.GE.F64",
-	arm_VADD_LT_F64:       "VADD.LT.F64",
-	arm_VADD_GT_F64:       "VADD.GT.F64",
-	arm_VADD_LE_F64:       "VADD.LE.F64",
-	arm_VADD_F64:          "VADD.F64",
-	arm_VADD_ZZ_F64:       "VADD.ZZ.F64",
-	arm_VCMP_EQ_F32:       "VCMP.EQ.F32",
-	arm_VCMP_NE_F32:       "VCMP.NE.F32",
-	arm_VCMP_CS_F32:       "VCMP.CS.F32",
-	arm_VCMP_CC_F32:       "VCMP.CC.F32",
-	arm_VCMP_MI_F32:       "VCMP.MI.F32",
-	arm_VCMP_PL_F32:       "VCMP.PL.F32",
-	arm_VCMP_VS_F32:       "VCMP.VS.F32",
-	arm_VCMP_VC_F32:       "VCMP.VC.F32",
-	arm_VCMP_HI_F32:       "VCMP.HI.F32",
-	arm_VCMP_LS_F32:       "VCMP.LS.F32",
-	arm_VCMP_GE_F32:       "VCMP.GE.F32",
-	arm_VCMP_LT_F32:       "VCMP.LT.F32",
-	arm_VCMP_GT_F32:       "VCMP.GT.F32",
-	arm_VCMP_LE_F32:       "VCMP.LE.F32",
-	arm_VCMP_F32:          "VCMP.F32",
-	arm_VCMP_ZZ_F32:       "VCMP.ZZ.F32",
-	arm_VCMP_EQ_F64:       "VCMP.EQ.F64",
-	arm_VCMP_NE_F64:       "VCMP.NE.F64",
-	arm_VCMP_CS_F64:       "VCMP.CS.F64",
-	arm_VCMP_CC_F64:       "VCMP.CC.F64",
-	arm_VCMP_MI_F64:       "VCMP.MI.F64",
-	arm_VCMP_PL_F64:       "VCMP.PL.F64",
-	arm_VCMP_VS_F64:       "VCMP.VS.F64",
-	arm_VCMP_VC_F64:       "VCMP.VC.F64",
-	arm_VCMP_HI_F64:       "VCMP.HI.F64",
-	arm_VCMP_LS_F64:       "VCMP.LS.F64",
-	arm_VCMP_GE_F64:       "VCMP.GE.F64",
-	arm_VCMP_LT_F64:       "VCMP.LT.F64",
-	arm_VCMP_GT_F64:       "VCMP.GT.F64",
-	arm_VCMP_LE_F64:       "VCMP.LE.F64",
-	arm_VCMP_F64:          "VCMP.F64",
-	arm_VCMP_ZZ_F64:       "VCMP.ZZ.F64",
-	arm_VCMP_E_EQ_F32:     "VCMP.E.EQ.F32",
-	arm_VCMP_E_NE_F32:     "VCMP.E.NE.F32",
-	arm_VCMP_E_CS_F32:     "VCMP.E.CS.F32",
-	arm_VCMP_E_CC_F32:     "VCMP.E.CC.F32",
-	arm_VCMP_E_MI_F32:     "VCMP.E.MI.F32",
-	arm_VCMP_E_PL_F32:     "VCMP.E.PL.F32",
-	arm_VCMP_E_VS_F32:     "VCMP.E.VS.F32",
-	arm_VCMP_E_VC_F32:     "VCMP.E.VC.F32",
-	arm_VCMP_E_HI_F32:     "VCMP.E.HI.F32",
-	arm_VCMP_E_LS_F32:     "VCMP.E.LS.F32",
-	arm_VCMP_E_GE_F32:     "VCMP.E.GE.F32",
-	arm_VCMP_E_LT_F32:     "VCMP.E.LT.F32",
-	arm_VCMP_E_GT_F32:     "VCMP.E.GT.F32",
-	arm_VCMP_E_LE_F32:     "VCMP.E.LE.F32",
-	arm_VCMP_E_F32:        "VCMP.E.F32",
-	arm_VCMP_E_ZZ_F32:     "VCMP.E.ZZ.F32",
-	arm_VCMP_E_EQ_F64:     "VCMP.E.EQ.F64",
-	arm_VCMP_E_NE_F64:     "VCMP.E.NE.F64",
-	arm_VCMP_E_CS_F64:     "VCMP.E.CS.F64",
-	arm_VCMP_E_CC_F64:     "VCMP.E.CC.F64",
-	arm_VCMP_E_MI_F64:     "VCMP.E.MI.F64",
-	arm_VCMP_E_PL_F64:     "VCMP.E.PL.F64",
-	arm_VCMP_E_VS_F64:     "VCMP.E.VS.F64",
-	arm_VCMP_E_VC_F64:     "VCMP.E.VC.F64",
-	arm_VCMP_E_HI_F64:     "VCMP.E.HI.F64",
-	arm_VCMP_E_LS_F64:     "VCMP.E.LS.F64",
-	arm_VCMP_E_GE_F64:     "VCMP.E.GE.F64",
-	arm_VCMP_E_LT_F64:     "VCMP.E.LT.F64",
-	arm_VCMP_E_GT_F64:     "VCMP.E.GT.F64",
-	arm_VCMP_E_LE_F64:     "VCMP.E.LE.F64",
-	arm_VCMP_E_F64:        "VCMP.E.F64",
-	arm_VCMP_E_ZZ_F64:     "VCMP.E.ZZ.F64",
-	arm_VCVT_EQ_F32_FXS16: "VCVT.EQ.F32.FXS16",
-	arm_VCVT_NE_F32_FXS16: "VCVT.NE.F32.FXS16",
-	arm_VCVT_CS_F32_FXS16: "VCVT.CS.F32.FXS16",
-	arm_VCVT_CC_F32_FXS16: "VCVT.CC.F32.FXS16",
-	arm_VCVT_MI_F32_FXS16: "VCVT.MI.F32.FXS16",
-	arm_VCVT_PL_F32_FXS16: "VCVT.PL.F32.FXS16",
-	arm_VCVT_VS_F32_FXS16: "VCVT.VS.F32.FXS16",
-	arm_VCVT_VC_F32_FXS16: "VCVT.VC.F32.FXS16",
-	arm_VCVT_HI_F32_FXS16: "VCVT.HI.F32.FXS16",
-	arm_VCVT_LS_F32_FXS16: "VCVT.LS.F32.FXS16",
-	arm_VCVT_GE_F32_FXS16: "VCVT.GE.F32.FXS16",
-	arm_VCVT_LT_F32_FXS16: "VCVT.LT.F32.FXS16",
-	arm_VCVT_GT_F32_FXS16: "VCVT.GT.F32.FXS16",
-	arm_VCVT_LE_F32_FXS16: "VCVT.LE.F32.FXS16",
-	arm_VCVT_F32_FXS16:    "VCVT.F32.FXS16",
-	arm_VCVT_ZZ_F32_FXS16: "VCVT.ZZ.F32.FXS16",
-	arm_VCVT_EQ_F32_FXS32: "VCVT.EQ.F32.FXS32",
-	arm_VCVT_NE_F32_FXS32: "VCVT.NE.F32.FXS32",
-	arm_VCVT_CS_F32_FXS32: "VCVT.CS.F32.FXS32",
-	arm_VCVT_CC_F32_FXS32: "VCVT.CC.F32.FXS32",
-	arm_VCVT_MI_F32_FXS32: "VCVT.MI.F32.FXS32",
-	arm_VCVT_PL_F32_FXS32: "VCVT.PL.F32.FXS32",
-	arm_VCVT_VS_F32_FXS32: "VCVT.VS.F32.FXS32",
-	arm_VCVT_VC_F32_FXS32: "VCVT.VC.F32.FXS32",
-	arm_VCVT_HI_F32_FXS32: "VCVT.HI.F32.FXS32",
-	arm_VCVT_LS_F32_FXS32: "VCVT.LS.F32.FXS32",
-	arm_VCVT_GE_F32_FXS32: "VCVT.GE.F32.FXS32",
-	arm_VCVT_LT_F32_FXS32: "VCVT.LT.F32.FXS32",
-	arm_VCVT_GT_F32_FXS32: "VCVT.GT.F32.FXS32",
-	arm_VCVT_LE_F32_FXS32: "VCVT.LE.F32.FXS32",
-	arm_VCVT_F32_FXS32:    "VCVT.F32.FXS32",
-	arm_VCVT_ZZ_F32_FXS32: "VCVT.ZZ.F32.FXS32",
-	arm_VCVT_EQ_F32_FXU16: "VCVT.EQ.F32.FXU16",
-	arm_VCVT_NE_F32_FXU16: "VCVT.NE.F32.FXU16",
-	arm_VCVT_CS_F32_FXU16: "VCVT.CS.F32.FXU16",
-	arm_VCVT_CC_F32_FXU16: "VCVT.CC.F32.FXU16",
-	arm_VCVT_MI_F32_FXU16: "VCVT.MI.F32.FXU16",
-	arm_VCVT_PL_F32_FXU16: "VCVT.PL.F32.FXU16",
-	arm_VCVT_VS_F32_FXU16: "VCVT.VS.F32.FXU16",
-	arm_VCVT_VC_F32_FXU16: "VCVT.VC.F32.FXU16",
-	arm_VCVT_HI_F32_FXU16: "VCVT.HI.F32.FXU16",
-	arm_VCVT_LS_F32_FXU16: "VCVT.LS.F32.FXU16",
-	arm_VCVT_GE_F32_FXU16: "VCVT.GE.F32.FXU16",
-	arm_VCVT_LT_F32_FXU16: "VCVT.LT.F32.FXU16",
-	arm_VCVT_GT_F32_FXU16: "VCVT.GT.F32.FXU16",
-	arm_VCVT_LE_F32_FXU16: "VCVT.LE.F32.FXU16",
-	arm_VCVT_F32_FXU16:    "VCVT.F32.FXU16",
-	arm_VCVT_ZZ_F32_FXU16: "VCVT.ZZ.F32.FXU16",
-	arm_VCVT_EQ_F32_FXU32: "VCVT.EQ.F32.FXU32",
-	arm_VCVT_NE_F32_FXU32: "VCVT.NE.F32.FXU32",
-	arm_VCVT_CS_F32_FXU32: "VCVT.CS.F32.FXU32",
-	arm_VCVT_CC_F32_FXU32: "VCVT.CC.F32.FXU32",
-	arm_VCVT_MI_F32_FXU32: "VCVT.MI.F32.FXU32",
-	arm_VCVT_PL_F32_FXU32: "VCVT.PL.F32.FXU32",
-	arm_VCVT_VS_F32_FXU32: "VCVT.VS.F32.FXU32",
-	arm_VCVT_VC_F32_FXU32: "VCVT.VC.F32.FXU32",
-	arm_VCVT_HI_F32_FXU32: "VCVT.HI.F32.FXU32",
-	arm_VCVT_LS_F32_FXU32: "VCVT.LS.F32.FXU32",
-	arm_VCVT_GE_F32_FXU32: "VCVT.GE.F32.FXU32",
-	arm_VCVT_LT_F32_FXU32: "VCVT.LT.F32.FXU32",
-	arm_VCVT_GT_F32_FXU32: "VCVT.GT.F32.FXU32",
-	arm_VCVT_LE_F32_FXU32: "VCVT.LE.F32.FXU32",
-	arm_VCVT_F32_FXU32:    "VCVT.F32.FXU32",
-	arm_VCVT_ZZ_F32_FXU32: "VCVT.ZZ.F32.FXU32",
-	arm_VCVT_EQ_F64_FXS16: "VCVT.EQ.F64.FXS16",
-	arm_VCVT_NE_F64_FXS16: "VCVT.NE.F64.FXS16",
-	arm_VCVT_CS_F64_FXS16: "VCVT.CS.F64.FXS16",
-	arm_VCVT_CC_F64_FXS16: "VCVT.CC.F64.FXS16",
-	arm_VCVT_MI_F64_FXS16: "VCVT.MI.F64.FXS16",
-	arm_VCVT_PL_F64_FXS16: "VCVT.PL.F64.FXS16",
-	arm_VCVT_VS_F64_FXS16: "VCVT.VS.F64.FXS16",
-	arm_VCVT_VC_F64_FXS16: "VCVT.VC.F64.FXS16",
-	arm_VCVT_HI_F64_FXS16: "VCVT.HI.F64.FXS16",
-	arm_VCVT_LS_F64_FXS16: "VCVT.LS.F64.FXS16",
-	arm_VCVT_GE_F64_FXS16: "VCVT.GE.F64.FXS16",
-	arm_VCVT_LT_F64_FXS16: "VCVT.LT.F64.FXS16",
-	arm_VCVT_GT_F64_FXS16: "VCVT.GT.F64.FXS16",
-	arm_VCVT_LE_F64_FXS16: "VCVT.LE.F64.FXS16",
-	arm_VCVT_F64_FXS16:    "VCVT.F64.FXS16",
-	arm_VCVT_ZZ_F64_FXS16: "VCVT.ZZ.F64.FXS16",
-	arm_VCVT_EQ_F64_FXS32: "VCVT.EQ.F64.FXS32",
-	arm_VCVT_NE_F64_FXS32: "VCVT.NE.F64.FXS32",
-	arm_VCVT_CS_F64_FXS32: "VCVT.CS.F64.FXS32",
-	arm_VCVT_CC_F64_FXS32: "VCVT.CC.F64.FXS32",
-	arm_VCVT_MI_F64_FXS32: "VCVT.MI.F64.FXS32",
-	arm_VCVT_PL_F64_FXS32: "VCVT.PL.F64.FXS32",
-	arm_VCVT_VS_F64_FXS32: "VCVT.VS.F64.FXS32",
-	arm_VCVT_VC_F64_FXS32: "VCVT.VC.F64.FXS32",
-	arm_VCVT_HI_F64_FXS32: "VCVT.HI.F64.FXS32",
-	arm_VCVT_LS_F64_FXS32: "VCVT.LS.F64.FXS32",
-	arm_VCVT_GE_F64_FXS32: "VCVT.GE.F64.FXS32",
-	arm_VCVT_LT_F64_FXS32: "VCVT.LT.F64.FXS32",
-	arm_VCVT_GT_F64_FXS32: "VCVT.GT.F64.FXS32",
-	arm_VCVT_LE_F64_FXS32: "VCVT.LE.F64.FXS32",
-	arm_VCVT_F64_FXS32:    "VCVT.F64.FXS32",
-	arm_VCVT_ZZ_F64_FXS32: "VCVT.ZZ.F64.FXS32",
-	arm_VCVT_EQ_F64_FXU16: "VCVT.EQ.F64.FXU16",
-	arm_VCVT_NE_F64_FXU16: "VCVT.NE.F64.FXU16",
-	arm_VCVT_CS_F64_FXU16: "VCVT.CS.F64.FXU16",
-	arm_VCVT_CC_F64_FXU16: "VCVT.CC.F64.FXU16",
-	arm_VCVT_MI_F64_FXU16: "VCVT.MI.F64.FXU16",
-	arm_VCVT_PL_F64_FXU16: "VCVT.PL.F64.FXU16",
-	arm_VCVT_VS_F64_FXU16: "VCVT.VS.F64.FXU16",
-	arm_VCVT_VC_F64_FXU16: "VCVT.VC.F64.FXU16",
-	arm_VCVT_HI_F64_FXU16: "VCVT.HI.F64.FXU16",
-	arm_VCVT_LS_F64_FXU16: "VCVT.LS.F64.FXU16",
-	arm_VCVT_GE_F64_FXU16: "VCVT.GE.F64.FXU16",
-	arm_VCVT_LT_F64_FXU16: "VCVT.LT.F64.FXU16",
-	arm_VCVT_GT_F64_FXU16: "VCVT.GT.F64.FXU16",
-	arm_VCVT_LE_F64_FXU16: "VCVT.LE.F64.FXU16",
-	arm_VCVT_F64_FXU16:    "VCVT.F64.FXU16",
-	arm_VCVT_ZZ_F64_FXU16: "VCVT.ZZ.F64.FXU16",
-	arm_VCVT_EQ_F64_FXU32: "VCVT.EQ.F64.FXU32",
-	arm_VCVT_NE_F64_FXU32: "VCVT.NE.F64.FXU32",
-	arm_VCVT_CS_F64_FXU32: "VCVT.CS.F64.FXU32",
-	arm_VCVT_CC_F64_FXU32: "VCVT.CC.F64.FXU32",
-	arm_VCVT_MI_F64_FXU32: "VCVT.MI.F64.FXU32",
-	arm_VCVT_PL_F64_FXU32: "VCVT.PL.F64.FXU32",
-	arm_VCVT_VS_F64_FXU32: "VCVT.VS.F64.FXU32",
-	arm_VCVT_VC_F64_FXU32: "VCVT.VC.F64.FXU32",
-	arm_VCVT_HI_F64_FXU32: "VCVT.HI.F64.FXU32",
-	arm_VCVT_LS_F64_FXU32: "VCVT.LS.F64.FXU32",
-	arm_VCVT_GE_F64_FXU32: "VCVT.GE.F64.FXU32",
-	arm_VCVT_LT_F64_FXU32: "VCVT.LT.F64.FXU32",
-	arm_VCVT_GT_F64_FXU32: "VCVT.GT.F64.FXU32",
-	arm_VCVT_LE_F64_FXU32: "VCVT.LE.F64.FXU32",
-	arm_VCVT_F64_FXU32:    "VCVT.F64.FXU32",
-	arm_VCVT_ZZ_F64_FXU32: "VCVT.ZZ.F64.FXU32",
-	arm_VCVT_EQ_F32_U32:   "VCVT.EQ.F32.U32",
-	arm_VCVT_NE_F32_U32:   "VCVT.NE.F32.U32",
-	arm_VCVT_CS_F32_U32:   "VCVT.CS.F32.U32",
-	arm_VCVT_CC_F32_U32:   "VCVT.CC.F32.U32",
-	arm_VCVT_MI_F32_U32:   "VCVT.MI.F32.U32",
-	arm_VCVT_PL_F32_U32:   "VCVT.PL.F32.U32",
-	arm_VCVT_VS_F32_U32:   "VCVT.VS.F32.U32",
-	arm_VCVT_VC_F32_U32:   "VCVT.VC.F32.U32",
-	arm_VCVT_HI_F32_U32:   "VCVT.HI.F32.U32",
-	arm_VCVT_LS_F32_U32:   "VCVT.LS.F32.U32",
-	arm_VCVT_GE_F32_U32:   "VCVT.GE.F32.U32",
-	arm_VCVT_LT_F32_U32:   "VCVT.LT.F32.U32",
-	arm_VCVT_GT_F32_U32:   "VCVT.GT.F32.U32",
-	arm_VCVT_LE_F32_U32:   "VCVT.LE.F32.U32",
-	arm_VCVT_F32_U32:      "VCVT.F32.U32",
-	arm_VCVT_ZZ_F32_U32:   "VCVT.ZZ.F32.U32",
-	arm_VCVT_EQ_F32_S32:   "VCVT.EQ.F32.S32",
-	arm_VCVT_NE_F32_S32:   "VCVT.NE.F32.S32",
-	arm_VCVT_CS_F32_S32:   "VCVT.CS.F32.S32",
-	arm_VCVT_CC_F32_S32:   "VCVT.CC.F32.S32",
-	arm_VCVT_MI_F32_S32:   "VCVT.MI.F32.S32",
-	arm_VCVT_PL_F32_S32:   "VCVT.PL.F32.S32",
-	arm_VCVT_VS_F32_S32:   "VCVT.VS.F32.S32",
-	arm_VCVT_VC_F32_S32:   "VCVT.VC.F32.S32",
-	arm_VCVT_HI_F32_S32:   "VCVT.HI.F32.S32",
-	arm_VCVT_LS_F32_S32:   "VCVT.LS.F32.S32",
-	arm_VCVT_GE_F32_S32:   "VCVT.GE.F32.S32",
-	arm_VCVT_LT_F32_S32:   "VCVT.LT.F32.S32",
-	arm_VCVT_GT_F32_S32:   "VCVT.GT.F32.S32",
-	arm_VCVT_LE_F32_S32:   "VCVT.LE.F32.S32",
-	arm_VCVT_F32_S32:      "VCVT.F32.S32",
-	arm_VCVT_ZZ_F32_S32:   "VCVT.ZZ.F32.S32",
-	arm_VCVT_EQ_F64_U32:   "VCVT.EQ.F64.U32",
-	arm_VCVT_NE_F64_U32:   "VCVT.NE.F64.U32",
-	arm_VCVT_CS_F64_U32:   "VCVT.CS.F64.U32",
-	arm_VCVT_CC_F64_U32:   "VCVT.CC.F64.U32",
-	arm_VCVT_MI_F64_U32:   "VCVT.MI.F64.U32",
-	arm_VCVT_PL_F64_U32:   "VCVT.PL.F64.U32",
-	arm_VCVT_VS_F64_U32:   "VCVT.VS.F64.U32",
-	arm_VCVT_VC_F64_U32:   "VCVT.VC.F64.U32",
-	arm_VCVT_HI_F64_U32:   "VCVT.HI.F64.U32",
-	arm_VCVT_LS_F64_U32:   "VCVT.LS.F64.U32",
-	arm_VCVT_GE_F64_U32:   "VCVT.GE.F64.U32",
-	arm_VCVT_LT_F64_U32:   "VCVT.LT.F64.U32",
-	arm_VCVT_GT_F64_U32:   "VCVT.GT.F64.U32",
-	arm_VCVT_LE_F64_U32:   "VCVT.LE.F64.U32",
-	arm_VCVT_F64_U32:      "VCVT.F64.U32",
-	arm_VCVT_ZZ_F64_U32:   "VCVT.ZZ.F64.U32",
-	arm_VCVT_EQ_F64_S32:   "VCVT.EQ.F64.S32",
-	arm_VCVT_NE_F64_S32:   "VCVT.NE.F64.S32",
-	arm_VCVT_CS_F64_S32:   "VCVT.CS.F64.S32",
-	arm_VCVT_CC_F64_S32:   "VCVT.CC.F64.S32",
-	arm_VCVT_MI_F64_S32:   "VCVT.MI.F64.S32",
-	arm_VCVT_PL_F64_S32:   "VCVT.PL.F64.S32",
-	arm_VCVT_VS_F64_S32:   "VCVT.VS.F64.S32",
-	arm_VCVT_VC_F64_S32:   "VCVT.VC.F64.S32",
-	arm_VCVT_HI_F64_S32:   "VCVT.HI.F64.S32",
-	arm_VCVT_LS_F64_S32:   "VCVT.LS.F64.S32",
-	arm_VCVT_GE_F64_S32:   "VCVT.GE.F64.S32",
-	arm_VCVT_LT_F64_S32:   "VCVT.LT.F64.S32",
-	arm_VCVT_GT_F64_S32:   "VCVT.GT.F64.S32",
-	arm_VCVT_LE_F64_S32:   "VCVT.LE.F64.S32",
-	arm_VCVT_F64_S32:      "VCVT.F64.S32",
-	arm_VCVT_ZZ_F64_S32:   "VCVT.ZZ.F64.S32",
-	arm_VCVT_EQ_F64_F32:   "VCVT.EQ.F64.F32",
-	arm_VCVT_NE_F64_F32:   "VCVT.NE.F64.F32",
-	arm_VCVT_CS_F64_F32:   "VCVT.CS.F64.F32",
-	arm_VCVT_CC_F64_F32:   "VCVT.CC.F64.F32",
-	arm_VCVT_MI_F64_F32:   "VCVT.MI.F64.F32",
-	arm_VCVT_PL_F64_F32:   "VCVT.PL.F64.F32",
-	arm_VCVT_VS_F64_F32:   "VCVT.VS.F64.F32",
-	arm_VCVT_VC_F64_F32:   "VCVT.VC.F64.F32",
-	arm_VCVT_HI_F64_F32:   "VCVT.HI.F64.F32",
-	arm_VCVT_LS_F64_F32:   "VCVT.LS.F64.F32",
-	arm_VCVT_GE_F64_F32:   "VCVT.GE.F64.F32",
-	arm_VCVT_LT_F64_F32:   "VCVT.LT.F64.F32",
-	arm_VCVT_GT_F64_F32:   "VCVT.GT.F64.F32",
-	arm_VCVT_LE_F64_F32:   "VCVT.LE.F64.F32",
-	arm_VCVT_F64_F32:      "VCVT.F64.F32",
-	arm_VCVT_ZZ_F64_F32:   "VCVT.ZZ.F64.F32",
-	arm_VCVT_EQ_F32_F64:   "VCVT.EQ.F32.F64",
-	arm_VCVT_NE_F32_F64:   "VCVT.NE.F32.F64",
-	arm_VCVT_CS_F32_F64:   "VCVT.CS.F32.F64",
-	arm_VCVT_CC_F32_F64:   "VCVT.CC.F32.F64",
-	arm_VCVT_MI_F32_F64:   "VCVT.MI.F32.F64",
-	arm_VCVT_PL_F32_F64:   "VCVT.PL.F32.F64",
-	arm_VCVT_VS_F32_F64:   "VCVT.VS.F32.F64",
-	arm_VCVT_VC_F32_F64:   "VCVT.VC.F32.F64",
-	arm_VCVT_HI_F32_F64:   "VCVT.HI.F32.F64",
-	arm_VCVT_LS_F32_F64:   "VCVT.LS.F32.F64",
-	arm_VCVT_GE_F32_F64:   "VCVT.GE.F32.F64",
-	arm_VCVT_LT_F32_F64:   "VCVT.LT.F32.F64",
-	arm_VCVT_GT_F32_F64:   "VCVT.GT.F32.F64",
-	arm_VCVT_LE_F32_F64:   "VCVT.LE.F32.F64",
-	arm_VCVT_F32_F64:      "VCVT.F32.F64",
-	arm_VCVT_ZZ_F32_F64:   "VCVT.ZZ.F32.F64",
-	arm_VCVT_EQ_FXS16_F32: "VCVT.EQ.FXS16.F32",
-	arm_VCVT_NE_FXS16_F32: "VCVT.NE.FXS16.F32",
-	arm_VCVT_CS_FXS16_F32: "VCVT.CS.FXS16.F32",
-	arm_VCVT_CC_FXS16_F32: "VCVT.CC.FXS16.F32",
-	arm_VCVT_MI_FXS16_F32: "VCVT.MI.FXS16.F32",
-	arm_VCVT_PL_FXS16_F32: "VCVT.PL.FXS16.F32",
-	arm_VCVT_VS_FXS16_F32: "VCVT.VS.FXS16.F32",
-	arm_VCVT_VC_FXS16_F32: "VCVT.VC.FXS16.F32",
-	arm_VCVT_HI_FXS16_F32: "VCVT.HI.FXS16.F32",
-	arm_VCVT_LS_FXS16_F32: "VCVT.LS.FXS16.F32",
-	arm_VCVT_GE_FXS16_F32: "VCVT.GE.FXS16.F32",
-	arm_VCVT_LT_FXS16_F32: "VCVT.LT.FXS16.F32",
-	arm_VCVT_GT_FXS16_F32: "VCVT.GT.FXS16.F32",
-	arm_VCVT_LE_FXS16_F32: "VCVT.LE.FXS16.F32",
-	arm_VCVT_FXS16_F32:    "VCVT.FXS16.F32",
-	arm_VCVT_ZZ_FXS16_F32: "VCVT.ZZ.FXS16.F32",
-	arm_VCVT_EQ_FXS16_F64: "VCVT.EQ.FXS16.F64",
-	arm_VCVT_NE_FXS16_F64: "VCVT.NE.FXS16.F64",
-	arm_VCVT_CS_FXS16_F64: "VCVT.CS.FXS16.F64",
-	arm_VCVT_CC_FXS16_F64: "VCVT.CC.FXS16.F64",
-	arm_VCVT_MI_FXS16_F64: "VCVT.MI.FXS16.F64",
-	arm_VCVT_PL_FXS16_F64: "VCVT.PL.FXS16.F64",
-	arm_VCVT_VS_FXS16_F64: "VCVT.VS.FXS16.F64",
-	arm_VCVT_VC_FXS16_F64: "VCVT.VC.FXS16.F64",
-	arm_VCVT_HI_FXS16_F64: "VCVT.HI.FXS16.F64",
-	arm_VCVT_LS_FXS16_F64: "VCVT.LS.FXS16.F64",
-	arm_VCVT_GE_FXS16_F64: "VCVT.GE.FXS16.F64",
-	arm_VCVT_LT_FXS16_F64: "VCVT.LT.FXS16.F64",
-	arm_VCVT_GT_FXS16_F64: "VCVT.GT.FXS16.F64",
-	arm_VCVT_LE_FXS16_F64: "VCVT.LE.FXS16.F64",
-	arm_VCVT_FXS16_F64:    "VCVT.FXS16.F64",
-	arm_VCVT_ZZ_FXS16_F64: "VCVT.ZZ.FXS16.F64",
-	arm_VCVT_EQ_FXS32_F32: "VCVT.EQ.FXS32.F32",
-	arm_VCVT_NE_FXS32_F32: "VCVT.NE.FXS32.F32",
-	arm_VCVT_CS_FXS32_F32: "VCVT.CS.FXS32.F32",
-	arm_VCVT_CC_FXS32_F32: "VCVT.CC.FXS32.F32",
-	arm_VCVT_MI_FXS32_F32: "VCVT.MI.FXS32.F32",
-	arm_VCVT_PL_FXS32_F32: "VCVT.PL.FXS32.F32",
-	arm_VCVT_VS_FXS32_F32: "VCVT.VS.FXS32.F32",
-	arm_VCVT_VC_FXS32_F32: "VCVT.VC.FXS32.F32",
-	arm_VCVT_HI_FXS32_F32: "VCVT.HI.FXS32.F32",
-	arm_VCVT_LS_FXS32_F32: "VCVT.LS.FXS32.F32",
-	arm_VCVT_GE_FXS32_F32: "VCVT.GE.FXS32.F32",
-	arm_VCVT_LT_FXS32_F32: "VCVT.LT.FXS32.F32",
-	arm_VCVT_GT_FXS32_F32: "VCVT.GT.FXS32.F32",
-	arm_VCVT_LE_FXS32_F32: "VCVT.LE.FXS32.F32",
-	arm_VCVT_FXS32_F32:    "VCVT.FXS32.F32",
-	arm_VCVT_ZZ_FXS32_F32: "VCVT.ZZ.FXS32.F32",
-	arm_VCVT_EQ_FXS32_F64: "VCVT.EQ.FXS32.F64",
-	arm_VCVT_NE_FXS32_F64: "VCVT.NE.FXS32.F64",
-	arm_VCVT_CS_FXS32_F64: "VCVT.CS.FXS32.F64",
-	arm_VCVT_CC_FXS32_F64: "VCVT.CC.FXS32.F64",
-	arm_VCVT_MI_FXS32_F64: "VCVT.MI.FXS32.F64",
-	arm_VCVT_PL_FXS32_F64: "VCVT.PL.FXS32.F64",
-	arm_VCVT_VS_FXS32_F64: "VCVT.VS.FXS32.F64",
-	arm_VCVT_VC_FXS32_F64: "VCVT.VC.FXS32.F64",
-	arm_VCVT_HI_FXS32_F64: "VCVT.HI.FXS32.F64",
-	arm_VCVT_LS_FXS32_F64: "VCVT.LS.FXS32.F64",
-	arm_VCVT_GE_FXS32_F64: "VCVT.GE.FXS32.F64",
-	arm_VCVT_LT_FXS32_F64: "VCVT.LT.FXS32.F64",
-	arm_VCVT_GT_FXS32_F64: "VCVT.GT.FXS32.F64",
-	arm_VCVT_LE_FXS32_F64: "VCVT.LE.FXS32.F64",
-	arm_VCVT_FXS32_F64:    "VCVT.FXS32.F64",
-	arm_VCVT_ZZ_FXS32_F64: "VCVT.ZZ.FXS32.F64",
-	arm_VCVT_EQ_FXU16_F32: "VCVT.EQ.FXU16.F32",
-	arm_VCVT_NE_FXU16_F32: "VCVT.NE.FXU16.F32",
-	arm_VCVT_CS_FXU16_F32: "VCVT.CS.FXU16.F32",
-	arm_VCVT_CC_FXU16_F32: "VCVT.CC.FXU16.F32",
-	arm_VCVT_MI_FXU16_F32: "VCVT.MI.FXU16.F32",
-	arm_VCVT_PL_FXU16_F32: "VCVT.PL.FXU16.F32",
-	arm_VCVT_VS_FXU16_F32: "VCVT.VS.FXU16.F32",
-	arm_VCVT_VC_FXU16_F32: "VCVT.VC.FXU16.F32",
-	arm_VCVT_HI_FXU16_F32: "VCVT.HI.FXU16.F32",
-	arm_VCVT_LS_FXU16_F32: "VCVT.LS.FXU16.F32",
-	arm_VCVT_GE_FXU16_F32: "VCVT.GE.FXU16.F32",
-	arm_VCVT_LT_FXU16_F32: "VCVT.LT.FXU16.F32",
-	arm_VCVT_GT_FXU16_F32: "VCVT.GT.FXU16.F32",
-	arm_VCVT_LE_FXU16_F32: "VCVT.LE.FXU16.F32",
-	arm_VCVT_FXU16_F32:    "VCVT.FXU16.F32",
-	arm_VCVT_ZZ_FXU16_F32: "VCVT.ZZ.FXU16.F32",
-	arm_VCVT_EQ_FXU16_F64: "VCVT.EQ.FXU16.F64",
-	arm_VCVT_NE_FXU16_F64: "VCVT.NE.FXU16.F64",
-	arm_VCVT_CS_FXU16_F64: "VCVT.CS.FXU16.F64",
-	arm_VCVT_CC_FXU16_F64: "VCVT.CC.FXU16.F64",
-	arm_VCVT_MI_FXU16_F64: "VCVT.MI.FXU16.F64",
-	arm_VCVT_PL_FXU16_F64: "VCVT.PL.FXU16.F64",
-	arm_VCVT_VS_FXU16_F64: "VCVT.VS.FXU16.F64",
-	arm_VCVT_VC_FXU16_F64: "VCVT.VC.FXU16.F64",
-	arm_VCVT_HI_FXU16_F64: "VCVT.HI.FXU16.F64",
-	arm_VCVT_LS_FXU16_F64: "VCVT.LS.FXU16.F64",
-	arm_VCVT_GE_FXU16_F64: "VCVT.GE.FXU16.F64",
-	arm_VCVT_LT_FXU16_F64: "VCVT.LT.FXU16.F64",
-	arm_VCVT_GT_FXU16_F64: "VCVT.GT.FXU16.F64",
-	arm_VCVT_LE_FXU16_F64: "VCVT.LE.FXU16.F64",
-	arm_VCVT_FXU16_F64:    "VCVT.FXU16.F64",
-	arm_VCVT_ZZ_FXU16_F64: "VCVT.ZZ.FXU16.F64",
-	arm_VCVT_EQ_FXU32_F32: "VCVT.EQ.FXU32.F32",
-	arm_VCVT_NE_FXU32_F32: "VCVT.NE.FXU32.F32",
-	arm_VCVT_CS_FXU32_F32: "VCVT.CS.FXU32.F32",
-	arm_VCVT_CC_FXU32_F32: "VCVT.CC.FXU32.F32",
-	arm_VCVT_MI_FXU32_F32: "VCVT.MI.FXU32.F32",
-	arm_VCVT_PL_FXU32_F32: "VCVT.PL.FXU32.F32",
-	arm_VCVT_VS_FXU32_F32: "VCVT.VS.FXU32.F32",
-	arm_VCVT_VC_FXU32_F32: "VCVT.VC.FXU32.F32",
-	arm_VCVT_HI_FXU32_F32: "VCVT.HI.FXU32.F32",
-	arm_VCVT_LS_FXU32_F32: "VCVT.LS.FXU32.F32",
-	arm_VCVT_GE_FXU32_F32: "VCVT.GE.FXU32.F32",
-	arm_VCVT_LT_FXU32_F32: "VCVT.LT.FXU32.F32",
-	arm_VCVT_GT_FXU32_F32: "VCVT.GT.FXU32.F32",
-	arm_VCVT_LE_FXU32_F32: "VCVT.LE.FXU32.F32",
-	arm_VCVT_FXU32_F32:    "VCVT.FXU32.F32",
-	arm_VCVT_ZZ_FXU32_F32: "VCVT.ZZ.FXU32.F32",
-	arm_VCVT_EQ_FXU32_F64: "VCVT.EQ.FXU32.F64",
-	arm_VCVT_NE_FXU32_F64: "VCVT.NE.FXU32.F64",
-	arm_VCVT_CS_FXU32_F64: "VCVT.CS.FXU32.F64",
-	arm_VCVT_CC_FXU32_F64: "VCVT.CC.FXU32.F64",
-	arm_VCVT_MI_FXU32_F64: "VCVT.MI.FXU32.F64",
-	arm_VCVT_PL_FXU32_F64: "VCVT.PL.FXU32.F64",
-	arm_VCVT_VS_FXU32_F64: "VCVT.VS.FXU32.F64",
-	arm_VCVT_VC_FXU32_F64: "VCVT.VC.FXU32.F64",
-	arm_VCVT_HI_FXU32_F64: "VCVT.HI.FXU32.F64",
-	arm_VCVT_LS_FXU32_F64: "VCVT.LS.FXU32.F64",
-	arm_VCVT_GE_FXU32_F64: "VCVT.GE.FXU32.F64",
-	arm_VCVT_LT_FXU32_F64: "VCVT.LT.FXU32.F64",
-	arm_VCVT_GT_FXU32_F64: "VCVT.GT.FXU32.F64",
-	arm_VCVT_LE_FXU32_F64: "VCVT.LE.FXU32.F64",
-	arm_VCVT_FXU32_F64:    "VCVT.FXU32.F64",
-	arm_VCVT_ZZ_FXU32_F64: "VCVT.ZZ.FXU32.F64",
-	arm_VCVTB_EQ_F32_F16:  "VCVTB.EQ.F32.F16",
-	arm_VCVTB_NE_F32_F16:  "VCVTB.NE.F32.F16",
-	arm_VCVTB_CS_F32_F16:  "VCVTB.CS.F32.F16",
-	arm_VCVTB_CC_F32_F16:  "VCVTB.CC.F32.F16",
-	arm_VCVTB_MI_F32_F16:  "VCVTB.MI.F32.F16",
-	arm_VCVTB_PL_F32_F16:  "VCVTB.PL.F32.F16",
-	arm_VCVTB_VS_F32_F16:  "VCVTB.VS.F32.F16",
-	arm_VCVTB_VC_F32_F16:  "VCVTB.VC.F32.F16",
-	arm_VCVTB_HI_F32_F16:  "VCVTB.HI.F32.F16",
-	arm_VCVTB_LS_F32_F16:  "VCVTB.LS.F32.F16",
-	arm_VCVTB_GE_F32_F16:  "VCVTB.GE.F32.F16",
-	arm_VCVTB_LT_F32_F16:  "VCVTB.LT.F32.F16",
-	arm_VCVTB_GT_F32_F16:  "VCVTB.GT.F32.F16",
-	arm_VCVTB_LE_F32_F16:  "VCVTB.LE.F32.F16",
-	arm_VCVTB_F32_F16:     "VCVTB.F32.F16",
-	arm_VCVTB_ZZ_F32_F16:  "VCVTB.ZZ.F32.F16",
-	arm_VCVTB_EQ_F16_F32:  "VCVTB.EQ.F16.F32",
-	arm_VCVTB_NE_F16_F32:  "VCVTB.NE.F16.F32",
-	arm_VCVTB_CS_F16_F32:  "VCVTB.CS.F16.F32",
-	arm_VCVTB_CC_F16_F32:  "VCVTB.CC.F16.F32",
-	arm_VCVTB_MI_F16_F32:  "VCVTB.MI.F16.F32",
-	arm_VCVTB_PL_F16_F32:  "VCVTB.PL.F16.F32",
-	arm_VCVTB_VS_F16_F32:  "VCVTB.VS.F16.F32",
-	arm_VCVTB_VC_F16_F32:  "VCVTB.VC.F16.F32",
-	arm_VCVTB_HI_F16_F32:  "VCVTB.HI.F16.F32",
-	arm_VCVTB_LS_F16_F32:  "VCVTB.LS.F16.F32",
-	arm_VCVTB_GE_F16_F32:  "VCVTB.GE.F16.F32",
-	arm_VCVTB_LT_F16_F32:  "VCVTB.LT.F16.F32",
-	arm_VCVTB_GT_F16_F32:  "VCVTB.GT.F16.F32",
-	arm_VCVTB_LE_F16_F32:  "VCVTB.LE.F16.F32",
-	arm_VCVTB_F16_F32:     "VCVTB.F16.F32",
-	arm_VCVTB_ZZ_F16_F32:  "VCVTB.ZZ.F16.F32",
-	arm_VCVTT_EQ_F32_F16:  "VCVTT.EQ.F32.F16",
-	arm_VCVTT_NE_F32_F16:  "VCVTT.NE.F32.F16",
-	arm_VCVTT_CS_F32_F16:  "VCVTT.CS.F32.F16",
-	arm_VCVTT_CC_F32_F16:  "VCVTT.CC.F32.F16",
-	arm_VCVTT_MI_F32_F16:  "VCVTT.MI.F32.F16",
-	arm_VCVTT_PL_F32_F16:  "VCVTT.PL.F32.F16",
-	arm_VCVTT_VS_F32_F16:  "VCVTT.VS.F32.F16",
-	arm_VCVTT_VC_F32_F16:  "VCVTT.VC.F32.F16",
-	arm_VCVTT_HI_F32_F16:  "VCVTT.HI.F32.F16",
-	arm_VCVTT_LS_F32_F16:  "VCVTT.LS.F32.F16",
-	arm_VCVTT_GE_F32_F16:  "VCVTT.GE.F32.F16",
-	arm_VCVTT_LT_F32_F16:  "VCVTT.LT.F32.F16",
-	arm_VCVTT_GT_F32_F16:  "VCVTT.GT.F32.F16",
-	arm_VCVTT_LE_F32_F16:  "VCVTT.LE.F32.F16",
-	arm_VCVTT_F32_F16:     "VCVTT.F32.F16",
-	arm_VCVTT_ZZ_F32_F16:  "VCVTT.ZZ.F32.F16",
-	arm_VCVTT_EQ_F16_F32:  "VCVTT.EQ.F16.F32",
-	arm_VCVTT_NE_F16_F32:  "VCVTT.NE.F16.F32",
-	arm_VCVTT_CS_F16_F32:  "VCVTT.CS.F16.F32",
-	arm_VCVTT_CC_F16_F32:  "VCVTT.CC.F16.F32",
-	arm_VCVTT_MI_F16_F32:  "VCVTT.MI.F16.F32",
-	arm_VCVTT_PL_F16_F32:  "VCVTT.PL.F16.F32",
-	arm_VCVTT_VS_F16_F32:  "VCVTT.VS.F16.F32",
-	arm_VCVTT_VC_F16_F32:  "VCVTT.VC.F16.F32",
-	arm_VCVTT_HI_F16_F32:  "VCVTT.HI.F16.F32",
-	arm_VCVTT_LS_F16_F32:  "VCVTT.LS.F16.F32",
-	arm_VCVTT_GE_F16_F32:  "VCVTT.GE.F16.F32",
-	arm_VCVTT_LT_F16_F32:  "VCVTT.LT.F16.F32",
-	arm_VCVTT_GT_F16_F32:  "VCVTT.GT.F16.F32",
-	arm_VCVTT_LE_F16_F32:  "VCVTT.LE.F16.F32",
-	arm_VCVTT_F16_F32:     "VCVTT.F16.F32",
-	arm_VCVTT_ZZ_F16_F32:  "VCVTT.ZZ.F16.F32",
-	arm_VCVTR_EQ_U32_F32:  "VCVTR.EQ.U32.F32",
-	arm_VCVTR_NE_U32_F32:  "VCVTR.NE.U32.F32",
-	arm_VCVTR_CS_U32_F32:  "VCVTR.CS.U32.F32",
-	arm_VCVTR_CC_U32_F32:  "VCVTR.CC.U32.F32",
-	arm_VCVTR_MI_U32_F32:  "VCVTR.MI.U32.F32",
-	arm_VCVTR_PL_U32_F32:  "VCVTR.PL.U32.F32",
-	arm_VCVTR_VS_U32_F32:  "VCVTR.VS.U32.F32",
-	arm_VCVTR_VC_U32_F32:  "VCVTR.VC.U32.F32",
-	arm_VCVTR_HI_U32_F32:  "VCVTR.HI.U32.F32",
-	arm_VCVTR_LS_U32_F32:  "VCVTR.LS.U32.F32",
-	arm_VCVTR_GE_U32_F32:  "VCVTR.GE.U32.F32",
-	arm_VCVTR_LT_U32_F32:  "VCVTR.LT.U32.F32",
-	arm_VCVTR_GT_U32_F32:  "VCVTR.GT.U32.F32",
-	arm_VCVTR_LE_U32_F32:  "VCVTR.LE.U32.F32",
-	arm_VCVTR_U32_F32:     "VCVTR.U32.F32",
-	arm_VCVTR_ZZ_U32_F32:  "VCVTR.ZZ.U32.F32",
-	arm_VCVTR_EQ_U32_F64:  "VCVTR.EQ.U32.F64",
-	arm_VCVTR_NE_U32_F64:  "VCVTR.NE.U32.F64",
-	arm_VCVTR_CS_U32_F64:  "VCVTR.CS.U32.F64",
-	arm_VCVTR_CC_U32_F64:  "VCVTR.CC.U32.F64",
-	arm_VCVTR_MI_U32_F64:  "VCVTR.MI.U32.F64",
-	arm_VCVTR_PL_U32_F64:  "VCVTR.PL.U32.F64",
-	arm_VCVTR_VS_U32_F64:  "VCVTR.VS.U32.F64",
-	arm_VCVTR_VC_U32_F64:  "VCVTR.VC.U32.F64",
-	arm_VCVTR_HI_U32_F64:  "VCVTR.HI.U32.F64",
-	arm_VCVTR_LS_U32_F64:  "VCVTR.LS.U32.F64",
-	arm_VCVTR_GE_U32_F64:  "VCVTR.GE.U32.F64",
-	arm_VCVTR_LT_U32_F64:  "VCVTR.LT.U32.F64",
-	arm_VCVTR_GT_U32_F64:  "VCVTR.GT.U32.F64",
-	arm_VCVTR_LE_U32_F64:  "VCVTR.LE.U32.F64",
-	arm_VCVTR_U32_F64:     "VCVTR.U32.F64",
-	arm_VCVTR_ZZ_U32_F64:  "VCVTR.ZZ.U32.F64",
-	arm_VCVTR_EQ_S32_F32:  "VCVTR.EQ.S32.F32",
-	arm_VCVTR_NE_S32_F32:  "VCVTR.NE.S32.F32",
-	arm_VCVTR_CS_S32_F32:  "VCVTR.CS.S32.F32",
-	arm_VCVTR_CC_S32_F32:  "VCVTR.CC.S32.F32",
-	arm_VCVTR_MI_S32_F32:  "VCVTR.MI.S32.F32",
-	arm_VCVTR_PL_S32_F32:  "VCVTR.PL.S32.F32",
-	arm_VCVTR_VS_S32_F32:  "VCVTR.VS.S32.F32",
-	arm_VCVTR_VC_S32_F32:  "VCVTR.VC.S32.F32",
-	arm_VCVTR_HI_S32_F32:  "VCVTR.HI.S32.F32",
-	arm_VCVTR_LS_S32_F32:  "VCVTR.LS.S32.F32",
-	arm_VCVTR_GE_S32_F32:  "VCVTR.GE.S32.F32",
-	arm_VCVTR_LT_S32_F32:  "VCVTR.LT.S32.F32",
-	arm_VCVTR_GT_S32_F32:  "VCVTR.GT.S32.F32",
-	arm_VCVTR_LE_S32_F32:  "VCVTR.LE.S32.F32",
-	arm_VCVTR_S32_F32:     "VCVTR.S32.F32",
-	arm_VCVTR_ZZ_S32_F32:  "VCVTR.ZZ.S32.F32",
-	arm_VCVTR_EQ_S32_F64:  "VCVTR.EQ.S32.F64",
-	arm_VCVTR_NE_S32_F64:  "VCVTR.NE.S32.F64",
-	arm_VCVTR_CS_S32_F64:  "VCVTR.CS.S32.F64",
-	arm_VCVTR_CC_S32_F64:  "VCVTR.CC.S32.F64",
-	arm_VCVTR_MI_S32_F64:  "VCVTR.MI.S32.F64",
-	arm_VCVTR_PL_S32_F64:  "VCVTR.PL.S32.F64",
-	arm_VCVTR_VS_S32_F64:  "VCVTR.VS.S32.F64",
-	arm_VCVTR_VC_S32_F64:  "VCVTR.VC.S32.F64",
-	arm_VCVTR_HI_S32_F64:  "VCVTR.HI.S32.F64",
-	arm_VCVTR_LS_S32_F64:  "VCVTR.LS.S32.F64",
-	arm_VCVTR_GE_S32_F64:  "VCVTR.GE.S32.F64",
-	arm_VCVTR_LT_S32_F64:  "VCVTR.LT.S32.F64",
-	arm_VCVTR_GT_S32_F64:  "VCVTR.GT.S32.F64",
-	arm_VCVTR_LE_S32_F64:  "VCVTR.LE.S32.F64",
-	arm_VCVTR_S32_F64:     "VCVTR.S32.F64",
-	arm_VCVTR_ZZ_S32_F64:  "VCVTR.ZZ.S32.F64",
-	arm_VCVT_EQ_U32_F32:   "VCVT.EQ.U32.F32",
-	arm_VCVT_NE_U32_F32:   "VCVT.NE.U32.F32",
-	arm_VCVT_CS_U32_F32:   "VCVT.CS.U32.F32",
-	arm_VCVT_CC_U32_F32:   "VCVT.CC.U32.F32",
-	arm_VCVT_MI_U32_F32:   "VCVT.MI.U32.F32",
-	arm_VCVT_PL_U32_F32:   "VCVT.PL.U32.F32",
-	arm_VCVT_VS_U32_F32:   "VCVT.VS.U32.F32",
-	arm_VCVT_VC_U32_F32:   "VCVT.VC.U32.F32",
-	arm_VCVT_HI_U32_F32:   "VCVT.HI.U32.F32",
-	arm_VCVT_LS_U32_F32:   "VCVT.LS.U32.F32",
-	arm_VCVT_GE_U32_F32:   "VCVT.GE.U32.F32",
-	arm_VCVT_LT_U32_F32:   "VCVT.LT.U32.F32",
-	arm_VCVT_GT_U32_F32:   "VCVT.GT.U32.F32",
-	arm_VCVT_LE_U32_F32:   "VCVT.LE.U32.F32",
-	arm_VCVT_U32_F32:      "VCVT.U32.F32",
-	arm_VCVT_ZZ_U32_F32:   "VCVT.ZZ.U32.F32",
-	arm_VCVT_EQ_U32_F64:   "VCVT.EQ.U32.F64",
-	arm_VCVT_NE_U32_F64:   "VCVT.NE.U32.F64",
-	arm_VCVT_CS_U32_F64:   "VCVT.CS.U32.F64",
-	arm_VCVT_CC_U32_F64:   "VCVT.CC.U32.F64",
-	arm_VCVT_MI_U32_F64:   "VCVT.MI.U32.F64",
-	arm_VCVT_PL_U32_F64:   "VCVT.PL.U32.F64",
-	arm_VCVT_VS_U32_F64:   "VCVT.VS.U32.F64",
-	arm_VCVT_VC_U32_F64:   "VCVT.VC.U32.F64",
-	arm_VCVT_HI_U32_F64:   "VCVT.HI.U32.F64",
-	arm_VCVT_LS_U32_F64:   "VCVT.LS.U32.F64",
-	arm_VCVT_GE_U32_F64:   "VCVT.GE.U32.F64",
-	arm_VCVT_LT_U32_F64:   "VCVT.LT.U32.F64",
-	arm_VCVT_GT_U32_F64:   "VCVT.GT.U32.F64",
-	arm_VCVT_LE_U32_F64:   "VCVT.LE.U32.F64",
-	arm_VCVT_U32_F64:      "VCVT.U32.F64",
-	arm_VCVT_ZZ_U32_F64:   "VCVT.ZZ.U32.F64",
-	arm_VCVT_EQ_S32_F32:   "VCVT.EQ.S32.F32",
-	arm_VCVT_NE_S32_F32:   "VCVT.NE.S32.F32",
-	arm_VCVT_CS_S32_F32:   "VCVT.CS.S32.F32",
-	arm_VCVT_CC_S32_F32:   "VCVT.CC.S32.F32",
-	arm_VCVT_MI_S32_F32:   "VCVT.MI.S32.F32",
-	arm_VCVT_PL_S32_F32:   "VCVT.PL.S32.F32",
-	arm_VCVT_VS_S32_F32:   "VCVT.VS.S32.F32",
-	arm_VCVT_VC_S32_F32:   "VCVT.VC.S32.F32",
-	arm_VCVT_HI_S32_F32:   "VCVT.HI.S32.F32",
-	arm_VCVT_LS_S32_F32:   "VCVT.LS.S32.F32",
-	arm_VCVT_GE_S32_F32:   "VCVT.GE.S32.F32",
-	arm_VCVT_LT_S32_F32:   "VCVT.LT.S32.F32",
-	arm_VCVT_GT_S32_F32:   "VCVT.GT.S32.F32",
-	arm_VCVT_LE_S32_F32:   "VCVT.LE.S32.F32",
-	arm_VCVT_S32_F32:      "VCVT.S32.F32",
-	arm_VCVT_ZZ_S32_F32:   "VCVT.ZZ.S32.F32",
-	arm_VCVT_EQ_S32_F64:   "VCVT.EQ.S32.F64",
-	arm_VCVT_NE_S32_F64:   "VCVT.NE.S32.F64",
-	arm_VCVT_CS_S32_F64:   "VCVT.CS.S32.F64",
-	arm_VCVT_CC_S32_F64:   "VCVT.CC.S32.F64",
-	arm_VCVT_MI_S32_F64:   "VCVT.MI.S32.F64",
-	arm_VCVT_PL_S32_F64:   "VCVT.PL.S32.F64",
-	arm_VCVT_VS_S32_F64:   "VCVT.VS.S32.F64",
-	arm_VCVT_VC_S32_F64:   "VCVT.VC.S32.F64",
-	arm_VCVT_HI_S32_F64:   "VCVT.HI.S32.F64",
-	arm_VCVT_LS_S32_F64:   "VCVT.LS.S32.F64",
-	arm_VCVT_GE_S32_F64:   "VCVT.GE.S32.F64",
-	arm_VCVT_LT_S32_F64:   "VCVT.LT.S32.F64",
-	arm_VCVT_GT_S32_F64:   "VCVT.GT.S32.F64",
-	arm_VCVT_LE_S32_F64:   "VCVT.LE.S32.F64",
-	arm_VCVT_S32_F64:      "VCVT.S32.F64",
-	arm_VCVT_ZZ_S32_F64:   "VCVT.ZZ.S32.F64",
-	arm_VDIV_EQ_F32:       "VDIV.EQ.F32",
-	arm_VDIV_NE_F32:       "VDIV.NE.F32",
-	arm_VDIV_CS_F32:       "VDIV.CS.F32",
-	arm_VDIV_CC_F32:       "VDIV.CC.F32",
-	arm_VDIV_MI_F32:       "VDIV.MI.F32",
-	arm_VDIV_PL_F32:       "VDIV.PL.F32",
-	arm_VDIV_VS_F32:       "VDIV.VS.F32",
-	arm_VDIV_VC_F32:       "VDIV.VC.F32",
-	arm_VDIV_HI_F32:       "VDIV.HI.F32",
-	arm_VDIV_LS_F32:       "VDIV.LS.F32",
-	arm_VDIV_GE_F32:       "VDIV.GE.F32",
-	arm_VDIV_LT_F32:       "VDIV.LT.F32",
-	arm_VDIV_GT_F32:       "VDIV.GT.F32",
-	arm_VDIV_LE_F32:       "VDIV.LE.F32",
-	arm_VDIV_F32:          "VDIV.F32",
-	arm_VDIV_ZZ_F32:       "VDIV.ZZ.F32",
-	arm_VDIV_EQ_F64:       "VDIV.EQ.F64",
-	arm_VDIV_NE_F64:       "VDIV.NE.F64",
-	arm_VDIV_CS_F64:       "VDIV.CS.F64",
-	arm_VDIV_CC_F64:       "VDIV.CC.F64",
-	arm_VDIV_MI_F64:       "VDIV.MI.F64",
-	arm_VDIV_PL_F64:       "VDIV.PL.F64",
-	arm_VDIV_VS_F64:       "VDIV.VS.F64",
-	arm_VDIV_VC_F64:       "VDIV.VC.F64",
-	arm_VDIV_HI_F64:       "VDIV.HI.F64",
-	arm_VDIV_LS_F64:       "VDIV.LS.F64",
-	arm_VDIV_GE_F64:       "VDIV.GE.F64",
-	arm_VDIV_LT_F64:       "VDIV.LT.F64",
-	arm_VDIV_GT_F64:       "VDIV.GT.F64",
-	arm_VDIV_LE_F64:       "VDIV.LE.F64",
-	arm_VDIV_F64:          "VDIV.F64",
-	arm_VDIV_ZZ_F64:       "VDIV.ZZ.F64",
-	arm_VLDR_EQ:           "VLDR.EQ",
-	arm_VLDR_NE:           "VLDR.NE",
-	arm_VLDR_CS:           "VLDR.CS",
-	arm_VLDR_CC:           "VLDR.CC",
-	arm_VLDR_MI:           "VLDR.MI",
-	arm_VLDR_PL:           "VLDR.PL",
-	arm_VLDR_VS:           "VLDR.VS",
-	arm_VLDR_VC:           "VLDR.VC",
-	arm_VLDR_HI:           "VLDR.HI",
-	arm_VLDR_LS:           "VLDR.LS",
-	arm_VLDR_GE:           "VLDR.GE",
-	arm_VLDR_LT:           "VLDR.LT",
-	arm_VLDR_GT:           "VLDR.GT",
-	arm_VLDR_LE:           "VLDR.LE",
-	arm_VLDR:              "VLDR",
-	arm_VLDR_ZZ:           "VLDR.ZZ",
-	arm_VMLA_EQ_F32:       "VMLA.EQ.F32",
-	arm_VMLA_NE_F32:       "VMLA.NE.F32",
-	arm_VMLA_CS_F32:       "VMLA.CS.F32",
-	arm_VMLA_CC_F32:       "VMLA.CC.F32",
-	arm_VMLA_MI_F32:       "VMLA.MI.F32",
-	arm_VMLA_PL_F32:       "VMLA.PL.F32",
-	arm_VMLA_VS_F32:       "VMLA.VS.F32",
-	arm_VMLA_VC_F32:       "VMLA.VC.F32",
-	arm_VMLA_HI_F32:       "VMLA.HI.F32",
-	arm_VMLA_LS_F32:       "VMLA.LS.F32",
-	arm_VMLA_GE_F32:       "VMLA.GE.F32",
-	arm_VMLA_LT_F32:       "VMLA.LT.F32",
-	arm_VMLA_GT_F32:       "VMLA.GT.F32",
-	arm_VMLA_LE_F32:       "VMLA.LE.F32",
-	arm_VMLA_F32:          "VMLA.F32",
-	arm_VMLA_ZZ_F32:       "VMLA.ZZ.F32",
-	arm_VMLA_EQ_F64:       "VMLA.EQ.F64",
-	arm_VMLA_NE_F64:       "VMLA.NE.F64",
-	arm_VMLA_CS_F64:       "VMLA.CS.F64",
-	arm_VMLA_CC_F64:       "VMLA.CC.F64",
-	arm_VMLA_MI_F64:       "VMLA.MI.F64",
-	arm_VMLA_PL_F64:       "VMLA.PL.F64",
-	arm_VMLA_VS_F64:       "VMLA.VS.F64",
-	arm_VMLA_VC_F64:       "VMLA.VC.F64",
-	arm_VMLA_HI_F64:       "VMLA.HI.F64",
-	arm_VMLA_LS_F64:       "VMLA.LS.F64",
-	arm_VMLA_GE_F64:       "VMLA.GE.F64",
-	arm_VMLA_LT_F64:       "VMLA.LT.F64",
-	arm_VMLA_GT_F64:       "VMLA.GT.F64",
-	arm_VMLA_LE_F64:       "VMLA.LE.F64",
-	arm_VMLA_F64:          "VMLA.F64",
-	arm_VMLA_ZZ_F64:       "VMLA.ZZ.F64",
-	arm_VMLS_EQ_F32:       "VMLS.EQ.F32",
-	arm_VMLS_NE_F32:       "VMLS.NE.F32",
-	arm_VMLS_CS_F32:       "VMLS.CS.F32",
-	arm_VMLS_CC_F32:       "VMLS.CC.F32",
-	arm_VMLS_MI_F32:       "VMLS.MI.F32",
-	arm_VMLS_PL_F32:       "VMLS.PL.F32",
-	arm_VMLS_VS_F32:       "VMLS.VS.F32",
-	arm_VMLS_VC_F32:       "VMLS.VC.F32",
-	arm_VMLS_HI_F32:       "VMLS.HI.F32",
-	arm_VMLS_LS_F32:       "VMLS.LS.F32",
-	arm_VMLS_GE_F32:       "VMLS.GE.F32",
-	arm_VMLS_LT_F32:       "VMLS.LT.F32",
-	arm_VMLS_GT_F32:       "VMLS.GT.F32",
-	arm_VMLS_LE_F32:       "VMLS.LE.F32",
-	arm_VMLS_F32:          "VMLS.F32",
-	arm_VMLS_ZZ_F32:       "VMLS.ZZ.F32",
-	arm_VMLS_EQ_F64:       "VMLS.EQ.F64",
-	arm_VMLS_NE_F64:       "VMLS.NE.F64",
-	arm_VMLS_CS_F64:       "VMLS.CS.F64",
-	arm_VMLS_CC_F64:       "VMLS.CC.F64",
-	arm_VMLS_MI_F64:       "VMLS.MI.F64",
-	arm_VMLS_PL_F64:       "VMLS.PL.F64",
-	arm_VMLS_VS_F64:       "VMLS.VS.F64",
-	arm_VMLS_VC_F64:       "VMLS.VC.F64",
-	arm_VMLS_HI_F64:       "VMLS.HI.F64",
-	arm_VMLS_LS_F64:       "VMLS.LS.F64",
-	arm_VMLS_GE_F64:       "VMLS.GE.F64",
-	arm_VMLS_LT_F64:       "VMLS.LT.F64",
-	arm_VMLS_GT_F64:       "VMLS.GT.F64",
-	arm_VMLS_LE_F64:       "VMLS.LE.F64",
-	arm_VMLS_F64:          "VMLS.F64",
-	arm_VMLS_ZZ_F64:       "VMLS.ZZ.F64",
-	arm_VMOV_EQ:           "VMOV.EQ",
-	arm_VMOV_NE:           "VMOV.NE",
-	arm_VMOV_CS:           "VMOV.CS",
-	arm_VMOV_CC:           "VMOV.CC",
-	arm_VMOV_MI:           "VMOV.MI",
-	arm_VMOV_PL:           "VMOV.PL",
-	arm_VMOV_VS:           "VMOV.VS",
-	arm_VMOV_VC:           "VMOV.VC",
-	arm_VMOV_HI:           "VMOV.HI",
-	arm_VMOV_LS:           "VMOV.LS",
-	arm_VMOV_GE:           "VMOV.GE",
-	arm_VMOV_LT:           "VMOV.LT",
-	arm_VMOV_GT:           "VMOV.GT",
-	arm_VMOV_LE:           "VMOV.LE",
-	arm_VMOV:              "VMOV",
-	arm_VMOV_ZZ:           "VMOV.ZZ",
-	arm_VMOV_EQ_32:        "VMOV.EQ.32",
-	arm_VMOV_NE_32:        "VMOV.NE.32",
-	arm_VMOV_CS_32:        "VMOV.CS.32",
-	arm_VMOV_CC_32:        "VMOV.CC.32",
-	arm_VMOV_MI_32:        "VMOV.MI.32",
-	arm_VMOV_PL_32:        "VMOV.PL.32",
-	arm_VMOV_VS_32:        "VMOV.VS.32",
-	arm_VMOV_VC_32:        "VMOV.VC.32",
-	arm_VMOV_HI_32:        "VMOV.HI.32",
-	arm_VMOV_LS_32:        "VMOV.LS.32",
-	arm_VMOV_GE_32:        "VMOV.GE.32",
-	arm_VMOV_LT_32:        "VMOV.LT.32",
-	arm_VMOV_GT_32:        "VMOV.GT.32",
-	arm_VMOV_LE_32:        "VMOV.LE.32",
-	arm_VMOV_32:           "VMOV.32",
-	arm_VMOV_ZZ_32:        "VMOV.ZZ.32",
-	arm_VMOV_EQ_F32:       "VMOV.EQ.F32",
-	arm_VMOV_NE_F32:       "VMOV.NE.F32",
-	arm_VMOV_CS_F32:       "VMOV.CS.F32",
-	arm_VMOV_CC_F32:       "VMOV.CC.F32",
-	arm_VMOV_MI_F32:       "VMOV.MI.F32",
-	arm_VMOV_PL_F32:       "VMOV.PL.F32",
-	arm_VMOV_VS_F32:       "VMOV.VS.F32",
-	arm_VMOV_VC_F32:       "VMOV.VC.F32",
-	arm_VMOV_HI_F32:       "VMOV.HI.F32",
-	arm_VMOV_LS_F32:       "VMOV.LS.F32",
-	arm_VMOV_GE_F32:       "VMOV.GE.F32",
-	arm_VMOV_LT_F32:       "VMOV.LT.F32",
-	arm_VMOV_GT_F32:       "VMOV.GT.F32",
-	arm_VMOV_LE_F32:       "VMOV.LE.F32",
-	arm_VMOV_F32:          "VMOV.F32",
-	arm_VMOV_ZZ_F32:       "VMOV.ZZ.F32",
-	arm_VMOV_EQ_F64:       "VMOV.EQ.F64",
-	arm_VMOV_NE_F64:       "VMOV.NE.F64",
-	arm_VMOV_CS_F64:       "VMOV.CS.F64",
-	arm_VMOV_CC_F64:       "VMOV.CC.F64",
-	arm_VMOV_MI_F64:       "VMOV.MI.F64",
-	arm_VMOV_PL_F64:       "VMOV.PL.F64",
-	arm_VMOV_VS_F64:       "VMOV.VS.F64",
-	arm_VMOV_VC_F64:       "VMOV.VC.F64",
-	arm_VMOV_HI_F64:       "VMOV.HI.F64",
-	arm_VMOV_LS_F64:       "VMOV.LS.F64",
-	arm_VMOV_GE_F64:       "VMOV.GE.F64",
-	arm_VMOV_LT_F64:       "VMOV.LT.F64",
-	arm_VMOV_GT_F64:       "VMOV.GT.F64",
-	arm_VMOV_LE_F64:       "VMOV.LE.F64",
-	arm_VMOV_F64:          "VMOV.F64",
-	arm_VMOV_ZZ_F64:       "VMOV.ZZ.F64",
-	arm_VMRS_EQ:           "VMRS.EQ",
-	arm_VMRS_NE:           "VMRS.NE",
-	arm_VMRS_CS:           "VMRS.CS",
-	arm_VMRS_CC:           "VMRS.CC",
-	arm_VMRS_MI:           "VMRS.MI",
-	arm_VMRS_PL:           "VMRS.PL",
-	arm_VMRS_VS:           "VMRS.VS",
-	arm_VMRS_VC:           "VMRS.VC",
-	arm_VMRS_HI:           "VMRS.HI",
-	arm_VMRS_LS:           "VMRS.LS",
-	arm_VMRS_GE:           "VMRS.GE",
-	arm_VMRS_LT:           "VMRS.LT",
-	arm_VMRS_GT:           "VMRS.GT",
-	arm_VMRS_LE:           "VMRS.LE",
-	arm_VMRS:              "VMRS",
-	arm_VMRS_ZZ:           "VMRS.ZZ",
-	arm_VMSR_EQ:           "VMSR.EQ",
-	arm_VMSR_NE:           "VMSR.NE",
-	arm_VMSR_CS:           "VMSR.CS",
-	arm_VMSR_CC:           "VMSR.CC",
-	arm_VMSR_MI:           "VMSR.MI",
-	arm_VMSR_PL:           "VMSR.PL",
-	arm_VMSR_VS:           "VMSR.VS",
-	arm_VMSR_VC:           "VMSR.VC",
-	arm_VMSR_HI:           "VMSR.HI",
-	arm_VMSR_LS:           "VMSR.LS",
-	arm_VMSR_GE:           "VMSR.GE",
-	arm_VMSR_LT:           "VMSR.LT",
-	arm_VMSR_GT:           "VMSR.GT",
-	arm_VMSR_LE:           "VMSR.LE",
-	arm_VMSR:              "VMSR",
-	arm_VMSR_ZZ:           "VMSR.ZZ",
-	arm_VMUL_EQ_F32:       "VMUL.EQ.F32",
-	arm_VMUL_NE_F32:       "VMUL.NE.F32",
-	arm_VMUL_CS_F32:       "VMUL.CS.F32",
-	arm_VMUL_CC_F32:       "VMUL.CC.F32",
-	arm_VMUL_MI_F32:       "VMUL.MI.F32",
-	arm_VMUL_PL_F32:       "VMUL.PL.F32",
-	arm_VMUL_VS_F32:       "VMUL.VS.F32",
-	arm_VMUL_VC_F32:       "VMUL.VC.F32",
-	arm_VMUL_HI_F32:       "VMUL.HI.F32",
-	arm_VMUL_LS_F32:       "VMUL.LS.F32",
-	arm_VMUL_GE_F32:       "VMUL.GE.F32",
-	arm_VMUL_LT_F32:       "VMUL.LT.F32",
-	arm_VMUL_GT_F32:       "VMUL.GT.F32",
-	arm_VMUL_LE_F32:       "VMUL.LE.F32",
-	arm_VMUL_F32:          "VMUL.F32",
-	arm_VMUL_ZZ_F32:       "VMUL.ZZ.F32",
-	arm_VMUL_EQ_F64:       "VMUL.EQ.F64",
-	arm_VMUL_NE_F64:       "VMUL.NE.F64",
-	arm_VMUL_CS_F64:       "VMUL.CS.F64",
-	arm_VMUL_CC_F64:       "VMUL.CC.F64",
-	arm_VMUL_MI_F64:       "VMUL.MI.F64",
-	arm_VMUL_PL_F64:       "VMUL.PL.F64",
-	arm_VMUL_VS_F64:       "VMUL.VS.F64",
-	arm_VMUL_VC_F64:       "VMUL.VC.F64",
-	arm_VMUL_HI_F64:       "VMUL.HI.F64",
-	arm_VMUL_LS_F64:       "VMUL.LS.F64",
-	arm_VMUL_GE_F64:       "VMUL.GE.F64",
-	arm_VMUL_LT_F64:       "VMUL.LT.F64",
-	arm_VMUL_GT_F64:       "VMUL.GT.F64",
-	arm_VMUL_LE_F64:       "VMUL.LE.F64",
-	arm_VMUL_F64:          "VMUL.F64",
-	arm_VMUL_ZZ_F64:       "VMUL.ZZ.F64",
-	arm_VNEG_EQ_F32:       "VNEG.EQ.F32",
-	arm_VNEG_NE_F32:       "VNEG.NE.F32",
-	arm_VNEG_CS_F32:       "VNEG.CS.F32",
-	arm_VNEG_CC_F32:       "VNEG.CC.F32",
-	arm_VNEG_MI_F32:       "VNEG.MI.F32",
-	arm_VNEG_PL_F32:       "VNEG.PL.F32",
-	arm_VNEG_VS_F32:       "VNEG.VS.F32",
-	arm_VNEG_VC_F32:       "VNEG.VC.F32",
-	arm_VNEG_HI_F32:       "VNEG.HI.F32",
-	arm_VNEG_LS_F32:       "VNEG.LS.F32",
-	arm_VNEG_GE_F32:       "VNEG.GE.F32",
-	arm_VNEG_LT_F32:       "VNEG.LT.F32",
-	arm_VNEG_GT_F32:       "VNEG.GT.F32",
-	arm_VNEG_LE_F32:       "VNEG.LE.F32",
-	arm_VNEG_F32:          "VNEG.F32",
-	arm_VNEG_ZZ_F32:       "VNEG.ZZ.F32",
-	arm_VNEG_EQ_F64:       "VNEG.EQ.F64",
-	arm_VNEG_NE_F64:       "VNEG.NE.F64",
-	arm_VNEG_CS_F64:       "VNEG.CS.F64",
-	arm_VNEG_CC_F64:       "VNEG.CC.F64",
-	arm_VNEG_MI_F64:       "VNEG.MI.F64",
-	arm_VNEG_PL_F64:       "VNEG.PL.F64",
-	arm_VNEG_VS_F64:       "VNEG.VS.F64",
-	arm_VNEG_VC_F64:       "VNEG.VC.F64",
-	arm_VNEG_HI_F64:       "VNEG.HI.F64",
-	arm_VNEG_LS_F64:       "VNEG.LS.F64",
-	arm_VNEG_GE_F64:       "VNEG.GE.F64",
-	arm_VNEG_LT_F64:       "VNEG.LT.F64",
-	arm_VNEG_GT_F64:       "VNEG.GT.F64",
-	arm_VNEG_LE_F64:       "VNEG.LE.F64",
-	arm_VNEG_F64:          "VNEG.F64",
-	arm_VNEG_ZZ_F64:       "VNEG.ZZ.F64",
-	arm_VNMLS_EQ_F32:      "VNMLS.EQ.F32",
-	arm_VNMLS_NE_F32:      "VNMLS.NE.F32",
-	arm_VNMLS_CS_F32:      "VNMLS.CS.F32",
-	arm_VNMLS_CC_F32:      "VNMLS.CC.F32",
-	arm_VNMLS_MI_F32:      "VNMLS.MI.F32",
-	arm_VNMLS_PL_F32:      "VNMLS.PL.F32",
-	arm_VNMLS_VS_F32:      "VNMLS.VS.F32",
-	arm_VNMLS_VC_F32:      "VNMLS.VC.F32",
-	arm_VNMLS_HI_F32:      "VNMLS.HI.F32",
-	arm_VNMLS_LS_F32:      "VNMLS.LS.F32",
-	arm_VNMLS_GE_F32:      "VNMLS.GE.F32",
-	arm_VNMLS_LT_F32:      "VNMLS.LT.F32",
-	arm_VNMLS_GT_F32:      "VNMLS.GT.F32",
-	arm_VNMLS_LE_F32:      "VNMLS.LE.F32",
-	arm_VNMLS_F32:         "VNMLS.F32",
-	arm_VNMLS_ZZ_F32:      "VNMLS.ZZ.F32",
-	arm_VNMLS_EQ_F64:      "VNMLS.EQ.F64",
-	arm_VNMLS_NE_F64:      "VNMLS.NE.F64",
-	arm_VNMLS_CS_F64:      "VNMLS.CS.F64",
-	arm_VNMLS_CC_F64:      "VNMLS.CC.F64",
-	arm_VNMLS_MI_F64:      "VNMLS.MI.F64",
-	arm_VNMLS_PL_F64:      "VNMLS.PL.F64",
-	arm_VNMLS_VS_F64:      "VNMLS.VS.F64",
-	arm_VNMLS_VC_F64:      "VNMLS.VC.F64",
-	arm_VNMLS_HI_F64:      "VNMLS.HI.F64",
-	arm_VNMLS_LS_F64:      "VNMLS.LS.F64",
-	arm_VNMLS_GE_F64:      "VNMLS.GE.F64",
-	arm_VNMLS_LT_F64:      "VNMLS.LT.F64",
-	arm_VNMLS_GT_F64:      "VNMLS.GT.F64",
-	arm_VNMLS_LE_F64:      "VNMLS.LE.F64",
-	arm_VNMLS_F64:         "VNMLS.F64",
-	arm_VNMLS_ZZ_F64:      "VNMLS.ZZ.F64",
-	arm_VNMLA_EQ_F32:      "VNMLA.EQ.F32",
-	arm_VNMLA_NE_F32:      "VNMLA.NE.F32",
-	arm_VNMLA_CS_F32:      "VNMLA.CS.F32",
-	arm_VNMLA_CC_F32:      "VNMLA.CC.F32",
-	arm_VNMLA_MI_F32:      "VNMLA.MI.F32",
-	arm_VNMLA_PL_F32:      "VNMLA.PL.F32",
-	arm_VNMLA_VS_F32:      "VNMLA.VS.F32",
-	arm_VNMLA_VC_F32:      "VNMLA.VC.F32",
-	arm_VNMLA_HI_F32:      "VNMLA.HI.F32",
-	arm_VNMLA_LS_F32:      "VNMLA.LS.F32",
-	arm_VNMLA_GE_F32:      "VNMLA.GE.F32",
-	arm_VNMLA_LT_F32:      "VNMLA.LT.F32",
-	arm_VNMLA_GT_F32:      "VNMLA.GT.F32",
-	arm_VNMLA_LE_F32:      "VNMLA.LE.F32",
-	arm_VNMLA_F32:         "VNMLA.F32",
-	arm_VNMLA_ZZ_F32:      "VNMLA.ZZ.F32",
-	arm_VNMLA_EQ_F64:      "VNMLA.EQ.F64",
-	arm_VNMLA_NE_F64:      "VNMLA.NE.F64",
-	arm_VNMLA_CS_F64:      "VNMLA.CS.F64",
-	arm_VNMLA_CC_F64:      "VNMLA.CC.F64",
-	arm_VNMLA_MI_F64:      "VNMLA.MI.F64",
-	arm_VNMLA_PL_F64:      "VNMLA.PL.F64",
-	arm_VNMLA_VS_F64:      "VNMLA.VS.F64",
-	arm_VNMLA_VC_F64:      "VNMLA.VC.F64",
-	arm_VNMLA_HI_F64:      "VNMLA.HI.F64",
-	arm_VNMLA_LS_F64:      "VNMLA.LS.F64",
-	arm_VNMLA_GE_F64:      "VNMLA.GE.F64",
-	arm_VNMLA_LT_F64:      "VNMLA.LT.F64",
-	arm_VNMLA_GT_F64:      "VNMLA.GT.F64",
-	arm_VNMLA_LE_F64:      "VNMLA.LE.F64",
-	arm_VNMLA_F64:         "VNMLA.F64",
-	arm_VNMLA_ZZ_F64:      "VNMLA.ZZ.F64",
-	arm_VNMUL_EQ_F32:      "VNMUL.EQ.F32",
-	arm_VNMUL_NE_F32:      "VNMUL.NE.F32",
-	arm_VNMUL_CS_F32:      "VNMUL.CS.F32",
-	arm_VNMUL_CC_F32:      "VNMUL.CC.F32",
-	arm_VNMUL_MI_F32:      "VNMUL.MI.F32",
-	arm_VNMUL_PL_F32:      "VNMUL.PL.F32",
-	arm_VNMUL_VS_F32:      "VNMUL.VS.F32",
-	arm_VNMUL_VC_F32:      "VNMUL.VC.F32",
-	arm_VNMUL_HI_F32:      "VNMUL.HI.F32",
-	arm_VNMUL_LS_F32:      "VNMUL.LS.F32",
-	arm_VNMUL_GE_F32:      "VNMUL.GE.F32",
-	arm_VNMUL_LT_F32:      "VNMUL.LT.F32",
-	arm_VNMUL_GT_F32:      "VNMUL.GT.F32",
-	arm_VNMUL_LE_F32:      "VNMUL.LE.F32",
-	arm_VNMUL_F32:         "VNMUL.F32",
-	arm_VNMUL_ZZ_F32:      "VNMUL.ZZ.F32",
-	arm_VNMUL_EQ_F64:      "VNMUL.EQ.F64",
-	arm_VNMUL_NE_F64:      "VNMUL.NE.F64",
-	arm_VNMUL_CS_F64:      "VNMUL.CS.F64",
-	arm_VNMUL_CC_F64:      "VNMUL.CC.F64",
-	arm_VNMUL_MI_F64:      "VNMUL.MI.F64",
-	arm_VNMUL_PL_F64:      "VNMUL.PL.F64",
-	arm_VNMUL_VS_F64:      "VNMUL.VS.F64",
-	arm_VNMUL_VC_F64:      "VNMUL.VC.F64",
-	arm_VNMUL_HI_F64:      "VNMUL.HI.F64",
-	arm_VNMUL_LS_F64:      "VNMUL.LS.F64",
-	arm_VNMUL_GE_F64:      "VNMUL.GE.F64",
-	arm_VNMUL_LT_F64:      "VNMUL.LT.F64",
-	arm_VNMUL_GT_F64:      "VNMUL.GT.F64",
-	arm_VNMUL_LE_F64:      "VNMUL.LE.F64",
-	arm_VNMUL_F64:         "VNMUL.F64",
-	arm_VNMUL_ZZ_F64:      "VNMUL.ZZ.F64",
-	arm_VSQRT_EQ_F32:      "VSQRT.EQ.F32",
-	arm_VSQRT_NE_F32:      "VSQRT.NE.F32",
-	arm_VSQRT_CS_F32:      "VSQRT.CS.F32",
-	arm_VSQRT_CC_F32:      "VSQRT.CC.F32",
-	arm_VSQRT_MI_F32:      "VSQRT.MI.F32",
-	arm_VSQRT_PL_F32:      "VSQRT.PL.F32",
-	arm_VSQRT_VS_F32:      "VSQRT.VS.F32",
-	arm_VSQRT_VC_F32:      "VSQRT.VC.F32",
-	arm_VSQRT_HI_F32:      "VSQRT.HI.F32",
-	arm_VSQRT_LS_F32:      "VSQRT.LS.F32",
-	arm_VSQRT_GE_F32:      "VSQRT.GE.F32",
-	arm_VSQRT_LT_F32:      "VSQRT.LT.F32",
-	arm_VSQRT_GT_F32:      "VSQRT.GT.F32",
-	arm_VSQRT_LE_F32:      "VSQRT.LE.F32",
-	arm_VSQRT_F32:         "VSQRT.F32",
-	arm_VSQRT_ZZ_F32:      "VSQRT.ZZ.F32",
-	arm_VSQRT_EQ_F64:      "VSQRT.EQ.F64",
-	arm_VSQRT_NE_F64:      "VSQRT.NE.F64",
-	arm_VSQRT_CS_F64:      "VSQRT.CS.F64",
-	arm_VSQRT_CC_F64:      "VSQRT.CC.F64",
-	arm_VSQRT_MI_F64:      "VSQRT.MI.F64",
-	arm_VSQRT_PL_F64:      "VSQRT.PL.F64",
-	arm_VSQRT_VS_F64:      "VSQRT.VS.F64",
-	arm_VSQRT_VC_F64:      "VSQRT.VC.F64",
-	arm_VSQRT_HI_F64:      "VSQRT.HI.F64",
-	arm_VSQRT_LS_F64:      "VSQRT.LS.F64",
-	arm_VSQRT_GE_F64:      "VSQRT.GE.F64",
-	arm_VSQRT_LT_F64:      "VSQRT.LT.F64",
-	arm_VSQRT_GT_F64:      "VSQRT.GT.F64",
-	arm_VSQRT_LE_F64:      "VSQRT.LE.F64",
-	arm_VSQRT_F64:         "VSQRT.F64",
-	arm_VSQRT_ZZ_F64:      "VSQRT.ZZ.F64",
-	arm_VSTR_EQ:           "VSTR.EQ",
-	arm_VSTR_NE:           "VSTR.NE",
-	arm_VSTR_CS:           "VSTR.CS",
-	arm_VSTR_CC:           "VSTR.CC",
-	arm_VSTR_MI:           "VSTR.MI",
-	arm_VSTR_PL:           "VSTR.PL",
-	arm_VSTR_VS:           "VSTR.VS",
-	arm_VSTR_VC:           "VSTR.VC",
-	arm_VSTR_HI:           "VSTR.HI",
-	arm_VSTR_LS:           "VSTR.LS",
-	arm_VSTR_GE:           "VSTR.GE",
-	arm_VSTR_LT:           "VSTR.LT",
-	arm_VSTR_GT:           "VSTR.GT",
-	arm_VSTR_LE:           "VSTR.LE",
-	arm_VSTR:              "VSTR",
-	arm_VSTR_ZZ:           "VSTR.ZZ",
-	arm_VSUB_EQ_F32:       "VSUB.EQ.F32",
-	arm_VSUB_NE_F32:       "VSUB.NE.F32",
-	arm_VSUB_CS_F32:       "VSUB.CS.F32",
-	arm_VSUB_CC_F32:       "VSUB.CC.F32",
-	arm_VSUB_MI_F32:       "VSUB.MI.F32",
-	arm_VSUB_PL_F32:       "VSUB.PL.F32",
-	arm_VSUB_VS_F32:       "VSUB.VS.F32",
-	arm_VSUB_VC_F32:       "VSUB.VC.F32",
-	arm_VSUB_HI_F32:       "VSUB.HI.F32",
-	arm_VSUB_LS_F32:       "VSUB.LS.F32",
-	arm_VSUB_GE_F32:       "VSUB.GE.F32",
-	arm_VSUB_LT_F32:       "VSUB.LT.F32",
-	arm_VSUB_GT_F32:       "VSUB.GT.F32",
-	arm_VSUB_LE_F32:       "VSUB.LE.F32",
-	arm_VSUB_F32:          "VSUB.F32",
-	arm_VSUB_ZZ_F32:       "VSUB.ZZ.F32",
-	arm_VSUB_EQ_F64:       "VSUB.EQ.F64",
-	arm_VSUB_NE_F64:       "VSUB.NE.F64",
-	arm_VSUB_CS_F64:       "VSUB.CS.F64",
-	arm_VSUB_CC_F64:       "VSUB.CC.F64",
-	arm_VSUB_MI_F64:       "VSUB.MI.F64",
-	arm_VSUB_PL_F64:       "VSUB.PL.F64",
-	arm_VSUB_VS_F64:       "VSUB.VS.F64",
-	arm_VSUB_VC_F64:       "VSUB.VC.F64",
-	arm_VSUB_HI_F64:       "VSUB.HI.F64",
-	arm_VSUB_LS_F64:       "VSUB.LS.F64",
-	arm_VSUB_GE_F64:       "VSUB.GE.F64",
-	arm_VSUB_LT_F64:       "VSUB.LT.F64",
-	arm_VSUB_GT_F64:       "VSUB.GT.F64",
-	arm_VSUB_LE_F64:       "VSUB.LE.F64",
-	arm_VSUB_F64:          "VSUB.F64",
-	arm_VSUB_ZZ_F64:       "VSUB.ZZ.F64",
-	arm_WFE_EQ:            "WFE.EQ",
-	arm_WFE_NE:            "WFE.NE",
-	arm_WFE_CS:            "WFE.CS",
-	arm_WFE_CC:            "WFE.CC",
-	arm_WFE_MI:            "WFE.MI",
-	arm_WFE_PL:            "WFE.PL",
-	arm_WFE_VS:            "WFE.VS",
-	arm_WFE_VC:            "WFE.VC",
-	arm_WFE_HI:            "WFE.HI",
-	arm_WFE_LS:            "WFE.LS",
-	arm_WFE_GE:            "WFE.GE",
-	arm_WFE_LT:            "WFE.LT",
-	arm_WFE_GT:            "WFE.GT",
-	arm_WFE_LE:            "WFE.LE",
-	arm_WFE:               "WFE",
-	arm_WFE_ZZ:            "WFE.ZZ",
-	arm_WFI_EQ:            "WFI.EQ",
-	arm_WFI_NE:            "WFI.NE",
-	arm_WFI_CS:            "WFI.CS",
-	arm_WFI_CC:            "WFI.CC",
-	arm_WFI_MI:            "WFI.MI",
-	arm_WFI_PL:            "WFI.PL",
-	arm_WFI_VS:            "WFI.VS",
-	arm_WFI_VC:            "WFI.VC",
-	arm_WFI_HI:            "WFI.HI",
-	arm_WFI_LS:            "WFI.LS",
-	arm_WFI_GE:            "WFI.GE",
-	arm_WFI_LT:            "WFI.LT",
-	arm_WFI_GT:            "WFI.GT",
-	arm_WFI_LE:            "WFI.LE",
-	arm_WFI:               "WFI",
-	arm_WFI_ZZ:            "WFI.ZZ",
-	arm_YIELD_EQ:          "YIELD.EQ",
-	arm_YIELD_NE:          "YIELD.NE",
-	arm_YIELD_CS:          "YIELD.CS",
-	arm_YIELD_CC:          "YIELD.CC",
-	arm_YIELD_MI:          "YIELD.MI",
-	arm_YIELD_PL:          "YIELD.PL",
-	arm_YIELD_VS:          "YIELD.VS",
-	arm_YIELD_VC:          "YIELD.VC",
-	arm_YIELD_HI:          "YIELD.HI",
-	arm_YIELD_LS:          "YIELD.LS",
-	arm_YIELD_GE:          "YIELD.GE",
-	arm_YIELD_LT:          "YIELD.LT",
-	arm_YIELD_GT:          "YIELD.GT",
-	arm_YIELD_LE:          "YIELD.LE",
-	arm_YIELD:             "YIELD",
-	arm_YIELD_ZZ:          "YIELD.ZZ",
-}
-
-var arm_instFormats = [...]arm_instFormat{
-	{0x0fe00000, 0x02a00000, 2, arm_ADC_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_const}},                      // ADC{S}<c> <Rd>,<Rn>,#<const> cond:4|0|0|1|0|1|0|1|S|Rn:4|Rd:4|imm12:12
-	{0x0fe00090, 0x00a00010, 4, arm_ADC_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_shift_R}},                  // ADC{S}<c> <Rd>,<Rn>,<Rm>,<type> <Rs> cond:4|0|0|0|0|1|0|1|S|Rn:4|Rd:4|Rs:4|0|type:2|1|Rm:4
-	{0x0fe00010, 0x00a00000, 2, arm_ADC_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_shift_imm}},                // ADC{S}<c> <Rd>,<Rn>,<Rm>{,<shift>} cond:4|0|0|0|0|1|0|1|S|Rn:4|Rd:4|imm5:5|type:2|0|Rm:4
-	{0x0fe00000, 0x02800000, 2, arm_ADD_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_const}},                      // ADD{S}<c> <Rd>,<Rn>,#<const> cond:4|0|0|1|0|1|0|0|S|Rn:4|Rd:4|imm12:12
-	{0x0fe00090, 0x00800010, 4, arm_ADD_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_shift_R}},                  // ADD{S}<c> <Rd>,<Rn>,<Rm>,<type> <Rs> cond:4|0|0|0|0|1|0|0|S|Rn:4|Rd:4|Rs:4|0|type:2|1|Rm:4
-	{0x0fe00010, 0x00800000, 2, arm_ADD_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_shift_imm}},                // ADD{S}<c> <Rd>,<Rn>,<Rm>{,<shift>} cond:4|0|0|0|0|1|0|0|S|Rn:4|Rd:4|imm5:5|type:2|0|Rm:4
-	{0x0fef0000, 0x028d0000, 2, arm_ADD_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_SP, arm_arg_const}},                        // ADD{S}<c> <Rd>,SP,#<const> cond:4|0|0|1|0|1|0|0|S|1|1|0|1|Rd:4|imm12:12
-	{0x0fef0010, 0x008d0000, 2, arm_ADD_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_SP, arm_arg_R_shift_imm}},                  // ADD{S}<c> <Rd>,SP,<Rm>{,<shift>} cond:4|0|0|0|0|1|0|0|S|1|1|0|1|Rd:4|imm5:5|type:2|0|Rm:4
-	{0x0fe00000, 0x02000000, 2, arm_AND_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_const}},                      // AND{S}<c> <Rd>,<Rn>,#<const> cond:4|0|0|1|0|0|0|0|S|Rn:4|Rd:4|imm12:12
-	{0x0fe00090, 0x00000010, 4, arm_AND_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_shift_R}},                  // AND{S}<c> <Rd>,<Rn>,<Rm>,<type> <Rs> cond:4|0|0|0|0|0|0|0|S|Rn:4|Rd:4|Rs:4|0|type:2|1|Rm:4
-	{0x0fe00010, 0x00000000, 2, arm_AND_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_shift_imm}},                // AND{S}<c> <Rd>,<Rn>,<Rm>{,<shift>} cond:4|0|0|0|0|0|0|0|S|Rn:4|Rd:4|imm5:5|type:2|0|Rm:4
-	{0x0fef0070, 0x01a00040, 4, arm_ASR_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0, arm_arg_imm5_32}},                     // ASR{S}<c> <Rd>,<Rm>,#<imm5_32> cond:4|0|0|0|1|1|0|1|S|0|0|0|0|Rd:4|imm5:5|1|0|0|Rm:4
-	{0x0fef00f0, 0x01a00050, 4, arm_ASR_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0, arm_arg_R_8}},                         // ASR{S}<c> <Rd>,<Rn>,<Rm> cond:4|0|0|0|1|1|0|1|S|0|0|0|0|Rd:4|Rm:4|0|1|0|1|Rn:4
-	{0x0f000000, 0x0a000000, 4, arm_B_EQ, 0x1c04, arm_instArgs{arm_arg_label24}},                                                      // B<c> <label24> cond:4|1|0|1|0|imm24:24
-	{0x0fe0007f, 0x07c0001f, 4, arm_BFC_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_imm5, arm_arg_lsb_width}},                      // BFC<c> <Rd>,#<lsb>,#<width> cond:4|0|1|1|1|1|1|0|msb:5|Rd:4|lsb:5|0|0|1|1|1|1|1
-	{0x0fe00070, 0x07c00010, 2, arm_BFI_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0, arm_arg_imm5, arm_arg_lsb_width}},         // BFI<c> <Rd>,<Rn>,#<lsb>,#<width> cond:4|0|1|1|1|1|1|0|msb:5|Rd:4|lsb:5|0|0|1|Rn:4
-	{0x0fe00000, 0x03c00000, 2, arm_BIC_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_const}},                      // BIC{S}<c> <Rd>,<Rn>,#<const> cond:4|0|0|1|1|1|1|0|S|Rn:4|Rd:4|imm12:12
-	{0x0fe00090, 0x01c00010, 4, arm_BIC_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_shift_R}},                  // BIC{S}<c> <Rd>,<Rn>,<Rm>,<type> <Rs> cond:4|0|0|0|1|1|1|0|S|Rn:4|Rd:4|Rs:4|0|type:2|1|Rm:4
-	{0x0fe00010, 0x01c00000, 2, arm_BIC_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_shift_imm}},                // BIC{S}<c> <Rd>,<Rn>,<Rm>{,<shift>} cond:4|0|0|0|1|1|1|0|S|Rn:4|Rd:4|imm5:5|type:2|0|Rm:4
-	{0x0ff000f0, 0x01200070, 4, arm_BKPT_EQ, 0x1c04, arm_instArgs{arm_arg_imm_12at8_4at0}},                                            // BKPT<c> #<imm12+4> cond:4|0|0|0|1|0|0|1|0|imm12:12|0|1|1|1|imm4:4
-	{0x0f000000, 0x0b000000, 4, arm_BL_EQ, 0x1c04, arm_instArgs{arm_arg_label24}},                                                     // BL<c> <label24> cond:4|1|0|1|1|imm24:24
-	{0xfe000000, 0xfa000000, 4, arm_BLX, 0x0, arm_instArgs{arm_arg_label24H}},                                                         // BLX <label24H> 1|1|1|1|1|0|1|H|imm24:24
-	{0x0ffffff0, 0x012fff30, 4, arm_BLX_EQ, 0x1c04, arm_instArgs{arm_arg_R_0}},                                                        // BLX<c> <Rm> cond:4|0|0|0|1|0|0|1|0|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|0|0|1|1|Rm:4
-	{0x0ff000f0, 0x012fff30, 3, arm_BLX_EQ, 0x1c04, arm_instArgs{arm_arg_R_0}},                                                        // BLX<c> <Rm> cond:4|0|0|0|1|0|0|1|0|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|0|0|1|1|Rm:4
-	{0x0ffffff0, 0x012fff10, 4, arm_BX_EQ, 0x1c04, arm_instArgs{arm_arg_R_0}},                                                         // BX<c> <Rm> cond:4|0|0|0|1|0|0|1|0|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|0|0|0|1|Rm:4
-	{0x0ff000f0, 0x012fff10, 3, arm_BX_EQ, 0x1c04, arm_instArgs{arm_arg_R_0}},                                                         // BX<c> <Rm> cond:4|0|0|0|1|0|0|1|0|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|0|0|0|1|Rm:4
-	{0x0ffffff0, 0x012fff20, 4, arm_BXJ_EQ, 0x1c04, arm_instArgs{arm_arg_R_0}},                                                        // BXJ<c> <Rm> cond:4|0|0|0|1|0|0|1|0|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|0|0|1|0|Rm:4
-	{0x0ff000f0, 0x012fff20, 3, arm_BXJ_EQ, 0x1c04, arm_instArgs{arm_arg_R_0}},                                                        // BXJ<c> <Rm> cond:4|0|0|0|1|0|0|1|0|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|0|0|1|0|Rm:4
-	{0xffffffff, 0xf57ff01f, 4, arm_CLREX, 0x0, arm_instArgs{}},                                                                       // CLREX 1|1|1|1|0|1|0|1|0|1|1|1|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(0)|(0)|(0)|(0)|0|0|0|1|(1)|(1)|(1)|(1)
-	{0xfff000f0, 0xf57ff01f, 3, arm_CLREX, 0x0, arm_instArgs{}},                                                                       // CLREX 1|1|1|1|0|1|0|1|0|1|1|1|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(0)|(0)|(0)|(0)|0|0|0|1|(1)|(1)|(1)|(1)
-	{0x0fff0ff0, 0x016f0f10, 4, arm_CLZ_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0}},                                          // CLZ<c> <Rd>,<Rm> cond:4|0|0|0|1|0|1|1|0|(1)|(1)|(1)|(1)|Rd:4|(1)|(1)|(1)|(1)|0|0|0|1|Rm:4
-	{0x0ff000f0, 0x016f0f10, 3, arm_CLZ_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0}},                                          // CLZ<c> <Rd>,<Rm> cond:4|0|0|0|1|0|1|1|0|(1)|(1)|(1)|(1)|Rd:4|(1)|(1)|(1)|(1)|0|0|0|1|Rm:4
-	{0x0ff0f000, 0x03700000, 4, arm_CMN_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_const}},                                        // CMN<c> <Rn>,#<const> cond:4|0|0|1|1|0|1|1|1|Rn:4|(0)|(0)|(0)|(0)|imm12:12
-	{0x0ff00000, 0x03700000, 3, arm_CMN_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_const}},                                        // CMN<c> <Rn>,#<const> cond:4|0|0|1|1|0|1|1|1|Rn:4|(0)|(0)|(0)|(0)|imm12:12
-	{0x0ff0f090, 0x01700010, 4, arm_CMN_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_R_shift_R}},                                    // CMN<c> <Rn>,<Rm>,<type> <Rs> cond:4|0|0|0|1|0|1|1|1|Rn:4|(0)|(0)|(0)|(0)|Rs:4|0|type:2|1|Rm:4
-	{0x0ff00090, 0x01700010, 3, arm_CMN_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_R_shift_R}},                                    // CMN<c> <Rn>,<Rm>,<type> <Rs> cond:4|0|0|0|1|0|1|1|1|Rn:4|(0)|(0)|(0)|(0)|Rs:4|0|type:2|1|Rm:4
-	{0x0ff0f010, 0x01700000, 4, arm_CMN_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_R_shift_imm}},                                  // CMN<c> <Rn>,<Rm>{,<shift>} cond:4|0|0|0|1|0|1|1|1|Rn:4|(0)|(0)|(0)|(0)|imm5:5|type:2|0|Rm:4
-	{0x0ff00010, 0x01700000, 3, arm_CMN_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_R_shift_imm}},                                  // CMN<c> <Rn>,<Rm>{,<shift>} cond:4|0|0|0|1|0|1|1|1|Rn:4|(0)|(0)|(0)|(0)|imm5:5|type:2|0|Rm:4
-	{0x0ff0f000, 0x03500000, 4, arm_CMP_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_const}},                                        // CMP<c> <Rn>,#<const> cond:4|0|0|1|1|0|1|0|1|Rn:4|(0)|(0)|(0)|(0)|imm12:12
-	{0x0ff00000, 0x03500000, 3, arm_CMP_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_const}},                                        // CMP<c> <Rn>,#<const> cond:4|0|0|1|1|0|1|0|1|Rn:4|(0)|(0)|(0)|(0)|imm12:12
-	{0x0ff0f090, 0x01500010, 4, arm_CMP_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_R_shift_R}},                                    // CMP<c> <Rn>,<Rm>,<type> <Rs> cond:4|0|0|0|1|0|1|0|1|Rn:4|(0)|(0)|(0)|(0)|Rs:4|0|type:2|1|Rm:4
-	{0x0ff00090, 0x01500010, 3, arm_CMP_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_R_shift_R}},                                    // CMP<c> <Rn>,<Rm>,<type> <Rs> cond:4|0|0|0|1|0|1|0|1|Rn:4|(0)|(0)|(0)|(0)|Rs:4|0|type:2|1|Rm:4
-	{0x0ff0f010, 0x01500000, 4, arm_CMP_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_R_shift_imm}},                                  // CMP<c> <Rn>,<Rm>{,<shift>} cond:4|0|0|0|1|0|1|0|1|Rn:4|(0)|(0)|(0)|(0)|imm5:5|type:2|0|Rm:4
-	{0x0ff00010, 0x01500000, 3, arm_CMP_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_R_shift_imm}},                                  // CMP<c> <Rn>,<Rm>{,<shift>} cond:4|0|0|0|1|0|1|0|1|Rn:4|(0)|(0)|(0)|(0)|imm5:5|type:2|0|Rm:4
-	{0x0ffffff0, 0x0320f0f0, 4, arm_DBG_EQ, 0x1c04, arm_instArgs{arm_arg_option}},                                                     // DBG<c> #<option> cond:4|0|0|1|1|0|0|1|0|0|0|0|0|(1)|(1)|(1)|(1)|(0)|(0)|(0)|(0)|1|1|1|1|option:4
-	{0x0fff00f0, 0x0320f0f0, 3, arm_DBG_EQ, 0x1c04, arm_instArgs{arm_arg_option}},                                                     // DBG<c> #<option> cond:4|0|0|1|1|0|0|1|0|0|0|0|0|(1)|(1)|(1)|(1)|(0)|(0)|(0)|(0)|1|1|1|1|option:4
-	{0xfffffff0, 0xf57ff050, 4, arm_DMB, 0x0, arm_instArgs{arm_arg_option}},                                                           // DMB #<option> 1|1|1|1|0|1|0|1|0|1|1|1|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(0)|(0)|(0)|(0)|0|1|0|1|option:4
-	{0xfff000f0, 0xf57ff050, 3, arm_DMB, 0x0, arm_instArgs{arm_arg_option}},                                                           // DMB #<option> 1|1|1|1|0|1|0|1|0|1|1|1|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(0)|(0)|(0)|(0)|0|1|0|1|option:4
-	{0xfffffff0, 0xf57ff040, 4, arm_DSB, 0x0, arm_instArgs{arm_arg_option}},                                                           // DSB #<option> 1|1|1|1|0|1|0|1|0|1|1|1|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(0)|(0)|(0)|(0)|0|1|0|0|option:4
-	{0xfff000f0, 0xf57ff040, 3, arm_DSB, 0x0, arm_instArgs{arm_arg_option}},                                                           // DSB #<option> 1|1|1|1|0|1|0|1|0|1|1|1|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(0)|(0)|(0)|(0)|0|1|0|0|option:4
-	{0x0fe00000, 0x02200000, 2, arm_EOR_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_const}},                      // EOR{S}<c> <Rd>,<Rn>,#<const> cond:4|0|0|1|0|0|0|1|S|Rn:4|Rd:4|imm12:12
-	{0x0fe00090, 0x00200010, 4, arm_EOR_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_shift_R}},                  // EOR{S}<c> <Rd>,<Rn>,<Rm>,<type> <Rs> cond:4|0|0|0|0|0|0|1|S|Rn:4|Rd:4|Rs:4|0|type:2|1|Rm:4
-	{0x0fe00010, 0x00200000, 2, arm_EOR_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_shift_imm}},                // EOR{S}<c> <Rd>,<Rn>,<Rm>{,<shift>} cond:4|0|0|0|0|0|0|1|S|Rn:4|Rd:4|imm5:5|type:2|0|Rm:4
-	{0xfffffff0, 0xf57ff060, 4, arm_ISB, 0x0, arm_instArgs{arm_arg_option}},                                                           // ISB #<option> 1|1|1|1|0|1|0|1|0|1|1|1|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(0)|(0)|(0)|(0)|0|1|1|0|option:4
-	{0xfff000f0, 0xf57ff060, 3, arm_ISB, 0x0, arm_instArgs{arm_arg_option}},                                                           // ISB #<option> 1|1|1|1|0|1|0|1|0|1|1|1|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(1)|(0)|(0)|(0)|(0)|0|1|1|0|option:4
-	{0x0fd00000, 0x08900000, 2, arm_LDM_EQ, 0x1c04, arm_instArgs{arm_arg_R_16_WB, arm_arg_registers}},                                 // LDM<c> <Rn>{!},<registers> cond:4|1|0|0|0|1|0|W|1|Rn:4|register_list:16
-	{0x0fd00000, 0x08100000, 4, arm_LDMDA_EQ, 0x1c04, arm_instArgs{arm_arg_R_16_WB, arm_arg_registers}},                               // LDMDA<c> <Rn>{!},<registers> cond:4|1|0|0|0|0|0|W|1|Rn:4|register_list:16
-	{0x0fd00000, 0x09100000, 4, arm_LDMDB_EQ, 0x1c04, arm_instArgs{arm_arg_R_16_WB, arm_arg_registers}},                               // LDMDB<c> <Rn>{!},<registers> cond:4|1|0|0|1|0|0|W|1|Rn:4|register_list:16
-	{0x0fd00000, 0x09900000, 4, arm_LDMIB_EQ, 0x1c04, arm_instArgs{arm_arg_R_16_WB, arm_arg_registers}},                               // LDMIB<c> <Rn>{!},<registers> cond:4|1|0|0|1|1|0|W|1|Rn:4|register_list:16
-	{0x0f7f0000, 0x051f0000, 4, arm_LDR_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_label_pm_12}},                                  // LDR<c> <Rt>,<label+/-12> cond:4|0|1|0|(1)|U|0|(0)|1|1|1|1|1|Rt:4|imm12:12
-	{0x0e5f0000, 0x051f0000, 3, arm_LDR_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_label_pm_12}},                                  // LDR<c> <Rt>,<label+/-12> cond:4|0|1|0|(1)|U|0|(0)|1|1|1|1|1|Rt:4|imm12:12
-	{0x0e500010, 0x06100000, 2, arm_LDR_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R_pm_R_shift_imm_W}},                       // LDR<c> <Rt>,[<Rn>,+/-<Rm>{, <shift>}]{!} cond:4|0|1|1|P|U|0|W|1|Rn:4|Rt:4|imm5:5|type:2|0|Rm:4
-	{0x0e500000, 0x04100000, 2, arm_LDR_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R_pm_imm12_W}},                             // LDR<c> <Rt>,[<Rn>{,#+/-<imm12>}]{!} cond:4|0|1|0|P|U|0|W|1|Rn:4|Rt:4|imm12:12
-	{0x0f7f0000, 0x055f0000, 4, arm_LDRB_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_label_pm_12}},                                 // LDRB<c> <Rt>,<label+/-12> cond:4|0|1|0|(1)|U|1|(0)|1|1|1|1|1|Rt:4|imm12:12
-	{0x0e5f0000, 0x055f0000, 3, arm_LDRB_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_label_pm_12}},                                 // LDRB<c> <Rt>,<label+/-12> cond:4|0|1|0|(1)|U|1|(0)|1|1|1|1|1|Rt:4|imm12:12
-	{0x0e500010, 0x06500000, 2, arm_LDRB_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R_pm_R_shift_imm_W}},                      // LDRB<c> <Rt>,[<Rn>,+/-<Rm>{, <shift>}]{!} cond:4|0|1|1|P|U|1|W|1|Rn:4|Rt:4|imm5:5|type:2|0|Rm:4
-	{0x0e500000, 0x04500000, 2, arm_LDRB_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R_pm_imm12_W}},                            // LDRB<c> <Rt>,[<Rn>{,#+/-<imm12>}]{!} cond:4|0|1|0|P|U|1|W|1|Rn:4|Rt:4|imm12:12
-	{0x0f700000, 0x04700000, 4, arm_LDRBT_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R_pm_imm12_postindex}},                   // LDRBT<c> <Rt>,[<Rn>],#+/-<imm12> cond:4|0|1|0|0|U|1|1|1|Rn:4|Rt:4|imm12:12
-	{0x0f700010, 0x06700000, 4, arm_LDRBT_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R_pm_R_shift_imm_postindex}},             // LDRBT<c> <Rt>,[<Rn>],+/-<Rm>{, <shift>} cond:4|0|1|1|0|U|1|1|1|Rn:4|Rt:4|imm5:5|type:2|0|Rm:4
-	{0x0e500ff0, 0x000000d0, 4, arm_LDRD_EQ, 0x1c04, arm_instArgs{arm_arg_R1_12, arm_arg_R2_12, arm_arg_mem_R_pm_R_W}},                // LDRD<c> <Rt1>,<Rt2>,[<Rn>,+/-<Rm>]{!} cond:4|0|0|0|P|U|0|W|0|Rn:4|Rt:4|(0)|(0)|(0)|(0)|1|1|0|1|Rm:4
-	{0x0e5000f0, 0x000000d0, 3, arm_LDRD_EQ, 0x1c04, arm_instArgs{arm_arg_R1_12, arm_arg_R2_12, arm_arg_mem_R_pm_R_W}},                // LDRD<c> <Rt1>,<Rt2>,[<Rn>,+/-<Rm>]{!} cond:4|0|0|0|P|U|0|W|0|Rn:4|Rt:4|(0)|(0)|(0)|(0)|1|1|0|1|Rm:4
-	{0x0e5000f0, 0x004000d0, 2, arm_LDRD_EQ, 0x1c04, arm_instArgs{arm_arg_R1_12, arm_arg_R2_12, arm_arg_mem_R_pm_imm8_W}},             // LDRD<c> <Rt1>,<Rt2>,[<Rn>{,#+/-<imm8>}]{!} cond:4|0|0|0|P|U|1|W|0|Rn:4|Rt:4|imm4H:4|1|1|0|1|imm4L:4
-	{0x0ff00fff, 0x01900f9f, 4, arm_LDREX_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R}},                                      // LDREX<c> <Rt>,[<Rn>] cond:4|0|0|0|1|1|0|0|1|Rn:4|Rt:4|(1)|(1)|(1)|(1)|1|0|0|1|(1)|(1)|(1)|(1)
-	{0x0ff000f0, 0x01900f9f, 3, arm_LDREX_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R}},                                      // LDREX<c> <Rt>,[<Rn>] cond:4|0|0|0|1|1|0|0|1|Rn:4|Rt:4|(1)|(1)|(1)|(1)|1|0|0|1|(1)|(1)|(1)|(1)
-	{0x0ff00fff, 0x01d00f9f, 4, arm_LDREXB_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R}},                                     // LDREXB<c> <Rt>, [<Rn>] cond:4|0|0|0|1|1|1|0|1|Rn:4|Rt:4|(1)|(1)|(1)|(1)|1|0|0|1|(1)|(1)|(1)|(1)
-	{0x0ff000f0, 0x01d00f9f, 3, arm_LDREXB_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R}},                                     // LDREXB<c> <Rt>, [<Rn>] cond:4|0|0|0|1|1|1|0|1|Rn:4|Rt:4|(1)|(1)|(1)|(1)|1|0|0|1|(1)|(1)|(1)|(1)
-	{0x0ff00fff, 0x01b00f9f, 4, arm_LDREXD_EQ, 0x1c04, arm_instArgs{arm_arg_R1_12, arm_arg_R2_12, arm_arg_mem_R}},                     // LDREXD<c> <Rt1>,<Rt2>,[<Rn>] cond:4|0|0|0|1|1|0|1|1|Rn:4|Rt:4|(1)|(1)|(1)|(1)|1|0|0|1|(1)|(1)|(1)|(1)
-	{0x0ff000f0, 0x01b00f9f, 3, arm_LDREXD_EQ, 0x1c04, arm_instArgs{arm_arg_R1_12, arm_arg_R2_12, arm_arg_mem_R}},                     // LDREXD<c> <Rt1>,<Rt2>,[<Rn>] cond:4|0|0|0|1|1|0|1|1|Rn:4|Rt:4|(1)|(1)|(1)|(1)|1|0|0|1|(1)|(1)|(1)|(1)
-	{0x0ff00fff, 0x01f00f9f, 4, arm_LDREXH_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R}},                                     // LDREXH<c> <Rt>, [<Rn>] cond:4|0|0|0|1|1|1|1|1|Rn:4|Rt:4|(1)|(1)|(1)|(1)|1|0|0|1|(1)|(1)|(1)|(1)
-	{0x0ff000f0, 0x01f00f9f, 3, arm_LDREXH_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R}},                                     // LDREXH<c> <Rt>, [<Rn>] cond:4|0|0|0|1|1|1|1|1|Rn:4|Rt:4|(1)|(1)|(1)|(1)|1|0|0|1|(1)|(1)|(1)|(1)
-	{0x0e500ff0, 0x001000b0, 2, arm_LDRH_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R_pm_R_W}},                                // LDRH<c> <Rt>,[<Rn>,+/-<Rm>]{!} cond:4|0|0|0|P|U|0|W|1|Rn:4|Rt:4|0|0|0|0|1|0|1|1|Rm:4
-	{0x0e5000f0, 0x005000b0, 2, arm_LDRH_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R_pm_imm8_W}},                             // LDRH<c> <Rt>,[<Rn>{,#+/-<imm8>}]{!} cond:4|0|0|0|P|U|1|W|1|Rn:4|Rt:4|imm4H:4|1|0|1|1|imm4L:4
-	{0x0f7000f0, 0x007000b0, 4, arm_LDRHT_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R_pm_imm8_postindex}},                    // LDRHT<c> <Rt>, [<Rn>] {,#+/-<imm8>} cond:4|0|0|0|0|U|1|1|1|Rn:4|Rt:4|imm4H:4|1|0|1|1|imm4L:4
-	{0x0f700ff0, 0x003000b0, 4, arm_LDRHT_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R_pm_R_postindex}},                       // LDRHT<c> <Rt>, [<Rn>], +/-<Rm> cond:4|0|0|0|0|U|0|1|1|Rn:4|Rt:4|0|0|0|0|1|0|1|1|Rm:4
-	{0x0e500ff0, 0x001000d0, 2, arm_LDRSB_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R_pm_R_W}},                               // LDRSB<c> <Rt>,[<Rn>,+/-<Rm>]{!} cond:4|0|0|0|P|U|0|W|1|Rn:4|Rt:4|0|0|0|0|1|1|0|1|Rm:4
-	{0x0e5000f0, 0x005000d0, 2, arm_LDRSB_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R_pm_imm8_W}},                            // LDRSB<c> <Rt>,[<Rn>{,#+/-<imm8>}]{!} cond:4|0|0|0|P|U|1|W|1|Rn:4|Rt:4|imm4H:4|1|1|0|1|imm4L:4
-	{0x0f7000f0, 0x007000d0, 4, arm_LDRSBT_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R_pm_imm8_postindex}},                   // LDRSBT<c> <Rt>, [<Rn>] {,#+/-<imm8>} cond:4|0|0|0|0|U|1|1|1|Rn:4|Rt:4|imm4H:4|1|1|0|1|imm4L:4
-	{0x0f700ff0, 0x003000d0, 4, arm_LDRSBT_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R_pm_R_postindex}},                      // LDRSBT<c> <Rt>, [<Rn>], +/-<Rm> cond:4|0|0|0|0|U|0|1|1|Rn:4|Rt:4|0|0|0|0|1|1|0|1|Rm:4
-	{0x0e500ff0, 0x001000f0, 2, arm_LDRSH_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R_pm_R_W}},                               // LDRSH<c> <Rt>,[<Rn>,+/-<Rm>]{!} cond:4|0|0|0|P|U|0|W|1|Rn:4|Rt:4|0|0|0|0|1|1|1|1|Rm:4
-	{0x0e5000f0, 0x005000f0, 2, arm_LDRSH_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R_pm_imm8_W}},                            // LDRSH<c> <Rt>,[<Rn>{,#+/-<imm8>}]{!} cond:4|0|0|0|P|U|1|W|1|Rn:4|Rt:4|imm4H:4|1|1|1|1|imm4L:4
-	{0x0f7000f0, 0x007000f0, 4, arm_LDRSHT_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R_pm_imm8_postindex}},                   // LDRSHT<c> <Rt>, [<Rn>] {,#+/-<imm8>} cond:4|0|0|0|0|U|1|1|1|Rn:4|Rt:4|imm4H:4|1|1|1|1|imm4L:4
-	{0x0f700ff0, 0x003000f0, 4, arm_LDRSHT_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R_pm_R_postindex}},                      // LDRSHT<c> <Rt>, [<Rn>], +/-<Rm> cond:4|0|0|0|0|U|0|1|1|Rn:4|Rt:4|0|0|0|0|1|1|1|1|Rm:4
-	{0x0f700000, 0x04300000, 4, arm_LDRT_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R_pm_imm12_postindex}},                    // LDRT<c> <Rt>, [<Rn>] {,#+/-<imm12>} cond:4|0|1|0|0|U|0|1|1|Rn:4|Rt:4|imm12:12
-	{0x0f700010, 0x06300000, 4, arm_LDRT_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R_pm_R_shift_imm_postindex}},              // LDRT<c> <Rt>,[<Rn>],+/-<Rm>{, <shift>} cond:4|0|1|1|0|U|0|1|1|Rn:4|Rt:4|imm5:5|type:2|0|Rm:4
-	{0x0fef0070, 0x01a00000, 2, arm_LSL_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0, arm_arg_imm5_nz}},                     // LSL{S}<c> <Rd>,<Rm>,#<imm5_nz> cond:4|0|0|0|1|1|0|1|S|0|0|0|0|Rd:4|imm5:5|0|0|0|Rm:4
-	{0x0fef00f0, 0x01a00010, 4, arm_LSL_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0, arm_arg_R_8}},                         // LSL{S}<c> <Rd>,<Rn>,<Rm> cond:4|0|0|0|1|1|0|1|S|0|0|0|0|Rd:4|Rm:4|0|0|0|1|Rn:4
-	{0x0fef0070, 0x01a00020, 4, arm_LSR_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0, arm_arg_imm5_32}},                     // LSR{S}<c> <Rd>,<Rm>,#<imm5_32> cond:4|0|0|0|1|1|0|1|S|0|0|0|0|Rd:4|imm5:5|0|1|0|Rm:4
-	{0x0fef00f0, 0x01a00030, 4, arm_LSR_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0, arm_arg_R_8}},                         // LSR{S}<c> <Rd>,<Rn>,<Rm> cond:4|0|0|0|1|1|0|1|S|0|0|0|0|Rd:4|Rm:4|0|0|1|1|Rn:4
-	{0x0fe000f0, 0x00200090, 4, arm_MLA_EQ, 0x14011c04, arm_instArgs{arm_arg_R_16, arm_arg_R_0, arm_arg_R_8, arm_arg_R_12}},           // MLA{S}<c> <Rd>,<Rn>,<Rm>,<Ra> cond:4|0|0|0|0|0|0|1|S|Rd:4|Ra:4|Rm:4|1|0|0|1|Rn:4
-	{0x0ff000f0, 0x00600090, 4, arm_MLS_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_R_0, arm_arg_R_8, arm_arg_R_12}},               // MLS<c> <Rd>,<Rn>,<Rm>,<Ra> cond:4|0|0|0|0|0|1|1|0|Rd:4|Ra:4|Rm:4|1|0|0|1|Rn:4
-	{0x0ff00000, 0x03400000, 4, arm_MOVT_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_imm_4at16_12at0}},                             // MOVT<c> <Rd>,#<imm12+4> cond:4|0|0|1|1|0|1|0|0|imm4:4|Rd:4|imm12:12
-	{0x0ff00000, 0x03000000, 4, arm_MOVW_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_imm_4at16_12at0}},                             // MOVW<c> <Rd>,#<imm12+4> cond:4|0|0|1|1|0|0|0|0|imm4:4|Rd:4|imm12:12
-	{0x0fef0000, 0x03a00000, 2, arm_MOV_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_const}},                                    // MOV{S}<c> <Rd>,#<const> cond:4|0|0|1|1|1|0|1|S|0|0|0|0|Rd:4|imm12:12
-	{0x0fef0ff0, 0x01a00000, 2, arm_MOV_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0}},                                      // MOV{S}<c> <Rd>,<Rm> cond:4|0|0|0|1|1|0|1|S|0|0|0|0|Rd:4|0|0|0|0|0|0|0|0|Rm:4
-	{0x0fff0fff, 0x010f0000, 4, arm_MRS_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_APSR}},                                         // MRS<c> <Rd>,APSR cond:4|0|0|0|1|0|0|0|0|(1)|(1)|(1)|(1)|Rd:4|(0)|(0)|(0)|(0)|0|0|0|0|(0)|(0)|(0)|(0)
-	{0x0ff000f0, 0x010f0000, 3, arm_MRS_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_APSR}},                                         // MRS<c> <Rd>,APSR cond:4|0|0|0|1|0|0|0|0|(1)|(1)|(1)|(1)|Rd:4|(0)|(0)|(0)|(0)|0|0|0|0|(0)|(0)|(0)|(0)
-	{0x0fe0f0f0, 0x00000090, 4, arm_MUL_EQ, 0x14011c04, arm_instArgs{arm_arg_R_16, arm_arg_R_0, arm_arg_R_8}},                         // MUL{S}<c> <Rd>,<Rn>,<Rm> cond:4|0|0|0|0|0|0|0|S|Rd:4|(0)|(0)|(0)|(0)|Rm:4|1|0|0|1|Rn:4
-	{0x0fe000f0, 0x00000090, 3, arm_MUL_EQ, 0x14011c04, arm_instArgs{arm_arg_R_16, arm_arg_R_0, arm_arg_R_8}},                         // MUL{S}<c> <Rd>,<Rn>,<Rm> cond:4|0|0|0|0|0|0|0|S|Rd:4|(0)|(0)|(0)|(0)|Rm:4|1|0|0|1|Rn:4
-	{0x0fef0000, 0x03e00000, 2, arm_MVN_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_const}},                                    // MVN{S}<c> <Rd>,#<const> cond:4|0|0|1|1|1|1|1|S|(0)|(0)|(0)|(0)|Rd:4|imm12:12
-	{0x0fe00000, 0x03e00000, 1, arm_MVN_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_const}},                                    // MVN{S}<c> <Rd>,#<const> cond:4|0|0|1|1|1|1|1|S|(0)|(0)|(0)|(0)|Rd:4|imm12:12
-	{0x0fef0090, 0x01e00010, 4, arm_MVN_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_shift_R}},                                // MVN{S}<c> <Rd>,<Rm>,<type> <Rs> cond:4|0|0|0|1|1|1|1|S|(0)|(0)|(0)|(0)|Rd:4|Rs:4|0|type:2|1|Rm:4
-	{0x0fe00090, 0x01e00010, 3, arm_MVN_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_shift_R}},                                // MVN{S}<c> <Rd>,<Rm>,<type> <Rs> cond:4|0|0|0|1|1|1|1|S|(0)|(0)|(0)|(0)|Rd:4|Rs:4|0|type:2|1|Rm:4
-	{0x0fef0010, 0x01e00000, 2, arm_MVN_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_shift_imm}},                              // MVN{S}<c> <Rd>,<Rm>{,<shift>} cond:4|0|0|0|1|1|1|1|S|(0)|(0)|(0)|(0)|Rd:4|imm5:5|type:2|0|Rm:4
-	{0x0fe00010, 0x01e00000, 1, arm_MVN_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_shift_imm}},                              // MVN{S}<c> <Rd>,<Rm>{,<shift>} cond:4|0|0|0|1|1|1|1|S|(0)|(0)|(0)|(0)|Rd:4|imm5:5|type:2|0|Rm:4
-	{0x0fffffff, 0x0320f000, 4, arm_NOP_EQ, 0x1c04, arm_instArgs{}},                                                                   // NOP<c> cond:4|0|0|1|1|0|0|1|0|0|0|0|0|(1)|(1)|(1)|(1)|(0)|(0)|(0)|(0)|0|0|0|0|0|0|0|0
-	{0x0fff00ff, 0x0320f000, 3, arm_NOP_EQ, 0x1c04, arm_instArgs{}},                                                                   // NOP<c> cond:4|0|0|1|1|0|0|1|0|0|0|0|0|(1)|(1)|(1)|(1)|(0)|(0)|(0)|(0)|0|0|0|0|0|0|0|0
-	{0x0fe00000, 0x03800000, 2, arm_ORR_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_const}},                      // ORR{S}<c> <Rd>,<Rn>,#<const> cond:4|0|0|1|1|1|0|0|S|Rn:4|Rd:4|imm12:12
-	{0x0fe00090, 0x01800010, 4, arm_ORR_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_shift_R}},                  // ORR{S}<c> <Rd>,<Rn>,<Rm>,<type> <Rs> cond:4|0|0|0|1|1|0|0|S|Rn:4|Rd:4|Rs:4|0|type:2|1|Rm:4
-	{0x0fe00010, 0x01800000, 2, arm_ORR_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_shift_imm}},                // ORR{S}<c> <Rd>,<Rn>,<Rm>{,<shift>} cond:4|0|0|0|1|1|0|0|S|Rn:4|Rd:4|imm5:5|type:2|0|Rm:4
-	{0x0ff00030, 0x06800010, 4, arm_PKHBT_EQ, 0x6011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_shift_imm}},               // PKH<BT,TB><c> <Rd>,<Rn>,<Rm>{,LSL #<imm5>} cond:4|0|1|1|0|1|0|0|0|Rn:4|Rd:4|imm5:5|tb|0|1|Rm:4
-	{0xff7ff000, 0xf55ff000, 4, arm_PLD, 0x0, arm_instArgs{arm_arg_label_pm_12}},                                                      // PLD <label+/-12> 1|1|1|1|0|1|0|1|U|(1)|0|1|1|1|1|1|(1)|(1)|(1)|(1)|imm12:12
-	{0xff3f0000, 0xf55ff000, 3, arm_PLD, 0x0, arm_instArgs{arm_arg_label_pm_12}},                                                      // PLD <label+/-12> 1|1|1|1|0|1|0|1|U|(1)|0|1|1|1|1|1|(1)|(1)|(1)|(1)|imm12:12
-	{0xff30f000, 0xf510f000, 2, arm_PLD_W, 0x1601, arm_instArgs{arm_arg_mem_R_pm_imm12_offset}},                                       // PLD{W} [<Rn>,#+/-<imm12>] 1|1|1|1|0|1|0|1|U|R|0|1|Rn:4|(1)|(1)|(1)|(1)|imm12:12
-	{0xff300000, 0xf510f000, 1, arm_PLD_W, 0x1601, arm_instArgs{arm_arg_mem_R_pm_imm12_offset}},                                       // PLD{W} [<Rn>,#+/-<imm12>] 1|1|1|1|0|1|0|1|U|R|0|1|Rn:4|(1)|(1)|(1)|(1)|imm12:12
-	{0xff30f010, 0xf710f000, 4, arm_PLD_W, 0x1601, arm_instArgs{arm_arg_mem_R_pm_R_shift_imm_offset}},                                 // PLD{W} [<Rn>,+/-<Rm>{, <shift>}] 1|1|1|1|0|1|1|1|U|R|0|1|Rn:4|(1)|(1)|(1)|(1)|imm5:5|type:2|0|Rm:4
-	{0xff300010, 0xf710f000, 3, arm_PLD_W, 0x1601, arm_instArgs{arm_arg_mem_R_pm_R_shift_imm_offset}},                                 // PLD{W} [<Rn>,+/-<Rm>{, <shift>}] 1|1|1|1|0|1|1|1|U|R|0|1|Rn:4|(1)|(1)|(1)|(1)|imm5:5|type:2|0|Rm:4
-	{0xff70f000, 0xf450f000, 4, arm_PLI, 0x0, arm_instArgs{arm_arg_mem_R_pm_imm12_offset}},                                            // PLI [<Rn>,#+/-<imm12>] 1|1|1|1|0|1|0|0|U|1|0|1|Rn:4|(1)|(1)|(1)|(1)|imm12:12
-	{0xff700000, 0xf450f000, 3, arm_PLI, 0x0, arm_instArgs{arm_arg_mem_R_pm_imm12_offset}},                                            // PLI [<Rn>,#+/-<imm12>] 1|1|1|1|0|1|0|0|U|1|0|1|Rn:4|(1)|(1)|(1)|(1)|imm12:12
-	{0xff70f010, 0xf650f000, 4, arm_PLI, 0x0, arm_instArgs{arm_arg_mem_R_pm_R_shift_imm_offset}},                                      // PLI [<Rn>,+/-<Rm>{, <shift>}] 1|1|1|1|0|1|1|0|U|1|0|1|Rn:4|(1)|(1)|(1)|(1)|imm5:5|type:2|0|Rm:4
-	{0xff700010, 0xf650f000, 3, arm_PLI, 0x0, arm_instArgs{arm_arg_mem_R_pm_R_shift_imm_offset}},                                      // PLI [<Rn>,+/-<Rm>{, <shift>}] 1|1|1|1|0|1|1|0|U|1|0|1|Rn:4|(1)|(1)|(1)|(1)|imm5:5|type:2|0|Rm:4
-	{0x0fff0000, 0x08bd0000, 4, arm_POP_EQ, 0x1c04, arm_instArgs{arm_arg_registers2}},                                                 // POP<c> <registers2> cond:4|1|0|0|0|1|0|1|1|1|1|0|1|register_list:16
-	{0x0fff0fff, 0x049d0004, 4, arm_POP_EQ, 0x1c04, arm_instArgs{arm_arg_registers1}},                                                 // POP<c> <registers1> cond:4|0|1|0|0|1|0|0|1|1|1|0|1|Rt:4|0|0|0|0|0|0|0|0|0|1|0|0
-	{0x0fff0000, 0x092d0000, 4, arm_PUSH_EQ, 0x1c04, arm_instArgs{arm_arg_registers2}},                                                // PUSH<c> <registers2> cond:4|1|0|0|1|0|0|1|0|1|1|0|1|register_list:16
-	{0x0fff0fff, 0x052d0004, 4, arm_PUSH_EQ, 0x1c04, arm_instArgs{arm_arg_registers1}},                                                // PUSH<c> <registers1> cond:4|0|1|0|1|0|0|1|0|1|1|0|1|Rt:4|0|0|0|0|0|0|0|0|0|1|0|0
-	{0x0ff00ff0, 0x06200f10, 4, arm_QADD16_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}},                         // QADD16<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|1|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|0|0|1|Rm:4
-	{0x0ff000f0, 0x06200f10, 3, arm_QADD16_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}},                         // QADD16<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|1|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|0|0|1|Rm:4
-	{0x0ff00ff0, 0x06200f90, 4, arm_QADD8_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}},                          // QADD8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|1|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|0|0|1|Rm:4
-	{0x0ff000f0, 0x06200f90, 3, arm_QADD8_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}},                          // QADD8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|1|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|0|0|1|Rm:4
-	{0x0ff00ff0, 0x01000050, 4, arm_QADD_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0, arm_arg_R_16}},                           // QADD<c> <Rd>,<Rm>,<Rn> cond:4|0|0|0|1|0|0|0|0|Rn:4|Rd:4|(0)|(0)|(0)|(0)|0|1|0|1|Rm:4
-	{0x0ff000f0, 0x01000050, 3, arm_QADD_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0, arm_arg_R_16}},                           // QADD<c> <Rd>,<Rm>,<Rn> cond:4|0|0|0|1|0|0|0|0|Rn:4|Rd:4|(0)|(0)|(0)|(0)|0|1|0|1|Rm:4
-	{0x0ff00ff0, 0x06200f30, 4, arm_QASX_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}},                           // QASX<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|1|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|0|1|1|Rm:4
-	{0x0ff000f0, 0x06200f30, 3, arm_QASX_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}},                           // QASX<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|1|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|0|1|1|Rm:4
-	{0x0ff00ff0, 0x01400050, 4, arm_QDADD_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0, arm_arg_R_16}},                          // QDADD<c> <Rd>,<Rm>,<Rn> cond:4|0|0|0|1|0|1|0|0|Rn:4|Rd:4|(0)|(0)|(0)|(0)|0|1|0|1|Rm:4
-	{0x0ff000f0, 0x01400050, 3, arm_QDADD_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0, arm_arg_R_16}},                          // QDADD<c> <Rd>,<Rm>,<Rn> cond:4|0|0|0|1|0|1|0|0|Rn:4|Rd:4|(0)|(0)|(0)|(0)|0|1|0|1|Rm:4
-	{0x0ff00ff0, 0x01600050, 4, arm_QDSUB_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0, arm_arg_R_16}},                          // QDSUB<c> <Rd>,<Rm>,<Rn> cond:4|0|0|0|1|0|1|1|0|Rn:4|Rd:4|0|0|0|0|0|1|0|1|Rm:4
-	{0x0ff00ff0, 0x06200f50, 4, arm_QSAX_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}},                           // QSAX<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|1|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|1|0|1|Rm:4
-	{0x0ff000f0, 0x06200f50, 3, arm_QSAX_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}},                           // QSAX<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|1|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|1|0|1|Rm:4
-	{0x0ff00ff0, 0x06200f70, 4, arm_QSUB16_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}},                         // QSUB16<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|1|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|1|1|1|Rm:4
-	{0x0ff000f0, 0x06200f70, 3, arm_QSUB16_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}},                         // QSUB16<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|1|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|1|1|1|Rm:4
-	{0x0ff00ff0, 0x06200ff0, 4, arm_QSUB8_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}},                          // QSUB8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|1|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|1|1|1|Rm:4
-	{0x0ff000f0, 0x06200ff0, 3, arm_QSUB8_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}},                          // QSUB8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|1|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|1|1|1|Rm:4
-	{0x0ff00ff0, 0x01200050, 4, arm_QSUB_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0, arm_arg_R_16}},                           // QSUB<c> <Rd>,<Rm>,<Rn> cond:4|0|0|0|1|0|0|1|0|Rn:4|Rd:4|0|0|0|0|0|1|0|1|Rm:4
-	{0x0fff0ff0, 0x06ff0f30, 4, arm_RBIT_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0}},                                         // RBIT<c> <Rd>,<Rm> cond:4|0|1|1|0|1|1|1|1|(1)|(1)|(1)|(1)|Rd:4|(1)|(1)|(1)|(1)|0|0|1|1|Rm:4
-	{0x0ff000f0, 0x06ff0f30, 3, arm_RBIT_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0}},                                         // RBIT<c> <Rd>,<Rm> cond:4|0|1|1|0|1|1|1|1|(1)|(1)|(1)|(1)|Rd:4|(1)|(1)|(1)|(1)|0|0|1|1|Rm:4
-	{0x0fff0ff0, 0x06bf0fb0, 4, arm_REV16_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0}},                                        // REV16<c> <Rd>,<Rm> cond:4|0|1|1|0|1|0|1|1|(1)|(1)|(1)|(1)|Rd:4|(1)|(1)|(1)|(1)|1|0|1|1|Rm:4
-	{0x0ff000f0, 0x06bf0fb0, 3, arm_REV16_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0}},                                        // REV16<c> <Rd>,<Rm> cond:4|0|1|1|0|1|0|1|1|(1)|(1)|(1)|(1)|Rd:4|(1)|(1)|(1)|(1)|1|0|1|1|Rm:4
-	{0x0fff0ff0, 0x06bf0f30, 4, arm_REV_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0}},                                          // REV<c> <Rd>,<Rm> cond:4|0|1|1|0|1|0|1|1|(1)|(1)|(1)|(1)|Rd:4|(1)|(1)|(1)|(1)|0|0|1|1|Rm:4
-	{0x0ff000f0, 0x06bf0f30, 3, arm_REV_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0}},                                          // REV<c> <Rd>,<Rm> cond:4|0|1|1|0|1|0|1|1|(1)|(1)|(1)|(1)|Rd:4|(1)|(1)|(1)|(1)|0|0|1|1|Rm:4
-	{0x0fff0ff0, 0x06ff0fb0, 4, arm_REVSH_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0}},                                        // REVSH<c> <Rd>,<Rm> cond:4|0|1|1|0|1|1|1|1|(1)|(1)|(1)|(1)|Rd:4|(1)|(1)|(1)|(1)|1|0|1|1|Rm:4
-	{0x0ff000f0, 0x06ff0fb0, 3, arm_REVSH_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0}},                                        // REVSH<c> <Rd>,<Rm> cond:4|0|1|1|0|1|1|1|1|(1)|(1)|(1)|(1)|Rd:4|(1)|(1)|(1)|(1)|1|0|1|1|Rm:4
-	{0x0fef0070, 0x01a00060, 2, arm_ROR_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0, arm_arg_imm5}},                        // ROR{S}<c> <Rd>,<Rm>,#<imm5> cond:4|0|0|0|1|1|0|1|S|0|0|0|0|Rd:4|imm5:5|1|1|0|Rm:4
-	{0x0fef00f0, 0x01a00070, 4, arm_ROR_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0, arm_arg_R_8}},                         // ROR{S}<c> <Rd>,<Rn>,<Rm> cond:4|0|0|0|1|1|0|1|S|0|0|0|0|Rd:4|Rm:4|0|1|1|1|Rn:4
-	{0x0fef0ff0, 0x01a00060, 4, arm_RRX_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0}},                                      // RRX{S}<c> <Rd>,<Rm> cond:4|0|0|0|1|1|0|1|S|0|0|0|0|Rd:4|0|0|0|0|0|1|1|0|Rm:4
-	{0x0fe00000, 0x02600000, 2, arm_RSB_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_const}},                      // RSB{S}<c> <Rd>,<Rn>,#<const> cond:4|0|0|1|0|0|1|1|S|Rn:4|Rd:4|imm12:12
-	{0x0fe00090, 0x00600010, 4, arm_RSB_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_shift_R}},                  // RSB{S}<c> <Rd>,<Rn>,<Rm>,<type> <Rs> cond:4|0|0|0|0|0|1|1|S|Rn:4|Rd:4|Rs:4|0|type:2|1|Rm:4
-	{0x0fe00010, 0x00600000, 2, arm_RSB_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_shift_imm}},                // RSB{S}<c> <Rd>,<Rn>,<Rm>{,<shift>} cond:4|0|0|0|0|0|1|1|S|Rn:4|Rd:4|imm5:5|type:2|0|Rm:4
-	{0x0fe00000, 0x02e00000, 2, arm_RSC_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_const}},                      // RSC{S}<c> <Rd>,<Rn>,#<const> cond:4|0|0|1|0|1|1|1|S|Rn:4|Rd:4|imm12:12
-	{0x0fe00090, 0x00e00010, 4, arm_RSC_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_shift_R}},                  // RSC{S}<c> <Rd>,<Rn>,<Rm>,<type> <Rs> cond:4|0|0|0|0|1|1|1|S|Rn:4|Rd:4|Rs:4|0|type:2|1|Rm:4
-	{0x0fe00010, 0x00e00000, 2, arm_RSC_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_shift_imm}},                // RSC{S}<c> <Rd>,<Rn>,<Rm>{,<shift>} cond:4|0|0|0|0|1|1|1|S|Rn:4|Rd:4|imm5:5|type:2|0|Rm:4
-	{0x0ff00ff0, 0x06100f10, 4, arm_SADD16_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}},                         // SADD16<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|0|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|0|0|1|Rm:4
-	{0x0ff000f0, 0x06100f10, 3, arm_SADD16_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}},                         // SADD16<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|0|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|0|0|1|Rm:4
-	{0x0ff00ff0, 0x06100f90, 4, arm_SADD8_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}},                          // SADD8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|0|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|0|0|1|Rm:4
-	{0x0ff000f0, 0x06100f90, 3, arm_SADD8_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}},                          // SADD8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|0|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|0|0|1|Rm:4
-	{0x0ff00ff0, 0x06100f30, 4, arm_SASX_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}},                           // SASX<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|0|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|0|1|1|Rm:4
-	{0x0ff000f0, 0x06100f30, 3, arm_SASX_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}},                           // SASX<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|0|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|0|1|1|Rm:4
-	{0x0fe00000, 0x02c00000, 2, arm_SBC_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_const}},                      // SBC{S}<c> <Rd>,<Rn>,#<const> cond:4|0|0|1|0|1|1|0|S|Rn:4|Rd:4|imm12:12
-	{0x0fe00090, 0x00c00010, 4, arm_SBC_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_shift_R}},                  // SBC{S}<c> <Rd>,<Rn>,<Rm>,<type> <Rs> cond:4|0|0|0|0|1|1|0|S|Rn:4|Rd:4|Rs:4|0|type:2|1|Rm:4
-	{0x0fe00010, 0x00c00000, 2, arm_SBC_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_shift_imm}},                // SBC{S}<c> <Rd>,<Rn>,<Rm>{,<shift>} cond:4|0|0|0|0|1|1|0|S|Rn:4|Rd:4|imm5:5|type:2|0|Rm:4
-	{0x0fe00070, 0x07a00050, 4, arm_SBFX_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0, arm_arg_imm5, arm_arg_widthm1}},          // SBFX<c> <Rd>,<Rn>,#<lsb>,#<widthm1> cond:4|0|1|1|1|1|0|1|widthm1:5|Rd:4|lsb:5|1|0|1|Rn:4
-	{0x0ff00ff0, 0x06800fb0, 4, arm_SEL_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}},                            // SEL<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|1|0|0|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|0|1|1|Rm:4
-	{0x0ff000f0, 0x06800fb0, 3, arm_SEL_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}},                            // SEL<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|1|0|0|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|0|1|1|Rm:4
-	{0xfffffdff, 0xf1010000, 4, arm_SETEND, 0x0, arm_instArgs{arm_arg_endian}},                                                        // SETEND <endian_specifier> 1|1|1|1|0|0|0|1|0|0|0|0|0|0|0|1|0|0|0|0|0|0|E|(0)|(0)|(0)|(0)|(0)|(0)|(0)|(0)|(0)
-	{0xfffffc00, 0xf1010000, 3, arm_SETEND, 0x0, arm_instArgs{arm_arg_endian}},                                                        // SETEND <endian_specifier> 1|1|1|1|0|0|0|1|0|0|0|0|0|0|0|1|0|0|0|0|0|0|E|(0)|(0)|(0)|(0)|(0)|(0)|(0)|(0)|(0)
-	{0x0fffffff, 0x0320f004, 4, arm_SEV_EQ, 0x1c04, arm_instArgs{}},                                                                   // SEV<c> cond:4|0|0|1|1|0|0|1|0|0|0|0|0|(1)|(1)|(1)|(1)|(0)|(0)|(0)|(0)|0|0|0|0|0|1|0|0
-	{0x0fff00ff, 0x0320f004, 3, arm_SEV_EQ, 0x1c04, arm_instArgs{}},                                                                   // SEV<c> cond:4|0|0|1|1|0|0|1|0|0|0|0|0|(1)|(1)|(1)|(1)|(0)|(0)|(0)|(0)|0|0|0|0|0|1|0|0
-	{0x0ff00ff0, 0x06300f10, 4, arm_SHADD16_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}},                        // SHADD16<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|1|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|0|0|1|Rm:4
-	{0x0ff000f0, 0x06300f10, 3, arm_SHADD16_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}},                        // SHADD16<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|1|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|0|0|1|Rm:4
-	{0x0ff00ff0, 0x06300f90, 4, arm_SHADD8_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}},                         // SHADD8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|1|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|0|0|1|Rm:4
-	{0x0ff000f0, 0x06300f90, 3, arm_SHADD8_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}},                         // SHADD8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|1|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|0|0|1|Rm:4
-	{0x0ff00ff0, 0x06300f30, 4, arm_SHASX_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}},                          // SHASX<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|1|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|0|1|1|Rm:4
-	{0x0ff000f0, 0x06300f30, 3, arm_SHASX_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}},                          // SHASX<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|1|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|0|1|1|Rm:4
-	{0x0ff00ff0, 0x06300f50, 4, arm_SHSAX_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}},                          // SHSAX<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|1|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|1|0|1|Rm:4
-	{0x0ff000f0, 0x06300f50, 3, arm_SHSAX_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}},                          // SHSAX<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|1|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|1|0|1|Rm:4
-	{0x0ff00ff0, 0x06300f70, 4, arm_SHSUB16_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}},                        // SHSUB16<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|1|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|1|1|1|Rm:4
-	{0x0ff000f0, 0x06300f70, 3, arm_SHSUB16_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}},                        // SHSUB16<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|1|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|1|1|1|Rm:4
-	{0x0ff00ff0, 0x06300ff0, 4, arm_SHSUB8_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}},                         // SHSUB8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|1|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|1|1|1|Rm:4
-	{0x0ff000f0, 0x06300ff0, 3, arm_SHSUB8_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}},                         // SHSUB8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|1|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|1|1|1|Rm:4
-	{0x0ff00090, 0x01000080, 4, arm_SMLABB_EQ, 0x50106011c04, arm_instArgs{arm_arg_R_16, arm_arg_R_0, arm_arg_R_8, arm_arg_R_12}},     // SMLA<x><y><c> <Rd>,<Rn>,<Rm>,<Ra> cond:4|0|0|0|1|0|0|0|0|Rd:4|Ra:4|Rm:4|1|M|N|0|Rn:4
-	{0x0ff000d0, 0x07000010, 2, arm_SMLAD_EQ, 0x5011c04, arm_instArgs{arm_arg_R_16, arm_arg_R_0, arm_arg_R_8, arm_arg_R_12}},          // SMLAD{X}<c> <Rd>,<Rn>,<Rm>,<Ra> cond:4|0|1|1|1|0|0|0|0|Rd:4|Ra:4|Rm:4|0|0|M|1|Rn:4
-	{0x0ff00090, 0x01400080, 4, arm_SMLALBB_EQ, 0x50106011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0, arm_arg_R_8}},    // SMLAL<x><y><c> <RdLo>,<RdHi>,<Rn>,<Rm> cond:4|0|0|0|1|0|1|0|0|RdHi:4|RdLo:4|Rm:4|1|M|N|0|Rn:4
-	{0x0ff000d0, 0x07400010, 4, arm_SMLALD_EQ, 0x5011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0, arm_arg_R_8}},         // SMLALD{X}<c> <RdLo>,<RdHi>,<Rn>,<Rm> cond:4|0|1|1|1|0|1|0|0|RdHi:4|RdLo:4|Rm:4|0|0|M|1|Rn:4
-	{0x0fe000f0, 0x00e00090, 4, arm_SMLAL_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0, arm_arg_R_8}},         // SMLAL{S}<c> <RdLo>,<RdHi>,<Rn>,<Rm> cond:4|0|0|0|0|1|1|1|S|RdHi:4|RdLo:4|Rm:4|1|0|0|1|Rn:4
-	{0x0ff000b0, 0x01200080, 4, arm_SMLAWB_EQ, 0x6011c04, arm_instArgs{arm_arg_R_16, arm_arg_R_0, arm_arg_R_8, arm_arg_R_12}},         // SMLAW<y><c> <Rd>,<Rn>,<Rm>,<Ra> cond:4|0|0|0|1|0|0|1|0|Rd:4|Ra:4|Rm:4|1|M|0|0|Rn:4
-	{0x0ff000d0, 0x07000050, 2, arm_SMLSD_EQ, 0x5011c04, arm_instArgs{arm_arg_R_16, arm_arg_R_0, arm_arg_R_8, arm_arg_R_12}},          // SMLSD{X}<c> <Rd>,<Rn>,<Rm>,<Ra> cond:4|0|1|1|1|0|0|0|0|Rd:4|Ra:4|Rm:4|0|1|M|1|Rn:4
-	{0x0ff000d0, 0x07400050, 4, arm_SMLSLD_EQ, 0x5011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0, arm_arg_R_8}},         // SMLSLD{X}<c> <RdLo>,<RdHi>,<Rn>,<Rm> cond:4|0|1|1|1|0|1|0|0|RdHi:4|RdLo:4|Rm:4|0|1|M|1|Rn:4
-	{0x0ff000d0, 0x07500010, 2, arm_SMMLA_EQ, 0x5011c04, arm_instArgs{arm_arg_R_16, arm_arg_R_0, arm_arg_R_8, arm_arg_R_12}},          // SMMLA{R}<c> <Rd>,<Rn>,<Rm>,<Ra> cond:4|0|1|1|1|0|1|0|1|Rd:4|Ra:4|Rm:4|0|0|R|1|Rn:4
-	{0x0ff000d0, 0x075000d0, 4, arm_SMMLS_EQ, 0x5011c04, arm_instArgs{arm_arg_R_16, arm_arg_R_0, arm_arg_R_8, arm_arg_R_12}},          // SMMLS{R}<c> <Rd>,<Rn>,<Rm>,<Ra> cond:4|0|1|1|1|0|1|0|1|Rd:4|Ra:4|Rm:4|1|1|R|1|Rn:4
-	{0x0ff0f0d0, 0x0750f010, 4, arm_SMMUL_EQ, 0x5011c04, arm_instArgs{arm_arg_R_16, arm_arg_R_0, arm_arg_R_8}},                        // SMMUL{R}<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|1|0|1|0|1|Rd:4|1|1|1|1|Rm:4|0|0|R|1|Rn:4
-	{0x0ff0f0d0, 0x0700f010, 4, arm_SMUAD_EQ, 0x5011c04, arm_instArgs{arm_arg_R_16, arm_arg_R_0, arm_arg_R_8}},                        // SMUAD{X}<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|1|0|0|0|0|Rd:4|1|1|1|1|Rm:4|0|0|M|1|Rn:4
-	{0x0ff0f090, 0x01600080, 4, arm_SMULBB_EQ, 0x50106011c04, arm_instArgs{arm_arg_R_16, arm_arg_R_0, arm_arg_R_8}},                   // SMUL<x><y><c> <Rd>,<Rn>,<Rm> cond:4|0|0|0|1|0|1|1|0|Rd:4|0|0|0|0|Rm:4|1|M|N|0|Rn:4
-	{0x0fe000f0, 0x00c00090, 4, arm_SMULL_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0, arm_arg_R_8}},         // SMULL{S}<c> <RdLo>,<RdHi>,<Rn>,<Rm> cond:4|0|0|0|0|1|1|0|S|RdHi:4|RdLo:4|Rm:4|1|0|0|1|Rn:4
-	{0x0ff0f0b0, 0x012000a0, 4, arm_SMULWB_EQ, 0x6011c04, arm_instArgs{arm_arg_R_16, arm_arg_R_0, arm_arg_R_8}},                       // SMULW<y><c> <Rd>,<Rn>,<Rm> cond:4|0|0|0|1|0|0|1|0|Rd:4|0|0|0|0|Rm:4|1|M|1|0|Rn:4
-	{0x0ff0f0d0, 0x0700f050, 4, arm_SMUSD_EQ, 0x5011c04, arm_instArgs{arm_arg_R_16, arm_arg_R_0, arm_arg_R_8}},                        // SMUSD{X}<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|1|0|0|0|0|Rd:4|1|1|1|1|Rm:4|0|1|M|1|Rn:4
-	{0x0ff00ff0, 0x06a00f30, 4, arm_SSAT16_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_satimm4m1, arm_arg_R_0}},                    // SSAT16<c> <Rd>,#<sat_imm4m1>,<Rn> cond:4|0|1|1|0|1|0|1|0|sat_imm:4|Rd:4|(1)|(1)|(1)|(1)|0|0|1|1|Rn:4
-	{0x0ff000f0, 0x06a00f30, 3, arm_SSAT16_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_satimm4m1, arm_arg_R_0}},                    // SSAT16<c> <Rd>,#<sat_imm4m1>,<Rn> cond:4|0|1|1|0|1|0|1|0|sat_imm:4|Rd:4|(1)|(1)|(1)|(1)|0|0|1|1|Rn:4
-	{0x0fe00030, 0x06a00010, 4, arm_SSAT_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_satimm5m1, arm_arg_R_shift_imm}},              // SSAT<c> <Rd>,#<sat_imm5m1>,<Rn>{,<shift>} cond:4|0|1|1|0|1|0|1|sat_imm:5|Rd:4|imm5:5|sh|0|1|Rn:4
-	{0x0ff00ff0, 0x06100f50, 4, arm_SSAX_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}},                           // SSAX<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|0|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|1|0|1|Rm:4
-	{0x0ff000f0, 0x06100f50, 3, arm_SSAX_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}},                           // SSAX<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|0|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|1|0|1|Rm:4
-	{0x0ff00ff0, 0x06100f70, 4, arm_SSUB16_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}},                         // SSUB16<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|0|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|1|1|1|Rm:4
-	{0x0ff000f0, 0x06100f70, 3, arm_SSUB16_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}},                         // SSUB16<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|0|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|1|1|1|Rm:4
-	{0x0ff00ff0, 0x06100ff0, 4, arm_SSUB8_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}},                          // SSUB8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|0|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|1|1|1|Rm:4
-	{0x0ff000f0, 0x06100ff0, 3, arm_SSUB8_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}},                          // SSUB8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|0|0|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|1|1|1|Rm:4
-	{0x0fd00000, 0x08800000, 4, arm_STM_EQ, 0x1c04, arm_instArgs{arm_arg_R_16_WB, arm_arg_registers}},                                 // STM<c> <Rn>{!},<registers> cond:4|1|0|0|0|1|0|W|0|Rn:4|register_list:16
-	{0x0fd00000, 0x08000000, 4, arm_STMDA_EQ, 0x1c04, arm_instArgs{arm_arg_R_16_WB, arm_arg_registers}},                               // STMDA<c> <Rn>{!},<registers> cond:4|1|0|0|0|0|0|W|0|Rn:4|register_list:16
-	{0x0fd00000, 0x09000000, 2, arm_STMDB_EQ, 0x1c04, arm_instArgs{arm_arg_R_16_WB, arm_arg_registers}},                               // STMDB<c> <Rn>{!},<registers> cond:4|1|0|0|1|0|0|W|0|Rn:4|register_list:16
-	{0x0fd00000, 0x09800000, 4, arm_STMIB_EQ, 0x1c04, arm_instArgs{arm_arg_R_16_WB, arm_arg_registers}},                               // STMIB<c> <Rn>{!},<registers> cond:4|1|0|0|1|1|0|W|0|Rn:4|register_list:16
-	{0x0e500018, 0x06000000, 2, arm_STR_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R_pm_R_shift_imm_W}},                       // STR<c> <Rt>,[<Rn>,+/-<Rm>{, <shift>}]{!} cond:4|0|1|1|P|U|0|W|0|Rn:4|Rt:4|imm5:5|type:2|0|Rm:4
-	{0x0e500000, 0x04000000, 2, arm_STR_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R_pm_imm12_W}},                             // STR<c> <Rt>,[<Rn>{,#+/-<imm12>}]{!} cond:4|0|1|0|P|U|0|W|0|Rn:4|Rt:4|imm12:12
-	{0x0e500010, 0x06400000, 2, arm_STRB_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R_pm_R_shift_imm_W}},                      // STRB<c> <Rt>,[<Rn>,+/-<Rm>{, <shift>}]{!} cond:4|0|1|1|P|U|1|W|0|Rn:4|Rt:4|imm5:5|type:2|0|Rm:4
-	{0x0e500000, 0x04400000, 2, arm_STRB_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R_pm_imm12_W}},                            // STRB<c> <Rt>,[<Rn>{,#+/-<imm12>}]{!} cond:4|0|1|0|P|U|1|W|0|Rn:4|Rt:4|imm12:12
-	{0x0f700000, 0x04600000, 4, arm_STRBT_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R_pm_imm12_postindex}},                   // STRBT<c> <Rt>,[<Rn>],#+/-<imm12> cond:4|0|1|0|0|U|1|1|0|Rn:4|Rt:4|imm12:12
-	{0x0f700010, 0x06600000, 4, arm_STRBT_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R_pm_R_shift_imm_postindex}},             // STRBT<c> <Rt>,[<Rn>],+/-<Rm>{, <shift>} cond:4|0|1|1|0|U|1|1|0|Rn:4|Rt:4|imm5:5|type:2|0|Rm:4
-	{0x0e500ff0, 0x000000f0, 4, arm_STRD_EQ, 0x1c04, arm_instArgs{arm_arg_R1_12, arm_arg_R2_12, arm_arg_mem_R_pm_R_W}},                // STRD<c> <Rt1>,<Rt2>,[<Rn>,+/-<Rm>]{!} cond:4|0|0|0|P|U|0|W|0|Rn:4|Rt:4|(0)|(0)|(0)|(0)|1|1|1|1|Rm:4
-	{0x0e5000f0, 0x000000f0, 3, arm_STRD_EQ, 0x1c04, arm_instArgs{arm_arg_R1_12, arm_arg_R2_12, arm_arg_mem_R_pm_R_W}},                // STRD<c> <Rt1>,<Rt2>,[<Rn>,+/-<Rm>]{!} cond:4|0|0|0|P|U|0|W|0|Rn:4|Rt:4|(0)|(0)|(0)|(0)|1|1|1|1|Rm:4
-	{0x0e5000f0, 0x004000f0, 4, arm_STRD_EQ, 0x1c04, arm_instArgs{arm_arg_R1_12, arm_arg_R2_12, arm_arg_mem_R_pm_imm8_W}},             // STRD<c> <Rt1>,<Rt2>,[<Rn>{,#+/-<imm8>}]{!} cond:4|0|0|0|P|U|1|W|0|Rn:4|Rt:4|imm4H:4|1|1|1|1|imm4L:4
-	{0x0ff00ff0, 0x01800f90, 4, arm_STREX_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0, arm_arg_mem_R}},                         // STREX<c> <Rd>,<Rt>,[<Rn>] cond:4|0|0|0|1|1|0|0|0|Rn:4|Rd:4|1|1|1|1|1|0|0|1|Rt:4
-	{0x0ff00ff0, 0x01c00f90, 4, arm_STREXB_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0, arm_arg_mem_R}},                        // STREXB<c> <Rd>,<Rt>,[<Rn>] cond:4|0|0|0|1|1|1|0|0|Rn:4|Rd:4|1|1|1|1|1|0|0|1|Rt:4
-	{0x0ff00ff0, 0x01a00f90, 4, arm_STREXD_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R1_0, arm_arg_R2_0, arm_arg_mem_R}},         // STREXD<c> <Rd>,<Rt1>,<Rt2>,[<Rn>] cond:4|0|0|0|1|1|0|1|0|Rn:4|Rd:4|1|1|1|1|1|0|0|1|Rt:4
-	{0x0ff00ff0, 0x01e00f90, 4, arm_STREXH_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0, arm_arg_mem_R}},                        // STREXH<c> <Rd>,<Rt>,[<Rn>] cond:4|0|0|0|1|1|1|1|0|Rn:4|Rd:4|1|1|1|1|1|0|0|1|Rt:4
-	{0x0e500ff0, 0x000000b0, 2, arm_STRH_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R_pm_R_W}},                                // STRH<c> <Rt>,[<Rn>,+/-<Rm>]{!} cond:4|0|0|0|P|U|0|W|0|Rn:4|Rt:4|0|0|0|0|1|0|1|1|Rm:4
-	{0x0e5000f0, 0x004000b0, 2, arm_STRH_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R_pm_imm8_W}},                             // STRH<c> <Rt>,[<Rn>{,#+/-<imm8>}]{!} cond:4|0|0|0|P|U|1|W|0|Rn:4|Rt:4|imm4H:4|1|0|1|1|imm4L:4
-	{0x0f7000f0, 0x006000b0, 4, arm_STRHT_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R_pm_imm8_postindex}},                    // STRHT<c> <Rt>, [<Rn>] {,#+/-<imm8>} cond:4|0|0|0|0|U|1|1|0|Rn:4|Rt:4|imm4H:4|1|0|1|1|imm4L:4
-	{0x0f700ff0, 0x002000b0, 4, arm_STRHT_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R_pm_R_postindex}},                       // STRHT<c> <Rt>, [<Rn>], +/-<Rm> cond:4|0|0|0|0|U|0|1|0|Rn:4|Rt:4|0|0|0|0|1|0|1|1|Rm:4
-	{0x0f700000, 0x04200000, 4, arm_STRT_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R_pm_imm12_postindex}},                    // STRT<c> <Rt>, [<Rn>] {,#+/-<imm12>} cond:4|0|1|0|0|U|0|1|0|Rn:4|Rt:4|imm12:12
-	{0x0f700010, 0x06200000, 4, arm_STRT_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_mem_R_pm_R_shift_imm_postindex}},              // STRT<c> <Rt>,[<Rn>],+/-<Rm>{, <shift>} cond:4|0|1|1|0|U|0|1|0|Rn:4|Rt:4|imm5:5|type:2|0|Rm:4
-	{0x0fe00000, 0x02400000, 2, arm_SUB_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_const}},                      // SUB{S}<c> <Rd>,<Rn>,#<const> cond:4|0|0|1|0|0|1|0|S|Rn:4|Rd:4|imm12:12
-	{0x0fe00090, 0x00400010, 4, arm_SUB_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_shift_R}},                  // SUB{S}<c> <Rd>,<Rn>,<Rm>,<type> <Rs> cond:4|0|0|0|0|0|1|0|S|Rn:4|Rd:4|Rs:4|0|type:2|1|Rm:4
-	{0x0fe00010, 0x00400000, 2, arm_SUB_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_shift_imm}},                // SUB{S}<c> <Rd>,<Rn>,<Rm>{,<shift>} cond:4|0|0|0|0|0|1|0|S|Rn:4|Rd:4|imm5:5|type:2|0|Rm:4
-	{0x0fef0000, 0x024d0000, 2, arm_SUB_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_SP, arm_arg_const}},                        // SUB{S}<c> <Rd>,SP,#<const> cond:4|0|0|1|0|0|1|0|S|1|1|0|1|Rd:4|imm12:12
-	{0x0fef0010, 0x004d0000, 2, arm_SUB_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_SP, arm_arg_R_shift_imm}},                  // SUB{S}<c> <Rd>,SP,<Rm>{,<shift>} cond:4|0|0|0|0|0|1|0|S|1|1|0|1|Rd:4|imm5:5|type:2|0|Rm:4
-	{0x0f000000, 0x0f000000, 4, arm_SVC_EQ, 0x1c04, arm_instArgs{arm_arg_imm24}},                                                      // SVC<c> #<imm24> cond:4|1|1|1|1|imm24:24
-	{0x0fb00ff0, 0x01000090, 4, arm_SWP_EQ, 0x16011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0, arm_arg_mem_R}},                       // SWP{B}<c> <Rt>,<Rm>,[<Rn>] cond:4|0|0|0|1|0|B|0|0|Rn:4|Rt:4|0|0|0|0|1|0|0|1|Rm:4
-	{0x0ff003f0, 0x06800070, 2, arm_SXTAB16_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_rotate}},                   // SXTAB16<c> <Rd>,<Rn>,<Rm>{,<rotation>} cond:4|0|1|1|0|1|0|0|0|Rn:4|Rd:4|rotate:2|0|0|0|1|1|1|Rm:4
-	{0x0ff003f0, 0x06a00070, 2, arm_SXTAB_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_rotate}},                     // SXTAB<c> <Rd>,<Rn>,<Rm>{,<rotation>} cond:4|0|1|1|0|1|0|1|0|Rn:4|Rd:4|rotate:2|0|0|0|1|1|1|Rm:4
-	{0x0ff003f0, 0x06b00070, 2, arm_SXTAH_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_rotate}},                     // SXTAH<c> <Rd>,<Rn>,<Rm>{,<rotation>} cond:4|0|1|1|0|1|0|1|1|Rn:4|Rd:4|rotate:2|0|0|0|1|1|1|Rm:4
-	{0x0fff03f0, 0x068f0070, 4, arm_SXTB16_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_rotate}},                                  // SXTB16<c> <Rd>,<Rm>{,<rotation>} cond:4|0|1|1|0|1|0|0|0|1|1|1|1|Rd:4|rotate:2|0|0|0|1|1|1|Rm:4
-	{0x0fff03f0, 0x06af0070, 4, arm_SXTB_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_rotate}},                                    // SXTB<c> <Rd>,<Rm>{,<rotation>} cond:4|0|1|1|0|1|0|1|0|1|1|1|1|Rd:4|rotate:2|0|0|0|1|1|1|Rm:4
-	{0x0fff03f0, 0x06bf0070, 4, arm_SXTH_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_rotate}},                                    // SXTH<c> <Rd>,<Rm>{,<rotation>} cond:4|0|1|1|0|1|0|1|1|1|1|1|1|Rd:4|rotate:2|0|0|0|1|1|1|Rm:4
-	{0x0ff0f000, 0x03300000, 4, arm_TEQ_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_const}},                                        // TEQ<c> <Rn>,#<const> cond:4|0|0|1|1|0|0|1|1|Rn:4|(0)|(0)|(0)|(0)|imm12:12
-	{0x0ff00000, 0x03300000, 3, arm_TEQ_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_const}},                                        // TEQ<c> <Rn>,#<const> cond:4|0|0|1|1|0|0|1|1|Rn:4|(0)|(0)|(0)|(0)|imm12:12
-	{0x0ff0f090, 0x01300010, 4, arm_TEQ_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_R_shift_R}},                                    // TEQ<c> <Rn>,<Rm>,<type> <Rs> cond:4|0|0|0|1|0|0|1|1|Rn:4|(0)|(0)|(0)|(0)|Rs:4|0|type:2|1|Rm:4
-	{0x0ff00090, 0x01300010, 3, arm_TEQ_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_R_shift_R}},                                    // TEQ<c> <Rn>,<Rm>,<type> <Rs> cond:4|0|0|0|1|0|0|1|1|Rn:4|(0)|(0)|(0)|(0)|Rs:4|0|type:2|1|Rm:4
-	{0x0ff0f010, 0x01300000, 4, arm_TEQ_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_R_shift_imm}},                                  // TEQ<c> <Rn>,<Rm>{,<shift>} cond:4|0|0|0|1|0|0|1|1|Rn:4|(0)|(0)|(0)|(0)|imm5:5|type:2|0|Rm:4
-	{0x0ff00010, 0x01300000, 3, arm_TEQ_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_R_shift_imm}},                                  // TEQ<c> <Rn>,<Rm>{,<shift>} cond:4|0|0|0|1|0|0|1|1|Rn:4|(0)|(0)|(0)|(0)|imm5:5|type:2|0|Rm:4
-	{0x0ff0f000, 0x03100000, 4, arm_TST_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_const}},                                        // TST<c> <Rn>,#<const> cond:4|0|0|1|1|0|0|0|1|Rn:4|(0)|(0)|(0)|(0)|imm12:12
-	{0x0ff00000, 0x03100000, 3, arm_TST_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_const}},                                        // TST<c> <Rn>,#<const> cond:4|0|0|1|1|0|0|0|1|Rn:4|(0)|(0)|(0)|(0)|imm12:12
-	{0x0ff0f090, 0x01100010, 4, arm_TST_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_R_shift_R}},                                    // TST<c> <Rn>,<Rm>,<type> <Rs> cond:4|0|0|0|1|0|0|0|1|Rn:4|(0)|(0)|(0)|(0)|Rs:4|0|type:2|1|Rm:4
-	{0x0ff00090, 0x01100010, 3, arm_TST_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_R_shift_R}},                                    // TST<c> <Rn>,<Rm>,<type> <Rs> cond:4|0|0|0|1|0|0|0|1|Rn:4|(0)|(0)|(0)|(0)|Rs:4|0|type:2|1|Rm:4
-	{0x0ff0f010, 0x01100000, 4, arm_TST_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_R_shift_imm}},                                  // TST<c> <Rn>,<Rm>{,<shift>} cond:4|0|0|0|1|0|0|0|1|Rn:4|(0)|(0)|(0)|(0)|imm5:5|type:2|0|Rm:4
-	{0x0ff00010, 0x01100000, 3, arm_TST_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_R_shift_imm}},                                  // TST<c> <Rn>,<Rm>{,<shift>} cond:4|0|0|0|1|0|0|0|1|Rn:4|(0)|(0)|(0)|(0)|imm5:5|type:2|0|Rm:4
-	{0x0ff00ff0, 0x06500f10, 4, arm_UADD16_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}},                         // UADD16<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|0|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|0|0|1|Rm:4
-	{0x0ff000f0, 0x06500f10, 3, arm_UADD16_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}},                         // UADD16<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|0|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|0|0|1|Rm:4
-	{0x0ff00ff0, 0x06500f90, 4, arm_UADD8_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}},                          // UADD8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|0|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|0|0|1|Rm:4
-	{0x0ff000f0, 0x06500f90, 3, arm_UADD8_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}},                          // UADD8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|0|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|0|0|1|Rm:4
-	{0x0ff00ff0, 0x06500f30, 4, arm_UASX_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}},                           // UASX<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|0|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|0|1|1|Rm:4
-	{0x0ff000f0, 0x06500f30, 3, arm_UASX_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}},                           // UASX<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|0|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|0|1|1|Rm:4
-	{0x0fe00070, 0x07e00050, 4, arm_UBFX_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_0, arm_arg_imm5, arm_arg_widthm1}},          // UBFX<c> <Rd>,<Rn>,#<lsb>,#<widthm1> cond:4|0|1|1|1|1|1|1|widthm1:5|Rd:4|lsb:5|1|0|1|Rn:4
-	{0x0ff00ff0, 0x06700f10, 4, arm_UHADD16_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}},                        // UHADD16<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|1|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|0|0|1|Rm:4
-	{0x0ff000f0, 0x06700f10, 3, arm_UHADD16_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}},                        // UHADD16<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|1|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|0|0|1|Rm:4
-	{0x0ff00ff0, 0x06700f90, 4, arm_UHADD8_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}},                         // UHADD8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|1|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|0|0|1|Rm:4
-	{0x0ff000f0, 0x06700f90, 3, arm_UHADD8_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}},                         // UHADD8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|1|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|0|0|1|Rm:4
-	{0x0ff00ff0, 0x06700f30, 4, arm_UHASX_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}},                          // UHASX<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|1|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|0|1|1|Rm:4
-	{0x0ff000f0, 0x06700f30, 3, arm_UHASX_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}},                          // UHASX<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|1|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|0|1|1|Rm:4
-	{0x0ff00ff0, 0x06700f50, 4, arm_UHSAX_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}},                          // UHSAX<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|1|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|1|0|1|Rm:4
-	{0x0ff000f0, 0x06700f50, 3, arm_UHSAX_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}},                          // UHSAX<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|1|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|1|0|1|Rm:4
-	{0x0ff00ff0, 0x06700f70, 4, arm_UHSUB16_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}},                        // UHSUB16<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|1|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|1|1|1|Rm:4
-	{0x0ff000f0, 0x06700f70, 3, arm_UHSUB16_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}},                        // UHSUB16<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|1|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|1|1|1|Rm:4
-	{0x0ff00ff0, 0x06700ff0, 4, arm_UHSUB8_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}},                         // UHSUB8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|1|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|1|1|1|Rm:4
-	{0x0ff000f0, 0x06700ff0, 3, arm_UHSUB8_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}},                         // UHSUB8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|1|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|1|1|1|Rm:4
-	{0x0ff000f0, 0x00400090, 4, arm_UMAAL_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0, arm_arg_R_8}},             // UMAAL<c> <RdLo>,<RdHi>,<Rn>,<Rm> cond:4|0|0|0|0|0|1|0|0|RdHi:4|RdLo:4|Rm:4|1|0|0|1|Rn:4
-	{0x0fe000f0, 0x00a00090, 4, arm_UMLAL_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0, arm_arg_R_8}},         // UMLAL{S}<c> <RdLo>,<RdHi>,<Rn>,<Rm> cond:4|0|0|0|0|1|0|1|S|RdHi:4|RdLo:4|Rm:4|1|0|0|1|Rn:4
-	{0x0fe000f0, 0x00800090, 4, arm_UMULL_EQ, 0x14011c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0, arm_arg_R_8}},         // UMULL{S}<c> <RdLo>,<RdHi>,<Rn>,<Rm> cond:4|0|0|0|0|1|0|0|S|RdHi:4|RdLo:4|Rm:4|1|0|0|1|Rn:4
-	{0x0ff00ff0, 0x06600f10, 4, arm_UQADD16_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}},                        // UQADD16<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|1|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|0|0|1|Rm:4
-	{0x0ff000f0, 0x06600f10, 3, arm_UQADD16_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}},                        // UQADD16<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|1|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|0|0|1|Rm:4
-	{0x0ff00ff0, 0x06600f90, 4, arm_UQADD8_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}},                         // UQADD8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|1|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|0|0|1|Rm:4
-	{0x0ff000f0, 0x06600f90, 3, arm_UQADD8_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}},                         // UQADD8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|1|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|0|0|1|Rm:4
-	{0x0ff00ff0, 0x06600f30, 4, arm_UQASX_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}},                          // UQASX<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|1|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|0|1|1|Rm:4
-	{0x0ff000f0, 0x06600f30, 3, arm_UQASX_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}},                          // UQASX<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|1|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|0|1|1|Rm:4
-	{0x0ff00ff0, 0x06600f50, 4, arm_UQSAX_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}},                          // UQSAX<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|1|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|1|0|1|Rm:4
-	{0x0ff000f0, 0x06600f50, 3, arm_UQSAX_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}},                          // UQSAX<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|1|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|1|0|1|Rm:4
-	{0x0ff00ff0, 0x06600f70, 4, arm_UQSUB16_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}},                        // UQSUB16<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|1|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|1|1|1|Rm:4
-	{0x0ff000f0, 0x06600f70, 3, arm_UQSUB16_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}},                        // UQSUB16<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|1|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|1|1|1|Rm:4
-	{0x0ff00ff0, 0x06600ff0, 4, arm_UQSUB8_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}},                         // UQSUB8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|1|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|1|1|1|Rm:4
-	{0x0ff000f0, 0x06600ff0, 3, arm_UQSUB8_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}},                         // UQSUB8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|1|0|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|1|1|1|Rm:4
-	{0x0ff0f0f0, 0x0780f010, 4, arm_USAD8_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_R_0, arm_arg_R_8}},                           // USAD8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|1|1|0|0|0|Rd:4|1|1|1|1|Rm:4|0|0|0|1|Rn:4
-	{0x0ff000f0, 0x07800010, 2, arm_USADA8_EQ, 0x1c04, arm_instArgs{arm_arg_R_16, arm_arg_R_0, arm_arg_R_8, arm_arg_R_12}},            // USADA8<c> <Rd>,<Rn>,<Rm>,<Ra> cond:4|0|1|1|1|1|0|0|0|Rd:4|Ra:4|Rm:4|0|0|0|1|Rn:4
-	{0x0ff00ff0, 0x06e00f30, 4, arm_USAT16_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_satimm4, arm_arg_R_0}},                      // USAT16<c> <Rd>,#<sat_imm4>,<Rn> cond:4|0|1|1|0|1|1|1|0|sat_imm:4|Rd:4|(1)|(1)|(1)|(1)|0|0|1|1|Rn:4
-	{0x0ff000f0, 0x06e00f30, 3, arm_USAT16_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_satimm4, arm_arg_R_0}},                      // USAT16<c> <Rd>,#<sat_imm4>,<Rn> cond:4|0|1|1|0|1|1|1|0|sat_imm:4|Rd:4|(1)|(1)|(1)|(1)|0|0|1|1|Rn:4
-	{0x0fe00030, 0x06e00010, 4, arm_USAT_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_satimm5, arm_arg_R_shift_imm}},                // USAT<c> <Rd>,#<sat_imm5>,<Rn>{,<shift>} cond:4|0|1|1|0|1|1|1|sat_imm:5|Rd:4|imm5:5|sh|0|1|Rn:4
-	{0x0ff00ff0, 0x06500f50, 4, arm_USAX_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}},                           // USAX<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|0|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|1|0|1|Rm:4
-	{0x0ff000f0, 0x06500f50, 3, arm_USAX_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}},                           // USAX<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|0|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|1|0|1|Rm:4
-	{0x0ff00ff0, 0x06500f70, 4, arm_USUB16_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}},                         // USUB16<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|0|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|1|1|1|Rm:4
-	{0x0ff000f0, 0x06500f70, 3, arm_USUB16_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}},                         // USUB16<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|0|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|0|1|1|1|Rm:4
-	{0x0ff00ff0, 0x06500ff0, 4, arm_USUB8_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}},                          // USUB8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|0|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|1|1|1|Rm:4
-	{0x0ff000f0, 0x06500ff0, 3, arm_USUB8_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_0}},                          // USUB8<c> <Rd>,<Rn>,<Rm> cond:4|0|1|1|0|0|1|0|1|Rn:4|Rd:4|(1)|(1)|(1)|(1)|1|1|1|1|Rm:4
-	{0x0ff003f0, 0x06c00070, 2, arm_UXTAB16_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_rotate}},                   // UXTAB16<c> <Rd>,<Rn>,<Rm>{,<rotation>} cond:4|0|1|1|0|1|1|0|0|Rn:4|Rd:4|rotate:2|0|0|0|1|1|1|Rm:4
-	{0x0ff003f0, 0x06e00070, 2, arm_UXTAB_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_rotate}},                     // UXTAB<c> <Rd>,<Rn>,<Rm>{,<rotation>} cond:4|0|1|1|0|1|1|1|0|Rn:4|Rd:4|rotate:2|0|0|0|1|1|1|Rm:4
-	{0x0ff003f0, 0x06f00070, 2, arm_UXTAH_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_16, arm_arg_R_rotate}},                     // UXTAH<c> <Rd>,<Rn>,<Rm>{,<rotation>} cond:4|0|1|1|0|1|1|1|1|Rn:4|Rd:4|rotate:2|0|0|0|1|1|1|Rm:4
-	{0x0fff03f0, 0x06cf0070, 4, arm_UXTB16_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_rotate}},                                  // UXTB16<c> <Rd>,<Rm>{,<rotation>} cond:4|0|1|1|0|1|1|0|0|1|1|1|1|Rd:4|rotate:2|0|0|0|1|1|1|Rm:4
-	{0x0fff03f0, 0x06ef0070, 4, arm_UXTB_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_rotate}},                                    // UXTB<c> <Rd>,<Rm>{,<rotation>} cond:4|0|1|1|0|1|1|1|0|1|1|1|1|Rd:4|rotate:2|0|0|0|1|1|1|Rm:4
-	{0x0fff03f0, 0x06ff0070, 4, arm_UXTH_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_R_rotate}},                                    // UXTH<c> <Rd>,<Rm>{,<rotation>} cond:4|0|1|1|0|1|1|1|1|1|1|1|1|Rd:4|rotate:2|0|0|0|1|1|1|Rm:4
-	{0x0fb00e10, 0x0e000a00, 4, arm_VMLA_EQ_F32, 0x60108011c04, arm_instArgs{arm_arg_Sd_Dd, arm_arg_Sn_Dn, arm_arg_Sm_Dm}},            // V<MLA,MLS><c>.F<32,64> <Sd,Dd>, <Sn,Dn>, <Sm,Dm> cond:4|1|1|1|0|0|D|0|0|Vn:4|Vd:4|1|0|1|sz|N|op|M|0|Vm:4
-	{0x0fbf0ed0, 0x0eb00ac0, 4, arm_VABS_EQ_F32, 0x8011c04, arm_instArgs{arm_arg_Sd_Dd, arm_arg_Sm_Dm}},                               // VABS<c>.F<32,64> <Sd,Dd>, <Sm,Dm> cond:4|1|1|1|0|1|D|1|1|0|0|0|0|Vd:4|1|0|1|sz|1|1|M|0|Vm:4
-	{0x0fb00e50, 0x0e300a00, 4, arm_VADD_EQ_F32, 0x8011c04, arm_instArgs{arm_arg_Sd_Dd, arm_arg_Sn_Dn, arm_arg_Sm_Dm}},                // VADD<c>.F<32,64> <Sd,Dd>, <Sn,Dn>, <Sm,Dm> cond:4|1|1|1|0|0|D|1|1|Vn:4|Vd:4|1|0|1|sz|N|0|M|0|Vm:4
-	{0x0fbf0e7f, 0x0eb50a40, 4, arm_VCMP_EQ_F32, 0x70108011c04, arm_instArgs{arm_arg_Sd_Dd, arm_arg_fp_0}},                            // VCMP{E}<c>.F<32,64> <Sd,Dd>, #0.0 cond:4|1|1|1|0|1|D|1|1|0|1|0|1|Vd:4|1|0|1|sz|E|1|0|0|(0)|(0)|(0)|(0)
-	{0x0fbf0e70, 0x0eb50a40, 3, arm_VCMP_EQ_F32, 0x70108011c04, arm_instArgs{arm_arg_Sd_Dd, arm_arg_fp_0}},                            // VCMP{E}<c>.F<32,64> <Sd,Dd>, #0.0 cond:4|1|1|1|0|1|D|1|1|0|1|0|1|Vd:4|1|0|1|sz|E|1|0|0|(0)|(0)|(0)|(0)
-	{0x0fbf0e50, 0x0eb40a40, 4, arm_VCMP_EQ_F32, 0x70108011c04, arm_instArgs{arm_arg_Sd_Dd, arm_arg_Sm_Dm}},                           // VCMP{E}<c>.F<32,64> <Sd,Dd>, <Sm,Dm> cond:4|1|1|1|0|1|D|1|1|0|1|0|0|Vd:4|1|0|1|sz|E|1|M|0|Vm:4
-	{0x0fbe0e50, 0x0eba0a40, 4, arm_VCVT_EQ_F32_FXS16, 0x801100107011c04, arm_instArgs{arm_arg_Sd_Dd, arm_arg_Sd_Dd, arm_arg_fbits}},  // VCVT<c>.F<32,64>.FX<S,U><16,32> <Sd,Dd>, <Sd,Dd>, #<fbits> cond:4|1|1|1|0|1|D|1|1|1|0|1|U|Vd:4|1|0|1|sz|sx|1|i|0|imm4:4
-	{0x0fbe0e50, 0x0ebe0a40, 4, arm_VCVT_EQ_FXS16_F32, 0x1001070108011c04, arm_instArgs{arm_arg_Sd_Dd, arm_arg_Sd_Dd, arm_arg_fbits}}, // VCVT<c>.FX<S,U><16,32>.F<32,64> <Sd,Dd>, <Sd,Dd>, #<fbits> cond:4|1|1|1|0|1|D|1|1|1|1|1|U|Vd:4|1|0|1|sz|sx|1|i|0|imm4:4
-	{0x0fbf0ed0, 0x0eb70ac0, 4, arm_VCVT_EQ_F64_F32, 0x8011c04, arm_instArgs{arm_arg_Dd_Sd, arm_arg_Sm_Dm}},                           // VCVT<c>.<F64.F32,F32.F64> <Dd,Sd>, <Sm,Dm> cond:4|1|1|1|0|1|D|1|1|0|1|1|1|Vd:4|1|0|1|sz|1|1|M|0|Vm:4
-	{0x0fbe0f50, 0x0eb20a40, 4, arm_VCVTB_EQ_F32_F16, 0x70110011c04, arm_instArgs{arm_arg_Sd, arm_arg_Sm}},                            // VCVT<B,T><c>.<F32.F16,F16.F32> <Sd>, <Sm> cond:4|1|1|1|0|1|D|1|1|0|0|1|op|Vd:4|1|0|1|0|T|1|M|0|Vm:4
-	{0x0fbf0e50, 0x0eb80a40, 4, arm_VCVT_EQ_F32_U32, 0x80107011c04, arm_instArgs{arm_arg_Sd_Dd, arm_arg_Sm}},                          // VCVT<c>.F<32,64>.<U,S>32 <Sd,Dd>, <Sm> cond:4|1|1|1|0|1|D|1|1|1|0|0|0|Vd:4|1|0|1|sz|op|1|M|0|Vm:4
-	{0x0fbe0e50, 0x0ebc0a40, 4, arm_VCVTR_EQ_U32_F32, 0x701100108011c04, arm_instArgs{arm_arg_Sd, arm_arg_Sm_Dm}},                     // VCVT<R,><c>.<U,S>32.F<32,64> <Sd>, <Sm,Dm> cond:4|1|1|1|0|1|D|1|1|1|1|0|signed|Vd:4|1|0|1|sz|op|1|M|0|Vm:4
-	{0x0fb00e50, 0x0e800a00, 4, arm_VDIV_EQ_F32, 0x8011c04, arm_instArgs{arm_arg_Sd_Dd, arm_arg_Sn_Dn, arm_arg_Sm_Dm}},                // VDIV<c>.F<32,64> <Sd,Dd>, <Sn,Dn>, <Sm,Dm> cond:4|1|1|1|0|1|D|0|0|Vn:4|Vd:4|1|0|1|sz|N|0|M|0|Vm:4
-	{0x0f300e00, 0x0d100a00, 4, arm_VLDR_EQ, 0x1c04, arm_instArgs{arm_arg_Sd_Dd, arm_arg_mem_R_pm_imm8at0_offset}},                    // VLDR<c> <Sd,Dd>, [<Rn>{,#+/-<imm8>}] cond:4|1|1|0|1|U|D|0|1|Rn:4|Vd:4|1|0|1|sz|imm8:8
-	{0x0ff00f7f, 0x0e000a10, 4, arm_VMOV_EQ, 0x1c04, arm_instArgs{arm_arg_Sn, arm_arg_R_12}},                                          // VMOV<c> <Sn>, <Rt> cond:4|1|1|1|0|0|0|0|0|Vn:4|Rt:4|1|0|1|0|N|0|0|1|0|0|0|0
-	{0x0ff00f7f, 0x0e100a10, 4, arm_VMOV_EQ, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_Sn}},                                          // VMOV<c> <Rt>, <Sn> cond:4|1|1|1|0|0|0|0|1|Vn:4|Rt:4|1|0|1|0|N|0|0|1|0|0|0|0
-	{0x0fd00f7f, 0x0e100b10, 4, arm_VMOV_EQ_32, 0x1c04, arm_instArgs{arm_arg_R_12, arm_arg_Dn_half}},                                  // VMOV<c>.32 <Rt>, <Dn[x]> cond:4|1|1|1|0|0|0|opc1|1|Vn:4|Rt:4|1|0|1|1|N|0|0|1|0|0|0|0
-	{0x0fd00f7f, 0x0e000b10, 4, arm_VMOV_EQ_32, 0x1c04, arm_instArgs{arm_arg_Dn_half, arm_arg_R_12}},                                  // VMOV<c>.32 <Dd[x]>, <Rt> cond:4|1|1|1|0|0|0|opc1|0|Vd:4|Rt:4|1|0|1|1|D|0|0|1|0|0|0|0
-	{0x0fb00ef0, 0x0eb00a00, 4, arm_VMOV_EQ_F32, 0x8011c04, arm_instArgs{arm_arg_Sd_Dd, arm_arg_imm_vfp}},                             // VMOV<c>.F<32,64> <Sd,Dd>, #<imm_vfp> cond:4|1|1|1|0|1|D|1|1|imm4H:4|Vd:4|1|0|1|sz|0|0|0|0|imm4L:4
-	{0x0fbf0ed0, 0x0eb00a40, 4, arm_VMOV_EQ_F32, 0x8011c04, arm_instArgs{arm_arg_Sd_Dd, arm_arg_Sm_Dm}},                               // VMOV<c>.F<32,64> <Sd,Dd>, <Sm,Dm> cond:4|1|1|1|0|1|D|1|1|0|0|0|0|Vd:4|1|0|1|sz|0|1|M|0|Vm:4
-	{0x0fff0fff, 0x0ef10a10, 4, arm_VMRS_EQ, 0x1c04, arm_instArgs{arm_arg_R_12_nzcv, arm_arg_FPSCR}},                                  // VMRS<c> <Rt_nzcv>, FPSCR cond:4|1|1|1|0|1|1|1|1|0|0|0|1|Rt:4|1|0|1|0|0|0|0|1|0|0|0|0
-	{0x0fff0fff, 0x0ee10a10, 4, arm_VMSR_EQ, 0x1c04, arm_instArgs{arm_arg_FPSCR, arm_arg_R_12}},                                       // VMSR<c> FPSCR, <Rt> cond:4|1|1|1|0|1|1|1|0|0|0|0|1|Rt:4|1|0|1|0|0|0|0|1|0|0|0|0
-	{0x0fb00e50, 0x0e200a00, 4, arm_VMUL_EQ_F32, 0x8011c04, arm_instArgs{arm_arg_Sd_Dd, arm_arg_Sn_Dn, arm_arg_Sm_Dm}},                // VMUL<c>.F<32,64> <Sd,Dd>, <Sn,Dn>, <Sm,Dm> cond:4|1|1|1|0|0|D|1|0|Vn:4|Vd:4|1|0|1|sz|N|0|M|0|Vm:4
-	{0x0fbf0ed0, 0x0eb10a40, 4, arm_VNEG_EQ_F32, 0x8011c04, arm_instArgs{arm_arg_Sd_Dd, arm_arg_Sm_Dm}},                               // VNEG<c>.F<32,64> <Sd,Dd>, <Sm,Dm> cond:4|1|1|1|0|1|D|1|1|0|0|0|1|Vd:4|1|0|1|sz|0|1|M|0|Vm:4
-	{0x0fb00e10, 0x0e100a00, 4, arm_VNMLS_EQ_F32, 0x60108011c04, arm_instArgs{arm_arg_Sd_Dd, arm_arg_Sn_Dn, arm_arg_Sm_Dm}},           // VN<MLS,MLA><c>.F<32,64> <Sd,Dd>, <Sn,Dn>, <Sm,Dm> cond:4|1|1|1|0|0|D|0|1|Vn:4|Vd:4|1|0|1|sz|N|op|M|0|Vm:4
-	{0x0fb00e50, 0x0e200a40, 4, arm_VNMUL_EQ_F32, 0x8011c04, arm_instArgs{arm_arg_Sd_Dd, arm_arg_Sn_Dn, arm_arg_Sm_Dm}},               // VNMUL<c>.F<32,64> <Sd,Dd>, <Sn,Dn>, <Sm,Dm> cond:4|1|1|1|0|0|D|1|0|Vn:4|Vd:4|1|0|1|sz|N|1|M|0|Vm:4
-	{0x0fbf0ed0, 0x0eb10ac0, 4, arm_VSQRT_EQ_F32, 0x8011c04, arm_instArgs{arm_arg_Sd_Dd, arm_arg_Sm_Dm}},                              // VSQRT<c>.F<32,64> <Sd,Dd>, <Sm,Dm> cond:4|1|1|1|0|1|D|1|1|0|0|0|1|Vd:4|1|0|1|sz|1|1|M|0|Vm:4
-	{0x0f300e00, 0x0d000a00, 4, arm_VSTR_EQ, 0x1c04, arm_instArgs{arm_arg_Sd_Dd, arm_arg_mem_R_pm_imm8at0_offset}},                    // VSTR<c> <Sd,Dd>, [<Rn>{,#+/-<imm8>}] cond:4|1|1|0|1|U|D|0|0|Rn:4|Vd:4|1|0|1|sz|imm8:8
-	{0x0fb00e50, 0x0e300a40, 4, arm_VSUB_EQ_F32, 0x8011c04, arm_instArgs{arm_arg_Sd_Dd, arm_arg_Sn_Dn, arm_arg_Sm_Dm}},                // VSUB<c>.F<32,64> <Sd,Dd>, <Sn,Dn>, <Sm,Dm> cond:4|1|1|1|0|0|D|1|1|Vn:4|Vd:4|1|0|1|sz|N|1|M|0|Vm:4
-	{0x0fffffff, 0x0320f002, 4, arm_WFE_EQ, 0x1c04, arm_instArgs{}},                                                                   // WFE<c> cond:4|0|0|1|1|0|0|1|0|0|0|0|0|(1)|(1)|(1)|(1)|(0)|(0)|(0)|(0)|0|0|0|0|0|0|1|0
-	{0x0fff00ff, 0x0320f002, 3, arm_WFE_EQ, 0x1c04, arm_instArgs{}},                                                                   // WFE<c> cond:4|0|0|1|1|0|0|1|0|0|0|0|0|(1)|(1)|(1)|(1)|(0)|(0)|(0)|(0)|0|0|0|0|0|0|1|0
-	{0x0fffffff, 0x0320f003, 4, arm_WFI_EQ, 0x1c04, arm_instArgs{}},                                                                   // WFI<c> cond:4|0|0|1|1|0|0|1|0|0|0|0|0|(1)|(1)|(1)|(1)|(0)|(0)|(0)|(0)|0|0|0|0|0|0|1|1
-	{0x0fff00ff, 0x0320f003, 3, arm_WFI_EQ, 0x1c04, arm_instArgs{}},                                                                   // WFI<c> cond:4|0|0|1|1|0|0|1|0|0|0|0|0|(1)|(1)|(1)|(1)|(0)|(0)|(0)|(0)|0|0|0|0|0|0|1|1
-	{0x0fffffff, 0x0320f001, 4, arm_YIELD_EQ, 0x1c04, arm_instArgs{}},                                                                 // YIELD<c> cond:4|0|0|1|1|0|0|1|0|0|0|0|0|(1)|(1)|(1)|(1)|(0)|(0)|(0)|(0)|0|0|0|0|0|0|0|1
-	{0x0fff00ff, 0x0320f001, 3, arm_YIELD_EQ, 0x1c04, arm_instArgs{}},                                                                 // YIELD<c> cond:4|0|0|1|1|0|0|1|0|0|0|0|0|(1)|(1)|(1)|(1)|(0)|(0)|(0)|(0)|0|0|0|0|0|0|0|1
-	{0xffffffff, 0xf7fabcfd, 4, arm_UNDEF, 0x0, arm_instArgs{}},                                                                       // UNDEF 1|1|1|1|0|1|1|1|1|1|1|1|1|0|1|0|1|0|1|1|1|1|0|0|1|1|1|1|1|1|0|1
-}
diff --git a/src/cmd/objdump/elf.go b/src/cmd/objdump/elf.go
deleted file mode 100644
index 906e903..0000000
--- a/src/cmd/objdump/elf.go
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright 2013 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Parsing of ELF executables (Linux, FreeBSD, and so on).
-
-package main
-
-import (
-	"debug/elf"
-	"os"
-)
-
-func elfSymbols(f *os.File) (syms []Sym, goarch string) {
-	p, err := elf.NewFile(f)
-	if err != nil {
-		errorf("parsing %s: %v", f.Name(), err)
-		return
-	}
-
-	elfSyms, err := p.Symbols()
-	if err != nil {
-		errorf("parsing %s: %v", f.Name(), err)
-		return
-	}
-
-	switch p.Machine {
-	case elf.EM_X86_64:
-		goarch = "amd64"
-	case elf.EM_386:
-		goarch = "386"
-	case elf.EM_ARM:
-		goarch = "arm"
-	}
-
-	for _, s := range elfSyms {
-		sym := Sym{Addr: s.Value, Name: s.Name, Size: int64(s.Size), Code: '?'}
-		switch s.Section {
-		case elf.SHN_UNDEF:
-			sym.Code = 'U'
-		case elf.SHN_COMMON:
-			sym.Code = 'B'
-		default:
-			i := int(s.Section)
-			if i < 0 || i >= len(p.Sections) {
-				break
-			}
-			sect := p.Sections[i]
-			switch sect.Flags & (elf.SHF_WRITE | elf.SHF_ALLOC | elf.SHF_EXECINSTR) {
-			case elf.SHF_ALLOC | elf.SHF_EXECINSTR:
-				sym.Code = 'T'
-			case elf.SHF_ALLOC:
-				sym.Code = 'R'
-			case elf.SHF_ALLOC | elf.SHF_WRITE:
-				sym.Code = 'D'
-			}
-		}
-		if elf.ST_BIND(s.Info) == elf.STB_LOCAL {
-			sym.Code += 'a' - 'A'
-		}
-		syms = append(syms, sym)
-	}
-
-	return
-}
diff --git a/src/cmd/objdump/macho.go b/src/cmd/objdump/macho.go
deleted file mode 100644
index 6e0ad22..0000000
--- a/src/cmd/objdump/macho.go
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright 2013 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Parsing of Mach-O executables (OS X).
-
-package main
-
-import (
-	"debug/macho"
-	"os"
-	"sort"
-)
-
-func machoSymbols(f *os.File) (syms []Sym, goarch string) {
-	p, err := macho.NewFile(f)
-	if err != nil {
-		errorf("parsing %s: %v", f.Name(), err)
-		return
-	}
-
-	if p.Symtab == nil {
-		errorf("%s: no symbol table", f.Name())
-		return
-	}
-
-	switch p.Cpu {
-	case macho.Cpu386:
-		goarch = "386"
-	case macho.CpuAmd64:
-		goarch = "amd64"
-	case macho.CpuArm:
-		goarch = "arm"
-	}
-
-	// Build sorted list of addresses of all symbols.
-	// We infer the size of a symbol by looking at where the next symbol begins.
-	var addrs []uint64
-	for _, s := range p.Symtab.Syms {
-		addrs = append(addrs, s.Value)
-	}
-	sort.Sort(uint64s(addrs))
-
-	for _, s := range p.Symtab.Syms {
-		sym := Sym{Name: s.Name, Addr: s.Value, Code: '?'}
-		i := sort.Search(len(addrs), func(x int) bool { return addrs[x] > s.Value })
-		if i < len(addrs) {
-			sym.Size = int64(addrs[i] - s.Value)
-		}
-		if s.Sect == 0 {
-			sym.Code = 'U'
-		} else if int(s.Sect) <= len(p.Sections) {
-			sect := p.Sections[s.Sect-1]
-			switch sect.Seg {
-			case "__TEXT":
-				sym.Code = 'R'
-			case "__DATA":
-				sym.Code = 'D'
-			}
-			switch sect.Seg + " " + sect.Name {
-			case "__TEXT __text":
-				sym.Code = 'T'
-			case "__DATA __bss", "__DATA __noptrbss":
-				sym.Code = 'B'
-			}
-		}
-		syms = append(syms, sym)
-	}
-
-	return
-}
-
-type uint64s []uint64
-
-func (x uint64s) Len() int           { return len(x) }
-func (x uint64s) Swap(i, j int)      { x[i], x[j] = x[j], x[i] }
-func (x uint64s) Less(i, j int) bool { return x[i] < x[j] }
diff --git a/src/cmd/objdump/main.go b/src/cmd/objdump/main.go
index ade5436..708a853 100644
--- a/src/cmd/objdump/main.go
+++ b/src/cmd/objdump/main.go
@@ -29,30 +29,18 @@
 // Each stanza gives the disassembly for a contiguous range of addresses
 // all mapped to the same original source file and line number.
 // This mode is intended for use by pprof.
-//
-// The ARM disassembler is missing (golang.org/issue/7452) but will be added
-// before the Go 1.3 release.
 package main
 
 import (
-	"bufio"
-	"bytes"
-	"debug/elf"
-	"debug/gosym"
-	"debug/macho"
-	"debug/pe"
-	"debug/plan9obj"
-	"encoding/binary"
 	"flag"
 	"fmt"
-	"io"
 	"log"
 	"os"
 	"regexp"
-	"sort"
 	"strconv"
 	"strings"
-	"text/tabwriter"
+
+	"cmd/internal/objfile"
 )
 
 var symregexp = flag.String("s", "", "only dump symbols matching this regexp")
@@ -85,435 +73,35 @@ func main() {
 		symRE = re
 	}
 
-	f, err := os.Open(flag.Arg(0))
+	f, err := objfile.Open(flag.Arg(0))
 	if err != nil {
 		log.Fatal(err)
 	}
 
-	textStart, textData, symtab, pclntab, err := loadTables(f)
-	if err != nil {
-		log.Fatalf("reading %s: %v", flag.Arg(0), err)
-	}
-
-	syms, goarch, err := loadSymbols(f)
-	if err != nil {
-		log.Fatalf("reading %s: %v", flag.Arg(0), err)
-	}
-
-	// Filter out section symbols, overwriting syms in place.
-	keep := syms[:0]
-	for _, sym := range syms {
-		switch sym.Name {
-		case "text", "_text", "etext", "_etext":
-			// drop
-		default:
-			keep = append(keep, sym)
-		}
-	}
-	syms = keep
-
-	disasm := disasms[goarch]
-	if disasm == nil {
-		log.Fatalf("reading %s: unknown architecture", flag.Arg(0))
-	}
-
-	lookup := func(addr uint64) (string, uint64) {
-		i := sort.Search(len(syms), func(i int) bool { return syms[i].Addr > addr })
-		if i > 0 {
-			s := syms[i-1]
-			if s.Addr <= addr && addr < s.Addr+uint64(s.Size) && s.Name != "etext" && s.Name != "_etext" {
-				return s.Name, s.Addr
-			}
-		}
-		return "", 0
-	}
-
-	pcln := gosym.NewLineTable(pclntab, textStart)
-	tab, err := gosym.NewTable(symtab, pcln)
-	if err != nil {
-		log.Fatalf("reading %s: %v", flag.Arg(0), err)
-	}
-
-	if flag.NArg() == 1 {
-		// disassembly of entire object - our format
-		dump(tab, lookup, disasm, goarch, syms, textData, textStart)
-		os.Exit(exitCode)
-	}
-
-	// disassembly of specific piece of object - gnu objdump format for pprof
-	gnuDump(tab, lookup, disasm, textData, textStart)
-	os.Exit(exitCode)
-}
-
-// base returns the final element in the path.
-// It works on both Windows and Unix paths.
-func base(path string) string {
-	path = path[strings.LastIndex(path, "/")+1:]
-	path = path[strings.LastIndex(path, `\`)+1:]
-	return path
-}
-
-func dump(tab *gosym.Table, lookup lookupFunc, disasm disasmFunc, goarch string, syms []Sym, textData []byte, textStart uint64) {
-	stdout := bufio.NewWriter(os.Stdout)
-	defer stdout.Flush()
-
-	printed := false
-	for _, sym := range syms {
-		if sym.Code != 'T' || sym.Size == 0 || sym.Name == "_text" || sym.Name == "text" || sym.Addr < textStart || symRE != nil && !symRE.MatchString(sym.Name) {
-			continue
-		}
-		if sym.Addr >= textStart+uint64(len(textData)) || sym.Addr+uint64(sym.Size) > textStart+uint64(len(textData)) {
-			break
-		}
-		if printed {
-			fmt.Fprintf(stdout, "\n")
-		} else {
-			printed = true
-		}
-		file, _, _ := tab.PCToLine(sym.Addr)
-		fmt.Fprintf(stdout, "TEXT %s(SB) %s\n", sym.Name, file)
-		tw := tabwriter.NewWriter(stdout, 1, 8, 1, '\t', 0)
-		start := sym.Addr
-		end := sym.Addr + uint64(sym.Size)
-		for pc := start; pc < end; {
-			i := pc - textStart
-			text, size := disasm(textData[i:end-textStart], pc, lookup)
-			file, line, _ := tab.PCToLine(pc)
-
-			// ARM is word-based, so show actual word hex, not byte hex.
-			// Since ARM is little endian, they're different.
-			if goarch == "arm" && size == 4 {
-				fmt.Fprintf(tw, "\t%s:%d\t%#x\t%08x\t%s\n", base(file), line, pc, binary.LittleEndian.Uint32(textData[i:i+uint64(size)]), text)
-			} else {
-				fmt.Fprintf(tw, "\t%s:%d\t%#x\t%x\t%s\n", base(file), line, pc, textData[i:i+uint64(size)], text)
-			}
-			pc += uint64(size)
-		}
-		tw.Flush()
-	}
-}
-
-func disasm_386(code []byte, pc uint64, lookup lookupFunc) (string, int) {
-	return disasm_x86(code, pc, lookup, 32)
-}
-
-func disasm_amd64(code []byte, pc uint64, lookup lookupFunc) (string, int) {
-	return disasm_x86(code, pc, lookup, 64)
-}
-
-func disasm_x86(code []byte, pc uint64, lookup lookupFunc, arch int) (string, int) {
-	inst, err := x86_Decode(code, 64)
-	var text string
-	size := inst.Len
-	if err != nil || size == 0 || inst.Op == 0 {
-		size = 1
-		text = "?"
-	} else {
-		text = x86_plan9Syntax(inst, pc, lookup)
-	}
-	return text, size
-}
-
-type textReader struct {
-	code []byte
-	pc   uint64
-}
-
-func (r textReader) ReadAt(data []byte, off int64) (n int, err error) {
-	if off < 0 || uint64(off) < r.pc {
-		return 0, io.EOF
-	}
-	d := uint64(off) - r.pc
-	if d >= uint64(len(r.code)) {
-		return 0, io.EOF
-	}
-	n = copy(data, r.code[d:])
-	if n < len(data) {
-		err = io.ErrUnexpectedEOF
-	}
-	return
-}
-
-func disasm_arm(code []byte, pc uint64, lookup lookupFunc) (string, int) {
-	inst, err := arm_Decode(code, arm_ModeARM)
-	var text string
-	size := inst.Len
-	if err != nil || size == 0 || inst.Op == 0 {
-		size = 4
-		text = "?"
-	} else {
-		text = arm_plan9Syntax(inst, pc, lookup, textReader{code, pc})
-	}
-	return text, size
-}
-
-var disasms = map[string]disasmFunc{
-	"386":   disasm_386,
-	"amd64": disasm_amd64,
-	"arm":   disasm_arm,
-}
-
-func gnuDump(tab *gosym.Table, lookup lookupFunc, disasm disasmFunc, textData []byte, textStart uint64) {
-	start, err := strconv.ParseUint(strings.TrimPrefix(flag.Arg(1), "0x"), 16, 64)
+	dis, err := f.Disasm()
 	if err != nil {
-		log.Fatalf("invalid start PC: %v", err)
-	}
-	end, err := strconv.ParseUint(strings.TrimPrefix(flag.Arg(2), "0x"), 16, 64)
-	if err != nil {
-		log.Fatalf("invalid end PC: %v", err)
-	}
-	if start < textStart {
-		start = textStart
-	}
-	if end < start {
-		end = start
-	}
-	if end > textStart+uint64(len(textData)) {
-		end = textStart + uint64(len(textData))
-	}
-
-	stdout := bufio.NewWriter(os.Stdout)
-	defer stdout.Flush()
-
-	// For now, find spans of same PC/line/fn and
-	// emit them as having dummy instructions.
-	var (
-		spanPC   uint64
-		spanFile string
-		spanLine int
-		spanFn   *gosym.Func
-	)
-
-	flush := func(endPC uint64) {
-		if spanPC == 0 {
-			return
-		}
-		fmt.Fprintf(stdout, "%s:%d\n", spanFile, spanLine)
-		for pc := spanPC; pc < endPC; {
-			text, size := disasm(textData[pc-textStart:], pc, lookup)
-			fmt.Fprintf(stdout, " %x: %s\n", pc, text)
-			pc += uint64(size)
-		}
-		spanPC = 0
-	}
-
-	for pc := start; pc < end; pc++ {
-		file, line, fn := tab.PCToLine(pc)
-		if file != spanFile || line != spanLine || fn != spanFn {
-			flush(pc)
-			spanPC, spanFile, spanLine, spanFn = pc, file, line, fn
-		}
-	}
-	flush(end)
-}
-
-func loadTables(f *os.File) (textStart uint64, textData, symtab, pclntab []byte, err error) {
-	if obj, err := elf.NewFile(f); err == nil {
-		if sect := obj.Section(".text"); sect != nil {
-			textStart = sect.Addr
-			textData, _ = sect.Data()
-		}
-		if sect := obj.Section(".gosymtab"); sect != nil {
-			if symtab, err = sect.Data(); err != nil {
-				return 0, nil, nil, nil, err
-			}
-		}
-		if sect := obj.Section(".gopclntab"); sect != nil {
-			if pclntab, err = sect.Data(); err != nil {
-				return 0, nil, nil, nil, err
-			}
-		}
-		return textStart, textData, symtab, pclntab, nil
+		log.Fatal("disassemble %s: %v", flag.Arg(0), err)
 	}
 
-	if obj, err := macho.NewFile(f); err == nil {
-		if sect := obj.Section("__text"); sect != nil {
-			textStart = sect.Addr
-			textData, _ = sect.Data()
-		}
-		if sect := obj.Section("__gosymtab"); sect != nil {
-			if symtab, err = sect.Data(); err != nil {
-				return 0, nil, nil, nil, err
-			}
-		}
-		if sect := obj.Section("__gopclntab"); sect != nil {
-			if pclntab, err = sect.Data(); err != nil {
-				return 0, nil, nil, nil, err
-			}
-		}
-		return textStart, textData, symtab, pclntab, nil
-	}
-
-	if obj, err := pe.NewFile(f); err == nil {
-		var imageBase uint64
-		switch oh := obj.OptionalHeader.(type) {
-		case *pe.OptionalHeader32:
-			imageBase = uint64(oh.ImageBase)
-		case *pe.OptionalHeader64:
-			imageBase = oh.ImageBase
-		default:
-			return 0, nil, nil, nil, fmt.Errorf("pe file format not recognized")
-		}
-		if sect := obj.Section(".text"); sect != nil {
-			textStart = imageBase + uint64(sect.VirtualAddress)
-			textData, _ = sect.Data()
-		}
-		if pclntab, err = loadPETable(obj, "pclntab", "epclntab"); err != nil {
-			return 0, nil, nil, nil, err
-		}
-		if symtab, err = loadPETable(obj, "symtab", "esymtab"); err != nil {
-			return 0, nil, nil, nil, err
-		}
-		return textStart, textData, symtab, pclntab, nil
-	}
-
-	if obj, err := plan9obj.NewFile(f); err == nil {
-		sym, err := findPlan9Symbol(obj, "text")
+	switch flag.NArg() {
+	default:
+		usage()
+	case 1:
+		// disassembly of entire object
+		dis.Print(os.Stdout, symRE, 0, ^uint64(0))
+		os.Exit(0)
+
+	case 3:
+		// disassembly of PC range
+		start, err := strconv.ParseUint(strings.TrimPrefix(flag.Arg(1), "0x"), 16, 64)
 		if err != nil {
-			return 0, nil, nil, nil, err
-		}
-		textStart = sym.Value
-		if sect := obj.Section("text"); sect != nil {
-			textData, _ = sect.Data()
-		}
-		if pclntab, err = loadPlan9Table(obj, "pclntab", "epclntab"); err != nil {
-			return 0, nil, nil, nil, err
-		}
-		if symtab, err = loadPlan9Table(obj, "symtab", "esymtab"); err != nil {
-			return 0, nil, nil, nil, err
-		}
-		return textStart, textData, symtab, pclntab, nil
-	}
-
-	return 0, nil, nil, nil, fmt.Errorf("unrecognized binary format")
-}
-
-func findPESymbol(f *pe.File, name string) (*pe.Symbol, error) {
-	for _, s := range f.Symbols {
-		if s.Name != name {
-			continue
-		}
-		if s.SectionNumber <= 0 {
-			return nil, fmt.Errorf("symbol %s: invalid section number %d", name, s.SectionNumber)
-		}
-		if len(f.Sections) < int(s.SectionNumber) {
-			return nil, fmt.Errorf("symbol %s: section number %d is larger than max %d", name, s.SectionNumber, len(f.Sections))
-		}
-		return s, nil
-	}
-	return nil, fmt.Errorf("no %s symbol found", name)
-}
-
-func loadPETable(f *pe.File, sname, ename string) ([]byte, error) {
-	ssym, err := findPESymbol(f, sname)
-	if err != nil {
-		return nil, err
-	}
-	esym, err := findPESymbol(f, ename)
-	if err != nil {
-		return nil, err
-	}
-	if ssym.SectionNumber != esym.SectionNumber {
-		return nil, fmt.Errorf("%s and %s symbols must be in the same section", sname, ename)
-	}
-	sect := f.Sections[ssym.SectionNumber-1]
-	data, err := sect.Data()
-	if err != nil {
-		return nil, err
-	}
-	return data[ssym.Value:esym.Value], nil
-}
-
-func findPlan9Symbol(f *plan9obj.File, name string) (*plan9obj.Sym, error) {
-	syms, err := f.Symbols()
-	if err != nil {
-		return nil, err
-	}
-	for _, s := range syms {
-		if s.Name != name {
-			continue
+			log.Fatalf("invalid start PC: %v", err)
 		}
-		return &s, nil
-	}
-	return nil, fmt.Errorf("no %s symbol found", name)
-}
-
-func loadPlan9Table(f *plan9obj.File, sname, ename string) ([]byte, error) {
-	ssym, err := findPlan9Symbol(f, sname)
-	if err != nil {
-		return nil, err
-	}
-	esym, err := findPlan9Symbol(f, ename)
-	if err != nil {
-		return nil, err
-	}
-	text, err := findPlan9Symbol(f, "text")
-	if err != nil {
-		return nil, err
-	}
-	sect := f.Section("text")
-	if sect == nil {
-		return nil, err
-	}
-	data, err := sect.Data()
-	if err != nil {
-		return nil, err
-	}
-	return data[ssym.Value-text.Value : esym.Value-text.Value], nil
-}
-
-// TODO(rsc): This code is taken from cmd/nm. Arrange some way to share the code.
-
-var exitCode = 0
-
-func errorf(format string, args ...interface{}) {
-	log.Printf(format, args...)
-	exitCode = 1
-}
-
-func loadSymbols(f *os.File) (syms []Sym, goarch string, err error) {
-	f.Seek(0, 0)
-	buf := make([]byte, 16)
-	io.ReadFull(f, buf)
-	f.Seek(0, 0)
-
-	for _, p := range parsers {
-		if bytes.HasPrefix(buf, p.prefix) {
-			syms, goarch = p.parse(f)
-			sort.Sort(byAddr(syms))
-			return
+		end, err := strconv.ParseUint(strings.TrimPrefix(flag.Arg(2), "0x"), 16, 64)
+		if err != nil {
+			log.Fatalf("invalid end PC: %v", err)
 		}
+		dis.Print(os.Stdout, symRE, start, end)
+		os.Exit(0)
 	}
-	err = fmt.Errorf("unknown file format")
-	return
-}
-
-type Sym struct {
-	Addr uint64
-	Size int64
-	Code rune
-	Name string
-	Type string
 }
-
-var parsers = []struct {
-	prefix []byte
-	parse  func(*os.File) ([]Sym, string)
-}{
-	{[]byte("\x7FELF"), elfSymbols},
-	{[]byte("\xFE\xED\xFA\xCE"), machoSymbols},
-	{[]byte("\xFE\xED\xFA\xCF"), machoSymbols},
-	{[]byte("\xCE\xFA\xED\xFE"), machoSymbols},
-	{[]byte("\xCF\xFA\xED\xFE"), machoSymbols},
-	{[]byte("MZ"), peSymbols},
-	{[]byte("\x00\x00\x01\xEB"), plan9Symbols}, // 386
-	{[]byte("\x00\x00\x04\x07"), plan9Symbols}, // mips
-	{[]byte("\x00\x00\x06\x47"), plan9Symbols}, // arm
-	{[]byte("\x00\x00\x8A\x97"), plan9Symbols}, // amd64
-}
-
-type byAddr []Sym
-
-func (x byAddr) Len() int           { return len(x) }
-func (x byAddr) Swap(i, j int)      { x[i], x[j] = x[j], x[i] }
-func (x byAddr) Less(i, j int) bool { return x[i].Addr < x[j].Addr }
diff --git a/src/cmd/objdump/objdump_test.go b/src/cmd/objdump/objdump_test.go
index 82311bb..2bb7466 100644
--- a/src/cmd/objdump/objdump_test.go
+++ b/src/cmd/objdump/objdump_test.go
@@ -5,114 +5,19 @@
 package main
 
 import (
-	"bufio"
-	"bytes"
-	"fmt"
 	"io/ioutil"
 	"os"
 	"os/exec"
 	"path/filepath"
 	"runtime"
-	"strconv"
 	"strings"
 	"testing"
 )
 
-func loadSyms(t *testing.T) map[string]string {
-	if runtime.GOOS == "nacl" {
-		t.Skip("skipping on nacl")
-	}
-
-	cmd := exec.Command("go", "tool", "nm", os.Args[0])
-	out, err := cmd.CombinedOutput()
-	if err != nil {
-		t.Fatalf("go tool nm %v: %v\n%s", os.Args[0], err, string(out))
-	}
-	syms := make(map[string]string)
-	scanner := bufio.NewScanner(bytes.NewReader(out))
-	for scanner.Scan() {
-		f := strings.Fields(scanner.Text())
-		if len(f) < 3 {
-			continue
-		}
-		syms[f[2]] = f[0]
-	}
-	if err := scanner.Err(); err != nil {
-		t.Fatalf("error reading symbols: %v", err)
-	}
-	return syms
-}
-
-func runObjDump(t *testing.T, exe, startaddr, endaddr string) (path, lineno string) {
-	if runtime.GOOS == "nacl" {
-		t.Skip("skipping on nacl")
-	}
-
-	cmd := exec.Command(exe, os.Args[0], startaddr, endaddr)
-	out, err := cmd.CombinedOutput()
-	if err != nil {
-		t.Fatalf("go tool objdump %v: %v\n%s", os.Args[0], err, string(out))
-	}
-	f := strings.Split(string(out), "\n")
-	if len(f) < 1 {
-		t.Fatal("objdump output must have at least one line")
-	}
-	pathAndLineNo := f[0]
-	f = strings.Split(pathAndLineNo, ":")
-	if runtime.GOOS == "windows" {
-		switch len(f) {
-		case 2:
-			return f[0], f[1]
-		case 3:
-			return f[0] + ":" + f[1], f[2]
-		default:
-			t.Fatalf("no line number found in %q", pathAndLineNo)
-		}
-	}
-	if len(f) != 2 {
-		t.Fatalf("no line number found in %q", pathAndLineNo)
-	}
-	return f[0], f[1]
-}
-
-func testObjDump(t *testing.T, exe, startaddr, endaddr string, line int) {
-	srcPath, srcLineNo := runObjDump(t, exe, startaddr, endaddr)
-	fi1, err := os.Stat("objdump_test.go")
-	if err != nil {
-		t.Fatalf("Stat failed: %v", err)
-	}
-	fi2, err := os.Stat(srcPath)
-	if err != nil {
-		t.Fatalf("Stat failed: %v", err)
-	}
-	if !os.SameFile(fi1, fi2) {
-		t.Fatalf("objdump_test.go and %s are not same file", srcPath)
-	}
-	if srcLineNo != fmt.Sprint(line) {
-		t.Fatalf("line number = %v; want %d", srcLineNo, line)
-	}
-}
-
-func TestObjDump(t *testing.T) {
-	_, _, line, _ := runtime.Caller(0)
-	syms := loadSyms(t)
-
-	tmp, exe := buildObjdump(t)
-	defer os.RemoveAll(tmp)
-
-	startaddr := syms["cmd/objdump.TestObjDump"]
-	addr, err := strconv.ParseUint(startaddr, 16, 64)
-	if err != nil {
-		t.Fatalf("invalid start address %v: %v", startaddr, err)
-	}
-	endaddr := fmt.Sprintf("%x", addr+10)
-	testObjDump(t, exe, startaddr, endaddr, line-1)
-	testObjDump(t, exe, "0x"+startaddr, "0x"+endaddr, line-1)
-}
-
 func buildObjdump(t *testing.T) (tmp, exe string) {
-	if runtime.GOOS == "nacl" {
-		t.Skip("skipping on nacl")
+	switch runtime.GOOS {
+	case "android", "nacl":
+		t.Skipf("skipping on %s", runtime.GOOS)
 	}
 
 	tmp, err := ioutil.TempDir("", "TestObjDump")
@@ -140,7 +45,7 @@ var x86Need = []string{
 var armNeed = []string{
 	"fmthello.go:6",
 	"TEXT main.main(SB)",
-	"B.LS main.main(SB)",
+	//"B.LS main.main(SB)", // TODO(rsc): restore; golang.org/issue/9021
 	"BL fmt.Println(SB)",
 	"RET",
 }
@@ -154,12 +59,15 @@ var armNeed = []string{
 // binary for the current system (only) and test that objdump
 // can handle that one.
 
-func TestDisasm(t *testing.T) {
+func testDisasm(t *testing.T, flags ...string) {
 	tmp, exe := buildObjdump(t)
 	defer os.RemoveAll(tmp)
 
 	hello := filepath.Join(tmp, "hello.exe")
-	out, err := exec.Command("go", "build", "-o", hello, "testdata/fmthello.go").CombinedOutput()
+	args := []string{"build", "-o", hello}
+	args = append(args, flags...)
+	args = append(args, "testdata/fmthello.go")
+	out, err := exec.Command("go", args...).CombinedOutput()
 	if err != nil {
 		t.Fatalf("go build fmthello.go: %v\n%s", err, out)
 	}
@@ -191,3 +99,15 @@ func TestDisasm(t *testing.T) {
 		t.Logf("full disassembly:\n%s", text)
 	}
 }
+
+func TestDisasm(t *testing.T) {
+	testDisasm(t)
+}
+
+func TestDisasmExtld(t *testing.T) {
+	switch runtime.GOOS {
+	case "plan9", "windows":
+		t.Skipf("skipping on %s", runtime.GOOS)
+	}
+	testDisasm(t, "-ldflags=-linkmode=external")
+}
diff --git a/src/cmd/objdump/pe.go b/src/cmd/objdump/pe.go
deleted file mode 100644
index 3819009..0000000
--- a/src/cmd/objdump/pe.go
+++ /dev/null
@@ -1,99 +0,0 @@
-// Copyright 2013 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Parsing of PE executables (Microsoft Windows).
-
-package main
-
-import (
-	"debug/pe"
-	"os"
-	"sort"
-)
-
-func peSymbols(f *os.File) (syms []Sym, goarch string) {
-	p, err := pe.NewFile(f)
-	if err != nil {
-		errorf("parsing %s: %v", f.Name(), err)
-		return
-	}
-
-	// Build sorted list of addresses of all symbols.
-	// We infer the size of a symbol by looking at where the next symbol begins.
-	var addrs []uint64
-
-	var imageBase uint64
-	switch oh := p.OptionalHeader.(type) {
-	case *pe.OptionalHeader32:
-		imageBase = uint64(oh.ImageBase)
-		goarch = "386"
-	case *pe.OptionalHeader64:
-		imageBase = oh.ImageBase
-		goarch = "amd64"
-	default:
-		errorf("parsing %s: file format not recognized", f.Name())
-		return
-	}
-
-	for _, s := range p.Symbols {
-		const (
-			N_UNDEF = 0  // An undefined (extern) symbol
-			N_ABS   = -1 // An absolute symbol (e_value is a constant, not an address)
-			N_DEBUG = -2 // A debugging symbol
-		)
-		sym := Sym{Name: s.Name, Addr: uint64(s.Value), Code: '?'}
-		switch s.SectionNumber {
-		case N_UNDEF:
-			sym.Code = 'U'
-		case N_ABS:
-			sym.Code = 'C'
-		case N_DEBUG:
-			sym.Code = '?'
-		default:
-			if s.SectionNumber < 0 {
-				errorf("parsing %s: invalid section number %d", f.Name(), s.SectionNumber)
-				return
-			}
-			if len(p.Sections) < int(s.SectionNumber) {
-				errorf("parsing %s: section number %d is large then max %d", f.Name(), s.SectionNumber, len(p.Sections))
-				return
-			}
-			sect := p.Sections[s.SectionNumber-1]
-			const (
-				text  = 0x20
-				data  = 0x40
-				bss   = 0x80
-				permX = 0x20000000
-				permR = 0x40000000
-				permW = 0x80000000
-			)
-			ch := sect.Characteristics
-			switch {
-			case ch&text != 0:
-				sym.Code = 'T'
-			case ch&data != 0:
-				if ch&permW == 0 {
-					sym.Code = 'R'
-				} else {
-					sym.Code = 'D'
-				}
-			case ch&bss != 0:
-				sym.Code = 'B'
-			}
-			sym.Addr += imageBase + uint64(sect.VirtualAddress)
-		}
-		syms = append(syms, sym)
-		addrs = append(addrs, sym.Addr)
-	}
-
-	sort.Sort(uint64s(addrs))
-	for i := range syms {
-		j := sort.Search(len(addrs), func(x int) bool { return addrs[x] > syms[i].Addr })
-		if j < len(addrs) {
-			syms[i].Size = int64(addrs[j] - syms[i].Addr)
-		}
-	}
-
-	return
-}
diff --git a/src/cmd/objdump/plan9obj.go b/src/cmd/objdump/plan9obj.go
deleted file mode 100644
index 34462f3..0000000
--- a/src/cmd/objdump/plan9obj.go
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright 2014 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Parsing of Plan 9 a.out executables.
-
-package main
-
-import (
-	"debug/plan9obj"
-	"os"
-	"sort"
-)
-
-var validSymType = map[rune]bool{
-	'T': true,
-	't': true,
-	'D': true,
-	'd': true,
-	'B': true,
-	'b': true,
-}
-
-func plan9Symbols(f *os.File) (syms []Sym, goarch string) {
-	p, err := plan9obj.NewFile(f)
-	if err != nil {
-		errorf("parsing %s: %v", f.Name(), err)
-		return
-	}
-
-	plan9Syms, err := p.Symbols()
-	if err != nil {
-		errorf("parsing %s: %v", f.Name(), err)
-		return
-	}
-
-	goarch = "386"
-
-	// Build sorted list of addresses of all symbols.
-	// We infer the size of a symbol by looking at where the next symbol begins.
-	var addrs []uint64
-	for _, s := range plan9Syms {
-		if !validSymType[s.Type] {
-			continue
-		}
-		addrs = append(addrs, s.Value)
-	}
-	sort.Sort(uint64s(addrs))
-
-	for _, s := range plan9Syms {
-		if !validSymType[s.Type] {
-			continue
-		}
-		sym := Sym{Addr: s.Value, Name: s.Name, Code: rune(s.Type)}
-		i := sort.Search(len(addrs), func(x int) bool { return addrs[x] > s.Value })
-		if i < len(addrs) {
-			sym.Size = int64(addrs[i] - s.Value)
-		}
-		syms = append(syms, sym)
-	}
-
-	return
-}
diff --git a/src/cmd/objdump/x86.go b/src/cmd/objdump/x86.go
deleted file mode 100644
index 8e74133..0000000
--- a/src/cmd/objdump/x86.go
+++ /dev/null
@@ -1,13800 +0,0 @@
-// DO NOT EDIT. Generated by code.google.com/p/rsc/cmd/bundle
-// bundle -p main -x x86_ rsc.io/x86/x86asm
-
-/* decode.go */
-
-// 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.
-
-// Table-driven decoding of x86 instructions.
-
-package main
-
-import (
-	"bytes"
-	"encoding/binary"
-	"errors"
-	"fmt"
-	"runtime"
-	"strings"
-)
-
-// Set trace to true to cause the decoder to print the PC sequence
-// of the executed instruction codes. This is typically only useful
-// when you are running a test of a single input case.
-const x86_trace = false
-
-// A decodeOp is a single instruction in the decoder bytecode program.
-//
-// The decodeOps correspond to consuming and conditionally branching
-// on input bytes, consuming additional fields, and then interpreting
-// consumed data as instruction arguments. The names of the xRead and xArg
-// operations are taken from the Intel manual conventions, for example
-// Volume 2, Section 3.1.1, page 487 of
-// http://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-manual-325462.pdf
-//
-// The actual decoding program is generated by ../x86map.
-//
-// TODO(rsc): We may be able to merge various of the memory operands
-// since we don't care about, say, the distinction between m80dec and m80bcd.
-// Similarly, mm and mm1 have identical meaning, as do xmm and xmm1.
-
-type x86_decodeOp uint16
-
-const (
-	x86_xFail  x86_decodeOp = iota // invalid instruction (return)
-	x86_xMatch                     // completed match
-	x86_xJump                      // jump to pc
-
-	x86_xCondByte     // switch on instruction byte value
-	x86_xCondSlashR   // read and switch on instruction /r value
-	x86_xCondPrefix   // switch on presence of instruction prefix
-	x86_xCondIs64     // switch on 64-bit processor mode
-	x86_xCondDataSize // switch on operand size
-	x86_xCondAddrSize // switch on address size
-	x86_xCondIsMem    // switch on memory vs register argument
-
-	x86_xSetOp // set instruction opcode
-
-	x86_xReadSlashR // read /r
-	x86_xReadIb     // read ib
-	x86_xReadIw     // read iw
-	x86_xReadId     // read id
-	x86_xReadIo     // read io
-	x86_xReadCb     // read cb
-	x86_xReadCw     // read cw
-	x86_xReadCd     // read cd
-	x86_xReadCp     // read cp
-	x86_xReadCm     // read cm
-
-	x86_xArg1            // arg 1
-	x86_xArg3            // arg 3
-	x86_xArgAL           // arg AL
-	x86_xArgAX           // arg AX
-	x86_xArgCL           // arg CL
-	x86_xArgCR0dashCR7   // arg CR0-CR7
-	x86_xArgCS           // arg CS
-	x86_xArgDR0dashDR7   // arg DR0-DR7
-	x86_xArgDS           // arg DS
-	x86_xArgDX           // arg DX
-	x86_xArgEAX          // arg EAX
-	x86_xArgEDX          // arg EDX
-	x86_xArgES           // arg ES
-	x86_xArgFS           // arg FS
-	x86_xArgGS           // arg GS
-	x86_xArgImm16        // arg imm16
-	x86_xArgImm32        // arg imm32
-	x86_xArgImm64        // arg imm64
-	x86_xArgImm8         // arg imm8
-	x86_xArgImm8u        // arg imm8 but record as unsigned
-	x86_xArgImm16u       // arg imm8 but record as unsigned
-	x86_xArgM            // arg m
-	x86_xArgM128         // arg m128
-	x86_xArgM1428byte    // arg m14/28byte
-	x86_xArgM16          // arg m16
-	x86_xArgM16and16     // arg m16&16
-	x86_xArgM16and32     // arg m16&32
-	x86_xArgM16and64     // arg m16&64
-	x86_xArgM16colon16   // arg m16:16
-	x86_xArgM16colon32   // arg m16:32
-	x86_xArgM16colon64   // arg m16:64
-	x86_xArgM16int       // arg m16int
-	x86_xArgM2byte       // arg m2byte
-	x86_xArgM32          // arg m32
-	x86_xArgM32and32     // arg m32&32
-	x86_xArgM32fp        // arg m32fp
-	x86_xArgM32int       // arg m32int
-	x86_xArgM512byte     // arg m512byte
-	x86_xArgM64          // arg m64
-	x86_xArgM64fp        // arg m64fp
-	x86_xArgM64int       // arg m64int
-	x86_xArgM8           // arg m8
-	x86_xArgM80bcd       // arg m80bcd
-	x86_xArgM80dec       // arg m80dec
-	x86_xArgM80fp        // arg m80fp
-	x86_xArgM94108byte   // arg m94/108byte
-	x86_xArgMm           // arg mm
-	x86_xArgMm1          // arg mm1
-	x86_xArgMm2          // arg mm2
-	x86_xArgMm2M64       // arg mm2/m64
-	x86_xArgMmM32        // arg mm/m32
-	x86_xArgMmM64        // arg mm/m64
-	x86_xArgMem          // arg mem
-	x86_xArgMoffs16      // arg moffs16
-	x86_xArgMoffs32      // arg moffs32
-	x86_xArgMoffs64      // arg moffs64
-	x86_xArgMoffs8       // arg moffs8
-	x86_xArgPtr16colon16 // arg ptr16:16
-	x86_xArgPtr16colon32 // arg ptr16:32
-	x86_xArgR16          // arg r16
-	x86_xArgR16op        // arg r16 with +rw in opcode
-	x86_xArgR32          // arg r32
-	x86_xArgR32M16       // arg r32/m16
-	x86_xArgR32M8        // arg r32/m8
-	x86_xArgR32op        // arg r32 with +rd in opcode
-	x86_xArgR64          // arg r64
-	x86_xArgR64M16       // arg r64/m16
-	x86_xArgR64op        // arg r64 with +rd in opcode
-	x86_xArgR8           // arg r8
-	x86_xArgR8op         // arg r8 with +rb in opcode
-	x86_xArgRAX          // arg RAX
-	x86_xArgRDX          // arg RDX
-	x86_xArgRM           // arg r/m
-	x86_xArgRM16         // arg r/m16
-	x86_xArgRM32         // arg r/m32
-	x86_xArgRM64         // arg r/m64
-	x86_xArgRM8          // arg r/m8
-	x86_xArgReg          // arg reg
-	x86_xArgRegM16       // arg reg/m16
-	x86_xArgRegM32       // arg reg/m32
-	x86_xArgRegM8        // arg reg/m8
-	x86_xArgRel16        // arg rel16
-	x86_xArgRel32        // arg rel32
-	x86_xArgRel8         // arg rel8
-	x86_xArgSS           // arg SS
-	x86_xArgST           // arg ST, aka ST(0)
-	x86_xArgSTi          // arg ST(i) with +i in opcode
-	x86_xArgSreg         // arg Sreg
-	x86_xArgTR0dashTR7   // arg TR0-TR7
-	x86_xArgXmm          // arg xmm
-	x86_xArgXMM0         // arg <XMM0>
-	x86_xArgXmm1         // arg xmm1
-	x86_xArgXmm2         // arg xmm2
-	x86_xArgXmm2M128     // arg xmm2/m128
-	x86_xArgXmm2M16      // arg xmm2/m16
-	x86_xArgXmm2M32      // arg xmm2/m32
-	x86_xArgXmm2M64      // arg xmm2/m64
-	x86_xArgXmmM128      // arg xmm/m128
-	x86_xArgXmmM32       // arg xmm/m32
-	x86_xArgXmmM64       // arg xmm/m64
-	x86_xArgRmf16        // arg r/m16 but force mod=3
-	x86_xArgRmf32        // arg r/m32 but force mod=3
-	x86_xArgRmf64        // arg r/m64 but force mod=3
-)
-
-// instPrefix returns an Inst describing just one prefix byte.
-// It is only used if there is a prefix followed by an unintelligible
-// or invalid instruction byte sequence.
-func x86_instPrefix(b byte, mode int) (x86_Inst, error) {
-	// When tracing it is useful to see what called instPrefix to report an error.
-	if x86_trace {
-		_, file, line, _ := runtime.Caller(1)
-		fmt.Printf("%s:%d\n", file, line)
-	}
-	p := x86_Prefix(b)
-	switch p {
-	case x86_PrefixDataSize:
-		if mode == 16 {
-			p = x86_PrefixData32
-		} else {
-			p = x86_PrefixData16
-		}
-	case x86_PrefixAddrSize:
-		if mode == 32 {
-			p = x86_PrefixAddr16
-		} else {
-			p = x86_PrefixAddr32
-		}
-	}
-	// Note: using composite literal with Prefix key confuses 'bundle' tool.
-	inst := x86_Inst{Len: 1}
-	inst.Prefix = x86_Prefixes{p}
-	return inst, nil
-}
-
-// truncated reports a truncated instruction.
-// For now we use instPrefix but perhaps later we will return
-// a specific error here.
-func x86_truncated(src []byte, mode int) (x86_Inst, error) {
-	//	return Inst{}, len(src), ErrTruncated
-	return x86_instPrefix(src[0], mode) // too long
-}
-
-// These are the errors returned by Decode.
-var (
-	x86_ErrInvalidMode  = errors.New("invalid x86 mode in Decode")
-	x86_ErrTruncated    = errors.New("truncated instruction")
-	x86_ErrUnrecognized = errors.New("unrecognized instruction")
-)
-
-// decoderCover records coverage information for which parts
-// of the byte code have been executed.
-// TODO(rsc): This is for testing. Only use this if a flag is given.
-var x86_decoderCover []bool
-
-// Decode decodes the leading bytes in src as a single instruction.
-// The mode arguments specifies the assumed processor mode:
-// 16, 32, or 64 for 16-, 32-, and 64-bit execution modes.
-func x86_Decode(src []byte, mode int) (inst x86_Inst, err error) {
-	return x86_decode1(src, mode, false)
-}
-
-// decode1 is the implementation of Decode but takes an extra
-// gnuCompat flag to cause it to change its behavior to mimic
-// bugs (or at least unique features) of GNU libopcodes as used
-// by objdump. We don't believe that logic is the right thing to do
-// in general, but when testing against libopcodes it simplifies the
-// comparison if we adjust a few small pieces of logic.
-// The affected logic is in the conditional branch for "mandatory" prefixes,
-// case xCondPrefix.
-func x86_decode1(src []byte, mode int, gnuCompat bool) (x86_Inst, error) {
-	switch mode {
-	case 16, 32, 64:
-		// ok
-		// TODO(rsc): 64-bit mode not tested, probably not working.
-	default:
-		return x86_Inst{}, x86_ErrInvalidMode
-	}
-
-	// Maximum instruction size is 15 bytes.
-	// If we need to read more, return 'truncated instruction.
-	if len(src) > 15 {
-		src = src[:15]
-	}
-
-	var (
-		// prefix decoding information
-		pos           = 0        // position reading src
-		nprefix       = 0        // number of prefixes
-		lockIndex     = -1       // index of LOCK prefix in src and inst.Prefix
-		repIndex      = -1       // index of REP/REPN prefix in src and inst.Prefix
-		segIndex      = -1       // index of Group 2 prefix in src and inst.Prefix
-		dataSizeIndex = -1       // index of Group 3 prefix in src and inst.Prefix
-		addrSizeIndex = -1       // index of Group 4 prefix in src and inst.Prefix
-		rex           x86_Prefix // rex byte if present (or 0)
-		rexUsed       x86_Prefix // bits used in rex byte
-		rexIndex      = -1       // index of rex byte
-
-		addrMode = mode // address mode (width in bits)
-		dataMode = mode // operand mode (width in bits)
-
-		// decoded ModR/M fields
-		haveModrm bool
-		modrm     int
-		mod       int
-		regop     int
-		rm        int
-
-		// if ModR/M is memory reference, Mem form
-		mem     x86_Mem
-		haveMem bool
-
-		// decoded SIB fields
-		haveSIB bool
-		sib     int
-		scale   int
-		index   int
-		base    int
-
-		// decoded immediate values
-		imm  int64
-		imm8 int8
-		immc int64
-
-		// output
-		opshift int
-		inst    x86_Inst
-		narg    int // number of arguments written to inst
-	)
-
-	if mode == 64 {
-		dataMode = 32
-	}
-
-	// Prefixes are certainly the most complex and underspecified part of
-	// decoding x86 instructions. Although the manuals say things like
-	// up to four prefixes, one from each group, nearly everyone seems to
-	// agree that in practice as many prefixes as possible, including multiple
-	// from a particular group or repetitions of a given prefix, can be used on
-	// an instruction, provided the total instruction length including prefixes
-	// does not exceed the agreed-upon maximum of 15 bytes.
-	// Everyone also agrees that if one of these prefixes is the LOCK prefix
-	// and the instruction is not one of the instructions that can be used with
-	// the LOCK prefix or if the destination is not a memory operand,
-	// then the instruction is invalid and produces the #UD exception.
-	// However, that is the end of any semblance of agreement.
-	//
-	// What happens if prefixes are given that conflict with other prefixes?
-	// For example, the memory segment overrides CS, DS, ES, FS, GS, SS
-	// conflict with each other: only one segment can be in effect.
-	// Disassemblers seem to agree that later prefixes take priority over
-	// earlier ones. I have not taken the time to write assembly programs
-	// to check to see if the hardware agrees.
-	//
-	// What happens if prefixes are given that have no meaning for the
-	// specific instruction to which they are attached? It depends.
-	// If they really have no meaning, they are ignored. However, a future
-	// processor may assign a different meaning. As a disassembler, we
-	// don't really know whether we're seeing a meaningless prefix or one
-	// whose meaning we simply haven't been told yet.
-	//
-	// Combining the two questions, what happens when conflicting
-	// extension prefixes are given? No one seems to know for sure.
-	// For example, MOVQ is 66 0F D6 /r, MOVDQ2Q is F2 0F D6 /r,
-	// and MOVQ2DQ is F3 0F D6 /r. What is '66 F2 F3 0F D6 /r'?
-	// Which prefix wins? See the xCondPrefix prefix for more.
-	//
-	// Writing assembly test cases to divine which interpretation the
-	// CPU uses might clarify the situation, but more likely it would
-	// make the situation even less clear.
-
-	// Read non-REX prefixes.
-ReadPrefixes:
-	for ; pos < len(src); pos++ {
-		p := x86_Prefix(src[pos])
-		switch p {
-		default:
-			nprefix = pos
-			break ReadPrefixes
-
-		// Group 1 - lock and repeat prefixes
-		// According to Intel, there should only be one from this set,
-		// but according to AMD both can be present.
-		case 0xF0:
-			if lockIndex >= 0 {
-				inst.Prefix[lockIndex] |= x86_PrefixIgnored
-			}
-			lockIndex = pos
-		case 0xF2, 0xF3:
-			if repIndex >= 0 {
-				inst.Prefix[repIndex] |= x86_PrefixIgnored
-			}
-			repIndex = pos
-
-		// Group 2 - segment override / branch hints
-		case 0x26, 0x2E, 0x36, 0x3E:
-			if mode == 64 {
-				p |= x86_PrefixIgnored
-				break
-			}
-			fallthrough
-		case 0x64, 0x65:
-			if segIndex >= 0 {
-				inst.Prefix[segIndex] |= x86_PrefixIgnored
-			}
-			segIndex = pos
-
-		// Group 3 - operand size override
-		case 0x66:
-			if mode == 16 {
-				dataMode = 32
-				p = x86_PrefixData32
-			} else {
-				dataMode = 16
-				p = x86_PrefixData16
-			}
-			if dataSizeIndex >= 0 {
-				inst.Prefix[dataSizeIndex] |= x86_PrefixIgnored
-			}
-			dataSizeIndex = pos
-
-		// Group 4 - address size override
-		case 0x67:
-			if mode == 32 {
-				addrMode = 16
-				p = x86_PrefixAddr16
-			} else {
-				addrMode = 32
-				p = x86_PrefixAddr32
-			}
-			if addrSizeIndex >= 0 {
-				inst.Prefix[addrSizeIndex] |= x86_PrefixIgnored
-			}
-			addrSizeIndex = pos
-		}
-
-		if pos >= len(inst.Prefix) {
-			return x86_instPrefix(src[0], mode) // too long
-		}
-
-		inst.Prefix[pos] = p
-	}
-
-	// Read REX prefix.
-	if pos < len(src) && mode == 64 && x86_Prefix(src[pos]).IsREX() {
-		rex = x86_Prefix(src[pos])
-		rexIndex = pos
-		if pos >= len(inst.Prefix) {
-			return x86_instPrefix(src[0], mode) // too long
-		}
-		inst.Prefix[pos] = rex
-		pos++
-		if rex&x86_PrefixREXW != 0 {
-			dataMode = 64
-			if dataSizeIndex >= 0 {
-				inst.Prefix[dataSizeIndex] |= x86_PrefixIgnored
-			}
-		}
-	}
-
-	// Decode instruction stream, interpreting decoding instructions.
-	// opshift gives the shift to use when saving the next
-	// opcode byte into inst.Opcode.
-	opshift = 24
-	if x86_decoderCover == nil {
-		x86_decoderCover = make([]bool, len(x86_decoder))
-	}
-
-	// Decode loop, executing decoder program.
-	var oldPC, prevPC int
-Decode:
-	for pc := 1; ; { // TODO uint
-		oldPC = prevPC
-		prevPC = pc
-		if x86_trace {
-			println("run", pc)
-		}
-		x := x86_decoder[pc]
-		x86_decoderCover[pc] = true
-		pc++
-
-		// Read and decode ModR/M if needed by opcode.
-		switch x86_decodeOp(x) {
-		case x86_xCondSlashR, x86_xReadSlashR:
-			if haveModrm {
-				return x86_Inst{Len: pos}, x86_errInternal
-			}
-			haveModrm = true
-			if pos >= len(src) {
-				return x86_truncated(src, mode)
-			}
-			modrm = int(src[pos])
-			pos++
-			if opshift >= 0 {
-				inst.Opcode |= uint32(modrm) << uint(opshift)
-				opshift -= 8
-			}
-			mod = modrm >> 6
-			regop = (modrm >> 3) & 07
-			rm = modrm & 07
-			if rex&x86_PrefixREXR != 0 {
-				rexUsed |= x86_PrefixREXR
-				regop |= 8
-			}
-			if addrMode == 16 {
-				// 16-bit modrm form
-				if mod != 3 {
-					haveMem = true
-					mem = x86_addr16[rm]
-					if rm == 6 && mod == 0 {
-						mem.Base = 0
-					}
-
-					// Consume disp16 if present.
-					if mod == 0 && rm == 6 || mod == 2 {
-						if pos+2 > len(src) {
-							return x86_truncated(src, mode)
-						}
-						mem.Disp = int64(binary.LittleEndian.Uint16(src[pos:]))
-						pos += 2
-					}
-
-					// Consume disp8 if present.
-					if mod == 1 {
-						if pos >= len(src) {
-							return x86_truncated(src, mode)
-						}
-						mem.Disp = int64(int8(src[pos]))
-						pos++
-					}
-				}
-			} else {
-				haveMem = mod != 3
-
-				// 32-bit or 64-bit form
-				// Consume SIB encoding if present.
-				if rm == 4 && mod != 3 {
-					haveSIB = true
-					if pos >= len(src) {
-						return x86_truncated(src, mode)
-					}
-					sib = int(src[pos])
-					pos++
-					if opshift >= 0 {
-						inst.Opcode |= uint32(sib) << uint(opshift)
-						opshift -= 8
-					}
-					scale = sib >> 6
-					index = (sib >> 3) & 07
-					base = sib & 07
-					if rex&x86_PrefixREXB != 0 {
-						rexUsed |= x86_PrefixREXB
-						base |= 8
-					}
-					if rex&x86_PrefixREXX != 0 {
-						rexUsed |= x86_PrefixREXX
-						index |= 8
-					}
-
-					mem.Scale = 1 << uint(scale)
-					if index == 4 {
-						// no mem.Index
-					} else {
-						mem.Index = x86_baseRegForBits(addrMode) + x86_Reg(index)
-					}
-					if base&7 == 5 && mod == 0 {
-						// no mem.Base
-					} else {
-						mem.Base = x86_baseRegForBits(addrMode) + x86_Reg(base)
-					}
-				} else {
-					if rex&x86_PrefixREXB != 0 {
-						rexUsed |= x86_PrefixREXB
-						rm |= 8
-					}
-					if mod == 0 && rm&7 == 5 || rm&7 == 4 {
-						// base omitted
-					} else if mod != 3 {
-						mem.Base = x86_baseRegForBits(addrMode) + x86_Reg(rm)
-					}
-				}
-
-				// Consume disp32 if present.
-				if mod == 0 && (rm&7 == 5 || haveSIB && base&7 == 5) || mod == 2 {
-					if pos+4 > len(src) {
-						return x86_truncated(src, mode)
-					}
-					mem.Disp = int64(binary.LittleEndian.Uint32(src[pos:]))
-					pos += 4
-				}
-
-				// Consume disp8 if present.
-				if mod == 1 {
-					if pos >= len(src) {
-						return x86_truncated(src, mode)
-					}
-					mem.Disp = int64(int8(src[pos]))
-					pos++
-				}
-
-				// In 64-bit, mod=0 rm=5 is PC-relative instead of just disp.
-				// See Vol 2A. Table 2-7.
-				if mode == 64 && mod == 0 && rm&7 == 5 {
-					if addrMode == 32 {
-						mem.Base = x86_EIP
-					} else {
-						mem.Base = x86_RIP
-					}
-				}
-			}
-
-			if segIndex >= 0 {
-				mem.Segment = x86_prefixToSegment(inst.Prefix[segIndex])
-			}
-		}
-
-		// Execute single opcode.
-		switch x86_decodeOp(x) {
-		default:
-			println("bad op", x, "at", pc-1, "from", oldPC)
-			return x86_Inst{Len: pos}, x86_errInternal
-
-		case x86_xFail:
-			inst.Op = 0
-			break Decode
-
-		case x86_xMatch:
-			break Decode
-
-		case x86_xJump:
-			pc = int(x86_decoder[pc])
-
-		// Conditional branches.
-
-		case x86_xCondByte:
-			if pos >= len(src) {
-				return x86_truncated(src, mode)
-			}
-			b := src[pos]
-			n := int(x86_decoder[pc])
-			pc++
-			for i := 0; i < n; i++ {
-				xb, xpc := x86_decoder[pc], int(x86_decoder[pc+1])
-				pc += 2
-				if b == byte(xb) {
-					pc = xpc
-					pos++
-					if opshift >= 0 {
-						inst.Opcode |= uint32(b) << uint(opshift)
-						opshift -= 8
-					}
-					continue Decode
-				}
-			}
-			// xCondByte is the only conditional with a fall through,
-			// so that it can be used to pick off special cases before
-			// an xCondSlash. If the fallthrough instruction is xFail,
-			// advance the position so that the decoded instruction
-			// size includes the byte we just compared against.
-			if x86_decodeOp(x86_decoder[pc]) == x86_xJump {
-				pc = int(x86_decoder[pc+1])
-			}
-			if x86_decodeOp(x86_decoder[pc]) == x86_xFail {
-				pos++
-			}
-
-		case x86_xCondIs64:
-			if mode == 64 {
-				pc = int(x86_decoder[pc+1])
-			} else {
-				pc = int(x86_decoder[pc])
-			}
-
-		case x86_xCondIsMem:
-			mem := haveMem
-			if !haveModrm {
-				if pos >= len(src) {
-					return x86_instPrefix(src[0], mode) // too long
-				}
-				mem = src[pos]>>6 != 3
-			}
-			if mem {
-				pc = int(x86_decoder[pc+1])
-			} else {
-				pc = int(x86_decoder[pc])
-			}
-
-		case x86_xCondDataSize:
-			switch dataMode {
-			case 16:
-				if dataSizeIndex >= 0 {
-					inst.Prefix[dataSizeIndex] |= x86_PrefixImplicit
-				}
-				pc = int(x86_decoder[pc])
-			case 32:
-				if dataSizeIndex >= 0 {
-					inst.Prefix[dataSizeIndex] |= x86_PrefixImplicit
-				}
-				pc = int(x86_decoder[pc+1])
-			case 64:
-				rexUsed |= x86_PrefixREXW
-				pc = int(x86_decoder[pc+2])
-			}
-
-		case x86_xCondAddrSize:
-			switch addrMode {
-			case 16:
-				if addrSizeIndex >= 0 {
-					inst.Prefix[addrSizeIndex] |= x86_PrefixImplicit
-				}
-				pc = int(x86_decoder[pc])
-			case 32:
-				if addrSizeIndex >= 0 {
-					inst.Prefix[addrSizeIndex] |= x86_PrefixImplicit
-				}
-				pc = int(x86_decoder[pc+1])
-			case 64:
-				pc = int(x86_decoder[pc+2])
-			}
-
-		case x86_xCondPrefix:
-			// Conditional branch based on presence or absence of prefixes.
-			// The conflict cases here are completely undocumented and
-			// differ significantly between GNU libopcodes and Intel xed.
-			// I have not written assembly code to divine what various CPUs
-			// do, but it wouldn't surprise me if they are not consistent either.
-			//
-			// The basic idea is to switch on the presence of a prefix, so that
-			// for example:
-			//
-			//	xCondPrefix, 4
-			//	0xF3, 123,
-			//	0xF2, 234,
-			//	0x66, 345,
-			//	0, 456
-			//
-			// branch to 123 if the F3 prefix is present, 234 if the F2 prefix
-			// is present, 66 if the 345 prefix is present, and 456 otherwise.
-			// The prefixes are given in descending order so that the 0 will be last.
-			//
-			// It is unclear what should happen if multiple conditions are
-			// satisfied: what if F2 and F3 are both present, or if 66 and F2
-			// are present, or if all three are present? The one chosen becomes
-			// part of the opcode and the others do not. Perhaps the answer
-			// depends on the specific opcodes in question.
-			//
-			// The only clear example is that CRC32 is F2 0F 38 F1 /r, and
-			// it comes in 16-bit and 32-bit forms based on the 66 prefix,
-			// so 66 F2 0F 38 F1 /r should be treated as F2 taking priority,
-			// with the 66 being only an operand size override, and probably
-			// F2 66 0F 38 F1 /r should be treated the same.
-			// Perhaps that rule is specific to the case of CRC32, since no
-			// 66 0F 38 F1 instruction is defined (today) (that we know of).
-			// However, both libopcodes and xed seem to generalize this
-			// example and choose F2/F3 in preference to 66, and we
-			// do the same.
-			//
-			// Next, what if both F2 and F3 are present? Which wins?
-			// The Intel xed rule, and ours, is that the one that occurs last wins.
-			// The GNU libopcodes rule, which we implement only in gnuCompat mode,
-			// is that F3 beats F2 unless F3 has no special meaning, in which
-			// case F3 can be a modified on an F2 special meaning.
-			//
-			// Concretely,
-			//	66 0F D6 /r is MOVQ
-			//	F2 0F D6 /r is MOVDQ2Q
-			//	F3 0F D6 /r is MOVQ2DQ.
-			//
-			//	F2 66 0F D6 /r is 66 + MOVDQ2Q always.
-			//	66 F2 0F D6 /r is 66 + MOVDQ2Q always.
-			//	F3 66 0F D6 /r is 66 + MOVQ2DQ always.
-			//	66 F3 0F D6 /r is 66 + MOVQ2DQ always.
-			//	F2 F3 0F D6 /r is F2 + MOVQ2DQ always.
-			//	F3 F2 0F D6 /r is F3 + MOVQ2DQ in Intel xed, but F2 + MOVQ2DQ in GNU libopcodes.
-			//	Adding 66 anywhere in the prefix section of the
-			//	last two cases does not change the outcome.
-			//
-			// Finally, what if there is a variant in which 66 is a mandatory
-			// prefix rather than an operand size override, but we know of
-			// no corresponding F2/F3 form, and we see both F2/F3 and 66.
-			// Does F2/F3 still take priority, so that the result is an unknown
-			// instruction, or does the 66 take priority, so that the extended
-			// 66 instruction should be interpreted as having a REP/REPN prefix?
-			// Intel xed does the former and GNU libopcodes does the latter.
-			// We side with Intel xed, unless we are trying to match libopcodes
-			// more closely during the comparison-based test suite.
-			//
-			// In 64-bit mode REX.W is another valid prefix to test for, but
-			// there is less ambiguity about that. When present, REX.W is
-			// always the first entry in the table.
-			n := int(x86_decoder[pc])
-			pc++
-			sawF3 := false
-			for j := 0; j < n; j++ {
-				prefix := x86_Prefix(x86_decoder[pc+2*j])
-				if prefix.IsREX() {
-					rexUsed |= prefix
-					if rex&prefix == prefix {
-						pc = int(x86_decoder[pc+2*j+1])
-						continue Decode
-					}
-					continue
-				}
-				ok := false
-				if prefix == 0 {
-					ok = true
-				} else if prefix.IsREX() {
-					rexUsed |= prefix
-					if rex&prefix == prefix {
-						ok = true
-					}
-				} else {
-					if prefix == 0xF3 {
-						sawF3 = true
-					}
-					switch prefix {
-					case x86_PrefixLOCK:
-						if lockIndex >= 0 {
-							inst.Prefix[lockIndex] |= x86_PrefixImplicit
-							ok = true
-						}
-					case x86_PrefixREP, x86_PrefixREPN:
-						if repIndex >= 0 && inst.Prefix[repIndex]&0xFF == prefix {
-							inst.Prefix[repIndex] |= x86_PrefixImplicit
-							ok = true
-						}
-						if gnuCompat && !ok && prefix == 0xF3 && repIndex >= 0 && (j+1 >= n || x86_decoder[pc+2*(j+1)] != 0xF2) {
-							// Check to see if earlier prefix F3 is present.
-							for i := repIndex - 1; i >= 0; i-- {
-								if inst.Prefix[i]&0xFF == prefix {
-									inst.Prefix[i] |= x86_PrefixImplicit
-									ok = true
-								}
-							}
-						}
-						if gnuCompat && !ok && prefix == 0xF2 && repIndex >= 0 && !sawF3 && inst.Prefix[repIndex]&0xFF == 0xF3 {
-							// Check to see if earlier prefix F2 is present.
-							for i := repIndex - 1; i >= 0; i-- {
-								if inst.Prefix[i]&0xFF == prefix {
-									inst.Prefix[i] |= x86_PrefixImplicit
-									ok = true
-								}
-							}
-						}
-					case x86_PrefixCS, x86_PrefixDS, x86_PrefixES, x86_PrefixFS, x86_PrefixGS, x86_PrefixSS:
-						if segIndex >= 0 && inst.Prefix[segIndex]&0xFF == prefix {
-							inst.Prefix[segIndex] |= x86_PrefixImplicit
-							ok = true
-						}
-					case x86_PrefixDataSize:
-						// Looking for 66 mandatory prefix.
-						// The F2/F3 mandatory prefixes take priority when both are present.
-						// If we got this far in the xCondPrefix table and an F2/F3 is present,
-						// it means the table didn't have any entry for that prefix. But if 66 has
-						// special meaning, perhaps F2/F3 have special meaning that we don't know.
-						// Intel xed works this way, treating the F2/F3 as inhibiting the 66.
-						// GNU libopcodes allows the 66 to match. We do what Intel xed does
-						// except in gnuCompat mode.
-						if repIndex >= 0 && !gnuCompat {
-							inst.Op = 0
-							break Decode
-						}
-						if dataSizeIndex >= 0 {
-							inst.Prefix[dataSizeIndex] |= x86_PrefixImplicit
-							ok = true
-						}
-					case x86_PrefixAddrSize:
-						if addrSizeIndex >= 0 {
-							inst.Prefix[addrSizeIndex] |= x86_PrefixImplicit
-							ok = true
-						}
-					}
-				}
-				if ok {
-					pc = int(x86_decoder[pc+2*j+1])
-					continue Decode
-				}
-			}
-			inst.Op = 0
-			break Decode
-
-		case x86_xCondSlashR:
-			pc = int(x86_decoder[pc+regop&7])
-
-		// Input.
-
-		case x86_xReadSlashR:
-			// done above
-
-		case x86_xReadIb:
-			if pos >= len(src) {
-				return x86_truncated(src, mode)
-			}
-			imm8 = int8(src[pos])
-			pos++
-
-		case x86_xReadIw:
-			if pos+2 > len(src) {
-				return x86_truncated(src, mode)
-			}
-			imm = int64(binary.LittleEndian.Uint16(src[pos:]))
-			pos += 2
-
-		case x86_xReadId:
-			if pos+4 > len(src) {
-				return x86_truncated(src, mode)
-			}
-			imm = int64(binary.LittleEndian.Uint32(src[pos:]))
-			pos += 4
-
-		case x86_xReadIo:
-			if pos+8 > len(src) {
-				return x86_truncated(src, mode)
-			}
-			imm = int64(binary.LittleEndian.Uint64(src[pos:]))
-			pos += 8
-
-		case x86_xReadCb:
-			if pos >= len(src) {
-				return x86_truncated(src, mode)
-			}
-			immc = int64(src[pos])
-			pos++
-
-		case x86_xReadCw:
-			if pos+2 > len(src) {
-				return x86_truncated(src, mode)
-			}
-			immc = int64(binary.LittleEndian.Uint16(src[pos:]))
-			pos += 2
-
-		case x86_xReadCm:
-			if addrMode == 16 {
-				if pos+2 > len(src) {
-					return x86_truncated(src, mode)
-				}
-				immc = int64(binary.LittleEndian.Uint16(src[pos:]))
-				pos += 2
-			} else if addrMode == 32 {
-				if pos+4 > len(src) {
-					return x86_truncated(src, mode)
-				}
-				immc = int64(binary.LittleEndian.Uint32(src[pos:]))
-				pos += 4
-			} else {
-				if pos+8 > len(src) {
-					return x86_truncated(src, mode)
-				}
-				immc = int64(binary.LittleEndian.Uint64(src[pos:]))
-				pos += 8
-			}
-		case x86_xReadCd:
-			if pos+4 > len(src) {
-				return x86_truncated(src, mode)
-			}
-			immc = int64(binary.LittleEndian.Uint32(src[pos:]))
-			pos += 4
-
-		case x86_xReadCp:
-			if pos+6 > len(src) {
-				return x86_truncated(src, mode)
-			}
-			w := binary.LittleEndian.Uint32(src[pos:])
-			w2 := binary.LittleEndian.Uint16(src[pos+4:])
-			immc = int64(w2)<<32 | int64(w)
-			pos += 6
-
-		// Output.
-
-		case x86_xSetOp:
-			inst.Op = x86_Op(x86_decoder[pc])
-			pc++
-
-		case x86_xArg1,
-			x86_xArg3,
-			x86_xArgAL,
-			x86_xArgAX,
-			x86_xArgCL,
-			x86_xArgCS,
-			x86_xArgDS,
-			x86_xArgDX,
-			x86_xArgEAX,
-			x86_xArgEDX,
-			x86_xArgES,
-			x86_xArgFS,
-			x86_xArgGS,
-			x86_xArgRAX,
-			x86_xArgRDX,
-			x86_xArgSS,
-			x86_xArgST,
-			x86_xArgXMM0:
-			inst.Args[narg] = x86_fixedArg[x]
-			narg++
-
-		case x86_xArgImm8:
-			inst.Args[narg] = x86_Imm(imm8)
-			narg++
-
-		case x86_xArgImm8u:
-			inst.Args[narg] = x86_Imm(uint8(imm8))
-			narg++
-
-		case x86_xArgImm16:
-			inst.Args[narg] = x86_Imm(int16(imm))
-			narg++
-
-		case x86_xArgImm16u:
-			inst.Args[narg] = x86_Imm(uint16(imm))
-			narg++
-
-		case x86_xArgImm32:
-			inst.Args[narg] = x86_Imm(int32(imm))
-			narg++
-
-		case x86_xArgImm64:
-			inst.Args[narg] = x86_Imm(imm)
-			narg++
-
-		case x86_xArgM,
-			x86_xArgM128,
-			x86_xArgM1428byte,
-			x86_xArgM16,
-			x86_xArgM16and16,
-			x86_xArgM16and32,
-			x86_xArgM16and64,
-			x86_xArgM16colon16,
-			x86_xArgM16colon32,
-			x86_xArgM16colon64,
-			x86_xArgM16int,
-			x86_xArgM2byte,
-			x86_xArgM32,
-			x86_xArgM32and32,
-			x86_xArgM32fp,
-			x86_xArgM32int,
-			x86_xArgM512byte,
-			x86_xArgM64,
-			x86_xArgM64fp,
-			x86_xArgM64int,
-			x86_xArgM8,
-			x86_xArgM80bcd,
-			x86_xArgM80dec,
-			x86_xArgM80fp,
-			x86_xArgM94108byte,
-			x86_xArgMem:
-			if !haveMem {
-				inst.Op = 0
-				break Decode
-			}
-			inst.Args[narg] = mem
-			inst.MemBytes = int(x86_memBytes[x86_decodeOp(x)])
-			narg++
-
-		case x86_xArgPtr16colon16:
-			inst.Args[narg] = x86_Imm(immc >> 16)
-			inst.Args[narg+1] = x86_Imm(immc & (1<<16 - 1))
-			narg += 2
-
-		case x86_xArgPtr16colon32:
-			inst.Args[narg] = x86_Imm(immc >> 32)
-			inst.Args[narg+1] = x86_Imm(immc & (1<<32 - 1))
-			narg += 2
-
-		case x86_xArgMoffs8, x86_xArgMoffs16, x86_xArgMoffs32, x86_xArgMoffs64:
-			// TODO(rsc): Can address be 64 bits?
-			mem = x86_Mem{Disp: int64(immc)}
-			if segIndex >= 0 {
-				mem.Segment = x86_prefixToSegment(inst.Prefix[segIndex])
-				inst.Prefix[segIndex] |= x86_PrefixImplicit
-			}
-			inst.Args[narg] = mem
-			inst.MemBytes = int(x86_memBytes[x86_decodeOp(x)])
-			narg++
-
-		case x86_xArgR8, x86_xArgR16, x86_xArgR32, x86_xArgR64, x86_xArgXmm, x86_xArgXmm1, x86_xArgDR0dashDR7:
-			base := x86_baseReg[x]
-			index := x86_Reg(regop)
-			if rex != 0 && base == x86_AL && index >= 4 {
-				rexUsed |= x86_PrefixREX
-				index -= 4
-				base = x86_SPB
-			}
-			inst.Args[narg] = base + index
-			narg++
-
-		case x86_xArgMm, x86_xArgMm1, x86_xArgTR0dashTR7:
-			inst.Args[narg] = x86_baseReg[x] + x86_Reg(regop&7)
-			narg++
-
-		case x86_xArgCR0dashCR7:
-			// AMD documents an extension that the LOCK prefix
-			// can be used in place of a REX prefix in order to access
-			// CR8 from 32-bit mode. The LOCK prefix is allowed in
-			// all modes, provided the corresponding CPUID bit is set.
-			if lockIndex >= 0 {
-				inst.Prefix[lockIndex] |= x86_PrefixImplicit
-				regop += 8
-			}
-			inst.Args[narg] = x86_CR0 + x86_Reg(regop)
-			narg++
-
-		case x86_xArgSreg:
-			regop &= 7
-			if regop >= 6 {
-				inst.Op = 0
-				break Decode
-			}
-			inst.Args[narg] = x86_ES + x86_Reg(regop)
-			narg++
-
-		case x86_xArgRmf16, x86_xArgRmf32, x86_xArgRmf64:
-			base := x86_baseReg[x]
-			index := x86_Reg(modrm & 07)
-			if rex&x86_PrefixREXB != 0 {
-				rexUsed |= x86_PrefixREXB
-				index += 8
-			}
-			inst.Args[narg] = base + index
-			narg++
-
-		case x86_xArgR8op, x86_xArgR16op, x86_xArgR32op, x86_xArgR64op, x86_xArgSTi:
-			n := inst.Opcode >> uint(opshift+8) & 07
-			base := x86_baseReg[x]
-			index := x86_Reg(n)
-			if rex&x86_PrefixREXB != 0 && x86_decodeOp(x) != x86_xArgSTi {
-				rexUsed |= x86_PrefixREXB
-				index += 8
-			}
-			if rex != 0 && base == x86_AL && index >= 4 {
-				rexUsed |= x86_PrefixREX
-				index -= 4
-				base = x86_SPB
-			}
-			inst.Args[narg] = base + index
-			narg++
-
-		case x86_xArgRM8, x86_xArgRM16, x86_xArgRM32, x86_xArgRM64, x86_xArgR32M16, x86_xArgR32M8, x86_xArgR64M16,
-			x86_xArgMmM32, x86_xArgMmM64, x86_xArgMm2M64,
-			x86_xArgXmm2M16, x86_xArgXmm2M32, x86_xArgXmm2M64, x86_xArgXmmM64, x86_xArgXmmM128, x86_xArgXmmM32, x86_xArgXmm2M128:
-			if haveMem {
-				inst.Args[narg] = mem
-				inst.MemBytes = int(x86_memBytes[x86_decodeOp(x)])
-			} else {
-				base := x86_baseReg[x]
-				index := x86_Reg(rm)
-				switch x86_decodeOp(x) {
-				case x86_xArgMmM32, x86_xArgMmM64, x86_xArgMm2M64:
-					// There are only 8 MMX registers, so these ignore the REX.X bit.
-					index &= 7
-				case x86_xArgRM8:
-					if rex != 0 && index >= 4 {
-						rexUsed |= x86_PrefixREX
-						index -= 4
-						base = x86_SPB
-					}
-				}
-				inst.Args[narg] = base + index
-			}
-			narg++
-
-		case x86_xArgMm2: // register only; TODO(rsc): Handle with tag modrm_regonly tag
-			if haveMem {
-				inst.Op = 0
-				break Decode
-			}
-			inst.Args[narg] = x86_baseReg[x] + x86_Reg(rm&7)
-			narg++
-
-		case x86_xArgXmm2: // register only; TODO(rsc): Handle with tag modrm_regonly tag
-			if haveMem {
-				inst.Op = 0
-				break Decode
-			}
-			inst.Args[narg] = x86_baseReg[x] + x86_Reg(rm)
-			narg++
-
-		case x86_xArgRel8:
-			inst.Args[narg] = x86_Rel(int8(immc))
-			narg++
-
-		case x86_xArgRel16:
-			inst.Args[narg] = x86_Rel(int16(immc))
-			narg++
-
-		case x86_xArgRel32:
-			inst.Args[narg] = x86_Rel(int32(immc))
-			narg++
-		}
-	}
-
-	if inst.Op == 0 {
-		// Invalid instruction.
-		if nprefix > 0 {
-			return x86_instPrefix(src[0], mode) // invalid instruction
-		}
-		return x86_Inst{Len: pos}, x86_ErrUnrecognized
-	}
-
-	// Matched! Hooray!
-
-	// 90 decodes as XCHG EAX, EAX but is NOP.
-	// 66 90 decodes as XCHG AX, AX and is NOP too.
-	// 48 90 decodes as XCHG RAX, RAX and is NOP too.
-	// 43 90 decodes as XCHG R8D, EAX and is *not* NOP.
-	// F3 90 decodes as REP XCHG EAX, EAX but is PAUSE.
-	// It's all too special to handle in the decoding tables, at least for now.
-	if inst.Op == x86_XCHG && inst.Opcode>>24 == 0x90 {
-		if inst.Args[0] == x86_RAX || inst.Args[0] == x86_EAX || inst.Args[0] == x86_AX {
-			inst.Op = x86_NOP
-			if dataSizeIndex >= 0 {
-				inst.Prefix[dataSizeIndex] &^= x86_PrefixImplicit
-			}
-			inst.Args[0] = nil
-			inst.Args[1] = nil
-		}
-		if repIndex >= 0 && inst.Prefix[repIndex] == 0xF3 {
-			inst.Prefix[repIndex] |= x86_PrefixImplicit
-			inst.Op = x86_PAUSE
-			inst.Args[0] = nil
-			inst.Args[1] = nil
-		} else if gnuCompat {
-			for i := nprefix - 1; i >= 0; i-- {
-				if inst.Prefix[i]&0xFF == 0xF3 {
-					inst.Prefix[i] |= x86_PrefixImplicit
-					inst.Op = x86_PAUSE
-					inst.Args[0] = nil
-					inst.Args[1] = nil
-					break
-				}
-			}
-		}
-	}
-
-	// defaultSeg returns the default segment for an implicit
-	// memory reference: the final override if present, or else DS.
-	defaultSeg := func() x86_Reg {
-		if segIndex >= 0 {
-			inst.Prefix[segIndex] |= x86_PrefixImplicit
-			return x86_prefixToSegment(inst.Prefix[segIndex])
-		}
-		return x86_DS
-	}
-
-	// Add implicit arguments not present in the tables.
-	// Normally we shy away from making implicit arguments explicit,
-	// following the Intel manuals, but adding the arguments seems
-	// the best way to express the effect of the segment override prefixes.
-	// TODO(rsc): Perhaps add these to the tables and
-	// create bytecode instructions for them.
-	usedAddrSize := false
-	switch inst.Op {
-	case x86_INSB, x86_INSW, x86_INSD:
-		inst.Args[0] = x86_Mem{Segment: x86_ES, Base: x86_baseRegForBits(addrMode) + x86_DI - x86_AX}
-		inst.Args[1] = x86_DX
-		usedAddrSize = true
-
-	case x86_OUTSB, x86_OUTSW, x86_OUTSD:
-		inst.Args[0] = x86_DX
-		inst.Args[1] = x86_Mem{Segment: defaultSeg(), Base: x86_baseRegForBits(addrMode) + x86_SI - x86_AX}
-		usedAddrSize = true
-
-	case x86_MOVSB, x86_MOVSW, x86_MOVSD, x86_MOVSQ:
-		inst.Args[0] = x86_Mem{Segment: x86_ES, Base: x86_baseRegForBits(addrMode) + x86_DI - x86_AX}
-		inst.Args[1] = x86_Mem{Segment: defaultSeg(), Base: x86_baseRegForBits(addrMode) + x86_SI - x86_AX}
-		usedAddrSize = true
-
-	case x86_CMPSB, x86_CMPSW, x86_CMPSD, x86_CMPSQ:
-		inst.Args[0] = x86_Mem{Segment: defaultSeg(), Base: x86_baseRegForBits(addrMode) + x86_SI - x86_AX}
-		inst.Args[1] = x86_Mem{Segment: x86_ES, Base: x86_baseRegForBits(addrMode) + x86_DI - x86_AX}
-		usedAddrSize = true
-
-	case x86_LODSB, x86_LODSW, x86_LODSD, x86_LODSQ:
-		switch inst.Op {
-		case x86_LODSB:
-			inst.Args[0] = x86_AL
-		case x86_LODSW:
-			inst.Args[0] = x86_AX
-		case x86_LODSD:
-			inst.Args[0] = x86_EAX
-		case x86_LODSQ:
-			inst.Args[0] = x86_RAX
-		}
-		inst.Args[1] = x86_Mem{Segment: defaultSeg(), Base: x86_baseRegForBits(addrMode) + x86_SI - x86_AX}
-		usedAddrSize = true
-
-	case x86_STOSB, x86_STOSW, x86_STOSD, x86_STOSQ:
-		inst.Args[0] = x86_Mem{Segment: x86_ES, Base: x86_baseRegForBits(addrMode) + x86_DI - x86_AX}
-		switch inst.Op {
-		case x86_STOSB:
-			inst.Args[1] = x86_AL
-		case x86_STOSW:
-			inst.Args[1] = x86_AX
-		case x86_STOSD:
-			inst.Args[1] = x86_EAX
-		case x86_STOSQ:
-			inst.Args[1] = x86_RAX
-		}
-		usedAddrSize = true
-
-	case x86_SCASB, x86_SCASW, x86_SCASD, x86_SCASQ:
-		inst.Args[1] = x86_Mem{Segment: x86_ES, Base: x86_baseRegForBits(addrMode) + x86_DI - x86_AX}
-		switch inst.Op {
-		case x86_SCASB:
-			inst.Args[0] = x86_AL
-		case x86_SCASW:
-			inst.Args[0] = x86_AX
-		case x86_SCASD:
-			inst.Args[0] = x86_EAX
-		case x86_SCASQ:
-			inst.Args[0] = x86_RAX
-		}
-		usedAddrSize = true
-
-	case x86_XLATB:
-		inst.Args[0] = x86_Mem{Segment: defaultSeg(), Base: x86_baseRegForBits(addrMode) + x86_BX - x86_AX}
-		usedAddrSize = true
-	}
-
-	// If we used the address size annotation to construct the
-	// argument list, mark that prefix as implicit: it doesn't need
-	// to be shown when printing the instruction.
-	if haveMem || usedAddrSize {
-		if addrSizeIndex >= 0 {
-			inst.Prefix[addrSizeIndex] |= x86_PrefixImplicit
-		}
-	}
-
-	// Similarly, if there's some memory operand, the segment
-	// will be shown there and doesn't need to be shown as an
-	// explicit prefix.
-	if haveMem {
-		if segIndex >= 0 {
-			inst.Prefix[segIndex] |= x86_PrefixImplicit
-		}
-	}
-
-	// Branch predict prefixes are overloaded segment prefixes,
-	// since segment prefixes don't make sense on conditional jumps.
-	// Rewrite final instance to prediction prefix.
-	// The set of instructions to which the prefixes apply (other then the
-	// Jcc conditional jumps) is not 100% clear from the manuals, but
-	// the disassemblers seem to agree about the LOOP and JCXZ instructions,
-	// so we'll follow along.
-	// TODO(rsc): Perhaps this instruction class should be derived from the CSV.
-	if x86_isCondJmp[inst.Op] || x86_isLoop[inst.Op] || inst.Op == x86_JCXZ || inst.Op == x86_JECXZ || inst.Op == x86_JRCXZ {
-	PredictLoop:
-		for i := nprefix - 1; i >= 0; i-- {
-			p := inst.Prefix[i]
-			switch p & 0xFF {
-			case x86_PrefixCS:
-				inst.Prefix[i] = x86_PrefixPN
-				break PredictLoop
-			case x86_PrefixDS:
-				inst.Prefix[i] = x86_PrefixPT
-				break PredictLoop
-			}
-		}
-	}
-
-	// The BND prefix is part of the Intel Memory Protection Extensions (MPX).
-	// A REPN applied to certain control transfers is a BND prefix to bound
-	// the range of possible destinations. There's surprisingly little documentation
-	// about this, so we just do what libopcodes and xed agree on.
-	// In particular, it's unclear why a REPN applied to LOOP or JCXZ instructions
-	// does not turn into a BND.
-	// TODO(rsc): Perhaps this instruction class should be derived from the CSV.
-	if x86_isCondJmp[inst.Op] || inst.Op == x86_JMP || inst.Op == x86_CALL || inst.Op == x86_RET {
-		for i := nprefix - 1; i >= 0; i-- {
-			p := inst.Prefix[i]
-			if p&^x86_PrefixIgnored == x86_PrefixREPN {
-				inst.Prefix[i] = x86_PrefixBND
-				break
-			}
-		}
-	}
-
-	// The LOCK prefix only applies to certain instructions, and then only
-	// to instances of the instruction with a memory destination.
-	// Other uses of LOCK are invalid and cause a processor exception,
-	// in contrast to the "just ignore it" spirit applied to all other prefixes.
-	// Mark invalid lock prefixes.
-	hasLock := false
-	if lockIndex >= 0 && inst.Prefix[lockIndex]&x86_PrefixImplicit == 0 {
-		switch inst.Op {
-		// TODO(rsc): Perhaps this instruction class should be derived from the CSV.
-		case x86_ADD, x86_ADC, x86_AND, x86_BTC, x86_BTR, x86_BTS, x86_CMPXCHG, x86_CMPXCHG8B, x86_CMPXCHG16B, x86_DEC, x86_INC, x86_NEG, x86_NOT, x86_OR, x86_SBB, x86_SUB, x86_XOR, x86_XADD, x86_XCHG:
-			if x86_isMem(inst.Args[0]) {
-				hasLock = true
-				break
-			}
-			fallthrough
-		default:
-			inst.Prefix[lockIndex] |= x86_PrefixInvalid
-		}
-	}
-
-	// In certain cases, all of which require a memory destination,
-	// the REPN and REP prefixes are interpreted as XACQUIRE and XRELEASE
-	// from the Intel Transactional Synchroniation Extensions (TSX).
-	//
-	// The specific rules are:
-	// (1) Any instruction with a valid LOCK prefix can have XACQUIRE or XRELEASE.
-	// (2) Any XCHG, which always has an implicit LOCK, can have XACQUIRE or XRELEASE.
-	// (3) Any 0x88-, 0x89-, 0xC6-, or 0xC7-opcode MOV can have XRELEASE.
-	if x86_isMem(inst.Args[0]) {
-		if inst.Op == x86_XCHG {
-			hasLock = true
-		}
-
-		for i := len(inst.Prefix) - 1; i >= 0; i-- {
-			p := inst.Prefix[i] &^ x86_PrefixIgnored
-			switch p {
-			case x86_PrefixREPN:
-				if hasLock {
-					inst.Prefix[i] = inst.Prefix[i]&x86_PrefixIgnored | x86_PrefixXACQUIRE
-				}
-
-			case x86_PrefixREP:
-				if hasLock {
-					inst.Prefix[i] = inst.Prefix[i]&x86_PrefixIgnored | x86_PrefixXRELEASE
-				}
-
-				if inst.Op == x86_MOV {
-					op := (inst.Opcode >> 24) &^ 1
-					if op == 0x88 || op == 0xC6 {
-						inst.Prefix[i] = inst.Prefix[i]&x86_PrefixIgnored | x86_PrefixXRELEASE
-					}
-				}
-			}
-		}
-	}
-
-	// If REP is used on a non-REP-able instruction, mark the prefix as ignored.
-	if repIndex >= 0 {
-		switch inst.Prefix[repIndex] {
-		case x86_PrefixREP, x86_PrefixREPN:
-			switch inst.Op {
-			// According to the manuals, the REP/REPE prefix applies to all of these,
-			// while the REPN applies only to some of them. However, both libopcodes
-			// and xed show both prefixes explicitly for all instructions, so we do the same.
-			// TODO(rsc): Perhaps this instruction class should be derived from the CSV.
-			case x86_INSB, x86_INSW, x86_INSD,
-				x86_MOVSB, x86_MOVSW, x86_MOVSD, x86_MOVSQ,
-				x86_OUTSB, x86_OUTSW, x86_OUTSD,
-				x86_LODSB, x86_LODSW, x86_LODSD, x86_LODSQ,
-				x86_CMPSB, x86_CMPSW, x86_CMPSD, x86_CMPSQ,
-				x86_SCASB, x86_SCASW, x86_SCASD, x86_SCASQ,
-				x86_STOSB, x86_STOSW, x86_STOSD, x86_STOSQ:
-				// ok
-			default:
-				inst.Prefix[repIndex] |= x86_PrefixIgnored
-			}
-		}
-	}
-
-	// If REX was present, mark implicit if all the 1 bits were consumed.
-	if rexIndex >= 0 {
-		if rexUsed != 0 {
-			rexUsed |= x86_PrefixREX
-		}
-		if rex&^rexUsed == 0 {
-			inst.Prefix[rexIndex] |= x86_PrefixImplicit
-		}
-	}
-
-	inst.DataSize = dataMode
-	inst.AddrSize = addrMode
-	inst.Mode = mode
-	inst.Len = pos
-	return inst, nil
-}
-
-var x86_errInternal = errors.New("internal error")
-
-// addr16 records the eight 16-bit addressing modes.
-var x86_addr16 = [8]x86_Mem{
-	{Base: x86_BX, Scale: 1, Index: x86_SI},
-	{Base: x86_BX, Scale: 1, Index: x86_DI},
-	{Base: x86_BP, Scale: 1, Index: x86_SI},
-	{Base: x86_BP, Scale: 1, Index: x86_DI},
-	{Base: x86_SI},
-	{Base: x86_DI},
-	{Base: x86_BP},
-	{Base: x86_BX},
-}
-
-// baseReg returns the base register for a given register size in bits.
-func x86_baseRegForBits(bits int) x86_Reg {
-	switch bits {
-	case 8:
-		return x86_AL
-	case 16:
-		return x86_AX
-	case 32:
-		return x86_EAX
-	case 64:
-		return x86_RAX
-	}
-	return 0
-}
-
-// baseReg records the base register for argument types that specify
-// a range of registers indexed by op, regop, or rm.
-var x86_baseReg = [...]x86_Reg{
-	x86_xArgDR0dashDR7: x86_DR0,
-	x86_xArgMm1:        x86_M0,
-	x86_xArgMm2:        x86_M0,
-	x86_xArgMm2M64:     x86_M0,
-	x86_xArgMm:         x86_M0,
-	x86_xArgMmM32:      x86_M0,
-	x86_xArgMmM64:      x86_M0,
-	x86_xArgR16:        x86_AX,
-	x86_xArgR16op:      x86_AX,
-	x86_xArgR32:        x86_EAX,
-	x86_xArgR32M16:     x86_EAX,
-	x86_xArgR32M8:      x86_EAX,
-	x86_xArgR32op:      x86_EAX,
-	x86_xArgR64:        x86_RAX,
-	x86_xArgR64M16:     x86_RAX,
-	x86_xArgR64op:      x86_RAX,
-	x86_xArgR8:         x86_AL,
-	x86_xArgR8op:       x86_AL,
-	x86_xArgRM16:       x86_AX,
-	x86_xArgRM32:       x86_EAX,
-	x86_xArgRM64:       x86_RAX,
-	x86_xArgRM8:        x86_AL,
-	x86_xArgRmf16:      x86_AX,
-	x86_xArgRmf32:      x86_EAX,
-	x86_xArgRmf64:      x86_RAX,
-	x86_xArgSTi:        x86_F0,
-	x86_xArgTR0dashTR7: x86_TR0,
-	x86_xArgXmm1:       x86_X0,
-	x86_xArgXmm2:       x86_X0,
-	x86_xArgXmm2M128:   x86_X0,
-	x86_xArgXmm2M16:    x86_X0,
-	x86_xArgXmm2M32:    x86_X0,
-	x86_xArgXmm2M64:    x86_X0,
-	x86_xArgXmm:        x86_X0,
-	x86_xArgXmmM128:    x86_X0,
-	x86_xArgXmmM32:     x86_X0,
-	x86_xArgXmmM64:     x86_X0,
-}
-
-// prefixToSegment returns the segment register
-// corresponding to a particular segment prefix.
-func x86_prefixToSegment(p x86_Prefix) x86_Reg {
-	switch p &^ x86_PrefixImplicit {
-	case x86_PrefixCS:
-		return x86_CS
-	case x86_PrefixDS:
-		return x86_DS
-	case x86_PrefixES:
-		return x86_ES
-	case x86_PrefixFS:
-		return x86_FS
-	case x86_PrefixGS:
-		return x86_GS
-	case x86_PrefixSS:
-		return x86_SS
-	}
-	return 0
-}
-
-// fixedArg records the fixed arguments corresponding to the given bytecodes.
-var x86_fixedArg = [...]x86_Arg{
-	x86_xArg1:    x86_Imm(1),
-	x86_xArg3:    x86_Imm(3),
-	x86_xArgAL:   x86_AL,
-	x86_xArgAX:   x86_AX,
-	x86_xArgDX:   x86_DX,
-	x86_xArgEAX:  x86_EAX,
-	x86_xArgEDX:  x86_EDX,
-	x86_xArgRAX:  x86_RAX,
-	x86_xArgRDX:  x86_RDX,
-	x86_xArgCL:   x86_CL,
-	x86_xArgCS:   x86_CS,
-	x86_xArgDS:   x86_DS,
-	x86_xArgES:   x86_ES,
-	x86_xArgFS:   x86_FS,
-	x86_xArgGS:   x86_GS,
-	x86_xArgSS:   x86_SS,
-	x86_xArgST:   x86_F0,
-	x86_xArgXMM0: x86_X0,
-}
-
-// memBytes records the size of the memory pointed at
-// by a memory argument of the given form.
-var x86_memBytes = [...]int8{
-	x86_xArgM128:       128 / 8,
-	x86_xArgM16:        16 / 8,
-	x86_xArgM16and16:   (16 + 16) / 8,
-	x86_xArgM16colon16: (16 + 16) / 8,
-	x86_xArgM16colon32: (16 + 32) / 8,
-	x86_xArgM16int:     16 / 8,
-	x86_xArgM2byte:     2,
-	x86_xArgM32:        32 / 8,
-	x86_xArgM32and32:   (32 + 32) / 8,
-	x86_xArgM32fp:      32 / 8,
-	x86_xArgM32int:     32 / 8,
-	x86_xArgM64:        64 / 8,
-	x86_xArgM64fp:      64 / 8,
-	x86_xArgM64int:     64 / 8,
-	x86_xArgMm2M64:     64 / 8,
-	x86_xArgMmM32:      32 / 8,
-	x86_xArgMmM64:      64 / 8,
-	x86_xArgMoffs16:    16 / 8,
-	x86_xArgMoffs32:    32 / 8,
-	x86_xArgMoffs64:    64 / 8,
-	x86_xArgMoffs8:     8 / 8,
-	x86_xArgR32M16:     16 / 8,
-	x86_xArgR32M8:      8 / 8,
-	x86_xArgR64M16:     16 / 8,
-	x86_xArgRM16:       16 / 8,
-	x86_xArgRM32:       32 / 8,
-	x86_xArgRM64:       64 / 8,
-	x86_xArgRM8:        8 / 8,
-	x86_xArgXmm2M128:   128 / 8,
-	x86_xArgXmm2M16:    16 / 8,
-	x86_xArgXmm2M32:    32 / 8,
-	x86_xArgXmm2M64:    64 / 8,
-	x86_xArgXmm:        128 / 8,
-	x86_xArgXmmM128:    128 / 8,
-	x86_xArgXmmM32:     32 / 8,
-	x86_xArgXmmM64:     64 / 8,
-}
-
-// isCondJmp records the conditional jumps.
-var x86_isCondJmp = [x86_maxOp + 1]bool{
-	x86_JA:  true,
-	x86_JAE: true,
-	x86_JB:  true,
-	x86_JBE: true,
-	x86_JE:  true,
-	x86_JG:  true,
-	x86_JGE: true,
-	x86_JL:  true,
-	x86_JLE: true,
-	x86_JNE: true,
-	x86_JNO: true,
-	x86_JNP: true,
-	x86_JNS: true,
-	x86_JO:  true,
-	x86_JP:  true,
-	x86_JS:  true,
-}
-
-// isLoop records the loop operators.
-var x86_isLoop = [x86_maxOp + 1]bool{
-	x86_LOOP:   true,
-	x86_LOOPE:  true,
-	x86_LOOPNE: true,
-	x86_JECXZ:  true,
-	x86_JRCXZ:  true,
-}
-
-/* gnu.go */
-
-// 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.
-
-// GNUSyntax returns the GNU assembler syntax for the instruction, as defined by GNU binutils.
-// This general form is often called ``AT&T syntax'' as a reference to AT&T System V Unix.
-func x86_GNUSyntax(inst x86_Inst) string {
-	// Rewrite instruction to mimic GNU peculiarities.
-	// Note that inst has been passed by value and contains
-	// no pointers, so any changes we make here are local
-	// and will not propagate back out to the caller.
-
-	// Adjust opcode [sic].
-	switch inst.Op {
-	case x86_FDIV, x86_FDIVR, x86_FSUB, x86_FSUBR, x86_FDIVP, x86_FDIVRP, x86_FSUBP, x86_FSUBRP:
-		// DC E0, DC F0: libopcodes swaps FSUBR/FSUB and FDIVR/FDIV, at least
-		// if you believe the Intel manual is correct (the encoding is irregular as given;
-		// libopcodes uses the more regular expected encoding).
-		// TODO(rsc): Test to ensure Intel manuals are correct and report to libopcodes maintainers?
-		// NOTE: iant thinks this is deliberate, but we can't find the history.
-		_, reg1 := inst.Args[0].(x86_Reg)
-		_, reg2 := inst.Args[1].(x86_Reg)
-		if reg1 && reg2 && (inst.Opcode>>24 == 0xDC || inst.Opcode>>24 == 0xDE) {
-			switch inst.Op {
-			case x86_FDIV:
-				inst.Op = x86_FDIVR
-			case x86_FDIVR:
-				inst.Op = x86_FDIV
-			case x86_FSUB:
-				inst.Op = x86_FSUBR
-			case x86_FSUBR:
-				inst.Op = x86_FSUB
-			case x86_FDIVP:
-				inst.Op = x86_FDIVRP
-			case x86_FDIVRP:
-				inst.Op = x86_FDIVP
-			case x86_FSUBP:
-				inst.Op = x86_FSUBRP
-			case x86_FSUBRP:
-				inst.Op = x86_FSUBP
-			}
-		}
-
-	case x86_MOVNTSD:
-		// MOVNTSD is F2 0F 2B /r.
-		// MOVNTSS is F3 0F 2B /r (supposedly; not in manuals).
-		// Usually inner prefixes win for display,
-		// so that F3 F2 0F 2B 11 is REP MOVNTSD
-		// and F2 F3 0F 2B 11 is REPN MOVNTSS.
-		// Libopcodes always prefers MOVNTSS regardless of prefix order.
-		if x86_countPrefix(&inst, 0xF3) > 0 {
-			found := false
-			for i := len(inst.Prefix) - 1; i >= 0; i-- {
-				switch inst.Prefix[i] & 0xFF {
-				case 0xF3:
-					if !found {
-						found = true
-						inst.Prefix[i] |= x86_PrefixImplicit
-					}
-				case 0xF2:
-					inst.Prefix[i] &^= x86_PrefixImplicit
-				}
-			}
-			inst.Op = x86_MOVNTSS
-		}
-	}
-
-	// Add implicit arguments.
-	switch inst.Op {
-	case x86_MONITOR:
-		inst.Args[0] = x86_EDX
-		inst.Args[1] = x86_ECX
-		inst.Args[2] = x86_EAX
-		if inst.AddrSize == 16 {
-			inst.Args[2] = x86_AX
-		}
-
-	case x86_MWAIT:
-		if inst.Mode == 64 {
-			inst.Args[0] = x86_RCX
-			inst.Args[1] = x86_RAX
-		} else {
-			inst.Args[0] = x86_ECX
-			inst.Args[1] = x86_EAX
-		}
-	}
-
-	// Adjust which prefixes will be displayed.
-	// The rule is to display all the prefixes not implied by
-	// the usual instruction display, that is, all the prefixes
-	// except the ones with PrefixImplicit set.
-	// However, of course, there are exceptions to the rule.
-	switch inst.Op {
-	case x86_CRC32:
-		// CRC32 has a mandatory F2 prefix.
-		// If there are multiple F2s and no F3s, the extra F2s do not print.
-		// (And Decode has already marked them implicit.)
-		// However, if there is an F3 anywhere, then the extra F2s do print.
-		// If there are multiple F2 prefixes *and* an (ignored) F3,
-		// then libopcodes prints the extra F2s as REPNs.
-		if x86_countPrefix(&inst, 0xF2) > 1 {
-			x86_unmarkImplicit(&inst, 0xF2)
-			x86_markLastImplicit(&inst, 0xF2)
-		}
-
-		// An unused data size override should probably be shown,
-		// to distinguish DATA16 CRC32B from plain CRC32B,
-		// but libopcodes always treats the final override as implicit
-		// and the others as explicit.
-		x86_unmarkImplicit(&inst, x86_PrefixDataSize)
-		x86_markLastImplicit(&inst, x86_PrefixDataSize)
-
-	case x86_CVTSI2SD, x86_CVTSI2SS:
-		if !x86_isMem(inst.Args[1]) {
-			x86_markLastImplicit(&inst, x86_PrefixDataSize)
-		}
-
-	case x86_CVTSD2SI, x86_CVTSS2SI, x86_CVTTSD2SI, x86_CVTTSS2SI,
-		x86_ENTER, x86_FLDENV, x86_FNSAVE, x86_FNSTENV, x86_FRSTOR, x86_LGDT, x86_LIDT, x86_LRET,
-		x86_POP, x86_PUSH, x86_RET, x86_SGDT, x86_SIDT, x86_SYSRET, x86_XBEGIN:
-		x86_markLastImplicit(&inst, x86_PrefixDataSize)
-
-	case x86_LOOP, x86_LOOPE, x86_LOOPNE, x86_MONITOR:
-		x86_markLastImplicit(&inst, x86_PrefixAddrSize)
-
-	case x86_MOV:
-		// The 16-bit and 32-bit forms of MOV Sreg, dst and MOV src, Sreg
-		// cannot be distinguished when src or dst refers to memory, because
-		// Sreg is always a 16-bit value, even when we're doing a 32-bit
-		// instruction. Because the instruction tables distinguished these two,
-		// any operand size prefix has been marked as used (to decide which
-		// branch to take). Unmark it, so that it will show up in disassembly,
-		// so that the reader can tell the size of memory operand.
-		// up with the same arguments
-		dst, _ := inst.Args[0].(x86_Reg)
-		src, _ := inst.Args[1].(x86_Reg)
-		if x86_ES <= src && src <= x86_GS && x86_isMem(inst.Args[0]) || x86_ES <= dst && dst <= x86_GS && x86_isMem(inst.Args[1]) {
-			x86_unmarkImplicit(&inst, x86_PrefixDataSize)
-		}
-
-	case x86_MOVDQU:
-		if x86_countPrefix(&inst, 0xF3) > 1 {
-			x86_unmarkImplicit(&inst, 0xF3)
-			x86_markLastImplicit(&inst, 0xF3)
-		}
-
-	case x86_MOVQ2DQ:
-		x86_markLastImplicit(&inst, x86_PrefixDataSize)
-
-	case x86_SLDT, x86_SMSW, x86_STR, x86_FXRSTOR, x86_XRSTOR, x86_XSAVE, x86_XSAVEOPT, x86_CMPXCHG8B:
-		if x86_isMem(inst.Args[0]) {
-			x86_unmarkImplicit(&inst, x86_PrefixDataSize)
-		}
-
-	case x86_SYSEXIT:
-		x86_unmarkImplicit(&inst, x86_PrefixDataSize)
-	}
-
-	if x86_isCondJmp[inst.Op] || x86_isLoop[inst.Op] || inst.Op == x86_JCXZ || inst.Op == x86_JECXZ || inst.Op == x86_JRCXZ {
-		if x86_countPrefix(&inst, x86_PrefixCS) > 0 && x86_countPrefix(&inst, x86_PrefixDS) > 0 {
-			for i, p := range inst.Prefix {
-				switch p & 0xFFF {
-				case x86_PrefixPN, x86_PrefixPT:
-					inst.Prefix[i] &= 0xF0FF // cut interpretation bits, producing original segment prefix
-				}
-			}
-		}
-	}
-
-	// XACQUIRE/XRELEASE adjustment.
-	if inst.Op == x86_MOV {
-		// MOV into memory is a candidate for turning REP into XRELEASE.
-		// However, if the REP is followed by a REPN, that REPN blocks the
-		// conversion.
-		haveREPN := false
-		for i := len(inst.Prefix) - 1; i >= 0; i-- {
-			switch inst.Prefix[i] &^ x86_PrefixIgnored {
-			case x86_PrefixREPN:
-				haveREPN = true
-			case x86_PrefixXRELEASE:
-				if haveREPN {
-					inst.Prefix[i] = x86_PrefixREP
-				}
-			}
-		}
-	}
-
-	// We only format the final F2/F3 as XRELEASE/XACQUIRE.
-	haveXA := false
-	haveXR := false
-	for i := len(inst.Prefix) - 1; i >= 0; i-- {
-		switch inst.Prefix[i] &^ x86_PrefixIgnored {
-		case x86_PrefixXRELEASE:
-			if !haveXR {
-				haveXR = true
-			} else {
-				inst.Prefix[i] = x86_PrefixREP
-			}
-
-		case x86_PrefixXACQUIRE:
-			if !haveXA {
-				haveXA = true
-			} else {
-				inst.Prefix[i] = x86_PrefixREPN
-			}
-		}
-	}
-
-	// Determine opcode.
-	op := strings.ToLower(inst.Op.String())
-	if alt := x86_gnuOp[inst.Op]; alt != "" {
-		op = alt
-	}
-
-	// Determine opcode suffix.
-	// Libopcodes omits the suffix if the width of the operation
-	// can be inferred from a register arguments. For example,
-	// add $1, %ebx has no suffix because you can tell from the
-	// 32-bit register destination that it is a 32-bit add,
-	// but in addl $1, (%ebx), the destination is memory, so the
-	// size is not evident without the l suffix.
-	needSuffix := true
-SuffixLoop:
-	for i, a := range inst.Args {
-		if a == nil {
-			break
-		}
-		switch a := a.(type) {
-		case x86_Reg:
-			switch inst.Op {
-			case x86_MOVSX, x86_MOVZX:
-				continue
-
-			case x86_SHL, x86_SHR, x86_RCL, x86_RCR, x86_ROL, x86_ROR, x86_SAR:
-				if i == 1 {
-					// shift count does not tell us operand size
-					continue
-				}
-
-			case x86_CRC32:
-				// The source argument does tell us operand size,
-				// but libopcodes still always puts a suffix on crc32.
-				continue
-
-			case x86_PUSH, x86_POP:
-				// Even though segment registers are 16-bit, push and pop
-				// can save/restore them from 32-bit slots, so they
-				// do not imply operand size.
-				if x86_ES <= a && a <= x86_GS {
-					continue
-				}
-
-			case x86_CVTSI2SD, x86_CVTSI2SS:
-				// The integer register argument takes priority.
-				if x86_X0 <= a && a <= x86_X15 {
-					continue
-				}
-			}
-
-			if x86_AL <= a && a <= x86_R15 || x86_ES <= a && a <= x86_GS || x86_X0 <= a && a <= x86_X15 || x86_M0 <= a && a <= x86_M7 {
-				needSuffix = false
-				break SuffixLoop
-			}
-		}
-	}
-
-	if needSuffix {
-		switch inst.Op {
-		case x86_CMPXCHG8B, x86_FLDCW, x86_FNSTCW, x86_FNSTSW, x86_LDMXCSR, x86_LLDT, x86_LMSW, x86_LTR, x86_PCLMULQDQ,
-			x86_SETA, x86_SETAE, x86_SETB, x86_SETBE, x86_SETE, x86_SETG, x86_SETGE, x86_SETL, x86_SETLE, x86_SETNE, x86_SETNO, x86_SETNP, x86_SETNS, x86_SETO, x86_SETP, x86_SETS,
-			x86_SLDT, x86_SMSW, x86_STMXCSR, x86_STR, x86_VERR, x86_VERW:
-			// For various reasons, libopcodes emits no suffix for these instructions.
-
-		case x86_CRC32:
-			op += x86_byteSizeSuffix(x86_argBytes(&inst, inst.Args[1]))
-
-		case x86_LGDT, x86_LIDT, x86_SGDT, x86_SIDT:
-			op += x86_byteSizeSuffix(inst.DataSize / 8)
-
-		case x86_MOVZX, x86_MOVSX:
-			// Integer size conversions get two suffixes.
-			op = op[:4] + x86_byteSizeSuffix(x86_argBytes(&inst, inst.Args[1])) + x86_byteSizeSuffix(x86_argBytes(&inst, inst.Args[0]))
-
-		case x86_LOOP, x86_LOOPE, x86_LOOPNE:
-			// Add w suffix to indicate use of CX register instead of ECX.
-			if inst.AddrSize == 16 {
-				op += "w"
-			}
-
-		case x86_CALL, x86_ENTER, x86_JMP, x86_LCALL, x86_LEAVE, x86_LJMP, x86_LRET, x86_RET, x86_SYSRET, x86_XBEGIN:
-			// Add w suffix to indicate use of 16-bit target.
-			// Exclude JMP rel8.
-			if inst.Opcode>>24 == 0xEB {
-				break
-			}
-			if inst.DataSize == 16 && inst.Mode != 16 {
-				x86_markLastImplicit(&inst, x86_PrefixDataSize)
-				op += "w"
-			} else if inst.Mode == 64 {
-				op += "q"
-			}
-
-		case x86_FRSTOR, x86_FNSAVE, x86_FNSTENV, x86_FLDENV:
-			// Add s suffix to indicate shortened FPU state (I guess).
-			if inst.DataSize == 16 {
-				op += "s"
-			}
-
-		case x86_PUSH, x86_POP:
-			if x86_markLastImplicit(&inst, x86_PrefixDataSize) {
-				op += x86_byteSizeSuffix(inst.DataSize / 8)
-			} else if inst.Mode == 64 {
-				op += "q"
-			} else {
-				op += x86_byteSizeSuffix(inst.MemBytes)
-			}
-
-		default:
-			if x86_isFloat(inst.Op) {
-				// I can't explain any of this, but it's what libopcodes does.
-				switch inst.MemBytes {
-				default:
-					if (inst.Op == x86_FLD || inst.Op == x86_FSTP) && x86_isMem(inst.Args[0]) {
-						op += "t"
-					}
-				case 4:
-					if x86_isFloatInt(inst.Op) {
-						op += "l"
-					} else {
-						op += "s"
-					}
-				case 8:
-					if x86_isFloatInt(inst.Op) {
-						op += "ll"
-					} else {
-						op += "l"
-					}
-				}
-				break
-			}
-
-			op += x86_byteSizeSuffix(inst.MemBytes)
-		}
-	}
-
-	// Adjust special case opcodes.
-	switch inst.Op {
-	case 0:
-		if inst.Prefix[0] != 0 {
-			return strings.ToLower(inst.Prefix[0].String())
-		}
-
-	case x86_INT:
-		if inst.Opcode>>24 == 0xCC {
-			inst.Args[0] = nil
-			op = "int3"
-		}
-
-	case x86_CMPPS, x86_CMPPD, x86_CMPSD_XMM, x86_CMPSS:
-		imm, ok := inst.Args[2].(x86_Imm)
-		if ok && 0 <= imm && imm < 8 {
-			inst.Args[2] = nil
-			op = x86_cmppsOps[imm] + op[3:]
-		}
-
-	case x86_PCLMULQDQ:
-		imm, ok := inst.Args[2].(x86_Imm)
-		if ok && imm&^0x11 == 0 {
-			inst.Args[2] = nil
-			op = x86_pclmulqOps[(imm&0x10)>>3|(imm&1)]
-		}
-
-	case x86_XLATB:
-		if x86_markLastImplicit(&inst, x86_PrefixAddrSize) {
-			op = "xlat" // not xlatb
-		}
-	}
-
-	// Build list of argument strings.
-	var (
-		usedPrefixes bool     // segment prefixes consumed by Mem formatting
-		args         []string // formatted arguments
-	)
-	for i, a := range inst.Args {
-		if a == nil {
-			break
-		}
-		switch inst.Op {
-		case x86_MOVSB, x86_MOVSW, x86_MOVSD, x86_MOVSQ, x86_OUTSB, x86_OUTSW, x86_OUTSD:
-			if i == 0 {
-				usedPrefixes = true // disable use of prefixes for first argument
-			} else {
-				usedPrefixes = false
-			}
-		}
-		if a == x86_Imm(1) && (inst.Opcode>>24)&^1 == 0xD0 {
-			continue
-		}
-		args = append(args, x86_gnuArg(&inst, a, &usedPrefixes))
-	}
-
-	// The default is to print the arguments in reverse Intel order.
-	// A few instructions inhibit this behavior.
-	switch inst.Op {
-	case x86_BOUND, x86_LCALL, x86_ENTER, x86_LJMP:
-		// no reverse
-	default:
-		// reverse args
-		for i, j := 0, len(args)-1; i < j; i, j = i+1, j-1 {
-			args[i], args[j] = args[j], args[i]
-		}
-	}
-
-	// Build prefix string.
-	// Must be after argument formatting, which can turn off segment prefixes.
-	var (
-		prefix       = "" // output string
-		numAddr      = 0
-		numData      = 0
-		implicitData = false
-	)
-	for _, p := range inst.Prefix {
-		if p&0xFF == x86_PrefixDataSize && p&x86_PrefixImplicit != 0 {
-			implicitData = true
-		}
-	}
-	for _, p := range inst.Prefix {
-		if p == 0 {
-			break
-		}
-		if p&x86_PrefixImplicit != 0 {
-			continue
-		}
-		switch p &^ (x86_PrefixIgnored | x86_PrefixInvalid) {
-		default:
-			if p.IsREX() {
-				if p&0xFF == x86_PrefixREX {
-					prefix += "rex "
-				} else {
-					prefix += "rex." + p.String()[4:] + " "
-				}
-				break
-			}
-			prefix += strings.ToLower(p.String()) + " "
-
-		case x86_PrefixPN:
-			op += ",pn"
-			continue
-
-		case x86_PrefixPT:
-			op += ",pt"
-			continue
-
-		case x86_PrefixAddrSize, x86_PrefixAddr16, x86_PrefixAddr32:
-			// For unknown reasons, if the addr16 prefix is repeated,
-			// libopcodes displays all but the last as addr32, even though
-			// the addressing form used in a memory reference is clearly
-			// still 16-bit.
-			n := 32
-			if inst.Mode == 32 {
-				n = 16
-			}
-			numAddr++
-			if x86_countPrefix(&inst, x86_PrefixAddrSize) > numAddr {
-				n = inst.Mode
-			}
-			prefix += fmt.Sprintf("addr%d ", n)
-			continue
-
-		case x86_PrefixData16, x86_PrefixData32:
-			if implicitData && x86_countPrefix(&inst, x86_PrefixDataSize) > 1 {
-				// Similar to the addr32 logic above, but it only kicks in
-				// when something used the data size prefix (one is implicit).
-				n := 16
-				if inst.Mode == 16 {
-					n = 32
-				}
-				numData++
-				if x86_countPrefix(&inst, x86_PrefixDataSize) > numData {
-					if inst.Mode == 16 {
-						n = 16
-					} else {
-						n = 32
-					}
-				}
-				prefix += fmt.Sprintf("data%d ", n)
-				continue
-			}
-			prefix += strings.ToLower(p.String()) + " "
-		}
-	}
-
-	// Finally! Put it all together.
-	text := prefix + op
-	if args != nil {
-		text += " "
-		// Indirect call/jmp gets a star to distinguish from direct jump address.
-		if (inst.Op == x86_CALL || inst.Op == x86_JMP || inst.Op == x86_LJMP || inst.Op == x86_LCALL) && (x86_isMem(inst.Args[0]) || x86_isReg(inst.Args[0])) {
-			text += "*"
-		}
-		text += strings.Join(args, ",")
-	}
-	return text
-}
-
-// gnuArg returns the GNU syntax for the argument x from the instruction inst.
-// If *usedPrefixes is false and x is a Mem, then the formatting
-// includes any segment prefixes and sets *usedPrefixes to true.
-func x86_gnuArg(inst *x86_Inst, x x86_Arg, usedPrefixes *bool) string {
-	if x == nil {
-		return "<nil>"
-	}
-	switch x := x.(type) {
-	case x86_Reg:
-		switch inst.Op {
-		case x86_CVTSI2SS, x86_CVTSI2SD, x86_CVTSS2SI, x86_CVTSD2SI, x86_CVTTSD2SI, x86_CVTTSS2SI:
-			if inst.DataSize == 16 && x86_EAX <= x && x <= x86_R15L {
-				x -= x86_EAX - x86_AX
-			}
-
-		case x86_IN, x86_INSB, x86_INSW, x86_INSD, x86_OUT, x86_OUTSB, x86_OUTSW, x86_OUTSD:
-			// DX is the port, but libopcodes prints it as if it were a memory reference.
-			if x == x86_DX {
-				return "(%dx)"
-			}
-		}
-		return x86_gccRegName[x]
-	case x86_Mem:
-		seg := ""
-		var haveCS, haveDS, haveES, haveFS, haveGS, haveSS bool
-		switch x.Segment {
-		case x86_CS:
-			haveCS = true
-		case x86_DS:
-			haveDS = true
-		case x86_ES:
-			haveES = true
-		case x86_FS:
-			haveFS = true
-		case x86_GS:
-			haveGS = true
-		case x86_SS:
-			haveSS = true
-		}
-		switch inst.Op {
-		case x86_INSB, x86_INSW, x86_INSD, x86_STOSB, x86_STOSW, x86_STOSD, x86_STOSQ, x86_SCASB, x86_SCASW, x86_SCASD, x86_SCASQ:
-			// These do not accept segment prefixes, at least in the GNU rendering.
-		default:
-			if *usedPrefixes {
-				break
-			}
-			for i := len(inst.Prefix) - 1; i >= 0; i-- {
-				p := inst.Prefix[i] &^ x86_PrefixIgnored
-				if p == 0 {
-					continue
-				}
-				switch p {
-				case x86_PrefixCS:
-					if !haveCS {
-						haveCS = true
-						inst.Prefix[i] |= x86_PrefixImplicit
-					}
-				case x86_PrefixDS:
-					if !haveDS {
-						haveDS = true
-						inst.Prefix[i] |= x86_PrefixImplicit
-					}
-				case x86_PrefixES:
-					if !haveES {
-						haveES = true
-						inst.Prefix[i] |= x86_PrefixImplicit
-					}
-				case x86_PrefixFS:
-					if !haveFS {
-						haveFS = true
-						inst.Prefix[i] |= x86_PrefixImplicit
-					}
-				case x86_PrefixGS:
-					if !haveGS {
-						haveGS = true
-						inst.Prefix[i] |= x86_PrefixImplicit
-					}
-				case x86_PrefixSS:
-					if !haveSS {
-						haveSS = true
-						inst.Prefix[i] |= x86_PrefixImplicit
-					}
-				}
-			}
-			*usedPrefixes = true
-		}
-		if haveCS {
-			seg += "%cs:"
-		}
-		if haveDS {
-			seg += "%ds:"
-		}
-		if haveSS {
-			seg += "%ss:"
-		}
-		if haveES {
-			seg += "%es:"
-		}
-		if haveFS {
-			seg += "%fs:"
-		}
-		if haveGS {
-			seg += "%gs:"
-		}
-		disp := ""
-		if x.Disp != 0 {
-			disp = fmt.Sprintf("%#x", x.Disp)
-		}
-		if x.Scale == 0 || x.Index == 0 && x.Scale == 1 && (x.Base == x86_ESP || x.Base == x86_RSP || x.Base == 0 && inst.Mode == 64) {
-			if x.Base == 0 {
-				return seg + disp
-			}
-			return fmt.Sprintf("%s%s(%s)", seg, disp, x86_gccRegName[x.Base])
-		}
-		base := x86_gccRegName[x.Base]
-		if x.Base == 0 {
-			base = ""
-		}
-		index := x86_gccRegName[x.Index]
-		if x.Index == 0 {
-			if inst.AddrSize == 64 {
-				index = "%riz"
-			} else {
-				index = "%eiz"
-			}
-		}
-		if x86_AX <= x.Base && x.Base <= x86_DI {
-			// 16-bit addressing - no scale
-			return fmt.Sprintf("%s%s(%s,%s)", seg, disp, base, index)
-		}
-		return fmt.Sprintf("%s%s(%s,%s,%d)", seg, disp, base, index, x.Scale)
-	case x86_Rel:
-		return fmt.Sprintf(".%+#x", int32(x))
-	case x86_Imm:
-		if inst.Mode == 32 {
-			return fmt.Sprintf("$%#x", uint32(x))
-		}
-		return fmt.Sprintf("$%#x", int64(x))
-	}
-	return x.String()
-}
-
-var x86_gccRegName = [...]string{
-	0:        "REG0",
-	x86_AL:   "%al",
-	x86_CL:   "%cl",
-	x86_BL:   "%bl",
-	x86_DL:   "%dl",
-	x86_AH:   "%ah",
-	x86_CH:   "%ch",
-	x86_BH:   "%bh",
-	x86_DH:   "%dh",
-	x86_SPB:  "%spl",
-	x86_BPB:  "%bpl",
-	x86_SIB:  "%sil",
-	x86_DIB:  "%dil",
-	x86_R8B:  "%r8b",
-	x86_R9B:  "%r9b",
-	x86_R10B: "%r10b",
-	x86_R11B: "%r11b",
-	x86_R12B: "%r12b",
-	x86_R13B: "%r13b",
-	x86_R14B: "%r14b",
-	x86_R15B: "%r15b",
-	x86_AX:   "%ax",
-	x86_CX:   "%cx",
-	x86_BX:   "%bx",
-	x86_DX:   "%dx",
-	x86_SP:   "%sp",
-	x86_BP:   "%bp",
-	x86_SI:   "%si",
-	x86_DI:   "%di",
-	x86_R8W:  "%r8w",
-	x86_R9W:  "%r9w",
-	x86_R10W: "%r10w",
-	x86_R11W: "%r11w",
-	x86_R12W: "%r12w",
-	x86_R13W: "%r13w",
-	x86_R14W: "%r14w",
-	x86_R15W: "%r15w",
-	x86_EAX:  "%eax",
-	x86_ECX:  "%ecx",
-	x86_EDX:  "%edx",
-	x86_EBX:  "%ebx",
-	x86_ESP:  "%esp",
-	x86_EBP:  "%ebp",
-	x86_ESI:  "%esi",
-	x86_EDI:  "%edi",
-	x86_R8L:  "%r8d",
-	x86_R9L:  "%r9d",
-	x86_R10L: "%r10d",
-	x86_R11L: "%r11d",
-	x86_R12L: "%r12d",
-	x86_R13L: "%r13d",
-	x86_R14L: "%r14d",
-	x86_R15L: "%r15d",
-	x86_RAX:  "%rax",
-	x86_RCX:  "%rcx",
-	x86_RDX:  "%rdx",
-	x86_RBX:  "%rbx",
-	x86_RSP:  "%rsp",
-	x86_RBP:  "%rbp",
-	x86_RSI:  "%rsi",
-	x86_RDI:  "%rdi",
-	x86_R8:   "%r8",
-	x86_R9:   "%r9",
-	x86_R10:  "%r10",
-	x86_R11:  "%r11",
-	x86_R12:  "%r12",
-	x86_R13:  "%r13",
-	x86_R14:  "%r14",
-	x86_R15:  "%r15",
-	x86_IP:   "%ip",
-	x86_EIP:  "%eip",
-	x86_RIP:  "%rip",
-	x86_F0:   "%st",
-	x86_F1:   "%st(1)",
-	x86_F2:   "%st(2)",
-	x86_F3:   "%st(3)",
-	x86_F4:   "%st(4)",
-	x86_F5:   "%st(5)",
-	x86_F6:   "%st(6)",
-	x86_F7:   "%st(7)",
-	x86_M0:   "%mm0",
-	x86_M1:   "%mm1",
-	x86_M2:   "%mm2",
-	x86_M3:   "%mm3",
-	x86_M4:   "%mm4",
-	x86_M5:   "%mm5",
-	x86_M6:   "%mm6",
-	x86_M7:   "%mm7",
-	x86_X0:   "%xmm0",
-	x86_X1:   "%xmm1",
-	x86_X2:   "%xmm2",
-	x86_X3:   "%xmm3",
-	x86_X4:   "%xmm4",
-	x86_X5:   "%xmm5",
-	x86_X6:   "%xmm6",
-	x86_X7:   "%xmm7",
-	x86_X8:   "%xmm8",
-	x86_X9:   "%xmm9",
-	x86_X10:  "%xmm10",
-	x86_X11:  "%xmm11",
-	x86_X12:  "%xmm12",
-	x86_X13:  "%xmm13",
-	x86_X14:  "%xmm14",
-	x86_X15:  "%xmm15",
-	x86_CS:   "%cs",
-	x86_SS:   "%ss",
-	x86_DS:   "%ds",
-	x86_ES:   "%es",
-	x86_FS:   "%fs",
-	x86_GS:   "%gs",
-	x86_GDTR: "%gdtr",
-	x86_IDTR: "%idtr",
-	x86_LDTR: "%ldtr",
-	x86_MSW:  "%msw",
-	x86_TASK: "%task",
-	x86_CR0:  "%cr0",
-	x86_CR1:  "%cr1",
-	x86_CR2:  "%cr2",
-	x86_CR3:  "%cr3",
-	x86_CR4:  "%cr4",
-	x86_CR5:  "%cr5",
-	x86_CR6:  "%cr6",
-	x86_CR7:  "%cr7",
-	x86_CR8:  "%cr8",
-	x86_CR9:  "%cr9",
-	x86_CR10: "%cr10",
-	x86_CR11: "%cr11",
-	x86_CR12: "%cr12",
-	x86_CR13: "%cr13",
-	x86_CR14: "%cr14",
-	x86_CR15: "%cr15",
-	x86_DR0:  "%db0",
-	x86_DR1:  "%db1",
-	x86_DR2:  "%db2",
-	x86_DR3:  "%db3",
-	x86_DR4:  "%db4",
-	x86_DR5:  "%db5",
-	x86_DR6:  "%db6",
-	x86_DR7:  "%db7",
-	x86_TR0:  "%tr0",
-	x86_TR1:  "%tr1",
-	x86_TR2:  "%tr2",
-	x86_TR3:  "%tr3",
-	x86_TR4:  "%tr4",
-	x86_TR5:  "%tr5",
-	x86_TR6:  "%tr6",
-	x86_TR7:  "%tr7",
-}
-
-var x86_gnuOp = map[x86_Op]string{
-	x86_CBW:       "cbtw",
-	x86_CDQ:       "cltd",
-	x86_CMPSD:     "cmpsl",
-	x86_CMPSD_XMM: "cmpsd",
-	x86_CWD:       "cwtd",
-	x86_CWDE:      "cwtl",
-	x86_CQO:       "cqto",
-	x86_INSD:      "insl",
-	x86_IRET:      "iretw",
-	x86_IRETD:     "iret",
-	x86_IRETQ:     "iretq",
-	x86_LODSB:     "lods",
-	x86_LODSD:     "lods",
-	x86_LODSQ:     "lods",
-	x86_LODSW:     "lods",
-	x86_MOVSD:     "movsl",
-	x86_MOVSD_XMM: "movsd",
-	x86_OUTSD:     "outsl",
-	x86_POPA:      "popaw",
-	x86_POPAD:     "popa",
-	x86_POPF:      "popfw",
-	x86_POPFD:     "popf",
-	x86_PUSHA:     "pushaw",
-	x86_PUSHAD:    "pusha",
-	x86_PUSHF:     "pushfw",
-	x86_PUSHFD:    "pushf",
-	x86_SCASB:     "scas",
-	x86_SCASD:     "scas",
-	x86_SCASQ:     "scas",
-	x86_SCASW:     "scas",
-	x86_STOSB:     "stos",
-	x86_STOSD:     "stos",
-	x86_STOSQ:     "stos",
-	x86_STOSW:     "stos",
-	x86_XLATB:     "xlat",
-}
-
-var x86_cmppsOps = []string{
-	"cmpeq",
-	"cmplt",
-	"cmple",
-	"cmpunord",
-	"cmpneq",
-	"cmpnlt",
-	"cmpnle",
-	"cmpord",
-}
-
-var x86_pclmulqOps = []string{
-	"pclmullqlqdq",
-	"pclmulhqlqdq",
-	"pclmullqhqdq",
-	"pclmulhqhqdq",
-}
-
-func x86_countPrefix(inst *x86_Inst, target x86_Prefix) int {
-	n := 0
-	for _, p := range inst.Prefix {
-		if p&0xFF == target&0xFF {
-			n++
-		}
-	}
-	return n
-}
-
-func x86_markLastImplicit(inst *x86_Inst, prefix x86_Prefix) bool {
-	for i := len(inst.Prefix) - 1; i >= 0; i-- {
-		p := inst.Prefix[i]
-		if p&0xFF == prefix {
-			inst.Prefix[i] |= x86_PrefixImplicit
-			return true
-		}
-	}
-	return false
-}
-
-func x86_unmarkImplicit(inst *x86_Inst, prefix x86_Prefix) {
-	for i := len(inst.Prefix) - 1; i >= 0; i-- {
-		p := inst.Prefix[i]
-		if p&0xFF == prefix {
-			inst.Prefix[i] &^= x86_PrefixImplicit
-		}
-	}
-}
-
-func x86_byteSizeSuffix(b int) string {
-	switch b {
-	case 1:
-		return "b"
-	case 2:
-		return "w"
-	case 4:
-		return "l"
-	case 8:
-		return "q"
-	}
-	return ""
-}
-
-func x86_argBytes(inst *x86_Inst, arg x86_Arg) int {
-	if x86_isMem(arg) {
-		return inst.MemBytes
-	}
-	return x86_regBytes(arg)
-}
-
-func x86_isFloat(op x86_Op) bool {
-	switch op {
-	case x86_FADD, x86_FCOM, x86_FCOMP, x86_FDIV, x86_FDIVR, x86_FIADD, x86_FICOM, x86_FICOMP, x86_FIDIV, x86_FIDIVR, x86_FILD, x86_FIMUL, x86_FIST, x86_FISTP, x86_FISTTP, x86_FISUB, x86_FISUBR, x86_FLD, x86_FMUL, x86_FST, x86_FSTP, x86_FSUB, x86_FSUBR:
-		return true
-	}
-	return false
-}
-
-func x86_isFloatInt(op x86_Op) bool {
-	switch op {
-	case x86_FIADD, x86_FICOM, x86_FICOMP, x86_FIDIV, x86_FIDIVR, x86_FILD, x86_FIMUL, x86_FIST, x86_FISTP, x86_FISTTP, x86_FISUB, x86_FISUBR:
-		return true
-	}
-	return false
-}
-
-/* inst.go */
-
-// 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 x86asm implements decoding of x86 machine code.
-
-// An Inst is a single instruction.
-type x86_Inst struct {
-	Prefix   x86_Prefixes // Prefixes applied to the instruction.
-	Op       x86_Op       // Opcode mnemonic
-	Opcode   uint32       // Encoded opcode bits, left aligned (first byte is Opcode>>24, etc)
-	Args     x86_Args     // Instruction arguments, in Intel order
-	Mode     int          // processor mode in bits: 16, 32, or 64
-	AddrSize int          // address size in bits: 16, 32, or 64
-	DataSize int          // operand size in bits: 16, 32, or 64
-	MemBytes int          // size of memory argument in bytes: 1, 2, 4, 8, 16, and so on.
-	Len      int          // length of encoded instruction in bytes
-}
-
-// Prefixes is an array of prefixes associated with a single instruction.
-// The prefixes are listed in the same order as found in the instruction:
-// each prefix byte corresponds to one slot in the array. The first zero
-// in the array marks the end of the prefixes.
-type x86_Prefixes [14]x86_Prefix
-
-// A Prefix represents an Intel instruction prefix.
-// The low 8 bits are the actual prefix byte encoding,
-// and the top 8 bits contain distinguishing bits and metadata.
-type x86_Prefix uint16
-
-const (
-	// Metadata about the role of a prefix in an instruction.
-	x86_PrefixImplicit x86_Prefix = 0x8000 // prefix is implied by instruction text
-	x86_PrefixIgnored  x86_Prefix = 0x4000 // prefix is ignored: either irrelevant or overridden by a later prefix
-	x86_PrefixInvalid  x86_Prefix = 0x2000 // prefix makes entire instruction invalid (bad LOCK)
-
-	// Memory segment overrides.
-	x86_PrefixES x86_Prefix = 0x26 // ES segment override
-	x86_PrefixCS x86_Prefix = 0x2E // CS segment override
-	x86_PrefixSS x86_Prefix = 0x36 // SS segment override
-	x86_PrefixDS x86_Prefix = 0x3E // DS segment override
-	x86_PrefixFS x86_Prefix = 0x64 // FS segment override
-	x86_PrefixGS x86_Prefix = 0x65 // GS segment override
-
-	// Branch prediction.
-	x86_PrefixPN x86_Prefix = 0x12E // predict not taken (conditional branch only)
-	x86_PrefixPT x86_Prefix = 0x13E // predict taken (conditional branch only)
-
-	// Size attributes.
-	x86_PrefixDataSize x86_Prefix = 0x66 // operand size override
-	x86_PrefixData16   x86_Prefix = 0x166
-	x86_PrefixData32   x86_Prefix = 0x266
-	x86_PrefixAddrSize x86_Prefix = 0x67 // address size override
-	x86_PrefixAddr16   x86_Prefix = 0x167
-	x86_PrefixAddr32   x86_Prefix = 0x267
-
-	// One of a kind.
-	x86_PrefixLOCK     x86_Prefix = 0xF0 // lock
-	x86_PrefixREPN     x86_Prefix = 0xF2 // repeat not zero
-	x86_PrefixXACQUIRE x86_Prefix = 0x1F2
-	x86_PrefixBND      x86_Prefix = 0x2F2
-	x86_PrefixREP      x86_Prefix = 0xF3 // repeat
-	x86_PrefixXRELEASE x86_Prefix = 0x1F3
-
-	// The REX prefixes must be in the range [PrefixREX, PrefixREX+0x10).
-	// the other bits are set or not according to the intended use.
-	x86_PrefixREX  x86_Prefix = 0x40 // REX 64-bit extension prefix
-	x86_PrefixREXW x86_Prefix = 0x08 // extension bit W (64-bit instruction width)
-	x86_PrefixREXR x86_Prefix = 0x04 // extension bit R (r field in modrm)
-	x86_PrefixREXX x86_Prefix = 0x02 // extension bit X (index field in sib)
-	x86_PrefixREXB x86_Prefix = 0x01 // extension bit B (r/m field in modrm or base field in sib)
-)
-
-// IsREX reports whether p is a REX prefix byte.
-func (p x86_Prefix) IsREX() bool {
-	return p&0xF0 == x86_PrefixREX
-}
-
-func (p x86_Prefix) String() string {
-	p &^= x86_PrefixImplicit | x86_PrefixIgnored | x86_PrefixInvalid
-	if s := x86_prefixNames[p]; s != "" {
-		return s
-	}
-
-	if p.IsREX() {
-		s := "REX."
-		if p&x86_PrefixREXW != 0 {
-			s += "W"
-		}
-		if p&x86_PrefixREXR != 0 {
-			s += "R"
-		}
-		if p&x86_PrefixREXX != 0 {
-			s += "X"
-		}
-		if p&x86_PrefixREXB != 0 {
-			s += "B"
-		}
-		return s
-	}
-
-	return fmt.Sprintf("Prefix(%#x)", int(p))
-}
-
-// An Op is an x86 opcode.
-type x86_Op uint32
-
-func (op x86_Op) String() string {
-	i := int(op)
-	if i < 0 || i >= len(x86_opNames) || x86_opNames[i] == "" {
-		return fmt.Sprintf("Op(%d)", i)
-	}
-	return x86_opNames[i]
-}
-
-// An Args holds the instruction arguments.
-// If an instruction has fewer than 4 arguments,
-// the final elements in the array are nil.
-type x86_Args [4]x86_Arg
-
-// An Arg is a single instruction argument,
-// one of these types: Reg, Mem, Imm, Rel.
-type x86_Arg interface {
-	String() string
-	isArg()
-}
-
-// Note that the implements of Arg that follow are all sized
-// so that on a 64-bit machine the data can be inlined in
-// the interface value instead of requiring an allocation.
-
-// A Reg is a single register.
-// The zero Reg value has no name but indicates ``no register.''
-type x86_Reg uint8
-
-const (
-	_ x86_Reg = iota
-
-	// 8-bit
-	x86_AL
-	x86_CL
-	x86_DL
-	x86_BL
-	x86_AH
-	x86_CH
-	x86_DH
-	x86_BH
-	x86_SPB
-	x86_BPB
-	x86_SIB
-	x86_DIB
-	x86_R8B
-	x86_R9B
-	x86_R10B
-	x86_R11B
-	x86_R12B
-	x86_R13B
-	x86_R14B
-	x86_R15B
-
-	// 16-bit
-	x86_AX
-	x86_CX
-	x86_DX
-	x86_BX
-	x86_SP
-	x86_BP
-	x86_SI
-	x86_DI
-	x86_R8W
-	x86_R9W
-	x86_R10W
-	x86_R11W
-	x86_R12W
-	x86_R13W
-	x86_R14W
-	x86_R15W
-
-	// 32-bit
-	x86_EAX
-	x86_ECX
-	x86_EDX
-	x86_EBX
-	x86_ESP
-	x86_EBP
-	x86_ESI
-	x86_EDI
-	x86_R8L
-	x86_R9L
-	x86_R10L
-	x86_R11L
-	x86_R12L
-	x86_R13L
-	x86_R14L
-	x86_R15L
-
-	// 64-bit
-	x86_RAX
-	x86_RCX
-	x86_RDX
-	x86_RBX
-	x86_RSP
-	x86_RBP
-	x86_RSI
-	x86_RDI
-	x86_R8
-	x86_R9
-	x86_R10
-	x86_R11
-	x86_R12
-	x86_R13
-	x86_R14
-	x86_R15
-
-	// Instruction pointer.
-	x86_IP  // 16-bit
-	x86_EIP // 32-bit
-	x86_RIP // 64-bit
-
-	// 387 floating point registers.
-	x86_F0
-	x86_F1
-	x86_F2
-	x86_F3
-	x86_F4
-	x86_F5
-	x86_F6
-	x86_F7
-
-	// MMX registers.
-	x86_M0
-	x86_M1
-	x86_M2
-	x86_M3
-	x86_M4
-	x86_M5
-	x86_M6
-	x86_M7
-
-	// XMM registers.
-	x86_X0
-	x86_X1
-	x86_X2
-	x86_X3
-	x86_X4
-	x86_X5
-	x86_X6
-	x86_X7
-	x86_X8
-	x86_X9
-	x86_X10
-	x86_X11
-	x86_X12
-	x86_X13
-	x86_X14
-	x86_X15
-
-	// Segment registers.
-	x86_ES
-	x86_CS
-	x86_SS
-	x86_DS
-	x86_FS
-	x86_GS
-
-	// System registers.
-	x86_GDTR
-	x86_IDTR
-	x86_LDTR
-	x86_MSW
-	x86_TASK
-
-	// Control registers.
-	x86_CR0
-	x86_CR1
-	x86_CR2
-	x86_CR3
-	x86_CR4
-	x86_CR5
-	x86_CR6
-	x86_CR7
-	x86_CR8
-	x86_CR9
-	x86_CR10
-	x86_CR11
-	x86_CR12
-	x86_CR13
-	x86_CR14
-	x86_CR15
-
-	// Debug registers.
-	x86_DR0
-	x86_DR1
-	x86_DR2
-	x86_DR3
-	x86_DR4
-	x86_DR5
-	x86_DR6
-	x86_DR7
-	x86_DR8
-	x86_DR9
-	x86_DR10
-	x86_DR11
-	x86_DR12
-	x86_DR13
-	x86_DR14
-	x86_DR15
-
-	// Task registers.
-	x86_TR0
-	x86_TR1
-	x86_TR2
-	x86_TR3
-	x86_TR4
-	x86_TR5
-	x86_TR6
-	x86_TR7
-)
-
-const x86_regMax = x86_TR7
-
-func (x86_Reg) isArg() {}
-
-func (r x86_Reg) String() string {
-	i := int(r)
-	if i < 0 || i >= len(x86_regNames) || x86_regNames[i] == "" {
-		return fmt.Sprintf("Reg(%d)", i)
-	}
-	return x86_regNames[i]
-}
-
-// A Mem is a memory reference.
-// The general form is Segment:[Base+Scale*Index+Disp].
-type x86_Mem struct {
-	Segment x86_Reg
-	Base    x86_Reg
-	Scale   uint8
-	Index   x86_Reg
-	Disp    int64
-}
-
-func (x86_Mem) isArg() {}
-
-func (m x86_Mem) String() string {
-	var base, plus, scale, index, disp string
-
-	if m.Base != 0 {
-		base = m.Base.String()
-	}
-	if m.Scale != 0 {
-		if m.Base != 0 {
-			plus = "+"
-		}
-		if m.Scale > 1 {
-			scale = fmt.Sprintf("%d*", m.Scale)
-		}
-		index = m.Index.String()
-	}
-	if m.Disp != 0 || m.Base == 0 && m.Scale == 0 {
-		disp = fmt.Sprintf("%+#x", m.Disp)
-	}
-	return "[" + base + plus + scale + index + disp + "]"
-}
-
-// A Rel is an offset relative to the current instruction pointer.
-type x86_Rel int32
-
-func (x86_Rel) isArg() {}
-
-func (r x86_Rel) String() string {
-	return fmt.Sprintf(".%+d", r)
-}
-
-// An Imm is an integer constant.
-type x86_Imm int64
-
-func (x86_Imm) isArg() {}
-
-func (i x86_Imm) String() string {
-	return fmt.Sprintf("%#x", int64(i))
-}
-
-func (i x86_Inst) String() string {
-	var buf bytes.Buffer
-	for _, p := range i.Prefix {
-		if p == 0 {
-			break
-		}
-		if p&x86_PrefixImplicit != 0 {
-			continue
-		}
-		fmt.Fprintf(&buf, "%v ", p)
-	}
-	fmt.Fprintf(&buf, "%v", i.Op)
-	sep := " "
-	for _, v := range i.Args {
-		if v == nil {
-			break
-		}
-		fmt.Fprintf(&buf, "%s%v", sep, v)
-		sep = ", "
-	}
-	return buf.String()
-}
-
-func x86_isReg(a x86_Arg) bool {
-	_, ok := a.(x86_Reg)
-	return ok
-}
-
-func x86_isSegReg(a x86_Arg) bool {
-	r, ok := a.(x86_Reg)
-	return ok && x86_ES <= r && r <= x86_GS
-}
-
-func x86_isMem(a x86_Arg) bool {
-	_, ok := a.(x86_Mem)
-	return ok
-}
-
-func x86_isImm(a x86_Arg) bool {
-	_, ok := a.(x86_Imm)
-	return ok
-}
-
-func x86_regBytes(a x86_Arg) int {
-	r, ok := a.(x86_Reg)
-	if !ok {
-		return 0
-	}
-	if x86_AL <= r && r <= x86_R15B {
-		return 1
-	}
-	if x86_AX <= r && r <= x86_R15W {
-		return 2
-	}
-	if x86_EAX <= r && r <= x86_R15L {
-		return 4
-	}
-	if x86_RAX <= r && r <= x86_R15 {
-		return 8
-	}
-	return 0
-}
-
-func x86_isSegment(p x86_Prefix) bool {
-	switch p {
-	case x86_PrefixCS, x86_PrefixDS, x86_PrefixES, x86_PrefixFS, x86_PrefixGS, x86_PrefixSS:
-		return true
-	}
-	return false
-}
-
-// The Op definitions and string list are in tables.go.
-
-var x86_prefixNames = map[x86_Prefix]string{
-	x86_PrefixCS:       "CS",
-	x86_PrefixDS:       "DS",
-	x86_PrefixES:       "ES",
-	x86_PrefixFS:       "FS",
-	x86_PrefixGS:       "GS",
-	x86_PrefixSS:       "SS",
-	x86_PrefixLOCK:     "LOCK",
-	x86_PrefixREP:      "REP",
-	x86_PrefixREPN:     "REPN",
-	x86_PrefixAddrSize: "ADDRSIZE",
-	x86_PrefixDataSize: "DATASIZE",
-	x86_PrefixAddr16:   "ADDR16",
-	x86_PrefixData16:   "DATA16",
-	x86_PrefixAddr32:   "ADDR32",
-	x86_PrefixData32:   "DATA32",
-	x86_PrefixBND:      "BND",
-	x86_PrefixXACQUIRE: "XACQUIRE",
-	x86_PrefixXRELEASE: "XRELEASE",
-	x86_PrefixREX:      "REX",
-	x86_PrefixPT:       "PT",
-	x86_PrefixPN:       "PN",
-}
-
-var x86_regNames = [...]string{
-	x86_AL:   "AL",
-	x86_CL:   "CL",
-	x86_BL:   "BL",
-	x86_DL:   "DL",
-	x86_AH:   "AH",
-	x86_CH:   "CH",
-	x86_BH:   "BH",
-	x86_DH:   "DH",
-	x86_SPB:  "SPB",
-	x86_BPB:  "BPB",
-	x86_SIB:  "SIB",
-	x86_DIB:  "DIB",
-	x86_R8B:  "R8B",
-	x86_R9B:  "R9B",
-	x86_R10B: "R10B",
-	x86_R11B: "R11B",
-	x86_R12B: "R12B",
-	x86_R13B: "R13B",
-	x86_R14B: "R14B",
-	x86_R15B: "R15B",
-	x86_AX:   "AX",
-	x86_CX:   "CX",
-	x86_BX:   "BX",
-	x86_DX:   "DX",
-	x86_SP:   "SP",
-	x86_BP:   "BP",
-	x86_SI:   "SI",
-	x86_DI:   "DI",
-	x86_R8W:  "R8W",
-	x86_R9W:  "R9W",
-	x86_R10W: "R10W",
-	x86_R11W: "R11W",
-	x86_R12W: "R12W",
-	x86_R13W: "R13W",
-	x86_R14W: "R14W",
-	x86_R15W: "R15W",
-	x86_EAX:  "EAX",
-	x86_ECX:  "ECX",
-	x86_EDX:  "EDX",
-	x86_EBX:  "EBX",
-	x86_ESP:  "ESP",
-	x86_EBP:  "EBP",
-	x86_ESI:  "ESI",
-	x86_EDI:  "EDI",
-	x86_R8L:  "R8L",
-	x86_R9L:  "R9L",
-	x86_R10L: "R10L",
-	x86_R11L: "R11L",
-	x86_R12L: "R12L",
-	x86_R13L: "R13L",
-	x86_R14L: "R14L",
-	x86_R15L: "R15L",
-	x86_RAX:  "RAX",
-	x86_RCX:  "RCX",
-	x86_RDX:  "RDX",
-	x86_RBX:  "RBX",
-	x86_RSP:  "RSP",
-	x86_RBP:  "RBP",
-	x86_RSI:  "RSI",
-	x86_RDI:  "RDI",
-	x86_R8:   "R8",
-	x86_R9:   "R9",
-	x86_R10:  "R10",
-	x86_R11:  "R11",
-	x86_R12:  "R12",
-	x86_R13:  "R13",
-	x86_R14:  "R14",
-	x86_R15:  "R15",
-	x86_IP:   "IP",
-	x86_EIP:  "EIP",
-	x86_RIP:  "RIP",
-	x86_F0:   "F0",
-	x86_F1:   "F1",
-	x86_F2:   "F2",
-	x86_F3:   "F3",
-	x86_F4:   "F4",
-	x86_F5:   "F5",
-	x86_F6:   "F6",
-	x86_F7:   "F7",
-	x86_M0:   "M0",
-	x86_M1:   "M1",
-	x86_M2:   "M2",
-	x86_M3:   "M3",
-	x86_M4:   "M4",
-	x86_M5:   "M5",
-	x86_M6:   "M6",
-	x86_M7:   "M7",
-	x86_X0:   "X0",
-	x86_X1:   "X1",
-	x86_X2:   "X2",
-	x86_X3:   "X3",
-	x86_X4:   "X4",
-	x86_X5:   "X5",
-	x86_X6:   "X6",
-	x86_X7:   "X7",
-	x86_X8:   "X8",
-	x86_X9:   "X9",
-	x86_X10:  "X10",
-	x86_X11:  "X11",
-	x86_X12:  "X12",
-	x86_X13:  "X13",
-	x86_X14:  "X14",
-	x86_X15:  "X15",
-	x86_CS:   "CS",
-	x86_SS:   "SS",
-	x86_DS:   "DS",
-	x86_ES:   "ES",
-	x86_FS:   "FS",
-	x86_GS:   "GS",
-	x86_GDTR: "GDTR",
-	x86_IDTR: "IDTR",
-	x86_LDTR: "LDTR",
-	x86_MSW:  "MSW",
-	x86_TASK: "TASK",
-	x86_CR0:  "CR0",
-	x86_CR1:  "CR1",
-	x86_CR2:  "CR2",
-	x86_CR3:  "CR3",
-	x86_CR4:  "CR4",
-	x86_CR5:  "CR5",
-	x86_CR6:  "CR6",
-	x86_CR7:  "CR7",
-	x86_CR8:  "CR8",
-	x86_CR9:  "CR9",
-	x86_CR10: "CR10",
-	x86_CR11: "CR11",
-	x86_CR12: "CR12",
-	x86_CR13: "CR13",
-	x86_CR14: "CR14",
-	x86_CR15: "CR15",
-	x86_DR0:  "DR0",
-	x86_DR1:  "DR1",
-	x86_DR2:  "DR2",
-	x86_DR3:  "DR3",
-	x86_DR4:  "DR4",
-	x86_DR5:  "DR5",
-	x86_DR6:  "DR6",
-	x86_DR7:  "DR7",
-	x86_DR8:  "DR8",
-	x86_DR9:  "DR9",
-	x86_DR10: "DR10",
-	x86_DR11: "DR11",
-	x86_DR12: "DR12",
-	x86_DR13: "DR13",
-	x86_DR14: "DR14",
-	x86_DR15: "DR15",
-	x86_TR0:  "TR0",
-	x86_TR1:  "TR1",
-	x86_TR2:  "TR2",
-	x86_TR3:  "TR3",
-	x86_TR4:  "TR4",
-	x86_TR5:  "TR5",
-	x86_TR6:  "TR6",
-	x86_TR7:  "TR7",
-}
-
-/* intel.go */
-
-// 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.
-
-// IntelSyntax returns the Intel assembler syntax for the instruction, as defined by Intel's XED tool.
-func x86_IntelSyntax(inst x86_Inst) string {
-	var iargs []x86_Arg
-	for _, a := range inst.Args {
-		if a == nil {
-			break
-		}
-		iargs = append(iargs, a)
-	}
-
-	switch inst.Op {
-	case x86_INSB, x86_INSD, x86_INSW, x86_OUTSB, x86_OUTSD, x86_OUTSW, x86_LOOPNE, x86_JCXZ, x86_JECXZ, x86_JRCXZ, x86_LOOP, x86_LOOPE, x86_MOV, x86_XLATB:
-		if inst.Op == x86_MOV && (inst.Opcode>>16)&0xFFFC != 0x0F20 {
-			break
-		}
-		for i, p := range inst.Prefix {
-			if p&0xFF == x86_PrefixAddrSize {
-				inst.Prefix[i] &^= x86_PrefixImplicit
-			}
-		}
-	}
-
-	switch inst.Op {
-	case x86_MOV:
-		dst, _ := inst.Args[0].(x86_Reg)
-		src, _ := inst.Args[1].(x86_Reg)
-		if x86_ES <= dst && dst <= x86_GS && x86_EAX <= src && src <= x86_R15L {
-			src -= x86_EAX - x86_AX
-			iargs[1] = src
-		}
-		if x86_ES <= dst && dst <= x86_GS && x86_RAX <= src && src <= x86_R15 {
-			src -= x86_RAX - x86_AX
-			iargs[1] = src
-		}
-
-		if inst.Opcode>>24&^3 == 0xA0 {
-			for i, p := range inst.Prefix {
-				if p&0xFF == x86_PrefixAddrSize {
-					inst.Prefix[i] |= x86_PrefixImplicit
-				}
-			}
-		}
-	}
-
-	switch inst.Op {
-	case x86_AAM, x86_AAD:
-		if imm, ok := iargs[0].(x86_Imm); ok {
-			if inst.DataSize == 32 {
-				iargs[0] = x86_Imm(uint32(int8(imm)))
-			} else if inst.DataSize == 16 {
-				iargs[0] = x86_Imm(uint16(int8(imm)))
-			}
-		}
-
-	case x86_PUSH:
-		if imm, ok := iargs[0].(x86_Imm); ok {
-			iargs[0] = x86_Imm(uint32(imm))
-		}
-	}
-
-	for _, p := range inst.Prefix {
-		if p&x86_PrefixImplicit != 0 {
-			for j, pj := range inst.Prefix {
-				if pj&0xFF == p&0xFF {
-					inst.Prefix[j] |= x86_PrefixImplicit
-				}
-			}
-		}
-	}
-
-	if inst.Op != 0 {
-		for i, p := range inst.Prefix {
-			switch p &^ x86_PrefixIgnored {
-			case x86_PrefixData16, x86_PrefixData32, x86_PrefixCS, x86_PrefixDS, x86_PrefixES, x86_PrefixSS:
-				inst.Prefix[i] |= x86_PrefixImplicit
-			}
-			if p.IsREX() {
-				inst.Prefix[i] |= x86_PrefixImplicit
-			}
-		}
-	}
-
-	if x86_isLoop[inst.Op] || inst.Op == x86_JCXZ || inst.Op == x86_JECXZ || inst.Op == x86_JRCXZ {
-		for i, p := range inst.Prefix {
-			if p == x86_PrefixPT || p == x86_PrefixPN {
-				inst.Prefix[i] |= x86_PrefixImplicit
-			}
-		}
-	}
-
-	switch inst.Op {
-	case x86_AAA, x86_AAS, x86_CBW, x86_CDQE, x86_CLC, x86_CLD, x86_CLI, x86_CLTS, x86_CMC, x86_CPUID, x86_CQO, x86_CWD, x86_DAA, x86_DAS,
-		x86_FDECSTP, x86_FINCSTP, x86_FNCLEX, x86_FNINIT, x86_FNOP, x86_FWAIT, x86_HLT,
-		x86_ICEBP, x86_INSB, x86_INSD, x86_INSW, x86_INT, x86_INTO, x86_INVD, x86_IRET, x86_IRETQ,
-		x86_LAHF, x86_LEAVE, x86_LRET, x86_MONITOR, x86_MWAIT, x86_NOP, x86_OUTSB, x86_OUTSD, x86_OUTSW,
-		x86_PAUSE, x86_POPA, x86_POPF, x86_POPFQ, x86_PUSHA, x86_PUSHF, x86_PUSHFQ,
-		x86_RDMSR, x86_RDPMC, x86_RDTSC, x86_RDTSCP, x86_RET, x86_RSM,
-		x86_SAHF, x86_STC, x86_STD, x86_STI, x86_SYSENTER, x86_SYSEXIT, x86_SYSRET,
-		x86_UD2, x86_WBINVD, x86_WRMSR, x86_XEND, x86_XLATB, x86_XTEST:
-
-		if inst.Op == x86_NOP && inst.Opcode>>24 != 0x90 {
-			break
-		}
-		if inst.Op == x86_RET && inst.Opcode>>24 != 0xC3 {
-			break
-		}
-		if inst.Op == x86_INT && inst.Opcode>>24 != 0xCC {
-			break
-		}
-		if inst.Op == x86_LRET && inst.Opcode>>24 != 0xcb {
-			break
-		}
-		for i, p := range inst.Prefix {
-			if p&0xFF == x86_PrefixDataSize {
-				inst.Prefix[i] &^= x86_PrefixImplicit | x86_PrefixIgnored
-			}
-		}
-
-	case 0:
-		// ok
-	}
-
-	switch inst.Op {
-	case x86_INSB, x86_INSD, x86_INSW, x86_OUTSB, x86_OUTSD, x86_OUTSW, x86_MONITOR, x86_MWAIT, x86_XLATB:
-		iargs = nil
-
-	case x86_STOSB, x86_STOSW, x86_STOSD, x86_STOSQ:
-		iargs = iargs[:1]
-
-	case x86_LODSB, x86_LODSW, x86_LODSD, x86_LODSQ, x86_SCASB, x86_SCASW, x86_SCASD, x86_SCASQ:
-		iargs = iargs[1:]
-	}
-
-	const (
-		haveData16 = 1 << iota
-		haveData32
-		haveAddr16
-		haveAddr32
-		haveXacquire
-		haveXrelease
-		haveLock
-		haveHintTaken
-		haveHintNotTaken
-		haveBnd
-	)
-	var prefixBits uint32
-	prefix := ""
-	for _, p := range inst.Prefix {
-		if p == 0 {
-			break
-		}
-		if p&0xFF == 0xF3 {
-			prefixBits &^= haveBnd
-		}
-		if p&(x86_PrefixImplicit|x86_PrefixIgnored) != 0 {
-			continue
-		}
-		switch p {
-		default:
-			prefix += strings.ToLower(p.String()) + " "
-		case x86_PrefixCS, x86_PrefixDS, x86_PrefixES, x86_PrefixFS, x86_PrefixGS, x86_PrefixSS:
-			if inst.Op == 0 {
-				prefix += strings.ToLower(p.String()) + " "
-			}
-		case x86_PrefixREPN:
-			prefix += "repne "
-		case x86_PrefixLOCK:
-			prefixBits |= haveLock
-		case x86_PrefixData16, x86_PrefixDataSize:
-			prefixBits |= haveData16
-		case x86_PrefixData32:
-			prefixBits |= haveData32
-		case x86_PrefixAddrSize, x86_PrefixAddr16:
-			prefixBits |= haveAddr16
-		case x86_PrefixAddr32:
-			prefixBits |= haveAddr32
-		case x86_PrefixXACQUIRE:
-			prefixBits |= haveXacquire
-		case x86_PrefixXRELEASE:
-			prefixBits |= haveXrelease
-		case x86_PrefixPT:
-			prefixBits |= haveHintTaken
-		case x86_PrefixPN:
-			prefixBits |= haveHintNotTaken
-		case x86_PrefixBND:
-			prefixBits |= haveBnd
-		}
-	}
-	switch inst.Op {
-	case x86_JMP:
-		if inst.Opcode>>24 == 0xEB {
-			prefixBits &^= haveBnd
-		}
-	case x86_RET, x86_LRET:
-		prefixBits &^= haveData16 | haveData32
-	}
-
-	if prefixBits&haveXacquire != 0 {
-		prefix += "xacquire "
-	}
-	if prefixBits&haveXrelease != 0 {
-		prefix += "xrelease "
-	}
-	if prefixBits&haveLock != 0 {
-		prefix += "lock "
-	}
-	if prefixBits&haveBnd != 0 {
-		prefix += "bnd "
-	}
-	if prefixBits&haveHintTaken != 0 {
-		prefix += "hint-taken "
-	}
-	if prefixBits&haveHintNotTaken != 0 {
-		prefix += "hint-not-taken "
-	}
-	if prefixBits&haveAddr16 != 0 {
-		prefix += "addr16 "
-	}
-	if prefixBits&haveAddr32 != 0 {
-		prefix += "addr32 "
-	}
-	if prefixBits&haveData16 != 0 {
-		prefix += "data16 "
-	}
-	if prefixBits&haveData32 != 0 {
-		prefix += "data32 "
-	}
-
-	if inst.Op == 0 {
-		if prefix == "" {
-			return "<no instruction>"
-		}
-		return prefix[:len(prefix)-1]
-	}
-
-	var args []string
-	for _, a := range iargs {
-		if a == nil {
-			break
-		}
-		args = append(args, x86_intelArg(&inst, a))
-	}
-
-	var op string
-	switch inst.Op {
-	case x86_NOP:
-		if inst.Opcode>>24 == 0x0F {
-			if inst.DataSize == 16 {
-				args = append(args, "ax")
-			} else {
-				args = append(args, "eax")
-			}
-		}
-
-	case x86_BLENDVPD, x86_BLENDVPS, x86_PBLENDVB:
-		args = args[:2]
-
-	case x86_INT:
-		if inst.Opcode>>24 == 0xCC {
-			args = nil
-			op = "int3"
-		}
-
-	case x86_LCALL, x86_LJMP:
-		if len(args) == 2 {
-			args[0], args[1] = args[1], args[0]
-		}
-
-	case x86_FCHS, x86_FABS, x86_FTST, x86_FLDPI, x86_FLDL2E, x86_FLDLG2, x86_F2XM1, x86_FXAM, x86_FLD1, x86_FLDL2T, x86_FSQRT, x86_FRNDINT, x86_FCOS, x86_FSIN:
-		if len(args) == 0 {
-			args = append(args, "st0")
-		}
-
-	case x86_FPTAN, x86_FSINCOS, x86_FUCOMPP, x86_FCOMPP, x86_FYL2X, x86_FPATAN, x86_FXTRACT, x86_FPREM1, x86_FPREM, x86_FYL2XP1, x86_FSCALE:
-		if len(args) == 0 {
-			args = []string{"st0", "st1"}
-		}
-
-	case x86_FST, x86_FSTP, x86_FISTTP, x86_FIST, x86_FISTP, x86_FBSTP:
-		if len(args) == 1 {
-			args = append(args, "st0")
-		}
-
-	case x86_FLD, x86_FXCH, x86_FCOM, x86_FCOMP, x86_FIADD, x86_FIMUL, x86_FICOM, x86_FICOMP, x86_FISUBR, x86_FIDIV, x86_FUCOM, x86_FUCOMP, x86_FILD, x86_FBLD, x86_FADD, x86_FMUL, x86_FSUB, x86_FSUBR, x86_FISUB, x86_FDIV, x86_FDIVR, x86_FIDIVR:
-		if len(args) == 1 {
-			args = []string{"st0", args[0]}
-		}
-
-	case x86_MASKMOVDQU, x86_MASKMOVQ, x86_XLATB, x86_OUTSB, x86_OUTSW, x86_OUTSD:
-	FixSegment:
-		for i := len(inst.Prefix) - 1; i >= 0; i-- {
-			p := inst.Prefix[i] & 0xFF
-			switch p {
-			case x86_PrefixCS, x86_PrefixES, x86_PrefixFS, x86_PrefixGS, x86_PrefixSS:
-				if inst.Mode != 64 || p == x86_PrefixFS || p == x86_PrefixGS {
-					args = append(args, strings.ToLower((inst.Prefix[i] & 0xFF).String()))
-					break FixSegment
-				}
-			case x86_PrefixDS:
-				if inst.Mode != 64 {
-					break FixSegment
-				}
-			}
-		}
-	}
-
-	if op == "" {
-		op = x86_intelOp[inst.Op]
-	}
-	if op == "" {
-		op = strings.ToLower(inst.Op.String())
-	}
-	if args != nil {
-		op += " " + strings.Join(args, ", ")
-	}
-	return prefix + op
-}
-
-func x86_intelArg(inst *x86_Inst, arg x86_Arg) string {
-	switch a := arg.(type) {
-	case x86_Imm:
-		if inst.Mode == 32 {
-			return fmt.Sprintf("%#x", uint32(a))
-		}
-		if x86_Imm(int32(a)) == a {
-			return fmt.Sprintf("%#x", int64(a))
-		}
-		return fmt.Sprintf("%#x", uint64(a))
-	case x86_Mem:
-		if a.Base == x86_EIP {
-			a.Base = x86_RIP
-		}
-		prefix := ""
-		switch inst.MemBytes {
-		case 1:
-			prefix = "byte "
-		case 2:
-			prefix = "word "
-		case 4:
-			prefix = "dword "
-		case 8:
-			prefix = "qword "
-		case 16:
-			prefix = "xmmword "
-		}
-		switch inst.Op {
-		case x86_INVLPG:
-			prefix = "byte "
-		case x86_STOSB, x86_MOVSB, x86_CMPSB, x86_LODSB, x86_SCASB:
-			prefix = "byte "
-		case x86_STOSW, x86_MOVSW, x86_CMPSW, x86_LODSW, x86_SCASW:
-			prefix = "word "
-		case x86_STOSD, x86_MOVSD, x86_CMPSD, x86_LODSD, x86_SCASD:
-			prefix = "dword "
-		case x86_STOSQ, x86_MOVSQ, x86_CMPSQ, x86_LODSQ, x86_SCASQ:
-			prefix = "qword "
-		case x86_LAR:
-			prefix = "word "
-		case x86_BOUND:
-			if inst.Mode == 32 {
-				prefix = "qword "
-			} else {
-				prefix = "dword "
-			}
-		case x86_PREFETCHW, x86_PREFETCHNTA, x86_PREFETCHT0, x86_PREFETCHT1, x86_PREFETCHT2, x86_CLFLUSH:
-			prefix = "zmmword "
-		}
-		switch inst.Op {
-		case x86_MOVSB, x86_MOVSW, x86_MOVSD, x86_MOVSQ, x86_CMPSB, x86_CMPSW, x86_CMPSD, x86_CMPSQ, x86_STOSB, x86_STOSW, x86_STOSD, x86_STOSQ, x86_SCASB, x86_SCASW, x86_SCASD, x86_SCASQ, x86_LODSB, x86_LODSW, x86_LODSD, x86_LODSQ:
-			switch a.Base {
-			case x86_DI, x86_EDI, x86_RDI:
-				if a.Segment == x86_ES {
-					a.Segment = 0
-				}
-			case x86_SI, x86_ESI, x86_RSI:
-				if a.Segment == x86_DS {
-					a.Segment = 0
-				}
-			}
-		case x86_LEA:
-			a.Segment = 0
-		default:
-			switch a.Base {
-			case x86_SP, x86_ESP, x86_RSP, x86_BP, x86_EBP, x86_RBP:
-				if a.Segment == x86_SS {
-					a.Segment = 0
-				}
-			default:
-				if a.Segment == x86_DS {
-					a.Segment = 0
-				}
-			}
-		}
-
-		if inst.Mode == 64 && a.Segment != x86_FS && a.Segment != x86_GS {
-			a.Segment = 0
-		}
-
-		prefix += "ptr "
-		if a.Segment != 0 {
-			prefix += strings.ToLower(a.Segment.String()) + ":"
-		}
-		prefix += "["
-		if a.Base != 0 {
-			prefix += x86_intelArg(inst, a.Base)
-		}
-		if a.Scale != 0 && a.Index != 0 {
-			if a.Base != 0 {
-				prefix += "+"
-			}
-			prefix += fmt.Sprintf("%s*%d", x86_intelArg(inst, a.Index), a.Scale)
-		}
-		if a.Disp != 0 {
-			if prefix[len(prefix)-1] == '[' && (a.Disp >= 0 || int64(int32(a.Disp)) != a.Disp) {
-				prefix += fmt.Sprintf("%#x", uint64(a.Disp))
-			} else {
-				prefix += fmt.Sprintf("%+#x", a.Disp)
-			}
-		}
-		prefix += "]"
-		return prefix
-	case x86_Rel:
-		return fmt.Sprintf(".%+#x", int64(a))
-	case x86_Reg:
-		if int(a) < len(x86_intelReg) && x86_intelReg[a] != "" {
-			return x86_intelReg[a]
-		}
-	}
-	return strings.ToLower(arg.String())
-}
-
-var x86_intelOp = map[x86_Op]string{
-	x86_JAE:       "jnb",
-	x86_JA:        "jnbe",
-	x86_JGE:       "jnl",
-	x86_JNE:       "jnz",
-	x86_JG:        "jnle",
-	x86_JE:        "jz",
-	x86_SETAE:     "setnb",
-	x86_SETA:      "setnbe",
-	x86_SETGE:     "setnl",
-	x86_SETNE:     "setnz",
-	x86_SETG:      "setnle",
-	x86_SETE:      "setz",
-	x86_CMOVAE:    "cmovnb",
-	x86_CMOVA:     "cmovnbe",
-	x86_CMOVGE:    "cmovnl",
-	x86_CMOVNE:    "cmovnz",
-	x86_CMOVG:     "cmovnle",
-	x86_CMOVE:     "cmovz",
-	x86_LCALL:     "call far",
-	x86_LJMP:      "jmp far",
-	x86_LRET:      "ret far",
-	x86_ICEBP:     "int1",
-	x86_MOVSD_XMM: "movsd",
-	x86_XLATB:     "xlat",
-}
-
-var x86_intelReg = [...]string{
-	x86_F0:  "st0",
-	x86_F1:  "st1",
-	x86_F2:  "st2",
-	x86_F3:  "st3",
-	x86_F4:  "st4",
-	x86_F5:  "st5",
-	x86_F6:  "st6",
-	x86_F7:  "st7",
-	x86_M0:  "mmx0",
-	x86_M1:  "mmx1",
-	x86_M2:  "mmx2",
-	x86_M3:  "mmx3",
-	x86_M4:  "mmx4",
-	x86_M5:  "mmx5",
-	x86_M6:  "mmx6",
-	x86_M7:  "mmx7",
-	x86_X0:  "xmm0",
-	x86_X1:  "xmm1",
-	x86_X2:  "xmm2",
-	x86_X3:  "xmm3",
-	x86_X4:  "xmm4",
-	x86_X5:  "xmm5",
-	x86_X6:  "xmm6",
-	x86_X7:  "xmm7",
-	x86_X8:  "xmm8",
-	x86_X9:  "xmm9",
-	x86_X10: "xmm10",
-	x86_X11: "xmm11",
-	x86_X12: "xmm12",
-	x86_X13: "xmm13",
-	x86_X14: "xmm14",
-	x86_X15: "xmm15",
-
-	// TODO: Maybe the constants are named wrong.
-	x86_SPB: "spl",
-	x86_BPB: "bpl",
-	x86_SIB: "sil",
-	x86_DIB: "dil",
-
-	x86_R8L:  "r8d",
-	x86_R9L:  "r9d",
-	x86_R10L: "r10d",
-	x86_R11L: "r11d",
-	x86_R12L: "r12d",
-	x86_R13L: "r13d",
-	x86_R14L: "r14d",
-	x86_R15L: "r15d",
-}
-
-/* plan9x.go */
-
-// 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.
-
-// plan9Syntax returns the Go assembler syntax for the instruction.
-// The syntax was originally defined by Plan 9.
-// The pc is the program counter of the instruction, used for expanding
-// PC-relative addresses into absolute ones.
-// The symname function queries the symbol table for the program
-// being disassembled. Given a target address it returns the name and base
-// address of the symbol containing the target, if any; otherwise it returns "", 0.
-func x86_plan9Syntax(inst x86_Inst, pc uint64, symname func(uint64) (string, uint64)) string {
-	if symname == nil {
-		symname = func(uint64) (string, uint64) { return "", 0 }
-	}
-	var args []string
-	for i := len(inst.Args) - 1; i >= 0; i-- {
-		a := inst.Args[i]
-		if a == nil {
-			continue
-		}
-		args = append(args, x86_plan9Arg(&inst, pc, symname, a))
-	}
-
-	var last x86_Prefix
-	for _, p := range inst.Prefix {
-		if p == 0 || p.IsREX() {
-			break
-		}
-		last = p
-	}
-
-	prefix := ""
-	switch last & 0xFF {
-	case 0, 0x66, 0x67:
-		// ignore
-	case x86_PrefixREPN:
-		prefix += "REPNE "
-	default:
-		prefix += last.String() + " "
-	}
-
-	op := inst.Op.String()
-	if x86_plan9Suffix[inst.Op] {
-		switch inst.DataSize {
-		case 8:
-			op += "B"
-		case 16:
-			op += "W"
-		case 32:
-			op += "L"
-		case 64:
-			op += "Q"
-		}
-	}
-
-	if args != nil {
-		op += " " + strings.Join(args, ", ")
-	}
-
-	return prefix + op
-}
-
-func x86_plan9Arg(inst *x86_Inst, pc uint64, symname func(uint64) (string, uint64), arg x86_Arg) string {
-	switch a := arg.(type) {
-	case x86_Reg:
-		return x86_plan9Reg[a]
-	case x86_Rel:
-		if pc == 0 {
-			break
-		}
-		// If the absolute address is the start of a symbol, use the name.
-		// Otherwise use the raw address, so that things like relative
-		// jumps show up as JMP 0x123 instead of JMP f+10(SB).
-		// It is usually easier to search for 0x123 than to do the mental
-		// arithmetic to find f+10.
-		addr := pc + uint64(inst.Len) + uint64(a)
-		if s, base := symname(addr); s != "" && addr == base {
-			return fmt.Sprintf("%s(SB)", s)
-		}
-		return fmt.Sprintf("%#x", addr)
-
-	case x86_Imm:
-		if s, base := symname(uint64(a)); s != "" {
-			suffix := ""
-			if uint64(a) != base {
-				suffix = fmt.Sprintf("%+d", uint64(a)-base)
-			}
-			return fmt.Sprintf("$%s%s(SB)", s, suffix)
-		}
-		if inst.Mode == 32 {
-			return fmt.Sprintf("$%#x", uint32(a))
-		}
-		if x86_Imm(int32(a)) == a {
-			return fmt.Sprintf("$%#x", int64(a))
-		}
-		return fmt.Sprintf("$%#x", uint64(a))
-	case x86_Mem:
-		if a.Segment == 0 && a.Disp != 0 && a.Base == 0 && (a.Index == 0 || a.Scale == 0) {
-			if s, base := symname(uint64(a.Disp)); s != "" {
-				suffix := ""
-				if uint64(a.Disp) != base {
-					suffix = fmt.Sprintf("%+d", uint64(a.Disp)-base)
-				}
-				return fmt.Sprintf("%s%s(SB)", s, suffix)
-			}
-		}
-		s := ""
-		if a.Segment != 0 {
-			s += fmt.Sprintf("%s:", x86_plan9Reg[a.Segment])
-		}
-		if a.Disp != 0 {
-			s += fmt.Sprintf("%#x", a.Disp)
-		} else {
-			s += "0"
-		}
-		if a.Base != 0 {
-			s += fmt.Sprintf("(%s)", x86_plan9Reg[a.Base])
-		}
-		if a.Index != 0 && a.Scale != 0 {
-			s += fmt.Sprintf("(%s*%d)", x86_plan9Reg[a.Index], a.Scale)
-		}
-		return s
-	}
-	return arg.String()
-}
-
-var x86_plan9Suffix = [x86_maxOp + 1]bool{
-	x86_ADC:       true,
-	x86_ADD:       true,
-	x86_AND:       true,
-	x86_BSF:       true,
-	x86_BSR:       true,
-	x86_BT:        true,
-	x86_BTC:       true,
-	x86_BTR:       true,
-	x86_BTS:       true,
-	x86_CMP:       true,
-	x86_CMPXCHG:   true,
-	x86_CVTSI2SD:  true,
-	x86_CVTSI2SS:  true,
-	x86_CVTSD2SI:  true,
-	x86_CVTSS2SI:  true,
-	x86_CVTTSD2SI: true,
-	x86_CVTTSS2SI: true,
-	x86_DEC:       true,
-	x86_DIV:       true,
-	x86_FLDENV:    true,
-	x86_FRSTOR:    true,
-	x86_IDIV:      true,
-	x86_IMUL:      true,
-	x86_IN:        true,
-	x86_INC:       true,
-	x86_LEA:       true,
-	x86_MOV:       true,
-	x86_MOVNTI:    true,
-	x86_MUL:       true,
-	x86_NEG:       true,
-	x86_NOP:       true,
-	x86_NOT:       true,
-	x86_OR:        true,
-	x86_OUT:       true,
-	x86_POP:       true,
-	x86_POPA:      true,
-	x86_PUSH:      true,
-	x86_PUSHA:     true,
-	x86_RCL:       true,
-	x86_RCR:       true,
-	x86_ROL:       true,
-	x86_ROR:       true,
-	x86_SAR:       true,
-	x86_SBB:       true,
-	x86_SHL:       true,
-	x86_SHLD:      true,
-	x86_SHR:       true,
-	x86_SHRD:      true,
-	x86_SUB:       true,
-	x86_TEST:      true,
-	x86_XADD:      true,
-	x86_XCHG:      true,
-	x86_XOR:       true,
-}
-
-var x86_plan9Reg = [...]string{
-	x86_AL:   "AL",
-	x86_CL:   "CL",
-	x86_BL:   "BL",
-	x86_DL:   "DL",
-	x86_AH:   "AH",
-	x86_CH:   "CH",
-	x86_BH:   "BH",
-	x86_DH:   "DH",
-	x86_SPB:  "SP",
-	x86_BPB:  "BP",
-	x86_SIB:  "SI",
-	x86_DIB:  "DI",
-	x86_R8B:  "R8",
-	x86_R9B:  "R9",
-	x86_R10B: "R10",
-	x86_R11B: "R11",
-	x86_R12B: "R12",
-	x86_R13B: "R13",
-	x86_R14B: "R14",
-	x86_R15B: "R15",
-	x86_AX:   "AX",
-	x86_CX:   "CX",
-	x86_BX:   "BX",
-	x86_DX:   "DX",
-	x86_SP:   "SP",
-	x86_BP:   "BP",
-	x86_SI:   "SI",
-	x86_DI:   "DI",
-	x86_R8W:  "R8",
-	x86_R9W:  "R9",
-	x86_R10W: "R10",
-	x86_R11W: "R11",
-	x86_R12W: "R12",
-	x86_R13W: "R13",
-	x86_R14W: "R14",
-	x86_R15W: "R15",
-	x86_EAX:  "AX",
-	x86_ECX:  "CX",
-	x86_EDX:  "DX",
-	x86_EBX:  "BX",
-	x86_ESP:  "SP",
-	x86_EBP:  "BP",
-	x86_ESI:  "SI",
-	x86_EDI:  "DI",
-	x86_R8L:  "R8",
-	x86_R9L:  "R9",
-	x86_R10L: "R10",
-	x86_R11L: "R11",
-	x86_R12L: "R12",
-	x86_R13L: "R13",
-	x86_R14L: "R14",
-	x86_R15L: "R15",
-	x86_RAX:  "AX",
-	x86_RCX:  "CX",
-	x86_RDX:  "DX",
-	x86_RBX:  "BX",
-	x86_RSP:  "SP",
-	x86_RBP:  "BP",
-	x86_RSI:  "SI",
-	x86_RDI:  "DI",
-	x86_R8:   "R8",
-	x86_R9:   "R9",
-	x86_R10:  "R10",
-	x86_R11:  "R11",
-	x86_R12:  "R12",
-	x86_R13:  "R13",
-	x86_R14:  "R14",
-	x86_R15:  "R15",
-	x86_IP:   "IP",
-	x86_EIP:  "IP",
-	x86_RIP:  "IP",
-	x86_F0:   "F0",
-	x86_F1:   "F1",
-	x86_F2:   "F2",
-	x86_F3:   "F3",
-	x86_F4:   "F4",
-	x86_F5:   "F5",
-	x86_F6:   "F6",
-	x86_F7:   "F7",
-	x86_M0:   "M0",
-	x86_M1:   "M1",
-	x86_M2:   "M2",
-	x86_M3:   "M3",
-	x86_M4:   "M4",
-	x86_M5:   "M5",
-	x86_M6:   "M6",
-	x86_M7:   "M7",
-	x86_X0:   "X0",
-	x86_X1:   "X1",
-	x86_X2:   "X2",
-	x86_X3:   "X3",
-	x86_X4:   "X4",
-	x86_X5:   "X5",
-	x86_X6:   "X6",
-	x86_X7:   "X7",
-	x86_X8:   "X8",
-	x86_X9:   "X9",
-	x86_X10:  "X10",
-	x86_X11:  "X11",
-	x86_X12:  "X12",
-	x86_X13:  "X13",
-	x86_X14:  "X14",
-	x86_X15:  "X15",
-	x86_CS:   "CS",
-	x86_SS:   "SS",
-	x86_DS:   "DS",
-	x86_ES:   "ES",
-	x86_FS:   "FS",
-	x86_GS:   "GS",
-	x86_GDTR: "GDTR",
-	x86_IDTR: "IDTR",
-	x86_LDTR: "LDTR",
-	x86_MSW:  "MSW",
-	x86_TASK: "TASK",
-	x86_CR0:  "CR0",
-	x86_CR1:  "CR1",
-	x86_CR2:  "CR2",
-	x86_CR3:  "CR3",
-	x86_CR4:  "CR4",
-	x86_CR5:  "CR5",
-	x86_CR6:  "CR6",
-	x86_CR7:  "CR7",
-	x86_CR8:  "CR8",
-	x86_CR9:  "CR9",
-	x86_CR10: "CR10",
-	x86_CR11: "CR11",
-	x86_CR12: "CR12",
-	x86_CR13: "CR13",
-	x86_CR14: "CR14",
-	x86_CR15: "CR15",
-	x86_DR0:  "DR0",
-	x86_DR1:  "DR1",
-	x86_DR2:  "DR2",
-	x86_DR3:  "DR3",
-	x86_DR4:  "DR4",
-	x86_DR5:  "DR5",
-	x86_DR6:  "DR6",
-	x86_DR7:  "DR7",
-	x86_DR8:  "DR8",
-	x86_DR9:  "DR9",
-	x86_DR10: "DR10",
-	x86_DR11: "DR11",
-	x86_DR12: "DR12",
-	x86_DR13: "DR13",
-	x86_DR14: "DR14",
-	x86_DR15: "DR15",
-	x86_TR0:  "TR0",
-	x86_TR1:  "TR1",
-	x86_TR2:  "TR2",
-	x86_TR3:  "TR3",
-	x86_TR4:  "TR4",
-	x86_TR5:  "TR5",
-	x86_TR6:  "TR6",
-	x86_TR7:  "TR7",
-}
-
-/* tables.go */
-
-// DO NOT EDIT
-// generated by: x86map -fmt=decoder ../x86.csv
-
-var x86_decoder = [...]uint16{
-	uint16(x86_xFail),
-	/*1*/ uint16(x86_xCondByte), 243,
-	0x00, 490,
-	0x01, 496,
-	0x02, 525,
-	0x03, 531,
-	0x04, 560,
-	0x05, 566,
-	0x06, 595,
-	0x07, 602,
-	0x08, 609,
-	0x09, 615,
-	0x0A, 644,
-	0x0B, 650,
-	0x0C, 679,
-	0x0D, 685,
-	0x0E, 714,
-	0x0F, 721,
-	0x10, 8026,
-	0x11, 8032,
-	0x12, 8061,
-	0x13, 8067,
-	0x14, 8096,
-	0x15, 8102,
-	0x16, 8131,
-	0x17, 8138,
-	0x18, 8145,
-	0x19, 8151,
-	0x1A, 8180,
-	0x1B, 8186,
-	0x1C, 8215,
-	0x1D, 8221,
-	0x1E, 8250,
-	0x1F, 8257,
-	0x20, 8264,
-	0x21, 8270,
-	0x22, 8299,
-	0x23, 8305,
-	0x24, 8334,
-	0x25, 8340,
-	0x27, 8369,
-	0x28, 8375,
-	0x29, 8381,
-	0x2A, 8410,
-	0x2B, 8416,
-	0x2C, 8445,
-	0x2D, 8451,
-	0x2F, 8480,
-	0x30, 8486,
-	0x31, 8492,
-	0x32, 8521,
-	0x33, 8527,
-	0x34, 8556,
-	0x35, 8562,
-	0x37, 8591,
-	0x38, 8597,
-	0x39, 8603,
-	0x3A, 8632,
-	0x3B, 8638,
-	0x3C, 8667,
-	0x3D, 8673,
-	0x3F, 8702,
-	0x40, 8708,
-	0x41, 8708,
-	0x42, 8708,
-	0x43, 8708,
-	0x44, 8708,
-	0x45, 8708,
-	0x46, 8708,
-	0x47, 8708,
-	0x48, 8723,
-	0x49, 8723,
-	0x4a, 8723,
-	0x4b, 8723,
-	0x4c, 8723,
-	0x4d, 8723,
-	0x4e, 8723,
-	0x4f, 8723,
-	0x50, 8738,
-	0x51, 8738,
-	0x52, 8738,
-	0x53, 8738,
-	0x54, 8738,
-	0x55, 8738,
-	0x56, 8738,
-	0x57, 8738,
-	0x58, 8765,
-	0x59, 8765,
-	0x5a, 8765,
-	0x5b, 8765,
-	0x5c, 8765,
-	0x5d, 8765,
-	0x5e, 8765,
-	0x5f, 8765,
-	0x60, 8792,
-	0x61, 8805,
-	0x62, 8818,
-	0x63, 8837,
-	0x68, 8868,
-	0x69, 8887,
-	0x6A, 8922,
-	0x6B, 8927,
-	0x6C, 8962,
-	0x6D, 8965,
-	0x6E, 8978,
-	0x6F, 8981,
-	0x70, 8994,
-	0x71, 8999,
-	0x72, 9004,
-	0x73, 9009,
-	0x74, 9014,
-	0x75, 9019,
-	0x76, 9024,
-	0x77, 9029,
-	0x78, 9034,
-	0x79, 9039,
-	0x7A, 9044,
-	0x7B, 9049,
-	0x7C, 9054,
-	0x7D, 9059,
-	0x7E, 9064,
-	0x7F, 9069,
-	0x80, 9074,
-	0x81, 9131,
-	0x83, 9372,
-	0x84, 9613,
-	0x85, 9619,
-	0x86, 9648,
-	0x87, 9654,
-	0x88, 9683,
-	0x89, 9689,
-	0x8A, 9711,
-	0x8B, 9717,
-	0x8C, 9739,
-	0x8D, 9768,
-	0x8E, 9797,
-	0x8F, 9826,
-	0x90, 9862,
-	0x91, 9862,
-	0x92, 9862,
-	0x93, 9862,
-	0x94, 9862,
-	0x95, 9862,
-	0x96, 9862,
-	0x97, 9862,
-	0x98, 9888,
-	0x99, 9908,
-	0x9A, 9928,
-	0x9B, 9945,
-	0x9C, 9948,
-	0x9D, 9971,
-	0x9E, 9994,
-	0x9F, 9997,
-	0xA0, 10000,
-	0xA1, 10019,
-	0xA2, 10041,
-	0xA3, 10060,
-	0xA4, 10082,
-	0xA5, 10085,
-	0xA6, 10105,
-	0xA7, 10108,
-	0xA8, 10128,
-	0xA9, 10134,
-	0xAA, 10163,
-	0xAB, 10166,
-	0xAC, 10186,
-	0xAD, 10189,
-	0xAE, 10209,
-	0xAF, 10212,
-	0xb0, 10232,
-	0xb1, 10232,
-	0xb2, 10232,
-	0xb3, 10232,
-	0xb4, 10232,
-	0xb5, 10232,
-	0xb6, 10232,
-	0xb7, 10232,
-	0xb8, 10238,
-	0xb9, 10238,
-	0xba, 10238,
-	0xbb, 10238,
-	0xbc, 10238,
-	0xbd, 10238,
-	0xbe, 10238,
-	0xbf, 10238,
-	0xC0, 10267,
-	0xC1, 10318,
-	0xC2, 10516,
-	0xC3, 10521,
-	0xC4, 10524,
-	0xC5, 10543,
-	0xC6, 10562,
-	0xC7, 10586,
-	0xC8, 10647,
-	0xC9, 10654,
-	0xCA, 10677,
-	0xCB, 10682,
-	0xCC, 10685,
-	0xCD, 10689,
-	0xCE, 10694,
-	0xCF, 10700,
-	0xD0, 10720,
-	0xD1, 10764,
-	0xD2, 10955,
-	0xD3, 10999,
-	0xD4, 11190,
-	0xD5, 11198,
-	0xD7, 11206,
-	0xD8, 11219,
-	0xD9, 11428,
-	0xDA, 11637,
-	0xDB, 11769,
-	0xDC, 11940,
-	0xDD, 12109,
-	0xDE, 12248,
-	0xDF, 12422,
-	0xE0, 12533,
-	0xE1, 12538,
-	0xE2, 12543,
-	0xE3, 12548,
-	0xE4, 12574,
-	0xE5, 12580,
-	0xE6, 12602,
-	0xE7, 12608,
-	0xE8, 12630,
-	0xE9, 12661,
-	0xEA, 12692,
-	0xEB, 12709,
-	0xEC, 12714,
-	0xED, 12719,
-	0xEE, 12738,
-	0xEF, 12743,
-	0xF1, 12762,
-	0xF4, 12765,
-	0xF5, 12768,
-	0xF6, 12771,
-	0xF7, 12810,
-	0xF8, 12986,
-	0xF9, 12989,
-	0xFA, 12992,
-	0xFB, 12995,
-	0xFC, 12998,
-	0xFD, 13001,
-	0xFE, 13004,
-	0xFF, 13021,
-	uint16(x86_xFail),
-	/*490*/ uint16(x86_xSetOp), uint16(x86_ADD),
-	/*492*/ uint16(x86_xReadSlashR),
-	/*493*/ uint16(x86_xArgRM8),
-	/*494*/ uint16(x86_xArgR8),
-	/*495*/ uint16(x86_xMatch),
-	/*496*/ uint16(x86_xCondIs64), 499, 515,
-	/*499*/ uint16(x86_xCondDataSize), 503, 509, 0,
-	/*503*/ uint16(x86_xSetOp), uint16(x86_ADD),
-	/*505*/ uint16(x86_xReadSlashR),
-	/*506*/ uint16(x86_xArgRM16),
-	/*507*/ uint16(x86_xArgR16),
-	/*508*/ uint16(x86_xMatch),
-	/*509*/ uint16(x86_xSetOp), uint16(x86_ADD),
-	/*511*/ uint16(x86_xReadSlashR),
-	/*512*/ uint16(x86_xArgRM32),
-	/*513*/ uint16(x86_xArgR32),
-	/*514*/ uint16(x86_xMatch),
-	/*515*/ uint16(x86_xCondDataSize), 503, 509, 519,
-	/*519*/ uint16(x86_xSetOp), uint16(x86_ADD),
-	/*521*/ uint16(x86_xReadSlashR),
-	/*522*/ uint16(x86_xArgRM64),
-	/*523*/ uint16(x86_xArgR64),
-	/*524*/ uint16(x86_xMatch),
-	/*525*/ uint16(x86_xSetOp), uint16(x86_ADD),
-	/*527*/ uint16(x86_xReadSlashR),
-	/*528*/ uint16(x86_xArgR8),
-	/*529*/ uint16(x86_xArgRM8),
-	/*530*/ uint16(x86_xMatch),
-	/*531*/ uint16(x86_xCondIs64), 534, 550,
-	/*534*/ uint16(x86_xCondDataSize), 538, 544, 0,
-	/*538*/ uint16(x86_xSetOp), uint16(x86_ADD),
-	/*540*/ uint16(x86_xReadSlashR),
-	/*541*/ uint16(x86_xArgR16),
-	/*542*/ uint16(x86_xArgRM16),
-	/*543*/ uint16(x86_xMatch),
-	/*544*/ uint16(x86_xSetOp), uint16(x86_ADD),
-	/*546*/ uint16(x86_xReadSlashR),
-	/*547*/ uint16(x86_xArgR32),
-	/*548*/ uint16(x86_xArgRM32),
-	/*549*/ uint16(x86_xMatch),
-	/*550*/ uint16(x86_xCondDataSize), 538, 544, 554,
-	/*554*/ uint16(x86_xSetOp), uint16(x86_ADD),
-	/*556*/ uint16(x86_xReadSlashR),
-	/*557*/ uint16(x86_xArgR64),
-	/*558*/ uint16(x86_xArgRM64),
-	/*559*/ uint16(x86_xMatch),
-	/*560*/ uint16(x86_xSetOp), uint16(x86_ADD),
-	/*562*/ uint16(x86_xReadIb),
-	/*563*/ uint16(x86_xArgAL),
-	/*564*/ uint16(x86_xArgImm8u),
-	/*565*/ uint16(x86_xMatch),
-	/*566*/ uint16(x86_xCondIs64), 569, 585,
-	/*569*/ uint16(x86_xCondDataSize), 573, 579, 0,
-	/*573*/ uint16(x86_xSetOp), uint16(x86_ADD),
-	/*575*/ uint16(x86_xReadIw),
-	/*576*/ uint16(x86_xArgAX),
-	/*577*/ uint16(x86_xArgImm16),
-	/*578*/ uint16(x86_xMatch),
-	/*579*/ uint16(x86_xSetOp), uint16(x86_ADD),
-	/*581*/ uint16(x86_xReadId),
-	/*582*/ uint16(x86_xArgEAX),
-	/*583*/ uint16(x86_xArgImm32),
-	/*584*/ uint16(x86_xMatch),
-	/*585*/ uint16(x86_xCondDataSize), 573, 579, 589,
-	/*589*/ uint16(x86_xSetOp), uint16(x86_ADD),
-	/*591*/ uint16(x86_xReadId),
-	/*592*/ uint16(x86_xArgRAX),
-	/*593*/ uint16(x86_xArgImm32),
-	/*594*/ uint16(x86_xMatch),
-	/*595*/ uint16(x86_xCondIs64), 598, 0,
-	/*598*/ uint16(x86_xSetOp), uint16(x86_PUSH),
-	/*600*/ uint16(x86_xArgES),
-	/*601*/ uint16(x86_xMatch),
-	/*602*/ uint16(x86_xCondIs64), 605, 0,
-	/*605*/ uint16(x86_xSetOp), uint16(x86_POP),
-	/*607*/ uint16(x86_xArgES),
-	/*608*/ uint16(x86_xMatch),
-	/*609*/ uint16(x86_xSetOp), uint16(x86_OR),
-	/*611*/ uint16(x86_xReadSlashR),
-	/*612*/ uint16(x86_xArgRM8),
-	/*613*/ uint16(x86_xArgR8),
-	/*614*/ uint16(x86_xMatch),
-	/*615*/ uint16(x86_xCondIs64), 618, 634,
-	/*618*/ uint16(x86_xCondDataSize), 622, 628, 0,
-	/*622*/ uint16(x86_xSetOp), uint16(x86_OR),
-	/*624*/ uint16(x86_xReadSlashR),
-	/*625*/ uint16(x86_xArgRM16),
-	/*626*/ uint16(x86_xArgR16),
-	/*627*/ uint16(x86_xMatch),
-	/*628*/ uint16(x86_xSetOp), uint16(x86_OR),
-	/*630*/ uint16(x86_xReadSlashR),
-	/*631*/ uint16(x86_xArgRM32),
-	/*632*/ uint16(x86_xArgR32),
-	/*633*/ uint16(x86_xMatch),
-	/*634*/ uint16(x86_xCondDataSize), 622, 628, 638,
-	/*638*/ uint16(x86_xSetOp), uint16(x86_OR),
-	/*640*/ uint16(x86_xReadSlashR),
-	/*641*/ uint16(x86_xArgRM64),
-	/*642*/ uint16(x86_xArgR64),
-	/*643*/ uint16(x86_xMatch),
-	/*644*/ uint16(x86_xSetOp), uint16(x86_OR),
-	/*646*/ uint16(x86_xReadSlashR),
-	/*647*/ uint16(x86_xArgR8),
-	/*648*/ uint16(x86_xArgRM8),
-	/*649*/ uint16(x86_xMatch),
-	/*650*/ uint16(x86_xCondIs64), 653, 669,
-	/*653*/ uint16(x86_xCondDataSize), 657, 663, 0,
-	/*657*/ uint16(x86_xSetOp), uint16(x86_OR),
-	/*659*/ uint16(x86_xReadSlashR),
-	/*660*/ uint16(x86_xArgR16),
-	/*661*/ uint16(x86_xArgRM16),
-	/*662*/ uint16(x86_xMatch),
-	/*663*/ uint16(x86_xSetOp), uint16(x86_OR),
-	/*665*/ uint16(x86_xReadSlashR),
-	/*666*/ uint16(x86_xArgR32),
-	/*667*/ uint16(x86_xArgRM32),
-	/*668*/ uint16(x86_xMatch),
-	/*669*/ uint16(x86_xCondDataSize), 657, 663, 673,
-	/*673*/ uint16(x86_xSetOp), uint16(x86_OR),
-	/*675*/ uint16(x86_xReadSlashR),
-	/*676*/ uint16(x86_xArgR64),
-	/*677*/ uint16(x86_xArgRM64),
-	/*678*/ uint16(x86_xMatch),
-	/*679*/ uint16(x86_xSetOp), uint16(x86_OR),
-	/*681*/ uint16(x86_xReadIb),
-	/*682*/ uint16(x86_xArgAL),
-	/*683*/ uint16(x86_xArgImm8u),
-	/*684*/ uint16(x86_xMatch),
-	/*685*/ uint16(x86_xCondIs64), 688, 704,
-	/*688*/ uint16(x86_xCondDataSize), 692, 698, 0,
-	/*692*/ uint16(x86_xSetOp), uint16(x86_OR),
-	/*694*/ uint16(x86_xReadIw),
-	/*695*/ uint16(x86_xArgAX),
-	/*696*/ uint16(x86_xArgImm16),
-	/*697*/ uint16(x86_xMatch),
-	/*698*/ uint16(x86_xSetOp), uint16(x86_OR),
-	/*700*/ uint16(x86_xReadId),
-	/*701*/ uint16(x86_xArgEAX),
-	/*702*/ uint16(x86_xArgImm32),
-	/*703*/ uint16(x86_xMatch),
-	/*704*/ uint16(x86_xCondDataSize), 692, 698, 708,
-	/*708*/ uint16(x86_xSetOp), uint16(x86_OR),
-	/*710*/ uint16(x86_xReadId),
-	/*711*/ uint16(x86_xArgRAX),
-	/*712*/ uint16(x86_xArgImm32),
-	/*713*/ uint16(x86_xMatch),
-	/*714*/ uint16(x86_xCondIs64), 717, 0,
-	/*717*/ uint16(x86_xSetOp), uint16(x86_PUSH),
-	/*719*/ uint16(x86_xArgCS),
-	/*720*/ uint16(x86_xMatch),
-	/*721*/ uint16(x86_xCondByte), 228,
-	0x00, 1180,
-	0x01, 1237,
-	0x02, 1345,
-	0x03, 1367,
-	0x05, 1389,
-	0x06, 1395,
-	0x07, 1398,
-	0x08, 1404,
-	0x09, 1407,
-	0x0B, 1410,
-	0x0D, 1413,
-	0x10, 1426,
-	0x11, 1460,
-	0x12, 1494,
-	0x13, 1537,
-	0x14, 1555,
-	0x15, 1573,
-	0x16, 1591,
-	0x17, 1626,
-	0x18, 1644,
-	0x1F, 1669,
-	0x20, 1690,
-	0x21, 1705,
-	0x22, 1720,
-	0x23, 1735,
-	0x24, 1750,
-	0x26, 1765,
-	0x28, 1780,
-	0x29, 1798,
-	0x2A, 1816,
-	0x2B, 1903,
-	0x2C, 1937,
-	0x2D, 2024,
-	0x2E, 2111,
-	0x2F, 2129,
-	0x30, 2147,
-	0x31, 2150,
-	0x32, 2153,
-	0x33, 2156,
-	0x34, 2159,
-	0x35, 2162,
-	0x38, 2172,
-	0x3A, 3073,
-	0x40, 3484,
-	0x41, 3513,
-	0x42, 3542,
-	0x43, 3571,
-	0x44, 3600,
-	0x45, 3629,
-	0x46, 3658,
-	0x47, 3687,
-	0x48, 3716,
-	0x49, 3745,
-	0x4A, 3774,
-	0x4B, 3803,
-	0x4C, 3832,
-	0x4D, 3861,
-	0x4E, 3890,
-	0x4F, 3919,
-	0x50, 3948,
-	0x51, 3966,
-	0x52, 4000,
-	0x53, 4018,
-	0x54, 4036,
-	0x55, 4054,
-	0x56, 4072,
-	0x57, 4090,
-	0x58, 4108,
-	0x59, 4142,
-	0x5A, 4176,
-	0x5B, 4210,
-	0x5C, 4236,
-	0x5D, 4270,
-	0x5E, 4304,
-	0x5F, 4338,
-	0x60, 4372,
-	0x61, 4390,
-	0x62, 4408,
-	0x63, 4426,
-	0x64, 4444,
-	0x65, 4462,
-	0x66, 4480,
-	0x67, 4498,
-	0x68, 4516,
-	0x69, 4534,
-	0x6A, 4552,
-	0x6B, 4570,
-	0x6C, 4588,
-	0x6D, 4598,
-	0x6E, 4608,
-	0x6F, 4675,
-	0x70, 4701,
-	0x71, 4743,
-	0x72, 4806,
-	0x73, 4869,
-	0x74, 4934,
-	0x75, 4952,
-	0x76, 4970,
-	0x77, 4988,
-	0x7C, 4991,
-	0x7D, 5009,
-	0x7E, 5027,
-	0x7F, 5104,
-	0x80, 5130,
-	0x81, 5161,
-	0x82, 5192,
-	0x83, 5223,
-	0x84, 5254,
-	0x85, 5285,
-	0x86, 5316,
-	0x87, 5347,
-	0x88, 5378,
-	0x89, 5409,
-	0x8A, 5440,
-	0x8B, 5471,
-	0x8C, 5502,
-	0x8D, 5533,
-	0x8E, 5564,
-	0x8F, 5595,
-	0x90, 5626,
-	0x91, 5631,
-	0x92, 5636,
-	0x93, 5641,
-	0x94, 5646,
-	0x95, 5651,
-	0x96, 5656,
-	0x97, 5661,
-	0x98, 5666,
-	0x99, 5671,
-	0x9A, 5676,
-	0x9B, 5681,
-	0x9C, 5686,
-	0x9D, 5691,
-	0x9E, 5696,
-	0x9F, 5701,
-	0xA0, 5706,
-	0xA1, 5710,
-	0xA2, 5737,
-	0xA3, 5740,
-	0xA4, 5769,
-	0xA5, 5804,
-	0xA8, 5836,
-	0xA9, 5840,
-	0xAA, 5867,
-	0xAB, 5870,
-	0xAC, 5899,
-	0xAD, 5934,
-	0xAE, 5966,
-	0xAF, 6224,
-	0xB0, 6253,
-	0xB1, 6259,
-	0xB2, 6288,
-	0xB3, 6317,
-	0xB4, 6346,
-	0xB5, 6375,
-	0xB6, 6404,
-	0xB7, 6433,
-	0xB8, 6462,
-	0xB9, 6499,
-	0xBA, 6502,
-	0xBB, 6627,
-	0xBC, 6656,
-	0xBD, 6723,
-	0xBE, 6790,
-	0xBF, 6819,
-	0xC0, 6848,
-	0xC1, 6854,
-	0xC2, 6883,
-	0xC3, 6925,
-	0xC4, 6954,
-	0xC5, 6976,
-	0xC6, 6998,
-	0xC7, 7020,
-	0xc8, 7149,
-	0xc9, 7149,
-	0xca, 7149,
-	0xcb, 7149,
-	0xcc, 7149,
-	0xcd, 7149,
-	0xce, 7149,
-	0xcf, 7149,
-	0xD0, 7172,
-	0xD1, 7190,
-	0xD2, 7208,
-	0xD3, 7226,
-	0xD4, 7244,
-	0xD5, 7262,
-	0xD6, 7280,
-	0xD7, 7306,
-	0xD8, 7324,
-	0xD9, 7342,
-	0xDA, 7360,
-	0xDB, 7378,
-	0xDC, 7396,
-	0xDD, 7414,
-	0xDE, 7432,
-	0xDF, 7450,
-	0xE0, 7468,
-	0xE1, 7486,
-	0xE2, 7504,
-	0xE3, 7522,
-	0xE4, 7540,
-	0xE5, 7558,
-	0xE6, 7576,
-	0xE7, 7602,
-	0xE8, 7620,
-	0xE9, 7638,
-	0xEA, 7656,
-	0xEB, 7674,
-	0xEC, 7692,
-	0xED, 7710,
-	0xEE, 7728,
-	0xEF, 7746,
-	0xF0, 7764,
-	0xF1, 7774,
-	0xF2, 7792,
-	0xF3, 7810,
-	0xF4, 7828,
-	0xF5, 7846,
-	0xF6, 7864,
-	0xF7, 7882,
-	0xF8, 7900,
-	0xF9, 7918,
-	0xFA, 7936,
-	0xFB, 7954,
-	0xFC, 7972,
-	0xFD, 7990,
-	0xFE, 8008,
-	uint16(x86_xFail),
-	/*1180*/ uint16(x86_xCondSlashR),
-	1189, // 0
-	1205, // 1
-	1221, // 2
-	1225, // 3
-	1229, // 4
-	1233, // 5
-	0,    // 6
-	0,    // 7
-	/*1189*/ uint16(x86_xCondDataSize), 1193, 1197, 1201,
-	/*1193*/ uint16(x86_xSetOp), uint16(x86_SLDT),
-	/*1195*/ uint16(x86_xArgRM16),
-	/*1196*/ uint16(x86_xMatch),
-	/*1197*/ uint16(x86_xSetOp), uint16(x86_SLDT),
-	/*1199*/ uint16(x86_xArgR32M16),
-	/*1200*/ uint16(x86_xMatch),
-	/*1201*/ uint16(x86_xSetOp), uint16(x86_SLDT),
-	/*1203*/ uint16(x86_xArgR64M16),
-	/*1204*/ uint16(x86_xMatch),
-	/*1205*/ uint16(x86_xCondDataSize), 1209, 1213, 1217,
-	/*1209*/ uint16(x86_xSetOp), uint16(x86_STR),
-	/*1211*/ uint16(x86_xArgRM16),
-	/*1212*/ uint16(x86_xMatch),
-	/*1213*/ uint16(x86_xSetOp), uint16(x86_STR),
-	/*1215*/ uint16(x86_xArgR32M16),
-	/*1216*/ uint16(x86_xMatch),
-	/*1217*/ uint16(x86_xSetOp), uint16(x86_STR),
-	/*1219*/ uint16(x86_xArgR64M16),
-	/*1220*/ uint16(x86_xMatch),
-	/*1221*/ uint16(x86_xSetOp), uint16(x86_LLDT),
-	/*1223*/ uint16(x86_xArgRM16),
-	/*1224*/ uint16(x86_xMatch),
-	/*1225*/ uint16(x86_xSetOp), uint16(x86_LTR),
-	/*1227*/ uint16(x86_xArgRM16),
-	/*1228*/ uint16(x86_xMatch),
-	/*1229*/ uint16(x86_xSetOp), uint16(x86_VERR),
-	/*1231*/ uint16(x86_xArgRM16),
-	/*1232*/ uint16(x86_xMatch),
-	/*1233*/ uint16(x86_xSetOp), uint16(x86_VERW),
-	/*1235*/ uint16(x86_xArgRM16),
-	/*1236*/ uint16(x86_xMatch),
-	/*1237*/ uint16(x86_xCondByte), 8,
-	0xC8, 1318,
-	0xC9, 1321,
-	0xD0, 1324,
-	0xD1, 1327,
-	0xD5, 1330,
-	0xD6, 1333,
-	0xF8, 1336,
-	0xF9, 1342,
-	/*1255*/ uint16(x86_xCondSlashR),
-	1264, // 0
-	1268, // 1
-	1272, // 2
-	1283, // 3
-	1294, // 4
-	0,    // 5
-	1310, // 6
-	1314, // 7
-	/*1264*/ uint16(x86_xSetOp), uint16(x86_SGDT),
-	/*1266*/ uint16(x86_xArgM),
-	/*1267*/ uint16(x86_xMatch),
-	/*1268*/ uint16(x86_xSetOp), uint16(x86_SIDT),
-	/*1270*/ uint16(x86_xArgM),
-	/*1271*/ uint16(x86_xMatch),
-	/*1272*/ uint16(x86_xCondIs64), 1275, 1279,
-	/*1275*/ uint16(x86_xSetOp), uint16(x86_LGDT),
-	/*1277*/ uint16(x86_xArgM16and32),
-	/*1278*/ uint16(x86_xMatch),
-	/*1279*/ uint16(x86_xSetOp), uint16(x86_LGDT),
-	/*1281*/ uint16(x86_xArgM16and64),
-	/*1282*/ uint16(x86_xMatch),
-	/*1283*/ uint16(x86_xCondIs64), 1286, 1290,
-	/*1286*/ uint16(x86_xSetOp), uint16(x86_LIDT),
-	/*1288*/ uint16(x86_xArgM16and32),
-	/*1289*/ uint16(x86_xMatch),
-	/*1290*/ uint16(x86_xSetOp), uint16(x86_LIDT),
-	/*1292*/ uint16(x86_xArgM16and64),
-	/*1293*/ uint16(x86_xMatch),
-	/*1294*/ uint16(x86_xCondDataSize), 1298, 1302, 1306,
-	/*1298*/ uint16(x86_xSetOp), uint16(x86_SMSW),
-	/*1300*/ uint16(x86_xArgRM16),
-	/*1301*/ uint16(x86_xMatch),
-	/*1302*/ uint16(x86_xSetOp), uint16(x86_SMSW),
-	/*1304*/ uint16(x86_xArgR32M16),
-	/*1305*/ uint16(x86_xMatch),
-	/*1306*/ uint16(x86_xSetOp), uint16(x86_SMSW),
-	/*1308*/ uint16(x86_xArgR64M16),
-	/*1309*/ uint16(x86_xMatch),
-	/*1310*/ uint16(x86_xSetOp), uint16(x86_LMSW),
-	/*1312*/ uint16(x86_xArgRM16),
-	/*1313*/ uint16(x86_xMatch),
-	/*1314*/ uint16(x86_xSetOp), uint16(x86_INVLPG),
-	/*1316*/ uint16(x86_xArgM),
-	/*1317*/ uint16(x86_xMatch),
-	/*1318*/ uint16(x86_xSetOp), uint16(x86_MONITOR),
-	/*1320*/ uint16(x86_xMatch),
-	/*1321*/ uint16(x86_xSetOp), uint16(x86_MWAIT),
-	/*1323*/ uint16(x86_xMatch),
-	/*1324*/ uint16(x86_xSetOp), uint16(x86_XGETBV),
-	/*1326*/ uint16(x86_xMatch),
-	/*1327*/ uint16(x86_xSetOp), uint16(x86_XSETBV),
-	/*1329*/ uint16(x86_xMatch),
-	/*1330*/ uint16(x86_xSetOp), uint16(x86_XEND),
-	/*1332*/ uint16(x86_xMatch),
-	/*1333*/ uint16(x86_xSetOp), uint16(x86_XTEST),
-	/*1335*/ uint16(x86_xMatch),
-	/*1336*/ uint16(x86_xCondIs64), 0, 1339,
-	/*1339*/ uint16(x86_xSetOp), uint16(x86_SWAPGS),
-	/*1341*/ uint16(x86_xMatch),
-	/*1342*/ uint16(x86_xSetOp), uint16(x86_RDTSCP),
-	/*1344*/ uint16(x86_xMatch),
-	/*1345*/ uint16(x86_xCondDataSize), 1349, 1355, 1361,
-	/*1349*/ uint16(x86_xSetOp), uint16(x86_LAR),
-	/*1351*/ uint16(x86_xReadSlashR),
-	/*1352*/ uint16(x86_xArgR16),
-	/*1353*/ uint16(x86_xArgRM16),
-	/*1354*/ uint16(x86_xMatch),
-	/*1355*/ uint16(x86_xSetOp), uint16(x86_LAR),
-	/*1357*/ uint16(x86_xReadSlashR),
-	/*1358*/ uint16(x86_xArgR32),
-	/*1359*/ uint16(x86_xArgR32M16),
-	/*1360*/ uint16(x86_xMatch),
-	/*1361*/ uint16(x86_xSetOp), uint16(x86_LAR),
-	/*1363*/ uint16(x86_xReadSlashR),
-	/*1364*/ uint16(x86_xArgR64),
-	/*1365*/ uint16(x86_xArgR64M16),
-	/*1366*/ uint16(x86_xMatch),
-	/*1367*/ uint16(x86_xCondDataSize), 1371, 1377, 1383,
-	/*1371*/ uint16(x86_xSetOp), uint16(x86_LSL),
-	/*1373*/ uint16(x86_xReadSlashR),
-	/*1374*/ uint16(x86_xArgR16),
-	/*1375*/ uint16(x86_xArgRM16),
-	/*1376*/ uint16(x86_xMatch),
-	/*1377*/ uint16(x86_xSetOp), uint16(x86_LSL),
-	/*1379*/ uint16(x86_xReadSlashR),
-	/*1380*/ uint16(x86_xArgR32),
-	/*1381*/ uint16(x86_xArgR32M16),
-	/*1382*/ uint16(x86_xMatch),
-	/*1383*/ uint16(x86_xSetOp), uint16(x86_LSL),
-	/*1385*/ uint16(x86_xReadSlashR),
-	/*1386*/ uint16(x86_xArgR64),
-	/*1387*/ uint16(x86_xArgR32M16),
-	/*1388*/ uint16(x86_xMatch),
-	/*1389*/ uint16(x86_xCondIs64), 0, 1392,
-	/*1392*/ uint16(x86_xSetOp), uint16(x86_SYSCALL),
-	/*1394*/ uint16(x86_xMatch),
-	/*1395*/ uint16(x86_xSetOp), uint16(x86_CLTS),
-	/*1397*/ uint16(x86_xMatch),
-	/*1398*/ uint16(x86_xCondIs64), 0, 1401,
-	/*1401*/ uint16(x86_xSetOp), uint16(x86_SYSRET),
-	/*1403*/ uint16(x86_xMatch),
-	/*1404*/ uint16(x86_xSetOp), uint16(x86_INVD),
-	/*1406*/ uint16(x86_xMatch),
-	/*1407*/ uint16(x86_xSetOp), uint16(x86_WBINVD),
-	/*1409*/ uint16(x86_xMatch),
-	/*1410*/ uint16(x86_xSetOp), uint16(x86_UD2),
-	/*1412*/ uint16(x86_xMatch),
-	/*1413*/ uint16(x86_xCondSlashR),
-	0,    // 0
-	1422, // 1
-	0,    // 2
-	0,    // 3
-	0,    // 4
-	0,    // 5
-	0,    // 6
-	0,    // 7
-	/*1422*/ uint16(x86_xSetOp), uint16(x86_PREFETCHW),
-	/*1424*/ uint16(x86_xArgM8),
-	/*1425*/ uint16(x86_xMatch),
-	/*1426*/ uint16(x86_xCondPrefix), 4,
-	0xF3, 1454,
-	0xF2, 1448,
-	0x66, 1442,
-	0x0, 1436,
-	/*1436*/ uint16(x86_xSetOp), uint16(x86_MOVUPS),
-	/*1438*/ uint16(x86_xReadSlashR),
-	/*1439*/ uint16(x86_xArgXmm1),
-	/*1440*/ uint16(x86_xArgXmm2M128),
-	/*1441*/ uint16(x86_xMatch),
-	/*1442*/ uint16(x86_xSetOp), uint16(x86_MOVUPD),
-	/*1444*/ uint16(x86_xReadSlashR),
-	/*1445*/ uint16(x86_xArgXmm1),
-	/*1446*/ uint16(x86_xArgXmm2M128),
-	/*1447*/ uint16(x86_xMatch),
-	/*1448*/ uint16(x86_xSetOp), uint16(x86_MOVSD_XMM),
-	/*1450*/ uint16(x86_xReadSlashR),
-	/*1451*/ uint16(x86_xArgXmm1),
-	/*1452*/ uint16(x86_xArgXmm2M64),
-	/*1453*/ uint16(x86_xMatch),
-	/*1454*/ uint16(x86_xSetOp), uint16(x86_MOVSS),
-	/*1456*/ uint16(x86_xReadSlashR),
-	/*1457*/ uint16(x86_xArgXmm1),
-	/*1458*/ uint16(x86_xArgXmm2M32),
-	/*1459*/ uint16(x86_xMatch),
-	/*1460*/ uint16(x86_xCondPrefix), 4,
-	0xF3, 1488,
-	0xF2, 1482,
-	0x66, 1476,
-	0x0, 1470,
-	/*1470*/ uint16(x86_xSetOp), uint16(x86_MOVUPS),
-	/*1472*/ uint16(x86_xReadSlashR),
-	/*1473*/ uint16(x86_xArgXmm2M128),
-	/*1474*/ uint16(x86_xArgXmm1),
-	/*1475*/ uint16(x86_xMatch),
-	/*1476*/ uint16(x86_xSetOp), uint16(x86_MOVUPD),
-	/*1478*/ uint16(x86_xReadSlashR),
-	/*1479*/ uint16(x86_xArgXmm2M128),
-	/*1480*/ uint16(x86_xArgXmm),
-	/*1481*/ uint16(x86_xMatch),
-	/*1482*/ uint16(x86_xSetOp), uint16(x86_MOVSD_XMM),
-	/*1484*/ uint16(x86_xReadSlashR),
-	/*1485*/ uint16(x86_xArgXmm2M64),
-	/*1486*/ uint16(x86_xArgXmm1),
-	/*1487*/ uint16(x86_xMatch),
-	/*1488*/ uint16(x86_xSetOp), uint16(x86_MOVSS),
-	/*1490*/ uint16(x86_xReadSlashR),
-	/*1491*/ uint16(x86_xArgXmm2M32),
-	/*1492*/ uint16(x86_xArgXmm),
-	/*1493*/ uint16(x86_xMatch),
-	/*1494*/ uint16(x86_xCondPrefix), 4,
-	0xF3, 1531,
-	0xF2, 1525,
-	0x66, 1519,
-	0x0, 1504,
-	/*1504*/ uint16(x86_xCondIsMem), 1507, 1513,
-	/*1507*/ uint16(x86_xSetOp), uint16(x86_MOVHLPS),
-	/*1509*/ uint16(x86_xReadSlashR),
-	/*1510*/ uint16(x86_xArgXmm1),
-	/*1511*/ uint16(x86_xArgXmm2),
-	/*1512*/ uint16(x86_xMatch),
-	/*1513*/ uint16(x86_xSetOp), uint16(x86_MOVLPS),
-	/*1515*/ uint16(x86_xReadSlashR),
-	/*1516*/ uint16(x86_xArgXmm),
-	/*1517*/ uint16(x86_xArgM64),
-	/*1518*/ uint16(x86_xMatch),
-	/*1519*/ uint16(x86_xSetOp), uint16(x86_MOVLPD),
-	/*1521*/ uint16(x86_xReadSlashR),
-	/*1522*/ uint16(x86_xArgXmm),
-	/*1523*/ uint16(x86_xArgXmm2M64),
-	/*1524*/ uint16(x86_xMatch),
-	/*1525*/ uint16(x86_xSetOp), uint16(x86_MOVDDUP),
-	/*1527*/ uint16(x86_xReadSlashR),
-	/*1528*/ uint16(x86_xArgXmm1),
-	/*1529*/ uint16(x86_xArgXmm2M64),
-	/*1530*/ uint16(x86_xMatch),
-	/*1531*/ uint16(x86_xSetOp), uint16(x86_MOVSLDUP),
-	/*1533*/ uint16(x86_xReadSlashR),
-	/*1534*/ uint16(x86_xArgXmm1),
-	/*1535*/ uint16(x86_xArgXmm2M128),
-	/*1536*/ uint16(x86_xMatch),
-	/*1537*/ uint16(x86_xCondPrefix), 2,
-	0x66, 1549,
-	0x0, 1543,
-	/*1543*/ uint16(x86_xSetOp), uint16(x86_MOVLPS),
-	/*1545*/ uint16(x86_xReadSlashR),
-	/*1546*/ uint16(x86_xArgM64),
-	/*1547*/ uint16(x86_xArgXmm),
-	/*1548*/ uint16(x86_xMatch),
-	/*1549*/ uint16(x86_xSetOp), uint16(x86_MOVLPD),
-	/*1551*/ uint16(x86_xReadSlashR),
-	/*1552*/ uint16(x86_xArgXmm2M64),
-	/*1553*/ uint16(x86_xArgXmm),
-	/*1554*/ uint16(x86_xMatch),
-	/*1555*/ uint16(x86_xCondPrefix), 2,
-	0x66, 1567,
-	0x0, 1561,
-	/*1561*/ uint16(x86_xSetOp), uint16(x86_UNPCKLPS),
-	/*1563*/ uint16(x86_xReadSlashR),
-	/*1564*/ uint16(x86_xArgXmm1),
-	/*1565*/ uint16(x86_xArgXmm2M128),
-	/*1566*/ uint16(x86_xMatch),
-	/*1567*/ uint16(x86_xSetOp), uint16(x86_UNPCKLPD),
-	/*1569*/ uint16(x86_xReadSlashR),
-	/*1570*/ uint16(x86_xArgXmm1),
-	/*1571*/ uint16(x86_xArgXmm2M128),
-	/*1572*/ uint16(x86_xMatch),
-	/*1573*/ uint16(x86_xCondPrefix), 2,
-	0x66, 1585,
-	0x0, 1579,
-	/*1579*/ uint16(x86_xSetOp), uint16(x86_UNPCKHPS),
-	/*1581*/ uint16(x86_xReadSlashR),
-	/*1582*/ uint16(x86_xArgXmm1),
-	/*1583*/ uint16(x86_xArgXmm2M128),
-	/*1584*/ uint16(x86_xMatch),
-	/*1585*/ uint16(x86_xSetOp), uint16(x86_UNPCKHPD),
-	/*1587*/ uint16(x86_xReadSlashR),
-	/*1588*/ uint16(x86_xArgXmm1),
-	/*1589*/ uint16(x86_xArgXmm2M128),
-	/*1590*/ uint16(x86_xMatch),
-	/*1591*/ uint16(x86_xCondPrefix), 3,
-	0xF3, 1620,
-	0x66, 1614,
-	0x0, 1599,
-	/*1599*/ uint16(x86_xCondIsMem), 1602, 1608,
-	/*1602*/ uint16(x86_xSetOp), uint16(x86_MOVLHPS),
-	/*1604*/ uint16(x86_xReadSlashR),
-	/*1605*/ uint16(x86_xArgXmm1),
-	/*1606*/ uint16(x86_xArgXmm2),
-	/*1607*/ uint16(x86_xMatch),
-	/*1608*/ uint16(x86_xSetOp), uint16(x86_MOVHPS),
-	/*1610*/ uint16(x86_xReadSlashR),
-	/*1611*/ uint16(x86_xArgXmm),
-	/*1612*/ uint16(x86_xArgM64),
-	/*1613*/ uint16(x86_xMatch),
-	/*1614*/ uint16(x86_xSetOp), uint16(x86_MOVHPD),
-	/*1616*/ uint16(x86_xReadSlashR),
-	/*1617*/ uint16(x86_xArgXmm),
-	/*1618*/ uint16(x86_xArgXmm2M64),
-	/*1619*/ uint16(x86_xMatch),
-	/*1620*/ uint16(x86_xSetOp), uint16(x86_MOVSHDUP),
-	/*1622*/ uint16(x86_xReadSlashR),
-	/*1623*/ uint16(x86_xArgXmm1),
-	/*1624*/ uint16(x86_xArgXmm2M128),
-	/*1625*/ uint16(x86_xMatch),
-	/*1626*/ uint16(x86_xCondPrefix), 2,
-	0x66, 1638,
-	0x0, 1632,
-	/*1632*/ uint16(x86_xSetOp), uint16(x86_MOVHPS),
-	/*1634*/ uint16(x86_xReadSlashR),
-	/*1635*/ uint16(x86_xArgM64),
-	/*1636*/ uint16(x86_xArgXmm),
-	/*1637*/ uint16(x86_xMatch),
-	/*1638*/ uint16(x86_xSetOp), uint16(x86_MOVHPD),
-	/*1640*/ uint16(x86_xReadSlashR),
-	/*1641*/ uint16(x86_xArgXmm2M64),
-	/*1642*/ uint16(x86_xArgXmm),
-	/*1643*/ uint16(x86_xMatch),
-	/*1644*/ uint16(x86_xCondSlashR),
-	1653, // 0
-	1657, // 1
-	1661, // 2
-	1665, // 3
-	0,    // 4
-	0,    // 5
-	0,    // 6
-	0,    // 7
-	/*1653*/ uint16(x86_xSetOp), uint16(x86_PREFETCHNTA),
-	/*1655*/ uint16(x86_xArgM8),
-	/*1656*/ uint16(x86_xMatch),
-	/*1657*/ uint16(x86_xSetOp), uint16(x86_PREFETCHT0),
-	/*1659*/ uint16(x86_xArgM8),
-	/*1660*/ uint16(x86_xMatch),
-	/*1661*/ uint16(x86_xSetOp), uint16(x86_PREFETCHT1),
-	/*1663*/ uint16(x86_xArgM8),
-	/*1664*/ uint16(x86_xMatch),
-	/*1665*/ uint16(x86_xSetOp), uint16(x86_PREFETCHT2),
-	/*1667*/ uint16(x86_xArgM8),
-	/*1668*/ uint16(x86_xMatch),
-	/*1669*/ uint16(x86_xCondSlashR),
-	1678, // 0
-	0,    // 1
-	0,    // 2
-	0,    // 3
-	0,    // 4
-	0,    // 5
-	0,    // 6
-	0,    // 7
-	/*1678*/ uint16(x86_xCondDataSize), 1682, 1686, 0,
-	/*1682*/ uint16(x86_xSetOp), uint16(x86_NOP),
-	/*1684*/ uint16(x86_xArgRM16),
-	/*1685*/ uint16(x86_xMatch),
-	/*1686*/ uint16(x86_xSetOp), uint16(x86_NOP),
-	/*1688*/ uint16(x86_xArgRM32),
-	/*1689*/ uint16(x86_xMatch),
-	/*1690*/ uint16(x86_xCondIs64), 1693, 1699,
-	/*1693*/ uint16(x86_xSetOp), uint16(x86_MOV),
-	/*1695*/ uint16(x86_xReadSlashR),
-	/*1696*/ uint16(x86_xArgRmf32),
-	/*1697*/ uint16(x86_xArgCR0dashCR7),
-	/*1698*/ uint16(x86_xMatch),
-	/*1699*/ uint16(x86_xSetOp), uint16(x86_MOV),
-	/*1701*/ uint16(x86_xReadSlashR),
-	/*1702*/ uint16(x86_xArgRmf64),
-	/*1703*/ uint16(x86_xArgCR0dashCR7),
-	/*1704*/ uint16(x86_xMatch),
-	/*1705*/ uint16(x86_xCondIs64), 1708, 1714,
-	/*1708*/ uint16(x86_xSetOp), uint16(x86_MOV),
-	/*1710*/ uint16(x86_xReadSlashR),
-	/*1711*/ uint16(x86_xArgRmf32),
-	/*1712*/ uint16(x86_xArgDR0dashDR7),
-	/*1713*/ uint16(x86_xMatch),
-	/*1714*/ uint16(x86_xSetOp), uint16(x86_MOV),
-	/*1716*/ uint16(x86_xReadSlashR),
-	/*1717*/ uint16(x86_xArgRmf64),
-	/*1718*/ uint16(x86_xArgDR0dashDR7),
-	/*1719*/ uint16(x86_xMatch),
-	/*1720*/ uint16(x86_xCondIs64), 1723, 1729,
-	/*1723*/ uint16(x86_xSetOp), uint16(x86_MOV),
-	/*1725*/ uint16(x86_xReadSlashR),
-	/*1726*/ uint16(x86_xArgCR0dashCR7),
-	/*1727*/ uint16(x86_xArgRmf32),
-	/*1728*/ uint16(x86_xMatch),
-	/*1729*/ uint16(x86_xSetOp), uint16(x86_MOV),
-	/*1731*/ uint16(x86_xReadSlashR),
-	/*1732*/ uint16(x86_xArgCR0dashCR7),
-	/*1733*/ uint16(x86_xArgRmf64),
-	/*1734*/ uint16(x86_xMatch),
-	/*1735*/ uint16(x86_xCondIs64), 1738, 1744,
-	/*1738*/ uint16(x86_xSetOp), uint16(x86_MOV),
-	/*1740*/ uint16(x86_xReadSlashR),
-	/*1741*/ uint16(x86_xArgDR0dashDR7),
-	/*1742*/ uint16(x86_xArgRmf32),
-	/*1743*/ uint16(x86_xMatch),
-	/*1744*/ uint16(x86_xSetOp), uint16(x86_MOV),
-	/*1746*/ uint16(x86_xReadSlashR),
-	/*1747*/ uint16(x86_xArgDR0dashDR7),
-	/*1748*/ uint16(x86_xArgRmf64),
-	/*1749*/ uint16(x86_xMatch),
-	/*1750*/ uint16(x86_xCondIs64), 1753, 1759,
-	/*1753*/ uint16(x86_xSetOp), uint16(x86_MOV),
-	/*1755*/ uint16(x86_xReadSlashR),
-	/*1756*/ uint16(x86_xArgRmf32),
-	/*1757*/ uint16(x86_xArgTR0dashTR7),
-	/*1758*/ uint16(x86_xMatch),
-	/*1759*/ uint16(x86_xSetOp), uint16(x86_MOV),
-	/*1761*/ uint16(x86_xReadSlashR),
-	/*1762*/ uint16(x86_xArgRmf64),
-	/*1763*/ uint16(x86_xArgTR0dashTR7),
-	/*1764*/ uint16(x86_xMatch),
-	/*1765*/ uint16(x86_xCondIs64), 1768, 1774,
-	/*1768*/ uint16(x86_xSetOp), uint16(x86_MOV),
-	/*1770*/ uint16(x86_xReadSlashR),
-	/*1771*/ uint16(x86_xArgTR0dashTR7),
-	/*1772*/ uint16(x86_xArgRmf32),
-	/*1773*/ uint16(x86_xMatch),
-	/*1774*/ uint16(x86_xSetOp), uint16(x86_MOV),
-	/*1776*/ uint16(x86_xReadSlashR),
-	/*1777*/ uint16(x86_xArgTR0dashTR7),
-	/*1778*/ uint16(x86_xArgRmf64),
-	/*1779*/ uint16(x86_xMatch),
-	/*1780*/ uint16(x86_xCondPrefix), 2,
-	0x66, 1792,
-	0x0, 1786,
-	/*1786*/ uint16(x86_xSetOp), uint16(x86_MOVAPS),
-	/*1788*/ uint16(x86_xReadSlashR),
-	/*1789*/ uint16(x86_xArgXmm1),
-	/*1790*/ uint16(x86_xArgXmm2M128),
-	/*1791*/ uint16(x86_xMatch),
-	/*1792*/ uint16(x86_xSetOp), uint16(x86_MOVAPD),
-	/*1794*/ uint16(x86_xReadSlashR),
-	/*1795*/ uint16(x86_xArgXmm1),
-	/*1796*/ uint16(x86_xArgXmm2M128),
-	/*1797*/ uint16(x86_xMatch),
-	/*1798*/ uint16(x86_xCondPrefix), 2,
-	0x66, 1810,
-	0x0, 1804,
-	/*1804*/ uint16(x86_xSetOp), uint16(x86_MOVAPS),
-	/*1806*/ uint16(x86_xReadSlashR),
-	/*1807*/ uint16(x86_xArgXmm2M128),
-	/*1808*/ uint16(x86_xArgXmm1),
-	/*1809*/ uint16(x86_xMatch),
-	/*1810*/ uint16(x86_xSetOp), uint16(x86_MOVAPD),
-	/*1812*/ uint16(x86_xReadSlashR),
-	/*1813*/ uint16(x86_xArgXmm2M128),
-	/*1814*/ uint16(x86_xArgXmm1),
-	/*1815*/ uint16(x86_xMatch),
-	/*1816*/ uint16(x86_xCondIs64), 1819, 1873,
-	/*1819*/ uint16(x86_xCondPrefix), 4,
-	0xF3, 1857,
-	0xF2, 1841,
-	0x66, 1835,
-	0x0, 1829,
-	/*1829*/ uint16(x86_xSetOp), uint16(x86_CVTPI2PS),
-	/*1831*/ uint16(x86_xReadSlashR),
-	/*1832*/ uint16(x86_xArgXmm),
-	/*1833*/ uint16(x86_xArgMmM64),
-	/*1834*/ uint16(x86_xMatch),
-	/*1835*/ uint16(x86_xSetOp), uint16(x86_CVTPI2PD),
-	/*1837*/ uint16(x86_xReadSlashR),
-	/*1838*/ uint16(x86_xArgXmm),
-	/*1839*/ uint16(x86_xArgMmM64),
-	/*1840*/ uint16(x86_xMatch),
-	/*1841*/ uint16(x86_xCondDataSize), 1845, 1851, 0,
-	/*1845*/ uint16(x86_xSetOp), uint16(x86_CVTSI2SD),
-	/*1847*/ uint16(x86_xReadSlashR),
-	/*1848*/ uint16(x86_xArgXmm),
-	/*1849*/ uint16(x86_xArgRM32),
-	/*1850*/ uint16(x86_xMatch),
-	/*1851*/ uint16(x86_xSetOp), uint16(x86_CVTSI2SD),
-	/*1853*/ uint16(x86_xReadSlashR),
-	/*1854*/ uint16(x86_xArgXmm),
-	/*1855*/ uint16(x86_xArgRM32),
-	/*1856*/ uint16(x86_xMatch),
-	/*1857*/ uint16(x86_xCondDataSize), 1861, 1867, 0,
-	/*1861*/ uint16(x86_xSetOp), uint16(x86_CVTSI2SS),
-	/*1863*/ uint16(x86_xReadSlashR),
-	/*1864*/ uint16(x86_xArgXmm),
-	/*1865*/ uint16(x86_xArgRM32),
-	/*1866*/ uint16(x86_xMatch),
-	/*1867*/ uint16(x86_xSetOp), uint16(x86_CVTSI2SS),
-	/*1869*/ uint16(x86_xReadSlashR),
-	/*1870*/ uint16(x86_xArgXmm),
-	/*1871*/ uint16(x86_xArgRM32),
-	/*1872*/ uint16(x86_xMatch),
-	/*1873*/ uint16(x86_xCondPrefix), 4,
-	0xF3, 1893,
-	0xF2, 1883,
-	0x66, 1835,
-	0x0, 1829,
-	/*1883*/ uint16(x86_xCondDataSize), 1845, 1851, 1887,
-	/*1887*/ uint16(x86_xSetOp), uint16(x86_CVTSI2SD),
-	/*1889*/ uint16(x86_xReadSlashR),
-	/*1890*/ uint16(x86_xArgXmm),
-	/*1891*/ uint16(x86_xArgRM64),
-	/*1892*/ uint16(x86_xMatch),
-	/*1893*/ uint16(x86_xCondDataSize), 1861, 1867, 1897,
-	/*1897*/ uint16(x86_xSetOp), uint16(x86_CVTSI2SS),
-	/*1899*/ uint16(x86_xReadSlashR),
-	/*1900*/ uint16(x86_xArgXmm),
-	/*1901*/ uint16(x86_xArgRM64),
-	/*1902*/ uint16(x86_xMatch),
-	/*1903*/ uint16(x86_xCondPrefix), 4,
-	0xF3, 1931,
-	0xF2, 1925,
-	0x66, 1919,
-	0x0, 1913,
-	/*1913*/ uint16(x86_xSetOp), uint16(x86_MOVNTPS),
-	/*1915*/ uint16(x86_xReadSlashR),
-	/*1916*/ uint16(x86_xArgM128),
-	/*1917*/ uint16(x86_xArgXmm),
-	/*1918*/ uint16(x86_xMatch),
-	/*1919*/ uint16(x86_xSetOp), uint16(x86_MOVNTPD),
-	/*1921*/ uint16(x86_xReadSlashR),
-	/*1922*/ uint16(x86_xArgM128),
-	/*1923*/ uint16(x86_xArgXmm),
-	/*1924*/ uint16(x86_xMatch),
-	/*1925*/ uint16(x86_xSetOp), uint16(x86_MOVNTSD),
-	/*1927*/ uint16(x86_xReadSlashR),
-	/*1928*/ uint16(x86_xArgM64),
-	/*1929*/ uint16(x86_xArgXmm),
-	/*1930*/ uint16(x86_xMatch),
-	/*1931*/ uint16(x86_xSetOp), uint16(x86_MOVNTSS),
-	/*1933*/ uint16(x86_xReadSlashR),
-	/*1934*/ uint16(x86_xArgM32),
-	/*1935*/ uint16(x86_xArgXmm),
-	/*1936*/ uint16(x86_xMatch),
-	/*1937*/ uint16(x86_xCondIs64), 1940, 1994,
-	/*1940*/ uint16(x86_xCondPrefix), 4,
-	0xF3, 1978,
-	0xF2, 1962,
-	0x66, 1956,
-	0x0, 1950,
-	/*1950*/ uint16(x86_xSetOp), uint16(x86_CVTTPS2PI),
-	/*1952*/ uint16(x86_xReadSlashR),
-	/*1953*/ uint16(x86_xArgMm),
-	/*1954*/ uint16(x86_xArgXmmM64),
-	/*1955*/ uint16(x86_xMatch),
-	/*1956*/ uint16(x86_xSetOp), uint16(x86_CVTTPD2PI),
-	/*1958*/ uint16(x86_xReadSlashR),
-	/*1959*/ uint16(x86_xArgMm),
-	/*1960*/ uint16(x86_xArgXmmM128),
-	/*1961*/ uint16(x86_xMatch),
-	/*1962*/ uint16(x86_xCondDataSize), 1966, 1972, 0,
-	/*1966*/ uint16(x86_xSetOp), uint16(x86_CVTTSD2SI),
-	/*1968*/ uint16(x86_xReadSlashR),
-	/*1969*/ uint16(x86_xArgR32),
-	/*1970*/ uint16(x86_xArgXmmM64),
-	/*1971*/ uint16(x86_xMatch),
-	/*1972*/ uint16(x86_xSetOp), uint16(x86_CVTTSD2SI),
-	/*1974*/ uint16(x86_xReadSlashR),
-	/*1975*/ uint16(x86_xArgR32),
-	/*1976*/ uint16(x86_xArgXmmM64),
-	/*1977*/ uint16(x86_xMatch),
-	/*1978*/ uint16(x86_xCondDataSize), 1982, 1988, 0,
-	/*1982*/ uint16(x86_xSetOp), uint16(x86_CVTTSS2SI),
-	/*1984*/ uint16(x86_xReadSlashR),
-	/*1985*/ uint16(x86_xArgR32),
-	/*1986*/ uint16(x86_xArgXmmM32),
-	/*1987*/ uint16(x86_xMatch),
-	/*1988*/ uint16(x86_xSetOp), uint16(x86_CVTTSS2SI),
-	/*1990*/ uint16(x86_xReadSlashR),
-	/*1991*/ uint16(x86_xArgR32),
-	/*1992*/ uint16(x86_xArgXmmM32),
-	/*1993*/ uint16(x86_xMatch),
-	/*1994*/ uint16(x86_xCondPrefix), 4,
-	0xF3, 2014,
-	0xF2, 2004,
-	0x66, 1956,
-	0x0, 1950,
-	/*2004*/ uint16(x86_xCondDataSize), 1966, 1972, 2008,
-	/*2008*/ uint16(x86_xSetOp), uint16(x86_CVTTSD2SI),
-	/*2010*/ uint16(x86_xReadSlashR),
-	/*2011*/ uint16(x86_xArgR64),
-	/*2012*/ uint16(x86_xArgXmmM64),
-	/*2013*/ uint16(x86_xMatch),
-	/*2014*/ uint16(x86_xCondDataSize), 1982, 1988, 2018,
-	/*2018*/ uint16(x86_xSetOp), uint16(x86_CVTTSS2SI),
-	/*2020*/ uint16(x86_xReadSlashR),
-	/*2021*/ uint16(x86_xArgR64),
-	/*2022*/ uint16(x86_xArgXmmM32),
-	/*2023*/ uint16(x86_xMatch),
-	/*2024*/ uint16(x86_xCondIs64), 2027, 2081,
-	/*2027*/ uint16(x86_xCondPrefix), 4,
-	0xF3, 2065,
-	0xF2, 2049,
-	0x66, 2043,
-	0x0, 2037,
-	/*2037*/ uint16(x86_xSetOp), uint16(x86_CVTPS2PI),
-	/*2039*/ uint16(x86_xReadSlashR),
-	/*2040*/ uint16(x86_xArgMm),
-	/*2041*/ uint16(x86_xArgXmmM64),
-	/*2042*/ uint16(x86_xMatch),
-	/*2043*/ uint16(x86_xSetOp), uint16(x86_CVTPD2PI),
-	/*2045*/ uint16(x86_xReadSlashR),
-	/*2046*/ uint16(x86_xArgMm),
-	/*2047*/ uint16(x86_xArgXmmM128),
-	/*2048*/ uint16(x86_xMatch),
-	/*2049*/ uint16(x86_xCondDataSize), 2053, 2059, 0,
-	/*2053*/ uint16(x86_xSetOp), uint16(x86_CVTSD2SI),
-	/*2055*/ uint16(x86_xReadSlashR),
-	/*2056*/ uint16(x86_xArgR32),
-	/*2057*/ uint16(x86_xArgXmmM64),
-	/*2058*/ uint16(x86_xMatch),
-	/*2059*/ uint16(x86_xSetOp), uint16(x86_CVTSD2SI),
-	/*2061*/ uint16(x86_xReadSlashR),
-	/*2062*/ uint16(x86_xArgR32),
-	/*2063*/ uint16(x86_xArgXmmM64),
-	/*2064*/ uint16(x86_xMatch),
-	/*2065*/ uint16(x86_xCondDataSize), 2069, 2075, 0,
-	/*2069*/ uint16(x86_xSetOp), uint16(x86_CVTSS2SI),
-	/*2071*/ uint16(x86_xReadSlashR),
-	/*2072*/ uint16(x86_xArgR32),
-	/*2073*/ uint16(x86_xArgXmmM32),
-	/*2074*/ uint16(x86_xMatch),
-	/*2075*/ uint16(x86_xSetOp), uint16(x86_CVTSS2SI),
-	/*2077*/ uint16(x86_xReadSlashR),
-	/*2078*/ uint16(x86_xArgR32),
-	/*2079*/ uint16(x86_xArgXmmM32),
-	/*2080*/ uint16(x86_xMatch),
-	/*2081*/ uint16(x86_xCondPrefix), 4,
-	0xF3, 2101,
-	0xF2, 2091,
-	0x66, 2043,
-	0x0, 2037,
-	/*2091*/ uint16(x86_xCondDataSize), 2053, 2059, 2095,
-	/*2095*/ uint16(x86_xSetOp), uint16(x86_CVTSD2SI),
-	/*2097*/ uint16(x86_xReadSlashR),
-	/*2098*/ uint16(x86_xArgR64),
-	/*2099*/ uint16(x86_xArgXmmM64),
-	/*2100*/ uint16(x86_xMatch),
-	/*2101*/ uint16(x86_xCondDataSize), 2069, 2075, 2105,
-	/*2105*/ uint16(x86_xSetOp), uint16(x86_CVTSS2SI),
-	/*2107*/ uint16(x86_xReadSlashR),
-	/*2108*/ uint16(x86_xArgR64),
-	/*2109*/ uint16(x86_xArgXmmM32),
-	/*2110*/ uint16(x86_xMatch),
-	/*2111*/ uint16(x86_xCondPrefix), 2,
-	0x66, 2123,
-	0x0, 2117,
-	/*2117*/ uint16(x86_xSetOp), uint16(x86_UCOMISS),
-	/*2119*/ uint16(x86_xReadSlashR),
-	/*2120*/ uint16(x86_xArgXmm1),
-	/*2121*/ uint16(x86_xArgXmm2M32),
-	/*2122*/ uint16(x86_xMatch),
-	/*2123*/ uint16(x86_xSetOp), uint16(x86_UCOMISD),
-	/*2125*/ uint16(x86_xReadSlashR),
-	/*2126*/ uint16(x86_xArgXmm1),
-	/*2127*/ uint16(x86_xArgXmm2M64),
-	/*2128*/ uint16(x86_xMatch),
-	/*2129*/ uint16(x86_xCondPrefix), 2,
-	0x66, 2141,
-	0x0, 2135,
-	/*2135*/ uint16(x86_xSetOp), uint16(x86_COMISS),
-	/*2137*/ uint16(x86_xReadSlashR),
-	/*2138*/ uint16(x86_xArgXmm1),
-	/*2139*/ uint16(x86_xArgXmm2M32),
-	/*2140*/ uint16(x86_xMatch),
-	/*2141*/ uint16(x86_xSetOp), uint16(x86_COMISD),
-	/*2143*/ uint16(x86_xReadSlashR),
-	/*2144*/ uint16(x86_xArgXmm1),
-	/*2145*/ uint16(x86_xArgXmm2M64),
-	/*2146*/ uint16(x86_xMatch),
-	/*2147*/ uint16(x86_xSetOp), uint16(x86_WRMSR),
-	/*2149*/ uint16(x86_xMatch),
-	/*2150*/ uint16(x86_xSetOp), uint16(x86_RDTSC),
-	/*2152*/ uint16(x86_xMatch),
-	/*2153*/ uint16(x86_xSetOp), uint16(x86_RDMSR),
-	/*2155*/ uint16(x86_xMatch),
-	/*2156*/ uint16(x86_xSetOp), uint16(x86_RDPMC),
-	/*2158*/ uint16(x86_xMatch),
-	/*2159*/ uint16(x86_xSetOp), uint16(x86_SYSENTER),
-	/*2161*/ uint16(x86_xMatch),
-	/*2162*/ uint16(x86_xCondDataSize), 2166, 2166, 2169,
-	/*2166*/ uint16(x86_xSetOp), uint16(x86_SYSEXIT),
-	/*2168*/ uint16(x86_xMatch),
-	/*2169*/ uint16(x86_xSetOp), uint16(x86_SYSEXIT),
-	/*2171*/ uint16(x86_xMatch),
-	/*2172*/ uint16(x86_xCondByte), 54,
-	0x00, 2283,
-	0x01, 2301,
-	0x02, 2319,
-	0x03, 2337,
-	0x04, 2355,
-	0x05, 2373,
-	0x06, 2391,
-	0x07, 2409,
-	0x08, 2427,
-	0x09, 2445,
-	0x0A, 2463,
-	0x0B, 2481,
-	0x10, 2499,
-	0x14, 2510,
-	0x15, 2521,
-	0x17, 2532,
-	0x1C, 2542,
-	0x1D, 2560,
-	0x1E, 2578,
-	0x20, 2596,
-	0x21, 2606,
-	0x22, 2616,
-	0x23, 2626,
-	0x24, 2636,
-	0x25, 2646,
-	0x28, 2656,
-	0x29, 2666,
-	0x2A, 2676,
-	0x2B, 2686,
-	0x30, 2696,
-	0x31, 2706,
-	0x32, 2716,
-	0x33, 2726,
-	0x34, 2736,
-	0x35, 2746,
-	0x37, 2756,
-	0x38, 2766,
-	0x39, 2776,
-	0x3A, 2786,
-	0x3B, 2796,
-	0x3C, 2806,
-	0x3D, 2816,
-	0x3E, 2826,
-	0x3F, 2836,
-	0x40, 2846,
-	0x41, 2856,
-	0x82, 2866,
-	0xDB, 2889,
-	0xDC, 2899,
-	0xDD, 2909,
-	0xDE, 2919,
-	0xDF, 2929,
-	0xF0, 2939,
-	0xF1, 3006,
-	uint16(x86_xFail),
-	/*2283*/ uint16(x86_xCondPrefix), 2,
-	0x66, 2295,
-	0x0, 2289,
-	/*2289*/ uint16(x86_xSetOp), uint16(x86_PSHUFB),
-	/*2291*/ uint16(x86_xReadSlashR),
-	/*2292*/ uint16(x86_xArgMm1),
-	/*2293*/ uint16(x86_xArgMm2M64),
-	/*2294*/ uint16(x86_xMatch),
-	/*2295*/ uint16(x86_xSetOp), uint16(x86_PSHUFB),
-	/*2297*/ uint16(x86_xReadSlashR),
-	/*2298*/ uint16(x86_xArgXmm1),
-	/*2299*/ uint16(x86_xArgXmm2M128),
-	/*2300*/ uint16(x86_xMatch),
-	/*2301*/ uint16(x86_xCondPrefix), 2,
-	0x66, 2313,
-	0x0, 2307,
-	/*2307*/ uint16(x86_xSetOp), uint16(x86_PHADDW),
-	/*2309*/ uint16(x86_xReadSlashR),
-	/*2310*/ uint16(x86_xArgMm1),
-	/*2311*/ uint16(x86_xArgMm2M64),
-	/*2312*/ uint16(x86_xMatch),
-	/*2313*/ uint16(x86_xSetOp), uint16(x86_PHADDW),
-	/*2315*/ uint16(x86_xReadSlashR),
-	/*2316*/ uint16(x86_xArgXmm1),
-	/*2317*/ uint16(x86_xArgXmm2M128),
-	/*2318*/ uint16(x86_xMatch),
-	/*2319*/ uint16(x86_xCondPrefix), 2,
-	0x66, 2331,
-	0x0, 2325,
-	/*2325*/ uint16(x86_xSetOp), uint16(x86_PHADDD),
-	/*2327*/ uint16(x86_xReadSlashR),
-	/*2328*/ uint16(x86_xArgMm1),
-	/*2329*/ uint16(x86_xArgMm2M64),
-	/*2330*/ uint16(x86_xMatch),
-	/*2331*/ uint16(x86_xSetOp), uint16(x86_PHADDD),
-	/*2333*/ uint16(x86_xReadSlashR),
-	/*2334*/ uint16(x86_xArgXmm1),
-	/*2335*/ uint16(x86_xArgXmm2M128),
-	/*2336*/ uint16(x86_xMatch),
-	/*2337*/ uint16(x86_xCondPrefix), 2,
-	0x66, 2349,
-	0x0, 2343,
-	/*2343*/ uint16(x86_xSetOp), uint16(x86_PHADDSW),
-	/*2345*/ uint16(x86_xReadSlashR),
-	/*2346*/ uint16(x86_xArgMm1),
-	/*2347*/ uint16(x86_xArgMm2M64),
-	/*2348*/ uint16(x86_xMatch),
-	/*2349*/ uint16(x86_xSetOp), uint16(x86_PHADDSW),
-	/*2351*/ uint16(x86_xReadSlashR),
-	/*2352*/ uint16(x86_xArgXmm1),
-	/*2353*/ uint16(x86_xArgXmm2M128),
-	/*2354*/ uint16(x86_xMatch),
-	/*2355*/ uint16(x86_xCondPrefix), 2,
-	0x66, 2367,
-	0x0, 2361,
-	/*2361*/ uint16(x86_xSetOp), uint16(x86_PMADDUBSW),
-	/*2363*/ uint16(x86_xReadSlashR),
-	/*2364*/ uint16(x86_xArgMm1),
-	/*2365*/ uint16(x86_xArgMm2M64),
-	/*2366*/ uint16(x86_xMatch),
-	/*2367*/ uint16(x86_xSetOp), uint16(x86_PMADDUBSW),
-	/*2369*/ uint16(x86_xReadSlashR),
-	/*2370*/ uint16(x86_xArgXmm1),
-	/*2371*/ uint16(x86_xArgXmm2M128),
-	/*2372*/ uint16(x86_xMatch),
-	/*2373*/ uint16(x86_xCondPrefix), 2,
-	0x66, 2385,
-	0x0, 2379,
-	/*2379*/ uint16(x86_xSetOp), uint16(x86_PHSUBW),
-	/*2381*/ uint16(x86_xReadSlashR),
-	/*2382*/ uint16(x86_xArgMm1),
-	/*2383*/ uint16(x86_xArgMm2M64),
-	/*2384*/ uint16(x86_xMatch),
-	/*2385*/ uint16(x86_xSetOp), uint16(x86_PHSUBW),
-	/*2387*/ uint16(x86_xReadSlashR),
-	/*2388*/ uint16(x86_xArgXmm1),
-	/*2389*/ uint16(x86_xArgXmm2M128),
-	/*2390*/ uint16(x86_xMatch),
-	/*2391*/ uint16(x86_xCondPrefix), 2,
-	0x66, 2403,
-	0x0, 2397,
-	/*2397*/ uint16(x86_xSetOp), uint16(x86_PHSUBD),
-	/*2399*/ uint16(x86_xReadSlashR),
-	/*2400*/ uint16(x86_xArgMm1),
-	/*2401*/ uint16(x86_xArgMm2M64),
-	/*2402*/ uint16(x86_xMatch),
-	/*2403*/ uint16(x86_xSetOp), uint16(x86_PHSUBD),
-	/*2405*/ uint16(x86_xReadSlashR),
-	/*2406*/ uint16(x86_xArgXmm1),
-	/*2407*/ uint16(x86_xArgXmm2M128),
-	/*2408*/ uint16(x86_xMatch),
-	/*2409*/ uint16(x86_xCondPrefix), 2,
-	0x66, 2421,
-	0x0, 2415,
-	/*2415*/ uint16(x86_xSetOp), uint16(x86_PHSUBSW),
-	/*2417*/ uint16(x86_xReadSlashR),
-	/*2418*/ uint16(x86_xArgMm1),
-	/*2419*/ uint16(x86_xArgMm2M64),
-	/*2420*/ uint16(x86_xMatch),
-	/*2421*/ uint16(x86_xSetOp), uint16(x86_PHSUBSW),
-	/*2423*/ uint16(x86_xReadSlashR),
-	/*2424*/ uint16(x86_xArgXmm1),
-	/*2425*/ uint16(x86_xArgXmm2M128),
-	/*2426*/ uint16(x86_xMatch),
-	/*2427*/ uint16(x86_xCondPrefix), 2,
-	0x66, 2439,
-	0x0, 2433,
-	/*2433*/ uint16(x86_xSetOp), uint16(x86_PSIGNB),
-	/*2435*/ uint16(x86_xReadSlashR),
-	/*2436*/ uint16(x86_xArgMm1),
-	/*2437*/ uint16(x86_xArgMm2M64),
-	/*2438*/ uint16(x86_xMatch),
-	/*2439*/ uint16(x86_xSetOp), uint16(x86_PSIGNB),
-	/*2441*/ uint16(x86_xReadSlashR),
-	/*2442*/ uint16(x86_xArgXmm1),
-	/*2443*/ uint16(x86_xArgXmm2M128),
-	/*2444*/ uint16(x86_xMatch),
-	/*2445*/ uint16(x86_xCondPrefix), 2,
-	0x66, 2457,
-	0x0, 2451,
-	/*2451*/ uint16(x86_xSetOp), uint16(x86_PSIGNW),
-	/*2453*/ uint16(x86_xReadSlashR),
-	/*2454*/ uint16(x86_xArgMm1),
-	/*2455*/ uint16(x86_xArgMm2M64),
-	/*2456*/ uint16(x86_xMatch),
-	/*2457*/ uint16(x86_xSetOp), uint16(x86_PSIGNW),
-	/*2459*/ uint16(x86_xReadSlashR),
-	/*2460*/ uint16(x86_xArgXmm1),
-	/*2461*/ uint16(x86_xArgXmm2M128),
-	/*2462*/ uint16(x86_xMatch),
-	/*2463*/ uint16(x86_xCondPrefix), 2,
-	0x66, 2475,
-	0x0, 2469,
-	/*2469*/ uint16(x86_xSetOp), uint16(x86_PSIGND),
-	/*2471*/ uint16(x86_xReadSlashR),
-	/*2472*/ uint16(x86_xArgMm1),
-	/*2473*/ uint16(x86_xArgMm2M64),
-	/*2474*/ uint16(x86_xMatch),
-	/*2475*/ uint16(x86_xSetOp), uint16(x86_PSIGND),
-	/*2477*/ uint16(x86_xReadSlashR),
-	/*2478*/ uint16(x86_xArgXmm1),
-	/*2479*/ uint16(x86_xArgXmm2M128),
-	/*2480*/ uint16(x86_xMatch),
-	/*2481*/ uint16(x86_xCondPrefix), 2,
-	0x66, 2493,
-	0x0, 2487,
-	/*2487*/ uint16(x86_xSetOp), uint16(x86_PMULHRSW),
-	/*2489*/ uint16(x86_xReadSlashR),
-	/*2490*/ uint16(x86_xArgMm1),
-	/*2491*/ uint16(x86_xArgMm2M64),
-	/*2492*/ uint16(x86_xMatch),
-	/*2493*/ uint16(x86_xSetOp), uint16(x86_PMULHRSW),
-	/*2495*/ uint16(x86_xReadSlashR),
-	/*2496*/ uint16(x86_xArgXmm1),
-	/*2497*/ uint16(x86_xArgXmm2M128),
-	/*2498*/ uint16(x86_xMatch),
-	/*2499*/ uint16(x86_xCondPrefix), 1,
-	0x66, 2503,
-	/*2503*/ uint16(x86_xSetOp), uint16(x86_PBLENDVB),
-	/*2505*/ uint16(x86_xReadSlashR),
-	/*2506*/ uint16(x86_xArgXmm1),
-	/*2507*/ uint16(x86_xArgXmm2M128),
-	/*2508*/ uint16(x86_xArgXMM0),
-	/*2509*/ uint16(x86_xMatch),
-	/*2510*/ uint16(x86_xCondPrefix), 1,
-	0x66, 2514,
-	/*2514*/ uint16(x86_xSetOp), uint16(x86_BLENDVPS),
-	/*2516*/ uint16(x86_xReadSlashR),
-	/*2517*/ uint16(x86_xArgXmm1),
-	/*2518*/ uint16(x86_xArgXmm2M128),
-	/*2519*/ uint16(x86_xArgXMM0),
-	/*2520*/ uint16(x86_xMatch),
-	/*2521*/ uint16(x86_xCondPrefix), 1,
-	0x66, 2525,
-	/*2525*/ uint16(x86_xSetOp), uint16(x86_BLENDVPD),
-	/*2527*/ uint16(x86_xReadSlashR),
-	/*2528*/ uint16(x86_xArgXmm1),
-	/*2529*/ uint16(x86_xArgXmm2M128),
-	/*2530*/ uint16(x86_xArgXMM0),
-	/*2531*/ uint16(x86_xMatch),
-	/*2532*/ uint16(x86_xCondPrefix), 1,
-	0x66, 2536,
-	/*2536*/ uint16(x86_xSetOp), uint16(x86_PTEST),
-	/*2538*/ uint16(x86_xReadSlashR),
-	/*2539*/ uint16(x86_xArgXmm1),
-	/*2540*/ uint16(x86_xArgXmm2M128),
-	/*2541*/ uint16(x86_xMatch),
-	/*2542*/ uint16(x86_xCondPrefix), 2,
-	0x66, 2554,
-	0x0, 2548,
-	/*2548*/ uint16(x86_xSetOp), uint16(x86_PABSB),
-	/*2550*/ uint16(x86_xReadSlashR),
-	/*2551*/ uint16(x86_xArgMm1),
-	/*2552*/ uint16(x86_xArgMm2M64),
-	/*2553*/ uint16(x86_xMatch),
-	/*2554*/ uint16(x86_xSetOp), uint16(x86_PABSB),
-	/*2556*/ uint16(x86_xReadSlashR),
-	/*2557*/ uint16(x86_xArgXmm1),
-	/*2558*/ uint16(x86_xArgXmm2M128),
-	/*2559*/ uint16(x86_xMatch),
-	/*2560*/ uint16(x86_xCondPrefix), 2,
-	0x66, 2572,
-	0x0, 2566,
-	/*2566*/ uint16(x86_xSetOp), uint16(x86_PABSW),
-	/*2568*/ uint16(x86_xReadSlashR),
-	/*2569*/ uint16(x86_xArgMm1),
-	/*2570*/ uint16(x86_xArgMm2M64),
-	/*2571*/ uint16(x86_xMatch),
-	/*2572*/ uint16(x86_xSetOp), uint16(x86_PABSW),
-	/*2574*/ uint16(x86_xReadSlashR),
-	/*2575*/ uint16(x86_xArgXmm1),
-	/*2576*/ uint16(x86_xArgXmm2M128),
-	/*2577*/ uint16(x86_xMatch),
-	/*2578*/ uint16(x86_xCondPrefix), 2,
-	0x66, 2590,
-	0x0, 2584,
-	/*2584*/ uint16(x86_xSetOp), uint16(x86_PABSD),
-	/*2586*/ uint16(x86_xReadSlashR),
-	/*2587*/ uint16(x86_xArgMm1),
-	/*2588*/ uint16(x86_xArgMm2M64),
-	/*2589*/ uint16(x86_xMatch),
-	/*2590*/ uint16(x86_xSetOp), uint16(x86_PABSD),
-	/*2592*/ uint16(x86_xReadSlashR),
-	/*2593*/ uint16(x86_xArgXmm1),
-	/*2594*/ uint16(x86_xArgXmm2M128),
-	/*2595*/ uint16(x86_xMatch),
-	/*2596*/ uint16(x86_xCondPrefix), 1,
-	0x66, 2600,
-	/*2600*/ uint16(x86_xSetOp), uint16(x86_PMOVSXBW),
-	/*2602*/ uint16(x86_xReadSlashR),
-	/*2603*/ uint16(x86_xArgXmm1),
-	/*2604*/ uint16(x86_xArgXmm2M64),
-	/*2605*/ uint16(x86_xMatch),
-	/*2606*/ uint16(x86_xCondPrefix), 1,
-	0x66, 2610,
-	/*2610*/ uint16(x86_xSetOp), uint16(x86_PMOVSXBD),
-	/*2612*/ uint16(x86_xReadSlashR),
-	/*2613*/ uint16(x86_xArgXmm1),
-	/*2614*/ uint16(x86_xArgXmm2M32),
-	/*2615*/ uint16(x86_xMatch),
-	/*2616*/ uint16(x86_xCondPrefix), 1,
-	0x66, 2620,
-	/*2620*/ uint16(x86_xSetOp), uint16(x86_PMOVSXBQ),
-	/*2622*/ uint16(x86_xReadSlashR),
-	/*2623*/ uint16(x86_xArgXmm1),
-	/*2624*/ uint16(x86_xArgXmm2M16),
-	/*2625*/ uint16(x86_xMatch),
-	/*2626*/ uint16(x86_xCondPrefix), 1,
-	0x66, 2630,
-	/*2630*/ uint16(x86_xSetOp), uint16(x86_PMOVSXWD),
-	/*2632*/ uint16(x86_xReadSlashR),
-	/*2633*/ uint16(x86_xArgXmm1),
-	/*2634*/ uint16(x86_xArgXmm2M64),
-	/*2635*/ uint16(x86_xMatch),
-	/*2636*/ uint16(x86_xCondPrefix), 1,
-	0x66, 2640,
-	/*2640*/ uint16(x86_xSetOp), uint16(x86_PMOVSXWQ),
-	/*2642*/ uint16(x86_xReadSlashR),
-	/*2643*/ uint16(x86_xArgXmm1),
-	/*2644*/ uint16(x86_xArgXmm2M32),
-	/*2645*/ uint16(x86_xMatch),
-	/*2646*/ uint16(x86_xCondPrefix), 1,
-	0x66, 2650,
-	/*2650*/ uint16(x86_xSetOp), uint16(x86_PMOVSXDQ),
-	/*2652*/ uint16(x86_xReadSlashR),
-	/*2653*/ uint16(x86_xArgXmm1),
-	/*2654*/ uint16(x86_xArgXmm2M64),
-	/*2655*/ uint16(x86_xMatch),
-	/*2656*/ uint16(x86_xCondPrefix), 1,
-	0x66, 2660,
-	/*2660*/ uint16(x86_xSetOp), uint16(x86_PMULDQ),
-	/*2662*/ uint16(x86_xReadSlashR),
-	/*2663*/ uint16(x86_xArgXmm1),
-	/*2664*/ uint16(x86_xArgXmm2M128),
-	/*2665*/ uint16(x86_xMatch),
-	/*2666*/ uint16(x86_xCondPrefix), 1,
-	0x66, 2670,
-	/*2670*/ uint16(x86_xSetOp), uint16(x86_PCMPEQQ),
-	/*2672*/ uint16(x86_xReadSlashR),
-	/*2673*/ uint16(x86_xArgXmm1),
-	/*2674*/ uint16(x86_xArgXmm2M128),
-	/*2675*/ uint16(x86_xMatch),
-	/*2676*/ uint16(x86_xCondPrefix), 1,
-	0x66, 2680,
-	/*2680*/ uint16(x86_xSetOp), uint16(x86_MOVNTDQA),
-	/*2682*/ uint16(x86_xReadSlashR),
-	/*2683*/ uint16(x86_xArgXmm1),
-	/*2684*/ uint16(x86_xArgM128),
-	/*2685*/ uint16(x86_xMatch),
-	/*2686*/ uint16(x86_xCondPrefix), 1,
-	0x66, 2690,
-	/*2690*/ uint16(x86_xSetOp), uint16(x86_PACKUSDW),
-	/*2692*/ uint16(x86_xReadSlashR),
-	/*2693*/ uint16(x86_xArgXmm1),
-	/*2694*/ uint16(x86_xArgXmm2M128),
-	/*2695*/ uint16(x86_xMatch),
-	/*2696*/ uint16(x86_xCondPrefix), 1,
-	0x66, 2700,
-	/*2700*/ uint16(x86_xSetOp), uint16(x86_PMOVZXBW),
-	/*2702*/ uint16(x86_xReadSlashR),
-	/*2703*/ uint16(x86_xArgXmm1),
-	/*2704*/ uint16(x86_xArgXmm2M64),
-	/*2705*/ uint16(x86_xMatch),
-	/*2706*/ uint16(x86_xCondPrefix), 1,
-	0x66, 2710,
-	/*2710*/ uint16(x86_xSetOp), uint16(x86_PMOVZXBD),
-	/*2712*/ uint16(x86_xReadSlashR),
-	/*2713*/ uint16(x86_xArgXmm1),
-	/*2714*/ uint16(x86_xArgXmm2M32),
-	/*2715*/ uint16(x86_xMatch),
-	/*2716*/ uint16(x86_xCondPrefix), 1,
-	0x66, 2720,
-	/*2720*/ uint16(x86_xSetOp), uint16(x86_PMOVZXBQ),
-	/*2722*/ uint16(x86_xReadSlashR),
-	/*2723*/ uint16(x86_xArgXmm1),
-	/*2724*/ uint16(x86_xArgXmm2M16),
-	/*2725*/ uint16(x86_xMatch),
-	/*2726*/ uint16(x86_xCondPrefix), 1,
-	0x66, 2730,
-	/*2730*/ uint16(x86_xSetOp), uint16(x86_PMOVZXWD),
-	/*2732*/ uint16(x86_xReadSlashR),
-	/*2733*/ uint16(x86_xArgXmm1),
-	/*2734*/ uint16(x86_xArgXmm2M64),
-	/*2735*/ uint16(x86_xMatch),
-	/*2736*/ uint16(x86_xCondPrefix), 1,
-	0x66, 2740,
-	/*2740*/ uint16(x86_xSetOp), uint16(x86_PMOVZXWQ),
-	/*2742*/ uint16(x86_xReadSlashR),
-	/*2743*/ uint16(x86_xArgXmm1),
-	/*2744*/ uint16(x86_xArgXmm2M32),
-	/*2745*/ uint16(x86_xMatch),
-	/*2746*/ uint16(x86_xCondPrefix), 1,
-	0x66, 2750,
-	/*2750*/ uint16(x86_xSetOp), uint16(x86_PMOVZXDQ),
-	/*2752*/ uint16(x86_xReadSlashR),
-	/*2753*/ uint16(x86_xArgXmm1),
-	/*2754*/ uint16(x86_xArgXmm2M64),
-	/*2755*/ uint16(x86_xMatch),
-	/*2756*/ uint16(x86_xCondPrefix), 1,
-	0x66, 2760,
-	/*2760*/ uint16(x86_xSetOp), uint16(x86_PCMPGTQ),
-	/*2762*/ uint16(x86_xReadSlashR),
-	/*2763*/ uint16(x86_xArgXmm1),
-	/*2764*/ uint16(x86_xArgXmm2M128),
-	/*2765*/ uint16(x86_xMatch),
-	/*2766*/ uint16(x86_xCondPrefix), 1,
-	0x66, 2770,
-	/*2770*/ uint16(x86_xSetOp), uint16(x86_PMINSB),
-	/*2772*/ uint16(x86_xReadSlashR),
-	/*2773*/ uint16(x86_xArgXmm1),
-	/*2774*/ uint16(x86_xArgXmm2M128),
-	/*2775*/ uint16(x86_xMatch),
-	/*2776*/ uint16(x86_xCondPrefix), 1,
-	0x66, 2780,
-	/*2780*/ uint16(x86_xSetOp), uint16(x86_PMINSD),
-	/*2782*/ uint16(x86_xReadSlashR),
-	/*2783*/ uint16(x86_xArgXmm1),
-	/*2784*/ uint16(x86_xArgXmm2M128),
-	/*2785*/ uint16(x86_xMatch),
-	/*2786*/ uint16(x86_xCondPrefix), 1,
-	0x66, 2790,
-	/*2790*/ uint16(x86_xSetOp), uint16(x86_PMINUW),
-	/*2792*/ uint16(x86_xReadSlashR),
-	/*2793*/ uint16(x86_xArgXmm1),
-	/*2794*/ uint16(x86_xArgXmm2M128),
-	/*2795*/ uint16(x86_xMatch),
-	/*2796*/ uint16(x86_xCondPrefix), 1,
-	0x66, 2800,
-	/*2800*/ uint16(x86_xSetOp), uint16(x86_PMINUD),
-	/*2802*/ uint16(x86_xReadSlashR),
-	/*2803*/ uint16(x86_xArgXmm1),
-	/*2804*/ uint16(x86_xArgXmm2M128),
-	/*2805*/ uint16(x86_xMatch),
-	/*2806*/ uint16(x86_xCondPrefix), 1,
-	0x66, 2810,
-	/*2810*/ uint16(x86_xSetOp), uint16(x86_PMAXSB),
-	/*2812*/ uint16(x86_xReadSlashR),
-	/*2813*/ uint16(x86_xArgXmm1),
-	/*2814*/ uint16(x86_xArgXmm2M128),
-	/*2815*/ uint16(x86_xMatch),
-	/*2816*/ uint16(x86_xCondPrefix), 1,
-	0x66, 2820,
-	/*2820*/ uint16(x86_xSetOp), uint16(x86_PMAXSD),
-	/*2822*/ uint16(x86_xReadSlashR),
-	/*2823*/ uint16(x86_xArgXmm1),
-	/*2824*/ uint16(x86_xArgXmm2M128),
-	/*2825*/ uint16(x86_xMatch),
-	/*2826*/ uint16(x86_xCondPrefix), 1,
-	0x66, 2830,
-	/*2830*/ uint16(x86_xSetOp), uint16(x86_PMAXUW),
-	/*2832*/ uint16(x86_xReadSlashR),
-	/*2833*/ uint16(x86_xArgXmm1),
-	/*2834*/ uint16(x86_xArgXmm2M128),
-	/*2835*/ uint16(x86_xMatch),
-	/*2836*/ uint16(x86_xCondPrefix), 1,
-	0x66, 2840,
-	/*2840*/ uint16(x86_xSetOp), uint16(x86_PMAXUD),
-	/*2842*/ uint16(x86_xReadSlashR),
-	/*2843*/ uint16(x86_xArgXmm1),
-	/*2844*/ uint16(x86_xArgXmm2M128),
-	/*2845*/ uint16(x86_xMatch),
-	/*2846*/ uint16(x86_xCondPrefix), 1,
-	0x66, 2850,
-	/*2850*/ uint16(x86_xSetOp), uint16(x86_PMULLD),
-	/*2852*/ uint16(x86_xReadSlashR),
-	/*2853*/ uint16(x86_xArgXmm1),
-	/*2854*/ uint16(x86_xArgXmm2M128),
-	/*2855*/ uint16(x86_xMatch),
-	/*2856*/ uint16(x86_xCondPrefix), 1,
-	0x66, 2860,
-	/*2860*/ uint16(x86_xSetOp), uint16(x86_PHMINPOSUW),
-	/*2862*/ uint16(x86_xReadSlashR),
-	/*2863*/ uint16(x86_xArgXmm1),
-	/*2864*/ uint16(x86_xArgXmm2M128),
-	/*2865*/ uint16(x86_xMatch),
-	/*2866*/ uint16(x86_xCondIs64), 2869, 2879,
-	/*2869*/ uint16(x86_xCondPrefix), 1,
-	0x66, 2873,
-	/*2873*/ uint16(x86_xSetOp), uint16(x86_INVPCID),
-	/*2875*/ uint16(x86_xReadSlashR),
-	/*2876*/ uint16(x86_xArgR32),
-	/*2877*/ uint16(x86_xArgM128),
-	/*2878*/ uint16(x86_xMatch),
-	/*2879*/ uint16(x86_xCondPrefix), 1,
-	0x66, 2883,
-	/*2883*/ uint16(x86_xSetOp), uint16(x86_INVPCID),
-	/*2885*/ uint16(x86_xReadSlashR),
-	/*2886*/ uint16(x86_xArgR64),
-	/*2887*/ uint16(x86_xArgM128),
-	/*2888*/ uint16(x86_xMatch),
-	/*2889*/ uint16(x86_xCondPrefix), 1,
-	0x66, 2893,
-	/*2893*/ uint16(x86_xSetOp), uint16(x86_AESIMC),
-	/*2895*/ uint16(x86_xReadSlashR),
-	/*2896*/ uint16(x86_xArgXmm1),
-	/*2897*/ uint16(x86_xArgXmm2M128),
-	/*2898*/ uint16(x86_xMatch),
-	/*2899*/ uint16(x86_xCondPrefix), 1,
-	0x66, 2903,
-	/*2903*/ uint16(x86_xSetOp), uint16(x86_AESENC),
-	/*2905*/ uint16(x86_xReadSlashR),
-	/*2906*/ uint16(x86_xArgXmm1),
-	/*2907*/ uint16(x86_xArgXmm2M128),
-	/*2908*/ uint16(x86_xMatch),
-	/*2909*/ uint16(x86_xCondPrefix), 1,
-	0x66, 2913,
-	/*2913*/ uint16(x86_xSetOp), uint16(x86_AESENCLAST),
-	/*2915*/ uint16(x86_xReadSlashR),
-	/*2916*/ uint16(x86_xArgXmm1),
-	/*2917*/ uint16(x86_xArgXmm2M128),
-	/*2918*/ uint16(x86_xMatch),
-	/*2919*/ uint16(x86_xCondPrefix), 1,
-	0x66, 2923,
-	/*2923*/ uint16(x86_xSetOp), uint16(x86_AESDEC),
-	/*2925*/ uint16(x86_xReadSlashR),
-	/*2926*/ uint16(x86_xArgXmm1),
-	/*2927*/ uint16(x86_xArgXmm2M128),
-	/*2928*/ uint16(x86_xMatch),
-	/*2929*/ uint16(x86_xCondPrefix), 1,
-	0x66, 2933,
-	/*2933*/ uint16(x86_xSetOp), uint16(x86_AESDECLAST),
-	/*2935*/ uint16(x86_xReadSlashR),
-	/*2936*/ uint16(x86_xArgXmm1),
-	/*2937*/ uint16(x86_xArgXmm2M128),
-	/*2938*/ uint16(x86_xMatch),
-	/*2939*/ uint16(x86_xCondIs64), 2942, 2980,
-	/*2942*/ uint16(x86_xCondPrefix), 2,
-	0xF2, 2964,
-	0x0, 2948,
-	/*2948*/ uint16(x86_xCondDataSize), 2952, 2958, 0,
-	/*2952*/ uint16(x86_xSetOp), uint16(x86_MOVBE),
-	/*2954*/ uint16(x86_xReadSlashR),
-	/*2955*/ uint16(x86_xArgR16),
-	/*2956*/ uint16(x86_xArgM16),
-	/*2957*/ uint16(x86_xMatch),
-	/*2958*/ uint16(x86_xSetOp), uint16(x86_MOVBE),
-	/*2960*/ uint16(x86_xReadSlashR),
-	/*2961*/ uint16(x86_xArgR32),
-	/*2962*/ uint16(x86_xArgM32),
-	/*2963*/ uint16(x86_xMatch),
-	/*2964*/ uint16(x86_xCondDataSize), 2968, 2974, 0,
-	/*2968*/ uint16(x86_xSetOp), uint16(x86_CRC32),
-	/*2970*/ uint16(x86_xReadSlashR),
-	/*2971*/ uint16(x86_xArgR32),
-	/*2972*/ uint16(x86_xArgRM8),
-	/*2973*/ uint16(x86_xMatch),
-	/*2974*/ uint16(x86_xSetOp), uint16(x86_CRC32),
-	/*2976*/ uint16(x86_xReadSlashR),
-	/*2977*/ uint16(x86_xArgR32),
-	/*2978*/ uint16(x86_xArgRM8),
-	/*2979*/ uint16(x86_xMatch),
-	/*2980*/ uint16(x86_xCondPrefix), 2,
-	0xF2, 2996,
-	0x0, 2986,
-	/*2986*/ uint16(x86_xCondDataSize), 2952, 2958, 2990,
-	/*2990*/ uint16(x86_xSetOp), uint16(x86_MOVBE),
-	/*2992*/ uint16(x86_xReadSlashR),
-	/*2993*/ uint16(x86_xArgR64),
-	/*2994*/ uint16(x86_xArgM64),
-	/*2995*/ uint16(x86_xMatch),
-	/*2996*/ uint16(x86_xCondDataSize), 2968, 2974, 3000,
-	/*3000*/ uint16(x86_xSetOp), uint16(x86_CRC32),
-	/*3002*/ uint16(x86_xReadSlashR),
-	/*3003*/ uint16(x86_xArgR64),
-	/*3004*/ uint16(x86_xArgRM8),
-	/*3005*/ uint16(x86_xMatch),
-	/*3006*/ uint16(x86_xCondIs64), 3009, 3047,
-	/*3009*/ uint16(x86_xCondPrefix), 2,
-	0xF2, 3031,
-	0x0, 3015,
-	/*3015*/ uint16(x86_xCondDataSize), 3019, 3025, 0,
-	/*3019*/ uint16(x86_xSetOp), uint16(x86_MOVBE),
-	/*3021*/ uint16(x86_xReadSlashR),
-	/*3022*/ uint16(x86_xArgM16),
-	/*3023*/ uint16(x86_xArgR16),
-	/*3024*/ uint16(x86_xMatch),
-	/*3025*/ uint16(x86_xSetOp), uint16(x86_MOVBE),
-	/*3027*/ uint16(x86_xReadSlashR),
-	/*3028*/ uint16(x86_xArgM32),
-	/*3029*/ uint16(x86_xArgR32),
-	/*3030*/ uint16(x86_xMatch),
-	/*3031*/ uint16(x86_xCondDataSize), 3035, 3041, 0,
-	/*3035*/ uint16(x86_xSetOp), uint16(x86_CRC32),
-	/*3037*/ uint16(x86_xReadSlashR),
-	/*3038*/ uint16(x86_xArgR32),
-	/*3039*/ uint16(x86_xArgRM16),
-	/*3040*/ uint16(x86_xMatch),
-	/*3041*/ uint16(x86_xSetOp), uint16(x86_CRC32),
-	/*3043*/ uint16(x86_xReadSlashR),
-	/*3044*/ uint16(x86_xArgR32),
-	/*3045*/ uint16(x86_xArgRM32),
-	/*3046*/ uint16(x86_xMatch),
-	/*3047*/ uint16(x86_xCondPrefix), 2,
-	0xF2, 3063,
-	0x0, 3053,
-	/*3053*/ uint16(x86_xCondDataSize), 3019, 3025, 3057,
-	/*3057*/ uint16(x86_xSetOp), uint16(x86_MOVBE),
-	/*3059*/ uint16(x86_xReadSlashR),
-	/*3060*/ uint16(x86_xArgM64),
-	/*3061*/ uint16(x86_xArgR64),
-	/*3062*/ uint16(x86_xMatch),
-	/*3063*/ uint16(x86_xCondDataSize), 3035, 3041, 3067,
-	/*3067*/ uint16(x86_xSetOp), uint16(x86_CRC32),
-	/*3069*/ uint16(x86_xReadSlashR),
-	/*3070*/ uint16(x86_xArgR64),
-	/*3071*/ uint16(x86_xArgRM64),
-	/*3072*/ uint16(x86_xMatch),
-	/*3073*/ uint16(x86_xCondByte), 24,
-	0x08, 3124,
-	0x09, 3136,
-	0x0A, 3148,
-	0x0B, 3160,
-	0x0C, 3172,
-	0x0D, 3184,
-	0x0E, 3196,
-	0x0F, 3208,
-	0x14, 3230,
-	0x15, 3242,
-	0x16, 3254,
-	0x17, 3297,
-	0x20, 3309,
-	0x21, 3321,
-	0x22, 3333,
-	0x40, 3376,
-	0x41, 3388,
-	0x42, 3400,
-	0x44, 3412,
-	0x60, 3424,
-	0x61, 3436,
-	0x62, 3448,
-	0x63, 3460,
-	0xDF, 3472,
-	uint16(x86_xFail),
-	/*3124*/ uint16(x86_xCondPrefix), 1,
-	0x66, 3128,
-	/*3128*/ uint16(x86_xSetOp), uint16(x86_ROUNDPS),
-	/*3130*/ uint16(x86_xReadSlashR),
-	/*3131*/ uint16(x86_xReadIb),
-	/*3132*/ uint16(x86_xArgXmm1),
-	/*3133*/ uint16(x86_xArgXmm2M128),
-	/*3134*/ uint16(x86_xArgImm8u),
-	/*3135*/ uint16(x86_xMatch),
-	/*3136*/ uint16(x86_xCondPrefix), 1,
-	0x66, 3140,
-	/*3140*/ uint16(x86_xSetOp), uint16(x86_ROUNDPD),
-	/*3142*/ uint16(x86_xReadSlashR),
-	/*3143*/ uint16(x86_xReadIb),
-	/*3144*/ uint16(x86_xArgXmm1),
-	/*3145*/ uint16(x86_xArgXmm2M128),
-	/*3146*/ uint16(x86_xArgImm8u),
-	/*3147*/ uint16(x86_xMatch),
-	/*3148*/ uint16(x86_xCondPrefix), 1,
-	0x66, 3152,
-	/*3152*/ uint16(x86_xSetOp), uint16(x86_ROUNDSS),
-	/*3154*/ uint16(x86_xReadSlashR),
-	/*3155*/ uint16(x86_xReadIb),
-	/*3156*/ uint16(x86_xArgXmm1),
-	/*3157*/ uint16(x86_xArgXmm2M32),
-	/*3158*/ uint16(x86_xArgImm8u),
-	/*3159*/ uint16(x86_xMatch),
-	/*3160*/ uint16(x86_xCondPrefix), 1,
-	0x66, 3164,
-	/*3164*/ uint16(x86_xSetOp), uint16(x86_ROUNDSD),
-	/*3166*/ uint16(x86_xReadSlashR),
-	/*3167*/ uint16(x86_xReadIb),
-	/*3168*/ uint16(x86_xArgXmm1),
-	/*3169*/ uint16(x86_xArgXmm2M64),
-	/*3170*/ uint16(x86_xArgImm8u),
-	/*3171*/ uint16(x86_xMatch),
-	/*3172*/ uint16(x86_xCondPrefix), 1,
-	0x66, 3176,
-	/*3176*/ uint16(x86_xSetOp), uint16(x86_BLENDPS),
-	/*3178*/ uint16(x86_xReadSlashR),
-	/*3179*/ uint16(x86_xReadIb),
-	/*3180*/ uint16(x86_xArgXmm1),
-	/*3181*/ uint16(x86_xArgXmm2M128),
-	/*3182*/ uint16(x86_xArgImm8u),
-	/*3183*/ uint16(x86_xMatch),
-	/*3184*/ uint16(x86_xCondPrefix), 1,
-	0x66, 3188,
-	/*3188*/ uint16(x86_xSetOp), uint16(x86_BLENDPD),
-	/*3190*/ uint16(x86_xReadSlashR),
-	/*3191*/ uint16(x86_xReadIb),
-	/*3192*/ uint16(x86_xArgXmm1),
-	/*3193*/ uint16(x86_xArgXmm2M128),
-	/*3194*/ uint16(x86_xArgImm8u),
-	/*3195*/ uint16(x86_xMatch),
-	/*3196*/ uint16(x86_xCondPrefix), 1,
-	0x66, 3200,
-	/*3200*/ uint16(x86_xSetOp), uint16(x86_PBLENDW),
-	/*3202*/ uint16(x86_xReadSlashR),
-	/*3203*/ uint16(x86_xReadIb),
-	/*3204*/ uint16(x86_xArgXmm1),
-	/*3205*/ uint16(x86_xArgXmm2M128),
-	/*3206*/ uint16(x86_xArgImm8u),
-	/*3207*/ uint16(x86_xMatch),
-	/*3208*/ uint16(x86_xCondPrefix), 2,
-	0x66, 3222,
-	0x0, 3214,
-	/*3214*/ uint16(x86_xSetOp), uint16(x86_PALIGNR),
-	/*3216*/ uint16(x86_xReadSlashR),
-	/*3217*/ uint16(x86_xReadIb),
-	/*3218*/ uint16(x86_xArgMm1),
-	/*3219*/ uint16(x86_xArgMm2M64),
-	/*3220*/ uint16(x86_xArgImm8u),
-	/*3221*/ uint16(x86_xMatch),
-	/*3222*/ uint16(x86_xSetOp), uint16(x86_PALIGNR),
-	/*3224*/ uint16(x86_xReadSlashR),
-	/*3225*/ uint16(x86_xReadIb),
-	/*3226*/ uint16(x86_xArgXmm1),
-	/*3227*/ uint16(x86_xArgXmm2M128),
-	/*3228*/ uint16(x86_xArgImm8u),
-	/*3229*/ uint16(x86_xMatch),
-	/*3230*/ uint16(x86_xCondPrefix), 1,
-	0x66, 3234,
-	/*3234*/ uint16(x86_xSetOp), uint16(x86_PEXTRB),
-	/*3236*/ uint16(x86_xReadSlashR),
-	/*3237*/ uint16(x86_xReadIb),
-	/*3238*/ uint16(x86_xArgR32M8),
-	/*3239*/ uint16(x86_xArgXmm1),
-	/*3240*/ uint16(x86_xArgImm8u),
-	/*3241*/ uint16(x86_xMatch),
-	/*3242*/ uint16(x86_xCondPrefix), 1,
-	0x66, 3246,
-	/*3246*/ uint16(x86_xSetOp), uint16(x86_PEXTRW),
-	/*3248*/ uint16(x86_xReadSlashR),
-	/*3249*/ uint16(x86_xReadIb),
-	/*3250*/ uint16(x86_xArgR32M16),
-	/*3251*/ uint16(x86_xArgXmm1),
-	/*3252*/ uint16(x86_xArgImm8u),
-	/*3253*/ uint16(x86_xMatch),
-	/*3254*/ uint16(x86_xCondIs64), 3257, 3281,
-	/*3257*/ uint16(x86_xCondPrefix), 1,
-	0x66, 3261,
-	/*3261*/ uint16(x86_xCondDataSize), 3265, 3273, 0,
-	/*3265*/ uint16(x86_xSetOp), uint16(x86_PEXTRD),
-	/*3267*/ uint16(x86_xReadSlashR),
-	/*3268*/ uint16(x86_xReadIb),
-	/*3269*/ uint16(x86_xArgRM32),
-	/*3270*/ uint16(x86_xArgXmm1),
-	/*3271*/ uint16(x86_xArgImm8u),
-	/*3272*/ uint16(x86_xMatch),
-	/*3273*/ uint16(x86_xSetOp), uint16(x86_PEXTRD),
-	/*3275*/ uint16(x86_xReadSlashR),
-	/*3276*/ uint16(x86_xReadIb),
-	/*3277*/ uint16(x86_xArgRM32),
-	/*3278*/ uint16(x86_xArgXmm1),
-	/*3279*/ uint16(x86_xArgImm8u),
-	/*3280*/ uint16(x86_xMatch),
-	/*3281*/ uint16(x86_xCondPrefix), 1,
-	0x66, 3285,
-	/*3285*/ uint16(x86_xCondDataSize), 3265, 3273, 3289,
-	/*3289*/ uint16(x86_xSetOp), uint16(x86_PEXTRQ),
-	/*3291*/ uint16(x86_xReadSlashR),
-	/*3292*/ uint16(x86_xReadIb),
-	/*3293*/ uint16(x86_xArgRM64),
-	/*3294*/ uint16(x86_xArgXmm1),
-	/*3295*/ uint16(x86_xArgImm8u),
-	/*3296*/ uint16(x86_xMatch),
-	/*3297*/ uint16(x86_xCondPrefix), 1,
-	0x66, 3301,
-	/*3301*/ uint16(x86_xSetOp), uint16(x86_EXTRACTPS),
-	/*3303*/ uint16(x86_xReadSlashR),
-	/*3304*/ uint16(x86_xReadIb),
-	/*3305*/ uint16(x86_xArgRM32),
-	/*3306*/ uint16(x86_xArgXmm1),
-	/*3307*/ uint16(x86_xArgImm8u),
-	/*3308*/ uint16(x86_xMatch),
-	/*3309*/ uint16(x86_xCondPrefix), 1,
-	0x66, 3313,
-	/*3313*/ uint16(x86_xSetOp), uint16(x86_PINSRB),
-	/*3315*/ uint16(x86_xReadSlashR),
-	/*3316*/ uint16(x86_xReadIb),
-	/*3317*/ uint16(x86_xArgXmm1),
-	/*3318*/ uint16(x86_xArgR32M8),
-	/*3319*/ uint16(x86_xArgImm8u),
-	/*3320*/ uint16(x86_xMatch),
-	/*3321*/ uint16(x86_xCondPrefix), 1,
-	0x66, 3325,
-	/*3325*/ uint16(x86_xSetOp), uint16(x86_INSERTPS),
-	/*3327*/ uint16(x86_xReadSlashR),
-	/*3328*/ uint16(x86_xReadIb),
-	/*3329*/ uint16(x86_xArgXmm1),
-	/*3330*/ uint16(x86_xArgXmm2M32),
-	/*3331*/ uint16(x86_xArgImm8u),
-	/*3332*/ uint16(x86_xMatch),
-	/*3333*/ uint16(x86_xCondIs64), 3336, 3360,
-	/*3336*/ uint16(x86_xCondPrefix), 1,
-	0x66, 3340,
-	/*3340*/ uint16(x86_xCondDataSize), 3344, 3352, 0,
-	/*3344*/ uint16(x86_xSetOp), uint16(x86_PINSRD),
-	/*3346*/ uint16(x86_xReadSlashR),
-	/*3347*/ uint16(x86_xReadIb),
-	/*3348*/ uint16(x86_xArgXmm1),
-	/*3349*/ uint16(x86_xArgRM32),
-	/*3350*/ uint16(x86_xArgImm8u),
-	/*3351*/ uint16(x86_xMatch),
-	/*3352*/ uint16(x86_xSetOp), uint16(x86_PINSRD),
-	/*3354*/ uint16(x86_xReadSlashR),
-	/*3355*/ uint16(x86_xReadIb),
-	/*3356*/ uint16(x86_xArgXmm1),
-	/*3357*/ uint16(x86_xArgRM32),
-	/*3358*/ uint16(x86_xArgImm8u),
-	/*3359*/ uint16(x86_xMatch),
-	/*3360*/ uint16(x86_xCondPrefix), 1,
-	0x66, 3364,
-	/*3364*/ uint16(x86_xCondDataSize), 3344, 3352, 3368,
-	/*3368*/ uint16(x86_xSetOp), uint16(x86_PINSRQ),
-	/*3370*/ uint16(x86_xReadSlashR),
-	/*3371*/ uint16(x86_xReadIb),
-	/*3372*/ uint16(x86_xArgXmm1),
-	/*3373*/ uint16(x86_xArgRM64),
-	/*3374*/ uint16(x86_xArgImm8u),
-	/*3375*/ uint16(x86_xMatch),
-	/*3376*/ uint16(x86_xCondPrefix), 1,
-	0x66, 3380,
-	/*3380*/ uint16(x86_xSetOp), uint16(x86_DPPS),
-	/*3382*/ uint16(x86_xReadSlashR),
-	/*3383*/ uint16(x86_xReadIb),
-	/*3384*/ uint16(x86_xArgXmm1),
-	/*3385*/ uint16(x86_xArgXmm2M128),
-	/*3386*/ uint16(x86_xArgImm8u),
-	/*3387*/ uint16(x86_xMatch),
-	/*3388*/ uint16(x86_xCondPrefix), 1,
-	0x66, 3392,
-	/*3392*/ uint16(x86_xSetOp), uint16(x86_DPPD),
-	/*3394*/ uint16(x86_xReadSlashR),
-	/*3395*/ uint16(x86_xReadIb),
-	/*3396*/ uint16(x86_xArgXmm1),
-	/*3397*/ uint16(x86_xArgXmm2M128),
-	/*3398*/ uint16(x86_xArgImm8u),
-	/*3399*/ uint16(x86_xMatch),
-	/*3400*/ uint16(x86_xCondPrefix), 1,
-	0x66, 3404,
-	/*3404*/ uint16(x86_xSetOp), uint16(x86_MPSADBW),
-	/*3406*/ uint16(x86_xReadSlashR),
-	/*3407*/ uint16(x86_xReadIb),
-	/*3408*/ uint16(x86_xArgXmm1),
-	/*3409*/ uint16(x86_xArgXmm2M128),
-	/*3410*/ uint16(x86_xArgImm8u),
-	/*3411*/ uint16(x86_xMatch),
-	/*3412*/ uint16(x86_xCondPrefix), 1,
-	0x66, 3416,
-	/*3416*/ uint16(x86_xSetOp), uint16(x86_PCLMULQDQ),
-	/*3418*/ uint16(x86_xReadSlashR),
-	/*3419*/ uint16(x86_xReadIb),
-	/*3420*/ uint16(x86_xArgXmm1),
-	/*3421*/ uint16(x86_xArgXmm2M128),
-	/*3422*/ uint16(x86_xArgImm8u),
-	/*3423*/ uint16(x86_xMatch),
-	/*3424*/ uint16(x86_xCondPrefix), 1,
-	0x66, 3428,
-	/*3428*/ uint16(x86_xSetOp), uint16(x86_PCMPESTRM),
-	/*3430*/ uint16(x86_xReadSlashR),
-	/*3431*/ uint16(x86_xReadIb),
-	/*3432*/ uint16(x86_xArgXmm1),
-	/*3433*/ uint16(x86_xArgXmm2M128),
-	/*3434*/ uint16(x86_xArgImm8u),
-	/*3435*/ uint16(x86_xMatch),
-	/*3436*/ uint16(x86_xCondPrefix), 1,
-	0x66, 3440,
-	/*3440*/ uint16(x86_xSetOp), uint16(x86_PCMPESTRI),
-	/*3442*/ uint16(x86_xReadSlashR),
-	/*3443*/ uint16(x86_xReadIb),
-	/*3444*/ uint16(x86_xArgXmm1),
-	/*3445*/ uint16(x86_xArgXmm2M128),
-	/*3446*/ uint16(x86_xArgImm8u),
-	/*3447*/ uint16(x86_xMatch),
-	/*3448*/ uint16(x86_xCondPrefix), 1,
-	0x66, 3452,
-	/*3452*/ uint16(x86_xSetOp), uint16(x86_PCMPISTRM),
-	/*3454*/ uint16(x86_xReadSlashR),
-	/*3455*/ uint16(x86_xReadIb),
-	/*3456*/ uint16(x86_xArgXmm1),
-	/*3457*/ uint16(x86_xArgXmm2M128),
-	/*3458*/ uint16(x86_xArgImm8u),
-	/*3459*/ uint16(x86_xMatch),
-	/*3460*/ uint16(x86_xCondPrefix), 1,
-	0x66, 3464,
-	/*3464*/ uint16(x86_xSetOp), uint16(x86_PCMPISTRI),
-	/*3466*/ uint16(x86_xReadSlashR),
-	/*3467*/ uint16(x86_xReadIb),
-	/*3468*/ uint16(x86_xArgXmm1),
-	/*3469*/ uint16(x86_xArgXmm2M128),
-	/*3470*/ uint16(x86_xArgImm8u),
-	/*3471*/ uint16(x86_xMatch),
-	/*3472*/ uint16(x86_xCondPrefix), 1,
-	0x66, 3476,
-	/*3476*/ uint16(x86_xSetOp), uint16(x86_AESKEYGENASSIST),
-	/*3478*/ uint16(x86_xReadSlashR),
-	/*3479*/ uint16(x86_xReadIb),
-	/*3480*/ uint16(x86_xArgXmm1),
-	/*3481*/ uint16(x86_xArgXmm2M128),
-	/*3482*/ uint16(x86_xArgImm8u),
-	/*3483*/ uint16(x86_xMatch),
-	/*3484*/ uint16(x86_xCondIs64), 3487, 3503,
-	/*3487*/ uint16(x86_xCondDataSize), 3491, 3497, 0,
-	/*3491*/ uint16(x86_xSetOp), uint16(x86_CMOVO),
-	/*3493*/ uint16(x86_xReadSlashR),
-	/*3494*/ uint16(x86_xArgR16),
-	/*3495*/ uint16(x86_xArgRM16),
-	/*3496*/ uint16(x86_xMatch),
-	/*3497*/ uint16(x86_xSetOp), uint16(x86_CMOVO),
-	/*3499*/ uint16(x86_xReadSlashR),
-	/*3500*/ uint16(x86_xArgR32),
-	/*3501*/ uint16(x86_xArgRM32),
-	/*3502*/ uint16(x86_xMatch),
-	/*3503*/ uint16(x86_xCondDataSize), 3491, 3497, 3507,
-	/*3507*/ uint16(x86_xSetOp), uint16(x86_CMOVO),
-	/*3509*/ uint16(x86_xReadSlashR),
-	/*3510*/ uint16(x86_xArgR64),
-	/*3511*/ uint16(x86_xArgRM64),
-	/*3512*/ uint16(x86_xMatch),
-	/*3513*/ uint16(x86_xCondIs64), 3516, 3532,
-	/*3516*/ uint16(x86_xCondDataSize), 3520, 3526, 0,
-	/*3520*/ uint16(x86_xSetOp), uint16(x86_CMOVNO),
-	/*3522*/ uint16(x86_xReadSlashR),
-	/*3523*/ uint16(x86_xArgR16),
-	/*3524*/ uint16(x86_xArgRM16),
-	/*3525*/ uint16(x86_xMatch),
-	/*3526*/ uint16(x86_xSetOp), uint16(x86_CMOVNO),
-	/*3528*/ uint16(x86_xReadSlashR),
-	/*3529*/ uint16(x86_xArgR32),
-	/*3530*/ uint16(x86_xArgRM32),
-	/*3531*/ uint16(x86_xMatch),
-	/*3532*/ uint16(x86_xCondDataSize), 3520, 3526, 3536,
-	/*3536*/ uint16(x86_xSetOp), uint16(x86_CMOVNO),
-	/*3538*/ uint16(x86_xReadSlashR),
-	/*3539*/ uint16(x86_xArgR64),
-	/*3540*/ uint16(x86_xArgRM64),
-	/*3541*/ uint16(x86_xMatch),
-	/*3542*/ uint16(x86_xCondIs64), 3545, 3561,
-	/*3545*/ uint16(x86_xCondDataSize), 3549, 3555, 0,
-	/*3549*/ uint16(x86_xSetOp), uint16(x86_CMOVB),
-	/*3551*/ uint16(x86_xReadSlashR),
-	/*3552*/ uint16(x86_xArgR16),
-	/*3553*/ uint16(x86_xArgRM16),
-	/*3554*/ uint16(x86_xMatch),
-	/*3555*/ uint16(x86_xSetOp), uint16(x86_CMOVB),
-	/*3557*/ uint16(x86_xReadSlashR),
-	/*3558*/ uint16(x86_xArgR32),
-	/*3559*/ uint16(x86_xArgRM32),
-	/*3560*/ uint16(x86_xMatch),
-	/*3561*/ uint16(x86_xCondDataSize), 3549, 3555, 3565,
-	/*3565*/ uint16(x86_xSetOp), uint16(x86_CMOVB),
-	/*3567*/ uint16(x86_xReadSlashR),
-	/*3568*/ uint16(x86_xArgR64),
-	/*3569*/ uint16(x86_xArgRM64),
-	/*3570*/ uint16(x86_xMatch),
-	/*3571*/ uint16(x86_xCondIs64), 3574, 3590,
-	/*3574*/ uint16(x86_xCondDataSize), 3578, 3584, 0,
-	/*3578*/ uint16(x86_xSetOp), uint16(x86_CMOVAE),
-	/*3580*/ uint16(x86_xReadSlashR),
-	/*3581*/ uint16(x86_xArgR16),
-	/*3582*/ uint16(x86_xArgRM16),
-	/*3583*/ uint16(x86_xMatch),
-	/*3584*/ uint16(x86_xSetOp), uint16(x86_CMOVAE),
-	/*3586*/ uint16(x86_xReadSlashR),
-	/*3587*/ uint16(x86_xArgR32),
-	/*3588*/ uint16(x86_xArgRM32),
-	/*3589*/ uint16(x86_xMatch),
-	/*3590*/ uint16(x86_xCondDataSize), 3578, 3584, 3594,
-	/*3594*/ uint16(x86_xSetOp), uint16(x86_CMOVAE),
-	/*3596*/ uint16(x86_xReadSlashR),
-	/*3597*/ uint16(x86_xArgR64),
-	/*3598*/ uint16(x86_xArgRM64),
-	/*3599*/ uint16(x86_xMatch),
-	/*3600*/ uint16(x86_xCondIs64), 3603, 3619,
-	/*3603*/ uint16(x86_xCondDataSize), 3607, 3613, 0,
-	/*3607*/ uint16(x86_xSetOp), uint16(x86_CMOVE),
-	/*3609*/ uint16(x86_xReadSlashR),
-	/*3610*/ uint16(x86_xArgR16),
-	/*3611*/ uint16(x86_xArgRM16),
-	/*3612*/ uint16(x86_xMatch),
-	/*3613*/ uint16(x86_xSetOp), uint16(x86_CMOVE),
-	/*3615*/ uint16(x86_xReadSlashR),
-	/*3616*/ uint16(x86_xArgR32),
-	/*3617*/ uint16(x86_xArgRM32),
-	/*3618*/ uint16(x86_xMatch),
-	/*3619*/ uint16(x86_xCondDataSize), 3607, 3613, 3623,
-	/*3623*/ uint16(x86_xSetOp), uint16(x86_CMOVE),
-	/*3625*/ uint16(x86_xReadSlashR),
-	/*3626*/ uint16(x86_xArgR64),
-	/*3627*/ uint16(x86_xArgRM64),
-	/*3628*/ uint16(x86_xMatch),
-	/*3629*/ uint16(x86_xCondIs64), 3632, 3648,
-	/*3632*/ uint16(x86_xCondDataSize), 3636, 3642, 0,
-	/*3636*/ uint16(x86_xSetOp), uint16(x86_CMOVNE),
-	/*3638*/ uint16(x86_xReadSlashR),
-	/*3639*/ uint16(x86_xArgR16),
-	/*3640*/ uint16(x86_xArgRM16),
-	/*3641*/ uint16(x86_xMatch),
-	/*3642*/ uint16(x86_xSetOp), uint16(x86_CMOVNE),
-	/*3644*/ uint16(x86_xReadSlashR),
-	/*3645*/ uint16(x86_xArgR32),
-	/*3646*/ uint16(x86_xArgRM32),
-	/*3647*/ uint16(x86_xMatch),
-	/*3648*/ uint16(x86_xCondDataSize), 3636, 3642, 3652,
-	/*3652*/ uint16(x86_xSetOp), uint16(x86_CMOVNE),
-	/*3654*/ uint16(x86_xReadSlashR),
-	/*3655*/ uint16(x86_xArgR64),
-	/*3656*/ uint16(x86_xArgRM64),
-	/*3657*/ uint16(x86_xMatch),
-	/*3658*/ uint16(x86_xCondIs64), 3661, 3677,
-	/*3661*/ uint16(x86_xCondDataSize), 3665, 3671, 0,
-	/*3665*/ uint16(x86_xSetOp), uint16(x86_CMOVBE),
-	/*3667*/ uint16(x86_xReadSlashR),
-	/*3668*/ uint16(x86_xArgR16),
-	/*3669*/ uint16(x86_xArgRM16),
-	/*3670*/ uint16(x86_xMatch),
-	/*3671*/ uint16(x86_xSetOp), uint16(x86_CMOVBE),
-	/*3673*/ uint16(x86_xReadSlashR),
-	/*3674*/ uint16(x86_xArgR32),
-	/*3675*/ uint16(x86_xArgRM32),
-	/*3676*/ uint16(x86_xMatch),
-	/*3677*/ uint16(x86_xCondDataSize), 3665, 3671, 3681,
-	/*3681*/ uint16(x86_xSetOp), uint16(x86_CMOVBE),
-	/*3683*/ uint16(x86_xReadSlashR),
-	/*3684*/ uint16(x86_xArgR64),
-	/*3685*/ uint16(x86_xArgRM64),
-	/*3686*/ uint16(x86_xMatch),
-	/*3687*/ uint16(x86_xCondIs64), 3690, 3706,
-	/*3690*/ uint16(x86_xCondDataSize), 3694, 3700, 0,
-	/*3694*/ uint16(x86_xSetOp), uint16(x86_CMOVA),
-	/*3696*/ uint16(x86_xReadSlashR),
-	/*3697*/ uint16(x86_xArgR16),
-	/*3698*/ uint16(x86_xArgRM16),
-	/*3699*/ uint16(x86_xMatch),
-	/*3700*/ uint16(x86_xSetOp), uint16(x86_CMOVA),
-	/*3702*/ uint16(x86_xReadSlashR),
-	/*3703*/ uint16(x86_xArgR32),
-	/*3704*/ uint16(x86_xArgRM32),
-	/*3705*/ uint16(x86_xMatch),
-	/*3706*/ uint16(x86_xCondDataSize), 3694, 3700, 3710,
-	/*3710*/ uint16(x86_xSetOp), uint16(x86_CMOVA),
-	/*3712*/ uint16(x86_xReadSlashR),
-	/*3713*/ uint16(x86_xArgR64),
-	/*3714*/ uint16(x86_xArgRM64),
-	/*3715*/ uint16(x86_xMatch),
-	/*3716*/ uint16(x86_xCondIs64), 3719, 3735,
-	/*3719*/ uint16(x86_xCondDataSize), 3723, 3729, 0,
-	/*3723*/ uint16(x86_xSetOp), uint16(x86_CMOVS),
-	/*3725*/ uint16(x86_xReadSlashR),
-	/*3726*/ uint16(x86_xArgR16),
-	/*3727*/ uint16(x86_xArgRM16),
-	/*3728*/ uint16(x86_xMatch),
-	/*3729*/ uint16(x86_xSetOp), uint16(x86_CMOVS),
-	/*3731*/ uint16(x86_xReadSlashR),
-	/*3732*/ uint16(x86_xArgR32),
-	/*3733*/ uint16(x86_xArgRM32),
-	/*3734*/ uint16(x86_xMatch),
-	/*3735*/ uint16(x86_xCondDataSize), 3723, 3729, 3739,
-	/*3739*/ uint16(x86_xSetOp), uint16(x86_CMOVS),
-	/*3741*/ uint16(x86_xReadSlashR),
-	/*3742*/ uint16(x86_xArgR64),
-	/*3743*/ uint16(x86_xArgRM64),
-	/*3744*/ uint16(x86_xMatch),
-	/*3745*/ uint16(x86_xCondIs64), 3748, 3764,
-	/*3748*/ uint16(x86_xCondDataSize), 3752, 3758, 0,
-	/*3752*/ uint16(x86_xSetOp), uint16(x86_CMOVNS),
-	/*3754*/ uint16(x86_xReadSlashR),
-	/*3755*/ uint16(x86_xArgR16),
-	/*3756*/ uint16(x86_xArgRM16),
-	/*3757*/ uint16(x86_xMatch),
-	/*3758*/ uint16(x86_xSetOp), uint16(x86_CMOVNS),
-	/*3760*/ uint16(x86_xReadSlashR),
-	/*3761*/ uint16(x86_xArgR32),
-	/*3762*/ uint16(x86_xArgRM32),
-	/*3763*/ uint16(x86_xMatch),
-	/*3764*/ uint16(x86_xCondDataSize), 3752, 3758, 3768,
-	/*3768*/ uint16(x86_xSetOp), uint16(x86_CMOVNS),
-	/*3770*/ uint16(x86_xReadSlashR),
-	/*3771*/ uint16(x86_xArgR64),
-	/*3772*/ uint16(x86_xArgRM64),
-	/*3773*/ uint16(x86_xMatch),
-	/*3774*/ uint16(x86_xCondIs64), 3777, 3793,
-	/*3777*/ uint16(x86_xCondDataSize), 3781, 3787, 0,
-	/*3781*/ uint16(x86_xSetOp), uint16(x86_CMOVP),
-	/*3783*/ uint16(x86_xReadSlashR),
-	/*3784*/ uint16(x86_xArgR16),
-	/*3785*/ uint16(x86_xArgRM16),
-	/*3786*/ uint16(x86_xMatch),
-	/*3787*/ uint16(x86_xSetOp), uint16(x86_CMOVP),
-	/*3789*/ uint16(x86_xReadSlashR),
-	/*3790*/ uint16(x86_xArgR32),
-	/*3791*/ uint16(x86_xArgRM32),
-	/*3792*/ uint16(x86_xMatch),
-	/*3793*/ uint16(x86_xCondDataSize), 3781, 3787, 3797,
-	/*3797*/ uint16(x86_xSetOp), uint16(x86_CMOVP),
-	/*3799*/ uint16(x86_xReadSlashR),
-	/*3800*/ uint16(x86_xArgR64),
-	/*3801*/ uint16(x86_xArgRM64),
-	/*3802*/ uint16(x86_xMatch),
-	/*3803*/ uint16(x86_xCondIs64), 3806, 3822,
-	/*3806*/ uint16(x86_xCondDataSize), 3810, 3816, 0,
-	/*3810*/ uint16(x86_xSetOp), uint16(x86_CMOVNP),
-	/*3812*/ uint16(x86_xReadSlashR),
-	/*3813*/ uint16(x86_xArgR16),
-	/*3814*/ uint16(x86_xArgRM16),
-	/*3815*/ uint16(x86_xMatch),
-	/*3816*/ uint16(x86_xSetOp), uint16(x86_CMOVNP),
-	/*3818*/ uint16(x86_xReadSlashR),
-	/*3819*/ uint16(x86_xArgR32),
-	/*3820*/ uint16(x86_xArgRM32),
-	/*3821*/ uint16(x86_xMatch),
-	/*3822*/ uint16(x86_xCondDataSize), 3810, 3816, 3826,
-	/*3826*/ uint16(x86_xSetOp), uint16(x86_CMOVNP),
-	/*3828*/ uint16(x86_xReadSlashR),
-	/*3829*/ uint16(x86_xArgR64),
-	/*3830*/ uint16(x86_xArgRM64),
-	/*3831*/ uint16(x86_xMatch),
-	/*3832*/ uint16(x86_xCondIs64), 3835, 3851,
-	/*3835*/ uint16(x86_xCondDataSize), 3839, 3845, 0,
-	/*3839*/ uint16(x86_xSetOp), uint16(x86_CMOVL),
-	/*3841*/ uint16(x86_xReadSlashR),
-	/*3842*/ uint16(x86_xArgR16),
-	/*3843*/ uint16(x86_xArgRM16),
-	/*3844*/ uint16(x86_xMatch),
-	/*3845*/ uint16(x86_xSetOp), uint16(x86_CMOVL),
-	/*3847*/ uint16(x86_xReadSlashR),
-	/*3848*/ uint16(x86_xArgR32),
-	/*3849*/ uint16(x86_xArgRM32),
-	/*3850*/ uint16(x86_xMatch),
-	/*3851*/ uint16(x86_xCondDataSize), 3839, 3845, 3855,
-	/*3855*/ uint16(x86_xSetOp), uint16(x86_CMOVL),
-	/*3857*/ uint16(x86_xReadSlashR),
-	/*3858*/ uint16(x86_xArgR64),
-	/*3859*/ uint16(x86_xArgRM64),
-	/*3860*/ uint16(x86_xMatch),
-	/*3861*/ uint16(x86_xCondIs64), 3864, 3880,
-	/*3864*/ uint16(x86_xCondDataSize), 3868, 3874, 0,
-	/*3868*/ uint16(x86_xSetOp), uint16(x86_CMOVGE),
-	/*3870*/ uint16(x86_xReadSlashR),
-	/*3871*/ uint16(x86_xArgR16),
-	/*3872*/ uint16(x86_xArgRM16),
-	/*3873*/ uint16(x86_xMatch),
-	/*3874*/ uint16(x86_xSetOp), uint16(x86_CMOVGE),
-	/*3876*/ uint16(x86_xReadSlashR),
-	/*3877*/ uint16(x86_xArgR32),
-	/*3878*/ uint16(x86_xArgRM32),
-	/*3879*/ uint16(x86_xMatch),
-	/*3880*/ uint16(x86_xCondDataSize), 3868, 3874, 3884,
-	/*3884*/ uint16(x86_xSetOp), uint16(x86_CMOVGE),
-	/*3886*/ uint16(x86_xReadSlashR),
-	/*3887*/ uint16(x86_xArgR64),
-	/*3888*/ uint16(x86_xArgRM64),
-	/*3889*/ uint16(x86_xMatch),
-	/*3890*/ uint16(x86_xCondIs64), 3893, 3909,
-	/*3893*/ uint16(x86_xCondDataSize), 3897, 3903, 0,
-	/*3897*/ uint16(x86_xSetOp), uint16(x86_CMOVLE),
-	/*3899*/ uint16(x86_xReadSlashR),
-	/*3900*/ uint16(x86_xArgR16),
-	/*3901*/ uint16(x86_xArgRM16),
-	/*3902*/ uint16(x86_xMatch),
-	/*3903*/ uint16(x86_xSetOp), uint16(x86_CMOVLE),
-	/*3905*/ uint16(x86_xReadSlashR),
-	/*3906*/ uint16(x86_xArgR32),
-	/*3907*/ uint16(x86_xArgRM32),
-	/*3908*/ uint16(x86_xMatch),
-	/*3909*/ uint16(x86_xCondDataSize), 3897, 3903, 3913,
-	/*3913*/ uint16(x86_xSetOp), uint16(x86_CMOVLE),
-	/*3915*/ uint16(x86_xReadSlashR),
-	/*3916*/ uint16(x86_xArgR64),
-	/*3917*/ uint16(x86_xArgRM64),
-	/*3918*/ uint16(x86_xMatch),
-	/*3919*/ uint16(x86_xCondIs64), 3922, 3938,
-	/*3922*/ uint16(x86_xCondDataSize), 3926, 3932, 0,
-	/*3926*/ uint16(x86_xSetOp), uint16(x86_CMOVG),
-	/*3928*/ uint16(x86_xReadSlashR),
-	/*3929*/ uint16(x86_xArgR16),
-	/*3930*/ uint16(x86_xArgRM16),
-	/*3931*/ uint16(x86_xMatch),
-	/*3932*/ uint16(x86_xSetOp), uint16(x86_CMOVG),
-	/*3934*/ uint16(x86_xReadSlashR),
-	/*3935*/ uint16(x86_xArgR32),
-	/*3936*/ uint16(x86_xArgRM32),
-	/*3937*/ uint16(x86_xMatch),
-	/*3938*/ uint16(x86_xCondDataSize), 3926, 3932, 3942,
-	/*3942*/ uint16(x86_xSetOp), uint16(x86_CMOVG),
-	/*3944*/ uint16(x86_xReadSlashR),
-	/*3945*/ uint16(x86_xArgR64),
-	/*3946*/ uint16(x86_xArgRM64),
-	/*3947*/ uint16(x86_xMatch),
-	/*3948*/ uint16(x86_xCondPrefix), 2,
-	0x66, 3960,
-	0x0, 3954,
-	/*3954*/ uint16(x86_xSetOp), uint16(x86_MOVMSKPS),
-	/*3956*/ uint16(x86_xReadSlashR),
-	/*3957*/ uint16(x86_xArgR32),
-	/*3958*/ uint16(x86_xArgXmm2),
-	/*3959*/ uint16(x86_xMatch),
-	/*3960*/ uint16(x86_xSetOp), uint16(x86_MOVMSKPD),
-	/*3962*/ uint16(x86_xReadSlashR),
-	/*3963*/ uint16(x86_xArgR32),
-	/*3964*/ uint16(x86_xArgXmm2),
-	/*3965*/ uint16(x86_xMatch),
-	/*3966*/ uint16(x86_xCondPrefix), 4,
-	0xF3, 3994,
-	0xF2, 3988,
-	0x66, 3982,
-	0x0, 3976,
-	/*3976*/ uint16(x86_xSetOp), uint16(x86_SQRTPS),
-	/*3978*/ uint16(x86_xReadSlashR),
-	/*3979*/ uint16(x86_xArgXmm1),
-	/*3980*/ uint16(x86_xArgXmm2M128),
-	/*3981*/ uint16(x86_xMatch),
-	/*3982*/ uint16(x86_xSetOp), uint16(x86_SQRTPD),
-	/*3984*/ uint16(x86_xReadSlashR),
-	/*3985*/ uint16(x86_xArgXmm1),
-	/*3986*/ uint16(x86_xArgXmm2M128),
-	/*3987*/ uint16(x86_xMatch),
-	/*3988*/ uint16(x86_xSetOp), uint16(x86_SQRTSD),
-	/*3990*/ uint16(x86_xReadSlashR),
-	/*3991*/ uint16(x86_xArgXmm1),
-	/*3992*/ uint16(x86_xArgXmm2M64),
-	/*3993*/ uint16(x86_xMatch),
-	/*3994*/ uint16(x86_xSetOp), uint16(x86_SQRTSS),
-	/*3996*/ uint16(x86_xReadSlashR),
-	/*3997*/ uint16(x86_xArgXmm1),
-	/*3998*/ uint16(x86_xArgXmm2M32),
-	/*3999*/ uint16(x86_xMatch),
-	/*4000*/ uint16(x86_xCondPrefix), 2,
-	0xF3, 4012,
-	0x0, 4006,
-	/*4006*/ uint16(x86_xSetOp), uint16(x86_RSQRTPS),
-	/*4008*/ uint16(x86_xReadSlashR),
-	/*4009*/ uint16(x86_xArgXmm1),
-	/*4010*/ uint16(x86_xArgXmm2M128),
-	/*4011*/ uint16(x86_xMatch),
-	/*4012*/ uint16(x86_xSetOp), uint16(x86_RSQRTSS),
-	/*4014*/ uint16(x86_xReadSlashR),
-	/*4015*/ uint16(x86_xArgXmm1),
-	/*4016*/ uint16(x86_xArgXmm2M32),
-	/*4017*/ uint16(x86_xMatch),
-	/*4018*/ uint16(x86_xCondPrefix), 2,
-	0xF3, 4030,
-	0x0, 4024,
-	/*4024*/ uint16(x86_xSetOp), uint16(x86_RCPPS),
-	/*4026*/ uint16(x86_xReadSlashR),
-	/*4027*/ uint16(x86_xArgXmm1),
-	/*4028*/ uint16(x86_xArgXmm2M128),
-	/*4029*/ uint16(x86_xMatch),
-	/*4030*/ uint16(x86_xSetOp), uint16(x86_RCPSS),
-	/*4032*/ uint16(x86_xReadSlashR),
-	/*4033*/ uint16(x86_xArgXmm1),
-	/*4034*/ uint16(x86_xArgXmm2M32),
-	/*4035*/ uint16(x86_xMatch),
-	/*4036*/ uint16(x86_xCondPrefix), 2,
-	0x66, 4048,
-	0x0, 4042,
-	/*4042*/ uint16(x86_xSetOp), uint16(x86_ANDPS),
-	/*4044*/ uint16(x86_xReadSlashR),
-	/*4045*/ uint16(x86_xArgXmm1),
-	/*4046*/ uint16(x86_xArgXmm2M128),
-	/*4047*/ uint16(x86_xMatch),
-	/*4048*/ uint16(x86_xSetOp), uint16(x86_ANDPD),
-	/*4050*/ uint16(x86_xReadSlashR),
-	/*4051*/ uint16(x86_xArgXmm1),
-	/*4052*/ uint16(x86_xArgXmm2M128),
-	/*4053*/ uint16(x86_xMatch),
-	/*4054*/ uint16(x86_xCondPrefix), 2,
-	0x66, 4066,
-	0x0, 4060,
-	/*4060*/ uint16(x86_xSetOp), uint16(x86_ANDNPS),
-	/*4062*/ uint16(x86_xReadSlashR),
-	/*4063*/ uint16(x86_xArgXmm1),
-	/*4064*/ uint16(x86_xArgXmm2M128),
-	/*4065*/ uint16(x86_xMatch),
-	/*4066*/ uint16(x86_xSetOp), uint16(x86_ANDNPD),
-	/*4068*/ uint16(x86_xReadSlashR),
-	/*4069*/ uint16(x86_xArgXmm1),
-	/*4070*/ uint16(x86_xArgXmm2M128),
-	/*4071*/ uint16(x86_xMatch),
-	/*4072*/ uint16(x86_xCondPrefix), 2,
-	0x66, 4084,
-	0x0, 4078,
-	/*4078*/ uint16(x86_xSetOp), uint16(x86_ORPS),
-	/*4080*/ uint16(x86_xReadSlashR),
-	/*4081*/ uint16(x86_xArgXmm1),
-	/*4082*/ uint16(x86_xArgXmm2M128),
-	/*4083*/ uint16(x86_xMatch),
-	/*4084*/ uint16(x86_xSetOp), uint16(x86_ORPD),
-	/*4086*/ uint16(x86_xReadSlashR),
-	/*4087*/ uint16(x86_xArgXmm1),
-	/*4088*/ uint16(x86_xArgXmm2M128),
-	/*4089*/ uint16(x86_xMatch),
-	/*4090*/ uint16(x86_xCondPrefix), 2,
-	0x66, 4102,
-	0x0, 4096,
-	/*4096*/ uint16(x86_xSetOp), uint16(x86_XORPS),
-	/*4098*/ uint16(x86_xReadSlashR),
-	/*4099*/ uint16(x86_xArgXmm1),
-	/*4100*/ uint16(x86_xArgXmm2M128),
-	/*4101*/ uint16(x86_xMatch),
-	/*4102*/ uint16(x86_xSetOp), uint16(x86_XORPD),
-	/*4104*/ uint16(x86_xReadSlashR),
-	/*4105*/ uint16(x86_xArgXmm1),
-	/*4106*/ uint16(x86_xArgXmm2M128),
-	/*4107*/ uint16(x86_xMatch),
-	/*4108*/ uint16(x86_xCondPrefix), 4,
-	0xF3, 4136,
-	0xF2, 4130,
-	0x66, 4124,
-	0x0, 4118,
-	/*4118*/ uint16(x86_xSetOp), uint16(x86_ADDPS),
-	/*4120*/ uint16(x86_xReadSlashR),
-	/*4121*/ uint16(x86_xArgXmm1),
-	/*4122*/ uint16(x86_xArgXmm2M128),
-	/*4123*/ uint16(x86_xMatch),
-	/*4124*/ uint16(x86_xSetOp), uint16(x86_ADDPD),
-	/*4126*/ uint16(x86_xReadSlashR),
-	/*4127*/ uint16(x86_xArgXmm1),
-	/*4128*/ uint16(x86_xArgXmm2M128),
-	/*4129*/ uint16(x86_xMatch),
-	/*4130*/ uint16(x86_xSetOp), uint16(x86_ADDSD),
-	/*4132*/ uint16(x86_xReadSlashR),
-	/*4133*/ uint16(x86_xArgXmm1),
-	/*4134*/ uint16(x86_xArgXmm2M64),
-	/*4135*/ uint16(x86_xMatch),
-	/*4136*/ uint16(x86_xSetOp), uint16(x86_ADDSS),
-	/*4138*/ uint16(x86_xReadSlashR),
-	/*4139*/ uint16(x86_xArgXmm1),
-	/*4140*/ uint16(x86_xArgXmm2M32),
-	/*4141*/ uint16(x86_xMatch),
-	/*4142*/ uint16(x86_xCondPrefix), 4,
-	0xF3, 4170,
-	0xF2, 4164,
-	0x66, 4158,
-	0x0, 4152,
-	/*4152*/ uint16(x86_xSetOp), uint16(x86_MULPS),
-	/*4154*/ uint16(x86_xReadSlashR),
-	/*4155*/ uint16(x86_xArgXmm1),
-	/*4156*/ uint16(x86_xArgXmm2M128),
-	/*4157*/ uint16(x86_xMatch),
-	/*4158*/ uint16(x86_xSetOp), uint16(x86_MULPD),
-	/*4160*/ uint16(x86_xReadSlashR),
-	/*4161*/ uint16(x86_xArgXmm1),
-	/*4162*/ uint16(x86_xArgXmm2M128),
-	/*4163*/ uint16(x86_xMatch),
-	/*4164*/ uint16(x86_xSetOp), uint16(x86_MULSD),
-	/*4166*/ uint16(x86_xReadSlashR),
-	/*4167*/ uint16(x86_xArgXmm1),
-	/*4168*/ uint16(x86_xArgXmm2M64),
-	/*4169*/ uint16(x86_xMatch),
-	/*4170*/ uint16(x86_xSetOp), uint16(x86_MULSS),
-	/*4172*/ uint16(x86_xReadSlashR),
-	/*4173*/ uint16(x86_xArgXmm1),
-	/*4174*/ uint16(x86_xArgXmm2M32),
-	/*4175*/ uint16(x86_xMatch),
-	/*4176*/ uint16(x86_xCondPrefix), 4,
-	0xF3, 4204,
-	0xF2, 4198,
-	0x66, 4192,
-	0x0, 4186,
-	/*4186*/ uint16(x86_xSetOp), uint16(x86_CVTPS2PD),
-	/*4188*/ uint16(x86_xReadSlashR),
-	/*4189*/ uint16(x86_xArgXmm1),
-	/*4190*/ uint16(x86_xArgXmm2M64),
-	/*4191*/ uint16(x86_xMatch),
-	/*4192*/ uint16(x86_xSetOp), uint16(x86_CVTPD2PS),
-	/*4194*/ uint16(x86_xReadSlashR),
-	/*4195*/ uint16(x86_xArgXmm1),
-	/*4196*/ uint16(x86_xArgXmm2M128),
-	/*4197*/ uint16(x86_xMatch),
-	/*4198*/ uint16(x86_xSetOp), uint16(x86_CVTSD2SS),
-	/*4200*/ uint16(x86_xReadSlashR),
-	/*4201*/ uint16(x86_xArgXmm1),
-	/*4202*/ uint16(x86_xArgXmm2M64),
-	/*4203*/ uint16(x86_xMatch),
-	/*4204*/ uint16(x86_xSetOp), uint16(x86_CVTSS2SD),
-	/*4206*/ uint16(x86_xReadSlashR),
-	/*4207*/ uint16(x86_xArgXmm1),
-	/*4208*/ uint16(x86_xArgXmm2M32),
-	/*4209*/ uint16(x86_xMatch),
-	/*4210*/ uint16(x86_xCondPrefix), 3,
-	0xF3, 4230,
-	0x66, 4224,
-	0x0, 4218,
-	/*4218*/ uint16(x86_xSetOp), uint16(x86_CVTDQ2PS),
-	/*4220*/ uint16(x86_xReadSlashR),
-	/*4221*/ uint16(x86_xArgXmm1),
-	/*4222*/ uint16(x86_xArgXmm2M128),
-	/*4223*/ uint16(x86_xMatch),
-	/*4224*/ uint16(x86_xSetOp), uint16(x86_CVTPS2DQ),
-	/*4226*/ uint16(x86_xReadSlashR),
-	/*4227*/ uint16(x86_xArgXmm1),
-	/*4228*/ uint16(x86_xArgXmm2M128),
-	/*4229*/ uint16(x86_xMatch),
-	/*4230*/ uint16(x86_xSetOp), uint16(x86_CVTTPS2DQ),
-	/*4232*/ uint16(x86_xReadSlashR),
-	/*4233*/ uint16(x86_xArgXmm1),
-	/*4234*/ uint16(x86_xArgXmm2M128),
-	/*4235*/ uint16(x86_xMatch),
-	/*4236*/ uint16(x86_xCondPrefix), 4,
-	0xF3, 4264,
-	0xF2, 4258,
-	0x66, 4252,
-	0x0, 4246,
-	/*4246*/ uint16(x86_xSetOp), uint16(x86_SUBPS),
-	/*4248*/ uint16(x86_xReadSlashR),
-	/*4249*/ uint16(x86_xArgXmm1),
-	/*4250*/ uint16(x86_xArgXmm2M128),
-	/*4251*/ uint16(x86_xMatch),
-	/*4252*/ uint16(x86_xSetOp), uint16(x86_SUBPD),
-	/*4254*/ uint16(x86_xReadSlashR),
-	/*4255*/ uint16(x86_xArgXmm1),
-	/*4256*/ uint16(x86_xArgXmm2M128),
-	/*4257*/ uint16(x86_xMatch),
-	/*4258*/ uint16(x86_xSetOp), uint16(x86_SUBSD),
-	/*4260*/ uint16(x86_xReadSlashR),
-	/*4261*/ uint16(x86_xArgXmm1),
-	/*4262*/ uint16(x86_xArgXmm2M64),
-	/*4263*/ uint16(x86_xMatch),
-	/*4264*/ uint16(x86_xSetOp), uint16(x86_SUBSS),
-	/*4266*/ uint16(x86_xReadSlashR),
-	/*4267*/ uint16(x86_xArgXmm1),
-	/*4268*/ uint16(x86_xArgXmm2M32),
-	/*4269*/ uint16(x86_xMatch),
-	/*4270*/ uint16(x86_xCondPrefix), 4,
-	0xF3, 4298,
-	0xF2, 4292,
-	0x66, 4286,
-	0x0, 4280,
-	/*4280*/ uint16(x86_xSetOp), uint16(x86_MINPS),
-	/*4282*/ uint16(x86_xReadSlashR),
-	/*4283*/ uint16(x86_xArgXmm1),
-	/*4284*/ uint16(x86_xArgXmm2M128),
-	/*4285*/ uint16(x86_xMatch),
-	/*4286*/ uint16(x86_xSetOp), uint16(x86_MINPD),
-	/*4288*/ uint16(x86_xReadSlashR),
-	/*4289*/ uint16(x86_xArgXmm1),
-	/*4290*/ uint16(x86_xArgXmm2M128),
-	/*4291*/ uint16(x86_xMatch),
-	/*4292*/ uint16(x86_xSetOp), uint16(x86_MINSD),
-	/*4294*/ uint16(x86_xReadSlashR),
-	/*4295*/ uint16(x86_xArgXmm1),
-	/*4296*/ uint16(x86_xArgXmm2M64),
-	/*4297*/ uint16(x86_xMatch),
-	/*4298*/ uint16(x86_xSetOp), uint16(x86_MINSS),
-	/*4300*/ uint16(x86_xReadSlashR),
-	/*4301*/ uint16(x86_xArgXmm1),
-	/*4302*/ uint16(x86_xArgXmm2M32),
-	/*4303*/ uint16(x86_xMatch),
-	/*4304*/ uint16(x86_xCondPrefix), 4,
-	0xF3, 4332,
-	0xF2, 4326,
-	0x66, 4320,
-	0x0, 4314,
-	/*4314*/ uint16(x86_xSetOp), uint16(x86_DIVPS),
-	/*4316*/ uint16(x86_xReadSlashR),
-	/*4317*/ uint16(x86_xArgXmm1),
-	/*4318*/ uint16(x86_xArgXmm2M128),
-	/*4319*/ uint16(x86_xMatch),
-	/*4320*/ uint16(x86_xSetOp), uint16(x86_DIVPD),
-	/*4322*/ uint16(x86_xReadSlashR),
-	/*4323*/ uint16(x86_xArgXmm1),
-	/*4324*/ uint16(x86_xArgXmm2M128),
-	/*4325*/ uint16(x86_xMatch),
-	/*4326*/ uint16(x86_xSetOp), uint16(x86_DIVSD),
-	/*4328*/ uint16(x86_xReadSlashR),
-	/*4329*/ uint16(x86_xArgXmm1),
-	/*4330*/ uint16(x86_xArgXmm2M64),
-	/*4331*/ uint16(x86_xMatch),
-	/*4332*/ uint16(x86_xSetOp), uint16(x86_DIVSS),
-	/*4334*/ uint16(x86_xReadSlashR),
-	/*4335*/ uint16(x86_xArgXmm1),
-	/*4336*/ uint16(x86_xArgXmm2M32),
-	/*4337*/ uint16(x86_xMatch),
-	/*4338*/ uint16(x86_xCondPrefix), 4,
-	0xF3, 4366,
-	0xF2, 4360,
-	0x66, 4354,
-	0x0, 4348,
-	/*4348*/ uint16(x86_xSetOp), uint16(x86_MAXPS),
-	/*4350*/ uint16(x86_xReadSlashR),
-	/*4351*/ uint16(x86_xArgXmm1),
-	/*4352*/ uint16(x86_xArgXmm2M128),
-	/*4353*/ uint16(x86_xMatch),
-	/*4354*/ uint16(x86_xSetOp), uint16(x86_MAXPD),
-	/*4356*/ uint16(x86_xReadSlashR),
-	/*4357*/ uint16(x86_xArgXmm1),
-	/*4358*/ uint16(x86_xArgXmm2M128),
-	/*4359*/ uint16(x86_xMatch),
-	/*4360*/ uint16(x86_xSetOp), uint16(x86_MAXSD),
-	/*4362*/ uint16(x86_xReadSlashR),
-	/*4363*/ uint16(x86_xArgXmm1),
-	/*4364*/ uint16(x86_xArgXmm2M64),
-	/*4365*/ uint16(x86_xMatch),
-	/*4366*/ uint16(x86_xSetOp), uint16(x86_MAXSS),
-	/*4368*/ uint16(x86_xReadSlashR),
-	/*4369*/ uint16(x86_xArgXmm1),
-	/*4370*/ uint16(x86_xArgXmm2M32),
-	/*4371*/ uint16(x86_xMatch),
-	/*4372*/ uint16(x86_xCondPrefix), 2,
-	0x66, 4384,
-	0x0, 4378,
-	/*4378*/ uint16(x86_xSetOp), uint16(x86_PUNPCKLBW),
-	/*4380*/ uint16(x86_xReadSlashR),
-	/*4381*/ uint16(x86_xArgMm),
-	/*4382*/ uint16(x86_xArgMmM32),
-	/*4383*/ uint16(x86_xMatch),
-	/*4384*/ uint16(x86_xSetOp), uint16(x86_PUNPCKLBW),
-	/*4386*/ uint16(x86_xReadSlashR),
-	/*4387*/ uint16(x86_xArgXmm1),
-	/*4388*/ uint16(x86_xArgXmm2M128),
-	/*4389*/ uint16(x86_xMatch),
-	/*4390*/ uint16(x86_xCondPrefix), 2,
-	0x66, 4402,
-	0x0, 4396,
-	/*4396*/ uint16(x86_xSetOp), uint16(x86_PUNPCKLWD),
-	/*4398*/ uint16(x86_xReadSlashR),
-	/*4399*/ uint16(x86_xArgMm),
-	/*4400*/ uint16(x86_xArgMmM32),
-	/*4401*/ uint16(x86_xMatch),
-	/*4402*/ uint16(x86_xSetOp), uint16(x86_PUNPCKLWD),
-	/*4404*/ uint16(x86_xReadSlashR),
-	/*4405*/ uint16(x86_xArgXmm1),
-	/*4406*/ uint16(x86_xArgXmm2M128),
-	/*4407*/ uint16(x86_xMatch),
-	/*4408*/ uint16(x86_xCondPrefix), 2,
-	0x66, 4420,
-	0x0, 4414,
-	/*4414*/ uint16(x86_xSetOp), uint16(x86_PUNPCKLDQ),
-	/*4416*/ uint16(x86_xReadSlashR),
-	/*4417*/ uint16(x86_xArgMm),
-	/*4418*/ uint16(x86_xArgMmM32),
-	/*4419*/ uint16(x86_xMatch),
-	/*4420*/ uint16(x86_xSetOp), uint16(x86_PUNPCKLDQ),
-	/*4422*/ uint16(x86_xReadSlashR),
-	/*4423*/ uint16(x86_xArgXmm1),
-	/*4424*/ uint16(x86_xArgXmm2M128),
-	/*4425*/ uint16(x86_xMatch),
-	/*4426*/ uint16(x86_xCondPrefix), 2,
-	0x66, 4438,
-	0x0, 4432,
-	/*4432*/ uint16(x86_xSetOp), uint16(x86_PACKSSWB),
-	/*4434*/ uint16(x86_xReadSlashR),
-	/*4435*/ uint16(x86_xArgMm1),
-	/*4436*/ uint16(x86_xArgMm2M64),
-	/*4437*/ uint16(x86_xMatch),
-	/*4438*/ uint16(x86_xSetOp), uint16(x86_PACKSSWB),
-	/*4440*/ uint16(x86_xReadSlashR),
-	/*4441*/ uint16(x86_xArgXmm1),
-	/*4442*/ uint16(x86_xArgXmm2M128),
-	/*4443*/ uint16(x86_xMatch),
-	/*4444*/ uint16(x86_xCondPrefix), 2,
-	0x66, 4456,
-	0x0, 4450,
-	/*4450*/ uint16(x86_xSetOp), uint16(x86_PCMPGTB),
-	/*4452*/ uint16(x86_xReadSlashR),
-	/*4453*/ uint16(x86_xArgMm),
-	/*4454*/ uint16(x86_xArgMmM64),
-	/*4455*/ uint16(x86_xMatch),
-	/*4456*/ uint16(x86_xSetOp), uint16(x86_PCMPGTB),
-	/*4458*/ uint16(x86_xReadSlashR),
-	/*4459*/ uint16(x86_xArgXmm1),
-	/*4460*/ uint16(x86_xArgXmm2M128),
-	/*4461*/ uint16(x86_xMatch),
-	/*4462*/ uint16(x86_xCondPrefix), 2,
-	0x66, 4474,
-	0x0, 4468,
-	/*4468*/ uint16(x86_xSetOp), uint16(x86_PCMPGTW),
-	/*4470*/ uint16(x86_xReadSlashR),
-	/*4471*/ uint16(x86_xArgMm),
-	/*4472*/ uint16(x86_xArgMmM64),
-	/*4473*/ uint16(x86_xMatch),
-	/*4474*/ uint16(x86_xSetOp), uint16(x86_PCMPGTW),
-	/*4476*/ uint16(x86_xReadSlashR),
-	/*4477*/ uint16(x86_xArgXmm1),
-	/*4478*/ uint16(x86_xArgXmm2M128),
-	/*4479*/ uint16(x86_xMatch),
-	/*4480*/ uint16(x86_xCondPrefix), 2,
-	0x66, 4492,
-	0x0, 4486,
-	/*4486*/ uint16(x86_xSetOp), uint16(x86_PCMPGTD),
-	/*4488*/ uint16(x86_xReadSlashR),
-	/*4489*/ uint16(x86_xArgMm),
-	/*4490*/ uint16(x86_xArgMmM64),
-	/*4491*/ uint16(x86_xMatch),
-	/*4492*/ uint16(x86_xSetOp), uint16(x86_PCMPGTD),
-	/*4494*/ uint16(x86_xReadSlashR),
-	/*4495*/ uint16(x86_xArgXmm1),
-	/*4496*/ uint16(x86_xArgXmm2M128),
-	/*4497*/ uint16(x86_xMatch),
-	/*4498*/ uint16(x86_xCondPrefix), 2,
-	0x66, 4510,
-	0x0, 4504,
-	/*4504*/ uint16(x86_xSetOp), uint16(x86_PACKUSWB),
-	/*4506*/ uint16(x86_xReadSlashR),
-	/*4507*/ uint16(x86_xArgMm),
-	/*4508*/ uint16(x86_xArgMmM64),
-	/*4509*/ uint16(x86_xMatch),
-	/*4510*/ uint16(x86_xSetOp), uint16(x86_PACKUSWB),
-	/*4512*/ uint16(x86_xReadSlashR),
-	/*4513*/ uint16(x86_xArgXmm1),
-	/*4514*/ uint16(x86_xArgXmm2M128),
-	/*4515*/ uint16(x86_xMatch),
-	/*4516*/ uint16(x86_xCondPrefix), 2,
-	0x66, 4528,
-	0x0, 4522,
-	/*4522*/ uint16(x86_xSetOp), uint16(x86_PUNPCKHBW),
-	/*4524*/ uint16(x86_xReadSlashR),
-	/*4525*/ uint16(x86_xArgMm),
-	/*4526*/ uint16(x86_xArgMmM64),
-	/*4527*/ uint16(x86_xMatch),
-	/*4528*/ uint16(x86_xSetOp), uint16(x86_PUNPCKHBW),
-	/*4530*/ uint16(x86_xReadSlashR),
-	/*4531*/ uint16(x86_xArgXmm1),
-	/*4532*/ uint16(x86_xArgXmm2M128),
-	/*4533*/ uint16(x86_xMatch),
-	/*4534*/ uint16(x86_xCondPrefix), 2,
-	0x66, 4546,
-	0x0, 4540,
-	/*4540*/ uint16(x86_xSetOp), uint16(x86_PUNPCKHWD),
-	/*4542*/ uint16(x86_xReadSlashR),
-	/*4543*/ uint16(x86_xArgMm),
-	/*4544*/ uint16(x86_xArgMmM64),
-	/*4545*/ uint16(x86_xMatch),
-	/*4546*/ uint16(x86_xSetOp), uint16(x86_PUNPCKHWD),
-	/*4548*/ uint16(x86_xReadSlashR),
-	/*4549*/ uint16(x86_xArgXmm1),
-	/*4550*/ uint16(x86_xArgXmm2M128),
-	/*4551*/ uint16(x86_xMatch),
-	/*4552*/ uint16(x86_xCondPrefix), 2,
-	0x66, 4564,
-	0x0, 4558,
-	/*4558*/ uint16(x86_xSetOp), uint16(x86_PUNPCKHDQ),
-	/*4560*/ uint16(x86_xReadSlashR),
-	/*4561*/ uint16(x86_xArgMm),
-	/*4562*/ uint16(x86_xArgMmM64),
-	/*4563*/ uint16(x86_xMatch),
-	/*4564*/ uint16(x86_xSetOp), uint16(x86_PUNPCKHDQ),
-	/*4566*/ uint16(x86_xReadSlashR),
-	/*4567*/ uint16(x86_xArgXmm1),
-	/*4568*/ uint16(x86_xArgXmm2M128),
-	/*4569*/ uint16(x86_xMatch),
-	/*4570*/ uint16(x86_xCondPrefix), 2,
-	0x66, 4582,
-	0x0, 4576,
-	/*4576*/ uint16(x86_xSetOp), uint16(x86_PACKSSDW),
-	/*4578*/ uint16(x86_xReadSlashR),
-	/*4579*/ uint16(x86_xArgMm1),
-	/*4580*/ uint16(x86_xArgMm2M64),
-	/*4581*/ uint16(x86_xMatch),
-	/*4582*/ uint16(x86_xSetOp), uint16(x86_PACKSSDW),
-	/*4584*/ uint16(x86_xReadSlashR),
-	/*4585*/ uint16(x86_xArgXmm1),
-	/*4586*/ uint16(x86_xArgXmm2M128),
-	/*4587*/ uint16(x86_xMatch),
-	/*4588*/ uint16(x86_xCondPrefix), 1,
-	0x66, 4592,
-	/*4592*/ uint16(x86_xSetOp), uint16(x86_PUNPCKLQDQ),
-	/*4594*/ uint16(x86_xReadSlashR),
-	/*4595*/ uint16(x86_xArgXmm1),
-	/*4596*/ uint16(x86_xArgXmm2M128),
-	/*4597*/ uint16(x86_xMatch),
-	/*4598*/ uint16(x86_xCondPrefix), 1,
-	0x66, 4602,
-	/*4602*/ uint16(x86_xSetOp), uint16(x86_PUNPCKHQDQ),
-	/*4604*/ uint16(x86_xReadSlashR),
-	/*4605*/ uint16(x86_xArgXmm1),
-	/*4606*/ uint16(x86_xArgXmm2M128),
-	/*4607*/ uint16(x86_xMatch),
-	/*4608*/ uint16(x86_xCondIs64), 4611, 4649,
-	/*4611*/ uint16(x86_xCondPrefix), 2,
-	0x66, 4633,
-	0x0, 4617,
-	/*4617*/ uint16(x86_xCondDataSize), 4621, 4627, 0,
-	/*4621*/ uint16(x86_xSetOp), uint16(x86_MOVD),
-	/*4623*/ uint16(x86_xReadSlashR),
-	/*4624*/ uint16(x86_xArgMm),
-	/*4625*/ uint16(x86_xArgRM32),
-	/*4626*/ uint16(x86_xMatch),
-	/*4627*/ uint16(x86_xSetOp), uint16(x86_MOVD),
-	/*4629*/ uint16(x86_xReadSlashR),
-	/*4630*/ uint16(x86_xArgMm),
-	/*4631*/ uint16(x86_xArgRM32),
-	/*4632*/ uint16(x86_xMatch),
-	/*4633*/ uint16(x86_xCondDataSize), 4637, 4643, 0,
-	/*4637*/ uint16(x86_xSetOp), uint16(x86_MOVD),
-	/*4639*/ uint16(x86_xReadSlashR),
-	/*4640*/ uint16(x86_xArgXmm),
-	/*4641*/ uint16(x86_xArgRM32),
-	/*4642*/ uint16(x86_xMatch),
-	/*4643*/ uint16(x86_xSetOp), uint16(x86_MOVD),
-	/*4645*/ uint16(x86_xReadSlashR),
-	/*4646*/ uint16(x86_xArgXmm),
-	/*4647*/ uint16(x86_xArgRM32),
-	/*4648*/ uint16(x86_xMatch),
-	/*4649*/ uint16(x86_xCondPrefix), 2,
-	0x66, 4665,
-	0x0, 4655,
-	/*4655*/ uint16(x86_xCondDataSize), 4621, 4627, 4659,
-	/*4659*/ uint16(x86_xSetOp), uint16(x86_MOVQ),
-	/*4661*/ uint16(x86_xReadSlashR),
-	/*4662*/ uint16(x86_xArgMm),
-	/*4663*/ uint16(x86_xArgRM64),
-	/*4664*/ uint16(x86_xMatch),
-	/*4665*/ uint16(x86_xCondDataSize), 4637, 4643, 4669,
-	/*4669*/ uint16(x86_xSetOp), uint16(x86_MOVQ),
-	/*4671*/ uint16(x86_xReadSlashR),
-	/*4672*/ uint16(x86_xArgXmm),
-	/*4673*/ uint16(x86_xArgRM64),
-	/*4674*/ uint16(x86_xMatch),
-	/*4675*/ uint16(x86_xCondPrefix), 3,
-	0xF3, 4695,
-	0x66, 4689,
-	0x0, 4683,
-	/*4683*/ uint16(x86_xSetOp), uint16(x86_MOVQ),
-	/*4685*/ uint16(x86_xReadSlashR),
-	/*4686*/ uint16(x86_xArgMm),
-	/*4687*/ uint16(x86_xArgMmM64),
-	/*4688*/ uint16(x86_xMatch),
-	/*4689*/ uint16(x86_xSetOp), uint16(x86_MOVDQA),
-	/*4691*/ uint16(x86_xReadSlashR),
-	/*4692*/ uint16(x86_xArgXmm1),
-	/*4693*/ uint16(x86_xArgXmm2M128),
-	/*4694*/ uint16(x86_xMatch),
-	/*4695*/ uint16(x86_xSetOp), uint16(x86_MOVDQU),
-	/*4697*/ uint16(x86_xReadSlashR),
-	/*4698*/ uint16(x86_xArgXmm1),
-	/*4699*/ uint16(x86_xArgXmm2M128),
-	/*4700*/ uint16(x86_xMatch),
-	/*4701*/ uint16(x86_xCondPrefix), 4,
-	0xF3, 4735,
-	0xF2, 4727,
-	0x66, 4719,
-	0x0, 4711,
-	/*4711*/ uint16(x86_xSetOp), uint16(x86_PSHUFW),
-	/*4713*/ uint16(x86_xReadSlashR),
-	/*4714*/ uint16(x86_xReadIb),
-	/*4715*/ uint16(x86_xArgMm1),
-	/*4716*/ uint16(x86_xArgMm2M64),
-	/*4717*/ uint16(x86_xArgImm8u),
-	/*4718*/ uint16(x86_xMatch),
-	/*4719*/ uint16(x86_xSetOp), uint16(x86_PSHUFD),
-	/*4721*/ uint16(x86_xReadSlashR),
-	/*4722*/ uint16(x86_xReadIb),
-	/*4723*/ uint16(x86_xArgXmm1),
-	/*4724*/ uint16(x86_xArgXmm2M128),
-	/*4725*/ uint16(x86_xArgImm8u),
-	/*4726*/ uint16(x86_xMatch),
-	/*4727*/ uint16(x86_xSetOp), uint16(x86_PSHUFLW),
-	/*4729*/ uint16(x86_xReadSlashR),
-	/*4730*/ uint16(x86_xReadIb),
-	/*4731*/ uint16(x86_xArgXmm1),
-	/*4732*/ uint16(x86_xArgXmm2M128),
-	/*4733*/ uint16(x86_xArgImm8u),
-	/*4734*/ uint16(x86_xMatch),
-	/*4735*/ uint16(x86_xSetOp), uint16(x86_PSHUFHW),
-	/*4737*/ uint16(x86_xReadSlashR),
-	/*4738*/ uint16(x86_xReadIb),
-	/*4739*/ uint16(x86_xArgXmm1),
-	/*4740*/ uint16(x86_xArgXmm2M128),
-	/*4741*/ uint16(x86_xArgImm8u),
-	/*4742*/ uint16(x86_xMatch),
-	/*4743*/ uint16(x86_xCondSlashR),
-	0,    // 0
-	0,    // 1
-	4752, // 2
-	0,    // 3
-	4770, // 4
-	0,    // 5
-	4788, // 6
-	0,    // 7
-	/*4752*/ uint16(x86_xCondPrefix), 2,
-	0x66, 4764,
-	0x0, 4758,
-	/*4758*/ uint16(x86_xSetOp), uint16(x86_PSRLW),
-	/*4760*/ uint16(x86_xReadIb),
-	/*4761*/ uint16(x86_xArgMm2),
-	/*4762*/ uint16(x86_xArgImm8u),
-	/*4763*/ uint16(x86_xMatch),
-	/*4764*/ uint16(x86_xSetOp), uint16(x86_PSRLW),
-	/*4766*/ uint16(x86_xReadIb),
-	/*4767*/ uint16(x86_xArgXmm2),
-	/*4768*/ uint16(x86_xArgImm8u),
-	/*4769*/ uint16(x86_xMatch),
-	/*4770*/ uint16(x86_xCondPrefix), 2,
-	0x66, 4782,
-	0x0, 4776,
-	/*4776*/ uint16(x86_xSetOp), uint16(x86_PSRAW),
-	/*4778*/ uint16(x86_xReadIb),
-	/*4779*/ uint16(x86_xArgMm2),
-	/*4780*/ uint16(x86_xArgImm8u),
-	/*4781*/ uint16(x86_xMatch),
-	/*4782*/ uint16(x86_xSetOp), uint16(x86_PSRAW),
-	/*4784*/ uint16(x86_xReadIb),
-	/*4785*/ uint16(x86_xArgXmm2),
-	/*4786*/ uint16(x86_xArgImm8u),
-	/*4787*/ uint16(x86_xMatch),
-	/*4788*/ uint16(x86_xCondPrefix), 2,
-	0x66, 4800,
-	0x0, 4794,
-	/*4794*/ uint16(x86_xSetOp), uint16(x86_PSLLW),
-	/*4796*/ uint16(x86_xReadIb),
-	/*4797*/ uint16(x86_xArgMm2),
-	/*4798*/ uint16(x86_xArgImm8u),
-	/*4799*/ uint16(x86_xMatch),
-	/*4800*/ uint16(x86_xSetOp), uint16(x86_PSLLW),
-	/*4802*/ uint16(x86_xReadIb),
-	/*4803*/ uint16(x86_xArgXmm2),
-	/*4804*/ uint16(x86_xArgImm8u),
-	/*4805*/ uint16(x86_xMatch),
-	/*4806*/ uint16(x86_xCondSlashR),
-	0,    // 0
-	0,    // 1
-	4815, // 2
-	0,    // 3
-	4833, // 4
-	0,    // 5
-	4851, // 6
-	0,    // 7
-	/*4815*/ uint16(x86_xCondPrefix), 2,
-	0x66, 4827,
-	0x0, 4821,
-	/*4821*/ uint16(x86_xSetOp), uint16(x86_PSRLD),
-	/*4823*/ uint16(x86_xReadIb),
-	/*4824*/ uint16(x86_xArgMm2),
-	/*4825*/ uint16(x86_xArgImm8u),
-	/*4826*/ uint16(x86_xMatch),
-	/*4827*/ uint16(x86_xSetOp), uint16(x86_PSRLD),
-	/*4829*/ uint16(x86_xReadIb),
-	/*4830*/ uint16(x86_xArgXmm2),
-	/*4831*/ uint16(x86_xArgImm8u),
-	/*4832*/ uint16(x86_xMatch),
-	/*4833*/ uint16(x86_xCondPrefix), 2,
-	0x66, 4845,
-	0x0, 4839,
-	/*4839*/ uint16(x86_xSetOp), uint16(x86_PSRAD),
-	/*4841*/ uint16(x86_xReadIb),
-	/*4842*/ uint16(x86_xArgMm2),
-	/*4843*/ uint16(x86_xArgImm8u),
-	/*4844*/ uint16(x86_xMatch),
-	/*4845*/ uint16(x86_xSetOp), uint16(x86_PSRAD),
-	/*4847*/ uint16(x86_xReadIb),
-	/*4848*/ uint16(x86_xArgXmm2),
-	/*4849*/ uint16(x86_xArgImm8u),
-	/*4850*/ uint16(x86_xMatch),
-	/*4851*/ uint16(x86_xCondPrefix), 2,
-	0x66, 4863,
-	0x0, 4857,
-	/*4857*/ uint16(x86_xSetOp), uint16(x86_PSLLD),
-	/*4859*/ uint16(x86_xReadIb),
-	/*4860*/ uint16(x86_xArgMm2),
-	/*4861*/ uint16(x86_xArgImm8u),
-	/*4862*/ uint16(x86_xMatch),
-	/*4863*/ uint16(x86_xSetOp), uint16(x86_PSLLD),
-	/*4865*/ uint16(x86_xReadIb),
-	/*4866*/ uint16(x86_xArgXmm2),
-	/*4867*/ uint16(x86_xArgImm8u),
-	/*4868*/ uint16(x86_xMatch),
-	/*4869*/ uint16(x86_xCondSlashR),
-	0,    // 0
-	0,    // 1
-	4878, // 2
-	4896, // 3
-	0,    // 4
-	0,    // 5
-	4906, // 6
-	4924, // 7
-	/*4878*/ uint16(x86_xCondPrefix), 2,
-	0x66, 4890,
-	0x0, 4884,
-	/*4884*/ uint16(x86_xSetOp), uint16(x86_PSRLQ),
-	/*4886*/ uint16(x86_xReadIb),
-	/*4887*/ uint16(x86_xArgMm2),
-	/*4888*/ uint16(x86_xArgImm8u),
-	/*4889*/ uint16(x86_xMatch),
-	/*4890*/ uint16(x86_xSetOp), uint16(x86_PSRLQ),
-	/*4892*/ uint16(x86_xReadIb),
-	/*4893*/ uint16(x86_xArgXmm2),
-	/*4894*/ uint16(x86_xArgImm8u),
-	/*4895*/ uint16(x86_xMatch),
-	/*4896*/ uint16(x86_xCondPrefix), 1,
-	0x66, 4900,
-	/*4900*/ uint16(x86_xSetOp), uint16(x86_PSRLDQ),
-	/*4902*/ uint16(x86_xReadIb),
-	/*4903*/ uint16(x86_xArgXmm2),
-	/*4904*/ uint16(x86_xArgImm8u),
-	/*4905*/ uint16(x86_xMatch),
-	/*4906*/ uint16(x86_xCondPrefix), 2,
-	0x66, 4918,
-	0x0, 4912,
-	/*4912*/ uint16(x86_xSetOp), uint16(x86_PSLLQ),
-	/*4914*/ uint16(x86_xReadIb),
-	/*4915*/ uint16(x86_xArgMm2),
-	/*4916*/ uint16(x86_xArgImm8u),
-	/*4917*/ uint16(x86_xMatch),
-	/*4918*/ uint16(x86_xSetOp), uint16(x86_PSLLQ),
-	/*4920*/ uint16(x86_xReadIb),
-	/*4921*/ uint16(x86_xArgXmm2),
-	/*4922*/ uint16(x86_xArgImm8u),
-	/*4923*/ uint16(x86_xMatch),
-	/*4924*/ uint16(x86_xCondPrefix), 1,
-	0x66, 4928,
-	/*4928*/ uint16(x86_xSetOp), uint16(x86_PSLLDQ),
-	/*4930*/ uint16(x86_xReadIb),
-	/*4931*/ uint16(x86_xArgXmm2),
-	/*4932*/ uint16(x86_xArgImm8u),
-	/*4933*/ uint16(x86_xMatch),
-	/*4934*/ uint16(x86_xCondPrefix), 2,
-	0x66, 4946,
-	0x0, 4940,
-	/*4940*/ uint16(x86_xSetOp), uint16(x86_PCMPEQB),
-	/*4942*/ uint16(x86_xReadSlashR),
-	/*4943*/ uint16(x86_xArgMm),
-	/*4944*/ uint16(x86_xArgMmM64),
-	/*4945*/ uint16(x86_xMatch),
-	/*4946*/ uint16(x86_xSetOp), uint16(x86_PCMPEQB),
-	/*4948*/ uint16(x86_xReadSlashR),
-	/*4949*/ uint16(x86_xArgXmm1),
-	/*4950*/ uint16(x86_xArgXmm2M128),
-	/*4951*/ uint16(x86_xMatch),
-	/*4952*/ uint16(x86_xCondPrefix), 2,
-	0x66, 4964,
-	0x0, 4958,
-	/*4958*/ uint16(x86_xSetOp), uint16(x86_PCMPEQW),
-	/*4960*/ uint16(x86_xReadSlashR),
-	/*4961*/ uint16(x86_xArgMm),
-	/*4962*/ uint16(x86_xArgMmM64),
-	/*4963*/ uint16(x86_xMatch),
-	/*4964*/ uint16(x86_xSetOp), uint16(x86_PCMPEQW),
-	/*4966*/ uint16(x86_xReadSlashR),
-	/*4967*/ uint16(x86_xArgXmm1),
-	/*4968*/ uint16(x86_xArgXmm2M128),
-	/*4969*/ uint16(x86_xMatch),
-	/*4970*/ uint16(x86_xCondPrefix), 2,
-	0x66, 4982,
-	0x0, 4976,
-	/*4976*/ uint16(x86_xSetOp), uint16(x86_PCMPEQD),
-	/*4978*/ uint16(x86_xReadSlashR),
-	/*4979*/ uint16(x86_xArgMm),
-	/*4980*/ uint16(x86_xArgMmM64),
-	/*4981*/ uint16(x86_xMatch),
-	/*4982*/ uint16(x86_xSetOp), uint16(x86_PCMPEQD),
-	/*4984*/ uint16(x86_xReadSlashR),
-	/*4985*/ uint16(x86_xArgXmm1),
-	/*4986*/ uint16(x86_xArgXmm2M128),
-	/*4987*/ uint16(x86_xMatch),
-	/*4988*/ uint16(x86_xSetOp), uint16(x86_EMMS),
-	/*4990*/ uint16(x86_xMatch),
-	/*4991*/ uint16(x86_xCondPrefix), 2,
-	0xF2, 5003,
-	0x66, 4997,
-	/*4997*/ uint16(x86_xSetOp), uint16(x86_HADDPD),
-	/*4999*/ uint16(x86_xReadSlashR),
-	/*5000*/ uint16(x86_xArgXmm1),
-	/*5001*/ uint16(x86_xArgXmm2M128),
-	/*5002*/ uint16(x86_xMatch),
-	/*5003*/ uint16(x86_xSetOp), uint16(x86_HADDPS),
-	/*5005*/ uint16(x86_xReadSlashR),
-	/*5006*/ uint16(x86_xArgXmm1),
-	/*5007*/ uint16(x86_xArgXmm2M128),
-	/*5008*/ uint16(x86_xMatch),
-	/*5009*/ uint16(x86_xCondPrefix), 2,
-	0xF2, 5021,
-	0x66, 5015,
-	/*5015*/ uint16(x86_xSetOp), uint16(x86_HSUBPD),
-	/*5017*/ uint16(x86_xReadSlashR),
-	/*5018*/ uint16(x86_xArgXmm1),
-	/*5019*/ uint16(x86_xArgXmm2M128),
-	/*5020*/ uint16(x86_xMatch),
-	/*5021*/ uint16(x86_xSetOp), uint16(x86_HSUBPS),
-	/*5023*/ uint16(x86_xReadSlashR),
-	/*5024*/ uint16(x86_xArgXmm1),
-	/*5025*/ uint16(x86_xArgXmm2M128),
-	/*5026*/ uint16(x86_xMatch),
-	/*5027*/ uint16(x86_xCondIs64), 5030, 5076,
-	/*5030*/ uint16(x86_xCondPrefix), 3,
-	0xF3, 5070,
-	0x66, 5054,
-	0x0, 5038,
-	/*5038*/ uint16(x86_xCondDataSize), 5042, 5048, 0,
-	/*5042*/ uint16(x86_xSetOp), uint16(x86_MOVD),
-	/*5044*/ uint16(x86_xReadSlashR),
-	/*5045*/ uint16(x86_xArgRM32),
-	/*5046*/ uint16(x86_xArgMm),
-	/*5047*/ uint16(x86_xMatch),
-	/*5048*/ uint16(x86_xSetOp), uint16(x86_MOVD),
-	/*5050*/ uint16(x86_xReadSlashR),
-	/*5051*/ uint16(x86_xArgRM32),
-	/*5052*/ uint16(x86_xArgMm),
-	/*5053*/ uint16(x86_xMatch),
-	/*5054*/ uint16(x86_xCondDataSize), 5058, 5064, 0,
-	/*5058*/ uint16(x86_xSetOp), uint16(x86_MOVD),
-	/*5060*/ uint16(x86_xReadSlashR),
-	/*5061*/ uint16(x86_xArgRM32),
-	/*5062*/ uint16(x86_xArgXmm),
-	/*5063*/ uint16(x86_xMatch),
-	/*5064*/ uint16(x86_xSetOp), uint16(x86_MOVD),
-	/*5066*/ uint16(x86_xReadSlashR),
-	/*5067*/ uint16(x86_xArgRM32),
-	/*5068*/ uint16(x86_xArgXmm),
-	/*5069*/ uint16(x86_xMatch),
-	/*5070*/ uint16(x86_xSetOp), uint16(x86_MOVQ),
-	/*5072*/ uint16(x86_xReadSlashR),
-	/*5073*/ uint16(x86_xArgXmm1),
-	/*5074*/ uint16(x86_xArgXmm2M64),
-	/*5075*/ uint16(x86_xMatch),
-	/*5076*/ uint16(x86_xCondPrefix), 3,
-	0xF3, 5070,
-	0x66, 5094,
-	0x0, 5084,
-	/*5084*/ uint16(x86_xCondDataSize), 5042, 5048, 5088,
-	/*5088*/ uint16(x86_xSetOp), uint16(x86_MOVQ),
-	/*5090*/ uint16(x86_xReadSlashR),
-	/*5091*/ uint16(x86_xArgRM64),
-	/*5092*/ uint16(x86_xArgMm),
-	/*5093*/ uint16(x86_xMatch),
-	/*5094*/ uint16(x86_xCondDataSize), 5058, 5064, 5098,
-	/*5098*/ uint16(x86_xSetOp), uint16(x86_MOVQ),
-	/*5100*/ uint16(x86_xReadSlashR),
-	/*5101*/ uint16(x86_xArgRM64),
-	/*5102*/ uint16(x86_xArgXmm),
-	/*5103*/ uint16(x86_xMatch),
-	/*5104*/ uint16(x86_xCondPrefix), 3,
-	0xF3, 5124,
-	0x66, 5118,
-	0x0, 5112,
-	/*5112*/ uint16(x86_xSetOp), uint16(x86_MOVQ),
-	/*5114*/ uint16(x86_xReadSlashR),
-	/*5115*/ uint16(x86_xArgMmM64),
-	/*5116*/ uint16(x86_xArgMm),
-	/*5117*/ uint16(x86_xMatch),
-	/*5118*/ uint16(x86_xSetOp), uint16(x86_MOVDQA),
-	/*5120*/ uint16(x86_xReadSlashR),
-	/*5121*/ uint16(x86_xArgXmm2M128),
-	/*5122*/ uint16(x86_xArgXmm1),
-	/*5123*/ uint16(x86_xMatch),
-	/*5124*/ uint16(x86_xSetOp), uint16(x86_MOVDQU),
-	/*5126*/ uint16(x86_xReadSlashR),
-	/*5127*/ uint16(x86_xArgXmm2M128),
-	/*5128*/ uint16(x86_xArgXmm1),
-	/*5129*/ uint16(x86_xMatch),
-	/*5130*/ uint16(x86_xCondIs64), 5133, 5147,
-	/*5133*/ uint16(x86_xCondDataSize), 5137, 5142, 0,
-	/*5137*/ uint16(x86_xSetOp), uint16(x86_JO),
-	/*5139*/ uint16(x86_xReadCw),
-	/*5140*/ uint16(x86_xArgRel16),
-	/*5141*/ uint16(x86_xMatch),
-	/*5142*/ uint16(x86_xSetOp), uint16(x86_JO),
-	/*5144*/ uint16(x86_xReadCd),
-	/*5145*/ uint16(x86_xArgRel32),
-	/*5146*/ uint16(x86_xMatch),
-	/*5147*/ uint16(x86_xCondDataSize), 5151, 5142, 5156,
-	/*5151*/ uint16(x86_xSetOp), uint16(x86_JO),
-	/*5153*/ uint16(x86_xReadCd),
-	/*5154*/ uint16(x86_xArgRel32),
-	/*5155*/ uint16(x86_xMatch),
-	/*5156*/ uint16(x86_xSetOp), uint16(x86_JO),
-	/*5158*/ uint16(x86_xReadCd),
-	/*5159*/ uint16(x86_xArgRel32),
-	/*5160*/ uint16(x86_xMatch),
-	/*5161*/ uint16(x86_xCondIs64), 5164, 5178,
-	/*5164*/ uint16(x86_xCondDataSize), 5168, 5173, 0,
-	/*5168*/ uint16(x86_xSetOp), uint16(x86_JNO),
-	/*5170*/ uint16(x86_xReadCw),
-	/*5171*/ uint16(x86_xArgRel16),
-	/*5172*/ uint16(x86_xMatch),
-	/*5173*/ uint16(x86_xSetOp), uint16(x86_JNO),
-	/*5175*/ uint16(x86_xReadCd),
-	/*5176*/ uint16(x86_xArgRel32),
-	/*5177*/ uint16(x86_xMatch),
-	/*5178*/ uint16(x86_xCondDataSize), 5182, 5173, 5187,
-	/*5182*/ uint16(x86_xSetOp), uint16(x86_JNO),
-	/*5184*/ uint16(x86_xReadCd),
-	/*5185*/ uint16(x86_xArgRel32),
-	/*5186*/ uint16(x86_xMatch),
-	/*5187*/ uint16(x86_xSetOp), uint16(x86_JNO),
-	/*5189*/ uint16(x86_xReadCd),
-	/*5190*/ uint16(x86_xArgRel32),
-	/*5191*/ uint16(x86_xMatch),
-	/*5192*/ uint16(x86_xCondIs64), 5195, 5209,
-	/*5195*/ uint16(x86_xCondDataSize), 5199, 5204, 0,
-	/*5199*/ uint16(x86_xSetOp), uint16(x86_JB),
-	/*5201*/ uint16(x86_xReadCw),
-	/*5202*/ uint16(x86_xArgRel16),
-	/*5203*/ uint16(x86_xMatch),
-	/*5204*/ uint16(x86_xSetOp), uint16(x86_JB),
-	/*5206*/ uint16(x86_xReadCd),
-	/*5207*/ uint16(x86_xArgRel32),
-	/*5208*/ uint16(x86_xMatch),
-	/*5209*/ uint16(x86_xCondDataSize), 5213, 5204, 5218,
-	/*5213*/ uint16(x86_xSetOp), uint16(x86_JB),
-	/*5215*/ uint16(x86_xReadCd),
-	/*5216*/ uint16(x86_xArgRel32),
-	/*5217*/ uint16(x86_xMatch),
-	/*5218*/ uint16(x86_xSetOp), uint16(x86_JB),
-	/*5220*/ uint16(x86_xReadCd),
-	/*5221*/ uint16(x86_xArgRel32),
-	/*5222*/ uint16(x86_xMatch),
-	/*5223*/ uint16(x86_xCondIs64), 5226, 5240,
-	/*5226*/ uint16(x86_xCondDataSize), 5230, 5235, 0,
-	/*5230*/ uint16(x86_xSetOp), uint16(x86_JAE),
-	/*5232*/ uint16(x86_xReadCw),
-	/*5233*/ uint16(x86_xArgRel16),
-	/*5234*/ uint16(x86_xMatch),
-	/*5235*/ uint16(x86_xSetOp), uint16(x86_JAE),
-	/*5237*/ uint16(x86_xReadCd),
-	/*5238*/ uint16(x86_xArgRel32),
-	/*5239*/ uint16(x86_xMatch),
-	/*5240*/ uint16(x86_xCondDataSize), 5244, 5235, 5249,
-	/*5244*/ uint16(x86_xSetOp), uint16(x86_JAE),
-	/*5246*/ uint16(x86_xReadCd),
-	/*5247*/ uint16(x86_xArgRel32),
-	/*5248*/ uint16(x86_xMatch),
-	/*5249*/ uint16(x86_xSetOp), uint16(x86_JAE),
-	/*5251*/ uint16(x86_xReadCd),
-	/*5252*/ uint16(x86_xArgRel32),
-	/*5253*/ uint16(x86_xMatch),
-	/*5254*/ uint16(x86_xCondIs64), 5257, 5271,
-	/*5257*/ uint16(x86_xCondDataSize), 5261, 5266, 0,
-	/*5261*/ uint16(x86_xSetOp), uint16(x86_JE),
-	/*5263*/ uint16(x86_xReadCw),
-	/*5264*/ uint16(x86_xArgRel16),
-	/*5265*/ uint16(x86_xMatch),
-	/*5266*/ uint16(x86_xSetOp), uint16(x86_JE),
-	/*5268*/ uint16(x86_xReadCd),
-	/*5269*/ uint16(x86_xArgRel32),
-	/*5270*/ uint16(x86_xMatch),
-	/*5271*/ uint16(x86_xCondDataSize), 5275, 5266, 5280,
-	/*5275*/ uint16(x86_xSetOp), uint16(x86_JE),
-	/*5277*/ uint16(x86_xReadCd),
-	/*5278*/ uint16(x86_xArgRel32),
-	/*5279*/ uint16(x86_xMatch),
-	/*5280*/ uint16(x86_xSetOp), uint16(x86_JE),
-	/*5282*/ uint16(x86_xReadCd),
-	/*5283*/ uint16(x86_xArgRel32),
-	/*5284*/ uint16(x86_xMatch),
-	/*5285*/ uint16(x86_xCondIs64), 5288, 5302,
-	/*5288*/ uint16(x86_xCondDataSize), 5292, 5297, 0,
-	/*5292*/ uint16(x86_xSetOp), uint16(x86_JNE),
-	/*5294*/ uint16(x86_xReadCw),
-	/*5295*/ uint16(x86_xArgRel16),
-	/*5296*/ uint16(x86_xMatch),
-	/*5297*/ uint16(x86_xSetOp), uint16(x86_JNE),
-	/*5299*/ uint16(x86_xReadCd),
-	/*5300*/ uint16(x86_xArgRel32),
-	/*5301*/ uint16(x86_xMatch),
-	/*5302*/ uint16(x86_xCondDataSize), 5306, 5297, 5311,
-	/*5306*/ uint16(x86_xSetOp), uint16(x86_JNE),
-	/*5308*/ uint16(x86_xReadCd),
-	/*5309*/ uint16(x86_xArgRel32),
-	/*5310*/ uint16(x86_xMatch),
-	/*5311*/ uint16(x86_xSetOp), uint16(x86_JNE),
-	/*5313*/ uint16(x86_xReadCd),
-	/*5314*/ uint16(x86_xArgRel32),
-	/*5315*/ uint16(x86_xMatch),
-	/*5316*/ uint16(x86_xCondIs64), 5319, 5333,
-	/*5319*/ uint16(x86_xCondDataSize), 5323, 5328, 0,
-	/*5323*/ uint16(x86_xSetOp), uint16(x86_JBE),
-	/*5325*/ uint16(x86_xReadCw),
-	/*5326*/ uint16(x86_xArgRel16),
-	/*5327*/ uint16(x86_xMatch),
-	/*5328*/ uint16(x86_xSetOp), uint16(x86_JBE),
-	/*5330*/ uint16(x86_xReadCd),
-	/*5331*/ uint16(x86_xArgRel32),
-	/*5332*/ uint16(x86_xMatch),
-	/*5333*/ uint16(x86_xCondDataSize), 5337, 5328, 5342,
-	/*5337*/ uint16(x86_xSetOp), uint16(x86_JBE),
-	/*5339*/ uint16(x86_xReadCd),
-	/*5340*/ uint16(x86_xArgRel32),
-	/*5341*/ uint16(x86_xMatch),
-	/*5342*/ uint16(x86_xSetOp), uint16(x86_JBE),
-	/*5344*/ uint16(x86_xReadCd),
-	/*5345*/ uint16(x86_xArgRel32),
-	/*5346*/ uint16(x86_xMatch),
-	/*5347*/ uint16(x86_xCondIs64), 5350, 5364,
-	/*5350*/ uint16(x86_xCondDataSize), 5354, 5359, 0,
-	/*5354*/ uint16(x86_xSetOp), uint16(x86_JA),
-	/*5356*/ uint16(x86_xReadCw),
-	/*5357*/ uint16(x86_xArgRel16),
-	/*5358*/ uint16(x86_xMatch),
-	/*5359*/ uint16(x86_xSetOp), uint16(x86_JA),
-	/*5361*/ uint16(x86_xReadCd),
-	/*5362*/ uint16(x86_xArgRel32),
-	/*5363*/ uint16(x86_xMatch),
-	/*5364*/ uint16(x86_xCondDataSize), 5368, 5359, 5373,
-	/*5368*/ uint16(x86_xSetOp), uint16(x86_JA),
-	/*5370*/ uint16(x86_xReadCd),
-	/*5371*/ uint16(x86_xArgRel32),
-	/*5372*/ uint16(x86_xMatch),
-	/*5373*/ uint16(x86_xSetOp), uint16(x86_JA),
-	/*5375*/ uint16(x86_xReadCd),
-	/*5376*/ uint16(x86_xArgRel32),
-	/*5377*/ uint16(x86_xMatch),
-	/*5378*/ uint16(x86_xCondIs64), 5381, 5395,
-	/*5381*/ uint16(x86_xCondDataSize), 5385, 5390, 0,
-	/*5385*/ uint16(x86_xSetOp), uint16(x86_JS),
-	/*5387*/ uint16(x86_xReadCw),
-	/*5388*/ uint16(x86_xArgRel16),
-	/*5389*/ uint16(x86_xMatch),
-	/*5390*/ uint16(x86_xSetOp), uint16(x86_JS),
-	/*5392*/ uint16(x86_xReadCd),
-	/*5393*/ uint16(x86_xArgRel32),
-	/*5394*/ uint16(x86_xMatch),
-	/*5395*/ uint16(x86_xCondDataSize), 5399, 5390, 5404,
-	/*5399*/ uint16(x86_xSetOp), uint16(x86_JS),
-	/*5401*/ uint16(x86_xReadCd),
-	/*5402*/ uint16(x86_xArgRel32),
-	/*5403*/ uint16(x86_xMatch),
-	/*5404*/ uint16(x86_xSetOp), uint16(x86_JS),
-	/*5406*/ uint16(x86_xReadCd),
-	/*5407*/ uint16(x86_xArgRel32),
-	/*5408*/ uint16(x86_xMatch),
-	/*5409*/ uint16(x86_xCondIs64), 5412, 5426,
-	/*5412*/ uint16(x86_xCondDataSize), 5416, 5421, 0,
-	/*5416*/ uint16(x86_xSetOp), uint16(x86_JNS),
-	/*5418*/ uint16(x86_xReadCw),
-	/*5419*/ uint16(x86_xArgRel16),
-	/*5420*/ uint16(x86_xMatch),
-	/*5421*/ uint16(x86_xSetOp), uint16(x86_JNS),
-	/*5423*/ uint16(x86_xReadCd),
-	/*5424*/ uint16(x86_xArgRel32),
-	/*5425*/ uint16(x86_xMatch),
-	/*5426*/ uint16(x86_xCondDataSize), 5430, 5421, 5435,
-	/*5430*/ uint16(x86_xSetOp), uint16(x86_JNS),
-	/*5432*/ uint16(x86_xReadCd),
-	/*5433*/ uint16(x86_xArgRel32),
-	/*5434*/ uint16(x86_xMatch),
-	/*5435*/ uint16(x86_xSetOp), uint16(x86_JNS),
-	/*5437*/ uint16(x86_xReadCd),
-	/*5438*/ uint16(x86_xArgRel32),
-	/*5439*/ uint16(x86_xMatch),
-	/*5440*/ uint16(x86_xCondIs64), 5443, 5457,
-	/*5443*/ uint16(x86_xCondDataSize), 5447, 5452, 0,
-	/*5447*/ uint16(x86_xSetOp), uint16(x86_JP),
-	/*5449*/ uint16(x86_xReadCw),
-	/*5450*/ uint16(x86_xArgRel16),
-	/*5451*/ uint16(x86_xMatch),
-	/*5452*/ uint16(x86_xSetOp), uint16(x86_JP),
-	/*5454*/ uint16(x86_xReadCd),
-	/*5455*/ uint16(x86_xArgRel32),
-	/*5456*/ uint16(x86_xMatch),
-	/*5457*/ uint16(x86_xCondDataSize), 5461, 5452, 5466,
-	/*5461*/ uint16(x86_xSetOp), uint16(x86_JP),
-	/*5463*/ uint16(x86_xReadCd),
-	/*5464*/ uint16(x86_xArgRel32),
-	/*5465*/ uint16(x86_xMatch),
-	/*5466*/ uint16(x86_xSetOp), uint16(x86_JP),
-	/*5468*/ uint16(x86_xReadCd),
-	/*5469*/ uint16(x86_xArgRel32),
-	/*5470*/ uint16(x86_xMatch),
-	/*5471*/ uint16(x86_xCondIs64), 5474, 5488,
-	/*5474*/ uint16(x86_xCondDataSize), 5478, 5483, 0,
-	/*5478*/ uint16(x86_xSetOp), uint16(x86_JNP),
-	/*5480*/ uint16(x86_xReadCw),
-	/*5481*/ uint16(x86_xArgRel16),
-	/*5482*/ uint16(x86_xMatch),
-	/*5483*/ uint16(x86_xSetOp), uint16(x86_JNP),
-	/*5485*/ uint16(x86_xReadCd),
-	/*5486*/ uint16(x86_xArgRel32),
-	/*5487*/ uint16(x86_xMatch),
-	/*5488*/ uint16(x86_xCondDataSize), 5492, 5483, 5497,
-	/*5492*/ uint16(x86_xSetOp), uint16(x86_JNP),
-	/*5494*/ uint16(x86_xReadCd),
-	/*5495*/ uint16(x86_xArgRel32),
-	/*5496*/ uint16(x86_xMatch),
-	/*5497*/ uint16(x86_xSetOp), uint16(x86_JNP),
-	/*5499*/ uint16(x86_xReadCd),
-	/*5500*/ uint16(x86_xArgRel32),
-	/*5501*/ uint16(x86_xMatch),
-	/*5502*/ uint16(x86_xCondIs64), 5505, 5519,
-	/*5505*/ uint16(x86_xCondDataSize), 5509, 5514, 0,
-	/*5509*/ uint16(x86_xSetOp), uint16(x86_JL),
-	/*5511*/ uint16(x86_xReadCw),
-	/*5512*/ uint16(x86_xArgRel16),
-	/*5513*/ uint16(x86_xMatch),
-	/*5514*/ uint16(x86_xSetOp), uint16(x86_JL),
-	/*5516*/ uint16(x86_xReadCd),
-	/*5517*/ uint16(x86_xArgRel32),
-	/*5518*/ uint16(x86_xMatch),
-	/*5519*/ uint16(x86_xCondDataSize), 5523, 5514, 5528,
-	/*5523*/ uint16(x86_xSetOp), uint16(x86_JL),
-	/*5525*/ uint16(x86_xReadCd),
-	/*5526*/ uint16(x86_xArgRel32),
-	/*5527*/ uint16(x86_xMatch),
-	/*5528*/ uint16(x86_xSetOp), uint16(x86_JL),
-	/*5530*/ uint16(x86_xReadCd),
-	/*5531*/ uint16(x86_xArgRel32),
-	/*5532*/ uint16(x86_xMatch),
-	/*5533*/ uint16(x86_xCondIs64), 5536, 5550,
-	/*5536*/ uint16(x86_xCondDataSize), 5540, 5545, 0,
-	/*5540*/ uint16(x86_xSetOp), uint16(x86_JGE),
-	/*5542*/ uint16(x86_xReadCw),
-	/*5543*/ uint16(x86_xArgRel16),
-	/*5544*/ uint16(x86_xMatch),
-	/*5545*/ uint16(x86_xSetOp), uint16(x86_JGE),
-	/*5547*/ uint16(x86_xReadCd),
-	/*5548*/ uint16(x86_xArgRel32),
-	/*5549*/ uint16(x86_xMatch),
-	/*5550*/ uint16(x86_xCondDataSize), 5554, 5545, 5559,
-	/*5554*/ uint16(x86_xSetOp), uint16(x86_JGE),
-	/*5556*/ uint16(x86_xReadCd),
-	/*5557*/ uint16(x86_xArgRel32),
-	/*5558*/ uint16(x86_xMatch),
-	/*5559*/ uint16(x86_xSetOp), uint16(x86_JGE),
-	/*5561*/ uint16(x86_xReadCd),
-	/*5562*/ uint16(x86_xArgRel32),
-	/*5563*/ uint16(x86_xMatch),
-	/*5564*/ uint16(x86_xCondIs64), 5567, 5581,
-	/*5567*/ uint16(x86_xCondDataSize), 5571, 5576, 0,
-	/*5571*/ uint16(x86_xSetOp), uint16(x86_JLE),
-	/*5573*/ uint16(x86_xReadCw),
-	/*5574*/ uint16(x86_xArgRel16),
-	/*5575*/ uint16(x86_xMatch),
-	/*5576*/ uint16(x86_xSetOp), uint16(x86_JLE),
-	/*5578*/ uint16(x86_xReadCd),
-	/*5579*/ uint16(x86_xArgRel32),
-	/*5580*/ uint16(x86_xMatch),
-	/*5581*/ uint16(x86_xCondDataSize), 5585, 5576, 5590,
-	/*5585*/ uint16(x86_xSetOp), uint16(x86_JLE),
-	/*5587*/ uint16(x86_xReadCd),
-	/*5588*/ uint16(x86_xArgRel32),
-	/*5589*/ uint16(x86_xMatch),
-	/*5590*/ uint16(x86_xSetOp), uint16(x86_JLE),
-	/*5592*/ uint16(x86_xReadCd),
-	/*5593*/ uint16(x86_xArgRel32),
-	/*5594*/ uint16(x86_xMatch),
-	/*5595*/ uint16(x86_xCondIs64), 5598, 5612,
-	/*5598*/ uint16(x86_xCondDataSize), 5602, 5607, 0,
-	/*5602*/ uint16(x86_xSetOp), uint16(x86_JG),
-	/*5604*/ uint16(x86_xReadCw),
-	/*5605*/ uint16(x86_xArgRel16),
-	/*5606*/ uint16(x86_xMatch),
-	/*5607*/ uint16(x86_xSetOp), uint16(x86_JG),
-	/*5609*/ uint16(x86_xReadCd),
-	/*5610*/ uint16(x86_xArgRel32),
-	/*5611*/ uint16(x86_xMatch),
-	/*5612*/ uint16(x86_xCondDataSize), 5616, 5607, 5621,
-	/*5616*/ uint16(x86_xSetOp), uint16(x86_JG),
-	/*5618*/ uint16(x86_xReadCd),
-	/*5619*/ uint16(x86_xArgRel32),
-	/*5620*/ uint16(x86_xMatch),
-	/*5621*/ uint16(x86_xSetOp), uint16(x86_JG),
-	/*5623*/ uint16(x86_xReadCd),
-	/*5624*/ uint16(x86_xArgRel32),
-	/*5625*/ uint16(x86_xMatch),
-	/*5626*/ uint16(x86_xSetOp), uint16(x86_SETO),
-	/*5628*/ uint16(x86_xReadSlashR),
-	/*5629*/ uint16(x86_xArgRM8),
-	/*5630*/ uint16(x86_xMatch),
-	/*5631*/ uint16(x86_xSetOp), uint16(x86_SETNO),
-	/*5633*/ uint16(x86_xReadSlashR),
-	/*5634*/ uint16(x86_xArgRM8),
-	/*5635*/ uint16(x86_xMatch),
-	/*5636*/ uint16(x86_xSetOp), uint16(x86_SETB),
-	/*5638*/ uint16(x86_xReadSlashR),
-	/*5639*/ uint16(x86_xArgRM8),
-	/*5640*/ uint16(x86_xMatch),
-	/*5641*/ uint16(x86_xSetOp), uint16(x86_SETAE),
-	/*5643*/ uint16(x86_xReadSlashR),
-	/*5644*/ uint16(x86_xArgRM8),
-	/*5645*/ uint16(x86_xMatch),
-	/*5646*/ uint16(x86_xSetOp), uint16(x86_SETE),
-	/*5648*/ uint16(x86_xReadSlashR),
-	/*5649*/ uint16(x86_xArgRM8),
-	/*5650*/ uint16(x86_xMatch),
-	/*5651*/ uint16(x86_xSetOp), uint16(x86_SETNE),
-	/*5653*/ uint16(x86_xReadSlashR),
-	/*5654*/ uint16(x86_xArgRM8),
-	/*5655*/ uint16(x86_xMatch),
-	/*5656*/ uint16(x86_xSetOp), uint16(x86_SETBE),
-	/*5658*/ uint16(x86_xReadSlashR),
-	/*5659*/ uint16(x86_xArgRM8),
-	/*5660*/ uint16(x86_xMatch),
-	/*5661*/ uint16(x86_xSetOp), uint16(x86_SETA),
-	/*5663*/ uint16(x86_xReadSlashR),
-	/*5664*/ uint16(x86_xArgRM8),
-	/*5665*/ uint16(x86_xMatch),
-	/*5666*/ uint16(x86_xSetOp), uint16(x86_SETS),
-	/*5668*/ uint16(x86_xReadSlashR),
-	/*5669*/ uint16(x86_xArgRM8),
-	/*5670*/ uint16(x86_xMatch),
-	/*5671*/ uint16(x86_xSetOp), uint16(x86_SETNS),
-	/*5673*/ uint16(x86_xReadSlashR),
-	/*5674*/ uint16(x86_xArgRM8),
-	/*5675*/ uint16(x86_xMatch),
-	/*5676*/ uint16(x86_xSetOp), uint16(x86_SETP),
-	/*5678*/ uint16(x86_xReadSlashR),
-	/*5679*/ uint16(x86_xArgRM8),
-	/*5680*/ uint16(x86_xMatch),
-	/*5681*/ uint16(x86_xSetOp), uint16(x86_SETNP),
-	/*5683*/ uint16(x86_xReadSlashR),
-	/*5684*/ uint16(x86_xArgRM8),
-	/*5685*/ uint16(x86_xMatch),
-	/*5686*/ uint16(x86_xSetOp), uint16(x86_SETL),
-	/*5688*/ uint16(x86_xReadSlashR),
-	/*5689*/ uint16(x86_xArgRM8),
-	/*5690*/ uint16(x86_xMatch),
-	/*5691*/ uint16(x86_xSetOp), uint16(x86_SETGE),
-	/*5693*/ uint16(x86_xReadSlashR),
-	/*5694*/ uint16(x86_xArgRM8),
-	/*5695*/ uint16(x86_xMatch),
-	/*5696*/ uint16(x86_xSetOp), uint16(x86_SETLE),
-	/*5698*/ uint16(x86_xReadSlashR),
-	/*5699*/ uint16(x86_xArgRM8),
-	/*5700*/ uint16(x86_xMatch),
-	/*5701*/ uint16(x86_xSetOp), uint16(x86_SETG),
-	/*5703*/ uint16(x86_xReadSlashR),
-	/*5704*/ uint16(x86_xArgRM8),
-	/*5705*/ uint16(x86_xMatch),
-	/*5706*/ uint16(x86_xSetOp), uint16(x86_PUSH),
-	/*5708*/ uint16(x86_xArgFS),
-	/*5709*/ uint16(x86_xMatch),
-	/*5710*/ uint16(x86_xCondIs64), 5713, 5725,
-	/*5713*/ uint16(x86_xCondDataSize), 5717, 5721, 0,
-	/*5717*/ uint16(x86_xSetOp), uint16(x86_POP),
-	/*5719*/ uint16(x86_xArgFS),
-	/*5720*/ uint16(x86_xMatch),
-	/*5721*/ uint16(x86_xSetOp), uint16(x86_POP),
-	/*5723*/ uint16(x86_xArgFS),
-	/*5724*/ uint16(x86_xMatch),
-	/*5725*/ uint16(x86_xCondDataSize), 5717, 5729, 5733,
-	/*5729*/ uint16(x86_xSetOp), uint16(x86_POP),
-	/*5731*/ uint16(x86_xArgFS),
-	/*5732*/ uint16(x86_xMatch),
-	/*5733*/ uint16(x86_xSetOp), uint16(x86_POP),
-	/*5735*/ uint16(x86_xArgFS),
-	/*5736*/ uint16(x86_xMatch),
-	/*5737*/ uint16(x86_xSetOp), uint16(x86_CPUID),
-	/*5739*/ uint16(x86_xMatch),
-	/*5740*/ uint16(x86_xCondIs64), 5743, 5759,
-	/*5743*/ uint16(x86_xCondDataSize), 5747, 5753, 0,
-	/*5747*/ uint16(x86_xSetOp), uint16(x86_BT),
-	/*5749*/ uint16(x86_xReadSlashR),
-	/*5750*/ uint16(x86_xArgRM16),
-	/*5751*/ uint16(x86_xArgR16),
-	/*5752*/ uint16(x86_xMatch),
-	/*5753*/ uint16(x86_xSetOp), uint16(x86_BT),
-	/*5755*/ uint16(x86_xReadSlashR),
-	/*5756*/ uint16(x86_xArgRM32),
-	/*5757*/ uint16(x86_xArgR32),
-	/*5758*/ uint16(x86_xMatch),
-	/*5759*/ uint16(x86_xCondDataSize), 5747, 5753, 5763,
-	/*5763*/ uint16(x86_xSetOp), uint16(x86_BT),
-	/*5765*/ uint16(x86_xReadSlashR),
-	/*5766*/ uint16(x86_xArgRM64),
-	/*5767*/ uint16(x86_xArgR64),
-	/*5768*/ uint16(x86_xMatch),
-	/*5769*/ uint16(x86_xCondIs64), 5772, 5792,
-	/*5772*/ uint16(x86_xCondDataSize), 5776, 5784, 0,
-	/*5776*/ uint16(x86_xSetOp), uint16(x86_SHLD),
-	/*5778*/ uint16(x86_xReadSlashR),
-	/*5779*/ uint16(x86_xReadIb),
-	/*5780*/ uint16(x86_xArgRM16),
-	/*5781*/ uint16(x86_xArgR16),
-	/*5782*/ uint16(x86_xArgImm8u),
-	/*5783*/ uint16(x86_xMatch),
-	/*5784*/ uint16(x86_xSetOp), uint16(x86_SHLD),
-	/*5786*/ uint16(x86_xReadSlashR),
-	/*5787*/ uint16(x86_xReadIb),
-	/*5788*/ uint16(x86_xArgRM32),
-	/*5789*/ uint16(x86_xArgR32),
-	/*5790*/ uint16(x86_xArgImm8u),
-	/*5791*/ uint16(x86_xMatch),
-	/*5792*/ uint16(x86_xCondDataSize), 5776, 5784, 5796,
-	/*5796*/ uint16(x86_xSetOp), uint16(x86_SHLD),
-	/*5798*/ uint16(x86_xReadSlashR),
-	/*5799*/ uint16(x86_xReadIb),
-	/*5800*/ uint16(x86_xArgRM64),
-	/*5801*/ uint16(x86_xArgR64),
-	/*5802*/ uint16(x86_xArgImm8u),
-	/*5803*/ uint16(x86_xMatch),
-	/*5804*/ uint16(x86_xCondIs64), 5807, 5825,
-	/*5807*/ uint16(x86_xCondDataSize), 5811, 5818, 0,
-	/*5811*/ uint16(x86_xSetOp), uint16(x86_SHLD),
-	/*5813*/ uint16(x86_xReadSlashR),
-	/*5814*/ uint16(x86_xArgRM16),
-	/*5815*/ uint16(x86_xArgR16),
-	/*5816*/ uint16(x86_xArgCL),
-	/*5817*/ uint16(x86_xMatch),
-	/*5818*/ uint16(x86_xSetOp), uint16(x86_SHLD),
-	/*5820*/ uint16(x86_xReadSlashR),
-	/*5821*/ uint16(x86_xArgRM32),
-	/*5822*/ uint16(x86_xArgR32),
-	/*5823*/ uint16(x86_xArgCL),
-	/*5824*/ uint16(x86_xMatch),
-	/*5825*/ uint16(x86_xCondDataSize), 5811, 5818, 5829,
-	/*5829*/ uint16(x86_xSetOp), uint16(x86_SHLD),
-	/*5831*/ uint16(x86_xReadSlashR),
-	/*5832*/ uint16(x86_xArgRM64),
-	/*5833*/ uint16(x86_xArgR64),
-	/*5834*/ uint16(x86_xArgCL),
-	/*5835*/ uint16(x86_xMatch),
-	/*5836*/ uint16(x86_xSetOp), uint16(x86_PUSH),
-	/*5838*/ uint16(x86_xArgGS),
-	/*5839*/ uint16(x86_xMatch),
-	/*5840*/ uint16(x86_xCondIs64), 5843, 5855,
-	/*5843*/ uint16(x86_xCondDataSize), 5847, 5851, 0,
-	/*5847*/ uint16(x86_xSetOp), uint16(x86_POP),
-	/*5849*/ uint16(x86_xArgGS),
-	/*5850*/ uint16(x86_xMatch),
-	/*5851*/ uint16(x86_xSetOp), uint16(x86_POP),
-	/*5853*/ uint16(x86_xArgGS),
-	/*5854*/ uint16(x86_xMatch),
-	/*5855*/ uint16(x86_xCondDataSize), 5847, 5859, 5863,
-	/*5859*/ uint16(x86_xSetOp), uint16(x86_POP),
-	/*5861*/ uint16(x86_xArgGS),
-	/*5862*/ uint16(x86_xMatch),
-	/*5863*/ uint16(x86_xSetOp), uint16(x86_POP),
-	/*5865*/ uint16(x86_xArgGS),
-	/*5866*/ uint16(x86_xMatch),
-	/*5867*/ uint16(x86_xSetOp), uint16(x86_RSM),
-	/*5869*/ uint16(x86_xMatch),
-	/*5870*/ uint16(x86_xCondIs64), 5873, 5889,
-	/*5873*/ uint16(x86_xCondDataSize), 5877, 5883, 0,
-	/*5877*/ uint16(x86_xSetOp), uint16(x86_BTS),
-	/*5879*/ uint16(x86_xReadSlashR),
-	/*5880*/ uint16(x86_xArgRM16),
-	/*5881*/ uint16(x86_xArgR16),
-	/*5882*/ uint16(x86_xMatch),
-	/*5883*/ uint16(x86_xSetOp), uint16(x86_BTS),
-	/*5885*/ uint16(x86_xReadSlashR),
-	/*5886*/ uint16(x86_xArgRM32),
-	/*5887*/ uint16(x86_xArgR32),
-	/*5888*/ uint16(x86_xMatch),
-	/*5889*/ uint16(x86_xCondDataSize), 5877, 5883, 5893,
-	/*5893*/ uint16(x86_xSetOp), uint16(x86_BTS),
-	/*5895*/ uint16(x86_xReadSlashR),
-	/*5896*/ uint16(x86_xArgRM64),
-	/*5897*/ uint16(x86_xArgR64),
-	/*5898*/ uint16(x86_xMatch),
-	/*5899*/ uint16(x86_xCondIs64), 5902, 5922,
-	/*5902*/ uint16(x86_xCondDataSize), 5906, 5914, 0,
-	/*5906*/ uint16(x86_xSetOp), uint16(x86_SHRD),
-	/*5908*/ uint16(x86_xReadSlashR),
-	/*5909*/ uint16(x86_xReadIb),
-	/*5910*/ uint16(x86_xArgRM16),
-	/*5911*/ uint16(x86_xArgR16),
-	/*5912*/ uint16(x86_xArgImm8u),
-	/*5913*/ uint16(x86_xMatch),
-	/*5914*/ uint16(x86_xSetOp), uint16(x86_SHRD),
-	/*5916*/ uint16(x86_xReadSlashR),
-	/*5917*/ uint16(x86_xReadIb),
-	/*5918*/ uint16(x86_xArgRM32),
-	/*5919*/ uint16(x86_xArgR32),
-	/*5920*/ uint16(x86_xArgImm8u),
-	/*5921*/ uint16(x86_xMatch),
-	/*5922*/ uint16(x86_xCondDataSize), 5906, 5914, 5926,
-	/*5926*/ uint16(x86_xSetOp), uint16(x86_SHRD),
-	/*5928*/ uint16(x86_xReadSlashR),
-	/*5929*/ uint16(x86_xReadIb),
-	/*5930*/ uint16(x86_xArgRM64),
-	/*5931*/ uint16(x86_xArgR64),
-	/*5932*/ uint16(x86_xArgImm8u),
-	/*5933*/ uint16(x86_xMatch),
-	/*5934*/ uint16(x86_xCondIs64), 5937, 5955,
-	/*5937*/ uint16(x86_xCondDataSize), 5941, 5948, 0,
-	/*5941*/ uint16(x86_xSetOp), uint16(x86_SHRD),
-	/*5943*/ uint16(x86_xReadSlashR),
-	/*5944*/ uint16(x86_xArgRM16),
-	/*5945*/ uint16(x86_xArgR16),
-	/*5946*/ uint16(x86_xArgCL),
-	/*5947*/ uint16(x86_xMatch),
-	/*5948*/ uint16(x86_xSetOp), uint16(x86_SHRD),
-	/*5950*/ uint16(x86_xReadSlashR),
-	/*5951*/ uint16(x86_xArgRM32),
-	/*5952*/ uint16(x86_xArgR32),
-	/*5953*/ uint16(x86_xArgCL),
-	/*5954*/ uint16(x86_xMatch),
-	/*5955*/ uint16(x86_xCondDataSize), 5941, 5948, 5959,
-	/*5959*/ uint16(x86_xSetOp), uint16(x86_SHRD),
-	/*5961*/ uint16(x86_xReadSlashR),
-	/*5962*/ uint16(x86_xArgRM64),
-	/*5963*/ uint16(x86_xArgR64),
-	/*5964*/ uint16(x86_xArgCL),
-	/*5965*/ uint16(x86_xMatch),
-	/*5966*/ uint16(x86_xCondByte), 3,
-	0xE8, 6215,
-	0xF0, 6218,
-	0xF8, 6221,
-	/*5974*/ uint16(x86_xCondSlashR),
-	5983, // 0
-	6037, // 1
-	6091, // 2
-	6120, // 3
-	6149, // 4
-	6172, // 5
-	6195, // 6
-	6211, // 7
-	/*5983*/ uint16(x86_xCondIs64), 5986, 5998,
-	/*5986*/ uint16(x86_xCondDataSize), 5990, 5994, 0,
-	/*5990*/ uint16(x86_xSetOp), uint16(x86_FXSAVE),
-	/*5992*/ uint16(x86_xArgM512byte),
-	/*5993*/ uint16(x86_xMatch),
-	/*5994*/ uint16(x86_xSetOp), uint16(x86_FXSAVE),
-	/*5996*/ uint16(x86_xArgM512byte),
-	/*5997*/ uint16(x86_xMatch),
-	/*5998*/ uint16(x86_xCondPrefix), 2,
-	0xF3, 6012,
-	0x0, 6004,
-	/*6004*/ uint16(x86_xCondDataSize), 5990, 5994, 6008,
-	/*6008*/ uint16(x86_xSetOp), uint16(x86_FXSAVE64),
-	/*6010*/ uint16(x86_xArgM512byte),
-	/*6011*/ uint16(x86_xMatch),
-	/*6012*/ uint16(x86_xCondDataSize), 6016, 6023, 6030,
-	/*6016*/ uint16(x86_xCondIsMem), 6019, 0,
-	/*6019*/ uint16(x86_xSetOp), uint16(x86_RDFSBASE),
-	/*6021*/ uint16(x86_xArgRM32),
-	/*6022*/ uint16(x86_xMatch),
-	/*6023*/ uint16(x86_xCondIsMem), 6026, 0,
-	/*6026*/ uint16(x86_xSetOp), uint16(x86_RDFSBASE),
-	/*6028*/ uint16(x86_xArgRM32),
-	/*6029*/ uint16(x86_xMatch),
-	/*6030*/ uint16(x86_xCondIsMem), 6033, 0,
-	/*6033*/ uint16(x86_xSetOp), uint16(x86_RDFSBASE),
-	/*6035*/ uint16(x86_xArgRM64),
-	/*6036*/ uint16(x86_xMatch),
-	/*6037*/ uint16(x86_xCondIs64), 6040, 6052,
-	/*6040*/ uint16(x86_xCondDataSize), 6044, 6048, 0,
-	/*6044*/ uint16(x86_xSetOp), uint16(x86_FXRSTOR),
-	/*6046*/ uint16(x86_xArgM512byte),
-	/*6047*/ uint16(x86_xMatch),
-	/*6048*/ uint16(x86_xSetOp), uint16(x86_FXRSTOR),
-	/*6050*/ uint16(x86_xArgM512byte),
-	/*6051*/ uint16(x86_xMatch),
-	/*6052*/ uint16(x86_xCondPrefix), 2,
-	0xF3, 6066,
-	0x0, 6058,
-	/*6058*/ uint16(x86_xCondDataSize), 6044, 6048, 6062,
-	/*6062*/ uint16(x86_xSetOp), uint16(x86_FXRSTOR64),
-	/*6064*/ uint16(x86_xArgM512byte),
-	/*6065*/ uint16(x86_xMatch),
-	/*6066*/ uint16(x86_xCondDataSize), 6070, 6077, 6084,
-	/*6070*/ uint16(x86_xCondIsMem), 6073, 0,
-	/*6073*/ uint16(x86_xSetOp), uint16(x86_RDGSBASE),
-	/*6075*/ uint16(x86_xArgRM32),
-	/*6076*/ uint16(x86_xMatch),
-	/*6077*/ uint16(x86_xCondIsMem), 6080, 0,
-	/*6080*/ uint16(x86_xSetOp), uint16(x86_RDGSBASE),
-	/*6082*/ uint16(x86_xArgRM32),
-	/*6083*/ uint16(x86_xMatch),
-	/*6084*/ uint16(x86_xCondIsMem), 6087, 0,
-	/*6087*/ uint16(x86_xSetOp), uint16(x86_RDGSBASE),
-	/*6089*/ uint16(x86_xArgRM64),
-	/*6090*/ uint16(x86_xMatch),
-	/*6091*/ uint16(x86_xCondIs64), 6094, 6098,
-	/*6094*/ uint16(x86_xSetOp), uint16(x86_LDMXCSR),
-	/*6096*/ uint16(x86_xArgM32),
-	/*6097*/ uint16(x86_xMatch),
-	/*6098*/ uint16(x86_xCondPrefix), 2,
-	0xF3, 6104,
-	0x0, 6094,
-	/*6104*/ uint16(x86_xCondDataSize), 6108, 6112, 6116,
-	/*6108*/ uint16(x86_xSetOp), uint16(x86_WRFSBASE),
-	/*6110*/ uint16(x86_xArgRM32),
-	/*6111*/ uint16(x86_xMatch),
-	/*6112*/ uint16(x86_xSetOp), uint16(x86_WRFSBASE),
-	/*6114*/ uint16(x86_xArgRM32),
-	/*6115*/ uint16(x86_xMatch),
-	/*6116*/ uint16(x86_xSetOp), uint16(x86_WRFSBASE),
-	/*6118*/ uint16(x86_xArgRM64),
-	/*6119*/ uint16(x86_xMatch),
-	/*6120*/ uint16(x86_xCondIs64), 6123, 6127,
-	/*6123*/ uint16(x86_xSetOp), uint16(x86_STMXCSR),
-	/*6125*/ uint16(x86_xArgM32),
-	/*6126*/ uint16(x86_xMatch),
-	/*6127*/ uint16(x86_xCondPrefix), 2,
-	0xF3, 6133,
-	0x0, 6123,
-	/*6133*/ uint16(x86_xCondDataSize), 6137, 6141, 6145,
-	/*6137*/ uint16(x86_xSetOp), uint16(x86_WRGSBASE),
-	/*6139*/ uint16(x86_xArgRM32),
-	/*6140*/ uint16(x86_xMatch),
-	/*6141*/ uint16(x86_xSetOp), uint16(x86_WRGSBASE),
-	/*6143*/ uint16(x86_xArgRM32),
-	/*6144*/ uint16(x86_xMatch),
-	/*6145*/ uint16(x86_xSetOp), uint16(x86_WRGSBASE),
-	/*6147*/ uint16(x86_xArgRM64),
-	/*6148*/ uint16(x86_xMatch),
-	/*6149*/ uint16(x86_xCondIs64), 6152, 6164,
-	/*6152*/ uint16(x86_xCondDataSize), 6156, 6160, 0,
-	/*6156*/ uint16(x86_xSetOp), uint16(x86_XSAVE),
-	/*6158*/ uint16(x86_xArgMem),
-	/*6159*/ uint16(x86_xMatch),
-	/*6160*/ uint16(x86_xSetOp), uint16(x86_XSAVE),
-	/*6162*/ uint16(x86_xArgMem),
-	/*6163*/ uint16(x86_xMatch),
-	/*6164*/ uint16(x86_xCondDataSize), 6156, 6160, 6168,
-	/*6168*/ uint16(x86_xSetOp), uint16(x86_XSAVE64),
-	/*6170*/ uint16(x86_xArgMem),
-	/*6171*/ uint16(x86_xMatch),
-	/*6172*/ uint16(x86_xCondIs64), 6175, 6187,
-	/*6175*/ uint16(x86_xCondDataSize), 6179, 6183, 0,
-	/*6179*/ uint16(x86_xSetOp), uint16(x86_XRSTOR),
-	/*6181*/ uint16(x86_xArgMem),
-	/*6182*/ uint16(x86_xMatch),
-	/*6183*/ uint16(x86_xSetOp), uint16(x86_XRSTOR),
-	/*6185*/ uint16(x86_xArgMem),
-	/*6186*/ uint16(x86_xMatch),
-	/*6187*/ uint16(x86_xCondDataSize), 6179, 6183, 6191,
-	/*6191*/ uint16(x86_xSetOp), uint16(x86_XRSTOR64),
-	/*6193*/ uint16(x86_xArgMem),
-	/*6194*/ uint16(x86_xMatch),
-	/*6195*/ uint16(x86_xCondDataSize), 6199, 6203, 6207,
-	/*6199*/ uint16(x86_xSetOp), uint16(x86_XSAVEOPT),
-	/*6201*/ uint16(x86_xArgMem),
-	/*6202*/ uint16(x86_xMatch),
-	/*6203*/ uint16(x86_xSetOp), uint16(x86_XSAVEOPT),
-	/*6205*/ uint16(x86_xArgMem),
-	/*6206*/ uint16(x86_xMatch),
-	/*6207*/ uint16(x86_xSetOp), uint16(x86_XSAVEOPT64),
-	/*6209*/ uint16(x86_xArgMem),
-	/*6210*/ uint16(x86_xMatch),
-	/*6211*/ uint16(x86_xSetOp), uint16(x86_CLFLUSH),
-	/*6213*/ uint16(x86_xArgM8),
-	/*6214*/ uint16(x86_xMatch),
-	/*6215*/ uint16(x86_xSetOp), uint16(x86_LFENCE),
-	/*6217*/ uint16(x86_xMatch),
-	/*6218*/ uint16(x86_xSetOp), uint16(x86_MFENCE),
-	/*6220*/ uint16(x86_xMatch),
-	/*6221*/ uint16(x86_xSetOp), uint16(x86_SFENCE),
-	/*6223*/ uint16(x86_xMatch),
-	/*6224*/ uint16(x86_xCondIs64), 6227, 6243,
-	/*6227*/ uint16(x86_xCondDataSize), 6231, 6237, 0,
-	/*6231*/ uint16(x86_xSetOp), uint16(x86_IMUL),
-	/*6233*/ uint16(x86_xReadSlashR),
-	/*6234*/ uint16(x86_xArgR16),
-	/*6235*/ uint16(x86_xArgRM16),
-	/*6236*/ uint16(x86_xMatch),
-	/*6237*/ uint16(x86_xSetOp), uint16(x86_IMUL),
-	/*6239*/ uint16(x86_xReadSlashR),
-	/*6240*/ uint16(x86_xArgR32),
-	/*6241*/ uint16(x86_xArgRM32),
-	/*6242*/ uint16(x86_xMatch),
-	/*6243*/ uint16(x86_xCondDataSize), 6231, 6237, 6247,
-	/*6247*/ uint16(x86_xSetOp), uint16(x86_IMUL),
-	/*6249*/ uint16(x86_xReadSlashR),
-	/*6250*/ uint16(x86_xArgR64),
-	/*6251*/ uint16(x86_xArgRM64),
-	/*6252*/ uint16(x86_xMatch),
-	/*6253*/ uint16(x86_xSetOp), uint16(x86_CMPXCHG),
-	/*6255*/ uint16(x86_xReadSlashR),
-	/*6256*/ uint16(x86_xArgRM8),
-	/*6257*/ uint16(x86_xArgR8),
-	/*6258*/ uint16(x86_xMatch),
-	/*6259*/ uint16(x86_xCondIs64), 6262, 6278,
-	/*6262*/ uint16(x86_xCondDataSize), 6266, 6272, 0,
-	/*6266*/ uint16(x86_xSetOp), uint16(x86_CMPXCHG),
-	/*6268*/ uint16(x86_xReadSlashR),
-	/*6269*/ uint16(x86_xArgRM16),
-	/*6270*/ uint16(x86_xArgR16),
-	/*6271*/ uint16(x86_xMatch),
-	/*6272*/ uint16(x86_xSetOp), uint16(x86_CMPXCHG),
-	/*6274*/ uint16(x86_xReadSlashR),
-	/*6275*/ uint16(x86_xArgRM32),
-	/*6276*/ uint16(x86_xArgR32),
-	/*6277*/ uint16(x86_xMatch),
-	/*6278*/ uint16(x86_xCondDataSize), 6266, 6272, 6282,
-	/*6282*/ uint16(x86_xSetOp), uint16(x86_CMPXCHG),
-	/*6284*/ uint16(x86_xReadSlashR),
-	/*6285*/ uint16(x86_xArgRM64),
-	/*6286*/ uint16(x86_xArgR64),
-	/*6287*/ uint16(x86_xMatch),
-	/*6288*/ uint16(x86_xCondIs64), 6291, 6307,
-	/*6291*/ uint16(x86_xCondDataSize), 6295, 6301, 0,
-	/*6295*/ uint16(x86_xSetOp), uint16(x86_LSS),
-	/*6297*/ uint16(x86_xReadSlashR),
-	/*6298*/ uint16(x86_xArgR16),
-	/*6299*/ uint16(x86_xArgM16colon16),
-	/*6300*/ uint16(x86_xMatch),
-	/*6301*/ uint16(x86_xSetOp), uint16(x86_LSS),
-	/*6303*/ uint16(x86_xReadSlashR),
-	/*6304*/ uint16(x86_xArgR32),
-	/*6305*/ uint16(x86_xArgM16colon32),
-	/*6306*/ uint16(x86_xMatch),
-	/*6307*/ uint16(x86_xCondDataSize), 6295, 6301, 6311,
-	/*6311*/ uint16(x86_xSetOp), uint16(x86_LSS),
-	/*6313*/ uint16(x86_xReadSlashR),
-	/*6314*/ uint16(x86_xArgR64),
-	/*6315*/ uint16(x86_xArgM16colon64),
-	/*6316*/ uint16(x86_xMatch),
-	/*6317*/ uint16(x86_xCondIs64), 6320, 6336,
-	/*6320*/ uint16(x86_xCondDataSize), 6324, 6330, 0,
-	/*6324*/ uint16(x86_xSetOp), uint16(x86_BTR),
-	/*6326*/ uint16(x86_xReadSlashR),
-	/*6327*/ uint16(x86_xArgRM16),
-	/*6328*/ uint16(x86_xArgR16),
-	/*6329*/ uint16(x86_xMatch),
-	/*6330*/ uint16(x86_xSetOp), uint16(x86_BTR),
-	/*6332*/ uint16(x86_xReadSlashR),
-	/*6333*/ uint16(x86_xArgRM32),
-	/*6334*/ uint16(x86_xArgR32),
-	/*6335*/ uint16(x86_xMatch),
-	/*6336*/ uint16(x86_xCondDataSize), 6324, 6330, 6340,
-	/*6340*/ uint16(x86_xSetOp), uint16(x86_BTR),
-	/*6342*/ uint16(x86_xReadSlashR),
-	/*6343*/ uint16(x86_xArgRM64),
-	/*6344*/ uint16(x86_xArgR64),
-	/*6345*/ uint16(x86_xMatch),
-	/*6346*/ uint16(x86_xCondIs64), 6349, 6365,
-	/*6349*/ uint16(x86_xCondDataSize), 6353, 6359, 0,
-	/*6353*/ uint16(x86_xSetOp), uint16(x86_LFS),
-	/*6355*/ uint16(x86_xReadSlashR),
-	/*6356*/ uint16(x86_xArgR16),
-	/*6357*/ uint16(x86_xArgM16colon16),
-	/*6358*/ uint16(x86_xMatch),
-	/*6359*/ uint16(x86_xSetOp), uint16(x86_LFS),
-	/*6361*/ uint16(x86_xReadSlashR),
-	/*6362*/ uint16(x86_xArgR32),
-	/*6363*/ uint16(x86_xArgM16colon32),
-	/*6364*/ uint16(x86_xMatch),
-	/*6365*/ uint16(x86_xCondDataSize), 6353, 6359, 6369,
-	/*6369*/ uint16(x86_xSetOp), uint16(x86_LFS),
-	/*6371*/ uint16(x86_xReadSlashR),
-	/*6372*/ uint16(x86_xArgR64),
-	/*6373*/ uint16(x86_xArgM16colon64),
-	/*6374*/ uint16(x86_xMatch),
-	/*6375*/ uint16(x86_xCondIs64), 6378, 6394,
-	/*6378*/ uint16(x86_xCondDataSize), 6382, 6388, 0,
-	/*6382*/ uint16(x86_xSetOp), uint16(x86_LGS),
-	/*6384*/ uint16(x86_xReadSlashR),
-	/*6385*/ uint16(x86_xArgR16),
-	/*6386*/ uint16(x86_xArgM16colon16),
-	/*6387*/ uint16(x86_xMatch),
-	/*6388*/ uint16(x86_xSetOp), uint16(x86_LGS),
-	/*6390*/ uint16(x86_xReadSlashR),
-	/*6391*/ uint16(x86_xArgR32),
-	/*6392*/ uint16(x86_xArgM16colon32),
-	/*6393*/ uint16(x86_xMatch),
-	/*6394*/ uint16(x86_xCondDataSize), 6382, 6388, 6398,
-	/*6398*/ uint16(x86_xSetOp), uint16(x86_LGS),
-	/*6400*/ uint16(x86_xReadSlashR),
-	/*6401*/ uint16(x86_xArgR64),
-	/*6402*/ uint16(x86_xArgM16colon64),
-	/*6403*/ uint16(x86_xMatch),
-	/*6404*/ uint16(x86_xCondIs64), 6407, 6423,
-	/*6407*/ uint16(x86_xCondDataSize), 6411, 6417, 0,
-	/*6411*/ uint16(x86_xSetOp), uint16(x86_MOVZX),
-	/*6413*/ uint16(x86_xReadSlashR),
-	/*6414*/ uint16(x86_xArgR16),
-	/*6415*/ uint16(x86_xArgRM8),
-	/*6416*/ uint16(x86_xMatch),
-	/*6417*/ uint16(x86_xSetOp), uint16(x86_MOVZX),
-	/*6419*/ uint16(x86_xReadSlashR),
-	/*6420*/ uint16(x86_xArgR32),
-	/*6421*/ uint16(x86_xArgRM8),
-	/*6422*/ uint16(x86_xMatch),
-	/*6423*/ uint16(x86_xCondDataSize), 6411, 6417, 6427,
-	/*6427*/ uint16(x86_xSetOp), uint16(x86_MOVZX),
-	/*6429*/ uint16(x86_xReadSlashR),
-	/*6430*/ uint16(x86_xArgR64),
-	/*6431*/ uint16(x86_xArgRM8),
-	/*6432*/ uint16(x86_xMatch),
-	/*6433*/ uint16(x86_xCondIs64), 6436, 6452,
-	/*6436*/ uint16(x86_xCondDataSize), 6440, 6446, 0,
-	/*6440*/ uint16(x86_xSetOp), uint16(x86_MOVZX),
-	/*6442*/ uint16(x86_xReadSlashR),
-	/*6443*/ uint16(x86_xArgR16),
-	/*6444*/ uint16(x86_xArgRM16),
-	/*6445*/ uint16(x86_xMatch),
-	/*6446*/ uint16(x86_xSetOp), uint16(x86_MOVZX),
-	/*6448*/ uint16(x86_xReadSlashR),
-	/*6449*/ uint16(x86_xArgR32),
-	/*6450*/ uint16(x86_xArgRM16),
-	/*6451*/ uint16(x86_xMatch),
-	/*6452*/ uint16(x86_xCondDataSize), 6440, 6446, 6456,
-	/*6456*/ uint16(x86_xSetOp), uint16(x86_MOVZX),
-	/*6458*/ uint16(x86_xReadSlashR),
-	/*6459*/ uint16(x86_xArgR64),
-	/*6460*/ uint16(x86_xArgRM16),
-	/*6461*/ uint16(x86_xMatch),
-	/*6462*/ uint16(x86_xCondIs64), 6465, 6485,
-	/*6465*/ uint16(x86_xCondPrefix), 1,
-	0xF3, 6469,
-	/*6469*/ uint16(x86_xCondDataSize), 6473, 6479, 0,
-	/*6473*/ uint16(x86_xSetOp), uint16(x86_POPCNT),
-	/*6475*/ uint16(x86_xReadSlashR),
-	/*6476*/ uint16(x86_xArgR16),
-	/*6477*/ uint16(x86_xArgRM16),
-	/*6478*/ uint16(x86_xMatch),
-	/*6479*/ uint16(x86_xSetOp), uint16(x86_POPCNT),
-	/*6481*/ uint16(x86_xReadSlashR),
-	/*6482*/ uint16(x86_xArgR32),
-	/*6483*/ uint16(x86_xArgRM32),
-	/*6484*/ uint16(x86_xMatch),
-	/*6485*/ uint16(x86_xCondPrefix), 1,
-	0xF3, 6489,
-	/*6489*/ uint16(x86_xCondDataSize), 6473, 6479, 6493,
-	/*6493*/ uint16(x86_xSetOp), uint16(x86_POPCNT),
-	/*6495*/ uint16(x86_xReadSlashR),
-	/*6496*/ uint16(x86_xArgR64),
-	/*6497*/ uint16(x86_xArgRM64),
-	/*6498*/ uint16(x86_xMatch),
-	/*6499*/ uint16(x86_xSetOp), uint16(x86_UD1),
-	/*6501*/ uint16(x86_xMatch),
-	/*6502*/ uint16(x86_xCondSlashR),
-	0,    // 0
-	0,    // 1
-	0,    // 2
-	0,    // 3
-	6511, // 4
-	6540, // 5
-	6569, // 6
-	6598, // 7
-	/*6511*/ uint16(x86_xCondIs64), 6514, 6530,
-	/*6514*/ uint16(x86_xCondDataSize), 6518, 6524, 0,
-	/*6518*/ uint16(x86_xSetOp), uint16(x86_BT),
-	/*6520*/ uint16(x86_xReadIb),
-	/*6521*/ uint16(x86_xArgRM16),
-	/*6522*/ uint16(x86_xArgImm8u),
-	/*6523*/ uint16(x86_xMatch),
-	/*6524*/ uint16(x86_xSetOp), uint16(x86_BT),
-	/*6526*/ uint16(x86_xReadIb),
-	/*6527*/ uint16(x86_xArgRM32),
-	/*6528*/ uint16(x86_xArgImm8u),
-	/*6529*/ uint16(x86_xMatch),
-	/*6530*/ uint16(x86_xCondDataSize), 6518, 6524, 6534,
-	/*6534*/ uint16(x86_xSetOp), uint16(x86_BT),
-	/*6536*/ uint16(x86_xReadIb),
-	/*6537*/ uint16(x86_xArgRM64),
-	/*6538*/ uint16(x86_xArgImm8u),
-	/*6539*/ uint16(x86_xMatch),
-	/*6540*/ uint16(x86_xCondIs64), 6543, 6559,
-	/*6543*/ uint16(x86_xCondDataSize), 6547, 6553, 0,
-	/*6547*/ uint16(x86_xSetOp), uint16(x86_BTS),
-	/*6549*/ uint16(x86_xReadIb),
-	/*6550*/ uint16(x86_xArgRM16),
-	/*6551*/ uint16(x86_xArgImm8u),
-	/*6552*/ uint16(x86_xMatch),
-	/*6553*/ uint16(x86_xSetOp), uint16(x86_BTS),
-	/*6555*/ uint16(x86_xReadIb),
-	/*6556*/ uint16(x86_xArgRM32),
-	/*6557*/ uint16(x86_xArgImm8u),
-	/*6558*/ uint16(x86_xMatch),
-	/*6559*/ uint16(x86_xCondDataSize), 6547, 6553, 6563,
-	/*6563*/ uint16(x86_xSetOp), uint16(x86_BTS),
-	/*6565*/ uint16(x86_xReadIb),
-	/*6566*/ uint16(x86_xArgRM64),
-	/*6567*/ uint16(x86_xArgImm8u),
-	/*6568*/ uint16(x86_xMatch),
-	/*6569*/ uint16(x86_xCondIs64), 6572, 6588,
-	/*6572*/ uint16(x86_xCondDataSize), 6576, 6582, 0,
-	/*6576*/ uint16(x86_xSetOp), uint16(x86_BTR),
-	/*6578*/ uint16(x86_xReadIb),
-	/*6579*/ uint16(x86_xArgRM16),
-	/*6580*/ uint16(x86_xArgImm8u),
-	/*6581*/ uint16(x86_xMatch),
-	/*6582*/ uint16(x86_xSetOp), uint16(x86_BTR),
-	/*6584*/ uint16(x86_xReadIb),
-	/*6585*/ uint16(x86_xArgRM32),
-	/*6586*/ uint16(x86_xArgImm8u),
-	/*6587*/ uint16(x86_xMatch),
-	/*6588*/ uint16(x86_xCondDataSize), 6576, 6582, 6592,
-	/*6592*/ uint16(x86_xSetOp), uint16(x86_BTR),
-	/*6594*/ uint16(x86_xReadIb),
-	/*6595*/ uint16(x86_xArgRM64),
-	/*6596*/ uint16(x86_xArgImm8u),
-	/*6597*/ uint16(x86_xMatch),
-	/*6598*/ uint16(x86_xCondIs64), 6601, 6617,
-	/*6601*/ uint16(x86_xCondDataSize), 6605, 6611, 0,
-	/*6605*/ uint16(x86_xSetOp), uint16(x86_BTC),
-	/*6607*/ uint16(x86_xReadIb),
-	/*6608*/ uint16(x86_xArgRM16),
-	/*6609*/ uint16(x86_xArgImm8u),
-	/*6610*/ uint16(x86_xMatch),
-	/*6611*/ uint16(x86_xSetOp), uint16(x86_BTC),
-	/*6613*/ uint16(x86_xReadIb),
-	/*6614*/ uint16(x86_xArgRM32),
-	/*6615*/ uint16(x86_xArgImm8u),
-	/*6616*/ uint16(x86_xMatch),
-	/*6617*/ uint16(x86_xCondDataSize), 6605, 6611, 6621,
-	/*6621*/ uint16(x86_xSetOp), uint16(x86_BTC),
-	/*6623*/ uint16(x86_xReadIb),
-	/*6624*/ uint16(x86_xArgRM64),
-	/*6625*/ uint16(x86_xArgImm8u),
-	/*6626*/ uint16(x86_xMatch),
-	/*6627*/ uint16(x86_xCondIs64), 6630, 6646,
-	/*6630*/ uint16(x86_xCondDataSize), 6634, 6640, 0,
-	/*6634*/ uint16(x86_xSetOp), uint16(x86_BTC),
-	/*6636*/ uint16(x86_xReadSlashR),
-	/*6637*/ uint16(x86_xArgRM16),
-	/*6638*/ uint16(x86_xArgR16),
-	/*6639*/ uint16(x86_xMatch),
-	/*6640*/ uint16(x86_xSetOp), uint16(x86_BTC),
-	/*6642*/ uint16(x86_xReadSlashR),
-	/*6643*/ uint16(x86_xArgRM32),
-	/*6644*/ uint16(x86_xArgR32),
-	/*6645*/ uint16(x86_xMatch),
-	/*6646*/ uint16(x86_xCondDataSize), 6634, 6640, 6650,
-	/*6650*/ uint16(x86_xSetOp), uint16(x86_BTC),
-	/*6652*/ uint16(x86_xReadSlashR),
-	/*6653*/ uint16(x86_xArgRM64),
-	/*6654*/ uint16(x86_xArgR64),
-	/*6655*/ uint16(x86_xMatch),
-	/*6656*/ uint16(x86_xCondIs64), 6659, 6697,
-	/*6659*/ uint16(x86_xCondPrefix), 2,
-	0xF3, 6681,
-	0x0, 6665,
-	/*6665*/ uint16(x86_xCondDataSize), 6669, 6675, 0,
-	/*6669*/ uint16(x86_xSetOp), uint16(x86_BSF),
-	/*6671*/ uint16(x86_xReadSlashR),
-	/*6672*/ uint16(x86_xArgR16),
-	/*6673*/ uint16(x86_xArgRM16),
-	/*6674*/ uint16(x86_xMatch),
-	/*6675*/ uint16(x86_xSetOp), uint16(x86_BSF),
-	/*6677*/ uint16(x86_xReadSlashR),
-	/*6678*/ uint16(x86_xArgR32),
-	/*6679*/ uint16(x86_xArgRM32),
-	/*6680*/ uint16(x86_xMatch),
-	/*6681*/ uint16(x86_xCondDataSize), 6685, 6691, 0,
-	/*6685*/ uint16(x86_xSetOp), uint16(x86_TZCNT),
-	/*6687*/ uint16(x86_xReadSlashR),
-	/*6688*/ uint16(x86_xArgR16),
-	/*6689*/ uint16(x86_xArgRM16),
-	/*6690*/ uint16(x86_xMatch),
-	/*6691*/ uint16(x86_xSetOp), uint16(x86_TZCNT),
-	/*6693*/ uint16(x86_xReadSlashR),
-	/*6694*/ uint16(x86_xArgR32),
-	/*6695*/ uint16(x86_xArgRM32),
-	/*6696*/ uint16(x86_xMatch),
-	/*6697*/ uint16(x86_xCondPrefix), 2,
-	0xF3, 6713,
-	0x0, 6703,
-	/*6703*/ uint16(x86_xCondDataSize), 6669, 6675, 6707,
-	/*6707*/ uint16(x86_xSetOp), uint16(x86_BSF),
-	/*6709*/ uint16(x86_xReadSlashR),
-	/*6710*/ uint16(x86_xArgR64),
-	/*6711*/ uint16(x86_xArgRM64),
-	/*6712*/ uint16(x86_xMatch),
-	/*6713*/ uint16(x86_xCondDataSize), 6685, 6691, 6717,
-	/*6717*/ uint16(x86_xSetOp), uint16(x86_TZCNT),
-	/*6719*/ uint16(x86_xReadSlashR),
-	/*6720*/ uint16(x86_xArgR64),
-	/*6721*/ uint16(x86_xArgRM64),
-	/*6722*/ uint16(x86_xMatch),
-	/*6723*/ uint16(x86_xCondIs64), 6726, 6764,
-	/*6726*/ uint16(x86_xCondPrefix), 2,
-	0xF3, 6748,
-	0x0, 6732,
-	/*6732*/ uint16(x86_xCondDataSize), 6736, 6742, 0,
-	/*6736*/ uint16(x86_xSetOp), uint16(x86_BSR),
-	/*6738*/ uint16(x86_xReadSlashR),
-	/*6739*/ uint16(x86_xArgR16),
-	/*6740*/ uint16(x86_xArgRM16),
-	/*6741*/ uint16(x86_xMatch),
-	/*6742*/ uint16(x86_xSetOp), uint16(x86_BSR),
-	/*6744*/ uint16(x86_xReadSlashR),
-	/*6745*/ uint16(x86_xArgR32),
-	/*6746*/ uint16(x86_xArgRM32),
-	/*6747*/ uint16(x86_xMatch),
-	/*6748*/ uint16(x86_xCondDataSize), 6752, 6758, 0,
-	/*6752*/ uint16(x86_xSetOp), uint16(x86_LZCNT),
-	/*6754*/ uint16(x86_xReadSlashR),
-	/*6755*/ uint16(x86_xArgR16),
-	/*6756*/ uint16(x86_xArgRM16),
-	/*6757*/ uint16(x86_xMatch),
-	/*6758*/ uint16(x86_xSetOp), uint16(x86_LZCNT),
-	/*6760*/ uint16(x86_xReadSlashR),
-	/*6761*/ uint16(x86_xArgR32),
-	/*6762*/ uint16(x86_xArgRM32),
-	/*6763*/ uint16(x86_xMatch),
-	/*6764*/ uint16(x86_xCondPrefix), 2,
-	0xF3, 6780,
-	0x0, 6770,
-	/*6770*/ uint16(x86_xCondDataSize), 6736, 6742, 6774,
-	/*6774*/ uint16(x86_xSetOp), uint16(x86_BSR),
-	/*6776*/ uint16(x86_xReadSlashR),
-	/*6777*/ uint16(x86_xArgR64),
-	/*6778*/ uint16(x86_xArgRM64),
-	/*6779*/ uint16(x86_xMatch),
-	/*6780*/ uint16(x86_xCondDataSize), 6752, 6758, 6784,
-	/*6784*/ uint16(x86_xSetOp), uint16(x86_LZCNT),
-	/*6786*/ uint16(x86_xReadSlashR),
-	/*6787*/ uint16(x86_xArgR64),
-	/*6788*/ uint16(x86_xArgRM64),
-	/*6789*/ uint16(x86_xMatch),
-	/*6790*/ uint16(x86_xCondIs64), 6793, 6809,
-	/*6793*/ uint16(x86_xCondDataSize), 6797, 6803, 0,
-	/*6797*/ uint16(x86_xSetOp), uint16(x86_MOVSX),
-	/*6799*/ uint16(x86_xReadSlashR),
-	/*6800*/ uint16(x86_xArgR16),
-	/*6801*/ uint16(x86_xArgRM8),
-	/*6802*/ uint16(x86_xMatch),
-	/*6803*/ uint16(x86_xSetOp), uint16(x86_MOVSX),
-	/*6805*/ uint16(x86_xReadSlashR),
-	/*6806*/ uint16(x86_xArgR32),
-	/*6807*/ uint16(x86_xArgRM8),
-	/*6808*/ uint16(x86_xMatch),
-	/*6809*/ uint16(x86_xCondDataSize), 6797, 6803, 6813,
-	/*6813*/ uint16(x86_xSetOp), uint16(x86_MOVSX),
-	/*6815*/ uint16(x86_xReadSlashR),
-	/*6816*/ uint16(x86_xArgR64),
-	/*6817*/ uint16(x86_xArgRM8),
-	/*6818*/ uint16(x86_xMatch),
-	/*6819*/ uint16(x86_xCondIs64), 6822, 6838,
-	/*6822*/ uint16(x86_xCondDataSize), 6826, 6832, 0,
-	/*6826*/ uint16(x86_xSetOp), uint16(x86_MOVSX),
-	/*6828*/ uint16(x86_xReadSlashR),
-	/*6829*/ uint16(x86_xArgR16),
-	/*6830*/ uint16(x86_xArgRM16),
-	/*6831*/ uint16(x86_xMatch),
-	/*6832*/ uint16(x86_xSetOp), uint16(x86_MOVSX),
-	/*6834*/ uint16(x86_xReadSlashR),
-	/*6835*/ uint16(x86_xArgR32),
-	/*6836*/ uint16(x86_xArgRM16),
-	/*6837*/ uint16(x86_xMatch),
-	/*6838*/ uint16(x86_xCondDataSize), 6826, 6832, 6842,
-	/*6842*/ uint16(x86_xSetOp), uint16(x86_MOVSX),
-	/*6844*/ uint16(x86_xReadSlashR),
-	/*6845*/ uint16(x86_xArgR64),
-	/*6846*/ uint16(x86_xArgRM16),
-	/*6847*/ uint16(x86_xMatch),
-	/*6848*/ uint16(x86_xSetOp), uint16(x86_XADD),
-	/*6850*/ uint16(x86_xReadSlashR),
-	/*6851*/ uint16(x86_xArgRM8),
-	/*6852*/ uint16(x86_xArgR8),
-	/*6853*/ uint16(x86_xMatch),
-	/*6854*/ uint16(x86_xCondIs64), 6857, 6873,
-	/*6857*/ uint16(x86_xCondDataSize), 6861, 6867, 0,
-	/*6861*/ uint16(x86_xSetOp), uint16(x86_XADD),
-	/*6863*/ uint16(x86_xReadSlashR),
-	/*6864*/ uint16(x86_xArgRM16),
-	/*6865*/ uint16(x86_xArgR16),
-	/*6866*/ uint16(x86_xMatch),
-	/*6867*/ uint16(x86_xSetOp), uint16(x86_XADD),
-	/*6869*/ uint16(x86_xReadSlashR),
-	/*6870*/ uint16(x86_xArgRM32),
-	/*6871*/ uint16(x86_xArgR32),
-	/*6872*/ uint16(x86_xMatch),
-	/*6873*/ uint16(x86_xCondDataSize), 6861, 6867, 6877,
-	/*6877*/ uint16(x86_xSetOp), uint16(x86_XADD),
-	/*6879*/ uint16(x86_xReadSlashR),
-	/*6880*/ uint16(x86_xArgRM64),
-	/*6881*/ uint16(x86_xArgR64),
-	/*6882*/ uint16(x86_xMatch),
-	/*6883*/ uint16(x86_xCondPrefix), 4,
-	0xF3, 6917,
-	0xF2, 6909,
-	0x66, 6901,
-	0x0, 6893,
-	/*6893*/ uint16(x86_xSetOp), uint16(x86_CMPPS),
-	/*6895*/ uint16(x86_xReadSlashR),
-	/*6896*/ uint16(x86_xReadIb),
-	/*6897*/ uint16(x86_xArgXmm1),
-	/*6898*/ uint16(x86_xArgXmm2M128),
-	/*6899*/ uint16(x86_xArgImm8u),
-	/*6900*/ uint16(x86_xMatch),
-	/*6901*/ uint16(x86_xSetOp), uint16(x86_CMPPD),
-	/*6903*/ uint16(x86_xReadSlashR),
-	/*6904*/ uint16(x86_xReadIb),
-	/*6905*/ uint16(x86_xArgXmm1),
-	/*6906*/ uint16(x86_xArgXmm2M128),
-	/*6907*/ uint16(x86_xArgImm8u),
-	/*6908*/ uint16(x86_xMatch),
-	/*6909*/ uint16(x86_xSetOp), uint16(x86_CMPSD_XMM),
-	/*6911*/ uint16(x86_xReadSlashR),
-	/*6912*/ uint16(x86_xReadIb),
-	/*6913*/ uint16(x86_xArgXmm1),
-	/*6914*/ uint16(x86_xArgXmm2M64),
-	/*6915*/ uint16(x86_xArgImm8u),
-	/*6916*/ uint16(x86_xMatch),
-	/*6917*/ uint16(x86_xSetOp), uint16(x86_CMPSS),
-	/*6919*/ uint16(x86_xReadSlashR),
-	/*6920*/ uint16(x86_xReadIb),
-	/*6921*/ uint16(x86_xArgXmm1),
-	/*6922*/ uint16(x86_xArgXmm2M32),
-	/*6923*/ uint16(x86_xArgImm8u),
-	/*6924*/ uint16(x86_xMatch),
-	/*6925*/ uint16(x86_xCondIs64), 6928, 6944,
-	/*6928*/ uint16(x86_xCondDataSize), 6932, 6938, 0,
-	/*6932*/ uint16(x86_xSetOp), uint16(x86_MOVNTI),
-	/*6934*/ uint16(x86_xReadSlashR),
-	/*6935*/ uint16(x86_xArgM32),
-	/*6936*/ uint16(x86_xArgR32),
-	/*6937*/ uint16(x86_xMatch),
-	/*6938*/ uint16(x86_xSetOp), uint16(x86_MOVNTI),
-	/*6940*/ uint16(x86_xReadSlashR),
-	/*6941*/ uint16(x86_xArgM32),
-	/*6942*/ uint16(x86_xArgR32),
-	/*6943*/ uint16(x86_xMatch),
-	/*6944*/ uint16(x86_xCondDataSize), 6932, 6938, 6948,
-	/*6948*/ uint16(x86_xSetOp), uint16(x86_MOVNTI),
-	/*6950*/ uint16(x86_xReadSlashR),
-	/*6951*/ uint16(x86_xArgM64),
-	/*6952*/ uint16(x86_xArgR64),
-	/*6953*/ uint16(x86_xMatch),
-	/*6954*/ uint16(x86_xCondPrefix), 2,
-	0x66, 6968,
-	0x0, 6960,
-	/*6960*/ uint16(x86_xSetOp), uint16(x86_PINSRW),
-	/*6962*/ uint16(x86_xReadSlashR),
-	/*6963*/ uint16(x86_xReadIb),
-	/*6964*/ uint16(x86_xArgMm),
-	/*6965*/ uint16(x86_xArgR32M16),
-	/*6966*/ uint16(x86_xArgImm8u),
-	/*6967*/ uint16(x86_xMatch),
-	/*6968*/ uint16(x86_xSetOp), uint16(x86_PINSRW),
-	/*6970*/ uint16(x86_xReadSlashR),
-	/*6971*/ uint16(x86_xReadIb),
-	/*6972*/ uint16(x86_xArgXmm),
-	/*6973*/ uint16(x86_xArgR32M16),
-	/*6974*/ uint16(x86_xArgImm8u),
-	/*6975*/ uint16(x86_xMatch),
-	/*6976*/ uint16(x86_xCondPrefix), 2,
-	0x66, 6990,
-	0x0, 6982,
-	/*6982*/ uint16(x86_xSetOp), uint16(x86_PEXTRW),
-	/*6984*/ uint16(x86_xReadSlashR),
-	/*6985*/ uint16(x86_xReadIb),
-	/*6986*/ uint16(x86_xArgR32),
-	/*6987*/ uint16(x86_xArgMm2),
-	/*6988*/ uint16(x86_xArgImm8u),
-	/*6989*/ uint16(x86_xMatch),
-	/*6990*/ uint16(x86_xSetOp), uint16(x86_PEXTRW),
-	/*6992*/ uint16(x86_xReadSlashR),
-	/*6993*/ uint16(x86_xReadIb),
-	/*6994*/ uint16(x86_xArgR32),
-	/*6995*/ uint16(x86_xArgXmm2),
-	/*6996*/ uint16(x86_xArgImm8u),
-	/*6997*/ uint16(x86_xMatch),
-	/*6998*/ uint16(x86_xCondPrefix), 2,
-	0x66, 7012,
-	0x0, 7004,
-	/*7004*/ uint16(x86_xSetOp), uint16(x86_SHUFPS),
-	/*7006*/ uint16(x86_xReadSlashR),
-	/*7007*/ uint16(x86_xReadIb),
-	/*7008*/ uint16(x86_xArgXmm1),
-	/*7009*/ uint16(x86_xArgXmm2M128),
-	/*7010*/ uint16(x86_xArgImm8u),
-	/*7011*/ uint16(x86_xMatch),
-	/*7012*/ uint16(x86_xSetOp), uint16(x86_SHUFPD),
-	/*7014*/ uint16(x86_xReadSlashR),
-	/*7015*/ uint16(x86_xReadIb),
-	/*7016*/ uint16(x86_xArgXmm1),
-	/*7017*/ uint16(x86_xArgXmm2M128),
-	/*7018*/ uint16(x86_xArgImm8u),
-	/*7019*/ uint16(x86_xMatch),
-	/*7020*/ uint16(x86_xCondSlashR),
-	0,    // 0
-	7029, // 1
-	0,    // 2
-	7052, // 3
-	7075, // 4
-	7098, // 5
-	7121, // 6
-	0,    // 7
-	/*7029*/ uint16(x86_xCondIs64), 7032, 7044,
-	/*7032*/ uint16(x86_xCondDataSize), 7036, 7040, 0,
-	/*7036*/ uint16(x86_xSetOp), uint16(x86_CMPXCHG8B),
-	/*7038*/ uint16(x86_xArgM64),
-	/*7039*/ uint16(x86_xMatch),
-	/*7040*/ uint16(x86_xSetOp), uint16(x86_CMPXCHG8B),
-	/*7042*/ uint16(x86_xArgM64),
-	/*7043*/ uint16(x86_xMatch),
-	/*7044*/ uint16(x86_xCondDataSize), 7036, 7040, 7048,
-	/*7048*/ uint16(x86_xSetOp), uint16(x86_CMPXCHG16B),
-	/*7050*/ uint16(x86_xArgM128),
-	/*7051*/ uint16(x86_xMatch),
-	/*7052*/ uint16(x86_xCondIs64), 7055, 7067,
-	/*7055*/ uint16(x86_xCondDataSize), 7059, 7063, 0,
-	/*7059*/ uint16(x86_xSetOp), uint16(x86_XRSTORS),
-	/*7061*/ uint16(x86_xArgMem),
-	/*7062*/ uint16(x86_xMatch),
-	/*7063*/ uint16(x86_xSetOp), uint16(x86_XRSTORS),
-	/*7065*/ uint16(x86_xArgMem),
-	/*7066*/ uint16(x86_xMatch),
-	/*7067*/ uint16(x86_xCondDataSize), 7059, 7063, 7071,
-	/*7071*/ uint16(x86_xSetOp), uint16(x86_XRSTORS64),
-	/*7073*/ uint16(x86_xArgMem),
-	/*7074*/ uint16(x86_xMatch),
-	/*7075*/ uint16(x86_xCondIs64), 7078, 7090,
-	/*7078*/ uint16(x86_xCondDataSize), 7082, 7086, 0,
-	/*7082*/ uint16(x86_xSetOp), uint16(x86_XSAVEC),
-	/*7084*/ uint16(x86_xArgMem),
-	/*7085*/ uint16(x86_xMatch),
-	/*7086*/ uint16(x86_xSetOp), uint16(x86_XSAVEC),
-	/*7088*/ uint16(x86_xArgMem),
-	/*7089*/ uint16(x86_xMatch),
-	/*7090*/ uint16(x86_xCondDataSize), 7082, 7086, 7094,
-	/*7094*/ uint16(x86_xSetOp), uint16(x86_XSAVEC64),
-	/*7096*/ uint16(x86_xArgMem),
-	/*7097*/ uint16(x86_xMatch),
-	/*7098*/ uint16(x86_xCondIs64), 7101, 7113,
-	/*7101*/ uint16(x86_xCondDataSize), 7105, 7109, 0,
-	/*7105*/ uint16(x86_xSetOp), uint16(x86_XSAVES),
-	/*7107*/ uint16(x86_xArgMem),
-	/*7108*/ uint16(x86_xMatch),
-	/*7109*/ uint16(x86_xSetOp), uint16(x86_XSAVES),
-	/*7111*/ uint16(x86_xArgMem),
-	/*7112*/ uint16(x86_xMatch),
-	/*7113*/ uint16(x86_xCondDataSize), 7105, 7109, 7117,
-	/*7117*/ uint16(x86_xSetOp), uint16(x86_XSAVES64),
-	/*7119*/ uint16(x86_xArgMem),
-	/*7120*/ uint16(x86_xMatch),
-	/*7121*/ uint16(x86_xCondIs64), 7124, 7142,
-	/*7124*/ uint16(x86_xCondDataSize), 7128, 7135, 0,
-	/*7128*/ uint16(x86_xCondIsMem), 7131, 0,
-	/*7131*/ uint16(x86_xSetOp), uint16(x86_RDRAND),
-	/*7133*/ uint16(x86_xArgRmf16),
-	/*7134*/ uint16(x86_xMatch),
-	/*7135*/ uint16(x86_xCondIsMem), 7138, 0,
-	/*7138*/ uint16(x86_xSetOp), uint16(x86_RDRAND),
-	/*7140*/ uint16(x86_xArgRmf32),
-	/*7141*/ uint16(x86_xMatch),
-	/*7142*/ uint16(x86_xCondDataSize), 7128, 7135, 7146,
-	/*7146*/ uint16(x86_xSetOp), uint16(x86_RDRAND),
-	/*7148*/ uint16(x86_xMatch),
-	/*7149*/ uint16(x86_xCondIs64), 7152, 7164,
-	/*7152*/ uint16(x86_xCondDataSize), 7156, 7160, 0,
-	/*7156*/ uint16(x86_xSetOp), uint16(x86_BSWAP),
-	/*7158*/ uint16(x86_xArgR16op),
-	/*7159*/ uint16(x86_xMatch),
-	/*7160*/ uint16(x86_xSetOp), uint16(x86_BSWAP),
-	/*7162*/ uint16(x86_xArgR32op),
-	/*7163*/ uint16(x86_xMatch),
-	/*7164*/ uint16(x86_xCondDataSize), 7156, 7160, 7168,
-	/*7168*/ uint16(x86_xSetOp), uint16(x86_BSWAP),
-	/*7170*/ uint16(x86_xArgR64op),
-	/*7171*/ uint16(x86_xMatch),
-	/*7172*/ uint16(x86_xCondPrefix), 2,
-	0xF2, 7184,
-	0x66, 7178,
-	/*7178*/ uint16(x86_xSetOp), uint16(x86_ADDSUBPD),
-	/*7180*/ uint16(x86_xReadSlashR),
-	/*7181*/ uint16(x86_xArgXmm1),
-	/*7182*/ uint16(x86_xArgXmm2M128),
-	/*7183*/ uint16(x86_xMatch),
-	/*7184*/ uint16(x86_xSetOp), uint16(x86_ADDSUBPS),
-	/*7186*/ uint16(x86_xReadSlashR),
-	/*7187*/ uint16(x86_xArgXmm1),
-	/*7188*/ uint16(x86_xArgXmm2M128),
-	/*7189*/ uint16(x86_xMatch),
-	/*7190*/ uint16(x86_xCondPrefix), 2,
-	0x66, 7202,
-	0x0, 7196,
-	/*7196*/ uint16(x86_xSetOp), uint16(x86_PSRLW),
-	/*7198*/ uint16(x86_xReadSlashR),
-	/*7199*/ uint16(x86_xArgMm),
-	/*7200*/ uint16(x86_xArgMmM64),
-	/*7201*/ uint16(x86_xMatch),
-	/*7202*/ uint16(x86_xSetOp), uint16(x86_PSRLW),
-	/*7204*/ uint16(x86_xReadSlashR),
-	/*7205*/ uint16(x86_xArgXmm1),
-	/*7206*/ uint16(x86_xArgXmm2M128),
-	/*7207*/ uint16(x86_xMatch),
-	/*7208*/ uint16(x86_xCondPrefix), 2,
-	0x66, 7220,
-	0x0, 7214,
-	/*7214*/ uint16(x86_xSetOp), uint16(x86_PSRLD),
-	/*7216*/ uint16(x86_xReadSlashR),
-	/*7217*/ uint16(x86_xArgMm),
-	/*7218*/ uint16(x86_xArgMmM64),
-	/*7219*/ uint16(x86_xMatch),
-	/*7220*/ uint16(x86_xSetOp), uint16(x86_PSRLD),
-	/*7222*/ uint16(x86_xReadSlashR),
-	/*7223*/ uint16(x86_xArgXmm1),
-	/*7224*/ uint16(x86_xArgXmm2M128),
-	/*7225*/ uint16(x86_xMatch),
-	/*7226*/ uint16(x86_xCondPrefix), 2,
-	0x66, 7238,
-	0x0, 7232,
-	/*7232*/ uint16(x86_xSetOp), uint16(x86_PSRLQ),
-	/*7234*/ uint16(x86_xReadSlashR),
-	/*7235*/ uint16(x86_xArgMm),
-	/*7236*/ uint16(x86_xArgMmM64),
-	/*7237*/ uint16(x86_xMatch),
-	/*7238*/ uint16(x86_xSetOp), uint16(x86_PSRLQ),
-	/*7240*/ uint16(x86_xReadSlashR),
-	/*7241*/ uint16(x86_xArgXmm1),
-	/*7242*/ uint16(x86_xArgXmm2M128),
-	/*7243*/ uint16(x86_xMatch),
-	/*7244*/ uint16(x86_xCondPrefix), 2,
-	0x66, 7256,
-	0x0, 7250,
-	/*7250*/ uint16(x86_xSetOp), uint16(x86_PADDQ),
-	/*7252*/ uint16(x86_xReadSlashR),
-	/*7253*/ uint16(x86_xArgMm1),
-	/*7254*/ uint16(x86_xArgMm2M64),
-	/*7255*/ uint16(x86_xMatch),
-	/*7256*/ uint16(x86_xSetOp), uint16(x86_PADDQ),
-	/*7258*/ uint16(x86_xReadSlashR),
-	/*7259*/ uint16(x86_xArgXmm1),
-	/*7260*/ uint16(x86_xArgXmm2M128),
-	/*7261*/ uint16(x86_xMatch),
-	/*7262*/ uint16(x86_xCondPrefix), 2,
-	0x66, 7274,
-	0x0, 7268,
-	/*7268*/ uint16(x86_xSetOp), uint16(x86_PMULLW),
-	/*7270*/ uint16(x86_xReadSlashR),
-	/*7271*/ uint16(x86_xArgMm),
-	/*7272*/ uint16(x86_xArgMmM64),
-	/*7273*/ uint16(x86_xMatch),
-	/*7274*/ uint16(x86_xSetOp), uint16(x86_PMULLW),
-	/*7276*/ uint16(x86_xReadSlashR),
-	/*7277*/ uint16(x86_xArgXmm1),
-	/*7278*/ uint16(x86_xArgXmm2M128),
-	/*7279*/ uint16(x86_xMatch),
-	/*7280*/ uint16(x86_xCondPrefix), 3,
-	0xF3, 7300,
-	0xF2, 7294,
-	0x66, 7288,
-	/*7288*/ uint16(x86_xSetOp), uint16(x86_MOVQ),
-	/*7290*/ uint16(x86_xReadSlashR),
-	/*7291*/ uint16(x86_xArgXmm2M64),
-	/*7292*/ uint16(x86_xArgXmm1),
-	/*7293*/ uint16(x86_xMatch),
-	/*7294*/ uint16(x86_xSetOp), uint16(x86_MOVDQ2Q),
-	/*7296*/ uint16(x86_xReadSlashR),
-	/*7297*/ uint16(x86_xArgMm),
-	/*7298*/ uint16(x86_xArgXmm2),
-	/*7299*/ uint16(x86_xMatch),
-	/*7300*/ uint16(x86_xSetOp), uint16(x86_MOVQ2DQ),
-	/*7302*/ uint16(x86_xReadSlashR),
-	/*7303*/ uint16(x86_xArgXmm1),
-	/*7304*/ uint16(x86_xArgMm2),
-	/*7305*/ uint16(x86_xMatch),
-	/*7306*/ uint16(x86_xCondPrefix), 2,
-	0x66, 7318,
-	0x0, 7312,
-	/*7312*/ uint16(x86_xSetOp), uint16(x86_PMOVMSKB),
-	/*7314*/ uint16(x86_xReadSlashR),
-	/*7315*/ uint16(x86_xArgR32),
-	/*7316*/ uint16(x86_xArgMm2),
-	/*7317*/ uint16(x86_xMatch),
-	/*7318*/ uint16(x86_xSetOp), uint16(x86_PMOVMSKB),
-	/*7320*/ uint16(x86_xReadSlashR),
-	/*7321*/ uint16(x86_xArgR32),
-	/*7322*/ uint16(x86_xArgXmm2),
-	/*7323*/ uint16(x86_xMatch),
-	/*7324*/ uint16(x86_xCondPrefix), 2,
-	0x66, 7336,
-	0x0, 7330,
-	/*7330*/ uint16(x86_xSetOp), uint16(x86_PSUBUSB),
-	/*7332*/ uint16(x86_xReadSlashR),
-	/*7333*/ uint16(x86_xArgMm),
-	/*7334*/ uint16(x86_xArgMmM64),
-	/*7335*/ uint16(x86_xMatch),
-	/*7336*/ uint16(x86_xSetOp), uint16(x86_PSUBUSB),
-	/*7338*/ uint16(x86_xReadSlashR),
-	/*7339*/ uint16(x86_xArgXmm1),
-	/*7340*/ uint16(x86_xArgXmm2M128),
-	/*7341*/ uint16(x86_xMatch),
-	/*7342*/ uint16(x86_xCondPrefix), 2,
-	0x66, 7354,
-	0x0, 7348,
-	/*7348*/ uint16(x86_xSetOp), uint16(x86_PSUBUSW),
-	/*7350*/ uint16(x86_xReadSlashR),
-	/*7351*/ uint16(x86_xArgMm),
-	/*7352*/ uint16(x86_xArgMmM64),
-	/*7353*/ uint16(x86_xMatch),
-	/*7354*/ uint16(x86_xSetOp), uint16(x86_PSUBUSW),
-	/*7356*/ uint16(x86_xReadSlashR),
-	/*7357*/ uint16(x86_xArgXmm1),
-	/*7358*/ uint16(x86_xArgXmm2M128),
-	/*7359*/ uint16(x86_xMatch),
-	/*7360*/ uint16(x86_xCondPrefix), 2,
-	0x66, 7372,
-	0x0, 7366,
-	/*7366*/ uint16(x86_xSetOp), uint16(x86_PMINUB),
-	/*7368*/ uint16(x86_xReadSlashR),
-	/*7369*/ uint16(x86_xArgMm1),
-	/*7370*/ uint16(x86_xArgMm2M64),
-	/*7371*/ uint16(x86_xMatch),
-	/*7372*/ uint16(x86_xSetOp), uint16(x86_PMINUB),
-	/*7374*/ uint16(x86_xReadSlashR),
-	/*7375*/ uint16(x86_xArgXmm1),
-	/*7376*/ uint16(x86_xArgXmm2M128),
-	/*7377*/ uint16(x86_xMatch),
-	/*7378*/ uint16(x86_xCondPrefix), 2,
-	0x66, 7390,
-	0x0, 7384,
-	/*7384*/ uint16(x86_xSetOp), uint16(x86_PAND),
-	/*7386*/ uint16(x86_xReadSlashR),
-	/*7387*/ uint16(x86_xArgMm),
-	/*7388*/ uint16(x86_xArgMmM64),
-	/*7389*/ uint16(x86_xMatch),
-	/*7390*/ uint16(x86_xSetOp), uint16(x86_PAND),
-	/*7392*/ uint16(x86_xReadSlashR),
-	/*7393*/ uint16(x86_xArgXmm1),
-	/*7394*/ uint16(x86_xArgXmm2M128),
-	/*7395*/ uint16(x86_xMatch),
-	/*7396*/ uint16(x86_xCondPrefix), 2,
-	0x66, 7408,
-	0x0, 7402,
-	/*7402*/ uint16(x86_xSetOp), uint16(x86_PADDUSB),
-	/*7404*/ uint16(x86_xReadSlashR),
-	/*7405*/ uint16(x86_xArgMm),
-	/*7406*/ uint16(x86_xArgMmM64),
-	/*7407*/ uint16(x86_xMatch),
-	/*7408*/ uint16(x86_xSetOp), uint16(x86_PADDUSB),
-	/*7410*/ uint16(x86_xReadSlashR),
-	/*7411*/ uint16(x86_xArgXmm1),
-	/*7412*/ uint16(x86_xArgXmm2M128),
-	/*7413*/ uint16(x86_xMatch),
-	/*7414*/ uint16(x86_xCondPrefix), 2,
-	0x66, 7426,
-	0x0, 7420,
-	/*7420*/ uint16(x86_xSetOp), uint16(x86_PADDUSW),
-	/*7422*/ uint16(x86_xReadSlashR),
-	/*7423*/ uint16(x86_xArgMm),
-	/*7424*/ uint16(x86_xArgMmM64),
-	/*7425*/ uint16(x86_xMatch),
-	/*7426*/ uint16(x86_xSetOp), uint16(x86_PADDUSW),
-	/*7428*/ uint16(x86_xReadSlashR),
-	/*7429*/ uint16(x86_xArgXmm1),
-	/*7430*/ uint16(x86_xArgXmm2M128),
-	/*7431*/ uint16(x86_xMatch),
-	/*7432*/ uint16(x86_xCondPrefix), 2,
-	0x66, 7444,
-	0x0, 7438,
-	/*7438*/ uint16(x86_xSetOp), uint16(x86_PMAXUB),
-	/*7440*/ uint16(x86_xReadSlashR),
-	/*7441*/ uint16(x86_xArgMm1),
-	/*7442*/ uint16(x86_xArgMm2M64),
-	/*7443*/ uint16(x86_xMatch),
-	/*7444*/ uint16(x86_xSetOp), uint16(x86_PMAXUB),
-	/*7446*/ uint16(x86_xReadSlashR),
-	/*7447*/ uint16(x86_xArgXmm1),
-	/*7448*/ uint16(x86_xArgXmm2M128),
-	/*7449*/ uint16(x86_xMatch),
-	/*7450*/ uint16(x86_xCondPrefix), 2,
-	0x66, 7462,
-	0x0, 7456,
-	/*7456*/ uint16(x86_xSetOp), uint16(x86_PANDN),
-	/*7458*/ uint16(x86_xReadSlashR),
-	/*7459*/ uint16(x86_xArgMm),
-	/*7460*/ uint16(x86_xArgMmM64),
-	/*7461*/ uint16(x86_xMatch),
-	/*7462*/ uint16(x86_xSetOp), uint16(x86_PANDN),
-	/*7464*/ uint16(x86_xReadSlashR),
-	/*7465*/ uint16(x86_xArgXmm1),
-	/*7466*/ uint16(x86_xArgXmm2M128),
-	/*7467*/ uint16(x86_xMatch),
-	/*7468*/ uint16(x86_xCondPrefix), 2,
-	0x66, 7480,
-	0x0, 7474,
-	/*7474*/ uint16(x86_xSetOp), uint16(x86_PAVGB),
-	/*7476*/ uint16(x86_xReadSlashR),
-	/*7477*/ uint16(x86_xArgMm1),
-	/*7478*/ uint16(x86_xArgMm2M64),
-	/*7479*/ uint16(x86_xMatch),
-	/*7480*/ uint16(x86_xSetOp), uint16(x86_PAVGB),
-	/*7482*/ uint16(x86_xReadSlashR),
-	/*7483*/ uint16(x86_xArgXmm1),
-	/*7484*/ uint16(x86_xArgXmm2M128),
-	/*7485*/ uint16(x86_xMatch),
-	/*7486*/ uint16(x86_xCondPrefix), 2,
-	0x66, 7498,
-	0x0, 7492,
-	/*7492*/ uint16(x86_xSetOp), uint16(x86_PSRAW),
-	/*7494*/ uint16(x86_xReadSlashR),
-	/*7495*/ uint16(x86_xArgMm),
-	/*7496*/ uint16(x86_xArgMmM64),
-	/*7497*/ uint16(x86_xMatch),
-	/*7498*/ uint16(x86_xSetOp), uint16(x86_PSRAW),
-	/*7500*/ uint16(x86_xReadSlashR),
-	/*7501*/ uint16(x86_xArgXmm1),
-	/*7502*/ uint16(x86_xArgXmm2M128),
-	/*7503*/ uint16(x86_xMatch),
-	/*7504*/ uint16(x86_xCondPrefix), 2,
-	0x66, 7516,
-	0x0, 7510,
-	/*7510*/ uint16(x86_xSetOp), uint16(x86_PSRAD),
-	/*7512*/ uint16(x86_xReadSlashR),
-	/*7513*/ uint16(x86_xArgMm),
-	/*7514*/ uint16(x86_xArgMmM64),
-	/*7515*/ uint16(x86_xMatch),
-	/*7516*/ uint16(x86_xSetOp), uint16(x86_PSRAD),
-	/*7518*/ uint16(x86_xReadSlashR),
-	/*7519*/ uint16(x86_xArgXmm1),
-	/*7520*/ uint16(x86_xArgXmm2M128),
-	/*7521*/ uint16(x86_xMatch),
-	/*7522*/ uint16(x86_xCondPrefix), 2,
-	0x66, 7534,
-	0x0, 7528,
-	/*7528*/ uint16(x86_xSetOp), uint16(x86_PAVGW),
-	/*7530*/ uint16(x86_xReadSlashR),
-	/*7531*/ uint16(x86_xArgMm1),
-	/*7532*/ uint16(x86_xArgMm2M64),
-	/*7533*/ uint16(x86_xMatch),
-	/*7534*/ uint16(x86_xSetOp), uint16(x86_PAVGW),
-	/*7536*/ uint16(x86_xReadSlashR),
-	/*7537*/ uint16(x86_xArgXmm1),
-	/*7538*/ uint16(x86_xArgXmm2M128),
-	/*7539*/ uint16(x86_xMatch),
-	/*7540*/ uint16(x86_xCondPrefix), 2,
-	0x66, 7552,
-	0x0, 7546,
-	/*7546*/ uint16(x86_xSetOp), uint16(x86_PMULHUW),
-	/*7548*/ uint16(x86_xReadSlashR),
-	/*7549*/ uint16(x86_xArgMm1),
-	/*7550*/ uint16(x86_xArgMm2M64),
-	/*7551*/ uint16(x86_xMatch),
-	/*7552*/ uint16(x86_xSetOp), uint16(x86_PMULHUW),
-	/*7554*/ uint16(x86_xReadSlashR),
-	/*7555*/ uint16(x86_xArgXmm1),
-	/*7556*/ uint16(x86_xArgXmm2M128),
-	/*7557*/ uint16(x86_xMatch),
-	/*7558*/ uint16(x86_xCondPrefix), 2,
-	0x66, 7570,
-	0x0, 7564,
-	/*7564*/ uint16(x86_xSetOp), uint16(x86_PMULHW),
-	/*7566*/ uint16(x86_xReadSlashR),
-	/*7567*/ uint16(x86_xArgMm),
-	/*7568*/ uint16(x86_xArgMmM64),
-	/*7569*/ uint16(x86_xMatch),
-	/*7570*/ uint16(x86_xSetOp), uint16(x86_PMULHW),
-	/*7572*/ uint16(x86_xReadSlashR),
-	/*7573*/ uint16(x86_xArgXmm1),
-	/*7574*/ uint16(x86_xArgXmm2M128),
-	/*7575*/ uint16(x86_xMatch),
-	/*7576*/ uint16(x86_xCondPrefix), 3,
-	0xF3, 7596,
-	0xF2, 7590,
-	0x66, 7584,
-	/*7584*/ uint16(x86_xSetOp), uint16(x86_CVTTPD2DQ),
-	/*7586*/ uint16(x86_xReadSlashR),
-	/*7587*/ uint16(x86_xArgXmm1),
-	/*7588*/ uint16(x86_xArgXmm2M128),
-	/*7589*/ uint16(x86_xMatch),
-	/*7590*/ uint16(x86_xSetOp), uint16(x86_CVTPD2DQ),
-	/*7592*/ uint16(x86_xReadSlashR),
-	/*7593*/ uint16(x86_xArgXmm1),
-	/*7594*/ uint16(x86_xArgXmm2M128),
-	/*7595*/ uint16(x86_xMatch),
-	/*7596*/ uint16(x86_xSetOp), uint16(x86_CVTDQ2PD),
-	/*7598*/ uint16(x86_xReadSlashR),
-	/*7599*/ uint16(x86_xArgXmm1),
-	/*7600*/ uint16(x86_xArgXmm2M64),
-	/*7601*/ uint16(x86_xMatch),
-	/*7602*/ uint16(x86_xCondPrefix), 2,
-	0x66, 7614,
-	0x0, 7608,
-	/*7608*/ uint16(x86_xSetOp), uint16(x86_MOVNTQ),
-	/*7610*/ uint16(x86_xReadSlashR),
-	/*7611*/ uint16(x86_xArgM64),
-	/*7612*/ uint16(x86_xArgMm),
-	/*7613*/ uint16(x86_xMatch),
-	/*7614*/ uint16(x86_xSetOp), uint16(x86_MOVNTDQ),
-	/*7616*/ uint16(x86_xReadSlashR),
-	/*7617*/ uint16(x86_xArgM128),
-	/*7618*/ uint16(x86_xArgXmm),
-	/*7619*/ uint16(x86_xMatch),
-	/*7620*/ uint16(x86_xCondPrefix), 2,
-	0x66, 7632,
-	0x0, 7626,
-	/*7626*/ uint16(x86_xSetOp), uint16(x86_PSUBSB),
-	/*7628*/ uint16(x86_xReadSlashR),
-	/*7629*/ uint16(x86_xArgMm),
-	/*7630*/ uint16(x86_xArgMmM64),
-	/*7631*/ uint16(x86_xMatch),
-	/*7632*/ uint16(x86_xSetOp), uint16(x86_PSUBSB),
-	/*7634*/ uint16(x86_xReadSlashR),
-	/*7635*/ uint16(x86_xArgXmm1),
-	/*7636*/ uint16(x86_xArgXmm2M128),
-	/*7637*/ uint16(x86_xMatch),
-	/*7638*/ uint16(x86_xCondPrefix), 2,
-	0x66, 7650,
-	0x0, 7644,
-	/*7644*/ uint16(x86_xSetOp), uint16(x86_PSUBSW),
-	/*7646*/ uint16(x86_xReadSlashR),
-	/*7647*/ uint16(x86_xArgMm),
-	/*7648*/ uint16(x86_xArgMmM64),
-	/*7649*/ uint16(x86_xMatch),
-	/*7650*/ uint16(x86_xSetOp), uint16(x86_PSUBSW),
-	/*7652*/ uint16(x86_xReadSlashR),
-	/*7653*/ uint16(x86_xArgXmm1),
-	/*7654*/ uint16(x86_xArgXmm2M128),
-	/*7655*/ uint16(x86_xMatch),
-	/*7656*/ uint16(x86_xCondPrefix), 2,
-	0x66, 7668,
-	0x0, 7662,
-	/*7662*/ uint16(x86_xSetOp), uint16(x86_PMINSW),
-	/*7664*/ uint16(x86_xReadSlashR),
-	/*7665*/ uint16(x86_xArgMm1),
-	/*7666*/ uint16(x86_xArgMm2M64),
-	/*7667*/ uint16(x86_xMatch),
-	/*7668*/ uint16(x86_xSetOp), uint16(x86_PMINSW),
-	/*7670*/ uint16(x86_xReadSlashR),
-	/*7671*/ uint16(x86_xArgXmm1),
-	/*7672*/ uint16(x86_xArgXmm2M128),
-	/*7673*/ uint16(x86_xMatch),
-	/*7674*/ uint16(x86_xCondPrefix), 2,
-	0x66, 7686,
-	0x0, 7680,
-	/*7680*/ uint16(x86_xSetOp), uint16(x86_POR),
-	/*7682*/ uint16(x86_xReadSlashR),
-	/*7683*/ uint16(x86_xArgMm),
-	/*7684*/ uint16(x86_xArgMmM64),
-	/*7685*/ uint16(x86_xMatch),
-	/*7686*/ uint16(x86_xSetOp), uint16(x86_POR),
-	/*7688*/ uint16(x86_xReadSlashR),
-	/*7689*/ uint16(x86_xArgXmm1),
-	/*7690*/ uint16(x86_xArgXmm2M128),
-	/*7691*/ uint16(x86_xMatch),
-	/*7692*/ uint16(x86_xCondPrefix), 2,
-	0x66, 7704,
-	0x0, 7698,
-	/*7698*/ uint16(x86_xSetOp), uint16(x86_PADDSB),
-	/*7700*/ uint16(x86_xReadSlashR),
-	/*7701*/ uint16(x86_xArgMm),
-	/*7702*/ uint16(x86_xArgMmM64),
-	/*7703*/ uint16(x86_xMatch),
-	/*7704*/ uint16(x86_xSetOp), uint16(x86_PADDSB),
-	/*7706*/ uint16(x86_xReadSlashR),
-	/*7707*/ uint16(x86_xArgXmm1),
-	/*7708*/ uint16(x86_xArgXmm2M128),
-	/*7709*/ uint16(x86_xMatch),
-	/*7710*/ uint16(x86_xCondPrefix), 2,
-	0x66, 7722,
-	0x0, 7716,
-	/*7716*/ uint16(x86_xSetOp), uint16(x86_PADDSW),
-	/*7718*/ uint16(x86_xReadSlashR),
-	/*7719*/ uint16(x86_xArgMm),
-	/*7720*/ uint16(x86_xArgMmM64),
-	/*7721*/ uint16(x86_xMatch),
-	/*7722*/ uint16(x86_xSetOp), uint16(x86_PADDSW),
-	/*7724*/ uint16(x86_xReadSlashR),
-	/*7725*/ uint16(x86_xArgXmm1),
-	/*7726*/ uint16(x86_xArgXmm2M128),
-	/*7727*/ uint16(x86_xMatch),
-	/*7728*/ uint16(x86_xCondPrefix), 2,
-	0x66, 7740,
-	0x0, 7734,
-	/*7734*/ uint16(x86_xSetOp), uint16(x86_PMAXSW),
-	/*7736*/ uint16(x86_xReadSlashR),
-	/*7737*/ uint16(x86_xArgMm1),
-	/*7738*/ uint16(x86_xArgMm2M64),
-	/*7739*/ uint16(x86_xMatch),
-	/*7740*/ uint16(x86_xSetOp), uint16(x86_PMAXSW),
-	/*7742*/ uint16(x86_xReadSlashR),
-	/*7743*/ uint16(x86_xArgXmm1),
-	/*7744*/ uint16(x86_xArgXmm2M128),
-	/*7745*/ uint16(x86_xMatch),
-	/*7746*/ uint16(x86_xCondPrefix), 2,
-	0x66, 7758,
-	0x0, 7752,
-	/*7752*/ uint16(x86_xSetOp), uint16(x86_PXOR),
-	/*7754*/ uint16(x86_xReadSlashR),
-	/*7755*/ uint16(x86_xArgMm),
-	/*7756*/ uint16(x86_xArgMmM64),
-	/*7757*/ uint16(x86_xMatch),
-	/*7758*/ uint16(x86_xSetOp), uint16(x86_PXOR),
-	/*7760*/ uint16(x86_xReadSlashR),
-	/*7761*/ uint16(x86_xArgXmm1),
-	/*7762*/ uint16(x86_xArgXmm2M128),
-	/*7763*/ uint16(x86_xMatch),
-	/*7764*/ uint16(x86_xCondPrefix), 1,
-	0xF2, 7768,
-	/*7768*/ uint16(x86_xSetOp), uint16(x86_LDDQU),
-	/*7770*/ uint16(x86_xReadSlashR),
-	/*7771*/ uint16(x86_xArgXmm1),
-	/*7772*/ uint16(x86_xArgM128),
-	/*7773*/ uint16(x86_xMatch),
-	/*7774*/ uint16(x86_xCondPrefix), 2,
-	0x66, 7786,
-	0x0, 7780,
-	/*7780*/ uint16(x86_xSetOp), uint16(x86_PSLLW),
-	/*7782*/ uint16(x86_xReadSlashR),
-	/*7783*/ uint16(x86_xArgMm),
-	/*7784*/ uint16(x86_xArgMmM64),
-	/*7785*/ uint16(x86_xMatch),
-	/*7786*/ uint16(x86_xSetOp), uint16(x86_PSLLW),
-	/*7788*/ uint16(x86_xReadSlashR),
-	/*7789*/ uint16(x86_xArgXmm1),
-	/*7790*/ uint16(x86_xArgXmm2M128),
-	/*7791*/ uint16(x86_xMatch),
-	/*7792*/ uint16(x86_xCondPrefix), 2,
-	0x66, 7804,
-	0x0, 7798,
-	/*7798*/ uint16(x86_xSetOp), uint16(x86_PSLLD),
-	/*7800*/ uint16(x86_xReadSlashR),
-	/*7801*/ uint16(x86_xArgMm),
-	/*7802*/ uint16(x86_xArgMmM64),
-	/*7803*/ uint16(x86_xMatch),
-	/*7804*/ uint16(x86_xSetOp), uint16(x86_PSLLD),
-	/*7806*/ uint16(x86_xReadSlashR),
-	/*7807*/ uint16(x86_xArgXmm1),
-	/*7808*/ uint16(x86_xArgXmm2M128),
-	/*7809*/ uint16(x86_xMatch),
-	/*7810*/ uint16(x86_xCondPrefix), 2,
-	0x66, 7822,
-	0x0, 7816,
-	/*7816*/ uint16(x86_xSetOp), uint16(x86_PSLLQ),
-	/*7818*/ uint16(x86_xReadSlashR),
-	/*7819*/ uint16(x86_xArgMm),
-	/*7820*/ uint16(x86_xArgMmM64),
-	/*7821*/ uint16(x86_xMatch),
-	/*7822*/ uint16(x86_xSetOp), uint16(x86_PSLLQ),
-	/*7824*/ uint16(x86_xReadSlashR),
-	/*7825*/ uint16(x86_xArgXmm1),
-	/*7826*/ uint16(x86_xArgXmm2M128),
-	/*7827*/ uint16(x86_xMatch),
-	/*7828*/ uint16(x86_xCondPrefix), 2,
-	0x66, 7840,
-	0x0, 7834,
-	/*7834*/ uint16(x86_xSetOp), uint16(x86_PMULUDQ),
-	/*7836*/ uint16(x86_xReadSlashR),
-	/*7837*/ uint16(x86_xArgMm1),
-	/*7838*/ uint16(x86_xArgMm2M64),
-	/*7839*/ uint16(x86_xMatch),
-	/*7840*/ uint16(x86_xSetOp), uint16(x86_PMULUDQ),
-	/*7842*/ uint16(x86_xReadSlashR),
-	/*7843*/ uint16(x86_xArgXmm1),
-	/*7844*/ uint16(x86_xArgXmm2M128),
-	/*7845*/ uint16(x86_xMatch),
-	/*7846*/ uint16(x86_xCondPrefix), 2,
-	0x66, 7858,
-	0x0, 7852,
-	/*7852*/ uint16(x86_xSetOp), uint16(x86_PMADDWD),
-	/*7854*/ uint16(x86_xReadSlashR),
-	/*7855*/ uint16(x86_xArgMm),
-	/*7856*/ uint16(x86_xArgMmM64),
-	/*7857*/ uint16(x86_xMatch),
-	/*7858*/ uint16(x86_xSetOp), uint16(x86_PMADDWD),
-	/*7860*/ uint16(x86_xReadSlashR),
-	/*7861*/ uint16(x86_xArgXmm1),
-	/*7862*/ uint16(x86_xArgXmm2M128),
-	/*7863*/ uint16(x86_xMatch),
-	/*7864*/ uint16(x86_xCondPrefix), 2,
-	0x66, 7876,
-	0x0, 7870,
-	/*7870*/ uint16(x86_xSetOp), uint16(x86_PSADBW),
-	/*7872*/ uint16(x86_xReadSlashR),
-	/*7873*/ uint16(x86_xArgMm1),
-	/*7874*/ uint16(x86_xArgMm2M64),
-	/*7875*/ uint16(x86_xMatch),
-	/*7876*/ uint16(x86_xSetOp), uint16(x86_PSADBW),
-	/*7878*/ uint16(x86_xReadSlashR),
-	/*7879*/ uint16(x86_xArgXmm1),
-	/*7880*/ uint16(x86_xArgXmm2M128),
-	/*7881*/ uint16(x86_xMatch),
-	/*7882*/ uint16(x86_xCondPrefix), 2,
-	0x66, 7894,
-	0x0, 7888,
-	/*7888*/ uint16(x86_xSetOp), uint16(x86_MASKMOVQ),
-	/*7890*/ uint16(x86_xReadSlashR),
-	/*7891*/ uint16(x86_xArgMm1),
-	/*7892*/ uint16(x86_xArgMm2),
-	/*7893*/ uint16(x86_xMatch),
-	/*7894*/ uint16(x86_xSetOp), uint16(x86_MASKMOVDQU),
-	/*7896*/ uint16(x86_xReadSlashR),
-	/*7897*/ uint16(x86_xArgXmm1),
-	/*7898*/ uint16(x86_xArgXmm2),
-	/*7899*/ uint16(x86_xMatch),
-	/*7900*/ uint16(x86_xCondPrefix), 2,
-	0x66, 7912,
-	0x0, 7906,
-	/*7906*/ uint16(x86_xSetOp), uint16(x86_PSUBB),
-	/*7908*/ uint16(x86_xReadSlashR),
-	/*7909*/ uint16(x86_xArgMm),
-	/*7910*/ uint16(x86_xArgMmM64),
-	/*7911*/ uint16(x86_xMatch),
-	/*7912*/ uint16(x86_xSetOp), uint16(x86_PSUBB),
-	/*7914*/ uint16(x86_xReadSlashR),
-	/*7915*/ uint16(x86_xArgXmm1),
-	/*7916*/ uint16(x86_xArgXmm2M128),
-	/*7917*/ uint16(x86_xMatch),
-	/*7918*/ uint16(x86_xCondPrefix), 2,
-	0x66, 7930,
-	0x0, 7924,
-	/*7924*/ uint16(x86_xSetOp), uint16(x86_PSUBW),
-	/*7926*/ uint16(x86_xReadSlashR),
-	/*7927*/ uint16(x86_xArgMm),
-	/*7928*/ uint16(x86_xArgMmM64),
-	/*7929*/ uint16(x86_xMatch),
-	/*7930*/ uint16(x86_xSetOp), uint16(x86_PSUBW),
-	/*7932*/ uint16(x86_xReadSlashR),
-	/*7933*/ uint16(x86_xArgXmm1),
-	/*7934*/ uint16(x86_xArgXmm2M128),
-	/*7935*/ uint16(x86_xMatch),
-	/*7936*/ uint16(x86_xCondPrefix), 2,
-	0x66, 7948,
-	0x0, 7942,
-	/*7942*/ uint16(x86_xSetOp), uint16(x86_PSUBD),
-	/*7944*/ uint16(x86_xReadSlashR),
-	/*7945*/ uint16(x86_xArgMm),
-	/*7946*/ uint16(x86_xArgMmM64),
-	/*7947*/ uint16(x86_xMatch),
-	/*7948*/ uint16(x86_xSetOp), uint16(x86_PSUBD),
-	/*7950*/ uint16(x86_xReadSlashR),
-	/*7951*/ uint16(x86_xArgXmm1),
-	/*7952*/ uint16(x86_xArgXmm2M128),
-	/*7953*/ uint16(x86_xMatch),
-	/*7954*/ uint16(x86_xCondPrefix), 2,
-	0x66, 7966,
-	0x0, 7960,
-	/*7960*/ uint16(x86_xSetOp), uint16(x86_PSUBQ),
-	/*7962*/ uint16(x86_xReadSlashR),
-	/*7963*/ uint16(x86_xArgMm1),
-	/*7964*/ uint16(x86_xArgMm2M64),
-	/*7965*/ uint16(x86_xMatch),
-	/*7966*/ uint16(x86_xSetOp), uint16(x86_PSUBQ),
-	/*7968*/ uint16(x86_xReadSlashR),
-	/*7969*/ uint16(x86_xArgXmm1),
-	/*7970*/ uint16(x86_xArgXmm2M128),
-	/*7971*/ uint16(x86_xMatch),
-	/*7972*/ uint16(x86_xCondPrefix), 2,
-	0x66, 7984,
-	0x0, 7978,
-	/*7978*/ uint16(x86_xSetOp), uint16(x86_PADDB),
-	/*7980*/ uint16(x86_xReadSlashR),
-	/*7981*/ uint16(x86_xArgMm),
-	/*7982*/ uint16(x86_xArgMmM64),
-	/*7983*/ uint16(x86_xMatch),
-	/*7984*/ uint16(x86_xSetOp), uint16(x86_PADDB),
-	/*7986*/ uint16(x86_xReadSlashR),
-	/*7987*/ uint16(x86_xArgXmm1),
-	/*7988*/ uint16(x86_xArgXmm2M128),
-	/*7989*/ uint16(x86_xMatch),
-	/*7990*/ uint16(x86_xCondPrefix), 2,
-	0x66, 8002,
-	0x0, 7996,
-	/*7996*/ uint16(x86_xSetOp), uint16(x86_PADDW),
-	/*7998*/ uint16(x86_xReadSlashR),
-	/*7999*/ uint16(x86_xArgMm),
-	/*8000*/ uint16(x86_xArgMmM64),
-	/*8001*/ uint16(x86_xMatch),
-	/*8002*/ uint16(x86_xSetOp), uint16(x86_PADDW),
-	/*8004*/ uint16(x86_xReadSlashR),
-	/*8005*/ uint16(x86_xArgXmm1),
-	/*8006*/ uint16(x86_xArgXmm2M128),
-	/*8007*/ uint16(x86_xMatch),
-	/*8008*/ uint16(x86_xCondPrefix), 2,
-	0x66, 8020,
-	0x0, 8014,
-	/*8014*/ uint16(x86_xSetOp), uint16(x86_PADDD),
-	/*8016*/ uint16(x86_xReadSlashR),
-	/*8017*/ uint16(x86_xArgMm),
-	/*8018*/ uint16(x86_xArgMmM64),
-	/*8019*/ uint16(x86_xMatch),
-	/*8020*/ uint16(x86_xSetOp), uint16(x86_PADDD),
-	/*8022*/ uint16(x86_xReadSlashR),
-	/*8023*/ uint16(x86_xArgXmm1),
-	/*8024*/ uint16(x86_xArgXmm2M128),
-	/*8025*/ uint16(x86_xMatch),
-	/*8026*/ uint16(x86_xSetOp), uint16(x86_ADC),
-	/*8028*/ uint16(x86_xReadSlashR),
-	/*8029*/ uint16(x86_xArgRM8),
-	/*8030*/ uint16(x86_xArgR8),
-	/*8031*/ uint16(x86_xMatch),
-	/*8032*/ uint16(x86_xCondIs64), 8035, 8051,
-	/*8035*/ uint16(x86_xCondDataSize), 8039, 8045, 0,
-	/*8039*/ uint16(x86_xSetOp), uint16(x86_ADC),
-	/*8041*/ uint16(x86_xReadSlashR),
-	/*8042*/ uint16(x86_xArgRM16),
-	/*8043*/ uint16(x86_xArgR16),
-	/*8044*/ uint16(x86_xMatch),
-	/*8045*/ uint16(x86_xSetOp), uint16(x86_ADC),
-	/*8047*/ uint16(x86_xReadSlashR),
-	/*8048*/ uint16(x86_xArgRM32),
-	/*8049*/ uint16(x86_xArgR32),
-	/*8050*/ uint16(x86_xMatch),
-	/*8051*/ uint16(x86_xCondDataSize), 8039, 8045, 8055,
-	/*8055*/ uint16(x86_xSetOp), uint16(x86_ADC),
-	/*8057*/ uint16(x86_xReadSlashR),
-	/*8058*/ uint16(x86_xArgRM64),
-	/*8059*/ uint16(x86_xArgR64),
-	/*8060*/ uint16(x86_xMatch),
-	/*8061*/ uint16(x86_xSetOp), uint16(x86_ADC),
-	/*8063*/ uint16(x86_xReadSlashR),
-	/*8064*/ uint16(x86_xArgR8),
-	/*8065*/ uint16(x86_xArgRM8),
-	/*8066*/ uint16(x86_xMatch),
-	/*8067*/ uint16(x86_xCondIs64), 8070, 8086,
-	/*8070*/ uint16(x86_xCondDataSize), 8074, 8080, 0,
-	/*8074*/ uint16(x86_xSetOp), uint16(x86_ADC),
-	/*8076*/ uint16(x86_xReadSlashR),
-	/*8077*/ uint16(x86_xArgR16),
-	/*8078*/ uint16(x86_xArgRM16),
-	/*8079*/ uint16(x86_xMatch),
-	/*8080*/ uint16(x86_xSetOp), uint16(x86_ADC),
-	/*8082*/ uint16(x86_xReadSlashR),
-	/*8083*/ uint16(x86_xArgR32),
-	/*8084*/ uint16(x86_xArgRM32),
-	/*8085*/ uint16(x86_xMatch),
-	/*8086*/ uint16(x86_xCondDataSize), 8074, 8080, 8090,
-	/*8090*/ uint16(x86_xSetOp), uint16(x86_ADC),
-	/*8092*/ uint16(x86_xReadSlashR),
-	/*8093*/ uint16(x86_xArgR64),
-	/*8094*/ uint16(x86_xArgRM64),
-	/*8095*/ uint16(x86_xMatch),
-	/*8096*/ uint16(x86_xSetOp), uint16(x86_ADC),
-	/*8098*/ uint16(x86_xReadIb),
-	/*8099*/ uint16(x86_xArgAL),
-	/*8100*/ uint16(x86_xArgImm8u),
-	/*8101*/ uint16(x86_xMatch),
-	/*8102*/ uint16(x86_xCondIs64), 8105, 8121,
-	/*8105*/ uint16(x86_xCondDataSize), 8109, 8115, 0,
-	/*8109*/ uint16(x86_xSetOp), uint16(x86_ADC),
-	/*8111*/ uint16(x86_xReadIw),
-	/*8112*/ uint16(x86_xArgAX),
-	/*8113*/ uint16(x86_xArgImm16),
-	/*8114*/ uint16(x86_xMatch),
-	/*8115*/ uint16(x86_xSetOp), uint16(x86_ADC),
-	/*8117*/ uint16(x86_xReadId),
-	/*8118*/ uint16(x86_xArgEAX),
-	/*8119*/ uint16(x86_xArgImm32),
-	/*8120*/ uint16(x86_xMatch),
-	/*8121*/ uint16(x86_xCondDataSize), 8109, 8115, 8125,
-	/*8125*/ uint16(x86_xSetOp), uint16(x86_ADC),
-	/*8127*/ uint16(x86_xReadId),
-	/*8128*/ uint16(x86_xArgRAX),
-	/*8129*/ uint16(x86_xArgImm32),
-	/*8130*/ uint16(x86_xMatch),
-	/*8131*/ uint16(x86_xCondIs64), 8134, 0,
-	/*8134*/ uint16(x86_xSetOp), uint16(x86_PUSH),
-	/*8136*/ uint16(x86_xArgSS),
-	/*8137*/ uint16(x86_xMatch),
-	/*8138*/ uint16(x86_xCondIs64), 8141, 0,
-	/*8141*/ uint16(x86_xSetOp), uint16(x86_POP),
-	/*8143*/ uint16(x86_xArgSS),
-	/*8144*/ uint16(x86_xMatch),
-	/*8145*/ uint16(x86_xSetOp), uint16(x86_SBB),
-	/*8147*/ uint16(x86_xReadSlashR),
-	/*8148*/ uint16(x86_xArgRM8),
-	/*8149*/ uint16(x86_xArgR8),
-	/*8150*/ uint16(x86_xMatch),
-	/*8151*/ uint16(x86_xCondIs64), 8154, 8170,
-	/*8154*/ uint16(x86_xCondDataSize), 8158, 8164, 0,
-	/*8158*/ uint16(x86_xSetOp), uint16(x86_SBB),
-	/*8160*/ uint16(x86_xReadSlashR),
-	/*8161*/ uint16(x86_xArgRM16),
-	/*8162*/ uint16(x86_xArgR16),
-	/*8163*/ uint16(x86_xMatch),
-	/*8164*/ uint16(x86_xSetOp), uint16(x86_SBB),
-	/*8166*/ uint16(x86_xReadSlashR),
-	/*8167*/ uint16(x86_xArgRM32),
-	/*8168*/ uint16(x86_xArgR32),
-	/*8169*/ uint16(x86_xMatch),
-	/*8170*/ uint16(x86_xCondDataSize), 8158, 8164, 8174,
-	/*8174*/ uint16(x86_xSetOp), uint16(x86_SBB),
-	/*8176*/ uint16(x86_xReadSlashR),
-	/*8177*/ uint16(x86_xArgRM64),
-	/*8178*/ uint16(x86_xArgR64),
-	/*8179*/ uint16(x86_xMatch),
-	/*8180*/ uint16(x86_xSetOp), uint16(x86_SBB),
-	/*8182*/ uint16(x86_xReadSlashR),
-	/*8183*/ uint16(x86_xArgR8),
-	/*8184*/ uint16(x86_xArgRM8),
-	/*8185*/ uint16(x86_xMatch),
-	/*8186*/ uint16(x86_xCondIs64), 8189, 8205,
-	/*8189*/ uint16(x86_xCondDataSize), 8193, 8199, 0,
-	/*8193*/ uint16(x86_xSetOp), uint16(x86_SBB),
-	/*8195*/ uint16(x86_xReadSlashR),
-	/*8196*/ uint16(x86_xArgR16),
-	/*8197*/ uint16(x86_xArgRM16),
-	/*8198*/ uint16(x86_xMatch),
-	/*8199*/ uint16(x86_xSetOp), uint16(x86_SBB),
-	/*8201*/ uint16(x86_xReadSlashR),
-	/*8202*/ uint16(x86_xArgR32),
-	/*8203*/ uint16(x86_xArgRM32),
-	/*8204*/ uint16(x86_xMatch),
-	/*8205*/ uint16(x86_xCondDataSize), 8193, 8199, 8209,
-	/*8209*/ uint16(x86_xSetOp), uint16(x86_SBB),
-	/*8211*/ uint16(x86_xReadSlashR),
-	/*8212*/ uint16(x86_xArgR64),
-	/*8213*/ uint16(x86_xArgRM64),
-	/*8214*/ uint16(x86_xMatch),
-	/*8215*/ uint16(x86_xSetOp), uint16(x86_SBB),
-	/*8217*/ uint16(x86_xReadIb),
-	/*8218*/ uint16(x86_xArgAL),
-	/*8219*/ uint16(x86_xArgImm8u),
-	/*8220*/ uint16(x86_xMatch),
-	/*8221*/ uint16(x86_xCondIs64), 8224, 8240,
-	/*8224*/ uint16(x86_xCondDataSize), 8228, 8234, 0,
-	/*8228*/ uint16(x86_xSetOp), uint16(x86_SBB),
-	/*8230*/ uint16(x86_xReadIw),
-	/*8231*/ uint16(x86_xArgAX),
-	/*8232*/ uint16(x86_xArgImm16),
-	/*8233*/ uint16(x86_xMatch),
-	/*8234*/ uint16(x86_xSetOp), uint16(x86_SBB),
-	/*8236*/ uint16(x86_xReadId),
-	/*8237*/ uint16(x86_xArgEAX),
-	/*8238*/ uint16(x86_xArgImm32),
-	/*8239*/ uint16(x86_xMatch),
-	/*8240*/ uint16(x86_xCondDataSize), 8228, 8234, 8244,
-	/*8244*/ uint16(x86_xSetOp), uint16(x86_SBB),
-	/*8246*/ uint16(x86_xReadId),
-	/*8247*/ uint16(x86_xArgRAX),
-	/*8248*/ uint16(x86_xArgImm32),
-	/*8249*/ uint16(x86_xMatch),
-	/*8250*/ uint16(x86_xCondIs64), 8253, 0,
-	/*8253*/ uint16(x86_xSetOp), uint16(x86_PUSH),
-	/*8255*/ uint16(x86_xArgDS),
-	/*8256*/ uint16(x86_xMatch),
-	/*8257*/ uint16(x86_xCondIs64), 8260, 0,
-	/*8260*/ uint16(x86_xSetOp), uint16(x86_POP),
-	/*8262*/ uint16(x86_xArgDS),
-	/*8263*/ uint16(x86_xMatch),
-	/*8264*/ uint16(x86_xSetOp), uint16(x86_AND),
-	/*8266*/ uint16(x86_xReadSlashR),
-	/*8267*/ uint16(x86_xArgRM8),
-	/*8268*/ uint16(x86_xArgR8),
-	/*8269*/ uint16(x86_xMatch),
-	/*8270*/ uint16(x86_xCondIs64), 8273, 8289,
-	/*8273*/ uint16(x86_xCondDataSize), 8277, 8283, 0,
-	/*8277*/ uint16(x86_xSetOp), uint16(x86_AND),
-	/*8279*/ uint16(x86_xReadSlashR),
-	/*8280*/ uint16(x86_xArgRM16),
-	/*8281*/ uint16(x86_xArgR16),
-	/*8282*/ uint16(x86_xMatch),
-	/*8283*/ uint16(x86_xSetOp), uint16(x86_AND),
-	/*8285*/ uint16(x86_xReadSlashR),
-	/*8286*/ uint16(x86_xArgRM32),
-	/*8287*/ uint16(x86_xArgR32),
-	/*8288*/ uint16(x86_xMatch),
-	/*8289*/ uint16(x86_xCondDataSize), 8277, 8283, 8293,
-	/*8293*/ uint16(x86_xSetOp), uint16(x86_AND),
-	/*8295*/ uint16(x86_xReadSlashR),
-	/*8296*/ uint16(x86_xArgRM64),
-	/*8297*/ uint16(x86_xArgR64),
-	/*8298*/ uint16(x86_xMatch),
-	/*8299*/ uint16(x86_xSetOp), uint16(x86_AND),
-	/*8301*/ uint16(x86_xReadSlashR),
-	/*8302*/ uint16(x86_xArgR8),
-	/*8303*/ uint16(x86_xArgRM8),
-	/*8304*/ uint16(x86_xMatch),
-	/*8305*/ uint16(x86_xCondIs64), 8308, 8324,
-	/*8308*/ uint16(x86_xCondDataSize), 8312, 8318, 0,
-	/*8312*/ uint16(x86_xSetOp), uint16(x86_AND),
-	/*8314*/ uint16(x86_xReadSlashR),
-	/*8315*/ uint16(x86_xArgR16),
-	/*8316*/ uint16(x86_xArgRM16),
-	/*8317*/ uint16(x86_xMatch),
-	/*8318*/ uint16(x86_xSetOp), uint16(x86_AND),
-	/*8320*/ uint16(x86_xReadSlashR),
-	/*8321*/ uint16(x86_xArgR32),
-	/*8322*/ uint16(x86_xArgRM32),
-	/*8323*/ uint16(x86_xMatch),
-	/*8324*/ uint16(x86_xCondDataSize), 8312, 8318, 8328,
-	/*8328*/ uint16(x86_xSetOp), uint16(x86_AND),
-	/*8330*/ uint16(x86_xReadSlashR),
-	/*8331*/ uint16(x86_xArgR64),
-	/*8332*/ uint16(x86_xArgRM64),
-	/*8333*/ uint16(x86_xMatch),
-	/*8334*/ uint16(x86_xSetOp), uint16(x86_AND),
-	/*8336*/ uint16(x86_xReadIb),
-	/*8337*/ uint16(x86_xArgAL),
-	/*8338*/ uint16(x86_xArgImm8u),
-	/*8339*/ uint16(x86_xMatch),
-	/*8340*/ uint16(x86_xCondIs64), 8343, 8359,
-	/*8343*/ uint16(x86_xCondDataSize), 8347, 8353, 0,
-	/*8347*/ uint16(x86_xSetOp), uint16(x86_AND),
-	/*8349*/ uint16(x86_xReadIw),
-	/*8350*/ uint16(x86_xArgAX),
-	/*8351*/ uint16(x86_xArgImm16),
-	/*8352*/ uint16(x86_xMatch),
-	/*8353*/ uint16(x86_xSetOp), uint16(x86_AND),
-	/*8355*/ uint16(x86_xReadId),
-	/*8356*/ uint16(x86_xArgEAX),
-	/*8357*/ uint16(x86_xArgImm32),
-	/*8358*/ uint16(x86_xMatch),
-	/*8359*/ uint16(x86_xCondDataSize), 8347, 8353, 8363,
-	/*8363*/ uint16(x86_xSetOp), uint16(x86_AND),
-	/*8365*/ uint16(x86_xReadId),
-	/*8366*/ uint16(x86_xArgRAX),
-	/*8367*/ uint16(x86_xArgImm32),
-	/*8368*/ uint16(x86_xMatch),
-	/*8369*/ uint16(x86_xCondIs64), 8372, 0,
-	/*8372*/ uint16(x86_xSetOp), uint16(x86_DAA),
-	/*8374*/ uint16(x86_xMatch),
-	/*8375*/ uint16(x86_xSetOp), uint16(x86_SUB),
-	/*8377*/ uint16(x86_xReadSlashR),
-	/*8378*/ uint16(x86_xArgRM8),
-	/*8379*/ uint16(x86_xArgR8),
-	/*8380*/ uint16(x86_xMatch),
-	/*8381*/ uint16(x86_xCondIs64), 8384, 8400,
-	/*8384*/ uint16(x86_xCondDataSize), 8388, 8394, 0,
-	/*8388*/ uint16(x86_xSetOp), uint16(x86_SUB),
-	/*8390*/ uint16(x86_xReadSlashR),
-	/*8391*/ uint16(x86_xArgRM16),
-	/*8392*/ uint16(x86_xArgR16),
-	/*8393*/ uint16(x86_xMatch),
-	/*8394*/ uint16(x86_xSetOp), uint16(x86_SUB),
-	/*8396*/ uint16(x86_xReadSlashR),
-	/*8397*/ uint16(x86_xArgRM32),
-	/*8398*/ uint16(x86_xArgR32),
-	/*8399*/ uint16(x86_xMatch),
-	/*8400*/ uint16(x86_xCondDataSize), 8388, 8394, 8404,
-	/*8404*/ uint16(x86_xSetOp), uint16(x86_SUB),
-	/*8406*/ uint16(x86_xReadSlashR),
-	/*8407*/ uint16(x86_xArgRM64),
-	/*8408*/ uint16(x86_xArgR64),
-	/*8409*/ uint16(x86_xMatch),
-	/*8410*/ uint16(x86_xSetOp), uint16(x86_SUB),
-	/*8412*/ uint16(x86_xReadSlashR),
-	/*8413*/ uint16(x86_xArgR8),
-	/*8414*/ uint16(x86_xArgRM8),
-	/*8415*/ uint16(x86_xMatch),
-	/*8416*/ uint16(x86_xCondIs64), 8419, 8435,
-	/*8419*/ uint16(x86_xCondDataSize), 8423, 8429, 0,
-	/*8423*/ uint16(x86_xSetOp), uint16(x86_SUB),
-	/*8425*/ uint16(x86_xReadSlashR),
-	/*8426*/ uint16(x86_xArgR16),
-	/*8427*/ uint16(x86_xArgRM16),
-	/*8428*/ uint16(x86_xMatch),
-	/*8429*/ uint16(x86_xSetOp), uint16(x86_SUB),
-	/*8431*/ uint16(x86_xReadSlashR),
-	/*8432*/ uint16(x86_xArgR32),
-	/*8433*/ uint16(x86_xArgRM32),
-	/*8434*/ uint16(x86_xMatch),
-	/*8435*/ uint16(x86_xCondDataSize), 8423, 8429, 8439,
-	/*8439*/ uint16(x86_xSetOp), uint16(x86_SUB),
-	/*8441*/ uint16(x86_xReadSlashR),
-	/*8442*/ uint16(x86_xArgR64),
-	/*8443*/ uint16(x86_xArgRM64),
-	/*8444*/ uint16(x86_xMatch),
-	/*8445*/ uint16(x86_xSetOp), uint16(x86_SUB),
-	/*8447*/ uint16(x86_xReadIb),
-	/*8448*/ uint16(x86_xArgAL),
-	/*8449*/ uint16(x86_xArgImm8u),
-	/*8450*/ uint16(x86_xMatch),
-	/*8451*/ uint16(x86_xCondIs64), 8454, 8470,
-	/*8454*/ uint16(x86_xCondDataSize), 8458, 8464, 0,
-	/*8458*/ uint16(x86_xSetOp), uint16(x86_SUB),
-	/*8460*/ uint16(x86_xReadIw),
-	/*8461*/ uint16(x86_xArgAX),
-	/*8462*/ uint16(x86_xArgImm16),
-	/*8463*/ uint16(x86_xMatch),
-	/*8464*/ uint16(x86_xSetOp), uint16(x86_SUB),
-	/*8466*/ uint16(x86_xReadId),
-	/*8467*/ uint16(x86_xArgEAX),
-	/*8468*/ uint16(x86_xArgImm32),
-	/*8469*/ uint16(x86_xMatch),
-	/*8470*/ uint16(x86_xCondDataSize), 8458, 8464, 8474,
-	/*8474*/ uint16(x86_xSetOp), uint16(x86_SUB),
-	/*8476*/ uint16(x86_xReadId),
-	/*8477*/ uint16(x86_xArgRAX),
-	/*8478*/ uint16(x86_xArgImm32),
-	/*8479*/ uint16(x86_xMatch),
-	/*8480*/ uint16(x86_xCondIs64), 8483, 0,
-	/*8483*/ uint16(x86_xSetOp), uint16(x86_DAS),
-	/*8485*/ uint16(x86_xMatch),
-	/*8486*/ uint16(x86_xSetOp), uint16(x86_XOR),
-	/*8488*/ uint16(x86_xReadSlashR),
-	/*8489*/ uint16(x86_xArgRM8),
-	/*8490*/ uint16(x86_xArgR8),
-	/*8491*/ uint16(x86_xMatch),
-	/*8492*/ uint16(x86_xCondIs64), 8495, 8511,
-	/*8495*/ uint16(x86_xCondDataSize), 8499, 8505, 0,
-	/*8499*/ uint16(x86_xSetOp), uint16(x86_XOR),
-	/*8501*/ uint16(x86_xReadSlashR),
-	/*8502*/ uint16(x86_xArgRM16),
-	/*8503*/ uint16(x86_xArgR16),
-	/*8504*/ uint16(x86_xMatch),
-	/*8505*/ uint16(x86_xSetOp), uint16(x86_XOR),
-	/*8507*/ uint16(x86_xReadSlashR),
-	/*8508*/ uint16(x86_xArgRM32),
-	/*8509*/ uint16(x86_xArgR32),
-	/*8510*/ uint16(x86_xMatch),
-	/*8511*/ uint16(x86_xCondDataSize), 8499, 8505, 8515,
-	/*8515*/ uint16(x86_xSetOp), uint16(x86_XOR),
-	/*8517*/ uint16(x86_xReadSlashR),
-	/*8518*/ uint16(x86_xArgRM64),
-	/*8519*/ uint16(x86_xArgR64),
-	/*8520*/ uint16(x86_xMatch),
-	/*8521*/ uint16(x86_xSetOp), uint16(x86_XOR),
-	/*8523*/ uint16(x86_xReadSlashR),
-	/*8524*/ uint16(x86_xArgR8),
-	/*8525*/ uint16(x86_xArgRM8),
-	/*8526*/ uint16(x86_xMatch),
-	/*8527*/ uint16(x86_xCondIs64), 8530, 8546,
-	/*8530*/ uint16(x86_xCondDataSize), 8534, 8540, 0,
-	/*8534*/ uint16(x86_xSetOp), uint16(x86_XOR),
-	/*8536*/ uint16(x86_xReadSlashR),
-	/*8537*/ uint16(x86_xArgR16),
-	/*8538*/ uint16(x86_xArgRM16),
-	/*8539*/ uint16(x86_xMatch),
-	/*8540*/ uint16(x86_xSetOp), uint16(x86_XOR),
-	/*8542*/ uint16(x86_xReadSlashR),
-	/*8543*/ uint16(x86_xArgR32),
-	/*8544*/ uint16(x86_xArgRM32),
-	/*8545*/ uint16(x86_xMatch),
-	/*8546*/ uint16(x86_xCondDataSize), 8534, 8540, 8550,
-	/*8550*/ uint16(x86_xSetOp), uint16(x86_XOR),
-	/*8552*/ uint16(x86_xReadSlashR),
-	/*8553*/ uint16(x86_xArgR64),
-	/*8554*/ uint16(x86_xArgRM64),
-	/*8555*/ uint16(x86_xMatch),
-	/*8556*/ uint16(x86_xSetOp), uint16(x86_XOR),
-	/*8558*/ uint16(x86_xReadIb),
-	/*8559*/ uint16(x86_xArgAL),
-	/*8560*/ uint16(x86_xArgImm8u),
-	/*8561*/ uint16(x86_xMatch),
-	/*8562*/ uint16(x86_xCondIs64), 8565, 8581,
-	/*8565*/ uint16(x86_xCondDataSize), 8569, 8575, 0,
-	/*8569*/ uint16(x86_xSetOp), uint16(x86_XOR),
-	/*8571*/ uint16(x86_xReadIw),
-	/*8572*/ uint16(x86_xArgAX),
-	/*8573*/ uint16(x86_xArgImm16),
-	/*8574*/ uint16(x86_xMatch),
-	/*8575*/ uint16(x86_xSetOp), uint16(x86_XOR),
-	/*8577*/ uint16(x86_xReadId),
-	/*8578*/ uint16(x86_xArgEAX),
-	/*8579*/ uint16(x86_xArgImm32),
-	/*8580*/ uint16(x86_xMatch),
-	/*8581*/ uint16(x86_xCondDataSize), 8569, 8575, 8585,
-	/*8585*/ uint16(x86_xSetOp), uint16(x86_XOR),
-	/*8587*/ uint16(x86_xReadId),
-	/*8588*/ uint16(x86_xArgRAX),
-	/*8589*/ uint16(x86_xArgImm32),
-	/*8590*/ uint16(x86_xMatch),
-	/*8591*/ uint16(x86_xCondIs64), 8594, 0,
-	/*8594*/ uint16(x86_xSetOp), uint16(x86_AAA),
-	/*8596*/ uint16(x86_xMatch),
-	/*8597*/ uint16(x86_xSetOp), uint16(x86_CMP),
-	/*8599*/ uint16(x86_xReadSlashR),
-	/*8600*/ uint16(x86_xArgRM8),
-	/*8601*/ uint16(x86_xArgR8),
-	/*8602*/ uint16(x86_xMatch),
-	/*8603*/ uint16(x86_xCondIs64), 8606, 8622,
-	/*8606*/ uint16(x86_xCondDataSize), 8610, 8616, 0,
-	/*8610*/ uint16(x86_xSetOp), uint16(x86_CMP),
-	/*8612*/ uint16(x86_xReadSlashR),
-	/*8613*/ uint16(x86_xArgRM16),
-	/*8614*/ uint16(x86_xArgR16),
-	/*8615*/ uint16(x86_xMatch),
-	/*8616*/ uint16(x86_xSetOp), uint16(x86_CMP),
-	/*8618*/ uint16(x86_xReadSlashR),
-	/*8619*/ uint16(x86_xArgRM32),
-	/*8620*/ uint16(x86_xArgR32),
-	/*8621*/ uint16(x86_xMatch),
-	/*8622*/ uint16(x86_xCondDataSize), 8610, 8616, 8626,
-	/*8626*/ uint16(x86_xSetOp), uint16(x86_CMP),
-	/*8628*/ uint16(x86_xReadSlashR),
-	/*8629*/ uint16(x86_xArgRM64),
-	/*8630*/ uint16(x86_xArgR64),
-	/*8631*/ uint16(x86_xMatch),
-	/*8632*/ uint16(x86_xSetOp), uint16(x86_CMP),
-	/*8634*/ uint16(x86_xReadSlashR),
-	/*8635*/ uint16(x86_xArgR8),
-	/*8636*/ uint16(x86_xArgRM8),
-	/*8637*/ uint16(x86_xMatch),
-	/*8638*/ uint16(x86_xCondIs64), 8641, 8657,
-	/*8641*/ uint16(x86_xCondDataSize), 8645, 8651, 0,
-	/*8645*/ uint16(x86_xSetOp), uint16(x86_CMP),
-	/*8647*/ uint16(x86_xReadSlashR),
-	/*8648*/ uint16(x86_xArgR16),
-	/*8649*/ uint16(x86_xArgRM16),
-	/*8650*/ uint16(x86_xMatch),
-	/*8651*/ uint16(x86_xSetOp), uint16(x86_CMP),
-	/*8653*/ uint16(x86_xReadSlashR),
-	/*8654*/ uint16(x86_xArgR32),
-	/*8655*/ uint16(x86_xArgRM32),
-	/*8656*/ uint16(x86_xMatch),
-	/*8657*/ uint16(x86_xCondDataSize), 8645, 8651, 8661,
-	/*8661*/ uint16(x86_xSetOp), uint16(x86_CMP),
-	/*8663*/ uint16(x86_xReadSlashR),
-	/*8664*/ uint16(x86_xArgR64),
-	/*8665*/ uint16(x86_xArgRM64),
-	/*8666*/ uint16(x86_xMatch),
-	/*8667*/ uint16(x86_xSetOp), uint16(x86_CMP),
-	/*8669*/ uint16(x86_xReadIb),
-	/*8670*/ uint16(x86_xArgAL),
-	/*8671*/ uint16(x86_xArgImm8u),
-	/*8672*/ uint16(x86_xMatch),
-	/*8673*/ uint16(x86_xCondIs64), 8676, 8692,
-	/*8676*/ uint16(x86_xCondDataSize), 8680, 8686, 0,
-	/*8680*/ uint16(x86_xSetOp), uint16(x86_CMP),
-	/*8682*/ uint16(x86_xReadIw),
-	/*8683*/ uint16(x86_xArgAX),
-	/*8684*/ uint16(x86_xArgImm16),
-	/*8685*/ uint16(x86_xMatch),
-	/*8686*/ uint16(x86_xSetOp), uint16(x86_CMP),
-	/*8688*/ uint16(x86_xReadId),
-	/*8689*/ uint16(x86_xArgEAX),
-	/*8690*/ uint16(x86_xArgImm32),
-	/*8691*/ uint16(x86_xMatch),
-	/*8692*/ uint16(x86_xCondDataSize), 8680, 8686, 8696,
-	/*8696*/ uint16(x86_xSetOp), uint16(x86_CMP),
-	/*8698*/ uint16(x86_xReadId),
-	/*8699*/ uint16(x86_xArgRAX),
-	/*8700*/ uint16(x86_xArgImm32),
-	/*8701*/ uint16(x86_xMatch),
-	/*8702*/ uint16(x86_xCondIs64), 8705, 0,
-	/*8705*/ uint16(x86_xSetOp), uint16(x86_AAS),
-	/*8707*/ uint16(x86_xMatch),
-	/*8708*/ uint16(x86_xCondIs64), 8711, 0,
-	/*8711*/ uint16(x86_xCondDataSize), 8715, 8719, 0,
-	/*8715*/ uint16(x86_xSetOp), uint16(x86_INC),
-	/*8717*/ uint16(x86_xArgR16op),
-	/*8718*/ uint16(x86_xMatch),
-	/*8719*/ uint16(x86_xSetOp), uint16(x86_INC),
-	/*8721*/ uint16(x86_xArgR32op),
-	/*8722*/ uint16(x86_xMatch),
-	/*8723*/ uint16(x86_xCondIs64), 8726, 0,
-	/*8726*/ uint16(x86_xCondDataSize), 8730, 8734, 0,
-	/*8730*/ uint16(x86_xSetOp), uint16(x86_DEC),
-	/*8732*/ uint16(x86_xArgR16op),
-	/*8733*/ uint16(x86_xMatch),
-	/*8734*/ uint16(x86_xSetOp), uint16(x86_DEC),
-	/*8736*/ uint16(x86_xArgR32op),
-	/*8737*/ uint16(x86_xMatch),
-	/*8738*/ uint16(x86_xCondIs64), 8741, 8753,
-	/*8741*/ uint16(x86_xCondDataSize), 8745, 8749, 0,
-	/*8745*/ uint16(x86_xSetOp), uint16(x86_PUSH),
-	/*8747*/ uint16(x86_xArgR16op),
-	/*8748*/ uint16(x86_xMatch),
-	/*8749*/ uint16(x86_xSetOp), uint16(x86_PUSH),
-	/*8751*/ uint16(x86_xArgR32op),
-	/*8752*/ uint16(x86_xMatch),
-	/*8753*/ uint16(x86_xCondDataSize), 8745, 8757, 8761,
-	/*8757*/ uint16(x86_xSetOp), uint16(x86_PUSH),
-	/*8759*/ uint16(x86_xArgR64op),
-	/*8760*/ uint16(x86_xMatch),
-	/*8761*/ uint16(x86_xSetOp), uint16(x86_PUSH),
-	/*8763*/ uint16(x86_xArgR64op),
-	/*8764*/ uint16(x86_xMatch),
-	/*8765*/ uint16(x86_xCondIs64), 8768, 8780,
-	/*8768*/ uint16(x86_xCondDataSize), 8772, 8776, 0,
-	/*8772*/ uint16(x86_xSetOp), uint16(x86_POP),
-	/*8774*/ uint16(x86_xArgR16op),
-	/*8775*/ uint16(x86_xMatch),
-	/*8776*/ uint16(x86_xSetOp), uint16(x86_POP),
-	/*8778*/ uint16(x86_xArgR32op),
-	/*8779*/ uint16(x86_xMatch),
-	/*8780*/ uint16(x86_xCondDataSize), 8772, 8784, 8788,
-	/*8784*/ uint16(x86_xSetOp), uint16(x86_POP),
-	/*8786*/ uint16(x86_xArgR64op),
-	/*8787*/ uint16(x86_xMatch),
-	/*8788*/ uint16(x86_xSetOp), uint16(x86_POP),
-	/*8790*/ uint16(x86_xArgR64op),
-	/*8791*/ uint16(x86_xMatch),
-	/*8792*/ uint16(x86_xCondIs64), 8795, 0,
-	/*8795*/ uint16(x86_xCondDataSize), 8799, 8802, 0,
-	/*8799*/ uint16(x86_xSetOp), uint16(x86_PUSHA),
-	/*8801*/ uint16(x86_xMatch),
-	/*8802*/ uint16(x86_xSetOp), uint16(x86_PUSHAD),
-	/*8804*/ uint16(x86_xMatch),
-	/*8805*/ uint16(x86_xCondIs64), 8808, 0,
-	/*8808*/ uint16(x86_xCondDataSize), 8812, 8815, 0,
-	/*8812*/ uint16(x86_xSetOp), uint16(x86_POPA),
-	/*8814*/ uint16(x86_xMatch),
-	/*8815*/ uint16(x86_xSetOp), uint16(x86_POPAD),
-	/*8817*/ uint16(x86_xMatch),
-	/*8818*/ uint16(x86_xCondIs64), 8821, 0,
-	/*8821*/ uint16(x86_xCondDataSize), 8825, 8831, 0,
-	/*8825*/ uint16(x86_xSetOp), uint16(x86_BOUND),
-	/*8827*/ uint16(x86_xReadSlashR),
-	/*8828*/ uint16(x86_xArgR16),
-	/*8829*/ uint16(x86_xArgM16and16),
-	/*8830*/ uint16(x86_xMatch),
-	/*8831*/ uint16(x86_xSetOp), uint16(x86_BOUND),
-	/*8833*/ uint16(x86_xReadSlashR),
-	/*8834*/ uint16(x86_xArgR32),
-	/*8835*/ uint16(x86_xArgM32and32),
-	/*8836*/ uint16(x86_xMatch),
-	/*8837*/ uint16(x86_xCondIs64), 8840, 8846,
-	/*8840*/ uint16(x86_xSetOp), uint16(x86_ARPL),
-	/*8842*/ uint16(x86_xReadSlashR),
-	/*8843*/ uint16(x86_xArgRM16),
-	/*8844*/ uint16(x86_xArgR16),
-	/*8845*/ uint16(x86_xMatch),
-	/*8846*/ uint16(x86_xCondDataSize), 8850, 8856, 8862,
-	/*8850*/ uint16(x86_xSetOp), uint16(x86_MOVSXD),
-	/*8852*/ uint16(x86_xReadSlashR),
-	/*8853*/ uint16(x86_xArgR16),
-	/*8854*/ uint16(x86_xArgRM32),
-	/*8855*/ uint16(x86_xMatch),
-	/*8856*/ uint16(x86_xSetOp), uint16(x86_MOVSXD),
-	/*8858*/ uint16(x86_xReadSlashR),
-	/*8859*/ uint16(x86_xArgR32),
-	/*8860*/ uint16(x86_xArgRM32),
-	/*8861*/ uint16(x86_xMatch),
-	/*8862*/ uint16(x86_xSetOp), uint16(x86_MOVSXD),
-	/*8864*/ uint16(x86_xReadSlashR),
-	/*8865*/ uint16(x86_xArgR64),
-	/*8866*/ uint16(x86_xArgRM32),
-	/*8867*/ uint16(x86_xMatch),
-	/*8868*/ uint16(x86_xCondDataSize), 8872, 8877, 8882,
-	/*8872*/ uint16(x86_xSetOp), uint16(x86_PUSH),
-	/*8874*/ uint16(x86_xReadIw),
-	/*8875*/ uint16(x86_xArgImm16),
-	/*8876*/ uint16(x86_xMatch),
-	/*8877*/ uint16(x86_xSetOp), uint16(x86_PUSH),
-	/*8879*/ uint16(x86_xReadId),
-	/*8880*/ uint16(x86_xArgImm32),
-	/*8881*/ uint16(x86_xMatch),
-	/*8882*/ uint16(x86_xSetOp), uint16(x86_PUSH),
-	/*8884*/ uint16(x86_xReadId),
-	/*8885*/ uint16(x86_xArgImm32),
-	/*8886*/ uint16(x86_xMatch),
-	/*8887*/ uint16(x86_xCondIs64), 8890, 8910,
-	/*8890*/ uint16(x86_xCondDataSize), 8894, 8902, 0,
-	/*8894*/ uint16(x86_xSetOp), uint16(x86_IMUL),
-	/*8896*/ uint16(x86_xReadSlashR),
-	/*8897*/ uint16(x86_xReadIw),
-	/*8898*/ uint16(x86_xArgR16),
-	/*8899*/ uint16(x86_xArgRM16),
-	/*8900*/ uint16(x86_xArgImm16),
-	/*8901*/ uint16(x86_xMatch),
-	/*8902*/ uint16(x86_xSetOp), uint16(x86_IMUL),
-	/*8904*/ uint16(x86_xReadSlashR),
-	/*8905*/ uint16(x86_xReadId),
-	/*8906*/ uint16(x86_xArgR32),
-	/*8907*/ uint16(x86_xArgRM32),
-	/*8908*/ uint16(x86_xArgImm32),
-	/*8909*/ uint16(x86_xMatch),
-	/*8910*/ uint16(x86_xCondDataSize), 8894, 8902, 8914,
-	/*8914*/ uint16(x86_xSetOp), uint16(x86_IMUL),
-	/*8916*/ uint16(x86_xReadSlashR),
-	/*8917*/ uint16(x86_xReadId),
-	/*8918*/ uint16(x86_xArgR64),
-	/*8919*/ uint16(x86_xArgRM64),
-	/*8920*/ uint16(x86_xArgImm32),
-	/*8921*/ uint16(x86_xMatch),
-	/*8922*/ uint16(x86_xSetOp), uint16(x86_PUSH),
-	/*8924*/ uint16(x86_xReadIb),
-	/*8925*/ uint16(x86_xArgImm8),
-	/*8926*/ uint16(x86_xMatch),
-	/*8927*/ uint16(x86_xCondIs64), 8930, 8950,
-	/*8930*/ uint16(x86_xCondDataSize), 8934, 8942, 0,
-	/*8934*/ uint16(x86_xSetOp), uint16(x86_IMUL),
-	/*8936*/ uint16(x86_xReadSlashR),
-	/*8937*/ uint16(x86_xReadIb),
-	/*8938*/ uint16(x86_xArgR16),
-	/*8939*/ uint16(x86_xArgRM16),
-	/*8940*/ uint16(x86_xArgImm8),
-	/*8941*/ uint16(x86_xMatch),
-	/*8942*/ uint16(x86_xSetOp), uint16(x86_IMUL),
-	/*8944*/ uint16(x86_xReadSlashR),
-	/*8945*/ uint16(x86_xReadIb),
-	/*8946*/ uint16(x86_xArgR32),
-	/*8947*/ uint16(x86_xArgRM32),
-	/*8948*/ uint16(x86_xArgImm8),
-	/*8949*/ uint16(x86_xMatch),
-	/*8950*/ uint16(x86_xCondDataSize), 8934, 8942, 8954,
-	/*8954*/ uint16(x86_xSetOp), uint16(x86_IMUL),
-	/*8956*/ uint16(x86_xReadSlashR),
-	/*8957*/ uint16(x86_xReadIb),
-	/*8958*/ uint16(x86_xArgR64),
-	/*8959*/ uint16(x86_xArgRM64),
-	/*8960*/ uint16(x86_xArgImm8),
-	/*8961*/ uint16(x86_xMatch),
-	/*8962*/ uint16(x86_xSetOp), uint16(x86_INSB),
-	/*8964*/ uint16(x86_xMatch),
-	/*8965*/ uint16(x86_xCondDataSize), 8969, 8972, 8975,
-	/*8969*/ uint16(x86_xSetOp), uint16(x86_INSW),
-	/*8971*/ uint16(x86_xMatch),
-	/*8972*/ uint16(x86_xSetOp), uint16(x86_INSD),
-	/*8974*/ uint16(x86_xMatch),
-	/*8975*/ uint16(x86_xSetOp), uint16(x86_INSD),
-	/*8977*/ uint16(x86_xMatch),
-	/*8978*/ uint16(x86_xSetOp), uint16(x86_OUTSB),
-	/*8980*/ uint16(x86_xMatch),
-	/*8981*/ uint16(x86_xCondDataSize), 8985, 8988, 8991,
-	/*8985*/ uint16(x86_xSetOp), uint16(x86_OUTSW),
-	/*8987*/ uint16(x86_xMatch),
-	/*8988*/ uint16(x86_xSetOp), uint16(x86_OUTSD),
-	/*8990*/ uint16(x86_xMatch),
-	/*8991*/ uint16(x86_xSetOp), uint16(x86_OUTSD),
-	/*8993*/ uint16(x86_xMatch),
-	/*8994*/ uint16(x86_xSetOp), uint16(x86_JO),
-	/*8996*/ uint16(x86_xReadCb),
-	/*8997*/ uint16(x86_xArgRel8),
-	/*8998*/ uint16(x86_xMatch),
-	/*8999*/ uint16(x86_xSetOp), uint16(x86_JNO),
-	/*9001*/ uint16(x86_xReadCb),
-	/*9002*/ uint16(x86_xArgRel8),
-	/*9003*/ uint16(x86_xMatch),
-	/*9004*/ uint16(x86_xSetOp), uint16(x86_JB),
-	/*9006*/ uint16(x86_xReadCb),
-	/*9007*/ uint16(x86_xArgRel8),
-	/*9008*/ uint16(x86_xMatch),
-	/*9009*/ uint16(x86_xSetOp), uint16(x86_JAE),
-	/*9011*/ uint16(x86_xReadCb),
-	/*9012*/ uint16(x86_xArgRel8),
-	/*9013*/ uint16(x86_xMatch),
-	/*9014*/ uint16(x86_xSetOp), uint16(x86_JE),
-	/*9016*/ uint16(x86_xReadCb),
-	/*9017*/ uint16(x86_xArgRel8),
-	/*9018*/ uint16(x86_xMatch),
-	/*9019*/ uint16(x86_xSetOp), uint16(x86_JNE),
-	/*9021*/ uint16(x86_xReadCb),
-	/*9022*/ uint16(x86_xArgRel8),
-	/*9023*/ uint16(x86_xMatch),
-	/*9024*/ uint16(x86_xSetOp), uint16(x86_JBE),
-	/*9026*/ uint16(x86_xReadCb),
-	/*9027*/ uint16(x86_xArgRel8),
-	/*9028*/ uint16(x86_xMatch),
-	/*9029*/ uint16(x86_xSetOp), uint16(x86_JA),
-	/*9031*/ uint16(x86_xReadCb),
-	/*9032*/ uint16(x86_xArgRel8),
-	/*9033*/ uint16(x86_xMatch),
-	/*9034*/ uint16(x86_xSetOp), uint16(x86_JS),
-	/*9036*/ uint16(x86_xReadCb),
-	/*9037*/ uint16(x86_xArgRel8),
-	/*9038*/ uint16(x86_xMatch),
-	/*9039*/ uint16(x86_xSetOp), uint16(x86_JNS),
-	/*9041*/ uint16(x86_xReadCb),
-	/*9042*/ uint16(x86_xArgRel8),
-	/*9043*/ uint16(x86_xMatch),
-	/*9044*/ uint16(x86_xSetOp), uint16(x86_JP),
-	/*9046*/ uint16(x86_xReadCb),
-	/*9047*/ uint16(x86_xArgRel8),
-	/*9048*/ uint16(x86_xMatch),
-	/*9049*/ uint16(x86_xSetOp), uint16(x86_JNP),
-	/*9051*/ uint16(x86_xReadCb),
-	/*9052*/ uint16(x86_xArgRel8),
-	/*9053*/ uint16(x86_xMatch),
-	/*9054*/ uint16(x86_xSetOp), uint16(x86_JL),
-	/*9056*/ uint16(x86_xReadCb),
-	/*9057*/ uint16(x86_xArgRel8),
-	/*9058*/ uint16(x86_xMatch),
-	/*9059*/ uint16(x86_xSetOp), uint16(x86_JGE),
-	/*9061*/ uint16(x86_xReadCb),
-	/*9062*/ uint16(x86_xArgRel8),
-	/*9063*/ uint16(x86_xMatch),
-	/*9064*/ uint16(x86_xSetOp), uint16(x86_JLE),
-	/*9066*/ uint16(x86_xReadCb),
-	/*9067*/ uint16(x86_xArgRel8),
-	/*9068*/ uint16(x86_xMatch),
-	/*9069*/ uint16(x86_xSetOp), uint16(x86_JG),
-	/*9071*/ uint16(x86_xReadCb),
-	/*9072*/ uint16(x86_xArgRel8),
-	/*9073*/ uint16(x86_xMatch),
-	/*9074*/ uint16(x86_xCondSlashR),
-	9083, // 0
-	9089, // 1
-	9095, // 2
-	9101, // 3
-	9107, // 4
-	9113, // 5
-	9119, // 6
-	9125, // 7
-	/*9083*/ uint16(x86_xSetOp), uint16(x86_ADD),
-	/*9085*/ uint16(x86_xReadIb),
-	/*9086*/ uint16(x86_xArgRM8),
-	/*9087*/ uint16(x86_xArgImm8u),
-	/*9088*/ uint16(x86_xMatch),
-	/*9089*/ uint16(x86_xSetOp), uint16(x86_OR),
-	/*9091*/ uint16(x86_xReadIb),
-	/*9092*/ uint16(x86_xArgRM8),
-	/*9093*/ uint16(x86_xArgImm8u),
-	/*9094*/ uint16(x86_xMatch),
-	/*9095*/ uint16(x86_xSetOp), uint16(x86_ADC),
-	/*9097*/ uint16(x86_xReadIb),
-	/*9098*/ uint16(x86_xArgRM8),
-	/*9099*/ uint16(x86_xArgImm8u),
-	/*9100*/ uint16(x86_xMatch),
-	/*9101*/ uint16(x86_xSetOp), uint16(x86_SBB),
-	/*9103*/ uint16(x86_xReadIb),
-	/*9104*/ uint16(x86_xArgRM8),
-	/*9105*/ uint16(x86_xArgImm8u),
-	/*9106*/ uint16(x86_xMatch),
-	/*9107*/ uint16(x86_xSetOp), uint16(x86_AND),
-	/*9109*/ uint16(x86_xReadIb),
-	/*9110*/ uint16(x86_xArgRM8),
-	/*9111*/ uint16(x86_xArgImm8u),
-	/*9112*/ uint16(x86_xMatch),
-	/*9113*/ uint16(x86_xSetOp), uint16(x86_SUB),
-	/*9115*/ uint16(x86_xReadIb),
-	/*9116*/ uint16(x86_xArgRM8),
-	/*9117*/ uint16(x86_xArgImm8u),
-	/*9118*/ uint16(x86_xMatch),
-	/*9119*/ uint16(x86_xSetOp), uint16(x86_XOR),
-	/*9121*/ uint16(x86_xReadIb),
-	/*9122*/ uint16(x86_xArgRM8),
-	/*9123*/ uint16(x86_xArgImm8u),
-	/*9124*/ uint16(x86_xMatch),
-	/*9125*/ uint16(x86_xSetOp), uint16(x86_CMP),
-	/*9127*/ uint16(x86_xReadIb),
-	/*9128*/ uint16(x86_xArgRM8),
-	/*9129*/ uint16(x86_xArgImm8u),
-	/*9130*/ uint16(x86_xMatch),
-	/*9131*/ uint16(x86_xCondSlashR),
-	9140, // 0
-	9169, // 1
-	9198, // 2
-	9227, // 3
-	9256, // 4
-	9285, // 5
-	9314, // 6
-	9343, // 7
-	/*9140*/ uint16(x86_xCondIs64), 9143, 9159,
-	/*9143*/ uint16(x86_xCondDataSize), 9147, 9153, 0,
-	/*9147*/ uint16(x86_xSetOp), uint16(x86_ADD),
-	/*9149*/ uint16(x86_xReadIw),
-	/*9150*/ uint16(x86_xArgRM16),
-	/*9151*/ uint16(x86_xArgImm16),
-	/*9152*/ uint16(x86_xMatch),
-	/*9153*/ uint16(x86_xSetOp), uint16(x86_ADD),
-	/*9155*/ uint16(x86_xReadId),
-	/*9156*/ uint16(x86_xArgRM32),
-	/*9157*/ uint16(x86_xArgImm32),
-	/*9158*/ uint16(x86_xMatch),
-	/*9159*/ uint16(x86_xCondDataSize), 9147, 9153, 9163,
-	/*9163*/ uint16(x86_xSetOp), uint16(x86_ADD),
-	/*9165*/ uint16(x86_xReadId),
-	/*9166*/ uint16(x86_xArgRM64),
-	/*9167*/ uint16(x86_xArgImm32),
-	/*9168*/ uint16(x86_xMatch),
-	/*9169*/ uint16(x86_xCondIs64), 9172, 9188,
-	/*9172*/ uint16(x86_xCondDataSize), 9176, 9182, 0,
-	/*9176*/ uint16(x86_xSetOp), uint16(x86_OR),
-	/*9178*/ uint16(x86_xReadIw),
-	/*9179*/ uint16(x86_xArgRM16),
-	/*9180*/ uint16(x86_xArgImm16),
-	/*9181*/ uint16(x86_xMatch),
-	/*9182*/ uint16(x86_xSetOp), uint16(x86_OR),
-	/*9184*/ uint16(x86_xReadId),
-	/*9185*/ uint16(x86_xArgRM32),
-	/*9186*/ uint16(x86_xArgImm32),
-	/*9187*/ uint16(x86_xMatch),
-	/*9188*/ uint16(x86_xCondDataSize), 9176, 9182, 9192,
-	/*9192*/ uint16(x86_xSetOp), uint16(x86_OR),
-	/*9194*/ uint16(x86_xReadId),
-	/*9195*/ uint16(x86_xArgRM64),
-	/*9196*/ uint16(x86_xArgImm32),
-	/*9197*/ uint16(x86_xMatch),
-	/*9198*/ uint16(x86_xCondIs64), 9201, 9217,
-	/*9201*/ uint16(x86_xCondDataSize), 9205, 9211, 0,
-	/*9205*/ uint16(x86_xSetOp), uint16(x86_ADC),
-	/*9207*/ uint16(x86_xReadIw),
-	/*9208*/ uint16(x86_xArgRM16),
-	/*9209*/ uint16(x86_xArgImm16),
-	/*9210*/ uint16(x86_xMatch),
-	/*9211*/ uint16(x86_xSetOp), uint16(x86_ADC),
-	/*9213*/ uint16(x86_xReadId),
-	/*9214*/ uint16(x86_xArgRM32),
-	/*9215*/ uint16(x86_xArgImm32),
-	/*9216*/ uint16(x86_xMatch),
-	/*9217*/ uint16(x86_xCondDataSize), 9205, 9211, 9221,
-	/*9221*/ uint16(x86_xSetOp), uint16(x86_ADC),
-	/*9223*/ uint16(x86_xReadId),
-	/*9224*/ uint16(x86_xArgRM64),
-	/*9225*/ uint16(x86_xArgImm32),
-	/*9226*/ uint16(x86_xMatch),
-	/*9227*/ uint16(x86_xCondIs64), 9230, 9246,
-	/*9230*/ uint16(x86_xCondDataSize), 9234, 9240, 0,
-	/*9234*/ uint16(x86_xSetOp), uint16(x86_SBB),
-	/*9236*/ uint16(x86_xReadIw),
-	/*9237*/ uint16(x86_xArgRM16),
-	/*9238*/ uint16(x86_xArgImm16),
-	/*9239*/ uint16(x86_xMatch),
-	/*9240*/ uint16(x86_xSetOp), uint16(x86_SBB),
-	/*9242*/ uint16(x86_xReadId),
-	/*9243*/ uint16(x86_xArgRM32),
-	/*9244*/ uint16(x86_xArgImm32),
-	/*9245*/ uint16(x86_xMatch),
-	/*9246*/ uint16(x86_xCondDataSize), 9234, 9240, 9250,
-	/*9250*/ uint16(x86_xSetOp), uint16(x86_SBB),
-	/*9252*/ uint16(x86_xReadId),
-	/*9253*/ uint16(x86_xArgRM64),
-	/*9254*/ uint16(x86_xArgImm32),
-	/*9255*/ uint16(x86_xMatch),
-	/*9256*/ uint16(x86_xCondIs64), 9259, 9275,
-	/*9259*/ uint16(x86_xCondDataSize), 9263, 9269, 0,
-	/*9263*/ uint16(x86_xSetOp), uint16(x86_AND),
-	/*9265*/ uint16(x86_xReadIw),
-	/*9266*/ uint16(x86_xArgRM16),
-	/*9267*/ uint16(x86_xArgImm16),
-	/*9268*/ uint16(x86_xMatch),
-	/*9269*/ uint16(x86_xSetOp), uint16(x86_AND),
-	/*9271*/ uint16(x86_xReadId),
-	/*9272*/ uint16(x86_xArgRM32),
-	/*9273*/ uint16(x86_xArgImm32),
-	/*9274*/ uint16(x86_xMatch),
-	/*9275*/ uint16(x86_xCondDataSize), 9263, 9269, 9279,
-	/*9279*/ uint16(x86_xSetOp), uint16(x86_AND),
-	/*9281*/ uint16(x86_xReadId),
-	/*9282*/ uint16(x86_xArgRM64),
-	/*9283*/ uint16(x86_xArgImm32),
-	/*9284*/ uint16(x86_xMatch),
-	/*9285*/ uint16(x86_xCondIs64), 9288, 9304,
-	/*9288*/ uint16(x86_xCondDataSize), 9292, 9298, 0,
-	/*9292*/ uint16(x86_xSetOp), uint16(x86_SUB),
-	/*9294*/ uint16(x86_xReadIw),
-	/*9295*/ uint16(x86_xArgRM16),
-	/*9296*/ uint16(x86_xArgImm16),
-	/*9297*/ uint16(x86_xMatch),
-	/*9298*/ uint16(x86_xSetOp), uint16(x86_SUB),
-	/*9300*/ uint16(x86_xReadId),
-	/*9301*/ uint16(x86_xArgRM32),
-	/*9302*/ uint16(x86_xArgImm32),
-	/*9303*/ uint16(x86_xMatch),
-	/*9304*/ uint16(x86_xCondDataSize), 9292, 9298, 9308,
-	/*9308*/ uint16(x86_xSetOp), uint16(x86_SUB),
-	/*9310*/ uint16(x86_xReadId),
-	/*9311*/ uint16(x86_xArgRM64),
-	/*9312*/ uint16(x86_xArgImm32),
-	/*9313*/ uint16(x86_xMatch),
-	/*9314*/ uint16(x86_xCondIs64), 9317, 9333,
-	/*9317*/ uint16(x86_xCondDataSize), 9321, 9327, 0,
-	/*9321*/ uint16(x86_xSetOp), uint16(x86_XOR),
-	/*9323*/ uint16(x86_xReadIw),
-	/*9324*/ uint16(x86_xArgRM16),
-	/*9325*/ uint16(x86_xArgImm16),
-	/*9326*/ uint16(x86_xMatch),
-	/*9327*/ uint16(x86_xSetOp), uint16(x86_XOR),
-	/*9329*/ uint16(x86_xReadId),
-	/*9330*/ uint16(x86_xArgRM32),
-	/*9331*/ uint16(x86_xArgImm32),
-	/*9332*/ uint16(x86_xMatch),
-	/*9333*/ uint16(x86_xCondDataSize), 9321, 9327, 9337,
-	/*9337*/ uint16(x86_xSetOp), uint16(x86_XOR),
-	/*9339*/ uint16(x86_xReadId),
-	/*9340*/ uint16(x86_xArgRM64),
-	/*9341*/ uint16(x86_xArgImm32),
-	/*9342*/ uint16(x86_xMatch),
-	/*9343*/ uint16(x86_xCondIs64), 9346, 9362,
-	/*9346*/ uint16(x86_xCondDataSize), 9350, 9356, 0,
-	/*9350*/ uint16(x86_xSetOp), uint16(x86_CMP),
-	/*9352*/ uint16(x86_xReadIw),
-	/*9353*/ uint16(x86_xArgRM16),
-	/*9354*/ uint16(x86_xArgImm16),
-	/*9355*/ uint16(x86_xMatch),
-	/*9356*/ uint16(x86_xSetOp), uint16(x86_CMP),
-	/*9358*/ uint16(x86_xReadId),
-	/*9359*/ uint16(x86_xArgRM32),
-	/*9360*/ uint16(x86_xArgImm32),
-	/*9361*/ uint16(x86_xMatch),
-	/*9362*/ uint16(x86_xCondDataSize), 9350, 9356, 9366,
-	/*9366*/ uint16(x86_xSetOp), uint16(x86_CMP),
-	/*9368*/ uint16(x86_xReadId),
-	/*9369*/ uint16(x86_xArgRM64),
-	/*9370*/ uint16(x86_xArgImm32),
-	/*9371*/ uint16(x86_xMatch),
-	/*9372*/ uint16(x86_xCondSlashR),
-	9381, // 0
-	9410, // 1
-	9439, // 2
-	9468, // 3
-	9497, // 4
-	9526, // 5
-	9555, // 6
-	9584, // 7
-	/*9381*/ uint16(x86_xCondIs64), 9384, 9400,
-	/*9384*/ uint16(x86_xCondDataSize), 9388, 9394, 0,
-	/*9388*/ uint16(x86_xSetOp), uint16(x86_ADD),
-	/*9390*/ uint16(x86_xReadIb),
-	/*9391*/ uint16(x86_xArgRM16),
-	/*9392*/ uint16(x86_xArgImm8),
-	/*9393*/ uint16(x86_xMatch),
-	/*9394*/ uint16(x86_xSetOp), uint16(x86_ADD),
-	/*9396*/ uint16(x86_xReadIb),
-	/*9397*/ uint16(x86_xArgRM32),
-	/*9398*/ uint16(x86_xArgImm8),
-	/*9399*/ uint16(x86_xMatch),
-	/*9400*/ uint16(x86_xCondDataSize), 9388, 9394, 9404,
-	/*9404*/ uint16(x86_xSetOp), uint16(x86_ADD),
-	/*9406*/ uint16(x86_xReadIb),
-	/*9407*/ uint16(x86_xArgRM64),
-	/*9408*/ uint16(x86_xArgImm8),
-	/*9409*/ uint16(x86_xMatch),
-	/*9410*/ uint16(x86_xCondIs64), 9413, 9429,
-	/*9413*/ uint16(x86_xCondDataSize), 9417, 9423, 0,
-	/*9417*/ uint16(x86_xSetOp), uint16(x86_OR),
-	/*9419*/ uint16(x86_xReadIb),
-	/*9420*/ uint16(x86_xArgRM16),
-	/*9421*/ uint16(x86_xArgImm8),
-	/*9422*/ uint16(x86_xMatch),
-	/*9423*/ uint16(x86_xSetOp), uint16(x86_OR),
-	/*9425*/ uint16(x86_xReadIb),
-	/*9426*/ uint16(x86_xArgRM32),
-	/*9427*/ uint16(x86_xArgImm8),
-	/*9428*/ uint16(x86_xMatch),
-	/*9429*/ uint16(x86_xCondDataSize), 9417, 9423, 9433,
-	/*9433*/ uint16(x86_xSetOp), uint16(x86_OR),
-	/*9435*/ uint16(x86_xReadIb),
-	/*9436*/ uint16(x86_xArgRM64),
-	/*9437*/ uint16(x86_xArgImm8),
-	/*9438*/ uint16(x86_xMatch),
-	/*9439*/ uint16(x86_xCondIs64), 9442, 9458,
-	/*9442*/ uint16(x86_xCondDataSize), 9446, 9452, 0,
-	/*9446*/ uint16(x86_xSetOp), uint16(x86_ADC),
-	/*9448*/ uint16(x86_xReadIb),
-	/*9449*/ uint16(x86_xArgRM16),
-	/*9450*/ uint16(x86_xArgImm8),
-	/*9451*/ uint16(x86_xMatch),
-	/*9452*/ uint16(x86_xSetOp), uint16(x86_ADC),
-	/*9454*/ uint16(x86_xReadIb),
-	/*9455*/ uint16(x86_xArgRM32),
-	/*9456*/ uint16(x86_xArgImm8),
-	/*9457*/ uint16(x86_xMatch),
-	/*9458*/ uint16(x86_xCondDataSize), 9446, 9452, 9462,
-	/*9462*/ uint16(x86_xSetOp), uint16(x86_ADC),
-	/*9464*/ uint16(x86_xReadIb),
-	/*9465*/ uint16(x86_xArgRM64),
-	/*9466*/ uint16(x86_xArgImm8),
-	/*9467*/ uint16(x86_xMatch),
-	/*9468*/ uint16(x86_xCondIs64), 9471, 9487,
-	/*9471*/ uint16(x86_xCondDataSize), 9475, 9481, 0,
-	/*9475*/ uint16(x86_xSetOp), uint16(x86_SBB),
-	/*9477*/ uint16(x86_xReadIb),
-	/*9478*/ uint16(x86_xArgRM16),
-	/*9479*/ uint16(x86_xArgImm8),
-	/*9480*/ uint16(x86_xMatch),
-	/*9481*/ uint16(x86_xSetOp), uint16(x86_SBB),
-	/*9483*/ uint16(x86_xReadIb),
-	/*9484*/ uint16(x86_xArgRM32),
-	/*9485*/ uint16(x86_xArgImm8),
-	/*9486*/ uint16(x86_xMatch),
-	/*9487*/ uint16(x86_xCondDataSize), 9475, 9481, 9491,
-	/*9491*/ uint16(x86_xSetOp), uint16(x86_SBB),
-	/*9493*/ uint16(x86_xReadIb),
-	/*9494*/ uint16(x86_xArgRM64),
-	/*9495*/ uint16(x86_xArgImm8),
-	/*9496*/ uint16(x86_xMatch),
-	/*9497*/ uint16(x86_xCondIs64), 9500, 9516,
-	/*9500*/ uint16(x86_xCondDataSize), 9504, 9510, 0,
-	/*9504*/ uint16(x86_xSetOp), uint16(x86_AND),
-	/*9506*/ uint16(x86_xReadIb),
-	/*9507*/ uint16(x86_xArgRM16),
-	/*9508*/ uint16(x86_xArgImm8),
-	/*9509*/ uint16(x86_xMatch),
-	/*9510*/ uint16(x86_xSetOp), uint16(x86_AND),
-	/*9512*/ uint16(x86_xReadIb),
-	/*9513*/ uint16(x86_xArgRM32),
-	/*9514*/ uint16(x86_xArgImm8),
-	/*9515*/ uint16(x86_xMatch),
-	/*9516*/ uint16(x86_xCondDataSize), 9504, 9510, 9520,
-	/*9520*/ uint16(x86_xSetOp), uint16(x86_AND),
-	/*9522*/ uint16(x86_xReadIb),
-	/*9523*/ uint16(x86_xArgRM64),
-	/*9524*/ uint16(x86_xArgImm8),
-	/*9525*/ uint16(x86_xMatch),
-	/*9526*/ uint16(x86_xCondIs64), 9529, 9545,
-	/*9529*/ uint16(x86_xCondDataSize), 9533, 9539, 0,
-	/*9533*/ uint16(x86_xSetOp), uint16(x86_SUB),
-	/*9535*/ uint16(x86_xReadIb),
-	/*9536*/ uint16(x86_xArgRM16),
-	/*9537*/ uint16(x86_xArgImm8),
-	/*9538*/ uint16(x86_xMatch),
-	/*9539*/ uint16(x86_xSetOp), uint16(x86_SUB),
-	/*9541*/ uint16(x86_xReadIb),
-	/*9542*/ uint16(x86_xArgRM32),
-	/*9543*/ uint16(x86_xArgImm8),
-	/*9544*/ uint16(x86_xMatch),
-	/*9545*/ uint16(x86_xCondDataSize), 9533, 9539, 9549,
-	/*9549*/ uint16(x86_xSetOp), uint16(x86_SUB),
-	/*9551*/ uint16(x86_xReadIb),
-	/*9552*/ uint16(x86_xArgRM64),
-	/*9553*/ uint16(x86_xArgImm8),
-	/*9554*/ uint16(x86_xMatch),
-	/*9555*/ uint16(x86_xCondIs64), 9558, 9574,
-	/*9558*/ uint16(x86_xCondDataSize), 9562, 9568, 0,
-	/*9562*/ uint16(x86_xSetOp), uint16(x86_XOR),
-	/*9564*/ uint16(x86_xReadIb),
-	/*9565*/ uint16(x86_xArgRM16),
-	/*9566*/ uint16(x86_xArgImm8),
-	/*9567*/ uint16(x86_xMatch),
-	/*9568*/ uint16(x86_xSetOp), uint16(x86_XOR),
-	/*9570*/ uint16(x86_xReadIb),
-	/*9571*/ uint16(x86_xArgRM32),
-	/*9572*/ uint16(x86_xArgImm8),
-	/*9573*/ uint16(x86_xMatch),
-	/*9574*/ uint16(x86_xCondDataSize), 9562, 9568, 9578,
-	/*9578*/ uint16(x86_xSetOp), uint16(x86_XOR),
-	/*9580*/ uint16(x86_xReadIb),
-	/*9581*/ uint16(x86_xArgRM64),
-	/*9582*/ uint16(x86_xArgImm8),
-	/*9583*/ uint16(x86_xMatch),
-	/*9584*/ uint16(x86_xCondIs64), 9587, 9603,
-	/*9587*/ uint16(x86_xCondDataSize), 9591, 9597, 0,
-	/*9591*/ uint16(x86_xSetOp), uint16(x86_CMP),
-	/*9593*/ uint16(x86_xReadIb),
-	/*9594*/ uint16(x86_xArgRM16),
-	/*9595*/ uint16(x86_xArgImm8),
-	/*9596*/ uint16(x86_xMatch),
-	/*9597*/ uint16(x86_xSetOp), uint16(x86_CMP),
-	/*9599*/ uint16(x86_xReadIb),
-	/*9600*/ uint16(x86_xArgRM32),
-	/*9601*/ uint16(x86_xArgImm8),
-	/*9602*/ uint16(x86_xMatch),
-	/*9603*/ uint16(x86_xCondDataSize), 9591, 9597, 9607,
-	/*9607*/ uint16(x86_xSetOp), uint16(x86_CMP),
-	/*9609*/ uint16(x86_xReadIb),
-	/*9610*/ uint16(x86_xArgRM64),
-	/*9611*/ uint16(x86_xArgImm8),
-	/*9612*/ uint16(x86_xMatch),
-	/*9613*/ uint16(x86_xSetOp), uint16(x86_TEST),
-	/*9615*/ uint16(x86_xReadSlashR),
-	/*9616*/ uint16(x86_xArgRM8),
-	/*9617*/ uint16(x86_xArgR8),
-	/*9618*/ uint16(x86_xMatch),
-	/*9619*/ uint16(x86_xCondIs64), 9622, 9638,
-	/*9622*/ uint16(x86_xCondDataSize), 9626, 9632, 0,
-	/*9626*/ uint16(x86_xSetOp), uint16(x86_TEST),
-	/*9628*/ uint16(x86_xReadSlashR),
-	/*9629*/ uint16(x86_xArgRM16),
-	/*9630*/ uint16(x86_xArgR16),
-	/*9631*/ uint16(x86_xMatch),
-	/*9632*/ uint16(x86_xSetOp), uint16(x86_TEST),
-	/*9634*/ uint16(x86_xReadSlashR),
-	/*9635*/ uint16(x86_xArgRM32),
-	/*9636*/ uint16(x86_xArgR32),
-	/*9637*/ uint16(x86_xMatch),
-	/*9638*/ uint16(x86_xCondDataSize), 9626, 9632, 9642,
-	/*9642*/ uint16(x86_xSetOp), uint16(x86_TEST),
-	/*9644*/ uint16(x86_xReadSlashR),
-	/*9645*/ uint16(x86_xArgRM64),
-	/*9646*/ uint16(x86_xArgR64),
-	/*9647*/ uint16(x86_xMatch),
-	/*9648*/ uint16(x86_xSetOp), uint16(x86_XCHG),
-	/*9650*/ uint16(x86_xReadSlashR),
-	/*9651*/ uint16(x86_xArgRM8),
-	/*9652*/ uint16(x86_xArgR8),
-	/*9653*/ uint16(x86_xMatch),
-	/*9654*/ uint16(x86_xCondIs64), 9657, 9673,
-	/*9657*/ uint16(x86_xCondDataSize), 9661, 9667, 0,
-	/*9661*/ uint16(x86_xSetOp), uint16(x86_XCHG),
-	/*9663*/ uint16(x86_xReadSlashR),
-	/*9664*/ uint16(x86_xArgRM16),
-	/*9665*/ uint16(x86_xArgR16),
-	/*9666*/ uint16(x86_xMatch),
-	/*9667*/ uint16(x86_xSetOp), uint16(x86_XCHG),
-	/*9669*/ uint16(x86_xReadSlashR),
-	/*9670*/ uint16(x86_xArgRM32),
-	/*9671*/ uint16(x86_xArgR32),
-	/*9672*/ uint16(x86_xMatch),
-	/*9673*/ uint16(x86_xCondDataSize), 9661, 9667, 9677,
-	/*9677*/ uint16(x86_xSetOp), uint16(x86_XCHG),
-	/*9679*/ uint16(x86_xReadSlashR),
-	/*9680*/ uint16(x86_xArgRM64),
-	/*9681*/ uint16(x86_xArgR64),
-	/*9682*/ uint16(x86_xMatch),
-	/*9683*/ uint16(x86_xSetOp), uint16(x86_MOV),
-	/*9685*/ uint16(x86_xReadSlashR),
-	/*9686*/ uint16(x86_xArgRM8),
-	/*9687*/ uint16(x86_xArgR8),
-	/*9688*/ uint16(x86_xMatch),
-	/*9689*/ uint16(x86_xCondDataSize), 9693, 9699, 9705,
-	/*9693*/ uint16(x86_xSetOp), uint16(x86_MOV),
-	/*9695*/ uint16(x86_xReadSlashR),
-	/*9696*/ uint16(x86_xArgRM16),
-	/*9697*/ uint16(x86_xArgR16),
-	/*9698*/ uint16(x86_xMatch),
-	/*9699*/ uint16(x86_xSetOp), uint16(x86_MOV),
-	/*9701*/ uint16(x86_xReadSlashR),
-	/*9702*/ uint16(x86_xArgRM32),
-	/*9703*/ uint16(x86_xArgR32),
-	/*9704*/ uint16(x86_xMatch),
-	/*9705*/ uint16(x86_xSetOp), uint16(x86_MOV),
-	/*9707*/ uint16(x86_xReadSlashR),
-	/*9708*/ uint16(x86_xArgRM64),
-	/*9709*/ uint16(x86_xArgR64),
-	/*9710*/ uint16(x86_xMatch),
-	/*9711*/ uint16(x86_xSetOp), uint16(x86_MOV),
-	/*9713*/ uint16(x86_xReadSlashR),
-	/*9714*/ uint16(x86_xArgR8),
-	/*9715*/ uint16(x86_xArgRM8),
-	/*9716*/ uint16(x86_xMatch),
-	/*9717*/ uint16(x86_xCondDataSize), 9721, 9727, 9733,
-	/*9721*/ uint16(x86_xSetOp), uint16(x86_MOV),
-	/*9723*/ uint16(x86_xReadSlashR),
-	/*9724*/ uint16(x86_xArgR16),
-	/*9725*/ uint16(x86_xArgRM16),
-	/*9726*/ uint16(x86_xMatch),
-	/*9727*/ uint16(x86_xSetOp), uint16(x86_MOV),
-	/*9729*/ uint16(x86_xReadSlashR),
-	/*9730*/ uint16(x86_xArgR32),
-	/*9731*/ uint16(x86_xArgRM32),
-	/*9732*/ uint16(x86_xMatch),
-	/*9733*/ uint16(x86_xSetOp), uint16(x86_MOV),
-	/*9735*/ uint16(x86_xReadSlashR),
-	/*9736*/ uint16(x86_xArgR64),
-	/*9737*/ uint16(x86_xArgRM64),
-	/*9738*/ uint16(x86_xMatch),
-	/*9739*/ uint16(x86_xCondIs64), 9742, 9758,
-	/*9742*/ uint16(x86_xCondDataSize), 9746, 9752, 0,
-	/*9746*/ uint16(x86_xSetOp), uint16(x86_MOV),
-	/*9748*/ uint16(x86_xReadSlashR),
-	/*9749*/ uint16(x86_xArgRM16),
-	/*9750*/ uint16(x86_xArgSreg),
-	/*9751*/ uint16(x86_xMatch),
-	/*9752*/ uint16(x86_xSetOp), uint16(x86_MOV),
-	/*9754*/ uint16(x86_xReadSlashR),
-	/*9755*/ uint16(x86_xArgR32M16),
-	/*9756*/ uint16(x86_xArgSreg),
-	/*9757*/ uint16(x86_xMatch),
-	/*9758*/ uint16(x86_xCondDataSize), 9746, 9752, 9762,
-	/*9762*/ uint16(x86_xSetOp), uint16(x86_MOV),
-	/*9764*/ uint16(x86_xReadSlashR),
-	/*9765*/ uint16(x86_xArgR64M16),
-	/*9766*/ uint16(x86_xArgSreg),
-	/*9767*/ uint16(x86_xMatch),
-	/*9768*/ uint16(x86_xCondIs64), 9771, 9787,
-	/*9771*/ uint16(x86_xCondDataSize), 9775, 9781, 0,
-	/*9775*/ uint16(x86_xSetOp), uint16(x86_LEA),
-	/*9777*/ uint16(x86_xReadSlashR),
-	/*9778*/ uint16(x86_xArgR16),
-	/*9779*/ uint16(x86_xArgM),
-	/*9780*/ uint16(x86_xMatch),
-	/*9781*/ uint16(x86_xSetOp), uint16(x86_LEA),
-	/*9783*/ uint16(x86_xReadSlashR),
-	/*9784*/ uint16(x86_xArgR32),
-	/*9785*/ uint16(x86_xArgM),
-	/*9786*/ uint16(x86_xMatch),
-	/*9787*/ uint16(x86_xCondDataSize), 9775, 9781, 9791,
-	/*9791*/ uint16(x86_xSetOp), uint16(x86_LEA),
-	/*9793*/ uint16(x86_xReadSlashR),
-	/*9794*/ uint16(x86_xArgR64),
-	/*9795*/ uint16(x86_xArgM),
-	/*9796*/ uint16(x86_xMatch),
-	/*9797*/ uint16(x86_xCondIs64), 9800, 9816,
-	/*9800*/ uint16(x86_xCondDataSize), 9804, 9810, 0,
-	/*9804*/ uint16(x86_xSetOp), uint16(x86_MOV),
-	/*9806*/ uint16(x86_xReadSlashR),
-	/*9807*/ uint16(x86_xArgSreg),
-	/*9808*/ uint16(x86_xArgRM16),
-	/*9809*/ uint16(x86_xMatch),
-	/*9810*/ uint16(x86_xSetOp), uint16(x86_MOV),
-	/*9812*/ uint16(x86_xReadSlashR),
-	/*9813*/ uint16(x86_xArgSreg),
-	/*9814*/ uint16(x86_xArgR32M16),
-	/*9815*/ uint16(x86_xMatch),
-	/*9816*/ uint16(x86_xCondDataSize), 9804, 9810, 9820,
-	/*9820*/ uint16(x86_xSetOp), uint16(x86_MOV),
-	/*9822*/ uint16(x86_xReadSlashR),
-	/*9823*/ uint16(x86_xArgSreg),
-	/*9824*/ uint16(x86_xArgR64M16),
-	/*9825*/ uint16(x86_xMatch),
-	/*9826*/ uint16(x86_xCondSlashR),
-	9835, // 0
-	0,    // 1
-	0,    // 2
-	0,    // 3
-	0,    // 4
-	0,    // 5
-	0,    // 6
-	0,    // 7
-	/*9835*/ uint16(x86_xCondIs64), 9838, 9850,
-	/*9838*/ uint16(x86_xCondDataSize), 9842, 9846, 0,
-	/*9842*/ uint16(x86_xSetOp), uint16(x86_POP),
-	/*9844*/ uint16(x86_xArgRM16),
-	/*9845*/ uint16(x86_xMatch),
-	/*9846*/ uint16(x86_xSetOp), uint16(x86_POP),
-	/*9848*/ uint16(x86_xArgRM32),
-	/*9849*/ uint16(x86_xMatch),
-	/*9850*/ uint16(x86_xCondDataSize), 9842, 9854, 9858,
-	/*9854*/ uint16(x86_xSetOp), uint16(x86_POP),
-	/*9856*/ uint16(x86_xArgRM64),
-	/*9857*/ uint16(x86_xMatch),
-	/*9858*/ uint16(x86_xSetOp), uint16(x86_POP),
-	/*9860*/ uint16(x86_xArgRM64),
-	/*9861*/ uint16(x86_xMatch),
-	/*9862*/ uint16(x86_xCondIs64), 9865, 9879,
-	/*9865*/ uint16(x86_xCondDataSize), 9869, 9874, 0,
-	/*9869*/ uint16(x86_xSetOp), uint16(x86_XCHG),
-	/*9871*/ uint16(x86_xArgR16op),
-	/*9872*/ uint16(x86_xArgAX),
-	/*9873*/ uint16(x86_xMatch),
-	/*9874*/ uint16(x86_xSetOp), uint16(x86_XCHG),
-	/*9876*/ uint16(x86_xArgR32op),
-	/*9877*/ uint16(x86_xArgEAX),
-	/*9878*/ uint16(x86_xMatch),
-	/*9879*/ uint16(x86_xCondDataSize), 9869, 9874, 9883,
-	/*9883*/ uint16(x86_xSetOp), uint16(x86_XCHG),
-	/*9885*/ uint16(x86_xArgR64op),
-	/*9886*/ uint16(x86_xArgRAX),
-	/*9887*/ uint16(x86_xMatch),
-	/*9888*/ uint16(x86_xCondIs64), 9891, 9901,
-	/*9891*/ uint16(x86_xCondDataSize), 9895, 9898, 0,
-	/*9895*/ uint16(x86_xSetOp), uint16(x86_CBW),
-	/*9897*/ uint16(x86_xMatch),
-	/*9898*/ uint16(x86_xSetOp), uint16(x86_CWDE),
-	/*9900*/ uint16(x86_xMatch),
-	/*9901*/ uint16(x86_xCondDataSize), 9895, 9898, 9905,
-	/*9905*/ uint16(x86_xSetOp), uint16(x86_CDQE),
-	/*9907*/ uint16(x86_xMatch),
-	/*9908*/ uint16(x86_xCondIs64), 9911, 9921,
-	/*9911*/ uint16(x86_xCondDataSize), 9915, 9918, 0,
-	/*9915*/ uint16(x86_xSetOp), uint16(x86_CWD),
-	/*9917*/ uint16(x86_xMatch),
-	/*9918*/ uint16(x86_xSetOp), uint16(x86_CDQ),
-	/*9920*/ uint16(x86_xMatch),
-	/*9921*/ uint16(x86_xCondDataSize), 9915, 9918, 9925,
-	/*9925*/ uint16(x86_xSetOp), uint16(x86_CQO),
-	/*9927*/ uint16(x86_xMatch),
-	/*9928*/ uint16(x86_xCondIs64), 9931, 0,
-	/*9931*/ uint16(x86_xCondDataSize), 9935, 9940, 0,
-	/*9935*/ uint16(x86_xSetOp), uint16(x86_LCALL),
-	/*9937*/ uint16(x86_xReadCd),
-	/*9938*/ uint16(x86_xArgPtr16colon16),
-	/*9939*/ uint16(x86_xMatch),
-	/*9940*/ uint16(x86_xSetOp), uint16(x86_LCALL),
-	/*9942*/ uint16(x86_xReadCp),
-	/*9943*/ uint16(x86_xArgPtr16colon32),
-	/*9944*/ uint16(x86_xMatch),
-	/*9945*/ uint16(x86_xSetOp), uint16(x86_FWAIT),
-	/*9947*/ uint16(x86_xMatch),
-	/*9948*/ uint16(x86_xCondIs64), 9951, 9961,
-	/*9951*/ uint16(x86_xCondDataSize), 9955, 9958, 0,
-	/*9955*/ uint16(x86_xSetOp), uint16(x86_PUSHF),
-	/*9957*/ uint16(x86_xMatch),
-	/*9958*/ uint16(x86_xSetOp), uint16(x86_PUSHFD),
-	/*9960*/ uint16(x86_xMatch),
-	/*9961*/ uint16(x86_xCondDataSize), 9955, 9965, 9968,
-	/*9965*/ uint16(x86_xSetOp), uint16(x86_PUSHFQ),
-	/*9967*/ uint16(x86_xMatch),
-	/*9968*/ uint16(x86_xSetOp), uint16(x86_PUSHFQ),
-	/*9970*/ uint16(x86_xMatch),
-	/*9971*/ uint16(x86_xCondIs64), 9974, 9984,
-	/*9974*/ uint16(x86_xCondDataSize), 9978, 9981, 0,
-	/*9978*/ uint16(x86_xSetOp), uint16(x86_POPF),
-	/*9980*/ uint16(x86_xMatch),
-	/*9981*/ uint16(x86_xSetOp), uint16(x86_POPFD),
-	/*9983*/ uint16(x86_xMatch),
-	/*9984*/ uint16(x86_xCondDataSize), 9978, 9988, 9991,
-	/*9988*/ uint16(x86_xSetOp), uint16(x86_POPFQ),
-	/*9990*/ uint16(x86_xMatch),
-	/*9991*/ uint16(x86_xSetOp), uint16(x86_POPFQ),
-	/*9993*/ uint16(x86_xMatch),
-	/*9994*/ uint16(x86_xSetOp), uint16(x86_SAHF),
-	/*9996*/ uint16(x86_xMatch),
-	/*9997*/ uint16(x86_xSetOp), uint16(x86_LAHF),
-	/*9999*/ uint16(x86_xMatch),
-	/*10000*/ uint16(x86_xCondIs64), 10003, 10009,
-	/*10003*/ uint16(x86_xSetOp), uint16(x86_MOV),
-	/*10005*/ uint16(x86_xReadCm),
-	/*10006*/ uint16(x86_xArgAL),
-	/*10007*/ uint16(x86_xArgMoffs8),
-	/*10008*/ uint16(x86_xMatch),
-	/*10009*/ uint16(x86_xCondDataSize), 10003, 10003, 10013,
-	/*10013*/ uint16(x86_xSetOp), uint16(x86_MOV),
-	/*10015*/ uint16(x86_xReadCm),
-	/*10016*/ uint16(x86_xArgAL),
-	/*10017*/ uint16(x86_xArgMoffs8),
-	/*10018*/ uint16(x86_xMatch),
-	/*10019*/ uint16(x86_xCondDataSize), 10023, 10029, 10035,
-	/*10023*/ uint16(x86_xSetOp), uint16(x86_MOV),
-	/*10025*/ uint16(x86_xReadCm),
-	/*10026*/ uint16(x86_xArgAX),
-	/*10027*/ uint16(x86_xArgMoffs16),
-	/*10028*/ uint16(x86_xMatch),
-	/*10029*/ uint16(x86_xSetOp), uint16(x86_MOV),
-	/*10031*/ uint16(x86_xReadCm),
-	/*10032*/ uint16(x86_xArgEAX),
-	/*10033*/ uint16(x86_xArgMoffs32),
-	/*10034*/ uint16(x86_xMatch),
-	/*10035*/ uint16(x86_xSetOp), uint16(x86_MOV),
-	/*10037*/ uint16(x86_xReadCm),
-	/*10038*/ uint16(x86_xArgRAX),
-	/*10039*/ uint16(x86_xArgMoffs64),
-	/*10040*/ uint16(x86_xMatch),
-	/*10041*/ uint16(x86_xCondIs64), 10044, 10050,
-	/*10044*/ uint16(x86_xSetOp), uint16(x86_MOV),
-	/*10046*/ uint16(x86_xReadCm),
-	/*10047*/ uint16(x86_xArgMoffs8),
-	/*10048*/ uint16(x86_xArgAL),
-	/*10049*/ uint16(x86_xMatch),
-	/*10050*/ uint16(x86_xCondDataSize), 10044, 10044, 10054,
-	/*10054*/ uint16(x86_xSetOp), uint16(x86_MOV),
-	/*10056*/ uint16(x86_xReadCm),
-	/*10057*/ uint16(x86_xArgMoffs8),
-	/*10058*/ uint16(x86_xArgAL),
-	/*10059*/ uint16(x86_xMatch),
-	/*10060*/ uint16(x86_xCondDataSize), 10064, 10070, 10076,
-	/*10064*/ uint16(x86_xSetOp), uint16(x86_MOV),
-	/*10066*/ uint16(x86_xReadCm),
-	/*10067*/ uint16(x86_xArgMoffs16),
-	/*10068*/ uint16(x86_xArgAX),
-	/*10069*/ uint16(x86_xMatch),
-	/*10070*/ uint16(x86_xSetOp), uint16(x86_MOV),
-	/*10072*/ uint16(x86_xReadCm),
-	/*10073*/ uint16(x86_xArgMoffs32),
-	/*10074*/ uint16(x86_xArgEAX),
-	/*10075*/ uint16(x86_xMatch),
-	/*10076*/ uint16(x86_xSetOp), uint16(x86_MOV),
-	/*10078*/ uint16(x86_xReadCm),
-	/*10079*/ uint16(x86_xArgMoffs64),
-	/*10080*/ uint16(x86_xArgRAX),
-	/*10081*/ uint16(x86_xMatch),
-	/*10082*/ uint16(x86_xSetOp), uint16(x86_MOVSB),
-	/*10084*/ uint16(x86_xMatch),
-	/*10085*/ uint16(x86_xCondIs64), 10088, 10098,
-	/*10088*/ uint16(x86_xCondDataSize), 10092, 10095, 0,
-	/*10092*/ uint16(x86_xSetOp), uint16(x86_MOVSW),
-	/*10094*/ uint16(x86_xMatch),
-	/*10095*/ uint16(x86_xSetOp), uint16(x86_MOVSD),
-	/*10097*/ uint16(x86_xMatch),
-	/*10098*/ uint16(x86_xCondDataSize), 10092, 10095, 10102,
-	/*10102*/ uint16(x86_xSetOp), uint16(x86_MOVSQ),
-	/*10104*/ uint16(x86_xMatch),
-	/*10105*/ uint16(x86_xSetOp), uint16(x86_CMPSB),
-	/*10107*/ uint16(x86_xMatch),
-	/*10108*/ uint16(x86_xCondIs64), 10111, 10121,
-	/*10111*/ uint16(x86_xCondDataSize), 10115, 10118, 0,
-	/*10115*/ uint16(x86_xSetOp), uint16(x86_CMPSW),
-	/*10117*/ uint16(x86_xMatch),
-	/*10118*/ uint16(x86_xSetOp), uint16(x86_CMPSD),
-	/*10120*/ uint16(x86_xMatch),
-	/*10121*/ uint16(x86_xCondDataSize), 10115, 10118, 10125,
-	/*10125*/ uint16(x86_xSetOp), uint16(x86_CMPSQ),
-	/*10127*/ uint16(x86_xMatch),
-	/*10128*/ uint16(x86_xSetOp), uint16(x86_TEST),
-	/*10130*/ uint16(x86_xReadIb),
-	/*10131*/ uint16(x86_xArgAL),
-	/*10132*/ uint16(x86_xArgImm8u),
-	/*10133*/ uint16(x86_xMatch),
-	/*10134*/ uint16(x86_xCondIs64), 10137, 10153,
-	/*10137*/ uint16(x86_xCondDataSize), 10141, 10147, 0,
-	/*10141*/ uint16(x86_xSetOp), uint16(x86_TEST),
-	/*10143*/ uint16(x86_xReadIw),
-	/*10144*/ uint16(x86_xArgAX),
-	/*10145*/ uint16(x86_xArgImm16),
-	/*10146*/ uint16(x86_xMatch),
-	/*10147*/ uint16(x86_xSetOp), uint16(x86_TEST),
-	/*10149*/ uint16(x86_xReadId),
-	/*10150*/ uint16(x86_xArgEAX),
-	/*10151*/ uint16(x86_xArgImm32),
-	/*10152*/ uint16(x86_xMatch),
-	/*10153*/ uint16(x86_xCondDataSize), 10141, 10147, 10157,
-	/*10157*/ uint16(x86_xSetOp), uint16(x86_TEST),
-	/*10159*/ uint16(x86_xReadId),
-	/*10160*/ uint16(x86_xArgRAX),
-	/*10161*/ uint16(x86_xArgImm32),
-	/*10162*/ uint16(x86_xMatch),
-	/*10163*/ uint16(x86_xSetOp), uint16(x86_STOSB),
-	/*10165*/ uint16(x86_xMatch),
-	/*10166*/ uint16(x86_xCondIs64), 10169, 10179,
-	/*10169*/ uint16(x86_xCondDataSize), 10173, 10176, 0,
-	/*10173*/ uint16(x86_xSetOp), uint16(x86_STOSW),
-	/*10175*/ uint16(x86_xMatch),
-	/*10176*/ uint16(x86_xSetOp), uint16(x86_STOSD),
-	/*10178*/ uint16(x86_xMatch),
-	/*10179*/ uint16(x86_xCondDataSize), 10173, 10176, 10183,
-	/*10183*/ uint16(x86_xSetOp), uint16(x86_STOSQ),
-	/*10185*/ uint16(x86_xMatch),
-	/*10186*/ uint16(x86_xSetOp), uint16(x86_LODSB),
-	/*10188*/ uint16(x86_xMatch),
-	/*10189*/ uint16(x86_xCondIs64), 10192, 10202,
-	/*10192*/ uint16(x86_xCondDataSize), 10196, 10199, 0,
-	/*10196*/ uint16(x86_xSetOp), uint16(x86_LODSW),
-	/*10198*/ uint16(x86_xMatch),
-	/*10199*/ uint16(x86_xSetOp), uint16(x86_LODSD),
-	/*10201*/ uint16(x86_xMatch),
-	/*10202*/ uint16(x86_xCondDataSize), 10196, 10199, 10206,
-	/*10206*/ uint16(x86_xSetOp), uint16(x86_LODSQ),
-	/*10208*/ uint16(x86_xMatch),
-	/*10209*/ uint16(x86_xSetOp), uint16(x86_SCASB),
-	/*10211*/ uint16(x86_xMatch),
-	/*10212*/ uint16(x86_xCondIs64), 10215, 10225,
-	/*10215*/ uint16(x86_xCondDataSize), 10219, 10222, 0,
-	/*10219*/ uint16(x86_xSetOp), uint16(x86_SCASW),
-	/*10221*/ uint16(x86_xMatch),
-	/*10222*/ uint16(x86_xSetOp), uint16(x86_SCASD),
-	/*10224*/ uint16(x86_xMatch),
-	/*10225*/ uint16(x86_xCondDataSize), 10219, 10222, 10229,
-	/*10229*/ uint16(x86_xSetOp), uint16(x86_SCASQ),
-	/*10231*/ uint16(x86_xMatch),
-	/*10232*/ uint16(x86_xSetOp), uint16(x86_MOV),
-	/*10234*/ uint16(x86_xReadIb),
-	/*10235*/ uint16(x86_xArgR8op),
-	/*10236*/ uint16(x86_xArgImm8u),
-	/*10237*/ uint16(x86_xMatch),
-	/*10238*/ uint16(x86_xCondIs64), 10241, 10257,
-	/*10241*/ uint16(x86_xCondDataSize), 10245, 10251, 0,
-	/*10245*/ uint16(x86_xSetOp), uint16(x86_MOV),
-	/*10247*/ uint16(x86_xReadIw),
-	/*10248*/ uint16(x86_xArgR16op),
-	/*10249*/ uint16(x86_xArgImm16),
-	/*10250*/ uint16(x86_xMatch),
-	/*10251*/ uint16(x86_xSetOp), uint16(x86_MOV),
-	/*10253*/ uint16(x86_xReadId),
-	/*10254*/ uint16(x86_xArgR32op),
-	/*10255*/ uint16(x86_xArgImm32),
-	/*10256*/ uint16(x86_xMatch),
-	/*10257*/ uint16(x86_xCondDataSize), 10245, 10251, 10261,
-	/*10261*/ uint16(x86_xSetOp), uint16(x86_MOV),
-	/*10263*/ uint16(x86_xReadIo),
-	/*10264*/ uint16(x86_xArgR64op),
-	/*10265*/ uint16(x86_xArgImm64),
-	/*10266*/ uint16(x86_xMatch),
-	/*10267*/ uint16(x86_xCondSlashR),
-	10276, // 0
-	10282, // 1
-	10288, // 2
-	10294, // 3
-	10300, // 4
-	10306, // 5
-	0,     // 6
-	10312, // 7
-	/*10276*/ uint16(x86_xSetOp), uint16(x86_ROL),
-	/*10278*/ uint16(x86_xReadIb),
-	/*10279*/ uint16(x86_xArgRM8),
-	/*10280*/ uint16(x86_xArgImm8u),
-	/*10281*/ uint16(x86_xMatch),
-	/*10282*/ uint16(x86_xSetOp), uint16(x86_ROR),
-	/*10284*/ uint16(x86_xReadIb),
-	/*10285*/ uint16(x86_xArgRM8),
-	/*10286*/ uint16(x86_xArgImm8u),
-	/*10287*/ uint16(x86_xMatch),
-	/*10288*/ uint16(x86_xSetOp), uint16(x86_RCL),
-	/*10290*/ uint16(x86_xReadIb),
-	/*10291*/ uint16(x86_xArgRM8),
-	/*10292*/ uint16(x86_xArgImm8u),
-	/*10293*/ uint16(x86_xMatch),
-	/*10294*/ uint16(x86_xSetOp), uint16(x86_RCR),
-	/*10296*/ uint16(x86_xReadIb),
-	/*10297*/ uint16(x86_xArgRM8),
-	/*10298*/ uint16(x86_xArgImm8u),
-	/*10299*/ uint16(x86_xMatch),
-	/*10300*/ uint16(x86_xSetOp), uint16(x86_SHL),
-	/*10302*/ uint16(x86_xReadIb),
-	/*10303*/ uint16(x86_xArgRM8),
-	/*10304*/ uint16(x86_xArgImm8u),
-	/*10305*/ uint16(x86_xMatch),
-	/*10306*/ uint16(x86_xSetOp), uint16(x86_SHR),
-	/*10308*/ uint16(x86_xReadIb),
-	/*10309*/ uint16(x86_xArgRM8),
-	/*10310*/ uint16(x86_xArgImm8u),
-	/*10311*/ uint16(x86_xMatch),
-	/*10312*/ uint16(x86_xSetOp), uint16(x86_SAR),
-	/*10314*/ uint16(x86_xReadIb),
-	/*10315*/ uint16(x86_xArgRM8),
-	/*10316*/ uint16(x86_xArgImm8u),
-	/*10317*/ uint16(x86_xMatch),
-	/*10318*/ uint16(x86_xCondSlashR),
-	10327, // 0
-	10349, // 1
-	10371, // 2
-	10400, // 3
-	10429, // 4
-	10458, // 5
-	0,     // 6
-	10487, // 7
-	/*10327*/ uint16(x86_xCondDataSize), 10331, 10337, 10343,
-	/*10331*/ uint16(x86_xSetOp), uint16(x86_ROL),
-	/*10333*/ uint16(x86_xReadIb),
-	/*10334*/ uint16(x86_xArgRM16),
-	/*10335*/ uint16(x86_xArgImm8u),
-	/*10336*/ uint16(x86_xMatch),
-	/*10337*/ uint16(x86_xSetOp), uint16(x86_ROL),
-	/*10339*/ uint16(x86_xReadIb),
-	/*10340*/ uint16(x86_xArgRM32),
-	/*10341*/ uint16(x86_xArgImm8u),
-	/*10342*/ uint16(x86_xMatch),
-	/*10343*/ uint16(x86_xSetOp), uint16(x86_ROL),
-	/*10345*/ uint16(x86_xReadIb),
-	/*10346*/ uint16(x86_xArgRM64),
-	/*10347*/ uint16(x86_xArgImm8u),
-	/*10348*/ uint16(x86_xMatch),
-	/*10349*/ uint16(x86_xCondDataSize), 10353, 10359, 10365,
-	/*10353*/ uint16(x86_xSetOp), uint16(x86_ROR),
-	/*10355*/ uint16(x86_xReadIb),
-	/*10356*/ uint16(x86_xArgRM16),
-	/*10357*/ uint16(x86_xArgImm8u),
-	/*10358*/ uint16(x86_xMatch),
-	/*10359*/ uint16(x86_xSetOp), uint16(x86_ROR),
-	/*10361*/ uint16(x86_xReadIb),
-	/*10362*/ uint16(x86_xArgRM32),
-	/*10363*/ uint16(x86_xArgImm8u),
-	/*10364*/ uint16(x86_xMatch),
-	/*10365*/ uint16(x86_xSetOp), uint16(x86_ROR),
-	/*10367*/ uint16(x86_xReadIb),
-	/*10368*/ uint16(x86_xArgRM64),
-	/*10369*/ uint16(x86_xArgImm8u),
-	/*10370*/ uint16(x86_xMatch),
-	/*10371*/ uint16(x86_xCondIs64), 10374, 10390,
-	/*10374*/ uint16(x86_xCondDataSize), 10378, 10384, 0,
-	/*10378*/ uint16(x86_xSetOp), uint16(x86_RCL),
-	/*10380*/ uint16(x86_xReadIb),
-	/*10381*/ uint16(x86_xArgRM16),
-	/*10382*/ uint16(x86_xArgImm8u),
-	/*10383*/ uint16(x86_xMatch),
-	/*10384*/ uint16(x86_xSetOp), uint16(x86_RCL),
-	/*10386*/ uint16(x86_xReadIb),
-	/*10387*/ uint16(x86_xArgRM32),
-	/*10388*/ uint16(x86_xArgImm8u),
-	/*10389*/ uint16(x86_xMatch),
-	/*10390*/ uint16(x86_xCondDataSize), 10378, 10384, 10394,
-	/*10394*/ uint16(x86_xSetOp), uint16(x86_RCL),
-	/*10396*/ uint16(x86_xReadIb),
-	/*10397*/ uint16(x86_xArgRM64),
-	/*10398*/ uint16(x86_xArgImm8u),
-	/*10399*/ uint16(x86_xMatch),
-	/*10400*/ uint16(x86_xCondIs64), 10403, 10419,
-	/*10403*/ uint16(x86_xCondDataSize), 10407, 10413, 0,
-	/*10407*/ uint16(x86_xSetOp), uint16(x86_RCR),
-	/*10409*/ uint16(x86_xReadIb),
-	/*10410*/ uint16(x86_xArgRM16),
-	/*10411*/ uint16(x86_xArgImm8u),
-	/*10412*/ uint16(x86_xMatch),
-	/*10413*/ uint16(x86_xSetOp), uint16(x86_RCR),
-	/*10415*/ uint16(x86_xReadIb),
-	/*10416*/ uint16(x86_xArgRM32),
-	/*10417*/ uint16(x86_xArgImm8u),
-	/*10418*/ uint16(x86_xMatch),
-	/*10419*/ uint16(x86_xCondDataSize), 10407, 10413, 10423,
-	/*10423*/ uint16(x86_xSetOp), uint16(x86_RCR),
-	/*10425*/ uint16(x86_xReadIb),
-	/*10426*/ uint16(x86_xArgRM64),
-	/*10427*/ uint16(x86_xArgImm8u),
-	/*10428*/ uint16(x86_xMatch),
-	/*10429*/ uint16(x86_xCondIs64), 10432, 10448,
-	/*10432*/ uint16(x86_xCondDataSize), 10436, 10442, 0,
-	/*10436*/ uint16(x86_xSetOp), uint16(x86_SHL),
-	/*10438*/ uint16(x86_xReadIb),
-	/*10439*/ uint16(x86_xArgRM16),
-	/*10440*/ uint16(x86_xArgImm8u),
-	/*10441*/ uint16(x86_xMatch),
-	/*10442*/ uint16(x86_xSetOp), uint16(x86_SHL),
-	/*10444*/ uint16(x86_xReadIb),
-	/*10445*/ uint16(x86_xArgRM32),
-	/*10446*/ uint16(x86_xArgImm8u),
-	/*10447*/ uint16(x86_xMatch),
-	/*10448*/ uint16(x86_xCondDataSize), 10436, 10442, 10452,
-	/*10452*/ uint16(x86_xSetOp), uint16(x86_SHL),
-	/*10454*/ uint16(x86_xReadIb),
-	/*10455*/ uint16(x86_xArgRM64),
-	/*10456*/ uint16(x86_xArgImm8u),
-	/*10457*/ uint16(x86_xMatch),
-	/*10458*/ uint16(x86_xCondIs64), 10461, 10477,
-	/*10461*/ uint16(x86_xCondDataSize), 10465, 10471, 0,
-	/*10465*/ uint16(x86_xSetOp), uint16(x86_SHR),
-	/*10467*/ uint16(x86_xReadIb),
-	/*10468*/ uint16(x86_xArgRM16),
-	/*10469*/ uint16(x86_xArgImm8u),
-	/*10470*/ uint16(x86_xMatch),
-	/*10471*/ uint16(x86_xSetOp), uint16(x86_SHR),
-	/*10473*/ uint16(x86_xReadIb),
-	/*10474*/ uint16(x86_xArgRM32),
-	/*10475*/ uint16(x86_xArgImm8u),
-	/*10476*/ uint16(x86_xMatch),
-	/*10477*/ uint16(x86_xCondDataSize), 10465, 10471, 10481,
-	/*10481*/ uint16(x86_xSetOp), uint16(x86_SHR),
-	/*10483*/ uint16(x86_xReadIb),
-	/*10484*/ uint16(x86_xArgRM64),
-	/*10485*/ uint16(x86_xArgImm8u),
-	/*10486*/ uint16(x86_xMatch),
-	/*10487*/ uint16(x86_xCondIs64), 10490, 10506,
-	/*10490*/ uint16(x86_xCondDataSize), 10494, 10500, 0,
-	/*10494*/ uint16(x86_xSetOp), uint16(x86_SAR),
-	/*10496*/ uint16(x86_xReadIb),
-	/*10497*/ uint16(x86_xArgRM16),
-	/*10498*/ uint16(x86_xArgImm8u),
-	/*10499*/ uint16(x86_xMatch),
-	/*10500*/ uint16(x86_xSetOp), uint16(x86_SAR),
-	/*10502*/ uint16(x86_xReadIb),
-	/*10503*/ uint16(x86_xArgRM32),
-	/*10504*/ uint16(x86_xArgImm8u),
-	/*10505*/ uint16(x86_xMatch),
-	/*10506*/ uint16(x86_xCondDataSize), 10494, 10500, 10510,
-	/*10510*/ uint16(x86_xSetOp), uint16(x86_SAR),
-	/*10512*/ uint16(x86_xReadIb),
-	/*10513*/ uint16(x86_xArgRM64),
-	/*10514*/ uint16(x86_xArgImm8u),
-	/*10515*/ uint16(x86_xMatch),
-	/*10516*/ uint16(x86_xSetOp), uint16(x86_RET),
-	/*10518*/ uint16(x86_xReadIw),
-	/*10519*/ uint16(x86_xArgImm16u),
-	/*10520*/ uint16(x86_xMatch),
-	/*10521*/ uint16(x86_xSetOp), uint16(x86_RET),
-	/*10523*/ uint16(x86_xMatch),
-	/*10524*/ uint16(x86_xCondIs64), 10527, 0,
-	/*10527*/ uint16(x86_xCondDataSize), 10531, 10537, 0,
-	/*10531*/ uint16(x86_xSetOp), uint16(x86_LES),
-	/*10533*/ uint16(x86_xReadSlashR),
-	/*10534*/ uint16(x86_xArgR16),
-	/*10535*/ uint16(x86_xArgM16colon16),
-	/*10536*/ uint16(x86_xMatch),
-	/*10537*/ uint16(x86_xSetOp), uint16(x86_LES),
-	/*10539*/ uint16(x86_xReadSlashR),
-	/*10540*/ uint16(x86_xArgR32),
-	/*10541*/ uint16(x86_xArgM16colon32),
-	/*10542*/ uint16(x86_xMatch),
-	/*10543*/ uint16(x86_xCondIs64), 10546, 0,
-	/*10546*/ uint16(x86_xCondDataSize), 10550, 10556, 0,
-	/*10550*/ uint16(x86_xSetOp), uint16(x86_LDS),
-	/*10552*/ uint16(x86_xReadSlashR),
-	/*10553*/ uint16(x86_xArgR16),
-	/*10554*/ uint16(x86_xArgM16colon16),
-	/*10555*/ uint16(x86_xMatch),
-	/*10556*/ uint16(x86_xSetOp), uint16(x86_LDS),
-	/*10558*/ uint16(x86_xReadSlashR),
-	/*10559*/ uint16(x86_xArgR32),
-	/*10560*/ uint16(x86_xArgM16colon32),
-	/*10561*/ uint16(x86_xMatch),
-	/*10562*/ uint16(x86_xCondByte), 1,
-	0xF8, 10581,
-	/*10566*/ uint16(x86_xCondSlashR),
-	10575, // 0
-	0,     // 1
-	0,     // 2
-	0,     // 3
-	0,     // 4
-	0,     // 5
-	0,     // 6
-	0,     // 7
-	/*10575*/ uint16(x86_xSetOp), uint16(x86_MOV),
-	/*10577*/ uint16(x86_xReadIb),
-	/*10578*/ uint16(x86_xArgRM8),
-	/*10579*/ uint16(x86_xArgImm8u),
-	/*10580*/ uint16(x86_xMatch),
-	/*10581*/ uint16(x86_xSetOp), uint16(x86_XABORT),
-	/*10583*/ uint16(x86_xReadIb),
-	/*10584*/ uint16(x86_xArgImm8u),
-	/*10585*/ uint16(x86_xMatch),
-	/*10586*/ uint16(x86_xCondByte), 1,
-	0xF8, 10628,
-	/*10590*/ uint16(x86_xCondSlashR),
-	10599, // 0
-	0,     // 1
-	0,     // 2
-	0,     // 3
-	0,     // 4
-	0,     // 5
-	0,     // 6
-	0,     // 7
-	/*10599*/ uint16(x86_xCondIs64), 10602, 10618,
-	/*10602*/ uint16(x86_xCondDataSize), 10606, 10612, 0,
-	/*10606*/ uint16(x86_xSetOp), uint16(x86_MOV),
-	/*10608*/ uint16(x86_xReadIw),
-	/*10609*/ uint16(x86_xArgRM16),
-	/*10610*/ uint16(x86_xArgImm16),
-	/*10611*/ uint16(x86_xMatch),
-	/*10612*/ uint16(x86_xSetOp), uint16(x86_MOV),
-	/*10614*/ uint16(x86_xReadId),
-	/*10615*/ uint16(x86_xArgRM32),
-	/*10616*/ uint16(x86_xArgImm32),
-	/*10617*/ uint16(x86_xMatch),
-	/*10618*/ uint16(x86_xCondDataSize), 10606, 10612, 10622,
-	/*10622*/ uint16(x86_xSetOp), uint16(x86_MOV),
-	/*10624*/ uint16(x86_xReadId),
-	/*10625*/ uint16(x86_xArgRM64),
-	/*10626*/ uint16(x86_xArgImm32),
-	/*10627*/ uint16(x86_xMatch),
-	/*10628*/ uint16(x86_xCondDataSize), 10632, 10637, 10642,
-	/*10632*/ uint16(x86_xSetOp), uint16(x86_XBEGIN),
-	/*10634*/ uint16(x86_xReadCw),
-	/*10635*/ uint16(x86_xArgRel16),
-	/*10636*/ uint16(x86_xMatch),
-	/*10637*/ uint16(x86_xSetOp), uint16(x86_XBEGIN),
-	/*10639*/ uint16(x86_xReadCd),
-	/*10640*/ uint16(x86_xArgRel32),
-	/*10641*/ uint16(x86_xMatch),
-	/*10642*/ uint16(x86_xSetOp), uint16(x86_XBEGIN),
-	/*10644*/ uint16(x86_xReadCd),
-	/*10645*/ uint16(x86_xArgRel32),
-	/*10646*/ uint16(x86_xMatch),
-	/*10647*/ uint16(x86_xSetOp), uint16(x86_ENTER),
-	/*10649*/ uint16(x86_xReadIw),
-	/*10650*/ uint16(x86_xReadIb),
-	/*10651*/ uint16(x86_xArgImm16u),
-	/*10652*/ uint16(x86_xArgImm8u),
-	/*10653*/ uint16(x86_xMatch),
-	/*10654*/ uint16(x86_xCondIs64), 10657, 10667,
-	/*10657*/ uint16(x86_xCondDataSize), 10661, 10664, 0,
-	/*10661*/ uint16(x86_xSetOp), uint16(x86_LEAVE),
-	/*10663*/ uint16(x86_xMatch),
-	/*10664*/ uint16(x86_xSetOp), uint16(x86_LEAVE),
-	/*10666*/ uint16(x86_xMatch),
-	/*10667*/ uint16(x86_xCondDataSize), 10661, 10671, 10674,
-	/*10671*/ uint16(x86_xSetOp), uint16(x86_LEAVE),
-	/*10673*/ uint16(x86_xMatch),
-	/*10674*/ uint16(x86_xSetOp), uint16(x86_LEAVE),
-	/*10676*/ uint16(x86_xMatch),
-	/*10677*/ uint16(x86_xSetOp), uint16(x86_LRET),
-	/*10679*/ uint16(x86_xReadIw),
-	/*10680*/ uint16(x86_xArgImm16u),
-	/*10681*/ uint16(x86_xMatch),
-	/*10682*/ uint16(x86_xSetOp), uint16(x86_LRET),
-	/*10684*/ uint16(x86_xMatch),
-	/*10685*/ uint16(x86_xSetOp), uint16(x86_INT),
-	/*10687*/ uint16(x86_xArg3),
-	/*10688*/ uint16(x86_xMatch),
-	/*10689*/ uint16(x86_xSetOp), uint16(x86_INT),
-	/*10691*/ uint16(x86_xReadIb),
-	/*10692*/ uint16(x86_xArgImm8u),
-	/*10693*/ uint16(x86_xMatch),
-	/*10694*/ uint16(x86_xCondIs64), 10697, 0,
-	/*10697*/ uint16(x86_xSetOp), uint16(x86_INTO),
-	/*10699*/ uint16(x86_xMatch),
-	/*10700*/ uint16(x86_xCondIs64), 10703, 10713,
-	/*10703*/ uint16(x86_xCondDataSize), 10707, 10710, 0,
-	/*10707*/ uint16(x86_xSetOp), uint16(x86_IRET),
-	/*10709*/ uint16(x86_xMatch),
-	/*10710*/ uint16(x86_xSetOp), uint16(x86_IRETD),
-	/*10712*/ uint16(x86_xMatch),
-	/*10713*/ uint16(x86_xCondDataSize), 10707, 10710, 10717,
-	/*10717*/ uint16(x86_xSetOp), uint16(x86_IRETQ),
-	/*10719*/ uint16(x86_xMatch),
-	/*10720*/ uint16(x86_xCondSlashR),
-	10729, // 0
-	10734, // 1
-	10739, // 2
-	10744, // 3
-	10749, // 4
-	10754, // 5
-	0,     // 6
-	10759, // 7
-	/*10729*/ uint16(x86_xSetOp), uint16(x86_ROL),
-	/*10731*/ uint16(x86_xArgRM8),
-	/*10732*/ uint16(x86_xArg1),
-	/*10733*/ uint16(x86_xMatch),
-	/*10734*/ uint16(x86_xSetOp), uint16(x86_ROR),
-	/*10736*/ uint16(x86_xArgRM8),
-	/*10737*/ uint16(x86_xArg1),
-	/*10738*/ uint16(x86_xMatch),
-	/*10739*/ uint16(x86_xSetOp), uint16(x86_RCL),
-	/*10741*/ uint16(x86_xArgRM8),
-	/*10742*/ uint16(x86_xArg1),
-	/*10743*/ uint16(x86_xMatch),
-	/*10744*/ uint16(x86_xSetOp), uint16(x86_RCR),
-	/*10746*/ uint16(x86_xArgRM8),
-	/*10747*/ uint16(x86_xArg1),
-	/*10748*/ uint16(x86_xMatch),
-	/*10749*/ uint16(x86_xSetOp), uint16(x86_SHL),
-	/*10751*/ uint16(x86_xArgRM8),
-	/*10752*/ uint16(x86_xArg1),
-	/*10753*/ uint16(x86_xMatch),
-	/*10754*/ uint16(x86_xSetOp), uint16(x86_SHR),
-	/*10756*/ uint16(x86_xArgRM8),
-	/*10757*/ uint16(x86_xArg1),
-	/*10758*/ uint16(x86_xMatch),
-	/*10759*/ uint16(x86_xSetOp), uint16(x86_SAR),
-	/*10761*/ uint16(x86_xArgRM8),
-	/*10762*/ uint16(x86_xArg1),
-	/*10763*/ uint16(x86_xMatch),
-	/*10764*/ uint16(x86_xCondSlashR),
-	10773, // 0
-	10799, // 1
-	10825, // 2
-	10851, // 3
-	10877, // 4
-	10903, // 5
-	0,     // 6
-	10929, // 7
-	/*10773*/ uint16(x86_xCondIs64), 10776, 10790,
-	/*10776*/ uint16(x86_xCondDataSize), 10780, 10785, 0,
-	/*10780*/ uint16(x86_xSetOp), uint16(x86_ROL),
-	/*10782*/ uint16(x86_xArgRM16),
-	/*10783*/ uint16(x86_xArg1),
-	/*10784*/ uint16(x86_xMatch),
-	/*10785*/ uint16(x86_xSetOp), uint16(x86_ROL),
-	/*10787*/ uint16(x86_xArgRM32),
-	/*10788*/ uint16(x86_xArg1),
-	/*10789*/ uint16(x86_xMatch),
-	/*10790*/ uint16(x86_xCondDataSize), 10780, 10785, 10794,
-	/*10794*/ uint16(x86_xSetOp), uint16(x86_ROL),
-	/*10796*/ uint16(x86_xArgRM64),
-	/*10797*/ uint16(x86_xArg1),
-	/*10798*/ uint16(x86_xMatch),
-	/*10799*/ uint16(x86_xCondIs64), 10802, 10816,
-	/*10802*/ uint16(x86_xCondDataSize), 10806, 10811, 0,
-	/*10806*/ uint16(x86_xSetOp), uint16(x86_ROR),
-	/*10808*/ uint16(x86_xArgRM16),
-	/*10809*/ uint16(x86_xArg1),
-	/*10810*/ uint16(x86_xMatch),
-	/*10811*/ uint16(x86_xSetOp), uint16(x86_ROR),
-	/*10813*/ uint16(x86_xArgRM32),
-	/*10814*/ uint16(x86_xArg1),
-	/*10815*/ uint16(x86_xMatch),
-	/*10816*/ uint16(x86_xCondDataSize), 10806, 10811, 10820,
-	/*10820*/ uint16(x86_xSetOp), uint16(x86_ROR),
-	/*10822*/ uint16(x86_xArgRM64),
-	/*10823*/ uint16(x86_xArg1),
-	/*10824*/ uint16(x86_xMatch),
-	/*10825*/ uint16(x86_xCondIs64), 10828, 10842,
-	/*10828*/ uint16(x86_xCondDataSize), 10832, 10837, 0,
-	/*10832*/ uint16(x86_xSetOp), uint16(x86_RCL),
-	/*10834*/ uint16(x86_xArgRM16),
-	/*10835*/ uint16(x86_xArg1),
-	/*10836*/ uint16(x86_xMatch),
-	/*10837*/ uint16(x86_xSetOp), uint16(x86_RCL),
-	/*10839*/ uint16(x86_xArgRM32),
-	/*10840*/ uint16(x86_xArg1),
-	/*10841*/ uint16(x86_xMatch),
-	/*10842*/ uint16(x86_xCondDataSize), 10832, 10837, 10846,
-	/*10846*/ uint16(x86_xSetOp), uint16(x86_RCL),
-	/*10848*/ uint16(x86_xArgRM64),
-	/*10849*/ uint16(x86_xArg1),
-	/*10850*/ uint16(x86_xMatch),
-	/*10851*/ uint16(x86_xCondIs64), 10854, 10868,
-	/*10854*/ uint16(x86_xCondDataSize), 10858, 10863, 0,
-	/*10858*/ uint16(x86_xSetOp), uint16(x86_RCR),
-	/*10860*/ uint16(x86_xArgRM16),
-	/*10861*/ uint16(x86_xArg1),
-	/*10862*/ uint16(x86_xMatch),
-	/*10863*/ uint16(x86_xSetOp), uint16(x86_RCR),
-	/*10865*/ uint16(x86_xArgRM32),
-	/*10866*/ uint16(x86_xArg1),
-	/*10867*/ uint16(x86_xMatch),
-	/*10868*/ uint16(x86_xCondDataSize), 10858, 10863, 10872,
-	/*10872*/ uint16(x86_xSetOp), uint16(x86_RCR),
-	/*10874*/ uint16(x86_xArgRM64),
-	/*10875*/ uint16(x86_xArg1),
-	/*10876*/ uint16(x86_xMatch),
-	/*10877*/ uint16(x86_xCondIs64), 10880, 10894,
-	/*10880*/ uint16(x86_xCondDataSize), 10884, 10889, 0,
-	/*10884*/ uint16(x86_xSetOp), uint16(x86_SHL),
-	/*10886*/ uint16(x86_xArgRM16),
-	/*10887*/ uint16(x86_xArg1),
-	/*10888*/ uint16(x86_xMatch),
-	/*10889*/ uint16(x86_xSetOp), uint16(x86_SHL),
-	/*10891*/ uint16(x86_xArgRM32),
-	/*10892*/ uint16(x86_xArg1),
-	/*10893*/ uint16(x86_xMatch),
-	/*10894*/ uint16(x86_xCondDataSize), 10884, 10889, 10898,
-	/*10898*/ uint16(x86_xSetOp), uint16(x86_SHL),
-	/*10900*/ uint16(x86_xArgRM64),
-	/*10901*/ uint16(x86_xArg1),
-	/*10902*/ uint16(x86_xMatch),
-	/*10903*/ uint16(x86_xCondIs64), 10906, 10920,
-	/*10906*/ uint16(x86_xCondDataSize), 10910, 10915, 0,
-	/*10910*/ uint16(x86_xSetOp), uint16(x86_SHR),
-	/*10912*/ uint16(x86_xArgRM16),
-	/*10913*/ uint16(x86_xArg1),
-	/*10914*/ uint16(x86_xMatch),
-	/*10915*/ uint16(x86_xSetOp), uint16(x86_SHR),
-	/*10917*/ uint16(x86_xArgRM32),
-	/*10918*/ uint16(x86_xArg1),
-	/*10919*/ uint16(x86_xMatch),
-	/*10920*/ uint16(x86_xCondDataSize), 10910, 10915, 10924,
-	/*10924*/ uint16(x86_xSetOp), uint16(x86_SHR),
-	/*10926*/ uint16(x86_xArgRM64),
-	/*10927*/ uint16(x86_xArg1),
-	/*10928*/ uint16(x86_xMatch),
-	/*10929*/ uint16(x86_xCondIs64), 10932, 10946,
-	/*10932*/ uint16(x86_xCondDataSize), 10936, 10941, 0,
-	/*10936*/ uint16(x86_xSetOp), uint16(x86_SAR),
-	/*10938*/ uint16(x86_xArgRM16),
-	/*10939*/ uint16(x86_xArg1),
-	/*10940*/ uint16(x86_xMatch),
-	/*10941*/ uint16(x86_xSetOp), uint16(x86_SAR),
-	/*10943*/ uint16(x86_xArgRM32),
-	/*10944*/ uint16(x86_xArg1),
-	/*10945*/ uint16(x86_xMatch),
-	/*10946*/ uint16(x86_xCondDataSize), 10936, 10941, 10950,
-	/*10950*/ uint16(x86_xSetOp), uint16(x86_SAR),
-	/*10952*/ uint16(x86_xArgRM64),
-	/*10953*/ uint16(x86_xArg1),
-	/*10954*/ uint16(x86_xMatch),
-	/*10955*/ uint16(x86_xCondSlashR),
-	10964, // 0
-	10969, // 1
-	10974, // 2
-	10979, // 3
-	10984, // 4
-	10989, // 5
-	0,     // 6
-	10994, // 7
-	/*10964*/ uint16(x86_xSetOp), uint16(x86_ROL),
-	/*10966*/ uint16(x86_xArgRM8),
-	/*10967*/ uint16(x86_xArgCL),
-	/*10968*/ uint16(x86_xMatch),
-	/*10969*/ uint16(x86_xSetOp), uint16(x86_ROR),
-	/*10971*/ uint16(x86_xArgRM8),
-	/*10972*/ uint16(x86_xArgCL),
-	/*10973*/ uint16(x86_xMatch),
-	/*10974*/ uint16(x86_xSetOp), uint16(x86_RCL),
-	/*10976*/ uint16(x86_xArgRM8),
-	/*10977*/ uint16(x86_xArgCL),
-	/*10978*/ uint16(x86_xMatch),
-	/*10979*/ uint16(x86_xSetOp), uint16(x86_RCR),
-	/*10981*/ uint16(x86_xArgRM8),
-	/*10982*/ uint16(x86_xArgCL),
-	/*10983*/ uint16(x86_xMatch),
-	/*10984*/ uint16(x86_xSetOp), uint16(x86_SHL),
-	/*10986*/ uint16(x86_xArgRM8),
-	/*10987*/ uint16(x86_xArgCL),
-	/*10988*/ uint16(x86_xMatch),
-	/*10989*/ uint16(x86_xSetOp), uint16(x86_SHR),
-	/*10991*/ uint16(x86_xArgRM8),
-	/*10992*/ uint16(x86_xArgCL),
-	/*10993*/ uint16(x86_xMatch),
-	/*10994*/ uint16(x86_xSetOp), uint16(x86_SAR),
-	/*10996*/ uint16(x86_xArgRM8),
-	/*10997*/ uint16(x86_xArgCL),
-	/*10998*/ uint16(x86_xMatch),
-	/*10999*/ uint16(x86_xCondSlashR),
-	11008, // 0
-	11034, // 1
-	11060, // 2
-	11086, // 3
-	11112, // 4
-	11138, // 5
-	0,     // 6
-	11164, // 7
-	/*11008*/ uint16(x86_xCondIs64), 11011, 11025,
-	/*11011*/ uint16(x86_xCondDataSize), 11015, 11020, 0,
-	/*11015*/ uint16(x86_xSetOp), uint16(x86_ROL),
-	/*11017*/ uint16(x86_xArgRM16),
-	/*11018*/ uint16(x86_xArgCL),
-	/*11019*/ uint16(x86_xMatch),
-	/*11020*/ uint16(x86_xSetOp), uint16(x86_ROL),
-	/*11022*/ uint16(x86_xArgRM32),
-	/*11023*/ uint16(x86_xArgCL),
-	/*11024*/ uint16(x86_xMatch),
-	/*11025*/ uint16(x86_xCondDataSize), 11015, 11020, 11029,
-	/*11029*/ uint16(x86_xSetOp), uint16(x86_ROL),
-	/*11031*/ uint16(x86_xArgRM64),
-	/*11032*/ uint16(x86_xArgCL),
-	/*11033*/ uint16(x86_xMatch),
-	/*11034*/ uint16(x86_xCondIs64), 11037, 11051,
-	/*11037*/ uint16(x86_xCondDataSize), 11041, 11046, 0,
-	/*11041*/ uint16(x86_xSetOp), uint16(x86_ROR),
-	/*11043*/ uint16(x86_xArgRM16),
-	/*11044*/ uint16(x86_xArgCL),
-	/*11045*/ uint16(x86_xMatch),
-	/*11046*/ uint16(x86_xSetOp), uint16(x86_ROR),
-	/*11048*/ uint16(x86_xArgRM32),
-	/*11049*/ uint16(x86_xArgCL),
-	/*11050*/ uint16(x86_xMatch),
-	/*11051*/ uint16(x86_xCondDataSize), 11041, 11046, 11055,
-	/*11055*/ uint16(x86_xSetOp), uint16(x86_ROR),
-	/*11057*/ uint16(x86_xArgRM64),
-	/*11058*/ uint16(x86_xArgCL),
-	/*11059*/ uint16(x86_xMatch),
-	/*11060*/ uint16(x86_xCondIs64), 11063, 11077,
-	/*11063*/ uint16(x86_xCondDataSize), 11067, 11072, 0,
-	/*11067*/ uint16(x86_xSetOp), uint16(x86_RCL),
-	/*11069*/ uint16(x86_xArgRM16),
-	/*11070*/ uint16(x86_xArgCL),
-	/*11071*/ uint16(x86_xMatch),
-	/*11072*/ uint16(x86_xSetOp), uint16(x86_RCL),
-	/*11074*/ uint16(x86_xArgRM32),
-	/*11075*/ uint16(x86_xArgCL),
-	/*11076*/ uint16(x86_xMatch),
-	/*11077*/ uint16(x86_xCondDataSize), 11067, 11072, 11081,
-	/*11081*/ uint16(x86_xSetOp), uint16(x86_RCL),
-	/*11083*/ uint16(x86_xArgRM64),
-	/*11084*/ uint16(x86_xArgCL),
-	/*11085*/ uint16(x86_xMatch),
-	/*11086*/ uint16(x86_xCondIs64), 11089, 11103,
-	/*11089*/ uint16(x86_xCondDataSize), 11093, 11098, 0,
-	/*11093*/ uint16(x86_xSetOp), uint16(x86_RCR),
-	/*11095*/ uint16(x86_xArgRM16),
-	/*11096*/ uint16(x86_xArgCL),
-	/*11097*/ uint16(x86_xMatch),
-	/*11098*/ uint16(x86_xSetOp), uint16(x86_RCR),
-	/*11100*/ uint16(x86_xArgRM32),
-	/*11101*/ uint16(x86_xArgCL),
-	/*11102*/ uint16(x86_xMatch),
-	/*11103*/ uint16(x86_xCondDataSize), 11093, 11098, 11107,
-	/*11107*/ uint16(x86_xSetOp), uint16(x86_RCR),
-	/*11109*/ uint16(x86_xArgRM64),
-	/*11110*/ uint16(x86_xArgCL),
-	/*11111*/ uint16(x86_xMatch),
-	/*11112*/ uint16(x86_xCondIs64), 11115, 11129,
-	/*11115*/ uint16(x86_xCondDataSize), 11119, 11124, 0,
-	/*11119*/ uint16(x86_xSetOp), uint16(x86_SHL),
-	/*11121*/ uint16(x86_xArgRM16),
-	/*11122*/ uint16(x86_xArgCL),
-	/*11123*/ uint16(x86_xMatch),
-	/*11124*/ uint16(x86_xSetOp), uint16(x86_SHL),
-	/*11126*/ uint16(x86_xArgRM32),
-	/*11127*/ uint16(x86_xArgCL),
-	/*11128*/ uint16(x86_xMatch),
-	/*11129*/ uint16(x86_xCondDataSize), 11119, 11124, 11133,
-	/*11133*/ uint16(x86_xSetOp), uint16(x86_SHL),
-	/*11135*/ uint16(x86_xArgRM64),
-	/*11136*/ uint16(x86_xArgCL),
-	/*11137*/ uint16(x86_xMatch),
-	/*11138*/ uint16(x86_xCondIs64), 11141, 11155,
-	/*11141*/ uint16(x86_xCondDataSize), 11145, 11150, 0,
-	/*11145*/ uint16(x86_xSetOp), uint16(x86_SHR),
-	/*11147*/ uint16(x86_xArgRM16),
-	/*11148*/ uint16(x86_xArgCL),
-	/*11149*/ uint16(x86_xMatch),
-	/*11150*/ uint16(x86_xSetOp), uint16(x86_SHR),
-	/*11152*/ uint16(x86_xArgRM32),
-	/*11153*/ uint16(x86_xArgCL),
-	/*11154*/ uint16(x86_xMatch),
-	/*11155*/ uint16(x86_xCondDataSize), 11145, 11150, 11159,
-	/*11159*/ uint16(x86_xSetOp), uint16(x86_SHR),
-	/*11161*/ uint16(x86_xArgRM64),
-	/*11162*/ uint16(x86_xArgCL),
-	/*11163*/ uint16(x86_xMatch),
-	/*11164*/ uint16(x86_xCondIs64), 11167, 11181,
-	/*11167*/ uint16(x86_xCondDataSize), 11171, 11176, 0,
-	/*11171*/ uint16(x86_xSetOp), uint16(x86_SAR),
-	/*11173*/ uint16(x86_xArgRM16),
-	/*11174*/ uint16(x86_xArgCL),
-	/*11175*/ uint16(x86_xMatch),
-	/*11176*/ uint16(x86_xSetOp), uint16(x86_SAR),
-	/*11178*/ uint16(x86_xArgRM32),
-	/*11179*/ uint16(x86_xArgCL),
-	/*11180*/ uint16(x86_xMatch),
-	/*11181*/ uint16(x86_xCondDataSize), 11171, 11176, 11185,
-	/*11185*/ uint16(x86_xSetOp), uint16(x86_SAR),
-	/*11187*/ uint16(x86_xArgRM64),
-	/*11188*/ uint16(x86_xArgCL),
-	/*11189*/ uint16(x86_xMatch),
-	/*11190*/ uint16(x86_xCondIs64), 11193, 0,
-	/*11193*/ uint16(x86_xSetOp), uint16(x86_AAM),
-	/*11195*/ uint16(x86_xReadIb),
-	/*11196*/ uint16(x86_xArgImm8u),
-	/*11197*/ uint16(x86_xMatch),
-	/*11198*/ uint16(x86_xCondIs64), 11201, 0,
-	/*11201*/ uint16(x86_xSetOp), uint16(x86_AAD),
-	/*11203*/ uint16(x86_xReadIb),
-	/*11204*/ uint16(x86_xArgImm8u),
-	/*11205*/ uint16(x86_xMatch),
-	/*11206*/ uint16(x86_xCondIs64), 11209, 11212,
-	/*11209*/ uint16(x86_xSetOp), uint16(x86_XLATB),
-	/*11211*/ uint16(x86_xMatch),
-	/*11212*/ uint16(x86_xCondDataSize), 11209, 11209, 11216,
-	/*11216*/ uint16(x86_xSetOp), uint16(x86_XLATB),
-	/*11218*/ uint16(x86_xMatch),
-	/*11219*/ uint16(x86_xCondByte), 64,
-	0xc0, 11390,
-	0xc1, 11390,
-	0xc2, 11390,
-	0xc3, 11390,
-	0xc4, 11390,
-	0xc5, 11390,
-	0xc6, 11390,
-	0xc7, 11390,
-	0xc8, 11395,
-	0xc9, 11395,
-	0xca, 11395,
-	0xcb, 11395,
-	0xcc, 11395,
-	0xcd, 11395,
-	0xce, 11395,
-	0xcf, 11395,
-	0xd0, 11400,
-	0xd1, 11400,
-	0xd2, 11400,
-	0xd3, 11400,
-	0xd4, 11400,
-	0xd5, 11400,
-	0xd6, 11400,
-	0xd7, 11400,
-	0xd8, 11404,
-	0xd9, 11404,
-	0xda, 11404,
-	0xdb, 11404,
-	0xdc, 11404,
-	0xdd, 11404,
-	0xde, 11404,
-	0xdf, 11404,
-	0xe0, 11408,
-	0xe1, 11408,
-	0xe2, 11408,
-	0xe3, 11408,
-	0xe4, 11408,
-	0xe5, 11408,
-	0xe6, 11408,
-	0xe7, 11408,
-	0xe8, 11413,
-	0xe9, 11413,
-	0xea, 11413,
-	0xeb, 11413,
-	0xec, 11413,
-	0xed, 11413,
-	0xee, 11413,
-	0xef, 11413,
-	0xf0, 11418,
-	0xf1, 11418,
-	0xf2, 11418,
-	0xf3, 11418,
-	0xf4, 11418,
-	0xf5, 11418,
-	0xf6, 11418,
-	0xf7, 11418,
-	0xf8, 11423,
-	0xf9, 11423,
-	0xfa, 11423,
-	0xfb, 11423,
-	0xfc, 11423,
-	0xfd, 11423,
-	0xfe, 11423,
-	0xff, 11423,
-	/*11349*/ uint16(x86_xCondSlashR),
-	11358, // 0
-	11362, // 1
-	11366, // 2
-	11370, // 3
-	11374, // 4
-	11378, // 5
-	11382, // 6
-	11386, // 7
-	/*11358*/ uint16(x86_xSetOp), uint16(x86_FADD),
-	/*11360*/ uint16(x86_xArgM32fp),
-	/*11361*/ uint16(x86_xMatch),
-	/*11362*/ uint16(x86_xSetOp), uint16(x86_FMUL),
-	/*11364*/ uint16(x86_xArgM32fp),
-	/*11365*/ uint16(x86_xMatch),
-	/*11366*/ uint16(x86_xSetOp), uint16(x86_FCOM),
-	/*11368*/ uint16(x86_xArgM32fp),
-	/*11369*/ uint16(x86_xMatch),
-	/*11370*/ uint16(x86_xSetOp), uint16(x86_FCOMP),
-	/*11372*/ uint16(x86_xArgM32fp),
-	/*11373*/ uint16(x86_xMatch),
-	/*11374*/ uint16(x86_xSetOp), uint16(x86_FSUB),
-	/*11376*/ uint16(x86_xArgM32fp),
-	/*11377*/ uint16(x86_xMatch),
-	/*11378*/ uint16(x86_xSetOp), uint16(x86_FSUBR),
-	/*11380*/ uint16(x86_xArgM32fp),
-	/*11381*/ uint16(x86_xMatch),
-	/*11382*/ uint16(x86_xSetOp), uint16(x86_FDIV),
-	/*11384*/ uint16(x86_xArgM32fp),
-	/*11385*/ uint16(x86_xMatch),
-	/*11386*/ uint16(x86_xSetOp), uint16(x86_FDIVR),
-	/*11388*/ uint16(x86_xArgM32fp),
-	/*11389*/ uint16(x86_xMatch),
-	/*11390*/ uint16(x86_xSetOp), uint16(x86_FADD),
-	/*11392*/ uint16(x86_xArgST),
-	/*11393*/ uint16(x86_xArgSTi),
-	/*11394*/ uint16(x86_xMatch),
-	/*11395*/ uint16(x86_xSetOp), uint16(x86_FMUL),
-	/*11397*/ uint16(x86_xArgST),
-	/*11398*/ uint16(x86_xArgSTi),
-	/*11399*/ uint16(x86_xMatch),
-	/*11400*/ uint16(x86_xSetOp), uint16(x86_FCOM),
-	/*11402*/ uint16(x86_xArgSTi),
-	/*11403*/ uint16(x86_xMatch),
-	/*11404*/ uint16(x86_xSetOp), uint16(x86_FCOMP),
-	/*11406*/ uint16(x86_xArgSTi),
-	/*11407*/ uint16(x86_xMatch),
-	/*11408*/ uint16(x86_xSetOp), uint16(x86_FSUB),
-	/*11410*/ uint16(x86_xArgST),
-	/*11411*/ uint16(x86_xArgSTi),
-	/*11412*/ uint16(x86_xMatch),
-	/*11413*/ uint16(x86_xSetOp), uint16(x86_FSUBR),
-	/*11415*/ uint16(x86_xArgST),
-	/*11416*/ uint16(x86_xArgSTi),
-	/*11417*/ uint16(x86_xMatch),
-	/*11418*/ uint16(x86_xSetOp), uint16(x86_FDIV),
-	/*11420*/ uint16(x86_xArgST),
-	/*11421*/ uint16(x86_xArgSTi),
-	/*11422*/ uint16(x86_xMatch),
-	/*11423*/ uint16(x86_xSetOp), uint16(x86_FDIVR),
-	/*11425*/ uint16(x86_xArgST),
-	/*11426*/ uint16(x86_xArgSTi),
-	/*11427*/ uint16(x86_xMatch),
-	/*11428*/ uint16(x86_xCondByte), 42,
-	0xc0, 11551,
-	0xc1, 11551,
-	0xc2, 11551,
-	0xc3, 11551,
-	0xc4, 11551,
-	0xc5, 11551,
-	0xc6, 11551,
-	0xc7, 11551,
-	0xc8, 11555,
-	0xc9, 11555,
-	0xca, 11555,
-	0xcb, 11555,
-	0xcc, 11555,
-	0xcd, 11555,
-	0xce, 11555,
-	0xcf, 11555,
-	0xD0, 11559,
-	0xE0, 11562,
-	0xE1, 11565,
-	0xE4, 11568,
-	0xE5, 11571,
-	0xE8, 11574,
-	0xE9, 11577,
-	0xEA, 11580,
-	0xEB, 11583,
-	0xEC, 11586,
-	0xF0, 11589,
-	0xF1, 11592,
-	0xF2, 11595,
-	0xF3, 11598,
-	0xF4, 11601,
-	0xF5, 11604,
-	0xF6, 11607,
-	0xF7, 11610,
-	0xF8, 11613,
-	0xF9, 11616,
-	0xFA, 11619,
-	0xFB, 11622,
-	0xFC, 11625,
-	0xFD, 11628,
-	0xFE, 11631,
-	0xFF, 11634,
-	/*11514*/ uint16(x86_xCondSlashR),
-	11523, // 0
-	0,     // 1
-	11527, // 2
-	11531, // 3
-	11535, // 4
-	11539, // 5
-	11543, // 6
-	11547, // 7
-	/*11523*/ uint16(x86_xSetOp), uint16(x86_FLD),
-	/*11525*/ uint16(x86_xArgM32fp),
-	/*11526*/ uint16(x86_xMatch),
-	/*11527*/ uint16(x86_xSetOp), uint16(x86_FST),
-	/*11529*/ uint16(x86_xArgM32fp),
-	/*11530*/ uint16(x86_xMatch),
-	/*11531*/ uint16(x86_xSetOp), uint16(x86_FSTP),
-	/*11533*/ uint16(x86_xArgM32fp),
-	/*11534*/ uint16(x86_xMatch),
-	/*11535*/ uint16(x86_xSetOp), uint16(x86_FLDENV),
-	/*11537*/ uint16(x86_xArgM1428byte),
-	/*11538*/ uint16(x86_xMatch),
-	/*11539*/ uint16(x86_xSetOp), uint16(x86_FLDCW),
-	/*11541*/ uint16(x86_xArgM2byte),
-	/*11542*/ uint16(x86_xMatch),
-	/*11543*/ uint16(x86_xSetOp), uint16(x86_FNSTENV),
-	/*11545*/ uint16(x86_xArgM1428byte),
-	/*11546*/ uint16(x86_xMatch),
-	/*11547*/ uint16(x86_xSetOp), uint16(x86_FNSTCW),
-	/*11549*/ uint16(x86_xArgM2byte),
-	/*11550*/ uint16(x86_xMatch),
-	/*11551*/ uint16(x86_xSetOp), uint16(x86_FLD),
-	/*11553*/ uint16(x86_xArgSTi),
-	/*11554*/ uint16(x86_xMatch),
-	/*11555*/ uint16(x86_xSetOp), uint16(x86_FXCH),
-	/*11557*/ uint16(x86_xArgSTi),
-	/*11558*/ uint16(x86_xMatch),
-	/*11559*/ uint16(x86_xSetOp), uint16(x86_FNOP),
-	/*11561*/ uint16(x86_xMatch),
-	/*11562*/ uint16(x86_xSetOp), uint16(x86_FCHS),
-	/*11564*/ uint16(x86_xMatch),
-	/*11565*/ uint16(x86_xSetOp), uint16(x86_FABS),
-	/*11567*/ uint16(x86_xMatch),
-	/*11568*/ uint16(x86_xSetOp), uint16(x86_FTST),
-	/*11570*/ uint16(x86_xMatch),
-	/*11571*/ uint16(x86_xSetOp), uint16(x86_FXAM),
-	/*11573*/ uint16(x86_xMatch),
-	/*11574*/ uint16(x86_xSetOp), uint16(x86_FLD1),
-	/*11576*/ uint16(x86_xMatch),
-	/*11577*/ uint16(x86_xSetOp), uint16(x86_FLDL2T),
-	/*11579*/ uint16(x86_xMatch),
-	/*11580*/ uint16(x86_xSetOp), uint16(x86_FLDL2E),
-	/*11582*/ uint16(x86_xMatch),
-	/*11583*/ uint16(x86_xSetOp), uint16(x86_FLDPI),
-	/*11585*/ uint16(x86_xMatch),
-	/*11586*/ uint16(x86_xSetOp), uint16(x86_FLDLG2),
-	/*11588*/ uint16(x86_xMatch),
-	/*11589*/ uint16(x86_xSetOp), uint16(x86_F2XM1),
-	/*11591*/ uint16(x86_xMatch),
-	/*11592*/ uint16(x86_xSetOp), uint16(x86_FYL2X),
-	/*11594*/ uint16(x86_xMatch),
-	/*11595*/ uint16(x86_xSetOp), uint16(x86_FPTAN),
-	/*11597*/ uint16(x86_xMatch),
-	/*11598*/ uint16(x86_xSetOp), uint16(x86_FPATAN),
-	/*11600*/ uint16(x86_xMatch),
-	/*11601*/ uint16(x86_xSetOp), uint16(x86_FXTRACT),
-	/*11603*/ uint16(x86_xMatch),
-	/*11604*/ uint16(x86_xSetOp), uint16(x86_FPREM1),
-	/*11606*/ uint16(x86_xMatch),
-	/*11607*/ uint16(x86_xSetOp), uint16(x86_FDECSTP),
-	/*11609*/ uint16(x86_xMatch),
-	/*11610*/ uint16(x86_xSetOp), uint16(x86_FINCSTP),
-	/*11612*/ uint16(x86_xMatch),
-	/*11613*/ uint16(x86_xSetOp), uint16(x86_FPREM),
-	/*11615*/ uint16(x86_xMatch),
-	/*11616*/ uint16(x86_xSetOp), uint16(x86_FYL2XP1),
-	/*11618*/ uint16(x86_xMatch),
-	/*11619*/ uint16(x86_xSetOp), uint16(x86_FSQRT),
-	/*11621*/ uint16(x86_xMatch),
-	/*11622*/ uint16(x86_xSetOp), uint16(x86_FSINCOS),
-	/*11624*/ uint16(x86_xMatch),
-	/*11625*/ uint16(x86_xSetOp), uint16(x86_FRNDINT),
-	/*11627*/ uint16(x86_xMatch),
-	/*11628*/ uint16(x86_xSetOp), uint16(x86_FSCALE),
-	/*11630*/ uint16(x86_xMatch),
-	/*11631*/ uint16(x86_xSetOp), uint16(x86_FSIN),
-	/*11633*/ uint16(x86_xMatch),
-	/*11634*/ uint16(x86_xSetOp), uint16(x86_FCOS),
-	/*11636*/ uint16(x86_xMatch),
-	/*11637*/ uint16(x86_xCondByte), 33,
-	0xc0, 11746,
-	0xc1, 11746,
-	0xc2, 11746,
-	0xc3, 11746,
-	0xc4, 11746,
-	0xc5, 11746,
-	0xc6, 11746,
-	0xc7, 11746,
-	0xc8, 11751,
-	0xc9, 11751,
-	0xca, 11751,
-	0xcb, 11751,
-	0xcc, 11751,
-	0xcd, 11751,
-	0xce, 11751,
-	0xcf, 11751,
-	0xd0, 11756,
-	0xd1, 11756,
-	0xd2, 11756,
-	0xd3, 11756,
-	0xd4, 11756,
-	0xd5, 11756,
-	0xd6, 11756,
-	0xd7, 11756,
-	0xd8, 11761,
-	0xd9, 11761,
-	0xda, 11761,
-	0xdb, 11761,
-	0xdc, 11761,
-	0xdd, 11761,
-	0xde, 11761,
-	0xdf, 11761,
-	0xE9, 11766,
-	/*11705*/ uint16(x86_xCondSlashR),
-	11714, // 0
-	11718, // 1
-	11722, // 2
-	11726, // 3
-	11730, // 4
-	11734, // 5
-	11738, // 6
-	11742, // 7
-	/*11714*/ uint16(x86_xSetOp), uint16(x86_FIADD),
-	/*11716*/ uint16(x86_xArgM32int),
-	/*11717*/ uint16(x86_xMatch),
-	/*11718*/ uint16(x86_xSetOp), uint16(x86_FIMUL),
-	/*11720*/ uint16(x86_xArgM32int),
-	/*11721*/ uint16(x86_xMatch),
-	/*11722*/ uint16(x86_xSetOp), uint16(x86_FICOM),
-	/*11724*/ uint16(x86_xArgM32int),
-	/*11725*/ uint16(x86_xMatch),
-	/*11726*/ uint16(x86_xSetOp), uint16(x86_FICOMP),
-	/*11728*/ uint16(x86_xArgM32int),
-	/*11729*/ uint16(x86_xMatch),
-	/*11730*/ uint16(x86_xSetOp), uint16(x86_FISUB),
-	/*11732*/ uint16(x86_xArgM32int),
-	/*11733*/ uint16(x86_xMatch),
-	/*11734*/ uint16(x86_xSetOp), uint16(x86_FISUBR),
-	/*11736*/ uint16(x86_xArgM32int),
-	/*11737*/ uint16(x86_xMatch),
-	/*11738*/ uint16(x86_xSetOp), uint16(x86_FIDIV),
-	/*11740*/ uint16(x86_xArgM32int),
-	/*11741*/ uint16(x86_xMatch),
-	/*11742*/ uint16(x86_xSetOp), uint16(x86_FIDIVR),
-	/*11744*/ uint16(x86_xArgM32int),
-	/*11745*/ uint16(x86_xMatch),
-	/*11746*/ uint16(x86_xSetOp), uint16(x86_FCMOVB),
-	/*11748*/ uint16(x86_xArgST),
-	/*11749*/ uint16(x86_xArgSTi),
-	/*11750*/ uint16(x86_xMatch),
-	/*11751*/ uint16(x86_xSetOp), uint16(x86_FCMOVE),
-	/*11753*/ uint16(x86_xArgST),
-	/*11754*/ uint16(x86_xArgSTi),
-	/*11755*/ uint16(x86_xMatch),
-	/*11756*/ uint16(x86_xSetOp), uint16(x86_FCMOVBE),
-	/*11758*/ uint16(x86_xArgST),
-	/*11759*/ uint16(x86_xArgSTi),
-	/*11760*/ uint16(x86_xMatch),
-	/*11761*/ uint16(x86_xSetOp), uint16(x86_FCMOVU),
-	/*11763*/ uint16(x86_xArgST),
-	/*11764*/ uint16(x86_xArgSTi),
-	/*11765*/ uint16(x86_xMatch),
-	/*11766*/ uint16(x86_xSetOp), uint16(x86_FUCOMPP),
-	/*11768*/ uint16(x86_xMatch),
-	/*11769*/ uint16(x86_xCondByte), 50,
-	0xc0, 11904,
-	0xc1, 11904,
-	0xc2, 11904,
-	0xc3, 11904,
-	0xc4, 11904,
-	0xc5, 11904,
-	0xc6, 11904,
-	0xc7, 11904,
-	0xc8, 11909,
-	0xc9, 11909,
-	0xca, 11909,
-	0xcb, 11909,
-	0xcc, 11909,
-	0xcd, 11909,
-	0xce, 11909,
-	0xcf, 11909,
-	0xd0, 11914,
-	0xd1, 11914,
-	0xd2, 11914,
-	0xd3, 11914,
-	0xd4, 11914,
-	0xd5, 11914,
-	0xd6, 11914,
-	0xd7, 11914,
-	0xd8, 11919,
-	0xd9, 11919,
-	0xda, 11919,
-	0xdb, 11919,
-	0xdc, 11919,
-	0xdd, 11919,
-	0xde, 11919,
-	0xdf, 11919,
-	0xE2, 11924,
-	0xE3, 11927,
-	0xe8, 11930,
-	0xe9, 11930,
-	0xea, 11930,
-	0xeb, 11930,
-	0xec, 11930,
-	0xed, 11930,
-	0xee, 11930,
-	0xef, 11930,
-	0xf0, 11935,
-	0xf1, 11935,
-	0xf2, 11935,
-	0xf3, 11935,
-	0xf4, 11935,
-	0xf5, 11935,
-	0xf6, 11935,
-	0xf7, 11935,
-	/*11871*/ uint16(x86_xCondSlashR),
-	11880, // 0
-	11884, // 1
-	11888, // 2
-	11892, // 3
-	0,     // 4
-	11896, // 5
-	0,     // 6
-	11900, // 7
-	/*11880*/ uint16(x86_xSetOp), uint16(x86_FILD),
-	/*11882*/ uint16(x86_xArgM32int),
-	/*11883*/ uint16(x86_xMatch),
-	/*11884*/ uint16(x86_xSetOp), uint16(x86_FISTTP),
-	/*11886*/ uint16(x86_xArgM32int),
-	/*11887*/ uint16(x86_xMatch),
-	/*11888*/ uint16(x86_xSetOp), uint16(x86_FIST),
-	/*11890*/ uint16(x86_xArgM32int),
-	/*11891*/ uint16(x86_xMatch),
-	/*11892*/ uint16(x86_xSetOp), uint16(x86_FISTP),
-	/*11894*/ uint16(x86_xArgM32int),
-	/*11895*/ uint16(x86_xMatch),
-	/*11896*/ uint16(x86_xSetOp), uint16(x86_FLD),
-	/*11898*/ uint16(x86_xArgM80fp),
-	/*11899*/ uint16(x86_xMatch),
-	/*11900*/ uint16(x86_xSetOp), uint16(x86_FSTP),
-	/*11902*/ uint16(x86_xArgM80fp),
-	/*11903*/ uint16(x86_xMatch),
-	/*11904*/ uint16(x86_xSetOp), uint16(x86_FCMOVNB),
-	/*11906*/ uint16(x86_xArgST),
-	/*11907*/ uint16(x86_xArgSTi),
-	/*11908*/ uint16(x86_xMatch),
-	/*11909*/ uint16(x86_xSetOp), uint16(x86_FCMOVNE),
-	/*11911*/ uint16(x86_xArgST),
-	/*11912*/ uint16(x86_xArgSTi),
-	/*11913*/ uint16(x86_xMatch),
-	/*11914*/ uint16(x86_xSetOp), uint16(x86_FCMOVNBE),
-	/*11916*/ uint16(x86_xArgST),
-	/*11917*/ uint16(x86_xArgSTi),
-	/*11918*/ uint16(x86_xMatch),
-	/*11919*/ uint16(x86_xSetOp), uint16(x86_FCMOVNU),
-	/*11921*/ uint16(x86_xArgST),
-	/*11922*/ uint16(x86_xArgSTi),
-	/*11923*/ uint16(x86_xMatch),
-	/*11924*/ uint16(x86_xSetOp), uint16(x86_FNCLEX),
-	/*11926*/ uint16(x86_xMatch),
-	/*11927*/ uint16(x86_xSetOp), uint16(x86_FNINIT),
-	/*11929*/ uint16(x86_xMatch),
-	/*11930*/ uint16(x86_xSetOp), uint16(x86_FUCOMI),
-	/*11932*/ uint16(x86_xArgST),
-	/*11933*/ uint16(x86_xArgSTi),
-	/*11934*/ uint16(x86_xMatch),
-	/*11935*/ uint16(x86_xSetOp), uint16(x86_FCOMI),
-	/*11937*/ uint16(x86_xArgST),
-	/*11938*/ uint16(x86_xArgSTi),
-	/*11939*/ uint16(x86_xMatch),
-	/*11940*/ uint16(x86_xCondByte), 48,
-	0xc0, 12079,
-	0xc1, 12079,
-	0xc2, 12079,
-	0xc3, 12079,
-	0xc4, 12079,
-	0xc5, 12079,
-	0xc6, 12079,
-	0xc7, 12079,
-	0xc8, 12084,
-	0xc9, 12084,
-	0xca, 12084,
-	0xcb, 12084,
-	0xcc, 12084,
-	0xcd, 12084,
-	0xce, 12084,
-	0xcf, 12084,
-	0xe0, 12089,
-	0xe1, 12089,
-	0xe2, 12089,
-	0xe3, 12089,
-	0xe4, 12089,
-	0xe5, 12089,
-	0xe6, 12089,
-	0xe7, 12089,
-	0xe8, 12094,
-	0xe9, 12094,
-	0xea, 12094,
-	0xeb, 12094,
-	0xec, 12094,
-	0xed, 12094,
-	0xee, 12094,
-	0xef, 12094,
-	0xf0, 12099,
-	0xf1, 12099,
-	0xf2, 12099,
-	0xf3, 12099,
-	0xf4, 12099,
-	0xf5, 12099,
-	0xf6, 12099,
-	0xf7, 12099,
-	0xf8, 12104,
-	0xf9, 12104,
-	0xfa, 12104,
-	0xfb, 12104,
-	0xfc, 12104,
-	0xfd, 12104,
-	0xfe, 12104,
-	0xff, 12104,
-	/*12038*/ uint16(x86_xCondSlashR),
-	12047, // 0
-	12051, // 1
-	12055, // 2
-	12059, // 3
-	12063, // 4
-	12067, // 5
-	12071, // 6
-	12075, // 7
-	/*12047*/ uint16(x86_xSetOp), uint16(x86_FADD),
-	/*12049*/ uint16(x86_xArgM64fp),
-	/*12050*/ uint16(x86_xMatch),
-	/*12051*/ uint16(x86_xSetOp), uint16(x86_FMUL),
-	/*12053*/ uint16(x86_xArgM64fp),
-	/*12054*/ uint16(x86_xMatch),
-	/*12055*/ uint16(x86_xSetOp), uint16(x86_FCOM),
-	/*12057*/ uint16(x86_xArgM64fp),
-	/*12058*/ uint16(x86_xMatch),
-	/*12059*/ uint16(x86_xSetOp), uint16(x86_FCOMP),
-	/*12061*/ uint16(x86_xArgM64fp),
-	/*12062*/ uint16(x86_xMatch),
-	/*12063*/ uint16(x86_xSetOp), uint16(x86_FSUB),
-	/*12065*/ uint16(x86_xArgM64fp),
-	/*12066*/ uint16(x86_xMatch),
-	/*12067*/ uint16(x86_xSetOp), uint16(x86_FSUBR),
-	/*12069*/ uint16(x86_xArgM64fp),
-	/*12070*/ uint16(x86_xMatch),
-	/*12071*/ uint16(x86_xSetOp), uint16(x86_FDIV),
-	/*12073*/ uint16(x86_xArgM64fp),
-	/*12074*/ uint16(x86_xMatch),
-	/*12075*/ uint16(x86_xSetOp), uint16(x86_FDIVR),
-	/*12077*/ uint16(x86_xArgM64fp),
-	/*12078*/ uint16(x86_xMatch),
-	/*12079*/ uint16(x86_xSetOp), uint16(x86_FADD),
-	/*12081*/ uint16(x86_xArgSTi),
-	/*12082*/ uint16(x86_xArgST),
-	/*12083*/ uint16(x86_xMatch),
-	/*12084*/ uint16(x86_xSetOp), uint16(x86_FMUL),
-	/*12086*/ uint16(x86_xArgSTi),
-	/*12087*/ uint16(x86_xArgST),
-	/*12088*/ uint16(x86_xMatch),
-	/*12089*/ uint16(x86_xSetOp), uint16(x86_FSUBR),
-	/*12091*/ uint16(x86_xArgSTi),
-	/*12092*/ uint16(x86_xArgST),
-	/*12093*/ uint16(x86_xMatch),
-	/*12094*/ uint16(x86_xSetOp), uint16(x86_FSUB),
-	/*12096*/ uint16(x86_xArgSTi),
-	/*12097*/ uint16(x86_xArgST),
-	/*12098*/ uint16(x86_xMatch),
-	/*12099*/ uint16(x86_xSetOp), uint16(x86_FDIVR),
-	/*12101*/ uint16(x86_xArgSTi),
-	/*12102*/ uint16(x86_xArgST),
-	/*12103*/ uint16(x86_xMatch),
-	/*12104*/ uint16(x86_xSetOp), uint16(x86_FDIV),
-	/*12106*/ uint16(x86_xArgSTi),
-	/*12107*/ uint16(x86_xArgST),
-	/*12108*/ uint16(x86_xMatch),
-	/*12109*/ uint16(x86_xCondByte), 40,
-	0xc0, 12228,
-	0xc1, 12228,
-	0xc2, 12228,
-	0xc3, 12228,
-	0xc4, 12228,
-	0xc5, 12228,
-	0xc6, 12228,
-	0xc7, 12228,
-	0xd0, 12232,
-	0xd1, 12232,
-	0xd2, 12232,
-	0xd3, 12232,
-	0xd4, 12232,
-	0xd5, 12232,
-	0xd6, 12232,
-	0xd7, 12232,
-	0xd8, 12236,
-	0xd9, 12236,
-	0xda, 12236,
-	0xdb, 12236,
-	0xdc, 12236,
-	0xdd, 12236,
-	0xde, 12236,
-	0xdf, 12236,
-	0xe0, 12240,
-	0xe1, 12240,
-	0xe2, 12240,
-	0xe3, 12240,
-	0xe4, 12240,
-	0xe5, 12240,
-	0xe6, 12240,
-	0xe7, 12240,
-	0xe8, 12244,
-	0xe9, 12244,
-	0xea, 12244,
-	0xeb, 12244,
-	0xec, 12244,
-	0xed, 12244,
-	0xee, 12244,
-	0xef, 12244,
-	/*12191*/ uint16(x86_xCondSlashR),
-	12200, // 0
-	12204, // 1
-	12208, // 2
-	12212, // 3
-	12216, // 4
-	0,     // 5
-	12220, // 6
-	12224, // 7
-	/*12200*/ uint16(x86_xSetOp), uint16(x86_FLD),
-	/*12202*/ uint16(x86_xArgM64fp),
-	/*12203*/ uint16(x86_xMatch),
-	/*12204*/ uint16(x86_xSetOp), uint16(x86_FISTTP),
-	/*12206*/ uint16(x86_xArgM64int),
-	/*12207*/ uint16(x86_xMatch),
-	/*12208*/ uint16(x86_xSetOp), uint16(x86_FST),
-	/*12210*/ uint16(x86_xArgM64fp),
-	/*12211*/ uint16(x86_xMatch),
-	/*12212*/ uint16(x86_xSetOp), uint16(x86_FSTP),
-	/*12214*/ uint16(x86_xArgM64fp),
-	/*12215*/ uint16(x86_xMatch),
-	/*12216*/ uint16(x86_xSetOp), uint16(x86_FRSTOR),
-	/*12218*/ uint16(x86_xArgM94108byte),
-	/*12219*/ uint16(x86_xMatch),
-	/*12220*/ uint16(x86_xSetOp), uint16(x86_FNSAVE),
-	/*12222*/ uint16(x86_xArgM94108byte),
-	/*12223*/ uint16(x86_xMatch),
-	/*12224*/ uint16(x86_xSetOp), uint16(x86_FNSTSW),
-	/*12226*/ uint16(x86_xArgM2byte),
-	/*12227*/ uint16(x86_xMatch),
-	/*12228*/ uint16(x86_xSetOp), uint16(x86_FFREE),
-	/*12230*/ uint16(x86_xArgSTi),
-	/*12231*/ uint16(x86_xMatch),
-	/*12232*/ uint16(x86_xSetOp), uint16(x86_FST),
-	/*12234*/ uint16(x86_xArgSTi),
-	/*12235*/ uint16(x86_xMatch),
-	/*12236*/ uint16(x86_xSetOp), uint16(x86_FSTP),
-	/*12238*/ uint16(x86_xArgSTi),
-	/*12239*/ uint16(x86_xMatch),
-	/*12240*/ uint16(x86_xSetOp), uint16(x86_FUCOM),
-	/*12242*/ uint16(x86_xArgSTi),
-	/*12243*/ uint16(x86_xMatch),
-	/*12244*/ uint16(x86_xSetOp), uint16(x86_FUCOMP),
-	/*12246*/ uint16(x86_xArgSTi),
-	/*12247*/ uint16(x86_xMatch),
-	/*12248*/ uint16(x86_xCondByte), 49,
-	0xc0, 12389,
-	0xc1, 12389,
-	0xc2, 12389,
-	0xc3, 12389,
-	0xc4, 12389,
-	0xc5, 12389,
-	0xc6, 12389,
-	0xc7, 12389,
-	0xc8, 12394,
-	0xc9, 12394,
-	0xca, 12394,
-	0xcb, 12394,
-	0xcc, 12394,
-	0xcd, 12394,
-	0xce, 12394,
-	0xcf, 12394,
-	0xD9, 12399,
-	0xe0, 12402,
-	0xe1, 12402,
-	0xe2, 12402,
-	0xe3, 12402,
-	0xe4, 12402,
-	0xe5, 12402,
-	0xe6, 12402,
-	0xe7, 12402,
-	0xe8, 12407,
-	0xe9, 12407,
-	0xea, 12407,
-	0xeb, 12407,
-	0xec, 12407,
-	0xed, 12407,
-	0xee, 12407,
-	0xef, 12407,
-	0xf0, 12412,
-	0xf1, 12412,
-	0xf2, 12412,
-	0xf3, 12412,
-	0xf4, 12412,
-	0xf5, 12412,
-	0xf6, 12412,
-	0xf7, 12412,
-	0xf8, 12417,
-	0xf9, 12417,
-	0xfa, 12417,
-	0xfb, 12417,
-	0xfc, 12417,
-	0xfd, 12417,
-	0xfe, 12417,
-	0xff, 12417,
-	/*12348*/ uint16(x86_xCondSlashR),
-	12357, // 0
-	12361, // 1
-	12365, // 2
-	12369, // 3
-	12373, // 4
-	12377, // 5
-	12381, // 6
-	12385, // 7
-	/*12357*/ uint16(x86_xSetOp), uint16(x86_FIADD),
-	/*12359*/ uint16(x86_xArgM16int),
-	/*12360*/ uint16(x86_xMatch),
-	/*12361*/ uint16(x86_xSetOp), uint16(x86_FIMUL),
-	/*12363*/ uint16(x86_xArgM16int),
-	/*12364*/ uint16(x86_xMatch),
-	/*12365*/ uint16(x86_xSetOp), uint16(x86_FICOM),
-	/*12367*/ uint16(x86_xArgM16int),
-	/*12368*/ uint16(x86_xMatch),
-	/*12369*/ uint16(x86_xSetOp), uint16(x86_FICOMP),
-	/*12371*/ uint16(x86_xArgM16int),
-	/*12372*/ uint16(x86_xMatch),
-	/*12373*/ uint16(x86_xSetOp), uint16(x86_FISUB),
-	/*12375*/ uint16(x86_xArgM16int),
-	/*12376*/ uint16(x86_xMatch),
-	/*12377*/ uint16(x86_xSetOp), uint16(x86_FISUBR),
-	/*12379*/ uint16(x86_xArgM16int),
-	/*12380*/ uint16(x86_xMatch),
-	/*12381*/ uint16(x86_xSetOp), uint16(x86_FIDIV),
-	/*12383*/ uint16(x86_xArgM16int),
-	/*12384*/ uint16(x86_xMatch),
-	/*12385*/ uint16(x86_xSetOp), uint16(x86_FIDIVR),
-	/*12387*/ uint16(x86_xArgM16int),
-	/*12388*/ uint16(x86_xMatch),
-	/*12389*/ uint16(x86_xSetOp), uint16(x86_FADDP),
-	/*12391*/ uint16(x86_xArgSTi),
-	/*12392*/ uint16(x86_xArgST),
-	/*12393*/ uint16(x86_xMatch),
-	/*12394*/ uint16(x86_xSetOp), uint16(x86_FMULP),
-	/*12396*/ uint16(x86_xArgSTi),
-	/*12397*/ uint16(x86_xArgST),
-	/*12398*/ uint16(x86_xMatch),
-	/*12399*/ uint16(x86_xSetOp), uint16(x86_FCOMPP),
-	/*12401*/ uint16(x86_xMatch),
-	/*12402*/ uint16(x86_xSetOp), uint16(x86_FSUBRP),
-	/*12404*/ uint16(x86_xArgSTi),
-	/*12405*/ uint16(x86_xArgST),
-	/*12406*/ uint16(x86_xMatch),
-	/*12407*/ uint16(x86_xSetOp), uint16(x86_FSUBP),
-	/*12409*/ uint16(x86_xArgSTi),
-	/*12410*/ uint16(x86_xArgST),
-	/*12411*/ uint16(x86_xMatch),
-	/*12412*/ uint16(x86_xSetOp), uint16(x86_FDIVRP),
-	/*12414*/ uint16(x86_xArgSTi),
-	/*12415*/ uint16(x86_xArgST),
-	/*12416*/ uint16(x86_xMatch),
-	/*12417*/ uint16(x86_xSetOp), uint16(x86_FDIVP),
-	/*12419*/ uint16(x86_xArgSTi),
-	/*12420*/ uint16(x86_xArgST),
-	/*12421*/ uint16(x86_xMatch),
-	/*12422*/ uint16(x86_xCondByte), 25,
-	0xc0, 12515,
-	0xc1, 12515,
-	0xc2, 12515,
-	0xc3, 12515,
-	0xc4, 12515,
-	0xc5, 12515,
-	0xc6, 12515,
-	0xc7, 12515,
-	0xE0, 12519,
-	0xe8, 12523,
-	0xe9, 12523,
-	0xea, 12523,
-	0xeb, 12523,
-	0xec, 12523,
-	0xed, 12523,
-	0xee, 12523,
-	0xef, 12523,
-	0xf0, 12528,
-	0xf1, 12528,
-	0xf2, 12528,
-	0xf3, 12528,
-	0xf4, 12528,
-	0xf5, 12528,
-	0xf6, 12528,
-	0xf7, 12528,
-	/*12474*/ uint16(x86_xCondSlashR),
-	12483, // 0
-	12487, // 1
-	12491, // 2
-	12495, // 3
-	12499, // 4
-	12503, // 5
-	12507, // 6
-	12511, // 7
-	/*12483*/ uint16(x86_xSetOp), uint16(x86_FILD),
-	/*12485*/ uint16(x86_xArgM16int),
-	/*12486*/ uint16(x86_xMatch),
-	/*12487*/ uint16(x86_xSetOp), uint16(x86_FISTTP),
-	/*12489*/ uint16(x86_xArgM16int),
-	/*12490*/ uint16(x86_xMatch),
-	/*12491*/ uint16(x86_xSetOp), uint16(x86_FIST),
-	/*12493*/ uint16(x86_xArgM16int),
-	/*12494*/ uint16(x86_xMatch),
-	/*12495*/ uint16(x86_xSetOp), uint16(x86_FISTP),
-	/*12497*/ uint16(x86_xArgM16int),
-	/*12498*/ uint16(x86_xMatch),
-	/*12499*/ uint16(x86_xSetOp), uint16(x86_FBLD),
-	/*12501*/ uint16(x86_xArgM80dec),
-	/*12502*/ uint16(x86_xMatch),
-	/*12503*/ uint16(x86_xSetOp), uint16(x86_FILD),
-	/*12505*/ uint16(x86_xArgM64int),
-	/*12506*/ uint16(x86_xMatch),
-	/*12507*/ uint16(x86_xSetOp), uint16(x86_FBSTP),
-	/*12509*/ uint16(x86_xArgM80bcd),
-	/*12510*/ uint16(x86_xMatch),
-	/*12511*/ uint16(x86_xSetOp), uint16(x86_FISTP),
-	/*12513*/ uint16(x86_xArgM64int),
-	/*12514*/ uint16(x86_xMatch),
-	/*12515*/ uint16(x86_xSetOp), uint16(x86_FFREEP),
-	/*12517*/ uint16(x86_xArgSTi),
-	/*12518*/ uint16(x86_xMatch),
-	/*12519*/ uint16(x86_xSetOp), uint16(x86_FNSTSW),
-	/*12521*/ uint16(x86_xArgAX),
-	/*12522*/ uint16(x86_xMatch),
-	/*12523*/ uint16(x86_xSetOp), uint16(x86_FUCOMIP),
-	/*12525*/ uint16(x86_xArgST),
-	/*12526*/ uint16(x86_xArgSTi),
-	/*12527*/ uint16(x86_xMatch),
-	/*12528*/ uint16(x86_xSetOp), uint16(x86_FCOMIP),
-	/*12530*/ uint16(x86_xArgST),
-	/*12531*/ uint16(x86_xArgSTi),
-	/*12532*/ uint16(x86_xMatch),
-	/*12533*/ uint16(x86_xSetOp), uint16(x86_LOOPNE),
-	/*12535*/ uint16(x86_xReadCb),
-	/*12536*/ uint16(x86_xArgRel8),
-	/*12537*/ uint16(x86_xMatch),
-	/*12538*/ uint16(x86_xSetOp), uint16(x86_LOOPE),
-	/*12540*/ uint16(x86_xReadCb),
-	/*12541*/ uint16(x86_xArgRel8),
-	/*12542*/ uint16(x86_xMatch),
-	/*12543*/ uint16(x86_xSetOp), uint16(x86_LOOP),
-	/*12545*/ uint16(x86_xReadCb),
-	/*12546*/ uint16(x86_xArgRel8),
-	/*12547*/ uint16(x86_xMatch),
-	/*12548*/ uint16(x86_xCondIs64), 12551, 12565,
-	/*12551*/ uint16(x86_xCondAddrSize), 12555, 12560, 0,
-	/*12555*/ uint16(x86_xSetOp), uint16(x86_JCXZ),
-	/*12557*/ uint16(x86_xReadCb),
-	/*12558*/ uint16(x86_xArgRel8),
-	/*12559*/ uint16(x86_xMatch),
-	/*12560*/ uint16(x86_xSetOp), uint16(x86_JECXZ),
-	/*12562*/ uint16(x86_xReadCb),
-	/*12563*/ uint16(x86_xArgRel8),
-	/*12564*/ uint16(x86_xMatch),
-	/*12565*/ uint16(x86_xCondAddrSize), 0, 12560, 12569,
-	/*12569*/ uint16(x86_xSetOp), uint16(x86_JRCXZ),
-	/*12571*/ uint16(x86_xReadCb),
-	/*12572*/ uint16(x86_xArgRel8),
-	/*12573*/ uint16(x86_xMatch),
-	/*12574*/ uint16(x86_xSetOp), uint16(x86_IN),
-	/*12576*/ uint16(x86_xReadIb),
-	/*12577*/ uint16(x86_xArgAL),
-	/*12578*/ uint16(x86_xArgImm8u),
-	/*12579*/ uint16(x86_xMatch),
-	/*12580*/ uint16(x86_xCondDataSize), 12584, 12590, 12596,
-	/*12584*/ uint16(x86_xSetOp), uint16(x86_IN),
-	/*12586*/ uint16(x86_xReadIb),
-	/*12587*/ uint16(x86_xArgAX),
-	/*12588*/ uint16(x86_xArgImm8u),
-	/*12589*/ uint16(x86_xMatch),
-	/*12590*/ uint16(x86_xSetOp), uint16(x86_IN),
-	/*12592*/ uint16(x86_xReadIb),
-	/*12593*/ uint16(x86_xArgEAX),
-	/*12594*/ uint16(x86_xArgImm8u),
-	/*12595*/ uint16(x86_xMatch),
-	/*12596*/ uint16(x86_xSetOp), uint16(x86_IN),
-	/*12598*/ uint16(x86_xReadIb),
-	/*12599*/ uint16(x86_xArgEAX),
-	/*12600*/ uint16(x86_xArgImm8u),
-	/*12601*/ uint16(x86_xMatch),
-	/*12602*/ uint16(x86_xSetOp), uint16(x86_OUT),
-	/*12604*/ uint16(x86_xReadIb),
-	/*12605*/ uint16(x86_xArgImm8u),
-	/*12606*/ uint16(x86_xArgAL),
-	/*12607*/ uint16(x86_xMatch),
-	/*12608*/ uint16(x86_xCondDataSize), 12612, 12618, 12624,
-	/*12612*/ uint16(x86_xSetOp), uint16(x86_OUT),
-	/*12614*/ uint16(x86_xReadIb),
-	/*12615*/ uint16(x86_xArgImm8u),
-	/*12616*/ uint16(x86_xArgAX),
-	/*12617*/ uint16(x86_xMatch),
-	/*12618*/ uint16(x86_xSetOp), uint16(x86_OUT),
-	/*12620*/ uint16(x86_xReadIb),
-	/*12621*/ uint16(x86_xArgImm8u),
-	/*12622*/ uint16(x86_xArgEAX),
-	/*12623*/ uint16(x86_xMatch),
-	/*12624*/ uint16(x86_xSetOp), uint16(x86_OUT),
-	/*12626*/ uint16(x86_xReadIb),
-	/*12627*/ uint16(x86_xArgImm8u),
-	/*12628*/ uint16(x86_xArgEAX),
-	/*12629*/ uint16(x86_xMatch),
-	/*12630*/ uint16(x86_xCondIs64), 12633, 12647,
-	/*12633*/ uint16(x86_xCondDataSize), 12637, 12642, 0,
-	/*12637*/ uint16(x86_xSetOp), uint16(x86_CALL),
-	/*12639*/ uint16(x86_xReadCw),
-	/*12640*/ uint16(x86_xArgRel16),
-	/*12641*/ uint16(x86_xMatch),
-	/*12642*/ uint16(x86_xSetOp), uint16(x86_CALL),
-	/*12644*/ uint16(x86_xReadCd),
-	/*12645*/ uint16(x86_xArgRel32),
-	/*12646*/ uint16(x86_xMatch),
-	/*12647*/ uint16(x86_xCondDataSize), 12651, 12642, 12656,
-	/*12651*/ uint16(x86_xSetOp), uint16(x86_CALL),
-	/*12653*/ uint16(x86_xReadCd),
-	/*12654*/ uint16(x86_xArgRel32),
-	/*12655*/ uint16(x86_xMatch),
-	/*12656*/ uint16(x86_xSetOp), uint16(x86_CALL),
-	/*12658*/ uint16(x86_xReadCd),
-	/*12659*/ uint16(x86_xArgRel32),
-	/*12660*/ uint16(x86_xMatch),
-	/*12661*/ uint16(x86_xCondIs64), 12664, 12678,
-	/*12664*/ uint16(x86_xCondDataSize), 12668, 12673, 0,
-	/*12668*/ uint16(x86_xSetOp), uint16(x86_JMP),
-	/*12670*/ uint16(x86_xReadCw),
-	/*12671*/ uint16(x86_xArgRel16),
-	/*12672*/ uint16(x86_xMatch),
-	/*12673*/ uint16(x86_xSetOp), uint16(x86_JMP),
-	/*12675*/ uint16(x86_xReadCd),
-	/*12676*/ uint16(x86_xArgRel32),
-	/*12677*/ uint16(x86_xMatch),
-	/*12678*/ uint16(x86_xCondDataSize), 12682, 12673, 12687,
-	/*12682*/ uint16(x86_xSetOp), uint16(x86_JMP),
-	/*12684*/ uint16(x86_xReadCd),
-	/*12685*/ uint16(x86_xArgRel32),
-	/*12686*/ uint16(x86_xMatch),
-	/*12687*/ uint16(x86_xSetOp), uint16(x86_JMP),
-	/*12689*/ uint16(x86_xReadCd),
-	/*12690*/ uint16(x86_xArgRel32),
-	/*12691*/ uint16(x86_xMatch),
-	/*12692*/ uint16(x86_xCondIs64), 12695, 0,
-	/*12695*/ uint16(x86_xCondDataSize), 12699, 12704, 0,
-	/*12699*/ uint16(x86_xSetOp), uint16(x86_LJMP),
-	/*12701*/ uint16(x86_xReadCd),
-	/*12702*/ uint16(x86_xArgPtr16colon16),
-	/*12703*/ uint16(x86_xMatch),
-	/*12704*/ uint16(x86_xSetOp), uint16(x86_LJMP),
-	/*12706*/ uint16(x86_xReadCp),
-	/*12707*/ uint16(x86_xArgPtr16colon32),
-	/*12708*/ uint16(x86_xMatch),
-	/*12709*/ uint16(x86_xSetOp), uint16(x86_JMP),
-	/*12711*/ uint16(x86_xReadCb),
-	/*12712*/ uint16(x86_xArgRel8),
-	/*12713*/ uint16(x86_xMatch),
-	/*12714*/ uint16(x86_xSetOp), uint16(x86_IN),
-	/*12716*/ uint16(x86_xArgAL),
-	/*12717*/ uint16(x86_xArgDX),
-	/*12718*/ uint16(x86_xMatch),
-	/*12719*/ uint16(x86_xCondDataSize), 12723, 12728, 12733,
-	/*12723*/ uint16(x86_xSetOp), uint16(x86_IN),
-	/*12725*/ uint16(x86_xArgAX),
-	/*12726*/ uint16(x86_xArgDX),
-	/*12727*/ uint16(x86_xMatch),
-	/*12728*/ uint16(x86_xSetOp), uint16(x86_IN),
-	/*12730*/ uint16(x86_xArgEAX),
-	/*12731*/ uint16(x86_xArgDX),
-	/*12732*/ uint16(x86_xMatch),
-	/*12733*/ uint16(x86_xSetOp), uint16(x86_IN),
-	/*12735*/ uint16(x86_xArgEAX),
-	/*12736*/ uint16(x86_xArgDX),
-	/*12737*/ uint16(x86_xMatch),
-	/*12738*/ uint16(x86_xSetOp), uint16(x86_OUT),
-	/*12740*/ uint16(x86_xArgDX),
-	/*12741*/ uint16(x86_xArgAL),
-	/*12742*/ uint16(x86_xMatch),
-	/*12743*/ uint16(x86_xCondDataSize), 12747, 12752, 12757,
-	/*12747*/ uint16(x86_xSetOp), uint16(x86_OUT),
-	/*12749*/ uint16(x86_xArgDX),
-	/*12750*/ uint16(x86_xArgAX),
-	/*12751*/ uint16(x86_xMatch),
-	/*12752*/ uint16(x86_xSetOp), uint16(x86_OUT),
-	/*12754*/ uint16(x86_xArgDX),
-	/*12755*/ uint16(x86_xArgEAX),
-	/*12756*/ uint16(x86_xMatch),
-	/*12757*/ uint16(x86_xSetOp), uint16(x86_OUT),
-	/*12759*/ uint16(x86_xArgDX),
-	/*12760*/ uint16(x86_xArgEAX),
-	/*12761*/ uint16(x86_xMatch),
-	/*12762*/ uint16(x86_xSetOp), uint16(x86_ICEBP),
-	/*12764*/ uint16(x86_xMatch),
-	/*12765*/ uint16(x86_xSetOp), uint16(x86_HLT),
-	/*12767*/ uint16(x86_xMatch),
-	/*12768*/ uint16(x86_xSetOp), uint16(x86_CMC),
-	/*12770*/ uint16(x86_xMatch),
-	/*12771*/ uint16(x86_xCondSlashR),
-	12780, // 0
-	0,     // 1
-	12786, // 2
-	12790, // 3
-	12794, // 4
-	12798, // 5
-	12802, // 6
-	12806, // 7
-	/*12780*/ uint16(x86_xSetOp), uint16(x86_TEST),
-	/*12782*/ uint16(x86_xReadIb),
-	/*12783*/ uint16(x86_xArgRM8),
-	/*12784*/ uint16(x86_xArgImm8u),
-	/*12785*/ uint16(x86_xMatch),
-	/*12786*/ uint16(x86_xSetOp), uint16(x86_NOT),
-	/*12788*/ uint16(x86_xArgRM8),
-	/*12789*/ uint16(x86_xMatch),
-	/*12790*/ uint16(x86_xSetOp), uint16(x86_NEG),
-	/*12792*/ uint16(x86_xArgRM8),
-	/*12793*/ uint16(x86_xMatch),
-	/*12794*/ uint16(x86_xSetOp), uint16(x86_MUL),
-	/*12796*/ uint16(x86_xArgRM8),
-	/*12797*/ uint16(x86_xMatch),
-	/*12798*/ uint16(x86_xSetOp), uint16(x86_IMUL),
-	/*12800*/ uint16(x86_xArgRM8),
-	/*12801*/ uint16(x86_xMatch),
-	/*12802*/ uint16(x86_xSetOp), uint16(x86_DIV),
-	/*12804*/ uint16(x86_xArgRM8),
-	/*12805*/ uint16(x86_xMatch),
-	/*12806*/ uint16(x86_xSetOp), uint16(x86_IDIV),
-	/*12808*/ uint16(x86_xArgRM8),
-	/*12809*/ uint16(x86_xMatch),
-	/*12810*/ uint16(x86_xCondSlashR),
-	12819, // 0
-	0,     // 1
-	12848, // 2
-	12871, // 3
-	12894, // 4
-	12917, // 5
-	12940, // 6
-	12963, // 7
-	/*12819*/ uint16(x86_xCondIs64), 12822, 12838,
-	/*12822*/ uint16(x86_xCondDataSize), 12826, 12832, 0,
-	/*12826*/ uint16(x86_xSetOp), uint16(x86_TEST),
-	/*12828*/ uint16(x86_xReadIw),
-	/*12829*/ uint16(x86_xArgRM16),
-	/*12830*/ uint16(x86_xArgImm16),
-	/*12831*/ uint16(x86_xMatch),
-	/*12832*/ uint16(x86_xSetOp), uint16(x86_TEST),
-	/*12834*/ uint16(x86_xReadId),
-	/*12835*/ uint16(x86_xArgRM32),
-	/*12836*/ uint16(x86_xArgImm32),
-	/*12837*/ uint16(x86_xMatch),
-	/*12838*/ uint16(x86_xCondDataSize), 12826, 12832, 12842,
-	/*12842*/ uint16(x86_xSetOp), uint16(x86_TEST),
-	/*12844*/ uint16(x86_xReadId),
-	/*12845*/ uint16(x86_xArgRM64),
-	/*12846*/ uint16(x86_xArgImm32),
-	/*12847*/ uint16(x86_xMatch),
-	/*12848*/ uint16(x86_xCondIs64), 12851, 12863,
-	/*12851*/ uint16(x86_xCondDataSize), 12855, 12859, 0,
-	/*12855*/ uint16(x86_xSetOp), uint16(x86_NOT),
-	/*12857*/ uint16(x86_xArgRM16),
-	/*12858*/ uint16(x86_xMatch),
-	/*12859*/ uint16(x86_xSetOp), uint16(x86_NOT),
-	/*12861*/ uint16(x86_xArgRM32),
-	/*12862*/ uint16(x86_xMatch),
-	/*12863*/ uint16(x86_xCondDataSize), 12855, 12859, 12867,
-	/*12867*/ uint16(x86_xSetOp), uint16(x86_NOT),
-	/*12869*/ uint16(x86_xArgRM64),
-	/*12870*/ uint16(x86_xMatch),
-	/*12871*/ uint16(x86_xCondIs64), 12874, 12886,
-	/*12874*/ uint16(x86_xCondDataSize), 12878, 12882, 0,
-	/*12878*/ uint16(x86_xSetOp), uint16(x86_NEG),
-	/*12880*/ uint16(x86_xArgRM16),
-	/*12881*/ uint16(x86_xMatch),
-	/*12882*/ uint16(x86_xSetOp), uint16(x86_NEG),
-	/*12884*/ uint16(x86_xArgRM32),
-	/*12885*/ uint16(x86_xMatch),
-	/*12886*/ uint16(x86_xCondDataSize), 12878, 12882, 12890,
-	/*12890*/ uint16(x86_xSetOp), uint16(x86_NEG),
-	/*12892*/ uint16(x86_xArgRM64),
-	/*12893*/ uint16(x86_xMatch),
-	/*12894*/ uint16(x86_xCondIs64), 12897, 12909,
-	/*12897*/ uint16(x86_xCondDataSize), 12901, 12905, 0,
-	/*12901*/ uint16(x86_xSetOp), uint16(x86_MUL),
-	/*12903*/ uint16(x86_xArgRM16),
-	/*12904*/ uint16(x86_xMatch),
-	/*12905*/ uint16(x86_xSetOp), uint16(x86_MUL),
-	/*12907*/ uint16(x86_xArgRM32),
-	/*12908*/ uint16(x86_xMatch),
-	/*12909*/ uint16(x86_xCondDataSize), 12901, 12905, 12913,
-	/*12913*/ uint16(x86_xSetOp), uint16(x86_MUL),
-	/*12915*/ uint16(x86_xArgRM64),
-	/*12916*/ uint16(x86_xMatch),
-	/*12917*/ uint16(x86_xCondIs64), 12920, 12932,
-	/*12920*/ uint16(x86_xCondDataSize), 12924, 12928, 0,
-	/*12924*/ uint16(x86_xSetOp), uint16(x86_IMUL),
-	/*12926*/ uint16(x86_xArgRM16),
-	/*12927*/ uint16(x86_xMatch),
-	/*12928*/ uint16(x86_xSetOp), uint16(x86_IMUL),
-	/*12930*/ uint16(x86_xArgRM32),
-	/*12931*/ uint16(x86_xMatch),
-	/*12932*/ uint16(x86_xCondDataSize), 12924, 12928, 12936,
-	/*12936*/ uint16(x86_xSetOp), uint16(x86_IMUL),
-	/*12938*/ uint16(x86_xArgRM64),
-	/*12939*/ uint16(x86_xMatch),
-	/*12940*/ uint16(x86_xCondIs64), 12943, 12955,
-	/*12943*/ uint16(x86_xCondDataSize), 12947, 12951, 0,
-	/*12947*/ uint16(x86_xSetOp), uint16(x86_DIV),
-	/*12949*/ uint16(x86_xArgRM16),
-	/*12950*/ uint16(x86_xMatch),
-	/*12951*/ uint16(x86_xSetOp), uint16(x86_DIV),
-	/*12953*/ uint16(x86_xArgRM32),
-	/*12954*/ uint16(x86_xMatch),
-	/*12955*/ uint16(x86_xCondDataSize), 12947, 12951, 12959,
-	/*12959*/ uint16(x86_xSetOp), uint16(x86_DIV),
-	/*12961*/ uint16(x86_xArgRM64),
-	/*12962*/ uint16(x86_xMatch),
-	/*12963*/ uint16(x86_xCondIs64), 12966, 12978,
-	/*12966*/ uint16(x86_xCondDataSize), 12970, 12974, 0,
-	/*12970*/ uint16(x86_xSetOp), uint16(x86_IDIV),
-	/*12972*/ uint16(x86_xArgRM16),
-	/*12973*/ uint16(x86_xMatch),
-	/*12974*/ uint16(x86_xSetOp), uint16(x86_IDIV),
-	/*12976*/ uint16(x86_xArgRM32),
-	/*12977*/ uint16(x86_xMatch),
-	/*12978*/ uint16(x86_xCondDataSize), 12970, 12974, 12982,
-	/*12982*/ uint16(x86_xSetOp), uint16(x86_IDIV),
-	/*12984*/ uint16(x86_xArgRM64),
-	/*12985*/ uint16(x86_xMatch),
-	/*12986*/ uint16(x86_xSetOp), uint16(x86_CLC),
-	/*12988*/ uint16(x86_xMatch),
-	/*12989*/ uint16(x86_xSetOp), uint16(x86_STC),
-	/*12991*/ uint16(x86_xMatch),
-	/*12992*/ uint16(x86_xSetOp), uint16(x86_CLI),
-	/*12994*/ uint16(x86_xMatch),
-	/*12995*/ uint16(x86_xSetOp), uint16(x86_STI),
-	/*12997*/ uint16(x86_xMatch),
-	/*12998*/ uint16(x86_xSetOp), uint16(x86_CLD),
-	/*13000*/ uint16(x86_xMatch),
-	/*13001*/ uint16(x86_xSetOp), uint16(x86_STD),
-	/*13003*/ uint16(x86_xMatch),
-	/*13004*/ uint16(x86_xCondSlashR),
-	13013, // 0
-	13017, // 1
-	0,     // 2
-	0,     // 3
-	0,     // 4
-	0,     // 5
-	0,     // 6
-	0,     // 7
-	/*13013*/ uint16(x86_xSetOp), uint16(x86_INC),
-	/*13015*/ uint16(x86_xArgRM8),
-	/*13016*/ uint16(x86_xMatch),
-	/*13017*/ uint16(x86_xSetOp), uint16(x86_DEC),
-	/*13019*/ uint16(x86_xArgRM8),
-	/*13020*/ uint16(x86_xMatch),
-	/*13021*/ uint16(x86_xCondSlashR),
-	13030, // 0
-	13053, // 1
-	13076, // 2
-	13095, // 3
-	13118, // 4
-	13137, // 5
-	13160, // 6
-	0,     // 7
-	/*13030*/ uint16(x86_xCondIs64), 13033, 13045,
-	/*13033*/ uint16(x86_xCondDataSize), 13037, 13041, 0,
-	/*13037*/ uint16(x86_xSetOp), uint16(x86_INC),
-	/*13039*/ uint16(x86_xArgRM16),
-	/*13040*/ uint16(x86_xMatch),
-	/*13041*/ uint16(x86_xSetOp), uint16(x86_INC),
-	/*13043*/ uint16(x86_xArgRM32),
-	/*13044*/ uint16(x86_xMatch),
-	/*13045*/ uint16(x86_xCondDataSize), 13037, 13041, 13049,
-	/*13049*/ uint16(x86_xSetOp), uint16(x86_INC),
-	/*13051*/ uint16(x86_xArgRM64),
-	/*13052*/ uint16(x86_xMatch),
-	/*13053*/ uint16(x86_xCondIs64), 13056, 13068,
-	/*13056*/ uint16(x86_xCondDataSize), 13060, 13064, 0,
-	/*13060*/ uint16(x86_xSetOp), uint16(x86_DEC),
-	/*13062*/ uint16(x86_xArgRM16),
-	/*13063*/ uint16(x86_xMatch),
-	/*13064*/ uint16(x86_xSetOp), uint16(x86_DEC),
-	/*13066*/ uint16(x86_xArgRM32),
-	/*13067*/ uint16(x86_xMatch),
-	/*13068*/ uint16(x86_xCondDataSize), 13060, 13064, 13072,
-	/*13072*/ uint16(x86_xSetOp), uint16(x86_DEC),
-	/*13074*/ uint16(x86_xArgRM64),
-	/*13075*/ uint16(x86_xMatch),
-	/*13076*/ uint16(x86_xCondIs64), 13079, 13091,
-	/*13079*/ uint16(x86_xCondDataSize), 13083, 13087, 0,
-	/*13083*/ uint16(x86_xSetOp), uint16(x86_CALL),
-	/*13085*/ uint16(x86_xArgRM16),
-	/*13086*/ uint16(x86_xMatch),
-	/*13087*/ uint16(x86_xSetOp), uint16(x86_CALL),
-	/*13089*/ uint16(x86_xArgRM32),
-	/*13090*/ uint16(x86_xMatch),
-	/*13091*/ uint16(x86_xSetOp), uint16(x86_CALL),
-	/*13093*/ uint16(x86_xArgRM64),
-	/*13094*/ uint16(x86_xMatch),
-	/*13095*/ uint16(x86_xCondIs64), 13098, 13110,
-	/*13098*/ uint16(x86_xCondDataSize), 13102, 13106, 0,
-	/*13102*/ uint16(x86_xSetOp), uint16(x86_LCALL),
-	/*13104*/ uint16(x86_xArgM16colon16),
-	/*13105*/ uint16(x86_xMatch),
-	/*13106*/ uint16(x86_xSetOp), uint16(x86_LCALL),
-	/*13108*/ uint16(x86_xArgM16colon32),
-	/*13109*/ uint16(x86_xMatch),
-	/*13110*/ uint16(x86_xCondDataSize), 13102, 13106, 13114,
-	/*13114*/ uint16(x86_xSetOp), uint16(x86_LCALL),
-	/*13116*/ uint16(x86_xArgM16colon64),
-	/*13117*/ uint16(x86_xMatch),
-	/*13118*/ uint16(x86_xCondIs64), 13121, 13133,
-	/*13121*/ uint16(x86_xCondDataSize), 13125, 13129, 0,
-	/*13125*/ uint16(x86_xSetOp), uint16(x86_JMP),
-	/*13127*/ uint16(x86_xArgRM16),
-	/*13128*/ uint16(x86_xMatch),
-	/*13129*/ uint16(x86_xSetOp), uint16(x86_JMP),
-	/*13131*/ uint16(x86_xArgRM32),
-	/*13132*/ uint16(x86_xMatch),
-	/*13133*/ uint16(x86_xSetOp), uint16(x86_JMP),
-	/*13135*/ uint16(x86_xArgRM64),
-	/*13136*/ uint16(x86_xMatch),
-	/*13137*/ uint16(x86_xCondIs64), 13140, 13152,
-	/*13140*/ uint16(x86_xCondDataSize), 13144, 13148, 0,
-	/*13144*/ uint16(x86_xSetOp), uint16(x86_LJMP),
-	/*13146*/ uint16(x86_xArgM16colon16),
-	/*13147*/ uint16(x86_xMatch),
-	/*13148*/ uint16(x86_xSetOp), uint16(x86_LJMP),
-	/*13150*/ uint16(x86_xArgM16colon32),
-	/*13151*/ uint16(x86_xMatch),
-	/*13152*/ uint16(x86_xCondDataSize), 13144, 13148, 13156,
-	/*13156*/ uint16(x86_xSetOp), uint16(x86_LJMP),
-	/*13158*/ uint16(x86_xArgM16colon64),
-	/*13159*/ uint16(x86_xMatch),
-	/*13160*/ uint16(x86_xCondIs64), 13163, 13175,
-	/*13163*/ uint16(x86_xCondDataSize), 13167, 13171, 0,
-	/*13167*/ uint16(x86_xSetOp), uint16(x86_PUSH),
-	/*13169*/ uint16(x86_xArgRM16),
-	/*13170*/ uint16(x86_xMatch),
-	/*13171*/ uint16(x86_xSetOp), uint16(x86_PUSH),
-	/*13173*/ uint16(x86_xArgRM32),
-	/*13174*/ uint16(x86_xMatch),
-	/*13175*/ uint16(x86_xCondDataSize), 13167, 13179, 13183,
-	/*13179*/ uint16(x86_xSetOp), uint16(x86_PUSH),
-	/*13181*/ uint16(x86_xArgRM64),
-	/*13182*/ uint16(x86_xMatch),
-	/*13183*/ uint16(x86_xSetOp), uint16(x86_PUSH),
-	/*13185*/ uint16(x86_xArgRM64),
-	/*13186*/ uint16(x86_xMatch),
-}
-
-const (
-	_ x86_Op = iota
-
-	x86_AAA
-	x86_AAD
-	x86_AAM
-	x86_AAS
-	x86_ADC
-	x86_ADD
-	x86_ADDPD
-	x86_ADDPS
-	x86_ADDSD
-	x86_ADDSS
-	x86_ADDSUBPD
-	x86_ADDSUBPS
-	x86_AESDEC
-	x86_AESDECLAST
-	x86_AESENC
-	x86_AESENCLAST
-	x86_AESIMC
-	x86_AESKEYGENASSIST
-	x86_AND
-	x86_ANDNPD
-	x86_ANDNPS
-	x86_ANDPD
-	x86_ANDPS
-	x86_ARPL
-	x86_BLENDPD
-	x86_BLENDPS
-	x86_BLENDVPD
-	x86_BLENDVPS
-	x86_BOUND
-	x86_BSF
-	x86_BSR
-	x86_BSWAP
-	x86_BT
-	x86_BTC
-	x86_BTR
-	x86_BTS
-	x86_CALL
-	x86_CBW
-	x86_CDQ
-	x86_CDQE
-	x86_CLC
-	x86_CLD
-	x86_CLFLUSH
-	x86_CLI
-	x86_CLTS
-	x86_CMC
-	x86_CMOVA
-	x86_CMOVAE
-	x86_CMOVB
-	x86_CMOVBE
-	x86_CMOVE
-	x86_CMOVG
-	x86_CMOVGE
-	x86_CMOVL
-	x86_CMOVLE
-	x86_CMOVNE
-	x86_CMOVNO
-	x86_CMOVNP
-	x86_CMOVNS
-	x86_CMOVO
-	x86_CMOVP
-	x86_CMOVS
-	x86_CMP
-	x86_CMPPD
-	x86_CMPPS
-	x86_CMPSB
-	x86_CMPSD
-	x86_CMPSD_XMM
-	x86_CMPSQ
-	x86_CMPSS
-	x86_CMPSW
-	x86_CMPXCHG
-	x86_CMPXCHG16B
-	x86_CMPXCHG8B
-	x86_COMISD
-	x86_COMISS
-	x86_CPUID
-	x86_CQO
-	x86_CRC32
-	x86_CVTDQ2PD
-	x86_CVTDQ2PS
-	x86_CVTPD2DQ
-	x86_CVTPD2PI
-	x86_CVTPD2PS
-	x86_CVTPI2PD
-	x86_CVTPI2PS
-	x86_CVTPS2DQ
-	x86_CVTPS2PD
-	x86_CVTPS2PI
-	x86_CVTSD2SI
-	x86_CVTSD2SS
-	x86_CVTSI2SD
-	x86_CVTSI2SS
-	x86_CVTSS2SD
-	x86_CVTSS2SI
-	x86_CVTTPD2DQ
-	x86_CVTTPD2PI
-	x86_CVTTPS2DQ
-	x86_CVTTPS2PI
-	x86_CVTTSD2SI
-	x86_CVTTSS2SI
-	x86_CWD
-	x86_CWDE
-	x86_DAA
-	x86_DAS
-	x86_DEC
-	x86_DIV
-	x86_DIVPD
-	x86_DIVPS
-	x86_DIVSD
-	x86_DIVSS
-	x86_DPPD
-	x86_DPPS
-	x86_EMMS
-	x86_ENTER
-	x86_EXTRACTPS
-	x86_F2XM1
-	x86_FABS
-	x86_FADD
-	x86_FADDP
-	x86_FBLD
-	x86_FBSTP
-	x86_FCHS
-	x86_FCMOVB
-	x86_FCMOVBE
-	x86_FCMOVE
-	x86_FCMOVNB
-	x86_FCMOVNBE
-	x86_FCMOVNE
-	x86_FCMOVNU
-	x86_FCMOVU
-	x86_FCOM
-	x86_FCOMI
-	x86_FCOMIP
-	x86_FCOMP
-	x86_FCOMPP
-	x86_FCOS
-	x86_FDECSTP
-	x86_FDIV
-	x86_FDIVP
-	x86_FDIVR
-	x86_FDIVRP
-	x86_FFREE
-	x86_FFREEP
-	x86_FIADD
-	x86_FICOM
-	x86_FICOMP
-	x86_FIDIV
-	x86_FIDIVR
-	x86_FILD
-	x86_FIMUL
-	x86_FINCSTP
-	x86_FIST
-	x86_FISTP
-	x86_FISTTP
-	x86_FISUB
-	x86_FISUBR
-	x86_FLD
-	x86_FLD1
-	x86_FLDCW
-	x86_FLDENV
-	x86_FLDL2E
-	x86_FLDL2T
-	x86_FLDLG2
-	x86_FLDPI
-	x86_FMUL
-	x86_FMULP
-	x86_FNCLEX
-	x86_FNINIT
-	x86_FNOP
-	x86_FNSAVE
-	x86_FNSTCW
-	x86_FNSTENV
-	x86_FNSTSW
-	x86_FPATAN
-	x86_FPREM
-	x86_FPREM1
-	x86_FPTAN
-	x86_FRNDINT
-	x86_FRSTOR
-	x86_FSCALE
-	x86_FSIN
-	x86_FSINCOS
-	x86_FSQRT
-	x86_FST
-	x86_FSTP
-	x86_FSUB
-	x86_FSUBP
-	x86_FSUBR
-	x86_FSUBRP
-	x86_FTST
-	x86_FUCOM
-	x86_FUCOMI
-	x86_FUCOMIP
-	x86_FUCOMP
-	x86_FUCOMPP
-	x86_FWAIT
-	x86_FXAM
-	x86_FXCH
-	x86_FXRSTOR
-	x86_FXRSTOR64
-	x86_FXSAVE
-	x86_FXSAVE64
-	x86_FXTRACT
-	x86_FYL2X
-	x86_FYL2XP1
-	x86_HADDPD
-	x86_HADDPS
-	x86_HLT
-	x86_HSUBPD
-	x86_HSUBPS
-	x86_ICEBP
-	x86_IDIV
-	x86_IMUL
-	x86_IN
-	x86_INC
-	x86_INSB
-	x86_INSD
-	x86_INSERTPS
-	x86_INSW
-	x86_INT
-	x86_INTO
-	x86_INVD
-	x86_INVLPG
-	x86_INVPCID
-	x86_IRET
-	x86_IRETD
-	x86_IRETQ
-	x86_JA
-	x86_JAE
-	x86_JB
-	x86_JBE
-	x86_JCXZ
-	x86_JE
-	x86_JECXZ
-	x86_JG
-	x86_JGE
-	x86_JL
-	x86_JLE
-	x86_JMP
-	x86_JNE
-	x86_JNO
-	x86_JNP
-	x86_JNS
-	x86_JO
-	x86_JP
-	x86_JRCXZ
-	x86_JS
-	x86_LAHF
-	x86_LAR
-	x86_LCALL
-	x86_LDDQU
-	x86_LDMXCSR
-	x86_LDS
-	x86_LEA
-	x86_LEAVE
-	x86_LES
-	x86_LFENCE
-	x86_LFS
-	x86_LGDT
-	x86_LGS
-	x86_LIDT
-	x86_LJMP
-	x86_LLDT
-	x86_LMSW
-	x86_LODSB
-	x86_LODSD
-	x86_LODSQ
-	x86_LODSW
-	x86_LOOP
-	x86_LOOPE
-	x86_LOOPNE
-	x86_LRET
-	x86_LSL
-	x86_LSS
-	x86_LTR
-	x86_LZCNT
-	x86_MASKMOVDQU
-	x86_MASKMOVQ
-	x86_MAXPD
-	x86_MAXPS
-	x86_MAXSD
-	x86_MAXSS
-	x86_MFENCE
-	x86_MINPD
-	x86_MINPS
-	x86_MINSD
-	x86_MINSS
-	x86_MONITOR
-	x86_MOV
-	x86_MOVAPD
-	x86_MOVAPS
-	x86_MOVBE
-	x86_MOVD
-	x86_MOVDDUP
-	x86_MOVDQ2Q
-	x86_MOVDQA
-	x86_MOVDQU
-	x86_MOVHLPS
-	x86_MOVHPD
-	x86_MOVHPS
-	x86_MOVLHPS
-	x86_MOVLPD
-	x86_MOVLPS
-	x86_MOVMSKPD
-	x86_MOVMSKPS
-	x86_MOVNTDQ
-	x86_MOVNTDQA
-	x86_MOVNTI
-	x86_MOVNTPD
-	x86_MOVNTPS
-	x86_MOVNTQ
-	x86_MOVNTSD
-	x86_MOVNTSS
-	x86_MOVQ
-	x86_MOVQ2DQ
-	x86_MOVSB
-	x86_MOVSD
-	x86_MOVSD_XMM
-	x86_MOVSHDUP
-	x86_MOVSLDUP
-	x86_MOVSQ
-	x86_MOVSS
-	x86_MOVSW
-	x86_MOVSX
-	x86_MOVSXD
-	x86_MOVUPD
-	x86_MOVUPS
-	x86_MOVZX
-	x86_MPSADBW
-	x86_MUL
-	x86_MULPD
-	x86_MULPS
-	x86_MULSD
-	x86_MULSS
-	x86_MWAIT
-	x86_NEG
-	x86_NOP
-	x86_NOT
-	x86_OR
-	x86_ORPD
-	x86_ORPS
-	x86_OUT
-	x86_OUTSB
-	x86_OUTSD
-	x86_OUTSW
-	x86_PABSB
-	x86_PABSD
-	x86_PABSW
-	x86_PACKSSDW
-	x86_PACKSSWB
-	x86_PACKUSDW
-	x86_PACKUSWB
-	x86_PADDB
-	x86_PADDD
-	x86_PADDQ
-	x86_PADDSB
-	x86_PADDSW
-	x86_PADDUSB
-	x86_PADDUSW
-	x86_PADDW
-	x86_PALIGNR
-	x86_PAND
-	x86_PANDN
-	x86_PAUSE
-	x86_PAVGB
-	x86_PAVGW
-	x86_PBLENDVB
-	x86_PBLENDW
-	x86_PCLMULQDQ
-	x86_PCMPEQB
-	x86_PCMPEQD
-	x86_PCMPEQQ
-	x86_PCMPEQW
-	x86_PCMPESTRI
-	x86_PCMPESTRM
-	x86_PCMPGTB
-	x86_PCMPGTD
-	x86_PCMPGTQ
-	x86_PCMPGTW
-	x86_PCMPISTRI
-	x86_PCMPISTRM
-	x86_PEXTRB
-	x86_PEXTRD
-	x86_PEXTRQ
-	x86_PEXTRW
-	x86_PHADDD
-	x86_PHADDSW
-	x86_PHADDW
-	x86_PHMINPOSUW
-	x86_PHSUBD
-	x86_PHSUBSW
-	x86_PHSUBW
-	x86_PINSRB
-	x86_PINSRD
-	x86_PINSRQ
-	x86_PINSRW
-	x86_PMADDUBSW
-	x86_PMADDWD
-	x86_PMAXSB
-	x86_PMAXSD
-	x86_PMAXSW
-	x86_PMAXUB
-	x86_PMAXUD
-	x86_PMAXUW
-	x86_PMINSB
-	x86_PMINSD
-	x86_PMINSW
-	x86_PMINUB
-	x86_PMINUD
-	x86_PMINUW
-	x86_PMOVMSKB
-	x86_PMOVSXBD
-	x86_PMOVSXBQ
-	x86_PMOVSXBW
-	x86_PMOVSXDQ
-	x86_PMOVSXWD
-	x86_PMOVSXWQ
-	x86_PMOVZXBD
-	x86_PMOVZXBQ
-	x86_PMOVZXBW
-	x86_PMOVZXDQ
-	x86_PMOVZXWD
-	x86_PMOVZXWQ
-	x86_PMULDQ
-	x86_PMULHRSW
-	x86_PMULHUW
-	x86_PMULHW
-	x86_PMULLD
-	x86_PMULLW
-	x86_PMULUDQ
-	x86_POP
-	x86_POPA
-	x86_POPAD
-	x86_POPCNT
-	x86_POPF
-	x86_POPFD
-	x86_POPFQ
-	x86_POR
-	x86_PREFETCHNTA
-	x86_PREFETCHT0
-	x86_PREFETCHT1
-	x86_PREFETCHT2
-	x86_PREFETCHW
-	x86_PSADBW
-	x86_PSHUFB
-	x86_PSHUFD
-	x86_PSHUFHW
-	x86_PSHUFLW
-	x86_PSHUFW
-	x86_PSIGNB
-	x86_PSIGND
-	x86_PSIGNW
-	x86_PSLLD
-	x86_PSLLDQ
-	x86_PSLLQ
-	x86_PSLLW
-	x86_PSRAD
-	x86_PSRAW
-	x86_PSRLD
-	x86_PSRLDQ
-	x86_PSRLQ
-	x86_PSRLW
-	x86_PSUBB
-	x86_PSUBD
-	x86_PSUBQ
-	x86_PSUBSB
-	x86_PSUBSW
-	x86_PSUBUSB
-	x86_PSUBUSW
-	x86_PSUBW
-	x86_PTEST
-	x86_PUNPCKHBW
-	x86_PUNPCKHDQ
-	x86_PUNPCKHQDQ
-	x86_PUNPCKHWD
-	x86_PUNPCKLBW
-	x86_PUNPCKLDQ
-	x86_PUNPCKLQDQ
-	x86_PUNPCKLWD
-	x86_PUSH
-	x86_PUSHA
-	x86_PUSHAD
-	x86_PUSHF
-	x86_PUSHFD
-	x86_PUSHFQ
-	x86_PXOR
-	x86_RCL
-	x86_RCPPS
-	x86_RCPSS
-	x86_RCR
-	x86_RDFSBASE
-	x86_RDGSBASE
-	x86_RDMSR
-	x86_RDPMC
-	x86_RDRAND
-	x86_RDTSC
-	x86_RDTSCP
-	x86_RET
-	x86_ROL
-	x86_ROR
-	x86_ROUNDPD
-	x86_ROUNDPS
-	x86_ROUNDSD
-	x86_ROUNDSS
-	x86_RSM
-	x86_RSQRTPS
-	x86_RSQRTSS
-	x86_SAHF
-	x86_SAR
-	x86_SBB
-	x86_SCASB
-	x86_SCASD
-	x86_SCASQ
-	x86_SCASW
-	x86_SETA
-	x86_SETAE
-	x86_SETB
-	x86_SETBE
-	x86_SETE
-	x86_SETG
-	x86_SETGE
-	x86_SETL
-	x86_SETLE
-	x86_SETNE
-	x86_SETNO
-	x86_SETNP
-	x86_SETNS
-	x86_SETO
-	x86_SETP
-	x86_SETS
-	x86_SFENCE
-	x86_SGDT
-	x86_SHL
-	x86_SHLD
-	x86_SHR
-	x86_SHRD
-	x86_SHUFPD
-	x86_SHUFPS
-	x86_SIDT
-	x86_SLDT
-	x86_SMSW
-	x86_SQRTPD
-	x86_SQRTPS
-	x86_SQRTSD
-	x86_SQRTSS
-	x86_STC
-	x86_STD
-	x86_STI
-	x86_STMXCSR
-	x86_STOSB
-	x86_STOSD
-	x86_STOSQ
-	x86_STOSW
-	x86_STR
-	x86_SUB
-	x86_SUBPD
-	x86_SUBPS
-	x86_SUBSD
-	x86_SUBSS
-	x86_SWAPGS
-	x86_SYSCALL
-	x86_SYSENTER
-	x86_SYSEXIT
-	x86_SYSRET
-	x86_TEST
-	x86_TZCNT
-	x86_UCOMISD
-	x86_UCOMISS
-	x86_UD1
-	x86_UD2
-	x86_UNPCKHPD
-	x86_UNPCKHPS
-	x86_UNPCKLPD
-	x86_UNPCKLPS
-	x86_VERR
-	x86_VERW
-	x86_WBINVD
-	x86_WRFSBASE
-	x86_WRGSBASE
-	x86_WRMSR
-	x86_XABORT
-	x86_XADD
-	x86_XBEGIN
-	x86_XCHG
-	x86_XEND
-	x86_XGETBV
-	x86_XLATB
-	x86_XOR
-	x86_XORPD
-	x86_XORPS
-	x86_XRSTOR
-	x86_XRSTOR64
-	x86_XRSTORS
-	x86_XRSTORS64
-	x86_XSAVE
-	x86_XSAVE64
-	x86_XSAVEC
-	x86_XSAVEC64
-	x86_XSAVEOPT
-	x86_XSAVEOPT64
-	x86_XSAVES
-	x86_XSAVES64
-	x86_XSETBV
-	x86_XTEST
-)
-
-const x86_maxOp = x86_XTEST
-
-var x86_opNames = [...]string{
-	x86_AAA:             "AAA",
-	x86_AAD:             "AAD",
-	x86_AAM:             "AAM",
-	x86_AAS:             "AAS",
-	x86_ADC:             "ADC",
-	x86_ADD:             "ADD",
-	x86_ADDPD:           "ADDPD",
-	x86_ADDPS:           "ADDPS",
-	x86_ADDSD:           "ADDSD",
-	x86_ADDSS:           "ADDSS",
-	x86_ADDSUBPD:        "ADDSUBPD",
-	x86_ADDSUBPS:        "ADDSUBPS",
-	x86_AESDEC:          "AESDEC",
-	x86_AESDECLAST:      "AESDECLAST",
-	x86_AESENC:          "AESENC",
-	x86_AESENCLAST:      "AESENCLAST",
-	x86_AESIMC:          "AESIMC",
-	x86_AESKEYGENASSIST: "AESKEYGENASSIST",
-	x86_AND:             "AND",
-	x86_ANDNPD:          "ANDNPD",
-	x86_ANDNPS:          "ANDNPS",
-	x86_ANDPD:           "ANDPD",
-	x86_ANDPS:           "ANDPS",
-	x86_ARPL:            "ARPL",
-	x86_BLENDPD:         "BLENDPD",
-	x86_BLENDPS:         "BLENDPS",
-	x86_BLENDVPD:        "BLENDVPD",
-	x86_BLENDVPS:        "BLENDVPS",
-	x86_BOUND:           "BOUND",
-	x86_BSF:             "BSF",
-	x86_BSR:             "BSR",
-	x86_BSWAP:           "BSWAP",
-	x86_BT:              "BT",
-	x86_BTC:             "BTC",
-	x86_BTR:             "BTR",
-	x86_BTS:             "BTS",
-	x86_CALL:            "CALL",
-	x86_CBW:             "CBW",
-	x86_CDQ:             "CDQ",
-	x86_CDQE:            "CDQE",
-	x86_CLC:             "CLC",
-	x86_CLD:             "CLD",
-	x86_CLFLUSH:         "CLFLUSH",
-	x86_CLI:             "CLI",
-	x86_CLTS:            "CLTS",
-	x86_CMC:             "CMC",
-	x86_CMOVA:           "CMOVA",
-	x86_CMOVAE:          "CMOVAE",
-	x86_CMOVB:           "CMOVB",
-	x86_CMOVBE:          "CMOVBE",
-	x86_CMOVE:           "CMOVE",
-	x86_CMOVG:           "CMOVG",
-	x86_CMOVGE:          "CMOVGE",
-	x86_CMOVL:           "CMOVL",
-	x86_CMOVLE:          "CMOVLE",
-	x86_CMOVNE:          "CMOVNE",
-	x86_CMOVNO:          "CMOVNO",
-	x86_CMOVNP:          "CMOVNP",
-	x86_CMOVNS:          "CMOVNS",
-	x86_CMOVO:           "CMOVO",
-	x86_CMOVP:           "CMOVP",
-	x86_CMOVS:           "CMOVS",
-	x86_CMP:             "CMP",
-	x86_CMPPD:           "CMPPD",
-	x86_CMPPS:           "CMPPS",
-	x86_CMPSB:           "CMPSB",
-	x86_CMPSD:           "CMPSD",
-	x86_CMPSD_XMM:       "CMPSD_XMM",
-	x86_CMPSQ:           "CMPSQ",
-	x86_CMPSS:           "CMPSS",
-	x86_CMPSW:           "CMPSW",
-	x86_CMPXCHG:         "CMPXCHG",
-	x86_CMPXCHG16B:      "CMPXCHG16B",
-	x86_CMPXCHG8B:       "CMPXCHG8B",
-	x86_COMISD:          "COMISD",
-	x86_COMISS:          "COMISS",
-	x86_CPUID:           "CPUID",
-	x86_CQO:             "CQO",
-	x86_CRC32:           "CRC32",
-	x86_CVTDQ2PD:        "CVTDQ2PD",
-	x86_CVTDQ2PS:        "CVTDQ2PS",
-	x86_CVTPD2DQ:        "CVTPD2DQ",
-	x86_CVTPD2PI:        "CVTPD2PI",
-	x86_CVTPD2PS:        "CVTPD2PS",
-	x86_CVTPI2PD:        "CVTPI2PD",
-	x86_CVTPI2PS:        "CVTPI2PS",
-	x86_CVTPS2DQ:        "CVTPS2DQ",
-	x86_CVTPS2PD:        "CVTPS2PD",
-	x86_CVTPS2PI:        "CVTPS2PI",
-	x86_CVTSD2SI:        "CVTSD2SI",
-	x86_CVTSD2SS:        "CVTSD2SS",
-	x86_CVTSI2SD:        "CVTSI2SD",
-	x86_CVTSI2SS:        "CVTSI2SS",
-	x86_CVTSS2SD:        "CVTSS2SD",
-	x86_CVTSS2SI:        "CVTSS2SI",
-	x86_CVTTPD2DQ:       "CVTTPD2DQ",
-	x86_CVTTPD2PI:       "CVTTPD2PI",
-	x86_CVTTPS2DQ:       "CVTTPS2DQ",
-	x86_CVTTPS2PI:       "CVTTPS2PI",
-	x86_CVTTSD2SI:       "CVTTSD2SI",
-	x86_CVTTSS2SI:       "CVTTSS2SI",
-	x86_CWD:             "CWD",
-	x86_CWDE:            "CWDE",
-	x86_DAA:             "DAA",
-	x86_DAS:             "DAS",
-	x86_DEC:             "DEC",
-	x86_DIV:             "DIV",
-	x86_DIVPD:           "DIVPD",
-	x86_DIVPS:           "DIVPS",
-	x86_DIVSD:           "DIVSD",
-	x86_DIVSS:           "DIVSS",
-	x86_DPPD:            "DPPD",
-	x86_DPPS:            "DPPS",
-	x86_EMMS:            "EMMS",
-	x86_ENTER:           "ENTER",
-	x86_EXTRACTPS:       "EXTRACTPS",
-	x86_F2XM1:           "F2XM1",
-	x86_FABS:            "FABS",
-	x86_FADD:            "FADD",
-	x86_FADDP:           "FADDP",
-	x86_FBLD:            "FBLD",
-	x86_FBSTP:           "FBSTP",
-	x86_FCHS:            "FCHS",
-	x86_FCMOVB:          "FCMOVB",
-	x86_FCMOVBE:         "FCMOVBE",
-	x86_FCMOVE:          "FCMOVE",
-	x86_FCMOVNB:         "FCMOVNB",
-	x86_FCMOVNBE:        "FCMOVNBE",
-	x86_FCMOVNE:         "FCMOVNE",
-	x86_FCMOVNU:         "FCMOVNU",
-	x86_FCMOVU:          "FCMOVU",
-	x86_FCOM:            "FCOM",
-	x86_FCOMI:           "FCOMI",
-	x86_FCOMIP:          "FCOMIP",
-	x86_FCOMP:           "FCOMP",
-	x86_FCOMPP:          "FCOMPP",
-	x86_FCOS:            "FCOS",
-	x86_FDECSTP:         "FDECSTP",
-	x86_FDIV:            "FDIV",
-	x86_FDIVP:           "FDIVP",
-	x86_FDIVR:           "FDIVR",
-	x86_FDIVRP:          "FDIVRP",
-	x86_FFREE:           "FFREE",
-	x86_FFREEP:          "FFREEP",
-	x86_FIADD:           "FIADD",
-	x86_FICOM:           "FICOM",
-	x86_FICOMP:          "FICOMP",
-	x86_FIDIV:           "FIDIV",
-	x86_FIDIVR:          "FIDIVR",
-	x86_FILD:            "FILD",
-	x86_FIMUL:           "FIMUL",
-	x86_FINCSTP:         "FINCSTP",
-	x86_FIST:            "FIST",
-	x86_FISTP:           "FISTP",
-	x86_FISTTP:          "FISTTP",
-	x86_FISUB:           "FISUB",
-	x86_FISUBR:          "FISUBR",
-	x86_FLD:             "FLD",
-	x86_FLD1:            "FLD1",
-	x86_FLDCW:           "FLDCW",
-	x86_FLDENV:          "FLDENV",
-	x86_FLDL2E:          "FLDL2E",
-	x86_FLDL2T:          "FLDL2T",
-	x86_FLDLG2:          "FLDLG2",
-	x86_FLDPI:           "FLDPI",
-	x86_FMUL:            "FMUL",
-	x86_FMULP:           "FMULP",
-	x86_FNCLEX:          "FNCLEX",
-	x86_FNINIT:          "FNINIT",
-	x86_FNOP:            "FNOP",
-	x86_FNSAVE:          "FNSAVE",
-	x86_FNSTCW:          "FNSTCW",
-	x86_FNSTENV:         "FNSTENV",
-	x86_FNSTSW:          "FNSTSW",
-	x86_FPATAN:          "FPATAN",
-	x86_FPREM:           "FPREM",
-	x86_FPREM1:          "FPREM1",
-	x86_FPTAN:           "FPTAN",
-	x86_FRNDINT:         "FRNDINT",
-	x86_FRSTOR:          "FRSTOR",
-	x86_FSCALE:          "FSCALE",
-	x86_FSIN:            "FSIN",
-	x86_FSINCOS:         "FSINCOS",
-	x86_FSQRT:           "FSQRT",
-	x86_FST:             "FST",
-	x86_FSTP:            "FSTP",
-	x86_FSUB:            "FSUB",
-	x86_FSUBP:           "FSUBP",
-	x86_FSUBR:           "FSUBR",
-	x86_FSUBRP:          "FSUBRP",
-	x86_FTST:            "FTST",
-	x86_FUCOM:           "FUCOM",
-	x86_FUCOMI:          "FUCOMI",
-	x86_FUCOMIP:         "FUCOMIP",
-	x86_FUCOMP:          "FUCOMP",
-	x86_FUCOMPP:         "FUCOMPP",
-	x86_FWAIT:           "FWAIT",
-	x86_FXAM:            "FXAM",
-	x86_FXCH:            "FXCH",
-	x86_FXRSTOR:         "FXRSTOR",
-	x86_FXRSTOR64:       "FXRSTOR64",
-	x86_FXSAVE:          "FXSAVE",
-	x86_FXSAVE64:        "FXSAVE64",
-	x86_FXTRACT:         "FXTRACT",
-	x86_FYL2X:           "FYL2X",
-	x86_FYL2XP1:         "FYL2XP1",
-	x86_HADDPD:          "HADDPD",
-	x86_HADDPS:          "HADDPS",
-	x86_HLT:             "HLT",
-	x86_HSUBPD:          "HSUBPD",
-	x86_HSUBPS:          "HSUBPS",
-	x86_ICEBP:           "ICEBP",
-	x86_IDIV:            "IDIV",
-	x86_IMUL:            "IMUL",
-	x86_IN:              "IN",
-	x86_INC:             "INC",
-	x86_INSB:            "INSB",
-	x86_INSD:            "INSD",
-	x86_INSERTPS:        "INSERTPS",
-	x86_INSW:            "INSW",
-	x86_INT:             "INT",
-	x86_INTO:            "INTO",
-	x86_INVD:            "INVD",
-	x86_INVLPG:          "INVLPG",
-	x86_INVPCID:         "INVPCID",
-	x86_IRET:            "IRET",
-	x86_IRETD:           "IRETD",
-	x86_IRETQ:           "IRETQ",
-	x86_JA:              "JA",
-	x86_JAE:             "JAE",
-	x86_JB:              "JB",
-	x86_JBE:             "JBE",
-	x86_JCXZ:            "JCXZ",
-	x86_JE:              "JE",
-	x86_JECXZ:           "JECXZ",
-	x86_JG:              "JG",
-	x86_JGE:             "JGE",
-	x86_JL:              "JL",
-	x86_JLE:             "JLE",
-	x86_JMP:             "JMP",
-	x86_JNE:             "JNE",
-	x86_JNO:             "JNO",
-	x86_JNP:             "JNP",
-	x86_JNS:             "JNS",
-	x86_JO:              "JO",
-	x86_JP:              "JP",
-	x86_JRCXZ:           "JRCXZ",
-	x86_JS:              "JS",
-	x86_LAHF:            "LAHF",
-	x86_LAR:             "LAR",
-	x86_LCALL:           "LCALL",
-	x86_LDDQU:           "LDDQU",
-	x86_LDMXCSR:         "LDMXCSR",
-	x86_LDS:             "LDS",
-	x86_LEA:             "LEA",
-	x86_LEAVE:           "LEAVE",
-	x86_LES:             "LES",
-	x86_LFENCE:          "LFENCE",
-	x86_LFS:             "LFS",
-	x86_LGDT:            "LGDT",
-	x86_LGS:             "LGS",
-	x86_LIDT:            "LIDT",
-	x86_LJMP:            "LJMP",
-	x86_LLDT:            "LLDT",
-	x86_LMSW:            "LMSW",
-	x86_LODSB:           "LODSB",
-	x86_LODSD:           "LODSD",
-	x86_LODSQ:           "LODSQ",
-	x86_LODSW:           "LODSW",
-	x86_LOOP:            "LOOP",
-	x86_LOOPE:           "LOOPE",
-	x86_LOOPNE:          "LOOPNE",
-	x86_LRET:            "LRET",
-	x86_LSL:             "LSL",
-	x86_LSS:             "LSS",
-	x86_LTR:             "LTR",
-	x86_LZCNT:           "LZCNT",
-	x86_MASKMOVDQU:      "MASKMOVDQU",
-	x86_MASKMOVQ:        "MASKMOVQ",
-	x86_MAXPD:           "MAXPD",
-	x86_MAXPS:           "MAXPS",
-	x86_MAXSD:           "MAXSD",
-	x86_MAXSS:           "MAXSS",
-	x86_MFENCE:          "MFENCE",
-	x86_MINPD:           "MINPD",
-	x86_MINPS:           "MINPS",
-	x86_MINSD:           "MINSD",
-	x86_MINSS:           "MINSS",
-	x86_MONITOR:         "MONITOR",
-	x86_MOV:             "MOV",
-	x86_MOVAPD:          "MOVAPD",
-	x86_MOVAPS:          "MOVAPS",
-	x86_MOVBE:           "MOVBE",
-	x86_MOVD:            "MOVD",
-	x86_MOVDDUP:         "MOVDDUP",
-	x86_MOVDQ2Q:         "MOVDQ2Q",
-	x86_MOVDQA:          "MOVDQA",
-	x86_MOVDQU:          "MOVDQU",
-	x86_MOVHLPS:         "MOVHLPS",
-	x86_MOVHPD:          "MOVHPD",
-	x86_MOVHPS:          "MOVHPS",
-	x86_MOVLHPS:         "MOVLHPS",
-	x86_MOVLPD:          "MOVLPD",
-	x86_MOVLPS:          "MOVLPS",
-	x86_MOVMSKPD:        "MOVMSKPD",
-	x86_MOVMSKPS:        "MOVMSKPS",
-	x86_MOVNTDQ:         "MOVNTDQ",
-	x86_MOVNTDQA:        "MOVNTDQA",
-	x86_MOVNTI:          "MOVNTI",
-	x86_MOVNTPD:         "MOVNTPD",
-	x86_MOVNTPS:         "MOVNTPS",
-	x86_MOVNTQ:          "MOVNTQ",
-	x86_MOVNTSD:         "MOVNTSD",
-	x86_MOVNTSS:         "MOVNTSS",
-	x86_MOVQ:            "MOVQ",
-	x86_MOVQ2DQ:         "MOVQ2DQ",
-	x86_MOVSB:           "MOVSB",
-	x86_MOVSD:           "MOVSD",
-	x86_MOVSD_XMM:       "MOVSD_XMM",
-	x86_MOVSHDUP:        "MOVSHDUP",
-	x86_MOVSLDUP:        "MOVSLDUP",
-	x86_MOVSQ:           "MOVSQ",
-	x86_MOVSS:           "MOVSS",
-	x86_MOVSW:           "MOVSW",
-	x86_MOVSX:           "MOVSX",
-	x86_MOVSXD:          "MOVSXD",
-	x86_MOVUPD:          "MOVUPD",
-	x86_MOVUPS:          "MOVUPS",
-	x86_MOVZX:           "MOVZX",
-	x86_MPSADBW:         "MPSADBW",
-	x86_MUL:             "MUL",
-	x86_MULPD:           "MULPD",
-	x86_MULPS:           "MULPS",
-	x86_MULSD:           "MULSD",
-	x86_MULSS:           "MULSS",
-	x86_MWAIT:           "MWAIT",
-	x86_NEG:             "NEG",
-	x86_NOP:             "NOP",
-	x86_NOT:             "NOT",
-	x86_OR:              "OR",
-	x86_ORPD:            "ORPD",
-	x86_ORPS:            "ORPS",
-	x86_OUT:             "OUT",
-	x86_OUTSB:           "OUTSB",
-	x86_OUTSD:           "OUTSD",
-	x86_OUTSW:           "OUTSW",
-	x86_PABSB:           "PABSB",
-	x86_PABSD:           "PABSD",
-	x86_PABSW:           "PABSW",
-	x86_PACKSSDW:        "PACKSSDW",
-	x86_PACKSSWB:        "PACKSSWB",
-	x86_PACKUSDW:        "PACKUSDW",
-	x86_PACKUSWB:        "PACKUSWB",
-	x86_PADDB:           "PADDB",
-	x86_PADDD:           "PADDD",
-	x86_PADDQ:           "PADDQ",
-	x86_PADDSB:          "PADDSB",
-	x86_PADDSW:          "PADDSW",
-	x86_PADDUSB:         "PADDUSB",
-	x86_PADDUSW:         "PADDUSW",
-	x86_PADDW:           "PADDW",
-	x86_PALIGNR:         "PALIGNR",
-	x86_PAND:            "PAND",
-	x86_PANDN:           "PANDN",
-	x86_PAUSE:           "PAUSE",
-	x86_PAVGB:           "PAVGB",
-	x86_PAVGW:           "PAVGW",
-	x86_PBLENDVB:        "PBLENDVB",
-	x86_PBLENDW:         "PBLENDW",
-	x86_PCLMULQDQ:       "PCLMULQDQ",
-	x86_PCMPEQB:         "PCMPEQB",
-	x86_PCMPEQD:         "PCMPEQD",
-	x86_PCMPEQQ:         "PCMPEQQ",
-	x86_PCMPEQW:         "PCMPEQW",
-	x86_PCMPESTRI:       "PCMPESTRI",
-	x86_PCMPESTRM:       "PCMPESTRM",
-	x86_PCMPGTB:         "PCMPGTB",
-	x86_PCMPGTD:         "PCMPGTD",
-	x86_PCMPGTQ:         "PCMPGTQ",
-	x86_PCMPGTW:         "PCMPGTW",
-	x86_PCMPISTRI:       "PCMPISTRI",
-	x86_PCMPISTRM:       "PCMPISTRM",
-	x86_PEXTRB:          "PEXTRB",
-	x86_PEXTRD:          "PEXTRD",
-	x86_PEXTRQ:          "PEXTRQ",
-	x86_PEXTRW:          "PEXTRW",
-	x86_PHADDD:          "PHADDD",
-	x86_PHADDSW:         "PHADDSW",
-	x86_PHADDW:          "PHADDW",
-	x86_PHMINPOSUW:      "PHMINPOSUW",
-	x86_PHSUBD:          "PHSUBD",
-	x86_PHSUBSW:         "PHSUBSW",
-	x86_PHSUBW:          "PHSUBW",
-	x86_PINSRB:          "PINSRB",
-	x86_PINSRD:          "PINSRD",
-	x86_PINSRQ:          "PINSRQ",
-	x86_PINSRW:          "PINSRW",
-	x86_PMADDUBSW:       "PMADDUBSW",
-	x86_PMADDWD:         "PMADDWD",
-	x86_PMAXSB:          "PMAXSB",
-	x86_PMAXSD:          "PMAXSD",
-	x86_PMAXSW:          "PMAXSW",
-	x86_PMAXUB:          "PMAXUB",
-	x86_PMAXUD:          "PMAXUD",
-	x86_PMAXUW:          "PMAXUW",
-	x86_PMINSB:          "PMINSB",
-	x86_PMINSD:          "PMINSD",
-	x86_PMINSW:          "PMINSW",
-	x86_PMINUB:          "PMINUB",
-	x86_PMINUD:          "PMINUD",
-	x86_PMINUW:          "PMINUW",
-	x86_PMOVMSKB:        "PMOVMSKB",
-	x86_PMOVSXBD:        "PMOVSXBD",
-	x86_PMOVSXBQ:        "PMOVSXBQ",
-	x86_PMOVSXBW:        "PMOVSXBW",
-	x86_PMOVSXDQ:        "PMOVSXDQ",
-	x86_PMOVSXWD:        "PMOVSXWD",
-	x86_PMOVSXWQ:        "PMOVSXWQ",
-	x86_PMOVZXBD:        "PMOVZXBD",
-	x86_PMOVZXBQ:        "PMOVZXBQ",
-	x86_PMOVZXBW:        "PMOVZXBW",
-	x86_PMOVZXDQ:        "PMOVZXDQ",
-	x86_PMOVZXWD:        "PMOVZXWD",
-	x86_PMOVZXWQ:        "PMOVZXWQ",
-	x86_PMULDQ:          "PMULDQ",
-	x86_PMULHRSW:        "PMULHRSW",
-	x86_PMULHUW:         "PMULHUW",
-	x86_PMULHW:          "PMULHW",
-	x86_PMULLD:          "PMULLD",
-	x86_PMULLW:          "PMULLW",
-	x86_PMULUDQ:         "PMULUDQ",
-	x86_POP:             "POP",
-	x86_POPA:            "POPA",
-	x86_POPAD:           "POPAD",
-	x86_POPCNT:          "POPCNT",
-	x86_POPF:            "POPF",
-	x86_POPFD:           "POPFD",
-	x86_POPFQ:           "POPFQ",
-	x86_POR:             "POR",
-	x86_PREFETCHNTA:     "PREFETCHNTA",
-	x86_PREFETCHT0:      "PREFETCHT0",
-	x86_PREFETCHT1:      "PREFETCHT1",
-	x86_PREFETCHT2:      "PREFETCHT2",
-	x86_PREFETCHW:       "PREFETCHW",
-	x86_PSADBW:          "PSADBW",
-	x86_PSHUFB:          "PSHUFB",
-	x86_PSHUFD:          "PSHUFD",
-	x86_PSHUFHW:         "PSHUFHW",
-	x86_PSHUFLW:         "PSHUFLW",
-	x86_PSHUFW:          "PSHUFW",
-	x86_PSIGNB:          "PSIGNB",
-	x86_PSIGND:          "PSIGND",
-	x86_PSIGNW:          "PSIGNW",
-	x86_PSLLD:           "PSLLD",
-	x86_PSLLDQ:          "PSLLDQ",
-	x86_PSLLQ:           "PSLLQ",
-	x86_PSLLW:           "PSLLW",
-	x86_PSRAD:           "PSRAD",
-	x86_PSRAW:           "PSRAW",
-	x86_PSRLD:           "PSRLD",
-	x86_PSRLDQ:          "PSRLDQ",
-	x86_PSRLQ:           "PSRLQ",
-	x86_PSRLW:           "PSRLW",
-	x86_PSUBB:           "PSUBB",
-	x86_PSUBD:           "PSUBD",
-	x86_PSUBQ:           "PSUBQ",
-	x86_PSUBSB:          "PSUBSB",
-	x86_PSUBSW:          "PSUBSW",
-	x86_PSUBUSB:         "PSUBUSB",
-	x86_PSUBUSW:         "PSUBUSW",
-	x86_PSUBW:           "PSUBW",
-	x86_PTEST:           "PTEST",
-	x86_PUNPCKHBW:       "PUNPCKHBW",
-	x86_PUNPCKHDQ:       "PUNPCKHDQ",
-	x86_PUNPCKHQDQ:      "PUNPCKHQDQ",
-	x86_PUNPCKHWD:       "PUNPCKHWD",
-	x86_PUNPCKLBW:       "PUNPCKLBW",
-	x86_PUNPCKLDQ:       "PUNPCKLDQ",
-	x86_PUNPCKLQDQ:      "PUNPCKLQDQ",
-	x86_PUNPCKLWD:       "PUNPCKLWD",
-	x86_PUSH:            "PUSH",
-	x86_PUSHA:           "PUSHA",
-	x86_PUSHAD:          "PUSHAD",
-	x86_PUSHF:           "PUSHF",
-	x86_PUSHFD:          "PUSHFD",
-	x86_PUSHFQ:          "PUSHFQ",
-	x86_PXOR:            "PXOR",
-	x86_RCL:             "RCL",
-	x86_RCPPS:           "RCPPS",
-	x86_RCPSS:           "RCPSS",
-	x86_RCR:             "RCR",
-	x86_RDFSBASE:        "RDFSBASE",
-	x86_RDGSBASE:        "RDGSBASE",
-	x86_RDMSR:           "RDMSR",
-	x86_RDPMC:           "RDPMC",
-	x86_RDRAND:          "RDRAND",
-	x86_RDTSC:           "RDTSC",
-	x86_RDTSCP:          "RDTSCP",
-	x86_RET:             "RET",
-	x86_ROL:             "ROL",
-	x86_ROR:             "ROR",
-	x86_ROUNDPD:         "ROUNDPD",
-	x86_ROUNDPS:         "ROUNDPS",
-	x86_ROUNDSD:         "ROUNDSD",
-	x86_ROUNDSS:         "ROUNDSS",
-	x86_RSM:             "RSM",
-	x86_RSQRTPS:         "RSQRTPS",
-	x86_RSQRTSS:         "RSQRTSS",
-	x86_SAHF:            "SAHF",
-	x86_SAR:             "SAR",
-	x86_SBB:             "SBB",
-	x86_SCASB:           "SCASB",
-	x86_SCASD:           "SCASD",
-	x86_SCASQ:           "SCASQ",
-	x86_SCASW:           "SCASW",
-	x86_SETA:            "SETA",
-	x86_SETAE:           "SETAE",
-	x86_SETB:            "SETB",
-	x86_SETBE:           "SETBE",
-	x86_SETE:            "SETE",
-	x86_SETG:            "SETG",
-	x86_SETGE:           "SETGE",
-	x86_SETL:            "SETL",
-	x86_SETLE:           "SETLE",
-	x86_SETNE:           "SETNE",
-	x86_SETNO:           "SETNO",
-	x86_SETNP:           "SETNP",
-	x86_SETNS:           "SETNS",
-	x86_SETO:            "SETO",
-	x86_SETP:            "SETP",
-	x86_SETS:            "SETS",
-	x86_SFENCE:          "SFENCE",
-	x86_SGDT:            "SGDT",
-	x86_SHL:             "SHL",
-	x86_SHLD:            "SHLD",
-	x86_SHR:             "SHR",
-	x86_SHRD:            "SHRD",
-	x86_SHUFPD:          "SHUFPD",
-	x86_SHUFPS:          "SHUFPS",
-	x86_SIDT:            "SIDT",
-	x86_SLDT:            "SLDT",
-	x86_SMSW:            "SMSW",
-	x86_SQRTPD:          "SQRTPD",
-	x86_SQRTPS:          "SQRTPS",
-	x86_SQRTSD:          "SQRTSD",
-	x86_SQRTSS:          "SQRTSS",
-	x86_STC:             "STC",
-	x86_STD:             "STD",
-	x86_STI:             "STI",
-	x86_STMXCSR:         "STMXCSR",
-	x86_STOSB:           "STOSB",
-	x86_STOSD:           "STOSD",
-	x86_STOSQ:           "STOSQ",
-	x86_STOSW:           "STOSW",
-	x86_STR:             "STR",
-	x86_SUB:             "SUB",
-	x86_SUBPD:           "SUBPD",
-	x86_SUBPS:           "SUBPS",
-	x86_SUBSD:           "SUBSD",
-	x86_SUBSS:           "SUBSS",
-	x86_SWAPGS:          "SWAPGS",
-	x86_SYSCALL:         "SYSCALL",
-	x86_SYSENTER:        "SYSENTER",
-	x86_SYSEXIT:         "SYSEXIT",
-	x86_SYSRET:          "SYSRET",
-	x86_TEST:            "TEST",
-	x86_TZCNT:           "TZCNT",
-	x86_UCOMISD:         "UCOMISD",
-	x86_UCOMISS:         "UCOMISS",
-	x86_UD1:             "UD1",
-	x86_UD2:             "UD2",
-	x86_UNPCKHPD:        "UNPCKHPD",
-	x86_UNPCKHPS:        "UNPCKHPS",
-	x86_UNPCKLPD:        "UNPCKLPD",
-	x86_UNPCKLPS:        "UNPCKLPS",
-	x86_VERR:            "VERR",
-	x86_VERW:            "VERW",
-	x86_WBINVD:          "WBINVD",
-	x86_WRFSBASE:        "WRFSBASE",
-	x86_WRGSBASE:        "WRGSBASE",
-	x86_WRMSR:           "WRMSR",
-	x86_XABORT:          "XABORT",
-	x86_XADD:            "XADD",
-	x86_XBEGIN:          "XBEGIN",
-	x86_XCHG:            "XCHG",
-	x86_XEND:            "XEND",
-	x86_XGETBV:          "XGETBV",
-	x86_XLATB:           "XLATB",
-	x86_XOR:             "XOR",
-	x86_XORPD:           "XORPD",
-	x86_XORPS:           "XORPS",
-	x86_XRSTOR:          "XRSTOR",
-	x86_XRSTOR64:        "XRSTOR64",
-	x86_XRSTORS:         "XRSTORS",
-	x86_XRSTORS64:       "XRSTORS64",
-	x86_XSAVE:           "XSAVE",
-	x86_XSAVE64:         "XSAVE64",
-	x86_XSAVEC:          "XSAVEC",
-	x86_XSAVEC64:        "XSAVEC64",
-	x86_XSAVEOPT:        "XSAVEOPT",
-	x86_XSAVEOPT64:      "XSAVEOPT64",
-	x86_XSAVES:          "XSAVES",
-	x86_XSAVES64:        "XSAVES64",
-	x86_XSETBV:          "XSETBV",
-	x86_XTEST:           "XTEST",
-}
diff --git a/src/cmd/pack/doc.go b/src/cmd/pack/doc.go
index 1529e07..a702594 100644
--- a/src/cmd/pack/doc.go
+++ b/src/cmd/pack/doc.go
@@ -20,6 +20,10 @@ The operation op is given by one of these letters:
 	t	list files from the archive
 	x	extract files from the archive
 
+The archive argument to the c command must be non-existent or a
+valid archive file, which will be cleared before adding new entries. It
+is an error if the file exists but is not an archive.
+
 For the p, t, and x commands, listing no names on the command line
 causes the operation to apply to all files in the archive.
 
diff --git a/src/cmd/pack/pack.go b/src/cmd/pack/pack.go
index 5944337..ffb2d61 100644
--- a/src/cmd/pack/pack.go
+++ b/src/cmd/pack/pack.go
@@ -142,16 +142,19 @@ type Archive struct {
 	matchAll bool     // match all files in archive
 }
 
-// archive opens (or if necessary creates) the named archive.
+// archive opens (and if necessary creates) the named archive.
 func archive(name string, mode int, files []string) *Archive {
-	fd, err := os.OpenFile(name, mode, 0)
-	if err != nil && mode&^os.O_TRUNC == os.O_RDWR && os.IsNotExist(err) {
-		fd, err = create(name)
+	// If the file exists, it must be an archive. If it doesn't exist, or if
+	// we're doing the c command, indicated by O_TRUNC, truncate the archive.
+	if !existingArchive(name) || mode&os.O_TRUNC != 0 {
+		create(name)
+		mode &^= os.O_TRUNC
 	}
+	fd, err := os.OpenFile(name, mode, 0)
 	if err != nil {
 		log.Fatal(err)
 	}
-	mustBeArchive(fd)
+	checkHeader(fd)
 	return &Archive{
 		fd:       fd,
 		files:    files,
@@ -160,23 +163,40 @@ func archive(name string, mode int, files []string) *Archive {
 }
 
 // create creates and initializes an archive that does not exist.
-func create(name string) (*os.File, error) {
-	fd, err := os.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644)
+func create(name string) {
+	fd, err := os.Create(name)
 	if err != nil {
-		return nil, err
+		log.Fatal(err)
+	}
+	_, err = fmt.Fprint(fd, arHeader)
+	if err != nil {
+		log.Fatal(err)
+	}
+	fd.Close()
+}
+
+// existingArchive reports whether the file exists and is a valid archive.
+// If it exists but is not an archive, existingArchive will exit.
+func existingArchive(name string) bool {
+	fd, err := os.Open(name)
+	if err != nil {
+		if os.IsNotExist(err) {
+			return false
+		}
+		log.Fatal("cannot open file: %s", err)
 	}
-	fmt.Fprint(fd, arHeader)
-	fd.Seek(0, 0)
-	return fd, nil
+	checkHeader(fd)
+	fd.Close()
+	return true
 }
 
-// mustBeArchive verifies the header of the file. It assumes the file offset
-// is 0 coming in, and leaves it positioned immediately after the header.
-func mustBeArchive(fd *os.File) {
+// checkHeader verifies the header of the file. It assumes the file
+// is positioned at 0 and leaves it positioned at the end of the header.
+func checkHeader(fd *os.File) {
 	buf := make([]byte, len(arHeader))
 	_, err := io.ReadFull(fd, buf)
 	if err != nil || string(buf) != arHeader {
-		log.Fatal("file is not an archive: bad header")
+		log.Fatal("%s is not an archive: bad header", fd.Name())
 	}
 }
 
diff --git a/src/cmd/pack/pack_test.go b/src/cmd/pack/pack_test.go
index 4862426..cf6121f 100644
--- a/src/cmd/pack/pack_test.go
+++ b/src/cmd/pack/pack_test.go
@@ -56,11 +56,8 @@ func tmpDir(t *testing.T) string {
 	return name
 }
 
-// Test that we can create an archive, write to it, and get the same contents back.
-// Tests the rv and then the pv command on a new archive.
-func TestCreate(t *testing.T) {
-	dir := tmpDir(t)
-	defer os.RemoveAll(dir)
+// testCreate creates an archive in the specified directory.
+func testCreate(t *testing.T, dir string) {
 	name := filepath.Join(dir, "pack.a")
 	ar := archive(name, os.O_RDWR, nil)
 	// Add an entry by hand.
@@ -85,6 +82,22 @@ func TestCreate(t *testing.T) {
 	}
 }
 
+// Test that we can create an archive, write to it, and get the same contents back.
+// Tests the rv and then the pv command on a new archive.
+func TestCreate(t *testing.T) {
+	dir := tmpDir(t)
+	defer os.RemoveAll(dir)
+	testCreate(t, dir)
+}
+
+// Test that we can create an archive twice with the same name (Issue 8369).
+func TestCreateTwice(t *testing.T) {
+	dir := tmpDir(t)
+	defer os.RemoveAll(dir)
+	testCreate(t, dir)
+	testCreate(t, dir)
+}
+
 // Test that we can create an archive, put some files in it, and get back a correct listing.
 // Tests the tv command.
 func TestTableOfContents(t *testing.T) {
@@ -186,8 +199,9 @@ func TestExtract(t *testing.T) {
 
 // Test that pack-created archives can be understood by the tools.
 func TestHello(t *testing.T) {
-	if runtime.GOOS == "nacl" {
-		t.Skip("skipping on nacl")
+	switch runtime.GOOS {
+	case "android", "nacl":
+		t.Skipf("skipping on %s", runtime.GOOS)
 	}
 
 	dir := tmpDir(t)
@@ -222,8 +236,9 @@ func TestHello(t *testing.T) {
 
 // Test that pack works with very long lines in PKGDEF.
 func TestLargeDefs(t *testing.T) {
-	if runtime.GOOS == "nacl" {
-		t.Skip("skipping on nacl")
+	switch runtime.GOOS {
+	case "android", "nacl":
+		t.Skipf("skipping on %s", runtime.GOOS)
 	}
 
 	dir := tmpDir(t)
diff --git a/src/cmd/pprof/README b/src/cmd/pprof/README
new file mode 100644
index 0000000..a728ef2
--- /dev/null
+++ b/src/cmd/pprof/README
@@ -0,0 +1,8 @@
+The pprof in this directory is adapted from the pprof used inside Google
+for C++, Java, and Go programs. Because it was developed for that broader
+context, it is overgeneralized when used here for the specific use case
+of profiling standard Go programs. However, we've left the abstractions
+intact in order to share updates between this copy and Google's internal one.
+
+Please do not take the level of abstraction in this program as an example
+to follow in your own.
diff --git a/src/cmd/pprof/doc.go b/src/cmd/pprof/doc.go
new file mode 100644
index 0000000..c6ff11d
--- /dev/null
+++ b/src/cmd/pprof/doc.go
@@ -0,0 +1,12 @@
+// 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.
+
+// Pprof interprets and displays profiles of Go programs.
+//
+// Usage:
+//
+//	go tool pprof binary profile
+//
+// For more information, see http://blog.golang.org/profiling-go-programs.
+package main
diff --git a/src/cmd/pprof/internal/commands/commands.go b/src/cmd/pprof/internal/commands/commands.go
new file mode 100644
index 0000000..51397a3
--- /dev/null
+++ b/src/cmd/pprof/internal/commands/commands.go
@@ -0,0 +1,215 @@
+// 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 commands defines and manages the basic pprof commands
+package commands
+
+import (
+	"bytes"
+	"fmt"
+	"io"
+	"os"
+	"os/exec"
+	"runtime"
+	"strings"
+
+	"cmd/pprof/internal/plugin"
+	"cmd/pprof/internal/report"
+	"cmd/pprof/internal/svg"
+	"cmd/pprof/internal/tempfile"
+)
+
+// Commands describes the commands accepted by pprof.
+type Commands map[string]*Command
+
+// Command describes the actions for a pprof command. Includes a
+// function for command-line completion, the report format to use
+// during report generation, any postprocessing functions, and whether
+// the command expects a regexp parameter (typically a function name).
+type Command struct {
+	Complete    Completer     // autocomplete for interactive mode
+	Format      int           // report format to generate
+	PostProcess PostProcessor // postprocessing to run on report
+	HasParam    bool          // Collect a parameter from the CLI
+	Usage       string        // Help text
+}
+
+// Completer is a function for command-line autocompletion
+type Completer func(prefix string) string
+
+// PostProcessor is a function that applies post-processing to the report output
+type PostProcessor func(input *bytes.Buffer, output io.Writer, ui plugin.UI) error
+
+// PProf returns the basic pprof report-generation commands
+func PProf(c Completer, interactive **bool, svgpan **string) Commands {
+	return Commands{
+		// Commands that require no post-processing.
+		"tags":   {nil, report.Tags, nil, false, "Outputs all tags in the profile"},
+		"raw":    {c, report.Raw, nil, false, "Outputs a text representation of the raw profile"},
+		"dot":    {c, report.Dot, nil, false, "Outputs a graph in DOT format"},
+		"top":    {c, report.Text, nil, false, "Outputs top entries in text form"},
+		"tree":   {c, report.Tree, nil, false, "Outputs a text rendering of call graph"},
+		"text":   {c, report.Text, nil, false, "Outputs top entries in text form"},
+		"disasm": {c, report.Dis, nil, true, "Output annotated assembly for functions matching regexp or address"},
+		"list":   {c, report.List, nil, true, "Output annotated source for functions matching regexp"},
+		"peek":   {c, report.Tree, nil, true, "Output callers/callees of functions matching regexp"},
+
+		// Save binary formats to a file
+		"callgrind": {c, report.Callgrind, awayFromTTY("callgraph.out"), false, "Outputs a graph in callgrind format"},
+		"proto":     {c, report.Proto, awayFromTTY("pb.gz"), false, "Outputs the profile in compressed protobuf format"},
+
+		// Generate report in DOT format and postprocess with dot
+		"gif": {c, report.Dot, invokeDot("gif"), false, "Outputs a graph image in GIF format"},
+		"pdf": {c, report.Dot, invokeDot("pdf"), false, "Outputs a graph in PDF format"},
+		"png": {c, report.Dot, invokeDot("png"), false, "Outputs a graph image in PNG format"},
+		"ps":  {c, report.Dot, invokeDot("ps"), false, "Outputs a graph in PS format"},
+
+		// Save SVG output into a file after including svgpan library
+		"svg": {c, report.Dot, saveSVGToFile(svgpan), false, "Outputs a graph in SVG format"},
+
+		// Visualize postprocessed dot output
+		"eog":    {c, report.Dot, invokeVisualizer(interactive, invokeDot("svg"), "svg", []string{"eog"}), false, "Visualize graph through eog"},
+		"evince": {c, report.Dot, invokeVisualizer(interactive, invokeDot("pdf"), "pdf", []string{"evince"}), false, "Visualize graph through evince"},
+		"gv":     {c, report.Dot, invokeVisualizer(interactive, invokeDot("ps"), "ps", []string{"gv --noantialias"}), false, "Visualize graph through gv"},
+		"web":    {c, report.Dot, invokeVisualizer(interactive, saveSVGToFile(svgpan), "svg", browsers()), false, "Visualize graph through web browser"},
+
+		// Visualize HTML directly generated by report.
+		"weblist": {c, report.WebList, invokeVisualizer(interactive, awayFromTTY("html"), "html", browsers()), true, "Output annotated source in HTML for functions matching regexp or address"},
+	}
+}
+
+// browsers returns a list of commands to attempt for web visualization
+// on the current platform
+func browsers() []string {
+	cmds := []string{"chrome", "google-chrome", "firefox"}
+	switch runtime.GOOS {
+	case "darwin":
+		cmds = append(cmds, "/usr/bin/open")
+	case "windows":
+		cmds = append(cmds, "cmd /c start")
+	default:
+		cmds = append(cmds, "xdg-open")
+	}
+	return cmds
+}
+
+// NewCompleter creates an autocompletion function for a set of commands.
+func NewCompleter(cs Commands) Completer {
+	return func(line string) string {
+		switch tokens := strings.Fields(line); len(tokens) {
+		case 0:
+			// Nothing to complete
+		case 1:
+			// Single token -- complete command name
+			found := ""
+			for c := range cs {
+				if strings.HasPrefix(c, tokens[0]) {
+					if found != "" {
+						return line
+					}
+					found = c
+				}
+			}
+			if found != "" {
+				return found
+			}
+		default:
+			// Multiple tokens -- complete using command completer
+			if c, ok := cs[tokens[0]]; ok {
+				if c.Complete != nil {
+					lastTokenIdx := len(tokens) - 1
+					lastToken := tokens[lastTokenIdx]
+					if strings.HasPrefix(lastToken, "-") {
+						lastToken = "-" + c.Complete(lastToken[1:])
+					} else {
+						lastToken = c.Complete(lastToken)
+					}
+					return strings.Join(append(tokens[:lastTokenIdx], lastToken), " ")
+				}
+			}
+		}
+		return line
+	}
+}
+
+// awayFromTTY saves the output in a file if it would otherwise go to
+// the terminal screen. This is used to avoid dumping binary data on
+// the screen.
+func awayFromTTY(format string) PostProcessor {
+	return func(input *bytes.Buffer, output io.Writer, ui plugin.UI) error {
+		if output == os.Stdout && ui.IsTerminal() {
+			tempFile, err := tempfile.New("", "profile", "."+format)
+			if err != nil {
+				return err
+			}
+			ui.PrintErr("Generating report in ", tempFile.Name())
+			_, err = fmt.Fprint(tempFile, input)
+			return err
+		}
+		_, err := fmt.Fprint(output, input)
+		return err
+	}
+}
+
+func invokeDot(format string) PostProcessor {
+	divert := awayFromTTY(format)
+	return func(input *bytes.Buffer, output io.Writer, ui plugin.UI) error {
+		if _, err := exec.LookPath("dot"); err != nil {
+			ui.PrintErr("Cannot find dot, have you installed Graphviz?")
+			return err
+		}
+		cmd := exec.Command("dot", "-T"+format)
+		var buf bytes.Buffer
+		cmd.Stdin, cmd.Stdout, cmd.Stderr = input, &buf, os.Stderr
+		if err := cmd.Run(); err != nil {
+			return err
+		}
+		return divert(&buf, output, ui)
+	}
+}
+
+func saveSVGToFile(svgpan **string) PostProcessor {
+	generateSVG := invokeDot("svg")
+	divert := awayFromTTY("svg")
+	return func(input *bytes.Buffer, output io.Writer, ui plugin.UI) error {
+		baseSVG := &bytes.Buffer{}
+		generateSVG(input, baseSVG, ui)
+		massaged := &bytes.Buffer{}
+		fmt.Fprint(massaged, svg.Massage(*baseSVG, **svgpan))
+		return divert(massaged, output, ui)
+	}
+}
+
+func invokeVisualizer(interactive **bool, format PostProcessor, suffix string, visualizers []string) PostProcessor {
+	return func(input *bytes.Buffer, output io.Writer, ui plugin.UI) error {
+		tempFile, err := tempfile.New(os.Getenv("PPROF_TMPDIR"), "pprof", "."+suffix)
+		if err != nil {
+			return err
+		}
+		tempfile.DeferDelete(tempFile.Name())
+		if err = format(input, tempFile, ui); err != nil {
+			return err
+		}
+		tempFile.Close() // on windows, if the file is Open, start cannot access it.
+		// Try visualizers until one is successful
+		for _, v := range visualizers {
+			// Separate command and arguments for exec.Command.
+			args := strings.Split(v, " ")
+			if len(args) == 0 {
+				continue
+			}
+			viewer := exec.Command(args[0], append(args[1:], tempFile.Name())...)
+			viewer.Stderr = os.Stderr
+			if err = viewer.Start(); err == nil {
+				if !**interactive {
+					// In command-line mode, wait for the viewer to be closed
+					// before proceeding
+					return viewer.Wait()
+				}
+				return nil
+			}
+		}
+		return err
+	}
+}
diff --git a/src/cmd/pprof/internal/driver/driver.go b/src/cmd/pprof/internal/driver/driver.go
new file mode 100644
index 0000000..68b5d1b
--- /dev/null
+++ b/src/cmd/pprof/internal/driver/driver.go
@@ -0,0 +1,1036 @@
+// 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 driver implements the core pprof functionality. It can be
+// parameterized with a flag implementation, fetch and symbolize
+// mechanisms.
+package driver
+
+import (
+	"bytes"
+	"fmt"
+	"io"
+	"net/url"
+	"os"
+	"path/filepath"
+	"regexp"
+	"sort"
+	"strconv"
+	"strings"
+	"sync"
+	"time"
+
+	"cmd/pprof/internal/commands"
+	"cmd/pprof/internal/plugin"
+	"cmd/pprof/internal/profile"
+	"cmd/pprof/internal/report"
+	"cmd/pprof/internal/tempfile"
+)
+
+// PProf acquires a profile, and symbolizes it using a profile
+// manager. Then it generates a report formatted according to the
+// options selected through the flags package.
+func PProf(flagset plugin.FlagSet, fetch plugin.Fetcher, sym plugin.Symbolizer, obj plugin.ObjTool, ui plugin.UI, overrides commands.Commands) error {
+	// Remove any temporary files created during pprof processing.
+	defer tempfile.Cleanup()
+
+	f, err := getFlags(flagset, overrides, ui)
+	if err != nil {
+		return err
+	}
+
+	obj.SetConfig(*f.flagTools)
+
+	sources := f.profileSource
+	if len(sources) > 1 {
+		source := sources[0]
+		// If the first argument is a supported object file, treat as executable.
+		if file, err := obj.Open(source, 0); err == nil {
+			file.Close()
+			f.profileExecName = source
+			sources = sources[1:]
+		} else if *f.flagBuildID == "" && isBuildID(source) {
+			f.flagBuildID = &source
+			sources = sources[1:]
+		}
+	}
+
+	// errMu protects concurrent accesses to errset and err. errset is set if an
+	// error is encountered by one of the goroutines grabbing a profile.
+	errMu, errset := sync.Mutex{}, false
+
+	// Fetch profiles.
+	wg := sync.WaitGroup{}
+	profs := make([]*profile.Profile, len(sources))
+	for i, source := range sources {
+		wg.Add(1)
+		go func(i int, src string) {
+			defer wg.Done()
+			p, grabErr := grabProfile(src, f.profileExecName, *f.flagBuildID, fetch, sym, obj, ui, f)
+			if grabErr != nil {
+				errMu.Lock()
+				defer errMu.Unlock()
+				errset, err = true, grabErr
+				return
+			}
+			profs[i] = p
+		}(i, source)
+	}
+	wg.Wait()
+	if errset {
+		return err
+	}
+
+	// Merge profiles.
+	prof := profs[0]
+	for _, p := range profs[1:] {
+		if err = prof.Merge(p, 1); err != nil {
+			return err
+		}
+	}
+
+	if *f.flagBase != "" {
+		// Fetch base profile and subtract from current profile.
+		base, err := grabProfile(*f.flagBase, f.profileExecName, *f.flagBuildID, fetch, sym, obj, ui, f)
+		if err != nil {
+			return err
+		}
+
+		if err = prof.Merge(base, -1); err != nil {
+			return err
+		}
+	}
+
+	if err := processFlags(prof, ui, f); err != nil {
+		return err
+	}
+
+	prof.RemoveUninteresting()
+
+	if *f.flagInteractive {
+		return interactive(prof, obj, ui, f)
+	}
+
+	return generate(false, prof, obj, ui, f)
+}
+
+// isBuildID determines if the profile may contain a build ID, by
+// checking that it is a string of hex digits.
+func isBuildID(id string) bool {
+	return strings.Trim(id, "0123456789abcdefABCDEF") == ""
+}
+
+// adjustURL updates the profile source URL based on heuristics. It
+// will append ?seconds=sec for CPU profiles if not already
+// specified. Returns the hostname if the profile is remote.
+func adjustURL(source string, sec int, ui plugin.UI) (adjusted, host string, duration time.Duration) {
+	// If there is a local file with this name, just use it.
+	if _, err := os.Stat(source); err == nil {
+		return source, "", 0
+	}
+
+	url, err := url.Parse(source)
+
+	// Automatically add http:// to URLs of the form hostname:port/path.
+	// url.Parse treats "hostname" as the Scheme.
+	if err != nil || (url.Host == "" && url.Scheme != "" && url.Scheme != "file") {
+		url, err = url.Parse("http://" + source)
+		if err != nil {
+			return source, url.Host, time.Duration(30) * time.Second
+		}
+	}
+	if scheme := strings.ToLower(url.Scheme); scheme == "" || scheme == "file" {
+		url.Scheme = ""
+		return url.String(), "", 0
+	}
+
+	values := url.Query()
+	if urlSeconds := values.Get("seconds"); urlSeconds != "" {
+		if us, err := strconv.ParseInt(urlSeconds, 10, 32); err == nil {
+			if sec >= 0 {
+				ui.PrintErr("Overriding -seconds for URL ", source)
+			}
+			sec = int(us)
+		}
+	}
+
+	switch strings.ToLower(url.Path) {
+	case "", "/":
+		// Apply default /profilez.
+		url.Path = "/profilez"
+	case "/protoz":
+		// Rewrite to /profilez?type=proto
+		url.Path = "/profilez"
+		values.Set("type", "proto")
+	}
+
+	if hasDuration(url.Path) {
+		if sec > 0 {
+			duration = time.Duration(sec) * time.Second
+			values.Set("seconds", fmt.Sprintf("%d", sec))
+		} else {
+			// Assume default duration: 30 seconds
+			duration = 30 * time.Second
+		}
+	}
+	url.RawQuery = values.Encode()
+	return url.String(), url.Host, duration
+}
+
+func hasDuration(path string) bool {
+	for _, trigger := range []string{"profilez", "wallz", "/profile"} {
+		if strings.Contains(path, trigger) {
+			return true
+		}
+	}
+	return false
+}
+
+// preprocess does filtering and aggregation of a profile based on the
+// requested options.
+func preprocess(prof *profile.Profile, ui plugin.UI, f *flags) error {
+	if *f.flagFocus != "" || *f.flagIgnore != "" || *f.flagHide != "" {
+		focus, ignore, hide, err := compileFocusIgnore(*f.flagFocus, *f.flagIgnore, *f.flagHide)
+		if err != nil {
+			return err
+		}
+		fm, im, hm := prof.FilterSamplesByName(focus, ignore, hide)
+
+		warnNoMatches(fm, *f.flagFocus, "Focus", ui)
+		warnNoMatches(im, *f.flagIgnore, "Ignore", ui)
+		warnNoMatches(hm, *f.flagHide, "Hide", ui)
+	}
+
+	if *f.flagTagFocus != "" || *f.flagTagIgnore != "" {
+		focus, err := compileTagFilter(*f.flagTagFocus, ui)
+		if err != nil {
+			return err
+		}
+		ignore, err := compileTagFilter(*f.flagTagIgnore, ui)
+		if err != nil {
+			return err
+		}
+		fm, im := prof.FilterSamplesByTag(focus, ignore)
+
+		warnNoMatches(fm, *f.flagTagFocus, "TagFocus", ui)
+		warnNoMatches(im, *f.flagTagIgnore, "TagIgnore", ui)
+	}
+
+	return aggregate(prof, f)
+}
+
+func compileFocusIgnore(focus, ignore, hide string) (f, i, h *regexp.Regexp, err error) {
+	if focus != "" {
+		if f, err = regexp.Compile(focus); err != nil {
+			return nil, nil, nil, fmt.Errorf("parsing focus regexp: %v", err)
+		}
+	}
+
+	if ignore != "" {
+		if i, err = regexp.Compile(ignore); err != nil {
+			return nil, nil, nil, fmt.Errorf("parsing ignore regexp: %v", err)
+		}
+	}
+
+	if hide != "" {
+		if h, err = regexp.Compile(hide); err != nil {
+			return nil, nil, nil, fmt.Errorf("parsing hide regexp: %v", err)
+		}
+	}
+	return
+}
+
+func compileTagFilter(filter string, ui plugin.UI) (f func(string, string, int64) bool, err error) {
+	if filter == "" {
+		return nil, nil
+	}
+	if numFilter := parseTagFilterRange(filter); numFilter != nil {
+		ui.PrintErr("Interpreted '", filter, "' as range, not regexp")
+		return func(key, val string, num int64) bool {
+			if val != "" {
+				return false
+			}
+			return numFilter(num, key)
+		}, nil
+	}
+	fx, err := regexp.Compile(filter)
+	if err != nil {
+		return nil, err
+	}
+
+	return func(key, val string, num int64) bool {
+		if val == "" {
+			return false
+		}
+		return fx.MatchString(key + ":" + val)
+	}, nil
+}
+
+var tagFilterRangeRx = regexp.MustCompile("([[:digit:]]+)([[:alpha:]]+)")
+
+// parseTagFilterRange returns a function to checks if a value is
+// contained on the range described by a string. It can recognize
+// strings of the form:
+// "32kb" -- matches values == 32kb
+// ":64kb" -- matches values <= 64kb
+// "4mb:" -- matches values >= 4mb
+// "12kb:64mb" -- matches values between 12kb and 64mb (both included).
+func parseTagFilterRange(filter string) func(int64, string) bool {
+	ranges := tagFilterRangeRx.FindAllStringSubmatch(filter, 2)
+	if len(ranges) == 0 {
+		return nil // No ranges were identified
+	}
+	v, err := strconv.ParseInt(ranges[0][1], 10, 64)
+	if err != nil {
+		panic(fmt.Errorf("Failed to parse int %s: %v", ranges[0][1], err))
+	}
+	value, unit := report.ScaleValue(v, ranges[0][2], ranges[0][2])
+	if len(ranges) == 1 {
+		switch match := ranges[0][0]; filter {
+		case match:
+			return func(v int64, u string) bool {
+				sv, su := report.ScaleValue(v, u, unit)
+				return su == unit && sv == value
+			}
+		case match + ":":
+			return func(v int64, u string) bool {
+				sv, su := report.ScaleValue(v, u, unit)
+				return su == unit && sv >= value
+			}
+		case ":" + match:
+			return func(v int64, u string) bool {
+				sv, su := report.ScaleValue(v, u, unit)
+				return su == unit && sv <= value
+			}
+		}
+		return nil
+	}
+	if filter != ranges[0][0]+":"+ranges[1][0] {
+		return nil
+	}
+	if v, err = strconv.ParseInt(ranges[1][1], 10, 64); err != nil {
+		panic(fmt.Errorf("Failed to parse int %s: %v", ranges[1][1], err))
+	}
+	value2, unit2 := report.ScaleValue(v, ranges[1][2], unit)
+	if unit != unit2 {
+		return nil
+	}
+	return func(v int64, u string) bool {
+		sv, su := report.ScaleValue(v, u, unit)
+		return su == unit && sv >= value && sv <= value2
+	}
+}
+
+func warnNoMatches(match bool, rx, option string, ui plugin.UI) {
+	if !match && rx != "" && rx != "." {
+		ui.PrintErr(option + " expression matched no samples: " + rx)
+	}
+}
+
+// grabProfile fetches and symbolizes a profile.
+func grabProfile(source, exec, buildid string, fetch plugin.Fetcher, sym plugin.Symbolizer, obj plugin.ObjTool, ui plugin.UI, f *flags) (*profile.Profile, error) {
+	source, host, duration := adjustURL(source, *f.flagSeconds, ui)
+	remote := host != ""
+
+	if remote {
+		ui.Print("Fetching profile from ", source)
+		if duration != 0 {
+			ui.Print("Please wait... (" + duration.String() + ")")
+		}
+	}
+
+	now := time.Now()
+	// Fetch profile from source.
+	// Give 50% slack on the timeout.
+	p, err := fetch(source, duration+duration/2, ui)
+	if err != nil {
+		return nil, err
+	}
+
+	// Update the time/duration if the profile source doesn't include it.
+	// TODO(rsilvera): Remove this when we remove support for legacy profiles.
+	if remote {
+		if p.TimeNanos == 0 {
+			p.TimeNanos = now.UnixNano()
+		}
+		if duration != 0 && p.DurationNanos == 0 {
+			p.DurationNanos = int64(duration)
+		}
+	}
+
+	// Replace executable/buildID with the options provided in the
+	// command line. Assume the executable is the first Mapping entry.
+	if exec != "" || buildid != "" {
+		if len(p.Mapping) == 0 {
+			// Create a fake mapping to hold the user option, and associate
+			// all samples to it.
+			m := &profile.Mapping{
+				ID: 1,
+			}
+			for _, l := range p.Location {
+				l.Mapping = m
+			}
+			p.Mapping = []*profile.Mapping{m}
+		}
+		if exec != "" {
+			p.Mapping[0].File = exec
+		}
+		if buildid != "" {
+			p.Mapping[0].BuildID = buildid
+		}
+	}
+
+	if err := sym(*f.flagSymbolize, source, p, obj, ui); err != nil {
+		return nil, err
+	}
+
+	// Save a copy of any remote profiles, unless the user is explicitly
+	// saving it.
+	if remote && !f.isFormat("proto") {
+		prefix := "pprof."
+		if len(p.Mapping) > 0 && p.Mapping[0].File != "" {
+			prefix = prefix + filepath.Base(p.Mapping[0].File) + "."
+		}
+		if !strings.ContainsRune(host, os.PathSeparator) {
+			prefix = prefix + host + "."
+		}
+		for _, s := range p.SampleType {
+			prefix = prefix + s.Type + "."
+		}
+
+		dir := os.Getenv("PPROF_TMPDIR")
+		tempFile, err := tempfile.New(dir, prefix, ".pb.gz")
+		if err == nil {
+			if err = p.Write(tempFile); err == nil {
+				ui.PrintErr("Saved profile in ", tempFile.Name())
+			}
+		}
+		if err != nil {
+			ui.PrintErr("Could not save profile: ", err)
+		}
+	}
+
+	if err := p.Demangle(obj.Demangle); err != nil {
+		ui.PrintErr("Failed to demangle profile: ", err)
+	}
+
+	if err := p.CheckValid(); err != nil {
+		return nil, fmt.Errorf("Grab %s: %v", source, err)
+	}
+
+	return p, nil
+}
+
+type flags struct {
+	flagInteractive   *bool              // Accept commands interactively
+	flagCommands      map[string]*bool   // pprof commands without parameters
+	flagParamCommands map[string]*string // pprof commands with parameters
+
+	flagSVGPan *string // URL to fetch the SVG Pan library
+	flagOutput *string // Output file name
+
+	flagCum      *bool // Sort by cumulative data
+	flagCallTree *bool // generate a context-sensitive call tree
+
+	flagAddresses *bool // Report at address level
+	flagLines     *bool // Report at source line level
+	flagFiles     *bool // Report at file level
+	flagFunctions *bool // Report at function level [default]
+
+	flagSymbolize *string // Symbolization options (=none to disable)
+	flagBuildID   *string // Override build if for first mapping
+
+	flagNodeCount    *int     // Max number of nodes to show
+	flagNodeFraction *float64 // Hide nodes below <f>*total
+	flagEdgeFraction *float64 // Hide edges below <f>*total
+	flagTrim         *bool    // Set to false to ignore NodeCount/*Fraction
+	flagFocus        *string  // Restricts to paths going through a node matching regexp
+	flagIgnore       *string  // Skips paths going through any nodes matching regexp
+	flagHide         *string  // Skips sample locations matching regexp
+	flagTagFocus     *string  // Restrict to samples tagged with key:value matching regexp
+	flagTagIgnore    *string  // Discard samples tagged with key:value matching regexp
+	flagDropNegative *bool    // Skip negative values
+
+	flagBase *string // Source for base profile to user for comparison
+
+	flagSeconds *int // Length of time for dynamic profiles
+
+	flagTotalDelay  *bool // Display total delay at each region
+	flagContentions *bool // Display number of delays at each region
+	flagMeanDelay   *bool // Display mean delay at each region
+
+	flagInUseSpace   *bool    // Display in-use memory size
+	flagInUseObjects *bool    // Display in-use object counts
+	flagAllocSpace   *bool    // Display allocated memory size
+	flagAllocObjects *bool    // Display allocated object counts
+	flagDisplayUnit  *string  // Measurement unit to use on reports
+	flagDivideBy     *float64 // Ratio to divide sample values
+
+	flagSampleIndex *int  // Sample value to use in reports.
+	flagMean        *bool // Use mean of sample_index over count
+
+	flagTools       *string
+	profileSource   []string
+	profileExecName string
+
+	extraUsage string
+	commands   commands.Commands
+}
+
+func (f *flags) isFormat(format string) bool {
+	if fl := f.flagCommands[format]; fl != nil {
+		return *fl
+	}
+	if fl := f.flagParamCommands[format]; fl != nil {
+		return *fl != ""
+	}
+	return false
+}
+
+// String provides a printable representation for the current set of flags.
+func (f *flags) String(p *profile.Profile) string {
+	var ret string
+
+	if ix := *f.flagSampleIndex; ix != -1 {
+		ret += fmt.Sprintf("  %-25s : %d (%s)\n", "sample_index", ix, p.SampleType[ix].Type)
+	}
+	if ix := *f.flagMean; ix {
+		ret += boolFlagString("mean")
+	}
+	if *f.flagDisplayUnit != "minimum" {
+		ret += stringFlagString("unit", *f.flagDisplayUnit)
+	}
+
+	switch {
+	case *f.flagInteractive:
+		ret += boolFlagString("interactive")
+	}
+	for name, fl := range f.flagCommands {
+		if *fl {
+			ret += boolFlagString(name)
+		}
+	}
+
+	if *f.flagCum {
+		ret += boolFlagString("cum")
+	}
+	if *f.flagCallTree {
+		ret += boolFlagString("call_tree")
+	}
+
+	switch {
+	case *f.flagAddresses:
+		ret += boolFlagString("addresses")
+	case *f.flagLines:
+		ret += boolFlagString("lines")
+	case *f.flagFiles:
+		ret += boolFlagString("files")
+	case *f.flagFunctions:
+		ret += boolFlagString("functions")
+	}
+
+	if *f.flagNodeCount != -1 {
+		ret += intFlagString("nodecount", *f.flagNodeCount)
+	}
+
+	ret += floatFlagString("nodefraction", *f.flagNodeFraction)
+	ret += floatFlagString("edgefraction", *f.flagEdgeFraction)
+
+	if *f.flagFocus != "" {
+		ret += stringFlagString("focus", *f.flagFocus)
+	}
+	if *f.flagIgnore != "" {
+		ret += stringFlagString("ignore", *f.flagIgnore)
+	}
+	if *f.flagHide != "" {
+		ret += stringFlagString("hide", *f.flagHide)
+	}
+
+	if *f.flagTagFocus != "" {
+		ret += stringFlagString("tagfocus", *f.flagTagFocus)
+	}
+	if *f.flagTagIgnore != "" {
+		ret += stringFlagString("tagignore", *f.flagTagIgnore)
+	}
+
+	return ret
+}
+
+func boolFlagString(label string) string {
+	return fmt.Sprintf("  %-25s : true\n", label)
+}
+
+func stringFlagString(label, value string) string {
+	return fmt.Sprintf("  %-25s : %s\n", label, value)
+}
+
+func intFlagString(label string, value int) string {
+	return fmt.Sprintf("  %-25s : %d\n", label, value)
+}
+
+func floatFlagString(label string, value float64) string {
+	return fmt.Sprintf("  %-25s : %f\n", label, value)
+}
+
+// Utility routines to set flag values.
+func newBool(b bool) *bool {
+	return &b
+}
+
+func newString(s string) *string {
+	return &s
+}
+
+func newFloat64(fl float64) *float64 {
+	return &fl
+}
+
+func newInt(i int) *int {
+	return &i
+}
+
+func (f *flags) usage(ui plugin.UI) {
+	var commandMsg []string
+	for name, cmd := range f.commands {
+		if cmd.HasParam {
+			name = name + "=p"
+		}
+		commandMsg = append(commandMsg,
+			fmt.Sprintf("  -%-16s %s", name, cmd.Usage))
+	}
+
+	sort.Strings(commandMsg)
+
+	text := usageMsgHdr + strings.Join(commandMsg, "\n") + "\n" + usageMsg + "\n"
+	if f.extraUsage != "" {
+		text += f.extraUsage + "\n"
+	}
+	text += usageMsgVars
+	ui.Print(text)
+}
+
+func getFlags(flag plugin.FlagSet, overrides commands.Commands, ui plugin.UI) (*flags, error) {
+	f := &flags{
+		flagInteractive:   flag.Bool("interactive", false, "Accepts commands interactively"),
+		flagCommands:      make(map[string]*bool),
+		flagParamCommands: make(map[string]*string),
+
+		// Filename for file-based output formats, stdout by default.
+		flagOutput: flag.String("output", "", "Output filename for file-based outputs "),
+		// Comparisons.
+		flagBase:         flag.String("base", "", "Source for base profile for comparison"),
+		flagDropNegative: flag.Bool("drop_negative", false, "Ignore negative differences"),
+
+		flagSVGPan: flag.String("svgpan", "https://www.cyberz.org/projects/SVGPan/SVGPan.js", "URL for SVGPan Library"),
+		// Data sorting criteria.
+		flagCum: flag.Bool("cum", false, "Sort by cumulative data"),
+		// Graph handling options.
+		flagCallTree: flag.Bool("call_tree", false, "Create a context-sensitive call tree"),
+		// Granularity of output resolution.
+		flagAddresses: flag.Bool("addresses", false, "Report at address level"),
+		flagLines:     flag.Bool("lines", false, "Report at source line level"),
+		flagFiles:     flag.Bool("files", false, "Report at source file level"),
+		flagFunctions: flag.Bool("functions", false, "Report at function level [default]"),
+		// Internal options.
+		flagSymbolize: flag.String("symbolize", "", "Options for profile symbolization"),
+		flagBuildID:   flag.String("buildid", "", "Override build id for first mapping"),
+		// Filtering options
+		flagNodeCount:    flag.Int("nodecount", -1, "Max number of nodes to show"),
+		flagNodeFraction: flag.Float64("nodefraction", 0.005, "Hide nodes below <f>*total"),
+		flagEdgeFraction: flag.Float64("edgefraction", 0.001, "Hide edges below <f>*total"),
+		flagTrim:         flag.Bool("trim", true, "Honor nodefraction/edgefraction/nodecount defaults"),
+		flagFocus:        flag.String("focus", "", "Restricts to paths going through a node matching regexp"),
+		flagIgnore:       flag.String("ignore", "", "Skips paths going through any nodes matching regexp"),
+		flagHide:         flag.String("hide", "", "Skips nodes matching regexp"),
+		flagTagFocus:     flag.String("tagfocus", "", "Restrict to samples with tags in range or matched by regexp"),
+		flagTagIgnore:    flag.String("tagignore", "", "Discard samples with tags in range or matched by regexp"),
+		// CPU profile options
+		flagSeconds: flag.Int("seconds", -1, "Length of time for dynamic profiles"),
+		// Heap profile options
+		flagInUseSpace:   flag.Bool("inuse_space", false, "Display in-use memory size"),
+		flagInUseObjects: flag.Bool("inuse_objects", false, "Display in-use object counts"),
+		flagAllocSpace:   flag.Bool("alloc_space", false, "Display allocated memory size"),
+		flagAllocObjects: flag.Bool("alloc_objects", false, "Display allocated object counts"),
+		flagDisplayUnit:  flag.String("unit", "minimum", "Measurement units to display"),
+		flagDivideBy:     flag.Float64("divide_by", 1.0, "Ratio to divide all samples before visualization"),
+		flagSampleIndex:  flag.Int("sample_index", -1, "Index of sample value to report"),
+		flagMean:         flag.Bool("mean", false, "Average sample value over first value (count)"),
+		// Contention profile options
+		flagTotalDelay:  flag.Bool("total_delay", false, "Display total delay at each region"),
+		flagContentions: flag.Bool("contentions", false, "Display number of delays at each region"),
+		flagMeanDelay:   flag.Bool("mean_delay", false, "Display mean delay at each region"),
+		flagTools:       flag.String("tools", os.Getenv("PPROF_TOOLS"), "Path for object tool pathnames"),
+		extraUsage:      flag.ExtraUsage(),
+	}
+
+	// Flags used during command processing
+	interactive := &f.flagInteractive
+	svgpan := &f.flagSVGPan
+	f.commands = commands.PProf(functionCompleter, interactive, svgpan)
+
+	// Override commands
+	for name, cmd := range overrides {
+		f.commands[name] = cmd
+	}
+
+	for name, cmd := range f.commands {
+		if cmd.HasParam {
+			f.flagParamCommands[name] = flag.String(name, "", "Generate a report in "+name+" format, matching regexp")
+		} else {
+			f.flagCommands[name] = flag.Bool(name, false, "Generate a report in "+name+" format")
+		}
+	}
+
+	args := flag.Parse(func() { f.usage(ui) })
+	if len(args) == 0 {
+		return nil, fmt.Errorf("no profile source specified")
+	}
+
+	f.profileSource = args
+
+	// Instruct legacy heapz parsers to grab historical allocation data,
+	// instead of the default in-use data. Not available with tcmalloc.
+	if *f.flagAllocSpace || *f.flagAllocObjects {
+		profile.LegacyHeapAllocated = true
+	}
+
+	if profileDir := os.Getenv("PPROF_TMPDIR"); profileDir == "" {
+		profileDir = os.Getenv("HOME") + "/pprof"
+		os.Setenv("PPROF_TMPDIR", profileDir)
+		if err := os.MkdirAll(profileDir, 0755); err != nil {
+			return nil, fmt.Errorf("failed to access temp dir %s: %v", profileDir, err)
+		}
+	}
+
+	return f, nil
+}
+
+func processFlags(p *profile.Profile, ui plugin.UI, f *flags) error {
+	flagDis := f.isFormat("disasm")
+	flagPeek := f.isFormat("peek")
+	flagWebList := f.isFormat("weblist")
+	flagList := f.isFormat("list")
+
+	if flagDis || flagWebList {
+		// Collect all samples at address granularity for assembly
+		// listing.
+		f.flagNodeCount = newInt(0)
+		f.flagAddresses = newBool(true)
+		f.flagLines = newBool(false)
+		f.flagFiles = newBool(false)
+		f.flagFunctions = newBool(false)
+	}
+
+	if flagPeek {
+		// Collect all samples at function granularity for peek command
+		f.flagNodeCount = newInt(0)
+		f.flagAddresses = newBool(false)
+		f.flagLines = newBool(false)
+		f.flagFiles = newBool(false)
+		f.flagFunctions = newBool(true)
+	}
+
+	if flagList {
+		// Collect all samples at fileline granularity for source
+		// listing.
+		f.flagNodeCount = newInt(0)
+		f.flagAddresses = newBool(false)
+		f.flagLines = newBool(true)
+		f.flagFiles = newBool(false)
+		f.flagFunctions = newBool(false)
+	}
+
+	if !*f.flagTrim {
+		f.flagNodeCount = newInt(0)
+		f.flagNodeFraction = newFloat64(0)
+		f.flagEdgeFraction = newFloat64(0)
+	}
+
+	if oc := countFlagMap(f.flagCommands, f.flagParamCommands); oc == 0 {
+		f.flagInteractive = newBool(true)
+	} else if oc > 1 {
+		f.usage(ui)
+		return fmt.Errorf("must set at most one output format")
+	}
+
+	// Apply nodecount defaults for non-interactive mode. The
+	// interactive shell will apply defaults for the interactive mode.
+	if *f.flagNodeCount < 0 && !*f.flagInteractive {
+		switch {
+		default:
+			f.flagNodeCount = newInt(80)
+		case f.isFormat("text"):
+			f.flagNodeCount = newInt(0)
+		}
+	}
+
+	// Apply legacy options and diagnose conflicts.
+	if rc := countFlags([]*bool{f.flagAddresses, f.flagLines, f.flagFiles, f.flagFunctions}); rc == 0 {
+		f.flagFunctions = newBool(true)
+	} else if rc > 1 {
+		f.usage(ui)
+		return fmt.Errorf("must set at most one granularity option")
+	}
+
+	var err error
+	si, sm := *f.flagSampleIndex, *f.flagMean || *f.flagMeanDelay
+	si, err = sampleIndex(p, &f.flagTotalDelay, si, 1, "delay", "-total_delay", err)
+	si, err = sampleIndex(p, &f.flagMeanDelay, si, 1, "delay", "-mean_delay", err)
+	si, err = sampleIndex(p, &f.flagContentions, si, 0, "contentions", "-contentions", err)
+
+	si, err = sampleIndex(p, &f.flagInUseSpace, si, 1, "inuse_space", "-inuse_space", err)
+	si, err = sampleIndex(p, &f.flagInUseObjects, si, 0, "inuse_objects", "-inuse_objects", err)
+	si, err = sampleIndex(p, &f.flagAllocSpace, si, 1, "alloc_space", "-alloc_space", err)
+	si, err = sampleIndex(p, &f.flagAllocObjects, si, 0, "alloc_objects", "-alloc_objects", err)
+
+	if si == -1 {
+		// Use last value if none is requested.
+		si = len(p.SampleType) - 1
+	} else if si < 0 || si >= len(p.SampleType) {
+		err = fmt.Errorf("sample_index value %d out of range [0..%d]", si, len(p.SampleType)-1)
+	}
+
+	if err != nil {
+		f.usage(ui)
+		return err
+	}
+	f.flagSampleIndex, f.flagMean = newInt(si), newBool(sm)
+	return nil
+}
+
+func sampleIndex(p *profile.Profile, flag **bool,
+	sampleIndex int,
+	newSampleIndex int,
+	sampleType, option string,
+	err error) (int, error) {
+	if err != nil || !**flag {
+		return sampleIndex, err
+	}
+	*flag = newBool(false)
+	if sampleIndex != -1 {
+		return 0, fmt.Errorf("set at most one sample value selection option")
+	}
+	if newSampleIndex >= len(p.SampleType) ||
+		p.SampleType[newSampleIndex].Type != sampleType {
+		return 0, fmt.Errorf("option %s not valid for this profile", option)
+	}
+	return newSampleIndex, nil
+}
+
+func countFlags(bs []*bool) int {
+	var c int
+	for _, b := range bs {
+		if *b {
+			c++
+		}
+	}
+	return c
+}
+
+func countFlagMap(bms map[string]*bool, bmrxs map[string]*string) int {
+	var c int
+	for _, b := range bms {
+		if *b {
+			c++
+		}
+	}
+	for _, s := range bmrxs {
+		if *s != "" {
+			c++
+		}
+	}
+	return c
+}
+
+var usageMsgHdr = "usage: pprof [options] [binary] <profile source> ...\n" +
+	"Output format (only set one):\n"
+
+var usageMsg = "Output file parameters (for file-based output formats):\n" +
+	"  -output=f         Generate output on file f (stdout by default)\n" +
+	"Output granularity (only set one):\n" +
+	"  -functions        Report at function level [default]\n" +
+	"  -files            Report at source file level\n" +
+	"  -lines            Report at source line level\n" +
+	"  -addresses        Report at address level\n" +
+	"Comparison options:\n" +
+	"  -base <profile>   Show delta from this profile\n" +
+	"  -drop_negative    Ignore negative differences\n" +
+	"Sorting options:\n" +
+	"  -cum              Sort by cumulative data\n\n" +
+	"Dynamic profile options:\n" +
+	"  -seconds=N        Length of time for dynamic profiles\n" +
+	"Profile trimming options:\n" +
+	"  -nodecount=N      Max number of nodes to show\n" +
+	"  -nodefraction=f   Hide nodes below <f>*total\n" +
+	"  -edgefraction=f   Hide edges below <f>*total\n" +
+	"Sample value selection option (by index):\n" +
+	"  -sample_index      Index of sample value to display\n" +
+	"  -mean              Average sample value over first value\n" +
+	"Sample value selection option (for heap profiles):\n" +
+	"  -inuse_space      Display in-use memory size\n" +
+	"  -inuse_objects    Display in-use object counts\n" +
+	"  -alloc_space      Display allocated memory size\n" +
+	"  -alloc_objects    Display allocated object counts\n" +
+	"Sample value selection option (for contention profiles):\n" +
+	"  -total_delay      Display total delay at each region\n" +
+	"  -contentions      Display number of delays at each region\n" +
+	"  -mean_delay       Display mean delay at each region\n" +
+	"Filtering options:\n" +
+	"  -focus=r          Restricts to paths going through a node matching regexp\n" +
+	"  -ignore=r         Skips paths going through any nodes matching regexp\n" +
+	"  -tagfocus=r       Restrict to samples tagged with key:value matching regexp\n" +
+	"                    Restrict to samples with numeric tags in range (eg \"32kb:1mb\")\n" +
+	"  -tagignore=r      Discard samples tagged with key:value matching regexp\n" +
+	"                    Avoid samples with numeric tags in range (eg \"1mb:\")\n" +
+	"Miscellaneous:\n" +
+	"  -call_tree        Generate a context-sensitive call tree\n" +
+	"  -unit=u           Convert all samples to unit u for display\n" +
+	"  -show_bytes       Display all space in bytes\n" +
+	"  -divide_by=f      Scale all samples by dividing them by f\n" +
+	"  -buildid=id       Override build id for main binary in profile\n" +
+	"  -tools=path       Search path for object-level tools\n" +
+	"  -help             This message"
+
+var usageMsgVars = "Environment Variables:\n" +
+	"   PPROF_TMPDIR       Location for temporary files (default $HOME/pprof)\n" +
+	"   PPROF_TOOLS        Search path for object-level tools\n" +
+	"   PPROF_BINARY_PATH  Search path for local binary files\n" +
+	"                      default: $HOME/pprof/binaries\n" +
+	"                      finds binaries by $name and $buildid/$name"
+
+func aggregate(prof *profile.Profile, f *flags) error {
+	switch {
+	case f.isFormat("proto"), f.isFormat("raw"):
+		// No aggregation for raw profiles.
+	case f.isFormat("callgrind"):
+		// Aggregate to file/line for callgrind.
+		fallthrough
+	case *f.flagLines:
+		return prof.Aggregate(true, true, true, true, false)
+	case *f.flagFiles:
+		return prof.Aggregate(true, false, true, false, false)
+	case *f.flagFunctions:
+		return prof.Aggregate(true, true, false, false, false)
+	case f.isFormat("weblist"), f.isFormat("disasm"):
+		return prof.Aggregate(false, true, true, true, true)
+	}
+	return nil
+}
+
+// parseOptions parses the options into report.Options
+// Returns a function to postprocess the report after generation.
+func parseOptions(f *flags) (o *report.Options, p commands.PostProcessor, err error) {
+
+	if *f.flagDivideBy == 0 {
+		return nil, nil, fmt.Errorf("zero divisor specified")
+	}
+
+	o = &report.Options{
+		CumSort:        *f.flagCum,
+		CallTree:       *f.flagCallTree,
+		PrintAddresses: *f.flagAddresses,
+		DropNegative:   *f.flagDropNegative,
+		Ratio:          1 / *f.flagDivideBy,
+
+		NodeCount:    *f.flagNodeCount,
+		NodeFraction: *f.flagNodeFraction,
+		EdgeFraction: *f.flagEdgeFraction,
+		OutputUnit:   *f.flagDisplayUnit,
+	}
+
+	for cmd, b := range f.flagCommands {
+		if *b {
+			pcmd := f.commands[cmd]
+			o.OutputFormat = pcmd.Format
+			return o, pcmd.PostProcess, nil
+		}
+	}
+
+	for cmd, rx := range f.flagParamCommands {
+		if *rx != "" {
+			pcmd := f.commands[cmd]
+			if o.Symbol, err = regexp.Compile(*rx); err != nil {
+				return nil, nil, fmt.Errorf("parsing -%s regexp: %v", cmd, err)
+			}
+			o.OutputFormat = pcmd.Format
+			return o, pcmd.PostProcess, nil
+		}
+	}
+
+	return nil, nil, fmt.Errorf("no output format selected")
+}
+
+type sampleValueFunc func(*profile.Sample) int64
+
+// sampleFormat returns a function to extract values out of a profile.Sample,
+// and the type/units of those values.
+func sampleFormat(p *profile.Profile, f *flags) (sampleValueFunc, string, string) {
+	valueIndex := *f.flagSampleIndex
+
+	if *f.flagMean {
+		return meanExtractor(valueIndex), "mean_" + p.SampleType[valueIndex].Type, p.SampleType[valueIndex].Unit
+	}
+
+	return valueExtractor(valueIndex), p.SampleType[valueIndex].Type, p.SampleType[valueIndex].Unit
+}
+
+func valueExtractor(ix int) sampleValueFunc {
+	return func(s *profile.Sample) int64 {
+		return s.Value[ix]
+	}
+}
+
+func meanExtractor(ix int) sampleValueFunc {
+	return func(s *profile.Sample) int64 {
+		if s.Value[0] == 0 {
+			return 0
+		}
+		return s.Value[ix] / s.Value[0]
+	}
+}
+
+func generate(interactive bool, prof *profile.Profile, obj plugin.ObjTool, ui plugin.UI, f *flags) error {
+	o, postProcess, err := parseOptions(f)
+	if err != nil {
+		return err
+	}
+
+	var w io.Writer
+	if *f.flagOutput == "" {
+		w = os.Stdout
+	} else {
+		ui.PrintErr("Generating report in ", *f.flagOutput)
+		outputFile, err := os.Create(*f.flagOutput)
+		if err != nil {
+			return err
+		}
+		defer outputFile.Close()
+		w = outputFile
+	}
+
+	value, stype, unit := sampleFormat(prof, f)
+	o.SampleType = stype
+	rpt := report.New(prof, *o, value, unit)
+
+	// Do not apply filters if we're just generating a proto, so we
+	// still have all the data.
+	if o.OutputFormat != report.Proto {
+		// Delay applying focus/ignore until after creating the report so
+		// the report reflects the total number of samples.
+		if err := preprocess(prof, ui, f); err != nil {
+			return err
+		}
+	}
+
+	if postProcess == nil {
+		return report.Generate(w, rpt, obj)
+	}
+
+	var dot bytes.Buffer
+	if err = report.Generate(&dot, rpt, obj); err != nil {
+		return err
+	}
+
+	return postProcess(&dot, w, ui)
+}
diff --git a/src/cmd/pprof/internal/driver/interactive.go b/src/cmd/pprof/internal/driver/interactive.go
new file mode 100644
index 0000000..13009bf
--- /dev/null
+++ b/src/cmd/pprof/internal/driver/interactive.go
@@ -0,0 +1,492 @@
+// 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 driver
+
+import (
+	"fmt"
+	"io"
+	"regexp"
+	"sort"
+	"strconv"
+	"strings"
+
+	"cmd/pprof/internal/commands"
+	"cmd/pprof/internal/plugin"
+	"cmd/pprof/internal/profile"
+)
+
+var profileFunctionNames = []string{}
+
+// functionCompleter replaces provided substring with a function
+// name retrieved from a profile if a single match exists. Otherwise,
+// it returns unchanged substring. It defaults to no-op if the profile
+// is not specified.
+func functionCompleter(substring string) string {
+	found := ""
+	for _, fName := range profileFunctionNames {
+		if strings.Contains(fName, substring) {
+			if found != "" {
+				return substring
+			}
+			found = fName
+		}
+	}
+	if found != "" {
+		return found
+	}
+	return substring
+}
+
+// updateAutoComplete enhances autocompletion with information that can be
+// retrieved from the profile
+func updateAutoComplete(p *profile.Profile) {
+	profileFunctionNames = nil // remove function names retrieved previously
+	for _, fn := range p.Function {
+		profileFunctionNames = append(profileFunctionNames, fn.Name)
+	}
+}
+
+// splitCommand splits the command line input into tokens separated by
+// spaces. Takes care to separate commands of the form 'top10' into
+// two tokens: 'top' and '10'
+func splitCommand(input string) []string {
+	fields := strings.Fields(input)
+	if num := strings.IndexAny(fields[0], "0123456789"); num != -1 {
+		inputNumber := fields[0][num:]
+		fields[0] = fields[0][:num]
+		fields = append([]string{fields[0], inputNumber}, fields[1:]...)
+	}
+	return fields
+}
+
+// interactive displays a prompt and reads commands for profile
+// manipulation/visualization.
+func interactive(p *profile.Profile, obj plugin.ObjTool, ui plugin.UI, f *flags) error {
+	updateAutoComplete(p)
+
+	// Enter command processing loop.
+	ui.Print("Entering interactive mode (type \"help\" for commands)")
+	ui.SetAutoComplete(commands.NewCompleter(f.commands))
+
+	for {
+		input, err := readCommand(p, ui, f)
+		if err != nil {
+			if err != io.EOF {
+				return err
+			}
+			if input == "" {
+				return nil
+			}
+		}
+		// Process simple commands.
+		switch input {
+		case "":
+			continue
+		case ":":
+			f.flagFocus = newString("")
+			f.flagIgnore = newString("")
+			f.flagTagFocus = newString("")
+			f.flagTagIgnore = newString("")
+			f.flagHide = newString("")
+			continue
+		}
+
+		fields := splitCommand(input)
+		// Process report generation commands.
+		if _, ok := f.commands[fields[0]]; ok {
+			if err := generateReport(p, fields, obj, ui, f); err != nil {
+				if err == io.EOF {
+					return nil
+				}
+				ui.PrintErr(err)
+			}
+			continue
+		}
+
+		switch cmd := fields[0]; cmd {
+		case "help":
+			commandHelp(fields, ui, f)
+			continue
+		case "exit", "quit":
+			return nil
+		}
+
+		// Process option settings.
+		if of, err := optFlags(p, input, f); err == nil {
+			f = of
+		} else {
+			ui.PrintErr("Error: ", err.Error())
+		}
+	}
+}
+
+func generateReport(p *profile.Profile, cmd []string, obj plugin.ObjTool, ui plugin.UI, f *flags) error {
+	prof := p.Copy()
+
+	cf, err := cmdFlags(prof, cmd, ui, f)
+	if err != nil {
+		return err
+	}
+
+	return generate(true, prof, obj, ui, cf)
+}
+
+// validateRegex checks if a string is a valid regular expression.
+func validateRegex(v string) error {
+	_, err := regexp.Compile(v)
+	return err
+}
+
+// readCommand prompts for and reads the next command.
+func readCommand(p *profile.Profile, ui plugin.UI, f *flags) (string, error) {
+	//ui.Print("Options:\n", f.String(p))
+	s, err := ui.ReadLine()
+	return strings.TrimSpace(s), err
+}
+
+func commandHelp(_ []string, ui plugin.UI, f *flags) error {
+	help := `
+ Commands:
+   cmd [n] [--cum] [focus_regex]* [-ignore_regex]*
+       Produce a text report with the top n entries.
+       Include samples matching focus_regex, and exclude ignore_regex.
+       Add --cum to sort using cumulative data.
+       Available commands:
+`
+	var commands []string
+	for name, cmd := range f.commands {
+		commands = append(commands, fmt.Sprintf("         %-12s %s", name, cmd.Usage))
+	}
+	sort.Strings(commands)
+
+	help = help + strings.Join(commands, "\n") + `
+   peek func_regex
+       Display callers and callees of functions matching func_regex.
+
+   dot [n] [focus_regex]* [-ignore_regex]* [>file]
+       Produce an annotated callgraph with the top n entries.
+       Include samples matching focus_regex, and exclude ignore_regex.
+       For other outputs, replace dot with:
+       - Graphic formats: dot, svg, pdf, ps, gif, png (use > to name output file)
+       - Graph viewer:    gv, web, evince, eog
+
+   callgrind [n] [focus_regex]* [-ignore_regex]* [>file]
+       Produce a file in callgrind-compatible format.
+       Include samples matching focus_regex, and exclude ignore_regex.
+
+   weblist func_regex [-ignore_regex]*
+       Show annotated source with interspersed assembly in a web browser.
+
+   list func_regex [-ignore_regex]*
+       Print source for routines matching func_regex, and exclude ignore_regex.
+
+   disasm func_regex [-ignore_regex]*
+       Disassemble routines matching func_regex, and exclude ignore_regex.
+
+   tags tag_regex [-ignore_regex]*
+       List tags with key:value matching tag_regex and exclude ignore_regex.
+
+   quit/exit/^D
+ 	     Exit pprof.
+
+   option=value
+       The following options can be set individually:
+           cum/flat:           Sort entries based on cumulative or flat data
+           call_tree:          Build context-sensitive call trees
+           nodecount:          Max number of entries to display
+           nodefraction:       Min frequency ratio of nodes to display
+           edgefraction:       Min frequency ratio of edges to display
+           focus/ignore:       Regexp to include/exclude samples by name/file
+           tagfocus/tagignore: Regexp or value range to filter samples by tag
+                               eg "1mb", "1mb:2mb", ":64kb"
+
+           functions:          Level of aggregation for sample data
+           files:
+           lines:
+           addresses:
+
+           unit:               Measurement unit to use on reports
+
+           Sample value selection by index:
+            sample_index:      Index of sample value to display
+            mean:              Average sample value over first value
+
+           Sample value selection by name:
+            alloc_space        for heap profiles
+            alloc_objects
+            inuse_space
+            inuse_objects
+
+            total_delay        for contention profiles
+            mean_delay
+            contentions
+
+   :   Clear focus/ignore/hide/tagfocus/tagignore`
+
+	ui.Print(help)
+	return nil
+}
+
+// cmdFlags parses the options of an interactive command and returns
+// an updated flags object.
+func cmdFlags(prof *profile.Profile, input []string, ui plugin.UI, f *flags) (*flags, error) {
+	cf := *f
+
+	var focus, ignore string
+	output := *cf.flagOutput
+	nodeCount := *cf.flagNodeCount
+	cmd := input[0]
+
+	// Update output flags based on parameters.
+	tokens := input[1:]
+	for p := 0; p < len(tokens); p++ {
+		t := tokens[p]
+		if t == "" {
+			continue
+		}
+		if c, err := strconv.ParseInt(t, 10, 32); err == nil {
+			nodeCount = int(c)
+			continue
+		}
+		switch t[0] {
+		case '>':
+			if len(t) > 1 {
+				output = t[1:]
+				continue
+			}
+			// find next token
+			for p++; p < len(tokens); p++ {
+				if tokens[p] != "" {
+					output = tokens[p]
+					break
+				}
+			}
+		case '-':
+			if t == "--cum" || t == "-cum" {
+				cf.flagCum = newBool(true)
+				continue
+			}
+			ignore = catRegex(ignore, t[1:])
+		default:
+			focus = catRegex(focus, t)
+		}
+	}
+
+	pcmd, ok := f.commands[cmd]
+	if !ok {
+		return nil, fmt.Errorf("Unexpected parse failure: %v", input)
+	}
+	// Reset flags
+	cf.flagCommands = make(map[string]*bool)
+	cf.flagParamCommands = make(map[string]*string)
+
+	if !pcmd.HasParam {
+		cf.flagCommands[cmd] = newBool(true)
+
+		switch cmd {
+		case "tags":
+			cf.flagTagFocus = newString(focus)
+			cf.flagTagIgnore = newString(ignore)
+		default:
+			cf.flagFocus = newString(catRegex(*cf.flagFocus, focus))
+			cf.flagIgnore = newString(catRegex(*cf.flagIgnore, ignore))
+		}
+	} else {
+		if focus == "" {
+			focus = "."
+		}
+		cf.flagParamCommands[cmd] = newString(focus)
+		cf.flagIgnore = newString(catRegex(*cf.flagIgnore, ignore))
+	}
+
+	if nodeCount < 0 {
+		switch cmd {
+		case "text", "top":
+			// Default text/top to 10 nodes on interactive mode
+			nodeCount = 10
+		default:
+			nodeCount = 80
+		}
+	}
+
+	cf.flagNodeCount = newInt(nodeCount)
+	cf.flagOutput = newString(output)
+
+	// Do regular flags processing
+	if err := processFlags(prof, ui, &cf); err != nil {
+		cf.usage(ui)
+		return nil, err
+	}
+
+	return &cf, nil
+}
+
+func catRegex(a, b string) string {
+	if a == "" {
+		return b
+	}
+	if b == "" {
+		return a
+	}
+	return a + "|" + b
+}
+
+// optFlags parses an interactive option setting and returns
+// an updated flags object.
+func optFlags(p *profile.Profile, input string, f *flags) (*flags, error) {
+	inputs := strings.SplitN(input, "=", 2)
+	option := strings.ToLower(strings.TrimSpace(inputs[0]))
+	var value string
+	if len(inputs) == 2 {
+		value = strings.TrimSpace(inputs[1])
+	}
+
+	of := *f
+
+	var err error
+	var bv bool
+	var uv uint64
+	var fv float64
+
+	switch option {
+	case "cum":
+		if bv, err = parseBool(value); err != nil {
+			return nil, err
+		}
+		of.flagCum = newBool(bv)
+	case "flat":
+		if bv, err = parseBool(value); err != nil {
+			return nil, err
+		}
+		of.flagCum = newBool(!bv)
+	case "call_tree":
+		if bv, err = parseBool(value); err != nil {
+			return nil, err
+		}
+		of.flagCallTree = newBool(bv)
+	case "unit":
+		of.flagDisplayUnit = newString(value)
+	case "sample_index":
+		if uv, err = strconv.ParseUint(value, 10, 32); err != nil {
+			return nil, err
+		}
+		if ix := int(uv); ix < 0 || ix >= len(p.SampleType) {
+			return nil, fmt.Errorf("sample_index out of range [0..%d]", len(p.SampleType)-1)
+		}
+		of.flagSampleIndex = newInt(int(uv))
+	case "mean":
+		if bv, err = parseBool(value); err != nil {
+			return nil, err
+		}
+		of.flagMean = newBool(bv)
+	case "nodecount":
+		if uv, err = strconv.ParseUint(value, 10, 32); err != nil {
+			return nil, err
+		}
+		of.flagNodeCount = newInt(int(uv))
+	case "nodefraction":
+		if fv, err = strconv.ParseFloat(value, 64); err != nil {
+			return nil, err
+		}
+		of.flagNodeFraction = newFloat64(fv)
+	case "edgefraction":
+		if fv, err = strconv.ParseFloat(value, 64); err != nil {
+			return nil, err
+		}
+		of.flagEdgeFraction = newFloat64(fv)
+	case "focus":
+		if err = validateRegex(value); err != nil {
+			return nil, err
+		}
+		of.flagFocus = newString(value)
+	case "ignore":
+		if err = validateRegex(value); err != nil {
+			return nil, err
+		}
+		of.flagIgnore = newString(value)
+	case "tagfocus":
+		if err = validateRegex(value); err != nil {
+			return nil, err
+		}
+		of.flagTagFocus = newString(value)
+	case "tagignore":
+		if err = validateRegex(value); err != nil {
+			return nil, err
+		}
+		of.flagTagIgnore = newString(value)
+	case "hide":
+		if err = validateRegex(value); err != nil {
+			return nil, err
+		}
+		of.flagHide = newString(value)
+	case "addresses", "files", "lines", "functions":
+		if bv, err = parseBool(value); err != nil {
+			return nil, err
+		}
+		if !bv {
+			return nil, fmt.Errorf("select one of addresses/files/lines/functions")
+		}
+		setGranularityToggle(option, &of)
+	default:
+		if ix := findSampleIndex(p, "", option); ix >= 0 {
+			of.flagSampleIndex = newInt(ix)
+		} else if ix := findSampleIndex(p, "total_", option); ix >= 0 {
+			of.flagSampleIndex = newInt(ix)
+			of.flagMean = newBool(false)
+		} else if ix := findSampleIndex(p, "mean_", option); ix >= 1 {
+			of.flagSampleIndex = newInt(ix)
+			of.flagMean = newBool(true)
+		} else {
+			return nil, fmt.Errorf("unrecognized command: %s", input)
+		}
+	}
+	return &of, nil
+}
+
+// parseBool parses a string as a boolean value.
+func parseBool(v string) (bool, error) {
+	switch strings.ToLower(v) {
+	case "true", "t", "yes", "y", "1", "":
+		return true, nil
+	case "false", "f", "no", "n", "0":
+		return false, nil
+	}
+	return false, fmt.Errorf(`illegal input "%s" for bool value`, v)
+}
+
+func findSampleIndex(p *profile.Profile, prefix, sampleType string) int {
+	if !strings.HasPrefix(sampleType, prefix) {
+		return -1
+	}
+	sampleType = strings.TrimPrefix(sampleType, prefix)
+	for i, r := range p.SampleType {
+		if r.Type == sampleType {
+			return i
+		}
+	}
+	return -1
+}
+
+// setGranularityToggle manages the set of granularity options. These
+// operate as a toggle; turning one on turns the others off.
+func setGranularityToggle(o string, fl *flags) {
+	t, f := newBool(true), newBool(false)
+	fl.flagFunctions = f
+	fl.flagFiles = f
+	fl.flagLines = f
+	fl.flagAddresses = f
+	switch o {
+	case "functions":
+		fl.flagFunctions = t
+	case "files":
+		fl.flagFiles = t
+	case "lines":
+		fl.flagLines = t
+	case "addresses":
+		fl.flagAddresses = t
+	default:
+		panic(fmt.Errorf("unexpected option %s", o))
+	}
+}
diff --git a/src/cmd/pprof/internal/fetch/fetch.go b/src/cmd/pprof/internal/fetch/fetch.go
new file mode 100644
index 0000000..ec4a638
--- /dev/null
+++ b/src/cmd/pprof/internal/fetch/fetch.go
@@ -0,0 +1,82 @@
+// 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 fetch provides an extensible mechanism to fetch a profile
+// from a data source.
+package fetch
+
+import (
+	"fmt"
+	"io"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+	"os"
+	"strings"
+	"time"
+
+	"cmd/pprof/internal/plugin"
+	"cmd/pprof/internal/profile"
+)
+
+// FetchProfile reads from a data source (network, file) and generates a
+// profile.
+func FetchProfile(source string, timeout time.Duration) (*profile.Profile, error) {
+	return Fetcher(source, timeout, plugin.StandardUI())
+}
+
+// Fetcher is the plugin.Fetcher version of FetchProfile.
+func Fetcher(source string, timeout time.Duration, ui plugin.UI) (*profile.Profile, error) {
+	var f io.ReadCloser
+	var err error
+
+	url, err := url.Parse(source)
+	if err == nil && url.Host != "" {
+		f, err = FetchURL(source, timeout)
+	} else {
+		f, err = os.Open(source)
+	}
+	if err != nil {
+		return nil, err
+	}
+	defer f.Close()
+	return profile.Parse(f)
+}
+
+// FetchURL fetches a profile from a URL using HTTP.
+func FetchURL(source string, timeout time.Duration) (io.ReadCloser, error) {
+	resp, err := httpGet(source, timeout)
+	if err != nil {
+		return nil, fmt.Errorf("http fetch %s: %v", source, err)
+	}
+	if resp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf("server response: %s", resp.Status)
+	}
+
+	return resp.Body, nil
+}
+
+// PostURL issues a POST to a URL over HTTP.
+func PostURL(source, post string) ([]byte, error) {
+	resp, err := http.Post(source, "application/octet-stream", strings.NewReader(post))
+	if err != nil {
+		return nil, fmt.Errorf("http post %s: %v", source, err)
+	}
+	if resp.StatusCode != http.StatusOK {
+		return nil, fmt.Errorf("server response: %s", resp.Status)
+	}
+	defer resp.Body.Close()
+	return ioutil.ReadAll(resp.Body)
+}
+
+// httpGet is a wrapper around http.Get; it is defined as a variable
+// so it can be redefined during for testing.
+var httpGet = func(url string, timeout time.Duration) (*http.Response, error) {
+	client := &http.Client{
+		Transport: &http.Transport{
+			ResponseHeaderTimeout: timeout + 5*time.Second,
+		},
+	}
+	return client.Get(url)
+}
diff --git a/src/cmd/pprof/internal/plugin/plugin.go b/src/cmd/pprof/internal/plugin/plugin.go
new file mode 100644
index 0000000..a22ec5f
--- /dev/null
+++ b/src/cmd/pprof/internal/plugin/plugin.go
@@ -0,0 +1,213 @@
+// 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 plugin defines the plugin implementations that the main pprof driver requires.
+package plugin
+
+import (
+	"bufio"
+	"fmt"
+	"os"
+	"regexp"
+	"strings"
+	"time"
+
+	"cmd/pprof/internal/profile"
+)
+
+// A FlagSet creates and parses command-line flags.
+// It is similar to the standard flag.FlagSet.
+type FlagSet interface {
+	// Bool, Int, Float64, and String define new flags,
+	// like the functions of the same name in package flag.
+	Bool(name string, def bool, usage string) *bool
+	Int(name string, def int, usage string) *int
+	Float64(name string, def float64, usage string) *float64
+	String(name string, def string, usage string) *string
+
+	// ExtraUsage returns any additional text that should be
+	// printed after the standard usage message.
+	// The typical use of ExtraUsage is to show any custom flags
+	// defined by the specific pprof plugins being used.
+	ExtraUsage() string
+
+	// Parse initializes the flags with their values for this run
+	// and returns the non-flag command line arguments.
+	// If an unknown flag is encountered or there are no arguments,
+	// Parse should call usage and return nil.
+	Parse(usage func()) []string
+}
+
+// An ObjTool inspects shared libraries and executable files.
+type ObjTool interface {
+	// Open opens the named object file.
+	// If the object is a shared library, start is the address where
+	// it is mapped into memory in the address space being inspected.
+	Open(file string, start uint64) (ObjFile, error)
+
+	// Demangle translates a batch of symbol names from mangled
+	// form to human-readable form.
+	Demangle(names []string) (map[string]string, error)
+
+	// Disasm disassembles the named object file, starting at
+	// the start address and stopping at (before) the end address.
+	Disasm(file string, start, end uint64) ([]Inst, error)
+
+	// SetConfig configures the tool.
+	// The implementation defines the meaning of the string
+	// and can ignore it entirely.
+	SetConfig(config string)
+}
+
+// NoObjTool returns a trivial implementation of the ObjTool interface.
+// Open returns an error indicating that the requested file does not exist.
+// Demangle returns an empty map and a nil error.
+// Disasm returns an error.
+// SetConfig is a no-op.
+func NoObjTool() ObjTool {
+	return noObjTool{}
+}
+
+type noObjTool struct{}
+
+func (noObjTool) Open(file string, start uint64) (ObjFile, error) {
+	return nil, &os.PathError{Op: "open", Path: file, Err: os.ErrNotExist}
+}
+
+func (noObjTool) Demangle(name []string) (map[string]string, error) {
+	return make(map[string]string), nil
+}
+
+func (noObjTool) Disasm(file string, start, end uint64) ([]Inst, error) {
+	return nil, fmt.Errorf("disassembly not supported")
+}
+
+func (noObjTool) SetConfig(config string) {
+}
+
+// An ObjFile is a single object file: a shared library or executable.
+type ObjFile interface {
+	// Name returns the underlyinf file name, if available
+	Name() string
+
+	// Base returns the base address to use when looking up symbols in the file.
+	Base() uint64
+
+	// BuildID returns the GNU build ID of the file, or an empty string.
+	BuildID() string
+
+	// SourceLine reports the source line information for a given
+	// address in the file. Due to inlining, the source line information
+	// is in general a list of positions representing a call stack,
+	// with the leaf function first.
+	SourceLine(addr uint64) ([]Frame, error)
+
+	// Symbols returns a list of symbols in the object file.
+	// If r is not nil, Symbols restricts the list to symbols
+	// with names matching the regular expression.
+	// If addr is not zero, Symbols restricts the list to symbols
+	// containing that address.
+	Symbols(r *regexp.Regexp, addr uint64) ([]*Sym, error)
+
+	// Close closes the file, releasing associated resources.
+	Close() error
+}
+
+// A Frame describes a single line in a source file.
+type Frame struct {
+	Func string // name of function
+	File string // source file name
+	Line int    // line in file
+}
+
+// A Sym describes a single symbol in an object file.
+type Sym struct {
+	Name  []string // names of symbol (many if symbol was dedup'ed)
+	File  string   // object file containing symbol
+	Start uint64   // start virtual address
+	End   uint64   // virtual address of last byte in sym (Start+size-1)
+}
+
+// An Inst is a single instruction in an assembly listing.
+type Inst struct {
+	Addr uint64 // virtual address of instruction
+	Text string // instruction text
+	File string // source file
+	Line int    // source line
+}
+
+// A UI manages user interactions.
+type UI interface {
+	// Read returns a line of text (a command) read from the user.
+	ReadLine() (string, error)
+
+	// Print shows a message to the user.
+	// It formats the text as fmt.Print would and adds a final \n if not already present.
+	// For line-based UI, Print writes to standard error.
+	// (Standard output is reserved for report data.)
+	Print(...interface{})
+
+	// PrintErr shows an error message to the user.
+	// It formats the text as fmt.Print would and adds a final \n if not already present.
+	// For line-based UI, PrintErr writes to standard error.
+	PrintErr(...interface{})
+
+	// IsTerminal returns whether the UI is known to be tied to an
+	// interactive terminal (as opposed to being redirected to a file).
+	IsTerminal() bool
+
+	// SetAutoComplete instructs the UI to call complete(cmd) to obtain
+	// the auto-completion of cmd, if the UI supports auto-completion at all.
+	SetAutoComplete(complete func(string) string)
+}
+
+// StandardUI returns a UI that reads from standard input,
+// prints messages to standard output,
+// prints errors to standard error, and doesn't use auto-completion.
+func StandardUI() UI {
+	return &stdUI{r: bufio.NewReader(os.Stdin)}
+}
+
+type stdUI struct {
+	r *bufio.Reader
+}
+
+func (ui *stdUI) ReadLine() (string, error) {
+	os.Stdout.WriteString("(pprof) ")
+	return ui.r.ReadString('\n')
+}
+
+func (ui *stdUI) Print(args ...interface{}) {
+	ui.fprint(os.Stderr, args)
+}
+
+func (ui *stdUI) PrintErr(args ...interface{}) {
+	ui.fprint(os.Stderr, args)
+}
+
+func (ui *stdUI) IsTerminal() bool {
+	return false
+}
+
+func (ui *stdUI) SetAutoComplete(func(string) string) {
+}
+
+func (ui *stdUI) fprint(f *os.File, args []interface{}) {
+	text := fmt.Sprint(args...)
+	if !strings.HasSuffix(text, "\n") {
+		text += "\n"
+	}
+	f.WriteString(text)
+}
+
+// A Fetcher reads and returns the profile named by src.
+// It gives up after the given timeout, unless src contains a timeout override
+// (as defined by the implementation).
+// It can print messages to ui.
+type Fetcher func(src string, timeout time.Duration, ui UI) (*profile.Profile, error)
+
+// A Symbolizer annotates a profile with symbol information.
+// The profile was fetch from src.
+// The meaning of mode is defined by the implementation.
+type Symbolizer func(mode, src string, prof *profile.Profile, obj ObjTool, ui UI) error
diff --git a/src/cmd/pprof/internal/profile/encode.go b/src/cmd/pprof/internal/profile/encode.go
new file mode 100644
index 0000000..455aca2
--- /dev/null
+++ b/src/cmd/pprof/internal/profile/encode.go
@@ -0,0 +1,470 @@
+// 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 profile
+
+import (
+	"errors"
+	"fmt"
+	"sort"
+)
+
+func (p *Profile) decoder() []decoder {
+	return profileDecoder
+}
+
+// preEncode populates the unexported fields to be used by encode
+// (with suffix X) from the corresponding exported fields.  The
+// exported fields are cleared up to facilitate testing.
+func (p *Profile) preEncode() {
+	strings := make(map[string]int)
+	addString(strings, "")
+
+	for _, st := range p.SampleType {
+		st.typeX = addString(strings, st.Type)
+		st.unitX = addString(strings, st.Unit)
+	}
+
+	for _, s := range p.Sample {
+		s.labelX = nil
+		var keys []string
+		for k := range s.Label {
+			keys = append(keys, k)
+		}
+		sort.Strings(keys)
+		for _, k := range keys {
+			vs := s.Label[k]
+			for _, v := range vs {
+				s.labelX = append(s.labelX,
+					Label{
+						keyX: addString(strings, k),
+						strX: addString(strings, v),
+					},
+				)
+			}
+		}
+		var numKeys []string
+		for k := range s.NumLabel {
+			numKeys = append(numKeys, k)
+		}
+		sort.Strings(numKeys)
+		for _, k := range numKeys {
+			vs := s.NumLabel[k]
+			for _, v := range vs {
+				s.labelX = append(s.labelX,
+					Label{
+						keyX: addString(strings, k),
+						numX: v,
+					},
+				)
+			}
+		}
+		s.locationIDX = nil
+		for _, l := range s.Location {
+			s.locationIDX = append(s.locationIDX, l.ID)
+		}
+	}
+
+	for _, m := range p.Mapping {
+		m.fileX = addString(strings, m.File)
+		m.buildIDX = addString(strings, m.BuildID)
+	}
+
+	for _, l := range p.Location {
+		for i, ln := range l.Line {
+			if ln.Function != nil {
+				l.Line[i].functionIDX = ln.Function.ID
+			} else {
+				l.Line[i].functionIDX = 0
+			}
+		}
+		if l.Mapping != nil {
+			l.mappingIDX = l.Mapping.ID
+		} else {
+			l.mappingIDX = 0
+		}
+	}
+	for _, f := range p.Function {
+		f.nameX = addString(strings, f.Name)
+		f.systemNameX = addString(strings, f.SystemName)
+		f.filenameX = addString(strings, f.Filename)
+	}
+
+	p.dropFramesX = addString(strings, p.DropFrames)
+	p.keepFramesX = addString(strings, p.KeepFrames)
+
+	if pt := p.PeriodType; pt != nil {
+		pt.typeX = addString(strings, pt.Type)
+		pt.unitX = addString(strings, pt.Unit)
+	}
+
+	p.stringTable = make([]string, len(strings))
+	for s, i := range strings {
+		p.stringTable[i] = s
+	}
+}
+
+func (p *Profile) encode(b *buffer) {
+	for _, x := range p.SampleType {
+		encodeMessage(b, 1, x)
+	}
+	for _, x := range p.Sample {
+		encodeMessage(b, 2, x)
+	}
+	for _, x := range p.Mapping {
+		encodeMessage(b, 3, x)
+	}
+	for _, x := range p.Location {
+		encodeMessage(b, 4, x)
+	}
+	for _, x := range p.Function {
+		encodeMessage(b, 5, x)
+	}
+	encodeStrings(b, 6, p.stringTable)
+	encodeInt64Opt(b, 7, p.dropFramesX)
+	encodeInt64Opt(b, 8, p.keepFramesX)
+	encodeInt64Opt(b, 9, p.TimeNanos)
+	encodeInt64Opt(b, 10, p.DurationNanos)
+	if pt := p.PeriodType; pt != nil && (pt.typeX != 0 || pt.unitX != 0) {
+		encodeMessage(b, 11, p.PeriodType)
+	}
+	encodeInt64Opt(b, 12, p.Period)
+}
+
+var profileDecoder = []decoder{
+	nil, // 0
+	// repeated ValueType sample_type = 1
+	func(b *buffer, m message) error {
+		x := new(ValueType)
+		pp := m.(*Profile)
+		pp.SampleType = append(pp.SampleType, x)
+		return decodeMessage(b, x)
+	},
+	// repeated Sample sample = 2
+	func(b *buffer, m message) error {
+		x := new(Sample)
+		pp := m.(*Profile)
+		pp.Sample = append(pp.Sample, x)
+		return decodeMessage(b, x)
+	},
+	// repeated Mapping mapping = 3
+	func(b *buffer, m message) error {
+		x := new(Mapping)
+		pp := m.(*Profile)
+		pp.Mapping = append(pp.Mapping, x)
+		return decodeMessage(b, x)
+	},
+	// repeated Location location = 4
+	func(b *buffer, m message) error {
+		x := new(Location)
+		pp := m.(*Profile)
+		pp.Location = append(pp.Location, x)
+		return decodeMessage(b, x)
+	},
+	// repeasted Function function = 5
+	func(b *buffer, m message) error {
+		x := new(Function)
+		pp := m.(*Profile)
+		pp.Function = append(pp.Function, x)
+		return decodeMessage(b, x)
+	},
+	// repeated string string_table = 6
+	func(b *buffer, m message) error {
+		err := decodeStrings(b, &m.(*Profile).stringTable)
+		if err != nil {
+			return err
+		}
+		if *&m.(*Profile).stringTable[0] != "" {
+			return errors.New("string_table[0] must be ''")
+		}
+		return nil
+	},
+	// repeated int64 drop_frames = 7
+	func(b *buffer, m message) error { return decodeInt64(b, &m.(*Profile).dropFramesX) },
+	// repeated int64 keep_frames = 8
+	func(b *buffer, m message) error { return decodeInt64(b, &m.(*Profile).keepFramesX) },
+	// repeated int64 time_nanos = 9
+	func(b *buffer, m message) error { return decodeInt64(b, &m.(*Profile).TimeNanos) },
+	// repeated int64 duration_nanos = 10
+	func(b *buffer, m message) error { return decodeInt64(b, &m.(*Profile).DurationNanos) },
+	// optional string period_type = 11
+	func(b *buffer, m message) error {
+		x := new(ValueType)
+		pp := m.(*Profile)
+		pp.PeriodType = x
+		return decodeMessage(b, x)
+	},
+	// repeated int64 period = 12
+	func(b *buffer, m message) error { return decodeInt64(b, &m.(*Profile).Period) },
+}
+
+// postDecode takes the unexported fields populated by decode (with
+// suffix X) and populates the corresponding exported fields.
+// The unexported fields are cleared up to facilitate testing.
+func (p *Profile) postDecode() error {
+	var err error
+
+	mappings := make(map[uint64]*Mapping)
+	for _, m := range p.Mapping {
+		m.File, err = getString(p.stringTable, &m.fileX, err)
+		m.BuildID, err = getString(p.stringTable, &m.buildIDX, err)
+		mappings[m.ID] = m
+	}
+
+	functions := make(map[uint64]*Function)
+	for _, f := range p.Function {
+		f.Name, err = getString(p.stringTable, &f.nameX, err)
+		f.SystemName, err = getString(p.stringTable, &f.systemNameX, err)
+		f.Filename, err = getString(p.stringTable, &f.filenameX, err)
+		functions[f.ID] = f
+	}
+
+	locations := make(map[uint64]*Location)
+	for _, l := range p.Location {
+		l.Mapping = mappings[l.mappingIDX]
+		l.mappingIDX = 0
+		for i, ln := range l.Line {
+			if id := ln.functionIDX; id != 0 {
+				l.Line[i].Function = functions[id]
+				if l.Line[i].Function == nil {
+					return fmt.Errorf("Function ID %d not found", id)
+				}
+				l.Line[i].functionIDX = 0
+			}
+		}
+		locations[l.ID] = l
+	}
+
+	for _, st := range p.SampleType {
+		st.Type, err = getString(p.stringTable, &st.typeX, err)
+		st.Unit, err = getString(p.stringTable, &st.unitX, err)
+	}
+
+	for _, s := range p.Sample {
+		labels := make(map[string][]string)
+		numLabels := make(map[string][]int64)
+		for _, l := range s.labelX {
+			var key, value string
+			key, err = getString(p.stringTable, &l.keyX, err)
+			if l.strX != 0 {
+				value, err = getString(p.stringTable, &l.strX, err)
+				labels[key] = append(labels[key], value)
+			} else {
+				numLabels[key] = append(numLabels[key], l.numX)
+			}
+		}
+		if len(labels) > 0 {
+			s.Label = labels
+		}
+		if len(numLabels) > 0 {
+			s.NumLabel = numLabels
+		}
+		s.Location = nil
+		for _, lid := range s.locationIDX {
+			s.Location = append(s.Location, locations[lid])
+		}
+		s.locationIDX = nil
+	}
+
+	p.DropFrames, err = getString(p.stringTable, &p.dropFramesX, err)
+	p.KeepFrames, err = getString(p.stringTable, &p.keepFramesX, err)
+
+	if pt := p.PeriodType; pt == nil {
+		p.PeriodType = &ValueType{}
+	}
+
+	if pt := p.PeriodType; pt != nil {
+		pt.Type, err = getString(p.stringTable, &pt.typeX, err)
+		pt.Unit, err = getString(p.stringTable, &pt.unitX, err)
+	}
+	p.stringTable = nil
+	return nil
+}
+
+func (p *ValueType) decoder() []decoder {
+	return valueTypeDecoder
+}
+
+func (p *ValueType) encode(b *buffer) {
+	encodeInt64Opt(b, 1, p.typeX)
+	encodeInt64Opt(b, 2, p.unitX)
+}
+
+var valueTypeDecoder = []decoder{
+	nil, // 0
+	// optional int64 type = 1
+	func(b *buffer, m message) error { return decodeInt64(b, &m.(*ValueType).typeX) },
+	// optional int64 unit = 2
+	func(b *buffer, m message) error { return decodeInt64(b, &m.(*ValueType).unitX) },
+}
+
+func (p *Sample) decoder() []decoder {
+	return sampleDecoder
+}
+
+func (p *Sample) encode(b *buffer) {
+	encodeUint64s(b, 1, p.locationIDX)
+	for _, x := range p.Value {
+		encodeInt64(b, 2, x)
+	}
+	for _, x := range p.labelX {
+		encodeMessage(b, 3, x)
+	}
+}
+
+var sampleDecoder = []decoder{
+	nil, // 0
+	// repeated uint64 location = 1
+	func(b *buffer, m message) error { return decodeUint64s(b, &m.(*Sample).locationIDX) },
+	// repeated int64 value = 2
+	func(b *buffer, m message) error { return decodeInt64s(b, &m.(*Sample).Value) },
+	// repeated Label label = 3
+	func(b *buffer, m message) error {
+		s := m.(*Sample)
+		n := len(s.labelX)
+		s.labelX = append(s.labelX, Label{})
+		return decodeMessage(b, &s.labelX[n])
+	},
+}
+
+func (p Label) decoder() []decoder {
+	return labelDecoder
+}
+
+func (p Label) encode(b *buffer) {
+	encodeInt64Opt(b, 1, p.keyX)
+	encodeInt64Opt(b, 2, p.strX)
+	encodeInt64Opt(b, 3, p.numX)
+}
+
+var labelDecoder = []decoder{
+	nil, // 0
+	// optional int64 key = 1
+	func(b *buffer, m message) error { return decodeInt64(b, &m.(*Label).keyX) },
+	// optional int64 str = 2
+	func(b *buffer, m message) error { return decodeInt64(b, &m.(*Label).strX) },
+	// optional int64 num = 3
+	func(b *buffer, m message) error { return decodeInt64(b, &m.(*Label).numX) },
+}
+
+func (p *Mapping) decoder() []decoder {
+	return mappingDecoder
+}
+
+func (p *Mapping) encode(b *buffer) {
+	encodeUint64Opt(b, 1, p.ID)
+	encodeUint64Opt(b, 2, p.Start)
+	encodeUint64Opt(b, 3, p.Limit)
+	encodeUint64Opt(b, 4, p.Offset)
+	encodeInt64Opt(b, 5, p.fileX)
+	encodeInt64Opt(b, 6, p.buildIDX)
+	encodeBoolOpt(b, 7, p.HasFunctions)
+	encodeBoolOpt(b, 8, p.HasFilenames)
+	encodeBoolOpt(b, 9, p.HasLineNumbers)
+	encodeBoolOpt(b, 10, p.HasInlineFrames)
+}
+
+var mappingDecoder = []decoder{
+	nil, // 0
+	func(b *buffer, m message) error { return decodeUint64(b, &m.(*Mapping).ID) },            // optional uint64 id = 1
+	func(b *buffer, m message) error { return decodeUint64(b, &m.(*Mapping).Start) },         // optional uint64 memory_offset = 2
+	func(b *buffer, m message) error { return decodeUint64(b, &m.(*Mapping).Limit) },         // optional uint64 memory_limit = 3
+	func(b *buffer, m message) error { return decodeUint64(b, &m.(*Mapping).Offset) },        // optional uint64 file_offset = 4
+	func(b *buffer, m message) error { return decodeInt64(b, &m.(*Mapping).fileX) },          // optional int64 filename = 5
+	func(b *buffer, m message) error { return decodeInt64(b, &m.(*Mapping).buildIDX) },       // optional int64 build_id = 6
+	func(b *buffer, m message) error { return decodeBool(b, &m.(*Mapping).HasFunctions) },    // optional bool has_functions = 7
+	func(b *buffer, m message) error { return decodeBool(b, &m.(*Mapping).HasFilenames) },    // optional bool has_filenames = 8
+	func(b *buffer, m message) error { return decodeBool(b, &m.(*Mapping).HasLineNumbers) },  // optional bool has_line_numbers = 9
+	func(b *buffer, m message) error { return decodeBool(b, &m.(*Mapping).HasInlineFrames) }, // optional bool has_inline_frames = 10
+}
+
+func (p *Location) decoder() []decoder {
+	return locationDecoder
+}
+
+func (p *Location) encode(b *buffer) {
+	encodeUint64Opt(b, 1, p.ID)
+	encodeUint64Opt(b, 2, p.mappingIDX)
+	encodeUint64Opt(b, 3, p.Address)
+	for i := range p.Line {
+		encodeMessage(b, 4, &p.Line[i])
+	}
+}
+
+var locationDecoder = []decoder{
+	nil, // 0
+	func(b *buffer, m message) error { return decodeUint64(b, &m.(*Location).ID) },         // optional uint64 id = 1;
+	func(b *buffer, m message) error { return decodeUint64(b, &m.(*Location).mappingIDX) }, // optional uint64 mapping_id = 2;
+	func(b *buffer, m message) error { return decodeUint64(b, &m.(*Location).Address) },    // optional uint64 address = 3;
+	func(b *buffer, m message) error { // repeated Line line = 4
+		pp := m.(*Location)
+		n := len(pp.Line)
+		pp.Line = append(pp.Line, Line{})
+		return decodeMessage(b, &pp.Line[n])
+	},
+}
+
+func (p *Line) decoder() []decoder {
+	return lineDecoder
+}
+
+func (p *Line) encode(b *buffer) {
+	encodeUint64Opt(b, 1, p.functionIDX)
+	encodeInt64Opt(b, 2, p.Line)
+}
+
+var lineDecoder = []decoder{
+	nil, // 0
+	// optional uint64 function_id = 1
+	func(b *buffer, m message) error { return decodeUint64(b, &m.(*Line).functionIDX) },
+	// optional int64 line = 2
+	func(b *buffer, m message) error { return decodeInt64(b, &m.(*Line).Line) },
+}
+
+func (p *Function) decoder() []decoder {
+	return functionDecoder
+}
+
+func (p *Function) encode(b *buffer) {
+	encodeUint64Opt(b, 1, p.ID)
+	encodeInt64Opt(b, 2, p.nameX)
+	encodeInt64Opt(b, 3, p.systemNameX)
+	encodeInt64Opt(b, 4, p.filenameX)
+	encodeInt64Opt(b, 5, p.StartLine)
+}
+
+var functionDecoder = []decoder{
+	nil, // 0
+	// optional uint64 id = 1
+	func(b *buffer, m message) error { return decodeUint64(b, &m.(*Function).ID) },
+	// optional int64 function_name = 2
+	func(b *buffer, m message) error { return decodeInt64(b, &m.(*Function).nameX) },
+	// optional int64 function_system_name = 3
+	func(b *buffer, m message) error { return decodeInt64(b, &m.(*Function).systemNameX) },
+	// repeated int64 filename = 4
+	func(b *buffer, m message) error { return decodeInt64(b, &m.(*Function).filenameX) },
+	// optional int64 start_line = 5
+	func(b *buffer, m message) error { return decodeInt64(b, &m.(*Function).StartLine) },
+}
+
+func addString(strings map[string]int, s string) int64 {
+	i, ok := strings[s]
+	if !ok {
+		i = len(strings)
+		strings[s] = i
+	}
+	return int64(i)
+}
+
+func getString(strings []string, strng *int64, err error) (string, error) {
+	if err != nil {
+		return "", err
+	}
+	s := int(*strng)
+	if s < 0 || s >= len(strings) {
+		return "", errMalformed
+	}
+	*strng = 0
+	return strings[s], nil
+}
diff --git a/src/cmd/pprof/internal/profile/filter.go b/src/cmd/pprof/internal/profile/filter.go
new file mode 100644
index 0000000..903616a
--- /dev/null
+++ b/src/cmd/pprof/internal/profile/filter.go
@@ -0,0 +1,157 @@
+// 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.
+
+// Implements methods to filter samples from profiles.
+package profile
+
+import "regexp"
+
+// FilterSamplesByName filters the samples in a profile and only keeps
+// samples where at least one frame matches focus but none match ignore.
+// Returns true is the corresponding regexp matched at least one sample.
+func (p *Profile) FilterSamplesByName(focus, ignore, hide *regexp.Regexp) (fm, im, hm bool) {
+	focusOrIgnore := make(map[uint64]bool)
+	hidden := make(map[uint64]bool)
+	for _, l := range p.Location {
+		if ignore != nil && l.matchesName(ignore) {
+			im = true
+			focusOrIgnore[l.ID] = false
+		} else if focus == nil || l.matchesName(focus) {
+			fm = true
+			focusOrIgnore[l.ID] = true
+		}
+		if hide != nil && l.matchesName(hide) {
+			hm = true
+			l.Line = l.unmatchedLines(hide)
+			if len(l.Line) == 0 {
+				hidden[l.ID] = true
+			}
+		}
+	}
+
+	s := make([]*Sample, 0, len(p.Sample))
+	for _, sample := range p.Sample {
+		if focusedAndNotIgnored(sample.Location, focusOrIgnore) {
+			if len(hidden) > 0 {
+				var locs []*Location
+				for _, loc := range sample.Location {
+					if !hidden[loc.ID] {
+						locs = append(locs, loc)
+					}
+				}
+				if len(locs) == 0 {
+					// Remove sample with no locations (by not adding it to s).
+					continue
+				}
+				sample.Location = locs
+			}
+			s = append(s, sample)
+		}
+	}
+	p.Sample = s
+
+	return
+}
+
+// matchesName returns whether the function name or file in the
+// location matches the regular expression.
+func (loc *Location) matchesName(re *regexp.Regexp) bool {
+	for _, ln := range loc.Line {
+		if fn := ln.Function; fn != nil {
+			if re.MatchString(fn.Name) {
+				return true
+			}
+			if re.MatchString(fn.Filename) {
+				return true
+			}
+		}
+	}
+	return false
+}
+
+// unmatchedLines returns the lines in the location that do not match
+// the regular expression.
+func (loc *Location) unmatchedLines(re *regexp.Regexp) []Line {
+	var lines []Line
+	for _, ln := range loc.Line {
+		if fn := ln.Function; fn != nil {
+			if re.MatchString(fn.Name) {
+				continue
+			}
+			if re.MatchString(fn.Filename) {
+				continue
+			}
+		}
+		lines = append(lines, ln)
+	}
+	return lines
+}
+
+// focusedAndNotIgnored looks up a slice of ids against a map of
+// focused/ignored locations. The map only contains locations that are
+// explicitly focused or ignored. Returns whether there is at least
+// one focused location but no ignored locations.
+func focusedAndNotIgnored(locs []*Location, m map[uint64]bool) bool {
+	var f bool
+	for _, loc := range locs {
+		if focus, focusOrIgnore := m[loc.ID]; focusOrIgnore {
+			if focus {
+				// Found focused location. Must keep searching in case there
+				// is an ignored one as well.
+				f = true
+			} else {
+				// Found ignored location. Can return false right away.
+				return false
+			}
+		}
+	}
+	return f
+}
+
+// TagMatch selects tags for filtering
+type TagMatch func(key, val string, nval int64) bool
+
+// FilterSamplesByTag removes all samples from the profile, except
+// those that match focus and do not match the ignore regular
+// expression.
+func (p *Profile) FilterSamplesByTag(focus, ignore TagMatch) (fm, im bool) {
+	samples := make([]*Sample, 0, len(p.Sample))
+	for _, s := range p.Sample {
+		focused, ignored := focusedSample(s, focus, ignore)
+		fm = fm || focused
+		im = im || ignored
+		if focused && !ignored {
+			samples = append(samples, s)
+		}
+	}
+	p.Sample = samples
+	return
+}
+
+// focusedTag checks a sample against focus and ignore regexps.
+// Returns whether the focus/ignore regexps match any tags
+func focusedSample(s *Sample, focus, ignore TagMatch) (fm, im bool) {
+	fm = focus == nil
+	for key, vals := range s.Label {
+		for _, val := range vals {
+			if ignore != nil && ignore(key, val, 0) {
+				im = true
+			}
+			if !fm && focus(key, val, 0) {
+				fm = true
+			}
+		}
+	}
+	for key, vals := range s.NumLabel {
+		for _, val := range vals {
+			if ignore != nil && ignore(key, "", val) {
+				im = true
+			}
+			if !fm && focus(key, "", val) {
+				fm = true
+			}
+		}
+	}
+	return fm, im
+}
diff --git a/src/cmd/pprof/internal/profile/legacy_profile.go b/src/cmd/pprof/internal/profile/legacy_profile.go
new file mode 100644
index 0000000..bfc8110
--- /dev/null
+++ b/src/cmd/pprof/internal/profile/legacy_profile.go
@@ -0,0 +1,1250 @@
+// 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 file implements parsers to convert legacy profiles into the
+// profile.proto format.
+
+package profile
+
+import (
+	"bufio"
+	"bytes"
+	"fmt"
+	"io"
+	"math"
+	"regexp"
+	"strconv"
+	"strings"
+)
+
+var (
+	countStartRE = regexp.MustCompile(`\A(\w+) profile: total \d+\n\z`)
+	countRE      = regexp.MustCompile(`\A(\d+) @(( 0x[0-9a-f]+)+)\n\z`)
+
+	heapHeaderRE = regexp.MustCompile(`heap profile: *(\d+): *(\d+) *\[ *(\d+): *(\d+) *\] *@ *(heap[_a-z0-9]*)/?(\d*)`)
+	heapSampleRE = regexp.MustCompile(`(-?\d+): *(-?\d+) *\[ *(\d+): *(\d+) *] @([ x0-9a-f]*)`)
+
+	contentionSampleRE = regexp.MustCompile(`(\d+) *(\d+) @([ x0-9a-f]*)`)
+
+	hexNumberRE = regexp.MustCompile(`0x[0-9a-f]+`)
+
+	growthHeaderRE = regexp.MustCompile(`heap profile: *(\d+): *(\d+) *\[ *(\d+): *(\d+) *\] @ growthz`)
+
+	fragmentationHeaderRE = regexp.MustCompile(`heap profile: *(\d+): *(\d+) *\[ *(\d+): *(\d+) *\] @ fragmentationz`)
+
+	threadzStartRE = regexp.MustCompile(`--- threadz \d+ ---`)
+	threadStartRE  = regexp.MustCompile(`--- Thread ([[:xdigit:]]+) \(name: (.*)/(\d+)\) stack: ---`)
+
+	procMapsRE = regexp.MustCompile(`([[:xdigit:]]+)-([[:xdigit:]]+)\s+([-rwxp]+)\s+([[:xdigit:]]+)\s+([[:xdigit:]]+):([[:xdigit:]]+)\s+([[:digit:]]+)\s*(\S+)?`)
+
+	briefMapsRE = regexp.MustCompile(`\s*([[:xdigit:]]+)-([[:xdigit:]]+):\s*(\S+)(\s.*@)?([[:xdigit:]]+)?`)
+
+	// LegacyHeapAllocated instructs the heapz parsers to use the
+	// allocated memory stats instead of the default in-use memory. Note
+	// that tcmalloc doesn't provide all allocated memory, only in-use
+	// stats.
+	LegacyHeapAllocated bool
+)
+
+func isSpaceOrComment(line string) bool {
+	trimmed := strings.TrimSpace(line)
+	return len(trimmed) == 0 || trimmed[0] == '#'
+}
+
+// parseGoCount parses a Go count profile (e.g., threadcreate or
+// goroutine) and returns a new Profile.
+func parseGoCount(b []byte) (*Profile, error) {
+	r := bytes.NewBuffer(b)
+
+	var line string
+	var err error
+	for {
+		// Skip past comments and empty lines seeking a real header.
+		line, err = r.ReadString('\n')
+		if err != nil {
+			return nil, err
+		}
+		if !isSpaceOrComment(line) {
+			break
+		}
+	}
+
+	m := countStartRE.FindStringSubmatch(line)
+	if m == nil {
+		return nil, errUnrecognized
+	}
+	profileType := string(m[1])
+	p := &Profile{
+		PeriodType: &ValueType{Type: profileType, Unit: "count"},
+		Period:     1,
+		SampleType: []*ValueType{{Type: profileType, Unit: "count"}},
+	}
+	locations := make(map[uint64]*Location)
+	for {
+		line, err = r.ReadString('\n')
+		if err != nil {
+			if err == io.EOF {
+				break
+			}
+			return nil, err
+		}
+		if isSpaceOrComment(line) {
+			continue
+		}
+		if strings.HasPrefix(line, "---") {
+			break
+		}
+		m := countRE.FindStringSubmatch(line)
+		if m == nil {
+			return nil, errMalformed
+		}
+		n, err := strconv.ParseInt(string(m[1]), 0, 64)
+		if err != nil {
+			return nil, errMalformed
+		}
+		fields := strings.Fields(string(m[2]))
+		locs := make([]*Location, 0, len(fields))
+		for _, stk := range fields {
+			addr, err := strconv.ParseUint(stk, 0, 64)
+			if err != nil {
+				return nil, errMalformed
+			}
+			// Adjust all frames by -1 (except the leaf) to land on top of
+			// the call instruction.
+			if len(locs) > 0 {
+				addr--
+			}
+			loc := locations[addr]
+			if loc == nil {
+				loc = &Location{
+					Address: addr,
+				}
+				locations[addr] = loc
+				p.Location = append(p.Location, loc)
+			}
+			locs = append(locs, loc)
+		}
+		p.Sample = append(p.Sample, &Sample{
+			Location: locs,
+			Value:    []int64{n},
+		})
+	}
+
+	if err = parseAdditionalSections(strings.TrimSpace(line), r, p); err != nil {
+		return nil, err
+	}
+	return p, nil
+}
+
+// remapLocationIDs ensures there is a location for each address
+// referenced by a sample, and remaps the samples to point to the new
+// location ids.
+func (p *Profile) remapLocationIDs() {
+	seen := make(map[*Location]bool, len(p.Location))
+	var locs []*Location
+
+	for _, s := range p.Sample {
+		for _, l := range s.Location {
+			if seen[l] {
+				continue
+			}
+			l.ID = uint64(len(locs) + 1)
+			locs = append(locs, l)
+			seen[l] = true
+		}
+	}
+	p.Location = locs
+}
+
+func (p *Profile) remapFunctionIDs() {
+	seen := make(map[*Function]bool, len(p.Function))
+	var fns []*Function
+
+	for _, l := range p.Location {
+		for _, ln := range l.Line {
+			fn := ln.Function
+			if fn == nil || seen[fn] {
+				continue
+			}
+			fn.ID = uint64(len(fns) + 1)
+			fns = append(fns, fn)
+			seen[fn] = true
+		}
+	}
+	p.Function = fns
+}
+
+// remapMappingIDs matches location addresses with existing mappings
+// and updates them appropriately. This is O(N*M), if this ever shows
+// up as a bottleneck, evaluate sorting the mappings and doing a
+// binary search, which would make it O(N*log(M)).
+func (p *Profile) remapMappingIDs() {
+	if len(p.Mapping) == 0 {
+		return
+	}
+
+	// Some profile handlers will incorrectly set regions for the main
+	// executable if its section is remapped. Fix them through heuristics.
+
+	// Remove the initial mapping if named '/anon_hugepage' and has a
+	// consecutive adjacent mapping.
+	if m := p.Mapping[0]; strings.HasPrefix(m.File, "/anon_hugepage") {
+		if len(p.Mapping) > 1 && m.Limit == p.Mapping[1].Start {
+			p.Mapping = p.Mapping[1:]
+		}
+	}
+
+	// Subtract the offset from the start of the main mapping if it
+	// ends up at a recognizable start address.
+	const expectedStart = 0x400000
+	if m := p.Mapping[0]; m.Start-m.Offset == expectedStart {
+		m.Start = expectedStart
+		m.Offset = 0
+	}
+
+	for _, l := range p.Location {
+		if a := l.Address; a != 0 {
+			for _, m := range p.Mapping {
+				if m.Start <= a && a < m.Limit {
+					l.Mapping = m
+					break
+				}
+			}
+		}
+	}
+
+	// Reset all mapping IDs.
+	for i, m := range p.Mapping {
+		m.ID = uint64(i + 1)
+	}
+}
+
+var cpuInts = []func([]byte) (uint64, []byte){
+	get32l,
+	get32b,
+	get64l,
+	get64b,
+}
+
+func get32l(b []byte) (uint64, []byte) {
+	if len(b) < 4 {
+		return 0, nil
+	}
+	return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24, b[4:]
+}
+
+func get32b(b []byte) (uint64, []byte) {
+	if len(b) < 4 {
+		return 0, nil
+	}
+	return uint64(b[3]) | uint64(b[2])<<8 | uint64(b[1])<<16 | uint64(b[0])<<24, b[4:]
+}
+
+func get64l(b []byte) (uint64, []byte) {
+	if len(b) < 8 {
+		return 0, nil
+	}
+	return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56, b[8:]
+}
+
+func get64b(b []byte) (uint64, []byte) {
+	if len(b) < 8 {
+		return 0, nil
+	}
+	return uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 | uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56, b[8:]
+}
+
+// ParseTracebacks parses a set of tracebacks and returns a newly
+// populated profile. It will accept any text file and generate a
+// Profile out of it with any hex addresses it can identify, including
+// a process map if it can recognize one. Each sample will include a
+// tag "source" with the addresses recognized in string format.
+func ParseTracebacks(b []byte) (*Profile, error) {
+	r := bytes.NewBuffer(b)
+
+	p := &Profile{
+		PeriodType: &ValueType{Type: "trace", Unit: "count"},
+		Period:     1,
+		SampleType: []*ValueType{
+			{Type: "trace", Unit: "count"},
+		},
+	}
+
+	var sources []string
+	var sloc []*Location
+
+	locs := make(map[uint64]*Location)
+	for {
+		l, err := r.ReadString('\n')
+		if err != nil {
+			if err != io.EOF {
+				return nil, err
+			}
+			if l == "" {
+				break
+			}
+		}
+		if sectionTrigger(l) == memoryMapSection {
+			break
+		}
+		if s, addrs := extractHexAddresses(l); len(s) > 0 {
+			for _, addr := range addrs {
+				// Addresses from stack traces point to the next instruction after
+				// each call.  Adjust by -1 to land somewhere on the actual call
+				// (except for the leaf, which is not a call).
+				if len(sloc) > 0 {
+					addr--
+				}
+				loc := locs[addr]
+				if locs[addr] == nil {
+					loc = &Location{
+						Address: addr,
+					}
+					p.Location = append(p.Location, loc)
+					locs[addr] = loc
+				}
+				sloc = append(sloc, loc)
+			}
+
+			sources = append(sources, s...)
+		} else {
+			if len(sources) > 0 || len(sloc) > 0 {
+				addTracebackSample(sloc, sources, p)
+				sloc, sources = nil, nil
+			}
+		}
+	}
+
+	// Add final sample to save any leftover data.
+	if len(sources) > 0 || len(sloc) > 0 {
+		addTracebackSample(sloc, sources, p)
+	}
+
+	if err := p.ParseMemoryMap(r); err != nil {
+		return nil, err
+	}
+	return p, nil
+}
+
+func addTracebackSample(l []*Location, s []string, p *Profile) {
+	p.Sample = append(p.Sample,
+		&Sample{
+			Value:    []int64{1},
+			Location: l,
+			Label:    map[string][]string{"source": s},
+		})
+}
+
+// parseCPU parses a profilez legacy profile and returns a newly
+// populated Profile.
+//
+// The general format for profilez samples is a sequence of words in
+// binary format. The first words are a header with the following data:
+//   1st word -- 0
+//   2nd word -- 3
+//   3rd word -- 0 if a c++ application, 1 if a java application.
+//   4th word -- Sampling period (in microseconds).
+//   5th word -- Padding.
+func parseCPU(b []byte) (*Profile, error) {
+	var parse func([]byte) (uint64, []byte)
+	var n1, n2, n3, n4, n5 uint64
+	for _, parse = range cpuInts {
+		var tmp []byte
+		n1, tmp = parse(b)
+		n2, tmp = parse(tmp)
+		n3, tmp = parse(tmp)
+		n4, tmp = parse(tmp)
+		n5, tmp = parse(tmp)
+
+		if tmp != nil && n1 == 0 && n2 == 3 && n3 == 0 && n4 > 0 && n5 == 0 {
+			b = tmp
+			return cpuProfile(b, int64(n4), parse)
+		}
+	}
+	return nil, errUnrecognized
+}
+
+// cpuProfile returns a new Profile from C++ profilez data.
+// b is the profile bytes after the header, period is the profiling
+// period, and parse is a function to parse 8-byte chunks from the
+// profile in its native endianness.
+func cpuProfile(b []byte, period int64, parse func(b []byte) (uint64, []byte)) (*Profile, error) {
+	p := &Profile{
+		Period:     period * 1000,
+		PeriodType: &ValueType{Type: "cpu", Unit: "nanoseconds"},
+		SampleType: []*ValueType{
+			{Type: "samples", Unit: "count"},
+			{Type: "cpu", Unit: "nanoseconds"},
+		},
+	}
+	var err error
+	if b, _, err = parseCPUSamples(b, parse, true, p); err != nil {
+		return nil, err
+	}
+
+	// If all samples have the same second-to-the-bottom frame, it
+	// strongly suggests that it is an uninteresting artifact of
+	// measurement -- a stack frame pushed by the signal handler. The
+	// bottom frame is always correct as it is picked up from the signal
+	// structure, not the stack. Check if this is the case and if so,
+	// remove.
+	if len(p.Sample) > 1 && len(p.Sample[0].Location) > 1 {
+		allSame := true
+		id1 := p.Sample[0].Location[1].Address
+		for _, s := range p.Sample {
+			if len(s.Location) < 2 || id1 != s.Location[1].Address {
+				allSame = false
+				break
+			}
+		}
+		if allSame {
+			for _, s := range p.Sample {
+				s.Location = append(s.Location[:1], s.Location[2:]...)
+			}
+		}
+	}
+
+	if err := p.ParseMemoryMap(bytes.NewBuffer(b)); err != nil {
+		return nil, err
+	}
+	return p, nil
+}
+
+// parseCPUSamples parses a collection of profilez samples from a
+// profile.
+//
+// profilez samples are a repeated sequence of stack frames of the
+// form:
+//    1st word -- The number of times this stack was encountered.
+//    2nd word -- The size of the stack (StackSize).
+//    3rd word -- The first address on the stack.
+//    ...
+//    StackSize + 2 -- The last address on the stack
+// The last stack trace is of the form:
+//   1st word -- 0
+//   2nd word -- 1
+//   3rd word -- 0
+//
+// Addresses from stack traces may point to the next instruction after
+// each call.  Optionally adjust by -1 to land somewhere on the actual
+// call (except for the leaf, which is not a call).
+func parseCPUSamples(b []byte, parse func(b []byte) (uint64, []byte), adjust bool, p *Profile) ([]byte, map[uint64]*Location, error) {
+	locs := make(map[uint64]*Location)
+	for len(b) > 0 {
+		var count, nstk uint64
+		count, b = parse(b)
+		nstk, b = parse(b)
+		if b == nil || nstk > uint64(len(b)/4) {
+			return nil, nil, errUnrecognized
+		}
+		var sloc []*Location
+		addrs := make([]uint64, nstk)
+		for i := 0; i < int(nstk); i++ {
+			addrs[i], b = parse(b)
+		}
+
+		if count == 0 && nstk == 1 && addrs[0] == 0 {
+			// End of data marker
+			break
+		}
+		for i, addr := range addrs {
+			if adjust && i > 0 {
+				addr--
+			}
+			loc := locs[addr]
+			if loc == nil {
+				loc = &Location{
+					Address: addr,
+				}
+				locs[addr] = loc
+				p.Location = append(p.Location, loc)
+			}
+			sloc = append(sloc, loc)
+		}
+		p.Sample = append(p.Sample,
+			&Sample{
+				Value:    []int64{int64(count), int64(count) * int64(p.Period)},
+				Location: sloc,
+			})
+	}
+	// Reached the end without finding the EOD marker.
+	return b, locs, nil
+}
+
+// parseHeap parses a heapz legacy or a growthz profile and
+// returns a newly populated Profile.
+func parseHeap(b []byte) (p *Profile, err error) {
+	r := bytes.NewBuffer(b)
+	l, err := r.ReadString('\n')
+	if err != nil {
+		return nil, errUnrecognized
+	}
+
+	sampling := ""
+
+	if header := heapHeaderRE.FindStringSubmatch(l); header != nil {
+		p = &Profile{
+			SampleType: []*ValueType{
+				{Type: "objects", Unit: "count"},
+				{Type: "space", Unit: "bytes"},
+			},
+			PeriodType: &ValueType{Type: "objects", Unit: "bytes"},
+		}
+
+		var period int64
+		if len(header[6]) > 0 {
+			if period, err = strconv.ParseInt(string(header[6]), 10, 64); err != nil {
+				return nil, errUnrecognized
+			}
+		}
+
+		switch header[5] {
+		case "heapz_v2", "heap_v2":
+			sampling, p.Period = "v2", period
+		case "heapprofile":
+			sampling, p.Period = "", 1
+		case "heap":
+			sampling, p.Period = "v2", period/2
+		default:
+			return nil, errUnrecognized
+		}
+	} else if header = growthHeaderRE.FindStringSubmatch(l); header != nil {
+		p = &Profile{
+			SampleType: []*ValueType{
+				{Type: "objects", Unit: "count"},
+				{Type: "space", Unit: "bytes"},
+			},
+			PeriodType: &ValueType{Type: "heapgrowth", Unit: "count"},
+			Period:     1,
+		}
+	} else if header = fragmentationHeaderRE.FindStringSubmatch(l); header != nil {
+		p = &Profile{
+			SampleType: []*ValueType{
+				{Type: "objects", Unit: "count"},
+				{Type: "space", Unit: "bytes"},
+			},
+			PeriodType: &ValueType{Type: "allocations", Unit: "count"},
+			Period:     1,
+		}
+	} else {
+		return nil, errUnrecognized
+	}
+
+	if LegacyHeapAllocated {
+		for _, st := range p.SampleType {
+			st.Type = "alloc_" + st.Type
+		}
+	} else {
+		for _, st := range p.SampleType {
+			st.Type = "inuse_" + st.Type
+		}
+	}
+
+	locs := make(map[uint64]*Location)
+	for {
+		l, err = r.ReadString('\n')
+		if err != nil {
+			if err != io.EOF {
+				return nil, err
+			}
+
+			if l == "" {
+				break
+			}
+		}
+
+		if l = strings.TrimSpace(l); l == "" {
+			continue
+		}
+
+		if sectionTrigger(l) != unrecognizedSection {
+			break
+		}
+
+		value, blocksize, addrs, err := parseHeapSample(l, p.Period, sampling)
+		if err != nil {
+			return nil, err
+		}
+		var sloc []*Location
+		for i, addr := range addrs {
+			// Addresses from stack traces point to the next instruction after
+			// each call.  Adjust by -1 to land somewhere on the actual call
+			// (except for the leaf, which is not a call).
+			if i > 0 {
+				addr--
+			}
+			loc := locs[addr]
+			if locs[addr] == nil {
+				loc = &Location{
+					Address: addr,
+				}
+				p.Location = append(p.Location, loc)
+				locs[addr] = loc
+			}
+			sloc = append(sloc, loc)
+		}
+
+		p.Sample = append(p.Sample, &Sample{
+			Value:    value,
+			Location: sloc,
+			NumLabel: map[string][]int64{"bytes": []int64{blocksize}},
+		})
+	}
+
+	if err = parseAdditionalSections(l, r, p); err != nil {
+		return nil, err
+	}
+	return p, nil
+}
+
+// parseHeapSample parses a single row from a heap profile into a new Sample.
+func parseHeapSample(line string, rate int64, sampling string) (value []int64, blocksize int64, addrs []uint64, err error) {
+	sampleData := heapSampleRE.FindStringSubmatch(line)
+	if len(sampleData) != 6 {
+		return value, blocksize, addrs, fmt.Errorf("unexpected number of sample values: got %d, want 6", len(sampleData))
+	}
+
+	// Use first two values by default; tcmalloc sampling generates the
+	// same value for both, only the older heap-profile collect separate
+	// stats for in-use and allocated objects.
+	valueIndex := 1
+	if LegacyHeapAllocated {
+		valueIndex = 3
+	}
+
+	var v1, v2 int64
+	if v1, err = strconv.ParseInt(sampleData[valueIndex], 10, 64); err != nil {
+		return value, blocksize, addrs, fmt.Errorf("malformed sample: %s: %v", line, err)
+	}
+	if v2, err = strconv.ParseInt(sampleData[valueIndex+1], 10, 64); err != nil {
+		return value, blocksize, addrs, fmt.Errorf("malformed sample: %s: %v", line, err)
+	}
+
+	if v1 == 0 {
+		if v2 != 0 {
+			return value, blocksize, addrs, fmt.Errorf("allocation count was 0 but allocation bytes was %d", v2)
+		}
+	} else {
+		blocksize = v2 / v1
+		if sampling == "v2" {
+			v1, v2 = scaleHeapSample(v1, v2, rate)
+		}
+	}
+
+	value = []int64{v1, v2}
+	addrs = parseHexAddresses(sampleData[5])
+
+	return value, blocksize, addrs, nil
+}
+
+// extractHexAddresses extracts hex numbers from a string and returns
+// them, together with their numeric value, in a slice.
+func extractHexAddresses(s string) ([]string, []uint64) {
+	hexStrings := hexNumberRE.FindAllString(s, -1)
+	var ids []uint64
+	for _, s := range hexStrings {
+		if id, err := strconv.ParseUint(s, 0, 64); err == nil {
+			ids = append(ids, id)
+		} else {
+			// Do not expect any parsing failures due to the regexp matching.
+			panic("failed to parse hex value:" + s)
+		}
+	}
+	return hexStrings, ids
+}
+
+// parseHexAddresses parses hex numbers from a string and returns them
+// in a slice.
+func parseHexAddresses(s string) []uint64 {
+	_, ids := extractHexAddresses(s)
+	return ids
+}
+
+// scaleHeapSample adjusts the data from a heapz Sample to
+// account for its probability of appearing in the collected
+// data. heapz profiles are a sampling of the memory allocations
+// requests in a program. We estimate the unsampled value by dividing
+// each collected sample by its probability of appearing in the
+// profile. heapz v2 profiles rely on a poisson process to determine
+// which samples to collect, based on the desired average collection
+// rate R. The probability of a sample of size S to appear in that
+// profile is 1-exp(-S/R).
+func scaleHeapSample(count, size, rate int64) (int64, int64) {
+	if count == 0 || size == 0 {
+		return 0, 0
+	}
+
+	if rate <= 1 {
+		// if rate==1 all samples were collected so no adjustment is needed.
+		// if rate<1 treat as unknown and skip scaling.
+		return count, size
+	}
+
+	avgSize := float64(size) / float64(count)
+	scale := 1 / (1 - math.Exp(-avgSize/float64(rate)))
+
+	return int64(float64(count) * scale), int64(float64(size) * scale)
+}
+
+// parseContention parses a contentionz profile and returns a newly
+// populated Profile.
+func parseContention(b []byte) (p *Profile, err error) {
+	r := bytes.NewBuffer(b)
+	l, err := r.ReadString('\n')
+	if err != nil {
+		return nil, errUnrecognized
+	}
+
+	if !strings.HasPrefix(l, "--- contention") {
+		return nil, errUnrecognized
+	}
+
+	p = &Profile{
+		PeriodType: &ValueType{Type: "contentions", Unit: "count"},
+		Period:     1,
+		SampleType: []*ValueType{
+			{Type: "contentions", Unit: "count"},
+			{Type: "delay", Unit: "nanoseconds"},
+		},
+	}
+
+	var cpuHz int64
+	// Parse text of the form "attribute = value" before the samples.
+	const delimiter = "="
+	for {
+		l, err = r.ReadString('\n')
+		if err != nil {
+			if err != io.EOF {
+				return nil, err
+			}
+
+			if l == "" {
+				break
+			}
+		}
+
+		if l = strings.TrimSpace(l); l == "" {
+			continue
+		}
+
+		if strings.HasPrefix(l, "---") {
+			break
+		}
+
+		attr := strings.SplitN(l, delimiter, 2)
+		if len(attr) != 2 {
+			break
+		}
+		key, val := strings.TrimSpace(attr[0]), strings.TrimSpace(attr[1])
+		var err error
+		switch key {
+		case "cycles/second":
+			if cpuHz, err = strconv.ParseInt(val, 0, 64); err != nil {
+				return nil, errUnrecognized
+			}
+		case "sampling period":
+			if p.Period, err = strconv.ParseInt(val, 0, 64); err != nil {
+				return nil, errUnrecognized
+			}
+		case "ms since reset":
+			ms, err := strconv.ParseInt(val, 0, 64)
+			if err != nil {
+				return nil, errUnrecognized
+			}
+			p.DurationNanos = ms * 1000 * 1000
+		case "format":
+			// CPP contentionz profiles don't have format.
+			return nil, errUnrecognized
+		case "resolution":
+			// CPP contentionz profiles don't have resolution.
+			return nil, errUnrecognized
+		case "discarded samples":
+		default:
+			return nil, errUnrecognized
+		}
+	}
+
+	locs := make(map[uint64]*Location)
+	for {
+		if l = strings.TrimSpace(l); strings.HasPrefix(l, "---") {
+			break
+		}
+		value, addrs, err := parseContentionSample(l, p.Period, cpuHz)
+		if err != nil {
+			return nil, err
+		}
+		var sloc []*Location
+		for i, addr := range addrs {
+			// Addresses from stack traces point to the next instruction after
+			// each call.  Adjust by -1 to land somewhere on the actual call
+			// (except for the leaf, which is not a call).
+			if i > 0 {
+				addr--
+			}
+			loc := locs[addr]
+			if locs[addr] == nil {
+				loc = &Location{
+					Address: addr,
+				}
+				p.Location = append(p.Location, loc)
+				locs[addr] = loc
+			}
+			sloc = append(sloc, loc)
+		}
+		p.Sample = append(p.Sample, &Sample{
+			Value:    value,
+			Location: sloc,
+		})
+
+		if l, err = r.ReadString('\n'); err != nil {
+			if err != io.EOF {
+				return nil, err
+			}
+			if l == "" {
+				break
+			}
+		}
+	}
+
+	if err = parseAdditionalSections(l, r, p); err != nil {
+		return nil, err
+	}
+
+	return p, nil
+}
+
+// parseContentionSample parses a single row from a contention profile
+// into a new Sample.
+func parseContentionSample(line string, period, cpuHz int64) (value []int64, addrs []uint64, err error) {
+	sampleData := contentionSampleRE.FindStringSubmatch(line)
+	if sampleData == nil {
+		return value, addrs, errUnrecognized
+	}
+
+	v1, err := strconv.ParseInt(sampleData[1], 10, 64)
+	if err != nil {
+		return value, addrs, fmt.Errorf("malformed sample: %s: %v", line, err)
+	}
+	v2, err := strconv.ParseInt(sampleData[2], 10, 64)
+	if err != nil {
+		return value, addrs, fmt.Errorf("malformed sample: %s: %v", line, err)
+	}
+
+	// Unsample values if period and cpuHz are available.
+	// - Delays are scaled to cycles and then to nanoseconds.
+	// - Contentions are scaled to cycles.
+	if period > 0 {
+		if cpuHz > 0 {
+			cpuGHz := float64(cpuHz) / 1e9
+			v1 = int64(float64(v1) * float64(period) / cpuGHz)
+		}
+		v2 = v2 * period
+	}
+
+	value = []int64{v2, v1}
+	addrs = parseHexAddresses(sampleData[3])
+
+	return value, addrs, nil
+}
+
+// parseThread parses a Threadz profile and returns a new Profile.
+func parseThread(b []byte) (*Profile, error) {
+	r := bytes.NewBuffer(b)
+
+	var line string
+	var err error
+	for {
+		// Skip past comments and empty lines seeking a real header.
+		line, err = r.ReadString('\n')
+		if err != nil {
+			return nil, err
+		}
+		if !isSpaceOrComment(line) {
+			break
+		}
+	}
+
+	if m := threadzStartRE.FindStringSubmatch(line); m != nil {
+		// Advance over initial comments until first stack trace.
+		for {
+			line, err = r.ReadString('\n')
+			if err != nil {
+				if err != io.EOF {
+					return nil, err
+				}
+
+				if line == "" {
+					break
+				}
+			}
+			if sectionTrigger(line) != unrecognizedSection || line[0] == '-' {
+				break
+			}
+		}
+	} else if t := threadStartRE.FindStringSubmatch(line); len(t) != 4 {
+		return nil, errUnrecognized
+	}
+
+	p := &Profile{
+		SampleType: []*ValueType{{Type: "thread", Unit: "count"}},
+		PeriodType: &ValueType{Type: "thread", Unit: "count"},
+		Period:     1,
+	}
+
+	locs := make(map[uint64]*Location)
+	// Recognize each thread and populate profile samples.
+	for sectionTrigger(line) == unrecognizedSection {
+		if strings.HasPrefix(line, "---- no stack trace for") {
+			line = ""
+			break
+		}
+		if t := threadStartRE.FindStringSubmatch(line); len(t) != 4 {
+			return nil, errUnrecognized
+		}
+
+		var addrs []uint64
+		line, addrs, err = parseThreadSample(r)
+		if err != nil {
+			return nil, errUnrecognized
+		}
+		if len(addrs) == 0 {
+			// We got a --same as previous threads--. Bump counters.
+			if len(p.Sample) > 0 {
+				s := p.Sample[len(p.Sample)-1]
+				s.Value[0]++
+			}
+			continue
+		}
+
+		var sloc []*Location
+		for i, addr := range addrs {
+			// Addresses from stack traces point to the next instruction after
+			// each call.  Adjust by -1 to land somewhere on the actual call
+			// (except for the leaf, which is not a call).
+			if i > 0 {
+				addr--
+			}
+			loc := locs[addr]
+			if locs[addr] == nil {
+				loc = &Location{
+					Address: addr,
+				}
+				p.Location = append(p.Location, loc)
+				locs[addr] = loc
+			}
+			sloc = append(sloc, loc)
+		}
+
+		p.Sample = append(p.Sample, &Sample{
+			Value:    []int64{1},
+			Location: sloc,
+		})
+	}
+
+	if err = parseAdditionalSections(line, r, p); err != nil {
+		return nil, err
+	}
+
+	return p, nil
+}
+
+// parseThreadSample parses a symbolized or unsymbolized stack trace.
+// Returns the first line after the traceback, the sample (or nil if
+// it hits a 'same-as-previous' marker) and an error.
+func parseThreadSample(b *bytes.Buffer) (nextl string, addrs []uint64, err error) {
+	var l string
+	sameAsPrevious := false
+	for {
+		if l, err = b.ReadString('\n'); err != nil {
+			if err != io.EOF {
+				return "", nil, err
+			}
+			if l == "" {
+				break
+			}
+		}
+		if l = strings.TrimSpace(l); l == "" {
+			continue
+		}
+
+		if strings.HasPrefix(l, "---") {
+			break
+		}
+		if strings.Contains(l, "same as previous thread") {
+			sameAsPrevious = true
+			continue
+		}
+
+		addrs = append(addrs, parseHexAddresses(l)...)
+	}
+
+	if sameAsPrevious {
+		return l, nil, nil
+	}
+	return l, addrs, nil
+}
+
+// parseAdditionalSections parses any additional sections in the
+// profile, ignoring any unrecognized sections.
+func parseAdditionalSections(l string, b *bytes.Buffer, p *Profile) (err error) {
+	for {
+		if sectionTrigger(l) == memoryMapSection {
+			break
+		}
+		// Ignore any unrecognized sections.
+		if l, err := b.ReadString('\n'); err != nil {
+			if err != io.EOF {
+				return err
+			}
+			if l == "" {
+				break
+			}
+		}
+	}
+	return p.ParseMemoryMap(b)
+}
+
+// ParseMemoryMap parses a memory map in the format of
+// /proc/self/maps, and overrides the mappings in the current profile.
+// It renumbers the samples and locations in the profile correspondingly.
+func (p *Profile) ParseMemoryMap(rd io.Reader) error {
+	b := bufio.NewReader(rd)
+
+	var attrs []string
+	var r *strings.Replacer
+	const delimiter = "="
+	for {
+		l, err := b.ReadString('\n')
+		if err != nil {
+			if err != io.EOF {
+				return err
+			}
+			if l == "" {
+				break
+			}
+		}
+		if l = strings.TrimSpace(l); l == "" {
+			continue
+		}
+
+		if r != nil {
+			l = r.Replace(l)
+		}
+		m, err := parseMappingEntry(l)
+		if err != nil {
+			if err == errUnrecognized {
+				// Recognize assignments of the form: attr=value, and replace
+				// $attr with value on subsequent mappings.
+				if attr := strings.SplitN(l, delimiter, 2); len(attr) == 2 {
+					attrs = append(attrs, "$"+strings.TrimSpace(attr[0]), strings.TrimSpace(attr[1]))
+					r = strings.NewReplacer(attrs...)
+				}
+				// Ignore any unrecognized entries
+				continue
+			}
+			return err
+		}
+		if m == nil || (m.File == "" && len(p.Mapping) != 0) {
+			// In some cases the first entry may include the address range
+			// but not the name of the file. It should be followed by
+			// another entry with the name.
+			continue
+		}
+		if len(p.Mapping) == 1 && p.Mapping[0].File == "" {
+			// Update the name if this is the entry following that empty one.
+			p.Mapping[0].File = m.File
+			continue
+		}
+		p.Mapping = append(p.Mapping, m)
+	}
+	p.remapLocationIDs()
+	p.remapFunctionIDs()
+	p.remapMappingIDs()
+	return nil
+}
+
+func parseMappingEntry(l string) (*Mapping, error) {
+	mapping := &Mapping{}
+	var err error
+	if me := procMapsRE.FindStringSubmatch(l); len(me) == 9 {
+		if !strings.Contains(me[3], "x") {
+			// Skip non-executable entries.
+			return nil, nil
+		}
+		if mapping.Start, err = strconv.ParseUint(me[1], 16, 64); err != nil {
+			return nil, errUnrecognized
+		}
+		if mapping.Limit, err = strconv.ParseUint(me[2], 16, 64); err != nil {
+			return nil, errUnrecognized
+		}
+		if me[4] != "" {
+			if mapping.Offset, err = strconv.ParseUint(me[4], 16, 64); err != nil {
+				return nil, errUnrecognized
+			}
+		}
+		mapping.File = me[8]
+		return mapping, nil
+	}
+
+	if me := briefMapsRE.FindStringSubmatch(l); len(me) == 6 {
+		if mapping.Start, err = strconv.ParseUint(me[1], 16, 64); err != nil {
+			return nil, errUnrecognized
+		}
+		if mapping.Limit, err = strconv.ParseUint(me[2], 16, 64); err != nil {
+			return nil, errUnrecognized
+		}
+		mapping.File = me[3]
+		if me[5] != "" {
+			if mapping.Offset, err = strconv.ParseUint(me[5], 16, 64); err != nil {
+				return nil, errUnrecognized
+			}
+		}
+		return mapping, nil
+	}
+
+	return nil, errUnrecognized
+}
+
+type sectionType int
+
+const (
+	unrecognizedSection sectionType = iota
+	memoryMapSection
+)
+
+var memoryMapTriggers = []string{
+	"--- Memory map: ---",
+	"MAPPED_LIBRARIES:",
+}
+
+func sectionTrigger(line string) sectionType {
+	for _, trigger := range memoryMapTriggers {
+		if strings.Contains(line, trigger) {
+			return memoryMapSection
+		}
+	}
+	return unrecognizedSection
+}
+
+func (p *Profile) addLegacyFrameInfo() {
+	switch {
+	case isProfileType(p, heapzSampleTypes) ||
+		isProfileType(p, heapzInUseSampleTypes) ||
+		isProfileType(p, heapzAllocSampleTypes):
+		p.DropFrames, p.KeepFrames = allocRxStr, allocSkipRxStr
+	case isProfileType(p, contentionzSampleTypes):
+		p.DropFrames, p.KeepFrames = lockRxStr, ""
+	default:
+		p.DropFrames, p.KeepFrames = cpuProfilerRxStr, ""
+	}
+}
+
+var heapzSampleTypes = []string{"allocations", "size"} // early Go pprof profiles
+var heapzInUseSampleTypes = []string{"inuse_objects", "inuse_space"}
+var heapzAllocSampleTypes = []string{"alloc_objects", "alloc_space"}
+var contentionzSampleTypes = []string{"contentions", "delay"}
+
+func isProfileType(p *Profile, t []string) bool {
+	st := p.SampleType
+	if len(st) != len(t) {
+		return false
+	}
+
+	for i := range st {
+		if st[i].Type != t[i] {
+			return false
+		}
+	}
+	return true
+}
+
+var allocRxStr = strings.Join([]string{
+	// POSIX entry points.
+	`calloc`,
+	`cfree`,
+	`malloc`,
+	`free`,
+	`memalign`,
+	`do_memalign`,
+	`(__)?posix_memalign`,
+	`pvalloc`,
+	`valloc`,
+	`realloc`,
+
+	// TC malloc.
+	`tcmalloc::.*`,
+	`tc_calloc`,
+	`tc_cfree`,
+	`tc_malloc`,
+	`tc_free`,
+	`tc_memalign`,
+	`tc_posix_memalign`,
+	`tc_pvalloc`,
+	`tc_valloc`,
+	`tc_realloc`,
+	`tc_new`,
+	`tc_delete`,
+	`tc_newarray`,
+	`tc_deletearray`,
+	`tc_new_nothrow`,
+	`tc_newarray_nothrow`,
+
+	// Memory-allocation routines on OS X.
+	`malloc_zone_malloc`,
+	`malloc_zone_calloc`,
+	`malloc_zone_valloc`,
+	`malloc_zone_realloc`,
+	`malloc_zone_memalign`,
+	`malloc_zone_free`,
+
+	// Go runtime
+	`runtime\..*`,
+
+	// Other misc. memory allocation routines
+	`BaseArena::.*`,
+	`(::)?do_malloc_no_errno`,
+	`(::)?do_malloc_pages`,
+	`(::)?do_malloc`,
+	`DoSampledAllocation`,
+	`MallocedMemBlock::MallocedMemBlock`,
+	`_M_allocate`,
+	`__builtin_(vec_)?delete`,
+	`__builtin_(vec_)?new`,
+	`__gnu_cxx::new_allocator::allocate`,
+	`__libc_malloc`,
+	`__malloc_alloc_template::allocate`,
+	`allocate`,
+	`cpp_alloc`,
+	`operator new(\[\])?`,
+	`simple_alloc::allocate`,
+}, `|`)
+
+var allocSkipRxStr = strings.Join([]string{
+	// Preserve Go runtime frames that appear in the middle/bottom of
+	// the stack.
+	`runtime\.panic`,
+}, `|`)
+
+var cpuProfilerRxStr = strings.Join([]string{
+	`ProfileData::Add`,
+	`ProfileData::prof_handler`,
+	`CpuProfiler::prof_handler`,
+	`__pthread_sighandler`,
+	`__restore`,
+}, `|`)
+
+var lockRxStr = strings.Join([]string{
+	`RecordLockProfileData`,
+	`(base::)?RecordLockProfileData.*`,
+	`(base::)?SubmitMutexProfileData.*`,
+	`(base::)?SubmitSpinLockProfileData.*`,
+	`(Mutex::)?AwaitCommon.*`,
+	`(Mutex::)?Unlock.*`,
+	`(Mutex::)?UnlockSlow.*`,
+	`(Mutex::)?ReaderUnlock.*`,
+	`(MutexLock::)?~MutexLock.*`,
+	`(SpinLock::)?Unlock.*`,
+	`(SpinLock::)?SlowUnlock.*`,
+	`(SpinLockHolder::)?~SpinLockHolder.*`,
+}, `|`)
diff --git a/src/cmd/pprof/internal/profile/profile.go b/src/cmd/pprof/internal/profile/profile.go
new file mode 100644
index 0000000..7ee58ee
--- /dev/null
+++ b/src/cmd/pprof/internal/profile/profile.go
@@ -0,0 +1,567 @@
+// 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 profile provides a representation of profile.proto and
+// methods to encode/decode profiles in this format.
+package profile
+
+import (
+	"bytes"
+	"compress/gzip"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"regexp"
+	"strings"
+	"time"
+)
+
+// Profile is an in-memory representation of profile.proto.
+type Profile struct {
+	SampleType []*ValueType
+	Sample     []*Sample
+	Mapping    []*Mapping
+	Location   []*Location
+	Function   []*Function
+
+	DropFrames string
+	KeepFrames string
+
+	TimeNanos     int64
+	DurationNanos int64
+	PeriodType    *ValueType
+	Period        int64
+
+	dropFramesX int64
+	keepFramesX int64
+	stringTable []string
+}
+
+// ValueType corresponds to Profile.ValueType
+type ValueType struct {
+	Type string // cpu, wall, inuse_space, etc
+	Unit string // seconds, nanoseconds, bytes, etc
+
+	typeX int64
+	unitX int64
+}
+
+// Sample corresponds to Profile.Sample
+type Sample struct {
+	Location []*Location
+	Value    []int64
+	Label    map[string][]string
+	NumLabel map[string][]int64
+
+	locationIDX []uint64
+	labelX      []Label
+}
+
+// Label corresponds to Profile.Label
+type Label struct {
+	keyX int64
+	// Exactly one of the two following values must be set
+	strX int64
+	numX int64 // Integer value for this label
+}
+
+// Mapping corresponds to Profile.Mapping
+type Mapping struct {
+	ID              uint64
+	Start           uint64
+	Limit           uint64
+	Offset          uint64
+	File            string
+	BuildID         string
+	HasFunctions    bool
+	HasFilenames    bool
+	HasLineNumbers  bool
+	HasInlineFrames bool
+
+	fileX    int64
+	buildIDX int64
+}
+
+// Location corresponds to Profile.Location
+type Location struct {
+	ID      uint64
+	Mapping *Mapping
+	Address uint64
+	Line    []Line
+
+	mappingIDX uint64
+}
+
+// Line corresponds to Profile.Line
+type Line struct {
+	Function *Function
+	Line     int64
+
+	functionIDX uint64
+}
+
+// Function corresponds to Profile.Function
+type Function struct {
+	ID         uint64
+	Name       string
+	SystemName string
+	Filename   string
+	StartLine  int64
+
+	nameX       int64
+	systemNameX int64
+	filenameX   int64
+}
+
+// Parse parses a profile and checks for its validity.  The input
+// may be a gzip-compressed encoded protobuf or one of many legacy
+// profile formats which may be unsupported in the future.
+func Parse(r io.Reader) (*Profile, error) {
+	orig, err := ioutil.ReadAll(r)
+	if err != nil {
+		return nil, err
+	}
+
+	var p *Profile
+	if len(orig) >= 2 && orig[0] == 0x1f && orig[1] == 0x8b {
+		var data []byte
+
+		if gz, err := gzip.NewReader(bytes.NewBuffer(orig)); err == nil {
+			data, err = ioutil.ReadAll(gz)
+		}
+		if err != nil {
+			return nil, fmt.Errorf("decompressing profile: %v", err)
+		}
+		orig = data
+	}
+	if p, err = parseUncompressed(orig); err != nil {
+		if p, err = parseLegacy(orig); err != nil {
+			return nil, fmt.Errorf("parsing profile: %v", err)
+		}
+	}
+
+	if err := p.CheckValid(); err != nil {
+		return nil, fmt.Errorf("malformed profile: %v", err)
+	}
+	return p, nil
+}
+
+var errUnrecognized = fmt.Errorf("unrecognized profile format")
+var errMalformed = fmt.Errorf("malformed profile format")
+
+func parseLegacy(data []byte) (*Profile, error) {
+	parsers := []func([]byte) (*Profile, error){
+		parseCPU,
+		parseHeap,
+		parseGoCount, // goroutine, threadcreate
+		parseThread,
+		parseContention,
+	}
+
+	for _, parser := range parsers {
+		p, err := parser(data)
+		if err == nil {
+			p.setMain()
+			p.addLegacyFrameInfo()
+			return p, nil
+		}
+		if err != errUnrecognized {
+			return nil, err
+		}
+	}
+	return nil, errUnrecognized
+}
+
+func parseUncompressed(data []byte) (*Profile, error) {
+	p := &Profile{}
+	if err := unmarshal(data, p); err != nil {
+		return nil, err
+	}
+
+	if err := p.postDecode(); err != nil {
+		return nil, err
+	}
+
+	return p, nil
+}
+
+var libRx = regexp.MustCompile(`([.]so$|[.]so[._][0-9]+)`)
+
+// setMain scans Mapping entries and guesses which entry is main
+// because legacy profiles don't obey the convention of putting main
+// first.
+func (p *Profile) setMain() {
+	for i := 0; i < len(p.Mapping); i++ {
+		file := strings.TrimSpace(strings.Replace(p.Mapping[i].File, "(deleted)", "", -1))
+		if len(file) == 0 {
+			continue
+		}
+		if len(libRx.FindStringSubmatch(file)) > 0 {
+			continue
+		}
+		if strings.HasPrefix(file, "[") {
+			continue
+		}
+		// Swap what we guess is main to position 0.
+		tmp := p.Mapping[i]
+		p.Mapping[i] = p.Mapping[0]
+		p.Mapping[0] = tmp
+		break
+	}
+}
+
+// Write writes the profile as a gzip-compressed marshaled protobuf.
+func (p *Profile) Write(w io.Writer) error {
+	p.preEncode()
+	b := marshal(p)
+	zw := gzip.NewWriter(w)
+	defer zw.Close()
+	_, err := zw.Write(b)
+	return err
+}
+
+// CheckValid tests whether the profile is valid.  Checks include, but are
+// not limited to:
+//   - len(Profile.Sample[n].value) == len(Profile.value_unit)
+//   - Sample.id has a corresponding Profile.Location
+func (p *Profile) CheckValid() error {
+	// Check that sample values are consistent
+	sampleLen := len(p.SampleType)
+	if sampleLen == 0 && len(p.Sample) != 0 {
+		return fmt.Errorf("missing sample type information")
+	}
+	for _, s := range p.Sample {
+		if len(s.Value) != sampleLen {
+			return fmt.Errorf("mismatch: sample has: %d values vs. %d types", len(s.Value), len(p.SampleType))
+		}
+	}
+
+	// Check that all mappings/locations/functions are in the tables
+	// Check that there are no duplicate ids
+	mappings := make(map[uint64]*Mapping, len(p.Mapping))
+	for _, m := range p.Mapping {
+		if m.ID == 0 {
+			return fmt.Errorf("found mapping with reserved ID=0")
+		}
+		if mappings[m.ID] != nil {
+			return fmt.Errorf("multiple mappings with same id: %d", m.ID)
+		}
+		mappings[m.ID] = m
+	}
+	functions := make(map[uint64]*Function, len(p.Function))
+	for _, f := range p.Function {
+		if f.ID == 0 {
+			return fmt.Errorf("found function with reserved ID=0")
+		}
+		if functions[f.ID] != nil {
+			return fmt.Errorf("multiple functions with same id: %d", f.ID)
+		}
+		functions[f.ID] = f
+	}
+	locations := make(map[uint64]*Location, len(p.Location))
+	for _, l := range p.Location {
+		if l.ID == 0 {
+			return fmt.Errorf("found location with reserved id=0")
+		}
+		if locations[l.ID] != nil {
+			return fmt.Errorf("multiple locations with same id: %d", l.ID)
+		}
+		locations[l.ID] = l
+		if m := l.Mapping; m != nil {
+			if m.ID == 0 || mappings[m.ID] != m {
+				return fmt.Errorf("inconsistent mapping %p: %d", m, m.ID)
+			}
+		}
+		for _, ln := range l.Line {
+			if f := ln.Function; f != nil {
+				if f.ID == 0 || functions[f.ID] != f {
+					return fmt.Errorf("inconsistent function %p: %d", f, f.ID)
+				}
+			}
+		}
+	}
+	return nil
+}
+
+// Aggregate merges the locations in the profile into equivalence
+// classes preserving the request attributes. It also updates the
+// samples to point to the merged locations.
+func (p *Profile) Aggregate(inlineFrame, function, filename, linenumber, address bool) error {
+	for _, m := range p.Mapping {
+		m.HasInlineFrames = m.HasInlineFrames && inlineFrame
+		m.HasFunctions = m.HasFunctions && function
+		m.HasFilenames = m.HasFilenames && filename
+		m.HasLineNumbers = m.HasLineNumbers && linenumber
+	}
+
+	// Aggregate functions
+	if !function || !filename {
+		for _, f := range p.Function {
+			if !function {
+				f.Name = ""
+				f.SystemName = ""
+			}
+			if !filename {
+				f.Filename = ""
+			}
+		}
+	}
+
+	// Aggregate locations
+	if !inlineFrame || !address || !linenumber {
+		for _, l := range p.Location {
+			if !inlineFrame && len(l.Line) > 1 {
+				l.Line = l.Line[len(l.Line)-1:]
+			}
+			if !linenumber {
+				for i := range l.Line {
+					l.Line[i].Line = 0
+				}
+			}
+			if !address {
+				l.Address = 0
+			}
+		}
+	}
+
+	return p.CheckValid()
+}
+
+// Print dumps a text representation of a profile. Intended mainly
+// for debugging purposes.
+func (p *Profile) String() string {
+
+	ss := make([]string, 0, len(p.Sample)+len(p.Mapping)+len(p.Location))
+	if pt := p.PeriodType; pt != nil {
+		ss = append(ss, fmt.Sprintf("PeriodType: %s %s", pt.Type, pt.Unit))
+	}
+	ss = append(ss, fmt.Sprintf("Period: %d", p.Period))
+	if p.TimeNanos != 0 {
+		ss = append(ss, fmt.Sprintf("Time: %v", time.Unix(0, p.TimeNanos)))
+	}
+	if p.DurationNanos != 0 {
+		ss = append(ss, fmt.Sprintf("Duration: %v", time.Duration(p.DurationNanos)))
+	}
+
+	ss = append(ss, "Samples:")
+	var sh1 string
+	for _, s := range p.SampleType {
+		sh1 = sh1 + fmt.Sprintf("%s/%s ", s.Type, s.Unit)
+	}
+	ss = append(ss, strings.TrimSpace(sh1))
+	for _, s := range p.Sample {
+		var sv string
+		for _, v := range s.Value {
+			sv = fmt.Sprintf("%s %10d", sv, v)
+		}
+		sv = sv + ": "
+		for _, l := range s.Location {
+			sv = sv + fmt.Sprintf("%d ", l.ID)
+		}
+		ss = append(ss, sv)
+		const labelHeader = "                "
+		if len(s.Label) > 0 {
+			ls := labelHeader
+			for k, v := range s.Label {
+				ls = ls + fmt.Sprintf("%s:%v ", k, v)
+			}
+			ss = append(ss, ls)
+		}
+		if len(s.NumLabel) > 0 {
+			ls := labelHeader
+			for k, v := range s.NumLabel {
+				ls = ls + fmt.Sprintf("%s:%v ", k, v)
+			}
+			ss = append(ss, ls)
+		}
+	}
+
+	ss = append(ss, "Locations")
+	for _, l := range p.Location {
+		locStr := fmt.Sprintf("%6d: %#x ", l.ID, l.Address)
+		if m := l.Mapping; m != nil {
+			locStr = locStr + fmt.Sprintf("M=%d ", m.ID)
+		}
+		if len(l.Line) == 0 {
+			ss = append(ss, locStr)
+		}
+		for li := range l.Line {
+			lnStr := "??"
+			if fn := l.Line[li].Function; fn != nil {
+				lnStr = fmt.Sprintf("%s %s:%d s=%d",
+					fn.Name,
+					fn.Filename,
+					l.Line[li].Line,
+					fn.StartLine)
+				if fn.Name != fn.SystemName {
+					lnStr = lnStr + "(" + fn.SystemName + ")"
+				}
+			}
+			ss = append(ss, locStr+lnStr)
+			// Do not print location details past the first line
+			locStr = "             "
+		}
+	}
+
+	ss = append(ss, "Mappings")
+	for _, m := range p.Mapping {
+		bits := ""
+		if m.HasFunctions {
+			bits = bits + "[FN]"
+		}
+		if m.HasFilenames {
+			bits = bits + "[FL]"
+		}
+		if m.HasLineNumbers {
+			bits = bits + "[LN]"
+		}
+		if m.HasInlineFrames {
+			bits = bits + "[IN]"
+		}
+		ss = append(ss, fmt.Sprintf("%d: %#x/%#x/%#x %s %s %s",
+			m.ID,
+			m.Start, m.Limit, m.Offset,
+			m.File,
+			m.BuildID,
+			bits))
+	}
+
+	return strings.Join(ss, "\n") + "\n"
+}
+
+// Merge adds profile p adjusted by ratio r into profile p. Profiles
+// must be compatible (same Type and SampleType).
+// TODO(rsilvera): consider normalizing the profiles based on the
+// total samples collected.
+func (p *Profile) Merge(pb *Profile, r float64) error {
+	if err := p.Compatible(pb); err != nil {
+		return err
+	}
+
+	pb = pb.Copy()
+
+	// Keep the largest of the two periods.
+	if pb.Period > p.Period {
+		p.Period = pb.Period
+	}
+
+	p.DurationNanos += pb.DurationNanos
+
+	p.Mapping = append(p.Mapping, pb.Mapping...)
+	for i, m := range p.Mapping {
+		m.ID = uint64(i + 1)
+	}
+	p.Location = append(p.Location, pb.Location...)
+	for i, l := range p.Location {
+		l.ID = uint64(i + 1)
+	}
+	p.Function = append(p.Function, pb.Function...)
+	for i, f := range p.Function {
+		f.ID = uint64(i + 1)
+	}
+
+	if r != 1.0 {
+		for _, s := range pb.Sample {
+			for i, v := range s.Value {
+				s.Value[i] = int64((float64(v) * r))
+			}
+		}
+	}
+	p.Sample = append(p.Sample, pb.Sample...)
+	return p.CheckValid()
+}
+
+// Compatible determines if two profiles can be compared/merged.
+// returns nil if the profiles are compatible; otherwise an error with
+// details on the incompatibility.
+func (p *Profile) Compatible(pb *Profile) error {
+	if !compatibleValueTypes(p.PeriodType, pb.PeriodType) {
+		return fmt.Errorf("incompatible period types %v and %v", p.PeriodType, pb.PeriodType)
+	}
+
+	if len(p.SampleType) != len(pb.SampleType) {
+		return fmt.Errorf("incompatible sample types %v and %v", p.SampleType, pb.SampleType)
+	}
+
+	for i := range p.SampleType {
+		if !compatibleValueTypes(p.SampleType[i], pb.SampleType[i]) {
+			return fmt.Errorf("incompatible sample types %v and %v", p.SampleType, pb.SampleType)
+		}
+	}
+
+	return nil
+}
+
+// HasFunctions determines if all locations in this profile have
+// symbolized function information.
+func (p *Profile) HasFunctions() bool {
+	for _, l := range p.Location {
+		if l.Mapping == nil || !l.Mapping.HasFunctions {
+			return false
+		}
+	}
+	return true
+}
+
+// HasFileLines determines if all locations in this profile have
+// symbolized file and line number information.
+func (p *Profile) HasFileLines() bool {
+	for _, l := range p.Location {
+		if l.Mapping == nil || (!l.Mapping.HasFilenames || !l.Mapping.HasLineNumbers) {
+			return false
+		}
+	}
+	return true
+}
+
+func compatibleValueTypes(v1, v2 *ValueType) bool {
+	if v1 == nil || v2 == nil {
+		return true // No grounds to disqualify.
+	}
+	return v1.Type == v2.Type && v1.Unit == v2.Unit
+}
+
+// Copy makes a fully independent copy of a profile.
+func (p *Profile) Copy() *Profile {
+	p.preEncode()
+	b := marshal(p)
+
+	pp := &Profile{}
+	if err := unmarshal(b, pp); err != nil {
+		panic(err)
+	}
+	if err := pp.postDecode(); err != nil {
+		panic(err)
+	}
+
+	return pp
+}
+
+// Demangler maps symbol names to a human-readable form. This may
+// include C++ demangling and additional simplification. Names that
+// are not demangled may be missing from the resulting map.
+type Demangler func(name []string) (map[string]string, error)
+
+// Demangle attempts to demangle and optionally simplify any function
+// names referenced in the profile. It works on a best-effort basis:
+// it will silently preserve the original names in case of any errors.
+func (p *Profile) Demangle(d Demangler) error {
+	// Collect names to demangle.
+	var names []string
+	for _, fn := range p.Function {
+		names = append(names, fn.SystemName)
+	}
+
+	// Update profile with demangled names.
+	demangled, err := d(names)
+	if err != nil {
+		return err
+	}
+	for _, fn := range p.Function {
+		if dd, ok := demangled[fn.SystemName]; ok {
+			fn.Name = dd
+		}
+	}
+	return nil
+}
diff --git a/src/cmd/pprof/internal/profile/proto.go b/src/cmd/pprof/internal/profile/proto.go
new file mode 100644
index 0000000..475cf56
--- /dev/null
+++ b/src/cmd/pprof/internal/profile/proto.go
@@ -0,0 +1,298 @@
+// 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 file is a simple protocol buffer encoder and decoder.
+//
+// A protocol message must implement the message interface:
+//   decoder() []decoder
+//   encode(*buffer)
+//
+// The decode method returns a slice indexed by field number that gives the
+// function to decode that field.
+// The encode method encodes its receiver into the given buffer.
+//
+// The two methods are simple enough to be implemented by hand rather than
+// by using a protocol compiler.
+//
+// See profile.go for examples of messages implementing this interface.
+//
+// There is no support for groups, message sets, or "has" bits.
+
+package profile
+
+import "errors"
+
+type buffer struct {
+	field int
+	typ   int
+	u64   uint64
+	data  []byte
+	tmp   [16]byte
+}
+
+type decoder func(*buffer, message) error
+
+type message interface {
+	decoder() []decoder
+	encode(*buffer)
+}
+
+func marshal(m message) []byte {
+	var b buffer
+	m.encode(&b)
+	return b.data
+}
+
+func encodeVarint(b *buffer, x uint64) {
+	for x >= 128 {
+		b.data = append(b.data, byte(x)|0x80)
+		x >>= 7
+	}
+	b.data = append(b.data, byte(x))
+}
+
+func encodeLength(b *buffer, tag int, len int) {
+	encodeVarint(b, uint64(tag)<<3|2)
+	encodeVarint(b, uint64(len))
+}
+
+func encodeUint64(b *buffer, tag int, x uint64) {
+	// append varint to b.data
+	encodeVarint(b, uint64(tag)<<3|0)
+	encodeVarint(b, x)
+}
+
+func encodeUint64s(b *buffer, tag int, x []uint64) {
+	for _, u := range x {
+		encodeUint64(b, tag, u)
+	}
+}
+
+func encodeUint64Opt(b *buffer, tag int, x uint64) {
+	if x == 0 {
+		return
+	}
+	encodeUint64(b, tag, x)
+}
+
+func encodeInt64(b *buffer, tag int, x int64) {
+	u := uint64(x)
+	encodeUint64(b, tag, u)
+}
+
+func encodeInt64Opt(b *buffer, tag int, x int64) {
+	if x == 0 {
+		return
+	}
+	encodeInt64(b, tag, x)
+}
+
+func encodeString(b *buffer, tag int, x string) {
+	encodeLength(b, tag, len(x))
+	b.data = append(b.data, x...)
+}
+
+func encodeStrings(b *buffer, tag int, x []string) {
+	for _, s := range x {
+		encodeString(b, tag, s)
+	}
+}
+
+func encodeStringOpt(b *buffer, tag int, x string) {
+	if x == "" {
+		return
+	}
+	encodeString(b, tag, x)
+}
+
+func encodeBool(b *buffer, tag int, x bool) {
+	if x {
+		encodeUint64(b, tag, 1)
+	} else {
+		encodeUint64(b, tag, 0)
+	}
+}
+
+func encodeBoolOpt(b *buffer, tag int, x bool) {
+	if x == false {
+		return
+	}
+	encodeBool(b, tag, x)
+}
+
+func encodeMessage(b *buffer, tag int, m message) {
+	n1 := len(b.data)
+	m.encode(b)
+	n2 := len(b.data)
+	encodeLength(b, tag, n2-n1)
+	n3 := len(b.data)
+	copy(b.tmp[:], b.data[n2:n3])
+	copy(b.data[n1+(n3-n2):], b.data[n1:n2])
+	copy(b.data[n1:], b.tmp[:n3-n2])
+}
+
+func unmarshal(data []byte, m message) (err error) {
+	b := buffer{data: data, typ: 2}
+	return decodeMessage(&b, m)
+}
+
+func le64(p []byte) uint64 {
+	return uint64(p[0]) | uint64(p[1])<<8 | uint64(p[2])<<16 | uint64(p[3])<<24 | uint64(p[4])<<32 | uint64(p[5])<<40 | uint64(p[6])<<48 | uint64(p[7])<<56
+}
+
+func le32(p []byte) uint32 {
+	return uint32(p[0]) | uint32(p[1])<<8 | uint32(p[2])<<16 | uint32(p[3])<<24
+}
+
+func decodeVarint(data []byte) (uint64, []byte, error) {
+	var i int
+	var u uint64
+	for i = 0; ; i++ {
+		if i >= 10 || i >= len(data) {
+			return 0, nil, errors.New("bad varint")
+		}
+		u |= uint64(data[i]&0x7F) << uint(7*i)
+		if data[i]&0x80 == 0 {
+			return u, data[i+1:], nil
+		}
+	}
+}
+
+func decodeField(b *buffer, data []byte) ([]byte, error) {
+	x, data, err := decodeVarint(data)
+	if err != nil {
+		return nil, err
+	}
+	b.field = int(x >> 3)
+	b.typ = int(x & 7)
+	b.data = nil
+	b.u64 = 0
+	switch b.typ {
+	case 0:
+		b.u64, data, err = decodeVarint(data)
+		if err != nil {
+			return nil, err
+		}
+	case 1:
+		if len(data) < 8 {
+			return nil, errors.New("not enough data")
+		}
+		b.u64 = le64(data[:8])
+		data = data[8:]
+	case 2:
+		var n uint64
+		n, data, err = decodeVarint(data)
+		if err != nil {
+			return nil, err
+		}
+		if n > uint64(len(data)) {
+			return nil, errors.New("too much data")
+		}
+		b.data = data[:n]
+		data = data[n:]
+	case 5:
+		if len(data) < 4 {
+			return nil, errors.New("not enough data")
+		}
+		b.u64 = uint64(le32(data[:4]))
+		data = data[4:]
+	default:
+		return nil, errors.New("unknown type: " + string(b.typ))
+	}
+
+	return data, nil
+}
+
+func checkType(b *buffer, typ int) error {
+	if b.typ != typ {
+		return errors.New("type mismatch")
+	}
+	return nil
+}
+
+func decodeMessage(b *buffer, m message) error {
+	if err := checkType(b, 2); err != nil {
+		return err
+	}
+	dec := m.decoder()
+	data := b.data
+	for len(data) > 0 {
+		// pull varint field# + type
+		var err error
+		data, err = decodeField(b, data)
+		if err != nil {
+			return err
+		}
+		if b.field >= len(dec) || dec[b.field] == nil {
+			continue
+		}
+		if err := dec[b.field](b, m); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+func decodeInt64(b *buffer, x *int64) error {
+	if err := checkType(b, 0); err != nil {
+		return err
+	}
+	*x = int64(b.u64)
+	return nil
+}
+
+func decodeInt64s(b *buffer, x *[]int64) error {
+	var i int64
+	if err := decodeInt64(b, &i); err != nil {
+		return err
+	}
+	*x = append(*x, i)
+	return nil
+}
+
+func decodeUint64(b *buffer, x *uint64) error {
+	if err := checkType(b, 0); err != nil {
+		return err
+	}
+	*x = b.u64
+	return nil
+}
+
+func decodeUint64s(b *buffer, x *[]uint64) error {
+	var u uint64
+	if err := decodeUint64(b, &u); err != nil {
+		return err
+	}
+	*x = append(*x, u)
+	return nil
+}
+
+func decodeString(b *buffer, x *string) error {
+	if err := checkType(b, 2); err != nil {
+		return err
+	}
+	*x = string(b.data)
+	return nil
+}
+
+func decodeStrings(b *buffer, x *[]string) error {
+	var s string
+	if err := decodeString(b, &s); err != nil {
+		return err
+	}
+	*x = append(*x, s)
+	return nil
+}
+
+func decodeBool(b *buffer, x *bool) error {
+	if err := checkType(b, 0); err != nil {
+		return err
+	}
+	if int64(b.u64) == 0 {
+		*x = false
+	} else {
+		*x = true
+	}
+	return nil
+}
diff --git a/src/cmd/pprof/internal/profile/prune.go b/src/cmd/pprof/internal/profile/prune.go
new file mode 100644
index 0000000..abc898c
--- /dev/null
+++ b/src/cmd/pprof/internal/profile/prune.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.
+
+// Implements methods to remove frames from profiles.
+
+package profile
+
+import (
+	"fmt"
+	"regexp"
+)
+
+// Prune removes all nodes beneath a node matching dropRx, and not
+// matching keepRx.  If the root node of a Sample matches, the sample
+// will have an empty stack.
+func (p *Profile) Prune(dropRx, keepRx *regexp.Regexp) {
+	prune := make(map[uint64]bool)
+	pruneBeneath := make(map[uint64]bool)
+
+	for _, loc := range p.Location {
+		var i int
+		for i = len(loc.Line) - 1; i >= 0; i-- {
+			if fn := loc.Line[i].Function; fn != nil && fn.Name != "" {
+				funcName := fn.Name
+				// Account for leading '.' on the PPC ELF v1 ABI.
+				if funcName[0] == '.' {
+					funcName = funcName[1:]
+				}
+				if dropRx.MatchString(funcName) {
+					if keepRx == nil || !keepRx.MatchString(funcName) {
+						break
+					}
+				}
+			}
+		}
+
+		if i >= 0 {
+			// Found matching entry to prune.
+			pruneBeneath[loc.ID] = true
+
+			// Remove the matching location.
+			if i == len(loc.Line)-1 {
+				// Matched the top entry: prune the whole location.
+				prune[loc.ID] = true
+			} else {
+				loc.Line = loc.Line[i+1:]
+			}
+		}
+	}
+
+	// Prune locs from each Sample
+	for _, sample := range p.Sample {
+		// Scan from the root to the leaves to find the prune location.
+		// Do not prune frames before the first user frame, to avoid
+		// pruning everything.
+		foundUser := false
+		for i := len(sample.Location) - 1; i >= 0; i-- {
+			id := sample.Location[i].ID
+			if !prune[id] && !pruneBeneath[id] {
+				foundUser = true
+				continue
+			}
+			if !foundUser {
+				continue
+			}
+			if prune[id] {
+				sample.Location = sample.Location[i+1:]
+				break
+			}
+			if pruneBeneath[id] {
+				sample.Location = sample.Location[i:]
+				break
+			}
+		}
+	}
+}
+
+// RemoveUninteresting prunes and elides profiles using built-in
+// tables of uninteresting function names.
+func (p *Profile) RemoveUninteresting() error {
+	var keep, drop *regexp.Regexp
+	var err error
+
+	if p.DropFrames != "" {
+		if drop, err = regexp.Compile("^(" + p.DropFrames + ")$"); err != nil {
+			return fmt.Errorf("failed to compile regexp %s: %v", p.DropFrames, err)
+		}
+		if p.KeepFrames != "" {
+			if keep, err = regexp.Compile("^(" + p.KeepFrames + ")$"); err != nil {
+				return fmt.Errorf("failed to compile regexp %s: %v", p.KeepFrames, err)
+			}
+		}
+		p.Prune(drop, keep)
+	}
+	return nil
+}
diff --git a/src/cmd/pprof/internal/report/report.go b/src/cmd/pprof/internal/report/report.go
new file mode 100644
index 0000000..e5977fd
--- /dev/null
+++ b/src/cmd/pprof/internal/report/report.go
@@ -0,0 +1,1718 @@
+// 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 report summarizes a performance profile into a
+// human-readable report.
+package report
+
+import (
+	"fmt"
+	"io"
+	"math"
+	"os"
+	"path/filepath"
+	"regexp"
+	"sort"
+	"strconv"
+	"strings"
+	"time"
+
+	"cmd/pprof/internal/plugin"
+	"cmd/pprof/internal/profile"
+)
+
+// Generate generates a report as directed by the Report.
+func Generate(w io.Writer, rpt *Report, obj plugin.ObjTool) error {
+	o := rpt.options
+
+	switch o.OutputFormat {
+	case Dot:
+		return printDOT(w, rpt)
+	case Tree:
+		return printTree(w, rpt)
+	case Text:
+		return printText(w, rpt)
+	case Raw:
+		fmt.Fprint(w, rpt.prof.String())
+		return nil
+	case Tags:
+		return printTags(w, rpt)
+	case Proto:
+		return rpt.prof.Write(w)
+	case Dis:
+		return printAssembly(w, rpt, obj)
+	case List:
+		return printSource(w, rpt)
+	case WebList:
+		return printWebSource(w, rpt, obj)
+	case Callgrind:
+		return printCallgrind(w, rpt)
+	}
+	return fmt.Errorf("unexpected output format")
+}
+
+// printAssembly prints an annotated assembly listing.
+func printAssembly(w io.Writer, rpt *Report, obj plugin.ObjTool) error {
+	g, err := newGraph(rpt)
+	if err != nil {
+		return err
+	}
+
+	o := rpt.options
+	prof := rpt.prof
+
+	// If the regexp source can be parsed as an address, also match
+	// functions that land on that address.
+	var address *uint64
+	if hex, err := strconv.ParseUint(o.Symbol.String(), 0, 64); err == nil {
+		address = &hex
+	}
+
+	fmt.Fprintln(w, "Total:", rpt.formatValue(rpt.total))
+	symbols := symbolsFromBinaries(prof, g, o.Symbol, address, obj)
+	symNodes := nodesPerSymbol(g.ns, symbols)
+	// Sort function names for printing.
+	var syms objSymbols
+	for s := range symNodes {
+		syms = append(syms, s)
+	}
+	sort.Sort(syms)
+
+	// Correlate the symbols from the binary with the profile samples.
+	for _, s := range syms {
+		sns := symNodes[s]
+
+		// Gather samples for this symbol.
+		flatSum, cumSum := sumNodes(sns)
+
+		// Get the function assembly.
+		insns, err := obj.Disasm(s.sym.File, s.sym.Start, s.sym.End)
+		if err != nil {
+			return err
+		}
+
+		ns := annotateAssembly(insns, sns, s.base)
+
+		fmt.Fprintf(w, "ROUTINE ======================== %s\n", s.sym.Name[0])
+		for _, name := range s.sym.Name[1:] {
+			fmt.Fprintf(w, "    AKA ======================== %s\n", name)
+		}
+		fmt.Fprintf(w, "%10s %10s (flat, cum) %s of Total\n",
+			rpt.formatValue(flatSum), rpt.formatValue(cumSum),
+			percentage(cumSum, rpt.total))
+
+		for _, n := range ns {
+			fmt.Fprintf(w, "%10s %10s %10x: %s\n", valueOrDot(n.flat, rpt), valueOrDot(n.cum, rpt), n.info.address, n.info.name)
+		}
+	}
+	return nil
+}
+
+// symbolsFromBinaries examines the binaries listed on the profile
+// that have associated samples, and identifies symbols matching rx.
+func symbolsFromBinaries(prof *profile.Profile, g graph, rx *regexp.Regexp, address *uint64, obj plugin.ObjTool) []*objSymbol {
+	hasSamples := make(map[string]bool)
+	// Only examine mappings that have samples that match the
+	// regexp. This is an optimization to speed up pprof.
+	for _, n := range g.ns {
+		if name := n.info.prettyName(); rx.MatchString(name) && n.info.objfile != "" {
+			hasSamples[n.info.objfile] = true
+		}
+	}
+
+	// Walk all mappings looking for matching functions with samples.
+	var objSyms []*objSymbol
+	for _, m := range prof.Mapping {
+		if !hasSamples[filepath.Base(m.File)] {
+			if address == nil || !(m.Start <= *address && *address <= m.Limit) {
+				continue
+			}
+		}
+
+		f, err := obj.Open(m.File, m.Start)
+		if err != nil {
+			fmt.Printf("%v\n", err)
+			continue
+		}
+
+		// Find symbols in this binary matching the user regexp.
+		var addr uint64
+		if address != nil {
+			addr = *address
+		}
+		msyms, err := f.Symbols(rx, addr)
+		base := f.Base()
+		f.Close()
+		if err != nil {
+			continue
+		}
+		for _, ms := range msyms {
+			objSyms = append(objSyms,
+				&objSymbol{
+					sym:  ms,
+					base: base,
+				},
+			)
+		}
+	}
+
+	return objSyms
+}
+
+// objSym represents a symbol identified from a binary. It includes
+// the SymbolInfo from the disasm package and the base that must be
+// added to correspond to sample addresses
+type objSymbol struct {
+	sym  *plugin.Sym
+	base uint64
+}
+
+// objSymbols is a wrapper type to enable sorting of []*objSymbol.
+type objSymbols []*objSymbol
+
+func (o objSymbols) Len() int {
+	return len(o)
+}
+
+func (o objSymbols) Less(i, j int) bool {
+	if namei, namej := o[i].sym.Name[0], o[j].sym.Name[0]; namei != namej {
+		return namei < namej
+	}
+	return o[i].sym.Start < o[j].sym.Start
+}
+
+func (o objSymbols) Swap(i, j int) {
+	o[i], o[j] = o[j], o[i]
+}
+
+// nodesPerSymbol classifies nodes into a group of symbols.
+func nodesPerSymbol(ns nodes, symbols []*objSymbol) map[*objSymbol]nodes {
+	symNodes := make(map[*objSymbol]nodes)
+	for _, s := range symbols {
+		// Gather samples for this symbol.
+		for _, n := range ns {
+			address := n.info.address - s.base
+			if address >= s.sym.Start && address < s.sym.End {
+				symNodes[s] = append(symNodes[s], n)
+			}
+		}
+	}
+	return symNodes
+}
+
+// annotateAssembly annotates a set of assembly instructions with a
+// set of samples. It returns a set of nodes to display.  base is an
+// offset to adjust the sample addresses.
+func annotateAssembly(insns []plugin.Inst, samples nodes, base uint64) nodes {
+	// Add end marker to simplify printing loop.
+	insns = append(insns, plugin.Inst{^uint64(0), "", "", 0})
+
+	// Ensure samples are sorted by address.
+	samples.sort(addressOrder)
+
+	var s int
+	var asm nodes
+	for ix, in := range insns[:len(insns)-1] {
+		n := node{
+			info: nodeInfo{
+				address: in.Addr,
+				name:    in.Text,
+				file:    trimPath(in.File),
+				lineno:  in.Line,
+			},
+		}
+
+		// Sum all the samples until the next instruction (to account
+		// for samples attributed to the middle of an instruction).
+		for next := insns[ix+1].Addr; s < len(samples) && samples[s].info.address-base < next; s++ {
+			n.flat += samples[s].flat
+			n.cum += samples[s].cum
+			if samples[s].info.file != "" {
+				n.info.file = trimPath(samples[s].info.file)
+				n.info.lineno = samples[s].info.lineno
+			}
+		}
+		asm = append(asm, &n)
+	}
+
+	return asm
+}
+
+// valueOrDot formats a value according to a report, intercepting zero
+// values.
+func valueOrDot(value int64, rpt *Report) string {
+	if value == 0 {
+		return "."
+	}
+	return rpt.formatValue(value)
+}
+
+// canAccessFile determines if the filename can be opened for reading.
+func canAccessFile(path string) bool {
+	if fi, err := os.Stat(path); err == nil {
+		return fi.Mode().Perm()&0400 != 0
+	}
+	return false
+}
+
+// printTags collects all tags referenced in the profile and prints
+// them in a sorted table.
+func printTags(w io.Writer, rpt *Report) error {
+	p := rpt.prof
+
+	// Hashtable to keep accumulate tags as key,value,count.
+	tagMap := make(map[string]map[string]int64)
+	for _, s := range p.Sample {
+		for key, vals := range s.Label {
+			for _, val := range vals {
+				if valueMap, ok := tagMap[key]; ok {
+					valueMap[val] = valueMap[val] + s.Value[0]
+					continue
+				}
+				valueMap := make(map[string]int64)
+				valueMap[val] = s.Value[0]
+				tagMap[key] = valueMap
+			}
+		}
+		for key, vals := range s.NumLabel {
+			for _, nval := range vals {
+				val := scaledValueLabel(nval, key, "auto")
+				if valueMap, ok := tagMap[key]; ok {
+					valueMap[val] = valueMap[val] + s.Value[0]
+					continue
+				}
+				valueMap := make(map[string]int64)
+				valueMap[val] = s.Value[0]
+				tagMap[key] = valueMap
+			}
+		}
+	}
+
+	tagKeys := make(tags, 0, len(tagMap))
+	for key := range tagMap {
+		tagKeys = append(tagKeys, &tag{name: key})
+	}
+	sort.Sort(tagKeys)
+
+	for _, tagKey := range tagKeys {
+		var total int64
+		key := tagKey.name
+		tags := make(tags, 0, len(tagMap[key]))
+		for t, c := range tagMap[key] {
+			total += c
+			tags = append(tags, &tag{name: t, weight: c})
+		}
+
+		sort.Sort(tags)
+		fmt.Fprintf(w, "%s: Total %d\n", key, total)
+		for _, t := range tags {
+			if total > 0 {
+				fmt.Fprintf(w, "  %8d (%s): %s\n", t.weight,
+					percentage(t.weight, total), t.name)
+			} else {
+				fmt.Fprintf(w, "  %8d: %s\n", t.weight, t.name)
+			}
+		}
+		fmt.Fprintln(w)
+	}
+	return nil
+}
+
+// printText prints a flat text report for a profile.
+func printText(w io.Writer, rpt *Report) error {
+	g, err := newGraph(rpt)
+	if err != nil {
+		return err
+	}
+
+	origCount, droppedNodes, _ := g.preprocess(rpt)
+	fmt.Fprintln(w, strings.Join(legendDetailLabels(rpt, g, origCount, droppedNodes, 0), "\n"))
+
+	fmt.Fprintf(w, "%10s %5s%% %5s%% %10s %5s%%\n",
+		"flat", "flat", "sum", "cum", "cum")
+
+	var flatSum int64
+	for _, n := range g.ns {
+		name, flat, cum := n.info.prettyName(), n.flat, n.cum
+
+		flatSum += flat
+		fmt.Fprintf(w, "%10s %s %s %10s %s  %s\n",
+			rpt.formatValue(flat),
+			percentage(flat, rpt.total),
+			percentage(flatSum, rpt.total),
+			rpt.formatValue(cum),
+			percentage(cum, rpt.total),
+			name)
+	}
+	return nil
+}
+
+// printCallgrind prints a graph for a profile on callgrind format.
+func printCallgrind(w io.Writer, rpt *Report) error {
+	g, err := newGraph(rpt)
+	if err != nil {
+		return err
+	}
+
+	o := rpt.options
+	rpt.options.NodeFraction = 0
+	rpt.options.EdgeFraction = 0
+	rpt.options.NodeCount = 0
+
+	g.preprocess(rpt)
+
+	fmt.Fprintln(w, "events:", o.SampleType+"("+o.OutputUnit+")")
+
+	files := make(map[string]int)
+	names := make(map[string]int)
+	for _, n := range g.ns {
+		fmt.Fprintln(w, "fl="+callgrindName(files, n.info.file))
+		fmt.Fprintln(w, "fn="+callgrindName(names, n.info.name))
+		sv, _ := ScaleValue(n.flat, o.SampleUnit, o.OutputUnit)
+		fmt.Fprintf(w, "%d %d\n", n.info.lineno, int(sv))
+
+		// Print outgoing edges.
+		for _, out := range sortedEdges(n.out) {
+			c, _ := ScaleValue(out.weight, o.SampleUnit, o.OutputUnit)
+			count := fmt.Sprintf("%d", int(c))
+			callee := out.dest
+			fmt.Fprintln(w, "cfl="+callgrindName(files, callee.info.file))
+			fmt.Fprintln(w, "cfn="+callgrindName(names, callee.info.name))
+			fmt.Fprintln(w, "calls="+count, callee.info.lineno)
+			fmt.Fprintln(w, n.info.lineno, count)
+		}
+		fmt.Fprintln(w)
+	}
+
+	return nil
+}
+
+// callgrindName implements the callgrind naming compression scheme.
+// For names not previously seen returns "(N) name", where N is a
+// unique index.  For names previously seen returns "(N)" where N is
+// the index returned the first time.
+func callgrindName(names map[string]int, name string) string {
+	if name == "" {
+		return ""
+	}
+	if id, ok := names[name]; ok {
+		return fmt.Sprintf("(%d)", id)
+	}
+	id := len(names) + 1
+	names[name] = id
+	return fmt.Sprintf("(%d) %s", id, name)
+}
+
+// printTree prints a tree-based report in text form.
+func printTree(w io.Writer, rpt *Report) error {
+	const separator = "----------------------------------------------------------+-------------"
+	const legend = "      flat  flat%   sum%        cum   cum%   calls calls% + context 	 	 "
+
+	g, err := newGraph(rpt)
+	if err != nil {
+		return err
+	}
+
+	origCount, droppedNodes, _ := g.preprocess(rpt)
+	fmt.Fprintln(w, strings.Join(legendDetailLabels(rpt, g, origCount, droppedNodes, 0), "\n"))
+
+	fmt.Fprintln(w, separator)
+	fmt.Fprintln(w, legend)
+	var flatSum int64
+
+	rx := rpt.options.Symbol
+	for _, n := range g.ns {
+		name, flat, cum := n.info.prettyName(), n.flat, n.cum
+
+		// Skip any entries that do not match the regexp (for the "peek" command).
+		if rx != nil && !rx.MatchString(name) {
+			continue
+		}
+
+		fmt.Fprintln(w, separator)
+		// Print incoming edges.
+		inEdges := sortedEdges(n.in)
+		inSum := inEdges.sum()
+		for _, in := range inEdges {
+			fmt.Fprintf(w, "%50s %s |   %s\n", rpt.formatValue(in.weight),
+				percentage(in.weight, inSum), in.src.info.prettyName())
+		}
+
+		// Print current node.
+		flatSum += flat
+		fmt.Fprintf(w, "%10s %s %s %10s %s                | %s\n",
+			rpt.formatValue(flat),
+			percentage(flat, rpt.total),
+			percentage(flatSum, rpt.total),
+			rpt.formatValue(cum),
+			percentage(cum, rpt.total),
+			name)
+
+		// Print outgoing edges.
+		outEdges := sortedEdges(n.out)
+		outSum := outEdges.sum()
+		for _, out := range outEdges {
+			fmt.Fprintf(w, "%50s %s |   %s\n", rpt.formatValue(out.weight),
+				percentage(out.weight, outSum), out.dest.info.prettyName())
+		}
+	}
+	if len(g.ns) > 0 {
+		fmt.Fprintln(w, separator)
+	}
+	return nil
+}
+
+// printDOT prints an annotated callgraph in DOT format.
+func printDOT(w io.Writer, rpt *Report) error {
+	g, err := newGraph(rpt)
+	if err != nil {
+		return err
+	}
+
+	origCount, droppedNodes, droppedEdges := g.preprocess(rpt)
+
+	prof := rpt.prof
+	graphname := "unnamed"
+	if len(prof.Mapping) > 0 {
+		graphname = filepath.Base(prof.Mapping[0].File)
+	}
+	fmt.Fprintln(w, `digraph "`+graphname+`" {`)
+	fmt.Fprintln(w, `node [style=filled fillcolor="#f8f8f8"]`)
+	fmt.Fprintln(w, dotLegend(rpt, g, origCount, droppedNodes, droppedEdges))
+
+	if len(g.ns) == 0 {
+		fmt.Fprintln(w, "}")
+		return nil
+	}
+
+	// Make sure nodes have a unique consistent id.
+	nodeIndex := make(map[*node]int)
+	maxFlat := float64(g.ns[0].flat)
+	for i, n := range g.ns {
+		nodeIndex[n] = i + 1
+		if float64(n.flat) > maxFlat {
+			maxFlat = float64(n.flat)
+		}
+	}
+	var edges edgeList
+	for _, n := range g.ns {
+		node := dotNode(rpt, maxFlat, nodeIndex[n], n)
+		fmt.Fprintln(w, node)
+		if nodelets := dotNodelets(rpt, nodeIndex[n], n); nodelets != "" {
+			fmt.Fprint(w, nodelets)
+		}
+
+		// Collect outgoing edges.
+		for _, e := range n.out {
+			edges = append(edges, e)
+		}
+	}
+	// Sort edges by frequency as a hint to the graph layout engine.
+	sort.Sort(edges)
+	for _, e := range edges {
+		fmt.Fprintln(w, dotEdge(rpt, nodeIndex[e.src], nodeIndex[e.dest], e))
+	}
+	fmt.Fprintln(w, "}")
+	return nil
+}
+
+// percentage computes the percentage of total of a value, and encodes
+// it as a string. At least two digits of precision are printed.
+func percentage(value, total int64) string {
+	var ratio float64
+	if total != 0 {
+		ratio = float64(value) / float64(total) * 100
+	}
+	switch {
+	case ratio >= 99.95:
+		return "  100%"
+	case ratio >= 1.0:
+		return fmt.Sprintf("%5.2f%%", ratio)
+	default:
+		return fmt.Sprintf("%5.2g%%", ratio)
+	}
+}
+
+// dotLegend generates the overall graph label for a report in DOT format.
+func dotLegend(rpt *Report, g graph, origCount, droppedNodes, droppedEdges int) string {
+	label := legendLabels(rpt)
+	label = append(label, legendDetailLabels(rpt, g, origCount, droppedNodes, droppedEdges)...)
+	return fmt.Sprintf(`subgraph cluster_L { L [shape=box fontsize=32 label="%s\l"] }`, strings.Join(label, `\l`))
+}
+
+// legendLabels generates labels exclusive to graph visualization.
+func legendLabels(rpt *Report) []string {
+	prof := rpt.prof
+	o := rpt.options
+	var label []string
+	if len(prof.Mapping) > 0 {
+		if prof.Mapping[0].File != "" {
+			label = append(label, "File: "+filepath.Base(prof.Mapping[0].File))
+		}
+		if prof.Mapping[0].BuildID != "" {
+			label = append(label, "Build ID: "+prof.Mapping[0].BuildID)
+		}
+	}
+	if o.SampleType != "" {
+		label = append(label, "Type: "+o.SampleType)
+	}
+	if prof.TimeNanos != 0 {
+		const layout = "Jan 2, 2006 at 3:04pm (MST)"
+		label = append(label, "Time: "+time.Unix(0, prof.TimeNanos).Format(layout))
+	}
+	if prof.DurationNanos != 0 {
+		label = append(label, fmt.Sprintf("Duration: %v", time.Duration(prof.DurationNanos)))
+	}
+	return label
+}
+
+// legendDetailLabels generates labels common to graph and text visualization.
+func legendDetailLabels(rpt *Report, g graph, origCount, droppedNodes, droppedEdges int) []string {
+	nodeFraction := rpt.options.NodeFraction
+	edgeFraction := rpt.options.EdgeFraction
+	nodeCount := rpt.options.NodeCount
+
+	label := []string{}
+
+	var flatSum int64
+	for _, n := range g.ns {
+		flatSum = flatSum + n.flat
+	}
+
+	label = append(label, fmt.Sprintf("%s of %s total (%s)", rpt.formatValue(flatSum), rpt.formatValue(rpt.total), percentage(flatSum, rpt.total)))
+
+	if rpt.total > 0 {
+		if droppedNodes > 0 {
+			label = append(label, genLabel(droppedNodes, "node", "cum",
+				rpt.formatValue(int64(float64(rpt.total)*nodeFraction))))
+		}
+		if droppedEdges > 0 {
+			label = append(label, genLabel(droppedEdges, "edge", "freq",
+				rpt.formatValue(int64(float64(rpt.total)*edgeFraction))))
+		}
+		if nodeCount > 0 && nodeCount < origCount {
+			label = append(label, fmt.Sprintf("Showing top %d nodes out of %d (cum >= %s)",
+				nodeCount, origCount,
+				rpt.formatValue(g.ns[len(g.ns)-1].cum)))
+		}
+	}
+	return label
+}
+
+func genLabel(d int, n, l, f string) string {
+	if d > 1 {
+		n = n + "s"
+	}
+	return fmt.Sprintf("Dropped %d %s (%s <= %s)", d, n, l, f)
+}
+
+// dotNode generates a graph node in DOT format.
+func dotNode(rpt *Report, maxFlat float64, rIndex int, n *node) string {
+	flat, cum := n.flat, n.cum
+
+	labels := strings.Split(n.info.prettyName(), "::")
+	label := strings.Join(labels, `\n`) + `\n`
+
+	flatValue := rpt.formatValue(flat)
+	if flat > 0 {
+		label = label + fmt.Sprintf(`%s(%s)`,
+			flatValue,
+			strings.TrimSpace(percentage(flat, rpt.total)))
+	} else {
+		label = label + "0"
+	}
+	cumValue := flatValue
+	if cum != flat {
+		if flat > 0 {
+			label = label + `\n`
+		} else {
+			label = label + " "
+		}
+		cumValue = rpt.formatValue(cum)
+		label = label + fmt.Sprintf(`of %s(%s)`,
+			cumValue,
+			strings.TrimSpace(percentage(cum, rpt.total)))
+	}
+
+	// Scale font sizes from 8 to 24 based on percentage of flat frequency.
+	// Use non linear growth to emphasize the size difference.
+	baseFontSize, maxFontGrowth := 8, 16.0
+	fontSize := baseFontSize
+	if maxFlat > 0 && flat > 0 && float64(flat) <= maxFlat {
+		fontSize += int(math.Ceil(maxFontGrowth * math.Sqrt(float64(flat)/maxFlat)))
+	}
+	return fmt.Sprintf(`N%d [label="%s" fontsize=%d shape=box tooltip="%s (%s)"]`,
+		rIndex,
+		label,
+		fontSize, n.info.prettyName(), cumValue)
+}
+
+// dotEdge generates a graph edge in DOT format.
+func dotEdge(rpt *Report, from, to int, e *edgeInfo) string {
+	w := rpt.formatValue(e.weight)
+	attr := fmt.Sprintf(`label=" %s"`, w)
+	if rpt.total > 0 {
+		if weight := 1 + int(e.weight*100/rpt.total); weight > 1 {
+			attr = fmt.Sprintf(`%s weight=%d`, attr, weight)
+		}
+		if width := 1 + int(e.weight*5/rpt.total); width > 1 {
+			attr = fmt.Sprintf(`%s penwidth=%d`, attr, width)
+		}
+	}
+	arrow := "->"
+	if e.residual {
+		arrow = "..."
+	}
+	tooltip := fmt.Sprintf(`"%s %s %s (%s)"`,
+		e.src.info.prettyName(), arrow, e.dest.info.prettyName(), w)
+	attr = fmt.Sprintf(`%s tooltip=%s labeltooltip=%s`,
+		attr, tooltip, tooltip)
+
+	if e.residual {
+		attr = attr + ` style="dotted"`
+	}
+
+	if len(e.src.tags) > 0 {
+		// Separate children further if source has tags.
+		attr = attr + " minlen=2"
+	}
+	return fmt.Sprintf("N%d -> N%d [%s]", from, to, attr)
+}
+
+// dotNodelets generates the DOT boxes for the node tags.
+func dotNodelets(rpt *Report, rIndex int, n *node) (dot string) {
+	const maxNodelets = 4    // Number of nodelets for alphanumeric labels
+	const maxNumNodelets = 4 // Number of nodelets for numeric labels
+
+	var ts, nts tags
+	for _, t := range n.tags {
+		if t.unit == "" {
+			ts = append(ts, t)
+		} else {
+			nts = append(nts, t)
+		}
+	}
+
+	// Select the top maxNodelets alphanumeric labels by weight
+	sort.Sort(ts)
+	if len(ts) > maxNodelets {
+		ts = ts[:maxNodelets]
+	}
+	for i, t := range ts {
+		weight := rpt.formatValue(t.weight)
+		dot += fmt.Sprintf(`N%d_%d [label = "%s" fontsize=8 shape=box3d tooltip="%s"]`+"\n", rIndex, i, t.name, weight)
+		dot += fmt.Sprintf(`N%d -> N%d_%d [label=" %s" weight=100 tooltip="\L" labeltooltip="\L"]`+"\n", rIndex, rIndex, i, weight)
+	}
+
+	// Collapse numeric labels into maxNumNodelets buckets, of the form:
+	// 1MB..2MB, 3MB..5MB, ...
+	nts = collapseTags(nts, maxNumNodelets)
+	sort.Sort(nts)
+	for i, t := range nts {
+		weight := rpt.formatValue(t.weight)
+		dot += fmt.Sprintf(`NN%d_%d [label = "%s" fontsize=8 shape=box3d tooltip="%s"]`+"\n", rIndex, i, t.name, weight)
+		dot += fmt.Sprintf(`N%d -> NN%d_%d [label=" %s" weight=100 tooltip="\L" labeltooltip="\L"]`+"\n", rIndex, rIndex, i, weight)
+	}
+
+	return dot
+}
+
+// graph summarizes a performance profile into a format that is
+// suitable for visualization.
+type graph struct {
+	ns nodes
+}
+
+// nodes is an ordered collection of graph nodes.
+type nodes []*node
+
+// tags represent sample annotations
+type tags []*tag
+type tagMap map[string]*tag
+
+type tag struct {
+	name   string
+	unit   string // Describe the value, "" for non-numeric tags
+	value  int64
+	weight int64
+}
+
+func (t tags) Len() int      { return len(t) }
+func (t tags) Swap(i, j int) { t[i], t[j] = t[j], t[i] }
+func (t tags) Less(i, j int) bool {
+	if t[i].weight == t[j].weight {
+		return t[i].name < t[j].name
+	}
+	return t[i].weight > t[j].weight
+}
+
+// node is an entry on a profiling report. It represents a unique
+// program location. It can include multiple names to represent
+// inlined functions.
+type node struct {
+	info nodeInfo // Information associated to this entry.
+
+	// values associated to this node.
+	// flat is exclusive to this node, cum includes all descendents.
+	flat, cum int64
+
+	// in and out contains the nodes immediately reaching or reached by this nodes.
+	in, out edgeMap
+
+	// tags provide additional information about subsets of a sample.
+	tags tagMap
+}
+
+func (ts tags) string() string {
+	var ret string
+	for _, s := range ts {
+		ret = ret + fmt.Sprintf("%s %s %d %d\n", s.name, s.unit, s.value, s.weight)
+	}
+	return ret
+}
+
+type nodeInfo struct {
+	name              string
+	origName          string
+	address           uint64
+	file              string
+	startLine, lineno int
+	inline            bool
+	lowPriority       bool
+	objfile           string
+	parent            *node // Used only if creating a calltree
+}
+
+func (n *node) addTags(s *profile.Sample, weight int64) {
+	// Add a tag with all string labels
+	var labels []string
+	for key, vals := range s.Label {
+		for _, v := range vals {
+			labels = append(labels, key+":"+v)
+		}
+	}
+	if len(labels) > 0 {
+		sort.Strings(labels)
+		l := n.tags.findOrAddTag(strings.Join(labels, `\n`), "", 0)
+		l.weight += weight
+	}
+
+	for key, nvals := range s.NumLabel {
+		for _, v := range nvals {
+			label := scaledValueLabel(v, key, "auto")
+			l := n.tags.findOrAddTag(label, key, v)
+			l.weight += weight
+		}
+	}
+}
+
+func (m tagMap) findOrAddTag(label, unit string, value int64) *tag {
+	if l := m[label]; l != nil {
+		return l
+	}
+	l := &tag{
+		name:  label,
+		unit:  unit,
+		value: value,
+	}
+	m[label] = l
+	return l
+}
+
+// collapseTags reduces the number of entries in a tagMap by merging
+// adjacent nodes into ranges. It uses a greedy approach to merge
+// starting with the entries with the lowest weight.
+func collapseTags(ts tags, count int) tags {
+	if len(ts) <= count {
+		return ts
+	}
+
+	sort.Sort(ts)
+	tagGroups := make([]tags, count)
+	for i, t := range ts[:count] {
+		tagGroups[i] = tags{t}
+	}
+	for _, t := range ts[count:] {
+		g, d := 0, tagDistance(t, tagGroups[0][0])
+		for i := 1; i < count; i++ {
+			if nd := tagDistance(t, tagGroups[i][0]); nd < d {
+				g, d = i, nd
+			}
+		}
+		tagGroups[g] = append(tagGroups[g], t)
+	}
+
+	var nts tags
+	for _, g := range tagGroups {
+		l, w := tagGroupLabel(g)
+		nts = append(nts, &tag{
+			name:   l,
+			weight: w,
+		})
+	}
+	return nts
+}
+
+func tagDistance(t, u *tag) float64 {
+	v, _ := ScaleValue(u.value, u.unit, t.unit)
+	if v < float64(t.value) {
+		return float64(t.value) - v
+	}
+	return v - float64(t.value)
+}
+
+func tagGroupLabel(g tags) (string, int64) {
+	if len(g) == 1 {
+		t := g[0]
+		return scaledValueLabel(t.value, t.unit, "auto"), t.weight
+	}
+	min := g[0]
+	max := g[0]
+	w := min.weight
+	for _, t := range g[1:] {
+		if v, _ := ScaleValue(t.value, t.unit, min.unit); int64(v) < min.value {
+			min = t
+		}
+		if v, _ := ScaleValue(t.value, t.unit, max.unit); int64(v) > max.value {
+			max = t
+		}
+		w += t.weight
+	}
+	return scaledValueLabel(min.value, min.unit, "auto") + ".." +
+		scaledValueLabel(max.value, max.unit, "auto"), w
+}
+
+// sumNodes adds the flat and sum values on a report.
+func sumNodes(ns nodes) (flat int64, cum int64) {
+	for _, n := range ns {
+		flat += n.flat
+		cum += n.cum
+	}
+	return
+}
+
+type edgeMap map[*node]*edgeInfo
+
+// edgeInfo contains any attributes to be represented about edges in a graph/
+type edgeInfo struct {
+	src, dest *node
+	// The summary weight of the edge
+	weight int64
+	// residual edges connect nodes that were connected through a
+	// separate node, which has been removed from the report.
+	residual bool
+}
+
+// bumpWeight increases the weight of an edge. If there isn't such an
+// edge in the map one is created.
+func bumpWeight(from, to *node, w int64, residual bool) {
+	if from.out[to] != to.in[from] {
+		panic(fmt.Errorf("asymmetric edges %v %v", *from, *to))
+	}
+
+	if n := from.out[to]; n != nil {
+		n.weight += w
+		if n.residual && !residual {
+			n.residual = false
+		}
+		return
+	}
+
+	info := &edgeInfo{src: from, dest: to, weight: w, residual: residual}
+	from.out[to] = info
+	to.in[from] = info
+}
+
+// Output formats.
+const (
+	Proto = iota
+	Dot
+	Tags
+	Tree
+	Text
+	Raw
+	Dis
+	List
+	WebList
+	Callgrind
+)
+
+// Options are the formatting and filtering options used to generate a
+// profile.
+type Options struct {
+	OutputFormat int
+
+	CumSort        bool
+	CallTree       bool
+	PrintAddresses bool
+	DropNegative   bool
+	Ratio          float64
+
+	NodeCount    int
+	NodeFraction float64
+	EdgeFraction float64
+
+	SampleType string
+	SampleUnit string // Unit for the sample data from the profile.
+	OutputUnit string // Units for data formatting in report.
+
+	Symbol *regexp.Regexp // Symbols to include on disassembly report.
+}
+
+// newGraph summarizes performance data from a profile into a graph.
+func newGraph(rpt *Report) (g graph, err error) {
+	prof := rpt.prof
+	o := rpt.options
+
+	// Generate a tree for graphical output if requested.
+	buildTree := o.CallTree && o.OutputFormat == Dot
+
+	locations := make(map[uint64][]nodeInfo)
+	for _, l := range prof.Location {
+		locations[l.ID] = newLocInfo(l)
+	}
+
+	nm := make(nodeMap)
+	for _, sample := range prof.Sample {
+		if sample.Location == nil {
+			continue
+		}
+
+		// Construct list of node names for sample.
+		var stack []nodeInfo
+		for _, loc := range sample.Location {
+			id := loc.ID
+			stack = append(stack, locations[id]...)
+		}
+
+		// Upfront pass to update the parent chains, to prevent the
+		// merging of nodes with different parents.
+		if buildTree {
+			var nn *node
+			for i := len(stack); i > 0; i-- {
+				n := &stack[i-1]
+				n.parent = nn
+				nn = nm.findOrInsertNode(*n)
+			}
+		}
+
+		leaf := nm.findOrInsertNode(stack[0])
+		weight := rpt.sampleValue(sample)
+		leaf.addTags(sample, weight)
+
+		// Aggregate counter data.
+		leaf.flat += weight
+		seen := make(map[*node]bool)
+		var nn *node
+		for _, s := range stack {
+			n := nm.findOrInsertNode(s)
+			if !seen[n] {
+				seen[n] = true
+				n.cum += weight
+
+				if nn != nil {
+					bumpWeight(n, nn, weight, false)
+				}
+			}
+			nn = n
+		}
+	}
+
+	// Collect new nodes into a report.
+	ns := make(nodes, 0, len(nm))
+	for _, n := range nm {
+		if rpt.options.DropNegative && n.flat < 0 {
+			continue
+		}
+		ns = append(ns, n)
+	}
+
+	return graph{ns}, nil
+}
+
+// Create a slice of formatted names for a location.
+func newLocInfo(l *profile.Location) []nodeInfo {
+	var objfile string
+
+	if m := l.Mapping; m != nil {
+		objfile = filepath.Base(m.File)
+	}
+
+	if len(l.Line) == 0 {
+		return []nodeInfo{
+			{
+				address: l.Address,
+				objfile: objfile,
+			},
+		}
+	}
+	var info []nodeInfo
+	numInlineFrames := len(l.Line) - 1
+	for li, line := range l.Line {
+		ni := nodeInfo{
+			address: l.Address,
+			lineno:  int(line.Line),
+			inline:  li < numInlineFrames,
+			objfile: objfile,
+		}
+
+		if line.Function != nil {
+			ni.name = line.Function.Name
+			ni.origName = line.Function.SystemName
+			ni.file = line.Function.Filename
+			ni.startLine = int(line.Function.StartLine)
+		}
+
+		info = append(info, ni)
+	}
+	return info
+}
+
+// nodeMap maps from a node info struct to a node. It is used to merge
+// report entries with the same info.
+type nodeMap map[nodeInfo]*node
+
+func (m nodeMap) findOrInsertNode(info nodeInfo) *node {
+	rr := m[info]
+	if rr == nil {
+		rr = &node{
+			info: info,
+			in:   make(edgeMap),
+			out:  make(edgeMap),
+			tags: make(map[string]*tag),
+		}
+		m[info] = rr
+	}
+	return rr
+}
+
+// preprocess does any required filtering/sorting according to the
+// report options. Returns the mapping from each node to any nodes
+// removed by path compression and statistics on the nodes/edges removed.
+func (g *graph) preprocess(rpt *Report) (origCount, droppedNodes, droppedEdges int) {
+	o := rpt.options
+
+	// Compute total weight of current set of nodes.
+	// This is <= rpt.total because of node filtering.
+	var totalValue int64
+	for _, n := range g.ns {
+		totalValue += n.flat
+	}
+
+	// Remove nodes with value <= total*nodeFraction
+	if nodeFraction := o.NodeFraction; nodeFraction > 0 {
+		var removed nodes
+		minValue := int64(float64(totalValue) * nodeFraction)
+		kept := make(nodes, 0, len(g.ns))
+		for _, n := range g.ns {
+			if n.cum < minValue {
+				removed = append(removed, n)
+			} else {
+				kept = append(kept, n)
+				tagsKept := make(map[string]*tag)
+				for s, t := range n.tags {
+					if t.weight >= minValue {
+						tagsKept[s] = t
+					}
+				}
+				n.tags = tagsKept
+			}
+		}
+		droppedNodes = len(removed)
+		removeNodes(removed, false, false)
+		g.ns = kept
+	}
+
+	// Remove edges below minimum frequency.
+	if edgeFraction := o.EdgeFraction; edgeFraction > 0 {
+		minEdge := int64(float64(totalValue) * edgeFraction)
+		for _, n := range g.ns {
+			for src, e := range n.in {
+				if e.weight < minEdge {
+					delete(n.in, src)
+					delete(src.out, n)
+					droppedEdges++
+				}
+			}
+		}
+	}
+
+	sortOrder := flatName
+	if o.CumSort {
+		// Force cum sorting for graph output, to preserve connectivity.
+		sortOrder = cumName
+	}
+
+	// Nodes that have flat==0 and a single in/out do not provide much
+	// information. Give them first chance to be removed. Do not consider edges
+	// from/to nodes that are expected to be removed.
+	maxNodes := o.NodeCount
+	if o.OutputFormat == Dot {
+		if maxNodes > 0 && maxNodes < len(g.ns) {
+			sortOrder = cumName
+			g.ns.sort(cumName)
+			cumCutoff := g.ns[maxNodes].cum
+			for _, n := range g.ns {
+				if n.flat == 0 {
+					if count := countEdges(n.out, cumCutoff); count > 1 {
+						continue
+					}
+					if count := countEdges(n.in, cumCutoff); count != 1 {
+						continue
+					}
+					n.info.lowPriority = true
+				}
+			}
+		}
+	}
+
+	g.ns.sort(sortOrder)
+	if maxNodes > 0 {
+		origCount = len(g.ns)
+		for index, nodes := 0, 0; index < len(g.ns); index++ {
+			nodes++
+			// For DOT output, count the tags as nodes since we will draw
+			// boxes for them.
+			if o.OutputFormat == Dot {
+				nodes += len(g.ns[index].tags)
+			}
+			if nodes > maxNodes {
+				// Trim to the top n nodes. Create dotted edges to bridge any
+				// broken connections.
+				removeNodes(g.ns[index:], true, true)
+				g.ns = g.ns[:index]
+				break
+			}
+		}
+	}
+	removeRedundantEdges(g.ns)
+
+	// Select best unit for profile output.
+	// Find the appropriate units for the smallest non-zero sample
+	if o.OutputUnit == "minimum" && len(g.ns) > 0 {
+		var maxValue, minValue int64
+
+		for _, n := range g.ns {
+			if n.flat > 0 && (minValue == 0 || n.flat < minValue) {
+				minValue = n.flat
+			}
+			if n.cum > maxValue {
+				maxValue = n.cum
+			}
+		}
+		if r := o.Ratio; r > 0 && r != 1 {
+			minValue = int64(float64(minValue) * r)
+			maxValue = int64(float64(maxValue) * r)
+		}
+
+		_, minUnit := ScaleValue(minValue, o.SampleUnit, "minimum")
+		_, maxUnit := ScaleValue(maxValue, o.SampleUnit, "minimum")
+
+		unit := minUnit
+		if minUnit != maxUnit && minValue*100 < maxValue && o.OutputFormat != Callgrind {
+			// Minimum and maximum values have different units. Scale
+			// minimum by 100 to use larger units, allowing minimum value to
+			// be scaled down to 0.01, except for callgrind reports since
+			// they can only represent integer values.
+			_, unit = ScaleValue(100*minValue, o.SampleUnit, "minimum")
+		}
+
+		if unit != "" {
+			o.OutputUnit = unit
+		} else {
+			o.OutputUnit = o.SampleUnit
+		}
+	}
+	return
+}
+
+// countEdges counts the number of edges below the specified cutoff.
+func countEdges(el edgeMap, cutoff int64) int {
+	count := 0
+	for _, e := range el {
+		if e.weight > cutoff {
+			count++
+		}
+	}
+	return count
+}
+
+// removeNodes removes nodes from a report, optionally bridging
+// connections between in/out edges and spreading out their weights
+// proportionally. residual marks new bridge edges as residual
+// (dotted).
+func removeNodes(toRemove nodes, bridge, residual bool) {
+	for _, n := range toRemove {
+		for ei := range n.in {
+			delete(ei.out, n)
+		}
+		if bridge {
+			for ei, wi := range n.in {
+				for eo, wo := range n.out {
+					var weight int64
+					if n.cum != 0 {
+						weight = int64(float64(wo.weight) * (float64(wi.weight) / float64(n.cum)))
+					}
+					bumpWeight(ei, eo, weight, residual)
+				}
+			}
+		}
+		for eo := range n.out {
+			delete(eo.in, n)
+		}
+	}
+}
+
+// removeRedundantEdges removes residual edges if the destination can
+// be reached through another path. This is done to simplify the graph
+// while preserving connectivity.
+func removeRedundantEdges(ns nodes) {
+	// Walk the nodes and outgoing edges in reverse order to prefer
+	// removing edges with the lowest weight.
+	for i := len(ns); i > 0; i-- {
+		n := ns[i-1]
+		in := sortedEdges(n.in)
+		for j := len(in); j > 0; j-- {
+			if e := in[j-1]; e.residual && isRedundant(e) {
+				delete(e.src.out, e.dest)
+				delete(e.dest.in, e.src)
+			}
+		}
+	}
+}
+
+// isRedundant determines if an edge can be removed without impacting
+// connectivity of the whole graph. This is implemented by checking if the
+// nodes have a common ancestor after removing the edge.
+func isRedundant(e *edgeInfo) bool {
+	destPred := predecessors(e, e.dest)
+	if len(destPred) == 1 {
+		return false
+	}
+	srcPred := predecessors(e, e.src)
+
+	for n := range srcPred {
+		if destPred[n] && n != e.dest {
+			return true
+		}
+	}
+	return false
+}
+
+// predecessors collects all the predecessors to node n, excluding edge e.
+func predecessors(e *edgeInfo, n *node) map[*node]bool {
+	seen := map[*node]bool{n: true}
+	queue := []*node{n}
+	for len(queue) > 0 {
+		n := queue[0]
+		queue = queue[1:]
+		for _, ie := range n.in {
+			if e == ie || seen[ie.src] {
+				continue
+			}
+			seen[ie.src] = true
+			queue = append(queue, ie.src)
+		}
+	}
+	return seen
+}
+
+// nodeSorter is a mechanism used to allow a report to be sorted
+// in different ways.
+type nodeSorter struct {
+	rs   nodes
+	less func(i, j int) bool
+}
+
+func (s nodeSorter) Len() int           { return len(s.rs) }
+func (s nodeSorter) Swap(i, j int)      { s.rs[i], s.rs[j] = s.rs[j], s.rs[i] }
+func (s nodeSorter) Less(i, j int) bool { return s.less(i, j) }
+
+type nodeOrder int
+
+const (
+	flatName nodeOrder = iota
+	flatCumName
+	cumName
+	nameOrder
+	fileOrder
+	addressOrder
+)
+
+// sort reoders the entries in a report based on the specified
+// ordering criteria. The result is sorted in decreasing order for
+// numeric quantities, alphabetically for text, and increasing for
+// addresses.
+func (ns nodes) sort(o nodeOrder) error {
+	var s nodeSorter
+
+	switch o {
+	case flatName:
+		s = nodeSorter{ns,
+			func(i, j int) bool {
+				if iv, jv := ns[i].flat, ns[j].flat; iv != jv {
+					return iv > jv
+				}
+				if ns[i].info.prettyName() != ns[j].info.prettyName() {
+					return ns[i].info.prettyName() < ns[j].info.prettyName()
+				}
+				iv, jv := ns[i].cum, ns[j].cum
+				return iv > jv
+			},
+		}
+	case flatCumName:
+		s = nodeSorter{ns,
+			func(i, j int) bool {
+				if iv, jv := ns[i].flat, ns[j].flat; iv != jv {
+					return iv > jv
+				}
+				if iv, jv := ns[i].cum, ns[j].cum; iv != jv {
+					return iv > jv
+				}
+				return ns[i].info.prettyName() < ns[j].info.prettyName()
+			},
+		}
+	case cumName:
+		s = nodeSorter{ns,
+			func(i, j int) bool {
+				if ns[i].info.lowPriority != ns[j].info.lowPriority {
+					return ns[j].info.lowPriority
+				}
+				if iv, jv := ns[i].cum, ns[j].cum; iv != jv {
+					return iv > jv
+				}
+				if ns[i].info.prettyName() != ns[j].info.prettyName() {
+					return ns[i].info.prettyName() < ns[j].info.prettyName()
+				}
+				iv, jv := ns[i].flat, ns[j].flat
+				return iv > jv
+			},
+		}
+	case nameOrder:
+		s = nodeSorter{ns,
+			func(i, j int) bool {
+				return ns[i].info.name < ns[j].info.name
+			},
+		}
+	case fileOrder:
+		s = nodeSorter{ns,
+			func(i, j int) bool {
+				return ns[i].info.file < ns[j].info.file
+			},
+		}
+	case addressOrder:
+		s = nodeSorter{ns,
+			func(i, j int) bool {
+				return ns[i].info.address < ns[j].info.address
+			},
+		}
+	default:
+		return fmt.Errorf("report: unrecognized sort ordering: %d", o)
+	}
+	sort.Sort(s)
+	return nil
+}
+
+type edgeList []*edgeInfo
+
+// sortedEdges return a slice of the edges in the map, sorted for
+// visualization. The sort order is first based on the edge weight
+// (higher-to-lower) and then by the node names to avoid flakiness.
+func sortedEdges(edges map[*node]*edgeInfo) edgeList {
+	el := make(edgeList, 0, len(edges))
+	for _, w := range edges {
+		el = append(el, w)
+	}
+
+	sort.Sort(el)
+	return el
+}
+
+func (el edgeList) Len() int {
+	return len(el)
+}
+
+func (el edgeList) Less(i, j int) bool {
+	if el[i].weight != el[j].weight {
+		return el[i].weight > el[j].weight
+	}
+
+	from1 := el[i].src.info.prettyName()
+	from2 := el[j].src.info.prettyName()
+	if from1 != from2 {
+		return from1 < from2
+	}
+
+	to1 := el[i].dest.info.prettyName()
+	to2 := el[j].dest.info.prettyName()
+
+	return to1 < to2
+}
+
+func (el edgeList) Swap(i, j int) {
+	el[i], el[j] = el[j], el[i]
+}
+
+func (el edgeList) sum() int64 {
+	var ret int64
+	for _, e := range el {
+		ret += e.weight
+	}
+	return ret
+}
+
+// ScaleValue reformats a value from a unit to a different unit.
+func ScaleValue(value int64, fromUnit, toUnit string) (sv float64, su string) {
+	// Avoid infinite recursion on overflow.
+	if value < 0 && -value > 0 {
+		v, u := ScaleValue(-value, fromUnit, toUnit)
+		return -v, u
+	}
+	if m, u, ok := memoryLabel(value, fromUnit, toUnit); ok {
+		return m, u
+	}
+	if t, u, ok := timeLabel(value, fromUnit, toUnit); ok {
+		return t, u
+	}
+	// Skip non-interesting units.
+	switch toUnit {
+	case "count", "sample", "unit", "minimum":
+		return float64(value), ""
+	default:
+		return float64(value), toUnit
+	}
+}
+
+func scaledValueLabel(value int64, fromUnit, toUnit string) string {
+	v, u := ScaleValue(value, fromUnit, toUnit)
+
+	sv := strings.TrimSuffix(fmt.Sprintf("%.2f", v), ".00")
+	if sv == "0" || sv == "-0" {
+		return "0"
+	}
+	return sv + u
+}
+
+func memoryLabel(value int64, fromUnit, toUnit string) (v float64, u string, ok bool) {
+	fromUnit = strings.TrimSuffix(strings.ToLower(fromUnit), "s")
+	toUnit = strings.TrimSuffix(strings.ToLower(toUnit), "s")
+
+	switch fromUnit {
+	case "byte", "b":
+	case "kilobyte", "kb":
+		value *= 1024
+	case "megabyte", "mb":
+		value *= 1024 * 1024
+	case "gigabyte", "gb":
+		value *= 1024 * 1024
+	default:
+		return 0, "", false
+	}
+
+	if toUnit == "minimum" || toUnit == "auto" {
+		switch {
+		case value < 1024:
+			toUnit = "b"
+		case value < 1024*1024:
+			toUnit = "kb"
+		case value < 1024*1024*1024:
+			toUnit = "mb"
+		default:
+			toUnit = "gb"
+		}
+	}
+
+	var output float64
+	switch toUnit {
+	default:
+		output, toUnit = float64(value), "B"
+	case "kb", "kbyte", "kilobyte":
+		output, toUnit = float64(value)/1024, "kB"
+	case "mb", "mbyte", "megabyte":
+		output, toUnit = float64(value)/(1024*1024), "MB"
+	case "gb", "gbyte", "giggabyte":
+		output, toUnit = float64(value)/(1024*1024*1024), "GB"
+	}
+	return output, toUnit, true
+}
+
+func timeLabel(value int64, fromUnit, toUnit string) (v float64, u string, ok bool) {
+	fromUnit = strings.ToLower(fromUnit)
+	if len(fromUnit) > 2 {
+		fromUnit = strings.TrimSuffix(fromUnit, "s")
+	}
+
+	toUnit = strings.ToLower(toUnit)
+	if len(toUnit) > 2 {
+		toUnit = strings.TrimSuffix(toUnit, "s")
+	}
+
+	var d time.Duration
+	switch fromUnit {
+	case "nanosecond", "ns":
+		d = time.Duration(value) * time.Nanosecond
+	case "microsecond":
+		d = time.Duration(value) * time.Microsecond
+	case "millisecond", "ms":
+		d = time.Duration(value) * time.Millisecond
+	case "second", "sec":
+		d = time.Duration(value) * time.Second
+	case "cycle":
+		return float64(value), "", true
+	default:
+		return 0, "", false
+	}
+
+	if toUnit == "minimum" || toUnit == "auto" {
+		switch {
+		case d < 1*time.Microsecond:
+			toUnit = "ns"
+		case d < 1*time.Millisecond:
+			toUnit = "us"
+		case d < 1*time.Second:
+			toUnit = "ms"
+		case d < 1*time.Minute:
+			toUnit = "sec"
+		case d < 1*time.Hour:
+			toUnit = "min"
+		case d < 24*time.Hour:
+			toUnit = "hour"
+		case d < 15*24*time.Hour:
+			toUnit = "day"
+		case d < 120*24*time.Hour:
+			toUnit = "week"
+		default:
+			toUnit = "year"
+		}
+	}
+
+	var output float64
+	dd := float64(d)
+	switch toUnit {
+	case "ns", "nanosecond":
+		output, toUnit = dd/float64(time.Nanosecond), "ns"
+	case "us", "microsecond":
+		output, toUnit = dd/float64(time.Microsecond), "us"
+	case "ms", "millisecond":
+		output, toUnit = dd/float64(time.Millisecond), "ms"
+	case "min", "minute":
+		output, toUnit = dd/float64(time.Minute), "mins"
+	case "hour", "hr":
+		output, toUnit = dd/float64(time.Hour), "hrs"
+	case "day":
+		output, toUnit = dd/float64(24*time.Hour), "days"
+	case "week", "wk":
+		output, toUnit = dd/float64(7*24*time.Hour), "wks"
+	case "year", "yr":
+		output, toUnit = dd/float64(365*7*24*time.Hour), "yrs"
+	default:
+		fallthrough
+	case "sec", "second", "s":
+		output, toUnit = dd/float64(time.Second), "s"
+	}
+	return output, toUnit, true
+}
+
+// prettyName determines the printable name to be used for a node.
+func (info *nodeInfo) prettyName() string {
+	var name string
+	if info.address != 0 {
+		name = fmt.Sprintf("%016x", info.address)
+	}
+
+	if info.name != "" {
+		name = name + " " + info.name
+	}
+
+	if info.file != "" {
+		name += " " + trimPath(info.file)
+		if info.lineno != 0 {
+			name += fmt.Sprintf(":%d", info.lineno)
+		}
+	}
+
+	if info.inline {
+		name = name + " (inline)"
+	}
+
+	if name = strings.TrimSpace(name); name == "" && info.objfile != "" {
+		name = "[" + info.objfile + "]"
+	}
+	return name
+}
+
+// New builds a new report indexing the sample values interpreting the
+// samples with the provided function.
+func New(prof *profile.Profile, options Options, value func(s *profile.Sample) int64, unit string) *Report {
+	o := &options
+	if o.SampleUnit == "" {
+		o.SampleUnit = unit
+	}
+	format := func(v int64) string {
+		if r := o.Ratio; r > 0 && r != 1 {
+			fv := float64(v) * r
+			v = int64(fv)
+		}
+		return scaledValueLabel(v, o.SampleUnit, o.OutputUnit)
+	}
+	return &Report{prof, computeTotal(prof, value), o, value, format}
+}
+
+// NewDefault builds a new report indexing the sample values with the
+// last value available.
+func NewDefault(prof *profile.Profile, options Options) *Report {
+	index := len(prof.SampleType) - 1
+	o := &options
+	if o.SampleUnit == "" {
+		o.SampleUnit = strings.ToLower(prof.SampleType[index].Unit)
+	}
+	value := func(s *profile.Sample) int64 {
+		return s.Value[index]
+	}
+	format := func(v int64) string {
+		if r := o.Ratio; r > 0 && r != 1 {
+			fv := float64(v) * r
+			v = int64(fv)
+		}
+		return scaledValueLabel(v, o.SampleUnit, o.OutputUnit)
+	}
+	return &Report{prof, computeTotal(prof, value), o, value, format}
+}
+
+func computeTotal(prof *profile.Profile, value func(s *profile.Sample) int64) int64 {
+	var ret int64
+	for _, sample := range prof.Sample {
+		ret += value(sample)
+	}
+	return ret
+}
+
+// Report contains the data and associated routines to extract a
+// report from a profile.
+type Report struct {
+	prof        *profile.Profile
+	total       int64
+	options     *Options
+	sampleValue func(*profile.Sample) int64
+	formatValue func(int64) string
+}
+
+func (rpt *Report) formatTags(s *profile.Sample) (string, bool) {
+	var labels []string
+	for key, vals := range s.Label {
+		for _, v := range vals {
+			labels = append(labels, key+":"+v)
+		}
+	}
+	for key, nvals := range s.NumLabel {
+		for _, v := range nvals {
+			labels = append(labels, scaledValueLabel(v, key, "auto"))
+		}
+	}
+	if len(labels) == 0 {
+		return "", false
+	}
+	sort.Strings(labels)
+	return strings.Join(labels, `\n`), true
+}
diff --git a/src/cmd/pprof/internal/report/source.go b/src/cmd/pprof/internal/report/source.go
new file mode 100644
index 0000000..57300dd
--- /dev/null
+++ b/src/cmd/pprof/internal/report/source.go
@@ -0,0 +1,450 @@
+// 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 report
+
+// This file contains routines related to the generation of annotated
+// source listings.
+
+import (
+	"bufio"
+	"fmt"
+	"html/template"
+	"io"
+	"os"
+	"path/filepath"
+	"sort"
+	"strconv"
+	"strings"
+
+	"cmd/pprof/internal/plugin"
+)
+
+// printSource prints an annotated source listing, include all
+// functions with samples that match the regexp rpt.options.symbol.
+// The sources are sorted by function name and then by filename to
+// eliminate potential nondeterminism.
+func printSource(w io.Writer, rpt *Report) error {
+	o := rpt.options
+	g, err := newGraph(rpt)
+	if err != nil {
+		return err
+	}
+
+	// Identify all the functions that match the regexp provided.
+	// Group nodes for each matching function.
+	var functions nodes
+	functionNodes := make(map[string]nodes)
+	for _, n := range g.ns {
+		if !o.Symbol.MatchString(n.info.name) {
+			continue
+		}
+		if functionNodes[n.info.name] == nil {
+			functions = append(functions, n)
+		}
+		functionNodes[n.info.name] = append(functionNodes[n.info.name], n)
+	}
+	functions.sort(nameOrder)
+
+	fmt.Fprintf(w, "Total: %s\n", rpt.formatValue(rpt.total))
+	for _, fn := range functions {
+		name := fn.info.name
+
+		// Identify all the source files associated to this function.
+		// Group nodes for each source file.
+		var sourceFiles nodes
+		fileNodes := make(map[string]nodes)
+		for _, n := range functionNodes[name] {
+			if n.info.file == "" {
+				continue
+			}
+			if fileNodes[n.info.file] == nil {
+				sourceFiles = append(sourceFiles, n)
+			}
+			fileNodes[n.info.file] = append(fileNodes[n.info.file], n)
+		}
+
+		if len(sourceFiles) == 0 {
+			fmt.Printf("No source information for %s\n", name)
+			continue
+		}
+
+		sourceFiles.sort(fileOrder)
+
+		// Print each file associated with this function.
+		for _, fl := range sourceFiles {
+			filename := fl.info.file
+			fns := fileNodes[filename]
+			flatSum, cumSum := sumNodes(fns)
+
+			fnodes, path, err := getFunctionSource(name, filename, fns, 0, 0)
+			fmt.Fprintf(w, "ROUTINE ======================== %s in %s\n", name, path)
+			fmt.Fprintf(w, "%10s %10s (flat, cum) %s of Total\n",
+				rpt.formatValue(flatSum), rpt.formatValue(cumSum),
+				percentage(cumSum, rpt.total))
+
+			if err != nil {
+				fmt.Fprintf(w, " Error: %v\n", err)
+				continue
+			}
+
+			for _, fn := range fnodes {
+				fmt.Fprintf(w, "%10s %10s %6d:%s\n", valueOrDot(fn.flat, rpt), valueOrDot(fn.cum, rpt), fn.info.lineno, fn.info.name)
+			}
+		}
+	}
+	return nil
+}
+
+// printWebSource prints an annotated source listing, include all
+// functions with samples that match the regexp rpt.options.symbol.
+func printWebSource(w io.Writer, rpt *Report, obj plugin.ObjTool) error {
+	o := rpt.options
+	g, err := newGraph(rpt)
+	if err != nil {
+		return err
+	}
+
+	// If the regexp source can be parsed as an address, also match
+	// functions that land on that address.
+	var address *uint64
+	if hex, err := strconv.ParseUint(o.Symbol.String(), 0, 64); err == nil {
+		address = &hex
+	}
+
+	// Extract interesting symbols from binary files in the profile and
+	// classify samples per symbol.
+	symbols := symbolsFromBinaries(rpt.prof, g, o.Symbol, address, obj)
+	symNodes := nodesPerSymbol(g.ns, symbols)
+
+	// Sort symbols for printing.
+	var syms objSymbols
+	for s := range symNodes {
+		syms = append(syms, s)
+	}
+	sort.Sort(syms)
+
+	if len(syms) == 0 {
+		return fmt.Errorf("no samples found on routines matching: %s", o.Symbol.String())
+	}
+
+	printHeader(w, rpt)
+	for _, s := range syms {
+		name := s.sym.Name[0]
+		// Identify sources associated to a symbol by examining
+		// symbol samples. Classify samples per source file.
+		var sourceFiles nodes
+		fileNodes := make(map[string]nodes)
+		for _, n := range symNodes[s] {
+			if n.info.file == "" {
+				continue
+			}
+			if fileNodes[n.info.file] == nil {
+				sourceFiles = append(sourceFiles, n)
+			}
+			fileNodes[n.info.file] = append(fileNodes[n.info.file], n)
+		}
+
+		if len(sourceFiles) == 0 {
+			fmt.Printf("No source information for %s\n", name)
+			continue
+		}
+
+		sourceFiles.sort(fileOrder)
+
+		// Print each file associated with this function.
+		for _, fl := range sourceFiles {
+			filename := fl.info.file
+			fns := fileNodes[filename]
+
+			asm := assemblyPerSourceLine(symbols, fns, filename, obj)
+			start, end := sourceCoordinates(asm)
+
+			fnodes, path, err := getFunctionSource(name, filename, fns, start, end)
+			if err != nil {
+				fnodes, path = getMissingFunctionSource(filename, asm, start, end)
+			}
+
+			flatSum, cumSum := sumNodes(fnodes)
+			printFunctionHeader(w, name, path, flatSum, cumSum, rpt)
+			for _, fn := range fnodes {
+				printFunctionSourceLine(w, fn, asm[fn.info.lineno], rpt)
+			}
+			printFunctionClosing(w)
+		}
+	}
+	printPageClosing(w)
+	return nil
+}
+
+// sourceCoordinates returns the lowest and highest line numbers from
+// a set of assembly statements.
+func sourceCoordinates(asm map[int]nodes) (start, end int) {
+	for l := range asm {
+		if start == 0 || l < start {
+			start = l
+		}
+		if end == 0 || l > end {
+			end = l
+		}
+	}
+	return start, end
+}
+
+// assemblyPerSourceLine disassembles the binary containing a symbol
+// and classifies the assembly instructions according to its
+// corresponding source line, annotating them with a set of samples.
+func assemblyPerSourceLine(objSyms []*objSymbol, rs nodes, src string, obj plugin.ObjTool) map[int]nodes {
+	assembly := make(map[int]nodes)
+	// Identify symbol to use for this collection of samples.
+	o := findMatchingSymbol(objSyms, rs)
+	if o == nil {
+		return assembly
+	}
+
+	// Extract assembly for matched symbol
+	insns, err := obj.Disasm(o.sym.File, o.sym.Start, o.sym.End)
+	if err != nil {
+		return assembly
+	}
+
+	srcBase := filepath.Base(src)
+	anodes := annotateAssembly(insns, rs, o.base)
+	var lineno = 0
+	for _, an := range anodes {
+		if filepath.Base(an.info.file) == srcBase {
+			lineno = an.info.lineno
+		}
+		if lineno != 0 {
+			assembly[lineno] = append(assembly[lineno], an)
+		}
+	}
+
+	return assembly
+}
+
+// findMatchingSymbol looks for the symbol that corresponds to a set
+// of samples, by comparing their addresses.
+func findMatchingSymbol(objSyms []*objSymbol, ns nodes) *objSymbol {
+	for _, n := range ns {
+		for _, o := range objSyms {
+			if filepath.Base(o.sym.File) == n.info.objfile &&
+				o.sym.Start <= n.info.address-o.base &&
+				n.info.address-o.base <= o.sym.End {
+				return o
+			}
+		}
+	}
+	return nil
+}
+
+// printHeader prints the page header for a weblist report.
+func printHeader(w io.Writer, rpt *Report) {
+	fmt.Fprintln(w, weblistPageHeader)
+
+	var labels []string
+	for _, l := range legendLabels(rpt) {
+		labels = append(labels, template.HTMLEscapeString(l))
+	}
+
+	fmt.Fprintf(w, `<div class="legend">%s<br>Total: %s</div>`,
+		strings.Join(labels, "<br>\n"),
+		rpt.formatValue(rpt.total),
+	)
+}
+
+// printFunctionHeader prints a function header for a weblist report.
+func printFunctionHeader(w io.Writer, name, path string, flatSum, cumSum int64, rpt *Report) {
+	fmt.Fprintf(w, `<h1>%s</h1>%s
+<pre onClick="pprof_toggle_asm()">
+  Total:  %10s %10s (flat, cum) %s
+`,
+		template.HTMLEscapeString(name), template.HTMLEscapeString(path),
+		rpt.formatValue(flatSum), rpt.formatValue(cumSum),
+		percentage(cumSum, rpt.total))
+}
+
+// printFunctionSourceLine prints a source line and the corresponding assembly.
+func printFunctionSourceLine(w io.Writer, fn *node, assembly nodes, rpt *Report) {
+	if len(assembly) == 0 {
+		fmt.Fprintf(w,
+			"<span class=line> %6d</span> <span class=nop>  %10s %10s %s </span>\n",
+			fn.info.lineno,
+			valueOrDot(fn.flat, rpt), valueOrDot(fn.cum, rpt),
+			template.HTMLEscapeString(fn.info.name))
+		return
+	}
+
+	fmt.Fprintf(w,
+		"<span class=line> %6d</span> <span class=deadsrc>  %10s %10s %s </span>",
+		fn.info.lineno,
+		valueOrDot(fn.flat, rpt), valueOrDot(fn.cum, rpt),
+		template.HTMLEscapeString(fn.info.name))
+	fmt.Fprint(w, "<span class=asm>")
+	for _, an := range assembly {
+		var fileline string
+		class := "disasmloc"
+		if an.info.file != "" {
+			fileline = fmt.Sprintf("%s:%d", template.HTMLEscapeString(an.info.file), an.info.lineno)
+			if an.info.lineno != fn.info.lineno {
+				class = "unimportant"
+			}
+		}
+		fmt.Fprintf(w, " %8s %10s %10s %8x: %-48s <span class=%s>%s</span>\n", "",
+			valueOrDot(an.flat, rpt), valueOrDot(an.cum, rpt),
+			an.info.address,
+			template.HTMLEscapeString(an.info.name),
+			class,
+			template.HTMLEscapeString(fileline))
+	}
+	fmt.Fprintln(w, "</span>")
+}
+
+// printFunctionClosing prints the end of a function in a weblist report.
+func printFunctionClosing(w io.Writer) {
+	fmt.Fprintln(w, "</pre>")
+}
+
+// printPageClosing prints the end of the page in a weblist report.
+func printPageClosing(w io.Writer) {
+	fmt.Fprintln(w, weblistPageClosing)
+}
+
+// getFunctionSource collects the sources of a function from a source
+// file and annotates it with the samples in fns. Returns the sources
+// as nodes, using the info.name field to hold the source code.
+func getFunctionSource(fun, file string, fns nodes, start, end int) (nodes, string, error) {
+	f, file, err := adjustSourcePath(file)
+	if err != nil {
+		return nil, file, err
+	}
+
+	lineNodes := make(map[int]nodes)
+
+	// Collect source coordinates from profile.
+	const margin = 5 // Lines before first/after last sample.
+	if start == 0 {
+		if fns[0].info.startLine != 0 {
+			start = fns[0].info.startLine
+		} else {
+			start = fns[0].info.lineno - margin
+		}
+	} else {
+		start -= margin
+	}
+	if end == 0 {
+		end = fns[0].info.lineno
+	}
+	end += margin
+	for _, n := range fns {
+		lineno := n.info.lineno
+		nodeStart := n.info.startLine
+		if nodeStart == 0 {
+			nodeStart = lineno - margin
+		}
+		nodeEnd := lineno + margin
+		if nodeStart < start {
+			start = nodeStart
+		} else if nodeEnd > end {
+			end = nodeEnd
+		}
+		lineNodes[lineno] = append(lineNodes[lineno], n)
+	}
+
+	var src nodes
+	buf := bufio.NewReader(f)
+	lineno := 1
+	for {
+		line, err := buf.ReadString('\n')
+		if err != nil {
+			if line == "" || err != io.EOF {
+				return nil, file, err
+			}
+		}
+		if lineno >= start {
+			flat, cum := sumNodes(lineNodes[lineno])
+
+			src = append(src, &node{
+				info: nodeInfo{
+					name:   strings.TrimRight(line, "\n"),
+					lineno: lineno,
+				},
+				flat: flat,
+				cum:  cum,
+			})
+		}
+		lineno++
+		if lineno > end {
+			break
+		}
+	}
+	return src, file, nil
+}
+
+// getMissingFunctionSource creates a dummy function body to point to
+// the source file and annotates it with the samples in asm.
+func getMissingFunctionSource(filename string, asm map[int]nodes, start, end int) (nodes, string) {
+	var fnodes nodes
+	for i := start; i <= end; i++ {
+		lrs := asm[i]
+		if len(lrs) == 0 {
+			continue
+		}
+		flat, cum := sumNodes(lrs)
+		fnodes = append(fnodes, &node{
+			info: nodeInfo{
+				name:   "???",
+				lineno: i,
+			},
+			flat: flat,
+			cum:  cum,
+		})
+	}
+	return fnodes, filename
+}
+
+// adjustSourcePath adjusts the pathe for a source file by trimmming
+// known prefixes and searching for the file on all parents of the
+// current working dir.
+func adjustSourcePath(path string) (*os.File, string, error) {
+	path = trimPath(path)
+	f, err := os.Open(path)
+	if err == nil {
+		return f, path, nil
+	}
+
+	if dir, wderr := os.Getwd(); wderr == nil {
+		for {
+			parent := filepath.Dir(dir)
+			if parent == dir {
+				break
+			}
+			if f, err := os.Open(filepath.Join(parent, path)); err == nil {
+				return f, filepath.Join(parent, path), nil
+			}
+
+			dir = parent
+		}
+	}
+
+	return nil, path, err
+}
+
+// trimPath cleans up a path by removing prefixes that are commonly
+// found on profiles.
+func trimPath(path string) string {
+	basePaths := []string{
+		"/proc/self/cwd/./",
+		"/proc/self/cwd/",
+	}
+
+	sPath := filepath.ToSlash(path)
+
+	for _, base := range basePaths {
+		if strings.HasPrefix(sPath, base) {
+			return filepath.FromSlash(sPath[len(base):])
+		}
+	}
+	return path
+}
diff --git a/src/cmd/pprof/internal/report/source_html.go b/src/cmd/pprof/internal/report/source_html.go
new file mode 100644
index 0000000..267fabd
--- /dev/null
+++ b/src/cmd/pprof/internal/report/source_html.go
@@ -0,0 +1,77 @@
+// 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 report
+
+const weblistPageHeader = `
+<!DOCTYPE html>
+<html>
+<head>
+<title>Pprof listing</title>
+<style type="text/css">
+body {
+font-family: sans-serif;
+}
+h1 {
+  font-size: 1.5em;
+  margin-bottom: 4px;
+}
+.legend {
+  font-size: 1.25em;
+}
+.line {
+color: #aaaaaa;
+}
+.nop {
+color: #aaaaaa;
+}
+.unimportant {
+color: #cccccc;
+}
+.disasmloc {
+color: #000000;
+}
+.deadsrc {
+cursor: pointer;
+}
+.deadsrc:hover {
+background-color: #eeeeee;
+}
+.livesrc {
+color: #0000ff;
+cursor: pointer;
+}
+.livesrc:hover {
+background-color: #eeeeee;
+}
+.asm {
+color: #008800;
+display: none;
+}
+</style>
+<script type="text/javascript">
+function pprof_toggle_asm(e) {
+  var target;
+  if (!e) e = window.event;
+  if (e.target) target = e.target;
+  else if (e.srcElement) target = e.srcElement;
+
+  if (target) {
+    var asm = target.nextSibling;
+    if (asm && asm.className == "asm") {
+      asm.style.display = (asm.style.display == "block" ? "" : "block");
+      e.preventDefault();
+      return false;
+    }
+  }
+}
+</script>
+</head>
+<body>
+`
+
+const weblistPageClosing = `
+</body>
+</html>
+`
diff --git a/src/cmd/pprof/internal/svg/svg.go b/src/cmd/pprof/internal/svg/svg.go
new file mode 100644
index 0000000..aa65a1a
--- /dev/null
+++ b/src/cmd/pprof/internal/svg/svg.go
@@ -0,0 +1,75 @@
+// 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 svg provides tools related to handling of SVG files
+package svg
+
+import (
+	"bytes"
+	"regexp"
+	"strings"
+)
+
+var (
+	viewBox  = regexp.MustCompile(`<svg\s*width="[^"]+"\s*height="[^"]+"\s*viewBox="[^"]+"`)
+	graphId  = regexp.MustCompile(`<g id="graph\d"`)
+	svgClose = regexp.MustCompile(`</svg>`)
+)
+
+// Massage enhances the SVG output from DOT to provide bettern
+// panning inside a web browser. It uses the SVGPan library, which is
+// accessed through the svgPan URL.
+func Massage(in bytes.Buffer, svgPan string) string {
+	svg := string(in.Bytes())
+
+	// Work around for dot bug which misses quoting some ampersands,
+	// resulting on unparsable SVG.
+	svg = strings.Replace(svg, "&;", "&;", -1)
+	if svgPan == "" {
+		return svg
+	}
+
+	//Dot's SVG output is
+	//
+	//    <svg width="___" height="___"
+	//     viewBox="___" xmlns=...>
+	//    <g id="graph0" transform="...">
+	//    ...
+	//    </g>
+	//    </svg>
+	//
+	// Change it to
+	//
+	//    <svg width="100%" height="100%"
+	//     xmlns=...>
+	//    <script xlink:href=" ...$svgpan.. "/>
+
+	//    <g id="viewport" transform="translate(0,0)">
+	//    <g id="graph0" transform="...">
+	//    ...
+	//    </g>
+	//    </g>
+	//    </svg>
+
+	if loc := viewBox.FindStringIndex(svg); loc != nil {
+		svg = svg[:loc[0]] +
+			`<svg width="100%" height="100%"` +
+			svg[loc[1]:]
+	}
+
+	if loc := graphId.FindStringIndex(svg); loc != nil {
+		svg = svg[:loc[0]] +
+			`<script xlink:href="` + svgPan + `"/>` +
+			`<g id="viewport" transform="scale(0.5,0.5) translate(0,0)">` +
+			svg[loc[0]:]
+	}
+
+	if loc := svgClose.FindStringIndex(svg); loc != nil {
+		svg = svg[:loc[0]] +
+			`</g>` +
+			svg[loc[0]:]
+	}
+
+	return svg
+}
diff --git a/src/cmd/pprof/internal/symbolizer/symbolizer.go b/src/cmd/pprof/internal/symbolizer/symbolizer.go
new file mode 100644
index 0000000..86de564
--- /dev/null
+++ b/src/cmd/pprof/internal/symbolizer/symbolizer.go
@@ -0,0 +1,195 @@
+// 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 symbolizer provides a routine to populate a profile with
+// symbol, file and line number information. It relies on the
+// addr2liner and demangler packages to do the actual work.
+package symbolizer
+
+import (
+	"fmt"
+	"os"
+	"path/filepath"
+	"strings"
+
+	"cmd/pprof/internal/plugin"
+	"cmd/pprof/internal/profile"
+)
+
+// Symbolize adds symbol and line number information to all locations
+// in a profile. mode enables some options to control
+// symbolization. Currently only recognizes "force", which causes it
+// to overwrite any existing data.
+func Symbolize(mode string, prof *profile.Profile, obj plugin.ObjTool, ui plugin.UI) error {
+	force := false
+	// Disable some mechanisms based on mode string.
+	for _, o := range strings.Split(strings.ToLower(mode), ":") {
+		switch o {
+		case "force":
+			force = true
+		default:
+		}
+	}
+
+	if len(prof.Mapping) == 0 {
+		return fmt.Errorf("no known mappings")
+	}
+
+	mt, err := newMapping(prof, obj, ui, force)
+	if err != nil {
+		return err
+	}
+	defer mt.close()
+
+	functions := make(map[profile.Function]*profile.Function)
+	for _, l := range mt.prof.Location {
+		m := l.Mapping
+		segment := mt.segments[m]
+		if segment == nil {
+			// Nothing to do
+			continue
+		}
+
+		stack, err := segment.SourceLine(l.Address)
+		if err != nil || len(stack) == 0 {
+			// No answers from addr2line
+			continue
+		}
+
+		l.Line = make([]profile.Line, len(stack))
+		for i, frame := range stack {
+			if frame.Func != "" {
+				m.HasFunctions = true
+			}
+			if frame.File != "" {
+				m.HasFilenames = true
+			}
+			if frame.Line != 0 {
+				m.HasLineNumbers = true
+			}
+			f := &profile.Function{
+				Name:       frame.Func,
+				SystemName: frame.Func,
+				Filename:   frame.File,
+			}
+			if fp := functions[*f]; fp != nil {
+				f = fp
+			} else {
+				functions[*f] = f
+				f.ID = uint64(len(mt.prof.Function)) + 1
+				mt.prof.Function = append(mt.prof.Function, f)
+			}
+			l.Line[i] = profile.Line{
+				Function: f,
+				Line:     int64(frame.Line),
+			}
+		}
+
+		if len(stack) > 0 {
+			m.HasInlineFrames = true
+		}
+	}
+	return nil
+}
+
+// newMapping creates a mappingTable for a profile.
+func newMapping(prof *profile.Profile, obj plugin.ObjTool, ui plugin.UI, force bool) (*mappingTable, error) {
+	mt := &mappingTable{
+		prof:     prof,
+		segments: make(map[*profile.Mapping]plugin.ObjFile),
+	}
+
+	// Identify used mappings
+	mappings := make(map[*profile.Mapping]bool)
+	for _, l := range prof.Location {
+		mappings[l.Mapping] = true
+	}
+
+	for _, m := range prof.Mapping {
+		if !mappings[m] {
+			continue
+		}
+		// Do not attempt to re-symbolize a mapping that has already been symbolized.
+		if !force && (m.HasFunctions || m.HasFilenames || m.HasLineNumbers) {
+			continue
+		}
+
+		f, err := locateFile(obj, m.File, m.BuildID, m.Start)
+		if err != nil {
+			ui.PrintErr("Local symbolization failed for ", filepath.Base(m.File), ": ", err)
+			// Move on to other mappings
+			continue
+		}
+
+		if fid := f.BuildID(); m.BuildID != "" && fid != "" && fid != m.BuildID {
+			// Build ID mismatch - ignore.
+			f.Close()
+			continue
+		}
+
+		mt.segments[m] = f
+	}
+
+	return mt, nil
+}
+
+// locateFile opens a local file for symbolization on the search path
+// at $PPROF_BINARY_PATH. Looks inside these directories for files
+// named $BUILDID/$BASENAME and $BASENAME (if build id is available).
+func locateFile(obj plugin.ObjTool, file, buildID string, start uint64) (plugin.ObjFile, error) {
+	// Construct search path to examine
+	searchPath := os.Getenv("PPROF_BINARY_PATH")
+	if searchPath == "" {
+		// Use $HOME/pprof/binaries as default directory for local symbolization binaries
+		searchPath = filepath.Join(os.Getenv("HOME"), "pprof", "binaries")
+	}
+
+	// Collect names to search: {buildid/basename, basename}
+	var fileNames []string
+	if baseName := filepath.Base(file); buildID != "" {
+		fileNames = []string{filepath.Join(buildID, baseName), baseName}
+	} else {
+		fileNames = []string{baseName}
+	}
+	for _, path := range filepath.SplitList(searchPath) {
+		for nameIndex, name := range fileNames {
+			file := filepath.Join(path, name)
+			if f, err := obj.Open(file, start); err == nil {
+				fileBuildID := f.BuildID()
+				if buildID == "" || buildID == fileBuildID {
+					return f, nil
+				}
+				f.Close()
+				if nameIndex == 0 {
+					// If this is the first name, the path includes the build id. Report inconsistency.
+					return nil, fmt.Errorf("found file %s with inconsistent build id %s", file, fileBuildID)
+				}
+			}
+		}
+	}
+	// Try original file name
+	f, err := obj.Open(file, start)
+	if err == nil && buildID != "" {
+		if fileBuildID := f.BuildID(); fileBuildID != "" && fileBuildID != buildID {
+			// Mismatched build IDs, ignore
+			f.Close()
+			return nil, fmt.Errorf("mismatched build ids %s != %s", fileBuildID, buildID)
+		}
+	}
+	return f, err
+}
+
+// mappingTable contains the mechanisms for symbolization of a
+// profile.
+type mappingTable struct {
+	prof     *profile.Profile
+	segments map[*profile.Mapping]plugin.ObjFile
+}
+
+// Close releases any external processes being used for the mapping.
+func (mt *mappingTable) close() {
+	for _, segment := range mt.segments {
+		segment.Close()
+	}
+}
diff --git a/src/cmd/pprof/internal/symbolz/symbolz.go b/src/cmd/pprof/internal/symbolz/symbolz.go
new file mode 100644
index 0000000..c81e522
--- /dev/null
+++ b/src/cmd/pprof/internal/symbolz/symbolz.go
@@ -0,0 +1,111 @@
+// 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 symbolz symbolizes a profile using the output from the symbolz
+// service.
+package symbolz
+
+import (
+	"bytes"
+	"fmt"
+	"io"
+	"net/url"
+	"regexp"
+	"strconv"
+	"strings"
+
+	"cmd/pprof/internal/profile"
+)
+
+var (
+	symbolzRE = regexp.MustCompile(`(0x[[:xdigit:]]+)\s+(.*)`)
+)
+
+// Symbolize symbolizes profile p by parsing data returned by a
+// symbolz handler. syms receives the symbolz query (hex addresses
+// separated by '+') and returns the symbolz output in a string.  It
+// symbolizes all locations based on their addresses, regardless of
+// mapping.
+func Symbolize(source string, syms func(string, string) ([]byte, error), p *profile.Profile) error {
+	if source = symbolz(source, p); source == "" {
+		// If the source is not a recognizable URL, do nothing.
+		return nil
+	}
+
+	// Construct query of addresses to symbolize.
+	var a []string
+	for _, l := range p.Location {
+		if l.Address != 0 && len(l.Line) == 0 {
+			a = append(a, fmt.Sprintf("%#x", l.Address))
+		}
+	}
+
+	if len(a) == 0 {
+		// No addresses to symbolize.
+		return nil
+	}
+	lines := make(map[uint64]profile.Line)
+	functions := make(map[string]*profile.Function)
+	if b, err := syms(source, strings.Join(a, "+")); err == nil {
+		buf := bytes.NewBuffer(b)
+		for {
+			l, err := buf.ReadString('\n')
+
+			if err != nil {
+				if err == io.EOF {
+					break
+				}
+				return err
+			}
+
+			if symbol := symbolzRE.FindStringSubmatch(l); len(symbol) == 3 {
+				addr, err := strconv.ParseUint(symbol[1], 0, 64)
+				if err != nil {
+					return fmt.Errorf("unexpected parse failure %s: %v", symbol[1], err)
+				}
+
+				name := symbol[2]
+				fn := functions[name]
+				if fn == nil {
+					fn = &profile.Function{
+						ID:         uint64(len(p.Function) + 1),
+						Name:       name,
+						SystemName: name,
+					}
+					functions[name] = fn
+					p.Function = append(p.Function, fn)
+				}
+
+				lines[addr] = profile.Line{Function: fn}
+			}
+		}
+	}
+
+	for _, l := range p.Location {
+		if line, ok := lines[l.Address]; ok {
+			l.Line = []profile.Line{line}
+			if l.Mapping != nil {
+				l.Mapping.HasFunctions = true
+			}
+		}
+	}
+
+	return nil
+}
+
+// symbolz returns the corresponding symbolz source for a profile URL.
+func symbolz(source string, p *profile.Profile) string {
+	if url, err := url.Parse(source); err == nil && url.Host != "" {
+		if last := strings.LastIndex(url.Path, "/"); last != -1 {
+			if strings.HasSuffix(url.Path[:last], "pprof") {
+				url.Path = url.Path[:last] + "/symbol"
+			} else {
+				url.Path = url.Path[:last] + "/symbolz"
+			}
+			return url.String()
+		}
+	}
+
+	return ""
+}
diff --git a/src/cmd/pprof/internal/tempfile/tempfile.go b/src/cmd/pprof/internal/tempfile/tempfile.go
new file mode 100644
index 0000000..31c1176
--- /dev/null
+++ b/src/cmd/pprof/internal/tempfile/tempfile.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 tempfile provides tools to create and delete temporary files
+package tempfile
+
+import (
+	"fmt"
+	"os"
+	"path/filepath"
+	"sync"
+)
+
+// New returns an unused filename for output files.
+func New(dir, prefix, suffix string) (*os.File, error) {
+	for index := 1; index < 10000; index++ {
+		path := filepath.Join(dir, fmt.Sprintf("%s%03d%s", prefix, index, suffix))
+		if _, err := os.Stat(path); err != nil {
+			return os.Create(path)
+		}
+	}
+	// Give up
+	return nil, fmt.Errorf("could not create file of the form %s%03d%s", prefix, 1, suffix)
+}
+
+var tempFiles []string
+var tempFilesMu = sync.Mutex{}
+
+// DeferDelete marks a file to be deleted by next call to Cleanup()
+func DeferDelete(path string) {
+	tempFilesMu.Lock()
+	tempFiles = append(tempFiles, path)
+	tempFilesMu.Unlock()
+}
+
+// Cleanup removes any temporary files selected for deferred cleaning.
+func Cleanup() {
+	tempFilesMu.Lock()
+	for _, f := range tempFiles {
+		os.Remove(f)
+	}
+	tempFiles = nil
+	tempFilesMu.Unlock()
+}
diff --git a/src/cmd/pprof/pprof.go b/src/cmd/pprof/pprof.go
new file mode 100644
index 0000000..44f4f6c
--- /dev/null
+++ b/src/cmd/pprof/pprof.go
@@ -0,0 +1,237 @@
+// 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 (
+	"debug/gosym"
+	"flag"
+	"fmt"
+	"os"
+	"regexp"
+	"strings"
+	"sync"
+
+	"cmd/internal/objfile"
+	"cmd/pprof/internal/commands"
+	"cmd/pprof/internal/driver"
+	"cmd/pprof/internal/fetch"
+	"cmd/pprof/internal/plugin"
+	"cmd/pprof/internal/profile"
+	"cmd/pprof/internal/symbolizer"
+	"cmd/pprof/internal/symbolz"
+)
+
+func main() {
+	var extraCommands map[string]*commands.Command // no added Go-specific commands
+	if err := driver.PProf(flags{}, fetch.Fetcher, symbolize, new(objTool), plugin.StandardUI(), extraCommands); err != nil {
+		fmt.Fprintf(os.Stderr, "%v\n", err)
+	}
+}
+
+// symbolize attempts to symbolize profile p.
+// If the source is a local binary, it tries using symbolizer and obj.
+// If the source is a URL, it fetches symbol information using symbolz.
+func symbolize(mode, source string, p *profile.Profile, obj plugin.ObjTool, ui plugin.UI) error {
+	remote, local := true, true
+	for _, o := range strings.Split(strings.ToLower(mode), ":") {
+		switch o {
+		case "none", "no":
+			return nil
+		case "local":
+			remote, local = false, true
+		case "remote":
+			remote, local = true, false
+		default:
+			ui.PrintErr("ignoring unrecognized symbolization option: " + mode)
+			ui.PrintErr("expecting -symbolize=[local|remote|none][:force]")
+			fallthrough
+		case "", "force":
+			// Ignore these options, -force is recognized by symbolizer.Symbolize
+		}
+	}
+
+	var err error
+	if local {
+		// Symbolize using binutils.
+		if err = symbolizer.Symbolize(mode, p, obj, ui); err == nil {
+			return nil
+		}
+	}
+	if remote {
+		err = symbolz.Symbolize(source, fetch.PostURL, p)
+	}
+	return err
+}
+
+// flags implements the driver.FlagPackage interface using the builtin flag package.
+type flags struct {
+}
+
+func (flags) Bool(o string, d bool, c string) *bool {
+	return flag.Bool(o, d, c)
+}
+
+func (flags) Int(o string, d int, c string) *int {
+	return flag.Int(o, d, c)
+}
+
+func (flags) Float64(o string, d float64, c string) *float64 {
+	return flag.Float64(o, d, c)
+}
+
+func (flags) String(o, d, c string) *string {
+	return flag.String(o, d, c)
+}
+
+func (flags) Parse(usage func()) []string {
+	flag.Usage = usage
+	flag.Parse()
+	args := flag.Args()
+	if len(args) == 0 {
+		usage()
+	}
+	return args
+}
+
+func (flags) ExtraUsage() string {
+	return ""
+}
+
+// objTool implements plugin.ObjTool using Go libraries
+// (instead of invoking GNU binutils).
+type objTool struct {
+	mu          sync.Mutex
+	disasmCache map[string]*objfile.Disasm
+}
+
+func (*objTool) Open(name string, start uint64) (plugin.ObjFile, error) {
+	of, err := objfile.Open(name)
+	if err != nil {
+		return nil, err
+	}
+	f := &file{
+		name: name,
+		file: of,
+	}
+	return f, nil
+}
+
+func (*objTool) Demangle(names []string) (map[string]string, error) {
+	// No C++, nothing to demangle.
+	return make(map[string]string), nil
+}
+
+func (t *objTool) Disasm(file string, start, end uint64) ([]plugin.Inst, error) {
+	d, err := t.cachedDisasm(file)
+	if err != nil {
+		return nil, err
+	}
+	var asm []plugin.Inst
+	d.Decode(start, end, func(pc, size uint64, file string, line int, text string) {
+		asm = append(asm, plugin.Inst{Addr: pc, File: file, Line: line, Text: text})
+	})
+	return asm, nil
+}
+
+func (t *objTool) cachedDisasm(file string) (*objfile.Disasm, error) {
+	t.mu.Lock()
+	defer t.mu.Unlock()
+	if t.disasmCache == nil {
+		t.disasmCache = make(map[string]*objfile.Disasm)
+	}
+	d := t.disasmCache[file]
+	if d != nil {
+		return d, nil
+	}
+	f, err := objfile.Open(file)
+	if err != nil {
+		return nil, err
+	}
+	d, err = f.Disasm()
+	f.Close()
+	if err != nil {
+		return nil, err
+	}
+	t.disasmCache[file] = d
+	return d, nil
+}
+
+func (*objTool) SetConfig(config string) {
+	// config is usually used to say what binaries to invoke.
+	// Ignore entirely.
+}
+
+// file implements plugin.ObjFile using Go libraries
+// (instead of invoking GNU binutils).
+// A file represents a single executable being analyzed.
+type file struct {
+	name string
+	sym  []objfile.Sym
+	file *objfile.File
+	pcln *gosym.Table
+}
+
+func (f *file) Name() string {
+	return f.name
+}
+
+func (f *file) Base() uint64 {
+	// No support for shared libraries.
+	return 0
+}
+
+func (f *file) BuildID() string {
+	// No support for build ID.
+	return ""
+}
+
+func (f *file) SourceLine(addr uint64) ([]plugin.Frame, error) {
+	if f.pcln == nil {
+		pcln, err := f.file.PCLineTable()
+		if err != nil {
+			return nil, err
+		}
+		f.pcln = pcln
+	}
+	file, line, fn := f.pcln.PCToLine(addr)
+	if fn == nil {
+		return nil, fmt.Errorf("no line information for PC=%#x", addr)
+	}
+	frame := []plugin.Frame{
+		{
+			Func: fn.Name,
+			File: file,
+			Line: line,
+		},
+	}
+	return frame, nil
+}
+
+func (f *file) Symbols(r *regexp.Regexp, addr uint64) ([]*plugin.Sym, error) {
+	if f.sym == nil {
+		sym, err := f.file.Symbols()
+		if err != nil {
+			return nil, err
+		}
+		f.sym = sym
+	}
+	var out []*plugin.Sym
+	for _, s := range f.sym {
+		if (r == nil || r.MatchString(s.Name)) && (addr == 0 || s.Addr <= addr && addr < s.Addr+uint64(s.Size)) {
+			out = append(out, &plugin.Sym{
+				Name:  []string{s.Name},
+				File:  f.name,
+				Start: s.Addr,
+				End:   s.Addr + uint64(s.Size) - 1,
+			})
+		}
+	}
+	return out, nil
+}
+
+func (f *file) Close() error {
+	f.file.Close()
+	return nil
+}
diff --git a/src/cmd/yacc/Makefile b/src/cmd/yacc/Makefile
deleted file mode 100644
index f8c8169..0000000
--- a/src/cmd/yacc/Makefile
+++ /dev/null
@@ -1,12 +0,0 @@
-# Copyright 2009 The Go Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style
-# license that can be found in the LICENSE file.
-
-TARG=expr$(shell go env GOEXE)
-
-$(TARG): yacc.go expr.y
-	go run yacc.go -p expr expr.y
-	go build -o $(TARG) y.go
-
-clean:
-	rm -f y.go y.output $(TARG)
diff --git a/src/cmd/yacc/doc.go b/src/cmd/yacc/doc.go
index ceaaf24..702c9f0 100644
--- a/src/cmd/yacc/doc.go
+++ b/src/cmd/yacc/doc.go
@@ -20,8 +20,9 @@ written in C and documented at
 Adepts of the original yacc will have no trouble adapting to this
 form of the tool.
 
-The file expr.y in this directory is a yacc grammar for a very simple
-expression parser.  It needs the flag "-p expr" (see below).
+The directory $GOROOT/cmd/yacc/testdata/expr is a yacc program
+for a very simple expression parser. See expr.y and main.go in that
+directory for examples of how to write and build yacc programs.
 
 The generated parser is reentrant. Parse expects to be given an
 argument that conforms to the following interface:
diff --git a/src/cmd/yacc/expr.y b/src/cmd/yacc/expr.y
deleted file mode 100644
index 77e9259..0000000
--- a/src/cmd/yacc/expr.y
+++ /dev/null
@@ -1,205 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// This is an example of a goyacc program.
-// To build it:
-// go tool yacc -p "expr" expr.y (produces y.go)
-// go build -o expr y.go
-// expr
-// > <type an expression>
-
-%{
-
-// This tag will be copied to the generated file to prevent that file
-// confusing a future build.
-
-// +build ignore
-
-package main
-
-import (
-	"bufio"
-	"bytes"
-	"fmt"
-	"io"
-	"log"
-	"math/big"
-	"os"
-	"unicode/utf8"
-)
-
-%}
-
-%union {
-	num *big.Rat
-}
-
-%type	<num>	expr expr1 expr2 expr3
-
-%token	<num>	NUM
-
-%%
-
-top:
-	expr
-	{
-		if $1.IsInt() {
-			fmt.Println($1.Num().String())
-		} else {
-			fmt.Println($1.String())
-		}
-	}
-
-expr:
-	expr1
-|	'+' expr
-	{
-		$$ = $2
-	}
-|	'-' expr
-	{
-		$$.Neg($2)
-	}
-
-expr1:
-	expr2
-|	expr1 '+' expr2
-	{
-		$$.Add($1, $3)
-	}
-|	expr1 '-' expr2
-	{
-		$$.Sub($1, $3)
-	}
-
-expr2:
-	expr3
-|	expr2 '*' expr3
-	{
-		$$.Mul($1, $3)
-	}
-|	expr2 '/' expr3
-	{
-		$$.Quo($1, $3)
-	}
-
-expr3:
-	NUM
-|	'(' expr ')'
-	{
-		$$ = $2
-	}
-
-
-%%
-
-// The parser expects the lexer to return 0 on EOF.  Give it a name
-// for clarity.
-const eof = 0
-
-// The parser uses the type <prefix>Lex as a lexer.  It must provide
-// the methods Lex(*<prefix>SymType) int and Error(string).
-type exprLex struct {
-	line []byte
-	peek rune
-}
-
-// The parser calls this method to get each new token.  This
-// implementation returns operators and NUM.
-func (x *exprLex) Lex(yylval *exprSymType) int {
-	for {
-		c := x.next()
-		switch c {
-		case eof:
-			return eof
-		case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
-			return x.num(c, yylval)
-		case '+', '-', '*', '/', '(', ')':
-			return int(c)
-
-		// Recognize Unicode multiplication and division
-		// symbols, returning what the parser expects.
-		case '×':
-			return '*'
-		case '÷':
-			return '/'
-
-		case ' ', '\t', '\n', '\r':
-		default:
-			log.Printf("unrecognized character %q", c)
-		}
-	}
-}
-
-// Lex a number.
-func (x *exprLex) num(c rune, yylval *exprSymType) int {
-	add := func(b *bytes.Buffer, c rune) {
-		if _, err := b.WriteRune(c); err != nil {
-			log.Fatalf("WriteRune: %s", err)
-		}
-	}
-	var b bytes.Buffer
-	add(&b, c)
-	L: for {
-		c = x.next()
-		switch c {
-		case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.', 'e', 'E':
-			add(&b, c)
-		default:
-			break L
-		}
-	}
-	if c != eof {
-		x.peek = c
-	}
-	yylval.num = &big.Rat{}
-	_, ok := yylval.num.SetString(b.String())
-	if !ok {
-		log.Printf("bad number %q", b.String())
-		return eof
-	}
-	return NUM
-}
-
-// Return the next rune for the lexer.
-func (x *exprLex) next() rune {
-	if x.peek != eof {
-		r := x.peek
-		x.peek = eof
-		return r
-	}
-	if len(x.line) == 0 {
-		return eof
-	}
-	c, size := utf8.DecodeRune(x.line)
-	x.line = x.line[size:]
-	if c == utf8.RuneError && size == 1 {
-		log.Print("invalid utf8")
-		return x.next()
-	}
-	return c
-}
-
-// The parser calls this method on a parse error.
-func (x *exprLex) Error(s string) {
-	log.Printf("parse error: %s", s)
-}
-
-func main() {
-	in := bufio.NewReader(os.Stdin)
-	for {
-		if _, err := os.Stdout.WriteString("> "); err != nil {
-			log.Fatalf("WriteString: %s", err)
-		}
-		line, err := in.ReadBytes('\n')
-		if err == io.EOF {
-			return
-		}
-		if err != nil {
-			log.Fatalf("ReadBytes: %s", err)
-		}
-
-		exprParse(&exprLex{line: line})
-	}
-}
diff --git a/src/cmd/yacc/testdata/expr/README b/src/cmd/yacc/testdata/expr/README
new file mode 100644
index 0000000..302ef57
--- /dev/null
+++ b/src/cmd/yacc/testdata/expr/README
@@ -0,0 +1,20 @@
+This directory contains a simple program demonstrating how to use
+the Go version of yacc.
+
+To build it:
+
+	$ go generate
+	$ go build
+
+or
+
+	$ go generate
+	$ go run expr.go
+
+The file main.go contains the "go generate" command to run yacc to
+create expr.go from expr.y. It also has the package doc comment,
+as godoc will not scan the .y file.
+
+The actual implementation is in expr.y.
+
+The program is not installed in the binary distributions of Go.
diff --git a/src/cmd/yacc/testdata/expr/expr.y b/src/cmd/yacc/testdata/expr/expr.y
new file mode 100644
index 0000000..721b1c9
--- /dev/null
+++ b/src/cmd/yacc/testdata/expr/expr.y
@@ -0,0 +1,202 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This is an example of a goyacc program.
+// To build it:
+// go tool yacc -p "expr" expr.y (produces y.go)
+// go build -o expr y.go
+// expr
+// > <type an expression>
+
+%{
+
+package main
+
+import (
+	"bufio"
+	"bytes"
+	"fmt"
+	"io"
+	"log"
+	"math/big"
+	"os"
+	"unicode/utf8"
+)
+
+%}
+
+%union {
+	num *big.Rat
+}
+
+%type	<num>	expr expr1 expr2 expr3
+
+%token '+' '-' '*' '/' '(' ')'
+
+%token	<num>	NUM
+
+%%
+
+top:
+	expr
+	{
+		if $1.IsInt() {
+			fmt.Println($1.Num().String())
+		} else {
+			fmt.Println($1.String())
+		}
+	}
+
+expr:
+	expr1
+|	'+' expr
+	{
+		$$ = $2
+	}
+|	'-' expr
+	{
+		$$.Neg($2)
+	}
+
+expr1:
+	expr2
+|	expr1 '+' expr2
+	{
+		$$.Add($1, $3)
+	}
+|	expr1 '-' expr2
+	{
+		$$.Sub($1, $3)
+	}
+
+expr2:
+	expr3
+|	expr2 '*' expr3
+	{
+		$$.Mul($1, $3)
+	}
+|	expr2 '/' expr3
+	{
+		$$.Quo($1, $3)
+	}
+
+expr3:
+	NUM
+|	'(' expr ')'
+	{
+		$$ = $2
+	}
+
+
+%%
+
+// The parser expects the lexer to return 0 on EOF.  Give it a name
+// for clarity.
+const eof = 0
+
+// The parser uses the type <prefix>Lex as a lexer.  It must provide
+// the methods Lex(*<prefix>SymType) int and Error(string).
+type exprLex struct {
+	line []byte
+	peek rune
+}
+
+// The parser calls this method to get each new token.  This
+// implementation returns operators and NUM.
+func (x *exprLex) Lex(yylval *exprSymType) int {
+	for {
+		c := x.next()
+		switch c {
+		case eof:
+			return eof
+		case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
+			return x.num(c, yylval)
+		case '+', '-', '*', '/', '(', ')':
+			return int(c)
+
+		// Recognize Unicode multiplication and division
+		// symbols, returning what the parser expects.
+		case '×':
+			return '*'
+		case '÷':
+			return '/'
+
+		case ' ', '\t', '\n', '\r':
+		default:
+			log.Printf("unrecognized character %q", c)
+		}
+	}
+}
+
+// Lex a number.
+func (x *exprLex) num(c rune, yylval *exprSymType) int {
+	add := func(b *bytes.Buffer, c rune) {
+		if _, err := b.WriteRune(c); err != nil {
+			log.Fatalf("WriteRune: %s", err)
+		}
+	}
+	var b bytes.Buffer
+	add(&b, c)
+	L: for {
+		c = x.next()
+		switch c {
+		case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.', 'e', 'E':
+			add(&b, c)
+		default:
+			break L
+		}
+	}
+	if c != eof {
+		x.peek = c
+	}
+	yylval.num = &big.Rat{}
+	_, ok := yylval.num.SetString(b.String())
+	if !ok {
+		log.Printf("bad number %q", b.String())
+		return eof
+	}
+	return NUM
+}
+
+// Return the next rune for the lexer.
+func (x *exprLex) next() rune {
+	if x.peek != eof {
+		r := x.peek
+		x.peek = eof
+		return r
+	}
+	if len(x.line) == 0 {
+		return eof
+	}
+	c, size := utf8.DecodeRune(x.line)
+	x.line = x.line[size:]
+	if c == utf8.RuneError && size == 1 {
+		log.Print("invalid utf8")
+		return x.next()
+	}
+	return c
+}
+
+// The parser calls this method on a parse error.
+func (x *exprLex) Error(s string) {
+	log.Printf("parse error: %s", s)
+}
+
+func main() {
+	in := bufio.NewReader(os.Stdin)
+	for {
+		if _, err := os.Stdout.WriteString("> "); err != nil {
+			log.Fatalf("WriteString: %s", err)
+		}
+		line, err := in.ReadBytes('\n')
+		if err == io.EOF {
+			return
+		}
+		if err != nil {
+			log.Fatalf("ReadBytes: %s", err)
+		}
+
+		exprParse(&exprLex{line: line})
+	}
+}
diff --git a/src/cmd/yacc/testdata/expr/main.go b/src/cmd/yacc/testdata/expr/main.go
new file mode 100644
index 0000000..8d5b691
--- /dev/null
+++ b/src/cmd/yacc/testdata/expr/main.go
@@ -0,0 +1,15 @@
+// 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 file holds the go generate command to run yacc on the grammar in expr.y.
+// To build expr:
+//	% go generate
+//	% go build
+
+//go:generate -command yacc go tool yacc
+//go:generate yacc -o expr.go -p "expr" expr.y
+
+// Expr is a simple expression evaluator that serves as a working example of
+// how to use Go's yacc implemenation.
+package main
diff --git a/src/cmd/yacc/yacc.go b/src/cmd/yacc/yacc.go
index c534032..4dba376 100644
--- a/src/cmd/yacc/yacc.go
+++ b/src/cmd/yacc/yacc.go
@@ -52,9 +52,9 @@ import (
 	"go/format"
 	"io/ioutil"
 	"os"
+	"strconv"
 	"strings"
 	"unicode"
-	"unicode/utf8"
 )
 
 // the following are adjustable
@@ -195,8 +195,9 @@ type Item struct {
 }
 
 type Symb struct {
-	name  string
-	value int
+	name    string
+	noconst bool
+	value   int
 }
 
 type Wset struct {
@@ -509,8 +510,7 @@ outer:
 	// put out non-literal terminals
 	for i := TOKSTART; i <= ntokens; i++ {
 		// non-literals
-		c := tokset[i].name[0]
-		if c != ' ' && c != '$' {
+		if !tokset[i].noconst {
 			fmt.Fprintf(ftable, "const %v = %v\n", tokset[i].name, tokset[i].value)
 		}
 	}
@@ -734,7 +734,7 @@ func defin(nt int, s string) int {
 			copy(anontrst, nontrst)
 			nontrst = anontrst
 		}
-		nontrst[nnonter] = Symb{s, 0}
+		nontrst[nnonter] = Symb{name: s}
 		return NTBASE + nnonter
 	}
 
@@ -756,70 +756,26 @@ func defin(nt int, s string) int {
 
 	// establish value for token
 	// single character literal
-	if s[0] == ' ' {
-		s = s[1:]
-		r, size := utf8.DecodeRuneInString(s)
-		if r == utf8.RuneError && size == 1 {
-			errorf("invalid UTF-8 sequence %q", s)
-		}
-		val = int(r)
-		if val == '\\' { // escape sequence
-			switch {
-			case len(s) == 2:
-				// single character escape sequence
-				switch s[1] {
-				case '\'':
-					val = '\''
-				case '"':
-					val = '"'
-				case '\\':
-					val = '\\'
-				case 'a':
-					val = '\a'
-				case 'b':
-					val = '\b'
-				case 'f':
-					val = '\f'
-				case 'n':
-					val = '\n'
-				case 'r':
-					val = '\r'
-				case 't':
-					val = '\t'
-				case 'v':
-					val = '\v'
-				default:
-					errorf("invalid escape %s", s)
-				}
-			case s[1] == 'u' && len(s) == 2+4, // \unnnn sequence
-				s[1] == 'U' && len(s) == 2+8: // \Unnnnnnnn sequence
-				val = 0
-				s = s[2:]
-				for s != "" {
-					c := int(s[0])
-					switch {
-					case c >= '0' && c <= '9':
-						c -= '0'
-					case c >= 'a' && c <= 'f':
-						c -= 'a' - 10
-					case c >= 'A' && c <= 'F':
-						c -= 'A' - 10
-					default:
-						errorf(`illegal \u or \U construction`)
-					}
-					val = val*16 + c
-					s = s[1:]
-				}
-			default:
-				errorf("invalid escape %s", s)
-			}
+	if s[0] == '\'' || s[0] == '"' {
+		q, err := strconv.Unquote(s)
+		if err != nil {
+			errorf("invalid token: %s", err)
+		}
+		rq := []rune(q)
+		if len(rq) != 1 {
+			errorf("character token too long: %s", s)
 		}
+		val = int(rq[0])
 		if val == 0 {
 			errorf("token value 0 is illegal")
 		}
+		tokset[ntokens].noconst = true
 	} else {
 		val = extval
 		extval++
+		if s[0] == '$' {
+			tokset[ntokens].noconst = true
+		}
 	}
 
 	tokset[ntokens].value = val
@@ -896,7 +852,7 @@ func gettok() int {
 
 	case '"', '\'':
 		match = c
-		tokname = " "
+		tokname = string(c)
 		for {
 			c = getrune(finput)
 			if c == '\n' || c == EOF {
@@ -909,6 +865,7 @@ func gettok() int {
 				if tokflag {
 					fmt.Printf(">>> IDENTIFIER \"%v\" %v\n", tokname, lineno)
 				}
+				tokname += string(c)
 				return IDENTIFIER
 			}
 			tokname += string(c)
@@ -1029,7 +986,7 @@ func fdtype(t int) int {
 }
 
 func chfind(t int, s string) int {
-	if s[0] == ' ' {
+	if s[0] == '"' || s[0] == '\'' {
 		t = 0
 	}
 	for i := 0; i <= ntokens; i++ {
@@ -1516,9 +1473,6 @@ func symnam(i int) string {
 	} else {
 		s = tokset[i].name
 	}
-	if s[0] == ' ' {
-		s = s[1:]
-	}
 	return s
 }
 
diff --git a/src/pkg/compress/bzip2/bit_reader.go b/src/compress/bzip2/bit_reader.go
similarity index 100%
rename from src/pkg/compress/bzip2/bit_reader.go
rename to src/compress/bzip2/bit_reader.go
diff --git a/src/compress/bzip2/bzip2.go b/src/compress/bzip2/bzip2.go
new file mode 100644
index 0000000..15575d2
--- /dev/null
+++ b/src/compress/bzip2/bzip2.go
@@ -0,0 +1,503 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package bzip2 implements bzip2 decompression.
+package bzip2
+
+import "io"
+
+// There's no RFC for bzip2. I used the Wikipedia page for reference and a lot
+// of guessing: http://en.wikipedia.org/wiki/Bzip2
+// The source code to pyflate was useful for debugging:
+// http://www.paul.sladen.org/projects/pyflate
+
+// A StructuralError is returned when the bzip2 data is found to be
+// syntactically invalid.
+type StructuralError string
+
+func (s StructuralError) Error() string {
+	return "bzip2 data invalid: " + string(s)
+}
+
+// A reader decompresses bzip2 compressed data.
+type reader struct {
+	br           bitReader
+	fileCRC      uint32
+	blockCRC     uint32
+	wantBlockCRC uint32
+	setupDone    bool // true if we have parsed the bzip2 header.
+	blockSize    int  // blockSize in bytes, i.e. 900 * 1024.
+	eof          bool
+	buf          []byte    // stores Burrows-Wheeler transformed data.
+	c            [256]uint // the `C' array for the inverse BWT.
+	tt           []uint32  // mirrors the `tt' array in the bzip2 source and contains the P array in the upper 24 bits.
+	tPos         uint32    // Index of the next output byte in tt.
+
+	preRLE      []uint32 // contains the RLE data still to be processed.
+	preRLEUsed  int      // number of entries of preRLE used.
+	lastByte    int      // the last byte value seen.
+	byteRepeats uint     // the number of repeats of lastByte seen.
+	repeats     uint     // the number of copies of lastByte to output.
+}
+
+// NewReader returns an io.Reader which decompresses bzip2 data from r.
+// If r does not also implement io.ByteReader,
+// the decompressor may read more data than necessary from r.
+func NewReader(r io.Reader) io.Reader {
+	bz2 := new(reader)
+	bz2.br = newBitReader(r)
+	return bz2
+}
+
+const bzip2FileMagic = 0x425a // "BZ"
+const bzip2BlockMagic = 0x314159265359
+const bzip2FinalMagic = 0x177245385090
+
+// setup parses the bzip2 header.
+func (bz2 *reader) setup(needMagic bool) error {
+	br := &bz2.br
+
+	if needMagic {
+		magic := br.ReadBits(16)
+		if magic != bzip2FileMagic {
+			return StructuralError("bad magic value")
+		}
+	}
+
+	t := br.ReadBits(8)
+	if t != 'h' {
+		return StructuralError("non-Huffman entropy encoding")
+	}
+
+	level := br.ReadBits(8)
+	if level < '1' || level > '9' {
+		return StructuralError("invalid compression level")
+	}
+
+	bz2.fileCRC = 0
+	bz2.blockSize = 100 * 1024 * (int(level) - '0')
+	if bz2.blockSize > len(bz2.tt) {
+		bz2.tt = make([]uint32, bz2.blockSize)
+	}
+	return nil
+}
+
+func (bz2 *reader) Read(buf []byte) (n int, err error) {
+	if bz2.eof {
+		return 0, io.EOF
+	}
+
+	if !bz2.setupDone {
+		err = bz2.setup(true)
+		brErr := bz2.br.Err()
+		if brErr != nil {
+			err = brErr
+		}
+		if err != nil {
+			return 0, err
+		}
+		bz2.setupDone = true
+	}
+
+	n, err = bz2.read(buf)
+	brErr := bz2.br.Err()
+	if brErr != nil {
+		err = brErr
+	}
+	return
+}
+
+func (bz2 *reader) readFromBlock(buf []byte) int {
+	// bzip2 is a block based compressor, except that it has a run-length
+	// preprocessing step. The block based nature means that we can
+	// preallocate fixed-size buffers and reuse them. However, the RLE
+	// preprocessing would require allocating huge buffers to store the
+	// maximum expansion. Thus we process blocks all at once, except for
+	// the RLE which we decompress as required.
+	n := 0
+	for (bz2.repeats > 0 || bz2.preRLEUsed < len(bz2.preRLE)) && n < len(buf) {
+		// We have RLE data pending.
+
+		// The run-length encoding works like this:
+		// Any sequence of four equal bytes is followed by a length
+		// byte which contains the number of repeats of that byte to
+		// include. (The number of repeats can be zero.) Because we are
+		// decompressing on-demand our state is kept in the reader
+		// object.
+
+		if bz2.repeats > 0 {
+			buf[n] = byte(bz2.lastByte)
+			n++
+			bz2.repeats--
+			if bz2.repeats == 0 {
+				bz2.lastByte = -1
+			}
+			continue
+		}
+
+		bz2.tPos = bz2.preRLE[bz2.tPos]
+		b := byte(bz2.tPos)
+		bz2.tPos >>= 8
+		bz2.preRLEUsed++
+
+		if bz2.byteRepeats == 3 {
+			bz2.repeats = uint(b)
+			bz2.byteRepeats = 0
+			continue
+		}
+
+		if bz2.lastByte == int(b) {
+			bz2.byteRepeats++
+		} else {
+			bz2.byteRepeats = 0
+		}
+		bz2.lastByte = int(b)
+
+		buf[n] = b
+		n++
+	}
+
+	return n
+}
+
+func (bz2 *reader) read(buf []byte) (int, error) {
+	for {
+		n := bz2.readFromBlock(buf)
+		if n > 0 {
+			bz2.blockCRC = updateCRC(bz2.blockCRC, buf[:n])
+			return n, nil
+		}
+
+		// End of block. Check CRC.
+		if bz2.blockCRC != bz2.wantBlockCRC {
+			bz2.br.err = StructuralError("block checksum mismatch")
+			return 0, bz2.br.err
+		}
+
+		// Find next block.
+		br := &bz2.br
+		switch br.ReadBits64(48) {
+		default:
+			return 0, StructuralError("bad magic value found")
+
+		case bzip2BlockMagic:
+			// Start of block.
+			err := bz2.readBlock()
+			if err != nil {
+				return 0, err
+			}
+
+		case bzip2FinalMagic:
+			// Check end-of-file CRC.
+			wantFileCRC := uint32(br.ReadBits64(32))
+			if br.err != nil {
+				return 0, br.err
+			}
+			if bz2.fileCRC != wantFileCRC {
+				br.err = StructuralError("file checksum mismatch")
+				return 0, br.err
+			}
+
+			// Skip ahead to byte boundary.
+			// Is there a file concatenated to this one?
+			// It would start with BZ.
+			if br.bits%8 != 0 {
+				br.ReadBits(br.bits % 8)
+			}
+			b, err := br.r.ReadByte()
+			if err == io.EOF {
+				br.err = io.EOF
+				bz2.eof = true
+				return 0, io.EOF
+			}
+			if err != nil {
+				br.err = err
+				return 0, err
+			}
+			z, err := br.r.ReadByte()
+			if err != nil {
+				if err == io.EOF {
+					err = io.ErrUnexpectedEOF
+				}
+				br.err = err
+				return 0, err
+			}
+			if b != 'B' || z != 'Z' {
+				return 0, StructuralError("bad magic value in continuation file")
+			}
+			if err := bz2.setup(false); err != nil {
+				return 0, err
+			}
+		}
+	}
+}
+
+// readBlock reads a bzip2 block. The magic number should already have been consumed.
+func (bz2 *reader) readBlock() (err error) {
+	br := &bz2.br
+	bz2.wantBlockCRC = uint32(br.ReadBits64(32)) // skip checksum. TODO: check it if we can figure out what it is.
+	bz2.blockCRC = 0
+	bz2.fileCRC = (bz2.fileCRC<<1 | bz2.fileCRC>>31) ^ bz2.wantBlockCRC
+	randomized := br.ReadBits(1)
+	if randomized != 0 {
+		return StructuralError("deprecated randomized files")
+	}
+	origPtr := uint(br.ReadBits(24))
+
+	// If not every byte value is used in the block (i.e., it's text) then
+	// the symbol set is reduced. The symbols used are stored as a
+	// two-level, 16x16 bitmap.
+	symbolRangeUsedBitmap := br.ReadBits(16)
+	symbolPresent := make([]bool, 256)
+	numSymbols := 0
+	for symRange := uint(0); symRange < 16; symRange++ {
+		if symbolRangeUsedBitmap&(1<<(15-symRange)) != 0 {
+			bits := br.ReadBits(16)
+			for symbol := uint(0); symbol < 16; symbol++ {
+				if bits&(1<<(15-symbol)) != 0 {
+					symbolPresent[16*symRange+symbol] = true
+					numSymbols++
+				}
+			}
+		}
+	}
+
+	if numSymbols == 0 {
+		// There must be an EOF symbol.
+		return StructuralError("no symbols in input")
+	}
+
+	// A block uses between two and six different Huffman trees.
+	numHuffmanTrees := br.ReadBits(3)
+	if numHuffmanTrees < 2 || numHuffmanTrees > 6 {
+		return StructuralError("invalid number of Huffman trees")
+	}
+
+	// The Huffman tree can switch every 50 symbols so there's a list of
+	// tree indexes telling us which tree to use for each 50 symbol block.
+	numSelectors := br.ReadBits(15)
+	treeIndexes := make([]uint8, numSelectors)
+
+	// The tree indexes are move-to-front transformed and stored as unary
+	// numbers.
+	mtfTreeDecoder := newMTFDecoderWithRange(numHuffmanTrees)
+	for i := range treeIndexes {
+		c := 0
+		for {
+			inc := br.ReadBits(1)
+			if inc == 0 {
+				break
+			}
+			c++
+		}
+		if c >= numHuffmanTrees {
+			return StructuralError("tree index too large")
+		}
+		treeIndexes[i] = uint8(mtfTreeDecoder.Decode(c))
+	}
+
+	// The list of symbols for the move-to-front transform is taken from
+	// the previously decoded symbol bitmap.
+	symbols := make([]byte, numSymbols)
+	nextSymbol := 0
+	for i := 0; i < 256; i++ {
+		if symbolPresent[i] {
+			symbols[nextSymbol] = byte(i)
+			nextSymbol++
+		}
+	}
+	mtf := newMTFDecoder(symbols)
+
+	numSymbols += 2 // to account for RUNA and RUNB symbols
+	huffmanTrees := make([]huffmanTree, numHuffmanTrees)
+
+	// Now we decode the arrays of code-lengths for each tree.
+	lengths := make([]uint8, numSymbols)
+	for i := range huffmanTrees {
+		// The code lengths are delta encoded from a 5-bit base value.
+		length := br.ReadBits(5)
+		for j := range lengths {
+			for {
+				if !br.ReadBit() {
+					break
+				}
+				if br.ReadBit() {
+					length--
+				} else {
+					length++
+				}
+			}
+			if length < 0 || length > 20 {
+				return StructuralError("Huffman length out of range")
+			}
+			lengths[j] = uint8(length)
+		}
+		huffmanTrees[i], err = newHuffmanTree(lengths)
+		if err != nil {
+			return err
+		}
+	}
+
+	selectorIndex := 1 // the next tree index to use
+	if len(treeIndexes) == 0 {
+		return StructuralError("no tree selectors given")
+	}
+	if int(treeIndexes[0]) >= len(huffmanTrees) {
+		return StructuralError("tree selector out of range")
+	}
+	currentHuffmanTree := huffmanTrees[treeIndexes[0]]
+	bufIndex := 0 // indexes bz2.buf, the output buffer.
+	// The output of the move-to-front transform is run-length encoded and
+	// we merge the decoding into the Huffman parsing loop. These two
+	// variables accumulate the repeat count. See the Wikipedia page for
+	// details.
+	repeat := 0
+	repeat_power := 0
+
+	// The `C' array (used by the inverse BWT) needs to be zero initialized.
+	for i := range bz2.c {
+		bz2.c[i] = 0
+	}
+
+	decoded := 0 // counts the number of symbols decoded by the current tree.
+	for {
+		if decoded == 50 {
+			if selectorIndex >= numSelectors {
+				return StructuralError("insufficient selector indices for number of symbols")
+			}
+			if int(treeIndexes[selectorIndex]) >= len(huffmanTrees) {
+				return StructuralError("tree selector out of range")
+			}
+			currentHuffmanTree = huffmanTrees[treeIndexes[selectorIndex]]
+			selectorIndex++
+			decoded = 0
+		}
+
+		v := currentHuffmanTree.Decode(br)
+		decoded++
+
+		if v < 2 {
+			// This is either the RUNA or RUNB symbol.
+			if repeat == 0 {
+				repeat_power = 1
+			}
+			repeat += repeat_power << v
+			repeat_power <<= 1
+
+			// This limit of 2 million comes from the bzip2 source
+			// code. It prevents repeat from overflowing.
+			if repeat > 2*1024*1024 {
+				return StructuralError("repeat count too large")
+			}
+			continue
+		}
+
+		if repeat > 0 {
+			// We have decoded a complete run-length so we need to
+			// replicate the last output symbol.
+			if repeat > bz2.blockSize-bufIndex {
+				return StructuralError("repeats past end of block")
+			}
+			for i := 0; i < repeat; i++ {
+				b := byte(mtf.First())
+				bz2.tt[bufIndex] = uint32(b)
+				bz2.c[b]++
+				bufIndex++
+			}
+			repeat = 0
+		}
+
+		if int(v) == numSymbols-1 {
+			// This is the EOF symbol. Because it's always at the
+			// end of the move-to-front list, and never gets moved
+			// to the front, it has this unique value.
+			break
+		}
+
+		// Since two metasymbols (RUNA and RUNB) have values 0 and 1,
+		// one would expect |v-2| to be passed to the MTF decoder.
+		// However, the front of the MTF list is never referenced as 0,
+		// it's always referenced with a run-length of 1. Thus 0
+		// doesn't need to be encoded and we have |v-1| in the next
+		// line.
+		b := byte(mtf.Decode(int(v - 1)))
+		if bufIndex >= bz2.blockSize {
+			return StructuralError("data exceeds block size")
+		}
+		bz2.tt[bufIndex] = uint32(b)
+		bz2.c[b]++
+		bufIndex++
+	}
+
+	if origPtr >= uint(bufIndex) {
+		return StructuralError("origPtr out of bounds")
+	}
+
+	// We have completed the entropy decoding. Now we can perform the
+	// inverse BWT and setup the RLE buffer.
+	bz2.preRLE = bz2.tt[:bufIndex]
+	bz2.preRLEUsed = 0
+	bz2.tPos = inverseBWT(bz2.preRLE, origPtr, bz2.c[:])
+	bz2.lastByte = -1
+	bz2.byteRepeats = 0
+	bz2.repeats = 0
+
+	return nil
+}
+
+// inverseBWT implements the inverse Burrows-Wheeler transform as described in
+// http://www.hpl.hp.com/techreports/Compaq-DEC/SRC-RR-124.pdf, section 4.2.
+// In that document, origPtr is called `I' and c is the `C' array after the
+// first pass over the data. It's an argument here because we merge the first
+// pass with the Huffman decoding.
+//
+// This also implements the `single array' method from the bzip2 source code
+// which leaves the output, still shuffled, in the bottom 8 bits of tt with the
+// index of the next byte in the top 24-bits. The index of the first byte is
+// returned.
+func inverseBWT(tt []uint32, origPtr uint, c []uint) uint32 {
+	sum := uint(0)
+	for i := 0; i < 256; i++ {
+		sum += c[i]
+		c[i] = sum - c[i]
+	}
+
+	for i := range tt {
+		b := tt[i] & 0xff
+		tt[c[b]] |= uint32(i) << 8
+		c[b]++
+	}
+
+	return tt[origPtr] >> 8
+}
+
+// This is a standard CRC32 like in hash/crc32 except that all the shifts are reversed,
+// causing the bits in the input to be processed in the reverse of the usual order.
+
+var crctab [256]uint32
+
+func init() {
+	const poly = 0x04C11DB7
+	for i := range crctab {
+		crc := uint32(i) << 24
+		for j := 0; j < 8; j++ {
+			if crc&0x80000000 != 0 {
+				crc = (crc << 1) ^ poly
+			} else {
+				crc <<= 1
+			}
+		}
+		crctab[i] = crc
+	}
+}
+
+// updateCRC updates the crc value to incorporate the data in b.
+// The initial value is 0.
+func updateCRC(val uint32, b []byte) uint32 {
+	crc := ^val
+	for _, v := range b {
+		crc = crctab[byte(crc>>24)^v] ^ (crc << 8)
+	}
+	return ^crc
+}
diff --git a/src/compress/bzip2/bzip2_test.go b/src/compress/bzip2/bzip2_test.go
new file mode 100644
index 0000000..fb79d08
--- /dev/null
+++ b/src/compress/bzip2/bzip2_test.go
@@ -0,0 +1,419 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package bzip2
+
+import (
+	"bytes"
+	"encoding/base64"
+	"encoding/hex"
+	"io"
+	"io/ioutil"
+	"testing"
+)
+
+func TestBitReader(t *testing.T) {
+	buf := bytes.NewReader([]byte{0xaa})
+	br := newBitReader(buf)
+	if n := br.ReadBits(1); n != 1 {
+		t.Errorf("read 1 wrong")
+	}
+	if n := br.ReadBits(1); n != 0 {
+		t.Errorf("read 2 wrong")
+	}
+	if n := br.ReadBits(1); n != 1 {
+		t.Errorf("read 3 wrong")
+	}
+	if n := br.ReadBits(1); n != 0 {
+		t.Errorf("read 4 wrong")
+	}
+}
+
+func TestBitReaderLarge(t *testing.T) {
+	buf := bytes.NewReader([]byte{0x12, 0x34, 0x56, 0x78})
+	br := newBitReader(buf)
+	if n := br.ReadBits(32); n != 0x12345678 {
+		t.Errorf("got: %x want: %x", n, 0x12345678)
+	}
+}
+
+func readerFromHex(s string) io.Reader {
+	data, err := hex.DecodeString(s)
+	if err != nil {
+		panic("readerFromHex: bad input")
+	}
+	return bytes.NewReader(data)
+}
+
+func decompressHex(s string) (out []byte, err error) {
+	r := NewReader(readerFromHex(s))
+	return ioutil.ReadAll(r)
+}
+
+func TestHelloWorldBZ2(t *testing.T) {
+	out, err := decompressHex(helloWorldBZ2Hex)
+	if err != nil {
+		t.Errorf("error from Read: %s", err)
+		return
+	}
+
+	if !bytes.Equal(helloWorld, out) {
+		t.Errorf("got %x, want %x", out, helloWorld)
+	}
+}
+
+func TestConcat(t *testing.T) {
+	out, err := decompressHex(helloWorldBZ2Hex + helloWorldBZ2Hex)
+	if err != nil {
+		t.Errorf("error from Read: %s", err)
+		return
+	}
+
+	hello2 := bytes.Repeat(helloWorld, 2)
+	if !bytes.Equal(hello2, out) {
+		t.Errorf("got %x, want %x", out, hello2)
+	}
+}
+
+func testZeros(t *testing.T, inHex string, n int) {
+	out, err := decompressHex(inHex)
+	if err != nil {
+		t.Errorf("error from Read: %s", err)
+		return
+	}
+
+	expected := make([]byte, n)
+
+	if !bytes.Equal(expected, out) {
+		allZeros := true
+		for _, b := range out {
+			if b != 0 {
+				allZeros = false
+				break
+			}
+		}
+		t.Errorf("incorrect result, got %d bytes (allZeros: %t)", len(out), allZeros)
+	}
+}
+
+func Test32Zeros(t *testing.T) {
+	testZeros(t, thirtyTwoZerosBZ2Hex, 32)
+}
+
+func Test1MBZeros(t *testing.T) {
+	testZeros(t, oneMBZerosBZ2Hex, 1024*1024)
+}
+
+func testRandomData(t *testing.T, compressedHex, uncompressedHex string) {
+	out, err := decompressHex(compressedHex)
+	if err != nil {
+		t.Errorf("error from Read: %s", err)
+		return
+	}
+
+	expected, _ := hex.DecodeString(uncompressedHex)
+
+	if !bytes.Equal(out, expected) {
+		t.Errorf("incorrect result\ngot:  %x\nwant: %x", out, expected)
+	}
+}
+
+func TestRandomData1(t *testing.T) {
+	testRandomData(t, randBZ2Hex, randHex)
+}
+
+func TestRandomData2(t *testing.T) {
+	// This test involves several repeated bytes in the output, but they
+	// should trigger RLE decoding.
+	testRandomData(t, rand2BZ2Hex, rand2Hex)
+}
+
+func TestRandomData3(t *testing.T) {
+	// This test uses the full range of symbols.
+	testRandomData(t, rand3BZ2Hex, rand3Hex)
+}
+
+func Test1MBSawtooth(t *testing.T) {
+	out, err := decompressHex(oneMBSawtoothBZ2Hex)
+	if err != nil {
+		t.Errorf("error from Read: %s", err)
+		return
+	}
+
+	expected := make([]byte, 1024*1024)
+
+	for i := range expected {
+		expected[i] = byte(i)
+	}
+
+	if !bytes.Equal(out, expected) {
+		t.Error("incorrect result")
+	}
+}
+
+const helloWorldBZ2Hex = "425a68393141592653594eece83600000251800010400006449080200031064c4101a7a9a580bb9431f8bb9229c28482776741b0"
+
+var helloWorld = []byte("hello world\n")
+
+const thirtyTwoZerosBZ2Hex = "425a6839314159265359b5aa5098000000600040000004200021008283177245385090b5aa5098"
+const oneMBZerosBZ2Hex = "425a683931415926535938571ce50008084000c0040008200030cc0529a60806c4201e2ee48a70a12070ae39ca"
+
+const randBZ2Hex = "425a6839314159265359905d990d0001957fffffffffffafffffffffffffffffbfff6fffdfffffffffffffffffffffffffffffc002b6dd75676ed5b77720098320d11a64626981323d4da47a83131a13d09e8040f534cd4f4d27a464d193008cd09804601347a980026350c9886234d36864193d1351b44c136919e90340d26127a4cd264c32023009898981310c0344c340027a8303427a99a04c00003534c230d034f5006468d268cf54d36a3009a69a62626261311b40026013d34201a6934c9a604c98ca6c8460989fa9346234d30d3469a2604fd4131a7aa6d0046043d4c62098479269e89e835190d0 [...]
+const randHex = "c95138082bdf2b9bfa5b1072b23f729735d42c785eeb94320fb14c265b9c2ca421d01a3db986df1ac2acde5a0e6bf955d6f95e61261540905928e195f1a66644cc7f37281744fff4dc6df35566a494c41a8167151950eb74f5fc45f85ad0e5ed28b49adfe218aa7ec1707e8e1d55825f61f72beda3b4c006b8c9188d7336a5d875329b1b58c27cc4e89ecbae02c7712400c39dd131d2c6de82e2863da51d472bdfb21ecce62cc9cf769ed28aedc7583d755da45a0d90874bda269dd53283a9bdfd05f95fc8e9a304bb338ea1a2111894678c18134f17d31a15d9bfc1237894650f3e715e2548639ecbddb845cfe [...]
+
+const oneMBSawtoothBZ2Hex = "425a683931415926535971931ea00006ddffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe007de00000000000000024c00130001300000000000000000000000000000000000000000000000000000000126000980009800000000000000000000000000000000000000000000000000000000930004c0004c000000000000000000000000000000000000000000000000000000004980026000260000000000000000000000000000000000000000000000000000000009aaaaa000000000000000000000000000000000000000000000000000000000000 [...]
+
+const rand2BZ2Hex = "425a6839314159265359d992d0f60000137dfe84020310091c1e280e100e042801099210094806c0110002e70806402000546034000034000000f2830000032000d3403264049270eb7a9280d308ca06ad28f6981bee1bf8160727c7364510d73a1e123083421b63f031f63993a0f40051fbf177245385090d992d0f60"
+const rand2Hex = "92d5652616ac444a4a04af1a8a3964aca0450d43d6cf233bd03233f4ba92f8719e6c2a2bd4f5f88db07ecd0da3a33b263483db9b2c158786ad6363be35d17335ba"
+
+const rand3BZ2Hex = "425a68393141592653593be669d00000327ffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffc002b3b2b1b6e2bae400004c00132300004c0d268c004c08c0130026001a008683234c0684c34008c230261a04c0260064d07a8d00034000d27a1268c9931a8d327a3427a41faa69ea0da264c1a34219326869b51b49a6469a3268c689fa53269a62794687a9a68f5189994c9e487a8f534fd49a3d34043629e8c93d04da4f4648d30d4f44d3234c4d3023d0840680984d309934c234d3131a000640984f536a6132601300130130c8d00d04d1841ea7a8d31a02609b40023 [...]
+const rand3Hex = "1744b384d68c042371244e13500d4bfb98c6244e3d71a5b700224420b59c593553f33bd786e3d0ce31626f511bc985f59d1a88aa38ba8ad6218d306abee60dd9172540232b95be1af146c69e72e5fde667a090dc3f93bdc5c5af0ab80acdbaa7a505f628c59dc0247b31a439cacf5010a94376d71521df08c178b02fb96fdb1809144ea38c68536187c53201fea8631fb0a880b4451ccdca7cc61f6aafca21cc7449d920599db61789ac3b1e164b3390124f95022aeea39ccca3ec1053f4fa10de2978e2861ea58e477085c2220021a0927aa94c5d0006b5055abba340e4f9eba22e969978dfd18e278a8b89d8 [...]
+
+const (
+	digits = iota
+	twain
+)
+
+var testfiles = []string{
+	// Digits is the digits of the irrational number e. Its decimal representation
+	// does not repeat, but there are only 10 possible digits, so it should be
+	// reasonably compressible.
+	digits: "testdata/e.txt.bz2",
+	// Twain is Project Gutenberg's edition of Mark Twain's classic English novel.
+	twain: "testdata/Mark.Twain-Tom.Sawyer.txt.bz2",
+}
+
+func benchmarkDecode(b *testing.B, testfile int) {
+	compressed, err := ioutil.ReadFile(testfiles[testfile])
+	if err != nil {
+		b.Fatal(err)
+	}
+	b.SetBytes(int64(len(compressed)))
+	for i := 0; i < b.N; i++ {
+		r := bytes.NewReader(compressed)
+		io.Copy(ioutil.Discard, NewReader(r))
+	}
+}
+
+func BenchmarkDecodeDigits(b *testing.B) { benchmarkDecode(b, digits) }
+func BenchmarkDecodeTwain(b *testing.B)  { benchmarkDecode(b, twain) }
+
+func TestBufferOverrun(t *testing.T) {
+	// Tests https://code.google.com/p/go/issues/detail?id=5747.
+	buffer := bytes.NewReader([]byte(bufferOverrunBase64))
+	decoder := base64.NewDecoder(base64.StdEncoding, buffer)
+	decompressor := NewReader(decoder)
+	// This shouldn't panic.
+	ioutil.ReadAll(decompressor)
+}
+
+func TestOutOfRangeSelector(t *testing.T) {
+	// Tests https://code.google.com/p/go/issues/detail?id=8363.
+	buffer := bytes.NewReader(outOfRangeSelector)
+	decompressor := NewReader(buffer)
+	// This shouldn't panic.
+	ioutil.ReadAll(decompressor)
+}
+
+func TestMTF(t *testing.T) {
+	mtf := newMTFDecoderWithRange(5)
+
+	// 0 1 2 3 4
+	expect := byte(1)
+	x := mtf.Decode(1)
+	if x != expect {
+		t.Errorf("expected %v, got %v", expect, x)
+	}
+
+	// 1 0 2 3 4
+	x = mtf.Decode(0)
+	if x != expect {
+		t.Errorf("expected %v, got %v", expect, x)
+	}
+
+	// 1 0 2 3 4
+	expect = byte(0)
+	x = mtf.Decode(1)
+	if x != expect {
+		t.Errorf("expected %v, got %v", expect, x)
+	}
+
+	// 0 1 2 3 4
+	expect = byte(4)
+	x = mtf.Decode(4)
+	if x != expect {
+		t.Errorf("expected %v, got %v", expect, x)
+	}
+
+	// 4 0 1 2 3
+	expect = byte(0)
+	x = mtf.Decode(1)
+	if x != expect {
+		t.Errorf("expected %v, got %v", expect, x)
+	}
+}
+
+var bufferOverrunBase64 string = `
+QlpoNTFBWSZTWTzyiGcACMP/////////////////////////////////3/7f3///
+////4N/fCZODak2Xo44GIHZgkGzDRbFAuwAAKoFV7T6AO6qwA6APb6s2rOoAkAAD
+oACUoDtndh0iQAPkAAAAaPWihQoCgr5t97Obju21ChQB0NBm3RbA7apXrRoBooAA
+AhA+IAHWl2Us3O7t9yieb3udvd76+4+fd33nd3HO1bVvfcGRne6+3vfPvfc++995
+w7k973eJhasLVec970tzDNXdX28LoPXZ3H3K9z0s5ufWAfes49d5594c3dUYtI+2
++h1dvtpRa+uvrVEAG9bl893RVEN7cWvroSqWjPMGgAQi7Gq8TJSgKKdjKFBIB9Ae
+LqWxleu715eXe7ml9e5098Z6G1vr7t1QZ6ot76YzPd3j7333t2ql2Chm7XrA9ICQ
+VF77z3rVBWqkSXtlfb099hyezAr6USbGpICTSCFAaqHrKo+tUnm32rpE4Ue+t2mj
+bKUeipEqwc93EdhhTwmQpOhhesC9iqDSPNTWYNSnUtBdm1nsA0nqqNd7OWwDXtFL
+ONmmA6Ubke26I9UblvWIPR5VOWOnctai443URunnDy77uVC59OfRvezlDu33Z7Ly
+3NNuuHW63088xu3t3NHZhkZbG7tXRlj00qOtbaXTJUUdspTbABR9R6EUwQAEAAAA
+EMEwRpoAAAABMmhoAAjBNNAaCMhponpoGpgJpk9TEyp6niGKZkAaAEfqMQ09U80p
++pMGSCKngIAAAAgAAg0AAJhGgABGCEaaTyTKeNI1PE0wkj01GajMSNPSZGnqbU9T
+anlPUNAHqGQ0DQAMg9TamgAAYRU/IAAICAmjQJgjQBMEwp5DTSaaYmhTeqfplPID
+U1T9TynoU82pT1NPU/VP0j1NHqRpk9TTR7SnqaNNGmmQAaAD1Aeo0PSAAAAaaBiK
+eBAQBGgIABGQA0AmBNNBoaAgaJmpglPEyYap6npiTT0agGjJjUaaDTQAAAAAAM1A
+9QAaAAAADU8iEAQAEyAJk0NNNJgIZTJ5E00YSemiaZNGm1MpGNJ+lPU9qm9U2RDM
+oY0EzJB6h6nqDID1NMBDDRpo1AGNAjCMmhkMgaYSJIgAAAQyAAEyBoATECCNhTT0
+U/IZAmCM1DSTxkzUE8p6NDaGiZGJqntTFHvUyU9qPQp7Kn5GgKNPU9QAGg9QAAA3
+wz0Pk/g/m/m9P9H4vxv2+dH3gCS8nhbbbbbYxtgNsBsG0m2MbG0NNtsbYNsaY0wb
+bBibGmm22mxptNpsaGNDTY02JsG0MY0xg2MaYNNDbGwG0L5vsK/F9DO+EAA447Kq
+p7Wdf6Y+5c20T7DfHyMXIzRKrZexw72uiQI+y55vOe52xpqbCLC2uR20JdER7Zvr
+7ufuKb6zhiBxLuj0eA27v8RpMLucw9Ohwcizi2wrpt+yU1FdpM7ZYPcwS3XTef+A
+Wzjxwhdrgw3aH1LeC1eZW900x8V9Nv4hTPXp4l067P/4ANVZFF/imOe/d5bdueam
+/DFFokQWnFaU+ZqLBCM+d0PialJQWnLqRQZk/KhfbbYc2pCUTgffcSYbrCM1N+8l
+HU6gSz+h2GJXs+tbrNviL83M97X0vcTn/F82P8wen8/3/h3sHY+sf9CSej9ThYTV
+3lQ+FUHpfpGD4kv7dYMV995dpDX/y3xR8FoXx1bjUxBTNxuutwQ/h/Eedn9wpn6w
+E3+ND8YhN1HSriIxRE/6uFyMv6/oC6Elarw3aHMMqHJkGiiz6tejmvnYLQa+Qm6G
+deZ7jXTZV6NlpocgDnRdimS06bTYSkvPAL/xoWNLkX6N6VljU0dfKSBmm2uZE/xu
+sutQ1EdP7GdjhglIq4xlOFUFEQpmX+xx7R8y6c0GSAaqusOjNZwxZRudOvmXm1tZ
+T+YnbeB2ir9eiHNrtJNSLD/J/WDyuQpwBUtLKo0krccY/wIILP7f86teb9Z/9oyz
+OX05qEWbObfhpRw+9+rCvp/35ML8KX3aHaI0n+tudbFRsV5FLW+Oa8ruLN4peyVL
+DWjTHrXNthq/s7zAJYMeFJZkZt5mT9rfpH+5g3nc+piOSZ+J5nHtOnKI7Ff8Xl+j
+0t76XTNucCHQ6whav1OHdF53TY5wuv5OzvrdnxoId8fTyUvERr0ERINu/8XxZZ5f
+B5/kTZ8bBO0wv54Jp+ED/GQI8lZHzIQCP3vfQhwnCTj9TvITic7P4mYLDbH3fyzR
+i+6EajCcpXLWSGf+ZXkOrWspDWDhXtEKas0v3UqWksqgY1rTj45krX4KihN+daXs
+pZl5WPlta5p06CX6Xm2SfzqkMw12/3ix1bpnnZ+kFeBNX7A+E9zzG6OZaN78GOpl
+9Ht/eZn9PqWdav852zr0zqkDK2H5IjdvNah+b1YVGdQGzwR4Nw+f13yEKnV+y66W
+djfq7zWp7m5w+hzfv+Ly8O7oet5Vvd8/wQvO7qzOZ2vjf9X8Tj8PnMb/nc/nKqRR
++ml4UEhOOwfCeJEEI109CMYSh91iAJqPjMyH6KjrPD7W25llZVcREYNCTg6htbQt
+M38wYoquCWP6tdKYlVIv14xTNUeUf4El/FunCf6csZkmv+9tfWx7t59wuKIa3saU
+tZs9M+3HFOZtz3OLg/Unoaj9BYazYqA78xBU9tZzrtmF/rQL9CGJt90o/oYnSfcS
+SL3haaw351LXWQ1XOsv1SmH3v6ymuxEpPPnEDmBELaTYsvvMIWJsmPZFFww++Kd7
+s/Jo0JFeUU7uNtI+gVosAIpVVuWfI/9tOIycz7I5Z7zjV+NR2OuZbYtW5F08KX4o
+2k/xuJIchcNFPtxPfw9dkDgscRbMckyFMrzuZ3IvrcGzk0J6iI5ytrv37bGpAXMz
+WK9mMMPebepNevmLjjo/QWoM968Sjv7ldlPS5AinHcXwsFv6dmmh8lJt7UOJWoKu
+lMD1cB2ksIGpMdv8iuqR42Rn/kn+17BhhUZcwDBaUXVdX6bKW7fxlUYbq+mlqIcf
+a9v8HF87M9ANbi9bq9onf9TD7nQ6Xf6vZci8TBPX+/GI0He6j31fTVQYW+NsQxvO
+J8xrx+e58CCLQNjxeIyPt+F+qk/QMiXw+LyxGVkV/XcGQT9X03jSDP6beJ5QG1JW
+9Q3qLv/YixWI7gPV9Mrhf2oRYTc/9KLFRhkE3SjKOTKuSSBKQ24fI+hEznamH71D
+66Hwez8/0et7AtTv9zvamv2OD5He6fMV4k+ePl6+qPfO5CdHtK+eCDZL5+4f5yrl
+gTcRFiq8fXbc5IaI5fbbc1KMM/2T0Mr7+Hwaco6FtXm0fmhCgTZRqY4pKiEIfmaz
+QwHNOOCrtMJ2VwsyMumt7xsOolGnizRev6lILH43qPcczQM7Gc5zRin80YvFt1Qm
+h/57Z0auR2h0fuX50MBO4XQ+26y5l6v4j902R66c0j3z2KHstKQ04J/h6LbuNQE4
+D6cu/lyfK69DxxX8wb8XaQkMUcJdo1LzqUGDAb3Kfn/A3P/JYc99MO9qv67+SxWb
+wYTyqKdWTd+1KbR/Rcn0Io5zI/QquX7FA1bxfMytjQ/X+l0fh0Pf+Hx97meH4fQL
+7/T8/sdTm9Tn8nELvedyhydLlPPTScINdXyLIq9wgIJr4fWPbp9ZhFh/56fdSgOG
+HDXg+gkXsN2Rddr4HQ5P3u+RhLzmSjhzoqY5EsPC4QvRlX9JXjB84rPV5USR66qa
+/kjw4156GJnzoXtydKJE53t6PHfZWO+3ujsfI6iAdshc7OFzGXiZB9PtItKodhYq
+nABkTKdcpu4+TOpf9h5piX5slsaBjkeTnj/Ba02ilboQfcDVigxrYn/iTH5ySWUW
+/lHtg78s5UZM8sErwhNe3N3w+6ZOMnU+5i86/xFNtqZfDdXTGy1H3PzGbdtZXYT+
+Ixx2vpwBYzbPVYHxKosM5rPiVmcTllI9nuoSfeh9ib4foFWauOpvdmhBDqpTpKTX
+u8EO2l2Z195G2RIV7TlKSxGWjR5sl/nALu1uzBeLd9zpSujzMTd1uTX9Qk/Q1S+r
+vaW6bm8qqPO4jb6Wx6XIkm321nrIF6Ae25d1+Dpv/P5G4NoLd2j6/EtENC3FeR5z
+oo7bA+tI8yEQRhiF0z1FlJXLD5ZbhNNWQm/j/IbzRfh8JtOFZU7ruShLvHXysW9S
+9V909tr9jn8/E/Hb5N/1NVNHnZu2HIUvJvHJiHd2ucmeI9PWUMnppmE65GQ5E9xV
+ZRlGEH0X85EvmHyEupkMrCC0oMv9RCq+/H8gcfpe00Hs/S+regT5p58cyYomh93v
+qvuw/A06BE/wzJESuYbN9pqYpoXqXFemW1NksHEJ2w+PYMJ27WJyD5FpaXB85VaW
+qMOhDfO8E3QdH8ybyKt/UgI8/tDGpFbyOlaVdIv1FXJhoLp8soAA4Djg6/KZ066N
+ZFYuS8WdjpSZGP4/Lw+1yaXlzNznc/k2uHe2uXP3uFuPcHx+Dm44utxldoO1uBPy
++jzOs14+MIgOjOHMVNqAbMd8fUedLlhJMCfMtm4uz01enLNKcMrtLlPIR37Yukh1
+YEMXYpm7eU4XU+j+Jj3pDyaXtXs+p1fWfTN/cy9/Oxs4umUXQ4uHh1kObtayDJ56
+/QMxiHobjHNKuKfMxsrYEwN+QVIyVjAwMDYuMjQ1AAA9IwJniiBLRkZDAAAXt0Ja
+aDQxQVkmU1lZtwytAACLf///////////////////+//////v//////////bv78//
+/+AXO133uwO2xB2UxIvbKXrCqCoURUBL2ytFI82AFdcOwMhVTHtk5rD3szEVNYD4
+aIQINCaMRoTaSn7SbSMJiYmEwieTEp+psqbMCp+VNPaFNpqbBNR7UmanlPUeKfqm
+j1PU0/VPU08o9Q9EeKHlPJtKbYqeTCYhN6U9T1NH6mp+lPyoGNTI/Knkyg1MggAg
+CaMEyQnqZoaaRtRtJpppppoDaTR6hpphGh6mmgHpMQBpkGTTEAAaAAAA00AZDag0
+ADIBkGgABqemiRNTI0k8aU0PRGRoAZlP0UAAAGgAAAyAADQaAAAaAAAAAAAAAAAA
+AaAAAAM0kgRBJ5MlPFP1Gj0jTTTUaekxNAbUGjTQMgaZANNAAAAaAADTQAAAAAAA
+ANAA0AAANADQ0QAAAAAAAAAaGgAAAAAAABoA0AAA0AAAAAAAAAAAAANAAAAAkSEI
+aTRpomp5DUxNNDTJPTKaep6T09Kemmo2JG0aTQ9ENogaaGhkABo0NHqaBoDTI0DC
+Gj0gNAMhoDQ9QMQNAGQAaDDwyMPIMlbG1vhRBTFo6JksSupgpAjPbY0ec02IGXjb
+eS+FBsh01+O4ZOaD+srUZCFaT4DRjVDLx7uKIsFtESIDUg1ZkhyCSYov05C00MtR
+BdNNa/AYPGOQZWcs+VegXOPrkushFbZ3mBoRD6WamClkpBaHZrUhUl02bIfRXX4w
+b3/9cW9nHDVxh2qFBxqgRKfmq7/Jc/tdJk05nVrGbckGVy2PnIy30CDhpWmqrSot
+K2bOnX0NbP1iy2cd0Na0ZmbRstm4MzMzbbMySTd35F7f+zPP8DC+NJLYcakkkkRd
+NZlupJt3OMFoDAD2g+N3FAMCydhIpoRHRQAdFI5nNg4ugEXHCYxkMyGCwtaJmial
+y0IMlpSYYM/weXNJAhFqS0GNmvaPEtYGjbvaucMdklOTmBX1vfVAkTYB1uXCSK64
+UNIixOqRKLuRCFtqIQtgwqaFrCkIYbbewErWABa+VGADWsJXJjfx5SJViLuwiGXq
+Ru6vCuwmU5CJiJz3UiBpmLv0r2wskxUhY4tzPVGQ9RMXJl65eLSNwZVwaSyGZ9Cm
+A3jztQUUpFeUryBTskW95iVwRMFrhBCwZBAFJBZvhMEMNoDJJlUoIhQkAkjbExp2
+YZio+ZYeAZUwmH1qUbdQixmxf0+61+aVgJ1hwxsO1yG3hFx4pfjc09ITVht0pG8u
+FtVFhPa1KE0gTRUSVXywkITucqk0Waz5Fs6qJpVHYdNrbYRFxnFsQGY1qmsTLjK6
+4QX5Rddo6krM/Bx9CqIAKq4CzVQYHrmIAd2EBhYmwVYwLvhzKIUrc2EirnGIvyuD
+O4YZDSwsVTA0BpVvUOjDErkCraBoSutcKwUSSLGhVvNYHLz3klgZD++wWsa/swLw
+gvNDY2De+sncOv8X2lq4HD95ZdwPuTIMXCwSbg4RrIqv+L0y6F17pqDecyQYPEj3
+iN/0BBeWZlJAyBMi5U3Q1zAlsK8IlDhaXGmvZrgISq5CfNjmUgxDeMggOKqxu4sI
+OrilS49Lkl1J3u3GjXTuH+rX+4ccyFAQnizCpPClcY77F59j63S6fr5vr+y99tuO
+7Ox7Wg/ljwhdyaK4xMmXczeJbx7x07htJNtC4xcQfAtvzeznLrN6MN/ILIBOI65I
+qIA2D5fHHj1XN4aN6TvOjWDaSbSWqxCSCvXUpzkNJAkWXAuTwF8k5uSJvQj/rVo0
+hAhEMEIYkCRGx9AX+byIuXWlLMbbVeliHNUL5AQYmNwLFu4SkmGD+UWtBMyVHQOQ
+ss0ggoVKSKOBUgnVS6ljt7WE1qXqJJ4QA1pEwYNLEaguEE1LtPNoVr5WzjbSbWPk
+V9OW3y9IneUDLoIV5pAkEFTEFGFVjeTFxtpzBBfGgycBxVCdz8eESBIzsamRchAa
+TQunQH8DHnpfod9QuAuRvc7JBlKUCYmCjMvynLcxIFohxCaYrDvGw4QbXZB7oWQ7
+hpoGlz23ayDfB8NrRRzdilsEQyQniu9ASLQg7RrGZnoTr1ai12IbCEUCGdFq03P5
+nBnRFAGmisQGcyykV9gKtcVMWLhCuVmXg86dndn7slUpRNSSEAU20oaWIm1maFTu
+E0DT4gTbg0nuhjtz3kNOz+i7sBm0bkXjxQWuLqlZEmp60ZTyRZJDUqKSEKg6hqcy
+ERxdU22CSNOO10RYUUiDVpKhPNdKTOIE1thp02sBNoNTFSht8WJtaBQ09qN3jd5r
+dOLX4IA5fevRyCCzDgRXfV4wzik4KROjmxmTMglBySlIMEzcXehnDXCRiZSlvwA2
+0YsIOROcm4UrIRFxJHctJH7OdN5u1aHVHb5UaLHpv48NgmFRE56KTSoaWunqm2st
+S0mrAdOiqcR12PWVbdVRJKcQ0DQuhwlAPcRtpxN3D4kbXJjToSYJIFw406G2CSaK
+jQMIJPZGlQmgyFhoCSzeGS1VSq5SKKQQxs5RqKUcVUNY57YUETb4mXzV84SPngKi
+nsce0mXByZq5BKUA9puHZWLNwQIYuDaJUNgG+E01E3pDYVNLKYQ0hsVesgV5gZY0
+htDsRdGtm0+iGnkN6+Ea9YJtUZNAkx2GgSoix12nTW0avTUfxR3oYcpvZ7IdtABE
+UhBcjG4qZtDZsS1JQHys243vhLaDTSvvTeBiJA2tmokqECTBcSOCAGkAxMKlVAva
+4IsLRaBBqhxDbcGtgdw03mFcLUaFuhtKuuEIEkUleJQwby/zwu9uvvZK4xTV+ECM
+a8lmzxKmqkBggYK1+xPdbmJclm6tSZhE/OSJtCEjs+unJIQkT9hCWgBJqGMS07Eh
+AJNmBiuVEVdTyjkIJkavuZmx2sJF13htgEZUCC23lZFOE6gWbM9WyYNJTM8yCQrb
+0Sx3OQvBML5cRATAQkSQkAJOAhoxpQkNi4ZiEVDbdtJAME0RXNDXGHA3M3Q0mm1o
+IEwbWpaM1DQCSMbGRCAu3iRIQiT6RlBpT1n3tfwvUXz3gIVlx3mEximY/kZW1kNG
+sgEJIrBisaEoGYPJ+1CQUYFBw+eGEHJQBpNHjErXUJY2iWHQ30hXwFBuMSxQ2lB5
+bg+/LX3euG6HsHUB1lFvBvaiaBrITVwkCTa1d0s9CHZCiDZjbWReKyrpPE2oSa7o
+LPrR4BJvys9ttjUpzETSSMxh8vsr9dXTwKBtK+1xCTGDQmNIaE29HmHdS5GSxpya
+MismcAUSEgSxHBrKtgsZzduG7vHZn16l3kFkVITtENIzS2JsiBwFTDlhgexsjBHv
+5HXOYxHBzoSDCcPZ0ctvkY9aS5XpoQuFYkGJgCsqjJZeUMNUEpDSbKcnUc1PifIA
+CbR2UoXawBlspkEBr9HBfvUi/MUakZVOf1WKYrqSaIXce62JOyhJLq3qJBloTA0F
+VbILEtM+heFmNRCFt70GJrExVJri0ArYbCRbADSGDBpBXxxb/6fo+s3C7uaL7RjM
+LV2IQBNrAJrKFeJwTsPnxbAsemirUx2lk1kaxschzdK4TQNJN5wQnolIFg401OZ4
+2na11LnT3lR+1k1TMJhiAjXMk0F1ooHnYlt9LKfJ3ZIOmeY+2l9bUQHWFNGyEyfj
+EAcu3kpGLq0Ez7XOS+EpAASRQTAYMATfVQibHLTT30zG732+pNe9za1JNt8sNJYn
+RjWuJ6jL5ILV0rcd9vT7X9fObvcXitpvJ2XBJE+PhX2HaTkyWeF9pwnlQNrTe9hV
+tzhA+ihZrDrHNmLcQjZbnv/IMubqq8egxY80t5n6vZ6U5TR6U9uZJvai1xtqAyCR
+NWkW52m00rDTEuO6BA4q2RHDWwbETF55rRsWLIgNW9qJCyMHPbTM/dMBmWMQSMxz
+4M2pRzt47SICxA327UqSCEERqMFybmYi3nUxePtLgHYplqRiw4ynMbXd/kiQ0LE0
+PKJSSCXA42ymziCpAxNWflzpzQdJZusahRFr6t6m+4p273/Taj7k+hZyNgBAgXAY
+8F7pTts6orLb8IA6o4TOwkwQYmKvKu9VwMrE7+GUhVIAgY9a8DyQMiDBkEAwh7S1
+KgCBfao8DK1CwSS8Z3WjL5MEgt93z2koUQCD/YxMBppiCMp7SDVSmkkIHptfGpeh
+t+M13Ccv1tavIASFiaQl6rBz3K4N3DSGwNkCibrvEAC0fQirOWnc4NVbcLKpFG1l
+NQXF/eqdT79wq1Mvlap3QSCLhcD2D3fCkKVWid4aSjtp9FOX1Uaf7P9eT93zd9Sv
+mj2yNLRUGzyI/0oONNSzmmkvJ5Cq2X2CdldIWMGZO57RJ8oyATAWTQmRmNkfh0Sx
+uuR/J9oUsomVy1AEntc0dlPivkqBkBqrxU3j5PnWkaI3ZRGc0gg9spCQEISh4xEU
+pMhVrnmDQLfLP8Ouqpx917MAw7hkjQk6BJFTAbXDsz3LSHIxo/gB8qrA1vbvdZZh
+LtR0frJdfdppX8nAQX/TAxOQ8+H6yw8a9i7/zJEfSYIhop59N/fhcWW2F14cj2Xc
+fyHaZ04lTO4uPnly91jwuFPaREuZVp8AxImIhlkxkAN61tWdWG7tEbaCgszh6VIz
+ThFnHo2Vi8SQXPrXCN7J9Tc9ZYiAYqoThV/u6SYsea5aZL8deOvKBQCgZZuIxX1z
+4EnfcqG176vY4VqMBIC4pMJz0WcHJYqN+j7BiwGoMBwExrIdTB7q4XIFLotcIpS0
+1MqyVsesvoQq7WObmGQXdMliMirSLcDuSx8Qy+4pIBgGDIyMp1qbonnGdcHYvU8S
+O0A8s/iua5oFdNZTWvbVI4FUH9sKcLiB3/fIAF+sB4n8q6L+UCfmbPcAo/crQ6b3
+HqhDBMY9J0q/jdz9GNYZ/1fbXdkUqAQKFePhtzJDRBZba27+LPQNMCcrHMq06F1T
+4QmLmkHt7LxB2pAczUO+T2O9bHEw/HWw+dYf2MoRDUw=
+`
+
+var outOfRangeSelector = []byte{
+	0x42, 0x5a, 0x68, 0x39, 0x31, 0x41, 0x59, 0x26,
+	0x53, 0x59, 0x4e, 0xec, 0xe8, 0x36, 0x00, 0x00,
+	0x02, 0x51, 0x80, 0x00, 0x10, 0x40, 0x00, 0x06,
+	0x44, 0x90, 0x80, 0x20, 0x00, 0x31, 0x06, 0x4c,
+	0x41, 0x01, 0xa7, 0xa9, 0xa5, 0x80, 0xbb, 0x94,
+	0x31, 0x17, 0x72, 0x45, 0x38, 0x50, 0x90, 0x00,
+	0x00, 0x00, 0x00,
+}
diff --git a/src/pkg/compress/bzip2/huffman.go b/src/compress/bzip2/huffman.go
similarity index 100%
rename from src/pkg/compress/bzip2/huffman.go
rename to src/compress/bzip2/huffman.go
diff --git a/src/compress/bzip2/move_to_front.go b/src/compress/bzip2/move_to_front.go
new file mode 100644
index 0000000..526dfb3
--- /dev/null
+++ b/src/compress/bzip2/move_to_front.go
@@ -0,0 +1,53 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package bzip2
+
+// moveToFrontDecoder implements a move-to-front list. Such a list is an
+// efficient way to transform a string with repeating elements into one with
+// many small valued numbers, which is suitable for entropy encoding. It works
+// by starting with an initial list of symbols and references symbols by their
+// index into that list. When a symbol is referenced, it's moved to the front
+// of the list. Thus, a repeated symbol ends up being encoded with many zeros,
+// as the symbol will be at the front of the list after the first access.
+type moveToFrontDecoder []byte
+
+// newMTFDecoder creates a move-to-front decoder with an explicit initial list
+// of symbols.
+func newMTFDecoder(symbols []byte) moveToFrontDecoder {
+	if len(symbols) > 256 {
+		panic("too many symbols")
+	}
+	return moveToFrontDecoder(symbols)
+}
+
+// newMTFDecoderWithRange creates a move-to-front decoder with an initial
+// symbol list of 0...n-1.
+func newMTFDecoderWithRange(n int) moveToFrontDecoder {
+	if n > 256 {
+		panic("newMTFDecoderWithRange: cannot have > 256 symbols")
+	}
+
+	m := make([]byte, n)
+	for i := 0; i < n; i++ {
+		m[i] = byte(i)
+	}
+	return moveToFrontDecoder(m)
+}
+
+func (m moveToFrontDecoder) Decode(n int) (b byte) {
+	// Implement move-to-front with a simple copy. This approach
+	// beats more sophisticated approaches in benchmarking, probably
+	// because it has high locality of reference inside of a
+	// single cache line (most move-to-front operations have n < 64).
+	b = m[n]
+	copy(m[1:], m[:n])
+	m[0] = b
+	return
+}
+
+// First returns the symbol at the front of the list.
+func (m moveToFrontDecoder) First() byte {
+	return m[0]
+}
diff --git a/src/pkg/compress/bzip2/testdata/Mark.Twain-Tom.Sawyer.txt.bz2 b/src/compress/bzip2/testdata/Mark.Twain-Tom.Sawyer.txt.bz2
similarity index 100%
rename from src/pkg/compress/bzip2/testdata/Mark.Twain-Tom.Sawyer.txt.bz2
rename to src/compress/bzip2/testdata/Mark.Twain-Tom.Sawyer.txt.bz2
diff --git a/src/pkg/compress/bzip2/testdata/e.txt.bz2 b/src/compress/bzip2/testdata/e.txt.bz2
similarity index 100%
rename from src/pkg/compress/bzip2/testdata/e.txt.bz2
rename to src/compress/bzip2/testdata/e.txt.bz2
diff --git a/src/pkg/compress/flate/copy.go b/src/compress/flate/copy.go
similarity index 100%
rename from src/pkg/compress/flate/copy.go
rename to src/compress/flate/copy.go
diff --git a/src/pkg/compress/flate/copy_test.go b/src/compress/flate/copy_test.go
similarity index 100%
rename from src/pkg/compress/flate/copy_test.go
rename to src/compress/flate/copy_test.go
diff --git a/src/pkg/compress/flate/deflate.go b/src/compress/flate/deflate.go
similarity index 100%
rename from src/pkg/compress/flate/deflate.go
rename to src/compress/flate/deflate.go
diff --git a/src/pkg/compress/flate/deflate_test.go b/src/compress/flate/deflate_test.go
similarity index 100%
rename from src/pkg/compress/flate/deflate_test.go
rename to src/compress/flate/deflate_test.go
diff --git a/src/compress/flate/fixedhuff.go b/src/compress/flate/fixedhuff.go
new file mode 100644
index 0000000..7df8b9a
--- /dev/null
+++ b/src/compress/flate/fixedhuff.go
@@ -0,0 +1,78 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package flate
+
+// autogenerated by go run gen.go -output fixedhuff.go, DO NOT EDIT
+
+var fixedHuffmanDecoder = huffmanDecoder{
+	7,
+	[huffmanNumChunks]uint32{
+		0x1007, 0x0508, 0x0108, 0x1188, 0x1107, 0x0708, 0x0308, 0x0c09,
+		0x1087, 0x0608, 0x0208, 0x0a09, 0x0008, 0x0808, 0x0408, 0x0e09,
+		0x1047, 0x0588, 0x0188, 0x0909, 0x1147, 0x0788, 0x0388, 0x0d09,
+		0x10c7, 0x0688, 0x0288, 0x0b09, 0x0088, 0x0888, 0x0488, 0x0f09,
+		0x1027, 0x0548, 0x0148, 0x11c8, 0x1127, 0x0748, 0x0348, 0x0c89,
+		0x10a7, 0x0648, 0x0248, 0x0a89, 0x0048, 0x0848, 0x0448, 0x0e89,
+		0x1067, 0x05c8, 0x01c8, 0x0989, 0x1167, 0x07c8, 0x03c8, 0x0d89,
+		0x10e7, 0x06c8, 0x02c8, 0x0b89, 0x00c8, 0x08c8, 0x04c8, 0x0f89,
+		0x1017, 0x0528, 0x0128, 0x11a8, 0x1117, 0x0728, 0x0328, 0x0c49,
+		0x1097, 0x0628, 0x0228, 0x0a49, 0x0028, 0x0828, 0x0428, 0x0e49,
+		0x1057, 0x05a8, 0x01a8, 0x0949, 0x1157, 0x07a8, 0x03a8, 0x0d49,
+		0x10d7, 0x06a8, 0x02a8, 0x0b49, 0x00a8, 0x08a8, 0x04a8, 0x0f49,
+		0x1037, 0x0568, 0x0168, 0x11e8, 0x1137, 0x0768, 0x0368, 0x0cc9,
+		0x10b7, 0x0668, 0x0268, 0x0ac9, 0x0068, 0x0868, 0x0468, 0x0ec9,
+		0x1077, 0x05e8, 0x01e8, 0x09c9, 0x1177, 0x07e8, 0x03e8, 0x0dc9,
+		0x10f7, 0x06e8, 0x02e8, 0x0bc9, 0x00e8, 0x08e8, 0x04e8, 0x0fc9,
+		0x1007, 0x0518, 0x0118, 0x1198, 0x1107, 0x0718, 0x0318, 0x0c29,
+		0x1087, 0x0618, 0x0218, 0x0a29, 0x0018, 0x0818, 0x0418, 0x0e29,
+		0x1047, 0x0598, 0x0198, 0x0929, 0x1147, 0x0798, 0x0398, 0x0d29,
+		0x10c7, 0x0698, 0x0298, 0x0b29, 0x0098, 0x0898, 0x0498, 0x0f29,
+		0x1027, 0x0558, 0x0158, 0x11d8, 0x1127, 0x0758, 0x0358, 0x0ca9,
+		0x10a7, 0x0658, 0x0258, 0x0aa9, 0x0058, 0x0858, 0x0458, 0x0ea9,
+		0x1067, 0x05d8, 0x01d8, 0x09a9, 0x1167, 0x07d8, 0x03d8, 0x0da9,
+		0x10e7, 0x06d8, 0x02d8, 0x0ba9, 0x00d8, 0x08d8, 0x04d8, 0x0fa9,
+		0x1017, 0x0538, 0x0138, 0x11b8, 0x1117, 0x0738, 0x0338, 0x0c69,
+		0x1097, 0x0638, 0x0238, 0x0a69, 0x0038, 0x0838, 0x0438, 0x0e69,
+		0x1057, 0x05b8, 0x01b8, 0x0969, 0x1157, 0x07b8, 0x03b8, 0x0d69,
+		0x10d7, 0x06b8, 0x02b8, 0x0b69, 0x00b8, 0x08b8, 0x04b8, 0x0f69,
+		0x1037, 0x0578, 0x0178, 0x11f8, 0x1137, 0x0778, 0x0378, 0x0ce9,
+		0x10b7, 0x0678, 0x0278, 0x0ae9, 0x0078, 0x0878, 0x0478, 0x0ee9,
+		0x1077, 0x05f8, 0x01f8, 0x09e9, 0x1177, 0x07f8, 0x03f8, 0x0de9,
+		0x10f7, 0x06f8, 0x02f8, 0x0be9, 0x00f8, 0x08f8, 0x04f8, 0x0fe9,
+		0x1007, 0x0508, 0x0108, 0x1188, 0x1107, 0x0708, 0x0308, 0x0c19,
+		0x1087, 0x0608, 0x0208, 0x0a19, 0x0008, 0x0808, 0x0408, 0x0e19,
+		0x1047, 0x0588, 0x0188, 0x0919, 0x1147, 0x0788, 0x0388, 0x0d19,
+		0x10c7, 0x0688, 0x0288, 0x0b19, 0x0088, 0x0888, 0x0488, 0x0f19,
+		0x1027, 0x0548, 0x0148, 0x11c8, 0x1127, 0x0748, 0x0348, 0x0c99,
+		0x10a7, 0x0648, 0x0248, 0x0a99, 0x0048, 0x0848, 0x0448, 0x0e99,
+		0x1067, 0x05c8, 0x01c8, 0x0999, 0x1167, 0x07c8, 0x03c8, 0x0d99,
+		0x10e7, 0x06c8, 0x02c8, 0x0b99, 0x00c8, 0x08c8, 0x04c8, 0x0f99,
+		0x1017, 0x0528, 0x0128, 0x11a8, 0x1117, 0x0728, 0x0328, 0x0c59,
+		0x1097, 0x0628, 0x0228, 0x0a59, 0x0028, 0x0828, 0x0428, 0x0e59,
+		0x1057, 0x05a8, 0x01a8, 0x0959, 0x1157, 0x07a8, 0x03a8, 0x0d59,
+		0x10d7, 0x06a8, 0x02a8, 0x0b59, 0x00a8, 0x08a8, 0x04a8, 0x0f59,
+		0x1037, 0x0568, 0x0168, 0x11e8, 0x1137, 0x0768, 0x0368, 0x0cd9,
+		0x10b7, 0x0668, 0x0268, 0x0ad9, 0x0068, 0x0868, 0x0468, 0x0ed9,
+		0x1077, 0x05e8, 0x01e8, 0x09d9, 0x1177, 0x07e8, 0x03e8, 0x0dd9,
+		0x10f7, 0x06e8, 0x02e8, 0x0bd9, 0x00e8, 0x08e8, 0x04e8, 0x0fd9,
+		0x1007, 0x0518, 0x0118, 0x1198, 0x1107, 0x0718, 0x0318, 0x0c39,
+		0x1087, 0x0618, 0x0218, 0x0a39, 0x0018, 0x0818, 0x0418, 0x0e39,
+		0x1047, 0x0598, 0x0198, 0x0939, 0x1147, 0x0798, 0x0398, 0x0d39,
+		0x10c7, 0x0698, 0x0298, 0x0b39, 0x0098, 0x0898, 0x0498, 0x0f39,
+		0x1027, 0x0558, 0x0158, 0x11d8, 0x1127, 0x0758, 0x0358, 0x0cb9,
+		0x10a7, 0x0658, 0x0258, 0x0ab9, 0x0058, 0x0858, 0x0458, 0x0eb9,
+		0x1067, 0x05d8, 0x01d8, 0x09b9, 0x1167, 0x07d8, 0x03d8, 0x0db9,
+		0x10e7, 0x06d8, 0x02d8, 0x0bb9, 0x00d8, 0x08d8, 0x04d8, 0x0fb9,
+		0x1017, 0x0538, 0x0138, 0x11b8, 0x1117, 0x0738, 0x0338, 0x0c79,
+		0x1097, 0x0638, 0x0238, 0x0a79, 0x0038, 0x0838, 0x0438, 0x0e79,
+		0x1057, 0x05b8, 0x01b8, 0x0979, 0x1157, 0x07b8, 0x03b8, 0x0d79,
+		0x10d7, 0x06b8, 0x02b8, 0x0b79, 0x00b8, 0x08b8, 0x04b8, 0x0f79,
+		0x1037, 0x0578, 0x0178, 0x11f8, 0x1137, 0x0778, 0x0378, 0x0cf9,
+		0x10b7, 0x0678, 0x0278, 0x0af9, 0x0078, 0x0878, 0x0478, 0x0ef9,
+		0x1077, 0x05f8, 0x01f8, 0x09f9, 0x1177, 0x07f8, 0x03f8, 0x0df9,
+		0x10f7, 0x06f8, 0x02f8, 0x0bf9, 0x00f8, 0x08f8, 0x04f8, 0x0ff9,
+	},
+	nil, 0,
+}
diff --git a/src/pkg/compress/flate/flate_test.go b/src/compress/flate/flate_test.go
similarity index 100%
rename from src/pkg/compress/flate/flate_test.go
rename to src/compress/flate/flate_test.go
diff --git a/src/compress/flate/gen.go b/src/compress/flate/gen.go
new file mode 100644
index 0000000..6288ecd
--- /dev/null
+++ b/src/compress/flate/gen.go
@@ -0,0 +1,190 @@
+// Copyright 2012 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build ignore
+
+// This program generates fixedhuff.go
+// Invoke as
+//
+//	go run gen.go -output fixedhuff.go
+
+package main
+
+import (
+	"bytes"
+	"flag"
+	"fmt"
+	"go/format"
+	"io/ioutil"
+	"log"
+)
+
+var filename = flag.String("output", "fixedhuff.go", "output file name")
+
+const maxCodeLen = 16
+
+// Note: the definition of the huffmanDecoder struct is copied from
+// inflate.go, as it is private to the implementation.
+
+// chunk & 15 is number of bits
+// chunk >> 4 is value, including table link
+
+const (
+	huffmanChunkBits  = 9
+	huffmanNumChunks  = 1 << huffmanChunkBits
+	huffmanCountMask  = 15
+	huffmanValueShift = 4
+)
+
+type huffmanDecoder struct {
+	min      int                      // the minimum code length
+	chunks   [huffmanNumChunks]uint32 // chunks as described above
+	links    [][]uint32               // overflow links
+	linkMask uint32                   // mask the width of the link table
+}
+
+// Initialize Huffman decoding tables from array of code lengths.
+func (h *huffmanDecoder) init(bits []int) bool {
+	// Count number of codes of each length,
+	// compute min and max length.
+	var count [maxCodeLen]int
+	var min, max int
+	for _, n := range bits {
+		if n == 0 {
+			continue
+		}
+		if min == 0 || n < min {
+			min = n
+		}
+		if n > max {
+			max = n
+		}
+		count[n]++
+	}
+	if max == 0 {
+		return false
+	}
+
+	h.min = min
+	var linkBits uint
+	var numLinks int
+	if max > huffmanChunkBits {
+		linkBits = uint(max) - huffmanChunkBits
+		numLinks = 1 << linkBits
+		h.linkMask = uint32(numLinks - 1)
+	}
+	code := 0
+	var nextcode [maxCodeLen]int
+	for i := min; i <= max; i++ {
+		if i == huffmanChunkBits+1 {
+			// create link tables
+			link := code >> 1
+			h.links = make([][]uint32, huffmanNumChunks-link)
+			for j := uint(link); j < huffmanNumChunks; j++ {
+				reverse := int(reverseByte[j>>8]) | int(reverseByte[j&0xff])<<8
+				reverse >>= uint(16 - huffmanChunkBits)
+				off := j - uint(link)
+				h.chunks[reverse] = uint32(off<<huffmanValueShift + uint(i))
+				h.links[off] = make([]uint32, 1<<linkBits)
+			}
+		}
+		n := count[i]
+		nextcode[i] = code
+		code += n
+		code <<= 1
+	}
+
+	for i, n := range bits {
+		if n == 0 {
+			continue
+		}
+		code := nextcode[n]
+		nextcode[n]++
+		chunk := uint32(i<<huffmanValueShift | n)
+		reverse := int(reverseByte[code>>8]) | int(reverseByte[code&0xff])<<8
+		reverse >>= uint(16 - n)
+		if n <= huffmanChunkBits {
+			for off := reverse; off < huffmanNumChunks; off += 1 << uint(n) {
+				h.chunks[off] = chunk
+			}
+		} else {
+			linktab := h.links[h.chunks[reverse&(huffmanNumChunks-1)]>>huffmanValueShift]
+			reverse >>= huffmanChunkBits
+			for off := reverse; off < numLinks; off += 1 << uint(n-huffmanChunkBits) {
+				linktab[off] = chunk
+			}
+		}
+	}
+	return true
+}
+
+func main() {
+	flag.Parse()
+
+	var h huffmanDecoder
+	var bits [288]int
+	initReverseByte()
+	for i := 0; i < 144; i++ {
+		bits[i] = 8
+	}
+	for i := 144; i < 256; i++ {
+		bits[i] = 9
+	}
+	for i := 256; i < 280; i++ {
+		bits[i] = 7
+	}
+	for i := 280; i < 288; i++ {
+		bits[i] = 8
+	}
+	h.init(bits[:])
+
+	var buf bytes.Buffer
+
+	fmt.Fprintf(&buf, `// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.`+"\n\n")
+
+	fmt.Fprintln(&buf, "package flate")
+	fmt.Fprintln(&buf)
+	fmt.Fprintln(&buf, "// autogenerated by go run gen.go -output fixedhuff.go, DO NOT EDIT")
+	fmt.Fprintln(&buf)
+	fmt.Fprintln(&buf, "var fixedHuffmanDecoder = huffmanDecoder{")
+	fmt.Fprintf(&buf, "\t%d,\n", h.min)
+	fmt.Fprintln(&buf, "\t[huffmanNumChunks]uint32{")
+	for i := 0; i < huffmanNumChunks; i++ {
+		if i&7 == 0 {
+			fmt.Fprintf(&buf, "\t\t")
+		} else {
+			fmt.Fprintf(&buf, " ")
+		}
+		fmt.Fprintf(&buf, "0x%04x,", h.chunks[i])
+		if i&7 == 7 {
+			fmt.Fprintln(&buf)
+		}
+	}
+	fmt.Fprintln(&buf, "\t},")
+	fmt.Fprintln(&buf, "\tnil, 0,")
+	fmt.Fprintln(&buf, "}")
+
+	data, err := format.Source(buf.Bytes())
+	if err != nil {
+		log.Fatal(err)
+	}
+	err = ioutil.WriteFile(*filename, data, 0644)
+	if err != nil {
+		log.Fatal(err)
+	}
+}
+
+var reverseByte [256]byte
+
+func initReverseByte() {
+	for x := 0; x < 256; x++ {
+		var result byte
+		for i := uint(0); i < 8; i++ {
+			result |= byte(((x >> i) & 1) << (7 - i))
+		}
+		reverseByte[x] = result
+	}
+}
diff --git a/src/pkg/compress/flate/huffman_bit_writer.go b/src/compress/flate/huffman_bit_writer.go
similarity index 100%
rename from src/pkg/compress/flate/huffman_bit_writer.go
rename to src/compress/flate/huffman_bit_writer.go
diff --git a/src/pkg/compress/flate/huffman_code.go b/src/compress/flate/huffman_code.go
similarity index 100%
rename from src/pkg/compress/flate/huffman_code.go
rename to src/compress/flate/huffman_code.go
diff --git a/src/compress/flate/inflate.go b/src/compress/flate/inflate.go
new file mode 100644
index 0000000..76519bb
--- /dev/null
+++ b/src/compress/flate/inflate.go
@@ -0,0 +1,739 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:generate go run gen.go -output fixedhuff.go
+
+// Package flate implements the DEFLATE compressed data format, described in
+// RFC 1951.  The gzip and zlib packages implement access to DEFLATE-based file
+// formats.
+package flate
+
+import (
+	"bufio"
+	"io"
+	"strconv"
+)
+
+const (
+	maxCodeLen = 16    // max length of Huffman code
+	maxHist    = 32768 // max history required
+	// The next three numbers come from the RFC, section 3.2.7.
+	maxLit   = 286
+	maxDist  = 32
+	numCodes = 19 // number of codes in Huffman meta-code
+)
+
+// A CorruptInputError reports the presence of corrupt input at a given offset.
+type CorruptInputError int64
+
+func (e CorruptInputError) Error() string {
+	return "flate: corrupt input before offset " + strconv.FormatInt(int64(e), 10)
+}
+
+// An InternalError reports an error in the flate code itself.
+type InternalError string
+
+func (e InternalError) Error() string { return "flate: internal error: " + string(e) }
+
+// A ReadError reports an error encountered while reading input.
+type ReadError struct {
+	Offset int64 // byte offset where error occurred
+	Err    error // error returned by underlying Read
+}
+
+func (e *ReadError) Error() string {
+	return "flate: read error at offset " + strconv.FormatInt(e.Offset, 10) + ": " + e.Err.Error()
+}
+
+// A WriteError reports an error encountered while writing output.
+type WriteError struct {
+	Offset int64 // byte offset where error occurred
+	Err    error // error returned by underlying Write
+}
+
+func (e *WriteError) Error() string {
+	return "flate: write error at offset " + strconv.FormatInt(e.Offset, 10) + ": " + e.Err.Error()
+}
+
+// Resetter resets a ReadCloser returned by NewReader or NewReaderDict to
+// to switch to a new underlying Reader. This permits reusing a ReadCloser
+// instead of allocating a new one.
+type Resetter interface {
+	// Reset discards any buffered data and resets the Resetter as if it was
+	// newly initialized with the given reader.
+	Reset(r io.Reader, dict []byte) error
+}
+
+// Note that much of the implementation of huffmanDecoder is also copied
+// into gen.go (in package main) for the purpose of precomputing the
+// fixed huffman tables so they can be included statically.
+
+// The data structure for decoding Huffman tables is based on that of
+// zlib. There is a lookup table of a fixed bit width (huffmanChunkBits),
+// For codes smaller than the table width, there are multiple entries
+// (each combination of trailing bits has the same value). For codes
+// larger than the table width, the table contains a link to an overflow
+// table. The width of each entry in the link table is the maximum code
+// size minus the chunk width.
+
+// Note that you can do a lookup in the table even without all bits
+// filled. Since the extra bits are zero, and the DEFLATE Huffman codes
+// have the property that shorter codes come before longer ones, the
+// bit length estimate in the result is a lower bound on the actual
+// number of bits.
+
+// chunk & 15 is number of bits
+// chunk >> 4 is value, including table link
+
+const (
+	huffmanChunkBits  = 9
+	huffmanNumChunks  = 1 << huffmanChunkBits
+	huffmanCountMask  = 15
+	huffmanValueShift = 4
+)
+
+type huffmanDecoder struct {
+	min      int                      // the minimum code length
+	chunks   [huffmanNumChunks]uint32 // chunks as described above
+	links    [][]uint32               // overflow links
+	linkMask uint32                   // mask the width of the link table
+}
+
+// Initialize Huffman decoding tables from array of code lengths.
+func (h *huffmanDecoder) init(bits []int) bool {
+	if h.min != 0 {
+		*h = huffmanDecoder{}
+	}
+
+	// Count number of codes of each length,
+	// compute min and max length.
+	var count [maxCodeLen]int
+	var min, max int
+	for _, n := range bits {
+		if n == 0 {
+			continue
+		}
+		if min == 0 || n < min {
+			min = n
+		}
+		if n > max {
+			max = n
+		}
+		count[n]++
+	}
+	if max == 0 {
+		return false
+	}
+
+	h.min = min
+	var linkBits uint
+	var numLinks int
+	if max > huffmanChunkBits {
+		linkBits = uint(max) - huffmanChunkBits
+		numLinks = 1 << linkBits
+		h.linkMask = uint32(numLinks - 1)
+	}
+	code := 0
+	var nextcode [maxCodeLen]int
+	for i := min; i <= max; i++ {
+		if i == huffmanChunkBits+1 {
+			// create link tables
+			link := code >> 1
+			if huffmanNumChunks < link {
+				return false
+			}
+			h.links = make([][]uint32, huffmanNumChunks-link)
+			for j := uint(link); j < huffmanNumChunks; j++ {
+				reverse := int(reverseByte[j>>8]) | int(reverseByte[j&0xff])<<8
+				reverse >>= uint(16 - huffmanChunkBits)
+				off := j - uint(link)
+				h.chunks[reverse] = uint32(off<<huffmanValueShift + uint(i))
+				h.links[off] = make([]uint32, 1<<linkBits)
+			}
+		}
+		n := count[i]
+		nextcode[i] = code
+		code += n
+		code <<= 1
+	}
+
+	for i, n := range bits {
+		if n == 0 {
+			continue
+		}
+		code := nextcode[n]
+		nextcode[n]++
+		chunk := uint32(i<<huffmanValueShift | n)
+		reverse := int(reverseByte[code>>8]) | int(reverseByte[code&0xff])<<8
+		reverse >>= uint(16 - n)
+		if n <= huffmanChunkBits {
+			for off := reverse; off < huffmanNumChunks; off += 1 << uint(n) {
+				h.chunks[off] = chunk
+			}
+		} else {
+			value := h.chunks[reverse&(huffmanNumChunks-1)] >> huffmanValueShift
+			if value >= uint32(len(h.links)) {
+				return false
+			}
+			linktab := h.links[value]
+			reverse >>= huffmanChunkBits
+			for off := reverse; off < numLinks; off += 1 << uint(n-huffmanChunkBits) {
+				linktab[off] = chunk
+			}
+		}
+	}
+	return true
+}
+
+// The actual read interface needed by NewReader.
+// If the passed in io.Reader does not also have ReadByte,
+// the NewReader will introduce its own buffering.
+type Reader interface {
+	io.Reader
+	io.ByteReader
+}
+
+// Decompress state.
+type decompressor struct {
+	// Input source.
+	r       Reader
+	roffset int64
+	woffset int64
+
+	// Input bits, in top of b.
+	b  uint32
+	nb uint
+
+	// Huffman decoders for literal/length, distance.
+	h1, h2 huffmanDecoder
+
+	// Length arrays used to define Huffman codes.
+	bits     *[maxLit + maxDist]int
+	codebits *[numCodes]int
+
+	// Output history, buffer.
+	hist  *[maxHist]byte
+	hp    int  // current output position in buffer
+	hw    int  // have written hist[0:hw] already
+	hfull bool // buffer has filled at least once
+
+	// Temporary buffer (avoids repeated allocation).
+	buf [4]byte
+
+	// Next step in the decompression,
+	// and decompression state.
+	step     func(*decompressor)
+	final    bool
+	err      error
+	toRead   []byte
+	hl, hd   *huffmanDecoder
+	copyLen  int
+	copyDist int
+}
+
+func (f *decompressor) nextBlock() {
+	if f.final {
+		if f.hw != f.hp {
+			f.flush((*decompressor).nextBlock)
+			return
+		}
+		f.err = io.EOF
+		return
+	}
+	for f.nb < 1+2 {
+		if f.err = f.moreBits(); f.err != nil {
+			return
+		}
+	}
+	f.final = f.b&1 == 1
+	f.b >>= 1
+	typ := f.b & 3
+	f.b >>= 2
+	f.nb -= 1 + 2
+	switch typ {
+	case 0:
+		f.dataBlock()
+	case 1:
+		// compressed, fixed Huffman tables
+		f.hl = &fixedHuffmanDecoder
+		f.hd = nil
+		f.huffmanBlock()
+	case 2:
+		// compressed, dynamic Huffman tables
+		if f.err = f.readHuffman(); f.err != nil {
+			break
+		}
+		f.hl = &f.h1
+		f.hd = &f.h2
+		f.huffmanBlock()
+	default:
+		// 3 is reserved.
+		f.err = CorruptInputError(f.roffset)
+	}
+}
+
+func (f *decompressor) Read(b []byte) (int, error) {
+	for {
+		if len(f.toRead) > 0 {
+			n := copy(b, f.toRead)
+			f.toRead = f.toRead[n:]
+			return n, nil
+		}
+		if f.err != nil {
+			return 0, f.err
+		}
+		f.step(f)
+	}
+}
+
+func (f *decompressor) Close() error {
+	if f.err == io.EOF {
+		return nil
+	}
+	return f.err
+}
+
+// RFC 1951 section 3.2.7.
+// Compression with dynamic Huffman codes
+
+var codeOrder = [...]int{16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}
+
+func (f *decompressor) readHuffman() error {
+	// HLIT[5], HDIST[5], HCLEN[4].
+	for f.nb < 5+5+4 {
+		if err := f.moreBits(); err != nil {
+			return err
+		}
+	}
+	nlit := int(f.b&0x1F) + 257
+	if nlit > maxLit {
+		return CorruptInputError(f.roffset)
+	}
+	f.b >>= 5
+	ndist := int(f.b&0x1F) + 1
+	// maxDist is 32, so ndist is always valid.
+	f.b >>= 5
+	nclen := int(f.b&0xF) + 4
+	// numCodes is 19, so nclen is always valid.
+	f.b >>= 4
+	f.nb -= 5 + 5 + 4
+
+	// (HCLEN+4)*3 bits: code lengths in the magic codeOrder order.
+	for i := 0; i < nclen; i++ {
+		for f.nb < 3 {
+			if err := f.moreBits(); err != nil {
+				return err
+			}
+		}
+		f.codebits[codeOrder[i]] = int(f.b & 0x7)
+		f.b >>= 3
+		f.nb -= 3
+	}
+	for i := nclen; i < len(codeOrder); i++ {
+		f.codebits[codeOrder[i]] = 0
+	}
+	if !f.h1.init(f.codebits[0:]) {
+		return CorruptInputError(f.roffset)
+	}
+
+	// HLIT + 257 code lengths, HDIST + 1 code lengths,
+	// using the code length Huffman code.
+	for i, n := 0, nlit+ndist; i < n; {
+		x, err := f.huffSym(&f.h1)
+		if err != nil {
+			return err
+		}
+		if x < 16 {
+			// Actual length.
+			f.bits[i] = x
+			i++
+			continue
+		}
+		// Repeat previous length or zero.
+		var rep int
+		var nb uint
+		var b int
+		switch x {
+		default:
+			return InternalError("unexpected length code")
+		case 16:
+			rep = 3
+			nb = 2
+			if i == 0 {
+				return CorruptInputError(f.roffset)
+			}
+			b = f.bits[i-1]
+		case 17:
+			rep = 3
+			nb = 3
+			b = 0
+		case 18:
+			rep = 11
+			nb = 7
+			b = 0
+		}
+		for f.nb < nb {
+			if err := f.moreBits(); err != nil {
+				return err
+			}
+		}
+		rep += int(f.b & uint32(1<<nb-1))
+		f.b >>= nb
+		f.nb -= nb
+		if i+rep > n {
+			return CorruptInputError(f.roffset)
+		}
+		for j := 0; j < rep; j++ {
+			f.bits[i] = b
+			i++
+		}
+	}
+
+	if !f.h1.init(f.bits[0:nlit]) || !f.h2.init(f.bits[nlit:nlit+ndist]) {
+		return CorruptInputError(f.roffset)
+	}
+
+	return nil
+}
+
+// Decode a single Huffman block from f.
+// hl and hd are the Huffman states for the lit/length values
+// and the distance values, respectively.  If hd == nil, using the
+// fixed distance encoding associated with fixed Huffman blocks.
+func (f *decompressor) huffmanBlock() {
+	for {
+		v, err := f.huffSym(f.hl)
+		if err != nil {
+			f.err = err
+			return
+		}
+		var n uint // number of bits extra
+		var length int
+		switch {
+		case v < 256:
+			f.hist[f.hp] = byte(v)
+			f.hp++
+			if f.hp == len(f.hist) {
+				// After the flush, continue this loop.
+				f.flush((*decompressor).huffmanBlock)
+				return
+			}
+			continue
+		case v == 256:
+			// Done with huffman block; read next block.
+			f.step = (*decompressor).nextBlock
+			return
+		// otherwise, reference to older data
+		case v < 265:
+			length = v - (257 - 3)
+			n = 0
+		case v < 269:
+			length = v*2 - (265*2 - 11)
+			n = 1
+		case v < 273:
+			length = v*4 - (269*4 - 19)
+			n = 2
+		case v < 277:
+			length = v*8 - (273*8 - 35)
+			n = 3
+		case v < 281:
+			length = v*16 - (277*16 - 67)
+			n = 4
+		case v < 285:
+			length = v*32 - (281*32 - 131)
+			n = 5
+		default:
+			length = 258
+			n = 0
+		}
+		if n > 0 {
+			for f.nb < n {
+				if err = f.moreBits(); err != nil {
+					f.err = err
+					return
+				}
+			}
+			length += int(f.b & uint32(1<<n-1))
+			f.b >>= n
+			f.nb -= n
+		}
+
+		var dist int
+		if f.hd == nil {
+			for f.nb < 5 {
+				if err = f.moreBits(); err != nil {
+					f.err = err
+					return
+				}
+			}
+			dist = int(reverseByte[(f.b&0x1F)<<3])
+			f.b >>= 5
+			f.nb -= 5
+		} else {
+			if dist, err = f.huffSym(f.hd); err != nil {
+				f.err = err
+				return
+			}
+		}
+
+		switch {
+		case dist < 4:
+			dist++
+		case dist >= 30:
+			f.err = CorruptInputError(f.roffset)
+			return
+		default:
+			nb := uint(dist-2) >> 1
+			// have 1 bit in bottom of dist, need nb more.
+			extra := (dist & 1) << nb
+			for f.nb < nb {
+				if err = f.moreBits(); err != nil {
+					f.err = err
+					return
+				}
+			}
+			extra |= int(f.b & uint32(1<<nb-1))
+			f.b >>= nb
+			f.nb -= nb
+			dist = 1<<(nb+1) + 1 + extra
+		}
+
+		// Copy history[-dist:-dist+length] into output.
+		if dist > len(f.hist) {
+			f.err = InternalError("bad history distance")
+			return
+		}
+
+		// No check on length; encoding can be prescient.
+		if !f.hfull && dist > f.hp {
+			f.err = CorruptInputError(f.roffset)
+			return
+		}
+
+		f.copyLen, f.copyDist = length, dist
+		if f.copyHist() {
+			return
+		}
+	}
+}
+
+// copyHist copies f.copyLen bytes from f.hist (f.copyDist bytes ago) to itself.
+// It reports whether the f.hist buffer is full.
+func (f *decompressor) copyHist() bool {
+	p := f.hp - f.copyDist
+	if p < 0 {
+		p += len(f.hist)
+	}
+	for f.copyLen > 0 {
+		n := f.copyLen
+		if x := len(f.hist) - f.hp; n > x {
+			n = x
+		}
+		if x := len(f.hist) - p; n > x {
+			n = x
+		}
+		forwardCopy(f.hist[:], f.hp, p, n)
+		p += n
+		f.hp += n
+		f.copyLen -= n
+		if f.hp == len(f.hist) {
+			// After flush continue copying out of history.
+			f.flush((*decompressor).copyHuff)
+			return true
+		}
+		if p == len(f.hist) {
+			p = 0
+		}
+	}
+	return false
+}
+
+func (f *decompressor) copyHuff() {
+	if f.copyHist() {
+		return
+	}
+	f.huffmanBlock()
+}
+
+// Copy a single uncompressed data block from input to output.
+func (f *decompressor) dataBlock() {
+	// Uncompressed.
+	// Discard current half-byte.
+	f.nb = 0
+	f.b = 0
+
+	// Length then ones-complement of length.
+	nr, err := io.ReadFull(f.r, f.buf[0:4])
+	f.roffset += int64(nr)
+	if err != nil {
+		f.err = &ReadError{f.roffset, err}
+		return
+	}
+	n := int(f.buf[0]) | int(f.buf[1])<<8
+	nn := int(f.buf[2]) | int(f.buf[3])<<8
+	if uint16(nn) != uint16(^n) {
+		f.err = CorruptInputError(f.roffset)
+		return
+	}
+
+	if n == 0 {
+		// 0-length block means sync
+		f.flush((*decompressor).nextBlock)
+		return
+	}
+
+	f.copyLen = n
+	f.copyData()
+}
+
+// copyData copies f.copyLen bytes from the underlying reader into f.hist.
+// It pauses for reads when f.hist is full.
+func (f *decompressor) copyData() {
+	n := f.copyLen
+	for n > 0 {
+		m := len(f.hist) - f.hp
+		if m > n {
+			m = n
+		}
+		m, err := io.ReadFull(f.r, f.hist[f.hp:f.hp+m])
+		f.roffset += int64(m)
+		if err != nil {
+			f.err = &ReadError{f.roffset, err}
+			return
+		}
+		n -= m
+		f.hp += m
+		if f.hp == len(f.hist) {
+			f.copyLen = n
+			f.flush((*decompressor).copyData)
+			return
+		}
+	}
+	f.step = (*decompressor).nextBlock
+}
+
+func (f *decompressor) setDict(dict []byte) {
+	if len(dict) > len(f.hist) {
+		// Will only remember the tail.
+		dict = dict[len(dict)-len(f.hist):]
+	}
+
+	f.hp = copy(f.hist[:], dict)
+	if f.hp == len(f.hist) {
+		f.hp = 0
+		f.hfull = true
+	}
+	f.hw = f.hp
+}
+
+func (f *decompressor) moreBits() error {
+	c, err := f.r.ReadByte()
+	if err != nil {
+		if err == io.EOF {
+			err = io.ErrUnexpectedEOF
+		}
+		return err
+	}
+	f.roffset++
+	f.b |= uint32(c) << f.nb
+	f.nb += 8
+	return nil
+}
+
+// Read the next Huffman-encoded symbol from f according to h.
+func (f *decompressor) huffSym(h *huffmanDecoder) (int, error) {
+	n := uint(h.min)
+	for {
+		for f.nb < n {
+			if err := f.moreBits(); err != nil {
+				return 0, err
+			}
+		}
+		chunk := h.chunks[f.b&(huffmanNumChunks-1)]
+		n = uint(chunk & huffmanCountMask)
+		if n > huffmanChunkBits {
+			chunk = h.links[chunk>>huffmanValueShift][(f.b>>huffmanChunkBits)&h.linkMask]
+			n = uint(chunk & huffmanCountMask)
+			if n == 0 {
+				f.err = CorruptInputError(f.roffset)
+				return 0, f.err
+			}
+		}
+		if n <= f.nb {
+			f.b >>= n
+			f.nb -= n
+			return int(chunk >> huffmanValueShift), nil
+		}
+	}
+}
+
+// Flush any buffered output to the underlying writer.
+func (f *decompressor) flush(step func(*decompressor)) {
+	f.toRead = f.hist[f.hw:f.hp]
+	f.woffset += int64(f.hp - f.hw)
+	f.hw = f.hp
+	if f.hp == len(f.hist) {
+		f.hp = 0
+		f.hw = 0
+		f.hfull = true
+	}
+	f.step = step
+}
+
+func makeReader(r io.Reader) Reader {
+	if rr, ok := r.(Reader); ok {
+		return rr
+	}
+	return bufio.NewReader(r)
+}
+
+func (f *decompressor) Reset(r io.Reader, dict []byte) error {
+	*f = decompressor{
+		r:        makeReader(r),
+		bits:     f.bits,
+		codebits: f.codebits,
+		hist:     f.hist,
+		step:     (*decompressor).nextBlock,
+	}
+	if dict != nil {
+		f.setDict(dict)
+	}
+	return nil
+}
+
+// NewReader returns a new ReadCloser that can be used
+// to read the uncompressed version of r.
+// If r does not also implement io.ByteReader,
+// the decompressor may read more data than necessary from r.
+// It is the caller's responsibility to call Close on the ReadCloser
+// when finished reading.
+//
+// The ReadCloser returned by NewReader also implements Resetter.
+func NewReader(r io.Reader) io.ReadCloser {
+	var f decompressor
+	f.bits = new([maxLit + maxDist]int)
+	f.codebits = new([numCodes]int)
+	f.r = makeReader(r)
+	f.hist = new([maxHist]byte)
+	f.step = (*decompressor).nextBlock
+	return &f
+}
+
+// NewReaderDict is like NewReader but initializes the reader
+// with a preset dictionary.  The returned Reader behaves as if
+// the uncompressed data stream started with the given dictionary,
+// which has already been read.  NewReaderDict is typically used
+// to read data compressed by NewWriterDict.
+//
+// The ReadCloser returned by NewReader also implements Resetter.
+func NewReaderDict(r io.Reader, dict []byte) io.ReadCloser {
+	var f decompressor
+	f.r = makeReader(r)
+	f.hist = new([maxHist]byte)
+	f.bits = new([maxLit + maxDist]int)
+	f.codebits = new([numCodes]int)
+	f.step = (*decompressor).nextBlock
+	f.setDict(dict)
+	return &f
+}
diff --git a/src/compress/flate/inflate_test.go b/src/compress/flate/inflate_test.go
new file mode 100644
index 0000000..9f25d30
--- /dev/null
+++ b/src/compress/flate/inflate_test.go
@@ -0,0 +1,39 @@
+// 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 flate
+
+import (
+	"bytes"
+	"io"
+	"testing"
+)
+
+func TestReset(t *testing.T) {
+	ss := []string{
+		"lorem ipsum izzle fo rizzle",
+		"the quick brown fox jumped over",
+	}
+
+	deflated := make([]bytes.Buffer, 2)
+	for i, s := range ss {
+		w, _ := NewWriter(&deflated[i], 1)
+		w.Write([]byte(s))
+		w.Close()
+	}
+
+	inflated := make([]bytes.Buffer, 2)
+
+	f := NewReader(&deflated[0])
+	io.Copy(&inflated[0], f)
+	f.(Resetter).Reset(&deflated[1], nil)
+	io.Copy(&inflated[1], f)
+	f.Close()
+
+	for i, s := range ss {
+		if s != inflated[i].String() {
+			t.Errorf("inflated[%d]:\ngot  %q\nwant %q", i, inflated[i], s)
+		}
+	}
+}
diff --git a/src/pkg/compress/flate/reader_test.go b/src/compress/flate/reader_test.go
similarity index 100%
rename from src/pkg/compress/flate/reader_test.go
rename to src/compress/flate/reader_test.go
diff --git a/src/pkg/compress/flate/reverse_bits.go b/src/compress/flate/reverse_bits.go
similarity index 100%
rename from src/pkg/compress/flate/reverse_bits.go
rename to src/compress/flate/reverse_bits.go
diff --git a/src/pkg/compress/flate/token.go b/src/compress/flate/token.go
similarity index 100%
rename from src/pkg/compress/flate/token.go
rename to src/compress/flate/token.go
diff --git a/src/pkg/compress/flate/writer_test.go b/src/compress/flate/writer_test.go
similarity index 100%
rename from src/pkg/compress/flate/writer_test.go
rename to src/compress/flate/writer_test.go
diff --git a/src/compress/gzip/gunzip.go b/src/compress/gzip/gunzip.go
new file mode 100644
index 0000000..72ee55c
--- /dev/null
+++ b/src/compress/gzip/gunzip.go
@@ -0,0 +1,287 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package gzip implements reading and writing of gzip format compressed files,
+// as specified in RFC 1952.
+package gzip
+
+import (
+	"bufio"
+	"compress/flate"
+	"errors"
+	"hash"
+	"hash/crc32"
+	"io"
+	"time"
+)
+
+const (
+	gzipID1     = 0x1f
+	gzipID2     = 0x8b
+	gzipDeflate = 8
+	flagText    = 1 << 0
+	flagHdrCrc  = 1 << 1
+	flagExtra   = 1 << 2
+	flagName    = 1 << 3
+	flagComment = 1 << 4
+)
+
+func makeReader(r io.Reader) flate.Reader {
+	if rr, ok := r.(flate.Reader); ok {
+		return rr
+	}
+	return bufio.NewReader(r)
+}
+
+var (
+	// ErrChecksum is returned when reading GZIP data that has an invalid checksum.
+	ErrChecksum = errors.New("gzip: invalid checksum")
+	// ErrHeader is returned when reading GZIP data that has an invalid header.
+	ErrHeader = errors.New("gzip: invalid header")
+)
+
+// The gzip file stores a header giving metadata about the compressed file.
+// That header is exposed as the fields of the Writer and Reader structs.
+type Header struct {
+	Comment string    // comment
+	Extra   []byte    // "extra data"
+	ModTime time.Time // modification time
+	Name    string    // file name
+	OS      byte      // operating system type
+}
+
+// A Reader is an io.Reader that can be read to retrieve
+// uncompressed data from a gzip-format compressed file.
+//
+// In general, a gzip file can be a concatenation of gzip files,
+// each with its own header.  Reads from the Reader
+// return the concatenation of the uncompressed data of each.
+// Only the first header is recorded in the Reader fields.
+//
+// Gzip files store a length and checksum of the uncompressed data.
+// The Reader will return a ErrChecksum when Read
+// reaches the end of the uncompressed data if it does not
+// have the expected length or checksum.  Clients should treat data
+// returned by Read as tentative until they receive the io.EOF
+// marking the end of the data.
+type Reader struct {
+	Header
+	r            flate.Reader
+	decompressor io.ReadCloser
+	digest       hash.Hash32
+	size         uint32
+	flg          byte
+	buf          [512]byte
+	err          error
+	multistream  bool
+}
+
+// NewReader creates a new Reader reading the given reader.
+// If r does not also implement io.ByteReader,
+// the decompressor may read more data than necessary from r.
+// It is the caller's responsibility to call Close on the Reader when done.
+func NewReader(r io.Reader) (*Reader, error) {
+	z := new(Reader)
+	z.r = makeReader(r)
+	z.multistream = true
+	z.digest = crc32.NewIEEE()
+	if err := z.readHeader(true); err != nil {
+		return nil, err
+	}
+	return z, nil
+}
+
+// Reset discards the Reader z's state and makes it equivalent to the
+// result of its original state from NewReader, but reading from r instead.
+// This permits reusing a Reader rather than allocating a new one.
+func (z *Reader) Reset(r io.Reader) error {
+	z.r = makeReader(r)
+	if z.digest == nil {
+		z.digest = crc32.NewIEEE()
+	} else {
+		z.digest.Reset()
+	}
+	z.size = 0
+	z.err = nil
+	z.multistream = true
+	return z.readHeader(true)
+}
+
+// Multistream controls whether the reader supports multistream files.
+//
+// If enabled (the default), the Reader expects the input to be a sequence
+// of individually gzipped data streams, each with its own header and
+// trailer, ending at EOF. The effect is that the concatenation of a sequence
+// of gzipped files is treated as equivalent to the gzip of the concatenation
+// of the sequence. This is standard behavior for gzip readers.
+//
+// Calling Multistream(false) disables this behavior; disabling the behavior
+// can be useful when reading file formats that distinguish individual gzip
+// data streams or mix gzip data streams with other data streams.
+// In this mode, when the Reader reaches the end of the data stream,
+// Read returns io.EOF. If the underlying reader implements io.ByteReader,
+// it will be left positioned just after the gzip stream.
+// To start the next stream, call z.Reset(r) followed by z.Multistream(false).
+// If there is no next stream, z.Reset(r) will return io.EOF.
+func (z *Reader) Multistream(ok bool) {
+	z.multistream = ok
+}
+
+// GZIP (RFC 1952) is little-endian, unlike ZLIB (RFC 1950).
+func get4(p []byte) uint32 {
+	return uint32(p[0]) | uint32(p[1])<<8 | uint32(p[2])<<16 | uint32(p[3])<<24
+}
+
+func (z *Reader) readString() (string, error) {
+	var err error
+	needconv := false
+	for i := 0; ; i++ {
+		if i >= len(z.buf) {
+			return "", ErrHeader
+		}
+		z.buf[i], err = z.r.ReadByte()
+		if err != nil {
+			return "", err
+		}
+		if z.buf[i] > 0x7f {
+			needconv = true
+		}
+		if z.buf[i] == 0 {
+			// GZIP (RFC 1952) specifies that strings are NUL-terminated ISO 8859-1 (Latin-1).
+			if needconv {
+				s := make([]rune, 0, i)
+				for _, v := range z.buf[0:i] {
+					s = append(s, rune(v))
+				}
+				return string(s), nil
+			}
+			return string(z.buf[0:i]), nil
+		}
+	}
+}
+
+func (z *Reader) read2() (uint32, error) {
+	_, err := io.ReadFull(z.r, z.buf[0:2])
+	if err != nil {
+		return 0, err
+	}
+	return uint32(z.buf[0]) | uint32(z.buf[1])<<8, nil
+}
+
+func (z *Reader) readHeader(save bool) error {
+	_, err := io.ReadFull(z.r, z.buf[0:10])
+	if err != nil {
+		return err
+	}
+	if z.buf[0] != gzipID1 || z.buf[1] != gzipID2 || z.buf[2] != gzipDeflate {
+		return ErrHeader
+	}
+	z.flg = z.buf[3]
+	if save {
+		z.ModTime = time.Unix(int64(get4(z.buf[4:8])), 0)
+		// z.buf[8] is xfl, ignored
+		z.OS = z.buf[9]
+	}
+	z.digest.Reset()
+	z.digest.Write(z.buf[0:10])
+
+	if z.flg&flagExtra != 0 {
+		n, err := z.read2()
+		if err != nil {
+			return err
+		}
+		data := make([]byte, n)
+		if _, err = io.ReadFull(z.r, data); err != nil {
+			return err
+		}
+		if save {
+			z.Extra = data
+		}
+	}
+
+	var s string
+	if z.flg&flagName != 0 {
+		if s, err = z.readString(); err != nil {
+			return err
+		}
+		if save {
+			z.Name = s
+		}
+	}
+
+	if z.flg&flagComment != 0 {
+		if s, err = z.readString(); err != nil {
+			return err
+		}
+		if save {
+			z.Comment = s
+		}
+	}
+
+	if z.flg&flagHdrCrc != 0 {
+		n, err := z.read2()
+		if err != nil {
+			return err
+		}
+		sum := z.digest.Sum32() & 0xFFFF
+		if n != sum {
+			return ErrHeader
+		}
+	}
+
+	z.digest.Reset()
+	if z.decompressor == nil {
+		z.decompressor = flate.NewReader(z.r)
+	} else {
+		z.decompressor.(flate.Resetter).Reset(z.r, nil)
+	}
+	return nil
+}
+
+func (z *Reader) Read(p []byte) (n int, err error) {
+	if z.err != nil {
+		return 0, z.err
+	}
+	if len(p) == 0 {
+		return 0, nil
+	}
+
+	n, err = z.decompressor.Read(p)
+	z.digest.Write(p[0:n])
+	z.size += uint32(n)
+	if n != 0 || err != io.EOF {
+		z.err = err
+		return
+	}
+
+	// Finished file; check checksum + size.
+	if _, err := io.ReadFull(z.r, z.buf[0:8]); err != nil {
+		z.err = err
+		return 0, err
+	}
+	crc32, isize := get4(z.buf[0:4]), get4(z.buf[4:8])
+	sum := z.digest.Sum32()
+	if sum != crc32 || isize != z.size {
+		z.err = ErrChecksum
+		return 0, z.err
+	}
+
+	// File is ok; is there another?
+	if !z.multistream {
+		return 0, io.EOF
+	}
+
+	if err = z.readHeader(false); err != nil {
+		z.err = err
+		return
+	}
+
+	// Yes.  Reset and read from it.
+	z.digest.Reset()
+	z.size = 0
+	return z.Read(p)
+}
+
+// Close closes the Reader. It does not close the underlying io.Reader.
+func (z *Reader) Close() error { return z.decompressor.Close() }
diff --git a/src/compress/gzip/gunzip_test.go b/src/compress/gzip/gunzip_test.go
new file mode 100644
index 0000000..0636dec
--- /dev/null
+++ b/src/compress/gzip/gunzip_test.go
@@ -0,0 +1,410 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package gzip
+
+import (
+	"bytes"
+	"io"
+	"io/ioutil"
+	"os"
+	"strings"
+	"testing"
+	"time"
+)
+
+type gunzipTest struct {
+	name string
+	desc string
+	raw  string
+	gzip []byte
+	err  error
+}
+
+var gunzipTests = []gunzipTest{
+	{ // has 1 empty fixed-huffman block
+		"empty.txt",
+		"empty.txt",
+		"",
+		[]byte{
+			0x1f, 0x8b, 0x08, 0x08, 0xf7, 0x5e, 0x14, 0x4a,
+			0x00, 0x03, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e,
+			0x74, 0x78, 0x74, 0x00, 0x03, 0x00, 0x00, 0x00,
+			0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		},
+		nil,
+	},
+	{ // has 1 non-empty fixed huffman block
+		"hello.txt",
+		"hello.txt",
+		"hello world\n",
+		[]byte{
+			0x1f, 0x8b, 0x08, 0x08, 0xc8, 0x58, 0x13, 0x4a,
+			0x00, 0x03, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x2e,
+			0x74, 0x78, 0x74, 0x00, 0xcb, 0x48, 0xcd, 0xc9,
+			0xc9, 0x57, 0x28, 0xcf, 0x2f, 0xca, 0x49, 0xe1,
+			0x02, 0x00, 0x2d, 0x3b, 0x08, 0xaf, 0x0c, 0x00,
+			0x00, 0x00,
+		},
+		nil,
+	},
+	{ // concatenation
+		"hello.txt",
+		"hello.txt x2",
+		"hello world\n" +
+			"hello world\n",
+		[]byte{
+			0x1f, 0x8b, 0x08, 0x08, 0xc8, 0x58, 0x13, 0x4a,
+			0x00, 0x03, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x2e,
+			0x74, 0x78, 0x74, 0x00, 0xcb, 0x48, 0xcd, 0xc9,
+			0xc9, 0x57, 0x28, 0xcf, 0x2f, 0xca, 0x49, 0xe1,
+			0x02, 0x00, 0x2d, 0x3b, 0x08, 0xaf, 0x0c, 0x00,
+			0x00, 0x00,
+			0x1f, 0x8b, 0x08, 0x08, 0xc8, 0x58, 0x13, 0x4a,
+			0x00, 0x03, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x2e,
+			0x74, 0x78, 0x74, 0x00, 0xcb, 0x48, 0xcd, 0xc9,
+			0xc9, 0x57, 0x28, 0xcf, 0x2f, 0xca, 0x49, 0xe1,
+			0x02, 0x00, 0x2d, 0x3b, 0x08, 0xaf, 0x0c, 0x00,
+			0x00, 0x00,
+		},
+		nil,
+	},
+	{ // has a fixed huffman block with some length-distance pairs
+		"shesells.txt",
+		"shesells.txt",
+		"she sells seashells by the seashore\n",
+		[]byte{
+			0x1f, 0x8b, 0x08, 0x08, 0x72, 0x66, 0x8b, 0x4a,
+			0x00, 0x03, 0x73, 0x68, 0x65, 0x73, 0x65, 0x6c,
+			0x6c, 0x73, 0x2e, 0x74, 0x78, 0x74, 0x00, 0x2b,
+			0xce, 0x48, 0x55, 0x28, 0x4e, 0xcd, 0xc9, 0x29,
+			0x06, 0x92, 0x89, 0xc5, 0x19, 0x60, 0x56, 0x52,
+			0xa5, 0x42, 0x09, 0x58, 0x18, 0x28, 0x90, 0x5f,
+			0x94, 0xca, 0x05, 0x00, 0x76, 0xb0, 0x3b, 0xeb,
+			0x24, 0x00, 0x00, 0x00,
+		},
+		nil,
+	},
+	{ // has dynamic huffman blocks
+		"gettysburg",
+		"gettysburg",
+		"  Four score and seven years ago our fathers brought forth on\n" +
+			"this continent, a new nation, conceived in Liberty, and dedicated\n" +
+			"to the proposition that all men are created equal.\n" +
+			"  Now we are engaged in a great Civil War, testing whether that\n" +
+			"nation, or any nation so conceived and so dedicated, can long\n" +
+			"endure.\n" +
+			"  We are met on a great battle-field of that war.\n" +
+			"  We have come to dedicate a portion of that field, as a final\n" +
+			"resting place for those who here gave their lives that that\n" +
+			"nation might live.  It is altogether fitting and proper that\n" +
+			"we should do this.\n" +
+			"  But, in a larger sense, we can not dedicate — we can not\n" +
+			"consecrate — we can not hallow — this ground.\n" +
+			"  The brave men, living and dead, who struggled here, have\n" +
+			"consecrated it, far above our poor power to add or detract.\n" +
+			"The world will little note, nor long remember what we say here,\n" +
+			"but it can never forget what they did here.\n" +
+			"  It is for us the living, rather, to be dedicated here to the\n" +
+			"unfinished work which they who fought here have thus far so\n" +
+			"nobly advanced.  It is rather for us to be here dedicated to\n" +
+			"the great task remaining before us — that from these honored\n" +
+			"dead we take increased devotion to that cause for which they\n" +
+			"gave the last full measure of devotion —\n" +
+			"  that we here highly resolve that these dead shall not have\n" +
+			"died in vain — that this nation, under God, shall have a new\n" +
+			"birth of freedom — and that government of the people, by the\n" +
+			"people, for the people, shall not perish from this earth.\n" +
+			"\n" +
+			"Abraham Lincoln, November 19, 1863, Gettysburg, Pennsylvania\n",
+		[]byte{
+			0x1f, 0x8b, 0x08, 0x08, 0xd1, 0x12, 0x2b, 0x4a,
+			0x00, 0x03, 0x67, 0x65, 0x74, 0x74, 0x79, 0x73,
+			0x62, 0x75, 0x72, 0x67, 0x00, 0x65, 0x54, 0xcd,
+			0x6e, 0xd4, 0x30, 0x10, 0xbe, 0xfb, 0x29, 0xe6,
+			0x01, 0x42, 0xa5, 0x0a, 0x09, 0xc1, 0x11, 0x90,
+			0x40, 0x48, 0xa8, 0xe2, 0x80, 0xd4, 0xf3, 0x24,
+			0x9e, 0x24, 0x56, 0xbd, 0x9e, 0xc5, 0x76, 0x76,
+			0x95, 0x1b, 0x0f, 0xc1, 0x13, 0xf2, 0x24, 0x7c,
+			0x63, 0x77, 0x9b, 0x4a, 0x5c, 0xaa, 0x6e, 0x6c,
+			0xcf, 0x7c, 0x7f, 0x33, 0x44, 0x5f, 0x74, 0xcb,
+			0x54, 0x26, 0xcd, 0x42, 0x9c, 0x3c, 0x15, 0xb9,
+			0x48, 0xa2, 0x5d, 0x38, 0x17, 0xe2, 0x45, 0xc9,
+			0x4e, 0x67, 0xae, 0xab, 0xe0, 0xf7, 0x98, 0x75,
+			0x5b, 0xd6, 0x4a, 0xb3, 0xe6, 0xba, 0x92, 0x26,
+			0x57, 0xd7, 0x50, 0x68, 0xd2, 0x54, 0x43, 0x92,
+			0x54, 0x07, 0x62, 0x4a, 0x72, 0xa5, 0xc4, 0x35,
+			0x68, 0x1a, 0xec, 0x60, 0x92, 0x70, 0x11, 0x4f,
+			0x21, 0xd1, 0xf7, 0x30, 0x4a, 0xae, 0xfb, 0xd0,
+			0x9a, 0x78, 0xf1, 0x61, 0xe2, 0x2a, 0xde, 0x55,
+			0x25, 0xd4, 0xa6, 0x73, 0xd6, 0xb3, 0x96, 0x60,
+			0xef, 0xf0, 0x9b, 0x2b, 0x71, 0x8c, 0x74, 0x02,
+			0x10, 0x06, 0xac, 0x29, 0x8b, 0xdd, 0x25, 0xf9,
+			0xb5, 0x71, 0xbc, 0x73, 0x44, 0x0f, 0x7a, 0xa5,
+			0xab, 0xb4, 0x33, 0x49, 0x0b, 0x2f, 0xbd, 0x03,
+			0xd3, 0x62, 0x17, 0xe9, 0x73, 0xb8, 0x84, 0x48,
+			0x8f, 0x9c, 0x07, 0xaa, 0x52, 0x00, 0x6d, 0xa1,
+			0xeb, 0x2a, 0xc6, 0xa0, 0x95, 0x76, 0x37, 0x78,
+			0x9a, 0x81, 0x65, 0x7f, 0x46, 0x4b, 0x45, 0x5f,
+			0xe1, 0x6d, 0x42, 0xe8, 0x01, 0x13, 0x5c, 0x38,
+			0x51, 0xd4, 0xb4, 0x38, 0x49, 0x7e, 0xcb, 0x62,
+			0x28, 0x1e, 0x3b, 0x82, 0x93, 0x54, 0x48, 0xf1,
+			0xd2, 0x7d, 0xe4, 0x5a, 0xa3, 0xbc, 0x99, 0x83,
+			0x44, 0x4f, 0x3a, 0x77, 0x36, 0x57, 0xce, 0xcf,
+			0x2f, 0x56, 0xbe, 0x80, 0x90, 0x9e, 0x84, 0xea,
+			0x51, 0x1f, 0x8f, 0xcf, 0x90, 0xd4, 0x60, 0xdc,
+			0x5e, 0xb4, 0xf7, 0x10, 0x0b, 0x26, 0xe0, 0xff,
+			0xc4, 0xd1, 0xe5, 0x67, 0x2e, 0xe7, 0xc8, 0x93,
+			0x98, 0x05, 0xb8, 0xa8, 0x45, 0xc0, 0x4d, 0x09,
+			0xdc, 0x84, 0x16, 0x2b, 0x0d, 0x9a, 0x21, 0x53,
+			0x04, 0x8b, 0xd2, 0x0b, 0xbd, 0xa2, 0x4c, 0xa7,
+			0x60, 0xee, 0xd9, 0xe1, 0x1d, 0xd1, 0xb7, 0x4a,
+			0x30, 0x8f, 0x63, 0xd5, 0xa5, 0x8b, 0x33, 0x87,
+			0xda, 0x1a, 0x18, 0x79, 0xf3, 0xe3, 0xa6, 0x17,
+			0x94, 0x2e, 0xab, 0x6e, 0xa0, 0xe3, 0xcd, 0xac,
+			0x50, 0x8c, 0xca, 0xa7, 0x0d, 0x76, 0x37, 0xd1,
+			0x23, 0xe7, 0x05, 0x57, 0x8b, 0xa4, 0x22, 0x83,
+			0xd9, 0x62, 0x52, 0x25, 0xad, 0x07, 0xbb, 0xbf,
+			0xbf, 0xff, 0xbc, 0xfa, 0xee, 0x20, 0x73, 0x91,
+			0x29, 0xff, 0x7f, 0x02, 0x71, 0x62, 0x84, 0xb5,
+			0xf6, 0xb5, 0x25, 0x6b, 0x41, 0xde, 0x92, 0xb7,
+			0x76, 0x3f, 0x91, 0x91, 0x31, 0x1b, 0x41, 0x84,
+			0x62, 0x30, 0x0a, 0x37, 0xa4, 0x5e, 0x18, 0x3a,
+			0x99, 0x08, 0xa5, 0xe6, 0x6d, 0x59, 0x22, 0xec,
+			0x33, 0x39, 0x86, 0x26, 0xf5, 0xab, 0x66, 0xc8,
+			0x08, 0x20, 0xcf, 0x0c, 0xd7, 0x47, 0x45, 0x21,
+			0x0b, 0xf6, 0x59, 0xd5, 0xfe, 0x5c, 0x8d, 0xaa,
+			0x12, 0x7b, 0x6f, 0xa1, 0xf0, 0x52, 0x33, 0x4f,
+			0xf5, 0xce, 0x59, 0xd3, 0xab, 0x66, 0x10, 0xbf,
+			0x06, 0xc4, 0x31, 0x06, 0x73, 0xd6, 0x80, 0xa2,
+			0x78, 0xc2, 0x45, 0xcb, 0x03, 0x65, 0x39, 0xc9,
+			0x09, 0xd1, 0x06, 0x04, 0x33, 0x1a, 0x5a, 0xf1,
+			0xde, 0x01, 0xb8, 0x71, 0x83, 0xc4, 0xb5, 0xb3,
+			0xc3, 0x54, 0x65, 0x33, 0x0d, 0x5a, 0xf7, 0x9b,
+			0x90, 0x7c, 0x27, 0x1f, 0x3a, 0x58, 0xa3, 0xd8,
+			0xfd, 0x30, 0x5f, 0xb7, 0xd2, 0x66, 0xa2, 0x93,
+			0x1c, 0x28, 0xb7, 0xe9, 0x1b, 0x0c, 0xe1, 0x28,
+			0x47, 0x26, 0xbb, 0xe9, 0x7d, 0x7e, 0xdc, 0x96,
+			0x10, 0x92, 0x50, 0x56, 0x7c, 0x06, 0xe2, 0x27,
+			0xb4, 0x08, 0xd3, 0xda, 0x7b, 0x98, 0x34, 0x73,
+			0x9f, 0xdb, 0xf6, 0x62, 0xed, 0x31, 0x41, 0x13,
+			0xd3, 0xa2, 0xa8, 0x4b, 0x3a, 0xc6, 0x1d, 0xe4,
+			0x2f, 0x8c, 0xf8, 0xfb, 0x97, 0x64, 0xf4, 0xb6,
+			0x2f, 0x80, 0x5a, 0xf3, 0x56, 0xe0, 0x40, 0x50,
+			0xd5, 0x19, 0xd0, 0x1e, 0xfc, 0xca, 0xe5, 0xc9,
+			0xd4, 0x60, 0x00, 0x81, 0x2e, 0xa3, 0xcc, 0xb6,
+			0x52, 0xf0, 0xb4, 0xdb, 0x69, 0x99, 0xce, 0x7a,
+			0x32, 0x4c, 0x08, 0xed, 0xaa, 0x10, 0x10, 0xe3,
+			0x6f, 0xee, 0x99, 0x68, 0x95, 0x9f, 0x04, 0x71,
+			0xb2, 0x49, 0x2f, 0x62, 0xa6, 0x5e, 0xb4, 0xef,
+			0x02, 0xed, 0x4f, 0x27, 0xde, 0x4a, 0x0f, 0xfd,
+			0xc1, 0xcc, 0xdd, 0x02, 0x8f, 0x08, 0x16, 0x54,
+			0xdf, 0xda, 0xca, 0xe0, 0x82, 0xf1, 0xb4, 0x31,
+			0x7a, 0xa9, 0x81, 0xfe, 0x90, 0xb7, 0x3e, 0xdb,
+			0xd3, 0x35, 0xc0, 0x20, 0x80, 0x33, 0x46, 0x4a,
+			0x63, 0xab, 0xd1, 0x0d, 0x29, 0xd2, 0xe2, 0x84,
+			0xb8, 0xdb, 0xfa, 0xe9, 0x89, 0x44, 0x86, 0x7c,
+			0xe8, 0x0b, 0xe6, 0x02, 0x6a, 0x07, 0x9b, 0x96,
+			0xd0, 0xdb, 0x2e, 0x41, 0x4c, 0xa1, 0xd5, 0x57,
+			0x45, 0x14, 0xfb, 0xe3, 0xa6, 0x72, 0x5b, 0x87,
+			0x6e, 0x0c, 0x6d, 0x5b, 0xce, 0xe0, 0x2f, 0xe2,
+			0x21, 0x81, 0x95, 0xb0, 0xe8, 0xb6, 0x32, 0x0b,
+			0xb2, 0x98, 0x13, 0x52, 0x5d, 0xfb, 0xec, 0x63,
+			0x17, 0x8a, 0x9e, 0x23, 0x22, 0x36, 0xee, 0xcd,
+			0xda, 0xdb, 0xcf, 0x3e, 0xf1, 0xc7, 0xf1, 0x01,
+			0x12, 0x93, 0x0a, 0xeb, 0x6f, 0xf2, 0x02, 0x15,
+			0x96, 0x77, 0x5d, 0xef, 0x9c, 0xfb, 0x88, 0x91,
+			0x59, 0xf9, 0x84, 0xdd, 0x9b, 0x26, 0x8d, 0x80,
+			0xf9, 0x80, 0x66, 0x2d, 0xac, 0xf7, 0x1f, 0x06,
+			0xba, 0x7f, 0xff, 0xee, 0xed, 0x40, 0x5f, 0xa5,
+			0xd6, 0xbd, 0x8c, 0x5b, 0x46, 0xd2, 0x7e, 0x48,
+			0x4a, 0x65, 0x8f, 0x08, 0x42, 0x60, 0xf7, 0x0f,
+			0xb9, 0x16, 0x0b, 0x0c, 0x1a, 0x06, 0x00, 0x00,
+		},
+		nil,
+	},
+	{ // has 1 non-empty fixed huffman block then garbage
+		"hello.txt",
+		"hello.txt + garbage",
+		"hello world\n",
+		[]byte{
+			0x1f, 0x8b, 0x08, 0x08, 0xc8, 0x58, 0x13, 0x4a,
+			0x00, 0x03, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x2e,
+			0x74, 0x78, 0x74, 0x00, 0xcb, 0x48, 0xcd, 0xc9,
+			0xc9, 0x57, 0x28, 0xcf, 0x2f, 0xca, 0x49, 0xe1,
+			0x02, 0x00, 0x2d, 0x3b, 0x08, 0xaf, 0x0c, 0x00,
+			0x00, 0x00, 'g', 'a', 'r', 'b', 'a', 'g', 'e', '!', '!', '!',
+		},
+		ErrHeader,
+	},
+	{ // has 1 non-empty fixed huffman block not enough header
+		"hello.txt",
+		"hello.txt + garbage",
+		"hello world\n",
+		[]byte{
+			0x1f, 0x8b, 0x08, 0x08, 0xc8, 0x58, 0x13, 0x4a,
+			0x00, 0x03, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x2e,
+			0x74, 0x78, 0x74, 0x00, 0xcb, 0x48, 0xcd, 0xc9,
+			0xc9, 0x57, 0x28, 0xcf, 0x2f, 0xca, 0x49, 0xe1,
+			0x02, 0x00, 0x2d, 0x3b, 0x08, 0xaf, 0x0c, 0x00,
+			0x00, 0x00, gzipID1,
+		},
+		io.ErrUnexpectedEOF,
+	},
+	{ // has 1 non-empty fixed huffman block but corrupt checksum
+		"hello.txt",
+		"hello.txt + corrupt checksum",
+		"hello world\n",
+		[]byte{
+			0x1f, 0x8b, 0x08, 0x08, 0xc8, 0x58, 0x13, 0x4a,
+			0x00, 0x03, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x2e,
+			0x74, 0x78, 0x74, 0x00, 0xcb, 0x48, 0xcd, 0xc9,
+			0xc9, 0x57, 0x28, 0xcf, 0x2f, 0xca, 0x49, 0xe1,
+			0x02, 0x00, 0xff, 0xff, 0xff, 0xff, 0x0c, 0x00,
+			0x00, 0x00,
+		},
+		ErrChecksum,
+	},
+	{ // has 1 non-empty fixed huffman block but corrupt size
+		"hello.txt",
+		"hello.txt + corrupt size",
+		"hello world\n",
+		[]byte{
+			0x1f, 0x8b, 0x08, 0x08, 0xc8, 0x58, 0x13, 0x4a,
+			0x00, 0x03, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x2e,
+			0x74, 0x78, 0x74, 0x00, 0xcb, 0x48, 0xcd, 0xc9,
+			0xc9, 0x57, 0x28, 0xcf, 0x2f, 0xca, 0x49, 0xe1,
+			0x02, 0x00, 0x2d, 0x3b, 0x08, 0xaf, 0xff, 0x00,
+			0x00, 0x00,
+		},
+		ErrChecksum,
+	},
+}
+
+func TestDecompressor(t *testing.T) {
+	b := new(bytes.Buffer)
+	for _, tt := range gunzipTests {
+		in := bytes.NewReader(tt.gzip)
+		gzip, err := NewReader(in)
+		if err != nil {
+			t.Errorf("%s: NewReader: %s", tt.name, err)
+			continue
+		}
+		defer gzip.Close()
+		if tt.name != gzip.Name {
+			t.Errorf("%s: got name %s", tt.name, gzip.Name)
+		}
+		b.Reset()
+		n, err := io.Copy(b, gzip)
+		if err != tt.err {
+			t.Errorf("%s: io.Copy: %v want %v", tt.name, err, tt.err)
+		}
+		s := b.String()
+		if s != tt.raw {
+			t.Errorf("%s: got %d-byte %q want %d-byte %q", tt.name, n, s, len(tt.raw), tt.raw)
+		}
+
+		// Test Reader Reset.
+		in = bytes.NewReader(tt.gzip)
+		err = gzip.Reset(in)
+		if err != nil {
+			t.Errorf("%s: Reset: %s", tt.name, err)
+			continue
+		}
+		if tt.name != gzip.Name {
+			t.Errorf("%s: got name %s", tt.name, gzip.Name)
+		}
+		b.Reset()
+		n, err = io.Copy(b, gzip)
+		if err != tt.err {
+			t.Errorf("%s: io.Copy: %v want %v", tt.name, err, tt.err)
+		}
+		s = b.String()
+		if s != tt.raw {
+			t.Errorf("%s: got %d-byte %q want %d-byte %q", tt.name, n, s, len(tt.raw), tt.raw)
+		}
+	}
+}
+
+func TestIssue6550(t *testing.T) {
+	f, err := os.Open("testdata/issue6550.gz")
+	if err != nil {
+		t.Fatal(err)
+	}
+	gzip, err := NewReader(f)
+	if err != nil {
+		t.Fatalf("NewReader(testdata/issue6550.gz): %v", err)
+	}
+	defer gzip.Close()
+	done := make(chan bool, 1)
+	go func() {
+		_, err := io.Copy(ioutil.Discard, gzip)
+		if err == nil {
+			t.Errorf("Copy succeeded")
+		} else {
+			t.Logf("Copy failed (correctly): %v", err)
+		}
+		done <- true
+	}()
+	select {
+	case <-time.After(1 * time.Second):
+		t.Errorf("Copy hung")
+	case <-done:
+		// ok
+	}
+}
+
+func TestInitialReset(t *testing.T) {
+	var r Reader
+	if err := r.Reset(bytes.NewReader(gunzipTests[1].gzip)); err != nil {
+		t.Error(err)
+	}
+	var buf bytes.Buffer
+	if _, err := io.Copy(&buf, &r); err != nil {
+		t.Error(err)
+	}
+	if s := buf.String(); s != gunzipTests[1].raw {
+		t.Errorf("got %q want %q", s, gunzipTests[1].raw)
+	}
+}
+
+func TestMultistreamFalse(t *testing.T) {
+	// Find concatenation test.
+	var tt gunzipTest
+	for _, tt = range gunzipTests {
+		if strings.HasSuffix(tt.desc, " x2") {
+			goto Found
+		}
+	}
+	t.Fatal("cannot find hello.txt x2 in gunzip tests")
+
+Found:
+	br := bytes.NewReader(tt.gzip)
+	var r Reader
+	if err := r.Reset(br); err != nil {
+		t.Fatalf("first reset: %v", err)
+	}
+
+	// Expect two streams with "hello world\n", then real EOF.
+	const hello = "hello world\n"
+
+	r.Multistream(false)
+	data, err := ioutil.ReadAll(&r)
+	if string(data) != hello || err != nil {
+		t.Fatalf("first stream = %q, %v, want %q, %v", string(data), err, hello, nil)
+	}
+
+	if err := r.Reset(br); err != nil {
+		t.Fatalf("second reset: %v", err)
+	}
+	r.Multistream(false)
+	data, err = ioutil.ReadAll(&r)
+	if string(data) != hello || err != nil {
+		t.Fatalf("second stream = %q, %v, want %q, %v", string(data), err, hello, nil)
+	}
+
+	if err := r.Reset(br); err != io.EOF {
+		t.Fatalf("third reset: err=%v, want io.EOF", err)
+	}
+}
diff --git a/src/pkg/compress/gzip/gzip.go b/src/compress/gzip/gzip.go
similarity index 100%
rename from src/pkg/compress/gzip/gzip.go
rename to src/compress/gzip/gzip.go
diff --git a/src/pkg/compress/gzip/gzip_test.go b/src/compress/gzip/gzip_test.go
similarity index 100%
rename from src/pkg/compress/gzip/gzip_test.go
rename to src/compress/gzip/gzip_test.go
diff --git a/src/pkg/compress/gzip/testdata/issue6550.gz b/src/compress/gzip/testdata/issue6550.gz
similarity index 100%
rename from src/pkg/compress/gzip/testdata/issue6550.gz
rename to src/compress/gzip/testdata/issue6550.gz
diff --git a/src/compress/lzw/reader.go b/src/compress/lzw/reader.go
new file mode 100644
index 0000000..526620c
--- /dev/null
+++ b/src/compress/lzw/reader.go
@@ -0,0 +1,259 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package lzw implements the Lempel-Ziv-Welch compressed data format,
+// described in T. A. Welch, ``A Technique for High-Performance Data
+// Compression'', Computer, 17(6) (June 1984), pp 8-19.
+//
+// In particular, it implements LZW as used by the GIF and PDF file
+// formats, which means variable-width codes up to 12 bits and the first
+// two non-literal codes are a clear code and an EOF code.
+//
+// The TIFF file format uses a similar but incompatible version of the LZW
+// algorithm. See the golang.org/x/image/tiff/lzw package for an
+// implementation.
+package lzw
+
+// TODO(nigeltao): check that PDF uses LZW in the same way as GIF,
+// modulo LSB/MSB packing order.
+
+import (
+	"bufio"
+	"errors"
+	"fmt"
+	"io"
+)
+
+// Order specifies the bit ordering in an LZW data stream.
+type Order int
+
+const (
+	// LSB means Least Significant Bits first, as used in the GIF file format.
+	LSB Order = iota
+	// MSB means Most Significant Bits first, as used in the TIFF and PDF
+	// file formats.
+	MSB
+)
+
+const (
+	maxWidth           = 12
+	decoderInvalidCode = 0xffff
+	flushBuffer        = 1 << maxWidth
+)
+
+// decoder is the state from which the readXxx method converts a byte
+// stream into a code stream.
+type decoder struct {
+	r        io.ByteReader
+	bits     uint32
+	nBits    uint
+	width    uint
+	read     func(*decoder) (uint16, error) // readLSB or readMSB
+	litWidth int                            // width in bits of literal codes
+	err      error
+
+	// The first 1<<litWidth codes are literal codes.
+	// The next two codes mean clear and EOF.
+	// Other valid codes are in the range [lo, hi] where lo := clear + 2,
+	// with the upper bound incrementing on each code seen.
+	// overflow is the code at which hi overflows the code width.
+	// last is the most recently seen code, or decoderInvalidCode.
+	clear, eof, hi, overflow, last uint16
+
+	// Each code c in [lo, hi] expands to two or more bytes. For c != hi:
+	//   suffix[c] is the last of these bytes.
+	//   prefix[c] is the code for all but the last byte.
+	//   This code can either be a literal code or another code in [lo, c).
+	// The c == hi case is a special case.
+	suffix [1 << maxWidth]uint8
+	prefix [1 << maxWidth]uint16
+
+	// output is the temporary output buffer.
+	// Literal codes are accumulated from the start of the buffer.
+	// Non-literal codes decode to a sequence of suffixes that are first
+	// written right-to-left from the end of the buffer before being copied
+	// to the start of the buffer.
+	// It is flushed when it contains >= 1<<maxWidth bytes,
+	// so that there is always room to decode an entire code.
+	output [2 * 1 << maxWidth]byte
+	o      int    // write index into output
+	toRead []byte // bytes to return from Read
+}
+
+// readLSB returns the next code for "Least Significant Bits first" data.
+func (d *decoder) readLSB() (uint16, error) {
+	for d.nBits < d.width {
+		x, err := d.r.ReadByte()
+		if err != nil {
+			return 0, err
+		}
+		d.bits |= uint32(x) << d.nBits
+		d.nBits += 8
+	}
+	code := uint16(d.bits & (1<<d.width - 1))
+	d.bits >>= d.width
+	d.nBits -= d.width
+	return code, nil
+}
+
+// readMSB returns the next code for "Most Significant Bits first" data.
+func (d *decoder) readMSB() (uint16, error) {
+	for d.nBits < d.width {
+		x, err := d.r.ReadByte()
+		if err != nil {
+			return 0, err
+		}
+		d.bits |= uint32(x) << (24 - d.nBits)
+		d.nBits += 8
+	}
+	code := uint16(d.bits >> (32 - d.width))
+	d.bits <<= d.width
+	d.nBits -= d.width
+	return code, nil
+}
+
+func (d *decoder) Read(b []byte) (int, error) {
+	for {
+		if len(d.toRead) > 0 {
+			n := copy(b, d.toRead)
+			d.toRead = d.toRead[n:]
+			return n, nil
+		}
+		if d.err != nil {
+			return 0, d.err
+		}
+		d.decode()
+	}
+}
+
+// decode decompresses bytes from r and leaves them in d.toRead.
+// read specifies how to decode bytes into codes.
+// litWidth is the width in bits of literal codes.
+func (d *decoder) decode() {
+	// Loop over the code stream, converting codes into decompressed bytes.
+	for {
+		code, err := d.read(d)
+		if err != nil {
+			if err == io.EOF {
+				err = io.ErrUnexpectedEOF
+			}
+			d.err = err
+			return
+		}
+		switch {
+		case code < d.clear:
+			// We have a literal code.
+			d.output[d.o] = uint8(code)
+			d.o++
+			if d.last != decoderInvalidCode {
+				// Save what the hi code expands to.
+				d.suffix[d.hi] = uint8(code)
+				d.prefix[d.hi] = d.last
+			}
+		case code == d.clear:
+			d.width = 1 + uint(d.litWidth)
+			d.hi = d.eof
+			d.overflow = 1 << d.width
+			d.last = decoderInvalidCode
+			continue
+		case code == d.eof:
+			d.flush()
+			d.err = io.EOF
+			return
+		case code <= d.hi:
+			c, i := code, len(d.output)-1
+			if code == d.hi {
+				// code == hi is a special case which expands to the last expansion
+				// followed by the head of the last expansion. To find the head, we walk
+				// the prefix chain until we find a literal code.
+				c = d.last
+				for c >= d.clear {
+					c = d.prefix[c]
+				}
+				d.output[i] = uint8(c)
+				i--
+				c = d.last
+			}
+			// Copy the suffix chain into output and then write that to w.
+			for c >= d.clear {
+				d.output[i] = d.suffix[c]
+				i--
+				c = d.prefix[c]
+			}
+			d.output[i] = uint8(c)
+			d.o += copy(d.output[d.o:], d.output[i:])
+			if d.last != decoderInvalidCode {
+				// Save what the hi code expands to.
+				d.suffix[d.hi] = uint8(c)
+				d.prefix[d.hi] = d.last
+			}
+		default:
+			d.err = errors.New("lzw: invalid code")
+			return
+		}
+		d.last, d.hi = code, d.hi+1
+		if d.hi >= d.overflow {
+			if d.width == maxWidth {
+				d.last = decoderInvalidCode
+			} else {
+				d.width++
+				d.overflow <<= 1
+			}
+		}
+		if d.o >= flushBuffer {
+			d.flush()
+			return
+		}
+	}
+}
+
+func (d *decoder) flush() {
+	d.toRead = d.output[:d.o]
+	d.o = 0
+}
+
+var errClosed = errors.New("compress/lzw: reader/writer is closed")
+
+func (d *decoder) Close() error {
+	d.err = errClosed // in case any Reads come along
+	return nil
+}
+
+// NewReader creates a new io.ReadCloser.
+// Reads from the returned io.ReadCloser read and decompress data from r.
+// If r does not also implement io.ByteReader,
+// the decompressor may read more data than necessary from r.
+// It is the caller's responsibility to call Close on the ReadCloser when
+// finished reading.
+// The number of bits to use for literal codes, litWidth, must be in the
+// range [2,8] and is typically 8.
+func NewReader(r io.Reader, order Order, litWidth int) io.ReadCloser {
+	d := new(decoder)
+	switch order {
+	case LSB:
+		d.read = (*decoder).readLSB
+	case MSB:
+		d.read = (*decoder).readMSB
+	default:
+		d.err = errors.New("lzw: unknown order")
+		return d
+	}
+	if litWidth < 2 || 8 < litWidth {
+		d.err = fmt.Errorf("lzw: litWidth %d out of range", litWidth)
+		return d
+	}
+	if br, ok := r.(io.ByteReader); ok {
+		d.r = br
+	} else {
+		d.r = bufio.NewReader(r)
+	}
+	d.litWidth = litWidth
+	d.width = 1 + uint(litWidth)
+	d.clear = uint16(1) << uint(litWidth)
+	d.eof, d.hi = d.clear+1, d.clear+1
+	d.overflow = uint16(1) << d.width
+	d.last = decoderInvalidCode
+
+	return d
+}
diff --git a/src/pkg/compress/lzw/reader_test.go b/src/compress/lzw/reader_test.go
similarity index 100%
rename from src/pkg/compress/lzw/reader_test.go
rename to src/compress/lzw/reader_test.go
diff --git a/src/pkg/compress/lzw/writer.go b/src/compress/lzw/writer.go
similarity index 100%
rename from src/pkg/compress/lzw/writer.go
rename to src/compress/lzw/writer.go
diff --git a/src/pkg/compress/lzw/writer_test.go b/src/compress/lzw/writer_test.go
similarity index 100%
rename from src/pkg/compress/lzw/writer_test.go
rename to src/compress/lzw/writer_test.go
diff --git a/src/pkg/compress/testdata/Mark.Twain-Tom.Sawyer.txt b/src/compress/testdata/Mark.Twain-Tom.Sawyer.txt
similarity index 100%
rename from src/pkg/compress/testdata/Mark.Twain-Tom.Sawyer.txt
rename to src/compress/testdata/Mark.Twain-Tom.Sawyer.txt
diff --git a/src/pkg/compress/testdata/e.txt b/src/compress/testdata/e.txt
similarity index 100%
rename from src/pkg/compress/testdata/e.txt
rename to src/compress/testdata/e.txt
diff --git a/src/pkg/compress/testdata/pi.txt b/src/compress/testdata/pi.txt
similarity index 100%
rename from src/pkg/compress/testdata/pi.txt
rename to src/compress/testdata/pi.txt
diff --git a/src/pkg/compress/zlib/example_test.go b/src/compress/zlib/example_test.go
similarity index 100%
rename from src/pkg/compress/zlib/example_test.go
rename to src/compress/zlib/example_test.go
diff --git a/src/compress/zlib/reader.go b/src/compress/zlib/reader.go
new file mode 100644
index 0000000..816f1bf
--- /dev/null
+++ b/src/compress/zlib/reader.go
@@ -0,0 +1,161 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+/*
+Package zlib implements reading and writing of zlib format compressed data,
+as specified in RFC 1950.
+
+The implementation provides filters that uncompress during reading
+and compress during writing.  For example, to write compressed data
+to a buffer:
+
+	var b bytes.Buffer
+	w := zlib.NewWriter(&b)
+	w.Write([]byte("hello, world\n"))
+	w.Close()
+
+and to read that data back:
+
+	r, err := zlib.NewReader(&b)
+	io.Copy(os.Stdout, r)
+	r.Close()
+*/
+package zlib
+
+import (
+	"bufio"
+	"compress/flate"
+	"errors"
+	"hash"
+	"hash/adler32"
+	"io"
+)
+
+const zlibDeflate = 8
+
+var (
+	// ErrChecksum is returned when reading ZLIB data that has an invalid checksum.
+	ErrChecksum = errors.New("zlib: invalid checksum")
+	// ErrDictionary is returned when reading ZLIB data that has an invalid dictionary.
+	ErrDictionary = errors.New("zlib: invalid dictionary")
+	// ErrHeader is returned when reading ZLIB data that has an invalid header.
+	ErrHeader = errors.New("zlib: invalid header")
+)
+
+type reader struct {
+	r            flate.Reader
+	decompressor io.ReadCloser
+	digest       hash.Hash32
+	err          error
+	scratch      [4]byte
+}
+
+// Resetter resets a ReadCloser returned by NewReader or NewReaderDict to
+// to switch to a new underlying Reader. This permits reusing a ReadCloser
+// instead of allocating a new one.
+type Resetter interface {
+	// Reset discards any buffered data and resets the Resetter as if it was
+	// newly initialized with the given reader.
+	Reset(r io.Reader, dict []byte) error
+}
+
+// NewReader creates a new ReadCloser.
+// Reads from the returned ReadCloser read and decompress data from r.
+// The implementation buffers input and may read more data than necessary from r.
+// It is the caller's responsibility to call Close on the ReadCloser when done.
+//
+// The ReadCloser returned by NewReader also implements Resetter.
+func NewReader(r io.Reader) (io.ReadCloser, error) {
+	return NewReaderDict(r, nil)
+}
+
+// NewReaderDict is like NewReader but uses a preset dictionary.
+// NewReaderDict ignores the dictionary if the compressed data does not refer to it.
+// If the compressed data refers to a different dictionary, NewReaderDict returns ErrDictionary.
+//
+// The ReadCloser returned by NewReaderDict also implements Resetter.
+func NewReaderDict(r io.Reader, dict []byte) (io.ReadCloser, error) {
+	z := new(reader)
+	err := z.Reset(r, dict)
+	if err != nil {
+		return nil, err
+	}
+	return z, nil
+}
+
+func (z *reader) Read(p []byte) (n int, err error) {
+	if z.err != nil {
+		return 0, z.err
+	}
+	if len(p) == 0 {
+		return 0, nil
+	}
+
+	n, err = z.decompressor.Read(p)
+	z.digest.Write(p[0:n])
+	if n != 0 || err != io.EOF {
+		z.err = err
+		return
+	}
+
+	// Finished file; check checksum.
+	if _, err := io.ReadFull(z.r, z.scratch[0:4]); err != nil {
+		z.err = err
+		return 0, err
+	}
+	// ZLIB (RFC 1950) is big-endian, unlike GZIP (RFC 1952).
+	checksum := uint32(z.scratch[0])<<24 | uint32(z.scratch[1])<<16 | uint32(z.scratch[2])<<8 | uint32(z.scratch[3])
+	if checksum != z.digest.Sum32() {
+		z.err = ErrChecksum
+		return 0, z.err
+	}
+	return
+}
+
+// Calling Close does not close the wrapped io.Reader originally passed to NewReader.
+func (z *reader) Close() error {
+	if z.err != nil {
+		return z.err
+	}
+	z.err = z.decompressor.Close()
+	return z.err
+}
+
+func (z *reader) Reset(r io.Reader, dict []byte) error {
+	if fr, ok := r.(flate.Reader); ok {
+		z.r = fr
+	} else {
+		z.r = bufio.NewReader(r)
+	}
+	_, err := io.ReadFull(z.r, z.scratch[0:2])
+	if err != nil {
+		return err
+	}
+	h := uint(z.scratch[0])<<8 | uint(z.scratch[1])
+	if (z.scratch[0]&0x0f != zlibDeflate) || (h%31 != 0) {
+		return ErrHeader
+	}
+	haveDict := z.scratch[1]&0x20 != 0
+	if haveDict {
+		_, err = io.ReadFull(z.r, z.scratch[0:4])
+		if err != nil {
+			return err
+		}
+		checksum := uint32(z.scratch[0])<<24 | uint32(z.scratch[1])<<16 | uint32(z.scratch[2])<<8 | uint32(z.scratch[3])
+		if checksum != adler32.Checksum(dict) {
+			return ErrDictionary
+		}
+	}
+	if z.decompressor == nil {
+		if haveDict {
+			z.decompressor = flate.NewReaderDict(z.r, dict)
+		} else {
+			z.decompressor = flate.NewReader(z.r)
+		}
+	} else {
+		z.decompressor.(flate.Resetter).Reset(z.r, dict)
+	}
+	z.digest = adler32.New()
+	return nil
+}
diff --git a/src/pkg/compress/zlib/reader_test.go b/src/compress/zlib/reader_test.go
similarity index 100%
rename from src/pkg/compress/zlib/reader_test.go
rename to src/compress/zlib/reader_test.go
diff --git a/src/pkg/compress/zlib/writer.go b/src/compress/zlib/writer.go
similarity index 100%
rename from src/pkg/compress/zlib/writer.go
rename to src/compress/zlib/writer.go
diff --git a/src/pkg/compress/zlib/writer_test.go b/src/compress/zlib/writer_test.go
similarity index 100%
rename from src/pkg/compress/zlib/writer_test.go
rename to src/compress/zlib/writer_test.go
diff --git a/src/pkg/container/heap/example_intheap_test.go b/src/container/heap/example_intheap_test.go
similarity index 100%
rename from src/pkg/container/heap/example_intheap_test.go
rename to src/container/heap/example_intheap_test.go
diff --git a/src/pkg/container/heap/example_pq_test.go b/src/container/heap/example_pq_test.go
similarity index 100%
rename from src/pkg/container/heap/example_pq_test.go
rename to src/container/heap/example_pq_test.go
diff --git a/src/pkg/container/heap/heap.go b/src/container/heap/heap.go
similarity index 100%
rename from src/pkg/container/heap/heap.go
rename to src/container/heap/heap.go
diff --git a/src/pkg/container/heap/heap_test.go b/src/container/heap/heap_test.go
similarity index 100%
rename from src/pkg/container/heap/heap_test.go
rename to src/container/heap/heap_test.go
diff --git a/src/pkg/container/list/example_test.go b/src/container/list/example_test.go
similarity index 100%
rename from src/pkg/container/list/example_test.go
rename to src/container/list/example_test.go
diff --git a/src/pkg/container/list/list.go b/src/container/list/list.go
similarity index 100%
rename from src/pkg/container/list/list.go
rename to src/container/list/list.go
diff --git a/src/pkg/container/list/list_test.go b/src/container/list/list_test.go
similarity index 100%
rename from src/pkg/container/list/list_test.go
rename to src/container/list/list_test.go
diff --git a/src/pkg/container/ring/ring.go b/src/container/ring/ring.go
similarity index 100%
rename from src/pkg/container/ring/ring.go
rename to src/container/ring/ring.go
diff --git a/src/pkg/container/ring/ring_test.go b/src/container/ring/ring_test.go
similarity index 100%
rename from src/pkg/container/ring/ring_test.go
rename to src/container/ring/ring_test.go
diff --git a/src/pkg/crypto/aes/aes_test.go b/src/crypto/aes/aes_test.go
similarity index 100%
rename from src/pkg/crypto/aes/aes_test.go
rename to src/crypto/aes/aes_test.go
diff --git a/src/crypto/aes/asm_amd64.s b/src/crypto/aes/asm_amd64.s
new file mode 100644
index 0000000..6a6e6ac
--- /dev/null
+++ b/src/crypto/aes/asm_amd64.s
@@ -0,0 +1,289 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+// func hasAsm() bool
+// returns whether AES-NI is supported
+TEXT ·hasAsm(SB),NOSPLIT,$0
+	XORQ AX, AX
+	INCL AX
+	CPUID
+	SHRQ $25, CX
+	ANDQ $1, CX
+	MOVB CX, ret+0(FP)
+	RET
+
+// func encryptBlockAsm(nr int, xk *uint32, dst, src *byte)
+TEXT ·encryptBlockAsm(SB),NOSPLIT,$0
+	MOVQ nr+0(FP), CX
+	MOVQ xk+8(FP), AX
+	MOVQ dst+16(FP), DX
+	MOVQ src+24(FP), BX
+	MOVUPS 0(AX), X1
+	MOVUPS 0(BX), X0
+	ADDQ $16, AX
+	PXOR X1, X0
+	SUBQ $12, CX
+	JE Lenc196
+	JB Lenc128
+Lenc256:
+	MOVUPS 0(AX), X1
+	AESENC X1, X0
+	MOVUPS 16(AX), X1
+	AESENC X1, X0
+	ADDQ $32, AX
+Lenc196:
+	MOVUPS 0(AX), X1
+	AESENC X1, X0
+	MOVUPS 16(AX), X1
+	AESENC X1, X0
+	ADDQ $32, AX
+Lenc128:
+	MOVUPS 0(AX), X1
+	AESENC X1, X0
+	MOVUPS 16(AX), X1
+	AESENC X1, X0
+	MOVUPS 32(AX), X1
+	AESENC X1, X0
+	MOVUPS 48(AX), X1
+	AESENC X1, X0
+	MOVUPS 64(AX), X1
+	AESENC X1, X0
+	MOVUPS 80(AX), X1
+	AESENC X1, X0
+	MOVUPS 96(AX), X1
+	AESENC X1, X0
+	MOVUPS 112(AX), X1
+	AESENC X1, X0
+	MOVUPS 128(AX), X1
+	AESENC X1, X0
+	MOVUPS 144(AX), X1
+	AESENCLAST X1, X0
+	MOVUPS X0, 0(DX)
+	RET
+
+// func decryptBlockAsm(nr int, xk *uint32, dst, src *byte)
+TEXT ·decryptBlockAsm(SB),NOSPLIT,$0
+	MOVQ nr+0(FP), CX
+	MOVQ xk+8(FP), AX
+	MOVQ dst+16(FP), DX
+	MOVQ src+24(FP), BX
+	MOVUPS 0(AX), X1
+	MOVUPS 0(BX), X0
+	ADDQ $16, AX
+	PXOR X1, X0
+	SUBQ $12, CX
+	JE Ldec196
+	JB Ldec128
+Ldec256:
+	MOVUPS 0(AX), X1
+	AESDEC X1, X0
+	MOVUPS 16(AX), X1
+	AESDEC X1, X0
+	ADDQ $32, AX
+Ldec196:
+	MOVUPS 0(AX), X1
+	AESDEC X1, X0
+	MOVUPS 16(AX), X1
+	AESDEC X1, X0
+	ADDQ $32, AX
+Ldec128:
+	MOVUPS 0(AX), X1
+	AESDEC X1, X0
+	MOVUPS 16(AX), X1
+	AESDEC X1, X0
+	MOVUPS 32(AX), X1
+	AESDEC X1, X0
+	MOVUPS 48(AX), X1
+	AESDEC X1, X0
+	MOVUPS 64(AX), X1
+	AESDEC X1, X0
+	MOVUPS 80(AX), X1
+	AESDEC X1, X0
+	MOVUPS 96(AX), X1
+	AESDEC X1, X0
+	MOVUPS 112(AX), X1
+	AESDEC X1, X0
+	MOVUPS 128(AX), X1
+	AESDEC X1, X0
+	MOVUPS 144(AX), X1
+	AESDECLAST X1, X0
+	MOVUPS X0, 0(DX)
+	RET
+
+// func expandKeyAsm(nr int, key *byte, enc, dec *uint32) {
+// Note that round keys are stored in uint128 format, not uint32
+TEXT ·expandKeyAsm(SB),NOSPLIT,$0
+	MOVQ nr+0(FP), CX
+	MOVQ key+8(FP), AX
+	MOVQ enc+16(FP), BX
+	MOVQ dec+24(FP), DX
+	MOVUPS (AX), X0
+	// enc
+	MOVUPS X0, (BX)
+	ADDQ $16, BX
+	PXOR X4, X4 // _expand_key_* expect X4 to be zero
+	CMPL CX, $12
+	JE Lexp_enc196
+	JB Lexp_enc128
+Lexp_enc256:
+	MOVUPS 16(AX), X2
+	MOVUPS X2, (BX)
+	ADDQ $16, BX
+	AESKEYGENASSIST $0x01, X2, X1
+	CALL _expand_key_256a<>(SB)
+	AESKEYGENASSIST $0x01, X0, X1
+	CALL _expand_key_256b<>(SB)
+	AESKEYGENASSIST $0x02, X2, X1
+	CALL _expand_key_256a<>(SB)
+	AESKEYGENASSIST $0x02, X0, X1
+	CALL _expand_key_256b<>(SB)
+	AESKEYGENASSIST $0x04, X2, X1
+	CALL _expand_key_256a<>(SB)
+	AESKEYGENASSIST $0x04, X0, X1
+	CALL _expand_key_256b<>(SB)
+	AESKEYGENASSIST $0x08, X2, X1
+	CALL _expand_key_256a<>(SB)
+	AESKEYGENASSIST $0x08, X0, X1
+	CALL _expand_key_256b<>(SB)
+	AESKEYGENASSIST $0x10, X2, X1
+	CALL _expand_key_256a<>(SB)
+	AESKEYGENASSIST $0x10, X0, X1
+	CALL _expand_key_256b<>(SB)
+	AESKEYGENASSIST $0x20, X2, X1
+	CALL _expand_key_256a<>(SB)
+	AESKEYGENASSIST $0x20, X0, X1
+	CALL _expand_key_256b<>(SB)
+	AESKEYGENASSIST $0x40, X2, X1
+	CALL _expand_key_256a<>(SB)
+	JMP Lexp_dec
+Lexp_enc196:
+	MOVQ 16(AX), X2
+	AESKEYGENASSIST $0x01, X2, X1
+	CALL _expand_key_192a<>(SB)
+	AESKEYGENASSIST $0x02, X2, X1
+	CALL _expand_key_192b<>(SB)
+	AESKEYGENASSIST $0x04, X2, X1
+	CALL _expand_key_192a<>(SB)
+	AESKEYGENASSIST $0x08, X2, X1
+	CALL _expand_key_192b<>(SB)
+	AESKEYGENASSIST $0x10, X2, X1
+	CALL _expand_key_192a<>(SB)
+	AESKEYGENASSIST $0x20, X2, X1
+	CALL _expand_key_192b<>(SB)
+	AESKEYGENASSIST $0x40, X2, X1
+	CALL _expand_key_192a<>(SB)
+	AESKEYGENASSIST $0x80, X2, X1
+	CALL _expand_key_192b<>(SB)
+	JMP Lexp_dec
+Lexp_enc128:
+	AESKEYGENASSIST $0x01, X0, X1
+	CALL _expand_key_128<>(SB)
+	AESKEYGENASSIST $0x02, X0, X1
+	CALL _expand_key_128<>(SB)
+	AESKEYGENASSIST $0x04, X0, X1
+	CALL _expand_key_128<>(SB)
+	AESKEYGENASSIST $0x08, X0, X1
+	CALL _expand_key_128<>(SB)
+	AESKEYGENASSIST $0x10, X0, X1
+	CALL _expand_key_128<>(SB)
+	AESKEYGENASSIST $0x20, X0, X1
+	CALL _expand_key_128<>(SB)
+	AESKEYGENASSIST $0x40, X0, X1
+	CALL _expand_key_128<>(SB)
+	AESKEYGENASSIST $0x80, X0, X1
+	CALL _expand_key_128<>(SB)
+	AESKEYGENASSIST $0x1b, X0, X1
+	CALL _expand_key_128<>(SB)
+	AESKEYGENASSIST $0x36, X0, X1
+	CALL _expand_key_128<>(SB)
+Lexp_dec:
+	// dec
+	SUBQ $16, BX
+	MOVUPS (BX), X1
+	MOVUPS X1, (DX)
+	DECQ CX
+Lexp_dec_loop:
+	MOVUPS -16(BX), X1
+	AESIMC X1, X0
+	MOVUPS X0, 16(DX)
+	SUBQ $16, BX
+	ADDQ $16, DX
+	DECQ CX
+	JNZ Lexp_dec_loop
+	MOVUPS -16(BX), X0
+	MOVUPS X0, 16(DX)
+	RET
+
+#define PSHUFD_X0_X0_ BYTE $0x66; BYTE $0x0f; BYTE $0x70; BYTE $0xc0
+#define PSHUFD_X1_X1_ BYTE $0x66; BYTE $0x0f; BYTE $0x70; BYTE $0xc9
+TEXT _expand_key_128<>(SB),NOSPLIT,$0
+	PSHUFD $0xff, X1, X1
+	SHUFPS $0x10, X0, X4
+	PXOR X4, X0
+	SHUFPS $0x8c, X0, X4
+	PXOR X4, X0
+	PXOR X1, X0
+	MOVUPS X0, (BX)
+	ADDQ $16, BX
+	RET
+
+#define PSLLDQ_X5_ BYTE $0x66; BYTE $0x0f; BYTE $0x73; BYTE $0xfd
+#define PSHUFD_X0_X3_ BYTE $0x66; BYTE $0x0f; BYTE $0x70; BYTE $0xd8
+TEXT _expand_key_192a<>(SB),NOSPLIT,$0
+	PSHUFD $0x55, X1, X1
+	SHUFPS $0x10, X0, X4
+	PXOR X4, X0
+	SHUFPS $0x8c, X0, X4
+	PXOR X4, X0
+	PXOR X1, X0
+
+	MOVAPS X2, X5
+	MOVAPS X2, X6
+	PSLLDQ_X5_; BYTE $0x4
+	PSHUFD $0xff, X0, X3
+	PXOR X3, X2
+	PXOR X5, X2
+
+	MOVAPS X0, X1
+	SHUFPS $0x44, X0, X6
+	MOVUPS X6, (BX)
+	SHUFPS $0x4e, X2, X1
+	MOVUPS X1, 16(BX)
+	ADDQ $32, BX
+	RET
+
+TEXT _expand_key_192b<>(SB),NOSPLIT,$0
+	PSHUFD $0x55, X1, X1
+	SHUFPS $0x10, X0, X4
+	PXOR X4, X0
+	SHUFPS $0x8c, X0, X4
+	PXOR X4, X0
+	PXOR X1, X0
+
+	MOVAPS X2, X5
+	PSLLDQ_X5_; BYTE $0x4
+	PSHUFD $0xff, X0, X3
+	PXOR X3, X2
+	PXOR X5, X2
+
+	MOVUPS X0, (BX)
+	ADDQ $16, BX
+	RET
+
+TEXT _expand_key_256a<>(SB),NOSPLIT,$0
+	JMP _expand_key_128<>(SB)
+
+TEXT _expand_key_256b<>(SB),NOSPLIT,$0
+	PSHUFD $0xaa, X1, X1
+	SHUFPS $0x10, X2, X4
+	PXOR X4, X2
+	SHUFPS $0x8c, X2, X4
+	PXOR X4, X2
+	PXOR X1, X2
+
+	MOVUPS X2, (BX)
+	ADDQ $16, BX
+	RET
diff --git a/src/pkg/crypto/aes/block.go b/src/crypto/aes/block.go
similarity index 100%
rename from src/pkg/crypto/aes/block.go
rename to src/crypto/aes/block.go
diff --git a/src/pkg/crypto/aes/cipher.go b/src/crypto/aes/cipher.go
similarity index 100%
rename from src/pkg/crypto/aes/cipher.go
rename to src/crypto/aes/cipher.go
diff --git a/src/pkg/crypto/aes/cipher_asm.go b/src/crypto/aes/cipher_asm.go
similarity index 100%
rename from src/pkg/crypto/aes/cipher_asm.go
rename to src/crypto/aes/cipher_asm.go
diff --git a/src/pkg/crypto/aes/cipher_generic.go b/src/crypto/aes/cipher_generic.go
similarity index 100%
rename from src/pkg/crypto/aes/cipher_generic.go
rename to src/crypto/aes/cipher_generic.go
diff --git a/src/pkg/crypto/aes/const.go b/src/crypto/aes/const.go
similarity index 100%
rename from src/pkg/crypto/aes/const.go
rename to src/crypto/aes/const.go
diff --git a/src/pkg/crypto/cipher/benchmark_test.go b/src/crypto/cipher/benchmark_test.go
similarity index 100%
rename from src/pkg/crypto/cipher/benchmark_test.go
rename to src/crypto/cipher/benchmark_test.go
diff --git a/src/pkg/crypto/cipher/cbc.go b/src/crypto/cipher/cbc.go
similarity index 100%
rename from src/pkg/crypto/cipher/cbc.go
rename to src/crypto/cipher/cbc.go
diff --git a/src/pkg/crypto/cipher/cbc_aes_test.go b/src/crypto/cipher/cbc_aes_test.go
similarity index 100%
rename from src/pkg/crypto/cipher/cbc_aes_test.go
rename to src/crypto/cipher/cbc_aes_test.go
diff --git a/src/pkg/crypto/cipher/cfb.go b/src/crypto/cipher/cfb.go
similarity index 100%
rename from src/pkg/crypto/cipher/cfb.go
rename to src/crypto/cipher/cfb.go
diff --git a/src/crypto/cipher/cfb_test.go b/src/crypto/cipher/cfb_test.go
new file mode 100644
index 0000000..9b544bb
--- /dev/null
+++ b/src/crypto/cipher/cfb_test.go
@@ -0,0 +1,113 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package cipher_test
+
+import (
+	"bytes"
+	"crypto/aes"
+	"crypto/cipher"
+	"crypto/rand"
+	"encoding/hex"
+	"testing"
+)
+
+// cfbTests contains the test vectors from
+// http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf, section
+// F.3.13.
+var cfbTests = []struct {
+	key, iv, plaintext, ciphertext string
+}{
+	{
+		"2b7e151628aed2a6abf7158809cf4f3c",
+		"000102030405060708090a0b0c0d0e0f",
+		"6bc1bee22e409f96e93d7e117393172a",
+		"3b3fd92eb72dad20333449f8e83cfb4a",
+	},
+	{
+		"2b7e151628aed2a6abf7158809cf4f3c",
+		"3B3FD92EB72DAD20333449F8E83CFB4A",
+		"ae2d8a571e03ac9c9eb76fac45af8e51",
+		"c8a64537a0b3a93fcde3cdad9f1ce58b",
+	},
+	{
+		"2b7e151628aed2a6abf7158809cf4f3c",
+		"C8A64537A0B3A93FCDE3CDAD9F1CE58B",
+		"30c81c46a35ce411e5fbc1191a0a52ef",
+		"26751f67a3cbb140b1808cf187a4f4df",
+	},
+	{
+		"2b7e151628aed2a6abf7158809cf4f3c",
+		"26751F67A3CBB140B1808CF187A4F4DF",
+		"f69f2445df4f9b17ad2b417be66c3710",
+		"c04b05357c5d1c0eeac4c66f9ff7f2e6",
+	},
+}
+
+func TestCFBVectors(t *testing.T) {
+	for i, test := range cfbTests {
+		key, err := hex.DecodeString(test.key)
+		if err != nil {
+			t.Fatal(err)
+		}
+		iv, err := hex.DecodeString(test.iv)
+		if err != nil {
+			t.Fatal(err)
+		}
+		plaintext, err := hex.DecodeString(test.plaintext)
+		if err != nil {
+			t.Fatal(err)
+		}
+		expected, err := hex.DecodeString(test.ciphertext)
+		if err != nil {
+			t.Fatal(err)
+		}
+
+		block, err := aes.NewCipher(key)
+		if err != nil {
+			t.Fatal(err)
+		}
+
+		ciphertext := make([]byte, len(plaintext))
+		cfb := cipher.NewCFBEncrypter(block, iv)
+		cfb.XORKeyStream(ciphertext, plaintext)
+
+		if !bytes.Equal(ciphertext, expected) {
+			t.Errorf("#%d: wrong output: got %x, expected %x", i, ciphertext, expected)
+		}
+
+		cfbdec := cipher.NewCFBDecrypter(block, iv)
+		plaintextCopy := make([]byte, len(ciphertext))
+		cfbdec.XORKeyStream(plaintextCopy, ciphertext)
+
+		if !bytes.Equal(plaintextCopy, plaintextCopy) {
+			t.Errorf("#%d: wrong plaintext: got %x, expected %x", i, plaintextCopy, plaintext)
+		}
+	}
+}
+
+func TestCFBInverse(t *testing.T) {
+	block, err := aes.NewCipher(commonKey128)
+	if err != nil {
+		t.Error(err)
+		return
+	}
+
+	plaintext := []byte("this is the plaintext. this is the plaintext.")
+	iv := make([]byte, block.BlockSize())
+	rand.Reader.Read(iv)
+	cfb := cipher.NewCFBEncrypter(block, iv)
+	ciphertext := make([]byte, len(plaintext))
+	copy(ciphertext, plaintext)
+	cfb.XORKeyStream(ciphertext, ciphertext)
+
+	cfbdec := cipher.NewCFBDecrypter(block, iv)
+	plaintextCopy := make([]byte, len(plaintext))
+	copy(plaintextCopy, ciphertext)
+	cfbdec.XORKeyStream(plaintextCopy, plaintextCopy)
+
+	if !bytes.Equal(plaintextCopy, plaintext) {
+		t.Errorf("got: %x, want: %x", plaintextCopy, plaintext)
+	}
+}
diff --git a/src/pkg/crypto/cipher/cipher.go b/src/crypto/cipher/cipher.go
similarity index 100%
rename from src/pkg/crypto/cipher/cipher.go
rename to src/crypto/cipher/cipher.go
diff --git a/src/pkg/crypto/cipher/cipher_test.go b/src/crypto/cipher/cipher_test.go
similarity index 100%
rename from src/pkg/crypto/cipher/cipher_test.go
rename to src/crypto/cipher/cipher_test.go
diff --git a/src/pkg/crypto/cipher/common_test.go b/src/crypto/cipher/common_test.go
similarity index 100%
rename from src/pkg/crypto/cipher/common_test.go
rename to src/crypto/cipher/common_test.go
diff --git a/src/pkg/crypto/cipher/ctr.go b/src/crypto/cipher/ctr.go
similarity index 100%
rename from src/pkg/crypto/cipher/ctr.go
rename to src/crypto/cipher/ctr.go
diff --git a/src/pkg/crypto/cipher/ctr_aes_test.go b/src/crypto/cipher/ctr_aes_test.go
similarity index 100%
rename from src/pkg/crypto/cipher/ctr_aes_test.go
rename to src/crypto/cipher/ctr_aes_test.go
diff --git a/src/crypto/cipher/example_test.go b/src/crypto/cipher/example_test.go
new file mode 100644
index 0000000..1cfa982
--- /dev/null
+++ b/src/crypto/cipher/example_test.go
@@ -0,0 +1,283 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package cipher_test
+
+import (
+	"crypto/aes"
+	"crypto/cipher"
+	"crypto/rand"
+	"encoding/hex"
+	"fmt"
+	"io"
+	"os"
+)
+
+func ExampleNewCBCDecrypter() {
+	key := []byte("example key 1234")
+	ciphertext, _ := hex.DecodeString("f363f3ccdcb12bb883abf484ba77d9cd7d32b5baecb3d4b1b3e0e4beffdb3ded")
+
+	block, err := aes.NewCipher(key)
+	if err != nil {
+		panic(err)
+	}
+
+	// The IV needs to be unique, but not secure. Therefore it's common to
+	// include it at the beginning of the ciphertext.
+	if len(ciphertext) < aes.BlockSize {
+		panic("ciphertext too short")
+	}
+	iv := ciphertext[:aes.BlockSize]
+	ciphertext = ciphertext[aes.BlockSize:]
+
+	// CBC mode always works in whole blocks.
+	if len(ciphertext)%aes.BlockSize != 0 {
+		panic("ciphertext is not a multiple of the block size")
+	}
+
+	mode := cipher.NewCBCDecrypter(block, iv)
+
+	// CryptBlocks can work in-place if the two arguments are the same.
+	mode.CryptBlocks(ciphertext, ciphertext)
+
+	// If the original plaintext lengths are not a multiple of the block
+	// size, padding would have to be added when encrypting, which would be
+	// removed at this point. For an example, see
+	// https://tools.ietf.org/html/rfc5246#section-6.2.3.2. However, it's
+	// critical to note that ciphertexts must be authenticated (i.e. by
+	// using crypto/hmac) before being decrypted in order to avoid creating
+	// a padding oracle.
+
+	fmt.Printf("%s\n", ciphertext)
+	// Output: exampleplaintext
+}
+
+func ExampleNewCBCEncrypter() {
+	key := []byte("example key 1234")
+	plaintext := []byte("exampleplaintext")
+
+	// CBC mode works on blocks so plaintexts may need to be padded to the
+	// next whole block. For an example of such padding, see
+	// https://tools.ietf.org/html/rfc5246#section-6.2.3.2. Here we'll
+	// assume that the plaintext is already of the correct length.
+	if len(plaintext)%aes.BlockSize != 0 {
+		panic("plaintext is not a multiple of the block size")
+	}
+
+	block, err := aes.NewCipher(key)
+	if err != nil {
+		panic(err)
+	}
+
+	// The IV needs to be unique, but not secure. Therefore it's common to
+	// include it at the beginning of the ciphertext.
+	ciphertext := make([]byte, aes.BlockSize+len(plaintext))
+	iv := ciphertext[:aes.BlockSize]
+	if _, err := io.ReadFull(rand.Reader, iv); err != nil {
+		panic(err)
+	}
+
+	mode := cipher.NewCBCEncrypter(block, iv)
+	mode.CryptBlocks(ciphertext[aes.BlockSize:], plaintext)
+
+	// It's important to remember that ciphertexts must be authenticated
+	// (i.e. by using crypto/hmac) as well as being encrypted in order to
+	// be secure.
+
+	fmt.Printf("%x\n", ciphertext)
+}
+
+func ExampleNewCFBDecrypter() {
+	key := []byte("example key 1234")
+	ciphertext, _ := hex.DecodeString("22277966616d9bc47177bd02603d08c9a67d5380d0fe8cf3b44438dff7b9")
+
+	block, err := aes.NewCipher(key)
+	if err != nil {
+		panic(err)
+	}
+
+	// The IV needs to be unique, but not secure. Therefore it's common to
+	// include it at the beginning of the ciphertext.
+	if len(ciphertext) < aes.BlockSize {
+		panic("ciphertext too short")
+	}
+	iv := ciphertext[:aes.BlockSize]
+	ciphertext = ciphertext[aes.BlockSize:]
+
+	stream := cipher.NewCFBDecrypter(block, iv)
+
+	// XORKeyStream can work in-place if the two arguments are the same.
+	stream.XORKeyStream(ciphertext, ciphertext)
+	fmt.Printf("%s", ciphertext)
+	// Output: some plaintext
+}
+
+func ExampleNewCFBEncrypter() {
+	key := []byte("example key 1234")
+	plaintext := []byte("some plaintext")
+
+	block, err := aes.NewCipher(key)
+	if err != nil {
+		panic(err)
+	}
+
+	// The IV needs to be unique, but not secure. Therefore it's common to
+	// include it at the beginning of the ciphertext.
+	ciphertext := make([]byte, aes.BlockSize+len(plaintext))
+	iv := ciphertext[:aes.BlockSize]
+	if _, err := io.ReadFull(rand.Reader, iv); err != nil {
+		panic(err)
+	}
+
+	stream := cipher.NewCFBEncrypter(block, iv)
+	stream.XORKeyStream(ciphertext[aes.BlockSize:], plaintext)
+
+	// It's important to remember that ciphertexts must be authenticated
+	// (i.e. by using crypto/hmac) as well as being encrypted in order to
+	// be secure.
+}
+
+func ExampleNewCTR() {
+	key := []byte("example key 1234")
+	plaintext := []byte("some plaintext")
+
+	block, err := aes.NewCipher(key)
+	if err != nil {
+		panic(err)
+	}
+
+	// The IV needs to be unique, but not secure. Therefore it's common to
+	// include it at the beginning of the ciphertext.
+	ciphertext := make([]byte, aes.BlockSize+len(plaintext))
+	iv := ciphertext[:aes.BlockSize]
+	if _, err := io.ReadFull(rand.Reader, iv); err != nil {
+		panic(err)
+	}
+
+	stream := cipher.NewCTR(block, iv)
+	stream.XORKeyStream(ciphertext[aes.BlockSize:], plaintext)
+
+	// It's important to remember that ciphertexts must be authenticated
+	// (i.e. by using crypto/hmac) as well as being encrypted in order to
+	// be secure.
+
+	// CTR mode is the same for both encryption and decryption, so we can
+	// also decrypt that ciphertext with NewCTR.
+
+	plaintext2 := make([]byte, len(plaintext))
+	stream = cipher.NewCTR(block, iv)
+	stream.XORKeyStream(plaintext2, ciphertext[aes.BlockSize:])
+
+	fmt.Printf("%s\n", plaintext2)
+	// Output: some plaintext
+}
+
+func ExampleNewOFB() {
+	key := []byte("example key 1234")
+	plaintext := []byte("some plaintext")
+
+	block, err := aes.NewCipher(key)
+	if err != nil {
+		panic(err)
+	}
+
+	// The IV needs to be unique, but not secure. Therefore it's common to
+	// include it at the beginning of the ciphertext.
+	ciphertext := make([]byte, aes.BlockSize+len(plaintext))
+	iv := ciphertext[:aes.BlockSize]
+	if _, err := io.ReadFull(rand.Reader, iv); err != nil {
+		panic(err)
+	}
+
+	stream := cipher.NewOFB(block, iv)
+	stream.XORKeyStream(ciphertext[aes.BlockSize:], plaintext)
+
+	// It's important to remember that ciphertexts must be authenticated
+	// (i.e. by using crypto/hmac) as well as being encrypted in order to
+	// be secure.
+
+	// OFB mode is the same for both encryption and decryption, so we can
+	// also decrypt that ciphertext with NewOFB.
+
+	plaintext2 := make([]byte, len(plaintext))
+	stream = cipher.NewOFB(block, iv)
+	stream.XORKeyStream(plaintext2, ciphertext[aes.BlockSize:])
+
+	fmt.Printf("%s\n", plaintext2)
+	// Output: some plaintext
+}
+
+func ExampleStreamReader() {
+	key := []byte("example key 1234")
+
+	inFile, err := os.Open("encrypted-file")
+	if err != nil {
+		panic(err)
+	}
+	defer inFile.Close()
+
+	block, err := aes.NewCipher(key)
+	if err != nil {
+		panic(err)
+	}
+
+	// If the key is unique for each ciphertext, then it's ok to use a zero
+	// IV.
+	var iv [aes.BlockSize]byte
+	stream := cipher.NewOFB(block, iv[:])
+
+	outFile, err := os.OpenFile("decrypted-file", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
+	if err != nil {
+		panic(err)
+	}
+	defer outFile.Close()
+
+	reader := &cipher.StreamReader{S: stream, R: inFile}
+	// Copy the input file to the output file, decrypting as we go.
+	if _, err := io.Copy(outFile, reader); err != nil {
+		panic(err)
+	}
+
+	// Note that this example is simplistic in that it omits any
+	// authentication of the encrypted data. If you were actually to use
+	// StreamReader in this manner, an attacker could flip arbitrary bits in
+	// the output.
+}
+
+func ExampleStreamWriter() {
+	key := []byte("example key 1234")
+
+	inFile, err := os.Open("plaintext-file")
+	if err != nil {
+		panic(err)
+	}
+	defer inFile.Close()
+
+	block, err := aes.NewCipher(key)
+	if err != nil {
+		panic(err)
+	}
+
+	// If the key is unique for each ciphertext, then it's ok to use a zero
+	// IV.
+	var iv [aes.BlockSize]byte
+	stream := cipher.NewOFB(block, iv[:])
+
+	outFile, err := os.OpenFile("encrypted-file", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
+	if err != nil {
+		panic(err)
+	}
+	defer outFile.Close()
+
+	writer := &cipher.StreamWriter{S: stream, W: outFile}
+	// Copy the input file to the output file, encrypting as we go.
+	if _, err := io.Copy(writer, inFile); err != nil {
+		panic(err)
+	}
+
+	// Note that this example is simplistic in that it omits any
+	// authentication of the encrypted data. If you were actually to use
+	// StreamReader in this manner, an attacker could flip arbitrary bits in
+	// the decrypted result.
+}
diff --git a/src/pkg/crypto/cipher/gcm.go b/src/crypto/cipher/gcm.go
similarity index 100%
rename from src/pkg/crypto/cipher/gcm.go
rename to src/crypto/cipher/gcm.go
diff --git a/src/pkg/crypto/cipher/gcm_test.go b/src/crypto/cipher/gcm_test.go
similarity index 100%
rename from src/pkg/crypto/cipher/gcm_test.go
rename to src/crypto/cipher/gcm_test.go
diff --git a/src/pkg/crypto/cipher/io.go b/src/crypto/cipher/io.go
similarity index 100%
rename from src/pkg/crypto/cipher/io.go
rename to src/crypto/cipher/io.go
diff --git a/src/pkg/crypto/cipher/ofb.go b/src/crypto/cipher/ofb.go
similarity index 100%
rename from src/pkg/crypto/cipher/ofb.go
rename to src/crypto/cipher/ofb.go
diff --git a/src/pkg/crypto/cipher/ofb_test.go b/src/crypto/cipher/ofb_test.go
similarity index 100%
rename from src/pkg/crypto/cipher/ofb_test.go
rename to src/crypto/cipher/ofb_test.go
diff --git a/src/pkg/crypto/cipher/xor.go b/src/crypto/cipher/xor.go
similarity index 100%
rename from src/pkg/crypto/cipher/xor.go
rename to src/crypto/cipher/xor.go
diff --git a/src/pkg/crypto/cipher/xor_test.go b/src/crypto/cipher/xor_test.go
similarity index 100%
rename from src/pkg/crypto/cipher/xor_test.go
rename to src/crypto/cipher/xor_test.go
diff --git a/src/crypto/crypto.go b/src/crypto/crypto.go
new file mode 100644
index 0000000..59b23e9
--- /dev/null
+++ b/src/crypto/crypto.go
@@ -0,0 +1,126 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package crypto collects common cryptographic constants.
+package crypto
+
+import (
+	"hash"
+	"io"
+	"strconv"
+)
+
+// Hash identifies a cryptographic hash function that is implemented in another
+// package.
+type Hash uint
+
+// HashFunc simply returns the value of h so that Hash implements SignerOpts.
+func (h Hash) HashFunc() Hash {
+	return h
+}
+
+const (
+	MD4       Hash = 1 + iota // import golang.org/x/crypto/md4
+	MD5                       // import crypto/md5
+	SHA1                      // import crypto/sha1
+	SHA224                    // import crypto/sha256
+	SHA256                    // import crypto/sha256
+	SHA384                    // import crypto/sha512
+	SHA512                    // import crypto/sha512
+	MD5SHA1                   // no implementation; MD5+SHA1 used for TLS RSA
+	RIPEMD160                 // import golang.org/x/crypto/ripemd160
+	SHA3_224                  // import golang.org/x/crypto/sha3
+	SHA3_256                  // import golang.org/x/crypto/sha3
+	SHA3_384                  // import golang.org/x/crypto/sha3
+	SHA3_512                  // import golang.org/x/crypto/sha3
+	maxHash
+)
+
+var digestSizes = []uint8{
+	MD4:       16,
+	MD5:       16,
+	SHA1:      20,
+	SHA224:    28,
+	SHA256:    32,
+	SHA384:    48,
+	SHA512:    64,
+	SHA3_224:  28,
+	SHA3_256:  32,
+	SHA3_384:  48,
+	SHA3_512:  64,
+	MD5SHA1:   36,
+	RIPEMD160: 20,
+}
+
+// Size returns the length, in bytes, of a digest resulting from the given hash
+// function. It doesn't require that the hash function in question be linked
+// into the program.
+func (h Hash) Size() int {
+	if h > 0 && h < maxHash {
+		return int(digestSizes[h])
+	}
+	panic("crypto: Size of unknown hash function")
+}
+
+var hashes = make([]func() hash.Hash, maxHash)
+
+// New returns a new hash.Hash calculating the given hash function. New panics
+// if the hash function is not linked into the binary.
+func (h Hash) New() hash.Hash {
+	if h > 0 && h < maxHash {
+		f := hashes[h]
+		if f != nil {
+			return f()
+		}
+	}
+	panic("crypto: requested hash function #" + strconv.Itoa(int(h)) + " is unavailable")
+}
+
+// Available reports whether the given hash function is linked into the binary.
+func (h Hash) Available() bool {
+	return h < maxHash && hashes[h] != nil
+}
+
+// RegisterHash registers a function that returns a new instance of the given
+// hash function. This is intended to be called from the init function in
+// packages that implement hash functions.
+func RegisterHash(h Hash, f func() hash.Hash) {
+	if h >= maxHash {
+		panic("crypto: RegisterHash of unknown hash function")
+	}
+	hashes[h] = f
+}
+
+// PublicKey represents a public key using an unspecified algorithm.
+type PublicKey interface{}
+
+// PrivateKey represents a private key using an unspecified algorithm.
+type PrivateKey interface{}
+
+// Signer is an interface for an opaque private key that can be used for
+// signing operations. For example, an RSA key kept in a hardware module.
+type Signer interface {
+	// Public returns the public key corresponding to the opaque,
+	// private key.
+	Public() PublicKey
+
+	// Sign signs msg with the private key, possibly using entropy from
+	// rand. For an RSA key, the resulting signature should be either a
+	// PKCS#1 v1.5 or PSS signature (as indicated by opts). For an (EC)DSA
+	// key, it should be a DER-serialised, ASN.1 signature structure.
+	//
+	// Hash implements the SignerOpts interface and, in most cases, one can
+	// simply pass in the hash function used as opts. Sign may also attempt
+	// to type assert opts to other types in order to obtain algorithm
+	// specific values. See the documentation in each package for details.
+	Sign(rand io.Reader, msg []byte, opts SignerOpts) (signature []byte, err error)
+}
+
+// SignerOpts contains options for signing with a Signer.
+type SignerOpts interface {
+	// HashFunc returns an identifier for the hash function used to produce
+	// the message passed to Signer.Sign, or else zero to indicate that no
+	// hashing was done.
+	HashFunc() Hash
+}
diff --git a/src/pkg/crypto/des/block.go b/src/crypto/des/block.go
similarity index 100%
rename from src/pkg/crypto/des/block.go
rename to src/crypto/des/block.go
diff --git a/src/pkg/crypto/des/cipher.go b/src/crypto/des/cipher.go
similarity index 100%
rename from src/pkg/crypto/des/cipher.go
rename to src/crypto/des/cipher.go
diff --git a/src/pkg/crypto/des/const.go b/src/crypto/des/const.go
similarity index 100%
rename from src/pkg/crypto/des/const.go
rename to src/crypto/des/const.go
diff --git a/src/pkg/crypto/des/des_test.go b/src/crypto/des/des_test.go
similarity index 100%
rename from src/pkg/crypto/des/des_test.go
rename to src/crypto/des/des_test.go
diff --git a/src/pkg/crypto/des/example_test.go b/src/crypto/des/example_test.go
similarity index 100%
rename from src/pkg/crypto/des/example_test.go
rename to src/crypto/des/example_test.go
diff --git a/src/pkg/crypto/dsa/dsa.go b/src/crypto/dsa/dsa.go
similarity index 100%
rename from src/pkg/crypto/dsa/dsa.go
rename to src/crypto/dsa/dsa.go
diff --git a/src/pkg/crypto/dsa/dsa_test.go b/src/crypto/dsa/dsa_test.go
similarity index 100%
rename from src/pkg/crypto/dsa/dsa_test.go
rename to src/crypto/dsa/dsa_test.go
diff --git a/src/crypto/ecdsa/ecdsa.go b/src/crypto/ecdsa/ecdsa.go
new file mode 100644
index 0000000..d613553
--- /dev/null
+++ b/src/crypto/ecdsa/ecdsa.go
@@ -0,0 +1,189 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package ecdsa implements the Elliptic Curve Digital Signature Algorithm, as
+// defined in FIPS 186-3.
+package ecdsa
+
+// References:
+//   [NSA]: Suite B implementer's guide to FIPS 186-3,
+//     http://www.nsa.gov/ia/_files/ecdsa.pdf
+//   [SECG]: SECG, SEC1
+//     http://www.secg.org/download/aid-780/sec1-v2.pdf
+
+import (
+	"crypto"
+	"crypto/elliptic"
+	"encoding/asn1"
+	"io"
+	"math/big"
+)
+
+// PublicKey represents an ECDSA public key.
+type PublicKey struct {
+	elliptic.Curve
+	X, Y *big.Int
+}
+
+// PrivateKey represents a ECDSA private key.
+type PrivateKey struct {
+	PublicKey
+	D *big.Int
+}
+
+type ecdsaSignature struct {
+	R, S *big.Int
+}
+
+// Public returns the public key corresponding to priv.
+func (priv *PrivateKey) Public() crypto.PublicKey {
+	return &priv.PublicKey
+}
+
+// Sign signs msg with priv, reading randomness from rand. This method is
+// intended to support keys where the private part is kept in, for example, a
+// hardware module. Common uses should use the Sign function in this package
+// directly.
+func (priv *PrivateKey) Sign(rand io.Reader, msg []byte, opts crypto.SignerOpts) ([]byte, error) {
+	r, s, err := Sign(rand, priv, msg)
+	if err != nil {
+		return nil, err
+	}
+
+	return asn1.Marshal(ecdsaSignature{r, s})
+}
+
+var one = new(big.Int).SetInt64(1)
+
+// randFieldElement returns a random element of the field underlying the given
+// curve using the procedure given in [NSA] A.2.1.
+func randFieldElement(c elliptic.Curve, rand io.Reader) (k *big.Int, err error) {
+	params := c.Params()
+	b := make([]byte, params.BitSize/8+8)
+	_, err = io.ReadFull(rand, b)
+	if err != nil {
+		return
+	}
+
+	k = new(big.Int).SetBytes(b)
+	n := new(big.Int).Sub(params.N, one)
+	k.Mod(k, n)
+	k.Add(k, one)
+	return
+}
+
+// GenerateKey generates a public and private key pair.
+func GenerateKey(c elliptic.Curve, rand io.Reader) (priv *PrivateKey, err error) {
+	k, err := randFieldElement(c, rand)
+	if err != nil {
+		return
+	}
+
+	priv = new(PrivateKey)
+	priv.PublicKey.Curve = c
+	priv.D = k
+	priv.PublicKey.X, priv.PublicKey.Y = c.ScalarBaseMult(k.Bytes())
+	return
+}
+
+// hashToInt converts a hash value to an integer. There is some disagreement
+// about how this is done. [NSA] suggests that this is done in the obvious
+// manner, but [SECG] truncates the hash to the bit-length of the curve order
+// first. We follow [SECG] because that's what OpenSSL does. Additionally,
+// OpenSSL right shifts excess bits from the number if the hash is too large
+// and we mirror that too.
+func hashToInt(hash []byte, c elliptic.Curve) *big.Int {
+	orderBits := c.Params().N.BitLen()
+	orderBytes := (orderBits + 7) / 8
+	if len(hash) > orderBytes {
+		hash = hash[:orderBytes]
+	}
+
+	ret := new(big.Int).SetBytes(hash)
+	excess := len(hash)*8 - orderBits
+	if excess > 0 {
+		ret.Rsh(ret, uint(excess))
+	}
+	return ret
+}
+
+// fermatInverse calculates the inverse of k in GF(P) using Fermat's method.
+// This has better constant-time properties than Euclid's method (implemented
+// in math/big.Int.ModInverse) although math/big itself isn't strictly
+// constant-time so it's not perfect.
+func fermatInverse(k, N *big.Int) *big.Int {
+	two := big.NewInt(2)
+	nMinus2 := new(big.Int).Sub(N, two)
+	return new(big.Int).Exp(k, nMinus2, N)
+}
+
+// Sign signs an arbitrary length hash (which should be the result of hashing a
+// larger message) using the private key, priv. It returns the signature as a
+// pair of integers. The security of the private key depends on the entropy of
+// rand.
+func Sign(rand io.Reader, priv *PrivateKey, hash []byte) (r, s *big.Int, err error) {
+	// See [NSA] 3.4.1
+	c := priv.PublicKey.Curve
+	N := c.Params().N
+
+	var k, kInv *big.Int
+	for {
+		for {
+			k, err = randFieldElement(c, rand)
+			if err != nil {
+				r = nil
+				return
+			}
+
+			kInv = fermatInverse(k, N)
+			r, _ = priv.Curve.ScalarBaseMult(k.Bytes())
+			r.Mod(r, N)
+			if r.Sign() != 0 {
+				break
+			}
+		}
+
+		e := hashToInt(hash, c)
+		s = new(big.Int).Mul(priv.D, r)
+		s.Add(s, e)
+		s.Mul(s, kInv)
+		s.Mod(s, N)
+		if s.Sign() != 0 {
+			break
+		}
+	}
+
+	return
+}
+
+// Verify verifies the signature in r, s of hash using the public key, pub. Its
+// return value records whether the signature is valid.
+func Verify(pub *PublicKey, hash []byte, r, s *big.Int) bool {
+	// See [NSA] 3.4.2
+	c := pub.Curve
+	N := c.Params().N
+
+	if r.Sign() == 0 || s.Sign() == 0 {
+		return false
+	}
+	if r.Cmp(N) >= 0 || s.Cmp(N) >= 0 {
+		return false
+	}
+	e := hashToInt(hash, c)
+	w := new(big.Int).ModInverse(s, N)
+
+	u1 := e.Mul(e, w)
+	u1.Mod(u1, N)
+	u2 := w.Mul(r, w)
+	u2.Mod(u2, N)
+
+	x1, y1 := c.ScalarBaseMult(u1.Bytes())
+	x2, y2 := c.ScalarMult(pub.X, pub.Y, u2.Bytes())
+	x, y := c.Add(x1, y1, x2, y2)
+	if x.Sign() == 0 && y.Sign() == 0 {
+		return false
+	}
+	x.Mod(x, N)
+	return x.Cmp(r) == 0
+}
diff --git a/src/pkg/crypto/ecdsa/ecdsa_test.go b/src/crypto/ecdsa/ecdsa_test.go
similarity index 100%
rename from src/pkg/crypto/ecdsa/ecdsa_test.go
rename to src/crypto/ecdsa/ecdsa_test.go
diff --git a/src/pkg/crypto/ecdsa/testdata/SigVer.rsp.bz2 b/src/crypto/ecdsa/testdata/SigVer.rsp.bz2
similarity index 100%
rename from src/pkg/crypto/ecdsa/testdata/SigVer.rsp.bz2
rename to src/crypto/ecdsa/testdata/SigVer.rsp.bz2
diff --git a/src/pkg/crypto/elliptic/elliptic.go b/src/crypto/elliptic/elliptic.go
similarity index 100%
rename from src/pkg/crypto/elliptic/elliptic.go
rename to src/crypto/elliptic/elliptic.go
diff --git a/src/pkg/crypto/elliptic/elliptic_test.go b/src/crypto/elliptic/elliptic_test.go
similarity index 100%
rename from src/pkg/crypto/elliptic/elliptic_test.go
rename to src/crypto/elliptic/elliptic_test.go
diff --git a/src/pkg/crypto/elliptic/p224.go b/src/crypto/elliptic/p224.go
similarity index 100%
rename from src/pkg/crypto/elliptic/p224.go
rename to src/crypto/elliptic/p224.go
diff --git a/src/pkg/crypto/elliptic/p224_test.go b/src/crypto/elliptic/p224_test.go
similarity index 100%
rename from src/pkg/crypto/elliptic/p224_test.go
rename to src/crypto/elliptic/p224_test.go
diff --git a/src/pkg/crypto/elliptic/p256.go b/src/crypto/elliptic/p256.go
similarity index 100%
rename from src/pkg/crypto/elliptic/p256.go
rename to src/crypto/elliptic/p256.go
diff --git a/src/pkg/crypto/hmac/hmac.go b/src/crypto/hmac/hmac.go
similarity index 100%
rename from src/pkg/crypto/hmac/hmac.go
rename to src/crypto/hmac/hmac.go
diff --git a/src/pkg/crypto/hmac/hmac_test.go b/src/crypto/hmac/hmac_test.go
similarity index 100%
rename from src/pkg/crypto/hmac/hmac_test.go
rename to src/crypto/hmac/hmac_test.go
diff --git a/src/pkg/crypto/md5/example_test.go b/src/crypto/md5/example_test.go
similarity index 100%
rename from src/pkg/crypto/md5/example_test.go
rename to src/crypto/md5/example_test.go
diff --git a/src/crypto/md5/gen.go b/src/crypto/md5/gen.go
new file mode 100644
index 0000000..8cd0a63
--- /dev/null
+++ b/src/crypto/md5/gen.go
@@ -0,0 +1,331 @@
+// Copyright 2012 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build ignore
+
+// This program generates md5block.go
+// Invoke as
+//
+//	go run gen.go [-full] -output md5block.go
+//
+// The -full flag causes the generated code to do a full
+// (16x) unrolling instead of a 4x unrolling.
+
+package main
+
+import (
+	"bytes"
+	"flag"
+	"go/format"
+	"io/ioutil"
+	"log"
+	"strings"
+	"text/template"
+)
+
+var filename = flag.String("output", "md5block.go", "output file name")
+
+func main() {
+	flag.Parse()
+
+	var buf bytes.Buffer
+
+	t := template.Must(template.New("main").Funcs(funcs).Parse(program))
+	if err := t.Execute(&buf, data); err != nil {
+		log.Fatal(err)
+	}
+
+	data, err := format.Source(buf.Bytes())
+	if err != nil {
+		log.Fatal(err)
+	}
+	err = ioutil.WriteFile(*filename, data, 0644)
+	if err != nil {
+		log.Fatal(err)
+	}
+}
+
+type Data struct {
+	a, b, c, d string
+	Shift1     []int
+	Shift2     []int
+	Shift3     []int
+	Shift4     []int
+	Table1     []uint32
+	Table2     []uint32
+	Table3     []uint32
+	Table4     []uint32
+	Full       bool
+}
+
+var funcs = template.FuncMap{
+	"dup":     dup,
+	"relabel": relabel,
+	"rotate":  rotate,
+}
+
+func dup(count int, x []int) []int {
+	var out []int
+	for i := 0; i < count; i++ {
+		out = append(out, x...)
+	}
+	return out
+}
+
+func relabel(s string) string {
+	return strings.NewReplacer("a", data.a, "b", data.b, "c", data.c, "d", data.d).Replace(s)
+}
+
+func rotate() string {
+	data.a, data.b, data.c, data.d = data.d, data.a, data.b, data.c
+	return "" // no output
+}
+
+func init() {
+	flag.BoolVar(&data.Full, "full", false, "complete unrolling")
+}
+
+var data = Data{
+	a:      "a",
+	b:      "b",
+	c:      "c",
+	d:      "d",
+	Shift1: []int{7, 12, 17, 22},
+	Shift2: []int{5, 9, 14, 20},
+	Shift3: []int{4, 11, 16, 23},
+	Shift4: []int{6, 10, 15, 21},
+
+	// table[i] = int((1<<32) * abs(sin(i+1 radians))).
+	Table1: []uint32{
+		// round 1
+		0xd76aa478,
+		0xe8c7b756,
+		0x242070db,
+		0xc1bdceee,
+		0xf57c0faf,
+		0x4787c62a,
+		0xa8304613,
+		0xfd469501,
+		0x698098d8,
+		0x8b44f7af,
+		0xffff5bb1,
+		0x895cd7be,
+		0x6b901122,
+		0xfd987193,
+		0xa679438e,
+		0x49b40821,
+	},
+	Table2: []uint32{
+		// round 2
+		0xf61e2562,
+		0xc040b340,
+		0x265e5a51,
+		0xe9b6c7aa,
+		0xd62f105d,
+		0x2441453,
+		0xd8a1e681,
+		0xe7d3fbc8,
+		0x21e1cde6,
+		0xc33707d6,
+		0xf4d50d87,
+		0x455a14ed,
+		0xa9e3e905,
+		0xfcefa3f8,
+		0x676f02d9,
+		0x8d2a4c8a,
+	},
+	Table3: []uint32{
+		// round3
+		0xfffa3942,
+		0x8771f681,
+		0x6d9d6122,
+		0xfde5380c,
+		0xa4beea44,
+		0x4bdecfa9,
+		0xf6bb4b60,
+		0xbebfbc70,
+		0x289b7ec6,
+		0xeaa127fa,
+		0xd4ef3085,
+		0x4881d05,
+		0xd9d4d039,
+		0xe6db99e5,
+		0x1fa27cf8,
+		0xc4ac5665,
+	},
+	Table4: []uint32{
+		// round 4
+		0xf4292244,
+		0x432aff97,
+		0xab9423a7,
+		0xfc93a039,
+		0x655b59c3,
+		0x8f0ccc92,
+		0xffeff47d,
+		0x85845dd1,
+		0x6fa87e4f,
+		0xfe2ce6e0,
+		0xa3014314,
+		0x4e0811a1,
+		0xf7537e82,
+		0xbd3af235,
+		0x2ad7d2bb,
+		0xeb86d391,
+	},
+}
+
+var program = `// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// DO NOT EDIT.
+// Generate with: go run gen.go{{if .Full}} -full{{end}} -output md5block.go
+
+package md5
+
+import (
+	"unsafe"
+	"runtime"
+)
+
+{{if not .Full}}
+	var t1 = [...]uint32{
+	{{range .Table1}}{{printf "\t%#x,\n" .}}{{end}}
+	}
+	
+	var t2 = [...]uint32{
+	{{range .Table2}}{{printf "\t%#x,\n" .}}{{end}}
+	}
+	
+	var t3 = [...]uint32{
+	{{range .Table3}}{{printf "\t%#x,\n" .}}{{end}}
+	}
+	
+	var t4 = [...]uint32{
+	{{range .Table4}}{{printf "\t%#x,\n" .}}{{end}}
+	}
+{{end}}
+
+const x86 = runtime.GOARCH == "amd64" || runtime.GOARCH == "386"
+
+var littleEndian bool
+
+func init() {
+	x := uint32(0x04030201)
+	y := [4]byte{0x1, 0x2, 0x3, 0x4}
+	littleEndian = *(*[4]byte)(unsafe.Pointer(&x)) == y
+}
+
+func blockGeneric(dig *digest, p []byte) {
+	a := dig.s[0]
+	b := dig.s[1]
+	c := dig.s[2]
+	d := dig.s[3]
+	var X *[16]uint32
+	var xbuf [16]uint32
+	for len(p) >= chunk {
+		aa, bb, cc, dd := a, b, c, d
+
+		// This is a constant condition - it is not evaluated on each iteration.
+		if x86 {
+			// MD5 was designed so that x86 processors can just iterate
+			// over the block data directly as uint32s, and we generate
+			// less code and run 1.3x faster if we take advantage of that.
+			// My apologies.
+			X = (*[16]uint32)(unsafe.Pointer(&p[0]))
+		} else if littleEndian && uintptr(unsafe.Pointer(&p[0]))&(unsafe.Alignof(uint32(0))-1) == 0 {
+			X = (*[16]uint32)(unsafe.Pointer(&p[0]))
+		} else {
+			X = &xbuf
+			j := 0
+			for i := 0; i < 16; i++ {
+				X[i&15] = uint32(p[j]) | uint32(p[j+1])<<8 | uint32(p[j+2])<<16 | uint32(p[j+3])<<24
+				j += 4
+			}
+		}
+
+		{{if .Full}}
+			// Round 1.
+			{{range $i, $s := dup 4 .Shift1}}
+				{{index $.Table1 $i | printf "a += (((c^d)&b)^d) + X[%d] + %d" $i | relabel}}
+				{{printf "a = a<<%d | a>>(32-%d) + b" $s $s | relabel}}
+				{{rotate}}
+			{{end}}
+	
+			// Round 2.
+			{{range $i, $s := dup 4 .Shift2}}
+				{{index $.Table2 $i | printf "a += (((b^c)&d)^c) + X[(1+5*%d)&15] + %d" $i | relabel}}
+				{{printf "a = a<<%d | a>>(32-%d) + b" $s $s | relabel}}
+				{{rotate}}
+			{{end}}
+	
+			// Round 3.
+			{{range $i, $s := dup 4 .Shift3}}
+				{{index $.Table3 $i | printf "a += (b^c^d) + X[(5+3*%d)&15] + %d" $i | relabel}}
+				{{printf "a = a<<%d | a>>(32-%d) + b" $s $s | relabel}}
+				{{rotate}}
+			{{end}}
+	
+			// Round 4.
+			{{range $i, $s := dup 4 .Shift4}}
+				{{index $.Table4 $i | printf "a += (c^(b|^d)) + X[(7*%d)&15] + %d" $i | relabel}}
+				{{printf "a = a<<%d | a>>(32-%d) + b" $s $s | relabel}}
+				{{rotate}}
+			{{end}}
+		{{else}}
+			// Round 1.
+			for i := uint(0); i < 16; {
+				{{range $s := .Shift1}}
+					{{printf "a += (((c^d)&b)^d) + X[i&15] + t1[i&15]" | relabel}}
+					{{printf "a = a<<%d | a>>(32-%d) + b" $s $s | relabel}}
+					i++
+					{{rotate}}
+				{{end}}
+			}
+	
+			// Round 2.
+			for i := uint(0); i < 16; {
+				{{range $s := .Shift2}}
+					{{printf "a += (((b^c)&d)^c) + X[(1+5*i)&15] + t2[i&15]" | relabel}}
+					{{printf "a = a<<%d | a>>(32-%d) + b" $s $s | relabel}}
+					i++
+					{{rotate}}
+				{{end}}
+			}
+	
+			// Round 3.
+			for i := uint(0); i < 16; {
+				{{range $s := .Shift3}}
+					{{printf "a += (b^c^d) + X[(5+3*i)&15] + t3[i&15]" | relabel}}
+					{{printf "a = a<<%d | a>>(32-%d) + b" $s $s | relabel}}
+					i++
+					{{rotate}}
+				{{end}}
+			}
+	
+			// Round 4.
+			for i := uint(0); i < 16; {
+				{{range $s := .Shift4}}
+					{{printf "a += (c^(b|^d)) + X[(7*i)&15] + t4[i&15]" | relabel}}
+					{{printf "a = a<<%d | a>>(32-%d) + b" $s $s | relabel}}
+					i++
+					{{rotate}}
+				{{end}}
+			}
+		{{end}}
+
+		a += aa
+		b += bb
+		c += cc
+		d += dd
+
+		p = p[chunk:]
+	}
+
+	dig.s[0] = a
+	dig.s[1] = b
+	dig.s[2] = c
+	dig.s[3] = d
+}
+`
diff --git a/src/crypto/md5/md5.go b/src/crypto/md5/md5.go
new file mode 100644
index 0000000..8c50c6d
--- /dev/null
+++ b/src/crypto/md5/md5.go
@@ -0,0 +1,136 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:generate go run gen.go -full -output md5block.go
+
+// Package md5 implements the MD5 hash algorithm as defined in RFC 1321.
+package md5
+
+import (
+	"crypto"
+	"hash"
+)
+
+func init() {
+	crypto.RegisterHash(crypto.MD5, New)
+}
+
+// The size of an MD5 checksum in bytes.
+const Size = 16
+
+// The blocksize of MD5 in bytes.
+const BlockSize = 64
+
+const (
+	chunk = 64
+	init0 = 0x67452301
+	init1 = 0xEFCDAB89
+	init2 = 0x98BADCFE
+	init3 = 0x10325476
+)
+
+// digest represents the partial evaluation of a checksum.
+type digest struct {
+	s   [4]uint32
+	x   [chunk]byte
+	nx  int
+	len uint64
+}
+
+func (d *digest) Reset() {
+	d.s[0] = init0
+	d.s[1] = init1
+	d.s[2] = init2
+	d.s[3] = init3
+	d.nx = 0
+	d.len = 0
+}
+
+// New returns a new hash.Hash computing the MD5 checksum.
+func New() hash.Hash {
+	d := new(digest)
+	d.Reset()
+	return d
+}
+
+func (d *digest) Size() int { return Size }
+
+func (d *digest) BlockSize() int { return BlockSize }
+
+func (d *digest) Write(p []byte) (nn int, err error) {
+	nn = len(p)
+	d.len += uint64(nn)
+	if d.nx > 0 {
+		n := len(p)
+		if n > chunk-d.nx {
+			n = chunk - d.nx
+		}
+		for i := 0; i < n; i++ {
+			d.x[d.nx+i] = p[i]
+		}
+		d.nx += n
+		if d.nx == chunk {
+			block(d, d.x[0:chunk])
+			d.nx = 0
+		}
+		p = p[n:]
+	}
+	if len(p) >= chunk {
+		n := len(p) &^ (chunk - 1)
+		block(d, p[:n])
+		p = p[n:]
+	}
+	if len(p) > 0 {
+		d.nx = copy(d.x[:], p)
+	}
+	return
+}
+
+func (d0 *digest) Sum(in []byte) []byte {
+	// Make a copy of d0 so that caller can keep writing and summing.
+	d := *d0
+	hash := d.checkSum()
+	return append(in, hash[:]...)
+}
+
+func (d *digest) checkSum() [Size]byte {
+	// Padding.  Add a 1 bit and 0 bits until 56 bytes mod 64.
+	len := d.len
+	var tmp [64]byte
+	tmp[0] = 0x80
+	if len%64 < 56 {
+		d.Write(tmp[0 : 56-len%64])
+	} else {
+		d.Write(tmp[0 : 64+56-len%64])
+	}
+
+	// Length in bits.
+	len <<= 3
+	for i := uint(0); i < 8; i++ {
+		tmp[i] = byte(len >> (8 * i))
+	}
+	d.Write(tmp[0:8])
+
+	if d.nx != 0 {
+		panic("d.nx != 0")
+	}
+
+	var digest [Size]byte
+	for i, s := range d.s {
+		digest[i*4] = byte(s)
+		digest[i*4+1] = byte(s >> 8)
+		digest[i*4+2] = byte(s >> 16)
+		digest[i*4+3] = byte(s >> 24)
+	}
+
+	return digest
+}
+
+// Sum returns the MD5 checksum of the data.
+func Sum(data []byte) [Size]byte {
+	var d digest
+	d.Reset()
+	d.Write(data)
+	return d.checkSum()
+}
diff --git a/src/pkg/crypto/md5/md5_test.go b/src/crypto/md5/md5_test.go
similarity index 100%
rename from src/pkg/crypto/md5/md5_test.go
rename to src/crypto/md5/md5_test.go
diff --git a/src/crypto/md5/md5block.go b/src/crypto/md5/md5block.go
new file mode 100644
index 0000000..64e1e7c
--- /dev/null
+++ b/src/crypto/md5/md5block.go
@@ -0,0 +1,265 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// DO NOT EDIT.
+// Generate with: go run gen.go -full -output md5block.go
+
+package md5
+
+import (
+	"runtime"
+	"unsafe"
+)
+
+const x86 = runtime.GOARCH == "amd64" || runtime.GOARCH == "386"
+
+var littleEndian bool
+
+func init() {
+	x := uint32(0x04030201)
+	y := [4]byte{0x1, 0x2, 0x3, 0x4}
+	littleEndian = *(*[4]byte)(unsafe.Pointer(&x)) == y
+}
+
+func blockGeneric(dig *digest, p []byte) {
+	a := dig.s[0]
+	b := dig.s[1]
+	c := dig.s[2]
+	d := dig.s[3]
+	var X *[16]uint32
+	var xbuf [16]uint32
+	for len(p) >= chunk {
+		aa, bb, cc, dd := a, b, c, d
+
+		// This is a constant condition - it is not evaluated on each iteration.
+		if x86 {
+			// MD5 was designed so that x86 processors can just iterate
+			// over the block data directly as uint32s, and we generate
+			// less code and run 1.3x faster if we take advantage of that.
+			// My apologies.
+			X = (*[16]uint32)(unsafe.Pointer(&p[0]))
+		} else if littleEndian && uintptr(unsafe.Pointer(&p[0]))&(unsafe.Alignof(uint32(0))-1) == 0 {
+			X = (*[16]uint32)(unsafe.Pointer(&p[0]))
+		} else {
+			X = &xbuf
+			j := 0
+			for i := 0; i < 16; i++ {
+				X[i&15] = uint32(p[j]) | uint32(p[j+1])<<8 | uint32(p[j+2])<<16 | uint32(p[j+3])<<24
+				j += 4
+			}
+		}
+
+		// Round 1.
+
+		a += (((c ^ d) & b) ^ d) + X[0] + 3614090360
+		a = a<<7 | a>>(32-7) + b
+
+		d += (((b ^ c) & a) ^ c) + X[1] + 3905402710
+		d = d<<12 | d>>(32-12) + a
+
+		c += (((a ^ b) & d) ^ b) + X[2] + 606105819
+		c = c<<17 | c>>(32-17) + d
+
+		b += (((d ^ a) & c) ^ a) + X[3] + 3250441966
+		b = b<<22 | b>>(32-22) + c
+
+		a += (((c ^ d) & b) ^ d) + X[4] + 4118548399
+		a = a<<7 | a>>(32-7) + b
+
+		d += (((b ^ c) & a) ^ c) + X[5] + 1200080426
+		d = d<<12 | d>>(32-12) + a
+
+		c += (((a ^ b) & d) ^ b) + X[6] + 2821735955
+		c = c<<17 | c>>(32-17) + d
+
+		b += (((d ^ a) & c) ^ a) + X[7] + 4249261313
+		b = b<<22 | b>>(32-22) + c
+
+		a += (((c ^ d) & b) ^ d) + X[8] + 1770035416
+		a = a<<7 | a>>(32-7) + b
+
+		d += (((b ^ c) & a) ^ c) + X[9] + 2336552879
+		d = d<<12 | d>>(32-12) + a
+
+		c += (((a ^ b) & d) ^ b) + X[10] + 4294925233
+		c = c<<17 | c>>(32-17) + d
+
+		b += (((d ^ a) & c) ^ a) + X[11] + 2304563134
+		b = b<<22 | b>>(32-22) + c
+
+		a += (((c ^ d) & b) ^ d) + X[12] + 1804603682
+		a = a<<7 | a>>(32-7) + b
+
+		d += (((b ^ c) & a) ^ c) + X[13] + 4254626195
+		d = d<<12 | d>>(32-12) + a
+
+		c += (((a ^ b) & d) ^ b) + X[14] + 2792965006
+		c = c<<17 | c>>(32-17) + d
+
+		b += (((d ^ a) & c) ^ a) + X[15] + 1236535329
+		b = b<<22 | b>>(32-22) + c
+
+		// Round 2.
+
+		a += (((b ^ c) & d) ^ c) + X[(1+5*0)&15] + 4129170786
+		a = a<<5 | a>>(32-5) + b
+
+		d += (((a ^ b) & c) ^ b) + X[(1+5*1)&15] + 3225465664
+		d = d<<9 | d>>(32-9) + a
+
+		c += (((d ^ a) & b) ^ a) + X[(1+5*2)&15] + 643717713
+		c = c<<14 | c>>(32-14) + d
+
+		b += (((c ^ d) & a) ^ d) + X[(1+5*3)&15] + 3921069994
+		b = b<<20 | b>>(32-20) + c
+
+		a += (((b ^ c) & d) ^ c) + X[(1+5*4)&15] + 3593408605
+		a = a<<5 | a>>(32-5) + b
+
+		d += (((a ^ b) & c) ^ b) + X[(1+5*5)&15] + 38016083
+		d = d<<9 | d>>(32-9) + a
+
+		c += (((d ^ a) & b) ^ a) + X[(1+5*6)&15] + 3634488961
+		c = c<<14 | c>>(32-14) + d
+
+		b += (((c ^ d) & a) ^ d) + X[(1+5*7)&15] + 3889429448
+		b = b<<20 | b>>(32-20) + c
+
+		a += (((b ^ c) & d) ^ c) + X[(1+5*8)&15] + 568446438
+		a = a<<5 | a>>(32-5) + b
+
+		d += (((a ^ b) & c) ^ b) + X[(1+5*9)&15] + 3275163606
+		d = d<<9 | d>>(32-9) + a
+
+		c += (((d ^ a) & b) ^ a) + X[(1+5*10)&15] + 4107603335
+		c = c<<14 | c>>(32-14) + d
+
+		b += (((c ^ d) & a) ^ d) + X[(1+5*11)&15] + 1163531501
+		b = b<<20 | b>>(32-20) + c
+
+		a += (((b ^ c) & d) ^ c) + X[(1+5*12)&15] + 2850285829
+		a = a<<5 | a>>(32-5) + b
+
+		d += (((a ^ b) & c) ^ b) + X[(1+5*13)&15] + 4243563512
+		d = d<<9 | d>>(32-9) + a
+
+		c += (((d ^ a) & b) ^ a) + X[(1+5*14)&15] + 1735328473
+		c = c<<14 | c>>(32-14) + d
+
+		b += (((c ^ d) & a) ^ d) + X[(1+5*15)&15] + 2368359562
+		b = b<<20 | b>>(32-20) + c
+
+		// Round 3.
+
+		a += (b ^ c ^ d) + X[(5+3*0)&15] + 4294588738
+		a = a<<4 | a>>(32-4) + b
+
+		d += (a ^ b ^ c) + X[(5+3*1)&15] + 2272392833
+		d = d<<11 | d>>(32-11) + a
+
+		c += (d ^ a ^ b) + X[(5+3*2)&15] + 1839030562
+		c = c<<16 | c>>(32-16) + d
+
+		b += (c ^ d ^ a) + X[(5+3*3)&15] + 4259657740
+		b = b<<23 | b>>(32-23) + c
+
+		a += (b ^ c ^ d) + X[(5+3*4)&15] + 2763975236
+		a = a<<4 | a>>(32-4) + b
+
+		d += (a ^ b ^ c) + X[(5+3*5)&15] + 1272893353
+		d = d<<11 | d>>(32-11) + a
+
+		c += (d ^ a ^ b) + X[(5+3*6)&15] + 4139469664
+		c = c<<16 | c>>(32-16) + d
+
+		b += (c ^ d ^ a) + X[(5+3*7)&15] + 3200236656
+		b = b<<23 | b>>(32-23) + c
+
+		a += (b ^ c ^ d) + X[(5+3*8)&15] + 681279174
+		a = a<<4 | a>>(32-4) + b
+
+		d += (a ^ b ^ c) + X[(5+3*9)&15] + 3936430074
+		d = d<<11 | d>>(32-11) + a
+
+		c += (d ^ a ^ b) + X[(5+3*10)&15] + 3572445317
+		c = c<<16 | c>>(32-16) + d
+
+		b += (c ^ d ^ a) + X[(5+3*11)&15] + 76029189
+		b = b<<23 | b>>(32-23) + c
+
+		a += (b ^ c ^ d) + X[(5+3*12)&15] + 3654602809
+		a = a<<4 | a>>(32-4) + b
+
+		d += (a ^ b ^ c) + X[(5+3*13)&15] + 3873151461
+		d = d<<11 | d>>(32-11) + a
+
+		c += (d ^ a ^ b) + X[(5+3*14)&15] + 530742520
+		c = c<<16 | c>>(32-16) + d
+
+		b += (c ^ d ^ a) + X[(5+3*15)&15] + 3299628645
+		b = b<<23 | b>>(32-23) + c
+
+		// Round 4.
+
+		a += (c ^ (b | ^d)) + X[(7*0)&15] + 4096336452
+		a = a<<6 | a>>(32-6) + b
+
+		d += (b ^ (a | ^c)) + X[(7*1)&15] + 1126891415
+		d = d<<10 | d>>(32-10) + a
+
+		c += (a ^ (d | ^b)) + X[(7*2)&15] + 2878612391
+		c = c<<15 | c>>(32-15) + d
+
+		b += (d ^ (c | ^a)) + X[(7*3)&15] + 4237533241
+		b = b<<21 | b>>(32-21) + c
+
+		a += (c ^ (b | ^d)) + X[(7*4)&15] + 1700485571
+		a = a<<6 | a>>(32-6) + b
+
+		d += (b ^ (a | ^c)) + X[(7*5)&15] + 2399980690
+		d = d<<10 | d>>(32-10) + a
+
+		c += (a ^ (d | ^b)) + X[(7*6)&15] + 4293915773
+		c = c<<15 | c>>(32-15) + d
+
+		b += (d ^ (c | ^a)) + X[(7*7)&15] + 2240044497
+		b = b<<21 | b>>(32-21) + c
+
+		a += (c ^ (b | ^d)) + X[(7*8)&15] + 1873313359
+		a = a<<6 | a>>(32-6) + b
+
+		d += (b ^ (a | ^c)) + X[(7*9)&15] + 4264355552
+		d = d<<10 | d>>(32-10) + a
+
+		c += (a ^ (d | ^b)) + X[(7*10)&15] + 2734768916
+		c = c<<15 | c>>(32-15) + d
+
+		b += (d ^ (c | ^a)) + X[(7*11)&15] + 1309151649
+		b = b<<21 | b>>(32-21) + c
+
+		a += (c ^ (b | ^d)) + X[(7*12)&15] + 4149444226
+		a = a<<6 | a>>(32-6) + b
+
+		d += (b ^ (a | ^c)) + X[(7*13)&15] + 3174756917
+		d = d<<10 | d>>(32-10) + a
+
+		c += (a ^ (d | ^b)) + X[(7*14)&15] + 718787259
+		c = c<<15 | c>>(32-15) + d
+
+		b += (d ^ (c | ^a)) + X[(7*15)&15] + 3951481745
+		b = b<<21 | b>>(32-21) + c
+
+		a += aa
+		b += bb
+		c += cc
+		d += dd
+
+		p = p[chunk:]
+	}
+
+	dig.s[0] = a
+	dig.s[1] = b
+	dig.s[2] = c
+	dig.s[3] = d
+}
diff --git a/src/crypto/md5/md5block_386.s b/src/crypto/md5/md5block_386.s
new file mode 100644
index 0000000..8e426d1
--- /dev/null
+++ b/src/crypto/md5/md5block_386.s
@@ -0,0 +1,182 @@
+// Original source:
+//	http://www.zorinaq.com/papers/md5-amd64.html
+//	http://www.zorinaq.com/papers/md5-amd64.tar.bz2
+//
+// Translated from Perl generating GNU assembly into
+// #defines generating 8a assembly, and adjusted for 386,
+// by the Go Authors.
+
+#include "textflag.h"
+
+// MD5 optimized for AMD64.
+//
+// Author: Marc Bevand <bevand_m (at) epita.fr>
+// Licence: I hereby disclaim the copyright on this code and place it
+// in the public domain.
+
+#define ROUND1(a, b, c, d, index, const, shift) \
+	XORL	c, BP; \
+	LEAL	const(a)(DI*1), a; \
+	ANDL	b, BP; \
+	XORL d, BP; \
+	MOVL (index*4)(SI), DI; \
+	ADDL BP, a; \
+	ROLL $shift, a; \
+	MOVL c, BP; \
+	ADDL b, a
+
+#define ROUND2(a, b, c, d, index, const, shift) \
+	LEAL	const(a)(DI*1),a; \
+	MOVL	d,		DI; \
+	ANDL	b,		DI; \
+	MOVL	d,		BP; \
+	NOTL	BP; \
+	ANDL	c,		BP; \
+	ORL	DI,		BP; \
+	MOVL	(index*4)(SI),DI; \
+	ADDL	BP,		a; \
+	ROLL	$shift,	a; \
+	ADDL	b,		a
+
+#define ROUND3(a, b, c, d, index, const, shift) \
+	LEAL	const(a)(DI*1),a; \
+	MOVL	(index*4)(SI),DI; \
+	XORL	d,		BP; \
+	XORL	b,		BP; \
+	ADDL	BP,		a; \
+	ROLL	$shift,		a; \
+	MOVL	b,		BP; \
+	ADDL	b,		a
+
+#define ROUND4(a, b, c, d, index, const, shift) \
+	LEAL	const(a)(DI*1),a; \
+	ORL	b,		BP; \
+	XORL	c,		BP; \
+	ADDL	BP,		a; \
+	MOVL	(index*4)(SI),DI; \
+	MOVL	$0xffffffff,	BP; \
+	ROLL	$shift,		a; \
+	XORL	c,		BP; \
+	ADDL	b,		a
+
+TEXT	·block(SB),NOSPLIT,$24-16
+	MOVL	dig+0(FP),	BP
+	MOVL	p+4(FP),	SI
+	MOVL	p_len+8(FP), DX
+	SHRL	$6,		DX
+	SHLL	$6,		DX
+
+	LEAL	(SI)(DX*1),	DI
+	MOVL	(0*4)(BP),	AX
+	MOVL	(1*4)(BP),	BX
+	MOVL	(2*4)(BP),	CX
+	MOVL	(3*4)(BP),	DX
+
+	CMPL	SI,		DI
+	JEQ	end
+
+	MOVL	DI,		16(SP)
+
+loop:
+	MOVL	AX,		0(SP)
+	MOVL	BX,		4(SP)
+	MOVL	CX,		8(SP)
+	MOVL	DX,		12(SP)
+
+	MOVL	(0*4)(SI),	DI
+	MOVL	DX,		BP
+
+	ROUND1(AX,BX,CX,DX, 1,0xd76aa478, 7);
+	ROUND1(DX,AX,BX,CX, 2,0xe8c7b756,12);
+	ROUND1(CX,DX,AX,BX, 3,0x242070db,17);
+	ROUND1(BX,CX,DX,AX, 4,0xc1bdceee,22);
+	ROUND1(AX,BX,CX,DX, 5,0xf57c0faf, 7);
+	ROUND1(DX,AX,BX,CX, 6,0x4787c62a,12);
+	ROUND1(CX,DX,AX,BX, 7,0xa8304613,17);
+	ROUND1(BX,CX,DX,AX, 8,0xfd469501,22);
+	ROUND1(AX,BX,CX,DX, 9,0x698098d8, 7);
+	ROUND1(DX,AX,BX,CX,10,0x8b44f7af,12);
+	ROUND1(CX,DX,AX,BX,11,0xffff5bb1,17);
+	ROUND1(BX,CX,DX,AX,12,0x895cd7be,22);
+	ROUND1(AX,BX,CX,DX,13,0x6b901122, 7);
+	ROUND1(DX,AX,BX,CX,14,0xfd987193,12);
+	ROUND1(CX,DX,AX,BX,15,0xa679438e,17);
+	ROUND1(BX,CX,DX,AX, 0,0x49b40821,22);
+
+	MOVL	(1*4)(SI),	DI
+	MOVL	DX,		BP
+
+	ROUND2(AX,BX,CX,DX, 6,0xf61e2562, 5);
+	ROUND2(DX,AX,BX,CX,11,0xc040b340, 9);
+	ROUND2(CX,DX,AX,BX, 0,0x265e5a51,14);
+	ROUND2(BX,CX,DX,AX, 5,0xe9b6c7aa,20);
+	ROUND2(AX,BX,CX,DX,10,0xd62f105d, 5);
+	ROUND2(DX,AX,BX,CX,15, 0x2441453, 9);
+	ROUND2(CX,DX,AX,BX, 4,0xd8a1e681,14);
+	ROUND2(BX,CX,DX,AX, 9,0xe7d3fbc8,20);
+	ROUND2(AX,BX,CX,DX,14,0x21e1cde6, 5);
+	ROUND2(DX,AX,BX,CX, 3,0xc33707d6, 9);
+	ROUND2(CX,DX,AX,BX, 8,0xf4d50d87,14);
+	ROUND2(BX,CX,DX,AX,13,0x455a14ed,20);
+	ROUND2(AX,BX,CX,DX, 2,0xa9e3e905, 5);
+	ROUND2(DX,AX,BX,CX, 7,0xfcefa3f8, 9);
+	ROUND2(CX,DX,AX,BX,12,0x676f02d9,14);
+	ROUND2(BX,CX,DX,AX, 0,0x8d2a4c8a,20);
+ 
+	MOVL	(5*4)(SI),	DI
+	MOVL	CX,		BP
+
+	ROUND3(AX,BX,CX,DX, 8,0xfffa3942, 4);
+	ROUND3(DX,AX,BX,CX,11,0x8771f681,11);
+	ROUND3(CX,DX,AX,BX,14,0x6d9d6122,16);
+	ROUND3(BX,CX,DX,AX, 1,0xfde5380c,23);
+	ROUND3(AX,BX,CX,DX, 4,0xa4beea44, 4);
+	ROUND3(DX,AX,BX,CX, 7,0x4bdecfa9,11);
+	ROUND3(CX,DX,AX,BX,10,0xf6bb4b60,16);
+	ROUND3(BX,CX,DX,AX,13,0xbebfbc70,23);
+	ROUND3(AX,BX,CX,DX, 0,0x289b7ec6, 4);
+	ROUND3(DX,AX,BX,CX, 3,0xeaa127fa,11);
+	ROUND3(CX,DX,AX,BX, 6,0xd4ef3085,16);
+	ROUND3(BX,CX,DX,AX, 9, 0x4881d05,23);
+	ROUND3(AX,BX,CX,DX,12,0xd9d4d039, 4);
+	ROUND3(DX,AX,BX,CX,15,0xe6db99e5,11);
+	ROUND3(CX,DX,AX,BX, 2,0x1fa27cf8,16);
+	ROUND3(BX,CX,DX,AX, 0,0xc4ac5665,23);
+
+	MOVL	(0*4)(SI),	DI
+	MOVL	$0xffffffff,	BP
+	XORL	DX,		BP
+
+	ROUND4(AX,BX,CX,DX, 7,0xf4292244, 6);
+	ROUND4(DX,AX,BX,CX,14,0x432aff97,10);
+	ROUND4(CX,DX,AX,BX, 5,0xab9423a7,15);
+	ROUND4(BX,CX,DX,AX,12,0xfc93a039,21);
+	ROUND4(AX,BX,CX,DX, 3,0x655b59c3, 6);
+	ROUND4(DX,AX,BX,CX,10,0x8f0ccc92,10);
+	ROUND4(CX,DX,AX,BX, 1,0xffeff47d,15);
+	ROUND4(BX,CX,DX,AX, 8,0x85845dd1,21);
+	ROUND4(AX,BX,CX,DX,15,0x6fa87e4f, 6);
+	ROUND4(DX,AX,BX,CX, 6,0xfe2ce6e0,10);
+	ROUND4(CX,DX,AX,BX,13,0xa3014314,15);
+	ROUND4(BX,CX,DX,AX, 4,0x4e0811a1,21);
+	ROUND4(AX,BX,CX,DX,11,0xf7537e82, 6);
+	ROUND4(DX,AX,BX,CX, 2,0xbd3af235,10);
+	ROUND4(CX,DX,AX,BX, 9,0x2ad7d2bb,15);
+	ROUND4(BX,CX,DX,AX, 0,0xeb86d391,21);
+
+	ADDL	0(SP),	AX
+	ADDL	4(SP),	BX
+	ADDL	8(SP),	CX
+	ADDL	12(SP),	DX
+
+	ADDL	$64,		SI
+	CMPL	SI,		16(SP)
+	JB	loop
+
+end:
+	MOVL	dig+0(FP),	BP
+	MOVL	AX,		(0*4)(BP)
+	MOVL	BX,		(1*4)(BP)
+	MOVL	CX,		(2*4)(BP)
+	MOVL	DX,		(3*4)(BP)
+	RET
diff --git a/src/crypto/md5/md5block_amd64.s b/src/crypto/md5/md5block_amd64.s
new file mode 100644
index 0000000..a3ae7d9
--- /dev/null
+++ b/src/crypto/md5/md5block_amd64.s
@@ -0,0 +1,179 @@
+// Original source:
+//	http://www.zorinaq.com/papers/md5-amd64.html
+//	http://www.zorinaq.com/papers/md5-amd64.tar.bz2
+//
+// Translated from Perl generating GNU assembly into
+// #defines generating 6a assembly by the Go Authors.
+
+#include "textflag.h"
+
+// MD5 optimized for AMD64.
+//
+// Author: Marc Bevand <bevand_m (at) epita.fr>
+// Licence: I hereby disclaim the copyright on this code and place it
+// in the public domain.
+
+TEXT	·block(SB),NOSPLIT,$0-32
+	MOVQ	dig+0(FP),	BP
+	MOVQ	p+8(FP),	SI
+	MOVQ	p_len+16(FP), DX
+	SHRQ	$6,		DX
+	SHLQ	$6,		DX
+
+	LEAQ	(SI)(DX*1),	DI
+	MOVL	(0*4)(BP),	AX
+	MOVL	(1*4)(BP),	BX
+	MOVL	(2*4)(BP),	CX
+	MOVL	(3*4)(BP),	DX
+
+	CMPQ	SI,		DI
+	JEQ	end
+
+loop:
+	MOVL	AX,		R12
+	MOVL	BX,		R13
+	MOVL	CX,		R14
+	MOVL	DX,		R15
+
+	MOVL	(0*4)(SI),	R8
+	MOVL	DX,		R9
+
+#define ROUND1(a, b, c, d, index, const, shift) \
+	XORL	c, R9; \
+	LEAL	const(a)(R8*1), a; \
+	ANDL	b, R9; \
+	XORL d, R9; \
+	MOVL (index*4)(SI), R8; \
+	ADDL R9, a; \
+	ROLL $shift, a; \
+	MOVL c, R9; \
+	ADDL b, a
+
+	ROUND1(AX,BX,CX,DX, 1,0xd76aa478, 7);
+	ROUND1(DX,AX,BX,CX, 2,0xe8c7b756,12);
+	ROUND1(CX,DX,AX,BX, 3,0x242070db,17);
+	ROUND1(BX,CX,DX,AX, 4,0xc1bdceee,22);
+	ROUND1(AX,BX,CX,DX, 5,0xf57c0faf, 7);
+	ROUND1(DX,AX,BX,CX, 6,0x4787c62a,12);
+	ROUND1(CX,DX,AX,BX, 7,0xa8304613,17);
+	ROUND1(BX,CX,DX,AX, 8,0xfd469501,22);
+	ROUND1(AX,BX,CX,DX, 9,0x698098d8, 7);
+	ROUND1(DX,AX,BX,CX,10,0x8b44f7af,12);
+	ROUND1(CX,DX,AX,BX,11,0xffff5bb1,17);
+	ROUND1(BX,CX,DX,AX,12,0x895cd7be,22);
+	ROUND1(AX,BX,CX,DX,13,0x6b901122, 7);
+	ROUND1(DX,AX,BX,CX,14,0xfd987193,12);
+	ROUND1(CX,DX,AX,BX,15,0xa679438e,17);
+	ROUND1(BX,CX,DX,AX, 0,0x49b40821,22);
+
+	MOVL	(1*4)(SI),	R8
+	MOVL	DX,		R9
+	MOVL	DX,		R10
+
+#define ROUND2(a, b, c, d, index, const, shift) \
+	NOTL	R9; \
+	LEAL	const(a)(R8*1),a; \
+	ANDL	b,		R10; \
+	ANDL	c,		R9; \
+	MOVL	(index*4)(SI),R8; \
+	ORL	R9,		R10; \
+	MOVL	c,		R9; \
+	ADDL	R10,		a; \
+	MOVL	c,		R10; \
+	ROLL	$shift,	a; \
+	ADDL	b,		a
+
+	ROUND2(AX,BX,CX,DX, 6,0xf61e2562, 5);
+	ROUND2(DX,AX,BX,CX,11,0xc040b340, 9);
+	ROUND2(CX,DX,AX,BX, 0,0x265e5a51,14);
+	ROUND2(BX,CX,DX,AX, 5,0xe9b6c7aa,20);
+	ROUND2(AX,BX,CX,DX,10,0xd62f105d, 5);
+	ROUND2(DX,AX,BX,CX,15, 0x2441453, 9);
+	ROUND2(CX,DX,AX,BX, 4,0xd8a1e681,14);
+	ROUND2(BX,CX,DX,AX, 9,0xe7d3fbc8,20);
+	ROUND2(AX,BX,CX,DX,14,0x21e1cde6, 5);
+	ROUND2(DX,AX,BX,CX, 3,0xc33707d6, 9);
+	ROUND2(CX,DX,AX,BX, 8,0xf4d50d87,14);
+	ROUND2(BX,CX,DX,AX,13,0x455a14ed,20);
+	ROUND2(AX,BX,CX,DX, 2,0xa9e3e905, 5);
+	ROUND2(DX,AX,BX,CX, 7,0xfcefa3f8, 9);
+	ROUND2(CX,DX,AX,BX,12,0x676f02d9,14);
+	ROUND2(BX,CX,DX,AX, 0,0x8d2a4c8a,20);
+ 
+	MOVL	(5*4)(SI),	R8
+	MOVL	CX,		R9
+
+#define ROUND3(a, b, c, d, index, const, shift) \
+	LEAL	const(a)(R8*1),a; \
+	MOVL	(index*4)(SI),R8; \
+	XORL	d,		R9; \
+	XORL	b,		R9; \
+	ADDL	R9,		a; \
+	ROLL	$shift,		a; \
+	MOVL	b,		R9; \
+	ADDL	b,		a
+
+	ROUND3(AX,BX,CX,DX, 8,0xfffa3942, 4);
+	ROUND3(DX,AX,BX,CX,11,0x8771f681,11);
+	ROUND3(CX,DX,AX,BX,14,0x6d9d6122,16);
+	ROUND3(BX,CX,DX,AX, 1,0xfde5380c,23);
+	ROUND3(AX,BX,CX,DX, 4,0xa4beea44, 4);
+	ROUND3(DX,AX,BX,CX, 7,0x4bdecfa9,11);
+	ROUND3(CX,DX,AX,BX,10,0xf6bb4b60,16);
+	ROUND3(BX,CX,DX,AX,13,0xbebfbc70,23);
+	ROUND3(AX,BX,CX,DX, 0,0x289b7ec6, 4);
+	ROUND3(DX,AX,BX,CX, 3,0xeaa127fa,11);
+	ROUND3(CX,DX,AX,BX, 6,0xd4ef3085,16);
+	ROUND3(BX,CX,DX,AX, 9, 0x4881d05,23);
+	ROUND3(AX,BX,CX,DX,12,0xd9d4d039, 4);
+	ROUND3(DX,AX,BX,CX,15,0xe6db99e5,11);
+	ROUND3(CX,DX,AX,BX, 2,0x1fa27cf8,16);
+	ROUND3(BX,CX,DX,AX, 0,0xc4ac5665,23);
+
+	MOVL	(0*4)(SI),	R8
+	MOVL	$0xffffffff,	R9
+	XORL	DX,		R9
+
+#define ROUND4(a, b, c, d, index, const, shift) \
+	LEAL	const(a)(R8*1),a; \
+	ORL	b,		R9; \
+	XORL	c,		R9; \
+	ADDL	R9,		a; \
+	MOVL	(index*4)(SI),R8; \
+	MOVL	$0xffffffff,	R9; \
+	ROLL	$shift,		a; \
+	XORL	c,		R9; \
+	ADDL	b,		a
+	
+	ROUND4(AX,BX,CX,DX, 7,0xf4292244, 6);
+	ROUND4(DX,AX,BX,CX,14,0x432aff97,10);
+	ROUND4(CX,DX,AX,BX, 5,0xab9423a7,15);
+	ROUND4(BX,CX,DX,AX,12,0xfc93a039,21);
+	ROUND4(AX,BX,CX,DX, 3,0x655b59c3, 6);
+	ROUND4(DX,AX,BX,CX,10,0x8f0ccc92,10);
+	ROUND4(CX,DX,AX,BX, 1,0xffeff47d,15);
+	ROUND4(BX,CX,DX,AX, 8,0x85845dd1,21);
+	ROUND4(AX,BX,CX,DX,15,0x6fa87e4f, 6);
+	ROUND4(DX,AX,BX,CX, 6,0xfe2ce6e0,10);
+	ROUND4(CX,DX,AX,BX,13,0xa3014314,15);
+	ROUND4(BX,CX,DX,AX, 4,0x4e0811a1,21);
+	ROUND4(AX,BX,CX,DX,11,0xf7537e82, 6);
+	ROUND4(DX,AX,BX,CX, 2,0xbd3af235,10);
+	ROUND4(CX,DX,AX,BX, 9,0x2ad7d2bb,15);
+	ROUND4(BX,CX,DX,AX, 0,0xeb86d391,21);
+
+	ADDL	R12,	AX
+	ADDL	R13,	BX
+	ADDL	R14,	CX
+	ADDL	R15,	DX
+
+	ADDQ	$64,		SI
+	CMPQ	SI,		DI
+	JB	loop
+
+end:
+	MOVL	AX,		(0*4)(BP)
+	MOVL	BX,		(1*4)(BP)
+	MOVL	CX,		(2*4)(BP)
+	MOVL	DX,		(3*4)(BP)
+	RET
diff --git a/src/crypto/md5/md5block_amd64p32.s b/src/crypto/md5/md5block_amd64p32.s
new file mode 100644
index 0000000..d918a67
--- /dev/null
+++ b/src/crypto/md5/md5block_amd64p32.s
@@ -0,0 +1,184 @@
+// Original source:
+//	http://www.zorinaq.com/papers/md5-amd64.html
+//	http://www.zorinaq.com/papers/md5-amd64.tar.bz2
+//
+// Translated from Perl generating GNU assembly into
+// #defines generating 6a assembly by the Go Authors.
+//
+// Restrictions to make code safe for Native Client:
+// replace BP with R11, reloaded before use at return.
+// replace R15 with R11.
+
+#include "textflag.h"
+
+// MD5 optimized for AMD64.
+//
+// Author: Marc Bevand <bevand_m (at) epita.fr>
+// Licence: I hereby disclaim the copyright on this code and place it
+// in the public domain.
+
+TEXT	·block(SB),NOSPLIT,$0-32
+	MOVL	dig+0(FP),	R11
+	MOVL	p+4(FP),	SI
+	MOVL	p_len+8(FP), DX
+	SHRQ	$6,		DX
+	SHLQ	$6,		DX
+
+	LEAQ	(SI)(DX*1),	DI
+	MOVL	(0*4)(R11),	AX
+	MOVL	(1*4)(R11),	BX
+	MOVL	(2*4)(R11),	CX
+	MOVL	(3*4)(R11),	DX
+
+	CMPQ	SI,		DI
+	JEQ	end
+
+loop:
+	MOVL	AX,		R12
+	MOVL	BX,		R13
+	MOVL	CX,		R14
+	MOVL	DX,		R11
+
+	MOVL	(0*4)(SI),	R8
+	MOVL	DX,		R9
+
+#define ROUND1(a, b, c, d, index, const, shift) \
+	XORL	c, R9; \
+	LEAL	const(a)(R8*1), a; \
+	ANDL	b, R9; \
+	XORL d, R9; \
+	MOVL (index*4)(SI), R8; \
+	ADDL R9, a; \
+	ROLL $shift, a; \
+	MOVL c, R9; \
+	ADDL b, a
+
+	ROUND1(AX,BX,CX,DX, 1,0xd76aa478, 7);
+	ROUND1(DX,AX,BX,CX, 2,0xe8c7b756,12);
+	ROUND1(CX,DX,AX,BX, 3,0x242070db,17);
+	ROUND1(BX,CX,DX,AX, 4,0xc1bdceee,22);
+	ROUND1(AX,BX,CX,DX, 5,0xf57c0faf, 7);
+	ROUND1(DX,AX,BX,CX, 6,0x4787c62a,12);
+	ROUND1(CX,DX,AX,BX, 7,0xa8304613,17);
+	ROUND1(BX,CX,DX,AX, 8,0xfd469501,22);
+	ROUND1(AX,BX,CX,DX, 9,0x698098d8, 7);
+	ROUND1(DX,AX,BX,CX,10,0x8b44f7af,12);
+	ROUND1(CX,DX,AX,BX,11,0xffff5bb1,17);
+	ROUND1(BX,CX,DX,AX,12,0x895cd7be,22);
+	ROUND1(AX,BX,CX,DX,13,0x6b901122, 7);
+	ROUND1(DX,AX,BX,CX,14,0xfd987193,12);
+	ROUND1(CX,DX,AX,BX,15,0xa679438e,17);
+	ROUND1(BX,CX,DX,AX, 0,0x49b40821,22);
+
+	MOVL	(1*4)(SI),	R8
+	MOVL	DX,		R9
+	MOVL	DX,		R10
+
+#define ROUND2(a, b, c, d, index, const, shift) \
+	NOTL	R9; \
+	LEAL	const(a)(R8*1),a; \
+	ANDL	b,		R10; \
+	ANDL	c,		R9; \
+	MOVL	(index*4)(SI),R8; \
+	ORL	R9,		R10; \
+	MOVL	c,		R9; \
+	ADDL	R10,		a; \
+	MOVL	c,		R10; \
+	ROLL	$shift,	a; \
+	ADDL	b,		a
+
+	ROUND2(AX,BX,CX,DX, 6,0xf61e2562, 5);
+	ROUND2(DX,AX,BX,CX,11,0xc040b340, 9);
+	ROUND2(CX,DX,AX,BX, 0,0x265e5a51,14);
+	ROUND2(BX,CX,DX,AX, 5,0xe9b6c7aa,20);
+	ROUND2(AX,BX,CX,DX,10,0xd62f105d, 5);
+	ROUND2(DX,AX,BX,CX,15, 0x2441453, 9);
+	ROUND2(CX,DX,AX,BX, 4,0xd8a1e681,14);
+	ROUND2(BX,CX,DX,AX, 9,0xe7d3fbc8,20);
+	ROUND2(AX,BX,CX,DX,14,0x21e1cde6, 5);
+	ROUND2(DX,AX,BX,CX, 3,0xc33707d6, 9);
+	ROUND2(CX,DX,AX,BX, 8,0xf4d50d87,14);
+	ROUND2(BX,CX,DX,AX,13,0x455a14ed,20);
+	ROUND2(AX,BX,CX,DX, 2,0xa9e3e905, 5);
+	ROUND2(DX,AX,BX,CX, 7,0xfcefa3f8, 9);
+	ROUND2(CX,DX,AX,BX,12,0x676f02d9,14);
+	ROUND2(BX,CX,DX,AX, 0,0x8d2a4c8a,20);
+ 
+	MOVL	(5*4)(SI),	R8
+	MOVL	CX,		R9
+
+#define ROUND3(a, b, c, d, index, const, shift) \
+	LEAL	const(a)(R8*1),a; \
+	MOVL	(index*4)(SI),R8; \
+	XORL	d,		R9; \
+	XORL	b,		R9; \
+	ADDL	R9,		a; \
+	ROLL	$shift,		a; \
+	MOVL	b,		R9; \
+	ADDL	b,		a
+
+	ROUND3(AX,BX,CX,DX, 8,0xfffa3942, 4);
+	ROUND3(DX,AX,BX,CX,11,0x8771f681,11);
+	ROUND3(CX,DX,AX,BX,14,0x6d9d6122,16);
+	ROUND3(BX,CX,DX,AX, 1,0xfde5380c,23);
+	ROUND3(AX,BX,CX,DX, 4,0xa4beea44, 4);
+	ROUND3(DX,AX,BX,CX, 7,0x4bdecfa9,11);
+	ROUND3(CX,DX,AX,BX,10,0xf6bb4b60,16);
+	ROUND3(BX,CX,DX,AX,13,0xbebfbc70,23);
+	ROUND3(AX,BX,CX,DX, 0,0x289b7ec6, 4);
+	ROUND3(DX,AX,BX,CX, 3,0xeaa127fa,11);
+	ROUND3(CX,DX,AX,BX, 6,0xd4ef3085,16);
+	ROUND3(BX,CX,DX,AX, 9, 0x4881d05,23);
+	ROUND3(AX,BX,CX,DX,12,0xd9d4d039, 4);
+	ROUND3(DX,AX,BX,CX,15,0xe6db99e5,11);
+	ROUND3(CX,DX,AX,BX, 2,0x1fa27cf8,16);
+	ROUND3(BX,CX,DX,AX, 0,0xc4ac5665,23);
+
+	MOVL	(0*4)(SI),	R8
+	MOVL	$0xffffffff,	R9
+	XORL	DX,		R9
+
+#define ROUND4(a, b, c, d, index, const, shift) \
+	LEAL	const(a)(R8*1),a; \
+	ORL	b,		R9; \
+	XORL	c,		R9; \
+	ADDL	R9,		a; \
+	MOVL	(index*4)(SI),R8; \
+	MOVL	$0xffffffff,	R9; \
+	ROLL	$shift,		a; \
+	XORL	c,		R9; \
+	ADDL	b,		a
+	
+	ROUND4(AX,BX,CX,DX, 7,0xf4292244, 6);
+	ROUND4(DX,AX,BX,CX,14,0x432aff97,10);
+	ROUND4(CX,DX,AX,BX, 5,0xab9423a7,15);
+	ROUND4(BX,CX,DX,AX,12,0xfc93a039,21);
+	ROUND4(AX,BX,CX,DX, 3,0x655b59c3, 6);
+	ROUND4(DX,AX,BX,CX,10,0x8f0ccc92,10);
+	ROUND4(CX,DX,AX,BX, 1,0xffeff47d,15);
+	ROUND4(BX,CX,DX,AX, 8,0x85845dd1,21);
+	ROUND4(AX,BX,CX,DX,15,0x6fa87e4f, 6);
+	ROUND4(DX,AX,BX,CX, 6,0xfe2ce6e0,10);
+	ROUND4(CX,DX,AX,BX,13,0xa3014314,15);
+	ROUND4(BX,CX,DX,AX, 4,0x4e0811a1,21);
+	ROUND4(AX,BX,CX,DX,11,0xf7537e82, 6);
+	ROUND4(DX,AX,BX,CX, 2,0xbd3af235,10);
+	ROUND4(CX,DX,AX,BX, 9,0x2ad7d2bb,15);
+	ROUND4(BX,CX,DX,AX, 0,0xeb86d391,21);
+
+	ADDL	R12,	AX
+	ADDL	R13,	BX
+	ADDL	R14,	CX
+	ADDL	R11,	DX
+
+	ADDQ	$64,		SI
+	CMPQ	SI,		DI
+	JB	loop
+
+end:
+	MOVL	dig+0(FP),	R11
+	MOVL	AX,		(0*4)(R11)
+	MOVL	BX,		(1*4)(R11)
+	MOVL	CX,		(2*4)(R11)
+	MOVL	DX,		(3*4)(R11)
+	RET
diff --git a/src/crypto/md5/md5block_arm.s b/src/crypto/md5/md5block_arm.s
new file mode 100644
index 0000000..3b26e54
--- /dev/null
+++ b/src/crypto/md5/md5block_arm.s
@@ -0,0 +1,299 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+//
+// ARM version of md5block.go
+
+#include "textflag.h"
+
+// Register definitions
+table = 0	// Pointer to MD5 constants table
+data = 1	// Pointer to data to hash
+a = 2		// MD5 accumulator
+b = 3		// MD5 accumulator
+c = 4		// MD5 accumulator
+d = 5		// MD5 accumulator
+c0 = 6		// MD5 constant
+c1 = 7		// MD5 constant
+c2 = 8		// MD5 constant
+// r9, r10 are forbidden
+// r11 is OK provided you check the assembler that no synthetic instructions use it
+c3 = 11		// MD5 constant
+t0 = 12		// temporary
+t1 = 14		// temporary
+
+// func block(dig *digest, p []byte)
+// 0(FP) is *digest
+// 4(FP) is p.array (struct Slice)
+// 8(FP) is p.len
+//12(FP) is p.cap
+//
+// Stack frame
+p_end = -4	// -4(SP) pointer to the end of data
+p_data = -8	// -8(SP) current data pointer
+buf = -8-4*16	//-72(SP) 16 words temporary buffer
+		// 3 words at 4..12(R13) for called routine parameters
+
+TEXT	·block(SB), NOSPLIT, $84-16
+	MOVW	p+4(FP), R(data)	// pointer to the data
+	MOVW	p_len+8(FP), R(t0)	// number of bytes
+	ADD	R(data), R(t0)
+	MOVW	R(t0), p_end(SP)	// pointer to end of data
+
+loop:
+	MOVW	R(data), p_data(SP)	// Save R(data)
+	AND.S	$3, R(data), R(t0)	// TST $3, R(data) not working see issue 5921
+	BEQ	aligned			// aligned detected - skip copy
+
+	// Copy the unaligned source data into the aligned temporary buffer
+	// memove(to=4(R13), from=8(R13), n=12(R13)) - Corrupts all registers
+	MOVW	$buf(SP), R(table)	// to
+	MOVW	$64, R(c0)		// n
+	MOVM.IB	[R(table),R(data),R(c0)], (R13)
+	BL	runtime·memmove(SB)
+
+	// Point to the local aligned copy of the data
+	MOVW	$buf(SP), R(data)
+
+aligned:
+	// Point to the table of constants
+	// A PC relative add would be cheaper than this
+	MOVW	$·table(SB), R(table)
+
+	// Load up initial MD5 accumulator
+	MOVW	dig+0(FP), R(c0)
+	MOVM.IA (R(c0)), [R(a),R(b),R(c),R(d)]
+
+// a += (((c^d)&b)^d) + X[index] + const
+// a = a<<shift | a>>(32-shift) + b
+#define ROUND1(a, b, c, d, index, shift, const) \
+	EOR	R(c), R(d), R(t0)		; \
+	AND	R(b), R(t0)			; \
+	EOR	R(d), R(t0)			; \
+	MOVW	(index<<2)(R(data)), R(t1)	; \
+	ADD	R(t1), R(t0)			; \
+	ADD	R(const), R(t0)			; \
+	ADD	R(t0), R(a)			; \
+	ADD	R(a)@>(32-shift), R(b), R(a)	;
+
+	MOVM.IA.W (R(table)), [R(c0),R(c1),R(c2),R(c3)]
+	ROUND1(a, b, c, d,  0,	7, c0)
+	ROUND1(d, a, b, c,  1, 12, c1)
+	ROUND1(c, d, a, b,  2, 17, c2)
+	ROUND1(b, c, d, a,  3, 22, c3)
+
+	MOVM.IA.W (R(table)), [R(c0),R(c1),R(c2),R(c3)]
+	ROUND1(a, b, c, d,  4,	7, c0)
+	ROUND1(d, a, b, c,  5, 12, c1)
+	ROUND1(c, d, a, b,  6, 17, c2)
+	ROUND1(b, c, d, a,  7, 22, c3)
+
+	MOVM.IA.W (R(table)), [R(c0),R(c1),R(c2),R(c3)]
+	ROUND1(a, b, c, d,  8,	7, c0)
+	ROUND1(d, a, b, c,  9, 12, c1)
+	ROUND1(c, d, a, b, 10, 17, c2)
+	ROUND1(b, c, d, a, 11, 22, c3)
+
+	MOVM.IA.W (R(table)), [R(c0),R(c1),R(c2),R(c3)]
+	ROUND1(a, b, c, d, 12,	7, c0)
+	ROUND1(d, a, b, c, 13, 12, c1)
+	ROUND1(c, d, a, b, 14, 17, c2)
+	ROUND1(b, c, d, a, 15, 22, c3)
+
+// a += (((b^c)&d)^c) + X[index] + const
+// a = a<<shift | a>>(32-shift) + b
+#define ROUND2(a, b, c, d, index, shift, const) \
+	EOR	R(b), R(c), R(t0)		; \
+	AND	R(d), R(t0)			; \
+	EOR	R(c), R(t0)			; \
+	MOVW	(index<<2)(R(data)), R(t1)	; \
+	ADD	R(t1), R(t0)			; \
+	ADD	R(const), R(t0)			; \
+	ADD	R(t0), R(a)			; \
+	ADD	R(a)@>(32-shift), R(b), R(a)	;
+
+	MOVM.IA.W (R(table)), [R(c0),R(c1),R(c2),R(c3)]
+	ROUND2(a, b, c, d,  1,	5, c0)
+	ROUND2(d, a, b, c,  6,	9, c1)
+	ROUND2(c, d, a, b, 11, 14, c2)
+	ROUND2(b, c, d, a,  0, 20, c3)
+
+	MOVM.IA.W (R(table)), [R(c0),R(c1),R(c2),R(c3)]
+	ROUND2(a, b, c, d,  5,	5, c0)
+	ROUND2(d, a, b, c, 10,	9, c1)
+	ROUND2(c, d, a, b, 15, 14, c2)
+	ROUND2(b, c, d, a,  4, 20, c3)
+
+	MOVM.IA.W (R(table)), [R(c0),R(c1),R(c2),R(c3)]
+	ROUND2(a, b, c, d,  9,	5, c0)
+	ROUND2(d, a, b, c, 14,	9, c1)
+	ROUND2(c, d, a, b,  3, 14, c2)
+	ROUND2(b, c, d, a,  8, 20, c3)
+
+	MOVM.IA.W (R(table)), [R(c0),R(c1),R(c2),R(c3)]
+	ROUND2(a, b, c, d, 13,	5, c0)
+	ROUND2(d, a, b, c,  2,	9, c1)
+	ROUND2(c, d, a, b,  7, 14, c2)
+	ROUND2(b, c, d, a, 12, 20, c3)
+
+// a += (b^c^d) + X[index] + const
+// a = a<<shift | a>>(32-shift) + b
+#define ROUND3(a, b, c, d, index, shift, const) \
+	EOR	R(b), R(c), R(t0)		; \
+	EOR	R(d), R(t0)			; \
+	MOVW	(index<<2)(R(data)), R(t1)	; \
+	ADD	R(t1), R(t0)			; \
+	ADD	R(const), R(t0)			; \
+	ADD	R(t0), R(a)			; \
+	ADD	R(a)@>(32-shift), R(b), R(a)	;
+
+	MOVM.IA.W (R(table)), [R(c0),R(c1),R(c2),R(c3)]
+	ROUND3(a, b, c, d,  5,	4, c0)
+	ROUND3(d, a, b, c,  8, 11, c1)
+	ROUND3(c, d, a, b, 11, 16, c2)
+	ROUND3(b, c, d, a, 14, 23, c3)
+
+	MOVM.IA.W (R(table)), [R(c0),R(c1),R(c2),R(c3)]
+	ROUND3(a, b, c, d,  1,	4, c0)
+	ROUND3(d, a, b, c,  4, 11, c1)
+	ROUND3(c, d, a, b,  7, 16, c2)
+	ROUND3(b, c, d, a, 10, 23, c3)
+
+	MOVM.IA.W (R(table)), [R(c0),R(c1),R(c2),R(c3)]
+	ROUND3(a, b, c, d, 13,	4, c0)
+	ROUND3(d, a, b, c,  0, 11, c1)
+	ROUND3(c, d, a, b,  3, 16, c2)
+	ROUND3(b, c, d, a,  6, 23, c3)
+
+	MOVM.IA.W (R(table)), [R(c0),R(c1),R(c2),R(c3)]
+	ROUND3(a, b, c, d,  9,	4, c0)
+	ROUND3(d, a, b, c, 12, 11, c1)
+	ROUND3(c, d, a, b, 15, 16, c2)
+	ROUND3(b, c, d, a,  2, 23, c3)
+
+// a += (c^(b|^d)) + X[index] + const
+// a = a<<shift | a>>(32-shift) + b
+#define ROUND4(a, b, c, d, index, shift, const) \
+	MVN	R(d), R(t0)			; \
+	ORR	R(b), R(t0)			; \
+	EOR	R(c), R(t0)			; \
+	MOVW	(index<<2)(R(data)), R(t1)	; \
+	ADD	R(t1), R(t0)			; \
+	ADD	R(const), R(t0)			; \
+	ADD	R(t0), R(a)			; \
+	ADD	R(a)@>(32-shift), R(b), R(a)	;
+
+	MOVM.IA.W (R(table)), [R(c0),R(c1),R(c2),R(c3)]
+	ROUND4(a, b, c, d,  0,	6, c0)
+	ROUND4(d, a, b, c,  7, 10, c1)
+	ROUND4(c, d, a, b, 14, 15, c2)
+	ROUND4(b, c, d, a,  5, 21, c3)
+
+	MOVM.IA.W (R(table)), [R(c0),R(c1),R(c2),R(c3)]
+	ROUND4(a, b, c, d, 12,	6, c0)
+	ROUND4(d, a, b, c,  3, 10, c1)
+	ROUND4(c, d, a, b, 10, 15, c2)
+	ROUND4(b, c, d, a,  1, 21, c3)
+
+	MOVM.IA.W (R(table)), [R(c0),R(c1),R(c2),R(c3)]
+	ROUND4(a, b, c, d,  8,	6, c0)
+	ROUND4(d, a, b, c, 15, 10, c1)
+	ROUND4(c, d, a, b,  6, 15, c2)
+	ROUND4(b, c, d, a, 13, 21, c3)
+
+	MOVM.IA.W (R(table)), [R(c0),R(c1),R(c2),R(c3)]
+	ROUND4(a, b, c, d,  4,	6, c0)
+	ROUND4(d, a, b, c, 11, 10, c1)
+	ROUND4(c, d, a, b,  2, 15, c2)
+	ROUND4(b, c, d, a,  9, 21, c3)
+
+	MOVW	dig+0(FP), R(t0)
+	MOVM.IA (R(t0)), [R(c0),R(c1),R(c2),R(c3)]
+
+	ADD	R(c0), R(a)
+	ADD	R(c1), R(b)
+	ADD	R(c2), R(c)
+	ADD	R(c3), R(d)
+
+	MOVM.IA [R(a),R(b),R(c),R(d)], (R(t0))
+
+	MOVW	p_data(SP), R(data)
+	MOVW	p_end(SP), R(t0)
+	ADD	$64, R(data)
+	CMP	R(t0), R(data)
+	BLO	loop
+
+	RET
+
+// MD5 constants table
+
+	// Round 1
+	DATA	·table+0x00(SB)/4, $0xd76aa478
+	DATA	·table+0x04(SB)/4, $0xe8c7b756
+	DATA	·table+0x08(SB)/4, $0x242070db
+	DATA	·table+0x0c(SB)/4, $0xc1bdceee
+	DATA	·table+0x10(SB)/4, $0xf57c0faf
+	DATA	·table+0x14(SB)/4, $0x4787c62a
+	DATA	·table+0x18(SB)/4, $0xa8304613
+	DATA	·table+0x1c(SB)/4, $0xfd469501
+	DATA	·table+0x20(SB)/4, $0x698098d8
+	DATA	·table+0x24(SB)/4, $0x8b44f7af
+	DATA	·table+0x28(SB)/4, $0xffff5bb1
+	DATA	·table+0x2c(SB)/4, $0x895cd7be
+	DATA	·table+0x30(SB)/4, $0x6b901122
+	DATA	·table+0x34(SB)/4, $0xfd987193
+	DATA	·table+0x38(SB)/4, $0xa679438e
+	DATA	·table+0x3c(SB)/4, $0x49b40821
+	// Round 2
+	DATA	·table+0x40(SB)/4, $0xf61e2562
+	DATA	·table+0x44(SB)/4, $0xc040b340
+	DATA	·table+0x48(SB)/4, $0x265e5a51
+	DATA	·table+0x4c(SB)/4, $0xe9b6c7aa
+	DATA	·table+0x50(SB)/4, $0xd62f105d
+	DATA	·table+0x54(SB)/4, $0x02441453
+	DATA	·table+0x58(SB)/4, $0xd8a1e681
+	DATA	·table+0x5c(SB)/4, $0xe7d3fbc8
+	DATA	·table+0x60(SB)/4, $0x21e1cde6
+	DATA	·table+0x64(SB)/4, $0xc33707d6
+	DATA	·table+0x68(SB)/4, $0xf4d50d87
+	DATA	·table+0x6c(SB)/4, $0x455a14ed
+	DATA	·table+0x70(SB)/4, $0xa9e3e905
+	DATA	·table+0x74(SB)/4, $0xfcefa3f8
+	DATA	·table+0x78(SB)/4, $0x676f02d9
+	DATA	·table+0x7c(SB)/4, $0x8d2a4c8a
+	// Round 3
+	DATA	·table+0x80(SB)/4, $0xfffa3942
+	DATA	·table+0x84(SB)/4, $0x8771f681
+	DATA	·table+0x88(SB)/4, $0x6d9d6122
+	DATA	·table+0x8c(SB)/4, $0xfde5380c
+	DATA	·table+0x90(SB)/4, $0xa4beea44
+	DATA	·table+0x94(SB)/4, $0x4bdecfa9
+	DATA	·table+0x98(SB)/4, $0xf6bb4b60
+	DATA	·table+0x9c(SB)/4, $0xbebfbc70
+	DATA	·table+0xa0(SB)/4, $0x289b7ec6
+	DATA	·table+0xa4(SB)/4, $0xeaa127fa
+	DATA	·table+0xa8(SB)/4, $0xd4ef3085
+	DATA	·table+0xac(SB)/4, $0x04881d05
+	DATA	·table+0xb0(SB)/4, $0xd9d4d039
+	DATA	·table+0xb4(SB)/4, $0xe6db99e5
+	DATA	·table+0xb8(SB)/4, $0x1fa27cf8
+	DATA	·table+0xbc(SB)/4, $0xc4ac5665
+	// Round 4
+	DATA	·table+0xc0(SB)/4, $0xf4292244
+	DATA	·table+0xc4(SB)/4, $0x432aff97
+	DATA	·table+0xc8(SB)/4, $0xab9423a7
+	DATA	·table+0xcc(SB)/4, $0xfc93a039
+	DATA	·table+0xd0(SB)/4, $0x655b59c3
+	DATA	·table+0xd4(SB)/4, $0x8f0ccc92
+	DATA	·table+0xd8(SB)/4, $0xffeff47d
+	DATA	·table+0xdc(SB)/4, $0x85845dd1
+	DATA	·table+0xe0(SB)/4, $0x6fa87e4f
+	DATA	·table+0xe4(SB)/4, $0xfe2ce6e0
+	DATA	·table+0xe8(SB)/4, $0xa3014314
+	DATA	·table+0xec(SB)/4, $0x4e0811a1
+	DATA	·table+0xf0(SB)/4, $0xf7537e82
+	DATA	·table+0xf4(SB)/4, $0xbd3af235
+	DATA	·table+0xf8(SB)/4, $0x2ad7d2bb
+	DATA	·table+0xfc(SB)/4, $0xeb86d391
+	// Global definition
+	GLOBL	·table(SB),8,$256
diff --git a/src/pkg/crypto/md5/md5block_decl.go b/src/crypto/md5/md5block_decl.go
similarity index 100%
rename from src/pkg/crypto/md5/md5block_decl.go
rename to src/crypto/md5/md5block_decl.go
diff --git a/src/pkg/crypto/md5/md5block_generic.go b/src/crypto/md5/md5block_generic.go
similarity index 100%
rename from src/pkg/crypto/md5/md5block_generic.go
rename to src/crypto/md5/md5block_generic.go
diff --git a/src/pkg/crypto/rand/example_test.go b/src/crypto/rand/example_test.go
similarity index 100%
rename from src/pkg/crypto/rand/example_test.go
rename to src/crypto/rand/example_test.go
diff --git a/src/pkg/crypto/rand/rand.go b/src/crypto/rand/rand.go
similarity index 100%
rename from src/pkg/crypto/rand/rand.go
rename to src/crypto/rand/rand.go
diff --git a/src/crypto/rand/rand_linux.go b/src/crypto/rand/rand_linux.go
new file mode 100644
index 0000000..8cb59c7
--- /dev/null
+++ b/src/crypto/rand/rand_linux.go
@@ -0,0 +1,39 @@
+// 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 rand
+
+import (
+	"internal/syscall"
+	"sync"
+)
+
+func init() {
+	altGetRandom = getRandomLinux
+}
+
+var (
+	once       sync.Once
+	useSyscall bool
+)
+
+func pickStrategy() {
+	// Test whether we should use the system call or /dev/urandom.
+	// We'll fall back to urandom if:
+	// - the kernel is too old (before 3.17)
+	// - the machine has no entropy available (early boot + no hardware
+	//   entropy source?) and we want to avoid blocking later.
+	var buf [1]byte
+	n, err := syscall.GetRandom(buf[:], syscall.GRND_NONBLOCK)
+	useSyscall = n == 1 && err == nil
+}
+
+func getRandomLinux(p []byte) (ok bool) {
+	once.Do(pickStrategy)
+	if !useSyscall {
+		return false
+	}
+	n, err := syscall.GetRandom(p, 0)
+	return n == len(p) && err == nil
+}
diff --git a/src/pkg/crypto/rand/rand_test.go b/src/crypto/rand/rand_test.go
similarity index 100%
rename from src/pkg/crypto/rand/rand_test.go
rename to src/crypto/rand/rand_test.go
diff --git a/src/crypto/rand/rand_unix.go b/src/crypto/rand/rand_unix.go
new file mode 100644
index 0000000..62d0fbd
--- /dev/null
+++ b/src/crypto/rand/rand_unix.go
@@ -0,0 +1,147 @@
+// Copyright 2010 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin dragonfly freebsd linux nacl netbsd openbsd plan9 solaris
+
+// Unix cryptographically secure pseudorandom number
+// generator.
+
+package rand
+
+import (
+	"bufio"
+	"crypto/aes"
+	"crypto/cipher"
+	"io"
+	"os"
+	"runtime"
+	"sync"
+	"time"
+)
+
+const urandomDevice = "/dev/urandom"
+
+// Easy implementation: read from /dev/urandom.
+// This is sufficient on Linux, OS X, and FreeBSD.
+
+func init() {
+	if runtime.GOOS == "plan9" {
+		Reader = newReader(nil)
+	} else {
+		Reader = &devReader{name: urandomDevice}
+	}
+}
+
+// A devReader satisfies reads by reading the file named name.
+type devReader struct {
+	name string
+	f    io.Reader
+	mu   sync.Mutex
+}
+
+// altGetRandom if non-nil specifies an OS-specific function to get
+// urandom-style randomness.
+var altGetRandom func([]byte) (ok bool)
+
+func (r *devReader) Read(b []byte) (n int, err error) {
+	if altGetRandom != nil && r.name == urandomDevice && altGetRandom(b) {
+		return len(b), nil
+	}
+	r.mu.Lock()
+	defer r.mu.Unlock()
+	if r.f == nil {
+		f, err := os.Open(r.name)
+		if f == nil {
+			return 0, err
+		}
+		if runtime.GOOS == "plan9" {
+			r.f = f
+		} else {
+			r.f = bufio.NewReader(f)
+		}
+	}
+	return r.f.Read(b)
+}
+
+// Alternate pseudo-random implementation for use on
+// systems without a reliable /dev/urandom.
+
+// newReader returns a new pseudorandom generator that
+// seeds itself by reading from entropy.  If entropy == nil,
+// the generator seeds itself by reading from the system's
+// random number generator, typically /dev/random.
+// The Read method on the returned reader always returns
+// the full amount asked for, or else it returns an error.
+//
+// The generator uses the X9.31 algorithm with AES-128,
+// reseeding after every 1 MB of generated data.
+func newReader(entropy io.Reader) io.Reader {
+	if entropy == nil {
+		entropy = &devReader{name: "/dev/random"}
+	}
+	return &reader{entropy: entropy}
+}
+
+type reader struct {
+	mu                   sync.Mutex
+	budget               int // number of bytes that can be generated
+	cipher               cipher.Block
+	entropy              io.Reader
+	time, seed, dst, key [aes.BlockSize]byte
+}
+
+func (r *reader) Read(b []byte) (n int, err error) {
+	r.mu.Lock()
+	defer r.mu.Unlock()
+	n = len(b)
+
+	for len(b) > 0 {
+		if r.budget == 0 {
+			_, err := io.ReadFull(r.entropy, r.seed[0:])
+			if err != nil {
+				return n - len(b), err
+			}
+			_, err = io.ReadFull(r.entropy, r.key[0:])
+			if err != nil {
+				return n - len(b), err
+			}
+			r.cipher, err = aes.NewCipher(r.key[0:])
+			if err != nil {
+				return n - len(b), err
+			}
+			r.budget = 1 << 20 // reseed after generating 1MB
+		}
+		r.budget -= aes.BlockSize
+
+		// ANSI X9.31 (== X9.17) algorithm, but using AES in place of 3DES.
+		//
+		// single block:
+		// t = encrypt(time)
+		// dst = encrypt(t^seed)
+		// seed = encrypt(t^dst)
+		ns := time.Now().UnixNano()
+		r.time[0] = byte(ns >> 56)
+		r.time[1] = byte(ns >> 48)
+		r.time[2] = byte(ns >> 40)
+		r.time[3] = byte(ns >> 32)
+		r.time[4] = byte(ns >> 24)
+		r.time[5] = byte(ns >> 16)
+		r.time[6] = byte(ns >> 8)
+		r.time[7] = byte(ns)
+		r.cipher.Encrypt(r.time[0:], r.time[0:])
+		for i := 0; i < aes.BlockSize; i++ {
+			r.dst[i] = r.time[i] ^ r.seed[i]
+		}
+		r.cipher.Encrypt(r.dst[0:], r.dst[0:])
+		for i := 0; i < aes.BlockSize; i++ {
+			r.seed[i] = r.time[i] ^ r.dst[i]
+		}
+		r.cipher.Encrypt(r.seed[0:], r.seed[0:])
+
+		m := copy(b, r.dst[0:])
+		b = b[m:]
+	}
+
+	return n, nil
+}
diff --git a/src/pkg/crypto/rand/rand_windows.go b/src/crypto/rand/rand_windows.go
similarity index 100%
rename from src/pkg/crypto/rand/rand_windows.go
rename to src/crypto/rand/rand_windows.go
diff --git a/src/pkg/crypto/rand/util.go b/src/crypto/rand/util.go
similarity index 100%
rename from src/pkg/crypto/rand/util.go
rename to src/crypto/rand/util.go
diff --git a/src/pkg/crypto/rand/util_test.go b/src/crypto/rand/util_test.go
similarity index 100%
rename from src/pkg/crypto/rand/util_test.go
rename to src/crypto/rand/util_test.go
diff --git a/src/pkg/crypto/rc4/rc4.go b/src/crypto/rc4/rc4.go
similarity index 100%
rename from src/pkg/crypto/rc4/rc4.go
rename to src/crypto/rc4/rc4.go
diff --git a/src/crypto/rc4/rc4_386.s b/src/crypto/rc4/rc4_386.s
new file mode 100644
index 0000000..5422103
--- /dev/null
+++ b/src/crypto/rc4/rc4_386.s
@@ -0,0 +1,53 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+// func xorKeyStream(dst, src *byte, n int, state *[256]byte, i, j *uint8)
+TEXT ·xorKeyStream(SB),NOSPLIT,$0
+	MOVL dst+0(FP), DI
+	MOVL src+4(FP), SI
+	MOVL state+12(FP), BP
+
+	MOVL i+16(FP), AX
+	MOVBLZX (AX), AX
+	MOVL j+20(FP), BX
+	MOVBLZX (BX), BX
+	CMPL n+8(FP), $0
+	JEQ done
+
+loop:
+	// i += 1
+	INCB AX
+
+	// j += c.s[i]
+	MOVBLZX (BP)(AX*4), DX
+	ADDB DX, BX
+	MOVBLZX BX, BX
+
+	// c.s[i], c.s[j] = c.s[j], c.s[i]
+	MOVBLZX (BP)(BX*4), CX
+	MOVB CX, (BP)(AX*4)
+	MOVB DX, (BP)(BX*4)
+
+	// *dst = *src ^ c.s[c.s[i]+c.s[j]]
+	ADDB DX, CX
+	MOVBLZX CX, CX
+	MOVB (BP)(CX*4), CX
+	XORB (SI), CX
+	MOVBLZX CX, CX
+	MOVB CX, (DI)
+
+	INCL SI
+	INCL DI
+	DECL n+8(FP)
+	JNE loop
+
+done:
+	MOVL i+16(FP), CX
+	MOVB AX, (CX)
+	MOVL j+20(FP), CX
+	MOVB BX, (CX)
+
+	RET
diff --git a/src/crypto/rc4/rc4_amd64.s b/src/crypto/rc4/rc4_amd64.s
new file mode 100644
index 0000000..57d941c
--- /dev/null
+++ b/src/crypto/rc4/rc4_amd64.s
@@ -0,0 +1,179 @@
+// Original source:
+//	http://www.zorinaq.com/papers/rc4-amd64.html
+//	http://www.zorinaq.com/papers/rc4-amd64.tar.bz2
+
+#include "textflag.h"
+
+// Local modifications:
+//
+// Transliterated from GNU to 6a assembly syntax by the Go authors.
+// The comments and spacing are from the original.
+//
+// The new EXTEND macros avoid a bad stall on some systems after 8-bit math.
+//
+// The original code accumulated 64 bits of key stream in an integer
+// register and then XOR'ed the key stream into the data 8 bytes at a time.
+// Modified to accumulate 128 bits of key stream into an XMM register
+// and then XOR the key stream into the data 16 bytes at a time.
+// Approximately doubles throughput.
+
+// NOTE: Changing EXTEND to a no-op makes the code run 1.2x faster on Core i5
+// but makes the code run 2.0x slower on Xeon.
+#define EXTEND(r) MOVBLZX r, r
+
+/*
+** RC4 implementation optimized for AMD64.
+**
+** Author: Marc Bevand <bevand_m (at) epita.fr>
+** Licence: I hereby disclaim the copyright on this code and place it
+** in the public domain.
+**
+** The code has been designed to be easily integrated into openssl:
+** the exported RC4() function can replace the actual implementations
+** openssl already contains. Please note that when linking with openssl,
+** it requires that sizeof(RC4_INT) == 8. So openssl must be compiled
+** with -DRC4_INT='unsigned long'.
+**
+** The throughput achieved by this code is about 320 MBytes/sec, on
+** a 1.8 GHz AMD Opteron (rev C0) processor.
+*/
+
+TEXT ·xorKeyStream(SB),NOSPLIT,$0
+	MOVQ	n+16(FP),	BX		// rbx = ARG(len)
+	MOVQ	src+8(FP),	SI		// in = ARG(in)
+	MOVQ	dst+0(FP),	DI		// out = ARG(out)
+	MOVQ	state+24(FP),	BP		// d = ARG(data)
+	MOVQ	i+32(FP),	AX
+	MOVBQZX	0(AX),		CX		// x = *xp
+	MOVQ	j+40(FP),	AX
+	MOVBQZX	0(AX),		DX		// y = *yp
+
+	LEAQ	(SI)(BX*1),	R9		// limit = in+len
+
+l1:	CMPQ	SI,		R9		// cmp in with in+len
+	JGE	finished			// jump if (in >= in+len)
+
+	INCB	CX
+	EXTEND(CX)
+	TESTL	$15,		CX
+	JZ	wordloop
+
+	MOVBLZX	(BP)(CX*4),	AX
+
+	ADDB	AX,		DX		// y += tx
+	EXTEND(DX)
+	MOVBLZX	(BP)(DX*4),	BX		// ty = d[y]
+	MOVB	BX,		(BP)(CX*4)	// d[x] = ty
+	ADDB	AX,		BX		// val = ty+tx
+	EXTEND(BX)
+	MOVB	AX,		(BP)(DX*4)	// d[y] = tx
+	MOVBLZX	(BP)(BX*4),	R8		// val = d[val]
+	XORB	(SI),		R8		// xor 1 byte
+	MOVB	R8,		(DI)
+	INCQ	SI				// in++
+	INCQ	DI				// out++
+	JMP l1
+
+wordloop:
+	SUBQ	$16,		R9
+	CMPQ	SI,		R9
+	JGT	end
+
+start:
+	ADDQ	$16,		SI		// increment in
+	ADDQ	$16,		DI		// increment out
+
+	// Each KEYROUND generates one byte of key and
+	// inserts it into an XMM register at the given 16-bit index.
+	// The key state array is uint32 words only using the bottom
+	// byte of each word, so the 16-bit OR only copies 8 useful bits.
+	// We accumulate alternating bytes into X0 and X1, and then at
+	// the end we OR X1<<8 into X0 to produce the actual key.
+	//
+	// At the beginning of the loop, CX%16 == 0, so the 16 loads
+	// at state[CX], state[CX+1], ..., state[CX+15] can precompute
+	// (state+CX) as R12 and then become R12[0], R12[1], ... R12[15],
+	// without fear of the byte computation CX+15 wrapping around.
+	//
+	// The first round needs R12[0], the second needs R12[1], and so on.
+	// We can avoid memory stalls by starting the load for round n+1
+	// before the end of round n, using the LOAD macro.
+	LEAQ	(BP)(CX*4),	R12
+
+#define KEYROUND(xmm, load, off, r1, r2, index) \
+	MOVBLZX	(BP)(DX*4),	R8; \
+	MOVB	r1,		(BP)(DX*4); \
+	load((off+1), r2); \
+	MOVB	R8,		(off*4)(R12); \
+	ADDB	r1,		R8; \
+	EXTEND(R8); \
+	PINSRW	$index, (BP)(R8*4), xmm
+
+#define LOAD(off, reg) \
+	MOVBLZX	(off*4)(R12),	reg; \
+	ADDB	reg,		DX; \
+	EXTEND(DX)
+
+#define SKIP(off, reg)
+
+	LOAD(0, AX)
+	KEYROUND(X0, LOAD, 0, AX, BX, 0)
+	KEYROUND(X1, LOAD, 1, BX, AX, 0)
+	KEYROUND(X0, LOAD, 2, AX, BX, 1)
+	KEYROUND(X1, LOAD, 3, BX, AX, 1)
+	KEYROUND(X0, LOAD, 4, AX, BX, 2)
+	KEYROUND(X1, LOAD, 5, BX, AX, 2)
+	KEYROUND(X0, LOAD, 6, AX, BX, 3)
+	KEYROUND(X1, LOAD, 7, BX, AX, 3)
+	KEYROUND(X0, LOAD, 8, AX, BX, 4)
+	KEYROUND(X1, LOAD, 9, BX, AX, 4)
+	KEYROUND(X0, LOAD, 10, AX, BX, 5)
+	KEYROUND(X1, LOAD, 11, BX, AX, 5)
+	KEYROUND(X0, LOAD, 12, AX, BX, 6)
+	KEYROUND(X1, LOAD, 13, BX, AX, 6)
+	KEYROUND(X0, LOAD, 14, AX, BX, 7)
+	KEYROUND(X1, SKIP, 15, BX, AX, 7)
+	
+	ADDB	$16,		CX
+
+	PSLLQ	$8,		X1
+	PXOR	X1,		X0
+	MOVOU	-16(SI),	X2
+	PXOR	X0,		X2
+	MOVOU	X2,		-16(DI)
+
+	CMPQ	SI,		R9		// cmp in with in+len-16
+	JLE	start				// jump if (in <= in+len-16)
+
+end:
+	DECB	CX
+	ADDQ	$16,		R9		// tmp = in+len
+
+	// handle the last bytes, one by one
+l2:	CMPQ	SI,		R9		// cmp in with in+len
+	JGE	finished			// jump if (in >= in+len)
+
+	INCB	CX
+	EXTEND(CX)
+	MOVBLZX	(BP)(CX*4),	AX
+
+	ADDB	AX,		DX		// y += tx
+	EXTEND(DX)
+	MOVBLZX	(BP)(DX*4),	BX		// ty = d[y]
+	MOVB	BX,		(BP)(CX*4)	// d[x] = ty
+	ADDB	AX,		BX		// val = ty+tx
+	EXTEND(BX)
+	MOVB	AX,		(BP)(DX*4)	// d[y] = tx
+	MOVBLZX	(BP)(BX*4),	R8		// val = d[val]
+	XORB	(SI),		R8		// xor 1 byte
+	MOVB	R8,		(DI)
+	INCQ	SI				// in++
+	INCQ	DI				// out++
+	JMP l2
+
+finished:
+	MOVQ	j+40(FP),	BX
+	MOVB	DX, 0(BX)
+	MOVQ	i+32(FP),	AX
+	MOVB	CX, 0(AX)
+	RET
diff --git a/src/crypto/rc4/rc4_amd64p32.s b/src/crypto/rc4/rc4_amd64p32.s
new file mode 100644
index 0000000..970b34e
--- /dev/null
+++ b/src/crypto/rc4/rc4_amd64p32.s
@@ -0,0 +1,192 @@
+// Original source:
+//	http://www.zorinaq.com/papers/rc4-amd64.html
+//	http://www.zorinaq.com/papers/rc4-amd64.tar.bz2
+
+#include "textflag.h"
+
+// Local modifications:
+//
+// Transliterated from GNU to 6a assembly syntax by the Go authors.
+// The comments and spacing are from the original.
+//
+// The new EXTEND macros avoid a bad stall on some systems after 8-bit math.
+//
+// The original code accumulated 64 bits of key stream in an integer
+// register and then XOR'ed the key stream into the data 8 bytes at a time.
+// Modified to accumulate 128 bits of key stream into an XMM register
+// and then XOR the key stream into the data 16 bytes at a time.
+// Approximately doubles throughput.
+//
+// Converted to amd64p32.
+//
+// To make safe for Native Client, avoid use of BP, R15,
+// and two-register addressing modes.
+
+// NOTE: Changing EXTEND to a no-op makes the code run 1.2x faster on Core i5
+// but makes the code run 2.0x slower on Xeon.
+#define EXTEND(r) MOVBLZX r, r
+
+/*
+** RC4 implementation optimized for AMD64.
+**
+** Author: Marc Bevand <bevand_m (at) epita.fr>
+** Licence: I hereby disclaim the copyright on this code and place it
+** in the public domain.
+**
+** The code has been designed to be easily integrated into openssl:
+** the exported RC4() function can replace the actual implementations
+** openssl already contains. Please note that when linking with openssl,
+** it requires that sizeof(RC4_INT) == 8. So openssl must be compiled
+** with -DRC4_INT='unsigned long'.
+**
+** The throughput achieved by this code is about 320 MBytes/sec, on
+** a 1.8 GHz AMD Opteron (rev C0) processor.
+*/
+
+TEXT ·xorKeyStream(SB),NOSPLIT,$0
+	MOVL	n+8(FP),	BX		// rbx = ARG(len)
+	MOVL	src+4(FP),	SI		// in = ARG(in)
+	MOVL	dst+0(FP),	DI		// out = ARG(out)
+	MOVL	state+12(FP),	R10		// d = ARG(data)
+	MOVL	i+16(FP),	AX
+	MOVBQZX	0(AX),		CX		// x = *xp
+	MOVL	j+20(FP),	AX
+	MOVBQZX	0(AX),		DX		// y = *yp
+
+	LEAQ	(SI)(BX*1),	R9		// limit = in+len
+
+l1:	CMPQ	SI,		R9		// cmp in with in+len
+	JGE	finished			// jump if (in >= in+len)
+
+	INCB	CX
+	EXTEND(CX)
+	TESTL	$15,		CX
+	JZ	wordloop
+	LEAL	(R10)(CX*4), R12
+
+	MOVBLZX	(R12),	AX
+
+	ADDB	AX,		DX		// y += tx
+	EXTEND(DX)
+	LEAL (R10)(DX*4), R11
+	MOVBLZX	(R11),	BX		// ty = d[y]
+	MOVB	BX,		(R12)	// d[x] = ty
+	ADDB	AX,		BX		// val = ty+tx
+	EXTEND(BX)
+	LEAL (R10)(BX*4), R13
+	MOVB	AX,		(R11)	// d[y] = tx
+	MOVBLZX	(R13),	R8		// val = d[val]
+	XORB	(SI),		R8		// xor 1 byte
+	MOVB	R8,		(DI)
+	INCQ	SI				// in++
+	INCQ	DI				// out++
+	JMP l1
+
+wordloop:
+	SUBQ	$16,		R9
+	CMPQ	SI,		R9
+	JGT	end
+
+start:
+	ADDQ	$16,		SI		// increment in
+	ADDQ	$16,		DI		// increment out
+
+	// Each KEYROUND generates one byte of key and
+	// inserts it into an XMM register at the given 16-bit index.
+	// The key state array is uint32 words only using the bottom
+	// byte of each word, so the 16-bit OR only copies 8 useful bits.
+	// We accumulate alternating bytes into X0 and X1, and then at
+	// the end we OR X1<<8 into X0 to produce the actual key.
+	//
+	// At the beginning of the loop, CX%16 == 0, so the 16 loads
+	// at state[CX], state[CX+1], ..., state[CX+15] can precompute
+	// (state+CX) as R12 and then become R12[0], R12[1], ... R12[15],
+	// without fear of the byte computation CX+15 wrapping around.
+	//
+	// The first round needs R12[0], the second needs R12[1], and so on.
+	// We can avoid memory stalls by starting the load for round n+1
+	// before the end of round n, using the LOAD macro.
+	LEAQ	(R10)(CX*4),	R12
+
+#define KEYROUND(xmm, load, off, r1, r2, index) \
+	LEAL (R10)(DX*4), R11; \
+	MOVBLZX	(R11),	R8; \
+	MOVB	r1,		(R11); \
+	load((off+1), r2); \
+	MOVB	R8,		(off*4)(R12); \
+	ADDB	r1,		R8; \
+	EXTEND(R8); \
+	LEAL (R10)(R8*4), R14; \
+	PINSRW	$index, (R14), xmm
+
+#define LOAD(off, reg) \
+	MOVBLZX	(off*4)(R12),	reg; \
+	ADDB	reg,		DX; \
+	EXTEND(DX)
+
+#define SKIP(off, reg)
+
+	LOAD(0, AX)
+	KEYROUND(X0, LOAD, 0, AX, BX, 0)
+	KEYROUND(X1, LOAD, 1, BX, AX, 0)
+	KEYROUND(X0, LOAD, 2, AX, BX, 1)
+	KEYROUND(X1, LOAD, 3, BX, AX, 1)
+	KEYROUND(X0, LOAD, 4, AX, BX, 2)
+	KEYROUND(X1, LOAD, 5, BX, AX, 2)
+	KEYROUND(X0, LOAD, 6, AX, BX, 3)
+	KEYROUND(X1, LOAD, 7, BX, AX, 3)
+	KEYROUND(X0, LOAD, 8, AX, BX, 4)
+	KEYROUND(X1, LOAD, 9, BX, AX, 4)
+	KEYROUND(X0, LOAD, 10, AX, BX, 5)
+	KEYROUND(X1, LOAD, 11, BX, AX, 5)
+	KEYROUND(X0, LOAD, 12, AX, BX, 6)
+	KEYROUND(X1, LOAD, 13, BX, AX, 6)
+	KEYROUND(X0, LOAD, 14, AX, BX, 7)
+	KEYROUND(X1, SKIP, 15, BX, AX, 7)
+	
+	ADDB	$16,		CX
+
+	PSLLQ	$8,		X1
+	PXOR	X1,		X0
+	MOVOU	-16(SI),	X2
+	PXOR	X0,		X2
+	MOVOU	X2,		-16(DI)
+
+	CMPQ	SI,		R9		// cmp in with in+len-16
+	JLE	start				// jump if (in <= in+len-16)
+
+end:
+	DECB	CX
+	ADDQ	$16,		R9		// tmp = in+len
+
+	// handle the last bytes, one by one
+l2:	CMPQ	SI,		R9		// cmp in with in+len
+	JGE	finished			// jump if (in >= in+len)
+
+	INCB	CX
+	EXTEND(CX)
+	LEAL (R10)(CX*4), R12
+	MOVBLZX	(R12),	AX
+
+	ADDB	AX,		DX		// y += tx
+	EXTEND(DX)
+	LEAL (R10)(DX*4), R11
+	MOVBLZX	(R11),	BX		// ty = d[y]
+	MOVB	BX,		(R12)	// d[x] = ty
+	ADDB	AX,		BX		// val = ty+tx
+	EXTEND(BX)
+	LEAL (R10)(BX*4), R13
+	MOVB	AX,		(R11)	// d[y] = tx
+	MOVBLZX	(R13),	R8		// val = d[val]
+	XORB	(SI),		R8		// xor 1 byte
+	MOVB	R8,		(DI)
+	INCQ	SI				// in++
+	INCQ	DI				// out++
+	JMP l2
+
+finished:
+	MOVL	j+20(FP),	BX
+	MOVB	DX, 0(BX)
+	MOVL	i+16(FP),	AX
+	MOVB	CX, 0(AX)
+	RET
diff --git a/src/crypto/rc4/rc4_arm.s b/src/crypto/rc4/rc4_arm.s
new file mode 100644
index 0000000..51be3bf
--- /dev/null
+++ b/src/crypto/rc4/rc4_arm.s
@@ -0,0 +1,62 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !nacl
+
+#include "textflag.h"
+
+// Registers
+dst = 0
+src = 1
+n = 2
+state = 3
+pi = 4
+pj = 5
+i = 6
+j = 7
+k = 8
+t = 11
+t2 = 12
+
+// func xorKeyStream(dst, src *byte, n int, state *[256]byte, i, j *uint8)
+TEXT ·xorKeyStream(SB),NOSPLIT,$0
+	MOVW 0(FP), R(dst)
+	MOVW 4(FP), R(src)
+	MOVW 8(FP), R(n)
+	MOVW 12(FP), R(state)
+	MOVW 16(FP), R(pi)
+	MOVW 20(FP), R(pj)
+	MOVBU (R(pi)), R(i)
+	MOVBU (R(pj)), R(j)
+	MOVW $0, R(k)
+
+loop:
+	// i += 1; j += state[i]
+	ADD $1, R(i)
+	AND $0xff, R(i)
+	MOVBU R(i)<<2(R(state)), R(t)
+	ADD R(t), R(j)
+	AND $0xff, R(j)
+
+	// swap state[i] <-> state[j]
+	MOVBU R(j)<<2(R(state)), R(t2)
+	MOVB R(t2), R(i)<<2(R(state))
+	MOVB R(t), R(j)<<2(R(state))
+
+	// dst[k] = src[k] ^ state[state[i] + state[j]]
+	ADD R(t2), R(t)
+	AND $0xff, R(t)
+	MOVBU R(t)<<2(R(state)), R(t)
+	MOVBU R(k)<<0(R(src)), R(t2)
+	EOR R(t), R(t2)
+	MOVB R(t2), R(k)<<0(R(dst))
+
+	ADD $1, R(k)
+	CMP R(k), R(n)
+	BNE loop
+
+done:
+	MOVB R(i), (R(pi))
+	MOVB R(j), (R(pj))
+	RET
diff --git a/src/crypto/rc4/rc4_asm.go b/src/crypto/rc4/rc4_asm.go
new file mode 100644
index 0000000..02e5b67
--- /dev/null
+++ b/src/crypto/rc4/rc4_asm.go
@@ -0,0 +1,18 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build amd64 amd64p32 arm,!nacl 386
+
+package rc4
+
+func xorKeyStream(dst, src *byte, n int, state *[256]uint32, i, j *uint8)
+
+// XORKeyStream sets dst to the result of XORing src with the key stream.
+// Dst and src may be the same slice but otherwise should not overlap.
+func (c *Cipher) XORKeyStream(dst, src []byte) {
+	if len(src) == 0 {
+		return
+	}
+	xorKeyStream(&dst[0], &src[0], len(src), &c.s, &c.i, &c.j)
+}
diff --git a/src/crypto/rc4/rc4_ref.go b/src/crypto/rc4/rc4_ref.go
new file mode 100644
index 0000000..e34bd34
--- /dev/null
+++ b/src/crypto/rc4/rc4_ref.go
@@ -0,0 +1,13 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !amd64,!amd64p32,!arm,!386 arm,nacl
+
+package rc4
+
+// XORKeyStream sets dst to the result of XORing src with the key stream.
+// Dst and src may be the same slice but otherwise should not overlap.
+func (c *Cipher) XORKeyStream(dst, src []byte) {
+	c.xorKeyStreamGeneric(dst, src)
+}
diff --git a/src/pkg/crypto/rc4/rc4_test.go b/src/crypto/rc4/rc4_test.go
similarity index 100%
rename from src/pkg/crypto/rc4/rc4_test.go
rename to src/crypto/rc4/rc4_test.go
diff --git a/src/pkg/crypto/rsa/pkcs1v15.go b/src/crypto/rsa/pkcs1v15.go
similarity index 100%
rename from src/pkg/crypto/rsa/pkcs1v15.go
rename to src/crypto/rsa/pkcs1v15.go
diff --git a/src/pkg/crypto/rsa/pkcs1v15_test.go b/src/crypto/rsa/pkcs1v15_test.go
similarity index 100%
rename from src/pkg/crypto/rsa/pkcs1v15_test.go
rename to src/crypto/rsa/pkcs1v15_test.go
diff --git a/src/crypto/rsa/pss.go b/src/crypto/rsa/pss.go
new file mode 100644
index 0000000..e9f2908
--- /dev/null
+++ b/src/crypto/rsa/pss.go
@@ -0,0 +1,297 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package rsa
+
+// This file implements the PSS signature scheme [1].
+//
+// [1] http://www.rsa.com/rsalabs/pkcs/files/h11300-wp-pkcs-1v2-2-rsa-cryptography-standard.pdf
+
+import (
+	"bytes"
+	"crypto"
+	"errors"
+	"hash"
+	"io"
+	"math/big"
+)
+
+func emsaPSSEncode(mHash []byte, emBits int, salt []byte, hash hash.Hash) ([]byte, error) {
+	// See [1], section 9.1.1
+	hLen := hash.Size()
+	sLen := len(salt)
+	emLen := (emBits + 7) / 8
+
+	// 1.  If the length of M is greater than the input limitation for the
+	//     hash function (2^61 - 1 octets for SHA-1), output "message too
+	//     long" and stop.
+	//
+	// 2.  Let mHash = Hash(M), an octet string of length hLen.
+
+	if len(mHash) != hLen {
+		return nil, errors.New("crypto/rsa: input must be hashed message")
+	}
+
+	// 3.  If emLen < hLen + sLen + 2, output "encoding error" and stop.
+
+	if emLen < hLen+sLen+2 {
+		return nil, errors.New("crypto/rsa: encoding error")
+	}
+
+	em := make([]byte, emLen)
+	db := em[:emLen-sLen-hLen-2+1+sLen]
+	h := em[emLen-sLen-hLen-2+1+sLen : emLen-1]
+
+	// 4.  Generate a random octet string salt of length sLen; if sLen = 0,
+	//     then salt is the empty string.
+	//
+	// 5.  Let
+	//       M' = (0x)00 00 00 00 00 00 00 00 || mHash || salt;
+	//
+	//     M' is an octet string of length 8 + hLen + sLen with eight
+	//     initial zero octets.
+	//
+	// 6.  Let H = Hash(M'), an octet string of length hLen.
+
+	var prefix [8]byte
+
+	hash.Write(prefix[:])
+	hash.Write(mHash)
+	hash.Write(salt)
+
+	h = hash.Sum(h[:0])
+	hash.Reset()
+
+	// 7.  Generate an octet string PS consisting of emLen - sLen - hLen - 2
+	//     zero octets.  The length of PS may be 0.
+	//
+	// 8.  Let DB = PS || 0x01 || salt; DB is an octet string of length
+	//     emLen - hLen - 1.
+
+	db[emLen-sLen-hLen-2] = 0x01
+	copy(db[emLen-sLen-hLen-1:], salt)
+
+	// 9.  Let dbMask = MGF(H, emLen - hLen - 1).
+	//
+	// 10. Let maskedDB = DB \xor dbMask.
+
+	mgf1XOR(db, hash, h)
+
+	// 11. Set the leftmost 8 * emLen - emBits bits of the leftmost octet in
+	//     maskedDB to zero.
+
+	db[0] &= (0xFF >> uint(8*emLen-emBits))
+
+	// 12. Let EM = maskedDB || H || 0xbc.
+	em[emLen-1] = 0xBC
+
+	// 13. Output EM.
+	return em, nil
+}
+
+func emsaPSSVerify(mHash, em []byte, emBits, sLen int, hash hash.Hash) error {
+	// 1.  If the length of M is greater than the input limitation for the
+	//     hash function (2^61 - 1 octets for SHA-1), output "inconsistent"
+	//     and stop.
+	//
+	// 2.  Let mHash = Hash(M), an octet string of length hLen.
+	hLen := hash.Size()
+	if hLen != len(mHash) {
+		return ErrVerification
+	}
+
+	// 3.  If emLen < hLen + sLen + 2, output "inconsistent" and stop.
+	emLen := (emBits + 7) / 8
+	if emLen < hLen+sLen+2 {
+		return ErrVerification
+	}
+
+	// 4.  If the rightmost octet of EM does not have hexadecimal value
+	//     0xbc, output "inconsistent" and stop.
+	if em[len(em)-1] != 0xBC {
+		return ErrVerification
+	}
+
+	// 5.  Let maskedDB be the leftmost emLen - hLen - 1 octets of EM, and
+	//     let H be the next hLen octets.
+	db := em[:emLen-hLen-1]
+	h := em[emLen-hLen-1 : len(em)-1]
+
+	// 6.  If the leftmost 8 * emLen - emBits bits of the leftmost octet in
+	//     maskedDB are not all equal to zero, output "inconsistent" and
+	//     stop.
+	if em[0]&(0xFF<<uint(8-(8*emLen-emBits))) != 0 {
+		return ErrVerification
+	}
+
+	// 7.  Let dbMask = MGF(H, emLen - hLen - 1).
+	//
+	// 8.  Let DB = maskedDB \xor dbMask.
+	mgf1XOR(db, hash, h)
+
+	// 9.  Set the leftmost 8 * emLen - emBits bits of the leftmost octet in DB
+	//     to zero.
+	db[0] &= (0xFF >> uint(8*emLen-emBits))
+
+	if sLen == PSSSaltLengthAuto {
+	FindSaltLength:
+		for sLen = emLen - (hLen + 2); sLen >= 0; sLen-- {
+			switch db[emLen-hLen-sLen-2] {
+			case 1:
+				break FindSaltLength
+			case 0:
+				continue
+			default:
+				return ErrVerification
+			}
+		}
+		if sLen < 0 {
+			return ErrVerification
+		}
+	} else {
+		// 10. If the emLen - hLen - sLen - 2 leftmost octets of DB are not zero
+		//     or if the octet at position emLen - hLen - sLen - 1 (the leftmost
+		//     position is "position 1") does not have hexadecimal value 0x01,
+		//     output "inconsistent" and stop.
+		for _, e := range db[:emLen-hLen-sLen-2] {
+			if e != 0x00 {
+				return ErrVerification
+			}
+		}
+		if db[emLen-hLen-sLen-2] != 0x01 {
+			return ErrVerification
+		}
+	}
+
+	// 11.  Let salt be the last sLen octets of DB.
+	salt := db[len(db)-sLen:]
+
+	// 12.  Let
+	//          M' = (0x)00 00 00 00 00 00 00 00 || mHash || salt ;
+	//     M' is an octet string of length 8 + hLen + sLen with eight
+	//     initial zero octets.
+	//
+	// 13. Let H' = Hash(M'), an octet string of length hLen.
+	var prefix [8]byte
+	hash.Write(prefix[:])
+	hash.Write(mHash)
+	hash.Write(salt)
+
+	h0 := hash.Sum(nil)
+
+	// 14. If H = H', output "consistent." Otherwise, output "inconsistent."
+	if !bytes.Equal(h0, h) {
+		return ErrVerification
+	}
+	return nil
+}
+
+// signPSSWithSalt calculates the signature of hashed using PSS [1] with specified salt.
+// Note that hashed must be the result of hashing the input message using the
+// given hash function. salt is a random sequence of bytes whose length will be
+// later used to verify the signature.
+func signPSSWithSalt(rand io.Reader, priv *PrivateKey, hash crypto.Hash, hashed, salt []byte) (s []byte, err error) {
+	nBits := priv.N.BitLen()
+	em, err := emsaPSSEncode(hashed, nBits-1, salt, hash.New())
+	if err != nil {
+		return
+	}
+	m := new(big.Int).SetBytes(em)
+	c, err := decrypt(rand, priv, m)
+	if err != nil {
+		return
+	}
+	s = make([]byte, (nBits+7)/8)
+	copyWithLeftPad(s, c.Bytes())
+	return
+}
+
+const (
+	// PSSSaltLengthAuto causes the salt in a PSS signature to be as large
+	// as possible when signing, and to be auto-detected when verifying.
+	PSSSaltLengthAuto = 0
+	// PSSSaltLengthEqualsHash causes the salt length to equal the length
+	// of the hash used in the signature.
+	PSSSaltLengthEqualsHash = -1
+)
+
+// PSSOptions contains options for creating and verifying PSS signatures.
+type PSSOptions struct {
+	// SaltLength controls the length of the salt used in the PSS
+	// signature. It can either be a number of bytes, or one of the special
+	// PSSSaltLength constants.
+	SaltLength int
+
+	// Hash, if not zero, overrides the hash function passed to SignPSS.
+	// This is the only way to specify the hash function when using the
+	// crypto.Signer interface.
+	Hash crypto.Hash
+}
+
+// HashFunc returns pssOpts.Hash so that PSSOptions implements
+// crypto.SignerOpts.
+func (pssOpts *PSSOptions) HashFunc() crypto.Hash {
+	return pssOpts.Hash
+}
+
+func (opts *PSSOptions) saltLength() int {
+	if opts == nil {
+		return PSSSaltLengthAuto
+	}
+	return opts.SaltLength
+}
+
+// SignPSS calculates the signature of hashed using RSASSA-PSS [1].
+// Note that hashed must be the result of hashing the input message using the
+// given hash function. The opts argument may be nil, in which case sensible
+// defaults are used.
+func SignPSS(rand io.Reader, priv *PrivateKey, hash crypto.Hash, hashed []byte, opts *PSSOptions) (s []byte, err error) {
+	saltLength := opts.saltLength()
+	switch saltLength {
+	case PSSSaltLengthAuto:
+		saltLength = (priv.N.BitLen()+7)/8 - 2 - hash.Size()
+	case PSSSaltLengthEqualsHash:
+		saltLength = hash.Size()
+	}
+
+	if opts.Hash != 0 {
+		hash = opts.Hash
+	}
+
+	salt := make([]byte, saltLength)
+	if _, err = io.ReadFull(rand, salt); err != nil {
+		return
+	}
+	return signPSSWithSalt(rand, priv, hash, hashed, salt)
+}
+
+// VerifyPSS verifies a PSS signature.
+// hashed is the result of hashing the input message using the given hash
+// function and sig is the signature. A valid signature is indicated by
+// returning a nil error. The opts argument may be nil, in which case sensible
+// defaults are used.
+func VerifyPSS(pub *PublicKey, hash crypto.Hash, hashed []byte, sig []byte, opts *PSSOptions) error {
+	return verifyPSS(pub, hash, hashed, sig, opts.saltLength())
+}
+
+// verifyPSS verifies a PSS signature with the given salt length.
+func verifyPSS(pub *PublicKey, hash crypto.Hash, hashed []byte, sig []byte, saltLen int) error {
+	nBits := pub.N.BitLen()
+	if len(sig) != (nBits+7)/8 {
+		return ErrVerification
+	}
+	s := new(big.Int).SetBytes(sig)
+	m := encrypt(new(big.Int), pub, s)
+	emBits := nBits - 1
+	emLen := (emBits + 7) / 8
+	if emLen < len(m.Bytes()) {
+		return ErrVerification
+	}
+	em := make([]byte, emLen)
+	copyWithLeftPad(em, m.Bytes())
+	if saltLen == PSSSaltLengthEqualsHash {
+		saltLen = hash.Size()
+	}
+	return emsaPSSVerify(hashed, em, emBits, saltLen, hash.New())
+}
diff --git a/src/pkg/crypto/rsa/pss_test.go b/src/crypto/rsa/pss_test.go
similarity index 100%
rename from src/pkg/crypto/rsa/pss_test.go
rename to src/crypto/rsa/pss_test.go
diff --git a/src/crypto/rsa/rsa.go b/src/crypto/rsa/rsa.go
new file mode 100644
index 0000000..2702311
--- /dev/null
+++ b/src/crypto/rsa/rsa.go
@@ -0,0 +1,557 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package rsa implements RSA encryption as specified in PKCS#1.
+package rsa
+
+import (
+	"crypto"
+	"crypto/rand"
+	"crypto/subtle"
+	"errors"
+	"hash"
+	"io"
+	"math/big"
+)
+
+var bigZero = big.NewInt(0)
+var bigOne = big.NewInt(1)
+
+// A PublicKey represents the public part of an RSA key.
+type PublicKey struct {
+	N *big.Int // modulus
+	E int      // public exponent
+}
+
+var (
+	errPublicModulus       = errors.New("crypto/rsa: missing public modulus")
+	errPublicExponentSmall = errors.New("crypto/rsa: public exponent too small")
+	errPublicExponentLarge = errors.New("crypto/rsa: public exponent too large")
+)
+
+// checkPub sanity checks the public key before we use it.
+// We require pub.E to fit into a 32-bit integer so that we
+// do not have different behavior depending on whether
+// int is 32 or 64 bits. See also
+// http://www.imperialviolet.org/2012/03/16/rsae.html.
+func checkPub(pub *PublicKey) error {
+	if pub.N == nil {
+		return errPublicModulus
+	}
+	if pub.E < 2 {
+		return errPublicExponentSmall
+	}
+	if pub.E > 1<<31-1 {
+		return errPublicExponentLarge
+	}
+	return nil
+}
+
+// A PrivateKey represents an RSA key
+type PrivateKey struct {
+	PublicKey            // public part.
+	D         *big.Int   // private exponent
+	Primes    []*big.Int // prime factors of N, has >= 2 elements.
+
+	// Precomputed contains precomputed values that speed up private
+	// operations, if available.
+	Precomputed PrecomputedValues
+}
+
+// Public returns the public key corresponding to priv.
+func (priv *PrivateKey) Public() crypto.PublicKey {
+	return &priv.PublicKey
+}
+
+// Sign signs msg with priv, reading randomness from rand. If opts is a
+// *PSSOptions then the PSS algorithm will be used, otherwise PKCS#1 v1.5 will
+// be used. This method is intended to support keys where the private part is
+// kept in, for example, a hardware module. Common uses should use the Sign*
+// functions in this package.
+func (priv *PrivateKey) Sign(rand io.Reader, msg []byte, opts crypto.SignerOpts) ([]byte, error) {
+	if pssOpts, ok := opts.(*PSSOptions); ok {
+		return SignPSS(rand, priv, pssOpts.Hash, msg, pssOpts)
+	}
+
+	return SignPKCS1v15(rand, priv, opts.HashFunc(), msg)
+}
+
+type PrecomputedValues struct {
+	Dp, Dq *big.Int // D mod (P-1) (or mod Q-1)
+	Qinv   *big.Int // Q^-1 mod P
+
+	// CRTValues is used for the 3rd and subsequent primes. Due to a
+	// historical accident, the CRT for the first two primes is handled
+	// differently in PKCS#1 and interoperability is sufficiently
+	// important that we mirror this.
+	CRTValues []CRTValue
+}
+
+// CRTValue contains the precomputed chinese remainder theorem values.
+type CRTValue struct {
+	Exp   *big.Int // D mod (prime-1).
+	Coeff *big.Int // R·Coeff ≡ 1 mod Prime.
+	R     *big.Int // product of primes prior to this (inc p and q).
+}
+
+// Validate performs basic sanity checks on the key.
+// It returns nil if the key is valid, or else an error describing a problem.
+func (priv *PrivateKey) Validate() error {
+	if err := checkPub(&priv.PublicKey); err != nil {
+		return err
+	}
+
+	// Check that the prime factors are actually prime. Note that this is
+	// just a sanity check. Since the random witnesses chosen by
+	// ProbablyPrime are deterministic, given the candidate number, it's
+	// easy for an attack to generate composites that pass this test.
+	for _, prime := range priv.Primes {
+		if !prime.ProbablyPrime(20) {
+			return errors.New("crypto/rsa: prime factor is composite")
+		}
+	}
+
+	// Check that Πprimes == n.
+	modulus := new(big.Int).Set(bigOne)
+	for _, prime := range priv.Primes {
+		modulus.Mul(modulus, prime)
+	}
+	if modulus.Cmp(priv.N) != 0 {
+		return errors.New("crypto/rsa: invalid modulus")
+	}
+
+	// Check that de ≡ 1 mod p-1, for each prime.
+	// This implies that e is coprime to each p-1 as e has a multiplicative
+	// inverse. Therefore e is coprime to lcm(p-1,q-1,r-1,...) =
+	// exponent(ℤ/nℤ). It also implies that a^de ≡ a mod p as a^(p-1) ≡ 1
+	// mod p. Thus a^de ≡ a mod n for all a coprime to n, as required.
+	congruence := new(big.Int)
+	de := new(big.Int).SetInt64(int64(priv.E))
+	de.Mul(de, priv.D)
+	for _, prime := range priv.Primes {
+		pminus1 := new(big.Int).Sub(prime, bigOne)
+		congruence.Mod(de, pminus1)
+		if congruence.Cmp(bigOne) != 0 {
+			return errors.New("crypto/rsa: invalid exponents")
+		}
+	}
+	return nil
+}
+
+// GenerateKey generates an RSA keypair of the given bit size using the
+// random source random (for example, crypto/rand.Reader).
+func GenerateKey(random io.Reader, bits int) (priv *PrivateKey, err error) {
+	return GenerateMultiPrimeKey(random, 2, bits)
+}
+
+// GenerateMultiPrimeKey generates a multi-prime RSA keypair of the given bit
+// size and the given random source, as suggested in [1]. Although the public
+// keys are compatible (actually, indistinguishable) from the 2-prime case,
+// the private keys are not. Thus it may not be possible to export multi-prime
+// private keys in certain formats or to subsequently import them into other
+// code.
+//
+// Table 1 in [2] suggests maximum numbers of primes for a given size.
+//
+// [1] US patent 4405829 (1972, expired)
+// [2] http://www.cacr.math.uwaterloo.ca/techreports/2006/cacr2006-16.pdf
+func GenerateMultiPrimeKey(random io.Reader, nprimes int, bits int) (priv *PrivateKey, err error) {
+	priv = new(PrivateKey)
+	priv.E = 65537
+
+	if nprimes < 2 {
+		return nil, errors.New("crypto/rsa: GenerateMultiPrimeKey: nprimes must be >= 2")
+	}
+
+	primes := make([]*big.Int, nprimes)
+
+NextSetOfPrimes:
+	for {
+		todo := bits
+		// crypto/rand should set the top two bits in each prime.
+		// Thus each prime has the form
+		//   p_i = 2^bitlen(p_i) × 0.11... (in base 2).
+		// And the product is:
+		//   P = 2^todo × α
+		// where α is the product of nprimes numbers of the form 0.11...
+		//
+		// If α < 1/2 (which can happen for nprimes > 2), we need to
+		// shift todo to compensate for lost bits: the mean value of 0.11...
+		// is 7/8, so todo + shift - nprimes * log2(7/8) ~= bits - 1/2
+		// will give good results.
+		if nprimes >= 7 {
+			todo += (nprimes - 2) / 5
+		}
+		for i := 0; i < nprimes; i++ {
+			primes[i], err = rand.Prime(random, todo/(nprimes-i))
+			if err != nil {
+				return nil, err
+			}
+			todo -= primes[i].BitLen()
+		}
+
+		// Make sure that primes is pairwise unequal.
+		for i, prime := range primes {
+			for j := 0; j < i; j++ {
+				if prime.Cmp(primes[j]) == 0 {
+					continue NextSetOfPrimes
+				}
+			}
+		}
+
+		n := new(big.Int).Set(bigOne)
+		totient := new(big.Int).Set(bigOne)
+		pminus1 := new(big.Int)
+		for _, prime := range primes {
+			n.Mul(n, prime)
+			pminus1.Sub(prime, bigOne)
+			totient.Mul(totient, pminus1)
+		}
+		if n.BitLen() != bits {
+			// This should never happen for nprimes == 2 because
+			// crypto/rand should set the top two bits in each prime.
+			// For nprimes > 2 we hope it does not happen often.
+			continue NextSetOfPrimes
+		}
+
+		g := new(big.Int)
+		priv.D = new(big.Int)
+		y := new(big.Int)
+		e := big.NewInt(int64(priv.E))
+		g.GCD(priv.D, y, e, totient)
+
+		if g.Cmp(bigOne) == 0 {
+			if priv.D.Sign() < 0 {
+				priv.D.Add(priv.D, totient)
+			}
+			priv.Primes = primes
+			priv.N = n
+
+			break
+		}
+	}
+
+	priv.Precompute()
+	return
+}
+
+// incCounter increments a four byte, big-endian counter.
+func incCounter(c *[4]byte) {
+	if c[3]++; c[3] != 0 {
+		return
+	}
+	if c[2]++; c[2] != 0 {
+		return
+	}
+	if c[1]++; c[1] != 0 {
+		return
+	}
+	c[0]++
+}
+
+// mgf1XOR XORs the bytes in out with a mask generated using the MGF1 function
+// specified in PKCS#1 v2.1.
+func mgf1XOR(out []byte, hash hash.Hash, seed []byte) {
+	var counter [4]byte
+	var digest []byte
+
+	done := 0
+	for done < len(out) {
+		hash.Write(seed)
+		hash.Write(counter[0:4])
+		digest = hash.Sum(digest[:0])
+		hash.Reset()
+
+		for i := 0; i < len(digest) && done < len(out); i++ {
+			out[done] ^= digest[i]
+			done++
+		}
+		incCounter(&counter)
+	}
+}
+
+// ErrMessageTooLong is returned when attempting to encrypt a message which is
+// too large for the size of the public key.
+var ErrMessageTooLong = errors.New("crypto/rsa: message too long for RSA public key size")
+
+func encrypt(c *big.Int, pub *PublicKey, m *big.Int) *big.Int {
+	e := big.NewInt(int64(pub.E))
+	c.Exp(m, e, pub.N)
+	return c
+}
+
+// EncryptOAEP encrypts the given message with RSA-OAEP.
+// The message must be no longer than the length of the public modulus less
+// twice the hash length plus 2.
+func EncryptOAEP(hash hash.Hash, random io.Reader, pub *PublicKey, msg []byte, label []byte) (out []byte, err error) {
+	if err := checkPub(pub); err != nil {
+		return nil, err
+	}
+	hash.Reset()
+	k := (pub.N.BitLen() + 7) / 8
+	if len(msg) > k-2*hash.Size()-2 {
+		err = ErrMessageTooLong
+		return
+	}
+
+	hash.Write(label)
+	lHash := hash.Sum(nil)
+	hash.Reset()
+
+	em := make([]byte, k)
+	seed := em[1 : 1+hash.Size()]
+	db := em[1+hash.Size():]
+
+	copy(db[0:hash.Size()], lHash)
+	db[len(db)-len(msg)-1] = 1
+	copy(db[len(db)-len(msg):], msg)
+
+	_, err = io.ReadFull(random, seed)
+	if err != nil {
+		return
+	}
+
+	mgf1XOR(db, hash, seed)
+	mgf1XOR(seed, hash, db)
+
+	m := new(big.Int)
+	m.SetBytes(em)
+	c := encrypt(new(big.Int), pub, m)
+	out = c.Bytes()
+
+	if len(out) < k {
+		// If the output is too small, we need to left-pad with zeros.
+		t := make([]byte, k)
+		copy(t[k-len(out):], out)
+		out = t
+	}
+
+	return
+}
+
+// ErrDecryption represents a failure to decrypt a message.
+// It is deliberately vague to avoid adaptive attacks.
+var ErrDecryption = errors.New("crypto/rsa: decryption error")
+
+// ErrVerification represents a failure to verify a signature.
+// It is deliberately vague to avoid adaptive attacks.
+var ErrVerification = errors.New("crypto/rsa: verification error")
+
+// modInverse returns ia, the inverse of a in the multiplicative group of prime
+// order n. It requires that a be a member of the group (i.e. less than n).
+func modInverse(a, n *big.Int) (ia *big.Int, ok bool) {
+	g := new(big.Int)
+	x := new(big.Int)
+	y := new(big.Int)
+	g.GCD(x, y, a, n)
+	if g.Cmp(bigOne) != 0 {
+		// In this case, a and n aren't coprime and we cannot calculate
+		// the inverse. This happens because the values of n are nearly
+		// prime (being the product of two primes) rather than truly
+		// prime.
+		return
+	}
+
+	if x.Cmp(bigOne) < 0 {
+		// 0 is not the multiplicative inverse of any element so, if x
+		// < 1, then x is negative.
+		x.Add(x, n)
+	}
+
+	return x, true
+}
+
+// Precompute performs some calculations that speed up private key operations
+// in the future.
+func (priv *PrivateKey) Precompute() {
+	if priv.Precomputed.Dp != nil {
+		return
+	}
+
+	priv.Precomputed.Dp = new(big.Int).Sub(priv.Primes[0], bigOne)
+	priv.Precomputed.Dp.Mod(priv.D, priv.Precomputed.Dp)
+
+	priv.Precomputed.Dq = new(big.Int).Sub(priv.Primes[1], bigOne)
+	priv.Precomputed.Dq.Mod(priv.D, priv.Precomputed.Dq)
+
+	priv.Precomputed.Qinv = new(big.Int).ModInverse(priv.Primes[1], priv.Primes[0])
+
+	r := new(big.Int).Mul(priv.Primes[0], priv.Primes[1])
+	priv.Precomputed.CRTValues = make([]CRTValue, len(priv.Primes)-2)
+	for i := 2; i < len(priv.Primes); i++ {
+		prime := priv.Primes[i]
+		values := &priv.Precomputed.CRTValues[i-2]
+
+		values.Exp = new(big.Int).Sub(prime, bigOne)
+		values.Exp.Mod(priv.D, values.Exp)
+
+		values.R = new(big.Int).Set(r)
+		values.Coeff = new(big.Int).ModInverse(r, prime)
+
+		r.Mul(r, prime)
+	}
+}
+
+// decrypt performs an RSA decryption, resulting in a plaintext integer. If a
+// random source is given, RSA blinding is used.
+func decrypt(random io.Reader, priv *PrivateKey, c *big.Int) (m *big.Int, err error) {
+	// TODO(agl): can we get away with reusing blinds?
+	if c.Cmp(priv.N) > 0 {
+		err = ErrDecryption
+		return
+	}
+
+	var ir *big.Int
+	if random != nil {
+		// Blinding enabled. Blinding involves multiplying c by r^e.
+		// Then the decryption operation performs (m^e * r^e)^d mod n
+		// which equals mr mod n. The factor of r can then be removed
+		// by multiplying by the multiplicative inverse of r.
+
+		var r *big.Int
+
+		for {
+			r, err = rand.Int(random, priv.N)
+			if err != nil {
+				return
+			}
+			if r.Cmp(bigZero) == 0 {
+				r = bigOne
+			}
+			var ok bool
+			ir, ok = modInverse(r, priv.N)
+			if ok {
+				break
+			}
+		}
+		bigE := big.NewInt(int64(priv.E))
+		rpowe := new(big.Int).Exp(r, bigE, priv.N)
+		cCopy := new(big.Int).Set(c)
+		cCopy.Mul(cCopy, rpowe)
+		cCopy.Mod(cCopy, priv.N)
+		c = cCopy
+	}
+
+	if priv.Precomputed.Dp == nil {
+		m = new(big.Int).Exp(c, priv.D, priv.N)
+	} else {
+		// We have the precalculated values needed for the CRT.
+		m = new(big.Int).Exp(c, priv.Precomputed.Dp, priv.Primes[0])
+		m2 := new(big.Int).Exp(c, priv.Precomputed.Dq, priv.Primes[1])
+		m.Sub(m, m2)
+		if m.Sign() < 0 {
+			m.Add(m, priv.Primes[0])
+		}
+		m.Mul(m, priv.Precomputed.Qinv)
+		m.Mod(m, priv.Primes[0])
+		m.Mul(m, priv.Primes[1])
+		m.Add(m, m2)
+
+		for i, values := range priv.Precomputed.CRTValues {
+			prime := priv.Primes[2+i]
+			m2.Exp(c, values.Exp, prime)
+			m2.Sub(m2, m)
+			m2.Mul(m2, values.Coeff)
+			m2.Mod(m2, prime)
+			if m2.Sign() < 0 {
+				m2.Add(m2, prime)
+			}
+			m2.Mul(m2, values.R)
+			m.Add(m, m2)
+		}
+	}
+
+	if ir != nil {
+		// Unblind.
+		m.Mul(m, ir)
+		m.Mod(m, priv.N)
+	}
+
+	return
+}
+
+// DecryptOAEP decrypts ciphertext using RSA-OAEP.
+// If random != nil, DecryptOAEP uses RSA blinding to avoid timing side-channel attacks.
+func DecryptOAEP(hash hash.Hash, random io.Reader, priv *PrivateKey, ciphertext []byte, label []byte) (msg []byte, err error) {
+	if err := checkPub(&priv.PublicKey); err != nil {
+		return nil, err
+	}
+	k := (priv.N.BitLen() + 7) / 8
+	if len(ciphertext) > k ||
+		k < hash.Size()*2+2 {
+		err = ErrDecryption
+		return
+	}
+
+	c := new(big.Int).SetBytes(ciphertext)
+
+	m, err := decrypt(random, priv, c)
+	if err != nil {
+		return
+	}
+
+	hash.Write(label)
+	lHash := hash.Sum(nil)
+	hash.Reset()
+
+	// Converting the plaintext number to bytes will strip any
+	// leading zeros so we may have to left pad. We do this unconditionally
+	// to avoid leaking timing information. (Although we still probably
+	// leak the number of leading zeros. It's not clear that we can do
+	// anything about this.)
+	em := leftPad(m.Bytes(), k)
+
+	firstByteIsZero := subtle.ConstantTimeByteEq(em[0], 0)
+
+	seed := em[1 : hash.Size()+1]
+	db := em[hash.Size()+1:]
+
+	mgf1XOR(seed, hash, db)
+	mgf1XOR(db, hash, seed)
+
+	lHash2 := db[0:hash.Size()]
+
+	// We have to validate the plaintext in constant time in order to avoid
+	// attacks like: J. Manger. A Chosen Ciphertext Attack on RSA Optimal
+	// Asymmetric Encryption Padding (OAEP) as Standardized in PKCS #1
+	// v2.0. In J. Kilian, editor, Advances in Cryptology.
+	lHash2Good := subtle.ConstantTimeCompare(lHash, lHash2)
+
+	// The remainder of the plaintext must be zero or more 0x00, followed
+	// by 0x01, followed by the message.
+	//   lookingForIndex: 1 iff we are still looking for the 0x01
+	//   index: the offset of the first 0x01 byte
+	//   invalid: 1 iff we saw a non-zero byte before the 0x01.
+	var lookingForIndex, index, invalid int
+	lookingForIndex = 1
+	rest := db[hash.Size():]
+
+	for i := 0; i < len(rest); i++ {
+		equals0 := subtle.ConstantTimeByteEq(rest[i], 0)
+		equals1 := subtle.ConstantTimeByteEq(rest[i], 1)
+		index = subtle.ConstantTimeSelect(lookingForIndex&equals1, i, index)
+		lookingForIndex = subtle.ConstantTimeSelect(equals1, 0, lookingForIndex)
+		invalid = subtle.ConstantTimeSelect(lookingForIndex&^equals0, 1, invalid)
+	}
+
+	if firstByteIsZero&lHash2Good&^invalid&^lookingForIndex != 1 {
+		err = ErrDecryption
+		return
+	}
+
+	msg = rest[index+1:]
+	return
+}
+
+// leftPad returns a new slice of length size. The contents of input are right
+// aligned in the new slice.
+func leftPad(input []byte, size int) (out []byte) {
+	n := len(input)
+	if n > size {
+		n = size
+	}
+	out = make([]byte, size)
+	copy(out[len(out)-n:], input)
+	return
+}
diff --git a/src/pkg/crypto/rsa/rsa_test.go b/src/crypto/rsa/rsa_test.go
similarity index 100%
rename from src/pkg/crypto/rsa/rsa_test.go
rename to src/crypto/rsa/rsa_test.go
diff --git a/src/pkg/crypto/rsa/testdata/pss-vect.txt.bz2 b/src/crypto/rsa/testdata/pss-vect.txt.bz2
similarity index 100%
rename from src/pkg/crypto/rsa/testdata/pss-vect.txt.bz2
rename to src/crypto/rsa/testdata/pss-vect.txt.bz2
diff --git a/src/pkg/crypto/sha1/example_test.go b/src/crypto/sha1/example_test.go
similarity index 100%
rename from src/pkg/crypto/sha1/example_test.go
rename to src/crypto/sha1/example_test.go
diff --git a/src/pkg/crypto/sha1/sha1.go b/src/crypto/sha1/sha1.go
similarity index 100%
rename from src/pkg/crypto/sha1/sha1.go
rename to src/crypto/sha1/sha1.go
diff --git a/src/pkg/crypto/sha1/sha1_test.go b/src/crypto/sha1/sha1_test.go
similarity index 100%
rename from src/pkg/crypto/sha1/sha1_test.go
rename to src/crypto/sha1/sha1_test.go
diff --git a/src/pkg/crypto/sha1/sha1block.go b/src/crypto/sha1/sha1block.go
similarity index 100%
rename from src/pkg/crypto/sha1/sha1block.go
rename to src/crypto/sha1/sha1block.go
diff --git a/src/crypto/sha1/sha1block_386.s b/src/crypto/sha1/sha1block_386.s
new file mode 100644
index 0000000..a0adabc
--- /dev/null
+++ b/src/crypto/sha1/sha1block_386.s
@@ -0,0 +1,233 @@
+// Copyright 2013 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+// SHA1 block routine. See sha1block.go for Go equivalent.
+//
+// There are 80 rounds of 4 types:
+//   - rounds 0-15 are type 1 and load data (ROUND1 macro).
+//   - rounds 16-19 are type 1 and do not load data (ROUND1x macro).
+//   - rounds 20-39 are type 2 and do not load data (ROUND2 macro).
+//   - rounds 40-59 are type 3 and do not load data (ROUND3 macro).
+//   - rounds 60-79 are type 4 and do not load data (ROUND4 macro).
+//
+// Each round loads or shuffles the data, then computes a per-round
+// function of b, c, d, and then mixes the result into and rotates the
+// five registers a, b, c, d, e holding the intermediate results.
+//
+// The register rotation is implemented by rotating the arguments to
+// the round macros instead of by explicit move instructions.
+
+// Like sha1block_amd64.s, but we keep the data and limit pointers on the stack.
+// To free up the word pointer (R10 on amd64, DI here), we add it to e during
+// LOAD/SHUFFLE instead of during MIX.
+//
+// The stack holds the intermediate word array - 16 uint32s - at 0(SP) up to 64(SP).
+// The saved a, b, c, d, e (R11 through R15 on amd64) are at 64(SP) up to 84(SP).
+// The saved limit pointer (DI on amd64) is at 84(SP).
+// The saved data pointer (SI on amd64) is at 88(SP).
+
+#define LOAD(index, e) \
+	MOVL	88(SP), SI; \
+	MOVL	(index*4)(SI), DI; \
+	BSWAPL	DI; \
+	MOVL	DI, (index*4)(SP); \
+	ADDL	DI, e
+
+#define SHUFFLE(index, e) \
+	MOVL	(((index)&0xf)*4)(SP), DI; \
+	XORL	(((index-3)&0xf)*4)(SP), DI; \
+	XORL	(((index-8)&0xf)*4)(SP), DI; \
+	XORL	(((index-14)&0xf)*4)(SP), DI; \
+	ROLL	$1, DI; \
+	MOVL	DI, (((index)&0xf)*4)(SP); \
+	ADDL	DI, e
+
+#define FUNC1(a, b, c, d, e) \
+	MOVL	d, DI; \
+	XORL	c, DI; \
+	ANDL	b, DI; \
+	XORL	d, DI
+
+#define FUNC2(a, b, c, d, e) \
+	MOVL	b, DI; \
+	XORL	c, DI; \
+	XORL	d, DI
+
+#define FUNC3(a, b, c, d, e) \
+	MOVL	b, SI; \
+	ORL	c, SI; \
+	ANDL	d, SI; \
+	MOVL	b, DI; \
+	ANDL	c, DI; \
+	ORL	SI, DI
+
+#define FUNC4 FUNC2
+
+#define MIX(a, b, c, d, e, const) \
+	ROLL	$30, b; \
+	ADDL	DI, e; \
+	MOVL	a, SI; \
+	ROLL	$5, SI; \
+	LEAL	const(e)(SI*1), e
+
+#define ROUND1(a, b, c, d, e, index) \
+	LOAD(index, e); \
+	FUNC1(a, b, c, d, e); \
+	MIX(a, b, c, d, e, 0x5A827999)
+
+#define ROUND1x(a, b, c, d, e, index) \
+	SHUFFLE(index, e); \
+	FUNC1(a, b, c, d, e); \
+	MIX(a, b, c, d, e, 0x5A827999)
+
+#define ROUND2(a, b, c, d, e, index) \
+	SHUFFLE(index, e); \
+	FUNC2(a, b, c, d, e); \
+	MIX(a, b, c, d, e, 0x6ED9EBA1)
+
+#define ROUND3(a, b, c, d, e, index) \
+	SHUFFLE(index, e); \
+	FUNC3(a, b, c, d, e); \
+	MIX(a, b, c, d, e, 0x8F1BBCDC)
+
+#define ROUND4(a, b, c, d, e, index) \
+	SHUFFLE(index, e); \
+	FUNC4(a, b, c, d, e); \
+	MIX(a, b, c, d, e, 0xCA62C1D6)
+
+// func block(dig *digest, p []byte)
+TEXT ·block(SB),NOSPLIT,$92-16
+	MOVL	dig+0(FP),	BP
+	MOVL	p+4(FP),	SI
+	MOVL	p_len+8(FP),	DX
+	SHRL	$6,		DX
+	SHLL	$6,		DX
+	
+	LEAL	(SI)(DX*1),	DI
+	MOVL	(0*4)(BP),	AX
+	MOVL	(1*4)(BP),	BX
+	MOVL	(2*4)(BP),	CX
+	MOVL	(3*4)(BP),	DX
+	MOVL	(4*4)(BP),	BP
+
+	CMPL	SI,		DI
+	JEQ	end
+
+	MOVL	DI,	84(SP)
+
+loop:
+	MOVL	SI,	88(SP)
+
+	MOVL	AX,	64(SP)
+	MOVL	BX,	68(SP)
+	MOVL	CX,	72(SP)
+	MOVL	DX,	76(SP)
+	MOVL	BP,	80(SP)
+
+	ROUND1(AX, BX, CX, DX, BP, 0)
+	ROUND1(BP, AX, BX, CX, DX, 1)
+	ROUND1(DX, BP, AX, BX, CX, 2)
+	ROUND1(CX, DX, BP, AX, BX, 3)
+	ROUND1(BX, CX, DX, BP, AX, 4)
+	ROUND1(AX, BX, CX, DX, BP, 5)
+	ROUND1(BP, AX, BX, CX, DX, 6)
+	ROUND1(DX, BP, AX, BX, CX, 7)
+	ROUND1(CX, DX, BP, AX, BX, 8)
+	ROUND1(BX, CX, DX, BP, AX, 9)
+	ROUND1(AX, BX, CX, DX, BP, 10)
+	ROUND1(BP, AX, BX, CX, DX, 11)
+	ROUND1(DX, BP, AX, BX, CX, 12)
+	ROUND1(CX, DX, BP, AX, BX, 13)
+	ROUND1(BX, CX, DX, BP, AX, 14)
+	ROUND1(AX, BX, CX, DX, BP, 15)
+
+	ROUND1x(BP, AX, BX, CX, DX, 16)
+	ROUND1x(DX, BP, AX, BX, CX, 17)
+	ROUND1x(CX, DX, BP, AX, BX, 18)
+	ROUND1x(BX, CX, DX, BP, AX, 19)
+	
+	ROUND2(AX, BX, CX, DX, BP, 20)
+	ROUND2(BP, AX, BX, CX, DX, 21)
+	ROUND2(DX, BP, AX, BX, CX, 22)
+	ROUND2(CX, DX, BP, AX, BX, 23)
+	ROUND2(BX, CX, DX, BP, AX, 24)
+	ROUND2(AX, BX, CX, DX, BP, 25)
+	ROUND2(BP, AX, BX, CX, DX, 26)
+	ROUND2(DX, BP, AX, BX, CX, 27)
+	ROUND2(CX, DX, BP, AX, BX, 28)
+	ROUND2(BX, CX, DX, BP, AX, 29)
+	ROUND2(AX, BX, CX, DX, BP, 30)
+	ROUND2(BP, AX, BX, CX, DX, 31)
+	ROUND2(DX, BP, AX, BX, CX, 32)
+	ROUND2(CX, DX, BP, AX, BX, 33)
+	ROUND2(BX, CX, DX, BP, AX, 34)
+	ROUND2(AX, BX, CX, DX, BP, 35)
+	ROUND2(BP, AX, BX, CX, DX, 36)
+	ROUND2(DX, BP, AX, BX, CX, 37)
+	ROUND2(CX, DX, BP, AX, BX, 38)
+	ROUND2(BX, CX, DX, BP, AX, 39)
+	
+	ROUND3(AX, BX, CX, DX, BP, 40)
+	ROUND3(BP, AX, BX, CX, DX, 41)
+	ROUND3(DX, BP, AX, BX, CX, 42)
+	ROUND3(CX, DX, BP, AX, BX, 43)
+	ROUND3(BX, CX, DX, BP, AX, 44)
+	ROUND3(AX, BX, CX, DX, BP, 45)
+	ROUND3(BP, AX, BX, CX, DX, 46)
+	ROUND3(DX, BP, AX, BX, CX, 47)
+	ROUND3(CX, DX, BP, AX, BX, 48)
+	ROUND3(BX, CX, DX, BP, AX, 49)
+	ROUND3(AX, BX, CX, DX, BP, 50)
+	ROUND3(BP, AX, BX, CX, DX, 51)
+	ROUND3(DX, BP, AX, BX, CX, 52)
+	ROUND3(CX, DX, BP, AX, BX, 53)
+	ROUND3(BX, CX, DX, BP, AX, 54)
+	ROUND3(AX, BX, CX, DX, BP, 55)
+	ROUND3(BP, AX, BX, CX, DX, 56)
+	ROUND3(DX, BP, AX, BX, CX, 57)
+	ROUND3(CX, DX, BP, AX, BX, 58)
+	ROUND3(BX, CX, DX, BP, AX, 59)
+	
+	ROUND4(AX, BX, CX, DX, BP, 60)
+	ROUND4(BP, AX, BX, CX, DX, 61)
+	ROUND4(DX, BP, AX, BX, CX, 62)
+	ROUND4(CX, DX, BP, AX, BX, 63)
+	ROUND4(BX, CX, DX, BP, AX, 64)
+	ROUND4(AX, BX, CX, DX, BP, 65)
+	ROUND4(BP, AX, BX, CX, DX, 66)
+	ROUND4(DX, BP, AX, BX, CX, 67)
+	ROUND4(CX, DX, BP, AX, BX, 68)
+	ROUND4(BX, CX, DX, BP, AX, 69)
+	ROUND4(AX, BX, CX, DX, BP, 70)
+	ROUND4(BP, AX, BX, CX, DX, 71)
+	ROUND4(DX, BP, AX, BX, CX, 72)
+	ROUND4(CX, DX, BP, AX, BX, 73)
+	ROUND4(BX, CX, DX, BP, AX, 74)
+	ROUND4(AX, BX, CX, DX, BP, 75)
+	ROUND4(BP, AX, BX, CX, DX, 76)
+	ROUND4(DX, BP, AX, BX, CX, 77)
+	ROUND4(CX, DX, BP, AX, BX, 78)
+	ROUND4(BX, CX, DX, BP, AX, 79)
+
+	ADDL	64(SP), AX
+	ADDL	68(SP), BX
+	ADDL	72(SP), CX
+	ADDL	76(SP), DX
+	ADDL	80(SP), BP
+
+	MOVL	88(SP), SI
+	ADDL	$64, SI
+	CMPL	SI, 84(SP)
+	JB	loop
+
+end:
+	MOVL	dig+0(FP), DI
+	MOVL	AX, (0*4)(DI)
+	MOVL	BX, (1*4)(DI)
+	MOVL	CX, (2*4)(DI)
+	MOVL	DX, (3*4)(DI)
+	MOVL	BP, (4*4)(DI)
+	RET
diff --git a/src/crypto/sha1/sha1block_amd64.s b/src/crypto/sha1/sha1block_amd64.s
new file mode 100644
index 0000000..4319df6
--- /dev/null
+++ b/src/crypto/sha1/sha1block_amd64.s
@@ -0,0 +1,216 @@
+// Copyright 2013 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+// SHA1 block routine. See sha1block.go for Go equivalent.
+//
+// There are 80 rounds of 4 types:
+//   - rounds 0-15 are type 1 and load data (ROUND1 macro).
+//   - rounds 16-19 are type 1 and do not load data (ROUND1x macro).
+//   - rounds 20-39 are type 2 and do not load data (ROUND2 macro).
+//   - rounds 40-59 are type 3 and do not load data (ROUND3 macro).
+//   - rounds 60-79 are type 4 and do not load data (ROUND4 macro).
+//
+// Each round loads or shuffles the data, then computes a per-round
+// function of b, c, d, and then mixes the result into and rotates the
+// five registers a, b, c, d, e holding the intermediate results.
+//
+// The register rotation is implemented by rotating the arguments to
+// the round macros instead of by explicit move instructions.
+
+#define LOAD(index) \
+	MOVL	(index*4)(SI), R10; \
+	BSWAPL	R10; \
+	MOVL	R10, (index*4)(SP)
+
+#define SHUFFLE(index) \
+	MOVL	(((index)&0xf)*4)(SP), R10; \
+	XORL	(((index-3)&0xf)*4)(SP), R10; \
+	XORL	(((index-8)&0xf)*4)(SP), R10; \
+	XORL	(((index-14)&0xf)*4)(SP), R10; \
+	ROLL	$1, R10; \
+	MOVL	R10, (((index)&0xf)*4)(SP)
+
+#define FUNC1(a, b, c, d, e) \
+	MOVL	d, R9; \
+	XORL	c, R9; \
+	ANDL	b, R9; \
+	XORL	d, R9
+
+#define FUNC2(a, b, c, d, e) \
+	MOVL	b, R9; \
+	XORL	c, R9; \
+	XORL	d, R9
+
+#define FUNC3(a, b, c, d, e) \
+	MOVL	b, R8; \
+	ORL	c, R8; \
+	ANDL	d, R8; \
+	MOVL	b, R9; \
+	ANDL	c, R9; \
+	ORL	R8, R9
+	
+#define FUNC4 FUNC2
+
+#define MIX(a, b, c, d, e, const) \
+	ROLL	$30, b; \
+	ADDL	R9, e; \
+	MOVL	a, R8; \
+	ROLL	$5, R8; \
+	LEAL	const(e)(R10*1), e; \
+	ADDL	R8, e
+
+#define ROUND1(a, b, c, d, e, index) \
+	LOAD(index); \
+	FUNC1(a, b, c, d, e); \
+	MIX(a, b, c, d, e, 0x5A827999)
+
+#define ROUND1x(a, b, c, d, e, index) \
+	SHUFFLE(index); \
+	FUNC1(a, b, c, d, e); \
+	MIX(a, b, c, d, e, 0x5A827999)
+
+#define ROUND2(a, b, c, d, e, index) \
+	SHUFFLE(index); \
+	FUNC2(a, b, c, d, e); \
+	MIX(a, b, c, d, e, 0x6ED9EBA1)
+
+#define ROUND3(a, b, c, d, e, index) \
+	SHUFFLE(index); \
+	FUNC3(a, b, c, d, e); \
+	MIX(a, b, c, d, e, 0x8F1BBCDC)
+
+#define ROUND4(a, b, c, d, e, index) \
+	SHUFFLE(index); \
+	FUNC4(a, b, c, d, e); \
+	MIX(a, b, c, d, e, 0xCA62C1D6)
+
+TEXT ·block(SB),NOSPLIT,$64-32
+	MOVQ	dig+0(FP),	BP
+	MOVQ	p_base+8(FP),	SI
+	MOVQ	p_len+16(FP),	DX
+	SHRQ	$6,		DX
+	SHLQ	$6,		DX
+	
+	LEAQ	(SI)(DX*1),	DI
+	MOVL	(0*4)(BP),	AX
+	MOVL	(1*4)(BP),	BX
+	MOVL	(2*4)(BP),	CX
+	MOVL	(3*4)(BP),	DX
+	MOVL	(4*4)(BP),	BP
+
+	CMPQ	SI,		DI
+	JEQ	end
+
+loop:
+	MOVL	AX,	R11
+	MOVL	BX,	R12
+	MOVL	CX,	R13
+	MOVL	DX,	R14
+	MOVL	BP,	R15
+
+	ROUND1(AX, BX, CX, DX, BP, 0)
+	ROUND1(BP, AX, BX, CX, DX, 1)
+	ROUND1(DX, BP, AX, BX, CX, 2)
+	ROUND1(CX, DX, BP, AX, BX, 3)
+	ROUND1(BX, CX, DX, BP, AX, 4)
+	ROUND1(AX, BX, CX, DX, BP, 5)
+	ROUND1(BP, AX, BX, CX, DX, 6)
+	ROUND1(DX, BP, AX, BX, CX, 7)
+	ROUND1(CX, DX, BP, AX, BX, 8)
+	ROUND1(BX, CX, DX, BP, AX, 9)
+	ROUND1(AX, BX, CX, DX, BP, 10)
+	ROUND1(BP, AX, BX, CX, DX, 11)
+	ROUND1(DX, BP, AX, BX, CX, 12)
+	ROUND1(CX, DX, BP, AX, BX, 13)
+	ROUND1(BX, CX, DX, BP, AX, 14)
+	ROUND1(AX, BX, CX, DX, BP, 15)
+
+	ROUND1x(BP, AX, BX, CX, DX, 16)
+	ROUND1x(DX, BP, AX, BX, CX, 17)
+	ROUND1x(CX, DX, BP, AX, BX, 18)
+	ROUND1x(BX, CX, DX, BP, AX, 19)
+	
+	ROUND2(AX, BX, CX, DX, BP, 20)
+	ROUND2(BP, AX, BX, CX, DX, 21)
+	ROUND2(DX, BP, AX, BX, CX, 22)
+	ROUND2(CX, DX, BP, AX, BX, 23)
+	ROUND2(BX, CX, DX, BP, AX, 24)
+	ROUND2(AX, BX, CX, DX, BP, 25)
+	ROUND2(BP, AX, BX, CX, DX, 26)
+	ROUND2(DX, BP, AX, BX, CX, 27)
+	ROUND2(CX, DX, BP, AX, BX, 28)
+	ROUND2(BX, CX, DX, BP, AX, 29)
+	ROUND2(AX, BX, CX, DX, BP, 30)
+	ROUND2(BP, AX, BX, CX, DX, 31)
+	ROUND2(DX, BP, AX, BX, CX, 32)
+	ROUND2(CX, DX, BP, AX, BX, 33)
+	ROUND2(BX, CX, DX, BP, AX, 34)
+	ROUND2(AX, BX, CX, DX, BP, 35)
+	ROUND2(BP, AX, BX, CX, DX, 36)
+	ROUND2(DX, BP, AX, BX, CX, 37)
+	ROUND2(CX, DX, BP, AX, BX, 38)
+	ROUND2(BX, CX, DX, BP, AX, 39)
+	
+	ROUND3(AX, BX, CX, DX, BP, 40)
+	ROUND3(BP, AX, BX, CX, DX, 41)
+	ROUND3(DX, BP, AX, BX, CX, 42)
+	ROUND3(CX, DX, BP, AX, BX, 43)
+	ROUND3(BX, CX, DX, BP, AX, 44)
+	ROUND3(AX, BX, CX, DX, BP, 45)
+	ROUND3(BP, AX, BX, CX, DX, 46)
+	ROUND3(DX, BP, AX, BX, CX, 47)
+	ROUND3(CX, DX, BP, AX, BX, 48)
+	ROUND3(BX, CX, DX, BP, AX, 49)
+	ROUND3(AX, BX, CX, DX, BP, 50)
+	ROUND3(BP, AX, BX, CX, DX, 51)
+	ROUND3(DX, BP, AX, BX, CX, 52)
+	ROUND3(CX, DX, BP, AX, BX, 53)
+	ROUND3(BX, CX, DX, BP, AX, 54)
+	ROUND3(AX, BX, CX, DX, BP, 55)
+	ROUND3(BP, AX, BX, CX, DX, 56)
+	ROUND3(DX, BP, AX, BX, CX, 57)
+	ROUND3(CX, DX, BP, AX, BX, 58)
+	ROUND3(BX, CX, DX, BP, AX, 59)
+	
+	ROUND4(AX, BX, CX, DX, BP, 60)
+	ROUND4(BP, AX, BX, CX, DX, 61)
+	ROUND4(DX, BP, AX, BX, CX, 62)
+	ROUND4(CX, DX, BP, AX, BX, 63)
+	ROUND4(BX, CX, DX, BP, AX, 64)
+	ROUND4(AX, BX, CX, DX, BP, 65)
+	ROUND4(BP, AX, BX, CX, DX, 66)
+	ROUND4(DX, BP, AX, BX, CX, 67)
+	ROUND4(CX, DX, BP, AX, BX, 68)
+	ROUND4(BX, CX, DX, BP, AX, 69)
+	ROUND4(AX, BX, CX, DX, BP, 70)
+	ROUND4(BP, AX, BX, CX, DX, 71)
+	ROUND4(DX, BP, AX, BX, CX, 72)
+	ROUND4(CX, DX, BP, AX, BX, 73)
+	ROUND4(BX, CX, DX, BP, AX, 74)
+	ROUND4(AX, BX, CX, DX, BP, 75)
+	ROUND4(BP, AX, BX, CX, DX, 76)
+	ROUND4(DX, BP, AX, BX, CX, 77)
+	ROUND4(CX, DX, BP, AX, BX, 78)
+	ROUND4(BX, CX, DX, BP, AX, 79)
+
+	ADDL	R11, AX
+	ADDL	R12, BX
+	ADDL	R13, CX
+	ADDL	R14, DX
+	ADDL	R15, BP
+
+	ADDQ	$64, SI
+	CMPQ	SI, DI
+	JB	loop
+
+end:
+	MOVQ	dig+0(FP), DI
+	MOVL	AX, (0*4)(DI)
+	MOVL	BX, (1*4)(DI)
+	MOVL	CX, (2*4)(DI)
+	MOVL	DX, (3*4)(DI)
+	MOVL	BP, (4*4)(DI)
+	RET
diff --git a/src/crypto/sha1/sha1block_amd64p32.s b/src/crypto/sha1/sha1block_amd64p32.s
new file mode 100644
index 0000000..d93fbf1
--- /dev/null
+++ b/src/crypto/sha1/sha1block_amd64p32.s
@@ -0,0 +1,216 @@
+// Copyright 2013 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+// SHA1 block routine. See sha1block.go for Go equivalent.
+//
+// There are 80 rounds of 4 types:
+//   - rounds 0-15 are type 1 and load data (ROUND1 macro).
+//   - rounds 16-19 are type 1 and do not load data (ROUND1x macro).
+//   - rounds 20-39 are type 2 and do not load data (ROUND2 macro).
+//   - rounds 40-59 are type 3 and do not load data (ROUND3 macro).
+//   - rounds 60-79 are type 4 and do not load data (ROUND4 macro).
+//
+// Each round loads or shuffles the data, then computes a per-round
+// function of b, c, d, and then mixes the result into and rotates the
+// five registers a, b, c, d, e holding the intermediate results.
+//
+// The register rotation is implemented by rotating the arguments to
+// the round macros instead of by explicit move instructions.
+//
+// amd64p32 version.
+// To ensure safety for Native Client, avoids use of BP and R15
+// as well as two-register addressing modes.
+
+#define LOAD(index) \
+	MOVL	(index*4)(SI), R10; \
+	BSWAPL	R10; \
+	MOVL	R10, (index*4)(SP)
+
+#define SHUFFLE(index) \
+	MOVL	(((index)&0xf)*4)(SP), R10; \
+	XORL	(((index-3)&0xf)*4)(SP), R10; \
+	XORL	(((index-8)&0xf)*4)(SP), R10; \
+	XORL	(((index-14)&0xf)*4)(SP), R10; \
+	ROLL	$1, R10; \
+	MOVL	R10, (((index)&0xf)*4)(SP)
+
+#define FUNC1(a, b, c, d, e) \
+	MOVL	d, R9; \
+	XORL	c, R9; \
+	ANDL	b, R9; \
+	XORL	d, R9
+
+#define FUNC2(a, b, c, d, e) \
+	MOVL	b, R9; \
+	XORL	c, R9; \
+	XORL	d, R9
+
+#define FUNC3(a, b, c, d, e) \
+	MOVL	b, R8; \
+	ORL	c, R8; \
+	ANDL	d, R8; \
+	MOVL	b, R9; \
+	ANDL	c, R9; \
+	ORL	R8, R9
+	
+#define FUNC4 FUNC2
+
+#define MIX(a, b, c, d, e, const) \
+	ROLL	$30, b; \
+	ADDL	R9, e; \
+	MOVL	a, R8; \
+	ROLL	$5, R8; \
+	LEAL	const(e)(R10*1), e; \
+	ADDL	R8, e
+
+#define ROUND1(a, b, c, d, e, index) \
+	LOAD(index); \
+	FUNC1(a, b, c, d, e); \
+	MIX(a, b, c, d, e, 0x5A827999)
+
+#define ROUND1x(a, b, c, d, e, index) \
+	SHUFFLE(index); \
+	FUNC1(a, b, c, d, e); \
+	MIX(a, b, c, d, e, 0x5A827999)
+
+#define ROUND2(a, b, c, d, e, index) \
+	SHUFFLE(index); \
+	FUNC2(a, b, c, d, e); \
+	MIX(a, b, c, d, e, 0x6ED9EBA1)
+
+#define ROUND3(a, b, c, d, e, index) \
+	SHUFFLE(index); \
+	FUNC3(a, b, c, d, e); \
+	MIX(a, b, c, d, e, 0x8F1BBCDC)
+
+#define ROUND4(a, b, c, d, e, index) \
+	SHUFFLE(index); \
+	FUNC4(a, b, c, d, e); \
+	MIX(a, b, c, d, e, 0xCA62C1D6)
+
+TEXT ·block(SB),NOSPLIT,$64-32
+	MOVL	dig+0(FP),	R14
+	MOVL	p_base+4(FP),	SI
+	MOVL	p_len+8(FP),	DX
+	SHRQ	$6,		DX
+	SHLQ	$6,		DX
+	
+	LEAQ	(SI)(DX*1),	DI
+	MOVL	(0*4)(R14),	AX
+	MOVL	(1*4)(R14),	BX
+	MOVL	(2*4)(R14),	CX
+	MOVL	(3*4)(R14),	DX
+	MOVL	(4*4)(R14),	R13
+
+	CMPQ	SI,		DI
+	JEQ	end
+
+loop:
+#define BP R13 /* keep diff from sha1block_amd64.s small */
+	ROUND1(AX, BX, CX, DX, BP, 0)
+	ROUND1(BP, AX, BX, CX, DX, 1)
+	ROUND1(DX, BP, AX, BX, CX, 2)
+	ROUND1(CX, DX, BP, AX, BX, 3)
+	ROUND1(BX, CX, DX, BP, AX, 4)
+	ROUND1(AX, BX, CX, DX, BP, 5)
+	ROUND1(BP, AX, BX, CX, DX, 6)
+	ROUND1(DX, BP, AX, BX, CX, 7)
+	ROUND1(CX, DX, BP, AX, BX, 8)
+	ROUND1(BX, CX, DX, BP, AX, 9)
+	ROUND1(AX, BX, CX, DX, BP, 10)
+	ROUND1(BP, AX, BX, CX, DX, 11)
+	ROUND1(DX, BP, AX, BX, CX, 12)
+	ROUND1(CX, DX, BP, AX, BX, 13)
+	ROUND1(BX, CX, DX, BP, AX, 14)
+	ROUND1(AX, BX, CX, DX, BP, 15)
+
+	ROUND1x(BP, AX, BX, CX, DX, 16)
+	ROUND1x(DX, BP, AX, BX, CX, 17)
+	ROUND1x(CX, DX, BP, AX, BX, 18)
+	ROUND1x(BX, CX, DX, BP, AX, 19)
+	
+	ROUND2(AX, BX, CX, DX, BP, 20)
+	ROUND2(BP, AX, BX, CX, DX, 21)
+	ROUND2(DX, BP, AX, BX, CX, 22)
+	ROUND2(CX, DX, BP, AX, BX, 23)
+	ROUND2(BX, CX, DX, BP, AX, 24)
+	ROUND2(AX, BX, CX, DX, BP, 25)
+	ROUND2(BP, AX, BX, CX, DX, 26)
+	ROUND2(DX, BP, AX, BX, CX, 27)
+	ROUND2(CX, DX, BP, AX, BX, 28)
+	ROUND2(BX, CX, DX, BP, AX, 29)
+	ROUND2(AX, BX, CX, DX, BP, 30)
+	ROUND2(BP, AX, BX, CX, DX, 31)
+	ROUND2(DX, BP, AX, BX, CX, 32)
+	ROUND2(CX, DX, BP, AX, BX, 33)
+	ROUND2(BX, CX, DX, BP, AX, 34)
+	ROUND2(AX, BX, CX, DX, BP, 35)
+	ROUND2(BP, AX, BX, CX, DX, 36)
+	ROUND2(DX, BP, AX, BX, CX, 37)
+	ROUND2(CX, DX, BP, AX, BX, 38)
+	ROUND2(BX, CX, DX, BP, AX, 39)
+	
+	ROUND3(AX, BX, CX, DX, BP, 40)
+	ROUND3(BP, AX, BX, CX, DX, 41)
+	ROUND3(DX, BP, AX, BX, CX, 42)
+	ROUND3(CX, DX, BP, AX, BX, 43)
+	ROUND3(BX, CX, DX, BP, AX, 44)
+	ROUND3(AX, BX, CX, DX, BP, 45)
+	ROUND3(BP, AX, BX, CX, DX, 46)
+	ROUND3(DX, BP, AX, BX, CX, 47)
+	ROUND3(CX, DX, BP, AX, BX, 48)
+	ROUND3(BX, CX, DX, BP, AX, 49)
+	ROUND3(AX, BX, CX, DX, BP, 50)
+	ROUND3(BP, AX, BX, CX, DX, 51)
+	ROUND3(DX, BP, AX, BX, CX, 52)
+	ROUND3(CX, DX, BP, AX, BX, 53)
+	ROUND3(BX, CX, DX, BP, AX, 54)
+	ROUND3(AX, BX, CX, DX, BP, 55)
+	ROUND3(BP, AX, BX, CX, DX, 56)
+	ROUND3(DX, BP, AX, BX, CX, 57)
+	ROUND3(CX, DX, BP, AX, BX, 58)
+	ROUND3(BX, CX, DX, BP, AX, 59)
+	
+	ROUND4(AX, BX, CX, DX, BP, 60)
+	ROUND4(BP, AX, BX, CX, DX, 61)
+	ROUND4(DX, BP, AX, BX, CX, 62)
+	ROUND4(CX, DX, BP, AX, BX, 63)
+	ROUND4(BX, CX, DX, BP, AX, 64)
+	ROUND4(AX, BX, CX, DX, BP, 65)
+	ROUND4(BP, AX, BX, CX, DX, 66)
+	ROUND4(DX, BP, AX, BX, CX, 67)
+	ROUND4(CX, DX, BP, AX, BX, 68)
+	ROUND4(BX, CX, DX, BP, AX, 69)
+	ROUND4(AX, BX, CX, DX, BP, 70)
+	ROUND4(BP, AX, BX, CX, DX, 71)
+	ROUND4(DX, BP, AX, BX, CX, 72)
+	ROUND4(CX, DX, BP, AX, BX, 73)
+	ROUND4(BX, CX, DX, BP, AX, 74)
+	ROUND4(AX, BX, CX, DX, BP, 75)
+	ROUND4(BP, AX, BX, CX, DX, 76)
+	ROUND4(DX, BP, AX, BX, CX, 77)
+	ROUND4(CX, DX, BP, AX, BX, 78)
+	ROUND4(BX, CX, DX, BP, AX, 79)
+#undef BP
+
+	ADDL	(0*4)(R14), AX
+	ADDL	(1*4)(R14), BX
+	ADDL	(2*4)(R14), CX
+	ADDL	(3*4)(R14), DX
+	ADDL	(4*4)(R14), R13
+
+	MOVL	AX, (0*4)(R14)
+	MOVL	BX, (1*4)(R14)
+	MOVL	CX, (2*4)(R14)
+	MOVL	DX, (3*4)(R14)
+	MOVL	R13, (4*4)(R14)
+
+	ADDQ	$64, SI
+	CMPQ	SI, DI
+	JB	loop
+
+end:
+	RET
diff --git a/src/crypto/sha1/sha1block_arm.s b/src/crypto/sha1/sha1block_arm.s
new file mode 100644
index 0000000..f11f33d
--- /dev/null
+++ b/src/crypto/sha1/sha1block_arm.s
@@ -0,0 +1,217 @@
+// 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.
+//
+// ARM version of md5block.go
+
+#include "textflag.h"
+
+// SHA1 block routine. See sha1block.go for Go equivalent.
+//
+// There are 80 rounds of 4 types:
+//   - rounds 0-15 are type 1 and load data (ROUND1 macro).
+//   - rounds 16-19 are type 1 and do not load data (ROUND1x macro).
+//   - rounds 20-39 are type 2 and do not load data (ROUND2 macro).
+//   - rounds 40-59 are type 3 and do not load data (ROUND3 macro).
+//   - rounds 60-79 are type 4 and do not load data (ROUND4 macro).
+//
+// Each round loads or shuffles the data, then computes a per-round
+// function of b, c, d, and then mixes the result into and rotates the
+// five registers a, b, c, d, e holding the intermediate results.
+//
+// The register rotation is implemented by rotating the arguments to
+// the round macros instead of by explicit move instructions.
+
+// Register definitions
+data = 0	// Pointer to incoming data
+const = 1	// Current constant for SHA round
+a = 2		// SHA1 accumulator
+b = 3		// SHA1 accumulator
+c = 4		// SHA1 accumulator
+d = 5		// SHA1 accumulator
+e = 6		// SHA1 accumulator
+t0 = 7		// Temporary
+t1 = 8		// Temporary
+// r9, r10 are forbidden
+// r11 is OK provided you check the assembler that no synthetic instructions use it
+t2 = 11		// Temporary
+ctr = 12	// loop counter
+w = 14		// point to w buffer
+
+// func block(dig *digest, p []byte)
+// 0(FP) is *digest
+// 4(FP) is p.array (struct Slice)
+// 8(FP) is p.len
+//12(FP) is p.cap
+//
+// Stack frame
+p_end = -4		// -4(SP) pointer to the end of data
+p_data = p_end - 4	// -8(SP) current data pointer
+w_buf = p_data - 4*80	// -328(SP) 80 words temporary buffer w uint32[80]
+saved = w_buf - 4*5	// -348(SP) saved sha1 registers a,b,c,d,e - these must be last
+// Total size +4 for saved LR is 352
+
+	// w[i] = p[j]<<24 | p[j+1]<<16 | p[j+2]<<8 | p[j+3]
+	// e += w[i]
+#define LOAD(e) \
+	MOVBU	2(R(data)), R(t0) ; \
+	MOVBU	3(R(data)), R(t1) ; \
+	MOVBU	1(R(data)), R(t2) ; \
+	ORR	R(t0)<<8, R(t1), R(t0)	    ; \
+	MOVBU.P	4(R(data)), R(t1) ; \
+	ORR	R(t2)<<16, R(t0), R(t0)	    ; \
+	ORR	R(t1)<<24, R(t0), R(t0)	    ; \
+	MOVW.P	R(t0), 4(R(w))		    ; \
+	ADD	R(t0), R(e), R(e)
+	
+	// tmp := w[(i-3)&0xf] ^ w[(i-8)&0xf] ^ w[(i-14)&0xf] ^ w[(i)&0xf]
+	// w[i&0xf] = tmp<<1 | tmp>>(32-1)
+	// e += w[i&0xf] 
+#define SHUFFLE(e) \
+	MOVW	(-16*4)(R(w)), R(t0) ; \
+	MOVW	(-14*4)(R(w)), R(t1) ; \
+	MOVW	(-8*4)(R(w)), R(t2)  ; \
+	EOR	R(t0), R(t1), R(t0)  ; \
+	MOVW	(-3*4)(R(w)), R(t1)  ; \
+	EOR	R(t2), R(t0), R(t0)  ; \
+	EOR	R(t0), R(t1), R(t0)  ; \
+	MOVW	R(t0)@>(32-1), R(t0)  ; \
+	MOVW.P	R(t0), 4(R(w))	  ; \
+	ADD	R(t0), R(e), R(e)
+
+	// t1 = (b & c) | ((~b) & d)
+#define FUNC1(a, b, c, d, e) \
+	MVN	R(b), R(t1)	   ; \
+	AND	R(b), R(c), R(t0)  ; \
+	AND	R(d), R(t1), R(t1) ; \
+	ORR	R(t0), R(t1), R(t1)
+
+	// t1 = b ^ c ^ d
+#define FUNC2(a, b, c, d, e) \
+	EOR	R(b), R(c), R(t1) ; \
+	EOR	R(d), R(t1), R(t1)
+
+	// t1 = (b & c) | (b & d) | (c & d) =
+	// t1 = (b & c) | ((b | c) & d)
+#define FUNC3(a, b, c, d, e) \
+	ORR	R(b), R(c), R(t0)  ; \
+	AND	R(b), R(c), R(t1)  ; \
+	AND	R(d), R(t0), R(t0) ; \
+	ORR	R(t0), R(t1), R(t1)
+
+#define FUNC4 FUNC2
+
+	// a5 := a<<5 | a>>(32-5)
+	// b = b<<30 | b>>(32-30)
+	// e = a5 + t1 + e + const
+#define MIX(a, b, c, d, e) \
+	ADD	R(t1), R(e), R(e)	 ; \
+	MOVW	R(b)@>(32-30), R(b)	 ; \
+	ADD	R(a)@>(32-5), R(e), R(e) ; \
+	ADD	R(const), R(e), R(e)
+
+#define ROUND1(a, b, c, d, e) \
+	LOAD(e)		; \
+	FUNC1(a, b, c, d, e)	; \
+	MIX(a, b, c, d, e)
+
+#define ROUND1x(a, b, c, d, e) \
+	SHUFFLE(e)	; \
+	FUNC1(a, b, c, d, e)	; \
+	MIX(a, b, c, d, e)
+
+#define ROUND2(a, b, c, d, e) \
+	SHUFFLE(e)	; \
+	FUNC2(a, b, c, d, e)	; \
+	MIX(a, b, c, d, e)
+
+#define ROUND3(a, b, c, d, e) \
+	SHUFFLE(e)	; \
+	FUNC3(a, b, c, d, e)	; \
+	MIX(a, b, c, d, e)
+
+#define ROUND4(a, b, c, d, e) \
+	SHUFFLE(e)	; \
+	FUNC4(a, b, c, d, e)	; \
+	MIX(a, b, c, d, e)
+
+
+// func block(dig *digest, p []byte)
+TEXT	·block(SB), 0, $352-16
+	MOVW	p+4(FP), R(data)	// pointer to the data
+	MOVW	p_len+8(FP), R(t0)	// number of bytes
+	ADD	R(data), R(t0)
+	MOVW	R(t0), p_end(SP)	// pointer to end of data
+
+	// Load up initial SHA1 accumulator
+	MOVW	dig+0(FP), R(t0)
+	MOVM.IA (R(t0)), [R(a),R(b),R(c),R(d),R(e)]
+
+loop:
+	// Save registers at SP+4 onwards
+	MOVM.IB [R(a),R(b),R(c),R(d),R(e)], (R13)
+
+	MOVW	$w_buf(SP), R(w)
+	MOVW	$0x5A827999, R(const)
+	MOVW	$3, R(ctr)
+loop1:	ROUND1(a, b, c, d, e)
+	ROUND1(e, a, b, c, d)
+	ROUND1(d, e, a, b, c)
+	ROUND1(c, d, e, a, b)
+	ROUND1(b, c, d, e, a)
+	SUB.S	$1, R(ctr)
+	BNE	loop1
+
+	ROUND1(a, b, c, d, e)
+	ROUND1x(e, a, b, c, d)
+	ROUND1x(d, e, a, b, c)
+	ROUND1x(c, d, e, a, b)
+	ROUND1x(b, c, d, e, a)
+	
+	MOVW	$0x6ED9EBA1, R(const)
+	MOVW	$4, R(ctr)
+loop2:	ROUND2(a, b, c, d, e)
+	ROUND2(e, a, b, c, d)
+	ROUND2(d, e, a, b, c)
+	ROUND2(c, d, e, a, b)
+	ROUND2(b, c, d, e, a)
+	SUB.S	$1, R(ctr)
+	BNE	loop2
+	
+	MOVW	$0x8F1BBCDC, R(const)
+	MOVW	$4, R(ctr)
+loop3:	ROUND3(a, b, c, d, e)
+	ROUND3(e, a, b, c, d)
+	ROUND3(d, e, a, b, c)
+	ROUND3(c, d, e, a, b)
+	ROUND3(b, c, d, e, a)
+	SUB.S	$1, R(ctr)
+	BNE	loop3
+	
+	MOVW	$0xCA62C1D6, R(const)
+	MOVW	$4, R(ctr)
+loop4:	ROUND4(a, b, c, d, e)
+	ROUND4(e, a, b, c, d)
+	ROUND4(d, e, a, b, c)
+	ROUND4(c, d, e, a, b)
+	ROUND4(b, c, d, e, a)
+	SUB.S	$1, R(ctr)
+	BNE	loop4
+
+	// Accumulate - restoring registers from SP+4
+	MOVM.IB (R13), [R(t0),R(t1),R(t2),R(ctr),R(w)]
+	ADD	R(t0), R(a)
+	ADD	R(t1), R(b)
+	ADD	R(t2), R(c)
+	ADD	R(ctr), R(d)
+	ADD	R(w), R(e)
+
+	MOVW	p_end(SP), R(t0)
+	CMP	R(t0), R(data)
+	BLO	loop
+
+	// Save final SHA1 accumulator
+	MOVW	dig+0(FP), R(t0)
+	MOVM.IA [R(a),R(b),R(c),R(d),R(e)], (R(t0))
+
+	RET
diff --git a/src/pkg/crypto/sha1/sha1block_decl.go b/src/crypto/sha1/sha1block_decl.go
similarity index 100%
rename from src/pkg/crypto/sha1/sha1block_decl.go
rename to src/crypto/sha1/sha1block_decl.go
diff --git a/src/pkg/crypto/sha1/sha1block_generic.go b/src/crypto/sha1/sha1block_generic.go
similarity index 100%
rename from src/pkg/crypto/sha1/sha1block_generic.go
rename to src/crypto/sha1/sha1block_generic.go
diff --git a/src/pkg/crypto/sha256/sha256.go b/src/crypto/sha256/sha256.go
similarity index 100%
rename from src/pkg/crypto/sha256/sha256.go
rename to src/crypto/sha256/sha256.go
diff --git a/src/pkg/crypto/sha256/sha256_test.go b/src/crypto/sha256/sha256_test.go
similarity index 100%
rename from src/pkg/crypto/sha256/sha256_test.go
rename to src/crypto/sha256/sha256_test.go
diff --git a/src/pkg/crypto/sha256/sha256block.go b/src/crypto/sha256/sha256block.go
similarity index 100%
rename from src/pkg/crypto/sha256/sha256block.go
rename to src/crypto/sha256/sha256block.go
diff --git a/src/pkg/crypto/sha256/sha256block_386.s b/src/crypto/sha256/sha256block_386.s
similarity index 100%
rename from src/pkg/crypto/sha256/sha256block_386.s
rename to src/crypto/sha256/sha256block_386.s
diff --git a/src/crypto/sha256/sha256block_amd64.s b/src/crypto/sha256/sha256block_amd64.s
new file mode 100644
index 0000000..868eaed
--- /dev/null
+++ b/src/crypto/sha256/sha256block_amd64.s
@@ -0,0 +1,256 @@
+// Copyright 2013 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+// SHA256 block routine. See sha256block.go for Go equivalent.
+//
+// The algorithm is detailed in FIPS 180-4:
+//
+//  http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf
+//
+// Wt = Mt; for 0 <= t <= 15
+// Wt = SIGMA1(Wt-2) + SIGMA0(Wt-15) + Wt-16; for 16 <= t <= 63
+//
+// a = H0
+// b = H1
+// c = H2
+// d = H3
+// e = H4
+// f = H5
+// g = H6
+// h = H7
+//
+// for t = 0 to 63 {
+//    T1 = h + BIGSIGMA1(e) + Ch(e,f,g) + Kt + Wt
+//    T2 = BIGSIGMA0(a) + Maj(a,b,c)
+//    h = g
+//    g = f
+//    f = e
+//    e = d + T1
+//    d = c
+//    c = b
+//    b = a
+//    a = T1 + T2
+// }
+//
+// H0 = a + H0
+// H1 = b + H1
+// H2 = c + H2
+// H3 = d + H3
+// H4 = e + H4
+// H5 = f + H5
+// H6 = g + H6
+// H7 = h + H7
+
+// Wt = Mt; for 0 <= t <= 15
+#define MSGSCHEDULE0(index) \
+	MOVL	(index*4)(SI), AX; \
+	BSWAPL	AX; \
+	MOVL	AX, (index*4)(BP)
+
+// Wt = SIGMA1(Wt-2) + Wt-7 + SIGMA0(Wt-15) + Wt-16; for 16 <= t <= 63
+//   SIGMA0(x) = ROTR(7,x) XOR ROTR(18,x) XOR SHR(3,x)
+//   SIGMA1(x) = ROTR(17,x) XOR ROTR(19,x) XOR SHR(10,x)
+#define MSGSCHEDULE1(index) \
+	MOVL	((index-2)*4)(BP), AX; \
+	MOVL	AX, CX; \
+	RORL	$17, AX; \
+	MOVL	CX, DX; \
+	RORL	$19, CX; \
+	SHRL	$10, DX; \
+	MOVL	((index-15)*4)(BP), BX; \
+	XORL	CX, AX; \
+	MOVL	BX, CX; \
+	XORL	DX, AX; \
+	RORL	$7, BX; \
+	MOVL	CX, DX; \
+	SHRL	$3, DX; \
+	RORL	$18, CX; \
+	ADDL	((index-7)*4)(BP), AX; \
+	XORL	CX, BX; \
+	XORL	DX, BX; \
+	ADDL	((index-16)*4)(BP), BX; \
+	ADDL	BX, AX; \
+	MOVL	AX, ((index)*4)(BP)
+
+// Calculate T1 in AX - uses AX, CX and DX registers.
+// h is also used as an accumulator. Wt is passed in AX.
+//   T1 = h + BIGSIGMA1(e) + Ch(e, f, g) + Kt + Wt
+//     BIGSIGMA1(x) = ROTR(6,x) XOR ROTR(11,x) XOR ROTR(25,x)
+//     Ch(x, y, z) = (x AND y) XOR (NOT x AND z)
+#define SHA256T1(const, e, f, g, h) \
+	ADDL	AX, h; \
+	MOVL	e, AX; \
+	ADDL	$const, h; \
+	MOVL	e, CX; \
+	RORL	$6, AX; \
+	MOVL	e, DX; \
+	RORL	$11, CX; \
+	XORL	CX, AX; \
+	MOVL	e, CX; \
+	RORL	$25, DX; \
+	ANDL	f, CX; \
+	XORL	AX, DX; \
+	MOVL	e, AX; \
+	NOTL	AX; \
+	ADDL	DX, h; \
+	ANDL	g, AX; \
+	XORL	CX, AX; \
+	ADDL	h, AX
+
+// Calculate T2 in BX - uses BX, CX, DX and DI registers.
+//   T2 = BIGSIGMA0(a) + Maj(a, b, c)
+//     BIGSIGMA0(x) = ROTR(2,x) XOR ROTR(13,x) XOR ROTR(22,x)
+//     Maj(x, y, z) = (x AND y) XOR (x AND z) XOR (y AND z)
+#define SHA256T2(a, b, c) \
+	MOVL	a, DI; \
+	MOVL	c, BX; \
+	RORL	$2, DI; \
+	MOVL	a, DX; \
+	ANDL	b, BX; \
+	RORL	$13, DX; \
+	MOVL	a, CX; \
+	ANDL	c, CX; \
+	XORL	DX, DI; \
+	XORL	CX, BX; \
+	MOVL	a, DX; \
+	MOVL	b, CX; \
+	RORL	$22, DX; \
+	ANDL	a, CX; \
+	XORL	CX, BX; \
+	XORL	DX, DI; \
+	ADDL	DI, BX
+
+// Calculate T1 and T2, then e = d + T1 and a = T1 + T2.
+// The values for e and a are stored in d and h, ready for rotation.
+#define SHA256ROUND(index, const, a, b, c, d, e, f, g, h) \
+	SHA256T1(const, e, f, g, h); \
+	SHA256T2(a, b, c); \
+	MOVL	BX, h; \
+	ADDL	AX, d; \
+	ADDL	AX, h
+
+#define SHA256ROUND0(index, const, a, b, c, d, e, f, g, h) \
+	MSGSCHEDULE0(index); \
+	SHA256ROUND(index, const, a, b, c, d, e, f, g, h)
+
+#define SHA256ROUND1(index, const, a, b, c, d, e, f, g, h) \
+	MSGSCHEDULE1(index); \
+	SHA256ROUND(index, const, a, b, c, d, e, f, g, h)
+
+TEXT ·block(SB),0,$264-32
+	MOVQ	p_base+8(FP), SI
+	MOVQ	p_len+16(FP), DX
+	SHRQ	$6, DX
+	SHLQ	$6, DX
+
+	LEAQ	(SI)(DX*1), DI
+	MOVQ	DI, 256(SP)
+	CMPQ	SI, DI
+	JEQ	end
+
+	MOVQ	dig+0(FP), BP
+	MOVL	(0*4)(BP), R8		// a = H0
+	MOVL	(1*4)(BP), R9		// b = H1
+	MOVL	(2*4)(BP), R10		// c = H2
+	MOVL	(3*4)(BP), R11		// d = H3
+	MOVL	(4*4)(BP), R12		// e = H4
+	MOVL	(5*4)(BP), R13		// f = H5
+	MOVL	(6*4)(BP), R14		// g = H6
+	MOVL	(7*4)(BP), R15		// h = H7
+
+loop:
+	MOVQ	SP, BP			// message schedule
+
+	SHA256ROUND0(0, 0x428a2f98, R8, R9, R10, R11, R12, R13, R14, R15)
+	SHA256ROUND0(1, 0x71374491, R15, R8, R9, R10, R11, R12, R13, R14)
+	SHA256ROUND0(2, 0xb5c0fbcf, R14, R15, R8, R9, R10, R11, R12, R13)
+	SHA256ROUND0(3, 0xe9b5dba5, R13, R14, R15, R8, R9, R10, R11, R12)
+	SHA256ROUND0(4, 0x3956c25b, R12, R13, R14, R15, R8, R9, R10, R11)
+	SHA256ROUND0(5, 0x59f111f1, R11, R12, R13, R14, R15, R8, R9, R10)
+	SHA256ROUND0(6, 0x923f82a4, R10, R11, R12, R13, R14, R15, R8, R9)
+	SHA256ROUND0(7, 0xab1c5ed5, R9, R10, R11, R12, R13, R14, R15, R8)
+	SHA256ROUND0(8, 0xd807aa98, R8, R9, R10, R11, R12, R13, R14, R15)
+	SHA256ROUND0(9, 0x12835b01, R15, R8, R9, R10, R11, R12, R13, R14)
+	SHA256ROUND0(10, 0x243185be, R14, R15, R8, R9, R10, R11, R12, R13)
+	SHA256ROUND0(11, 0x550c7dc3, R13, R14, R15, R8, R9, R10, R11, R12)
+	SHA256ROUND0(12, 0x72be5d74, R12, R13, R14, R15, R8, R9, R10, R11)
+	SHA256ROUND0(13, 0x80deb1fe, R11, R12, R13, R14, R15, R8, R9, R10)
+	SHA256ROUND0(14, 0x9bdc06a7, R10, R11, R12, R13, R14, R15, R8, R9)
+	SHA256ROUND0(15, 0xc19bf174, R9, R10, R11, R12, R13, R14, R15, R8)
+
+	SHA256ROUND1(16, 0xe49b69c1, R8, R9, R10, R11, R12, R13, R14, R15)
+	SHA256ROUND1(17, 0xefbe4786, R15, R8, R9, R10, R11, R12, R13, R14)
+	SHA256ROUND1(18, 0x0fc19dc6, R14, R15, R8, R9, R10, R11, R12, R13)
+	SHA256ROUND1(19, 0x240ca1cc, R13, R14, R15, R8, R9, R10, R11, R12)
+	SHA256ROUND1(20, 0x2de92c6f, R12, R13, R14, R15, R8, R9, R10, R11)
+	SHA256ROUND1(21, 0x4a7484aa, R11, R12, R13, R14, R15, R8, R9, R10)
+	SHA256ROUND1(22, 0x5cb0a9dc, R10, R11, R12, R13, R14, R15, R8, R9)
+	SHA256ROUND1(23, 0x76f988da, R9, R10, R11, R12, R13, R14, R15, R8)
+	SHA256ROUND1(24, 0x983e5152, R8, R9, R10, R11, R12, R13, R14, R15)
+	SHA256ROUND1(25, 0xa831c66d, R15, R8, R9, R10, R11, R12, R13, R14)
+	SHA256ROUND1(26, 0xb00327c8, R14, R15, R8, R9, R10, R11, R12, R13)
+	SHA256ROUND1(27, 0xbf597fc7, R13, R14, R15, R8, R9, R10, R11, R12)
+	SHA256ROUND1(28, 0xc6e00bf3, R12, R13, R14, R15, R8, R9, R10, R11)
+	SHA256ROUND1(29, 0xd5a79147, R11, R12, R13, R14, R15, R8, R9, R10)
+	SHA256ROUND1(30, 0x06ca6351, R10, R11, R12, R13, R14, R15, R8, R9)
+	SHA256ROUND1(31, 0x14292967, R9, R10, R11, R12, R13, R14, R15, R8)
+	SHA256ROUND1(32, 0x27b70a85, R8, R9, R10, R11, R12, R13, R14, R15)
+	SHA256ROUND1(33, 0x2e1b2138, R15, R8, R9, R10, R11, R12, R13, R14)
+	SHA256ROUND1(34, 0x4d2c6dfc, R14, R15, R8, R9, R10, R11, R12, R13)
+	SHA256ROUND1(35, 0x53380d13, R13, R14, R15, R8, R9, R10, R11, R12)
+	SHA256ROUND1(36, 0x650a7354, R12, R13, R14, R15, R8, R9, R10, R11)
+	SHA256ROUND1(37, 0x766a0abb, R11, R12, R13, R14, R15, R8, R9, R10)
+	SHA256ROUND1(38, 0x81c2c92e, R10, R11, R12, R13, R14, R15, R8, R9)
+	SHA256ROUND1(39, 0x92722c85, R9, R10, R11, R12, R13, R14, R15, R8)
+	SHA256ROUND1(40, 0xa2bfe8a1, R8, R9, R10, R11, R12, R13, R14, R15)
+	SHA256ROUND1(41, 0xa81a664b, R15, R8, R9, R10, R11, R12, R13, R14)
+	SHA256ROUND1(42, 0xc24b8b70, R14, R15, R8, R9, R10, R11, R12, R13)
+	SHA256ROUND1(43, 0xc76c51a3, R13, R14, R15, R8, R9, R10, R11, R12)
+	SHA256ROUND1(44, 0xd192e819, R12, R13, R14, R15, R8, R9, R10, R11)
+	SHA256ROUND1(45, 0xd6990624, R11, R12, R13, R14, R15, R8, R9, R10)
+	SHA256ROUND1(46, 0xf40e3585, R10, R11, R12, R13, R14, R15, R8, R9)
+	SHA256ROUND1(47, 0x106aa070, R9, R10, R11, R12, R13, R14, R15, R8)
+	SHA256ROUND1(48, 0x19a4c116, R8, R9, R10, R11, R12, R13, R14, R15)
+	SHA256ROUND1(49, 0x1e376c08, R15, R8, R9, R10, R11, R12, R13, R14)
+	SHA256ROUND1(50, 0x2748774c, R14, R15, R8, R9, R10, R11, R12, R13)
+	SHA256ROUND1(51, 0x34b0bcb5, R13, R14, R15, R8, R9, R10, R11, R12)
+	SHA256ROUND1(52, 0x391c0cb3, R12, R13, R14, R15, R8, R9, R10, R11)
+	SHA256ROUND1(53, 0x4ed8aa4a, R11, R12, R13, R14, R15, R8, R9, R10)
+	SHA256ROUND1(54, 0x5b9cca4f, R10, R11, R12, R13, R14, R15, R8, R9)
+	SHA256ROUND1(55, 0x682e6ff3, R9, R10, R11, R12, R13, R14, R15, R8)
+	SHA256ROUND1(56, 0x748f82ee, R8, R9, R10, R11, R12, R13, R14, R15)
+	SHA256ROUND1(57, 0x78a5636f, R15, R8, R9, R10, R11, R12, R13, R14)
+	SHA256ROUND1(58, 0x84c87814, R14, R15, R8, R9, R10, R11, R12, R13)
+	SHA256ROUND1(59, 0x8cc70208, R13, R14, R15, R8, R9, R10, R11, R12)
+	SHA256ROUND1(60, 0x90befffa, R12, R13, R14, R15, R8, R9, R10, R11)
+	SHA256ROUND1(61, 0xa4506ceb, R11, R12, R13, R14, R15, R8, R9, R10)
+	SHA256ROUND1(62, 0xbef9a3f7, R10, R11, R12, R13, R14, R15, R8, R9)
+	SHA256ROUND1(63, 0xc67178f2, R9, R10, R11, R12, R13, R14, R15, R8)
+
+	MOVQ	dig+0(FP), BP
+	ADDL	(0*4)(BP), R8	// H0 = a + H0
+	MOVL	R8, (0*4)(BP)
+	ADDL	(1*4)(BP), R9	// H1 = b + H1
+	MOVL	R9, (1*4)(BP)
+	ADDL	(2*4)(BP), R10	// H2 = c + H2
+	MOVL	R10, (2*4)(BP)
+	ADDL	(3*4)(BP), R11	// H3 = d + H3
+	MOVL	R11, (3*4)(BP)
+	ADDL	(4*4)(BP), R12	// H4 = e + H4
+	MOVL	R12, (4*4)(BP)
+	ADDL	(5*4)(BP), R13	// H5 = f + H5
+	MOVL	R13, (5*4)(BP)
+	ADDL	(6*4)(BP), R14	// H6 = g + H6
+	MOVL	R14, (6*4)(BP)
+	ADDL	(7*4)(BP), R15	// H7 = h + H7
+	MOVL	R15, (7*4)(BP)
+
+	ADDQ	$64, SI
+	CMPQ	SI, 256(SP)
+	JB	loop
+
+end:
+	RET
diff --git a/src/pkg/crypto/sha256/sha256block_decl.go b/src/crypto/sha256/sha256block_decl.go
similarity index 100%
rename from src/pkg/crypto/sha256/sha256block_decl.go
rename to src/crypto/sha256/sha256block_decl.go
diff --git a/src/pkg/crypto/sha512/sha512.go b/src/crypto/sha512/sha512.go
similarity index 100%
rename from src/pkg/crypto/sha512/sha512.go
rename to src/crypto/sha512/sha512.go
diff --git a/src/pkg/crypto/sha512/sha512_test.go b/src/crypto/sha512/sha512_test.go
similarity index 100%
rename from src/pkg/crypto/sha512/sha512_test.go
rename to src/crypto/sha512/sha512_test.go
diff --git a/src/pkg/crypto/sha512/sha512block.go b/src/crypto/sha512/sha512block.go
similarity index 100%
rename from src/pkg/crypto/sha512/sha512block.go
rename to src/crypto/sha512/sha512block.go
diff --git a/src/crypto/sha512/sha512block_amd64.s b/src/crypto/sha512/sha512block_amd64.s
new file mode 100644
index 0000000..2e10233
--- /dev/null
+++ b/src/crypto/sha512/sha512block_amd64.s
@@ -0,0 +1,273 @@
+// Copyright 2013 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+// SHA512 block routine. See sha512block.go for Go equivalent.
+//
+// The algorithm is detailed in FIPS 180-4:
+//
+//  http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf
+//
+// Wt = Mt; for 0 <= t <= 15
+// Wt = SIGMA1(Wt-2) + SIGMA0(Wt-15) + Wt-16; for 16 <= t <= 79
+//
+// a = H0
+// b = H1
+// c = H2
+// d = H3
+// e = H4
+// f = H5
+// g = H6
+// h = H7
+//
+// for t = 0 to 79 {
+//    T1 = h + BIGSIGMA1(e) + Ch(e,f,g) + Kt + Wt
+//    T2 = BIGSIGMA0(a) + Maj(a,b,c)
+//    h = g
+//    g = f
+//    f = e
+//    e = d + T1
+//    d = c
+//    c = b
+//    b = a
+//    a = T1 + T2
+// }
+//
+// H0 = a + H0
+// H1 = b + H1
+// H2 = c + H2
+// H3 = d + H3
+// H4 = e + H4
+// H5 = f + H5
+// H6 = g + H6
+// H7 = h + H7
+
+// Wt = Mt; for 0 <= t <= 15
+#define MSGSCHEDULE0(index) \
+	MOVQ	(index*8)(SI), AX; \
+	BSWAPQ	AX; \
+	MOVQ	AX, (index*8)(BP)
+
+// Wt = SIGMA1(Wt-2) + Wt-7 + SIGMA0(Wt-15) + Wt-16; for 16 <= t <= 79
+//   SIGMA0(x) = ROTR(1,x) XOR ROTR(8,x) XOR SHR(7,x)
+//   SIGMA1(x) = ROTR(19,x) XOR ROTR(61,x) XOR SHR(6,x)
+#define MSGSCHEDULE1(index) \
+	MOVQ	((index-2)*8)(BP), AX; \
+	MOVQ	AX, CX; \
+	RORQ	$19, AX; \
+	MOVQ	CX, DX; \
+	RORQ	$61, CX; \
+	SHRQ	$6, DX; \
+	MOVQ	((index-15)*8)(BP), BX; \
+	XORQ	CX, AX; \
+	MOVQ	BX, CX; \
+	XORQ	DX, AX; \
+	RORQ	$1, BX; \
+	MOVQ	CX, DX; \
+	SHRQ	$7, DX; \
+	RORQ	$8, CX; \
+	ADDQ	((index-7)*8)(BP), AX; \
+	XORQ	CX, BX; \
+	XORQ	DX, BX; \
+	ADDQ	((index-16)*8)(BP), BX; \
+	ADDQ	BX, AX; \
+	MOVQ	AX, ((index)*8)(BP)
+
+// Calculate T1 in AX - uses AX, CX and DX registers.
+// h is also used as an accumulator. Wt is passed in AX.
+//   T1 = h + BIGSIGMA1(e) + Ch(e, f, g) + Kt + Wt
+//     BIGSIGMA1(x) = ROTR(14,x) XOR ROTR(18,x) XOR ROTR(41,x)
+//     Ch(x, y, z) = (x AND y) XOR (NOT x AND z)
+#define SHA512T1(const, e, f, g, h) \
+	MOVQ	$const, DX; \
+	ADDQ	AX, h; \
+	MOVQ	e, AX; \
+	ADDQ	DX, h; \
+	MOVQ	e, CX; \
+	RORQ	$14, AX; \
+	MOVQ	e, DX; \
+	RORQ	$18, CX; \
+	XORQ	CX, AX; \
+	MOVQ	e, CX; \
+	RORQ	$41, DX; \
+	ANDQ	f, CX; \
+	XORQ	AX, DX; \
+	MOVQ	e, AX; \
+	NOTQ	AX; \
+	ADDQ	DX, h; \
+	ANDQ	g, AX; \
+	XORQ	CX, AX; \
+	ADDQ	h, AX
+
+// Calculate T2 in BX - uses BX, CX, DX and DI registers.
+//   T2 = BIGSIGMA0(a) + Maj(a, b, c)
+//     BIGSIGMA0(x) = ROTR(28,x) XOR ROTR(34,x) XOR ROTR(39,x)
+//     Maj(x, y, z) = (x AND y) XOR (x AND z) XOR (y AND z)
+#define SHA512T2(a, b, c) \
+	MOVQ	a, DI; \
+	MOVQ	c, BX; \
+	RORQ	$28, DI; \
+	MOVQ	a, DX; \
+	ANDQ	b, BX; \
+	RORQ	$34, DX; \
+	MOVQ	a, CX; \
+	ANDQ	c, CX; \
+	XORQ	DX, DI; \
+	XORQ	CX, BX; \
+	MOVQ	a, DX; \
+	MOVQ	b, CX; \
+	RORQ	$39, DX; \
+	ANDQ	a, CX; \
+	XORQ	CX, BX; \
+	XORQ	DX, DI; \
+	ADDQ	DI, BX
+
+// Calculate T1 and T2, then e = d + T1 and a = T1 + T2.
+// The values for e and a are stored in d and h, ready for rotation.
+#define SHA512ROUND(index, const, a, b, c, d, e, f, g, h) \
+	SHA512T1(const, e, f, g, h); \
+	SHA512T2(a, b, c); \
+	MOVQ	BX, h; \
+	ADDQ	AX, d; \
+	ADDQ	AX, h
+
+#define SHA512ROUND0(index, const, a, b, c, d, e, f, g, h) \
+	MSGSCHEDULE0(index); \
+	SHA512ROUND(index, const, a, b, c, d, e, f, g, h)
+
+#define SHA512ROUND1(index, const, a, b, c, d, e, f, g, h) \
+	MSGSCHEDULE1(index); \
+	SHA512ROUND(index, const, a, b, c, d, e, f, g, h)
+
+TEXT ·block(SB),0,$648-32
+	MOVQ	p_base+8(FP), SI
+	MOVQ	p_len+16(FP), DX
+	SHRQ	$7, DX
+	SHLQ	$7, DX
+
+	LEAQ	(SI)(DX*1), DI
+	MOVQ	DI, 640(SP)
+	CMPQ	SI, DI
+	JEQ	end
+
+	MOVQ	dig+0(FP), BP
+	MOVQ	(0*8)(BP), R8		// a = H0
+	MOVQ	(1*8)(BP), R9		// b = H1
+	MOVQ	(2*8)(BP), R10		// c = H2
+	MOVQ	(3*8)(BP), R11		// d = H3
+	MOVQ	(4*8)(BP), R12		// e = H4
+	MOVQ	(5*8)(BP), R13		// f = H5
+	MOVQ	(6*8)(BP), R14		// g = H6
+	MOVQ	(7*8)(BP), R15		// h = H7
+
+loop:
+	MOVQ	SP, BP			// message schedule
+
+	SHA512ROUND0(0, 0x428a2f98d728ae22, R8, R9, R10, R11, R12, R13, R14, R15)
+	SHA512ROUND0(1, 0x7137449123ef65cd, R15, R8, R9, R10, R11, R12, R13, R14)
+	SHA512ROUND0(2, 0xb5c0fbcfec4d3b2f, R14, R15, R8, R9, R10, R11, R12, R13)
+	SHA512ROUND0(3, 0xe9b5dba58189dbbc, R13, R14, R15, R8, R9, R10, R11, R12)
+	SHA512ROUND0(4, 0x3956c25bf348b538, R12, R13, R14, R15, R8, R9, R10, R11)
+	SHA512ROUND0(5, 0x59f111f1b605d019, R11, R12, R13, R14, R15, R8, R9, R10)
+	SHA512ROUND0(6, 0x923f82a4af194f9b, R10, R11, R12, R13, R14, R15, R8, R9)
+	SHA512ROUND0(7, 0xab1c5ed5da6d8118, R9, R10, R11, R12, R13, R14, R15, R8)
+	SHA512ROUND0(8, 0xd807aa98a3030242, R8, R9, R10, R11, R12, R13, R14, R15)
+	SHA512ROUND0(9, 0x12835b0145706fbe, R15, R8, R9, R10, R11, R12, R13, R14)
+	SHA512ROUND0(10, 0x243185be4ee4b28c, R14, R15, R8, R9, R10, R11, R12, R13)
+	SHA512ROUND0(11, 0x550c7dc3d5ffb4e2, R13, R14, R15, R8, R9, R10, R11, R12)
+	SHA512ROUND0(12, 0x72be5d74f27b896f, R12, R13, R14, R15, R8, R9, R10, R11)
+	SHA512ROUND0(13, 0x80deb1fe3b1696b1, R11, R12, R13, R14, R15, R8, R9, R10)
+	SHA512ROUND0(14, 0x9bdc06a725c71235, R10, R11, R12, R13, R14, R15, R8, R9)
+	SHA512ROUND0(15, 0xc19bf174cf692694, R9, R10, R11, R12, R13, R14, R15, R8)
+
+	SHA512ROUND1(16, 0xe49b69c19ef14ad2, R8, R9, R10, R11, R12, R13, R14, R15)
+	SHA512ROUND1(17, 0xefbe4786384f25e3, R15, R8, R9, R10, R11, R12, R13, R14)
+	SHA512ROUND1(18, 0x0fc19dc68b8cd5b5, R14, R15, R8, R9, R10, R11, R12, R13)
+	SHA512ROUND1(19, 0x240ca1cc77ac9c65, R13, R14, R15, R8, R9, R10, R11, R12)
+	SHA512ROUND1(20, 0x2de92c6f592b0275, R12, R13, R14, R15, R8, R9, R10, R11)
+	SHA512ROUND1(21, 0x4a7484aa6ea6e483, R11, R12, R13, R14, R15, R8, R9, R10)
+	SHA512ROUND1(22, 0x5cb0a9dcbd41fbd4, R10, R11, R12, R13, R14, R15, R8, R9)
+	SHA512ROUND1(23, 0x76f988da831153b5, R9, R10, R11, R12, R13, R14, R15, R8)
+	SHA512ROUND1(24, 0x983e5152ee66dfab, R8, R9, R10, R11, R12, R13, R14, R15)
+	SHA512ROUND1(25, 0xa831c66d2db43210, R15, R8, R9, R10, R11, R12, R13, R14)
+	SHA512ROUND1(26, 0xb00327c898fb213f, R14, R15, R8, R9, R10, R11, R12, R13)
+	SHA512ROUND1(27, 0xbf597fc7beef0ee4, R13, R14, R15, R8, R9, R10, R11, R12)
+	SHA512ROUND1(28, 0xc6e00bf33da88fc2, R12, R13, R14, R15, R8, R9, R10, R11)
+	SHA512ROUND1(29, 0xd5a79147930aa725, R11, R12, R13, R14, R15, R8, R9, R10)
+	SHA512ROUND1(30, 0x06ca6351e003826f, R10, R11, R12, R13, R14, R15, R8, R9)
+	SHA512ROUND1(31, 0x142929670a0e6e70, R9, R10, R11, R12, R13, R14, R15, R8)
+	SHA512ROUND1(32, 0x27b70a8546d22ffc, R8, R9, R10, R11, R12, R13, R14, R15)
+	SHA512ROUND1(33, 0x2e1b21385c26c926, R15, R8, R9, R10, R11, R12, R13, R14)
+	SHA512ROUND1(34, 0x4d2c6dfc5ac42aed, R14, R15, R8, R9, R10, R11, R12, R13)
+	SHA512ROUND1(35, 0x53380d139d95b3df, R13, R14, R15, R8, R9, R10, R11, R12)
+	SHA512ROUND1(36, 0x650a73548baf63de, R12, R13, R14, R15, R8, R9, R10, R11)
+	SHA512ROUND1(37, 0x766a0abb3c77b2a8, R11, R12, R13, R14, R15, R8, R9, R10)
+	SHA512ROUND1(38, 0x81c2c92e47edaee6, R10, R11, R12, R13, R14, R15, R8, R9)
+	SHA512ROUND1(39, 0x92722c851482353b, R9, R10, R11, R12, R13, R14, R15, R8)
+	SHA512ROUND1(40, 0xa2bfe8a14cf10364, R8, R9, R10, R11, R12, R13, R14, R15)
+	SHA512ROUND1(41, 0xa81a664bbc423001, R15, R8, R9, R10, R11, R12, R13, R14)
+	SHA512ROUND1(42, 0xc24b8b70d0f89791, R14, R15, R8, R9, R10, R11, R12, R13)
+	SHA512ROUND1(43, 0xc76c51a30654be30, R13, R14, R15, R8, R9, R10, R11, R12)
+	SHA512ROUND1(44, 0xd192e819d6ef5218, R12, R13, R14, R15, R8, R9, R10, R11)
+	SHA512ROUND1(45, 0xd69906245565a910, R11, R12, R13, R14, R15, R8, R9, R10)
+	SHA512ROUND1(46, 0xf40e35855771202a, R10, R11, R12, R13, R14, R15, R8, R9)
+	SHA512ROUND1(47, 0x106aa07032bbd1b8, R9, R10, R11, R12, R13, R14, R15, R8)
+	SHA512ROUND1(48, 0x19a4c116b8d2d0c8, R8, R9, R10, R11, R12, R13, R14, R15)
+	SHA512ROUND1(49, 0x1e376c085141ab53, R15, R8, R9, R10, R11, R12, R13, R14)
+	SHA512ROUND1(50, 0x2748774cdf8eeb99, R14, R15, R8, R9, R10, R11, R12, R13)
+	SHA512ROUND1(51, 0x34b0bcb5e19b48a8, R13, R14, R15, R8, R9, R10, R11, R12)
+	SHA512ROUND1(52, 0x391c0cb3c5c95a63, R12, R13, R14, R15, R8, R9, R10, R11)
+	SHA512ROUND1(53, 0x4ed8aa4ae3418acb, R11, R12, R13, R14, R15, R8, R9, R10)
+	SHA512ROUND1(54, 0x5b9cca4f7763e373, R10, R11, R12, R13, R14, R15, R8, R9)
+	SHA512ROUND1(55, 0x682e6ff3d6b2b8a3, R9, R10, R11, R12, R13, R14, R15, R8)
+	SHA512ROUND1(56, 0x748f82ee5defb2fc, R8, R9, R10, R11, R12, R13, R14, R15)
+	SHA512ROUND1(57, 0x78a5636f43172f60, R15, R8, R9, R10, R11, R12, R13, R14)
+	SHA512ROUND1(58, 0x84c87814a1f0ab72, R14, R15, R8, R9, R10, R11, R12, R13)
+	SHA512ROUND1(59, 0x8cc702081a6439ec, R13, R14, R15, R8, R9, R10, R11, R12)
+	SHA512ROUND1(60, 0x90befffa23631e28, R12, R13, R14, R15, R8, R9, R10, R11)
+	SHA512ROUND1(61, 0xa4506cebde82bde9, R11, R12, R13, R14, R15, R8, R9, R10)
+	SHA512ROUND1(62, 0xbef9a3f7b2c67915, R10, R11, R12, R13, R14, R15, R8, R9)
+	SHA512ROUND1(63, 0xc67178f2e372532b, R9, R10, R11, R12, R13, R14, R15, R8)
+	SHA512ROUND1(64, 0xca273eceea26619c, R8, R9, R10, R11, R12, R13, R14, R15)
+	SHA512ROUND1(65, 0xd186b8c721c0c207, R15, R8, R9, R10, R11, R12, R13, R14)
+	SHA512ROUND1(66, 0xeada7dd6cde0eb1e, R14, R15, R8, R9, R10, R11, R12, R13)
+	SHA512ROUND1(67, 0xf57d4f7fee6ed178, R13, R14, R15, R8, R9, R10, R11, R12)
+	SHA512ROUND1(68, 0x06f067aa72176fba, R12, R13, R14, R15, R8, R9, R10, R11)
+	SHA512ROUND1(69, 0x0a637dc5a2c898a6, R11, R12, R13, R14, R15, R8, R9, R10)
+	SHA512ROUND1(70, 0x113f9804bef90dae, R10, R11, R12, R13, R14, R15, R8, R9)
+	SHA512ROUND1(71, 0x1b710b35131c471b, R9, R10, R11, R12, R13, R14, R15, R8)
+	SHA512ROUND1(72, 0x28db77f523047d84, R8, R9, R10, R11, R12, R13, R14, R15)
+	SHA512ROUND1(73, 0x32caab7b40c72493, R15, R8, R9, R10, R11, R12, R13, R14)
+	SHA512ROUND1(74, 0x3c9ebe0a15c9bebc, R14, R15, R8, R9, R10, R11, R12, R13)
+	SHA512ROUND1(75, 0x431d67c49c100d4c, R13, R14, R15, R8, R9, R10, R11, R12)
+	SHA512ROUND1(76, 0x4cc5d4becb3e42b6, R12, R13, R14, R15, R8, R9, R10, R11)
+	SHA512ROUND1(77, 0x597f299cfc657e2a, R11, R12, R13, R14, R15, R8, R9, R10)
+	SHA512ROUND1(78, 0x5fcb6fab3ad6faec, R10, R11, R12, R13, R14, R15, R8, R9)
+	SHA512ROUND1(79, 0x6c44198c4a475817, R9, R10, R11, R12, R13, R14, R15, R8)
+
+	MOVQ	dig+0(FP), BP
+	ADDQ	(0*8)(BP), R8	// H0 = a + H0
+	MOVQ	R8, (0*8)(BP)
+	ADDQ	(1*8)(BP), R9	// H1 = b + H1
+	MOVQ	R9, (1*8)(BP)
+	ADDQ	(2*8)(BP), R10	// H2 = c + H2
+	MOVQ	R10, (2*8)(BP)
+	ADDQ	(3*8)(BP), R11	// H3 = d + H3
+	MOVQ	R11, (3*8)(BP)
+	ADDQ	(4*8)(BP), R12	// H4 = e + H4
+	MOVQ	R12, (4*8)(BP)
+	ADDQ	(5*8)(BP), R13	// H5 = f + H5
+	MOVQ	R13, (5*8)(BP)
+	ADDQ	(6*8)(BP), R14	// H6 = g + H6
+	MOVQ	R14, (6*8)(BP)
+	ADDQ	(7*8)(BP), R15	// H7 = h + H7
+	MOVQ	R15, (7*8)(BP)
+
+	ADDQ	$128, SI
+	CMPQ	SI, 640(SP)
+	JB	loop
+
+end:
+	RET
diff --git a/src/pkg/crypto/sha512/sha512block_decl.go b/src/crypto/sha512/sha512block_decl.go
similarity index 100%
rename from src/pkg/crypto/sha512/sha512block_decl.go
rename to src/crypto/sha512/sha512block_decl.go
diff --git a/src/crypto/subtle/constant_time.go b/src/crypto/subtle/constant_time.go
new file mode 100644
index 0000000..6f80e7c
--- /dev/null
+++ b/src/crypto/subtle/constant_time.go
@@ -0,0 +1,73 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package subtle implements functions that are often useful in cryptographic
+// code but require careful thought to use correctly.
+package subtle
+
+// ConstantTimeCompare returns 1 iff the two slices, x
+// and y, have equal contents. The time taken is a function of the length of
+// the slices and is independent of the contents.
+func ConstantTimeCompare(x, y []byte) int {
+	if len(x) != len(y) {
+		return 0
+	}
+
+	var v byte
+
+	for i := 0; i < len(x); i++ {
+		v |= x[i] ^ y[i]
+	}
+
+	return ConstantTimeByteEq(v, 0)
+}
+
+// ConstantTimeSelect returns x if v is 1 and y if v is 0.
+// Its behavior is undefined if v takes any other value.
+func ConstantTimeSelect(v, x, y int) int { return ^(v-1)&x | (v-1)&y }
+
+// ConstantTimeByteEq returns 1 if x == y and 0 otherwise.
+func ConstantTimeByteEq(x, y uint8) int {
+	z := ^(x ^ y)
+	z &= z >> 4
+	z &= z >> 2
+	z &= z >> 1
+
+	return int(z)
+}
+
+// ConstantTimeEq returns 1 if x == y and 0 otherwise.
+func ConstantTimeEq(x, y int32) int {
+	z := ^(x ^ y)
+	z &= z >> 16
+	z &= z >> 8
+	z &= z >> 4
+	z &= z >> 2
+	z &= z >> 1
+
+	return int(z & 1)
+}
+
+// ConstantTimeCopy copies the contents of y into x (a slice of equal length)
+// if v == 1. If v == 0, x is left unchanged. Its behavior is undefined if v
+// takes any other value.
+func ConstantTimeCopy(v int, x, y []byte) {
+	if len(x) != len(y) {
+		panic("subtle: slices have different lengths")
+	}
+
+	xmask := byte(v - 1)
+	ymask := byte(^(v - 1))
+	for i := 0; i < len(x); i++ {
+		x[i] = x[i]&xmask | y[i]&ymask
+	}
+}
+
+// ConstantTimeLessOrEq returns 1 if x <= y and 0 otherwise.
+// Its behavior is undefined if x or y are negative or > 2**31 - 1.
+func ConstantTimeLessOrEq(x, y int) int {
+	x32 := int32(x)
+	y32 := int32(y)
+	return int(((x32 - y32 - 1) >> 31) & 1)
+}
diff --git a/src/crypto/subtle/constant_time_test.go b/src/crypto/subtle/constant_time_test.go
new file mode 100644
index 0000000..619a454
--- /dev/null
+++ b/src/crypto/subtle/constant_time_test.go
@@ -0,0 +1,127 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package subtle
+
+import (
+	"testing"
+	"testing/quick"
+)
+
+type TestConstantTimeCompareStruct struct {
+	a, b []byte
+	out  int
+}
+
+var testConstantTimeCompareData = []TestConstantTimeCompareStruct{
+	{[]byte{}, []byte{}, 1},
+	{[]byte{0x11}, []byte{0x11}, 1},
+	{[]byte{0x12}, []byte{0x11}, 0},
+	{[]byte{0x11}, []byte{0x11, 0x12}, 0},
+	{[]byte{0x11, 0x12}, []byte{0x11}, 0},
+}
+
+func TestConstantTimeCompare(t *testing.T) {
+	for i, test := range testConstantTimeCompareData {
+		if r := ConstantTimeCompare(test.a, test.b); r != test.out {
+			t.Errorf("#%d bad result (got %x, want %x)", i, r, test.out)
+		}
+	}
+}
+
+type TestConstantTimeByteEqStruct struct {
+	a, b uint8
+	out  int
+}
+
+var testConstandTimeByteEqData = []TestConstantTimeByteEqStruct{
+	{0, 0, 1},
+	{0, 1, 0},
+	{1, 0, 0},
+	{0xff, 0xff, 1},
+	{0xff, 0xfe, 0},
+}
+
+func byteEq(a, b uint8) int {
+	if a == b {
+		return 1
+	}
+	return 0
+}
+
+func TestConstantTimeByteEq(t *testing.T) {
+	for i, test := range testConstandTimeByteEqData {
+		if r := ConstantTimeByteEq(test.a, test.b); r != test.out {
+			t.Errorf("#%d bad result (got %x, want %x)", i, r, test.out)
+		}
+	}
+	err := quick.CheckEqual(ConstantTimeByteEq, byteEq, nil)
+	if err != nil {
+		t.Error(err)
+	}
+}
+
+func eq(a, b int32) int {
+	if a == b {
+		return 1
+	}
+	return 0
+}
+
+func TestConstantTimeEq(t *testing.T) {
+	err := quick.CheckEqual(ConstantTimeEq, eq, nil)
+	if err != nil {
+		t.Error(err)
+	}
+}
+
+func makeCopy(v int, x, y []byte) []byte {
+	if len(x) > len(y) {
+		x = x[0:len(y)]
+	} else {
+		y = y[0:len(x)]
+	}
+	if v == 1 {
+		copy(x, y)
+	}
+	return x
+}
+
+func constantTimeCopyWrapper(v int, x, y []byte) []byte {
+	if len(x) > len(y) {
+		x = x[0:len(y)]
+	} else {
+		y = y[0:len(x)]
+	}
+	v &= 1
+	ConstantTimeCopy(v, x, y)
+	return x
+}
+
+func TestConstantTimeCopy(t *testing.T) {
+	err := quick.CheckEqual(constantTimeCopyWrapper, makeCopy, nil)
+	if err != nil {
+		t.Error(err)
+	}
+}
+
+var lessOrEqTests = []struct {
+	x, y, result int
+}{
+	{0, 0, 1},
+	{1, 0, 0},
+	{0, 1, 1},
+	{10, 20, 1},
+	{20, 10, 0},
+	{10, 10, 1},
+}
+
+func TestConstantTimeLessOrEq(t *testing.T) {
+	for i, test := range lessOrEqTests {
+		result := ConstantTimeLessOrEq(test.x, test.y)
+		if result != test.result {
+			t.Errorf("#%d: %d <= %d gave %d, expected %d", i, test.x, test.y, result, test.result)
+		}
+	}
+}
diff --git a/src/crypto/tls/alert.go b/src/crypto/tls/alert.go
new file mode 100644
index 0000000..3de4834
--- /dev/null
+++ b/src/crypto/tls/alert.go
@@ -0,0 +1,79 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tls
+
+import "strconv"
+
+type alert uint8
+
+const (
+	// alert level
+	alertLevelWarning = 1
+	alertLevelError   = 2
+)
+
+const (
+	alertCloseNotify            alert = 0
+	alertUnexpectedMessage      alert = 10
+	alertBadRecordMAC           alert = 20
+	alertDecryptionFailed       alert = 21
+	alertRecordOverflow         alert = 22
+	alertDecompressionFailure   alert = 30
+	alertHandshakeFailure       alert = 40
+	alertBadCertificate         alert = 42
+	alertUnsupportedCertificate alert = 43
+	alertCertificateRevoked     alert = 44
+	alertCertificateExpired     alert = 45
+	alertCertificateUnknown     alert = 46
+	alertIllegalParameter       alert = 47
+	alertUnknownCA              alert = 48
+	alertAccessDenied           alert = 49
+	alertDecodeError            alert = 50
+	alertDecryptError           alert = 51
+	alertProtocolVersion        alert = 70
+	alertInsufficientSecurity   alert = 71
+	alertInternalError          alert = 80
+	alertInappropriateFallback  alert = 86
+	alertUserCanceled           alert = 90
+	alertNoRenegotiation        alert = 100
+)
+
+var alertText = map[alert]string{
+	alertCloseNotify:            "close notify",
+	alertUnexpectedMessage:      "unexpected message",
+	alertBadRecordMAC:           "bad record MAC",
+	alertDecryptionFailed:       "decryption failed",
+	alertRecordOverflow:         "record overflow",
+	alertDecompressionFailure:   "decompression failure",
+	alertHandshakeFailure:       "handshake failure",
+	alertBadCertificate:         "bad certificate",
+	alertUnsupportedCertificate: "unsupported certificate",
+	alertCertificateRevoked:     "revoked certificate",
+	alertCertificateExpired:     "expired certificate",
+	alertCertificateUnknown:     "unknown certificate",
+	alertIllegalParameter:       "illegal parameter",
+	alertUnknownCA:              "unknown certificate authority",
+	alertAccessDenied:           "access denied",
+	alertDecodeError:            "error decoding message",
+	alertDecryptError:           "error decrypting message",
+	alertProtocolVersion:        "protocol version not supported",
+	alertInsufficientSecurity:   "insufficient security level",
+	alertInternalError:          "internal error",
+	alertInappropriateFallback:  "inappropriate fallback",
+	alertUserCanceled:           "user canceled",
+	alertNoRenegotiation:        "no renegotiation",
+}
+
+func (e alert) String() string {
+	s, ok := alertText[e]
+	if ok {
+		return s
+	}
+	return "alert(" + strconv.Itoa(int(e)) + ")"
+}
+
+func (e alert) Error() string {
+	return e.String()
+}
diff --git a/src/crypto/tls/cipher_suites.go b/src/crypto/tls/cipher_suites.go
new file mode 100644
index 0000000..226e06d
--- /dev/null
+++ b/src/crypto/tls/cipher_suites.go
@@ -0,0 +1,275 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tls
+
+import (
+	"crypto/aes"
+	"crypto/cipher"
+	"crypto/des"
+	"crypto/hmac"
+	"crypto/rc4"
+	"crypto/sha1"
+	"crypto/x509"
+	"hash"
+)
+
+// a keyAgreement implements the client and server side of a TLS key agreement
+// protocol by generating and processing key exchange messages.
+type keyAgreement interface {
+	// On the server side, the first two methods are called in order.
+
+	// In the case that the key agreement protocol doesn't use a
+	// ServerKeyExchange message, generateServerKeyExchange can return nil,
+	// nil.
+	generateServerKeyExchange(*Config, *Certificate, *clientHelloMsg, *serverHelloMsg) (*serverKeyExchangeMsg, error)
+	processClientKeyExchange(*Config, *Certificate, *clientKeyExchangeMsg, uint16) ([]byte, error)
+
+	// On the client side, the next two methods are called in order.
+
+	// This method may not be called if the server doesn't send a
+	// ServerKeyExchange message.
+	processServerKeyExchange(*Config, *clientHelloMsg, *serverHelloMsg, *x509.Certificate, *serverKeyExchangeMsg) error
+	generateClientKeyExchange(*Config, *clientHelloMsg, *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error)
+}
+
+const (
+	// suiteECDH indicates that the cipher suite involves elliptic curve
+	// Diffie-Hellman. This means that it should only be selected when the
+	// client indicates that it supports ECC with a curve and point format
+	// that we're happy with.
+	suiteECDHE = 1 << iota
+	// suiteECDSA indicates that the cipher suite involves an ECDSA
+	// signature and therefore may only be selected when the server's
+	// certificate is ECDSA. If this is not set then the cipher suite is
+	// RSA based.
+	suiteECDSA
+	// suiteTLS12 indicates that the cipher suite should only be advertised
+	// and accepted when using TLS 1.2.
+	suiteTLS12
+)
+
+// A cipherSuite is a specific combination of key agreement, cipher and MAC
+// function. All cipher suites currently assume RSA key agreement.
+type cipherSuite struct {
+	id uint16
+	// the lengths, in bytes, of the key material needed for each component.
+	keyLen int
+	macLen int
+	ivLen  int
+	ka     func(version uint16) keyAgreement
+	// flags is a bitmask of the suite* values, above.
+	flags  int
+	cipher func(key, iv []byte, isRead bool) interface{}
+	mac    func(version uint16, macKey []byte) macFunction
+	aead   func(key, fixedNonce []byte) cipher.AEAD
+}
+
+var cipherSuites = []*cipherSuite{
+	// Ciphersuite order is chosen so that ECDHE comes before plain RSA
+	// and RC4 comes before AES (because of the Lucky13 attack).
+	{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, ecdheRSAKA, suiteECDHE | suiteTLS12, nil, nil, aeadAESGCM},
+	{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, ecdheECDSAKA, suiteECDHE | suiteECDSA | suiteTLS12, nil, nil, aeadAESGCM},
+	{TLS_ECDHE_RSA_WITH_RC4_128_SHA, 16, 20, 0, ecdheRSAKA, suiteECDHE, cipherRC4, macSHA1, nil},
+	{TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, 16, 20, 0, ecdheECDSAKA, suiteECDHE | suiteECDSA, cipherRC4, macSHA1, nil},
+	{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdheRSAKA, suiteECDHE, cipherAES, macSHA1, nil},
+	{TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdheECDSAKA, suiteECDHE | suiteECDSA, cipherAES, macSHA1, nil},
+	{TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdheRSAKA, suiteECDHE, cipherAES, macSHA1, nil},
+	{TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdheECDSAKA, suiteECDHE | suiteECDSA, cipherAES, macSHA1, nil},
+	{TLS_RSA_WITH_RC4_128_SHA, 16, 20, 0, rsaKA, 0, cipherRC4, macSHA1, nil},
+	{TLS_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, rsaKA, 0, cipherAES, macSHA1, nil},
+	{TLS_RSA_WITH_AES_256_CBC_SHA, 32, 20, 16, rsaKA, 0, cipherAES, macSHA1, nil},
+	{TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, ecdheRSAKA, suiteECDHE, cipher3DES, macSHA1, nil},
+	{TLS_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, rsaKA, 0, cipher3DES, macSHA1, nil},
+}
+
+func cipherRC4(key, iv []byte, isRead bool) interface{} {
+	cipher, _ := rc4.NewCipher(key)
+	return cipher
+}
+
+func cipher3DES(key, iv []byte, isRead bool) interface{} {
+	block, _ := des.NewTripleDESCipher(key)
+	if isRead {
+		return cipher.NewCBCDecrypter(block, iv)
+	}
+	return cipher.NewCBCEncrypter(block, iv)
+}
+
+func cipherAES(key, iv []byte, isRead bool) interface{} {
+	block, _ := aes.NewCipher(key)
+	if isRead {
+		return cipher.NewCBCDecrypter(block, iv)
+	}
+	return cipher.NewCBCEncrypter(block, iv)
+}
+
+// macSHA1 returns a macFunction for the given protocol version.
+func macSHA1(version uint16, key []byte) macFunction {
+	if version == VersionSSL30 {
+		mac := ssl30MAC{
+			h:   sha1.New(),
+			key: make([]byte, len(key)),
+		}
+		copy(mac.key, key)
+		return mac
+	}
+	return tls10MAC{hmac.New(sha1.New, key)}
+}
+
+type macFunction interface {
+	Size() int
+	MAC(digestBuf, seq, header, data []byte) []byte
+}
+
+// fixedNonceAEAD wraps an AEAD and prefixes a fixed portion of the nonce to
+// each call.
+type fixedNonceAEAD struct {
+	// sealNonce and openNonce are buffers where the larger nonce will be
+	// constructed. Since a seal and open operation may be running
+	// concurrently, there is a separate buffer for each.
+	sealNonce, openNonce []byte
+	aead                 cipher.AEAD
+}
+
+func (f *fixedNonceAEAD) NonceSize() int { return 8 }
+func (f *fixedNonceAEAD) Overhead() int  { return f.aead.Overhead() }
+
+func (f *fixedNonceAEAD) Seal(out, nonce, plaintext, additionalData []byte) []byte {
+	copy(f.sealNonce[len(f.sealNonce)-8:], nonce)
+	return f.aead.Seal(out, f.sealNonce, plaintext, additionalData)
+}
+
+func (f *fixedNonceAEAD) Open(out, nonce, plaintext, additionalData []byte) ([]byte, error) {
+	copy(f.openNonce[len(f.openNonce)-8:], nonce)
+	return f.aead.Open(out, f.openNonce, plaintext, additionalData)
+}
+
+func aeadAESGCM(key, fixedNonce []byte) cipher.AEAD {
+	aes, err := aes.NewCipher(key)
+	if err != nil {
+		panic(err)
+	}
+	aead, err := cipher.NewGCM(aes)
+	if err != nil {
+		panic(err)
+	}
+
+	nonce1, nonce2 := make([]byte, 12), make([]byte, 12)
+	copy(nonce1, fixedNonce)
+	copy(nonce2, fixedNonce)
+
+	return &fixedNonceAEAD{nonce1, nonce2, aead}
+}
+
+// ssl30MAC implements the SSLv3 MAC function, as defined in
+// www.mozilla.org/projects/security/pki/nss/ssl/draft302.txt section 5.2.3.1
+type ssl30MAC struct {
+	h   hash.Hash
+	key []byte
+}
+
+func (s ssl30MAC) Size() int {
+	return s.h.Size()
+}
+
+var ssl30Pad1 = [48]byte{0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36}
+
+var ssl30Pad2 = [48]byte{0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c}
+
+func (s ssl30MAC) MAC(digestBuf, seq, header, data []byte) []byte {
+	padLength := 48
+	if s.h.Size() == 20 {
+		padLength = 40
+	}
+
+	s.h.Reset()
+	s.h.Write(s.key)
+	s.h.Write(ssl30Pad1[:padLength])
+	s.h.Write(seq)
+	s.h.Write(header[:1])
+	s.h.Write(header[3:5])
+	s.h.Write(data)
+	digestBuf = s.h.Sum(digestBuf[:0])
+
+	s.h.Reset()
+	s.h.Write(s.key)
+	s.h.Write(ssl30Pad2[:padLength])
+	s.h.Write(digestBuf)
+	return s.h.Sum(digestBuf[:0])
+}
+
+// tls10MAC implements the TLS 1.0 MAC function. RFC 2246, section 6.2.3.
+type tls10MAC struct {
+	h hash.Hash
+}
+
+func (s tls10MAC) Size() int {
+	return s.h.Size()
+}
+
+func (s tls10MAC) MAC(digestBuf, seq, header, data []byte) []byte {
+	s.h.Reset()
+	s.h.Write(seq)
+	s.h.Write(header)
+	s.h.Write(data)
+	return s.h.Sum(digestBuf[:0])
+}
+
+func rsaKA(version uint16) keyAgreement {
+	return rsaKeyAgreement{}
+}
+
+func ecdheECDSAKA(version uint16) keyAgreement {
+	return &ecdheKeyAgreement{
+		sigType: signatureECDSA,
+		version: version,
+	}
+}
+
+func ecdheRSAKA(version uint16) keyAgreement {
+	return &ecdheKeyAgreement{
+		sigType: signatureRSA,
+		version: version,
+	}
+}
+
+// mutualCipherSuite returns a cipherSuite given a list of supported
+// ciphersuites and the id requested by the peer.
+func mutualCipherSuite(have []uint16, want uint16) *cipherSuite {
+	for _, id := range have {
+		if id == want {
+			for _, suite := range cipherSuites {
+				if suite.id == want {
+					return suite
+				}
+			}
+			return nil
+		}
+	}
+	return nil
+}
+
+// A list of the possible cipher suite ids. Taken from
+// http://www.iana.org/assignments/tls-parameters/tls-parameters.xml
+const (
+	TLS_RSA_WITH_RC4_128_SHA                uint16 = 0x0005
+	TLS_RSA_WITH_3DES_EDE_CBC_SHA           uint16 = 0x000a
+	TLS_RSA_WITH_AES_128_CBC_SHA            uint16 = 0x002f
+	TLS_RSA_WITH_AES_256_CBC_SHA            uint16 = 0x0035
+	TLS_ECDHE_ECDSA_WITH_RC4_128_SHA        uint16 = 0xc007
+	TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA    uint16 = 0xc009
+	TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA    uint16 = 0xc00a
+	TLS_ECDHE_RSA_WITH_RC4_128_SHA          uint16 = 0xc011
+	TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA     uint16 = 0xc012
+	TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA      uint16 = 0xc013
+	TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA      uint16 = 0xc014
+	TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256   uint16 = 0xc02f
+	TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 uint16 = 0xc02b
+
+	// TLS_FALLBACK_SCSV isn't a standard cipher suite but an indicator
+	// that the client is doing version fallback. See
+	// https://tools.ietf.org/html/draft-ietf-tls-downgrade-scsv-00.
+	TLS_FALLBACK_SCSV uint16 = 0x5600
+)
diff --git a/src/crypto/tls/common.go b/src/crypto/tls/common.go
new file mode 100644
index 0000000..776b70c
--- /dev/null
+++ b/src/crypto/tls/common.go
@@ -0,0 +1,621 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tls
+
+import (
+	"container/list"
+	"crypto"
+	"crypto/rand"
+	"crypto/x509"
+	"fmt"
+	"io"
+	"math/big"
+	"strings"
+	"sync"
+	"time"
+)
+
+const (
+	VersionSSL30 = 0x0300
+	VersionTLS10 = 0x0301
+	VersionTLS11 = 0x0302
+	VersionTLS12 = 0x0303
+)
+
+const (
+	maxPlaintext    = 16384        // maximum plaintext payload length
+	maxCiphertext   = 16384 + 2048 // maximum ciphertext payload length
+	recordHeaderLen = 5            // record header length
+	maxHandshake    = 65536        // maximum handshake we support (protocol max is 16 MB)
+
+	minVersion = VersionSSL30
+	maxVersion = VersionTLS12
+)
+
+// TLS record types.
+type recordType uint8
+
+const (
+	recordTypeChangeCipherSpec recordType = 20
+	recordTypeAlert            recordType = 21
+	recordTypeHandshake        recordType = 22
+	recordTypeApplicationData  recordType = 23
+)
+
+// TLS handshake message types.
+const (
+	typeClientHello        uint8 = 1
+	typeServerHello        uint8 = 2
+	typeNewSessionTicket   uint8 = 4
+	typeCertificate        uint8 = 11
+	typeServerKeyExchange  uint8 = 12
+	typeCertificateRequest uint8 = 13
+	typeServerHelloDone    uint8 = 14
+	typeCertificateVerify  uint8 = 15
+	typeClientKeyExchange  uint8 = 16
+	typeFinished           uint8 = 20
+	typeCertificateStatus  uint8 = 22
+	typeNextProtocol       uint8 = 67 // Not IANA assigned
+)
+
+// TLS compression types.
+const (
+	compressionNone uint8 = 0
+)
+
+// TLS extension numbers
+const (
+	extensionServerName          uint16 = 0
+	extensionStatusRequest       uint16 = 5
+	extensionSupportedCurves     uint16 = 10
+	extensionSupportedPoints     uint16 = 11
+	extensionSignatureAlgorithms uint16 = 13
+	extensionALPN                uint16 = 16
+	extensionSessionTicket       uint16 = 35
+	extensionNextProtoNeg        uint16 = 13172 // not IANA assigned
+	extensionRenegotiationInfo   uint16 = 0xff01
+)
+
+// TLS signaling cipher suite values
+const (
+	scsvRenegotiation uint16 = 0x00ff
+)
+
+// CurveID is the type of a TLS identifier for an elliptic curve. See
+// http://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-8
+type CurveID uint16
+
+const (
+	CurveP256 CurveID = 23
+	CurveP384 CurveID = 24
+	CurveP521 CurveID = 25
+)
+
+// TLS Elliptic Curve Point Formats
+// http://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-9
+const (
+	pointFormatUncompressed uint8 = 0
+)
+
+// TLS CertificateStatusType (RFC 3546)
+const (
+	statusTypeOCSP uint8 = 1
+)
+
+// Certificate types (for certificateRequestMsg)
+const (
+	certTypeRSASign    = 1 // A certificate containing an RSA key
+	certTypeDSSSign    = 2 // A certificate containing a DSA key
+	certTypeRSAFixedDH = 3 // A certificate containing a static DH key
+	certTypeDSSFixedDH = 4 // A certificate containing a static DH key
+
+	// See RFC4492 sections 3 and 5.5.
+	certTypeECDSASign      = 64 // A certificate containing an ECDSA-capable public key, signed with ECDSA.
+	certTypeRSAFixedECDH   = 65 // A certificate containing an ECDH-capable public key, signed with RSA.
+	certTypeECDSAFixedECDH = 66 // A certificate containing an ECDH-capable public key, signed with ECDSA.
+
+	// Rest of these are reserved by the TLS spec
+)
+
+// Hash functions for TLS 1.2 (See RFC 5246, section A.4.1)
+const (
+	hashSHA1   uint8 = 2
+	hashSHA256 uint8 = 4
+)
+
+// Signature algorithms for TLS 1.2 (See RFC 5246, section A.4.1)
+const (
+	signatureRSA   uint8 = 1
+	signatureECDSA uint8 = 3
+)
+
+// signatureAndHash mirrors the TLS 1.2, SignatureAndHashAlgorithm struct. See
+// RFC 5246, section A.4.1.
+type signatureAndHash struct {
+	hash, signature uint8
+}
+
+// supportedSKXSignatureAlgorithms contains the signature and hash algorithms
+// that the code advertises as supported in a TLS 1.2 ClientHello.
+var supportedSKXSignatureAlgorithms = []signatureAndHash{
+	{hashSHA256, signatureRSA},
+	{hashSHA256, signatureECDSA},
+	{hashSHA1, signatureRSA},
+	{hashSHA1, signatureECDSA},
+}
+
+// supportedClientCertSignatureAlgorithms contains the signature and hash
+// algorithms that the code advertises as supported in a TLS 1.2
+// CertificateRequest.
+var supportedClientCertSignatureAlgorithms = []signatureAndHash{
+	{hashSHA256, signatureRSA},
+	{hashSHA256, signatureECDSA},
+}
+
+// ConnectionState records basic TLS details about the connection.
+type ConnectionState struct {
+	Version                    uint16                // TLS version used by the connection (e.g. VersionTLS12)
+	HandshakeComplete          bool                  // TLS handshake is complete
+	DidResume                  bool                  // connection resumes a previous TLS connection
+	CipherSuite                uint16                // cipher suite in use (TLS_RSA_WITH_RC4_128_SHA, ...)
+	NegotiatedProtocol         string                // negotiated next protocol (from Config.NextProtos)
+	NegotiatedProtocolIsMutual bool                  // negotiated protocol was advertised by server
+	ServerName                 string                // server name requested by client, if any (server side only)
+	PeerCertificates           []*x509.Certificate   // certificate chain presented by remote peer
+	VerifiedChains             [][]*x509.Certificate // verified chains built from PeerCertificates
+
+	// TLSUnique contains the "tls-unique" channel binding value (see RFC
+	// 5929, section 3). For resumed sessions this value will be nil
+	// because resumption does not include enough context (see
+	// https://secure-resumption.com/#channelbindings). This will change in
+	// future versions of Go once the TLS master-secret fix has been
+	// standardized and implemented.
+	TLSUnique []byte
+}
+
+// ClientAuthType declares the policy the server will follow for
+// TLS Client Authentication.
+type ClientAuthType int
+
+const (
+	NoClientCert ClientAuthType = iota
+	RequestClientCert
+	RequireAnyClientCert
+	VerifyClientCertIfGiven
+	RequireAndVerifyClientCert
+)
+
+// ClientSessionState contains the state needed by clients to resume TLS
+// sessions.
+type ClientSessionState struct {
+	sessionTicket      []uint8             // Encrypted ticket used for session resumption with server
+	vers               uint16              // SSL/TLS version negotiated for the session
+	cipherSuite        uint16              // Ciphersuite negotiated for the session
+	masterSecret       []byte              // MasterSecret generated by client on a full handshake
+	serverCertificates []*x509.Certificate // Certificate chain presented by the server
+}
+
+// ClientSessionCache is a cache of ClientSessionState objects that can be used
+// by a client to resume a TLS session with a given server. ClientSessionCache
+// implementations should expect to be called concurrently from different
+// goroutines.
+type ClientSessionCache interface {
+	// Get searches for a ClientSessionState associated with the given key.
+	// On return, ok is true if one was found.
+	Get(sessionKey string) (session *ClientSessionState, ok bool)
+
+	// Put adds the ClientSessionState to the cache with the given key.
+	Put(sessionKey string, cs *ClientSessionState)
+}
+
+// ClientHelloInfo contains information from a ClientHello message in order to
+// guide certificate selection in the GetCertificate callback.
+type ClientHelloInfo struct {
+	// CipherSuites lists the CipherSuites supported by the client (e.g.
+	// TLS_RSA_WITH_RC4_128_SHA).
+	CipherSuites []uint16
+
+	// ServerName indicates the name of the server requested by the client
+	// in order to support virtual hosting. ServerName is only set if the
+	// client is using SNI (see
+	// http://tools.ietf.org/html/rfc4366#section-3.1).
+	ServerName string
+
+	// SupportedCurves lists the elliptic curves supported by the client.
+	// SupportedCurves is set only if the Supported Elliptic Curves
+	// Extension is being used (see
+	// http://tools.ietf.org/html/rfc4492#section-5.1.1).
+	SupportedCurves []CurveID
+
+	// SupportedPoints lists the point formats supported by the client.
+	// SupportedPoints is set only if the Supported Point Formats Extension
+	// is being used (see
+	// http://tools.ietf.org/html/rfc4492#section-5.1.2).
+	SupportedPoints []uint8
+}
+
+// A Config structure is used to configure a TLS client or server.
+// After one has been passed to a TLS function it must not be
+// modified. A Config may be reused; the tls package will also not
+// modify it.
+type Config struct {
+	// Rand provides the source of entropy for nonces and RSA blinding.
+	// If Rand is nil, TLS uses the cryptographic random reader in package
+	// crypto/rand.
+	// The Reader must be safe for use by multiple goroutines.
+	Rand io.Reader
+
+	// Time returns the current time as the number of seconds since the epoch.
+	// If Time is nil, TLS uses time.Now.
+	Time func() time.Time
+
+	// Certificates contains one or more certificate chains
+	// to present to the other side of the connection.
+	// Server configurations must include at least one certificate.
+	Certificates []Certificate
+
+	// NameToCertificate maps from a certificate name to an element of
+	// Certificates. Note that a certificate name can be of the form
+	// '*.example.com' and so doesn't have to be a domain name as such.
+	// See Config.BuildNameToCertificate
+	// The nil value causes the first element of Certificates to be used
+	// for all connections.
+	NameToCertificate map[string]*Certificate
+
+	// GetCertificate returns a Certificate based on the given
+	// ClientHelloInfo. If GetCertificate is nil or returns nil, then the
+	// certificate is retrieved from NameToCertificate. If
+	// NameToCertificate is nil, the first element of Certificates will be
+	// used.
+	GetCertificate func(clientHello *ClientHelloInfo) (*Certificate, error)
+
+	// RootCAs defines the set of root certificate authorities
+	// that clients use when verifying server certificates.
+	// If RootCAs is nil, TLS uses the host's root CA set.
+	RootCAs *x509.CertPool
+
+	// NextProtos is a list of supported, application level protocols.
+	NextProtos []string
+
+	// ServerName is used to verify the hostname on the returned
+	// certificates unless InsecureSkipVerify is given. It is also included
+	// in the client's handshake to support virtual hosting.
+	ServerName string
+
+	// ClientAuth determines the server's policy for
+	// TLS Client Authentication. The default is NoClientCert.
+	ClientAuth ClientAuthType
+
+	// ClientCAs defines the set of root certificate authorities
+	// that servers use if required to verify a client certificate
+	// by the policy in ClientAuth.
+	ClientCAs *x509.CertPool
+
+	// InsecureSkipVerify controls whether a client verifies the
+	// server's certificate chain and host name.
+	// If InsecureSkipVerify is true, TLS accepts any certificate
+	// presented by the server and any host name in that certificate.
+	// In this mode, TLS is susceptible to man-in-the-middle attacks.
+	// This should be used only for testing.
+	InsecureSkipVerify bool
+
+	// CipherSuites is a list of supported cipher suites. If CipherSuites
+	// is nil, TLS uses a list of suites supported by the implementation.
+	CipherSuites []uint16
+
+	// PreferServerCipherSuites controls whether the server selects the
+	// client's most preferred ciphersuite, or the server's most preferred
+	// ciphersuite. If true then the server's preference, as expressed in
+	// the order of elements in CipherSuites, is used.
+	PreferServerCipherSuites bool
+
+	// SessionTicketsDisabled may be set to true to disable session ticket
+	// (resumption) support.
+	SessionTicketsDisabled bool
+
+	// SessionTicketKey is used by TLS servers to provide session
+	// resumption. See RFC 5077. If zero, it will be filled with
+	// random data before the first server handshake.
+	//
+	// If multiple servers are terminating connections for the same host
+	// they should all have the same SessionTicketKey. If the
+	// SessionTicketKey leaks, previously recorded and future TLS
+	// connections using that key are compromised.
+	SessionTicketKey [32]byte
+
+	// SessionCache is a cache of ClientSessionState entries for TLS session
+	// resumption.
+	ClientSessionCache ClientSessionCache
+
+	// MinVersion contains the minimum SSL/TLS version that is acceptable.
+	// If zero, then SSLv3 is taken as the minimum.
+	MinVersion uint16
+
+	// MaxVersion contains the maximum SSL/TLS version that is acceptable.
+	// If zero, then the maximum version supported by this package is used,
+	// which is currently TLS 1.2.
+	MaxVersion uint16
+
+	// CurvePreferences contains the elliptic curves that will be used in
+	// an ECDHE handshake, in preference order. If empty, the default will
+	// be used.
+	CurvePreferences []CurveID
+
+	serverInitOnce sync.Once // guards calling (*Config).serverInit
+}
+
+func (c *Config) serverInit() {
+	if c.SessionTicketsDisabled {
+		return
+	}
+
+	// If the key has already been set then we have nothing to do.
+	for _, b := range c.SessionTicketKey {
+		if b != 0 {
+			return
+		}
+	}
+
+	if _, err := io.ReadFull(c.rand(), c.SessionTicketKey[:]); err != nil {
+		c.SessionTicketsDisabled = true
+	}
+}
+
+func (c *Config) rand() io.Reader {
+	r := c.Rand
+	if r == nil {
+		return rand.Reader
+	}
+	return r
+}
+
+func (c *Config) time() time.Time {
+	t := c.Time
+	if t == nil {
+		t = time.Now
+	}
+	return t()
+}
+
+func (c *Config) cipherSuites() []uint16 {
+	s := c.CipherSuites
+	if s == nil {
+		s = defaultCipherSuites()
+	}
+	return s
+}
+
+func (c *Config) minVersion() uint16 {
+	if c == nil || c.MinVersion == 0 {
+		return minVersion
+	}
+	return c.MinVersion
+}
+
+func (c *Config) maxVersion() uint16 {
+	if c == nil || c.MaxVersion == 0 {
+		return maxVersion
+	}
+	return c.MaxVersion
+}
+
+var defaultCurvePreferences = []CurveID{CurveP256, CurveP384, CurveP521}
+
+func (c *Config) curvePreferences() []CurveID {
+	if c == nil || len(c.CurvePreferences) == 0 {
+		return defaultCurvePreferences
+	}
+	return c.CurvePreferences
+}
+
+// mutualVersion returns the protocol version to use given the advertised
+// version of the peer.
+func (c *Config) mutualVersion(vers uint16) (uint16, bool) {
+	minVersion := c.minVersion()
+	maxVersion := c.maxVersion()
+
+	if vers < minVersion {
+		return 0, false
+	}
+	if vers > maxVersion {
+		vers = maxVersion
+	}
+	return vers, true
+}
+
+// getCertificate returns the best certificate for the given ClientHelloInfo,
+// defaulting to the first element of c.Certificates.
+func (c *Config) getCertificate(clientHello *ClientHelloInfo) (*Certificate, error) {
+	if c.GetCertificate != nil {
+		cert, err := c.GetCertificate(clientHello)
+		if cert != nil || err != nil {
+			return cert, err
+		}
+	}
+
+	if len(c.Certificates) == 1 || c.NameToCertificate == nil {
+		// There's only one choice, so no point doing any work.
+		return &c.Certificates[0], nil
+	}
+
+	name := strings.ToLower(clientHello.ServerName)
+	for len(name) > 0 && name[len(name)-1] == '.' {
+		name = name[:len(name)-1]
+	}
+
+	if cert, ok := c.NameToCertificate[name]; ok {
+		return cert, nil
+	}
+
+	// try replacing labels in the name with wildcards until we get a
+	// match.
+	labels := strings.Split(name, ".")
+	for i := range labels {
+		labels[i] = "*"
+		candidate := strings.Join(labels, ".")
+		if cert, ok := c.NameToCertificate[candidate]; ok {
+			return cert, nil
+		}
+	}
+
+	// If nothing matches, return the first certificate.
+	return &c.Certificates[0], nil
+}
+
+// BuildNameToCertificate parses c.Certificates and builds c.NameToCertificate
+// from the CommonName and SubjectAlternateName fields of each of the leaf
+// certificates.
+func (c *Config) BuildNameToCertificate() {
+	c.NameToCertificate = make(map[string]*Certificate)
+	for i := range c.Certificates {
+		cert := &c.Certificates[i]
+		x509Cert, err := x509.ParseCertificate(cert.Certificate[0])
+		if err != nil {
+			continue
+		}
+		if len(x509Cert.Subject.CommonName) > 0 {
+			c.NameToCertificate[x509Cert.Subject.CommonName] = cert
+		}
+		for _, san := range x509Cert.DNSNames {
+			c.NameToCertificate[san] = cert
+		}
+	}
+}
+
+// A Certificate is a chain of one or more certificates, leaf first.
+type Certificate struct {
+	Certificate [][]byte
+	// PrivateKey contains the private key corresponding to the public key
+	// in Leaf. For a server, this must be a *rsa.PrivateKey or
+	// *ecdsa.PrivateKey. For a client doing client authentication, this
+	// can be any type that implements crypto.Signer (which includes RSA
+	// and ECDSA private keys).
+	PrivateKey crypto.PrivateKey
+	// OCSPStaple contains an optional OCSP response which will be served
+	// to clients that request it.
+	OCSPStaple []byte
+	// Leaf is the parsed form of the leaf certificate, which may be
+	// initialized using x509.ParseCertificate to reduce per-handshake
+	// processing for TLS clients doing client authentication. If nil, the
+	// leaf certificate will be parsed as needed.
+	Leaf *x509.Certificate
+}
+
+// A TLS record.
+type record struct {
+	contentType  recordType
+	major, minor uint8
+	payload      []byte
+}
+
+type handshakeMessage interface {
+	marshal() []byte
+	unmarshal([]byte) bool
+}
+
+// lruSessionCache is a ClientSessionCache implementation that uses an LRU
+// caching strategy.
+type lruSessionCache struct {
+	sync.Mutex
+
+	m        map[string]*list.Element
+	q        *list.List
+	capacity int
+}
+
+type lruSessionCacheEntry struct {
+	sessionKey string
+	state      *ClientSessionState
+}
+
+// NewLRUClientSessionCache returns a ClientSessionCache with the given
+// capacity that uses an LRU strategy. If capacity is < 1, a default capacity
+// is used instead.
+func NewLRUClientSessionCache(capacity int) ClientSessionCache {
+	const defaultSessionCacheCapacity = 64
+
+	if capacity < 1 {
+		capacity = defaultSessionCacheCapacity
+	}
+	return &lruSessionCache{
+		m:        make(map[string]*list.Element),
+		q:        list.New(),
+		capacity: capacity,
+	}
+}
+
+// Put adds the provided (sessionKey, cs) pair to the cache.
+func (c *lruSessionCache) Put(sessionKey string, cs *ClientSessionState) {
+	c.Lock()
+	defer c.Unlock()
+
+	if elem, ok := c.m[sessionKey]; ok {
+		entry := elem.Value.(*lruSessionCacheEntry)
+		entry.state = cs
+		c.q.MoveToFront(elem)
+		return
+	}
+
+	if c.q.Len() < c.capacity {
+		entry := &lruSessionCacheEntry{sessionKey, cs}
+		c.m[sessionKey] = c.q.PushFront(entry)
+		return
+	}
+
+	elem := c.q.Back()
+	entry := elem.Value.(*lruSessionCacheEntry)
+	delete(c.m, entry.sessionKey)
+	entry.sessionKey = sessionKey
+	entry.state = cs
+	c.q.MoveToFront(elem)
+	c.m[sessionKey] = elem
+}
+
+// Get returns the ClientSessionState value associated with a given key. It
+// returns (nil, false) if no value is found.
+func (c *lruSessionCache) Get(sessionKey string) (*ClientSessionState, bool) {
+	c.Lock()
+	defer c.Unlock()
+
+	if elem, ok := c.m[sessionKey]; ok {
+		c.q.MoveToFront(elem)
+		return elem.Value.(*lruSessionCacheEntry).state, true
+	}
+	return nil, false
+}
+
+// TODO(jsing): Make these available to both crypto/x509 and crypto/tls.
+type dsaSignature struct {
+	R, S *big.Int
+}
+
+type ecdsaSignature dsaSignature
+
+var emptyConfig Config
+
+func defaultConfig() *Config {
+	return &emptyConfig
+}
+
+var (
+	once                   sync.Once
+	varDefaultCipherSuites []uint16
+)
+
+func defaultCipherSuites() []uint16 {
+	once.Do(initDefaultCipherSuites)
+	return varDefaultCipherSuites
+}
+
+func initDefaultCipherSuites() {
+	varDefaultCipherSuites = make([]uint16, len(cipherSuites))
+	for i, suite := range cipherSuites {
+		varDefaultCipherSuites[i] = suite.id
+	}
+}
+
+func unexpectedMessageError(wanted, got interface{}) error {
+	return fmt.Errorf("tls: received unexpected handshake message of type %T when waiting for %T", got, wanted)
+}
diff --git a/src/crypto/tls/conn.go b/src/crypto/tls/conn.go
new file mode 100644
index 0000000..ba8e4c2
--- /dev/null
+++ b/src/crypto/tls/conn.go
@@ -0,0 +1,1030 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// TLS low level connection and record layer
+
+package tls
+
+import (
+	"bytes"
+	"crypto/cipher"
+	"crypto/subtle"
+	"crypto/x509"
+	"errors"
+	"fmt"
+	"io"
+	"net"
+	"sync"
+	"time"
+)
+
+// A Conn represents a secured connection.
+// It implements the net.Conn interface.
+type Conn struct {
+	// constant
+	conn     net.Conn
+	isClient bool
+
+	// constant after handshake; protected by handshakeMutex
+	handshakeMutex    sync.Mutex // handshakeMutex < in.Mutex, out.Mutex, errMutex
+	handshakeErr      error      // error resulting from handshake
+	vers              uint16     // TLS version
+	haveVers          bool       // version has been negotiated
+	config            *Config    // configuration passed to constructor
+	handshakeComplete bool
+	didResume         bool // whether this connection was a session resumption
+	cipherSuite       uint16
+	ocspResponse      []byte // stapled OCSP response
+	peerCertificates  []*x509.Certificate
+	// verifiedChains contains the certificate chains that we built, as
+	// opposed to the ones presented by the server.
+	verifiedChains [][]*x509.Certificate
+	// serverName contains the server name indicated by the client, if any.
+	serverName string
+	// firstFinished contains the first Finished hash sent during the
+	// handshake. This is the "tls-unique" channel binding value.
+	firstFinished [12]byte
+
+	clientProtocol         string
+	clientProtocolFallback bool
+
+	// input/output
+	in, out  halfConn     // in.Mutex < out.Mutex
+	rawInput *block       // raw input, right off the wire
+	input    *block       // application data waiting to be read
+	hand     bytes.Buffer // handshake data waiting to be read
+
+	tmp [16]byte
+}
+
+// Access to net.Conn methods.
+// Cannot just embed net.Conn because that would
+// export the struct field too.
+
+// LocalAddr returns the local network address.
+func (c *Conn) LocalAddr() net.Addr {
+	return c.conn.LocalAddr()
+}
+
+// RemoteAddr returns the remote network address.
+func (c *Conn) RemoteAddr() net.Addr {
+	return c.conn.RemoteAddr()
+}
+
+// SetDeadline sets the read and write deadlines associated with the connection.
+// A zero value for t means Read and Write will not time out.
+// After a Write has timed out, the TLS state is corrupt and all future writes will return the same error.
+func (c *Conn) SetDeadline(t time.Time) error {
+	return c.conn.SetDeadline(t)
+}
+
+// SetReadDeadline sets the read deadline on the underlying connection.
+// A zero value for t means Read will not time out.
+func (c *Conn) SetReadDeadline(t time.Time) error {
+	return c.conn.SetReadDeadline(t)
+}
+
+// SetWriteDeadline sets the write deadline on the underlying connection.
+// A zero value for t means Write will not time out.
+// After a Write has timed out, the TLS state is corrupt and all future writes will return the same error.
+func (c *Conn) SetWriteDeadline(t time.Time) error {
+	return c.conn.SetWriteDeadline(t)
+}
+
+// A halfConn represents one direction of the record layer
+// connection, either sending or receiving.
+type halfConn struct {
+	sync.Mutex
+
+	err     error       // first permanent error
+	version uint16      // protocol version
+	cipher  interface{} // cipher algorithm
+	mac     macFunction
+	seq     [8]byte // 64-bit sequence number
+	bfree   *block  // list of free blocks
+
+	nextCipher interface{} // next encryption state
+	nextMac    macFunction // next MAC algorithm
+
+	// used to save allocating a new buffer for each MAC.
+	inDigestBuf, outDigestBuf []byte
+}
+
+func (hc *halfConn) setErrorLocked(err error) error {
+	hc.err = err
+	return err
+}
+
+func (hc *halfConn) error() error {
+	hc.Lock()
+	err := hc.err
+	hc.Unlock()
+	return err
+}
+
+// prepareCipherSpec sets the encryption and MAC states
+// that a subsequent changeCipherSpec will use.
+func (hc *halfConn) prepareCipherSpec(version uint16, cipher interface{}, mac macFunction) {
+	hc.version = version
+	hc.nextCipher = cipher
+	hc.nextMac = mac
+}
+
+// changeCipherSpec changes the encryption and MAC states
+// to the ones previously passed to prepareCipherSpec.
+func (hc *halfConn) changeCipherSpec() error {
+	if hc.nextCipher == nil {
+		return alertInternalError
+	}
+	hc.cipher = hc.nextCipher
+	hc.mac = hc.nextMac
+	hc.nextCipher = nil
+	hc.nextMac = nil
+	for i := range hc.seq {
+		hc.seq[i] = 0
+	}
+	return nil
+}
+
+// incSeq increments the sequence number.
+func (hc *halfConn) incSeq() {
+	for i := 7; i >= 0; i-- {
+		hc.seq[i]++
+		if hc.seq[i] != 0 {
+			return
+		}
+	}
+
+	// Not allowed to let sequence number wrap.
+	// Instead, must renegotiate before it does.
+	// Not likely enough to bother.
+	panic("TLS: sequence number wraparound")
+}
+
+// resetSeq resets the sequence number to zero.
+func (hc *halfConn) resetSeq() {
+	for i := range hc.seq {
+		hc.seq[i] = 0
+	}
+}
+
+// removePadding returns an unpadded slice, in constant time, which is a prefix
+// of the input. It also returns a byte which is equal to 255 if the padding
+// was valid and 0 otherwise. See RFC 2246, section 6.2.3.2
+func removePadding(payload []byte) ([]byte, byte) {
+	if len(payload) < 1 {
+		return payload, 0
+	}
+
+	paddingLen := payload[len(payload)-1]
+	t := uint(len(payload)-1) - uint(paddingLen)
+	// if len(payload) >= (paddingLen - 1) then the MSB of t is zero
+	good := byte(int32(^t) >> 31)
+
+	toCheck := 255 // the maximum possible padding length
+	// The length of the padded data is public, so we can use an if here
+	if toCheck+1 > len(payload) {
+		toCheck = len(payload) - 1
+	}
+
+	for i := 0; i < toCheck; i++ {
+		t := uint(paddingLen) - uint(i)
+		// if i <= paddingLen then the MSB of t is zero
+		mask := byte(int32(^t) >> 31)
+		b := payload[len(payload)-1-i]
+		good &^= mask&paddingLen ^ mask&b
+	}
+
+	// We AND together the bits of good and replicate the result across
+	// all the bits.
+	good &= good << 4
+	good &= good << 2
+	good &= good << 1
+	good = uint8(int8(good) >> 7)
+
+	toRemove := good&paddingLen + 1
+	return payload[:len(payload)-int(toRemove)], good
+}
+
+// removePaddingSSL30 is a replacement for removePadding in the case that the
+// protocol version is SSLv3. In this version, the contents of the padding
+// are random and cannot be checked.
+func removePaddingSSL30(payload []byte) ([]byte, byte) {
+	if len(payload) < 1 {
+		return payload, 0
+	}
+
+	paddingLen := int(payload[len(payload)-1]) + 1
+	if paddingLen > len(payload) {
+		return payload, 0
+	}
+
+	return payload[:len(payload)-paddingLen], 255
+}
+
+func roundUp(a, b int) int {
+	return a + (b-a%b)%b
+}
+
+// cbcMode is an interface for block ciphers using cipher block chaining.
+type cbcMode interface {
+	cipher.BlockMode
+	SetIV([]byte)
+}
+
+// decrypt checks and strips the mac and decrypts the data in b. Returns a
+// success boolean, the number of bytes to skip from the start of the record in
+// order to get the application payload, and an optional alert value.
+func (hc *halfConn) decrypt(b *block) (ok bool, prefixLen int, alertValue alert) {
+	// pull out payload
+	payload := b.data[recordHeaderLen:]
+
+	macSize := 0
+	if hc.mac != nil {
+		macSize = hc.mac.Size()
+	}
+
+	paddingGood := byte(255)
+	explicitIVLen := 0
+
+	// decrypt
+	if hc.cipher != nil {
+		switch c := hc.cipher.(type) {
+		case cipher.Stream:
+			c.XORKeyStream(payload, payload)
+		case cipher.AEAD:
+			explicitIVLen = 8
+			if len(payload) < explicitIVLen {
+				return false, 0, alertBadRecordMAC
+			}
+			nonce := payload[:8]
+			payload = payload[8:]
+
+			var additionalData [13]byte
+			copy(additionalData[:], hc.seq[:])
+			copy(additionalData[8:], b.data[:3])
+			n := len(payload) - c.Overhead()
+			additionalData[11] = byte(n >> 8)
+			additionalData[12] = byte(n)
+			var err error
+			payload, err = c.Open(payload[:0], nonce, payload, additionalData[:])
+			if err != nil {
+				return false, 0, alertBadRecordMAC
+			}
+			b.resize(recordHeaderLen + explicitIVLen + len(payload))
+		case cbcMode:
+			blockSize := c.BlockSize()
+			if hc.version >= VersionTLS11 {
+				explicitIVLen = blockSize
+			}
+
+			if len(payload)%blockSize != 0 || len(payload) < roundUp(explicitIVLen+macSize+1, blockSize) {
+				return false, 0, alertBadRecordMAC
+			}
+
+			if explicitIVLen > 0 {
+				c.SetIV(payload[:explicitIVLen])
+				payload = payload[explicitIVLen:]
+			}
+			c.CryptBlocks(payload, payload)
+			if hc.version == VersionSSL30 {
+				payload, paddingGood = removePaddingSSL30(payload)
+			} else {
+				payload, paddingGood = removePadding(payload)
+			}
+			b.resize(recordHeaderLen + explicitIVLen + len(payload))
+
+			// note that we still have a timing side-channel in the
+			// MAC check, below. An attacker can align the record
+			// so that a correct padding will cause one less hash
+			// block to be calculated. Then they can iteratively
+			// decrypt a record by breaking each byte. See
+			// "Password Interception in a SSL/TLS Channel", Brice
+			// Canvel et al.
+			//
+			// However, our behavior matches OpenSSL, so we leak
+			// only as much as they do.
+		default:
+			panic("unknown cipher type")
+		}
+	}
+
+	// check, strip mac
+	if hc.mac != nil {
+		if len(payload) < macSize {
+			return false, 0, alertBadRecordMAC
+		}
+
+		// strip mac off payload, b.data
+		n := len(payload) - macSize
+		b.data[3] = byte(n >> 8)
+		b.data[4] = byte(n)
+		b.resize(recordHeaderLen + explicitIVLen + n)
+		remoteMAC := payload[n:]
+		localMAC := hc.mac.MAC(hc.inDigestBuf, hc.seq[0:], b.data[:recordHeaderLen], payload[:n])
+
+		if subtle.ConstantTimeCompare(localMAC, remoteMAC) != 1 || paddingGood != 255 {
+			return false, 0, alertBadRecordMAC
+		}
+		hc.inDigestBuf = localMAC
+	}
+	hc.incSeq()
+
+	return true, recordHeaderLen + explicitIVLen, 0
+}
+
+// padToBlockSize calculates the needed padding block, if any, for a payload.
+// On exit, prefix aliases payload and extends to the end of the last full
+// block of payload. finalBlock is a fresh slice which contains the contents of
+// any suffix of payload as well as the needed padding to make finalBlock a
+// full block.
+func padToBlockSize(payload []byte, blockSize int) (prefix, finalBlock []byte) {
+	overrun := len(payload) % blockSize
+	paddingLen := blockSize - overrun
+	prefix = payload[:len(payload)-overrun]
+	finalBlock = make([]byte, blockSize)
+	copy(finalBlock, payload[len(payload)-overrun:])
+	for i := overrun; i < blockSize; i++ {
+		finalBlock[i] = byte(paddingLen - 1)
+	}
+	return
+}
+
+// encrypt encrypts and macs the data in b.
+func (hc *halfConn) encrypt(b *block, explicitIVLen int) (bool, alert) {
+	// mac
+	if hc.mac != nil {
+		mac := hc.mac.MAC(hc.outDigestBuf, hc.seq[0:], b.data[:recordHeaderLen], b.data[recordHeaderLen+explicitIVLen:])
+
+		n := len(b.data)
+		b.resize(n + len(mac))
+		copy(b.data[n:], mac)
+		hc.outDigestBuf = mac
+	}
+
+	payload := b.data[recordHeaderLen:]
+
+	// encrypt
+	if hc.cipher != nil {
+		switch c := hc.cipher.(type) {
+		case cipher.Stream:
+			c.XORKeyStream(payload, payload)
+		case cipher.AEAD:
+			payloadLen := len(b.data) - recordHeaderLen - explicitIVLen
+			b.resize(len(b.data) + c.Overhead())
+			nonce := b.data[recordHeaderLen : recordHeaderLen+explicitIVLen]
+			payload := b.data[recordHeaderLen+explicitIVLen:]
+			payload = payload[:payloadLen]
+
+			var additionalData [13]byte
+			copy(additionalData[:], hc.seq[:])
+			copy(additionalData[8:], b.data[:3])
+			additionalData[11] = byte(payloadLen >> 8)
+			additionalData[12] = byte(payloadLen)
+
+			c.Seal(payload[:0], nonce, payload, additionalData[:])
+		case cbcMode:
+			blockSize := c.BlockSize()
+			if explicitIVLen > 0 {
+				c.SetIV(payload[:explicitIVLen])
+				payload = payload[explicitIVLen:]
+			}
+			prefix, finalBlock := padToBlockSize(payload, blockSize)
+			b.resize(recordHeaderLen + explicitIVLen + len(prefix) + len(finalBlock))
+			c.CryptBlocks(b.data[recordHeaderLen+explicitIVLen:], prefix)
+			c.CryptBlocks(b.data[recordHeaderLen+explicitIVLen+len(prefix):], finalBlock)
+		default:
+			panic("unknown cipher type")
+		}
+	}
+
+	// update length to include MAC and any block padding needed.
+	n := len(b.data) - recordHeaderLen
+	b.data[3] = byte(n >> 8)
+	b.data[4] = byte(n)
+	hc.incSeq()
+
+	return true, 0
+}
+
+// A block is a simple data buffer.
+type block struct {
+	data []byte
+	off  int // index for Read
+	link *block
+}
+
+// resize resizes block to be n bytes, growing if necessary.
+func (b *block) resize(n int) {
+	if n > cap(b.data) {
+		b.reserve(n)
+	}
+	b.data = b.data[0:n]
+}
+
+// reserve makes sure that block contains a capacity of at least n bytes.
+func (b *block) reserve(n int) {
+	if cap(b.data) >= n {
+		return
+	}
+	m := cap(b.data)
+	if m == 0 {
+		m = 1024
+	}
+	for m < n {
+		m *= 2
+	}
+	data := make([]byte, len(b.data), m)
+	copy(data, b.data)
+	b.data = data
+}
+
+// readFromUntil reads from r into b until b contains at least n bytes
+// or else returns an error.
+func (b *block) readFromUntil(r io.Reader, n int) error {
+	// quick case
+	if len(b.data) >= n {
+		return nil
+	}
+
+	// read until have enough.
+	b.reserve(n)
+	for {
+		m, err := r.Read(b.data[len(b.data):cap(b.data)])
+		b.data = b.data[0 : len(b.data)+m]
+		if len(b.data) >= n {
+			// TODO(bradfitz,agl): slightly suspicious
+			// that we're throwing away r.Read's err here.
+			break
+		}
+		if err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+func (b *block) Read(p []byte) (n int, err error) {
+	n = copy(p, b.data[b.off:])
+	b.off += n
+	return
+}
+
+// newBlock allocates a new block, from hc's free list if possible.
+func (hc *halfConn) newBlock() *block {
+	b := hc.bfree
+	if b == nil {
+		return new(block)
+	}
+	hc.bfree = b.link
+	b.link = nil
+	b.resize(0)
+	return b
+}
+
+// freeBlock returns a block to hc's free list.
+// The protocol is such that each side only has a block or two on
+// its free list at a time, so there's no need to worry about
+// trimming the list, etc.
+func (hc *halfConn) freeBlock(b *block) {
+	b.link = hc.bfree
+	hc.bfree = b
+}
+
+// splitBlock splits a block after the first n bytes,
+// returning a block with those n bytes and a
+// block with the remainder.  the latter may be nil.
+func (hc *halfConn) splitBlock(b *block, n int) (*block, *block) {
+	if len(b.data) <= n {
+		return b, nil
+	}
+	bb := hc.newBlock()
+	bb.resize(len(b.data) - n)
+	copy(bb.data, b.data[n:])
+	b.data = b.data[0:n]
+	return b, bb
+}
+
+// readRecord reads the next TLS record from the connection
+// and updates the record layer state.
+// c.in.Mutex <= L; c.input == nil.
+func (c *Conn) readRecord(want recordType) error {
+	// Caller must be in sync with connection:
+	// handshake data if handshake not yet completed,
+	// else application data.  (We don't support renegotiation.)
+	switch want {
+	default:
+		c.sendAlert(alertInternalError)
+		return c.in.setErrorLocked(errors.New("tls: unknown record type requested"))
+	case recordTypeHandshake, recordTypeChangeCipherSpec:
+		if c.handshakeComplete {
+			c.sendAlert(alertInternalError)
+			return c.in.setErrorLocked(errors.New("tls: handshake or ChangeCipherSpec requested after handshake complete"))
+		}
+	case recordTypeApplicationData:
+		if !c.handshakeComplete {
+			c.sendAlert(alertInternalError)
+			return c.in.setErrorLocked(errors.New("tls: application data record requested before handshake complete"))
+		}
+	}
+
+Again:
+	if c.rawInput == nil {
+		c.rawInput = c.in.newBlock()
+	}
+	b := c.rawInput
+
+	// Read header, payload.
+	if err := b.readFromUntil(c.conn, recordHeaderLen); err != nil {
+		// RFC suggests that EOF without an alertCloseNotify is
+		// an error, but popular web sites seem to do this,
+		// so we can't make it an error.
+		// if err == io.EOF {
+		// 	err = io.ErrUnexpectedEOF
+		// }
+		if e, ok := err.(net.Error); !ok || !e.Temporary() {
+			c.in.setErrorLocked(err)
+		}
+		return err
+	}
+	typ := recordType(b.data[0])
+
+	// No valid TLS record has a type of 0x80, however SSLv2 handshakes
+	// start with a uint16 length where the MSB is set and the first record
+	// is always < 256 bytes long. Therefore typ == 0x80 strongly suggests
+	// an SSLv2 client.
+	if want == recordTypeHandshake && typ == 0x80 {
+		c.sendAlert(alertProtocolVersion)
+		return c.in.setErrorLocked(errors.New("tls: unsupported SSLv2 handshake received"))
+	}
+
+	vers := uint16(b.data[1])<<8 | uint16(b.data[2])
+	n := int(b.data[3])<<8 | int(b.data[4])
+	if c.haveVers && vers != c.vers {
+		c.sendAlert(alertProtocolVersion)
+		return c.in.setErrorLocked(fmt.Errorf("tls: received record with version %x when expecting version %x", vers, c.vers))
+	}
+	if n > maxCiphertext {
+		c.sendAlert(alertRecordOverflow)
+		return c.in.setErrorLocked(fmt.Errorf("tls: oversized record received with length %d", n))
+	}
+	if !c.haveVers {
+		// First message, be extra suspicious:
+		// this might not be a TLS client.
+		// Bail out before reading a full 'body', if possible.
+		// The current max version is 3.1.
+		// If the version is >= 16.0, it's probably not real.
+		// Similarly, a clientHello message encodes in
+		// well under a kilobyte.  If the length is >= 12 kB,
+		// it's probably not real.
+		if (typ != recordTypeAlert && typ != want) || vers >= 0x1000 || n >= 0x3000 {
+			c.sendAlert(alertUnexpectedMessage)
+			return c.in.setErrorLocked(fmt.Errorf("tls: first record does not look like a TLS handshake"))
+		}
+	}
+	if err := b.readFromUntil(c.conn, recordHeaderLen+n); err != nil {
+		if err == io.EOF {
+			err = io.ErrUnexpectedEOF
+		}
+		if e, ok := err.(net.Error); !ok || !e.Temporary() {
+			c.in.setErrorLocked(err)
+		}
+		return err
+	}
+
+	// Process message.
+	b, c.rawInput = c.in.splitBlock(b, recordHeaderLen+n)
+	ok, off, err := c.in.decrypt(b)
+	if !ok {
+		c.in.setErrorLocked(c.sendAlert(err))
+	}
+	b.off = off
+	data := b.data[b.off:]
+	if len(data) > maxPlaintext {
+		err := c.sendAlert(alertRecordOverflow)
+		c.in.freeBlock(b)
+		return c.in.setErrorLocked(err)
+	}
+
+	switch typ {
+	default:
+		c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
+
+	case recordTypeAlert:
+		if len(data) != 2 {
+			c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
+			break
+		}
+		if alert(data[1]) == alertCloseNotify {
+			c.in.setErrorLocked(io.EOF)
+			break
+		}
+		switch data[0] {
+		case alertLevelWarning:
+			// drop on the floor
+			c.in.freeBlock(b)
+			goto Again
+		case alertLevelError:
+			c.in.setErrorLocked(&net.OpError{Op: "remote error", Err: alert(data[1])})
+		default:
+			c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
+		}
+
+	case recordTypeChangeCipherSpec:
+		if typ != want || len(data) != 1 || data[0] != 1 {
+			c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
+			break
+		}
+		err := c.in.changeCipherSpec()
+		if err != nil {
+			c.in.setErrorLocked(c.sendAlert(err.(alert)))
+		}
+
+	case recordTypeApplicationData:
+		if typ != want {
+			c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
+			break
+		}
+		c.input = b
+		b = nil
+
+	case recordTypeHandshake:
+		// TODO(rsc): Should at least pick off connection close.
+		if typ != want {
+			return c.in.setErrorLocked(c.sendAlert(alertNoRenegotiation))
+		}
+		c.hand.Write(data)
+	}
+
+	if b != nil {
+		c.in.freeBlock(b)
+	}
+	return c.in.err
+}
+
+// sendAlert sends a TLS alert message.
+// c.out.Mutex <= L.
+func (c *Conn) sendAlertLocked(err alert) error {
+	switch err {
+	case alertNoRenegotiation, alertCloseNotify:
+		c.tmp[0] = alertLevelWarning
+	default:
+		c.tmp[0] = alertLevelError
+	}
+	c.tmp[1] = byte(err)
+	c.writeRecord(recordTypeAlert, c.tmp[0:2])
+	// closeNotify is a special case in that it isn't an error:
+	if err != alertCloseNotify {
+		return c.out.setErrorLocked(&net.OpError{Op: "local error", Err: err})
+	}
+	return nil
+}
+
+// sendAlert sends a TLS alert message.
+// L < c.out.Mutex.
+func (c *Conn) sendAlert(err alert) error {
+	c.out.Lock()
+	defer c.out.Unlock()
+	return c.sendAlertLocked(err)
+}
+
+// writeRecord writes a TLS record with the given type and payload
+// to the connection and updates the record layer state.
+// c.out.Mutex <= L.
+func (c *Conn) writeRecord(typ recordType, data []byte) (n int, err error) {
+	b := c.out.newBlock()
+	for len(data) > 0 {
+		m := len(data)
+		if m > maxPlaintext {
+			m = maxPlaintext
+		}
+		explicitIVLen := 0
+		explicitIVIsSeq := false
+
+		var cbc cbcMode
+		if c.out.version >= VersionTLS11 {
+			var ok bool
+			if cbc, ok = c.out.cipher.(cbcMode); ok {
+				explicitIVLen = cbc.BlockSize()
+			}
+		}
+		if explicitIVLen == 0 {
+			if _, ok := c.out.cipher.(cipher.AEAD); ok {
+				explicitIVLen = 8
+				// The AES-GCM construction in TLS has an
+				// explicit nonce so that the nonce can be
+				// random. However, the nonce is only 8 bytes
+				// which is too small for a secure, random
+				// nonce. Therefore we use the sequence number
+				// as the nonce.
+				explicitIVIsSeq = true
+			}
+		}
+		b.resize(recordHeaderLen + explicitIVLen + m)
+		b.data[0] = byte(typ)
+		vers := c.vers
+		if vers == 0 {
+			// Some TLS servers fail if the record version is
+			// greater than TLS 1.0 for the initial ClientHello.
+			vers = VersionTLS10
+		}
+		b.data[1] = byte(vers >> 8)
+		b.data[2] = byte(vers)
+		b.data[3] = byte(m >> 8)
+		b.data[4] = byte(m)
+		if explicitIVLen > 0 {
+			explicitIV := b.data[recordHeaderLen : recordHeaderLen+explicitIVLen]
+			if explicitIVIsSeq {
+				copy(explicitIV, c.out.seq[:])
+			} else {
+				if _, err = io.ReadFull(c.config.rand(), explicitIV); err != nil {
+					break
+				}
+			}
+		}
+		copy(b.data[recordHeaderLen+explicitIVLen:], data)
+		c.out.encrypt(b, explicitIVLen)
+		_, err = c.conn.Write(b.data)
+		if err != nil {
+			break
+		}
+		n += m
+		data = data[m:]
+	}
+	c.out.freeBlock(b)
+
+	if typ == recordTypeChangeCipherSpec {
+		err = c.out.changeCipherSpec()
+		if err != nil {
+			// Cannot call sendAlert directly,
+			// because we already hold c.out.Mutex.
+			c.tmp[0] = alertLevelError
+			c.tmp[1] = byte(err.(alert))
+			c.writeRecord(recordTypeAlert, c.tmp[0:2])
+			return n, c.out.setErrorLocked(&net.OpError{Op: "local error", Err: err})
+		}
+	}
+	return
+}
+
+// readHandshake reads the next handshake message from
+// the record layer.
+// c.in.Mutex < L; c.out.Mutex < L.
+func (c *Conn) readHandshake() (interface{}, error) {
+	for c.hand.Len() < 4 {
+		if err := c.in.err; err != nil {
+			return nil, err
+		}
+		if err := c.readRecord(recordTypeHandshake); err != nil {
+			return nil, err
+		}
+	}
+
+	data := c.hand.Bytes()
+	n := int(data[1])<<16 | int(data[2])<<8 | int(data[3])
+	if n > maxHandshake {
+		return nil, c.in.setErrorLocked(c.sendAlert(alertInternalError))
+	}
+	for c.hand.Len() < 4+n {
+		if err := c.in.err; err != nil {
+			return nil, err
+		}
+		if err := c.readRecord(recordTypeHandshake); err != nil {
+			return nil, err
+		}
+	}
+	data = c.hand.Next(4 + n)
+	var m handshakeMessage
+	switch data[0] {
+	case typeClientHello:
+		m = new(clientHelloMsg)
+	case typeServerHello:
+		m = new(serverHelloMsg)
+	case typeNewSessionTicket:
+		m = new(newSessionTicketMsg)
+	case typeCertificate:
+		m = new(certificateMsg)
+	case typeCertificateRequest:
+		m = &certificateRequestMsg{
+			hasSignatureAndHash: c.vers >= VersionTLS12,
+		}
+	case typeCertificateStatus:
+		m = new(certificateStatusMsg)
+	case typeServerKeyExchange:
+		m = new(serverKeyExchangeMsg)
+	case typeServerHelloDone:
+		m = new(serverHelloDoneMsg)
+	case typeClientKeyExchange:
+		m = new(clientKeyExchangeMsg)
+	case typeCertificateVerify:
+		m = &certificateVerifyMsg{
+			hasSignatureAndHash: c.vers >= VersionTLS12,
+		}
+	case typeNextProtocol:
+		m = new(nextProtoMsg)
+	case typeFinished:
+		m = new(finishedMsg)
+	default:
+		return nil, c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
+	}
+
+	// The handshake message unmarshallers
+	// expect to be able to keep references to data,
+	// so pass in a fresh copy that won't be overwritten.
+	data = append([]byte(nil), data...)
+
+	if !m.unmarshal(data) {
+		return nil, c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
+	}
+	return m, nil
+}
+
+// Write writes data to the connection.
+func (c *Conn) Write(b []byte) (int, error) {
+	if err := c.Handshake(); err != nil {
+		return 0, err
+	}
+
+	c.out.Lock()
+	defer c.out.Unlock()
+
+	if err := c.out.err; err != nil {
+		return 0, err
+	}
+
+	if !c.handshakeComplete {
+		return 0, alertInternalError
+	}
+
+	// SSL 3.0 and TLS 1.0 are susceptible to a chosen-plaintext
+	// attack when using block mode ciphers due to predictable IVs.
+	// This can be prevented by splitting each Application Data
+	// record into two records, effectively randomizing the IV.
+	//
+	// http://www.openssl.org/~bodo/tls-cbc.txt
+	// https://bugzilla.mozilla.org/show_bug.cgi?id=665814
+	// http://www.imperialviolet.org/2012/01/15/beastfollowup.html
+
+	var m int
+	if len(b) > 1 && c.vers <= VersionTLS10 {
+		if _, ok := c.out.cipher.(cipher.BlockMode); ok {
+			n, err := c.writeRecord(recordTypeApplicationData, b[:1])
+			if err != nil {
+				return n, c.out.setErrorLocked(err)
+			}
+			m, b = 1, b[1:]
+		}
+	}
+
+	n, err := c.writeRecord(recordTypeApplicationData, b)
+	return n + m, c.out.setErrorLocked(err)
+}
+
+// Read can be made to time out and return a net.Error with Timeout() == true
+// after a fixed time limit; see SetDeadline and SetReadDeadline.
+func (c *Conn) Read(b []byte) (n int, err error) {
+	if err = c.Handshake(); err != nil {
+		return
+	}
+	if len(b) == 0 {
+		// Put this after Handshake, in case people were calling
+		// Read(nil) for the side effect of the Handshake.
+		return
+	}
+
+	c.in.Lock()
+	defer c.in.Unlock()
+
+	// Some OpenSSL servers send empty records in order to randomize the
+	// CBC IV. So this loop ignores a limited number of empty records.
+	const maxConsecutiveEmptyRecords = 100
+	for emptyRecordCount := 0; emptyRecordCount <= maxConsecutiveEmptyRecords; emptyRecordCount++ {
+		for c.input == nil && c.in.err == nil {
+			if err := c.readRecord(recordTypeApplicationData); err != nil {
+				// Soft error, like EAGAIN
+				return 0, err
+			}
+		}
+		if err := c.in.err; err != nil {
+			return 0, err
+		}
+
+		n, err = c.input.Read(b)
+		if c.input.off >= len(c.input.data) {
+			c.in.freeBlock(c.input)
+			c.input = nil
+		}
+
+		// If a close-notify alert is waiting, read it so that
+		// we can return (n, EOF) instead of (n, nil), to signal
+		// to the HTTP response reading goroutine that the
+		// connection is now closed. This eliminates a race
+		// where the HTTP response reading goroutine would
+		// otherwise not observe the EOF until its next read,
+		// by which time a client goroutine might have already
+		// tried to reuse the HTTP connection for a new
+		// request.
+		// See https://codereview.appspot.com/76400046
+		// and http://golang.org/issue/3514
+		if ri := c.rawInput; ri != nil &&
+			n != 0 && err == nil &&
+			c.input == nil && len(ri.data) > 0 && recordType(ri.data[0]) == recordTypeAlert {
+			if recErr := c.readRecord(recordTypeApplicationData); recErr != nil {
+				err = recErr // will be io.EOF on closeNotify
+			}
+		}
+
+		if n != 0 || err != nil {
+			return n, err
+		}
+	}
+
+	return 0, io.ErrNoProgress
+}
+
+// Close closes the connection.
+func (c *Conn) Close() error {
+	var alertErr error
+
+	c.handshakeMutex.Lock()
+	defer c.handshakeMutex.Unlock()
+	if c.handshakeComplete {
+		alertErr = c.sendAlert(alertCloseNotify)
+	}
+
+	if err := c.conn.Close(); err != nil {
+		return err
+	}
+	return alertErr
+}
+
+// Handshake runs the client or server handshake
+// protocol if it has not yet been run.
+// Most uses of this package need not call Handshake
+// explicitly: the first Read or Write will call it automatically.
+func (c *Conn) Handshake() error {
+	c.handshakeMutex.Lock()
+	defer c.handshakeMutex.Unlock()
+	if err := c.handshakeErr; err != nil {
+		return err
+	}
+	if c.handshakeComplete {
+		return nil
+	}
+
+	if c.isClient {
+		c.handshakeErr = c.clientHandshake()
+	} else {
+		c.handshakeErr = c.serverHandshake()
+	}
+	return c.handshakeErr
+}
+
+// ConnectionState returns basic TLS details about the connection.
+func (c *Conn) ConnectionState() ConnectionState {
+	c.handshakeMutex.Lock()
+	defer c.handshakeMutex.Unlock()
+
+	var state ConnectionState
+	state.HandshakeComplete = c.handshakeComplete
+	if c.handshakeComplete {
+		state.Version = c.vers
+		state.NegotiatedProtocol = c.clientProtocol
+		state.DidResume = c.didResume
+		state.NegotiatedProtocolIsMutual = !c.clientProtocolFallback
+		state.CipherSuite = c.cipherSuite
+		state.PeerCertificates = c.peerCertificates
+		state.VerifiedChains = c.verifiedChains
+		state.ServerName = c.serverName
+		if !c.didResume {
+			state.TLSUnique = c.firstFinished[:]
+		}
+	}
+
+	return state
+}
+
+// OCSPResponse returns the stapled OCSP response from the TLS server, if
+// any. (Only valid for client connections.)
+func (c *Conn) OCSPResponse() []byte {
+	c.handshakeMutex.Lock()
+	defer c.handshakeMutex.Unlock()
+
+	return c.ocspResponse
+}
+
+// VerifyHostname checks that the peer certificate chain is valid for
+// connecting to host.  If so, it returns nil; if not, it returns an error
+// describing the problem.
+func (c *Conn) VerifyHostname(host string) error {
+	c.handshakeMutex.Lock()
+	defer c.handshakeMutex.Unlock()
+	if !c.isClient {
+		return errors.New("tls: VerifyHostname called on TLS server connection")
+	}
+	if !c.handshakeComplete {
+		return errors.New("tls: handshake has not yet been performed")
+	}
+	return c.peerCertificates[0].VerifyHostname(host)
+}
diff --git a/src/crypto/tls/conn_test.go b/src/crypto/tls/conn_test.go
new file mode 100644
index 0000000..ec802ca
--- /dev/null
+++ b/src/crypto/tls/conn_test.go
@@ -0,0 +1,118 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tls
+
+import (
+	"testing"
+)
+
+func TestRoundUp(t *testing.T) {
+	if roundUp(0, 16) != 0 ||
+		roundUp(1, 16) != 16 ||
+		roundUp(15, 16) != 16 ||
+		roundUp(16, 16) != 16 ||
+		roundUp(17, 16) != 32 {
+		t.Error("roundUp broken")
+	}
+}
+
+var paddingTests = []struct {
+	in          []byte
+	good        bool
+	expectedLen int
+}{
+	{[]byte{1, 2, 3, 4, 0}, true, 4},
+	{[]byte{1, 2, 3, 4, 0, 1}, false, 0},
+	{[]byte{1, 2, 3, 4, 99, 99}, false, 0},
+	{[]byte{1, 2, 3, 4, 1, 1}, true, 4},
+	{[]byte{1, 2, 3, 2, 2, 2}, true, 3},
+	{[]byte{1, 2, 3, 3, 3, 3}, true, 2},
+	{[]byte{1, 2, 3, 4, 3, 3}, false, 0},
+	{[]byte{1, 4, 4, 4, 4, 4}, true, 1},
+	{[]byte{5, 5, 5, 5, 5, 5}, true, 0},
+	{[]byte{6, 6, 6, 6, 6, 6}, false, 0},
+}
+
+func TestRemovePadding(t *testing.T) {
+	for i, test := range paddingTests {
+		payload, good := removePadding(test.in)
+		expectedGood := byte(255)
+		if !test.good {
+			expectedGood = 0
+		}
+		if good != expectedGood {
+			t.Errorf("#%d: wrong validity, want:%d got:%d", i, expectedGood, good)
+		}
+		if good == 255 && len(payload) != test.expectedLen {
+			t.Errorf("#%d: got %d, want %d", i, len(payload), test.expectedLen)
+		}
+	}
+}
+
+var certExampleCom = `308201403081eda003020102020101300b06092a864886f70d010105301e311c301a060355040a131354657374696e67204365727469666963617465301e170d3131313030313138353835325a170d3132303933303138353835325a301e311c301a060355040a131354657374696e67204365727469666963617465305a300b06092a864886f70d010101034b003048024100bced6e32368599eeddf18796bfd03958a154f87e5b084f96e85136a56b886733592f493f0fc68b0d6b3551781cb95e13c5de458b28d6fb60d20a9129313261410203010001a31a301830160603551d11040f300d820b6578 [...]
+
+var certWildcardExampleCom = `308201423081efa003020102020101300b06092a864886f70d010105301e311c301a060355040a131354657374696e67204365727469666963617465301e170d3131313030313139303034365a170d3132303933303139303034365a301e311c301a060355040a131354657374696e67204365727469666963617465305a300b06092a864886f70d010101034b003048024100bced6e32368599eeddf18796bfd03958a154f87e5b084f96e85136a56b886733592f493f0fc68b0d6b3551781cb95e13c5de458b28d6fb60d20a9129313261410203010001a31c301a30180603551d110411300f [...]
+
+var certFooExampleCom = `308201443081f1a003020102020101300b06092a864886f70d010105301e311c301a060355040a131354657374696e67204365727469666963617465301e170d3131313030313139303131345a170d3132303933303139303131345a301e311c301a060355040a131354657374696e67204365727469666963617465305a300b06092a864886f70d010101034b003048024100bced6e32368599eeddf18796bfd03958a154f87e5b084f96e85136a56b886733592f493f0fc68b0d6b3551781cb95e13c5de458b28d6fb60d20a9129313261410203010001a31e301c301a0603551d1104133011820f6 [...]
+
+var certDoubleWildcardExampleCom = `308201443081f1a003020102020101300b06092a864886f70d010105301e311c301a060355040a131354657374696e67204365727469666963617465301e170d3131313030313139303134315a170d3132303933303139303134315a301e311c301a060355040a131354657374696e67204365727469666963617465305a300b06092a864886f70d010101034b003048024100bced6e32368599eeddf18796bfd03958a154f87e5b084f96e85136a56b886733592f493f0fc68b0d6b3551781cb95e13c5de458b28d6fb60d20a9129313261410203010001a31e301c301a0603551d1104 [...]
+
+func TestCertificateSelection(t *testing.T) {
+	config := Config{
+		Certificates: []Certificate{
+			{
+				Certificate: [][]byte{fromHex(certExampleCom)},
+			},
+			{
+				Certificate: [][]byte{fromHex(certWildcardExampleCom)},
+			},
+			{
+				Certificate: [][]byte{fromHex(certFooExampleCom)},
+			},
+			{
+				Certificate: [][]byte{fromHex(certDoubleWildcardExampleCom)},
+			},
+		},
+	}
+
+	config.BuildNameToCertificate()
+
+	pointerToIndex := func(c *Certificate) int {
+		for i := range config.Certificates {
+			if c == &config.Certificates[i] {
+				return i
+			}
+		}
+		return -1
+	}
+
+	certificateForName := func(name string) *Certificate {
+		clientHello := &ClientHelloInfo{
+			ServerName: name,
+		}
+		if cert, err := config.getCertificate(clientHello); err != nil {
+			t.Errorf("unable to get certificate for name '%s': %s", name, err)
+			return nil
+		} else {
+			return cert
+		}
+	}
+
+	if n := pointerToIndex(certificateForName("example.com")); n != 0 {
+		t.Errorf("example.com returned certificate %d, not 0", n)
+	}
+	if n := pointerToIndex(certificateForName("bar.example.com")); n != 1 {
+		t.Errorf("bar.example.com returned certificate %d, not 1", n)
+	}
+	if n := pointerToIndex(certificateForName("foo.example.com")); n != 2 {
+		t.Errorf("foo.example.com returned certificate %d, not 2", n)
+	}
+	if n := pointerToIndex(certificateForName("foo.bar.example.com")); n != 3 {
+		t.Errorf("foo.bar.example.com returned certificate %d, not 3", n)
+	}
+	if n := pointerToIndex(certificateForName("foo.bar.baz.example.com")); n != 0 {
+		t.Errorf("foo.bar.baz.example.com returned certificate %d, not 0", n)
+	}
+}
diff --git a/src/pkg/crypto/tls/example_test.go b/src/crypto/tls/example_test.go
similarity index 100%
rename from src/pkg/crypto/tls/example_test.go
rename to src/crypto/tls/example_test.go
diff --git a/src/crypto/tls/generate_cert.go b/src/crypto/tls/generate_cert.go
new file mode 100644
index 0000000..83f9916
--- /dev/null
+++ b/src/crypto/tls/generate_cert.go
@@ -0,0 +1,161 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build ignore
+
+// Generate a self-signed X.509 certificate for a TLS server. Outputs to
+// 'cert.pem' and 'key.pem' and will overwrite existing files.
+
+package main
+
+import (
+	"crypto/ecdsa"
+	"crypto/elliptic"
+	"crypto/rand"
+	"crypto/rsa"
+	"crypto/x509"
+	"crypto/x509/pkix"
+	"encoding/pem"
+	"flag"
+	"fmt"
+	"log"
+	"math/big"
+	"net"
+	"os"
+	"strings"
+	"time"
+)
+
+var (
+	host       = flag.String("host", "", "Comma-separated hostnames and IPs to generate a certificate for")
+	validFrom  = flag.String("start-date", "", "Creation date formatted as Jan 1 15:04:05 2011")
+	validFor   = flag.Duration("duration", 365*24*time.Hour, "Duration that certificate is valid for")
+	isCA       = flag.Bool("ca", false, "whether this cert should be its own Certificate Authority")
+	rsaBits    = flag.Int("rsa-bits", 2048, "Size of RSA key to generate. Ignored if --ecdsa-curve is set")
+	ecdsaCurve = flag.String("ecdsa-curve", "", "ECDSA curve to use to generate a key. Valid values are P224, P256, P384, P521")
+)
+
+func publicKey(priv interface{}) interface{} {
+	switch k := priv.(type) {
+	case *rsa.PrivateKey:
+		return &k.PublicKey
+	case *ecdsa.PrivateKey:
+		return &k.PublicKey
+	default:
+		return nil
+	}
+}
+
+func pemBlockForKey(priv interface{}) *pem.Block {
+	switch k := priv.(type) {
+	case *rsa.PrivateKey:
+		return &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(k)}
+	case *ecdsa.PrivateKey:
+		b, err := x509.MarshalECPrivateKey(k)
+		if err != nil {
+			fmt.Fprintf(os.Stderr, "Unable to marshal ECDSA private key: %v", err)
+			os.Exit(2)
+		}
+		return &pem.Block{Type: "EC PRIVATE KEY", Bytes: b}
+	default:
+		return nil
+	}
+}
+
+func main() {
+	flag.Parse()
+
+	if len(*host) == 0 {
+		log.Fatalf("Missing required --host parameter")
+	}
+
+	var priv interface{}
+	var err error
+	switch *ecdsaCurve {
+	case "":
+		priv, err = rsa.GenerateKey(rand.Reader, *rsaBits)
+	case "P224":
+		priv, err = ecdsa.GenerateKey(elliptic.P224(), rand.Reader)
+	case "P256":
+		priv, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
+	case "P384":
+		priv, err = ecdsa.GenerateKey(elliptic.P384(), rand.Reader)
+	case "P521":
+		priv, err = ecdsa.GenerateKey(elliptic.P521(), rand.Reader)
+	default:
+		fmt.Fprintf(os.Stderr, "Unrecognized elliptic curve: %q", *ecdsaCurve)
+		os.Exit(1)
+	}
+	if err != nil {
+		log.Fatalf("failed to generate private key: %s", err)
+	}
+
+	var notBefore time.Time
+	if len(*validFrom) == 0 {
+		notBefore = time.Now()
+	} else {
+		notBefore, err = time.Parse("Jan 2 15:04:05 2006", *validFrom)
+		if err != nil {
+			fmt.Fprintf(os.Stderr, "Failed to parse creation date: %s\n", err)
+			os.Exit(1)
+		}
+	}
+
+	notAfter := notBefore.Add(*validFor)
+
+	serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
+	serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
+	if err != nil {
+		log.Fatalf("failed to generate serial number: %s", err)
+	}
+
+	template := x509.Certificate{
+		SerialNumber: serialNumber,
+		Subject: pkix.Name{
+			Organization: []string{"Acme Co"},
+		},
+		NotBefore: notBefore,
+		NotAfter:  notAfter,
+
+		KeyUsage:              x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
+		ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
+		BasicConstraintsValid: true,
+	}
+
+	hosts := strings.Split(*host, ",")
+	for _, h := range hosts {
+		if ip := net.ParseIP(h); ip != nil {
+			template.IPAddresses = append(template.IPAddresses, ip)
+		} else {
+			template.DNSNames = append(template.DNSNames, h)
+		}
+	}
+
+	if *isCA {
+		template.IsCA = true
+		template.KeyUsage |= x509.KeyUsageCertSign
+	}
+
+	derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, publicKey(priv), priv)
+	if err != nil {
+		log.Fatalf("Failed to create certificate: %s", err)
+	}
+
+	certOut, err := os.Create("cert.pem")
+	if err != nil {
+		log.Fatalf("failed to open cert.pem for writing: %s", err)
+	}
+	pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes})
+	certOut.Close()
+	log.Print("written cert.pem\n")
+
+	keyOut, err := os.OpenFile("key.pem", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
+	if err != nil {
+		log.Print("failed to open key.pem for writing:", err)
+		return
+	}
+	pem.Encode(keyOut, pemBlockForKey(priv))
+	keyOut.Close()
+	log.Print("written key.pem\n")
+}
diff --git a/src/crypto/tls/handshake_client.go b/src/crypto/tls/handshake_client.go
new file mode 100644
index 0000000..7f662e9
--- /dev/null
+++ b/src/crypto/tls/handshake_client.go
@@ -0,0 +1,638 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tls
+
+import (
+	"bytes"
+	"crypto"
+	"crypto/ecdsa"
+	"crypto/rsa"
+	"crypto/subtle"
+	"crypto/x509"
+	"errors"
+	"fmt"
+	"io"
+	"net"
+	"strconv"
+)
+
+type clientHandshakeState struct {
+	c            *Conn
+	serverHello  *serverHelloMsg
+	hello        *clientHelloMsg
+	suite        *cipherSuite
+	finishedHash finishedHash
+	masterSecret []byte
+	session      *ClientSessionState
+}
+
+func (c *Conn) clientHandshake() error {
+	if c.config == nil {
+		c.config = defaultConfig()
+	}
+
+	if len(c.config.ServerName) == 0 && !c.config.InsecureSkipVerify {
+		return errors.New("tls: either ServerName or InsecureSkipVerify must be specified in the tls.Config")
+	}
+
+	nextProtosLength := 0
+	for _, proto := range c.config.NextProtos {
+		if l := len(proto); l == 0 || l > 255 {
+			return errors.New("tls: invalid NextProtos value")
+		} else {
+			nextProtosLength += 1 + l
+		}
+	}
+	if nextProtosLength > 0xffff {
+		return errors.New("tls: NextProtos values too large")
+	}
+
+	hello := &clientHelloMsg{
+		vers:                c.config.maxVersion(),
+		compressionMethods:  []uint8{compressionNone},
+		random:              make([]byte, 32),
+		ocspStapling:        true,
+		serverName:          c.config.ServerName,
+		supportedCurves:     c.config.curvePreferences(),
+		supportedPoints:     []uint8{pointFormatUncompressed},
+		nextProtoNeg:        len(c.config.NextProtos) > 0,
+		secureRenegotiation: true,
+		alpnProtocols:       c.config.NextProtos,
+	}
+
+	possibleCipherSuites := c.config.cipherSuites()
+	hello.cipherSuites = make([]uint16, 0, len(possibleCipherSuites))
+
+NextCipherSuite:
+	for _, suiteId := range possibleCipherSuites {
+		for _, suite := range cipherSuites {
+			if suite.id != suiteId {
+				continue
+			}
+			// Don't advertise TLS 1.2-only cipher suites unless
+			// we're attempting TLS 1.2.
+			if hello.vers < VersionTLS12 && suite.flags&suiteTLS12 != 0 {
+				continue
+			}
+			hello.cipherSuites = append(hello.cipherSuites, suiteId)
+			continue NextCipherSuite
+		}
+	}
+
+	_, err := io.ReadFull(c.config.rand(), hello.random)
+	if err != nil {
+		c.sendAlert(alertInternalError)
+		return errors.New("tls: short read from Rand: " + err.Error())
+	}
+
+	if hello.vers >= VersionTLS12 {
+		hello.signatureAndHashes = supportedSKXSignatureAlgorithms
+	}
+
+	var session *ClientSessionState
+	var cacheKey string
+	sessionCache := c.config.ClientSessionCache
+	if c.config.SessionTicketsDisabled {
+		sessionCache = nil
+	}
+
+	if sessionCache != nil {
+		hello.ticketSupported = true
+
+		// Try to resume a previously negotiated TLS session, if
+		// available.
+		cacheKey = clientSessionCacheKey(c.conn.RemoteAddr(), c.config)
+		candidateSession, ok := sessionCache.Get(cacheKey)
+		if ok {
+			// Check that the ciphersuite/version used for the
+			// previous session are still valid.
+			cipherSuiteOk := false
+			for _, id := range hello.cipherSuites {
+				if id == candidateSession.cipherSuite {
+					cipherSuiteOk = true
+					break
+				}
+			}
+
+			versOk := candidateSession.vers >= c.config.minVersion() &&
+				candidateSession.vers <= c.config.maxVersion()
+			if versOk && cipherSuiteOk {
+				session = candidateSession
+			}
+		}
+	}
+
+	if session != nil {
+		hello.sessionTicket = session.sessionTicket
+		// A random session ID is used to detect when the
+		// server accepted the ticket and is resuming a session
+		// (see RFC 5077).
+		hello.sessionId = make([]byte, 16)
+		if _, err := io.ReadFull(c.config.rand(), hello.sessionId); err != nil {
+			c.sendAlert(alertInternalError)
+			return errors.New("tls: short read from Rand: " + err.Error())
+		}
+	}
+
+	c.writeRecord(recordTypeHandshake, hello.marshal())
+
+	msg, err := c.readHandshake()
+	if err != nil {
+		return err
+	}
+	serverHello, ok := msg.(*serverHelloMsg)
+	if !ok {
+		c.sendAlert(alertUnexpectedMessage)
+		return unexpectedMessageError(serverHello, msg)
+	}
+
+	vers, ok := c.config.mutualVersion(serverHello.vers)
+	if !ok || vers < VersionTLS10 {
+		// TLS 1.0 is the minimum version supported as a client.
+		c.sendAlert(alertProtocolVersion)
+		return fmt.Errorf("tls: server selected unsupported protocol version %x", serverHello.vers)
+	}
+	c.vers = vers
+	c.haveVers = true
+
+	suite := mutualCipherSuite(c.config.cipherSuites(), serverHello.cipherSuite)
+	if suite == nil {
+		c.sendAlert(alertHandshakeFailure)
+		return fmt.Errorf("tls: server selected an unsupported cipher suite")
+	}
+
+	hs := &clientHandshakeState{
+		c:            c,
+		serverHello:  serverHello,
+		hello:        hello,
+		suite:        suite,
+		finishedHash: newFinishedHash(c.vers),
+		session:      session,
+	}
+
+	hs.finishedHash.Write(hs.hello.marshal())
+	hs.finishedHash.Write(hs.serverHello.marshal())
+
+	isResume, err := hs.processServerHello()
+	if err != nil {
+		return err
+	}
+
+	if isResume {
+		if err := hs.establishKeys(); err != nil {
+			return err
+		}
+		if err := hs.readSessionTicket(); err != nil {
+			return err
+		}
+		if err := hs.readFinished(c.firstFinished[:]); err != nil {
+			return err
+		}
+		if err := hs.sendFinished(nil); err != nil {
+			return err
+		}
+	} else {
+		if err := hs.doFullHandshake(); err != nil {
+			return err
+		}
+		if err := hs.establishKeys(); err != nil {
+			return err
+		}
+		if err := hs.sendFinished(c.firstFinished[:]); err != nil {
+			return err
+		}
+		if err := hs.readSessionTicket(); err != nil {
+			return err
+		}
+		if err := hs.readFinished(nil); err != nil {
+			return err
+		}
+	}
+
+	if sessionCache != nil && hs.session != nil && session != hs.session {
+		sessionCache.Put(cacheKey, hs.session)
+	}
+
+	c.didResume = isResume
+	c.handshakeComplete = true
+	c.cipherSuite = suite.id
+	return nil
+}
+
+func (hs *clientHandshakeState) doFullHandshake() error {
+	c := hs.c
+
+	msg, err := c.readHandshake()
+	if err != nil {
+		return err
+	}
+	certMsg, ok := msg.(*certificateMsg)
+	if !ok || len(certMsg.certificates) == 0 {
+		c.sendAlert(alertUnexpectedMessage)
+		return unexpectedMessageError(certMsg, msg)
+	}
+	hs.finishedHash.Write(certMsg.marshal())
+
+	certs := make([]*x509.Certificate, len(certMsg.certificates))
+	for i, asn1Data := range certMsg.certificates {
+		cert, err := x509.ParseCertificate(asn1Data)
+		if err != nil {
+			c.sendAlert(alertBadCertificate)
+			return errors.New("tls: failed to parse certificate from server: " + err.Error())
+		}
+		certs[i] = cert
+	}
+
+	if !c.config.InsecureSkipVerify {
+		opts := x509.VerifyOptions{
+			Roots:         c.config.RootCAs,
+			CurrentTime:   c.config.time(),
+			DNSName:       c.config.ServerName,
+			Intermediates: x509.NewCertPool(),
+		}
+
+		for i, cert := range certs {
+			if i == 0 {
+				continue
+			}
+			opts.Intermediates.AddCert(cert)
+		}
+		c.verifiedChains, err = certs[0].Verify(opts)
+		if err != nil {
+			c.sendAlert(alertBadCertificate)
+			return err
+		}
+	}
+
+	switch certs[0].PublicKey.(type) {
+	case *rsa.PublicKey, *ecdsa.PublicKey:
+		break
+	default:
+		c.sendAlert(alertUnsupportedCertificate)
+		return fmt.Errorf("tls: server's certificate contains an unsupported type of public key: %T", certs[0].PublicKey)
+	}
+
+	c.peerCertificates = certs
+
+	if hs.serverHello.ocspStapling {
+		msg, err = c.readHandshake()
+		if err != nil {
+			return err
+		}
+		cs, ok := msg.(*certificateStatusMsg)
+		if !ok {
+			c.sendAlert(alertUnexpectedMessage)
+			return unexpectedMessageError(cs, msg)
+		}
+		hs.finishedHash.Write(cs.marshal())
+
+		if cs.statusType == statusTypeOCSP {
+			c.ocspResponse = cs.response
+		}
+	}
+
+	msg, err = c.readHandshake()
+	if err != nil {
+		return err
+	}
+
+	keyAgreement := hs.suite.ka(c.vers)
+
+	skx, ok := msg.(*serverKeyExchangeMsg)
+	if ok {
+		hs.finishedHash.Write(skx.marshal())
+		err = keyAgreement.processServerKeyExchange(c.config, hs.hello, hs.serverHello, certs[0], skx)
+		if err != nil {
+			c.sendAlert(alertUnexpectedMessage)
+			return err
+		}
+
+		msg, err = c.readHandshake()
+		if err != nil {
+			return err
+		}
+	}
+
+	var chainToSend *Certificate
+	var certRequested bool
+	certReq, ok := msg.(*certificateRequestMsg)
+	if ok {
+		certRequested = true
+
+		// RFC 4346 on the certificateAuthorities field:
+		// A list of the distinguished names of acceptable certificate
+		// authorities. These distinguished names may specify a desired
+		// distinguished name for a root CA or for a subordinate CA;
+		// thus, this message can be used to describe both known roots
+		// and a desired authorization space. If the
+		// certificate_authorities list is empty then the client MAY
+		// send any certificate of the appropriate
+		// ClientCertificateType, unless there is some external
+		// arrangement to the contrary.
+
+		hs.finishedHash.Write(certReq.marshal())
+
+		var rsaAvail, ecdsaAvail bool
+		for _, certType := range certReq.certificateTypes {
+			switch certType {
+			case certTypeRSASign:
+				rsaAvail = true
+			case certTypeECDSASign:
+				ecdsaAvail = true
+			}
+		}
+
+		// We need to search our list of client certs for one
+		// where SignatureAlgorithm is acceptable to the server and the
+		// Issuer is in certReq.certificateAuthorities
+	findCert:
+		for i, chain := range c.config.Certificates {
+			if !rsaAvail && !ecdsaAvail {
+				continue
+			}
+
+			for j, cert := range chain.Certificate {
+				x509Cert := chain.Leaf
+				// parse the certificate if this isn't the leaf
+				// node, or if chain.Leaf was nil
+				if j != 0 || x509Cert == nil {
+					if x509Cert, err = x509.ParseCertificate(cert); err != nil {
+						c.sendAlert(alertInternalError)
+						return errors.New("tls: failed to parse client certificate #" + strconv.Itoa(i) + ": " + err.Error())
+					}
+				}
+
+				switch {
+				case rsaAvail && x509Cert.PublicKeyAlgorithm == x509.RSA:
+				case ecdsaAvail && x509Cert.PublicKeyAlgorithm == x509.ECDSA:
+				default:
+					continue findCert
+				}
+
+				if len(certReq.certificateAuthorities) == 0 {
+					// they gave us an empty list, so just take the
+					// first cert from c.config.Certificates
+					chainToSend = &chain
+					break findCert
+				}
+
+				for _, ca := range certReq.certificateAuthorities {
+					if bytes.Equal(x509Cert.RawIssuer, ca) {
+						chainToSend = &chain
+						break findCert
+					}
+				}
+			}
+		}
+
+		msg, err = c.readHandshake()
+		if err != nil {
+			return err
+		}
+	}
+
+	shd, ok := msg.(*serverHelloDoneMsg)
+	if !ok {
+		c.sendAlert(alertUnexpectedMessage)
+		return unexpectedMessageError(shd, msg)
+	}
+	hs.finishedHash.Write(shd.marshal())
+
+	// If the server requested a certificate then we have to send a
+	// Certificate message, even if it's empty because we don't have a
+	// certificate to send.
+	if certRequested {
+		certMsg = new(certificateMsg)
+		if chainToSend != nil {
+			certMsg.certificates = chainToSend.Certificate
+		}
+		hs.finishedHash.Write(certMsg.marshal())
+		c.writeRecord(recordTypeHandshake, certMsg.marshal())
+	}
+
+	preMasterSecret, ckx, err := keyAgreement.generateClientKeyExchange(c.config, hs.hello, certs[0])
+	if err != nil {
+		c.sendAlert(alertInternalError)
+		return err
+	}
+	if ckx != nil {
+		hs.finishedHash.Write(ckx.marshal())
+		c.writeRecord(recordTypeHandshake, ckx.marshal())
+	}
+
+	if chainToSend != nil {
+		var signed []byte
+		certVerify := &certificateVerifyMsg{
+			hasSignatureAndHash: c.vers >= VersionTLS12,
+		}
+
+		key, ok := chainToSend.PrivateKey.(crypto.Signer)
+		if !ok {
+			c.sendAlert(alertInternalError)
+			return fmt.Errorf("tls: client certificate private key of type %T does not implement crypto.Signer", chainToSend.PrivateKey)
+		}
+		switch key.Public().(type) {
+		case *ecdsa.PublicKey:
+			digest, hashFunc, hashId := hs.finishedHash.hashForClientCertificate(signatureECDSA)
+			signed, err = key.Sign(c.config.rand(), digest, hashFunc)
+			certVerify.signatureAndHash.signature = signatureECDSA
+			certVerify.signatureAndHash.hash = hashId
+		case *rsa.PublicKey:
+			digest, hashFunc, hashId := hs.finishedHash.hashForClientCertificate(signatureRSA)
+			signed, err = key.Sign(c.config.rand(), digest, hashFunc)
+			certVerify.signatureAndHash.signature = signatureRSA
+			certVerify.signatureAndHash.hash = hashId
+		default:
+			err = fmt.Errorf("tls: unknown client certificate key type: %T", key)
+		}
+		if err != nil {
+			c.sendAlert(alertInternalError)
+			return errors.New("tls: failed to sign handshake with client certificate: " + err.Error())
+		}
+		certVerify.signature = signed
+
+		hs.finishedHash.Write(certVerify.marshal())
+		c.writeRecord(recordTypeHandshake, certVerify.marshal())
+	}
+
+	hs.masterSecret = masterFromPreMasterSecret(c.vers, preMasterSecret, hs.hello.random, hs.serverHello.random)
+	return nil
+}
+
+func (hs *clientHandshakeState) establishKeys() error {
+	c := hs.c
+
+	clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV :=
+		keysFromMasterSecret(c.vers, hs.masterSecret, hs.hello.random, hs.serverHello.random, hs.suite.macLen, hs.suite.keyLen, hs.suite.ivLen)
+	var clientCipher, serverCipher interface{}
+	var clientHash, serverHash macFunction
+	if hs.suite.cipher != nil {
+		clientCipher = hs.suite.cipher(clientKey, clientIV, false /* not for reading */)
+		clientHash = hs.suite.mac(c.vers, clientMAC)
+		serverCipher = hs.suite.cipher(serverKey, serverIV, true /* for reading */)
+		serverHash = hs.suite.mac(c.vers, serverMAC)
+	} else {
+		clientCipher = hs.suite.aead(clientKey, clientIV)
+		serverCipher = hs.suite.aead(serverKey, serverIV)
+	}
+
+	c.in.prepareCipherSpec(c.vers, serverCipher, serverHash)
+	c.out.prepareCipherSpec(c.vers, clientCipher, clientHash)
+	return nil
+}
+
+func (hs *clientHandshakeState) serverResumedSession() bool {
+	// If the server responded with the same sessionId then it means the
+	// sessionTicket is being used to resume a TLS session.
+	return hs.session != nil && hs.hello.sessionId != nil &&
+		bytes.Equal(hs.serverHello.sessionId, hs.hello.sessionId)
+}
+
+func (hs *clientHandshakeState) processServerHello() (bool, error) {
+	c := hs.c
+
+	if hs.serverHello.compressionMethod != compressionNone {
+		c.sendAlert(alertUnexpectedMessage)
+		return false, errors.New("tls: server selected unsupported compression format")
+	}
+
+	clientDidNPN := hs.hello.nextProtoNeg
+	clientDidALPN := len(hs.hello.alpnProtocols) > 0
+	serverHasNPN := hs.serverHello.nextProtoNeg
+	serverHasALPN := len(hs.serverHello.alpnProtocol) > 0
+
+	if !clientDidNPN && serverHasNPN {
+		c.sendAlert(alertHandshakeFailure)
+		return false, errors.New("server advertised unrequested NPN extension")
+	}
+
+	if !clientDidALPN && serverHasALPN {
+		c.sendAlert(alertHandshakeFailure)
+		return false, errors.New("server advertised unrequested ALPN extension")
+	}
+
+	if serverHasNPN && serverHasALPN {
+		c.sendAlert(alertHandshakeFailure)
+		return false, errors.New("server advertised both NPN and ALPN extensions")
+	}
+
+	if serverHasALPN {
+		c.clientProtocol = hs.serverHello.alpnProtocol
+		c.clientProtocolFallback = false
+	}
+
+	if hs.serverResumedSession() {
+		// Restore masterSecret and peerCerts from previous state
+		hs.masterSecret = hs.session.masterSecret
+		c.peerCertificates = hs.session.serverCertificates
+		return true, nil
+	}
+	return false, nil
+}
+
+func (hs *clientHandshakeState) readFinished(out []byte) error {
+	c := hs.c
+
+	c.readRecord(recordTypeChangeCipherSpec)
+	if err := c.in.error(); err != nil {
+		return err
+	}
+
+	msg, err := c.readHandshake()
+	if err != nil {
+		return err
+	}
+	serverFinished, ok := msg.(*finishedMsg)
+	if !ok {
+		c.sendAlert(alertUnexpectedMessage)
+		return unexpectedMessageError(serverFinished, msg)
+	}
+
+	verify := hs.finishedHash.serverSum(hs.masterSecret)
+	if len(verify) != len(serverFinished.verifyData) ||
+		subtle.ConstantTimeCompare(verify, serverFinished.verifyData) != 1 {
+		c.sendAlert(alertHandshakeFailure)
+		return errors.New("tls: server's Finished message was incorrect")
+	}
+	hs.finishedHash.Write(serverFinished.marshal())
+	copy(out, verify)
+	return nil
+}
+
+func (hs *clientHandshakeState) readSessionTicket() error {
+	if !hs.serverHello.ticketSupported {
+		return nil
+	}
+
+	c := hs.c
+	msg, err := c.readHandshake()
+	if err != nil {
+		return err
+	}
+	sessionTicketMsg, ok := msg.(*newSessionTicketMsg)
+	if !ok {
+		c.sendAlert(alertUnexpectedMessage)
+		return unexpectedMessageError(sessionTicketMsg, msg)
+	}
+	hs.finishedHash.Write(sessionTicketMsg.marshal())
+
+	hs.session = &ClientSessionState{
+		sessionTicket:      sessionTicketMsg.ticket,
+		vers:               c.vers,
+		cipherSuite:        hs.suite.id,
+		masterSecret:       hs.masterSecret,
+		serverCertificates: c.peerCertificates,
+	}
+
+	return nil
+}
+
+func (hs *clientHandshakeState) sendFinished(out []byte) error {
+	c := hs.c
+
+	c.writeRecord(recordTypeChangeCipherSpec, []byte{1})
+	if hs.serverHello.nextProtoNeg {
+		nextProto := new(nextProtoMsg)
+		proto, fallback := mutualProtocol(c.config.NextProtos, hs.serverHello.nextProtos)
+		nextProto.proto = proto
+		c.clientProtocol = proto
+		c.clientProtocolFallback = fallback
+
+		hs.finishedHash.Write(nextProto.marshal())
+		c.writeRecord(recordTypeHandshake, nextProto.marshal())
+	}
+
+	finished := new(finishedMsg)
+	finished.verifyData = hs.finishedHash.clientSum(hs.masterSecret)
+	hs.finishedHash.Write(finished.marshal())
+	c.writeRecord(recordTypeHandshake, finished.marshal())
+	copy(out, finished.verifyData)
+	return nil
+}
+
+// clientSessionCacheKey returns a key used to cache sessionTickets that could
+// be used to resume previously negotiated TLS sessions with a server.
+func clientSessionCacheKey(serverAddr net.Addr, config *Config) string {
+	if len(config.ServerName) > 0 {
+		return config.ServerName
+	}
+	return serverAddr.String()
+}
+
+// mutualProtocol finds the mutual Next Protocol Negotiation or ALPN protocol
+// given list of possible protocols and a list of the preference order. The
+// first list must not be empty. It returns the resulting protocol and flag
+// indicating if the fallback case was reached.
+func mutualProtocol(protos, preferenceProtos []string) (string, bool) {
+	for _, s := range preferenceProtos {
+		for _, c := range protos {
+			if s == c {
+				return s, false
+			}
+		}
+	}
+
+	return protos[0], true
+}
diff --git a/src/crypto/tls/handshake_client_test.go b/src/crypto/tls/handshake_client_test.go
new file mode 100644
index 0000000..e5eaa7d
--- /dev/null
+++ b/src/crypto/tls/handshake_client_test.go
@@ -0,0 +1,490 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tls
+
+import (
+	"bytes"
+	"crypto/ecdsa"
+	"crypto/rsa"
+	"crypto/x509"
+	"encoding/pem"
+	"fmt"
+	"io"
+	"net"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"strconv"
+	"testing"
+	"time"
+)
+
+// Note: see comment in handshake_test.go for details of how the reference
+// tests work.
+
+// blockingSource is an io.Reader that blocks a Read call until it's closed.
+type blockingSource chan bool
+
+func (b blockingSource) Read([]byte) (n int, err error) {
+	<-b
+	return 0, io.EOF
+}
+
+// clientTest represents a test of the TLS client handshake against a reference
+// implementation.
+type clientTest struct {
+	// name is a freeform string identifying the test and the file in which
+	// the expected results will be stored.
+	name string
+	// command, if not empty, contains a series of arguments for the
+	// command to run for the reference server.
+	command []string
+	// config, if not nil, contains a custom Config to use for this test.
+	config *Config
+	// cert, if not empty, contains a DER-encoded certificate for the
+	// reference server.
+	cert []byte
+	// key, if not nil, contains either a *rsa.PrivateKey or
+	// *ecdsa.PrivateKey which is the private key for the reference server.
+	key interface{}
+	// validate, if not nil, is a function that will be called with the
+	// ConnectionState of the resulting connection. It returns a non-nil
+	// error if the ConnectionState is unacceptable.
+	validate func(ConnectionState) error
+}
+
+var defaultServerCommand = []string{"openssl", "s_server"}
+
+// connFromCommand starts the reference server process, connects to it and
+// returns a recordingConn for the connection. The stdin return value is a
+// blockingSource for the stdin of the child process. It must be closed before
+// Waiting for child.
+func (test *clientTest) connFromCommand() (conn *recordingConn, child *exec.Cmd, stdin blockingSource, err error) {
+	cert := testRSACertificate
+	if len(test.cert) > 0 {
+		cert = test.cert
+	}
+	certPath := tempFile(string(cert))
+	defer os.Remove(certPath)
+
+	var key interface{} = testRSAPrivateKey
+	if test.key != nil {
+		key = test.key
+	}
+	var pemType string
+	var derBytes []byte
+	switch key := key.(type) {
+	case *rsa.PrivateKey:
+		pemType = "RSA"
+		derBytes = x509.MarshalPKCS1PrivateKey(key)
+	case *ecdsa.PrivateKey:
+		pemType = "EC"
+		var err error
+		derBytes, err = x509.MarshalECPrivateKey(key)
+		if err != nil {
+			panic(err)
+		}
+	default:
+		panic("unknown key type")
+	}
+
+	var pemOut bytes.Buffer
+	pem.Encode(&pemOut, &pem.Block{Type: pemType + " PRIVATE KEY", Bytes: derBytes})
+
+	keyPath := tempFile(string(pemOut.Bytes()))
+	defer os.Remove(keyPath)
+
+	var command []string
+	if len(test.command) > 0 {
+		command = append(command, test.command...)
+	} else {
+		command = append(command, defaultServerCommand...)
+	}
+	command = append(command, "-cert", certPath, "-certform", "DER", "-key", keyPath)
+	// serverPort contains the port that OpenSSL will listen on. OpenSSL
+	// can't take "0" as an argument here so we have to pick a number and
+	// hope that it's not in use on the machine. Since this only occurs
+	// when -update is given and thus when there's a human watching the
+	// test, this isn't too bad.
+	const serverPort = 24323
+	command = append(command, "-accept", strconv.Itoa(serverPort))
+
+	cmd := exec.Command(command[0], command[1:]...)
+	stdin = blockingSource(make(chan bool))
+	cmd.Stdin = stdin
+	var out bytes.Buffer
+	cmd.Stdout = &out
+	cmd.Stderr = &out
+	if err := cmd.Start(); err != nil {
+		return nil, nil, nil, err
+	}
+
+	// OpenSSL does print an "ACCEPT" banner, but it does so *before*
+	// opening the listening socket, so we can't use that to wait until it
+	// has started listening. Thus we are forced to poll until we get a
+	// connection.
+	var tcpConn net.Conn
+	for i := uint(0); i < 5; i++ {
+		var err error
+		tcpConn, err = net.DialTCP("tcp", nil, &net.TCPAddr{
+			IP:   net.IPv4(127, 0, 0, 1),
+			Port: serverPort,
+		})
+		if err == nil {
+			break
+		}
+		time.Sleep((1 << i) * 5 * time.Millisecond)
+	}
+	if tcpConn == nil {
+		close(stdin)
+		out.WriteTo(os.Stdout)
+		cmd.Process.Kill()
+		return nil, nil, nil, cmd.Wait()
+	}
+
+	record := &recordingConn{
+		Conn: tcpConn,
+	}
+
+	return record, cmd, stdin, nil
+}
+
+func (test *clientTest) dataPath() string {
+	return filepath.Join("testdata", "Client-"+test.name)
+}
+
+func (test *clientTest) loadData() (flows [][]byte, err error) {
+	in, err := os.Open(test.dataPath())
+	if err != nil {
+		return nil, err
+	}
+	defer in.Close()
+	return parseTestData(in)
+}
+
+func (test *clientTest) run(t *testing.T, write bool) {
+	var clientConn, serverConn net.Conn
+	var recordingConn *recordingConn
+	var childProcess *exec.Cmd
+	var stdin blockingSource
+
+	if write {
+		var err error
+		recordingConn, childProcess, stdin, err = test.connFromCommand()
+		if err != nil {
+			t.Fatalf("Failed to start subcommand: %s", err)
+		}
+		clientConn = recordingConn
+	} else {
+		clientConn, serverConn = net.Pipe()
+	}
+
+	config := test.config
+	if config == nil {
+		config = testConfig
+	}
+	client := Client(clientConn, config)
+
+	doneChan := make(chan bool)
+	go func() {
+		if _, err := client.Write([]byte("hello\n")); err != nil {
+			t.Logf("Client.Write failed: %s", err)
+		}
+		if test.validate != nil {
+			if err := test.validate(client.ConnectionState()); err != nil {
+				t.Logf("validate callback returned error: %s", err)
+			}
+		}
+		client.Close()
+		clientConn.Close()
+		doneChan <- true
+	}()
+
+	if !write {
+		flows, err := test.loadData()
+		if err != nil {
+			t.Fatalf("%s: failed to load data from %s: %v", test.name, test.dataPath(), err)
+		}
+		for i, b := range flows {
+			if i%2 == 1 {
+				serverConn.Write(b)
+				continue
+			}
+			bb := make([]byte, len(b))
+			_, err := io.ReadFull(serverConn, bb)
+			if err != nil {
+				t.Fatalf("%s #%d: %s", test.name, i, err)
+			}
+			if !bytes.Equal(b, bb) {
+				t.Fatalf("%s #%d: mismatch on read: got:%x want:%x", test.name, i, bb, b)
+			}
+		}
+		serverConn.Close()
+	}
+
+	<-doneChan
+
+	if write {
+		path := test.dataPath()
+		out, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
+		if err != nil {
+			t.Fatalf("Failed to create output file: %s", err)
+		}
+		defer out.Close()
+		recordingConn.Close()
+		close(stdin)
+		childProcess.Process.Kill()
+		childProcess.Wait()
+		if len(recordingConn.flows) < 3 {
+			childProcess.Stdout.(*bytes.Buffer).WriteTo(os.Stdout)
+			t.Fatalf("Client connection didn't work")
+		}
+		recordingConn.WriteTo(out)
+		fmt.Printf("Wrote %s\n", path)
+	}
+}
+
+func runClientTestForVersion(t *testing.T, template *clientTest, prefix, option string) {
+	test := *template
+	test.name = prefix + test.name
+	if len(test.command) == 0 {
+		test.command = defaultClientCommand
+	}
+	test.command = append([]string(nil), test.command...)
+	test.command = append(test.command, option)
+	test.run(t, *update)
+}
+
+func runClientTestTLS10(t *testing.T, template *clientTest) {
+	runClientTestForVersion(t, template, "TLSv10-", "-tls1")
+}
+
+func runClientTestTLS11(t *testing.T, template *clientTest) {
+	runClientTestForVersion(t, template, "TLSv11-", "-tls1_1")
+}
+
+func runClientTestTLS12(t *testing.T, template *clientTest) {
+	runClientTestForVersion(t, template, "TLSv12-", "-tls1_2")
+}
+
+func TestHandshakeClientRSARC4(t *testing.T) {
+	test := &clientTest{
+		name:    "RSA-RC4",
+		command: []string{"openssl", "s_server", "-cipher", "RC4-SHA"},
+	}
+	runClientTestTLS10(t, test)
+	runClientTestTLS11(t, test)
+	runClientTestTLS12(t, test)
+}
+
+func TestHandshakeClientECDHERSAAES(t *testing.T) {
+	test := &clientTest{
+		name:    "ECDHE-RSA-AES",
+		command: []string{"openssl", "s_server", "-cipher", "ECDHE-RSA-AES128-SHA"},
+	}
+	runClientTestTLS10(t, test)
+	runClientTestTLS11(t, test)
+	runClientTestTLS12(t, test)
+}
+
+func TestHandshakeClientECDHEECDSAAES(t *testing.T) {
+	test := &clientTest{
+		name:    "ECDHE-ECDSA-AES",
+		command: []string{"openssl", "s_server", "-cipher", "ECDHE-ECDSA-AES128-SHA"},
+		cert:    testECDSACertificate,
+		key:     testECDSAPrivateKey,
+	}
+	runClientTestTLS10(t, test)
+	runClientTestTLS11(t, test)
+	runClientTestTLS12(t, test)
+}
+
+func TestHandshakeClientECDHEECDSAAESGCM(t *testing.T) {
+	test := &clientTest{
+		name:    "ECDHE-ECDSA-AES-GCM",
+		command: []string{"openssl", "s_server", "-cipher", "ECDHE-ECDSA-AES128-GCM-SHA256"},
+		cert:    testECDSACertificate,
+		key:     testECDSAPrivateKey,
+	}
+	runClientTestTLS12(t, test)
+}
+
+func TestHandshakeClientCertRSA(t *testing.T) {
+	config := *testConfig
+	cert, _ := X509KeyPair([]byte(clientCertificatePEM), []byte(clientKeyPEM))
+	config.Certificates = []Certificate{cert}
+
+	test := &clientTest{
+		name:    "ClientCert-RSA-RSA",
+		command: []string{"openssl", "s_server", "-cipher", "RC4-SHA", "-verify", "1"},
+		config:  &config,
+	}
+
+	runClientTestTLS10(t, test)
+	runClientTestTLS12(t, test)
+
+	test = &clientTest{
+		name:    "ClientCert-RSA-ECDSA",
+		command: []string{"openssl", "s_server", "-cipher", "ECDHE-ECDSA-AES128-SHA", "-verify", "1"},
+		config:  &config,
+		cert:    testECDSACertificate,
+		key:     testECDSAPrivateKey,
+	}
+
+	runClientTestTLS10(t, test)
+	runClientTestTLS12(t, test)
+}
+
+func TestHandshakeClientCertECDSA(t *testing.T) {
+	config := *testConfig
+	cert, _ := X509KeyPair([]byte(clientECDSACertificatePEM), []byte(clientECDSAKeyPEM))
+	config.Certificates = []Certificate{cert}
+
+	test := &clientTest{
+		name:    "ClientCert-ECDSA-RSA",
+		command: []string{"openssl", "s_server", "-cipher", "RC4-SHA", "-verify", "1"},
+		config:  &config,
+	}
+
+	runClientTestTLS10(t, test)
+	runClientTestTLS12(t, test)
+
+	test = &clientTest{
+		name:    "ClientCert-ECDSA-ECDSA",
+		command: []string{"openssl", "s_server", "-cipher", "ECDHE-ECDSA-AES128-SHA", "-verify", "1"},
+		config:  &config,
+		cert:    testECDSACertificate,
+		key:     testECDSAPrivateKey,
+	}
+
+	runClientTestTLS10(t, test)
+	runClientTestTLS12(t, test)
+}
+
+func TestClientResumption(t *testing.T) {
+	serverConfig := &Config{
+		CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA},
+		Certificates: testConfig.Certificates,
+	}
+	clientConfig := &Config{
+		CipherSuites:       []uint16{TLS_RSA_WITH_RC4_128_SHA},
+		InsecureSkipVerify: true,
+		ClientSessionCache: NewLRUClientSessionCache(32),
+	}
+
+	testResumeState := func(test string, didResume bool) {
+		hs, err := testHandshake(clientConfig, serverConfig)
+		if err != nil {
+			t.Fatalf("%s: handshake failed: %s", test, err)
+		}
+		if hs.DidResume != didResume {
+			t.Fatalf("%s resumed: %v, expected: %v", test, hs.DidResume, didResume)
+		}
+	}
+
+	testResumeState("Handshake", false)
+	testResumeState("Resume", true)
+
+	if _, err := io.ReadFull(serverConfig.rand(), serverConfig.SessionTicketKey[:]); err != nil {
+		t.Fatalf("Failed to invalidate SessionTicketKey")
+	}
+	testResumeState("InvalidSessionTicketKey", false)
+	testResumeState("ResumeAfterInvalidSessionTicketKey", true)
+
+	clientConfig.CipherSuites = []uint16{TLS_ECDHE_RSA_WITH_RC4_128_SHA}
+	testResumeState("DifferentCipherSuite", false)
+	testResumeState("DifferentCipherSuiteRecovers", true)
+
+	clientConfig.ClientSessionCache = nil
+	testResumeState("WithoutSessionCache", false)
+}
+
+func TestLRUClientSessionCache(t *testing.T) {
+	// Initialize cache of capacity 4.
+	cache := NewLRUClientSessionCache(4)
+	cs := make([]ClientSessionState, 6)
+	keys := []string{"0", "1", "2", "3", "4", "5", "6"}
+
+	// Add 4 entries to the cache and look them up.
+	for i := 0; i < 4; i++ {
+		cache.Put(keys[i], &cs[i])
+	}
+	for i := 0; i < 4; i++ {
+		if s, ok := cache.Get(keys[i]); !ok || s != &cs[i] {
+			t.Fatalf("session cache failed lookup for added key: %s", keys[i])
+		}
+	}
+
+	// Add 2 more entries to the cache. First 2 should be evicted.
+	for i := 4; i < 6; i++ {
+		cache.Put(keys[i], &cs[i])
+	}
+	for i := 0; i < 2; i++ {
+		if s, ok := cache.Get(keys[i]); ok || s != nil {
+			t.Fatalf("session cache should have evicted key: %s", keys[i])
+		}
+	}
+
+	// Touch entry 2. LRU should evict 3 next.
+	cache.Get(keys[2])
+	cache.Put(keys[0], &cs[0])
+	if s, ok := cache.Get(keys[3]); ok || s != nil {
+		t.Fatalf("session cache should have evicted key 3")
+	}
+
+	// Update entry 0 in place.
+	cache.Put(keys[0], &cs[3])
+	if s, ok := cache.Get(keys[0]); !ok || s != &cs[3] {
+		t.Fatalf("session cache failed update for key 0")
+	}
+
+	// Adding a nil entry is valid.
+	cache.Put(keys[0], nil)
+	if s, ok := cache.Get(keys[0]); !ok || s != nil {
+		t.Fatalf("failed to add nil entry to cache")
+	}
+}
+
+func TestHandshakeClientALPNMatch(t *testing.T) {
+	config := *testConfig
+	config.NextProtos = []string{"proto2", "proto1"}
+
+	test := &clientTest{
+		name: "ALPN",
+		// Note that this needs OpenSSL 1.0.2 because that is the first
+		// version that supports the -alpn flag.
+		command: []string{"openssl", "s_server", "-alpn", "proto1,proto2"},
+		config:  &config,
+		validate: func(state ConnectionState) error {
+			// The server's preferences should override the client.
+			if state.NegotiatedProtocol != "proto1" {
+				return fmt.Errorf("Got protocol %q, wanted proto1", state.NegotiatedProtocol)
+			}
+			return nil
+		},
+	}
+	runClientTestTLS12(t, test)
+}
+
+func TestHandshakeClientALPNNoMatch(t *testing.T) {
+	config := *testConfig
+	config.NextProtos = []string{"proto3"}
+
+	test := &clientTest{
+		name: "ALPN-NoMatch",
+		// Note that this needs OpenSSL 1.0.2 because that is the first
+		// version that supports the -alpn flag.
+		command: []string{"openssl", "s_server", "-alpn", "proto1,proto2"},
+		config:  &config,
+		validate: func(state ConnectionState) error {
+			// There's no overlap so OpenSSL will not select a protocol.
+			if state.NegotiatedProtocol != "" {
+				return fmt.Errorf("Got protocol %q, wanted ''", state.NegotiatedProtocol)
+			}
+			return nil
+		},
+	}
+	runClientTestTLS12(t, test)
+}
diff --git a/src/crypto/tls/handshake_messages.go b/src/crypto/tls/handshake_messages.go
new file mode 100644
index 0000000..5d14871
--- /dev/null
+++ b/src/crypto/tls/handshake_messages.go
@@ -0,0 +1,1438 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tls
+
+import "bytes"
+
+type clientHelloMsg struct {
+	raw                 []byte
+	vers                uint16
+	random              []byte
+	sessionId           []byte
+	cipherSuites        []uint16
+	compressionMethods  []uint8
+	nextProtoNeg        bool
+	serverName          string
+	ocspStapling        bool
+	supportedCurves     []CurveID
+	supportedPoints     []uint8
+	ticketSupported     bool
+	sessionTicket       []uint8
+	signatureAndHashes  []signatureAndHash
+	secureRenegotiation bool
+	alpnProtocols       []string
+}
+
+func (m *clientHelloMsg) equal(i interface{}) bool {
+	m1, ok := i.(*clientHelloMsg)
+	if !ok {
+		return false
+	}
+
+	return bytes.Equal(m.raw, m1.raw) &&
+		m.vers == m1.vers &&
+		bytes.Equal(m.random, m1.random) &&
+		bytes.Equal(m.sessionId, m1.sessionId) &&
+		eqUint16s(m.cipherSuites, m1.cipherSuites) &&
+		bytes.Equal(m.compressionMethods, m1.compressionMethods) &&
+		m.nextProtoNeg == m1.nextProtoNeg &&
+		m.serverName == m1.serverName &&
+		m.ocspStapling == m1.ocspStapling &&
+		eqCurveIDs(m.supportedCurves, m1.supportedCurves) &&
+		bytes.Equal(m.supportedPoints, m1.supportedPoints) &&
+		m.ticketSupported == m1.ticketSupported &&
+		bytes.Equal(m.sessionTicket, m1.sessionTicket) &&
+		eqSignatureAndHashes(m.signatureAndHashes, m1.signatureAndHashes) &&
+		m.secureRenegotiation == m1.secureRenegotiation &&
+		eqStrings(m.alpnProtocols, m1.alpnProtocols)
+}
+
+func (m *clientHelloMsg) marshal() []byte {
+	if m.raw != nil {
+		return m.raw
+	}
+
+	length := 2 + 32 + 1 + len(m.sessionId) + 2 + len(m.cipherSuites)*2 + 1 + len(m.compressionMethods)
+	numExtensions := 0
+	extensionsLength := 0
+	if m.nextProtoNeg {
+		numExtensions++
+	}
+	if m.ocspStapling {
+		extensionsLength += 1 + 2 + 2
+		numExtensions++
+	}
+	if len(m.serverName) > 0 {
+		extensionsLength += 5 + len(m.serverName)
+		numExtensions++
+	}
+	if len(m.supportedCurves) > 0 {
+		extensionsLength += 2 + 2*len(m.supportedCurves)
+		numExtensions++
+	}
+	if len(m.supportedPoints) > 0 {
+		extensionsLength += 1 + len(m.supportedPoints)
+		numExtensions++
+	}
+	if m.ticketSupported {
+		extensionsLength += len(m.sessionTicket)
+		numExtensions++
+	}
+	if len(m.signatureAndHashes) > 0 {
+		extensionsLength += 2 + 2*len(m.signatureAndHashes)
+		numExtensions++
+	}
+	if m.secureRenegotiation {
+		extensionsLength += 1
+		numExtensions++
+	}
+	if len(m.alpnProtocols) > 0 {
+		extensionsLength += 2
+		for _, s := range m.alpnProtocols {
+			if l := len(s); l == 0 || l > 255 {
+				panic("invalid ALPN protocol")
+			}
+			extensionsLength++
+			extensionsLength += len(s)
+		}
+		numExtensions++
+	}
+	if numExtensions > 0 {
+		extensionsLength += 4 * numExtensions
+		length += 2 + extensionsLength
+	}
+
+	x := make([]byte, 4+length)
+	x[0] = typeClientHello
+	x[1] = uint8(length >> 16)
+	x[2] = uint8(length >> 8)
+	x[3] = uint8(length)
+	x[4] = uint8(m.vers >> 8)
+	x[5] = uint8(m.vers)
+	copy(x[6:38], m.random)
+	x[38] = uint8(len(m.sessionId))
+	copy(x[39:39+len(m.sessionId)], m.sessionId)
+	y := x[39+len(m.sessionId):]
+	y[0] = uint8(len(m.cipherSuites) >> 7)
+	y[1] = uint8(len(m.cipherSuites) << 1)
+	for i, suite := range m.cipherSuites {
+		y[2+i*2] = uint8(suite >> 8)
+		y[3+i*2] = uint8(suite)
+	}
+	z := y[2+len(m.cipherSuites)*2:]
+	z[0] = uint8(len(m.compressionMethods))
+	copy(z[1:], m.compressionMethods)
+
+	z = z[1+len(m.compressionMethods):]
+	if numExtensions > 0 {
+		z[0] = byte(extensionsLength >> 8)
+		z[1] = byte(extensionsLength)
+		z = z[2:]
+	}
+	if m.nextProtoNeg {
+		z[0] = byte(extensionNextProtoNeg >> 8)
+		z[1] = byte(extensionNextProtoNeg & 0xff)
+		// The length is always 0
+		z = z[4:]
+	}
+	if len(m.serverName) > 0 {
+		z[0] = byte(extensionServerName >> 8)
+		z[1] = byte(extensionServerName & 0xff)
+		l := len(m.serverName) + 5
+		z[2] = byte(l >> 8)
+		z[3] = byte(l)
+		z = z[4:]
+
+		// RFC 3546, section 3.1
+		//
+		// struct {
+		//     NameType name_type;
+		//     select (name_type) {
+		//         case host_name: HostName;
+		//     } name;
+		// } ServerName;
+		//
+		// enum {
+		//     host_name(0), (255)
+		// } NameType;
+		//
+		// opaque HostName<1..2^16-1>;
+		//
+		// struct {
+		//     ServerName server_name_list<1..2^16-1>
+		// } ServerNameList;
+
+		z[0] = byte((len(m.serverName) + 3) >> 8)
+		z[1] = byte(len(m.serverName) + 3)
+		z[3] = byte(len(m.serverName) >> 8)
+		z[4] = byte(len(m.serverName))
+		copy(z[5:], []byte(m.serverName))
+		z = z[l:]
+	}
+	if m.ocspStapling {
+		// RFC 4366, section 3.6
+		z[0] = byte(extensionStatusRequest >> 8)
+		z[1] = byte(extensionStatusRequest)
+		z[2] = 0
+		z[3] = 5
+		z[4] = 1 // OCSP type
+		// Two zero valued uint16s for the two lengths.
+		z = z[9:]
+	}
+	if len(m.supportedCurves) > 0 {
+		// http://tools.ietf.org/html/rfc4492#section-5.5.1
+		z[0] = byte(extensionSupportedCurves >> 8)
+		z[1] = byte(extensionSupportedCurves)
+		l := 2 + 2*len(m.supportedCurves)
+		z[2] = byte(l >> 8)
+		z[3] = byte(l)
+		l -= 2
+		z[4] = byte(l >> 8)
+		z[5] = byte(l)
+		z = z[6:]
+		for _, curve := range m.supportedCurves {
+			z[0] = byte(curve >> 8)
+			z[1] = byte(curve)
+			z = z[2:]
+		}
+	}
+	if len(m.supportedPoints) > 0 {
+		// http://tools.ietf.org/html/rfc4492#section-5.5.2
+		z[0] = byte(extensionSupportedPoints >> 8)
+		z[1] = byte(extensionSupportedPoints)
+		l := 1 + len(m.supportedPoints)
+		z[2] = byte(l >> 8)
+		z[3] = byte(l)
+		l--
+		z[4] = byte(l)
+		z = z[5:]
+		for _, pointFormat := range m.supportedPoints {
+			z[0] = byte(pointFormat)
+			z = z[1:]
+		}
+	}
+	if m.ticketSupported {
+		// http://tools.ietf.org/html/rfc5077#section-3.2
+		z[0] = byte(extensionSessionTicket >> 8)
+		z[1] = byte(extensionSessionTicket)
+		l := len(m.sessionTicket)
+		z[2] = byte(l >> 8)
+		z[3] = byte(l)
+		z = z[4:]
+		copy(z, m.sessionTicket)
+		z = z[len(m.sessionTicket):]
+	}
+	if len(m.signatureAndHashes) > 0 {
+		// https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
+		z[0] = byte(extensionSignatureAlgorithms >> 8)
+		z[1] = byte(extensionSignatureAlgorithms)
+		l := 2 + 2*len(m.signatureAndHashes)
+		z[2] = byte(l >> 8)
+		z[3] = byte(l)
+		z = z[4:]
+
+		l -= 2
+		z[0] = byte(l >> 8)
+		z[1] = byte(l)
+		z = z[2:]
+		for _, sigAndHash := range m.signatureAndHashes {
+			z[0] = sigAndHash.hash
+			z[1] = sigAndHash.signature
+			z = z[2:]
+		}
+	}
+	if m.secureRenegotiation {
+		z[0] = byte(extensionRenegotiationInfo >> 8)
+		z[1] = byte(extensionRenegotiationInfo & 0xff)
+		z[2] = 0
+		z[3] = 1
+		z = z[5:]
+	}
+	if len(m.alpnProtocols) > 0 {
+		z[0] = byte(extensionALPN >> 8)
+		z[1] = byte(extensionALPN & 0xff)
+		lengths := z[2:]
+		z = z[6:]
+
+		stringsLength := 0
+		for _, s := range m.alpnProtocols {
+			l := len(s)
+			z[0] = byte(l)
+			copy(z[1:], s)
+			z = z[1+l:]
+			stringsLength += 1 + l
+		}
+
+		lengths[2] = byte(stringsLength >> 8)
+		lengths[3] = byte(stringsLength)
+		stringsLength += 2
+		lengths[0] = byte(stringsLength >> 8)
+		lengths[1] = byte(stringsLength)
+	}
+
+	m.raw = x
+
+	return x
+}
+
+func (m *clientHelloMsg) unmarshal(data []byte) bool {
+	if len(data) < 42 {
+		return false
+	}
+	m.raw = data
+	m.vers = uint16(data[4])<<8 | uint16(data[5])
+	m.random = data[6:38]
+	sessionIdLen := int(data[38])
+	if sessionIdLen > 32 || len(data) < 39+sessionIdLen {
+		return false
+	}
+	m.sessionId = data[39 : 39+sessionIdLen]
+	data = data[39+sessionIdLen:]
+	if len(data) < 2 {
+		return false
+	}
+	// cipherSuiteLen is the number of bytes of cipher suite numbers. Since
+	// they are uint16s, the number must be even.
+	cipherSuiteLen := int(data[0])<<8 | int(data[1])
+	if cipherSuiteLen%2 == 1 || len(data) < 2+cipherSuiteLen {
+		return false
+	}
+	numCipherSuites := cipherSuiteLen / 2
+	m.cipherSuites = make([]uint16, numCipherSuites)
+	for i := 0; i < numCipherSuites; i++ {
+		m.cipherSuites[i] = uint16(data[2+2*i])<<8 | uint16(data[3+2*i])
+		if m.cipherSuites[i] == scsvRenegotiation {
+			m.secureRenegotiation = true
+		}
+	}
+	data = data[2+cipherSuiteLen:]
+	if len(data) < 1 {
+		return false
+	}
+	compressionMethodsLen := int(data[0])
+	if len(data) < 1+compressionMethodsLen {
+		return false
+	}
+	m.compressionMethods = data[1 : 1+compressionMethodsLen]
+
+	data = data[1+compressionMethodsLen:]
+
+	m.nextProtoNeg = false
+	m.serverName = ""
+	m.ocspStapling = false
+	m.ticketSupported = false
+	m.sessionTicket = nil
+	m.signatureAndHashes = nil
+	m.alpnProtocols = nil
+
+	if len(data) == 0 {
+		// ClientHello is optionally followed by extension data
+		return true
+	}
+	if len(data) < 2 {
+		return false
+	}
+
+	extensionsLength := int(data[0])<<8 | int(data[1])
+	data = data[2:]
+	if extensionsLength != len(data) {
+		return false
+	}
+
+	for len(data) != 0 {
+		if len(data) < 4 {
+			return false
+		}
+		extension := uint16(data[0])<<8 | uint16(data[1])
+		length := int(data[2])<<8 | int(data[3])
+		data = data[4:]
+		if len(data) < length {
+			return false
+		}
+
+		switch extension {
+		case extensionServerName:
+			if length < 2 {
+				return false
+			}
+			numNames := int(data[0])<<8 | int(data[1])
+			d := data[2:]
+			for i := 0; i < numNames; i++ {
+				if len(d) < 3 {
+					return false
+				}
+				nameType := d[0]
+				nameLen := int(d[1])<<8 | int(d[2])
+				d = d[3:]
+				if len(d) < nameLen {
+					return false
+				}
+				if nameType == 0 {
+					m.serverName = string(d[0:nameLen])
+					break
+				}
+				d = d[nameLen:]
+			}
+		case extensionNextProtoNeg:
+			if length > 0 {
+				return false
+			}
+			m.nextProtoNeg = true
+		case extensionStatusRequest:
+			m.ocspStapling = length > 0 && data[0] == statusTypeOCSP
+		case extensionSupportedCurves:
+			// http://tools.ietf.org/html/rfc4492#section-5.5.1
+			if length < 2 {
+				return false
+			}
+			l := int(data[0])<<8 | int(data[1])
+			if l%2 == 1 || length != l+2 {
+				return false
+			}
+			numCurves := l / 2
+			m.supportedCurves = make([]CurveID, numCurves)
+			d := data[2:]
+			for i := 0; i < numCurves; i++ {
+				m.supportedCurves[i] = CurveID(d[0])<<8 | CurveID(d[1])
+				d = d[2:]
+			}
+		case extensionSupportedPoints:
+			// http://tools.ietf.org/html/rfc4492#section-5.5.2
+			if length < 1 {
+				return false
+			}
+			l := int(data[0])
+			if length != l+1 {
+				return false
+			}
+			m.supportedPoints = make([]uint8, l)
+			copy(m.supportedPoints, data[1:])
+		case extensionSessionTicket:
+			// http://tools.ietf.org/html/rfc5077#section-3.2
+			m.ticketSupported = true
+			m.sessionTicket = data[:length]
+		case extensionSignatureAlgorithms:
+			// https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
+			if length < 2 || length&1 != 0 {
+				return false
+			}
+			l := int(data[0])<<8 | int(data[1])
+			if l != length-2 {
+				return false
+			}
+			n := l / 2
+			d := data[2:]
+			m.signatureAndHashes = make([]signatureAndHash, n)
+			for i := range m.signatureAndHashes {
+				m.signatureAndHashes[i].hash = d[0]
+				m.signatureAndHashes[i].signature = d[1]
+				d = d[2:]
+			}
+		case extensionRenegotiationInfo + 1:
+			if length != 1 || data[0] != 0 {
+				return false
+			}
+			m.secureRenegotiation = true
+		case extensionALPN:
+			if length < 2 {
+				return false
+			}
+			l := int(data[0])<<8 | int(data[1])
+			if l != length-2 {
+				return false
+			}
+			d := data[2:length]
+			for len(d) != 0 {
+				stringLen := int(d[0])
+				d = d[1:]
+				if stringLen == 0 || stringLen > len(d) {
+					return false
+				}
+				m.alpnProtocols = append(m.alpnProtocols, string(d[:stringLen]))
+				d = d[stringLen:]
+			}
+		}
+		data = data[length:]
+	}
+
+	return true
+}
+
+type serverHelloMsg struct {
+	raw                 []byte
+	vers                uint16
+	random              []byte
+	sessionId           []byte
+	cipherSuite         uint16
+	compressionMethod   uint8
+	nextProtoNeg        bool
+	nextProtos          []string
+	ocspStapling        bool
+	ticketSupported     bool
+	secureRenegotiation bool
+	alpnProtocol        string
+}
+
+func (m *serverHelloMsg) equal(i interface{}) bool {
+	m1, ok := i.(*serverHelloMsg)
+	if !ok {
+		return false
+	}
+
+	return bytes.Equal(m.raw, m1.raw) &&
+		m.vers == m1.vers &&
+		bytes.Equal(m.random, m1.random) &&
+		bytes.Equal(m.sessionId, m1.sessionId) &&
+		m.cipherSuite == m1.cipherSuite &&
+		m.compressionMethod == m1.compressionMethod &&
+		m.nextProtoNeg == m1.nextProtoNeg &&
+		eqStrings(m.nextProtos, m1.nextProtos) &&
+		m.ocspStapling == m1.ocspStapling &&
+		m.ticketSupported == m1.ticketSupported &&
+		m.secureRenegotiation == m1.secureRenegotiation &&
+		m.alpnProtocol == m1.alpnProtocol
+}
+
+func (m *serverHelloMsg) marshal() []byte {
+	if m.raw != nil {
+		return m.raw
+	}
+
+	length := 38 + len(m.sessionId)
+	numExtensions := 0
+	extensionsLength := 0
+
+	nextProtoLen := 0
+	if m.nextProtoNeg {
+		numExtensions++
+		for _, v := range m.nextProtos {
+			nextProtoLen += len(v)
+		}
+		nextProtoLen += len(m.nextProtos)
+		extensionsLength += nextProtoLen
+	}
+	if m.ocspStapling {
+		numExtensions++
+	}
+	if m.ticketSupported {
+		numExtensions++
+	}
+	if m.secureRenegotiation {
+		extensionsLength += 1
+		numExtensions++
+	}
+	if alpnLen := len(m.alpnProtocol); alpnLen > 0 {
+		if alpnLen >= 256 {
+			panic("invalid ALPN protocol")
+		}
+		extensionsLength += 2 + 1 + alpnLen
+		numExtensions++
+	}
+
+	if numExtensions > 0 {
+		extensionsLength += 4 * numExtensions
+		length += 2 + extensionsLength
+	}
+
+	x := make([]byte, 4+length)
+	x[0] = typeServerHello
+	x[1] = uint8(length >> 16)
+	x[2] = uint8(length >> 8)
+	x[3] = uint8(length)
+	x[4] = uint8(m.vers >> 8)
+	x[5] = uint8(m.vers)
+	copy(x[6:38], m.random)
+	x[38] = uint8(len(m.sessionId))
+	copy(x[39:39+len(m.sessionId)], m.sessionId)
+	z := x[39+len(m.sessionId):]
+	z[0] = uint8(m.cipherSuite >> 8)
+	z[1] = uint8(m.cipherSuite)
+	z[2] = uint8(m.compressionMethod)
+
+	z = z[3:]
+	if numExtensions > 0 {
+		z[0] = byte(extensionsLength >> 8)
+		z[1] = byte(extensionsLength)
+		z = z[2:]
+	}
+	if m.nextProtoNeg {
+		z[0] = byte(extensionNextProtoNeg >> 8)
+		z[1] = byte(extensionNextProtoNeg & 0xff)
+		z[2] = byte(nextProtoLen >> 8)
+		z[3] = byte(nextProtoLen)
+		z = z[4:]
+
+		for _, v := range m.nextProtos {
+			l := len(v)
+			if l > 255 {
+				l = 255
+			}
+			z[0] = byte(l)
+			copy(z[1:], []byte(v[0:l]))
+			z = z[1+l:]
+		}
+	}
+	if m.ocspStapling {
+		z[0] = byte(extensionStatusRequest >> 8)
+		z[1] = byte(extensionStatusRequest)
+		z = z[4:]
+	}
+	if m.ticketSupported {
+		z[0] = byte(extensionSessionTicket >> 8)
+		z[1] = byte(extensionSessionTicket)
+		z = z[4:]
+	}
+	if m.secureRenegotiation {
+		z[0] = byte(extensionRenegotiationInfo >> 8)
+		z[1] = byte(extensionRenegotiationInfo & 0xff)
+		z[2] = 0
+		z[3] = 1
+		z = z[5:]
+	}
+	if alpnLen := len(m.alpnProtocol); alpnLen > 0 {
+		z[0] = byte(extensionALPN >> 8)
+		z[1] = byte(extensionALPN & 0xff)
+		l := 2 + 1 + alpnLen
+		z[2] = byte(l >> 8)
+		z[3] = byte(l)
+		l -= 2
+		z[4] = byte(l >> 8)
+		z[5] = byte(l)
+		l -= 1
+		z[6] = byte(l)
+		copy(z[7:], []byte(m.alpnProtocol))
+		z = z[7+alpnLen:]
+	}
+
+	m.raw = x
+
+	return x
+}
+
+func (m *serverHelloMsg) unmarshal(data []byte) bool {
+	if len(data) < 42 {
+		return false
+	}
+	m.raw = data
+	m.vers = uint16(data[4])<<8 | uint16(data[5])
+	m.random = data[6:38]
+	sessionIdLen := int(data[38])
+	if sessionIdLen > 32 || len(data) < 39+sessionIdLen {
+		return false
+	}
+	m.sessionId = data[39 : 39+sessionIdLen]
+	data = data[39+sessionIdLen:]
+	if len(data) < 3 {
+		return false
+	}
+	m.cipherSuite = uint16(data[0])<<8 | uint16(data[1])
+	m.compressionMethod = data[2]
+	data = data[3:]
+
+	m.nextProtoNeg = false
+	m.nextProtos = nil
+	m.ocspStapling = false
+	m.ticketSupported = false
+	m.alpnProtocol = ""
+
+	if len(data) == 0 {
+		// ServerHello is optionally followed by extension data
+		return true
+	}
+	if len(data) < 2 {
+		return false
+	}
+
+	extensionsLength := int(data[0])<<8 | int(data[1])
+	data = data[2:]
+	if len(data) != extensionsLength {
+		return false
+	}
+
+	for len(data) != 0 {
+		if len(data) < 4 {
+			return false
+		}
+		extension := uint16(data[0])<<8 | uint16(data[1])
+		length := int(data[2])<<8 | int(data[3])
+		data = data[4:]
+		if len(data) < length {
+			return false
+		}
+
+		switch extension {
+		case extensionNextProtoNeg:
+			m.nextProtoNeg = true
+			d := data[:length]
+			for len(d) > 0 {
+				l := int(d[0])
+				d = d[1:]
+				if l == 0 || l > len(d) {
+					return false
+				}
+				m.nextProtos = append(m.nextProtos, string(d[:l]))
+				d = d[l:]
+			}
+		case extensionStatusRequest:
+			if length > 0 {
+				return false
+			}
+			m.ocspStapling = true
+		case extensionSessionTicket:
+			if length > 0 {
+				return false
+			}
+			m.ticketSupported = true
+		case extensionRenegotiationInfo:
+			if length != 1 || data[0] != 0 {
+				return false
+			}
+			m.secureRenegotiation = true
+		case extensionALPN:
+			d := data[:length]
+			if len(d) < 3 {
+				return false
+			}
+			l := int(d[0])<<8 | int(d[1])
+			if l != len(d)-2 {
+				return false
+			}
+			d = d[2:]
+			l = int(d[0])
+			if l != len(d)-1 {
+				return false
+			}
+			d = d[1:]
+			m.alpnProtocol = string(d)
+		}
+		data = data[length:]
+	}
+
+	return true
+}
+
+type certificateMsg struct {
+	raw          []byte
+	certificates [][]byte
+}
+
+func (m *certificateMsg) equal(i interface{}) bool {
+	m1, ok := i.(*certificateMsg)
+	if !ok {
+		return false
+	}
+
+	return bytes.Equal(m.raw, m1.raw) &&
+		eqByteSlices(m.certificates, m1.certificates)
+}
+
+func (m *certificateMsg) marshal() (x []byte) {
+	if m.raw != nil {
+		return m.raw
+	}
+
+	var i int
+	for _, slice := range m.certificates {
+		i += len(slice)
+	}
+
+	length := 3 + 3*len(m.certificates) + i
+	x = make([]byte, 4+length)
+	x[0] = typeCertificate
+	x[1] = uint8(length >> 16)
+	x[2] = uint8(length >> 8)
+	x[3] = uint8(length)
+
+	certificateOctets := length - 3
+	x[4] = uint8(certificateOctets >> 16)
+	x[5] = uint8(certificateOctets >> 8)
+	x[6] = uint8(certificateOctets)
+
+	y := x[7:]
+	for _, slice := range m.certificates {
+		y[0] = uint8(len(slice) >> 16)
+		y[1] = uint8(len(slice) >> 8)
+		y[2] = uint8(len(slice))
+		copy(y[3:], slice)
+		y = y[3+len(slice):]
+	}
+
+	m.raw = x
+	return
+}
+
+func (m *certificateMsg) unmarshal(data []byte) bool {
+	if len(data) < 7 {
+		return false
+	}
+
+	m.raw = data
+	certsLen := uint32(data[4])<<16 | uint32(data[5])<<8 | uint32(data[6])
+	if uint32(len(data)) != certsLen+7 {
+		return false
+	}
+
+	numCerts := 0
+	d := data[7:]
+	for certsLen > 0 {
+		if len(d) < 4 {
+			return false
+		}
+		certLen := uint32(d[0])<<16 | uint32(d[1])<<8 | uint32(d[2])
+		if uint32(len(d)) < 3+certLen {
+			return false
+		}
+		d = d[3+certLen:]
+		certsLen -= 3 + certLen
+		numCerts++
+	}
+
+	m.certificates = make([][]byte, numCerts)
+	d = data[7:]
+	for i := 0; i < numCerts; i++ {
+		certLen := uint32(d[0])<<16 | uint32(d[1])<<8 | uint32(d[2])
+		m.certificates[i] = d[3 : 3+certLen]
+		d = d[3+certLen:]
+	}
+
+	return true
+}
+
+type serverKeyExchangeMsg struct {
+	raw []byte
+	key []byte
+}
+
+func (m *serverKeyExchangeMsg) equal(i interface{}) bool {
+	m1, ok := i.(*serverKeyExchangeMsg)
+	if !ok {
+		return false
+	}
+
+	return bytes.Equal(m.raw, m1.raw) &&
+		bytes.Equal(m.key, m1.key)
+}
+
+func (m *serverKeyExchangeMsg) marshal() []byte {
+	if m.raw != nil {
+		return m.raw
+	}
+	length := len(m.key)
+	x := make([]byte, length+4)
+	x[0] = typeServerKeyExchange
+	x[1] = uint8(length >> 16)
+	x[2] = uint8(length >> 8)
+	x[3] = uint8(length)
+	copy(x[4:], m.key)
+
+	m.raw = x
+	return x
+}
+
+func (m *serverKeyExchangeMsg) unmarshal(data []byte) bool {
+	m.raw = data
+	if len(data) < 4 {
+		return false
+	}
+	m.key = data[4:]
+	return true
+}
+
+type certificateStatusMsg struct {
+	raw        []byte
+	statusType uint8
+	response   []byte
+}
+
+func (m *certificateStatusMsg) equal(i interface{}) bool {
+	m1, ok := i.(*certificateStatusMsg)
+	if !ok {
+		return false
+	}
+
+	return bytes.Equal(m.raw, m1.raw) &&
+		m.statusType == m1.statusType &&
+		bytes.Equal(m.response, m1.response)
+}
+
+func (m *certificateStatusMsg) marshal() []byte {
+	if m.raw != nil {
+		return m.raw
+	}
+
+	var x []byte
+	if m.statusType == statusTypeOCSP {
+		x = make([]byte, 4+4+len(m.response))
+		x[0] = typeCertificateStatus
+		l := len(m.response) + 4
+		x[1] = byte(l >> 16)
+		x[2] = byte(l >> 8)
+		x[3] = byte(l)
+		x[4] = statusTypeOCSP
+
+		l -= 4
+		x[5] = byte(l >> 16)
+		x[6] = byte(l >> 8)
+		x[7] = byte(l)
+		copy(x[8:], m.response)
+	} else {
+		x = []byte{typeCertificateStatus, 0, 0, 1, m.statusType}
+	}
+
+	m.raw = x
+	return x
+}
+
+func (m *certificateStatusMsg) unmarshal(data []byte) bool {
+	m.raw = data
+	if len(data) < 5 {
+		return false
+	}
+	m.statusType = data[4]
+
+	m.response = nil
+	if m.statusType == statusTypeOCSP {
+		if len(data) < 8 {
+			return false
+		}
+		respLen := uint32(data[5])<<16 | uint32(data[6])<<8 | uint32(data[7])
+		if uint32(len(data)) != 4+4+respLen {
+			return false
+		}
+		m.response = data[8:]
+	}
+	return true
+}
+
+type serverHelloDoneMsg struct{}
+
+func (m *serverHelloDoneMsg) equal(i interface{}) bool {
+	_, ok := i.(*serverHelloDoneMsg)
+	return ok
+}
+
+func (m *serverHelloDoneMsg) marshal() []byte {
+	x := make([]byte, 4)
+	x[0] = typeServerHelloDone
+	return x
+}
+
+func (m *serverHelloDoneMsg) unmarshal(data []byte) bool {
+	return len(data) == 4
+}
+
+type clientKeyExchangeMsg struct {
+	raw        []byte
+	ciphertext []byte
+}
+
+func (m *clientKeyExchangeMsg) equal(i interface{}) bool {
+	m1, ok := i.(*clientKeyExchangeMsg)
+	if !ok {
+		return false
+	}
+
+	return bytes.Equal(m.raw, m1.raw) &&
+		bytes.Equal(m.ciphertext, m1.ciphertext)
+}
+
+func (m *clientKeyExchangeMsg) marshal() []byte {
+	if m.raw != nil {
+		return m.raw
+	}
+	length := len(m.ciphertext)
+	x := make([]byte, length+4)
+	x[0] = typeClientKeyExchange
+	x[1] = uint8(length >> 16)
+	x[2] = uint8(length >> 8)
+	x[3] = uint8(length)
+	copy(x[4:], m.ciphertext)
+
+	m.raw = x
+	return x
+}
+
+func (m *clientKeyExchangeMsg) unmarshal(data []byte) bool {
+	m.raw = data
+	if len(data) < 4 {
+		return false
+	}
+	l := int(data[1])<<16 | int(data[2])<<8 | int(data[3])
+	if l != len(data)-4 {
+		return false
+	}
+	m.ciphertext = data[4:]
+	return true
+}
+
+type finishedMsg struct {
+	raw        []byte
+	verifyData []byte
+}
+
+func (m *finishedMsg) equal(i interface{}) bool {
+	m1, ok := i.(*finishedMsg)
+	if !ok {
+		return false
+	}
+
+	return bytes.Equal(m.raw, m1.raw) &&
+		bytes.Equal(m.verifyData, m1.verifyData)
+}
+
+func (m *finishedMsg) marshal() (x []byte) {
+	if m.raw != nil {
+		return m.raw
+	}
+
+	x = make([]byte, 4+len(m.verifyData))
+	x[0] = typeFinished
+	x[3] = byte(len(m.verifyData))
+	copy(x[4:], m.verifyData)
+	m.raw = x
+	return
+}
+
+func (m *finishedMsg) unmarshal(data []byte) bool {
+	m.raw = data
+	if len(data) < 4 {
+		return false
+	}
+	m.verifyData = data[4:]
+	return true
+}
+
+type nextProtoMsg struct {
+	raw   []byte
+	proto string
+}
+
+func (m *nextProtoMsg) equal(i interface{}) bool {
+	m1, ok := i.(*nextProtoMsg)
+	if !ok {
+		return false
+	}
+
+	return bytes.Equal(m.raw, m1.raw) &&
+		m.proto == m1.proto
+}
+
+func (m *nextProtoMsg) marshal() []byte {
+	if m.raw != nil {
+		return m.raw
+	}
+	l := len(m.proto)
+	if l > 255 {
+		l = 255
+	}
+
+	padding := 32 - (l+2)%32
+	length := l + padding + 2
+	x := make([]byte, length+4)
+	x[0] = typeNextProtocol
+	x[1] = uint8(length >> 16)
+	x[2] = uint8(length >> 8)
+	x[3] = uint8(length)
+
+	y := x[4:]
+	y[0] = byte(l)
+	copy(y[1:], []byte(m.proto[0:l]))
+	y = y[1+l:]
+	y[0] = byte(padding)
+
+	m.raw = x
+
+	return x
+}
+
+func (m *nextProtoMsg) unmarshal(data []byte) bool {
+	m.raw = data
+
+	if len(data) < 5 {
+		return false
+	}
+	data = data[4:]
+	protoLen := int(data[0])
+	data = data[1:]
+	if len(data) < protoLen {
+		return false
+	}
+	m.proto = string(data[0:protoLen])
+	data = data[protoLen:]
+
+	if len(data) < 1 {
+		return false
+	}
+	paddingLen := int(data[0])
+	data = data[1:]
+	if len(data) != paddingLen {
+		return false
+	}
+
+	return true
+}
+
+type certificateRequestMsg struct {
+	raw []byte
+	// hasSignatureAndHash indicates whether this message includes a list
+	// of signature and hash functions. This change was introduced with TLS
+	// 1.2.
+	hasSignatureAndHash bool
+
+	certificateTypes       []byte
+	signatureAndHashes     []signatureAndHash
+	certificateAuthorities [][]byte
+}
+
+func (m *certificateRequestMsg) equal(i interface{}) bool {
+	m1, ok := i.(*certificateRequestMsg)
+	if !ok {
+		return false
+	}
+
+	return bytes.Equal(m.raw, m1.raw) &&
+		bytes.Equal(m.certificateTypes, m1.certificateTypes) &&
+		eqByteSlices(m.certificateAuthorities, m1.certificateAuthorities) &&
+		eqSignatureAndHashes(m.signatureAndHashes, m1.signatureAndHashes)
+}
+
+func (m *certificateRequestMsg) marshal() (x []byte) {
+	if m.raw != nil {
+		return m.raw
+	}
+
+	// See http://tools.ietf.org/html/rfc4346#section-7.4.4
+	length := 1 + len(m.certificateTypes) + 2
+	casLength := 0
+	for _, ca := range m.certificateAuthorities {
+		casLength += 2 + len(ca)
+	}
+	length += casLength
+
+	if m.hasSignatureAndHash {
+		length += 2 + 2*len(m.signatureAndHashes)
+	}
+
+	x = make([]byte, 4+length)
+	x[0] = typeCertificateRequest
+	x[1] = uint8(length >> 16)
+	x[2] = uint8(length >> 8)
+	x[3] = uint8(length)
+
+	x[4] = uint8(len(m.certificateTypes))
+
+	copy(x[5:], m.certificateTypes)
+	y := x[5+len(m.certificateTypes):]
+
+	if m.hasSignatureAndHash {
+		n := len(m.signatureAndHashes) * 2
+		y[0] = uint8(n >> 8)
+		y[1] = uint8(n)
+		y = y[2:]
+		for _, sigAndHash := range m.signatureAndHashes {
+			y[0] = sigAndHash.hash
+			y[1] = sigAndHash.signature
+			y = y[2:]
+		}
+	}
+
+	y[0] = uint8(casLength >> 8)
+	y[1] = uint8(casLength)
+	y = y[2:]
+	for _, ca := range m.certificateAuthorities {
+		y[0] = uint8(len(ca) >> 8)
+		y[1] = uint8(len(ca))
+		y = y[2:]
+		copy(y, ca)
+		y = y[len(ca):]
+	}
+
+	m.raw = x
+	return
+}
+
+func (m *certificateRequestMsg) unmarshal(data []byte) bool {
+	m.raw = data
+
+	if len(data) < 5 {
+		return false
+	}
+
+	length := uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
+	if uint32(len(data))-4 != length {
+		return false
+	}
+
+	numCertTypes := int(data[4])
+	data = data[5:]
+	if numCertTypes == 0 || len(data) <= numCertTypes {
+		return false
+	}
+
+	m.certificateTypes = make([]byte, numCertTypes)
+	if copy(m.certificateTypes, data) != numCertTypes {
+		return false
+	}
+
+	data = data[numCertTypes:]
+
+	if m.hasSignatureAndHash {
+		if len(data) < 2 {
+			return false
+		}
+		sigAndHashLen := uint16(data[0])<<8 | uint16(data[1])
+		data = data[2:]
+		if sigAndHashLen&1 != 0 {
+			return false
+		}
+		if len(data) < int(sigAndHashLen) {
+			return false
+		}
+		numSigAndHash := sigAndHashLen / 2
+		m.signatureAndHashes = make([]signatureAndHash, numSigAndHash)
+		for i := range m.signatureAndHashes {
+			m.signatureAndHashes[i].hash = data[0]
+			m.signatureAndHashes[i].signature = data[1]
+			data = data[2:]
+		}
+	}
+
+	if len(data) < 2 {
+		return false
+	}
+	casLength := uint16(data[0])<<8 | uint16(data[1])
+	data = data[2:]
+	if len(data) < int(casLength) {
+		return false
+	}
+	cas := make([]byte, casLength)
+	copy(cas, data)
+	data = data[casLength:]
+
+	m.certificateAuthorities = nil
+	for len(cas) > 0 {
+		if len(cas) < 2 {
+			return false
+		}
+		caLen := uint16(cas[0])<<8 | uint16(cas[1])
+		cas = cas[2:]
+
+		if len(cas) < int(caLen) {
+			return false
+		}
+
+		m.certificateAuthorities = append(m.certificateAuthorities, cas[:caLen])
+		cas = cas[caLen:]
+	}
+	if len(data) > 0 {
+		return false
+	}
+
+	return true
+}
+
+type certificateVerifyMsg struct {
+	raw                 []byte
+	hasSignatureAndHash bool
+	signatureAndHash    signatureAndHash
+	signature           []byte
+}
+
+func (m *certificateVerifyMsg) equal(i interface{}) bool {
+	m1, ok := i.(*certificateVerifyMsg)
+	if !ok {
+		return false
+	}
+
+	return bytes.Equal(m.raw, m1.raw) &&
+		m.hasSignatureAndHash == m1.hasSignatureAndHash &&
+		m.signatureAndHash.hash == m1.signatureAndHash.hash &&
+		m.signatureAndHash.signature == m1.signatureAndHash.signature &&
+		bytes.Equal(m.signature, m1.signature)
+}
+
+func (m *certificateVerifyMsg) marshal() (x []byte) {
+	if m.raw != nil {
+		return m.raw
+	}
+
+	// See http://tools.ietf.org/html/rfc4346#section-7.4.8
+	siglength := len(m.signature)
+	length := 2 + siglength
+	if m.hasSignatureAndHash {
+		length += 2
+	}
+	x = make([]byte, 4+length)
+	x[0] = typeCertificateVerify
+	x[1] = uint8(length >> 16)
+	x[2] = uint8(length >> 8)
+	x[3] = uint8(length)
+	y := x[4:]
+	if m.hasSignatureAndHash {
+		y[0] = m.signatureAndHash.hash
+		y[1] = m.signatureAndHash.signature
+		y = y[2:]
+	}
+	y[0] = uint8(siglength >> 8)
+	y[1] = uint8(siglength)
+	copy(y[2:], m.signature)
+
+	m.raw = x
+
+	return
+}
+
+func (m *certificateVerifyMsg) unmarshal(data []byte) bool {
+	m.raw = data
+
+	if len(data) < 6 {
+		return false
+	}
+
+	length := uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
+	if uint32(len(data))-4 != length {
+		return false
+	}
+
+	data = data[4:]
+	if m.hasSignatureAndHash {
+		m.signatureAndHash.hash = data[0]
+		m.signatureAndHash.signature = data[1]
+		data = data[2:]
+	}
+
+	if len(data) < 2 {
+		return false
+	}
+	siglength := int(data[0])<<8 + int(data[1])
+	data = data[2:]
+	if len(data) != siglength {
+		return false
+	}
+
+	m.signature = data
+
+	return true
+}
+
+type newSessionTicketMsg struct {
+	raw    []byte
+	ticket []byte
+}
+
+func (m *newSessionTicketMsg) equal(i interface{}) bool {
+	m1, ok := i.(*newSessionTicketMsg)
+	if !ok {
+		return false
+	}
+
+	return bytes.Equal(m.raw, m1.raw) &&
+		bytes.Equal(m.ticket, m1.ticket)
+}
+
+func (m *newSessionTicketMsg) marshal() (x []byte) {
+	if m.raw != nil {
+		return m.raw
+	}
+
+	// See http://tools.ietf.org/html/rfc5077#section-3.3
+	ticketLen := len(m.ticket)
+	length := 2 + 4 + ticketLen
+	x = make([]byte, 4+length)
+	x[0] = typeNewSessionTicket
+	x[1] = uint8(length >> 16)
+	x[2] = uint8(length >> 8)
+	x[3] = uint8(length)
+	x[8] = uint8(ticketLen >> 8)
+	x[9] = uint8(ticketLen)
+	copy(x[10:], m.ticket)
+
+	m.raw = x
+
+	return
+}
+
+func (m *newSessionTicketMsg) unmarshal(data []byte) bool {
+	m.raw = data
+
+	if len(data) < 10 {
+		return false
+	}
+
+	length := uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
+	if uint32(len(data))-4 != length {
+		return false
+	}
+
+	ticketLen := int(data[8])<<8 + int(data[9])
+	if len(data)-10 != ticketLen {
+		return false
+	}
+
+	m.ticket = data[10:]
+
+	return true
+}
+
+func eqUint16s(x, y []uint16) bool {
+	if len(x) != len(y) {
+		return false
+	}
+	for i, v := range x {
+		if y[i] != v {
+			return false
+		}
+	}
+	return true
+}
+
+func eqCurveIDs(x, y []CurveID) bool {
+	if len(x) != len(y) {
+		return false
+	}
+	for i, v := range x {
+		if y[i] != v {
+			return false
+		}
+	}
+	return true
+}
+
+func eqStrings(x, y []string) bool {
+	if len(x) != len(y) {
+		return false
+	}
+	for i, v := range x {
+		if y[i] != v {
+			return false
+		}
+	}
+	return true
+}
+
+func eqByteSlices(x, y [][]byte) bool {
+	if len(x) != len(y) {
+		return false
+	}
+	for i, v := range x {
+		if !bytes.Equal(v, y[i]) {
+			return false
+		}
+	}
+	return true
+}
+
+func eqSignatureAndHashes(x, y []signatureAndHash) bool {
+	if len(x) != len(y) {
+		return false
+	}
+	for i, v := range x {
+		v2 := y[i]
+		if v.hash != v2.hash || v.signature != v2.signature {
+			return false
+		}
+	}
+	return true
+}
diff --git a/src/crypto/tls/handshake_messages_test.go b/src/crypto/tls/handshake_messages_test.go
new file mode 100644
index 0000000..a96e95c
--- /dev/null
+++ b/src/crypto/tls/handshake_messages_test.go
@@ -0,0 +1,251 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tls
+
+import (
+	"math/rand"
+	"reflect"
+	"testing"
+	"testing/quick"
+)
+
+var tests = []interface{}{
+	&clientHelloMsg{},
+	&serverHelloMsg{},
+	&finishedMsg{},
+
+	&certificateMsg{},
+	&certificateRequestMsg{},
+	&certificateVerifyMsg{},
+	&certificateStatusMsg{},
+	&clientKeyExchangeMsg{},
+	&nextProtoMsg{},
+	&newSessionTicketMsg{},
+	&sessionState{},
+}
+
+type testMessage interface {
+	marshal() []byte
+	unmarshal([]byte) bool
+	equal(interface{}) bool
+}
+
+func TestMarshalUnmarshal(t *testing.T) {
+	rand := rand.New(rand.NewSource(0))
+
+	for i, iface := range tests {
+		ty := reflect.ValueOf(iface).Type()
+
+		n := 100
+		if testing.Short() {
+			n = 5
+		}
+		for j := 0; j < n; j++ {
+			v, ok := quick.Value(ty, rand)
+			if !ok {
+				t.Errorf("#%d: failed to create value", i)
+				break
+			}
+
+			m1 := v.Interface().(testMessage)
+			marshaled := m1.marshal()
+			m2 := iface.(testMessage)
+			if !m2.unmarshal(marshaled) {
+				t.Errorf("#%d failed to unmarshal %#v %x", i, m1, marshaled)
+				break
+			}
+			m2.marshal() // to fill any marshal cache in the message
+
+			if !m1.equal(m2) {
+				t.Errorf("#%d got:%#v want:%#v %x", i, m2, m1, marshaled)
+				break
+			}
+
+			if i >= 3 {
+				// The first three message types (ClientHello,
+				// ServerHello and Finished) are allowed to
+				// have parsable prefixes because the extension
+				// data is optional and the length of the
+				// Finished varies across versions.
+				for j := 0; j < len(marshaled); j++ {
+					if m2.unmarshal(marshaled[0:j]) {
+						t.Errorf("#%d unmarshaled a prefix of length %d of %#v", i, j, m1)
+						break
+					}
+				}
+			}
+		}
+	}
+}
+
+func TestFuzz(t *testing.T) {
+	rand := rand.New(rand.NewSource(0))
+	for _, iface := range tests {
+		m := iface.(testMessage)
+
+		for j := 0; j < 1000; j++ {
+			len := rand.Intn(100)
+			bytes := randomBytes(len, rand)
+			// This just looks for crashes due to bounds errors etc.
+			m.unmarshal(bytes)
+		}
+	}
+}
+
+func randomBytes(n int, rand *rand.Rand) []byte {
+	r := make([]byte, n)
+	for i := 0; i < n; i++ {
+		r[i] = byte(rand.Int31())
+	}
+	return r
+}
+
+func randomString(n int, rand *rand.Rand) string {
+	b := randomBytes(n, rand)
+	return string(b)
+}
+
+func (*clientHelloMsg) Generate(rand *rand.Rand, size int) reflect.Value {
+	m := &clientHelloMsg{}
+	m.vers = uint16(rand.Intn(65536))
+	m.random = randomBytes(32, rand)
+	m.sessionId = randomBytes(rand.Intn(32), rand)
+	m.cipherSuites = make([]uint16, rand.Intn(63)+1)
+	for i := 0; i < len(m.cipherSuites); i++ {
+		m.cipherSuites[i] = uint16(rand.Int31())
+	}
+	m.compressionMethods = randomBytes(rand.Intn(63)+1, rand)
+	if rand.Intn(10) > 5 {
+		m.nextProtoNeg = true
+	}
+	if rand.Intn(10) > 5 {
+		m.serverName = randomString(rand.Intn(255), rand)
+	}
+	m.ocspStapling = rand.Intn(10) > 5
+	m.supportedPoints = randomBytes(rand.Intn(5)+1, rand)
+	m.supportedCurves = make([]CurveID, rand.Intn(5)+1)
+	for i := range m.supportedCurves {
+		m.supportedCurves[i] = CurveID(rand.Intn(30000))
+	}
+	if rand.Intn(10) > 5 {
+		m.ticketSupported = true
+		if rand.Intn(10) > 5 {
+			m.sessionTicket = randomBytes(rand.Intn(300), rand)
+		}
+	}
+	if rand.Intn(10) > 5 {
+		m.signatureAndHashes = supportedSKXSignatureAlgorithms
+	}
+	m.alpnProtocols = make([]string, rand.Intn(5))
+	for i := range m.alpnProtocols {
+		m.alpnProtocols[i] = randomString(rand.Intn(20)+1, rand)
+	}
+
+	return reflect.ValueOf(m)
+}
+
+func (*serverHelloMsg) Generate(rand *rand.Rand, size int) reflect.Value {
+	m := &serverHelloMsg{}
+	m.vers = uint16(rand.Intn(65536))
+	m.random = randomBytes(32, rand)
+	m.sessionId = randomBytes(rand.Intn(32), rand)
+	m.cipherSuite = uint16(rand.Int31())
+	m.compressionMethod = uint8(rand.Intn(256))
+
+	if rand.Intn(10) > 5 {
+		m.nextProtoNeg = true
+
+		n := rand.Intn(10)
+		m.nextProtos = make([]string, n)
+		for i := 0; i < n; i++ {
+			m.nextProtos[i] = randomString(20, rand)
+		}
+	}
+
+	if rand.Intn(10) > 5 {
+		m.ocspStapling = true
+	}
+	if rand.Intn(10) > 5 {
+		m.ticketSupported = true
+	}
+	m.alpnProtocol = randomString(rand.Intn(32)+1, rand)
+
+	return reflect.ValueOf(m)
+}
+
+func (*certificateMsg) Generate(rand *rand.Rand, size int) reflect.Value {
+	m := &certificateMsg{}
+	numCerts := rand.Intn(20)
+	m.certificates = make([][]byte, numCerts)
+	for i := 0; i < numCerts; i++ {
+		m.certificates[i] = randomBytes(rand.Intn(10)+1, rand)
+	}
+	return reflect.ValueOf(m)
+}
+
+func (*certificateRequestMsg) Generate(rand *rand.Rand, size int) reflect.Value {
+	m := &certificateRequestMsg{}
+	m.certificateTypes = randomBytes(rand.Intn(5)+1, rand)
+	numCAs := rand.Intn(100)
+	m.certificateAuthorities = make([][]byte, numCAs)
+	for i := 0; i < numCAs; i++ {
+		m.certificateAuthorities[i] = randomBytes(rand.Intn(15)+1, rand)
+	}
+	return reflect.ValueOf(m)
+}
+
+func (*certificateVerifyMsg) Generate(rand *rand.Rand, size int) reflect.Value {
+	m := &certificateVerifyMsg{}
+	m.signature = randomBytes(rand.Intn(15)+1, rand)
+	return reflect.ValueOf(m)
+}
+
+func (*certificateStatusMsg) Generate(rand *rand.Rand, size int) reflect.Value {
+	m := &certificateStatusMsg{}
+	if rand.Intn(10) > 5 {
+		m.statusType = statusTypeOCSP
+		m.response = randomBytes(rand.Intn(10)+1, rand)
+	} else {
+		m.statusType = 42
+	}
+	return reflect.ValueOf(m)
+}
+
+func (*clientKeyExchangeMsg) Generate(rand *rand.Rand, size int) reflect.Value {
+	m := &clientKeyExchangeMsg{}
+	m.ciphertext = randomBytes(rand.Intn(1000)+1, rand)
+	return reflect.ValueOf(m)
+}
+
+func (*finishedMsg) Generate(rand *rand.Rand, size int) reflect.Value {
+	m := &finishedMsg{}
+	m.verifyData = randomBytes(12, rand)
+	return reflect.ValueOf(m)
+}
+
+func (*nextProtoMsg) Generate(rand *rand.Rand, size int) reflect.Value {
+	m := &nextProtoMsg{}
+	m.proto = randomString(rand.Intn(255), rand)
+	return reflect.ValueOf(m)
+}
+
+func (*newSessionTicketMsg) Generate(rand *rand.Rand, size int) reflect.Value {
+	m := &newSessionTicketMsg{}
+	m.ticket = randomBytes(rand.Intn(4), rand)
+	return reflect.ValueOf(m)
+}
+
+func (*sessionState) Generate(rand *rand.Rand, size int) reflect.Value {
+	s := &sessionState{}
+	s.vers = uint16(rand.Intn(10000))
+	s.cipherSuite = uint16(rand.Intn(10000))
+	s.masterSecret = randomBytes(rand.Intn(100), rand)
+	numCerts := rand.Intn(20)
+	s.certificates = make([][]byte, numCerts)
+	for i := 0; i < numCerts; i++ {
+		s.certificates[i] = randomBytes(rand.Intn(10)+1, rand)
+	}
+	return reflect.ValueOf(s)
+}
diff --git a/src/crypto/tls/handshake_server.go b/src/crypto/tls/handshake_server.go
new file mode 100644
index 0000000..0d90765
--- /dev/null
+++ b/src/crypto/tls/handshake_server.go
@@ -0,0 +1,685 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tls
+
+import (
+	"crypto"
+	"crypto/ecdsa"
+	"crypto/rsa"
+	"crypto/subtle"
+	"crypto/x509"
+	"encoding/asn1"
+	"errors"
+	"fmt"
+	"io"
+)
+
+// serverHandshakeState contains details of a server handshake in progress.
+// It's discarded once the handshake has completed.
+type serverHandshakeState struct {
+	c               *Conn
+	clientHello     *clientHelloMsg
+	hello           *serverHelloMsg
+	suite           *cipherSuite
+	ellipticOk      bool
+	ecdsaOk         bool
+	sessionState    *sessionState
+	finishedHash    finishedHash
+	masterSecret    []byte
+	certsFromClient [][]byte
+	cert            *Certificate
+}
+
+// serverHandshake performs a TLS handshake as a server.
+func (c *Conn) serverHandshake() error {
+	config := c.config
+
+	// If this is the first server handshake, we generate a random key to
+	// encrypt the tickets with.
+	config.serverInitOnce.Do(config.serverInit)
+
+	hs := serverHandshakeState{
+		c: c,
+	}
+	isResume, err := hs.readClientHello()
+	if err != nil {
+		return err
+	}
+
+	// For an overview of TLS handshaking, see https://tools.ietf.org/html/rfc5246#section-7.3
+	if isResume {
+		// The client has included a session ticket and so we do an abbreviated handshake.
+		if err := hs.doResumeHandshake(); err != nil {
+			return err
+		}
+		if err := hs.establishKeys(); err != nil {
+			return err
+		}
+		if err := hs.sendFinished(c.firstFinished[:]); err != nil {
+			return err
+		}
+		if err := hs.readFinished(nil); err != nil {
+			return err
+		}
+		c.didResume = true
+	} else {
+		// The client didn't include a session ticket, or it wasn't
+		// valid so we do a full handshake.
+		if err := hs.doFullHandshake(); err != nil {
+			return err
+		}
+		if err := hs.establishKeys(); err != nil {
+			return err
+		}
+		if err := hs.readFinished(c.firstFinished[:]); err != nil {
+			return err
+		}
+		if err := hs.sendSessionTicket(); err != nil {
+			return err
+		}
+		if err := hs.sendFinished(nil); err != nil {
+			return err
+		}
+	}
+	c.handshakeComplete = true
+
+	return nil
+}
+
+// readClientHello reads a ClientHello message from the client and decides
+// whether we will perform session resumption.
+func (hs *serverHandshakeState) readClientHello() (isResume bool, err error) {
+	config := hs.c.config
+	c := hs.c
+
+	msg, err := c.readHandshake()
+	if err != nil {
+		return false, err
+	}
+	var ok bool
+	hs.clientHello, ok = msg.(*clientHelloMsg)
+	if !ok {
+		c.sendAlert(alertUnexpectedMessage)
+		return false, unexpectedMessageError(hs.clientHello, msg)
+	}
+	c.vers, ok = config.mutualVersion(hs.clientHello.vers)
+	if !ok {
+		c.sendAlert(alertProtocolVersion)
+		return false, fmt.Errorf("tls: client offered an unsupported, maximum protocol version of %x", hs.clientHello.vers)
+	}
+	c.haveVers = true
+
+	hs.finishedHash = newFinishedHash(c.vers)
+	hs.finishedHash.Write(hs.clientHello.marshal())
+
+	hs.hello = new(serverHelloMsg)
+
+	supportedCurve := false
+	preferredCurves := config.curvePreferences()
+Curves:
+	for _, curve := range hs.clientHello.supportedCurves {
+		for _, supported := range preferredCurves {
+			if supported == curve {
+				supportedCurve = true
+				break Curves
+			}
+		}
+	}
+
+	supportedPointFormat := false
+	for _, pointFormat := range hs.clientHello.supportedPoints {
+		if pointFormat == pointFormatUncompressed {
+			supportedPointFormat = true
+			break
+		}
+	}
+	hs.ellipticOk = supportedCurve && supportedPointFormat
+
+	foundCompression := false
+	// We only support null compression, so check that the client offered it.
+	for _, compression := range hs.clientHello.compressionMethods {
+		if compression == compressionNone {
+			foundCompression = true
+			break
+		}
+	}
+
+	if !foundCompression {
+		c.sendAlert(alertHandshakeFailure)
+		return false, errors.New("tls: client does not support uncompressed connections")
+	}
+
+	hs.hello.vers = c.vers
+	hs.hello.random = make([]byte, 32)
+	_, err = io.ReadFull(config.rand(), hs.hello.random)
+	if err != nil {
+		c.sendAlert(alertInternalError)
+		return false, err
+	}
+	hs.hello.secureRenegotiation = hs.clientHello.secureRenegotiation
+	hs.hello.compressionMethod = compressionNone
+	if len(hs.clientHello.serverName) > 0 {
+		c.serverName = hs.clientHello.serverName
+	}
+
+	if len(hs.clientHello.alpnProtocols) > 0 {
+		if selectedProto, fallback := mutualProtocol(hs.clientHello.alpnProtocols, c.config.NextProtos); !fallback {
+			hs.hello.alpnProtocol = selectedProto
+			c.clientProtocol = selectedProto
+		}
+	} else {
+		// Although sending an empty NPN extension is reasonable, Firefox has
+		// had a bug around this. Best to send nothing at all if
+		// config.NextProtos is empty. See
+		// https://code.google.com/p/go/issues/detail?id=5445.
+		if hs.clientHello.nextProtoNeg && len(config.NextProtos) > 0 {
+			hs.hello.nextProtoNeg = true
+			hs.hello.nextProtos = config.NextProtos
+		}
+	}
+
+	if len(config.Certificates) == 0 {
+		c.sendAlert(alertInternalError)
+		return false, errors.New("tls: no certificates configured")
+	}
+	hs.cert = &config.Certificates[0]
+	if len(hs.clientHello.serverName) > 0 {
+		chi := &ClientHelloInfo{
+			CipherSuites:    hs.clientHello.cipherSuites,
+			ServerName:      hs.clientHello.serverName,
+			SupportedCurves: hs.clientHello.supportedCurves,
+			SupportedPoints: hs.clientHello.supportedPoints,
+		}
+		if hs.cert, err = config.getCertificate(chi); err != nil {
+			c.sendAlert(alertInternalError)
+			return false, err
+		}
+	}
+
+	_, hs.ecdsaOk = hs.cert.PrivateKey.(*ecdsa.PrivateKey)
+
+	if hs.checkForResumption() {
+		return true, nil
+	}
+
+	var preferenceList, supportedList []uint16
+	if c.config.PreferServerCipherSuites {
+		preferenceList = c.config.cipherSuites()
+		supportedList = hs.clientHello.cipherSuites
+	} else {
+		preferenceList = hs.clientHello.cipherSuites
+		supportedList = c.config.cipherSuites()
+	}
+
+	for _, id := range preferenceList {
+		if hs.suite = c.tryCipherSuite(id, supportedList, c.vers, hs.ellipticOk, hs.ecdsaOk); hs.suite != nil {
+			break
+		}
+	}
+
+	if hs.suite == nil {
+		c.sendAlert(alertHandshakeFailure)
+		return false, errors.New("tls: no cipher suite supported by both client and server")
+	}
+
+	// See https://tools.ietf.org/html/draft-ietf-tls-downgrade-scsv-00.
+	for _, id := range hs.clientHello.cipherSuites {
+		if id == TLS_FALLBACK_SCSV {
+			// The client is doing a fallback connection.
+			if hs.clientHello.vers < c.config.MaxVersion {
+				c.sendAlert(alertInappropriateFallback)
+				return false, errors.New("tls: client using inppropriate protocol fallback")
+			}
+			break
+		}
+	}
+
+	return false, nil
+}
+
+// checkForResumption returns true if we should perform resumption on this connection.
+func (hs *serverHandshakeState) checkForResumption() bool {
+	c := hs.c
+
+	if c.config.SessionTicketsDisabled {
+		return false
+	}
+
+	var ok bool
+	if hs.sessionState, ok = c.decryptTicket(hs.clientHello.sessionTicket); !ok {
+		return false
+	}
+
+	if hs.sessionState.vers > hs.clientHello.vers {
+		return false
+	}
+	if vers, ok := c.config.mutualVersion(hs.sessionState.vers); !ok || vers != hs.sessionState.vers {
+		return false
+	}
+
+	cipherSuiteOk := false
+	// Check that the client is still offering the ciphersuite in the session.
+	for _, id := range hs.clientHello.cipherSuites {
+		if id == hs.sessionState.cipherSuite {
+			cipherSuiteOk = true
+			break
+		}
+	}
+	if !cipherSuiteOk {
+		return false
+	}
+
+	// Check that we also support the ciphersuite from the session.
+	hs.suite = c.tryCipherSuite(hs.sessionState.cipherSuite, c.config.cipherSuites(), hs.sessionState.vers, hs.ellipticOk, hs.ecdsaOk)
+	if hs.suite == nil {
+		return false
+	}
+
+	sessionHasClientCerts := len(hs.sessionState.certificates) != 0
+	needClientCerts := c.config.ClientAuth == RequireAnyClientCert || c.config.ClientAuth == RequireAndVerifyClientCert
+	if needClientCerts && !sessionHasClientCerts {
+		return false
+	}
+	if sessionHasClientCerts && c.config.ClientAuth == NoClientCert {
+		return false
+	}
+
+	return true
+}
+
+func (hs *serverHandshakeState) doResumeHandshake() error {
+	c := hs.c
+
+	hs.hello.cipherSuite = hs.suite.id
+	// We echo the client's session ID in the ServerHello to let it know
+	// that we're doing a resumption.
+	hs.hello.sessionId = hs.clientHello.sessionId
+	hs.finishedHash.Write(hs.hello.marshal())
+	c.writeRecord(recordTypeHandshake, hs.hello.marshal())
+
+	if len(hs.sessionState.certificates) > 0 {
+		if _, err := hs.processCertsFromClient(hs.sessionState.certificates); err != nil {
+			return err
+		}
+	}
+
+	hs.masterSecret = hs.sessionState.masterSecret
+
+	return nil
+}
+
+func (hs *serverHandshakeState) doFullHandshake() error {
+	config := hs.c.config
+	c := hs.c
+
+	if hs.clientHello.ocspStapling && len(hs.cert.OCSPStaple) > 0 {
+		hs.hello.ocspStapling = true
+	}
+
+	hs.hello.ticketSupported = hs.clientHello.ticketSupported && !config.SessionTicketsDisabled
+	hs.hello.cipherSuite = hs.suite.id
+	hs.finishedHash.Write(hs.hello.marshal())
+	c.writeRecord(recordTypeHandshake, hs.hello.marshal())
+
+	certMsg := new(certificateMsg)
+	certMsg.certificates = hs.cert.Certificate
+	hs.finishedHash.Write(certMsg.marshal())
+	c.writeRecord(recordTypeHandshake, certMsg.marshal())
+
+	if hs.hello.ocspStapling {
+		certStatus := new(certificateStatusMsg)
+		certStatus.statusType = statusTypeOCSP
+		certStatus.response = hs.cert.OCSPStaple
+		hs.finishedHash.Write(certStatus.marshal())
+		c.writeRecord(recordTypeHandshake, certStatus.marshal())
+	}
+
+	keyAgreement := hs.suite.ka(c.vers)
+	skx, err := keyAgreement.generateServerKeyExchange(config, hs.cert, hs.clientHello, hs.hello)
+	if err != nil {
+		c.sendAlert(alertHandshakeFailure)
+		return err
+	}
+	if skx != nil {
+		hs.finishedHash.Write(skx.marshal())
+		c.writeRecord(recordTypeHandshake, skx.marshal())
+	}
+
+	if config.ClientAuth >= RequestClientCert {
+		// Request a client certificate
+		certReq := new(certificateRequestMsg)
+		certReq.certificateTypes = []byte{
+			byte(certTypeRSASign),
+			byte(certTypeECDSASign),
+		}
+		if c.vers >= VersionTLS12 {
+			certReq.hasSignatureAndHash = true
+			certReq.signatureAndHashes = supportedClientCertSignatureAlgorithms
+		}
+
+		// An empty list of certificateAuthorities signals to
+		// the client that it may send any certificate in response
+		// to our request. When we know the CAs we trust, then
+		// we can send them down, so that the client can choose
+		// an appropriate certificate to give to us.
+		if config.ClientCAs != nil {
+			certReq.certificateAuthorities = config.ClientCAs.Subjects()
+		}
+		hs.finishedHash.Write(certReq.marshal())
+		c.writeRecord(recordTypeHandshake, certReq.marshal())
+	}
+
+	helloDone := new(serverHelloDoneMsg)
+	hs.finishedHash.Write(helloDone.marshal())
+	c.writeRecord(recordTypeHandshake, helloDone.marshal())
+
+	var pub crypto.PublicKey // public key for client auth, if any
+
+	msg, err := c.readHandshake()
+	if err != nil {
+		return err
+	}
+
+	var ok bool
+	// If we requested a client certificate, then the client must send a
+	// certificate message, even if it's empty.
+	if config.ClientAuth >= RequestClientCert {
+		if certMsg, ok = msg.(*certificateMsg); !ok {
+			c.sendAlert(alertUnexpectedMessage)
+			return unexpectedMessageError(certMsg, msg)
+		}
+		hs.finishedHash.Write(certMsg.marshal())
+
+		if len(certMsg.certificates) == 0 {
+			// The client didn't actually send a certificate
+			switch config.ClientAuth {
+			case RequireAnyClientCert, RequireAndVerifyClientCert:
+				c.sendAlert(alertBadCertificate)
+				return errors.New("tls: client didn't provide a certificate")
+			}
+		}
+
+		pub, err = hs.processCertsFromClient(certMsg.certificates)
+		if err != nil {
+			return err
+		}
+
+		msg, err = c.readHandshake()
+		if err != nil {
+			return err
+		}
+	}
+
+	// Get client key exchange
+	ckx, ok := msg.(*clientKeyExchangeMsg)
+	if !ok {
+		c.sendAlert(alertUnexpectedMessage)
+		return unexpectedMessageError(ckx, msg)
+	}
+	hs.finishedHash.Write(ckx.marshal())
+
+	// If we received a client cert in response to our certificate request message,
+	// the client will send us a certificateVerifyMsg immediately after the
+	// clientKeyExchangeMsg.  This message is a digest of all preceding
+	// handshake-layer messages that is signed using the private key corresponding
+	// to the client's certificate. This allows us to verify that the client is in
+	// possession of the private key of the certificate.
+	if len(c.peerCertificates) > 0 {
+		msg, err = c.readHandshake()
+		if err != nil {
+			return err
+		}
+		certVerify, ok := msg.(*certificateVerifyMsg)
+		if !ok {
+			c.sendAlert(alertUnexpectedMessage)
+			return unexpectedMessageError(certVerify, msg)
+		}
+
+		switch key := pub.(type) {
+		case *ecdsa.PublicKey:
+			ecdsaSig := new(ecdsaSignature)
+			if _, err = asn1.Unmarshal(certVerify.signature, ecdsaSig); err != nil {
+				break
+			}
+			if ecdsaSig.R.Sign() <= 0 || ecdsaSig.S.Sign() <= 0 {
+				err = errors.New("ECDSA signature contained zero or negative values")
+				break
+			}
+			digest, _, _ := hs.finishedHash.hashForClientCertificate(signatureECDSA)
+			if !ecdsa.Verify(key, digest, ecdsaSig.R, ecdsaSig.S) {
+				err = errors.New("ECDSA verification failure")
+				break
+			}
+		case *rsa.PublicKey:
+			digest, hashFunc, _ := hs.finishedHash.hashForClientCertificate(signatureRSA)
+			err = rsa.VerifyPKCS1v15(key, hashFunc, digest, certVerify.signature)
+		}
+		if err != nil {
+			c.sendAlert(alertBadCertificate)
+			return errors.New("could not validate signature of connection nonces: " + err.Error())
+		}
+
+		hs.finishedHash.Write(certVerify.marshal())
+	}
+
+	preMasterSecret, err := keyAgreement.processClientKeyExchange(config, hs.cert, ckx, c.vers)
+	if err != nil {
+		c.sendAlert(alertHandshakeFailure)
+		return err
+	}
+	hs.masterSecret = masterFromPreMasterSecret(c.vers, preMasterSecret, hs.clientHello.random, hs.hello.random)
+
+	return nil
+}
+
+func (hs *serverHandshakeState) establishKeys() error {
+	c := hs.c
+
+	clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV :=
+		keysFromMasterSecret(c.vers, hs.masterSecret, hs.clientHello.random, hs.hello.random, hs.suite.macLen, hs.suite.keyLen, hs.suite.ivLen)
+
+	var clientCipher, serverCipher interface{}
+	var clientHash, serverHash macFunction
+
+	if hs.suite.aead == nil {
+		clientCipher = hs.suite.cipher(clientKey, clientIV, true /* for reading */)
+		clientHash = hs.suite.mac(c.vers, clientMAC)
+		serverCipher = hs.suite.cipher(serverKey, serverIV, false /* not for reading */)
+		serverHash = hs.suite.mac(c.vers, serverMAC)
+	} else {
+		clientCipher = hs.suite.aead(clientKey, clientIV)
+		serverCipher = hs.suite.aead(serverKey, serverIV)
+	}
+
+	c.in.prepareCipherSpec(c.vers, clientCipher, clientHash)
+	c.out.prepareCipherSpec(c.vers, serverCipher, serverHash)
+
+	return nil
+}
+
+func (hs *serverHandshakeState) readFinished(out []byte) error {
+	c := hs.c
+
+	c.readRecord(recordTypeChangeCipherSpec)
+	if err := c.in.error(); err != nil {
+		return err
+	}
+
+	if hs.hello.nextProtoNeg {
+		msg, err := c.readHandshake()
+		if err != nil {
+			return err
+		}
+		nextProto, ok := msg.(*nextProtoMsg)
+		if !ok {
+			c.sendAlert(alertUnexpectedMessage)
+			return unexpectedMessageError(nextProto, msg)
+		}
+		hs.finishedHash.Write(nextProto.marshal())
+		c.clientProtocol = nextProto.proto
+	}
+
+	msg, err := c.readHandshake()
+	if err != nil {
+		return err
+	}
+	clientFinished, ok := msg.(*finishedMsg)
+	if !ok {
+		c.sendAlert(alertUnexpectedMessage)
+		return unexpectedMessageError(clientFinished, msg)
+	}
+
+	verify := hs.finishedHash.clientSum(hs.masterSecret)
+	if len(verify) != len(clientFinished.verifyData) ||
+		subtle.ConstantTimeCompare(verify, clientFinished.verifyData) != 1 {
+		c.sendAlert(alertHandshakeFailure)
+		return errors.New("tls: client's Finished message is incorrect")
+	}
+
+	hs.finishedHash.Write(clientFinished.marshal())
+	copy(out, verify)
+	return nil
+}
+
+func (hs *serverHandshakeState) sendSessionTicket() error {
+	if !hs.hello.ticketSupported {
+		return nil
+	}
+
+	c := hs.c
+	m := new(newSessionTicketMsg)
+
+	var err error
+	state := sessionState{
+		vers:         c.vers,
+		cipherSuite:  hs.suite.id,
+		masterSecret: hs.masterSecret,
+		certificates: hs.certsFromClient,
+	}
+	m.ticket, err = c.encryptTicket(&state)
+	if err != nil {
+		return err
+	}
+
+	hs.finishedHash.Write(m.marshal())
+	c.writeRecord(recordTypeHandshake, m.marshal())
+
+	return nil
+}
+
+func (hs *serverHandshakeState) sendFinished(out []byte) error {
+	c := hs.c
+
+	c.writeRecord(recordTypeChangeCipherSpec, []byte{1})
+
+	finished := new(finishedMsg)
+	finished.verifyData = hs.finishedHash.serverSum(hs.masterSecret)
+	hs.finishedHash.Write(finished.marshal())
+	c.writeRecord(recordTypeHandshake, finished.marshal())
+
+	c.cipherSuite = hs.suite.id
+	copy(out, finished.verifyData)
+
+	return nil
+}
+
+// processCertsFromClient takes a chain of client certificates either from a
+// Certificates message or from a sessionState and verifies them. It returns
+// the public key of the leaf certificate.
+func (hs *serverHandshakeState) processCertsFromClient(certificates [][]byte) (crypto.PublicKey, error) {
+	c := hs.c
+
+	hs.certsFromClient = certificates
+	certs := make([]*x509.Certificate, len(certificates))
+	var err error
+	for i, asn1Data := range certificates {
+		if certs[i], err = x509.ParseCertificate(asn1Data); err != nil {
+			c.sendAlert(alertBadCertificate)
+			return nil, errors.New("tls: failed to parse client certificate: " + err.Error())
+		}
+	}
+
+	if c.config.ClientAuth >= VerifyClientCertIfGiven && len(certs) > 0 {
+		opts := x509.VerifyOptions{
+			Roots:         c.config.ClientCAs,
+			CurrentTime:   c.config.time(),
+			Intermediates: x509.NewCertPool(),
+			KeyUsages:     []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
+		}
+
+		for _, cert := range certs[1:] {
+			opts.Intermediates.AddCert(cert)
+		}
+
+		chains, err := certs[0].Verify(opts)
+		if err != nil {
+			c.sendAlert(alertBadCertificate)
+			return nil, errors.New("tls: failed to verify client's certificate: " + err.Error())
+		}
+
+		ok := false
+		for _, ku := range certs[0].ExtKeyUsage {
+			if ku == x509.ExtKeyUsageClientAuth {
+				ok = true
+				break
+			}
+		}
+		if !ok {
+			c.sendAlert(alertHandshakeFailure)
+			return nil, errors.New("tls: client's certificate's extended key usage doesn't permit it to be used for client authentication")
+		}
+
+		c.verifiedChains = chains
+	}
+
+	if len(certs) > 0 {
+		var pub crypto.PublicKey
+		switch key := certs[0].PublicKey.(type) {
+		case *ecdsa.PublicKey, *rsa.PublicKey:
+			pub = key
+		default:
+			c.sendAlert(alertUnsupportedCertificate)
+			return nil, fmt.Errorf("tls: client's certificate contains an unsupported public key of type %T", certs[0].PublicKey)
+		}
+		c.peerCertificates = certs
+		return pub, nil
+	}
+
+	return nil, nil
+}
+
+// tryCipherSuite returns a cipherSuite with the given id if that cipher suite
+// is acceptable to use.
+func (c *Conn) tryCipherSuite(id uint16, supportedCipherSuites []uint16, version uint16, ellipticOk, ecdsaOk bool) *cipherSuite {
+	for _, supported := range supportedCipherSuites {
+		if id == supported {
+			var candidate *cipherSuite
+
+			for _, s := range cipherSuites {
+				if s.id == id {
+					candidate = s
+					break
+				}
+			}
+			if candidate == nil {
+				continue
+			}
+			// Don't select a ciphersuite which we can't
+			// support for this client.
+			if (candidate.flags&suiteECDHE != 0) && !ellipticOk {
+				continue
+			}
+			if (candidate.flags&suiteECDSA != 0) != ecdsaOk {
+				continue
+			}
+			if version < VersionTLS12 && candidate.flags&suiteTLS12 != 0 {
+				continue
+			}
+			return candidate
+		}
+	}
+
+	return nil
+}
diff --git a/src/crypto/tls/handshake_server_test.go b/src/crypto/tls/handshake_server_test.go
new file mode 100644
index 0000000..0338af4
--- /dev/null
+++ b/src/crypto/tls/handshake_server_test.go
@@ -0,0 +1,868 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tls
+
+import (
+	"bytes"
+	"crypto/ecdsa"
+	"crypto/elliptic"
+	"crypto/rsa"
+	"encoding/hex"
+	"encoding/pem"
+	"errors"
+	"fmt"
+	"io"
+	"math/big"
+	"net"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"strings"
+	"testing"
+	"time"
+)
+
+// zeroSource is an io.Reader that returns an unlimited number of zero bytes.
+type zeroSource struct{}
+
+func (zeroSource) Read(b []byte) (n int, err error) {
+	for i := range b {
+		b[i] = 0
+	}
+
+	return len(b), nil
+}
+
+var testConfig *Config
+
+func init() {
+	testConfig = &Config{
+		Time:               func() time.Time { return time.Unix(0, 0) },
+		Rand:               zeroSource{},
+		Certificates:       make([]Certificate, 2),
+		InsecureSkipVerify: true,
+		MinVersion:         VersionSSL30,
+		MaxVersion:         VersionTLS12,
+	}
+	testConfig.Certificates[0].Certificate = [][]byte{testRSACertificate}
+	testConfig.Certificates[0].PrivateKey = testRSAPrivateKey
+	testConfig.Certificates[1].Certificate = [][]byte{testSNICertificate}
+	testConfig.Certificates[1].PrivateKey = testRSAPrivateKey
+	testConfig.BuildNameToCertificate()
+}
+
+func testClientHelloFailure(t *testing.T, m handshakeMessage, expectedSubStr string) {
+	// Create in-memory network connection,
+	// send message to server.  Should return
+	// expected error.
+	c, s := net.Pipe()
+	go func() {
+		cli := Client(c, testConfig)
+		if ch, ok := m.(*clientHelloMsg); ok {
+			cli.vers = ch.vers
+		}
+		cli.writeRecord(recordTypeHandshake, m.marshal())
+		c.Close()
+	}()
+	err := Server(s, testConfig).Handshake()
+	s.Close()
+	if err == nil || !strings.Contains(err.Error(), expectedSubStr) {
+		t.Errorf("Got error: %s; expected to match substring '%s'", err, expectedSubStr)
+	}
+}
+
+func TestSimpleError(t *testing.T) {
+	testClientHelloFailure(t, &serverHelloDoneMsg{}, "unexpected handshake message")
+}
+
+var badProtocolVersions = []uint16{0x0000, 0x0005, 0x0100, 0x0105, 0x0200, 0x0205}
+
+func TestRejectBadProtocolVersion(t *testing.T) {
+	for _, v := range badProtocolVersions {
+		testClientHelloFailure(t, &clientHelloMsg{vers: v}, "unsupported, maximum protocol version")
+	}
+}
+
+func TestNoSuiteOverlap(t *testing.T) {
+	clientHello := &clientHelloMsg{
+		vers:               0x0301,
+		cipherSuites:       []uint16{0xff00},
+		compressionMethods: []uint8{0},
+	}
+	testClientHelloFailure(t, clientHello, "no cipher suite supported by both client and server")
+}
+
+func TestNoCompressionOverlap(t *testing.T) {
+	clientHello := &clientHelloMsg{
+		vers:               0x0301,
+		cipherSuites:       []uint16{TLS_RSA_WITH_RC4_128_SHA},
+		compressionMethods: []uint8{0xff},
+	}
+	testClientHelloFailure(t, clientHello, "client does not support uncompressed connections")
+}
+
+func TestTLS12OnlyCipherSuites(t *testing.T) {
+	// Test that a Server doesn't select a TLS 1.2-only cipher suite when
+	// the client negotiates TLS 1.1.
+	var zeros [32]byte
+
+	clientHello := &clientHelloMsg{
+		vers:   VersionTLS11,
+		random: zeros[:],
+		cipherSuites: []uint16{
+			// The Server, by default, will use the client's
+			// preference order. So the GCM cipher suite
+			// will be selected unless it's excluded because
+			// of the version in this ClientHello.
+			TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+			TLS_RSA_WITH_RC4_128_SHA,
+		},
+		compressionMethods: []uint8{compressionNone},
+		supportedCurves:    []CurveID{CurveP256, CurveP384, CurveP521},
+		supportedPoints:    []uint8{pointFormatUncompressed},
+	}
+
+	c, s := net.Pipe()
+	var reply interface{}
+	var clientErr error
+	go func() {
+		cli := Client(c, testConfig)
+		cli.vers = clientHello.vers
+		cli.writeRecord(recordTypeHandshake, clientHello.marshal())
+		reply, clientErr = cli.readHandshake()
+		c.Close()
+	}()
+	config := *testConfig
+	config.CipherSuites = clientHello.cipherSuites
+	Server(s, &config).Handshake()
+	s.Close()
+	if clientErr != nil {
+		t.Fatal(clientErr)
+	}
+	serverHello, ok := reply.(*serverHelloMsg)
+	if !ok {
+		t.Fatalf("didn't get ServerHello message in reply. Got %v\n", reply)
+	}
+	if s := serverHello.cipherSuite; s != TLS_RSA_WITH_RC4_128_SHA {
+		t.Fatalf("bad cipher suite from server: %x", s)
+	}
+}
+
+func TestAlertForwarding(t *testing.T) {
+	c, s := net.Pipe()
+	go func() {
+		Client(c, testConfig).sendAlert(alertUnknownCA)
+		c.Close()
+	}()
+
+	err := Server(s, testConfig).Handshake()
+	s.Close()
+	if e, ok := err.(*net.OpError); !ok || e.Err != error(alertUnknownCA) {
+		t.Errorf("Got error: %s; expected: %s", err, error(alertUnknownCA))
+	}
+}
+
+func TestClose(t *testing.T) {
+	c, s := net.Pipe()
+	go c.Close()
+
+	err := Server(s, testConfig).Handshake()
+	s.Close()
+	if err != io.EOF {
+		t.Errorf("Got error: %s; expected: %s", err, io.EOF)
+	}
+}
+
+func testHandshake(clientConfig, serverConfig *Config) (state ConnectionState, err error) {
+	c, s := net.Pipe()
+	done := make(chan bool)
+	go func() {
+		cli := Client(c, clientConfig)
+		cli.Handshake()
+		c.Close()
+		done <- true
+	}()
+	server := Server(s, serverConfig)
+	err = server.Handshake()
+	if err == nil {
+		state = server.ConnectionState()
+	}
+	s.Close()
+	<-done
+	return
+}
+
+func TestVersion(t *testing.T) {
+	serverConfig := &Config{
+		Certificates: testConfig.Certificates,
+		MaxVersion:   VersionTLS11,
+	}
+	clientConfig := &Config{
+		InsecureSkipVerify: true,
+	}
+	state, err := testHandshake(clientConfig, serverConfig)
+	if err != nil {
+		t.Fatalf("handshake failed: %s", err)
+	}
+	if state.Version != VersionTLS11 {
+		t.Fatalf("Incorrect version %x, should be %x", state.Version, VersionTLS11)
+	}
+}
+
+func TestCipherSuitePreference(t *testing.T) {
+	serverConfig := &Config{
+		CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA},
+		Certificates: testConfig.Certificates,
+		MaxVersion:   VersionTLS11,
+	}
+	clientConfig := &Config{
+		CipherSuites:       []uint16{TLS_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_RC4_128_SHA},
+		InsecureSkipVerify: true,
+	}
+	state, err := testHandshake(clientConfig, serverConfig)
+	if err != nil {
+		t.Fatalf("handshake failed: %s", err)
+	}
+	if state.CipherSuite != TLS_RSA_WITH_AES_128_CBC_SHA {
+		// By default the server should use the client's preference.
+		t.Fatalf("Client's preference was not used, got %x", state.CipherSuite)
+	}
+
+	serverConfig.PreferServerCipherSuites = true
+	state, err = testHandshake(clientConfig, serverConfig)
+	if err != nil {
+		t.Fatalf("handshake failed: %s", err)
+	}
+	if state.CipherSuite != TLS_RSA_WITH_RC4_128_SHA {
+		t.Fatalf("Server's preference was not used, got %x", state.CipherSuite)
+	}
+}
+
+// Note: see comment in handshake_test.go for details of how the reference
+// tests work.
+
+// serverTest represents a test of the TLS server handshake against a reference
+// implementation.
+type serverTest struct {
+	// name is a freeform string identifying the test and the file in which
+	// the expected results will be stored.
+	name string
+	// command, if not empty, contains a series of arguments for the
+	// command to run for the reference server.
+	command []string
+	// expectedPeerCerts contains a list of PEM blocks of expected
+	// certificates from the client.
+	expectedPeerCerts []string
+	// config, if not nil, contains a custom Config to use for this test.
+	config *Config
+	// expectAlert, if true, indicates that a fatal alert should be returned
+	// when handshaking with the server.
+	expectAlert bool
+	// expectHandshakeErrorIncluding, when not empty, contains a string
+	// that must be a substring of the error resulting from the handshake.
+	expectHandshakeErrorIncluding string
+	// validate, if not nil, is a function that will be called with the
+	// ConnectionState of the resulting connection. It returns false if the
+	// ConnectionState is unacceptable.
+	validate func(ConnectionState) error
+}
+
+var defaultClientCommand = []string{"openssl", "s_client", "-no_ticket"}
+
+// connFromCommand starts opens a listening socket and starts the reference
+// client to connect to it. It returns a recordingConn that wraps the resulting
+// connection.
+func (test *serverTest) connFromCommand() (conn *recordingConn, child *exec.Cmd, err error) {
+	l, err := net.ListenTCP("tcp", &net.TCPAddr{
+		IP:   net.IPv4(127, 0, 0, 1),
+		Port: 0,
+	})
+	if err != nil {
+		return nil, nil, err
+	}
+	defer l.Close()
+
+	port := l.Addr().(*net.TCPAddr).Port
+
+	var command []string
+	command = append(command, test.command...)
+	if len(command) == 0 {
+		command = defaultClientCommand
+	}
+	command = append(command, "-connect")
+	command = append(command, fmt.Sprintf("127.0.0.1:%d", port))
+	cmd := exec.Command(command[0], command[1:]...)
+	cmd.Stdin = nil
+	var output bytes.Buffer
+	cmd.Stdout = &output
+	cmd.Stderr = &output
+	if err := cmd.Start(); err != nil {
+		return nil, nil, err
+	}
+
+	connChan := make(chan interface{})
+	go func() {
+		tcpConn, err := l.Accept()
+		if err != nil {
+			connChan <- err
+		}
+		connChan <- tcpConn
+	}()
+
+	var tcpConn net.Conn
+	select {
+	case connOrError := <-connChan:
+		if err, ok := connOrError.(error); ok {
+			return nil, nil, err
+		}
+		tcpConn = connOrError.(net.Conn)
+	case <-time.After(2 * time.Second):
+		output.WriteTo(os.Stdout)
+		return nil, nil, errors.New("timed out waiting for connection from child process")
+	}
+
+	record := &recordingConn{
+		Conn: tcpConn,
+	}
+
+	return record, cmd, nil
+}
+
+func (test *serverTest) dataPath() string {
+	return filepath.Join("testdata", "Server-"+test.name)
+}
+
+func (test *serverTest) loadData() (flows [][]byte, err error) {
+	in, err := os.Open(test.dataPath())
+	if err != nil {
+		return nil, err
+	}
+	defer in.Close()
+	return parseTestData(in)
+}
+
+func (test *serverTest) run(t *testing.T, write bool) {
+	var clientConn, serverConn net.Conn
+	var recordingConn *recordingConn
+	var childProcess *exec.Cmd
+
+	if write {
+		var err error
+		recordingConn, childProcess, err = test.connFromCommand()
+		if err != nil {
+			t.Fatalf("Failed to start subcommand: %s", err)
+		}
+		serverConn = recordingConn
+	} else {
+		clientConn, serverConn = net.Pipe()
+	}
+	config := test.config
+	if config == nil {
+		config = testConfig
+	}
+	server := Server(serverConn, config)
+	connStateChan := make(chan ConnectionState, 1)
+	go func() {
+		var err error
+		if _, err = server.Write([]byte("hello, world\n")); err != nil {
+			t.Logf("Error from Server.Write: %s", err)
+		}
+		if len(test.expectHandshakeErrorIncluding) > 0 {
+			if err == nil {
+				t.Errorf("Error expected, but no error returned")
+			} else if s := err.Error(); !strings.Contains(s, test.expectHandshakeErrorIncluding) {
+				t.Errorf("Error expected containing '%s' but got '%s'", test.expectHandshakeErrorIncluding, s)
+			}
+		}
+		server.Close()
+		serverConn.Close()
+		connStateChan <- server.ConnectionState()
+	}()
+
+	if !write {
+		flows, err := test.loadData()
+		if err != nil {
+			if !test.expectAlert {
+				t.Fatalf("%s: failed to load data from %s", test.name, test.dataPath())
+			}
+		}
+		for i, b := range flows {
+			if i%2 == 0 {
+				clientConn.Write(b)
+				continue
+			}
+			bb := make([]byte, len(b))
+			n, err := io.ReadFull(clientConn, bb)
+			if test.expectAlert {
+				if err == nil {
+					t.Fatal("Expected read failure but read succeeded")
+				}
+			} else {
+				if err != nil {
+					t.Fatalf("%s #%d: %s\nRead %d, wanted %d, got %x, wanted %x\n", test.name, i+1, err, n, len(bb), bb[:n], b)
+				}
+				if !bytes.Equal(b, bb) {
+					t.Fatalf("%s #%d: mismatch on read: got:%x want:%x", test.name, i+1, bb, b)
+				}
+			}
+		}
+		clientConn.Close()
+	}
+
+	connState := <-connStateChan
+	peerCerts := connState.PeerCertificates
+	if len(peerCerts) == len(test.expectedPeerCerts) {
+		for i, peerCert := range peerCerts {
+			block, _ := pem.Decode([]byte(test.expectedPeerCerts[i]))
+			if !bytes.Equal(block.Bytes, peerCert.Raw) {
+				t.Fatalf("%s: mismatch on peer cert %d", test.name, i+1)
+			}
+		}
+	} else {
+		t.Fatalf("%s: mismatch on peer list length: %d (wanted) != %d (got)", test.name, len(test.expectedPeerCerts), len(peerCerts))
+	}
+
+	if test.validate != nil {
+		if err := test.validate(connState); err != nil {
+			t.Fatalf("validate callback returned error: %s", err)
+		}
+	}
+
+	if write {
+		path := test.dataPath()
+		out, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
+		if err != nil {
+			t.Fatalf("Failed to create output file: %s", err)
+		}
+		defer out.Close()
+		recordingConn.Close()
+		if len(recordingConn.flows) < 3 {
+			childProcess.Stdout.(*bytes.Buffer).WriteTo(os.Stdout)
+			if len(test.expectHandshakeErrorIncluding) == 0 {
+				t.Fatalf("Handshake failed")
+			}
+		}
+		recordingConn.WriteTo(out)
+		fmt.Printf("Wrote %s\n", path)
+		childProcess.Wait()
+	}
+}
+
+func runServerTestForVersion(t *testing.T, template *serverTest, prefix, option string) {
+	test := *template
+	test.name = prefix + test.name
+	if len(test.command) == 0 {
+		test.command = defaultClientCommand
+	}
+	test.command = append([]string(nil), test.command...)
+	test.command = append(test.command, option)
+	test.run(t, *update)
+}
+
+func runServerTestSSLv3(t *testing.T, template *serverTest) {
+	runServerTestForVersion(t, template, "SSLv3-", "-ssl3")
+}
+
+func runServerTestTLS10(t *testing.T, template *serverTest) {
+	runServerTestForVersion(t, template, "TLSv10-", "-tls1")
+}
+
+func runServerTestTLS11(t *testing.T, template *serverTest) {
+	runServerTestForVersion(t, template, "TLSv11-", "-tls1_1")
+}
+
+func runServerTestTLS12(t *testing.T, template *serverTest) {
+	runServerTestForVersion(t, template, "TLSv12-", "-tls1_2")
+}
+
+func TestHandshakeServerRSARC4(t *testing.T) {
+	test := &serverTest{
+		name:    "RSA-RC4",
+		command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "RC4-SHA"},
+	}
+	runServerTestSSLv3(t, test)
+	runServerTestTLS10(t, test)
+	runServerTestTLS11(t, test)
+	runServerTestTLS12(t, test)
+}
+
+func TestHandshakeServerRSA3DES(t *testing.T) {
+	test := &serverTest{
+		name:    "RSA-3DES",
+		command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "DES-CBC3-SHA"},
+	}
+	runServerTestSSLv3(t, test)
+	runServerTestTLS10(t, test)
+	runServerTestTLS12(t, test)
+}
+
+func TestHandshakeServerRSAAES(t *testing.T) {
+	test := &serverTest{
+		name:    "RSA-AES",
+		command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "AES128-SHA"},
+	}
+	runServerTestSSLv3(t, test)
+	runServerTestTLS10(t, test)
+	runServerTestTLS12(t, test)
+}
+
+func TestHandshakeServerAESGCM(t *testing.T) {
+	test := &serverTest{
+		name:    "RSA-AES-GCM",
+		command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "ECDHE-RSA-AES128-GCM-SHA256"},
+	}
+	runServerTestTLS12(t, test)
+}
+
+func TestHandshakeServerECDHEECDSAAES(t *testing.T) {
+	config := *testConfig
+	config.Certificates = make([]Certificate, 1)
+	config.Certificates[0].Certificate = [][]byte{testECDSACertificate}
+	config.Certificates[0].PrivateKey = testECDSAPrivateKey
+	config.BuildNameToCertificate()
+
+	test := &serverTest{
+		name:    "ECDHE-ECDSA-AES",
+		command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "ECDHE-ECDSA-AES256-SHA"},
+		config:  &config,
+	}
+	runServerTestTLS10(t, test)
+	runServerTestTLS12(t, test)
+}
+
+func TestHandshakeServerALPN(t *testing.T) {
+	config := *testConfig
+	config.NextProtos = []string{"proto1", "proto2"}
+
+	test := &serverTest{
+		name: "ALPN",
+		// Note that this needs OpenSSL 1.0.2 because that is the first
+		// version that supports the -alpn flag.
+		command: []string{"openssl", "s_client", "-alpn", "proto2,proto1"},
+		config:  &config,
+		validate: func(state ConnectionState) error {
+			// The server's preferences should override the client.
+			if state.NegotiatedProtocol != "proto1" {
+				return fmt.Errorf("Got protocol %q, wanted proto1", state.NegotiatedProtocol)
+			}
+			return nil
+		},
+	}
+	runServerTestTLS12(t, test)
+}
+
+func TestHandshakeServerALPNNoMatch(t *testing.T) {
+	config := *testConfig
+	config.NextProtos = []string{"proto3"}
+
+	test := &serverTest{
+		name: "ALPN-NoMatch",
+		// Note that this needs OpenSSL 1.0.2 because that is the first
+		// version that supports the -alpn flag.
+		command: []string{"openssl", "s_client", "-alpn", "proto2,proto1"},
+		config:  &config,
+		validate: func(state ConnectionState) error {
+			// Rather than reject the connection, Go doesn't select
+			// a protocol when there is no overlap.
+			if state.NegotiatedProtocol != "" {
+				return fmt.Errorf("Got protocol %q, wanted ''", state.NegotiatedProtocol)
+			}
+			return nil
+		},
+	}
+	runServerTestTLS12(t, test)
+}
+
+// TestHandshakeServerSNI involves a client sending an SNI extension of
+// "snitest.com", which happens to match the CN of testSNICertificate. The test
+// verifies that the server correctly selects that certificate.
+func TestHandshakeServerSNI(t *testing.T) {
+	test := &serverTest{
+		name:    "SNI",
+		command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "AES128-SHA", "-servername", "snitest.com"},
+	}
+	runServerTestTLS12(t, test)
+}
+
+// TestHandshakeServerSNICertForName is similar to TestHandshakeServerSNI, but
+// tests the dynamic GetCertificate method
+func TestHandshakeServerSNIGetCertificate(t *testing.T) {
+	config := *testConfig
+
+	// Replace the NameToCertificate map with a GetCertificate function
+	nameToCert := config.NameToCertificate
+	config.NameToCertificate = nil
+	config.GetCertificate = func(clientHello *ClientHelloInfo) (*Certificate, error) {
+		cert, _ := nameToCert[clientHello.ServerName]
+		return cert, nil
+	}
+	test := &serverTest{
+		name:    "SNI",
+		command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "AES128-SHA", "-servername", "snitest.com"},
+		config:  &config,
+	}
+	runServerTestTLS12(t, test)
+}
+
+// TestHandshakeServerSNICertForNameNotFound is similar to
+// TestHandshakeServerSNICertForName, but tests to make sure that when the
+// GetCertificate method doesn't return a cert, we fall back to what's in
+// the NameToCertificate map.
+func TestHandshakeServerSNIGetCertificateNotFound(t *testing.T) {
+	config := *testConfig
+
+	config.GetCertificate = func(clientHello *ClientHelloInfo) (*Certificate, error) {
+		return nil, nil
+	}
+	test := &serverTest{
+		name:    "SNI",
+		command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "AES128-SHA", "-servername", "snitest.com"},
+		config:  &config,
+	}
+	runServerTestTLS12(t, test)
+}
+
+// TestHandshakeServerSNICertForNameError tests to make sure that errors in
+// GetCertificate result in a tls alert.
+func TestHandshakeServerSNIGetCertificateError(t *testing.T) {
+	config := *testConfig
+
+	config.GetCertificate = func(clientHello *ClientHelloInfo) (*Certificate, error) {
+		return nil, fmt.Errorf("Test error in GetCertificate")
+	}
+	test := &serverTest{
+		name:        "SNI",
+		command:     []string{"openssl", "s_client", "-no_ticket", "-cipher", "AES128-SHA", "-servername", "snitest.com"},
+		config:      &config,
+		expectAlert: true,
+	}
+	runServerTestTLS12(t, test)
+}
+
+// TestCipherSuiteCertPreferance ensures that we select an RSA ciphersuite with
+// an RSA certificate and an ECDSA ciphersuite with an ECDSA certificate.
+func TestCipherSuiteCertPreferenceECDSA(t *testing.T) {
+	config := *testConfig
+	config.CipherSuites = []uint16{TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA}
+	config.PreferServerCipherSuites = true
+
+	test := &serverTest{
+		name:   "CipherSuiteCertPreferenceRSA",
+		config: &config,
+	}
+	runServerTestTLS12(t, test)
+
+	config = *testConfig
+	config.CipherSuites = []uint16{TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA}
+	config.Certificates = []Certificate{
+		{
+			Certificate: [][]byte{testECDSACertificate},
+			PrivateKey:  testECDSAPrivateKey,
+		},
+	}
+	config.BuildNameToCertificate()
+	config.PreferServerCipherSuites = true
+
+	test = &serverTest{
+		name:   "CipherSuiteCertPreferenceECDSA",
+		config: &config,
+	}
+	runServerTestTLS12(t, test)
+}
+
+func TestResumption(t *testing.T) {
+	sessionFilePath := tempFile("")
+	defer os.Remove(sessionFilePath)
+
+	test := &serverTest{
+		name:    "IssueTicket",
+		command: []string{"openssl", "s_client", "-cipher", "RC4-SHA", "-sess_out", sessionFilePath},
+	}
+	runServerTestTLS12(t, test)
+
+	test = &serverTest{
+		name:    "Resume",
+		command: []string{"openssl", "s_client", "-cipher", "RC4-SHA", "-sess_in", sessionFilePath},
+	}
+	runServerTestTLS12(t, test)
+}
+
+func TestResumptionDisabled(t *testing.T) {
+	sessionFilePath := tempFile("")
+	defer os.Remove(sessionFilePath)
+
+	config := *testConfig
+
+	test := &serverTest{
+		name:    "IssueTicketPreDisable",
+		command: []string{"openssl", "s_client", "-cipher", "RC4-SHA", "-sess_out", sessionFilePath},
+		config:  &config,
+	}
+	runServerTestTLS12(t, test)
+
+	config.SessionTicketsDisabled = true
+
+	test = &serverTest{
+		name:    "ResumeDisabled",
+		command: []string{"openssl", "s_client", "-cipher", "RC4-SHA", "-sess_in", sessionFilePath},
+		config:  &config,
+	}
+	runServerTestTLS12(t, test)
+
+	// One needs to manually confirm that the handshake in the golden data
+	// file for ResumeDisabled does not include a resumption handshake.
+}
+
+func TestFallbackSCSV(t *testing.T) {
+	test := &serverTest{
+		name: "FallbackSCSV",
+		// OpenSSL 1.0.1j is needed for the -fallback_scsv option.
+		command: []string{"openssl", "s_client", "-fallback_scsv"},
+		expectHandshakeErrorIncluding: "inppropriate protocol fallback",
+	}
+	runServerTestTLS11(t, test)
+}
+
+// cert.pem and key.pem were generated with generate_cert.go
+// Thus, they have no ExtKeyUsage fields and trigger an error
+// when verification is turned on.
+
+const clientCertificatePEM = `
+-----BEGIN CERTIFICATE-----
+MIIB7TCCAVigAwIBAgIBADALBgkqhkiG9w0BAQUwJjEQMA4GA1UEChMHQWNtZSBD
+bzESMBAGA1UEAxMJMTI3LjAuMC4xMB4XDTExMTIwODA3NTUxMloXDTEyMTIwNzA4
+MDAxMlowJjEQMA4GA1UEChMHQWNtZSBDbzESMBAGA1UEAxMJMTI3LjAuMC4xMIGc
+MAsGCSqGSIb3DQEBAQOBjAAwgYgCgYBO0Hsx44Jk2VnAwoekXh6LczPHY1PfZpIG
+hPZk1Y/kNqcdK+izIDZFI7Xjla7t4PUgnI2V339aEu+H5Fto5OkOdOwEin/ekyfE
+ARl6vfLcPRSr0FTKIQzQTW6HLlzF0rtNS0/Otiz3fojsfNcCkXSmHgwa2uNKWi7e
+E5xMQIhZkwIDAQABozIwMDAOBgNVHQ8BAf8EBAMCAKAwDQYDVR0OBAYEBAECAwQw
+DwYDVR0jBAgwBoAEAQIDBDALBgkqhkiG9w0BAQUDgYEANh+zegx1yW43RmEr1b3A
+p0vMRpqBWHyFeSnIyMZn3TJWRSt1tukkqVCavh9a+hoV2cxVlXIWg7nCto/9iIw4
+hB2rXZIxE0/9gzvGnfERYraL7KtnvshksBFQRlgXa5kc0x38BvEO5ZaoDPl4ILdE
+GFGNEH5PlGffo05wc46QkYU=
+-----END CERTIFICATE-----`
+
+const clientKeyPEM = `
+-----BEGIN RSA PRIVATE KEY-----
+MIICWgIBAAKBgE7QezHjgmTZWcDCh6ReHotzM8djU99mkgaE9mTVj+Q2px0r6LMg
+NkUjteOVru3g9SCcjZXff1oS74fkW2jk6Q507ASKf96TJ8QBGXq98tw9FKvQVMoh
+DNBNbocuXMXSu01LT862LPd+iOx81wKRdKYeDBra40paLt4TnExAiFmTAgMBAAEC
+gYBxvXd8yNteFTns8A/2yomEMC4yeosJJSpp1CsN3BJ7g8/qTnrVPxBy+RU+qr63
+t2WquaOu/cr5P8iEsa6lk20tf8pjKLNXeX0b1RTzK8rJLbS7nGzP3tvOhL096VtQ
+dAo4ROEaro0TzYpHmpciSvxVIeEIAAdFDObDJPKqcJAxyQJBAJizfYgK8Gzx9fsx
+hxp+VteCbVPg2euASH5Yv3K5LukRdKoSzHE2grUVQgN/LafC0eZibRanxHegYSr7
+7qaswKUCQQCEIWor/X4XTMdVj3Oj+vpiw75y/S9gh682+myZL+d/02IEkwnB098P
+RkKVpenBHyrGg0oeN5La7URILWKj7CPXAkBKo6F+d+phNjwIFoN1Xb/RA32w/D1I
+saG9sF+UEhRt9AxUfW/U/tIQ9V0ZHHcSg1XaCM5Nvp934brdKdvTOKnJAkBD5h/3
+Rybatlvg/fzBEaJFyq09zhngkxlZOUtBVTqzl17RVvY2orgH02U4HbCHy4phxOn7
+qTdQRYlHRftgnWK1AkANibn9PRYJ7mJyJ9Dyj2QeNcSkSTzrt0tPvUMf4+meJymN
+1Ntu5+S1DLLzfxlaljWG6ylW6DNxujCyuXIV2rvA
+-----END RSA PRIVATE KEY-----`
+
+const clientECDSACertificatePEM = `
+-----BEGIN CERTIFICATE-----
+MIIB/DCCAV4CCQCaMIRsJjXZFzAJBgcqhkjOPQQBMEUxCzAJBgNVBAYTAkFVMRMw
+EQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0
+eSBMdGQwHhcNMTIxMTE0MTMyNTUzWhcNMjIxMTEyMTMyNTUzWjBBMQswCQYDVQQG
+EwJBVTEMMAoGA1UECBMDTlNXMRAwDgYDVQQHEwdQeXJtb250MRIwEAYDVQQDEwlK
+b2VsIFNpbmcwgZswEAYHKoZIzj0CAQYFK4EEACMDgYYABACVjJF1FMBexFe01MNv
+ja5oHt1vzobhfm6ySD6B5U7ixohLZNz1MLvT/2XMW/TdtWo+PtAd3kfDdq0Z9kUs
+jLzYHQFMH3CQRnZIi4+DzEpcj0B22uCJ7B0rxE4wdihBsmKo+1vx+U56jb0JuK7q
+ixgnTy5w/hOWusPTQBbNZU6sER7m8TAJBgcqhkjOPQQBA4GMADCBiAJCAOAUxGBg
+C3JosDJdYUoCdFzCgbkWqD8pyDbHgf9stlvZcPE4O1BIKJTLCRpS8V3ujfK58PDa
+2RU6+b0DeoeiIzXsAkIBo9SKeDUcSpoj0gq+KxAxnZxfvuiRs9oa9V2jI/Umi0Vw
+jWVim34BmT0Y9hCaOGGbLlfk+syxis7iI6CH8OFnUes=
+-----END CERTIFICATE-----`
+
+const clientECDSAKeyPEM = `
+-----BEGIN EC PARAMETERS-----
+BgUrgQQAIw==
+-----END EC PARAMETERS-----
+-----BEGIN EC PRIVATE KEY-----
+MIHcAgEBBEIBkJN9X4IqZIguiEVKMqeBUP5xtRsEv4HJEtOpOGLELwO53SD78Ew8
+k+wLWoqizS3NpQyMtrU8JFdWfj+C57UNkOugBwYFK4EEACOhgYkDgYYABACVjJF1
+FMBexFe01MNvja5oHt1vzobhfm6ySD6B5U7ixohLZNz1MLvT/2XMW/TdtWo+PtAd
+3kfDdq0Z9kUsjLzYHQFMH3CQRnZIi4+DzEpcj0B22uCJ7B0rxE4wdihBsmKo+1vx
++U56jb0JuK7qixgnTy5w/hOWusPTQBbNZU6sER7m8Q==
+-----END EC PRIVATE KEY-----`
+
+func TestClientAuth(t *testing.T) {
+	var certPath, keyPath, ecdsaCertPath, ecdsaKeyPath string
+
+	if *update {
+		certPath = tempFile(clientCertificatePEM)
+		defer os.Remove(certPath)
+		keyPath = tempFile(clientKeyPEM)
+		defer os.Remove(keyPath)
+		ecdsaCertPath = tempFile(clientECDSACertificatePEM)
+		defer os.Remove(ecdsaCertPath)
+		ecdsaKeyPath = tempFile(clientECDSAKeyPEM)
+		defer os.Remove(ecdsaKeyPath)
+	}
+
+	config := *testConfig
+	config.ClientAuth = RequestClientCert
+
+	test := &serverTest{
+		name:    "ClientAuthRequestedNotGiven",
+		command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "RC4-SHA"},
+		config:  &config,
+	}
+	runServerTestTLS12(t, test)
+
+	test = &serverTest{
+		name:              "ClientAuthRequestedAndGiven",
+		command:           []string{"openssl", "s_client", "-no_ticket", "-cipher", "RC4-SHA", "-cert", certPath, "-key", keyPath},
+		config:            &config,
+		expectedPeerCerts: []string{clientCertificatePEM},
+	}
+	runServerTestTLS12(t, test)
+
+	test = &serverTest{
+		name:              "ClientAuthRequestedAndECDSAGiven",
+		command:           []string{"openssl", "s_client", "-no_ticket", "-cipher", "RC4-SHA", "-cert", ecdsaCertPath, "-key", ecdsaKeyPath},
+		config:            &config,
+		expectedPeerCerts: []string{clientECDSACertificatePEM},
+	}
+	runServerTestTLS12(t, test)
+}
+
+func bigFromString(s string) *big.Int {
+	ret := new(big.Int)
+	ret.SetString(s, 10)
+	return ret
+}
+
+func fromHex(s string) []byte {
+	b, _ := hex.DecodeString(s)
+	return b
+}
+
+var testRSACertificate = fromHex("308202b030820219a00302010202090085b0bba48a7fb8ca300d06092a864886f70d01010505003045310b3009060355040613024155311330110603550408130a536f6d652d53746174653121301f060355040a1318496e7465726e6574205769646769747320507479204c7464301e170d3130303432343039303933385a170d3131303432343039303933385a3045310b3009060355040613024155311330110603550408130a536f6d652d53746174653121301f060355040a1318496e7465726e6574205769646769747320507479204c746430819f300d06092a864886f70d010101 [...]
+
+var testECDSACertificate = fromHex("3082020030820162020900b8bf2d47a0d2ebf4300906072a8648ce3d04013045310b3009060355040613024155311330110603550408130a536f6d652d53746174653121301f060355040a1318496e7465726e6574205769646769747320507479204c7464301e170d3132313132323135303633325a170d3232313132303135303633325a3045310b3009060355040613024155311330110603550408130a536f6d652d53746174653121301f060355040a1318496e7465726e6574205769646769747320507479204c746430819b301006072a8648ce3d020106052b81040023038186 [...]
+
+var testSNICertificate = fromHex("308201f23082015da003020102020100300b06092a864886f70d01010530283110300e060355040a130741636d6520436f311430120603550403130b736e69746573742e636f6d301e170d3132303431313137343033355a170d3133303431313137343533355a30283110300e060355040a130741636d6520436f311430120603550403130b736e69746573742e636f6d30819d300b06092a864886f70d01010103818d0030818902818100bb79d6f517b5e5bf4610d0dc69bee62b07435ad0032d8a7a4385b71452e7a5654c2c78b8238cb5b482e5de1f953b7e62a52ca533d6fe125c7a [...]
+
+var testRSAPrivateKey = &rsa.PrivateKey{
+	PublicKey: rsa.PublicKey{
+		N: bigFromString("131650079503776001033793877885499001334664249354723305978524647182322416328664556247316495448366990052837680518067798333412266673813370895702118944398081598789828837447552603077848001020611640547221687072142537202428102790818451901395596882588063427854225330436740647715202971973145151161964464812406232198521"),
+		E: 65537,
+	},
+	D: bigFromString("29354450337804273969007277378287027274721892607543397931919078829901848876371746653677097639302788129485893852488285045793268732234230875671682624082413996177431586734171663258657462237320300610850244186316880055243099640544518318093544057213190320837094958164973959123058337475052510833916491060913053867729"),
+	Primes: []*big.Int{
+		bigFromString("11969277782311800166562047708379380720136961987713178380670422671426759650127150688426177829077494755200794297055316163155755835813760102405344560929062149"),
+		bigFromString("10998999429884441391899182616418192492905073053684657075974935218461686523870125521822756579792315215543092255516093840728890783887287417039645833477273829"),
+	},
+}
+
+var testECDSAPrivateKey = &ecdsa.PrivateKey{
+	PublicKey: ecdsa.PublicKey{
+		Curve: elliptic.P521(),
+		X:     bigFromString("2636411247892461147287360222306590634450676461695221912739908880441342231985950069527906976759812296359387337367668045707086543273113073382714101597903639351"),
+		Y:     bigFromString("3204695818431246682253994090650952614555094516658732116404513121125038617915183037601737180082382202488628239201196033284060130040574800684774115478859677243"),
+	},
+	D: bigFromString("5477294338614160138026852784385529180817726002953041720191098180813046231640184669647735805135001309477695746518160084669446643325196003346204701381388769751"),
+}
diff --git a/src/pkg/crypto/tls/handshake_test.go b/src/crypto/tls/handshake_test.go
similarity index 100%
rename from src/pkg/crypto/tls/handshake_test.go
rename to src/crypto/tls/handshake_test.go
diff --git a/src/crypto/tls/key_agreement.go b/src/crypto/tls/key_agreement.go
new file mode 100644
index 0000000..0974fc6
--- /dev/null
+++ b/src/crypto/tls/key_agreement.go
@@ -0,0 +1,413 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tls
+
+import (
+	"crypto"
+	"crypto/ecdsa"
+	"crypto/elliptic"
+	"crypto/md5"
+	"crypto/rsa"
+	"crypto/sha1"
+	"crypto/sha256"
+	"crypto/x509"
+	"encoding/asn1"
+	"errors"
+	"io"
+	"math/big"
+)
+
+var errClientKeyExchange = errors.New("tls: invalid ClientKeyExchange message")
+var errServerKeyExchange = errors.New("tls: invalid ServerKeyExchange message")
+
+// rsaKeyAgreement implements the standard TLS key agreement where the client
+// encrypts the pre-master secret to the server's public key.
+type rsaKeyAgreement struct{}
+
+func (ka rsaKeyAgreement) generateServerKeyExchange(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) {
+	return nil, nil
+}
+
+func (ka rsaKeyAgreement) processClientKeyExchange(config *Config, cert *Certificate, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) {
+	preMasterSecret := make([]byte, 48)
+	_, err := io.ReadFull(config.rand(), preMasterSecret[2:])
+	if err != nil {
+		return nil, err
+	}
+
+	if len(ckx.ciphertext) < 2 {
+		return nil, errClientKeyExchange
+	}
+
+	ciphertext := ckx.ciphertext
+	if version != VersionSSL30 {
+		ciphertextLen := int(ckx.ciphertext[0])<<8 | int(ckx.ciphertext[1])
+		if ciphertextLen != len(ckx.ciphertext)-2 {
+			return nil, errClientKeyExchange
+		}
+		ciphertext = ckx.ciphertext[2:]
+	}
+
+	err = rsa.DecryptPKCS1v15SessionKey(config.rand(), cert.PrivateKey.(*rsa.PrivateKey), ciphertext, preMasterSecret)
+	if err != nil {
+		return nil, err
+	}
+	// We don't check the version number in the premaster secret.  For one,
+	// by checking it, we would leak information about the validity of the
+	// encrypted pre-master secret. Secondly, it provides only a small
+	// benefit against a downgrade attack and some implementations send the
+	// wrong version anyway. See the discussion at the end of section
+	// 7.4.7.1 of RFC 4346.
+	return preMasterSecret, nil
+}
+
+func (ka rsaKeyAgreement) processServerKeyExchange(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, cert *x509.Certificate, skx *serverKeyExchangeMsg) error {
+	return errors.New("tls: unexpected ServerKeyExchange")
+}
+
+func (ka rsaKeyAgreement) generateClientKeyExchange(config *Config, clientHello *clientHelloMsg, cert *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) {
+	preMasterSecret := make([]byte, 48)
+	preMasterSecret[0] = byte(clientHello.vers >> 8)
+	preMasterSecret[1] = byte(clientHello.vers)
+	_, err := io.ReadFull(config.rand(), preMasterSecret[2:])
+	if err != nil {
+		return nil, nil, err
+	}
+
+	encrypted, err := rsa.EncryptPKCS1v15(config.rand(), cert.PublicKey.(*rsa.PublicKey), preMasterSecret)
+	if err != nil {
+		return nil, nil, err
+	}
+	ckx := new(clientKeyExchangeMsg)
+	ckx.ciphertext = make([]byte, len(encrypted)+2)
+	ckx.ciphertext[0] = byte(len(encrypted) >> 8)
+	ckx.ciphertext[1] = byte(len(encrypted))
+	copy(ckx.ciphertext[2:], encrypted)
+	return preMasterSecret, ckx, nil
+}
+
+// sha1Hash calculates a SHA1 hash over the given byte slices.
+func sha1Hash(slices [][]byte) []byte {
+	hsha1 := sha1.New()
+	for _, slice := range slices {
+		hsha1.Write(slice)
+	}
+	return hsha1.Sum(nil)
+}
+
+// md5SHA1Hash implements TLS 1.0's hybrid hash function which consists of the
+// concatenation of an MD5 and SHA1 hash.
+func md5SHA1Hash(slices [][]byte) []byte {
+	md5sha1 := make([]byte, md5.Size+sha1.Size)
+	hmd5 := md5.New()
+	for _, slice := range slices {
+		hmd5.Write(slice)
+	}
+	copy(md5sha1, hmd5.Sum(nil))
+	copy(md5sha1[md5.Size:], sha1Hash(slices))
+	return md5sha1
+}
+
+// sha256Hash implements TLS 1.2's hash function.
+func sha256Hash(slices [][]byte) []byte {
+	h := sha256.New()
+	for _, slice := range slices {
+		h.Write(slice)
+	}
+	return h.Sum(nil)
+}
+
+// hashForServerKeyExchange hashes the given slices and returns their digest
+// and the identifier of the hash function used. The hashFunc argument is only
+// used for >= TLS 1.2 and precisely identifies the hash function to use.
+func hashForServerKeyExchange(sigType, hashFunc uint8, version uint16, slices ...[]byte) ([]byte, crypto.Hash, error) {
+	if version >= VersionTLS12 {
+		switch hashFunc {
+		case hashSHA256:
+			return sha256Hash(slices), crypto.SHA256, nil
+		case hashSHA1:
+			return sha1Hash(slices), crypto.SHA1, nil
+		default:
+			return nil, crypto.Hash(0), errors.New("tls: unknown hash function used by peer")
+		}
+	}
+	if sigType == signatureECDSA {
+		return sha1Hash(slices), crypto.SHA1, nil
+	}
+	return md5SHA1Hash(slices), crypto.MD5SHA1, nil
+}
+
+// pickTLS12HashForSignature returns a TLS 1.2 hash identifier for signing a
+// ServerKeyExchange given the signature type being used and the client's
+// advertised list of supported signature and hash combinations.
+func pickTLS12HashForSignature(sigType uint8, clientSignatureAndHashes []signatureAndHash) (uint8, error) {
+	if len(clientSignatureAndHashes) == 0 {
+		// If the client didn't specify any signature_algorithms
+		// extension then we can assume that it supports SHA1. See
+		// http://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
+		return hashSHA1, nil
+	}
+
+	for _, sigAndHash := range clientSignatureAndHashes {
+		if sigAndHash.signature != sigType {
+			continue
+		}
+		switch sigAndHash.hash {
+		case hashSHA1, hashSHA256:
+			return sigAndHash.hash, nil
+		}
+	}
+
+	return 0, errors.New("tls: client doesn't support any common hash functions")
+}
+
+func curveForCurveID(id CurveID) (elliptic.Curve, bool) {
+	switch id {
+	case CurveP256:
+		return elliptic.P256(), true
+	case CurveP384:
+		return elliptic.P384(), true
+	case CurveP521:
+		return elliptic.P521(), true
+	default:
+		return nil, false
+	}
+
+}
+
+// ecdheRSAKeyAgreement implements a TLS key agreement where the server
+// generates a ephemeral EC public/private key pair and signs it. The
+// pre-master secret is then calculated using ECDH. The signature may
+// either be ECDSA or RSA.
+type ecdheKeyAgreement struct {
+	version    uint16
+	sigType    uint8
+	privateKey []byte
+	curve      elliptic.Curve
+	x, y       *big.Int
+}
+
+func (ka *ecdheKeyAgreement) generateServerKeyExchange(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) {
+	var curveid CurveID
+	preferredCurves := config.curvePreferences()
+
+NextCandidate:
+	for _, candidate := range preferredCurves {
+		for _, c := range clientHello.supportedCurves {
+			if candidate == c {
+				curveid = c
+				break NextCandidate
+			}
+		}
+	}
+
+	if curveid == 0 {
+		return nil, errors.New("tls: no supported elliptic curves offered")
+	}
+
+	var ok bool
+	if ka.curve, ok = curveForCurveID(curveid); !ok {
+		return nil, errors.New("tls: preferredCurves includes unsupported curve")
+	}
+
+	var x, y *big.Int
+	var err error
+	ka.privateKey, x, y, err = elliptic.GenerateKey(ka.curve, config.rand())
+	if err != nil {
+		return nil, err
+	}
+	ecdhePublic := elliptic.Marshal(ka.curve, x, y)
+
+	// http://tools.ietf.org/html/rfc4492#section-5.4
+	serverECDHParams := make([]byte, 1+2+1+len(ecdhePublic))
+	serverECDHParams[0] = 3 // named curve
+	serverECDHParams[1] = byte(curveid >> 8)
+	serverECDHParams[2] = byte(curveid)
+	serverECDHParams[3] = byte(len(ecdhePublic))
+	copy(serverECDHParams[4:], ecdhePublic)
+
+	var tls12HashId uint8
+	if ka.version >= VersionTLS12 {
+		if tls12HashId, err = pickTLS12HashForSignature(ka.sigType, clientHello.signatureAndHashes); err != nil {
+			return nil, err
+		}
+	}
+
+	digest, hashFunc, err := hashForServerKeyExchange(ka.sigType, tls12HashId, ka.version, clientHello.random, hello.random, serverECDHParams)
+	if err != nil {
+		return nil, err
+	}
+	var sig []byte
+	switch ka.sigType {
+	case signatureECDSA:
+		privKey, ok := cert.PrivateKey.(*ecdsa.PrivateKey)
+		if !ok {
+			return nil, errors.New("ECDHE ECDSA requires an ECDSA server private key")
+		}
+		r, s, err := ecdsa.Sign(config.rand(), privKey, digest)
+		if err != nil {
+			return nil, errors.New("failed to sign ECDHE parameters: " + err.Error())
+		}
+		sig, err = asn1.Marshal(ecdsaSignature{r, s})
+	case signatureRSA:
+		privKey, ok := cert.PrivateKey.(*rsa.PrivateKey)
+		if !ok {
+			return nil, errors.New("ECDHE RSA requires a RSA server private key")
+		}
+		sig, err = rsa.SignPKCS1v15(config.rand(), privKey, hashFunc, digest)
+		if err != nil {
+			return nil, errors.New("failed to sign ECDHE parameters: " + err.Error())
+		}
+	default:
+		return nil, errors.New("unknown ECDHE signature algorithm")
+	}
+
+	skx := new(serverKeyExchangeMsg)
+	sigAndHashLen := 0
+	if ka.version >= VersionTLS12 {
+		sigAndHashLen = 2
+	}
+	skx.key = make([]byte, len(serverECDHParams)+sigAndHashLen+2+len(sig))
+	copy(skx.key, serverECDHParams)
+	k := skx.key[len(serverECDHParams):]
+	if ka.version >= VersionTLS12 {
+		k[0] = tls12HashId
+		k[1] = ka.sigType
+		k = k[2:]
+	}
+	k[0] = byte(len(sig) >> 8)
+	k[1] = byte(len(sig))
+	copy(k[2:], sig)
+
+	return skx, nil
+}
+
+func (ka *ecdheKeyAgreement) processClientKeyExchange(config *Config, cert *Certificate, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) {
+	if len(ckx.ciphertext) == 0 || int(ckx.ciphertext[0]) != len(ckx.ciphertext)-1 {
+		return nil, errClientKeyExchange
+	}
+	x, y := elliptic.Unmarshal(ka.curve, ckx.ciphertext[1:])
+	if x == nil {
+		return nil, errClientKeyExchange
+	}
+	if !ka.curve.IsOnCurve(x, y) {
+		return nil, errClientKeyExchange
+	}
+	x, _ = ka.curve.ScalarMult(x, y, ka.privateKey)
+	preMasterSecret := make([]byte, (ka.curve.Params().BitSize+7)>>3)
+	xBytes := x.Bytes()
+	copy(preMasterSecret[len(preMasterSecret)-len(xBytes):], xBytes)
+
+	return preMasterSecret, nil
+}
+
+func (ka *ecdheKeyAgreement) processServerKeyExchange(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, cert *x509.Certificate, skx *serverKeyExchangeMsg) error {
+	if len(skx.key) < 4 {
+		return errServerKeyExchange
+	}
+	if skx.key[0] != 3 { // named curve
+		return errors.New("tls: server selected unsupported curve")
+	}
+	curveid := CurveID(skx.key[1])<<8 | CurveID(skx.key[2])
+
+	var ok bool
+	if ka.curve, ok = curveForCurveID(curveid); !ok {
+		return errors.New("tls: server selected unsupported curve")
+	}
+
+	publicLen := int(skx.key[3])
+	if publicLen+4 > len(skx.key) {
+		return errServerKeyExchange
+	}
+	ka.x, ka.y = elliptic.Unmarshal(ka.curve, skx.key[4:4+publicLen])
+	if ka.x == nil {
+		return errServerKeyExchange
+	}
+	if !ka.curve.IsOnCurve(ka.x, ka.y) {
+		return errServerKeyExchange
+	}
+	serverECDHParams := skx.key[:4+publicLen]
+
+	sig := skx.key[4+publicLen:]
+	if len(sig) < 2 {
+		return errServerKeyExchange
+	}
+
+	var tls12HashId uint8
+	if ka.version >= VersionTLS12 {
+		// handle SignatureAndHashAlgorithm
+		var sigAndHash []uint8
+		sigAndHash, sig = sig[:2], sig[2:]
+		if sigAndHash[1] != ka.sigType {
+			return errServerKeyExchange
+		}
+		tls12HashId = sigAndHash[0]
+		if len(sig) < 2 {
+			return errServerKeyExchange
+		}
+	}
+	sigLen := int(sig[0])<<8 | int(sig[1])
+	if sigLen+2 != len(sig) {
+		return errServerKeyExchange
+	}
+	sig = sig[2:]
+
+	digest, hashFunc, err := hashForServerKeyExchange(ka.sigType, tls12HashId, ka.version, clientHello.random, serverHello.random, serverECDHParams)
+	if err != nil {
+		return err
+	}
+	switch ka.sigType {
+	case signatureECDSA:
+		pubKey, ok := cert.PublicKey.(*ecdsa.PublicKey)
+		if !ok {
+			return errors.New("ECDHE ECDSA requires a ECDSA server public key")
+		}
+		ecdsaSig := new(ecdsaSignature)
+		if _, err := asn1.Unmarshal(sig, ecdsaSig); err != nil {
+			return err
+		}
+		if ecdsaSig.R.Sign() <= 0 || ecdsaSig.S.Sign() <= 0 {
+			return errors.New("ECDSA signature contained zero or negative values")
+		}
+		if !ecdsa.Verify(pubKey, digest, ecdsaSig.R, ecdsaSig.S) {
+			return errors.New("ECDSA verification failure")
+		}
+	case signatureRSA:
+		pubKey, ok := cert.PublicKey.(*rsa.PublicKey)
+		if !ok {
+			return errors.New("ECDHE RSA requires a RSA server public key")
+		}
+		if err := rsa.VerifyPKCS1v15(pubKey, hashFunc, digest, sig); err != nil {
+			return err
+		}
+	default:
+		return errors.New("unknown ECDHE signature algorithm")
+	}
+
+	return nil
+}
+
+func (ka *ecdheKeyAgreement) generateClientKeyExchange(config *Config, clientHello *clientHelloMsg, cert *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) {
+	if ka.curve == nil {
+		return nil, nil, errors.New("missing ServerKeyExchange message")
+	}
+	priv, mx, my, err := elliptic.GenerateKey(ka.curve, config.rand())
+	if err != nil {
+		return nil, nil, err
+	}
+	x, _ := ka.curve.ScalarMult(ka.x, ka.y, priv)
+	preMasterSecret := make([]byte, (ka.curve.Params().BitSize+7)>>3)
+	xBytes := x.Bytes()
+	copy(preMasterSecret[len(preMasterSecret)-len(xBytes):], xBytes)
+
+	serialized := elliptic.Marshal(ka.curve, mx, my)
+
+	ckx := new(clientKeyExchangeMsg)
+	ckx.ciphertext = make([]byte, 1+len(serialized))
+	ckx.ciphertext[0] = byte(len(serialized))
+	copy(ckx.ciphertext[1:], serialized)
+
+	return preMasterSecret, ckx, nil
+}
diff --git a/src/pkg/crypto/tls/prf.go b/src/crypto/tls/prf.go
similarity index 100%
rename from src/pkg/crypto/tls/prf.go
rename to src/crypto/tls/prf.go
diff --git a/src/pkg/crypto/tls/prf_test.go b/src/crypto/tls/prf_test.go
similarity index 100%
rename from src/pkg/crypto/tls/prf_test.go
rename to src/crypto/tls/prf_test.go
diff --git a/src/pkg/crypto/tls/testdata/Client-TLSv10-ClientCert-ECDSA-ECDSA b/src/crypto/tls/testdata/Client-TLSv10-ClientCert-ECDSA-ECDSA
similarity index 100%
rename from src/pkg/crypto/tls/testdata/Client-TLSv10-ClientCert-ECDSA-ECDSA
rename to src/crypto/tls/testdata/Client-TLSv10-ClientCert-ECDSA-ECDSA
diff --git a/src/pkg/crypto/tls/testdata/Client-TLSv10-ClientCert-ECDSA-RSA b/src/crypto/tls/testdata/Client-TLSv10-ClientCert-ECDSA-RSA
similarity index 100%
rename from src/pkg/crypto/tls/testdata/Client-TLSv10-ClientCert-ECDSA-RSA
rename to src/crypto/tls/testdata/Client-TLSv10-ClientCert-ECDSA-RSA
diff --git a/src/pkg/crypto/tls/testdata/Client-TLSv10-ClientCert-RSA-ECDSA b/src/crypto/tls/testdata/Client-TLSv10-ClientCert-RSA-ECDSA
similarity index 100%
rename from src/pkg/crypto/tls/testdata/Client-TLSv10-ClientCert-RSA-ECDSA
rename to src/crypto/tls/testdata/Client-TLSv10-ClientCert-RSA-ECDSA
diff --git a/src/pkg/crypto/tls/testdata/Client-TLSv10-ClientCert-RSA-RSA b/src/crypto/tls/testdata/Client-TLSv10-ClientCert-RSA-RSA
similarity index 100%
rename from src/pkg/crypto/tls/testdata/Client-TLSv10-ClientCert-RSA-RSA
rename to src/crypto/tls/testdata/Client-TLSv10-ClientCert-RSA-RSA
diff --git a/src/pkg/crypto/tls/testdata/Client-TLSv10-ECDHE-ECDSA-AES b/src/crypto/tls/testdata/Client-TLSv10-ECDHE-ECDSA-AES
similarity index 100%
rename from src/pkg/crypto/tls/testdata/Client-TLSv10-ECDHE-ECDSA-AES
rename to src/crypto/tls/testdata/Client-TLSv10-ECDHE-ECDSA-AES
diff --git a/src/pkg/crypto/tls/testdata/Client-TLSv10-ECDHE-RSA-AES b/src/crypto/tls/testdata/Client-TLSv10-ECDHE-RSA-AES
similarity index 100%
rename from src/pkg/crypto/tls/testdata/Client-TLSv10-ECDHE-RSA-AES
rename to src/crypto/tls/testdata/Client-TLSv10-ECDHE-RSA-AES
diff --git a/src/pkg/crypto/tls/testdata/Client-TLSv10-RSA-RC4 b/src/crypto/tls/testdata/Client-TLSv10-RSA-RC4
similarity index 100%
rename from src/pkg/crypto/tls/testdata/Client-TLSv10-RSA-RC4
rename to src/crypto/tls/testdata/Client-TLSv10-RSA-RC4
diff --git a/src/pkg/crypto/tls/testdata/Client-TLSv11-ECDHE-ECDSA-AES b/src/crypto/tls/testdata/Client-TLSv11-ECDHE-ECDSA-AES
similarity index 100%
rename from src/pkg/crypto/tls/testdata/Client-TLSv11-ECDHE-ECDSA-AES
rename to src/crypto/tls/testdata/Client-TLSv11-ECDHE-ECDSA-AES
diff --git a/src/pkg/crypto/tls/testdata/Client-TLSv11-ECDHE-RSA-AES b/src/crypto/tls/testdata/Client-TLSv11-ECDHE-RSA-AES
similarity index 100%
rename from src/pkg/crypto/tls/testdata/Client-TLSv11-ECDHE-RSA-AES
rename to src/crypto/tls/testdata/Client-TLSv11-ECDHE-RSA-AES
diff --git a/src/pkg/crypto/tls/testdata/Client-TLSv11-RSA-RC4 b/src/crypto/tls/testdata/Client-TLSv11-RSA-RC4
similarity index 100%
rename from src/pkg/crypto/tls/testdata/Client-TLSv11-RSA-RC4
rename to src/crypto/tls/testdata/Client-TLSv11-RSA-RC4
diff --git a/src/crypto/tls/testdata/Client-TLSv12-ALPN b/src/crypto/tls/testdata/Client-TLSv12-ALPN
new file mode 100644
index 0000000..f09a4f1
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv12-ALPN
@@ -0,0 +1,97 @@
+>>> Flow 1 (client to server)
+00000000  16 03 01 00 8d 01 00 00  89 03 03 00 00 00 00 00  |................|
+00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
+00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 1a c0 2f  |.............../|
+00000030  c0 2b c0 11 c0 07 c0 13  c0 09 c0 14 c0 0a 00 05  |.+..............|
+00000040  00 2f 00 35 c0 12 00 0a  01 00 00 46 33 74 00 00  |./.5.......F3t..|
+00000050  00 05 00 05 01 00 00 00  00 00 0a 00 08 00 06 00  |................|
+00000060  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 0a 00  |................|
+00000070  08 04 01 04 03 02 01 02  03 ff 01 00 01 00 00 10  |................|
+00000080  00 10 00 0e 06 70 72 6f  74 6f 32 06 70 72 6f 74  |.....proto2.prot|
+00000090  6f 31                                             |o1|
+>>> Flow 2 (server to client)
+00000000  16 03 03 00 66 02 00 00  62 03 03 77 a9 7d 9c 4b  |....f...b..w.}.K|
+00000010  69 65 aa dc 95 cb 78 08  3d d2 1a 0a 45 69 23 73  |ie....x.=...Ei#s|
+00000020  4f 41 4f 24 12 2e 57 47  b7 53 64 20 82 9a f8 e7  |OAO$..WG.Sd ....|
+00000030  79 f8 13 2c 9d cd b5 cb  cb 9a 95 56 0e e9 cb a8  |y..,.......V....|
+00000040  e4 a2 8a d6 bc dc fa 25  b3 57 cc cf c0 2f 00 00  |.......%.W.../..|
+00000050  1a ff 01 00 01 00 00 0b  00 04 03 00 01 02 00 10  |................|
+00000060  00 09 00 07 06 70 72 6f  74 6f 31 16 03 03 02 be  |.....proto1.....|
+00000070  0b 00 02 ba 00 02 b7 00  02 b4 30 82 02 b0 30 82  |..........0...0.|
+00000080  02 19 a0 03 02 01 02 02  09 00 85 b0 bb a4 8a 7f  |................|
+00000090  b8 ca 30 0d 06 09 2a 86  48 86 f7 0d 01 01 05 05  |..0...*.H.......|
+000000a0  00 30 45 31 0b 30 09 06  03 55 04 06 13 02 41 55  |.0E1.0...U....AU|
+000000b0  31 13 30 11 06 03 55 04  08 13 0a 53 6f 6d 65 2d  |1.0...U....Some-|
+000000c0  53 74 61 74 65 31 21 30  1f 06 03 55 04 0a 13 18  |State1!0...U....|
+000000d0  49 6e 74 65 72 6e 65 74  20 57 69 64 67 69 74 73  |Internet Widgits|
+000000e0  20 50 74 79 20 4c 74 64  30 1e 17 0d 31 30 30 34  | Pty Ltd0...1004|
+000000f0  32 34 30 39 30 39 33 38  5a 17 0d 31 31 30 34 32  |24090938Z..11042|
+00000100  34 30 39 30 39 33 38 5a  30 45 31 0b 30 09 06 03  |4090938Z0E1.0...|
+00000110  55 04 06 13 02 41 55 31  13 30 11 06 03 55 04 08  |U....AU1.0...U..|
+00000120  13 0a 53 6f 6d 65 2d 53  74 61 74 65 31 21 30 1f  |..Some-State1!0.|
+00000130  06 03 55 04 0a 13 18 49  6e 74 65 72 6e 65 74 20  |..U....Internet |
+00000140  57 69 64 67 69 74 73 20  50 74 79 20 4c 74 64 30  |Widgits Pty Ltd0|
+00000150  81 9f 30 0d 06 09 2a 86  48 86 f7 0d 01 01 01 05  |..0...*.H.......|
+00000160  00 03 81 8d 00 30 81 89  02 81 81 00 bb 79 d6 f5  |.....0.......y..|
+00000170  17 b5 e5 bf 46 10 d0 dc  69 be e6 2b 07 43 5a d0  |....F...i..+.CZ.|
+00000180  03 2d 8a 7a 43 85 b7 14  52 e7 a5 65 4c 2c 78 b8  |.-.zC...R..eL,x.|
+00000190  23 8c b5 b4 82 e5 de 1f  95 3b 7e 62 a5 2c a5 33  |#........;~b.,.3|
+000001a0  d6 fe 12 5c 7a 56 fc f5  06 bf fa 58 7b 26 3f b5  |...\zV.....X{&?.|
+000001b0  cd 04 d3 d0 c9 21 96 4a  c7 f4 54 9f 5a bf ef 42  |.....!.J..T.Z..B|
+000001c0  71 00 fe 18 99 07 7f 7e  88 7d 7d f1 04 39 c4 a2  |q......~.}}..9..|
+000001d0  2e db 51 c9 7c e3 c0 4c  3b 32 66 01 cf af b1 1d  |..Q.|..L;2f.....|
+000001e0  b8 71 9a 1d db db 89 6b  ae da 2d 79 02 03 01 00  |.q.....k..-y....|
+000001f0  01 a3 81 a7 30 81 a4 30  1d 06 03 55 1d 0e 04 16  |....0..0...U....|
+00000200  04 14 b1 ad e2 85 5a cf  cb 28 db 69 ce 23 69 de  |......Z..(.i.#i.|
+00000210  d3 26 8e 18 88 39 30 75  06 03 55 1d 23 04 6e 30  |.&...90u..U.#.n0|
+00000220  6c 80 14 b1 ad e2 85 5a  cf cb 28 db 69 ce 23 69  |l......Z..(.i.#i|
+00000230  de d3 26 8e 18 88 39 a1  49 a4 47 30 45 31 0b 30  |..&...9.I.G0E1.0|
+00000240  09 06 03 55 04 06 13 02  41 55 31 13 30 11 06 03  |...U....AU1.0...|
+00000250  55 04 08 13 0a 53 6f 6d  65 2d 53 74 61 74 65 31  |U....Some-State1|
+00000260  21 30 1f 06 03 55 04 0a  13 18 49 6e 74 65 72 6e  |!0...U....Intern|
+00000270  65 74 20 57 69 64 67 69  74 73 20 50 74 79 20 4c  |et Widgits Pty L|
+00000280  74 64 82 09 00 85 b0 bb  a4 8a 7f b8 ca 30 0c 06  |td...........0..|
+00000290  03 55 1d 13 04 05 30 03  01 01 ff 30 0d 06 09 2a  |.U....0....0...*|
+000002a0  86 48 86 f7 0d 01 01 05  05 00 03 81 81 00 08 6c  |.H.............l|
+000002b0  45 24 c7 6b b1 59 ab 0c  52 cc f2 b0 14 d7 87 9d  |E$.k.Y..R.......|
+000002c0  7a 64 75 b5 5a 95 66 e4  c5 2b 8e ae 12 66 1f eb  |zdu.Z.f..+...f..|
+000002d0  4f 38 b3 6e 60 d3 92 fd  f7 41 08 b5 25 13 b1 18  |O8.n`....A..%...|
+000002e0  7a 24 fb 30 1d ba ed 98  b9 17 ec e7 d7 31 59 db  |z$.0.........1Y.|
+000002f0  95 d3 1d 78 ea 50 56 5c  d5 82 5a 2d 5a 5f 33 c4  |...x.PV\..Z-Z_3.|
+00000300  b6 d8 c9 75 90 96 8c 0f  52 98 b5 cd 98 1f 89 20  |...u....R...... |
+00000310  5f f2 a0 1c a3 1b 96 94  dd a9 fd 57 e9 70 e8 26  |_..........W.p.&|
+00000320  6d 71 99 9b 26 6e 38 50  29 6c 90 a7 bd d9 16 03  |mq..&n8P)l......|
+00000330  03 00 cd 0c 00 00 c9 03  00 17 41 04 1b 42 c3 ae  |..........A..B..|
+00000340  44 19 d3 84 7c 6c 98 cb  b9 22 a2 67 63 95 aa cc  |D...|l...".gc...|
+00000350  bd e4 1e f8 08 e6 60 f3  bc 83 9f 81 da 9c 1c 8c  |......`.........|
+00000360  ff 6f f4 3e 1e e5 3b f6  49 61 f9 70 43 7f c1 69  |.o.>..;.Ia.pC..i|
+00000370  de 73 98 4b bd 5c c3 78  24 18 a8 ec 04 01 00 80  |.s.K.\.x$.......|
+00000380  70 d2 5b e1 39 cf 4d 54  de d2 74 4e 5e a8 b3 ca  |p.[.9.MT..tN^...|
+00000390  e1 f2 4e 76 3c 77 8b ef  f7 d1 df b9 ad c1 70 39  |..Nv<w........p9|
+000003a0  c7 a3 1e 0f 7b 6c 78 2e  c1 86 d2 67 36 d8 25 e0  |....{lx....g6.%.|
+000003b0  e8 e5 cc 35 a2 96 a1 b4  b7 06 68 1e aa c7 06 97  |...5......h.....|
+000003c0  b7 c2 83 ce c0 17 dd 4f  9e 6f 7a bd cd c7 6e 7f  |.......O.oz...n.|
+000003d0  cb 80 d1 7d 06 2d f9 f1  fb 5f cc bb d8 62 5b f0  |...}.-..._...b[.|
+000003e0  27 12 57 d5 9b 55 aa 55  4b 9a 5a f6 a5 aa c1 82  |'.W..U.UK.Z.....|
+000003f0  39 11 6b dc 83 7f a8 47  28 5a 0f 3d 3f 0f c2 22  |9.k....G(Z.=?.."|
+00000400  16 03 03 00 04 0e 00 00  00                       |.........|
+>>> Flow 3 (client to server)
+00000000  16 03 03 00 46 10 00 00  42 41 04 1e 18 37 ef 0d  |....F...BA...7..|
+00000010  19 51 88 35 75 71 b5 e5  54 5b 12 2e 8f 09 67 fd  |.Q.5uq..T[....g.|
+00000020  a7 24 20 3e b2 56 1c ce  97 28 5e f8 2b 2d 4f 9e  |.$ >.V...(^.+-O.|
+00000030  f1 07 9f 6c 4b 5b 83 56  e2 32 42 e9 58 b6 d7 49  |...lK[.V.2B.X..I|
+00000040  a6 b5 68 1a 41 03 56 6b  dc 5a 89 14 03 03 00 01  |..h.A.Vk.Z......|
+00000050  01 16 03 03 00 28 00 00  00 00 00 00 00 00 35 9d  |.....(........5.|
+00000060  92 e8 bf df 7f a7 77 1b  cf 03 2a bf e2 6c 62 2b  |......w...*..lb+|
+00000070  26 f0 fb 93 d3 df fd 55  84 d3 ed 88 31 cb        |&......U....1.|
+>>> Flow 4 (server to client)
+00000000  14 03 03 00 01 01 16 03  03 00 28 c8 c0 78 09 73  |..........(..x.s|
+00000010  58 41 73 66 88 cf db f3  fe c6 57 ab 45 be 2e d8  |XAsf......W.E...|
+00000020  4e e5 ff 42 57 13 74 d2  cc c2 62 07 39 8b 06 46  |N..BW.t...b.9..F|
+00000030  1d 8f 88                                          |...|
+>>> Flow 5 (client to server)
+00000000  17 03 03 00 1e 00 00 00  00 00 00 00 01 10 c3 5f  |..............._|
+00000010  3f c8 92 6c 7a a7 23 05  f3 d8 31 20 01 52 f1 99  |?..lz.#...1 .R..|
+00000020  33 c1 2a 15 03 03 00 1a  00 00 00 00 00 00 00 02  |3.*.............|
+00000030  cc ef eb 78 e4 e1 9d 90  05 6d 95 ac f2 49 ba 8e  |...x.....m...I..|
+00000040  6b 8d                                             |k.|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-ALPN-NoMatch b/src/crypto/tls/testdata/Client-TLSv12-ALPN-NoMatch
new file mode 100644
index 0000000..f24a70c
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv12-ALPN-NoMatch
@@ -0,0 +1,95 @@
+>>> Flow 1 (client to server)
+00000000  16 03 01 00 86 01 00 00  82 03 03 00 00 00 00 00  |................|
+00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
+00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 1a c0 2f  |.............../|
+00000030  c0 2b c0 11 c0 07 c0 13  c0 09 c0 14 c0 0a 00 05  |.+..............|
+00000040  00 2f 00 35 c0 12 00 0a  01 00 00 3f 33 74 00 00  |./.5.......?3t..|
+00000050  00 05 00 05 01 00 00 00  00 00 0a 00 08 00 06 00  |................|
+00000060  17 00 18 00 19 00 0b 00  02 01 00 00 0d 00 0a 00  |................|
+00000070  08 04 01 04 03 02 01 02  03 ff 01 00 01 00 00 10  |................|
+00000080  00 09 00 07 06 70 72 6f  74 6f 33                 |.....proto3|
+>>> Flow 2 (server to client)
+00000000  16 03 03 00 59 02 00 00  55 03 03 69 84 d1 d3 44  |....Y...U..i...D|
+00000010  e9 66 08 48 bc 70 d8 ae  40 0b 17 69 e7 27 f6 7a  |.f.H.p.. at ..i.'.z|
+00000020  d5 ee 86 74 54 9e a8 bb  79 76 89 20 57 53 1b 02  |...tT...yv. WS..|
+00000030  5b 70 81 a6 f1 53 bc 9d  b7 42 5e ac 92 93 b5 20  |[p...S...B^.... |
+00000040  8a bb 36 cc 8f cb 7e a0  61 a2 e8 ef c0 2f 00 00  |..6...~.a..../..|
+00000050  0d ff 01 00 01 00 00 0b  00 04 03 00 01 02 16 03  |................|
+00000060  03 02 be 0b 00 02 ba 00  02 b7 00 02 b4 30 82 02  |.............0..|
+00000070  b0 30 82 02 19 a0 03 02  01 02 02 09 00 85 b0 bb  |.0..............|
+00000080  a4 8a 7f b8 ca 30 0d 06  09 2a 86 48 86 f7 0d 01  |.....0...*.H....|
+00000090  01 05 05 00 30 45 31 0b  30 09 06 03 55 04 06 13  |....0E1.0...U...|
+000000a0  02 41 55 31 13 30 11 06  03 55 04 08 13 0a 53 6f  |.AU1.0...U....So|
+000000b0  6d 65 2d 53 74 61 74 65  31 21 30 1f 06 03 55 04  |me-State1!0...U.|
+000000c0  0a 13 18 49 6e 74 65 72  6e 65 74 20 57 69 64 67  |...Internet Widg|
+000000d0  69 74 73 20 50 74 79 20  4c 74 64 30 1e 17 0d 31  |its Pty Ltd0...1|
+000000e0  30 30 34 32 34 30 39 30  39 33 38 5a 17 0d 31 31  |00424090938Z..11|
+000000f0  30 34 32 34 30 39 30 39  33 38 5a 30 45 31 0b 30  |0424090938Z0E1.0|
+00000100  09 06 03 55 04 06 13 02  41 55 31 13 30 11 06 03  |...U....AU1.0...|
+00000110  55 04 08 13 0a 53 6f 6d  65 2d 53 74 61 74 65 31  |U....Some-State1|
+00000120  21 30 1f 06 03 55 04 0a  13 18 49 6e 74 65 72 6e  |!0...U....Intern|
+00000130  65 74 20 57 69 64 67 69  74 73 20 50 74 79 20 4c  |et Widgits Pty L|
+00000140  74 64 30 81 9f 30 0d 06  09 2a 86 48 86 f7 0d 01  |td0..0...*.H....|
+00000150  01 01 05 00 03 81 8d 00  30 81 89 02 81 81 00 bb  |........0.......|
+00000160  79 d6 f5 17 b5 e5 bf 46  10 d0 dc 69 be e6 2b 07  |y......F...i..+.|
+00000170  43 5a d0 03 2d 8a 7a 43  85 b7 14 52 e7 a5 65 4c  |CZ..-.zC...R..eL|
+00000180  2c 78 b8 23 8c b5 b4 82  e5 de 1f 95 3b 7e 62 a5  |,x.#........;~b.|
+00000190  2c a5 33 d6 fe 12 5c 7a  56 fc f5 06 bf fa 58 7b  |,.3...\zV.....X{|
+000001a0  26 3f b5 cd 04 d3 d0 c9  21 96 4a c7 f4 54 9f 5a  |&?......!.J..T.Z|
+000001b0  bf ef 42 71 00 fe 18 99  07 7f 7e 88 7d 7d f1 04  |..Bq......~.}}..|
+000001c0  39 c4 a2 2e db 51 c9 7c  e3 c0 4c 3b 32 66 01 cf  |9....Q.|..L;2f..|
+000001d0  af b1 1d b8 71 9a 1d db  db 89 6b ae da 2d 79 02  |....q.....k..-y.|
+000001e0  03 01 00 01 a3 81 a7 30  81 a4 30 1d 06 03 55 1d  |.......0..0...U.|
+000001f0  0e 04 16 04 14 b1 ad e2  85 5a cf cb 28 db 69 ce  |.........Z..(.i.|
+00000200  23 69 de d3 26 8e 18 88  39 30 75 06 03 55 1d 23  |#i..&...90u..U.#|
+00000210  04 6e 30 6c 80 14 b1 ad  e2 85 5a cf cb 28 db 69  |.n0l......Z..(.i|
+00000220  ce 23 69 de d3 26 8e 18  88 39 a1 49 a4 47 30 45  |.#i..&...9.I.G0E|
+00000230  31 0b 30 09 06 03 55 04  06 13 02 41 55 31 13 30  |1.0...U....AU1.0|
+00000240  11 06 03 55 04 08 13 0a  53 6f 6d 65 2d 53 74 61  |...U....Some-Sta|
+00000250  74 65 31 21 30 1f 06 03  55 04 0a 13 18 49 6e 74  |te1!0...U....Int|
+00000260  65 72 6e 65 74 20 57 69  64 67 69 74 73 20 50 74  |ernet Widgits Pt|
+00000270  79 20 4c 74 64 82 09 00  85 b0 bb a4 8a 7f b8 ca  |y Ltd...........|
+00000280  30 0c 06 03 55 1d 13 04  05 30 03 01 01 ff 30 0d  |0...U....0....0.|
+00000290  06 09 2a 86 48 86 f7 0d  01 01 05 05 00 03 81 81  |..*.H...........|
+000002a0  00 08 6c 45 24 c7 6b b1  59 ab 0c 52 cc f2 b0 14  |..lE$.k.Y..R....|
+000002b0  d7 87 9d 7a 64 75 b5 5a  95 66 e4 c5 2b 8e ae 12  |...zdu.Z.f..+...|
+000002c0  66 1f eb 4f 38 b3 6e 60  d3 92 fd f7 41 08 b5 25  |f..O8.n`....A..%|
+000002d0  13 b1 18 7a 24 fb 30 1d  ba ed 98 b9 17 ec e7 d7  |...z$.0.........|
+000002e0  31 59 db 95 d3 1d 78 ea  50 56 5c d5 82 5a 2d 5a  |1Y....x.PV\..Z-Z|
+000002f0  5f 33 c4 b6 d8 c9 75 90  96 8c 0f 52 98 b5 cd 98  |_3....u....R....|
+00000300  1f 89 20 5f f2 a0 1c a3  1b 96 94 dd a9 fd 57 e9  |.. _..........W.|
+00000310  70 e8 26 6d 71 99 9b 26  6e 38 50 29 6c 90 a7 bd  |p.&mq..&n8P)l...|
+00000320  d9 16 03 03 00 cd 0c 00  00 c9 03 00 17 41 04 04  |.............A..|
+00000330  be 27 08 6f 12 83 1b 04  76 fa 5f 16 d6 e3 64 76  |.'.o....v._...dv|
+00000340  ad 0a 77 37 71 64 44 4c  3f 1a be dc 85 ce 46 c8  |..w7qdDL?.....F.|
+00000350  29 a1 e2 24 78 66 1f 35  90 05 46 c0 91 d1 fd dd  |)..$xf.5..F.....|
+00000360  b5 5b 87 d7 6d 9d 77 a7  f7 b3 df 68 27 fd 6d 04  |.[..m.w....h'.m.|
+00000370  01 00 80 7b 9b fd 0d 62  57 07 ef 97 f5 ff a9 00  |...{...bW.......|
+00000380  a0 89 35 5a 8a e6 e7 ae  7b 55 c5 dc 21 64 87 6e  |..5Z....{U..!d.n|
+00000390  0f ab 85 6d 82 e8 83 fd  7d 3b 49 a7 ae 92 5f 6d  |...m....};I..._m|
+000003a0  a3 42 ce ff ef a6 00 6a  33 32 1f 7b eb b7 c2 5c  |.B.....j32.{...\|
+000003b0  2d 38 cf 10 4b 59 69 4d  15 e0 68 49 39 ba cb 2a  |-8..KYiM..hI9..*|
+000003c0  d9 b9 f3 fe 33 01 4f 7e  ac 69 02 35 a5 e0 33 8d  |....3.O~.i.5..3.|
+000003d0  b3 74 34 14 45 9c 89 ad  41 2d d0 27 22 90 58 c6  |.t4.E...A-.'".X.|
+000003e0  e0 2c b4 6e 19 04 e4 46  26 ec 13 35 48 a6 3f 64  |.,.n...F&..5H.?d|
+000003f0  dc 85 2b 16 03 03 00 04  0e 00 00 00              |..+.........|
+>>> Flow 3 (client to server)
+00000000  16 03 03 00 46 10 00 00  42 41 04 1e 18 37 ef 0d  |....F...BA...7..|
+00000010  19 51 88 35 75 71 b5 e5  54 5b 12 2e 8f 09 67 fd  |.Q.5uq..T[....g.|
+00000020  a7 24 20 3e b2 56 1c ce  97 28 5e f8 2b 2d 4f 9e  |.$ >.V...(^.+-O.|
+00000030  f1 07 9f 6c 4b 5b 83 56  e2 32 42 e9 58 b6 d7 49  |...lK[.V.2B.X..I|
+00000040  a6 b5 68 1a 41 03 56 6b  dc 5a 89 14 03 03 00 01  |..h.A.Vk.Z......|
+00000050  01 16 03 03 00 28 00 00  00 00 00 00 00 00 88 0d  |.....(..........|
+00000060  04 8b 8e 93 55 58 d6 75  ca 16 26 42 a3 60 20 67  |....UX.u..&B.` g|
+00000070  84 cf d7 b3 10 fe 63 6c  2f 40 64 0c d6 78        |......cl/@d..x|
+>>> Flow 4 (server to client)
+00000000  14 03 03 00 01 01 16 03  03 00 28 bd 6c 2f 70 b9  |..........(.l/p.|
+00000010  2f 9c 29 70 af 34 49 4c  5b 25 c3 14 b6 6d 28 81  |/.)p.4IL[%...m(.|
+00000020  ff 54 d9 71 8d 2c c7 38  dd 44 27 6b 54 1e 53 7b  |.T.q.,.8.D'kT.S{|
+00000030  22 cb 65                                          |".e|
+>>> Flow 5 (client to server)
+00000000  17 03 03 00 1e 00 00 00  00 00 00 00 01 7f 0d d7  |................|
+00000010  d9 4b 87 7b 36 fb 24 92  69 22 43 50 1e 46 fb c4  |.K.{6.$.i"CP.F..|
+00000020  86 64 6f 15 03 03 00 1a  00 00 00 00 00 00 00 02  |.do.............|
+00000030  37 d5 2d 0a be c5 a8 ae  d4 bd 2b 09 34 18 a0 87  |7.-.......+.4...|
+00000040  08 a6                                             |..|
diff --git a/src/pkg/crypto/tls/testdata/Client-TLSv12-ClientCert-ECDSA-ECDSA b/src/crypto/tls/testdata/Client-TLSv12-ClientCert-ECDSA-ECDSA
similarity index 100%
rename from src/pkg/crypto/tls/testdata/Client-TLSv12-ClientCert-ECDSA-ECDSA
rename to src/crypto/tls/testdata/Client-TLSv12-ClientCert-ECDSA-ECDSA
diff --git a/src/pkg/crypto/tls/testdata/Client-TLSv12-ClientCert-ECDSA-RSA b/src/crypto/tls/testdata/Client-TLSv12-ClientCert-ECDSA-RSA
similarity index 100%
rename from src/pkg/crypto/tls/testdata/Client-TLSv12-ClientCert-ECDSA-RSA
rename to src/crypto/tls/testdata/Client-TLSv12-ClientCert-ECDSA-RSA
diff --git a/src/pkg/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-ECDSA b/src/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-ECDSA
similarity index 100%
rename from src/pkg/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-ECDSA
rename to src/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-ECDSA
diff --git a/src/pkg/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-RSA b/src/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-RSA
similarity index 100%
rename from src/pkg/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-RSA
rename to src/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-RSA
diff --git a/src/pkg/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-AES b/src/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-AES
similarity index 100%
rename from src/pkg/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-AES
rename to src/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-AES
diff --git a/src/pkg/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-AES-GCM b/src/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-AES-GCM
similarity index 100%
rename from src/pkg/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-AES-GCM
rename to src/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-AES-GCM
diff --git a/src/pkg/crypto/tls/testdata/Client-TLSv12-ECDHE-RSA-AES b/src/crypto/tls/testdata/Client-TLSv12-ECDHE-RSA-AES
similarity index 100%
rename from src/pkg/crypto/tls/testdata/Client-TLSv12-ECDHE-RSA-AES
rename to src/crypto/tls/testdata/Client-TLSv12-ECDHE-RSA-AES
diff --git a/src/pkg/crypto/tls/testdata/Client-TLSv12-RSA-RC4 b/src/crypto/tls/testdata/Client-TLSv12-RSA-RC4
similarity index 100%
rename from src/pkg/crypto/tls/testdata/Client-TLSv12-RSA-RC4
rename to src/crypto/tls/testdata/Client-TLSv12-RSA-RC4
diff --git a/src/pkg/crypto/tls/testdata/Server-SSLv3-RSA-3DES b/src/crypto/tls/testdata/Server-SSLv3-RSA-3DES
similarity index 100%
rename from src/pkg/crypto/tls/testdata/Server-SSLv3-RSA-3DES
rename to src/crypto/tls/testdata/Server-SSLv3-RSA-3DES
diff --git a/src/pkg/crypto/tls/testdata/Server-SSLv3-RSA-AES b/src/crypto/tls/testdata/Server-SSLv3-RSA-AES
similarity index 100%
rename from src/pkg/crypto/tls/testdata/Server-SSLv3-RSA-AES
rename to src/crypto/tls/testdata/Server-SSLv3-RSA-AES
diff --git a/src/pkg/crypto/tls/testdata/Server-SSLv3-RSA-RC4 b/src/crypto/tls/testdata/Server-SSLv3-RSA-RC4
similarity index 100%
rename from src/pkg/crypto/tls/testdata/Server-SSLv3-RSA-RC4
rename to src/crypto/tls/testdata/Server-SSLv3-RSA-RC4
diff --git a/src/pkg/crypto/tls/testdata/Server-TLSv10-ECDHE-ECDSA-AES b/src/crypto/tls/testdata/Server-TLSv10-ECDHE-ECDSA-AES
similarity index 100%
rename from src/pkg/crypto/tls/testdata/Server-TLSv10-ECDHE-ECDSA-AES
rename to src/crypto/tls/testdata/Server-TLSv10-ECDHE-ECDSA-AES
diff --git a/src/pkg/crypto/tls/testdata/Server-TLSv10-RSA-3DES b/src/crypto/tls/testdata/Server-TLSv10-RSA-3DES
similarity index 100%
rename from src/pkg/crypto/tls/testdata/Server-TLSv10-RSA-3DES
rename to src/crypto/tls/testdata/Server-TLSv10-RSA-3DES
diff --git a/src/pkg/crypto/tls/testdata/Server-TLSv10-RSA-AES b/src/crypto/tls/testdata/Server-TLSv10-RSA-AES
similarity index 100%
rename from src/pkg/crypto/tls/testdata/Server-TLSv10-RSA-AES
rename to src/crypto/tls/testdata/Server-TLSv10-RSA-AES
diff --git a/src/pkg/crypto/tls/testdata/Server-TLSv10-RSA-RC4 b/src/crypto/tls/testdata/Server-TLSv10-RSA-RC4
similarity index 100%
rename from src/pkg/crypto/tls/testdata/Server-TLSv10-RSA-RC4
rename to src/crypto/tls/testdata/Server-TLSv10-RSA-RC4
diff --git a/src/crypto/tls/testdata/Server-TLSv11-FallbackSCSV b/src/crypto/tls/testdata/Server-TLSv11-FallbackSCSV
new file mode 100644
index 0000000..2d8dfbc
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv11-FallbackSCSV
@@ -0,0 +1,17 @@
+>>> Flow 1 (client to server)
+00000000  16 03 01 00 d4 01 00 00  d0 03 02 74 2d da 6d 98  |...........t-.m.|
+00000010  ad 3e a5 ec 90 ea d1 5b  f0 e0 a7 45 33 d9 5e 8d  |.>.....[...E3.^.|
+00000020  0f 1d 01 16 6d 00 31 65  ed 50 88 00 00 5e c0 14  |....m.1e.P...^..|
+00000030  c0 0a 00 39 00 38 00 88  00 87 c0 0f c0 05 00 35  |...9.8.........5|
+00000040  00 84 c0 13 c0 09 00 33  00 32 00 9a 00 99 00 45  |.......3.2.....E|
+00000050  00 44 c0 0e c0 04 00 2f  00 96 00 41 00 07 c0 11  |.D...../...A....|
+00000060  c0 07 c0 0c c0 02 00 05  00 04 c0 12 c0 08 00 16  |................|
+00000070  00 13 c0 0d c0 03 00 0a  00 15 00 12 00 09 00 14  |................|
+00000080  00 11 00 08 00 06 00 03  00 ff 56 00 01 00 00 49  |..........V....I|
+00000090  00 0b 00 04 03 00 01 02  00 0a 00 34 00 32 00 0e  |...........4.2..|
+000000a0  00 0d 00 19 00 0b 00 0c  00 18 00 09 00 0a 00 16  |................|
+000000b0  00 17 00 08 00 06 00 07  00 14 00 15 00 04 00 05  |................|
+000000c0  00 12 00 13 00 01 00 02  00 03 00 0f 00 10 00 11  |................|
+000000d0  00 23 00 00 00 0f 00 01  01                       |.#.......|
+>>> Flow 2 (server to client)
+00000000  15 03 02 00 02 02 56                              |......V|
diff --git a/src/pkg/crypto/tls/testdata/Server-TLSv11-RSA-RC4 b/src/crypto/tls/testdata/Server-TLSv11-RSA-RC4
similarity index 100%
rename from src/pkg/crypto/tls/testdata/Server-TLSv11-RSA-RC4
rename to src/crypto/tls/testdata/Server-TLSv11-RSA-RC4
diff --git a/src/crypto/tls/testdata/Server-TLSv12-ALPN b/src/crypto/tls/testdata/Server-TLSv12-ALPN
new file mode 100644
index 0000000..106244d
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv12-ALPN
@@ -0,0 +1,122 @@
+>>> Flow 1 (client to server)
+00000000  16 03 01 01 8a 01 00 01  86 03 03 34 54 69 f3 d7  |...........4Ti..|
+00000010  20 9d 1d 74 db 72 e9 2f  51 7c c2 82 0a 9b cb 6d  | ..t.r./Q|.....m|
+00000020  90 b4 8e a2 1f 2f c7 66  74 8f 33 00 00 d6 c0 30  |...../.ft.3....0|
+00000030  c0 2c c0 28 c0 24 c0 14  c0 0a c0 22 c0 21 c0 20  |.,.(.$.....".!. |
+00000040  00 a5 00 a3 00 a1 00 9f  00 6b 00 6a 00 69 00 68  |.........k.j.i.h|
+00000050  00 39 00 38 00 37 00 36  00 88 00 87 00 86 00 85  |.9.8.7.6........|
+00000060  c0 32 c0 2e c0 2a c0 26  c0 0f c0 05 00 9d 00 3d  |.2...*.&.......=|
+00000070  00 35 00 84 c0 2f c0 2b  c0 27 c0 23 c0 13 c0 09  |.5.../.+.'.#....|
+00000080  c0 1f c0 1e c0 1d 00 a4  00 a2 00 a0 00 9e 00 67  |...............g|
+00000090  00 40 00 3f 00 3e 00 33  00 32 00 31 00 30 00 9a  |. at .?.>.3.2.1.0..|
+000000a0  00 99 00 98 00 97 00 45  00 44 00 43 00 42 c0 31  |.......E.D.C.B.1|
+000000b0  c0 2d c0 29 c0 25 c0 0e  c0 04 00 9c 00 3c 00 2f  |.-.).%.......<./|
+000000c0  00 96 00 41 00 07 c0 11  c0 07 c0 0c c0 02 00 05  |...A............|
+000000d0  00 04 c0 12 c0 08 c0 1c  c0 1b c0 1a 00 16 00 13  |................|
+000000e0  00 10 00 0d c0 0d c0 03  00 0a 00 15 00 12 00 0f  |................|
+000000f0  00 0c 00 09 00 14 00 11  00 0e 00 0b 00 08 00 06  |................|
+00000100  00 03 00 ff 01 00 00 87  00 0b 00 04 03 00 01 02  |................|
+00000110  00 0a 00 3a 00 38 00 0e  00 0d 00 19 00 1c 00 0b  |...:.8..........|
+00000120  00 0c 00 1b 00 18 00 09  00 0a 00 1a 00 16 00 17  |................|
+00000130  00 08 00 06 00 07 00 14  00 15 00 04 00 05 00 12  |................|
+00000140  00 13 00 01 00 02 00 03  00 0f 00 10 00 11 00 23  |...............#|
+00000150  00 00 00 0d 00 20 00 1e  06 01 06 02 06 03 05 01  |..... ..........|
+00000160  05 02 05 03 04 01 04 02  04 03 03 01 03 02 03 03  |................|
+00000170  02 01 02 02 02 03 00 0f  00 01 01 00 10 00 10 00  |................|
+00000180  0e 06 70 72 6f 74 6f 32  06 70 72 6f 74 6f 31     |..proto2.proto1|
+>>> Flow 2 (server to client)
+00000000  16 03 03 00 42 02 00 00  3e 03 03 00 00 00 00 00  |....B...>.......|
+00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
+00000020  00 00 00 00 00 00 00 00  00 00 00 00 c0 14 00 00  |................|
+00000030  16 00 23 00 00 ff 01 00  01 00 00 10 00 09 00 07  |..#.............|
+00000040  06 70 72 6f 74 6f 31 16  03 03 02 be 0b 00 02 ba  |.proto1.........|
+00000050  00 02 b7 00 02 b4 30 82  02 b0 30 82 02 19 a0 03  |......0...0.....|
+00000060  02 01 02 02 09 00 85 b0  bb a4 8a 7f b8 ca 30 0d  |..............0.|
+00000070  06 09 2a 86 48 86 f7 0d  01 01 05 05 00 30 45 31  |..*.H........0E1|
+00000080  0b 30 09 06 03 55 04 06  13 02 41 55 31 13 30 11  |.0...U....AU1.0.|
+00000090  06 03 55 04 08 13 0a 53  6f 6d 65 2d 53 74 61 74  |..U....Some-Stat|
+000000a0  65 31 21 30 1f 06 03 55  04 0a 13 18 49 6e 74 65  |e1!0...U....Inte|
+000000b0  72 6e 65 74 20 57 69 64  67 69 74 73 20 50 74 79  |rnet Widgits Pty|
+000000c0  20 4c 74 64 30 1e 17 0d  31 30 30 34 32 34 30 39  | Ltd0...10042409|
+000000d0  30 39 33 38 5a 17 0d 31  31 30 34 32 34 30 39 30  |0938Z..110424090|
+000000e0  39 33 38 5a 30 45 31 0b  30 09 06 03 55 04 06 13  |938Z0E1.0...U...|
+000000f0  02 41 55 31 13 30 11 06  03 55 04 08 13 0a 53 6f  |.AU1.0...U....So|
+00000100  6d 65 2d 53 74 61 74 65  31 21 30 1f 06 03 55 04  |me-State1!0...U.|
+00000110  0a 13 18 49 6e 74 65 72  6e 65 74 20 57 69 64 67  |...Internet Widg|
+00000120  69 74 73 20 50 74 79 20  4c 74 64 30 81 9f 30 0d  |its Pty Ltd0..0.|
+00000130  06 09 2a 86 48 86 f7 0d  01 01 01 05 00 03 81 8d  |..*.H...........|
+00000140  00 30 81 89 02 81 81 00  bb 79 d6 f5 17 b5 e5 bf  |.0.......y......|
+00000150  46 10 d0 dc 69 be e6 2b  07 43 5a d0 03 2d 8a 7a  |F...i..+.CZ..-.z|
+00000160  43 85 b7 14 52 e7 a5 65  4c 2c 78 b8 23 8c b5 b4  |C...R..eL,x.#...|
+00000170  82 e5 de 1f 95 3b 7e 62  a5 2c a5 33 d6 fe 12 5c  |.....;~b.,.3...\|
+00000180  7a 56 fc f5 06 bf fa 58  7b 26 3f b5 cd 04 d3 d0  |zV.....X{&?.....|
+00000190  c9 21 96 4a c7 f4 54 9f  5a bf ef 42 71 00 fe 18  |.!.J..T.Z..Bq...|
+000001a0  99 07 7f 7e 88 7d 7d f1  04 39 c4 a2 2e db 51 c9  |...~.}}..9....Q.|
+000001b0  7c e3 c0 4c 3b 32 66 01  cf af b1 1d b8 71 9a 1d  ||..L;2f......q..|
+000001c0  db db 89 6b ae da 2d 79  02 03 01 00 01 a3 81 a7  |...k..-y........|
+000001d0  30 81 a4 30 1d 06 03 55  1d 0e 04 16 04 14 b1 ad  |0..0...U........|
+000001e0  e2 85 5a cf cb 28 db 69  ce 23 69 de d3 26 8e 18  |..Z..(.i.#i..&..|
+000001f0  88 39 30 75 06 03 55 1d  23 04 6e 30 6c 80 14 b1  |.90u..U.#.n0l...|
+00000200  ad e2 85 5a cf cb 28 db  69 ce 23 69 de d3 26 8e  |...Z..(.i.#i..&.|
+00000210  18 88 39 a1 49 a4 47 30  45 31 0b 30 09 06 03 55  |..9.I.G0E1.0...U|
+00000220  04 06 13 02 41 55 31 13  30 11 06 03 55 04 08 13  |....AU1.0...U...|
+00000230  0a 53 6f 6d 65 2d 53 74  61 74 65 31 21 30 1f 06  |.Some-State1!0..|
+00000240  03 55 04 0a 13 18 49 6e  74 65 72 6e 65 74 20 57  |.U....Internet W|
+00000250  69 64 67 69 74 73 20 50  74 79 20 4c 74 64 82 09  |idgits Pty Ltd..|
+00000260  00 85 b0 bb a4 8a 7f b8  ca 30 0c 06 03 55 1d 13  |.........0...U..|
+00000270  04 05 30 03 01 01 ff 30  0d 06 09 2a 86 48 86 f7  |..0....0...*.H..|
+00000280  0d 01 01 05 05 00 03 81  81 00 08 6c 45 24 c7 6b  |...........lE$.k|
+00000290  b1 59 ab 0c 52 cc f2 b0  14 d7 87 9d 7a 64 75 b5  |.Y..R.......zdu.|
+000002a0  5a 95 66 e4 c5 2b 8e ae  12 66 1f eb 4f 38 b3 6e  |Z.f..+...f..O8.n|
+000002b0  60 d3 92 fd f7 41 08 b5  25 13 b1 18 7a 24 fb 30  |`....A..%...z$.0|
+000002c0  1d ba ed 98 b9 17 ec e7  d7 31 59 db 95 d3 1d 78  |.........1Y....x|
+000002d0  ea 50 56 5c d5 82 5a 2d  5a 5f 33 c4 b6 d8 c9 75  |.PV\..Z-Z_3....u|
+000002e0  90 96 8c 0f 52 98 b5 cd  98 1f 89 20 5f f2 a0 1c  |....R...... _...|
+000002f0  a3 1b 96 94 dd a9 fd 57  e9 70 e8 26 6d 71 99 9b  |.......W.p.&mq..|
+00000300  26 6e 38 50 29 6c 90 a7  bd d9 16 03 03 00 cd 0c  |&n8P)l..........|
+00000310  00 00 c9 03 00 17 41 04  1e 18 37 ef 0d 19 51 88  |......A...7...Q.|
+00000320  35 75 71 b5 e5 54 5b 12  2e 8f 09 67 fd a7 24 20  |5uq..T[....g..$ |
+00000330  3e b2 56 1c ce 97 28 5e  f8 2b 2d 4f 9e f1 07 9f  |>.V...(^.+-O....|
+00000340  6c 4b 5b 83 56 e2 32 42  e9 58 b6 d7 49 a6 b5 68  |lK[.V.2B.X..I..h|
+00000350  1a 41 03 56 6b dc 5a 89  04 01 00 80 2d a0 6e 47  |.A.Vk.Z.....-.nG|
+00000360  93 a2 19 17 32 f5 42 58  93 f6 4f d4 e9 4d a4 0f  |....2.BX..O..M..|
+00000370  fe 4e d7 2c 62 b6 fb 83  37 a3 09 60 4b 69 e2 4c  |.N.,b...7..`Ki.L|
+00000380  fc b8 4c d1 a6 9a 89 a0  c5 76 f5 62 b7 e8 eb c2  |..L......v.b....|
+00000390  fa 0f 0e 61 86 bc 70 da  13 72 8d 87 94 16 9a 8d  |...a..p..r......|
+000003a0  5f 80 82 92 77 37 4f 9e  55 5d dc 35 42 a3 75 5c  |_...w7O.U].5B.u\|
+000003b0  ec a4 58 78 66 97 97 da  49 67 2e b6 7e 11 de fb  |..Xxf...Ig..~...|
+000003c0  e3 8f e8 bf 1d 91 1e 91  20 1b 2a df c6 58 e4 82  |........ .*..X..|
+000003d0  ce 37 dd 6f a5 ac 51 3d  65 db 3f f5 16 03 03 00  |.7.o..Q=e.?.....|
+000003e0  04 0e 00 00 00                                    |.....|
+>>> Flow 3 (client to server)
+00000000  16 03 03 00 46 10 00 00  42 41 04 f3 fc ea d8 50  |....F...BA.....P|
+00000010  e6 15 b0 e7 11 c7 6d ee  09 ad 80 d5 54 eb 4f 62  |......m.....T.Ob|
+00000020  7d bb a7 2d 28 0c 66 33  42 09 cf 2b 58 f8 58 41  |}..-(.f3B..+X.XA|
+00000030  bd 46 51 0a f0 7d 8c 0c  98 9e 26 77 20 fd 5e c1  |.FQ..}....&w .^.|
+00000040  a9 b3 e5 c3 6c 05 97 e3  81 fd db 14 03 03 00 01  |....l...........|
+00000050  01 16 03 03 00 40 02 2a  28 41 e3 9c 5d 45 d4 45  |..... at .*(A..]E.E|
+00000060  51 8c 7a c0 ba b1 8e a4  84 2c f3 83 cd c4 55 5c  |Q.z......,....U\|
+00000070  d6 5c 6f 72 ab 89 7a c6  d7 9c 2a 54 f0 c4 20 ee  |.\or..z...*T.. .|
+00000080  37 74 9b b6 8c f7 e4 37  2c eb d4 9f 5c 5e 55 a0  |7t.....7,...\^U.|
+00000090  e2 5a fe 1e c8 67                                 |.Z...g|
+>>> Flow 4 (server to client)
+00000000  16 03 03 00 72 04 00 00  6e 00 00 00 00 00 68 00  |....r...n.....h.|
+00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 65  |...............e|
+00000020  ea 8b c0 ef ba 59 31 75  33 96 f1 f8 c9 e1 ef 30  |.....Y1u3......0|
+00000030  00 a3 a9 1d ab c8 4b 29  94 f2 c8 c8 8d 03 57 ab  |......K)......W.|
+00000040  56 df 0f 4e 0d 30 13 09  c9 e4 fa 51 4e b3 26 ad  |V..N.0.....QN.&.|
+00000050  43 9f ae 62 d5 59 23 05  9b 69 8f 5b a8 ba 39 f1  |C..b.Y#..i.[..9.|
+00000060  90 84 35 bf 8f 8d d5 39  93 98 ee b9 75 03 3f 91  |..5....9....u.?.|
+00000070  e8 56 0b cb 44 a6 7a 14  03 03 00 01 01 16 03 03  |.V..D.z.........|
+00000080  00 40 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |. at ..............|
+00000090  00 00 f9 a0 8e 23 34 f1  61 15 a8 4e ae c4 f3 2a  |.....#4.a..N...*|
+000000a0  a6 f8 ee 1b 65 c4 c0 ff  93 14 74 ed 82 ae 48 a8  |....e.....t...H.|
+000000b0  42 fb a9 24 5d dd fd 98  b8 65 73 03 88 99 e1 ed  |B..$]....es.....|
+000000c0  02 95 17 03 03 00 40 00  00 00 00 00 00 00 00 00  |...... at .........|
+000000d0  00 00 00 00 00 00 00 b9  b3 f5 41 84 3b 2a a9 c3  |..........A.;*..|
+000000e0  9c e3 d4 38 90 76 c1 8c  f0 4f 10 1b 04 b5 07 fe  |...8.v...O......|
+000000f0  79 3d 7b 77 a4 17 0f 4e  df 64 70 70 9e 34 8e b6  |y={w...N.dpp.4..|
+00000100  db b2 b6 fd 41 fe b3 15  03 03 00 30 00 00 00 00  |....A......0....|
+00000110  00 00 00 00 00 00 00 00  00 00 00 00 02 73 de fe  |.............s..|
+00000120  fa 4b 69 6d 30 69 79 96  7e 4f 2f 04 67 36 96 27  |.Kim0iy.~O/.g6.'|
+00000130  67 23 2b dc 7a c4 6c 34  ea fc 79 fd              |g#+.z.l4..y.|
diff --git a/src/crypto/tls/testdata/Server-TLSv12-ALPN-NoMatch b/src/crypto/tls/testdata/Server-TLSv12-ALPN-NoMatch
new file mode 100644
index 0000000..db5881b
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv12-ALPN-NoMatch
@@ -0,0 +1,121 @@
+>>> Flow 1 (client to server)
+00000000  16 03 01 01 8a 01 00 01  86 03 03 0a a8 82 53 61  |..............Sa|
+00000010  68 e0 83 91 71 36 f9 c1  19 ff e8 09 fc 21 9f 03  |h...q6.......!..|
+00000020  31 f3 87 4a 04 8c 3d c2  6e 00 32 00 00 d6 c0 30  |1..J..=.n.2....0|
+00000030  c0 2c c0 28 c0 24 c0 14  c0 0a c0 22 c0 21 c0 20  |.,.(.$.....".!. |
+00000040  00 a5 00 a3 00 a1 00 9f  00 6b 00 6a 00 69 00 68  |.........k.j.i.h|
+00000050  00 39 00 38 00 37 00 36  00 88 00 87 00 86 00 85  |.9.8.7.6........|
+00000060  c0 32 c0 2e c0 2a c0 26  c0 0f c0 05 00 9d 00 3d  |.2...*.&.......=|
+00000070  00 35 00 84 c0 2f c0 2b  c0 27 c0 23 c0 13 c0 09  |.5.../.+.'.#....|
+00000080  c0 1f c0 1e c0 1d 00 a4  00 a2 00 a0 00 9e 00 67  |...............g|
+00000090  00 40 00 3f 00 3e 00 33  00 32 00 31 00 30 00 9a  |. at .?.>.3.2.1.0..|
+000000a0  00 99 00 98 00 97 00 45  00 44 00 43 00 42 c0 31  |.......E.D.C.B.1|
+000000b0  c0 2d c0 29 c0 25 c0 0e  c0 04 00 9c 00 3c 00 2f  |.-.).%.......<./|
+000000c0  00 96 00 41 00 07 c0 11  c0 07 c0 0c c0 02 00 05  |...A............|
+000000d0  00 04 c0 12 c0 08 c0 1c  c0 1b c0 1a 00 16 00 13  |................|
+000000e0  00 10 00 0d c0 0d c0 03  00 0a 00 15 00 12 00 0f  |................|
+000000f0  00 0c 00 09 00 14 00 11  00 0e 00 0b 00 08 00 06  |................|
+00000100  00 03 00 ff 01 00 00 87  00 0b 00 04 03 00 01 02  |................|
+00000110  00 0a 00 3a 00 38 00 0e  00 0d 00 19 00 1c 00 0b  |...:.8..........|
+00000120  00 0c 00 1b 00 18 00 09  00 0a 00 1a 00 16 00 17  |................|
+00000130  00 08 00 06 00 07 00 14  00 15 00 04 00 05 00 12  |................|
+00000140  00 13 00 01 00 02 00 03  00 0f 00 10 00 11 00 23  |...............#|
+00000150  00 00 00 0d 00 20 00 1e  06 01 06 02 06 03 05 01  |..... ..........|
+00000160  05 02 05 03 04 01 04 02  04 03 03 01 03 02 03 03  |................|
+00000170  02 01 02 02 02 03 00 0f  00 01 01 00 10 00 10 00  |................|
+00000180  0e 06 70 72 6f 74 6f 32  06 70 72 6f 74 6f 31     |..proto2.proto1|
+>>> Flow 2 (server to client)
+00000000  16 03 03 00 35 02 00 00  31 03 03 00 00 00 00 00  |....5...1.......|
+00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
+00000020  00 00 00 00 00 00 00 00  00 00 00 00 c0 14 00 00  |................|
+00000030  09 00 23 00 00 ff 01 00  01 00 16 03 03 02 be 0b  |..#.............|
+00000040  00 02 ba 00 02 b7 00 02  b4 30 82 02 b0 30 82 02  |.........0...0..|
+00000050  19 a0 03 02 01 02 02 09  00 85 b0 bb a4 8a 7f b8  |................|
+00000060  ca 30 0d 06 09 2a 86 48  86 f7 0d 01 01 05 05 00  |.0...*.H........|
+00000070  30 45 31 0b 30 09 06 03  55 04 06 13 02 41 55 31  |0E1.0...U....AU1|
+00000080  13 30 11 06 03 55 04 08  13 0a 53 6f 6d 65 2d 53  |.0...U....Some-S|
+00000090  74 61 74 65 31 21 30 1f  06 03 55 04 0a 13 18 49  |tate1!0...U....I|
+000000a0  6e 74 65 72 6e 65 74 20  57 69 64 67 69 74 73 20  |nternet Widgits |
+000000b0  50 74 79 20 4c 74 64 30  1e 17 0d 31 30 30 34 32  |Pty Ltd0...10042|
+000000c0  34 30 39 30 39 33 38 5a  17 0d 31 31 30 34 32 34  |4090938Z..110424|
+000000d0  30 39 30 39 33 38 5a 30  45 31 0b 30 09 06 03 55  |090938Z0E1.0...U|
+000000e0  04 06 13 02 41 55 31 13  30 11 06 03 55 04 08 13  |....AU1.0...U...|
+000000f0  0a 53 6f 6d 65 2d 53 74  61 74 65 31 21 30 1f 06  |.Some-State1!0..|
+00000100  03 55 04 0a 13 18 49 6e  74 65 72 6e 65 74 20 57  |.U....Internet W|
+00000110  69 64 67 69 74 73 20 50  74 79 20 4c 74 64 30 81  |idgits Pty Ltd0.|
+00000120  9f 30 0d 06 09 2a 86 48  86 f7 0d 01 01 01 05 00  |.0...*.H........|
+00000130  03 81 8d 00 30 81 89 02  81 81 00 bb 79 d6 f5 17  |....0.......y...|
+00000140  b5 e5 bf 46 10 d0 dc 69  be e6 2b 07 43 5a d0 03  |...F...i..+.CZ..|
+00000150  2d 8a 7a 43 85 b7 14 52  e7 a5 65 4c 2c 78 b8 23  |-.zC...R..eL,x.#|
+00000160  8c b5 b4 82 e5 de 1f 95  3b 7e 62 a5 2c a5 33 d6  |........;~b.,.3.|
+00000170  fe 12 5c 7a 56 fc f5 06  bf fa 58 7b 26 3f b5 cd  |..\zV.....X{&?..|
+00000180  04 d3 d0 c9 21 96 4a c7  f4 54 9f 5a bf ef 42 71  |....!.J..T.Z..Bq|
+00000190  00 fe 18 99 07 7f 7e 88  7d 7d f1 04 39 c4 a2 2e  |......~.}}..9...|
+000001a0  db 51 c9 7c e3 c0 4c 3b  32 66 01 cf af b1 1d b8  |.Q.|..L;2f......|
+000001b0  71 9a 1d db db 89 6b ae  da 2d 79 02 03 01 00 01  |q.....k..-y.....|
+000001c0  a3 81 a7 30 81 a4 30 1d  06 03 55 1d 0e 04 16 04  |...0..0...U.....|
+000001d0  14 b1 ad e2 85 5a cf cb  28 db 69 ce 23 69 de d3  |.....Z..(.i.#i..|
+000001e0  26 8e 18 88 39 30 75 06  03 55 1d 23 04 6e 30 6c  |&...90u..U.#.n0l|
+000001f0  80 14 b1 ad e2 85 5a cf  cb 28 db 69 ce 23 69 de  |......Z..(.i.#i.|
+00000200  d3 26 8e 18 88 39 a1 49  a4 47 30 45 31 0b 30 09  |.&...9.I.G0E1.0.|
+00000210  06 03 55 04 06 13 02 41  55 31 13 30 11 06 03 55  |..U....AU1.0...U|
+00000220  04 08 13 0a 53 6f 6d 65  2d 53 74 61 74 65 31 21  |....Some-State1!|
+00000230  30 1f 06 03 55 04 0a 13  18 49 6e 74 65 72 6e 65  |0...U....Interne|
+00000240  74 20 57 69 64 67 69 74  73 20 50 74 79 20 4c 74  |t Widgits Pty Lt|
+00000250  64 82 09 00 85 b0 bb a4  8a 7f b8 ca 30 0c 06 03  |d...........0...|
+00000260  55 1d 13 04 05 30 03 01  01 ff 30 0d 06 09 2a 86  |U....0....0...*.|
+00000270  48 86 f7 0d 01 01 05 05  00 03 81 81 00 08 6c 45  |H.............lE|
+00000280  24 c7 6b b1 59 ab 0c 52  cc f2 b0 14 d7 87 9d 7a  |$.k.Y..R.......z|
+00000290  64 75 b5 5a 95 66 e4 c5  2b 8e ae 12 66 1f eb 4f  |du.Z.f..+...f..O|
+000002a0  38 b3 6e 60 d3 92 fd f7  41 08 b5 25 13 b1 18 7a  |8.n`....A..%...z|
+000002b0  24 fb 30 1d ba ed 98 b9  17 ec e7 d7 31 59 db 95  |$.0.........1Y..|
+000002c0  d3 1d 78 ea 50 56 5c d5  82 5a 2d 5a 5f 33 c4 b6  |..x.PV\..Z-Z_3..|
+000002d0  d8 c9 75 90 96 8c 0f 52  98 b5 cd 98 1f 89 20 5f  |..u....R...... _|
+000002e0  f2 a0 1c a3 1b 96 94 dd  a9 fd 57 e9 70 e8 26 6d  |..........W.p.&m|
+000002f0  71 99 9b 26 6e 38 50 29  6c 90 a7 bd d9 16 03 03  |q..&n8P)l.......|
+00000300  00 cd 0c 00 00 c9 03 00  17 41 04 1e 18 37 ef 0d  |.........A...7..|
+00000310  19 51 88 35 75 71 b5 e5  54 5b 12 2e 8f 09 67 fd  |.Q.5uq..T[....g.|
+00000320  a7 24 20 3e b2 56 1c ce  97 28 5e f8 2b 2d 4f 9e  |.$ >.V...(^.+-O.|
+00000330  f1 07 9f 6c 4b 5b 83 56  e2 32 42 e9 58 b6 d7 49  |...lK[.V.2B.X..I|
+00000340  a6 b5 68 1a 41 03 56 6b  dc 5a 89 04 01 00 80 b9  |..h.A.Vk.Z......|
+00000350  0f 79 8a 16 f4 da 8f 27  b4 16 fc c0 51 db ae d1  |.y.....'....Q...|
+00000360  af 79 77 d5 d5 a2 13 05  45 20 cc eb ac ed cb 30  |.yw.....E .....0|
+00000370  32 2e 2c bd fa 1c 4d b5  32 a6 37 43 c8 5c 2d f8  |2.,...M.2.7C.\-.|
+00000380  6e 85 f5 cd 54 92 29 ad  13 7d d5 9e 8c 1d b7 d0  |n...T.)..}......|
+00000390  c1 c7 3d e8 ba 4a 0f 9a  a6 3e 25 5f 27 62 b1 00  |..=..J...>%_'b..|
+000003a0  91 d9 23 48 3f 10 fe c5  e3 07 9a 58 57 6d cc 10  |..#H?......XWm..|
+000003b0  3b f8 1a d5 6e 8b 1f 03  6f 82 84 98 b5 f7 71 5d  |;...n...o.....q]|
+000003c0  c2 ad 60 14 c1 88 07 5a  3d 99 fd a8 c9 9a 03 16  |..`....Z=.......|
+000003d0  03 03 00 04 0e 00 00 00                           |........|
+>>> Flow 3 (client to server)
+00000000  16 03 03 00 46 10 00 00  42 41 04 76 aa 4e b9 f9  |....F...BA.v.N..|
+00000010  68 85 81 74 7c d9 f9 64  7f bd 09 83 08 5b 4f 76  |h..t|..d.....[Ov|
+00000020  6e be 79 b6 4e 97 17 63  e4 b5 1c 77 e5 85 76 8a  |n.y.N..c...w..v.|
+00000030  5d 9f f1 21 88 ec f9 a7  7c 41 af f9 c5 fe 11 81  |]..!....|A......|
+00000040  11 51 8e a7 20 33 5f cf  e7 90 90 14 03 03 00 01  |.Q.. 3_.........|
+00000050  01 16 03 03 00 40 44 3e  32 01 71 ac 5a b5 1f 2c  |..... at D>2.q.Z..,|
+00000060  37 d9 4b 70 72 91 89 d4  d7 c2 c3 e7 ff dc 72 2a  |7.Kpr.........r*|
+00000070  ba f5 30 b0 e9 dd 48 10  3d cd 98 48 a3 e3 ca de  |..0...H.=..H....|
+00000080  15 0e 90 8e e5 04 14 74  42 b8 b0 12 cc 68 7b 7d  |.......tB....h{}|
+00000090  6c 43 72 60 05 0d                                 |lCr`..|
+>>> Flow 4 (server to client)
+00000000  16 03 03 00 72 04 00 00  6e 00 00 00 00 00 68 00  |....r...n.....h.|
+00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 65  |...............e|
+00000020  ea 8b c0 ef ba 12 45 17  61 24 cd d2 4c 22 bb 3b  |......E.a$..L".;|
+00000030  e3 0e d0 ff 83 e9 7c b7  8f 10 3c 16 1c fc c2 44  |......|...<....D|
+00000040  ef 45 f8 27 30 56 db ea  eb ae f5 b6 17 b2 ef f9  |.E.'0V..........|
+00000050  96 0d 2d db e4 59 23 0a  fc fa e3 13 48 57 e5 b3  |..-..Y#.....HW..|
+00000060  3a d1 f5 5e ca ef d7 3f  7b b5 f4 69 85 c3 bd da  |:..^...?{..i....|
+00000070  fd 9c 50 05 2f 86 ce 14  03 03 00 01 01 16 03 03  |..P./...........|
+00000080  00 40 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |. at ..............|
+00000090  00 00 60 25 1c ed 6f c6  a5 bd b2 29 39 4e 09 d1  |..`%..o....)9N..|
+000000a0  64 cc 75 cd df 91 a8 90  9d 03 aa 92 07 f2 d0 8a  |d.u.............|
+000000b0  60 bb 3e 85 21 22 fe f8  dc 52 3c 4e 82 77 14 14  |`.>.!"...R<N.w..|
+000000c0  0f 1f 17 03 03 00 40 00  00 00 00 00 00 00 00 00  |...... at .........|
+000000d0  00 00 00 00 00 00 00 0b  87 12 62 3e e5 3e 7d 74  |..........b>.>}t|
+000000e0  0d ac c4 a9 df 67 1c 5a  ad 3e 01 34 03 88 2f 39  |.....g.Z.>.4../9|
+000000f0  f7 3c 06 e4 f6 81 43 66  b1 1b ed a5 e5 b6 a8 43  |.<....Cf.......C|
+00000100  7f 36 2f b2 da 45 9a 15  03 03 00 30 00 00 00 00  |.6/..E.....0....|
+00000110  00 00 00 00 00 00 00 00  00 00 00 00 fa 63 4e c5  |.............cN.|
+00000120  77 89 71 56 e3 0a cf 98  da 2f 89 8f 74 8e 76 24  |w.qV...../..t.v$|
+00000130  e2 40 a5 9f 29 1b b2 11  ef 7a 55 7f              |. at ..)....zU.|
diff --git a/src/pkg/crypto/tls/testdata/Server-TLSv12-CipherSuiteCertPreferenceECDSA b/src/crypto/tls/testdata/Server-TLSv12-CipherSuiteCertPreferenceECDSA
similarity index 100%
rename from src/pkg/crypto/tls/testdata/Server-TLSv12-CipherSuiteCertPreferenceECDSA
rename to src/crypto/tls/testdata/Server-TLSv12-CipherSuiteCertPreferenceECDSA
diff --git a/src/pkg/crypto/tls/testdata/Server-TLSv12-CipherSuiteCertPreferenceRSA b/src/crypto/tls/testdata/Server-TLSv12-CipherSuiteCertPreferenceRSA
similarity index 100%
rename from src/pkg/crypto/tls/testdata/Server-TLSv12-CipherSuiteCertPreferenceRSA
rename to src/crypto/tls/testdata/Server-TLSv12-CipherSuiteCertPreferenceRSA
diff --git a/src/pkg/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedAndECDSAGiven b/src/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedAndECDSAGiven
similarity index 100%
rename from src/pkg/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedAndECDSAGiven
rename to src/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedAndECDSAGiven
diff --git a/src/pkg/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedAndGiven b/src/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedAndGiven
similarity index 100%
rename from src/pkg/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedAndGiven
rename to src/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedAndGiven
diff --git a/src/pkg/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedNotGiven b/src/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedNotGiven
similarity index 100%
rename from src/pkg/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedNotGiven
rename to src/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedNotGiven
diff --git a/src/pkg/crypto/tls/testdata/Server-TLSv12-ECDHE-ECDSA-AES b/src/crypto/tls/testdata/Server-TLSv12-ECDHE-ECDSA-AES
similarity index 100%
rename from src/pkg/crypto/tls/testdata/Server-TLSv12-ECDHE-ECDSA-AES
rename to src/crypto/tls/testdata/Server-TLSv12-ECDHE-ECDSA-AES
diff --git a/src/pkg/crypto/tls/testdata/Server-TLSv12-IssueTicket b/src/crypto/tls/testdata/Server-TLSv12-IssueTicket
similarity index 100%
rename from src/pkg/crypto/tls/testdata/Server-TLSv12-IssueTicket
rename to src/crypto/tls/testdata/Server-TLSv12-IssueTicket
diff --git a/src/pkg/crypto/tls/testdata/Server-TLSv12-IssueTicketPreDisable b/src/crypto/tls/testdata/Server-TLSv12-IssueTicketPreDisable
similarity index 100%
rename from src/pkg/crypto/tls/testdata/Server-TLSv12-IssueTicketPreDisable
rename to src/crypto/tls/testdata/Server-TLSv12-IssueTicketPreDisable
diff --git a/src/pkg/crypto/tls/testdata/Server-TLSv12-RSA-3DES b/src/crypto/tls/testdata/Server-TLSv12-RSA-3DES
similarity index 100%
rename from src/pkg/crypto/tls/testdata/Server-TLSv12-RSA-3DES
rename to src/crypto/tls/testdata/Server-TLSv12-RSA-3DES
diff --git a/src/pkg/crypto/tls/testdata/Server-TLSv12-RSA-AES b/src/crypto/tls/testdata/Server-TLSv12-RSA-AES
similarity index 100%
rename from src/pkg/crypto/tls/testdata/Server-TLSv12-RSA-AES
rename to src/crypto/tls/testdata/Server-TLSv12-RSA-AES
diff --git a/src/pkg/crypto/tls/testdata/Server-TLSv12-RSA-AES-GCM b/src/crypto/tls/testdata/Server-TLSv12-RSA-AES-GCM
similarity index 100%
rename from src/pkg/crypto/tls/testdata/Server-TLSv12-RSA-AES-GCM
rename to src/crypto/tls/testdata/Server-TLSv12-RSA-AES-GCM
diff --git a/src/pkg/crypto/tls/testdata/Server-TLSv12-RSA-RC4 b/src/crypto/tls/testdata/Server-TLSv12-RSA-RC4
similarity index 100%
rename from src/pkg/crypto/tls/testdata/Server-TLSv12-RSA-RC4
rename to src/crypto/tls/testdata/Server-TLSv12-RSA-RC4
diff --git a/src/pkg/crypto/tls/testdata/Server-TLSv12-Resume b/src/crypto/tls/testdata/Server-TLSv12-Resume
similarity index 100%
rename from src/pkg/crypto/tls/testdata/Server-TLSv12-Resume
rename to src/crypto/tls/testdata/Server-TLSv12-Resume
diff --git a/src/pkg/crypto/tls/testdata/Server-TLSv12-ResumeDisabled b/src/crypto/tls/testdata/Server-TLSv12-ResumeDisabled
similarity index 100%
rename from src/pkg/crypto/tls/testdata/Server-TLSv12-ResumeDisabled
rename to src/crypto/tls/testdata/Server-TLSv12-ResumeDisabled
diff --git a/src/pkg/crypto/tls/testdata/Server-TLSv12-SNI b/src/crypto/tls/testdata/Server-TLSv12-SNI
similarity index 100%
rename from src/pkg/crypto/tls/testdata/Server-TLSv12-SNI
rename to src/crypto/tls/testdata/Server-TLSv12-SNI
diff --git a/src/pkg/crypto/tls/ticket.go b/src/crypto/tls/ticket.go
similarity index 100%
rename from src/pkg/crypto/tls/ticket.go
rename to src/crypto/tls/ticket.go
diff --git a/src/pkg/crypto/tls/tls.go b/src/crypto/tls/tls.go
similarity index 100%
rename from src/pkg/crypto/tls/tls.go
rename to src/crypto/tls/tls.go
diff --git a/src/crypto/tls/tls_test.go b/src/crypto/tls/tls_test.go
new file mode 100644
index 0000000..e82579e
--- /dev/null
+++ b/src/crypto/tls/tls_test.go
@@ -0,0 +1,282 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tls
+
+import (
+	"bytes"
+	"fmt"
+	"io"
+	"net"
+	"strings"
+	"testing"
+	"time"
+)
+
+var rsaCertPEM = `-----BEGIN CERTIFICATE-----
+MIIB0zCCAX2gAwIBAgIJAI/M7BYjwB+uMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV
+BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
+aWRnaXRzIFB0eSBMdGQwHhcNMTIwOTEyMjE1MjAyWhcNMTUwOTEyMjE1MjAyWjBF
+MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50
+ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANLJ
+hPHhITqQbPklG3ibCVxwGMRfp/v4XqhfdQHdcVfHap6NQ5Wok/4xIA+ui35/MmNa
+rtNuC+BdZ1tMuVCPFZcCAwEAAaNQME4wHQYDVR0OBBYEFJvKs8RfJaXTH08W+SGv
+zQyKn0H8MB8GA1UdIwQYMBaAFJvKs8RfJaXTH08W+SGvzQyKn0H8MAwGA1UdEwQF
+MAMBAf8wDQYJKoZIhvcNAQEFBQADQQBJlffJHybjDGxRMqaRmDhX0+6v02TUKZsW
+r5QuVbpQhH6u+0UgcW0jp9QwpxoPTLTWGXEWBBBurxFwiCBhkQ+V
+-----END CERTIFICATE-----
+`
+
+var rsaKeyPEM = `-----BEGIN RSA PRIVATE KEY-----
+MIIBOwIBAAJBANLJhPHhITqQbPklG3ibCVxwGMRfp/v4XqhfdQHdcVfHap6NQ5Wo
+k/4xIA+ui35/MmNartNuC+BdZ1tMuVCPFZcCAwEAAQJAEJ2N+zsR0Xn8/Q6twa4G
+6OB1M1WO+k+ztnX/1SvNeWu8D6GImtupLTYgjZcHufykj09jiHmjHx8u8ZZB/o1N
+MQIhAPW+eyZo7ay3lMz1V01WVjNKK9QSn1MJlb06h/LuYv9FAiEA25WPedKgVyCW
+SmUwbPw8fnTcpqDWE3yTO3vKcebqMSsCIBF3UmVue8YU3jybC3NxuXq3wNm34R8T
+xVLHwDXh/6NJAiEAl2oHGGLz64BuAfjKrqwz7qMYr9HCLIe/YsoWq/olzScCIQDi
+D2lWusoe2/nEqfDVVWGWlyJ7yOmqaVm/iNUN9B2N2g==
+-----END RSA PRIVATE KEY-----
+`
+
+// keyPEM is the same as rsaKeyPEM, but declares itself as just
+// "PRIVATE KEY", not "RSA PRIVATE KEY".  http://golang.org/issue/4477
+var keyPEM = `-----BEGIN PRIVATE KEY-----
+MIIBOwIBAAJBANLJhPHhITqQbPklG3ibCVxwGMRfp/v4XqhfdQHdcVfHap6NQ5Wo
+k/4xIA+ui35/MmNartNuC+BdZ1tMuVCPFZcCAwEAAQJAEJ2N+zsR0Xn8/Q6twa4G
+6OB1M1WO+k+ztnX/1SvNeWu8D6GImtupLTYgjZcHufykj09jiHmjHx8u8ZZB/o1N
+MQIhAPW+eyZo7ay3lMz1V01WVjNKK9QSn1MJlb06h/LuYv9FAiEA25WPedKgVyCW
+SmUwbPw8fnTcpqDWE3yTO3vKcebqMSsCIBF3UmVue8YU3jybC3NxuXq3wNm34R8T
+xVLHwDXh/6NJAiEAl2oHGGLz64BuAfjKrqwz7qMYr9HCLIe/YsoWq/olzScCIQDi
+D2lWusoe2/nEqfDVVWGWlyJ7yOmqaVm/iNUN9B2N2g==
+-----END PRIVATE KEY-----
+`
+
+var ecdsaCertPEM = `-----BEGIN CERTIFICATE-----
+MIIB/jCCAWICCQDscdUxw16XFDAJBgcqhkjOPQQBMEUxCzAJBgNVBAYTAkFVMRMw
+EQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0
+eSBMdGQwHhcNMTIxMTE0MTI0MDQ4WhcNMTUxMTE0MTI0MDQ4WjBFMQswCQYDVQQG
+EwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lk
+Z2l0cyBQdHkgTHRkMIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQBY9+my9OoeSUR
+lDQdV/x8LsOuLilthhiS1Tz4aGDHIPwC1mlvnf7fg5lecYpMCrLLhauAc1UJXcgl
+01xoLuzgtAEAgv2P/jgytzRSpUYvgLBt1UA0leLYBy6mQQbrNEuqT3INapKIcUv8
+XxYP0xMEUksLPq6Ca+CRSqTtrd/23uTnapkwCQYHKoZIzj0EAQOBigAwgYYCQXJo
+A7Sl2nLVf+4Iu/tAX/IF4MavARKC4PPHK3zfuGfPR3oCCcsAoz3kAzOeijvd0iXb
+H5jBImIxPL4WxQNiBTexAkF8D1EtpYuWdlVQ80/h/f4pBcGiXPqX5h2PQSQY7hP1
++jwM1FGS4fREIOvlBYr/SzzQRtwrvrzGYxDEDbsC0ZGRnA==
+-----END CERTIFICATE-----
+`
+
+var ecdsaKeyPEM = `-----BEGIN EC PARAMETERS-----
+BgUrgQQAIw==
+-----END EC PARAMETERS-----
+-----BEGIN EC PRIVATE KEY-----
+MIHcAgEBBEIBrsoKp0oqcv6/JovJJDoDVSGWdirrkgCWxrprGlzB9o0X8fV675X0
+NwuBenXFfeZvVcwluO7/Q9wkYoPd/t3jGImgBwYFK4EEACOhgYkDgYYABAFj36bL
+06h5JRGUNB1X/Hwuw64uKW2GGJLVPPhoYMcg/ALWaW+d/t+DmV5xikwKssuFq4Bz
+VQldyCXTXGgu7OC0AQCC/Y/+ODK3NFKlRi+AsG3VQDSV4tgHLqZBBus0S6pPcg1q
+kohxS/xfFg/TEwRSSws+roJr4JFKpO2t3/be5OdqmQ==
+-----END EC PRIVATE KEY-----
+`
+
+var keyPairTests = []struct {
+	algo string
+	cert string
+	key  string
+}{
+	{"ECDSA", ecdsaCertPEM, ecdsaKeyPEM},
+	{"RSA", rsaCertPEM, rsaKeyPEM},
+	{"RSA-untyped", rsaCertPEM, keyPEM}, // golang.org/issue/4477
+}
+
+func TestX509KeyPair(t *testing.T) {
+	var pem []byte
+	for _, test := range keyPairTests {
+		pem = []byte(test.cert + test.key)
+		if _, err := X509KeyPair(pem, pem); err != nil {
+			t.Errorf("Failed to load %s cert followed by %s key: %s", test.algo, test.algo, err)
+		}
+		pem = []byte(test.key + test.cert)
+		if _, err := X509KeyPair(pem, pem); err != nil {
+			t.Errorf("Failed to load %s key followed by %s cert: %s", test.algo, test.algo, err)
+		}
+	}
+}
+
+func TestX509MixedKeyPair(t *testing.T) {
+	if _, err := X509KeyPair([]byte(rsaCertPEM), []byte(ecdsaKeyPEM)); err == nil {
+		t.Error("Load of RSA certificate succeeded with ECDSA private key")
+	}
+	if _, err := X509KeyPair([]byte(ecdsaCertPEM), []byte(rsaKeyPEM)); err == nil {
+		t.Error("Load of ECDSA certificate succeeded with RSA private key")
+	}
+}
+
+func newLocalListener(t *testing.T) net.Listener {
+	ln, err := net.Listen("tcp", "127.0.0.1:0")
+	if err != nil {
+		ln, err = net.Listen("tcp6", "[::1]:0")
+	}
+	if err != nil {
+		t.Fatal(err)
+	}
+	return ln
+}
+
+func TestDialTimeout(t *testing.T) {
+	if testing.Short() {
+		t.Skip("skipping in short mode")
+	}
+	listener := newLocalListener(t)
+
+	addr := listener.Addr().String()
+	defer listener.Close()
+
+	complete := make(chan bool)
+	defer close(complete)
+
+	go func() {
+		conn, err := listener.Accept()
+		if err != nil {
+			t.Error(err)
+			return
+		}
+		<-complete
+		conn.Close()
+	}()
+
+	dialer := &net.Dialer{
+		Timeout: 10 * time.Millisecond,
+	}
+
+	var err error
+	if _, err = DialWithDialer(dialer, "tcp", addr, nil); err == nil {
+		t.Fatal("DialWithTimeout completed successfully")
+	}
+
+	if !strings.Contains(err.Error(), "timed out") {
+		t.Errorf("resulting error not a timeout: %s", err)
+	}
+}
+
+// tests that Conn.Read returns (non-zero, io.EOF) instead of
+// (non-zero, nil) when a Close (alertCloseNotify) is sitting right
+// behind the application data in the buffer.
+func TestConnReadNonzeroAndEOF(t *testing.T) {
+	// This test is racy: it assumes that after a write to a
+	// localhost TCP connection, the peer TCP connection can
+	// immediately read it.  Because it's racy, we skip this test
+	// in short mode, and then retry it several times with an
+	// increasing sleep in between our final write (via srv.Close
+	// below) and the following read.
+	if testing.Short() {
+		t.Skip("skipping in short mode")
+	}
+	var err error
+	for delay := time.Millisecond; delay <= 64*time.Millisecond; delay *= 2 {
+		if err = testConnReadNonzeroAndEOF(t, delay); err == nil {
+			return
+		}
+	}
+	t.Error(err)
+}
+
+func testConnReadNonzeroAndEOF(t *testing.T, delay time.Duration) error {
+	ln := newLocalListener(t)
+	defer ln.Close()
+
+	srvCh := make(chan *Conn, 1)
+	var serr error
+	go func() {
+		sconn, err := ln.Accept()
+		if err != nil {
+			serr = err
+			srvCh <- nil
+			return
+		}
+		serverConfig := *testConfig
+		srv := Server(sconn, &serverConfig)
+		if err := srv.Handshake(); err != nil {
+			serr = fmt.Errorf("handshake: %v", err)
+			srvCh <- nil
+			return
+		}
+		srvCh <- srv
+	}()
+
+	clientConfig := *testConfig
+	conn, err := Dial("tcp", ln.Addr().String(), &clientConfig)
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer conn.Close()
+
+	srv := <-srvCh
+	if srv == nil {
+		return serr
+	}
+
+	buf := make([]byte, 6)
+
+	srv.Write([]byte("foobar"))
+	n, err := conn.Read(buf)
+	if n != 6 || err != nil || string(buf) != "foobar" {
+		return fmt.Errorf("Read = %d, %v, data %q; want 6, nil, foobar", n, err, buf)
+	}
+
+	srv.Write([]byte("abcdef"))
+	srv.Close()
+	time.Sleep(delay)
+	n, err = conn.Read(buf)
+	if n != 6 || string(buf) != "abcdef" {
+		return fmt.Errorf("Read = %d, buf= %q; want 6, abcdef", n, buf)
+	}
+	if err != io.EOF {
+		return fmt.Errorf("Second Read error = %v; want io.EOF", err)
+	}
+	return nil
+}
+
+func TestTLSUniqueMatches(t *testing.T) {
+	ln := newLocalListener(t)
+	defer ln.Close()
+
+	serverTLSUniques := make(chan []byte)
+	go func() {
+		for i := 0; i < 2; i++ {
+			sconn, err := ln.Accept()
+			if err != nil {
+				t.Fatal(err)
+			}
+			serverConfig := *testConfig
+			srv := Server(sconn, &serverConfig)
+			if err := srv.Handshake(); err != nil {
+				t.Fatal(err)
+			}
+			serverTLSUniques <- srv.ConnectionState().TLSUnique
+		}
+	}()
+
+	clientConfig := *testConfig
+	clientConfig.ClientSessionCache = NewLRUClientSessionCache(1)
+	conn, err := Dial("tcp", ln.Addr().String(), &clientConfig)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if !bytes.Equal(conn.ConnectionState().TLSUnique, <-serverTLSUniques) {
+		t.Error("client and server channel bindings differ")
+	}
+	conn.Close()
+
+	conn, err = Dial("tcp", ln.Addr().String(), &clientConfig)
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer conn.Close()
+	if !conn.ConnectionState().DidResume {
+		t.Error("second session did not use resumption")
+	}
+	if !bytes.Equal(conn.ConnectionState().TLSUnique, <-serverTLSUniques) {
+		t.Error("client and server channel bindings differ when session resumption is used")
+	}
+}
diff --git a/src/pkg/crypto/x509/cert_pool.go b/src/crypto/x509/cert_pool.go
similarity index 100%
rename from src/pkg/crypto/x509/cert_pool.go
rename to src/crypto/x509/cert_pool.go
diff --git a/src/pkg/crypto/x509/example_test.go b/src/crypto/x509/example_test.go
similarity index 100%
rename from src/pkg/crypto/x509/example_test.go
rename to src/crypto/x509/example_test.go
diff --git a/src/pkg/crypto/x509/pem_decrypt.go b/src/crypto/x509/pem_decrypt.go
similarity index 100%
rename from src/pkg/crypto/x509/pem_decrypt.go
rename to src/crypto/x509/pem_decrypt.go
diff --git a/src/crypto/x509/pem_decrypt_test.go b/src/crypto/x509/pem_decrypt_test.go
new file mode 100644
index 0000000..13e4700
--- /dev/null
+++ b/src/crypto/x509/pem_decrypt_test.go
@@ -0,0 +1,223 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package x509
+
+import (
+	"bytes"
+	"crypto/rand"
+	"encoding/base64"
+	"encoding/pem"
+	"testing"
+)
+
+func TestDecrypt(t *testing.T) {
+	for i, data := range testData {
+		t.Logf("test %v. %v", i, data.kind)
+		block, rest := pem.Decode(data.pemData)
+		if len(rest) > 0 {
+			t.Error("extra data")
+		}
+		der, err := DecryptPEMBlock(block, data.password)
+		if err != nil {
+			t.Error("decrypt failed: ", err)
+			continue
+		}
+		if _, err := ParsePKCS1PrivateKey(der); err != nil {
+			t.Error("invalid private key: ", err)
+		}
+		plainDER, err := base64.StdEncoding.DecodeString(data.plainDER)
+		if err != nil {
+			t.Fatal("cannot decode test DER data: ", err)
+		}
+		if !bytes.Equal(der, plainDER) {
+			t.Error("data mismatch")
+		}
+	}
+}
+
+func TestEncrypt(t *testing.T) {
+	for i, data := range testData {
+		t.Logf("test %v. %v", i, data.kind)
+		plainDER, err := base64.StdEncoding.DecodeString(data.plainDER)
+		if err != nil {
+			t.Fatal("cannot decode test DER data: ", err)
+		}
+		password := []byte("kremvax1")
+		block, err := EncryptPEMBlock(rand.Reader, "RSA PRIVATE KEY", plainDER, password, data.kind)
+		if err != nil {
+			t.Error("encrypt: ", err)
+			continue
+		}
+		if !IsEncryptedPEMBlock(block) {
+			t.Error("PEM block does not appear to be encrypted")
+		}
+		if block.Type != "RSA PRIVATE KEY" {
+			t.Errorf("unexpected block type; got %q want %q", block.Type, "RSA PRIVATE KEY")
+		}
+		if block.Headers["Proc-Type"] != "4,ENCRYPTED" {
+			t.Errorf("block does not have correct Proc-Type header")
+		}
+		der, err := DecryptPEMBlock(block, password)
+		if err != nil {
+			t.Error("decrypt: ", err)
+			continue
+		}
+		if !bytes.Equal(der, plainDER) {
+			t.Errorf("data mismatch")
+		}
+	}
+}
+
+var testData = []struct {
+	kind     PEMCipher
+	password []byte
+	pemData  []byte
+	plainDER string
+}{
+	{
+		kind:     PEMCipherDES,
+		password: []byte("asdf"),
+		pemData: []byte(`
+-----BEGIN RSA PRIVATE KEY-----
+Proc-Type: 4,ENCRYPTED
+DEK-Info: DES-CBC,34F09A4FC8DE22B5
+
+WXxy8kbZdiZvANtKvhmPBLV7eVFj2A5z6oAxvI9KGyhG0ZK0skfnt00C24vfU7m5
+ICXeoqP67lzJ18xCzQfHjDaBNs53DSDT+Iz4e8QUep1xQ30+8QKX2NA2coee3nwc
+6oM1cuvhNUDemBH2i3dKgMVkfaga0zQiiOq6HJyGSncCMSruQ7F9iWEfRbFcxFCx
+qtHb1kirfGKEtgWTF+ynyco6+2gMXNu70L7nJcnxnV/RLFkHt7AUU1yrclxz7eZz
+XOH9VfTjb52q/I8Suozq9coVQwg4tXfIoYUdT//O+mB7zJb9HI9Ps77b9TxDE6Gm
+4C9brwZ3zg2vqXcwwV6QRZMtyll9rOpxkbw6NPlpfBqkc3xS51bbxivbO/Nve4KD
+r12ymjFNF4stXCfJnNqKoZ50BHmEEUDu5Wb0fpVn82XrGw7CYc4iug==
+-----END RSA PRIVATE KEY-----`),
+		plainDER: `
+MIIBPAIBAAJBAPASZe+tCPU6p80AjHhDkVsLYa51D35e/YGa8QcZyooeZM8EHozo
+KD0fNiKI+53bHdy07N+81VQ8/ejPcRoXPlsCAwEAAQJBAMTxIuSq27VpR+zZ7WJf
+c6fvv1OBvpMZ0/d1pxL/KnOAgq2rD5hDtk9b0LGhTPgQAmrrMTKuSeGoIuYE+gKQ
+QvkCIQD+GC1m+/do+QRurr0uo46Kx1LzLeSCrjBk34wiOp2+dwIhAPHfTLRXS2fv
+7rljm0bYa4+eDZpz+E8RcXEgzhhvcQQ9AiAI5eHZJGOyml3MXnQjiPi55WcDOw0w
+glcRgT6QCEtz2wIhANSyqaFtosIkHKqrDUGfz/bb5tqMYTAnBruVPaf/WEOBAiEA
+9xORWeRG1tRpso4+dYy4KdDkuLPIO01KY6neYGm3BCM=`,
+	},
+	{
+		kind:     PEMCipher3DES,
+		password: []byte("asdf"),
+		pemData: []byte(`
+-----BEGIN RSA PRIVATE KEY-----
+Proc-Type: 4,ENCRYPTED
+DEK-Info: DES-EDE3-CBC,C1F4A6A03682C2C7
+
+0JqVdBEH6iqM7drTkj+e2W/bE3LqakaiWhb9WUVonFkhyu8ca/QzebY3b5gCvAZQ
+YwBvDcT/GHospKqPx+cxDHJNsUASDZws6bz8ZXWJGwZGExKzr0+Qx5fgXn44Ms3x
+8g1ENFuTXtxo+KoNK0zuAMAqp66Llcds3Fjl4XR18QaD0CrVNAfOdgATWZm5GJxk
+Fgx5f84nT+/ovvreG+xeOzWgvtKo0UUZVrhGOgfKLpa57adumcJ6SkUuBtEFpZFB
+ldw5w7WC7d13x2LsRkwo8ZrDKgIV+Y9GNvhuCCkTzNP0V3gNeJpd201HZHR+9n3w
+3z0VjR/MGqsfcy1ziEWMNOO53At3zlG6zP05aHMnMcZoVXadEK6L1gz++inSSDCq
+gI0UJP4e3JVB7AkgYymYAwiYALAkoEIuanxoc50njJk=
+-----END RSA PRIVATE KEY-----`),
+		plainDER: `
+MIIBOwIBAAJBANOCXKdoNS/iP/MAbl9cf1/SF3P+Ns7ZeNL27CfmDh0O6Zduaax5
+NBiumd2PmjkaCu7lQ5JOibHfWn+xJsc3kw0CAwEAAQJANX/W8d1Q/sCqzkuAn4xl
+B5a7qfJWaLHndu1QRLNTRJPn0Ee7OKJ4H0QKOhQM6vpjRrz+P2u9thn6wUxoPsef
+QQIhAP/jCkfejFcy4v15beqKzwz08/tslVjF+Yq41eJGejmxAiEA05pMoqfkyjcx
+fyvGhpoOyoCp71vSGUfR2I9CR65oKh0CIC1Msjs66LlfJtQctRq6bCEtFCxEcsP+
+eEjYo/Sk6WphAiEAxpgWPMJeU/shFT28gS+tmhjPZLpEoT1qkVlC14u0b3ECIQDX
+tZZZxCtPAm7shftEib0VU77Lk8MsXJcx2C4voRsjEw==`,
+	},
+	{
+		kind:     PEMCipherAES128,
+		password: []byte("asdf"),
+		pemData: []byte(`
+-----BEGIN RSA PRIVATE KEY-----
+Proc-Type: 4,ENCRYPTED
+DEK-Info: AES-128-CBC,D4492E793FC835CC038A728ED174F78A
+
+EyfQSzXSjv6BaNH+NHdXRlkHdimpF9izWlugVJAPApgXrq5YldPe2aGIOFXyJ+QE
+ZIG20DYqaPzJRjTEbPNZ6Es0S2JJ5yCpKxwJuDkgJZKtF39Q2i36JeGbSZQIuWJE
+GZbBpf1jDH/pr0iGonuAdl2PCCZUiy+8eLsD2tyviHUkFLOB+ykYoJ5t8ngZ/B6D
+33U43LLb7+9zD4y3Q9OVHqBFGyHcxCY9+9Qh4ZnFp7DTf6RY5TNEvE3s4g6aDpBs
+3NbvRVvYTgs8K9EPk4K+5R+P2kD8J8KvEIGxVa1vz8QoCJ/jr7Ka2rvNgPCex5/E
+080LzLHPCrXKdlr/f50yhNWq08ZxMWQFkui+FDHPDUaEELKAXV8/5PDxw80Rtybo
+AVYoCVIbZXZCuCO81op8UcOgEpTtyU5Lgh3Mw5scQL0=
+-----END RSA PRIVATE KEY-----`),
+		plainDER: `
+MIIBOgIBAAJBAMBlj5FxYtqbcy8wY89d/S7n0+r5MzD9F63BA/Lpl78vQKtdJ5dT
+cDGh/rBt1ufRrNp0WihcmZi7Mpl/3jHjiWECAwEAAQJABNOHYnKhtDIqFYj1OAJ3
+k3GlU0OlERmIOoeY/cL2V4lgwllPBEs7r134AY4wMmZSBUj8UR/O4SNO668ElKPE
+cQIhAOuqY7/115x5KCdGDMWi+jNaMxIvI4ETGwV40ykGzqlzAiEA0P9oEC3m9tHB
+kbpjSTxaNkrXxDgdEOZz8X0uOUUwHNsCIAwzcSCiGLyYJTULUmP1ESERfW1mlV78
+XzzESaJpIM/zAiBQkSTcl9VhcJreQqvjn5BnPZLP4ZHS4gPwJAGdsj5J4QIhAOVR
+B3WlRNTXR2WsJ5JdByezg9xzdXzULqmga0OE339a`,
+	},
+	{
+		kind:     PEMCipherAES192,
+		password: []byte("asdf"),
+		pemData: []byte(`
+-----BEGIN RSA PRIVATE KEY-----
+Proc-Type: 4,ENCRYPTED
+DEK-Info: AES-192-CBC,E2C9FB02BCA23ADE1829F8D8BC5F5369
+
+cqVslvHqDDM6qwU6YjezCRifXmKsrgEev7ng6Qs7UmDJOpHDgJQZI9fwMFUhIyn5
+FbCu1SHkLMW52Ld3CuEqMnzWMlhPrW8tFvUOrMWPYSisv7nNq88HobZEJcUNL2MM
+Y15XmHW6IJwPqhKyLHpWXyOCVEh4ODND2nV15PCoi18oTa475baxSk7+1qH7GuIs
+Rb7tshNTMqHbCpyo9Rn3UxeFIf9efdl8YLiMoIqc7J8E5e9VlbeQSdLMQOgDAQJG
+ReUtTw8exmKsY4gsSjhkg5uiw7/ZB1Ihto0qnfQJgjGc680qGkT1d6JfvOfeYAk6
+xn5RqS/h8rYAYm64KnepfC9vIujo4NqpaREDmaLdX5MJPQ+SlytITQvgUsUq3q/t
+Ss85xjQEZH3hzwjQqdJvmA4hYP6SUjxYpBM+02xZ1Xw=
+-----END RSA PRIVATE KEY-----`),
+		plainDER: `
+MIIBOwIBAAJBAMGcRrZiNNmtF20zyS6MQ7pdGx17aFDl+lTl+qnLuJRUCMUG05xs
+OmxmL/O1Qlf+bnqR8Bgg65SfKg21SYuLhiMCAwEAAQJBAL94uuHyO4wux2VC+qpj
+IzPykjdU7XRcDHbbvksf4xokSeUFjjD3PB0Qa83M94y89ZfdILIqS9x5EgSB4/lX
+qNkCIQD6cCIqLfzq/lYbZbQgAAjpBXeQVYsbvVtJrPrXJAlVVQIhAMXpDKMeFPMn
+J0g2rbx1gngx0qOa5r5iMU5w/noN4W2XAiBjf+WzCG5yFvazD+dOx3TC0A8+4x3P
+uZ3pWbaXf5PNuQIgAcdXarvhelH2w2piY1g3BPeFqhzBSCK/yLGxR82KIh8CIQDD
++qGKsd09NhQ/G27y/DARzOYtml1NvdmCQAgsDIIOLA==`,
+	},
+	{
+		kind:     PEMCipherAES256,
+		password: []byte("asdf"),
+		pemData: []byte(`
+-----BEGIN RSA PRIVATE KEY-----
+Proc-Type: 4,ENCRYPTED
+DEK-Info: AES-256-CBC,8E7ED5CD731902CE938957A886A5FFBD
+
+4Mxr+KIzRVwoOP0wwq6caSkvW0iS+GE2h2Ov/u+n9ZTMwL83PRnmjfjzBgfRZLVf
+JFPXxUK26kMNpIdssNnqGOds+DhB+oSrsNKoxgxSl5OBoYv9eJTVYm7qOyAFIsjr
+DRKAcjYCmzfesr7PVTowwy0RtHmYwyXMGDlAzzZrEvaiySFFmMyKKvtoavwaFoc7
+Pz3RZScwIuubzTGJ1x8EzdffYOsdCa9Mtgpp3L136+23dOd6L/qK2EG2fzrJSHs/
+2XugkleBFSMKzEp9mxXKRfa++uidQvMZTFLDK9w5YjrRvMBo/l2BoZIsq0jAIE1N
+sv5Z/KwlX+3MDEpPQpUwGPlGGdLnjI3UZ+cjgqBcoMiNc6HfgbBgYJSU6aDSHuCk
+clCwByxWkBNgJ2GrkwNrF26v+bGJJJNR4SKouY1jQf0=
+-----END RSA PRIVATE KEY-----`),
+		plainDER: `
+MIIBOgIBAAJBAKy3GFkstoCHIEeUU/qO8207m8WSrjksR+p9B4tf1w5k+2O1V/GY
+AQ5WFCApItcOkQe/I0yZZJk/PmCqMzSxrc8CAwEAAQJAOCAz0F7AW9oNelVQSP8F
+Sfzx7O1yom+qWyAQQJF/gFR11gpf9xpVnnyu1WxIRnDUh1LZwUsjwlDYb7MB74id
+oQIhANPcOiLwOPT4sIUpRM5HG6BF1BI7L77VpyGVk8xNP7X/AiEA0LMHZtk4I+lJ
+nClgYp4Yh2JZ1Znbu7IoQMCEJCjwKDECIGd8Dzm5tViTkUW6Hs3Tlf73nNs65duF
+aRnSglss8I3pAiEAonEnKruawgD8RavDFR+fUgmQiPz4FnGGeVgfwpGG1JECIBYq
+PXHYtPqxQIbD2pScR5qum7iGUh11lEUPkmt+2uqS`,
+	},
+	{
+		// generated with:
+		// openssl genrsa -aes128 -passout pass:asdf -out server.orig.key 128
+		kind:     PEMCipherAES128,
+		password: []byte("asdf"),
+		pemData: []byte(`
+-----BEGIN RSA PRIVATE KEY-----
+Proc-Type: 4,ENCRYPTED
+DEK-Info: AES-128-CBC,74611ABC2571AF11B1BF9B69E62C89E7
+
+6ei/MlytjE0FFgZOGQ+jrwomKfpl8kdefeE0NSt/DMRrw8OacHAzBNi3pPEa0eX3
+eND9l7C9meCirWovjj9QWVHrXyugFuDIqgdhQ8iHTgCfF3lrmcttVrbIfMDw+smD
+hTP8O1mS/MHl92NE0nhv0w==
+-----END RSA PRIVATE KEY-----`),
+		plainDER: `
+MGMCAQACEQC6ssxmYuauuHGOCDAI54RdAgMBAAECEQCWIn6Yv2O+kBcDF7STctKB
+AgkA8SEfu/2i3g0CCQDGNlXbBHX7kQIIK3Ww5o0cYbECCQDCimPb0dYGsQIIeQ7A
+jryIst8=`,
+	},
+}
diff --git a/src/pkg/crypto/x509/pkcs1.go b/src/crypto/x509/pkcs1.go
similarity index 100%
rename from src/pkg/crypto/x509/pkcs1.go
rename to src/crypto/x509/pkcs1.go
diff --git a/src/pkg/crypto/x509/pkcs8.go b/src/crypto/x509/pkcs8.go
similarity index 100%
rename from src/pkg/crypto/x509/pkcs8.go
rename to src/crypto/x509/pkcs8.go
diff --git a/src/pkg/crypto/x509/pkcs8_test.go b/src/crypto/x509/pkcs8_test.go
similarity index 100%
rename from src/pkg/crypto/x509/pkcs8_test.go
rename to src/crypto/x509/pkcs8_test.go
diff --git a/src/crypto/x509/pkix/pkix.go b/src/crypto/x509/pkix/pkix.go
new file mode 100644
index 0000000..8768b78
--- /dev/null
+++ b/src/crypto/x509/pkix/pkix.go
@@ -0,0 +1,178 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package pkix contains shared, low level structures used for ASN.1 parsing
+// and serialization of X.509 certificates, CRL and OCSP.
+package pkix
+
+import (
+	"encoding/asn1"
+	"math/big"
+	"time"
+)
+
+// AlgorithmIdentifier represents the ASN.1 structure of the same name. See RFC
+// 5280, section 4.1.1.2.
+type AlgorithmIdentifier struct {
+	Algorithm  asn1.ObjectIdentifier
+	Parameters asn1.RawValue `asn1:"optional"`
+}
+
+type RDNSequence []RelativeDistinguishedNameSET
+
+type RelativeDistinguishedNameSET []AttributeTypeAndValue
+
+// AttributeTypeAndValue mirrors the ASN.1 structure of the same name in
+// http://tools.ietf.org/html/rfc5280#section-4.1.2.4
+type AttributeTypeAndValue struct {
+	Type  asn1.ObjectIdentifier
+	Value interface{}
+}
+
+// AttributeTypeAndValueSET represents a set of ASN.1 sequences of
+// AttributeTypeAndValue sequences from RFC 2986 (PKCS #10).
+type AttributeTypeAndValueSET struct {
+	Type  asn1.ObjectIdentifier
+	Value [][]AttributeTypeAndValue `asn1:"set"`
+}
+
+// Extension represents the ASN.1 structure of the same name. See RFC
+// 5280, section 4.2.
+type Extension struct {
+	Id       asn1.ObjectIdentifier
+	Critical bool `asn1:"optional"`
+	Value    []byte
+}
+
+// Name represents an X.509 distinguished name. This only includes the common
+// elements of a DN.  Additional elements in the name are ignored.
+type Name struct {
+	Country, Organization, OrganizationalUnit []string
+	Locality, Province                        []string
+	StreetAddress, PostalCode                 []string
+	SerialNumber, CommonName                  string
+
+	Names []AttributeTypeAndValue
+}
+
+func (n *Name) FillFromRDNSequence(rdns *RDNSequence) {
+	for _, rdn := range *rdns {
+		if len(rdn) == 0 {
+			continue
+		}
+		atv := rdn[0]
+		n.Names = append(n.Names, atv)
+		value, ok := atv.Value.(string)
+		if !ok {
+			continue
+		}
+
+		t := atv.Type
+		if len(t) == 4 && t[0] == 2 && t[1] == 5 && t[2] == 4 {
+			switch t[3] {
+			case 3:
+				n.CommonName = value
+			case 5:
+				n.SerialNumber = value
+			case 6:
+				n.Country = append(n.Country, value)
+			case 7:
+				n.Locality = append(n.Locality, value)
+			case 8:
+				n.Province = append(n.Province, value)
+			case 9:
+				n.StreetAddress = append(n.StreetAddress, value)
+			case 10:
+				n.Organization = append(n.Organization, value)
+			case 11:
+				n.OrganizationalUnit = append(n.OrganizationalUnit, value)
+			case 17:
+				n.PostalCode = append(n.PostalCode, value)
+			}
+		}
+	}
+}
+
+var (
+	oidCountry            = []int{2, 5, 4, 6}
+	oidOrganization       = []int{2, 5, 4, 10}
+	oidOrganizationalUnit = []int{2, 5, 4, 11}
+	oidCommonName         = []int{2, 5, 4, 3}
+	oidSerialNumber       = []int{2, 5, 4, 5}
+	oidLocality           = []int{2, 5, 4, 7}
+	oidProvince           = []int{2, 5, 4, 8}
+	oidStreetAddress      = []int{2, 5, 4, 9}
+	oidPostalCode         = []int{2, 5, 4, 17}
+)
+
+// appendRDNs appends a relativeDistinguishedNameSET to the given RDNSequence
+// and returns the new value. The relativeDistinguishedNameSET contains an
+// attributeTypeAndValue for each of the given values. See RFC 5280, A.1, and
+// search for AttributeTypeAndValue.
+func appendRDNs(in RDNSequence, values []string, oid asn1.ObjectIdentifier) RDNSequence {
+	if len(values) == 0 {
+		return in
+	}
+
+	s := make([]AttributeTypeAndValue, len(values))
+	for i, value := range values {
+		s[i].Type = oid
+		s[i].Value = value
+	}
+
+	return append(in, s)
+}
+
+func (n Name) ToRDNSequence() (ret RDNSequence) {
+	ret = appendRDNs(ret, n.Country, oidCountry)
+	ret = appendRDNs(ret, n.Organization, oidOrganization)
+	ret = appendRDNs(ret, n.OrganizationalUnit, oidOrganizationalUnit)
+	ret = appendRDNs(ret, n.Locality, oidLocality)
+	ret = appendRDNs(ret, n.Province, oidProvince)
+	ret = appendRDNs(ret, n.StreetAddress, oidStreetAddress)
+	ret = appendRDNs(ret, n.PostalCode, oidPostalCode)
+	if len(n.CommonName) > 0 {
+		ret = appendRDNs(ret, []string{n.CommonName}, oidCommonName)
+	}
+	if len(n.SerialNumber) > 0 {
+		ret = appendRDNs(ret, []string{n.SerialNumber}, oidSerialNumber)
+	}
+
+	return ret
+}
+
+// CertificateList represents the ASN.1 structure of the same name. See RFC
+// 5280, section 5.1. Use Certificate.CheckCRLSignature to verify the
+// signature.
+type CertificateList struct {
+	TBSCertList        TBSCertificateList
+	SignatureAlgorithm AlgorithmIdentifier
+	SignatureValue     asn1.BitString
+}
+
+// HasExpired reports whether now is past the expiry time of certList.
+func (certList *CertificateList) HasExpired(now time.Time) bool {
+	return now.After(certList.TBSCertList.NextUpdate)
+}
+
+// TBSCertificateList represents the ASN.1 structure of the same name. See RFC
+// 5280, section 5.1.
+type TBSCertificateList struct {
+	Raw                 asn1.RawContent
+	Version             int `asn1:"optional,default:2"`
+	Signature           AlgorithmIdentifier
+	Issuer              RDNSequence
+	ThisUpdate          time.Time
+	NextUpdate          time.Time            `asn1:"optional"`
+	RevokedCertificates []RevokedCertificate `asn1:"optional"`
+	Extensions          []Extension          `asn1:"tag:0,optional,explicit"`
+}
+
+// RevokedCertificate represents the ASN.1 structure of the same name. See RFC
+// 5280, section 5.1.
+type RevokedCertificate struct {
+	SerialNumber   *big.Int
+	RevocationTime time.Time
+	Extensions     []Extension `asn1:"optional"`
+}
diff --git a/src/pkg/crypto/x509/root.go b/src/crypto/x509/root.go
similarity index 100%
rename from src/pkg/crypto/x509/root.go
rename to src/crypto/x509/root.go
diff --git a/src/pkg/crypto/x509/root_cgo_darwin.go b/src/crypto/x509/root_cgo_darwin.go
similarity index 100%
rename from src/pkg/crypto/x509/root_cgo_darwin.go
rename to src/crypto/x509/root_cgo_darwin.go
diff --git a/src/pkg/crypto/x509/root_darwin.go b/src/crypto/x509/root_darwin.go
similarity index 100%
rename from src/pkg/crypto/x509/root_darwin.go
rename to src/crypto/x509/root_darwin.go
diff --git a/src/pkg/crypto/x509/root_darwin_test.go b/src/crypto/x509/root_darwin_test.go
similarity index 100%
rename from src/pkg/crypto/x509/root_darwin_test.go
rename to src/crypto/x509/root_darwin_test.go
diff --git a/src/pkg/crypto/x509/root_nocgo_darwin.go b/src/crypto/x509/root_nocgo_darwin.go
similarity index 100%
rename from src/pkg/crypto/x509/root_nocgo_darwin.go
rename to src/crypto/x509/root_nocgo_darwin.go
diff --git a/src/pkg/crypto/x509/root_plan9.go b/src/crypto/x509/root_plan9.go
similarity index 100%
rename from src/pkg/crypto/x509/root_plan9.go
rename to src/crypto/x509/root_plan9.go
diff --git a/src/crypto/x509/root_unix.go b/src/crypto/x509/root_unix.go
new file mode 100644
index 0000000..f77d6c0
--- /dev/null
+++ b/src/crypto/x509/root_unix.go
@@ -0,0 +1,64 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build dragonfly freebsd linux nacl netbsd openbsd solaris
+
+package x509
+
+import "io/ioutil"
+
+// Possible certificate files; stop after finding one.
+var certFiles = []string{
+	"/etc/ssl/certs/ca-certificates.crt",     // Debian/Ubuntu/Gentoo etc.
+	"/etc/pki/tls/certs/ca-bundle.crt",       // Fedora/RHEL
+	"/etc/ssl/ca-bundle.pem",                 // OpenSUSE
+	"/etc/ssl/cert.pem",                      // OpenBSD
+	"/usr/local/share/certs/ca-root-nss.crt", // FreeBSD/DragonFly
+	"/etc/pki/tls/cacert.pem",                // OpenELEC
+	"/etc/certs/ca-certificates.crt",         // Solaris 11.2+
+}
+
+// Possible directories with certificate files; stop after successfully
+// reading at least one file from a directory.
+var certDirectories = []string{
+	"/system/etc/security/cacerts", // Android
+
+}
+
+func (c *Certificate) systemVerify(opts *VerifyOptions) (chains [][]*Certificate, err error) {
+	return nil, nil
+}
+
+func initSystemRoots() {
+	roots := NewCertPool()
+	for _, file := range certFiles {
+		data, err := ioutil.ReadFile(file)
+		if err == nil {
+			roots.AppendCertsFromPEM(data)
+			systemRoots = roots
+			return
+		}
+	}
+
+	for _, directory := range certDirectories {
+		fis, err := ioutil.ReadDir(directory)
+		if err != nil {
+			continue
+		}
+		rootsAdded := false
+		for _, fi := range fis {
+			data, err := ioutil.ReadFile(directory + "/" + fi.Name())
+			if err == nil && roots.AppendCertsFromPEM(data) {
+				rootsAdded = true
+			}
+		}
+		if rootsAdded {
+			systemRoots = roots
+			return
+		}
+	}
+
+	// All of the files failed to load. systemRoots will be nil which will
+	// trigger a specific error at verification time.
+}
diff --git a/src/pkg/crypto/x509/root_windows.go b/src/crypto/x509/root_windows.go
similarity index 100%
rename from src/pkg/crypto/x509/root_windows.go
rename to src/crypto/x509/root_windows.go
diff --git a/src/pkg/crypto/x509/sec1.go b/src/crypto/x509/sec1.go
similarity index 100%
rename from src/pkg/crypto/x509/sec1.go
rename to src/crypto/x509/sec1.go
diff --git a/src/pkg/crypto/x509/sec1_test.go b/src/crypto/x509/sec1_test.go
similarity index 100%
rename from src/pkg/crypto/x509/sec1_test.go
rename to src/crypto/x509/sec1_test.go
diff --git a/src/crypto/x509/verify.go b/src/crypto/x509/verify.go
new file mode 100644
index 0000000..ec19814
--- /dev/null
+++ b/src/crypto/x509/verify.go
@@ -0,0 +1,476 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package x509
+
+import (
+	"fmt"
+	"net"
+	"runtime"
+	"strings"
+	"time"
+	"unicode/utf8"
+)
+
+type InvalidReason int
+
+const (
+	// NotAuthorizedToSign results when a certificate is signed by another
+	// which isn't marked as a CA certificate.
+	NotAuthorizedToSign InvalidReason = iota
+	// Expired results when a certificate has expired, based on the time
+	// given in the VerifyOptions.
+	Expired
+	// CANotAuthorizedForThisName results when an intermediate or root
+	// certificate has a name constraint which doesn't include the name
+	// being checked.
+	CANotAuthorizedForThisName
+	// TooManyIntermediates results when a path length constraint is
+	// violated.
+	TooManyIntermediates
+	// IncompatibleUsage results when the certificate's key usage indicates
+	// that it may only be used for a different purpose.
+	IncompatibleUsage
+)
+
+// CertificateInvalidError results when an odd error occurs. Users of this
+// library probably want to handle all these errors uniformly.
+type CertificateInvalidError struct {
+	Cert   *Certificate
+	Reason InvalidReason
+}
+
+func (e CertificateInvalidError) Error() string {
+	switch e.Reason {
+	case NotAuthorizedToSign:
+		return "x509: certificate is not authorized to sign other certificates"
+	case Expired:
+		return "x509: certificate has expired or is not yet valid"
+	case CANotAuthorizedForThisName:
+		return "x509: a root or intermediate certificate is not authorized to sign in this domain"
+	case TooManyIntermediates:
+		return "x509: too many intermediates for path length constraint"
+	case IncompatibleUsage:
+		return "x509: certificate specifies an incompatible key usage"
+	}
+	return "x509: unknown error"
+}
+
+// HostnameError results when the set of authorized names doesn't match the
+// requested name.
+type HostnameError struct {
+	Certificate *Certificate
+	Host        string
+}
+
+func (h HostnameError) Error() string {
+	c := h.Certificate
+
+	var valid string
+	if ip := net.ParseIP(h.Host); ip != nil {
+		// Trying to validate an IP
+		if len(c.IPAddresses) == 0 {
+			return "x509: cannot validate certificate for " + h.Host + " because it doesn't contain any IP SANs"
+		}
+		for _, san := range c.IPAddresses {
+			if len(valid) > 0 {
+				valid += ", "
+			}
+			valid += san.String()
+		}
+	} else {
+		if len(c.DNSNames) > 0 {
+			valid = strings.Join(c.DNSNames, ", ")
+		} else {
+			valid = c.Subject.CommonName
+		}
+	}
+	return "x509: certificate is valid for " + valid + ", not " + h.Host
+}
+
+// UnknownAuthorityError results when the certificate issuer is unknown
+type UnknownAuthorityError struct {
+	cert *Certificate
+	// hintErr contains an error that may be helpful in determining why an
+	// authority wasn't found.
+	hintErr error
+	// hintCert contains a possible authority certificate that was rejected
+	// because of the error in hintErr.
+	hintCert *Certificate
+}
+
+func (e UnknownAuthorityError) Error() string {
+	s := "x509: certificate signed by unknown authority"
+	if e.hintErr != nil {
+		certName := e.hintCert.Subject.CommonName
+		if len(certName) == 0 {
+			if len(e.hintCert.Subject.Organization) > 0 {
+				certName = e.hintCert.Subject.Organization[0]
+			}
+			certName = "serial:" + e.hintCert.SerialNumber.String()
+		}
+		s += fmt.Sprintf(" (possibly because of %q while trying to verify candidate authority certificate %q)", e.hintErr, certName)
+	}
+	return s
+}
+
+// SystemRootsError results when we fail to load the system root certificates.
+type SystemRootsError struct{}
+
+func (SystemRootsError) Error() string {
+	return "x509: failed to load system roots and no roots provided"
+}
+
+// VerifyOptions contains parameters for Certificate.Verify. It's a structure
+// because other PKIX verification APIs have ended up needing many options.
+type VerifyOptions struct {
+	DNSName       string
+	Intermediates *CertPool
+	Roots         *CertPool // if nil, the system roots are used
+	CurrentTime   time.Time // if zero, the current time is used
+	// KeyUsage specifies which Extended Key Usage values are acceptable.
+	// An empty list means ExtKeyUsageServerAuth. Key usage is considered a
+	// constraint down the chain which mirrors Windows CryptoAPI behaviour,
+	// but not the spec. To accept any key usage, include ExtKeyUsageAny.
+	KeyUsages []ExtKeyUsage
+}
+
+const (
+	leafCertificate = iota
+	intermediateCertificate
+	rootCertificate
+)
+
+// isValid performs validity checks on the c.
+func (c *Certificate) isValid(certType int, currentChain []*Certificate, opts *VerifyOptions) error {
+	now := opts.CurrentTime
+	if now.IsZero() {
+		now = time.Now()
+	}
+	if now.Before(c.NotBefore) || now.After(c.NotAfter) {
+		return CertificateInvalidError{c, Expired}
+	}
+
+	if len(c.PermittedDNSDomains) > 0 {
+		ok := false
+		for _, domain := range c.PermittedDNSDomains {
+			if opts.DNSName == domain ||
+				(strings.HasSuffix(opts.DNSName, domain) &&
+					len(opts.DNSName) >= 1+len(domain) &&
+					opts.DNSName[len(opts.DNSName)-len(domain)-1] == '.') {
+				ok = true
+				break
+			}
+		}
+
+		if !ok {
+			return CertificateInvalidError{c, CANotAuthorizedForThisName}
+		}
+	}
+
+	// KeyUsage status flags are ignored. From Engineering Security, Peter
+	// Gutmann: A European government CA marked its signing certificates as
+	// being valid for encryption only, but no-one noticed. Another
+	// European CA marked its signature keys as not being valid for
+	// signatures. A different CA marked its own trusted root certificate
+	// as being invalid for certificate signing.  Another national CA
+	// distributed a certificate to be used to encrypt data for the
+	// country’s tax authority that was marked as only being usable for
+	// digital signatures but not for encryption. Yet another CA reversed
+	// the order of the bit flags in the keyUsage due to confusion over
+	// encoding endianness, essentially setting a random keyUsage in
+	// certificates that it issued. Another CA created a self-invalidating
+	// certificate by adding a certificate policy statement stipulating
+	// that the certificate had to be used strictly as specified in the
+	// keyUsage, and a keyUsage containing a flag indicating that the RSA
+	// encryption key could only be used for Diffie-Hellman key agreement.
+
+	if certType == intermediateCertificate && (!c.BasicConstraintsValid || !c.IsCA) {
+		return CertificateInvalidError{c, NotAuthorizedToSign}
+	}
+
+	if c.BasicConstraintsValid && c.MaxPathLen >= 0 {
+		numIntermediates := len(currentChain) - 1
+		if numIntermediates > c.MaxPathLen {
+			return CertificateInvalidError{c, TooManyIntermediates}
+		}
+	}
+
+	return nil
+}
+
+// Verify attempts to verify c by building one or more chains from c to a
+// certificate in opts.Roots, using certificates in opts.Intermediates if
+// needed. If successful, it returns one or more chains where the first
+// element of the chain is c and the last element is from opts.Roots.
+//
+// If opts.Roots is nil and system roots are unavailable the returned error
+// will be of type SystemRootsError.
+//
+// WARNING: this doesn't do any revocation checking.
+func (c *Certificate) Verify(opts VerifyOptions) (chains [][]*Certificate, err error) {
+	// Use Windows's own verification and chain building.
+	if opts.Roots == nil && runtime.GOOS == "windows" {
+		return c.systemVerify(&opts)
+	}
+
+	if opts.Roots == nil {
+		opts.Roots = systemRootsPool()
+		if opts.Roots == nil {
+			return nil, SystemRootsError{}
+		}
+	}
+
+	err = c.isValid(leafCertificate, nil, &opts)
+	if err != nil {
+		return
+	}
+
+	if len(opts.DNSName) > 0 {
+		err = c.VerifyHostname(opts.DNSName)
+		if err != nil {
+			return
+		}
+	}
+
+	candidateChains, err := c.buildChains(make(map[int][][]*Certificate), []*Certificate{c}, &opts)
+	if err != nil {
+		return
+	}
+
+	keyUsages := opts.KeyUsages
+	if len(keyUsages) == 0 {
+		keyUsages = []ExtKeyUsage{ExtKeyUsageServerAuth}
+	}
+
+	// If any key usage is acceptable then we're done.
+	for _, usage := range keyUsages {
+		if usage == ExtKeyUsageAny {
+			chains = candidateChains
+			return
+		}
+	}
+
+	for _, candidate := range candidateChains {
+		if checkChainForKeyUsage(candidate, keyUsages) {
+			chains = append(chains, candidate)
+		}
+	}
+
+	if len(chains) == 0 {
+		err = CertificateInvalidError{c, IncompatibleUsage}
+	}
+
+	return
+}
+
+func appendToFreshChain(chain []*Certificate, cert *Certificate) []*Certificate {
+	n := make([]*Certificate, len(chain)+1)
+	copy(n, chain)
+	n[len(chain)] = cert
+	return n
+}
+
+func (c *Certificate) buildChains(cache map[int][][]*Certificate, currentChain []*Certificate, opts *VerifyOptions) (chains [][]*Certificate, err error) {
+	possibleRoots, failedRoot, rootErr := opts.Roots.findVerifiedParents(c)
+	for _, rootNum := range possibleRoots {
+		root := opts.Roots.certs[rootNum]
+		err = root.isValid(rootCertificate, currentChain, opts)
+		if err != nil {
+			continue
+		}
+		chains = append(chains, appendToFreshChain(currentChain, root))
+	}
+
+	possibleIntermediates, failedIntermediate, intermediateErr := opts.Intermediates.findVerifiedParents(c)
+nextIntermediate:
+	for _, intermediateNum := range possibleIntermediates {
+		intermediate := opts.Intermediates.certs[intermediateNum]
+		for _, cert := range currentChain {
+			if cert == intermediate {
+				continue nextIntermediate
+			}
+		}
+		err = intermediate.isValid(intermediateCertificate, currentChain, opts)
+		if err != nil {
+			continue
+		}
+		var childChains [][]*Certificate
+		childChains, ok := cache[intermediateNum]
+		if !ok {
+			childChains, err = intermediate.buildChains(cache, appendToFreshChain(currentChain, intermediate), opts)
+			cache[intermediateNum] = childChains
+		}
+		chains = append(chains, childChains...)
+	}
+
+	if len(chains) > 0 {
+		err = nil
+	}
+
+	if len(chains) == 0 && err == nil {
+		hintErr := rootErr
+		hintCert := failedRoot
+		if hintErr == nil {
+			hintErr = intermediateErr
+			hintCert = failedIntermediate
+		}
+		err = UnknownAuthorityError{c, hintErr, hintCert}
+	}
+
+	return
+}
+
+func matchHostnames(pattern, host string) bool {
+	if len(pattern) == 0 || len(host) == 0 {
+		return false
+	}
+
+	patternParts := strings.Split(pattern, ".")
+	hostParts := strings.Split(host, ".")
+
+	if len(patternParts) != len(hostParts) {
+		return false
+	}
+
+	for i, patternPart := range patternParts {
+		if patternPart == "*" {
+			continue
+		}
+		if patternPart != hostParts[i] {
+			return false
+		}
+	}
+
+	return true
+}
+
+// toLowerCaseASCII returns a lower-case version of in. See RFC 6125 6.4.1. We use
+// an explicitly ASCII function to avoid any sharp corners resulting from
+// performing Unicode operations on DNS labels.
+func toLowerCaseASCII(in string) string {
+	// If the string is already lower-case then there's nothing to do.
+	isAlreadyLowerCase := true
+	for _, c := range in {
+		if c == utf8.RuneError {
+			// If we get a UTF-8 error then there might be
+			// upper-case ASCII bytes in the invalid sequence.
+			isAlreadyLowerCase = false
+			break
+		}
+		if 'A' <= c && c <= 'Z' {
+			isAlreadyLowerCase = false
+			break
+		}
+	}
+
+	if isAlreadyLowerCase {
+		return in
+	}
+
+	out := []byte(in)
+	for i, c := range out {
+		if 'A' <= c && c <= 'Z' {
+			out[i] += 'a' - 'A'
+		}
+	}
+	return string(out)
+}
+
+// VerifyHostname returns nil if c is a valid certificate for the named host.
+// Otherwise it returns an error describing the mismatch.
+func (c *Certificate) VerifyHostname(h string) error {
+	// IP addresses may be written in [ ].
+	candidateIP := h
+	if len(h) >= 3 && h[0] == '[' && h[len(h)-1] == ']' {
+		candidateIP = h[1 : len(h)-1]
+	}
+	if ip := net.ParseIP(candidateIP); ip != nil {
+		// We only match IP addresses against IP SANs.
+		// https://tools.ietf.org/html/rfc6125#appendix-B.2
+		for _, candidate := range c.IPAddresses {
+			if ip.Equal(candidate) {
+				return nil
+			}
+		}
+		return HostnameError{c, candidateIP}
+	}
+
+	lowered := toLowerCaseASCII(h)
+
+	if len(c.DNSNames) > 0 {
+		for _, match := range c.DNSNames {
+			if matchHostnames(toLowerCaseASCII(match), lowered) {
+				return nil
+			}
+		}
+		// If Subject Alt Name is given, we ignore the common name.
+	} else if matchHostnames(toLowerCaseASCII(c.Subject.CommonName), lowered) {
+		return nil
+	}
+
+	return HostnameError{c, h}
+}
+
+func checkChainForKeyUsage(chain []*Certificate, keyUsages []ExtKeyUsage) bool {
+	usages := make([]ExtKeyUsage, len(keyUsages))
+	copy(usages, keyUsages)
+
+	if len(chain) == 0 {
+		return false
+	}
+
+	usagesRemaining := len(usages)
+
+	// We walk down the list and cross out any usages that aren't supported
+	// by each certificate. If we cross out all the usages, then the chain
+	// is unacceptable.
+
+NextCert:
+	for i := len(chain) - 1; i >= 0; i-- {
+		cert := chain[i]
+		if len(cert.ExtKeyUsage) == 0 && len(cert.UnknownExtKeyUsage) == 0 {
+			// The certificate doesn't have any extended key usage specified.
+			continue
+		}
+
+		for _, usage := range cert.ExtKeyUsage {
+			if usage == ExtKeyUsageAny {
+				// The certificate is explicitly good for any usage.
+				continue NextCert
+			}
+		}
+
+		const invalidUsage ExtKeyUsage = -1
+
+	NextRequestedUsage:
+		for i, requestedUsage := range usages {
+			if requestedUsage == invalidUsage {
+				continue
+			}
+
+			for _, usage := range cert.ExtKeyUsage {
+				if requestedUsage == usage {
+					continue NextRequestedUsage
+				} else if requestedUsage == ExtKeyUsageServerAuth &&
+					(usage == ExtKeyUsageNetscapeServerGatedCrypto ||
+						usage == ExtKeyUsageMicrosoftServerGatedCrypto) {
+					// In order to support COMODO
+					// certificate chains, we have to
+					// accept Netscape or Microsoft SGC
+					// usages as equal to ServerAuth.
+					continue NextRequestedUsage
+				}
+			}
+
+			usages[i] = invalidUsage
+			usagesRemaining--
+			if usagesRemaining == 0 {
+				return false
+			}
+		}
+	}
+
+	return true
+}
diff --git a/src/pkg/crypto/x509/verify_test.go b/src/crypto/x509/verify_test.go
similarity index 100%
rename from src/pkg/crypto/x509/verify_test.go
rename to src/crypto/x509/verify_test.go
diff --git a/src/crypto/x509/x509.go b/src/crypto/x509/x509.go
new file mode 100644
index 0000000..7a37b98
--- /dev/null
+++ b/src/crypto/x509/x509.go
@@ -0,0 +1,1916 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package x509 parses X.509-encoded keys and certificates.
+package x509
+
+import (
+	"bytes"
+	"crypto"
+	"crypto/dsa"
+	"crypto/ecdsa"
+	"crypto/elliptic"
+	"crypto/rsa"
+	"crypto/sha1"
+	_ "crypto/sha256"
+	_ "crypto/sha512"
+	"crypto/x509/pkix"
+	"encoding/asn1"
+	"encoding/pem"
+	"errors"
+	"io"
+	"math/big"
+	"net"
+	"strconv"
+	"time"
+)
+
+// pkixPublicKey reflects a PKIX public key structure. See SubjectPublicKeyInfo
+// in RFC 3280.
+type pkixPublicKey struct {
+	Algo      pkix.AlgorithmIdentifier
+	BitString asn1.BitString
+}
+
+// ParsePKIXPublicKey parses a DER encoded public key. These values are
+// typically found in PEM blocks with "BEGIN PUBLIC KEY".
+func ParsePKIXPublicKey(derBytes []byte) (pub interface{}, err error) {
+	var pki publicKeyInfo
+	if _, err = asn1.Unmarshal(derBytes, &pki); err != nil {
+		return
+	}
+	algo := getPublicKeyAlgorithmFromOID(pki.Algorithm.Algorithm)
+	if algo == UnknownPublicKeyAlgorithm {
+		return nil, errors.New("x509: unknown public key algorithm")
+	}
+	return parsePublicKey(algo, &pki)
+}
+
+func marshalPublicKey(pub interface{}) (publicKeyBytes []byte, publicKeyAlgorithm pkix.AlgorithmIdentifier, err error) {
+	switch pub := pub.(type) {
+	case *rsa.PublicKey:
+		publicKeyBytes, err = asn1.Marshal(rsaPublicKey{
+			N: pub.N,
+			E: pub.E,
+		})
+		publicKeyAlgorithm.Algorithm = oidPublicKeyRSA
+		// This is a NULL parameters value which is technically
+		// superfluous, but most other code includes it and, by
+		// doing this, we match their public key hashes.
+		publicKeyAlgorithm.Parameters = asn1.RawValue{
+			Tag: 5,
+		}
+	case *ecdsa.PublicKey:
+		publicKeyBytes = elliptic.Marshal(pub.Curve, pub.X, pub.Y)
+		oid, ok := oidFromNamedCurve(pub.Curve)
+		if !ok {
+			return nil, pkix.AlgorithmIdentifier{}, errors.New("x509: unsupported elliptic curve")
+		}
+		publicKeyAlgorithm.Algorithm = oidPublicKeyECDSA
+		var paramBytes []byte
+		paramBytes, err = asn1.Marshal(oid)
+		if err != nil {
+			return
+		}
+		publicKeyAlgorithm.Parameters.FullBytes = paramBytes
+	default:
+		return nil, pkix.AlgorithmIdentifier{}, errors.New("x509: only RSA and ECDSA public keys supported")
+	}
+
+	return publicKeyBytes, publicKeyAlgorithm, nil
+}
+
+// MarshalPKIXPublicKey serialises a public key to DER-encoded PKIX format.
+func MarshalPKIXPublicKey(pub interface{}) ([]byte, error) {
+	var publicKeyBytes []byte
+	var publicKeyAlgorithm pkix.AlgorithmIdentifier
+	var err error
+
+	if publicKeyBytes, publicKeyAlgorithm, err = marshalPublicKey(pub); err != nil {
+		return nil, err
+	}
+
+	pkix := pkixPublicKey{
+		Algo: publicKeyAlgorithm,
+		BitString: asn1.BitString{
+			Bytes:     publicKeyBytes,
+			BitLength: 8 * len(publicKeyBytes),
+		},
+	}
+
+	ret, _ := asn1.Marshal(pkix)
+	return ret, nil
+}
+
+// These structures reflect the ASN.1 structure of X.509 certificates.:
+
+type certificate struct {
+	Raw                asn1.RawContent
+	TBSCertificate     tbsCertificate
+	SignatureAlgorithm pkix.AlgorithmIdentifier
+	SignatureValue     asn1.BitString
+}
+
+type tbsCertificate struct {
+	Raw                asn1.RawContent
+	Version            int `asn1:"optional,explicit,default:1,tag:0"`
+	SerialNumber       *big.Int
+	SignatureAlgorithm pkix.AlgorithmIdentifier
+	Issuer             asn1.RawValue
+	Validity           validity
+	Subject            asn1.RawValue
+	PublicKey          publicKeyInfo
+	UniqueId           asn1.BitString   `asn1:"optional,tag:1"`
+	SubjectUniqueId    asn1.BitString   `asn1:"optional,tag:2"`
+	Extensions         []pkix.Extension `asn1:"optional,explicit,tag:3"`
+}
+
+type dsaAlgorithmParameters struct {
+	P, Q, G *big.Int
+}
+
+type dsaSignature struct {
+	R, S *big.Int
+}
+
+type ecdsaSignature dsaSignature
+
+type validity struct {
+	NotBefore, NotAfter time.Time
+}
+
+type publicKeyInfo struct {
+	Raw       asn1.RawContent
+	Algorithm pkix.AlgorithmIdentifier
+	PublicKey asn1.BitString
+}
+
+// RFC 5280,  4.2.1.1
+type authKeyId struct {
+	Id []byte `asn1:"optional,tag:0"`
+}
+
+type SignatureAlgorithm int
+
+const (
+	UnknownSignatureAlgorithm SignatureAlgorithm = iota
+	MD2WithRSA
+	MD5WithRSA
+	SHA1WithRSA
+	SHA256WithRSA
+	SHA384WithRSA
+	SHA512WithRSA
+	DSAWithSHA1
+	DSAWithSHA256
+	ECDSAWithSHA1
+	ECDSAWithSHA256
+	ECDSAWithSHA384
+	ECDSAWithSHA512
+)
+
+type PublicKeyAlgorithm int
+
+const (
+	UnknownPublicKeyAlgorithm PublicKeyAlgorithm = iota
+	RSA
+	DSA
+	ECDSA
+)
+
+// OIDs for signature algorithms
+//
+// pkcs-1 OBJECT IDENTIFIER ::= {
+//    iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 1 }
+//
+//
+// RFC 3279 2.2.1 RSA Signature Algorithms
+//
+// md2WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 2 }
+//
+// md5WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 4 }
+//
+// sha-1WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 5 }
+//
+// dsaWithSha1 OBJECT IDENTIFIER ::= {
+//    iso(1) member-body(2) us(840) x9-57(10040) x9cm(4) 3 }
+//
+// RFC 3279 2.2.3 ECDSA Signature Algorithm
+//
+// ecdsa-with-SHA1 OBJECT IDENTIFIER ::= {
+// 	  iso(1) member-body(2) us(840) ansi-x962(10045)
+//    signatures(4) ecdsa-with-SHA1(1)}
+//
+//
+// RFC 4055 5 PKCS #1 Version 1.5
+//
+// sha256WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 11 }
+//
+// sha384WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 12 }
+//
+// sha512WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 13 }
+//
+//
+// RFC 5758 3.1 DSA Signature Algorithms
+//
+// dsaWithSha256 OBJECT IDENTIFIER ::= {
+//    joint-iso-ccitt(2) country(16) us(840) organization(1) gov(101)
+//    csor(3) algorithms(4) id-dsa-with-sha2(3) 2}
+//
+// RFC 5758 3.2 ECDSA Signature Algorithm
+//
+// ecdsa-with-SHA256 OBJECT IDENTIFIER ::= { iso(1) member-body(2)
+//    us(840) ansi-X9-62(10045) signatures(4) ecdsa-with-SHA2(3) 2 }
+//
+// ecdsa-with-SHA384 OBJECT IDENTIFIER ::= { iso(1) member-body(2)
+//    us(840) ansi-X9-62(10045) signatures(4) ecdsa-with-SHA2(3) 3 }
+//
+// ecdsa-with-SHA512 OBJECT IDENTIFIER ::= { iso(1) member-body(2)
+//    us(840) ansi-X9-62(10045) signatures(4) ecdsa-with-SHA2(3) 4 }
+
+var (
+	oidSignatureMD2WithRSA      = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 2}
+	oidSignatureMD5WithRSA      = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 4}
+	oidSignatureSHA1WithRSA     = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 5}
+	oidSignatureSHA256WithRSA   = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 11}
+	oidSignatureSHA384WithRSA   = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 12}
+	oidSignatureSHA512WithRSA   = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 13}
+	oidSignatureDSAWithSHA1     = asn1.ObjectIdentifier{1, 2, 840, 10040, 4, 3}
+	oidSignatureDSAWithSHA256   = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 4, 3, 2}
+	oidSignatureECDSAWithSHA1   = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 1}
+	oidSignatureECDSAWithSHA256 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 2}
+	oidSignatureECDSAWithSHA384 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 3}
+	oidSignatureECDSAWithSHA512 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 4}
+)
+
+var signatureAlgorithmDetails = []struct {
+	algo       SignatureAlgorithm
+	oid        asn1.ObjectIdentifier
+	pubKeyAlgo PublicKeyAlgorithm
+	hash       crypto.Hash
+}{
+	{MD2WithRSA, oidSignatureMD2WithRSA, RSA, crypto.Hash(0) /* no value for MD2 */},
+	{MD5WithRSA, oidSignatureMD5WithRSA, RSA, crypto.MD5},
+	{SHA1WithRSA, oidSignatureSHA1WithRSA, RSA, crypto.SHA1},
+	{SHA256WithRSA, oidSignatureSHA256WithRSA, RSA, crypto.SHA256},
+	{SHA384WithRSA, oidSignatureSHA384WithRSA, RSA, crypto.SHA384},
+	{SHA512WithRSA, oidSignatureSHA512WithRSA, RSA, crypto.SHA512},
+	{DSAWithSHA1, oidSignatureDSAWithSHA1, DSA, crypto.SHA1},
+	{DSAWithSHA256, oidSignatureDSAWithSHA256, DSA, crypto.SHA256},
+	{ECDSAWithSHA1, oidSignatureECDSAWithSHA1, ECDSA, crypto.SHA1},
+	{ECDSAWithSHA256, oidSignatureECDSAWithSHA256, ECDSA, crypto.SHA256},
+	{ECDSAWithSHA384, oidSignatureECDSAWithSHA384, ECDSA, crypto.SHA384},
+	{ECDSAWithSHA512, oidSignatureECDSAWithSHA512, ECDSA, crypto.SHA512},
+}
+
+func getSignatureAlgorithmFromOID(oid asn1.ObjectIdentifier) SignatureAlgorithm {
+	for _, details := range signatureAlgorithmDetails {
+		if oid.Equal(details.oid) {
+			return details.algo
+		}
+	}
+	return UnknownSignatureAlgorithm
+}
+
+// RFC 3279, 2.3 Public Key Algorithms
+//
+// pkcs-1 OBJECT IDENTIFIER ::== { iso(1) member-body(2) us(840)
+//    rsadsi(113549) pkcs(1) 1 }
+//
+// rsaEncryption OBJECT IDENTIFIER ::== { pkcs1-1 1 }
+//
+// id-dsa OBJECT IDENTIFIER ::== { iso(1) member-body(2) us(840)
+//    x9-57(10040) x9cm(4) 1 }
+//
+// RFC 5480, 2.1.1 Unrestricted Algorithm Identifier and Parameters
+//
+// id-ecPublicKey OBJECT IDENTIFIER ::= {
+//       iso(1) member-body(2) us(840) ansi-X9-62(10045) keyType(2) 1 }
+var (
+	oidPublicKeyRSA   = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 1}
+	oidPublicKeyDSA   = asn1.ObjectIdentifier{1, 2, 840, 10040, 4, 1}
+	oidPublicKeyECDSA = asn1.ObjectIdentifier{1, 2, 840, 10045, 2, 1}
+)
+
+func getPublicKeyAlgorithmFromOID(oid asn1.ObjectIdentifier) PublicKeyAlgorithm {
+	switch {
+	case oid.Equal(oidPublicKeyRSA):
+		return RSA
+	case oid.Equal(oidPublicKeyDSA):
+		return DSA
+	case oid.Equal(oidPublicKeyECDSA):
+		return ECDSA
+	}
+	return UnknownPublicKeyAlgorithm
+}
+
+// RFC 5480, 2.1.1.1. Named Curve
+//
+// secp224r1 OBJECT IDENTIFIER ::= {
+//   iso(1) identified-organization(3) certicom(132) curve(0) 33 }
+//
+// secp256r1 OBJECT IDENTIFIER ::= {
+//   iso(1) member-body(2) us(840) ansi-X9-62(10045) curves(3)
+//   prime(1) 7 }
+//
+// secp384r1 OBJECT IDENTIFIER ::= {
+//   iso(1) identified-organization(3) certicom(132) curve(0) 34 }
+//
+// secp521r1 OBJECT IDENTIFIER ::= {
+//   iso(1) identified-organization(3) certicom(132) curve(0) 35 }
+//
+// NB: secp256r1 is equivalent to prime256v1
+var (
+	oidNamedCurveP224 = asn1.ObjectIdentifier{1, 3, 132, 0, 33}
+	oidNamedCurveP256 = asn1.ObjectIdentifier{1, 2, 840, 10045, 3, 1, 7}
+	oidNamedCurveP384 = asn1.ObjectIdentifier{1, 3, 132, 0, 34}
+	oidNamedCurveP521 = asn1.ObjectIdentifier{1, 3, 132, 0, 35}
+)
+
+func namedCurveFromOID(oid asn1.ObjectIdentifier) elliptic.Curve {
+	switch {
+	case oid.Equal(oidNamedCurveP224):
+		return elliptic.P224()
+	case oid.Equal(oidNamedCurveP256):
+		return elliptic.P256()
+	case oid.Equal(oidNamedCurveP384):
+		return elliptic.P384()
+	case oid.Equal(oidNamedCurveP521):
+		return elliptic.P521()
+	}
+	return nil
+}
+
+func oidFromNamedCurve(curve elliptic.Curve) (asn1.ObjectIdentifier, bool) {
+	switch curve {
+	case elliptic.P224():
+		return oidNamedCurveP224, true
+	case elliptic.P256():
+		return oidNamedCurveP256, true
+	case elliptic.P384():
+		return oidNamedCurveP384, true
+	case elliptic.P521():
+		return oidNamedCurveP521, true
+	}
+
+	return nil, false
+}
+
+// KeyUsage represents the set of actions that are valid for a given key. It's
+// a bitmap of the KeyUsage* constants.
+type KeyUsage int
+
+const (
+	KeyUsageDigitalSignature KeyUsage = 1 << iota
+	KeyUsageContentCommitment
+	KeyUsageKeyEncipherment
+	KeyUsageDataEncipherment
+	KeyUsageKeyAgreement
+	KeyUsageCertSign
+	KeyUsageCRLSign
+	KeyUsageEncipherOnly
+	KeyUsageDecipherOnly
+)
+
+// RFC 5280, 4.2.1.12  Extended Key Usage
+//
+// anyExtendedKeyUsage OBJECT IDENTIFIER ::= { id-ce-extKeyUsage 0 }
+//
+// id-kp OBJECT IDENTIFIER ::= { id-pkix 3 }
+//
+// id-kp-serverAuth             OBJECT IDENTIFIER ::= { id-kp 1 }
+// id-kp-clientAuth             OBJECT IDENTIFIER ::= { id-kp 2 }
+// id-kp-codeSigning            OBJECT IDENTIFIER ::= { id-kp 3 }
+// id-kp-emailProtection        OBJECT IDENTIFIER ::= { id-kp 4 }
+// id-kp-timeStamping           OBJECT IDENTIFIER ::= { id-kp 8 }
+// id-kp-OCSPSigning            OBJECT IDENTIFIER ::= { id-kp 9 }
+var (
+	oidExtKeyUsageAny                        = asn1.ObjectIdentifier{2, 5, 29, 37, 0}
+	oidExtKeyUsageServerAuth                 = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 1}
+	oidExtKeyUsageClientAuth                 = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 2}
+	oidExtKeyUsageCodeSigning                = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 3}
+	oidExtKeyUsageEmailProtection            = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 4}
+	oidExtKeyUsageIPSECEndSystem             = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 5}
+	oidExtKeyUsageIPSECTunnel                = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 6}
+	oidExtKeyUsageIPSECUser                  = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 7}
+	oidExtKeyUsageTimeStamping               = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 8}
+	oidExtKeyUsageOCSPSigning                = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 9}
+	oidExtKeyUsageMicrosoftServerGatedCrypto = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 10, 3, 3}
+	oidExtKeyUsageNetscapeServerGatedCrypto  = asn1.ObjectIdentifier{2, 16, 840, 1, 113730, 4, 1}
+)
+
+// ExtKeyUsage represents an extended set of actions that are valid for a given key.
+// Each of the ExtKeyUsage* constants define a unique action.
+type ExtKeyUsage int
+
+const (
+	ExtKeyUsageAny ExtKeyUsage = iota
+	ExtKeyUsageServerAuth
+	ExtKeyUsageClientAuth
+	ExtKeyUsageCodeSigning
+	ExtKeyUsageEmailProtection
+	ExtKeyUsageIPSECEndSystem
+	ExtKeyUsageIPSECTunnel
+	ExtKeyUsageIPSECUser
+	ExtKeyUsageTimeStamping
+	ExtKeyUsageOCSPSigning
+	ExtKeyUsageMicrosoftServerGatedCrypto
+	ExtKeyUsageNetscapeServerGatedCrypto
+)
+
+// extKeyUsageOIDs contains the mapping between an ExtKeyUsage and its OID.
+var extKeyUsageOIDs = []struct {
+	extKeyUsage ExtKeyUsage
+	oid         asn1.ObjectIdentifier
+}{
+	{ExtKeyUsageAny, oidExtKeyUsageAny},
+	{ExtKeyUsageServerAuth, oidExtKeyUsageServerAuth},
+	{ExtKeyUsageClientAuth, oidExtKeyUsageClientAuth},
+	{ExtKeyUsageCodeSigning, oidExtKeyUsageCodeSigning},
+	{ExtKeyUsageEmailProtection, oidExtKeyUsageEmailProtection},
+	{ExtKeyUsageIPSECEndSystem, oidExtKeyUsageIPSECEndSystem},
+	{ExtKeyUsageIPSECTunnel, oidExtKeyUsageIPSECTunnel},
+	{ExtKeyUsageIPSECUser, oidExtKeyUsageIPSECUser},
+	{ExtKeyUsageTimeStamping, oidExtKeyUsageTimeStamping},
+	{ExtKeyUsageOCSPSigning, oidExtKeyUsageOCSPSigning},
+	{ExtKeyUsageMicrosoftServerGatedCrypto, oidExtKeyUsageMicrosoftServerGatedCrypto},
+	{ExtKeyUsageNetscapeServerGatedCrypto, oidExtKeyUsageNetscapeServerGatedCrypto},
+}
+
+func extKeyUsageFromOID(oid asn1.ObjectIdentifier) (eku ExtKeyUsage, ok bool) {
+	for _, pair := range extKeyUsageOIDs {
+		if oid.Equal(pair.oid) {
+			return pair.extKeyUsage, true
+		}
+	}
+	return
+}
+
+func oidFromExtKeyUsage(eku ExtKeyUsage) (oid asn1.ObjectIdentifier, ok bool) {
+	for _, pair := range extKeyUsageOIDs {
+		if eku == pair.extKeyUsage {
+			return pair.oid, true
+		}
+	}
+	return
+}
+
+// A Certificate represents an X.509 certificate.
+type Certificate struct {
+	Raw                     []byte // Complete ASN.1 DER content (certificate, signature algorithm and signature).
+	RawTBSCertificate       []byte // Certificate part of raw ASN.1 DER content.
+	RawSubjectPublicKeyInfo []byte // DER encoded SubjectPublicKeyInfo.
+	RawSubject              []byte // DER encoded Subject
+	RawIssuer               []byte // DER encoded Issuer
+
+	Signature          []byte
+	SignatureAlgorithm SignatureAlgorithm
+
+	PublicKeyAlgorithm PublicKeyAlgorithm
+	PublicKey          interface{}
+
+	Version             int
+	SerialNumber        *big.Int
+	Issuer              pkix.Name
+	Subject             pkix.Name
+	NotBefore, NotAfter time.Time // Validity bounds.
+	KeyUsage            KeyUsage
+
+	// Extensions contains raw X.509 extensions. When parsing certificates,
+	// this can be used to extract non-critical extensions that are not
+	// parsed by this package. When marshaling certificates, the Extensions
+	// field is ignored, see ExtraExtensions.
+	Extensions []pkix.Extension
+
+	// ExtraExtensions contains extensions to be copied, raw, into any
+	// marshaled certificates. Values override any extensions that would
+	// otherwise be produced based on the other fields. The ExtraExtensions
+	// field is not populated when parsing certificates, see Extensions.
+	ExtraExtensions []pkix.Extension
+
+	ExtKeyUsage        []ExtKeyUsage           // Sequence of extended key usages.
+	UnknownExtKeyUsage []asn1.ObjectIdentifier // Encountered extended key usages unknown to this package.
+
+	BasicConstraintsValid bool // if true then the next two fields are valid.
+	IsCA                  bool
+	MaxPathLen            int
+	// MaxPathLenZero indicates that BasicConstraintsValid==true and
+	// MaxPathLen==0 should be interpreted as an actual maximum path length
+	// of zero. Otherwise, that combination is interpreted as MaxPathLen
+	// not being set.
+	MaxPathLenZero bool
+
+	SubjectKeyId   []byte
+	AuthorityKeyId []byte
+
+	// RFC 5280, 4.2.2.1 (Authority Information Access)
+	OCSPServer            []string
+	IssuingCertificateURL []string
+
+	// Subject Alternate Name values
+	DNSNames       []string
+	EmailAddresses []string
+	IPAddresses    []net.IP
+
+	// Name constraints
+	PermittedDNSDomainsCritical bool // if true then the name constraints are marked critical.
+	PermittedDNSDomains         []string
+
+	// CRL Distribution Points
+	CRLDistributionPoints []string
+
+	PolicyIdentifiers []asn1.ObjectIdentifier
+}
+
+// ErrUnsupportedAlgorithm results from attempting to perform an operation that
+// involves algorithms that are not currently implemented.
+var ErrUnsupportedAlgorithm = errors.New("x509: cannot verify signature: algorithm unimplemented")
+
+// ConstraintViolationError results when a requested usage is not permitted by
+// a certificate. For example: checking a signature when the public key isn't a
+// certificate signing key.
+type ConstraintViolationError struct{}
+
+func (ConstraintViolationError) Error() string {
+	return "x509: invalid signature: parent certificate cannot sign this kind of certificate"
+}
+
+func (c *Certificate) Equal(other *Certificate) bool {
+	return bytes.Equal(c.Raw, other.Raw)
+}
+
+// Entrust have a broken root certificate (CN=Entrust.net Certification
+// Authority (2048)) which isn't marked as a CA certificate and is thus invalid
+// according to PKIX.
+// We recognise this certificate by its SubjectPublicKeyInfo and exempt it
+// from the Basic Constraints requirement.
+// See http://www.entrust.net/knowledge-base/technote.cfm?tn=7869
+//
+// TODO(agl): remove this hack once their reissued root is sufficiently
+// widespread.
+var entrustBrokenSPKI = []byte{
+	0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09,
+	0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
+	0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00,
+	0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01,
+	0x00, 0x97, 0xa3, 0x2d, 0x3c, 0x9e, 0xde, 0x05,
+	0xda, 0x13, 0xc2, 0x11, 0x8d, 0x9d, 0x8e, 0xe3,
+	0x7f, 0xc7, 0x4b, 0x7e, 0x5a, 0x9f, 0xb3, 0xff,
+	0x62, 0xab, 0x73, 0xc8, 0x28, 0x6b, 0xba, 0x10,
+	0x64, 0x82, 0x87, 0x13, 0xcd, 0x57, 0x18, 0xff,
+	0x28, 0xce, 0xc0, 0xe6, 0x0e, 0x06, 0x91, 0x50,
+	0x29, 0x83, 0xd1, 0xf2, 0xc3, 0x2a, 0xdb, 0xd8,
+	0xdb, 0x4e, 0x04, 0xcc, 0x00, 0xeb, 0x8b, 0xb6,
+	0x96, 0xdc, 0xbc, 0xaa, 0xfa, 0x52, 0x77, 0x04,
+	0xc1, 0xdb, 0x19, 0xe4, 0xae, 0x9c, 0xfd, 0x3c,
+	0x8b, 0x03, 0xef, 0x4d, 0xbc, 0x1a, 0x03, 0x65,
+	0xf9, 0xc1, 0xb1, 0x3f, 0x72, 0x86, 0xf2, 0x38,
+	0xaa, 0x19, 0xae, 0x10, 0x88, 0x78, 0x28, 0xda,
+	0x75, 0xc3, 0x3d, 0x02, 0x82, 0x02, 0x9c, 0xb9,
+	0xc1, 0x65, 0x77, 0x76, 0x24, 0x4c, 0x98, 0xf7,
+	0x6d, 0x31, 0x38, 0xfb, 0xdb, 0xfe, 0xdb, 0x37,
+	0x02, 0x76, 0xa1, 0x18, 0x97, 0xa6, 0xcc, 0xde,
+	0x20, 0x09, 0x49, 0x36, 0x24, 0x69, 0x42, 0xf6,
+	0xe4, 0x37, 0x62, 0xf1, 0x59, 0x6d, 0xa9, 0x3c,
+	0xed, 0x34, 0x9c, 0xa3, 0x8e, 0xdb, 0xdc, 0x3a,
+	0xd7, 0xf7, 0x0a, 0x6f, 0xef, 0x2e, 0xd8, 0xd5,
+	0x93, 0x5a, 0x7a, 0xed, 0x08, 0x49, 0x68, 0xe2,
+	0x41, 0xe3, 0x5a, 0x90, 0xc1, 0x86, 0x55, 0xfc,
+	0x51, 0x43, 0x9d, 0xe0, 0xb2, 0xc4, 0x67, 0xb4,
+	0xcb, 0x32, 0x31, 0x25, 0xf0, 0x54, 0x9f, 0x4b,
+	0xd1, 0x6f, 0xdb, 0xd4, 0xdd, 0xfc, 0xaf, 0x5e,
+	0x6c, 0x78, 0x90, 0x95, 0xde, 0xca, 0x3a, 0x48,
+	0xb9, 0x79, 0x3c, 0x9b, 0x19, 0xd6, 0x75, 0x05,
+	0xa0, 0xf9, 0x88, 0xd7, 0xc1, 0xe8, 0xa5, 0x09,
+	0xe4, 0x1a, 0x15, 0xdc, 0x87, 0x23, 0xaa, 0xb2,
+	0x75, 0x8c, 0x63, 0x25, 0x87, 0xd8, 0xf8, 0x3d,
+	0xa6, 0xc2, 0xcc, 0x66, 0xff, 0xa5, 0x66, 0x68,
+	0x55, 0x02, 0x03, 0x01, 0x00, 0x01,
+}
+
+// CheckSignatureFrom verifies that the signature on c is a valid signature
+// from parent.
+func (c *Certificate) CheckSignatureFrom(parent *Certificate) (err error) {
+	// RFC 5280, 4.2.1.9:
+	// "If the basic constraints extension is not present in a version 3
+	// certificate, or the extension is present but the cA boolean is not
+	// asserted, then the certified public key MUST NOT be used to verify
+	// certificate signatures."
+	// (except for Entrust, see comment above entrustBrokenSPKI)
+	if (parent.Version == 3 && !parent.BasicConstraintsValid ||
+		parent.BasicConstraintsValid && !parent.IsCA) &&
+		!bytes.Equal(c.RawSubjectPublicKeyInfo, entrustBrokenSPKI) {
+		return ConstraintViolationError{}
+	}
+
+	if parent.KeyUsage != 0 && parent.KeyUsage&KeyUsageCertSign == 0 {
+		return ConstraintViolationError{}
+	}
+
+	if parent.PublicKeyAlgorithm == UnknownPublicKeyAlgorithm {
+		return ErrUnsupportedAlgorithm
+	}
+
+	// TODO(agl): don't ignore the path length constraint.
+
+	return parent.CheckSignature(c.SignatureAlgorithm, c.RawTBSCertificate, c.Signature)
+}
+
+// CheckSignature verifies that signature is a valid signature over signed from
+// c's public key.
+func (c *Certificate) CheckSignature(algo SignatureAlgorithm, signed, signature []byte) (err error) {
+	var hashType crypto.Hash
+
+	switch algo {
+	case SHA1WithRSA, DSAWithSHA1, ECDSAWithSHA1:
+		hashType = crypto.SHA1
+	case SHA256WithRSA, DSAWithSHA256, ECDSAWithSHA256:
+		hashType = crypto.SHA256
+	case SHA384WithRSA, ECDSAWithSHA384:
+		hashType = crypto.SHA384
+	case SHA512WithRSA, ECDSAWithSHA512:
+		hashType = crypto.SHA512
+	default:
+		return ErrUnsupportedAlgorithm
+	}
+
+	if !hashType.Available() {
+		return ErrUnsupportedAlgorithm
+	}
+	h := hashType.New()
+
+	h.Write(signed)
+	digest := h.Sum(nil)
+
+	switch pub := c.PublicKey.(type) {
+	case *rsa.PublicKey:
+		return rsa.VerifyPKCS1v15(pub, hashType, digest, signature)
+	case *dsa.PublicKey:
+		dsaSig := new(dsaSignature)
+		if _, err := asn1.Unmarshal(signature, dsaSig); err != nil {
+			return err
+		}
+		if dsaSig.R.Sign() <= 0 || dsaSig.S.Sign() <= 0 {
+			return errors.New("x509: DSA signature contained zero or negative values")
+		}
+		if !dsa.Verify(pub, digest, dsaSig.R, dsaSig.S) {
+			return errors.New("x509: DSA verification failure")
+		}
+		return
+	case *ecdsa.PublicKey:
+		ecdsaSig := new(ecdsaSignature)
+		if _, err := asn1.Unmarshal(signature, ecdsaSig); err != nil {
+			return err
+		}
+		if ecdsaSig.R.Sign() <= 0 || ecdsaSig.S.Sign() <= 0 {
+			return errors.New("x509: ECDSA signature contained zero or negative values")
+		}
+		if !ecdsa.Verify(pub, digest, ecdsaSig.R, ecdsaSig.S) {
+			return errors.New("x509: ECDSA verification failure")
+		}
+		return
+	}
+	return ErrUnsupportedAlgorithm
+}
+
+// CheckCRLSignature checks that the signature in crl is from c.
+func (c *Certificate) CheckCRLSignature(crl *pkix.CertificateList) (err error) {
+	algo := getSignatureAlgorithmFromOID(crl.SignatureAlgorithm.Algorithm)
+	return c.CheckSignature(algo, crl.TBSCertList.Raw, crl.SignatureValue.RightAlign())
+}
+
+type UnhandledCriticalExtension struct{}
+
+func (h UnhandledCriticalExtension) Error() string {
+	return "x509: unhandled critical extension"
+}
+
+type basicConstraints struct {
+	IsCA       bool `asn1:"optional"`
+	MaxPathLen int  `asn1:"optional,default:-1"`
+}
+
+// RFC 5280 4.2.1.4
+type policyInformation struct {
+	Policy asn1.ObjectIdentifier
+	// policyQualifiers omitted
+}
+
+// RFC 5280, 4.2.1.10
+type nameConstraints struct {
+	Permitted []generalSubtree `asn1:"optional,tag:0"`
+	Excluded  []generalSubtree `asn1:"optional,tag:1"`
+}
+
+type generalSubtree struct {
+	Name string `asn1:"tag:2,optional,ia5"`
+}
+
+// RFC 5280, 4.2.2.1
+type authorityInfoAccess struct {
+	Method   asn1.ObjectIdentifier
+	Location asn1.RawValue
+}
+
+// RFC 5280, 4.2.1.14
+type distributionPoint struct {
+	DistributionPoint distributionPointName `asn1:"optional,tag:0"`
+	Reason            asn1.BitString        `asn1:"optional,tag:1"`
+	CRLIssuer         asn1.RawValue         `asn1:"optional,tag:2"`
+}
+
+type distributionPointName struct {
+	FullName     asn1.RawValue    `asn1:"optional,tag:0"`
+	RelativeName pkix.RDNSequence `asn1:"optional,tag:1"`
+}
+
+func parsePublicKey(algo PublicKeyAlgorithm, keyData *publicKeyInfo) (interface{}, error) {
+	asn1Data := keyData.PublicKey.RightAlign()
+	switch algo {
+	case RSA:
+		p := new(rsaPublicKey)
+		_, err := asn1.Unmarshal(asn1Data, p)
+		if err != nil {
+			return nil, err
+		}
+
+		if p.N.Sign() <= 0 {
+			return nil, errors.New("x509: RSA modulus is not a positive number")
+		}
+		if p.E <= 0 {
+			return nil, errors.New("x509: RSA public exponent is not a positive number")
+		}
+
+		pub := &rsa.PublicKey{
+			E: p.E,
+			N: p.N,
+		}
+		return pub, nil
+	case DSA:
+		var p *big.Int
+		_, err := asn1.Unmarshal(asn1Data, &p)
+		if err != nil {
+			return nil, err
+		}
+		paramsData := keyData.Algorithm.Parameters.FullBytes
+		params := new(dsaAlgorithmParameters)
+		_, err = asn1.Unmarshal(paramsData, params)
+		if err != nil {
+			return nil, err
+		}
+		if p.Sign() <= 0 || params.P.Sign() <= 0 || params.Q.Sign() <= 0 || params.G.Sign() <= 0 {
+			return nil, errors.New("x509: zero or negative DSA parameter")
+		}
+		pub := &dsa.PublicKey{
+			Parameters: dsa.Parameters{
+				P: params.P,
+				Q: params.Q,
+				G: params.G,
+			},
+			Y: p,
+		}
+		return pub, nil
+	case ECDSA:
+		paramsData := keyData.Algorithm.Parameters.FullBytes
+		namedCurveOID := new(asn1.ObjectIdentifier)
+		_, err := asn1.Unmarshal(paramsData, namedCurveOID)
+		if err != nil {
+			return nil, err
+		}
+		namedCurve := namedCurveFromOID(*namedCurveOID)
+		if namedCurve == nil {
+			return nil, errors.New("x509: unsupported elliptic curve")
+		}
+		x, y := elliptic.Unmarshal(namedCurve, asn1Data)
+		if x == nil {
+			return nil, errors.New("x509: failed to unmarshal elliptic curve point")
+		}
+		pub := &ecdsa.PublicKey{
+			Curve: namedCurve,
+			X:     x,
+			Y:     y,
+		}
+		return pub, nil
+	default:
+		return nil, nil
+	}
+}
+
+func parseSANExtension(value []byte) (dnsNames, emailAddresses []string, ipAddresses []net.IP, err error) {
+	// RFC 5280, 4.2.1.6
+
+	// SubjectAltName ::= GeneralNames
+	//
+	// GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
+	//
+	// GeneralName ::= CHOICE {
+	//      otherName                       [0]     OtherName,
+	//      rfc822Name                      [1]     IA5String,
+	//      dNSName                         [2]     IA5String,
+	//      x400Address                     [3]     ORAddress,
+	//      directoryName                   [4]     Name,
+	//      ediPartyName                    [5]     EDIPartyName,
+	//      uniformResourceIdentifier       [6]     IA5String,
+	//      iPAddress                       [7]     OCTET STRING,
+	//      registeredID                    [8]     OBJECT IDENTIFIER }
+	var seq asn1.RawValue
+	if _, err = asn1.Unmarshal(value, &seq); err != nil {
+		return
+	}
+	if !seq.IsCompound || seq.Tag != 16 || seq.Class != 0 {
+		err = asn1.StructuralError{Msg: "bad SAN sequence"}
+		return
+	}
+
+	rest := seq.Bytes
+	for len(rest) > 0 {
+		var v asn1.RawValue
+		rest, err = asn1.Unmarshal(rest, &v)
+		if err != nil {
+			return
+		}
+		switch v.Tag {
+		case 1:
+			emailAddresses = append(emailAddresses, string(v.Bytes))
+		case 2:
+			dnsNames = append(dnsNames, string(v.Bytes))
+		case 7:
+			switch len(v.Bytes) {
+			case net.IPv4len, net.IPv6len:
+				ipAddresses = append(ipAddresses, v.Bytes)
+			default:
+				err = errors.New("x509: certificate contained IP address of length " + strconv.Itoa(len(v.Bytes)))
+				return
+			}
+		}
+	}
+
+	return
+}
+
+func parseCertificate(in *certificate) (*Certificate, error) {
+	out := new(Certificate)
+	out.Raw = in.Raw
+	out.RawTBSCertificate = in.TBSCertificate.Raw
+	out.RawSubjectPublicKeyInfo = in.TBSCertificate.PublicKey.Raw
+	out.RawSubject = in.TBSCertificate.Subject.FullBytes
+	out.RawIssuer = in.TBSCertificate.Issuer.FullBytes
+
+	out.Signature = in.SignatureValue.RightAlign()
+	out.SignatureAlgorithm =
+		getSignatureAlgorithmFromOID(in.TBSCertificate.SignatureAlgorithm.Algorithm)
+
+	out.PublicKeyAlgorithm =
+		getPublicKeyAlgorithmFromOID(in.TBSCertificate.PublicKey.Algorithm.Algorithm)
+	var err error
+	out.PublicKey, err = parsePublicKey(out.PublicKeyAlgorithm, &in.TBSCertificate.PublicKey)
+	if err != nil {
+		return nil, err
+	}
+
+	if in.TBSCertificate.SerialNumber.Sign() < 0 {
+		return nil, errors.New("x509: negative serial number")
+	}
+
+	out.Version = in.TBSCertificate.Version + 1
+	out.SerialNumber = in.TBSCertificate.SerialNumber
+
+	var issuer, subject pkix.RDNSequence
+	if _, err := asn1.Unmarshal(in.TBSCertificate.Subject.FullBytes, &subject); err != nil {
+		return nil, err
+	}
+	if _, err := asn1.Unmarshal(in.TBSCertificate.Issuer.FullBytes, &issuer); err != nil {
+		return nil, err
+	}
+
+	out.Issuer.FillFromRDNSequence(&issuer)
+	out.Subject.FillFromRDNSequence(&subject)
+
+	out.NotBefore = in.TBSCertificate.Validity.NotBefore
+	out.NotAfter = in.TBSCertificate.Validity.NotAfter
+
+	for _, e := range in.TBSCertificate.Extensions {
+		out.Extensions = append(out.Extensions, e)
+
+		if len(e.Id) == 4 && e.Id[0] == 2 && e.Id[1] == 5 && e.Id[2] == 29 {
+			switch e.Id[3] {
+			case 15:
+				// RFC 5280, 4.2.1.3
+				var usageBits asn1.BitString
+				_, err := asn1.Unmarshal(e.Value, &usageBits)
+
+				if err == nil {
+					var usage int
+					for i := 0; i < 9; i++ {
+						if usageBits.At(i) != 0 {
+							usage |= 1 << uint(i)
+						}
+					}
+					out.KeyUsage = KeyUsage(usage)
+					continue
+				}
+			case 19:
+				// RFC 5280, 4.2.1.9
+				var constraints basicConstraints
+				_, err := asn1.Unmarshal(e.Value, &constraints)
+
+				if err == nil {
+					out.BasicConstraintsValid = true
+					out.IsCA = constraints.IsCA
+					out.MaxPathLen = constraints.MaxPathLen
+					out.MaxPathLenZero = out.MaxPathLen == 0
+					continue
+				}
+			case 17:
+				out.DNSNames, out.EmailAddresses, out.IPAddresses, err = parseSANExtension(e.Value)
+				if err != nil {
+					return nil, err
+				}
+
+				if len(out.DNSNames) > 0 || len(out.EmailAddresses) > 0 || len(out.IPAddresses) > 0 {
+					continue
+				}
+				// If we didn't parse any of the names then we
+				// fall through to the critical check below.
+
+			case 30:
+				// RFC 5280, 4.2.1.10
+
+				// NameConstraints ::= SEQUENCE {
+				//      permittedSubtrees       [0]     GeneralSubtrees OPTIONAL,
+				//      excludedSubtrees        [1]     GeneralSubtrees OPTIONAL }
+				//
+				// GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree
+				//
+				// GeneralSubtree ::= SEQUENCE {
+				//      base                    GeneralName,
+				//      minimum         [0]     BaseDistance DEFAULT 0,
+				//      maximum         [1]     BaseDistance OPTIONAL }
+				//
+				// BaseDistance ::= INTEGER (0..MAX)
+
+				var constraints nameConstraints
+				_, err := asn1.Unmarshal(e.Value, &constraints)
+				if err != nil {
+					return nil, err
+				}
+
+				if len(constraints.Excluded) > 0 && e.Critical {
+					return out, UnhandledCriticalExtension{}
+				}
+
+				for _, subtree := range constraints.Permitted {
+					if len(subtree.Name) == 0 {
+						if e.Critical {
+							return out, UnhandledCriticalExtension{}
+						}
+						continue
+					}
+					out.PermittedDNSDomains = append(out.PermittedDNSDomains, subtree.Name)
+				}
+				continue
+
+			case 31:
+				// RFC 5280, 4.2.1.14
+
+				// CRLDistributionPoints ::= SEQUENCE SIZE (1..MAX) OF DistributionPoint
+				//
+				// DistributionPoint ::= SEQUENCE {
+				//     distributionPoint       [0]     DistributionPointName OPTIONAL,
+				//     reasons                 [1]     ReasonFlags OPTIONAL,
+				//     cRLIssuer               [2]     GeneralNames OPTIONAL }
+				//
+				// DistributionPointName ::= CHOICE {
+				//     fullName                [0]     GeneralNames,
+				//     nameRelativeToCRLIssuer [1]     RelativeDistinguishedName }
+
+				var cdp []distributionPoint
+				_, err := asn1.Unmarshal(e.Value, &cdp)
+				if err != nil {
+					return nil, err
+				}
+
+				for _, dp := range cdp {
+					var n asn1.RawValue
+					_, err = asn1.Unmarshal(dp.DistributionPoint.FullName.Bytes, &n)
+					if err != nil {
+						return nil, err
+					}
+
+					if n.Tag == 6 {
+						out.CRLDistributionPoints = append(out.CRLDistributionPoints, string(n.Bytes))
+					}
+				}
+				continue
+
+			case 35:
+				// RFC 5280, 4.2.1.1
+				var a authKeyId
+				_, err = asn1.Unmarshal(e.Value, &a)
+				if err != nil {
+					return nil, err
+				}
+				out.AuthorityKeyId = a.Id
+				continue
+
+			case 37:
+				// RFC 5280, 4.2.1.12.  Extended Key Usage
+
+				// id-ce-extKeyUsage OBJECT IDENTIFIER ::= { id-ce 37 }
+				//
+				// ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
+				//
+				// KeyPurposeId ::= OBJECT IDENTIFIER
+
+				var keyUsage []asn1.ObjectIdentifier
+				_, err = asn1.Unmarshal(e.Value, &keyUsage)
+				if err != nil {
+					return nil, err
+				}
+
+				for _, u := range keyUsage {
+					if extKeyUsage, ok := extKeyUsageFromOID(u); ok {
+						out.ExtKeyUsage = append(out.ExtKeyUsage, extKeyUsage)
+					} else {
+						out.UnknownExtKeyUsage = append(out.UnknownExtKeyUsage, u)
+					}
+				}
+
+				continue
+
+			case 14:
+				// RFC 5280, 4.2.1.2
+				var keyid []byte
+				_, err = asn1.Unmarshal(e.Value, &keyid)
+				if err != nil {
+					return nil, err
+				}
+				out.SubjectKeyId = keyid
+				continue
+
+			case 32:
+				// RFC 5280 4.2.1.4: Certificate Policies
+				var policies []policyInformation
+				if _, err = asn1.Unmarshal(e.Value, &policies); err != nil {
+					return nil, err
+				}
+				out.PolicyIdentifiers = make([]asn1.ObjectIdentifier, len(policies))
+				for i, policy := range policies {
+					out.PolicyIdentifiers[i] = policy.Policy
+				}
+			}
+		} else if e.Id.Equal(oidExtensionAuthorityInfoAccess) {
+			// RFC 5280 4.2.2.1: Authority Information Access
+			var aia []authorityInfoAccess
+			if _, err = asn1.Unmarshal(e.Value, &aia); err != nil {
+				return nil, err
+			}
+
+			for _, v := range aia {
+				// GeneralName: uniformResourceIdentifier [6] IA5String
+				if v.Location.Tag != 6 {
+					continue
+				}
+				if v.Method.Equal(oidAuthorityInfoAccessOcsp) {
+					out.OCSPServer = append(out.OCSPServer, string(v.Location.Bytes))
+				} else if v.Method.Equal(oidAuthorityInfoAccessIssuers) {
+					out.IssuingCertificateURL = append(out.IssuingCertificateURL, string(v.Location.Bytes))
+				}
+			}
+		}
+
+		if e.Critical {
+			return out, UnhandledCriticalExtension{}
+		}
+	}
+
+	return out, nil
+}
+
+// ParseCertificate parses a single certificate from the given ASN.1 DER data.
+func ParseCertificate(asn1Data []byte) (*Certificate, error) {
+	var cert certificate
+	rest, err := asn1.Unmarshal(asn1Data, &cert)
+	if err != nil {
+		return nil, err
+	}
+	if len(rest) > 0 {
+		return nil, asn1.SyntaxError{Msg: "trailing data"}
+	}
+
+	return parseCertificate(&cert)
+}
+
+// ParseCertificates parses one or more certificates from the given ASN.1 DER
+// data. The certificates must be concatenated with no intermediate padding.
+func ParseCertificates(asn1Data []byte) ([]*Certificate, error) {
+	var v []*certificate
+
+	for len(asn1Data) > 0 {
+		cert := new(certificate)
+		var err error
+		asn1Data, err = asn1.Unmarshal(asn1Data, cert)
+		if err != nil {
+			return nil, err
+		}
+		v = append(v, cert)
+	}
+
+	ret := make([]*Certificate, len(v))
+	for i, ci := range v {
+		cert, err := parseCertificate(ci)
+		if err != nil {
+			return nil, err
+		}
+		ret[i] = cert
+	}
+
+	return ret, nil
+}
+
+func reverseBitsInAByte(in byte) byte {
+	b1 := in>>4 | in<<4
+	b2 := b1>>2&0x33 | b1<<2&0xcc
+	b3 := b2>>1&0x55 | b2<<1&0xaa
+	return b3
+}
+
+var (
+	oidExtensionSubjectKeyId          = []int{2, 5, 29, 14}
+	oidExtensionKeyUsage              = []int{2, 5, 29, 15}
+	oidExtensionExtendedKeyUsage      = []int{2, 5, 29, 37}
+	oidExtensionAuthorityKeyId        = []int{2, 5, 29, 35}
+	oidExtensionBasicConstraints      = []int{2, 5, 29, 19}
+	oidExtensionSubjectAltName        = []int{2, 5, 29, 17}
+	oidExtensionCertificatePolicies   = []int{2, 5, 29, 32}
+	oidExtensionNameConstraints       = []int{2, 5, 29, 30}
+	oidExtensionCRLDistributionPoints = []int{2, 5, 29, 31}
+	oidExtensionAuthorityInfoAccess   = []int{1, 3, 6, 1, 5, 5, 7, 1, 1}
+)
+
+var (
+	oidAuthorityInfoAccessOcsp    = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 48, 1}
+	oidAuthorityInfoAccessIssuers = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 48, 2}
+)
+
+// oidNotInExtensions returns whether an extension with the given oid exists in
+// extensions.
+func oidInExtensions(oid asn1.ObjectIdentifier, extensions []pkix.Extension) bool {
+	for _, e := range extensions {
+		if e.Id.Equal(oid) {
+			return true
+		}
+	}
+	return false
+}
+
+// marshalSANs marshals a list of addresses into a the contents of an X.509
+// SubjectAlternativeName extension.
+func marshalSANs(dnsNames, emailAddresses []string, ipAddresses []net.IP) (derBytes []byte, err error) {
+	var rawValues []asn1.RawValue
+	for _, name := range dnsNames {
+		rawValues = append(rawValues, asn1.RawValue{Tag: 2, Class: 2, Bytes: []byte(name)})
+	}
+	for _, email := range emailAddresses {
+		rawValues = append(rawValues, asn1.RawValue{Tag: 1, Class: 2, Bytes: []byte(email)})
+	}
+	for _, rawIP := range ipAddresses {
+		// If possible, we always want to encode IPv4 addresses in 4 bytes.
+		ip := rawIP.To4()
+		if ip == nil {
+			ip = rawIP
+		}
+		rawValues = append(rawValues, asn1.RawValue{Tag: 7, Class: 2, Bytes: ip})
+	}
+	return asn1.Marshal(rawValues)
+}
+
+func buildExtensions(template *Certificate) (ret []pkix.Extension, err error) {
+	ret = make([]pkix.Extension, 10 /* maximum number of elements. */)
+	n := 0
+
+	if template.KeyUsage != 0 &&
+		!oidInExtensions(oidExtensionKeyUsage, template.ExtraExtensions) {
+		ret[n].Id = oidExtensionKeyUsage
+		ret[n].Critical = true
+
+		var a [2]byte
+		a[0] = reverseBitsInAByte(byte(template.KeyUsage))
+		a[1] = reverseBitsInAByte(byte(template.KeyUsage >> 8))
+
+		l := 1
+		if a[1] != 0 {
+			l = 2
+		}
+
+		ret[n].Value, err = asn1.Marshal(asn1.BitString{Bytes: a[0:l], BitLength: l * 8})
+		if err != nil {
+			return
+		}
+		n++
+	}
+
+	if (len(template.ExtKeyUsage) > 0 || len(template.UnknownExtKeyUsage) > 0) &&
+		!oidInExtensions(oidExtensionExtendedKeyUsage, template.ExtraExtensions) {
+		ret[n].Id = oidExtensionExtendedKeyUsage
+
+		var oids []asn1.ObjectIdentifier
+		for _, u := range template.ExtKeyUsage {
+			if oid, ok := oidFromExtKeyUsage(u); ok {
+				oids = append(oids, oid)
+			} else {
+				panic("internal error")
+			}
+		}
+
+		oids = append(oids, template.UnknownExtKeyUsage...)
+
+		ret[n].Value, err = asn1.Marshal(oids)
+		if err != nil {
+			return
+		}
+		n++
+	}
+
+	if template.BasicConstraintsValid && !oidInExtensions(oidExtensionBasicConstraints, template.ExtraExtensions) {
+		// Leaving MaxPathLen as zero indicates that no maximum path
+		// length is desired, unless MaxPathLenZero is set. A value of
+		// -1 causes encoding/asn1 to omit the value as desired.
+		maxPathLen := template.MaxPathLen
+		if maxPathLen == 0 && !template.MaxPathLenZero {
+			maxPathLen = -1
+		}
+		ret[n].Id = oidExtensionBasicConstraints
+		ret[n].Value, err = asn1.Marshal(basicConstraints{template.IsCA, maxPathLen})
+		ret[n].Critical = true
+		if err != nil {
+			return
+		}
+		n++
+	}
+
+	if len(template.SubjectKeyId) > 0 && !oidInExtensions(oidExtensionSubjectKeyId, template.ExtraExtensions) {
+		ret[n].Id = oidExtensionSubjectKeyId
+		ret[n].Value, err = asn1.Marshal(template.SubjectKeyId)
+		if err != nil {
+			return
+		}
+		n++
+	}
+
+	if len(template.AuthorityKeyId) > 0 && !oidInExtensions(oidExtensionAuthorityKeyId, template.ExtraExtensions) {
+		ret[n].Id = oidExtensionAuthorityKeyId
+		ret[n].Value, err = asn1.Marshal(authKeyId{template.AuthorityKeyId})
+		if err != nil {
+			return
+		}
+		n++
+	}
+
+	if (len(template.OCSPServer) > 0 || len(template.IssuingCertificateURL) > 0) &&
+		!oidInExtensions(oidExtensionAuthorityInfoAccess, template.ExtraExtensions) {
+		ret[n].Id = oidExtensionAuthorityInfoAccess
+		var aiaValues []authorityInfoAccess
+		for _, name := range template.OCSPServer {
+			aiaValues = append(aiaValues, authorityInfoAccess{
+				Method:   oidAuthorityInfoAccessOcsp,
+				Location: asn1.RawValue{Tag: 6, Class: 2, Bytes: []byte(name)},
+			})
+		}
+		for _, name := range template.IssuingCertificateURL {
+			aiaValues = append(aiaValues, authorityInfoAccess{
+				Method:   oidAuthorityInfoAccessIssuers,
+				Location: asn1.RawValue{Tag: 6, Class: 2, Bytes: []byte(name)},
+			})
+		}
+		ret[n].Value, err = asn1.Marshal(aiaValues)
+		if err != nil {
+			return
+		}
+		n++
+	}
+
+	if (len(template.DNSNames) > 0 || len(template.EmailAddresses) > 0 || len(template.IPAddresses) > 0) &&
+		!oidInExtensions(oidExtensionSubjectAltName, template.ExtraExtensions) {
+		ret[n].Id = oidExtensionSubjectAltName
+		ret[n].Value, err = marshalSANs(template.DNSNames, template.EmailAddresses, template.IPAddresses)
+		if err != nil {
+			return
+		}
+		n++
+	}
+
+	if len(template.PolicyIdentifiers) > 0 &&
+		!oidInExtensions(oidExtensionCertificatePolicies, template.ExtraExtensions) {
+		ret[n].Id = oidExtensionCertificatePolicies
+		policies := make([]policyInformation, len(template.PolicyIdentifiers))
+		for i, policy := range template.PolicyIdentifiers {
+			policies[i].Policy = policy
+		}
+		ret[n].Value, err = asn1.Marshal(policies)
+		if err != nil {
+			return
+		}
+		n++
+	}
+
+	if len(template.PermittedDNSDomains) > 0 &&
+		!oidInExtensions(oidExtensionNameConstraints, template.ExtraExtensions) {
+		ret[n].Id = oidExtensionNameConstraints
+		ret[n].Critical = template.PermittedDNSDomainsCritical
+
+		var out nameConstraints
+		out.Permitted = make([]generalSubtree, len(template.PermittedDNSDomains))
+		for i, permitted := range template.PermittedDNSDomains {
+			out.Permitted[i] = generalSubtree{Name: permitted}
+		}
+		ret[n].Value, err = asn1.Marshal(out)
+		if err != nil {
+			return
+		}
+		n++
+	}
+
+	if len(template.CRLDistributionPoints) > 0 &&
+		!oidInExtensions(oidExtensionCRLDistributionPoints, template.ExtraExtensions) {
+		ret[n].Id = oidExtensionCRLDistributionPoints
+
+		var crlDp []distributionPoint
+		for _, name := range template.CRLDistributionPoints {
+			rawFullName, _ := asn1.Marshal(asn1.RawValue{Tag: 6, Class: 2, Bytes: []byte(name)})
+
+			dp := distributionPoint{
+				DistributionPoint: distributionPointName{
+					FullName: asn1.RawValue{Tag: 0, Class: 2, IsCompound: true, Bytes: rawFullName},
+				},
+			}
+			crlDp = append(crlDp, dp)
+		}
+
+		ret[n].Value, err = asn1.Marshal(crlDp)
+		if err != nil {
+			return
+		}
+		n++
+	}
+
+	// Adding another extension here? Remember to update the maximum number
+	// of elements in the make() at the top of the function.
+
+	return append(ret[:n], template.ExtraExtensions...), nil
+}
+
+func subjectBytes(cert *Certificate) ([]byte, error) {
+	if len(cert.RawSubject) > 0 {
+		return cert.RawSubject, nil
+	}
+
+	return asn1.Marshal(cert.Subject.ToRDNSequence())
+}
+
+// signingParamsForPrivateKey returns the parameters to use for signing with
+// priv. If requestedSigAlgo is not zero then it overrides the default
+// signature algorithm.
+func signingParamsForPrivateKey(priv interface{}, requestedSigAlgo SignatureAlgorithm) (hashFunc crypto.Hash, sigAlgo pkix.AlgorithmIdentifier, err error) {
+	var pubType PublicKeyAlgorithm
+
+	switch priv := priv.(type) {
+	case *rsa.PrivateKey:
+		pubType = RSA
+		sigAlgo.Algorithm = oidSignatureSHA256WithRSA
+		hashFunc = crypto.SHA256
+
+	case *ecdsa.PrivateKey:
+		pubType = ECDSA
+
+		switch priv.Curve {
+		case elliptic.P224(), elliptic.P256():
+			hashFunc = crypto.SHA256
+			sigAlgo.Algorithm = oidSignatureECDSAWithSHA256
+		case elliptic.P384():
+			hashFunc = crypto.SHA384
+			sigAlgo.Algorithm = oidSignatureECDSAWithSHA384
+		case elliptic.P521():
+			hashFunc = crypto.SHA512
+			sigAlgo.Algorithm = oidSignatureECDSAWithSHA512
+		default:
+			err = errors.New("x509: unknown elliptic curve")
+		}
+
+	default:
+		err = errors.New("x509: only RSA and ECDSA private keys supported")
+	}
+
+	if err != nil {
+		return
+	}
+
+	if requestedSigAlgo == 0 {
+		return
+	}
+
+	found := false
+	for _, details := range signatureAlgorithmDetails {
+		if details.algo == requestedSigAlgo {
+			if details.pubKeyAlgo != pubType {
+				err = errors.New("x509: requested SignatureAlgorithm does not match private key type")
+				return
+			}
+			sigAlgo.Algorithm, hashFunc = details.oid, details.hash
+			if hashFunc == 0 {
+				err = errors.New("x509: cannot sign with hash function requested")
+				return
+			}
+			found = true
+			break
+		}
+	}
+
+	if !found {
+		err = errors.New("x509: unknown SignatureAlgorithm")
+	}
+
+	return
+}
+
+// CreateCertificate creates a new certificate based on a template. The
+// following members of template are used: SerialNumber, Subject, NotBefore,
+// NotAfter, KeyUsage, ExtKeyUsage, UnknownExtKeyUsage, BasicConstraintsValid,
+// IsCA, MaxPathLen, SubjectKeyId, DNSNames, PermittedDNSDomainsCritical,
+// PermittedDNSDomains, SignatureAlgorithm.
+//
+// The certificate is signed by parent. If parent is equal to template then the
+// certificate is self-signed. The parameter pub is the public key of the
+// signee and priv is the private key of the signer.
+//
+// The returned slice is the certificate in DER encoding.
+//
+// The only supported key types are RSA and ECDSA (*rsa.PublicKey or
+// *ecdsa.PublicKey for pub, *rsa.PrivateKey or *ecdsa.PrivateKey for priv).
+func CreateCertificate(rand io.Reader, template, parent *Certificate, pub interface{}, priv interface{}) (cert []byte, err error) {
+	hashFunc, signatureAlgorithm, err := signingParamsForPrivateKey(priv, template.SignatureAlgorithm)
+	if err != nil {
+		return nil, err
+	}
+
+	publicKeyBytes, publicKeyAlgorithm, err := marshalPublicKey(pub)
+	if err != nil {
+		return nil, err
+	}
+
+	if err != nil {
+		return
+	}
+
+	if len(parent.SubjectKeyId) > 0 {
+		template.AuthorityKeyId = parent.SubjectKeyId
+	}
+
+	extensions, err := buildExtensions(template)
+	if err != nil {
+		return
+	}
+
+	asn1Issuer, err := subjectBytes(parent)
+	if err != nil {
+		return
+	}
+
+	asn1Subject, err := subjectBytes(template)
+	if err != nil {
+		return
+	}
+
+	encodedPublicKey := asn1.BitString{BitLength: len(publicKeyBytes) * 8, Bytes: publicKeyBytes}
+	c := tbsCertificate{
+		Version:            2,
+		SerialNumber:       template.SerialNumber,
+		SignatureAlgorithm: signatureAlgorithm,
+		Issuer:             asn1.RawValue{FullBytes: asn1Issuer},
+		Validity:           validity{template.NotBefore.UTC(), template.NotAfter.UTC()},
+		Subject:            asn1.RawValue{FullBytes: asn1Subject},
+		PublicKey:          publicKeyInfo{nil, publicKeyAlgorithm, encodedPublicKey},
+		Extensions:         extensions,
+	}
+
+	tbsCertContents, err := asn1.Marshal(c)
+	if err != nil {
+		return
+	}
+
+	c.Raw = tbsCertContents
+
+	h := hashFunc.New()
+	h.Write(tbsCertContents)
+	digest := h.Sum(nil)
+
+	var signature []byte
+
+	switch priv := priv.(type) {
+	case *rsa.PrivateKey:
+		signature, err = rsa.SignPKCS1v15(rand, priv, hashFunc, digest)
+	case *ecdsa.PrivateKey:
+		var r, s *big.Int
+		if r, s, err = ecdsa.Sign(rand, priv, digest); err == nil {
+			signature, err = asn1.Marshal(ecdsaSignature{r, s})
+		}
+	default:
+		panic("internal error")
+	}
+
+	if err != nil {
+		return
+	}
+
+	cert, err = asn1.Marshal(certificate{
+		nil,
+		c,
+		signatureAlgorithm,
+		asn1.BitString{Bytes: signature, BitLength: len(signature) * 8},
+	})
+	return
+}
+
+// pemCRLPrefix is the magic string that indicates that we have a PEM encoded
+// CRL.
+var pemCRLPrefix = []byte("-----BEGIN X509 CRL")
+
+// pemType is the type of a PEM encoded CRL.
+var pemType = "X509 CRL"
+
+// ParseCRL parses a CRL from the given bytes. It's often the case that PEM
+// encoded CRLs will appear where they should be DER encoded, so this function
+// will transparently handle PEM encoding as long as there isn't any leading
+// garbage.
+func ParseCRL(crlBytes []byte) (certList *pkix.CertificateList, err error) {
+	if bytes.HasPrefix(crlBytes, pemCRLPrefix) {
+		block, _ := pem.Decode(crlBytes)
+		if block != nil && block.Type == pemType {
+			crlBytes = block.Bytes
+		}
+	}
+	return ParseDERCRL(crlBytes)
+}
+
+// ParseDERCRL parses a DER encoded CRL from the given bytes.
+func ParseDERCRL(derBytes []byte) (certList *pkix.CertificateList, err error) {
+	certList = new(pkix.CertificateList)
+	_, err = asn1.Unmarshal(derBytes, certList)
+	if err != nil {
+		certList = nil
+	}
+	return
+}
+
+// CreateCRL returns a DER encoded CRL, signed by this Certificate, that
+// contains the given list of revoked certificates.
+//
+// The only supported key type is RSA (*rsa.PrivateKey for priv).
+func (c *Certificate) CreateCRL(rand io.Reader, priv interface{}, revokedCerts []pkix.RevokedCertificate, now, expiry time.Time) (crlBytes []byte, err error) {
+	rsaPriv, ok := priv.(*rsa.PrivateKey)
+	if !ok {
+		return nil, errors.New("x509: non-RSA private keys not supported")
+	}
+	tbsCertList := pkix.TBSCertificateList{
+		Version: 2,
+		Signature: pkix.AlgorithmIdentifier{
+			Algorithm: oidSignatureSHA1WithRSA,
+		},
+		Issuer:              c.Subject.ToRDNSequence(),
+		ThisUpdate:          now.UTC(),
+		NextUpdate:          expiry.UTC(),
+		RevokedCertificates: revokedCerts,
+	}
+
+	tbsCertListContents, err := asn1.Marshal(tbsCertList)
+	if err != nil {
+		return
+	}
+
+	h := sha1.New()
+	h.Write(tbsCertListContents)
+	digest := h.Sum(nil)
+
+	signature, err := rsa.SignPKCS1v15(rand, rsaPriv, crypto.SHA1, digest)
+	if err != nil {
+		return
+	}
+
+	return asn1.Marshal(pkix.CertificateList{
+		TBSCertList: tbsCertList,
+		SignatureAlgorithm: pkix.AlgorithmIdentifier{
+			Algorithm: oidSignatureSHA1WithRSA,
+		},
+		SignatureValue: asn1.BitString{Bytes: signature, BitLength: len(signature) * 8},
+	})
+}
+
+// CertificateRequest represents a PKCS #10, certificate signature request.
+type CertificateRequest struct {
+	Raw                      []byte // Complete ASN.1 DER content (CSR, signature algorithm and signature).
+	RawTBSCertificateRequest []byte // Certificate request info part of raw ASN.1 DER content.
+	RawSubjectPublicKeyInfo  []byte // DER encoded SubjectPublicKeyInfo.
+	RawSubject               []byte // DER encoded Subject.
+
+	Version            int
+	Signature          []byte
+	SignatureAlgorithm SignatureAlgorithm
+
+	PublicKeyAlgorithm PublicKeyAlgorithm
+	PublicKey          interface{}
+
+	Subject pkix.Name
+
+	// Attributes is a collection of attributes providing
+	// additional information about the subject of the certificate.
+	// See RFC 2986 section 4.1.
+	Attributes []pkix.AttributeTypeAndValueSET
+
+	// Extensions contains raw X.509 extensions. When parsing CSRs, this
+	// can be used to extract extensions that are not parsed by this
+	// package.
+	Extensions []pkix.Extension
+
+	// ExtraExtensions contains extensions to be copied, raw, into any
+	// marshaled CSR. Values override any extensions that would otherwise
+	// be produced based on the other fields but are overridden by any
+	// extensions specified in Attributes.
+	//
+	// The ExtraExtensions field is not populated when parsing CSRs, see
+	// Extensions.
+	ExtraExtensions []pkix.Extension
+
+	// Subject Alternate Name values.
+	DNSNames       []string
+	EmailAddresses []string
+	IPAddresses    []net.IP
+}
+
+// These structures reflect the ASN.1 structure of X.509 certificate
+// signature requests (see RFC 2986):
+
+type tbsCertificateRequest struct {
+	Raw        asn1.RawContent
+	Version    int
+	Subject    asn1.RawValue
+	PublicKey  publicKeyInfo
+	Attributes []pkix.AttributeTypeAndValueSET `asn1:"tag:0"`
+}
+
+type certificateRequest struct {
+	Raw                asn1.RawContent
+	TBSCSR             tbsCertificateRequest
+	SignatureAlgorithm pkix.AlgorithmIdentifier
+	SignatureValue     asn1.BitString
+}
+
+// oidExtensionRequest is a PKCS#9 OBJECT IDENTIFIER that indicates requested
+// extensions in a CSR.
+var oidExtensionRequest = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 14}
+
+// CreateCertificateRequest creates a new certificate based on a template. The
+// following members of template are used: Subject, Attributes,
+// SignatureAlgorithm, Extensions, DNSNames, EmailAddresses, and IPAddresses.
+// The private key is the private key of the signer.
+//
+// The returned slice is the certificate request in DER encoding.
+//
+// The only supported key types are RSA (*rsa.PrivateKey) and ECDSA
+// (*ecdsa.PrivateKey).
+func CreateCertificateRequest(rand io.Reader, template *CertificateRequest, priv interface{}) (csr []byte, err error) {
+	hashFunc, sigAlgo, err := signingParamsForPrivateKey(priv, template.SignatureAlgorithm)
+	if err != nil {
+		return nil, err
+	}
+
+	var publicKeyBytes []byte
+	var publicKeyAlgorithm pkix.AlgorithmIdentifier
+
+	switch priv := priv.(type) {
+	case *rsa.PrivateKey:
+		publicKeyBytes, publicKeyAlgorithm, err = marshalPublicKey(&priv.PublicKey)
+	case *ecdsa.PrivateKey:
+		publicKeyBytes, publicKeyAlgorithm, err = marshalPublicKey(&priv.PublicKey)
+	default:
+		panic("internal error")
+	}
+
+	if err != nil {
+		return nil, err
+	}
+
+	var extensions []pkix.Extension
+
+	if (len(template.DNSNames) > 0 || len(template.EmailAddresses) > 0 || len(template.IPAddresses) > 0) &&
+		!oidInExtensions(oidExtensionSubjectAltName, template.ExtraExtensions) {
+		sanBytes, err := marshalSANs(template.DNSNames, template.EmailAddresses, template.IPAddresses)
+		if err != nil {
+			return nil, err
+		}
+
+		extensions = append(extensions, pkix.Extension{
+			Id:    oidExtensionSubjectAltName,
+			Value: sanBytes,
+		})
+	}
+
+	extensions = append(extensions, template.ExtraExtensions...)
+
+	var attributes []pkix.AttributeTypeAndValueSET
+	attributes = append(attributes, template.Attributes...)
+
+	if len(extensions) > 0 {
+		// specifiedExtensions contains all the extensions that we
+		// found specified via template.Attributes.
+		specifiedExtensions := make(map[string]bool)
+
+		for _, atvSet := range template.Attributes {
+			if !atvSet.Type.Equal(oidExtensionRequest) {
+				continue
+			}
+
+			for _, atvs := range atvSet.Value {
+				for _, atv := range atvs {
+					specifiedExtensions[atv.Type.String()] = true
+				}
+			}
+		}
+
+		atvs := make([]pkix.AttributeTypeAndValue, 0, len(extensions))
+		for _, e := range extensions {
+			if specifiedExtensions[e.Id.String()] {
+				// Attributes already contained a value for
+				// this extension and it takes priority.
+				continue
+			}
+
+			atvs = append(atvs, pkix.AttributeTypeAndValue{
+				// There is no place for the critical flag in a CSR.
+				Type:  e.Id,
+				Value: e.Value,
+			})
+		}
+
+		// Append the extensions to an existing attribute if possible.
+		appended := false
+		for _, atvSet := range attributes {
+			if !atvSet.Type.Equal(oidExtensionRequest) || len(atvSet.Value) == 0 {
+				continue
+			}
+
+			atvSet.Value[0] = append(atvSet.Value[0], atvs...)
+			appended = true
+			break
+		}
+
+		// Otherwise, add a new attribute for the extensions.
+		if !appended {
+			attributes = append(attributes, pkix.AttributeTypeAndValueSET{
+				Type: oidExtensionRequest,
+				Value: [][]pkix.AttributeTypeAndValue{
+					atvs,
+				},
+			})
+		}
+	}
+
+	asn1Subject := template.RawSubject
+	if len(asn1Subject) == 0 {
+		asn1Subject, err = asn1.Marshal(template.Subject.ToRDNSequence())
+		if err != nil {
+			return
+		}
+	}
+
+	tbsCSR := tbsCertificateRequest{
+		Version: 0, // PKCS #10, RFC 2986
+		Subject: asn1.RawValue{FullBytes: asn1Subject},
+		PublicKey: publicKeyInfo{
+			Algorithm: publicKeyAlgorithm,
+			PublicKey: asn1.BitString{
+				Bytes:     publicKeyBytes,
+				BitLength: len(publicKeyBytes) * 8,
+			},
+		},
+		Attributes: attributes,
+	}
+
+	tbsCSRContents, err := asn1.Marshal(tbsCSR)
+	if err != nil {
+		return
+	}
+	tbsCSR.Raw = tbsCSRContents
+
+	h := hashFunc.New()
+	h.Write(tbsCSRContents)
+	digest := h.Sum(nil)
+
+	var signature []byte
+	switch priv := priv.(type) {
+	case *rsa.PrivateKey:
+		signature, err = rsa.SignPKCS1v15(rand, priv, hashFunc, digest)
+	case *ecdsa.PrivateKey:
+		var r, s *big.Int
+		if r, s, err = ecdsa.Sign(rand, priv, digest); err == nil {
+			signature, err = asn1.Marshal(ecdsaSignature{r, s})
+		}
+	default:
+		panic("internal error")
+	}
+
+	if err != nil {
+		return
+	}
+
+	return asn1.Marshal(certificateRequest{
+		TBSCSR:             tbsCSR,
+		SignatureAlgorithm: sigAlgo,
+		SignatureValue: asn1.BitString{
+			Bytes:     signature,
+			BitLength: len(signature) * 8,
+		},
+	})
+}
+
+// ParseCertificateRequest parses a single certificate request from the
+// given ASN.1 DER data.
+func ParseCertificateRequest(asn1Data []byte) (*CertificateRequest, error) {
+	var csr certificateRequest
+
+	rest, err := asn1.Unmarshal(asn1Data, &csr)
+	if err != nil {
+		return nil, err
+	} else if len(rest) != 0 {
+		return nil, asn1.SyntaxError{Msg: "trailing data"}
+	}
+
+	return parseCertificateRequest(&csr)
+}
+
+func parseCertificateRequest(in *certificateRequest) (*CertificateRequest, error) {
+	out := &CertificateRequest{
+		Raw: in.Raw,
+		RawTBSCertificateRequest: in.TBSCSR.Raw,
+		RawSubjectPublicKeyInfo:  in.TBSCSR.PublicKey.Raw,
+		RawSubject:               in.TBSCSR.Subject.FullBytes,
+
+		Signature:          in.SignatureValue.RightAlign(),
+		SignatureAlgorithm: getSignatureAlgorithmFromOID(in.SignatureAlgorithm.Algorithm),
+
+		PublicKeyAlgorithm: getPublicKeyAlgorithmFromOID(in.TBSCSR.PublicKey.Algorithm.Algorithm),
+
+		Version:    in.TBSCSR.Version,
+		Attributes: in.TBSCSR.Attributes,
+	}
+
+	var err error
+	out.PublicKey, err = parsePublicKey(out.PublicKeyAlgorithm, &in.TBSCSR.PublicKey)
+	if err != nil {
+		return nil, err
+	}
+
+	var subject pkix.RDNSequence
+	if _, err := asn1.Unmarshal(in.TBSCSR.Subject.FullBytes, &subject); err != nil {
+		return nil, err
+	}
+
+	out.Subject.FillFromRDNSequence(&subject)
+
+	var extensions []pkix.AttributeTypeAndValue
+
+	for _, atvSet := range in.TBSCSR.Attributes {
+		if !atvSet.Type.Equal(oidExtensionRequest) {
+			continue
+		}
+
+		for _, atvs := range atvSet.Value {
+			extensions = append(extensions, atvs...)
+		}
+	}
+
+	out.Extensions = make([]pkix.Extension, 0, len(extensions))
+
+	for _, e := range extensions {
+		value, ok := e.Value.([]byte)
+		if !ok {
+			return nil, errors.New("x509: extension attribute contained non-OCTET STRING data")
+		}
+
+		out.Extensions = append(out.Extensions, pkix.Extension{
+			Id:    e.Type,
+			Value: value,
+		})
+
+		if len(e.Type) == 4 && e.Type[0] == 2 && e.Type[1] == 5 && e.Type[2] == 29 {
+			switch e.Type[3] {
+			case 17:
+				out.DNSNames, out.EmailAddresses, out.IPAddresses, err = parseSANExtension(value)
+				if err != nil {
+					return nil, err
+				}
+			}
+		}
+	}
+
+	return out, nil
+}
diff --git a/src/crypto/x509/x509_test.go b/src/crypto/x509/x509_test.go
new file mode 100644
index 0000000..4f5173f
--- /dev/null
+++ b/src/crypto/x509/x509_test.go
@@ -0,0 +1,1027 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package x509
+
+import (
+	"bytes"
+	"crypto/dsa"
+	"crypto/ecdsa"
+	"crypto/elliptic"
+	"crypto/rand"
+	"crypto/rsa"
+	_ "crypto/sha256"
+	_ "crypto/sha512"
+	"crypto/x509/pkix"
+	"encoding/asn1"
+	"encoding/base64"
+	"encoding/hex"
+	"encoding/pem"
+	"math/big"
+	"net"
+	"os/exec"
+	"reflect"
+	"runtime"
+	"testing"
+	"time"
+)
+
+func TestParsePKCS1PrivateKey(t *testing.T) {
+	block, _ := pem.Decode([]byte(pemPrivateKey))
+	priv, err := ParsePKCS1PrivateKey(block.Bytes)
+	if err != nil {
+		t.Errorf("Failed to parse private key: %s", err)
+		return
+	}
+	if priv.PublicKey.N.Cmp(rsaPrivateKey.PublicKey.N) != 0 ||
+		priv.PublicKey.E != rsaPrivateKey.PublicKey.E ||
+		priv.D.Cmp(rsaPrivateKey.D) != 0 ||
+		priv.Primes[0].Cmp(rsaPrivateKey.Primes[0]) != 0 ||
+		priv.Primes[1].Cmp(rsaPrivateKey.Primes[1]) != 0 {
+		t.Errorf("got:%+v want:%+v", priv, rsaPrivateKey)
+	}
+}
+
+func TestParsePKIXPublicKey(t *testing.T) {
+	block, _ := pem.Decode([]byte(pemPublicKey))
+	pub, err := ParsePKIXPublicKey(block.Bytes)
+	if err != nil {
+		t.Errorf("Failed to parse RSA public key: %s", err)
+		return
+	}
+	rsaPub, ok := pub.(*rsa.PublicKey)
+	if !ok {
+		t.Errorf("Value returned from ParsePKIXPublicKey was not an RSA public key")
+		return
+	}
+
+	pubBytes2, err := MarshalPKIXPublicKey(rsaPub)
+	if err != nil {
+		t.Errorf("Failed to marshal RSA public key for the second time: %s", err)
+		return
+	}
+	if !bytes.Equal(pubBytes2, block.Bytes) {
+		t.Errorf("Reserialization of public key didn't match. got %x, want %x", pubBytes2, block.Bytes)
+	}
+}
+
+var pemPublicKey = `-----BEGIN PUBLIC KEY-----
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3VoPN9PKUjKFLMwOge6+
+wnDi8sbETGIx2FKXGgqtAKpzmem53kRGEQg8WeqRmp12wgp74TGpkEXsGae7RS1k
+enJCnma4fii+noGH7R0qKgHvPrI2Bwa9hzsH8tHxpyM3qrXslOmD45EH9SxIDUBJ
+FehNdaPbLP1gFyahKMsdfxFJLUvbUycuZSJ2ZnIgeVxwm4qbSvZInL9Iu4FzuPtg
+fINKcbbovy1qq4KvPIrXzhbY3PWDc6btxCf3SE0JdE1MCPThntB62/bLMSQ7xdDR
+FF53oIpvxe/SCOymfWq/LW849Ytv3Xwod0+wzAP8STXG4HSELS4UedPYeHJJJYcZ
++QIDAQAB
+-----END PUBLIC KEY-----
+`
+
+var pemPrivateKey = `-----BEGIN RSA PRIVATE KEY-----
+MIIBOgIBAAJBALKZD0nEffqM1ACuak0bijtqE2QrI/KLADv7l3kK3ppMyCuLKoF0
+fd7Ai2KW5ToIwzFofvJcS/STa6HA5gQenRUCAwEAAQJBAIq9amn00aS0h/CrjXqu
+/ThglAXJmZhOMPVn4eiu7/ROixi9sex436MaVeMqSNf7Ex9a8fRNfWss7Sqd9eWu
+RTUCIQDasvGASLqmjeffBNLTXV2A5g4t+kLVCpsEIZAycV5GswIhANEPLmax0ME/
+EO+ZJ79TJKN5yiGBRsv5yvx5UiHxajEXAiAhAol5N4EUyq6I9w1rYdhPMGpLfk7A
+IU2snfRJ6Nq2CQIgFrPsWRCkV+gOYcajD17rEqmuLrdIRexpg8N1DOSXoJ8CIGlS
+tAboUGBxTDq3ZroNism3DaMIbKPyYrAqhKov1h5V
+-----END RSA PRIVATE KEY-----
+`
+
+func bigFromString(s string) *big.Int {
+	ret := new(big.Int)
+	ret.SetString(s, 10)
+	return ret
+}
+
+func fromBase10(base10 string) *big.Int {
+	i := new(big.Int)
+	i.SetString(base10, 10)
+	return i
+}
+
+func bigFromHexString(s string) *big.Int {
+	ret := new(big.Int)
+	ret.SetString(s, 16)
+	return ret
+}
+
+var rsaPrivateKey = &rsa.PrivateKey{
+	PublicKey: rsa.PublicKey{
+		N: bigFromString("9353930466774385905609975137998169297361893554149986716853295022578535724979677252958524466350471210367835187480748268864277464700638583474144061408845077"),
+		E: 65537,
+	},
+	D: bigFromString("7266398431328116344057699379749222532279343923819063639497049039389899328538543087657733766554155839834519529439851673014800261285757759040931985506583861"),
+	Primes: []*big.Int{
+		bigFromString("98920366548084643601728869055592650835572950932266967461790948584315647051443"),
+		bigFromString("94560208308847015747498523884063394671606671904944666360068158221458669711639"),
+	},
+}
+
+func TestMarshalRSAPrivateKey(t *testing.T) {
+	priv := &rsa.PrivateKey{
+		PublicKey: rsa.PublicKey{
+			N: fromBase10("163463789223821934005382697499360491063202653175117663575997325752773828440517910965693338085989218523515777627185298180728491911224194106120335924014037649250961367599344976877654539058841495051754260530374204866970724486090227536836837180577955668114019388333679546429514334733370663119788211805264396414969732960370000525461085078052692794147890354611580731567721518924522511061735072404889936086508819296291634650994768496431656827090474620105813087195770539057874962969 [...]
+			E: 3,
+		},
+		D: fromBase10("1089758594825479560035884649995736607088017687834117757173315505018492189603452739771288920573261456823438517514568654538189946074827960707468906160093584328339742450662299845851030260392276633678361736868609004276571829091409933444915482937517995836999340772494618624324956892823708621575925990986174864212407187487986129938987423048992827162125929489414284042840719693244447408885774612310497861709885861944567553258778702322885238314955747007780271870542027573973795895379 [...]
+		Primes: []*big.Int{
+			fromBase10("1025363189502892836833747188838978207017355117492483312747347695538428729137306368764177201532277413433182799108299960196606011786562992097313508180436744488171474690412562218914213688661311117337381958560443"),
+			fromBase10("3467903426626310123395340254094941045497208049900750380025518552334536945536837294961497712862519984786362199788654739924501424784631315081391467293694361474867825728031147665777546570788493758372218019373"),
+			fromBase10("4597024781409332673052708605078359346966325141767460991205742124888960305710298765592730135879076084498363772408626791576005136245060321874472727132746643162385746062759369754202494417496879741537284589047"),
+		},
+	}
+
+	derBytes := MarshalPKCS1PrivateKey(priv)
+
+	priv2, err := ParsePKCS1PrivateKey(derBytes)
+	if err != nil {
+		t.Errorf("error parsing serialized key: %s", err)
+		return
+	}
+	if priv.PublicKey.N.Cmp(priv2.PublicKey.N) != 0 ||
+		priv.PublicKey.E != priv2.PublicKey.E ||
+		priv.D.Cmp(priv2.D) != 0 ||
+		len(priv2.Primes) != 3 ||
+		priv.Primes[0].Cmp(priv2.Primes[0]) != 0 ||
+		priv.Primes[1].Cmp(priv2.Primes[1]) != 0 ||
+		priv.Primes[2].Cmp(priv2.Primes[2]) != 0 {
+		t.Errorf("got:%+v want:%+v", priv, priv2)
+	}
+}
+
+type matchHostnamesTest struct {
+	pattern, host string
+	ok            bool
+}
+
+var matchHostnamesTests = []matchHostnamesTest{
+	{"a.b.c", "a.b.c", true},
+	{"a.b.c", "b.b.c", false},
+	{"", "b.b.c", false},
+	{"a.b.c", "", false},
+	{"example.com", "example.com", true},
+	{"example.com", "www.example.com", false},
+	{"*.example.com", "www.example.com", true},
+	{"*.example.com", "xyz.www.example.com", false},
+	{"*.*.example.com", "xyz.www.example.com", true},
+	{"*.www.*.com", "xyz.www.example.com", true},
+}
+
+func TestMatchHostnames(t *testing.T) {
+	for i, test := range matchHostnamesTests {
+		r := matchHostnames(test.pattern, test.host)
+		if r != test.ok {
+			t.Errorf("#%d mismatch got: %t want: %t", i, r, test.ok)
+		}
+	}
+}
+
+func TestMatchIP(t *testing.T) {
+	// Check that pattern matching is working.
+	c := &Certificate{
+		DNSNames: []string{"*.foo.bar.baz"},
+		Subject: pkix.Name{
+			CommonName: "*.foo.bar.baz",
+		},
+	}
+	err := c.VerifyHostname("quux.foo.bar.baz")
+	if err != nil {
+		t.Fatalf("VerifyHostname(quux.foo.bar.baz): %v", err)
+	}
+
+	// But check that if we change it to be matching against an IP address,
+	// it is rejected.
+	c = &Certificate{
+		DNSNames: []string{"*.2.3.4"},
+		Subject: pkix.Name{
+			CommonName: "*.2.3.4",
+		},
+	}
+	err = c.VerifyHostname("1.2.3.4")
+	if err == nil {
+		t.Fatalf("VerifyHostname(1.2.3.4) should have failed, did not")
+	}
+
+	c = &Certificate{
+		IPAddresses: []net.IP{net.ParseIP("127.0.0.1"), net.ParseIP("::1")},
+	}
+	err = c.VerifyHostname("127.0.0.1")
+	if err != nil {
+		t.Fatalf("VerifyHostname(127.0.0.1): %v", err)
+	}
+	err = c.VerifyHostname("::1")
+	if err != nil {
+		t.Fatalf("VerifyHostname(::1): %v", err)
+	}
+	err = c.VerifyHostname("[::1]")
+	if err != nil {
+		t.Fatalf("VerifyHostname([::1]): %v", err)
+	}
+}
+
+func TestCertificateParse(t *testing.T) {
+	s, _ := hex.DecodeString(certBytes)
+	certs, err := ParseCertificates(s)
+	if err != nil {
+		t.Error(err)
+	}
+	if len(certs) != 2 {
+		t.Errorf("Wrong number of certs: got %d want 2", len(certs))
+		return
+	}
+
+	err = certs[0].CheckSignatureFrom(certs[1])
+	if err != nil {
+		t.Error(err)
+	}
+
+	if err := certs[0].VerifyHostname("mail.google.com"); err != nil {
+		t.Error(err)
+	}
+
+	const expectedExtensions = 4
+	if n := len(certs[0].Extensions); n != expectedExtensions {
+		t.Errorf("want %d extensions, got %d", expectedExtensions, n)
+	}
+}
+
+var certBytes = "308203223082028ba00302010202106edf0d9499fd4533dd1297fc42a93be1300d06092a864886" +
+	"f70d0101050500304c310b3009060355040613025a4131253023060355040a131c546861777465" +
+	"20436f6e73756c74696e67202850747929204c74642e311630140603550403130d546861777465" +
+	"20534743204341301e170d3039303332353136343932395a170d3130303332353136343932395a" +
+	"3069310b3009060355040613025553311330110603550408130a43616c69666f726e6961311630" +
+	"140603550407130d4d6f756e7461696e205669657731133011060355040a130a476f6f676c6520" +
+	"496e63311830160603550403130f6d61696c2e676f6f676c652e636f6d30819f300d06092a8648" +
+	"86f70d010101050003818d0030818902818100c5d6f892fccaf5614b064149e80a2c9581a218ef" +
+	"41ec35bd7a58125ae76f9ea54ddc893abbeb029f6b73616bf0ffd868791fba7af9c4aebf3706ba" +
+	"3eeaeed27435b4ddcfb157c05f351d66aa87fee0de072d66d773affbd36ab78bef090e0cc861a9" +
+	"03ac90dd98b51c9c41566c017f0beec3bff391051ffba0f5cc6850ad2a590203010001a381e730" +
+	"81e430280603551d250421301f06082b0601050507030106082b06010505070302060960864801" +
+	"86f842040130360603551d1f042f302d302ba029a0278625687474703a2f2f63726c2e74686177" +
+	"74652e636f6d2f54686177746553474343412e63726c307206082b060105050701010466306430" +
+	"2206082b060105050730018616687474703a2f2f6f6373702e7468617774652e636f6d303e0608" +
+	"2b060105050730028632687474703a2f2f7777772e7468617774652e636f6d2f7265706f736974" +
+	"6f72792f5468617774655f5347435f43412e637274300c0603551d130101ff04023000300d0609" +
+	"2a864886f70d01010505000381810062f1f3050ebc105e497c7aedf87e24d2f4a986bb3b837bd1" +
+	"9b91ebcad98b065992f6bd2b49b7d6d3cb2e427a99d606c7b1d46352527fac39e6a8b6726de5bf" +
+	"70212a52cba07634a5e332011bd1868e78eb5e3c93cf03072276786f207494feaa0ed9d53b2110" +
+	"a76571f90209cdae884385c882587030ee15f33d761e2e45a6bc308203233082028ca003020102" +
+	"020430000002300d06092a864886f70d0101050500305f310b3009060355040613025553311730" +
+	"15060355040a130e566572695369676e2c20496e632e31373035060355040b132e436c61737320" +
+	"33205075626c6963205072696d6172792043657274696669636174696f6e20417574686f726974" +
+	"79301e170d3034303531333030303030305a170d3134303531323233353935395a304c310b3009" +
+	"060355040613025a4131253023060355040a131c54686177746520436f6e73756c74696e672028" +
+	"50747929204c74642e311630140603550403130d5468617774652053474320434130819f300d06" +
+	"092a864886f70d010101050003818d0030818902818100d4d367d08d157faecd31fe7d1d91a13f" +
+	"0b713cacccc864fb63fc324b0794bd6f80ba2fe10493c033fc093323e90b742b71c403c6d2cde2" +
+	"2ff50963cdff48a500bfe0e7f388b72d32de9836e60aad007bc4644a3b847503f270927d0e62f5" +
+	"21ab693684317590f8bfc76c881b06957cc9e5a8de75a12c7a68dfd5ca1c875860190203010001" +
+	"a381fe3081fb30120603551d130101ff040830060101ff020100300b0603551d0f040403020106" +
+	"301106096086480186f842010104040302010630280603551d110421301fa41d301b3119301706" +
+	"035504031310507269766174654c6162656c332d313530310603551d1f042a30283026a024a022" +
+	"8620687474703a2f2f63726c2e766572697369676e2e636f6d2f706361332e63726c303206082b" +
+	"0601050507010104263024302206082b060105050730018616687474703a2f2f6f6373702e7468" +
+	"617774652e636f6d30340603551d25042d302b06082b0601050507030106082b06010505070302" +
+	"06096086480186f8420401060a6086480186f845010801300d06092a864886f70d010105050003" +
+	"81810055ac63eadea1ddd2905f9f0bce76be13518f93d9052bc81b774bad6950a1eededcfddb07" +
+	"e9e83994dcab72792f06bfab8170c4a8edea5334edef1e53d906c7562bd15cf4d18a8eb42bb137" +
+	"9048084225c53e8acb7feb6f04d16dc574a2f7a27c7b603c77cd0ece48027f012fb69b37e02a2a" +
+	"36dcd585d6ace53f546f961e05af"
+
+func TestCreateSelfSignedCertificate(t *testing.T) {
+	random := rand.Reader
+
+	block, _ := pem.Decode([]byte(pemPrivateKey))
+	rsaPriv, err := ParsePKCS1PrivateKey(block.Bytes)
+	if err != nil {
+		t.Fatalf("Failed to parse private key: %s", err)
+	}
+
+	ecdsaPriv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
+	if err != nil {
+		t.Fatalf("Failed to generate ECDSA key: %s", err)
+	}
+
+	tests := []struct {
+		name      string
+		pub, priv interface{}
+		checkSig  bool
+		sigAlgo   SignatureAlgorithm
+	}{
+		{"RSA/RSA", &rsaPriv.PublicKey, rsaPriv, true, SHA1WithRSA},
+		{"RSA/ECDSA", &rsaPriv.PublicKey, ecdsaPriv, false, ECDSAWithSHA384},
+		{"ECDSA/RSA", &ecdsaPriv.PublicKey, rsaPriv, false, SHA256WithRSA},
+		{"ECDSA/ECDSA", &ecdsaPriv.PublicKey, ecdsaPriv, true, ECDSAWithSHA1},
+	}
+
+	testExtKeyUsage := []ExtKeyUsage{ExtKeyUsageClientAuth, ExtKeyUsageServerAuth}
+	testUnknownExtKeyUsage := []asn1.ObjectIdentifier{[]int{1, 2, 3}, []int{2, 59, 1}}
+	extraExtensionData := []byte("extra extension")
+
+	for _, test := range tests {
+		commonName := "test.example.com"
+		template := Certificate{
+			SerialNumber: big.NewInt(1),
+			Subject: pkix.Name{
+				CommonName:   commonName,
+				Organization: []string{"Σ Acme Co"},
+			},
+			NotBefore: time.Unix(1000, 0),
+			NotAfter:  time.Unix(100000, 0),
+
+			SignatureAlgorithm: test.sigAlgo,
+
+			SubjectKeyId: []byte{1, 2, 3, 4},
+			KeyUsage:     KeyUsageCertSign,
+
+			ExtKeyUsage:        testExtKeyUsage,
+			UnknownExtKeyUsage: testUnknownExtKeyUsage,
+
+			BasicConstraintsValid: true,
+			IsCA: true,
+
+			OCSPServer:            []string{"http://ocsp.example.com"},
+			IssuingCertificateURL: []string{"http://crt.example.com/ca1.crt"},
+
+			DNSNames:       []string{"test.example.com"},
+			EmailAddresses: []string{"gopher at golang.org"},
+			IPAddresses:    []net.IP{net.IPv4(127, 0, 0, 1).To4(), net.ParseIP("2001:4860:0:2001::68")},
+
+			PolicyIdentifiers:   []asn1.ObjectIdentifier{[]int{1, 2, 3}},
+			PermittedDNSDomains: []string{".example.com", "example.com"},
+
+			CRLDistributionPoints: []string{"http://crl1.example.com/ca1.crl", "http://crl2.example.com/ca1.crl"},
+
+			ExtraExtensions: []pkix.Extension{
+				{
+					Id:    []int{1, 2, 3, 4},
+					Value: extraExtensionData,
+				},
+				// This extension should override the SubjectKeyId, above.
+				{
+					Id:       oidExtensionSubjectKeyId,
+					Critical: false,
+					Value:    []byte{0x04, 0x04, 4, 3, 2, 1},
+				},
+			},
+		}
+
+		derBytes, err := CreateCertificate(random, &template, &template, test.pub, test.priv)
+		if err != nil {
+			t.Errorf("%s: failed to create certificate: %s", test.name, err)
+			continue
+		}
+
+		cert, err := ParseCertificate(derBytes)
+		if err != nil {
+			t.Errorf("%s: failed to parse certificate: %s", test.name, err)
+			continue
+		}
+
+		if len(cert.PolicyIdentifiers) != 1 || !cert.PolicyIdentifiers[0].Equal(template.PolicyIdentifiers[0]) {
+			t.Errorf("%s: failed to parse policy identifiers: got:%#v want:%#v", test.name, cert.PolicyIdentifiers, template.PolicyIdentifiers)
+		}
+
+		if len(cert.PermittedDNSDomains) != 2 || cert.PermittedDNSDomains[0] != ".example.com" || cert.PermittedDNSDomains[1] != "example.com" {
+			t.Errorf("%s: failed to parse name constraints: %#v", test.name, cert.PermittedDNSDomains)
+		}
+
+		if cert.Subject.CommonName != commonName {
+			t.Errorf("%s: subject wasn't correctly copied from the template. Got %s, want %s", test.name, cert.Subject.CommonName, commonName)
+		}
+
+		if cert.Issuer.CommonName != commonName {
+			t.Errorf("%s: issuer wasn't correctly copied from the template. Got %s, want %s", test.name, cert.Issuer.CommonName, commonName)
+		}
+
+		if cert.SignatureAlgorithm != test.sigAlgo {
+			t.Errorf("%s: SignatureAlgorithm wasn't copied from template. Got %v, want %v", test.name, cert.SignatureAlgorithm, test.sigAlgo)
+		}
+
+		if !reflect.DeepEqual(cert.ExtKeyUsage, testExtKeyUsage) {
+			t.Errorf("%s: extkeyusage wasn't correctly copied from the template. Got %v, want %v", test.name, cert.ExtKeyUsage, testExtKeyUsage)
+		}
+
+		if !reflect.DeepEqual(cert.UnknownExtKeyUsage, testUnknownExtKeyUsage) {
+			t.Errorf("%s: unknown extkeyusage wasn't correctly copied from the template. Got %v, want %v", test.name, cert.UnknownExtKeyUsage, testUnknownExtKeyUsage)
+		}
+
+		if !reflect.DeepEqual(cert.OCSPServer, template.OCSPServer) {
+			t.Errorf("%s: OCSP servers differ from template. Got %v, want %v", test.name, cert.OCSPServer, template.OCSPServer)
+		}
+
+		if !reflect.DeepEqual(cert.IssuingCertificateURL, template.IssuingCertificateURL) {
+			t.Errorf("%s: Issuing certificate URLs differ from template. Got %v, want %v", test.name, cert.IssuingCertificateURL, template.IssuingCertificateURL)
+		}
+
+		if !reflect.DeepEqual(cert.DNSNames, template.DNSNames) {
+			t.Errorf("%s: SAN DNS names differ from template. Got %v, want %v", test.name, cert.DNSNames, template.DNSNames)
+		}
+
+		if !reflect.DeepEqual(cert.EmailAddresses, template.EmailAddresses) {
+			t.Errorf("%s: SAN emails differ from template. Got %v, want %v", test.name, cert.EmailAddresses, template.EmailAddresses)
+		}
+
+		if !reflect.DeepEqual(cert.IPAddresses, template.IPAddresses) {
+			t.Errorf("%s: SAN IPs differ from template. Got %v, want %v", test.name, cert.IPAddresses, template.IPAddresses)
+		}
+
+		if !reflect.DeepEqual(cert.CRLDistributionPoints, template.CRLDistributionPoints) {
+			t.Errorf("%s: CRL distribution points differ from template. Got %v, want %v", test.name, cert.CRLDistributionPoints, template.CRLDistributionPoints)
+		}
+
+		if !bytes.Equal(cert.SubjectKeyId, []byte{4, 3, 2, 1}) {
+			t.Errorf("%s: ExtraExtensions didn't override SubjectKeyId", test.name)
+		}
+
+		if bytes.Index(derBytes, extraExtensionData) == -1 {
+			t.Errorf("%s: didn't find extra extension in DER output", test.name)
+		}
+
+		if test.checkSig {
+			err = cert.CheckSignatureFrom(cert)
+			if err != nil {
+				t.Errorf("%s: signature verification failed: %s", test.name, err)
+			}
+		}
+	}
+}
+
+// Self-signed certificate using ECDSA with SHA1 & secp256r1
+var ecdsaSHA1CertPem = `
+-----BEGIN CERTIFICATE-----
+MIICDjCCAbUCCQDF6SfN0nsnrjAJBgcqhkjOPQQBMIGPMQswCQYDVQQGEwJVUzET
+MBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEVMBMG
+A1UECgwMR29vZ2xlLCBJbmMuMRcwFQYDVQQDDA53d3cuZ29vZ2xlLmNvbTEjMCEG
+CSqGSIb3DQEJARYUZ29sYW5nLWRldkBnbWFpbC5jb20wHhcNMTIwNTIwMjAyMDUw
+WhcNMjIwNTE4MjAyMDUwWjCBjzELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlm
+b3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxFTATBgNVBAoMDEdvb2dsZSwg
+SW5jLjEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20xIzAhBgkqhkiG9w0BCQEWFGdv
+bGFuZy1kZXZAZ21haWwuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE/Wgn
+WQDo5+bz71T0327ERgd5SDDXFbXLpzIZDXTkjpe8QTEbsF+ezsQfrekrpDPC4Cd3
+P9LY0tG+aI8IyVKdUjAJBgcqhkjOPQQBA0gAMEUCIGlsqMcRqWVIWTD6wXwe6Jk2
+DKxL46r/FLgJYnzBEH99AiEA3fBouObsvV1R3oVkb4BQYnD4/4LeId6lAT43YvyV
+a/A=
+-----END CERTIFICATE-----
+`
+
+// Self-signed certificate using ECDSA with SHA256 & secp256r1
+var ecdsaSHA256p256CertPem = `
+-----BEGIN CERTIFICATE-----
+MIICDzCCAbYCCQDlsuMWvgQzhTAKBggqhkjOPQQDAjCBjzELMAkGA1UEBhMCVVMx
+EzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxFTAT
+BgNVBAoMDEdvb2dsZSwgSW5jLjEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20xIzAh
+BgkqhkiG9w0BCQEWFGdvbGFuZy1kZXZAZ21haWwuY29tMB4XDTEyMDUyMTAwMTkx
+NloXDTIyMDUxOTAwMTkxNlowgY8xCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxp
+Zm9ybmlhMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MRUwEwYDVQQKDAxHb29nbGUs
+IEluYy4xFzAVBgNVBAMMDnd3dy5nb29nbGUuY29tMSMwIQYJKoZIhvcNAQkBFhRn
+b2xhbmctZGV2QGdtYWlsLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABPMt
+2ErhxAty5EJRu9yM+MTy+hUXm3pdW1ensAv382KoGExSXAFWP7pjJnNtHO+XSwVm
+YNtqjcAGFKpweoN//kQwCgYIKoZIzj0EAwIDRwAwRAIgIYSaUA/IB81gjbIw/hUV
+70twxJr5EcgOo0hLp3Jm+EYCIFDO3NNcgmURbJ1kfoS3N/0O+irUtoPw38YoNkqJ
+h5wi
+-----END CERTIFICATE-----
+`
+
+// Self-signed certificate using ECDSA with SHA256 & secp384r1
+var ecdsaSHA256p384CertPem = `
+-----BEGIN CERTIFICATE-----
+MIICSjCCAdECCQDje/no7mXkVzAKBggqhkjOPQQDAjCBjjELMAkGA1UEBhMCVVMx
+EzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxFDAS
+BgNVBAoMC0dvb2dsZSwgSW5jMRcwFQYDVQQDDA53d3cuZ29vZ2xlLmNvbTEjMCEG
+CSqGSIb3DQEJARYUZ29sYW5nLWRldkBnbWFpbC5jb20wHhcNMTIwNTIxMDYxMDM0
+WhcNMjIwNTE5MDYxMDM0WjCBjjELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlm
+b3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxFDASBgNVBAoMC0dvb2dsZSwg
+SW5jMRcwFQYDVQQDDA53d3cuZ29vZ2xlLmNvbTEjMCEGCSqGSIb3DQEJARYUZ29s
+YW5nLWRldkBnbWFpbC5jb20wdjAQBgcqhkjOPQIBBgUrgQQAIgNiAARRuzRNIKRK
+jIktEmXanNmrTR/q/FaHXLhWRZ6nHWe26Fw7Rsrbk+VjGy4vfWtNn7xSFKrOu5ze
+qxKnmE0h5E480MNgrUiRkaGO2GMJJVmxx20aqkXOk59U8yGA4CghE6MwCgYIKoZI
+zj0EAwIDZwAwZAIwBZEN8gvmRmfeP/9C1PRLzODIY4JqWub2PLRT4mv9GU+yw3Gr
+PU9A3CHMdEcdw/MEAjBBO1lId8KOCh9UZunsSMfqXiVurpzmhWd6VYZ/32G+M+Mh
+3yILeYQzllt/g0rKVRk=
+-----END CERTIFICATE-----
+`
+
+// Self-signed certificate using ECDSA with SHA384 & secp521r1
+var ecdsaSHA384p521CertPem = `
+-----BEGIN CERTIFICATE-----
+MIICljCCAfcCCQDhp1AFD/ahKjAKBggqhkjOPQQDAzCBjjELMAkGA1UEBhMCVVMx
+EzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxFDAS
+BgNVBAoMC0dvb2dsZSwgSW5jMRcwFQYDVQQDDA53d3cuZ29vZ2xlLmNvbTEjMCEG
+CSqGSIb3DQEJARYUZ29sYW5nLWRldkBnbWFpbC5jb20wHhcNMTIwNTIxMTUwNDI5
+WhcNMjIwNTE5MTUwNDI5WjCBjjELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlm
+b3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxFDASBgNVBAoMC0dvb2dsZSwg
+SW5jMRcwFQYDVQQDDA53d3cuZ29vZ2xlLmNvbTEjMCEGCSqGSIb3DQEJARYUZ29s
+YW5nLWRldkBnbWFpbC5jb20wgZswEAYHKoZIzj0CAQYFK4EEACMDgYYABACqx9Rv
+IssRs1LWYcNN+WffwlHw4Tv3y8/LIAA9MF1ZScIonU9nRMxt4a2uGJVCPDw6JHpz
+PaYc0E9puLoE9AfKpwFr59Jkot7dBg55SKPEFkddoip/rvmN7NPAWjMBirOwjOkm
+8FPthvPhGPqsu9AvgVuHu3PosWiHGNrhh379pva8MzAKBggqhkjOPQQDAwOBjAAw
+gYgCQgEHNmswkUdPpHqrVxp9PvLVl+xxPuHBkT+75z9JizyxtqykHQo9Uh6SWCYH
+BF9KLolo01wMt8DjoYP5Fb3j5MH7xwJCAbWZzTOp4l4DPkIvAh4LeC4VWbwPPyqh
+kBg71w/iEcSY3wUKgHGcJJrObZw7wys91I5kENljqw/Samdr3ka+jBJa
+-----END CERTIFICATE-----
+`
+
+var ecdsaTests = []struct {
+	sigAlgo SignatureAlgorithm
+	pemCert string
+}{
+	{ECDSAWithSHA1, ecdsaSHA1CertPem},
+	{ECDSAWithSHA256, ecdsaSHA256p256CertPem},
+	{ECDSAWithSHA256, ecdsaSHA256p384CertPem},
+	{ECDSAWithSHA384, ecdsaSHA384p521CertPem},
+}
+
+func TestECDSA(t *testing.T) {
+	for i, test := range ecdsaTests {
+		pemBlock, _ := pem.Decode([]byte(test.pemCert))
+		cert, err := ParseCertificate(pemBlock.Bytes)
+		if err != nil {
+			t.Errorf("%d: failed to parse certificate: %s", i, err)
+			continue
+		}
+		if sa := cert.SignatureAlgorithm; sa != test.sigAlgo {
+			t.Errorf("%d: signature algorithm is %v, want %v", i, sa, test.sigAlgo)
+		}
+		if parsedKey, ok := cert.PublicKey.(*ecdsa.PublicKey); !ok {
+			t.Errorf("%d: wanted an ECDSA public key but found: %#v", i, parsedKey)
+		}
+		if pka := cert.PublicKeyAlgorithm; pka != ECDSA {
+			t.Errorf("%d: public key algorithm is %v, want ECDSA", i, pka)
+		}
+		if err = cert.CheckSignatureFrom(cert); err != nil {
+			t.Errorf("%d: certificate verification failed: %s", i, err)
+		}
+	}
+}
+
+// Self-signed certificate using DSA with SHA1
+var dsaCertPem = `-----BEGIN CERTIFICATE-----
+MIIEDTCCA82gAwIBAgIJALHPghaoxeDhMAkGByqGSM44BAMweTELMAkGA1UEBhMC
+VVMxCzAJBgNVBAgTAk5DMQ8wDQYDVQQHEwZOZXd0b24xFDASBgNVBAoTC0dvb2ds
+ZSwgSW5jMRIwEAYDVQQDEwlKb24gQWxsaWUxIjAgBgkqhkiG9w0BCQEWE2pvbmFs
+bGllQGdvb2dsZS5jb20wHhcNMTEwNTE0MDMwMTQ1WhcNMTEwNjEzMDMwMTQ1WjB5
+MQswCQYDVQQGEwJVUzELMAkGA1UECBMCTkMxDzANBgNVBAcTBk5ld3RvbjEUMBIG
+A1UEChMLR29vZ2xlLCBJbmMxEjAQBgNVBAMTCUpvbiBBbGxpZTEiMCAGCSqGSIb3
+DQEJARYTam9uYWxsaWVAZ29vZ2xlLmNvbTCCAbcwggEsBgcqhkjOOAQBMIIBHwKB
+gQC8hLUnQ7FpFYu4WXTj6DKvXvz8QrJkNJCVMTpKAT7uBpobk32S5RrPKXocd4gN
+8lyGB9ggS03EVlEwXvSmO0DH2MQtke2jl9j1HLydClMf4sbx5V6TV9IFw505U1iW
+jL7awRMgxge+FsudtJK254FjMFo03ZnOQ8ZJJ9E6AEDrlwIVAJpnBn9moyP11Ox5
+Asc/5dnjb6dPAoGBAJFHd4KVv1iTVCvEG6gGiYop5DJh28hUQcN9kul+2A0yPUSC
+X93oN00P8Vh3eYgSaCWZsha7zDG53MrVJ0Zf6v/X/CoZNhLldeNOepivTRAzn+Rz
+kKUYy5l1sxYLHQKF0UGNCXfFKZT0PCmgU+PWhYNBBMn6/cIh44vp85ideo5CA4GE
+AAKBgFmifCafzeRaohYKXJgMGSEaggCVCRq5xdyDCat+wbOkjC4mfG01/um3G8u5
+LxasjlWRKTR/tcAL7t0QuokVyQaYdVypZXNaMtx1db7YBuHjj3aP+8JOQRI9xz8c
+bp5NDJ5pISiFOv4p3GZfqZPcqckDt78AtkQrmnal2txhhjF6o4HeMIHbMB0GA1Ud
+DgQWBBQVyyr7hO11ZFFpWX50298Sa3V+rzCBqwYDVR0jBIGjMIGggBQVyyr7hO11
+ZFFpWX50298Sa3V+r6F9pHsweTELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAk5DMQ8w
+DQYDVQQHEwZOZXd0b24xFDASBgNVBAoTC0dvb2dsZSwgSW5jMRIwEAYDVQQDEwlK
+b24gQWxsaWUxIjAgBgkqhkiG9w0BCQEWE2pvbmFsbGllQGdvb2dsZS5jb22CCQCx
+z4IWqMXg4TAMBgNVHRMEBTADAQH/MAkGByqGSM44BAMDLwAwLAIUPtn/5j8Q1jJI
+7ggOIsgrhgUdjGQCFCsmDq1H11q9+9Wp9IMeGrTSKHIM
+-----END CERTIFICATE-----
+`
+
+func TestParseCertificateWithDsaPublicKey(t *testing.T) {
+	expectedKey := &dsa.PublicKey{
+		Parameters: dsa.Parameters{
+			P: bigFromHexString("00BC84B52743B169158BB85974E3E832AF5EFCFC42B264349095313A4A013EEE069A1B937D92E51ACF297A1C77880DF25C8607D8204B4DC45651305EF4A63B40C7D8C42D91EDA397D8F51CBC9D0A531FE2C6F1E55E9357D205C39D395358968CBEDAC11320C607BE16CB9DB492B6E78163305A34DD99CE43C64927D13A0040EB97"),
+			Q: bigFromHexString("009A67067F66A323F5D4EC7902C73FE5D9E36FA74F"),
+			G: bigFromHexString("009147778295BF5893542BC41BA806898A29E43261DBC85441C37D92E97ED80D323D44825FDDE8374D0FF15877798812682599B216BBCC31B9DCCAD527465FEAFFD7FC2A193612E575E34E7A98AF4D10339FE47390A518CB9975B3160B1D0285D1418D0977C52994F43C29A053E3D685834104C9FAFDC221E38BE9F3989D7A8E42"),
+		},
+		Y: bigFromHexString("59A27C269FCDE45AA2160A5C980C19211A820095091AB9C5DC8309AB7EC1B3A48C2E267C6D35FEE9B71BCBB92F16AC8E559129347FB5C00BEEDD10BA8915C90698755CA965735A32DC7575BED806E1E38F768FFBC24E41123DC73F1C6E9E4D0C9E692128853AFE29DC665FA993DCA9C903B7BF00B6442B9A76A5DADC6186317A"),
+	}
+	pemBlock, _ := pem.Decode([]byte(dsaCertPem))
+	cert, err := ParseCertificate(pemBlock.Bytes)
+	if err != nil {
+		t.Fatalf("Failed to parse certificate: %s", err)
+	}
+	if cert.PublicKeyAlgorithm != DSA {
+		t.Errorf("Parsed key algorithm was not DSA")
+	}
+	parsedKey, ok := cert.PublicKey.(*dsa.PublicKey)
+	if !ok {
+		t.Fatalf("Parsed key was not a DSA key: %s", err)
+	}
+	if expectedKey.Y.Cmp(parsedKey.Y) != 0 ||
+		expectedKey.P.Cmp(parsedKey.P) != 0 ||
+		expectedKey.Q.Cmp(parsedKey.Q) != 0 ||
+		expectedKey.G.Cmp(parsedKey.G) != 0 {
+		t.Fatal("Parsed key differs from expected key")
+	}
+}
+
+func TestParseCertificateWithDSASignatureAlgorithm(t *testing.T) {
+	pemBlock, _ := pem.Decode([]byte(dsaCertPem))
+	cert, err := ParseCertificate(pemBlock.Bytes)
+	if err != nil {
+		t.Fatalf("Failed to parse certificate: %s", err)
+	}
+	if cert.SignatureAlgorithm != DSAWithSHA1 {
+		t.Errorf("Parsed signature algorithm was not DSAWithSHA1")
+	}
+}
+
+func TestVerifyCertificateWithDSASignature(t *testing.T) {
+	pemBlock, _ := pem.Decode([]byte(dsaCertPem))
+	cert, err := ParseCertificate(pemBlock.Bytes)
+	if err != nil {
+		t.Fatalf("Failed to parse certificate: %s", err)
+	}
+	// test cert is self-signed
+	if err = cert.CheckSignatureFrom(cert); err != nil {
+		t.Fatalf("DSA Certificate verification failed: %s", err)
+	}
+}
+
+const pemCertificate = `-----BEGIN CERTIFICATE-----
+MIIB5DCCAZCgAwIBAgIBATALBgkqhkiG9w0BAQUwLTEQMA4GA1UEChMHQWNtZSBDbzEZMBcGA1UE
+AxMQdGVzdC5leGFtcGxlLmNvbTAeFw03MDAxMDEwMDE2NDBaFw03MDAxMDIwMzQ2NDBaMC0xEDAO
+BgNVBAoTB0FjbWUgQ28xGTAXBgNVBAMTEHRlc3QuZXhhbXBsZS5jb20wWjALBgkqhkiG9w0BAQED
+SwAwSAJBALKZD0nEffqM1ACuak0bijtqE2QrI/KLADv7l3kK3ppMyCuLKoF0fd7Ai2KW5ToIwzFo
+fvJcS/STa6HA5gQenRUCAwEAAaOBnjCBmzAOBgNVHQ8BAf8EBAMCAAQwDwYDVR0TAQH/BAUwAwEB
+/zANBgNVHQ4EBgQEAQIDBDAPBgNVHSMECDAGgAQBAgMEMBsGA1UdEQQUMBKCEHRlc3QuZXhhbXBs
+ZS5jb20wDwYDVR0gBAgwBjAEBgIqAzAqBgNVHR4EIzAhoB8wDoIMLmV4YW1wbGUuY29tMA2CC2V4
+YW1wbGUuY29tMAsGCSqGSIb3DQEBBQNBAHKZKoS1wEQOGhgklx4+/yFYQlnqwKXvar/ZecQvJwui
+0seMQnwBhwdBkHfVIU2Fu5VUMRyxlf0ZNaDXcpU581k=
+-----END CERTIFICATE-----`
+
+func TestCRLCreation(t *testing.T) {
+	block, _ := pem.Decode([]byte(pemPrivateKey))
+	priv, _ := ParsePKCS1PrivateKey(block.Bytes)
+	block, _ = pem.Decode([]byte(pemCertificate))
+	cert, _ := ParseCertificate(block.Bytes)
+
+	now := time.Unix(1000, 0)
+	expiry := time.Unix(10000, 0)
+
+	revokedCerts := []pkix.RevokedCertificate{
+		{
+			SerialNumber:   big.NewInt(1),
+			RevocationTime: now,
+		},
+		{
+			SerialNumber:   big.NewInt(42),
+			RevocationTime: now,
+		},
+	}
+
+	crlBytes, err := cert.CreateCRL(rand.Reader, priv, revokedCerts, now, expiry)
+	if err != nil {
+		t.Errorf("error creating CRL: %s", err)
+	}
+
+	_, err = ParseDERCRL(crlBytes)
+	if err != nil {
+		t.Errorf("error reparsing CRL: %s", err)
+	}
+}
+
+func fromBase64(in string) []byte {
+	out := make([]byte, base64.StdEncoding.DecodedLen(len(in)))
+	n, err := base64.StdEncoding.Decode(out, []byte(in))
+	if err != nil {
+		panic("failed to base64 decode")
+	}
+	return out[:n]
+}
+
+func TestParseDERCRL(t *testing.T) {
+	derBytes := fromBase64(derCRLBase64)
+	certList, err := ParseDERCRL(derBytes)
+	if err != nil {
+		t.Errorf("error parsing: %s", err)
+		return
+	}
+	numCerts := len(certList.TBSCertList.RevokedCertificates)
+	expected := 88
+	if numCerts != expected {
+		t.Errorf("bad number of revoked certificates. got: %d want: %d", numCerts, expected)
+	}
+
+	if certList.HasExpired(time.Unix(1302517272, 0)) {
+		t.Errorf("CRL has expired (but shouldn't have)")
+	}
+
+	// Can't check the signature here without a package cycle.
+}
+
+func TestCRLWithoutExpiry(t *testing.T) {
+	derBytes := fromBase64("MIHYMIGZMAkGByqGSM44BAMwEjEQMA4GA1UEAxMHQ2FybERTUxcNOTkwODI3MDcwMDAwWjBpMBMCAgDIFw05OTA4MjIwNzAwMDBaMBMCAgDJFw05OTA4MjIwNzAwMDBaMBMCAgDTFw05OTA4MjIwNzAwMDBaMBMCAgDSFw05OTA4MjIwNzAwMDBaMBMCAgDUFw05OTA4MjQwNzAwMDBaMAkGByqGSM44BAMDLwAwLAIUfmVSdjP+NHMX0feW+aDU2G1cfT0CFAJ6W7fVWxjBz4fvftok8yqDnDWh")
+	certList, err := ParseDERCRL(derBytes)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if !certList.TBSCertList.NextUpdate.IsZero() {
+		t.Errorf("NextUpdate is not the zero value")
+	}
+}
+
+func TestParsePEMCRL(t *testing.T) {
+	pemBytes := fromBase64(pemCRLBase64)
+	certList, err := ParseCRL(pemBytes)
+	if err != nil {
+		t.Errorf("error parsing: %s", err)
+		return
+	}
+	numCerts := len(certList.TBSCertList.RevokedCertificates)
+	expected := 2
+	if numCerts != expected {
+		t.Errorf("bad number of revoked certificates. got: %d want: %d", numCerts, expected)
+	}
+
+	if certList.HasExpired(time.Unix(1302517272, 0)) {
+		t.Errorf("CRL has expired (but shouldn't have)")
+	}
+
+	// Can't check the signature here without a package cycle.
+}
+
+func TestImports(t *testing.T) {
+	switch runtime.GOOS {
+	case "android", "nacl":
+		t.Skipf("skipping on %s", runtime.GOOS)
+	}
+
+	if err := exec.Command("go", "run", "x509_test_import.go").Run(); err != nil {
+		t.Errorf("failed to run x509_test_import.go: %s", err)
+	}
+}
+
+const derCRLBase64 = "MIINqzCCDJMCAQEwDQYJKoZIhvcNAQEFBQAwVjEZMBcGA1UEAxMQUEtJIEZJTk1FQ0NBTklDQTEVMBMGA1UEChMMRklOTUVDQ0FOSUNBMRUwEwYDVQQLEwxGSU5NRUNDQU5JQ0ExCzAJBgNVBAYTAklUFw0xMTA1MDQxNjU3NDJaFw0xMTA1MDQyMDU3NDJaMIIMBzAhAg4Ze1od49Lt1qIXBydAzhcNMDkwNzE2MDg0MzIyWjAAMCECDl0HSL9bcZ1Ci/UHJ0DPFw0wOTA3MTYwODQzMTNaMAAwIQIOESB9tVAmX3cY7QcnQNAXDTA5MDcxNjA4NDUyMlowADAhAg4S1tGAQ3mHt8uVBydA1RcNMDkwODA0MTUyNTIyWjAAMCECDlQ249Y7vtC25ScHJ0DWFw0wOTA4MDQxNTI1MzdaMAAwIQIOISMop3NkA4PfYwcnQNkXDTA5MDgwNDExMD [...]
+
+const pemCRLBase64 = "LS0tLS1CRUdJTiBYNTA5IENSTC0tLS0tDQpNSUlCOWpDQ0FWOENBUUV3RFFZSktvWklodmNOQVFFRkJRQXdiREVhTUJnR0ExVUVDaE1SVWxOQklGTmxZM1Z5DQphWFI1SUVsdVl5NHhIakFjQmdOVkJBTVRGVkpUUVNCUWRXSnNhV01nVW05dmRDQkRRU0IyTVRFdU1Dd0dDU3FHDQpTSWIzRFFFSkFSWWZjbk5oYTJWdmJuSnZiM1J6YVdkdVFISnpZWE5sWTNWeWFYUjVMbU52YlJjTk1URXdNakl6DQpNVGt5T0RNd1doY05NVEV3T0RJeU1Ua3lPRE13V2pDQmpEQktBaEVBckRxb2g5RkhKSFhUN09QZ3V1bjQrQmNODQpNRGt4TVRBeU1UUXlOekE1V2pBbU1Bb0dBMVVkRlFRRENnRUpNQmdHQTFVZEdBUVJHQTh5TURBNU1URXdNak [...]
+
+func TestCreateCertificateRequest(t *testing.T) {
+	random := rand.Reader
+
+	block, _ := pem.Decode([]byte(pemPrivateKey))
+	rsaPriv, err := ParsePKCS1PrivateKey(block.Bytes)
+	if err != nil {
+		t.Fatalf("Failed to parse private key: %s", err)
+	}
+
+	ecdsa256Priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
+	if err != nil {
+		t.Fatalf("Failed to generate ECDSA key: %s", err)
+	}
+
+	ecdsa384Priv, err := ecdsa.GenerateKey(elliptic.P384(), rand.Reader)
+	if err != nil {
+		t.Fatalf("Failed to generate ECDSA key: %s", err)
+	}
+
+	ecdsa521Priv, err := ecdsa.GenerateKey(elliptic.P521(), rand.Reader)
+	if err != nil {
+		t.Fatalf("Failed to generate ECDSA key: %s", err)
+	}
+
+	tests := []struct {
+		name    string
+		priv    interface{}
+		sigAlgo SignatureAlgorithm
+	}{
+		{"RSA", rsaPriv, SHA1WithRSA},
+		{"ECDSA-256", ecdsa256Priv, ECDSAWithSHA1},
+		{"ECDSA-384", ecdsa384Priv, ECDSAWithSHA1},
+		{"ECDSA-521", ecdsa521Priv, ECDSAWithSHA1},
+	}
+
+	for _, test := range tests {
+		template := CertificateRequest{
+			Subject: pkix.Name{
+				CommonName:   "test.example.com",
+				Organization: []string{"Σ Acme Co"},
+			},
+			SignatureAlgorithm: test.sigAlgo,
+			DNSNames:           []string{"test.example.com"},
+			EmailAddresses:     []string{"gopher at golang.org"},
+			IPAddresses:        []net.IP{net.IPv4(127, 0, 0, 1).To4(), net.ParseIP("2001:4860:0:2001::68")},
+		}
+
+		derBytes, err := CreateCertificateRequest(random, &template, test.priv)
+		if err != nil {
+			t.Errorf("%s: failed to create certificate request: %s", test.name, err)
+			continue
+		}
+
+		out, err := ParseCertificateRequest(derBytes)
+		if err != nil {
+			t.Errorf("%s: failed to create certificate request: %s", test.name, err)
+			continue
+		}
+
+		if out.Subject.CommonName != template.Subject.CommonName {
+			t.Errorf("%s: output subject common name and template subject common name don't match", test.name)
+		} else if len(out.Subject.Organization) != len(template.Subject.Organization) {
+			t.Errorf("%s: output subject organisation and template subject organisation don't match", test.name)
+		} else if len(out.DNSNames) != len(template.DNSNames) {
+			t.Errorf("%s: output DNS names and template DNS names don't match", test.name)
+		} else if len(out.EmailAddresses) != len(template.EmailAddresses) {
+			t.Errorf("%s: output email addresses and template email addresses don't match", test.name)
+		} else if len(out.IPAddresses) != len(template.IPAddresses) {
+			t.Errorf("%s: output IP addresses and template IP addresses names don't match", test.name)
+		}
+	}
+}
+
+func marshalAndParseCSR(t *testing.T, template *CertificateRequest) *CertificateRequest {
+	block, _ := pem.Decode([]byte(pemPrivateKey))
+	rsaPriv, err := ParsePKCS1PrivateKey(block.Bytes)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	derBytes, err := CreateCertificateRequest(rand.Reader, template, rsaPriv)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	csr, err := ParseCertificateRequest(derBytes)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	return csr
+}
+
+func TestCertificateRequestOverrides(t *testing.T) {
+	sanContents, err := marshalSANs([]string{"foo.example.com"}, nil, nil)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	template := CertificateRequest{
+		Subject: pkix.Name{
+			CommonName:   "test.example.com",
+			Organization: []string{"Σ Acme Co"},
+		},
+		DNSNames: []string{"test.example.com"},
+
+		// An explicit extension should override the DNSNames from the
+		// template.
+		ExtraExtensions: []pkix.Extension{
+			{
+				Id:    oidExtensionSubjectAltName,
+				Value: sanContents,
+			},
+		},
+	}
+
+	csr := marshalAndParseCSR(t, &template)
+
+	if len(csr.DNSNames) != 1 || csr.DNSNames[0] != "foo.example.com" {
+		t.Errorf("Extension did not override template. Got %v\n", csr.DNSNames)
+	}
+
+	// If there is already an attribute with X.509 extensions then the
+	// extra extensions should be added to it rather than creating a CSR
+	// with two extension attributes.
+
+	template.Attributes = []pkix.AttributeTypeAndValueSET{
+		{
+			Type: oidExtensionRequest,
+			Value: [][]pkix.AttributeTypeAndValue{
+				{
+					{
+						Type:  oidExtensionAuthorityInfoAccess,
+						Value: []byte("foo"),
+					},
+				},
+			},
+		},
+	}
+
+	csr = marshalAndParseCSR(t, &template)
+	if l := len(csr.Attributes); l != 1 {
+		t.Errorf("incorrect number of attributes: %d\n", l)
+	}
+
+	if !csr.Attributes[0].Type.Equal(oidExtensionRequest) ||
+		len(csr.Attributes[0].Value) != 1 ||
+		len(csr.Attributes[0].Value[0]) != 2 {
+		t.Errorf("bad attributes: %#v\n", csr.Attributes)
+	}
+
+	sanContents2, err := marshalSANs([]string{"foo2.example.com"}, nil, nil)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	// Extensions in Attributes should override those in ExtraExtensions.
+	template.Attributes[0].Value[0] = append(template.Attributes[0].Value[0], pkix.AttributeTypeAndValue{
+		Type:  oidExtensionSubjectAltName,
+		Value: sanContents2,
+	})
+
+	csr = marshalAndParseCSR(t, &template)
+
+	if len(csr.DNSNames) != 1 || csr.DNSNames[0] != "foo2.example.com" {
+		t.Errorf("Attributes did not override ExtraExtensions. Got %v\n", csr.DNSNames)
+	}
+}
+
+func TestParseCertificateRequest(t *testing.T) {
+	csrBytes := fromBase64(csrBase64)
+	csr, err := ParseCertificateRequest(csrBytes)
+	if err != nil {
+		t.Fatalf("failed to parse CSR: %s", err)
+	}
+
+	if len(csr.EmailAddresses) != 1 || csr.EmailAddresses[0] != "gopher at golang.org" {
+		t.Errorf("incorrect email addresses found: %v", csr.EmailAddresses)
+	}
+
+	if len(csr.DNSNames) != 1 || csr.DNSNames[0] != "test.example.com" {
+		t.Errorf("incorrect DNS names found: %v", csr.DNSNames)
+	}
+
+	if len(csr.Subject.Country) != 1 || csr.Subject.Country[0] != "AU" {
+		t.Errorf("incorrect Subject name: %v", csr.Subject)
+	}
+
+	found := false
+	for _, e := range csr.Extensions {
+		if e.Id.Equal(oidExtensionBasicConstraints) {
+			found = true
+			break
+		}
+	}
+	if !found {
+		t.Errorf("basic constraints extension not found in CSR")
+	}
+}
+
+func TestMaxPathLen(t *testing.T) {
+	block, _ := pem.Decode([]byte(pemPrivateKey))
+	rsaPriv, err := ParsePKCS1PrivateKey(block.Bytes)
+	if err != nil {
+		t.Fatalf("Failed to parse private key: %s", err)
+	}
+
+	template := &Certificate{
+		SerialNumber: big.NewInt(1),
+		Subject: pkix.Name{
+			CommonName: "Σ Acme Co",
+		},
+		NotBefore: time.Unix(1000, 0),
+		NotAfter:  time.Unix(100000, 0),
+
+		BasicConstraintsValid: true,
+		IsCA: true,
+	}
+
+	serialiseAndParse := func(template *Certificate) *Certificate {
+		derBytes, err := CreateCertificate(rand.Reader, template, template, &rsaPriv.PublicKey, rsaPriv)
+		if err != nil {
+			t.Fatalf("failed to create certificate: %s", err)
+			return nil
+		}
+
+		cert, err := ParseCertificate(derBytes)
+		if err != nil {
+			t.Fatalf("failed to parse certificate: %s", err)
+			return nil
+		}
+
+		return cert
+	}
+
+	cert1 := serialiseAndParse(template)
+	if m := cert1.MaxPathLen; m != -1 {
+		t.Errorf("Omitting MaxPathLen didn't turn into -1, got %d", m)
+	}
+	if cert1.MaxPathLenZero {
+		t.Errorf("Omitting MaxPathLen resulted in MaxPathLenZero")
+	}
+
+	template.MaxPathLen = 1
+	cert2 := serialiseAndParse(template)
+	if m := cert2.MaxPathLen; m != 1 {
+		t.Errorf("Setting MaxPathLen didn't work. Got %d but set 1", m)
+	}
+	if cert2.MaxPathLenZero {
+		t.Errorf("Setting MaxPathLen resulted in MaxPathLenZero")
+	}
+
+	template.MaxPathLen = 0
+	template.MaxPathLenZero = true
+	cert3 := serialiseAndParse(template)
+	if m := cert3.MaxPathLen; m != 0 {
+		t.Errorf("Setting MaxPathLenZero didn't work, got %d", m)
+	}
+	if !cert3.MaxPathLenZero {
+		t.Errorf("Setting MaxPathLen to zero didn't result in MaxPathLenZero")
+	}
+}
+
+// This CSR was generated with OpenSSL:
+//  openssl req -out CSR.csr -new -newkey rsa:2048 -nodes -keyout privateKey.key -config openssl.cnf
+//
+// The openssl.cnf needs to include this section:
+//   [ v3_req ]
+//   basicConstraints = CA:FALSE
+//   keyUsage = nonRepudiation, digitalSignature, keyEncipherment
+//   subjectAltName = email:gopher at golang.org,DNS:test.example.com
+const csrBase64 = "MIIC4zCCAcsCAQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOY+MVedRg2JEnyeLcSzcsMv2VcsTfkB5+Etd6hihAh6MrGezNyASMMKuQN6YhCX1icQDiQtGsDLTtheNnSXK06tAhHjAP/hGlszRJp+5+rP2M58fDBAkUBEhskbCUWwpY14jFtVuGNJ8vF8h8IeczdolvQhX9lVai9G0EUXJMliMKdjA899H0mRs9PzHyidyrXFNiZlQXfD8Kg7gETn2Ny965iyI6ujAIYSCvam6TnxRHYH2MBKyVGvsYGbPYUQJCsgdgyajEg6ekihvQY3SzO1HSAlZAd7d1QYO4VeWJ2mY6Wu3Jpmh+AmG19S9CcHq [...]
diff --git a/src/pkg/crypto/x509/x509_test_import.go b/src/crypto/x509/x509_test_import.go
similarity index 100%
rename from src/pkg/crypto/x509/x509_test_import.go
rename to src/crypto/x509/x509_test_import.go
diff --git a/src/pkg/database/sql/convert.go b/src/database/sql/convert.go
similarity index 100%
rename from src/pkg/database/sql/convert.go
rename to src/database/sql/convert.go
diff --git a/src/database/sql/convert_test.go b/src/database/sql/convert_test.go
new file mode 100644
index 0000000..98af9fb
--- /dev/null
+++ b/src/database/sql/convert_test.go
@@ -0,0 +1,348 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package sql
+
+import (
+	"database/sql/driver"
+	"fmt"
+	"reflect"
+	"runtime"
+	"testing"
+	"time"
+)
+
+var someTime = time.Unix(123, 0)
+var answer int64 = 42
+
+type conversionTest struct {
+	s, d interface{} // source and destination
+
+	// following are used if they're non-zero
+	wantint   int64
+	wantuint  uint64
+	wantstr   string
+	wantbytes []byte
+	wantraw   RawBytes
+	wantf32   float32
+	wantf64   float64
+	wanttime  time.Time
+	wantbool  bool // used if d is of type *bool
+	wanterr   string
+	wantiface interface{}
+	wantptr   *int64 // if non-nil, *d's pointed value must be equal to *wantptr
+	wantnil   bool   // if true, *d must be *int64(nil)
+}
+
+// Target variables for scanning into.
+var (
+	scanstr    string
+	scanbytes  []byte
+	scanraw    RawBytes
+	scanint    int
+	scanint8   int8
+	scanint16  int16
+	scanint32  int32
+	scanuint8  uint8
+	scanuint16 uint16
+	scanbool   bool
+	scanf32    float32
+	scanf64    float64
+	scantime   time.Time
+	scanptr    *int64
+	scaniface  interface{}
+)
+
+var conversionTests = []conversionTest{
+	// Exact conversions (destination pointer type matches source type)
+	{s: "foo", d: &scanstr, wantstr: "foo"},
+	{s: 123, d: &scanint, wantint: 123},
+	{s: someTime, d: &scantime, wanttime: someTime},
+
+	// To strings
+	{s: "string", d: &scanstr, wantstr: "string"},
+	{s: []byte("byteslice"), d: &scanstr, wantstr: "byteslice"},
+	{s: 123, d: &scanstr, wantstr: "123"},
+	{s: int8(123), d: &scanstr, wantstr: "123"},
+	{s: int64(123), d: &scanstr, wantstr: "123"},
+	{s: uint8(123), d: &scanstr, wantstr: "123"},
+	{s: uint16(123), d: &scanstr, wantstr: "123"},
+	{s: uint32(123), d: &scanstr, wantstr: "123"},
+	{s: uint64(123), d: &scanstr, wantstr: "123"},
+	{s: 1.5, d: &scanstr, wantstr: "1.5"},
+
+	// To []byte
+	{s: nil, d: &scanbytes, wantbytes: nil},
+	{s: "string", d: &scanbytes, wantbytes: []byte("string")},
+	{s: []byte("byteslice"), d: &scanbytes, wantbytes: []byte("byteslice")},
+	{s: 123, d: &scanbytes, wantbytes: []byte("123")},
+	{s: int8(123), d: &scanbytes, wantbytes: []byte("123")},
+	{s: int64(123), d: &scanbytes, wantbytes: []byte("123")},
+	{s: uint8(123), d: &scanbytes, wantbytes: []byte("123")},
+	{s: uint16(123), d: &scanbytes, wantbytes: []byte("123")},
+	{s: uint32(123), d: &scanbytes, wantbytes: []byte("123")},
+	{s: uint64(123), d: &scanbytes, wantbytes: []byte("123")},
+	{s: 1.5, d: &scanbytes, wantbytes: []byte("1.5")},
+
+	// To RawBytes
+	{s: nil, d: &scanraw, wantraw: nil},
+	{s: []byte("byteslice"), d: &scanraw, wantraw: RawBytes("byteslice")},
+	{s: 123, d: &scanraw, wantraw: RawBytes("123")},
+	{s: int8(123), d: &scanraw, wantraw: RawBytes("123")},
+	{s: int64(123), d: &scanraw, wantraw: RawBytes("123")},
+	{s: uint8(123), d: &scanraw, wantraw: RawBytes("123")},
+	{s: uint16(123), d: &scanraw, wantraw: RawBytes("123")},
+	{s: uint32(123), d: &scanraw, wantraw: RawBytes("123")},
+	{s: uint64(123), d: &scanraw, wantraw: RawBytes("123")},
+	{s: 1.5, d: &scanraw, wantraw: RawBytes("1.5")},
+
+	// Strings to integers
+	{s: "255", d: &scanuint8, wantuint: 255},
+	{s: "256", d: &scanuint8, wanterr: `converting string "256" to a uint8: strconv.ParseUint: parsing "256": value out of range`},
+	{s: "256", d: &scanuint16, wantuint: 256},
+	{s: "-1", d: &scanint, wantint: -1},
+	{s: "foo", d: &scanint, wanterr: `converting string "foo" to a int: strconv.ParseInt: parsing "foo": invalid syntax`},
+
+	// True bools
+	{s: true, d: &scanbool, wantbool: true},
+	{s: "True", d: &scanbool, wantbool: true},
+	{s: "TRUE", d: &scanbool, wantbool: true},
+	{s: "1", d: &scanbool, wantbool: true},
+	{s: 1, d: &scanbool, wantbool: true},
+	{s: int64(1), d: &scanbool, wantbool: true},
+	{s: uint16(1), d: &scanbool, wantbool: true},
+
+	// False bools
+	{s: false, d: &scanbool, wantbool: false},
+	{s: "false", d: &scanbool, wantbool: false},
+	{s: "FALSE", d: &scanbool, wantbool: false},
+	{s: "0", d: &scanbool, wantbool: false},
+	{s: 0, d: &scanbool, wantbool: false},
+	{s: int64(0), d: &scanbool, wantbool: false},
+	{s: uint16(0), d: &scanbool, wantbool: false},
+
+	// Not bools
+	{s: "yup", d: &scanbool, wanterr: `sql/driver: couldn't convert "yup" into type bool`},
+	{s: 2, d: &scanbool, wanterr: `sql/driver: couldn't convert 2 into type bool`},
+
+	// Floats
+	{s: float64(1.5), d: &scanf64, wantf64: float64(1.5)},
+	{s: int64(1), d: &scanf64, wantf64: float64(1)},
+	{s: float64(1.5), d: &scanf32, wantf32: float32(1.5)},
+	{s: "1.5", d: &scanf32, wantf32: float32(1.5)},
+	{s: "1.5", d: &scanf64, wantf64: float64(1.5)},
+
+	// Pointers
+	{s: interface{}(nil), d: &scanptr, wantnil: true},
+	{s: int64(42), d: &scanptr, wantptr: &answer},
+
+	// To interface{}
+	{s: float64(1.5), d: &scaniface, wantiface: float64(1.5)},
+	{s: int64(1), d: &scaniface, wantiface: int64(1)},
+	{s: "str", d: &scaniface, wantiface: "str"},
+	{s: []byte("byteslice"), d: &scaniface, wantiface: []byte("byteslice")},
+	{s: true, d: &scaniface, wantiface: true},
+	{s: nil, d: &scaniface},
+	{s: []byte(nil), d: &scaniface, wantiface: []byte(nil)},
+}
+
+func intPtrValue(intptr interface{}) interface{} {
+	return reflect.Indirect(reflect.Indirect(reflect.ValueOf(intptr))).Int()
+}
+
+func intValue(intptr interface{}) int64 {
+	return reflect.Indirect(reflect.ValueOf(intptr)).Int()
+}
+
+func uintValue(intptr interface{}) uint64 {
+	return reflect.Indirect(reflect.ValueOf(intptr)).Uint()
+}
+
+func float64Value(ptr interface{}) float64 {
+	return *(ptr.(*float64))
+}
+
+func float32Value(ptr interface{}) float32 {
+	return *(ptr.(*float32))
+}
+
+func timeValue(ptr interface{}) time.Time {
+	return *(ptr.(*time.Time))
+}
+
+func TestConversions(t *testing.T) {
+	for n, ct := range conversionTests {
+		err := convertAssign(ct.d, ct.s)
+		errstr := ""
+		if err != nil {
+			errstr = err.Error()
+		}
+		errf := func(format string, args ...interface{}) {
+			base := fmt.Sprintf("convertAssign #%d: for %v (%T) -> %T, ", n, ct.s, ct.s, ct.d)
+			t.Errorf(base+format, args...)
+		}
+		if errstr != ct.wanterr {
+			errf("got error %q, want error %q", errstr, ct.wanterr)
+		}
+		if ct.wantstr != "" && ct.wantstr != scanstr {
+			errf("want string %q, got %q", ct.wantstr, scanstr)
+		}
+		if ct.wantint != 0 && ct.wantint != intValue(ct.d) {
+			errf("want int %d, got %d", ct.wantint, intValue(ct.d))
+		}
+		if ct.wantuint != 0 && ct.wantuint != uintValue(ct.d) {
+			errf("want uint %d, got %d", ct.wantuint, uintValue(ct.d))
+		}
+		if ct.wantf32 != 0 && ct.wantf32 != float32Value(ct.d) {
+			errf("want float32 %v, got %v", ct.wantf32, float32Value(ct.d))
+		}
+		if ct.wantf64 != 0 && ct.wantf64 != float64Value(ct.d) {
+			errf("want float32 %v, got %v", ct.wantf64, float64Value(ct.d))
+		}
+		if bp, boolTest := ct.d.(*bool); boolTest && *bp != ct.wantbool && ct.wanterr == "" {
+			errf("want bool %v, got %v", ct.wantbool, *bp)
+		}
+		if !ct.wanttime.IsZero() && !ct.wanttime.Equal(timeValue(ct.d)) {
+			errf("want time %v, got %v", ct.wanttime, timeValue(ct.d))
+		}
+		if ct.wantnil && *ct.d.(**int64) != nil {
+			errf("want nil, got %v", intPtrValue(ct.d))
+		}
+		if ct.wantptr != nil {
+			if *ct.d.(**int64) == nil {
+				errf("want pointer to %v, got nil", *ct.wantptr)
+			} else if *ct.wantptr != intPtrValue(ct.d) {
+				errf("want pointer to %v, got %v", *ct.wantptr, intPtrValue(ct.d))
+			}
+		}
+		if ifptr, ok := ct.d.(*interface{}); ok {
+			if !reflect.DeepEqual(ct.wantiface, scaniface) {
+				errf("want interface %#v, got %#v", ct.wantiface, scaniface)
+				continue
+			}
+			if srcBytes, ok := ct.s.([]byte); ok {
+				dstBytes := (*ifptr).([]byte)
+				if len(srcBytes) > 0 && &dstBytes[0] == &srcBytes[0] {
+					errf("copy into interface{} didn't copy []byte data")
+				}
+			}
+		}
+	}
+}
+
+func TestNullString(t *testing.T) {
+	var ns NullString
+	convertAssign(&ns, []byte("foo"))
+	if !ns.Valid {
+		t.Errorf("expecting not null")
+	}
+	if ns.String != "foo" {
+		t.Errorf("expecting foo; got %q", ns.String)
+	}
+	convertAssign(&ns, nil)
+	if ns.Valid {
+		t.Errorf("expecting null on nil")
+	}
+	if ns.String != "" {
+		t.Errorf("expecting blank on nil; got %q", ns.String)
+	}
+}
+
+type valueConverterTest struct {
+	c       driver.ValueConverter
+	in, out interface{}
+	err     string
+}
+
+var valueConverterTests = []valueConverterTest{
+	{driver.DefaultParameterConverter, NullString{"hi", true}, "hi", ""},
+	{driver.DefaultParameterConverter, NullString{"", false}, nil, ""},
+}
+
+func TestValueConverters(t *testing.T) {
+	for i, tt := range valueConverterTests {
+		out, err := tt.c.ConvertValue(tt.in)
+		goterr := ""
+		if err != nil {
+			goterr = err.Error()
+		}
+		if goterr != tt.err {
+			t.Errorf("test %d: %T(%T(%v)) error = %q; want error = %q",
+				i, tt.c, tt.in, tt.in, goterr, tt.err)
+		}
+		if tt.err != "" {
+			continue
+		}
+		if !reflect.DeepEqual(out, tt.out) {
+			t.Errorf("test %d: %T(%T(%v)) = %v (%T); want %v (%T)",
+				i, tt.c, tt.in, tt.in, out, out, tt.out, tt.out)
+		}
+	}
+}
+
+// Tests that assigning to RawBytes doesn't allocate (and also works).
+func TestRawBytesAllocs(t *testing.T) {
+	var tests = []struct {
+		name string
+		in   interface{}
+		want string
+	}{
+		{"uint64", uint64(12345678), "12345678"},
+		{"uint32", uint32(1234), "1234"},
+		{"uint16", uint16(12), "12"},
+		{"uint8", uint8(1), "1"},
+		{"uint", uint(123), "123"},
+		{"int", int(123), "123"},
+		{"int8", int8(1), "1"},
+		{"int16", int16(12), "12"},
+		{"int32", int32(1234), "1234"},
+		{"int64", int64(12345678), "12345678"},
+		{"float32", float32(1.5), "1.5"},
+		{"float64", float64(64), "64"},
+		{"bool", false, "false"},
+	}
+
+	buf := make(RawBytes, 10)
+	test := func(name string, in interface{}, want string) {
+		if err := convertAssign(&buf, in); err != nil {
+			t.Fatalf("%s: convertAssign = %v", name, err)
+		}
+		match := len(buf) == len(want)
+		if match {
+			for i, b := range buf {
+				if want[i] != b {
+					match = false
+					break
+				}
+			}
+		}
+		if !match {
+			t.Fatalf("%s: got %q (len %d); want %q (len %d)", name, buf, len(buf), want, len(want))
+		}
+	}
+
+	n := testing.AllocsPerRun(100, func() {
+		for _, tt := range tests {
+			test(tt.name, tt.in, tt.want)
+		}
+	})
+
+	// The numbers below are only valid for 64-bit interface word sizes,
+	// and gc. With 32-bit words there are more convT2E allocs, and
+	// with gccgo, only pointers currently go in interface data.
+	// So only care on amd64 gc for now.
+	measureAllocs := runtime.GOARCH == "amd64" && runtime.Compiler == "gc"
+
+	if n > 0.5 && measureAllocs {
+		t.Fatalf("allocs = %v; want 0", n)
+	}
+
+	// This one involves a convT2E allocation, string -> interface{}
+	n = testing.AllocsPerRun(100, func() {
+		test("string", "foo", "foo")
+	})
+	if n > 1.5 && measureAllocs {
+		t.Fatalf("allocs = %v; want max 1", n)
+	}
+}
diff --git a/src/pkg/database/sql/doc.txt b/src/database/sql/doc.txt
similarity index 100%
rename from src/pkg/database/sql/doc.txt
rename to src/database/sql/doc.txt
diff --git a/src/pkg/database/sql/driver/driver.go b/src/database/sql/driver/driver.go
similarity index 100%
rename from src/pkg/database/sql/driver/driver.go
rename to src/database/sql/driver/driver.go
diff --git a/src/pkg/database/sql/driver/types.go b/src/database/sql/driver/types.go
similarity index 100%
rename from src/pkg/database/sql/driver/types.go
rename to src/database/sql/driver/types.go
diff --git a/src/pkg/database/sql/driver/types_test.go b/src/database/sql/driver/types_test.go
similarity index 100%
rename from src/pkg/database/sql/driver/types_test.go
rename to src/database/sql/driver/types_test.go
diff --git a/src/pkg/database/sql/example_test.go b/src/database/sql/example_test.go
similarity index 100%
rename from src/pkg/database/sql/example_test.go
rename to src/database/sql/example_test.go
diff --git a/src/database/sql/fakedb_test.go b/src/database/sql/fakedb_test.go
new file mode 100644
index 0000000..a993fd4
--- /dev/null
+++ b/src/database/sql/fakedb_test.go
@@ -0,0 +1,829 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package sql
+
+import (
+	"database/sql/driver"
+	"errors"
+	"fmt"
+	"io"
+	"log"
+	"sort"
+	"strconv"
+	"strings"
+	"sync"
+	"testing"
+	"time"
+)
+
+var _ = log.Printf
+
+// fakeDriver is a fake database that implements Go's driver.Driver
+// interface, just for testing.
+//
+// It speaks a query language that's semantically similar to but
+// syntactically different and simpler than SQL.  The syntax is as
+// follows:
+//
+//   WIPE
+//   CREATE|<tablename>|<col>=<type>,<col>=<type>,...
+//     where types are: "string", [u]int{8,16,32,64}, "bool"
+//   INSERT|<tablename>|col=val,col2=val2,col3=?
+//   SELECT|<tablename>|projectcol1,projectcol2|filtercol=?,filtercol2=?
+//
+// When opening a fakeDriver's database, it starts empty with no
+// tables.  All tables and data are stored in memory only.
+type fakeDriver struct {
+	mu         sync.Mutex // guards 3 following fields
+	openCount  int        // conn opens
+	closeCount int        // conn closes
+	waitCh     chan struct{}
+	waitingCh  chan struct{}
+	dbs        map[string]*fakeDB
+}
+
+type fakeDB struct {
+	name string
+
+	mu      sync.Mutex
+	free    []*fakeConn
+	tables  map[string]*table
+	badConn bool
+}
+
+type table struct {
+	mu      sync.Mutex
+	colname []string
+	coltype []string
+	rows    []*row
+}
+
+func (t *table) columnIndex(name string) int {
+	for n, nname := range t.colname {
+		if name == nname {
+			return n
+		}
+	}
+	return -1
+}
+
+type row struct {
+	cols []interface{} // must be same size as its table colname + coltype
+}
+
+func (r *row) clone() *row {
+	nrow := &row{cols: make([]interface{}, len(r.cols))}
+	copy(nrow.cols, r.cols)
+	return nrow
+}
+
+type fakeConn struct {
+	db *fakeDB // where to return ourselves to
+
+	currTx *fakeTx
+
+	// Stats for tests:
+	mu          sync.Mutex
+	stmtsMade   int
+	stmtsClosed int
+	numPrepare  int
+	bad         bool
+}
+
+func (c *fakeConn) incrStat(v *int) {
+	c.mu.Lock()
+	*v++
+	c.mu.Unlock()
+}
+
+type fakeTx struct {
+	c *fakeConn
+}
+
+type fakeStmt struct {
+	c *fakeConn
+	q string // just for debugging
+
+	cmd   string
+	table string
+
+	closed bool
+
+	colName      []string      // used by CREATE, INSERT, SELECT (selected columns)
+	colType      []string      // used by CREATE
+	colValue     []interface{} // used by INSERT (mix of strings and "?" for bound params)
+	placeholders int           // used by INSERT/SELECT: number of ? params
+
+	whereCol []string // used by SELECT (all placeholders)
+
+	placeholderConverter []driver.ValueConverter // used by INSERT
+}
+
+var fdriver driver.Driver = &fakeDriver{}
+
+func init() {
+	Register("test", fdriver)
+}
+
+func contains(list []string, y string) bool {
+	for _, x := range list {
+		if x == y {
+			return true
+		}
+	}
+	return false
+}
+
+type Dummy struct {
+	driver.Driver
+}
+
+func TestDrivers(t *testing.T) {
+	unregisterAllDrivers()
+	Register("test", fdriver)
+	Register("invalid", Dummy{})
+	all := Drivers()
+	if len(all) < 2 || !sort.StringsAreSorted(all) || !contains(all, "test") || !contains(all, "invalid") {
+		t.Fatalf("Drivers = %v, want sorted list with at least [invalid, test]", all)
+	}
+}
+
+// Supports dsn forms:
+//    <dbname>
+//    <dbname>;<opts>  (only currently supported option is `badConn`,
+//                      which causes driver.ErrBadConn to be returned on
+//                      every other conn.Begin())
+func (d *fakeDriver) Open(dsn string) (driver.Conn, error) {
+	parts := strings.Split(dsn, ";")
+	if len(parts) < 1 {
+		return nil, errors.New("fakedb: no database name")
+	}
+	name := parts[0]
+
+	db := d.getDB(name)
+
+	d.mu.Lock()
+	d.openCount++
+	d.mu.Unlock()
+	conn := &fakeConn{db: db}
+
+	if len(parts) >= 2 && parts[1] == "badConn" {
+		conn.bad = true
+	}
+	if d.waitCh != nil {
+		d.waitingCh <- struct{}{}
+		<-d.waitCh
+		d.waitCh = nil
+		d.waitingCh = nil
+	}
+	return conn, nil
+}
+
+func (d *fakeDriver) getDB(name string) *fakeDB {
+	d.mu.Lock()
+	defer d.mu.Unlock()
+	if d.dbs == nil {
+		d.dbs = make(map[string]*fakeDB)
+	}
+	db, ok := d.dbs[name]
+	if !ok {
+		db = &fakeDB{name: name}
+		d.dbs[name] = db
+	}
+	return db
+}
+
+func (db *fakeDB) wipe() {
+	db.mu.Lock()
+	defer db.mu.Unlock()
+	db.tables = nil
+}
+
+func (db *fakeDB) createTable(name string, columnNames, columnTypes []string) error {
+	db.mu.Lock()
+	defer db.mu.Unlock()
+	if db.tables == nil {
+		db.tables = make(map[string]*table)
+	}
+	if _, exist := db.tables[name]; exist {
+		return fmt.Errorf("table %q already exists", name)
+	}
+	if len(columnNames) != len(columnTypes) {
+		return fmt.Errorf("create table of %q len(names) != len(types): %d vs %d",
+			name, len(columnNames), len(columnTypes))
+	}
+	db.tables[name] = &table{colname: columnNames, coltype: columnTypes}
+	return nil
+}
+
+// must be called with db.mu lock held
+func (db *fakeDB) table(table string) (*table, bool) {
+	if db.tables == nil {
+		return nil, false
+	}
+	t, ok := db.tables[table]
+	return t, ok
+}
+
+func (db *fakeDB) columnType(table, column string) (typ string, ok bool) {
+	db.mu.Lock()
+	defer db.mu.Unlock()
+	t, ok := db.table(table)
+	if !ok {
+		return
+	}
+	for n, cname := range t.colname {
+		if cname == column {
+			return t.coltype[n], true
+		}
+	}
+	return "", false
+}
+
+func (c *fakeConn) isBad() bool {
+	// if not simulating bad conn, do nothing
+	if !c.bad {
+		return false
+	}
+	// alternate between bad conn and not bad conn
+	c.db.badConn = !c.db.badConn
+	return c.db.badConn
+}
+
+func (c *fakeConn) Begin() (driver.Tx, error) {
+	if c.isBad() {
+		return nil, driver.ErrBadConn
+	}
+	if c.currTx != nil {
+		return nil, errors.New("already in a transaction")
+	}
+	c.currTx = &fakeTx{c: c}
+	return c.currTx, nil
+}
+
+var hookPostCloseConn struct {
+	sync.Mutex
+	fn func(*fakeConn, error)
+}
+
+func setHookpostCloseConn(fn func(*fakeConn, error)) {
+	hookPostCloseConn.Lock()
+	defer hookPostCloseConn.Unlock()
+	hookPostCloseConn.fn = fn
+}
+
+var testStrictClose *testing.T
+
+// setStrictFakeConnClose sets the t to Errorf on when fakeConn.Close
+// fails to close. If nil, the check is disabled.
+func setStrictFakeConnClose(t *testing.T) {
+	testStrictClose = t
+}
+
+func (c *fakeConn) Close() (err error) {
+	drv := fdriver.(*fakeDriver)
+	defer func() {
+		if err != nil && testStrictClose != nil {
+			testStrictClose.Errorf("failed to close a test fakeConn: %v", err)
+		}
+		hookPostCloseConn.Lock()
+		fn := hookPostCloseConn.fn
+		hookPostCloseConn.Unlock()
+		if fn != nil {
+			fn(c, err)
+		}
+		if err == nil {
+			drv.mu.Lock()
+			drv.closeCount++
+			drv.mu.Unlock()
+		}
+	}()
+	if c.currTx != nil {
+		return errors.New("can't close fakeConn; in a Transaction")
+	}
+	if c.db == nil {
+		return errors.New("can't close fakeConn; already closed")
+	}
+	if c.stmtsMade > c.stmtsClosed {
+		return errors.New("can't close; dangling statement(s)")
+	}
+	c.db = nil
+	return nil
+}
+
+func checkSubsetTypes(args []driver.Value) error {
+	for n, arg := range args {
+		switch arg.(type) {
+		case int64, float64, bool, nil, []byte, string, time.Time:
+		default:
+			return fmt.Errorf("fakedb_test: invalid argument #%d: %v, type %T", n+1, arg, arg)
+		}
+	}
+	return nil
+}
+
+func (c *fakeConn) Exec(query string, args []driver.Value) (driver.Result, error) {
+	// This is an optional interface, but it's implemented here
+	// just to check that all the args are of the proper types.
+	// ErrSkip is returned so the caller acts as if we didn't
+	// implement this at all.
+	err := checkSubsetTypes(args)
+	if err != nil {
+		return nil, err
+	}
+	return nil, driver.ErrSkip
+}
+
+func (c *fakeConn) Query(query string, args []driver.Value) (driver.Rows, error) {
+	// This is an optional interface, but it's implemented here
+	// just to check that all the args are of the proper types.
+	// ErrSkip is returned so the caller acts as if we didn't
+	// implement this at all.
+	err := checkSubsetTypes(args)
+	if err != nil {
+		return nil, err
+	}
+	return nil, driver.ErrSkip
+}
+
+func errf(msg string, args ...interface{}) error {
+	return errors.New("fakedb: " + fmt.Sprintf(msg, args...))
+}
+
+// parts are table|selectCol1,selectCol2|whereCol=?,whereCol2=?
+// (note that where columns must always contain ? marks,
+//  just a limitation for fakedb)
+func (c *fakeConn) prepareSelect(stmt *fakeStmt, parts []string) (driver.Stmt, error) {
+	if len(parts) != 3 {
+		stmt.Close()
+		return nil, errf("invalid SELECT syntax with %d parts; want 3", len(parts))
+	}
+	stmt.table = parts[0]
+	stmt.colName = strings.Split(parts[1], ",")
+	for n, colspec := range strings.Split(parts[2], ",") {
+		if colspec == "" {
+			continue
+		}
+		nameVal := strings.Split(colspec, "=")
+		if len(nameVal) != 2 {
+			stmt.Close()
+			return nil, errf("SELECT on table %q has invalid column spec of %q (index %d)", stmt.table, colspec, n)
+		}
+		column, value := nameVal[0], nameVal[1]
+		_, ok := c.db.columnType(stmt.table, column)
+		if !ok {
+			stmt.Close()
+			return nil, errf("SELECT on table %q references non-existent column %q", stmt.table, column)
+		}
+		if value != "?" {
+			stmt.Close()
+			return nil, errf("SELECT on table %q has pre-bound value for where column %q; need a question mark",
+				stmt.table, column)
+		}
+		stmt.whereCol = append(stmt.whereCol, column)
+		stmt.placeholders++
+	}
+	return stmt, nil
+}
+
+// parts are table|col=type,col2=type2
+func (c *fakeConn) prepareCreate(stmt *fakeStmt, parts []string) (driver.Stmt, error) {
+	if len(parts) != 2 {
+		stmt.Close()
+		return nil, errf("invalid CREATE syntax with %d parts; want 2", len(parts))
+	}
+	stmt.table = parts[0]
+	for n, colspec := range strings.Split(parts[1], ",") {
+		nameType := strings.Split(colspec, "=")
+		if len(nameType) != 2 {
+			stmt.Close()
+			return nil, errf("CREATE table %q has invalid column spec of %q (index %d)", stmt.table, colspec, n)
+		}
+		stmt.colName = append(stmt.colName, nameType[0])
+		stmt.colType = append(stmt.colType, nameType[1])
+	}
+	return stmt, nil
+}
+
+// parts are table|col=?,col2=val
+func (c *fakeConn) prepareInsert(stmt *fakeStmt, parts []string) (driver.Stmt, error) {
+	if len(parts) != 2 {
+		stmt.Close()
+		return nil, errf("invalid INSERT syntax with %d parts; want 2", len(parts))
+	}
+	stmt.table = parts[0]
+	for n, colspec := range strings.Split(parts[1], ",") {
+		nameVal := strings.Split(colspec, "=")
+		if len(nameVal) != 2 {
+			stmt.Close()
+			return nil, errf("INSERT table %q has invalid column spec of %q (index %d)", stmt.table, colspec, n)
+		}
+		column, value := nameVal[0], nameVal[1]
+		ctype, ok := c.db.columnType(stmt.table, column)
+		if !ok {
+			stmt.Close()
+			return nil, errf("INSERT table %q references non-existent column %q", stmt.table, column)
+		}
+		stmt.colName = append(stmt.colName, column)
+
+		if value != "?" {
+			var subsetVal interface{}
+			// Convert to driver subset type
+			switch ctype {
+			case "string":
+				subsetVal = []byte(value)
+			case "blob":
+				subsetVal = []byte(value)
+			case "int32":
+				i, err := strconv.Atoi(value)
+				if err != nil {
+					stmt.Close()
+					return nil, errf("invalid conversion to int32 from %q", value)
+				}
+				subsetVal = int64(i) // int64 is a subset type, but not int32
+			default:
+				stmt.Close()
+				return nil, errf("unsupported conversion for pre-bound parameter %q to type %q", value, ctype)
+			}
+			stmt.colValue = append(stmt.colValue, subsetVal)
+		} else {
+			stmt.placeholders++
+			stmt.placeholderConverter = append(stmt.placeholderConverter, converterForType(ctype))
+			stmt.colValue = append(stmt.colValue, "?")
+		}
+	}
+	return stmt, nil
+}
+
+// hook to simulate broken connections
+var hookPrepareBadConn func() bool
+
+func (c *fakeConn) Prepare(query string) (driver.Stmt, error) {
+	c.numPrepare++
+	if c.db == nil {
+		panic("nil c.db; conn = " + fmt.Sprintf("%#v", c))
+	}
+
+	if hookPrepareBadConn != nil && hookPrepareBadConn() {
+		return nil, driver.ErrBadConn
+	}
+
+	parts := strings.Split(query, "|")
+	if len(parts) < 1 {
+		return nil, errf("empty query")
+	}
+	cmd := parts[0]
+	parts = parts[1:]
+	stmt := &fakeStmt{q: query, c: c, cmd: cmd}
+	c.incrStat(&c.stmtsMade)
+	switch cmd {
+	case "WIPE":
+		// Nothing
+	case "SELECT":
+		return c.prepareSelect(stmt, parts)
+	case "CREATE":
+		return c.prepareCreate(stmt, parts)
+	case "INSERT":
+		return c.prepareInsert(stmt, parts)
+	case "NOSERT":
+		// Do all the prep-work like for an INSERT but don't actually insert the row.
+		// Used for some of the concurrent tests.
+		return c.prepareInsert(stmt, parts)
+	default:
+		stmt.Close()
+		return nil, errf("unsupported command type %q", cmd)
+	}
+	return stmt, nil
+}
+
+func (s *fakeStmt) ColumnConverter(idx int) driver.ValueConverter {
+	if len(s.placeholderConverter) == 0 {
+		return driver.DefaultParameterConverter
+	}
+	return s.placeholderConverter[idx]
+}
+
+func (s *fakeStmt) Close() error {
+	if s.c == nil {
+		panic("nil conn in fakeStmt.Close")
+	}
+	if s.c.db == nil {
+		panic("in fakeStmt.Close, conn's db is nil (already closed)")
+	}
+	if !s.closed {
+		s.c.incrStat(&s.c.stmtsClosed)
+		s.closed = true
+	}
+	return nil
+}
+
+var errClosed = errors.New("fakedb: statement has been closed")
+
+// hook to simulate broken connections
+var hookExecBadConn func() bool
+
+func (s *fakeStmt) Exec(args []driver.Value) (driver.Result, error) {
+	if s.closed {
+		return nil, errClosed
+	}
+
+	if hookExecBadConn != nil && hookExecBadConn() {
+		return nil, driver.ErrBadConn
+	}
+
+	err := checkSubsetTypes(args)
+	if err != nil {
+		return nil, err
+	}
+
+	db := s.c.db
+	switch s.cmd {
+	case "WIPE":
+		db.wipe()
+		return driver.ResultNoRows, nil
+	case "CREATE":
+		if err := db.createTable(s.table, s.colName, s.colType); err != nil {
+			return nil, err
+		}
+		return driver.ResultNoRows, nil
+	case "INSERT":
+		return s.execInsert(args, true)
+	case "NOSERT":
+		// Do all the prep-work like for an INSERT but don't actually insert the row.
+		// Used for some of the concurrent tests.
+		return s.execInsert(args, false)
+	}
+	fmt.Printf("EXEC statement, cmd=%q: %#v\n", s.cmd, s)
+	return nil, fmt.Errorf("unimplemented statement Exec command type of %q", s.cmd)
+}
+
+// When doInsert is true, add the row to the table.
+// When doInsert is false do prep-work and error checking, but don't
+// actually add the row to the table.
+func (s *fakeStmt) execInsert(args []driver.Value, doInsert bool) (driver.Result, error) {
+	db := s.c.db
+	if len(args) != s.placeholders {
+		panic("error in pkg db; should only get here if size is correct")
+	}
+	db.mu.Lock()
+	t, ok := db.table(s.table)
+	db.mu.Unlock()
+	if !ok {
+		return nil, fmt.Errorf("fakedb: table %q doesn't exist", s.table)
+	}
+
+	t.mu.Lock()
+	defer t.mu.Unlock()
+
+	var cols []interface{}
+	if doInsert {
+		cols = make([]interface{}, len(t.colname))
+	}
+	argPos := 0
+	for n, colname := range s.colName {
+		colidx := t.columnIndex(colname)
+		if colidx == -1 {
+			return nil, fmt.Errorf("fakedb: column %q doesn't exist or dropped since prepared statement was created", colname)
+		}
+		var val interface{}
+		if strvalue, ok := s.colValue[n].(string); ok && strvalue == "?" {
+			val = args[argPos]
+			argPos++
+		} else {
+			val = s.colValue[n]
+		}
+		if doInsert {
+			cols[colidx] = val
+		}
+	}
+
+	if doInsert {
+		t.rows = append(t.rows, &row{cols: cols})
+	}
+	return driver.RowsAffected(1), nil
+}
+
+// hook to simulate broken connections
+var hookQueryBadConn func() bool
+
+func (s *fakeStmt) Query(args []driver.Value) (driver.Rows, error) {
+	if s.closed {
+		return nil, errClosed
+	}
+
+	if hookQueryBadConn != nil && hookQueryBadConn() {
+		return nil, driver.ErrBadConn
+	}
+
+	err := checkSubsetTypes(args)
+	if err != nil {
+		return nil, err
+	}
+
+	db := s.c.db
+	if len(args) != s.placeholders {
+		panic("error in pkg db; should only get here if size is correct")
+	}
+
+	db.mu.Lock()
+	t, ok := db.table(s.table)
+	db.mu.Unlock()
+	if !ok {
+		return nil, fmt.Errorf("fakedb: table %q doesn't exist", s.table)
+	}
+
+	if s.table == "magicquery" {
+		if len(s.whereCol) == 2 && s.whereCol[0] == "op" && s.whereCol[1] == "millis" {
+			if args[0] == "sleep" {
+				time.Sleep(time.Duration(args[1].(int64)) * time.Millisecond)
+			}
+		}
+	}
+
+	t.mu.Lock()
+	defer t.mu.Unlock()
+
+	colIdx := make(map[string]int) // select column name -> column index in table
+	for _, name := range s.colName {
+		idx := t.columnIndex(name)
+		if idx == -1 {
+			return nil, fmt.Errorf("fakedb: unknown column name %q", name)
+		}
+		colIdx[name] = idx
+	}
+
+	mrows := []*row{}
+rows:
+	for _, trow := range t.rows {
+		// Process the where clause, skipping non-match rows. This is lazy
+		// and just uses fmt.Sprintf("%v") to test equality.  Good enough
+		// for test code.
+		for widx, wcol := range s.whereCol {
+			idx := t.columnIndex(wcol)
+			if idx == -1 {
+				return nil, fmt.Errorf("db: invalid where clause column %q", wcol)
+			}
+			tcol := trow.cols[idx]
+			if bs, ok := tcol.([]byte); ok {
+				// lazy hack to avoid sprintf %v on a []byte
+				tcol = string(bs)
+			}
+			if fmt.Sprintf("%v", tcol) != fmt.Sprintf("%v", args[widx]) {
+				continue rows
+			}
+		}
+		mrow := &row{cols: make([]interface{}, len(s.colName))}
+		for seli, name := range s.colName {
+			mrow.cols[seli] = trow.cols[colIdx[name]]
+		}
+		mrows = append(mrows, mrow)
+	}
+
+	cursor := &rowsCursor{
+		pos:    -1,
+		rows:   mrows,
+		cols:   s.colName,
+		errPos: -1,
+	}
+	return cursor, nil
+}
+
+func (s *fakeStmt) NumInput() int {
+	return s.placeholders
+}
+
+func (tx *fakeTx) Commit() error {
+	tx.c.currTx = nil
+	return nil
+}
+
+func (tx *fakeTx) Rollback() error {
+	tx.c.currTx = nil
+	return nil
+}
+
+type rowsCursor struct {
+	cols   []string
+	pos    int
+	rows   []*row
+	closed bool
+
+	// errPos and err are for making Next return early with error.
+	errPos int
+	err    error
+
+	// a clone of slices to give out to clients, indexed by the
+	// the original slice's first byte address.  we clone them
+	// just so we're able to corrupt them on close.
+	bytesClone map[*byte][]byte
+}
+
+func (rc *rowsCursor) Close() error {
+	if !rc.closed {
+		for _, bs := range rc.bytesClone {
+			bs[0] = 255 // first byte corrupted
+		}
+	}
+	rc.closed = true
+	return nil
+}
+
+func (rc *rowsCursor) Columns() []string {
+	return rc.cols
+}
+
+var rowsCursorNextHook func(dest []driver.Value) error
+
+func (rc *rowsCursor) Next(dest []driver.Value) error {
+	if rowsCursorNextHook != nil {
+		return rowsCursorNextHook(dest)
+	}
+
+	if rc.closed {
+		return errors.New("fakedb: cursor is closed")
+	}
+	rc.pos++
+	if rc.pos == rc.errPos {
+		return rc.err
+	}
+	if rc.pos >= len(rc.rows) {
+		return io.EOF // per interface spec
+	}
+	for i, v := range rc.rows[rc.pos].cols {
+		// TODO(bradfitz): convert to subset types? naah, I
+		// think the subset types should only be input to
+		// driver, but the sql package should be able to handle
+		// a wider range of types coming out of drivers. all
+		// for ease of drivers, and to prevent drivers from
+		// messing up conversions or doing them differently.
+		dest[i] = v
+
+		if bs, ok := v.([]byte); ok {
+			if rc.bytesClone == nil {
+				rc.bytesClone = make(map[*byte][]byte)
+			}
+			clone, ok := rc.bytesClone[&bs[0]]
+			if !ok {
+				clone = make([]byte, len(bs))
+				copy(clone, bs)
+				rc.bytesClone[&bs[0]] = clone
+			}
+			dest[i] = clone
+		}
+	}
+	return nil
+}
+
+// fakeDriverString is like driver.String, but indirects pointers like
+// DefaultValueConverter.
+//
+// This could be surprising behavior to retroactively apply to
+// driver.String now that Go1 is out, but this is convenient for
+// our TestPointerParamsAndScans.
+//
+type fakeDriverString struct{}
+
+func (fakeDriverString) ConvertValue(v interface{}) (driver.Value, error) {
+	switch c := v.(type) {
+	case string, []byte:
+		return v, nil
+	case *string:
+		if c == nil {
+			return nil, nil
+		}
+		return *c, nil
+	}
+	return fmt.Sprintf("%v", v), nil
+}
+
+func converterForType(typ string) driver.ValueConverter {
+	switch typ {
+	case "bool":
+		return driver.Bool
+	case "nullbool":
+		return driver.Null{Converter: driver.Bool}
+	case "int32":
+		return driver.Int32
+	case "string":
+		return driver.NotNull{Converter: fakeDriverString{}}
+	case "nullstring":
+		return driver.Null{Converter: fakeDriverString{}}
+	case "int64":
+		// TODO(coopernurse): add type-specific converter
+		return driver.NotNull{Converter: driver.DefaultParameterConverter}
+	case "nullint64":
+		// TODO(coopernurse): add type-specific converter
+		return driver.Null{Converter: driver.DefaultParameterConverter}
+	case "float64":
+		// TODO(coopernurse): add type-specific converter
+		return driver.NotNull{Converter: driver.DefaultParameterConverter}
+	case "nullfloat64":
+		// TODO(coopernurse): add type-specific converter
+		return driver.Null{Converter: driver.DefaultParameterConverter}
+	case "datetime":
+		return driver.DefaultParameterConverter
+	}
+	panic("invalid fakedb column type of " + typ)
+}
diff --git a/src/database/sql/sql.go b/src/database/sql/sql.go
new file mode 100644
index 0000000..6e6f246
--- /dev/null
+++ b/src/database/sql/sql.go
@@ -0,0 +1,1770 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package sql provides a generic interface around SQL (or SQL-like)
+// databases.
+//
+// The sql package must be used in conjunction with a database driver.
+// See http://golang.org/s/sqldrivers for a list of drivers.
+//
+// For more usage examples, see the wiki page at
+// http://golang.org/s/sqlwiki.
+package sql
+
+import (
+	"database/sql/driver"
+	"errors"
+	"fmt"
+	"io"
+	"runtime"
+	"sort"
+	"sync"
+)
+
+var drivers = make(map[string]driver.Driver)
+
+// Register makes a database driver available by the provided name.
+// If Register is called twice with the same name or if driver is nil,
+// it panics.
+func Register(name string, driver driver.Driver) {
+	if driver == nil {
+		panic("sql: Register driver is nil")
+	}
+	if _, dup := drivers[name]; dup {
+		panic("sql: Register called twice for driver " + name)
+	}
+	drivers[name] = driver
+}
+
+func unregisterAllDrivers() {
+	// For tests.
+	drivers = make(map[string]driver.Driver)
+}
+
+// Drivers returns a sorted list of the names of the registered drivers.
+func Drivers() []string {
+	var list []string
+	for name := range drivers {
+		list = append(list, name)
+	}
+	sort.Strings(list)
+	return list
+}
+
+// RawBytes is a byte slice that holds a reference to memory owned by
+// the database itself. After a Scan into a RawBytes, the slice is only
+// valid until the next call to Next, Scan, or Close.
+type RawBytes []byte
+
+// NullString represents a string that may be null.
+// NullString implements the Scanner interface so
+// it can be used as a scan destination:
+//
+//  var s NullString
+//  err := db.QueryRow("SELECT name FROM foo WHERE id=?", id).Scan(&s)
+//  ...
+//  if s.Valid {
+//     // use s.String
+//  } else {
+//     // NULL value
+//  }
+//
+type NullString struct {
+	String string
+	Valid  bool // Valid is true if String is not NULL
+}
+
+// Scan implements the Scanner interface.
+func (ns *NullString) Scan(value interface{}) error {
+	if value == nil {
+		ns.String, ns.Valid = "", false
+		return nil
+	}
+	ns.Valid = true
+	return convertAssign(&ns.String, value)
+}
+
+// Value implements the driver Valuer interface.
+func (ns NullString) Value() (driver.Value, error) {
+	if !ns.Valid {
+		return nil, nil
+	}
+	return ns.String, nil
+}
+
+// NullInt64 represents an int64 that may be null.
+// NullInt64 implements the Scanner interface so
+// it can be used as a scan destination, similar to NullString.
+type NullInt64 struct {
+	Int64 int64
+	Valid bool // Valid is true if Int64 is not NULL
+}
+
+// Scan implements the Scanner interface.
+func (n *NullInt64) Scan(value interface{}) error {
+	if value == nil {
+		n.Int64, n.Valid = 0, false
+		return nil
+	}
+	n.Valid = true
+	return convertAssign(&n.Int64, value)
+}
+
+// Value implements the driver Valuer interface.
+func (n NullInt64) Value() (driver.Value, error) {
+	if !n.Valid {
+		return nil, nil
+	}
+	return n.Int64, nil
+}
+
+// NullFloat64 represents a float64 that may be null.
+// NullFloat64 implements the Scanner interface so
+// it can be used as a scan destination, similar to NullString.
+type NullFloat64 struct {
+	Float64 float64
+	Valid   bool // Valid is true if Float64 is not NULL
+}
+
+// Scan implements the Scanner interface.
+func (n *NullFloat64) Scan(value interface{}) error {
+	if value == nil {
+		n.Float64, n.Valid = 0, false
+		return nil
+	}
+	n.Valid = true
+	return convertAssign(&n.Float64, value)
+}
+
+// Value implements the driver Valuer interface.
+func (n NullFloat64) Value() (driver.Value, error) {
+	if !n.Valid {
+		return nil, nil
+	}
+	return n.Float64, nil
+}
+
+// NullBool represents a bool that may be null.
+// NullBool implements the Scanner interface so
+// it can be used as a scan destination, similar to NullString.
+type NullBool struct {
+	Bool  bool
+	Valid bool // Valid is true if Bool is not NULL
+}
+
+// Scan implements the Scanner interface.
+func (n *NullBool) Scan(value interface{}) error {
+	if value == nil {
+		n.Bool, n.Valid = false, false
+		return nil
+	}
+	n.Valid = true
+	return convertAssign(&n.Bool, value)
+}
+
+// Value implements the driver Valuer interface.
+func (n NullBool) Value() (driver.Value, error) {
+	if !n.Valid {
+		return nil, nil
+	}
+	return n.Bool, nil
+}
+
+// Scanner is an interface used by Scan.
+type Scanner interface {
+	// Scan assigns a value from a database driver.
+	//
+	// The src value will be of one of the following restricted
+	// set of types:
+	//
+	//    int64
+	//    float64
+	//    bool
+	//    []byte
+	//    string
+	//    time.Time
+	//    nil - for NULL values
+	//
+	// An error should be returned if the value can not be stored
+	// without loss of information.
+	Scan(src interface{}) error
+}
+
+// ErrNoRows is returned by Scan when QueryRow doesn't return a
+// row. In such a case, QueryRow returns a placeholder *Row value that
+// defers this error until a Scan.
+var ErrNoRows = errors.New("sql: no rows in result set")
+
+// DB is a database handle representing a pool of zero or more
+// underlying connections. It's safe for concurrent use by multiple
+// goroutines.
+//
+// The sql package creates and frees connections automatically; it
+// also maintains a free pool of idle connections. If the database has
+// a concept of per-connection state, such state can only be reliably
+// observed within a transaction. Once DB.Begin is called, the
+// returned Tx is bound to a single connection. Once Commit or
+// Rollback is called on the transaction, that transaction's
+// connection is returned to DB's idle connection pool. The pool size
+// can be controlled with SetMaxIdleConns.
+type DB struct {
+	driver driver.Driver
+	dsn    string
+
+	mu           sync.Mutex // protects following fields
+	freeConn     []*driverConn
+	connRequests []chan connRequest
+	numOpen      int
+	pendingOpens int
+	// Used to signal the need for new connections
+	// a goroutine running connectionOpener() reads on this chan and
+	// maybeOpenNewConnections sends on the chan (one send per needed connection)
+	// It is closed during db.Close(). The close tells the connectionOpener
+	// goroutine to exit.
+	openerCh chan struct{}
+	closed   bool
+	dep      map[finalCloser]depSet
+	lastPut  map[*driverConn]string // stacktrace of last conn's put; debug only
+	maxIdle  int                    // zero means defaultMaxIdleConns; negative means 0
+	maxOpen  int                    // <= 0 means unlimited
+}
+
+// driverConn wraps a driver.Conn with a mutex, to
+// be held during all calls into the Conn. (including any calls onto
+// interfaces returned via that Conn, such as calls on Tx, Stmt,
+// Result, Rows)
+type driverConn struct {
+	db *DB
+
+	sync.Mutex  // guards following
+	ci          driver.Conn
+	closed      bool
+	finalClosed bool // ci.Close has been called
+	openStmt    map[driver.Stmt]bool
+
+	// guarded by db.mu
+	inUse      bool
+	onPut      []func() // code (with db.mu held) run when conn is next returned
+	dbmuClosed bool     // same as closed, but guarded by db.mu, for connIfFree
+}
+
+func (dc *driverConn) releaseConn(err error) {
+	dc.db.putConn(dc, err)
+}
+
+func (dc *driverConn) removeOpenStmt(si driver.Stmt) {
+	dc.Lock()
+	defer dc.Unlock()
+	delete(dc.openStmt, si)
+}
+
+func (dc *driverConn) prepareLocked(query string) (driver.Stmt, error) {
+	si, err := dc.ci.Prepare(query)
+	if err == nil {
+		// Track each driverConn's open statements, so we can close them
+		// before closing the conn.
+		//
+		// TODO(bradfitz): let drivers opt out of caring about
+		// stmt closes if the conn is about to close anyway? For now
+		// do the safe thing, in case stmts need to be closed.
+		//
+		// TODO(bradfitz): after Go 1.2, closing driver.Stmts
+		// should be moved to driverStmt, using unique
+		// *driverStmts everywhere (including from
+		// *Stmt.connStmt, instead of returning a
+		// driver.Stmt), using driverStmt as a pointer
+		// everywhere, and making it a finalCloser.
+		if dc.openStmt == nil {
+			dc.openStmt = make(map[driver.Stmt]bool)
+		}
+		dc.openStmt[si] = true
+	}
+	return si, err
+}
+
+// the dc.db's Mutex is held.
+func (dc *driverConn) closeDBLocked() func() error {
+	dc.Lock()
+	defer dc.Unlock()
+	if dc.closed {
+		return func() error { return errors.New("sql: duplicate driverConn close") }
+	}
+	dc.closed = true
+	return dc.db.removeDepLocked(dc, dc)
+}
+
+func (dc *driverConn) Close() error {
+	dc.Lock()
+	if dc.closed {
+		dc.Unlock()
+		return errors.New("sql: duplicate driverConn close")
+	}
+	dc.closed = true
+	dc.Unlock() // not defer; removeDep finalClose calls may need to lock
+
+	// And now updates that require holding dc.mu.Lock.
+	dc.db.mu.Lock()
+	dc.dbmuClosed = true
+	fn := dc.db.removeDepLocked(dc, dc)
+	dc.db.mu.Unlock()
+	return fn()
+}
+
+func (dc *driverConn) finalClose() error {
+	dc.Lock()
+
+	for si := range dc.openStmt {
+		si.Close()
+	}
+	dc.openStmt = nil
+
+	err := dc.ci.Close()
+	dc.ci = nil
+	dc.finalClosed = true
+	dc.Unlock()
+
+	dc.db.mu.Lock()
+	dc.db.numOpen--
+	dc.db.maybeOpenNewConnections()
+	dc.db.mu.Unlock()
+
+	return err
+}
+
+// driverStmt associates a driver.Stmt with the
+// *driverConn from which it came, so the driverConn's lock can be
+// held during calls.
+type driverStmt struct {
+	sync.Locker // the *driverConn
+	si          driver.Stmt
+}
+
+func (ds *driverStmt) Close() error {
+	ds.Lock()
+	defer ds.Unlock()
+	return ds.si.Close()
+}
+
+// depSet is a finalCloser's outstanding dependencies
+type depSet map[interface{}]bool // set of true bools
+
+// The finalCloser interface is used by (*DB).addDep and related
+// dependency reference counting.
+type finalCloser interface {
+	// finalClose is called when the reference count of an object
+	// goes to zero. (*DB).mu is not held while calling it.
+	finalClose() error
+}
+
+// addDep notes that x now depends on dep, and x's finalClose won't be
+// called until all of x's dependencies are removed with removeDep.
+func (db *DB) addDep(x finalCloser, dep interface{}) {
+	//println(fmt.Sprintf("addDep(%T %p, %T %p)", x, x, dep, dep))
+	db.mu.Lock()
+	defer db.mu.Unlock()
+	db.addDepLocked(x, dep)
+}
+
+func (db *DB) addDepLocked(x finalCloser, dep interface{}) {
+	if db.dep == nil {
+		db.dep = make(map[finalCloser]depSet)
+	}
+	xdep := db.dep[x]
+	if xdep == nil {
+		xdep = make(depSet)
+		db.dep[x] = xdep
+	}
+	xdep[dep] = true
+}
+
+// removeDep notes that x no longer depends on dep.
+// If x still has dependencies, nil is returned.
+// If x no longer has any dependencies, its finalClose method will be
+// called and its error value will be returned.
+func (db *DB) removeDep(x finalCloser, dep interface{}) error {
+	db.mu.Lock()
+	fn := db.removeDepLocked(x, dep)
+	db.mu.Unlock()
+	return fn()
+}
+
+func (db *DB) removeDepLocked(x finalCloser, dep interface{}) func() error {
+	//println(fmt.Sprintf("removeDep(%T %p, %T %p)", x, x, dep, dep))
+
+	xdep, ok := db.dep[x]
+	if !ok {
+		panic(fmt.Sprintf("unpaired removeDep: no deps for %T", x))
+	}
+
+	l0 := len(xdep)
+	delete(xdep, dep)
+
+	switch len(xdep) {
+	case l0:
+		// Nothing removed. Shouldn't happen.
+		panic(fmt.Sprintf("unpaired removeDep: no %T dep on %T", dep, x))
+	case 0:
+		// No more dependencies.
+		delete(db.dep, x)
+		return x.finalClose
+	default:
+		// Dependencies remain.
+		return func() error { return nil }
+	}
+}
+
+// This is the size of the connectionOpener request chan (dn.openerCh).
+// This value should be larger than the maximum typical value
+// used for db.maxOpen. If maxOpen is significantly larger than
+// connectionRequestQueueSize then it is possible for ALL calls into the *DB
+// to block until the connectionOpener can satisfy the backlog of requests.
+var connectionRequestQueueSize = 1000000
+
+// Open opens a database specified by its database driver name and a
+// driver-specific data source name, usually consisting of at least a
+// database name and connection information.
+//
+// Most users will open a database via a driver-specific connection
+// helper function that returns a *DB. No database drivers are included
+// in the Go standard library. See http://golang.org/s/sqldrivers for
+// a list of third-party drivers.
+//
+// Open may just validate its arguments without creating a connection
+// to the database. To verify that the data source name is valid, call
+// Ping.
+//
+// The returned DB is safe for concurrent use by multiple goroutines
+// and maintains its own pool of idle connections. Thus, the Open
+// function should be called just once. It is rarely necessary to
+// close a DB.
+func Open(driverName, dataSourceName string) (*DB, error) {
+	driveri, ok := drivers[driverName]
+	if !ok {
+		return nil, fmt.Errorf("sql: unknown driver %q (forgotten import?)", driverName)
+	}
+	db := &DB{
+		driver:   driveri,
+		dsn:      dataSourceName,
+		openerCh: make(chan struct{}, connectionRequestQueueSize),
+		lastPut:  make(map[*driverConn]string),
+	}
+	go db.connectionOpener()
+	return db, nil
+}
+
+// Ping verifies a connection to the database is still alive,
+// establishing a connection if necessary.
+func (db *DB) Ping() error {
+	// TODO(bradfitz): give drivers an optional hook to implement
+	// this in a more efficient or more reliable way, if they
+	// have one.
+	dc, err := db.conn()
+	if err != nil {
+		return err
+	}
+	db.putConn(dc, nil)
+	return nil
+}
+
+// Close closes the database, releasing any open resources.
+//
+// It is rare to Close a DB, as the DB handle is meant to be
+// long-lived and shared between many goroutines.
+func (db *DB) Close() error {
+	db.mu.Lock()
+	if db.closed { // Make DB.Close idempotent
+		db.mu.Unlock()
+		return nil
+	}
+	close(db.openerCh)
+	var err error
+	fns := make([]func() error, 0, len(db.freeConn))
+	for _, dc := range db.freeConn {
+		fns = append(fns, dc.closeDBLocked())
+	}
+	db.freeConn = nil
+	db.closed = true
+	for _, req := range db.connRequests {
+		close(req)
+	}
+	db.mu.Unlock()
+	for _, fn := range fns {
+		err1 := fn()
+		if err1 != nil {
+			err = err1
+		}
+	}
+	return err
+}
+
+const defaultMaxIdleConns = 2
+
+func (db *DB) maxIdleConnsLocked() int {
+	n := db.maxIdle
+	switch {
+	case n == 0:
+		// TODO(bradfitz): ask driver, if supported, for its default preference
+		return defaultMaxIdleConns
+	case n < 0:
+		return 0
+	default:
+		return n
+	}
+}
+
+// SetMaxIdleConns sets the maximum number of connections in the idle
+// connection pool.
+//
+// If MaxOpenConns is greater than 0 but less than the new MaxIdleConns
+// then the new MaxIdleConns will be reduced to match the MaxOpenConns limit
+//
+// If n <= 0, no idle connections are retained.
+func (db *DB) SetMaxIdleConns(n int) {
+	db.mu.Lock()
+	if n > 0 {
+		db.maxIdle = n
+	} else {
+		// No idle connections.
+		db.maxIdle = -1
+	}
+	// Make sure maxIdle doesn't exceed maxOpen
+	if db.maxOpen > 0 && db.maxIdleConnsLocked() > db.maxOpen {
+		db.maxIdle = db.maxOpen
+	}
+	var closing []*driverConn
+	idleCount := len(db.freeConn)
+	maxIdle := db.maxIdleConnsLocked()
+	if idleCount > maxIdle {
+		closing = db.freeConn[maxIdle:]
+		db.freeConn = db.freeConn[:maxIdle]
+	}
+	db.mu.Unlock()
+	for _, c := range closing {
+		c.Close()
+	}
+}
+
+// SetMaxOpenConns sets the maximum number of open connections to the database.
+//
+// If MaxIdleConns is greater than 0 and the new MaxOpenConns is less than
+// MaxIdleConns, then MaxIdleConns will be reduced to match the new
+// MaxOpenConns limit
+//
+// If n <= 0, then there is no limit on the number of open connections.
+// The default is 0 (unlimited).
+func (db *DB) SetMaxOpenConns(n int) {
+	db.mu.Lock()
+	db.maxOpen = n
+	if n < 0 {
+		db.maxOpen = 0
+	}
+	syncMaxIdle := db.maxOpen > 0 && db.maxIdleConnsLocked() > db.maxOpen
+	db.mu.Unlock()
+	if syncMaxIdle {
+		db.SetMaxIdleConns(n)
+	}
+}
+
+// Assumes db.mu is locked.
+// If there are connRequests and the connection limit hasn't been reached,
+// then tell the connectionOpener to open new connections.
+func (db *DB) maybeOpenNewConnections() {
+	numRequests := len(db.connRequests) - db.pendingOpens
+	if db.maxOpen > 0 {
+		numCanOpen := db.maxOpen - (db.numOpen + db.pendingOpens)
+		if numRequests > numCanOpen {
+			numRequests = numCanOpen
+		}
+	}
+	for numRequests > 0 {
+		db.pendingOpens++
+		numRequests--
+		db.openerCh <- struct{}{}
+	}
+}
+
+// Runs in a separate goroutine, opens new connections when requested.
+func (db *DB) connectionOpener() {
+	for range db.openerCh {
+		db.openNewConnection()
+	}
+}
+
+// Open one new connection
+func (db *DB) openNewConnection() {
+	ci, err := db.driver.Open(db.dsn)
+	db.mu.Lock()
+	defer db.mu.Unlock()
+	if db.closed {
+		if err == nil {
+			ci.Close()
+		}
+		return
+	}
+	db.pendingOpens--
+	if err != nil {
+		db.putConnDBLocked(nil, err)
+		return
+	}
+	dc := &driverConn{
+		db: db,
+		ci: ci,
+	}
+	if db.putConnDBLocked(dc, err) {
+		db.addDepLocked(dc, dc)
+		db.numOpen++
+	} else {
+		ci.Close()
+	}
+}
+
+// connRequest represents one request for a new connection
+// When there are no idle connections available, DB.conn will create
+// a new connRequest and put it on the db.connRequests list.
+type connRequest struct {
+	conn *driverConn
+	err  error
+}
+
+var errDBClosed = errors.New("sql: database is closed")
+
+// conn returns a newly-opened or cached *driverConn
+func (db *DB) conn() (*driverConn, error) {
+	db.mu.Lock()
+	if db.closed {
+		db.mu.Unlock()
+		return nil, errDBClosed
+	}
+
+	// If db.maxOpen > 0 and the number of open connections is over the limit
+	// and there are no free connection, make a request and wait.
+	if db.maxOpen > 0 && db.numOpen >= db.maxOpen && len(db.freeConn) == 0 {
+		// Make the connRequest channel. It's buffered so that the
+		// connectionOpener doesn't block while waiting for the req to be read.
+		req := make(chan connRequest, 1)
+		db.connRequests = append(db.connRequests, req)
+		db.maybeOpenNewConnections()
+		db.mu.Unlock()
+		ret := <-req
+		return ret.conn, ret.err
+	}
+
+	if c := len(db.freeConn); c > 0 {
+		conn := db.freeConn[0]
+		copy(db.freeConn, db.freeConn[1:])
+		db.freeConn = db.freeConn[:c-1]
+		conn.inUse = true
+		db.mu.Unlock()
+		return conn, nil
+	}
+
+	db.numOpen++ // optimistically
+	db.mu.Unlock()
+	ci, err := db.driver.Open(db.dsn)
+	if err != nil {
+		db.mu.Lock()
+		db.numOpen-- // correct for earlier optimism
+		db.mu.Unlock()
+		return nil, err
+	}
+	db.mu.Lock()
+	dc := &driverConn{
+		db: db,
+		ci: ci,
+	}
+	db.addDepLocked(dc, dc)
+	dc.inUse = true
+	db.mu.Unlock()
+	return dc, nil
+}
+
+var (
+	errConnClosed = errors.New("database/sql: internal sentinel error: conn is closed")
+	errConnBusy   = errors.New("database/sql: internal sentinel error: conn is busy")
+)
+
+// connIfFree returns (wanted, nil) if wanted is still a valid conn and
+// isn't in use.
+//
+// The error is errConnClosed if the connection if the requested connection
+// is invalid because it's been closed.
+//
+// The error is errConnBusy if the connection is in use.
+func (db *DB) connIfFree(wanted *driverConn) (*driverConn, error) {
+	db.mu.Lock()
+	defer db.mu.Unlock()
+	if wanted.dbmuClosed {
+		return nil, errConnClosed
+	}
+	if wanted.inUse {
+		return nil, errConnBusy
+	}
+	idx := -1
+	for ii, v := range db.freeConn {
+		if v == wanted {
+			idx = ii
+			break
+		}
+	}
+	if idx >= 0 {
+		db.freeConn = append(db.freeConn[:idx], db.freeConn[idx+1:]...)
+		wanted.inUse = true
+		return wanted, nil
+	}
+	// TODO(bradfitz): shouldn't get here. After Go 1.1, change this to:
+	// panic("connIfFree call requested a non-closed, non-busy, non-free conn")
+	// Which passes all the tests, but I'm too paranoid to include this
+	// late in Go 1.1.
+	// Instead, treat it like a busy connection:
+	return nil, errConnBusy
+}
+
+// putConnHook is a hook for testing.
+var putConnHook func(*DB, *driverConn)
+
+// noteUnusedDriverStatement notes that si is no longer used and should
+// be closed whenever possible (when c is next not in use), unless c is
+// already closed.
+func (db *DB) noteUnusedDriverStatement(c *driverConn, si driver.Stmt) {
+	db.mu.Lock()
+	defer db.mu.Unlock()
+	if c.inUse {
+		c.onPut = append(c.onPut, func() {
+			si.Close()
+		})
+	} else {
+		c.Lock()
+		defer c.Unlock()
+		if !c.finalClosed {
+			si.Close()
+		}
+	}
+}
+
+// debugGetPut determines whether getConn & putConn calls' stack traces
+// are returned for more verbose crashes.
+const debugGetPut = false
+
+// putConn adds a connection to the db's free pool.
+// err is optionally the last error that occurred on this connection.
+func (db *DB) putConn(dc *driverConn, err error) {
+	db.mu.Lock()
+	if !dc.inUse {
+		if debugGetPut {
+			fmt.Printf("putConn(%v) DUPLICATE was: %s\n\nPREVIOUS was: %s", dc, stack(), db.lastPut[dc])
+		}
+		panic("sql: connection returned that was never out")
+	}
+	if debugGetPut {
+		db.lastPut[dc] = stack()
+	}
+	dc.inUse = false
+
+	for _, fn := range dc.onPut {
+		fn()
+	}
+	dc.onPut = nil
+
+	if err == driver.ErrBadConn {
+		// Don't reuse bad connections.
+		// Since the conn is considered bad and is being discarded, treat it
+		// as closed. Don't decrement the open count here, finalClose will
+		// take care of that.
+		db.maybeOpenNewConnections()
+		db.mu.Unlock()
+		dc.Close()
+		return
+	}
+	if putConnHook != nil {
+		putConnHook(db, dc)
+	}
+	added := db.putConnDBLocked(dc, nil)
+	db.mu.Unlock()
+
+	if !added {
+		dc.Close()
+	}
+}
+
+// Satisfy a connRequest or put the driverConn in the idle pool and return true
+// or return false.
+// putConnDBLocked will satisfy a connRequest if there is one, or it will
+// return the *driverConn to the freeConn list if err == nil and the idle
+// connection limit will not be exceeded.
+// If err != nil, the value of dc is ignored.
+// If err == nil, then dc must not equal nil.
+// If a connRequest was fulfilled or the *driverConn was placed in the
+// freeConn list, then true is returned, otherwise false is returned.
+func (db *DB) putConnDBLocked(dc *driverConn, err error) bool {
+	if c := len(db.connRequests); c > 0 {
+		req := db.connRequests[0]
+		// This copy is O(n) but in practice faster than a linked list.
+		// TODO: consider compacting it down less often and
+		// moving the base instead?
+		copy(db.connRequests, db.connRequests[1:])
+		db.connRequests = db.connRequests[:c-1]
+		if err == nil {
+			dc.inUse = true
+		}
+		req <- connRequest{
+			conn: dc,
+			err:  err,
+		}
+		return true
+	} else if err == nil && !db.closed && db.maxIdleConnsLocked() > len(db.freeConn) {
+		db.freeConn = append(db.freeConn, dc)
+		return true
+	}
+	return false
+}
+
+// maxBadConnRetries is the number of maximum retries if the driver returns
+// driver.ErrBadConn to signal a broken connection.
+const maxBadConnRetries = 10
+
+// Prepare creates a prepared statement for later queries or executions.
+// Multiple queries or executions may be run concurrently from the
+// returned statement.
+func (db *DB) Prepare(query string) (*Stmt, error) {
+	var stmt *Stmt
+	var err error
+	for i := 0; i < maxBadConnRetries; i++ {
+		stmt, err = db.prepare(query)
+		if err != driver.ErrBadConn {
+			break
+		}
+	}
+	return stmt, err
+}
+
+func (db *DB) prepare(query string) (*Stmt, error) {
+	// TODO: check if db.driver supports an optional
+	// driver.Preparer interface and call that instead, if so,
+	// otherwise we make a prepared statement that's bound
+	// to a connection, and to execute this prepared statement
+	// we either need to use this connection (if it's free), else
+	// get a new connection + re-prepare + execute on that one.
+	dc, err := db.conn()
+	if err != nil {
+		return nil, err
+	}
+	dc.Lock()
+	si, err := dc.prepareLocked(query)
+	dc.Unlock()
+	if err != nil {
+		db.putConn(dc, err)
+		return nil, err
+	}
+	stmt := &Stmt{
+		db:    db,
+		query: query,
+		css:   []connStmt{{dc, si}},
+	}
+	db.addDep(stmt, stmt)
+	db.putConn(dc, nil)
+	return stmt, nil
+}
+
+// Exec executes a query without returning any rows.
+// The args are for any placeholder parameters in the query.
+func (db *DB) Exec(query string, args ...interface{}) (Result, error) {
+	var res Result
+	var err error
+	for i := 0; i < maxBadConnRetries; i++ {
+		res, err = db.exec(query, args)
+		if err != driver.ErrBadConn {
+			break
+		}
+	}
+	return res, err
+}
+
+func (db *DB) exec(query string, args []interface{}) (res Result, err error) {
+	dc, err := db.conn()
+	if err != nil {
+		return nil, err
+	}
+	defer func() {
+		db.putConn(dc, err)
+	}()
+
+	if execer, ok := dc.ci.(driver.Execer); ok {
+		dargs, err := driverArgs(nil, args)
+		if err != nil {
+			return nil, err
+		}
+		dc.Lock()
+		resi, err := execer.Exec(query, dargs)
+		dc.Unlock()
+		if err != driver.ErrSkip {
+			if err != nil {
+				return nil, err
+			}
+			return driverResult{dc, resi}, nil
+		}
+	}
+
+	dc.Lock()
+	si, err := dc.ci.Prepare(query)
+	dc.Unlock()
+	if err != nil {
+		return nil, err
+	}
+	defer withLock(dc, func() { si.Close() })
+	return resultFromStatement(driverStmt{dc, si}, args...)
+}
+
+// Query executes a query that returns rows, typically a SELECT.
+// The args are for any placeholder parameters in the query.
+func (db *DB) Query(query string, args ...interface{}) (*Rows, error) {
+	var rows *Rows
+	var err error
+	for i := 0; i < maxBadConnRetries; i++ {
+		rows, err = db.query(query, args)
+		if err != driver.ErrBadConn {
+			break
+		}
+	}
+	return rows, err
+}
+
+func (db *DB) query(query string, args []interface{}) (*Rows, error) {
+	ci, err := db.conn()
+	if err != nil {
+		return nil, err
+	}
+
+	return db.queryConn(ci, ci.releaseConn, query, args)
+}
+
+// queryConn executes a query on the given connection.
+// The connection gets released by the releaseConn function.
+func (db *DB) queryConn(dc *driverConn, releaseConn func(error), query string, args []interface{}) (*Rows, error) {
+	if queryer, ok := dc.ci.(driver.Queryer); ok {
+		dargs, err := driverArgs(nil, args)
+		if err != nil {
+			releaseConn(err)
+			return nil, err
+		}
+		dc.Lock()
+		rowsi, err := queryer.Query(query, dargs)
+		dc.Unlock()
+		if err != driver.ErrSkip {
+			if err != nil {
+				releaseConn(err)
+				return nil, err
+			}
+			// Note: ownership of dc passes to the *Rows, to be freed
+			// with releaseConn.
+			rows := &Rows{
+				dc:          dc,
+				releaseConn: releaseConn,
+				rowsi:       rowsi,
+			}
+			return rows, nil
+		}
+	}
+
+	dc.Lock()
+	si, err := dc.ci.Prepare(query)
+	dc.Unlock()
+	if err != nil {
+		releaseConn(err)
+		return nil, err
+	}
+
+	ds := driverStmt{dc, si}
+	rowsi, err := rowsiFromStatement(ds, args...)
+	if err != nil {
+		dc.Lock()
+		si.Close()
+		dc.Unlock()
+		releaseConn(err)
+		return nil, err
+	}
+
+	// Note: ownership of ci passes to the *Rows, to be freed
+	// with releaseConn.
+	rows := &Rows{
+		dc:          dc,
+		releaseConn: releaseConn,
+		rowsi:       rowsi,
+		closeStmt:   si,
+	}
+	return rows, nil
+}
+
+// QueryRow executes a query that is expected to return at most one row.
+// QueryRow always return a non-nil value. Errors are deferred until
+// Row's Scan method is called.
+func (db *DB) QueryRow(query string, args ...interface{}) *Row {
+	rows, err := db.Query(query, args...)
+	return &Row{rows: rows, err: err}
+}
+
+// Begin starts a transaction. The isolation level is dependent on
+// the driver.
+func (db *DB) Begin() (*Tx, error) {
+	var tx *Tx
+	var err error
+	for i := 0; i < maxBadConnRetries; i++ {
+		tx, err = db.begin()
+		if err != driver.ErrBadConn {
+			break
+		}
+	}
+	return tx, err
+}
+
+func (db *DB) begin() (tx *Tx, err error) {
+	dc, err := db.conn()
+	if err != nil {
+		return nil, err
+	}
+	dc.Lock()
+	txi, err := dc.ci.Begin()
+	dc.Unlock()
+	if err != nil {
+		db.putConn(dc, err)
+		return nil, err
+	}
+	return &Tx{
+		db:  db,
+		dc:  dc,
+		txi: txi,
+	}, nil
+}
+
+// Driver returns the database's underlying driver.
+func (db *DB) Driver() driver.Driver {
+	return db.driver
+}
+
+// Tx is an in-progress database transaction.
+//
+// A transaction must end with a call to Commit or Rollback.
+//
+// After a call to Commit or Rollback, all operations on the
+// transaction fail with ErrTxDone.
+type Tx struct {
+	db *DB
+
+	// dc is owned exclusively until Commit or Rollback, at which point
+	// it's returned with putConn.
+	dc  *driverConn
+	txi driver.Tx
+
+	// done transitions from false to true exactly once, on Commit
+	// or Rollback. once done, all operations fail with
+	// ErrTxDone.
+	done bool
+
+	// All Stmts prepared for this transaction.  These will be closed after the
+	// transaction has been committed or rolled back.
+	stmts struct {
+		sync.Mutex
+		v []*Stmt
+	}
+}
+
+var ErrTxDone = errors.New("sql: Transaction has already been committed or rolled back")
+
+func (tx *Tx) close() {
+	if tx.done {
+		panic("double close") // internal error
+	}
+	tx.done = true
+	tx.db.putConn(tx.dc, nil)
+	tx.dc = nil
+	tx.txi = nil
+}
+
+func (tx *Tx) grabConn() (*driverConn, error) {
+	if tx.done {
+		return nil, ErrTxDone
+	}
+	return tx.dc, nil
+}
+
+// Closes all Stmts prepared for this transaction.
+func (tx *Tx) closePrepared() {
+	tx.stmts.Lock()
+	for _, stmt := range tx.stmts.v {
+		stmt.Close()
+	}
+	tx.stmts.Unlock()
+}
+
+// Commit commits the transaction.
+func (tx *Tx) Commit() error {
+	if tx.done {
+		return ErrTxDone
+	}
+	defer tx.close()
+	tx.dc.Lock()
+	err := tx.txi.Commit()
+	tx.dc.Unlock()
+	if err != driver.ErrBadConn {
+		tx.closePrepared()
+	}
+	return err
+}
+
+// Rollback aborts the transaction.
+func (tx *Tx) Rollback() error {
+	if tx.done {
+		return ErrTxDone
+	}
+	defer tx.close()
+	tx.dc.Lock()
+	err := tx.txi.Rollback()
+	tx.dc.Unlock()
+	if err != driver.ErrBadConn {
+		tx.closePrepared()
+	}
+	return err
+}
+
+// Prepare creates a prepared statement for use within a transaction.
+//
+// The returned statement operates within the transaction and can no longer
+// be used once the transaction has been committed or rolled back.
+//
+// To use an existing prepared statement on this transaction, see Tx.Stmt.
+func (tx *Tx) Prepare(query string) (*Stmt, error) {
+	// TODO(bradfitz): We could be more efficient here and either
+	// provide a method to take an existing Stmt (created on
+	// perhaps a different Conn), and re-create it on this Conn if
+	// necessary. Or, better: keep a map in DB of query string to
+	// Stmts, and have Stmt.Execute do the right thing and
+	// re-prepare if the Conn in use doesn't have that prepared
+	// statement.  But we'll want to avoid caching the statement
+	// in the case where we only call conn.Prepare implicitly
+	// (such as in db.Exec or tx.Exec), but the caller package
+	// can't be holding a reference to the returned statement.
+	// Perhaps just looking at the reference count (by noting
+	// Stmt.Close) would be enough. We might also want a finalizer
+	// on Stmt to drop the reference count.
+	dc, err := tx.grabConn()
+	if err != nil {
+		return nil, err
+	}
+
+	dc.Lock()
+	si, err := dc.ci.Prepare(query)
+	dc.Unlock()
+	if err != nil {
+		return nil, err
+	}
+
+	stmt := &Stmt{
+		db: tx.db,
+		tx: tx,
+		txsi: &driverStmt{
+			Locker: dc,
+			si:     si,
+		},
+		query: query,
+	}
+	tx.stmts.Lock()
+	tx.stmts.v = append(tx.stmts.v, stmt)
+	tx.stmts.Unlock()
+	return stmt, nil
+}
+
+// Stmt returns a transaction-specific prepared statement from
+// an existing statement.
+//
+// Example:
+//  updateMoney, err := db.Prepare("UPDATE balance SET money=money+? WHERE id=?")
+//  ...
+//  tx, err := db.Begin()
+//  ...
+//  res, err := tx.Stmt(updateMoney).Exec(123.45, 98293203)
+func (tx *Tx) Stmt(stmt *Stmt) *Stmt {
+	// TODO(bradfitz): optimize this. Currently this re-prepares
+	// each time.  This is fine for now to illustrate the API but
+	// we should really cache already-prepared statements
+	// per-Conn. See also the big comment in Tx.Prepare.
+
+	if tx.db != stmt.db {
+		return &Stmt{stickyErr: errors.New("sql: Tx.Stmt: statement from different database used")}
+	}
+	dc, err := tx.grabConn()
+	if err != nil {
+		return &Stmt{stickyErr: err}
+	}
+	dc.Lock()
+	si, err := dc.ci.Prepare(stmt.query)
+	dc.Unlock()
+	txs := &Stmt{
+		db: tx.db,
+		tx: tx,
+		txsi: &driverStmt{
+			Locker: dc,
+			si:     si,
+		},
+		query:     stmt.query,
+		stickyErr: err,
+	}
+	tx.stmts.Lock()
+	tx.stmts.v = append(tx.stmts.v, txs)
+	tx.stmts.Unlock()
+	return txs
+}
+
+// Exec executes a query that doesn't return rows.
+// For example: an INSERT and UPDATE.
+func (tx *Tx) Exec(query string, args ...interface{}) (Result, error) {
+	dc, err := tx.grabConn()
+	if err != nil {
+		return nil, err
+	}
+
+	if execer, ok := dc.ci.(driver.Execer); ok {
+		dargs, err := driverArgs(nil, args)
+		if err != nil {
+			return nil, err
+		}
+		dc.Lock()
+		resi, err := execer.Exec(query, dargs)
+		dc.Unlock()
+		if err == nil {
+			return driverResult{dc, resi}, nil
+		}
+		if err != driver.ErrSkip {
+			return nil, err
+		}
+	}
+
+	dc.Lock()
+	si, err := dc.ci.Prepare(query)
+	dc.Unlock()
+	if err != nil {
+		return nil, err
+	}
+	defer withLock(dc, func() { si.Close() })
+
+	return resultFromStatement(driverStmt{dc, si}, args...)
+}
+
+// Query executes a query that returns rows, typically a SELECT.
+func (tx *Tx) Query(query string, args ...interface{}) (*Rows, error) {
+	dc, err := tx.grabConn()
+	if err != nil {
+		return nil, err
+	}
+	releaseConn := func(error) {}
+	return tx.db.queryConn(dc, releaseConn, query, args)
+}
+
+// QueryRow executes a query that is expected to return at most one row.
+// QueryRow always return a non-nil value. Errors are deferred until
+// Row's Scan method is called.
+func (tx *Tx) QueryRow(query string, args ...interface{}) *Row {
+	rows, err := tx.Query(query, args...)
+	return &Row{rows: rows, err: err}
+}
+
+// connStmt is a prepared statement on a particular connection.
+type connStmt struct {
+	dc *driverConn
+	si driver.Stmt
+}
+
+// Stmt is a prepared statement. Stmt is safe for concurrent use by multiple goroutines.
+type Stmt struct {
+	// Immutable:
+	db        *DB    // where we came from
+	query     string // that created the Stmt
+	stickyErr error  // if non-nil, this error is returned for all operations
+
+	closemu sync.RWMutex // held exclusively during close, for read otherwise.
+
+	// If in a transaction, else both nil:
+	tx   *Tx
+	txsi *driverStmt
+
+	mu     sync.Mutex // protects the rest of the fields
+	closed bool
+
+	// css is a list of underlying driver statement interfaces
+	// that are valid on particular connections.  This is only
+	// used if tx == nil and one is found that has idle
+	// connections.  If tx != nil, txsi is always used.
+	css []connStmt
+}
+
+// Exec executes a prepared statement with the given arguments and
+// returns a Result summarizing the effect of the statement.
+func (s *Stmt) Exec(args ...interface{}) (Result, error) {
+	s.closemu.RLock()
+	defer s.closemu.RUnlock()
+
+	var res Result
+	for i := 0; i < maxBadConnRetries; i++ {
+		dc, releaseConn, si, err := s.connStmt()
+		if err != nil {
+			if err == driver.ErrBadConn {
+				continue
+			}
+			return nil, err
+		}
+
+		res, err = resultFromStatement(driverStmt{dc, si}, args...)
+		releaseConn(err)
+		if err != driver.ErrBadConn {
+			return res, err
+		}
+	}
+	return nil, driver.ErrBadConn
+}
+
+func resultFromStatement(ds driverStmt, args ...interface{}) (Result, error) {
+	ds.Lock()
+	want := ds.si.NumInput()
+	ds.Unlock()
+
+	// -1 means the driver doesn't know how to count the number of
+	// placeholders, so we won't sanity check input here and instead let the
+	// driver deal with errors.
+	if want != -1 && len(args) != want {
+		return nil, fmt.Errorf("sql: expected %d arguments, got %d", want, len(args))
+	}
+
+	dargs, err := driverArgs(&ds, args)
+	if err != nil {
+		return nil, err
+	}
+
+	ds.Lock()
+	resi, err := ds.si.Exec(dargs)
+	ds.Unlock()
+	if err != nil {
+		return nil, err
+	}
+	return driverResult{ds.Locker, resi}, nil
+}
+
+// connStmt returns a free driver connection on which to execute the
+// statement, a function to call to release the connection, and a
+// statement bound to that connection.
+func (s *Stmt) connStmt() (ci *driverConn, releaseConn func(error), si driver.Stmt, err error) {
+	if err = s.stickyErr; err != nil {
+		return
+	}
+	s.mu.Lock()
+	if s.closed {
+		s.mu.Unlock()
+		err = errors.New("sql: statement is closed")
+		return
+	}
+
+	// In a transaction, we always use the connection that the
+	// transaction was created on.
+	if s.tx != nil {
+		s.mu.Unlock()
+		ci, err = s.tx.grabConn() // blocks, waiting for the connection.
+		if err != nil {
+			return
+		}
+		releaseConn = func(error) {}
+		return ci, releaseConn, s.txsi.si, nil
+	}
+
+	for i := 0; i < len(s.css); i++ {
+		v := s.css[i]
+		_, err := s.db.connIfFree(v.dc)
+		if err == nil {
+			s.mu.Unlock()
+			return v.dc, v.dc.releaseConn, v.si, nil
+		}
+		if err == errConnClosed {
+			// Lazily remove dead conn from our freelist.
+			s.css[i] = s.css[len(s.css)-1]
+			s.css = s.css[:len(s.css)-1]
+			i--
+		}
+
+	}
+	s.mu.Unlock()
+
+	// If all connections are busy, either wait for one to become available (if
+	// we've already hit the maximum number of open connections) or create a
+	// new one.
+	//
+	// TODO(bradfitz): or always wait for one? make configurable later?
+	dc, err := s.db.conn()
+	if err != nil {
+		return nil, nil, nil, err
+	}
+
+	// Do another pass over the list to see whether this statement has
+	// already been prepared on the connection assigned to us.
+	s.mu.Lock()
+	for _, v := range s.css {
+		if v.dc == dc {
+			s.mu.Unlock()
+			return dc, dc.releaseConn, v.si, nil
+		}
+	}
+	s.mu.Unlock()
+
+	// No luck; we need to prepare the statement on this connection
+	dc.Lock()
+	si, err = dc.prepareLocked(s.query)
+	dc.Unlock()
+	if err != nil {
+		s.db.putConn(dc, err)
+		return nil, nil, nil, err
+	}
+	s.mu.Lock()
+	cs := connStmt{dc, si}
+	s.css = append(s.css, cs)
+	s.mu.Unlock()
+
+	return dc, dc.releaseConn, si, nil
+}
+
+// Query executes a prepared query statement with the given arguments
+// and returns the query results as a *Rows.
+func (s *Stmt) Query(args ...interface{}) (*Rows, error) {
+	s.closemu.RLock()
+	defer s.closemu.RUnlock()
+
+	var rowsi driver.Rows
+	for i := 0; i < maxBadConnRetries; i++ {
+		dc, releaseConn, si, err := s.connStmt()
+		if err != nil {
+			if err == driver.ErrBadConn {
+				continue
+			}
+			return nil, err
+		}
+
+		rowsi, err = rowsiFromStatement(driverStmt{dc, si}, args...)
+		if err == nil {
+			// Note: ownership of ci passes to the *Rows, to be freed
+			// with releaseConn.
+			rows := &Rows{
+				dc:    dc,
+				rowsi: rowsi,
+				// releaseConn set below
+			}
+			s.db.addDep(s, rows)
+			rows.releaseConn = func(err error) {
+				releaseConn(err)
+				s.db.removeDep(s, rows)
+			}
+			return rows, nil
+		}
+
+		releaseConn(err)
+		if err != driver.ErrBadConn {
+			return nil, err
+		}
+	}
+	return nil, driver.ErrBadConn
+}
+
+func rowsiFromStatement(ds driverStmt, args ...interface{}) (driver.Rows, error) {
+	ds.Lock()
+	want := ds.si.NumInput()
+	ds.Unlock()
+
+	// -1 means the driver doesn't know how to count the number of
+	// placeholders, so we won't sanity check input here and instead let the
+	// driver deal with errors.
+	if want != -1 && len(args) != want {
+		return nil, fmt.Errorf("sql: statement expects %d inputs; got %d", want, len(args))
+	}
+
+	dargs, err := driverArgs(&ds, args)
+	if err != nil {
+		return nil, err
+	}
+
+	ds.Lock()
+	rowsi, err := ds.si.Query(dargs)
+	ds.Unlock()
+	if err != nil {
+		return nil, err
+	}
+	return rowsi, nil
+}
+
+// QueryRow executes a prepared query statement with the given arguments.
+// If an error occurs during the execution of the statement, that error will
+// be returned by a call to Scan on the returned *Row, which is always non-nil.
+// If the query selects no rows, the *Row's Scan will return ErrNoRows.
+// Otherwise, the *Row's Scan scans the first selected row and discards
+// the rest.
+//
+// Example usage:
+//
+//  var name string
+//  err := nameByUseridStmt.QueryRow(id).Scan(&name)
+func (s *Stmt) QueryRow(args ...interface{}) *Row {
+	rows, err := s.Query(args...)
+	if err != nil {
+		return &Row{err: err}
+	}
+	return &Row{rows: rows}
+}
+
+// Close closes the statement.
+func (s *Stmt) Close() error {
+	s.closemu.Lock()
+	defer s.closemu.Unlock()
+
+	if s.stickyErr != nil {
+		return s.stickyErr
+	}
+	s.mu.Lock()
+	if s.closed {
+		s.mu.Unlock()
+		return nil
+	}
+	s.closed = true
+
+	if s.tx != nil {
+		s.txsi.Close()
+		s.mu.Unlock()
+		return nil
+	}
+	s.mu.Unlock()
+
+	return s.db.removeDep(s, s)
+}
+
+func (s *Stmt) finalClose() error {
+	s.mu.Lock()
+	defer s.mu.Unlock()
+	if s.css != nil {
+		for _, v := range s.css {
+			s.db.noteUnusedDriverStatement(v.dc, v.si)
+			v.dc.removeOpenStmt(v.si)
+		}
+		s.css = nil
+	}
+	return nil
+}
+
+// Rows is the result of a query. Its cursor starts before the first row
+// of the result set. Use Next to advance through the rows:
+//
+//     rows, err := db.Query("SELECT ...")
+//     ...
+//     defer rows.Close()
+//     for rows.Next() {
+//         var id int
+//         var name string
+//         err = rows.Scan(&id, &name)
+//         ...
+//     }
+//     err = rows.Err() // get any error encountered during iteration
+//     ...
+type Rows struct {
+	dc          *driverConn // owned; must call releaseConn when closed to release
+	releaseConn func(error)
+	rowsi       driver.Rows
+
+	closed    bool
+	lastcols  []driver.Value
+	lasterr   error       // non-nil only if closed is true
+	closeStmt driver.Stmt // if non-nil, statement to Close on close
+}
+
+// Next prepares the next result row for reading with the Scan method.  It
+// returns true on success, or false if there is no next result row or an error
+// happened while preparing it.  Err should be consulted to distinguish between
+// the two cases.
+//
+// Every call to Scan, even the first one, must be preceded by a call to Next.
+func (rs *Rows) Next() bool {
+	if rs.closed {
+		return false
+	}
+	if rs.lastcols == nil {
+		rs.lastcols = make([]driver.Value, len(rs.rowsi.Columns()))
+	}
+	rs.lasterr = rs.rowsi.Next(rs.lastcols)
+	if rs.lasterr != nil {
+		rs.Close()
+		return false
+	}
+	return true
+}
+
+// Err returns the error, if any, that was encountered during iteration.
+// Err may be called after an explicit or implicit Close.
+func (rs *Rows) Err() error {
+	if rs.lasterr == io.EOF {
+		return nil
+	}
+	return rs.lasterr
+}
+
+// Columns returns the column names.
+// Columns returns an error if the rows are closed, or if the rows
+// are from QueryRow and there was a deferred error.
+func (rs *Rows) Columns() ([]string, error) {
+	if rs.closed {
+		return nil, errors.New("sql: Rows are closed")
+	}
+	if rs.rowsi == nil {
+		return nil, errors.New("sql: no Rows available")
+	}
+	return rs.rowsi.Columns(), nil
+}
+
+// Scan copies the columns in the current row into the values pointed
+// at by dest.
+//
+// If an argument has type *[]byte, Scan saves in that argument a copy
+// of the corresponding data. The copy is owned by the caller and can
+// be modified and held indefinitely. The copy can be avoided by using
+// an argument of type *RawBytes instead; see the documentation for
+// RawBytes for restrictions on its use.
+//
+// If an argument has type *interface{}, Scan copies the value
+// provided by the underlying driver without conversion. If the value
+// is of type []byte, a copy is made and the caller owns the result.
+func (rs *Rows) Scan(dest ...interface{}) error {
+	if rs.closed {
+		return errors.New("sql: Rows are closed")
+	}
+	if rs.lastcols == nil {
+		return errors.New("sql: Scan called without calling Next")
+	}
+	if len(dest) != len(rs.lastcols) {
+		return fmt.Errorf("sql: expected %d destination arguments in Scan, not %d", len(rs.lastcols), len(dest))
+	}
+	for i, sv := range rs.lastcols {
+		err := convertAssign(dest[i], sv)
+		if err != nil {
+			return fmt.Errorf("sql: Scan error on column index %d: %v", i, err)
+		}
+	}
+	return nil
+}
+
+var rowsCloseHook func(*Rows, *error)
+
+// Close closes the Rows, preventing further enumeration. If Next returns
+// false, the Rows are closed automatically and it will suffice to check the
+// result of Err. Close is idempotent and does not affect the result of Err.
+func (rs *Rows) Close() error {
+	if rs.closed {
+		return nil
+	}
+	rs.closed = true
+	err := rs.rowsi.Close()
+	if fn := rowsCloseHook; fn != nil {
+		fn(rs, &err)
+	}
+	if rs.closeStmt != nil {
+		rs.closeStmt.Close()
+	}
+	rs.releaseConn(err)
+	return err
+}
+
+// Row is the result of calling QueryRow to select a single row.
+type Row struct {
+	// One of these two will be non-nil:
+	err  error // deferred error for easy chaining
+	rows *Rows
+}
+
+// Scan copies the columns from the matched row into the values
+// pointed at by dest.  If more than one row matches the query,
+// Scan uses the first row and discards the rest.  If no row matches
+// the query, Scan returns ErrNoRows.
+func (r *Row) Scan(dest ...interface{}) error {
+	if r.err != nil {
+		return r.err
+	}
+
+	// TODO(bradfitz): for now we need to defensively clone all
+	// []byte that the driver returned (not permitting
+	// *RawBytes in Rows.Scan), since we're about to close
+	// the Rows in our defer, when we return from this function.
+	// the contract with the driver.Next(...) interface is that it
+	// can return slices into read-only temporary memory that's
+	// only valid until the next Scan/Close.  But the TODO is that
+	// for a lot of drivers, this copy will be unnecessary.  We
+	// should provide an optional interface for drivers to
+	// implement to say, "don't worry, the []bytes that I return
+	// from Next will not be modified again." (for instance, if
+	// they were obtained from the network anyway) But for now we
+	// don't care.
+	defer r.rows.Close()
+	for _, dp := range dest {
+		if _, ok := dp.(*RawBytes); ok {
+			return errors.New("sql: RawBytes isn't allowed on Row.Scan")
+		}
+	}
+
+	if !r.rows.Next() {
+		if err := r.rows.Err(); err != nil {
+			return err
+		}
+		return ErrNoRows
+	}
+	err := r.rows.Scan(dest...)
+	if err != nil {
+		return err
+	}
+	// Make sure the query can be processed to completion with no errors.
+	if err := r.rows.Close(); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+// A Result summarizes an executed SQL command.
+type Result interface {
+	// LastInsertId returns the integer generated by the database
+	// in response to a command. Typically this will be from an
+	// "auto increment" column when inserting a new row. Not all
+	// databases support this feature, and the syntax of such
+	// statements varies.
+	LastInsertId() (int64, error)
+
+	// RowsAffected returns the number of rows affected by an
+	// update, insert, or delete. Not every database or database
+	// driver may support this.
+	RowsAffected() (int64, error)
+}
+
+type driverResult struct {
+	sync.Locker // the *driverConn
+	resi        driver.Result
+}
+
+func (dr driverResult) LastInsertId() (int64, error) {
+	dr.Lock()
+	defer dr.Unlock()
+	return dr.resi.LastInsertId()
+}
+
+func (dr driverResult) RowsAffected() (int64, error) {
+	dr.Lock()
+	defer dr.Unlock()
+	return dr.resi.RowsAffected()
+}
+
+func stack() string {
+	var buf [2 << 10]byte
+	return string(buf[:runtime.Stack(buf[:], false)])
+}
+
+// withLock runs while holding lk.
+func withLock(lk sync.Locker, fn func()) {
+	lk.Lock()
+	fn()
+	lk.Unlock()
+}
diff --git a/src/database/sql/sql_test.go b/src/database/sql/sql_test.go
new file mode 100644
index 0000000..34efdf2
--- /dev/null
+++ b/src/database/sql/sql_test.go
@@ -0,0 +1,1987 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package sql
+
+import (
+	"database/sql/driver"
+	"errors"
+	"fmt"
+	"math/rand"
+	"reflect"
+	"runtime"
+	"strings"
+	"sync"
+	"testing"
+	"time"
+)
+
+func init() {
+	type dbConn struct {
+		db *DB
+		c  *driverConn
+	}
+	freedFrom := make(map[dbConn]string)
+	putConnHook = func(db *DB, c *driverConn) {
+		idx := -1
+		for i, v := range db.freeConn {
+			if v == c {
+				idx = i
+				break
+			}
+		}
+		if idx >= 0 {
+			// print before panic, as panic may get lost due to conflicting panic
+			// (all goroutines asleep) elsewhere, since we might not unlock
+			// the mutex in freeConn here.
+			println("double free of conn. conflicts are:\nA) " + freedFrom[dbConn{db, c}] + "\n\nand\nB) " + stack())
+			panic("double free of conn.")
+		}
+		freedFrom[dbConn{db, c}] = stack()
+	}
+}
+
+const fakeDBName = "foo"
+
+var chrisBirthday = time.Unix(123456789, 0)
+
+func newTestDB(t testing.TB, name string) *DB {
+	db, err := Open("test", fakeDBName)
+	if err != nil {
+		t.Fatalf("Open: %v", err)
+	}
+	if _, err := db.Exec("WIPE"); err != nil {
+		t.Fatalf("exec wipe: %v", err)
+	}
+	if name == "people" {
+		exec(t, db, "CREATE|people|name=string,age=int32,photo=blob,dead=bool,bdate=datetime")
+		exec(t, db, "INSERT|people|name=Alice,age=?,photo=APHOTO", 1)
+		exec(t, db, "INSERT|people|name=Bob,age=?,photo=BPHOTO", 2)
+		exec(t, db, "INSERT|people|name=Chris,age=?,photo=CPHOTO,bdate=?", 3, chrisBirthday)
+	}
+	if name == "magicquery" {
+		// Magic table name and column, known by fakedb_test.go.
+		exec(t, db, "CREATE|magicquery|op=string,millis=int32")
+		exec(t, db, "INSERT|magicquery|op=sleep,millis=10")
+	}
+	return db
+}
+
+func exec(t testing.TB, db *DB, query string, args ...interface{}) {
+	_, err := db.Exec(query, args...)
+	if err != nil {
+		t.Fatalf("Exec of %q: %v", query, err)
+	}
+}
+
+func closeDB(t testing.TB, db *DB) {
+	if e := recover(); e != nil {
+		fmt.Printf("Panic: %v\n", e)
+		panic(e)
+	}
+	defer setHookpostCloseConn(nil)
+	setHookpostCloseConn(func(_ *fakeConn, err error) {
+		if err != nil {
+			t.Errorf("Error closing fakeConn: %v", err)
+		}
+	})
+	for i, dc := range db.freeConn {
+		if n := len(dc.openStmt); n > 0 {
+			// Just a sanity check. This is legal in
+			// general, but if we make the tests clean up
+			// their statements first, then we can safely
+			// verify this is always zero here, and any
+			// other value is a leak.
+			t.Errorf("while closing db, freeConn %d/%d had %d open stmts; want 0", i, len(db.freeConn), n)
+		}
+	}
+	err := db.Close()
+	if err != nil {
+		t.Fatalf("error closing DB: %v", err)
+	}
+	db.mu.Lock()
+	count := db.numOpen
+	db.mu.Unlock()
+	if count != 0 {
+		t.Fatalf("%d connections still open after closing DB", db.numOpen)
+	}
+}
+
+// numPrepares assumes that db has exactly 1 idle conn and returns
+// its count of calls to Prepare
+func numPrepares(t *testing.T, db *DB) int {
+	if n := len(db.freeConn); n != 1 {
+		t.Fatalf("free conns = %d; want 1", n)
+	}
+	return db.freeConn[0].ci.(*fakeConn).numPrepare
+}
+
+func (db *DB) numDeps() int {
+	db.mu.Lock()
+	defer db.mu.Unlock()
+	return len(db.dep)
+}
+
+// Dependencies are closed via a goroutine, so this polls waiting for
+// numDeps to fall to want, waiting up to d.
+func (db *DB) numDepsPollUntil(want int, d time.Duration) int {
+	deadline := time.Now().Add(d)
+	for {
+		n := db.numDeps()
+		if n <= want || time.Now().After(deadline) {
+			return n
+		}
+		time.Sleep(50 * time.Millisecond)
+	}
+}
+
+func (db *DB) numFreeConns() int {
+	db.mu.Lock()
+	defer db.mu.Unlock()
+	return len(db.freeConn)
+}
+
+func (db *DB) dumpDeps(t *testing.T) {
+	for fc := range db.dep {
+		db.dumpDep(t, 0, fc, map[finalCloser]bool{})
+	}
+}
+
+func (db *DB) dumpDep(t *testing.T, depth int, dep finalCloser, seen map[finalCloser]bool) {
+	seen[dep] = true
+	indent := strings.Repeat("  ", depth)
+	ds := db.dep[dep]
+	for k := range ds {
+		t.Logf("%s%T (%p) waiting for -> %T (%p)", indent, dep, dep, k, k)
+		if fc, ok := k.(finalCloser); ok {
+			if !seen[fc] {
+				db.dumpDep(t, depth+1, fc, seen)
+			}
+		}
+	}
+}
+
+func TestQuery(t *testing.T) {
+	db := newTestDB(t, "people")
+	defer closeDB(t, db)
+	prepares0 := numPrepares(t, db)
+	rows, err := db.Query("SELECT|people|age,name|")
+	if err != nil {
+		t.Fatalf("Query: %v", err)
+	}
+	type row struct {
+		age  int
+		name string
+	}
+	got := []row{}
+	for rows.Next() {
+		var r row
+		err = rows.Scan(&r.age, &r.name)
+		if err != nil {
+			t.Fatalf("Scan: %v", err)
+		}
+		got = append(got, r)
+	}
+	err = rows.Err()
+	if err != nil {
+		t.Fatalf("Err: %v", err)
+	}
+	want := []row{
+		{age: 1, name: "Alice"},
+		{age: 2, name: "Bob"},
+		{age: 3, name: "Chris"},
+	}
+	if !reflect.DeepEqual(got, want) {
+		t.Errorf("mismatch.\n got: %#v\nwant: %#v", got, want)
+	}
+
+	// And verify that the final rows.Next() call, which hit EOF,
+	// also closed the rows connection.
+	if n := db.numFreeConns(); n != 1 {
+		t.Fatalf("free conns after query hitting EOF = %d; want 1", n)
+	}
+	if prepares := numPrepares(t, db) - prepares0; prepares != 1 {
+		t.Errorf("executed %d Prepare statements; want 1", prepares)
+	}
+}
+
+func TestByteOwnership(t *testing.T) {
+	db := newTestDB(t, "people")
+	defer closeDB(t, db)
+	rows, err := db.Query("SELECT|people|name,photo|")
+	if err != nil {
+		t.Fatalf("Query: %v", err)
+	}
+	type row struct {
+		name  []byte
+		photo RawBytes
+	}
+	got := []row{}
+	for rows.Next() {
+		var r row
+		err = rows.Scan(&r.name, &r.photo)
+		if err != nil {
+			t.Fatalf("Scan: %v", err)
+		}
+		got = append(got, r)
+	}
+	corruptMemory := []byte("\xffPHOTO")
+	want := []row{
+		{name: []byte("Alice"), photo: corruptMemory},
+		{name: []byte("Bob"), photo: corruptMemory},
+		{name: []byte("Chris"), photo: corruptMemory},
+	}
+	if !reflect.DeepEqual(got, want) {
+		t.Errorf("mismatch.\n got: %#v\nwant: %#v", got, want)
+	}
+
+	var photo RawBytes
+	err = db.QueryRow("SELECT|people|photo|name=?", "Alice").Scan(&photo)
+	if err == nil {
+		t.Error("want error scanning into RawBytes from QueryRow")
+	}
+}
+
+func TestRowsColumns(t *testing.T) {
+	db := newTestDB(t, "people")
+	defer closeDB(t, db)
+	rows, err := db.Query("SELECT|people|age,name|")
+	if err != nil {
+		t.Fatalf("Query: %v", err)
+	}
+	cols, err := rows.Columns()
+	if err != nil {
+		t.Fatalf("Columns: %v", err)
+	}
+	want := []string{"age", "name"}
+	if !reflect.DeepEqual(cols, want) {
+		t.Errorf("got %#v; want %#v", cols, want)
+	}
+	if err := rows.Close(); err != nil {
+		t.Errorf("error closing rows: %s", err)
+	}
+}
+
+func TestQueryRow(t *testing.T) {
+	db := newTestDB(t, "people")
+	defer closeDB(t, db)
+	var name string
+	var age int
+	var birthday time.Time
+
+	err := db.QueryRow("SELECT|people|age,name|age=?", 3).Scan(&age)
+	if err == nil || !strings.Contains(err.Error(), "expected 2 destination arguments") {
+		t.Errorf("expected error from wrong number of arguments; actually got: %v", err)
+	}
+
+	err = db.QueryRow("SELECT|people|bdate|age=?", 3).Scan(&birthday)
+	if err != nil || !birthday.Equal(chrisBirthday) {
+		t.Errorf("chris birthday = %v, err = %v; want %v", birthday, err, chrisBirthday)
+	}
+
+	err = db.QueryRow("SELECT|people|age,name|age=?", 2).Scan(&age, &name)
+	if err != nil {
+		t.Fatalf("age QueryRow+Scan: %v", err)
+	}
+	if name != "Bob" {
+		t.Errorf("expected name Bob, got %q", name)
+	}
+	if age != 2 {
+		t.Errorf("expected age 2, got %d", age)
+	}
+
+	err = db.QueryRow("SELECT|people|age,name|name=?", "Alice").Scan(&age, &name)
+	if err != nil {
+		t.Fatalf("name QueryRow+Scan: %v", err)
+	}
+	if name != "Alice" {
+		t.Errorf("expected name Alice, got %q", name)
+	}
+	if age != 1 {
+		t.Errorf("expected age 1, got %d", age)
+	}
+
+	var photo []byte
+	err = db.QueryRow("SELECT|people|photo|name=?", "Alice").Scan(&photo)
+	if err != nil {
+		t.Fatalf("photo QueryRow+Scan: %v", err)
+	}
+	want := []byte("APHOTO")
+	if !reflect.DeepEqual(photo, want) {
+		t.Errorf("photo = %q; want %q", photo, want)
+	}
+}
+
+func TestStatementErrorAfterClose(t *testing.T) {
+	db := newTestDB(t, "people")
+	defer closeDB(t, db)
+	stmt, err := db.Prepare("SELECT|people|age|name=?")
+	if err != nil {
+		t.Fatalf("Prepare: %v", err)
+	}
+	err = stmt.Close()
+	if err != nil {
+		t.Fatalf("Close: %v", err)
+	}
+	var name string
+	err = stmt.QueryRow("foo").Scan(&name)
+	if err == nil {
+		t.Errorf("expected error from QueryRow.Scan after Stmt.Close")
+	}
+}
+
+func TestStatementQueryRow(t *testing.T) {
+	db := newTestDB(t, "people")
+	defer closeDB(t, db)
+	stmt, err := db.Prepare("SELECT|people|age|name=?")
+	if err != nil {
+		t.Fatalf("Prepare: %v", err)
+	}
+	defer stmt.Close()
+	var age int
+	for n, tt := range []struct {
+		name string
+		want int
+	}{
+		{"Alice", 1},
+		{"Bob", 2},
+		{"Chris", 3},
+	} {
+		if err := stmt.QueryRow(tt.name).Scan(&age); err != nil {
+			t.Errorf("%d: on %q, QueryRow/Scan: %v", n, tt.name, err)
+		} else if age != tt.want {
+			t.Errorf("%d: age=%d, want %d", n, age, tt.want)
+		}
+	}
+}
+
+// golang.org/issue/3734
+func TestStatementQueryRowConcurrent(t *testing.T) {
+	db := newTestDB(t, "people")
+	defer closeDB(t, db)
+	stmt, err := db.Prepare("SELECT|people|age|name=?")
+	if err != nil {
+		t.Fatalf("Prepare: %v", err)
+	}
+	defer stmt.Close()
+
+	const n = 10
+	ch := make(chan error, n)
+	for i := 0; i < n; i++ {
+		go func() {
+			var age int
+			err := stmt.QueryRow("Alice").Scan(&age)
+			if err == nil && age != 1 {
+				err = fmt.Errorf("unexpected age %d", age)
+			}
+			ch <- err
+		}()
+	}
+	for i := 0; i < n; i++ {
+		if err := <-ch; err != nil {
+			t.Error(err)
+		}
+	}
+}
+
+// just a test of fakedb itself
+func TestBogusPreboundParameters(t *testing.T) {
+	db := newTestDB(t, "foo")
+	defer closeDB(t, db)
+	exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool")
+	_, err := db.Prepare("INSERT|t1|name=?,age=bogusconversion")
+	if err == nil {
+		t.Fatalf("expected error")
+	}
+	if err.Error() != `fakedb: invalid conversion to int32 from "bogusconversion"` {
+		t.Errorf("unexpected error: %v", err)
+	}
+}
+
+func TestExec(t *testing.T) {
+	db := newTestDB(t, "foo")
+	defer closeDB(t, db)
+	exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool")
+	stmt, err := db.Prepare("INSERT|t1|name=?,age=?")
+	if err != nil {
+		t.Errorf("Stmt, err = %v, %v", stmt, err)
+	}
+	defer stmt.Close()
+
+	type execTest struct {
+		args    []interface{}
+		wantErr string
+	}
+	execTests := []execTest{
+		// Okay:
+		{[]interface{}{"Brad", 31}, ""},
+		{[]interface{}{"Brad", int64(31)}, ""},
+		{[]interface{}{"Bob", "32"}, ""},
+		{[]interface{}{7, 9}, ""},
+
+		// Invalid conversions:
+		{[]interface{}{"Brad", int64(0xFFFFFFFF)}, "sql: converting argument #1's type: sql/driver: value 4294967295 overflows int32"},
+		{[]interface{}{"Brad", "strconv fail"}, "sql: converting argument #1's type: sql/driver: value \"strconv fail\" can't be converted to int32"},
+
+		// Wrong number of args:
+		{[]interface{}{}, "sql: expected 2 arguments, got 0"},
+		{[]interface{}{1, 2, 3}, "sql: expected 2 arguments, got 3"},
+	}
+	for n, et := range execTests {
+		_, err := stmt.Exec(et.args...)
+		errStr := ""
+		if err != nil {
+			errStr = err.Error()
+		}
+		if errStr != et.wantErr {
+			t.Errorf("stmt.Execute #%d: for %v, got error %q, want error %q",
+				n, et.args, errStr, et.wantErr)
+		}
+	}
+}
+
+func TestTxPrepare(t *testing.T) {
+	db := newTestDB(t, "")
+	defer closeDB(t, db)
+	exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool")
+	tx, err := db.Begin()
+	if err != nil {
+		t.Fatalf("Begin = %v", err)
+	}
+	stmt, err := tx.Prepare("INSERT|t1|name=?,age=?")
+	if err != nil {
+		t.Fatalf("Stmt, err = %v, %v", stmt, err)
+	}
+	defer stmt.Close()
+	_, err = stmt.Exec("Bobby", 7)
+	if err != nil {
+		t.Fatalf("Exec = %v", err)
+	}
+	err = tx.Commit()
+	if err != nil {
+		t.Fatalf("Commit = %v", err)
+	}
+	// Commit() should have closed the statement
+	if !stmt.closed {
+		t.Fatal("Stmt not closed after Commit")
+	}
+}
+
+func TestTxStmt(t *testing.T) {
+	db := newTestDB(t, "")
+	defer closeDB(t, db)
+	exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool")
+	stmt, err := db.Prepare("INSERT|t1|name=?,age=?")
+	if err != nil {
+		t.Fatalf("Stmt, err = %v, %v", stmt, err)
+	}
+	defer stmt.Close()
+	tx, err := db.Begin()
+	if err != nil {
+		t.Fatalf("Begin = %v", err)
+	}
+	txs := tx.Stmt(stmt)
+	defer txs.Close()
+	_, err = txs.Exec("Bobby", 7)
+	if err != nil {
+		t.Fatalf("Exec = %v", err)
+	}
+	err = tx.Commit()
+	if err != nil {
+		t.Fatalf("Commit = %v", err)
+	}
+	// Commit() should have closed the statement
+	if !txs.closed {
+		t.Fatal("Stmt not closed after Commit")
+	}
+}
+
+// Issue: http://golang.org/issue/2784
+// This test didn't fail before because we got lucky with the fakedb driver.
+// It was failing, and now not, in github.com/bradfitz/go-sql-test
+func TestTxQuery(t *testing.T) {
+	db := newTestDB(t, "")
+	defer closeDB(t, db)
+	exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool")
+	exec(t, db, "INSERT|t1|name=Alice")
+
+	tx, err := db.Begin()
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer tx.Rollback()
+
+	r, err := tx.Query("SELECT|t1|name|")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer r.Close()
+
+	if !r.Next() {
+		if r.Err() != nil {
+			t.Fatal(r.Err())
+		}
+		t.Fatal("expected one row")
+	}
+
+	var x string
+	err = r.Scan(&x)
+	if err != nil {
+		t.Fatal(err)
+	}
+}
+
+func TestTxQueryInvalid(t *testing.T) {
+	db := newTestDB(t, "")
+	defer closeDB(t, db)
+
+	tx, err := db.Begin()
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer tx.Rollback()
+
+	_, err = tx.Query("SELECT|t1|name|")
+	if err == nil {
+		t.Fatal("Error expected")
+	}
+}
+
+// Tests fix for issue 4433, that retries in Begin happen when
+// conn.Begin() returns ErrBadConn
+func TestTxErrBadConn(t *testing.T) {
+	db, err := Open("test", fakeDBName+";badConn")
+	if err != nil {
+		t.Fatalf("Open: %v", err)
+	}
+	if _, err := db.Exec("WIPE"); err != nil {
+		t.Fatalf("exec wipe: %v", err)
+	}
+	defer closeDB(t, db)
+	exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool")
+	stmt, err := db.Prepare("INSERT|t1|name=?,age=?")
+	if err != nil {
+		t.Fatalf("Stmt, err = %v, %v", stmt, err)
+	}
+	defer stmt.Close()
+	tx, err := db.Begin()
+	if err != nil {
+		t.Fatalf("Begin = %v", err)
+	}
+	txs := tx.Stmt(stmt)
+	defer txs.Close()
+	_, err = txs.Exec("Bobby", 7)
+	if err != nil {
+		t.Fatalf("Exec = %v", err)
+	}
+	err = tx.Commit()
+	if err != nil {
+		t.Fatalf("Commit = %v", err)
+	}
+}
+
+// Tests fix for issue 2542, that we release a lock when querying on
+// a closed connection.
+func TestIssue2542Deadlock(t *testing.T) {
+	db := newTestDB(t, "people")
+	closeDB(t, db)
+	for i := 0; i < 2; i++ {
+		_, err := db.Query("SELECT|people|age,name|")
+		if err == nil {
+			t.Fatalf("expected error")
+		}
+	}
+}
+
+// From golang.org/issue/3865
+func TestCloseStmtBeforeRows(t *testing.T) {
+	db := newTestDB(t, "people")
+	defer closeDB(t, db)
+
+	s, err := db.Prepare("SELECT|people|name|")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	r, err := s.Query()
+	if err != nil {
+		s.Close()
+		t.Fatal(err)
+	}
+
+	err = s.Close()
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	r.Close()
+}
+
+// Tests fix for issue 2788, that we bind nil to a []byte if the
+// value in the column is sql null
+func TestNullByteSlice(t *testing.T) {
+	db := newTestDB(t, "")
+	defer closeDB(t, db)
+	exec(t, db, "CREATE|t|id=int32,name=nullstring")
+	exec(t, db, "INSERT|t|id=10,name=?", nil)
+
+	var name []byte
+
+	err := db.QueryRow("SELECT|t|name|id=?", 10).Scan(&name)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if name != nil {
+		t.Fatalf("name []byte should be nil for null column value, got: %#v", name)
+	}
+
+	exec(t, db, "INSERT|t|id=11,name=?", "bob")
+	err = db.QueryRow("SELECT|t|name|id=?", 11).Scan(&name)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if string(name) != "bob" {
+		t.Fatalf("name []byte should be bob, got: %q", string(name))
+	}
+}
+
+func TestPointerParamsAndScans(t *testing.T) {
+	db := newTestDB(t, "")
+	defer closeDB(t, db)
+	exec(t, db, "CREATE|t|id=int32,name=nullstring")
+
+	bob := "bob"
+	var name *string
+
+	name = &bob
+	exec(t, db, "INSERT|t|id=10,name=?", name)
+	name = nil
+	exec(t, db, "INSERT|t|id=20,name=?", name)
+
+	err := db.QueryRow("SELECT|t|name|id=?", 10).Scan(&name)
+	if err != nil {
+		t.Fatalf("querying id 10: %v", err)
+	}
+	if name == nil {
+		t.Errorf("id 10's name = nil; want bob")
+	} else if *name != "bob" {
+		t.Errorf("id 10's name = %q; want bob", *name)
+	}
+
+	err = db.QueryRow("SELECT|t|name|id=?", 20).Scan(&name)
+	if err != nil {
+		t.Fatalf("querying id 20: %v", err)
+	}
+	if name != nil {
+		t.Errorf("id 20 = %q; want nil", *name)
+	}
+}
+
+func TestQueryRowClosingStmt(t *testing.T) {
+	db := newTestDB(t, "people")
+	defer closeDB(t, db)
+	var name string
+	var age int
+	err := db.QueryRow("SELECT|people|age,name|age=?", 3).Scan(&age, &name)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if len(db.freeConn) != 1 {
+		t.Fatalf("expected 1 free conn")
+	}
+	fakeConn := db.freeConn[0].ci.(*fakeConn)
+	if made, closed := fakeConn.stmtsMade, fakeConn.stmtsClosed; made != closed {
+		t.Errorf("statement close mismatch: made %d, closed %d", made, closed)
+	}
+}
+
+// Test issue 6651
+func TestIssue6651(t *testing.T) {
+	db := newTestDB(t, "people")
+	defer closeDB(t, db)
+
+	var v string
+
+	want := "error in rows.Next"
+	rowsCursorNextHook = func(dest []driver.Value) error {
+		return fmt.Errorf(want)
+	}
+	defer func() { rowsCursorNextHook = nil }()
+	err := db.QueryRow("SELECT|people|name|").Scan(&v)
+	if err == nil || err.Error() != want {
+		t.Errorf("error = %q; want %q", err, want)
+	}
+	rowsCursorNextHook = nil
+
+	want = "error in rows.Close"
+	rowsCloseHook = func(rows *Rows, err *error) {
+		*err = fmt.Errorf(want)
+	}
+	defer func() { rowsCloseHook = nil }()
+	err = db.QueryRow("SELECT|people|name|").Scan(&v)
+	if err == nil || err.Error() != want {
+		t.Errorf("error = %q; want %q", err, want)
+	}
+}
+
+type nullTestRow struct {
+	nullParam    interface{}
+	notNullParam interface{}
+	scanNullVal  interface{}
+}
+
+type nullTestSpec struct {
+	nullType    string
+	notNullType string
+	rows        [6]nullTestRow
+}
+
+func TestNullStringParam(t *testing.T) {
+	spec := nullTestSpec{"nullstring", "string", [6]nullTestRow{
+		{NullString{"aqua", true}, "", NullString{"aqua", true}},
+		{NullString{"brown", false}, "", NullString{"", false}},
+		{"chartreuse", "", NullString{"chartreuse", true}},
+		{NullString{"darkred", true}, "", NullString{"darkred", true}},
+		{NullString{"eel", false}, "", NullString{"", false}},
+		{"foo", NullString{"black", false}, nil},
+	}}
+	nullTestRun(t, spec)
+}
+
+func TestNullInt64Param(t *testing.T) {
+	spec := nullTestSpec{"nullint64", "int64", [6]nullTestRow{
+		{NullInt64{31, true}, 1, NullInt64{31, true}},
+		{NullInt64{-22, false}, 1, NullInt64{0, false}},
+		{22, 1, NullInt64{22, true}},
+		{NullInt64{33, true}, 1, NullInt64{33, true}},
+		{NullInt64{222, false}, 1, NullInt64{0, false}},
+		{0, NullInt64{31, false}, nil},
+	}}
+	nullTestRun(t, spec)
+}
+
+func TestNullFloat64Param(t *testing.T) {
+	spec := nullTestSpec{"nullfloat64", "float64", [6]nullTestRow{
+		{NullFloat64{31.2, true}, 1, NullFloat64{31.2, true}},
+		{NullFloat64{13.1, false}, 1, NullFloat64{0, false}},
+		{-22.9, 1, NullFloat64{-22.9, true}},
+		{NullFloat64{33.81, true}, 1, NullFloat64{33.81, true}},
+		{NullFloat64{222, false}, 1, NullFloat64{0, false}},
+		{10, NullFloat64{31.2, false}, nil},
+	}}
+	nullTestRun(t, spec)
+}
+
+func TestNullBoolParam(t *testing.T) {
+	spec := nullTestSpec{"nullbool", "bool", [6]nullTestRow{
+		{NullBool{false, true}, true, NullBool{false, true}},
+		{NullBool{true, false}, false, NullBool{false, false}},
+		{true, true, NullBool{true, true}},
+		{NullBool{true, true}, false, NullBool{true, true}},
+		{NullBool{true, false}, true, NullBool{false, false}},
+		{true, NullBool{true, false}, nil},
+	}}
+	nullTestRun(t, spec)
+}
+
+func nullTestRun(t *testing.T, spec nullTestSpec) {
+	db := newTestDB(t, "")
+	defer closeDB(t, db)
+	exec(t, db, fmt.Sprintf("CREATE|t|id=int32,name=string,nullf=%s,notnullf=%s", spec.nullType, spec.notNullType))
+
+	// Inserts with db.Exec:
+	exec(t, db, "INSERT|t|id=?,name=?,nullf=?,notnullf=?", 1, "alice", spec.rows[0].nullParam, spec.rows[0].notNullParam)
+	exec(t, db, "INSERT|t|id=?,name=?,nullf=?,notnullf=?", 2, "bob", spec.rows[1].nullParam, spec.rows[1].notNullParam)
+
+	// Inserts with a prepared statement:
+	stmt, err := db.Prepare("INSERT|t|id=?,name=?,nullf=?,notnullf=?")
+	if err != nil {
+		t.Fatalf("prepare: %v", err)
+	}
+	defer stmt.Close()
+	if _, err := stmt.Exec(3, "chris", spec.rows[2].nullParam, spec.rows[2].notNullParam); err != nil {
+		t.Errorf("exec insert chris: %v", err)
+	}
+	if _, err := stmt.Exec(4, "dave", spec.rows[3].nullParam, spec.rows[3].notNullParam); err != nil {
+		t.Errorf("exec insert dave: %v", err)
+	}
+	if _, err := stmt.Exec(5, "eleanor", spec.rows[4].nullParam, spec.rows[4].notNullParam); err != nil {
+		t.Errorf("exec insert eleanor: %v", err)
+	}
+
+	// Can't put null val into non-null col
+	if _, err := stmt.Exec(6, "bob", spec.rows[5].nullParam, spec.rows[5].notNullParam); err == nil {
+		t.Errorf("expected error inserting nil val with prepared statement Exec")
+	}
+
+	_, err = db.Exec("INSERT|t|id=?,name=?,nullf=?", 999, nil, nil)
+	if err == nil {
+		// TODO: this test fails, but it's just because
+		// fakeConn implements the optional Execer interface,
+		// so arguably this is the correct behavior.  But
+		// maybe I should flesh out the fakeConn.Exec
+		// implementation so this properly fails.
+		// t.Errorf("expected error inserting nil name with Exec")
+	}
+
+	paramtype := reflect.TypeOf(spec.rows[0].nullParam)
+	bindVal := reflect.New(paramtype).Interface()
+
+	for i := 0; i < 5; i++ {
+		id := i + 1
+		if err := db.QueryRow("SELECT|t|nullf|id=?", id).Scan(bindVal); err != nil {
+			t.Errorf("id=%d Scan: %v", id, err)
+		}
+		bindValDeref := reflect.ValueOf(bindVal).Elem().Interface()
+		if !reflect.DeepEqual(bindValDeref, spec.rows[i].scanNullVal) {
+			t.Errorf("id=%d got %#v, want %#v", id, bindValDeref, spec.rows[i].scanNullVal)
+		}
+	}
+}
+
+// golang.org/issue/4859
+func TestQueryRowNilScanDest(t *testing.T) {
+	db := newTestDB(t, "people")
+	defer closeDB(t, db)
+	var name *string // nil pointer
+	err := db.QueryRow("SELECT|people|name|").Scan(name)
+	want := "sql: Scan error on column index 0: destination pointer is nil"
+	if err == nil || err.Error() != want {
+		t.Errorf("error = %q; want %q", err.Error(), want)
+	}
+}
+
+func TestIssue4902(t *testing.T) {
+	db := newTestDB(t, "people")
+	defer closeDB(t, db)
+
+	driver := db.driver.(*fakeDriver)
+	opens0 := driver.openCount
+
+	var stmt *Stmt
+	var err error
+	for i := 0; i < 10; i++ {
+		stmt, err = db.Prepare("SELECT|people|name|")
+		if err != nil {
+			t.Fatal(err)
+		}
+		err = stmt.Close()
+		if err != nil {
+			t.Fatal(err)
+		}
+	}
+
+	opens := driver.openCount - opens0
+	if opens > 1 {
+		t.Errorf("opens = %d; want <= 1", opens)
+		t.Logf("db = %#v", db)
+		t.Logf("driver = %#v", driver)
+		t.Logf("stmt = %#v", stmt)
+	}
+}
+
+// Issue 3857
+// This used to deadlock.
+func TestSimultaneousQueries(t *testing.T) {
+	db := newTestDB(t, "people")
+	defer closeDB(t, db)
+
+	tx, err := db.Begin()
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer tx.Rollback()
+
+	r1, err := tx.Query("SELECT|people|name|")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer r1.Close()
+
+	r2, err := tx.Query("SELECT|people|name|")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer r2.Close()
+}
+
+func TestMaxIdleConns(t *testing.T) {
+	db := newTestDB(t, "people")
+	defer closeDB(t, db)
+
+	tx, err := db.Begin()
+	if err != nil {
+		t.Fatal(err)
+	}
+	tx.Commit()
+	if got := len(db.freeConn); got != 1 {
+		t.Errorf("freeConns = %d; want 1", got)
+	}
+
+	db.SetMaxIdleConns(0)
+
+	if got := len(db.freeConn); got != 0 {
+		t.Errorf("freeConns after set to zero = %d; want 0", got)
+	}
+
+	tx, err = db.Begin()
+	if err != nil {
+		t.Fatal(err)
+	}
+	tx.Commit()
+	if got := len(db.freeConn); got != 0 {
+		t.Errorf("freeConns = %d; want 0", got)
+	}
+}
+
+func TestMaxOpenConns(t *testing.T) {
+	if testing.Short() {
+		t.Skip("skipping in short mode")
+	}
+	defer setHookpostCloseConn(nil)
+	setHookpostCloseConn(func(_ *fakeConn, err error) {
+		if err != nil {
+			t.Errorf("Error closing fakeConn: %v", err)
+		}
+	})
+
+	db := newTestDB(t, "magicquery")
+	defer closeDB(t, db)
+
+	driver := db.driver.(*fakeDriver)
+
+	// Force the number of open connections to 0 so we can get an accurate
+	// count for the test
+	db.SetMaxIdleConns(0)
+
+	if g, w := db.numFreeConns(), 0; g != w {
+		t.Errorf("free conns = %d; want %d", g, w)
+	}
+
+	if n := db.numDepsPollUntil(0, time.Second); n > 0 {
+		t.Errorf("number of dependencies = %d; expected 0", n)
+		db.dumpDeps(t)
+	}
+
+	driver.mu.Lock()
+	opens0 := driver.openCount
+	closes0 := driver.closeCount
+	driver.mu.Unlock()
+
+	db.SetMaxIdleConns(10)
+	db.SetMaxOpenConns(10)
+
+	stmt, err := db.Prepare("SELECT|magicquery|op|op=?,millis=?")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	// Start 50 parallel slow queries.
+	const (
+		nquery      = 50
+		sleepMillis = 25
+		nbatch      = 2
+	)
+	var wg sync.WaitGroup
+	for batch := 0; batch < nbatch; batch++ {
+		for i := 0; i < nquery; i++ {
+			wg.Add(1)
+			go func() {
+				defer wg.Done()
+				var op string
+				if err := stmt.QueryRow("sleep", sleepMillis).Scan(&op); err != nil && err != ErrNoRows {
+					t.Error(err)
+				}
+			}()
+		}
+		// Sleep for twice the expected length of time for the
+		// batch of 50 queries above to finish before starting
+		// the next round.
+		time.Sleep(2 * sleepMillis * time.Millisecond)
+	}
+	wg.Wait()
+
+	if g, w := db.numFreeConns(), 10; g != w {
+		t.Errorf("free conns = %d; want %d", g, w)
+	}
+
+	if n := db.numDepsPollUntil(20, time.Second); n > 20 {
+		t.Errorf("number of dependencies = %d; expected <= 20", n)
+		db.dumpDeps(t)
+	}
+
+	driver.mu.Lock()
+	opens := driver.openCount - opens0
+	closes := driver.closeCount - closes0
+	driver.mu.Unlock()
+
+	if opens > 10 {
+		t.Logf("open calls = %d", opens)
+		t.Logf("close calls = %d", closes)
+		t.Errorf("db connections opened = %d; want <= 10", opens)
+		db.dumpDeps(t)
+	}
+
+	if err := stmt.Close(); err != nil {
+		t.Fatal(err)
+	}
+
+	if g, w := db.numFreeConns(), 10; g != w {
+		t.Errorf("free conns = %d; want %d", g, w)
+	}
+
+	if n := db.numDepsPollUntil(10, time.Second); n > 10 {
+		t.Errorf("number of dependencies = %d; expected <= 10", n)
+		db.dumpDeps(t)
+	}
+
+	db.SetMaxOpenConns(5)
+
+	if g, w := db.numFreeConns(), 5; g != w {
+		t.Errorf("free conns = %d; want %d", g, w)
+	}
+
+	if n := db.numDepsPollUntil(5, time.Second); n > 5 {
+		t.Errorf("number of dependencies = %d; expected 0", n)
+		db.dumpDeps(t)
+	}
+
+	db.SetMaxOpenConns(0)
+
+	if g, w := db.numFreeConns(), 5; g != w {
+		t.Errorf("free conns = %d; want %d", g, w)
+	}
+
+	if n := db.numDepsPollUntil(5, time.Second); n > 5 {
+		t.Errorf("number of dependencies = %d; expected 0", n)
+		db.dumpDeps(t)
+	}
+
+	db.SetMaxIdleConns(0)
+
+	if g, w := db.numFreeConns(), 0; g != w {
+		t.Errorf("free conns = %d; want %d", g, w)
+	}
+
+	if n := db.numDepsPollUntil(0, time.Second); n > 0 {
+		t.Errorf("number of dependencies = %d; expected 0", n)
+		db.dumpDeps(t)
+	}
+}
+
+func TestSingleOpenConn(t *testing.T) {
+	db := newTestDB(t, "people")
+	defer closeDB(t, db)
+
+	db.SetMaxOpenConns(1)
+
+	rows, err := db.Query("SELECT|people|name|")
+	if err != nil {
+		t.Fatal(err)
+	}
+	if err = rows.Close(); err != nil {
+		t.Fatal(err)
+	}
+	// shouldn't deadlock
+	rows, err = db.Query("SELECT|people|name|")
+	if err != nil {
+		t.Fatal(err)
+	}
+	if err = rows.Close(); err != nil {
+		t.Fatal(err)
+	}
+}
+
+// golang.org/issue/5323
+func TestStmtCloseDeps(t *testing.T) {
+	if testing.Short() {
+		t.Skip("skipping in short mode")
+	}
+	defer setHookpostCloseConn(nil)
+	setHookpostCloseConn(func(_ *fakeConn, err error) {
+		if err != nil {
+			t.Errorf("Error closing fakeConn: %v", err)
+		}
+	})
+
+	db := newTestDB(t, "magicquery")
+	defer closeDB(t, db)
+
+	driver := db.driver.(*fakeDriver)
+
+	driver.mu.Lock()
+	opens0 := driver.openCount
+	closes0 := driver.closeCount
+	driver.mu.Unlock()
+	openDelta0 := opens0 - closes0
+
+	stmt, err := db.Prepare("SELECT|magicquery|op|op=?,millis=?")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	// Start 50 parallel slow queries.
+	const (
+		nquery      = 50
+		sleepMillis = 25
+		nbatch      = 2
+	)
+	var wg sync.WaitGroup
+	for batch := 0; batch < nbatch; batch++ {
+		for i := 0; i < nquery; i++ {
+			wg.Add(1)
+			go func() {
+				defer wg.Done()
+				var op string
+				if err := stmt.QueryRow("sleep", sleepMillis).Scan(&op); err != nil && err != ErrNoRows {
+					t.Error(err)
+				}
+			}()
+		}
+		// Sleep for twice the expected length of time for the
+		// batch of 50 queries above to finish before starting
+		// the next round.
+		time.Sleep(2 * sleepMillis * time.Millisecond)
+	}
+	wg.Wait()
+
+	if g, w := db.numFreeConns(), 2; g != w {
+		t.Errorf("free conns = %d; want %d", g, w)
+	}
+
+	if n := db.numDepsPollUntil(4, time.Second); n > 4 {
+		t.Errorf("number of dependencies = %d; expected <= 4", n)
+		db.dumpDeps(t)
+	}
+
+	driver.mu.Lock()
+	opens := driver.openCount - opens0
+	closes := driver.closeCount - closes0
+	openDelta := (driver.openCount - driver.closeCount) - openDelta0
+	driver.mu.Unlock()
+
+	if openDelta > 2 {
+		t.Logf("open calls = %d", opens)
+		t.Logf("close calls = %d", closes)
+		t.Logf("open delta = %d", openDelta)
+		t.Errorf("db connections opened = %d; want <= 2", openDelta)
+		db.dumpDeps(t)
+	}
+
+	if len(stmt.css) > nquery {
+		t.Errorf("len(stmt.css) = %d; want <= %d", len(stmt.css), nquery)
+	}
+
+	if err := stmt.Close(); err != nil {
+		t.Fatal(err)
+	}
+
+	if g, w := db.numFreeConns(), 2; g != w {
+		t.Errorf("free conns = %d; want %d", g, w)
+	}
+
+	if n := db.numDepsPollUntil(2, time.Second); n > 2 {
+		t.Errorf("number of dependencies = %d; expected <= 2", n)
+		db.dumpDeps(t)
+	}
+
+	db.SetMaxIdleConns(0)
+
+	if g, w := db.numFreeConns(), 0; g != w {
+		t.Errorf("free conns = %d; want %d", g, w)
+	}
+
+	if n := db.numDepsPollUntil(0, time.Second); n > 0 {
+		t.Errorf("number of dependencies = %d; expected 0", n)
+		db.dumpDeps(t)
+	}
+}
+
+// golang.org/issue/5046
+func TestCloseConnBeforeStmts(t *testing.T) {
+	db := newTestDB(t, "people")
+	defer closeDB(t, db)
+
+	defer setHookpostCloseConn(nil)
+	setHookpostCloseConn(func(_ *fakeConn, err error) {
+		if err != nil {
+			t.Errorf("Error closing fakeConn: %v; from %s", err, stack())
+			db.dumpDeps(t)
+			t.Errorf("DB = %#v", db)
+		}
+	})
+
+	stmt, err := db.Prepare("SELECT|people|name|")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if len(db.freeConn) != 1 {
+		t.Fatalf("expected 1 freeConn; got %d", len(db.freeConn))
+	}
+	dc := db.freeConn[0]
+	if dc.closed {
+		t.Errorf("conn shouldn't be closed")
+	}
+
+	if n := len(dc.openStmt); n != 1 {
+		t.Errorf("driverConn num openStmt = %d; want 1", n)
+	}
+	err = db.Close()
+	if err != nil {
+		t.Errorf("db Close = %v", err)
+	}
+	if !dc.closed {
+		t.Errorf("after db.Close, driverConn should be closed")
+	}
+	if n := len(dc.openStmt); n != 0 {
+		t.Errorf("driverConn num openStmt = %d; want 0", n)
+	}
+
+	err = stmt.Close()
+	if err != nil {
+		t.Errorf("Stmt close = %v", err)
+	}
+
+	if !dc.closed {
+		t.Errorf("conn should be closed")
+	}
+	if dc.ci != nil {
+		t.Errorf("after Stmt Close, driverConn's Conn interface should be nil")
+	}
+}
+
+// golang.org/issue/5283: don't release the Rows' connection in Close
+// before calling Stmt.Close.
+func TestRowsCloseOrder(t *testing.T) {
+	db := newTestDB(t, "people")
+	defer closeDB(t, db)
+
+	db.SetMaxIdleConns(0)
+	setStrictFakeConnClose(t)
+	defer setStrictFakeConnClose(nil)
+
+	rows, err := db.Query("SELECT|people|age,name|")
+	if err != nil {
+		t.Fatal(err)
+	}
+	err = rows.Close()
+	if err != nil {
+		t.Fatal(err)
+	}
+}
+
+func TestRowsImplicitClose(t *testing.T) {
+	db := newTestDB(t, "people")
+	defer closeDB(t, db)
+
+	rows, err := db.Query("SELECT|people|age,name|")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	want, fail := 2, errors.New("fail")
+	r := rows.rowsi.(*rowsCursor)
+	r.errPos, r.err = want, fail
+
+	got := 0
+	for rows.Next() {
+		got++
+	}
+	if got != want {
+		t.Errorf("got %d rows, want %d", got, want)
+	}
+	if err := rows.Err(); err != fail {
+		t.Errorf("got error %v, want %v", err, fail)
+	}
+	if !r.closed {
+		t.Errorf("r.closed is false, want true")
+	}
+}
+
+func TestStmtCloseOrder(t *testing.T) {
+	db := newTestDB(t, "people")
+	defer closeDB(t, db)
+
+	db.SetMaxIdleConns(0)
+	setStrictFakeConnClose(t)
+	defer setStrictFakeConnClose(nil)
+
+	_, err := db.Query("SELECT|non_existent|name|")
+	if err == nil {
+		t.Fatal("Quering non-existent table should fail")
+	}
+}
+
+// golang.org/issue/5781
+func TestErrBadConnReconnect(t *testing.T) {
+	db := newTestDB(t, "foo")
+	defer closeDB(t, db)
+	exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool")
+
+	simulateBadConn := func(name string, hook *func() bool, op func() error) {
+		broken, retried := false, false
+		numOpen := db.numOpen
+
+		// simulate a broken connection on the first try
+		*hook = func() bool {
+			if !broken {
+				broken = true
+				return true
+			}
+			retried = true
+			return false
+		}
+
+		if err := op(); err != nil {
+			t.Errorf(name+": %v", err)
+			return
+		}
+
+		if !broken || !retried {
+			t.Error(name + ": Failed to simulate broken connection")
+		}
+		*hook = nil
+
+		if numOpen != db.numOpen {
+			t.Errorf(name+": leaked %d connection(s)!", db.numOpen-numOpen)
+			numOpen = db.numOpen
+		}
+	}
+
+	// db.Exec
+	dbExec := func() error {
+		_, err := db.Exec("INSERT|t1|name=?,age=?,dead=?", "Gordon", 3, true)
+		return err
+	}
+	simulateBadConn("db.Exec prepare", &hookPrepareBadConn, dbExec)
+	simulateBadConn("db.Exec exec", &hookExecBadConn, dbExec)
+
+	// db.Query
+	dbQuery := func() error {
+		rows, err := db.Query("SELECT|t1|age,name|")
+		if err == nil {
+			err = rows.Close()
+		}
+		return err
+	}
+	simulateBadConn("db.Query prepare", &hookPrepareBadConn, dbQuery)
+	simulateBadConn("db.Query query", &hookQueryBadConn, dbQuery)
+
+	// db.Prepare
+	simulateBadConn("db.Prepare", &hookPrepareBadConn, func() error {
+		stmt, err := db.Prepare("INSERT|t1|name=?,age=?,dead=?")
+		if err != nil {
+			return err
+		}
+		stmt.Close()
+		return nil
+	})
+
+	// Provide a way to force a re-prepare of a statement on next execution
+	forcePrepare := func(stmt *Stmt) {
+		stmt.css = nil
+	}
+
+	// stmt.Exec
+	stmt1, err := db.Prepare("INSERT|t1|name=?,age=?,dead=?")
+	if err != nil {
+		t.Fatalf("prepare: %v", err)
+	}
+	defer stmt1.Close()
+	// make sure we must prepare the stmt first
+	forcePrepare(stmt1)
+
+	stmtExec := func() error {
+		_, err := stmt1.Exec("Gopher", 3, false)
+		return err
+	}
+	simulateBadConn("stmt.Exec prepare", &hookPrepareBadConn, stmtExec)
+	simulateBadConn("stmt.Exec exec", &hookExecBadConn, stmtExec)
+
+	// stmt.Query
+	stmt2, err := db.Prepare("SELECT|t1|age,name|")
+	if err != nil {
+		t.Fatalf("prepare: %v", err)
+	}
+	defer stmt2.Close()
+	// make sure we must prepare the stmt first
+	forcePrepare(stmt2)
+
+	stmtQuery := func() error {
+		rows, err := stmt2.Query()
+		if err == nil {
+			err = rows.Close()
+		}
+		return err
+	}
+	simulateBadConn("stmt.Query prepare", &hookPrepareBadConn, stmtQuery)
+	simulateBadConn("stmt.Query exec", &hookQueryBadConn, stmtQuery)
+}
+
+type concurrentTest interface {
+	init(t testing.TB, db *DB)
+	finish(t testing.TB)
+	test(t testing.TB) error
+}
+
+type concurrentDBQueryTest struct {
+	db *DB
+}
+
+func (c *concurrentDBQueryTest) init(t testing.TB, db *DB) {
+	c.db = db
+}
+
+func (c *concurrentDBQueryTest) finish(t testing.TB) {
+	c.db = nil
+}
+
+func (c *concurrentDBQueryTest) test(t testing.TB) error {
+	rows, err := c.db.Query("SELECT|people|name|")
+	if err != nil {
+		t.Error(err)
+		return err
+	}
+	var name string
+	for rows.Next() {
+		rows.Scan(&name)
+	}
+	rows.Close()
+	return nil
+}
+
+type concurrentDBExecTest struct {
+	db *DB
+}
+
+func (c *concurrentDBExecTest) init(t testing.TB, db *DB) {
+	c.db = db
+}
+
+func (c *concurrentDBExecTest) finish(t testing.TB) {
+	c.db = nil
+}
+
+func (c *concurrentDBExecTest) test(t testing.TB) error {
+	_, err := c.db.Exec("NOSERT|people|name=Chris,age=?,photo=CPHOTO,bdate=?", 3, chrisBirthday)
+	if err != nil {
+		t.Error(err)
+		return err
+	}
+	return nil
+}
+
+type concurrentStmtQueryTest struct {
+	db   *DB
+	stmt *Stmt
+}
+
+func (c *concurrentStmtQueryTest) init(t testing.TB, db *DB) {
+	c.db = db
+	var err error
+	c.stmt, err = db.Prepare("SELECT|people|name|")
+	if err != nil {
+		t.Fatal(err)
+	}
+}
+
+func (c *concurrentStmtQueryTest) finish(t testing.TB) {
+	if c.stmt != nil {
+		c.stmt.Close()
+		c.stmt = nil
+	}
+	c.db = nil
+}
+
+func (c *concurrentStmtQueryTest) test(t testing.TB) error {
+	rows, err := c.stmt.Query()
+	if err != nil {
+		t.Errorf("error on query:  %v", err)
+		return err
+	}
+
+	var name string
+	for rows.Next() {
+		rows.Scan(&name)
+	}
+	rows.Close()
+	return nil
+}
+
+type concurrentStmtExecTest struct {
+	db   *DB
+	stmt *Stmt
+}
+
+func (c *concurrentStmtExecTest) init(t testing.TB, db *DB) {
+	c.db = db
+	var err error
+	c.stmt, err = db.Prepare("NOSERT|people|name=Chris,age=?,photo=CPHOTO,bdate=?")
+	if err != nil {
+		t.Fatal(err)
+	}
+}
+
+func (c *concurrentStmtExecTest) finish(t testing.TB) {
+	if c.stmt != nil {
+		c.stmt.Close()
+		c.stmt = nil
+	}
+	c.db = nil
+}
+
+func (c *concurrentStmtExecTest) test(t testing.TB) error {
+	_, err := c.stmt.Exec(3, chrisBirthday)
+	if err != nil {
+		t.Errorf("error on exec:  %v", err)
+		return err
+	}
+	return nil
+}
+
+type concurrentTxQueryTest struct {
+	db *DB
+	tx *Tx
+}
+
+func (c *concurrentTxQueryTest) init(t testing.TB, db *DB) {
+	c.db = db
+	var err error
+	c.tx, err = c.db.Begin()
+	if err != nil {
+		t.Fatal(err)
+	}
+}
+
+func (c *concurrentTxQueryTest) finish(t testing.TB) {
+	if c.tx != nil {
+		c.tx.Rollback()
+		c.tx = nil
+	}
+	c.db = nil
+}
+
+func (c *concurrentTxQueryTest) test(t testing.TB) error {
+	rows, err := c.db.Query("SELECT|people|name|")
+	if err != nil {
+		t.Error(err)
+		return err
+	}
+	var name string
+	for rows.Next() {
+		rows.Scan(&name)
+	}
+	rows.Close()
+	return nil
+}
+
+type concurrentTxExecTest struct {
+	db *DB
+	tx *Tx
+}
+
+func (c *concurrentTxExecTest) init(t testing.TB, db *DB) {
+	c.db = db
+	var err error
+	c.tx, err = c.db.Begin()
+	if err != nil {
+		t.Fatal(err)
+	}
+}
+
+func (c *concurrentTxExecTest) finish(t testing.TB) {
+	if c.tx != nil {
+		c.tx.Rollback()
+		c.tx = nil
+	}
+	c.db = nil
+}
+
+func (c *concurrentTxExecTest) test(t testing.TB) error {
+	_, err := c.tx.Exec("NOSERT|people|name=Chris,age=?,photo=CPHOTO,bdate=?", 3, chrisBirthday)
+	if err != nil {
+		t.Error(err)
+		return err
+	}
+	return nil
+}
+
+type concurrentTxStmtQueryTest struct {
+	db   *DB
+	tx   *Tx
+	stmt *Stmt
+}
+
+func (c *concurrentTxStmtQueryTest) init(t testing.TB, db *DB) {
+	c.db = db
+	var err error
+	c.tx, err = c.db.Begin()
+	if err != nil {
+		t.Fatal(err)
+	}
+	c.stmt, err = c.tx.Prepare("SELECT|people|name|")
+	if err != nil {
+		t.Fatal(err)
+	}
+}
+
+func (c *concurrentTxStmtQueryTest) finish(t testing.TB) {
+	if c.stmt != nil {
+		c.stmt.Close()
+		c.stmt = nil
+	}
+	if c.tx != nil {
+		c.tx.Rollback()
+		c.tx = nil
+	}
+	c.db = nil
+}
+
+func (c *concurrentTxStmtQueryTest) test(t testing.TB) error {
+	rows, err := c.stmt.Query()
+	if err != nil {
+		t.Errorf("error on query:  %v", err)
+		return err
+	}
+
+	var name string
+	for rows.Next() {
+		rows.Scan(&name)
+	}
+	rows.Close()
+	return nil
+}
+
+type concurrentTxStmtExecTest struct {
+	db   *DB
+	tx   *Tx
+	stmt *Stmt
+}
+
+func (c *concurrentTxStmtExecTest) init(t testing.TB, db *DB) {
+	c.db = db
+	var err error
+	c.tx, err = c.db.Begin()
+	if err != nil {
+		t.Fatal(err)
+	}
+	c.stmt, err = c.tx.Prepare("NOSERT|people|name=Chris,age=?,photo=CPHOTO,bdate=?")
+	if err != nil {
+		t.Fatal(err)
+	}
+}
+
+func (c *concurrentTxStmtExecTest) finish(t testing.TB) {
+	if c.stmt != nil {
+		c.stmt.Close()
+		c.stmt = nil
+	}
+	if c.tx != nil {
+		c.tx.Rollback()
+		c.tx = nil
+	}
+	c.db = nil
+}
+
+func (c *concurrentTxStmtExecTest) test(t testing.TB) error {
+	_, err := c.stmt.Exec(3, chrisBirthday)
+	if err != nil {
+		t.Errorf("error on exec:  %v", err)
+		return err
+	}
+	return nil
+}
+
+type concurrentRandomTest struct {
+	tests []concurrentTest
+}
+
+func (c *concurrentRandomTest) init(t testing.TB, db *DB) {
+	c.tests = []concurrentTest{
+		new(concurrentDBQueryTest),
+		new(concurrentDBExecTest),
+		new(concurrentStmtQueryTest),
+		new(concurrentStmtExecTest),
+		new(concurrentTxQueryTest),
+		new(concurrentTxExecTest),
+		new(concurrentTxStmtQueryTest),
+		new(concurrentTxStmtExecTest),
+	}
+	for _, ct := range c.tests {
+		ct.init(t, db)
+	}
+}
+
+func (c *concurrentRandomTest) finish(t testing.TB) {
+	for _, ct := range c.tests {
+		ct.finish(t)
+	}
+}
+
+func (c *concurrentRandomTest) test(t testing.TB) error {
+	ct := c.tests[rand.Intn(len(c.tests))]
+	return ct.test(t)
+}
+
+func doConcurrentTest(t testing.TB, ct concurrentTest) {
+	maxProcs, numReqs := 1, 500
+	if testing.Short() {
+		maxProcs, numReqs = 4, 50
+	}
+	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(maxProcs))
+
+	db := newTestDB(t, "people")
+	defer closeDB(t, db)
+
+	ct.init(t, db)
+	defer ct.finish(t)
+
+	var wg sync.WaitGroup
+	wg.Add(numReqs)
+
+	reqs := make(chan bool)
+	defer close(reqs)
+
+	for i := 0; i < maxProcs*2; i++ {
+		go func() {
+			for range reqs {
+				err := ct.test(t)
+				if err != nil {
+					wg.Done()
+					continue
+				}
+				wg.Done()
+			}
+		}()
+	}
+
+	for i := 0; i < numReqs; i++ {
+		reqs <- true
+	}
+
+	wg.Wait()
+}
+
+func manyConcurrentQueries(t testing.TB) {
+	maxProcs, numReqs := 16, 500
+	if testing.Short() {
+		maxProcs, numReqs = 4, 50
+	}
+	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(maxProcs))
+
+	db := newTestDB(t, "people")
+	defer closeDB(t, db)
+
+	stmt, err := db.Prepare("SELECT|people|name|")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer stmt.Close()
+
+	var wg sync.WaitGroup
+	wg.Add(numReqs)
+
+	reqs := make(chan bool)
+	defer close(reqs)
+
+	for i := 0; i < maxProcs*2; i++ {
+		go func() {
+			for range reqs {
+				rows, err := stmt.Query()
+				if err != nil {
+					t.Errorf("error on query:  %v", err)
+					wg.Done()
+					continue
+				}
+
+				var name string
+				for rows.Next() {
+					rows.Scan(&name)
+				}
+				rows.Close()
+
+				wg.Done()
+			}
+		}()
+	}
+
+	for i := 0; i < numReqs; i++ {
+		reqs <- true
+	}
+
+	wg.Wait()
+}
+
+func TestIssue6081(t *testing.T) {
+	db := newTestDB(t, "people")
+	defer closeDB(t, db)
+
+	drv := db.driver.(*fakeDriver)
+	drv.mu.Lock()
+	opens0 := drv.openCount
+	closes0 := drv.closeCount
+	drv.mu.Unlock()
+
+	stmt, err := db.Prepare("SELECT|people|name|")
+	if err != nil {
+		t.Fatal(err)
+	}
+	rowsCloseHook = func(rows *Rows, err *error) {
+		*err = driver.ErrBadConn
+	}
+	defer func() { rowsCloseHook = nil }()
+	for i := 0; i < 10; i++ {
+		rows, err := stmt.Query()
+		if err != nil {
+			t.Fatal(err)
+		}
+		rows.Close()
+	}
+	if n := len(stmt.css); n > 1 {
+		t.Errorf("len(css slice) = %d; want <= 1", n)
+	}
+	stmt.Close()
+	if n := len(stmt.css); n != 0 {
+		t.Errorf("len(css slice) after Close = %d; want 0", n)
+	}
+
+	drv.mu.Lock()
+	opens := drv.openCount - opens0
+	closes := drv.closeCount - closes0
+	drv.mu.Unlock()
+	if opens < 9 {
+		t.Errorf("opens = %d; want >= 9", opens)
+	}
+	if closes < 9 {
+		t.Errorf("closes = %d; want >= 9", closes)
+	}
+}
+
+func TestConcurrency(t *testing.T) {
+	doConcurrentTest(t, new(concurrentDBQueryTest))
+	doConcurrentTest(t, new(concurrentDBExecTest))
+	doConcurrentTest(t, new(concurrentStmtQueryTest))
+	doConcurrentTest(t, new(concurrentStmtExecTest))
+	doConcurrentTest(t, new(concurrentTxQueryTest))
+	doConcurrentTest(t, new(concurrentTxExecTest))
+	doConcurrentTest(t, new(concurrentTxStmtQueryTest))
+	doConcurrentTest(t, new(concurrentTxStmtExecTest))
+	doConcurrentTest(t, new(concurrentRandomTest))
+}
+
+func TestConnectionLeak(t *testing.T) {
+	db := newTestDB(t, "people")
+	defer closeDB(t, db)
+	// Start by opening defaultMaxIdleConns
+	rows := make([]*Rows, defaultMaxIdleConns)
+	// We need to SetMaxOpenConns > MaxIdleConns, so the DB can open
+	// a new connection and we can fill the idle queue with the released
+	// connections.
+	db.SetMaxOpenConns(len(rows) + 1)
+	for ii := range rows {
+		r, err := db.Query("SELECT|people|name|")
+		if err != nil {
+			t.Fatal(err)
+		}
+		r.Next()
+		if err := r.Err(); err != nil {
+			t.Fatal(err)
+		}
+		rows[ii] = r
+	}
+	// Now we have defaultMaxIdleConns busy connections. Open
+	// a new one, but wait until the busy connections are released
+	// before returning control to DB.
+	drv := db.driver.(*fakeDriver)
+	drv.waitCh = make(chan struct{}, 1)
+	drv.waitingCh = make(chan struct{}, 1)
+	var wg sync.WaitGroup
+	wg.Add(1)
+	go func() {
+		r, err := db.Query("SELECT|people|name|")
+		if err != nil {
+			t.Fatal(err)
+		}
+		r.Close()
+		wg.Done()
+	}()
+	// Wait until the goroutine we've just created has started waiting.
+	<-drv.waitingCh
+	// Now close the busy connections. This provides a connection for
+	// the blocked goroutine and then fills up the idle queue.
+	for _, v := range rows {
+		v.Close()
+	}
+	// At this point we give the new connection to DB. This connection is
+	// now useless, since the idle queue is full and there are no pending
+	// requests. DB should deal with this situation without leaking the
+	// connection.
+	drv.waitCh <- struct{}{}
+	wg.Wait()
+}
+
+func BenchmarkConcurrentDBExec(b *testing.B) {
+	b.ReportAllocs()
+	ct := new(concurrentDBExecTest)
+	for i := 0; i < b.N; i++ {
+		doConcurrentTest(b, ct)
+	}
+}
+
+func BenchmarkConcurrentStmtQuery(b *testing.B) {
+	b.ReportAllocs()
+	ct := new(concurrentStmtQueryTest)
+	for i := 0; i < b.N; i++ {
+		doConcurrentTest(b, ct)
+	}
+}
+
+func BenchmarkConcurrentStmtExec(b *testing.B) {
+	b.ReportAllocs()
+	ct := new(concurrentStmtExecTest)
+	for i := 0; i < b.N; i++ {
+		doConcurrentTest(b, ct)
+	}
+}
+
+func BenchmarkConcurrentTxQuery(b *testing.B) {
+	b.ReportAllocs()
+	ct := new(concurrentTxQueryTest)
+	for i := 0; i < b.N; i++ {
+		doConcurrentTest(b, ct)
+	}
+}
+
+func BenchmarkConcurrentTxExec(b *testing.B) {
+	b.ReportAllocs()
+	ct := new(concurrentTxExecTest)
+	for i := 0; i < b.N; i++ {
+		doConcurrentTest(b, ct)
+	}
+}
+
+func BenchmarkConcurrentTxStmtQuery(b *testing.B) {
+	b.ReportAllocs()
+	ct := new(concurrentTxStmtQueryTest)
+	for i := 0; i < b.N; i++ {
+		doConcurrentTest(b, ct)
+	}
+}
+
+func BenchmarkConcurrentTxStmtExec(b *testing.B) {
+	b.ReportAllocs()
+	ct := new(concurrentTxStmtExecTest)
+	for i := 0; i < b.N; i++ {
+		doConcurrentTest(b, ct)
+	}
+}
+
+func BenchmarkConcurrentRandom(b *testing.B) {
+	b.ReportAllocs()
+	ct := new(concurrentRandomTest)
+	for i := 0; i < b.N; i++ {
+		doConcurrentTest(b, ct)
+	}
+}
diff --git a/src/pkg/debug/dwarf/buf.go b/src/debug/dwarf/buf.go
similarity index 100%
rename from src/pkg/debug/dwarf/buf.go
rename to src/debug/dwarf/buf.go
diff --git a/src/pkg/debug/dwarf/const.go b/src/debug/dwarf/const.go
similarity index 100%
rename from src/pkg/debug/dwarf/const.go
rename to src/debug/dwarf/const.go
diff --git a/src/pkg/debug/dwarf/entry.go b/src/debug/dwarf/entry.go
similarity index 100%
rename from src/pkg/debug/dwarf/entry.go
rename to src/debug/dwarf/entry.go
diff --git a/src/pkg/debug/dwarf/open.go b/src/debug/dwarf/open.go
similarity index 100%
rename from src/pkg/debug/dwarf/open.go
rename to src/debug/dwarf/open.go
diff --git a/src/pkg/debug/dwarf/testdata/typedef.c b/src/debug/dwarf/testdata/typedef.c
similarity index 100%
rename from src/pkg/debug/dwarf/testdata/typedef.c
rename to src/debug/dwarf/testdata/typedef.c
diff --git a/src/pkg/debug/dwarf/testdata/typedef.elf b/src/debug/dwarf/testdata/typedef.elf
similarity index 100%
rename from src/pkg/debug/dwarf/testdata/typedef.elf
rename to src/debug/dwarf/testdata/typedef.elf
diff --git a/src/pkg/debug/dwarf/testdata/typedef.elf4 b/src/debug/dwarf/testdata/typedef.elf4
similarity index 100%
rename from src/pkg/debug/dwarf/testdata/typedef.elf4
rename to src/debug/dwarf/testdata/typedef.elf4
diff --git a/src/pkg/debug/dwarf/testdata/typedef.macho b/src/debug/dwarf/testdata/typedef.macho
similarity index 100%
rename from src/pkg/debug/dwarf/testdata/typedef.macho
rename to src/debug/dwarf/testdata/typedef.macho
diff --git a/src/debug/dwarf/type.go b/src/debug/dwarf/type.go
new file mode 100644
index 0000000..6986b19
--- /dev/null
+++ b/src/debug/dwarf/type.go
@@ -0,0 +1,696 @@
+// Copyright 2009 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// DWARF type information structures.
+// The format is heavily biased toward C, but for simplicity
+// the String methods use a pseudo-Go syntax.
+
+package dwarf
+
+import "strconv"
+
+// A Type conventionally represents a pointer to any of the
+// specific Type structures (CharType, StructType, etc.).
+type Type interface {
+	Common() *CommonType
+	String() string
+	Size() int64
+}
+
+// A CommonType holds fields common to multiple types.
+// If a field is not known or not applicable for a given type,
+// the zero value is used.
+type CommonType struct {
+	ByteSize int64  // size of value of this type, in bytes
+	Name     string // name that can be used to refer to type
+}
+
+func (c *CommonType) Common() *CommonType { return c }
+
+func (c *CommonType) Size() int64 { return c.ByteSize }
+
+// Basic types
+
+// A BasicType holds fields common to all basic types.
+type BasicType struct {
+	CommonType
+	BitSize   int64
+	BitOffset int64
+}
+
+func (b *BasicType) Basic() *BasicType { return b }
+
+func (t *BasicType) String() string {
+	if t.Name != "" {
+		return t.Name
+	}
+	return "?"
+}
+
+// A CharType represents a signed character type.
+type CharType struct {
+	BasicType
+}
+
+// A UcharType represents an unsigned character type.
+type UcharType struct {
+	BasicType
+}
+
+// An IntType represents a signed integer type.
+type IntType struct {
+	BasicType
+}
+
+// A UintType represents an unsigned integer type.
+type UintType struct {
+	BasicType
+}
+
+// A FloatType represents a floating point type.
+type FloatType struct {
+	BasicType
+}
+
+// A ComplexType represents a complex floating point type.
+type ComplexType struct {
+	BasicType
+}
+
+// A BoolType represents a boolean type.
+type BoolType struct {
+	BasicType
+}
+
+// An AddrType represents a machine address type.
+type AddrType struct {
+	BasicType
+}
+
+// An UnspecifiedType represents an implicit, unknown, ambiguous or nonexistent type.
+type UnspecifiedType struct {
+	BasicType
+}
+
+// qualifiers
+
+// A QualType represents a type that has the C/C++ "const", "restrict", or "volatile" qualifier.
+type QualType struct {
+	CommonType
+	Qual string
+	Type Type
+}
+
+func (t *QualType) String() string { return t.Qual + " " + t.Type.String() }
+
+func (t *QualType) Size() int64 { return t.Type.Size() }
+
+// An ArrayType represents a fixed size array type.
+type ArrayType struct {
+	CommonType
+	Type          Type
+	StrideBitSize int64 // if > 0, number of bits to hold each element
+	Count         int64 // if == -1, an incomplete array, like char x[].
+}
+
+func (t *ArrayType) String() string {
+	return "[" + strconv.FormatInt(t.Count, 10) + "]" + t.Type.String()
+}
+
+func (t *ArrayType) Size() int64 {
+	if t.Count == -1 {
+		return 0
+	}
+	return t.Count * t.Type.Size()
+}
+
+// A VoidType represents the C void type.
+type VoidType struct {
+	CommonType
+}
+
+func (t *VoidType) String() string { return "void" }
+
+// A PtrType represents a pointer type.
+type PtrType struct {
+	CommonType
+	Type Type
+}
+
+func (t *PtrType) String() string { return "*" + t.Type.String() }
+
+// A StructType represents a struct, union, or C++ class type.
+type StructType struct {
+	CommonType
+	StructName string
+	Kind       string // "struct", "union", or "class".
+	Field      []*StructField
+	Incomplete bool // if true, struct, union, class is declared but not defined
+}
+
+// A StructField represents a field in a struct, union, or C++ class type.
+type StructField struct {
+	Name       string
+	Type       Type
+	ByteOffset int64
+	ByteSize   int64
+	BitOffset  int64 // within the ByteSize bytes at ByteOffset
+	BitSize    int64 // zero if not a bit field
+}
+
+func (t *StructType) String() string {
+	if t.StructName != "" {
+		return t.Kind + " " + t.StructName
+	}
+	return t.Defn()
+}
+
+func (t *StructType) Defn() string {
+	s := t.Kind
+	if t.StructName != "" {
+		s += " " + t.StructName
+	}
+	if t.Incomplete {
+		s += " /*incomplete*/"
+		return s
+	}
+	s += " {"
+	for i, f := range t.Field {
+		if i > 0 {
+			s += "; "
+		}
+		s += f.Name + " " + f.Type.String()
+		s += "@" + strconv.FormatInt(f.ByteOffset, 10)
+		if f.BitSize > 0 {
+			s += " : " + strconv.FormatInt(f.BitSize, 10)
+			s += "@" + strconv.FormatInt(f.BitOffset, 10)
+		}
+	}
+	s += "}"
+	return s
+}
+
+// An EnumType represents an enumerated type.
+// The only indication of its native integer type is its ByteSize
+// (inside CommonType).
+type EnumType struct {
+	CommonType
+	EnumName string
+	Val      []*EnumValue
+}
+
+// An EnumValue represents a single enumeration value.
+type EnumValue struct {
+	Name string
+	Val  int64
+}
+
+func (t *EnumType) String() string {
+	s := "enum"
+	if t.EnumName != "" {
+		s += " " + t.EnumName
+	}
+	s += " {"
+	for i, v := range t.Val {
+		if i > 0 {
+			s += "; "
+		}
+		s += v.Name + "=" + strconv.FormatInt(v.Val, 10)
+	}
+	s += "}"
+	return s
+}
+
+// A FuncType represents a function type.
+type FuncType struct {
+	CommonType
+	ReturnType Type
+	ParamType  []Type
+}
+
+func (t *FuncType) String() string {
+	s := "func("
+	for i, t := range t.ParamType {
+		if i > 0 {
+			s += ", "
+		}
+		s += t.String()
+	}
+	s += ")"
+	if t.ReturnType != nil {
+		s += " " + t.ReturnType.String()
+	}
+	return s
+}
+
+// A DotDotDotType represents the variadic ... function parameter.
+type DotDotDotType struct {
+	CommonType
+}
+
+func (t *DotDotDotType) String() string { return "..." }
+
+// A TypedefType represents a named type.
+type TypedefType struct {
+	CommonType
+	Type Type
+}
+
+func (t *TypedefType) String() string { return t.Name }
+
+func (t *TypedefType) Size() int64 { return t.Type.Size() }
+
+// typeReader is used to read from either the info section or the
+// types section.
+type typeReader interface {
+	Seek(Offset)
+	Next() (*Entry, error)
+	clone() typeReader
+	offset() Offset
+}
+
+// Type reads the type at off in the DWARF ``info'' section.
+func (d *Data) Type(off Offset) (Type, error) {
+	return d.readType("info", d.Reader(), off, d.typeCache)
+}
+
+// readType reads a type from r at off of name using and updating a
+// type cache.
+func (d *Data) readType(name string, r typeReader, off Offset, typeCache map[Offset]Type) (Type, error) {
+	if t, ok := typeCache[off]; ok {
+		return t, nil
+	}
+	r.Seek(off)
+	e, err := r.Next()
+	if err != nil {
+		return nil, err
+	}
+	if e == nil || e.Offset != off {
+		return nil, DecodeError{name, off, "no type at offset"}
+	}
+
+	// Parse type from Entry.
+	// Must always set typeCache[off] before calling
+	// d.Type recursively, to handle circular types correctly.
+	var typ Type
+
+	nextDepth := 0
+
+	// Get next child; set err if error happens.
+	next := func() *Entry {
+		if !e.Children {
+			return nil
+		}
+		// Only return direct children.
+		// Skip over composite entries that happen to be nested
+		// inside this one. Most DWARF generators wouldn't generate
+		// such a thing, but clang does.
+		// See golang.org/issue/6472.
+		for {
+			kid, err1 := r.Next()
+			if err1 != nil {
+				err = err1
+				return nil
+			}
+			if kid == nil {
+				err = DecodeError{name, r.offset(), "unexpected end of DWARF entries"}
+				return nil
+			}
+			if kid.Tag == 0 {
+				if nextDepth > 0 {
+					nextDepth--
+					continue
+				}
+				return nil
+			}
+			if kid.Children {
+				nextDepth++
+			}
+			if nextDepth > 0 {
+				continue
+			}
+			return kid
+		}
+	}
+
+	// Get Type referred to by Entry's AttrType field.
+	// Set err if error happens.  Not having a type is an error.
+	typeOf := func(e *Entry) Type {
+		tval := e.Val(AttrType)
+		var t Type
+		switch toff := tval.(type) {
+		case Offset:
+			if t, err = d.readType(name, r.clone(), toff, typeCache); err != nil {
+				return nil
+			}
+		case uint64:
+			if t, err = d.sigToType(toff); err != nil {
+				return nil
+			}
+		default:
+			// It appears that no Type means "void".
+			return new(VoidType)
+		}
+		return t
+	}
+
+	switch e.Tag {
+	case TagArrayType:
+		// Multi-dimensional array.  (DWARF v2 §5.4)
+		// Attributes:
+		//	AttrType:subtype [required]
+		//	AttrStrideSize: size in bits of each element of the array
+		//	AttrByteSize: size of entire array
+		// Children:
+		//	TagSubrangeType or TagEnumerationType giving one dimension.
+		//	dimensions are in left to right order.
+		t := new(ArrayType)
+		typ = t
+		typeCache[off] = t
+		if t.Type = typeOf(e); err != nil {
+			goto Error
+		}
+		t.StrideBitSize, _ = e.Val(AttrStrideSize).(int64)
+
+		// Accumulate dimensions,
+		var dims []int64
+		for kid := next(); kid != nil; kid = next() {
+			// TODO(rsc): Can also be TagEnumerationType
+			// but haven't seen that in the wild yet.
+			switch kid.Tag {
+			case TagSubrangeType:
+				count, ok := kid.Val(AttrCount).(int64)
+				if !ok {
+					// Old binaries may have an upper bound instead.
+					count, ok = kid.Val(AttrUpperBound).(int64)
+					if ok {
+						count++ // Length is one more than upper bound.
+					} else if len(dims) == 0 {
+						count = -1 // As in x[].
+					}
+				}
+				dims = append(dims, count)
+			case TagEnumerationType:
+				err = DecodeError{name, kid.Offset, "cannot handle enumeration type as array bound"}
+				goto Error
+			}
+		}
+		if len(dims) == 0 {
+			// LLVM generates this for x[].
+			dims = []int64{-1}
+		}
+
+		t.Count = dims[0]
+		for i := len(dims) - 1; i >= 1; i-- {
+			t.Type = &ArrayType{Type: t.Type, Count: dims[i]}
+		}
+
+	case TagBaseType:
+		// Basic type.  (DWARF v2 §5.1)
+		// Attributes:
+		//	AttrName: name of base type in programming language of the compilation unit [required]
+		//	AttrEncoding: encoding value for type (encFloat etc) [required]
+		//	AttrByteSize: size of type in bytes [required]
+		//	AttrBitOffset: for sub-byte types, size in bits
+		//	AttrBitSize: for sub-byte types, bit offset of high order bit in the AttrByteSize bytes
+		name, _ := e.Val(AttrName).(string)
+		enc, ok := e.Val(AttrEncoding).(int64)
+		if !ok {
+			err = DecodeError{name, e.Offset, "missing encoding attribute for " + name}
+			goto Error
+		}
+		switch enc {
+		default:
+			err = DecodeError{name, e.Offset, "unrecognized encoding attribute value"}
+			goto Error
+
+		case encAddress:
+			typ = new(AddrType)
+		case encBoolean:
+			typ = new(BoolType)
+		case encComplexFloat:
+			typ = new(ComplexType)
+			if name == "complex" {
+				// clang writes out 'complex' instead of 'complex float' or 'complex double'.
+				// clang also writes out a byte size that we can use to distinguish.
+				// See issue 8694.
+				switch byteSize, _ := e.Val(AttrByteSize).(int64); byteSize {
+				case 8:
+					name = "complex float"
+				case 16:
+					name = "complex double"
+				}
+			}
+		case encFloat:
+			typ = new(FloatType)
+		case encSigned:
+			typ = new(IntType)
+		case encUnsigned:
+			typ = new(UintType)
+		case encSignedChar:
+			typ = new(CharType)
+		case encUnsignedChar:
+			typ = new(UcharType)
+		}
+		typeCache[off] = typ
+		t := typ.(interface {
+			Basic() *BasicType
+		}).Basic()
+		t.Name = name
+		t.BitSize, _ = e.Val(AttrBitSize).(int64)
+		t.BitOffset, _ = e.Val(AttrBitOffset).(int64)
+
+	case TagClassType, TagStructType, TagUnionType:
+		// Structure, union, or class type.  (DWARF v2 §5.5)
+		// Attributes:
+		//	AttrName: name of struct, union, or class
+		//	AttrByteSize: byte size [required]
+		//	AttrDeclaration: if true, struct/union/class is incomplete
+		// Children:
+		//	TagMember to describe one member.
+		//		AttrName: name of member [required]
+		//		AttrType: type of member [required]
+		//		AttrByteSize: size in bytes
+		//		AttrBitOffset: bit offset within bytes for bit fields
+		//		AttrBitSize: bit size for bit fields
+		//		AttrDataMemberLoc: location within struct [required for struct, class]
+		// There is much more to handle C++, all ignored for now.
+		t := new(StructType)
+		typ = t
+		typeCache[off] = t
+		switch e.Tag {
+		case TagClassType:
+			t.Kind = "class"
+		case TagStructType:
+			t.Kind = "struct"
+		case TagUnionType:
+			t.Kind = "union"
+		}
+		t.StructName, _ = e.Val(AttrName).(string)
+		t.Incomplete = e.Val(AttrDeclaration) != nil
+		t.Field = make([]*StructField, 0, 8)
+		var lastFieldType *Type
+		var lastFieldBitOffset int64
+		for kid := next(); kid != nil; kid = next() {
+			if kid.Tag == TagMember {
+				f := new(StructField)
+				if f.Type = typeOf(kid); err != nil {
+					goto Error
+				}
+				switch loc := kid.Val(AttrDataMemberLoc).(type) {
+				case []byte:
+					// TODO: Should have original compilation
+					// unit here, not unknownFormat.
+					b := makeBuf(d, unknownFormat{}, "location", 0, loc)
+					if b.uint8() != opPlusUconst {
+						err = DecodeError{name, kid.Offset, "unexpected opcode"}
+						goto Error
+					}
+					f.ByteOffset = int64(b.uint())
+					if b.err != nil {
+						err = b.err
+						goto Error
+					}
+				case int64:
+					f.ByteOffset = loc
+				}
+
+				haveBitOffset := false
+				f.Name, _ = kid.Val(AttrName).(string)
+				f.ByteSize, _ = kid.Val(AttrByteSize).(int64)
+				f.BitOffset, haveBitOffset = kid.Val(AttrBitOffset).(int64)
+				f.BitSize, _ = kid.Val(AttrBitSize).(int64)
+				t.Field = append(t.Field, f)
+
+				bito := f.BitOffset
+				if !haveBitOffset {
+					bito = f.ByteOffset * 8
+				}
+				if bito == lastFieldBitOffset && t.Kind != "union" {
+					// Last field was zero width.  Fix array length.
+					// (DWARF writes out 0-length arrays as if they were 1-length arrays.)
+					zeroArray(lastFieldType)
+				}
+				lastFieldType = &f.Type
+				lastFieldBitOffset = bito
+			}
+		}
+		if t.Kind != "union" {
+			b, ok := e.Val(AttrByteSize).(int64)
+			if ok && b*8 == lastFieldBitOffset {
+				// Final field must be zero width.  Fix array length.
+				zeroArray(lastFieldType)
+			}
+		}
+
+	case TagConstType, TagVolatileType, TagRestrictType:
+		// Type modifier (DWARF v2 §5.2)
+		// Attributes:
+		//	AttrType: subtype
+		t := new(QualType)
+		typ = t
+		typeCache[off] = t
+		if t.Type = typeOf(e); err != nil {
+			goto Error
+		}
+		switch e.Tag {
+		case TagConstType:
+			t.Qual = "const"
+		case TagRestrictType:
+			t.Qual = "restrict"
+		case TagVolatileType:
+			t.Qual = "volatile"
+		}
+
+	case TagEnumerationType:
+		// Enumeration type (DWARF v2 §5.6)
+		// Attributes:
+		//	AttrName: enum name if any
+		//	AttrByteSize: bytes required to represent largest value
+		// Children:
+		//	TagEnumerator:
+		//		AttrName: name of constant
+		//		AttrConstValue: value of constant
+		t := new(EnumType)
+		typ = t
+		typeCache[off] = t
+		t.EnumName, _ = e.Val(AttrName).(string)
+		t.Val = make([]*EnumValue, 0, 8)
+		for kid := next(); kid != nil; kid = next() {
+			if kid.Tag == TagEnumerator {
+				f := new(EnumValue)
+				f.Name, _ = kid.Val(AttrName).(string)
+				f.Val, _ = kid.Val(AttrConstValue).(int64)
+				n := len(t.Val)
+				if n >= cap(t.Val) {
+					val := make([]*EnumValue, n, n*2)
+					copy(val, t.Val)
+					t.Val = val
+				}
+				t.Val = t.Val[0 : n+1]
+				t.Val[n] = f
+			}
+		}
+
+	case TagPointerType:
+		// Type modifier (DWARF v2 §5.2)
+		// Attributes:
+		//	AttrType: subtype [not required!  void* has no AttrType]
+		//	AttrAddrClass: address class [ignored]
+		t := new(PtrType)
+		typ = t
+		typeCache[off] = t
+		if e.Val(AttrType) == nil {
+			t.Type = &VoidType{}
+			break
+		}
+		t.Type = typeOf(e)
+
+	case TagSubroutineType:
+		// Subroutine type.  (DWARF v2 §5.7)
+		// Attributes:
+		//	AttrType: type of return value if any
+		//	AttrName: possible name of type [ignored]
+		//	AttrPrototyped: whether used ANSI C prototype [ignored]
+		// Children:
+		//	TagFormalParameter: typed parameter
+		//		AttrType: type of parameter
+		//	TagUnspecifiedParameter: final ...
+		t := new(FuncType)
+		typ = t
+		typeCache[off] = t
+		if t.ReturnType = typeOf(e); err != nil {
+			goto Error
+		}
+		t.ParamType = make([]Type, 0, 8)
+		for kid := next(); kid != nil; kid = next() {
+			var tkid Type
+			switch kid.Tag {
+			default:
+				continue
+			case TagFormalParameter:
+				if tkid = typeOf(kid); err != nil {
+					goto Error
+				}
+			case TagUnspecifiedParameters:
+				tkid = &DotDotDotType{}
+			}
+			t.ParamType = append(t.ParamType, tkid)
+		}
+
+	case TagTypedef:
+		// Typedef (DWARF v2 §5.3)
+		// Attributes:
+		//	AttrName: name [required]
+		//	AttrType: type definition [required]
+		t := new(TypedefType)
+		typ = t
+		typeCache[off] = t
+		t.Name, _ = e.Val(AttrName).(string)
+		t.Type = typeOf(e)
+
+	case TagUnspecifiedType:
+		// Unspecified type (DWARF v3 §5.2)
+		// Attributes:
+		//	AttrName: name
+		t := new(UnspecifiedType)
+		typ = t
+		typeCache[off] = t
+		t.Name, _ = e.Val(AttrName).(string)
+	}
+
+	if err != nil {
+		goto Error
+	}
+
+	{
+		b, ok := e.Val(AttrByteSize).(int64)
+		if !ok {
+			b = -1
+		}
+		typ.Common().ByteSize = b
+	}
+	return typ, nil
+
+Error:
+	// If the parse fails, take the type out of the cache
+	// so that the next call with this offset doesn't hit
+	// the cache and return success.
+	delete(typeCache, off)
+	return nil, err
+}
+
+func zeroArray(t *Type) {
+	if t == nil {
+		return
+	}
+	at, ok := (*t).(*ArrayType)
+	if !ok || at.Type.Size() == 0 {
+		return
+	}
+	// Make a copy to avoid invalidating typeCache.
+	tt := *at
+	tt.Count = 0
+	*t = &tt
+}
diff --git a/src/pkg/debug/dwarf/type_test.go b/src/debug/dwarf/type_test.go
similarity index 100%
rename from src/pkg/debug/dwarf/type_test.go
rename to src/debug/dwarf/type_test.go
diff --git a/src/pkg/debug/dwarf/typeunit.go b/src/debug/dwarf/typeunit.go
similarity index 100%
rename from src/pkg/debug/dwarf/typeunit.go
rename to src/debug/dwarf/typeunit.go
diff --git a/src/pkg/debug/dwarf/unit.go b/src/debug/dwarf/unit.go
similarity index 100%
rename from src/pkg/debug/dwarf/unit.go
rename to src/debug/dwarf/unit.go
diff --git a/src/debug/elf/elf.go b/src/debug/elf/elf.go
new file mode 100644
index 0000000..cde296c
--- /dev/null
+++ b/src/debug/elf/elf.go
@@ -0,0 +1,1773 @@
+/*
+ * ELF constants and data structures
+ *
+ * Derived from:
+ * $FreeBSD: src/sys/sys/elf32.h,v 1.8.14.1 2005/12/30 22:13:58 marcel Exp $
+ * $FreeBSD: src/sys/sys/elf64.h,v 1.10.14.1 2005/12/30 22:13:58 marcel Exp $
+ * $FreeBSD: src/sys/sys/elf_common.h,v 1.15.8.1 2005/12/30 22:13:58 marcel Exp $
+ * $FreeBSD: src/sys/alpha/include/elf.h,v 1.14 2003/09/25 01:10:22 peter Exp $
+ * $FreeBSD: src/sys/amd64/include/elf.h,v 1.18 2004/08/03 08:21:48 dfr Exp $
+ * $FreeBSD: src/sys/arm/include/elf.h,v 1.5.2.1 2006/06/30 21:42:52 cognet Exp $
+ * $FreeBSD: src/sys/i386/include/elf.h,v 1.16 2004/08/02 19:12:17 dfr Exp $
+ * $FreeBSD: src/sys/powerpc/include/elf.h,v 1.7 2004/11/02 09:47:01 ssouhlal Exp $
+ * $FreeBSD: src/sys/sparc64/include/elf.h,v 1.12 2003/09/25 01:10:26 peter Exp $
+ * "ELF for the ARM® 64-bit Architecture (AArch64)" (ARM IHI 0056B)
+ *
+ * Copyright (c) 1996-1998 John D. Polstra.  All rights reserved.
+ * Copyright (c) 2001 David E. O'Brien
+ * Portions Copyright 2009 The Go Authors.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+package elf
+
+import "strconv"
+
+/*
+ * Constants
+ */
+
+// Indexes into the Header.Ident array.
+const (
+	EI_CLASS      = 4  /* Class of machine. */
+	EI_DATA       = 5  /* Data format. */
+	EI_VERSION    = 6  /* ELF format version. */
+	EI_OSABI      = 7  /* Operating system / ABI identification */
+	EI_ABIVERSION = 8  /* ABI version */
+	EI_PAD        = 9  /* Start of padding (per SVR4 ABI). */
+	EI_NIDENT     = 16 /* Size of e_ident array. */
+)
+
+// Initial magic number for ELF files.
+const ELFMAG = "\177ELF"
+
+// Version is found in Header.Ident[EI_VERSION] and Header.Version.
+type Version byte
+
+const (
+	EV_NONE    Version = 0
+	EV_CURRENT Version = 1
+)
+
+var versionStrings = []intName{
+	{0, "EV_NONE"},
+	{1, "EV_CURRENT"},
+}
+
+func (i Version) String() string   { return stringName(uint32(i), versionStrings, false) }
+func (i Version) GoString() string { return stringName(uint32(i), versionStrings, true) }
+
+// Class is found in Header.Ident[EI_CLASS] and Header.Class.
+type Class byte
+
+const (
+	ELFCLASSNONE Class = 0 /* Unknown class. */
+	ELFCLASS32   Class = 1 /* 32-bit architecture. */
+	ELFCLASS64   Class = 2 /* 64-bit architecture. */
+)
+
+var classStrings = []intName{
+	{0, "ELFCLASSNONE"},
+	{1, "ELFCLASS32"},
+	{2, "ELFCLASS64"},
+}
+
+func (i Class) String() string   { return stringName(uint32(i), classStrings, false) }
+func (i Class) GoString() string { return stringName(uint32(i), classStrings, true) }
+
+// Data is found in Header.Ident[EI_DATA] and Header.Data.
+type Data byte
+
+const (
+	ELFDATANONE Data = 0 /* Unknown data format. */
+	ELFDATA2LSB Data = 1 /* 2's complement little-endian. */
+	ELFDATA2MSB Data = 2 /* 2's complement big-endian. */
+)
+
+var dataStrings = []intName{
+	{0, "ELFDATANONE"},
+	{1, "ELFDATA2LSB"},
+	{2, "ELFDATA2MSB"},
+}
+
+func (i Data) String() string   { return stringName(uint32(i), dataStrings, false) }
+func (i Data) GoString() string { return stringName(uint32(i), dataStrings, true) }
+
+// OSABI is found in Header.Ident[EI_OSABI] and Header.OSABI.
+type OSABI byte
+
+const (
+	ELFOSABI_NONE       OSABI = 0   /* UNIX System V ABI */
+	ELFOSABI_HPUX       OSABI = 1   /* HP-UX operating system */
+	ELFOSABI_NETBSD     OSABI = 2   /* NetBSD */
+	ELFOSABI_LINUX      OSABI = 3   /* GNU/Linux */
+	ELFOSABI_HURD       OSABI = 4   /* GNU/Hurd */
+	ELFOSABI_86OPEN     OSABI = 5   /* 86Open common IA32 ABI */
+	ELFOSABI_SOLARIS    OSABI = 6   /* Solaris */
+	ELFOSABI_AIX        OSABI = 7   /* AIX */
+	ELFOSABI_IRIX       OSABI = 8   /* IRIX */
+	ELFOSABI_FREEBSD    OSABI = 9   /* FreeBSD */
+	ELFOSABI_TRU64      OSABI = 10  /* TRU64 UNIX */
+	ELFOSABI_MODESTO    OSABI = 11  /* Novell Modesto */
+	ELFOSABI_OPENBSD    OSABI = 12  /* OpenBSD */
+	ELFOSABI_OPENVMS    OSABI = 13  /* Open VMS */
+	ELFOSABI_NSK        OSABI = 14  /* HP Non-Stop Kernel */
+	ELFOSABI_ARM        OSABI = 97  /* ARM */
+	ELFOSABI_STANDALONE OSABI = 255 /* Standalone (embedded) application */
+)
+
+var osabiStrings = []intName{
+	{0, "ELFOSABI_NONE"},
+	{1, "ELFOSABI_HPUX"},
+	{2, "ELFOSABI_NETBSD"},
+	{3, "ELFOSABI_LINUX"},
+	{4, "ELFOSABI_HURD"},
+	{5, "ELFOSABI_86OPEN"},
+	{6, "ELFOSABI_SOLARIS"},
+	{7, "ELFOSABI_AIX"},
+	{8, "ELFOSABI_IRIX"},
+	{9, "ELFOSABI_FREEBSD"},
+	{10, "ELFOSABI_TRU64"},
+	{11, "ELFOSABI_MODESTO"},
+	{12, "ELFOSABI_OPENBSD"},
+	{13, "ELFOSABI_OPENVMS"},
+	{14, "ELFOSABI_NSK"},
+	{97, "ELFOSABI_ARM"},
+	{255, "ELFOSABI_STANDALONE"},
+}
+
+func (i OSABI) String() string   { return stringName(uint32(i), osabiStrings, false) }
+func (i OSABI) GoString() string { return stringName(uint32(i), osabiStrings, true) }
+
+// Type is found in Header.Type.
+type Type uint16
+
+const (
+	ET_NONE   Type = 0      /* Unknown type. */
+	ET_REL    Type = 1      /* Relocatable. */
+	ET_EXEC   Type = 2      /* Executable. */
+	ET_DYN    Type = 3      /* Shared object. */
+	ET_CORE   Type = 4      /* Core file. */
+	ET_LOOS   Type = 0xfe00 /* First operating system specific. */
+	ET_HIOS   Type = 0xfeff /* Last operating system-specific. */
+	ET_LOPROC Type = 0xff00 /* First processor-specific. */
+	ET_HIPROC Type = 0xffff /* Last processor-specific. */
+)
+
+var typeStrings = []intName{
+	{0, "ET_NONE"},
+	{1, "ET_REL"},
+	{2, "ET_EXEC"},
+	{3, "ET_DYN"},
+	{4, "ET_CORE"},
+	{0xfe00, "ET_LOOS"},
+	{0xfeff, "ET_HIOS"},
+	{0xff00, "ET_LOPROC"},
+	{0xffff, "ET_HIPROC"},
+}
+
+func (i Type) String() string   { return stringName(uint32(i), typeStrings, false) }
+func (i Type) GoString() string { return stringName(uint32(i), typeStrings, true) }
+
+// Machine is found in Header.Machine.
+type Machine uint16
+
+const (
+	EM_NONE        Machine = 0   /* Unknown machine. */
+	EM_M32         Machine = 1   /* AT&T WE32100. */
+	EM_SPARC       Machine = 2   /* Sun SPARC. */
+	EM_386         Machine = 3   /* Intel i386. */
+	EM_68K         Machine = 4   /* Motorola 68000. */
+	EM_88K         Machine = 5   /* Motorola 88000. */
+	EM_860         Machine = 7   /* Intel i860. */
+	EM_MIPS        Machine = 8   /* MIPS R3000 Big-Endian only. */
+	EM_S370        Machine = 9   /* IBM System/370. */
+	EM_MIPS_RS3_LE Machine = 10  /* MIPS R3000 Little-Endian. */
+	EM_PARISC      Machine = 15  /* HP PA-RISC. */
+	EM_VPP500      Machine = 17  /* Fujitsu VPP500. */
+	EM_SPARC32PLUS Machine = 18  /* SPARC v8plus. */
+	EM_960         Machine = 19  /* Intel 80960. */
+	EM_PPC         Machine = 20  /* PowerPC 32-bit. */
+	EM_PPC64       Machine = 21  /* PowerPC 64-bit. */
+	EM_S390        Machine = 22  /* IBM System/390. */
+	EM_V800        Machine = 36  /* NEC V800. */
+	EM_FR20        Machine = 37  /* Fujitsu FR20. */
+	EM_RH32        Machine = 38  /* TRW RH-32. */
+	EM_RCE         Machine = 39  /* Motorola RCE. */
+	EM_ARM         Machine = 40  /* ARM. */
+	EM_SH          Machine = 42  /* Hitachi SH. */
+	EM_SPARCV9     Machine = 43  /* SPARC v9 64-bit. */
+	EM_TRICORE     Machine = 44  /* Siemens TriCore embedded processor. */
+	EM_ARC         Machine = 45  /* Argonaut RISC Core. */
+	EM_H8_300      Machine = 46  /* Hitachi H8/300. */
+	EM_H8_300H     Machine = 47  /* Hitachi H8/300H. */
+	EM_H8S         Machine = 48  /* Hitachi H8S. */
+	EM_H8_500      Machine = 49  /* Hitachi H8/500. */
+	EM_IA_64       Machine = 50  /* Intel IA-64 Processor. */
+	EM_MIPS_X      Machine = 51  /* Stanford MIPS-X. */
+	EM_COLDFIRE    Machine = 52  /* Motorola ColdFire. */
+	EM_68HC12      Machine = 53  /* Motorola M68HC12. */
+	EM_MMA         Machine = 54  /* Fujitsu MMA. */
+	EM_PCP         Machine = 55  /* Siemens PCP. */
+	EM_NCPU        Machine = 56  /* Sony nCPU. */
+	EM_NDR1        Machine = 57  /* Denso NDR1 microprocessor. */
+	EM_STARCORE    Machine = 58  /* Motorola Star*Core processor. */
+	EM_ME16        Machine = 59  /* Toyota ME16 processor. */
+	EM_ST100       Machine = 60  /* STMicroelectronics ST100 processor. */
+	EM_TINYJ       Machine = 61  /* Advanced Logic Corp. TinyJ processor. */
+	EM_X86_64      Machine = 62  /* Advanced Micro Devices x86-64 */
+	EM_AARCH64     Machine = 183 /* ARM 64-bit Architecture (AArch64) */
+
+	/* Non-standard or deprecated. */
+	EM_486         Machine = 6      /* Intel i486. */
+	EM_MIPS_RS4_BE Machine = 10     /* MIPS R4000 Big-Endian */
+	EM_ALPHA_STD   Machine = 41     /* Digital Alpha (standard value). */
+	EM_ALPHA       Machine = 0x9026 /* Alpha (written in the absence of an ABI) */
+)
+
+var machineStrings = []intName{
+	{0, "EM_NONE"},
+	{1, "EM_M32"},
+	{2, "EM_SPARC"},
+	{3, "EM_386"},
+	{4, "EM_68K"},
+	{5, "EM_88K"},
+	{7, "EM_860"},
+	{8, "EM_MIPS"},
+	{9, "EM_S370"},
+	{10, "EM_MIPS_RS3_LE"},
+	{15, "EM_PARISC"},
+	{17, "EM_VPP500"},
+	{18, "EM_SPARC32PLUS"},
+	{19, "EM_960"},
+	{20, "EM_PPC"},
+	{21, "EM_PPC64"},
+	{22, "EM_S390"},
+	{36, "EM_V800"},
+	{37, "EM_FR20"},
+	{38, "EM_RH32"},
+	{39, "EM_RCE"},
+	{40, "EM_ARM"},
+	{42, "EM_SH"},
+	{43, "EM_SPARCV9"},
+	{44, "EM_TRICORE"},
+	{45, "EM_ARC"},
+	{46, "EM_H8_300"},
+	{47, "EM_H8_300H"},
+	{48, "EM_H8S"},
+	{49, "EM_H8_500"},
+	{50, "EM_IA_64"},
+	{51, "EM_MIPS_X"},
+	{52, "EM_COLDFIRE"},
+	{53, "EM_68HC12"},
+	{54, "EM_MMA"},
+	{55, "EM_PCP"},
+	{56, "EM_NCPU"},
+	{57, "EM_NDR1"},
+	{58, "EM_STARCORE"},
+	{59, "EM_ME16"},
+	{60, "EM_ST100"},
+	{61, "EM_TINYJ"},
+	{62, "EM_X86_64"},
+
+	/* Non-standard or deprecated. */
+	{6, "EM_486"},
+	{10, "EM_MIPS_RS4_BE"},
+	{41, "EM_ALPHA_STD"},
+	{0x9026, "EM_ALPHA"},
+}
+
+func (i Machine) String() string   { return stringName(uint32(i), machineStrings, false) }
+func (i Machine) GoString() string { return stringName(uint32(i), machineStrings, true) }
+
+// Special section indices.
+type SectionIndex int
+
+const (
+	SHN_UNDEF     SectionIndex = 0      /* Undefined, missing, irrelevant. */
+	SHN_LORESERVE SectionIndex = 0xff00 /* First of reserved range. */
+	SHN_LOPROC    SectionIndex = 0xff00 /* First processor-specific. */
+	SHN_HIPROC    SectionIndex = 0xff1f /* Last processor-specific. */
+	SHN_LOOS      SectionIndex = 0xff20 /* First operating system-specific. */
+	SHN_HIOS      SectionIndex = 0xff3f /* Last operating system-specific. */
+	SHN_ABS       SectionIndex = 0xfff1 /* Absolute values. */
+	SHN_COMMON    SectionIndex = 0xfff2 /* Common data. */
+	SHN_XINDEX    SectionIndex = 0xffff /* Escape -- index stored elsewhere. */
+	SHN_HIRESERVE SectionIndex = 0xffff /* Last of reserved range. */
+)
+
+var shnStrings = []intName{
+	{0, "SHN_UNDEF"},
+	{0xff00, "SHN_LOPROC"},
+	{0xff20, "SHN_LOOS"},
+	{0xfff1, "SHN_ABS"},
+	{0xfff2, "SHN_COMMON"},
+	{0xffff, "SHN_XINDEX"},
+}
+
+func (i SectionIndex) String() string   { return stringName(uint32(i), shnStrings, false) }
+func (i SectionIndex) GoString() string { return stringName(uint32(i), shnStrings, true) }
+
+// Section type.
+type SectionType uint32
+
+const (
+	SHT_NULL           SectionType = 0          /* inactive */
+	SHT_PROGBITS       SectionType = 1          /* program defined information */
+	SHT_SYMTAB         SectionType = 2          /* symbol table section */
+	SHT_STRTAB         SectionType = 3          /* string table section */
+	SHT_RELA           SectionType = 4          /* relocation section with addends */
+	SHT_HASH           SectionType = 5          /* symbol hash table section */
+	SHT_DYNAMIC        SectionType = 6          /* dynamic section */
+	SHT_NOTE           SectionType = 7          /* note section */
+	SHT_NOBITS         SectionType = 8          /* no space section */
+	SHT_REL            SectionType = 9          /* relocation section - no addends */
+	SHT_SHLIB          SectionType = 10         /* reserved - purpose unknown */
+	SHT_DYNSYM         SectionType = 11         /* dynamic symbol table section */
+	SHT_INIT_ARRAY     SectionType = 14         /* Initialization function pointers. */
+	SHT_FINI_ARRAY     SectionType = 15         /* Termination function pointers. */
+	SHT_PREINIT_ARRAY  SectionType = 16         /* Pre-initialization function ptrs. */
+	SHT_GROUP          SectionType = 17         /* Section group. */
+	SHT_SYMTAB_SHNDX   SectionType = 18         /* Section indexes (see SHN_XINDEX). */
+	SHT_LOOS           SectionType = 0x60000000 /* First of OS specific semantics */
+	SHT_GNU_ATTRIBUTES SectionType = 0x6ffffff5 /* GNU object attributes */
+	SHT_GNU_HASH       SectionType = 0x6ffffff6 /* GNU hash table */
+	SHT_GNU_LIBLIST    SectionType = 0x6ffffff7 /* GNU prelink library list */
+	SHT_GNU_VERDEF     SectionType = 0x6ffffffd /* GNU version definition section */
+	SHT_GNU_VERNEED    SectionType = 0x6ffffffe /* GNU version needs section */
+	SHT_GNU_VERSYM     SectionType = 0x6fffffff /* GNU version symbol table */
+	SHT_HIOS           SectionType = 0x6fffffff /* Last of OS specific semantics */
+	SHT_LOPROC         SectionType = 0x70000000 /* reserved range for processor */
+	SHT_HIPROC         SectionType = 0x7fffffff /* specific section header types */
+	SHT_LOUSER         SectionType = 0x80000000 /* reserved range for application */
+	SHT_HIUSER         SectionType = 0xffffffff /* specific indexes */
+)
+
+var shtStrings = []intName{
+	{0, "SHT_NULL"},
+	{1, "SHT_PROGBITS"},
+	{2, "SHT_SYMTAB"},
+	{3, "SHT_STRTAB"},
+	{4, "SHT_RELA"},
+	{5, "SHT_HASH"},
+	{6, "SHT_DYNAMIC"},
+	{7, "SHT_NOTE"},
+	{8, "SHT_NOBITS"},
+	{9, "SHT_REL"},
+	{10, "SHT_SHLIB"},
+	{11, "SHT_DYNSYM"},
+	{14, "SHT_INIT_ARRAY"},
+	{15, "SHT_FINI_ARRAY"},
+	{16, "SHT_PREINIT_ARRAY"},
+	{17, "SHT_GROUP"},
+	{18, "SHT_SYMTAB_SHNDX"},
+	{0x60000000, "SHT_LOOS"},
+	{0x6ffffff5, "SHT_GNU_ATTRIBUTES"},
+	{0x6ffffff6, "SHT_GNU_HASH"},
+	{0x6ffffff7, "SHT_GNU_LIBLIST"},
+	{0x6ffffffd, "SHT_GNU_VERDEF"},
+	{0x6ffffffe, "SHT_GNU_VERNEED"},
+	{0x6fffffff, "SHT_GNU_VERSYM"},
+	{0x70000000, "SHT_LOPROC"},
+	{0x7fffffff, "SHT_HIPROC"},
+	{0x80000000, "SHT_LOUSER"},
+	{0xffffffff, "SHT_HIUSER"},
+}
+
+func (i SectionType) String() string   { return stringName(uint32(i), shtStrings, false) }
+func (i SectionType) GoString() string { return stringName(uint32(i), shtStrings, true) }
+
+// Section flags.
+type SectionFlag uint32
+
+const (
+	SHF_WRITE            SectionFlag = 0x1        /* Section contains writable data. */
+	SHF_ALLOC            SectionFlag = 0x2        /* Section occupies memory. */
+	SHF_EXECINSTR        SectionFlag = 0x4        /* Section contains instructions. */
+	SHF_MERGE            SectionFlag = 0x10       /* Section may be merged. */
+	SHF_STRINGS          SectionFlag = 0x20       /* Section contains strings. */
+	SHF_INFO_LINK        SectionFlag = 0x40       /* sh_info holds section index. */
+	SHF_LINK_ORDER       SectionFlag = 0x80       /* Special ordering requirements. */
+	SHF_OS_NONCONFORMING SectionFlag = 0x100      /* OS-specific processing required. */
+	SHF_GROUP            SectionFlag = 0x200      /* Member of section group. */
+	SHF_TLS              SectionFlag = 0x400      /* Section contains TLS data. */
+	SHF_MASKOS           SectionFlag = 0x0ff00000 /* OS-specific semantics. */
+	SHF_MASKPROC         SectionFlag = 0xf0000000 /* Processor-specific semantics. */
+)
+
+var shfStrings = []intName{
+	{0x1, "SHF_WRITE"},
+	{0x2, "SHF_ALLOC"},
+	{0x4, "SHF_EXECINSTR"},
+	{0x10, "SHF_MERGE"},
+	{0x20, "SHF_STRINGS"},
+	{0x40, "SHF_INFO_LINK"},
+	{0x80, "SHF_LINK_ORDER"},
+	{0x100, "SHF_OS_NONCONFORMING"},
+	{0x200, "SHF_GROUP"},
+	{0x400, "SHF_TLS"},
+}
+
+func (i SectionFlag) String() string   { return flagName(uint32(i), shfStrings, false) }
+func (i SectionFlag) GoString() string { return flagName(uint32(i), shfStrings, true) }
+
+// Prog.Type
+type ProgType int
+
+const (
+	PT_NULL    ProgType = 0          /* Unused entry. */
+	PT_LOAD    ProgType = 1          /* Loadable segment. */
+	PT_DYNAMIC ProgType = 2          /* Dynamic linking information segment. */
+	PT_INTERP  ProgType = 3          /* Pathname of interpreter. */
+	PT_NOTE    ProgType = 4          /* Auxiliary information. */
+	PT_SHLIB   ProgType = 5          /* Reserved (not used). */
+	PT_PHDR    ProgType = 6          /* Location of program header itself. */
+	PT_TLS     ProgType = 7          /* Thread local storage segment */
+	PT_LOOS    ProgType = 0x60000000 /* First OS-specific. */
+	PT_HIOS    ProgType = 0x6fffffff /* Last OS-specific. */
+	PT_LOPROC  ProgType = 0x70000000 /* First processor-specific type. */
+	PT_HIPROC  ProgType = 0x7fffffff /* Last processor-specific type. */
+)
+
+var ptStrings = []intName{
+	{0, "PT_NULL"},
+	{1, "PT_LOAD"},
+	{2, "PT_DYNAMIC"},
+	{3, "PT_INTERP"},
+	{4, "PT_NOTE"},
+	{5, "PT_SHLIB"},
+	{6, "PT_PHDR"},
+	{7, "PT_TLS"},
+	{0x60000000, "PT_LOOS"},
+	{0x6fffffff, "PT_HIOS"},
+	{0x70000000, "PT_LOPROC"},
+	{0x7fffffff, "PT_HIPROC"},
+}
+
+func (i ProgType) String() string   { return stringName(uint32(i), ptStrings, false) }
+func (i ProgType) GoString() string { return stringName(uint32(i), ptStrings, true) }
+
+// Prog.Flag
+type ProgFlag uint32
+
+const (
+	PF_X        ProgFlag = 0x1        /* Executable. */
+	PF_W        ProgFlag = 0x2        /* Writable. */
+	PF_R        ProgFlag = 0x4        /* Readable. */
+	PF_MASKOS   ProgFlag = 0x0ff00000 /* Operating system-specific. */
+	PF_MASKPROC ProgFlag = 0xf0000000 /* Processor-specific. */
+)
+
+var pfStrings = []intName{
+	{0x1, "PF_X"},
+	{0x2, "PF_W"},
+	{0x4, "PF_R"},
+}
+
+func (i ProgFlag) String() string   { return flagName(uint32(i), pfStrings, false) }
+func (i ProgFlag) GoString() string { return flagName(uint32(i), pfStrings, true) }
+
+// Dyn.Tag
+type DynTag int
+
+const (
+	DT_NULL         DynTag = 0  /* Terminating entry. */
+	DT_NEEDED       DynTag = 1  /* String table offset of a needed shared library. */
+	DT_PLTRELSZ     DynTag = 2  /* Total size in bytes of PLT relocations. */
+	DT_PLTGOT       DynTag = 3  /* Processor-dependent address. */
+	DT_HASH         DynTag = 4  /* Address of symbol hash table. */
+	DT_STRTAB       DynTag = 5  /* Address of string table. */
+	DT_SYMTAB       DynTag = 6  /* Address of symbol table. */
+	DT_RELA         DynTag = 7  /* Address of ElfNN_Rela relocations. */
+	DT_RELASZ       DynTag = 8  /* Total size of ElfNN_Rela relocations. */
+	DT_RELAENT      DynTag = 9  /* Size of each ElfNN_Rela relocation entry. */
+	DT_STRSZ        DynTag = 10 /* Size of string table. */
+	DT_SYMENT       DynTag = 11 /* Size of each symbol table entry. */
+	DT_INIT         DynTag = 12 /* Address of initialization function. */
+	DT_FINI         DynTag = 13 /* Address of finalization function. */
+	DT_SONAME       DynTag = 14 /* String table offset of shared object name. */
+	DT_RPATH        DynTag = 15 /* String table offset of library path. [sup] */
+	DT_SYMBOLIC     DynTag = 16 /* Indicates "symbolic" linking. [sup] */
+	DT_REL          DynTag = 17 /* Address of ElfNN_Rel relocations. */
+	DT_RELSZ        DynTag = 18 /* Total size of ElfNN_Rel relocations. */
+	DT_RELENT       DynTag = 19 /* Size of each ElfNN_Rel relocation. */
+	DT_PLTREL       DynTag = 20 /* Type of relocation used for PLT. */
+	DT_DEBUG        DynTag = 21 /* Reserved (not used). */
+	DT_TEXTREL      DynTag = 22 /* Indicates there may be relocations in non-writable segments. [sup] */
+	DT_JMPREL       DynTag = 23 /* Address of PLT relocations. */
+	DT_BIND_NOW     DynTag = 24 /* [sup] */
+	DT_INIT_ARRAY   DynTag = 25 /* Address of the array of pointers to initialization functions */
+	DT_FINI_ARRAY   DynTag = 26 /* Address of the array of pointers to termination functions */
+	DT_INIT_ARRAYSZ DynTag = 27 /* Size in bytes of the array of initialization functions. */
+	DT_FINI_ARRAYSZ DynTag = 28 /* Size in bytes of the array of termination functions. */
+	DT_RUNPATH      DynTag = 29 /* String table offset of a null-terminated library search path string. */
+	DT_FLAGS        DynTag = 30 /* Object specific flag values. */
+	DT_ENCODING     DynTag = 32 /* Values greater than or equal to DT_ENCODING
+	   and less than DT_LOOS follow the rules for
+	   the interpretation of the d_un union
+	   as follows: even == 'd_ptr', even == 'd_val'
+	   or none */
+	DT_PREINIT_ARRAY   DynTag = 32         /* Address of the array of pointers to pre-initialization functions. */
+	DT_PREINIT_ARRAYSZ DynTag = 33         /* Size in bytes of the array of pre-initialization functions. */
+	DT_LOOS            DynTag = 0x6000000d /* First OS-specific */
+	DT_HIOS            DynTag = 0x6ffff000 /* Last OS-specific */
+	DT_VERSYM          DynTag = 0x6ffffff0
+	DT_VERNEED         DynTag = 0x6ffffffe
+	DT_VERNEEDNUM      DynTag = 0x6fffffff
+	DT_LOPROC          DynTag = 0x70000000 /* First processor-specific type. */
+	DT_HIPROC          DynTag = 0x7fffffff /* Last processor-specific type. */
+)
+
+var dtStrings = []intName{
+	{0, "DT_NULL"},
+	{1, "DT_NEEDED"},
+	{2, "DT_PLTRELSZ"},
+	{3, "DT_PLTGOT"},
+	{4, "DT_HASH"},
+	{5, "DT_STRTAB"},
+	{6, "DT_SYMTAB"},
+	{7, "DT_RELA"},
+	{8, "DT_RELASZ"},
+	{9, "DT_RELAENT"},
+	{10, "DT_STRSZ"},
+	{11, "DT_SYMENT"},
+	{12, "DT_INIT"},
+	{13, "DT_FINI"},
+	{14, "DT_SONAME"},
+	{15, "DT_RPATH"},
+	{16, "DT_SYMBOLIC"},
+	{17, "DT_REL"},
+	{18, "DT_RELSZ"},
+	{19, "DT_RELENT"},
+	{20, "DT_PLTREL"},
+	{21, "DT_DEBUG"},
+	{22, "DT_TEXTREL"},
+	{23, "DT_JMPREL"},
+	{24, "DT_BIND_NOW"},
+	{25, "DT_INIT_ARRAY"},
+	{26, "DT_FINI_ARRAY"},
+	{27, "DT_INIT_ARRAYSZ"},
+	{28, "DT_FINI_ARRAYSZ"},
+	{29, "DT_RUNPATH"},
+	{30, "DT_FLAGS"},
+	{32, "DT_ENCODING"},
+	{32, "DT_PREINIT_ARRAY"},
+	{33, "DT_PREINIT_ARRAYSZ"},
+	{0x6000000d, "DT_LOOS"},
+	{0x6ffff000, "DT_HIOS"},
+	{0x6ffffff0, "DT_VERSYM"},
+	{0x6ffffffe, "DT_VERNEED"},
+	{0x6fffffff, "DT_VERNEEDNUM"},
+	{0x70000000, "DT_LOPROC"},
+	{0x7fffffff, "DT_HIPROC"},
+}
+
+func (i DynTag) String() string   { return stringName(uint32(i), dtStrings, false) }
+func (i DynTag) GoString() string { return stringName(uint32(i), dtStrings, true) }
+
+// DT_FLAGS values.
+type DynFlag int
+
+const (
+	DF_ORIGIN DynFlag = 0x0001 /* Indicates that the object being loaded may
+	   make reference to the
+	   $ORIGIN substitution string */
+	DF_SYMBOLIC DynFlag = 0x0002 /* Indicates "symbolic" linking. */
+	DF_TEXTREL  DynFlag = 0x0004 /* Indicates there may be relocations in non-writable segments. */
+	DF_BIND_NOW DynFlag = 0x0008 /* Indicates that the dynamic linker should
+	   process all relocations for the object
+	   containing this entry before transferring
+	   control to the program. */
+	DF_STATIC_TLS DynFlag = 0x0010 /* Indicates that the shared object or
+	   executable contains code using a static
+	   thread-local storage scheme. */
+)
+
+var dflagStrings = []intName{
+	{0x0001, "DF_ORIGIN"},
+	{0x0002, "DF_SYMBOLIC"},
+	{0x0004, "DF_TEXTREL"},
+	{0x0008, "DF_BIND_NOW"},
+	{0x0010, "DF_STATIC_TLS"},
+}
+
+func (i DynFlag) String() string   { return flagName(uint32(i), dflagStrings, false) }
+func (i DynFlag) GoString() string { return flagName(uint32(i), dflagStrings, true) }
+
+// NType values; used in core files.
+type NType int
+
+const (
+	NT_PRSTATUS NType = 1 /* Process status. */
+	NT_FPREGSET NType = 2 /* Floating point registers. */
+	NT_PRPSINFO NType = 3 /* Process state info. */
+)
+
+var ntypeStrings = []intName{
+	{1, "NT_PRSTATUS"},
+	{2, "NT_FPREGSET"},
+	{3, "NT_PRPSINFO"},
+}
+
+func (i NType) String() string   { return stringName(uint32(i), ntypeStrings, false) }
+func (i NType) GoString() string { return stringName(uint32(i), ntypeStrings, true) }
+
+/* Symbol Binding - ELFNN_ST_BIND - st_info */
+type SymBind int
+
+const (
+	STB_LOCAL  SymBind = 0  /* Local symbol */
+	STB_GLOBAL SymBind = 1  /* Global symbol */
+	STB_WEAK   SymBind = 2  /* like global - lower precedence */
+	STB_LOOS   SymBind = 10 /* Reserved range for operating system */
+	STB_HIOS   SymBind = 12 /*   specific semantics. */
+	STB_LOPROC SymBind = 13 /* reserved range for processor */
+	STB_HIPROC SymBind = 15 /*   specific semantics. */
+)
+
+var stbStrings = []intName{
+	{0, "STB_LOCAL"},
+	{1, "STB_GLOBAL"},
+	{2, "STB_WEAK"},
+	{10, "STB_LOOS"},
+	{12, "STB_HIOS"},
+	{13, "STB_LOPROC"},
+	{15, "STB_HIPROC"},
+}
+
+func (i SymBind) String() string   { return stringName(uint32(i), stbStrings, false) }
+func (i SymBind) GoString() string { return stringName(uint32(i), stbStrings, true) }
+
+/* Symbol type - ELFNN_ST_TYPE - st_info */
+type SymType int
+
+const (
+	STT_NOTYPE  SymType = 0  /* Unspecified type. */
+	STT_OBJECT  SymType = 1  /* Data object. */
+	STT_FUNC    SymType = 2  /* Function. */
+	STT_SECTION SymType = 3  /* Section. */
+	STT_FILE    SymType = 4  /* Source file. */
+	STT_COMMON  SymType = 5  /* Uninitialized common block. */
+	STT_TLS     SymType = 6  /* TLS object. */
+	STT_LOOS    SymType = 10 /* Reserved range for operating system */
+	STT_HIOS    SymType = 12 /*   specific semantics. */
+	STT_LOPROC  SymType = 13 /* reserved range for processor */
+	STT_HIPROC  SymType = 15 /*   specific semantics. */
+)
+
+var sttStrings = []intName{
+	{0, "STT_NOTYPE"},
+	{1, "STT_OBJECT"},
+	{2, "STT_FUNC"},
+	{3, "STT_SECTION"},
+	{4, "STT_FILE"},
+	{5, "STT_COMMON"},
+	{6, "STT_TLS"},
+	{10, "STT_LOOS"},
+	{12, "STT_HIOS"},
+	{13, "STT_LOPROC"},
+	{15, "STT_HIPROC"},
+}
+
+func (i SymType) String() string   { return stringName(uint32(i), sttStrings, false) }
+func (i SymType) GoString() string { return stringName(uint32(i), sttStrings, true) }
+
+/* Symbol visibility - ELFNN_ST_VISIBILITY - st_other */
+type SymVis int
+
+const (
+	STV_DEFAULT   SymVis = 0x0 /* Default visibility (see binding). */
+	STV_INTERNAL  SymVis = 0x1 /* Special meaning in relocatable objects. */
+	STV_HIDDEN    SymVis = 0x2 /* Not visible. */
+	STV_PROTECTED SymVis = 0x3 /* Visible but not preemptible. */
+)
+
+var stvStrings = []intName{
+	{0x0, "STV_DEFAULT"},
+	{0x1, "STV_INTERNAL"},
+	{0x2, "STV_HIDDEN"},
+	{0x3, "STV_PROTECTED"},
+}
+
+func (i SymVis) String() string   { return stringName(uint32(i), stvStrings, false) }
+func (i SymVis) GoString() string { return stringName(uint32(i), stvStrings, true) }
+
+/*
+ * Relocation types.
+ */
+
+// Relocation types for x86-64.
+type R_X86_64 int
+
+const (
+	R_X86_64_NONE     R_X86_64 = 0  /* No relocation. */
+	R_X86_64_64       R_X86_64 = 1  /* Add 64 bit symbol value. */
+	R_X86_64_PC32     R_X86_64 = 2  /* PC-relative 32 bit signed sym value. */
+	R_X86_64_GOT32    R_X86_64 = 3  /* PC-relative 32 bit GOT offset. */
+	R_X86_64_PLT32    R_X86_64 = 4  /* PC-relative 32 bit PLT offset. */
+	R_X86_64_COPY     R_X86_64 = 5  /* Copy data from shared object. */
+	R_X86_64_GLOB_DAT R_X86_64 = 6  /* Set GOT entry to data address. */
+	R_X86_64_JMP_SLOT R_X86_64 = 7  /* Set GOT entry to code address. */
+	R_X86_64_RELATIVE R_X86_64 = 8  /* Add load address of shared object. */
+	R_X86_64_GOTPCREL R_X86_64 = 9  /* Add 32 bit signed pcrel offset to GOT. */
+	R_X86_64_32       R_X86_64 = 10 /* Add 32 bit zero extended symbol value */
+	R_X86_64_32S      R_X86_64 = 11 /* Add 32 bit sign extended symbol value */
+	R_X86_64_16       R_X86_64 = 12 /* Add 16 bit zero extended symbol value */
+	R_X86_64_PC16     R_X86_64 = 13 /* Add 16 bit signed extended pc relative symbol value */
+	R_X86_64_8        R_X86_64 = 14 /* Add 8 bit zero extended symbol value */
+	R_X86_64_PC8      R_X86_64 = 15 /* Add 8 bit signed extended pc relative symbol value */
+	R_X86_64_DTPMOD64 R_X86_64 = 16 /* ID of module containing symbol */
+	R_X86_64_DTPOFF64 R_X86_64 = 17 /* Offset in TLS block */
+	R_X86_64_TPOFF64  R_X86_64 = 18 /* Offset in static TLS block */
+	R_X86_64_TLSGD    R_X86_64 = 19 /* PC relative offset to GD GOT entry */
+	R_X86_64_TLSLD    R_X86_64 = 20 /* PC relative offset to LD GOT entry */
+	R_X86_64_DTPOFF32 R_X86_64 = 21 /* Offset in TLS block */
+	R_X86_64_GOTTPOFF R_X86_64 = 22 /* PC relative offset to IE GOT entry */
+	R_X86_64_TPOFF32  R_X86_64 = 23 /* Offset in static TLS block */
+)
+
+var rx86_64Strings = []intName{
+	{0, "R_X86_64_NONE"},
+	{1, "R_X86_64_64"},
+	{2, "R_X86_64_PC32"},
+	{3, "R_X86_64_GOT32"},
+	{4, "R_X86_64_PLT32"},
+	{5, "R_X86_64_COPY"},
+	{6, "R_X86_64_GLOB_DAT"},
+	{7, "R_X86_64_JMP_SLOT"},
+	{8, "R_X86_64_RELATIVE"},
+	{9, "R_X86_64_GOTPCREL"},
+	{10, "R_X86_64_32"},
+	{11, "R_X86_64_32S"},
+	{12, "R_X86_64_16"},
+	{13, "R_X86_64_PC16"},
+	{14, "R_X86_64_8"},
+	{15, "R_X86_64_PC8"},
+	{16, "R_X86_64_DTPMOD64"},
+	{17, "R_X86_64_DTPOFF64"},
+	{18, "R_X86_64_TPOFF64"},
+	{19, "R_X86_64_TLSGD"},
+	{20, "R_X86_64_TLSLD"},
+	{21, "R_X86_64_DTPOFF32"},
+	{22, "R_X86_64_GOTTPOFF"},
+	{23, "R_X86_64_TPOFF32"},
+}
+
+func (i R_X86_64) String() string   { return stringName(uint32(i), rx86_64Strings, false) }
+func (i R_X86_64) GoString() string { return stringName(uint32(i), rx86_64Strings, true) }
+
+// Relocation types for AArch64 (aka arm64)
+type R_AARCH64 int
+
+const (
+	R_AARCH64_NONE                            R_AARCH64 = 0
+	R_AARCH64_P32_ABS32                       R_AARCH64 = 1
+	R_AARCH64_P32_ABS16                       R_AARCH64 = 2
+	R_AARCH64_P32_PREL32                      R_AARCH64 = 3
+	R_AARCH64_P32_PREL16                      R_AARCH64 = 4
+	R_AARCH64_P32_MOVW_UABS_G0                R_AARCH64 = 5
+	R_AARCH64_P32_MOVW_UABS_G0_NC             R_AARCH64 = 6
+	R_AARCH64_P32_MOVW_UABS_G1                R_AARCH64 = 7
+	R_AARCH64_P32_MOVW_SABS_G0                R_AARCH64 = 8
+	R_AARCH64_P32_LD_PREL_LO19                R_AARCH64 = 9
+	R_AARCH64_P32_ADR_PREL_LO21               R_AARCH64 = 10
+	R_AARCH64_P32_ADR_PREL_PG_HI21            R_AARCH64 = 11
+	R_AARCH64_P32_ADD_ABS_LO12_NC             R_AARCH64 = 12
+	R_AARCH64_P32_LDST8_ABS_LO12_NC           R_AARCH64 = 13
+	R_AARCH64_P32_LDST16_ABS_LO12_NC          R_AARCH64 = 14
+	R_AARCH64_P32_LDST32_ABS_LO12_NC          R_AARCH64 = 15
+	R_AARCH64_P32_LDST64_ABS_LO12_NC          R_AARCH64 = 16
+	R_AARCH64_P32_LDST128_ABS_LO12_NC         R_AARCH64 = 17
+	R_AARCH64_P32_TSTBR14                     R_AARCH64 = 18
+	R_AARCH64_P32_CONDBR19                    R_AARCH64 = 19
+	R_AARCH64_P32_JUMP26                      R_AARCH64 = 20
+	R_AARCH64_P32_CALL26                      R_AARCH64 = 21
+	R_AARCH64_P32_GOT_LD_PREL19               R_AARCH64 = 25
+	R_AARCH64_P32_ADR_GOT_PAGE                R_AARCH64 = 26
+	R_AARCH64_P32_LD32_GOT_LO12_NC            R_AARCH64 = 27
+	R_AARCH64_P32_TLSGD_ADR_PAGE21            R_AARCH64 = 81
+	R_AARCH64_P32_TLSGD_ADD_LO12_NC           R_AARCH64 = 82
+	R_AARCH64_P32_TLSIE_ADR_GOTTPREL_PAGE21   R_AARCH64 = 103
+	R_AARCH64_P32_TLSIE_LD32_GOTTPREL_LO12_NC R_AARCH64 = 104
+	R_AARCH64_P32_TLSIE_LD_GOTTPREL_PREL19    R_AARCH64 = 105
+	R_AARCH64_P32_TLSLE_MOVW_TPREL_G1         R_AARCH64 = 106
+	R_AARCH64_P32_TLSLE_MOVW_TPREL_G0         R_AARCH64 = 107
+	R_AARCH64_P32_TLSLE_MOVW_TPREL_G0_NC      R_AARCH64 = 108
+	R_AARCH64_P32_TLSLE_ADD_TPREL_HI12        R_AARCH64 = 109
+	R_AARCH64_P32_TLSLE_ADD_TPREL_LO12        R_AARCH64 = 110
+	R_AARCH64_P32_TLSLE_ADD_TPREL_LO12_NC     R_AARCH64 = 111
+	R_AARCH64_P32_TLSDESC_LD_PREL19           R_AARCH64 = 122
+	R_AARCH64_P32_TLSDESC_ADR_PREL21          R_AARCH64 = 123
+	R_AARCH64_P32_TLSDESC_ADR_PAGE21          R_AARCH64 = 124
+	R_AARCH64_P32_TLSDESC_LD32_LO12_NC        R_AARCH64 = 125
+	R_AARCH64_P32_TLSDESC_ADD_LO12_NC         R_AARCH64 = 126
+	R_AARCH64_P32_TLSDESC_CALL                R_AARCH64 = 127
+	R_AARCH64_P32_COPY                        R_AARCH64 = 180
+	R_AARCH64_P32_GLOB_DAT                    R_AARCH64 = 181
+	R_AARCH64_P32_JUMP_SLOT                   R_AARCH64 = 182
+	R_AARCH64_P32_RELATIVE                    R_AARCH64 = 183
+	R_AARCH64_P32_TLS_DTPMOD                  R_AARCH64 = 184
+	R_AARCH64_P32_TLS_DTPREL                  R_AARCH64 = 185
+	R_AARCH64_P32_TLS_TPREL                   R_AARCH64 = 186
+	R_AARCH64_P32_TLSDESC                     R_AARCH64 = 187
+	R_AARCH64_P32_IRELATIVE                   R_AARCH64 = 188
+	R_AARCH64_NULL                            R_AARCH64 = 256
+	R_AARCH64_ABS64                           R_AARCH64 = 257
+	R_AARCH64_ABS32                           R_AARCH64 = 258
+	R_AARCH64_ABS16                           R_AARCH64 = 259
+	R_AARCH64_PREL64                          R_AARCH64 = 260
+	R_AARCH64_PREL32                          R_AARCH64 = 261
+	R_AARCH64_PREL16                          R_AARCH64 = 262
+	R_AARCH64_MOVW_UABS_G0                    R_AARCH64 = 263
+	R_AARCH64_MOVW_UABS_G0_NC                 R_AARCH64 = 264
+	R_AARCH64_MOVW_UABS_G1                    R_AARCH64 = 265
+	R_AARCH64_MOVW_UABS_G1_NC                 R_AARCH64 = 266
+	R_AARCH64_MOVW_UABS_G2                    R_AARCH64 = 267
+	R_AARCH64_MOVW_UABS_G2_NC                 R_AARCH64 = 268
+	R_AARCH64_MOVW_UABS_G3                    R_AARCH64 = 269
+	R_AARCH64_MOVW_SABS_G0                    R_AARCH64 = 270
+	R_AARCH64_MOVW_SABS_G1                    R_AARCH64 = 271
+	R_AARCH64_MOVW_SABS_G2                    R_AARCH64 = 272
+	R_AARCH64_LD_PREL_LO19                    R_AARCH64 = 273
+	R_AARCH64_ADR_PREL_LO21                   R_AARCH64 = 274
+	R_AARCH64_ADR_PREL_PG_HI21                R_AARCH64 = 275
+	R_AARCH64_ADR_PREL_PG_HI21_NC             R_AARCH64 = 276
+	R_AARCH64_ADD_ABS_LO12_NC                 R_AARCH64 = 277
+	R_AARCH64_LDST8_ABS_LO12_NC               R_AARCH64 = 278
+	R_AARCH64_TSTBR14                         R_AARCH64 = 279
+	R_AARCH64_CONDBR19                        R_AARCH64 = 280
+	R_AARCH64_JUMP26                          R_AARCH64 = 282
+	R_AARCH64_CALL26                          R_AARCH64 = 283
+	R_AARCH64_LDST16_ABS_LO12_NC              R_AARCH64 = 284
+	R_AARCH64_LDST32_ABS_LO12_NC              R_AARCH64 = 285
+	R_AARCH64_LDST64_ABS_LO12_NC              R_AARCH64 = 286
+	R_AARCH64_LDST128_ABS_LO12_NC             R_AARCH64 = 299
+	R_AARCH64_GOT_LD_PREL19                   R_AARCH64 = 309
+	R_AARCH64_ADR_GOT_PAGE                    R_AARCH64 = 311
+	R_AARCH64_LD64_GOT_LO12_NC                R_AARCH64 = 312
+	R_AARCH64_TLSGD_ADR_PAGE21                R_AARCH64 = 513
+	R_AARCH64_TLSGD_ADD_LO12_NC               R_AARCH64 = 514
+	R_AARCH64_TLSIE_MOVW_GOTTPREL_G1          R_AARCH64 = 539
+	R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC       R_AARCH64 = 540
+	R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21       R_AARCH64 = 541
+	R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC     R_AARCH64 = 542
+	R_AARCH64_TLSIE_LD_GOTTPREL_PREL19        R_AARCH64 = 543
+	R_AARCH64_TLSLE_MOVW_TPREL_G2             R_AARCH64 = 544
+	R_AARCH64_TLSLE_MOVW_TPREL_G1             R_AARCH64 = 545
+	R_AARCH64_TLSLE_MOVW_TPREL_G1_NC          R_AARCH64 = 546
+	R_AARCH64_TLSLE_MOVW_TPREL_G0             R_AARCH64 = 547
+	R_AARCH64_TLSLE_MOVW_TPREL_G0_NC          R_AARCH64 = 548
+	R_AARCH64_TLSLE_ADD_TPREL_HI12            R_AARCH64 = 549
+	R_AARCH64_TLSLE_ADD_TPREL_LO12            R_AARCH64 = 550
+	R_AARCH64_TLSLE_ADD_TPREL_LO12_NC         R_AARCH64 = 551
+	R_AARCH64_TLSDESC_LD_PREL19               R_AARCH64 = 560
+	R_AARCH64_TLSDESC_ADR_PREL21              R_AARCH64 = 561
+	R_AARCH64_TLSDESC_ADR_PAGE21              R_AARCH64 = 562
+	R_AARCH64_TLSDESC_LD64_LO12_NC            R_AARCH64 = 563
+	R_AARCH64_TLSDESC_ADD_LO12_NC             R_AARCH64 = 564
+	R_AARCH64_TLSDESC_OFF_G1                  R_AARCH64 = 565
+	R_AARCH64_TLSDESC_OFF_G0_NC               R_AARCH64 = 566
+	R_AARCH64_TLSDESC_LDR                     R_AARCH64 = 567
+	R_AARCH64_TLSDESC_ADD                     R_AARCH64 = 568
+	R_AARCH64_TLSDESC_CALL                    R_AARCH64 = 569
+	R_AARCH64_COPY                            R_AARCH64 = 1024
+	R_AARCH64_GLOB_DAT                        R_AARCH64 = 1025
+	R_AARCH64_JUMP_SLOT                       R_AARCH64 = 1026
+	R_AARCH64_RELATIVE                        R_AARCH64 = 1027
+	R_AARCH64_TLS_DTPMOD64                    R_AARCH64 = 1028
+	R_AARCH64_TLS_DTPREL64                    R_AARCH64 = 1029
+	R_AARCH64_TLS_TPREL64                     R_AARCH64 = 1030
+	R_AARCH64_TLSDESC                         R_AARCH64 = 1031
+	R_AARCH64_IRELATIVE                       R_AARCH64 = 1032
+)
+
+var raarch64Strings = []intName{
+	{0, "R_AARCH64_NONE"},
+	{1, "R_AARCH64_P32_ABS32"},
+	{2, "R_AARCH64_P32_ABS16"},
+	{3, "R_AARCH64_P32_PREL32"},
+	{4, "R_AARCH64_P32_PREL16"},
+	{5, "R_AARCH64_P32_MOVW_UABS_G0"},
+	{6, "R_AARCH64_P32_MOVW_UABS_G0_NC"},
+	{7, "R_AARCH64_P32_MOVW_UABS_G1"},
+	{8, "R_AARCH64_P32_MOVW_SABS_G0"},
+	{9, "R_AARCH64_P32_LD_PREL_LO19"},
+	{10, "R_AARCH64_P32_ADR_PREL_LO21"},
+	{11, "R_AARCH64_P32_ADR_PREL_PG_HI21"},
+	{12, "R_AARCH64_P32_ADD_ABS_LO12_NC"},
+	{13, "R_AARCH64_P32_LDST8_ABS_LO12_NC"},
+	{14, "R_AARCH64_P32_LDST16_ABS_LO12_NC"},
+	{15, "R_AARCH64_P32_LDST32_ABS_LO12_NC"},
+	{16, "R_AARCH64_P32_LDST64_ABS_LO12_NC"},
+	{17, "R_AARCH64_P32_LDST128_ABS_LO12_NC"},
+	{18, "R_AARCH64_P32_TSTBR14"},
+	{19, "R_AARCH64_P32_CONDBR19"},
+	{20, "R_AARCH64_P32_JUMP26"},
+	{21, "R_AARCH64_P32_CALL26"},
+	{25, "R_AARCH64_P32_GOT_LD_PREL19"},
+	{26, "R_AARCH64_P32_ADR_GOT_PAGE"},
+	{27, "R_AARCH64_P32_LD32_GOT_LO12_NC"},
+	{81, "R_AARCH64_P32_TLSGD_ADR_PAGE21"},
+	{82, "R_AARCH64_P32_TLSGD_ADD_LO12_NC"},
+	{103, "R_AARCH64_P32_TLSIE_ADR_GOTTPREL_PAGE21"},
+	{104, "R_AARCH64_P32_TLSIE_LD32_GOTTPREL_LO12_NC"},
+	{105, "R_AARCH64_P32_TLSIE_LD_GOTTPREL_PREL19"},
+	{106, "R_AARCH64_P32_TLSLE_MOVW_TPREL_G1"},
+	{107, "R_AARCH64_P32_TLSLE_MOVW_TPREL_G0"},
+	{108, "R_AARCH64_P32_TLSLE_MOVW_TPREL_G0_NC"},
+	{109, "R_AARCH64_P32_TLSLE_ADD_TPREL_HI12"},
+	{110, "R_AARCH64_P32_TLSLE_ADD_TPREL_LO12"},
+	{111, "R_AARCH64_P32_TLSLE_ADD_TPREL_LO12_NC"},
+	{122, "R_AARCH64_P32_TLSDESC_LD_PREL19"},
+	{123, "R_AARCH64_P32_TLSDESC_ADR_PREL21"},
+	{124, "R_AARCH64_P32_TLSDESC_ADR_PAGE21"},
+	{125, "R_AARCH64_P32_TLSDESC_LD32_LO12_NC"},
+	{126, "R_AARCH64_P32_TLSDESC_ADD_LO12_NC"},
+	{127, "R_AARCH64_P32_TLSDESC_CALL"},
+	{180, "R_AARCH64_P32_COPY"},
+	{181, "R_AARCH64_P32_GLOB_DAT"},
+	{182, "R_AARCH64_P32_JUMP_SLOT"},
+	{183, "R_AARCH64_P32_RELATIVE"},
+	{184, "R_AARCH64_P32_TLS_DTPMOD"},
+	{185, "R_AARCH64_P32_TLS_DTPREL"},
+	{186, "R_AARCH64_P32_TLS_TPREL"},
+	{187, "R_AARCH64_P32_TLSDESC"},
+	{188, "R_AARCH64_P32_IRELATIVE"},
+	{256, "R_AARCH64_NULL"},
+	{257, "R_AARCH64_ABS64"},
+	{258, "R_AARCH64_ABS32"},
+	{259, "R_AARCH64_ABS16"},
+	{260, "R_AARCH64_PREL64"},
+	{261, "R_AARCH64_PREL32"},
+	{262, "R_AARCH64_PREL16"},
+	{263, "R_AARCH64_MOVW_UABS_G0"},
+	{264, "R_AARCH64_MOVW_UABS_G0_NC"},
+	{265, "R_AARCH64_MOVW_UABS_G1"},
+	{266, "R_AARCH64_MOVW_UABS_G1_NC"},
+	{267, "R_AARCH64_MOVW_UABS_G2"},
+	{268, "R_AARCH64_MOVW_UABS_G2_NC"},
+	{269, "R_AARCH64_MOVW_UABS_G3"},
+	{270, "R_AARCH64_MOVW_SABS_G0"},
+	{271, "R_AARCH64_MOVW_SABS_G1"},
+	{272, "R_AARCH64_MOVW_SABS_G2"},
+	{273, "R_AARCH64_LD_PREL_LO19"},
+	{274, "R_AARCH64_ADR_PREL_LO21"},
+	{275, "R_AARCH64_ADR_PREL_PG_HI21"},
+	{276, "R_AARCH64_ADR_PREL_PG_HI21_NC"},
+	{277, "R_AARCH64_ADD_ABS_LO12_NC"},
+	{278, "R_AARCH64_LDST8_ABS_LO12_NC"},
+	{279, "R_AARCH64_TSTBR14"},
+	{280, "R_AARCH64_CONDBR19"},
+	{282, "R_AARCH64_JUMP26"},
+	{283, "R_AARCH64_CALL26"},
+	{284, "R_AARCH64_LDST16_ABS_LO12_NC"},
+	{285, "R_AARCH64_LDST32_ABS_LO12_NC"},
+	{286, "R_AARCH64_LDST64_ABS_LO12_NC"},
+	{299, "R_AARCH64_LDST128_ABS_LO12_NC"},
+	{309, "R_AARCH64_GOT_LD_PREL19"},
+	{311, "R_AARCH64_ADR_GOT_PAGE"},
+	{312, "R_AARCH64_LD64_GOT_LO12_NC"},
+	{513, "R_AARCH64_TLSGD_ADR_PAGE21"},
+	{514, "R_AARCH64_TLSGD_ADD_LO12_NC"},
+	{539, "R_AARCH64_TLSIE_MOVW_GOTTPREL_G1"},
+	{540, "R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC"},
+	{541, "R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21"},
+	{542, "R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC"},
+	{543, "R_AARCH64_TLSIE_LD_GOTTPREL_PREL19"},
+	{544, "R_AARCH64_TLSLE_MOVW_TPREL_G2"},
+	{545, "R_AARCH64_TLSLE_MOVW_TPREL_G1"},
+	{546, "R_AARCH64_TLSLE_MOVW_TPREL_G1_NC"},
+	{547, "R_AARCH64_TLSLE_MOVW_TPREL_G0"},
+	{548, "R_AARCH64_TLSLE_MOVW_TPREL_G0_NC"},
+	{549, "R_AARCH64_TLSLE_ADD_TPREL_HI12"},
+	{550, "R_AARCH64_TLSLE_ADD_TPREL_LO12"},
+	{551, "R_AARCH64_TLSLE_ADD_TPREL_LO12_NC"},
+	{560, "R_AARCH64_TLSDESC_LD_PREL19"},
+	{561, "R_AARCH64_TLSDESC_ADR_PREL21"},
+	{562, "R_AARCH64_TLSDESC_ADR_PAGE21"},
+	{563, "R_AARCH64_TLSDESC_LD64_LO12_NC"},
+	{564, "R_AARCH64_TLSDESC_ADD_LO12_NC"},
+	{565, "R_AARCH64_TLSDESC_OFF_G1"},
+	{566, "R_AARCH64_TLSDESC_OFF_G0_NC"},
+	{567, "R_AARCH64_TLSDESC_LDR"},
+	{568, "R_AARCH64_TLSDESC_ADD"},
+	{569, "R_AARCH64_TLSDESC_CALL"},
+	{1024, "R_AARCH64_COPY"},
+	{1025, "R_AARCH64_GLOB_DAT"},
+	{1026, "R_AARCH64_JUMP_SLOT"},
+	{1027, "R_AARCH64_RELATIVE"},
+	{1028, "R_AARCH64_TLS_DTPMOD64"},
+	{1029, "R_AARCH64_TLS_DTPREL64"},
+	{1030, "R_AARCH64_TLS_TPREL64"},
+	{1031, "R_AARCH64_TLSDESC"},
+	{1032, "R_AARCH64_IRELATIVE"},
+}
+
+func (i R_AARCH64) String() string   { return stringName(uint32(i), raarch64Strings, false) }
+func (i R_AARCH64) GoString() string { return stringName(uint32(i), raarch64Strings, true) }
+
+// Relocation types for Alpha.
+type R_ALPHA int
+
+const (
+	R_ALPHA_NONE           R_ALPHA = 0  /* No reloc */
+	R_ALPHA_REFLONG        R_ALPHA = 1  /* Direct 32 bit */
+	R_ALPHA_REFQUAD        R_ALPHA = 2  /* Direct 64 bit */
+	R_ALPHA_GPREL32        R_ALPHA = 3  /* GP relative 32 bit */
+	R_ALPHA_LITERAL        R_ALPHA = 4  /* GP relative 16 bit w/optimization */
+	R_ALPHA_LITUSE         R_ALPHA = 5  /* Optimization hint for LITERAL */
+	R_ALPHA_GPDISP         R_ALPHA = 6  /* Add displacement to GP */
+	R_ALPHA_BRADDR         R_ALPHA = 7  /* PC+4 relative 23 bit shifted */
+	R_ALPHA_HINT           R_ALPHA = 8  /* PC+4 relative 16 bit shifted */
+	R_ALPHA_SREL16         R_ALPHA = 9  /* PC relative 16 bit */
+	R_ALPHA_SREL32         R_ALPHA = 10 /* PC relative 32 bit */
+	R_ALPHA_SREL64         R_ALPHA = 11 /* PC relative 64 bit */
+	R_ALPHA_OP_PUSH        R_ALPHA = 12 /* OP stack push */
+	R_ALPHA_OP_STORE       R_ALPHA = 13 /* OP stack pop and store */
+	R_ALPHA_OP_PSUB        R_ALPHA = 14 /* OP stack subtract */
+	R_ALPHA_OP_PRSHIFT     R_ALPHA = 15 /* OP stack right shift */
+	R_ALPHA_GPVALUE        R_ALPHA = 16
+	R_ALPHA_GPRELHIGH      R_ALPHA = 17
+	R_ALPHA_GPRELLOW       R_ALPHA = 18
+	R_ALPHA_IMMED_GP_16    R_ALPHA = 19
+	R_ALPHA_IMMED_GP_HI32  R_ALPHA = 20
+	R_ALPHA_IMMED_SCN_HI32 R_ALPHA = 21
+	R_ALPHA_IMMED_BR_HI32  R_ALPHA = 22
+	R_ALPHA_IMMED_LO32     R_ALPHA = 23
+	R_ALPHA_COPY           R_ALPHA = 24 /* Copy symbol at runtime */
+	R_ALPHA_GLOB_DAT       R_ALPHA = 25 /* Create GOT entry */
+	R_ALPHA_JMP_SLOT       R_ALPHA = 26 /* Create PLT entry */
+	R_ALPHA_RELATIVE       R_ALPHA = 27 /* Adjust by program base */
+)
+
+var ralphaStrings = []intName{
+	{0, "R_ALPHA_NONE"},
+	{1, "R_ALPHA_REFLONG"},
+	{2, "R_ALPHA_REFQUAD"},
+	{3, "R_ALPHA_GPREL32"},
+	{4, "R_ALPHA_LITERAL"},
+	{5, "R_ALPHA_LITUSE"},
+	{6, "R_ALPHA_GPDISP"},
+	{7, "R_ALPHA_BRADDR"},
+	{8, "R_ALPHA_HINT"},
+	{9, "R_ALPHA_SREL16"},
+	{10, "R_ALPHA_SREL32"},
+	{11, "R_ALPHA_SREL64"},
+	{12, "R_ALPHA_OP_PUSH"},
+	{13, "R_ALPHA_OP_STORE"},
+	{14, "R_ALPHA_OP_PSUB"},
+	{15, "R_ALPHA_OP_PRSHIFT"},
+	{16, "R_ALPHA_GPVALUE"},
+	{17, "R_ALPHA_GPRELHIGH"},
+	{18, "R_ALPHA_GPRELLOW"},
+	{19, "R_ALPHA_IMMED_GP_16"},
+	{20, "R_ALPHA_IMMED_GP_HI32"},
+	{21, "R_ALPHA_IMMED_SCN_HI32"},
+	{22, "R_ALPHA_IMMED_BR_HI32"},
+	{23, "R_ALPHA_IMMED_LO32"},
+	{24, "R_ALPHA_COPY"},
+	{25, "R_ALPHA_GLOB_DAT"},
+	{26, "R_ALPHA_JMP_SLOT"},
+	{27, "R_ALPHA_RELATIVE"},
+}
+
+func (i R_ALPHA) String() string   { return stringName(uint32(i), ralphaStrings, false) }
+func (i R_ALPHA) GoString() string { return stringName(uint32(i), ralphaStrings, true) }
+
+// Relocation types for ARM.
+type R_ARM int
+
+const (
+	R_ARM_NONE          R_ARM = 0 /* No relocation. */
+	R_ARM_PC24          R_ARM = 1
+	R_ARM_ABS32         R_ARM = 2
+	R_ARM_REL32         R_ARM = 3
+	R_ARM_PC13          R_ARM = 4
+	R_ARM_ABS16         R_ARM = 5
+	R_ARM_ABS12         R_ARM = 6
+	R_ARM_THM_ABS5      R_ARM = 7
+	R_ARM_ABS8          R_ARM = 8
+	R_ARM_SBREL32       R_ARM = 9
+	R_ARM_THM_PC22      R_ARM = 10
+	R_ARM_THM_PC8       R_ARM = 11
+	R_ARM_AMP_VCALL9    R_ARM = 12
+	R_ARM_SWI24         R_ARM = 13
+	R_ARM_THM_SWI8      R_ARM = 14
+	R_ARM_XPC25         R_ARM = 15
+	R_ARM_THM_XPC22     R_ARM = 16
+	R_ARM_COPY          R_ARM = 20 /* Copy data from shared object. */
+	R_ARM_GLOB_DAT      R_ARM = 21 /* Set GOT entry to data address. */
+	R_ARM_JUMP_SLOT     R_ARM = 22 /* Set GOT entry to code address. */
+	R_ARM_RELATIVE      R_ARM = 23 /* Add load address of shared object. */
+	R_ARM_GOTOFF        R_ARM = 24 /* Add GOT-relative symbol address. */
+	R_ARM_GOTPC         R_ARM = 25 /* Add PC-relative GOT table address. */
+	R_ARM_GOT32         R_ARM = 26 /* Add PC-relative GOT offset. */
+	R_ARM_PLT32         R_ARM = 27 /* Add PC-relative PLT offset. */
+	R_ARM_GNU_VTENTRY   R_ARM = 100
+	R_ARM_GNU_VTINHERIT R_ARM = 101
+	R_ARM_RSBREL32      R_ARM = 250
+	R_ARM_THM_RPC22     R_ARM = 251
+	R_ARM_RREL32        R_ARM = 252
+	R_ARM_RABS32        R_ARM = 253
+	R_ARM_RPC24         R_ARM = 254
+	R_ARM_RBASE         R_ARM = 255
+)
+
+var rarmStrings = []intName{
+	{0, "R_ARM_NONE"},
+	{1, "R_ARM_PC24"},
+	{2, "R_ARM_ABS32"},
+	{3, "R_ARM_REL32"},
+	{4, "R_ARM_PC13"},
+	{5, "R_ARM_ABS16"},
+	{6, "R_ARM_ABS12"},
+	{7, "R_ARM_THM_ABS5"},
+	{8, "R_ARM_ABS8"},
+	{9, "R_ARM_SBREL32"},
+	{10, "R_ARM_THM_PC22"},
+	{11, "R_ARM_THM_PC8"},
+	{12, "R_ARM_AMP_VCALL9"},
+	{13, "R_ARM_SWI24"},
+	{14, "R_ARM_THM_SWI8"},
+	{15, "R_ARM_XPC25"},
+	{16, "R_ARM_THM_XPC22"},
+	{20, "R_ARM_COPY"},
+	{21, "R_ARM_GLOB_DAT"},
+	{22, "R_ARM_JUMP_SLOT"},
+	{23, "R_ARM_RELATIVE"},
+	{24, "R_ARM_GOTOFF"},
+	{25, "R_ARM_GOTPC"},
+	{26, "R_ARM_GOT32"},
+	{27, "R_ARM_PLT32"},
+	{100, "R_ARM_GNU_VTENTRY"},
+	{101, "R_ARM_GNU_VTINHERIT"},
+	{250, "R_ARM_RSBREL32"},
+	{251, "R_ARM_THM_RPC22"},
+	{252, "R_ARM_RREL32"},
+	{253, "R_ARM_RABS32"},
+	{254, "R_ARM_RPC24"},
+	{255, "R_ARM_RBASE"},
+}
+
+func (i R_ARM) String() string   { return stringName(uint32(i), rarmStrings, false) }
+func (i R_ARM) GoString() string { return stringName(uint32(i), rarmStrings, true) }
+
+// Relocation types for 386.
+type R_386 int
+
+const (
+	R_386_NONE         R_386 = 0  /* No relocation. */
+	R_386_32           R_386 = 1  /* Add symbol value. */
+	R_386_PC32         R_386 = 2  /* Add PC-relative symbol value. */
+	R_386_GOT32        R_386 = 3  /* Add PC-relative GOT offset. */
+	R_386_PLT32        R_386 = 4  /* Add PC-relative PLT offset. */
+	R_386_COPY         R_386 = 5  /* Copy data from shared object. */
+	R_386_GLOB_DAT     R_386 = 6  /* Set GOT entry to data address. */
+	R_386_JMP_SLOT     R_386 = 7  /* Set GOT entry to code address. */
+	R_386_RELATIVE     R_386 = 8  /* Add load address of shared object. */
+	R_386_GOTOFF       R_386 = 9  /* Add GOT-relative symbol address. */
+	R_386_GOTPC        R_386 = 10 /* Add PC-relative GOT table address. */
+	R_386_TLS_TPOFF    R_386 = 14 /* Negative offset in static TLS block */
+	R_386_TLS_IE       R_386 = 15 /* Absolute address of GOT for -ve static TLS */
+	R_386_TLS_GOTIE    R_386 = 16 /* GOT entry for negative static TLS block */
+	R_386_TLS_LE       R_386 = 17 /* Negative offset relative to static TLS */
+	R_386_TLS_GD       R_386 = 18 /* 32 bit offset to GOT (index,off) pair */
+	R_386_TLS_LDM      R_386 = 19 /* 32 bit offset to GOT (index,zero) pair */
+	R_386_TLS_GD_32    R_386 = 24 /* 32 bit offset to GOT (index,off) pair */
+	R_386_TLS_GD_PUSH  R_386 = 25 /* pushl instruction for Sun ABI GD sequence */
+	R_386_TLS_GD_CALL  R_386 = 26 /* call instruction for Sun ABI GD sequence */
+	R_386_TLS_GD_POP   R_386 = 27 /* popl instruction for Sun ABI GD sequence */
+	R_386_TLS_LDM_32   R_386 = 28 /* 32 bit offset to GOT (index,zero) pair */
+	R_386_TLS_LDM_PUSH R_386 = 29 /* pushl instruction for Sun ABI LD sequence */
+	R_386_TLS_LDM_CALL R_386 = 30 /* call instruction for Sun ABI LD sequence */
+	R_386_TLS_LDM_POP  R_386 = 31 /* popl instruction for Sun ABI LD sequence */
+	R_386_TLS_LDO_32   R_386 = 32 /* 32 bit offset from start of TLS block */
+	R_386_TLS_IE_32    R_386 = 33 /* 32 bit offset to GOT static TLS offset entry */
+	R_386_TLS_LE_32    R_386 = 34 /* 32 bit offset within static TLS block */
+	R_386_TLS_DTPMOD32 R_386 = 35 /* GOT entry containing TLS index */
+	R_386_TLS_DTPOFF32 R_386 = 36 /* GOT entry containing TLS offset */
+	R_386_TLS_TPOFF32  R_386 = 37 /* GOT entry of -ve static TLS offset */
+)
+
+var r386Strings = []intName{
+	{0, "R_386_NONE"},
+	{1, "R_386_32"},
+	{2, "R_386_PC32"},
+	{3, "R_386_GOT32"},
+	{4, "R_386_PLT32"},
+	{5, "R_386_COPY"},
+	{6, "R_386_GLOB_DAT"},
+	{7, "R_386_JMP_SLOT"},
+	{8, "R_386_RELATIVE"},
+	{9, "R_386_GOTOFF"},
+	{10, "R_386_GOTPC"},
+	{14, "R_386_TLS_TPOFF"},
+	{15, "R_386_TLS_IE"},
+	{16, "R_386_TLS_GOTIE"},
+	{17, "R_386_TLS_LE"},
+	{18, "R_386_TLS_GD"},
+	{19, "R_386_TLS_LDM"},
+	{24, "R_386_TLS_GD_32"},
+	{25, "R_386_TLS_GD_PUSH"},
+	{26, "R_386_TLS_GD_CALL"},
+	{27, "R_386_TLS_GD_POP"},
+	{28, "R_386_TLS_LDM_32"},
+	{29, "R_386_TLS_LDM_PUSH"},
+	{30, "R_386_TLS_LDM_CALL"},
+	{31, "R_386_TLS_LDM_POP"},
+	{32, "R_386_TLS_LDO_32"},
+	{33, "R_386_TLS_IE_32"},
+	{34, "R_386_TLS_LE_32"},
+	{35, "R_386_TLS_DTPMOD32"},
+	{36, "R_386_TLS_DTPOFF32"},
+	{37, "R_386_TLS_TPOFF32"},
+}
+
+func (i R_386) String() string   { return stringName(uint32(i), r386Strings, false) }
+func (i R_386) GoString() string { return stringName(uint32(i), r386Strings, true) }
+
+// Relocation types for PowerPC.
+type R_PPC int
+
+const (
+	R_PPC_NONE            R_PPC = 0 /* No relocation. */
+	R_PPC_ADDR32          R_PPC = 1
+	R_PPC_ADDR24          R_PPC = 2
+	R_PPC_ADDR16          R_PPC = 3
+	R_PPC_ADDR16_LO       R_PPC = 4
+	R_PPC_ADDR16_HI       R_PPC = 5
+	R_PPC_ADDR16_HA       R_PPC = 6
+	R_PPC_ADDR14          R_PPC = 7
+	R_PPC_ADDR14_BRTAKEN  R_PPC = 8
+	R_PPC_ADDR14_BRNTAKEN R_PPC = 9
+	R_PPC_REL24           R_PPC = 10
+	R_PPC_REL14           R_PPC = 11
+	R_PPC_REL14_BRTAKEN   R_PPC = 12
+	R_PPC_REL14_BRNTAKEN  R_PPC = 13
+	R_PPC_GOT16           R_PPC = 14
+	R_PPC_GOT16_LO        R_PPC = 15
+	R_PPC_GOT16_HI        R_PPC = 16
+	R_PPC_GOT16_HA        R_PPC = 17
+	R_PPC_PLTREL24        R_PPC = 18
+	R_PPC_COPY            R_PPC = 19
+	R_PPC_GLOB_DAT        R_PPC = 20
+	R_PPC_JMP_SLOT        R_PPC = 21
+	R_PPC_RELATIVE        R_PPC = 22
+	R_PPC_LOCAL24PC       R_PPC = 23
+	R_PPC_UADDR32         R_PPC = 24
+	R_PPC_UADDR16         R_PPC = 25
+	R_PPC_REL32           R_PPC = 26
+	R_PPC_PLT32           R_PPC = 27
+	R_PPC_PLTREL32        R_PPC = 28
+	R_PPC_PLT16_LO        R_PPC = 29
+	R_PPC_PLT16_HI        R_PPC = 30
+	R_PPC_PLT16_HA        R_PPC = 31
+	R_PPC_SDAREL16        R_PPC = 32
+	R_PPC_SECTOFF         R_PPC = 33
+	R_PPC_SECTOFF_LO      R_PPC = 34
+	R_PPC_SECTOFF_HI      R_PPC = 35
+	R_PPC_SECTOFF_HA      R_PPC = 36
+	R_PPC_TLS             R_PPC = 67
+	R_PPC_DTPMOD32        R_PPC = 68
+	R_PPC_TPREL16         R_PPC = 69
+	R_PPC_TPREL16_LO      R_PPC = 70
+	R_PPC_TPREL16_HI      R_PPC = 71
+	R_PPC_TPREL16_HA      R_PPC = 72
+	R_PPC_TPREL32         R_PPC = 73
+	R_PPC_DTPREL16        R_PPC = 74
+	R_PPC_DTPREL16_LO     R_PPC = 75
+	R_PPC_DTPREL16_HI     R_PPC = 76
+	R_PPC_DTPREL16_HA     R_PPC = 77
+	R_PPC_DTPREL32        R_PPC = 78
+	R_PPC_GOT_TLSGD16     R_PPC = 79
+	R_PPC_GOT_TLSGD16_LO  R_PPC = 80
+	R_PPC_GOT_TLSGD16_HI  R_PPC = 81
+	R_PPC_GOT_TLSGD16_HA  R_PPC = 82
+	R_PPC_GOT_TLSLD16     R_PPC = 83
+	R_PPC_GOT_TLSLD16_LO  R_PPC = 84
+	R_PPC_GOT_TLSLD16_HI  R_PPC = 85
+	R_PPC_GOT_TLSLD16_HA  R_PPC = 86
+	R_PPC_GOT_TPREL16     R_PPC = 87
+	R_PPC_GOT_TPREL16_LO  R_PPC = 88
+	R_PPC_GOT_TPREL16_HI  R_PPC = 89
+	R_PPC_GOT_TPREL16_HA  R_PPC = 90
+	R_PPC_EMB_NADDR32     R_PPC = 101
+	R_PPC_EMB_NADDR16     R_PPC = 102
+	R_PPC_EMB_NADDR16_LO  R_PPC = 103
+	R_PPC_EMB_NADDR16_HI  R_PPC = 104
+	R_PPC_EMB_NADDR16_HA  R_PPC = 105
+	R_PPC_EMB_SDAI16      R_PPC = 106
+	R_PPC_EMB_SDA2I16     R_PPC = 107
+	R_PPC_EMB_SDA2REL     R_PPC = 108
+	R_PPC_EMB_SDA21       R_PPC = 109
+	R_PPC_EMB_MRKREF      R_PPC = 110
+	R_PPC_EMB_RELSEC16    R_PPC = 111
+	R_PPC_EMB_RELST_LO    R_PPC = 112
+	R_PPC_EMB_RELST_HI    R_PPC = 113
+	R_PPC_EMB_RELST_HA    R_PPC = 114
+	R_PPC_EMB_BIT_FLD     R_PPC = 115
+	R_PPC_EMB_RELSDA      R_PPC = 116
+)
+
+var rppcStrings = []intName{
+	{0, "R_PPC_NONE"},
+	{1, "R_PPC_ADDR32"},
+	{2, "R_PPC_ADDR24"},
+	{3, "R_PPC_ADDR16"},
+	{4, "R_PPC_ADDR16_LO"},
+	{5, "R_PPC_ADDR16_HI"},
+	{6, "R_PPC_ADDR16_HA"},
+	{7, "R_PPC_ADDR14"},
+	{8, "R_PPC_ADDR14_BRTAKEN"},
+	{9, "R_PPC_ADDR14_BRNTAKEN"},
+	{10, "R_PPC_REL24"},
+	{11, "R_PPC_REL14"},
+	{12, "R_PPC_REL14_BRTAKEN"},
+	{13, "R_PPC_REL14_BRNTAKEN"},
+	{14, "R_PPC_GOT16"},
+	{15, "R_PPC_GOT16_LO"},
+	{16, "R_PPC_GOT16_HI"},
+	{17, "R_PPC_GOT16_HA"},
+	{18, "R_PPC_PLTREL24"},
+	{19, "R_PPC_COPY"},
+	{20, "R_PPC_GLOB_DAT"},
+	{21, "R_PPC_JMP_SLOT"},
+	{22, "R_PPC_RELATIVE"},
+	{23, "R_PPC_LOCAL24PC"},
+	{24, "R_PPC_UADDR32"},
+	{25, "R_PPC_UADDR16"},
+	{26, "R_PPC_REL32"},
+	{27, "R_PPC_PLT32"},
+	{28, "R_PPC_PLTREL32"},
+	{29, "R_PPC_PLT16_LO"},
+	{30, "R_PPC_PLT16_HI"},
+	{31, "R_PPC_PLT16_HA"},
+	{32, "R_PPC_SDAREL16"},
+	{33, "R_PPC_SECTOFF"},
+	{34, "R_PPC_SECTOFF_LO"},
+	{35, "R_PPC_SECTOFF_HI"},
+	{36, "R_PPC_SECTOFF_HA"},
+
+	{67, "R_PPC_TLS"},
+	{68, "R_PPC_DTPMOD32"},
+	{69, "R_PPC_TPREL16"},
+	{70, "R_PPC_TPREL16_LO"},
+	{71, "R_PPC_TPREL16_HI"},
+	{72, "R_PPC_TPREL16_HA"},
+	{73, "R_PPC_TPREL32"},
+	{74, "R_PPC_DTPREL16"},
+	{75, "R_PPC_DTPREL16_LO"},
+	{76, "R_PPC_DTPREL16_HI"},
+	{77, "R_PPC_DTPREL16_HA"},
+	{78, "R_PPC_DTPREL32"},
+	{79, "R_PPC_GOT_TLSGD16"},
+	{80, "R_PPC_GOT_TLSGD16_LO"},
+	{81, "R_PPC_GOT_TLSGD16_HI"},
+	{82, "R_PPC_GOT_TLSGD16_HA"},
+	{83, "R_PPC_GOT_TLSLD16"},
+	{84, "R_PPC_GOT_TLSLD16_LO"},
+	{85, "R_PPC_GOT_TLSLD16_HI"},
+	{86, "R_PPC_GOT_TLSLD16_HA"},
+	{87, "R_PPC_GOT_TPREL16"},
+	{88, "R_PPC_GOT_TPREL16_LO"},
+	{89, "R_PPC_GOT_TPREL16_HI"},
+	{90, "R_PPC_GOT_TPREL16_HA"},
+
+	{101, "R_PPC_EMB_NADDR32"},
+	{102, "R_PPC_EMB_NADDR16"},
+	{103, "R_PPC_EMB_NADDR16_LO"},
+	{104, "R_PPC_EMB_NADDR16_HI"},
+	{105, "R_PPC_EMB_NADDR16_HA"},
+	{106, "R_PPC_EMB_SDAI16"},
+	{107, "R_PPC_EMB_SDA2I16"},
+	{108, "R_PPC_EMB_SDA2REL"},
+	{109, "R_PPC_EMB_SDA21"},
+	{110, "R_PPC_EMB_MRKREF"},
+	{111, "R_PPC_EMB_RELSEC16"},
+	{112, "R_PPC_EMB_RELST_LO"},
+	{113, "R_PPC_EMB_RELST_HI"},
+	{114, "R_PPC_EMB_RELST_HA"},
+	{115, "R_PPC_EMB_BIT_FLD"},
+	{116, "R_PPC_EMB_RELSDA"},
+}
+
+func (i R_PPC) String() string   { return stringName(uint32(i), rppcStrings, false) }
+func (i R_PPC) GoString() string { return stringName(uint32(i), rppcStrings, true) }
+
+// Relocation types for SPARC.
+type R_SPARC int
+
+const (
+	R_SPARC_NONE     R_SPARC = 0
+	R_SPARC_8        R_SPARC = 1
+	R_SPARC_16       R_SPARC = 2
+	R_SPARC_32       R_SPARC = 3
+	R_SPARC_DISP8    R_SPARC = 4
+	R_SPARC_DISP16   R_SPARC = 5
+	R_SPARC_DISP32   R_SPARC = 6
+	R_SPARC_WDISP30  R_SPARC = 7
+	R_SPARC_WDISP22  R_SPARC = 8
+	R_SPARC_HI22     R_SPARC = 9
+	R_SPARC_22       R_SPARC = 10
+	R_SPARC_13       R_SPARC = 11
+	R_SPARC_LO10     R_SPARC = 12
+	R_SPARC_GOT10    R_SPARC = 13
+	R_SPARC_GOT13    R_SPARC = 14
+	R_SPARC_GOT22    R_SPARC = 15
+	R_SPARC_PC10     R_SPARC = 16
+	R_SPARC_PC22     R_SPARC = 17
+	R_SPARC_WPLT30   R_SPARC = 18
+	R_SPARC_COPY     R_SPARC = 19
+	R_SPARC_GLOB_DAT R_SPARC = 20
+	R_SPARC_JMP_SLOT R_SPARC = 21
+	R_SPARC_RELATIVE R_SPARC = 22
+	R_SPARC_UA32     R_SPARC = 23
+	R_SPARC_PLT32    R_SPARC = 24
+	R_SPARC_HIPLT22  R_SPARC = 25
+	R_SPARC_LOPLT10  R_SPARC = 26
+	R_SPARC_PCPLT32  R_SPARC = 27
+	R_SPARC_PCPLT22  R_SPARC = 28
+	R_SPARC_PCPLT10  R_SPARC = 29
+	R_SPARC_10       R_SPARC = 30
+	R_SPARC_11       R_SPARC = 31
+	R_SPARC_64       R_SPARC = 32
+	R_SPARC_OLO10    R_SPARC = 33
+	R_SPARC_HH22     R_SPARC = 34
+	R_SPARC_HM10     R_SPARC = 35
+	R_SPARC_LM22     R_SPARC = 36
+	R_SPARC_PC_HH22  R_SPARC = 37
+	R_SPARC_PC_HM10  R_SPARC = 38
+	R_SPARC_PC_LM22  R_SPARC = 39
+	R_SPARC_WDISP16  R_SPARC = 40
+	R_SPARC_WDISP19  R_SPARC = 41
+	R_SPARC_GLOB_JMP R_SPARC = 42
+	R_SPARC_7        R_SPARC = 43
+	R_SPARC_5        R_SPARC = 44
+	R_SPARC_6        R_SPARC = 45
+	R_SPARC_DISP64   R_SPARC = 46
+	R_SPARC_PLT64    R_SPARC = 47
+	R_SPARC_HIX22    R_SPARC = 48
+	R_SPARC_LOX10    R_SPARC = 49
+	R_SPARC_H44      R_SPARC = 50
+	R_SPARC_M44      R_SPARC = 51
+	R_SPARC_L44      R_SPARC = 52
+	R_SPARC_REGISTER R_SPARC = 53
+	R_SPARC_UA64     R_SPARC = 54
+	R_SPARC_UA16     R_SPARC = 55
+)
+
+var rsparcStrings = []intName{
+	{0, "R_SPARC_NONE"},
+	{1, "R_SPARC_8"},
+	{2, "R_SPARC_16"},
+	{3, "R_SPARC_32"},
+	{4, "R_SPARC_DISP8"},
+	{5, "R_SPARC_DISP16"},
+	{6, "R_SPARC_DISP32"},
+	{7, "R_SPARC_WDISP30"},
+	{8, "R_SPARC_WDISP22"},
+	{9, "R_SPARC_HI22"},
+	{10, "R_SPARC_22"},
+	{11, "R_SPARC_13"},
+	{12, "R_SPARC_LO10"},
+	{13, "R_SPARC_GOT10"},
+	{14, "R_SPARC_GOT13"},
+	{15, "R_SPARC_GOT22"},
+	{16, "R_SPARC_PC10"},
+	{17, "R_SPARC_PC22"},
+	{18, "R_SPARC_WPLT30"},
+	{19, "R_SPARC_COPY"},
+	{20, "R_SPARC_GLOB_DAT"},
+	{21, "R_SPARC_JMP_SLOT"},
+	{22, "R_SPARC_RELATIVE"},
+	{23, "R_SPARC_UA32"},
+	{24, "R_SPARC_PLT32"},
+	{25, "R_SPARC_HIPLT22"},
+	{26, "R_SPARC_LOPLT10"},
+	{27, "R_SPARC_PCPLT32"},
+	{28, "R_SPARC_PCPLT22"},
+	{29, "R_SPARC_PCPLT10"},
+	{30, "R_SPARC_10"},
+	{31, "R_SPARC_11"},
+	{32, "R_SPARC_64"},
+	{33, "R_SPARC_OLO10"},
+	{34, "R_SPARC_HH22"},
+	{35, "R_SPARC_HM10"},
+	{36, "R_SPARC_LM22"},
+	{37, "R_SPARC_PC_HH22"},
+	{38, "R_SPARC_PC_HM10"},
+	{39, "R_SPARC_PC_LM22"},
+	{40, "R_SPARC_WDISP16"},
+	{41, "R_SPARC_WDISP19"},
+	{42, "R_SPARC_GLOB_JMP"},
+	{43, "R_SPARC_7"},
+	{44, "R_SPARC_5"},
+	{45, "R_SPARC_6"},
+	{46, "R_SPARC_DISP64"},
+	{47, "R_SPARC_PLT64"},
+	{48, "R_SPARC_HIX22"},
+	{49, "R_SPARC_LOX10"},
+	{50, "R_SPARC_H44"},
+	{51, "R_SPARC_M44"},
+	{52, "R_SPARC_L44"},
+	{53, "R_SPARC_REGISTER"},
+	{54, "R_SPARC_UA64"},
+	{55, "R_SPARC_UA16"},
+}
+
+func (i R_SPARC) String() string   { return stringName(uint32(i), rsparcStrings, false) }
+func (i R_SPARC) GoString() string { return stringName(uint32(i), rsparcStrings, true) }
+
+// Magic number for the elf trampoline, chosen wisely to be an immediate value.
+const ARM_MAGIC_TRAMP_NUMBER = 0x5c000003
+
+// ELF32 File header.
+type Header32 struct {
+	Ident     [EI_NIDENT]byte /* File identification. */
+	Type      uint16          /* File type. */
+	Machine   uint16          /* Machine architecture. */
+	Version   uint32          /* ELF format version. */
+	Entry     uint32          /* Entry point. */
+	Phoff     uint32          /* Program header file offset. */
+	Shoff     uint32          /* Section header file offset. */
+	Flags     uint32          /* Architecture-specific flags. */
+	Ehsize    uint16          /* Size of ELF header in bytes. */
+	Phentsize uint16          /* Size of program header entry. */
+	Phnum     uint16          /* Number of program header entries. */
+	Shentsize uint16          /* Size of section header entry. */
+	Shnum     uint16          /* Number of section header entries. */
+	Shstrndx  uint16          /* Section name strings section. */
+}
+
+// ELF32 Section header.
+type Section32 struct {
+	Name      uint32 /* Section name (index into the section header string table). */
+	Type      uint32 /* Section type. */
+	Flags     uint32 /* Section flags. */
+	Addr      uint32 /* Address in memory image. */
+	Off       uint32 /* Offset in file. */
+	Size      uint32 /* Size in bytes. */
+	Link      uint32 /* Index of a related section. */
+	Info      uint32 /* Depends on section type. */
+	Addralign uint32 /* Alignment in bytes. */
+	Entsize   uint32 /* Size of each entry in section. */
+}
+
+// ELF32 Program header.
+type Prog32 struct {
+	Type   uint32 /* Entry type. */
+	Off    uint32 /* File offset of contents. */
+	Vaddr  uint32 /* Virtual address in memory image. */
+	Paddr  uint32 /* Physical address (not used). */
+	Filesz uint32 /* Size of contents in file. */
+	Memsz  uint32 /* Size of contents in memory. */
+	Flags  uint32 /* Access permission flags. */
+	Align  uint32 /* Alignment in memory and file. */
+}
+
+// ELF32 Dynamic structure.  The ".dynamic" section contains an array of them.
+type Dyn32 struct {
+	Tag int32  /* Entry type. */
+	Val uint32 /* Integer/Address value. */
+}
+
+/*
+ * Relocation entries.
+ */
+
+// ELF32 Relocations that don't need an addend field.
+type Rel32 struct {
+	Off  uint32 /* Location to be relocated. */
+	Info uint32 /* Relocation type and symbol index. */
+}
+
+// ELF32 Relocations that need an addend field.
+type Rela32 struct {
+	Off    uint32 /* Location to be relocated. */
+	Info   uint32 /* Relocation type and symbol index. */
+	Addend int32  /* Addend. */
+}
+
+func R_SYM32(info uint32) uint32      { return uint32(info >> 8) }
+func R_TYPE32(info uint32) uint32     { return uint32(info & 0xff) }
+func R_INFO32(sym, typ uint32) uint32 { return sym<<8 | typ }
+
+// ELF32 Symbol.
+type Sym32 struct {
+	Name  uint32
+	Value uint32
+	Size  uint32
+	Info  uint8
+	Other uint8
+	Shndx uint16
+}
+
+const Sym32Size = 16
+
+func ST_BIND(info uint8) SymBind { return SymBind(info >> 4) }
+func ST_TYPE(info uint8) SymType { return SymType(info & 0xF) }
+func ST_INFO(bind SymBind, typ SymType) uint8 {
+	return uint8(bind)<<4 | uint8(typ)&0xf
+}
+func ST_VISIBILITY(other uint8) SymVis { return SymVis(other & 3) }
+
+/*
+ * ELF64
+ */
+
+// ELF64 file header.
+type Header64 struct {
+	Ident     [EI_NIDENT]byte /* File identification. */
+	Type      uint16          /* File type. */
+	Machine   uint16          /* Machine architecture. */
+	Version   uint32          /* ELF format version. */
+	Entry     uint64          /* Entry point. */
+	Phoff     uint64          /* Program header file offset. */
+	Shoff     uint64          /* Section header file offset. */
+	Flags     uint32          /* Architecture-specific flags. */
+	Ehsize    uint16          /* Size of ELF header in bytes. */
+	Phentsize uint16          /* Size of program header entry. */
+	Phnum     uint16          /* Number of program header entries. */
+	Shentsize uint16          /* Size of section header entry. */
+	Shnum     uint16          /* Number of section header entries. */
+	Shstrndx  uint16          /* Section name strings section. */
+}
+
+// ELF64 Section header.
+type Section64 struct {
+	Name      uint32 /* Section name (index into the section header string table). */
+	Type      uint32 /* Section type. */
+	Flags     uint64 /* Section flags. */
+	Addr      uint64 /* Address in memory image. */
+	Off       uint64 /* Offset in file. */
+	Size      uint64 /* Size in bytes. */
+	Link      uint32 /* Index of a related section. */
+	Info      uint32 /* Depends on section type. */
+	Addralign uint64 /* Alignment in bytes. */
+	Entsize   uint64 /* Size of each entry in section. */
+}
+
+// ELF64 Program header.
+type Prog64 struct {
+	Type   uint32 /* Entry type. */
+	Flags  uint32 /* Access permission flags. */
+	Off    uint64 /* File offset of contents. */
+	Vaddr  uint64 /* Virtual address in memory image. */
+	Paddr  uint64 /* Physical address (not used). */
+	Filesz uint64 /* Size of contents in file. */
+	Memsz  uint64 /* Size of contents in memory. */
+	Align  uint64 /* Alignment in memory and file. */
+}
+
+// ELF64 Dynamic structure.  The ".dynamic" section contains an array of them.
+type Dyn64 struct {
+	Tag int64  /* Entry type. */
+	Val uint64 /* Integer/address value */
+}
+
+/*
+ * Relocation entries.
+ */
+
+/* ELF64 relocations that don't need an addend field. */
+type Rel64 struct {
+	Off  uint64 /* Location to be relocated. */
+	Info uint64 /* Relocation type and symbol index. */
+}
+
+/* ELF64 relocations that need an addend field. */
+type Rela64 struct {
+	Off    uint64 /* Location to be relocated. */
+	Info   uint64 /* Relocation type and symbol index. */
+	Addend int64  /* Addend. */
+}
+
+func R_SYM64(info uint64) uint32    { return uint32(info >> 32) }
+func R_TYPE64(info uint64) uint32   { return uint32(info) }
+func R_INFO(sym, typ uint32) uint64 { return uint64(sym)<<32 | uint64(typ) }
+
+// ELF64 symbol table entries.
+type Sym64 struct {
+	Name  uint32 /* String table index of name. */
+	Info  uint8  /* Type and binding information. */
+	Other uint8  /* Reserved (not used). */
+	Shndx uint16 /* Section index of symbol. */
+	Value uint64 /* Symbol value. */
+	Size  uint64 /* Size of associated object. */
+}
+
+const Sym64Size = 24
+
+type intName struct {
+	i uint32
+	s string
+}
+
+func stringName(i uint32, names []intName, goSyntax bool) string {
+	for _, n := range names {
+		if n.i == i {
+			if goSyntax {
+				return "elf." + n.s
+			}
+			return n.s
+		}
+	}
+
+	// second pass - look for smaller to add with.
+	// assume sorted already
+	for j := len(names) - 1; j >= 0; j-- {
+		n := names[j]
+		if n.i < i {
+			s := n.s
+			if goSyntax {
+				s = "elf." + s
+			}
+			return s + "+" + strconv.FormatUint(uint64(i-n.i), 10)
+		}
+	}
+
+	return strconv.FormatUint(uint64(i), 10)
+}
+
+func flagName(i uint32, names []intName, goSyntax bool) string {
+	s := ""
+	for _, n := range names {
+		if n.i&i == n.i {
+			if len(s) > 0 {
+				s += "+"
+			}
+			if goSyntax {
+				s += "elf."
+			}
+			s += n.s
+			i -= n.i
+		}
+	}
+	if len(s) == 0 {
+		return "0x" + strconv.FormatUint(uint64(i), 16)
+	}
+	if i != 0 {
+		s += "+0x" + strconv.FormatUint(uint64(i), 16)
+	}
+	return s
+}
diff --git a/src/pkg/debug/elf/elf_test.go b/src/debug/elf/elf_test.go
similarity index 100%
rename from src/pkg/debug/elf/elf_test.go
rename to src/debug/elf/elf_test.go
diff --git a/src/debug/elf/file.go b/src/debug/elf/file.go
new file mode 100644
index 0000000..de8a3a2
--- /dev/null
+++ b/src/debug/elf/file.go
@@ -0,0 +1,953 @@
+// Copyright 2009 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package elf implements access to ELF object files.
+package elf
+
+import (
+	"bytes"
+	"debug/dwarf"
+	"encoding/binary"
+	"errors"
+	"fmt"
+	"io"
+	"os"
+)
+
+// TODO: error reporting detail
+
+/*
+ * Internal ELF representation
+ */
+
+// A FileHeader represents an ELF file header.
+type FileHeader struct {
+	Class      Class
+	Data       Data
+	Version    Version
+	OSABI      OSABI
+	ABIVersion uint8
+	ByteOrder  binary.ByteOrder
+	Type       Type
+	Machine    Machine
+	Entry      uint64
+}
+
+// A File represents an open ELF file.
+type File struct {
+	FileHeader
+	Sections  []*Section
+	Progs     []*Prog
+	closer    io.Closer
+	gnuNeed   []verneed
+	gnuVersym []byte
+}
+
+// A SectionHeader represents a single ELF section header.
+type SectionHeader struct {
+	Name      string
+	Type      SectionType
+	Flags     SectionFlag
+	Addr      uint64
+	Offset    uint64
+	Size      uint64
+	Link      uint32
+	Info      uint32
+	Addralign uint64
+	Entsize   uint64
+}
+
+// A Section represents a single section in an ELF file.
+type Section struct {
+	SectionHeader
+
+	// Embed ReaderAt for ReadAt method.
+	// Do not embed SectionReader directly
+	// to avoid having Read and Seek.
+	// If a client wants Read and Seek it must use
+	// Open() to avoid fighting over the seek offset
+	// with other clients.
+	io.ReaderAt
+	sr *io.SectionReader
+}
+
+// Data reads and returns the contents of the ELF section.
+func (s *Section) Data() ([]byte, error) {
+	dat := make([]byte, s.sr.Size())
+	n, err := s.sr.ReadAt(dat, 0)
+	if n == len(dat) {
+		err = nil
+	}
+	return dat[0:n], err
+}
+
+// stringTable reads and returns the string table given by the
+// specified link value.
+func (f *File) stringTable(link uint32) ([]byte, error) {
+	if link <= 0 || link >= uint32(len(f.Sections)) {
+		return nil, errors.New("section has invalid string table link")
+	}
+	return f.Sections[link].Data()
+}
+
+// Open returns a new ReadSeeker reading the ELF section.
+func (s *Section) Open() io.ReadSeeker { return io.NewSectionReader(s.sr, 0, 1<<63-1) }
+
+// A ProgHeader represents a single ELF program header.
+type ProgHeader struct {
+	Type   ProgType
+	Flags  ProgFlag
+	Off    uint64
+	Vaddr  uint64
+	Paddr  uint64
+	Filesz uint64
+	Memsz  uint64
+	Align  uint64
+}
+
+// A Prog represents a single ELF program header in an ELF binary.
+type Prog struct {
+	ProgHeader
+
+	// Embed ReaderAt for ReadAt method.
+	// Do not embed SectionReader directly
+	// to avoid having Read and Seek.
+	// If a client wants Read and Seek it must use
+	// Open() to avoid fighting over the seek offset
+	// with other clients.
+	io.ReaderAt
+	sr *io.SectionReader
+}
+
+// Open returns a new ReadSeeker reading the ELF program body.
+func (p *Prog) Open() io.ReadSeeker { return io.NewSectionReader(p.sr, 0, 1<<63-1) }
+
+// A Symbol represents an entry in an ELF symbol table section.
+type Symbol struct {
+	Name        string
+	Info, Other byte
+	Section     SectionIndex
+	Value, Size uint64
+}
+
+/*
+ * ELF reader
+ */
+
+type FormatError struct {
+	off int64
+	msg string
+	val interface{}
+}
+
+func (e *FormatError) Error() string {
+	msg := e.msg
+	if e.val != nil {
+		msg += fmt.Sprintf(" '%v' ", e.val)
+	}
+	msg += fmt.Sprintf("in record at byte %#x", e.off)
+	return msg
+}
+
+// Open opens the named file using os.Open and prepares it for use as an ELF binary.
+func Open(name string) (*File, error) {
+	f, err := os.Open(name)
+	if err != nil {
+		return nil, err
+	}
+	ff, err := NewFile(f)
+	if err != nil {
+		f.Close()
+		return nil, err
+	}
+	ff.closer = f
+	return ff, nil
+}
+
+// Close closes the File.
+// If the File was created using NewFile directly instead of Open,
+// Close has no effect.
+func (f *File) Close() error {
+	var err error
+	if f.closer != nil {
+		err = f.closer.Close()
+		f.closer = nil
+	}
+	return err
+}
+
+// SectionByType returns the first section in f with the
+// given type, or nil if there is no such section.
+func (f *File) SectionByType(typ SectionType) *Section {
+	for _, s := range f.Sections {
+		if s.Type == typ {
+			return s
+		}
+	}
+	return nil
+}
+
+// NewFile creates a new File for accessing an ELF binary in an underlying reader.
+// The ELF binary is expected to start at position 0 in the ReaderAt.
+func NewFile(r io.ReaderAt) (*File, error) {
+	sr := io.NewSectionReader(r, 0, 1<<63-1)
+	// Read and decode ELF identifier
+	var ident [16]uint8
+	if _, err := r.ReadAt(ident[0:], 0); err != nil {
+		return nil, err
+	}
+	if ident[0] != '\x7f' || ident[1] != 'E' || ident[2] != 'L' || ident[3] != 'F' {
+		return nil, &FormatError{0, "bad magic number", ident[0:4]}
+	}
+
+	f := new(File)
+	f.Class = Class(ident[EI_CLASS])
+	switch f.Class {
+	case ELFCLASS32:
+	case ELFCLASS64:
+		// ok
+	default:
+		return nil, &FormatError{0, "unknown ELF class", f.Class}
+	}
+
+	f.Data = Data(ident[EI_DATA])
+	switch f.Data {
+	case ELFDATA2LSB:
+		f.ByteOrder = binary.LittleEndian
+	case ELFDATA2MSB:
+		f.ByteOrder = binary.BigEndian
+	default:
+		return nil, &FormatError{0, "unknown ELF data encoding", f.Data}
+	}
+
+	f.Version = Version(ident[EI_VERSION])
+	if f.Version != EV_CURRENT {
+		return nil, &FormatError{0, "unknown ELF version", f.Version}
+	}
+
+	f.OSABI = OSABI(ident[EI_OSABI])
+	f.ABIVersion = ident[EI_ABIVERSION]
+
+	// Read ELF file header
+	var phoff int64
+	var phentsize, phnum int
+	var shoff int64
+	var shentsize, shnum, shstrndx int
+	shstrndx = -1
+	switch f.Class {
+	case ELFCLASS32:
+		hdr := new(Header32)
+		sr.Seek(0, os.SEEK_SET)
+		if err := binary.Read(sr, f.ByteOrder, hdr); err != nil {
+			return nil, err
+		}
+		f.Type = Type(hdr.Type)
+		f.Machine = Machine(hdr.Machine)
+		f.Entry = uint64(hdr.Entry)
+		if v := Version(hdr.Version); v != f.Version {
+			return nil, &FormatError{0, "mismatched ELF version", v}
+		}
+		phoff = int64(hdr.Phoff)
+		phentsize = int(hdr.Phentsize)
+		phnum = int(hdr.Phnum)
+		shoff = int64(hdr.Shoff)
+		shentsize = int(hdr.Shentsize)
+		shnum = int(hdr.Shnum)
+		shstrndx = int(hdr.Shstrndx)
+	case ELFCLASS64:
+		hdr := new(Header64)
+		sr.Seek(0, os.SEEK_SET)
+		if err := binary.Read(sr, f.ByteOrder, hdr); err != nil {
+			return nil, err
+		}
+		f.Type = Type(hdr.Type)
+		f.Machine = Machine(hdr.Machine)
+		f.Entry = uint64(hdr.Entry)
+		if v := Version(hdr.Version); v != f.Version {
+			return nil, &FormatError{0, "mismatched ELF version", v}
+		}
+		phoff = int64(hdr.Phoff)
+		phentsize = int(hdr.Phentsize)
+		phnum = int(hdr.Phnum)
+		shoff = int64(hdr.Shoff)
+		shentsize = int(hdr.Shentsize)
+		shnum = int(hdr.Shnum)
+		shstrndx = int(hdr.Shstrndx)
+	}
+
+	if shnum > 0 && shoff > 0 && (shstrndx < 0 || shstrndx >= shnum) {
+		return nil, &FormatError{0, "invalid ELF shstrndx", shstrndx}
+	}
+
+	// Read program headers
+	f.Progs = make([]*Prog, phnum)
+	for i := 0; i < phnum; i++ {
+		off := phoff + int64(i)*int64(phentsize)
+		sr.Seek(off, os.SEEK_SET)
+		p := new(Prog)
+		switch f.Class {
+		case ELFCLASS32:
+			ph := new(Prog32)
+			if err := binary.Read(sr, f.ByteOrder, ph); err != nil {
+				return nil, err
+			}
+			p.ProgHeader = ProgHeader{
+				Type:   ProgType(ph.Type),
+				Flags:  ProgFlag(ph.Flags),
+				Off:    uint64(ph.Off),
+				Vaddr:  uint64(ph.Vaddr),
+				Paddr:  uint64(ph.Paddr),
+				Filesz: uint64(ph.Filesz),
+				Memsz:  uint64(ph.Memsz),
+				Align:  uint64(ph.Align),
+			}
+		case ELFCLASS64:
+			ph := new(Prog64)
+			if err := binary.Read(sr, f.ByteOrder, ph); err != nil {
+				return nil, err
+			}
+			p.ProgHeader = ProgHeader{
+				Type:   ProgType(ph.Type),
+				Flags:  ProgFlag(ph.Flags),
+				Off:    uint64(ph.Off),
+				Vaddr:  uint64(ph.Vaddr),
+				Paddr:  uint64(ph.Paddr),
+				Filesz: uint64(ph.Filesz),
+				Memsz:  uint64(ph.Memsz),
+				Align:  uint64(ph.Align),
+			}
+		}
+		p.sr = io.NewSectionReader(r, int64(p.Off), int64(p.Filesz))
+		p.ReaderAt = p.sr
+		f.Progs[i] = p
+	}
+
+	// Read section headers
+	f.Sections = make([]*Section, shnum)
+	names := make([]uint32, shnum)
+	for i := 0; i < shnum; i++ {
+		off := shoff + int64(i)*int64(shentsize)
+		sr.Seek(off, os.SEEK_SET)
+		s := new(Section)
+		switch f.Class {
+		case ELFCLASS32:
+			sh := new(Section32)
+			if err := binary.Read(sr, f.ByteOrder, sh); err != nil {
+				return nil, err
+			}
+			names[i] = sh.Name
+			s.SectionHeader = SectionHeader{
+				Type:      SectionType(sh.Type),
+				Flags:     SectionFlag(sh.Flags),
+				Addr:      uint64(sh.Addr),
+				Offset:    uint64(sh.Off),
+				Size:      uint64(sh.Size),
+				Link:      uint32(sh.Link),
+				Info:      uint32(sh.Info),
+				Addralign: uint64(sh.Addralign),
+				Entsize:   uint64(sh.Entsize),
+			}
+		case ELFCLASS64:
+			sh := new(Section64)
+			if err := binary.Read(sr, f.ByteOrder, sh); err != nil {
+				return nil, err
+			}
+			names[i] = sh.Name
+			s.SectionHeader = SectionHeader{
+				Type:      SectionType(sh.Type),
+				Flags:     SectionFlag(sh.Flags),
+				Offset:    uint64(sh.Off),
+				Size:      uint64(sh.Size),
+				Addr:      uint64(sh.Addr),
+				Link:      uint32(sh.Link),
+				Info:      uint32(sh.Info),
+				Addralign: uint64(sh.Addralign),
+				Entsize:   uint64(sh.Entsize),
+			}
+		}
+		s.sr = io.NewSectionReader(r, int64(s.Offset), int64(s.Size))
+		s.ReaderAt = s.sr
+		f.Sections[i] = s
+	}
+
+	if len(f.Sections) == 0 {
+		return f, nil
+	}
+
+	// Load section header string table.
+	shstrtab, err := f.Sections[shstrndx].Data()
+	if err != nil {
+		return nil, err
+	}
+	for i, s := range f.Sections {
+		var ok bool
+		s.Name, ok = getString(shstrtab, int(names[i]))
+		if !ok {
+			return nil, &FormatError{shoff + int64(i*shentsize), "bad section name index", names[i]}
+		}
+	}
+
+	return f, nil
+}
+
+// getSymbols returns a slice of Symbols from parsing the symbol table
+// with the given type, along with the associated string table.
+func (f *File) getSymbols(typ SectionType) ([]Symbol, []byte, error) {
+	switch f.Class {
+	case ELFCLASS64:
+		return f.getSymbols64(typ)
+
+	case ELFCLASS32:
+		return f.getSymbols32(typ)
+	}
+
+	return nil, nil, errors.New("not implemented")
+}
+
+// ErrNoSymbols is returned by File.Symbols and File.DynamicSymbols
+// if there is no such section in the File.
+var ErrNoSymbols = errors.New("no symbol section")
+
+func (f *File) getSymbols32(typ SectionType) ([]Symbol, []byte, error) {
+	symtabSection := f.SectionByType(typ)
+	if symtabSection == nil {
+		return nil, nil, ErrNoSymbols
+	}
+
+	data, err := symtabSection.Data()
+	if err != nil {
+		return nil, nil, errors.New("cannot load symbol section")
+	}
+	symtab := bytes.NewReader(data)
+	if symtab.Len()%Sym32Size != 0 {
+		return nil, nil, errors.New("length of symbol section is not a multiple of SymSize")
+	}
+
+	strdata, err := f.stringTable(symtabSection.Link)
+	if err != nil {
+		return nil, nil, errors.New("cannot load string table section")
+	}
+
+	// The first entry is all zeros.
+	var skip [Sym32Size]byte
+	symtab.Read(skip[:])
+
+	symbols := make([]Symbol, symtab.Len()/Sym32Size)
+
+	i := 0
+	var sym Sym32
+	for symtab.Len() > 0 {
+		binary.Read(symtab, f.ByteOrder, &sym)
+		str, _ := getString(strdata, int(sym.Name))
+		symbols[i].Name = str
+		symbols[i].Info = sym.Info
+		symbols[i].Other = sym.Other
+		symbols[i].Section = SectionIndex(sym.Shndx)
+		symbols[i].Value = uint64(sym.Value)
+		symbols[i].Size = uint64(sym.Size)
+		i++
+	}
+
+	return symbols, strdata, nil
+}
+
+func (f *File) getSymbols64(typ SectionType) ([]Symbol, []byte, error) {
+	symtabSection := f.SectionByType(typ)
+	if symtabSection == nil {
+		return nil, nil, ErrNoSymbols
+	}
+
+	data, err := symtabSection.Data()
+	if err != nil {
+		return nil, nil, errors.New("cannot load symbol section")
+	}
+	symtab := bytes.NewReader(data)
+	if symtab.Len()%Sym64Size != 0 {
+		return nil, nil, errors.New("length of symbol section is not a multiple of Sym64Size")
+	}
+
+	strdata, err := f.stringTable(symtabSection.Link)
+	if err != nil {
+		return nil, nil, errors.New("cannot load string table section")
+	}
+
+	// The first entry is all zeros.
+	var skip [Sym64Size]byte
+	symtab.Read(skip[:])
+
+	symbols := make([]Symbol, symtab.Len()/Sym64Size)
+
+	i := 0
+	var sym Sym64
+	for symtab.Len() > 0 {
+		binary.Read(symtab, f.ByteOrder, &sym)
+		str, _ := getString(strdata, int(sym.Name))
+		symbols[i].Name = str
+		symbols[i].Info = sym.Info
+		symbols[i].Other = sym.Other
+		symbols[i].Section = SectionIndex(sym.Shndx)
+		symbols[i].Value = sym.Value
+		symbols[i].Size = sym.Size
+		i++
+	}
+
+	return symbols, strdata, nil
+}
+
+// getString extracts a string from an ELF string table.
+func getString(section []byte, start int) (string, bool) {
+	if start < 0 || start >= len(section) {
+		return "", false
+	}
+
+	for end := start; end < len(section); end++ {
+		if section[end] == 0 {
+			return string(section[start:end]), true
+		}
+	}
+	return "", false
+}
+
+// Section returns a section with the given name, or nil if no such
+// section exists.
+func (f *File) Section(name string) *Section {
+	for _, s := range f.Sections {
+		if s.Name == name {
+			return s
+		}
+	}
+	return nil
+}
+
+// applyRelocations applies relocations to dst. rels is a relocations section
+// in RELA format.
+func (f *File) applyRelocations(dst []byte, rels []byte) error {
+	if f.Class == ELFCLASS64 && f.Machine == EM_X86_64 {
+		return f.applyRelocationsAMD64(dst, rels)
+	}
+	if f.Class == ELFCLASS32 && f.Machine == EM_386 {
+		return f.applyRelocations386(dst, rels)
+	}
+	if f.Class == ELFCLASS64 && f.Machine == EM_AARCH64 {
+		return f.applyRelocationsARM64(dst, rels)
+	}
+
+	return errors.New("not implemented")
+}
+
+func (f *File) applyRelocationsAMD64(dst []byte, rels []byte) error {
+	// 24 is the size of Rela64.
+	if len(rels)%24 != 0 {
+		return errors.New("length of relocation section is not a multiple of 24")
+	}
+
+	symbols, _, err := f.getSymbols(SHT_SYMTAB)
+	if err != nil {
+		return err
+	}
+
+	b := bytes.NewReader(rels)
+	var rela Rela64
+
+	for b.Len() > 0 {
+		binary.Read(b, f.ByteOrder, &rela)
+		symNo := rela.Info >> 32
+		t := R_X86_64(rela.Info & 0xffff)
+
+		if symNo == 0 || symNo > uint64(len(symbols)) {
+			continue
+		}
+		sym := &symbols[symNo-1]
+		if SymType(sym.Info&0xf) != STT_SECTION {
+			// We don't handle non-section relocations for now.
+			continue
+		}
+
+		// There are relocations, so this must be a normal
+		// object file, and we only look at section symbols,
+		// so we assume that the symbol value is 0.
+
+		switch t {
+		case R_X86_64_64:
+			if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 {
+				continue
+			}
+			f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], uint64(rela.Addend))
+		case R_X86_64_32:
+			if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 {
+				continue
+			}
+			f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], uint32(rela.Addend))
+		}
+	}
+
+	return nil
+}
+
+func (f *File) applyRelocations386(dst []byte, rels []byte) error {
+	// 8 is the size of Rel32.
+	if len(rels)%8 != 0 {
+		return errors.New("length of relocation section is not a multiple of 8")
+	}
+
+	symbols, _, err := f.getSymbols(SHT_SYMTAB)
+	if err != nil {
+		return err
+	}
+
+	b := bytes.NewReader(rels)
+	var rel Rel32
+
+	for b.Len() > 0 {
+		binary.Read(b, f.ByteOrder, &rel)
+		symNo := rel.Info >> 8
+		t := R_386(rel.Info & 0xff)
+
+		if symNo == 0 || symNo > uint32(len(symbols)) {
+			continue
+		}
+		sym := &symbols[symNo-1]
+
+		if t == R_386_32 {
+			if rel.Off+4 >= uint32(len(dst)) {
+				continue
+			}
+			val := f.ByteOrder.Uint32(dst[rel.Off : rel.Off+4])
+			val += uint32(sym.Value)
+			f.ByteOrder.PutUint32(dst[rel.Off:rel.Off+4], val)
+		}
+	}
+
+	return nil
+}
+
+func (f *File) applyRelocationsARM64(dst []byte, rels []byte) error {
+	// 24 is the size of Rela64.
+	if len(rels)%24 != 0 {
+		return errors.New("length of relocation section is not a multiple of 24")
+	}
+
+	symbols, _, err := f.getSymbols(SHT_SYMTAB)
+	if err != nil {
+		return err
+	}
+
+	b := bytes.NewReader(rels)
+	var rela Rela64
+
+	for b.Len() > 0 {
+		binary.Read(b, f.ByteOrder, &rela)
+		symNo := rela.Info >> 32
+		t := R_AARCH64(rela.Info & 0xffff)
+
+		if symNo == 0 || symNo > uint64(len(symbols)) {
+			continue
+		}
+		sym := &symbols[symNo-1]
+		if SymType(sym.Info&0xf) != STT_SECTION {
+			// We don't handle non-section relocations for now.
+			continue
+		}
+
+		// There are relocations, so this must be a normal
+		// object file, and we only look at section symbols,
+		// so we assume that the symbol value is 0.
+
+		switch t {
+		case R_AARCH64_ABS64:
+			if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 {
+				continue
+			}
+			f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], uint64(rela.Addend))
+		case R_AARCH64_ABS32:
+			if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 {
+				continue
+			}
+			f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], uint32(rela.Addend))
+		}
+	}
+
+	return nil
+}
+
+func (f *File) DWARF() (*dwarf.Data, error) {
+	// There are many other DWARF sections, but these
+	// are the required ones, and the debug/dwarf package
+	// does not use the others, so don't bother loading them.
+	var names = [...]string{"abbrev", "info", "str"}
+	var dat [len(names)][]byte
+	for i, name := range names {
+		name = ".debug_" + name
+		s := f.Section(name)
+		if s == nil {
+			continue
+		}
+		b, err := s.Data()
+		if err != nil && uint64(len(b)) < s.Size {
+			return nil, err
+		}
+		dat[i] = b
+	}
+
+	// If there's a relocation table for .debug_info, we have to process it
+	// now otherwise the data in .debug_info is invalid for x86-64 objects.
+	rela := f.Section(".rela.debug_info")
+	if rela != nil && rela.Type == SHT_RELA && (f.Machine == EM_X86_64 || f.Machine == EM_AARCH64) {
+		data, err := rela.Data()
+		if err != nil {
+			return nil, err
+		}
+		err = f.applyRelocations(dat[1], data)
+		if err != nil {
+			return nil, err
+		}
+	}
+
+	// When using clang we need to process relocations even for 386.
+	rel := f.Section(".rel.debug_info")
+	if rel != nil && rel.Type == SHT_REL && f.Machine == EM_386 {
+		data, err := rel.Data()
+		if err != nil {
+			return nil, err
+		}
+		err = f.applyRelocations(dat[1], data)
+		if err != nil {
+			return nil, err
+		}
+	}
+
+	abbrev, info, str := dat[0], dat[1], dat[2]
+	d, err := dwarf.New(abbrev, nil, nil, info, nil, nil, nil, str)
+	if err != nil {
+		return nil, err
+	}
+
+	// Look for DWARF4 .debug_types sections.
+	for i, s := range f.Sections {
+		if s.Name == ".debug_types" {
+			b, err := s.Data()
+			if err != nil && uint64(len(b)) < s.Size {
+				return nil, err
+			}
+
+			for _, r := range f.Sections {
+				if r.Type != SHT_RELA && r.Type != SHT_REL {
+					continue
+				}
+				if int(r.Info) != i {
+					continue
+				}
+				rd, err := r.Data()
+				if err != nil {
+					return nil, err
+				}
+				err = f.applyRelocations(b, rd)
+				if err != nil {
+					return nil, err
+				}
+			}
+
+			err = d.AddTypes(fmt.Sprintf("types-%d", i), b)
+			if err != nil {
+				return nil, err
+			}
+		}
+	}
+
+	return d, nil
+}
+
+// Symbols returns the symbol table for f. The symbols will be listed in the order
+// they appear in f.
+//
+// For compatibility with Go 1.0, Symbols omits the null symbol at index 0.
+// After retrieving the symbols as symtab, an externally supplied index x
+// corresponds to symtab[x-1], not symtab[x].
+func (f *File) Symbols() ([]Symbol, error) {
+	sym, _, err := f.getSymbols(SHT_SYMTAB)
+	return sym, err
+}
+
+// DynamicSymbols returns the dynamic symbol table for f. The symbols
+// will be listed in the order they appear in f.
+//
+// For compatibility with Symbols, DynamicSymbols omits the null symbol at index 0.
+// After retrieving the symbols as symtab, an externally supplied index x
+// corresponds to symtab[x-1], not symtab[x].
+func (f *File) DynamicSymbols() ([]Symbol, error) {
+	sym, _, err := f.getSymbols(SHT_DYNSYM)
+	return sym, err
+}
+
+type ImportedSymbol struct {
+	Name    string
+	Version string
+	Library string
+}
+
+// ImportedSymbols returns the names of all symbols
+// referred to by the binary f that are expected to be
+// satisfied by other libraries at dynamic load time.
+// It does not return weak symbols.
+func (f *File) ImportedSymbols() ([]ImportedSymbol, error) {
+	sym, str, err := f.getSymbols(SHT_DYNSYM)
+	if err != nil {
+		return nil, err
+	}
+	f.gnuVersionInit(str)
+	var all []ImportedSymbol
+	for i, s := range sym {
+		if ST_BIND(s.Info) == STB_GLOBAL && s.Section == SHN_UNDEF {
+			all = append(all, ImportedSymbol{Name: s.Name})
+			f.gnuVersion(i, &all[len(all)-1])
+		}
+	}
+	return all, nil
+}
+
+type verneed struct {
+	File string
+	Name string
+}
+
+// gnuVersionInit parses the GNU version tables
+// for use by calls to gnuVersion.
+func (f *File) gnuVersionInit(str []byte) {
+	// Accumulate verneed information.
+	vn := f.SectionByType(SHT_GNU_VERNEED)
+	if vn == nil {
+		return
+	}
+	d, _ := vn.Data()
+
+	var need []verneed
+	i := 0
+	for {
+		if i+16 > len(d) {
+			break
+		}
+		vers := f.ByteOrder.Uint16(d[i : i+2])
+		if vers != 1 {
+			break
+		}
+		cnt := f.ByteOrder.Uint16(d[i+2 : i+4])
+		fileoff := f.ByteOrder.Uint32(d[i+4 : i+8])
+		aux := f.ByteOrder.Uint32(d[i+8 : i+12])
+		next := f.ByteOrder.Uint32(d[i+12 : i+16])
+		file, _ := getString(str, int(fileoff))
+
+		var name string
+		j := i + int(aux)
+		for c := 0; c < int(cnt); c++ {
+			if j+16 > len(d) {
+				break
+			}
+			// hash := f.ByteOrder.Uint32(d[j:j+4])
+			// flags := f.ByteOrder.Uint16(d[j+4:j+6])
+			other := f.ByteOrder.Uint16(d[j+6 : j+8])
+			nameoff := f.ByteOrder.Uint32(d[j+8 : j+12])
+			next := f.ByteOrder.Uint32(d[j+12 : j+16])
+			name, _ = getString(str, int(nameoff))
+			ndx := int(other)
+			if ndx >= len(need) {
+				a := make([]verneed, 2*(ndx+1))
+				copy(a, need)
+				need = a
+			}
+
+			need[ndx] = verneed{file, name}
+			if next == 0 {
+				break
+			}
+			j += int(next)
+		}
+
+		if next == 0 {
+			break
+		}
+		i += int(next)
+	}
+
+	// Versym parallels symbol table, indexing into verneed.
+	vs := f.SectionByType(SHT_GNU_VERSYM)
+	if vs == nil {
+		return
+	}
+	d, _ = vs.Data()
+
+	f.gnuNeed = need
+	f.gnuVersym = d
+}
+
+// gnuVersion adds Library and Version information to sym,
+// which came from offset i of the symbol table.
+func (f *File) gnuVersion(i int, sym *ImportedSymbol) {
+	// Each entry is two bytes.
+	i = (i + 1) * 2
+	if i >= len(f.gnuVersym) {
+		return
+	}
+	j := int(f.ByteOrder.Uint16(f.gnuVersym[i:]))
+	if j < 2 || j >= len(f.gnuNeed) {
+		return
+	}
+	n := &f.gnuNeed[j]
+	sym.Library = n.File
+	sym.Version = n.Name
+}
+
+// ImportedLibraries returns the names of all libraries
+// referred to by the binary f that are expected to be
+// linked with the binary at dynamic link time.
+func (f *File) ImportedLibraries() ([]string, error) {
+	return f.DynString(DT_NEEDED)
+}
+
+// DynString returns the strings listed for the given tag in the file's dynamic
+// section.
+//
+// The tag must be one that takes string values: DT_NEEDED, DT_SONAME, DT_RPATH, or
+// DT_RUNPATH.
+func (f *File) DynString(tag DynTag) ([]string, error) {
+	switch tag {
+	case DT_NEEDED, DT_SONAME, DT_RPATH, DT_RUNPATH:
+	default:
+		return nil, fmt.Errorf("non-string-valued tag %v", tag)
+	}
+	ds := f.SectionByType(SHT_DYNAMIC)
+	if ds == nil {
+		// not dynamic, so no libraries
+		return nil, nil
+	}
+	d, err := ds.Data()
+	if err != nil {
+		return nil, err
+	}
+	str, err := f.stringTable(ds.Link)
+	if err != nil {
+		return nil, err
+	}
+	var all []string
+	for len(d) > 0 {
+		var t DynTag
+		var v uint64
+		switch f.Class {
+		case ELFCLASS32:
+			t = DynTag(f.ByteOrder.Uint32(d[0:4]))
+			v = uint64(f.ByteOrder.Uint32(d[4:8]))
+			d = d[8:]
+		case ELFCLASS64:
+			t = DynTag(f.ByteOrder.Uint64(d[0:8]))
+			v = f.ByteOrder.Uint64(d[8:16])
+			d = d[16:]
+		}
+		if t == tag {
+			s, ok := getString(str, int(v))
+			if ok {
+				all = append(all, s)
+			}
+		}
+	}
+	return all, nil
+}
diff --git a/src/debug/elf/file_test.go b/src/debug/elf/file_test.go
new file mode 100644
index 0000000..5e5ba52
--- /dev/null
+++ b/src/debug/elf/file_test.go
@@ -0,0 +1,345 @@
+// Copyright 2009 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package elf
+
+import (
+	"bytes"
+	"compress/gzip"
+	"debug/dwarf"
+	"encoding/binary"
+	"io"
+	"net"
+	"os"
+	"path"
+	"reflect"
+	"runtime"
+	"testing"
+)
+
+type fileTest struct {
+	file     string
+	hdr      FileHeader
+	sections []SectionHeader
+	progs    []ProgHeader
+	needed   []string
+}
+
+var fileTests = []fileTest{
+	{
+		"testdata/gcc-386-freebsd-exec",
+		FileHeader{ELFCLASS32, ELFDATA2LSB, EV_CURRENT, ELFOSABI_FREEBSD, 0, binary.LittleEndian, ET_EXEC, EM_386, 0x80483cc},
+		[]SectionHeader{
+			{"", SHT_NULL, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
+			{".interp", SHT_PROGBITS, SHF_ALLOC, 0x80480d4, 0xd4, 0x15, 0x0, 0x0, 0x1, 0x0},
+			{".hash", SHT_HASH, SHF_ALLOC, 0x80480ec, 0xec, 0x90, 0x3, 0x0, 0x4, 0x4},
+			{".dynsym", SHT_DYNSYM, SHF_ALLOC, 0x804817c, 0x17c, 0x110, 0x4, 0x1, 0x4, 0x10},
+			{".dynstr", SHT_STRTAB, SHF_ALLOC, 0x804828c, 0x28c, 0xbb, 0x0, 0x0, 0x1, 0x0},
+			{".rel.plt", SHT_REL, SHF_ALLOC, 0x8048348, 0x348, 0x20, 0x3, 0x7, 0x4, 0x8},
+			{".init", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x8048368, 0x368, 0x11, 0x0, 0x0, 0x4, 0x0},
+			{".plt", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x804837c, 0x37c, 0x50, 0x0, 0x0, 0x4, 0x4},
+			{".text", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x80483cc, 0x3cc, 0x180, 0x0, 0x0, 0x4, 0x0},
+			{".fini", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x804854c, 0x54c, 0xc, 0x0, 0x0, 0x4, 0x0},
+			{".rodata", SHT_PROGBITS, SHF_ALLOC, 0x8048558, 0x558, 0xa3, 0x0, 0x0, 0x1, 0x0},
+			{".data", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x80495fc, 0x5fc, 0xc, 0x0, 0x0, 0x4, 0x0},
+			{".eh_frame", SHT_PROGBITS, SHF_ALLOC, 0x8049608, 0x608, 0x4, 0x0, 0x0, 0x4, 0x0},
+			{".dynamic", SHT_DYNAMIC, SHF_WRITE + SHF_ALLOC, 0x804960c, 0x60c, 0x98, 0x4, 0x0, 0x4, 0x8},
+			{".ctors", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x80496a4, 0x6a4, 0x8, 0x0, 0x0, 0x4, 0x0},
+			{".dtors", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x80496ac, 0x6ac, 0x8, 0x0, 0x0, 0x4, 0x0},
+			{".jcr", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x80496b4, 0x6b4, 0x4, 0x0, 0x0, 0x4, 0x0},
+			{".got", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x80496b8, 0x6b8, 0x1c, 0x0, 0x0, 0x4, 0x4},
+			{".bss", SHT_NOBITS, SHF_WRITE + SHF_ALLOC, 0x80496d4, 0x6d4, 0x20, 0x0, 0x0, 0x4, 0x0},
+			{".comment", SHT_PROGBITS, 0x0, 0x0, 0x6d4, 0x12d, 0x0, 0x0, 0x1, 0x0},
+			{".debug_aranges", SHT_PROGBITS, 0x0, 0x0, 0x801, 0x20, 0x0, 0x0, 0x1, 0x0},
+			{".debug_pubnames", SHT_PROGBITS, 0x0, 0x0, 0x821, 0x1b, 0x0, 0x0, 0x1, 0x0},
+			{".debug_info", SHT_PROGBITS, 0x0, 0x0, 0x83c, 0x11d, 0x0, 0x0, 0x1, 0x0},
+			{".debug_abbrev", SHT_PROGBITS, 0x0, 0x0, 0x959, 0x41, 0x0, 0x0, 0x1, 0x0},
+			{".debug_line", SHT_PROGBITS, 0x0, 0x0, 0x99a, 0x35, 0x0, 0x0, 0x1, 0x0},
+			{".debug_frame", SHT_PROGBITS, 0x0, 0x0, 0x9d0, 0x30, 0x0, 0x0, 0x4, 0x0},
+			{".debug_str", SHT_PROGBITS, 0x0, 0x0, 0xa00, 0xd, 0x0, 0x0, 0x1, 0x0},
+			{".shstrtab", SHT_STRTAB, 0x0, 0x0, 0xa0d, 0xf8, 0x0, 0x0, 0x1, 0x0},
+			{".symtab", SHT_SYMTAB, 0x0, 0x0, 0xfb8, 0x4b0, 0x1d, 0x38, 0x4, 0x10},
+			{".strtab", SHT_STRTAB, 0x0, 0x0, 0x1468, 0x206, 0x0, 0x0, 0x1, 0x0},
+		},
+		[]ProgHeader{
+			{PT_PHDR, PF_R + PF_X, 0x34, 0x8048034, 0x8048034, 0xa0, 0xa0, 0x4},
+			{PT_INTERP, PF_R, 0xd4, 0x80480d4, 0x80480d4, 0x15, 0x15, 0x1},
+			{PT_LOAD, PF_R + PF_X, 0x0, 0x8048000, 0x8048000, 0x5fb, 0x5fb, 0x1000},
+			{PT_LOAD, PF_R + PF_W, 0x5fc, 0x80495fc, 0x80495fc, 0xd8, 0xf8, 0x1000},
+			{PT_DYNAMIC, PF_R + PF_W, 0x60c, 0x804960c, 0x804960c, 0x98, 0x98, 0x4},
+		},
+		[]string{"libc.so.6"},
+	},
+	{
+		"testdata/gcc-amd64-linux-exec",
+		FileHeader{ELFCLASS64, ELFDATA2LSB, EV_CURRENT, ELFOSABI_NONE, 0, binary.LittleEndian, ET_EXEC, EM_X86_64, 0x4003e0},
+		[]SectionHeader{
+			{"", SHT_NULL, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
+			{".interp", SHT_PROGBITS, SHF_ALLOC, 0x400200, 0x200, 0x1c, 0x0, 0x0, 0x1, 0x0},
+			{".note.ABI-tag", SHT_NOTE, SHF_ALLOC, 0x40021c, 0x21c, 0x20, 0x0, 0x0, 0x4, 0x0},
+			{".hash", SHT_HASH, SHF_ALLOC, 0x400240, 0x240, 0x24, 0x5, 0x0, 0x8, 0x4},
+			{".gnu.hash", SHT_LOOS + 268435446, SHF_ALLOC, 0x400268, 0x268, 0x1c, 0x5, 0x0, 0x8, 0x0},
+			{".dynsym", SHT_DYNSYM, SHF_ALLOC, 0x400288, 0x288, 0x60, 0x6, 0x1, 0x8, 0x18},
+			{".dynstr", SHT_STRTAB, SHF_ALLOC, 0x4002e8, 0x2e8, 0x3d, 0x0, 0x0, 0x1, 0x0},
+			{".gnu.version", SHT_HIOS, SHF_ALLOC, 0x400326, 0x326, 0x8, 0x5, 0x0, 0x2, 0x2},
+			{".gnu.version_r", SHT_LOOS + 268435454, SHF_ALLOC, 0x400330, 0x330, 0x20, 0x6, 0x1, 0x8, 0x0},
+			{".rela.dyn", SHT_RELA, SHF_ALLOC, 0x400350, 0x350, 0x18, 0x5, 0x0, 0x8, 0x18},
+			{".rela.plt", SHT_RELA, SHF_ALLOC, 0x400368, 0x368, 0x30, 0x5, 0xc, 0x8, 0x18},
+			{".init", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x400398, 0x398, 0x18, 0x0, 0x0, 0x4, 0x0},
+			{".plt", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x4003b0, 0x3b0, 0x30, 0x0, 0x0, 0x4, 0x10},
+			{".text", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x4003e0, 0x3e0, 0x1b4, 0x0, 0x0, 0x10, 0x0},
+			{".fini", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x400594, 0x594, 0xe, 0x0, 0x0, 0x4, 0x0},
+			{".rodata", SHT_PROGBITS, SHF_ALLOC, 0x4005a4, 0x5a4, 0x11, 0x0, 0x0, 0x4, 0x0},
+			{".eh_frame_hdr", SHT_PROGBITS, SHF_ALLOC, 0x4005b8, 0x5b8, 0x24, 0x0, 0x0, 0x4, 0x0},
+			{".eh_frame", SHT_PROGBITS, SHF_ALLOC, 0x4005e0, 0x5e0, 0xa4, 0x0, 0x0, 0x8, 0x0},
+			{".ctors", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x600688, 0x688, 0x10, 0x0, 0x0, 0x8, 0x0},
+			{".dtors", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x600698, 0x698, 0x10, 0x0, 0x0, 0x8, 0x0},
+			{".jcr", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x6006a8, 0x6a8, 0x8, 0x0, 0x0, 0x8, 0x0},
+			{".dynamic", SHT_DYNAMIC, SHF_WRITE + SHF_ALLOC, 0x6006b0, 0x6b0, 0x1a0, 0x6, 0x0, 0x8, 0x10},
+			{".got", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x600850, 0x850, 0x8, 0x0, 0x0, 0x8, 0x8},
+			{".got.plt", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x600858, 0x858, 0x28, 0x0, 0x0, 0x8, 0x8},
+			{".data", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x600880, 0x880, 0x18, 0x0, 0x0, 0x8, 0x0},
+			{".bss", SHT_NOBITS, SHF_WRITE + SHF_ALLOC, 0x600898, 0x898, 0x8, 0x0, 0x0, 0x4, 0x0},
+			{".comment", SHT_PROGBITS, 0x0, 0x0, 0x898, 0x126, 0x0, 0x0, 0x1, 0x0},
+			{".debug_aranges", SHT_PROGBITS, 0x0, 0x0, 0x9c0, 0x90, 0x0, 0x0, 0x10, 0x0},
+			{".debug_pubnames", SHT_PROGBITS, 0x0, 0x0, 0xa50, 0x25, 0x0, 0x0, 0x1, 0x0},
+			{".debug_info", SHT_PROGBITS, 0x0, 0x0, 0xa75, 0x1a7, 0x0, 0x0, 0x1, 0x0},
+			{".debug_abbrev", SHT_PROGBITS, 0x0, 0x0, 0xc1c, 0x6f, 0x0, 0x0, 0x1, 0x0},
+			{".debug_line", SHT_PROGBITS, 0x0, 0x0, 0xc8b, 0x13f, 0x0, 0x0, 0x1, 0x0},
+			{".debug_str", SHT_PROGBITS, SHF_MERGE + SHF_STRINGS, 0x0, 0xdca, 0xb1, 0x0, 0x0, 0x1, 0x1},
+			{".debug_ranges", SHT_PROGBITS, 0x0, 0x0, 0xe80, 0x90, 0x0, 0x0, 0x10, 0x0},
+			{".shstrtab", SHT_STRTAB, 0x0, 0x0, 0xf10, 0x149, 0x0, 0x0, 0x1, 0x0},
+			{".symtab", SHT_SYMTAB, 0x0, 0x0, 0x19a0, 0x6f0, 0x24, 0x39, 0x8, 0x18},
+			{".strtab", SHT_STRTAB, 0x0, 0x0, 0x2090, 0x1fc, 0x0, 0x0, 0x1, 0x0},
+		},
+		[]ProgHeader{
+			{PT_PHDR, PF_R + PF_X, 0x40, 0x400040, 0x400040, 0x1c0, 0x1c0, 0x8},
+			{PT_INTERP, PF_R, 0x200, 0x400200, 0x400200, 0x1c, 0x1c, 1},
+			{PT_LOAD, PF_R + PF_X, 0x0, 0x400000, 0x400000, 0x684, 0x684, 0x200000},
+			{PT_LOAD, PF_R + PF_W, 0x688, 0x600688, 0x600688, 0x210, 0x218, 0x200000},
+			{PT_DYNAMIC, PF_R + PF_W, 0x6b0, 0x6006b0, 0x6006b0, 0x1a0, 0x1a0, 0x8},
+			{PT_NOTE, PF_R, 0x21c, 0x40021c, 0x40021c, 0x20, 0x20, 0x4},
+			{PT_LOOS + 0x474E550, PF_R, 0x5b8, 0x4005b8, 0x4005b8, 0x24, 0x24, 0x4},
+			{PT_LOOS + 0x474E551, PF_R + PF_W, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8},
+		},
+		[]string{"libc.so.6"},
+	},
+	{
+		"testdata/hello-world-core.gz",
+		FileHeader{ELFCLASS64, ELFDATA2LSB, EV_CURRENT, ELFOSABI_NONE, 0x0, binary.LittleEndian, ET_CORE, EM_X86_64, 0x0},
+		[]SectionHeader{},
+		[]ProgHeader{
+			{Type: PT_NOTE, Flags: 0x0, Off: 0x3f8, Vaddr: 0x0, Paddr: 0x0, Filesz: 0x8ac, Memsz: 0x0, Align: 0x0},
+			{Type: PT_LOAD, Flags: PF_X + PF_R, Off: 0x1000, Vaddr: 0x400000, Paddr: 0x0, Filesz: 0x0, Memsz: 0x1000, Align: 0x1000},
+			{Type: PT_LOAD, Flags: PF_R, Off: 0x1000, Vaddr: 0x401000, Paddr: 0x0, Filesz: 0x1000, Memsz: 0x1000, Align: 0x1000},
+			{Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0x2000, Vaddr: 0x402000, Paddr: 0x0, Filesz: 0x1000, Memsz: 0x1000, Align: 0x1000},
+			{Type: PT_LOAD, Flags: PF_X + PF_R, Off: 0x3000, Vaddr: 0x7f54078b8000, Paddr: 0x0, Filesz: 0x0, Memsz: 0x1b5000, Align: 0x1000},
+			{Type: PT_LOAD, Flags: 0x0, Off: 0x3000, Vaddr: 0x7f5407a6d000, Paddr: 0x0, Filesz: 0x0, Memsz: 0x1ff000, Align: 0x1000},
+			{Type: PT_LOAD, Flags: PF_R, Off: 0x3000, Vaddr: 0x7f5407c6c000, Paddr: 0x0, Filesz: 0x4000, Memsz: 0x4000, Align: 0x1000},
+			{Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0x7000, Vaddr: 0x7f5407c70000, Paddr: 0x0, Filesz: 0x2000, Memsz: 0x2000, Align: 0x1000},
+			{Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0x9000, Vaddr: 0x7f5407c72000, Paddr: 0x0, Filesz: 0x5000, Memsz: 0x5000, Align: 0x1000},
+			{Type: PT_LOAD, Flags: PF_X + PF_R, Off: 0xe000, Vaddr: 0x7f5407c77000, Paddr: 0x0, Filesz: 0x0, Memsz: 0x22000, Align: 0x1000},
+			{Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0xe000, Vaddr: 0x7f5407e81000, Paddr: 0x0, Filesz: 0x3000, Memsz: 0x3000, Align: 0x1000},
+			{Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0x11000, Vaddr: 0x7f5407e96000, Paddr: 0x0, Filesz: 0x3000, Memsz: 0x3000, Align: 0x1000},
+			{Type: PT_LOAD, Flags: PF_R, Off: 0x14000, Vaddr: 0x7f5407e99000, Paddr: 0x0, Filesz: 0x1000, Memsz: 0x1000, Align: 0x1000},
+			{Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0x15000, Vaddr: 0x7f5407e9a000, Paddr: 0x0, Filesz: 0x2000, Memsz: 0x2000, Align: 0x1000},
+			{Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0x17000, Vaddr: 0x7fff79972000, Paddr: 0x0, Filesz: 0x23000, Memsz: 0x23000, Align: 0x1000},
+			{Type: PT_LOAD, Flags: PF_X + PF_R, Off: 0x3a000, Vaddr: 0x7fff799f8000, Paddr: 0x0, Filesz: 0x1000, Memsz: 0x1000, Align: 0x1000},
+			{Type: PT_LOAD, Flags: PF_X + PF_R, Off: 0x3b000, Vaddr: 0xffffffffff600000, Paddr: 0x0, Filesz: 0x1000, Memsz: 0x1000, Align: 0x1000},
+		},
+		nil,
+	},
+}
+
+func TestOpen(t *testing.T) {
+	for i := range fileTests {
+		tt := &fileTests[i]
+
+		var f *File
+		var err error
+		if path.Ext(tt.file) == ".gz" {
+			var r io.ReaderAt
+			if r, err = decompress(tt.file); err == nil {
+				f, err = NewFile(r)
+			}
+		} else {
+			f, err = Open(tt.file)
+		}
+		if err != nil {
+			t.Errorf("cannot open file %s: %v", tt.file, err)
+			continue
+		}
+		defer f.Close()
+		if !reflect.DeepEqual(f.FileHeader, tt.hdr) {
+			t.Errorf("open %s:\n\thave %#v\n\twant %#v\n", tt.file, f.FileHeader, tt.hdr)
+			continue
+		}
+		for i, s := range f.Sections {
+			if i >= len(tt.sections) {
+				break
+			}
+			sh := &tt.sections[i]
+			if !reflect.DeepEqual(&s.SectionHeader, sh) {
+				t.Errorf("open %s, section %d:\n\thave %#v\n\twant %#v\n", tt.file, i, &s.SectionHeader, sh)
+			}
+		}
+		for i, p := range f.Progs {
+			if i >= len(tt.progs) {
+				break
+			}
+			ph := &tt.progs[i]
+			if !reflect.DeepEqual(&p.ProgHeader, ph) {
+				t.Errorf("open %s, program %d:\n\thave %#v\n\twant %#v\n", tt.file, i, &p.ProgHeader, ph)
+			}
+		}
+		tn := len(tt.sections)
+		fn := len(f.Sections)
+		if tn != fn {
+			t.Errorf("open %s: len(Sections) = %d, want %d", tt.file, fn, tn)
+		}
+		tn = len(tt.progs)
+		fn = len(f.Progs)
+		if tn != fn {
+			t.Errorf("open %s: len(Progs) = %d, want %d", tt.file, fn, tn)
+		}
+		tl := tt.needed
+		fl, err := f.ImportedLibraries()
+		if err != nil {
+			t.Error(err)
+		}
+		if !reflect.DeepEqual(tl, fl) {
+			t.Errorf("open %s: DT_NEEDED = %v, want %v", tt.file, tl, fl)
+		}
+	}
+}
+
+// elf.NewFile requires io.ReaderAt, which compress/gzip cannot
+// provide. Decompress the file to a bytes.Reader.
+func decompress(gz string) (io.ReaderAt, error) {
+	in, err := os.Open(gz)
+	if err != nil {
+		return nil, err
+	}
+	defer in.Close()
+	r, err := gzip.NewReader(in)
+	if err != nil {
+		return nil, err
+	}
+	var out bytes.Buffer
+	_, err = io.Copy(&out, r)
+	return bytes.NewReader(out.Bytes()), err
+}
+
+type relocationTestEntry struct {
+	entryNumber int
+	entry       *dwarf.Entry
+}
+
+type relocationTest struct {
+	file    string
+	entries []relocationTestEntry
+}
+
+var relocationTests = []relocationTest{
+	{
+		"testdata/go-relocation-test-gcc441-x86-64.obj",
+		[]relocationTestEntry{
+			{0, &dwarf.Entry{Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{{Attr: dwarf.AttrProducer, Val: "GNU C 4.4.1"}, {Attr: dwarf.AttrLanguage, Val: int64(1)}, {Attr: dwarf.AttrName, Val: "go-relocation-test.c"}, {Attr: dwarf.AttrCompDir, Val: "/tmp"}, {Attr: dwarf.AttrLowpc, Val: uint64(0x0)}, {Attr: dwarf.AttrHighpc, Val: uint64(0x6)}, {Attr: dwarf.AttrStmtList, Val: int64(0)}}}},
+		},
+	},
+	{
+		"testdata/go-relocation-test-gcc441-x86.obj",
+		[]relocationTestEntry{
+			{0, &dwarf.Entry{Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{{Attr: dwarf.AttrProducer, Val: "GNU C 4.4.1"}, {Attr: dwarf.AttrLanguage, Val: int64(1)}, {Attr: dwarf.AttrName, Val: "t.c"}, {Attr: dwarf.AttrCompDir, Val: "/tmp"}, {Attr: dwarf.AttrLowpc, Val: uint64(0x0)}, {Attr: dwarf.AttrHighpc, Val: uint64(0x5)}, {Attr: dwarf.AttrStmtList, Val: int64(0)}}}},
+		},
+	},
+	{
+		"testdata/go-relocation-test-gcc424-x86-64.obj",
+		[]relocationTestEntry{
+			{0, &dwarf.Entry{Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{{Attr: dwarf.AttrProducer, Val: "GNU C 4.2.4 (Ubuntu 4.2.4-1ubuntu4)"}, {Attr: dwarf.AttrLanguage, Val: int64(1)}, {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc424.c"}, {Attr: dwarf.AttrCompDir, Val: "/tmp"}, {Attr: dwarf.AttrLowpc, Val: uint64(0x0)}, {Attr: dwarf.AttrHighpc, Val: uint64(0x6)}, {Attr: dwarf.AttrStmtList, Val: int64(0)}}}},
+		},
+	},
+	{
+		"testdata/go-relocation-test-gcc482-aarch64.obj",
+		[]relocationTestEntry{
+			{0, &dwarf.Entry{Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{{Attr: dwarf.AttrProducer, Val: "GNU C 4.8.2 -g -fstack-protector"}, {Attr: dwarf.AttrLanguage, Val: int64(1)}, {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc482.c"}, {Attr: dwarf.AttrCompDir, Val: "/tmp"}, {Attr: dwarf.AttrLowpc, Val: uint64(0x0)}, {Attr: dwarf.AttrHighpc, Val: int64(0x24)}, {Attr: dwarf.AttrStmtList, Val: int64(0)}}}},
+		},
+	},
+	{
+		"testdata/go-relocation-test-clang-x86.obj",
+		[]relocationTestEntry{
+			{0, &dwarf.Entry{Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{{Attr: dwarf.AttrProducer, Val: "clang version google3-trunk (trunk r209387)"}, {Attr: dwarf.AttrLanguage, Val: int64(12)}, {Attr: dwarf.AttrName, Val: "go-relocation-test-clang.c"}, {Attr: dwarf.AttrStmtList, Val: int64(0)}, {Attr: dwarf.AttrCompDir, Val: "/tmp"}}}},
+		},
+	},
+	{
+		"testdata/gcc-amd64-openbsd-debug-with-rela.obj",
+		[]relocationTestEntry{
+			{203, &dwarf.Entry{Offset: 0xc62, Tag: dwarf.TagMember, Children: false, Field: []dwarf.Field{{Attr: dwarf.AttrName, Val: "it_interval"}, {Attr: dwarf.AttrDeclFile, Val: int64(7)}, {Attr: dwarf.AttrDeclLine, Val: int64(236)}, {Attr: dwarf.AttrType, Val: dwarf.Offset(0xb7f)}, {Attr: dwarf.AttrDataMemberLoc, Val: []byte{0x23, 0x0}}}}},
+			{204, &dwarf.Entry{Offset: 0xc70, Tag: dwarf.TagMember, Children: false, Field: []dwarf.Field{{Attr: dwarf.AttrName, Val: "it_value"}, {Attr: dwarf.AttrDeclFile, Val: int64(7)}, {Attr: dwarf.AttrDeclLine, Val: int64(237)}, {Attr: dwarf.AttrType, Val: dwarf.Offset(0xb7f)}, {Attr: dwarf.AttrDataMemberLoc, Val: []byte{0x23, 0x10}}}}},
+		},
+	},
+}
+
+func TestDWARFRelocations(t *testing.T) {
+	for i, test := range relocationTests {
+		f, err := Open(test.file)
+		if err != nil {
+			t.Error(err)
+			continue
+		}
+		dwarf, err := f.DWARF()
+		if err != nil {
+			t.Error(err)
+			continue
+		}
+		for _, testEntry := range test.entries {
+			reader := dwarf.Reader()
+			for j := 0; j < testEntry.entryNumber; j++ {
+				entry, err := reader.Next()
+				if entry == nil || err != nil {
+					t.Errorf("Failed to skip to entry %d: %v", testEntry.entryNumber, err)
+					continue
+				}
+			}
+			entry, err := reader.Next()
+			if err != nil {
+				t.Error(err)
+				continue
+			}
+			if !reflect.DeepEqual(testEntry.entry, entry) {
+				t.Errorf("#%d/%d: mismatch: got:%#v want:%#v", i, testEntry.entryNumber, entry, testEntry.entry)
+				continue
+			}
+		}
+	}
+}
+
+func TestNoSectionOverlaps(t *testing.T) {
+	// Ensure 6l outputs sections without overlaps.
+	if runtime.GOOS != "linux" && runtime.GOOS != "freebsd" {
+		return // not ELF
+	}
+	_ = net.ResolveIPAddr // force dynamic linkage
+	f, err := Open(os.Args[0])
+	if err != nil {
+		t.Error(err)
+		return
+	}
+	for i, si := range f.Sections {
+		sih := si.SectionHeader
+		if sih.Type == SHT_NOBITS {
+			continue
+		}
+		for j, sj := range f.Sections {
+			sjh := sj.SectionHeader
+			if i == j || sjh.Type == SHT_NOBITS || sih.Offset == sjh.Offset && sih.Size == 0 {
+				continue
+			}
+			if sih.Offset >= sjh.Offset && sih.Offset < sjh.Offset+sjh.Size {
+				t.Errorf("ld produced ELF with section %s within %s: 0x%x <= 0x%x..0x%x < 0x%x",
+					sih.Name, sjh.Name, sjh.Offset, sih.Offset, sih.Offset+sih.Size, sjh.Offset+sjh.Size)
+			}
+		}
+	}
+}
diff --git a/src/debug/elf/symbols_test.go b/src/debug/elf/symbols_test.go
new file mode 100644
index 0000000..1b79520
--- /dev/null
+++ b/src/debug/elf/symbols_test.go
@@ -0,0 +1,834 @@
+// 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 elf
+
+import (
+	"io"
+	"path"
+	"reflect"
+	"testing"
+)
+
+// TODO: remove duplicate code
+func TestSymbols(t *testing.T) {
+	do := func(file string, ts []Symbol, getfunc func(*File) ([]Symbol, error)) {
+		var f *File
+		var err error
+		if path.Ext(file) == ".gz" {
+			var r io.ReaderAt
+			if r, err = decompress(file); err == nil {
+				f, err = NewFile(r)
+			}
+		} else {
+			f, err = Open(file)
+		}
+		if err != nil {
+			t.Errorf("TestSymbols: cannot open file %s: %v", file, err)
+			return
+		}
+		defer f.Close()
+		fs, err := getfunc(f)
+		if err != nil && err != ErrNoSymbols {
+			t.Error(err)
+			return
+		} else if err == ErrNoSymbols {
+			fs = []Symbol{}
+		}
+		if !reflect.DeepEqual(ts, fs) {
+			t.Errorf("%s: Symbols = %v, want %v", file, ts, fs)
+		}
+	}
+	for file, ts := range symbolsGolden {
+		do(file, ts, (*File).Symbols)
+	}
+	for file, ts := range dynamicSymbolsGolden {
+		do(file, ts, (*File).DynamicSymbols)
+	}
+}
+
+// golden symbol table data generated by testdata/getgoldsym.c
+
+var symbolsGolden = map[string][]Symbol{
+	"testdata/gcc-amd64-linux-exec": {
+		Symbol{
+			Name:    "",
+			Info:    0x3,
+			Other:   0x0,
+			Section: 0x1,
+			Value:   0x400200,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "",
+			Info:    0x3,
+			Other:   0x0,
+			Section: 0x2,
+			Value:   0x40021C,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "",
+			Info:    0x3,
+			Other:   0x0,
+			Section: 0x3,
+			Value:   0x400240,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "",
+			Info:    0x3,
+			Other:   0x0,
+			Section: 0x4,
+			Value:   0x400268,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "",
+			Info:    0x3,
+			Other:   0x0,
+			Section: 0x5,
+			Value:   0x400288,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "",
+			Info:    0x3,
+			Other:   0x0,
+			Section: 0x6,
+			Value:   0x4002E8,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "",
+			Info:    0x3,
+			Other:   0x0,
+			Section: 0x7,
+			Value:   0x400326,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "",
+			Info:    0x3,
+			Other:   0x0,
+			Section: 0x8,
+			Value:   0x400330,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "",
+			Info:    0x3,
+			Other:   0x0,
+			Section: 0x9,
+			Value:   0x400350,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "",
+			Info:    0x3,
+			Other:   0x0,
+			Section: 0xA,
+			Value:   0x400368,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "",
+			Info:    0x3,
+			Other:   0x0,
+			Section: 0xB,
+			Value:   0x400398,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "",
+			Info:    0x3,
+			Other:   0x0,
+			Section: 0xC,
+			Value:   0x4003B0,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "",
+			Info:    0x3,
+			Other:   0x0,
+			Section: 0xD,
+			Value:   0x4003E0,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "",
+			Info:    0x3,
+			Other:   0x0,
+			Section: 0xE,
+			Value:   0x400594,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "",
+			Info:    0x3,
+			Other:   0x0,
+			Section: 0xF,
+			Value:   0x4005A4,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "",
+			Info:    0x3,
+			Other:   0x0,
+			Section: 0x10,
+			Value:   0x4005B8,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "",
+			Info:    0x3,
+			Other:   0x0,
+			Section: 0x11,
+			Value:   0x4005E0,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "",
+			Info:    0x3,
+			Other:   0x0,
+			Section: 0x12,
+			Value:   0x600688,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "",
+			Info:    0x3,
+			Other:   0x0,
+			Section: 0x13,
+			Value:   0x600698,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "",
+			Info:    0x3,
+			Other:   0x0,
+			Section: 0x14,
+			Value:   0x6006A8,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "",
+			Info:    0x3,
+			Other:   0x0,
+			Section: 0x15,
+			Value:   0x6006B0,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "",
+			Info:    0x3,
+			Other:   0x0,
+			Section: 0x16,
+			Value:   0x600850,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "",
+			Info:    0x3,
+			Other:   0x0,
+			Section: 0x17,
+			Value:   0x600858,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "",
+			Info:    0x3,
+			Other:   0x0,
+			Section: 0x18,
+			Value:   0x600880,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "",
+			Info:    0x3,
+			Other:   0x0,
+			Section: 0x19,
+			Value:   0x600898,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "",
+			Info:    0x3,
+			Other:   0x0,
+			Section: 0x1A,
+			Value:   0x0,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "",
+			Info:    0x3,
+			Other:   0x0,
+			Section: 0x1B,
+			Value:   0x0,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "",
+			Info:    0x3,
+			Other:   0x0,
+			Section: 0x1C,
+			Value:   0x0,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "",
+			Info:    0x3,
+			Other:   0x0,
+			Section: 0x1D,
+			Value:   0x0,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "",
+			Info:    0x3,
+			Other:   0x0,
+			Section: 0x1E,
+			Value:   0x0,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "",
+			Info:    0x3,
+			Other:   0x0,
+			Section: 0x1F,
+			Value:   0x0,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "",
+			Info:    0x3,
+			Other:   0x0,
+			Section: 0x20,
+			Value:   0x0,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "",
+			Info:    0x3,
+			Other:   0x0,
+			Section: 0x21,
+			Value:   0x0,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "init.c",
+			Info:    0x4,
+			Other:   0x0,
+			Section: 0xFFF1,
+			Value:   0x0,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "initfini.c",
+			Info:    0x4,
+			Other:   0x0,
+			Section: 0xFFF1,
+			Value:   0x0,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "call_gmon_start",
+			Info:    0x2,
+			Other:   0x0,
+			Section: 0xD,
+			Value:   0x40040C,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "crtstuff.c",
+			Info:    0x4,
+			Other:   0x0,
+			Section: 0xFFF1,
+			Value:   0x0,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "__CTOR_LIST__",
+			Info:    0x1,
+			Other:   0x0,
+			Section: 0x12,
+			Value:   0x600688,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "__DTOR_LIST__",
+			Info:    0x1,
+			Other:   0x0,
+			Section: 0x13,
+			Value:   0x600698,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "__JCR_LIST__",
+			Info:    0x1,
+			Other:   0x0,
+			Section: 0x14,
+			Value:   0x6006A8,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "__do_global_dtors_aux",
+			Info:    0x2,
+			Other:   0x0,
+			Section: 0xD,
+			Value:   0x400430,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "completed.6183",
+			Info:    0x1,
+			Other:   0x0,
+			Section: 0x19,
+			Value:   0x600898,
+			Size:    0x1,
+		},
+		Symbol{
+			Name:    "p.6181",
+			Info:    0x1,
+			Other:   0x0,
+			Section: 0x18,
+			Value:   0x600890,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "frame_dummy",
+			Info:    0x2,
+			Other:   0x0,
+			Section: 0xD,
+			Value:   0x400470,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "crtstuff.c",
+			Info:    0x4,
+			Other:   0x0,
+			Section: 0xFFF1,
+			Value:   0x0,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "__CTOR_END__",
+			Info:    0x1,
+			Other:   0x0,
+			Section: 0x12,
+			Value:   0x600690,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "__DTOR_END__",
+			Info:    0x1,
+			Other:   0x0,
+			Section: 0x13,
+			Value:   0x6006A0,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "__FRAME_END__",
+			Info:    0x1,
+			Other:   0x0,
+			Section: 0x11,
+			Value:   0x400680,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "__JCR_END__",
+			Info:    0x1,
+			Other:   0x0,
+			Section: 0x14,
+			Value:   0x6006A8,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "__do_global_ctors_aux",
+			Info:    0x2,
+			Other:   0x0,
+			Section: 0xD,
+			Value:   0x400560,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "initfini.c",
+			Info:    0x4,
+			Other:   0x0,
+			Section: 0xFFF1,
+			Value:   0x0,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "hello.c",
+			Info:    0x4,
+			Other:   0x0,
+			Section: 0xFFF1,
+			Value:   0x0,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "_GLOBAL_OFFSET_TABLE_",
+			Info:    0x1,
+			Other:   0x2,
+			Section: 0x17,
+			Value:   0x600858,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "__init_array_end",
+			Info:    0x0,
+			Other:   0x2,
+			Section: 0x12,
+			Value:   0x600684,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "__init_array_start",
+			Info:    0x0,
+			Other:   0x2,
+			Section: 0x12,
+			Value:   0x600684,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "_DYNAMIC",
+			Info:    0x1,
+			Other:   0x2,
+			Section: 0x15,
+			Value:   0x6006B0,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "data_start",
+			Info:    0x20,
+			Other:   0x0,
+			Section: 0x18,
+			Value:   0x600880,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "__libc_csu_fini",
+			Info:    0x12,
+			Other:   0x0,
+			Section: 0xD,
+			Value:   0x4004C0,
+			Size:    0x2,
+		},
+		Symbol{
+			Name:    "_start",
+			Info:    0x12,
+			Other:   0x0,
+			Section: 0xD,
+			Value:   0x4003E0,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "__gmon_start__",
+			Info:    0x20,
+			Other:   0x0,
+			Section: 0x0,
+			Value:   0x0,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "_Jv_RegisterClasses",
+			Info:    0x20,
+			Other:   0x0,
+			Section: 0x0,
+			Value:   0x0,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "puts@@GLIBC_2.2.5",
+			Info:    0x12,
+			Other:   0x0,
+			Section: 0x0,
+			Value:   0x0,
+			Size:    0x18C,
+		},
+		Symbol{
+			Name:    "_fini",
+			Info:    0x12,
+			Other:   0x0,
+			Section: 0xE,
+			Value:   0x400594,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "__libc_start_main@@GLIBC_2.2.5",
+			Info:    0x12,
+			Other:   0x0,
+			Section: 0x0,
+			Value:   0x0,
+			Size:    0x1C2,
+		},
+		Symbol{
+			Name:    "_IO_stdin_used",
+			Info:    0x11,
+			Other:   0x0,
+			Section: 0xF,
+			Value:   0x4005A4,
+			Size:    0x4,
+		},
+		Symbol{
+			Name:    "__data_start",
+			Info:    0x10,
+			Other:   0x0,
+			Section: 0x18,
+			Value:   0x600880,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "__dso_handle",
+			Info:    0x11,
+			Other:   0x2,
+			Section: 0x18,
+			Value:   0x600888,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "__libc_csu_init",
+			Info:    0x12,
+			Other:   0x0,
+			Section: 0xD,
+			Value:   0x4004D0,
+			Size:    0x89,
+		},
+		Symbol{
+			Name:    "__bss_start",
+			Info:    0x10,
+			Other:   0x0,
+			Section: 0xFFF1,
+			Value:   0x600898,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "_end",
+			Info:    0x10,
+			Other:   0x0,
+			Section: 0xFFF1,
+			Value:   0x6008A0,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "_edata",
+			Info:    0x10,
+			Other:   0x0,
+			Section: 0xFFF1,
+			Value:   0x600898,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "main",
+			Info:    0x12,
+			Other:   0x0,
+			Section: 0xD,
+			Value:   0x400498,
+			Size:    0x1B,
+		},
+		Symbol{
+			Name:    "_init",
+			Info:    0x12,
+			Other:   0x0,
+			Section: 0xB,
+			Value:   0x400398,
+			Size:    0x0,
+		},
+	},
+	"testdata/go-relocation-test-clang-x86.obj": {
+		Symbol{
+			Name:    "go-relocation-test-clang.c",
+			Info:    0x4,
+			Other:   0x0,
+			Section: 0xFFF1,
+			Value:   0x0,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    ".Linfo_string0",
+			Info:    0x0,
+			Other:   0x0,
+			Section: 0xC,
+			Value:   0x0,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    ".Linfo_string1",
+			Info:    0x0,
+			Other:   0x0,
+			Section: 0xC,
+			Value:   0x2C,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    ".Linfo_string2",
+			Info:    0x0,
+			Other:   0x0,
+			Section: 0xC,
+			Value:   0x47,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    ".Linfo_string3",
+			Info:    0x0,
+			Other:   0x0,
+			Section: 0xC,
+			Value:   0x4C,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    ".Linfo_string4",
+			Info:    0x0,
+			Other:   0x0,
+			Section: 0xC,
+			Value:   0x4E,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "",
+			Info:    0x3,
+			Other:   0x0,
+			Section: 0x1,
+			Value:   0x0,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "",
+			Info:    0x3,
+			Other:   0x0,
+			Section: 0x2,
+			Value:   0x0,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "",
+			Info:    0x3,
+			Other:   0x0,
+			Section: 0x3,
+			Value:   0x0,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "",
+			Info:    0x3,
+			Other:   0x0,
+			Section: 0x4,
+			Value:   0x0,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "",
+			Info:    0x3,
+			Other:   0x0,
+			Section: 0x6,
+			Value:   0x0,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "",
+			Info:    0x3,
+			Other:   0x0,
+			Section: 0x7,
+			Value:   0x0,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "",
+			Info:    0x3,
+			Other:   0x0,
+			Section: 0x8,
+			Value:   0x0,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "",
+			Info:    0x3,
+			Other:   0x0,
+			Section: 0xA,
+			Value:   0x0,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "",
+			Info:    0x3,
+			Other:   0x0,
+			Section: 0xC,
+			Value:   0x0,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "",
+			Info:    0x3,
+			Other:   0x0,
+			Section: 0xD,
+			Value:   0x0,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "",
+			Info:    0x3,
+			Other:   0x0,
+			Section: 0xE,
+			Value:   0x0,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "",
+			Info:    0x3,
+			Other:   0x0,
+			Section: 0xF,
+			Value:   0x0,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "",
+			Info:    0x3,
+			Other:   0x0,
+			Section: 0x10,
+			Value:   0x0,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "v",
+			Info:    0x11,
+			Other:   0x0,
+			Section: 0xFFF2,
+			Value:   0x4,
+			Size:    0x4,
+		},
+	},
+	"testdata/hello-world-core.gz": {},
+}
+
+var dynamicSymbolsGolden = map[string][]Symbol{
+	"testdata/gcc-amd64-linux-exec": {
+		Symbol{
+			Name:    "__gmon_start__",
+			Info:    0x20,
+			Other:   0x0,
+			Section: 0x0,
+			Value:   0x0,
+			Size:    0x0,
+		},
+		Symbol{
+			Name:    "puts",
+			Info:    0x12,
+			Other:   0x0,
+			Section: 0x0,
+			Value:   0x0,
+			Size:    0x18C,
+		},
+		Symbol{
+			Name:    "__libc_start_main",
+			Info:    0x12,
+			Other:   0x0,
+			Section: 0x0,
+			Value:   0x0,
+			Size:    0x1C2,
+		},
+	},
+	"testdata/go-relocation-test-clang-x86.obj": {},
+	"testdata/hello-world-core.gz":              {},
+}
diff --git a/src/pkg/debug/elf/testdata/gcc-386-freebsd-exec b/src/debug/elf/testdata/gcc-386-freebsd-exec
similarity index 100%
rename from src/pkg/debug/elf/testdata/gcc-386-freebsd-exec
rename to src/debug/elf/testdata/gcc-386-freebsd-exec
diff --git a/src/pkg/debug/elf/testdata/gcc-amd64-linux-exec b/src/debug/elf/testdata/gcc-amd64-linux-exec
similarity index 100%
rename from src/pkg/debug/elf/testdata/gcc-amd64-linux-exec
rename to src/debug/elf/testdata/gcc-amd64-linux-exec
diff --git a/src/pkg/debug/elf/testdata/gcc-amd64-openbsd-debug-with-rela.obj b/src/debug/elf/testdata/gcc-amd64-openbsd-debug-with-rela.obj
similarity index 100%
rename from src/pkg/debug/elf/testdata/gcc-amd64-openbsd-debug-with-rela.obj
rename to src/debug/elf/testdata/gcc-amd64-openbsd-debug-with-rela.obj
diff --git a/src/pkg/debug/elf/testdata/go-relocation-test-clang-x86.obj b/src/debug/elf/testdata/go-relocation-test-clang-x86.obj
similarity index 100%
rename from src/pkg/debug/elf/testdata/go-relocation-test-clang-x86.obj
rename to src/debug/elf/testdata/go-relocation-test-clang-x86.obj
diff --git a/src/pkg/debug/elf/testdata/go-relocation-test-gcc424-x86-64.obj b/src/debug/elf/testdata/go-relocation-test-gcc424-x86-64.obj
similarity index 100%
rename from src/pkg/debug/elf/testdata/go-relocation-test-gcc424-x86-64.obj
rename to src/debug/elf/testdata/go-relocation-test-gcc424-x86-64.obj
diff --git a/src/pkg/debug/elf/testdata/go-relocation-test-gcc441-x86-64.obj b/src/debug/elf/testdata/go-relocation-test-gcc441-x86-64.obj
similarity index 100%
rename from src/pkg/debug/elf/testdata/go-relocation-test-gcc441-x86-64.obj
rename to src/debug/elf/testdata/go-relocation-test-gcc441-x86-64.obj
diff --git a/src/pkg/debug/elf/testdata/go-relocation-test-gcc441-x86.obj b/src/debug/elf/testdata/go-relocation-test-gcc441-x86.obj
similarity index 100%
rename from src/pkg/debug/elf/testdata/go-relocation-test-gcc441-x86.obj
rename to src/debug/elf/testdata/go-relocation-test-gcc441-x86.obj
diff --git a/src/debug/elf/testdata/go-relocation-test-gcc482-aarch64.obj b/src/debug/elf/testdata/go-relocation-test-gcc482-aarch64.obj
new file mode 100644
index 0000000..849e264
Binary files /dev/null and b/src/debug/elf/testdata/go-relocation-test-gcc482-aarch64.obj differ
diff --git a/src/pkg/debug/elf/testdata/hello-world-core.gz b/src/debug/elf/testdata/hello-world-core.gz
similarity index 100%
rename from src/pkg/debug/elf/testdata/hello-world-core.gz
rename to src/debug/elf/testdata/hello-world-core.gz
diff --git a/src/pkg/debug/elf/testdata/hello.c b/src/debug/elf/testdata/hello.c
similarity index 100%
rename from src/pkg/debug/elf/testdata/hello.c
rename to src/debug/elf/testdata/hello.c
diff --git a/src/pkg/debug/gosym/pclinetest.asm b/src/debug/gosym/pclinetest.asm
similarity index 100%
rename from src/pkg/debug/gosym/pclinetest.asm
rename to src/debug/gosym/pclinetest.asm
diff --git a/src/pkg/debug/gosym/pclinetest.h b/src/debug/gosym/pclinetest.h
similarity index 100%
rename from src/pkg/debug/gosym/pclinetest.h
rename to src/debug/gosym/pclinetest.h
diff --git a/src/pkg/debug/gosym/pclntab.go b/src/debug/gosym/pclntab.go
similarity index 100%
rename from src/pkg/debug/gosym/pclntab.go
rename to src/debug/gosym/pclntab.go
diff --git a/src/pkg/debug/gosym/pclntab_test.go b/src/debug/gosym/pclntab_test.go
similarity index 100%
rename from src/pkg/debug/gosym/pclntab_test.go
rename to src/debug/gosym/pclntab_test.go
diff --git a/src/debug/gosym/symtab.go b/src/debug/gosym/symtab.go
new file mode 100644
index 0000000..ee18499
--- /dev/null
+++ b/src/debug/gosym/symtab.go
@@ -0,0 +1,710 @@
+// Copyright 2009 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package gosym implements access to the Go symbol
+// and line number tables embedded in Go binaries generated
+// by the gc compilers.
+package gosym
+
+// The table format is a variant of the format used in Plan 9's a.out
+// format, documented at http://plan9.bell-labs.com/magic/man2html/6/a.out.
+// The best reference for the differences between the Plan 9 format
+// and the Go format is the runtime source, specifically ../../runtime/symtab.c.
+
+import (
+	"bytes"
+	"encoding/binary"
+	"fmt"
+	"strconv"
+	"strings"
+)
+
+/*
+ * Symbols
+ */
+
+// A Sym represents a single symbol table entry.
+type Sym struct {
+	Value  uint64
+	Type   byte
+	Name   string
+	GoType uint64
+	// If this symbol if a function symbol, the corresponding Func
+	Func *Func
+}
+
+// Static reports whether this symbol is static (not visible outside its file).
+func (s *Sym) Static() bool { return s.Type >= 'a' }
+
+// PackageName returns the package part of the symbol name,
+// or the empty string if there is none.
+func (s *Sym) PackageName() string {
+	if i := strings.Index(s.Name, "."); i != -1 {
+		return s.Name[0:i]
+	}
+	return ""
+}
+
+// ReceiverName returns the receiver type name of this symbol,
+// or the empty string if there is none.
+func (s *Sym) ReceiverName() string {
+	l := strings.Index(s.Name, ".")
+	r := strings.LastIndex(s.Name, ".")
+	if l == -1 || r == -1 || l == r {
+		return ""
+	}
+	return s.Name[l+1 : r]
+}
+
+// BaseName returns the symbol name without the package or receiver name.
+func (s *Sym) BaseName() string {
+	if i := strings.LastIndex(s.Name, "."); i != -1 {
+		return s.Name[i+1:]
+	}
+	return s.Name
+}
+
+// A Func collects information about a single function.
+type Func struct {
+	Entry uint64
+	*Sym
+	End       uint64
+	Params    []*Sym
+	Locals    []*Sym
+	FrameSize int
+	LineTable *LineTable
+	Obj       *Obj
+}
+
+// An Obj represents a collection of functions in a symbol table.
+//
+// The exact method of division of a binary into separate Objs is an internal detail
+// of the symbol table format.
+//
+// In early versions of Go each source file became a different Obj.
+//
+// In Go 1 and Go 1.1, each package produced one Obj for all Go sources
+// and one Obj per C source file.
+//
+// In Go 1.2, there is a single Obj for the entire program.
+type Obj struct {
+	// Funcs is a list of functions in the Obj.
+	Funcs []Func
+
+	// In Go 1.1 and earlier, Paths is a list of symbols corresponding
+	// to the source file names that produced the Obj.
+	// In Go 1.2, Paths is nil.
+	// Use the keys of Table.Files to obtain a list of source files.
+	Paths []Sym // meta
+}
+
+/*
+ * Symbol tables
+ */
+
+// Table represents a Go symbol table.  It stores all of the
+// symbols decoded from the program and provides methods to translate
+// between symbols, names, and addresses.
+type Table struct {
+	Syms  []Sym
+	Funcs []Func
+	Files map[string]*Obj // nil for Go 1.2 and later binaries
+	Objs  []Obj           // nil for Go 1.2 and later binaries
+
+	go12line *LineTable // Go 1.2 line number table
+}
+
+type sym struct {
+	value  uint64
+	gotype uint64
+	typ    byte
+	name   []byte
+}
+
+var (
+	littleEndianSymtab    = []byte{0xFD, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00}
+	bigEndianSymtab       = []byte{0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00}
+	oldLittleEndianSymtab = []byte{0xFE, 0xFF, 0xFF, 0xFF, 0x00, 0x00}
+)
+
+func walksymtab(data []byte, fn func(sym) error) error {
+	if len(data) == 0 { // missing symtab is okay
+		return nil
+	}
+	var order binary.ByteOrder = binary.BigEndian
+	newTable := false
+	switch {
+	case bytes.HasPrefix(data, oldLittleEndianSymtab):
+		// Same as Go 1.0, but little endian.
+		// Format was used during interim development between Go 1.0 and Go 1.1.
+		// Should not be widespread, but easy to support.
+		data = data[6:]
+		order = binary.LittleEndian
+	case bytes.HasPrefix(data, bigEndianSymtab):
+		newTable = true
+	case bytes.HasPrefix(data, littleEndianSymtab):
+		newTable = true
+		order = binary.LittleEndian
+	}
+	var ptrsz int
+	if newTable {
+		if len(data) < 8 {
+			return &DecodingError{len(data), "unexpected EOF", nil}
+		}
+		ptrsz = int(data[7])
+		if ptrsz != 4 && ptrsz != 8 {
+			return &DecodingError{7, "invalid pointer size", ptrsz}
+		}
+		data = data[8:]
+	}
+	var s sym
+	p := data
+	for len(p) >= 4 {
+		var typ byte
+		if newTable {
+			// Symbol type, value, Go type.
+			typ = p[0] & 0x3F
+			wideValue := p[0]&0x40 != 0
+			goType := p[0]&0x80 != 0
+			if typ < 26 {
+				typ += 'A'
+			} else {
+				typ += 'a' - 26
+			}
+			s.typ = typ
+			p = p[1:]
+			if wideValue {
+				if len(p) < ptrsz {
+					return &DecodingError{len(data), "unexpected EOF", nil}
+				}
+				// fixed-width value
+				if ptrsz == 8 {
+					s.value = order.Uint64(p[0:8])
+					p = p[8:]
+				} else {
+					s.value = uint64(order.Uint32(p[0:4]))
+					p = p[4:]
+				}
+			} else {
+				// varint value
+				s.value = 0
+				shift := uint(0)
+				for len(p) > 0 && p[0]&0x80 != 0 {
+					s.value |= uint64(p[0]&0x7F) << shift
+					shift += 7
+					p = p[1:]
+				}
+				if len(p) == 0 {
+					return &DecodingError{len(data), "unexpected EOF", nil}
+				}
+				s.value |= uint64(p[0]) << shift
+				p = p[1:]
+			}
+			if goType {
+				if len(p) < ptrsz {
+					return &DecodingError{len(data), "unexpected EOF", nil}
+				}
+				// fixed-width go type
+				if ptrsz == 8 {
+					s.gotype = order.Uint64(p[0:8])
+					p = p[8:]
+				} else {
+					s.gotype = uint64(order.Uint32(p[0:4]))
+					p = p[4:]
+				}
+			}
+		} else {
+			// Value, symbol type.
+			s.value = uint64(order.Uint32(p[0:4]))
+			if len(p) < 5 {
+				return &DecodingError{len(data), "unexpected EOF", nil}
+			}
+			typ = p[4]
+			if typ&0x80 == 0 {
+				return &DecodingError{len(data) - len(p) + 4, "bad symbol type", typ}
+			}
+			typ &^= 0x80
+			s.typ = typ
+			p = p[5:]
+		}
+
+		// Name.
+		var i int
+		var nnul int
+		for i = 0; i < len(p); i++ {
+			if p[i] == 0 {
+				nnul = 1
+				break
+			}
+		}
+		switch typ {
+		case 'z', 'Z':
+			p = p[i+nnul:]
+			for i = 0; i+2 <= len(p); i += 2 {
+				if p[i] == 0 && p[i+1] == 0 {
+					nnul = 2
+					break
+				}
+			}
+		}
+		if len(p) < i+nnul {
+			return &DecodingError{len(data), "unexpected EOF", nil}
+		}
+		s.name = p[0:i]
+		i += nnul
+		p = p[i:]
+
+		if !newTable {
+			if len(p) < 4 {
+				return &DecodingError{len(data), "unexpected EOF", nil}
+			}
+			// Go type.
+			s.gotype = uint64(order.Uint32(p[:4]))
+			p = p[4:]
+		}
+		fn(s)
+	}
+	return nil
+}
+
+// NewTable decodes the Go symbol table in data,
+// returning an in-memory representation.
+func NewTable(symtab []byte, pcln *LineTable) (*Table, error) {
+	var n int
+	err := walksymtab(symtab, func(s sym) error {
+		n++
+		return nil
+	})
+	if err != nil {
+		return nil, err
+	}
+
+	var t Table
+	if pcln.isGo12() {
+		t.go12line = pcln
+	}
+	fname := make(map[uint16]string)
+	t.Syms = make([]Sym, 0, n)
+	nf := 0
+	nz := 0
+	lasttyp := uint8(0)
+	err = walksymtab(symtab, func(s sym) error {
+		n := len(t.Syms)
+		t.Syms = t.Syms[0 : n+1]
+		ts := &t.Syms[n]
+		ts.Type = s.typ
+		ts.Value = uint64(s.value)
+		ts.GoType = uint64(s.gotype)
+		switch s.typ {
+		default:
+			// rewrite name to use . instead of · (c2 b7)
+			w := 0
+			b := s.name
+			for i := 0; i < len(b); i++ {
+				if b[i] == 0xc2 && i+1 < len(b) && b[i+1] == 0xb7 {
+					i++
+					b[i] = '.'
+				}
+				b[w] = b[i]
+				w++
+			}
+			ts.Name = string(s.name[0:w])
+		case 'z', 'Z':
+			if lasttyp != 'z' && lasttyp != 'Z' {
+				nz++
+			}
+			for i := 0; i < len(s.name); i += 2 {
+				eltIdx := binary.BigEndian.Uint16(s.name[i : i+2])
+				elt, ok := fname[eltIdx]
+				if !ok {
+					return &DecodingError{-1, "bad filename code", eltIdx}
+				}
+				if n := len(ts.Name); n > 0 && ts.Name[n-1] != '/' {
+					ts.Name += "/"
+				}
+				ts.Name += elt
+			}
+		}
+		switch s.typ {
+		case 'T', 't', 'L', 'l':
+			nf++
+		case 'f':
+			fname[uint16(s.value)] = ts.Name
+		}
+		lasttyp = s.typ
+		return nil
+	})
+	if err != nil {
+		return nil, err
+	}
+
+	t.Funcs = make([]Func, 0, nf)
+	t.Files = make(map[string]*Obj)
+
+	var obj *Obj
+	if t.go12line != nil {
+		// Put all functions into one Obj.
+		t.Objs = make([]Obj, 1)
+		obj = &t.Objs[0]
+		t.go12line.go12MapFiles(t.Files, obj)
+	} else {
+		t.Objs = make([]Obj, 0, nz)
+	}
+
+	// Count text symbols and attach frame sizes, parameters, and
+	// locals to them.  Also, find object file boundaries.
+	lastf := 0
+	for i := 0; i < len(t.Syms); i++ {
+		sym := &t.Syms[i]
+		switch sym.Type {
+		case 'Z', 'z': // path symbol
+			if t.go12line != nil {
+				// Go 1.2 binaries have the file information elsewhere. Ignore.
+				break
+			}
+			// Finish the current object
+			if obj != nil {
+				obj.Funcs = t.Funcs[lastf:]
+			}
+			lastf = len(t.Funcs)
+
+			// Start new object
+			n := len(t.Objs)
+			t.Objs = t.Objs[0 : n+1]
+			obj = &t.Objs[n]
+
+			// Count & copy path symbols
+			var end int
+			for end = i + 1; end < len(t.Syms); end++ {
+				if c := t.Syms[end].Type; c != 'Z' && c != 'z' {
+					break
+				}
+			}
+			obj.Paths = t.Syms[i:end]
+			i = end - 1 // loop will i++
+
+			// Record file names
+			depth := 0
+			for j := range obj.Paths {
+				s := &obj.Paths[j]
+				if s.Name == "" {
+					depth--
+				} else {
+					if depth == 0 {
+						t.Files[s.Name] = obj
+					}
+					depth++
+				}
+			}
+
+		case 'T', 't', 'L', 'l': // text symbol
+			if n := len(t.Funcs); n > 0 {
+				t.Funcs[n-1].End = sym.Value
+			}
+			if sym.Name == "runtime.etext" || sym.Name == "etext" {
+				continue
+			}
+
+			// Count parameter and local (auto) syms
+			var np, na int
+			var end int
+		countloop:
+			for end = i + 1; end < len(t.Syms); end++ {
+				switch t.Syms[end].Type {
+				case 'T', 't', 'L', 'l', 'Z', 'z':
+					break countloop
+				case 'p':
+					np++
+				case 'a':
+					na++
+				}
+			}
+
+			// Fill in the function symbol
+			n := len(t.Funcs)
+			t.Funcs = t.Funcs[0 : n+1]
+			fn := &t.Funcs[n]
+			sym.Func = fn
+			fn.Params = make([]*Sym, 0, np)
+			fn.Locals = make([]*Sym, 0, na)
+			fn.Sym = sym
+			fn.Entry = sym.Value
+			fn.Obj = obj
+			if t.go12line != nil {
+				// All functions share the same line table.
+				// It knows how to narrow down to a specific
+				// function quickly.
+				fn.LineTable = t.go12line
+			} else if pcln != nil {
+				fn.LineTable = pcln.slice(fn.Entry)
+				pcln = fn.LineTable
+			}
+			for j := i; j < end; j++ {
+				s := &t.Syms[j]
+				switch s.Type {
+				case 'm':
+					fn.FrameSize = int(s.Value)
+				case 'p':
+					n := len(fn.Params)
+					fn.Params = fn.Params[0 : n+1]
+					fn.Params[n] = s
+				case 'a':
+					n := len(fn.Locals)
+					fn.Locals = fn.Locals[0 : n+1]
+					fn.Locals[n] = s
+				}
+			}
+			i = end - 1 // loop will i++
+		}
+	}
+
+	if t.go12line != nil && nf == 0 {
+		t.Funcs = t.go12line.go12Funcs()
+	}
+	if obj != nil {
+		obj.Funcs = t.Funcs[lastf:]
+	}
+	return &t, nil
+}
+
+// PCToFunc returns the function containing the program counter pc,
+// or nil if there is no such function.
+func (t *Table) PCToFunc(pc uint64) *Func {
+	funcs := t.Funcs
+	for len(funcs) > 0 {
+		m := len(funcs) / 2
+		fn := &funcs[m]
+		switch {
+		case pc < fn.Entry:
+			funcs = funcs[0:m]
+		case fn.Entry <= pc && pc < fn.End:
+			return fn
+		default:
+			funcs = funcs[m+1:]
+		}
+	}
+	return nil
+}
+
+// PCToLine looks up line number information for a program counter.
+// If there is no information, it returns fn == nil.
+func (t *Table) PCToLine(pc uint64) (file string, line int, fn *Func) {
+	if fn = t.PCToFunc(pc); fn == nil {
+		return
+	}
+	if t.go12line != nil {
+		file = t.go12line.go12PCToFile(pc)
+		line = t.go12line.go12PCToLine(pc)
+	} else {
+		file, line = fn.Obj.lineFromAline(fn.LineTable.PCToLine(pc))
+	}
+	return
+}
+
+// LineToPC looks up the first program counter on the given line in
+// the named file.  It returns UnknownPathError or UnknownLineError if
+// there is an error looking up this line.
+func (t *Table) LineToPC(file string, line int) (pc uint64, fn *Func, err error) {
+	obj, ok := t.Files[file]
+	if !ok {
+		return 0, nil, UnknownFileError(file)
+	}
+
+	if t.go12line != nil {
+		pc := t.go12line.go12LineToPC(file, line)
+		if pc == 0 {
+			return 0, nil, &UnknownLineError{file, line}
+		}
+		return pc, t.PCToFunc(pc), nil
+	}
+
+	abs, err := obj.alineFromLine(file, line)
+	if err != nil {
+		return
+	}
+	for i := range obj.Funcs {
+		f := &obj.Funcs[i]
+		pc := f.LineTable.LineToPC(abs, f.End)
+		if pc != 0 {
+			return pc, f, nil
+		}
+	}
+	return 0, nil, &UnknownLineError{file, line}
+}
+
+// LookupSym returns the text, data, or bss symbol with the given name,
+// or nil if no such symbol is found.
+func (t *Table) LookupSym(name string) *Sym {
+	// TODO(austin) Maybe make a map
+	for i := range t.Syms {
+		s := &t.Syms[i]
+		switch s.Type {
+		case 'T', 't', 'L', 'l', 'D', 'd', 'B', 'b':
+			if s.Name == name {
+				return s
+			}
+		}
+	}
+	return nil
+}
+
+// LookupFunc returns the text, data, or bss symbol with the given name,
+// or nil if no such symbol is found.
+func (t *Table) LookupFunc(name string) *Func {
+	for i := range t.Funcs {
+		f := &t.Funcs[i]
+		if f.Sym.Name == name {
+			return f
+		}
+	}
+	return nil
+}
+
+// SymByAddr returns the text, data, or bss symbol starting at the given address.
+func (t *Table) SymByAddr(addr uint64) *Sym {
+	for i := range t.Syms {
+		s := &t.Syms[i]
+		switch s.Type {
+		case 'T', 't', 'L', 'l', 'D', 'd', 'B', 'b':
+			if s.Value == addr {
+				return s
+			}
+		}
+	}
+	return nil
+}
+
+/*
+ * Object files
+ */
+
+// This is legacy code for Go 1.1 and earlier, which used the
+// Plan 9 format for pc-line tables. This code was never quite
+// correct. It's probably very close, and it's usually correct, but
+// we never quite found all the corner cases.
+//
+// Go 1.2 and later use a simpler format, documented at golang.org/s/go12symtab.
+
+func (o *Obj) lineFromAline(aline int) (string, int) {
+	type stackEnt struct {
+		path   string
+		start  int
+		offset int
+		prev   *stackEnt
+	}
+
+	noPath := &stackEnt{"", 0, 0, nil}
+	tos := noPath
+
+pathloop:
+	for _, s := range o.Paths {
+		val := int(s.Value)
+		switch {
+		case val > aline:
+			break pathloop
+
+		case val == 1:
+			// Start a new stack
+			tos = &stackEnt{s.Name, val, 0, noPath}
+
+		case s.Name == "":
+			// Pop
+			if tos == noPath {
+				return "<malformed symbol table>", 0
+			}
+			tos.prev.offset += val - tos.start
+			tos = tos.prev
+
+		default:
+			// Push
+			tos = &stackEnt{s.Name, val, 0, tos}
+		}
+	}
+
+	if tos == noPath {
+		return "", 0
+	}
+	return tos.path, aline - tos.start - tos.offset + 1
+}
+
+func (o *Obj) alineFromLine(path string, line int) (int, error) {
+	if line < 1 {
+		return 0, &UnknownLineError{path, line}
+	}
+
+	for i, s := range o.Paths {
+		// Find this path
+		if s.Name != path {
+			continue
+		}
+
+		// Find this line at this stack level
+		depth := 0
+		var incstart int
+		line += int(s.Value)
+	pathloop:
+		for _, s := range o.Paths[i:] {
+			val := int(s.Value)
+			switch {
+			case depth == 1 && val >= line:
+				return line - 1, nil
+
+			case s.Name == "":
+				depth--
+				if depth == 0 {
+					break pathloop
+				} else if depth == 1 {
+					line += val - incstart
+				}
+
+			default:
+				if depth == 1 {
+					incstart = val
+				}
+				depth++
+			}
+		}
+		return 0, &UnknownLineError{path, line}
+	}
+	return 0, UnknownFileError(path)
+}
+
+/*
+ * Errors
+ */
+
+// UnknownFileError represents a failure to find the specific file in
+// the symbol table.
+type UnknownFileError string
+
+func (e UnknownFileError) Error() string { return "unknown file: " + string(e) }
+
+// UnknownLineError represents a failure to map a line to a program
+// counter, either because the line is beyond the bounds of the file
+// or because there is no code on the given line.
+type UnknownLineError struct {
+	File string
+	Line int
+}
+
+func (e *UnknownLineError) Error() string {
+	return "no code at " + e.File + ":" + strconv.Itoa(e.Line)
+}
+
+// DecodingError represents an error during the decoding of
+// the symbol table.
+type DecodingError struct {
+	off int
+	msg string
+	val interface{}
+}
+
+func (e *DecodingError) Error() string {
+	msg := e.msg
+	if e.val != nil {
+		msg += fmt.Sprintf(" '%v'", e.val)
+	}
+	msg += fmt.Sprintf(" at byte %#x", e.off)
+	return msg
+}
diff --git a/src/pkg/debug/macho/fat.go b/src/debug/macho/fat.go
similarity index 100%
rename from src/pkg/debug/macho/fat.go
rename to src/debug/macho/fat.go
diff --git a/src/pkg/debug/macho/file.go b/src/debug/macho/file.go
similarity index 100%
rename from src/pkg/debug/macho/file.go
rename to src/debug/macho/file.go
diff --git a/src/pkg/debug/macho/file_test.go b/src/debug/macho/file_test.go
similarity index 100%
rename from src/pkg/debug/macho/file_test.go
rename to src/debug/macho/file_test.go
diff --git a/src/pkg/debug/macho/macho.go b/src/debug/macho/macho.go
similarity index 100%
rename from src/pkg/debug/macho/macho.go
rename to src/debug/macho/macho.go
diff --git a/src/pkg/debug/macho/testdata/fat-gcc-386-amd64-darwin-exec b/src/debug/macho/testdata/fat-gcc-386-amd64-darwin-exec
similarity index 100%
rename from src/pkg/debug/macho/testdata/fat-gcc-386-amd64-darwin-exec
rename to src/debug/macho/testdata/fat-gcc-386-amd64-darwin-exec
diff --git a/src/pkg/debug/macho/testdata/gcc-386-darwin-exec b/src/debug/macho/testdata/gcc-386-darwin-exec
similarity index 100%
rename from src/pkg/debug/macho/testdata/gcc-386-darwin-exec
rename to src/debug/macho/testdata/gcc-386-darwin-exec
diff --git a/src/pkg/debug/macho/testdata/gcc-amd64-darwin-exec b/src/debug/macho/testdata/gcc-amd64-darwin-exec
similarity index 100%
rename from src/pkg/debug/macho/testdata/gcc-amd64-darwin-exec
rename to src/debug/macho/testdata/gcc-amd64-darwin-exec
diff --git a/src/pkg/debug/macho/testdata/gcc-amd64-darwin-exec-debug b/src/debug/macho/testdata/gcc-amd64-darwin-exec-debug
similarity index 100%
rename from src/pkg/debug/macho/testdata/gcc-amd64-darwin-exec-debug
rename to src/debug/macho/testdata/gcc-amd64-darwin-exec-debug
diff --git a/src/pkg/debug/macho/testdata/hello.c b/src/debug/macho/testdata/hello.c
similarity index 100%
rename from src/pkg/debug/macho/testdata/hello.c
rename to src/debug/macho/testdata/hello.c
diff --git a/src/debug/pe/file.go b/src/debug/pe/file.go
new file mode 100644
index 0000000..759e567
--- /dev/null
+++ b/src/debug/pe/file.go
@@ -0,0 +1,394 @@
+// Copyright 2009 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package pe implements access to PE (Microsoft Windows Portable Executable) files.
+package pe
+
+import (
+	"debug/dwarf"
+	"encoding/binary"
+	"errors"
+	"fmt"
+	"io"
+	"os"
+	"strconv"
+)
+
+// A File represents an open PE file.
+type File struct {
+	FileHeader
+	OptionalHeader interface{} // of type *OptionalHeader32 or *OptionalHeader64
+	Sections       []*Section
+	Symbols        []*Symbol
+
+	closer io.Closer
+}
+
+type SectionHeader struct {
+	Name                 string
+	VirtualSize          uint32
+	VirtualAddress       uint32
+	Size                 uint32
+	Offset               uint32
+	PointerToRelocations uint32
+	PointerToLineNumbers uint32
+	NumberOfRelocations  uint16
+	NumberOfLineNumbers  uint16
+	Characteristics      uint32
+}
+
+type Section struct {
+	SectionHeader
+
+	// Embed ReaderAt for ReadAt method.
+	// Do not embed SectionReader directly
+	// to avoid having Read and Seek.
+	// If a client wants Read and Seek it must use
+	// Open() to avoid fighting over the seek offset
+	// with other clients.
+	io.ReaderAt
+	sr *io.SectionReader
+}
+
+type Symbol struct {
+	Name          string
+	Value         uint32
+	SectionNumber int16
+	Type          uint16
+	StorageClass  uint8
+}
+
+type ImportDirectory struct {
+	OriginalFirstThunk uint32
+	TimeDateStamp      uint32
+	ForwarderChain     uint32
+	Name               uint32
+	FirstThunk         uint32
+
+	dll string
+}
+
+// Data reads and returns the contents of the PE section.
+func (s *Section) Data() ([]byte, error) {
+	dat := make([]byte, s.sr.Size())
+	n, err := s.sr.ReadAt(dat, 0)
+	if n == len(dat) {
+		err = nil
+	}
+	return dat[0:n], err
+}
+
+// Open returns a new ReadSeeker reading the PE section.
+func (s *Section) Open() io.ReadSeeker { return io.NewSectionReader(s.sr, 0, 1<<63-1) }
+
+type FormatError struct {
+	off int64
+	msg string
+	val interface{}
+}
+
+func (e *FormatError) Error() string {
+	msg := e.msg
+	if e.val != nil {
+		msg += fmt.Sprintf(" '%v'", e.val)
+	}
+	msg += fmt.Sprintf(" in record at byte %#x", e.off)
+	return msg
+}
+
+// Open opens the named file using os.Open and prepares it for use as a PE binary.
+func Open(name string) (*File, error) {
+	f, err := os.Open(name)
+	if err != nil {
+		return nil, err
+	}
+	ff, err := NewFile(f)
+	if err != nil {
+		f.Close()
+		return nil, err
+	}
+	ff.closer = f
+	return ff, nil
+}
+
+// Close closes the File.
+// If the File was created using NewFile directly instead of Open,
+// Close has no effect.
+func (f *File) Close() error {
+	var err error
+	if f.closer != nil {
+		err = f.closer.Close()
+		f.closer = nil
+	}
+	return err
+}
+
+var (
+	sizeofOptionalHeader32 = uint16(binary.Size(OptionalHeader32{}))
+	sizeofOptionalHeader64 = uint16(binary.Size(OptionalHeader64{}))
+)
+
+// NewFile creates a new File for accessing a PE binary in an underlying reader.
+func NewFile(r io.ReaderAt) (*File, error) {
+	f := new(File)
+	sr := io.NewSectionReader(r, 0, 1<<63-1)
+
+	var dosheader [96]byte
+	if _, err := r.ReadAt(dosheader[0:], 0); err != nil {
+		return nil, err
+	}
+	var base int64
+	if dosheader[0] == 'M' && dosheader[1] == 'Z' {
+		signoff := int64(binary.LittleEndian.Uint32(dosheader[0x3c:]))
+		var sign [4]byte
+		r.ReadAt(sign[:], signoff)
+		if !(sign[0] == 'P' && sign[1] == 'E' && sign[2] == 0 && sign[3] == 0) {
+			return nil, errors.New("Invalid PE File Format.")
+		}
+		base = signoff + 4
+	} else {
+		base = int64(0)
+	}
+	sr.Seek(base, os.SEEK_SET)
+	if err := binary.Read(sr, binary.LittleEndian, &f.FileHeader); err != nil {
+		return nil, err
+	}
+	if f.FileHeader.Machine != IMAGE_FILE_MACHINE_UNKNOWN && f.FileHeader.Machine != IMAGE_FILE_MACHINE_AMD64 && f.FileHeader.Machine != IMAGE_FILE_MACHINE_I386 {
+		return nil, errors.New("Invalid PE File Format.")
+	}
+
+	var ss []byte
+	if f.FileHeader.NumberOfSymbols > 0 {
+		// Get COFF string table, which is located at the end of the COFF symbol table.
+		sr.Seek(int64(f.FileHeader.PointerToSymbolTable+COFFSymbolSize*f.FileHeader.NumberOfSymbols), os.SEEK_SET)
+		var l uint32
+		if err := binary.Read(sr, binary.LittleEndian, &l); err != nil {
+			return nil, err
+		}
+		ss = make([]byte, l)
+		if _, err := r.ReadAt(ss, int64(f.FileHeader.PointerToSymbolTable+COFFSymbolSize*f.FileHeader.NumberOfSymbols)); err != nil {
+			return nil, err
+		}
+
+		// Process COFF symbol table.
+		sr.Seek(int64(f.FileHeader.PointerToSymbolTable), os.SEEK_SET)
+		aux := uint8(0)
+		for i := 0; i < int(f.FileHeader.NumberOfSymbols); i++ {
+			cs := new(COFFSymbol)
+			if err := binary.Read(sr, binary.LittleEndian, cs); err != nil {
+				return nil, err
+			}
+			if aux > 0 {
+				aux--
+				continue
+			}
+			var name string
+			if cs.Name[0] == 0 && cs.Name[1] == 0 && cs.Name[2] == 0 && cs.Name[3] == 0 {
+				si := int(binary.LittleEndian.Uint32(cs.Name[4:]))
+				name, _ = getString(ss, si)
+			} else {
+				name = cstring(cs.Name[:])
+			}
+			aux = cs.NumberOfAuxSymbols
+			s := &Symbol{
+				Name:          name,
+				Value:         cs.Value,
+				SectionNumber: cs.SectionNumber,
+				Type:          cs.Type,
+				StorageClass:  cs.StorageClass,
+			}
+			f.Symbols = append(f.Symbols, s)
+		}
+	}
+
+	// Read optional header.
+	sr.Seek(base, os.SEEK_SET)
+	if err := binary.Read(sr, binary.LittleEndian, &f.FileHeader); err != nil {
+		return nil, err
+	}
+	var oh32 OptionalHeader32
+	var oh64 OptionalHeader64
+	switch f.FileHeader.SizeOfOptionalHeader {
+	case sizeofOptionalHeader32:
+		if err := binary.Read(sr, binary.LittleEndian, &oh32); err != nil {
+			return nil, err
+		}
+		if oh32.Magic != 0x10b { // PE32
+			return nil, fmt.Errorf("pe32 optional header has unexpected Magic of 0x%x", oh32.Magic)
+		}
+		f.OptionalHeader = &oh32
+	case sizeofOptionalHeader64:
+		if err := binary.Read(sr, binary.LittleEndian, &oh64); err != nil {
+			return nil, err
+		}
+		if oh64.Magic != 0x20b { // PE32+
+			return nil, fmt.Errorf("pe32+ optional header has unexpected Magic of 0x%x", oh64.Magic)
+		}
+		f.OptionalHeader = &oh64
+	}
+
+	// Process sections.
+	f.Sections = make([]*Section, f.FileHeader.NumberOfSections)
+	for i := 0; i < int(f.FileHeader.NumberOfSections); i++ {
+		sh := new(SectionHeader32)
+		if err := binary.Read(sr, binary.LittleEndian, sh); err != nil {
+			return nil, err
+		}
+		var name string
+		if sh.Name[0] == '\x2F' {
+			si, _ := strconv.Atoi(cstring(sh.Name[1:]))
+			name, _ = getString(ss, si)
+		} else {
+			name = cstring(sh.Name[0:])
+		}
+		s := new(Section)
+		s.SectionHeader = SectionHeader{
+			Name:                 name,
+			VirtualSize:          sh.VirtualSize,
+			VirtualAddress:       sh.VirtualAddress,
+			Size:                 sh.SizeOfRawData,
+			Offset:               sh.PointerToRawData,
+			PointerToRelocations: sh.PointerToRelocations,
+			PointerToLineNumbers: sh.PointerToLineNumbers,
+			NumberOfRelocations:  sh.NumberOfRelocations,
+			NumberOfLineNumbers:  sh.NumberOfLineNumbers,
+			Characteristics:      sh.Characteristics,
+		}
+		s.sr = io.NewSectionReader(r, int64(s.SectionHeader.Offset), int64(s.SectionHeader.Size))
+		s.ReaderAt = s.sr
+		f.Sections[i] = s
+	}
+	return f, nil
+}
+
+func cstring(b []byte) string {
+	var i int
+	for i = 0; i < len(b) && b[i] != 0; i++ {
+	}
+	return string(b[0:i])
+}
+
+// getString extracts a string from symbol string table.
+func getString(section []byte, start int) (string, bool) {
+	if start < 0 || start >= len(section) {
+		return "", false
+	}
+
+	for end := start; end < len(section); end++ {
+		if section[end] == 0 {
+			return string(section[start:end]), true
+		}
+	}
+	return "", false
+}
+
+// Section returns the first section with the given name, or nil if no such
+// section exists.
+func (f *File) Section(name string) *Section {
+	for _, s := range f.Sections {
+		if s.Name == name {
+			return s
+		}
+	}
+	return nil
+}
+
+func (f *File) DWARF() (*dwarf.Data, error) {
+	// There are many other DWARF sections, but these
+	// are the required ones, and the debug/dwarf package
+	// does not use the others, so don't bother loading them.
+	var names = [...]string{"abbrev", "info", "str"}
+	var dat [len(names)][]byte
+	for i, name := range names {
+		name = ".debug_" + name
+		s := f.Section(name)
+		if s == nil {
+			continue
+		}
+		b, err := s.Data()
+		if err != nil && uint32(len(b)) < s.Size {
+			return nil, err
+		}
+		dat[i] = b
+	}
+
+	abbrev, info, str := dat[0], dat[1], dat[2]
+	return dwarf.New(abbrev, nil, nil, info, nil, nil, nil, str)
+}
+
+// ImportedSymbols returns the names of all symbols
+// referred to by the binary f that are expected to be
+// satisfied by other libraries at dynamic load time.
+// It does not return weak symbols.
+func (f *File) ImportedSymbols() ([]string, error) {
+	pe64 := f.Machine == IMAGE_FILE_MACHINE_AMD64
+	ds := f.Section(".idata")
+	if ds == nil {
+		// not dynamic, so no libraries
+		return nil, nil
+	}
+	d, err := ds.Data()
+	if err != nil {
+		return nil, err
+	}
+	var ida []ImportDirectory
+	for len(d) > 0 {
+		var dt ImportDirectory
+		dt.OriginalFirstThunk = binary.LittleEndian.Uint32(d[0:4])
+		dt.Name = binary.LittleEndian.Uint32(d[12:16])
+		dt.FirstThunk = binary.LittleEndian.Uint32(d[16:20])
+		d = d[20:]
+		if dt.OriginalFirstThunk == 0 {
+			break
+		}
+		ida = append(ida, dt)
+	}
+	names, _ := ds.Data()
+	var all []string
+	for _, dt := range ida {
+		dt.dll, _ = getString(names, int(dt.Name-ds.VirtualAddress))
+		d, _ = ds.Data()
+		// seek to OriginalFirstThunk
+		d = d[dt.OriginalFirstThunk-ds.VirtualAddress:]
+		for len(d) > 0 {
+			if pe64 { // 64bit
+				va := binary.LittleEndian.Uint64(d[0:8])
+				d = d[8:]
+				if va == 0 {
+					break
+				}
+				if va&0x8000000000000000 > 0 { // is Ordinal
+					// TODO add dynimport ordinal support.
+				} else {
+					fn, _ := getString(names, int(uint32(va)-ds.VirtualAddress+2))
+					all = append(all, fn+":"+dt.dll)
+				}
+			} else { // 32bit
+				va := binary.LittleEndian.Uint32(d[0:4])
+				d = d[4:]
+				if va == 0 {
+					break
+				}
+				if va&0x80000000 > 0 { // is Ordinal
+					// TODO add dynimport ordinal support.
+					//ord := va&0x0000FFFF
+				} else {
+					fn, _ := getString(names, int(va-ds.VirtualAddress+2))
+					all = append(all, fn+":"+dt.dll)
+				}
+			}
+		}
+	}
+
+	return all, nil
+}
+
+// ImportedLibraries returns the names of all libraries
+// referred to by the binary f that are expected to be
+// linked with the binary at dynamic link time.
+func (f *File) ImportedLibraries() ([]string, error) {
+	// TODO
+	// cgo -dynimport don't use this for windows PE, so just return.
+	return nil, nil
+}
diff --git a/src/debug/pe/file_test.go b/src/debug/pe/file_test.go
new file mode 100644
index 0000000..0d73969
--- /dev/null
+++ b/src/debug/pe/file_test.go
@@ -0,0 +1,243 @@
+// Copyright 2009 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package pe
+
+import (
+	"reflect"
+	"testing"
+)
+
+type fileTest struct {
+	file     string
+	hdr      FileHeader
+	opthdr   interface{}
+	sections []*SectionHeader
+	symbols  []*Symbol
+}
+
+var fileTests = []fileTest{
+	{
+		"testdata/gcc-386-mingw-obj",
+		FileHeader{0x014c, 0x000c, 0x0, 0x64a, 0x1e, 0x0, 0x104},
+		nil,
+		[]*SectionHeader{
+			{".text", 0, 0, 36, 500, 1440, 0, 3, 0, 0x60300020},
+			{".data", 0, 0, 0, 0, 0, 0, 0, 0, 3224371264},
+			{".bss", 0, 0, 0, 0, 0, 0, 0, 0, 3224371328},
+			{".debug_abbrev", 0, 0, 137, 536, 0, 0, 0, 0, 0x42100000},
+			{".debug_info", 0, 0, 418, 673, 1470, 0, 7, 0, 1108344832},
+			{".debug_line", 0, 0, 128, 1091, 1540, 0, 1, 0, 1108344832},
+			{".rdata", 0, 0, 16, 1219, 0, 0, 0, 0, 1076887616},
+			{".debug_frame", 0, 0, 52, 1235, 1550, 0, 2, 0, 1110441984},
+			{".debug_loc", 0, 0, 56, 1287, 0, 0, 0, 0, 1108344832},
+			{".debug_pubnames", 0, 0, 27, 1343, 1570, 0, 1, 0, 1108344832},
+			{".debug_pubtypes", 0, 0, 38, 1370, 1580, 0, 1, 0, 1108344832},
+			{".debug_aranges", 0, 0, 32, 1408, 1590, 0, 2, 0, 1108344832},
+		},
+		[]*Symbol{
+			{".file", 0x0, -2, 0x0, 0x67},
+			{"_main", 0x0, 1, 0x20, 0x2},
+			{".text", 0x0, 1, 0x0, 0x3},
+			{".data", 0x0, 2, 0x0, 0x3},
+			{".bss", 0x0, 3, 0x0, 0x3},
+			{".debug_abbrev", 0x0, 4, 0x0, 0x3},
+			{".debug_info", 0x0, 5, 0x0, 0x3},
+			{".debug_line", 0x0, 6, 0x0, 0x3},
+			{".rdata", 0x0, 7, 0x0, 0x3},
+			{".debug_frame", 0x0, 8, 0x0, 0x3},
+			{".debug_loc", 0x0, 9, 0x0, 0x3},
+			{".debug_pubnames", 0x0, 10, 0x0, 0x3},
+			{".debug_pubtypes", 0x0, 11, 0x0, 0x3},
+			{".debug_aranges", 0x0, 12, 0x0, 0x3},
+			{"___main", 0x0, 0, 0x20, 0x2},
+			{"_puts", 0x0, 0, 0x20, 0x2},
+		},
+	},
+	{
+		"testdata/gcc-386-mingw-exec",
+		FileHeader{0x014c, 0x000f, 0x4c6a1b60, 0x3c00, 0x282, 0xe0, 0x107},
+		&OptionalHeader32{
+			0x10b, 0x2, 0x38, 0xe00, 0x1a00, 0x200, 0x1160, 0x1000, 0x2000, 0x400000, 0x1000, 0x200, 0x4, 0x0, 0x1, 0x0, 0x4, 0x0, 0x0, 0x10000, 0x400, 0x14abb, 0x3, 0x0, 0x200000, 0x1000, 0x100000, 0x1000, 0x0, 0x10,
+			[16]DataDirectory{
+				{0x0, 0x0},
+				{0x5000, 0x3c8},
+				{0x0, 0x0},
+				{0x0, 0x0},
+				{0x0, 0x0},
+				{0x0, 0x0},
+				{0x0, 0x0},
+				{0x0, 0x0},
+				{0x0, 0x0},
+				{0x7000, 0x18},
+				{0x0, 0x0},
+				{0x0, 0x0},
+				{0x0, 0x0},
+				{0x0, 0x0},
+				{0x0, 0x0},
+				{0x0, 0x0},
+			},
+		},
+		[]*SectionHeader{
+			{".text", 0xcd8, 0x1000, 0xe00, 0x400, 0x0, 0x0, 0x0, 0x0, 0x60500060},
+			{".data", 0x10, 0x2000, 0x200, 0x1200, 0x0, 0x0, 0x0, 0x0, 0xc0300040},
+			{".rdata", 0x120, 0x3000, 0x200, 0x1400, 0x0, 0x0, 0x0, 0x0, 0x40300040},
+			{".bss", 0xdc, 0x4000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0400080},
+			{".idata", 0x3c8, 0x5000, 0x400, 0x1600, 0x0, 0x0, 0x0, 0x0, 0xc0300040},
+			{".CRT", 0x18, 0x6000, 0x200, 0x1a00, 0x0, 0x0, 0x0, 0x0, 0xc0300040},
+			{".tls", 0x20, 0x7000, 0x200, 0x1c00, 0x0, 0x0, 0x0, 0x0, 0xc0300040},
+			{".debug_aranges", 0x20, 0x8000, 0x200, 0x1e00, 0x0, 0x0, 0x0, 0x0, 0x42100000},
+			{".debug_pubnames", 0x51, 0x9000, 0x200, 0x2000, 0x0, 0x0, 0x0, 0x0, 0x42100000},
+			{".debug_pubtypes", 0x91, 0xa000, 0x200, 0x2200, 0x0, 0x0, 0x0, 0x0, 0x42100000},
+			{".debug_info", 0xe22, 0xb000, 0x1000, 0x2400, 0x0, 0x0, 0x0, 0x0, 0x42100000},
+			{".debug_abbrev", 0x157, 0xc000, 0x200, 0x3400, 0x0, 0x0, 0x0, 0x0, 0x42100000},
+			{".debug_line", 0x144, 0xd000, 0x200, 0x3600, 0x0, 0x0, 0x0, 0x0, 0x42100000},
+			{".debug_frame", 0x34, 0xe000, 0x200, 0x3800, 0x0, 0x0, 0x0, 0x0, 0x42300000},
+			{".debug_loc", 0x38, 0xf000, 0x200, 0x3a00, 0x0, 0x0, 0x0, 0x0, 0x42100000},
+		},
+		[]*Symbol{},
+	},
+	{
+		"testdata/gcc-amd64-mingw-obj",
+		FileHeader{0x8664, 0x6, 0x0, 0x198, 0x12, 0x0, 0x4},
+		nil,
+		[]*SectionHeader{
+			{".text", 0x0, 0x0, 0x30, 0x104, 0x15c, 0x0, 0x3, 0x0, 0x60500020},
+			{".data", 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0500040},
+			{".bss", 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0500080},
+			{".rdata", 0x0, 0x0, 0x10, 0x134, 0x0, 0x0, 0x0, 0x0, 0x40500040},
+			{".xdata", 0x0, 0x0, 0xc, 0x144, 0x0, 0x0, 0x0, 0x0, 0x40300040},
+			{".pdata", 0x0, 0x0, 0xc, 0x150, 0x17a, 0x0, 0x3, 0x0, 0x40300040},
+		},
+		[]*Symbol{
+			{".file", 0x0, -2, 0x0, 0x67},
+			{"main", 0x0, 1, 0x20, 0x2},
+			{".text", 0x0, 1, 0x0, 0x3},
+			{".data", 0x0, 2, 0x0, 0x3},
+			{".bss", 0x0, 3, 0x0, 0x3},
+			{".rdata", 0x0, 4, 0x0, 0x3},
+			{".xdata", 0x0, 5, 0x0, 0x3},
+			{".pdata", 0x0, 6, 0x0, 0x3},
+			{"__main", 0x0, 0, 0x20, 0x2},
+			{"puts", 0x0, 0, 0x20, 0x2},
+		},
+	},
+	{
+		"testdata/gcc-amd64-mingw-exec",
+		FileHeader{0x8664, 0x11, 0x53e4364f, 0x39600, 0x6fc, 0xf0, 0x27},
+		&OptionalHeader64{
+			0x20b, 0x2, 0x16, 0x6a00, 0x2400, 0x1600, 0x14e0, 0x1000, 0x400000, 0x1000, 0x200, 0x4, 0x0, 0x0, 0x0, 0x5, 0x2, 0x0, 0x45000, 0x600, 0x46f19, 0x3, 0x0, 0x200000, 0x1000, 0x100000, 0x1000, 0x0, 0x10,
+			[16]DataDirectory{
+				{0x0, 0x0},
+				{0xe000, 0x990},
+				{0x0, 0x0},
+				{0xa000, 0x498},
+				{0x0, 0x0},
+				{0x0, 0x0},
+				{0x0, 0x0},
+				{0x0, 0x0},
+				{0x0, 0x0},
+				{0x10000, 0x28},
+				{0x0, 0x0},
+				{0x0, 0x0},
+				{0xe254, 0x218},
+				{0x0, 0x0},
+				{0x0, 0x0},
+				{0x0, 0x0},
+			}},
+		[]*SectionHeader{
+			{".text", 0x6860, 0x1000, 0x6a00, 0x600, 0x0, 0x0, 0x0, 0x0, 0x60500020},
+			{".data", 0xe0, 0x8000, 0x200, 0x7000, 0x0, 0x0, 0x0, 0x0, 0xc0500040},
+			{".rdata", 0x6b0, 0x9000, 0x800, 0x7200, 0x0, 0x0, 0x0, 0x0, 0x40600040},
+			{".pdata", 0x498, 0xa000, 0x600, 0x7a00, 0x0, 0x0, 0x0, 0x0, 0x40300040},
+			{".xdata", 0x488, 0xb000, 0x600, 0x8000, 0x0, 0x0, 0x0, 0x0, 0x40300040},
+			{".bss", 0x1410, 0xc000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0600080},
+			{".idata", 0x990, 0xe000, 0xa00, 0x8600, 0x0, 0x0, 0x0, 0x0, 0xc0300040},
+			{".CRT", 0x68, 0xf000, 0x200, 0x9000, 0x0, 0x0, 0x0, 0x0, 0xc0400040},
+			{".tls", 0x48, 0x10000, 0x200, 0x9200, 0x0, 0x0, 0x0, 0x0, 0xc0600040},
+			{".debug_aranges", 0x600, 0x11000, 0x600, 0x9400, 0x0, 0x0, 0x0, 0x0, 0x42500040},
+			{".debug_info", 0x1316e, 0x12000, 0x13200, 0x9a00, 0x0, 0x0, 0x0, 0x0, 0x42100040},
+			{".debug_abbrev", 0x2ccb, 0x26000, 0x2e00, 0x1cc00, 0x0, 0x0, 0x0, 0x0, 0x42100040},
+			{".debug_line", 0x3c4d, 0x29000, 0x3e00, 0x1fa00, 0x0, 0x0, 0x0, 0x0, 0x42100040},
+			{".debug_frame", 0x18b8, 0x2d000, 0x1a00, 0x23800, 0x0, 0x0, 0x0, 0x0, 0x42400040},
+			{".debug_str", 0x396, 0x2f000, 0x400, 0x25200, 0x0, 0x0, 0x0, 0x0, 0x42100040},
+			{".debug_loc", 0x13240, 0x30000, 0x13400, 0x25600, 0x0, 0x0, 0x0, 0x0, 0x42100040},
+			{".debug_ranges", 0xa70, 0x44000, 0xc00, 0x38a00, 0x0, 0x0, 0x0, 0x0, 0x42100040},
+		},
+		[]*Symbol{},
+	},
+}
+
+func isOptHdrEq(a, b interface{}) bool {
+	switch va := a.(type) {
+	case *OptionalHeader32:
+		vb, ok := b.(*OptionalHeader32)
+		if !ok {
+			return false
+		}
+		return *vb == *va
+	case *OptionalHeader64:
+		vb, ok := b.(*OptionalHeader64)
+		if !ok {
+			return false
+		}
+		return *vb == *va
+	case nil:
+		return b == nil
+	}
+	return false
+}
+
+func TestOpen(t *testing.T) {
+	for i := range fileTests {
+		tt := &fileTests[i]
+
+		f, err := Open(tt.file)
+		if err != nil {
+			t.Error(err)
+			continue
+		}
+		if !reflect.DeepEqual(f.FileHeader, tt.hdr) {
+			t.Errorf("open %s:\n\thave %#v\n\twant %#v\n", tt.file, f.FileHeader, tt.hdr)
+			continue
+		}
+		if !isOptHdrEq(tt.opthdr, f.OptionalHeader) {
+			t.Errorf("open %s:\n\thave %#v\n\twant %#v\n", tt.file, f.OptionalHeader, tt.opthdr)
+			continue
+		}
+
+		for i, sh := range f.Sections {
+			if i >= len(tt.sections) {
+				break
+			}
+			have := &sh.SectionHeader
+			want := tt.sections[i]
+			if !reflect.DeepEqual(have, want) {
+				t.Errorf("open %s, section %d:\n\thave %#v\n\twant %#v\n", tt.file, i, have, want)
+			}
+		}
+		tn := len(tt.sections)
+		fn := len(f.Sections)
+		if tn != fn {
+			t.Errorf("open %s: len(Sections) = %d, want %d", tt.file, fn, tn)
+		}
+		for i, have := range f.Symbols {
+			if i >= len(tt.symbols) {
+				break
+			}
+			want := tt.symbols[i]
+			if !reflect.DeepEqual(have, want) {
+				t.Errorf("open %s, symbol %d:\n\thave %#v\n\twant %#v\n", tt.file, i, have, want)
+			}
+		}
+	}
+}
+
+func TestOpenFailure(t *testing.T) {
+	filename := "file.go"    // not a PE file
+	_, err := Open(filename) // don't crash
+	if err == nil {
+		t.Errorf("open %s: succeeded unexpectedly", filename)
+	}
+}
diff --git a/src/pkg/debug/pe/pe.go b/src/debug/pe/pe.go
similarity index 100%
rename from src/pkg/debug/pe/pe.go
rename to src/debug/pe/pe.go
diff --git a/src/pkg/debug/pe/testdata/gcc-386-mingw-exec b/src/debug/pe/testdata/gcc-386-mingw-exec
similarity index 100%
rename from src/pkg/debug/pe/testdata/gcc-386-mingw-exec
rename to src/debug/pe/testdata/gcc-386-mingw-exec
diff --git a/src/pkg/debug/pe/testdata/gcc-386-mingw-obj b/src/debug/pe/testdata/gcc-386-mingw-obj
similarity index 100%
rename from src/pkg/debug/pe/testdata/gcc-386-mingw-obj
rename to src/debug/pe/testdata/gcc-386-mingw-obj
diff --git a/src/debug/pe/testdata/gcc-amd64-mingw-exec b/src/debug/pe/testdata/gcc-amd64-mingw-exec
new file mode 100644
index 0000000..ce6feb6
Binary files /dev/null and b/src/debug/pe/testdata/gcc-amd64-mingw-exec differ
diff --git a/src/pkg/debug/pe/testdata/gcc-amd64-mingw-obj b/src/debug/pe/testdata/gcc-amd64-mingw-obj
similarity index 100%
rename from src/pkg/debug/pe/testdata/gcc-amd64-mingw-obj
rename to src/debug/pe/testdata/gcc-amd64-mingw-obj
diff --git a/src/pkg/debug/pe/testdata/hello.c b/src/debug/pe/testdata/hello.c
similarity index 100%
rename from src/pkg/debug/pe/testdata/hello.c
rename to src/debug/pe/testdata/hello.c
diff --git a/src/debug/plan9obj/file.go b/src/debug/plan9obj/file.go
new file mode 100644
index 0000000..b11ed86
--- /dev/null
+++ b/src/debug/plan9obj/file.go
@@ -0,0 +1,328 @@
+// 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 plan9obj implements access to Plan 9 a.out object files.
+package plan9obj
+
+import (
+	"encoding/binary"
+	"errors"
+	"fmt"
+	"io"
+	"os"
+)
+
+// A FileHeader represents a Plan 9 a.out file header.
+type FileHeader struct {
+	Magic       uint32
+	Bss         uint32
+	Entry       uint64
+	PtrSize     int
+	LoadAddress uint64
+	HdrSize     uint64
+}
+
+// A File represents an open Plan 9 a.out file.
+type File struct {
+	FileHeader
+	Sections []*Section
+	closer   io.Closer
+}
+
+// A SectionHeader represents a single Plan 9 a.out section header.
+// This structure doesn't exist on-disk, but eases navigation
+// through the object file.
+type SectionHeader struct {
+	Name   string
+	Size   uint32
+	Offset uint32
+}
+
+// A Section represents a single section in a Plan 9 a.out file.
+type Section struct {
+	SectionHeader
+
+	// Embed ReaderAt for ReadAt method.
+	// Do not embed SectionReader directly
+	// to avoid having Read and Seek.
+	// If a client wants Read and Seek it must use
+	// Open() to avoid fighting over the seek offset
+	// with other clients.
+	io.ReaderAt
+	sr *io.SectionReader
+}
+
+// Data reads and returns the contents of the Plan 9 a.out section.
+func (s *Section) Data() ([]byte, error) {
+	dat := make([]byte, s.sr.Size())
+	n, err := s.sr.ReadAt(dat, 0)
+	if n == len(dat) {
+		err = nil
+	}
+	return dat[0:n], err
+}
+
+// Open returns a new ReadSeeker reading the Plan 9 a.out section.
+func (s *Section) Open() io.ReadSeeker { return io.NewSectionReader(s.sr, 0, 1<<63-1) }
+
+// A Symbol represents an entry in a Plan 9 a.out symbol table section.
+type Sym struct {
+	Value uint64
+	Type  rune
+	Name  string
+}
+
+/*
+ * Plan 9 a.out reader
+ */
+
+// formatError is returned by some operations if the data does
+// not have the correct format for an object file.
+type formatError struct {
+	off int
+	msg string
+	val interface{}
+}
+
+func (e *formatError) Error() string {
+	msg := e.msg
+	if e.val != nil {
+		msg += fmt.Sprintf(" '%v'", e.val)
+	}
+	msg += fmt.Sprintf(" in record at byte %#x", e.off)
+	return msg
+}
+
+// Open opens the named file using os.Open and prepares it for use as a Plan 9 a.out binary.
+func Open(name string) (*File, error) {
+	f, err := os.Open(name)
+	if err != nil {
+		return nil, err
+	}
+	ff, err := NewFile(f)
+	if err != nil {
+		f.Close()
+		return nil, err
+	}
+	ff.closer = f
+	return ff, nil
+}
+
+// Close closes the File.
+// If the File was created using NewFile directly instead of Open,
+// Close has no effect.
+func (f *File) Close() error {
+	var err error
+	if f.closer != nil {
+		err = f.closer.Close()
+		f.closer = nil
+	}
+	return err
+}
+
+func parseMagic(magic []byte) (uint32, error) {
+	m := binary.BigEndian.Uint32(magic)
+	switch m {
+	case Magic386, MagicAMD64, MagicARM:
+		return m, nil
+	}
+	return 0, &formatError{0, "bad magic number", magic}
+}
+
+// NewFile creates a new File for accessing a Plan 9 binary in an underlying reader.
+// The Plan 9 binary is expected to start at position 0 in the ReaderAt.
+func NewFile(r io.ReaderAt) (*File, error) {
+	sr := io.NewSectionReader(r, 0, 1<<63-1)
+	// Read and decode Plan 9 magic
+	var magic [4]byte
+	if _, err := r.ReadAt(magic[:], 0); err != nil {
+		return nil, err
+	}
+	_, err := parseMagic(magic[:])
+	if err != nil {
+		return nil, err
+	}
+
+	ph := new(prog)
+	if err := binary.Read(sr, binary.BigEndian, ph); err != nil {
+		return nil, err
+	}
+
+	f := &File{FileHeader: FileHeader{
+		Magic:       ph.Magic,
+		Bss:         ph.Bss,
+		Entry:       uint64(ph.Entry),
+		PtrSize:     4,
+		LoadAddress: 0x1000,
+		HdrSize:     4 * 8,
+	}}
+
+	if ph.Magic&Magic64 != 0 {
+		if err := binary.Read(sr, binary.BigEndian, &f.Entry); err != nil {
+			return nil, err
+		}
+		f.PtrSize = 8
+		f.LoadAddress = 0x200000
+		f.HdrSize += 8
+	}
+
+	var sects = []struct {
+		name string
+		size uint32
+	}{
+		{"text", ph.Text},
+		{"data", ph.Data},
+		{"syms", ph.Syms},
+		{"spsz", ph.Spsz},
+		{"pcsz", ph.Pcsz},
+	}
+
+	f.Sections = make([]*Section, 5)
+
+	off := uint32(f.HdrSize)
+
+	for i, sect := range sects {
+		s := new(Section)
+		s.SectionHeader = SectionHeader{
+			Name:   sect.name,
+			Size:   sect.size,
+			Offset: off,
+		}
+		off += sect.size
+		s.sr = io.NewSectionReader(r, int64(s.Offset), int64(s.Size))
+		s.ReaderAt = s.sr
+		f.Sections[i] = s
+	}
+
+	return f, nil
+}
+
+func walksymtab(data []byte, ptrsz int, fn func(sym) error) error {
+	var order binary.ByteOrder = binary.BigEndian
+	var s sym
+	p := data
+	for len(p) >= 4 {
+		// Symbol type, value.
+		if len(p) < ptrsz {
+			return &formatError{len(data), "unexpected EOF", nil}
+		}
+		// fixed-width value
+		if ptrsz == 8 {
+			s.value = order.Uint64(p[0:8])
+			p = p[8:]
+		} else {
+			s.value = uint64(order.Uint32(p[0:4]))
+			p = p[4:]
+		}
+
+		var typ byte
+		typ = p[0] & 0x7F
+		s.typ = typ
+		p = p[1:]
+
+		// Name.
+		var i int
+		var nnul int
+		for i = 0; i < len(p); i++ {
+			if p[i] == 0 {
+				nnul = 1
+				break
+			}
+		}
+		switch typ {
+		case 'z', 'Z':
+			p = p[i+nnul:]
+			for i = 0; i+2 <= len(p); i += 2 {
+				if p[i] == 0 && p[i+1] == 0 {
+					nnul = 2
+					break
+				}
+			}
+		}
+		if len(p) < i+nnul {
+			return &formatError{len(data), "unexpected EOF", nil}
+		}
+		s.name = p[0:i]
+		i += nnul
+		p = p[i:]
+
+		fn(s)
+	}
+	return nil
+}
+
+// NewTable decodes the Go symbol table in data,
+// returning an in-memory representation.
+func newTable(symtab []byte, ptrsz int) ([]Sym, error) {
+	var n int
+	err := walksymtab(symtab, ptrsz, func(s sym) error {
+		n++
+		return nil
+	})
+	if err != nil {
+		return nil, err
+	}
+
+	fname := make(map[uint16]string)
+	syms := make([]Sym, 0, n)
+	err = walksymtab(symtab, ptrsz, func(s sym) error {
+		n := len(syms)
+		syms = syms[0 : n+1]
+		ts := &syms[n]
+		ts.Type = rune(s.typ)
+		ts.Value = s.value
+		switch s.typ {
+		default:
+			ts.Name = string(s.name[:])
+		case 'z', 'Z':
+			for i := 0; i < len(s.name); i += 2 {
+				eltIdx := binary.BigEndian.Uint16(s.name[i : i+2])
+				elt, ok := fname[eltIdx]
+				if !ok {
+					return &formatError{-1, "bad filename code", eltIdx}
+				}
+				if n := len(ts.Name); n > 0 && ts.Name[n-1] != '/' {
+					ts.Name += "/"
+				}
+				ts.Name += elt
+			}
+		}
+		switch s.typ {
+		case 'f':
+			fname[uint16(s.value)] = ts.Name
+		}
+		return nil
+	})
+	if err != nil {
+		return nil, err
+	}
+
+	return syms, nil
+}
+
+// Symbols returns the symbol table for f.
+func (f *File) Symbols() ([]Sym, error) {
+	symtabSection := f.Section("syms")
+	if symtabSection == nil {
+		return nil, errors.New("no symbol section")
+	}
+
+	symtab, err := symtabSection.Data()
+	if err != nil {
+		return nil, errors.New("cannot load symbol section")
+	}
+
+	return newTable(symtab, f.PtrSize)
+}
+
+// Section returns a section with the given name, or nil if no such
+// section exists.
+func (f *File) Section(name string) *Section {
+	for _, s := range f.Sections {
+		if s.Name == name {
+			return s
+		}
+	}
+	return nil
+}
diff --git a/src/debug/plan9obj/file_test.go b/src/debug/plan9obj/file_test.go
new file mode 100644
index 0000000..cfd7a61
--- /dev/null
+++ b/src/debug/plan9obj/file_test.go
@@ -0,0 +1,81 @@
+// 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 plan9obj
+
+import (
+	"reflect"
+	"testing"
+)
+
+type fileTest struct {
+	file     string
+	hdr      FileHeader
+	sections []*SectionHeader
+}
+
+var fileTests = []fileTest{
+	{
+		"testdata/386-plan9-exec",
+		FileHeader{Magic386, 0x324, 0x14, 4, 0x1000, 32},
+		[]*SectionHeader{
+			{"text", 0x4c5f, 0x20},
+			{"data", 0x94c, 0x4c7f},
+			{"syms", 0x2c2b, 0x55cb},
+			{"spsz", 0x0, 0x81f6},
+			{"pcsz", 0xf7a, 0x81f6},
+		},
+	},
+	{
+		"testdata/amd64-plan9-exec",
+		FileHeader{MagicAMD64, 0x618, 0x13, 8, 0x200000, 40},
+		[]*SectionHeader{
+			{"text", 0x4213, 0x28},
+			{"data", 0xa80, 0x423b},
+			{"syms", 0x2c8c, 0x4cbb},
+			{"spsz", 0x0, 0x7947},
+			{"pcsz", 0xca0, 0x7947},
+		},
+	},
+}
+
+func TestOpen(t *testing.T) {
+	for i := range fileTests {
+		tt := &fileTests[i]
+
+		f, err := Open(tt.file)
+		if err != nil {
+			t.Error(err)
+			continue
+		}
+		if !reflect.DeepEqual(f.FileHeader, tt.hdr) {
+			t.Errorf("open %s:\n\thave %#v\n\twant %#v\n", tt.file, f.FileHeader, tt.hdr)
+			continue
+		}
+
+		for i, sh := range f.Sections {
+			if i >= len(tt.sections) {
+				break
+			}
+			have := &sh.SectionHeader
+			want := tt.sections[i]
+			if !reflect.DeepEqual(have, want) {
+				t.Errorf("open %s, section %d:\n\thave %#v\n\twant %#v\n", tt.file, i, have, want)
+			}
+		}
+		tn := len(tt.sections)
+		fn := len(f.Sections)
+		if tn != fn {
+			t.Errorf("open %s: len(Sections) = %d, want %d", tt.file, fn, tn)
+		}
+	}
+}
+
+func TestOpenFailure(t *testing.T) {
+	filename := "file.go"    // not a Plan 9 a.out file
+	_, err := Open(filename) // don't crash
+	if err == nil {
+		t.Errorf("open %s: succeeded unexpectedly", filename)
+	}
+}
diff --git a/src/pkg/debug/plan9obj/plan9obj.go b/src/debug/plan9obj/plan9obj.go
similarity index 100%
rename from src/pkg/debug/plan9obj/plan9obj.go
rename to src/debug/plan9obj/plan9obj.go
diff --git a/src/pkg/debug/plan9obj/testdata/386-plan9-exec b/src/debug/plan9obj/testdata/386-plan9-exec
similarity index 100%
rename from src/pkg/debug/plan9obj/testdata/386-plan9-exec
rename to src/debug/plan9obj/testdata/386-plan9-exec
diff --git a/src/pkg/debug/plan9obj/testdata/amd64-plan9-exec b/src/debug/plan9obj/testdata/amd64-plan9-exec
similarity index 100%
rename from src/pkg/debug/plan9obj/testdata/amd64-plan9-exec
rename to src/debug/plan9obj/testdata/amd64-plan9-exec
diff --git a/src/pkg/debug/plan9obj/testdata/hello.c b/src/debug/plan9obj/testdata/hello.c
similarity index 100%
rename from src/pkg/debug/plan9obj/testdata/hello.c
rename to src/debug/plan9obj/testdata/hello.c
diff --git a/src/encoding/ascii85/ascii85.go b/src/encoding/ascii85/ascii85.go
new file mode 100644
index 0000000..4d71938
--- /dev/null
+++ b/src/encoding/ascii85/ascii85.go
@@ -0,0 +1,310 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package ascii85 implements the ascii85 data encoding
+// as used in the btoa tool and Adobe's PostScript and PDF document formats.
+package ascii85
+
+import (
+	"io"
+	"strconv"
+)
+
+/*
+ * Encoder
+ */
+
+// Encode encodes src into at most MaxEncodedLen(len(src))
+// bytes of dst, returning the actual number of bytes written.
+//
+// The encoding handles 4-byte chunks, using a special encoding
+// for the last fragment, so Encode is not appropriate for use on
+// individual blocks of a large data stream.  Use NewEncoder() instead.
+//
+// Often, ascii85-encoded data is wrapped in <~ and ~> symbols.
+// Encode does not add these.
+func Encode(dst, src []byte) int {
+	if len(src) == 0 {
+		return 0
+	}
+
+	n := 0
+	for len(src) > 0 {
+		dst[0] = 0
+		dst[1] = 0
+		dst[2] = 0
+		dst[3] = 0
+		dst[4] = 0
+
+		// Unpack 4 bytes into uint32 to repack into base 85 5-byte.
+		var v uint32
+		switch len(src) {
+		default:
+			v |= uint32(src[3])
+			fallthrough
+		case 3:
+			v |= uint32(src[2]) << 8
+			fallthrough
+		case 2:
+			v |= uint32(src[1]) << 16
+			fallthrough
+		case 1:
+			v |= uint32(src[0]) << 24
+		}
+
+		// Special case: zero (!!!!!) shortens to z.
+		if v == 0 && len(src) >= 4 {
+			dst[0] = 'z'
+			dst = dst[1:]
+			src = src[4:]
+			n++
+			continue
+		}
+
+		// Otherwise, 5 base 85 digits starting at !.
+		for i := 4; i >= 0; i-- {
+			dst[i] = '!' + byte(v%85)
+			v /= 85
+		}
+
+		// If src was short, discard the low destination bytes.
+		m := 5
+		if len(src) < 4 {
+			m -= 4 - len(src)
+			src = nil
+		} else {
+			src = src[4:]
+		}
+		dst = dst[m:]
+		n += m
+	}
+	return n
+}
+
+// MaxEncodedLen returns the maximum length of an encoding of n source bytes.
+func MaxEncodedLen(n int) int { return (n + 3) / 4 * 5 }
+
+// NewEncoder returns a new ascii85 stream encoder.  Data written to
+// the returned writer will be encoded and then written to w.
+// Ascii85 encodings operate in 32-bit blocks; when finished
+// writing, the caller must Close the returned encoder to flush any
+// trailing partial block.
+func NewEncoder(w io.Writer) io.WriteCloser { return &encoder{w: w} }
+
+type encoder struct {
+	err  error
+	w    io.Writer
+	buf  [4]byte    // buffered data waiting to be encoded
+	nbuf int        // number of bytes in buf
+	out  [1024]byte // output buffer
+}
+
+func (e *encoder) Write(p []byte) (n int, err error) {
+	if e.err != nil {
+		return 0, e.err
+	}
+
+	// Leading fringe.
+	if e.nbuf > 0 {
+		var i int
+		for i = 0; i < len(p) && e.nbuf < 4; i++ {
+			e.buf[e.nbuf] = p[i]
+			e.nbuf++
+		}
+		n += i
+		p = p[i:]
+		if e.nbuf < 4 {
+			return
+		}
+		nout := Encode(e.out[0:], e.buf[0:])
+		if _, e.err = e.w.Write(e.out[0:nout]); e.err != nil {
+			return n, e.err
+		}
+		e.nbuf = 0
+	}
+
+	// Large interior chunks.
+	for len(p) >= 4 {
+		nn := len(e.out) / 5 * 4
+		if nn > len(p) {
+			nn = len(p)
+		}
+		nn -= nn % 4
+		if nn > 0 {
+			nout := Encode(e.out[0:], p[0:nn])
+			if _, e.err = e.w.Write(e.out[0:nout]); e.err != nil {
+				return n, e.err
+			}
+		}
+		n += nn
+		p = p[nn:]
+	}
+
+	// Trailing fringe.
+	for i := 0; i < len(p); i++ {
+		e.buf[i] = p[i]
+	}
+	e.nbuf = len(p)
+	n += len(p)
+	return
+}
+
+// Close flushes any pending output from the encoder.
+// It is an error to call Write after calling Close.
+func (e *encoder) Close() error {
+	// If there's anything left in the buffer, flush it out
+	if e.err == nil && e.nbuf > 0 {
+		nout := Encode(e.out[0:], e.buf[0:e.nbuf])
+		e.nbuf = 0
+		_, e.err = e.w.Write(e.out[0:nout])
+	}
+	return e.err
+}
+
+/*
+ * Decoder
+ */
+
+type CorruptInputError int64
+
+func (e CorruptInputError) Error() string {
+	return "illegal ascii85 data at input byte " + strconv.FormatInt(int64(e), 10)
+}
+
+// Decode decodes src into dst, returning both the number
+// of bytes written to dst and the number consumed from src.
+// If src contains invalid ascii85 data, Decode will return the
+// number of bytes successfully written and a CorruptInputError.
+// Decode ignores space and control characters in src.
+// Often, ascii85-encoded data is wrapped in <~ and ~> symbols.
+// Decode expects these to have been stripped by the caller.
+//
+// If flush is true, Decode assumes that src represents the
+// end of the input stream and processes it completely rather
+// than wait for the completion of another 32-bit block.
+//
+// NewDecoder wraps an io.Reader interface around Decode.
+//
+func Decode(dst, src []byte, flush bool) (ndst, nsrc int, err error) {
+	var v uint32
+	var nb int
+	for i, b := range src {
+		if len(dst)-ndst < 4 {
+			return
+		}
+		switch {
+		case b <= ' ':
+			continue
+		case b == 'z' && nb == 0:
+			nb = 5
+			v = 0
+		case '!' <= b && b <= 'u':
+			v = v*85 + uint32(b-'!')
+			nb++
+		default:
+			return 0, 0, CorruptInputError(i)
+		}
+		if nb == 5 {
+			nsrc = i + 1
+			dst[ndst] = byte(v >> 24)
+			dst[ndst+1] = byte(v >> 16)
+			dst[ndst+2] = byte(v >> 8)
+			dst[ndst+3] = byte(v)
+			ndst += 4
+			nb = 0
+			v = 0
+		}
+	}
+	if flush {
+		nsrc = len(src)
+		if nb > 0 {
+			// The number of output bytes in the last fragment
+			// is the number of leftover input bytes - 1:
+			// the extra byte provides enough bits to cover
+			// the inefficiency of the encoding for the block.
+			if nb == 1 {
+				return 0, 0, CorruptInputError(len(src))
+			}
+			for i := nb; i < 5; i++ {
+				// The short encoding truncated the output value.
+				// We have to assume the worst case values (digit 84)
+				// in order to ensure that the top bits are correct.
+				v = v*85 + 84
+			}
+			for i := 0; i < nb-1; i++ {
+				dst[ndst] = byte(v >> 24)
+				v <<= 8
+				ndst++
+			}
+		}
+	}
+	return
+}
+
+// NewDecoder constructs a new ascii85 stream decoder.
+func NewDecoder(r io.Reader) io.Reader { return &decoder{r: r} }
+
+type decoder struct {
+	err     error
+	readErr error
+	r       io.Reader
+	buf     [1024]byte // leftover input
+	nbuf    int
+	out     []byte // leftover decoded output
+	outbuf  [1024]byte
+}
+
+func (d *decoder) Read(p []byte) (n int, err error) {
+	if len(p) == 0 {
+		return 0, nil
+	}
+	if d.err != nil {
+		return 0, d.err
+	}
+
+	for {
+		// Copy leftover output from last decode.
+		if len(d.out) > 0 {
+			n = copy(p, d.out)
+			d.out = d.out[n:]
+			return
+		}
+
+		// Decode leftover input from last read.
+		var nn, nsrc, ndst int
+		if d.nbuf > 0 {
+			ndst, nsrc, d.err = Decode(d.outbuf[0:], d.buf[0:d.nbuf], d.readErr != nil)
+			if ndst > 0 {
+				d.out = d.outbuf[0:ndst]
+				d.nbuf = copy(d.buf[0:], d.buf[nsrc:d.nbuf])
+				continue // copy out and return
+			}
+			if ndst == 0 && d.err == nil {
+				// Special case: input buffer is mostly filled with non-data bytes.
+				// Filter out such bytes to make room for more input.
+				off := 0
+				for i := 0; i < d.nbuf; i++ {
+					if d.buf[i] > ' ' {
+						d.buf[off] = d.buf[i]
+						off++
+					}
+				}
+				d.nbuf = off
+			}
+		}
+
+		// Out of input, out of decoded output.  Check errors.
+		if d.err != nil {
+			return 0, d.err
+		}
+		if d.readErr != nil {
+			d.err = d.readErr
+			return 0, d.err
+		}
+
+		// Read more data.
+		nn, d.readErr = d.r.Read(d.buf[d.nbuf:])
+		d.nbuf += nn
+	}
+}
diff --git a/src/pkg/encoding/ascii85/ascii85_test.go b/src/encoding/ascii85/ascii85_test.go
similarity index 100%
rename from src/pkg/encoding/ascii85/ascii85_test.go
rename to src/encoding/ascii85/ascii85_test.go
diff --git a/src/encoding/asn1/asn1.go b/src/encoding/asn1/asn1.go
new file mode 100644
index 0000000..8b3d1b3
--- /dev/null
+++ b/src/encoding/asn1/asn1.go
@@ -0,0 +1,922 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package asn1 implements parsing of DER-encoded ASN.1 data structures,
+// as defined in ITU-T Rec X.690.
+//
+// See also ``A Layman's Guide to a Subset of ASN.1, BER, and DER,''
+// http://luca.ntop.org/Teaching/Appunti/asn1.html.
+package asn1
+
+// ASN.1 is a syntax for specifying abstract objects and BER, DER, PER, XER etc
+// are different encoding formats for those objects. Here, we'll be dealing
+// with DER, the Distinguished Encoding Rules. DER is used in X.509 because
+// it's fast to parse and, unlike BER, has a unique encoding for every object.
+// When calculating hashes over objects, it's important that the resulting
+// bytes be the same at both ends and DER removes this margin of error.
+//
+// ASN.1 is very complex and this package doesn't attempt to implement
+// everything by any means.
+
+import (
+	"fmt"
+	"math/big"
+	"reflect"
+	"strconv"
+	"time"
+)
+
+// A StructuralError suggests that the ASN.1 data is valid, but the Go type
+// which is receiving it doesn't match.
+type StructuralError struct {
+	Msg string
+}
+
+func (e StructuralError) Error() string { return "asn1: structure error: " + e.Msg }
+
+// A SyntaxError suggests that the ASN.1 data is invalid.
+type SyntaxError struct {
+	Msg string
+}
+
+func (e SyntaxError) Error() string { return "asn1: syntax error: " + e.Msg }
+
+// We start by dealing with each of the primitive types in turn.
+
+// BOOLEAN
+
+func parseBool(bytes []byte) (ret bool, err error) {
+	if len(bytes) != 1 {
+		err = SyntaxError{"invalid boolean"}
+		return
+	}
+
+	// DER demands that "If the encoding represents the boolean value TRUE,
+	// its single contents octet shall have all eight bits set to one."
+	// Thus only 0 and 255 are valid encoded values.
+	switch bytes[0] {
+	case 0:
+		ret = false
+	case 0xff:
+		ret = true
+	default:
+		err = SyntaxError{"invalid boolean"}
+	}
+
+	return
+}
+
+// INTEGER
+
+// parseInt64 treats the given bytes as a big-endian, signed integer and
+// returns the result.
+func parseInt64(bytes []byte) (ret int64, err error) {
+	if len(bytes) > 8 {
+		// We'll overflow an int64 in this case.
+		err = StructuralError{"integer too large"}
+		return
+	}
+	for bytesRead := 0; bytesRead < len(bytes); bytesRead++ {
+		ret <<= 8
+		ret |= int64(bytes[bytesRead])
+	}
+
+	// Shift up and down in order to sign extend the result.
+	ret <<= 64 - uint8(len(bytes))*8
+	ret >>= 64 - uint8(len(bytes))*8
+	return
+}
+
+// parseInt treats the given bytes as a big-endian, signed integer and returns
+// the result.
+func parseInt32(bytes []byte) (int32, error) {
+	ret64, err := parseInt64(bytes)
+	if err != nil {
+		return 0, err
+	}
+	if ret64 != int64(int32(ret64)) {
+		return 0, StructuralError{"integer too large"}
+	}
+	return int32(ret64), nil
+}
+
+var bigOne = big.NewInt(1)
+
+// parseBigInt treats the given bytes as a big-endian, signed integer and returns
+// the result.
+func parseBigInt(bytes []byte) *big.Int {
+	ret := new(big.Int)
+	if len(bytes) > 0 && bytes[0]&0x80 == 0x80 {
+		// This is a negative number.
+		notBytes := make([]byte, len(bytes))
+		for i := range notBytes {
+			notBytes[i] = ^bytes[i]
+		}
+		ret.SetBytes(notBytes)
+		ret.Add(ret, bigOne)
+		ret.Neg(ret)
+		return ret
+	}
+	ret.SetBytes(bytes)
+	return ret
+}
+
+// BIT STRING
+
+// BitString is the structure to use when you want an ASN.1 BIT STRING type. A
+// bit string is padded up to the nearest byte in memory and the number of
+// valid bits is recorded. Padding bits will be zero.
+type BitString struct {
+	Bytes     []byte // bits packed into bytes.
+	BitLength int    // length in bits.
+}
+
+// At returns the bit at the given index. If the index is out of range it
+// returns false.
+func (b BitString) At(i int) int {
+	if i < 0 || i >= b.BitLength {
+		return 0
+	}
+	x := i / 8
+	y := 7 - uint(i%8)
+	return int(b.Bytes[x]>>y) & 1
+}
+
+// RightAlign returns a slice where the padding bits are at the beginning. The
+// slice may share memory with the BitString.
+func (b BitString) RightAlign() []byte {
+	shift := uint(8 - (b.BitLength % 8))
+	if shift == 8 || len(b.Bytes) == 0 {
+		return b.Bytes
+	}
+
+	a := make([]byte, len(b.Bytes))
+	a[0] = b.Bytes[0] >> shift
+	for i := 1; i < len(b.Bytes); i++ {
+		a[i] = b.Bytes[i-1] << (8 - shift)
+		a[i] |= b.Bytes[i] >> shift
+	}
+
+	return a
+}
+
+// parseBitString parses an ASN.1 bit string from the given byte slice and returns it.
+func parseBitString(bytes []byte) (ret BitString, err error) {
+	if len(bytes) == 0 {
+		err = SyntaxError{"zero length BIT STRING"}
+		return
+	}
+	paddingBits := int(bytes[0])
+	if paddingBits > 7 ||
+		len(bytes) == 1 && paddingBits > 0 ||
+		bytes[len(bytes)-1]&((1<<bytes[0])-1) != 0 {
+		err = SyntaxError{"invalid padding bits in BIT STRING"}
+		return
+	}
+	ret.BitLength = (len(bytes)-1)*8 - paddingBits
+	ret.Bytes = bytes[1:]
+	return
+}
+
+// OBJECT IDENTIFIER
+
+// An ObjectIdentifier represents an ASN.1 OBJECT IDENTIFIER.
+type ObjectIdentifier []int
+
+// Equal reports whether oi and other represent the same identifier.
+func (oi ObjectIdentifier) Equal(other ObjectIdentifier) bool {
+	if len(oi) != len(other) {
+		return false
+	}
+	for i := 0; i < len(oi); i++ {
+		if oi[i] != other[i] {
+			return false
+		}
+	}
+
+	return true
+}
+
+func (oi ObjectIdentifier) String() string {
+	var s string
+
+	for i, v := range oi {
+		if i > 0 {
+			s += "."
+		}
+		s += strconv.Itoa(v)
+	}
+
+	return s
+}
+
+// parseObjectIdentifier parses an OBJECT IDENTIFIER from the given bytes and
+// returns it. An object identifier is a sequence of variable length integers
+// that are assigned in a hierarchy.
+func parseObjectIdentifier(bytes []byte) (s []int, err error) {
+	if len(bytes) == 0 {
+		err = SyntaxError{"zero length OBJECT IDENTIFIER"}
+		return
+	}
+
+	// In the worst case, we get two elements from the first byte (which is
+	// encoded differently) and then every varint is a single byte long.
+	s = make([]int, len(bytes)+1)
+
+	// The first varint is 40*value1 + value2:
+	// According to this packing, value1 can take the values 0, 1 and 2 only.
+	// When value1 = 0 or value1 = 1, then value2 is <= 39. When value1 = 2,
+	// then there are no restrictions on value2.
+	v, offset, err := parseBase128Int(bytes, 0)
+	if err != nil {
+		return
+	}
+	if v < 80 {
+		s[0] = v / 40
+		s[1] = v % 40
+	} else {
+		s[0] = 2
+		s[1] = v - 80
+	}
+
+	i := 2
+	for ; offset < len(bytes); i++ {
+		v, offset, err = parseBase128Int(bytes, offset)
+		if err != nil {
+			return
+		}
+		s[i] = v
+	}
+	s = s[0:i]
+	return
+}
+
+// ENUMERATED
+
+// An Enumerated is represented as a plain int.
+type Enumerated int
+
+// FLAG
+
+// A Flag accepts any data and is set to true if present.
+type Flag bool
+
+// parseBase128Int parses a base-128 encoded int from the given offset in the
+// given byte slice. It returns the value and the new offset.
+func parseBase128Int(bytes []byte, initOffset int) (ret, offset int, err error) {
+	offset = initOffset
+	for shifted := 0; offset < len(bytes); shifted++ {
+		if shifted > 4 {
+			err = StructuralError{"base 128 integer too large"}
+			return
+		}
+		ret <<= 7
+		b := bytes[offset]
+		ret |= int(b & 0x7f)
+		offset++
+		if b&0x80 == 0 {
+			return
+		}
+	}
+	err = SyntaxError{"truncated base 128 integer"}
+	return
+}
+
+// UTCTime
+
+func parseUTCTime(bytes []byte) (ret time.Time, err error) {
+	s := string(bytes)
+	ret, err = time.Parse("0601021504Z0700", s)
+	if err != nil {
+		ret, err = time.Parse("060102150405Z0700", s)
+	}
+	if err == nil && ret.Year() >= 2050 {
+		// UTCTime only encodes times prior to 2050. See https://tools.ietf.org/html/rfc5280#section-4.1.2.5.1
+		ret = ret.AddDate(-100, 0, 0)
+	}
+
+	return
+}
+
+// parseGeneralizedTime parses the GeneralizedTime from the given byte slice
+// and returns the resulting time.
+func parseGeneralizedTime(bytes []byte) (ret time.Time, err error) {
+	return time.Parse("20060102150405Z0700", string(bytes))
+}
+
+// PrintableString
+
+// parsePrintableString parses a ASN.1 PrintableString from the given byte
+// array and returns it.
+func parsePrintableString(bytes []byte) (ret string, err error) {
+	for _, b := range bytes {
+		if !isPrintable(b) {
+			err = SyntaxError{"PrintableString contains invalid character"}
+			return
+		}
+	}
+	ret = string(bytes)
+	return
+}
+
+// isPrintable returns true iff the given b is in the ASN.1 PrintableString set.
+func isPrintable(b byte) bool {
+	return 'a' <= b && b <= 'z' ||
+		'A' <= b && b <= 'Z' ||
+		'0' <= b && b <= '9' ||
+		'\'' <= b && b <= ')' ||
+		'+' <= b && b <= '/' ||
+		b == ' ' ||
+		b == ':' ||
+		b == '=' ||
+		b == '?' ||
+		// This is technically not allowed in a PrintableString.
+		// However, x509 certificates with wildcard strings don't
+		// always use the correct string type so we permit it.
+		b == '*'
+}
+
+// IA5String
+
+// parseIA5String parses a ASN.1 IA5String (ASCII string) from the given
+// byte slice and returns it.
+func parseIA5String(bytes []byte) (ret string, err error) {
+	for _, b := range bytes {
+		if b >= 0x80 {
+			err = SyntaxError{"IA5String contains invalid character"}
+			return
+		}
+	}
+	ret = string(bytes)
+	return
+}
+
+// T61String
+
+// parseT61String parses a ASN.1 T61String (8-bit clean string) from the given
+// byte slice and returns it.
+func parseT61String(bytes []byte) (ret string, err error) {
+	return string(bytes), nil
+}
+
+// UTF8String
+
+// parseUTF8String parses a ASN.1 UTF8String (raw UTF-8) from the given byte
+// array and returns it.
+func parseUTF8String(bytes []byte) (ret string, err error) {
+	return string(bytes), nil
+}
+
+// A RawValue represents an undecoded ASN.1 object.
+type RawValue struct {
+	Class, Tag int
+	IsCompound bool
+	Bytes      []byte
+	FullBytes  []byte // includes the tag and length
+}
+
+// RawContent is used to signal that the undecoded, DER data needs to be
+// preserved for a struct. To use it, the first field of the struct must have
+// this type. It's an error for any of the other fields to have this type.
+type RawContent []byte
+
+// Tagging
+
+// parseTagAndLength parses an ASN.1 tag and length pair from the given offset
+// into a byte slice. It returns the parsed data and the new offset. SET and
+// SET OF (tag 17) are mapped to SEQUENCE and SEQUENCE OF (tag 16) since we
+// don't distinguish between ordered and unordered objects in this code.
+func parseTagAndLength(bytes []byte, initOffset int) (ret tagAndLength, offset int, err error) {
+	offset = initOffset
+	b := bytes[offset]
+	offset++
+	ret.class = int(b >> 6)
+	ret.isCompound = b&0x20 == 0x20
+	ret.tag = int(b & 0x1f)
+
+	// If the bottom five bits are set, then the tag number is actually base 128
+	// encoded afterwards
+	if ret.tag == 0x1f {
+		ret.tag, offset, err = parseBase128Int(bytes, offset)
+		if err != nil {
+			return
+		}
+	}
+	if offset >= len(bytes) {
+		err = SyntaxError{"truncated tag or length"}
+		return
+	}
+	b = bytes[offset]
+	offset++
+	if b&0x80 == 0 {
+		// The length is encoded in the bottom 7 bits.
+		ret.length = int(b & 0x7f)
+	} else {
+		// Bottom 7 bits give the number of length bytes to follow.
+		numBytes := int(b & 0x7f)
+		if numBytes == 0 {
+			err = SyntaxError{"indefinite length found (not DER)"}
+			return
+		}
+		ret.length = 0
+		for i := 0; i < numBytes; i++ {
+			if offset >= len(bytes) {
+				err = SyntaxError{"truncated tag or length"}
+				return
+			}
+			b = bytes[offset]
+			offset++
+			if ret.length >= 1<<23 {
+				// We can't shift ret.length up without
+				// overflowing.
+				err = StructuralError{"length too large"}
+				return
+			}
+			ret.length <<= 8
+			ret.length |= int(b)
+			if ret.length == 0 {
+				// DER requires that lengths be minimal.
+				err = StructuralError{"superfluous leading zeros in length"}
+				return
+			}
+		}
+	}
+
+	return
+}
+
+// parseSequenceOf is used for SEQUENCE OF and SET OF values. It tries to parse
+// a number of ASN.1 values from the given byte slice and returns them as a
+// slice of Go values of the given type.
+func parseSequenceOf(bytes []byte, sliceType reflect.Type, elemType reflect.Type) (ret reflect.Value, err error) {
+	expectedTag, compoundType, ok := getUniversalType(elemType)
+	if !ok {
+		err = StructuralError{"unknown Go type for slice"}
+		return
+	}
+
+	// First we iterate over the input and count the number of elements,
+	// checking that the types are correct in each case.
+	numElements := 0
+	for offset := 0; offset < len(bytes); {
+		var t tagAndLength
+		t, offset, err = parseTagAndLength(bytes, offset)
+		if err != nil {
+			return
+		}
+		switch t.tag {
+		case tagIA5String, tagGeneralString, tagT61String, tagUTF8String:
+			// We pretend that various other string types are
+			// PRINTABLE STRINGs so that a sequence of them can be
+			// parsed into a []string.
+			t.tag = tagPrintableString
+		case tagGeneralizedTime, tagUTCTime:
+			// Likewise, both time types are treated the same.
+			t.tag = tagUTCTime
+		}
+
+		if t.class != classUniversal || t.isCompound != compoundType || t.tag != expectedTag {
+			err = StructuralError{"sequence tag mismatch"}
+			return
+		}
+		if invalidLength(offset, t.length, len(bytes)) {
+			err = SyntaxError{"truncated sequence"}
+			return
+		}
+		offset += t.length
+		numElements++
+	}
+	ret = reflect.MakeSlice(sliceType, numElements, numElements)
+	params := fieldParameters{}
+	offset := 0
+	for i := 0; i < numElements; i++ {
+		offset, err = parseField(ret.Index(i), bytes, offset, params)
+		if err != nil {
+			return
+		}
+	}
+	return
+}
+
+var (
+	bitStringType        = reflect.TypeOf(BitString{})
+	objectIdentifierType = reflect.TypeOf(ObjectIdentifier{})
+	enumeratedType       = reflect.TypeOf(Enumerated(0))
+	flagType             = reflect.TypeOf(Flag(false))
+	timeType             = reflect.TypeOf(time.Time{})
+	rawValueType         = reflect.TypeOf(RawValue{})
+	rawContentsType      = reflect.TypeOf(RawContent(nil))
+	bigIntType           = reflect.TypeOf(new(big.Int))
+)
+
+// invalidLength returns true iff offset + length > sliceLength, or if the
+// addition would overflow.
+func invalidLength(offset, length, sliceLength int) bool {
+	return offset+length < offset || offset+length > sliceLength
+}
+
+// parseField is the main parsing function. Given a byte slice and an offset
+// into the array, it will try to parse a suitable ASN.1 value out and store it
+// in the given Value.
+func parseField(v reflect.Value, bytes []byte, initOffset int, params fieldParameters) (offset int, err error) {
+	offset = initOffset
+	fieldType := v.Type()
+
+	// If we have run out of data, it may be that there are optional elements at the end.
+	if offset == len(bytes) {
+		if !setDefaultValue(v, params) {
+			err = SyntaxError{"sequence truncated"}
+		}
+		return
+	}
+
+	// Deal with raw values.
+	if fieldType == rawValueType {
+		var t tagAndLength
+		t, offset, err = parseTagAndLength(bytes, offset)
+		if err != nil {
+			return
+		}
+		if invalidLength(offset, t.length, len(bytes)) {
+			err = SyntaxError{"data truncated"}
+			return
+		}
+		result := RawValue{t.class, t.tag, t.isCompound, bytes[offset : offset+t.length], bytes[initOffset : offset+t.length]}
+		offset += t.length
+		v.Set(reflect.ValueOf(result))
+		return
+	}
+
+	// Deal with the ANY type.
+	if ifaceType := fieldType; ifaceType.Kind() == reflect.Interface && ifaceType.NumMethod() == 0 {
+		var t tagAndLength
+		t, offset, err = parseTagAndLength(bytes, offset)
+		if err != nil {
+			return
+		}
+		if invalidLength(offset, t.length, len(bytes)) {
+			err = SyntaxError{"data truncated"}
+			return
+		}
+		var result interface{}
+		if !t.isCompound && t.class == classUniversal {
+			innerBytes := bytes[offset : offset+t.length]
+			switch t.tag {
+			case tagPrintableString:
+				result, err = parsePrintableString(innerBytes)
+			case tagIA5String:
+				result, err = parseIA5String(innerBytes)
+			case tagT61String:
+				result, err = parseT61String(innerBytes)
+			case tagUTF8String:
+				result, err = parseUTF8String(innerBytes)
+			case tagInteger:
+				result, err = parseInt64(innerBytes)
+			case tagBitString:
+				result, err = parseBitString(innerBytes)
+			case tagOID:
+				result, err = parseObjectIdentifier(innerBytes)
+			case tagUTCTime:
+				result, err = parseUTCTime(innerBytes)
+			case tagOctetString:
+				result = innerBytes
+			default:
+				// If we don't know how to handle the type, we just leave Value as nil.
+			}
+		}
+		offset += t.length
+		if err != nil {
+			return
+		}
+		if result != nil {
+			v.Set(reflect.ValueOf(result))
+		}
+		return
+	}
+	universalTag, compoundType, ok1 := getUniversalType(fieldType)
+	if !ok1 {
+		err = StructuralError{fmt.Sprintf("unknown Go type: %v", fieldType)}
+		return
+	}
+
+	t, offset, err := parseTagAndLength(bytes, offset)
+	if err != nil {
+		return
+	}
+	if params.explicit {
+		expectedClass := classContextSpecific
+		if params.application {
+			expectedClass = classApplication
+		}
+		if t.class == expectedClass && t.tag == *params.tag && (t.length == 0 || t.isCompound) {
+			if t.length > 0 {
+				t, offset, err = parseTagAndLength(bytes, offset)
+				if err != nil {
+					return
+				}
+			} else {
+				if fieldType != flagType {
+					err = StructuralError{"zero length explicit tag was not an asn1.Flag"}
+					return
+				}
+				v.SetBool(true)
+				return
+			}
+		} else {
+			// The tags didn't match, it might be an optional element.
+			ok := setDefaultValue(v, params)
+			if ok {
+				offset = initOffset
+			} else {
+				err = StructuralError{"explicitly tagged member didn't match"}
+			}
+			return
+		}
+	}
+
+	// Special case for strings: all the ASN.1 string types map to the Go
+	// type string. getUniversalType returns the tag for PrintableString
+	// when it sees a string, so if we see a different string type on the
+	// wire, we change the universal type to match.
+	if universalTag == tagPrintableString {
+		if t.class == classUniversal {
+			switch t.tag {
+			case tagIA5String, tagGeneralString, tagT61String, tagUTF8String:
+				universalTag = t.tag
+			}
+		} else if params.stringType != 0 {
+			universalTag = params.stringType
+		}
+	}
+
+	// Special case for time: UTCTime and GeneralizedTime both map to the
+	// Go type time.Time.
+	if universalTag == tagUTCTime && t.tag == tagGeneralizedTime && t.class == classUniversal {
+		universalTag = tagGeneralizedTime
+	}
+
+	if params.set {
+		universalTag = tagSet
+	}
+
+	expectedClass := classUniversal
+	expectedTag := universalTag
+
+	if !params.explicit && params.tag != nil {
+		expectedClass = classContextSpecific
+		expectedTag = *params.tag
+	}
+
+	if !params.explicit && params.application && params.tag != nil {
+		expectedClass = classApplication
+		expectedTag = *params.tag
+	}
+
+	// We have unwrapped any explicit tagging at this point.
+	if t.class != expectedClass || t.tag != expectedTag || t.isCompound != compoundType {
+		// Tags don't match. Again, it could be an optional element.
+		ok := setDefaultValue(v, params)
+		if ok {
+			offset = initOffset
+		} else {
+			err = StructuralError{fmt.Sprintf("tags don't match (%d vs %+v) %+v %s @%d", expectedTag, t, params, fieldType.Name(), offset)}
+		}
+		return
+	}
+	if invalidLength(offset, t.length, len(bytes)) {
+		err = SyntaxError{"data truncated"}
+		return
+	}
+	innerBytes := bytes[offset : offset+t.length]
+	offset += t.length
+
+	// We deal with the structures defined in this package first.
+	switch fieldType {
+	case objectIdentifierType:
+		newSlice, err1 := parseObjectIdentifier(innerBytes)
+		v.Set(reflect.MakeSlice(v.Type(), len(newSlice), len(newSlice)))
+		if err1 == nil {
+			reflect.Copy(v, reflect.ValueOf(newSlice))
+		}
+		err = err1
+		return
+	case bitStringType:
+		bs, err1 := parseBitString(innerBytes)
+		if err1 == nil {
+			v.Set(reflect.ValueOf(bs))
+		}
+		err = err1
+		return
+	case timeType:
+		var time time.Time
+		var err1 error
+		if universalTag == tagUTCTime {
+			time, err1 = parseUTCTime(innerBytes)
+		} else {
+			time, err1 = parseGeneralizedTime(innerBytes)
+		}
+		if err1 == nil {
+			v.Set(reflect.ValueOf(time))
+		}
+		err = err1
+		return
+	case enumeratedType:
+		parsedInt, err1 := parseInt32(innerBytes)
+		if err1 == nil {
+			v.SetInt(int64(parsedInt))
+		}
+		err = err1
+		return
+	case flagType:
+		v.SetBool(true)
+		return
+	case bigIntType:
+		parsedInt := parseBigInt(innerBytes)
+		v.Set(reflect.ValueOf(parsedInt))
+		return
+	}
+	switch val := v; val.Kind() {
+	case reflect.Bool:
+		parsedBool, err1 := parseBool(innerBytes)
+		if err1 == nil {
+			val.SetBool(parsedBool)
+		}
+		err = err1
+		return
+	case reflect.Int, reflect.Int32, reflect.Int64:
+		if val.Type().Size() == 4 {
+			parsedInt, err1 := parseInt32(innerBytes)
+			if err1 == nil {
+				val.SetInt(int64(parsedInt))
+			}
+			err = err1
+		} else {
+			parsedInt, err1 := parseInt64(innerBytes)
+			if err1 == nil {
+				val.SetInt(parsedInt)
+			}
+			err = err1
+		}
+		return
+	// TODO(dfc) Add support for the remaining integer types
+	case reflect.Struct:
+		structType := fieldType
+
+		if structType.NumField() > 0 &&
+			structType.Field(0).Type == rawContentsType {
+			bytes := bytes[initOffset:offset]
+			val.Field(0).Set(reflect.ValueOf(RawContent(bytes)))
+		}
+
+		innerOffset := 0
+		for i := 0; i < structType.NumField(); i++ {
+			field := structType.Field(i)
+			if i == 0 && field.Type == rawContentsType {
+				continue
+			}
+			innerOffset, err = parseField(val.Field(i), innerBytes, innerOffset, parseFieldParameters(field.Tag.Get("asn1")))
+			if err != nil {
+				return
+			}
+		}
+		// We allow extra bytes at the end of the SEQUENCE because
+		// adding elements to the end has been used in X.509 as the
+		// version numbers have increased.
+		return
+	case reflect.Slice:
+		sliceType := fieldType
+		if sliceType.Elem().Kind() == reflect.Uint8 {
+			val.Set(reflect.MakeSlice(sliceType, len(innerBytes), len(innerBytes)))
+			reflect.Copy(val, reflect.ValueOf(innerBytes))
+			return
+		}
+		newSlice, err1 := parseSequenceOf(innerBytes, sliceType, sliceType.Elem())
+		if err1 == nil {
+			val.Set(newSlice)
+		}
+		err = err1
+		return
+	case reflect.String:
+		var v string
+		switch universalTag {
+		case tagPrintableString:
+			v, err = parsePrintableString(innerBytes)
+		case tagIA5String:
+			v, err = parseIA5String(innerBytes)
+		case tagT61String:
+			v, err = parseT61String(innerBytes)
+		case tagUTF8String:
+			v, err = parseUTF8String(innerBytes)
+		case tagGeneralString:
+			// GeneralString is specified in ISO-2022/ECMA-35,
+			// A brief review suggests that it includes structures
+			// that allow the encoding to change midstring and
+			// such. We give up and pass it as an 8-bit string.
+			v, err = parseT61String(innerBytes)
+		default:
+			err = SyntaxError{fmt.Sprintf("internal error: unknown string type %d", universalTag)}
+		}
+		if err == nil {
+			val.SetString(v)
+		}
+		return
+	}
+	err = StructuralError{"unsupported: " + v.Type().String()}
+	return
+}
+
+// canHaveDefaultValue reports whether k is a Kind that we will set a default
+// value for. (A signed integer, essentially.)
+func canHaveDefaultValue(k reflect.Kind) bool {
+	switch k {
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		return true
+	}
+
+	return false
+}
+
+// setDefaultValue is used to install a default value, from a tag string, into
+// a Value. It is successful if the field was optional, even if a default value
+// wasn't provided or it failed to install it into the Value.
+func setDefaultValue(v reflect.Value, params fieldParameters) (ok bool) {
+	if !params.optional {
+		return
+	}
+	ok = true
+	if params.defaultValue == nil {
+		return
+	}
+	if canHaveDefaultValue(v.Kind()) {
+		v.SetInt(*params.defaultValue)
+	}
+	return
+}
+
+// Unmarshal parses the DER-encoded ASN.1 data structure b
+// and uses the reflect package to fill in an arbitrary value pointed at by val.
+// Because Unmarshal uses the reflect package, the structs
+// being written to must use upper case field names.
+//
+// An ASN.1 INTEGER can be written to an int, int32, int64,
+// or *big.Int (from the math/big package).
+// If the encoded value does not fit in the Go type,
+// Unmarshal returns a parse error.
+//
+// An ASN.1 BIT STRING can be written to a BitString.
+//
+// An ASN.1 OCTET STRING can be written to a []byte.
+//
+// An ASN.1 OBJECT IDENTIFIER can be written to an
+// ObjectIdentifier.
+//
+// An ASN.1 ENUMERATED can be written to an Enumerated.
+//
+// An ASN.1 UTCTIME or GENERALIZEDTIME can be written to a time.Time.
+//
+// An ASN.1 PrintableString or IA5String can be written to a string.
+//
+// Any of the above ASN.1 values can be written to an interface{}.
+// The value stored in the interface has the corresponding Go type.
+// For integers, that type is int64.
+//
+// An ASN.1 SEQUENCE OF x or SET OF x can be written
+// to a slice if an x can be written to the slice's element type.
+//
+// An ASN.1 SEQUENCE or SET can be written to a struct
+// if each of the elements in the sequence can be
+// written to the corresponding element in the struct.
+//
+// The following tags on struct fields have special meaning to Unmarshal:
+//
+//	application	specifies that a APPLICATION tag is used
+//	default:x	sets the default value for optional integer fields
+//	explicit	specifies that an additional, explicit tag wraps the implicit one
+//	optional	marks the field as ASN.1 OPTIONAL
+//	set		causes a SET, rather than a SEQUENCE type to be expected
+//	tag:x		specifies the ASN.1 tag number; implies ASN.1 CONTEXT SPECIFIC
+//
+// If the type of the first field of a structure is RawContent then the raw
+// ASN1 contents of the struct will be stored in it.
+//
+// If the type name of a slice element ends with "SET" then it's treated as if
+// the "set" tag was set on it. This can be used with nested slices where a
+// struct tag cannot be given.
+//
+// Other ASN.1 types are not supported; if it encounters them,
+// Unmarshal returns a parse error.
+func Unmarshal(b []byte, val interface{}) (rest []byte, err error) {
+	return UnmarshalWithParams(b, val, "")
+}
+
+// UnmarshalWithParams allows field parameters to be specified for the
+// top-level element. The form of the params is the same as the field tags.
+func UnmarshalWithParams(b []byte, val interface{}, params string) (rest []byte, err error) {
+	v := reflect.ValueOf(val).Elem()
+	offset, err := parseField(v, b, 0, parseFieldParameters(params))
+	if err != nil {
+		return nil, err
+	}
+	return b[offset:], nil
+}
diff --git a/src/encoding/asn1/asn1_test.go b/src/encoding/asn1/asn1_test.go
new file mode 100644
index 0000000..4e864d0
--- /dev/null
+++ b/src/encoding/asn1/asn1_test.go
@@ -0,0 +1,867 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package asn1
+
+import (
+	"bytes"
+	"fmt"
+	"math/big"
+	"reflect"
+	"testing"
+	"time"
+)
+
+type boolTest struct {
+	in  []byte
+	ok  bool
+	out bool
+}
+
+var boolTestData = []boolTest{
+	{[]byte{0x00}, true, false},
+	{[]byte{0xff}, true, true},
+	{[]byte{0x00, 0x00}, false, false},
+	{[]byte{0xff, 0xff}, false, false},
+	{[]byte{0x01}, false, false},
+}
+
+func TestParseBool(t *testing.T) {
+	for i, test := range boolTestData {
+		ret, err := parseBool(test.in)
+		if (err == nil) != test.ok {
+			t.Errorf("#%d: Incorrect error result (did fail? %v, expected: %v)", i, err == nil, test.ok)
+		}
+		if test.ok && ret != test.out {
+			t.Errorf("#%d: Bad result: %v (expected %v)", i, ret, test.out)
+		}
+	}
+}
+
+type int64Test struct {
+	in  []byte
+	ok  bool
+	out int64
+}
+
+var int64TestData = []int64Test{
+	{[]byte{0x00}, true, 0},
+	{[]byte{0x7f}, true, 127},
+	{[]byte{0x00, 0x80}, true, 128},
+	{[]byte{0x01, 0x00}, true, 256},
+	{[]byte{0x80}, true, -128},
+	{[]byte{0xff, 0x7f}, true, -129},
+	{[]byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, true, -1},
+	{[]byte{0xff}, true, -1},
+	{[]byte{0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, true, -9223372036854775808},
+	{[]byte{0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, false, 0},
+}
+
+func TestParseInt64(t *testing.T) {
+	for i, test := range int64TestData {
+		ret, err := parseInt64(test.in)
+		if (err == nil) != test.ok {
+			t.Errorf("#%d: Incorrect error result (did fail? %v, expected: %v)", i, err == nil, test.ok)
+		}
+		if test.ok && ret != test.out {
+			t.Errorf("#%d: Bad result: %v (expected %v)", i, ret, test.out)
+		}
+	}
+}
+
+type int32Test struct {
+	in  []byte
+	ok  bool
+	out int32
+}
+
+var int32TestData = []int32Test{
+	{[]byte{0x00}, true, 0},
+	{[]byte{0x7f}, true, 127},
+	{[]byte{0x00, 0x80}, true, 128},
+	{[]byte{0x01, 0x00}, true, 256},
+	{[]byte{0x80}, true, -128},
+	{[]byte{0xff, 0x7f}, true, -129},
+	{[]byte{0xff, 0xff, 0xff, 0xff}, true, -1},
+	{[]byte{0xff}, true, -1},
+	{[]byte{0x80, 0x00, 0x00, 0x00}, true, -2147483648},
+	{[]byte{0x80, 0x00, 0x00, 0x00, 0x00}, false, 0},
+}
+
+func TestParseInt32(t *testing.T) {
+	for i, test := range int32TestData {
+		ret, err := parseInt32(test.in)
+		if (err == nil) != test.ok {
+			t.Errorf("#%d: Incorrect error result (did fail? %v, expected: %v)", i, err == nil, test.ok)
+		}
+		if test.ok && int32(ret) != test.out {
+			t.Errorf("#%d: Bad result: %v (expected %v)", i, ret, test.out)
+		}
+	}
+}
+
+var bigIntTests = []struct {
+	in     []byte
+	base10 string
+}{
+	{[]byte{0xff}, "-1"},
+	{[]byte{0x00}, "0"},
+	{[]byte{0x01}, "1"},
+	{[]byte{0x00, 0xff}, "255"},
+	{[]byte{0xff, 0x00}, "-256"},
+	{[]byte{0x01, 0x00}, "256"},
+}
+
+func TestParseBigInt(t *testing.T) {
+	for i, test := range bigIntTests {
+		ret := parseBigInt(test.in)
+		if ret.String() != test.base10 {
+			t.Errorf("#%d: bad result from %x, got %s want %s", i, test.in, ret.String(), test.base10)
+		}
+		fw := newForkableWriter()
+		marshalBigInt(fw, ret)
+		result := fw.Bytes()
+		if !bytes.Equal(result, test.in) {
+			t.Errorf("#%d: got %x from marshaling %s, want %x", i, result, ret, test.in)
+		}
+	}
+}
+
+type bitStringTest struct {
+	in        []byte
+	ok        bool
+	out       []byte
+	bitLength int
+}
+
+var bitStringTestData = []bitStringTest{
+	{[]byte{}, false, []byte{}, 0},
+	{[]byte{0x00}, true, []byte{}, 0},
+	{[]byte{0x07, 0x00}, true, []byte{0x00}, 1},
+	{[]byte{0x07, 0x01}, false, []byte{}, 0},
+	{[]byte{0x07, 0x40}, false, []byte{}, 0},
+	{[]byte{0x08, 0x00}, false, []byte{}, 0},
+}
+
+func TestBitString(t *testing.T) {
+	for i, test := range bitStringTestData {
+		ret, err := parseBitString(test.in)
+		if (err == nil) != test.ok {
+			t.Errorf("#%d: Incorrect error result (did fail? %v, expected: %v)", i, err == nil, test.ok)
+		}
+		if err == nil {
+			if test.bitLength != ret.BitLength || !bytes.Equal(ret.Bytes, test.out) {
+				t.Errorf("#%d: Bad result: %v (expected %v %v)", i, ret, test.out, test.bitLength)
+			}
+		}
+	}
+}
+
+func TestBitStringAt(t *testing.T) {
+	bs := BitString{[]byte{0x82, 0x40}, 16}
+	if bs.At(0) != 1 {
+		t.Error("#1: Failed")
+	}
+	if bs.At(1) != 0 {
+		t.Error("#2: Failed")
+	}
+	if bs.At(6) != 1 {
+		t.Error("#3: Failed")
+	}
+	if bs.At(9) != 1 {
+		t.Error("#4: Failed")
+	}
+	if bs.At(-1) != 0 {
+		t.Error("#5: Failed")
+	}
+	if bs.At(17) != 0 {
+		t.Error("#6: Failed")
+	}
+}
+
+type bitStringRightAlignTest struct {
+	in    []byte
+	inlen int
+	out   []byte
+}
+
+var bitStringRightAlignTests = []bitStringRightAlignTest{
+	{[]byte{0x80}, 1, []byte{0x01}},
+	{[]byte{0x80, 0x80}, 9, []byte{0x01, 0x01}},
+	{[]byte{}, 0, []byte{}},
+	{[]byte{0xce}, 8, []byte{0xce}},
+	{[]byte{0xce, 0x47}, 16, []byte{0xce, 0x47}},
+	{[]byte{0x34, 0x50}, 12, []byte{0x03, 0x45}},
+}
+
+func TestBitStringRightAlign(t *testing.T) {
+	for i, test := range bitStringRightAlignTests {
+		bs := BitString{test.in, test.inlen}
+		out := bs.RightAlign()
+		if !bytes.Equal(out, test.out) {
+			t.Errorf("#%d got: %x want: %x", i, out, test.out)
+		}
+	}
+}
+
+type objectIdentifierTest struct {
+	in  []byte
+	ok  bool
+	out []int
+}
+
+var objectIdentifierTestData = []objectIdentifierTest{
+	{[]byte{}, false, []int{}},
+	{[]byte{85}, true, []int{2, 5}},
+	{[]byte{85, 0x02}, true, []int{2, 5, 2}},
+	{[]byte{85, 0x02, 0xc0, 0x00}, true, []int{2, 5, 2, 0x2000}},
+	{[]byte{0x81, 0x34, 0x03}, true, []int{2, 100, 3}},
+	{[]byte{85, 0x02, 0xc0, 0x80, 0x80, 0x80, 0x80}, false, []int{}},
+}
+
+func TestObjectIdentifier(t *testing.T) {
+	for i, test := range objectIdentifierTestData {
+		ret, err := parseObjectIdentifier(test.in)
+		if (err == nil) != test.ok {
+			t.Errorf("#%d: Incorrect error result (did fail? %v, expected: %v)", i, err == nil, test.ok)
+		}
+		if err == nil {
+			if !reflect.DeepEqual(test.out, ret) {
+				t.Errorf("#%d: Bad result: %v (expected %v)", i, ret, test.out)
+			}
+		}
+	}
+
+	if s := ObjectIdentifier([]int{1, 2, 3, 4}).String(); s != "1.2.3.4" {
+		t.Errorf("bad ObjectIdentifier.String(). Got %s, want 1.2.3.4", s)
+	}
+}
+
+type timeTest struct {
+	in  string
+	ok  bool
+	out time.Time
+}
+
+var utcTestData = []timeTest{
+	{"910506164540-0700", true, time.Date(1991, 05, 06, 16, 45, 40, 0, time.FixedZone("", -7*60*60))},
+	{"910506164540+0730", true, time.Date(1991, 05, 06, 16, 45, 40, 0, time.FixedZone("", 7*60*60+30*60))},
+	{"910506234540Z", true, time.Date(1991, 05, 06, 23, 45, 40, 0, time.UTC)},
+	{"9105062345Z", true, time.Date(1991, 05, 06, 23, 45, 0, 0, time.UTC)},
+	{"5105062345Z", true, time.Date(1951, 05, 06, 23, 45, 0, 0, time.UTC)},
+	{"a10506234540Z", false, time.Time{}},
+	{"91a506234540Z", false, time.Time{}},
+	{"9105a6234540Z", false, time.Time{}},
+	{"910506a34540Z", false, time.Time{}},
+	{"910506334a40Z", false, time.Time{}},
+	{"91050633444aZ", false, time.Time{}},
+	{"910506334461Z", false, time.Time{}},
+	{"910506334400Za", false, time.Time{}},
+}
+
+func TestUTCTime(t *testing.T) {
+	for i, test := range utcTestData {
+		ret, err := parseUTCTime([]byte(test.in))
+		if err != nil {
+			if test.ok {
+				t.Errorf("#%d: parseUTCTime(%q) = error %v", i, test.in, err)
+			}
+			continue
+		}
+		if !test.ok {
+			t.Errorf("#%d: parseUTCTime(%q) succeeded, should have failed", i, test.in)
+			continue
+		}
+		const format = "Jan _2 15:04:05 -0700 2006" // ignore zone name, just offset
+		have := ret.Format(format)
+		want := test.out.Format(format)
+		if have != want {
+			t.Errorf("#%d: parseUTCTime(%q) = %s, want %s", i, test.in, have, want)
+		}
+	}
+}
+
+var generalizedTimeTestData = []timeTest{
+	{"20100102030405Z", true, time.Date(2010, 01, 02, 03, 04, 05, 0, time.UTC)},
+	{"20100102030405", false, time.Time{}},
+	{"20100102030405+0607", true, time.Date(2010, 01, 02, 03, 04, 05, 0, time.FixedZone("", 6*60*60+7*60))},
+	{"20100102030405-0607", true, time.Date(2010, 01, 02, 03, 04, 05, 0, time.FixedZone("", -6*60*60-7*60))},
+}
+
+func TestGeneralizedTime(t *testing.T) {
+	for i, test := range generalizedTimeTestData {
+		ret, err := parseGeneralizedTime([]byte(test.in))
+		if (err == nil) != test.ok {
+			t.Errorf("#%d: Incorrect error result (did fail? %v, expected: %v)", i, err == nil, test.ok)
+		}
+		if err == nil {
+			if !reflect.DeepEqual(test.out, ret) {
+				t.Errorf("#%d: Bad result: %v (expected %v)", i, ret, test.out)
+			}
+		}
+	}
+}
+
+type tagAndLengthTest struct {
+	in  []byte
+	ok  bool
+	out tagAndLength
+}
+
+var tagAndLengthData = []tagAndLengthTest{
+	{[]byte{0x80, 0x01}, true, tagAndLength{2, 0, 1, false}},
+	{[]byte{0xa0, 0x01}, true, tagAndLength{2, 0, 1, true}},
+	{[]byte{0x02, 0x00}, true, tagAndLength{0, 2, 0, false}},
+	{[]byte{0xfe, 0x00}, true, tagAndLength{3, 30, 0, true}},
+	{[]byte{0x1f, 0x01, 0x00}, true, tagAndLength{0, 1, 0, false}},
+	{[]byte{0x1f, 0x81, 0x00, 0x00}, true, tagAndLength{0, 128, 0, false}},
+	{[]byte{0x1f, 0x81, 0x80, 0x01, 0x00}, true, tagAndLength{0, 0x4001, 0, false}},
+	{[]byte{0x00, 0x81, 0x01}, true, tagAndLength{0, 0, 1, false}},
+	{[]byte{0x00, 0x82, 0x01, 0x00}, true, tagAndLength{0, 0, 256, false}},
+	{[]byte{0x00, 0x83, 0x01, 0x00}, false, tagAndLength{}},
+	{[]byte{0x1f, 0x85}, false, tagAndLength{}},
+	{[]byte{0x30, 0x80}, false, tagAndLength{}},
+	// Superfluous zeros in the length should be an error.
+	{[]byte{0xa0, 0x82, 0x00, 0x01}, false, tagAndLength{}},
+	// Lengths up to the maximum size of an int should work.
+	{[]byte{0xa0, 0x84, 0x7f, 0xff, 0xff, 0xff}, true, tagAndLength{2, 0, 0x7fffffff, true}},
+	// Lengths that would overflow an int should be rejected.
+	{[]byte{0xa0, 0x84, 0x80, 0x00, 0x00, 0x00}, false, tagAndLength{}},
+}
+
+func TestParseTagAndLength(t *testing.T) {
+	for i, test := range tagAndLengthData {
+		tagAndLength, _, err := parseTagAndLength(test.in, 0)
+		if (err == nil) != test.ok {
+			t.Errorf("#%d: Incorrect error result (did pass? %v, expected: %v)", i, err == nil, test.ok)
+		}
+		if err == nil && !reflect.DeepEqual(test.out, tagAndLength) {
+			t.Errorf("#%d: Bad result: %v (expected %v)", i, tagAndLength, test.out)
+		}
+	}
+}
+
+type parseFieldParametersTest struct {
+	in  string
+	out fieldParameters
+}
+
+func newInt(n int) *int { return &n }
+
+func newInt64(n int64) *int64 { return &n }
+
+func newString(s string) *string { return &s }
+
+func newBool(b bool) *bool { return &b }
+
+var parseFieldParametersTestData []parseFieldParametersTest = []parseFieldParametersTest{
+	{"", fieldParameters{}},
+	{"ia5", fieldParameters{stringType: tagIA5String}},
+	{"printable", fieldParameters{stringType: tagPrintableString}},
+	{"optional", fieldParameters{optional: true}},
+	{"explicit", fieldParameters{explicit: true, tag: new(int)}},
+	{"application", fieldParameters{application: true, tag: new(int)}},
+	{"optional,explicit", fieldParameters{optional: true, explicit: true, tag: new(int)}},
+	{"default:42", fieldParameters{defaultValue: newInt64(42)}},
+	{"tag:17", fieldParameters{tag: newInt(17)}},
+	{"optional,explicit,default:42,tag:17", fieldParameters{optional: true, explicit: true, defaultValue: newInt64(42), tag: newInt(17)}},
+	{"optional,explicit,default:42,tag:17,rubbish1", fieldParameters{true, true, false, newInt64(42), newInt(17), 0, false, false}},
+	{"set", fieldParameters{set: true}},
+}
+
+func TestParseFieldParameters(t *testing.T) {
+	for i, test := range parseFieldParametersTestData {
+		f := parseFieldParameters(test.in)
+		if !reflect.DeepEqual(f, test.out) {
+			t.Errorf("#%d: Bad result: %v (expected %v)", i, f, test.out)
+		}
+	}
+}
+
+type TestObjectIdentifierStruct struct {
+	OID ObjectIdentifier
+}
+
+type TestContextSpecificTags struct {
+	A int `asn1:"tag:1"`
+}
+
+type TestContextSpecificTags2 struct {
+	A int `asn1:"explicit,tag:1"`
+	B int
+}
+
+type TestContextSpecificTags3 struct {
+	S string `asn1:"tag:1,utf8"`
+}
+
+type TestElementsAfterString struct {
+	S    string
+	A, B int
+}
+
+type TestBigInt struct {
+	X *big.Int
+}
+
+type TestSet struct {
+	Ints []int `asn1:"set"`
+}
+
+var unmarshalTestData = []struct {
+	in  []byte
+	out interface{}
+}{
+	{[]byte{0x02, 0x01, 0x42}, newInt(0x42)},
+	{[]byte{0x30, 0x08, 0x06, 0x06, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d}, &TestObjectIdentifierStruct{[]int{1, 2, 840, 113549}}},
+	{[]byte{0x03, 0x04, 0x06, 0x6e, 0x5d, 0xc0}, &BitString{[]byte{110, 93, 192}, 18}},
+	{[]byte{0x30, 0x09, 0x02, 0x01, 0x01, 0x02, 0x01, 0x02, 0x02, 0x01, 0x03}, &[]int{1, 2, 3}},
+	{[]byte{0x02, 0x01, 0x10}, newInt(16)},
+	{[]byte{0x13, 0x04, 't', 'e', 's', 't'}, newString("test")},
+	{[]byte{0x16, 0x04, 't', 'e', 's', 't'}, newString("test")},
+	{[]byte{0x16, 0x04, 't', 'e', 's', 't'}, &RawValue{0, 22, false, []byte("test"), []byte("\x16\x04test")}},
+	{[]byte{0x04, 0x04, 1, 2, 3, 4}, &RawValue{0, 4, false, []byte{1, 2, 3, 4}, []byte{4, 4, 1, 2, 3, 4}}},
+	{[]byte{0x30, 0x03, 0x81, 0x01, 0x01}, &TestContextSpecificTags{1}},
+	{[]byte{0x30, 0x08, 0xa1, 0x03, 0x02, 0x01, 0x01, 0x02, 0x01, 0x02}, &TestContextSpecificTags2{1, 2}},
+	{[]byte{0x30, 0x03, 0x81, 0x01, '@'}, &TestContextSpecificTags3{"@"}},
+	{[]byte{0x01, 0x01, 0x00}, newBool(false)},
+	{[]byte{0x01, 0x01, 0xff}, newBool(true)},
+	{[]byte{0x30, 0x0b, 0x13, 0x03, 0x66, 0x6f, 0x6f, 0x02, 0x01, 0x22, 0x02, 0x01, 0x33}, &TestElementsAfterString{"foo", 0x22, 0x33}},
+	{[]byte{0x30, 0x05, 0x02, 0x03, 0x12, 0x34, 0x56}, &TestBigInt{big.NewInt(0x123456)}},
+	{[]byte{0x30, 0x0b, 0x31, 0x09, 0x02, 0x01, 0x01, 0x02, 0x01, 0x02, 0x02, 0x01, 0x03}, &TestSet{Ints: []int{1, 2, 3}}},
+}
+
+func TestUnmarshal(t *testing.T) {
+	for i, test := range unmarshalTestData {
+		pv := reflect.New(reflect.TypeOf(test.out).Elem())
+		val := pv.Interface()
+		_, err := Unmarshal(test.in, val)
+		if err != nil {
+			t.Errorf("Unmarshal failed at index %d %v", i, err)
+		}
+		if !reflect.DeepEqual(val, test.out) {
+			t.Errorf("#%d:\nhave %#v\nwant %#v", i, val, test.out)
+		}
+	}
+}
+
+type Certificate struct {
+	TBSCertificate     TBSCertificate
+	SignatureAlgorithm AlgorithmIdentifier
+	SignatureValue     BitString
+}
+
+type TBSCertificate struct {
+	Version            int `asn1:"optional,explicit,default:0,tag:0"`
+	SerialNumber       RawValue
+	SignatureAlgorithm AlgorithmIdentifier
+	Issuer             RDNSequence
+	Validity           Validity
+	Subject            RDNSequence
+	PublicKey          PublicKeyInfo
+}
+
+type AlgorithmIdentifier struct {
+	Algorithm ObjectIdentifier
+}
+
+type RDNSequence []RelativeDistinguishedNameSET
+
+type RelativeDistinguishedNameSET []AttributeTypeAndValue
+
+type AttributeTypeAndValue struct {
+	Type  ObjectIdentifier
+	Value interface{}
+}
+
+type Validity struct {
+	NotBefore, NotAfter time.Time
+}
+
+type PublicKeyInfo struct {
+	Algorithm AlgorithmIdentifier
+	PublicKey BitString
+}
+
+func TestCertificate(t *testing.T) {
+	// This is a minimal, self-signed certificate that should parse correctly.
+	var cert Certificate
+	if _, err := Unmarshal(derEncodedSelfSignedCertBytes, &cert); err != nil {
+		t.Errorf("Unmarshal failed: %v", err)
+	}
+	if !reflect.DeepEqual(cert, derEncodedSelfSignedCert) {
+		t.Errorf("Bad result:\ngot: %+v\nwant: %+v", cert, derEncodedSelfSignedCert)
+	}
+}
+
+func TestCertificateWithNUL(t *testing.T) {
+	// This is the paypal NUL-hack certificate. It should fail to parse because
+	// NUL isn't a permitted character in a PrintableString.
+
+	var cert Certificate
+	if _, err := Unmarshal(derEncodedPaypalNULCertBytes, &cert); err == nil {
+		t.Error("Unmarshal succeeded, should not have")
+	}
+}
+
+type rawStructTest struct {
+	Raw RawContent
+	A   int
+}
+
+func TestRawStructs(t *testing.T) {
+	var s rawStructTest
+	input := []byte{0x30, 0x03, 0x02, 0x01, 0x50}
+
+	rest, err := Unmarshal(input, &s)
+	if len(rest) != 0 {
+		t.Errorf("incomplete parse: %x", rest)
+		return
+	}
+	if err != nil {
+		t.Error(err)
+		return
+	}
+	if s.A != 0x50 {
+		t.Errorf("bad value for A: got %d want %d", s.A, 0x50)
+	}
+	if !bytes.Equal([]byte(s.Raw), input) {
+		t.Errorf("bad value for Raw: got %x want %x", s.Raw, input)
+	}
+}
+
+type oiEqualTest struct {
+	first  ObjectIdentifier
+	second ObjectIdentifier
+	same   bool
+}
+
+var oiEqualTests = []oiEqualTest{
+	{
+		ObjectIdentifier{1, 2, 3},
+		ObjectIdentifier{1, 2, 3},
+		true,
+	},
+	{
+		ObjectIdentifier{1},
+		ObjectIdentifier{1, 2, 3},
+		false,
+	},
+	{
+		ObjectIdentifier{1, 2, 3},
+		ObjectIdentifier{10, 11, 12},
+		false,
+	},
+}
+
+func TestObjectIdentifierEqual(t *testing.T) {
+	for _, o := range oiEqualTests {
+		if s := o.first.Equal(o.second); s != o.same {
+			t.Errorf("ObjectIdentifier.Equal: got: %t want: %t", s, o.same)
+		}
+	}
+}
+
+var derEncodedSelfSignedCert = Certificate{
+	TBSCertificate: TBSCertificate{
+		Version:            0,
+		SerialNumber:       RawValue{Class: 0, Tag: 2, IsCompound: false, Bytes: []uint8{0x0, 0x8c, 0xc3, 0x37, 0x92, 0x10, 0xec, 0x2c, 0x98}, FullBytes: []byte{2, 9, 0x0, 0x8c, 0xc3, 0x37, 0x92, 0x10, 0xec, 0x2c, 0x98}},
+		SignatureAlgorithm: AlgorithmIdentifier{Algorithm: ObjectIdentifier{1, 2, 840, 113549, 1, 1, 5}},
+		Issuer: RDNSequence{
+			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 6}, Value: "XX"}},
+			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 8}, Value: "Some-State"}},
+			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 7}, Value: "City"}},
+			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 10}, Value: "Internet Widgits Pty Ltd"}},
+			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 3}, Value: "false.example.com"}},
+			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{1, 2, 840, 113549, 1, 9, 1}, Value: "false at example.com"}},
+		},
+		Validity: Validity{
+			NotBefore: time.Date(2009, 10, 8, 00, 25, 53, 0, time.UTC),
+			NotAfter:  time.Date(2010, 10, 8, 00, 25, 53, 0, time.UTC),
+		},
+		Subject: RDNSequence{
+			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 6}, Value: "XX"}},
+			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 8}, Value: "Some-State"}},
+			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 7}, Value: "City"}},
+			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 10}, Value: "Internet Widgits Pty Ltd"}},
+			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 3}, Value: "false.example.com"}},
+			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{1, 2, 840, 113549, 1, 9, 1}, Value: "false at example.com"}},
+		},
+		PublicKey: PublicKeyInfo{
+			Algorithm: AlgorithmIdentifier{Algorithm: ObjectIdentifier{1, 2, 840, 113549, 1, 1, 1}},
+			PublicKey: BitString{
+				Bytes: []uint8{
+					0x30, 0x48, 0x2, 0x41, 0x0, 0xcd, 0xb7,
+					0x63, 0x9c, 0x32, 0x78, 0xf0, 0x6, 0xaa, 0x27, 0x7f, 0x6e, 0xaf, 0x42,
+					0x90, 0x2b, 0x59, 0x2d, 0x8c, 0xbc, 0xbe, 0x38, 0xa1, 0xc9, 0x2b, 0xa4,
+					0x69, 0x5a, 0x33, 0x1b, 0x1d, 0xea, 0xde, 0xad, 0xd8, 0xe9, 0xa5, 0xc2,
+					0x7e, 0x8c, 0x4c, 0x2f, 0xd0, 0xa8, 0x88, 0x96, 0x57, 0x72, 0x2a, 0x4f,
+					0x2a, 0xf7, 0x58, 0x9c, 0xf2, 0xc7, 0x70, 0x45, 0xdc, 0x8f, 0xde, 0xec,
+					0x35, 0x7d, 0x2, 0x3, 0x1, 0x0, 0x1,
+				},
+				BitLength: 592,
+			},
+		},
+	},
+	SignatureAlgorithm: AlgorithmIdentifier{Algorithm: ObjectIdentifier{1, 2, 840, 113549, 1, 1, 5}},
+	SignatureValue: BitString{
+		Bytes: []uint8{
+			0xa6, 0x7b, 0x6, 0xec, 0x5e, 0xce,
+			0x92, 0x77, 0x2c, 0xa4, 0x13, 0xcb, 0xa3, 0xca, 0x12, 0x56, 0x8f, 0xdc, 0x6c,
+			0x7b, 0x45, 0x11, 0xcd, 0x40, 0xa7, 0xf6, 0x59, 0x98, 0x4, 0x2, 0xdf, 0x2b,
+			0x99, 0x8b, 0xb9, 0xa4, 0xa8, 0xcb, 0xeb, 0x34, 0xc0, 0xf0, 0xa7, 0x8c, 0xf8,
+			0xd9, 0x1e, 0xde, 0x14, 0xa5, 0xed, 0x76, 0xbf, 0x11, 0x6f, 0xe3, 0x60, 0xaa,
+			0xfa, 0x88, 0x21, 0x49, 0x4, 0x35,
+		},
+		BitLength: 512,
+	},
+}
+
+var derEncodedSelfSignedCertBytes = []byte{
+	0x30, 0x82, 0x02, 0x18, 0x30,
+	0x82, 0x01, 0xc2, 0x02, 0x09, 0x00, 0x8c, 0xc3, 0x37, 0x92, 0x10, 0xec, 0x2c,
+	0x98, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
+	0x05, 0x05, 0x00, 0x30, 0x81, 0x92, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
+	0x04, 0x06, 0x13, 0x02, 0x58, 0x58, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55,
+	0x04, 0x08, 0x13, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74,
+	0x65, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x04, 0x43,
+	0x69, 0x74, 0x79, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
+	0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64,
+	0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, 0x31,
+	0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x66, 0x61, 0x6c,
+	0x73, 0x65, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f,
+	0x6d, 0x31, 0x20, 0x30, 0x1e, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+	0x01, 0x09, 0x01, 0x16, 0x11, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x40, 0x65, 0x78,
+	0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d,
+	0x30, 0x39, 0x31, 0x30, 0x30, 0x38, 0x30, 0x30, 0x32, 0x35, 0x35, 0x33, 0x5a,
+	0x17, 0x0d, 0x31, 0x30, 0x31, 0x30, 0x30, 0x38, 0x30, 0x30, 0x32, 0x35, 0x35,
+	0x33, 0x5a, 0x30, 0x81, 0x92, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
+	0x06, 0x13, 0x02, 0x58, 0x58, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04,
+	0x08, 0x13, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65,
+	0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x04, 0x43, 0x69,
+	0x74, 0x79, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x18,
+	0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67,
+	0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, 0x31, 0x1a,
+	0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x66, 0x61, 0x6c, 0x73,
+	0x65, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d,
+	0x31, 0x20, 0x30, 0x1e, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+	0x09, 0x01, 0x16, 0x11, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x40, 0x65, 0x78, 0x61,
+	0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x5c, 0x30, 0x0d, 0x06,
+	0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03,
+	0x4b, 0x00, 0x30, 0x48, 0x02, 0x41, 0x00, 0xcd, 0xb7, 0x63, 0x9c, 0x32, 0x78,
+	0xf0, 0x06, 0xaa, 0x27, 0x7f, 0x6e, 0xaf, 0x42, 0x90, 0x2b, 0x59, 0x2d, 0x8c,
+	0xbc, 0xbe, 0x38, 0xa1, 0xc9, 0x2b, 0xa4, 0x69, 0x5a, 0x33, 0x1b, 0x1d, 0xea,
+	0xde, 0xad, 0xd8, 0xe9, 0xa5, 0xc2, 0x7e, 0x8c, 0x4c, 0x2f, 0xd0, 0xa8, 0x88,
+	0x96, 0x57, 0x72, 0x2a, 0x4f, 0x2a, 0xf7, 0x58, 0x9c, 0xf2, 0xc7, 0x70, 0x45,
+	0xdc, 0x8f, 0xde, 0xec, 0x35, 0x7d, 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x0d,
+	0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00,
+	0x03, 0x41, 0x00, 0xa6, 0x7b, 0x06, 0xec, 0x5e, 0xce, 0x92, 0x77, 0x2c, 0xa4,
+	0x13, 0xcb, 0xa3, 0xca, 0x12, 0x56, 0x8f, 0xdc, 0x6c, 0x7b, 0x45, 0x11, 0xcd,
+	0x40, 0xa7, 0xf6, 0x59, 0x98, 0x04, 0x02, 0xdf, 0x2b, 0x99, 0x8b, 0xb9, 0xa4,
+	0xa8, 0xcb, 0xeb, 0x34, 0xc0, 0xf0, 0xa7, 0x8c, 0xf8, 0xd9, 0x1e, 0xde, 0x14,
+	0xa5, 0xed, 0x76, 0xbf, 0x11, 0x6f, 0xe3, 0x60, 0xaa, 0xfa, 0x88, 0x21, 0x49,
+	0x04, 0x35,
+}
+
+var derEncodedPaypalNULCertBytes = []byte{
+	0x30, 0x82, 0x06, 0x44, 0x30,
+	0x82, 0x05, 0xad, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x03, 0x00, 0xf0, 0x9b,
+	0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05,
+	0x05, 0x00, 0x30, 0x82, 0x01, 0x12, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
+	0x04, 0x06, 0x13, 0x02, 0x45, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55,
+	0x04, 0x08, 0x13, 0x09, 0x42, 0x61, 0x72, 0x63, 0x65, 0x6c, 0x6f, 0x6e, 0x61,
+	0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x09, 0x42, 0x61,
+	0x72, 0x63, 0x65, 0x6c, 0x6f, 0x6e, 0x61, 0x31, 0x29, 0x30, 0x27, 0x06, 0x03,
+	0x55, 0x04, 0x0a, 0x13, 0x20, 0x49, 0x50, 0x53, 0x20, 0x43, 0x65, 0x72, 0x74,
+	0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74,
+	0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x73, 0x2e, 0x6c, 0x2e, 0x31, 0x2e,
+	0x30, 0x2c, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x14, 0x25, 0x67, 0x65, 0x6e, 0x65,
+	0x72, 0x61, 0x6c, 0x40, 0x69, 0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d,
+	0x20, 0x43, 0x2e, 0x49, 0x2e, 0x46, 0x2e, 0x20, 0x20, 0x42, 0x2d, 0x42, 0x36,
+	0x32, 0x32, 0x31, 0x30, 0x36, 0x39, 0x35, 0x31, 0x2e, 0x30, 0x2c, 0x06, 0x03,
+	0x55, 0x04, 0x0b, 0x13, 0x25, 0x69, 0x70, 0x73, 0x43, 0x41, 0x20, 0x43, 0x4c,
+	0x41, 0x53, 0x45, 0x41, 0x31, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
+	0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72,
+	0x69, 0x74, 0x79, 0x31, 0x2e, 0x30, 0x2c, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
+	0x25, 0x69, 0x70, 0x73, 0x43, 0x41, 0x20, 0x43, 0x4c, 0x41, 0x53, 0x45, 0x41,
+	0x31, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69,
+	0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31,
+	0x20, 0x30, 0x1e, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09,
+	0x01, 0x16, 0x11, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x40, 0x69, 0x70,
+	0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x39,
+	0x30, 0x32, 0x32, 0x34, 0x32, 0x33, 0x30, 0x34, 0x31, 0x37, 0x5a, 0x17, 0x0d,
+	0x31, 0x31, 0x30, 0x32, 0x32, 0x34, 0x32, 0x33, 0x30, 0x34, 0x31, 0x37, 0x5a,
+	0x30, 0x81, 0x94, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
+	0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13,
+	0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x16,
+	0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0d, 0x53, 0x61, 0x6e, 0x20,
+	0x46, 0x72, 0x61, 0x6e, 0x63, 0x69, 0x73, 0x63, 0x6f, 0x31, 0x11, 0x30, 0x0f,
+	0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x08, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69,
+	0x74, 0x79, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x0b,
+	0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x55, 0x6e, 0x69, 0x74, 0x31, 0x2f,
+	0x30, 0x2d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x26, 0x77, 0x77, 0x77, 0x2e,
+	0x70, 0x61, 0x79, 0x70, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x73, 0x73,
+	0x6c, 0x2e, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x63, 0x6f, 0x6e, 0x6e, 0x65,
+	0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x63, 0x63, 0x30, 0x81, 0x9f, 0x30, 0x0d,
+	0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00,
+	0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xd2, 0x69,
+	0xfa, 0x6f, 0x3a, 0x00, 0xb4, 0x21, 0x1b, 0xc8, 0xb1, 0x02, 0xd7, 0x3f, 0x19,
+	0xb2, 0xc4, 0x6d, 0xb4, 0x54, 0xf8, 0x8b, 0x8a, 0xcc, 0xdb, 0x72, 0xc2, 0x9e,
+	0x3c, 0x60, 0xb9, 0xc6, 0x91, 0x3d, 0x82, 0xb7, 0x7d, 0x99, 0xff, 0xd1, 0x29,
+	0x84, 0xc1, 0x73, 0x53, 0x9c, 0x82, 0xdd, 0xfc, 0x24, 0x8c, 0x77, 0xd5, 0x41,
+	0xf3, 0xe8, 0x1e, 0x42, 0xa1, 0xad, 0x2d, 0x9e, 0xff, 0x5b, 0x10, 0x26, 0xce,
+	0x9d, 0x57, 0x17, 0x73, 0x16, 0x23, 0x38, 0xc8, 0xd6, 0xf1, 0xba, 0xa3, 0x96,
+	0x5b, 0x16, 0x67, 0x4a, 0x4f, 0x73, 0x97, 0x3a, 0x4d, 0x14, 0xa4, 0xf4, 0xe2,
+	0x3f, 0x8b, 0x05, 0x83, 0x42, 0xd1, 0xd0, 0xdc, 0x2f, 0x7a, 0xe5, 0xb6, 0x10,
+	0xb2, 0x11, 0xc0, 0xdc, 0x21, 0x2a, 0x90, 0xff, 0xae, 0x97, 0x71, 0x5a, 0x49,
+	0x81, 0xac, 0x40, 0xf3, 0x3b, 0xb8, 0x59, 0xb2, 0x4f, 0x02, 0x03, 0x01, 0x00,
+	0x01, 0xa3, 0x82, 0x03, 0x21, 0x30, 0x82, 0x03, 0x1d, 0x30, 0x09, 0x06, 0x03,
+	0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x11, 0x06, 0x09, 0x60, 0x86,
+	0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x01, 0x04, 0x04, 0x03, 0x02, 0x06, 0x40,
+	0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x03, 0xf8,
+	0x30, 0x13, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x0c, 0x30, 0x0a, 0x06, 0x08,
+	0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x30, 0x1d, 0x06, 0x03, 0x55,
+	0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x61, 0x8f, 0x61, 0x34, 0x43, 0x55, 0x14,
+	0x7f, 0x27, 0x09, 0xce, 0x4c, 0x8b, 0xea, 0x9b, 0x7b, 0x19, 0x25, 0xbc, 0x6e,
+	0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14,
+	0x0e, 0x07, 0x60, 0xd4, 0x39, 0xc9, 0x1b, 0x5b, 0x5d, 0x90, 0x7b, 0x23, 0xc8,
+	0xd2, 0x34, 0x9d, 0x4a, 0x9a, 0x46, 0x39, 0x30, 0x09, 0x06, 0x03, 0x55, 0x1d,
+	0x11, 0x04, 0x02, 0x30, 0x00, 0x30, 0x1c, 0x06, 0x03, 0x55, 0x1d, 0x12, 0x04,
+	0x15, 0x30, 0x13, 0x81, 0x11, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x40,
+	0x69, 0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x72, 0x06, 0x09,
+	0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x0d, 0x04, 0x65, 0x16, 0x63,
+	0x4f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20,
+	0x49, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x4e,
+	0x4f, 0x54, 0x20, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x41, 0x54, 0x45, 0x44, 0x2e,
+	0x20, 0x43, 0x4c, 0x41, 0x53, 0x45, 0x41, 0x31, 0x20, 0x53, 0x65, 0x72, 0x76,
+	0x65, 0x72, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74,
+	0x65, 0x20, 0x69, 0x73, 0x73, 0x75, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x68,
+	0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x70,
+	0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x30, 0x2f, 0x06, 0x09, 0x60,
+	0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x02, 0x04, 0x22, 0x16, 0x20, 0x68,
+	0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x70,
+	0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61,
+	0x32, 0x30, 0x30, 0x32, 0x2f, 0x30, 0x43, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
+	0x86, 0xf8, 0x42, 0x01, 0x04, 0x04, 0x36, 0x16, 0x34, 0x68, 0x74, 0x74, 0x70,
+	0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x70, 0x73, 0x63, 0x61,
+	0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61, 0x32, 0x30, 0x30,
+	0x32, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61, 0x32, 0x30, 0x30, 0x32, 0x43, 0x4c,
+	0x41, 0x53, 0x45, 0x41, 0x31, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x46, 0x06, 0x09,
+	0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x03, 0x04, 0x39, 0x16, 0x37,
+	0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69,
+	0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x70, 0x73, 0x63,
+	0x61, 0x32, 0x30, 0x30, 0x32, 0x2f, 0x72, 0x65, 0x76, 0x6f, 0x63, 0x61, 0x74,
+	0x69, 0x6f, 0x6e, 0x43, 0x4c, 0x41, 0x53, 0x45, 0x41, 0x31, 0x2e, 0x68, 0x74,
+	0x6d, 0x6c, 0x3f, 0x30, 0x43, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8,
+	0x42, 0x01, 0x07, 0x04, 0x36, 0x16, 0x34, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a,
+	0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x70, 0x73, 0x63, 0x61, 0x2e, 0x63,
+	0x6f, 0x6d, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61, 0x32, 0x30, 0x30, 0x32, 0x2f,
+	0x72, 0x65, 0x6e, 0x65, 0x77, 0x61, 0x6c, 0x43, 0x4c, 0x41, 0x53, 0x45, 0x41,
+	0x31, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x3f, 0x30, 0x41, 0x06, 0x09, 0x60, 0x86,
+	0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x08, 0x04, 0x34, 0x16, 0x32, 0x68, 0x74,
+	0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x70, 0x73,
+	0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61, 0x32,
+	0x30, 0x30, 0x32, 0x2f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x43, 0x4c, 0x41,
+	0x53, 0x45, 0x41, 0x31, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x30, 0x81, 0x83, 0x06,
+	0x03, 0x55, 0x1d, 0x1f, 0x04, 0x7c, 0x30, 0x7a, 0x30, 0x39, 0xa0, 0x37, 0xa0,
+	0x35, 0x86, 0x33, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77,
+	0x2e, 0x69, 0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x70,
+	0x73, 0x63, 0x61, 0x32, 0x30, 0x30, 0x32, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61,
+	0x32, 0x30, 0x30, 0x32, 0x43, 0x4c, 0x41, 0x53, 0x45, 0x41, 0x31, 0x2e, 0x63,
+	0x72, 0x6c, 0x30, 0x3d, 0xa0, 0x3b, 0xa0, 0x39, 0x86, 0x37, 0x68, 0x74, 0x74,
+	0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x62, 0x61, 0x63, 0x6b, 0x2e, 0x69,
+	0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x70, 0x73, 0x63,
+	0x61, 0x32, 0x30, 0x30, 0x32, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61, 0x32, 0x30,
+	0x30, 0x32, 0x43, 0x4c, 0x41, 0x53, 0x45, 0x41, 0x31, 0x2e, 0x63, 0x72, 0x6c,
+	0x30, 0x32, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04,
+	0x26, 0x30, 0x24, 0x30, 0x22, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
+	0x30, 0x01, 0x86, 0x16, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63,
+	0x73, 0x70, 0x2e, 0x69, 0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
+	0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05,
+	0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x68, 0xee, 0x79, 0x97, 0x97, 0xdd, 0x3b,
+	0xef, 0x16, 0x6a, 0x06, 0xf2, 0x14, 0x9a, 0x6e, 0xcd, 0x9e, 0x12, 0xf7, 0xaa,
+	0x83, 0x10, 0xbd, 0xd1, 0x7c, 0x98, 0xfa, 0xc7, 0xae, 0xd4, 0x0e, 0x2c, 0x9e,
+	0x38, 0x05, 0x9d, 0x52, 0x60, 0xa9, 0x99, 0x0a, 0x81, 0xb4, 0x98, 0x90, 0x1d,
+	0xae, 0xbb, 0x4a, 0xd7, 0xb9, 0xdc, 0x88, 0x9e, 0x37, 0x78, 0x41, 0x5b, 0xf7,
+	0x82, 0xa5, 0xf2, 0xba, 0x41, 0x25, 0x5a, 0x90, 0x1a, 0x1e, 0x45, 0x38, 0xa1,
+	0x52, 0x58, 0x75, 0x94, 0x26, 0x44, 0xfb, 0x20, 0x07, 0xba, 0x44, 0xcc, 0xe5,
+	0x4a, 0x2d, 0x72, 0x3f, 0x98, 0x47, 0xf6, 0x26, 0xdc, 0x05, 0x46, 0x05, 0x07,
+	0x63, 0x21, 0xab, 0x46, 0x9b, 0x9c, 0x78, 0xd5, 0x54, 0x5b, 0x3d, 0x0c, 0x1e,
+	0xc8, 0x64, 0x8c, 0xb5, 0x50, 0x23, 0x82, 0x6f, 0xdb, 0xb8, 0x22, 0x1c, 0x43,
+	0x96, 0x07, 0xa8, 0xbb,
+}
+
+var stringSliceTestData = [][]string{
+	{"foo", "bar"},
+	{"foo", "\\bar"},
+	{"foo", "\"bar\""},
+	{"foo", "åäö"},
+}
+
+func TestStringSlice(t *testing.T) {
+	for _, test := range stringSliceTestData {
+		bs, err := Marshal(test)
+		if err != nil {
+			t.Error(err)
+		}
+
+		var res []string
+		_, err = Unmarshal(bs, &res)
+		if err != nil {
+			t.Error(err)
+		}
+
+		if fmt.Sprintf("%v", res) != fmt.Sprintf("%v", test) {
+			t.Errorf("incorrect marshal/unmarshal; %v != %v", res, test)
+		}
+	}
+}
+
+type explicitTaggedTimeTest struct {
+	Time time.Time `asn1:"explicit,tag:0"`
+}
+
+var explicitTaggedTimeTestData = []struct {
+	in  []byte
+	out explicitTaggedTimeTest
+}{
+	{[]byte{0x30, 0x11, 0xa0, 0xf, 0x17, 0xd, '9', '1', '0', '5', '0', '6', '1', '6', '4', '5', '4', '0', 'Z'},
+		explicitTaggedTimeTest{time.Date(1991, 05, 06, 16, 45, 40, 0, time.UTC)}},
+	{[]byte{0x30, 0x17, 0xa0, 0xf, 0x18, 0x13, '2', '0', '1', '0', '0', '1', '0', '2', '0', '3', '0', '4', '0', '5', '+', '0', '6', '0', '7'},
+		explicitTaggedTimeTest{time.Date(2010, 01, 02, 03, 04, 05, 0, time.FixedZone("", 6*60*60+7*60))}},
+}
+
+func TestExplicitTaggedTime(t *testing.T) {
+	// Test that a time.Time will match either tagUTCTime or
+	// tagGeneralizedTime.
+	for i, test := range explicitTaggedTimeTestData {
+		var got explicitTaggedTimeTest
+		_, err := Unmarshal(test.in, &got)
+		if err != nil {
+			t.Errorf("Unmarshal failed at index %d %v", i, err)
+		}
+		if !got.Time.Equal(test.out.Time) {
+			t.Errorf("#%d: got %v, want %v", i, got.Time, test.out.Time)
+		}
+	}
+}
+
+type implicitTaggedTimeTest struct {
+	Time time.Time `asn1:"tag:24"`
+}
+
+func TestImplicitTaggedTime(t *testing.T) {
+	// An implicitly tagged time value, that happens to have an implicit
+	// tag equal to a GENERALIZEDTIME, should still be parsed as a UTCTime.
+	// (There's no "timeType" in fieldParameters to determine what type of
+	// time should be expected when implicitly tagged.)
+	der := []byte{0x30, 0x0f, 0x80 | 24, 0xd, '9', '1', '0', '5', '0', '6', '1', '6', '4', '5', '4', '0', 'Z'}
+	var result implicitTaggedTimeTest
+	if _, err := Unmarshal(der, &result); err != nil {
+		t.Fatalf("Error while parsing: %s", err)
+	}
+	if expected := time.Date(1991, 05, 06, 16, 45, 40, 0, time.UTC); !result.Time.Equal(expected) {
+		t.Errorf("Wrong result. Got %v, want %v", result.Time, expected)
+	}
+}
diff --git a/src/pkg/encoding/asn1/common.go b/src/encoding/asn1/common.go
similarity index 100%
rename from src/pkg/encoding/asn1/common.go
rename to src/encoding/asn1/common.go
diff --git a/src/encoding/asn1/marshal.go b/src/encoding/asn1/marshal.go
new file mode 100644
index 0000000..b2f104b
--- /dev/null
+++ b/src/encoding/asn1/marshal.go
@@ -0,0 +1,646 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package asn1
+
+import (
+	"bytes"
+	"errors"
+	"fmt"
+	"io"
+	"math/big"
+	"reflect"
+	"time"
+	"unicode/utf8"
+)
+
+// A forkableWriter is an in-memory buffer that can be
+// 'forked' to create new forkableWriters that bracket the
+// original.  After
+//    pre, post := w.fork();
+// the overall sequence of bytes represented is logically w+pre+post.
+type forkableWriter struct {
+	*bytes.Buffer
+	pre, post *forkableWriter
+}
+
+func newForkableWriter() *forkableWriter {
+	return &forkableWriter{new(bytes.Buffer), nil, nil}
+}
+
+func (f *forkableWriter) fork() (pre, post *forkableWriter) {
+	if f.pre != nil || f.post != nil {
+		panic("have already forked")
+	}
+	f.pre = newForkableWriter()
+	f.post = newForkableWriter()
+	return f.pre, f.post
+}
+
+func (f *forkableWriter) Len() (l int) {
+	l += f.Buffer.Len()
+	if f.pre != nil {
+		l += f.pre.Len()
+	}
+	if f.post != nil {
+		l += f.post.Len()
+	}
+	return
+}
+
+func (f *forkableWriter) writeTo(out io.Writer) (n int, err error) {
+	n, err = out.Write(f.Bytes())
+	if err != nil {
+		return
+	}
+
+	var nn int
+
+	if f.pre != nil {
+		nn, err = f.pre.writeTo(out)
+		n += nn
+		if err != nil {
+			return
+		}
+	}
+
+	if f.post != nil {
+		nn, err = f.post.writeTo(out)
+		n += nn
+	}
+	return
+}
+
+func marshalBase128Int(out *forkableWriter, n int64) (err error) {
+	if n == 0 {
+		err = out.WriteByte(0)
+		return
+	}
+
+	l := 0
+	for i := n; i > 0; i >>= 7 {
+		l++
+	}
+
+	for i := l - 1; i >= 0; i-- {
+		o := byte(n >> uint(i*7))
+		o &= 0x7f
+		if i != 0 {
+			o |= 0x80
+		}
+		err = out.WriteByte(o)
+		if err != nil {
+			return
+		}
+	}
+
+	return nil
+}
+
+func marshalInt64(out *forkableWriter, i int64) (err error) {
+	n := int64Length(i)
+
+	for ; n > 0; n-- {
+		err = out.WriteByte(byte(i >> uint((n-1)*8)))
+		if err != nil {
+			return
+		}
+	}
+
+	return nil
+}
+
+func int64Length(i int64) (numBytes int) {
+	numBytes = 1
+
+	for i > 127 {
+		numBytes++
+		i >>= 8
+	}
+
+	for i < -128 {
+		numBytes++
+		i >>= 8
+	}
+
+	return
+}
+
+func marshalBigInt(out *forkableWriter, n *big.Int) (err error) {
+	if n.Sign() < 0 {
+		// A negative number has to be converted to two's-complement
+		// form. So we'll subtract 1 and invert. If the
+		// most-significant-bit isn't set then we'll need to pad the
+		// beginning with 0xff in order to keep the number negative.
+		nMinus1 := new(big.Int).Neg(n)
+		nMinus1.Sub(nMinus1, bigOne)
+		bytes := nMinus1.Bytes()
+		for i := range bytes {
+			bytes[i] ^= 0xff
+		}
+		if len(bytes) == 0 || bytes[0]&0x80 == 0 {
+			err = out.WriteByte(0xff)
+			if err != nil {
+				return
+			}
+		}
+		_, err = out.Write(bytes)
+	} else if n.Sign() == 0 {
+		// Zero is written as a single 0 zero rather than no bytes.
+		err = out.WriteByte(0x00)
+	} else {
+		bytes := n.Bytes()
+		if len(bytes) > 0 && bytes[0]&0x80 != 0 {
+			// We'll have to pad this with 0x00 in order to stop it
+			// looking like a negative number.
+			err = out.WriteByte(0)
+			if err != nil {
+				return
+			}
+		}
+		_, err = out.Write(bytes)
+	}
+	return
+}
+
+func marshalLength(out *forkableWriter, i int) (err error) {
+	n := lengthLength(i)
+
+	for ; n > 0; n-- {
+		err = out.WriteByte(byte(i >> uint((n-1)*8)))
+		if err != nil {
+			return
+		}
+	}
+
+	return nil
+}
+
+func lengthLength(i int) (numBytes int) {
+	numBytes = 1
+	for i > 255 {
+		numBytes++
+		i >>= 8
+	}
+	return
+}
+
+func marshalTagAndLength(out *forkableWriter, t tagAndLength) (err error) {
+	b := uint8(t.class) << 6
+	if t.isCompound {
+		b |= 0x20
+	}
+	if t.tag >= 31 {
+		b |= 0x1f
+		err = out.WriteByte(b)
+		if err != nil {
+			return
+		}
+		err = marshalBase128Int(out, int64(t.tag))
+		if err != nil {
+			return
+		}
+	} else {
+		b |= uint8(t.tag)
+		err = out.WriteByte(b)
+		if err != nil {
+			return
+		}
+	}
+
+	if t.length >= 128 {
+		l := lengthLength(t.length)
+		err = out.WriteByte(0x80 | byte(l))
+		if err != nil {
+			return
+		}
+		err = marshalLength(out, t.length)
+		if err != nil {
+			return
+		}
+	} else {
+		err = out.WriteByte(byte(t.length))
+		if err != nil {
+			return
+		}
+	}
+
+	return nil
+}
+
+func marshalBitString(out *forkableWriter, b BitString) (err error) {
+	paddingBits := byte((8 - b.BitLength%8) % 8)
+	err = out.WriteByte(paddingBits)
+	if err != nil {
+		return
+	}
+	_, err = out.Write(b.Bytes)
+	return
+}
+
+func marshalObjectIdentifier(out *forkableWriter, oid []int) (err error) {
+	if len(oid) < 2 || oid[0] > 2 || (oid[0] < 2 && oid[1] >= 40) {
+		return StructuralError{"invalid object identifier"}
+	}
+
+	err = marshalBase128Int(out, int64(oid[0]*40+oid[1]))
+	if err != nil {
+		return
+	}
+	for i := 2; i < len(oid); i++ {
+		err = marshalBase128Int(out, int64(oid[i]))
+		if err != nil {
+			return
+		}
+	}
+
+	return
+}
+
+func marshalPrintableString(out *forkableWriter, s string) (err error) {
+	b := []byte(s)
+	for _, c := range b {
+		if !isPrintable(c) {
+			return StructuralError{"PrintableString contains invalid character"}
+		}
+	}
+
+	_, err = out.Write(b)
+	return
+}
+
+func marshalIA5String(out *forkableWriter, s string) (err error) {
+	b := []byte(s)
+	for _, c := range b {
+		if c > 127 {
+			return StructuralError{"IA5String contains invalid character"}
+		}
+	}
+
+	_, err = out.Write(b)
+	return
+}
+
+func marshalUTF8String(out *forkableWriter, s string) (err error) {
+	_, err = out.Write([]byte(s))
+	return
+}
+
+func marshalTwoDigits(out *forkableWriter, v int) (err error) {
+	err = out.WriteByte(byte('0' + (v/10)%10))
+	if err != nil {
+		return
+	}
+	return out.WriteByte(byte('0' + v%10))
+}
+
+func marshalFourDigits(out *forkableWriter, v int) (err error) {
+	var bytes [4]byte
+	for i := range bytes {
+		bytes[3-i] = '0' + byte(v%10)
+		v /= 10
+	}
+	_, err = out.Write(bytes[:])
+	return
+}
+
+func outsideUTCRange(t time.Time) bool {
+	year := t.Year()
+	return year < 1950 || year >= 2050
+}
+
+func marshalUTCTime(out *forkableWriter, t time.Time) (err error) {
+	year := t.Year()
+
+	switch {
+	case 1950 <= year && year < 2000:
+		err = marshalTwoDigits(out, int(year-1900))
+	case 2000 <= year && year < 2050:
+		err = marshalTwoDigits(out, int(year-2000))
+	default:
+		return StructuralError{"cannot represent time as UTCTime"}
+	}
+	if err != nil {
+		return
+	}
+
+	return marshalTimeCommon(out, t)
+}
+
+func marshalGeneralizedTime(out *forkableWriter, t time.Time) (err error) {
+	year := t.Year()
+	if year < 0 || year > 9999 {
+		return StructuralError{"cannot represent time as GeneralizedTime"}
+	}
+	if err = marshalFourDigits(out, year); err != nil {
+		return
+	}
+
+	return marshalTimeCommon(out, t)
+}
+
+func marshalTimeCommon(out *forkableWriter, t time.Time) (err error) {
+	_, month, day := t.Date()
+
+	err = marshalTwoDigits(out, int(month))
+	if err != nil {
+		return
+	}
+
+	err = marshalTwoDigits(out, day)
+	if err != nil {
+		return
+	}
+
+	hour, min, sec := t.Clock()
+
+	err = marshalTwoDigits(out, hour)
+	if err != nil {
+		return
+	}
+
+	err = marshalTwoDigits(out, min)
+	if err != nil {
+		return
+	}
+
+	err = marshalTwoDigits(out, sec)
+	if err != nil {
+		return
+	}
+
+	_, offset := t.Zone()
+
+	switch {
+	case offset/60 == 0:
+		err = out.WriteByte('Z')
+		return
+	case offset > 0:
+		err = out.WriteByte('+')
+	case offset < 0:
+		err = out.WriteByte('-')
+	}
+
+	if err != nil {
+		return
+	}
+
+	offsetMinutes := offset / 60
+	if offsetMinutes < 0 {
+		offsetMinutes = -offsetMinutes
+	}
+
+	err = marshalTwoDigits(out, offsetMinutes/60)
+	if err != nil {
+		return
+	}
+
+	err = marshalTwoDigits(out, offsetMinutes%60)
+	return
+}
+
+func stripTagAndLength(in []byte) []byte {
+	_, offset, err := parseTagAndLength(in, 0)
+	if err != nil {
+		return in
+	}
+	return in[offset:]
+}
+
+func marshalBody(out *forkableWriter, value reflect.Value, params fieldParameters) (err error) {
+	switch value.Type() {
+	case timeType:
+		t := value.Interface().(time.Time)
+		if outsideUTCRange(t) {
+			return marshalGeneralizedTime(out, t)
+		} else {
+			return marshalUTCTime(out, t)
+		}
+	case bitStringType:
+		return marshalBitString(out, value.Interface().(BitString))
+	case objectIdentifierType:
+		return marshalObjectIdentifier(out, value.Interface().(ObjectIdentifier))
+	case bigIntType:
+		return marshalBigInt(out, value.Interface().(*big.Int))
+	}
+
+	switch v := value; v.Kind() {
+	case reflect.Bool:
+		if v.Bool() {
+			return out.WriteByte(255)
+		} else {
+			return out.WriteByte(0)
+		}
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		return marshalInt64(out, int64(v.Int()))
+	case reflect.Struct:
+		t := v.Type()
+
+		startingField := 0
+
+		// If the first element of the structure is a non-empty
+		// RawContents, then we don't bother serializing the rest.
+		if t.NumField() > 0 && t.Field(0).Type == rawContentsType {
+			s := v.Field(0)
+			if s.Len() > 0 {
+				bytes := make([]byte, s.Len())
+				for i := 0; i < s.Len(); i++ {
+					bytes[i] = uint8(s.Index(i).Uint())
+				}
+				/* The RawContents will contain the tag and
+				 * length fields but we'll also be writing
+				 * those ourselves, so we strip them out of
+				 * bytes */
+				_, err = out.Write(stripTagAndLength(bytes))
+				return
+			} else {
+				startingField = 1
+			}
+		}
+
+		for i := startingField; i < t.NumField(); i++ {
+			var pre *forkableWriter
+			pre, out = out.fork()
+			err = marshalField(pre, v.Field(i), parseFieldParameters(t.Field(i).Tag.Get("asn1")))
+			if err != nil {
+				return
+			}
+		}
+		return
+	case reflect.Slice:
+		sliceType := v.Type()
+		if sliceType.Elem().Kind() == reflect.Uint8 {
+			bytes := make([]byte, v.Len())
+			for i := 0; i < v.Len(); i++ {
+				bytes[i] = uint8(v.Index(i).Uint())
+			}
+			_, err = out.Write(bytes)
+			return
+		}
+
+		var fp fieldParameters
+		for i := 0; i < v.Len(); i++ {
+			var pre *forkableWriter
+			pre, out = out.fork()
+			err = marshalField(pre, v.Index(i), fp)
+			if err != nil {
+				return
+			}
+		}
+		return
+	case reflect.String:
+		switch params.stringType {
+		case tagIA5String:
+			return marshalIA5String(out, v.String())
+		case tagPrintableString:
+			return marshalPrintableString(out, v.String())
+		default:
+			return marshalUTF8String(out, v.String())
+		}
+	}
+
+	return StructuralError{"unknown Go type"}
+}
+
+func marshalField(out *forkableWriter, v reflect.Value, params fieldParameters) (err error) {
+	// If the field is an interface{} then recurse into it.
+	if v.Kind() == reflect.Interface && v.Type().NumMethod() == 0 {
+		return marshalField(out, v.Elem(), params)
+	}
+
+	if v.Kind() == reflect.Slice && v.Len() == 0 && params.omitEmpty {
+		return
+	}
+
+	if params.optional && params.defaultValue != nil && canHaveDefaultValue(v.Kind()) {
+		defaultValue := reflect.New(v.Type()).Elem()
+		defaultValue.SetInt(*params.defaultValue)
+
+		if reflect.DeepEqual(v.Interface(), defaultValue.Interface()) {
+			return
+		}
+	}
+
+	// If no default value is given then the zero value for the type is
+	// assumed to be the default value. This isn't obviously the correct
+	// behaviour, but it's what Go has traditionally done.
+	if params.optional && params.defaultValue == nil {
+		if reflect.DeepEqual(v.Interface(), reflect.Zero(v.Type()).Interface()) {
+			return
+		}
+	}
+
+	if v.Type() == rawValueType {
+		rv := v.Interface().(RawValue)
+		if len(rv.FullBytes) != 0 {
+			_, err = out.Write(rv.FullBytes)
+		} else {
+			err = marshalTagAndLength(out, tagAndLength{rv.Class, rv.Tag, len(rv.Bytes), rv.IsCompound})
+			if err != nil {
+				return
+			}
+			_, err = out.Write(rv.Bytes)
+		}
+		return
+	}
+
+	tag, isCompound, ok := getUniversalType(v.Type())
+	if !ok {
+		err = StructuralError{fmt.Sprintf("unknown Go type: %v", v.Type())}
+		return
+	}
+	class := classUniversal
+
+	if params.stringType != 0 && tag != tagPrintableString {
+		return StructuralError{"explicit string type given to non-string member"}
+	}
+
+	switch tag {
+	case tagPrintableString:
+		if params.stringType == 0 {
+			// This is a string without an explicit string type. We'll use
+			// a PrintableString if the character set in the string is
+			// sufficiently limited, otherwise we'll use a UTF8String.
+			for _, r := range v.String() {
+				if r >= utf8.RuneSelf || !isPrintable(byte(r)) {
+					if !utf8.ValidString(v.String()) {
+						return errors.New("asn1: string not valid UTF-8")
+					}
+					tag = tagUTF8String
+					break
+				}
+			}
+		} else {
+			tag = params.stringType
+		}
+	case tagUTCTime:
+		if outsideUTCRange(v.Interface().(time.Time)) {
+			tag = tagGeneralizedTime
+		}
+	}
+
+	if params.set {
+		if tag != tagSequence {
+			return StructuralError{"non sequence tagged as set"}
+		}
+		tag = tagSet
+	}
+
+	tags, body := out.fork()
+
+	err = marshalBody(body, v, params)
+	if err != nil {
+		return
+	}
+
+	bodyLen := body.Len()
+
+	var explicitTag *forkableWriter
+	if params.explicit {
+		explicitTag, tags = tags.fork()
+	}
+
+	if !params.explicit && params.tag != nil {
+		// implicit tag.
+		tag = *params.tag
+		class = classContextSpecific
+	}
+
+	err = marshalTagAndLength(tags, tagAndLength{class, tag, bodyLen, isCompound})
+	if err != nil {
+		return
+	}
+
+	if params.explicit {
+		err = marshalTagAndLength(explicitTag, tagAndLength{
+			class:      classContextSpecific,
+			tag:        *params.tag,
+			length:     bodyLen + tags.Len(),
+			isCompound: true,
+		})
+	}
+
+	return nil
+}
+
+// Marshal returns the ASN.1 encoding of val.
+//
+// In addition to the struct tags recognised by Unmarshal, the following can be
+// used:
+//
+//	ia5:		causes strings to be marshaled as ASN.1, IA5 strings
+//	omitempty:	causes empty slices to be skipped
+//	printable:	causes strings to be marshaled as ASN.1, PrintableString strings.
+//	utf8:		causes strings to be marshaled as ASN.1, UTF8 strings
+func Marshal(val interface{}) ([]byte, error) {
+	var out bytes.Buffer
+	v := reflect.ValueOf(val)
+	f := newForkableWriter()
+	err := marshalField(f, v, fieldParameters{})
+	if err != nil {
+		return nil, err
+	}
+	_, err = f.writeTo(&out)
+	return out.Bytes(), nil
+}
diff --git a/src/encoding/asn1/marshal_test.go b/src/encoding/asn1/marshal_test.go
new file mode 100644
index 0000000..5b0115f
--- /dev/null
+++ b/src/encoding/asn1/marshal_test.go
@@ -0,0 +1,164 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package asn1
+
+import (
+	"bytes"
+	"encoding/hex"
+	"math/big"
+	"testing"
+	"time"
+)
+
+type intStruct struct {
+	A int
+}
+
+type twoIntStruct struct {
+	A int
+	B int
+}
+
+type bigIntStruct struct {
+	A *big.Int
+}
+
+type nestedStruct struct {
+	A intStruct
+}
+
+type rawContentsStruct struct {
+	Raw RawContent
+	A   int
+}
+
+type implicitTagTest struct {
+	A int `asn1:"implicit,tag:5"`
+}
+
+type explicitTagTest struct {
+	A int `asn1:"explicit,tag:5"`
+}
+
+type ia5StringTest struct {
+	A string `asn1:"ia5"`
+}
+
+type printableStringTest struct {
+	A string `asn1:"printable"`
+}
+
+type optionalRawValueTest struct {
+	A RawValue `asn1:"optional"`
+}
+
+type omitEmptyTest struct {
+	A []string `asn1:"omitempty"`
+}
+
+type defaultTest struct {
+	A int `asn1:"optional,default:1"`
+}
+
+type testSET []int
+
+var PST = time.FixedZone("PST", -8*60*60)
+
+type marshalTest struct {
+	in  interface{}
+	out string // hex encoded
+}
+
+func farFuture() time.Time {
+	t, err := time.Parse(time.RFC3339, "2100-04-05T12:01:01Z")
+	if err != nil {
+		panic(err)
+	}
+	return t
+}
+
+var marshalTests = []marshalTest{
+	{10, "02010a"},
+	{127, "02017f"},
+	{128, "02020080"},
+	{-128, "020180"},
+	{-129, "0202ff7f"},
+	{intStruct{64}, "3003020140"},
+	{bigIntStruct{big.NewInt(0x123456)}, "30050203123456"},
+	{twoIntStruct{64, 65}, "3006020140020141"},
+	{nestedStruct{intStruct{127}}, "3005300302017f"},
+	{[]byte{1, 2, 3}, "0403010203"},
+	{implicitTagTest{64}, "3003850140"},
+	{explicitTagTest{64}, "3005a503020140"},
+	{time.Unix(0, 0).UTC(), "170d3730303130313030303030305a"},
+	{time.Unix(1258325776, 0).UTC(), "170d3039313131353232353631365a"},
+	{time.Unix(1258325776, 0).In(PST), "17113039313131353134353631362d30383030"},
+	{farFuture(), "180f32313030303430353132303130315a"},
+	{BitString{[]byte{0x80}, 1}, "03020780"},
+	{BitString{[]byte{0x81, 0xf0}, 12}, "03030481f0"},
+	{ObjectIdentifier([]int{1, 2, 3, 4}), "06032a0304"},
+	{ObjectIdentifier([]int{1, 2, 840, 133549, 1, 1, 5}), "06092a864888932d010105"},
+	{ObjectIdentifier([]int{2, 100, 3}), "0603813403"},
+	{"test", "130474657374"},
+	{
+		"" +
+			"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +
+			"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +
+			"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +
+			"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", // This is 127 times 'x'
+		"137f" +
+			"7878787878787878787878787878787878787878787878787878787878787878" +
+			"7878787878787878787878787878787878787878787878787878787878787878" +
+			"7878787878787878787878787878787878787878787878787878787878787878" +
+			"78787878787878787878787878787878787878787878787878787878787878",
+	},
+	{
+		"" +
+			"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +
+			"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +
+			"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +
+			"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", // This is 128 times 'x'
+		"138180" +
+			"7878787878787878787878787878787878787878787878787878787878787878" +
+			"7878787878787878787878787878787878787878787878787878787878787878" +
+			"7878787878787878787878787878787878787878787878787878787878787878" +
+			"7878787878787878787878787878787878787878787878787878787878787878",
+	},
+	{ia5StringTest{"test"}, "3006160474657374"},
+	{optionalRawValueTest{}, "3000"},
+	{printableStringTest{"test"}, "3006130474657374"},
+	{printableStringTest{"test*"}, "30071305746573742a"},
+	{rawContentsStruct{nil, 64}, "3003020140"},
+	{rawContentsStruct{[]byte{0x30, 3, 1, 2, 3}, 64}, "3003010203"},
+	{RawValue{Tag: 1, Class: 2, IsCompound: false, Bytes: []byte{1, 2, 3}}, "8103010203"},
+	{testSET([]int{10}), "310302010a"},
+	{omitEmptyTest{[]string{}}, "3000"},
+	{omitEmptyTest{[]string{"1"}}, "30053003130131"},
+	{"Σ", "0c02cea3"},
+	{defaultTest{0}, "3003020100"},
+	{defaultTest{1}, "3000"},
+	{defaultTest{2}, "3003020102"},
+}
+
+func TestMarshal(t *testing.T) {
+	for i, test := range marshalTests {
+		data, err := Marshal(test.in)
+		if err != nil {
+			t.Errorf("#%d failed: %s", i, err)
+		}
+		out, _ := hex.DecodeString(test.out)
+		if !bytes.Equal(out, data) {
+			t.Errorf("#%d got: %x want %x\n\t%q\n\t%q", i, data, out, data, out)
+
+		}
+	}
+}
+
+func TestInvalidUTF8(t *testing.T) {
+	_, err := Marshal(string([]byte{0xff, 0xff}))
+	if err == nil {
+		t.Errorf("invalid UTF8 string was accepted")
+	}
+}
diff --git a/src/encoding/base32/base32.go b/src/encoding/base32/base32.go
new file mode 100644
index 0000000..5a9e869
--- /dev/null
+++ b/src/encoding/base32/base32.go
@@ -0,0 +1,426 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package base32 implements base32 encoding as specified by RFC 4648.
+package base32
+
+import (
+	"bytes"
+	"io"
+	"strconv"
+	"strings"
+)
+
+/*
+ * Encodings
+ */
+
+// An Encoding is a radix 32 encoding/decoding scheme, defined by a
+// 32-character alphabet.  The most common is the "base32" encoding
+// introduced for SASL GSSAPI and standardized in RFC 4648.
+// The alternate "base32hex" encoding is used in DNSSEC.
+type Encoding struct {
+	encode    string
+	decodeMap [256]byte
+}
+
+const encodeStd = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"
+const encodeHex = "0123456789ABCDEFGHIJKLMNOPQRSTUV"
+
+// NewEncoding returns a new Encoding defined by the given alphabet,
+// which must be a 32-byte string.
+func NewEncoding(encoder string) *Encoding {
+	e := new(Encoding)
+	e.encode = encoder
+	for i := 0; i < len(e.decodeMap); i++ {
+		e.decodeMap[i] = 0xFF
+	}
+	for i := 0; i < len(encoder); i++ {
+		e.decodeMap[encoder[i]] = byte(i)
+	}
+	return e
+}
+
+// StdEncoding is the standard base32 encoding, as defined in
+// RFC 4648.
+var StdEncoding = NewEncoding(encodeStd)
+
+// HexEncoding is the ``Extended Hex Alphabet'' defined in RFC 4648.
+// It is typically used in DNS.
+var HexEncoding = NewEncoding(encodeHex)
+
+var removeNewlinesMapper = func(r rune) rune {
+	if r == '\r' || r == '\n' {
+		return -1
+	}
+	return r
+}
+
+/*
+ * Encoder
+ */
+
+// Encode encodes src using the encoding enc, writing
+// EncodedLen(len(src)) bytes to dst.
+//
+// The encoding pads the output to a multiple of 8 bytes,
+// so Encode is not appropriate for use on individual blocks
+// of a large data stream.  Use NewEncoder() instead.
+func (enc *Encoding) Encode(dst, src []byte) {
+	if len(src) == 0 {
+		return
+	}
+
+	for len(src) > 0 {
+		var b0, b1, b2, b3, b4, b5, b6, b7 byte
+
+		// Unpack 8x 5-bit source blocks into a 5 byte
+		// destination quantum
+		switch len(src) {
+		default:
+			b7 = src[4] & 0x1F
+			b6 = src[4] >> 5
+			fallthrough
+		case 4:
+			b6 |= (src[3] << 3) & 0x1F
+			b5 = (src[3] >> 2) & 0x1F
+			b4 = src[3] >> 7
+			fallthrough
+		case 3:
+			b4 |= (src[2] << 1) & 0x1F
+			b3 = (src[2] >> 4) & 0x1F
+			fallthrough
+		case 2:
+			b3 |= (src[1] << 4) & 0x1F
+			b2 = (src[1] >> 1) & 0x1F
+			b1 = (src[1] >> 6) & 0x1F
+			fallthrough
+		case 1:
+			b1 |= (src[0] << 2) & 0x1F
+			b0 = src[0] >> 3
+		}
+
+		// Encode 5-bit blocks using the base32 alphabet
+		dst[0] = enc.encode[b0]
+		dst[1] = enc.encode[b1]
+		dst[2] = enc.encode[b2]
+		dst[3] = enc.encode[b3]
+		dst[4] = enc.encode[b4]
+		dst[5] = enc.encode[b5]
+		dst[6] = enc.encode[b6]
+		dst[7] = enc.encode[b7]
+
+		// Pad the final quantum
+		if len(src) < 5 {
+			dst[7] = '='
+			if len(src) < 4 {
+				dst[6] = '='
+				dst[5] = '='
+				if len(src) < 3 {
+					dst[4] = '='
+					if len(src) < 2 {
+						dst[3] = '='
+						dst[2] = '='
+					}
+				}
+			}
+			break
+		}
+		src = src[5:]
+		dst = dst[8:]
+	}
+}
+
+// EncodeToString returns the base32 encoding of src.
+func (enc *Encoding) EncodeToString(src []byte) string {
+	buf := make([]byte, enc.EncodedLen(len(src)))
+	enc.Encode(buf, src)
+	return string(buf)
+}
+
+type encoder struct {
+	err  error
+	enc  *Encoding
+	w    io.Writer
+	buf  [5]byte    // buffered data waiting to be encoded
+	nbuf int        // number of bytes in buf
+	out  [1024]byte // output buffer
+}
+
+func (e *encoder) Write(p []byte) (n int, err error) {
+	if e.err != nil {
+		return 0, e.err
+	}
+
+	// Leading fringe.
+	if e.nbuf > 0 {
+		var i int
+		for i = 0; i < len(p) && e.nbuf < 5; i++ {
+			e.buf[e.nbuf] = p[i]
+			e.nbuf++
+		}
+		n += i
+		p = p[i:]
+		if e.nbuf < 5 {
+			return
+		}
+		e.enc.Encode(e.out[0:], e.buf[0:])
+		if _, e.err = e.w.Write(e.out[0:8]); e.err != nil {
+			return n, e.err
+		}
+		e.nbuf = 0
+	}
+
+	// Large interior chunks.
+	for len(p) >= 5 {
+		nn := len(e.out) / 8 * 5
+		if nn > len(p) {
+			nn = len(p)
+			nn -= nn % 5
+		}
+		e.enc.Encode(e.out[0:], p[0:nn])
+		if _, e.err = e.w.Write(e.out[0 : nn/5*8]); e.err != nil {
+			return n, e.err
+		}
+		n += nn
+		p = p[nn:]
+	}
+
+	// Trailing fringe.
+	for i := 0; i < len(p); i++ {
+		e.buf[i] = p[i]
+	}
+	e.nbuf = len(p)
+	n += len(p)
+	return
+}
+
+// Close flushes any pending output from the encoder.
+// It is an error to call Write after calling Close.
+func (e *encoder) Close() error {
+	// If there's anything left in the buffer, flush it out
+	if e.err == nil && e.nbuf > 0 {
+		e.enc.Encode(e.out[0:], e.buf[0:e.nbuf])
+		e.nbuf = 0
+		_, e.err = e.w.Write(e.out[0:8])
+	}
+	return e.err
+}
+
+// NewEncoder returns a new base32 stream encoder.  Data written to
+// the returned writer will be encoded using enc and then written to w.
+// Base32 encodings operate in 5-byte blocks; when finished
+// writing, the caller must Close the returned encoder to flush any
+// partially written blocks.
+func NewEncoder(enc *Encoding, w io.Writer) io.WriteCloser {
+	return &encoder{enc: enc, w: w}
+}
+
+// EncodedLen returns the length in bytes of the base32 encoding
+// of an input buffer of length n.
+func (enc *Encoding) EncodedLen(n int) int { return (n + 4) / 5 * 8 }
+
+/*
+ * Decoder
+ */
+
+type CorruptInputError int64
+
+func (e CorruptInputError) Error() string {
+	return "illegal base32 data at input byte " + strconv.FormatInt(int64(e), 10)
+}
+
+// decode is like Decode but returns an additional 'end' value, which
+// indicates if end-of-message padding was encountered and thus any
+// additional data is an error. This method assumes that src has been
+// stripped of all supported whitespace ('\r' and '\n').
+func (enc *Encoding) decode(dst, src []byte) (n int, end bool, err error) {
+	olen := len(src)
+	for len(src) > 0 && !end {
+		// Decode quantum using the base32 alphabet
+		var dbuf [8]byte
+		dlen := 8
+
+		for j := 0; j < 8; {
+			if len(src) == 0 {
+				return n, false, CorruptInputError(olen - len(src) - j)
+			}
+			in := src[0]
+			src = src[1:]
+			if in == '=' && j >= 2 && len(src) < 8 {
+				// We've reached the end and there's padding
+				if len(src)+j < 8-1 {
+					// not enough padding
+					return n, false, CorruptInputError(olen)
+				}
+				for k := 0; k < 8-1-j; k++ {
+					if len(src) > k && src[k] != '=' {
+						// incorrect padding
+						return n, false, CorruptInputError(olen - len(src) + k - 1)
+					}
+				}
+				dlen, end = j, true
+				// 7, 5 and 2 are not valid padding lengths, and so 1, 3 and 6 are not
+				// valid dlen values. See RFC 4648 Section 6 "Base 32 Encoding" listing
+				// the five valid padding lengths, and Section 9 "Illustrations and
+				// Examples" for an illustration for how the 1st, 3rd and 6th base32
+				// src bytes do not yield enough information to decode a dst byte.
+				if dlen == 1 || dlen == 3 || dlen == 6 {
+					return n, false, CorruptInputError(olen - len(src) - 1)
+				}
+				break
+			}
+			dbuf[j] = enc.decodeMap[in]
+			if dbuf[j] == 0xFF {
+				return n, false, CorruptInputError(olen - len(src) - 1)
+			}
+			j++
+		}
+
+		// Pack 8x 5-bit source blocks into 5 byte destination
+		// quantum
+		switch dlen {
+		case 8:
+			dst[4] = dbuf[6]<<5 | dbuf[7]
+			fallthrough
+		case 7:
+			dst[3] = dbuf[4]<<7 | dbuf[5]<<2 | dbuf[6]>>3
+			fallthrough
+		case 5:
+			dst[2] = dbuf[3]<<4 | dbuf[4]>>1
+			fallthrough
+		case 4:
+			dst[1] = dbuf[1]<<6 | dbuf[2]<<1 | dbuf[3]>>4
+			fallthrough
+		case 2:
+			dst[0] = dbuf[0]<<3 | dbuf[1]>>2
+		}
+		dst = dst[5:]
+		switch dlen {
+		case 2:
+			n += 1
+		case 4:
+			n += 2
+		case 5:
+			n += 3
+		case 7:
+			n += 4
+		case 8:
+			n += 5
+		}
+	}
+	return n, end, nil
+}
+
+// Decode decodes src using the encoding enc.  It writes at most
+// DecodedLen(len(src)) bytes to dst and returns the number of bytes
+// written.  If src contains invalid base32 data, it will return the
+// number of bytes successfully written and CorruptInputError.
+// New line characters (\r and \n) are ignored.
+func (enc *Encoding) Decode(dst, src []byte) (n int, err error) {
+	src = bytes.Map(removeNewlinesMapper, src)
+	n, _, err = enc.decode(dst, src)
+	return
+}
+
+// DecodeString returns the bytes represented by the base32 string s.
+func (enc *Encoding) DecodeString(s string) ([]byte, error) {
+	s = strings.Map(removeNewlinesMapper, s)
+	dbuf := make([]byte, enc.DecodedLen(len(s)))
+	n, _, err := enc.decode(dbuf, []byte(s))
+	return dbuf[:n], err
+}
+
+type decoder struct {
+	err    error
+	enc    *Encoding
+	r      io.Reader
+	end    bool       // saw end of message
+	buf    [1024]byte // leftover input
+	nbuf   int
+	out    []byte // leftover decoded output
+	outbuf [1024 / 8 * 5]byte
+}
+
+func (d *decoder) Read(p []byte) (n int, err error) {
+	if d.err != nil {
+		return 0, d.err
+	}
+
+	// Use leftover decoded output from last read.
+	if len(d.out) > 0 {
+		n = copy(p, d.out)
+		d.out = d.out[n:]
+		return n, nil
+	}
+
+	// Read a chunk.
+	nn := len(p) / 5 * 8
+	if nn < 8 {
+		nn = 8
+	}
+	if nn > len(d.buf) {
+		nn = len(d.buf)
+	}
+	nn, d.err = io.ReadAtLeast(d.r, d.buf[d.nbuf:nn], 8-d.nbuf)
+	d.nbuf += nn
+	if d.nbuf < 8 {
+		return 0, d.err
+	}
+
+	// Decode chunk into p, or d.out and then p if p is too small.
+	nr := d.nbuf / 8 * 8
+	nw := d.nbuf / 8 * 5
+	if nw > len(p) {
+		nw, d.end, d.err = d.enc.decode(d.outbuf[0:], d.buf[0:nr])
+		d.out = d.outbuf[0:nw]
+		n = copy(p, d.out)
+		d.out = d.out[n:]
+	} else {
+		n, d.end, d.err = d.enc.decode(p, d.buf[0:nr])
+	}
+	d.nbuf -= nr
+	for i := 0; i < d.nbuf; i++ {
+		d.buf[i] = d.buf[i+nr]
+	}
+
+	if d.err == nil {
+		d.err = err
+	}
+	return n, d.err
+}
+
+type newlineFilteringReader struct {
+	wrapped io.Reader
+}
+
+func (r *newlineFilteringReader) Read(p []byte) (int, error) {
+	n, err := r.wrapped.Read(p)
+	for n > 0 {
+		offset := 0
+		for i, b := range p[0:n] {
+			if b != '\r' && b != '\n' {
+				if i != offset {
+					p[offset] = b
+				}
+				offset++
+			}
+		}
+		if offset > 0 {
+			return offset, err
+		}
+		// Previous buffer entirely whitespace, read again
+		n, err = r.wrapped.Read(p)
+	}
+	return n, err
+}
+
+// NewDecoder constructs a new base32 stream decoder.
+func NewDecoder(enc *Encoding, r io.Reader) io.Reader {
+	return &decoder{enc: enc, r: &newlineFilteringReader{r}}
+}
+
+// DecodedLen returns the maximum length in bytes of the decoded data
+// corresponding to n bytes of base32-encoded data.
+func (enc *Encoding) DecodedLen(n int) int { return n / 8 * 5 }
diff --git a/src/encoding/base32/base32_test.go b/src/encoding/base32/base32_test.go
new file mode 100644
index 0000000..5a68f06
--- /dev/null
+++ b/src/encoding/base32/base32_test.go
@@ -0,0 +1,302 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package base32
+
+import (
+	"bytes"
+	"io"
+	"io/ioutil"
+	"strings"
+	"testing"
+)
+
+type testpair struct {
+	decoded, encoded string
+}
+
+var pairs = []testpair{
+	// RFC 4648 examples
+	{"", ""},
+	{"f", "MY======"},
+	{"fo", "MZXQ===="},
+	{"foo", "MZXW6==="},
+	{"foob", "MZXW6YQ="},
+	{"fooba", "MZXW6YTB"},
+	{"foobar", "MZXW6YTBOI======"},
+
+	// Wikipedia examples, converted to base32
+	{"sure.", "ON2XEZJO"},
+	{"sure", "ON2XEZI="},
+	{"sur", "ON2XE==="},
+	{"su", "ON2Q===="},
+	{"leasure.", "NRSWC43VOJSS4==="},
+	{"easure.", "MVQXG5LSMUXA===="},
+	{"asure.", "MFZXK4TFFY======"},
+	{"sure.", "ON2XEZJO"},
+}
+
+var bigtest = testpair{
+	"Twas brillig, and the slithy toves",
+	"KR3WC4ZAMJZGS3DMNFTSYIDBNZSCA5DIMUQHG3DJORUHSIDUN53GK4Y=",
+}
+
+func testEqual(t *testing.T, msg string, args ...interface{}) bool {
+	if args[len(args)-2] != args[len(args)-1] {
+		t.Errorf(msg, args...)
+		return false
+	}
+	return true
+}
+
+func TestEncode(t *testing.T) {
+	for _, p := range pairs {
+		got := StdEncoding.EncodeToString([]byte(p.decoded))
+		testEqual(t, "Encode(%q) = %q, want %q", p.decoded, got, p.encoded)
+	}
+}
+
+func TestEncoder(t *testing.T) {
+	for _, p := range pairs {
+		bb := &bytes.Buffer{}
+		encoder := NewEncoder(StdEncoding, bb)
+		encoder.Write([]byte(p.decoded))
+		encoder.Close()
+		testEqual(t, "Encode(%q) = %q, want %q", p.decoded, bb.String(), p.encoded)
+	}
+}
+
+func TestEncoderBuffering(t *testing.T) {
+	input := []byte(bigtest.decoded)
+	for bs := 1; bs <= 12; bs++ {
+		bb := &bytes.Buffer{}
+		encoder := NewEncoder(StdEncoding, bb)
+		for pos := 0; pos < len(input); pos += bs {
+			end := pos + bs
+			if end > len(input) {
+				end = len(input)
+			}
+			n, err := encoder.Write(input[pos:end])
+			testEqual(t, "Write(%q) gave error %v, want %v", input[pos:end], err, error(nil))
+			testEqual(t, "Write(%q) gave length %v, want %v", input[pos:end], n, end-pos)
+		}
+		err := encoder.Close()
+		testEqual(t, "Close gave error %v, want %v", err, error(nil))
+		testEqual(t, "Encoding/%d of %q = %q, want %q", bs, bigtest.decoded, bb.String(), bigtest.encoded)
+	}
+}
+
+func TestDecode(t *testing.T) {
+	for _, p := range pairs {
+		dbuf := make([]byte, StdEncoding.DecodedLen(len(p.encoded)))
+		count, end, err := StdEncoding.decode(dbuf, []byte(p.encoded))
+		testEqual(t, "Decode(%q) = error %v, want %v", p.encoded, err, error(nil))
+		testEqual(t, "Decode(%q) = length %v, want %v", p.encoded, count, len(p.decoded))
+		if len(p.encoded) > 0 {
+			testEqual(t, "Decode(%q) = end %v, want %v", p.encoded, end, (p.encoded[len(p.encoded)-1] == '='))
+		}
+		testEqual(t, "Decode(%q) = %q, want %q", p.encoded,
+			string(dbuf[0:count]),
+			p.decoded)
+
+		dbuf, err = StdEncoding.DecodeString(p.encoded)
+		testEqual(t, "DecodeString(%q) = error %v, want %v", p.encoded, err, error(nil))
+		testEqual(t, "DecodeString(%q) = %q, want %q", p.encoded, string(dbuf), p.decoded)
+	}
+}
+
+func TestDecoder(t *testing.T) {
+	for _, p := range pairs {
+		decoder := NewDecoder(StdEncoding, strings.NewReader(p.encoded))
+		dbuf := make([]byte, StdEncoding.DecodedLen(len(p.encoded)))
+		count, err := decoder.Read(dbuf)
+		if err != nil && err != io.EOF {
+			t.Fatal("Read failed", err)
+		}
+		testEqual(t, "Read from %q = length %v, want %v", p.encoded, count, len(p.decoded))
+		testEqual(t, "Decoding of %q = %q, want %q", p.encoded, string(dbuf[0:count]), p.decoded)
+		if err != io.EOF {
+			count, err = decoder.Read(dbuf)
+		}
+		testEqual(t, "Read from %q = %v, want %v", p.encoded, err, io.EOF)
+	}
+}
+
+func TestDecoderBuffering(t *testing.T) {
+	for bs := 1; bs <= 12; bs++ {
+		decoder := NewDecoder(StdEncoding, strings.NewReader(bigtest.encoded))
+		buf := make([]byte, len(bigtest.decoded)+12)
+		var total int
+		for total = 0; total < len(bigtest.decoded); {
+			n, err := decoder.Read(buf[total : total+bs])
+			testEqual(t, "Read from %q at pos %d = %d, %v, want _, %v", bigtest.encoded, total, n, err, error(nil))
+			total += n
+		}
+		testEqual(t, "Decoding/%d of %q = %q, want %q", bs, bigtest.encoded, string(buf[0:total]), bigtest.decoded)
+	}
+}
+
+func TestDecodeCorrupt(t *testing.T) {
+	testCases := []struct {
+		input  string
+		offset int // -1 means no corruption.
+	}{
+		{"", -1},
+		{"!!!!", 0},
+		{"x===", 0},
+		{"AA=A====", 2},
+		{"AAA=AAAA", 3},
+		{"MMMMMMMMM", 8},
+		{"MMMMMM", 0},
+		{"A=", 1},
+		{"AA=", 3},
+		{"AA==", 4},
+		{"AA===", 5},
+		{"AAAA=", 5},
+		{"AAAA==", 6},
+		{"AAAAA=", 6},
+		{"AAAAA==", 7},
+		{"A=======", 1},
+		{"AA======", -1},
+		{"AAA=====", 3},
+		{"AAAA====", -1},
+		{"AAAAA===", -1},
+		{"AAAAAA==", 6},
+		{"AAAAAAA=", -1},
+		{"AAAAAAAA", -1},
+	}
+	for _, tc := range testCases {
+		dbuf := make([]byte, StdEncoding.DecodedLen(len(tc.input)))
+		_, err := StdEncoding.Decode(dbuf, []byte(tc.input))
+		if tc.offset == -1 {
+			if err != nil {
+				t.Error("Decoder wrongly detected coruption in", tc.input)
+			}
+			continue
+		}
+		switch err := err.(type) {
+		case CorruptInputError:
+			testEqual(t, "Corruption in %q at offset %v, want %v", tc.input, int(err), tc.offset)
+		default:
+			t.Error("Decoder failed to detect corruption in", tc)
+		}
+	}
+}
+
+func TestBig(t *testing.T) {
+	n := 3*1000 + 1
+	raw := make([]byte, n)
+	const alpha = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+	for i := 0; i < n; i++ {
+		raw[i] = alpha[i%len(alpha)]
+	}
+	encoded := new(bytes.Buffer)
+	w := NewEncoder(StdEncoding, encoded)
+	nn, err := w.Write(raw)
+	if nn != n || err != nil {
+		t.Fatalf("Encoder.Write(raw) = %d, %v want %d, nil", nn, err, n)
+	}
+	err = w.Close()
+	if err != nil {
+		t.Fatalf("Encoder.Close() = %v want nil", err)
+	}
+	decoded, err := ioutil.ReadAll(NewDecoder(StdEncoding, encoded))
+	if err != nil {
+		t.Fatalf("ioutil.ReadAll(NewDecoder(...)): %v", err)
+	}
+
+	if !bytes.Equal(raw, decoded) {
+		var i int
+		for i = 0; i < len(decoded) && i < len(raw); i++ {
+			if decoded[i] != raw[i] {
+				break
+			}
+		}
+		t.Errorf("Decode(Encode(%d-byte string)) failed at offset %d", n, i)
+	}
+}
+
+func testStringEncoding(t *testing.T, expected string, examples []string) {
+	for _, e := range examples {
+		buf, err := StdEncoding.DecodeString(e)
+		if err != nil {
+			t.Errorf("Decode(%q) failed: %v", e, err)
+			continue
+		}
+		if s := string(buf); s != expected {
+			t.Errorf("Decode(%q) = %q, want %q", e, s, expected)
+		}
+	}
+}
+
+func TestNewLineCharacters(t *testing.T) {
+	// Each of these should decode to the string "sure", without errors.
+	examples := []string{
+		"ON2XEZI=",
+		"ON2XEZI=\r",
+		"ON2XEZI=\n",
+		"ON2XEZI=\r\n",
+		"ON2XEZ\r\nI=",
+		"ON2X\rEZ\nI=",
+		"ON2X\nEZ\rI=",
+		"ON2XEZ\nI=",
+		"ON2XEZI\n=",
+	}
+	testStringEncoding(t, "sure", examples)
+
+	// Each of these should decode to the string "foobar", without errors.
+	examples = []string{
+		"MZXW6YTBOI======",
+		"MZXW6YTBOI=\r\n=====",
+	}
+	testStringEncoding(t, "foobar", examples)
+}
+
+func TestDecoderIssue4779(t *testing.T) {
+	encoded := `JRXXEZLNEBUXA43VNUQGI33MN5ZCA43JOQQGC3LFOQWCAY3PNZZWKY3UMV2HK4
+RAMFSGS4DJONUWG2LOM4QGK3DJOQWCA43FMQQGI3YKMVUXK43NN5SCA5DFNVYG64RANFXGG2LENFSH
+K3TUEB2XIIDMMFRG64TFEBSXIIDEN5WG64TFEBWWCZ3OMEQGC3DJOF2WCLRAKV2CAZLONFWQUYLEEB
+WWS3TJNUQHMZLONFQW2LBAOF2WS4ZANZXXG5DSOVSCAZLYMVZGG2LUMF2GS33OEB2WY3DBNVRW6IDM
+MFRG64TJOMQG42LTNEQHK5AKMFWGS4LVNFYCAZLYEBSWCIDDN5WW233EN4QGG33OONSXC5LBOQXCAR
+DVNFZSAYLVORSSA2LSOVZGKIDEN5WG64RANFXAU4TFOBZGK2DFNZSGK4TJOQQGS3RAOZXWY5LQORQX
+IZJAOZSWY2LUEBSXG43FEBRWS3DMOVWSAZDPNRXXEZJAMV2SAZTVM5UWC5BANZ2WY3DBBJYGC4TJMF
+2HK4ROEBCXQY3FOB2GK5LSEBZWS3TUEBXWGY3BMVRWC5BAMN2XA2LEMF2GC5BANZXW4IDQOJXWSZDF
+NZ2CYIDTOVXHIIDJNYFGG5LMOBQSA4LVNEQG6ZTGNFRWSYJAMRSXGZLSOVXHIIDNN5WGY2LUEBQW42
+LNEBUWIIDFON2CA3DBMJXXE5LNFY==
+====`
+	encodedShort := strings.Replace(encoded, "\n", "", -1)
+
+	dec := NewDecoder(StdEncoding, strings.NewReader(encoded))
+	res1, err := ioutil.ReadAll(dec)
+	if err != nil {
+		t.Errorf("ReadAll failed: %v", err)
+	}
+
+	dec = NewDecoder(StdEncoding, strings.NewReader(encodedShort))
+	var res2 []byte
+	res2, err = ioutil.ReadAll(dec)
+	if err != nil {
+		t.Errorf("ReadAll failed: %v", err)
+	}
+
+	if !bytes.Equal(res1, res2) {
+		t.Error("Decoded results not equal")
+	}
+}
+
+func BenchmarkEncodeToString(b *testing.B) {
+	data := make([]byte, 8192)
+	b.SetBytes(int64(len(data)))
+	for i := 0; i < b.N; i++ {
+		StdEncoding.EncodeToString(data)
+	}
+}
+
+func BenchmarkDecodeString(b *testing.B) {
+	data := StdEncoding.EncodeToString(make([]byte, 8192))
+	b.SetBytes(int64(len(data)))
+	for i := 0; i < b.N; i++ {
+		StdEncoding.DecodeString(data)
+	}
+}
diff --git a/src/pkg/encoding/base32/example_test.go b/src/encoding/base32/example_test.go
similarity index 100%
rename from src/pkg/encoding/base32/example_test.go
rename to src/encoding/base32/example_test.go
diff --git a/src/encoding/base64/base64.go b/src/encoding/base64/base64.go
new file mode 100644
index 0000000..ad3abe6
--- /dev/null
+++ b/src/encoding/base64/base64.go
@@ -0,0 +1,391 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package base64 implements base64 encoding as specified by RFC 4648.
+package base64
+
+import (
+	"bytes"
+	"io"
+	"strconv"
+	"strings"
+)
+
+/*
+ * Encodings
+ */
+
+// An Encoding is a radix 64 encoding/decoding scheme, defined by a
+// 64-character alphabet.  The most common encoding is the "base64"
+// encoding defined in RFC 4648 and used in MIME (RFC 2045) and PEM
+// (RFC 1421).  RFC 4648 also defines an alternate encoding, which is
+// the standard encoding with - and _ substituted for + and /.
+type Encoding struct {
+	encode    string
+	decodeMap [256]byte
+}
+
+const encodeStd = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
+const encodeURL = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"
+
+// NewEncoding returns a new Encoding defined by the given alphabet,
+// which must be a 64-byte string.
+func NewEncoding(encoder string) *Encoding {
+	e := new(Encoding)
+	e.encode = encoder
+	for i := 0; i < len(e.decodeMap); i++ {
+		e.decodeMap[i] = 0xFF
+	}
+	for i := 0; i < len(encoder); i++ {
+		e.decodeMap[encoder[i]] = byte(i)
+	}
+	return e
+}
+
+// StdEncoding is the standard base64 encoding, as defined in
+// RFC 4648.
+var StdEncoding = NewEncoding(encodeStd)
+
+// URLEncoding is the alternate base64 encoding defined in RFC 4648.
+// It is typically used in URLs and file names.
+var URLEncoding = NewEncoding(encodeURL)
+
+var removeNewlinesMapper = func(r rune) rune {
+	if r == '\r' || r == '\n' {
+		return -1
+	}
+	return r
+}
+
+/*
+ * Encoder
+ */
+
+// Encode encodes src using the encoding enc, writing
+// EncodedLen(len(src)) bytes to dst.
+//
+// The encoding pads the output to a multiple of 4 bytes,
+// so Encode is not appropriate for use on individual blocks
+// of a large data stream.  Use NewEncoder() instead.
+func (enc *Encoding) Encode(dst, src []byte) {
+	if len(src) == 0 {
+		return
+	}
+
+	for len(src) > 0 {
+		var b0, b1, b2, b3 byte
+
+		// Unpack 4x 6-bit source blocks into a 4 byte
+		// destination quantum
+		switch len(src) {
+		default:
+			b3 = src[2] & 0x3F
+			b2 = src[2] >> 6
+			fallthrough
+		case 2:
+			b2 |= (src[1] << 2) & 0x3F
+			b1 = src[1] >> 4
+			fallthrough
+		case 1:
+			b1 |= (src[0] << 4) & 0x3F
+			b0 = src[0] >> 2
+		}
+
+		// Encode 6-bit blocks using the base64 alphabet
+		dst[0] = enc.encode[b0]
+		dst[1] = enc.encode[b1]
+		dst[2] = enc.encode[b2]
+		dst[3] = enc.encode[b3]
+
+		// Pad the final quantum
+		if len(src) < 3 {
+			dst[3] = '='
+			if len(src) < 2 {
+				dst[2] = '='
+			}
+			break
+		}
+
+		src = src[3:]
+		dst = dst[4:]
+	}
+}
+
+// EncodeToString returns the base64 encoding of src.
+func (enc *Encoding) EncodeToString(src []byte) string {
+	buf := make([]byte, enc.EncodedLen(len(src)))
+	enc.Encode(buf, src)
+	return string(buf)
+}
+
+type encoder struct {
+	err  error
+	enc  *Encoding
+	w    io.Writer
+	buf  [3]byte    // buffered data waiting to be encoded
+	nbuf int        // number of bytes in buf
+	out  [1024]byte // output buffer
+}
+
+func (e *encoder) Write(p []byte) (n int, err error) {
+	if e.err != nil {
+		return 0, e.err
+	}
+
+	// Leading fringe.
+	if e.nbuf > 0 {
+		var i int
+		for i = 0; i < len(p) && e.nbuf < 3; i++ {
+			e.buf[e.nbuf] = p[i]
+			e.nbuf++
+		}
+		n += i
+		p = p[i:]
+		if e.nbuf < 3 {
+			return
+		}
+		e.enc.Encode(e.out[0:], e.buf[0:])
+		if _, e.err = e.w.Write(e.out[0:4]); e.err != nil {
+			return n, e.err
+		}
+		e.nbuf = 0
+	}
+
+	// Large interior chunks.
+	for len(p) >= 3 {
+		nn := len(e.out) / 4 * 3
+		if nn > len(p) {
+			nn = len(p)
+			nn -= nn % 3
+		}
+		e.enc.Encode(e.out[0:], p[0:nn])
+		if _, e.err = e.w.Write(e.out[0 : nn/3*4]); e.err != nil {
+			return n, e.err
+		}
+		n += nn
+		p = p[nn:]
+	}
+
+	// Trailing fringe.
+	for i := 0; i < len(p); i++ {
+		e.buf[i] = p[i]
+	}
+	e.nbuf = len(p)
+	n += len(p)
+	return
+}
+
+// Close flushes any pending output from the encoder.
+// It is an error to call Write after calling Close.
+func (e *encoder) Close() error {
+	// If there's anything left in the buffer, flush it out
+	if e.err == nil && e.nbuf > 0 {
+		e.enc.Encode(e.out[0:], e.buf[0:e.nbuf])
+		e.nbuf = 0
+		_, e.err = e.w.Write(e.out[0:4])
+	}
+	return e.err
+}
+
+// NewEncoder returns a new base64 stream encoder.  Data written to
+// the returned writer will be encoded using enc and then written to w.
+// Base64 encodings operate in 4-byte blocks; when finished
+// writing, the caller must Close the returned encoder to flush any
+// partially written blocks.
+func NewEncoder(enc *Encoding, w io.Writer) io.WriteCloser {
+	return &encoder{enc: enc, w: w}
+}
+
+// EncodedLen returns the length in bytes of the base64 encoding
+// of an input buffer of length n.
+func (enc *Encoding) EncodedLen(n int) int { return (n + 2) / 3 * 4 }
+
+/*
+ * Decoder
+ */
+
+type CorruptInputError int64
+
+func (e CorruptInputError) Error() string {
+	return "illegal base64 data at input byte " + strconv.FormatInt(int64(e), 10)
+}
+
+// decode is like Decode but returns an additional 'end' value, which
+// indicates if end-of-message padding was encountered and thus any
+// additional data is an error. This method assumes that src has been
+// stripped of all supported whitespace ('\r' and '\n').
+func (enc *Encoding) decode(dst, src []byte) (n int, end bool, err error) {
+	olen := len(src)
+	for len(src) > 0 && !end {
+		// Decode quantum using the base64 alphabet
+		var dbuf [4]byte
+		dlen := 4
+
+		for j := range dbuf {
+			if len(src) == 0 {
+				return n, false, CorruptInputError(olen - len(src) - j)
+			}
+			in := src[0]
+			src = src[1:]
+			if in == '=' {
+				// We've reached the end and there's padding
+				switch j {
+				case 0, 1:
+					// incorrect padding
+					return n, false, CorruptInputError(olen - len(src) - 1)
+				case 2:
+					// "==" is expected, the first "=" is already consumed.
+					if len(src) == 0 {
+						// not enough padding
+						return n, false, CorruptInputError(olen)
+					}
+					if src[0] != '=' {
+						// incorrect padding
+						return n, false, CorruptInputError(olen - len(src) - 1)
+					}
+					src = src[1:]
+				}
+				if len(src) > 0 {
+					// trailing garbage
+					err = CorruptInputError(olen - len(src))
+				}
+				dlen, end = j, true
+				break
+			}
+			dbuf[j] = enc.decodeMap[in]
+			if dbuf[j] == 0xFF {
+				return n, false, CorruptInputError(olen - len(src) - 1)
+			}
+		}
+
+		// Pack 4x 6-bit source blocks into 3 byte destination
+		// quantum
+		switch dlen {
+		case 4:
+			dst[2] = dbuf[2]<<6 | dbuf[3]
+			fallthrough
+		case 3:
+			dst[1] = dbuf[1]<<4 | dbuf[2]>>2
+			fallthrough
+		case 2:
+			dst[0] = dbuf[0]<<2 | dbuf[1]>>4
+		}
+		dst = dst[3:]
+		n += dlen - 1
+	}
+
+	return n, end, err
+}
+
+// Decode decodes src using the encoding enc.  It writes at most
+// DecodedLen(len(src)) bytes to dst and returns the number of bytes
+// written.  If src contains invalid base64 data, it will return the
+// number of bytes successfully written and CorruptInputError.
+// New line characters (\r and \n) are ignored.
+func (enc *Encoding) Decode(dst, src []byte) (n int, err error) {
+	src = bytes.Map(removeNewlinesMapper, src)
+	n, _, err = enc.decode(dst, src)
+	return
+}
+
+// DecodeString returns the bytes represented by the base64 string s.
+func (enc *Encoding) DecodeString(s string) ([]byte, error) {
+	s = strings.Map(removeNewlinesMapper, s)
+	dbuf := make([]byte, enc.DecodedLen(len(s)))
+	n, _, err := enc.decode(dbuf, []byte(s))
+	return dbuf[:n], err
+}
+
+type decoder struct {
+	err    error
+	enc    *Encoding
+	r      io.Reader
+	end    bool       // saw end of message
+	buf    [1024]byte // leftover input
+	nbuf   int
+	out    []byte // leftover decoded output
+	outbuf [1024 / 4 * 3]byte
+}
+
+func (d *decoder) Read(p []byte) (n int, err error) {
+	if d.err != nil {
+		return 0, d.err
+	}
+
+	// Use leftover decoded output from last read.
+	if len(d.out) > 0 {
+		n = copy(p, d.out)
+		d.out = d.out[n:]
+		return n, nil
+	}
+
+	// Read a chunk.
+	nn := len(p) / 3 * 4
+	if nn < 4 {
+		nn = 4
+	}
+	if nn > len(d.buf) {
+		nn = len(d.buf)
+	}
+	nn, d.err = io.ReadAtLeast(d.r, d.buf[d.nbuf:nn], 4-d.nbuf)
+	d.nbuf += nn
+	if d.err != nil || d.nbuf < 4 {
+		return 0, d.err
+	}
+
+	// Decode chunk into p, or d.out and then p if p is too small.
+	nr := d.nbuf / 4 * 4
+	nw := d.nbuf / 4 * 3
+	if nw > len(p) {
+		nw, d.end, d.err = d.enc.decode(d.outbuf[0:], d.buf[0:nr])
+		d.out = d.outbuf[0:nw]
+		n = copy(p, d.out)
+		d.out = d.out[n:]
+	} else {
+		n, d.end, d.err = d.enc.decode(p, d.buf[0:nr])
+	}
+	d.nbuf -= nr
+	for i := 0; i < d.nbuf; i++ {
+		d.buf[i] = d.buf[i+nr]
+	}
+
+	if d.err == nil {
+		d.err = err
+	}
+	return n, d.err
+}
+
+type newlineFilteringReader struct {
+	wrapped io.Reader
+}
+
+func (r *newlineFilteringReader) Read(p []byte) (int, error) {
+	n, err := r.wrapped.Read(p)
+	for n > 0 {
+		offset := 0
+		for i, b := range p[0:n] {
+			if b != '\r' && b != '\n' {
+				if i != offset {
+					p[offset] = b
+				}
+				offset++
+			}
+		}
+		if offset > 0 {
+			return offset, err
+		}
+		// Previous buffer entirely whitespace, read again
+		n, err = r.wrapped.Read(p)
+	}
+	return n, err
+}
+
+// NewDecoder constructs a new base64 stream decoder.
+func NewDecoder(enc *Encoding, r io.Reader) io.Reader {
+	return &decoder{enc: enc, r: &newlineFilteringReader{r}}
+}
+
+// DecodedLen returns the maximum length in bytes of the decoded data
+// corresponding to n bytes of base64-encoded data.
+func (enc *Encoding) DecodedLen(n int) int { return n / 4 * 3 }
diff --git a/src/encoding/base64/base64_test.go b/src/encoding/base64/base64_test.go
new file mode 100644
index 0000000..7d199bf
--- /dev/null
+++ b/src/encoding/base64/base64_test.go
@@ -0,0 +1,360 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package base64
+
+import (
+	"bytes"
+	"errors"
+	"io"
+	"io/ioutil"
+	"reflect"
+	"strings"
+	"testing"
+	"time"
+)
+
+type testpair struct {
+	decoded, encoded string
+}
+
+var pairs = []testpair{
+	// RFC 3548 examples
+	{"\x14\xfb\x9c\x03\xd9\x7e", "FPucA9l+"},
+	{"\x14\xfb\x9c\x03\xd9", "FPucA9k="},
+	{"\x14\xfb\x9c\x03", "FPucAw=="},
+
+	// RFC 4648 examples
+	{"", ""},
+	{"f", "Zg=="},
+	{"fo", "Zm8="},
+	{"foo", "Zm9v"},
+	{"foob", "Zm9vYg=="},
+	{"fooba", "Zm9vYmE="},
+	{"foobar", "Zm9vYmFy"},
+
+	// Wikipedia examples
+	{"sure.", "c3VyZS4="},
+	{"sure", "c3VyZQ=="},
+	{"sur", "c3Vy"},
+	{"su", "c3U="},
+	{"leasure.", "bGVhc3VyZS4="},
+	{"easure.", "ZWFzdXJlLg=="},
+	{"asure.", "YXN1cmUu"},
+	{"sure.", "c3VyZS4="},
+}
+
+var bigtest = testpair{
+	"Twas brillig, and the slithy toves",
+	"VHdhcyBicmlsbGlnLCBhbmQgdGhlIHNsaXRoeSB0b3Zlcw==",
+}
+
+func testEqual(t *testing.T, msg string, args ...interface{}) bool {
+	if args[len(args)-2] != args[len(args)-1] {
+		t.Errorf(msg, args...)
+		return false
+	}
+	return true
+}
+
+func TestEncode(t *testing.T) {
+	for _, p := range pairs {
+		got := StdEncoding.EncodeToString([]byte(p.decoded))
+		testEqual(t, "Encode(%q) = %q, want %q", p.decoded, got, p.encoded)
+	}
+}
+
+func TestEncoder(t *testing.T) {
+	for _, p := range pairs {
+		bb := &bytes.Buffer{}
+		encoder := NewEncoder(StdEncoding, bb)
+		encoder.Write([]byte(p.decoded))
+		encoder.Close()
+		testEqual(t, "Encode(%q) = %q, want %q", p.decoded, bb.String(), p.encoded)
+	}
+}
+
+func TestEncoderBuffering(t *testing.T) {
+	input := []byte(bigtest.decoded)
+	for bs := 1; bs <= 12; bs++ {
+		bb := &bytes.Buffer{}
+		encoder := NewEncoder(StdEncoding, bb)
+		for pos := 0; pos < len(input); pos += bs {
+			end := pos + bs
+			if end > len(input) {
+				end = len(input)
+			}
+			n, err := encoder.Write(input[pos:end])
+			testEqual(t, "Write(%q) gave error %v, want %v", input[pos:end], err, error(nil))
+			testEqual(t, "Write(%q) gave length %v, want %v", input[pos:end], n, end-pos)
+		}
+		err := encoder.Close()
+		testEqual(t, "Close gave error %v, want %v", err, error(nil))
+		testEqual(t, "Encoding/%d of %q = %q, want %q", bs, bigtest.decoded, bb.String(), bigtest.encoded)
+	}
+}
+
+func TestDecode(t *testing.T) {
+	for _, p := range pairs {
+		dbuf := make([]byte, StdEncoding.DecodedLen(len(p.encoded)))
+		count, end, err := StdEncoding.decode(dbuf, []byte(p.encoded))
+		testEqual(t, "Decode(%q) = error %v, want %v", p.encoded, err, error(nil))
+		testEqual(t, "Decode(%q) = length %v, want %v", p.encoded, count, len(p.decoded))
+		if len(p.encoded) > 0 {
+			testEqual(t, "Decode(%q) = end %v, want %v", p.encoded, end, (p.encoded[len(p.encoded)-1] == '='))
+		}
+		testEqual(t, "Decode(%q) = %q, want %q", p.encoded, string(dbuf[0:count]), p.decoded)
+
+		dbuf, err = StdEncoding.DecodeString(p.encoded)
+		testEqual(t, "DecodeString(%q) = error %v, want %v", p.encoded, err, error(nil))
+		testEqual(t, "DecodeString(%q) = %q, want %q", string(dbuf), p.decoded)
+	}
+}
+
+func TestDecoder(t *testing.T) {
+	for _, p := range pairs {
+		decoder := NewDecoder(StdEncoding, strings.NewReader(p.encoded))
+		dbuf := make([]byte, StdEncoding.DecodedLen(len(p.encoded)))
+		count, err := decoder.Read(dbuf)
+		if err != nil && err != io.EOF {
+			t.Fatal("Read failed", err)
+		}
+		testEqual(t, "Read from %q = length %v, want %v", p.encoded, count, len(p.decoded))
+		testEqual(t, "Decoding of %q = %q, want %q", p.encoded, string(dbuf[0:count]), p.decoded)
+		if err != io.EOF {
+			count, err = decoder.Read(dbuf)
+		}
+		testEqual(t, "Read from %q = %v, want %v", p.encoded, err, io.EOF)
+	}
+}
+
+func TestDecoderBuffering(t *testing.T) {
+	for bs := 1; bs <= 12; bs++ {
+		decoder := NewDecoder(StdEncoding, strings.NewReader(bigtest.encoded))
+		buf := make([]byte, len(bigtest.decoded)+12)
+		var total int
+		for total = 0; total < len(bigtest.decoded); {
+			n, err := decoder.Read(buf[total : total+bs])
+			testEqual(t, "Read from %q at pos %d = %d, %v, want _, %v", bigtest.encoded, total, n, err, error(nil))
+			total += n
+		}
+		testEqual(t, "Decoding/%d of %q = %q, want %q", bs, bigtest.encoded, string(buf[0:total]), bigtest.decoded)
+	}
+}
+
+func TestDecodeCorrupt(t *testing.T) {
+	testCases := []struct {
+		input  string
+		offset int // -1 means no corruption.
+	}{
+		{"", -1},
+		{"!!!!", 0},
+		{"====", 0},
+		{"x===", 1},
+		{"=AAA", 0},
+		{"A=AA", 1},
+		{"AA=A", 2},
+		{"AA==A", 4},
+		{"AAA=AAAA", 4},
+		{"AAAAA", 4},
+		{"AAAAAA", 4},
+		{"A=", 1},
+		{"A==", 1},
+		{"AA=", 3},
+		{"AA==", -1},
+		{"AAA=", -1},
+		{"AAAA", -1},
+		{"AAAAAA=", 7},
+		{"YWJjZA=====", 8},
+	}
+	for _, tc := range testCases {
+		dbuf := make([]byte, StdEncoding.DecodedLen(len(tc.input)))
+		_, err := StdEncoding.Decode(dbuf, []byte(tc.input))
+		if tc.offset == -1 {
+			if err != nil {
+				t.Error("Decoder wrongly detected coruption in", tc.input)
+			}
+			continue
+		}
+		switch err := err.(type) {
+		case CorruptInputError:
+			testEqual(t, "Corruption in %q at offset %v, want %v", tc.input, int(err), tc.offset)
+		default:
+			t.Error("Decoder failed to detect corruption in", tc)
+		}
+	}
+}
+
+func TestBig(t *testing.T) {
+	n := 3*1000 + 1
+	raw := make([]byte, n)
+	const alpha = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+	for i := 0; i < n; i++ {
+		raw[i] = alpha[i%len(alpha)]
+	}
+	encoded := new(bytes.Buffer)
+	w := NewEncoder(StdEncoding, encoded)
+	nn, err := w.Write(raw)
+	if nn != n || err != nil {
+		t.Fatalf("Encoder.Write(raw) = %d, %v want %d, nil", nn, err, n)
+	}
+	err = w.Close()
+	if err != nil {
+		t.Fatalf("Encoder.Close() = %v want nil", err)
+	}
+	decoded, err := ioutil.ReadAll(NewDecoder(StdEncoding, encoded))
+	if err != nil {
+		t.Fatalf("ioutil.ReadAll(NewDecoder(...)): %v", err)
+	}
+
+	if !bytes.Equal(raw, decoded) {
+		var i int
+		for i = 0; i < len(decoded) && i < len(raw); i++ {
+			if decoded[i] != raw[i] {
+				break
+			}
+		}
+		t.Errorf("Decode(Encode(%d-byte string)) failed at offset %d", n, i)
+	}
+}
+
+func TestNewLineCharacters(t *testing.T) {
+	// Each of these should decode to the string "sure", without errors.
+	const expected = "sure"
+	examples := []string{
+		"c3VyZQ==",
+		"c3VyZQ==\r",
+		"c3VyZQ==\n",
+		"c3VyZQ==\r\n",
+		"c3VyZ\r\nQ==",
+		"c3V\ryZ\nQ==",
+		"c3V\nyZ\rQ==",
+		"c3VyZ\nQ==",
+		"c3VyZQ\n==",
+		"c3VyZQ=\n=",
+		"c3VyZQ=\r\n\r\n=",
+	}
+	for _, e := range examples {
+		buf, err := StdEncoding.DecodeString(e)
+		if err != nil {
+			t.Errorf("Decode(%q) failed: %v", e, err)
+			continue
+		}
+		if s := string(buf); s != expected {
+			t.Errorf("Decode(%q) = %q, want %q", e, s, expected)
+		}
+	}
+}
+
+type nextRead struct {
+	n   int   // bytes to return
+	err error // error to return
+}
+
+// faultInjectReader returns data from source, rate-limited
+// and with the errors as written to nextc.
+type faultInjectReader struct {
+	source string
+	nextc  <-chan nextRead
+}
+
+func (r *faultInjectReader) Read(p []byte) (int, error) {
+	nr := <-r.nextc
+	if len(p) > nr.n {
+		p = p[:nr.n]
+	}
+	n := copy(p, r.source)
+	r.source = r.source[n:]
+	return n, nr.err
+}
+
+// tests that we don't ignore errors from our underlying reader
+func TestDecoderIssue3577(t *testing.T) {
+	next := make(chan nextRead, 10)
+	wantErr := errors.New("my error")
+	next <- nextRead{5, nil}
+	next <- nextRead{10, wantErr}
+	next <- nextRead{0, wantErr}
+	d := NewDecoder(StdEncoding, &faultInjectReader{
+		source: "VHdhcyBicmlsbGlnLCBhbmQgdGhlIHNsaXRoeSB0b3Zlcw==", // twas brillig...
+		nextc:  next,
+	})
+	errc := make(chan error)
+	go func() {
+		_, err := ioutil.ReadAll(d)
+		errc <- err
+	}()
+	select {
+	case err := <-errc:
+		if err != wantErr {
+			t.Errorf("got error %v; want %v", err, wantErr)
+		}
+	case <-time.After(5 * time.Second):
+		t.Errorf("timeout; Decoder blocked without returning an error")
+	}
+}
+
+func TestDecoderIssue4779(t *testing.T) {
+	encoded := `CP/EAT8AAAEF
+AQEBAQEBAAAAAAAAAAMAAQIEBQYHCAkKCwEAAQUBAQEBAQEAAAAAAAAAAQACAwQFBgcICQoLEAAB
+BAEDAgQCBQcGCAUDDDMBAAIRAwQhEjEFQVFhEyJxgTIGFJGhsUIjJBVSwWIzNHKC0UMHJZJT8OHx
+Y3M1FqKygyZEk1RkRcKjdDYX0lXiZfKzhMPTdePzRieUpIW0lcTU5PSltcXV5fVWZnaGlqa2xtbm
+9jdHV2d3h5ent8fX5/cRAAICAQIEBAMEBQYHBwYFNQEAAhEDITESBEFRYXEiEwUygZEUobFCI8FS
+0fAzJGLhcoKSQ1MVY3M08SUGFqKygwcmNcLSRJNUoxdkRVU2dGXi8rOEw9N14/NGlKSFtJXE1OT0
+pbXF1eX1VmZ2hpamtsbW5vYnN0dXZ3eHl6e3x//aAAwDAQACEQMRAD8A9VSSSSUpJJJJSkkkJ+Tj
+1kiy1jCJJDnAcCTykpKkuQ6p/jN6FgmxlNduXawwAzaGH+V6jn/R/wCt71zdn+N/qL3kVYFNYB4N
+ji6PDVjWpKp9TSXnvTf8bFNjg3qOEa2n6VlLpj/rT/pf567DpX1i6L1hs9Py67X8mqdtg/rUWbbf
++gkp0kkkklKSSSSUpJJJJT//0PVUkkklKVLq3WMDpGI7KzrNjADtYNXvI/Mqr/Pd/q9W3vaxjnvM
+NaCXE9gNSvGPrf8AWS3qmba5jjsJhoB0DAf0NDf6sevf+/lf8Hj0JJATfWT6/dV6oXU1uOLQeKKn
+EQP+Hubtfe/+R7Mf/g7f5xcocp++Z11JMCJPgFBxOg7/AOuqDx8I/ikpkXkmSdU8mJIJA/O8EMAy
+j+mSARB/17pKVXYWHXjsj7yIex0PadzXMO1zT5KHoNA3HT8ietoGhgjsfA+CSnvvqh/jJtqsrwOv
+2b6NGNzXfTYexzJ+nU7/ALkf4P8Awv6P9KvTQQ4AgyDqCF85Pho3CTB7eHwXoH+LT65uZbX9X+o2
+bqbPb06551Y4
+`
+	encodedShort := strings.Replace(encoded, "\n", "", -1)
+
+	dec := NewDecoder(StdEncoding, strings.NewReader(encoded))
+	res1, err := ioutil.ReadAll(dec)
+	if err != nil {
+		t.Errorf("ReadAll failed: %v", err)
+	}
+
+	dec = NewDecoder(StdEncoding, strings.NewReader(encodedShort))
+	var res2 []byte
+	res2, err = ioutil.ReadAll(dec)
+	if err != nil {
+		t.Errorf("ReadAll failed: %v", err)
+	}
+
+	if !bytes.Equal(res1, res2) {
+		t.Error("Decoded results not equal")
+	}
+}
+
+func TestDecoderIssue7733(t *testing.T) {
+	s, err := StdEncoding.DecodeString("YWJjZA=====")
+	want := CorruptInputError(8)
+	if !reflect.DeepEqual(want, err) {
+		t.Errorf("Error = %v; want CorruptInputError(8)", err)
+	}
+	if string(s) != "abcd" {
+		t.Errorf("DecodeString = %q; want abcd", s)
+	}
+}
+
+func BenchmarkEncodeToString(b *testing.B) {
+	data := make([]byte, 8192)
+	b.SetBytes(int64(len(data)))
+	for i := 0; i < b.N; i++ {
+		StdEncoding.EncodeToString(data)
+	}
+}
+
+func BenchmarkDecodeString(b *testing.B) {
+	data := StdEncoding.EncodeToString(make([]byte, 8192))
+	b.SetBytes(int64(len(data)))
+	for i := 0; i < b.N; i++ {
+		StdEncoding.DecodeString(data)
+	}
+}
diff --git a/src/pkg/encoding/base64/example_test.go b/src/encoding/base64/example_test.go
similarity index 100%
rename from src/pkg/encoding/base64/example_test.go
rename to src/encoding/base64/example_test.go
diff --git a/src/encoding/binary/binary.go b/src/encoding/binary/binary.go
new file mode 100644
index 0000000..466bf97
--- /dev/null
+++ b/src/encoding/binary/binary.go
@@ -0,0 +1,634 @@
+// Copyright 2009 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package binary implements simple translation between numbers and byte
+// sequences and encoding and decoding of varints.
+//
+// Numbers are translated by reading and writing fixed-size values.
+// A fixed-size value is either a fixed-size arithmetic
+// type (int8, uint8, int16, float32, complex64, ...)
+// or an array or struct containing only fixed-size values.
+//
+// The varint functions encode and decode single integer values using
+// a variable-length encoding; smaller values require fewer bytes.
+// For a specification, see
+// http://code.google.com/apis/protocolbuffers/docs/encoding.html.
+//
+// This package favors simplicity over efficiency. Clients that require
+// high-performance serialization, especially for large data structures,
+// should look at more advanced solutions such as the encoding/gob
+// package or protocol buffers.
+package binary
+
+import (
+	"errors"
+	"io"
+	"math"
+	"reflect"
+)
+
+// A ByteOrder specifies how to convert byte sequences into
+// 16-, 32-, or 64-bit unsigned integers.
+type ByteOrder interface {
+	Uint16([]byte) uint16
+	Uint32([]byte) uint32
+	Uint64([]byte) uint64
+	PutUint16([]byte, uint16)
+	PutUint32([]byte, uint32)
+	PutUint64([]byte, uint64)
+	String() string
+}
+
+// LittleEndian is the little-endian implementation of ByteOrder.
+var LittleEndian littleEndian
+
+// BigEndian is the big-endian implementation of ByteOrder.
+var BigEndian bigEndian
+
+type littleEndian struct{}
+
+func (littleEndian) Uint16(b []byte) uint16 { return uint16(b[0]) | uint16(b[1])<<8 }
+
+func (littleEndian) PutUint16(b []byte, v uint16) {
+	b[0] = byte(v)
+	b[1] = byte(v >> 8)
+}
+
+func (littleEndian) Uint32(b []byte) uint32 {
+	return uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24
+}
+
+func (littleEndian) PutUint32(b []byte, v uint32) {
+	b[0] = byte(v)
+	b[1] = byte(v >> 8)
+	b[2] = byte(v >> 16)
+	b[3] = byte(v >> 24)
+}
+
+func (littleEndian) Uint64(b []byte) uint64 {
+	return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 |
+		uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56
+}
+
+func (littleEndian) PutUint64(b []byte, v uint64) {
+	b[0] = byte(v)
+	b[1] = byte(v >> 8)
+	b[2] = byte(v >> 16)
+	b[3] = byte(v >> 24)
+	b[4] = byte(v >> 32)
+	b[5] = byte(v >> 40)
+	b[6] = byte(v >> 48)
+	b[7] = byte(v >> 56)
+}
+
+func (littleEndian) String() string { return "LittleEndian" }
+
+func (littleEndian) GoString() string { return "binary.LittleEndian" }
+
+type bigEndian struct{}
+
+func (bigEndian) Uint16(b []byte) uint16 { return uint16(b[1]) | uint16(b[0])<<8 }
+
+func (bigEndian) PutUint16(b []byte, v uint16) {
+	b[0] = byte(v >> 8)
+	b[1] = byte(v)
+}
+
+func (bigEndian) Uint32(b []byte) uint32 {
+	return uint32(b[3]) | uint32(b[2])<<8 | uint32(b[1])<<16 | uint32(b[0])<<24
+}
+
+func (bigEndian) PutUint32(b []byte, v uint32) {
+	b[0] = byte(v >> 24)
+	b[1] = byte(v >> 16)
+	b[2] = byte(v >> 8)
+	b[3] = byte(v)
+}
+
+func (bigEndian) Uint64(b []byte) uint64 {
+	return uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 |
+		uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56
+}
+
+func (bigEndian) PutUint64(b []byte, v uint64) {
+	b[0] = byte(v >> 56)
+	b[1] = byte(v >> 48)
+	b[2] = byte(v >> 40)
+	b[3] = byte(v >> 32)
+	b[4] = byte(v >> 24)
+	b[5] = byte(v >> 16)
+	b[6] = byte(v >> 8)
+	b[7] = byte(v)
+}
+
+func (bigEndian) String() string { return "BigEndian" }
+
+func (bigEndian) GoString() string { return "binary.BigEndian" }
+
+// Read reads structured binary data from r into data.
+// Data must be a pointer to a fixed-size value or a slice
+// of fixed-size values.
+// Bytes read from r are decoded using the specified byte order
+// and written to successive fields of the data.
+// When reading into structs, the field data for fields with
+// blank (_) field names is skipped; i.e., blank field names
+// may be used for padding.
+// When reading into a struct, all non-blank fields must be exported.
+func Read(r io.Reader, order ByteOrder, data interface{}) error {
+	// Fast path for basic types and slices.
+	if n := intDataSize(data); n != 0 {
+		var b [8]byte
+		var bs []byte
+		if n > len(b) {
+			bs = make([]byte, n)
+		} else {
+			bs = b[:n]
+		}
+		if _, err := io.ReadFull(r, bs); err != nil {
+			return err
+		}
+		switch data := data.(type) {
+		case *int8:
+			*data = int8(b[0])
+		case *uint8:
+			*data = b[0]
+		case *int16:
+			*data = int16(order.Uint16(bs))
+		case *uint16:
+			*data = order.Uint16(bs)
+		case *int32:
+			*data = int32(order.Uint32(bs))
+		case *uint32:
+			*data = order.Uint32(bs)
+		case *int64:
+			*data = int64(order.Uint64(bs))
+		case *uint64:
+			*data = order.Uint64(bs)
+		case []int8:
+			for i, x := range bs { // Easier to loop over the input for 8-bit values.
+				data[i] = int8(x)
+			}
+		case []uint8:
+			copy(data, bs)
+		case []int16:
+			for i := range data {
+				data[i] = int16(order.Uint16(bs[2*i:]))
+			}
+		case []uint16:
+			for i := range data {
+				data[i] = order.Uint16(bs[2*i:])
+			}
+		case []int32:
+			for i := range data {
+				data[i] = int32(order.Uint32(bs[4*i:]))
+			}
+		case []uint32:
+			for i := range data {
+				data[i] = order.Uint32(bs[4*i:])
+			}
+		case []int64:
+			for i := range data {
+				data[i] = int64(order.Uint64(bs[8*i:]))
+			}
+		case []uint64:
+			for i := range data {
+				data[i] = order.Uint64(bs[8*i:])
+			}
+		}
+		return nil
+	}
+
+	// Fallback to reflect-based decoding.
+	v := reflect.ValueOf(data)
+	size := -1
+	switch v.Kind() {
+	case reflect.Ptr:
+		v = v.Elem()
+		size = dataSize(v)
+	case reflect.Slice:
+		size = dataSize(v)
+	}
+	if size < 0 {
+		return errors.New("binary.Read: invalid type " + reflect.TypeOf(data).String())
+	}
+	d := &decoder{order: order, buf: make([]byte, size)}
+	if _, err := io.ReadFull(r, d.buf); err != nil {
+		return err
+	}
+	d.value(v)
+	return nil
+}
+
+// Write writes the binary representation of data into w.
+// Data must be a fixed-size value or a slice of fixed-size
+// values, or a pointer to such data.
+// Bytes written to w are encoded using the specified byte order
+// and read from successive fields of the data.
+// When writing structs, zero values are written for fields
+// with blank (_) field names.
+func Write(w io.Writer, order ByteOrder, data interface{}) error {
+	// Fast path for basic types and slices.
+	if n := intDataSize(data); n != 0 {
+		var b [8]byte
+		var bs []byte
+		if n > len(b) {
+			bs = make([]byte, n)
+		} else {
+			bs = b[:n]
+		}
+		switch v := data.(type) {
+		case *int8:
+			bs = b[:1]
+			b[0] = byte(*v)
+		case int8:
+			bs = b[:1]
+			b[0] = byte(v)
+		case []int8:
+			for i, x := range v {
+				bs[i] = byte(x)
+			}
+		case *uint8:
+			bs = b[:1]
+			b[0] = *v
+		case uint8:
+			bs = b[:1]
+			b[0] = byte(v)
+		case []uint8:
+			bs = v
+		case *int16:
+			bs = b[:2]
+			order.PutUint16(bs, uint16(*v))
+		case int16:
+			bs = b[:2]
+			order.PutUint16(bs, uint16(v))
+		case []int16:
+			for i, x := range v {
+				order.PutUint16(bs[2*i:], uint16(x))
+			}
+		case *uint16:
+			bs = b[:2]
+			order.PutUint16(bs, *v)
+		case uint16:
+			bs = b[:2]
+			order.PutUint16(bs, v)
+		case []uint16:
+			for i, x := range v {
+				order.PutUint16(bs[2*i:], x)
+			}
+		case *int32:
+			bs = b[:4]
+			order.PutUint32(bs, uint32(*v))
+		case int32:
+			bs = b[:4]
+			order.PutUint32(bs, uint32(v))
+		case []int32:
+			for i, x := range v {
+				order.PutUint32(bs[4*i:], uint32(x))
+			}
+		case *uint32:
+			bs = b[:4]
+			order.PutUint32(bs, *v)
+		case uint32:
+			bs = b[:4]
+			order.PutUint32(bs, v)
+		case []uint32:
+			for i, x := range v {
+				order.PutUint32(bs[4*i:], x)
+			}
+		case *int64:
+			bs = b[:8]
+			order.PutUint64(bs, uint64(*v))
+		case int64:
+			bs = b[:8]
+			order.PutUint64(bs, uint64(v))
+		case []int64:
+			for i, x := range v {
+				order.PutUint64(bs[8*i:], uint64(x))
+			}
+		case *uint64:
+			bs = b[:8]
+			order.PutUint64(bs, *v)
+		case uint64:
+			bs = b[:8]
+			order.PutUint64(bs, v)
+		case []uint64:
+			for i, x := range v {
+				order.PutUint64(bs[8*i:], x)
+			}
+		}
+		_, err := w.Write(bs)
+		return err
+	}
+
+	// Fallback to reflect-based encoding.
+	v := reflect.Indirect(reflect.ValueOf(data))
+	size := dataSize(v)
+	if size < 0 {
+		return errors.New("binary.Write: invalid type " + reflect.TypeOf(data).String())
+	}
+	buf := make([]byte, size)
+	e := &encoder{order: order, buf: buf}
+	e.value(v)
+	_, err := w.Write(buf)
+	return err
+}
+
+// Size returns how many bytes Write would generate to encode the value v, which
+// must be a fixed-size value or a slice of fixed-size values, or a pointer to such data.
+// If v is neither of these, Size returns -1.
+func Size(v interface{}) int {
+	return dataSize(reflect.Indirect(reflect.ValueOf(v)))
+}
+
+// dataSize returns the number of bytes the actual data represented by v occupies in memory.
+// For compound structures, it sums the sizes of the elements. Thus, for instance, for a slice
+// it returns the length of the slice times the element size and does not count the memory
+// occupied by the header. If the type of v is not acceptable, dataSize returns -1.
+func dataSize(v reflect.Value) int {
+	if v.Kind() == reflect.Slice {
+		if s := sizeof(v.Type().Elem()); s >= 0 {
+			return s * v.Len()
+		}
+		return -1
+	}
+	return sizeof(v.Type())
+}
+
+// sizeof returns the size >= 0 of variables for the given type or -1 if the type is not acceptable.
+func sizeof(t reflect.Type) int {
+	switch t.Kind() {
+	case reflect.Array:
+		if s := sizeof(t.Elem()); s >= 0 {
+			return s * t.Len()
+		}
+
+	case reflect.Struct:
+		sum := 0
+		for i, n := 0, t.NumField(); i < n; i++ {
+			s := sizeof(t.Field(i).Type)
+			if s < 0 {
+				return -1
+			}
+			sum += s
+		}
+		return sum
+
+	case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
+		reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
+		reflect.Float32, reflect.Float64, reflect.Complex64, reflect.Complex128:
+		return int(t.Size())
+	}
+
+	return -1
+}
+
+type coder struct {
+	order ByteOrder
+	buf   []byte
+}
+
+type decoder coder
+type encoder coder
+
+func (d *decoder) uint8() uint8 {
+	x := d.buf[0]
+	d.buf = d.buf[1:]
+	return x
+}
+
+func (e *encoder) uint8(x uint8) {
+	e.buf[0] = x
+	e.buf = e.buf[1:]
+}
+
+func (d *decoder) uint16() uint16 {
+	x := d.order.Uint16(d.buf[0:2])
+	d.buf = d.buf[2:]
+	return x
+}
+
+func (e *encoder) uint16(x uint16) {
+	e.order.PutUint16(e.buf[0:2], x)
+	e.buf = e.buf[2:]
+}
+
+func (d *decoder) uint32() uint32 {
+	x := d.order.Uint32(d.buf[0:4])
+	d.buf = d.buf[4:]
+	return x
+}
+
+func (e *encoder) uint32(x uint32) {
+	e.order.PutUint32(e.buf[0:4], x)
+	e.buf = e.buf[4:]
+}
+
+func (d *decoder) uint64() uint64 {
+	x := d.order.Uint64(d.buf[0:8])
+	d.buf = d.buf[8:]
+	return x
+}
+
+func (e *encoder) uint64(x uint64) {
+	e.order.PutUint64(e.buf[0:8], x)
+	e.buf = e.buf[8:]
+}
+
+func (d *decoder) int8() int8 { return int8(d.uint8()) }
+
+func (e *encoder) int8(x int8) { e.uint8(uint8(x)) }
+
+func (d *decoder) int16() int16 { return int16(d.uint16()) }
+
+func (e *encoder) int16(x int16) { e.uint16(uint16(x)) }
+
+func (d *decoder) int32() int32 { return int32(d.uint32()) }
+
+func (e *encoder) int32(x int32) { e.uint32(uint32(x)) }
+
+func (d *decoder) int64() int64 { return int64(d.uint64()) }
+
+func (e *encoder) int64(x int64) { e.uint64(uint64(x)) }
+
+func (d *decoder) value(v reflect.Value) {
+	switch v.Kind() {
+	case reflect.Array:
+		l := v.Len()
+		for i := 0; i < l; i++ {
+			d.value(v.Index(i))
+		}
+
+	case reflect.Struct:
+		t := v.Type()
+		l := v.NumField()
+		for i := 0; i < l; i++ {
+			// Note: Calling v.CanSet() below is an optimization.
+			// It would be sufficient to check the field name,
+			// but creating the StructField info for each field is
+			// costly (run "go test -bench=ReadStruct" and compare
+			// results when making changes to this code).
+			if v := v.Field(i); v.CanSet() || t.Field(i).Name != "_" {
+				d.value(v)
+			} else {
+				d.skip(v)
+			}
+		}
+
+	case reflect.Slice:
+		l := v.Len()
+		for i := 0; i < l; i++ {
+			d.value(v.Index(i))
+		}
+
+	case reflect.Int8:
+		v.SetInt(int64(d.int8()))
+	case reflect.Int16:
+		v.SetInt(int64(d.int16()))
+	case reflect.Int32:
+		v.SetInt(int64(d.int32()))
+	case reflect.Int64:
+		v.SetInt(d.int64())
+
+	case reflect.Uint8:
+		v.SetUint(uint64(d.uint8()))
+	case reflect.Uint16:
+		v.SetUint(uint64(d.uint16()))
+	case reflect.Uint32:
+		v.SetUint(uint64(d.uint32()))
+	case reflect.Uint64:
+		v.SetUint(d.uint64())
+
+	case reflect.Float32:
+		v.SetFloat(float64(math.Float32frombits(d.uint32())))
+	case reflect.Float64:
+		v.SetFloat(math.Float64frombits(d.uint64()))
+
+	case reflect.Complex64:
+		v.SetComplex(complex(
+			float64(math.Float32frombits(d.uint32())),
+			float64(math.Float32frombits(d.uint32())),
+		))
+	case reflect.Complex128:
+		v.SetComplex(complex(
+			math.Float64frombits(d.uint64()),
+			math.Float64frombits(d.uint64()),
+		))
+	}
+}
+
+func (e *encoder) value(v reflect.Value) {
+	switch v.Kind() {
+	case reflect.Array:
+		l := v.Len()
+		for i := 0; i < l; i++ {
+			e.value(v.Index(i))
+		}
+
+	case reflect.Struct:
+		t := v.Type()
+		l := v.NumField()
+		for i := 0; i < l; i++ {
+			// see comment for corresponding code in decoder.value()
+			if v := v.Field(i); v.CanSet() || t.Field(i).Name != "_" {
+				e.value(v)
+			} else {
+				e.skip(v)
+			}
+		}
+
+	case reflect.Slice:
+		l := v.Len()
+		for i := 0; i < l; i++ {
+			e.value(v.Index(i))
+		}
+
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		switch v.Type().Kind() {
+		case reflect.Int8:
+			e.int8(int8(v.Int()))
+		case reflect.Int16:
+			e.int16(int16(v.Int()))
+		case reflect.Int32:
+			e.int32(int32(v.Int()))
+		case reflect.Int64:
+			e.int64(v.Int())
+		}
+
+	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+		switch v.Type().Kind() {
+		case reflect.Uint8:
+			e.uint8(uint8(v.Uint()))
+		case reflect.Uint16:
+			e.uint16(uint16(v.Uint()))
+		case reflect.Uint32:
+			e.uint32(uint32(v.Uint()))
+		case reflect.Uint64:
+			e.uint64(v.Uint())
+		}
+
+	case reflect.Float32, reflect.Float64:
+		switch v.Type().Kind() {
+		case reflect.Float32:
+			e.uint32(math.Float32bits(float32(v.Float())))
+		case reflect.Float64:
+			e.uint64(math.Float64bits(v.Float()))
+		}
+
+	case reflect.Complex64, reflect.Complex128:
+		switch v.Type().Kind() {
+		case reflect.Complex64:
+			x := v.Complex()
+			e.uint32(math.Float32bits(float32(real(x))))
+			e.uint32(math.Float32bits(float32(imag(x))))
+		case reflect.Complex128:
+			x := v.Complex()
+			e.uint64(math.Float64bits(real(x)))
+			e.uint64(math.Float64bits(imag(x)))
+		}
+	}
+}
+
+func (d *decoder) skip(v reflect.Value) {
+	d.buf = d.buf[dataSize(v):]
+}
+
+func (e *encoder) skip(v reflect.Value) {
+	n := dataSize(v)
+	for i := range e.buf[0:n] {
+		e.buf[i] = 0
+	}
+	e.buf = e.buf[n:]
+}
+
+// intDataSize returns the size of the data required to represent the data when encoded.
+// It returns zero if the type cannot be implemented by the fast path in Read or Write.
+func intDataSize(data interface{}) int {
+	switch data := data.(type) {
+	case int8, *int8, *uint8:
+		return 1
+	case []int8:
+		return len(data)
+	case []uint8:
+		return len(data)
+	case int16, *int16, *uint16:
+		return 2
+	case []int16:
+		return 2 * len(data)
+	case []uint16:
+		return 2 * len(data)
+	case int32, *int32, *uint32:
+		return 4
+	case []int32:
+		return 4 * len(data)
+	case []uint32:
+		return 4 * len(data)
+	case int64, *int64, *uint64:
+		return 8
+	case []int64:
+		return 8 * len(data)
+	case []uint64:
+		return 8 * len(data)
+	}
+	return 0
+}
diff --git a/src/encoding/binary/binary_test.go b/src/encoding/binary/binary_test.go
new file mode 100644
index 0000000..8ee595f
--- /dev/null
+++ b/src/encoding/binary/binary_test.go
@@ -0,0 +1,416 @@
+// Copyright 2009 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package binary
+
+import (
+	"bytes"
+	"io"
+	"math"
+	"reflect"
+	"strings"
+	"testing"
+)
+
+type Struct struct {
+	Int8       int8
+	Int16      int16
+	Int32      int32
+	Int64      int64
+	Uint8      uint8
+	Uint16     uint16
+	Uint32     uint32
+	Uint64     uint64
+	Float32    float32
+	Float64    float64
+	Complex64  complex64
+	Complex128 complex128
+	Array      [4]uint8
+}
+
+type T struct {
+	Int     int
+	Uint    uint
+	Uintptr uintptr
+	Array   [4]int
+}
+
+var s = Struct{
+	0x01,
+	0x0203,
+	0x04050607,
+	0x08090a0b0c0d0e0f,
+	0x10,
+	0x1112,
+	0x13141516,
+	0x1718191a1b1c1d1e,
+
+	math.Float32frombits(0x1f202122),
+	math.Float64frombits(0x232425262728292a),
+	complex(
+		math.Float32frombits(0x2b2c2d2e),
+		math.Float32frombits(0x2f303132),
+	),
+	complex(
+		math.Float64frombits(0x333435363738393a),
+		math.Float64frombits(0x3b3c3d3e3f404142),
+	),
+
+	[4]uint8{0x43, 0x44, 0x45, 0x46},
+}
+
+var big = []byte{
+	1,
+	2, 3,
+	4, 5, 6, 7,
+	8, 9, 10, 11, 12, 13, 14, 15,
+	16,
+	17, 18,
+	19, 20, 21, 22,
+	23, 24, 25, 26, 27, 28, 29, 30,
+
+	31, 32, 33, 34,
+	35, 36, 37, 38, 39, 40, 41, 42,
+	43, 44, 45, 46, 47, 48, 49, 50,
+	51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66,
+
+	67, 68, 69, 70,
+}
+
+var little = []byte{
+	1,
+	3, 2,
+	7, 6, 5, 4,
+	15, 14, 13, 12, 11, 10, 9, 8,
+	16,
+	18, 17,
+	22, 21, 20, 19,
+	30, 29, 28, 27, 26, 25, 24, 23,
+
+	34, 33, 32, 31,
+	42, 41, 40, 39, 38, 37, 36, 35,
+	46, 45, 44, 43, 50, 49, 48, 47,
+	58, 57, 56, 55, 54, 53, 52, 51, 66, 65, 64, 63, 62, 61, 60, 59,
+
+	67, 68, 69, 70,
+}
+
+var src = []byte{1, 2, 3, 4, 5, 6, 7, 8}
+var res = []int32{0x01020304, 0x05060708}
+
+func checkResult(t *testing.T, dir string, order ByteOrder, err error, have, want interface{}) {
+	if err != nil {
+		t.Errorf("%v %v: %v", dir, order, err)
+		return
+	}
+	if !reflect.DeepEqual(have, want) {
+		t.Errorf("%v %v:\n\thave %+v\n\twant %+v", dir, order, have, want)
+	}
+}
+
+func testRead(t *testing.T, order ByteOrder, b []byte, s1 interface{}) {
+	var s2 Struct
+	err := Read(bytes.NewReader(b), order, &s2)
+	checkResult(t, "Read", order, err, s2, s1)
+}
+
+func testWrite(t *testing.T, order ByteOrder, b []byte, s1 interface{}) {
+	buf := new(bytes.Buffer)
+	err := Write(buf, order, s1)
+	checkResult(t, "Write", order, err, buf.Bytes(), b)
+}
+
+func TestLittleEndianRead(t *testing.T)     { testRead(t, LittleEndian, little, s) }
+func TestLittleEndianWrite(t *testing.T)    { testWrite(t, LittleEndian, little, s) }
+func TestLittleEndianPtrWrite(t *testing.T) { testWrite(t, LittleEndian, little, &s) }
+
+func TestBigEndianRead(t *testing.T)     { testRead(t, BigEndian, big, s) }
+func TestBigEndianWrite(t *testing.T)    { testWrite(t, BigEndian, big, s) }
+func TestBigEndianPtrWrite(t *testing.T) { testWrite(t, BigEndian, big, &s) }
+
+func TestReadSlice(t *testing.T) {
+	slice := make([]int32, 2)
+	err := Read(bytes.NewReader(src), BigEndian, slice)
+	checkResult(t, "ReadSlice", BigEndian, err, slice, res)
+}
+
+func TestWriteSlice(t *testing.T) {
+	buf := new(bytes.Buffer)
+	err := Write(buf, BigEndian, res)
+	checkResult(t, "WriteSlice", BigEndian, err, buf.Bytes(), src)
+}
+
+// Addresses of arrays are easier to manipulate with reflection than are slices.
+var intArrays = []interface{}{
+	&[100]int8{},
+	&[100]int16{},
+	&[100]int32{},
+	&[100]int64{},
+	&[100]uint8{},
+	&[100]uint16{},
+	&[100]uint32{},
+	&[100]uint64{},
+}
+
+func TestSliceRoundTrip(t *testing.T) {
+	buf := new(bytes.Buffer)
+	for _, array := range intArrays {
+		src := reflect.ValueOf(array).Elem()
+		unsigned := false
+		switch src.Index(0).Kind() {
+		case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+			unsigned = true
+		}
+		for i := 0; i < src.Len(); i++ {
+			if unsigned {
+				src.Index(i).SetUint(uint64(i * 0x07654321))
+			} else {
+				src.Index(i).SetInt(int64(i * 0x07654321))
+			}
+		}
+		buf.Reset()
+		srcSlice := src.Slice(0, src.Len())
+		err := Write(buf, BigEndian, srcSlice.Interface())
+		if err != nil {
+			t.Fatal(err)
+		}
+		dst := reflect.New(src.Type()).Elem()
+		dstSlice := dst.Slice(0, dst.Len())
+		err = Read(buf, BigEndian, dstSlice.Interface())
+		if err != nil {
+			t.Fatal(err)
+		}
+		if !reflect.DeepEqual(src.Interface(), dst.Interface()) {
+			t.Fatal(src)
+		}
+	}
+}
+
+func TestWriteT(t *testing.T) {
+	buf := new(bytes.Buffer)
+	ts := T{}
+	if err := Write(buf, BigEndian, ts); err == nil {
+		t.Errorf("WriteT: have err == nil, want non-nil")
+	}
+
+	tv := reflect.Indirect(reflect.ValueOf(ts))
+	for i, n := 0, tv.NumField(); i < n; i++ {
+		typ := tv.Field(i).Type().String()
+		if typ == "[4]int" {
+			typ = "int" // the problem is int, not the [4]
+		}
+		if err := Write(buf, BigEndian, tv.Field(i).Interface()); err == nil {
+			t.Errorf("WriteT.%v: have err == nil, want non-nil", tv.Field(i).Type())
+		} else if !strings.Contains(err.Error(), typ) {
+			t.Errorf("WriteT: have err == %q, want it to mention %s", err, typ)
+		}
+	}
+}
+
+type BlankFields struct {
+	A uint32
+	_ int32
+	B float64
+	_ [4]int16
+	C byte
+	_ [7]byte
+	_ struct {
+		f [8]float32
+	}
+}
+
+type BlankFieldsProbe struct {
+	A  uint32
+	P0 int32
+	B  float64
+	P1 [4]int16
+	C  byte
+	P2 [7]byte
+	P3 struct {
+		F [8]float32
+	}
+}
+
+func TestBlankFields(t *testing.T) {
+	buf := new(bytes.Buffer)
+	b1 := BlankFields{A: 1234567890, B: 2.718281828, C: 42}
+	if err := Write(buf, LittleEndian, &b1); err != nil {
+		t.Error(err)
+	}
+
+	// zero values must have been written for blank fields
+	var p BlankFieldsProbe
+	if err := Read(buf, LittleEndian, &p); err != nil {
+		t.Error(err)
+	}
+
+	// quick test: only check first value of slices
+	if p.P0 != 0 || p.P1[0] != 0 || p.P2[0] != 0 || p.P3.F[0] != 0 {
+		t.Errorf("non-zero values for originally blank fields: %#v", p)
+	}
+
+	// write p and see if we can probe only some fields
+	if err := Write(buf, LittleEndian, &p); err != nil {
+		t.Error(err)
+	}
+
+	// read should ignore blank fields in b2
+	var b2 BlankFields
+	if err := Read(buf, LittleEndian, &b2); err != nil {
+		t.Error(err)
+	}
+	if b1.A != b2.A || b1.B != b2.B || b1.C != b2.C {
+		t.Errorf("%#v != %#v", b1, b2)
+	}
+}
+
+// An attempt to read into a struct with an unexported field will
+// panic.  This is probably not the best choice, but at this point
+// anything else would be an API change.
+
+type Unexported struct {
+	a int32
+}
+
+func TestUnexportedRead(t *testing.T) {
+	var buf bytes.Buffer
+	u1 := Unexported{a: 1}
+	if err := Write(&buf, LittleEndian, &u1); err != nil {
+		t.Fatal(err)
+	}
+
+	defer func() {
+		if recover() == nil {
+			t.Fatal("did not panic")
+		}
+	}()
+	var u2 Unexported
+	Read(&buf, LittleEndian, &u2)
+}
+
+func TestReadErrorMsg(t *testing.T) {
+	var buf bytes.Buffer
+	read := func(data interface{}) {
+		err := Read(&buf, LittleEndian, data)
+		want := "binary.Read: invalid type " + reflect.TypeOf(data).String()
+		if err == nil {
+			t.Errorf("%T: got no error; want %q", data, want)
+			return
+		}
+		if got := err.Error(); got != want {
+			t.Errorf("%T: got %q; want %q", data, got, want)
+		}
+	}
+	read(0)
+	s := new(struct{})
+	read(&s)
+	p := &s
+	read(&p)
+}
+
+type byteSliceReader struct {
+	remain []byte
+}
+
+func (br *byteSliceReader) Read(p []byte) (int, error) {
+	n := copy(p, br.remain)
+	br.remain = br.remain[n:]
+	return n, nil
+}
+
+func BenchmarkReadSlice1000Int32s(b *testing.B) {
+	bsr := &byteSliceReader{}
+	slice := make([]int32, 1000)
+	buf := make([]byte, len(slice)*4)
+	b.SetBytes(int64(len(buf)))
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		bsr.remain = buf
+		Read(bsr, BigEndian, slice)
+	}
+}
+
+func BenchmarkReadStruct(b *testing.B) {
+	bsr := &byteSliceReader{}
+	var buf bytes.Buffer
+	Write(&buf, BigEndian, &s)
+	b.SetBytes(int64(dataSize(reflect.ValueOf(s))))
+	t := s
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		bsr.remain = buf.Bytes()
+		Read(bsr, BigEndian, &t)
+	}
+	b.StopTimer()
+	if !reflect.DeepEqual(s, t) {
+		b.Fatal("no match")
+	}
+}
+
+func BenchmarkReadInts(b *testing.B) {
+	var ls Struct
+	bsr := &byteSliceReader{}
+	var r io.Reader = bsr
+	b.SetBytes(2 * (1 + 2 + 4 + 8))
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		bsr.remain = big
+		Read(r, BigEndian, &ls.Int8)
+		Read(r, BigEndian, &ls.Int16)
+		Read(r, BigEndian, &ls.Int32)
+		Read(r, BigEndian, &ls.Int64)
+		Read(r, BigEndian, &ls.Uint8)
+		Read(r, BigEndian, &ls.Uint16)
+		Read(r, BigEndian, &ls.Uint32)
+		Read(r, BigEndian, &ls.Uint64)
+	}
+
+	want := s
+	want.Float32 = 0
+	want.Float64 = 0
+	want.Complex64 = 0
+	want.Complex128 = 0
+	for i := range want.Array {
+		want.Array[i] = 0
+	}
+	b.StopTimer()
+	if !reflect.DeepEqual(ls, want) {
+		panic("no match")
+	}
+}
+
+func BenchmarkWriteInts(b *testing.B) {
+	buf := new(bytes.Buffer)
+	var w io.Writer = buf
+	b.SetBytes(2 * (1 + 2 + 4 + 8))
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		buf.Reset()
+		Write(w, BigEndian, s.Int8)
+		Write(w, BigEndian, s.Int16)
+		Write(w, BigEndian, s.Int32)
+		Write(w, BigEndian, s.Int64)
+		Write(w, BigEndian, s.Uint8)
+		Write(w, BigEndian, s.Uint16)
+		Write(w, BigEndian, s.Uint32)
+		Write(w, BigEndian, s.Uint64)
+	}
+	b.StopTimer()
+	if !bytes.Equal(buf.Bytes(), big[:30]) {
+		b.Fatalf("first half doesn't match: %x %x", buf.Bytes(), big[:30])
+	}
+}
+
+func BenchmarkWriteSlice1000Int32s(b *testing.B) {
+	slice := make([]int32, 1000)
+	buf := new(bytes.Buffer)
+	var w io.Writer = buf
+	b.SetBytes(4 * 1000)
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		buf.Reset()
+		Write(w, BigEndian, slice)
+	}
+	b.StopTimer()
+}
diff --git a/src/pkg/encoding/binary/example_test.go b/src/encoding/binary/example_test.go
similarity index 100%
rename from src/pkg/encoding/binary/example_test.go
rename to src/encoding/binary/example_test.go
diff --git a/src/pkg/encoding/binary/varint.go b/src/encoding/binary/varint.go
similarity index 100%
rename from src/pkg/encoding/binary/varint.go
rename to src/encoding/binary/varint.go
diff --git a/src/pkg/encoding/binary/varint_test.go b/src/encoding/binary/varint_test.go
similarity index 100%
rename from src/pkg/encoding/binary/varint_test.go
rename to src/encoding/binary/varint_test.go
diff --git a/src/pkg/encoding/csv/reader.go b/src/encoding/csv/reader.go
similarity index 100%
rename from src/pkg/encoding/csv/reader.go
rename to src/encoding/csv/reader.go
diff --git a/src/pkg/encoding/csv/reader_test.go b/src/encoding/csv/reader_test.go
similarity index 100%
rename from src/pkg/encoding/csv/reader_test.go
rename to src/encoding/csv/reader_test.go
diff --git a/src/encoding/csv/writer.go b/src/encoding/csv/writer.go
new file mode 100644
index 0000000..17e7bb7
--- /dev/null
+++ b/src/encoding/csv/writer.go
@@ -0,0 +1,139 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package csv
+
+import (
+	"bufio"
+	"io"
+	"strings"
+	"unicode"
+	"unicode/utf8"
+)
+
+// A Writer writes records to a CSV encoded file.
+//
+// As returned by NewWriter, a Writer writes records terminated by a
+// newline and uses ',' as the field delimiter.  The exported fields can be
+// changed to customize the details before the first call to Write or WriteAll.
+//
+// Comma is the field delimiter.
+//
+// If UseCRLF is true, the Writer ends each record with \r\n instead of \n.
+type Writer struct {
+	Comma   rune // Field delimiter (set to ',' by NewWriter)
+	UseCRLF bool // True to use \r\n as the line terminator
+	w       *bufio.Writer
+}
+
+// NewWriter returns a new Writer that writes to w.
+func NewWriter(w io.Writer) *Writer {
+	return &Writer{
+		Comma: ',',
+		w:     bufio.NewWriter(w),
+	}
+}
+
+// Writer writes a single CSV record to w along with any necessary quoting.
+// A record is a slice of strings with each string being one field.
+func (w *Writer) Write(record []string) (err error) {
+	for n, field := range record {
+		if n > 0 {
+			if _, err = w.w.WriteRune(w.Comma); err != nil {
+				return
+			}
+		}
+
+		// If we don't have to have a quoted field then just
+		// write out the field and continue to the next field.
+		if !w.fieldNeedsQuotes(field) {
+			if _, err = w.w.WriteString(field); err != nil {
+				return
+			}
+			continue
+		}
+		if err = w.w.WriteByte('"'); err != nil {
+			return
+		}
+
+		for _, r1 := range field {
+			switch r1 {
+			case '"':
+				_, err = w.w.WriteString(`""`)
+			case '\r':
+				if !w.UseCRLF {
+					err = w.w.WriteByte('\r')
+				}
+			case '\n':
+				if w.UseCRLF {
+					_, err = w.w.WriteString("\r\n")
+				} else {
+					err = w.w.WriteByte('\n')
+				}
+			default:
+				_, err = w.w.WriteRune(r1)
+			}
+			if err != nil {
+				return
+			}
+		}
+
+		if err = w.w.WriteByte('"'); err != nil {
+			return
+		}
+	}
+	if w.UseCRLF {
+		_, err = w.w.WriteString("\r\n")
+	} else {
+		err = w.w.WriteByte('\n')
+	}
+	return
+}
+
+// Flush writes any buffered data to the underlying io.Writer.
+// To check if an error occurred during the Flush, call Error.
+func (w *Writer) Flush() {
+	w.w.Flush()
+}
+
+// Error reports any error that has occurred during a previous Write or Flush.
+func (w *Writer) Error() error {
+	_, err := w.w.Write(nil)
+	return err
+}
+
+// WriteAll writes multiple CSV records to w using Write and then calls Flush.
+func (w *Writer) WriteAll(records [][]string) (err error) {
+	for _, record := range records {
+		err = w.Write(record)
+		if err != nil {
+			return err
+		}
+	}
+	return w.w.Flush()
+}
+
+// fieldNeedsQuotes returns true if our field must be enclosed in quotes.
+// Fields with a Comma, fields with a quote or newline, and
+// fields which start with a space must be enclosed in quotes.
+// We used to quote empty strings, but we do not anymore (as of Go 1.4).
+// The two representations should be equivalent, but Postgres distinguishes
+// quoted vs non-quoted empty string during database imports, and it has
+// an option to force the quoted behavior for non-quoted CSV but it has
+// no option to force the non-quoted behavior for quoted CSV, making
+// CSV with quoted empty strings strictly less useful.
+// Not quoting the empty string also makes this package match the behavior
+// of Microsoft Excel and Google Drive.
+// For Postgres, quote the data termating string `\.`.
+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 {
+		return true
+	}
+
+	r1, _ := utf8.DecodeRuneInString(field)
+	return unicode.IsSpace(r1)
+}
diff --git a/src/encoding/csv/writer_test.go b/src/encoding/csv/writer_test.go
new file mode 100644
index 0000000..8ddca0a
--- /dev/null
+++ b/src/encoding/csv/writer_test.go
@@ -0,0 +1,85 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package csv
+
+import (
+	"bytes"
+	"errors"
+	"testing"
+)
+
+var writeTests = []struct {
+	Input   [][]string
+	Output  string
+	UseCRLF bool
+}{
+	{Input: [][]string{{"abc"}}, Output: "abc\n"},
+	{Input: [][]string{{"abc"}}, Output: "abc\r\n", UseCRLF: true},
+	{Input: [][]string{{`"abc"`}}, Output: `"""abc"""` + "\n"},
+	{Input: [][]string{{`a"b`}}, Output: `"a""b"` + "\n"},
+	{Input: [][]string{{`"a"b"`}}, Output: `"""a""b"""` + "\n"},
+	{Input: [][]string{{" abc"}}, Output: `" abc"` + "\n"},
+	{Input: [][]string{{"abc,def"}}, Output: `"abc,def"` + "\n"},
+	{Input: [][]string{{"abc", "def"}}, Output: "abc,def\n"},
+	{Input: [][]string{{"abc"}, {"def"}}, Output: "abc\ndef\n"},
+	{Input: [][]string{{"abc\ndef"}}, Output: "\"abc\ndef\"\n"},
+	{Input: [][]string{{"abc\ndef"}}, Output: "\"abc\r\ndef\"\r\n", UseCRLF: true},
+	{Input: [][]string{{"abc\rdef"}}, Output: "\"abcdef\"\r\n", UseCRLF: true},
+	{Input: [][]string{{"abc\rdef"}}, Output: "\"abc\rdef\"\n", UseCRLF: false},
+	{Input: [][]string{{""}}, Output: "\n"},
+	{Input: [][]string{{"", ""}}, Output: ",\n"},
+	{Input: [][]string{{"", "", ""}}, Output: ",,\n"},
+	{Input: [][]string{{"", "", "a"}}, Output: ",,a\n"},
+	{Input: [][]string{{"", "a", ""}}, Output: ",a,\n"},
+	{Input: [][]string{{"", "a", "a"}}, Output: ",a,a\n"},
+	{Input: [][]string{{"a", "", ""}}, Output: "a,,\n"},
+	{Input: [][]string{{"a", "", "a"}}, Output: "a,,a\n"},
+	{Input: [][]string{{"a", "a", ""}}, Output: "a,a,\n"},
+	{Input: [][]string{{"a", "a", "a"}}, Output: "a,a,a\n"},
+	{Input: [][]string{{`\.`}}, Output: "\"\\.\"\n"},
+}
+
+func TestWrite(t *testing.T) {
+	for n, tt := range writeTests {
+		b := &bytes.Buffer{}
+		f := NewWriter(b)
+		f.UseCRLF = tt.UseCRLF
+		err := f.WriteAll(tt.Input)
+		if err != nil {
+			t.Errorf("Unexpected error: %s\n", err)
+		}
+		out := b.String()
+		if out != tt.Output {
+			t.Errorf("#%d: out=%q want %q", n, out, tt.Output)
+		}
+	}
+}
+
+type errorWriter struct{}
+
+func (e errorWriter) Write(b []byte) (int, error) {
+	return 0, errors.New("Test")
+}
+
+func TestError(t *testing.T) {
+	b := &bytes.Buffer{}
+	f := NewWriter(b)
+	f.Write([]string{"abc"})
+	f.Flush()
+	err := f.Error()
+
+	if err != nil {
+		t.Errorf("Unexpected error: %s\n", err)
+	}
+
+	f = NewWriter(errorWriter{})
+	f.Write([]string{"abc"})
+	f.Flush()
+	err = f.Error()
+
+	if err == nil {
+		t.Error("Error should not be nil")
+	}
+}
diff --git a/src/pkg/encoding/encoding.go b/src/encoding/encoding.go
similarity index 100%
rename from src/pkg/encoding/encoding.go
rename to src/encoding/encoding.go
diff --git a/src/encoding/gob/codec_test.go b/src/encoding/gob/codec_test.go
new file mode 100644
index 0000000..56a7298
--- /dev/null
+++ b/src/encoding/gob/codec_test.go
@@ -0,0 +1,1475 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package gob
+
+import (
+	"bytes"
+	"errors"
+	"flag"
+	"math"
+	"math/rand"
+	"reflect"
+	"strings"
+	"testing"
+	"time"
+)
+
+var doFuzzTests = flag.Bool("gob.fuzz", false, "run the fuzz tests, which are large and very slow")
+
+// Guarantee encoding format by comparing some encodings to hand-written values
+type EncodeT struct {
+	x uint64
+	b []byte
+}
+
+var encodeT = []EncodeT{
+	{0x00, []byte{0x00}},
+	{0x0F, []byte{0x0F}},
+	{0xFF, []byte{0xFF, 0xFF}},
+	{0xFFFF, []byte{0xFE, 0xFF, 0xFF}},
+	{0xFFFFFF, []byte{0xFD, 0xFF, 0xFF, 0xFF}},
+	{0xFFFFFFFF, []byte{0xFC, 0xFF, 0xFF, 0xFF, 0xFF}},
+	{0xFFFFFFFFFF, []byte{0xFB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}},
+	{0xFFFFFFFFFFFF, []byte{0xFA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}},
+	{0xFFFFFFFFFFFFFF, []byte{0xF9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}},
+	{0xFFFFFFFFFFFFFFFF, []byte{0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}},
+	{0x1111, []byte{0xFE, 0x11, 0x11}},
+	{0x1111111111111111, []byte{0xF8, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}},
+	{0x8888888888888888, []byte{0xF8, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88}},
+	{1 << 63, []byte{0xF8, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+}
+
+// testError is meant to be used as a deferred function to turn a panic(gobError) into a
+// plain test.Error call.
+func testError(t *testing.T) {
+	if e := recover(); e != nil {
+		t.Error(e.(gobError).err) // Will re-panic if not one of our errors, such as a runtime error.
+	}
+	return
+}
+
+func newDecBuffer(data []byte) *decBuffer {
+	return &decBuffer{
+		data: data,
+	}
+}
+
+// Test basic encode/decode routines for unsigned integers
+func TestUintCodec(t *testing.T) {
+	defer testError(t)
+	b := new(encBuffer)
+	encState := newEncoderState(b)
+	for _, tt := range encodeT {
+		b.Reset()
+		encState.encodeUint(tt.x)
+		if !bytes.Equal(tt.b, b.Bytes()) {
+			t.Errorf("encodeUint: %#x encode: expected % x got % x", tt.x, tt.b, b.Bytes())
+		}
+	}
+	for u := uint64(0); ; u = (u + 1) * 7 {
+		b.Reset()
+		encState.encodeUint(u)
+		decState := newDecodeState(newDecBuffer(b.Bytes()))
+		v := decState.decodeUint()
+		if u != v {
+			t.Errorf("Encode/Decode: sent %#x received %#x", u, v)
+		}
+		if u&(1<<63) != 0 {
+			break
+		}
+	}
+}
+
+func verifyInt(i int64, t *testing.T) {
+	defer testError(t)
+	var b = new(encBuffer)
+	encState := newEncoderState(b)
+	encState.encodeInt(i)
+	decState := newDecodeState(newDecBuffer(b.Bytes()))
+	decState.buf = make([]byte, 8)
+	j := decState.decodeInt()
+	if i != j {
+		t.Errorf("Encode/Decode: sent %#x received %#x", uint64(i), uint64(j))
+	}
+}
+
+// Test basic encode/decode routines for signed integers
+func TestIntCodec(t *testing.T) {
+	for u := uint64(0); ; u = (u + 1) * 7 {
+		// Do positive and negative values
+		i := int64(u)
+		verifyInt(i, t)
+		verifyInt(-i, t)
+		verifyInt(^i, t)
+		if u&(1<<63) != 0 {
+			break
+		}
+	}
+	verifyInt(-1<<63, t) // a tricky case
+}
+
+// The result of encoding a true boolean with field number 7
+var boolResult = []byte{0x07, 0x01}
+
+// The result of encoding a number 17 with field number 7
+var signedResult = []byte{0x07, 2 * 17}
+var unsignedResult = []byte{0x07, 17}
+var floatResult = []byte{0x07, 0xFE, 0x31, 0x40}
+
+// The result of encoding a number 17+19i with field number 7
+var complexResult = []byte{0x07, 0xFE, 0x31, 0x40, 0xFE, 0x33, 0x40}
+
+// The result of encoding "hello" with field number 7
+var bytesResult = []byte{0x07, 0x05, 'h', 'e', 'l', 'l', 'o'}
+
+func newDecodeState(buf *decBuffer) *decoderState {
+	d := new(decoderState)
+	d.b = buf
+	d.buf = make([]byte, uint64Size)
+	return d
+}
+
+func newEncoderState(b *encBuffer) *encoderState {
+	b.Reset()
+	state := &encoderState{enc: nil, b: b}
+	state.fieldnum = -1
+	return state
+}
+
+// Test instruction execution for encoding.
+// Do not run the machine yet; instead do individual instructions crafted by hand.
+func TestScalarEncInstructions(t *testing.T) {
+	var b = new(encBuffer)
+
+	// bool
+	{
+		var data bool = true
+		instr := &encInstr{encBool, 6, nil, 0}
+		state := newEncoderState(b)
+		instr.op(instr, state, reflect.ValueOf(data))
+		if !bytes.Equal(boolResult, b.Bytes()) {
+			t.Errorf("bool enc instructions: expected % x got % x", boolResult, b.Bytes())
+		}
+	}
+
+	// int
+	{
+		b.Reset()
+		var data int = 17
+		instr := &encInstr{encInt, 6, nil, 0}
+		state := newEncoderState(b)
+		instr.op(instr, state, reflect.ValueOf(data))
+		if !bytes.Equal(signedResult, b.Bytes()) {
+			t.Errorf("int enc instructions: expected % x got % x", signedResult, b.Bytes())
+		}
+	}
+
+	// uint
+	{
+		b.Reset()
+		var data uint = 17
+		instr := &encInstr{encUint, 6, nil, 0}
+		state := newEncoderState(b)
+		instr.op(instr, state, reflect.ValueOf(data))
+		if !bytes.Equal(unsignedResult, b.Bytes()) {
+			t.Errorf("uint enc instructions: expected % x got % x", unsignedResult, b.Bytes())
+		}
+	}
+
+	// int8
+	{
+		b.Reset()
+		var data int8 = 17
+		instr := &encInstr{encInt, 6, nil, 0}
+		state := newEncoderState(b)
+		instr.op(instr, state, reflect.ValueOf(data))
+		if !bytes.Equal(signedResult, b.Bytes()) {
+			t.Errorf("int8 enc instructions: expected % x got % x", signedResult, b.Bytes())
+		}
+	}
+
+	// uint8
+	{
+		b.Reset()
+		var data uint8 = 17
+		instr := &encInstr{encUint, 6, nil, 0}
+		state := newEncoderState(b)
+		instr.op(instr, state, reflect.ValueOf(data))
+		if !bytes.Equal(unsignedResult, b.Bytes()) {
+			t.Errorf("uint8 enc instructions: expected % x got % x", unsignedResult, b.Bytes())
+		}
+	}
+
+	// int16
+	{
+		b.Reset()
+		var data int16 = 17
+		instr := &encInstr{encInt, 6, nil, 0}
+		state := newEncoderState(b)
+		instr.op(instr, state, reflect.ValueOf(data))
+		if !bytes.Equal(signedResult, b.Bytes()) {
+			t.Errorf("int16 enc instructions: expected % x got % x", signedResult, b.Bytes())
+		}
+	}
+
+	// uint16
+	{
+		b.Reset()
+		var data uint16 = 17
+		instr := &encInstr{encUint, 6, nil, 0}
+		state := newEncoderState(b)
+		instr.op(instr, state, reflect.ValueOf(data))
+		if !bytes.Equal(unsignedResult, b.Bytes()) {
+			t.Errorf("uint16 enc instructions: expected % x got % x", unsignedResult, b.Bytes())
+		}
+	}
+
+	// int32
+	{
+		b.Reset()
+		var data int32 = 17
+		instr := &encInstr{encInt, 6, nil, 0}
+		state := newEncoderState(b)
+		instr.op(instr, state, reflect.ValueOf(data))
+		if !bytes.Equal(signedResult, b.Bytes()) {
+			t.Errorf("int32 enc instructions: expected % x got % x", signedResult, b.Bytes())
+		}
+	}
+
+	// uint32
+	{
+		b.Reset()
+		var data uint32 = 17
+		instr := &encInstr{encUint, 6, nil, 0}
+		state := newEncoderState(b)
+		instr.op(instr, state, reflect.ValueOf(data))
+		if !bytes.Equal(unsignedResult, b.Bytes()) {
+			t.Errorf("uint32 enc instructions: expected % x got % x", unsignedResult, b.Bytes())
+		}
+	}
+
+	// int64
+	{
+		b.Reset()
+		var data int64 = 17
+		instr := &encInstr{encInt, 6, nil, 0}
+		state := newEncoderState(b)
+		instr.op(instr, state, reflect.ValueOf(data))
+		if !bytes.Equal(signedResult, b.Bytes()) {
+			t.Errorf("int64 enc instructions: expected % x got % x", signedResult, b.Bytes())
+		}
+	}
+
+	// uint64
+	{
+		b.Reset()
+		var data uint64 = 17
+		instr := &encInstr{encUint, 6, nil, 0}
+		state := newEncoderState(b)
+		instr.op(instr, state, reflect.ValueOf(data))
+		if !bytes.Equal(unsignedResult, b.Bytes()) {
+			t.Errorf("uint64 enc instructions: expected % x got % x", unsignedResult, b.Bytes())
+		}
+	}
+
+	// float32
+	{
+		b.Reset()
+		var data float32 = 17
+		instr := &encInstr{encFloat, 6, nil, 0}
+		state := newEncoderState(b)
+		instr.op(instr, state, reflect.ValueOf(data))
+		if !bytes.Equal(floatResult, b.Bytes()) {
+			t.Errorf("float32 enc instructions: expected % x got % x", floatResult, b.Bytes())
+		}
+	}
+
+	// float64
+	{
+		b.Reset()
+		var data float64 = 17
+		instr := &encInstr{encFloat, 6, nil, 0}
+		state := newEncoderState(b)
+		instr.op(instr, state, reflect.ValueOf(data))
+		if !bytes.Equal(floatResult, b.Bytes()) {
+			t.Errorf("float64 enc instructions: expected % x got % x", floatResult, b.Bytes())
+		}
+	}
+
+	// bytes == []uint8
+	{
+		b.Reset()
+		data := []byte("hello")
+		instr := &encInstr{encUint8Array, 6, nil, 0}
+		state := newEncoderState(b)
+		instr.op(instr, state, reflect.ValueOf(data))
+		if !bytes.Equal(bytesResult, b.Bytes()) {
+			t.Errorf("bytes enc instructions: expected % x got % x", bytesResult, b.Bytes())
+		}
+	}
+
+	// string
+	{
+		b.Reset()
+		var data string = "hello"
+		instr := &encInstr{encString, 6, nil, 0}
+		state := newEncoderState(b)
+		instr.op(instr, state, reflect.ValueOf(data))
+		if !bytes.Equal(bytesResult, b.Bytes()) {
+			t.Errorf("string enc instructions: expected % x got % x", bytesResult, b.Bytes())
+		}
+	}
+}
+
+func execDec(typ string, instr *decInstr, state *decoderState, t *testing.T, value reflect.Value) {
+	defer testError(t)
+	v := int(state.decodeUint())
+	if v+state.fieldnum != 6 {
+		t.Fatalf("decoding field number %d, got %d", 6, v+state.fieldnum)
+	}
+	instr.op(instr, state, value.Elem())
+	state.fieldnum = 6
+}
+
+func newDecodeStateFromData(data []byte) *decoderState {
+	b := newDecBuffer(data)
+	state := newDecodeState(b)
+	state.fieldnum = -1
+	return state
+}
+
+// Test instruction execution for decoding.
+// Do not run the machine yet; instead do individual instructions crafted by hand.
+func TestScalarDecInstructions(t *testing.T) {
+	ovfl := errors.New("overflow")
+
+	// bool
+	{
+		var data bool
+		instr := &decInstr{decBool, 6, nil, ovfl}
+		state := newDecodeStateFromData(boolResult)
+		execDec("bool", instr, state, t, reflect.ValueOf(&data))
+		if data != true {
+			t.Errorf("bool a = %v not true", data)
+		}
+	}
+	// int
+	{
+		var data int
+		instr := &decInstr{decOpTable[reflect.Int], 6, nil, ovfl}
+		state := newDecodeStateFromData(signedResult)
+		execDec("int", instr, state, t, reflect.ValueOf(&data))
+		if data != 17 {
+			t.Errorf("int a = %v not 17", data)
+		}
+	}
+
+	// uint
+	{
+		var data uint
+		instr := &decInstr{decOpTable[reflect.Uint], 6, nil, ovfl}
+		state := newDecodeStateFromData(unsignedResult)
+		execDec("uint", instr, state, t, reflect.ValueOf(&data))
+		if data != 17 {
+			t.Errorf("uint a = %v not 17", data)
+		}
+	}
+
+	// int8
+	{
+		var data int8
+		instr := &decInstr{decInt8, 6, nil, ovfl}
+		state := newDecodeStateFromData(signedResult)
+		execDec("int8", instr, state, t, reflect.ValueOf(&data))
+		if data != 17 {
+			t.Errorf("int8 a = %v not 17", data)
+		}
+	}
+
+	// uint8
+	{
+		var data uint8
+		instr := &decInstr{decUint8, 6, nil, ovfl}
+		state := newDecodeStateFromData(unsignedResult)
+		execDec("uint8", instr, state, t, reflect.ValueOf(&data))
+		if data != 17 {
+			t.Errorf("uint8 a = %v not 17", data)
+		}
+	}
+
+	// int16
+	{
+		var data int16
+		instr := &decInstr{decInt16, 6, nil, ovfl}
+		state := newDecodeStateFromData(signedResult)
+		execDec("int16", instr, state, t, reflect.ValueOf(&data))
+		if data != 17 {
+			t.Errorf("int16 a = %v not 17", data)
+		}
+	}
+
+	// uint16
+	{
+		var data uint16
+		instr := &decInstr{decUint16, 6, nil, ovfl}
+		state := newDecodeStateFromData(unsignedResult)
+		execDec("uint16", instr, state, t, reflect.ValueOf(&data))
+		if data != 17 {
+			t.Errorf("uint16 a = %v not 17", data)
+		}
+	}
+
+	// int32
+	{
+		var data int32
+		instr := &decInstr{decInt32, 6, nil, ovfl}
+		state := newDecodeStateFromData(signedResult)
+		execDec("int32", instr, state, t, reflect.ValueOf(&data))
+		if data != 17 {
+			t.Errorf("int32 a = %v not 17", data)
+		}
+	}
+
+	// uint32
+	{
+		var data uint32
+		instr := &decInstr{decUint32, 6, nil, ovfl}
+		state := newDecodeStateFromData(unsignedResult)
+		execDec("uint32", instr, state, t, reflect.ValueOf(&data))
+		if data != 17 {
+			t.Errorf("uint32 a = %v not 17", data)
+		}
+	}
+
+	// uintptr
+	{
+		var data uintptr
+		instr := &decInstr{decOpTable[reflect.Uintptr], 6, nil, ovfl}
+		state := newDecodeStateFromData(unsignedResult)
+		execDec("uintptr", instr, state, t, reflect.ValueOf(&data))
+		if data != 17 {
+			t.Errorf("uintptr a = %v not 17", data)
+		}
+	}
+
+	// int64
+	{
+		var data int64
+		instr := &decInstr{decInt64, 6, nil, ovfl}
+		state := newDecodeStateFromData(signedResult)
+		execDec("int64", instr, state, t, reflect.ValueOf(&data))
+		if data != 17 {
+			t.Errorf("int64 a = %v not 17", data)
+		}
+	}
+
+	// uint64
+	{
+		var data uint64
+		instr := &decInstr{decUint64, 6, nil, ovfl}
+		state := newDecodeStateFromData(unsignedResult)
+		execDec("uint64", instr, state, t, reflect.ValueOf(&data))
+		if data != 17 {
+			t.Errorf("uint64 a = %v not 17", data)
+		}
+	}
+
+	// float32
+	{
+		var data float32
+		instr := &decInstr{decFloat32, 6, nil, ovfl}
+		state := newDecodeStateFromData(floatResult)
+		execDec("float32", instr, state, t, reflect.ValueOf(&data))
+		if data != 17 {
+			t.Errorf("float32 a = %v not 17", data)
+		}
+	}
+
+	// float64
+	{
+		var data float64
+		instr := &decInstr{decFloat64, 6, nil, ovfl}
+		state := newDecodeStateFromData(floatResult)
+		execDec("float64", instr, state, t, reflect.ValueOf(&data))
+		if data != 17 {
+			t.Errorf("float64 a = %v not 17", data)
+		}
+	}
+
+	// complex64
+	{
+		var data complex64
+		instr := &decInstr{decOpTable[reflect.Complex64], 6, nil, ovfl}
+		state := newDecodeStateFromData(complexResult)
+		execDec("complex", instr, state, t, reflect.ValueOf(&data))
+		if data != 17+19i {
+			t.Errorf("complex a = %v not 17+19i", data)
+		}
+	}
+
+	// complex128
+	{
+		var data complex128
+		instr := &decInstr{decOpTable[reflect.Complex128], 6, nil, ovfl}
+		state := newDecodeStateFromData(complexResult)
+		execDec("complex", instr, state, t, reflect.ValueOf(&data))
+		if data != 17+19i {
+			t.Errorf("complex a = %v not 17+19i", data)
+		}
+	}
+
+	// bytes == []uint8
+	{
+		var data []byte
+		instr := &decInstr{decUint8Slice, 6, nil, ovfl}
+		state := newDecodeStateFromData(bytesResult)
+		execDec("bytes", instr, state, t, reflect.ValueOf(&data))
+		if string(data) != "hello" {
+			t.Errorf(`bytes a = %q not "hello"`, string(data))
+		}
+	}
+
+	// string
+	{
+		var data string
+		instr := &decInstr{decString, 6, nil, ovfl}
+		state := newDecodeStateFromData(bytesResult)
+		execDec("bytes", instr, state, t, reflect.ValueOf(&data))
+		if data != "hello" {
+			t.Errorf(`bytes a = %q not "hello"`, data)
+		}
+	}
+}
+
+func TestEndToEnd(t *testing.T) {
+	type T2 struct {
+		T string
+	}
+	s1 := "string1"
+	s2 := "string2"
+	type T1 struct {
+		A, B, C  int
+		M        map[string]*float64
+		EmptyMap map[string]int // to check that we receive a non-nil map.
+		N        *[3]float64
+		Strs     *[2]string
+		Int64s   *[]int64
+		RI       complex64
+		S        string
+		Y        []byte
+		T        *T2
+	}
+	pi := 3.14159
+	e := 2.71828
+	t1 := &T1{
+		A:        17,
+		B:        18,
+		C:        -5,
+		M:        map[string]*float64{"pi": &pi, "e": &e},
+		EmptyMap: make(map[string]int),
+		N:        &[3]float64{1.5, 2.5, 3.5},
+		Strs:     &[2]string{s1, s2},
+		Int64s:   &[]int64{77, 89, 123412342134},
+		RI:       17 - 23i,
+		S:        "Now is the time",
+		Y:        []byte("hello, sailor"),
+		T:        &T2{"this is T2"},
+	}
+	b := new(bytes.Buffer)
+	err := NewEncoder(b).Encode(t1)
+	if err != nil {
+		t.Error("encode:", err)
+	}
+	var _t1 T1
+	err = NewDecoder(b).Decode(&_t1)
+	if err != nil {
+		t.Fatal("decode:", err)
+	}
+	if !reflect.DeepEqual(t1, &_t1) {
+		t.Errorf("encode expected %v got %v", *t1, _t1)
+	}
+	// Be absolutely sure the received map is non-nil.
+	if t1.EmptyMap == nil {
+		t.Errorf("nil map sent")
+	}
+	if _t1.EmptyMap == nil {
+		t.Errorf("nil map received")
+	}
+}
+
+func TestOverflow(t *testing.T) {
+	type inputT struct {
+		Maxi int64
+		Mini int64
+		Maxu uint64
+		Maxf float64
+		Minf float64
+		Maxc complex128
+		Minc complex128
+	}
+	var it inputT
+	var err error
+	b := new(bytes.Buffer)
+	enc := NewEncoder(b)
+	dec := NewDecoder(b)
+
+	// int8
+	b.Reset()
+	it = inputT{
+		Maxi: math.MaxInt8 + 1,
+	}
+	type outi8 struct {
+		Maxi int8
+		Mini int8
+	}
+	var o1 outi8
+	enc.Encode(it)
+	err = dec.Decode(&o1)
+	if err == nil || err.Error() != `value for "Maxi" out of range` {
+		t.Error("wrong overflow error for int8:", err)
+	}
+	it = inputT{
+		Mini: math.MinInt8 - 1,
+	}
+	b.Reset()
+	enc.Encode(it)
+	err = dec.Decode(&o1)
+	if err == nil || err.Error() != `value for "Mini" out of range` {
+		t.Error("wrong underflow error for int8:", err)
+	}
+
+	// int16
+	b.Reset()
+	it = inputT{
+		Maxi: math.MaxInt16 + 1,
+	}
+	type outi16 struct {
+		Maxi int16
+		Mini int16
+	}
+	var o2 outi16
+	enc.Encode(it)
+	err = dec.Decode(&o2)
+	if err == nil || err.Error() != `value for "Maxi" out of range` {
+		t.Error("wrong overflow error for int16:", err)
+	}
+	it = inputT{
+		Mini: math.MinInt16 - 1,
+	}
+	b.Reset()
+	enc.Encode(it)
+	err = dec.Decode(&o2)
+	if err == nil || err.Error() != `value for "Mini" out of range` {
+		t.Error("wrong underflow error for int16:", err)
+	}
+
+	// int32
+	b.Reset()
+	it = inputT{
+		Maxi: math.MaxInt32 + 1,
+	}
+	type outi32 struct {
+		Maxi int32
+		Mini int32
+	}
+	var o3 outi32
+	enc.Encode(it)
+	err = dec.Decode(&o3)
+	if err == nil || err.Error() != `value for "Maxi" out of range` {
+		t.Error("wrong overflow error for int32:", err)
+	}
+	it = inputT{
+		Mini: math.MinInt32 - 1,
+	}
+	b.Reset()
+	enc.Encode(it)
+	err = dec.Decode(&o3)
+	if err == nil || err.Error() != `value for "Mini" out of range` {
+		t.Error("wrong underflow error for int32:", err)
+	}
+
+	// uint8
+	b.Reset()
+	it = inputT{
+		Maxu: math.MaxUint8 + 1,
+	}
+	type outu8 struct {
+		Maxu uint8
+	}
+	var o4 outu8
+	enc.Encode(it)
+	err = dec.Decode(&o4)
+	if err == nil || err.Error() != `value for "Maxu" out of range` {
+		t.Error("wrong overflow error for uint8:", err)
+	}
+
+	// uint16
+	b.Reset()
+	it = inputT{
+		Maxu: math.MaxUint16 + 1,
+	}
+	type outu16 struct {
+		Maxu uint16
+	}
+	var o5 outu16
+	enc.Encode(it)
+	err = dec.Decode(&o5)
+	if err == nil || err.Error() != `value for "Maxu" out of range` {
+		t.Error("wrong overflow error for uint16:", err)
+	}
+
+	// uint32
+	b.Reset()
+	it = inputT{
+		Maxu: math.MaxUint32 + 1,
+	}
+	type outu32 struct {
+		Maxu uint32
+	}
+	var o6 outu32
+	enc.Encode(it)
+	err = dec.Decode(&o6)
+	if err == nil || err.Error() != `value for "Maxu" out of range` {
+		t.Error("wrong overflow error for uint32:", err)
+	}
+
+	// float32
+	b.Reset()
+	it = inputT{
+		Maxf: math.MaxFloat32 * 2,
+	}
+	type outf32 struct {
+		Maxf float32
+		Minf float32
+	}
+	var o7 outf32
+	enc.Encode(it)
+	err = dec.Decode(&o7)
+	if err == nil || err.Error() != `value for "Maxf" out of range` {
+		t.Error("wrong overflow error for float32:", err)
+	}
+
+	// complex64
+	b.Reset()
+	it = inputT{
+		Maxc: complex(math.MaxFloat32*2, math.MaxFloat32*2),
+	}
+	type outc64 struct {
+		Maxc complex64
+		Minc complex64
+	}
+	var o8 outc64
+	enc.Encode(it)
+	err = dec.Decode(&o8)
+	if err == nil || err.Error() != `value for "Maxc" out of range` {
+		t.Error("wrong overflow error for complex64:", err)
+	}
+}
+
+func TestNesting(t *testing.T) {
+	type RT struct {
+		A    string
+		Next *RT
+	}
+	rt := new(RT)
+	rt.A = "level1"
+	rt.Next = new(RT)
+	rt.Next.A = "level2"
+	b := new(bytes.Buffer)
+	NewEncoder(b).Encode(rt)
+	var drt RT
+	dec := NewDecoder(b)
+	err := dec.Decode(&drt)
+	if err != nil {
+		t.Fatal("decoder error:", err)
+	}
+	if drt.A != rt.A {
+		t.Errorf("nesting: encode expected %v got %v", *rt, drt)
+	}
+	if drt.Next == nil {
+		t.Errorf("nesting: recursion failed")
+	}
+	if drt.Next.A != rt.Next.A {
+		t.Errorf("nesting: encode expected %v got %v", *rt.Next, *drt.Next)
+	}
+}
+
+// These three structures have the same data with different indirections
+type T0 struct {
+	A int
+	B int
+	C int
+	D int
+}
+type T1 struct {
+	A int
+	B *int
+	C **int
+	D ***int
+}
+type T2 struct {
+	A ***int
+	B **int
+	C *int
+	D int
+}
+
+func TestAutoIndirection(t *testing.T) {
+	// First transfer t1 into t0
+	var t1 T1
+	t1.A = 17
+	t1.B = new(int)
+	*t1.B = 177
+	t1.C = new(*int)
+	*t1.C = new(int)
+	**t1.C = 1777
+	t1.D = new(**int)
+	*t1.D = new(*int)
+	**t1.D = new(int)
+	***t1.D = 17777
+	b := new(bytes.Buffer)
+	enc := NewEncoder(b)
+	enc.Encode(t1)
+	dec := NewDecoder(b)
+	var t0 T0
+	dec.Decode(&t0)
+	if t0.A != 17 || t0.B != 177 || t0.C != 1777 || t0.D != 17777 {
+		t.Errorf("t1->t0: expected {17 177 1777 17777}; got %v", t0)
+	}
+
+	// Now transfer t2 into t0
+	var t2 T2
+	t2.D = 17777
+	t2.C = new(int)
+	*t2.C = 1777
+	t2.B = new(*int)
+	*t2.B = new(int)
+	**t2.B = 177
+	t2.A = new(**int)
+	*t2.A = new(*int)
+	**t2.A = new(int)
+	***t2.A = 17
+	b.Reset()
+	enc.Encode(t2)
+	t0 = T0{}
+	dec.Decode(&t0)
+	if t0.A != 17 || t0.B != 177 || t0.C != 1777 || t0.D != 17777 {
+		t.Errorf("t2->t0 expected {17 177 1777 17777}; got %v", t0)
+	}
+
+	// Now transfer t0 into t1
+	t0 = T0{17, 177, 1777, 17777}
+	b.Reset()
+	enc.Encode(t0)
+	t1 = T1{}
+	dec.Decode(&t1)
+	if t1.A != 17 || *t1.B != 177 || **t1.C != 1777 || ***t1.D != 17777 {
+		t.Errorf("t0->t1 expected {17 177 1777 17777}; got {%d %d %d %d}", t1.A, *t1.B, **t1.C, ***t1.D)
+	}
+
+	// Now transfer t0 into t2
+	b.Reset()
+	enc.Encode(t0)
+	t2 = T2{}
+	dec.Decode(&t2)
+	if ***t2.A != 17 || **t2.B != 177 || *t2.C != 1777 || t2.D != 17777 {
+		t.Errorf("t0->t2 expected {17 177 1777 17777}; got {%d %d %d %d}", ***t2.A, **t2.B, *t2.C, t2.D)
+	}
+
+	// Now do t2 again but without pre-allocated pointers.
+	b.Reset()
+	enc.Encode(t0)
+	***t2.A = 0
+	**t2.B = 0
+	*t2.C = 0
+	t2.D = 0
+	dec.Decode(&t2)
+	if ***t2.A != 17 || **t2.B != 177 || *t2.C != 1777 || t2.D != 17777 {
+		t.Errorf("t0->t2 expected {17 177 1777 17777}; got {%d %d %d %d}", ***t2.A, **t2.B, *t2.C, t2.D)
+	}
+}
+
+type RT0 struct {
+	A int
+	B string
+	C float64
+}
+type RT1 struct {
+	C      float64
+	B      string
+	A      int
+	NotSet string
+}
+
+func TestReorderedFields(t *testing.T) {
+	var rt0 RT0
+	rt0.A = 17
+	rt0.B = "hello"
+	rt0.C = 3.14159
+	b := new(bytes.Buffer)
+	NewEncoder(b).Encode(rt0)
+	dec := NewDecoder(b)
+	var rt1 RT1
+	// Wire type is RT0, local type is RT1.
+	err := dec.Decode(&rt1)
+	if err != nil {
+		t.Fatal("decode error:", err)
+	}
+	if rt0.A != rt1.A || rt0.B != rt1.B || rt0.C != rt1.C {
+		t.Errorf("rt1->rt0: expected %v; got %v", rt0, rt1)
+	}
+}
+
+// Like an RT0 but with fields we'll ignore on the decode side.
+type IT0 struct {
+	A        int64
+	B        string
+	Ignore_d []int
+	Ignore_e [3]float64
+	Ignore_f bool
+	Ignore_g string
+	Ignore_h []byte
+	Ignore_i *RT1
+	Ignore_m map[string]int
+	C        float64
+}
+
+func TestIgnoredFields(t *testing.T) {
+	var it0 IT0
+	it0.A = 17
+	it0.B = "hello"
+	it0.C = 3.14159
+	it0.Ignore_d = []int{1, 2, 3}
+	it0.Ignore_e[0] = 1.0
+	it0.Ignore_e[1] = 2.0
+	it0.Ignore_e[2] = 3.0
+	it0.Ignore_f = true
+	it0.Ignore_g = "pay no attention"
+	it0.Ignore_h = []byte("to the curtain")
+	it0.Ignore_i = &RT1{3.1, "hi", 7, "hello"}
+	it0.Ignore_m = map[string]int{"one": 1, "two": 2}
+
+	b := new(bytes.Buffer)
+	NewEncoder(b).Encode(it0)
+	dec := NewDecoder(b)
+	var rt1 RT1
+	// Wire type is IT0, local type is RT1.
+	err := dec.Decode(&rt1)
+	if err != nil {
+		t.Error("error: ", err)
+	}
+	if int(it0.A) != rt1.A || it0.B != rt1.B || it0.C != rt1.C {
+		t.Errorf("rt0->rt1: expected %v; got %v", it0, rt1)
+	}
+}
+
+func TestBadRecursiveType(t *testing.T) {
+	type Rec ***Rec
+	var rec Rec
+	b := new(bytes.Buffer)
+	err := NewEncoder(b).Encode(&rec)
+	if err == nil {
+		t.Error("expected error; got none")
+	} else if strings.Index(err.Error(), "recursive") < 0 {
+		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.
+}
+
+type Indirect struct {
+	A ***[3]int
+	S ***[]int
+	M ****map[string]int
+}
+
+type Direct struct {
+	A [3]int
+	S []int
+	M map[string]int
+}
+
+func TestIndirectSliceMapArray(t *testing.T) {
+	// Marshal indirect, unmarshal to direct.
+	i := new(Indirect)
+	i.A = new(**[3]int)
+	*i.A = new(*[3]int)
+	**i.A = new([3]int)
+	***i.A = [3]int{1, 2, 3}
+	i.S = new(**[]int)
+	*i.S = new(*[]int)
+	**i.S = new([]int)
+	***i.S = []int{4, 5, 6}
+	i.M = new(***map[string]int)
+	*i.M = new(**map[string]int)
+	**i.M = new(*map[string]int)
+	***i.M = new(map[string]int)
+	****i.M = map[string]int{"one": 1, "two": 2, "three": 3}
+	b := new(bytes.Buffer)
+	NewEncoder(b).Encode(i)
+	dec := NewDecoder(b)
+	var d Direct
+	err := dec.Decode(&d)
+	if err != nil {
+		t.Error("error: ", err)
+	}
+	if len(d.A) != 3 || d.A[0] != 1 || d.A[1] != 2 || d.A[2] != 3 {
+		t.Errorf("indirect to direct: d.A is %v not %v", d.A, ***i.A)
+	}
+	if len(d.S) != 3 || d.S[0] != 4 || d.S[1] != 5 || d.S[2] != 6 {
+		t.Errorf("indirect to direct: d.S is %v not %v", d.S, ***i.S)
+	}
+	if len(d.M) != 3 || d.M["one"] != 1 || d.M["two"] != 2 || d.M["three"] != 3 {
+		t.Errorf("indirect to direct: d.M is %v not %v", d.M, ***i.M)
+	}
+	// Marshal direct, unmarshal to indirect.
+	d.A = [3]int{11, 22, 33}
+	d.S = []int{44, 55, 66}
+	d.M = map[string]int{"four": 4, "five": 5, "six": 6}
+	i = new(Indirect)
+	b.Reset()
+	NewEncoder(b).Encode(d)
+	dec = NewDecoder(b)
+	err = dec.Decode(&i)
+	if err != nil {
+		t.Fatal("error: ", err)
+	}
+	if len(***i.A) != 3 || (***i.A)[0] != 11 || (***i.A)[1] != 22 || (***i.A)[2] != 33 {
+		t.Errorf("direct to indirect: ***i.A is %v not %v", ***i.A, d.A)
+	}
+	if len(***i.S) != 3 || (***i.S)[0] != 44 || (***i.S)[1] != 55 || (***i.S)[2] != 66 {
+		t.Errorf("direct to indirect: ***i.S is %v not %v", ***i.S, ***i.S)
+	}
+	if len(****i.M) != 3 || (****i.M)["four"] != 4 || (****i.M)["five"] != 5 || (****i.M)["six"] != 6 {
+		t.Errorf("direct to indirect: ****i.M is %v not %v", ****i.M, d.M)
+	}
+}
+
+// An interface with several implementations
+type Squarer interface {
+	Square() int
+}
+
+type Int int
+
+func (i Int) Square() int {
+	return int(i * i)
+}
+
+type Float float64
+
+func (f Float) Square() int {
+	return int(f * f)
+}
+
+type Vector []int
+
+func (v Vector) Square() int {
+	sum := 0
+	for _, x := range v {
+		sum += x * x
+	}
+	return sum
+}
+
+type Point struct {
+	X, Y int
+}
+
+func (p Point) Square() int {
+	return p.X*p.X + p.Y*p.Y
+}
+
+// A struct with interfaces in it.
+type InterfaceItem struct {
+	I             int
+	Sq1, Sq2, Sq3 Squarer
+	F             float64
+	Sq            []Squarer
+}
+
+// The same struct without interfaces
+type NoInterfaceItem struct {
+	I int
+	F float64
+}
+
+func TestInterface(t *testing.T) {
+	iVal := Int(3)
+	fVal := Float(5)
+	// Sending a Vector will require that the receiver define a type in the middle of
+	// receiving the value for item2.
+	vVal := Vector{1, 2, 3}
+	b := new(bytes.Buffer)
+	item1 := &InterfaceItem{1, iVal, fVal, vVal, 11.5, []Squarer{iVal, fVal, nil, vVal}}
+	// Register the types.
+	Register(Int(0))
+	Register(Float(0))
+	Register(Vector{})
+	err := NewEncoder(b).Encode(item1)
+	if err != nil {
+		t.Error("expected no encode error; got", err)
+	}
+
+	item2 := InterfaceItem{}
+	err = NewDecoder(b).Decode(&item2)
+	if err != nil {
+		t.Fatal("decode:", err)
+	}
+	if item2.I != item1.I {
+		t.Error("normal int did not decode correctly")
+	}
+	if item2.Sq1 == nil || item2.Sq1.Square() != iVal.Square() {
+		t.Error("Int did not decode correctly")
+	}
+	if item2.Sq2 == nil || item2.Sq2.Square() != fVal.Square() {
+		t.Error("Float did not decode correctly")
+	}
+	if item2.Sq3 == nil || item2.Sq3.Square() != vVal.Square() {
+		t.Error("Vector did not decode correctly")
+	}
+	if item2.F != item1.F {
+		t.Error("normal float did not decode correctly")
+	}
+	// Now check that we received a slice of Squarers correctly, including a nil element
+	if len(item1.Sq) != len(item2.Sq) {
+		t.Fatalf("[]Squarer length wrong: got %d; expected %d", len(item2.Sq), len(item1.Sq))
+	}
+	for i, v1 := range item1.Sq {
+		v2 := item2.Sq[i]
+		if v1 == nil || v2 == nil {
+			if v1 != nil || v2 != nil {
+				t.Errorf("item %d inconsistent nils", i)
+			}
+		} else if v1.Square() != v2.Square() {
+			t.Errorf("item %d inconsistent values: %v %v", i, v1, v2)
+		}
+	}
+}
+
+// A struct with all basic types, stored in interfaces.
+type BasicInterfaceItem struct {
+	Int, Int8, Int16, Int32, Int64      interface{}
+	Uint, Uint8, Uint16, Uint32, Uint64 interface{}
+	Float32, Float64                    interface{}
+	Complex64, Complex128               interface{}
+	Bool                                interface{}
+	String                              interface{}
+	Bytes                               interface{}
+}
+
+func TestInterfaceBasic(t *testing.T) {
+	b := new(bytes.Buffer)
+	item1 := &BasicInterfaceItem{
+		int(1), int8(1), int16(1), int32(1), int64(1),
+		uint(1), uint8(1), uint16(1), uint32(1), uint64(1),
+		float32(1), 1.0,
+		complex64(1i), complex128(1i),
+		true,
+		"hello",
+		[]byte("sailor"),
+	}
+	err := NewEncoder(b).Encode(item1)
+	if err != nil {
+		t.Error("expected no encode error; got", err)
+	}
+
+	item2 := &BasicInterfaceItem{}
+	err = NewDecoder(b).Decode(&item2)
+	if err != nil {
+		t.Fatal("decode:", err)
+	}
+	if !reflect.DeepEqual(item1, item2) {
+		t.Errorf("encode expected %v got %v", item1, item2)
+	}
+	// Hand check a couple for correct types.
+	if v, ok := item2.Bool.(bool); !ok || !v {
+		t.Error("boolean should be true")
+	}
+	if v, ok := item2.String.(string); !ok || v != item1.String.(string) {
+		t.Errorf("string should be %v is %v", item1.String, v)
+	}
+}
+
+type String string
+
+type PtrInterfaceItem struct {
+	Str1 interface{} // basic
+	Str2 interface{} // derived
+}
+
+// We'll send pointers; should receive values.
+// Also check that we can register T but send *T.
+func TestInterfacePointer(t *testing.T) {
+	b := new(bytes.Buffer)
+	str1 := "howdy"
+	str2 := String("kiddo")
+	item1 := &PtrInterfaceItem{
+		&str1,
+		&str2,
+	}
+	// Register the type.
+	Register(str2)
+	err := NewEncoder(b).Encode(item1)
+	if err != nil {
+		t.Error("expected no encode error; got", err)
+	}
+
+	item2 := &PtrInterfaceItem{}
+	err = NewDecoder(b).Decode(&item2)
+	if err != nil {
+		t.Fatal("decode:", err)
+	}
+	// Hand test for correct types and values.
+	if v, ok := item2.Str1.(string); !ok || v != str1 {
+		t.Errorf("basic string failed: %q should be %q", v, str1)
+	}
+	if v, ok := item2.Str2.(String); !ok || v != str2 {
+		t.Errorf("derived type String failed: %q should be %q", v, str2)
+	}
+}
+
+func TestIgnoreInterface(t *testing.T) {
+	iVal := Int(3)
+	fVal := Float(5)
+	// Sending a Point will require that the receiver define a type in the middle of
+	// receiving the value for item2.
+	pVal := Point{2, 3}
+	b := new(bytes.Buffer)
+	item1 := &InterfaceItem{1, iVal, fVal, pVal, 11.5, nil}
+	// Register the types.
+	Register(Int(0))
+	Register(Float(0))
+	Register(Point{})
+	err := NewEncoder(b).Encode(item1)
+	if err != nil {
+		t.Error("expected no encode error; got", err)
+	}
+
+	item2 := NoInterfaceItem{}
+	err = NewDecoder(b).Decode(&item2)
+	if err != nil {
+		t.Fatal("decode:", err)
+	}
+	if item2.I != item1.I {
+		t.Error("normal int did not decode correctly")
+	}
+	if item2.F != item2.F {
+		t.Error("normal float did not decode correctly")
+	}
+}
+
+type U struct {
+	A int
+	B string
+	c float64
+	D uint
+}
+
+func TestUnexportedFields(t *testing.T) {
+	var u0 U
+	u0.A = 17
+	u0.B = "hello"
+	u0.c = 3.14159
+	u0.D = 23
+	b := new(bytes.Buffer)
+	NewEncoder(b).Encode(u0)
+	dec := NewDecoder(b)
+	var u1 U
+	u1.c = 1234.
+	err := dec.Decode(&u1)
+	if err != nil {
+		t.Fatal("decode error:", err)
+	}
+	if u0.A != u0.A || u0.B != u1.B || u0.D != u1.D {
+		t.Errorf("u1->u0: expected %v; got %v", u0, u1)
+	}
+	if u1.c != 1234. {
+		t.Error("u1.c modified")
+	}
+}
+
+var singletons = []interface{}{
+	true,
+	7,
+	3.2,
+	"hello",
+	[3]int{11, 22, 33},
+	[]float32{0.5, 0.25, 0.125},
+	map[string]int{"one": 1, "two": 2},
+}
+
+func TestDebugSingleton(t *testing.T) {
+	if debugFunc == nil {
+		return
+	}
+	b := new(bytes.Buffer)
+	// Accumulate a number of values and print them out all at once.
+	for _, x := range singletons {
+		err := NewEncoder(b).Encode(x)
+		if err != nil {
+			t.Fatal("encode:", err)
+		}
+	}
+	debugFunc(b)
+}
+
+// A type that won't be defined in the gob until we send it in an interface value.
+type OnTheFly struct {
+	A int
+}
+
+type DT struct {
+	//	X OnTheFly
+	A     int
+	B     string
+	C     float64
+	I     interface{}
+	J     interface{}
+	I_nil interface{}
+	M     map[string]int
+	T     [3]int
+	S     []string
+}
+
+func newDT() DT {
+	var dt DT
+	dt.A = 17
+	dt.B = "hello"
+	dt.C = 3.14159
+	dt.I = 271828
+	dt.J = OnTheFly{3}
+	dt.I_nil = nil
+	dt.M = map[string]int{"one": 1, "two": 2}
+	dt.T = [3]int{11, 22, 33}
+	dt.S = []string{"hi", "joe"}
+	return dt
+}
+
+func TestDebugStruct(t *testing.T) {
+	if debugFunc == nil {
+		return
+	}
+	Register(OnTheFly{})
+	dt := newDT()
+	b := new(bytes.Buffer)
+	err := NewEncoder(b).Encode(dt)
+	if err != nil {
+		t.Fatal("encode:", err)
+	}
+	debugBuffer := bytes.NewBuffer(b.Bytes())
+	dt2 := &DT{}
+	err = NewDecoder(b).Decode(&dt2)
+	if err != nil {
+		t.Error("decode:", err)
+	}
+	debugFunc(debugBuffer)
+}
+
+func encFuzzDec(rng *rand.Rand, in interface{}) error {
+	buf := new(bytes.Buffer)
+	enc := NewEncoder(buf)
+	if err := enc.Encode(&in); err != nil {
+		return err
+	}
+
+	b := buf.Bytes()
+	for i, bi := range b {
+		if rng.Intn(10) < 3 {
+			b[i] = bi + uint8(rng.Intn(256))
+		}
+	}
+
+	dec := NewDecoder(buf)
+	var e interface{}
+	if err := dec.Decode(&e); err != nil {
+		return err
+	}
+	return nil
+}
+
+// This does some "fuzz testing" by attempting to decode a sequence of random bytes.
+func TestFuzz(t *testing.T) {
+	if !*doFuzzTests {
+		t.Logf("disabled; run with -gob.fuzz to enable")
+		return
+	}
+
+	// all possible inputs
+	input := []interface{}{
+		new(int),
+		new(float32),
+		new(float64),
+		new(complex128),
+		&ByteStruct{255},
+		&ArrayStruct{},
+		&StringStruct{"hello"},
+		&GobTest1{0, &StringStruct{"hello"}},
+	}
+	testFuzz(t, time.Now().UnixNano(), 100, input...)
+}
+
+func TestFuzzRegressions(t *testing.T) {
+	if !*doFuzzTests {
+		t.Logf("disabled; run with -gob.fuzz to enable")
+		return
+	}
+
+	// An instance triggering a type name of length ~102 GB.
+	testFuzz(t, 1328492090837718000, 100, new(float32))
+	// An instance triggering a type name of 1.6 GB.
+	// Note: can take several minutes to run.
+	testFuzz(t, 1330522872628565000, 100, new(int))
+}
+
+func testFuzz(t *testing.T, seed int64, n int, input ...interface{}) {
+	for _, e := range input {
+		t.Logf("seed=%d n=%d e=%T", seed, n, e)
+		rng := rand.New(rand.NewSource(seed))
+		for i := 0; i < n; i++ {
+			encFuzzDec(rng, e)
+		}
+	}
+}
+
+// TestFuzzOneByte tries to decode corrupted input sequences
+// and checks that no panic occurs.
+func TestFuzzOneByte(t *testing.T) {
+	buf := new(bytes.Buffer)
+	Register(OnTheFly{})
+	dt := newDT()
+	if err := NewEncoder(buf).Encode(dt); err != nil {
+		t.Fatal(err)
+	}
+	s := buf.String()
+
+	indices := make([]int, 0, len(s))
+	for i := 0; i < len(s); i++ {
+		switch i {
+		case 14, 167, 231, 265: // a slice length, corruptions are not handled yet.
+			continue
+		}
+		indices = append(indices, i)
+	}
+	if testing.Short() {
+		indices = []int{1, 111, 178} // known fixed panics
+	}
+	for _, i := range indices {
+		for j := 0; j < 256; j += 3 {
+			b := []byte(s)
+			b[i] ^= byte(j)
+			var e DT
+			func() {
+				defer func() {
+					if p := recover(); p != nil {
+						t.Errorf("crash for b[%d] ^= 0x%x", i, j)
+						panic(p)
+					}
+				}()
+				err := NewDecoder(bytes.NewReader(b)).Decode(&e)
+				_ = err
+			}()
+		}
+	}
+}
diff --git a/src/encoding/gob/debug.go b/src/encoding/gob/debug.go
new file mode 100644
index 0000000..536bbdb
--- /dev/null
+++ b/src/encoding/gob/debug.go
@@ -0,0 +1,705 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Delete the next line to include in the gob package.
+// +build ignore
+
+package gob
+
+// This file is not normally included in the gob package.  Used only for debugging the package itself.
+// Except for reading uints, it is an implementation of a reader that is independent of
+// the one implemented by Decoder.
+// To enable the Debug function, delete the +build ignore line above and do
+//	go install
+
+import (
+	"bytes"
+	"fmt"
+	"io"
+	"os"
+	"strings"
+	"sync"
+)
+
+var dumpBytes = false // If true, print the remaining bytes in the input buffer at each item.
+
+// Init installs the debugging facility. If this file is not compiled in the
+// package, the tests in codec_test.go are no-ops.
+func init() {
+	debugFunc = Debug
+}
+
+var (
+	blanks = bytes.Repeat([]byte{' '}, 3*10)
+	empty  = []byte(": <empty>\n")
+	tabs   = strings.Repeat("\t", 100)
+)
+
+// tab indents itself when printed.
+type tab int
+
+func (t tab) String() string {
+	n := int(t)
+	if n > len(tabs) {
+		n = len(tabs)
+	}
+	return tabs[0:n]
+}
+
+func (t tab) print() {
+	fmt.Fprint(os.Stderr, t)
+}
+
+// A peekReader wraps an io.Reader, allowing one to peek ahead to see
+// what's coming without stealing the data from the client of the Reader.
+type peekReader struct {
+	r    io.Reader
+	data []byte // read-ahead data
+}
+
+// newPeekReader returns a peekReader that wraps r.
+func newPeekReader(r io.Reader) *peekReader {
+	return &peekReader{r: r}
+}
+
+// Read is the usual method. It will first take data that has been read ahead.
+func (p *peekReader) Read(b []byte) (n int, err error) {
+	if len(p.data) == 0 {
+		return p.r.Read(b)
+	}
+	// Satisfy what's possible from the read-ahead data.
+	n = copy(b, p.data)
+	// Move data down to beginning of slice, to avoid endless growth
+	copy(p.data, p.data[n:])
+	p.data = p.data[:len(p.data)-n]
+	return
+}
+
+// peek returns as many bytes as possible from the unread
+// portion of the stream, up to the length of b.
+func (p *peekReader) peek(b []byte) (n int, err error) {
+	if len(p.data) > 0 {
+		n = copy(b, p.data)
+		if n == len(b) {
+			return
+		}
+		b = b[n:]
+	}
+	if len(b) == 0 {
+		return
+	}
+	m, e := io.ReadFull(p.r, b)
+	if m > 0 {
+		p.data = append(p.data, b[:m]...)
+	}
+	n += m
+	if e == io.ErrUnexpectedEOF {
+		// That means m > 0 but we reached EOF. If we got data
+		// we won't complain about not being able to peek enough.
+		if n > 0 {
+			e = nil
+		} else {
+			e = io.EOF
+		}
+	}
+	return n, e
+}
+
+type debugger struct {
+	mutex          sync.Mutex
+	remain         int  // the number of bytes known to remain in the input
+	remainingKnown bool // the value of 'remain' is valid
+	r              *peekReader
+	wireType       map[typeId]*wireType
+	tmp            []byte // scratch space for decoding uints.
+}
+
+// dump prints the next nBytes of the input.
+// It arranges to print the output aligned from call to
+// call, to make it easy to see what has been consumed.
+func (deb *debugger) dump(format string, args ...interface{}) {
+	if !dumpBytes {
+		return
+	}
+	fmt.Fprintf(os.Stderr, format+" ", args...)
+	if !deb.remainingKnown {
+		return
+	}
+	if deb.remain < 0 {
+		fmt.Fprintf(os.Stderr, "remaining byte count is negative! %d\n", deb.remain)
+		return
+	}
+	data := make([]byte, deb.remain)
+	n, _ := deb.r.peek(data)
+	if n == 0 {
+		os.Stderr.Write(empty)
+		return
+	}
+	b := new(bytes.Buffer)
+	fmt.Fprintf(b, "[%d]{\n", deb.remain)
+	// Blanks until first byte
+	lineLength := 0
+	if n := len(data); n%10 != 0 {
+		lineLength = 10 - n%10
+		fmt.Fprintf(b, "\t%s", blanks[:lineLength*3])
+	}
+	// 10 bytes per line
+	for len(data) > 0 {
+		if lineLength == 0 {
+			fmt.Fprint(b, "\t")
+		}
+		m := 10 - lineLength
+		lineLength = 0
+		if m > len(data) {
+			m = len(data)
+		}
+		fmt.Fprintf(b, "% x\n", data[:m])
+		data = data[m:]
+	}
+	fmt.Fprint(b, "}\n")
+	os.Stderr.Write(b.Bytes())
+}
+
+// Debug prints a human-readable representation of the gob data read from r.
+// It is a no-op unless debugging was enabled when the package was built.
+func Debug(r io.Reader) {
+	err := debug(r)
+	if err != nil {
+		fmt.Fprintf(os.Stderr, "gob debug: %s\n", err)
+	}
+}
+
+// debug implements Debug, but catches panics and returns
+// them as errors to be printed by Debug.
+func debug(r io.Reader) (err error) {
+	defer catchError(&err)
+	fmt.Fprintln(os.Stderr, "Start of debugging")
+	deb := &debugger{
+		r:        newPeekReader(r),
+		wireType: make(map[typeId]*wireType),
+		tmp:      make([]byte, 16),
+	}
+	if b, ok := r.(*bytes.Buffer); ok {
+		deb.remain = b.Len()
+		deb.remainingKnown = true
+	}
+	deb.gobStream()
+	return
+}
+
+// note that we've consumed some bytes
+func (deb *debugger) consumed(n int) {
+	if deb.remainingKnown {
+		deb.remain -= n
+	}
+}
+
+// int64 decodes and returns the next integer, which must be present.
+// Don't call this if you could be at EOF.
+func (deb *debugger) int64() int64 {
+	return toInt(deb.uint64())
+}
+
+// uint64 returns and decodes the next unsigned integer, which must be present.
+// Don't call this if you could be at EOF.
+// TODO: handle errors better.
+func (deb *debugger) uint64() uint64 {
+	n, w, err := decodeUintReader(deb.r, deb.tmp)
+	if err != nil {
+		errorf("debug: read error: %s", err)
+	}
+	deb.consumed(w)
+	return n
+}
+
+// GobStream:
+//	DelimitedMessage* (until EOF)
+func (deb *debugger) gobStream() {
+	// Make sure we're single-threaded through here.
+	deb.mutex.Lock()
+	defer deb.mutex.Unlock()
+
+	for deb.delimitedMessage(0) {
+	}
+}
+
+// DelimitedMessage:
+//	uint(lengthOfMessage) Message
+func (deb *debugger) delimitedMessage(indent tab) bool {
+	for {
+		n := deb.loadBlock(true)
+		if n < 0 {
+			return false
+		}
+		deb.dump("Delimited message of length %d", n)
+		deb.message(indent)
+	}
+	return true
+}
+
+// loadBlock preps us to read a message
+// of the length specified next in the input. It returns
+// the length of the block. The argument tells whether
+// an EOF is acceptable now.  If it is and one is found,
+// the return value is negative.
+func (deb *debugger) loadBlock(eofOK bool) int {
+	n64, w, err := decodeUintReader(deb.r, deb.tmp) // deb.uint64 will error at EOF
+	if err != nil {
+		if eofOK && err == io.EOF {
+			return -1
+		}
+		errorf("debug: unexpected error: %s", err)
+	}
+	deb.consumed(w)
+	n := int(n64)
+	if n < 0 {
+		errorf("huge value for message length: %d", n64)
+	}
+	return int(n)
+}
+
+// Message:
+//	TypeSequence TypedValue
+// TypeSequence
+//	(TypeDefinition DelimitedTypeDefinition*)?
+// DelimitedTypeDefinition:
+//	uint(lengthOfTypeDefinition) TypeDefinition
+// TypedValue:
+//	int(typeId) Value
+func (deb *debugger) message(indent tab) bool {
+	for {
+		// Convert the uint64 to a signed integer typeId
+		uid := deb.int64()
+		id := typeId(uid)
+		deb.dump("type id=%d", id)
+		if id < 0 {
+			deb.typeDefinition(indent, -id)
+			n := deb.loadBlock(false)
+			deb.dump("Message of length %d", n)
+			continue
+		} else {
+			deb.value(indent, id)
+			break
+		}
+	}
+	return true
+}
+
+// Helper methods to make it easy to scan a type descriptor.
+
+// common returns the CommonType at the input point.
+func (deb *debugger) common() CommonType {
+	fieldNum := -1
+	name := ""
+	id := typeId(0)
+	for {
+		delta := deb.delta(-1)
+		if delta == 0 {
+			break
+		}
+		fieldNum += delta
+		switch fieldNum {
+		case 0:
+			name = deb.string()
+		case 1:
+			// Id typeId
+			id = deb.typeId()
+		default:
+			errorf("corrupted CommonType, delta is %d fieldNum is %d", delta, fieldNum)
+		}
+	}
+	return CommonType{name, id}
+}
+
+// uint returns the unsigned int at the input point, as a uint (not uint64).
+func (deb *debugger) uint() uint {
+	return uint(deb.uint64())
+}
+
+// int returns the signed int at the input point, as an int (not int64).
+func (deb *debugger) int() int {
+	return int(deb.int64())
+}
+
+// typeId returns the type id at the input point.
+func (deb *debugger) typeId() typeId {
+	return typeId(deb.int64())
+}
+
+// string returns the string at the input point.
+func (deb *debugger) string() string {
+	x := int(deb.uint64())
+	b := make([]byte, x)
+	nb, _ := deb.r.Read(b)
+	if nb != x {
+		errorf("corrupted type")
+	}
+	deb.consumed(nb)
+	return string(b)
+}
+
+// delta returns the field delta at the input point.  The expect argument,
+// if non-negative, identifies what the value should be.
+func (deb *debugger) delta(expect int) int {
+	delta := int(deb.uint64())
+	if delta < 0 || (expect >= 0 && delta != expect) {
+		errorf("decode: corrupted type: delta %d expected %d", delta, expect)
+	}
+	return delta
+}
+
+// TypeDefinition:
+//	[int(-typeId) (already read)] encodingOfWireType
+func (deb *debugger) typeDefinition(indent tab, id typeId) {
+	deb.dump("type definition for id %d", id)
+	// Encoding is of a wireType. Decode the structure as usual
+	fieldNum := -1
+	wire := new(wireType)
+	// A wireType defines a single field.
+	delta := deb.delta(-1)
+	fieldNum += delta
+	switch fieldNum {
+	case 0: // array type, one field of {{Common}, elem, length}
+		// Field number 0 is CommonType
+		deb.delta(1)
+		com := deb.common()
+		// Field number 1 is type Id of elem
+		deb.delta(1)
+		id := deb.typeId()
+		// Field number 3 is length
+		deb.delta(1)
+		length := deb.int()
+		wire.ArrayT = &arrayType{com, id, length}
+
+	case 1: // slice type, one field of {{Common}, elem}
+		// Field number 0 is CommonType
+		deb.delta(1)
+		com := deb.common()
+		// Field number 1 is type Id of elem
+		deb.delta(1)
+		id := deb.typeId()
+		wire.SliceT = &sliceType{com, id}
+
+	case 2: // struct type, one field of {{Common}, []fieldType}
+		// Field number 0 is CommonType
+		deb.delta(1)
+		com := deb.common()
+		// Field number 1 is slice of FieldType
+		deb.delta(1)
+		numField := int(deb.uint())
+		field := make([]*fieldType, numField)
+		for i := 0; i < numField; i++ {
+			field[i] = new(fieldType)
+			deb.delta(1) // field 0 of fieldType: name
+			field[i].Name = deb.string()
+			deb.delta(1) // field 1 of fieldType: id
+			field[i].Id = deb.typeId()
+			deb.delta(0) // end of fieldType
+		}
+		wire.StructT = &structType{com, field}
+
+	case 3: // map type, one field of {{Common}, key, elem}
+		// Field number 0 is CommonType
+		deb.delta(1)
+		com := deb.common()
+		// Field number 1 is type Id of key
+		deb.delta(1)
+		keyId := deb.typeId()
+		// Field number 2 is type Id of elem
+		deb.delta(1)
+		elemId := deb.typeId()
+		wire.MapT = &mapType{com, keyId, elemId}
+	case 4: // GobEncoder type, one field of {{Common}}
+		// Field number 0 is CommonType
+		deb.delta(1)
+		com := deb.common()
+		wire.GobEncoderT = &gobEncoderType{com}
+	case 5: // BinaryMarshaler type, one field of {{Common}}
+		// Field number 0 is CommonType
+		deb.delta(1)
+		com := deb.common()
+		wire.BinaryMarshalerT = &gobEncoderType{com}
+	case 6: // TextMarshaler type, one field of {{Common}}
+		// Field number 0 is CommonType
+		deb.delta(1)
+		com := deb.common()
+		wire.TextMarshalerT = &gobEncoderType{com}
+	default:
+		errorf("bad field in type %d", fieldNum)
+	}
+	deb.printWireType(indent, wire)
+	deb.delta(0) // end inner type (arrayType, etc.)
+	deb.delta(0) // end wireType
+	// Remember we've seen this type.
+	deb.wireType[id] = wire
+}
+
+// Value:
+//	SingletonValue | StructValue
+func (deb *debugger) value(indent tab, id typeId) {
+	wire, ok := deb.wireType[id]
+	if ok && wire.StructT != nil {
+		deb.structValue(indent, id)
+	} else {
+		deb.singletonValue(indent, id)
+	}
+}
+
+// SingletonValue:
+//	uint(0) FieldValue
+func (deb *debugger) singletonValue(indent tab, id typeId) {
+	deb.dump("Singleton value")
+	// is it a builtin type?
+	wire := deb.wireType[id]
+	_, ok := builtinIdToType[id]
+	if !ok && wire == nil {
+		errorf("type id %d not defined", id)
+	}
+	m := deb.uint64()
+	if m != 0 {
+		errorf("expected zero; got %d", m)
+	}
+	deb.fieldValue(indent, id)
+}
+
+// InterfaceValue:
+//	NilInterfaceValue | NonNilInterfaceValue
+func (deb *debugger) interfaceValue(indent tab) {
+	deb.dump("Start of interface value")
+	if nameLen := deb.uint64(); nameLen == 0 {
+		deb.nilInterfaceValue(indent)
+	} else {
+		deb.nonNilInterfaceValue(indent, int(nameLen))
+	}
+}
+
+// NilInterfaceValue:
+//	uint(0) [already read]
+func (deb *debugger) nilInterfaceValue(indent tab) int {
+	fmt.Fprintf(os.Stderr, "%snil interface\n", indent)
+	return 0
+}
+
+// NonNilInterfaceValue:
+//	ConcreteTypeName TypeSequence InterfaceContents
+// ConcreteTypeName:
+//	uint(lengthOfName) [already read=n] name
+// InterfaceContents:
+//	int(concreteTypeId) DelimitedValue
+// DelimitedValue:
+//	uint(length) Value
+func (deb *debugger) nonNilInterfaceValue(indent tab, nameLen int) {
+	// ConcreteTypeName
+	b := make([]byte, nameLen)
+	deb.r.Read(b) // TODO: CHECK THESE READS!!
+	deb.consumed(nameLen)
+	name := string(b)
+
+	for {
+		id := deb.typeId()
+		if id < 0 {
+			deb.typeDefinition(indent, -id)
+			n := deb.loadBlock(false)
+			deb.dump("Nested message of length %d", n)
+		} else {
+			// DelimitedValue
+			x := deb.uint64() // in case we want to ignore the value; we don't.
+			fmt.Fprintf(os.Stderr, "%sinterface value, type %q id=%d; valueLength %d\n", indent, name, id, x)
+			deb.value(indent, id)
+			break
+		}
+	}
+}
+
+// printCommonType prints a common type; used by printWireType.
+func (deb *debugger) printCommonType(indent tab, kind string, common *CommonType) {
+	indent.print()
+	fmt.Fprintf(os.Stderr, "%s %q id=%d\n", kind, common.Name, common.Id)
+}
+
+// printWireType prints the contents of a wireType.
+func (deb *debugger) printWireType(indent tab, wire *wireType) {
+	fmt.Fprintf(os.Stderr, "%stype definition {\n", indent)
+	indent++
+	switch {
+	case wire.ArrayT != nil:
+		deb.printCommonType(indent, "array", &wire.ArrayT.CommonType)
+		fmt.Fprintf(os.Stderr, "%slen %d\n", indent+1, wire.ArrayT.Len)
+		fmt.Fprintf(os.Stderr, "%selemid %d\n", indent+1, wire.ArrayT.Elem)
+	case wire.MapT != nil:
+		deb.printCommonType(indent, "map", &wire.MapT.CommonType)
+		fmt.Fprintf(os.Stderr, "%skey id=%d\n", indent+1, wire.MapT.Key)
+		fmt.Fprintf(os.Stderr, "%selem id=%d\n", indent+1, wire.MapT.Elem)
+	case wire.SliceT != nil:
+		deb.printCommonType(indent, "slice", &wire.SliceT.CommonType)
+		fmt.Fprintf(os.Stderr, "%selem id=%d\n", indent+1, wire.SliceT.Elem)
+	case wire.StructT != nil:
+		deb.printCommonType(indent, "struct", &wire.StructT.CommonType)
+		for i, field := range wire.StructT.Field {
+			fmt.Fprintf(os.Stderr, "%sfield %d:\t%s\tid=%d\n", indent+1, i, field.Name, field.Id)
+		}
+	case wire.GobEncoderT != nil:
+		deb.printCommonType(indent, "GobEncoder", &wire.GobEncoderT.CommonType)
+	}
+	indent--
+	fmt.Fprintf(os.Stderr, "%s}\n", indent)
+}
+
+// fieldValue prints a value of any type, such as a struct field.
+// FieldValue:
+//	builtinValue | ArrayValue | MapValue | SliceValue | StructValue | InterfaceValue
+func (deb *debugger) fieldValue(indent tab, id typeId) {
+	_, ok := builtinIdToType[id]
+	if ok {
+		if id == tInterface {
+			deb.interfaceValue(indent)
+		} else {
+			deb.printBuiltin(indent, id)
+		}
+		return
+	}
+	wire, ok := deb.wireType[id]
+	if !ok {
+		errorf("type id %d not defined", id)
+	}
+	switch {
+	case wire.ArrayT != nil:
+		deb.arrayValue(indent, wire)
+	case wire.MapT != nil:
+		deb.mapValue(indent, wire)
+	case wire.SliceT != nil:
+		deb.sliceValue(indent, wire)
+	case wire.StructT != nil:
+		deb.structValue(indent, id)
+	case wire.GobEncoderT != nil:
+		deb.gobEncoderValue(indent, id)
+	default:
+		panic("bad wire type for field")
+	}
+}
+
+// printBuiltin prints a value not of a fundamental type, that is,
+// one whose type is known to gobs at bootstrap time.
+func (deb *debugger) printBuiltin(indent tab, id typeId) {
+	switch id {
+	case tBool:
+		x := deb.int64()
+		if x == 0 {
+			fmt.Fprintf(os.Stderr, "%sfalse\n", indent)
+		} else {
+			fmt.Fprintf(os.Stderr, "%strue\n", indent)
+		}
+	case tInt:
+		x := deb.int64()
+		fmt.Fprintf(os.Stderr, "%s%d\n", indent, x)
+	case tUint:
+		x := deb.int64()
+		fmt.Fprintf(os.Stderr, "%s%d\n", indent, x)
+	case tFloat:
+		x := deb.uint64()
+		fmt.Fprintf(os.Stderr, "%s%g\n", indent, float64FromBits(x))
+	case tComplex:
+		r := deb.uint64()
+		i := deb.uint64()
+		fmt.Fprintf(os.Stderr, "%s%g+%gi\n", indent, float64FromBits(r), float64FromBits(i))
+	case tBytes:
+		x := int(deb.uint64())
+		b := make([]byte, x)
+		deb.r.Read(b)
+		deb.consumed(x)
+		fmt.Fprintf(os.Stderr, "%s{% x}=%q\n", indent, b, b)
+	case tString:
+		x := int(deb.uint64())
+		b := make([]byte, x)
+		deb.r.Read(b)
+		deb.consumed(x)
+		fmt.Fprintf(os.Stderr, "%s%q\n", indent, b)
+	default:
+		panic("unknown builtin")
+	}
+}
+
+// ArrayValue:
+//	uint(n) FieldValue*n
+func (deb *debugger) arrayValue(indent tab, wire *wireType) {
+	elemId := wire.ArrayT.Elem
+	u := deb.uint64()
+	length := int(u)
+	for i := 0; i < length; i++ {
+		deb.fieldValue(indent, elemId)
+	}
+	if length != wire.ArrayT.Len {
+		fmt.Fprintf(os.Stderr, "%s(wrong length for array: %d should be %d)\n", indent, length, wire.ArrayT.Len)
+	}
+}
+
+// MapValue:
+//	uint(n) (FieldValue FieldValue)*n  [n (key, value) pairs]
+func (deb *debugger) mapValue(indent tab, wire *wireType) {
+	keyId := wire.MapT.Key
+	elemId := wire.MapT.Elem
+	u := deb.uint64()
+	length := int(u)
+	for i := 0; i < length; i++ {
+		deb.fieldValue(indent+1, keyId)
+		deb.fieldValue(indent+1, elemId)
+	}
+}
+
+// SliceValue:
+//	uint(n) (n FieldValue)
+func (deb *debugger) sliceValue(indent tab, wire *wireType) {
+	elemId := wire.SliceT.Elem
+	u := deb.uint64()
+	length := int(u)
+	deb.dump("Start of slice of length %d", length)
+
+	for i := 0; i < length; i++ {
+		deb.fieldValue(indent, elemId)
+	}
+}
+
+// StructValue:
+//	(uint(fieldDelta) FieldValue)*
+func (deb *debugger) structValue(indent tab, id typeId) {
+	deb.dump("Start of struct value of %q id=%d\n<<\n", id.name(), id)
+	fmt.Fprintf(os.Stderr, "%s%s struct {\n", indent, id.name())
+	wire, ok := deb.wireType[id]
+	if !ok {
+		errorf("type id %d not defined", id)
+	}
+	strct := wire.StructT
+	fieldNum := -1
+	indent++
+	for {
+		delta := deb.uint64()
+		if delta == 0 { // struct terminator is zero delta fieldnum
+			break
+		}
+		fieldNum += int(delta)
+		if fieldNum < 0 || fieldNum >= len(strct.Field) {
+			deb.dump("field number out of range: prevField=%d delta=%d", fieldNum-int(delta), delta)
+			break
+		}
+		fmt.Fprintf(os.Stderr, "%sfield %d:\t%s\n", indent, fieldNum, wire.StructT.Field[fieldNum].Name)
+		deb.fieldValue(indent+1, strct.Field[fieldNum].Id)
+	}
+	indent--
+	fmt.Fprintf(os.Stderr, "%s} // end %s struct\n", indent, id.name())
+	deb.dump(">> End of struct value of type %d %q", id, id.name())
+}
+
+// GobEncoderValue:
+//	uint(n) byte*n
+func (deb *debugger) gobEncoderValue(indent tab, id typeId) {
+	len := deb.uint64()
+	deb.dump("GobEncoder value of %q id=%d, length %d\n", id.name(), id, len)
+	fmt.Fprintf(os.Stderr, "%s%s (implements GobEncoder)\n", indent, id.name())
+	data := make([]byte, len)
+	_, err := deb.r.Read(data)
+	if err != nil {
+		errorf("gobEncoder data read: %s", err)
+	}
+	fmt.Fprintf(os.Stderr, "%s[% .2x]\n", indent+1, data)
+}
diff --git a/src/encoding/gob/dec_helpers.go b/src/encoding/gob/dec_helpers.go
new file mode 100644
index 0000000..a1b6766
--- /dev/null
+++ b/src/encoding/gob/dec_helpers.go
@@ -0,0 +1,468 @@
+// Created by decgen --output dec_helpers.go; DO NOT EDIT
+
+// 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 gob
+
+import (
+	"math"
+	"reflect"
+)
+
+var decArrayHelper = map[reflect.Kind]decHelper{
+	reflect.Bool:       decBoolArray,
+	reflect.Complex64:  decComplex64Array,
+	reflect.Complex128: decComplex128Array,
+	reflect.Float32:    decFloat32Array,
+	reflect.Float64:    decFloat64Array,
+	reflect.Int:        decIntArray,
+	reflect.Int16:      decInt16Array,
+	reflect.Int32:      decInt32Array,
+	reflect.Int64:      decInt64Array,
+	reflect.Int8:       decInt8Array,
+	reflect.String:     decStringArray,
+	reflect.Uint:       decUintArray,
+	reflect.Uint16:     decUint16Array,
+	reflect.Uint32:     decUint32Array,
+	reflect.Uint64:     decUint64Array,
+	reflect.Uintptr:    decUintptrArray,
+}
+
+var decSliceHelper = map[reflect.Kind]decHelper{
+	reflect.Bool:       decBoolSlice,
+	reflect.Complex64:  decComplex64Slice,
+	reflect.Complex128: decComplex128Slice,
+	reflect.Float32:    decFloat32Slice,
+	reflect.Float64:    decFloat64Slice,
+	reflect.Int:        decIntSlice,
+	reflect.Int16:      decInt16Slice,
+	reflect.Int32:      decInt32Slice,
+	reflect.Int64:      decInt64Slice,
+	reflect.Int8:       decInt8Slice,
+	reflect.String:     decStringSlice,
+	reflect.Uint:       decUintSlice,
+	reflect.Uint16:     decUint16Slice,
+	reflect.Uint32:     decUint32Slice,
+	reflect.Uint64:     decUint64Slice,
+	reflect.Uintptr:    decUintptrSlice,
+}
+
+func decBoolArray(state *decoderState, v reflect.Value, length int, ovfl error) bool {
+	// Can only slice if it is addressable.
+	if !v.CanAddr() {
+		return false
+	}
+	return decBoolSlice(state, v.Slice(0, v.Len()), length, ovfl)
+}
+
+func decBoolSlice(state *decoderState, v reflect.Value, length int, ovfl error) bool {
+	slice, ok := v.Interface().([]bool)
+	if !ok {
+		// It is kind bool but not type bool. TODO: We can handle this unsafely.
+		return false
+	}
+	for i := 0; i < length; i++ {
+		if state.b.Len() == 0 {
+			errorf("decoding bool array or slice: length exceeds input size (%d elements)", length)
+		}
+		slice[i] = state.decodeUint() != 0
+	}
+	return true
+}
+
+func decComplex64Array(state *decoderState, v reflect.Value, length int, ovfl error) bool {
+	// Can only slice if it is addressable.
+	if !v.CanAddr() {
+		return false
+	}
+	return decComplex64Slice(state, v.Slice(0, v.Len()), length, ovfl)
+}
+
+func decComplex64Slice(state *decoderState, v reflect.Value, length int, ovfl error) bool {
+	slice, ok := v.Interface().([]complex64)
+	if !ok {
+		// It is kind complex64 but not type complex64. TODO: We can handle this unsafely.
+		return false
+	}
+	for i := 0; i < length; i++ {
+		if state.b.Len() == 0 {
+			errorf("decoding complex64 array or slice: length exceeds input size (%d elements)", length)
+		}
+		real := float32FromBits(state.decodeUint(), ovfl)
+		imag := float32FromBits(state.decodeUint(), ovfl)
+		slice[i] = complex(float32(real), float32(imag))
+	}
+	return true
+}
+
+func decComplex128Array(state *decoderState, v reflect.Value, length int, ovfl error) bool {
+	// Can only slice if it is addressable.
+	if !v.CanAddr() {
+		return false
+	}
+	return decComplex128Slice(state, v.Slice(0, v.Len()), length, ovfl)
+}
+
+func decComplex128Slice(state *decoderState, v reflect.Value, length int, ovfl error) bool {
+	slice, ok := v.Interface().([]complex128)
+	if !ok {
+		// It is kind complex128 but not type complex128. TODO: We can handle this unsafely.
+		return false
+	}
+	for i := 0; i < length; i++ {
+		if state.b.Len() == 0 {
+			errorf("decoding complex128 array or slice: length exceeds input size (%d elements)", length)
+		}
+		real := float64FromBits(state.decodeUint())
+		imag := float64FromBits(state.decodeUint())
+		slice[i] = complex(real, imag)
+	}
+	return true
+}
+
+func decFloat32Array(state *decoderState, v reflect.Value, length int, ovfl error) bool {
+	// Can only slice if it is addressable.
+	if !v.CanAddr() {
+		return false
+	}
+	return decFloat32Slice(state, v.Slice(0, v.Len()), length, ovfl)
+}
+
+func decFloat32Slice(state *decoderState, v reflect.Value, length int, ovfl error) bool {
+	slice, ok := v.Interface().([]float32)
+	if !ok {
+		// It is kind float32 but not type float32. TODO: We can handle this unsafely.
+		return false
+	}
+	for i := 0; i < length; i++ {
+		if state.b.Len() == 0 {
+			errorf("decoding float32 array or slice: length exceeds input size (%d elements)", length)
+		}
+		slice[i] = float32(float32FromBits(state.decodeUint(), ovfl))
+	}
+	return true
+}
+
+func decFloat64Array(state *decoderState, v reflect.Value, length int, ovfl error) bool {
+	// Can only slice if it is addressable.
+	if !v.CanAddr() {
+		return false
+	}
+	return decFloat64Slice(state, v.Slice(0, v.Len()), length, ovfl)
+}
+
+func decFloat64Slice(state *decoderState, v reflect.Value, length int, ovfl error) bool {
+	slice, ok := v.Interface().([]float64)
+	if !ok {
+		// It is kind float64 but not type float64. TODO: We can handle this unsafely.
+		return false
+	}
+	for i := 0; i < length; i++ {
+		if state.b.Len() == 0 {
+			errorf("decoding float64 array or slice: length exceeds input size (%d elements)", length)
+		}
+		slice[i] = float64FromBits(state.decodeUint())
+	}
+	return true
+}
+
+func decIntArray(state *decoderState, v reflect.Value, length int, ovfl error) bool {
+	// Can only slice if it is addressable.
+	if !v.CanAddr() {
+		return false
+	}
+	return decIntSlice(state, v.Slice(0, v.Len()), length, ovfl)
+}
+
+func decIntSlice(state *decoderState, v reflect.Value, length int, ovfl error) bool {
+	slice, ok := v.Interface().([]int)
+	if !ok {
+		// It is kind int but not type int. TODO: We can handle this unsafely.
+		return false
+	}
+	for i := 0; i < length; i++ {
+		if state.b.Len() == 0 {
+			errorf("decoding int array or slice: length exceeds input size (%d elements)", length)
+		}
+		x := state.decodeInt()
+		// MinInt and MaxInt
+		if x < ^int64(^uint(0)>>1) || int64(^uint(0)>>1) < x {
+			error_(ovfl)
+		}
+		slice[i] = int(x)
+	}
+	return true
+}
+
+func decInt16Array(state *decoderState, v reflect.Value, length int, ovfl error) bool {
+	// Can only slice if it is addressable.
+	if !v.CanAddr() {
+		return false
+	}
+	return decInt16Slice(state, v.Slice(0, v.Len()), length, ovfl)
+}
+
+func decInt16Slice(state *decoderState, v reflect.Value, length int, ovfl error) bool {
+	slice, ok := v.Interface().([]int16)
+	if !ok {
+		// It is kind int16 but not type int16. TODO: We can handle this unsafely.
+		return false
+	}
+	for i := 0; i < length; i++ {
+		if state.b.Len() == 0 {
+			errorf("decoding int16 array or slice: length exceeds input size (%d elements)", length)
+		}
+		x := state.decodeInt()
+		if x < math.MinInt16 || math.MaxInt16 < x {
+			error_(ovfl)
+		}
+		slice[i] = int16(x)
+	}
+	return true
+}
+
+func decInt32Array(state *decoderState, v reflect.Value, length int, ovfl error) bool {
+	// Can only slice if it is addressable.
+	if !v.CanAddr() {
+		return false
+	}
+	return decInt32Slice(state, v.Slice(0, v.Len()), length, ovfl)
+}
+
+func decInt32Slice(state *decoderState, v reflect.Value, length int, ovfl error) bool {
+	slice, ok := v.Interface().([]int32)
+	if !ok {
+		// It is kind int32 but not type int32. TODO: We can handle this unsafely.
+		return false
+	}
+	for i := 0; i < length; i++ {
+		if state.b.Len() == 0 {
+			errorf("decoding int32 array or slice: length exceeds input size (%d elements)", length)
+		}
+		x := state.decodeInt()
+		if x < math.MinInt32 || math.MaxInt32 < x {
+			error_(ovfl)
+		}
+		slice[i] = int32(x)
+	}
+	return true
+}
+
+func decInt64Array(state *decoderState, v reflect.Value, length int, ovfl error) bool {
+	// Can only slice if it is addressable.
+	if !v.CanAddr() {
+		return false
+	}
+	return decInt64Slice(state, v.Slice(0, v.Len()), length, ovfl)
+}
+
+func decInt64Slice(state *decoderState, v reflect.Value, length int, ovfl error) bool {
+	slice, ok := v.Interface().([]int64)
+	if !ok {
+		// It is kind int64 but not type int64. TODO: We can handle this unsafely.
+		return false
+	}
+	for i := 0; i < length; i++ {
+		if state.b.Len() == 0 {
+			errorf("decoding int64 array or slice: length exceeds input size (%d elements)", length)
+		}
+		slice[i] = state.decodeInt()
+	}
+	return true
+}
+
+func decInt8Array(state *decoderState, v reflect.Value, length int, ovfl error) bool {
+	// Can only slice if it is addressable.
+	if !v.CanAddr() {
+		return false
+	}
+	return decInt8Slice(state, v.Slice(0, v.Len()), length, ovfl)
+}
+
+func decInt8Slice(state *decoderState, v reflect.Value, length int, ovfl error) bool {
+	slice, ok := v.Interface().([]int8)
+	if !ok {
+		// It is kind int8 but not type int8. TODO: We can handle this unsafely.
+		return false
+	}
+	for i := 0; i < length; i++ {
+		if state.b.Len() == 0 {
+			errorf("decoding int8 array or slice: length exceeds input size (%d elements)", length)
+		}
+		x := state.decodeInt()
+		if x < math.MinInt8 || math.MaxInt8 < x {
+			error_(ovfl)
+		}
+		slice[i] = int8(x)
+	}
+	return true
+}
+
+func decStringArray(state *decoderState, v reflect.Value, length int, ovfl error) bool {
+	// Can only slice if it is addressable.
+	if !v.CanAddr() {
+		return false
+	}
+	return decStringSlice(state, v.Slice(0, v.Len()), length, ovfl)
+}
+
+func decStringSlice(state *decoderState, v reflect.Value, length int, ovfl error) bool {
+	slice, ok := v.Interface().([]string)
+	if !ok {
+		// It is kind string but not type string. TODO: We can handle this unsafely.
+		return false
+	}
+	for i := 0; i < length; i++ {
+		if state.b.Len() == 0 {
+			errorf("decoding string array or slice: length exceeds input size (%d elements)", length)
+		}
+		u := state.decodeUint()
+		n := int(u)
+		if n < 0 || uint64(n) != u || n > state.b.Len() {
+			errorf("length of string exceeds input size (%d bytes)", u)
+		}
+		if n > state.b.Len() {
+			errorf("string data too long for buffer: %d", n)
+		}
+		// Read the data.
+		data := make([]byte, n)
+		if _, err := state.b.Read(data); err != nil {
+			errorf("error decoding string: %s", err)
+		}
+		slice[i] = string(data)
+	}
+	return true
+}
+
+func decUintArray(state *decoderState, v reflect.Value, length int, ovfl error) bool {
+	// Can only slice if it is addressable.
+	if !v.CanAddr() {
+		return false
+	}
+	return decUintSlice(state, v.Slice(0, v.Len()), length, ovfl)
+}
+
+func decUintSlice(state *decoderState, v reflect.Value, length int, ovfl error) bool {
+	slice, ok := v.Interface().([]uint)
+	if !ok {
+		// It is kind uint but not type uint. TODO: We can handle this unsafely.
+		return false
+	}
+	for i := 0; i < length; i++ {
+		if state.b.Len() == 0 {
+			errorf("decoding uint array or slice: length exceeds input size (%d elements)", length)
+		}
+		x := state.decodeUint()
+		/*TODO if math.MaxUint32 < x {
+			error_(ovfl)
+		}*/
+		slice[i] = uint(x)
+	}
+	return true
+}
+
+func decUint16Array(state *decoderState, v reflect.Value, length int, ovfl error) bool {
+	// Can only slice if it is addressable.
+	if !v.CanAddr() {
+		return false
+	}
+	return decUint16Slice(state, v.Slice(0, v.Len()), length, ovfl)
+}
+
+func decUint16Slice(state *decoderState, v reflect.Value, length int, ovfl error) bool {
+	slice, ok := v.Interface().([]uint16)
+	if !ok {
+		// It is kind uint16 but not type uint16. TODO: We can handle this unsafely.
+		return false
+	}
+	for i := 0; i < length; i++ {
+		if state.b.Len() == 0 {
+			errorf("decoding uint16 array or slice: length exceeds input size (%d elements)", length)
+		}
+		x := state.decodeUint()
+		if math.MaxUint16 < x {
+			error_(ovfl)
+		}
+		slice[i] = uint16(x)
+	}
+	return true
+}
+
+func decUint32Array(state *decoderState, v reflect.Value, length int, ovfl error) bool {
+	// Can only slice if it is addressable.
+	if !v.CanAddr() {
+		return false
+	}
+	return decUint32Slice(state, v.Slice(0, v.Len()), length, ovfl)
+}
+
+func decUint32Slice(state *decoderState, v reflect.Value, length int, ovfl error) bool {
+	slice, ok := v.Interface().([]uint32)
+	if !ok {
+		// It is kind uint32 but not type uint32. TODO: We can handle this unsafely.
+		return false
+	}
+	for i := 0; i < length; i++ {
+		if state.b.Len() == 0 {
+			errorf("decoding uint32 array or slice: length exceeds input size (%d elements)", length)
+		}
+		x := state.decodeUint()
+		if math.MaxUint32 < x {
+			error_(ovfl)
+		}
+		slice[i] = uint32(x)
+	}
+	return true
+}
+
+func decUint64Array(state *decoderState, v reflect.Value, length int, ovfl error) bool {
+	// Can only slice if it is addressable.
+	if !v.CanAddr() {
+		return false
+	}
+	return decUint64Slice(state, v.Slice(0, v.Len()), length, ovfl)
+}
+
+func decUint64Slice(state *decoderState, v reflect.Value, length int, ovfl error) bool {
+	slice, ok := v.Interface().([]uint64)
+	if !ok {
+		// It is kind uint64 but not type uint64. TODO: We can handle this unsafely.
+		return false
+	}
+	for i := 0; i < length; i++ {
+		if state.b.Len() == 0 {
+			errorf("decoding uint64 array or slice: length exceeds input size (%d elements)", length)
+		}
+		slice[i] = state.decodeUint()
+	}
+	return true
+}
+
+func decUintptrArray(state *decoderState, v reflect.Value, length int, ovfl error) bool {
+	// Can only slice if it is addressable.
+	if !v.CanAddr() {
+		return false
+	}
+	return decUintptrSlice(state, v.Slice(0, v.Len()), length, ovfl)
+}
+
+func decUintptrSlice(state *decoderState, v reflect.Value, length int, ovfl error) bool {
+	slice, ok := v.Interface().([]uintptr)
+	if !ok {
+		// It is kind uintptr but not type uintptr. TODO: We can handle this unsafely.
+		return false
+	}
+	for i := 0; i < length; i++ {
+		if state.b.Len() == 0 {
+			errorf("decoding uintptr array or slice: length exceeds input size (%d elements)", length)
+		}
+		x := state.decodeUint()
+		if uint64(^uintptr(0)) < x {
+			error_(ovfl)
+		}
+		slice[i] = uintptr(x)
+	}
+	return true
+}
diff --git a/src/encoding/gob/decgen.go b/src/encoding/gob/decgen.go
new file mode 100644
index 0000000..da41a89
--- /dev/null
+++ b/src/encoding/gob/decgen.go
@@ -0,0 +1,240 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build ignore
+
+// encgen writes the helper functions for encoding. Intended to be
+// used with go generate; see the invocation in encode.go.
+
+// TODO: We could do more by being unsafe. Add a -unsafe flag?
+
+package main
+
+import (
+	"bytes"
+	"flag"
+	"fmt"
+	"go/format"
+	"log"
+	"os"
+)
+
+var output = flag.String("output", "dec_helpers.go", "file name to write")
+
+type Type struct {
+	lower   string
+	upper   string
+	decoder string
+}
+
+var types = []Type{
+	{
+		"bool",
+		"Bool",
+		`slice[i] = state.decodeUint() != 0`,
+	},
+	{
+		"complex64",
+		"Complex64",
+		`real := float32FromBits(state.decodeUint(), ovfl)
+		imag := float32FromBits(state.decodeUint(), ovfl)
+		slice[i] = complex(float32(real), float32(imag))`,
+	},
+	{
+		"complex128",
+		"Complex128",
+		`real := float64FromBits(state.decodeUint())
+		imag := float64FromBits(state.decodeUint())
+		slice[i] = complex(real, imag)`,
+	},
+	{
+		"float32",
+		"Float32",
+		`slice[i] = float32(float32FromBits(state.decodeUint(), ovfl))`,
+	},
+	{
+		"float64",
+		"Float64",
+		`slice[i] = float64FromBits(state.decodeUint())`,
+	},
+	{
+		"int",
+		"Int",
+		`x := state.decodeInt()
+		// MinInt and MaxInt
+		if x < ^int64(^uint(0)>>1) || int64(^uint(0)>>1) < x {
+			error_(ovfl)
+		}
+		slice[i] = int(x)`,
+	},
+	{
+		"int16",
+		"Int16",
+		`x := state.decodeInt()
+		if x < math.MinInt16 || math.MaxInt16 < x {
+			error_(ovfl)
+		}
+		slice[i] = int16(x)`,
+	},
+	{
+		"int32",
+		"Int32",
+		`x := state.decodeInt()
+		if x < math.MinInt32 || math.MaxInt32 < x {
+			error_(ovfl)
+		}
+		slice[i] = int32(x)`,
+	},
+	{
+		"int64",
+		"Int64",
+		`slice[i] = state.decodeInt()`,
+	},
+	{
+		"int8",
+		"Int8",
+		`x := state.decodeInt()
+		if x < math.MinInt8 || math.MaxInt8 < x {
+			error_(ovfl)
+		}
+		slice[i] = int8(x)`,
+	},
+	{
+		"string",
+		"String",
+		`u := state.decodeUint()
+		n := int(u)
+		if n < 0 || uint64(n) != u || n > state.b.Len() {
+			errorf("length of string exceeds input size (%d bytes)", u)
+		}
+		if n > state.b.Len() {
+			errorf("string data too long for buffer: %d", n)
+		}
+		// Read the data.
+		data := make([]byte, n)
+		if _, err := state.b.Read(data); err != nil {
+			errorf("error decoding string: %s", err)
+		}
+		slice[i] = string(data)`,
+	},
+	{
+		"uint",
+		"Uint",
+		`x := state.decodeUint()
+		/*TODO if math.MaxUint32 < x {
+			error_(ovfl)
+		}*/
+		slice[i] = uint(x)`,
+	},
+	{
+		"uint16",
+		"Uint16",
+		`x := state.decodeUint()
+		if math.MaxUint16 < x {
+			error_(ovfl)
+		}
+		slice[i] = uint16(x)`,
+	},
+	{
+		"uint32",
+		"Uint32",
+		`x := state.decodeUint()
+		if math.MaxUint32 < x {
+			error_(ovfl)
+		}
+		slice[i] = uint32(x)`,
+	},
+	{
+		"uint64",
+		"Uint64",
+		`slice[i] = state.decodeUint()`,
+	},
+	{
+		"uintptr",
+		"Uintptr",
+		`x := state.decodeUint()
+		if uint64(^uintptr(0)) < x {
+			error_(ovfl)
+		}
+		slice[i] = uintptr(x)`,
+	},
+	// uint8 Handled separately.
+}
+
+func main() {
+	log.SetFlags(0)
+	log.SetPrefix("decgen: ")
+	flag.Parse()
+	if flag.NArg() != 0 {
+		log.Fatal("usage: decgen [--output filename]")
+	}
+	var b bytes.Buffer
+	fmt.Fprintf(&b, "// Created by decgen --output %s; DO NOT EDIT\n", *output)
+	fmt.Fprint(&b, header)
+	printMaps(&b, "Array")
+	fmt.Fprint(&b, "\n")
+	printMaps(&b, "Slice")
+	for _, t := range types {
+		fmt.Fprintf(&b, arrayHelper, t.lower, t.upper)
+		fmt.Fprintf(&b, sliceHelper, t.lower, t.upper, t.decoder)
+	}
+	source, err := format.Source(b.Bytes())
+	if err != nil {
+		log.Fatal("source format error:", err)
+	}
+	fd, err := os.Create(*output)
+	_, err = fd.Write(source)
+	if err != nil {
+		log.Fatal(err)
+	}
+}
+
+func printMaps(b *bytes.Buffer, upperClass string) {
+	fmt.Fprintf(b, "var dec%sHelper = map[reflect.Kind]decHelper{\n", upperClass)
+	for _, t := range types {
+		fmt.Fprintf(b, "reflect.%s: dec%s%s,\n", t.upper, t.upper, upperClass)
+	}
+	fmt.Fprintf(b, "}\n")
+}
+
+const header = `
+// 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 gob
+
+import (
+	"math"
+	"reflect"
+)
+
+`
+
+const arrayHelper = `
+func dec%[2]sArray(state *decoderState, v reflect.Value, length int, ovfl error) bool {
+	// Can only slice if it is addressable.
+	if !v.CanAddr() {
+		return false
+	}
+	return dec%[2]sSlice(state, v.Slice(0, v.Len()), length, ovfl)
+}
+`
+
+const sliceHelper = `
+func dec%[2]sSlice(state *decoderState, v reflect.Value, length int, ovfl error) bool {
+	slice, ok := v.Interface().([]%[1]s)
+	if !ok {
+		// It is kind %[1]s but not type %[1]s. TODO: We can handle this unsafely.
+		return false
+	}
+	for i := 0; i < length; i++ {
+		if state.b.Len() == 0 {
+			errorf("decoding %[1]s array or slice: length exceeds input size (%%d elements)", length)
+		}
+		%[3]s
+	}
+	return true
+}
+`
diff --git a/src/encoding/gob/decode.go b/src/encoding/gob/decode.go
new file mode 100644
index 0000000..a5bef93
--- /dev/null
+++ b/src/encoding/gob/decode.go
@@ -0,0 +1,1217 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:generate go run decgen.go -output dec_helpers.go
+
+package gob
+
+import (
+	"encoding"
+	"errors"
+	"io"
+	"math"
+	"reflect"
+)
+
+var (
+	errBadUint = errors.New("gob: encoded unsigned integer out of range")
+	errBadType = errors.New("gob: unknown type id or corrupted data")
+	errRange   = errors.New("gob: bad data: field numbers out of bounds")
+)
+
+type decHelper func(state *decoderState, v reflect.Value, length int, ovfl error) bool
+
+// decoderState is the execution state of an instance of the decoder. A new state
+// is created for nested objects.
+type decoderState struct {
+	dec *Decoder
+	// The buffer is stored with an extra indirection because it may be replaced
+	// if we load a type during decode (when reading an interface value).
+	b        *decBuffer
+	fieldnum int // the last field number read.
+	buf      []byte
+	next     *decoderState // for free list
+}
+
+// decBuffer is an extremely simple, fast implementation of a read-only byte buffer.
+// It is initialized by calling Size and then copying the data into the slice returned by Bytes().
+type decBuffer struct {
+	data   []byte
+	offset int // Read offset.
+}
+
+func (d *decBuffer) Read(p []byte) (int, error) {
+	n := copy(p, d.data[d.offset:])
+	if n == 0 && len(p) != 0 {
+		return 0, io.EOF
+	}
+	d.offset += n
+	return n, nil
+}
+
+func (d *decBuffer) Drop(n int) {
+	if n > d.Len() {
+		panic("drop")
+	}
+	d.offset += n
+}
+
+// Size grows the buffer to exactly n bytes, so d.Bytes() will
+// return a slice of length n. Existing data is first discarded.
+func (d *decBuffer) Size(n int) {
+	d.Reset()
+	if cap(d.data) < n {
+		d.data = make([]byte, n)
+	} else {
+		d.data = d.data[0:n]
+	}
+}
+
+func (d *decBuffer) ReadByte() (byte, error) {
+	if d.offset >= len(d.data) {
+		return 0, io.EOF
+	}
+	c := d.data[d.offset]
+	d.offset++
+	return c, nil
+}
+
+func (d *decBuffer) Len() int {
+	return len(d.data) - d.offset
+}
+
+func (d *decBuffer) Bytes() []byte {
+	return d.data[d.offset:]
+}
+
+func (d *decBuffer) Reset() {
+	d.data = d.data[0:0]
+	d.offset = 0
+}
+
+// We pass the bytes.Buffer separately for easier testing of the infrastructure
+// without requiring a full Decoder.
+func (dec *Decoder) newDecoderState(buf *decBuffer) *decoderState {
+	d := dec.freeList
+	if d == nil {
+		d = new(decoderState)
+		d.dec = dec
+		d.buf = make([]byte, uint64Size)
+	} else {
+		dec.freeList = d.next
+	}
+	d.b = buf
+	return d
+}
+
+func (dec *Decoder) freeDecoderState(d *decoderState) {
+	d.next = dec.freeList
+	dec.freeList = d
+}
+
+func overflow(name string) error {
+	return errors.New(`value for "` + name + `" out of range`)
+}
+
+// decodeUintReader reads an encoded unsigned integer from an io.Reader.
+// Used only by the Decoder to read the message length.
+func decodeUintReader(r io.Reader, buf []byte) (x uint64, width int, err error) {
+	width = 1
+	n, err := io.ReadFull(r, buf[0:width])
+	if n == 0 {
+		return
+	}
+	b := buf[0]
+	if b <= 0x7f {
+		return uint64(b), width, nil
+	}
+	n = -int(int8(b))
+	if n > uint64Size {
+		err = errBadUint
+		return
+	}
+	width, err = io.ReadFull(r, buf[0:n])
+	if err != nil {
+		if err == io.EOF {
+			err = io.ErrUnexpectedEOF
+		}
+		return
+	}
+	// Could check that the high byte is zero but it's not worth it.
+	for _, b := range buf[0:width] {
+		x = x<<8 | uint64(b)
+	}
+	width++ // +1 for length byte
+	return
+}
+
+// decodeUint reads an encoded unsigned integer from state.r.
+// Does not check for overflow.
+func (state *decoderState) decodeUint() (x uint64) {
+	b, err := state.b.ReadByte()
+	if err != nil {
+		error_(err)
+	}
+	if b <= 0x7f {
+		return uint64(b)
+	}
+	n := -int(int8(b))
+	if n > uint64Size {
+		error_(errBadUint)
+	}
+	width, err := state.b.Read(state.buf[0:n])
+	if err != nil {
+		error_(err)
+	}
+	// Don't need to check error; it's safe to loop regardless.
+	// Could check that the high byte is zero but it's not worth it.
+	for _, b := range state.buf[0:width] {
+		x = x<<8 | uint64(b)
+	}
+	return x
+}
+
+// decodeInt reads an encoded signed integer from state.r.
+// Does not check for overflow.
+func (state *decoderState) decodeInt() int64 {
+	x := state.decodeUint()
+	if x&1 != 0 {
+		return ^int64(x >> 1)
+	}
+	return int64(x >> 1)
+}
+
+// decOp is the signature of a decoding operator for a given type.
+type decOp func(i *decInstr, state *decoderState, v reflect.Value)
+
+// The 'instructions' of the decoding machine
+type decInstr struct {
+	op    decOp
+	field int   // field number of the wire type
+	index []int // field access indices for destination type
+	ovfl  error // error message for overflow/underflow (for arrays, of the elements)
+}
+
+// ignoreUint discards a uint value with no destination.
+func ignoreUint(i *decInstr, state *decoderState, v reflect.Value) {
+	state.decodeUint()
+}
+
+// ignoreTwoUints discards a uint value with no destination. It's used to skip
+// complex values.
+func ignoreTwoUints(i *decInstr, state *decoderState, v reflect.Value) {
+	state.decodeUint()
+	state.decodeUint()
+}
+
+// Since the encoder writes no zeros, if we arrive at a decoder we have
+// a value to extract and store.  The field number has already been read
+// (it's how we knew to call this decoder).
+// Each decoder is responsible for handling any indirections associated
+// with the data structure.  If any pointer so reached is nil, allocation must
+// be done.
+
+// decAlloc takes a value and returns a settable value that can
+// be assigned to. If the value is a pointer, decAlloc guarantees it points to storage.
+// The callers to the individual decoders are expected to have used decAlloc.
+// The individual decoders don't need to it.
+func decAlloc(v reflect.Value) reflect.Value {
+	for v.Kind() == reflect.Ptr {
+		if v.IsNil() {
+			v.Set(reflect.New(v.Type().Elem()))
+		}
+		v = v.Elem()
+	}
+	return v
+}
+
+// decBool decodes a uint and stores it as a boolean in value.
+func decBool(i *decInstr, state *decoderState, value reflect.Value) {
+	value.SetBool(state.decodeUint() != 0)
+}
+
+// decInt8 decodes an integer and stores it as an int8 in value.
+func decInt8(i *decInstr, state *decoderState, value reflect.Value) {
+	v := state.decodeInt()
+	if v < math.MinInt8 || math.MaxInt8 < v {
+		error_(i.ovfl)
+	}
+	value.SetInt(v)
+}
+
+// decUint8 decodes an unsigned integer and stores it as a uint8 in value.
+func decUint8(i *decInstr, state *decoderState, value reflect.Value) {
+	v := state.decodeUint()
+	if math.MaxUint8 < v {
+		error_(i.ovfl)
+	}
+	value.SetUint(v)
+}
+
+// decInt16 decodes an integer and stores it as an int16 in value.
+func decInt16(i *decInstr, state *decoderState, value reflect.Value) {
+	v := state.decodeInt()
+	if v < math.MinInt16 || math.MaxInt16 < v {
+		error_(i.ovfl)
+	}
+	value.SetInt(v)
+}
+
+// decUint16 decodes an unsigned integer and stores it as a uint16 in value.
+func decUint16(i *decInstr, state *decoderState, value reflect.Value) {
+	v := state.decodeUint()
+	if math.MaxUint16 < v {
+		error_(i.ovfl)
+	}
+	value.SetUint(v)
+}
+
+// decInt32 decodes an integer and stores it as an int32 in value.
+func decInt32(i *decInstr, state *decoderState, value reflect.Value) {
+	v := state.decodeInt()
+	if v < math.MinInt32 || math.MaxInt32 < v {
+		error_(i.ovfl)
+	}
+	value.SetInt(v)
+}
+
+// decUint32 decodes an unsigned integer and stores it as a uint32 in value.
+func decUint32(i *decInstr, state *decoderState, value reflect.Value) {
+	v := state.decodeUint()
+	if math.MaxUint32 < v {
+		error_(i.ovfl)
+	}
+	value.SetUint(v)
+}
+
+// decInt64 decodes an integer and stores it as an int64 in value.
+func decInt64(i *decInstr, state *decoderState, value reflect.Value) {
+	v := state.decodeInt()
+	value.SetInt(v)
+}
+
+// decUint64 decodes an unsigned integer and stores it as a uint64 in value.
+func decUint64(i *decInstr, state *decoderState, value reflect.Value) {
+	v := state.decodeUint()
+	value.SetUint(v)
+}
+
+// Floating-point numbers are transmitted as uint64s holding the bits
+// of the underlying representation.  They are sent byte-reversed, with
+// the exponent end coming out first, so integer floating point numbers
+// (for example) transmit more compactly.  This routine does the
+// unswizzling.
+func float64FromBits(u uint64) float64 {
+	var v uint64
+	for i := 0; i < 8; i++ {
+		v <<= 8
+		v |= u & 0xFF
+		u >>= 8
+	}
+	return math.Float64frombits(v)
+}
+
+// float32FromBits decodes an unsigned integer, treats it as a 32-bit floating-point
+// number, and returns it. It's a helper function for float32 and complex64.
+// It returns a float64 because that's what reflection needs, but its return
+// value is known to be accurately representable in a float32.
+func float32FromBits(u uint64, ovfl error) float64 {
+	v := float64FromBits(u)
+	av := v
+	if av < 0 {
+		av = -av
+	}
+	// +Inf is OK in both 32- and 64-bit floats.  Underflow is always OK.
+	if math.MaxFloat32 < av && av <= math.MaxFloat64 {
+		error_(ovfl)
+	}
+	return v
+}
+
+// decFloat32 decodes an unsigned integer, treats it as a 32-bit floating-point
+// number, and stores it in value.
+func decFloat32(i *decInstr, state *decoderState, value reflect.Value) {
+	value.SetFloat(float32FromBits(state.decodeUint(), i.ovfl))
+}
+
+// decFloat64 decodes an unsigned integer, treats it as a 64-bit floating-point
+// number, and stores it in value.
+func decFloat64(i *decInstr, state *decoderState, value reflect.Value) {
+	value.SetFloat(float64FromBits(state.decodeUint()))
+}
+
+// decComplex64 decodes a pair of unsigned integers, treats them as a
+// pair of floating point numbers, and stores them as a complex64 in value.
+// The real part comes first.
+func decComplex64(i *decInstr, state *decoderState, value reflect.Value) {
+	real := float32FromBits(state.decodeUint(), i.ovfl)
+	imag := float32FromBits(state.decodeUint(), i.ovfl)
+	value.SetComplex(complex(real, imag))
+}
+
+// decComplex128 decodes a pair of unsigned integers, treats them as a
+// pair of floating point numbers, and stores them as a complex128 in value.
+// The real part comes first.
+func decComplex128(i *decInstr, state *decoderState, value reflect.Value) {
+	real := float64FromBits(state.decodeUint())
+	imag := float64FromBits(state.decodeUint())
+	value.SetComplex(complex(real, imag))
+}
+
+// decUint8Slice decodes a byte slice and stores in value a slice header
+// describing the data.
+// uint8 slices are encoded as an unsigned count followed by the raw bytes.
+func decUint8Slice(i *decInstr, state *decoderState, value reflect.Value) {
+	u := state.decodeUint()
+	n := int(u)
+	if n < 0 || uint64(n) != u {
+		errorf("length of %s exceeds input size (%d bytes)", value.Type(), u)
+	}
+	if n > state.b.Len() {
+		errorf("%s data too long for buffer: %d", value.Type(), n)
+	}
+	if n > tooBig {
+		errorf("byte slice too big: %d", n)
+	}
+	if value.Cap() < n {
+		value.Set(reflect.MakeSlice(value.Type(), n, n))
+	} else {
+		value.Set(value.Slice(0, n))
+	}
+	if _, err := state.b.Read(value.Bytes()); err != nil {
+		errorf("error decoding []byte: %s", err)
+	}
+}
+
+// decString decodes byte array and stores in value a string header
+// describing the data.
+// Strings are encoded as an unsigned count followed by the raw bytes.
+func decString(i *decInstr, state *decoderState, value reflect.Value) {
+	u := state.decodeUint()
+	n := int(u)
+	if n < 0 || uint64(n) != u || n > state.b.Len() {
+		errorf("length of %s exceeds input size (%d bytes)", value.Type(), u)
+	}
+	if n > state.b.Len() {
+		errorf("%s data too long for buffer: %d", value.Type(), n)
+	}
+	// Read the data.
+	data := make([]byte, n)
+	if _, err := state.b.Read(data); err != nil {
+		errorf("error decoding string: %s", err)
+	}
+	value.SetString(string(data))
+}
+
+// ignoreUint8Array skips over the data for a byte slice value with no destination.
+func ignoreUint8Array(i *decInstr, state *decoderState, value reflect.Value) {
+	b := make([]byte, state.decodeUint())
+	state.b.Read(b)
+}
+
+// Execution engine
+
+// The encoder engine is an array of instructions indexed by field number of the incoming
+// decoder.  It is executed with random access according to field number.
+type decEngine struct {
+	instr    []decInstr
+	numInstr int // the number of active instructions
+}
+
+// decodeSingle decodes a top-level value that is not a struct and stores it in value.
+// Such values are preceded by a zero, making them have the memory layout of a
+// struct field (although with an illegal field number).
+func (dec *Decoder) decodeSingle(engine *decEngine, ut *userTypeInfo, value reflect.Value) {
+	state := dec.newDecoderState(&dec.buf)
+	defer dec.freeDecoderState(state)
+	state.fieldnum = singletonField
+	if state.decodeUint() != 0 {
+		errorf("decode: corrupted data: non-zero delta for singleton")
+	}
+	instr := &engine.instr[singletonField]
+	instr.op(instr, state, value)
+}
+
+// decodeStruct decodes a top-level struct and stores it in value.
+// Indir is for the value, not the type.  At the time of the call it may
+// differ from ut.indir, which was computed when the engine was built.
+// This state cannot arise for decodeSingle, which is called directly
+// from the user's value, not from the innards of an engine.
+func (dec *Decoder) decodeStruct(engine *decEngine, ut *userTypeInfo, value reflect.Value) {
+	state := dec.newDecoderState(&dec.buf)
+	defer dec.freeDecoderState(state)
+	state.fieldnum = -1
+	for state.b.Len() > 0 {
+		delta := int(state.decodeUint())
+		if delta < 0 {
+			errorf("decode: corrupted data: negative delta")
+		}
+		if delta == 0 { // struct terminator is zero delta fieldnum
+			break
+		}
+		fieldnum := state.fieldnum + delta
+		if fieldnum >= len(engine.instr) {
+			error_(errRange)
+			break
+		}
+		instr := &engine.instr[fieldnum]
+		var field reflect.Value
+		if instr.index != nil {
+			// Otherwise the field is unknown to us and instr.op is an ignore op.
+			field = value.FieldByIndex(instr.index)
+			if field.Kind() == reflect.Ptr {
+				field = decAlloc(field)
+			}
+		}
+		instr.op(instr, state, field)
+		state.fieldnum = fieldnum
+	}
+}
+
+var noValue reflect.Value
+
+// ignoreStruct discards the data for a struct with no destination.
+func (dec *Decoder) ignoreStruct(engine *decEngine) {
+	state := dec.newDecoderState(&dec.buf)
+	defer dec.freeDecoderState(state)
+	state.fieldnum = -1
+	for state.b.Len() > 0 {
+		delta := int(state.decodeUint())
+		if delta < 0 {
+			errorf("ignore decode: corrupted data: negative delta")
+		}
+		if delta == 0 { // struct terminator is zero delta fieldnum
+			break
+		}
+		fieldnum := state.fieldnum + delta
+		if fieldnum >= len(engine.instr) {
+			error_(errRange)
+		}
+		instr := &engine.instr[fieldnum]
+		instr.op(instr, state, noValue)
+		state.fieldnum = fieldnum
+	}
+}
+
+// ignoreSingle discards the data for a top-level non-struct value with no
+// destination. It's used when calling Decode with a nil value.
+func (dec *Decoder) ignoreSingle(engine *decEngine) {
+	state := dec.newDecoderState(&dec.buf)
+	defer dec.freeDecoderState(state)
+	state.fieldnum = singletonField
+	delta := int(state.decodeUint())
+	if delta != 0 {
+		errorf("decode: corrupted data: non-zero delta for singleton")
+	}
+	instr := &engine.instr[singletonField]
+	instr.op(instr, state, noValue)
+}
+
+// decodeArrayHelper does the work for decoding arrays and slices.
+func (dec *Decoder) decodeArrayHelper(state *decoderState, value reflect.Value, elemOp decOp, length int, ovfl error, helper decHelper) {
+	if helper != nil && helper(state, value, length, ovfl) {
+		return
+	}
+	instr := &decInstr{elemOp, 0, nil, ovfl}
+	isPtr := value.Type().Elem().Kind() == reflect.Ptr
+	for i := 0; i < length; i++ {
+		if state.b.Len() == 0 {
+			errorf("decoding array or slice: length exceeds input size (%d elements)", length)
+		}
+		v := value.Index(i)
+		if isPtr {
+			v = decAlloc(v)
+		}
+		elemOp(instr, state, v)
+	}
+}
+
+// decodeArray decodes an array and stores it in value.
+// The length is an unsigned integer preceding the elements.  Even though the length is redundant
+// (it's part of the type), it's a useful check and is included in the encoding.
+func (dec *Decoder) decodeArray(atyp reflect.Type, state *decoderState, value reflect.Value, elemOp decOp, length int, ovfl error, helper decHelper) {
+	if n := state.decodeUint(); n != uint64(length) {
+		errorf("length mismatch in decodeArray")
+	}
+	dec.decodeArrayHelper(state, value, elemOp, length, ovfl, helper)
+}
+
+// decodeIntoValue is a helper for map decoding.
+func decodeIntoValue(state *decoderState, op decOp, isPtr bool, value reflect.Value, ovfl error) reflect.Value {
+	instr := &decInstr{op, 0, nil, ovfl}
+	v := value
+	if isPtr {
+		v = decAlloc(value)
+	}
+	op(instr, state, v)
+	return value
+}
+
+// decodeMap decodes a map and stores it in value.
+// Maps are encoded as a length followed by key:value pairs.
+// Because the internals of maps are not visible to us, we must
+// use reflection rather than pointer magic.
+func (dec *Decoder) decodeMap(mtyp reflect.Type, state *decoderState, value reflect.Value, keyOp, elemOp decOp, ovfl error) {
+	if value.IsNil() {
+		// Allocate map.
+		value.Set(reflect.MakeMap(mtyp))
+	}
+	n := int(state.decodeUint())
+	keyIsPtr := mtyp.Key().Kind() == reflect.Ptr
+	elemIsPtr := mtyp.Elem().Kind() == reflect.Ptr
+	for i := 0; i < n; i++ {
+		key := decodeIntoValue(state, keyOp, keyIsPtr, allocValue(mtyp.Key()), ovfl)
+		elem := decodeIntoValue(state, elemOp, elemIsPtr, allocValue(mtyp.Elem()), ovfl)
+		value.SetMapIndex(key, elem)
+	}
+}
+
+// ignoreArrayHelper does the work for discarding arrays and slices.
+func (dec *Decoder) ignoreArrayHelper(state *decoderState, elemOp decOp, length int) {
+	instr := &decInstr{elemOp, 0, nil, errors.New("no error")}
+	for i := 0; i < length; i++ {
+		elemOp(instr, state, noValue)
+	}
+}
+
+// ignoreArray discards the data for an array value with no destination.
+func (dec *Decoder) ignoreArray(state *decoderState, elemOp decOp, length int) {
+	if n := state.decodeUint(); n != uint64(length) {
+		errorf("length mismatch in ignoreArray")
+	}
+	dec.ignoreArrayHelper(state, elemOp, length)
+}
+
+// ignoreMap discards the data for a map value with no destination.
+func (dec *Decoder) ignoreMap(state *decoderState, keyOp, elemOp decOp) {
+	n := int(state.decodeUint())
+	keyInstr := &decInstr{keyOp, 0, nil, errors.New("no error")}
+	elemInstr := &decInstr{elemOp, 0, nil, errors.New("no error")}
+	for i := 0; i < n; i++ {
+		keyOp(keyInstr, state, noValue)
+		elemOp(elemInstr, state, noValue)
+	}
+}
+
+// decodeSlice decodes a slice and stores it in value.
+// Slices are encoded as an unsigned length followed by the elements.
+func (dec *Decoder) decodeSlice(state *decoderState, value reflect.Value, elemOp decOp, ovfl error, helper decHelper) {
+	u := state.decodeUint()
+	typ := value.Type()
+	size := uint64(typ.Elem().Size())
+	nBytes := u * size
+	n := int(u)
+	// Take care with overflow in this calculation.
+	if n < 0 || uint64(n) != u || nBytes > tooBig || (size > 0 && nBytes/size != u) {
+		// We don't check n against buffer length here because if it's a slice
+		// of interfaces, there will be buffer reloads.
+		errorf("%s slice too big: %d elements of %d bytes", typ.Elem(), u, size)
+	}
+	if value.Cap() < n {
+		value.Set(reflect.MakeSlice(typ, n, n))
+	} else {
+		value.Set(value.Slice(0, n))
+	}
+	dec.decodeArrayHelper(state, value, elemOp, n, ovfl, helper)
+}
+
+// ignoreSlice skips over the data for a slice value with no destination.
+func (dec *Decoder) ignoreSlice(state *decoderState, elemOp decOp) {
+	dec.ignoreArrayHelper(state, elemOp, int(state.decodeUint()))
+}
+
+// decodeInterface decodes an interface value and stores it in value.
+// Interfaces are encoded as the name of a concrete type followed by a value.
+// If the name is empty, the value is nil and no value is sent.
+func (dec *Decoder) decodeInterface(ityp reflect.Type, state *decoderState, value reflect.Value) {
+	// Read the name of the concrete type.
+	nr := state.decodeUint()
+	if nr < 0 || nr > 1<<31 { // zero is permissible for anonymous types
+		errorf("invalid type name length %d", nr)
+	}
+	if nr > uint64(state.b.Len()) {
+		errorf("invalid type name length %d: exceeds input size", nr)
+	}
+	b := make([]byte, nr)
+	state.b.Read(b)
+	name := string(b)
+	// Allocate the destination interface value.
+	if name == "" {
+		// Copy the nil interface value to the target.
+		value.Set(reflect.Zero(value.Type()))
+		return
+	}
+	if len(name) > 1024 {
+		errorf("name too long (%d bytes): %.20q...", len(name), name)
+	}
+	// The concrete type must be registered.
+	registerLock.RLock()
+	typ, ok := nameToConcreteType[name]
+	registerLock.RUnlock()
+	if !ok {
+		errorf("name not registered for interface: %q", name)
+	}
+	// Read the type id of the concrete value.
+	concreteId := dec.decodeTypeSequence(true)
+	if concreteId < 0 {
+		error_(dec.err)
+	}
+	// Byte count of value is next; we don't care what it is (it's there
+	// in case we want to ignore the value by skipping it completely).
+	state.decodeUint()
+	// Read the concrete value.
+	v := allocValue(typ)
+	dec.decodeValue(concreteId, v)
+	if dec.err != nil {
+		error_(dec.err)
+	}
+	// Assign the concrete value to the interface.
+	// Tread carefully; it might not satisfy the interface.
+	if !typ.AssignableTo(ityp) {
+		errorf("%s is not assignable to type %s", typ, ityp)
+	}
+	// Copy the interface value to the target.
+	value.Set(v)
+}
+
+// ignoreInterface discards the data for an interface value with no destination.
+func (dec *Decoder) ignoreInterface(state *decoderState) {
+	// Read the name of the concrete type.
+	b := make([]byte, state.decodeUint())
+	_, err := state.b.Read(b)
+	if err != nil {
+		error_(err)
+	}
+	id := dec.decodeTypeSequence(true)
+	if id < 0 {
+		error_(dec.err)
+	}
+	// At this point, the decoder buffer contains a delimited value. Just toss it.
+	state.b.Drop(int(state.decodeUint()))
+}
+
+// decodeGobDecoder decodes something implementing the GobDecoder interface.
+// The data is encoded as a byte slice.
+func (dec *Decoder) decodeGobDecoder(ut *userTypeInfo, state *decoderState, value reflect.Value) {
+	// Read the bytes for the value.
+	b := make([]byte, state.decodeUint())
+	_, err := state.b.Read(b)
+	if err != nil {
+		error_(err)
+	}
+	// We know it's one of these.
+	switch ut.externalDec {
+	case xGob:
+		err = value.Interface().(GobDecoder).GobDecode(b)
+	case xBinary:
+		err = value.Interface().(encoding.BinaryUnmarshaler).UnmarshalBinary(b)
+	case xText:
+		err = value.Interface().(encoding.TextUnmarshaler).UnmarshalText(b)
+	}
+	if err != nil {
+		error_(err)
+	}
+}
+
+// ignoreGobDecoder discards the data for a GobDecoder value with no destination.
+func (dec *Decoder) ignoreGobDecoder(state *decoderState) {
+	// Read the bytes for the value.
+	b := make([]byte, state.decodeUint())
+	_, err := state.b.Read(b)
+	if err != nil {
+		error_(err)
+	}
+}
+
+// Index by Go types.
+var decOpTable = [...]decOp{
+	reflect.Bool:       decBool,
+	reflect.Int8:       decInt8,
+	reflect.Int16:      decInt16,
+	reflect.Int32:      decInt32,
+	reflect.Int64:      decInt64,
+	reflect.Uint8:      decUint8,
+	reflect.Uint16:     decUint16,
+	reflect.Uint32:     decUint32,
+	reflect.Uint64:     decUint64,
+	reflect.Float32:    decFloat32,
+	reflect.Float64:    decFloat64,
+	reflect.Complex64:  decComplex64,
+	reflect.Complex128: decComplex128,
+	reflect.String:     decString,
+}
+
+// Indexed by gob types.  tComplex will be added during type.init().
+var decIgnoreOpMap = map[typeId]decOp{
+	tBool:    ignoreUint,
+	tInt:     ignoreUint,
+	tUint:    ignoreUint,
+	tFloat:   ignoreUint,
+	tBytes:   ignoreUint8Array,
+	tString:  ignoreUint8Array,
+	tComplex: ignoreTwoUints,
+}
+
+// decOpFor returns the decoding op for the base type under rt and
+// the indirection count to reach it.
+func (dec *Decoder) decOpFor(wireId typeId, rt reflect.Type, name string, inProgress map[reflect.Type]*decOp) *decOp {
+	ut := userType(rt)
+	// If the type implements GobEncoder, we handle it without further processing.
+	if ut.externalDec != 0 {
+		return dec.gobDecodeOpFor(ut)
+	}
+
+	// If this type is already in progress, it's a recursive type (e.g. map[string]*T).
+	// Return the pointer to the op we're already building.
+	if opPtr := inProgress[rt]; opPtr != nil {
+		return opPtr
+	}
+	typ := ut.base
+	var op decOp
+	k := typ.Kind()
+	if int(k) < len(decOpTable) {
+		op = decOpTable[k]
+	}
+	if op == nil {
+		inProgress[rt] = &op
+		// Special cases
+		switch t := typ; t.Kind() {
+		case reflect.Array:
+			name = "element of " + name
+			elemId := dec.wireType[wireId].ArrayT.Elem
+			elemOp := dec.decOpFor(elemId, t.Elem(), name, inProgress)
+			ovfl := overflow(name)
+			helper := decArrayHelper[t.Elem().Kind()]
+			op = func(i *decInstr, state *decoderState, value reflect.Value) {
+				state.dec.decodeArray(t, state, value, *elemOp, t.Len(), ovfl, helper)
+			}
+
+		case reflect.Map:
+			keyId := dec.wireType[wireId].MapT.Key
+			elemId := dec.wireType[wireId].MapT.Elem
+			keyOp := dec.decOpFor(keyId, t.Key(), "key of "+name, inProgress)
+			elemOp := dec.decOpFor(elemId, t.Elem(), "element of "+name, inProgress)
+			ovfl := overflow(name)
+			op = func(i *decInstr, state *decoderState, value reflect.Value) {
+				state.dec.decodeMap(t, state, value, *keyOp, *elemOp, ovfl)
+			}
+
+		case reflect.Slice:
+			name = "element of " + name
+			if t.Elem().Kind() == reflect.Uint8 {
+				op = decUint8Slice
+				break
+			}
+			var elemId typeId
+			if tt, ok := builtinIdToType[wireId]; ok {
+				elemId = tt.(*sliceType).Elem
+			} else {
+				elemId = dec.wireType[wireId].SliceT.Elem
+			}
+			elemOp := dec.decOpFor(elemId, t.Elem(), name, inProgress)
+			ovfl := overflow(name)
+			helper := decSliceHelper[t.Elem().Kind()]
+			op = func(i *decInstr, state *decoderState, value reflect.Value) {
+				state.dec.decodeSlice(state, value, *elemOp, ovfl, helper)
+			}
+
+		case reflect.Struct:
+			// Generate a closure that calls out to the engine for the nested type.
+			ut := userType(typ)
+			enginePtr, err := dec.getDecEnginePtr(wireId, ut)
+			if err != nil {
+				error_(err)
+			}
+			op = func(i *decInstr, state *decoderState, value reflect.Value) {
+				// indirect through enginePtr to delay evaluation for recursive structs.
+				dec.decodeStruct(*enginePtr, ut, value)
+			}
+		case reflect.Interface:
+			op = func(i *decInstr, state *decoderState, value reflect.Value) {
+				state.dec.decodeInterface(t, state, value)
+			}
+		}
+	}
+	if op == nil {
+		errorf("decode can't handle type %s", rt)
+	}
+	return &op
+}
+
+// decIgnoreOpFor returns the decoding op for a field that has no destination.
+func (dec *Decoder) decIgnoreOpFor(wireId typeId) decOp {
+	op, ok := decIgnoreOpMap[wireId]
+	if !ok {
+		if wireId == tInterface {
+			// Special case because it's a method: the ignored item might
+			// define types and we need to record their state in the decoder.
+			op = func(i *decInstr, state *decoderState, value reflect.Value) {
+				state.dec.ignoreInterface(state)
+			}
+			return op
+		}
+		// Special cases
+		wire := dec.wireType[wireId]
+		switch {
+		case wire == nil:
+			errorf("bad data: undefined type %s", wireId.string())
+		case wire.ArrayT != nil:
+			elemId := wire.ArrayT.Elem
+			elemOp := dec.decIgnoreOpFor(elemId)
+			op = func(i *decInstr, state *decoderState, value reflect.Value) {
+				state.dec.ignoreArray(state, elemOp, wire.ArrayT.Len)
+			}
+
+		case wire.MapT != nil:
+			keyId := dec.wireType[wireId].MapT.Key
+			elemId := dec.wireType[wireId].MapT.Elem
+			keyOp := dec.decIgnoreOpFor(keyId)
+			elemOp := dec.decIgnoreOpFor(elemId)
+			op = func(i *decInstr, state *decoderState, value reflect.Value) {
+				state.dec.ignoreMap(state, keyOp, elemOp)
+			}
+
+		case wire.SliceT != nil:
+			elemId := wire.SliceT.Elem
+			elemOp := dec.decIgnoreOpFor(elemId)
+			op = func(i *decInstr, state *decoderState, value reflect.Value) {
+				state.dec.ignoreSlice(state, elemOp)
+			}
+
+		case wire.StructT != nil:
+			// Generate a closure that calls out to the engine for the nested type.
+			enginePtr, err := dec.getIgnoreEnginePtr(wireId)
+			if err != nil {
+				error_(err)
+			}
+			op = func(i *decInstr, state *decoderState, value reflect.Value) {
+				// indirect through enginePtr to delay evaluation for recursive structs
+				state.dec.ignoreStruct(*enginePtr)
+			}
+
+		case wire.GobEncoderT != nil, wire.BinaryMarshalerT != nil, wire.TextMarshalerT != nil:
+			op = func(i *decInstr, state *decoderState, value reflect.Value) {
+				state.dec.ignoreGobDecoder(state)
+			}
+		}
+	}
+	if op == nil {
+		errorf("bad data: ignore can't handle type %s", wireId.string())
+	}
+	return op
+}
+
+// gobDecodeOpFor returns the op for a type that is known to implement
+// GobDecoder.
+func (dec *Decoder) gobDecodeOpFor(ut *userTypeInfo) *decOp {
+	rcvrType := ut.user
+	if ut.decIndir == -1 {
+		rcvrType = reflect.PtrTo(rcvrType)
+	} else if ut.decIndir > 0 {
+		for i := int8(0); i < ut.decIndir; i++ {
+			rcvrType = rcvrType.Elem()
+		}
+	}
+	var op decOp
+	op = func(i *decInstr, state *decoderState, value reflect.Value) {
+		// We now have the base type. We need its address if the receiver is a pointer.
+		if value.Kind() != reflect.Ptr && rcvrType.Kind() == reflect.Ptr {
+			value = value.Addr()
+		}
+		state.dec.decodeGobDecoder(ut, state, value)
+	}
+	return &op
+}
+
+// compatibleType asks: Are these two gob Types compatible?
+// Answers the question for basic types, arrays, maps and slices, plus
+// GobEncoder/Decoder pairs.
+// Structs are considered ok; fields will be checked later.
+func (dec *Decoder) compatibleType(fr reflect.Type, fw typeId, inProgress map[reflect.Type]typeId) bool {
+	if rhs, ok := inProgress[fr]; ok {
+		return rhs == fw
+	}
+	inProgress[fr] = fw
+	ut := userType(fr)
+	wire, ok := dec.wireType[fw]
+	// If wire was encoded with an encoding method, fr must have that method.
+	// And if not, it must not.
+	// At most one of the booleans in ut is set.
+	// We could possibly relax this constraint in the future in order to
+	// choose the decoding method using the data in the wireType.
+	// The parentheses look odd but are correct.
+	if (ut.externalDec == xGob) != (ok && wire.GobEncoderT != nil) ||
+		(ut.externalDec == xBinary) != (ok && wire.BinaryMarshalerT != nil) ||
+		(ut.externalDec == xText) != (ok && wire.TextMarshalerT != nil) {
+		return false
+	}
+	if ut.externalDec != 0 { // This test trumps all others.
+		return true
+	}
+	switch t := ut.base; t.Kind() {
+	default:
+		// chan, etc: cannot handle.
+		return false
+	case reflect.Bool:
+		return fw == tBool
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		return fw == tInt
+	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+		return fw == tUint
+	case reflect.Float32, reflect.Float64:
+		return fw == tFloat
+	case reflect.Complex64, reflect.Complex128:
+		return fw == tComplex
+	case reflect.String:
+		return fw == tString
+	case reflect.Interface:
+		return fw == tInterface
+	case reflect.Array:
+		if !ok || wire.ArrayT == nil {
+			return false
+		}
+		array := wire.ArrayT
+		return t.Len() == array.Len && dec.compatibleType(t.Elem(), array.Elem, inProgress)
+	case reflect.Map:
+		if !ok || wire.MapT == nil {
+			return false
+		}
+		MapType := wire.MapT
+		return dec.compatibleType(t.Key(), MapType.Key, inProgress) && dec.compatibleType(t.Elem(), MapType.Elem, inProgress)
+	case reflect.Slice:
+		// Is it an array of bytes?
+		if t.Elem().Kind() == reflect.Uint8 {
+			return fw == tBytes
+		}
+		// Extract and compare element types.
+		var sw *sliceType
+		if tt, ok := builtinIdToType[fw]; ok {
+			sw, _ = tt.(*sliceType)
+		} else if wire != nil {
+			sw = wire.SliceT
+		}
+		elem := userType(t.Elem()).base
+		return sw != nil && dec.compatibleType(elem, sw.Elem, inProgress)
+	case reflect.Struct:
+		return true
+	}
+}
+
+// typeString returns a human-readable description of the type identified by remoteId.
+func (dec *Decoder) typeString(remoteId typeId) string {
+	if t := idToType[remoteId]; t != nil {
+		// globally known type.
+		return t.string()
+	}
+	return dec.wireType[remoteId].string()
+}
+
+// compileSingle compiles the decoder engine for a non-struct top-level value, including
+// GobDecoders.
+func (dec *Decoder) compileSingle(remoteId typeId, ut *userTypeInfo) (engine *decEngine, err error) {
+	rt := ut.user
+	engine = new(decEngine)
+	engine.instr = make([]decInstr, 1) // one item
+	name := rt.String()                // best we can do
+	if !dec.compatibleType(rt, remoteId, make(map[reflect.Type]typeId)) {
+		remoteType := dec.typeString(remoteId)
+		// Common confusing case: local interface type, remote concrete type.
+		if ut.base.Kind() == reflect.Interface && remoteId != tInterface {
+			return nil, errors.New("gob: local interface type " + name + " can only be decoded from remote interface type; received concrete type " + remoteType)
+		}
+		return nil, errors.New("gob: decoding into local type " + name + ", received remote type " + remoteType)
+	}
+	op := dec.decOpFor(remoteId, rt, name, make(map[reflect.Type]*decOp))
+	ovfl := errors.New(`value for "` + name + `" out of range`)
+	engine.instr[singletonField] = decInstr{*op, singletonField, nil, ovfl}
+	engine.numInstr = 1
+	return
+}
+
+// compileIgnoreSingle compiles the decoder engine for a non-struct top-level value that will be discarded.
+func (dec *Decoder) compileIgnoreSingle(remoteId typeId) (engine *decEngine, err error) {
+	engine = new(decEngine)
+	engine.instr = make([]decInstr, 1) // one item
+	op := dec.decIgnoreOpFor(remoteId)
+	ovfl := overflow(dec.typeString(remoteId))
+	engine.instr[0] = decInstr{op, 0, nil, ovfl}
+	engine.numInstr = 1
+	return
+}
+
+// compileDec compiles the decoder engine for a value.  If the value is not a struct,
+// it calls out to compileSingle.
+func (dec *Decoder) compileDec(remoteId typeId, ut *userTypeInfo) (engine *decEngine, err error) {
+	rt := ut.base
+	srt := rt
+	if srt.Kind() != reflect.Struct || ut.externalDec != 0 {
+		return dec.compileSingle(remoteId, ut)
+	}
+	var wireStruct *structType
+	// Builtin types can come from global pool; the rest must be defined by the decoder.
+	// Also we know we're decoding a struct now, so the client must have sent one.
+	if t, ok := builtinIdToType[remoteId]; ok {
+		wireStruct, _ = t.(*structType)
+	} else {
+		wire := dec.wireType[remoteId]
+		if wire == nil {
+			error_(errBadType)
+		}
+		wireStruct = wire.StructT
+	}
+	if wireStruct == nil {
+		errorf("type mismatch in decoder: want struct type %s; got non-struct", rt)
+	}
+	engine = new(decEngine)
+	engine.instr = make([]decInstr, len(wireStruct.Field))
+	seen := make(map[reflect.Type]*decOp)
+	// Loop over the fields of the wire type.
+	for fieldnum := 0; fieldnum < len(wireStruct.Field); fieldnum++ {
+		wireField := wireStruct.Field[fieldnum]
+		if wireField.Name == "" {
+			errorf("empty name for remote field of type %s", wireStruct.Name)
+		}
+		ovfl := overflow(wireField.Name)
+		// Find the field of the local type with the same name.
+		localField, present := srt.FieldByName(wireField.Name)
+		// TODO(r): anonymous names
+		if !present || !isExported(wireField.Name) {
+			op := dec.decIgnoreOpFor(wireField.Id)
+			engine.instr[fieldnum] = decInstr{op, fieldnum, nil, ovfl}
+			continue
+		}
+		if !dec.compatibleType(localField.Type, wireField.Id, make(map[reflect.Type]typeId)) {
+			errorf("wrong type (%s) for received field %s.%s", localField.Type, wireStruct.Name, wireField.Name)
+		}
+		op := dec.decOpFor(wireField.Id, localField.Type, localField.Name, seen)
+		engine.instr[fieldnum] = decInstr{*op, fieldnum, localField.Index, ovfl}
+		engine.numInstr++
+	}
+	return
+}
+
+// getDecEnginePtr returns the engine for the specified type.
+func (dec *Decoder) getDecEnginePtr(remoteId typeId, ut *userTypeInfo) (enginePtr **decEngine, err error) {
+	rt := ut.user
+	decoderMap, ok := dec.decoderCache[rt]
+	if !ok {
+		decoderMap = make(map[typeId]**decEngine)
+		dec.decoderCache[rt] = decoderMap
+	}
+	if enginePtr, ok = decoderMap[remoteId]; !ok {
+		// To handle recursive types, mark this engine as underway before compiling.
+		enginePtr = new(*decEngine)
+		decoderMap[remoteId] = enginePtr
+		*enginePtr, err = dec.compileDec(remoteId, ut)
+		if err != nil {
+			delete(decoderMap, remoteId)
+		}
+	}
+	return
+}
+
+// emptyStruct is the type we compile into when ignoring a struct value.
+type emptyStruct struct{}
+
+var emptyStructType = reflect.TypeOf(emptyStruct{})
+
+// getDecEnginePtr returns the engine for the specified type when the value is to be discarded.
+func (dec *Decoder) getIgnoreEnginePtr(wireId typeId) (enginePtr **decEngine, err error) {
+	var ok bool
+	if enginePtr, ok = dec.ignorerCache[wireId]; !ok {
+		// To handle recursive types, mark this engine as underway before compiling.
+		enginePtr = new(*decEngine)
+		dec.ignorerCache[wireId] = enginePtr
+		wire := dec.wireType[wireId]
+		if wire != nil && wire.StructT != nil {
+			*enginePtr, err = dec.compileDec(wireId, userType(emptyStructType))
+		} else {
+			*enginePtr, err = dec.compileIgnoreSingle(wireId)
+		}
+		if err != nil {
+			delete(dec.ignorerCache, wireId)
+		}
+	}
+	return
+}
+
+// decodeValue decodes the data stream representing a value and stores it in value.
+func (dec *Decoder) decodeValue(wireId typeId, value reflect.Value) {
+	defer catchError(&dec.err)
+	// If the value is nil, it means we should just ignore this item.
+	if !value.IsValid() {
+		dec.decodeIgnoredValue(wireId)
+		return
+	}
+	// Dereference down to the underlying type.
+	ut := userType(value.Type())
+	base := ut.base
+	var enginePtr **decEngine
+	enginePtr, dec.err = dec.getDecEnginePtr(wireId, ut)
+	if dec.err != nil {
+		return
+	}
+	value = decAlloc(value)
+	engine := *enginePtr
+	if st := base; st.Kind() == reflect.Struct && ut.externalDec == 0 {
+		if engine.numInstr == 0 && st.NumField() > 0 &&
+			dec.wireType[wireId] != nil && len(dec.wireType[wireId].StructT.Field) > 0 {
+			name := base.Name()
+			errorf("type mismatch: no fields matched compiling decoder for %s", name)
+		}
+		dec.decodeStruct(engine, ut, value)
+	} else {
+		dec.decodeSingle(engine, ut, value)
+	}
+}
+
+// decodeIgnoredValue decodes the data stream representing a value of the specified type and discards it.
+func (dec *Decoder) decodeIgnoredValue(wireId typeId) {
+	var enginePtr **decEngine
+	enginePtr, dec.err = dec.getIgnoreEnginePtr(wireId)
+	if dec.err != nil {
+		return
+	}
+	wire := dec.wireType[wireId]
+	if wire != nil && wire.StructT != nil {
+		dec.ignoreStruct(*enginePtr)
+	} else {
+		dec.ignoreSingle(*enginePtr)
+	}
+}
+
+func init() {
+	var iop, uop decOp
+	switch reflect.TypeOf(int(0)).Bits() {
+	case 32:
+		iop = decInt32
+		uop = decUint32
+	case 64:
+		iop = decInt64
+		uop = decUint64
+	default:
+		panic("gob: unknown size of int/uint")
+	}
+	decOpTable[reflect.Int] = iop
+	decOpTable[reflect.Uint] = uop
+
+	// Finally uintptr
+	switch reflect.TypeOf(uintptr(0)).Bits() {
+	case 32:
+		uop = decUint32
+	case 64:
+		uop = decUint64
+	default:
+		panic("gob: unknown size of uintptr")
+	}
+	decOpTable[reflect.Uintptr] = uop
+}
+
+// Gob depends on being able to take the address
+// of zeroed Values it creates, so use this wrapper instead
+// of the standard reflect.Zero.
+// Each call allocates once.
+func allocValue(t reflect.Type) reflect.Value {
+	return reflect.New(t).Elem()
+}
diff --git a/src/encoding/gob/decoder.go b/src/encoding/gob/decoder.go
new file mode 100644
index 0000000..c453e9b
--- /dev/null
+++ b/src/encoding/gob/decoder.go
@@ -0,0 +1,218 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package gob
+
+import (
+	"bufio"
+	"errors"
+	"io"
+	"reflect"
+	"sync"
+)
+
+// tooBig provides a sanity check for sizes; used in several places.
+// Upper limit of 1GB, allowing room to grow a little without overflow.
+// TODO: make this adjustable?
+const tooBig = 1 << 30
+
+// A Decoder manages the receipt of type and data information read from the
+// remote side of a connection.
+type Decoder struct {
+	mutex        sync.Mutex                              // each item must be received atomically
+	r            io.Reader                               // source of the data
+	buf          decBuffer                               // buffer for more efficient i/o from r
+	wireType     map[typeId]*wireType                    // map from remote ID to local description
+	decoderCache map[reflect.Type]map[typeId]**decEngine // cache of compiled engines
+	ignorerCache map[typeId]**decEngine                  // ditto for ignored objects
+	freeList     *decoderState                           // list of free decoderStates; avoids reallocation
+	countBuf     []byte                                  // used for decoding integers while parsing messages
+	err          error
+}
+
+// NewDecoder returns a new decoder that reads from the io.Reader.
+// If r does not also implement io.ByteReader, it will be wrapped in a
+// bufio.Reader.
+func NewDecoder(r io.Reader) *Decoder {
+	dec := new(Decoder)
+	// We use the ability to read bytes as a plausible surrogate for buffering.
+	if _, ok := r.(io.ByteReader); !ok {
+		r = bufio.NewReader(r)
+	}
+	dec.r = r
+	dec.wireType = make(map[typeId]*wireType)
+	dec.decoderCache = make(map[reflect.Type]map[typeId]**decEngine)
+	dec.ignorerCache = make(map[typeId]**decEngine)
+	dec.countBuf = make([]byte, 9) // counts may be uint64s (unlikely!), require 9 bytes
+
+	return dec
+}
+
+// recvType loads the definition of a type.
+func (dec *Decoder) recvType(id typeId) {
+	// Have we already seen this type?  That's an error
+	if id < firstUserId || dec.wireType[id] != nil {
+		dec.err = errors.New("gob: duplicate type received")
+		return
+	}
+
+	// Type:
+	wire := new(wireType)
+	dec.decodeValue(tWireType, reflect.ValueOf(wire))
+	if dec.err != nil {
+		return
+	}
+	// Remember we've seen this type.
+	dec.wireType[id] = wire
+}
+
+var errBadCount = errors.New("invalid message length")
+
+// recvMessage reads the next count-delimited item from the input. It is the converse
+// of Encoder.writeMessage. It returns false on EOF or other error reading the message.
+func (dec *Decoder) recvMessage() bool {
+	// Read a count.
+	nbytes, _, err := decodeUintReader(dec.r, dec.countBuf)
+	if err != nil {
+		dec.err = err
+		return false
+	}
+	if nbytes >= tooBig {
+		dec.err = errBadCount
+		return false
+	}
+	dec.readMessage(int(nbytes))
+	return dec.err == nil
+}
+
+// readMessage reads the next nbytes bytes from the input.
+func (dec *Decoder) readMessage(nbytes int) {
+	if dec.buf.Len() != 0 {
+		// The buffer should always be empty now.
+		panic("non-empty decoder buffer")
+	}
+	// Read the data
+	dec.buf.Size(nbytes)
+	_, dec.err = io.ReadFull(dec.r, dec.buf.Bytes())
+	if dec.err != nil {
+		if dec.err == io.EOF {
+			dec.err = io.ErrUnexpectedEOF
+		}
+	}
+}
+
+// toInt turns an encoded uint64 into an int, according to the marshaling rules.
+func toInt(x uint64) int64 {
+	i := int64(x >> 1)
+	if x&1 != 0 {
+		i = ^i
+	}
+	return i
+}
+
+func (dec *Decoder) nextInt() int64 {
+	n, _, err := decodeUintReader(&dec.buf, dec.countBuf)
+	if err != nil {
+		dec.err = err
+	}
+	return toInt(n)
+}
+
+func (dec *Decoder) nextUint() uint64 {
+	n, _, err := decodeUintReader(&dec.buf, dec.countBuf)
+	if err != nil {
+		dec.err = err
+	}
+	return n
+}
+
+// decodeTypeSequence parses:
+// TypeSequence
+//	(TypeDefinition DelimitedTypeDefinition*)?
+// and returns the type id of the next value.  It returns -1 at
+// EOF.  Upon return, the remainder of dec.buf is the value to be
+// decoded.  If this is an interface value, it can be ignored by
+// resetting that buffer.
+func (dec *Decoder) decodeTypeSequence(isInterface bool) typeId {
+	for dec.err == nil {
+		if dec.buf.Len() == 0 {
+			if !dec.recvMessage() {
+				break
+			}
+		}
+		// Receive a type id.
+		id := typeId(dec.nextInt())
+		if id >= 0 {
+			// Value follows.
+			return id
+		}
+		// Type definition for (-id) follows.
+		dec.recvType(-id)
+		// When decoding an interface, after a type there may be a
+		// DelimitedValue still in the buffer.  Skip its count.
+		// (Alternatively, the buffer is empty and the byte count
+		// will be absorbed by recvMessage.)
+		if dec.buf.Len() > 0 {
+			if !isInterface {
+				dec.err = errors.New("extra data in buffer")
+				break
+			}
+			dec.nextUint()
+		}
+	}
+	return -1
+}
+
+// Decode reads the next value from the input stream and stores
+// it in the data represented by the empty interface value.
+// If e is nil, the value will be discarded. Otherwise,
+// the value underlying e must be a pointer to the
+// correct type for the next data item received.
+// If the input is at EOF, Decode returns io.EOF and
+// does not modify e.
+func (dec *Decoder) Decode(e interface{}) error {
+	if e == nil {
+		return dec.DecodeValue(reflect.Value{})
+	}
+	value := reflect.ValueOf(e)
+	// If e represents a value as opposed to a pointer, the answer won't
+	// get back to the caller.  Make sure it's a pointer.
+	if value.Type().Kind() != reflect.Ptr {
+		dec.err = errors.New("gob: attempt to decode into a non-pointer")
+		return dec.err
+	}
+	return dec.DecodeValue(value)
+}
+
+// DecodeValue reads the next value from the input stream.
+// If v is the zero reflect.Value (v.Kind() == Invalid), DecodeValue discards the value.
+// Otherwise, it stores the value into v.  In that case, v must represent
+// a non-nil pointer to data or be an assignable reflect.Value (v.CanSet())
+// If the input is at EOF, DecodeValue returns io.EOF and
+// does not modify v.
+func (dec *Decoder) DecodeValue(v reflect.Value) error {
+	if v.IsValid() {
+		if v.Kind() == reflect.Ptr && !v.IsNil() {
+			// That's okay, we'll store through the pointer.
+		} else if !v.CanSet() {
+			return errors.New("gob: DecodeValue of unassignable value")
+		}
+	}
+	// Make sure we're single-threaded through here.
+	dec.mutex.Lock()
+	defer dec.mutex.Unlock()
+
+	dec.buf.Reset() // In case data lingers from previous invocation.
+	dec.err = nil
+	id := dec.decodeTypeSequence(false)
+	if dec.err == nil {
+		dec.decodeValue(id, v)
+	}
+	return dec.err
+}
+
+// If debug.go is compiled into the program , debugFunc prints a human-readable
+// representation of the gob data read from r by calling that file's Debug function.
+// Otherwise it is nil.
+var debugFunc func(io.Reader)
diff --git a/src/pkg/encoding/gob/doc.go b/src/encoding/gob/doc.go
similarity index 100%
rename from src/pkg/encoding/gob/doc.go
rename to src/encoding/gob/doc.go
diff --git a/src/pkg/encoding/gob/dump.go b/src/encoding/gob/dump.go
similarity index 100%
rename from src/pkg/encoding/gob/dump.go
rename to src/encoding/gob/dump.go
diff --git a/src/encoding/gob/enc_helpers.go b/src/encoding/gob/enc_helpers.go
new file mode 100644
index 0000000..804e539
--- /dev/null
+++ b/src/encoding/gob/enc_helpers.go
@@ -0,0 +1,414 @@
+// Created by encgen --output enc_helpers.go; DO NOT EDIT
+
+// 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 gob
+
+import (
+	"reflect"
+)
+
+var encArrayHelper = map[reflect.Kind]encHelper{
+	reflect.Bool:       encBoolArray,
+	reflect.Complex64:  encComplex64Array,
+	reflect.Complex128: encComplex128Array,
+	reflect.Float32:    encFloat32Array,
+	reflect.Float64:    encFloat64Array,
+	reflect.Int:        encIntArray,
+	reflect.Int16:      encInt16Array,
+	reflect.Int32:      encInt32Array,
+	reflect.Int64:      encInt64Array,
+	reflect.Int8:       encInt8Array,
+	reflect.String:     encStringArray,
+	reflect.Uint:       encUintArray,
+	reflect.Uint16:     encUint16Array,
+	reflect.Uint32:     encUint32Array,
+	reflect.Uint64:     encUint64Array,
+	reflect.Uintptr:    encUintptrArray,
+}
+
+var encSliceHelper = map[reflect.Kind]encHelper{
+	reflect.Bool:       encBoolSlice,
+	reflect.Complex64:  encComplex64Slice,
+	reflect.Complex128: encComplex128Slice,
+	reflect.Float32:    encFloat32Slice,
+	reflect.Float64:    encFloat64Slice,
+	reflect.Int:        encIntSlice,
+	reflect.Int16:      encInt16Slice,
+	reflect.Int32:      encInt32Slice,
+	reflect.Int64:      encInt64Slice,
+	reflect.Int8:       encInt8Slice,
+	reflect.String:     encStringSlice,
+	reflect.Uint:       encUintSlice,
+	reflect.Uint16:     encUint16Slice,
+	reflect.Uint32:     encUint32Slice,
+	reflect.Uint64:     encUint64Slice,
+	reflect.Uintptr:    encUintptrSlice,
+}
+
+func encBoolArray(state *encoderState, v reflect.Value) bool {
+	// Can only slice if it is addressable.
+	if !v.CanAddr() {
+		return false
+	}
+	return encBoolSlice(state, v.Slice(0, v.Len()))
+}
+
+func encBoolSlice(state *encoderState, v reflect.Value) bool {
+	slice, ok := v.Interface().([]bool)
+	if !ok {
+		// It is kind bool but not type bool. TODO: We can handle this unsafely.
+		return false
+	}
+	for _, x := range slice {
+		if x != false || state.sendZero {
+			if x {
+				state.encodeUint(1)
+			} else {
+				state.encodeUint(0)
+			}
+		}
+	}
+	return true
+}
+
+func encComplex64Array(state *encoderState, v reflect.Value) bool {
+	// Can only slice if it is addressable.
+	if !v.CanAddr() {
+		return false
+	}
+	return encComplex64Slice(state, v.Slice(0, v.Len()))
+}
+
+func encComplex64Slice(state *encoderState, v reflect.Value) bool {
+	slice, ok := v.Interface().([]complex64)
+	if !ok {
+		// It is kind complex64 but not type complex64. TODO: We can handle this unsafely.
+		return false
+	}
+	for _, x := range slice {
+		if x != 0+0i || state.sendZero {
+			rpart := floatBits(float64(real(x)))
+			ipart := floatBits(float64(imag(x)))
+			state.encodeUint(rpart)
+			state.encodeUint(ipart)
+		}
+	}
+	return true
+}
+
+func encComplex128Array(state *encoderState, v reflect.Value) bool {
+	// Can only slice if it is addressable.
+	if !v.CanAddr() {
+		return false
+	}
+	return encComplex128Slice(state, v.Slice(0, v.Len()))
+}
+
+func encComplex128Slice(state *encoderState, v reflect.Value) bool {
+	slice, ok := v.Interface().([]complex128)
+	if !ok {
+		// It is kind complex128 but not type complex128. TODO: We can handle this unsafely.
+		return false
+	}
+	for _, x := range slice {
+		if x != 0+0i || state.sendZero {
+			rpart := floatBits(real(x))
+			ipart := floatBits(imag(x))
+			state.encodeUint(rpart)
+			state.encodeUint(ipart)
+		}
+	}
+	return true
+}
+
+func encFloat32Array(state *encoderState, v reflect.Value) bool {
+	// Can only slice if it is addressable.
+	if !v.CanAddr() {
+		return false
+	}
+	return encFloat32Slice(state, v.Slice(0, v.Len()))
+}
+
+func encFloat32Slice(state *encoderState, v reflect.Value) bool {
+	slice, ok := v.Interface().([]float32)
+	if !ok {
+		// It is kind float32 but not type float32. TODO: We can handle this unsafely.
+		return false
+	}
+	for _, x := range slice {
+		if x != 0 || state.sendZero {
+			bits := floatBits(float64(x))
+			state.encodeUint(bits)
+		}
+	}
+	return true
+}
+
+func encFloat64Array(state *encoderState, v reflect.Value) bool {
+	// Can only slice if it is addressable.
+	if !v.CanAddr() {
+		return false
+	}
+	return encFloat64Slice(state, v.Slice(0, v.Len()))
+}
+
+func encFloat64Slice(state *encoderState, v reflect.Value) bool {
+	slice, ok := v.Interface().([]float64)
+	if !ok {
+		// It is kind float64 but not type float64. TODO: We can handle this unsafely.
+		return false
+	}
+	for _, x := range slice {
+		if x != 0 || state.sendZero {
+			bits := floatBits(x)
+			state.encodeUint(bits)
+		}
+	}
+	return true
+}
+
+func encIntArray(state *encoderState, v reflect.Value) bool {
+	// Can only slice if it is addressable.
+	if !v.CanAddr() {
+		return false
+	}
+	return encIntSlice(state, v.Slice(0, v.Len()))
+}
+
+func encIntSlice(state *encoderState, v reflect.Value) bool {
+	slice, ok := v.Interface().([]int)
+	if !ok {
+		// It is kind int but not type int. TODO: We can handle this unsafely.
+		return false
+	}
+	for _, x := range slice {
+		if x != 0 || state.sendZero {
+			state.encodeInt(int64(x))
+		}
+	}
+	return true
+}
+
+func encInt16Array(state *encoderState, v reflect.Value) bool {
+	// Can only slice if it is addressable.
+	if !v.CanAddr() {
+		return false
+	}
+	return encInt16Slice(state, v.Slice(0, v.Len()))
+}
+
+func encInt16Slice(state *encoderState, v reflect.Value) bool {
+	slice, ok := v.Interface().([]int16)
+	if !ok {
+		// It is kind int16 but not type int16. TODO: We can handle this unsafely.
+		return false
+	}
+	for _, x := range slice {
+		if x != 0 || state.sendZero {
+			state.encodeInt(int64(x))
+		}
+	}
+	return true
+}
+
+func encInt32Array(state *encoderState, v reflect.Value) bool {
+	// Can only slice if it is addressable.
+	if !v.CanAddr() {
+		return false
+	}
+	return encInt32Slice(state, v.Slice(0, v.Len()))
+}
+
+func encInt32Slice(state *encoderState, v reflect.Value) bool {
+	slice, ok := v.Interface().([]int32)
+	if !ok {
+		// It is kind int32 but not type int32. TODO: We can handle this unsafely.
+		return false
+	}
+	for _, x := range slice {
+		if x != 0 || state.sendZero {
+			state.encodeInt(int64(x))
+		}
+	}
+	return true
+}
+
+func encInt64Array(state *encoderState, v reflect.Value) bool {
+	// Can only slice if it is addressable.
+	if !v.CanAddr() {
+		return false
+	}
+	return encInt64Slice(state, v.Slice(0, v.Len()))
+}
+
+func encInt64Slice(state *encoderState, v reflect.Value) bool {
+	slice, ok := v.Interface().([]int64)
+	if !ok {
+		// It is kind int64 but not type int64. TODO: We can handle this unsafely.
+		return false
+	}
+	for _, x := range slice {
+		if x != 0 || state.sendZero {
+			state.encodeInt(x)
+		}
+	}
+	return true
+}
+
+func encInt8Array(state *encoderState, v reflect.Value) bool {
+	// Can only slice if it is addressable.
+	if !v.CanAddr() {
+		return false
+	}
+	return encInt8Slice(state, v.Slice(0, v.Len()))
+}
+
+func encInt8Slice(state *encoderState, v reflect.Value) bool {
+	slice, ok := v.Interface().([]int8)
+	if !ok {
+		// It is kind int8 but not type int8. TODO: We can handle this unsafely.
+		return false
+	}
+	for _, x := range slice {
+		if x != 0 || state.sendZero {
+			state.encodeInt(int64(x))
+		}
+	}
+	return true
+}
+
+func encStringArray(state *encoderState, v reflect.Value) bool {
+	// Can only slice if it is addressable.
+	if !v.CanAddr() {
+		return false
+	}
+	return encStringSlice(state, v.Slice(0, v.Len()))
+}
+
+func encStringSlice(state *encoderState, v reflect.Value) bool {
+	slice, ok := v.Interface().([]string)
+	if !ok {
+		// It is kind string but not type string. TODO: We can handle this unsafely.
+		return false
+	}
+	for _, x := range slice {
+		if x != "" || state.sendZero {
+			state.encodeUint(uint64(len(x)))
+			state.b.WriteString(x)
+		}
+	}
+	return true
+}
+
+func encUintArray(state *encoderState, v reflect.Value) bool {
+	// Can only slice if it is addressable.
+	if !v.CanAddr() {
+		return false
+	}
+	return encUintSlice(state, v.Slice(0, v.Len()))
+}
+
+func encUintSlice(state *encoderState, v reflect.Value) bool {
+	slice, ok := v.Interface().([]uint)
+	if !ok {
+		// It is kind uint but not type uint. TODO: We can handle this unsafely.
+		return false
+	}
+	for _, x := range slice {
+		if x != 0 || state.sendZero {
+			state.encodeUint(uint64(x))
+		}
+	}
+	return true
+}
+
+func encUint16Array(state *encoderState, v reflect.Value) bool {
+	// Can only slice if it is addressable.
+	if !v.CanAddr() {
+		return false
+	}
+	return encUint16Slice(state, v.Slice(0, v.Len()))
+}
+
+func encUint16Slice(state *encoderState, v reflect.Value) bool {
+	slice, ok := v.Interface().([]uint16)
+	if !ok {
+		// It is kind uint16 but not type uint16. TODO: We can handle this unsafely.
+		return false
+	}
+	for _, x := range slice {
+		if x != 0 || state.sendZero {
+			state.encodeUint(uint64(x))
+		}
+	}
+	return true
+}
+
+func encUint32Array(state *encoderState, v reflect.Value) bool {
+	// Can only slice if it is addressable.
+	if !v.CanAddr() {
+		return false
+	}
+	return encUint32Slice(state, v.Slice(0, v.Len()))
+}
+
+func encUint32Slice(state *encoderState, v reflect.Value) bool {
+	slice, ok := v.Interface().([]uint32)
+	if !ok {
+		// It is kind uint32 but not type uint32. TODO: We can handle this unsafely.
+		return false
+	}
+	for _, x := range slice {
+		if x != 0 || state.sendZero {
+			state.encodeUint(uint64(x))
+		}
+	}
+	return true
+}
+
+func encUint64Array(state *encoderState, v reflect.Value) bool {
+	// Can only slice if it is addressable.
+	if !v.CanAddr() {
+		return false
+	}
+	return encUint64Slice(state, v.Slice(0, v.Len()))
+}
+
+func encUint64Slice(state *encoderState, v reflect.Value) bool {
+	slice, ok := v.Interface().([]uint64)
+	if !ok {
+		// It is kind uint64 but not type uint64. TODO: We can handle this unsafely.
+		return false
+	}
+	for _, x := range slice {
+		if x != 0 || state.sendZero {
+			state.encodeUint(x)
+		}
+	}
+	return true
+}
+
+func encUintptrArray(state *encoderState, v reflect.Value) bool {
+	// Can only slice if it is addressable.
+	if !v.CanAddr() {
+		return false
+	}
+	return encUintptrSlice(state, v.Slice(0, v.Len()))
+}
+
+func encUintptrSlice(state *encoderState, v reflect.Value) bool {
+	slice, ok := v.Interface().([]uintptr)
+	if !ok {
+		// It is kind uintptr but not type uintptr. TODO: We can handle this unsafely.
+		return false
+	}
+	for _, x := range slice {
+		if x != 0 || state.sendZero {
+			state.encodeUint(uint64(x))
+		}
+	}
+	return true
+}
diff --git a/src/encoding/gob/encgen.go b/src/encoding/gob/encgen.go
new file mode 100644
index 0000000..efdd928
--- /dev/null
+++ b/src/encoding/gob/encgen.go
@@ -0,0 +1,218 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build ignore
+
+// encgen writes the helper functions for encoding. Intended to be
+// used with go generate; see the invocation in encode.go.
+
+// TODO: We could do more by being unsafe. Add a -unsafe flag?
+
+package main
+
+import (
+	"bytes"
+	"flag"
+	"fmt"
+	"go/format"
+	"log"
+	"os"
+)
+
+var output = flag.String("output", "enc_helpers.go", "file name to write")
+
+type Type struct {
+	lower   string
+	upper   string
+	zero    string
+	encoder string
+}
+
+var types = []Type{
+	{
+		"bool",
+		"Bool",
+		"false",
+		`if x {
+			state.encodeUint(1)
+		} else {
+			state.encodeUint(0)
+		}`,
+	},
+	{
+		"complex64",
+		"Complex64",
+		"0+0i",
+		`rpart := floatBits(float64(real(x)))
+		ipart := floatBits(float64(imag(x)))
+		state.encodeUint(rpart)
+		state.encodeUint(ipart)`,
+	},
+	{
+		"complex128",
+		"Complex128",
+		"0+0i",
+		`rpart := floatBits(real(x))
+		ipart := floatBits(imag(x))
+		state.encodeUint(rpart)
+		state.encodeUint(ipart)`,
+	},
+	{
+		"float32",
+		"Float32",
+		"0",
+		`bits := floatBits(float64(x))
+		state.encodeUint(bits)`,
+	},
+	{
+		"float64",
+		"Float64",
+		"0",
+		`bits := floatBits(x)
+		state.encodeUint(bits)`,
+	},
+	{
+		"int",
+		"Int",
+		"0",
+		`state.encodeInt(int64(x))`,
+	},
+	{
+		"int16",
+		"Int16",
+		"0",
+		`state.encodeInt(int64(x))`,
+	},
+	{
+		"int32",
+		"Int32",
+		"0",
+		`state.encodeInt(int64(x))`,
+	},
+	{
+		"int64",
+		"Int64",
+		"0",
+		`state.encodeInt(x)`,
+	},
+	{
+		"int8",
+		"Int8",
+		"0",
+		`state.encodeInt(int64(x))`,
+	},
+	{
+		"string",
+		"String",
+		`""`,
+		`state.encodeUint(uint64(len(x)))
+		state.b.WriteString(x)`,
+	},
+	{
+		"uint",
+		"Uint",
+		"0",
+		`state.encodeUint(uint64(x))`,
+	},
+	{
+		"uint16",
+		"Uint16",
+		"0",
+		`state.encodeUint(uint64(x))`,
+	},
+	{
+		"uint32",
+		"Uint32",
+		"0",
+		`state.encodeUint(uint64(x))`,
+	},
+	{
+		"uint64",
+		"Uint64",
+		"0",
+		`state.encodeUint(x)`,
+	},
+	{
+		"uintptr",
+		"Uintptr",
+		"0",
+		`state.encodeUint(uint64(x))`,
+	},
+	// uint8 Handled separately.
+}
+
+func main() {
+	log.SetFlags(0)
+	log.SetPrefix("encgen: ")
+	flag.Parse()
+	if flag.NArg() != 0 {
+		log.Fatal("usage: encgen [--output filename]")
+	}
+	var b bytes.Buffer
+	fmt.Fprintf(&b, "// Created by encgen --output %s; DO NOT EDIT\n", *output)
+	fmt.Fprint(&b, header)
+	printMaps(&b, "Array")
+	fmt.Fprint(&b, "\n")
+	printMaps(&b, "Slice")
+	for _, t := range types {
+		fmt.Fprintf(&b, arrayHelper, t.lower, t.upper)
+		fmt.Fprintf(&b, sliceHelper, t.lower, t.upper, t.zero, t.encoder)
+	}
+	source, err := format.Source(b.Bytes())
+	if err != nil {
+		log.Fatal("source format error:", err)
+	}
+	fd, err := os.Create(*output)
+	_, err = fd.Write(source)
+	if err != nil {
+		log.Fatal(err)
+	}
+}
+
+func printMaps(b *bytes.Buffer, upperClass string) {
+	fmt.Fprintf(b, "var enc%sHelper = map[reflect.Kind]encHelper{\n", upperClass)
+	for _, t := range types {
+		fmt.Fprintf(b, "reflect.%s: enc%s%s,\n", t.upper, t.upper, upperClass)
+	}
+	fmt.Fprintf(b, "}\n")
+}
+
+const header = `
+// 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 gob
+
+import (
+	"reflect"
+)
+
+`
+
+const arrayHelper = `
+func enc%[2]sArray(state *encoderState, v reflect.Value) bool {
+	// Can only slice if it is addressable.
+	if !v.CanAddr() {
+		return false
+	}
+	return enc%[2]sSlice(state, v.Slice(0, v.Len()))
+}
+`
+
+const sliceHelper = `
+func enc%[2]sSlice(state *encoderState, v reflect.Value) bool {
+	slice, ok := v.Interface().([]%[1]s)
+	if !ok {
+		// It is kind %[1]s but not type %[1]s. TODO: We can handle this unsafely.
+		return false
+	}
+	for _, x := range slice {
+		if x != %[3]s || state.sendZero {
+			%[4]s
+		}
+	}
+	return true
+}
+`
diff --git a/src/encoding/gob/encode.go b/src/encoding/gob/encode.go
new file mode 100644
index 0000000..f66279f
--- /dev/null
+++ b/src/encoding/gob/encode.go
@@ -0,0 +1,696 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:generate go run encgen.go -output enc_helpers.go
+
+package gob
+
+import (
+	"encoding"
+	"math"
+	"reflect"
+)
+
+const uint64Size = 8
+
+type encHelper func(state *encoderState, v reflect.Value) bool
+
+// encoderState is the global execution state of an instance of the encoder.
+// Field numbers are delta encoded and always increase. The field
+// number is initialized to -1 so 0 comes out as delta(1). A delta of
+// 0 terminates the structure.
+type encoderState struct {
+	enc      *Encoder
+	b        *encBuffer
+	sendZero bool                 // encoding an array element or map key/value pair; send zero values
+	fieldnum int                  // the last field number written.
+	buf      [1 + uint64Size]byte // buffer used by the encoder; here to avoid allocation.
+	next     *encoderState        // for free list
+}
+
+// encBuffer is an extremely simple, fast implementation of a write-only byte buffer.
+// It never returns a non-nil error, but Write returns an error value so it matches io.Writer.
+type encBuffer struct {
+	data    []byte
+	scratch [64]byte
+}
+
+func (e *encBuffer) WriteByte(c byte) {
+	e.data = append(e.data, c)
+}
+
+func (e *encBuffer) Write(p []byte) (int, error) {
+	e.data = append(e.data, p...)
+	return len(p), nil
+}
+
+func (e *encBuffer) WriteString(s string) {
+	e.data = append(e.data, s...)
+}
+
+func (e *encBuffer) Len() int {
+	return len(e.data)
+}
+
+func (e *encBuffer) Bytes() []byte {
+	return e.data
+}
+
+func (e *encBuffer) Reset() {
+	e.data = e.data[0:0]
+}
+
+func (enc *Encoder) newEncoderState(b *encBuffer) *encoderState {
+	e := enc.freeList
+	if e == nil {
+		e = new(encoderState)
+		e.enc = enc
+	} else {
+		enc.freeList = e.next
+	}
+	e.sendZero = false
+	e.fieldnum = 0
+	e.b = b
+	if len(b.data) == 0 {
+		b.data = b.scratch[0:0]
+	}
+	return e
+}
+
+func (enc *Encoder) freeEncoderState(e *encoderState) {
+	e.next = enc.freeList
+	enc.freeList = e
+}
+
+// Unsigned integers have a two-state encoding.  If the number is less
+// than 128 (0 through 0x7F), its value is written directly.
+// Otherwise the value is written in big-endian byte order preceded
+// by the byte length, negated.
+
+// encodeUint writes an encoded unsigned integer to state.b.
+func (state *encoderState) encodeUint(x uint64) {
+	if x <= 0x7F {
+		state.b.WriteByte(uint8(x))
+		return
+	}
+	i := uint64Size
+	for x > 0 {
+		state.buf[i] = uint8(x)
+		x >>= 8
+		i--
+	}
+	state.buf[i] = uint8(i - uint64Size) // = loop count, negated
+	state.b.Write(state.buf[i : uint64Size+1])
+}
+
+// encodeInt writes an encoded signed integer to state.w.
+// The low bit of the encoding says whether to bit complement the (other bits of the)
+// uint to recover the int.
+func (state *encoderState) encodeInt(i int64) {
+	var x uint64
+	if i < 0 {
+		x = uint64(^i<<1) | 1
+	} else {
+		x = uint64(i << 1)
+	}
+	state.encodeUint(uint64(x))
+}
+
+// encOp is the signature of an encoding operator for a given type.
+type encOp func(i *encInstr, state *encoderState, v reflect.Value)
+
+// The 'instructions' of the encoding machine
+type encInstr struct {
+	op    encOp
+	field int   // field number in input
+	index []int // struct index
+	indir int   // how many pointer indirections to reach the value in the struct
+}
+
+// update emits a field number and updates the state to record its value for delta encoding.
+// If the instruction pointer is nil, it does nothing
+func (state *encoderState) update(instr *encInstr) {
+	if instr != nil {
+		state.encodeUint(uint64(instr.field - state.fieldnum))
+		state.fieldnum = instr.field
+	}
+}
+
+// Each encoder for a composite is responsible for handling any
+// indirections associated with the elements of the data structure.
+// If any pointer so reached is nil, no bytes are written.  If the
+// data item is zero, no bytes are written.  Single values - ints,
+// strings etc. - are indirected before calling their encoders.
+// Otherwise, the output (for a scalar) is the field number, as an
+// encoded integer, followed by the field data in its appropriate
+// format.
+
+// encIndirect dereferences pv indir times and returns the result.
+func encIndirect(pv reflect.Value, indir int) reflect.Value {
+	for ; indir > 0; indir-- {
+		if pv.IsNil() {
+			break
+		}
+		pv = pv.Elem()
+	}
+	return pv
+}
+
+// encBool encodes the bool referenced by v as an unsigned 0 or 1.
+func encBool(i *encInstr, state *encoderState, v reflect.Value) {
+	b := v.Bool()
+	if b || state.sendZero {
+		state.update(i)
+		if b {
+			state.encodeUint(1)
+		} else {
+			state.encodeUint(0)
+		}
+	}
+}
+
+// encInt encodes the signed integer (int int8 int16 int32 int64) referenced by v.
+func encInt(i *encInstr, state *encoderState, v reflect.Value) {
+	value := v.Int()
+	if value != 0 || state.sendZero {
+		state.update(i)
+		state.encodeInt(value)
+	}
+}
+
+// encUint encodes the unsigned integer (uint uint8 uint16 uint32 uint64 uintptr) referenced by v.
+func encUint(i *encInstr, state *encoderState, v reflect.Value) {
+	value := v.Uint()
+	if value != 0 || state.sendZero {
+		state.update(i)
+		state.encodeUint(value)
+	}
+}
+
+// floatBits returns a uint64 holding the bits of a floating-point number.
+// Floating-point numbers are transmitted as uint64s holding the bits
+// of the underlying representation.  They are sent byte-reversed, with
+// the exponent end coming out first, so integer floating point numbers
+// (for example) transmit more compactly.  This routine does the
+// swizzling.
+func floatBits(f float64) uint64 {
+	u := math.Float64bits(f)
+	var v uint64
+	for i := 0; i < 8; i++ {
+		v <<= 8
+		v |= u & 0xFF
+		u >>= 8
+	}
+	return v
+}
+
+// encFloat encodes the floating point value (float32 float64) referenced by v.
+func encFloat(i *encInstr, state *encoderState, v reflect.Value) {
+	f := v.Float()
+	if f != 0 || state.sendZero {
+		bits := floatBits(f)
+		state.update(i)
+		state.encodeUint(bits)
+	}
+}
+
+// encComplex encodes the complex value (complex64 complex128) referenced by v.
+// Complex numbers are just a pair of floating-point numbers, real part first.
+func encComplex(i *encInstr, state *encoderState, v reflect.Value) {
+	c := v.Complex()
+	if c != 0+0i || state.sendZero {
+		rpart := floatBits(real(c))
+		ipart := floatBits(imag(c))
+		state.update(i)
+		state.encodeUint(rpart)
+		state.encodeUint(ipart)
+	}
+}
+
+// encUint8Array encodes the byte array referenced by v.
+// Byte arrays are encoded as an unsigned count followed by the raw bytes.
+func encUint8Array(i *encInstr, state *encoderState, v reflect.Value) {
+	b := v.Bytes()
+	if len(b) > 0 || state.sendZero {
+		state.update(i)
+		state.encodeUint(uint64(len(b)))
+		state.b.Write(b)
+	}
+}
+
+// encString encodes the string referenced by v.
+// Strings are encoded as an unsigned count followed by the raw bytes.
+func encString(i *encInstr, state *encoderState, v reflect.Value) {
+	s := v.String()
+	if len(s) > 0 || state.sendZero {
+		state.update(i)
+		state.encodeUint(uint64(len(s)))
+		state.b.WriteString(s)
+	}
+}
+
+// encStructTerminator encodes the end of an encoded struct
+// as delta field number of 0.
+func encStructTerminator(i *encInstr, state *encoderState, v reflect.Value) {
+	state.encodeUint(0)
+}
+
+// Execution engine
+
+// encEngine an array of instructions indexed by field number of the encoding
+// data, typically a struct.  It is executed top to bottom, walking the struct.
+type encEngine struct {
+	instr []encInstr
+}
+
+const singletonField = 0
+
+// valid reports whether the value is valid and a non-nil pointer.
+// (Slices, maps, and chans take care of themselves.)
+func valid(v reflect.Value) bool {
+	switch v.Kind() {
+	case reflect.Invalid:
+		return false
+	case reflect.Ptr:
+		return !v.IsNil()
+	}
+	return true
+}
+
+// encodeSingle encodes a single top-level non-struct value.
+func (enc *Encoder) encodeSingle(b *encBuffer, engine *encEngine, value reflect.Value) {
+	state := enc.newEncoderState(b)
+	defer enc.freeEncoderState(state)
+	state.fieldnum = singletonField
+	// There is no surrounding struct to frame the transmission, so we must
+	// generate data even if the item is zero.  To do this, set sendZero.
+	state.sendZero = true
+	instr := &engine.instr[singletonField]
+	if instr.indir > 0 {
+		value = encIndirect(value, instr.indir)
+	}
+	if valid(value) {
+		instr.op(instr, state, value)
+	}
+}
+
+// encodeStruct encodes a single struct value.
+func (enc *Encoder) encodeStruct(b *encBuffer, engine *encEngine, value reflect.Value) {
+	if !valid(value) {
+		return
+	}
+	state := enc.newEncoderState(b)
+	defer enc.freeEncoderState(state)
+	state.fieldnum = -1
+	for i := 0; i < len(engine.instr); i++ {
+		instr := &engine.instr[i]
+		if i >= value.NumField() {
+			// encStructTerminator
+			instr.op(instr, state, reflect.Value{})
+			break
+		}
+		field := value.FieldByIndex(instr.index)
+		if instr.indir > 0 {
+			field = encIndirect(field, instr.indir)
+			// TODO: Is field guaranteed valid? If so we could avoid this check.
+			if !valid(field) {
+				continue
+			}
+		}
+		instr.op(instr, state, field)
+	}
+}
+
+// encodeArray encodes an array.
+func (enc *Encoder) encodeArray(b *encBuffer, value reflect.Value, op encOp, elemIndir int, length int, helper encHelper) {
+	state := enc.newEncoderState(b)
+	defer enc.freeEncoderState(state)
+	state.fieldnum = -1
+	state.sendZero = true
+	state.encodeUint(uint64(length))
+	if helper != nil && helper(state, value) {
+		return
+	}
+	for i := 0; i < length; i++ {
+		elem := value.Index(i)
+		if elemIndir > 0 {
+			elem = encIndirect(elem, elemIndir)
+			// TODO: Is elem guaranteed valid? If so we could avoid this check.
+			if !valid(elem) {
+				errorf("encodeArray: nil element")
+			}
+		}
+		op(nil, state, elem)
+	}
+}
+
+// encodeReflectValue is a helper for maps. It encodes the value v.
+func encodeReflectValue(state *encoderState, v reflect.Value, op encOp, indir int) {
+	for i := 0; i < indir && v.IsValid(); i++ {
+		v = reflect.Indirect(v)
+	}
+	if !v.IsValid() {
+		errorf("encodeReflectValue: nil element")
+	}
+	op(nil, state, v)
+}
+
+// encodeMap encodes a map as unsigned count followed by key:value pairs.
+func (enc *Encoder) encodeMap(b *encBuffer, mv reflect.Value, keyOp, elemOp encOp, keyIndir, elemIndir int) {
+	state := enc.newEncoderState(b)
+	state.fieldnum = -1
+	state.sendZero = true
+	keys := mv.MapKeys()
+	state.encodeUint(uint64(len(keys)))
+	for _, key := range keys {
+		encodeReflectValue(state, key, keyOp, keyIndir)
+		encodeReflectValue(state, mv.MapIndex(key), elemOp, elemIndir)
+	}
+	enc.freeEncoderState(state)
+}
+
+// encodeInterface encodes the interface value iv.
+// To send an interface, we send a string identifying the concrete type, followed
+// by the type identifier (which might require defining that type right now), followed
+// by the concrete value.  A nil value gets sent as the empty string for the name,
+// followed by no value.
+func (enc *Encoder) encodeInterface(b *encBuffer, iv reflect.Value) {
+	// Gobs can encode nil interface values but not typed interface
+	// values holding nil pointers, since nil pointers point to no value.
+	elem := iv.Elem()
+	if elem.Kind() == reflect.Ptr && elem.IsNil() {
+		errorf("gob: cannot encode nil pointer of type %s inside interface", iv.Elem().Type())
+	}
+	state := enc.newEncoderState(b)
+	state.fieldnum = -1
+	state.sendZero = true
+	if iv.IsNil() {
+		state.encodeUint(0)
+		return
+	}
+
+	ut := userType(iv.Elem().Type())
+	registerLock.RLock()
+	name, ok := concreteTypeToName[ut.base]
+	registerLock.RUnlock()
+	if !ok {
+		errorf("type not registered for interface: %s", ut.base)
+	}
+	// Send the name.
+	state.encodeUint(uint64(len(name)))
+	state.b.WriteString(name)
+	// Define the type id if necessary.
+	enc.sendTypeDescriptor(enc.writer(), state, ut)
+	// Send the type id.
+	enc.sendTypeId(state, ut)
+	// Encode the value into a new buffer.  Any nested type definitions
+	// should be written to b, before the encoded value.
+	enc.pushWriter(b)
+	data := new(encBuffer)
+	data.Write(spaceForLength)
+	enc.encode(data, elem, ut)
+	if enc.err != nil {
+		error_(enc.err)
+	}
+	enc.popWriter()
+	enc.writeMessage(b, data)
+	if enc.err != nil {
+		error_(enc.err)
+	}
+	enc.freeEncoderState(state)
+}
+
+// isZero reports whether the value is the zero of its type.
+func isZero(val reflect.Value) bool {
+	switch val.Kind() {
+	case reflect.Array:
+		for i := 0; i < val.Len(); i++ {
+			if !isZero(val.Index(i)) {
+				return false
+			}
+		}
+		return true
+	case reflect.Map, reflect.Slice, reflect.String:
+		return val.Len() == 0
+	case reflect.Bool:
+		return !val.Bool()
+	case reflect.Complex64, reflect.Complex128:
+		return val.Complex() == 0
+	case reflect.Chan, reflect.Func, reflect.Interface, reflect.Ptr:
+		return val.IsNil()
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		return val.Int() == 0
+	case reflect.Float32, reflect.Float64:
+		return val.Float() == 0
+	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+		return val.Uint() == 0
+	case reflect.Struct:
+		for i := 0; i < val.NumField(); i++ {
+			if !isZero(val.Field(i)) {
+				return false
+			}
+		}
+		return true
+	}
+	panic("unknown type in isZero " + val.Type().String())
+}
+
+// encGobEncoder encodes a value that implements the GobEncoder interface.
+// The data is sent as a byte array.
+func (enc *Encoder) encodeGobEncoder(b *encBuffer, ut *userTypeInfo, v reflect.Value) {
+	// TODO: should we catch panics from the called method?
+
+	var data []byte
+	var err error
+	// We know it's one of these.
+	switch ut.externalEnc {
+	case xGob:
+		data, err = v.Interface().(GobEncoder).GobEncode()
+	case xBinary:
+		data, err = v.Interface().(encoding.BinaryMarshaler).MarshalBinary()
+	case xText:
+		data, err = v.Interface().(encoding.TextMarshaler).MarshalText()
+	}
+	if err != nil {
+		error_(err)
+	}
+	state := enc.newEncoderState(b)
+	state.fieldnum = -1
+	state.encodeUint(uint64(len(data)))
+	state.b.Write(data)
+	enc.freeEncoderState(state)
+}
+
+var encOpTable = [...]encOp{
+	reflect.Bool:       encBool,
+	reflect.Int:        encInt,
+	reflect.Int8:       encInt,
+	reflect.Int16:      encInt,
+	reflect.Int32:      encInt,
+	reflect.Int64:      encInt,
+	reflect.Uint:       encUint,
+	reflect.Uint8:      encUint,
+	reflect.Uint16:     encUint,
+	reflect.Uint32:     encUint,
+	reflect.Uint64:     encUint,
+	reflect.Uintptr:    encUint,
+	reflect.Float32:    encFloat,
+	reflect.Float64:    encFloat,
+	reflect.Complex64:  encComplex,
+	reflect.Complex128: encComplex,
+	reflect.String:     encString,
+}
+
+// encOpFor returns (a pointer to) the encoding op for the base type under rt and
+// the indirection count to reach it.
+func encOpFor(rt reflect.Type, inProgress map[reflect.Type]*encOp, building map[*typeInfo]bool) (*encOp, int) {
+	ut := userType(rt)
+	// If the type implements GobEncoder, we handle it without further processing.
+	if ut.externalEnc != 0 {
+		return gobEncodeOpFor(ut)
+	}
+	// If this type is already in progress, it's a recursive type (e.g. map[string]*T).
+	// Return the pointer to the op we're already building.
+	if opPtr := inProgress[rt]; opPtr != nil {
+		return opPtr, ut.indir
+	}
+	typ := ut.base
+	indir := ut.indir
+	k := typ.Kind()
+	var op encOp
+	if int(k) < len(encOpTable) {
+		op = encOpTable[k]
+	}
+	if op == nil {
+		inProgress[rt] = &op
+		// Special cases
+		switch t := typ; t.Kind() {
+		case reflect.Slice:
+			if t.Elem().Kind() == reflect.Uint8 {
+				op = encUint8Array
+				break
+			}
+			// Slices have a header; we decode it to find the underlying array.
+			elemOp, elemIndir := encOpFor(t.Elem(), inProgress, building)
+			helper := encSliceHelper[t.Elem().Kind()]
+			op = func(i *encInstr, state *encoderState, slice reflect.Value) {
+				if !state.sendZero && slice.Len() == 0 {
+					return
+				}
+				state.update(i)
+				state.enc.encodeArray(state.b, slice, *elemOp, elemIndir, slice.Len(), helper)
+			}
+		case reflect.Array:
+			// True arrays have size in the type.
+			elemOp, elemIndir := encOpFor(t.Elem(), inProgress, building)
+			helper := encArrayHelper[t.Elem().Kind()]
+			op = func(i *encInstr, state *encoderState, array reflect.Value) {
+				state.update(i)
+				state.enc.encodeArray(state.b, array, *elemOp, elemIndir, array.Len(), helper)
+			}
+		case reflect.Map:
+			keyOp, keyIndir := encOpFor(t.Key(), inProgress, building)
+			elemOp, elemIndir := encOpFor(t.Elem(), inProgress, building)
+			op = func(i *encInstr, state *encoderState, mv reflect.Value) {
+				// We send zero-length (but non-nil) maps because the
+				// receiver might want to use the map.  (Maps don't use append.)
+				if !state.sendZero && mv.IsNil() {
+					return
+				}
+				state.update(i)
+				state.enc.encodeMap(state.b, mv, *keyOp, *elemOp, keyIndir, elemIndir)
+			}
+		case reflect.Struct:
+			// Generate a closure that calls out to the engine for the nested type.
+			getEncEngine(userType(typ), building)
+			info := mustGetTypeInfo(typ)
+			op = func(i *encInstr, state *encoderState, sv reflect.Value) {
+				state.update(i)
+				// indirect through info to delay evaluation for recursive structs
+				enc := info.encoder.Load().(*encEngine)
+				state.enc.encodeStruct(state.b, enc, sv)
+			}
+		case reflect.Interface:
+			op = func(i *encInstr, state *encoderState, iv reflect.Value) {
+				if !state.sendZero && (!iv.IsValid() || iv.IsNil()) {
+					return
+				}
+				state.update(i)
+				state.enc.encodeInterface(state.b, iv)
+			}
+		}
+	}
+	if op == nil {
+		errorf("can't happen: encode type %s", rt)
+	}
+	return &op, indir
+}
+
+// gobEncodeOpFor returns the op for a type that is known to implement GobEncoder.
+func gobEncodeOpFor(ut *userTypeInfo) (*encOp, int) {
+	rt := ut.user
+	if ut.encIndir == -1 {
+		rt = reflect.PtrTo(rt)
+	} else if ut.encIndir > 0 {
+		for i := int8(0); i < ut.encIndir; i++ {
+			rt = rt.Elem()
+		}
+	}
+	var op encOp
+	op = func(i *encInstr, state *encoderState, v reflect.Value) {
+		if ut.encIndir == -1 {
+			// Need to climb up one level to turn value into pointer.
+			if !v.CanAddr() {
+				errorf("unaddressable value of type %s", rt)
+			}
+			v = v.Addr()
+		}
+		if !state.sendZero && isZero(v) {
+			return
+		}
+		state.update(i)
+		state.enc.encodeGobEncoder(state.b, ut, v)
+	}
+	return &op, int(ut.encIndir) // encIndir: op will get called with p == address of receiver.
+}
+
+// compileEnc returns the engine to compile the type.
+func compileEnc(ut *userTypeInfo, building map[*typeInfo]bool) *encEngine {
+	srt := ut.base
+	engine := new(encEngine)
+	seen := make(map[reflect.Type]*encOp)
+	rt := ut.base
+	if ut.externalEnc != 0 {
+		rt = ut.user
+	}
+	if ut.externalEnc == 0 && srt.Kind() == reflect.Struct {
+		for fieldNum, wireFieldNum := 0, 0; fieldNum < srt.NumField(); fieldNum++ {
+			f := srt.Field(fieldNum)
+			if !isSent(&f) {
+				continue
+			}
+			op, indir := encOpFor(f.Type, seen, building)
+			engine.instr = append(engine.instr, encInstr{*op, wireFieldNum, f.Index, indir})
+			wireFieldNum++
+		}
+		if srt.NumField() > 0 && len(engine.instr) == 0 {
+			errorf("type %s has no exported fields", rt)
+		}
+		engine.instr = append(engine.instr, encInstr{encStructTerminator, 0, nil, 0})
+	} else {
+		engine.instr = make([]encInstr, 1)
+		op, indir := encOpFor(rt, seen, building)
+		engine.instr[0] = encInstr{*op, singletonField, nil, indir}
+	}
+	return engine
+}
+
+// getEncEngine returns the engine to compile the type.
+func getEncEngine(ut *userTypeInfo, building map[*typeInfo]bool) *encEngine {
+	info, err := getTypeInfo(ut)
+	if err != nil {
+		error_(err)
+	}
+	enc, ok := info.encoder.Load().(*encEngine)
+	if !ok {
+		enc = buildEncEngine(info, ut, building)
+	}
+	return enc
+}
+
+func buildEncEngine(info *typeInfo, ut *userTypeInfo, building map[*typeInfo]bool) *encEngine {
+	// Check for recursive types.
+	if building != nil && building[info] {
+		return nil
+	}
+	info.encInit.Lock()
+	defer info.encInit.Unlock()
+	enc, ok := info.encoder.Load().(*encEngine)
+	if !ok {
+		if building == nil {
+			building = make(map[*typeInfo]bool)
+		}
+		building[info] = true
+		enc = compileEnc(ut, building)
+		info.encoder.Store(enc)
+	}
+	return enc
+}
+
+func (enc *Encoder) encode(b *encBuffer, value reflect.Value, ut *userTypeInfo) {
+	defer catchError(&enc.err)
+	engine := getEncEngine(ut, nil)
+	indir := ut.indir
+	if ut.externalEnc != 0 {
+		indir = int(ut.encIndir)
+	}
+	for i := 0; i < indir; i++ {
+		value = reflect.Indirect(value)
+	}
+	if ut.externalEnc == 0 && value.Type().Kind() == reflect.Struct {
+		enc.encodeStruct(b, engine, value)
+	} else {
+		enc.encodeSingle(b, engine, value)
+	}
+}
diff --git a/src/encoding/gob/encoder.go b/src/encoding/gob/encoder.go
new file mode 100644
index 0000000..a340e47
--- /dev/null
+++ b/src/encoding/gob/encoder.go
@@ -0,0 +1,248 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package gob
+
+import (
+	"io"
+	"reflect"
+	"sync"
+)
+
+// An Encoder manages the transmission of type and data information to the
+// other side of a connection.
+type Encoder struct {
+	mutex      sync.Mutex              // each item must be sent atomically
+	w          []io.Writer             // where to send the data
+	sent       map[reflect.Type]typeId // which types we've already sent
+	countState *encoderState           // stage for writing counts
+	freeList   *encoderState           // list of free encoderStates; avoids reallocation
+	byteBuf    encBuffer               // buffer for top-level encoderState
+	err        error
+}
+
+// Before we encode a message, we reserve space at the head of the
+// buffer in which to encode its length. This means we can use the
+// buffer to assemble the message without another allocation.
+const maxLength = 9 // Maximum size of an encoded length.
+var spaceForLength = make([]byte, maxLength)
+
+// NewEncoder returns a new encoder that will transmit on the io.Writer.
+func NewEncoder(w io.Writer) *Encoder {
+	enc := new(Encoder)
+	enc.w = []io.Writer{w}
+	enc.sent = make(map[reflect.Type]typeId)
+	enc.countState = enc.newEncoderState(new(encBuffer))
+	return enc
+}
+
+// writer() returns the innermost writer the encoder is using
+func (enc *Encoder) writer() io.Writer {
+	return enc.w[len(enc.w)-1]
+}
+
+// pushWriter adds a writer to the encoder.
+func (enc *Encoder) pushWriter(w io.Writer) {
+	enc.w = append(enc.w, w)
+}
+
+// popWriter pops the innermost writer.
+func (enc *Encoder) popWriter() {
+	enc.w = enc.w[0 : len(enc.w)-1]
+}
+
+func (enc *Encoder) setError(err error) {
+	if enc.err == nil { // remember the first.
+		enc.err = err
+	}
+}
+
+// writeMessage sends the data item preceded by a unsigned count of its length.
+func (enc *Encoder) writeMessage(w io.Writer, b *encBuffer) {
+	// Space has been reserved for the length at the head of the message.
+	// This is a little dirty: we grab the slice from the bytes.Buffer and massage
+	// it by hand.
+	message := b.Bytes()
+	messageLen := len(message) - maxLength
+	// Encode the length.
+	enc.countState.b.Reset()
+	enc.countState.encodeUint(uint64(messageLen))
+	// Copy the length to be a prefix of the message.
+	offset := maxLength - enc.countState.b.Len()
+	copy(message[offset:], enc.countState.b.Bytes())
+	// Write the data.
+	_, err := w.Write(message[offset:])
+	// Drain the buffer and restore the space at the front for the count of the next message.
+	b.Reset()
+	b.Write(spaceForLength)
+	if err != nil {
+		enc.setError(err)
+	}
+}
+
+// sendActualType sends the requested type, without further investigation, unless
+// it's been sent before.
+func (enc *Encoder) sendActualType(w io.Writer, state *encoderState, ut *userTypeInfo, actual reflect.Type) (sent bool) {
+	if _, alreadySent := enc.sent[actual]; alreadySent {
+		return false
+	}
+	info, err := getTypeInfo(ut)
+	if err != nil {
+		enc.setError(err)
+		return
+	}
+	// Send the pair (-id, type)
+	// Id:
+	state.encodeInt(-int64(info.id))
+	// Type:
+	enc.encode(state.b, reflect.ValueOf(info.wire), wireTypeUserInfo)
+	enc.writeMessage(w, state.b)
+	if enc.err != nil {
+		return
+	}
+
+	// Remember we've sent this type, both what the user gave us and the base type.
+	enc.sent[ut.base] = info.id
+	if ut.user != ut.base {
+		enc.sent[ut.user] = info.id
+	}
+	// Now send the inner types
+	switch st := actual; st.Kind() {
+	case reflect.Struct:
+		for i := 0; i < st.NumField(); i++ {
+			if isExported(st.Field(i).Name) {
+				enc.sendType(w, state, st.Field(i).Type)
+			}
+		}
+	case reflect.Array, reflect.Slice:
+		enc.sendType(w, state, st.Elem())
+	case reflect.Map:
+		enc.sendType(w, state, st.Key())
+		enc.sendType(w, state, st.Elem())
+	}
+	return true
+}
+
+// sendType sends the type info to the other side, if necessary.
+func (enc *Encoder) sendType(w io.Writer, state *encoderState, origt reflect.Type) (sent bool) {
+	ut := userType(origt)
+	if ut.externalEnc != 0 {
+		// The rules are different: regardless of the underlying type's representation,
+		// we need to tell the other side that the base type is a GobEncoder.
+		return enc.sendActualType(w, state, ut, ut.base)
+	}
+
+	// It's a concrete value, so drill down to the base type.
+	switch rt := ut.base; rt.Kind() {
+	default:
+		// Basic types and interfaces do not need to be described.
+		return
+	case reflect.Slice:
+		// If it's []uint8, don't send; it's considered basic.
+		if rt.Elem().Kind() == reflect.Uint8 {
+			return
+		}
+		// Otherwise we do send.
+		break
+	case reflect.Array:
+		// arrays must be sent so we know their lengths and element types.
+		break
+	case reflect.Map:
+		// maps must be sent so we know their lengths and key/value types.
+		break
+	case reflect.Struct:
+		// structs must be sent so we know their fields.
+		break
+	case reflect.Chan, reflect.Func:
+		// If we get here, it's a field of a struct; ignore it.
+		return
+	}
+
+	return enc.sendActualType(w, state, ut, ut.base)
+}
+
+// Encode transmits the data item represented by the empty interface value,
+// guaranteeing that all necessary type information has been transmitted first.
+func (enc *Encoder) Encode(e interface{}) error {
+	return enc.EncodeValue(reflect.ValueOf(e))
+}
+
+// sendTypeDescriptor makes sure the remote side knows about this type.
+// It will send a descriptor if this is the first time the type has been
+// sent.
+func (enc *Encoder) sendTypeDescriptor(w io.Writer, state *encoderState, ut *userTypeInfo) {
+	// Make sure the type is known to the other side.
+	// First, have we already sent this type?
+	rt := ut.base
+	if ut.externalEnc != 0 {
+		rt = ut.user
+	}
+	if _, alreadySent := enc.sent[rt]; !alreadySent {
+		// No, so send it.
+		sent := enc.sendType(w, state, rt)
+		if enc.err != nil {
+			return
+		}
+		// If the type info has still not been transmitted, it means we have
+		// a singleton basic type (int, []byte etc.) at top level.  We don't
+		// need to send the type info but we do need to update enc.sent.
+		if !sent {
+			info, err := getTypeInfo(ut)
+			if err != nil {
+				enc.setError(err)
+				return
+			}
+			enc.sent[rt] = info.id
+		}
+	}
+}
+
+// sendTypeId sends the id, which must have already been defined.
+func (enc *Encoder) sendTypeId(state *encoderState, ut *userTypeInfo) {
+	// Identify the type of this top-level value.
+	state.encodeInt(int64(enc.sent[ut.base]))
+}
+
+// EncodeValue transmits the data item represented by the reflection value,
+// guaranteeing that all necessary type information has been transmitted first.
+func (enc *Encoder) EncodeValue(value reflect.Value) error {
+	// Gobs contain values. They cannot represent nil pointers, which
+	// have no value to encode.
+	if value.Kind() == reflect.Ptr && value.IsNil() {
+		panic("gob: cannot encode nil pointer of type " + value.Type().String())
+	}
+
+	// Make sure we're single-threaded through here, so multiple
+	// goroutines can share an encoder.
+	enc.mutex.Lock()
+	defer enc.mutex.Unlock()
+
+	// Remove any nested writers remaining due to previous errors.
+	enc.w = enc.w[0:1]
+
+	ut, err := validUserType(value.Type())
+	if err != nil {
+		return err
+	}
+
+	enc.err = nil
+	enc.byteBuf.Reset()
+	enc.byteBuf.Write(spaceForLength)
+	state := enc.newEncoderState(&enc.byteBuf)
+
+	enc.sendTypeDescriptor(enc.writer(), state, ut)
+	enc.sendTypeId(state, ut)
+	if enc.err != nil {
+		return enc.err
+	}
+
+	// Encode the object.
+	enc.encode(state.b, value, ut)
+	if enc.err == nil {
+		enc.writeMessage(enc.writer(), state.b)
+	}
+
+	enc.freeEncoderState(state)
+	return enc.err
+}
diff --git a/src/encoding/gob/encoder_test.go b/src/encoding/gob/encoder_test.go
new file mode 100644
index 0000000..0ea4c0e
--- /dev/null
+++ b/src/encoding/gob/encoder_test.go
@@ -0,0 +1,956 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package gob
+
+import (
+	"bytes"
+	"fmt"
+	"io"
+	"reflect"
+	"strings"
+	"testing"
+)
+
+// Test basic operations in a safe manner.
+func TestBasicEncoderDecoder(t *testing.T) {
+	var values = []interface{}{
+		true,
+		int(123),
+		int8(123),
+		int16(-12345),
+		int32(123456),
+		int64(-1234567),
+		uint(123),
+		uint8(123),
+		uint16(12345),
+		uint32(123456),
+		uint64(1234567),
+		uintptr(12345678),
+		float32(1.2345),
+		float64(1.2345678),
+		complex64(1.2345 + 2.3456i),
+		complex128(1.2345678 + 2.3456789i),
+		[]byte("hello"),
+		string("hello"),
+	}
+	for _, value := range values {
+		b := new(bytes.Buffer)
+		enc := NewEncoder(b)
+		err := enc.Encode(value)
+		if err != nil {
+			t.Error("encoder fail:", err)
+		}
+		dec := NewDecoder(b)
+		result := reflect.New(reflect.TypeOf(value))
+		err = dec.Decode(result.Interface())
+		if err != nil {
+			t.Fatalf("error decoding %T: %v:", reflect.TypeOf(value), err)
+		}
+		if !reflect.DeepEqual(value, result.Elem().Interface()) {
+			t.Fatalf("%T: expected %v got %v", value, value, result.Elem().Interface())
+		}
+	}
+}
+
+type ET0 struct {
+	A int
+	B string
+}
+
+type ET2 struct {
+	X string
+}
+
+type ET1 struct {
+	A    int
+	Et2  *ET2
+	Next *ET1
+}
+
+// Like ET1 but with a different name for a field
+type ET3 struct {
+	A             int
+	Et2           *ET2
+	DifferentNext *ET1
+}
+
+// Like ET1 but with a different type for a field
+type ET4 struct {
+	A    int
+	Et2  float64
+	Next int
+}
+
+func TestEncoderDecoder(t *testing.T) {
+	b := new(bytes.Buffer)
+	enc := NewEncoder(b)
+	et0 := new(ET0)
+	et0.A = 7
+	et0.B = "gobs of fun"
+	err := enc.Encode(et0)
+	if err != nil {
+		t.Error("encoder fail:", err)
+	}
+	//fmt.Printf("% x %q\n", b, b)
+	//Debug(b)
+	dec := NewDecoder(b)
+	newEt0 := new(ET0)
+	err = dec.Decode(newEt0)
+	if err != nil {
+		t.Fatal("error decoding ET0:", err)
+	}
+
+	if !reflect.DeepEqual(et0, newEt0) {
+		t.Fatalf("invalid data for et0: expected %+v; got %+v", *et0, *newEt0)
+	}
+	if b.Len() != 0 {
+		t.Error("not at eof;", b.Len(), "bytes left")
+	}
+	//	t.FailNow()
+
+	b = new(bytes.Buffer)
+	enc = NewEncoder(b)
+	et1 := new(ET1)
+	et1.A = 7
+	et1.Et2 = new(ET2)
+	err = enc.Encode(et1)
+	if err != nil {
+		t.Error("encoder fail:", err)
+	}
+	dec = NewDecoder(b)
+	newEt1 := new(ET1)
+	err = dec.Decode(newEt1)
+	if err != nil {
+		t.Fatal("error decoding ET1:", err)
+	}
+
+	if !reflect.DeepEqual(et1, newEt1) {
+		t.Fatalf("invalid data for et1: expected %+v; got %+v", *et1, *newEt1)
+	}
+	if b.Len() != 0 {
+		t.Error("not at eof;", b.Len(), "bytes left")
+	}
+
+	enc.Encode(et1)
+	newEt1 = new(ET1)
+	err = dec.Decode(newEt1)
+	if err != nil {
+		t.Fatal("round 2: error decoding ET1:", err)
+	}
+	if !reflect.DeepEqual(et1, newEt1) {
+		t.Fatalf("round 2: invalid data for et1: expected %+v; got %+v", *et1, *newEt1)
+	}
+	if b.Len() != 0 {
+		t.Error("round 2: not at eof;", b.Len(), "bytes left")
+	}
+
+	// Now test with a running encoder/decoder pair that we recognize a type mismatch.
+	err = enc.Encode(et1)
+	if err != nil {
+		t.Error("round 3: encoder fail:", err)
+	}
+	newEt2 := new(ET2)
+	err = dec.Decode(newEt2)
+	if err == nil {
+		t.Fatal("round 3: expected `bad type' error decoding ET2")
+	}
+}
+
+// Run one value through the encoder/decoder, but use the wrong type.
+// Input is always an ET1; we compare it to whatever is under 'e'.
+func badTypeCheck(e interface{}, shouldFail bool, msg string, t *testing.T) {
+	b := new(bytes.Buffer)
+	enc := NewEncoder(b)
+	et1 := new(ET1)
+	et1.A = 7
+	et1.Et2 = new(ET2)
+	err := enc.Encode(et1)
+	if err != nil {
+		t.Error("encoder fail:", err)
+	}
+	dec := NewDecoder(b)
+	err = dec.Decode(e)
+	if shouldFail && err == nil {
+		t.Error("expected error for", msg)
+	}
+	if !shouldFail && err != nil {
+		t.Error("unexpected error for", msg, err)
+	}
+}
+
+// Test that we recognize a bad type the first time.
+func TestWrongTypeDecoder(t *testing.T) {
+	badTypeCheck(new(ET2), true, "no fields in common", t)
+	badTypeCheck(new(ET3), false, "different name of field", t)
+	badTypeCheck(new(ET4), true, "different type of field", t)
+}
+
+func corruptDataCheck(s string, err error, t *testing.T) {
+	b := bytes.NewBufferString(s)
+	dec := NewDecoder(b)
+	err1 := dec.Decode(new(ET2))
+	if err1 != err {
+		t.Errorf("from %q expected error %s; got %s", s, err, err1)
+	}
+}
+
+// Check that we survive bad data.
+func TestBadData(t *testing.T) {
+	corruptDataCheck("", io.EOF, t)
+	corruptDataCheck("\x7Fhi", io.ErrUnexpectedEOF, t)
+	corruptDataCheck("\x03now is the time for all good men", errBadType, t)
+	// issue 6323.
+	corruptDataCheck("\x04\x24foo", errRange, t)
+}
+
+// Types not supported at top level by the Encoder.
+var unsupportedValues = []interface{}{
+	make(chan int),
+	func(a int) bool { return true },
+}
+
+func TestUnsupported(t *testing.T) {
+	var b bytes.Buffer
+	enc := NewEncoder(&b)
+	for _, v := range unsupportedValues {
+		err := enc.Encode(v)
+		if err == nil {
+			t.Errorf("expected error for %T; got none", v)
+		}
+	}
+}
+
+func encAndDec(in, out interface{}) error {
+	b := new(bytes.Buffer)
+	enc := NewEncoder(b)
+	err := enc.Encode(in)
+	if err != nil {
+		return err
+	}
+	dec := NewDecoder(b)
+	err = dec.Decode(out)
+	if err != nil {
+		return err
+	}
+	return nil
+}
+
+func TestTypeToPtrType(t *testing.T) {
+	// Encode a T, decode a *T
+	type Type0 struct {
+		A int
+	}
+	t0 := Type0{7}
+	t0p := new(Type0)
+	if err := encAndDec(t0, t0p); err != nil {
+		t.Error(err)
+	}
+}
+
+func TestPtrTypeToType(t *testing.T) {
+	// Encode a *T, decode a T
+	type Type1 struct {
+		A uint
+	}
+	t1p := &Type1{17}
+	var t1 Type1
+	if err := encAndDec(t1, t1p); err != nil {
+		t.Error(err)
+	}
+}
+
+func TestTypeToPtrPtrPtrPtrType(t *testing.T) {
+	type Type2 struct {
+		A ****float64
+	}
+	t2 := Type2{}
+	t2.A = new(***float64)
+	*t2.A = new(**float64)
+	**t2.A = new(*float64)
+	***t2.A = new(float64)
+	****t2.A = 27.4
+	t2pppp := new(***Type2)
+	if err := encAndDec(t2, t2pppp); err != nil {
+		t.Fatal(err)
+	}
+	if ****(****t2pppp).A != ****t2.A {
+		t.Errorf("wrong value after decode: %g not %g", ****(****t2pppp).A, ****t2.A)
+	}
+}
+
+func TestSlice(t *testing.T) {
+	type Type3 struct {
+		A []string
+	}
+	t3p := &Type3{[]string{"hello", "world"}}
+	var t3 Type3
+	if err := encAndDec(t3, t3p); err != nil {
+		t.Error(err)
+	}
+}
+
+func TestValueError(t *testing.T) {
+	// Encode a *T, decode a T
+	type Type4 struct {
+		A int
+	}
+	t4p := &Type4{3}
+	var t4 Type4 // note: not a pointer.
+	if err := encAndDec(t4p, t4); err == nil || strings.Index(err.Error(), "pointer") < 0 {
+		t.Error("expected error about pointer; got", err)
+	}
+}
+
+func TestArray(t *testing.T) {
+	type Type5 struct {
+		A [3]string
+		B [3]byte
+	}
+	type Type6 struct {
+		A [2]string // can't hold t5.a
+	}
+	t5 := Type5{[3]string{"hello", ",", "world"}, [3]byte{1, 2, 3}}
+	var t5p Type5
+	if err := encAndDec(t5, &t5p); err != nil {
+		t.Error(err)
+	}
+	var t6 Type6
+	if err := encAndDec(t5, &t6); err == nil {
+		t.Error("should fail with mismatched array sizes")
+	}
+}
+
+func TestRecursiveMapType(t *testing.T) {
+	type recursiveMap map[string]recursiveMap
+	r1 := recursiveMap{"A": recursiveMap{"B": nil, "C": nil}, "D": nil}
+	r2 := make(recursiveMap)
+	if err := encAndDec(r1, &r2); err != nil {
+		t.Error(err)
+	}
+}
+
+func TestRecursiveSliceType(t *testing.T) {
+	type recursiveSlice []recursiveSlice
+	r1 := recursiveSlice{0: recursiveSlice{0: nil}, 1: nil}
+	r2 := make(recursiveSlice, 0)
+	if err := encAndDec(r1, &r2); err != nil {
+		t.Error(err)
+	}
+}
+
+// Regression test for bug: must send zero values inside arrays
+func TestDefaultsInArray(t *testing.T) {
+	type Type7 struct {
+		B []bool
+		I []int
+		S []string
+		F []float64
+	}
+	t7 := Type7{
+		[]bool{false, false, true},
+		[]int{0, 0, 1},
+		[]string{"hi", "", "there"},
+		[]float64{0, 0, 1},
+	}
+	var t7p Type7
+	if err := encAndDec(t7, &t7p); err != nil {
+		t.Error(err)
+	}
+}
+
+var testInt int
+var testFloat32 float32
+var testString string
+var testSlice []string
+var testMap map[string]int
+var testArray [7]int
+
+type SingleTest struct {
+	in  interface{}
+	out interface{}
+	err string
+}
+
+var singleTests = []SingleTest{
+	{17, &testInt, ""},
+	{float32(17.5), &testFloat32, ""},
+	{"bike shed", &testString, ""},
+	{[]string{"bike", "shed", "paint", "color"}, &testSlice, ""},
+	{map[string]int{"seven": 7, "twelve": 12}, &testMap, ""},
+	{[7]int{4, 55, 0, 0, 0, 0, 0}, &testArray, ""}, // case that once triggered a bug
+	{[7]int{4, 55, 1, 44, 22, 66, 1234}, &testArray, ""},
+
+	// Decode errors
+	{172, &testFloat32, "type"},
+}
+
+func TestSingletons(t *testing.T) {
+	b := new(bytes.Buffer)
+	enc := NewEncoder(b)
+	dec := NewDecoder(b)
+	for _, test := range singleTests {
+		b.Reset()
+		err := enc.Encode(test.in)
+		if err != nil {
+			t.Errorf("error encoding %v: %s", test.in, err)
+			continue
+		}
+		err = dec.Decode(test.out)
+		switch {
+		case err != nil && test.err == "":
+			t.Errorf("error decoding %v: %s", test.in, err)
+			continue
+		case err == nil && test.err != "":
+			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 {
+				t.Errorf("wrong error decoding %v: wanted %s, got %v", test.in, test.err, err)
+			}
+			continue
+		}
+		// Get rid of the pointer in the rhs
+		val := reflect.ValueOf(test.out).Elem().Interface()
+		if !reflect.DeepEqual(test.in, val) {
+			t.Errorf("decoding singleton: expected %v got %v", test.in, val)
+		}
+	}
+}
+
+func TestStructNonStruct(t *testing.T) {
+	type Struct struct {
+		A string
+	}
+	type NonStruct string
+	s := Struct{"hello"}
+	var sp Struct
+	if err := encAndDec(s, &sp); err != nil {
+		t.Error(err)
+	}
+	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 {
+		t.Error("for struct/non-struct expected type error; got", err)
+	}
+	// Now try the other way
+	var nsp NonStruct
+	if err := encAndDec(ns, &nsp); err != nil {
+		t.Error(err)
+	}
+	if err := encAndDec(ns, &s); err == nil {
+		t.Error("should get error for non-struct/struct")
+	} else if strings.Index(err.Error(), "type") < 0 {
+		t.Error("for non-struct/struct expected type error; got", err)
+	}
+}
+
+type interfaceIndirectTestI interface {
+	F() bool
+}
+
+type interfaceIndirectTestT struct{}
+
+func (this *interfaceIndirectTestT) F() bool {
+	return true
+}
+
+// A version of a bug reported on golang-nuts.  Also tests top-level
+// slice of interfaces.  The issue was registering *T caused T to be
+// stored as the concrete type.
+func TestInterfaceIndirect(t *testing.T) {
+	Register(&interfaceIndirectTestT{})
+	b := new(bytes.Buffer)
+	w := []interfaceIndirectTestI{&interfaceIndirectTestT{}}
+	err := NewEncoder(b).Encode(w)
+	if err != nil {
+		t.Fatal("encode error:", err)
+	}
+
+	var r []interfaceIndirectTestI
+	err = NewDecoder(b).Decode(&r)
+	if err != nil {
+		t.Fatal("decode error:", err)
+	}
+}
+
+// Now follow various tests that decode into things that can't represent the
+// encoded value, all of which should be legal.
+
+// Also, when the ignored object contains an interface value, it may define
+// types. Make sure that skipping the value still defines the types by using
+// the encoder/decoder pair to send a value afterwards.  If an interface
+// is sent, its type in the test is always NewType0, so this checks that the
+// encoder and decoder don't skew with respect to type definitions.
+
+type Struct0 struct {
+	I interface{}
+}
+
+type NewType0 struct {
+	S string
+}
+
+type ignoreTest struct {
+	in, out interface{}
+}
+
+var ignoreTests = []ignoreTest{
+	// Decode normal struct into an empty struct
+	{&struct{ A int }{23}, &struct{}{}},
+	// Decode normal struct into a nil.
+	{&struct{ A int }{23}, nil},
+	// Decode singleton string into a nil.
+	{"hello, world", nil},
+	// Decode singleton slice into a nil.
+	{[]int{1, 2, 3, 4}, nil},
+	// Decode struct containing an interface into a nil.
+	{&Struct0{&NewType0{"value0"}}, nil},
+	// Decode singleton slice of interfaces into a nil.
+	{[]interface{}{"hi", &NewType0{"value1"}, 23}, nil},
+}
+
+func TestDecodeIntoNothing(t *testing.T) {
+	Register(new(NewType0))
+	for i, test := range ignoreTests {
+		b := new(bytes.Buffer)
+		enc := NewEncoder(b)
+		err := enc.Encode(test.in)
+		if err != nil {
+			t.Errorf("%d: encode error %s:", i, err)
+			continue
+		}
+		dec := NewDecoder(b)
+		err = dec.Decode(test.out)
+		if err != nil {
+			t.Errorf("%d: decode error: %s", i, err)
+			continue
+		}
+		// Now see if the encoder and decoder are in a consistent state.
+		str := fmt.Sprintf("Value %d", i)
+		err = enc.Encode(&NewType0{str})
+		if err != nil {
+			t.Fatalf("%d: NewType0 encode error: %s", i, err)
+		}
+		ns := new(NewType0)
+		err = dec.Decode(ns)
+		if err != nil {
+			t.Fatalf("%d: NewType0 decode error: %s", i, err)
+		}
+		if ns.S != str {
+			t.Fatalf("%d: expected %q got %q", i, str, ns.S)
+		}
+	}
+}
+
+// Another bug from golang-nuts, involving nested interfaces.
+type Bug0Outer struct {
+	Bug0Field interface{}
+}
+
+type Bug0Inner struct {
+	A int
+}
+
+func TestNestedInterfaces(t *testing.T) {
+	var buf bytes.Buffer
+	e := NewEncoder(&buf)
+	d := NewDecoder(&buf)
+	Register(new(Bug0Outer))
+	Register(new(Bug0Inner))
+	f := &Bug0Outer{&Bug0Outer{&Bug0Inner{7}}}
+	var v interface{} = f
+	err := e.Encode(&v)
+	if err != nil {
+		t.Fatal("Encode:", err)
+	}
+	err = d.Decode(&v)
+	if err != nil {
+		t.Fatal("Decode:", err)
+	}
+	// Make sure it decoded correctly.
+	outer1, ok := v.(*Bug0Outer)
+	if !ok {
+		t.Fatalf("v not Bug0Outer: %T", v)
+	}
+	outer2, ok := outer1.Bug0Field.(*Bug0Outer)
+	if !ok {
+		t.Fatalf("v.Bug0Field not Bug0Outer: %T", outer1.Bug0Field)
+	}
+	inner, ok := outer2.Bug0Field.(*Bug0Inner)
+	if !ok {
+		t.Fatalf("v.Bug0Field.Bug0Field not Bug0Inner: %T", outer2.Bug0Field)
+	}
+	if inner.A != 7 {
+		t.Fatalf("final value %d; expected %d", inner.A, 7)
+	}
+}
+
+// The bugs keep coming. We forgot to send map subtypes before the map.
+
+type Bug1Elem struct {
+	Name string
+	Id   int
+}
+
+type Bug1StructMap map[string]Bug1Elem
+
+func bug1EncDec(in Bug1StructMap, out *Bug1StructMap) error {
+	return nil
+}
+
+func TestMapBug1(t *testing.T) {
+	in := make(Bug1StructMap)
+	in["val1"] = Bug1Elem{"elem1", 1}
+	in["val2"] = Bug1Elem{"elem2", 2}
+
+	b := new(bytes.Buffer)
+	enc := NewEncoder(b)
+	err := enc.Encode(in)
+	if err != nil {
+		t.Fatal("encode:", err)
+	}
+	dec := NewDecoder(b)
+	out := make(Bug1StructMap)
+	err = dec.Decode(&out)
+	if err != nil {
+		t.Fatal("decode:", err)
+	}
+	if !reflect.DeepEqual(in, out) {
+		t.Errorf("mismatch: %v %v", in, out)
+	}
+}
+
+func TestGobMapInterfaceEncode(t *testing.T) {
+	m := map[string]interface{}{
+		"up": uintptr(0),
+		"i0": []int{-1},
+		"i1": []int8{-1},
+		"i2": []int16{-1},
+		"i3": []int32{-1},
+		"i4": []int64{-1},
+		"u0": []uint{1},
+		"u1": []uint8{1},
+		"u2": []uint16{1},
+		"u3": []uint32{1},
+		"u4": []uint64{1},
+		"f0": []float32{1},
+		"f1": []float64{1},
+		"c0": []complex64{complex(2, -2)},
+		"c1": []complex128{complex(2, float64(-2))},
+		"us": []uintptr{0},
+		"bo": []bool{false},
+		"st": []string{"s"},
+	}
+	enc := NewEncoder(new(bytes.Buffer))
+	err := enc.Encode(m)
+	if err != nil {
+		t.Errorf("encode map: %s", err)
+	}
+}
+
+func TestSliceReusesMemory(t *testing.T) {
+	buf := new(bytes.Buffer)
+	// Bytes
+	{
+		x := []byte("abcd")
+		enc := NewEncoder(buf)
+		err := enc.Encode(x)
+		if err != nil {
+			t.Errorf("bytes: encode: %s", err)
+		}
+		// Decode into y, which is big enough.
+		y := []byte("ABCDE")
+		addr := &y[0]
+		dec := NewDecoder(buf)
+		err = dec.Decode(&y)
+		if err != nil {
+			t.Fatal("bytes: decode:", err)
+		}
+		if !bytes.Equal(x, y) {
+			t.Errorf("bytes: expected %q got %q\n", x, y)
+		}
+		if addr != &y[0] {
+			t.Errorf("bytes: unnecessary reallocation")
+		}
+	}
+	// general slice
+	{
+		x := []rune("abcd")
+		enc := NewEncoder(buf)
+		err := enc.Encode(x)
+		if err != nil {
+			t.Errorf("ints: encode: %s", err)
+		}
+		// Decode into y, which is big enough.
+		y := []rune("ABCDE")
+		addr := &y[0]
+		dec := NewDecoder(buf)
+		err = dec.Decode(&y)
+		if err != nil {
+			t.Fatal("ints: decode:", err)
+		}
+		if !reflect.DeepEqual(x, y) {
+			t.Errorf("ints: expected %q got %q\n", x, y)
+		}
+		if addr != &y[0] {
+			t.Errorf("ints: unnecessary reallocation")
+		}
+	}
+}
+
+// Used to crash: negative count in recvMessage.
+func TestBadCount(t *testing.T) {
+	b := []byte{0xfb, 0xa5, 0x82, 0x2f, 0xca, 0x1}
+	if err := NewDecoder(bytes.NewReader(b)).Decode(nil); err == nil {
+		t.Error("expected error from bad count")
+	} else if err.Error() != errBadCount.Error() {
+		t.Error("expected bad count error; got", err)
+	}
+}
+
+// Verify that sequential Decoders built on a single input will
+// succeed if the input implements ReadByte and there is no
+// type information in the stream.
+func TestSequentialDecoder(t *testing.T) {
+	b := new(bytes.Buffer)
+	enc := NewEncoder(b)
+	const count = 10
+	for i := 0; i < count; i++ {
+		s := fmt.Sprintf("%d", i)
+		if err := enc.Encode(s); err != nil {
+			t.Error("encoder fail:", err)
+		}
+	}
+	for i := 0; i < count; i++ {
+		dec := NewDecoder(b)
+		var s string
+		if err := dec.Decode(&s); err != nil {
+			t.Fatal("decoder fail:", err)
+		}
+		if s != fmt.Sprintf("%d", i) {
+			t.Fatalf("decode expected %d got %s", i, s)
+		}
+	}
+}
+
+// Should be able to have unrepresentable fields (chan, func, *chan etc.); we just ignore them.
+type Bug2 struct {
+	A   int
+	C   chan int
+	CP  *chan int
+	F   func()
+	FPP **func()
+}
+
+func TestChanFuncIgnored(t *testing.T) {
+	c := make(chan int)
+	f := func() {}
+	fp := &f
+	b0 := Bug2{23, c, &c, f, &fp}
+	var buf bytes.Buffer
+	enc := NewEncoder(&buf)
+	if err := enc.Encode(b0); err != nil {
+		t.Fatal("error encoding:", err)
+	}
+	var b1 Bug2
+	err := NewDecoder(&buf).Decode(&b1)
+	if err != nil {
+		t.Fatal("decode:", err)
+	}
+	if b1.A != b0.A {
+		t.Fatalf("got %d want %d", b1.A, b0.A)
+	}
+	if b1.C != nil || b1.CP != nil || b1.F != nil || b1.FPP != nil {
+		t.Fatal("unexpected value for chan or func")
+	}
+}
+
+func TestSliceIncompatibility(t *testing.T) {
+	var in = []byte{1, 2, 3}
+	var out []int
+	if err := encAndDec(in, &out); err == nil {
+		t.Error("expected compatibility error")
+	}
+}
+
+// Mutually recursive slices of structs caused problems.
+type Bug3 struct {
+	Num      int
+	Children []*Bug3
+}
+
+func TestGobPtrSlices(t *testing.T) {
+	in := []*Bug3{
+		{1, nil},
+		{2, nil},
+	}
+	b := new(bytes.Buffer)
+	err := NewEncoder(b).Encode(&in)
+	if err != nil {
+		t.Fatal("encode:", err)
+	}
+
+	var out []*Bug3
+	err = NewDecoder(b).Decode(&out)
+	if err != nil {
+		t.Fatal("decode:", err)
+	}
+	if !reflect.DeepEqual(in, out) {
+		t.Fatalf("got %v; wanted %v", out, in)
+	}
+}
+
+// getDecEnginePtr cached engine for ut.base instead of ut.user so we passed
+// a *map and then tried to reuse its engine to decode the inner map.
+func TestPtrToMapOfMap(t *testing.T) {
+	Register(make(map[string]interface{}))
+	subdata := make(map[string]interface{})
+	subdata["bar"] = "baz"
+	data := make(map[string]interface{})
+	data["foo"] = subdata
+
+	b := new(bytes.Buffer)
+	err := NewEncoder(b).Encode(data)
+	if err != nil {
+		t.Fatal("encode:", err)
+	}
+	var newData map[string]interface{}
+	err = NewDecoder(b).Decode(&newData)
+	if err != nil {
+		t.Fatal("decode:", err)
+	}
+	if !reflect.DeepEqual(data, newData) {
+		t.Fatalf("expected %v got %v", data, newData)
+	}
+}
+
+// A top-level nil pointer generates a panic with a helpful string-valued message.
+func TestTopLevelNilPointer(t *testing.T) {
+	errMsg := topLevelNilPanic(t)
+	if errMsg == "" {
+		t.Fatal("top-level nil pointer did not panic")
+	}
+	if !strings.Contains(errMsg, "nil pointer") {
+		t.Fatal("expected nil pointer error, got:", errMsg)
+	}
+}
+
+func topLevelNilPanic(t *testing.T) (panicErr string) {
+	defer func() {
+		e := recover()
+		if err, ok := e.(string); ok {
+			panicErr = err
+		}
+	}()
+	var ip *int
+	buf := new(bytes.Buffer)
+	if err := NewEncoder(buf).Encode(ip); err != nil {
+		t.Fatal("error in encode:", err)
+	}
+	return
+}
+
+func TestNilPointerInsideInterface(t *testing.T) {
+	var ip *int
+	si := struct {
+		I interface{}
+	}{
+		I: ip,
+	}
+	buf := new(bytes.Buffer)
+	err := NewEncoder(buf).Encode(si)
+	if err == nil {
+		t.Fatal("expected error, got none")
+	}
+	errMsg := err.Error()
+	if !strings.Contains(errMsg, "nil pointer") || !strings.Contains(errMsg, "interface") {
+		t.Fatal("expected error about nil pointer and interface, got:", errMsg)
+	}
+}
+
+type Bug4Public struct {
+	Name   string
+	Secret Bug4Secret
+}
+
+type Bug4Secret struct {
+	a int // error: no exported fields.
+}
+
+// Test that a failed compilation doesn't leave around an executable encoder.
+// Issue 3273.
+func TestMutipleEncodingsOfBadType(t *testing.T) {
+	x := Bug4Public{
+		Name:   "name",
+		Secret: Bug4Secret{1},
+	}
+	buf := new(bytes.Buffer)
+	enc := NewEncoder(buf)
+	err := enc.Encode(x)
+	if err == nil {
+		t.Fatal("first encoding: expected error")
+	}
+	buf.Reset()
+	enc = NewEncoder(buf)
+	err = enc.Encode(x)
+	if err == nil {
+		t.Fatal("second encoding: expected error")
+	}
+	if !strings.Contains(err.Error(), "no exported fields") {
+		t.Errorf("expected error about no exported fields; got %v", err)
+	}
+}
+
+// There was an error check comparing the length of the input with the
+// length of the slice being decoded. It was wrong because the next
+// thing in the input might be a type definition, which would lead to
+// an incorrect length check.  This test reproduces the corner case.
+
+type Z struct {
+}
+
+func Test29ElementSlice(t *testing.T) {
+	Register(Z{})
+	src := make([]interface{}, 100) // Size needs to be bigger than size of type definition.
+	for i := range src {
+		src[i] = Z{}
+	}
+	buf := new(bytes.Buffer)
+	err := NewEncoder(buf).Encode(src)
+	if err != nil {
+		t.Fatalf("encode: %v", err)
+		return
+	}
+
+	var dst []interface{}
+	err = NewDecoder(buf).Decode(&dst)
+	if err != nil {
+		t.Errorf("decode: %v", err)
+		return
+	}
+}
+
+// Don't crash, just give error when allocating a huge slice.
+// Issue 8084.
+func TestErrorForHugeSlice(t *testing.T) {
+	// Encode an int slice.
+	buf := new(bytes.Buffer)
+	slice := []int{1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
+	err := NewEncoder(buf).Encode(slice)
+	if err != nil {
+		t.Fatal("encode:", err)
+	}
+	// Reach into the buffer and smash the count to make the encoded slice very long.
+	buf.Bytes()[buf.Len()-len(slice)-1] = 0xfa
+	// Decode and see error.
+	err = NewDecoder(buf).Decode(&slice)
+	if err == nil {
+		t.Fatal("decode: no error")
+	}
+	if !strings.Contains(err.Error(), "slice too big") {
+		t.Fatal("decode: expected slice too big error, got %s", err.Error())
+	}
+}
diff --git a/src/pkg/encoding/gob/error.go b/src/encoding/gob/error.go
similarity index 100%
rename from src/pkg/encoding/gob/error.go
rename to src/encoding/gob/error.go
diff --git a/src/pkg/encoding/gob/example_encdec_test.go b/src/encoding/gob/example_encdec_test.go
similarity index 100%
rename from src/pkg/encoding/gob/example_encdec_test.go
rename to src/encoding/gob/example_encdec_test.go
diff --git a/src/pkg/encoding/gob/example_interface_test.go b/src/encoding/gob/example_interface_test.go
similarity index 100%
rename from src/pkg/encoding/gob/example_interface_test.go
rename to src/encoding/gob/example_interface_test.go
diff --git a/src/pkg/encoding/gob/example_test.go b/src/encoding/gob/example_test.go
similarity index 100%
rename from src/pkg/encoding/gob/example_test.go
rename to src/encoding/gob/example_test.go
diff --git a/src/encoding/gob/gobencdec_test.go b/src/encoding/gob/gobencdec_test.go
new file mode 100644
index 0000000..eb76b48
--- /dev/null
+++ b/src/encoding/gob/gobencdec_test.go
@@ -0,0 +1,798 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file contains tests of the GobEncoder/GobDecoder support.
+
+package gob
+
+import (
+	"bytes"
+	"errors"
+	"fmt"
+	"io"
+	"net"
+	"strings"
+	"testing"
+	"time"
+)
+
+// Types that implement the GobEncoder/Decoder interfaces.
+
+type ByteStruct struct {
+	a byte // not an exported field
+}
+
+type StringStruct struct {
+	s string // not an exported field
+}
+
+type ArrayStruct struct {
+	a [8192]byte // not an exported field
+}
+
+type Gobber int
+
+type ValueGobber string // encodes with a value, decodes with a pointer.
+
+type BinaryGobber int
+
+type BinaryValueGobber string
+
+type TextGobber int
+
+type TextValueGobber string
+
+// The relevant methods
+
+func (g *ByteStruct) GobEncode() ([]byte, error) {
+	b := make([]byte, 3)
+	b[0] = g.a
+	b[1] = g.a + 1
+	b[2] = g.a + 2
+	return b, nil
+}
+
+func (g *ByteStruct) GobDecode(data []byte) error {
+	if g == nil {
+		return errors.New("NIL RECEIVER")
+	}
+	// Expect N sequential-valued bytes.
+	if len(data) == 0 {
+		return io.EOF
+	}
+	g.a = data[0]
+	for i, c := range data {
+		if c != g.a+byte(i) {
+			return errors.New("invalid data sequence")
+		}
+	}
+	return nil
+}
+
+func (g *StringStruct) GobEncode() ([]byte, error) {
+	return []byte(g.s), nil
+}
+
+func (g *StringStruct) GobDecode(data []byte) error {
+	// Expect N sequential-valued bytes.
+	if len(data) == 0 {
+		return io.EOF
+	}
+	a := data[0]
+	for i, c := range data {
+		if c != a+byte(i) {
+			return errors.New("invalid data sequence")
+		}
+	}
+	g.s = string(data)
+	return nil
+}
+
+func (a *ArrayStruct) GobEncode() ([]byte, error) {
+	return a.a[:], nil
+}
+
+func (a *ArrayStruct) GobDecode(data []byte) error {
+	if len(data) != len(a.a) {
+		return errors.New("wrong length in array decode")
+	}
+	copy(a.a[:], data)
+	return nil
+}
+
+func (g *Gobber) GobEncode() ([]byte, error) {
+	return []byte(fmt.Sprintf("VALUE=%d", *g)), nil
+}
+
+func (g *Gobber) GobDecode(data []byte) error {
+	_, err := fmt.Sscanf(string(data), "VALUE=%d", (*int)(g))
+	return err
+}
+
+func (g *BinaryGobber) MarshalBinary() ([]byte, error) {
+	return []byte(fmt.Sprintf("VALUE=%d", *g)), nil
+}
+
+func (g *BinaryGobber) UnmarshalBinary(data []byte) error {
+	_, err := fmt.Sscanf(string(data), "VALUE=%d", (*int)(g))
+	return err
+}
+
+func (g *TextGobber) MarshalText() ([]byte, error) {
+	return []byte(fmt.Sprintf("VALUE=%d", *g)), nil
+}
+
+func (g *TextGobber) UnmarshalText(data []byte) error {
+	_, err := fmt.Sscanf(string(data), "VALUE=%d", (*int)(g))
+	return err
+}
+
+func (v ValueGobber) GobEncode() ([]byte, error) {
+	return []byte(fmt.Sprintf("VALUE=%s", v)), nil
+}
+
+func (v *ValueGobber) GobDecode(data []byte) error {
+	_, err := fmt.Sscanf(string(data), "VALUE=%s", (*string)(v))
+	return err
+}
+
+func (v BinaryValueGobber) MarshalBinary() ([]byte, error) {
+	return []byte(fmt.Sprintf("VALUE=%s", v)), nil
+}
+
+func (v *BinaryValueGobber) UnmarshalBinary(data []byte) error {
+	_, err := fmt.Sscanf(string(data), "VALUE=%s", (*string)(v))
+	return err
+}
+
+func (v TextValueGobber) MarshalText() ([]byte, error) {
+	return []byte(fmt.Sprintf("VALUE=%s", v)), nil
+}
+
+func (v *TextValueGobber) UnmarshalText(data []byte) error {
+	_, err := fmt.Sscanf(string(data), "VALUE=%s", (*string)(v))
+	return err
+}
+
+// Structs that include GobEncodable fields.
+
+type GobTest0 struct {
+	X int // guarantee we have  something in common with GobTest*
+	G *ByteStruct
+}
+
+type GobTest1 struct {
+	X int // guarantee we have  something in common with GobTest*
+	G *StringStruct
+}
+
+type GobTest2 struct {
+	X int    // guarantee we have  something in common with GobTest*
+	G string // not a GobEncoder - should give us errors
+}
+
+type GobTest3 struct {
+	X int // guarantee we have  something in common with GobTest*
+	G *Gobber
+	B *BinaryGobber
+	T *TextGobber
+}
+
+type GobTest4 struct {
+	X  int // guarantee we have  something in common with GobTest*
+	V  ValueGobber
+	BV BinaryValueGobber
+	TV TextValueGobber
+}
+
+type GobTest5 struct {
+	X  int // guarantee we have  something in common with GobTest*
+	V  *ValueGobber
+	BV *BinaryValueGobber
+	TV *TextValueGobber
+}
+
+type GobTest6 struct {
+	X  int // guarantee we have  something in common with GobTest*
+	V  ValueGobber
+	W  *ValueGobber
+	BV BinaryValueGobber
+	BW *BinaryValueGobber
+	TV TextValueGobber
+	TW *TextValueGobber
+}
+
+type GobTest7 struct {
+	X  int // guarantee we have  something in common with GobTest*
+	V  *ValueGobber
+	W  ValueGobber
+	BV *BinaryValueGobber
+	BW BinaryValueGobber
+	TV *TextValueGobber
+	TW TextValueGobber
+}
+
+type GobTestIgnoreEncoder struct {
+	X int // guarantee we have  something in common with GobTest*
+}
+
+type GobTestValueEncDec struct {
+	X int          // guarantee we have  something in common with GobTest*
+	G StringStruct // not a pointer.
+}
+
+type GobTestIndirectEncDec struct {
+	X int             // guarantee we have  something in common with GobTest*
+	G ***StringStruct // indirections to the receiver.
+}
+
+type GobTestArrayEncDec struct {
+	X int         // guarantee we have  something in common with GobTest*
+	A ArrayStruct // not a pointer.
+}
+
+type GobTestIndirectArrayEncDec struct {
+	X int            // guarantee we have  something in common with GobTest*
+	A ***ArrayStruct // indirections to a large receiver.
+}
+
+func TestGobEncoderField(t *testing.T) {
+	b := new(bytes.Buffer)
+	// First a field that's a structure.
+	enc := NewEncoder(b)
+	err := enc.Encode(GobTest0{17, &ByteStruct{'A'}})
+	if err != nil {
+		t.Fatal("encode error:", err)
+	}
+	dec := NewDecoder(b)
+	x := new(GobTest0)
+	err = dec.Decode(x)
+	if err != nil {
+		t.Fatal("decode error:", err)
+	}
+	if x.G.a != 'A' {
+		t.Errorf("expected 'A' got %c", x.G.a)
+	}
+	// Now a field that's not a structure.
+	b.Reset()
+	gobber := Gobber(23)
+	bgobber := BinaryGobber(24)
+	tgobber := TextGobber(25)
+	err = enc.Encode(GobTest3{17, &gobber, &bgobber, &tgobber})
+	if err != nil {
+		t.Fatal("encode error:", err)
+	}
+	y := new(GobTest3)
+	err = dec.Decode(y)
+	if err != nil {
+		t.Fatal("decode error:", err)
+	}
+	if *y.G != 23 || *y.B != 24 || *y.T != 25 {
+		t.Errorf("expected '23 got %d", *y.G)
+	}
+}
+
+// Even though the field is a value, we can still take its address
+// and should be able to call the methods.
+func TestGobEncoderValueField(t *testing.T) {
+	b := new(bytes.Buffer)
+	// First a field that's a structure.
+	enc := NewEncoder(b)
+	err := enc.Encode(&GobTestValueEncDec{17, StringStruct{"HIJKL"}})
+	if err != nil {
+		t.Fatal("encode error:", err)
+	}
+	dec := NewDecoder(b)
+	x := new(GobTestValueEncDec)
+	err = dec.Decode(x)
+	if err != nil {
+		t.Fatal("decode error:", err)
+	}
+	if x.G.s != "HIJKL" {
+		t.Errorf("expected `HIJKL` got %s", x.G.s)
+	}
+}
+
+// GobEncode/Decode should work even if the value is
+// more indirect than the receiver.
+func TestGobEncoderIndirectField(t *testing.T) {
+	b := new(bytes.Buffer)
+	// First a field that's a structure.
+	enc := NewEncoder(b)
+	s := &StringStruct{"HIJKL"}
+	sp := &s
+	err := enc.Encode(GobTestIndirectEncDec{17, &sp})
+	if err != nil {
+		t.Fatal("encode error:", err)
+	}
+	dec := NewDecoder(b)
+	x := new(GobTestIndirectEncDec)
+	err = dec.Decode(x)
+	if err != nil {
+		t.Fatal("decode error:", err)
+	}
+	if (***x.G).s != "HIJKL" {
+		t.Errorf("expected `HIJKL` got %s", (***x.G).s)
+	}
+}
+
+// Test with a large field with methods.
+func TestGobEncoderArrayField(t *testing.T) {
+	b := new(bytes.Buffer)
+	enc := NewEncoder(b)
+	var a GobTestArrayEncDec
+	a.X = 17
+	for i := range a.A.a {
+		a.A.a[i] = byte(i)
+	}
+	err := enc.Encode(&a)
+	if err != nil {
+		t.Fatal("encode error:", err)
+	}
+	dec := NewDecoder(b)
+	x := new(GobTestArrayEncDec)
+	err = dec.Decode(x)
+	if err != nil {
+		t.Fatal("decode error:", err)
+	}
+	for i, v := range x.A.a {
+		if v != byte(i) {
+			t.Errorf("expected %x got %x", byte(i), v)
+			break
+		}
+	}
+}
+
+// Test an indirection to a large field with methods.
+func TestGobEncoderIndirectArrayField(t *testing.T) {
+	b := new(bytes.Buffer)
+	enc := NewEncoder(b)
+	var a GobTestIndirectArrayEncDec
+	a.X = 17
+	var array ArrayStruct
+	ap := &array
+	app := &ap
+	a.A = &app
+	for i := range array.a {
+		array.a[i] = byte(i)
+	}
+	err := enc.Encode(a)
+	if err != nil {
+		t.Fatal("encode error:", err)
+	}
+	dec := NewDecoder(b)
+	x := new(GobTestIndirectArrayEncDec)
+	err = dec.Decode(x)
+	if err != nil {
+		t.Fatal("decode error:", err)
+	}
+	for i, v := range (***x.A).a {
+		if v != byte(i) {
+			t.Errorf("expected %x got %x", byte(i), v)
+			break
+		}
+	}
+}
+
+// As long as the fields have the same name and implement the
+// interface, we can cross-connect them.  Not sure it's useful
+// and may even be bad but it works and it's hard to prevent
+// without exposing the contents of the object, which would
+// defeat the purpose.
+func TestGobEncoderFieldsOfDifferentType(t *testing.T) {
+	// first, string in field to byte in field
+	b := new(bytes.Buffer)
+	enc := NewEncoder(b)
+	err := enc.Encode(GobTest1{17, &StringStruct{"ABC"}})
+	if err != nil {
+		t.Fatal("encode error:", err)
+	}
+	dec := NewDecoder(b)
+	x := new(GobTest0)
+	err = dec.Decode(x)
+	if err != nil {
+		t.Fatal("decode error:", err)
+	}
+	if x.G.a != 'A' {
+		t.Errorf("expected 'A' got %c", x.G.a)
+	}
+	// now the other direction, byte in field to string in field
+	b.Reset()
+	err = enc.Encode(GobTest0{17, &ByteStruct{'X'}})
+	if err != nil {
+		t.Fatal("encode error:", err)
+	}
+	y := new(GobTest1)
+	err = dec.Decode(y)
+	if err != nil {
+		t.Fatal("decode error:", err)
+	}
+	if y.G.s != "XYZ" {
+		t.Fatalf("expected `XYZ` got %q", y.G.s)
+	}
+}
+
+// Test that we can encode a value and decode into a pointer.
+func TestGobEncoderValueEncoder(t *testing.T) {
+	// first, string in field to byte in field
+	b := new(bytes.Buffer)
+	enc := NewEncoder(b)
+	err := enc.Encode(GobTest4{17, ValueGobber("hello"), BinaryValueGobber("Καλημέρα"), TextValueGobber("こんにちは")})
+	if err != nil {
+		t.Fatal("encode error:", err)
+	}
+	dec := NewDecoder(b)
+	x := new(GobTest5)
+	err = dec.Decode(x)
+	if err != nil {
+		t.Fatal("decode error:", err)
+	}
+	if *x.V != "hello" || *x.BV != "Καλημέρα" || *x.TV != "こんにちは" {
+		t.Errorf("expected `hello` got %s", *x.V)
+	}
+}
+
+// Test that we can use a value then a pointer type of a GobEncoder
+// in the same encoded value.  Bug 4647.
+func TestGobEncoderValueThenPointer(t *testing.T) {
+	v := ValueGobber("forty-two")
+	w := ValueGobber("six-by-nine")
+	bv := BinaryValueGobber("1nanocentury")
+	bw := BinaryValueGobber("πseconds")
+	tv := TextValueGobber("gravitationalacceleration")
+	tw := TextValueGobber("π²ft/s²")
+
+	// this was a bug: encoding a GobEncoder by value before a GobEncoder
+	// pointer would cause duplicate type definitions to be sent.
+
+	b := new(bytes.Buffer)
+	enc := NewEncoder(b)
+	if err := enc.Encode(GobTest6{42, v, &w, bv, &bw, tv, &tw}); err != nil {
+		t.Fatal("encode error:", err)
+	}
+	dec := NewDecoder(b)
+	x := new(GobTest6)
+	if err := dec.Decode(x); err != nil {
+		t.Fatal("decode error:", err)
+	}
+
+	if got, want := x.V, v; got != want {
+		t.Errorf("v = %q, want %q", got, want)
+	}
+	if got, want := x.W, w; got == nil {
+		t.Errorf("w = nil, want %q", want)
+	} else if *got != want {
+		t.Errorf("w = %q, want %q", *got, want)
+	}
+
+	if got, want := x.BV, bv; got != want {
+		t.Errorf("bv = %q, want %q", got, want)
+	}
+	if got, want := x.BW, bw; got == nil {
+		t.Errorf("bw = nil, want %q", want)
+	} else if *got != want {
+		t.Errorf("bw = %q, want %q", *got, want)
+	}
+
+	if got, want := x.TV, tv; got != want {
+		t.Errorf("tv = %q, want %q", got, want)
+	}
+	if got, want := x.TW, tw; got == nil {
+		t.Errorf("tw = nil, want %q", want)
+	} else if *got != want {
+		t.Errorf("tw = %q, want %q", *got, want)
+	}
+}
+
+// Test that we can use a pointer then a value type of a GobEncoder
+// in the same encoded value.
+func TestGobEncoderPointerThenValue(t *testing.T) {
+	v := ValueGobber("forty-two")
+	w := ValueGobber("six-by-nine")
+	bv := BinaryValueGobber("1nanocentury")
+	bw := BinaryValueGobber("πseconds")
+	tv := TextValueGobber("gravitationalacceleration")
+	tw := TextValueGobber("π²ft/s²")
+
+	b := new(bytes.Buffer)
+	enc := NewEncoder(b)
+	if err := enc.Encode(GobTest7{42, &v, w, &bv, bw, &tv, tw}); err != nil {
+		t.Fatal("encode error:", err)
+	}
+	dec := NewDecoder(b)
+	x := new(GobTest7)
+	if err := dec.Decode(x); err != nil {
+		t.Fatal("decode error:", err)
+	}
+
+	if got, want := x.V, v; got == nil {
+		t.Errorf("v = nil, want %q", want)
+	} else if *got != want {
+		t.Errorf("v = %q, want %q", *got, want)
+	}
+	if got, want := x.W, w; got != want {
+		t.Errorf("w = %q, want %q", got, want)
+	}
+
+	if got, want := x.BV, bv; got == nil {
+		t.Errorf("bv = nil, want %q", want)
+	} else if *got != want {
+		t.Errorf("bv = %q, want %q", *got, want)
+	}
+	if got, want := x.BW, bw; got != want {
+		t.Errorf("bw = %q, want %q", got, want)
+	}
+
+	if got, want := x.TV, tv; got == nil {
+		t.Errorf("tv = nil, want %q", want)
+	} else if *got != want {
+		t.Errorf("tv = %q, want %q", *got, want)
+	}
+	if got, want := x.TW, tw; got != want {
+		t.Errorf("tw = %q, want %q", got, want)
+	}
+}
+
+func TestGobEncoderFieldTypeError(t *testing.T) {
+	// GobEncoder to non-decoder: error
+	b := new(bytes.Buffer)
+	enc := NewEncoder(b)
+	err := enc.Encode(GobTest1{17, &StringStruct{"ABC"}})
+	if err != nil {
+		t.Fatal("encode error:", err)
+	}
+	dec := NewDecoder(b)
+	x := &GobTest2{}
+	err = dec.Decode(x)
+	if err == nil {
+		t.Fatal("expected decode error for mismatched fields (encoder to non-decoder)")
+	}
+	if strings.Index(err.Error(), "type") < 0 {
+		t.Fatal("expected type error; got", err)
+	}
+	// Non-encoder to GobDecoder: error
+	b.Reset()
+	err = enc.Encode(GobTest2{17, "ABC"})
+	if err != nil {
+		t.Fatal("encode error:", err)
+	}
+	y := &GobTest1{}
+	err = dec.Decode(y)
+	if err == nil {
+		t.Fatal("expected decode error for mismatched fields (non-encoder to decoder)")
+	}
+	if strings.Index(err.Error(), "type") < 0 {
+		t.Fatal("expected type error; got", err)
+	}
+}
+
+// Even though ByteStruct is a struct, it's treated as a singleton at the top level.
+func TestGobEncoderStructSingleton(t *testing.T) {
+	b := new(bytes.Buffer)
+	enc := NewEncoder(b)
+	err := enc.Encode(&ByteStruct{'A'})
+	if err != nil {
+		t.Fatal("encode error:", err)
+	}
+	dec := NewDecoder(b)
+	x := new(ByteStruct)
+	err = dec.Decode(x)
+	if err != nil {
+		t.Fatal("decode error:", err)
+	}
+	if x.a != 'A' {
+		t.Errorf("expected 'A' got %c", x.a)
+	}
+}
+
+func TestGobEncoderNonStructSingleton(t *testing.T) {
+	b := new(bytes.Buffer)
+	enc := NewEncoder(b)
+	var g Gobber = 1234
+	err := enc.Encode(&g)
+	if err != nil {
+		t.Fatal("encode error:", err)
+	}
+	dec := NewDecoder(b)
+	var x Gobber
+	err = dec.Decode(&x)
+	if err != nil {
+		t.Fatal("decode error:", err)
+	}
+	if x != 1234 {
+		t.Errorf("expected 1234 got %d", x)
+	}
+}
+
+func TestGobEncoderIgnoreStructField(t *testing.T) {
+	b := new(bytes.Buffer)
+	// First a field that's a structure.
+	enc := NewEncoder(b)
+	err := enc.Encode(GobTest0{17, &ByteStruct{'A'}})
+	if err != nil {
+		t.Fatal("encode error:", err)
+	}
+	dec := NewDecoder(b)
+	x := new(GobTestIgnoreEncoder)
+	err = dec.Decode(x)
+	if err != nil {
+		t.Fatal("decode error:", err)
+	}
+	if x.X != 17 {
+		t.Errorf("expected 17 got %c", x.X)
+	}
+}
+
+func TestGobEncoderIgnoreNonStructField(t *testing.T) {
+	b := new(bytes.Buffer)
+	// First a field that's a structure.
+	enc := NewEncoder(b)
+	gobber := Gobber(23)
+	bgobber := BinaryGobber(24)
+	tgobber := TextGobber(25)
+	err := enc.Encode(GobTest3{17, &gobber, &bgobber, &tgobber})
+	if err != nil {
+		t.Fatal("encode error:", err)
+	}
+	dec := NewDecoder(b)
+	x := new(GobTestIgnoreEncoder)
+	err = dec.Decode(x)
+	if err != nil {
+		t.Fatal("decode error:", err)
+	}
+	if x.X != 17 {
+		t.Errorf("expected 17 got %c", x.X)
+	}
+}
+
+func TestGobEncoderIgnoreNilEncoder(t *testing.T) {
+	b := new(bytes.Buffer)
+	// First a field that's a structure.
+	enc := NewEncoder(b)
+	err := enc.Encode(GobTest0{X: 18}) // G is nil
+	if err != nil {
+		t.Fatal("encode error:", err)
+	}
+	dec := NewDecoder(b)
+	x := new(GobTest0)
+	err = dec.Decode(x)
+	if err != nil {
+		t.Fatal("decode error:", err)
+	}
+	if x.X != 18 {
+		t.Errorf("expected x.X = 18, got %v", x.X)
+	}
+	if x.G != nil {
+		t.Errorf("expected x.G = nil, got %v", x.G)
+	}
+}
+
+type gobDecoderBug0 struct {
+	foo, bar string
+}
+
+func (br *gobDecoderBug0) String() string {
+	return br.foo + "-" + br.bar
+}
+
+func (br *gobDecoderBug0) GobEncode() ([]byte, error) {
+	return []byte(br.String()), nil
+}
+
+func (br *gobDecoderBug0) GobDecode(b []byte) error {
+	br.foo = "foo"
+	br.bar = "bar"
+	return nil
+}
+
+// This was a bug: the receiver has a different indirection level
+// than the variable.
+func TestGobEncoderExtraIndirect(t *testing.T) {
+	gdb := &gobDecoderBug0{"foo", "bar"}
+	buf := new(bytes.Buffer)
+	e := NewEncoder(buf)
+	if err := e.Encode(gdb); err != nil {
+		t.Fatalf("encode: %v", err)
+	}
+	d := NewDecoder(buf)
+	var got *gobDecoderBug0
+	if err := d.Decode(&got); err != nil {
+		t.Fatalf("decode: %v", err)
+	}
+	if got.foo != gdb.foo || got.bar != gdb.bar {
+		t.Errorf("got = %q, want %q", got, gdb)
+	}
+}
+
+// Another bug: this caused a crash with the new Go1 Time type.
+// We throw in a gob-encoding array, to test another case of isZero,
+// and a struct containing an nil interface, to test a third.
+type isZeroBug struct {
+	T time.Time
+	S string
+	I int
+	A isZeroBugArray
+	F isZeroBugInterface
+}
+
+type isZeroBugArray [2]uint8
+
+// Receiver is value, not pointer, to test isZero of array.
+func (a isZeroBugArray) GobEncode() (b []byte, e error) {
+	b = append(b, a[:]...)
+	return b, nil
+}
+
+func (a *isZeroBugArray) GobDecode(data []byte) error {
+	if len(data) != len(a) {
+		return io.EOF
+	}
+	a[0] = data[0]
+	a[1] = data[1]
+	return nil
+}
+
+type isZeroBugInterface struct {
+	I interface{}
+}
+
+func (i isZeroBugInterface) GobEncode() (b []byte, e error) {
+	return []byte{}, nil
+}
+
+func (i *isZeroBugInterface) GobDecode(data []byte) error {
+	return nil
+}
+
+func TestGobEncodeIsZero(t *testing.T) {
+	x := isZeroBug{time.Now(), "hello", -55, isZeroBugArray{1, 2}, isZeroBugInterface{}}
+	b := new(bytes.Buffer)
+	enc := NewEncoder(b)
+	err := enc.Encode(x)
+	if err != nil {
+		t.Fatal("encode:", err)
+	}
+	var y isZeroBug
+	dec := NewDecoder(b)
+	err = dec.Decode(&y)
+	if err != nil {
+		t.Fatal("decode:", err)
+	}
+	if x != y {
+		t.Fatalf("%v != %v", x, y)
+	}
+}
+
+func TestGobEncodePtrError(t *testing.T) {
+	var err error
+	b := new(bytes.Buffer)
+	enc := NewEncoder(b)
+	err = enc.Encode(&err)
+	if err != nil {
+		t.Fatal("encode:", err)
+	}
+	dec := NewDecoder(b)
+	err2 := fmt.Errorf("foo")
+	err = dec.Decode(&err2)
+	if err != nil {
+		t.Fatal("decode:", err)
+	}
+	if err2 != nil {
+		t.Fatalf("expected nil, got %v", err2)
+	}
+}
+
+func TestNetIP(t *testing.T) {
+	// Encoding of net.IP{1,2,3,4} in Go 1.1.
+	enc := []byte{0x07, 0x0a, 0x00, 0x04, 0x01, 0x02, 0x03, 0x04}
+
+	var ip net.IP
+	err := NewDecoder(bytes.NewReader(enc)).Decode(&ip)
+	if err != nil {
+		t.Fatalf("decode: %v", err)
+	}
+	if ip.String() != "1.2.3.4" {
+		t.Errorf("decoded to %v, want 1.2.3.4", ip.String())
+	}
+}
diff --git a/src/encoding/gob/timing_test.go b/src/encoding/gob/timing_test.go
new file mode 100644
index 0000000..940e5ad
--- /dev/null
+++ b/src/encoding/gob/timing_test.go
@@ -0,0 +1,325 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package gob
+
+import (
+	"bytes"
+	"io"
+	"os"
+	"runtime"
+	"testing"
+)
+
+type Bench struct {
+	A int
+	B float64
+	C string
+	D []byte
+}
+
+func benchmarkEndToEnd(b *testing.B, ctor func() interface{}, pipe func() (r io.Reader, w io.Writer, err error)) {
+	b.RunParallel(func(pb *testing.PB) {
+		r, w, err := pipe()
+		if err != nil {
+			b.Fatal("can't get pipe:", err)
+		}
+		v := ctor()
+		enc := NewEncoder(w)
+		dec := NewDecoder(r)
+		for pb.Next() {
+			if err := enc.Encode(v); err != nil {
+				b.Fatal("encode error:", err)
+			}
+			if err := dec.Decode(v); err != nil {
+				b.Fatal("decode error:", err)
+			}
+		}
+	})
+}
+
+func BenchmarkEndToEndPipe(b *testing.B) {
+	benchmarkEndToEnd(b, func() interface{} {
+		return &Bench{7, 3.2, "now is the time", bytes.Repeat([]byte("for all good men"), 100)}
+	}, func() (r io.Reader, w io.Writer, err error) {
+		r, w, err = os.Pipe()
+		return
+	})
+}
+
+func BenchmarkEndToEndByteBuffer(b *testing.B) {
+	benchmarkEndToEnd(b, func() interface{} {
+		return &Bench{7, 3.2, "now is the time", bytes.Repeat([]byte("for all good men"), 100)}
+	}, func() (r io.Reader, w io.Writer, err error) {
+		var buf bytes.Buffer
+		return &buf, &buf, nil
+	})
+}
+
+func BenchmarkEndToEndSliceByteBuffer(b *testing.B) {
+	benchmarkEndToEnd(b, func() interface{} {
+		v := &Bench{7, 3.2, "now is the time", nil}
+		Register(v)
+		arr := make([]interface{}, 100)
+		for i := range arr {
+			arr[i] = v
+		}
+		return &arr
+	}, func() (r io.Reader, w io.Writer, err error) {
+		var buf bytes.Buffer
+		return &buf, &buf, nil
+	})
+}
+
+func TestCountEncodeMallocs(t *testing.T) {
+	if testing.Short() {
+		t.Skip("skipping malloc count in short mode")
+	}
+	if runtime.GOMAXPROCS(0) > 1 {
+		t.Skip("skipping; GOMAXPROCS>1")
+	}
+
+	const N = 1000
+
+	var buf bytes.Buffer
+	enc := NewEncoder(&buf)
+	bench := &Bench{7, 3.2, "now is the time", []byte("for all good men")}
+
+	allocs := testing.AllocsPerRun(N, func() {
+		err := enc.Encode(bench)
+		if err != nil {
+			t.Fatal("encode:", err)
+		}
+	})
+	if allocs != 0 {
+		t.Fatalf("mallocs per encode of type Bench: %v; wanted 0\n", allocs)
+	}
+}
+
+func TestCountDecodeMallocs(t *testing.T) {
+	if testing.Short() {
+		t.Skip("skipping malloc count in short mode")
+	}
+	if runtime.GOMAXPROCS(0) > 1 {
+		t.Skip("skipping; GOMAXPROCS>1")
+	}
+
+	const N = 1000
+
+	var buf bytes.Buffer
+	enc := NewEncoder(&buf)
+	bench := &Bench{7, 3.2, "now is the time", []byte("for all good men")}
+
+	// Fill the buffer with enough to decode
+	testing.AllocsPerRun(N, func() {
+		err := enc.Encode(bench)
+		if err != nil {
+			t.Fatal("encode:", err)
+		}
+	})
+
+	dec := NewDecoder(&buf)
+	allocs := testing.AllocsPerRun(N, func() {
+		*bench = Bench{}
+		err := dec.Decode(&bench)
+		if err != nil {
+			t.Fatal("decode:", err)
+		}
+	})
+	if allocs != 4 {
+		t.Fatalf("mallocs per decode of type Bench: %v; wanted 4\n", allocs)
+	}
+}
+
+func BenchmarkEncodeComplex128Slice(b *testing.B) {
+	var buf bytes.Buffer
+	enc := NewEncoder(&buf)
+	a := make([]complex128, 1000)
+	for i := range a {
+		a[i] = 1.2 + 3.4i
+	}
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		buf.Reset()
+		err := enc.Encode(a)
+		if err != nil {
+			b.Fatal(err)
+		}
+	}
+}
+
+func BenchmarkEncodeFloat64Slice(b *testing.B) {
+	var buf bytes.Buffer
+	enc := NewEncoder(&buf)
+	a := make([]float64, 1000)
+	for i := range a {
+		a[i] = 1.23e4
+	}
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		buf.Reset()
+		err := enc.Encode(a)
+		if err != nil {
+			b.Fatal(err)
+		}
+	}
+}
+
+func BenchmarkEncodeInt32Slice(b *testing.B) {
+	var buf bytes.Buffer
+	enc := NewEncoder(&buf)
+	a := make([]int32, 1000)
+	for i := range a {
+		a[i] = 1234
+	}
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		buf.Reset()
+		err := enc.Encode(a)
+		if err != nil {
+			b.Fatal(err)
+		}
+	}
+}
+
+func BenchmarkEncodeStringSlice(b *testing.B) {
+	var buf bytes.Buffer
+	enc := NewEncoder(&buf)
+	a := make([]string, 1000)
+	for i := range a {
+		a[i] = "now is the time"
+	}
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		buf.Reset()
+		err := enc.Encode(a)
+		if err != nil {
+			b.Fatal(err)
+		}
+	}
+}
+
+// benchmarkBuf is a read buffer we can reset
+type benchmarkBuf struct {
+	offset int
+	data   []byte
+}
+
+func (b *benchmarkBuf) Read(p []byte) (n int, err error) {
+	n = copy(p, b.data[b.offset:])
+	if n == 0 {
+		return 0, io.EOF
+	}
+	b.offset += n
+	return
+}
+
+func (b *benchmarkBuf) ReadByte() (c byte, err error) {
+	if b.offset >= len(b.data) {
+		return 0, io.EOF
+	}
+	c = b.data[b.offset]
+	b.offset++
+	return
+}
+
+func (b *benchmarkBuf) reset() {
+	b.offset = 0
+}
+
+func BenchmarkDecodeComplex128Slice(b *testing.B) {
+	var buf bytes.Buffer
+	enc := NewEncoder(&buf)
+	a := make([]complex128, 1000)
+	for i := range a {
+		a[i] = 1.2 + 3.4i
+	}
+	err := enc.Encode(a)
+	if err != nil {
+		b.Fatal(err)
+	}
+	x := make([]complex128, 1000)
+	bbuf := benchmarkBuf{data: buf.Bytes()}
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		bbuf.reset()
+		dec := NewDecoder(&bbuf)
+		err := dec.Decode(&x)
+		if err != nil {
+			b.Fatal(i, err)
+		}
+	}
+}
+
+func BenchmarkDecodeFloat64Slice(b *testing.B) {
+	var buf bytes.Buffer
+	enc := NewEncoder(&buf)
+	a := make([]float64, 1000)
+	for i := range a {
+		a[i] = 1.23e4
+	}
+	err := enc.Encode(a)
+	if err != nil {
+		b.Fatal(err)
+	}
+	x := make([]float64, 1000)
+	bbuf := benchmarkBuf{data: buf.Bytes()}
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		bbuf.reset()
+		dec := NewDecoder(&bbuf)
+		err := dec.Decode(&x)
+		if err != nil {
+			b.Fatal(i, err)
+		}
+	}
+}
+
+func BenchmarkDecodeInt32Slice(b *testing.B) {
+	var buf bytes.Buffer
+	enc := NewEncoder(&buf)
+	a := make([]int32, 1000)
+	for i := range a {
+		a[i] = 1234
+	}
+	err := enc.Encode(a)
+	if err != nil {
+		b.Fatal(err)
+	}
+	x := make([]int32, 1000)
+	bbuf := benchmarkBuf{data: buf.Bytes()}
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		bbuf.reset()
+		dec := NewDecoder(&bbuf)
+		err := dec.Decode(&x)
+		if err != nil {
+			b.Fatal(i, err)
+		}
+	}
+}
+
+func BenchmarkDecodeStringSlice(b *testing.B) {
+	var buf bytes.Buffer
+	enc := NewEncoder(&buf)
+	a := make([]string, 1000)
+	for i := range a {
+		a[i] = "now is the time"
+	}
+	err := enc.Encode(a)
+	if err != nil {
+		b.Fatal(err)
+	}
+	x := make([]string, 1000)
+	bbuf := benchmarkBuf{data: buf.Bytes()}
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		bbuf.reset()
+		dec := NewDecoder(&bbuf)
+		err := dec.Decode(&x)
+		if err != nil {
+			b.Fatal(i, err)
+		}
+	}
+}
diff --git a/src/encoding/gob/type.go b/src/encoding/gob/type.go
new file mode 100644
index 0000000..a49b71a
--- /dev/null
+++ b/src/encoding/gob/type.go
@@ -0,0 +1,923 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package gob
+
+import (
+	"encoding"
+	"errors"
+	"fmt"
+	"os"
+	"reflect"
+	"sync"
+	"sync/atomic"
+	"unicode"
+	"unicode/utf8"
+)
+
+// userTypeInfo stores the information associated with a type the user has handed
+// to the package.  It's computed once and stored in a map keyed by reflection
+// type.
+type userTypeInfo struct {
+	user        reflect.Type // the type the user handed us
+	base        reflect.Type // the base type after all indirections
+	indir       int          // number of indirections to reach the base type
+	externalEnc int          // xGob, xBinary, or xText
+	externalDec int          // xGob, xBinary or xText
+	encIndir    int8         // number of indirections to reach the receiver type; may be negative
+	decIndir    int8         // number of indirections to reach the receiver type; may be negative
+}
+
+// externalEncoding bits
+const (
+	xGob    = 1 + iota // GobEncoder or GobDecoder
+	xBinary            // encoding.BinaryMarshaler or encoding.BinaryUnmarshaler
+	xText              // encoding.TextMarshaler or encoding.TextUnmarshaler
+)
+
+var (
+	// Protected by an RWMutex because we read it a lot and write
+	// it only when we see a new type, typically when compiling.
+	userTypeLock  sync.RWMutex
+	userTypeCache = make(map[reflect.Type]*userTypeInfo)
+)
+
+// validType returns, and saves, the information associated with user-provided type rt.
+// If the user type is not valid, err will be non-nil.  To be used when the error handler
+// is not set up.
+func validUserType(rt reflect.Type) (ut *userTypeInfo, err error) {
+	userTypeLock.RLock()
+	ut = userTypeCache[rt]
+	userTypeLock.RUnlock()
+	if ut != nil {
+		return
+	}
+	// Now set the value under the write lock.
+	userTypeLock.Lock()
+	defer userTypeLock.Unlock()
+	if ut = userTypeCache[rt]; ut != nil {
+		// Lost the race; not a problem.
+		return
+	}
+	ut = new(userTypeInfo)
+	ut.base = rt
+	ut.user = rt
+	// A type that is just a cycle of pointers (such as type T *T) cannot
+	// be represented in gobs, which need some concrete data.  We use a
+	// cycle detection algorithm from Knuth, Vol 2, Section 3.1, Ex 6,
+	// pp 539-540.  As we step through indirections, run another type at
+	// half speed. If they meet up, there's a cycle.
+	slowpoke := ut.base // walks half as fast as ut.base
+	for {
+		pt := ut.base
+		if pt.Kind() != reflect.Ptr {
+			break
+		}
+		ut.base = pt.Elem()
+		if ut.base == slowpoke { // ut.base lapped slowpoke
+			// recursive pointer type.
+			return nil, errors.New("can't represent recursive pointer type " + ut.base.String())
+		}
+		if ut.indir%2 == 0 {
+			slowpoke = slowpoke.Elem()
+		}
+		ut.indir++
+	}
+
+	if ok, indir := implementsInterface(ut.user, gobEncoderInterfaceType); ok {
+		ut.externalEnc, ut.encIndir = xGob, indir
+	} else if ok, indir := implementsInterface(ut.user, binaryMarshalerInterfaceType); ok {
+		ut.externalEnc, ut.encIndir = xBinary, indir
+	}
+
+	// NOTE(rsc): Would like to allow MarshalText here, but results in incompatibility
+	// with older encodings for net.IP. See golang.org/issue/6760.
+	// } else if ok, indir := implementsInterface(ut.user, textMarshalerInterfaceType); ok {
+	// 	ut.externalEnc, ut.encIndir = xText, indir
+	// }
+
+	if ok, indir := implementsInterface(ut.user, gobDecoderInterfaceType); ok {
+		ut.externalDec, ut.decIndir = xGob, indir
+	} else if ok, indir := implementsInterface(ut.user, binaryUnmarshalerInterfaceType); ok {
+		ut.externalDec, ut.decIndir = xBinary, indir
+	}
+
+	// See note above.
+	// } else if ok, indir := implementsInterface(ut.user, textUnmarshalerInterfaceType); ok {
+	// 	ut.externalDec, ut.decIndir = xText, indir
+	// }
+
+	userTypeCache[rt] = ut
+	return
+}
+
+var (
+	gobEncoderInterfaceType        = reflect.TypeOf((*GobEncoder)(nil)).Elem()
+	gobDecoderInterfaceType        = reflect.TypeOf((*GobDecoder)(nil)).Elem()
+	binaryMarshalerInterfaceType   = reflect.TypeOf((*encoding.BinaryMarshaler)(nil)).Elem()
+	binaryUnmarshalerInterfaceType = reflect.TypeOf((*encoding.BinaryUnmarshaler)(nil)).Elem()
+	textMarshalerInterfaceType     = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem()
+	textUnmarshalerInterfaceType   = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem()
+)
+
+// implementsInterface reports whether the type implements the
+// gobEncoder/gobDecoder interface.
+// It also returns the number of indirections required to get to the
+// implementation.
+func implementsInterface(typ, gobEncDecType reflect.Type) (success bool, indir int8) {
+	if typ == nil {
+		return
+	}
+	rt := typ
+	// The type might be a pointer and we need to keep
+	// dereferencing to the base type until we find an implementation.
+	for {
+		if rt.Implements(gobEncDecType) {
+			return true, indir
+		}
+		if p := rt; p.Kind() == reflect.Ptr {
+			indir++
+			if indir > 100 { // insane number of indirections
+				return false, 0
+			}
+			rt = p.Elem()
+			continue
+		}
+		break
+	}
+	// No luck yet, but if this is a base type (non-pointer), the pointer might satisfy.
+	if typ.Kind() != reflect.Ptr {
+		// Not a pointer, but does the pointer work?
+		if reflect.PtrTo(typ).Implements(gobEncDecType) {
+			return true, -1
+		}
+	}
+	return false, 0
+}
+
+// userType returns, and saves, the information associated with user-provided type rt.
+// If the user type is not valid, it calls error.
+func userType(rt reflect.Type) *userTypeInfo {
+	ut, err := validUserType(rt)
+	if err != nil {
+		error_(err)
+	}
+	return ut
+}
+
+// A typeId represents a gob Type as an integer that can be passed on the wire.
+// Internally, typeIds are used as keys to a map to recover the underlying type info.
+type typeId int32
+
+var nextId typeId       // incremented for each new type we build
+var typeLock sync.Mutex // set while building a type
+const firstUserId = 64  // lowest id number granted to user
+
+type gobType interface {
+	id() typeId
+	setId(id typeId)
+	name() string
+	string() string // not public; only for debugging
+	safeString(seen map[typeId]bool) string
+}
+
+var types = make(map[reflect.Type]gobType)
+var idToType = make(map[typeId]gobType)
+var builtinIdToType map[typeId]gobType // set in init() after builtins are established
+
+func setTypeId(typ gobType) {
+	// When building recursive types, someone may get there before us.
+	if typ.id() != 0 {
+		return
+	}
+	nextId++
+	typ.setId(nextId)
+	idToType[nextId] = typ
+}
+
+func (t typeId) gobType() gobType {
+	if t == 0 {
+		return nil
+	}
+	return idToType[t]
+}
+
+// string returns the string representation of the type associated with the typeId.
+func (t typeId) string() string {
+	if t.gobType() == nil {
+		return "<nil>"
+	}
+	return t.gobType().string()
+}
+
+// Name returns the name of the type associated with the typeId.
+func (t typeId) name() string {
+	if t.gobType() == nil {
+		return "<nil>"
+	}
+	return t.gobType().name()
+}
+
+// CommonType holds elements of all types.
+// It is a historical artifact, kept for binary compatibility and exported
+// only for the benefit of the package's encoding of type descriptors. It is
+// not intended for direct use by clients.
+type CommonType struct {
+	Name string
+	Id   typeId
+}
+
+func (t *CommonType) id() typeId { return t.Id }
+
+func (t *CommonType) setId(id typeId) { t.Id = id }
+
+func (t *CommonType) string() string { return t.Name }
+
+func (t *CommonType) safeString(seen map[typeId]bool) string {
+	return t.Name
+}
+
+func (t *CommonType) name() string { return t.Name }
+
+// Create and check predefined types
+// The string for tBytes is "bytes" not "[]byte" to signify its specialness.
+
+var (
+	// Primordial types, needed during initialization.
+	// Always passed as pointers so the interface{} type
+	// goes through without losing its interfaceness.
+	tBool      = bootstrapType("bool", (*bool)(nil), 1)
+	tInt       = bootstrapType("int", (*int)(nil), 2)
+	tUint      = bootstrapType("uint", (*uint)(nil), 3)
+	tFloat     = bootstrapType("float", (*float64)(nil), 4)
+	tBytes     = bootstrapType("bytes", (*[]byte)(nil), 5)
+	tString    = bootstrapType("string", (*string)(nil), 6)
+	tComplex   = bootstrapType("complex", (*complex128)(nil), 7)
+	tInterface = bootstrapType("interface", (*interface{})(nil), 8)
+	// Reserve some Ids for compatible expansion
+	tReserved7 = bootstrapType("_reserved1", (*struct{ r7 int })(nil), 9)
+	tReserved6 = bootstrapType("_reserved1", (*struct{ r6 int })(nil), 10)
+	tReserved5 = bootstrapType("_reserved1", (*struct{ r5 int })(nil), 11)
+	tReserved4 = bootstrapType("_reserved1", (*struct{ r4 int })(nil), 12)
+	tReserved3 = bootstrapType("_reserved1", (*struct{ r3 int })(nil), 13)
+	tReserved2 = bootstrapType("_reserved1", (*struct{ r2 int })(nil), 14)
+	tReserved1 = bootstrapType("_reserved1", (*struct{ r1 int })(nil), 15)
+)
+
+// Predefined because it's needed by the Decoder
+var tWireType = mustGetTypeInfo(reflect.TypeOf(wireType{})).id
+var wireTypeUserInfo *userTypeInfo // userTypeInfo of (*wireType)
+
+func init() {
+	// Some magic numbers to make sure there are no surprises.
+	checkId(16, tWireType)
+	checkId(17, mustGetTypeInfo(reflect.TypeOf(arrayType{})).id)
+	checkId(18, mustGetTypeInfo(reflect.TypeOf(CommonType{})).id)
+	checkId(19, mustGetTypeInfo(reflect.TypeOf(sliceType{})).id)
+	checkId(20, mustGetTypeInfo(reflect.TypeOf(structType{})).id)
+	checkId(21, mustGetTypeInfo(reflect.TypeOf(fieldType{})).id)
+	checkId(23, mustGetTypeInfo(reflect.TypeOf(mapType{})).id)
+
+	builtinIdToType = make(map[typeId]gobType)
+	for k, v := range idToType {
+		builtinIdToType[k] = v
+	}
+
+	// Move the id space upwards to allow for growth in the predefined world
+	// without breaking existing files.
+	if nextId > firstUserId {
+		panic(fmt.Sprintln("nextId too large:", nextId))
+	}
+	nextId = firstUserId
+	registerBasics()
+	wireTypeUserInfo = userType(reflect.TypeOf((*wireType)(nil)))
+}
+
+// Array type
+type arrayType struct {
+	CommonType
+	Elem typeId
+	Len  int
+}
+
+func newArrayType(name string) *arrayType {
+	a := &arrayType{CommonType{Name: name}, 0, 0}
+	return a
+}
+
+func (a *arrayType) init(elem gobType, len int) {
+	// Set our type id before evaluating the element's, in case it's our own.
+	setTypeId(a)
+	a.Elem = elem.id()
+	a.Len = len
+}
+
+func (a *arrayType) safeString(seen map[typeId]bool) string {
+	if seen[a.Id] {
+		return a.Name
+	}
+	seen[a.Id] = true
+	return fmt.Sprintf("[%d]%s", a.Len, a.Elem.gobType().safeString(seen))
+}
+
+func (a *arrayType) string() string { return a.safeString(make(map[typeId]bool)) }
+
+// GobEncoder type (something that implements the GobEncoder interface)
+type gobEncoderType struct {
+	CommonType
+}
+
+func newGobEncoderType(name string) *gobEncoderType {
+	g := &gobEncoderType{CommonType{Name: name}}
+	setTypeId(g)
+	return g
+}
+
+func (g *gobEncoderType) safeString(seen map[typeId]bool) string {
+	return g.Name
+}
+
+func (g *gobEncoderType) string() string { return g.Name }
+
+// Map type
+type mapType struct {
+	CommonType
+	Key  typeId
+	Elem typeId
+}
+
+func newMapType(name string) *mapType {
+	m := &mapType{CommonType{Name: name}, 0, 0}
+	return m
+}
+
+func (m *mapType) init(key, elem gobType) {
+	// Set our type id before evaluating the element's, in case it's our own.
+	setTypeId(m)
+	m.Key = key.id()
+	m.Elem = elem.id()
+}
+
+func (m *mapType) safeString(seen map[typeId]bool) string {
+	if seen[m.Id] {
+		return m.Name
+	}
+	seen[m.Id] = true
+	key := m.Key.gobType().safeString(seen)
+	elem := m.Elem.gobType().safeString(seen)
+	return fmt.Sprintf("map[%s]%s", key, elem)
+}
+
+func (m *mapType) string() string { return m.safeString(make(map[typeId]bool)) }
+
+// Slice type
+type sliceType struct {
+	CommonType
+	Elem typeId
+}
+
+func newSliceType(name string) *sliceType {
+	s := &sliceType{CommonType{Name: name}, 0}
+	return s
+}
+
+func (s *sliceType) init(elem gobType) {
+	// Set our type id before evaluating the element's, in case it's our own.
+	setTypeId(s)
+	// See the comments about ids in newTypeObject. Only slices and
+	// structs have mutual recursion.
+	if elem.id() == 0 {
+		setTypeId(elem)
+	}
+	s.Elem = elem.id()
+}
+
+func (s *sliceType) safeString(seen map[typeId]bool) string {
+	if seen[s.Id] {
+		return s.Name
+	}
+	seen[s.Id] = true
+	return fmt.Sprintf("[]%s", s.Elem.gobType().safeString(seen))
+}
+
+func (s *sliceType) string() string { return s.safeString(make(map[typeId]bool)) }
+
+// Struct type
+type fieldType struct {
+	Name string
+	Id   typeId
+}
+
+type structType struct {
+	CommonType
+	Field []*fieldType
+}
+
+func (s *structType) safeString(seen map[typeId]bool) string {
+	if s == nil {
+		return "<nil>"
+	}
+	if _, ok := seen[s.Id]; ok {
+		return s.Name
+	}
+	seen[s.Id] = true
+	str := s.Name + " = struct { "
+	for _, f := range s.Field {
+		str += fmt.Sprintf("%s %s; ", f.Name, f.Id.gobType().safeString(seen))
+	}
+	str += "}"
+	return str
+}
+
+func (s *structType) string() string { return s.safeString(make(map[typeId]bool)) }
+
+func newStructType(name string) *structType {
+	s := &structType{CommonType{Name: name}, nil}
+	// For historical reasons we set the id here rather than init.
+	// See the comment in newTypeObject for details.
+	setTypeId(s)
+	return s
+}
+
+// newTypeObject allocates a gobType for the reflection type rt.
+// Unless ut represents a GobEncoder, rt should be the base type
+// of ut.
+// This is only called from the encoding side. The decoding side
+// works through typeIds and userTypeInfos alone.
+func newTypeObject(name string, ut *userTypeInfo, rt reflect.Type) (gobType, error) {
+	// Does this type implement GobEncoder?
+	if ut.externalEnc != 0 {
+		return newGobEncoderType(name), nil
+	}
+	var err error
+	var type0, type1 gobType
+	defer func() {
+		if err != nil {
+			delete(types, rt)
+		}
+	}()
+	// Install the top-level type before the subtypes (e.g. struct before
+	// fields) so recursive types can be constructed safely.
+	switch t := rt; t.Kind() {
+	// All basic types are easy: they are predefined.
+	case reflect.Bool:
+		return tBool.gobType(), nil
+
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		return tInt.gobType(), nil
+
+	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+		return tUint.gobType(), nil
+
+	case reflect.Float32, reflect.Float64:
+		return tFloat.gobType(), nil
+
+	case reflect.Complex64, reflect.Complex128:
+		return tComplex.gobType(), nil
+
+	case reflect.String:
+		return tString.gobType(), nil
+
+	case reflect.Interface:
+		return tInterface.gobType(), nil
+
+	case reflect.Array:
+		at := newArrayType(name)
+		types[rt] = at
+		type0, err = getBaseType("", t.Elem())
+		if err != nil {
+			return nil, err
+		}
+		// Historical aside:
+		// For arrays, maps, and slices, we set the type id after the elements
+		// are constructed. This is to retain the order of type id allocation after
+		// a fix made to handle recursive types, which changed the order in
+		// which types are built.  Delaying the setting in this way preserves
+		// type ids while allowing recursive types to be described. Structs,
+		// done below, were already handling recursion correctly so they
+		// assign the top-level id before those of the field.
+		at.init(type0, t.Len())
+		return at, nil
+
+	case reflect.Map:
+		mt := newMapType(name)
+		types[rt] = mt
+		type0, err = getBaseType("", t.Key())
+		if err != nil {
+			return nil, err
+		}
+		type1, err = getBaseType("", t.Elem())
+		if err != nil {
+			return nil, err
+		}
+		mt.init(type0, type1)
+		return mt, nil
+
+	case reflect.Slice:
+		// []byte == []uint8 is a special case
+		if t.Elem().Kind() == reflect.Uint8 {
+			return tBytes.gobType(), nil
+		}
+		st := newSliceType(name)
+		types[rt] = st
+		type0, err = getBaseType(t.Elem().Name(), t.Elem())
+		if err != nil {
+			return nil, err
+		}
+		st.init(type0)
+		return st, nil
+
+	case reflect.Struct:
+		st := newStructType(name)
+		types[rt] = st
+		idToType[st.id()] = st
+		for i := 0; i < t.NumField(); i++ {
+			f := t.Field(i)
+			if !isSent(&f) {
+				continue
+			}
+			typ := userType(f.Type).base
+			tname := typ.Name()
+			if tname == "" {
+				t := userType(f.Type).base
+				tname = t.String()
+			}
+			gt, err := getBaseType(tname, f.Type)
+			if err != nil {
+				return nil, err
+			}
+			// Some mutually recursive types can cause us to be here while
+			// still defining the element. Fix the element type id here.
+			// We could do this more neatly by setting the id at the start of
+			// building every type, but that would break binary compatibility.
+			if gt.id() == 0 {
+				setTypeId(gt)
+			}
+			st.Field = append(st.Field, &fieldType{f.Name, gt.id()})
+		}
+		return st, nil
+
+	default:
+		return nil, errors.New("gob NewTypeObject can't handle type: " + rt.String())
+	}
+}
+
+// isExported reports whether this is an exported - upper case - name.
+func isExported(name string) bool {
+	rune, _ := utf8.DecodeRuneInString(name)
+	return unicode.IsUpper(rune)
+}
+
+// isSent reports whether this struct field is to be transmitted.
+// It will be transmitted only if it is exported and not a chan or func field
+// or pointer to chan or func.
+func isSent(field *reflect.StructField) bool {
+	if !isExported(field.Name) {
+		return false
+	}
+	// If the field is a chan or func or pointer thereto, don't send it.
+	// That is, treat it like an unexported field.
+	typ := field.Type
+	for typ.Kind() == reflect.Ptr {
+		typ = typ.Elem()
+	}
+	if typ.Kind() == reflect.Chan || typ.Kind() == reflect.Func {
+		return false
+	}
+	return true
+}
+
+// getBaseType returns the Gob type describing the given reflect.Type's base type.
+// typeLock must be held.
+func getBaseType(name string, rt reflect.Type) (gobType, error) {
+	ut := userType(rt)
+	return getType(name, ut, ut.base)
+}
+
+// getType returns the Gob type describing the given reflect.Type.
+// Should be called only when handling GobEncoders/Decoders,
+// which may be pointers.  All other types are handled through the
+// base type, never a pointer.
+// typeLock must be held.
+func getType(name string, ut *userTypeInfo, rt reflect.Type) (gobType, error) {
+	typ, present := types[rt]
+	if present {
+		return typ, nil
+	}
+	typ, err := newTypeObject(name, ut, rt)
+	if err == nil {
+		types[rt] = typ
+	}
+	return typ, err
+}
+
+func checkId(want, got typeId) {
+	if want != got {
+		fmt.Fprintf(os.Stderr, "checkId: %d should be %d\n", int(got), int(want))
+		panic("bootstrap type wrong id: " + got.name() + " " + got.string() + " not " + want.string())
+	}
+}
+
+// used for building the basic types; called only from init().  the incoming
+// interface always refers to a pointer.
+func bootstrapType(name string, e interface{}, expect typeId) typeId {
+	rt := reflect.TypeOf(e).Elem()
+	_, present := types[rt]
+	if present {
+		panic("bootstrap type already present: " + name + ", " + rt.String())
+	}
+	typ := &CommonType{Name: name}
+	types[rt] = typ
+	setTypeId(typ)
+	checkId(expect, nextId)
+	userType(rt) // might as well cache it now
+	return nextId
+}
+
+// Representation of the information we send and receive about this type.
+// Each value we send is preceded by its type definition: an encoded int.
+// However, the very first time we send the value, we first send the pair
+// (-id, wireType).
+// For bootstrapping purposes, we assume that the recipient knows how
+// to decode a wireType; it is exactly the wireType struct here, interpreted
+// using the gob rules for sending a structure, except that we assume the
+// ids for wireType and structType etc. are known.  The relevant pieces
+// are built in encode.go's init() function.
+// To maintain binary compatibility, if you extend this type, always put
+// the new fields last.
+type wireType struct {
+	ArrayT           *arrayType
+	SliceT           *sliceType
+	StructT          *structType
+	MapT             *mapType
+	GobEncoderT      *gobEncoderType
+	BinaryMarshalerT *gobEncoderType
+	TextMarshalerT   *gobEncoderType
+}
+
+func (w *wireType) string() string {
+	const unknown = "unknown type"
+	if w == nil {
+		return unknown
+	}
+	switch {
+	case w.ArrayT != nil:
+		return w.ArrayT.Name
+	case w.SliceT != nil:
+		return w.SliceT.Name
+	case w.StructT != nil:
+		return w.StructT.Name
+	case w.MapT != nil:
+		return w.MapT.Name
+	case w.GobEncoderT != nil:
+		return w.GobEncoderT.Name
+	case w.BinaryMarshalerT != nil:
+		return w.BinaryMarshalerT.Name
+	case w.TextMarshalerT != nil:
+		return w.TextMarshalerT.Name
+	}
+	return unknown
+}
+
+type typeInfo struct {
+	id      typeId
+	encInit sync.Mutex   // protects creation of encoder
+	encoder atomic.Value // *encEngine
+	wire    *wireType
+}
+
+// typeInfoMap is an atomic pointer to map[reflect.Type]*typeInfo.
+// It's updated copy-on-write. Readers just do an atomic load
+// to get the current version of the map. Writers make a full copy of
+// the map and atomically update the pointer to point to the new map.
+// Under heavy read contention, this is significantly faster than a map
+// protected by a mutex.
+var typeInfoMap atomic.Value
+
+func lookupTypeInfo(rt reflect.Type) *typeInfo {
+	m, _ := typeInfoMap.Load().(map[reflect.Type]*typeInfo)
+	return m[rt]
+}
+
+func getTypeInfo(ut *userTypeInfo) (*typeInfo, error) {
+	rt := ut.base
+	if ut.externalEnc != 0 {
+		// We want the user type, not the base type.
+		rt = ut.user
+	}
+	if info := lookupTypeInfo(rt); info != nil {
+		return info, nil
+	}
+	return buildTypeInfo(ut, rt)
+}
+
+// buildTypeInfo constructs the type information for the type
+// and stores it in the type info map.
+func buildTypeInfo(ut *userTypeInfo, rt reflect.Type) (*typeInfo, error) {
+	typeLock.Lock()
+	defer typeLock.Unlock()
+
+	if info := lookupTypeInfo(rt); info != nil {
+		return info, nil
+	}
+
+	gt, err := getBaseType(rt.Name(), rt)
+	if err != nil {
+		return nil, err
+	}
+	info := &typeInfo{id: gt.id()}
+
+	if ut.externalEnc != 0 {
+		userType, err := getType(rt.Name(), ut, rt)
+		if err != nil {
+			return nil, err
+		}
+		gt := userType.id().gobType().(*gobEncoderType)
+		switch ut.externalEnc {
+		case xGob:
+			info.wire = &wireType{GobEncoderT: gt}
+		case xBinary:
+			info.wire = &wireType{BinaryMarshalerT: gt}
+		case xText:
+			info.wire = &wireType{TextMarshalerT: gt}
+		}
+		rt = ut.user
+	} else {
+		t := info.id.gobType()
+		switch typ := rt; typ.Kind() {
+		case reflect.Array:
+			info.wire = &wireType{ArrayT: t.(*arrayType)}
+		case reflect.Map:
+			info.wire = &wireType{MapT: t.(*mapType)}
+		case reflect.Slice:
+			// []byte == []uint8 is a special case handled separately
+			if typ.Elem().Kind() != reflect.Uint8 {
+				info.wire = &wireType{SliceT: t.(*sliceType)}
+			}
+		case reflect.Struct:
+			info.wire = &wireType{StructT: t.(*structType)}
+		}
+	}
+
+	// Create new map with old contents plus new entry.
+	newm := make(map[reflect.Type]*typeInfo)
+	m, _ := typeInfoMap.Load().(map[reflect.Type]*typeInfo)
+	for k, v := range m {
+		newm[k] = v
+	}
+	newm[rt] = info
+	typeInfoMap.Store(newm)
+	return info, nil
+}
+
+// Called only when a panic is acceptable and unexpected.
+func mustGetTypeInfo(rt reflect.Type) *typeInfo {
+	t, err := getTypeInfo(userType(rt))
+	if err != nil {
+		panic("getTypeInfo: " + err.Error())
+	}
+	return t
+}
+
+// GobEncoder is the interface describing data that provides its own
+// representation for encoding values for transmission to a GobDecoder.
+// A type that implements GobEncoder and GobDecoder has complete
+// control over the representation of its data and may therefore
+// contain things such as private fields, channels, and functions,
+// which are not usually transmissible in gob streams.
+//
+// Note: Since gobs can be stored permanently, It is good design
+// to guarantee the encoding used by a GobEncoder is stable as the
+// software evolves.  For instance, it might make sense for GobEncode
+// to include a version number in the encoding.
+type GobEncoder interface {
+	// GobEncode returns a byte slice representing the encoding of the
+	// receiver for transmission to a GobDecoder, usually of the same
+	// concrete type.
+	GobEncode() ([]byte, error)
+}
+
+// GobDecoder is the interface describing data that provides its own
+// routine for decoding transmitted values sent by a GobEncoder.
+type GobDecoder interface {
+	// GobDecode overwrites the receiver, which must be a pointer,
+	// with the value represented by the byte slice, which was written
+	// by GobEncode, usually for the same concrete type.
+	GobDecode([]byte) error
+}
+
+var (
+	registerLock       sync.RWMutex
+	nameToConcreteType = make(map[string]reflect.Type)
+	concreteTypeToName = make(map[reflect.Type]string)
+)
+
+// RegisterName is like Register but uses the provided name rather than the
+// type's default.
+func RegisterName(name string, value interface{}) {
+	if name == "" {
+		// reserved for nil
+		panic("attempt to register empty name")
+	}
+	registerLock.Lock()
+	defer registerLock.Unlock()
+	ut := userType(reflect.TypeOf(value))
+	// Check for incompatible duplicates. The name must refer to the
+	// same user type, and vice versa.
+	if t, ok := nameToConcreteType[name]; ok && t != ut.user {
+		panic(fmt.Sprintf("gob: registering duplicate types for %q: %s != %s", name, t, ut.user))
+	}
+	if n, ok := concreteTypeToName[ut.base]; ok && n != name {
+		panic(fmt.Sprintf("gob: registering duplicate names for %s: %q != %q", ut.user, n, name))
+	}
+	// Store the name and type provided by the user....
+	nameToConcreteType[name] = reflect.TypeOf(value)
+	// but the flattened type in the type table, since that's what decode needs.
+	concreteTypeToName[ut.base] = name
+}
+
+// Register records a type, identified by a value for that type, under its
+// internal type name.  That name will identify the concrete type of a value
+// sent or received as an interface variable.  Only types that will be
+// transferred as implementations of interface values need to be registered.
+// Expecting to be used only during initialization, it panics if the mapping
+// between types and names is not a bijection.
+func Register(value interface{}) {
+	// Default to printed representation for unnamed types
+	rt := reflect.TypeOf(value)
+	name := rt.String()
+
+	// But for named types (or pointers to them), qualify with import path (but see inner comment).
+	// Dereference one pointer looking for a named type.
+	star := ""
+	if rt.Name() == "" {
+		if pt := rt; pt.Kind() == reflect.Ptr {
+			star = "*"
+			// NOTE: The following line should be rt = pt.Elem() to implement
+			// what the comment above claims, but fixing it would break compatibility
+			// with existing gobs.
+			//
+			// Given package p imported as "full/p" with these definitions:
+			//     package p
+			//     type T1 struct { ... }
+			// this table shows the intended and actual strings used by gob to
+			// name the types:
+			//
+			// Type      Correct string     Actual string
+			//
+			// T1        full/p.T1          full/p.T1
+			// *T1       *full/p.T1         *p.T1
+			//
+			// The missing full path cannot be fixed without breaking existing gob decoders.
+			rt = pt
+		}
+	}
+	if rt.Name() != "" {
+		if rt.PkgPath() == "" {
+			name = star + rt.Name()
+		} else {
+			name = star + rt.PkgPath() + "." + rt.Name()
+		}
+	}
+
+	RegisterName(name, value)
+}
+
+func registerBasics() {
+	Register(int(0))
+	Register(int8(0))
+	Register(int16(0))
+	Register(int32(0))
+	Register(int64(0))
+	Register(uint(0))
+	Register(uint8(0))
+	Register(uint16(0))
+	Register(uint32(0))
+	Register(uint64(0))
+	Register(float32(0))
+	Register(float64(0))
+	Register(complex64(0i))
+	Register(complex128(0i))
+	Register(uintptr(0))
+	Register(false)
+	Register("")
+	Register([]byte(nil))
+	Register([]int(nil))
+	Register([]int8(nil))
+	Register([]int16(nil))
+	Register([]int32(nil))
+	Register([]int64(nil))
+	Register([]uint(nil))
+	Register([]uint8(nil))
+	Register([]uint16(nil))
+	Register([]uint32(nil))
+	Register([]uint64(nil))
+	Register([]float32(nil))
+	Register([]float64(nil))
+	Register([]complex64(nil))
+	Register([]complex128(nil))
+	Register([]uintptr(nil))
+	Register([]bool(nil))
+	Register([]string(nil))
+}
diff --git a/src/pkg/encoding/gob/type_test.go b/src/encoding/gob/type_test.go
similarity index 100%
rename from src/pkg/encoding/gob/type_test.go
rename to src/encoding/gob/type_test.go
diff --git a/src/pkg/encoding/hex/hex.go b/src/encoding/hex/hex.go
similarity index 100%
rename from src/pkg/encoding/hex/hex.go
rename to src/encoding/hex/hex.go
diff --git a/src/pkg/encoding/hex/hex_test.go b/src/encoding/hex/hex_test.go
similarity index 100%
rename from src/pkg/encoding/hex/hex_test.go
rename to src/encoding/hex/hex_test.go
diff --git a/src/pkg/encoding/json/bench_test.go b/src/encoding/json/bench_test.go
similarity index 100%
rename from src/pkg/encoding/json/bench_test.go
rename to src/encoding/json/bench_test.go
diff --git a/src/encoding/json/decode.go b/src/encoding/json/decode.go
new file mode 100644
index 0000000..705bc2e
--- /dev/null
+++ b/src/encoding/json/decode.go
@@ -0,0 +1,1084 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Represents JSON data structure using native Go types: booleans, floats,
+// strings, arrays, and maps.
+
+package json
+
+import (
+	"bytes"
+	"encoding"
+	"encoding/base64"
+	"errors"
+	"fmt"
+	"reflect"
+	"runtime"
+	"strconv"
+	"unicode"
+	"unicode/utf16"
+	"unicode/utf8"
+)
+
+// Unmarshal parses the JSON-encoded data and stores the result
+// in the value pointed to by v.
+//
+// Unmarshal uses the inverse of the encodings that
+// Marshal uses, allocating maps, slices, and pointers as necessary,
+// with the following additional rules:
+//
+// To unmarshal JSON into a pointer, Unmarshal first handles the case of
+// the JSON being the JSON literal null.  In that case, Unmarshal sets
+// the pointer to nil.  Otherwise, Unmarshal unmarshals the JSON into
+// the value pointed at by the pointer.  If the pointer is nil, Unmarshal
+// allocates a new value for it to point to.
+//
+// To unmarshal JSON into a struct, Unmarshal matches incoming object
+// keys to the keys used by Marshal (either the struct field name or its tag),
+// preferring an exact match but also accepting a case-insensitive match.
+//
+// To unmarshal JSON into an interface value,
+// Unmarshal stores one of these in the interface value:
+//
+//	bool, for JSON booleans
+//	float64, for JSON numbers
+//	string, for JSON strings
+//	[]interface{}, for JSON arrays
+//	map[string]interface{}, for JSON objects
+//	nil for JSON null
+//
+// If a JSON value is not appropriate for a given target type,
+// or if a JSON number overflows the target type, Unmarshal
+// skips that field and completes the unmarshalling as best it can.
+// If no more serious errors are encountered, Unmarshal returns
+// an UnmarshalTypeError describing the earliest such error.
+//
+// The JSON null value unmarshals into an interface, map, pointer, or slice
+// by setting that Go value to nil. Because null is often used in JSON to mean
+// ``not present,'' unmarshaling a JSON null into any other Go type has no effect
+// on the value and produces no error.
+//
+// When unmarshaling quoted strings, invalid UTF-8 or
+// invalid UTF-16 surrogate pairs are not treated as an error.
+// Instead, they are replaced by the Unicode replacement
+// character U+FFFD.
+//
+func Unmarshal(data []byte, v interface{}) error {
+	// Check for well-formedness.
+	// Avoids filling out half a data structure
+	// before discovering a JSON syntax error.
+	var d decodeState
+	err := checkValid(data, &d.scan)
+	if err != nil {
+		return err
+	}
+
+	d.init(data)
+	return d.unmarshal(v)
+}
+
+// Unmarshaler is the interface implemented by objects
+// that can unmarshal a JSON description of themselves.
+// The input can be assumed to be a valid encoding of
+// a JSON value. UnmarshalJSON must copy the JSON data
+// if it wishes to retain the data after returning.
+type Unmarshaler interface {
+	UnmarshalJSON([]byte) error
+}
+
+// An UnmarshalTypeError describes a JSON value that was
+// not appropriate for a value of a specific Go type.
+type UnmarshalTypeError struct {
+	Value string       // description of JSON value - "bool", "array", "number -5"
+	Type  reflect.Type // type of Go value it could not be assigned to
+}
+
+func (e *UnmarshalTypeError) Error() string {
+	return "json: cannot unmarshal " + e.Value + " into Go value of type " + e.Type.String()
+}
+
+// An UnmarshalFieldError describes a JSON object key that
+// led to an unexported (and therefore unwritable) struct field.
+// (No longer used; kept for compatibility.)
+type UnmarshalFieldError struct {
+	Key   string
+	Type  reflect.Type
+	Field reflect.StructField
+}
+
+func (e *UnmarshalFieldError) Error() string {
+	return "json: cannot unmarshal object key " + strconv.Quote(e.Key) + " into unexported field " + e.Field.Name + " of type " + e.Type.String()
+}
+
+// An InvalidUnmarshalError describes an invalid argument passed to Unmarshal.
+// (The argument to Unmarshal must be a non-nil pointer.)
+type InvalidUnmarshalError struct {
+	Type reflect.Type
+}
+
+func (e *InvalidUnmarshalError) Error() string {
+	if e.Type == nil {
+		return "json: Unmarshal(nil)"
+	}
+
+	if e.Type.Kind() != reflect.Ptr {
+		return "json: Unmarshal(non-pointer " + e.Type.String() + ")"
+	}
+	return "json: Unmarshal(nil " + e.Type.String() + ")"
+}
+
+func (d *decodeState) unmarshal(v interface{}) (err error) {
+	defer func() {
+		if r := recover(); r != nil {
+			if _, ok := r.(runtime.Error); ok {
+				panic(r)
+			}
+			err = r.(error)
+		}
+	}()
+
+	rv := reflect.ValueOf(v)
+	if rv.Kind() != reflect.Ptr || rv.IsNil() {
+		return &InvalidUnmarshalError{reflect.TypeOf(v)}
+	}
+
+	d.scan.reset()
+	// We decode rv not rv.Elem because the Unmarshaler interface
+	// test must be applied at the top level of the value.
+	d.value(rv)
+	return d.savedError
+}
+
+// A Number represents a JSON number literal.
+type Number string
+
+// String returns the literal text of the number.
+func (n Number) String() string { return string(n) }
+
+// Float64 returns the number as a float64.
+func (n Number) Float64() (float64, error) {
+	return strconv.ParseFloat(string(n), 64)
+}
+
+// Int64 returns the number as an int64.
+func (n Number) Int64() (int64, error) {
+	return strconv.ParseInt(string(n), 10, 64)
+}
+
+// decodeState represents the state while decoding a JSON value.
+type decodeState struct {
+	data       []byte
+	off        int // read offset in data
+	scan       scanner
+	nextscan   scanner // for calls to nextValue
+	savedError error
+	useNumber  bool
+}
+
+// errPhase is used for errors that should not happen unless
+// there is a bug in the JSON decoder or something is editing
+// the data slice while the decoder executes.
+var errPhase = errors.New("JSON decoder out of sync - data changing underfoot?")
+
+func (d *decodeState) init(data []byte) *decodeState {
+	d.data = data
+	d.off = 0
+	d.savedError = nil
+	return d
+}
+
+// error aborts the decoding by panicking with err.
+func (d *decodeState) error(err error) {
+	panic(err)
+}
+
+// saveError saves the first err it is called with,
+// for reporting at the end of the unmarshal.
+func (d *decodeState) saveError(err error) {
+	if d.savedError == nil {
+		d.savedError = err
+	}
+}
+
+// next cuts off and returns the next full JSON value in d.data[d.off:].
+// The next value is known to be an object or array, not a literal.
+func (d *decodeState) next() []byte {
+	c := d.data[d.off]
+	item, rest, err := nextValue(d.data[d.off:], &d.nextscan)
+	if err != nil {
+		d.error(err)
+	}
+	d.off = len(d.data) - len(rest)
+
+	// Our scanner has seen the opening brace/bracket
+	// and thinks we're still in the middle of the object.
+	// invent a closing brace/bracket to get it out.
+	if c == '{' {
+		d.scan.step(&d.scan, '}')
+	} else {
+		d.scan.step(&d.scan, ']')
+	}
+
+	return item
+}
+
+// scanWhile processes bytes in d.data[d.off:] until it
+// receives a scan code not equal to op.
+// It updates d.off and returns the new scan code.
+func (d *decodeState) scanWhile(op int) int {
+	var newOp int
+	for {
+		if d.off >= len(d.data) {
+			newOp = d.scan.eof()
+			d.off = len(d.data) + 1 // mark processed EOF with len+1
+		} else {
+			c := int(d.data[d.off])
+			d.off++
+			newOp = d.scan.step(&d.scan, c)
+		}
+		if newOp != op {
+			break
+		}
+	}
+	return newOp
+}
+
+// value decodes a JSON value from d.data[d.off:] into the value.
+// it updates d.off to point past the decoded value.
+func (d *decodeState) value(v reflect.Value) {
+	if !v.IsValid() {
+		_, rest, err := nextValue(d.data[d.off:], &d.nextscan)
+		if err != nil {
+			d.error(err)
+		}
+		d.off = len(d.data) - len(rest)
+
+		// d.scan thinks we're still at the beginning of the item.
+		// Feed in an empty string - the shortest, simplest value -
+		// so that it knows we got to the end of the value.
+		if d.scan.redo {
+			// rewind.
+			d.scan.redo = false
+			d.scan.step = stateBeginValue
+		}
+		d.scan.step(&d.scan, '"')
+		d.scan.step(&d.scan, '"')
+
+		n := len(d.scan.parseState)
+		if n > 0 && d.scan.parseState[n-1] == parseObjectKey {
+			// d.scan thinks we just read an object key; finish the object
+			d.scan.step(&d.scan, ':')
+			d.scan.step(&d.scan, '"')
+			d.scan.step(&d.scan, '"')
+			d.scan.step(&d.scan, '}')
+		}
+
+		return
+	}
+
+	switch op := d.scanWhile(scanSkipSpace); op {
+	default:
+		d.error(errPhase)
+
+	case scanBeginArray:
+		d.array(v)
+
+	case scanBeginObject:
+		d.object(v)
+
+	case scanBeginLiteral:
+		d.literal(v)
+	}
+}
+
+type unquotedValue struct{}
+
+// valueQuoted is like value but decodes a
+// quoted string literal or literal null into an interface value.
+// If it finds anything other than a quoted string literal or null,
+// valueQuoted returns unquotedValue{}.
+func (d *decodeState) valueQuoted() interface{} {
+	switch op := d.scanWhile(scanSkipSpace); op {
+	default:
+		d.error(errPhase)
+
+	case scanBeginArray:
+		d.array(reflect.Value{})
+
+	case scanBeginObject:
+		d.object(reflect.Value{})
+
+	case scanBeginLiteral:
+		switch v := d.literalInterface().(type) {
+		case nil, string:
+			return v
+		}
+	}
+	return unquotedValue{}
+}
+
+// indirect walks down v allocating pointers as needed,
+// until it gets to a non-pointer.
+// if it encounters an Unmarshaler, indirect stops and returns that.
+// if decodingNull is true, indirect stops at the last pointer so it can be set to nil.
+func (d *decodeState) indirect(v reflect.Value, decodingNull bool) (Unmarshaler, encoding.TextUnmarshaler, reflect.Value) {
+	// If v is a named type and is addressable,
+	// start with its address, so that if the type has pointer methods,
+	// we find them.
+	if v.Kind() != reflect.Ptr && v.Type().Name() != "" && v.CanAddr() {
+		v = v.Addr()
+	}
+	for {
+		// Load value from interface, but only if the result will be
+		// usefully addressable.
+		if v.Kind() == reflect.Interface && !v.IsNil() {
+			e := v.Elem()
+			if e.Kind() == reflect.Ptr && !e.IsNil() && (!decodingNull || e.Elem().Kind() == reflect.Ptr) {
+				v = e
+				continue
+			}
+		}
+
+		if v.Kind() != reflect.Ptr {
+			break
+		}
+
+		if v.Elem().Kind() != reflect.Ptr && decodingNull && v.CanSet() {
+			break
+		}
+		if v.IsNil() {
+			v.Set(reflect.New(v.Type().Elem()))
+		}
+		if v.Type().NumMethod() > 0 {
+			if u, ok := v.Interface().(Unmarshaler); ok {
+				return u, nil, reflect.Value{}
+			}
+			if u, ok := v.Interface().(encoding.TextUnmarshaler); ok {
+				return nil, u, reflect.Value{}
+			}
+		}
+		v = v.Elem()
+	}
+	return nil, nil, v
+}
+
+// array consumes an array from d.data[d.off-1:], decoding into the value v.
+// the first byte of the array ('[') has been read already.
+func (d *decodeState) array(v reflect.Value) {
+	// Check for unmarshaler.
+	u, ut, pv := d.indirect(v, false)
+	if u != nil {
+		d.off--
+		err := u.UnmarshalJSON(d.next())
+		if err != nil {
+			d.error(err)
+		}
+		return
+	}
+	if ut != nil {
+		d.saveError(&UnmarshalTypeError{"array", v.Type()})
+		d.off--
+		d.next()
+		return
+	}
+
+	v = pv
+
+	// Check type of target.
+	switch v.Kind() {
+	case reflect.Interface:
+		if v.NumMethod() == 0 {
+			// Decoding into nil interface?  Switch to non-reflect code.
+			v.Set(reflect.ValueOf(d.arrayInterface()))
+			return
+		}
+		// Otherwise it's invalid.
+		fallthrough
+	default:
+		d.saveError(&UnmarshalTypeError{"array", v.Type()})
+		d.off--
+		d.next()
+		return
+	case reflect.Array:
+	case reflect.Slice:
+		break
+	}
+
+	i := 0
+	for {
+		// Look ahead for ] - can only happen on first iteration.
+		op := d.scanWhile(scanSkipSpace)
+		if op == scanEndArray {
+			break
+		}
+
+		// Back up so d.value can have the byte we just read.
+		d.off--
+		d.scan.undo(op)
+
+		// Get element of array, growing if necessary.
+		if v.Kind() == reflect.Slice {
+			// Grow slice if necessary
+			if i >= v.Cap() {
+				newcap := v.Cap() + v.Cap()/2
+				if newcap < 4 {
+					newcap = 4
+				}
+				newv := reflect.MakeSlice(v.Type(), v.Len(), newcap)
+				reflect.Copy(newv, v)
+				v.Set(newv)
+			}
+			if i >= v.Len() {
+				v.SetLen(i + 1)
+			}
+		}
+
+		if i < v.Len() {
+			// Decode into element.
+			d.value(v.Index(i))
+		} else {
+			// Ran out of fixed array: skip.
+			d.value(reflect.Value{})
+		}
+		i++
+
+		// Next token must be , or ].
+		op = d.scanWhile(scanSkipSpace)
+		if op == scanEndArray {
+			break
+		}
+		if op != scanArrayValue {
+			d.error(errPhase)
+		}
+	}
+
+	if i < v.Len() {
+		if v.Kind() == reflect.Array {
+			// Array.  Zero the rest.
+			z := reflect.Zero(v.Type().Elem())
+			for ; i < v.Len(); i++ {
+				v.Index(i).Set(z)
+			}
+		} else {
+			v.SetLen(i)
+		}
+	}
+	if i == 0 && v.Kind() == reflect.Slice {
+		v.Set(reflect.MakeSlice(v.Type(), 0, 0))
+	}
+}
+
+var nullLiteral = []byte("null")
+
+// object consumes an object from d.data[d.off-1:], decoding into the value v.
+// the first byte ('{') of the object has been read already.
+func (d *decodeState) object(v reflect.Value) {
+	// Check for unmarshaler.
+	u, ut, pv := d.indirect(v, false)
+	if u != nil {
+		d.off--
+		err := u.UnmarshalJSON(d.next())
+		if err != nil {
+			d.error(err)
+		}
+		return
+	}
+	if ut != nil {
+		d.saveError(&UnmarshalTypeError{"object", v.Type()})
+		d.off--
+		d.next() // skip over { } in input
+		return
+	}
+	v = pv
+
+	// Decoding into nil interface?  Switch to non-reflect code.
+	if v.Kind() == reflect.Interface && v.NumMethod() == 0 {
+		v.Set(reflect.ValueOf(d.objectInterface()))
+		return
+	}
+
+	// Check type of target: struct or map[string]T
+	switch v.Kind() {
+	case reflect.Map:
+		// map must have string kind
+		t := v.Type()
+		if t.Key().Kind() != reflect.String {
+			d.saveError(&UnmarshalTypeError{"object", v.Type()})
+			d.off--
+			d.next() // skip over { } in input
+			return
+		}
+		if v.IsNil() {
+			v.Set(reflect.MakeMap(t))
+		}
+	case reflect.Struct:
+
+	default:
+		d.saveError(&UnmarshalTypeError{"object", v.Type()})
+		d.off--
+		d.next() // skip over { } in input
+		return
+	}
+
+	var mapElem reflect.Value
+
+	for {
+		// Read opening " of string key or closing }.
+		op := d.scanWhile(scanSkipSpace)
+		if op == scanEndObject {
+			// closing } - can only happen on first iteration.
+			break
+		}
+		if op != scanBeginLiteral {
+			d.error(errPhase)
+		}
+
+		// Read key.
+		start := d.off - 1
+		op = d.scanWhile(scanContinue)
+		item := d.data[start : d.off-1]
+		key, ok := unquoteBytes(item)
+		if !ok {
+			d.error(errPhase)
+		}
+
+		// Figure out field corresponding to key.
+		var subv reflect.Value
+		destring := false // whether the value is wrapped in a string to be decoded first
+
+		if v.Kind() == reflect.Map {
+			elemType := v.Type().Elem()
+			if !mapElem.IsValid() {
+				mapElem = reflect.New(elemType).Elem()
+			} else {
+				mapElem.Set(reflect.Zero(elemType))
+			}
+			subv = mapElem
+		} else {
+			var f *field
+			fields := cachedTypeFields(v.Type())
+			for i := range fields {
+				ff := &fields[i]
+				if bytes.Equal(ff.nameBytes, key) {
+					f = ff
+					break
+				}
+				if f == nil && ff.equalFold(ff.nameBytes, key) {
+					f = ff
+				}
+			}
+			if f != nil {
+				subv = v
+				destring = f.quoted
+				for _, i := range f.index {
+					if subv.Kind() == reflect.Ptr {
+						if subv.IsNil() {
+							subv.Set(reflect.New(subv.Type().Elem()))
+						}
+						subv = subv.Elem()
+					}
+					subv = subv.Field(i)
+				}
+			}
+		}
+
+		// Read : before value.
+		if op == scanSkipSpace {
+			op = d.scanWhile(scanSkipSpace)
+		}
+		if op != scanObjectKey {
+			d.error(errPhase)
+		}
+
+		// Read value.
+		if destring {
+			switch qv := d.valueQuoted().(type) {
+			case nil:
+				d.literalStore(nullLiteral, subv, false)
+			case string:
+				d.literalStore([]byte(qv), subv, true)
+			default:
+				d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal unquoted value into %v", item, v.Type()))
+			}
+		} else {
+			d.value(subv)
+		}
+
+		// Write value back to map;
+		// if using struct, subv points into struct already.
+		if v.Kind() == reflect.Map {
+			kv := reflect.ValueOf(key).Convert(v.Type().Key())
+			v.SetMapIndex(kv, subv)
+		}
+
+		// Next token must be , or }.
+		op = d.scanWhile(scanSkipSpace)
+		if op == scanEndObject {
+			break
+		}
+		if op != scanObjectValue {
+			d.error(errPhase)
+		}
+	}
+}
+
+// literal consumes a literal from d.data[d.off-1:], decoding into the value v.
+// The first byte of the literal has been read already
+// (that's how the caller knows it's a literal).
+func (d *decodeState) literal(v reflect.Value) {
+	// All bytes inside literal return scanContinue op code.
+	start := d.off - 1
+	op := d.scanWhile(scanContinue)
+
+	// Scan read one byte too far; back up.
+	d.off--
+	d.scan.undo(op)
+
+	d.literalStore(d.data[start:d.off], v, false)
+}
+
+// convertNumber converts the number literal s to a float64 or a Number
+// depending on the setting of d.useNumber.
+func (d *decodeState) convertNumber(s string) (interface{}, error) {
+	if d.useNumber {
+		return Number(s), nil
+	}
+	f, err := strconv.ParseFloat(s, 64)
+	if err != nil {
+		return nil, &UnmarshalTypeError{"number " + s, reflect.TypeOf(0.0)}
+	}
+	return f, nil
+}
+
+var numberType = reflect.TypeOf(Number(""))
+
+// literalStore decodes a literal stored in item into v.
+//
+// fromQuoted indicates whether this literal came from unwrapping a
+// string from the ",string" struct tag option. this is used only to
+// produce more helpful error messages.
+func (d *decodeState) literalStore(item []byte, v reflect.Value, fromQuoted bool) {
+	// Check for unmarshaler.
+	if len(item) == 0 {
+		//Empty string given
+		d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type()))
+		return
+	}
+	wantptr := item[0] == 'n' // null
+	u, ut, pv := d.indirect(v, wantptr)
+	if u != nil {
+		err := u.UnmarshalJSON(item)
+		if err != nil {
+			d.error(err)
+		}
+		return
+	}
+	if ut != nil {
+		if item[0] != '"' {
+			if fromQuoted {
+				d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type()))
+			} else {
+				d.saveError(&UnmarshalTypeError{"string", v.Type()})
+			}
+		}
+		s, ok := unquoteBytes(item)
+		if !ok {
+			if fromQuoted {
+				d.error(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type()))
+			} else {
+				d.error(errPhase)
+			}
+		}
+		err := ut.UnmarshalText(s)
+		if err != nil {
+			d.error(err)
+		}
+		return
+	}
+
+	v = pv
+
+	switch c := item[0]; c {
+	case 'n': // null
+		switch v.Kind() {
+		case reflect.Interface, reflect.Ptr, reflect.Map, reflect.Slice:
+			v.Set(reflect.Zero(v.Type()))
+			// otherwise, ignore null for primitives/string
+		}
+	case 't', 'f': // true, false
+		value := c == 't'
+		switch v.Kind() {
+		default:
+			if fromQuoted {
+				d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type()))
+			} else {
+				d.saveError(&UnmarshalTypeError{"bool", v.Type()})
+			}
+		case reflect.Bool:
+			v.SetBool(value)
+		case reflect.Interface:
+			if v.NumMethod() == 0 {
+				v.Set(reflect.ValueOf(value))
+			} else {
+				d.saveError(&UnmarshalTypeError{"bool", v.Type()})
+			}
+		}
+
+	case '"': // string
+		s, ok := unquoteBytes(item)
+		if !ok {
+			if fromQuoted {
+				d.error(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type()))
+			} else {
+				d.error(errPhase)
+			}
+		}
+		switch v.Kind() {
+		default:
+			d.saveError(&UnmarshalTypeError{"string", v.Type()})
+		case reflect.Slice:
+			if v.Type() != byteSliceType {
+				d.saveError(&UnmarshalTypeError{"string", v.Type()})
+				break
+			}
+			b := make([]byte, base64.StdEncoding.DecodedLen(len(s)))
+			n, err := base64.StdEncoding.Decode(b, s)
+			if err != nil {
+				d.saveError(err)
+				break
+			}
+			v.Set(reflect.ValueOf(b[0:n]))
+		case reflect.String:
+			v.SetString(string(s))
+		case reflect.Interface:
+			if v.NumMethod() == 0 {
+				v.Set(reflect.ValueOf(string(s)))
+			} else {
+				d.saveError(&UnmarshalTypeError{"string", v.Type()})
+			}
+		}
+
+	default: // number
+		if c != '-' && (c < '0' || c > '9') {
+			if fromQuoted {
+				d.error(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type()))
+			} else {
+				d.error(errPhase)
+			}
+		}
+		s := string(item)
+		switch v.Kind() {
+		default:
+			if v.Kind() == reflect.String && v.Type() == numberType {
+				v.SetString(s)
+				break
+			}
+			if fromQuoted {
+				d.error(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type()))
+			} else {
+				d.error(&UnmarshalTypeError{"number", v.Type()})
+			}
+		case reflect.Interface:
+			n, err := d.convertNumber(s)
+			if err != nil {
+				d.saveError(err)
+				break
+			}
+			if v.NumMethod() != 0 {
+				d.saveError(&UnmarshalTypeError{"number", v.Type()})
+				break
+			}
+			v.Set(reflect.ValueOf(n))
+
+		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+			n, err := strconv.ParseInt(s, 10, 64)
+			if err != nil || v.OverflowInt(n) {
+				d.saveError(&UnmarshalTypeError{"number " + s, v.Type()})
+				break
+			}
+			v.SetInt(n)
+
+		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+			n, err := strconv.ParseUint(s, 10, 64)
+			if err != nil || v.OverflowUint(n) {
+				d.saveError(&UnmarshalTypeError{"number " + s, v.Type()})
+				break
+			}
+			v.SetUint(n)
+
+		case reflect.Float32, reflect.Float64:
+			n, err := strconv.ParseFloat(s, v.Type().Bits())
+			if err != nil || v.OverflowFloat(n) {
+				d.saveError(&UnmarshalTypeError{"number " + s, v.Type()})
+				break
+			}
+			v.SetFloat(n)
+		}
+	}
+}
+
+// The xxxInterface routines build up a value to be stored
+// in an empty interface.  They are not strictly necessary,
+// but they avoid the weight of reflection in this common case.
+
+// valueInterface is like value but returns interface{}
+func (d *decodeState) valueInterface() interface{} {
+	switch d.scanWhile(scanSkipSpace) {
+	default:
+		d.error(errPhase)
+		panic("unreachable")
+	case scanBeginArray:
+		return d.arrayInterface()
+	case scanBeginObject:
+		return d.objectInterface()
+	case scanBeginLiteral:
+		return d.literalInterface()
+	}
+}
+
+// arrayInterface is like array but returns []interface{}.
+func (d *decodeState) arrayInterface() []interface{} {
+	var v = make([]interface{}, 0)
+	for {
+		// Look ahead for ] - can only happen on first iteration.
+		op := d.scanWhile(scanSkipSpace)
+		if op == scanEndArray {
+			break
+		}
+
+		// Back up so d.value can have the byte we just read.
+		d.off--
+		d.scan.undo(op)
+
+		v = append(v, d.valueInterface())
+
+		// Next token must be , or ].
+		op = d.scanWhile(scanSkipSpace)
+		if op == scanEndArray {
+			break
+		}
+		if op != scanArrayValue {
+			d.error(errPhase)
+		}
+	}
+	return v
+}
+
+// objectInterface is like object but returns map[string]interface{}.
+func (d *decodeState) objectInterface() map[string]interface{} {
+	m := make(map[string]interface{})
+	for {
+		// Read opening " of string key or closing }.
+		op := d.scanWhile(scanSkipSpace)
+		if op == scanEndObject {
+			// closing } - can only happen on first iteration.
+			break
+		}
+		if op != scanBeginLiteral {
+			d.error(errPhase)
+		}
+
+		// Read string key.
+		start := d.off - 1
+		op = d.scanWhile(scanContinue)
+		item := d.data[start : d.off-1]
+		key, ok := unquote(item)
+		if !ok {
+			d.error(errPhase)
+		}
+
+		// Read : before value.
+		if op == scanSkipSpace {
+			op = d.scanWhile(scanSkipSpace)
+		}
+		if op != scanObjectKey {
+			d.error(errPhase)
+		}
+
+		// Read value.
+		m[key] = d.valueInterface()
+
+		// Next token must be , or }.
+		op = d.scanWhile(scanSkipSpace)
+		if op == scanEndObject {
+			break
+		}
+		if op != scanObjectValue {
+			d.error(errPhase)
+		}
+	}
+	return m
+}
+
+// literalInterface is like literal but returns an interface value.
+func (d *decodeState) literalInterface() interface{} {
+	// All bytes inside literal return scanContinue op code.
+	start := d.off - 1
+	op := d.scanWhile(scanContinue)
+
+	// Scan read one byte too far; back up.
+	d.off--
+	d.scan.undo(op)
+	item := d.data[start:d.off]
+
+	switch c := item[0]; c {
+	case 'n': // null
+		return nil
+
+	case 't', 'f': // true, false
+		return c == 't'
+
+	case '"': // string
+		s, ok := unquote(item)
+		if !ok {
+			d.error(errPhase)
+		}
+		return s
+
+	default: // number
+		if c != '-' && (c < '0' || c > '9') {
+			d.error(errPhase)
+		}
+		n, err := d.convertNumber(string(item))
+		if err != nil {
+			d.saveError(err)
+		}
+		return n
+	}
+}
+
+// getu4 decodes \uXXXX from the beginning of s, returning the hex value,
+// or it returns -1.
+func getu4(s []byte) rune {
+	if len(s) < 6 || s[0] != '\\' || s[1] != 'u' {
+		return -1
+	}
+	r, err := strconv.ParseUint(string(s[2:6]), 16, 64)
+	if err != nil {
+		return -1
+	}
+	return rune(r)
+}
+
+// unquote converts a quoted JSON string literal s into an actual string t.
+// The rules are different than for Go, so cannot use strconv.Unquote.
+func unquote(s []byte) (t string, ok bool) {
+	s, ok = unquoteBytes(s)
+	t = string(s)
+	return
+}
+
+func unquoteBytes(s []byte) (t []byte, ok bool) {
+	if len(s) < 2 || s[0] != '"' || s[len(s)-1] != '"' {
+		return
+	}
+	s = s[1 : len(s)-1]
+
+	// Check for unusual characters. If there are none,
+	// then no unquoting is needed, so return a slice of the
+	// original bytes.
+	r := 0
+	for r < len(s) {
+		c := s[r]
+		if c == '\\' || c == '"' || c < ' ' {
+			break
+		}
+		if c < utf8.RuneSelf {
+			r++
+			continue
+		}
+		rr, size := utf8.DecodeRune(s[r:])
+		if rr == utf8.RuneError && size == 1 {
+			break
+		}
+		r += size
+	}
+	if r == len(s) {
+		return s, true
+	}
+
+	b := make([]byte, len(s)+2*utf8.UTFMax)
+	w := copy(b, s[0:r])
+	for r < len(s) {
+		// Out of room?  Can only happen if s is full of
+		// malformed UTF-8 and we're replacing each
+		// byte with RuneError.
+		if w >= len(b)-2*utf8.UTFMax {
+			nb := make([]byte, (len(b)+utf8.UTFMax)*2)
+			copy(nb, b[0:w])
+			b = nb
+		}
+		switch c := s[r]; {
+		case c == '\\':
+			r++
+			if r >= len(s) {
+				return
+			}
+			switch s[r] {
+			default:
+				return
+			case '"', '\\', '/', '\'':
+				b[w] = s[r]
+				r++
+				w++
+			case 'b':
+				b[w] = '\b'
+				r++
+				w++
+			case 'f':
+				b[w] = '\f'
+				r++
+				w++
+			case 'n':
+				b[w] = '\n'
+				r++
+				w++
+			case 'r':
+				b[w] = '\r'
+				r++
+				w++
+			case 't':
+				b[w] = '\t'
+				r++
+				w++
+			case 'u':
+				r--
+				rr := getu4(s[r:])
+				if rr < 0 {
+					return
+				}
+				r += 6
+				if utf16.IsSurrogate(rr) {
+					rr1 := getu4(s[r:])
+					if dec := utf16.DecodeRune(rr, rr1); dec != unicode.ReplacementChar {
+						// A valid pair; consume.
+						r += 6
+						w += utf8.EncodeRune(b[w:], dec)
+						break
+					}
+					// Invalid surrogate; fall back to replacement rune.
+					rr = unicode.ReplacementChar
+				}
+				w += utf8.EncodeRune(b[w:], rr)
+			}
+
+		// Quote, control characters are invalid.
+		case c == '"', c < ' ':
+			return
+
+		// ASCII
+		case c < utf8.RuneSelf:
+			b[w] = c
+			r++
+			w++
+
+		// Coerce to well-formed UTF-8.
+		default:
+			rr, size := utf8.DecodeRune(s[r:])
+			r += size
+			w += utf8.EncodeRune(b[w:], rr)
+		}
+	}
+	return b[0:w], true
+}
diff --git a/src/encoding/json/decode_test.go b/src/encoding/json/decode_test.go
new file mode 100644
index 0000000..7235969
--- /dev/null
+++ b/src/encoding/json/decode_test.go
@@ -0,0 +1,1373 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package json
+
+import (
+	"bytes"
+	"encoding"
+	"fmt"
+	"image"
+	"reflect"
+	"strings"
+	"testing"
+	"time"
+)
+
+type T struct {
+	X string
+	Y int
+	Z int `json:"-"`
+}
+
+type U struct {
+	Alphabet string `json:"alpha"`
+}
+
+type V struct {
+	F1 interface{}
+	F2 int32
+	F3 Number
+}
+
+// ifaceNumAsFloat64/ifaceNumAsNumber are used to test unmarshaling with and
+// without UseNumber
+var ifaceNumAsFloat64 = map[string]interface{}{
+	"k1": float64(1),
+	"k2": "s",
+	"k3": []interface{}{float64(1), float64(2.0), float64(3e-3)},
+	"k4": map[string]interface{}{"kk1": "s", "kk2": float64(2)},
+}
+
+var ifaceNumAsNumber = map[string]interface{}{
+	"k1": Number("1"),
+	"k2": "s",
+	"k3": []interface{}{Number("1"), Number("2.0"), Number("3e-3")},
+	"k4": map[string]interface{}{"kk1": "s", "kk2": Number("2")},
+}
+
+type tx struct {
+	x int
+}
+
+// A type that can unmarshal itself.
+
+type unmarshaler struct {
+	T bool
+}
+
+func (u *unmarshaler) UnmarshalJSON(b []byte) error {
+	*u = unmarshaler{true} // All we need to see that UnmarshalJSON is called.
+	return nil
+}
+
+type ustruct struct {
+	M unmarshaler
+}
+
+type unmarshalerText struct {
+	T bool
+}
+
+// needed for re-marshaling tests
+func (u *unmarshalerText) MarshalText() ([]byte, error) {
+	return []byte(""), nil
+}
+
+func (u *unmarshalerText) UnmarshalText(b []byte) error {
+	*u = unmarshalerText{true} // All we need to see that UnmarshalText is called.
+	return nil
+}
+
+var _ encoding.TextUnmarshaler = (*unmarshalerText)(nil)
+
+type ustructText struct {
+	M unmarshalerText
+}
+
+var (
+	um0, um1 unmarshaler // target2 of unmarshaling
+	ump      = &um1
+	umtrue   = unmarshaler{true}
+	umslice  = []unmarshaler{{true}}
+	umslicep = new([]unmarshaler)
+	umstruct = ustruct{unmarshaler{true}}
+
+	um0T, um1T unmarshalerText // target2 of unmarshaling
+	umpT       = &um1T
+	umtrueT    = unmarshalerText{true}
+	umsliceT   = []unmarshalerText{{true}}
+	umslicepT  = new([]unmarshalerText)
+	umstructT  = ustructText{unmarshalerText{true}}
+)
+
+// Test data structures for anonymous fields.
+
+type Point struct {
+	Z int
+}
+
+type Top struct {
+	Level0 int
+	Embed0
+	*Embed0a
+	*Embed0b `json:"e,omitempty"` // treated as named
+	Embed0c  `json:"-"`           // ignored
+	Loop
+	Embed0p // has Point with X, Y, used
+	Embed0q // has Point with Z, used
+}
+
+type Embed0 struct {
+	Level1a int // overridden by Embed0a's Level1a with json tag
+	Level1b int // used because Embed0a's Level1b is renamed
+	Level1c int // used because Embed0a's Level1c is ignored
+	Level1d int // annihilated by Embed0a's Level1d
+	Level1e int `json:"x"` // annihilated by Embed0a.Level1e
+}
+
+type Embed0a struct {
+	Level1a int `json:"Level1a,omitempty"`
+	Level1b int `json:"LEVEL1B,omitempty"`
+	Level1c int `json:"-"`
+	Level1d int // annihilated by Embed0's Level1d
+	Level1f int `json:"x"` // annihilated by Embed0's Level1e
+}
+
+type Embed0b Embed0
+
+type Embed0c Embed0
+
+type Embed0p struct {
+	image.Point
+}
+
+type Embed0q struct {
+	Point
+}
+
+type Loop struct {
+	Loop1 int `json:",omitempty"`
+	Loop2 int `json:",omitempty"`
+	*Loop
+}
+
+// From reflect test:
+// The X in S6 and S7 annihilate, but they also block the X in S8.S9.
+type S5 struct {
+	S6
+	S7
+	S8
+}
+
+type S6 struct {
+	X int
+}
+
+type S7 S6
+
+type S8 struct {
+	S9
+}
+
+type S9 struct {
+	X int
+	Y int
+}
+
+// From reflect test:
+// The X in S11.S6 and S12.S6 annihilate, but they also block the X in S13.S8.S9.
+type S10 struct {
+	S11
+	S12
+	S13
+}
+
+type S11 struct {
+	S6
+}
+
+type S12 struct {
+	S6
+}
+
+type S13 struct {
+	S8
+}
+
+type unmarshalTest struct {
+	in        string
+	ptr       interface{}
+	out       interface{}
+	err       error
+	useNumber bool
+}
+
+type Ambig struct {
+	// Given "hello", the first match should win.
+	First  int `json:"HELLO"`
+	Second int `json:"Hello"`
+}
+
+type XYZ struct {
+	X interface{}
+	Y interface{}
+	Z interface{}
+}
+
+var unmarshalTests = []unmarshalTest{
+	// basic types
+	{in: `true`, ptr: new(bool), out: true},
+	{in: `1`, ptr: new(int), out: 1},
+	{in: `1.2`, ptr: new(float64), out: 1.2},
+	{in: `-5`, ptr: new(int16), out: int16(-5)},
+	{in: `2`, ptr: new(Number), out: Number("2"), useNumber: true},
+	{in: `2`, ptr: new(Number), out: Number("2")},
+	{in: `2`, ptr: new(interface{}), out: float64(2.0)},
+	{in: `2`, ptr: new(interface{}), out: Number("2"), useNumber: true},
+	{in: `"a\u1234"`, ptr: new(string), out: "a\u1234"},
+	{in: `"http:\/\/"`, ptr: new(string), out: "http://"},
+	{in: `"g-clef: \uD834\uDD1E"`, ptr: new(string), out: "g-clef: \U0001D11E"},
+	{in: `"invalid: \uD834x\uDD1E"`, ptr: new(string), out: "invalid: \uFFFDx\uFFFD"},
+	{in: "null", ptr: new(interface{}), out: nil},
+	{in: `{"X": [1,2,3], "Y": 4}`, ptr: new(T), out: T{Y: 4}, err: &UnmarshalTypeError{"array", reflect.TypeOf("")}},
+	{in: `{"x": 1}`, ptr: new(tx), out: tx{}},
+	{in: `{"F1":1,"F2":2,"F3":3}`, ptr: new(V), out: V{F1: float64(1), F2: int32(2), F3: Number("3")}},
+	{in: `{"F1":1,"F2":2,"F3":3}`, ptr: new(V), out: V{F1: Number("1"), F2: int32(2), F3: Number("3")}, useNumber: true},
+	{in: `{"k1":1,"k2":"s","k3":[1,2.0,3e-3],"k4":{"kk1":"s","kk2":2}}`, ptr: new(interface{}), out: ifaceNumAsFloat64},
+	{in: `{"k1":1,"k2":"s","k3":[1,2.0,3e-3],"k4":{"kk1":"s","kk2":2}}`, ptr: new(interface{}), out: ifaceNumAsNumber, useNumber: true},
+
+	// raw values with whitespace
+	{in: "\n true ", ptr: new(bool), out: true},
+	{in: "\t 1 ", ptr: new(int), out: 1},
+	{in: "\r 1.2 ", ptr: new(float64), out: 1.2},
+	{in: "\t -5 \n", ptr: new(int16), out: int16(-5)},
+	{in: "\t \"a\\u1234\" \n", ptr: new(string), out: "a\u1234"},
+
+	// Z has a "-" tag.
+	{in: `{"Y": 1, "Z": 2}`, ptr: new(T), out: T{Y: 1}},
+
+	{in: `{"alpha": "abc", "alphabet": "xyz"}`, ptr: new(U), out: U{Alphabet: "abc"}},
+	{in: `{"alpha": "abc"}`, ptr: new(U), out: U{Alphabet: "abc"}},
+	{in: `{"alphabet": "xyz"}`, ptr: new(U), out: U{}},
+
+	// syntax errors
+	{in: `{"X": "foo", "Y"}`, err: &SyntaxError{"invalid character '}' after object key", 17}},
+	{in: `[1, 2, 3+]`, err: &SyntaxError{"invalid character '+' after array element", 9}},
+	{in: `{"X":12x}`, err: &SyntaxError{"invalid character 'x' after object key:value pair", 8}, useNumber: true},
+
+	// raw value errors
+	{in: "\x01 42", err: &SyntaxError{"invalid character '\\x01' looking for beginning of value", 1}},
+	{in: " 42 \x01", err: &SyntaxError{"invalid character '\\x01' after top-level value", 5}},
+	{in: "\x01 true", err: &SyntaxError{"invalid character '\\x01' looking for beginning of value", 1}},
+	{in: " false \x01", err: &SyntaxError{"invalid character '\\x01' after top-level value", 8}},
+	{in: "\x01 1.2", err: &SyntaxError{"invalid character '\\x01' looking for beginning of value", 1}},
+	{in: " 3.4 \x01", err: &SyntaxError{"invalid character '\\x01' after top-level value", 6}},
+	{in: "\x01 \"string\"", err: &SyntaxError{"invalid character '\\x01' looking for beginning of value", 1}},
+	{in: " \"string\" \x01", err: &SyntaxError{"invalid character '\\x01' after top-level value", 11}},
+
+	// array tests
+	{in: `[1, 2, 3]`, ptr: new([3]int), out: [3]int{1, 2, 3}},
+	{in: `[1, 2, 3]`, ptr: new([1]int), out: [1]int{1}},
+	{in: `[1, 2, 3]`, ptr: new([5]int), out: [5]int{1, 2, 3, 0, 0}},
+
+	// empty array to interface test
+	{in: `[]`, ptr: new([]interface{}), out: []interface{}{}},
+	{in: `null`, ptr: new([]interface{}), out: []interface{}(nil)},
+	{in: `{"T":[]}`, ptr: new(map[string]interface{}), out: map[string]interface{}{"T": []interface{}{}}},
+	{in: `{"T":null}`, ptr: new(map[string]interface{}), out: map[string]interface{}{"T": interface{}(nil)}},
+
+	// composite tests
+	{in: allValueIndent, ptr: new(All), out: allValue},
+	{in: allValueCompact, ptr: new(All), out: allValue},
+	{in: allValueIndent, ptr: new(*All), out: &allValue},
+	{in: allValueCompact, ptr: new(*All), out: &allValue},
+	{in: pallValueIndent, ptr: new(All), out: pallValue},
+	{in: pallValueCompact, ptr: new(All), out: pallValue},
+	{in: pallValueIndent, ptr: new(*All), out: &pallValue},
+	{in: pallValueCompact, ptr: new(*All), out: &pallValue},
+
+	// unmarshal interface test
+	{in: `{"T":false}`, ptr: &um0, out: umtrue}, // use "false" so test will fail if custom unmarshaler is not called
+	{in: `{"T":false}`, ptr: &ump, out: &umtrue},
+	{in: `[{"T":false}]`, ptr: &umslice, out: umslice},
+	{in: `[{"T":false}]`, ptr: &umslicep, out: &umslice},
+	{in: `{"M":{"T":false}}`, ptr: &umstruct, out: umstruct},
+
+	// UnmarshalText interface test
+	{in: `"X"`, ptr: &um0T, out: umtrueT}, // use "false" so test will fail if custom unmarshaler is not called
+	{in: `"X"`, ptr: &umpT, out: &umtrueT},
+	{in: `["X"]`, ptr: &umsliceT, out: umsliceT},
+	{in: `["X"]`, ptr: &umslicepT, out: &umsliceT},
+	{in: `{"M":"X"}`, ptr: &umstructT, out: umstructT},
+
+	{
+		in: `{
+			"Level0": 1,
+			"Level1b": 2,
+			"Level1c": 3,
+			"x": 4,
+			"Level1a": 5,
+			"LEVEL1B": 6,
+			"e": {
+				"Level1a": 8,
+				"Level1b": 9,
+				"Level1c": 10,
+				"Level1d": 11,
+				"x": 12
+			},
+			"Loop1": 13,
+			"Loop2": 14,
+			"X": 15,
+			"Y": 16,
+			"Z": 17
+		}`,
+		ptr: new(Top),
+		out: Top{
+			Level0: 1,
+			Embed0: Embed0{
+				Level1b: 2,
+				Level1c: 3,
+			},
+			Embed0a: &Embed0a{
+				Level1a: 5,
+				Level1b: 6,
+			},
+			Embed0b: &Embed0b{
+				Level1a: 8,
+				Level1b: 9,
+				Level1c: 10,
+				Level1d: 11,
+				Level1e: 12,
+			},
+			Loop: Loop{
+				Loop1: 13,
+				Loop2: 14,
+			},
+			Embed0p: Embed0p{
+				Point: image.Point{X: 15, Y: 16},
+			},
+			Embed0q: Embed0q{
+				Point: Point{Z: 17},
+			},
+		},
+	},
+	{
+		in:  `{"hello": 1}`,
+		ptr: new(Ambig),
+		out: Ambig{First: 1},
+	},
+
+	{
+		in:  `{"X": 1,"Y":2}`,
+		ptr: new(S5),
+		out: S5{S8: S8{S9: S9{Y: 2}}},
+	},
+	{
+		in:  `{"X": 1,"Y":2}`,
+		ptr: new(S10),
+		out: S10{S13: S13{S8: S8{S9: S9{Y: 2}}}},
+	},
+
+	// invalid UTF-8 is coerced to valid UTF-8.
+	{
+		in:  "\"hello\xffworld\"",
+		ptr: new(string),
+		out: "hello\ufffdworld",
+	},
+	{
+		in:  "\"hello\xc2\xc2world\"",
+		ptr: new(string),
+		out: "hello\ufffd\ufffdworld",
+	},
+	{
+		in:  "\"hello\xc2\xffworld\"",
+		ptr: new(string),
+		out: "hello\ufffd\ufffdworld",
+	},
+	{
+		in:  "\"hello\\ud800world\"",
+		ptr: new(string),
+		out: "hello\ufffdworld",
+	},
+	{
+		in:  "\"hello\\ud800\\ud800world\"",
+		ptr: new(string),
+		out: "hello\ufffd\ufffdworld",
+	},
+	{
+		in:  "\"hello\\ud800\\ud800world\"",
+		ptr: new(string),
+		out: "hello\ufffd\ufffdworld",
+	},
+	{
+		in:  "\"hello\xed\xa0\x80\xed\xb0\x80world\"",
+		ptr: new(string),
+		out: "hello\ufffd\ufffd\ufffd\ufffd\ufffd\ufffdworld",
+	},
+
+	// issue 8305
+	{
+		in:  `{"2009-11-10T23:00:00Z": "hello world"}`,
+		ptr: &map[time.Time]string{},
+		err: &UnmarshalTypeError{"object", reflect.TypeOf(map[time.Time]string{})},
+	},
+}
+
+func TestMarshal(t *testing.T) {
+	b, err := Marshal(allValue)
+	if err != nil {
+		t.Fatalf("Marshal allValue: %v", err)
+	}
+	if string(b) != allValueCompact {
+		t.Errorf("Marshal allValueCompact")
+		diff(t, b, []byte(allValueCompact))
+		return
+	}
+
+	b, err = Marshal(pallValue)
+	if err != nil {
+		t.Fatalf("Marshal pallValue: %v", err)
+	}
+	if string(b) != pallValueCompact {
+		t.Errorf("Marshal pallValueCompact")
+		diff(t, b, []byte(pallValueCompact))
+		return
+	}
+}
+
+var badUTF8 = []struct {
+	in, out string
+}{
+	{"hello\xffworld", `"hello\ufffdworld"`},
+	{"", `""`},
+	{"\xff", `"\ufffd"`},
+	{"\xff\xff", `"\ufffd\ufffd"`},
+	{"a\xffb", `"a\ufffdb"`},
+	{"\xe6\x97\xa5\xe6\x9c\xac\xff\xaa\x9e", `"日本\ufffd\ufffd\ufffd"`},
+}
+
+func TestMarshalBadUTF8(t *testing.T) {
+	for _, tt := range badUTF8 {
+		b, err := Marshal(tt.in)
+		if string(b) != tt.out || err != nil {
+			t.Errorf("Marshal(%q) = %#q, %v, want %#q, nil", tt.in, b, err, tt.out)
+		}
+	}
+}
+
+func TestMarshalNumberZeroVal(t *testing.T) {
+	var n Number
+	out, err := Marshal(n)
+	if err != nil {
+		t.Fatal(err)
+	}
+	outStr := string(out)
+	if outStr != "0" {
+		t.Fatalf("Invalid zero val for Number: %q", outStr)
+	}
+}
+
+func TestMarshalEmbeds(t *testing.T) {
+	top := &Top{
+		Level0: 1,
+		Embed0: Embed0{
+			Level1b: 2,
+			Level1c: 3,
+		},
+		Embed0a: &Embed0a{
+			Level1a: 5,
+			Level1b: 6,
+		},
+		Embed0b: &Embed0b{
+			Level1a: 8,
+			Level1b: 9,
+			Level1c: 10,
+			Level1d: 11,
+			Level1e: 12,
+		},
+		Loop: Loop{
+			Loop1: 13,
+			Loop2: 14,
+		},
+		Embed0p: Embed0p{
+			Point: image.Point{X: 15, Y: 16},
+		},
+		Embed0q: Embed0q{
+			Point: Point{Z: 17},
+		},
+	}
+	b, err := Marshal(top)
+	if err != nil {
+		t.Fatal(err)
+	}
+	want := "{\"Level0\":1,\"Level1b\":2,\"Level1c\":3,\"Level1a\":5,\"LEVEL1B\":6,\"e\":{\"Level1a\":8,\"Level1b\":9,\"Level1c\":10,\"Level1d\":11,\"x\":12},\"Loop1\":13,\"Loop2\":14,\"X\":15,\"Y\":16,\"Z\":17}"
+	if string(b) != want {
+		t.Errorf("Wrong marshal result.\n got: %q\nwant: %q", b, want)
+	}
+}
+
+func TestUnmarshal(t *testing.T) {
+	for i, tt := range unmarshalTests {
+		var scan scanner
+		in := []byte(tt.in)
+		if err := checkValid(in, &scan); err != nil {
+			if !reflect.DeepEqual(err, tt.err) {
+				t.Errorf("#%d: checkValid: %#v", i, err)
+				continue
+			}
+		}
+		if tt.ptr == nil {
+			continue
+		}
+
+		// v = new(right-type)
+		v := reflect.New(reflect.TypeOf(tt.ptr).Elem())
+		dec := NewDecoder(bytes.NewReader(in))
+		if tt.useNumber {
+			dec.UseNumber()
+		}
+		if err := dec.Decode(v.Interface()); !reflect.DeepEqual(err, tt.err) {
+			t.Errorf("#%d: %v, want %v", i, err, tt.err)
+			continue
+		} else if err != nil {
+			continue
+		}
+		if !reflect.DeepEqual(v.Elem().Interface(), tt.out) {
+			t.Errorf("#%d: mismatch\nhave: %#+v\nwant: %#+v", i, v.Elem().Interface(), tt.out)
+			data, _ := Marshal(v.Elem().Interface())
+			println(string(data))
+			data, _ = Marshal(tt.out)
+			println(string(data))
+			continue
+		}
+
+		// Check round trip.
+		if tt.err == nil {
+			enc, err := Marshal(v.Interface())
+			if err != nil {
+				t.Errorf("#%d: error re-marshaling: %v", i, err)
+				continue
+			}
+			vv := reflect.New(reflect.TypeOf(tt.ptr).Elem())
+			dec = NewDecoder(bytes.NewReader(enc))
+			if tt.useNumber {
+				dec.UseNumber()
+			}
+			if err := dec.Decode(vv.Interface()); err != nil {
+				t.Errorf("#%d: error re-unmarshaling %#q: %v", i, enc, err)
+				continue
+			}
+			if !reflect.DeepEqual(v.Elem().Interface(), vv.Elem().Interface()) {
+				t.Errorf("#%d: mismatch\nhave: %#+v\nwant: %#+v", i, v.Elem().Interface(), vv.Elem().Interface())
+				t.Errorf("     In: %q", strings.Map(noSpace, string(in)))
+				t.Errorf("Marshal: %q", strings.Map(noSpace, string(enc)))
+				continue
+			}
+		}
+	}
+}
+
+func TestUnmarshalMarshal(t *testing.T) {
+	initBig()
+	var v interface{}
+	if err := Unmarshal(jsonBig, &v); err != nil {
+		t.Fatalf("Unmarshal: %v", err)
+	}
+	b, err := Marshal(v)
+	if err != nil {
+		t.Fatalf("Marshal: %v", err)
+	}
+	if !bytes.Equal(jsonBig, b) {
+		t.Errorf("Marshal jsonBig")
+		diff(t, b, jsonBig)
+		return
+	}
+}
+
+var numberTests = []struct {
+	in       string
+	i        int64
+	intErr   string
+	f        float64
+	floatErr string
+}{
+	{in: "-1.23e1", intErr: "strconv.ParseInt: parsing \"-1.23e1\": invalid syntax", f: -1.23e1},
+	{in: "-12", i: -12, f: -12.0},
+	{in: "1e1000", intErr: "strconv.ParseInt: parsing \"1e1000\": invalid syntax", floatErr: "strconv.ParseFloat: parsing \"1e1000\": value out of range"},
+}
+
+// Independent of Decode, basic coverage of the accessors in Number
+func TestNumberAccessors(t *testing.T) {
+	for _, tt := range numberTests {
+		n := Number(tt.in)
+		if s := n.String(); s != tt.in {
+			t.Errorf("Number(%q).String() is %q", tt.in, s)
+		}
+		if i, err := n.Int64(); err == nil && tt.intErr == "" && i != tt.i {
+			t.Errorf("Number(%q).Int64() is %d", tt.in, i)
+		} else if (err == nil && tt.intErr != "") || (err != nil && err.Error() != tt.intErr) {
+			t.Errorf("Number(%q).Int64() wanted error %q but got: %v", tt.in, tt.intErr, err)
+		}
+		if f, err := n.Float64(); err == nil && tt.floatErr == "" && f != tt.f {
+			t.Errorf("Number(%q).Float64() is %g", tt.in, f)
+		} else if (err == nil && tt.floatErr != "") || (err != nil && err.Error() != tt.floatErr) {
+			t.Errorf("Number(%q).Float64() wanted error %q but got: %v", tt.in, tt.floatErr, err)
+		}
+	}
+}
+
+func TestLargeByteSlice(t *testing.T) {
+	s0 := make([]byte, 2000)
+	for i := range s0 {
+		s0[i] = byte(i)
+	}
+	b, err := Marshal(s0)
+	if err != nil {
+		t.Fatalf("Marshal: %v", err)
+	}
+	var s1 []byte
+	if err := Unmarshal(b, &s1); err != nil {
+		t.Fatalf("Unmarshal: %v", err)
+	}
+	if !bytes.Equal(s0, s1) {
+		t.Errorf("Marshal large byte slice")
+		diff(t, s0, s1)
+	}
+}
+
+type Xint struct {
+	X int
+}
+
+func TestUnmarshalInterface(t *testing.T) {
+	var xint Xint
+	var i interface{} = &xint
+	if err := Unmarshal([]byte(`{"X":1}`), &i); err != nil {
+		t.Fatalf("Unmarshal: %v", err)
+	}
+	if xint.X != 1 {
+		t.Fatalf("Did not write to xint")
+	}
+}
+
+func TestUnmarshalPtrPtr(t *testing.T) {
+	var xint Xint
+	pxint := &xint
+	if err := Unmarshal([]byte(`{"X":1}`), &pxint); err != nil {
+		t.Fatalf("Unmarshal: %v", err)
+	}
+	if xint.X != 1 {
+		t.Fatalf("Did not write to xint")
+	}
+}
+
+func TestEscape(t *testing.T) {
+	const input = `"foobar"<html>` + " [\u2028 \u2029]"
+	const expected = `"\"foobar\"\u003chtml\u003e [\u2028 \u2029]"`
+	b, err := Marshal(input)
+	if err != nil {
+		t.Fatalf("Marshal error: %v", err)
+	}
+	if s := string(b); s != expected {
+		t.Errorf("Encoding of [%s]:\n got [%s]\nwant [%s]", input, s, expected)
+	}
+}
+
+// WrongString is a struct that's misusing the ,string modifier.
+type WrongString struct {
+	Message string `json:"result,string"`
+}
+
+type wrongStringTest struct {
+	in, err string
+}
+
+var wrongStringTests = []wrongStringTest{
+	{`{"result":"x"}`, `json: invalid use of ,string struct tag, trying to unmarshal "x" into string`},
+	{`{"result":"foo"}`, `json: invalid use of ,string struct tag, trying to unmarshal "foo" into string`},
+	{`{"result":"123"}`, `json: invalid use of ,string struct tag, trying to unmarshal "123" into string`},
+}
+
+// If people misuse the ,string modifier, the error message should be
+// helpful, telling the user that they're doing it wrong.
+func TestErrorMessageFromMisusedString(t *testing.T) {
+	for n, tt := range wrongStringTests {
+		r := strings.NewReader(tt.in)
+		var s WrongString
+		err := NewDecoder(r).Decode(&s)
+		got := fmt.Sprintf("%v", err)
+		if got != tt.err {
+			t.Errorf("%d. got err = %q, want %q", n, got, tt.err)
+		}
+	}
+}
+
+func noSpace(c rune) rune {
+	if isSpace(c) {
+		return -1
+	}
+	return c
+}
+
+type All struct {
+	Bool    bool
+	Int     int
+	Int8    int8
+	Int16   int16
+	Int32   int32
+	Int64   int64
+	Uint    uint
+	Uint8   uint8
+	Uint16  uint16
+	Uint32  uint32
+	Uint64  uint64
+	Uintptr uintptr
+	Float32 float32
+	Float64 float64
+
+	Foo  string `json:"bar"`
+	Foo2 string `json:"bar2,dummyopt"`
+
+	IntStr int64 `json:",string"`
+
+	PBool    *bool
+	PInt     *int
+	PInt8    *int8
+	PInt16   *int16
+	PInt32   *int32
+	PInt64   *int64
+	PUint    *uint
+	PUint8   *uint8
+	PUint16  *uint16
+	PUint32  *uint32
+	PUint64  *uint64
+	PUintptr *uintptr
+	PFloat32 *float32
+	PFloat64 *float64
+
+	String  string
+	PString *string
+
+	Map   map[string]Small
+	MapP  map[string]*Small
+	PMap  *map[string]Small
+	PMapP *map[string]*Small
+
+	EmptyMap map[string]Small
+	NilMap   map[string]Small
+
+	Slice   []Small
+	SliceP  []*Small
+	PSlice  *[]Small
+	PSliceP *[]*Small
+
+	EmptySlice []Small
+	NilSlice   []Small
+
+	StringSlice []string
+	ByteSlice   []byte
+
+	Small   Small
+	PSmall  *Small
+	PPSmall **Small
+
+	Interface  interface{}
+	PInterface *interface{}
+
+	unexported int
+}
+
+type Small struct {
+	Tag string
+}
+
+var allValue = All{
+	Bool:    true,
+	Int:     2,
+	Int8:    3,
+	Int16:   4,
+	Int32:   5,
+	Int64:   6,
+	Uint:    7,
+	Uint8:   8,
+	Uint16:  9,
+	Uint32:  10,
+	Uint64:  11,
+	Uintptr: 12,
+	Float32: 14.1,
+	Float64: 15.1,
+	Foo:     "foo",
+	Foo2:    "foo2",
+	IntStr:  42,
+	String:  "16",
+	Map: map[string]Small{
+		"17": {Tag: "tag17"},
+		"18": {Tag: "tag18"},
+	},
+	MapP: map[string]*Small{
+		"19": {Tag: "tag19"},
+		"20": nil,
+	},
+	EmptyMap:    map[string]Small{},
+	Slice:       []Small{{Tag: "tag20"}, {Tag: "tag21"}},
+	SliceP:      []*Small{{Tag: "tag22"}, nil, {Tag: "tag23"}},
+	EmptySlice:  []Small{},
+	StringSlice: []string{"str24", "str25", "str26"},
+	ByteSlice:   []byte{27, 28, 29},
+	Small:       Small{Tag: "tag30"},
+	PSmall:      &Small{Tag: "tag31"},
+	Interface:   5.2,
+}
+
+var pallValue = All{
+	PBool:      &allValue.Bool,
+	PInt:       &allValue.Int,
+	PInt8:      &allValue.Int8,
+	PInt16:     &allValue.Int16,
+	PInt32:     &allValue.Int32,
+	PInt64:     &allValue.Int64,
+	PUint:      &allValue.Uint,
+	PUint8:     &allValue.Uint8,
+	PUint16:    &allValue.Uint16,
+	PUint32:    &allValue.Uint32,
+	PUint64:    &allValue.Uint64,
+	PUintptr:   &allValue.Uintptr,
+	PFloat32:   &allValue.Float32,
+	PFloat64:   &allValue.Float64,
+	PString:    &allValue.String,
+	PMap:       &allValue.Map,
+	PMapP:      &allValue.MapP,
+	PSlice:     &allValue.Slice,
+	PSliceP:    &allValue.SliceP,
+	PPSmall:    &allValue.PSmall,
+	PInterface: &allValue.Interface,
+}
+
+var allValueIndent = `{
+	"Bool": true,
+	"Int": 2,
+	"Int8": 3,
+	"Int16": 4,
+	"Int32": 5,
+	"Int64": 6,
+	"Uint": 7,
+	"Uint8": 8,
+	"Uint16": 9,
+	"Uint32": 10,
+	"Uint64": 11,
+	"Uintptr": 12,
+	"Float32": 14.1,
+	"Float64": 15.1,
+	"bar": "foo",
+	"bar2": "foo2",
+	"IntStr": "42",
+	"PBool": null,
+	"PInt": null,
+	"PInt8": null,
+	"PInt16": null,
+	"PInt32": null,
+	"PInt64": null,
+	"PUint": null,
+	"PUint8": null,
+	"PUint16": null,
+	"PUint32": null,
+	"PUint64": null,
+	"PUintptr": null,
+	"PFloat32": null,
+	"PFloat64": null,
+	"String": "16",
+	"PString": null,
+	"Map": {
+		"17": {
+			"Tag": "tag17"
+		},
+		"18": {
+			"Tag": "tag18"
+		}
+	},
+	"MapP": {
+		"19": {
+			"Tag": "tag19"
+		},
+		"20": null
+	},
+	"PMap": null,
+	"PMapP": null,
+	"EmptyMap": {},
+	"NilMap": null,
+	"Slice": [
+		{
+			"Tag": "tag20"
+		},
+		{
+			"Tag": "tag21"
+		}
+	],
+	"SliceP": [
+		{
+			"Tag": "tag22"
+		},
+		null,
+		{
+			"Tag": "tag23"
+		}
+	],
+	"PSlice": null,
+	"PSliceP": null,
+	"EmptySlice": [],
+	"NilSlice": null,
+	"StringSlice": [
+		"str24",
+		"str25",
+		"str26"
+	],
+	"ByteSlice": "Gxwd",
+	"Small": {
+		"Tag": "tag30"
+	},
+	"PSmall": {
+		"Tag": "tag31"
+	},
+	"PPSmall": null,
+	"Interface": 5.2,
+	"PInterface": null
+}`
+
+var allValueCompact = strings.Map(noSpace, allValueIndent)
+
+var pallValueIndent = `{
+	"Bool": false,
+	"Int": 0,
+	"Int8": 0,
+	"Int16": 0,
+	"Int32": 0,
+	"Int64": 0,
+	"Uint": 0,
+	"Uint8": 0,
+	"Uint16": 0,
+	"Uint32": 0,
+	"Uint64": 0,
+	"Uintptr": 0,
+	"Float32": 0,
+	"Float64": 0,
+	"bar": "",
+	"bar2": "",
+        "IntStr": "0",
+	"PBool": true,
+	"PInt": 2,
+	"PInt8": 3,
+	"PInt16": 4,
+	"PInt32": 5,
+	"PInt64": 6,
+	"PUint": 7,
+	"PUint8": 8,
+	"PUint16": 9,
+	"PUint32": 10,
+	"PUint64": 11,
+	"PUintptr": 12,
+	"PFloat32": 14.1,
+	"PFloat64": 15.1,
+	"String": "",
+	"PString": "16",
+	"Map": null,
+	"MapP": null,
+	"PMap": {
+		"17": {
+			"Tag": "tag17"
+		},
+		"18": {
+			"Tag": "tag18"
+		}
+	},
+	"PMapP": {
+		"19": {
+			"Tag": "tag19"
+		},
+		"20": null
+	},
+	"EmptyMap": null,
+	"NilMap": null,
+	"Slice": null,
+	"SliceP": null,
+	"PSlice": [
+		{
+			"Tag": "tag20"
+		},
+		{
+			"Tag": "tag21"
+		}
+	],
+	"PSliceP": [
+		{
+			"Tag": "tag22"
+		},
+		null,
+		{
+			"Tag": "tag23"
+		}
+	],
+	"EmptySlice": null,
+	"NilSlice": null,
+	"StringSlice": null,
+	"ByteSlice": null,
+	"Small": {
+		"Tag": ""
+	},
+	"PSmall": null,
+	"PPSmall": {
+		"Tag": "tag31"
+	},
+	"Interface": null,
+	"PInterface": 5.2
+}`
+
+var pallValueCompact = strings.Map(noSpace, pallValueIndent)
+
+func TestRefUnmarshal(t *testing.T) {
+	type S struct {
+		// Ref is defined in encode_test.go.
+		R0 Ref
+		R1 *Ref
+		R2 RefText
+		R3 *RefText
+	}
+	want := S{
+		R0: 12,
+		R1: new(Ref),
+		R2: 13,
+		R3: new(RefText),
+	}
+	*want.R1 = 12
+	*want.R3 = 13
+
+	var got S
+	if err := Unmarshal([]byte(`{"R0":"ref","R1":"ref","R2":"ref","R3":"ref"}`), &got); err != nil {
+		t.Fatalf("Unmarshal: %v", err)
+	}
+	if !reflect.DeepEqual(got, want) {
+		t.Errorf("got %+v, want %+v", got, want)
+	}
+}
+
+// Test that the empty string doesn't panic decoding when ,string is specified
+// Issue 3450
+func TestEmptyString(t *testing.T) {
+	type T2 struct {
+		Number1 int `json:",string"`
+		Number2 int `json:",string"`
+	}
+	data := `{"Number1":"1", "Number2":""}`
+	dec := NewDecoder(strings.NewReader(data))
+	var t2 T2
+	err := dec.Decode(&t2)
+	if err == nil {
+		t.Fatal("Decode: did not return error")
+	}
+	if t2.Number1 != 1 {
+		t.Fatal("Decode: did not set Number1")
+	}
+}
+
+// Test that a null for ,string is not replaced with the previous quoted string (issue 7046).
+// It should also not be an error (issue 2540, issue 8587).
+func TestNullString(t *testing.T) {
+	type T struct {
+		A int  `json:",string"`
+		B int  `json:",string"`
+		C *int `json:",string"`
+	}
+	data := []byte(`{"A": "1", "B": null, "C": null}`)
+	var s T
+	s.B = 1
+	s.C = new(int)
+	*s.C = 2
+	err := Unmarshal(data, &s)
+	if err != nil {
+		t.Fatalf("Unmarshal: %v")
+	}
+	if s.B != 1 || s.C != nil {
+		t.Fatalf("after Unmarshal, s.B=%d, s.C=%p, want 1, nil", s.B, s.C)
+	}
+}
+
+func intp(x int) *int {
+	p := new(int)
+	*p = x
+	return p
+}
+
+func intpp(x *int) **int {
+	pp := new(*int)
+	*pp = x
+	return pp
+}
+
+var interfaceSetTests = []struct {
+	pre  interface{}
+	json string
+	post interface{}
+}{
+	{"foo", `"bar"`, "bar"},
+	{"foo", `2`, 2.0},
+	{"foo", `true`, true},
+	{"foo", `null`, nil},
+
+	{nil, `null`, nil},
+	{new(int), `null`, nil},
+	{(*int)(nil), `null`, nil},
+	{new(*int), `null`, new(*int)},
+	{(**int)(nil), `null`, nil},
+	{intp(1), `null`, nil},
+	{intpp(nil), `null`, intpp(nil)},
+	{intpp(intp(1)), `null`, intpp(nil)},
+}
+
+func TestInterfaceSet(t *testing.T) {
+	for _, tt := range interfaceSetTests {
+		b := struct{ X interface{} }{tt.pre}
+		blob := `{"X":` + tt.json + `}`
+		if err := Unmarshal([]byte(blob), &b); err != nil {
+			t.Errorf("Unmarshal %#q: %v", blob, err)
+			continue
+		}
+		if !reflect.DeepEqual(b.X, tt.post) {
+			t.Errorf("Unmarshal %#q into %#v: X=%#v, want %#v", blob, tt.pre, b.X, tt.post)
+		}
+	}
+}
+
+// JSON null values should be ignored for primitives and string values instead of resulting in an error.
+// Issue 2540
+func TestUnmarshalNulls(t *testing.T) {
+	jsonData := []byte(`{
+		"Bool"    : null,
+		"Int"     : null,
+		"Int8"    : null,
+		"Int16"   : null,
+		"Int32"   : null,
+		"Int64"   : null,
+		"Uint"    : null,
+		"Uint8"   : null,
+		"Uint16"  : null,
+		"Uint32"  : null,
+		"Uint64"  : null,
+		"Float32" : null,
+		"Float64" : null,
+		"String"  : null}`)
+
+	nulls := All{
+		Bool:    true,
+		Int:     2,
+		Int8:    3,
+		Int16:   4,
+		Int32:   5,
+		Int64:   6,
+		Uint:    7,
+		Uint8:   8,
+		Uint16:  9,
+		Uint32:  10,
+		Uint64:  11,
+		Float32: 12.1,
+		Float64: 13.1,
+		String:  "14"}
+
+	err := Unmarshal(jsonData, &nulls)
+	if err != nil {
+		t.Errorf("Unmarshal of null values failed: %v", err)
+	}
+	if !nulls.Bool || nulls.Int != 2 || nulls.Int8 != 3 || nulls.Int16 != 4 || nulls.Int32 != 5 || nulls.Int64 != 6 ||
+		nulls.Uint != 7 || nulls.Uint8 != 8 || nulls.Uint16 != 9 || nulls.Uint32 != 10 || nulls.Uint64 != 11 ||
+		nulls.Float32 != 12.1 || nulls.Float64 != 13.1 || nulls.String != "14" {
+
+		t.Errorf("Unmarshal of null values affected primitives")
+	}
+}
+
+func TestStringKind(t *testing.T) {
+	type stringKind string
+
+	var m1, m2 map[stringKind]int
+	m1 = map[stringKind]int{
+		"foo": 42,
+	}
+
+	data, err := Marshal(m1)
+	if err != nil {
+		t.Errorf("Unexpected error marshalling: %v", err)
+	}
+
+	err = Unmarshal(data, &m2)
+	if err != nil {
+		t.Errorf("Unexpected error unmarshalling: %v", err)
+	}
+
+	if !reflect.DeepEqual(m1, m2) {
+		t.Error("Items should be equal after encoding and then decoding")
+	}
+
+}
+
+var decodeTypeErrorTests = []struct {
+	dest interface{}
+	src  string
+}{
+	{new(string), `{"user": "name"}`}, // issue 4628.
+	{new(error), `{}`},                // issue 4222
+	{new(error), `[]`},
+	{new(error), `""`},
+	{new(error), `123`},
+	{new(error), `true`},
+}
+
+func TestUnmarshalTypeError(t *testing.T) {
+	for _, item := range decodeTypeErrorTests {
+		err := Unmarshal([]byte(item.src), item.dest)
+		if _, ok := err.(*UnmarshalTypeError); !ok {
+			t.Errorf("expected type error for Unmarshal(%q, type %T): got %T",
+				item.src, item.dest, err)
+		}
+	}
+}
+
+var unmarshalSyntaxTests = []string{
+	"tru",
+	"fals",
+	"nul",
+	"123e",
+	`"hello`,
+	`[1,2,3`,
+	`{"key":1`,
+	`{"key":1,`,
+}
+
+func TestUnmarshalSyntax(t *testing.T) {
+	var x interface{}
+	for _, src := range unmarshalSyntaxTests {
+		err := Unmarshal([]byte(src), &x)
+		if _, ok := err.(*SyntaxError); !ok {
+			t.Errorf("expected syntax error for Unmarshal(%q): got %T", src, err)
+		}
+	}
+}
+
+// Test handling of unexported fields that should be ignored.
+// Issue 4660
+type unexportedFields struct {
+	Name string
+	m    map[string]interface{} `json:"-"`
+	m2   map[string]interface{} `json:"abcd"`
+}
+
+func TestUnmarshalUnexported(t *testing.T) {
+	input := `{"Name": "Bob", "m": {"x": 123}, "m2": {"y": 456}, "abcd": {"z": 789}}`
+	want := &unexportedFields{Name: "Bob"}
+
+	out := &unexportedFields{}
+	err := Unmarshal([]byte(input), out)
+	if err != nil {
+		t.Errorf("got error %v, expected nil", err)
+	}
+	if !reflect.DeepEqual(out, want) {
+		t.Errorf("got %q, want %q", out, want)
+	}
+}
+
+// Time3339 is a time.Time which encodes to and from JSON
+// as an RFC 3339 time in UTC.
+type Time3339 time.Time
+
+func (t *Time3339) UnmarshalJSON(b []byte) error {
+	if len(b) < 2 || b[0] != '"' || b[len(b)-1] != '"' {
+		return fmt.Errorf("types: failed to unmarshal non-string value %q as an RFC 3339 time", b)
+	}
+	tm, err := time.Parse(time.RFC3339, string(b[1:len(b)-1]))
+	if err != nil {
+		return err
+	}
+	*t = Time3339(tm)
+	return nil
+}
+
+func TestUnmarshalJSONLiteralError(t *testing.T) {
+	var t3 Time3339
+	err := Unmarshal([]byte(`"0000-00-00T00:00:00Z"`), &t3)
+	if err == nil {
+		t.Fatalf("expected error; got time %v", time.Time(t3))
+	}
+	if !strings.Contains(err.Error(), "range") {
+		t.Errorf("got err = %v; want out of range error", err)
+	}
+}
+
+// Test that extra object elements in an array do not result in a
+// "data changing underfoot" error.
+// Issue 3717
+func TestSkipArrayObjects(t *testing.T) {
+	json := `[{}]`
+	var dest [0]interface{}
+
+	err := Unmarshal([]byte(json), &dest)
+	if err != nil {
+		t.Errorf("got error %q, want nil", err)
+	}
+}
+
+// Test semantics of pre-filled struct fields and pre-filled map fields.
+// Issue 4900.
+func TestPrefilled(t *testing.T) {
+	ptrToMap := func(m map[string]interface{}) *map[string]interface{} { return &m }
+
+	// Values here change, cannot reuse table across runs.
+	var prefillTests = []struct {
+		in  string
+		ptr interface{}
+		out interface{}
+	}{
+		{
+			in:  `{"X": 1, "Y": 2}`,
+			ptr: &XYZ{X: float32(3), Y: int16(4), Z: 1.5},
+			out: &XYZ{X: float64(1), Y: float64(2), Z: 1.5},
+		},
+		{
+			in:  `{"X": 1, "Y": 2}`,
+			ptr: ptrToMap(map[string]interface{}{"X": float32(3), "Y": int16(4), "Z": 1.5}),
+			out: ptrToMap(map[string]interface{}{"X": float64(1), "Y": float64(2), "Z": 1.5}),
+		},
+	}
+
+	for _, tt := range prefillTests {
+		ptrstr := fmt.Sprintf("%v", tt.ptr)
+		err := Unmarshal([]byte(tt.in), tt.ptr) // tt.ptr edited here
+		if err != nil {
+			t.Errorf("Unmarshal: %v", err)
+		}
+		if !reflect.DeepEqual(tt.ptr, tt.out) {
+			t.Errorf("Unmarshal(%#q, %s): have %v, want %v", tt.in, ptrstr, tt.ptr, tt.out)
+		}
+	}
+}
+
+var invalidUnmarshalTests = []struct {
+	v    interface{}
+	want string
+}{
+	{nil, "json: Unmarshal(nil)"},
+	{struct{}{}, "json: Unmarshal(non-pointer struct {})"},
+	{(*int)(nil), "json: Unmarshal(nil *int)"},
+}
+
+func TestInvalidUnmarshal(t *testing.T) {
+	buf := []byte(`{"a":"1"}`)
+	for _, tt := range invalidUnmarshalTests {
+		err := Unmarshal(buf, tt.v)
+		if err == nil {
+			t.Errorf("Unmarshal expecting error, got nil")
+			continue
+		}
+		if got := err.Error(); got != tt.want {
+			t.Errorf("Unmarshal = %q; want %q", got, tt.want)
+		}
+	}
+}
diff --git a/src/encoding/json/encode.go b/src/encoding/json/encode.go
new file mode 100644
index 0000000..fca2a09
--- /dev/null
+++ b/src/encoding/json/encode.go
@@ -0,0 +1,1183 @@
+// Copyright 2010 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package json implements encoding and decoding of JSON objects as defined in
+// RFC 4627. The mapping between JSON objects and Go values is described
+// in the documentation for the Marshal and Unmarshal functions.
+//
+// See "JSON and Go" for an introduction to this package:
+// http://golang.org/doc/articles/json_and_go.html
+package json
+
+import (
+	"bytes"
+	"encoding"
+	"encoding/base64"
+	"math"
+	"reflect"
+	"runtime"
+	"sort"
+	"strconv"
+	"strings"
+	"sync"
+	"unicode"
+	"unicode/utf8"
+)
+
+// Marshal returns the JSON encoding of v.
+//
+// Marshal traverses the value v recursively.
+// If an encountered value implements the Marshaler interface
+// and is not a nil pointer, Marshal calls its MarshalJSON method
+// to produce JSON.  The nil pointer exception is not strictly necessary
+// but mimics a similar, necessary exception in the behavior of
+// UnmarshalJSON.
+//
+// Otherwise, Marshal uses the following type-dependent default encodings:
+//
+// Boolean values encode as JSON booleans.
+//
+// Floating point, integer, and Number values encode as JSON numbers.
+//
+// String values encode as JSON strings coerced to valid UTF-8,
+// replacing invalid bytes with the Unicode replacement rune.
+// The angle brackets "<" and ">" are escaped to "\u003c" and "\u003e"
+// to keep some browsers from misinterpreting JSON output as HTML.
+// Ampersand "&" is also escaped to "\u0026" for the same reason.
+//
+// Array and slice values encode as JSON arrays, except that
+// []byte encodes as a base64-encoded string, and a nil slice
+// encodes as the null JSON object.
+//
+// Struct values encode as JSON objects. Each exported struct field
+// becomes a member of the object unless
+//   - the field's tag is "-", or
+//   - the field is empty and its tag specifies the "omitempty" option.
+// The empty values are false, 0, any
+// nil pointer or interface value, and any array, slice, map, or string of
+// length zero. The object's default key string is the struct field name
+// but can be specified in the struct field's tag value. The "json" key in
+// the struct field's tag value is the key name, followed by an optional comma
+// and options. Examples:
+//
+//   // Field is ignored by this package.
+//   Field int `json:"-"`
+//
+//   // Field appears in JSON as key "myName".
+//   Field int `json:"myName"`
+//
+//   // Field appears in JSON as key "myName" and
+//   // the field is omitted from the object if its value is empty,
+//   // as defined above.
+//   Field int `json:"myName,omitempty"`
+//
+//   // Field appears in JSON as key "Field" (the default), but
+//   // the field is skipped if empty.
+//   // Note the leading comma.
+//   Field int `json:",omitempty"`
+//
+// The "string" option signals that a field is stored as JSON inside a
+// JSON-encoded string. It applies only to fields of string, floating point,
+// or integer types. This extra level of encoding is sometimes used when
+// communicating with JavaScript programs:
+//
+//    Int64String int64 `json:",string"`
+//
+// The key name will be used if it's a non-empty string consisting of
+// only Unicode letters, digits, dollar signs, percent signs, hyphens,
+// underscores and slashes.
+//
+// Anonymous struct fields are usually marshaled as if their inner exported fields
+// were fields in the outer struct, subject to the usual Go visibility rules amended
+// as described in the next paragraph.
+// An anonymous struct field with a name given in its JSON tag is treated as
+// having that name, rather than being anonymous.
+// An anonymous struct field of interface type is treated the same as having
+// that type as its name, rather than being anonymous.
+//
+// The Go visibility rules for struct fields are amended for JSON when
+// deciding which field to marshal or unmarshal. If there are
+// multiple fields at the same level, and that level is the least
+// nested (and would therefore be the nesting level selected by the
+// usual Go rules), the following extra rules apply:
+//
+// 1) Of those fields, if any are JSON-tagged, only tagged fields are considered,
+// even if there are multiple untagged fields that would otherwise conflict.
+// 2) If there is exactly one field (tagged or not according to the first rule), that is selected.
+// 3) Otherwise there are multiple fields, and all are ignored; no error occurs.
+//
+// Handling of anonymous struct fields is new in Go 1.1.
+// Prior to Go 1.1, anonymous struct fields were ignored. To force ignoring of
+// an anonymous struct field in both current and earlier versions, give the field
+// a JSON tag of "-".
+//
+// Map values encode as JSON objects.
+// The map's key type must be string; the object keys are used directly
+// as map keys.
+//
+// Pointer values encode as the value pointed to.
+// A nil pointer encodes as the null JSON object.
+//
+// Interface values encode as the value contained in the interface.
+// A nil interface value encodes as the null JSON object.
+//
+// Channel, complex, and function values cannot be encoded in JSON.
+// Attempting to encode such a value causes Marshal to return
+// an UnsupportedTypeError.
+//
+// JSON cannot represent cyclic data structures and Marshal does not
+// handle them.  Passing cyclic structures to Marshal will result in
+// an infinite recursion.
+//
+func Marshal(v interface{}) ([]byte, error) {
+	e := &encodeState{}
+	err := e.marshal(v)
+	if err != nil {
+		return nil, err
+	}
+	return e.Bytes(), nil
+}
+
+// MarshalIndent is like Marshal but applies Indent to format the output.
+func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) {
+	b, err := Marshal(v)
+	if err != nil {
+		return nil, err
+	}
+	var buf bytes.Buffer
+	err = Indent(&buf, b, prefix, indent)
+	if err != nil {
+		return nil, err
+	}
+	return buf.Bytes(), nil
+}
+
+// HTMLEscape appends to dst the JSON-encoded src with <, >, &, U+2028 and U+2029
+// characters inside string literals changed to \u003c, \u003e, \u0026, \u2028, \u2029
+// so that the JSON will be safe to embed inside HTML <script> tags.
+// For historical reasons, web browsers don't honor standard HTML
+// escaping within <script> tags, so an alternative JSON encoding must
+// be used.
+func HTMLEscape(dst *bytes.Buffer, src []byte) {
+	// The characters can only appear in string literals,
+	// so just scan the string one byte at a time.
+	start := 0
+	for i, c := range src {
+		if c == '<' || c == '>' || c == '&' {
+			if start < i {
+				dst.Write(src[start:i])
+			}
+			dst.WriteString(`\u00`)
+			dst.WriteByte(hex[c>>4])
+			dst.WriteByte(hex[c&0xF])
+			start = i + 1
+		}
+		// Convert U+2028 and U+2029 (E2 80 A8 and E2 80 A9).
+		if c == 0xE2 && i+2 < len(src) && src[i+1] == 0x80 && src[i+2]&^1 == 0xA8 {
+			if start < i {
+				dst.Write(src[start:i])
+			}
+			dst.WriteString(`\u202`)
+			dst.WriteByte(hex[src[i+2]&0xF])
+			start = i + 3
+		}
+	}
+	if start < len(src) {
+		dst.Write(src[start:])
+	}
+}
+
+// Marshaler is the interface implemented by objects that
+// can marshal themselves into valid JSON.
+type Marshaler interface {
+	MarshalJSON() ([]byte, error)
+}
+
+// An UnsupportedTypeError is returned by Marshal when attempting
+// to encode an unsupported value type.
+type UnsupportedTypeError struct {
+	Type reflect.Type
+}
+
+func (e *UnsupportedTypeError) Error() string {
+	return "json: unsupported type: " + e.Type.String()
+}
+
+type UnsupportedValueError struct {
+	Value reflect.Value
+	Str   string
+}
+
+func (e *UnsupportedValueError) Error() string {
+	return "json: unsupported value: " + e.Str
+}
+
+// Before Go 1.2, an InvalidUTF8Error was returned by Marshal when
+// attempting to encode a string value with invalid UTF-8 sequences.
+// As of Go 1.2, Marshal instead coerces the string to valid UTF-8 by
+// replacing invalid bytes with the Unicode replacement rune U+FFFD.
+// This error is no longer generated but is kept for backwards compatibility
+// with programs that might mention it.
+type InvalidUTF8Error struct {
+	S string // the whole string value that caused the error
+}
+
+func (e *InvalidUTF8Error) Error() string {
+	return "json: invalid UTF-8 in string: " + strconv.Quote(e.S)
+}
+
+type MarshalerError struct {
+	Type reflect.Type
+	Err  error
+}
+
+func (e *MarshalerError) Error() string {
+	return "json: error calling MarshalJSON for type " + e.Type.String() + ": " + e.Err.Error()
+}
+
+var hex = "0123456789abcdef"
+
+// An encodeState encodes JSON into a bytes.Buffer.
+type encodeState struct {
+	bytes.Buffer // accumulated output
+	scratch      [64]byte
+}
+
+var encodeStatePool sync.Pool
+
+func newEncodeState() *encodeState {
+	if v := encodeStatePool.Get(); v != nil {
+		e := v.(*encodeState)
+		e.Reset()
+		return e
+	}
+	return new(encodeState)
+}
+
+func (e *encodeState) marshal(v interface{}) (err error) {
+	defer func() {
+		if r := recover(); r != nil {
+			if _, ok := r.(runtime.Error); ok {
+				panic(r)
+			}
+			if s, ok := r.(string); ok {
+				panic(s)
+			}
+			err = r.(error)
+		}
+	}()
+	e.reflectValue(reflect.ValueOf(v))
+	return nil
+}
+
+func (e *encodeState) error(err error) {
+	panic(err)
+}
+
+var byteSliceType = reflect.TypeOf([]byte(nil))
+
+func isEmptyValue(v reflect.Value) bool {
+	switch v.Kind() {
+	case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
+		return v.Len() == 0
+	case reflect.Bool:
+		return !v.Bool()
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		return v.Int() == 0
+	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+		return v.Uint() == 0
+	case reflect.Float32, reflect.Float64:
+		return v.Float() == 0
+	case reflect.Interface, reflect.Ptr:
+		return v.IsNil()
+	}
+	return false
+}
+
+func (e *encodeState) reflectValue(v reflect.Value) {
+	valueEncoder(v)(e, v, false)
+}
+
+type encoderFunc func(e *encodeState, v reflect.Value, quoted bool)
+
+var encoderCache struct {
+	sync.RWMutex
+	m map[reflect.Type]encoderFunc
+}
+
+func valueEncoder(v reflect.Value) encoderFunc {
+	if !v.IsValid() {
+		return invalidValueEncoder
+	}
+	return typeEncoder(v.Type())
+}
+
+func typeEncoder(t reflect.Type) encoderFunc {
+	encoderCache.RLock()
+	f := encoderCache.m[t]
+	encoderCache.RUnlock()
+	if f != nil {
+		return f
+	}
+
+	// To deal with recursive types, populate the map with an
+	// indirect func before we build it. This type waits on the
+	// real func (f) to be ready and then calls it.  This indirect
+	// func is only used for recursive types.
+	encoderCache.Lock()
+	if encoderCache.m == nil {
+		encoderCache.m = make(map[reflect.Type]encoderFunc)
+	}
+	var wg sync.WaitGroup
+	wg.Add(1)
+	encoderCache.m[t] = func(e *encodeState, v reflect.Value, quoted bool) {
+		wg.Wait()
+		f(e, v, quoted)
+	}
+	encoderCache.Unlock()
+
+	// Compute fields without lock.
+	// Might duplicate effort but won't hold other computations back.
+	f = newTypeEncoder(t, true)
+	wg.Done()
+	encoderCache.Lock()
+	encoderCache.m[t] = f
+	encoderCache.Unlock()
+	return f
+}
+
+var (
+	marshalerType     = reflect.TypeOf(new(Marshaler)).Elem()
+	textMarshalerType = reflect.TypeOf(new(encoding.TextMarshaler)).Elem()
+)
+
+// newTypeEncoder constructs an encoderFunc for a type.
+// The returned encoder only checks CanAddr when allowAddr is true.
+func newTypeEncoder(t reflect.Type, allowAddr bool) encoderFunc {
+	if t.Implements(marshalerType) {
+		return marshalerEncoder
+	}
+	if t.Kind() != reflect.Ptr && allowAddr {
+		if reflect.PtrTo(t).Implements(marshalerType) {
+			return newCondAddrEncoder(addrMarshalerEncoder, newTypeEncoder(t, false))
+		}
+	}
+
+	if t.Implements(textMarshalerType) {
+		return textMarshalerEncoder
+	}
+	if t.Kind() != reflect.Ptr && allowAddr {
+		if reflect.PtrTo(t).Implements(textMarshalerType) {
+			return newCondAddrEncoder(addrTextMarshalerEncoder, newTypeEncoder(t, false))
+		}
+	}
+
+	switch t.Kind() {
+	case reflect.Bool:
+		return boolEncoder
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		return intEncoder
+	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+		return uintEncoder
+	case reflect.Float32:
+		return float32Encoder
+	case reflect.Float64:
+		return float64Encoder
+	case reflect.String:
+		return stringEncoder
+	case reflect.Interface:
+		return interfaceEncoder
+	case reflect.Struct:
+		return newStructEncoder(t)
+	case reflect.Map:
+		return newMapEncoder(t)
+	case reflect.Slice:
+		return newSliceEncoder(t)
+	case reflect.Array:
+		return newArrayEncoder(t)
+	case reflect.Ptr:
+		return newPtrEncoder(t)
+	default:
+		return unsupportedTypeEncoder
+	}
+}
+
+func invalidValueEncoder(e *encodeState, v reflect.Value, quoted bool) {
+	e.WriteString("null")
+}
+
+func marshalerEncoder(e *encodeState, v reflect.Value, quoted bool) {
+	if v.Kind() == reflect.Ptr && v.IsNil() {
+		e.WriteString("null")
+		return
+	}
+	m := v.Interface().(Marshaler)
+	b, err := m.MarshalJSON()
+	if err == nil {
+		// copy JSON into buffer, checking validity.
+		err = compact(&e.Buffer, b, true)
+	}
+	if err != nil {
+		e.error(&MarshalerError{v.Type(), err})
+	}
+}
+
+func addrMarshalerEncoder(e *encodeState, v reflect.Value, quoted bool) {
+	va := v.Addr()
+	if va.IsNil() {
+		e.WriteString("null")
+		return
+	}
+	m := va.Interface().(Marshaler)
+	b, err := m.MarshalJSON()
+	if err == nil {
+		// copy JSON into buffer, checking validity.
+		err = compact(&e.Buffer, b, true)
+	}
+	if err != nil {
+		e.error(&MarshalerError{v.Type(), err})
+	}
+}
+
+func textMarshalerEncoder(e *encodeState, v reflect.Value, quoted bool) {
+	if v.Kind() == reflect.Ptr && v.IsNil() {
+		e.WriteString("null")
+		return
+	}
+	m := v.Interface().(encoding.TextMarshaler)
+	b, err := m.MarshalText()
+	if err == nil {
+		_, err = e.stringBytes(b)
+	}
+	if err != nil {
+		e.error(&MarshalerError{v.Type(), err})
+	}
+}
+
+func addrTextMarshalerEncoder(e *encodeState, v reflect.Value, quoted bool) {
+	va := v.Addr()
+	if va.IsNil() {
+		e.WriteString("null")
+		return
+	}
+	m := va.Interface().(encoding.TextMarshaler)
+	b, err := m.MarshalText()
+	if err == nil {
+		_, err = e.stringBytes(b)
+	}
+	if err != nil {
+		e.error(&MarshalerError{v.Type(), err})
+	}
+}
+
+func boolEncoder(e *encodeState, v reflect.Value, quoted bool) {
+	if quoted {
+		e.WriteByte('"')
+	}
+	if v.Bool() {
+		e.WriteString("true")
+	} else {
+		e.WriteString("false")
+	}
+	if quoted {
+		e.WriteByte('"')
+	}
+}
+
+func intEncoder(e *encodeState, v reflect.Value, quoted bool) {
+	b := strconv.AppendInt(e.scratch[:0], v.Int(), 10)
+	if quoted {
+		e.WriteByte('"')
+	}
+	e.Write(b)
+	if quoted {
+		e.WriteByte('"')
+	}
+}
+
+func uintEncoder(e *encodeState, v reflect.Value, quoted bool) {
+	b := strconv.AppendUint(e.scratch[:0], v.Uint(), 10)
+	if quoted {
+		e.WriteByte('"')
+	}
+	e.Write(b)
+	if quoted {
+		e.WriteByte('"')
+	}
+}
+
+type floatEncoder int // number of bits
+
+func (bits floatEncoder) encode(e *encodeState, v reflect.Value, quoted bool) {
+	f := v.Float()
+	if math.IsInf(f, 0) || math.IsNaN(f) {
+		e.error(&UnsupportedValueError{v, strconv.FormatFloat(f, 'g', -1, int(bits))})
+	}
+	b := strconv.AppendFloat(e.scratch[:0], f, 'g', -1, int(bits))
+	if quoted {
+		e.WriteByte('"')
+	}
+	e.Write(b)
+	if quoted {
+		e.WriteByte('"')
+	}
+}
+
+var (
+	float32Encoder = (floatEncoder(32)).encode
+	float64Encoder = (floatEncoder(64)).encode
+)
+
+func stringEncoder(e *encodeState, v reflect.Value, quoted bool) {
+	if v.Type() == numberType {
+		numStr := v.String()
+		if numStr == "" {
+			numStr = "0" // Number's zero-val
+		}
+		e.WriteString(numStr)
+		return
+	}
+	if quoted {
+		sb, err := Marshal(v.String())
+		if err != nil {
+			e.error(err)
+		}
+		e.string(string(sb))
+	} else {
+		e.string(v.String())
+	}
+}
+
+func interfaceEncoder(e *encodeState, v reflect.Value, quoted bool) {
+	if v.IsNil() {
+		e.WriteString("null")
+		return
+	}
+	e.reflectValue(v.Elem())
+}
+
+func unsupportedTypeEncoder(e *encodeState, v reflect.Value, quoted bool) {
+	e.error(&UnsupportedTypeError{v.Type()})
+}
+
+type structEncoder struct {
+	fields    []field
+	fieldEncs []encoderFunc
+}
+
+func (se *structEncoder) encode(e *encodeState, v reflect.Value, quoted bool) {
+	e.WriteByte('{')
+	first := true
+	for i, f := range se.fields {
+		fv := fieldByIndex(v, f.index)
+		if !fv.IsValid() || f.omitEmpty && isEmptyValue(fv) {
+			continue
+		}
+		if first {
+			first = false
+		} else {
+			e.WriteByte(',')
+		}
+		e.string(f.name)
+		e.WriteByte(':')
+		se.fieldEncs[i](e, fv, f.quoted)
+	}
+	e.WriteByte('}')
+}
+
+func newStructEncoder(t reflect.Type) encoderFunc {
+	fields := cachedTypeFields(t)
+	se := &structEncoder{
+		fields:    fields,
+		fieldEncs: make([]encoderFunc, len(fields)),
+	}
+	for i, f := range fields {
+		se.fieldEncs[i] = typeEncoder(typeByIndex(t, f.index))
+	}
+	return se.encode
+}
+
+type mapEncoder struct {
+	elemEnc encoderFunc
+}
+
+func (me *mapEncoder) encode(e *encodeState, v reflect.Value, _ bool) {
+	if v.IsNil() {
+		e.WriteString("null")
+		return
+	}
+	e.WriteByte('{')
+	var sv stringValues = v.MapKeys()
+	sort.Sort(sv)
+	for i, k := range sv {
+		if i > 0 {
+			e.WriteByte(',')
+		}
+		e.string(k.String())
+		e.WriteByte(':')
+		me.elemEnc(e, v.MapIndex(k), false)
+	}
+	e.WriteByte('}')
+}
+
+func newMapEncoder(t reflect.Type) encoderFunc {
+	if t.Key().Kind() != reflect.String {
+		return unsupportedTypeEncoder
+	}
+	me := &mapEncoder{typeEncoder(t.Elem())}
+	return me.encode
+}
+
+func encodeByteSlice(e *encodeState, v reflect.Value, _ bool) {
+	if v.IsNil() {
+		e.WriteString("null")
+		return
+	}
+	s := v.Bytes()
+	e.WriteByte('"')
+	if len(s) < 1024 {
+		// for small buffers, using Encode directly is much faster.
+		dst := make([]byte, base64.StdEncoding.EncodedLen(len(s)))
+		base64.StdEncoding.Encode(dst, s)
+		e.Write(dst)
+	} else {
+		// for large buffers, avoid unnecessary extra temporary
+		// buffer space.
+		enc := base64.NewEncoder(base64.StdEncoding, e)
+		enc.Write(s)
+		enc.Close()
+	}
+	e.WriteByte('"')
+}
+
+// sliceEncoder just wraps an arrayEncoder, checking to make sure the value isn't nil.
+type sliceEncoder struct {
+	arrayEnc encoderFunc
+}
+
+func (se *sliceEncoder) encode(e *encodeState, v reflect.Value, _ bool) {
+	if v.IsNil() {
+		e.WriteString("null")
+		return
+	}
+	se.arrayEnc(e, v, false)
+}
+
+func newSliceEncoder(t reflect.Type) encoderFunc {
+	// Byte slices get special treatment; arrays don't.
+	if t.Elem().Kind() == reflect.Uint8 {
+		return encodeByteSlice
+	}
+	enc := &sliceEncoder{newArrayEncoder(t)}
+	return enc.encode
+}
+
+type arrayEncoder struct {
+	elemEnc encoderFunc
+}
+
+func (ae *arrayEncoder) encode(e *encodeState, v reflect.Value, _ bool) {
+	e.WriteByte('[')
+	n := v.Len()
+	for i := 0; i < n; i++ {
+		if i > 0 {
+			e.WriteByte(',')
+		}
+		ae.elemEnc(e, v.Index(i), false)
+	}
+	e.WriteByte(']')
+}
+
+func newArrayEncoder(t reflect.Type) encoderFunc {
+	enc := &arrayEncoder{typeEncoder(t.Elem())}
+	return enc.encode
+}
+
+type ptrEncoder struct {
+	elemEnc encoderFunc
+}
+
+func (pe *ptrEncoder) encode(e *encodeState, v reflect.Value, quoted bool) {
+	if v.IsNil() {
+		e.WriteString("null")
+		return
+	}
+	pe.elemEnc(e, v.Elem(), quoted)
+}
+
+func newPtrEncoder(t reflect.Type) encoderFunc {
+	enc := &ptrEncoder{typeEncoder(t.Elem())}
+	return enc.encode
+}
+
+type condAddrEncoder struct {
+	canAddrEnc, elseEnc encoderFunc
+}
+
+func (ce *condAddrEncoder) encode(e *encodeState, v reflect.Value, quoted bool) {
+	if v.CanAddr() {
+		ce.canAddrEnc(e, v, quoted)
+	} else {
+		ce.elseEnc(e, v, quoted)
+	}
+}
+
+// newCondAddrEncoder returns an encoder that checks whether its value
+// CanAddr and delegates to canAddrEnc if so, else to elseEnc.
+func newCondAddrEncoder(canAddrEnc, elseEnc encoderFunc) encoderFunc {
+	enc := &condAddrEncoder{canAddrEnc: canAddrEnc, elseEnc: elseEnc}
+	return enc.encode
+}
+
+func isValidTag(s string) bool {
+	if s == "" {
+		return false
+	}
+	for _, c := range s {
+		switch {
+		case strings.ContainsRune("!#$%&()*+-./:<=>?@[]^_{|}~ ", c):
+			// Backslash and quote chars are reserved, but
+			// otherwise any punctuation chars are allowed
+			// in a tag name.
+		default:
+			if !unicode.IsLetter(c) && !unicode.IsDigit(c) {
+				return false
+			}
+		}
+	}
+	return true
+}
+
+func fieldByIndex(v reflect.Value, index []int) reflect.Value {
+	for _, i := range index {
+		if v.Kind() == reflect.Ptr {
+			if v.IsNil() {
+				return reflect.Value{}
+			}
+			v = v.Elem()
+		}
+		v = v.Field(i)
+	}
+	return v
+}
+
+func typeByIndex(t reflect.Type, index []int) reflect.Type {
+	for _, i := range index {
+		if t.Kind() == reflect.Ptr {
+			t = t.Elem()
+		}
+		t = t.Field(i).Type
+	}
+	return t
+}
+
+// stringValues is a slice of reflect.Value holding *reflect.StringValue.
+// It implements the methods to sort by string.
+type stringValues []reflect.Value
+
+func (sv stringValues) Len() int           { return len(sv) }
+func (sv stringValues) Swap(i, j int)      { sv[i], sv[j] = sv[j], sv[i] }
+func (sv stringValues) Less(i, j int) bool { return sv.get(i) < sv.get(j) }
+func (sv stringValues) get(i int) string   { return sv[i].String() }
+
+// NOTE: keep in sync with stringBytes below.
+func (e *encodeState) string(s string) (int, error) {
+	len0 := e.Len()
+	e.WriteByte('"')
+	start := 0
+	for i := 0; i < len(s); {
+		if b := s[i]; b < utf8.RuneSelf {
+			if 0x20 <= b && b != '\\' && b != '"' && b != '<' && b != '>' && b != '&' {
+				i++
+				continue
+			}
+			if start < i {
+				e.WriteString(s[start:i])
+			}
+			switch b {
+			case '\\', '"':
+				e.WriteByte('\\')
+				e.WriteByte(b)
+			case '\n':
+				e.WriteByte('\\')
+				e.WriteByte('n')
+			case '\r':
+				e.WriteByte('\\')
+				e.WriteByte('r')
+			case '\t':
+				e.WriteByte('\\')
+				e.WriteByte('t')
+			default:
+				// This encodes bytes < 0x20 except for \n and \r,
+				// as well as <, > and &. The latter are escaped because they
+				// can lead to security holes when user-controlled strings
+				// are rendered into JSON and served to some browsers.
+				e.WriteString(`\u00`)
+				e.WriteByte(hex[b>>4])
+				e.WriteByte(hex[b&0xF])
+			}
+			i++
+			start = i
+			continue
+		}
+		c, size := utf8.DecodeRuneInString(s[i:])
+		if c == utf8.RuneError && size == 1 {
+			if start < i {
+				e.WriteString(s[start:i])
+			}
+			e.WriteString(`\ufffd`)
+			i += size
+			start = i
+			continue
+		}
+		// U+2028 is LINE SEPARATOR.
+		// U+2029 is PARAGRAPH SEPARATOR.
+		// They are both technically valid characters in JSON strings,
+		// but don't work in JSONP, which has to be evaluated as JavaScript,
+		// and can lead to security holes there. It is valid JSON to
+		// escape them, so we do so unconditionally.
+		// See http://timelessrepo.com/json-isnt-a-javascript-subset for discussion.
+		if c == '\u2028' || c == '\u2029' {
+			if start < i {
+				e.WriteString(s[start:i])
+			}
+			e.WriteString(`\u202`)
+			e.WriteByte(hex[c&0xF])
+			i += size
+			start = i
+			continue
+		}
+		i += size
+	}
+	if start < len(s) {
+		e.WriteString(s[start:])
+	}
+	e.WriteByte('"')
+	return e.Len() - len0, nil
+}
+
+// NOTE: keep in sync with string above.
+func (e *encodeState) stringBytes(s []byte) (int, error) {
+	len0 := e.Len()
+	e.WriteByte('"')
+	start := 0
+	for i := 0; i < len(s); {
+		if b := s[i]; b < utf8.RuneSelf {
+			if 0x20 <= b && b != '\\' && b != '"' && b != '<' && b != '>' && b != '&' {
+				i++
+				continue
+			}
+			if start < i {
+				e.Write(s[start:i])
+			}
+			switch b {
+			case '\\', '"':
+				e.WriteByte('\\')
+				e.WriteByte(b)
+			case '\n':
+				e.WriteByte('\\')
+				e.WriteByte('n')
+			case '\r':
+				e.WriteByte('\\')
+				e.WriteByte('r')
+			case '\t':
+				e.WriteByte('\\')
+				e.WriteByte('t')
+			default:
+				// This encodes bytes < 0x20 except for \n and \r,
+				// as well as <, >, and &. The latter are escaped because they
+				// can lead to security holes when user-controlled strings
+				// are rendered into JSON and served to some browsers.
+				e.WriteString(`\u00`)
+				e.WriteByte(hex[b>>4])
+				e.WriteByte(hex[b&0xF])
+			}
+			i++
+			start = i
+			continue
+		}
+		c, size := utf8.DecodeRune(s[i:])
+		if c == utf8.RuneError && size == 1 {
+			if start < i {
+				e.Write(s[start:i])
+			}
+			e.WriteString(`\ufffd`)
+			i += size
+			start = i
+			continue
+		}
+		// U+2028 is LINE SEPARATOR.
+		// U+2029 is PARAGRAPH SEPARATOR.
+		// They are both technically valid characters in JSON strings,
+		// but don't work in JSONP, which has to be evaluated as JavaScript,
+		// and can lead to security holes there. It is valid JSON to
+		// escape them, so we do so unconditionally.
+		// See http://timelessrepo.com/json-isnt-a-javascript-subset for discussion.
+		if c == '\u2028' || c == '\u2029' {
+			if start < i {
+				e.Write(s[start:i])
+			}
+			e.WriteString(`\u202`)
+			e.WriteByte(hex[c&0xF])
+			i += size
+			start = i
+			continue
+		}
+		i += size
+	}
+	if start < len(s) {
+		e.Write(s[start:])
+	}
+	e.WriteByte('"')
+	return e.Len() - len0, nil
+}
+
+// A field represents a single field found in a struct.
+type field struct {
+	name      string
+	nameBytes []byte                 // []byte(name)
+	equalFold func(s, t []byte) bool // bytes.EqualFold or equivalent
+
+	tag       bool
+	index     []int
+	typ       reflect.Type
+	omitEmpty bool
+	quoted    bool
+}
+
+func fillField(f field) field {
+	f.nameBytes = []byte(f.name)
+	f.equalFold = foldFunc(f.nameBytes)
+	return f
+}
+
+// byName sorts field by name, breaking ties with depth,
+// then breaking ties with "name came from json tag", then
+// breaking ties with index sequence.
+type byName []field
+
+func (x byName) Len() int { return len(x) }
+
+func (x byName) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
+
+func (x byName) Less(i, j int) bool {
+	if x[i].name != x[j].name {
+		return x[i].name < x[j].name
+	}
+	if len(x[i].index) != len(x[j].index) {
+		return len(x[i].index) < len(x[j].index)
+	}
+	if x[i].tag != x[j].tag {
+		return x[i].tag
+	}
+	return byIndex(x).Less(i, j)
+}
+
+// byIndex sorts field by index sequence.
+type byIndex []field
+
+func (x byIndex) Len() int { return len(x) }
+
+func (x byIndex) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
+
+func (x byIndex) Less(i, j int) bool {
+	for k, xik := range x[i].index {
+		if k >= len(x[j].index) {
+			return false
+		}
+		if xik != x[j].index[k] {
+			return xik < x[j].index[k]
+		}
+	}
+	return len(x[i].index) < len(x[j].index)
+}
+
+// typeFields returns a list of fields that JSON should recognize for the given type.
+// The algorithm is breadth-first search over the set of structs to include - the top struct
+// and then any reachable anonymous structs.
+func typeFields(t reflect.Type) []field {
+	// Anonymous fields to explore at the current level and the next.
+	current := []field{}
+	next := []field{{typ: t}}
+
+	// Count of queued names for current level and the next.
+	count := map[reflect.Type]int{}
+	nextCount := map[reflect.Type]int{}
+
+	// Types already visited at an earlier level.
+	visited := map[reflect.Type]bool{}
+
+	// Fields found.
+	var fields []field
+
+	for len(next) > 0 {
+		current, next = next, current[:0]
+		count, nextCount = nextCount, map[reflect.Type]int{}
+
+		for _, f := range current {
+			if visited[f.typ] {
+				continue
+			}
+			visited[f.typ] = true
+
+			// Scan f.typ for fields to include.
+			for i := 0; i < f.typ.NumField(); i++ {
+				sf := f.typ.Field(i)
+				if sf.PkgPath != "" { // unexported
+					continue
+				}
+				tag := sf.Tag.Get("json")
+				if tag == "-" {
+					continue
+				}
+				name, opts := parseTag(tag)
+				if !isValidTag(name) {
+					name = ""
+				}
+				index := make([]int, len(f.index)+1)
+				copy(index, f.index)
+				index[len(f.index)] = i
+
+				ft := sf.Type
+				if ft.Name() == "" && ft.Kind() == reflect.Ptr {
+					// Follow pointer.
+					ft = ft.Elem()
+				}
+
+				// Record found field and index sequence.
+				if name != "" || !sf.Anonymous || ft.Kind() != reflect.Struct {
+					tagged := name != ""
+					if name == "" {
+						name = sf.Name
+					}
+					fields = append(fields, fillField(field{
+						name:      name,
+						tag:       tagged,
+						index:     index,
+						typ:       ft,
+						omitEmpty: opts.Contains("omitempty"),
+						quoted:    opts.Contains("string"),
+					}))
+					if count[f.typ] > 1 {
+						// If there were multiple instances, add a second,
+						// so that the annihilation code will see a duplicate.
+						// It only cares about the distinction between 1 or 2,
+						// so don't bother generating any more copies.
+						fields = append(fields, fields[len(fields)-1])
+					}
+					continue
+				}
+
+				// Record new anonymous struct to explore in next round.
+				nextCount[ft]++
+				if nextCount[ft] == 1 {
+					next = append(next, fillField(field{name: ft.Name(), index: index, typ: ft}))
+				}
+			}
+		}
+	}
+
+	sort.Sort(byName(fields))
+
+	// Delete all fields that are hidden by the Go rules for embedded fields,
+	// except that fields with JSON tags are promoted.
+
+	// The fields are sorted in primary order of name, secondary order
+	// of field index length. Loop over names; for each name, delete
+	// hidden fields by choosing the one dominant field that survives.
+	out := fields[:0]
+	for advance, i := 0, 0; i < len(fields); i += advance {
+		// One iteration per name.
+		// Find the sequence of fields with the name of this first field.
+		fi := fields[i]
+		name := fi.name
+		for advance = 1; i+advance < len(fields); advance++ {
+			fj := fields[i+advance]
+			if fj.name != name {
+				break
+			}
+		}
+		if advance == 1 { // Only one field with this name
+			out = append(out, fi)
+			continue
+		}
+		dominant, ok := dominantField(fields[i : i+advance])
+		if ok {
+			out = append(out, dominant)
+		}
+	}
+
+	fields = out
+	sort.Sort(byIndex(fields))
+
+	return fields
+}
+
+// dominantField looks through the fields, all of which are known to
+// have the same name, to find the single field that dominates the
+// others using Go's embedding rules, modified by the presence of
+// JSON tags. If there are multiple top-level fields, the boolean
+// will be false: This condition is an error in Go and we skip all
+// the fields.
+func dominantField(fields []field) (field, bool) {
+	// The fields are sorted in increasing index-length order. The winner
+	// must therefore be one with the shortest index length. Drop all
+	// longer entries, which is easy: just truncate the slice.
+	length := len(fields[0].index)
+	tagged := -1 // Index of first tagged field.
+	for i, f := range fields {
+		if len(f.index) > length {
+			fields = fields[:i]
+			break
+		}
+		if f.tag {
+			if tagged >= 0 {
+				// Multiple tagged fields at the same level: conflict.
+				// Return no field.
+				return field{}, false
+			}
+			tagged = i
+		}
+	}
+	if tagged >= 0 {
+		return fields[tagged], true
+	}
+	// All remaining fields have the same length. If there's more than one,
+	// we have a conflict (two fields named "X" at the same level) and we
+	// return no field.
+	if len(fields) > 1 {
+		return field{}, false
+	}
+	return fields[0], true
+}
+
+var fieldCache struct {
+	sync.RWMutex
+	m map[reflect.Type][]field
+}
+
+// cachedTypeFields is like typeFields but uses a cache to avoid repeated work.
+func cachedTypeFields(t reflect.Type) []field {
+	fieldCache.RLock()
+	f := fieldCache.m[t]
+	fieldCache.RUnlock()
+	if f != nil {
+		return f
+	}
+
+	// Compute fields without lock.
+	// Might duplicate effort but won't hold other computations back.
+	f = typeFields(t)
+	if f == nil {
+		f = []field{}
+	}
+
+	fieldCache.Lock()
+	if fieldCache.m == nil {
+		fieldCache.m = map[reflect.Type][]field{}
+	}
+	fieldCache.m[t] = f
+	fieldCache.Unlock()
+	return f
+}
diff --git a/src/encoding/json/encode_test.go b/src/encoding/json/encode_test.go
new file mode 100644
index 0000000..7abfa85
--- /dev/null
+++ b/src/encoding/json/encode_test.go
@@ -0,0 +1,532 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package json
+
+import (
+	"bytes"
+	"math"
+	"reflect"
+	"testing"
+	"unicode"
+)
+
+type Optionals struct {
+	Sr string `json:"sr"`
+	So string `json:"so,omitempty"`
+	Sw string `json:"-"`
+
+	Ir int `json:"omitempty"` // actually named omitempty, not an option
+	Io int `json:"io,omitempty"`
+
+	Slr []string `json:"slr,random"`
+	Slo []string `json:"slo,omitempty"`
+
+	Mr map[string]interface{} `json:"mr"`
+	Mo map[string]interface{} `json:",omitempty"`
+
+	Fr float64 `json:"fr"`
+	Fo float64 `json:"fo,omitempty"`
+
+	Br bool `json:"br"`
+	Bo bool `json:"bo,omitempty"`
+
+	Ur uint `json:"ur"`
+	Uo uint `json:"uo,omitempty"`
+
+	Str struct{} `json:"str"`
+	Sto struct{} `json:"sto,omitempty"`
+}
+
+var optionalsExpected = `{
+ "sr": "",
+ "omitempty": 0,
+ "slr": null,
+ "mr": {},
+ "fr": 0,
+ "br": false,
+ "ur": 0,
+ "str": {},
+ "sto": {}
+}`
+
+func TestOmitEmpty(t *testing.T) {
+	var o Optionals
+	o.Sw = "something"
+	o.Mr = map[string]interface{}{}
+	o.Mo = map[string]interface{}{}
+
+	got, err := MarshalIndent(&o, "", " ")
+	if err != nil {
+		t.Fatal(err)
+	}
+	if got := string(got); got != optionalsExpected {
+		t.Errorf(" got: %s\nwant: %s\n", got, optionalsExpected)
+	}
+}
+
+type StringTag struct {
+	BoolStr bool   `json:",string"`
+	IntStr  int64  `json:",string"`
+	StrStr  string `json:",string"`
+}
+
+var stringTagExpected = `{
+ "BoolStr": "true",
+ "IntStr": "42",
+ "StrStr": "\"xzbit\""
+}`
+
+func TestStringTag(t *testing.T) {
+	var s StringTag
+	s.BoolStr = true
+	s.IntStr = 42
+	s.StrStr = "xzbit"
+	got, err := MarshalIndent(&s, "", " ")
+	if err != nil {
+		t.Fatal(err)
+	}
+	if got := string(got); got != stringTagExpected {
+		t.Fatalf(" got: %s\nwant: %s\n", got, stringTagExpected)
+	}
+
+	// Verify that it round-trips.
+	var s2 StringTag
+	err = NewDecoder(bytes.NewReader(got)).Decode(&s2)
+	if err != nil {
+		t.Fatalf("Decode: %v", err)
+	}
+	if !reflect.DeepEqual(s, s2) {
+		t.Fatalf("decode didn't match.\nsource: %#v\nEncoded as:\n%s\ndecode: %#v", s, string(got), s2)
+	}
+}
+
+// byte slices are special even if they're renamed types.
+type renamedByte byte
+type renamedByteSlice []byte
+type renamedRenamedByteSlice []renamedByte
+
+func TestEncodeRenamedByteSlice(t *testing.T) {
+	s := renamedByteSlice("abc")
+	result, err := Marshal(s)
+	if err != nil {
+		t.Fatal(err)
+	}
+	expect := `"YWJj"`
+	if string(result) != expect {
+		t.Errorf(" got %s want %s", result, expect)
+	}
+	r := renamedRenamedByteSlice("abc")
+	result, err = Marshal(r)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if string(result) != expect {
+		t.Errorf(" got %s want %s", result, expect)
+	}
+}
+
+var unsupportedValues = []interface{}{
+	math.NaN(),
+	math.Inf(-1),
+	math.Inf(1),
+}
+
+func TestUnsupportedValues(t *testing.T) {
+	for _, v := range unsupportedValues {
+		if _, err := Marshal(v); err != nil {
+			if _, ok := err.(*UnsupportedValueError); !ok {
+				t.Errorf("for %v, got %T want UnsupportedValueError", v, err)
+			}
+		} else {
+			t.Errorf("for %v, expected error", v)
+		}
+	}
+}
+
+// Ref has Marshaler and Unmarshaler methods with pointer receiver.
+type Ref int
+
+func (*Ref) MarshalJSON() ([]byte, error) {
+	return []byte(`"ref"`), nil
+}
+
+func (r *Ref) UnmarshalJSON([]byte) error {
+	*r = 12
+	return nil
+}
+
+// Val has Marshaler methods with value receiver.
+type Val int
+
+func (Val) MarshalJSON() ([]byte, error) {
+	return []byte(`"val"`), nil
+}
+
+// RefText has Marshaler and Unmarshaler methods with pointer receiver.
+type RefText int
+
+func (*RefText) MarshalText() ([]byte, error) {
+	return []byte(`"ref"`), nil
+}
+
+func (r *RefText) UnmarshalText([]byte) error {
+	*r = 13
+	return nil
+}
+
+// ValText has Marshaler methods with value receiver.
+type ValText int
+
+func (ValText) MarshalText() ([]byte, error) {
+	return []byte(`"val"`), nil
+}
+
+func TestRefValMarshal(t *testing.T) {
+	var s = struct {
+		R0 Ref
+		R1 *Ref
+		R2 RefText
+		R3 *RefText
+		V0 Val
+		V1 *Val
+		V2 ValText
+		V3 *ValText
+	}{
+		R0: 12,
+		R1: new(Ref),
+		R2: 14,
+		R3: new(RefText),
+		V0: 13,
+		V1: new(Val),
+		V2: 15,
+		V3: new(ValText),
+	}
+	const want = `{"R0":"ref","R1":"ref","R2":"\"ref\"","R3":"\"ref\"","V0":"val","V1":"val","V2":"\"val\"","V3":"\"val\""}`
+	b, err := Marshal(&s)
+	if err != nil {
+		t.Fatalf("Marshal: %v", err)
+	}
+	if got := string(b); got != want {
+		t.Errorf("got %q, want %q", got, want)
+	}
+}
+
+// C implements Marshaler and returns unescaped JSON.
+type C int
+
+func (C) MarshalJSON() ([]byte, error) {
+	return []byte(`"<&>"`), nil
+}
+
+// CText implements Marshaler and returns unescaped text.
+type CText int
+
+func (CText) MarshalText() ([]byte, error) {
+	return []byte(`"<&>"`), nil
+}
+
+func TestMarshalerEscaping(t *testing.T) {
+	var c C
+	want := `"\u003c\u0026\u003e"`
+	b, err := Marshal(c)
+	if err != nil {
+		t.Fatalf("Marshal(c): %v", err)
+	}
+	if got := string(b); got != want {
+		t.Errorf("Marshal(c) = %#q, want %#q", got, want)
+	}
+
+	var ct CText
+	want = `"\"\u003c\u0026\u003e\""`
+	b, err = Marshal(ct)
+	if err != nil {
+		t.Fatalf("Marshal(ct): %v", err)
+	}
+	if got := string(b); got != want {
+		t.Errorf("Marshal(ct) = %#q, want %#q", got, want)
+	}
+}
+
+type IntType int
+
+type MyStruct struct {
+	IntType
+}
+
+func TestAnonymousNonstruct(t *testing.T) {
+	var i IntType = 11
+	a := MyStruct{i}
+	const want = `{"IntType":11}`
+
+	b, err := Marshal(a)
+	if err != nil {
+		t.Fatalf("Marshal: %v", err)
+	}
+	if got := string(b); got != want {
+		t.Errorf("got %q, want %q", got, want)
+	}
+}
+
+type BugA struct {
+	S string
+}
+
+type BugB struct {
+	BugA
+	S string
+}
+
+type BugC struct {
+	S string
+}
+
+// Legal Go: We never use the repeated embedded field (S).
+type BugX struct {
+	A int
+	BugA
+	BugB
+}
+
+// Issue 5245.
+func TestEmbeddedBug(t *testing.T) {
+	v := BugB{
+		BugA{"A"},
+		"B",
+	}
+	b, err := Marshal(v)
+	if err != nil {
+		t.Fatal("Marshal:", err)
+	}
+	want := `{"S":"B"}`
+	got := string(b)
+	if got != want {
+		t.Fatalf("Marshal: got %s want %s", got, want)
+	}
+	// Now check that the duplicate field, S, does not appear.
+	x := BugX{
+		A: 23,
+	}
+	b, err = Marshal(x)
+	if err != nil {
+		t.Fatal("Marshal:", err)
+	}
+	want = `{"A":23}`
+	got = string(b)
+	if got != want {
+		t.Fatalf("Marshal: got %s want %s", got, want)
+	}
+}
+
+type BugD struct { // Same as BugA after tagging.
+	XXX string `json:"S"`
+}
+
+// BugD's tagged S field should dominate BugA's.
+type BugY struct {
+	BugA
+	BugD
+}
+
+// Test that a field with a tag dominates untagged fields.
+func TestTaggedFieldDominates(t *testing.T) {
+	v := BugY{
+		BugA{"BugA"},
+		BugD{"BugD"},
+	}
+	b, err := Marshal(v)
+	if err != nil {
+		t.Fatal("Marshal:", err)
+	}
+	want := `{"S":"BugD"}`
+	got := string(b)
+	if got != want {
+		t.Fatalf("Marshal: got %s want %s", got, want)
+	}
+}
+
+// There are no tags here, so S should not appear.
+type BugZ struct {
+	BugA
+	BugC
+	BugY // Contains a tagged S field through BugD; should not dominate.
+}
+
+func TestDuplicatedFieldDisappears(t *testing.T) {
+	v := BugZ{
+		BugA{"BugA"},
+		BugC{"BugC"},
+		BugY{
+			BugA{"nested BugA"},
+			BugD{"nested BugD"},
+		},
+	}
+	b, err := Marshal(v)
+	if err != nil {
+		t.Fatal("Marshal:", err)
+	}
+	want := `{}`
+	got := string(b)
+	if got != want {
+		t.Fatalf("Marshal: got %s want %s", got, want)
+	}
+}
+
+func TestStringBytes(t *testing.T) {
+	// Test that encodeState.stringBytes and encodeState.string use the same encoding.
+	es := &encodeState{}
+	var r []rune
+	for i := '\u0000'; i <= unicode.MaxRune; i++ {
+		r = append(r, i)
+	}
+	s := string(r) + "\xff\xff\xffhello" // some invalid UTF-8 too
+	_, err := es.string(s)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	esBytes := &encodeState{}
+	_, err = esBytes.stringBytes([]byte(s))
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	enc := es.Buffer.String()
+	encBytes := esBytes.Buffer.String()
+	if enc != encBytes {
+		i := 0
+		for i < len(enc) && i < len(encBytes) && enc[i] == encBytes[i] {
+			i++
+		}
+		enc = enc[i:]
+		encBytes = encBytes[i:]
+		i = 0
+		for i < len(enc) && i < len(encBytes) && enc[len(enc)-i-1] == encBytes[len(encBytes)-i-1] {
+			i++
+		}
+		enc = enc[:len(enc)-i]
+		encBytes = encBytes[:len(encBytes)-i]
+
+		if len(enc) > 20 {
+			enc = enc[:20] + "..."
+		}
+		if len(encBytes) > 20 {
+			encBytes = encBytes[:20] + "..."
+		}
+
+		t.Errorf("encodings differ at %#q vs %#q", enc, encBytes)
+	}
+}
+
+func TestIssue6458(t *testing.T) {
+	type Foo struct {
+		M RawMessage
+	}
+	x := Foo{RawMessage(`"foo"`)}
+
+	b, err := Marshal(&x)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if want := `{"M":"foo"}`; string(b) != want {
+		t.Errorf("Marshal(&x) = %#q; want %#q", b, want)
+	}
+
+	b, err = Marshal(x)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if want := `{"M":"ImZvbyI="}`; string(b) != want {
+		t.Errorf("Marshal(x) = %#q; want %#q", b, want)
+	}
+}
+
+func TestHTMLEscape(t *testing.T) {
+	var b, want bytes.Buffer
+	m := `{"M":"<html>foo &` + "\xe2\x80\xa8 \xe2\x80\xa9" + `</html>"}`
+	want.Write([]byte(`{"M":"\u003chtml\u003efoo \u0026\u2028 \u2029\u003c/html\u003e"}`))
+	HTMLEscape(&b, []byte(m))
+	if !bytes.Equal(b.Bytes(), want.Bytes()) {
+		t.Errorf("HTMLEscape(&b, []byte(m)) = %s; want %s", b.Bytes(), want.Bytes())
+	}
+}
+
+// golang.org/issue/8582
+func TestEncodePointerString(t *testing.T) {
+	type stringPointer struct {
+		N *int64 `json:"n,string"`
+	}
+	var n int64 = 42
+	b, err := Marshal(stringPointer{N: &n})
+	if err != nil {
+		t.Fatalf("Marshal: %v", err)
+	}
+	if got, want := string(b), `{"n":"42"}`; got != want {
+		t.Errorf("Marshal = %s, want %s", got, want)
+	}
+	var back stringPointer
+	err = Unmarshal(b, &back)
+	if err != nil {
+		t.Fatalf("Unmarshal: %v", err)
+	}
+	if back.N == nil {
+		t.Fatalf("Unmarshalled nil N field")
+	}
+	if *back.N != 42 {
+		t.Fatalf("*N = %d; want 42", *back.N)
+	}
+}
+
+var encodeStringTests = []struct {
+	in  string
+	out string
+}{
+	{"\x00", `"\u0000"`},
+	{"\x01", `"\u0001"`},
+	{"\x02", `"\u0002"`},
+	{"\x03", `"\u0003"`},
+	{"\x04", `"\u0004"`},
+	{"\x05", `"\u0005"`},
+	{"\x06", `"\u0006"`},
+	{"\x07", `"\u0007"`},
+	{"\x08", `"\u0008"`},
+	{"\x09", `"\t"`},
+	{"\x0a", `"\n"`},
+	{"\x0b", `"\u000b"`},
+	{"\x0c", `"\u000c"`},
+	{"\x0d", `"\r"`},
+	{"\x0e", `"\u000e"`},
+	{"\x0f", `"\u000f"`},
+	{"\x10", `"\u0010"`},
+	{"\x11", `"\u0011"`},
+	{"\x12", `"\u0012"`},
+	{"\x13", `"\u0013"`},
+	{"\x14", `"\u0014"`},
+	{"\x15", `"\u0015"`},
+	{"\x16", `"\u0016"`},
+	{"\x17", `"\u0017"`},
+	{"\x18", `"\u0018"`},
+	{"\x19", `"\u0019"`},
+	{"\x1a", `"\u001a"`},
+	{"\x1b", `"\u001b"`},
+	{"\x1c", `"\u001c"`},
+	{"\x1d", `"\u001d"`},
+	{"\x1e", `"\u001e"`},
+	{"\x1f", `"\u001f"`},
+}
+
+func TestEncodeString(t *testing.T) {
+	for _, tt := range encodeStringTests {
+		b, err := Marshal(tt.in)
+		if err != nil {
+			t.Errorf("Marshal(%q): %v", tt.in, err)
+			continue
+		}
+		out := string(b)
+		if out != tt.out {
+			t.Errorf("Marshal(%q) = %#q, want %#q", tt.in, out, tt.out)
+		}
+	}
+}
diff --git a/src/pkg/encoding/json/example_test.go b/src/encoding/json/example_test.go
similarity index 100%
rename from src/pkg/encoding/json/example_test.go
rename to src/encoding/json/example_test.go
diff --git a/src/pkg/encoding/json/fold.go b/src/encoding/json/fold.go
similarity index 100%
rename from src/pkg/encoding/json/fold.go
rename to src/encoding/json/fold.go
diff --git a/src/pkg/encoding/json/fold_test.go b/src/encoding/json/fold_test.go
similarity index 100%
rename from src/pkg/encoding/json/fold_test.go
rename to src/encoding/json/fold_test.go
diff --git a/src/pkg/encoding/json/indent.go b/src/encoding/json/indent.go
similarity index 100%
rename from src/pkg/encoding/json/indent.go
rename to src/encoding/json/indent.go
diff --git a/src/pkg/encoding/json/scanner.go b/src/encoding/json/scanner.go
similarity index 100%
rename from src/pkg/encoding/json/scanner.go
rename to src/encoding/json/scanner.go
diff --git a/src/pkg/encoding/json/scanner_test.go b/src/encoding/json/scanner_test.go
similarity index 100%
rename from src/pkg/encoding/json/scanner_test.go
rename to src/encoding/json/scanner_test.go
diff --git a/src/encoding/json/stream.go b/src/encoding/json/stream.go
new file mode 100644
index 0000000..9566eca
--- /dev/null
+++ b/src/encoding/json/stream.go
@@ -0,0 +1,200 @@
+// Copyright 2010 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package json
+
+import (
+	"bytes"
+	"errors"
+	"io"
+)
+
+// A Decoder reads and decodes JSON objects from an input stream.
+type Decoder struct {
+	r    io.Reader
+	buf  []byte
+	d    decodeState
+	scan scanner
+	err  error
+}
+
+// NewDecoder returns a new decoder that reads from r.
+//
+// The decoder introduces its own buffering and may
+// read data from r beyond the JSON values requested.
+func NewDecoder(r io.Reader) *Decoder {
+	return &Decoder{r: r}
+}
+
+// UseNumber causes the Decoder to unmarshal a number into an interface{} as a
+// Number instead of as a float64.
+func (dec *Decoder) UseNumber() { dec.d.useNumber = true }
+
+// Decode reads the next JSON-encoded value from its
+// input and stores it in the value pointed to by v.
+//
+// See the documentation for Unmarshal for details about
+// the conversion of JSON into a Go value.
+func (dec *Decoder) Decode(v interface{}) error {
+	if dec.err != nil {
+		return dec.err
+	}
+
+	n, err := dec.readValue()
+	if err != nil {
+		return err
+	}
+
+	// Don't save err from unmarshal into dec.err:
+	// the connection is still usable since we read a complete JSON
+	// object from it before the error happened.
+	dec.d.init(dec.buf[0:n])
+	err = dec.d.unmarshal(v)
+
+	// Slide rest of data down.
+	rest := copy(dec.buf, dec.buf[n:])
+	dec.buf = dec.buf[0:rest]
+
+	return err
+}
+
+// Buffered returns a reader of the data remaining in the Decoder's
+// buffer. The reader is valid until the next call to Decode.
+func (dec *Decoder) Buffered() io.Reader {
+	return bytes.NewReader(dec.buf)
+}
+
+// readValue reads a JSON value into dec.buf.
+// It returns the length of the encoding.
+func (dec *Decoder) readValue() (int, error) {
+	dec.scan.reset()
+
+	scanp := 0
+	var err error
+Input:
+	for {
+		// Look in the buffer for a new value.
+		for i, c := range dec.buf[scanp:] {
+			dec.scan.bytes++
+			v := dec.scan.step(&dec.scan, int(c))
+			if v == scanEnd {
+				scanp += i
+				break Input
+			}
+			// scanEnd is delayed one byte.
+			// We might block trying to get that byte from src,
+			// so instead invent a space byte.
+			if (v == scanEndObject || v == scanEndArray) && dec.scan.step(&dec.scan, ' ') == scanEnd {
+				scanp += i + 1
+				break Input
+			}
+			if v == scanError {
+				dec.err = dec.scan.err
+				return 0, dec.scan.err
+			}
+		}
+		scanp = len(dec.buf)
+
+		// Did the last read have an error?
+		// Delayed until now to allow buffer scan.
+		if err != nil {
+			if err == io.EOF {
+				if dec.scan.step(&dec.scan, ' ') == scanEnd {
+					break Input
+				}
+				if nonSpace(dec.buf) {
+					err = io.ErrUnexpectedEOF
+				}
+			}
+			dec.err = err
+			return 0, err
+		}
+
+		// Make room to read more into the buffer.
+		const minRead = 512
+		if cap(dec.buf)-len(dec.buf) < minRead {
+			newBuf := make([]byte, len(dec.buf), 2*cap(dec.buf)+minRead)
+			copy(newBuf, dec.buf)
+			dec.buf = newBuf
+		}
+
+		// Read.  Delay error for next iteration (after scan).
+		var n int
+		n, err = dec.r.Read(dec.buf[len(dec.buf):cap(dec.buf)])
+		dec.buf = dec.buf[0 : len(dec.buf)+n]
+	}
+	return scanp, nil
+}
+
+func nonSpace(b []byte) bool {
+	for _, c := range b {
+		if !isSpace(rune(c)) {
+			return true
+		}
+	}
+	return false
+}
+
+// An Encoder writes JSON objects to an output stream.
+type Encoder struct {
+	w   io.Writer
+	err error
+}
+
+// NewEncoder returns a new encoder that writes to w.
+func NewEncoder(w io.Writer) *Encoder {
+	return &Encoder{w: w}
+}
+
+// Encode writes the JSON encoding of v to the stream,
+// followed by a newline character.
+//
+// See the documentation for Marshal for details about the
+// conversion of Go values to JSON.
+func (enc *Encoder) Encode(v interface{}) error {
+	if enc.err != nil {
+		return enc.err
+	}
+	e := newEncodeState()
+	err := e.marshal(v)
+	if err != nil {
+		return err
+	}
+
+	// Terminate each value with a newline.
+	// This makes the output look a little nicer
+	// when debugging, and some kind of space
+	// is required if the encoded value was a number,
+	// so that the reader knows there aren't more
+	// digits coming.
+	e.WriteByte('\n')
+
+	if _, err = enc.w.Write(e.Bytes()); err != nil {
+		enc.err = err
+	}
+	encodeStatePool.Put(e)
+	return err
+}
+
+// RawMessage is a raw encoded JSON object.
+// It implements Marshaler and Unmarshaler and can
+// be used to delay JSON decoding or precompute a JSON encoding.
+type RawMessage []byte
+
+// MarshalJSON returns *m as the JSON encoding of m.
+func (m *RawMessage) MarshalJSON() ([]byte, error) {
+	return *m, nil
+}
+
+// UnmarshalJSON sets *m to a copy of data.
+func (m *RawMessage) UnmarshalJSON(data []byte) error {
+	if m == nil {
+		return errors.New("json.RawMessage: UnmarshalJSON on nil pointer")
+	}
+	*m = append((*m)[0:0], data...)
+	return nil
+}
+
+var _ Marshaler = (*RawMessage)(nil)
+var _ Unmarshaler = (*RawMessage)(nil)
diff --git a/src/pkg/encoding/json/stream_test.go b/src/encoding/json/stream_test.go
similarity index 100%
rename from src/pkg/encoding/json/stream_test.go
rename to src/encoding/json/stream_test.go
diff --git a/src/pkg/encoding/json/tagkey_test.go b/src/encoding/json/tagkey_test.go
similarity index 100%
rename from src/pkg/encoding/json/tagkey_test.go
rename to src/encoding/json/tagkey_test.go
diff --git a/src/pkg/encoding/json/tags.go b/src/encoding/json/tags.go
similarity index 100%
rename from src/pkg/encoding/json/tags.go
rename to src/encoding/json/tags.go
diff --git a/src/pkg/encoding/json/tags_test.go b/src/encoding/json/tags_test.go
similarity index 100%
rename from src/pkg/encoding/json/tags_test.go
rename to src/encoding/json/tags_test.go
diff --git a/src/pkg/encoding/json/testdata/code.json.gz b/src/encoding/json/testdata/code.json.gz
similarity index 100%
rename from src/pkg/encoding/json/testdata/code.json.gz
rename to src/encoding/json/testdata/code.json.gz
diff --git a/src/pkg/encoding/pem/pem.go b/src/encoding/pem/pem.go
similarity index 100%
rename from src/pkg/encoding/pem/pem.go
rename to src/encoding/pem/pem.go
diff --git a/src/pkg/encoding/pem/pem_test.go b/src/encoding/pem/pem_test.go
similarity index 100%
rename from src/pkg/encoding/pem/pem_test.go
rename to src/encoding/pem/pem_test.go
diff --git a/src/pkg/encoding/xml/atom_test.go b/src/encoding/xml/atom_test.go
similarity index 100%
rename from src/pkg/encoding/xml/atom_test.go
rename to src/encoding/xml/atom_test.go
diff --git a/src/pkg/encoding/xml/example_test.go b/src/encoding/xml/example_test.go
similarity index 100%
rename from src/pkg/encoding/xml/example_test.go
rename to src/encoding/xml/example_test.go
diff --git a/src/pkg/encoding/xml/marshal.go b/src/encoding/xml/marshal.go
similarity index 100%
rename from src/pkg/encoding/xml/marshal.go
rename to src/encoding/xml/marshal.go
diff --git a/src/pkg/encoding/xml/marshal_test.go b/src/encoding/xml/marshal_test.go
similarity index 100%
rename from src/pkg/encoding/xml/marshal_test.go
rename to src/encoding/xml/marshal_test.go
diff --git a/src/pkg/encoding/xml/read.go b/src/encoding/xml/read.go
similarity index 100%
rename from src/pkg/encoding/xml/read.go
rename to src/encoding/xml/read.go
diff --git a/src/pkg/encoding/xml/read_test.go b/src/encoding/xml/read_test.go
similarity index 100%
rename from src/pkg/encoding/xml/read_test.go
rename to src/encoding/xml/read_test.go
diff --git a/src/pkg/encoding/xml/typeinfo.go b/src/encoding/xml/typeinfo.go
similarity index 100%
rename from src/pkg/encoding/xml/typeinfo.go
rename to src/encoding/xml/typeinfo.go
diff --git a/src/encoding/xml/xml.go b/src/encoding/xml/xml.go
new file mode 100644
index 0000000..8c15b98
--- /dev/null
+++ b/src/encoding/xml/xml.go
@@ -0,0 +1,1945 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package xml implements a simple XML 1.0 parser that
+// understands XML name spaces.
+package xml
+
+// References:
+//    Annotated XML spec: http://www.xml.com/axml/testaxml.htm
+//    XML name spaces: http://www.w3.org/TR/REC-xml-names/
+
+// TODO(rsc):
+//	Test error handling.
+
+import (
+	"bufio"
+	"bytes"
+	"errors"
+	"fmt"
+	"io"
+	"strconv"
+	"strings"
+	"unicode"
+	"unicode/utf8"
+)
+
+// A SyntaxError represents a syntax error in the XML input stream.
+type SyntaxError struct {
+	Msg  string
+	Line int
+}
+
+func (e *SyntaxError) Error() string {
+	return "XML syntax error on line " + strconv.Itoa(e.Line) + ": " + e.Msg
+}
+
+// A Name represents an XML name (Local) annotated
+// with a name space identifier (Space).
+// In tokens returned by Decoder.Token, the Space identifier
+// is given as a canonical URL, not the short prefix used
+// in the document being parsed.
+type Name struct {
+	Space, Local string
+}
+
+// An Attr represents an attribute in an XML element (Name=Value).
+type Attr struct {
+	Name  Name
+	Value string
+}
+
+// A Token is an interface holding one of the token types:
+// StartElement, EndElement, CharData, Comment, ProcInst, or Directive.
+type Token interface{}
+
+// A StartElement represents an XML start element.
+type StartElement struct {
+	Name Name
+	Attr []Attr
+}
+
+func (e StartElement) Copy() StartElement {
+	attrs := make([]Attr, len(e.Attr))
+	copy(attrs, e.Attr)
+	e.Attr = attrs
+	return e
+}
+
+// End returns the corresponding XML end element.
+func (e StartElement) End() EndElement {
+	return EndElement{e.Name}
+}
+
+// An EndElement represents an XML end element.
+type EndElement struct {
+	Name Name
+}
+
+// A CharData represents XML character data (raw text),
+// in which XML escape sequences have been replaced by
+// the characters they represent.
+type CharData []byte
+
+func makeCopy(b []byte) []byte {
+	b1 := make([]byte, len(b))
+	copy(b1, b)
+	return b1
+}
+
+func (c CharData) Copy() CharData { return CharData(makeCopy(c)) }
+
+// A Comment represents an XML comment of the form <!--comment-->.
+// The bytes do not include the <!-- and --> comment markers.
+type Comment []byte
+
+func (c Comment) Copy() Comment { return Comment(makeCopy(c)) }
+
+// A ProcInst represents an XML processing instruction of the form <?target inst?>
+type ProcInst struct {
+	Target string
+	Inst   []byte
+}
+
+func (p ProcInst) Copy() ProcInst {
+	p.Inst = makeCopy(p.Inst)
+	return p
+}
+
+// A Directive represents an XML directive of the form <!text>.
+// The bytes do not include the <! and > markers.
+type Directive []byte
+
+func (d Directive) Copy() Directive { return Directive(makeCopy(d)) }
+
+// CopyToken returns a copy of a Token.
+func CopyToken(t Token) Token {
+	switch v := t.(type) {
+	case CharData:
+		return v.Copy()
+	case Comment:
+		return v.Copy()
+	case Directive:
+		return v.Copy()
+	case ProcInst:
+		return v.Copy()
+	case StartElement:
+		return v.Copy()
+	}
+	return t
+}
+
+// A Decoder represents an XML parser reading a particular input stream.
+// The parser assumes that its input is encoded in UTF-8.
+type Decoder struct {
+	// Strict defaults to true, enforcing the requirements
+	// of the XML specification.
+	// If set to false, the parser allows input containing common
+	// mistakes:
+	//	* If an element is missing an end tag, the parser invents
+	//	  end tags as necessary to keep the return values from Token
+	//	  properly balanced.
+	//	* In attribute values and character data, unknown or malformed
+	//	  character entities (sequences beginning with &) are left alone.
+	//
+	// Setting:
+	//
+	//	d.Strict = false;
+	//	d.AutoClose = HTMLAutoClose;
+	//	d.Entity = HTMLEntity
+	//
+	// creates a parser that can handle typical HTML.
+	//
+	// Strict mode does not enforce the requirements of the XML name spaces TR.
+	// In particular it does not reject name space tags using undefined prefixes.
+	// Such tags are recorded with the unknown prefix as the name space URL.
+	Strict bool
+
+	// When Strict == false, AutoClose indicates a set of elements to
+	// consider closed immediately after they are opened, regardless
+	// of whether an end element is present.
+	AutoClose []string
+
+	// Entity can be used to map non-standard entity names to string replacements.
+	// The parser behaves as if these standard mappings are present in the map,
+	// regardless of the actual map content:
+	//
+	//	"lt": "<",
+	//	"gt": ">",
+	//	"amp": "&",
+	//	"apos": "'",
+	//	"quot": `"`,
+	Entity map[string]string
+
+	// CharsetReader, if non-nil, defines a function to generate
+	// charset-conversion readers, converting from the provided
+	// non-UTF-8 charset into UTF-8. If CharsetReader is nil or
+	// returns an error, parsing stops with an error. One of the
+	// the CharsetReader's result values must be non-nil.
+	CharsetReader func(charset string, input io.Reader) (io.Reader, error)
+
+	// DefaultSpace sets the default name space used for unadorned tags,
+	// as if the entire XML stream were wrapped in an element containing
+	// the attribute xmlns="DefaultSpace".
+	DefaultSpace string
+
+	r              io.ByteReader
+	buf            bytes.Buffer
+	saved          *bytes.Buffer
+	stk            *stack
+	free           *stack
+	needClose      bool
+	toClose        Name
+	nextToken      Token
+	nextByte       int
+	ns             map[string]string
+	err            error
+	line           int
+	offset         int64
+	unmarshalDepth int
+}
+
+// NewDecoder creates a new XML parser reading from r.
+// If r does not implement io.ByteReader, NewDecoder will
+// do its own buffering.
+func NewDecoder(r io.Reader) *Decoder {
+	d := &Decoder{
+		ns:       make(map[string]string),
+		nextByte: -1,
+		line:     1,
+		Strict:   true,
+	}
+	d.switchToReader(r)
+	return d
+}
+
+// Token returns the next XML token in the input stream.
+// At the end of the input stream, Token returns nil, io.EOF.
+//
+// Slices of bytes in the returned token data refer to the
+// parser's internal buffer and remain valid only until the next
+// call to Token.  To acquire a copy of the bytes, call CopyToken
+// or the token's Copy method.
+//
+// Token expands self-closing elements such as <br/>
+// into separate start and end elements returned by successive calls.
+//
+// Token guarantees that the StartElement and EndElement
+// tokens it returns are properly nested and matched:
+// if Token encounters an unexpected end element,
+// it will return an error.
+//
+// Token implements XML name spaces as described by
+// http://www.w3.org/TR/REC-xml-names/.  Each of the
+// Name structures contained in the Token has the Space
+// set to the URL identifying its name space when known.
+// If Token encounters an unrecognized name space prefix,
+// it uses the prefix as the Space rather than report an error.
+func (d *Decoder) Token() (t Token, err error) {
+	if d.stk != nil && d.stk.kind == stkEOF {
+		err = io.EOF
+		return
+	}
+	if d.nextToken != nil {
+		t = d.nextToken
+		d.nextToken = nil
+	} else if t, err = d.rawToken(); err != nil {
+		return
+	}
+
+	if !d.Strict {
+		if t1, ok := d.autoClose(t); ok {
+			d.nextToken = t
+			t = t1
+		}
+	}
+	switch t1 := t.(type) {
+	case StartElement:
+		// In XML name spaces, the translations listed in the
+		// attributes apply to the element name and
+		// to the other attribute names, so process
+		// the translations first.
+		for _, a := range t1.Attr {
+			if a.Name.Space == "xmlns" {
+				v, ok := d.ns[a.Name.Local]
+				d.pushNs(a.Name.Local, v, ok)
+				d.ns[a.Name.Local] = a.Value
+			}
+			if a.Name.Space == "" && a.Name.Local == "xmlns" {
+				// Default space for untagged names
+				v, ok := d.ns[""]
+				d.pushNs("", v, ok)
+				d.ns[""] = a.Value
+			}
+		}
+
+		d.translate(&t1.Name, true)
+		for i := range t1.Attr {
+			d.translate(&t1.Attr[i].Name, false)
+		}
+		d.pushElement(t1.Name)
+		t = t1
+
+	case EndElement:
+		d.translate(&t1.Name, true)
+		if !d.popElement(&t1) {
+			return nil, d.err
+		}
+		t = t1
+	}
+	return
+}
+
+const xmlURL = "http://www.w3.org/XML/1998/namespace"
+
+// Apply name space translation to name n.
+// The default name space (for Space=="")
+// applies only to element names, not to attribute names.
+func (d *Decoder) translate(n *Name, isElementName bool) {
+	switch {
+	case n.Space == "xmlns":
+		return
+	case n.Space == "" && !isElementName:
+		return
+	case n.Space == "xml":
+		n.Space = xmlURL
+	case n.Space == "" && n.Local == "xmlns":
+		return
+	}
+	if v, ok := d.ns[n.Space]; ok {
+		n.Space = v
+	} else if n.Space == "" {
+		n.Space = d.DefaultSpace
+	}
+}
+
+func (d *Decoder) switchToReader(r io.Reader) {
+	// Get efficient byte at a time reader.
+	// Assume that if reader has its own
+	// ReadByte, it's efficient enough.
+	// Otherwise, use bufio.
+	if rb, ok := r.(io.ByteReader); ok {
+		d.r = rb
+	} else {
+		d.r = bufio.NewReader(r)
+	}
+}
+
+// Parsing state - stack holds old name space translations
+// and the current set of open elements.  The translations to pop when
+// ending a given tag are *below* it on the stack, which is
+// more work but forced on us by XML.
+type stack struct {
+	next *stack
+	kind int
+	name Name
+	ok   bool
+}
+
+const (
+	stkStart = iota
+	stkNs
+	stkEOF
+)
+
+func (d *Decoder) push(kind int) *stack {
+	s := d.free
+	if s != nil {
+		d.free = s.next
+	} else {
+		s = new(stack)
+	}
+	s.next = d.stk
+	s.kind = kind
+	d.stk = s
+	return s
+}
+
+func (d *Decoder) pop() *stack {
+	s := d.stk
+	if s != nil {
+		d.stk = s.next
+		s.next = d.free
+		d.free = s
+	}
+	return s
+}
+
+// Record that after the current element is finished
+// (that element is already pushed on the stack)
+// Token should return EOF until popEOF is called.
+func (d *Decoder) pushEOF() {
+	// Walk down stack to find Start.
+	// It might not be the top, because there might be stkNs
+	// entries above it.
+	start := d.stk
+	for start.kind != stkStart {
+		start = start.next
+	}
+	// The stkNs entries below a start are associated with that
+	// element too; skip over them.
+	for start.next != nil && start.next.kind == stkNs {
+		start = start.next
+	}
+	s := d.free
+	if s != nil {
+		d.free = s.next
+	} else {
+		s = new(stack)
+	}
+	s.kind = stkEOF
+	s.next = start.next
+	start.next = s
+}
+
+// Undo a pushEOF.
+// The element must have been finished, so the EOF should be at the top of the stack.
+func (d *Decoder) popEOF() bool {
+	if d.stk == nil || d.stk.kind != stkEOF {
+		return false
+	}
+	d.pop()
+	return true
+}
+
+// Record that we are starting an element with the given name.
+func (d *Decoder) pushElement(name Name) {
+	s := d.push(stkStart)
+	s.name = name
+}
+
+// Record that we are changing the value of ns[local].
+// The old value is url, ok.
+func (d *Decoder) pushNs(local string, url string, ok bool) {
+	s := d.push(stkNs)
+	s.name.Local = local
+	s.name.Space = url
+	s.ok = ok
+}
+
+// Creates a SyntaxError with the current line number.
+func (d *Decoder) syntaxError(msg string) error {
+	return &SyntaxError{Msg: msg, Line: d.line}
+}
+
+// Record that we are ending an element with the given name.
+// The name must match the record at the top of the stack,
+// which must be a pushElement record.
+// After popping the element, apply any undo records from
+// the stack to restore the name translations that existed
+// before we saw this element.
+func (d *Decoder) popElement(t *EndElement) bool {
+	s := d.pop()
+	name := t.Name
+	switch {
+	case s == nil || s.kind != stkStart:
+		d.err = d.syntaxError("unexpected end element </" + name.Local + ">")
+		return false
+	case s.name.Local != name.Local:
+		if !d.Strict {
+			d.needClose = true
+			d.toClose = t.Name
+			t.Name = s.name
+			return true
+		}
+		d.err = d.syntaxError("element <" + s.name.Local + "> closed by </" + name.Local + ">")
+		return false
+	case s.name.Space != name.Space:
+		d.err = d.syntaxError("element <" + s.name.Local + "> in space " + s.name.Space +
+			"closed by </" + name.Local + "> in space " + name.Space)
+		return false
+	}
+
+	// Pop stack until a Start or EOF is on the top, undoing the
+	// translations that were associated with the element we just closed.
+	for d.stk != nil && d.stk.kind != stkStart && d.stk.kind != stkEOF {
+		s := d.pop()
+		if s.ok {
+			d.ns[s.name.Local] = s.name.Space
+		} else {
+			delete(d.ns, s.name.Local)
+		}
+	}
+
+	return true
+}
+
+// If the top element on the stack is autoclosing and
+// t is not the end tag, invent the end tag.
+func (d *Decoder) autoClose(t Token) (Token, bool) {
+	if d.stk == nil || d.stk.kind != stkStart {
+		return nil, false
+	}
+	name := strings.ToLower(d.stk.name.Local)
+	for _, s := range d.AutoClose {
+		if strings.ToLower(s) == name {
+			// This one should be auto closed if t doesn't close it.
+			et, ok := t.(EndElement)
+			if !ok || et.Name.Local != name {
+				return EndElement{d.stk.name}, true
+			}
+			break
+		}
+	}
+	return nil, false
+}
+
+var errRawToken = errors.New("xml: cannot use RawToken from UnmarshalXML method")
+
+// RawToken is like Token but does not verify that
+// start and end elements match and does not translate
+// name space prefixes to their corresponding URLs.
+func (d *Decoder) RawToken() (Token, error) {
+	if d.unmarshalDepth > 0 {
+		return nil, errRawToken
+	}
+	return d.rawToken()
+}
+
+func (d *Decoder) rawToken() (Token, error) {
+	if d.err != nil {
+		return nil, d.err
+	}
+	if d.needClose {
+		// The last element we read was self-closing and
+		// we returned just the StartElement half.
+		// Return the EndElement half now.
+		d.needClose = false
+		return EndElement{d.toClose}, nil
+	}
+
+	b, ok := d.getc()
+	if !ok {
+		return nil, d.err
+	}
+
+	if b != '<' {
+		// Text section.
+		d.ungetc(b)
+		data := d.text(-1, false)
+		if data == nil {
+			return nil, d.err
+		}
+		return CharData(data), nil
+	}
+
+	if b, ok = d.mustgetc(); !ok {
+		return nil, d.err
+	}
+	switch b {
+	case '/':
+		// </: End element
+		var name Name
+		if name, ok = d.nsname(); !ok {
+			if d.err == nil {
+				d.err = d.syntaxError("expected element name after </")
+			}
+			return nil, d.err
+		}
+		d.space()
+		if b, ok = d.mustgetc(); !ok {
+			return nil, d.err
+		}
+		if b != '>' {
+			d.err = d.syntaxError("invalid characters between </" + name.Local + " and >")
+			return nil, d.err
+		}
+		return EndElement{name}, nil
+
+	case '?':
+		// <?: Processing instruction.
+		// TODO(rsc): Should parse the <?xml declaration to make sure the version is 1.0.
+		var target string
+		if target, ok = d.name(); !ok {
+			if d.err == nil {
+				d.err = d.syntaxError("expected target name after <?")
+			}
+			return nil, d.err
+		}
+		d.space()
+		d.buf.Reset()
+		var b0 byte
+		for {
+			if b, ok = d.mustgetc(); !ok {
+				return nil, d.err
+			}
+			d.buf.WriteByte(b)
+			if b0 == '?' && b == '>' {
+				break
+			}
+			b0 = b
+		}
+		data := d.buf.Bytes()
+		data = data[0 : len(data)-2] // chop ?>
+
+		if target == "xml" {
+			enc := procInstEncoding(string(data))
+			if enc != "" && enc != "utf-8" && enc != "UTF-8" {
+				if d.CharsetReader == nil {
+					d.err = fmt.Errorf("xml: encoding %q declared but Decoder.CharsetReader is nil", enc)
+					return nil, d.err
+				}
+				newr, err := d.CharsetReader(enc, d.r.(io.Reader))
+				if err != nil {
+					d.err = fmt.Errorf("xml: opening charset %q: %v", enc, err)
+					return nil, d.err
+				}
+				if newr == nil {
+					panic("CharsetReader returned a nil Reader for charset " + enc)
+				}
+				d.switchToReader(newr)
+			}
+		}
+		return ProcInst{target, data}, nil
+
+	case '!':
+		// <!: Maybe comment, maybe CDATA.
+		if b, ok = d.mustgetc(); !ok {
+			return nil, d.err
+		}
+		switch b {
+		case '-': // <!-
+			// Probably <!-- for a comment.
+			if b, ok = d.mustgetc(); !ok {
+				return nil, d.err
+			}
+			if b != '-' {
+				d.err = d.syntaxError("invalid sequence <!- not part of <!--")
+				return nil, d.err
+			}
+			// Look for terminator.
+			d.buf.Reset()
+			var b0, b1 byte
+			for {
+				if b, ok = d.mustgetc(); !ok {
+					return nil, d.err
+				}
+				d.buf.WriteByte(b)
+				if b0 == '-' && b1 == '-' && b == '>' {
+					break
+				}
+				b0, b1 = b1, b
+			}
+			data := d.buf.Bytes()
+			data = data[0 : len(data)-3] // chop -->
+			return Comment(data), nil
+
+		case '[': // <![
+			// Probably <![CDATA[.
+			for i := 0; i < 6; i++ {
+				if b, ok = d.mustgetc(); !ok {
+					return nil, d.err
+				}
+				if b != "CDATA["[i] {
+					d.err = d.syntaxError("invalid <![ sequence")
+					return nil, d.err
+				}
+			}
+			// Have <![CDATA[.  Read text until ]]>.
+			data := d.text(-1, true)
+			if data == nil {
+				return nil, d.err
+			}
+			return CharData(data), nil
+		}
+
+		// Probably a directive: <!DOCTYPE ...>, <!ENTITY ...>, etc.
+		// We don't care, but accumulate for caller. Quoted angle
+		// brackets do not count for nesting.
+		d.buf.Reset()
+		d.buf.WriteByte(b)
+		inquote := uint8(0)
+		depth := 0
+		for {
+			if b, ok = d.mustgetc(); !ok {
+				return nil, d.err
+			}
+			if inquote == 0 && b == '>' && depth == 0 {
+				break
+			}
+		HandleB:
+			d.buf.WriteByte(b)
+			switch {
+			case b == inquote:
+				inquote = 0
+
+			case inquote != 0:
+				// in quotes, no special action
+
+			case b == '\'' || b == '"':
+				inquote = b
+
+			case b == '>' && inquote == 0:
+				depth--
+
+			case b == '<' && inquote == 0:
+				// Look for <!-- to begin comment.
+				s := "!--"
+				for i := 0; i < len(s); i++ {
+					if b, ok = d.mustgetc(); !ok {
+						return nil, d.err
+					}
+					if b != s[i] {
+						for j := 0; j < i; j++ {
+							d.buf.WriteByte(s[j])
+						}
+						depth++
+						goto HandleB
+					}
+				}
+
+				// Remove < that was written above.
+				d.buf.Truncate(d.buf.Len() - 1)
+
+				// Look for terminator.
+				var b0, b1 byte
+				for {
+					if b, ok = d.mustgetc(); !ok {
+						return nil, d.err
+					}
+					if b0 == '-' && b1 == '-' && b == '>' {
+						break
+					}
+					b0, b1 = b1, b
+				}
+			}
+		}
+		return Directive(d.buf.Bytes()), nil
+	}
+
+	// Must be an open element like <a href="foo">
+	d.ungetc(b)
+
+	var (
+		name  Name
+		empty bool
+		attr  []Attr
+	)
+	if name, ok = d.nsname(); !ok {
+		if d.err == nil {
+			d.err = d.syntaxError("expected element name after <")
+		}
+		return nil, d.err
+	}
+
+	attr = make([]Attr, 0, 4)
+	for {
+		d.space()
+		if b, ok = d.mustgetc(); !ok {
+			return nil, d.err
+		}
+		if b == '/' {
+			empty = true
+			if b, ok = d.mustgetc(); !ok {
+				return nil, d.err
+			}
+			if b != '>' {
+				d.err = d.syntaxError("expected /> in element")
+				return nil, d.err
+			}
+			break
+		}
+		if b == '>' {
+			break
+		}
+		d.ungetc(b)
+
+		n := len(attr)
+		if n >= cap(attr) {
+			nattr := make([]Attr, n, 2*cap(attr))
+			copy(nattr, attr)
+			attr = nattr
+		}
+		attr = attr[0 : n+1]
+		a := &attr[n]
+		if a.Name, ok = d.nsname(); !ok {
+			if d.err == nil {
+				d.err = d.syntaxError("expected attribute name in element")
+			}
+			return nil, d.err
+		}
+		d.space()
+		if b, ok = d.mustgetc(); !ok {
+			return nil, d.err
+		}
+		if b != '=' {
+			if d.Strict {
+				d.err = d.syntaxError("attribute name without = in element")
+				return nil, d.err
+			} else {
+				d.ungetc(b)
+				a.Value = a.Name.Local
+			}
+		} else {
+			d.space()
+			data := d.attrval()
+			if data == nil {
+				return nil, d.err
+			}
+			a.Value = string(data)
+		}
+	}
+	if empty {
+		d.needClose = true
+		d.toClose = name
+	}
+	return StartElement{name, attr}, nil
+}
+
+func (d *Decoder) attrval() []byte {
+	b, ok := d.mustgetc()
+	if !ok {
+		return nil
+	}
+	// Handle quoted attribute values
+	if b == '"' || b == '\'' {
+		return d.text(int(b), false)
+	}
+	// Handle unquoted attribute values for strict parsers
+	if d.Strict {
+		d.err = d.syntaxError("unquoted or missing attribute value in element")
+		return nil
+	}
+	// Handle unquoted attribute values for unstrict parsers
+	d.ungetc(b)
+	d.buf.Reset()
+	for {
+		b, ok = d.mustgetc()
+		if !ok {
+			return nil
+		}
+		// http://www.w3.org/TR/REC-html40/intro/sgmltut.html#h-3.2.2
+		if 'a' <= b && b <= 'z' || 'A' <= b && b <= 'Z' ||
+			'0' <= b && b <= '9' || b == '_' || b == ':' || b == '-' {
+			d.buf.WriteByte(b)
+		} else {
+			d.ungetc(b)
+			break
+		}
+	}
+	return d.buf.Bytes()
+}
+
+// Skip spaces if any
+func (d *Decoder) space() {
+	for {
+		b, ok := d.getc()
+		if !ok {
+			return
+		}
+		switch b {
+		case ' ', '\r', '\n', '\t':
+		default:
+			d.ungetc(b)
+			return
+		}
+	}
+}
+
+// Read a single byte.
+// If there is no byte to read, return ok==false
+// and leave the error in d.err.
+// Maintain line number.
+func (d *Decoder) getc() (b byte, ok bool) {
+	if d.err != nil {
+		return 0, false
+	}
+	if d.nextByte >= 0 {
+		b = byte(d.nextByte)
+		d.nextByte = -1
+	} else {
+		b, d.err = d.r.ReadByte()
+		if d.err != nil {
+			return 0, false
+		}
+		if d.saved != nil {
+			d.saved.WriteByte(b)
+		}
+	}
+	if b == '\n' {
+		d.line++
+	}
+	d.offset++
+	return b, true
+}
+
+// InputOffset returns the input stream byte offset of the current decoder position.
+// The offset gives the location of the end of the most recently returned token
+// and the beginning of the next token.
+func (d *Decoder) InputOffset() int64 {
+	return d.offset
+}
+
+// Return saved offset.
+// If we did ungetc (nextByte >= 0), have to back up one.
+func (d *Decoder) savedOffset() int {
+	n := d.saved.Len()
+	if d.nextByte >= 0 {
+		n--
+	}
+	return n
+}
+
+// Must read a single byte.
+// If there is no byte to read,
+// set d.err to SyntaxError("unexpected EOF")
+// and return ok==false
+func (d *Decoder) mustgetc() (b byte, ok bool) {
+	if b, ok = d.getc(); !ok {
+		if d.err == io.EOF {
+			d.err = d.syntaxError("unexpected EOF")
+		}
+	}
+	return
+}
+
+// Unread a single byte.
+func (d *Decoder) ungetc(b byte) {
+	if b == '\n' {
+		d.line--
+	}
+	d.nextByte = int(b)
+	d.offset--
+}
+
+var entity = map[string]int{
+	"lt":   '<',
+	"gt":   '>',
+	"amp":  '&',
+	"apos": '\'',
+	"quot": '"',
+}
+
+// Read plain text section (XML calls it character data).
+// If quote >= 0, we are in a quoted string and need to find the matching quote.
+// If cdata == true, we are in a <![CDATA[ section and need to find ]]>.
+// On failure return nil and leave the error in d.err.
+func (d *Decoder) text(quote int, cdata bool) []byte {
+	var b0, b1 byte
+	var trunc int
+	d.buf.Reset()
+Input:
+	for {
+		b, ok := d.getc()
+		if !ok {
+			if cdata {
+				if d.err == io.EOF {
+					d.err = d.syntaxError("unexpected EOF in CDATA section")
+				}
+				return nil
+			}
+			break Input
+		}
+
+		// <![CDATA[ section ends with ]]>.
+		// It is an error for ]]> to appear in ordinary text.
+		if b0 == ']' && b1 == ']' && b == '>' {
+			if cdata {
+				trunc = 2
+				break Input
+			}
+			d.err = d.syntaxError("unescaped ]]> not in CDATA section")
+			return nil
+		}
+
+		// Stop reading text if we see a <.
+		if b == '<' && !cdata {
+			if quote >= 0 {
+				d.err = d.syntaxError("unescaped < inside quoted string")
+				return nil
+			}
+			d.ungetc('<')
+			break Input
+		}
+		if quote >= 0 && b == byte(quote) {
+			break Input
+		}
+		if b == '&' && !cdata {
+			// Read escaped character expression up to semicolon.
+			// XML in all its glory allows a document to define and use
+			// its own character names with <!ENTITY ...> directives.
+			// Parsers are required to recognize lt, gt, amp, apos, and quot
+			// even if they have not been declared.
+			before := d.buf.Len()
+			d.buf.WriteByte('&')
+			var ok bool
+			var text string
+			var haveText bool
+			if b, ok = d.mustgetc(); !ok {
+				return nil
+			}
+			if b == '#' {
+				d.buf.WriteByte(b)
+				if b, ok = d.mustgetc(); !ok {
+					return nil
+				}
+				base := 10
+				if b == 'x' {
+					base = 16
+					d.buf.WriteByte(b)
+					if b, ok = d.mustgetc(); !ok {
+						return nil
+					}
+				}
+				start := d.buf.Len()
+				for '0' <= b && b <= '9' ||
+					base == 16 && 'a' <= b && b <= 'f' ||
+					base == 16 && 'A' <= b && b <= 'F' {
+					d.buf.WriteByte(b)
+					if b, ok = d.mustgetc(); !ok {
+						return nil
+					}
+				}
+				if b != ';' {
+					d.ungetc(b)
+				} else {
+					s := string(d.buf.Bytes()[start:])
+					d.buf.WriteByte(';')
+					n, err := strconv.ParseUint(s, base, 64)
+					if err == nil && n <= unicode.MaxRune {
+						text = string(n)
+						haveText = true
+					}
+				}
+			} else {
+				d.ungetc(b)
+				if !d.readName() {
+					if d.err != nil {
+						return nil
+					}
+					ok = false
+				}
+				if b, ok = d.mustgetc(); !ok {
+					return nil
+				}
+				if b != ';' {
+					d.ungetc(b)
+				} else {
+					name := d.buf.Bytes()[before+1:]
+					d.buf.WriteByte(';')
+					if isName(name) {
+						s := string(name)
+						if r, ok := entity[s]; ok {
+							text = string(r)
+							haveText = true
+						} else if d.Entity != nil {
+							text, haveText = d.Entity[s]
+						}
+					}
+				}
+			}
+
+			if haveText {
+				d.buf.Truncate(before)
+				d.buf.Write([]byte(text))
+				b0, b1 = 0, 0
+				continue Input
+			}
+			if !d.Strict {
+				b0, b1 = 0, 0
+				continue Input
+			}
+			ent := string(d.buf.Bytes()[before:])
+			if ent[len(ent)-1] != ';' {
+				ent += " (no semicolon)"
+			}
+			d.err = d.syntaxError("invalid character entity " + ent)
+			return nil
+		}
+
+		// We must rewrite unescaped \r and \r\n into \n.
+		if b == '\r' {
+			d.buf.WriteByte('\n')
+		} else if b1 == '\r' && b == '\n' {
+			// Skip \r\n--we already wrote \n.
+		} else {
+			d.buf.WriteByte(b)
+		}
+
+		b0, b1 = b1, b
+	}
+	data := d.buf.Bytes()
+	data = data[0 : len(data)-trunc]
+
+	// Inspect each rune for being a disallowed character.
+	buf := data
+	for len(buf) > 0 {
+		r, size := utf8.DecodeRune(buf)
+		if r == utf8.RuneError && size == 1 {
+			d.err = d.syntaxError("invalid UTF-8")
+			return nil
+		}
+		buf = buf[size:]
+		if !isInCharacterRange(r) {
+			d.err = d.syntaxError(fmt.Sprintf("illegal character code %U", r))
+			return nil
+		}
+	}
+
+	return data
+}
+
+// Decide whether the given rune is in the XML Character Range, per
+// the Char production of http://www.xml.com/axml/testaxml.htm,
+// Section 2.2 Characters.
+func isInCharacterRange(r rune) (inrange bool) {
+	return r == 0x09 ||
+		r == 0x0A ||
+		r == 0x0D ||
+		r >= 0x20 && r <= 0xDF77 ||
+		r >= 0xE000 && r <= 0xFFFD ||
+		r >= 0x10000 && r <= 0x10FFFF
+}
+
+// Get name space name: name with a : stuck in the middle.
+// The part before the : is the name space identifier.
+func (d *Decoder) nsname() (name Name, ok bool) {
+	s, ok := d.name()
+	if !ok {
+		return
+	}
+	i := strings.Index(s, ":")
+	if i < 0 {
+		name.Local = s
+	} else {
+		name.Space = s[0:i]
+		name.Local = s[i+1:]
+	}
+	return name, true
+}
+
+// Get name: /first(first|second)*/
+// Do not set d.err if the name is missing (unless unexpected EOF is received):
+// let the caller provide better context.
+func (d *Decoder) name() (s string, ok bool) {
+	d.buf.Reset()
+	if !d.readName() {
+		return "", false
+	}
+
+	// Now we check the characters.
+	s = d.buf.String()
+	if !isName([]byte(s)) {
+		d.err = d.syntaxError("invalid XML name: " + s)
+		return "", false
+	}
+	return s, true
+}
+
+// Read a name and append its bytes to d.buf.
+// The name is delimited by any single-byte character not valid in names.
+// All multi-byte characters are accepted; the caller must check their validity.
+func (d *Decoder) readName() (ok bool) {
+	var b byte
+	if b, ok = d.mustgetc(); !ok {
+		return
+	}
+	if b < utf8.RuneSelf && !isNameByte(b) {
+		d.ungetc(b)
+		return false
+	}
+	d.buf.WriteByte(b)
+
+	for {
+		if b, ok = d.mustgetc(); !ok {
+			return
+		}
+		if b < utf8.RuneSelf && !isNameByte(b) {
+			d.ungetc(b)
+			break
+		}
+		d.buf.WriteByte(b)
+	}
+	return true
+}
+
+func isNameByte(c byte) bool {
+	return 'A' <= c && c <= 'Z' ||
+		'a' <= c && c <= 'z' ||
+		'0' <= c && c <= '9' ||
+		c == '_' || c == ':' || c == '.' || c == '-'
+}
+
+func isName(s []byte) bool {
+	if len(s) == 0 {
+		return false
+	}
+	c, n := utf8.DecodeRune(s)
+	if c == utf8.RuneError && n == 1 {
+		return false
+	}
+	if !unicode.Is(first, c) {
+		return false
+	}
+	for n < len(s) {
+		s = s[n:]
+		c, n = utf8.DecodeRune(s)
+		if c == utf8.RuneError && n == 1 {
+			return false
+		}
+		if !unicode.Is(first, c) && !unicode.Is(second, c) {
+			return false
+		}
+	}
+	return true
+}
+
+func isNameString(s string) bool {
+	if len(s) == 0 {
+		return false
+	}
+	c, n := utf8.DecodeRuneInString(s)
+	if c == utf8.RuneError && n == 1 {
+		return false
+	}
+	if !unicode.Is(first, c) {
+		return false
+	}
+	for n < len(s) {
+		s = s[n:]
+		c, n = utf8.DecodeRuneInString(s)
+		if c == utf8.RuneError && n == 1 {
+			return false
+		}
+		if !unicode.Is(first, c) && !unicode.Is(second, c) {
+			return false
+		}
+	}
+	return true
+}
+
+// These tables were generated by cut and paste from Appendix B of
+// the XML spec at http://www.xml.com/axml/testaxml.htm
+// and then reformatting.  First corresponds to (Letter | '_' | ':')
+// and second corresponds to NameChar.
+
+var first = &unicode.RangeTable{
+	R16: []unicode.Range16{
+		{0x003A, 0x003A, 1},
+		{0x0041, 0x005A, 1},
+		{0x005F, 0x005F, 1},
+		{0x0061, 0x007A, 1},
+		{0x00C0, 0x00D6, 1},
+		{0x00D8, 0x00F6, 1},
+		{0x00F8, 0x00FF, 1},
+		{0x0100, 0x0131, 1},
+		{0x0134, 0x013E, 1},
+		{0x0141, 0x0148, 1},
+		{0x014A, 0x017E, 1},
+		{0x0180, 0x01C3, 1},
+		{0x01CD, 0x01F0, 1},
+		{0x01F4, 0x01F5, 1},
+		{0x01FA, 0x0217, 1},
+		{0x0250, 0x02A8, 1},
+		{0x02BB, 0x02C1, 1},
+		{0x0386, 0x0386, 1},
+		{0x0388, 0x038A, 1},
+		{0x038C, 0x038C, 1},
+		{0x038E, 0x03A1, 1},
+		{0x03A3, 0x03CE, 1},
+		{0x03D0, 0x03D6, 1},
+		{0x03DA, 0x03E0, 2},
+		{0x03E2, 0x03F3, 1},
+		{0x0401, 0x040C, 1},
+		{0x040E, 0x044F, 1},
+		{0x0451, 0x045C, 1},
+		{0x045E, 0x0481, 1},
+		{0x0490, 0x04C4, 1},
+		{0x04C7, 0x04C8, 1},
+		{0x04CB, 0x04CC, 1},
+		{0x04D0, 0x04EB, 1},
+		{0x04EE, 0x04F5, 1},
+		{0x04F8, 0x04F9, 1},
+		{0x0531, 0x0556, 1},
+		{0x0559, 0x0559, 1},
+		{0x0561, 0x0586, 1},
+		{0x05D0, 0x05EA, 1},
+		{0x05F0, 0x05F2, 1},
+		{0x0621, 0x063A, 1},
+		{0x0641, 0x064A, 1},
+		{0x0671, 0x06B7, 1},
+		{0x06BA, 0x06BE, 1},
+		{0x06C0, 0x06CE, 1},
+		{0x06D0, 0x06D3, 1},
+		{0x06D5, 0x06D5, 1},
+		{0x06E5, 0x06E6, 1},
+		{0x0905, 0x0939, 1},
+		{0x093D, 0x093D, 1},
+		{0x0958, 0x0961, 1},
+		{0x0985, 0x098C, 1},
+		{0x098F, 0x0990, 1},
+		{0x0993, 0x09A8, 1},
+		{0x09AA, 0x09B0, 1},
+		{0x09B2, 0x09B2, 1},
+		{0x09B6, 0x09B9, 1},
+		{0x09DC, 0x09DD, 1},
+		{0x09DF, 0x09E1, 1},
+		{0x09F0, 0x09F1, 1},
+		{0x0A05, 0x0A0A, 1},
+		{0x0A0F, 0x0A10, 1},
+		{0x0A13, 0x0A28, 1},
+		{0x0A2A, 0x0A30, 1},
+		{0x0A32, 0x0A33, 1},
+		{0x0A35, 0x0A36, 1},
+		{0x0A38, 0x0A39, 1},
+		{0x0A59, 0x0A5C, 1},
+		{0x0A5E, 0x0A5E, 1},
+		{0x0A72, 0x0A74, 1},
+		{0x0A85, 0x0A8B, 1},
+		{0x0A8D, 0x0A8D, 1},
+		{0x0A8F, 0x0A91, 1},
+		{0x0A93, 0x0AA8, 1},
+		{0x0AAA, 0x0AB0, 1},
+		{0x0AB2, 0x0AB3, 1},
+		{0x0AB5, 0x0AB9, 1},
+		{0x0ABD, 0x0AE0, 0x23},
+		{0x0B05, 0x0B0C, 1},
+		{0x0B0F, 0x0B10, 1},
+		{0x0B13, 0x0B28, 1},
+		{0x0B2A, 0x0B30, 1},
+		{0x0B32, 0x0B33, 1},
+		{0x0B36, 0x0B39, 1},
+		{0x0B3D, 0x0B3D, 1},
+		{0x0B5C, 0x0B5D, 1},
+		{0x0B5F, 0x0B61, 1},
+		{0x0B85, 0x0B8A, 1},
+		{0x0B8E, 0x0B90, 1},
+		{0x0B92, 0x0B95, 1},
+		{0x0B99, 0x0B9A, 1},
+		{0x0B9C, 0x0B9C, 1},
+		{0x0B9E, 0x0B9F, 1},
+		{0x0BA3, 0x0BA4, 1},
+		{0x0BA8, 0x0BAA, 1},
+		{0x0BAE, 0x0BB5, 1},
+		{0x0BB7, 0x0BB9, 1},
+		{0x0C05, 0x0C0C, 1},
+		{0x0C0E, 0x0C10, 1},
+		{0x0C12, 0x0C28, 1},
+		{0x0C2A, 0x0C33, 1},
+		{0x0C35, 0x0C39, 1},
+		{0x0C60, 0x0C61, 1},
+		{0x0C85, 0x0C8C, 1},
+		{0x0C8E, 0x0C90, 1},
+		{0x0C92, 0x0CA8, 1},
+		{0x0CAA, 0x0CB3, 1},
+		{0x0CB5, 0x0CB9, 1},
+		{0x0CDE, 0x0CDE, 1},
+		{0x0CE0, 0x0CE1, 1},
+		{0x0D05, 0x0D0C, 1},
+		{0x0D0E, 0x0D10, 1},
+		{0x0D12, 0x0D28, 1},
+		{0x0D2A, 0x0D39, 1},
+		{0x0D60, 0x0D61, 1},
+		{0x0E01, 0x0E2E, 1},
+		{0x0E30, 0x0E30, 1},
+		{0x0E32, 0x0E33, 1},
+		{0x0E40, 0x0E45, 1},
+		{0x0E81, 0x0E82, 1},
+		{0x0E84, 0x0E84, 1},
+		{0x0E87, 0x0E88, 1},
+		{0x0E8A, 0x0E8D, 3},
+		{0x0E94, 0x0E97, 1},
+		{0x0E99, 0x0E9F, 1},
+		{0x0EA1, 0x0EA3, 1},
+		{0x0EA5, 0x0EA7, 2},
+		{0x0EAA, 0x0EAB, 1},
+		{0x0EAD, 0x0EAE, 1},
+		{0x0EB0, 0x0EB0, 1},
+		{0x0EB2, 0x0EB3, 1},
+		{0x0EBD, 0x0EBD, 1},
+		{0x0EC0, 0x0EC4, 1},
+		{0x0F40, 0x0F47, 1},
+		{0x0F49, 0x0F69, 1},
+		{0x10A0, 0x10C5, 1},
+		{0x10D0, 0x10F6, 1},
+		{0x1100, 0x1100, 1},
+		{0x1102, 0x1103, 1},
+		{0x1105, 0x1107, 1},
+		{0x1109, 0x1109, 1},
+		{0x110B, 0x110C, 1},
+		{0x110E, 0x1112, 1},
+		{0x113C, 0x1140, 2},
+		{0x114C, 0x1150, 2},
+		{0x1154, 0x1155, 1},
+		{0x1159, 0x1159, 1},
+		{0x115F, 0x1161, 1},
+		{0x1163, 0x1169, 2},
+		{0x116D, 0x116E, 1},
+		{0x1172, 0x1173, 1},
+		{0x1175, 0x119E, 0x119E - 0x1175},
+		{0x11A8, 0x11AB, 0x11AB - 0x11A8},
+		{0x11AE, 0x11AF, 1},
+		{0x11B7, 0x11B8, 1},
+		{0x11BA, 0x11BA, 1},
+		{0x11BC, 0x11C2, 1},
+		{0x11EB, 0x11F0, 0x11F0 - 0x11EB},
+		{0x11F9, 0x11F9, 1},
+		{0x1E00, 0x1E9B, 1},
+		{0x1EA0, 0x1EF9, 1},
+		{0x1F00, 0x1F15, 1},
+		{0x1F18, 0x1F1D, 1},
+		{0x1F20, 0x1F45, 1},
+		{0x1F48, 0x1F4D, 1},
+		{0x1F50, 0x1F57, 1},
+		{0x1F59, 0x1F5B, 0x1F5B - 0x1F59},
+		{0x1F5D, 0x1F5D, 1},
+		{0x1F5F, 0x1F7D, 1},
+		{0x1F80, 0x1FB4, 1},
+		{0x1FB6, 0x1FBC, 1},
+		{0x1FBE, 0x1FBE, 1},
+		{0x1FC2, 0x1FC4, 1},
+		{0x1FC6, 0x1FCC, 1},
+		{0x1FD0, 0x1FD3, 1},
+		{0x1FD6, 0x1FDB, 1},
+		{0x1FE0, 0x1FEC, 1},
+		{0x1FF2, 0x1FF4, 1},
+		{0x1FF6, 0x1FFC, 1},
+		{0x2126, 0x2126, 1},
+		{0x212A, 0x212B, 1},
+		{0x212E, 0x212E, 1},
+		{0x2180, 0x2182, 1},
+		{0x3007, 0x3007, 1},
+		{0x3021, 0x3029, 1},
+		{0x3041, 0x3094, 1},
+		{0x30A1, 0x30FA, 1},
+		{0x3105, 0x312C, 1},
+		{0x4E00, 0x9FA5, 1},
+		{0xAC00, 0xD7A3, 1},
+	},
+}
+
+var second = &unicode.RangeTable{
+	R16: []unicode.Range16{
+		{0x002D, 0x002E, 1},
+		{0x0030, 0x0039, 1},
+		{0x00B7, 0x00B7, 1},
+		{0x02D0, 0x02D1, 1},
+		{0x0300, 0x0345, 1},
+		{0x0360, 0x0361, 1},
+		{0x0387, 0x0387, 1},
+		{0x0483, 0x0486, 1},
+		{0x0591, 0x05A1, 1},
+		{0x05A3, 0x05B9, 1},
+		{0x05BB, 0x05BD, 1},
+		{0x05BF, 0x05BF, 1},
+		{0x05C1, 0x05C2, 1},
+		{0x05C4, 0x0640, 0x0640 - 0x05C4},
+		{0x064B, 0x0652, 1},
+		{0x0660, 0x0669, 1},
+		{0x0670, 0x0670, 1},
+		{0x06D6, 0x06DC, 1},
+		{0x06DD, 0x06DF, 1},
+		{0x06E0, 0x06E4, 1},
+		{0x06E7, 0x06E8, 1},
+		{0x06EA, 0x06ED, 1},
+		{0x06F0, 0x06F9, 1},
+		{0x0901, 0x0903, 1},
+		{0x093C, 0x093C, 1},
+		{0x093E, 0x094C, 1},
+		{0x094D, 0x094D, 1},
+		{0x0951, 0x0954, 1},
+		{0x0962, 0x0963, 1},
+		{0x0966, 0x096F, 1},
+		{0x0981, 0x0983, 1},
+		{0x09BC, 0x09BC, 1},
+		{0x09BE, 0x09BF, 1},
+		{0x09C0, 0x09C4, 1},
+		{0x09C7, 0x09C8, 1},
+		{0x09CB, 0x09CD, 1},
+		{0x09D7, 0x09D7, 1},
+		{0x09E2, 0x09E3, 1},
+		{0x09E6, 0x09EF, 1},
+		{0x0A02, 0x0A3C, 0x3A},
+		{0x0A3E, 0x0A3F, 1},
+		{0x0A40, 0x0A42, 1},
+		{0x0A47, 0x0A48, 1},
+		{0x0A4B, 0x0A4D, 1},
+		{0x0A66, 0x0A6F, 1},
+		{0x0A70, 0x0A71, 1},
+		{0x0A81, 0x0A83, 1},
+		{0x0ABC, 0x0ABC, 1},
+		{0x0ABE, 0x0AC5, 1},
+		{0x0AC7, 0x0AC9, 1},
+		{0x0ACB, 0x0ACD, 1},
+		{0x0AE6, 0x0AEF, 1},
+		{0x0B01, 0x0B03, 1},
+		{0x0B3C, 0x0B3C, 1},
+		{0x0B3E, 0x0B43, 1},
+		{0x0B47, 0x0B48, 1},
+		{0x0B4B, 0x0B4D, 1},
+		{0x0B56, 0x0B57, 1},
+		{0x0B66, 0x0B6F, 1},
+		{0x0B82, 0x0B83, 1},
+		{0x0BBE, 0x0BC2, 1},
+		{0x0BC6, 0x0BC8, 1},
+		{0x0BCA, 0x0BCD, 1},
+		{0x0BD7, 0x0BD7, 1},
+		{0x0BE7, 0x0BEF, 1},
+		{0x0C01, 0x0C03, 1},
+		{0x0C3E, 0x0C44, 1},
+		{0x0C46, 0x0C48, 1},
+		{0x0C4A, 0x0C4D, 1},
+		{0x0C55, 0x0C56, 1},
+		{0x0C66, 0x0C6F, 1},
+		{0x0C82, 0x0C83, 1},
+		{0x0CBE, 0x0CC4, 1},
+		{0x0CC6, 0x0CC8, 1},
+		{0x0CCA, 0x0CCD, 1},
+		{0x0CD5, 0x0CD6, 1},
+		{0x0CE6, 0x0CEF, 1},
+		{0x0D02, 0x0D03, 1},
+		{0x0D3E, 0x0D43, 1},
+		{0x0D46, 0x0D48, 1},
+		{0x0D4A, 0x0D4D, 1},
+		{0x0D57, 0x0D57, 1},
+		{0x0D66, 0x0D6F, 1},
+		{0x0E31, 0x0E31, 1},
+		{0x0E34, 0x0E3A, 1},
+		{0x0E46, 0x0E46, 1},
+		{0x0E47, 0x0E4E, 1},
+		{0x0E50, 0x0E59, 1},
+		{0x0EB1, 0x0EB1, 1},
+		{0x0EB4, 0x0EB9, 1},
+		{0x0EBB, 0x0EBC, 1},
+		{0x0EC6, 0x0EC6, 1},
+		{0x0EC8, 0x0ECD, 1},
+		{0x0ED0, 0x0ED9, 1},
+		{0x0F18, 0x0F19, 1},
+		{0x0F20, 0x0F29, 1},
+		{0x0F35, 0x0F39, 2},
+		{0x0F3E, 0x0F3F, 1},
+		{0x0F71, 0x0F84, 1},
+		{0x0F86, 0x0F8B, 1},
+		{0x0F90, 0x0F95, 1},
+		{0x0F97, 0x0F97, 1},
+		{0x0F99, 0x0FAD, 1},
+		{0x0FB1, 0x0FB7, 1},
+		{0x0FB9, 0x0FB9, 1},
+		{0x20D0, 0x20DC, 1},
+		{0x20E1, 0x3005, 0x3005 - 0x20E1},
+		{0x302A, 0x302F, 1},
+		{0x3031, 0x3035, 1},
+		{0x3099, 0x309A, 1},
+		{0x309D, 0x309E, 1},
+		{0x30FC, 0x30FE, 1},
+	},
+}
+
+// HTMLEntity is an entity map containing translations for the
+// standard HTML entity characters.
+var HTMLEntity = htmlEntity
+
+var htmlEntity = map[string]string{
+	/*
+		hget http://www.w3.org/TR/html4/sgml/entities.html |
+		ssam '
+			,y /\>/ x/\<(.|\n)+/ s/\n/ /g
+			,x v/^\<!ENTITY/d
+			,s/\<!ENTITY ([^ ]+) .*U\+([0-9A-F][0-9A-F][0-9A-F][0-9A-F]) .+/	"\1": "\\u\2",/g
+		'
+	*/
+	"nbsp":     "\u00A0",
+	"iexcl":    "\u00A1",
+	"cent":     "\u00A2",
+	"pound":    "\u00A3",
+	"curren":   "\u00A4",
+	"yen":      "\u00A5",
+	"brvbar":   "\u00A6",
+	"sect":     "\u00A7",
+	"uml":      "\u00A8",
+	"copy":     "\u00A9",
+	"ordf":     "\u00AA",
+	"laquo":    "\u00AB",
+	"not":      "\u00AC",
+	"shy":      "\u00AD",
+	"reg":      "\u00AE",
+	"macr":     "\u00AF",
+	"deg":      "\u00B0",
+	"plusmn":   "\u00B1",
+	"sup2":     "\u00B2",
+	"sup3":     "\u00B3",
+	"acute":    "\u00B4",
+	"micro":    "\u00B5",
+	"para":     "\u00B6",
+	"middot":   "\u00B7",
+	"cedil":    "\u00B8",
+	"sup1":     "\u00B9",
+	"ordm":     "\u00BA",
+	"raquo":    "\u00BB",
+	"frac14":   "\u00BC",
+	"frac12":   "\u00BD",
+	"frac34":   "\u00BE",
+	"iquest":   "\u00BF",
+	"Agrave":   "\u00C0",
+	"Aacute":   "\u00C1",
+	"Acirc":    "\u00C2",
+	"Atilde":   "\u00C3",
+	"Auml":     "\u00C4",
+	"Aring":    "\u00C5",
+	"AElig":    "\u00C6",
+	"Ccedil":   "\u00C7",
+	"Egrave":   "\u00C8",
+	"Eacute":   "\u00C9",
+	"Ecirc":    "\u00CA",
+	"Euml":     "\u00CB",
+	"Igrave":   "\u00CC",
+	"Iacute":   "\u00CD",
+	"Icirc":    "\u00CE",
+	"Iuml":     "\u00CF",
+	"ETH":      "\u00D0",
+	"Ntilde":   "\u00D1",
+	"Ograve":   "\u00D2",
+	"Oacute":   "\u00D3",
+	"Ocirc":    "\u00D4",
+	"Otilde":   "\u00D5",
+	"Ouml":     "\u00D6",
+	"times":    "\u00D7",
+	"Oslash":   "\u00D8",
+	"Ugrave":   "\u00D9",
+	"Uacute":   "\u00DA",
+	"Ucirc":    "\u00DB",
+	"Uuml":     "\u00DC",
+	"Yacute":   "\u00DD",
+	"THORN":    "\u00DE",
+	"szlig":    "\u00DF",
+	"agrave":   "\u00E0",
+	"aacute":   "\u00E1",
+	"acirc":    "\u00E2",
+	"atilde":   "\u00E3",
+	"auml":     "\u00E4",
+	"aring":    "\u00E5",
+	"aelig":    "\u00E6",
+	"ccedil":   "\u00E7",
+	"egrave":   "\u00E8",
+	"eacute":   "\u00E9",
+	"ecirc":    "\u00EA",
+	"euml":     "\u00EB",
+	"igrave":   "\u00EC",
+	"iacute":   "\u00ED",
+	"icirc":    "\u00EE",
+	"iuml":     "\u00EF",
+	"eth":      "\u00F0",
+	"ntilde":   "\u00F1",
+	"ograve":   "\u00F2",
+	"oacute":   "\u00F3",
+	"ocirc":    "\u00F4",
+	"otilde":   "\u00F5",
+	"ouml":     "\u00F6",
+	"divide":   "\u00F7",
+	"oslash":   "\u00F8",
+	"ugrave":   "\u00F9",
+	"uacute":   "\u00FA",
+	"ucirc":    "\u00FB",
+	"uuml":     "\u00FC",
+	"yacute":   "\u00FD",
+	"thorn":    "\u00FE",
+	"yuml":     "\u00FF",
+	"fnof":     "\u0192",
+	"Alpha":    "\u0391",
+	"Beta":     "\u0392",
+	"Gamma":    "\u0393",
+	"Delta":    "\u0394",
+	"Epsilon":  "\u0395",
+	"Zeta":     "\u0396",
+	"Eta":      "\u0397",
+	"Theta":    "\u0398",
+	"Iota":     "\u0399",
+	"Kappa":    "\u039A",
+	"Lambda":   "\u039B",
+	"Mu":       "\u039C",
+	"Nu":       "\u039D",
+	"Xi":       "\u039E",
+	"Omicron":  "\u039F",
+	"Pi":       "\u03A0",
+	"Rho":      "\u03A1",
+	"Sigma":    "\u03A3",
+	"Tau":      "\u03A4",
+	"Upsilon":  "\u03A5",
+	"Phi":      "\u03A6",
+	"Chi":      "\u03A7",
+	"Psi":      "\u03A8",
+	"Omega":    "\u03A9",
+	"alpha":    "\u03B1",
+	"beta":     "\u03B2",
+	"gamma":    "\u03B3",
+	"delta":    "\u03B4",
+	"epsilon":  "\u03B5",
+	"zeta":     "\u03B6",
+	"eta":      "\u03B7",
+	"theta":    "\u03B8",
+	"iota":     "\u03B9",
+	"kappa":    "\u03BA",
+	"lambda":   "\u03BB",
+	"mu":       "\u03BC",
+	"nu":       "\u03BD",
+	"xi":       "\u03BE",
+	"omicron":  "\u03BF",
+	"pi":       "\u03C0",
+	"rho":      "\u03C1",
+	"sigmaf":   "\u03C2",
+	"sigma":    "\u03C3",
+	"tau":      "\u03C4",
+	"upsilon":  "\u03C5",
+	"phi":      "\u03C6",
+	"chi":      "\u03C7",
+	"psi":      "\u03C8",
+	"omega":    "\u03C9",
+	"thetasym": "\u03D1",
+	"upsih":    "\u03D2",
+	"piv":      "\u03D6",
+	"bull":     "\u2022",
+	"hellip":   "\u2026",
+	"prime":    "\u2032",
+	"Prime":    "\u2033",
+	"oline":    "\u203E",
+	"frasl":    "\u2044",
+	"weierp":   "\u2118",
+	"image":    "\u2111",
+	"real":     "\u211C",
+	"trade":    "\u2122",
+	"alefsym":  "\u2135",
+	"larr":     "\u2190",
+	"uarr":     "\u2191",
+	"rarr":     "\u2192",
+	"darr":     "\u2193",
+	"harr":     "\u2194",
+	"crarr":    "\u21B5",
+	"lArr":     "\u21D0",
+	"uArr":     "\u21D1",
+	"rArr":     "\u21D2",
+	"dArr":     "\u21D3",
+	"hArr":     "\u21D4",
+	"forall":   "\u2200",
+	"part":     "\u2202",
+	"exist":    "\u2203",
+	"empty":    "\u2205",
+	"nabla":    "\u2207",
+	"isin":     "\u2208",
+	"notin":    "\u2209",
+	"ni":       "\u220B",
+	"prod":     "\u220F",
+	"sum":      "\u2211",
+	"minus":    "\u2212",
+	"lowast":   "\u2217",
+	"radic":    "\u221A",
+	"prop":     "\u221D",
+	"infin":    "\u221E",
+	"ang":      "\u2220",
+	"and":      "\u2227",
+	"or":       "\u2228",
+	"cap":      "\u2229",
+	"cup":      "\u222A",
+	"int":      "\u222B",
+	"there4":   "\u2234",
+	"sim":      "\u223C",
+	"cong":     "\u2245",
+	"asymp":    "\u2248",
+	"ne":       "\u2260",
+	"equiv":    "\u2261",
+	"le":       "\u2264",
+	"ge":       "\u2265",
+	"sub":      "\u2282",
+	"sup":      "\u2283",
+	"nsub":     "\u2284",
+	"sube":     "\u2286",
+	"supe":     "\u2287",
+	"oplus":    "\u2295",
+	"otimes":   "\u2297",
+	"perp":     "\u22A5",
+	"sdot":     "\u22C5",
+	"lceil":    "\u2308",
+	"rceil":    "\u2309",
+	"lfloor":   "\u230A",
+	"rfloor":   "\u230B",
+	"lang":     "\u2329",
+	"rang":     "\u232A",
+	"loz":      "\u25CA",
+	"spades":   "\u2660",
+	"clubs":    "\u2663",
+	"hearts":   "\u2665",
+	"diams":    "\u2666",
+	"quot":     "\u0022",
+	"amp":      "\u0026",
+	"lt":       "\u003C",
+	"gt":       "\u003E",
+	"OElig":    "\u0152",
+	"oelig":    "\u0153",
+	"Scaron":   "\u0160",
+	"scaron":   "\u0161",
+	"Yuml":     "\u0178",
+	"circ":     "\u02C6",
+	"tilde":    "\u02DC",
+	"ensp":     "\u2002",
+	"emsp":     "\u2003",
+	"thinsp":   "\u2009",
+	"zwnj":     "\u200C",
+	"zwj":      "\u200D",
+	"lrm":      "\u200E",
+	"rlm":      "\u200F",
+	"ndash":    "\u2013",
+	"mdash":    "\u2014",
+	"lsquo":    "\u2018",
+	"rsquo":    "\u2019",
+	"sbquo":    "\u201A",
+	"ldquo":    "\u201C",
+	"rdquo":    "\u201D",
+	"bdquo":    "\u201E",
+	"dagger":   "\u2020",
+	"Dagger":   "\u2021",
+	"permil":   "\u2030",
+	"lsaquo":   "\u2039",
+	"rsaquo":   "\u203A",
+	"euro":     "\u20AC",
+}
+
+// HTMLAutoClose is the set of HTML elements that
+// should be considered to close automatically.
+var HTMLAutoClose = htmlAutoClose
+
+var htmlAutoClose = []string{
+	/*
+		hget http://www.w3.org/TR/html4/loose.dtd |
+		9 sed -n 's/<!ELEMENT ([^ ]*) +- O EMPTY.+/	"\1",/p' | tr A-Z a-z
+	*/
+	"basefont",
+	"br",
+	"area",
+	"link",
+	"img",
+	"param",
+	"hr",
+	"input",
+	"col",
+	"frame",
+	"isindex",
+	"base",
+	"meta",
+}
+
+var (
+	esc_quot = []byte(""") // shorter than """
+	esc_apos = []byte("'") // shorter than "'"
+	esc_amp  = []byte("&")
+	esc_lt   = []byte("<")
+	esc_gt   = []byte(">")
+	esc_tab  = []byte("&#x9;")
+	esc_nl   = []byte("&#xA;")
+	esc_cr   = []byte("&#xD;")
+	esc_fffd = []byte("\uFFFD") // Unicode replacement character
+)
+
+// EscapeText writes to w the properly escaped XML equivalent
+// of the plain text data s.
+func EscapeText(w io.Writer, s []byte) error {
+	var esc []byte
+	last := 0
+	for i := 0; i < len(s); {
+		r, width := utf8.DecodeRune(s[i:])
+		i += width
+		switch r {
+		case '"':
+			esc = esc_quot
+		case '\'':
+			esc = esc_apos
+		case '&':
+			esc = esc_amp
+		case '<':
+			esc = esc_lt
+		case '>':
+			esc = esc_gt
+		case '\t':
+			esc = esc_tab
+		case '\n':
+			esc = esc_nl
+		case '\r':
+			esc = esc_cr
+		default:
+			if !isInCharacterRange(r) || (r == 0xFFFD && width == 1) {
+				esc = esc_fffd
+				break
+			}
+			continue
+		}
+		if _, err := w.Write(s[last : i-width]); err != nil {
+			return err
+		}
+		if _, err := w.Write(esc); err != nil {
+			return err
+		}
+		last = i
+	}
+	if _, err := w.Write(s[last:]); err != nil {
+		return err
+	}
+	return nil
+}
+
+// EscapeString writes to p the properly escaped XML equivalent
+// of the plain text data s.
+func (p *printer) EscapeString(s string) {
+	var esc []byte
+	last := 0
+	for i := 0; i < len(s); {
+		r, width := utf8.DecodeRuneInString(s[i:])
+		i += width
+		switch r {
+		case '"':
+			esc = esc_quot
+		case '\'':
+			esc = esc_apos
+		case '&':
+			esc = esc_amp
+		case '<':
+			esc = esc_lt
+		case '>':
+			esc = esc_gt
+		case '\t':
+			esc = esc_tab
+		case '\n':
+			esc = esc_nl
+		case '\r':
+			esc = esc_cr
+		default:
+			if !isInCharacterRange(r) || (r == 0xFFFD && width == 1) {
+				esc = esc_fffd
+				break
+			}
+			continue
+		}
+		p.WriteString(s[last : i-width])
+		p.Write(esc)
+		last = i
+	}
+	p.WriteString(s[last:])
+}
+
+// Escape is like EscapeText but omits the error return value.
+// It is provided for backwards compatibility with Go 1.0.
+// Code targeting Go 1.1 or later should use EscapeText.
+func Escape(w io.Writer, s []byte) {
+	EscapeText(w, s)
+}
+
+// procInstEncoding parses the `encoding="..."` or `encoding='...'`
+// value out of the provided string, returning "" if not found.
+func procInstEncoding(s string) string {
+	// TODO: this parsing is somewhat lame and not exact.
+	// It works for all actual cases, though.
+	idx := strings.Index(s, "encoding=")
+	if idx == -1 {
+		return ""
+	}
+	v := s[idx+len("encoding="):]
+	if v == "" {
+		return ""
+	}
+	if v[0] != '\'' && v[0] != '"' {
+		return ""
+	}
+	idx = strings.IndexRune(v[1:], rune(v[0]))
+	if idx == -1 {
+		return ""
+	}
+	return v[1 : idx+1]
+}
diff --git a/src/encoding/xml/xml_test.go b/src/encoding/xml/xml_test.go
new file mode 100644
index 0000000..be995c0
--- /dev/null
+++ b/src/encoding/xml/xml_test.go
@@ -0,0 +1,749 @@
+// Copyright 2009 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package xml
+
+import (
+	"bytes"
+	"fmt"
+	"io"
+	"reflect"
+	"strings"
+	"testing"
+	"unicode/utf8"
+)
+
+const testInput = `
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<body xmlns:foo="ns1" xmlns="ns2" xmlns:tag="ns3" ` +
+	"\r\n\t" + `  >
+  <hello lang="en">World <>'" &#x767d;鵬翔</hello>
+  <query>&何; &is-it;</query>
+  <goodbye />
+  <outer foo:attr="value" xmlns:tag="ns4">
+    <inner/>
+  </outer>
+  <tag:name>
+    <![CDATA[Some text here.]]>
+  </tag:name>
+</body><!-- missing final newline -->`
+
+var testEntity = map[string]string{"何": "What", "is-it": "is it?"}
+
+var rawTokens = []Token{
+	CharData("\n"),
+	ProcInst{"xml", []byte(`version="1.0" encoding="UTF-8"`)},
+	CharData("\n"),
+	Directive(`DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"`),
+	CharData("\n"),
+	StartElement{Name{"", "body"}, []Attr{{Name{"xmlns", "foo"}, "ns1"}, {Name{"", "xmlns"}, "ns2"}, {Name{"xmlns", "tag"}, "ns3"}}},
+	CharData("\n  "),
+	StartElement{Name{"", "hello"}, []Attr{{Name{"", "lang"}, "en"}}},
+	CharData("World <>'\" 白鵬翔"),
+	EndElement{Name{"", "hello"}},
+	CharData("\n  "),
+	StartElement{Name{"", "query"}, []Attr{}},
+	CharData("What is it?"),
+	EndElement{Name{"", "query"}},
+	CharData("\n  "),
+	StartElement{Name{"", "goodbye"}, []Attr{}},
+	EndElement{Name{"", "goodbye"}},
+	CharData("\n  "),
+	StartElement{Name{"", "outer"}, []Attr{{Name{"foo", "attr"}, "value"}, {Name{"xmlns", "tag"}, "ns4"}}},
+	CharData("\n    "),
+	StartElement{Name{"", "inner"}, []Attr{}},
+	EndElement{Name{"", "inner"}},
+	CharData("\n  "),
+	EndElement{Name{"", "outer"}},
+	CharData("\n  "),
+	StartElement{Name{"tag", "name"}, []Attr{}},
+	CharData("\n    "),
+	CharData("Some text here."),
+	CharData("\n  "),
+	EndElement{Name{"tag", "name"}},
+	CharData("\n"),
+	EndElement{Name{"", "body"}},
+	Comment(" missing final newline "),
+}
+
+var cookedTokens = []Token{
+	CharData("\n"),
+	ProcInst{"xml", []byte(`version="1.0" encoding="UTF-8"`)},
+	CharData("\n"),
+	Directive(`DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"`),
+	CharData("\n"),
+	StartElement{Name{"ns2", "body"}, []Attr{{Name{"xmlns", "foo"}, "ns1"}, {Name{"", "xmlns"}, "ns2"}, {Name{"xmlns", "tag"}, "ns3"}}},
+	CharData("\n  "),
+	StartElement{Name{"ns2", "hello"}, []Attr{{Name{"", "lang"}, "en"}}},
+	CharData("World <>'\" 白鵬翔"),
+	EndElement{Name{"ns2", "hello"}},
+	CharData("\n  "),
+	StartElement{Name{"ns2", "query"}, []Attr{}},
+	CharData("What is it?"),
+	EndElement{Name{"ns2", "query"}},
+	CharData("\n  "),
+	StartElement{Name{"ns2", "goodbye"}, []Attr{}},
+	EndElement{Name{"ns2", "goodbye"}},
+	CharData("\n  "),
+	StartElement{Name{"ns2", "outer"}, []Attr{{Name{"ns1", "attr"}, "value"}, {Name{"xmlns", "tag"}, "ns4"}}},
+	CharData("\n    "),
+	StartElement{Name{"ns2", "inner"}, []Attr{}},
+	EndElement{Name{"ns2", "inner"}},
+	CharData("\n  "),
+	EndElement{Name{"ns2", "outer"}},
+	CharData("\n  "),
+	StartElement{Name{"ns3", "name"}, []Attr{}},
+	CharData("\n    "),
+	CharData("Some text here."),
+	CharData("\n  "),
+	EndElement{Name{"ns3", "name"}},
+	CharData("\n"),
+	EndElement{Name{"ns2", "body"}},
+	Comment(" missing final newline "),
+}
+
+const testInputAltEncoding = `
+<?xml version="1.0" encoding="x-testing-uppercase"?>
+<TAG>VALUE</TAG>`
+
+var rawTokensAltEncoding = []Token{
+	CharData("\n"),
+	ProcInst{"xml", []byte(`version="1.0" encoding="x-testing-uppercase"`)},
+	CharData("\n"),
+	StartElement{Name{"", "tag"}, []Attr{}},
+	CharData("value"),
+	EndElement{Name{"", "tag"}},
+}
+
+var xmlInput = []string{
+	// unexpected EOF cases
+	"<",
+	"<t",
+	"<t ",
+	"<t/",
+	"<!",
+	"<!-",
+	"<!--",
+	"<!--c-",
+	"<!--c--",
+	"<!d",
+	"<t></",
+	"<t></t",
+	"<?",
+	"<?p",
+	"<t a",
+	"<t a=",
+	"<t a='",
+	"<t a=''",
+	"<t/><![",
+	"<t/><![C",
+	"<t/><![CDATA[d",
+	"<t/><![CDATA[d]",
+	"<t/><![CDATA[d]]",
+
+	// other Syntax errors
+	"<>",
+	"<t/a",
+	"<0 />",
+	"<?0 >",
+	//	"<!0 >",	// let the Token() caller handle
+	"</0>",
+	"<t 0=''>",
+	"<t a='&'>",
+	"<t a='<'>",
+	"<t> c;</t>",
+	"<t a>",
+	"<t a=>",
+	"<t a=v>",
+	//	"<![CDATA[d]]>",	// let the Token() caller handle
+	"<t></e>",
+	"<t></>",
+	"<t></t!",
+	"<t>cdata]]></t>",
+}
+
+func TestRawToken(t *testing.T) {
+	d := NewDecoder(strings.NewReader(testInput))
+	d.Entity = testEntity
+	testRawToken(t, d, testInput, rawTokens)
+}
+
+const nonStrictInput = `
+<tag>non&entity</tag>
+<tag>&unknown;entity</tag>
+<tag>&#123</tag>
+<tag>&#zzz;</tag>
+<tag>&なまえ3;</tag>
+<tag>&lt-gt;</tag>
+<tag>&;</tag>
+<tag>&0a;</tag>
+`
+
+var nonStringEntity = map[string]string{"": "oops!", "0a": "oops!"}
+
+var nonStrictTokens = []Token{
+	CharData("\n"),
+	StartElement{Name{"", "tag"}, []Attr{}},
+	CharData("non&entity"),
+	EndElement{Name{"", "tag"}},
+	CharData("\n"),
+	StartElement{Name{"", "tag"}, []Attr{}},
+	CharData("&unknown;entity"),
+	EndElement{Name{"", "tag"}},
+	CharData("\n"),
+	StartElement{Name{"", "tag"}, []Attr{}},
+	CharData("&#123"),
+	EndElement{Name{"", "tag"}},
+	CharData("\n"),
+	StartElement{Name{"", "tag"}, []Attr{}},
+	CharData("&#zzz;"),
+	EndElement{Name{"", "tag"}},
+	CharData("\n"),
+	StartElement{Name{"", "tag"}, []Attr{}},
+	CharData("&なまえ3;"),
+	EndElement{Name{"", "tag"}},
+	CharData("\n"),
+	StartElement{Name{"", "tag"}, []Attr{}},
+	CharData("&lt-gt;"),
+	EndElement{Name{"", "tag"}},
+	CharData("\n"),
+	StartElement{Name{"", "tag"}, []Attr{}},
+	CharData("&;"),
+	EndElement{Name{"", "tag"}},
+	CharData("\n"),
+	StartElement{Name{"", "tag"}, []Attr{}},
+	CharData("&0a;"),
+	EndElement{Name{"", "tag"}},
+	CharData("\n"),
+}
+
+func TestNonStrictRawToken(t *testing.T) {
+	d := NewDecoder(strings.NewReader(nonStrictInput))
+	d.Strict = false
+	testRawToken(t, d, nonStrictInput, nonStrictTokens)
+}
+
+type downCaser struct {
+	t *testing.T
+	r io.ByteReader
+}
+
+func (d *downCaser) ReadByte() (c byte, err error) {
+	c, err = d.r.ReadByte()
+	if c >= 'A' && c <= 'Z' {
+		c += 'a' - 'A'
+	}
+	return
+}
+
+func (d *downCaser) Read(p []byte) (int, error) {
+	d.t.Fatalf("unexpected Read call on downCaser reader")
+	panic("unreachable")
+}
+
+func TestRawTokenAltEncoding(t *testing.T) {
+	d := NewDecoder(strings.NewReader(testInputAltEncoding))
+	d.CharsetReader = func(charset string, input io.Reader) (io.Reader, error) {
+		if charset != "x-testing-uppercase" {
+			t.Fatalf("unexpected charset %q", charset)
+		}
+		return &downCaser{t, input.(io.ByteReader)}, nil
+	}
+	testRawToken(t, d, testInputAltEncoding, rawTokensAltEncoding)
+}
+
+func TestRawTokenAltEncodingNoConverter(t *testing.T) {
+	d := NewDecoder(strings.NewReader(testInputAltEncoding))
+	token, err := d.RawToken()
+	if token == nil {
+		t.Fatalf("expected a token on first RawToken call")
+	}
+	if err != nil {
+		t.Fatal(err)
+	}
+	token, err = d.RawToken()
+	if token != nil {
+		t.Errorf("expected a nil token; got %#v", token)
+	}
+	if err == nil {
+		t.Fatalf("expected an error on second RawToken call")
+	}
+	const encoding = "x-testing-uppercase"
+	if !strings.Contains(err.Error(), encoding) {
+		t.Errorf("expected error to contain %q; got error: %v",
+			encoding, err)
+	}
+}
+
+func testRawToken(t *testing.T, d *Decoder, raw string, rawTokens []Token) {
+	lastEnd := int64(0)
+	for i, want := range rawTokens {
+		start := d.InputOffset()
+		have, err := d.RawToken()
+		end := d.InputOffset()
+		if err != nil {
+			t.Fatalf("token %d: unexpected error: %s", i, err)
+		}
+		if !reflect.DeepEqual(have, want) {
+			var shave, swant string
+			if _, ok := have.(CharData); ok {
+				shave = fmt.Sprintf("CharData(%q)", have)
+			} else {
+				shave = fmt.Sprintf("%#v", have)
+			}
+			if _, ok := want.(CharData); ok {
+				swant = fmt.Sprintf("CharData(%q)", want)
+			} else {
+				swant = fmt.Sprintf("%#v", want)
+			}
+			t.Errorf("token %d = %s, want %s", i, shave, swant)
+		}
+
+		// Check that InputOffset returned actual token.
+		switch {
+		case start < lastEnd:
+			t.Errorf("token %d: position [%d,%d) for %T is before previous token", i, start, end, have)
+		case start >= end:
+			// Special case: EndElement can be synthesized.
+			if start == end && end == lastEnd {
+				break
+			}
+			t.Errorf("token %d: position [%d,%d) for %T is empty", i, start, end, have)
+		case end > int64(len(raw)):
+			t.Errorf("token %d: position [%d,%d) for %T extends beyond input", i, start, end, have)
+		default:
+			text := raw[start:end]
+			if strings.ContainsAny(text, "<>") && (!strings.HasPrefix(text, "<") || !strings.HasSuffix(text, ">")) {
+				t.Errorf("token %d: misaligned raw token %#q for %T", i, text, have)
+			}
+		}
+		lastEnd = end
+	}
+}
+
+// Ensure that directives (specifically !DOCTYPE) include the complete
+// text of any nested directives, noting that < and > do not change
+// nesting depth if they are in single or double quotes.
+
+var nestedDirectivesInput = `
+<!DOCTYPE [<!ENTITY rdf "http://www.w3.org/1999/02/22-rdf-syntax-ns#">]>
+<!DOCTYPE [<!ENTITY xlt ">">]>
+<!DOCTYPE [<!ENTITY xlt "<">]>
+<!DOCTYPE [<!ENTITY xlt '>'>]>
+<!DOCTYPE [<!ENTITY xlt '<'>]>
+<!DOCTYPE [<!ENTITY xlt '">'>]>
+<!DOCTYPE [<!ENTITY xlt "'<">]>
+`
+
+var nestedDirectivesTokens = []Token{
+	CharData("\n"),
+	Directive(`DOCTYPE [<!ENTITY rdf "http://www.w3.org/1999/02/22-rdf-syntax-ns#">]`),
+	CharData("\n"),
+	Directive(`DOCTYPE [<!ENTITY xlt ">">]`),
+	CharData("\n"),
+	Directive(`DOCTYPE [<!ENTITY xlt "<">]`),
+	CharData("\n"),
+	Directive(`DOCTYPE [<!ENTITY xlt '>'>]`),
+	CharData("\n"),
+	Directive(`DOCTYPE [<!ENTITY xlt '<'>]`),
+	CharData("\n"),
+	Directive(`DOCTYPE [<!ENTITY xlt '">'>]`),
+	CharData("\n"),
+	Directive(`DOCTYPE [<!ENTITY xlt "'<">]`),
+	CharData("\n"),
+}
+
+func TestNestedDirectives(t *testing.T) {
+	d := NewDecoder(strings.NewReader(nestedDirectivesInput))
+
+	for i, want := range nestedDirectivesTokens {
+		have, err := d.Token()
+		if err != nil {
+			t.Fatalf("token %d: unexpected error: %s", i, err)
+		}
+		if !reflect.DeepEqual(have, want) {
+			t.Errorf("token %d = %#v want %#v", i, have, want)
+		}
+	}
+}
+
+func TestToken(t *testing.T) {
+	d := NewDecoder(strings.NewReader(testInput))
+	d.Entity = testEntity
+
+	for i, want := range cookedTokens {
+		have, err := d.Token()
+		if err != nil {
+			t.Fatalf("token %d: unexpected error: %s", i, err)
+		}
+		if !reflect.DeepEqual(have, want) {
+			t.Errorf("token %d = %#v want %#v", i, have, want)
+		}
+	}
+}
+
+func TestSyntax(t *testing.T) {
+	for i := range xmlInput {
+		d := NewDecoder(strings.NewReader(xmlInput[i]))
+		var err error
+		for _, err = d.Token(); err == nil; _, err = d.Token() {
+		}
+		if _, ok := err.(*SyntaxError); !ok {
+			t.Fatalf(`xmlInput "%s": expected SyntaxError not received`, xmlInput[i])
+		}
+	}
+}
+
+type allScalars struct {
+	True1     bool
+	True2     bool
+	False1    bool
+	False2    bool
+	Int       int
+	Int8      int8
+	Int16     int16
+	Int32     int32
+	Int64     int64
+	Uint      int
+	Uint8     uint8
+	Uint16    uint16
+	Uint32    uint32
+	Uint64    uint64
+	Uintptr   uintptr
+	Float32   float32
+	Float64   float64
+	String    string
+	PtrString *string
+}
+
+var all = allScalars{
+	True1:     true,
+	True2:     true,
+	False1:    false,
+	False2:    false,
+	Int:       1,
+	Int8:      -2,
+	Int16:     3,
+	Int32:     -4,
+	Int64:     5,
+	Uint:      6,
+	Uint8:     7,
+	Uint16:    8,
+	Uint32:    9,
+	Uint64:    10,
+	Uintptr:   11,
+	Float32:   13.0,
+	Float64:   14.0,
+	String:    "15",
+	PtrString: &sixteen,
+}
+
+var sixteen = "16"
+
+const testScalarsInput = `<allscalars>
+	<True1>true</True1>
+	<True2>1</True2>
+	<False1>false</False1>
+	<False2>0</False2>
+	<Int>1</Int>
+	<Int8>-2</Int8>
+	<Int16>3</Int16>
+	<Int32>-4</Int32>
+	<Int64>5</Int64>
+	<Uint>6</Uint>
+	<Uint8>7</Uint8>
+	<Uint16>8</Uint16>
+	<Uint32>9</Uint32>
+	<Uint64>10</Uint64>
+	<Uintptr>11</Uintptr>
+	<Float>12.0</Float>
+	<Float32>13.0</Float32>
+	<Float64>14.0</Float64>
+	<String>15</String>
+	<PtrString>16</PtrString>
+</allscalars>`
+
+func TestAllScalars(t *testing.T) {
+	var a allScalars
+	err := Unmarshal([]byte(testScalarsInput), &a)
+
+	if err != nil {
+		t.Fatal(err)
+	}
+	if !reflect.DeepEqual(a, all) {
+		t.Errorf("have %+v want %+v", a, all)
+	}
+}
+
+type item struct {
+	Field_a string
+}
+
+func TestIssue569(t *testing.T) {
+	data := `<item><Field_a>abcd</Field_a></item>`
+	var i item
+	err := Unmarshal([]byte(data), &i)
+
+	if err != nil || i.Field_a != "abcd" {
+		t.Fatal("Expecting abcd")
+	}
+}
+
+func TestUnquotedAttrs(t *testing.T) {
+	data := "<tag attr=azAZ09:-_\t>"
+	d := NewDecoder(strings.NewReader(data))
+	d.Strict = false
+	token, err := d.Token()
+	if _, ok := err.(*SyntaxError); ok {
+		t.Errorf("Unexpected error: %v", err)
+	}
+	if token.(StartElement).Name.Local != "tag" {
+		t.Errorf("Unexpected tag name: %v", token.(StartElement).Name.Local)
+	}
+	attr := token.(StartElement).Attr[0]
+	if attr.Value != "azAZ09:-_" {
+		t.Errorf("Unexpected attribute value: %v", attr.Value)
+	}
+	if attr.Name.Local != "attr" {
+		t.Errorf("Unexpected attribute name: %v", attr.Name.Local)
+	}
+}
+
+func TestValuelessAttrs(t *testing.T) {
+	tests := [][3]string{
+		{"<p nowrap>", "p", "nowrap"},
+		{"<p nowrap >", "p", "nowrap"},
+		{"<input checked/>", "input", "checked"},
+		{"<input checked />", "input", "checked"},
+	}
+	for _, test := range tests {
+		d := NewDecoder(strings.NewReader(test[0]))
+		d.Strict = false
+		token, err := d.Token()
+		if _, ok := err.(*SyntaxError); ok {
+			t.Errorf("Unexpected error: %v", err)
+		}
+		if token.(StartElement).Name.Local != test[1] {
+			t.Errorf("Unexpected tag name: %v", token.(StartElement).Name.Local)
+		}
+		attr := token.(StartElement).Attr[0]
+		if attr.Value != test[2] {
+			t.Errorf("Unexpected attribute value: %v", attr.Value)
+		}
+		if attr.Name.Local != test[2] {
+			t.Errorf("Unexpected attribute name: %v", attr.Name.Local)
+		}
+	}
+}
+
+func TestCopyTokenCharData(t *testing.T) {
+	data := []byte("same data")
+	var tok1 Token = CharData(data)
+	tok2 := CopyToken(tok1)
+	if !reflect.DeepEqual(tok1, tok2) {
+		t.Error("CopyToken(CharData) != CharData")
+	}
+	data[1] = 'o'
+	if reflect.DeepEqual(tok1, tok2) {
+		t.Error("CopyToken(CharData) uses same buffer.")
+	}
+}
+
+func TestCopyTokenStartElement(t *testing.T) {
+	elt := StartElement{Name{"", "hello"}, []Attr{{Name{"", "lang"}, "en"}}}
+	var tok1 Token = elt
+	tok2 := CopyToken(tok1)
+	if tok1.(StartElement).Attr[0].Value != "en" {
+		t.Error("CopyToken overwrote Attr[0]")
+	}
+	if !reflect.DeepEqual(tok1, tok2) {
+		t.Error("CopyToken(StartElement) != StartElement")
+	}
+	tok1.(StartElement).Attr[0] = Attr{Name{"", "lang"}, "de"}
+	if reflect.DeepEqual(tok1, tok2) {
+		t.Error("CopyToken(CharData) uses same buffer.")
+	}
+}
+
+func TestSyntaxErrorLineNum(t *testing.T) {
+	testInput := "<P>Foo<P>\n\n<P>Bar</>\n"
+	d := NewDecoder(strings.NewReader(testInput))
+	var err error
+	for _, err = d.Token(); err == nil; _, err = d.Token() {
+	}
+	synerr, ok := err.(*SyntaxError)
+	if !ok {
+		t.Error("Expected SyntaxError.")
+	}
+	if synerr.Line != 3 {
+		t.Error("SyntaxError didn't have correct line number.")
+	}
+}
+
+func TestTrailingRawToken(t *testing.T) {
+	input := `<FOO></FOO>  `
+	d := NewDecoder(strings.NewReader(input))
+	var err error
+	for _, err = d.RawToken(); err == nil; _, err = d.RawToken() {
+	}
+	if err != io.EOF {
+		t.Fatalf("d.RawToken() = _, %v, want _, io.EOF", err)
+	}
+}
+
+func TestTrailingToken(t *testing.T) {
+	input := `<FOO></FOO>  `
+	d := NewDecoder(strings.NewReader(input))
+	var err error
+	for _, err = d.Token(); err == nil; _, err = d.Token() {
+	}
+	if err != io.EOF {
+		t.Fatalf("d.Token() = _, %v, want _, io.EOF", err)
+	}
+}
+
+func TestEntityInsideCDATA(t *testing.T) {
+	input := `<test><![CDATA[ &val=foo ]]></test>`
+	d := NewDecoder(strings.NewReader(input))
+	var err error
+	for _, err = d.Token(); err == nil; _, err = d.Token() {
+	}
+	if err != io.EOF {
+		t.Fatalf("d.Token() = _, %v, want _, io.EOF", err)
+	}
+}
+
+var characterTests = []struct {
+	in  string
+	err string
+}{
+	{"\x12<doc/>", "illegal character code U+0012"},
+	{"<?xml version=\"1.0\"?>\x0b<doc/>", "illegal character code U+000B"},
+	{"\xef\xbf\xbe<doc/>", "illegal character code U+FFFE"},
+	{"<?xml version=\"1.0\"?><doc>\r\n<hiya/>\x07<toots/></doc>", "illegal character code U+0007"},
+	{"<?xml version=\"1.0\"?><doc \x12='value'>what's up</doc>", "expected attribute name in element"},
+	{"<doc>&abc\x01;</doc>", "invalid character entity &abc (no semicolon)"},
+	{"<doc>&\x01;</doc>", "invalid character entity & (no semicolon)"},
+	{"<doc>&\xef\xbf\xbe;</doc>", "invalid character entity &\uFFFE;"},
+	{"<doc>&hello;</doc>", "invalid character entity &hello;"},
+}
+
+func TestDisallowedCharacters(t *testing.T) {
+
+	for i, tt := range characterTests {
+		d := NewDecoder(strings.NewReader(tt.in))
+		var err error
+
+		for err == nil {
+			_, err = d.Token()
+		}
+		synerr, ok := err.(*SyntaxError)
+		if !ok {
+			t.Fatalf("input %d d.Token() = _, %v, want _, *SyntaxError", i, err)
+		}
+		if synerr.Msg != tt.err {
+			t.Fatalf("input %d synerr.Msg wrong: want %q, got %q", i, tt.err, synerr.Msg)
+		}
+	}
+}
+
+type procInstEncodingTest struct {
+	expect, got string
+}
+
+var procInstTests = []struct {
+	input, expect string
+}{
+	{`version="1.0" encoding="utf-8"`, "utf-8"},
+	{`version="1.0" encoding='utf-8'`, "utf-8"},
+	{`version="1.0" encoding='utf-8' `, "utf-8"},
+	{`version="1.0" encoding=utf-8`, ""},
+	{`encoding="FOO" `, "FOO"},
+}
+
+func TestProcInstEncoding(t *testing.T) {
+	for _, test := range procInstTests {
+		got := procInstEncoding(test.input)
+		if got != test.expect {
+			t.Errorf("procInstEncoding(%q) = %q; want %q", test.input, got, test.expect)
+		}
+	}
+}
+
+// Ensure that directives with comments include the complete
+// text of any nested directives.
+
+var directivesWithCommentsInput = `
+<!DOCTYPE [<!-- a comment --><!ENTITY rdf "http://www.w3.org/1999/02/22-rdf-syntax-ns#">]>
+<!DOCTYPE [<!ENTITY go "Golang"><!-- a comment-->]>
+<!DOCTYPE <!-> <!> <!----> <!-->--> <!--->--> [<!ENTITY go "Golang"><!-- a comment-->]>
+`
+
+var directivesWithCommentsTokens = []Token{
+	CharData("\n"),
+	Directive(`DOCTYPE [<!ENTITY rdf "http://www.w3.org/1999/02/22-rdf-syntax-ns#">]`),
+	CharData("\n"),
+	Directive(`DOCTYPE [<!ENTITY go "Golang">]`),
+	CharData("\n"),
+	Directive(`DOCTYPE <!-> <!>    [<!ENTITY go "Golang">]`),
+	CharData("\n"),
+}
+
+func TestDirectivesWithComments(t *testing.T) {
+	d := NewDecoder(strings.NewReader(directivesWithCommentsInput))
+
+	for i, want := range directivesWithCommentsTokens {
+		have, err := d.Token()
+		if err != nil {
+			t.Fatalf("token %d: unexpected error: %s", i, err)
+		}
+		if !reflect.DeepEqual(have, want) {
+			t.Errorf("token %d = %#v want %#v", i, have, want)
+		}
+	}
+}
+
+// Writer whose Write method always returns an error.
+type errWriter struct{}
+
+func (errWriter) Write(p []byte) (n int, err error) { return 0, fmt.Errorf("unwritable") }
+
+func TestEscapeTextIOErrors(t *testing.T) {
+	expectErr := "unwritable"
+	err := EscapeText(errWriter{}, []byte{'A'})
+
+	if err == nil || err.Error() != expectErr {
+		t.Errorf("have %v, want %v", err, expectErr)
+	}
+}
+
+func TestEscapeTextInvalidChar(t *testing.T) {
+	input := []byte("A \x00 terminated string.")
+	expected := "A \uFFFD terminated string."
+
+	buff := new(bytes.Buffer)
+	if err := EscapeText(buff, input); err != nil {
+		t.Fatalf("have %v, want nil", err)
+	}
+	text := buff.String()
+
+	if text != expected {
+		t.Errorf("have %v, want %v", text, expected)
+	}
+}
+
+func TestIssue5880(t *testing.T) {
+	type T []byte
+	data, err := Marshal(T{192, 168, 0, 1})
+	if err != nil {
+		t.Errorf("Marshal error: %v", err)
+	}
+	if !utf8.Valid(data) {
+		t.Errorf("Marshal generated invalid UTF-8: %x", data)
+	}
+}
diff --git a/src/pkg/errors/errors.go b/src/errors/errors.go
similarity index 100%
rename from src/pkg/errors/errors.go
rename to src/errors/errors.go
diff --git a/src/pkg/errors/errors_test.go b/src/errors/errors_test.go
similarity index 100%
rename from src/pkg/errors/errors_test.go
rename to src/errors/errors_test.go
diff --git a/src/pkg/errors/example_test.go b/src/errors/example_test.go
similarity index 100%
rename from src/pkg/errors/example_test.go
rename to src/errors/example_test.go
diff --git a/src/pkg/expvar/expvar.go b/src/expvar/expvar.go
similarity index 100%
rename from src/pkg/expvar/expvar.go
rename to src/expvar/expvar.go
diff --git a/src/pkg/expvar/expvar_test.go b/src/expvar/expvar_test.go
similarity index 100%
rename from src/pkg/expvar/expvar_test.go
rename to src/expvar/expvar_test.go
diff --git a/src/pkg/flag/example_test.go b/src/flag/example_test.go
similarity index 100%
rename from src/pkg/flag/example_test.go
rename to src/flag/example_test.go
diff --git a/src/pkg/flag/export_test.go b/src/flag/export_test.go
similarity index 100%
rename from src/pkg/flag/export_test.go
rename to src/flag/export_test.go
diff --git a/src/flag/flag.go b/src/flag/flag.go
new file mode 100644
index 0000000..60aef5d
--- /dev/null
+++ b/src/flag/flag.go
@@ -0,0 +1,858 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+/*
+	Package flag implements command-line flag parsing.
+
+	Usage:
+
+	Define flags using flag.String(), Bool(), Int(), etc.
+
+	This declares an integer flag, -flagname, stored in the pointer ip, with type *int.
+		import "flag"
+		var ip = flag.Int("flagname", 1234, "help message for flagname")
+	If you like, you can bind the flag to a variable using the Var() functions.
+		var flagvar int
+		func init() {
+			flag.IntVar(&flagvar, "flagname", 1234, "help message for flagname")
+		}
+	Or you can create custom flags that satisfy the Value interface (with
+	pointer receivers) and couple them to flag parsing by
+		flag.Var(&flagVal, "name", "help message for flagname")
+	For such flags, the default value is just the initial value of the variable.
+
+	After all flags are defined, call
+		flag.Parse()
+	to parse the command line into the defined flags.
+
+	Flags may then be used directly. If you're using the flags themselves,
+	they are all pointers; if you bind to variables, they're values.
+		fmt.Println("ip has value ", *ip)
+		fmt.Println("flagvar has value ", flagvar)
+
+	After parsing, the arguments after the flag are available as the
+	slice flag.Args() or individually as flag.Arg(i).
+	The arguments are indexed from 0 through flag.NArg()-1.
+
+	Command line flag syntax:
+		-flag
+		-flag=x
+		-flag x  // non-boolean flags only
+	One or two minus signs may be used; they are equivalent.
+	The last form is not permitted for boolean flags because the
+	meaning of the command
+		cmd -x *
+	will change if there is a file called 0, false, etc.  You must
+	use the -flag=false form to turn off a boolean flag.
+
+	Flag parsing stops just before the first non-flag argument
+	("-" is a non-flag argument) or after the terminator "--".
+
+	Integer flags accept 1234, 0664, 0x1234 and may be negative.
+	Boolean flags may be:
+		1, 0, t, f, T, F, true, false, TRUE, FALSE, True, False
+	Duration flags accept any input valid for time.ParseDuration.
+
+	The default set of command-line flags is controlled by
+	top-level functions.  The FlagSet type allows one to define
+	independent sets of flags, such as to implement subcommands
+	in a command-line interface. The methods of FlagSet are
+	analogous to the top-level functions for the command-line
+	flag set.
+*/
+package flag
+
+import (
+	"errors"
+	"fmt"
+	"io"
+	"os"
+	"sort"
+	"strconv"
+	"time"
+)
+
+// ErrHelp is the error returned if the -help or -h flag is invoked
+// but no such flag is defined.
+var ErrHelp = errors.New("flag: help requested")
+
+// -- bool Value
+type boolValue bool
+
+func newBoolValue(val bool, p *bool) *boolValue {
+	*p = val
+	return (*boolValue)(p)
+}
+
+func (b *boolValue) Set(s string) error {
+	v, err := strconv.ParseBool(s)
+	*b = boolValue(v)
+	return err
+}
+
+func (b *boolValue) Get() interface{} { return bool(*b) }
+
+func (b *boolValue) String() string { return fmt.Sprintf("%v", *b) }
+
+func (b *boolValue) IsBoolFlag() bool { return true }
+
+// optional interface to indicate boolean flags that can be
+// supplied without "=value" text
+type boolFlag interface {
+	Value
+	IsBoolFlag() bool
+}
+
+// -- int Value
+type intValue int
+
+func newIntValue(val int, p *int) *intValue {
+	*p = val
+	return (*intValue)(p)
+}
+
+func (i *intValue) Set(s string) error {
+	v, err := strconv.ParseInt(s, 0, 64)
+	*i = intValue(v)
+	return err
+}
+
+func (i *intValue) Get() interface{} { return int(*i) }
+
+func (i *intValue) String() string { return fmt.Sprintf("%v", *i) }
+
+// -- int64 Value
+type int64Value int64
+
+func newInt64Value(val int64, p *int64) *int64Value {
+	*p = val
+	return (*int64Value)(p)
+}
+
+func (i *int64Value) Set(s string) error {
+	v, err := strconv.ParseInt(s, 0, 64)
+	*i = int64Value(v)
+	return err
+}
+
+func (i *int64Value) Get() interface{} { return int64(*i) }
+
+func (i *int64Value) String() string { return fmt.Sprintf("%v", *i) }
+
+// -- uint Value
+type uintValue uint
+
+func newUintValue(val uint, p *uint) *uintValue {
+	*p = val
+	return (*uintValue)(p)
+}
+
+func (i *uintValue) Set(s string) error {
+	v, err := strconv.ParseUint(s, 0, 64)
+	*i = uintValue(v)
+	return err
+}
+
+func (i *uintValue) Get() interface{} { return uint(*i) }
+
+func (i *uintValue) String() string { return fmt.Sprintf("%v", *i) }
+
+// -- uint64 Value
+type uint64Value uint64
+
+func newUint64Value(val uint64, p *uint64) *uint64Value {
+	*p = val
+	return (*uint64Value)(p)
+}
+
+func (i *uint64Value) Set(s string) error {
+	v, err := strconv.ParseUint(s, 0, 64)
+	*i = uint64Value(v)
+	return err
+}
+
+func (i *uint64Value) Get() interface{} { return uint64(*i) }
+
+func (i *uint64Value) String() string { return fmt.Sprintf("%v", *i) }
+
+// -- string Value
+type stringValue string
+
+func newStringValue(val string, p *string) *stringValue {
+	*p = val
+	return (*stringValue)(p)
+}
+
+func (s *stringValue) Set(val string) error {
+	*s = stringValue(val)
+	return nil
+}
+
+func (s *stringValue) Get() interface{} { return string(*s) }
+
+func (s *stringValue) String() string { return fmt.Sprintf("%s", *s) }
+
+// -- float64 Value
+type float64Value float64
+
+func newFloat64Value(val float64, p *float64) *float64Value {
+	*p = val
+	return (*float64Value)(p)
+}
+
+func (f *float64Value) Set(s string) error {
+	v, err := strconv.ParseFloat(s, 64)
+	*f = float64Value(v)
+	return err
+}
+
+func (f *float64Value) Get() interface{} { return float64(*f) }
+
+func (f *float64Value) String() string { return fmt.Sprintf("%v", *f) }
+
+// -- time.Duration Value
+type durationValue time.Duration
+
+func newDurationValue(val time.Duration, p *time.Duration) *durationValue {
+	*p = val
+	return (*durationValue)(p)
+}
+
+func (d *durationValue) Set(s string) error {
+	v, err := time.ParseDuration(s)
+	*d = durationValue(v)
+	return err
+}
+
+func (d *durationValue) Get() interface{} { return time.Duration(*d) }
+
+func (d *durationValue) String() string { return (*time.Duration)(d).String() }
+
+// Value is the interface to the dynamic value stored in a flag.
+// (The default value is represented as a string.)
+//
+// If a Value has an IsBoolFlag() bool method returning true,
+// the command-line parser makes -name equivalent to -name=true
+// rather than using the next command-line argument.
+type Value interface {
+	String() string
+	Set(string) error
+}
+
+// Getter is an interface that allows the contents of a Value to be retrieved.
+// It wraps the Value interface, rather than being part of it, because it
+// appeared after Go 1 and its compatibility rules. All Value types provided
+// by this package satisfy the Getter interface.
+type Getter interface {
+	Value
+	Get() interface{}
+}
+
+// ErrorHandling defines how to handle flag parsing errors.
+type ErrorHandling int
+
+const (
+	ContinueOnError ErrorHandling = iota
+	ExitOnError
+	PanicOnError
+)
+
+// A FlagSet represents a set of defined flags.  The zero value of a FlagSet
+// has no name and has ContinueOnError error handling.
+type FlagSet struct {
+	// Usage is the function called when an error occurs while parsing flags.
+	// The field is a function (not a method) that may be changed to point to
+	// a custom error handler.
+	Usage func()
+
+	name          string
+	parsed        bool
+	actual        map[string]*Flag
+	formal        map[string]*Flag
+	args          []string // arguments after flags
+	errorHandling ErrorHandling
+	output        io.Writer // nil means stderr; use out() accessor
+}
+
+// A Flag represents the state of a flag.
+type Flag struct {
+	Name     string // name as it appears on command line
+	Usage    string // help message
+	Value    Value  // value as set
+	DefValue string // default value (as text); for usage message
+}
+
+// sortFlags returns the flags as a slice in lexicographical sorted order.
+func sortFlags(flags map[string]*Flag) []*Flag {
+	list := make(sort.StringSlice, len(flags))
+	i := 0
+	for _, f := range flags {
+		list[i] = f.Name
+		i++
+	}
+	list.Sort()
+	result := make([]*Flag, len(list))
+	for i, name := range list {
+		result[i] = flags[name]
+	}
+	return result
+}
+
+func (f *FlagSet) out() io.Writer {
+	if f.output == nil {
+		return os.Stderr
+	}
+	return f.output
+}
+
+// SetOutput sets the destination for usage and error messages.
+// If output is nil, os.Stderr is used.
+func (f *FlagSet) SetOutput(output io.Writer) {
+	f.output = output
+}
+
+// VisitAll visits the flags in lexicographical order, calling fn for each.
+// It visits all flags, even those not set.
+func (f *FlagSet) VisitAll(fn func(*Flag)) {
+	for _, flag := range sortFlags(f.formal) {
+		fn(flag)
+	}
+}
+
+// VisitAll visits the command-line flags in lexicographical order, calling
+// fn for each.  It visits all flags, even those not set.
+func VisitAll(fn func(*Flag)) {
+	CommandLine.VisitAll(fn)
+}
+
+// Visit visits the flags in lexicographical order, calling fn for each.
+// It visits only those flags that have been set.
+func (f *FlagSet) Visit(fn func(*Flag)) {
+	for _, flag := range sortFlags(f.actual) {
+		fn(flag)
+	}
+}
+
+// Visit visits the command-line flags in lexicographical order, calling fn
+// for each.  It visits only those flags that have been set.
+func Visit(fn func(*Flag)) {
+	CommandLine.Visit(fn)
+}
+
+// Lookup returns the Flag structure of the named flag, returning nil if none exists.
+func (f *FlagSet) Lookup(name string) *Flag {
+	return f.formal[name]
+}
+
+// Lookup returns the Flag structure of the named command-line flag,
+// returning nil if none exists.
+func Lookup(name string) *Flag {
+	return CommandLine.formal[name]
+}
+
+// Set sets the value of the named flag.
+func (f *FlagSet) Set(name, value string) error {
+	flag, ok := f.formal[name]
+	if !ok {
+		return fmt.Errorf("no such flag -%v", name)
+	}
+	err := flag.Value.Set(value)
+	if err != nil {
+		return err
+	}
+	if f.actual == nil {
+		f.actual = make(map[string]*Flag)
+	}
+	f.actual[name] = flag
+	return nil
+}
+
+// Set sets the value of the named command-line flag.
+func Set(name, value string) error {
+	return CommandLine.Set(name, value)
+}
+
+// PrintDefaults prints, to standard error unless configured
+// otherwise, the default values of all defined flags in the set.
+func (f *FlagSet) PrintDefaults() {
+	f.VisitAll(func(flag *Flag) {
+		format := "  -%s=%s: %s\n"
+		if _, ok := flag.Value.(*stringValue); ok {
+			// put quotes on the value
+			format = "  -%s=%q: %s\n"
+		}
+		fmt.Fprintf(f.out(), format, flag.Name, flag.DefValue, flag.Usage)
+	})
+}
+
+// PrintDefaults prints to standard error the default values of all defined command-line flags.
+func PrintDefaults() {
+	CommandLine.PrintDefaults()
+}
+
+// defaultUsage is the default function to print a usage message.
+func defaultUsage(f *FlagSet) {
+	if f.name == "" {
+		fmt.Fprintf(f.out(), "Usage:\n")
+	} else {
+		fmt.Fprintf(f.out(), "Usage of %s:\n", f.name)
+	}
+	f.PrintDefaults()
+}
+
+// NOTE: Usage is not just defaultUsage(CommandLine)
+// because it serves (via godoc flag Usage) as the example
+// for how to write your own usage function.
+
+// Usage prints to standard error a usage message documenting all defined command-line flags.
+// It is called when an error occurs while parsing flags.
+// The function is a variable that may be changed to point to a custom function.
+var Usage = func() {
+	fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
+	PrintDefaults()
+}
+
+// NFlag returns the number of flags that have been set.
+func (f *FlagSet) NFlag() int { return len(f.actual) }
+
+// NFlag returns the number of command-line flags that have been set.
+func NFlag() int { return len(CommandLine.actual) }
+
+// Arg returns the i'th argument.  Arg(0) is the first remaining argument
+// after flags have been processed.
+func (f *FlagSet) Arg(i int) string {
+	if i < 0 || i >= len(f.args) {
+		return ""
+	}
+	return f.args[i]
+}
+
+// Arg returns the i'th command-line argument.  Arg(0) is the first remaining argument
+// after flags have been processed.
+func Arg(i int) string {
+	return CommandLine.Arg(i)
+}
+
+// NArg is the number of arguments remaining after flags have been processed.
+func (f *FlagSet) NArg() int { return len(f.args) }
+
+// NArg is the number of arguments remaining after flags have been processed.
+func NArg() int { return len(CommandLine.args) }
+
+// Args returns the non-flag arguments.
+func (f *FlagSet) Args() []string { return f.args }
+
+// Args returns the non-flag command-line arguments.
+func Args() []string { return CommandLine.args }
+
+// BoolVar defines a bool flag with specified name, default value, and usage string.
+// The argument p points to a bool variable in which to store the value of the flag.
+func (f *FlagSet) BoolVar(p *bool, name string, value bool, usage string) {
+	f.Var(newBoolValue(value, p), name, usage)
+}
+
+// BoolVar defines a bool flag with specified name, default value, and usage string.
+// The argument p points to a bool variable in which to store the value of the flag.
+func BoolVar(p *bool, name string, value bool, usage string) {
+	CommandLine.Var(newBoolValue(value, p), name, usage)
+}
+
+// Bool defines a bool flag with specified name, default value, and usage string.
+// The return value is the address of a bool variable that stores the value of the flag.
+func (f *FlagSet) Bool(name string, value bool, usage string) *bool {
+	p := new(bool)
+	f.BoolVar(p, name, value, usage)
+	return p
+}
+
+// Bool defines a bool flag with specified name, default value, and usage string.
+// The return value is the address of a bool variable that stores the value of the flag.
+func Bool(name string, value bool, usage string) *bool {
+	return CommandLine.Bool(name, value, usage)
+}
+
+// IntVar defines an int flag with specified name, default value, and usage string.
+// The argument p points to an int variable in which to store the value of the flag.
+func (f *FlagSet) IntVar(p *int, name string, value int, usage string) {
+	f.Var(newIntValue(value, p), name, usage)
+}
+
+// IntVar defines an int flag with specified name, default value, and usage string.
+// The argument p points to an int variable in which to store the value of the flag.
+func IntVar(p *int, name string, value int, usage string) {
+	CommandLine.Var(newIntValue(value, p), name, usage)
+}
+
+// Int defines an int flag with specified name, default value, and usage string.
+// The return value is the address of an int variable that stores the value of the flag.
+func (f *FlagSet) Int(name string, value int, usage string) *int {
+	p := new(int)
+	f.IntVar(p, name, value, usage)
+	return p
+}
+
+// Int defines an int flag with specified name, default value, and usage string.
+// The return value is the address of an int variable that stores the value of the flag.
+func Int(name string, value int, usage string) *int {
+	return CommandLine.Int(name, value, usage)
+}
+
+// Int64Var defines an int64 flag with specified name, default value, and usage string.
+// The argument p points to an int64 variable in which to store the value of the flag.
+func (f *FlagSet) Int64Var(p *int64, name string, value int64, usage string) {
+	f.Var(newInt64Value(value, p), name, usage)
+}
+
+// Int64Var defines an int64 flag with specified name, default value, and usage string.
+// The argument p points to an int64 variable in which to store the value of the flag.
+func Int64Var(p *int64, name string, value int64, usage string) {
+	CommandLine.Var(newInt64Value(value, p), name, usage)
+}
+
+// Int64 defines an int64 flag with specified name, default value, and usage string.
+// The return value is the address of an int64 variable that stores the value of the flag.
+func (f *FlagSet) Int64(name string, value int64, usage string) *int64 {
+	p := new(int64)
+	f.Int64Var(p, name, value, usage)
+	return p
+}
+
+// Int64 defines an int64 flag with specified name, default value, and usage string.
+// The return value is the address of an int64 variable that stores the value of the flag.
+func Int64(name string, value int64, usage string) *int64 {
+	return CommandLine.Int64(name, value, usage)
+}
+
+// UintVar defines a uint flag with specified name, default value, and usage string.
+// The argument p points to a uint variable in which to store the value of the flag.
+func (f *FlagSet) UintVar(p *uint, name string, value uint, usage string) {
+	f.Var(newUintValue(value, p), name, usage)
+}
+
+// UintVar defines a uint flag with specified name, default value, and usage string.
+// The argument p points to a uint  variable in which to store the value of the flag.
+func UintVar(p *uint, name string, value uint, usage string) {
+	CommandLine.Var(newUintValue(value, p), name, usage)
+}
+
+// Uint defines a uint flag with specified name, default value, and usage string.
+// The return value is the address of a uint  variable that stores the value of the flag.
+func (f *FlagSet) Uint(name string, value uint, usage string) *uint {
+	p := new(uint)
+	f.UintVar(p, name, value, usage)
+	return p
+}
+
+// Uint defines a uint flag with specified name, default value, and usage string.
+// The return value is the address of a uint  variable that stores the value of the flag.
+func Uint(name string, value uint, usage string) *uint {
+	return CommandLine.Uint(name, value, usage)
+}
+
+// Uint64Var defines a uint64 flag with specified name, default value, and usage string.
+// The argument p points to a uint64 variable in which to store the value of the flag.
+func (f *FlagSet) Uint64Var(p *uint64, name string, value uint64, usage string) {
+	f.Var(newUint64Value(value, p), name, usage)
+}
+
+// Uint64Var defines a uint64 flag with specified name, default value, and usage string.
+// The argument p points to a uint64 variable in which to store the value of the flag.
+func Uint64Var(p *uint64, name string, value uint64, usage string) {
+	CommandLine.Var(newUint64Value(value, p), name, usage)
+}
+
+// Uint64 defines a uint64 flag with specified name, default value, and usage string.
+// The return value is the address of a uint64 variable that stores the value of the flag.
+func (f *FlagSet) Uint64(name string, value uint64, usage string) *uint64 {
+	p := new(uint64)
+	f.Uint64Var(p, name, value, usage)
+	return p
+}
+
+// Uint64 defines a uint64 flag with specified name, default value, and usage string.
+// The return value is the address of a uint64 variable that stores the value of the flag.
+func Uint64(name string, value uint64, usage string) *uint64 {
+	return CommandLine.Uint64(name, value, usage)
+}
+
+// StringVar defines a string flag with specified name, default value, and usage string.
+// The argument p points to a string variable in which to store the value of the flag.
+func (f *FlagSet) StringVar(p *string, name string, value string, usage string) {
+	f.Var(newStringValue(value, p), name, usage)
+}
+
+// StringVar defines a string flag with specified name, default value, and usage string.
+// The argument p points to a string variable in which to store the value of the flag.
+func StringVar(p *string, name string, value string, usage string) {
+	CommandLine.Var(newStringValue(value, p), name, usage)
+}
+
+// String defines a string flag with specified name, default value, and usage string.
+// The return value is the address of a string variable that stores the value of the flag.
+func (f *FlagSet) String(name string, value string, usage string) *string {
+	p := new(string)
+	f.StringVar(p, name, value, usage)
+	return p
+}
+
+// String defines a string flag with specified name, default value, and usage string.
+// The return value is the address of a string variable that stores the value of the flag.
+func String(name string, value string, usage string) *string {
+	return CommandLine.String(name, value, usage)
+}
+
+// Float64Var defines a float64 flag with specified name, default value, and usage string.
+// The argument p points to a float64 variable in which to store the value of the flag.
+func (f *FlagSet) Float64Var(p *float64, name string, value float64, usage string) {
+	f.Var(newFloat64Value(value, p), name, usage)
+}
+
+// Float64Var defines a float64 flag with specified name, default value, and usage string.
+// The argument p points to a float64 variable in which to store the value of the flag.
+func Float64Var(p *float64, name string, value float64, usage string) {
+	CommandLine.Var(newFloat64Value(value, p), name, usage)
+}
+
+// Float64 defines a float64 flag with specified name, default value, and usage string.
+// The return value is the address of a float64 variable that stores the value of the flag.
+func (f *FlagSet) Float64(name string, value float64, usage string) *float64 {
+	p := new(float64)
+	f.Float64Var(p, name, value, usage)
+	return p
+}
+
+// Float64 defines a float64 flag with specified name, default value, and usage string.
+// The return value is the address of a float64 variable that stores the value of the flag.
+func Float64(name string, value float64, usage string) *float64 {
+	return CommandLine.Float64(name, value, usage)
+}
+
+// DurationVar defines a time.Duration flag with specified name, default value, and usage string.
+// The argument p points to a time.Duration variable in which to store the value of the flag.
+// The flag accepts a value acceptable to time.ParseDuration.
+func (f *FlagSet) DurationVar(p *time.Duration, name string, value time.Duration, usage string) {
+	f.Var(newDurationValue(value, p), name, usage)
+}
+
+// DurationVar defines a time.Duration flag with specified name, default value, and usage string.
+// The argument p points to a time.Duration variable in which to store the value of the flag.
+// The flag accepts a value acceptable to time.ParseDuration.
+func DurationVar(p *time.Duration, name string, value time.Duration, usage string) {
+	CommandLine.Var(newDurationValue(value, p), name, usage)
+}
+
+// Duration defines a time.Duration flag with specified name, default value, and usage string.
+// The return value is the address of a time.Duration variable that stores the value of the flag.
+// The flag accepts a value acceptable to time.ParseDuration.
+func (f *FlagSet) Duration(name string, value time.Duration, usage string) *time.Duration {
+	p := new(time.Duration)
+	f.DurationVar(p, name, value, usage)
+	return p
+}
+
+// Duration defines a time.Duration flag with specified name, default value, and usage string.
+// The return value is the address of a time.Duration variable that stores the value of the flag.
+// The flag accepts a value acceptable to time.ParseDuration.
+func Duration(name string, value time.Duration, usage string) *time.Duration {
+	return CommandLine.Duration(name, value, usage)
+}
+
+// Var defines a flag with the specified name and usage string. The type and
+// value of the flag are represented by the first argument, of type Value, which
+// typically holds a user-defined implementation of Value. For instance, the
+// caller could create a flag that turns a comma-separated string into a slice
+// of strings by giving the slice the methods of Value; in particular, Set would
+// decompose the comma-separated string into the slice.
+func (f *FlagSet) Var(value Value, name string, usage string) {
+	// Remember the default value as a string; it won't change.
+	flag := &Flag{name, usage, value, value.String()}
+	_, alreadythere := f.formal[name]
+	if alreadythere {
+		var msg string
+		if f.name == "" {
+			msg = fmt.Sprintf("flag redefined: %s", name)
+		} else {
+			msg = fmt.Sprintf("%s flag redefined: %s", f.name, name)
+		}
+		fmt.Fprintln(f.out(), msg)
+		panic(msg) // Happens only if flags are declared with identical names
+	}
+	if f.formal == nil {
+		f.formal = make(map[string]*Flag)
+	}
+	f.formal[name] = flag
+}
+
+// Var defines a flag with the specified name and usage string. The type and
+// value of the flag are represented by the first argument, of type Value, which
+// typically holds a user-defined implementation of Value. For instance, the
+// caller could create a flag that turns a comma-separated string into a slice
+// of strings by giving the slice the methods of Value; in particular, Set would
+// decompose the comma-separated string into the slice.
+func Var(value Value, name string, usage string) {
+	CommandLine.Var(value, name, usage)
+}
+
+// failf prints to standard error a formatted error and usage message and
+// returns the error.
+func (f *FlagSet) failf(format string, a ...interface{}) error {
+	err := fmt.Errorf(format, a...)
+	fmt.Fprintln(f.out(), err)
+	f.usage()
+	return err
+}
+
+// usage calls the Usage method for the flag set if one is specified,
+// or the appropriate default usage function otherwise.
+func (f *FlagSet) usage() {
+	if f.Usage == nil {
+		if f == CommandLine {
+			Usage()
+		} else {
+			defaultUsage(f)
+		}
+	} else {
+		f.Usage()
+	}
+}
+
+// parseOne parses one flag. It reports whether a flag was seen.
+func (f *FlagSet) parseOne() (bool, error) {
+	if len(f.args) == 0 {
+		return false, nil
+	}
+	s := f.args[0]
+	if len(s) == 0 || s[0] != '-' || len(s) == 1 {
+		return false, nil
+	}
+	num_minuses := 1
+	if s[1] == '-' {
+		num_minuses++
+		if len(s) == 2 { // "--" terminates the flags
+			f.args = f.args[1:]
+			return false, nil
+		}
+	}
+	name := s[num_minuses:]
+	if len(name) == 0 || name[0] == '-' || name[0] == '=' {
+		return false, f.failf("bad flag syntax: %s", s)
+	}
+
+	// it's a flag. does it have an argument?
+	f.args = f.args[1:]
+	has_value := false
+	value := ""
+	for i := 1; i < len(name); i++ { // equals cannot be first
+		if name[i] == '=' {
+			value = name[i+1:]
+			has_value = true
+			name = name[0:i]
+			break
+		}
+	}
+	m := f.formal
+	flag, alreadythere := m[name] // BUG
+	if !alreadythere {
+		if name == "help" || name == "h" { // special case for nice help message.
+			f.usage()
+			return false, ErrHelp
+		}
+		return false, f.failf("flag provided but not defined: -%s", name)
+	}
+
+	if fv, ok := flag.Value.(boolFlag); ok && fv.IsBoolFlag() { // special case: doesn't need an arg
+		if has_value {
+			if err := fv.Set(value); err != nil {
+				return false, f.failf("invalid boolean value %q for -%s: %v", value, name, err)
+			}
+		} else {
+			fv.Set("true")
+		}
+	} else {
+		// It must have a value, which might be the next argument.
+		if !has_value && len(f.args) > 0 {
+			// value is the next arg
+			has_value = true
+			value, f.args = f.args[0], f.args[1:]
+		}
+		if !has_value {
+			return false, f.failf("flag needs an argument: -%s", name)
+		}
+		if err := flag.Value.Set(value); err != nil {
+			return false, f.failf("invalid value %q for flag -%s: %v", value, name, err)
+		}
+	}
+	if f.actual == nil {
+		f.actual = make(map[string]*Flag)
+	}
+	f.actual[name] = flag
+	return true, nil
+}
+
+// Parse parses flag definitions from the argument list, which should not
+// include the command name.  Must be called after all flags in the FlagSet
+// are defined and before flags are accessed by the program.
+// The return value will be ErrHelp if -help or -h were set but not defined.
+func (f *FlagSet) Parse(arguments []string) error {
+	f.parsed = true
+	f.args = arguments
+	for {
+		seen, err := f.parseOne()
+		if seen {
+			continue
+		}
+		if err == nil {
+			break
+		}
+		switch f.errorHandling {
+		case ContinueOnError:
+			return err
+		case ExitOnError:
+			os.Exit(2)
+		case PanicOnError:
+			panic(err)
+		}
+	}
+	return nil
+}
+
+// Parsed reports whether f.Parse has been called.
+func (f *FlagSet) Parsed() bool {
+	return f.parsed
+}
+
+// Parse parses the command-line flags from os.Args[1:].  Must be called
+// after all flags are defined and before flags are accessed by the program.
+func Parse() {
+	// Ignore errors; CommandLine is set for ExitOnError.
+	CommandLine.Parse(os.Args[1:])
+}
+
+// Parsed returns true if the command-line flags have been parsed.
+func Parsed() bool {
+	return CommandLine.Parsed()
+}
+
+// CommandLine is the default set of command-line flags, parsed from os.Args.
+// The top-level functions such as BoolVar, Arg, and so on are wrappers for the
+// methods of CommandLine.
+var CommandLine = NewFlagSet(os.Args[0], ExitOnError)
+
+// NewFlagSet returns a new, empty flag set with the specified name and
+// error handling property.
+func NewFlagSet(name string, errorHandling ErrorHandling) *FlagSet {
+	f := &FlagSet{
+		name:          name,
+		errorHandling: errorHandling,
+	}
+	return f
+}
+
+// Init sets the name and error handling property for a flag set.
+// By default, the zero FlagSet uses an empty name and the
+// ContinueOnError error handling policy.
+func (f *FlagSet) Init(name string, errorHandling ErrorHandling) {
+	f.name = name
+	f.errorHandling = errorHandling
+}
diff --git a/src/flag/flag_test.go b/src/flag/flag_test.go
new file mode 100644
index 0000000..8c88c8c
--- /dev/null
+++ b/src/flag/flag_test.go
@@ -0,0 +1,379 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package flag_test
+
+import (
+	"bytes"
+	. "flag"
+	"fmt"
+	"os"
+	"sort"
+	"strings"
+	"testing"
+	"time"
+)
+
+func boolString(s string) string {
+	if s == "0" {
+		return "false"
+	}
+	return "true"
+}
+
+func TestEverything(t *testing.T) {
+	ResetForTesting(nil)
+	Bool("test_bool", false, "bool value")
+	Int("test_int", 0, "int value")
+	Int64("test_int64", 0, "int64 value")
+	Uint("test_uint", 0, "uint value")
+	Uint64("test_uint64", 0, "uint64 value")
+	String("test_string", "0", "string value")
+	Float64("test_float64", 0, "float64 value")
+	Duration("test_duration", 0, "time.Duration value")
+
+	m := make(map[string]*Flag)
+	desired := "0"
+	visitor := func(f *Flag) {
+		if len(f.Name) > 5 && f.Name[0:5] == "test_" {
+			m[f.Name] = f
+			ok := false
+			switch {
+			case f.Value.String() == desired:
+				ok = true
+			case f.Name == "test_bool" && f.Value.String() == boolString(desired):
+				ok = true
+			case f.Name == "test_duration" && f.Value.String() == desired+"s":
+				ok = true
+			}
+			if !ok {
+				t.Error("Visit: bad value", f.Value.String(), "for", f.Name)
+			}
+		}
+	}
+	VisitAll(visitor)
+	if len(m) != 8 {
+		t.Error("VisitAll misses some flags")
+		for k, v := range m {
+			t.Log(k, *v)
+		}
+	}
+	m = make(map[string]*Flag)
+	Visit(visitor)
+	if len(m) != 0 {
+		t.Errorf("Visit sees unset flags")
+		for k, v := range m {
+			t.Log(k, *v)
+		}
+	}
+	// Now set all flags
+	Set("test_bool", "true")
+	Set("test_int", "1")
+	Set("test_int64", "1")
+	Set("test_uint", "1")
+	Set("test_uint64", "1")
+	Set("test_string", "1")
+	Set("test_float64", "1")
+	Set("test_duration", "1s")
+	desired = "1"
+	Visit(visitor)
+	if len(m) != 8 {
+		t.Error("Visit fails after set")
+		for k, v := range m {
+			t.Log(k, *v)
+		}
+	}
+	// Now test they're visited in sort order.
+	var flagNames []string
+	Visit(func(f *Flag) { flagNames = append(flagNames, f.Name) })
+	if !sort.StringsAreSorted(flagNames) {
+		t.Errorf("flag names not sorted: %v", flagNames)
+	}
+}
+
+func TestGet(t *testing.T) {
+	ResetForTesting(nil)
+	Bool("test_bool", true, "bool value")
+	Int("test_int", 1, "int value")
+	Int64("test_int64", 2, "int64 value")
+	Uint("test_uint", 3, "uint value")
+	Uint64("test_uint64", 4, "uint64 value")
+	String("test_string", "5", "string value")
+	Float64("test_float64", 6, "float64 value")
+	Duration("test_duration", 7, "time.Duration value")
+
+	visitor := func(f *Flag) {
+		if len(f.Name) > 5 && f.Name[0:5] == "test_" {
+			g, ok := f.Value.(Getter)
+			if !ok {
+				t.Errorf("Visit: value does not satisfy Getter: %T", f.Value)
+				return
+			}
+			switch f.Name {
+			case "test_bool":
+				ok = g.Get() == true
+			case "test_int":
+				ok = g.Get() == int(1)
+			case "test_int64":
+				ok = g.Get() == int64(2)
+			case "test_uint":
+				ok = g.Get() == uint(3)
+			case "test_uint64":
+				ok = g.Get() == uint64(4)
+			case "test_string":
+				ok = g.Get() == "5"
+			case "test_float64":
+				ok = g.Get() == float64(6)
+			case "test_duration":
+				ok = g.Get() == time.Duration(7)
+			}
+			if !ok {
+				t.Errorf("Visit: bad value %T(%v) for %s", g.Get(), g.Get(), f.Name)
+			}
+		}
+	}
+	VisitAll(visitor)
+}
+
+func TestUsage(t *testing.T) {
+	called := false
+	ResetForTesting(func() { called = true })
+	if CommandLine.Parse([]string{"-x"}) == nil {
+		t.Error("parse did not fail for unknown flag")
+	}
+	if !called {
+		t.Error("did not call Usage for unknown flag")
+	}
+}
+
+func testParse(f *FlagSet, t *testing.T) {
+	if f.Parsed() {
+		t.Error("f.Parse() = true before Parse")
+	}
+	boolFlag := f.Bool("bool", false, "bool value")
+	bool2Flag := f.Bool("bool2", false, "bool2 value")
+	intFlag := f.Int("int", 0, "int value")
+	int64Flag := f.Int64("int64", 0, "int64 value")
+	uintFlag := f.Uint("uint", 0, "uint value")
+	uint64Flag := f.Uint64("uint64", 0, "uint64 value")
+	stringFlag := f.String("string", "0", "string value")
+	float64Flag := f.Float64("float64", 0, "float64 value")
+	durationFlag := f.Duration("duration", 5*time.Second, "time.Duration value")
+	extra := "one-extra-argument"
+	args := []string{
+		"-bool",
+		"-bool2=true",
+		"--int", "22",
+		"--int64", "0x23",
+		"-uint", "24",
+		"--uint64", "25",
+		"-string", "hello",
+		"-float64", "2718e28",
+		"-duration", "2m",
+		extra,
+	}
+	if err := f.Parse(args); err != nil {
+		t.Fatal(err)
+	}
+	if !f.Parsed() {
+		t.Error("f.Parse() = false after Parse")
+	}
+	if *boolFlag != true {
+		t.Error("bool flag should be true, is ", *boolFlag)
+	}
+	if *bool2Flag != true {
+		t.Error("bool2 flag should be true, is ", *bool2Flag)
+	}
+	if *intFlag != 22 {
+		t.Error("int flag should be 22, is ", *intFlag)
+	}
+	if *int64Flag != 0x23 {
+		t.Error("int64 flag should be 0x23, is ", *int64Flag)
+	}
+	if *uintFlag != 24 {
+		t.Error("uint flag should be 24, is ", *uintFlag)
+	}
+	if *uint64Flag != 25 {
+		t.Error("uint64 flag should be 25, is ", *uint64Flag)
+	}
+	if *stringFlag != "hello" {
+		t.Error("string flag should be `hello`, is ", *stringFlag)
+	}
+	if *float64Flag != 2718e28 {
+		t.Error("float64 flag should be 2718e28, is ", *float64Flag)
+	}
+	if *durationFlag != 2*time.Minute {
+		t.Error("duration flag should be 2m, is ", *durationFlag)
+	}
+	if len(f.Args()) != 1 {
+		t.Error("expected one argument, got", len(f.Args()))
+	} else if f.Args()[0] != extra {
+		t.Errorf("expected argument %q got %q", extra, f.Args()[0])
+	}
+}
+
+func TestParse(t *testing.T) {
+	ResetForTesting(func() { t.Error("bad parse") })
+	testParse(CommandLine, t)
+}
+
+func TestFlagSetParse(t *testing.T) {
+	testParse(NewFlagSet("test", ContinueOnError), t)
+}
+
+// Declare a user-defined flag type.
+type flagVar []string
+
+func (f *flagVar) String() string {
+	return fmt.Sprint([]string(*f))
+}
+
+func (f *flagVar) Set(value string) error {
+	*f = append(*f, value)
+	return nil
+}
+
+func TestUserDefined(t *testing.T) {
+	var flags FlagSet
+	flags.Init("test", ContinueOnError)
+	var v flagVar
+	flags.Var(&v, "v", "usage")
+	if err := flags.Parse([]string{"-v", "1", "-v", "2", "-v=3"}); err != nil {
+		t.Error(err)
+	}
+	if len(v) != 3 {
+		t.Fatal("expected 3 args; got ", len(v))
+	}
+	expect := "[1 2 3]"
+	if v.String() != expect {
+		t.Errorf("expected value %q got %q", expect, v.String())
+	}
+}
+
+func TestUserDefinedForCommandLine(t *testing.T) {
+	const help = "HELP"
+	var result string
+	ResetForTesting(func() { result = help })
+	Usage()
+	if result != help {
+		t.Fatalf("got %q; expected %q", result, help)
+	}
+}
+
+// Declare a user-defined boolean flag type.
+type boolFlagVar struct {
+	count int
+}
+
+func (b *boolFlagVar) String() string {
+	return fmt.Sprintf("%d", b.count)
+}
+
+func (b *boolFlagVar) Set(value string) error {
+	if value == "true" {
+		b.count++
+	}
+	return nil
+}
+
+func (b *boolFlagVar) IsBoolFlag() bool {
+	return b.count < 4
+}
+
+func TestUserDefinedBool(t *testing.T) {
+	var flags FlagSet
+	flags.Init("test", ContinueOnError)
+	var b boolFlagVar
+	var err error
+	flags.Var(&b, "b", "usage")
+	if err = flags.Parse([]string{"-b", "-b", "-b", "-b=true", "-b=false", "-b", "barg", "-b"}); err != nil {
+		if b.count < 4 {
+			t.Error(err)
+		}
+	}
+
+	if b.count != 4 {
+		t.Errorf("want: %d; got: %d", 4, b.count)
+	}
+
+	if err == nil {
+		t.Error("expected error; got none")
+	}
+}
+
+func TestSetOutput(t *testing.T) {
+	var flags FlagSet
+	var buf bytes.Buffer
+	flags.SetOutput(&buf)
+	flags.Init("test", ContinueOnError)
+	flags.Parse([]string{"-unknown"})
+	if out := buf.String(); !strings.Contains(out, "-unknown") {
+		t.Logf("expected output mentioning unknown; got %q", out)
+	}
+}
+
+// This tests that one can reset the flags. This still works but not well, and is
+// superseded by FlagSet.
+func TestChangingArgs(t *testing.T) {
+	ResetForTesting(func() { t.Fatal("bad parse") })
+	oldArgs := os.Args
+	defer func() { os.Args = oldArgs }()
+	os.Args = []string{"cmd", "-before", "subcmd", "-after", "args"}
+	before := Bool("before", false, "")
+	if err := CommandLine.Parse(os.Args[1:]); err != nil {
+		t.Fatal(err)
+	}
+	cmd := Arg(0)
+	os.Args = Args()
+	after := Bool("after", false, "")
+	Parse()
+	args := Args()
+
+	if !*before || cmd != "subcmd" || !*after || len(args) != 1 || args[0] != "args" {
+		t.Fatalf("expected true subcmd true [args] got %v %v %v %v", *before, cmd, *after, args)
+	}
+}
+
+// Test that -help invokes the usage message and returns ErrHelp.
+func TestHelp(t *testing.T) {
+	var helpCalled = false
+	fs := NewFlagSet("help test", ContinueOnError)
+	fs.Usage = func() { helpCalled = true }
+	var flag bool
+	fs.BoolVar(&flag, "flag", false, "regular flag")
+	// Regular flag invocation should work
+	err := fs.Parse([]string{"-flag=true"})
+	if err != nil {
+		t.Fatal("expected no error; got ", err)
+	}
+	if !flag {
+		t.Error("flag was not set by -flag")
+	}
+	if helpCalled {
+		t.Error("help called for regular flag")
+		helpCalled = false // reset for next test
+	}
+	// Help flag should work as expected.
+	err = fs.Parse([]string{"-help"})
+	if err == nil {
+		t.Fatal("error expected")
+	}
+	if err != ErrHelp {
+		t.Fatal("expected ErrHelp; got ", err)
+	}
+	if !helpCalled {
+		t.Fatal("help was not called")
+	}
+	// If we define a help flag, that should override.
+	var help bool
+	fs.BoolVar(&help, "help", false, "help flag")
+	helpCalled = false
+	err = fs.Parse([]string{"-help"})
+	if err != nil {
+		t.Fatal("expected no error for defined -help; got ", err)
+	}
+	if helpCalled {
+		t.Fatal("help was called; should not have been for defined help flag")
+	}
+}
diff --git a/src/fmt/doc.go b/src/fmt/doc.go
new file mode 100644
index 0000000..ee54463
--- /dev/null
+++ b/src/fmt/doc.go
@@ -0,0 +1,295 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+/*
+	Package fmt implements formatted I/O with functions analogous
+	to C's printf and scanf.  The format 'verbs' are derived from C's but
+	are simpler.
+
+
+	Printing
+
+	The verbs:
+
+	General:
+		%v	the value in a default format
+			when printing structs, the plus flag (%+v) adds field names
+		%#v	a Go-syntax representation of the value
+		%T	a Go-syntax representation of the type of the value
+		%%	a literal percent sign; consumes no value
+
+	Boolean:
+		%t	the word true or false
+	Integer:
+		%b	base 2
+		%c	the character represented by the corresponding Unicode code point
+		%d	base 10
+		%o	base 8
+		%q	a single-quoted character literal safely escaped with Go syntax.
+		%x	base 16, with lower-case letters for a-f
+		%X	base 16, with upper-case letters for A-F
+		%U	Unicode format: U+1234; same as "U+%04X"
+	Floating-point and complex constituents:
+		%b	decimalless scientific notation with exponent a power of two,
+			in the manner of strconv.FormatFloat with the 'b' format,
+			e.g. -123456p-78
+		%e	scientific notation, e.g. -1234.456e+78
+		%E	scientific notation, e.g. -1234.456E+78
+		%f	decimal point but no exponent, e.g. 123.456
+		%F	synonym for %f
+		%g	%e for large exponents, %f otherwise
+		%G	%E for large exponents, %F otherwise
+	String and slice of bytes:
+		%s	the uninterpreted bytes of the string or slice
+		%q	a double-quoted string safely escaped with Go syntax
+		%x	base 16, lower-case, two characters per byte
+		%X	base 16, upper-case, two characters per byte
+	Pointer:
+		%p	base 16 notation, with leading 0x
+
+	There is no 'u' flag.  Integers are printed unsigned if they have unsigned type.
+	Similarly, there is no need to specify the size of the operand (int8, int64).
+
+	The default format for %v is:
+		bool:                    %t
+		int, int8 etc.:          %d
+		uint, uint8 etc.:        %d, %x if printed with %#v
+		float32, complex64, etc: %g
+		string:                  %s
+		chan:                    %p
+		pointer:                 %p
+	For compound objects, the elements are printed using these rules, recursively,
+	laid out like this:
+		struct:             {field0 field1 ...}
+		array, slice:       [elem0  elem1 ...]
+		maps:               map[key1:value1 key2:value2]
+		pointer to above:   &{}, &[], &map[]
+
+	Width is specified by an optional decimal number immediately following the verb.
+	If absent, the width is whatever is necessary to represent the value.
+	Precision is specified after the (optional) width by a period followed by a
+	decimal number. If no period is present, a default precision is used.
+	A period with no following number specifies a precision of zero.
+	Examples:
+		%f:    default width, default precision
+		%9f    width 9, default precision
+		%.2f   default width, precision 2
+		%9.2f  width 9, precision 2
+		%9.f   width 9, precision 0
+
+	Width and precision are measured in units of Unicode code points,
+	that is, runes. (This differs from C's printf where the
+	units are always measured in bytes.) Either or both of the flags
+	may be replaced with the character '*', causing their values to be
+	obtained from the next operand, which must be of type int.
+
+	For most values, width is the minimum number of runes to output,
+	padding the formatted form with spaces if necessary.
+
+	For strings, byte slices and byte arrays, however, precision
+	limits the length of the input to be formatted (not the size of
+	the output), truncating if necessary. Normally it is measured in
+	runes, but for these types when formatted with the %x or %X format
+	it is measured in bytes.
+
+	For floating-point values, width sets the minimum width of the field and
+	precision sets the number of places after the decimal, if appropriate,
+	except that for %g/%G it sets the total number of digits. For example,
+	given 123.45 the format %6.2f prints 123.45 while %.4g prints 123.5.
+	The default precision for %e and %f is 6; for %g it is the smallest
+	number of digits necessary to identify the value uniquely.
+
+	For complex numbers, the width and precision apply to the two
+	components independently and the result is parenthesized, so %f applied
+	to 1.2+3.4i produces (1.200000+3.400000i).
+
+	Other flags:
+		+	always print a sign for numeric values;
+			guarantee ASCII-only output for %q (%+q)
+		-	pad with spaces on the right rather than the left (left-justify the field)
+		#	alternate format: add leading 0 for octal (%#o), 0x for hex (%#x);
+			0X for hex (%#X); suppress 0x for %p (%#p);
+			for %q, print a raw (backquoted) string if strconv.CanBackquote
+			returns true;
+			write e.g. U+0078 'x' if the character is printable for %U (%#U).
+		' '	(space) leave a space for elided sign in numbers (% d);
+			put spaces between bytes printing strings or slices in hex (% x, % X)
+		0	pad with leading zeros rather than spaces;
+			for numbers, this moves the padding after the sign
+
+	Flags are ignored by verbs that do not expect them.
+	For example there is no alternate decimal format, so %#d and %d
+	behave identically.
+
+	For each Printf-like function, there is also a Print function
+	that takes no format and is equivalent to saying %v for every
+	operand.  Another variant Println inserts blanks between
+	operands and appends a newline.
+
+	Regardless of the verb, if an operand is an interface value,
+	the internal concrete value is used, not the interface itself.
+	Thus:
+		var i interface{} = 23
+		fmt.Printf("%v\n", i)
+	will print 23.
+
+	Except when printed using the verbs %T and %p, special
+	formatting considerations apply for operands that implement
+	certain interfaces. In order of application:
+
+	1. If an operand implements the Formatter interface, it will
+	be invoked. Formatter provides fine control of formatting.
+
+	2. If the %v verb is used with the # flag (%#v) and the operand
+	implements the GoStringer interface, that will be invoked.
+
+	If the format (which is implicitly %v for Println etc.) is valid
+	for a string (%s %q %v %x %X), the following two rules apply:
+
+	3. If an operand implements the error interface, the Error method
+	will be invoked to convert the object to a string, which will then
+	be formatted as required by the verb (if any).
+
+	4. If an operand implements method String() string, that method
+	will be invoked to convert the object to a string, which will then
+	be formatted as required by the verb (if any).
+
+	For compound operands such as slices and structs, the format
+	applies to the elements of each operand, recursively, not to the
+	operand as a whole. Thus %q will quote each element of a slice
+	of strings, and %6.2f will control formatting for each element
+	of a floating-point array.
+
+	To avoid recursion in cases such as
+		type X string
+		func (x X) String() string { return Sprintf("<%s>", x) }
+	convert the value before recurring:
+		func (x X) String() string { return Sprintf("<%s>", string(x)) }
+	Infinite recursion can also be triggered by self-referential data
+	structures, such as a slice that contains itself as an element, if
+	that type has a String method. Such pathologies are rare, however,
+	and the package does not protect against them.
+
+	Explicit argument indexes:
+
+	In Printf, Sprintf, and Fprintf, the default behavior is for each
+	formatting verb to format successive arguments passed in the call.
+	However, the notation [n] immediately before the verb indicates that the
+	nth one-indexed argument is to be formatted instead. The same notation
+	before a '*' for a width or precision selects the argument index holding
+	the value. After processing a bracketed expression [n], arguments n+1,
+	n+2, etc. will be processed unless otherwise directed.
+
+	For example,
+		fmt.Sprintf("%[2]d %[1]d\n", 11, 22)
+	will yield "22 11", while
+		fmt.Sprintf("%[3]*.[2]*[1]f", 12.0, 2, 6),
+	equivalent to
+		fmt.Sprintf("%6.2f", 12.0),
+	will yield " 12.00". Because an explicit index affects subsequent verbs,
+	this notation can be used to print the same values multiple times
+	by resetting the index for the first argument to be repeated:
+		fmt.Sprintf("%d %d %#[1]x %#x", 16, 17)
+	will yield "16 17 0x10 0x11".
+
+	Format errors:
+
+	If an invalid argument is given for a verb, such as providing
+	a string to %d, the generated string will contain a
+	description of the problem, as in these examples:
+
+		Wrong type or unknown verb: %!verb(type=value)
+			Printf("%d", hi):          %!d(string=hi)
+		Too many arguments: %!(EXTRA type=value)
+			Printf("hi", "guys"):      hi%!(EXTRA string=guys)
+		Too few arguments: %!verb(MISSING)
+			Printf("hi%d"):            hi %!d(MISSING)
+		Non-int for width or precision: %!(BADWIDTH) or %!(BADPREC)
+			Printf("%*s", 4.5, "hi"):  %!(BADWIDTH)hi
+			Printf("%.*s", 4.5, "hi"): %!(BADPREC)hi
+		Invalid or invalid use of argument index: %!(BADINDEX)
+			Printf("%*[2]d", 7):       %!d(BADINDEX)
+			Printf("%.[2]d", 7):       %!d(BADINDEX)
+
+	All errors begin with the string "%!" followed sometimes
+	by a single character (the verb) and end with a parenthesized
+	description.
+
+	If an Error or String method triggers a panic when called by a
+	print routine, the fmt package reformats the error message
+	from the panic, decorating it with an indication that it came
+	through the fmt package.  For example, if a String method
+	calls panic("bad"), the resulting formatted message will look
+	like
+		%!s(PANIC=bad)
+
+	The %!s just shows the print verb in use when the failure
+	occurred.
+
+	Scanning
+
+	An analogous set of functions scans formatted text to yield
+	values.  Scan, Scanf and Scanln read from os.Stdin; Fscan,
+	Fscanf and Fscanln read from a specified io.Reader; Sscan,
+	Sscanf and Sscanln read from an argument string.  Scanln,
+	Fscanln and Sscanln stop scanning at a newline and require that
+	the items be followed by one; Scanf, Fscanf and Sscanf require
+	newlines in the input to match newlines in the format; the other
+	routines treat newlines as spaces.
+
+	Scanf, Fscanf, and Sscanf parse the arguments according to a
+	format string, analogous to that of Printf.  For example, %x
+	will scan an integer as a hexadecimal number, and %v will scan
+	the default representation format for the value.
+
+	The formats behave analogously to those of Printf with the
+	following exceptions:
+
+		%p is not implemented
+		%T is not implemented
+		%e %E %f %F %g %G are all equivalent and scan any floating point or complex value
+		%s and %v on strings scan a space-delimited token
+		Flags # and + are not implemented.
+
+	The familiar base-setting prefixes 0 (octal) and 0x
+	(hexadecimal) are accepted when scanning integers without a
+	format or with the %v verb.
+
+	Width is interpreted in the input text (%5s means at most
+	five runes of input will be read to scan a string) but there
+	is no syntax for scanning with a precision (no %5.2f, just
+	%5f).
+
+	When scanning with a format, all non-empty runs of space
+	characters (except newline) are equivalent to a single
+	space in both the format and the input.  With that proviso,
+	text in the format string must match the input text; scanning
+	stops if it does not, with the return value of the function
+	indicating the number of arguments scanned.
+
+	In all the scanning functions, a carriage return followed
+	immediately by a newline is treated as a plain newline
+	(\r\n means the same as \n).
+
+	In all the scanning functions, if an operand implements method
+	Scan (that is, it implements the Scanner interface) that
+	method will be used to scan the text for that operand.  Also,
+	if the number of arguments scanned is less than the number of
+	arguments provided, an error is returned.
+
+	All arguments to be scanned must be either pointers to basic
+	types or implementations of the Scanner interface.
+
+	Note: Fscan etc. can read one character (rune) past the input
+	they return, which means that a loop calling a scan routine
+	may skip some of the input.  This is usually a problem only
+	when there is no space between input values.  If the reader
+	provided to Fscan implements ReadRune, that method will be used
+	to read characters.  If the reader also implements UnreadRune,
+	that method will be used to save the character and successive
+	calls will not lose data.  To attach ReadRune and UnreadRune
+	methods to a reader without that capability, use
+	bufio.NewReader.
+*/
+package fmt
diff --git a/src/pkg/fmt/export_test.go b/src/fmt/export_test.go
similarity index 100%
rename from src/pkg/fmt/export_test.go
rename to src/fmt/export_test.go
diff --git a/src/fmt/fmt_test.go b/src/fmt/fmt_test.go
new file mode 100644
index 0000000..ff5fa79
--- /dev/null
+++ b/src/fmt/fmt_test.go
@@ -0,0 +1,1310 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package fmt_test
+
+import (
+	"bytes"
+	. "fmt"
+	"io"
+	"math"
+	"runtime"
+	"strings"
+	"testing"
+	"time"
+	"unicode"
+)
+
+type (
+	renamedBool       bool
+	renamedInt        int
+	renamedInt8       int8
+	renamedInt16      int16
+	renamedInt32      int32
+	renamedInt64      int64
+	renamedUint       uint
+	renamedUint8      uint8
+	renamedUint16     uint16
+	renamedUint32     uint32
+	renamedUint64     uint64
+	renamedUintptr    uintptr
+	renamedString     string
+	renamedBytes      []byte
+	renamedFloat32    float32
+	renamedFloat64    float64
+	renamedComplex64  complex64
+	renamedComplex128 complex128
+)
+
+func TestFmtInterface(t *testing.T) {
+	var i1 interface{}
+	i1 = "abc"
+	s := Sprintf("%s", i1)
+	if s != "abc" {
+		t.Errorf(`Sprintf("%%s", empty("abc")) = %q want %q`, s, "abc")
+	}
+}
+
+const b32 uint32 = 1<<32 - 1
+const b64 uint64 = 1<<64 - 1
+
+var array = [5]int{1, 2, 3, 4, 5}
+var iarray = [4]interface{}{1, "hello", 2.5, nil}
+var slice = array[:]
+var islice = iarray[:]
+
+type A struct {
+	i int
+	j uint
+	s string
+	x []int
+}
+
+type I int
+
+func (i I) String() string { return Sprintf("<%d>", int(i)) }
+
+type B struct {
+	I I
+	j int
+}
+
+type C struct {
+	i int
+	B
+}
+
+type F int
+
+func (f F) Format(s State, c rune) {
+	Fprintf(s, "<%c=F(%d)>", c, int(f))
+}
+
+type G int
+
+func (g G) GoString() string {
+	return Sprintf("GoString(%d)", int(g))
+}
+
+type S struct {
+	F F // a struct field that Formats
+	G G // a struct field that GoStrings
+}
+
+type SI struct {
+	I interface{}
+}
+
+// P is a type with a String method with pointer receiver for testing %p.
+type P int
+
+var pValue P
+
+func (p *P) String() string {
+	return "String(p)"
+}
+
+var barray = [5]renamedUint8{1, 2, 3, 4, 5}
+var bslice = barray[:]
+
+type byteStringer byte
+
+func (byteStringer) String() string { return "X" }
+
+var byteStringerSlice = []byteStringer{97, 98, 99, 100}
+
+type byteFormatter byte
+
+func (byteFormatter) Format(f State, _ rune) {
+	Fprint(f, "X")
+}
+
+var byteFormatterSlice = []byteFormatter{97, 98, 99, 100}
+
+var b byte
+
+var fmtTests = []struct {
+	fmt string
+	val interface{}
+	out string
+}{
+	{"%d", 12345, "12345"},
+	{"%v", 12345, "12345"},
+	{"%t", true, "true"},
+
+	// basic string
+	{"%s", "abc", "abc"},
+	{"%x", "abc", "616263"},
+	{"%x", "xyz", "78797a"},
+	{"%X", "xyz", "78797A"},
+	{"%q", "abc", `"abc"`},
+	{"%#x", []byte("abc\xff"), "0x616263ff"},
+	{"%#X", []byte("abc\xff"), "0X616263FF"},
+	{"%# x", []byte("abc\xff"), "0x61 0x62 0x63 0xff"},
+	{"%# X", []byte("abc\xff"), "0X61 0X62 0X63 0XFF"},
+
+	// basic bytes
+	{"%s", []byte("abc"), "abc"},
+	{"%x", []byte("abc"), "616263"},
+	{"% x", []byte("abc\xff"), "61 62 63 ff"},
+	{"%#x", []byte("abc\xff"), "0x616263ff"},
+	{"%#X", []byte("abc\xff"), "0X616263FF"},
+	{"%# x", []byte("abc\xff"), "0x61 0x62 0x63 0xff"},
+	{"%# X", []byte("abc\xff"), "0X61 0X62 0X63 0XFF"},
+	{"% X", []byte("abc\xff"), "61 62 63 FF"},
+	{"%x", []byte("xyz"), "78797a"},
+	{"%X", []byte("xyz"), "78797A"},
+	{"%q", []byte("abc"), `"abc"`},
+
+	// escaped strings
+	{"%#q", `abc`, "`abc`"},
+	{"%#q", `"`, "`\"`"},
+	{"1 %#q", `\n`, "1 `\\n`"},
+	{"2 %#q", "\n", `2 "\n"`},
+	{"%q", `"`, `"\""`},
+	{"%q", "\a\b\f\r\n\t\v", `"\a\b\f\r\n\t\v"`},
+	{"%q", "abc\xffdef", `"abc\xffdef"`},
+	{"%q", "\u263a", `"☺"`},
+	{"%+q", "\u263a", `"\u263a"`},
+	{"%q", "\U0010ffff", `"\U0010ffff"`},
+
+	// escaped characters
+	{"%q", 'x', `'x'`},
+	{"%q", 0, `'\x00'`},
+	{"%q", '\n', `'\n'`},
+	{"%q", '\u0e00', `'\u0e00'`},         // not a printable rune.
+	{"%q", '\U000c2345', `'\U000c2345'`}, // not a printable rune.
+	{"%q", int64(0x7FFFFFFF), `%!q(int64=2147483647)`},
+	{"%q", uint64(0xFFFFFFFF), `%!q(uint64=4294967295)`},
+	{"%q", '"', `'"'`},
+	{"%q", '\'', `'\''`},
+	{"%q", "\u263a", `"☺"`},
+	{"%+q", "\u263a", `"\u263a"`},
+
+	// width
+	{"%5s", "abc", "  abc"},
+	{"%2s", "\u263a", " ☺"},
+	{"%-5s", "abc", "abc  "},
+	{"%-8q", "abc", `"abc"   `},
+	{"%05s", "abc", "00abc"},
+	{"%08q", "abc", `000"abc"`},
+	{"%5s", "abcdefghijklmnopqrstuvwxyz", "abcdefghijklmnopqrstuvwxyz"},
+	{"%.5s", "abcdefghijklmnopqrstuvwxyz", "abcde"},
+	{"%.5s", "日本語日本語", "日本語日本"},
+	{"%.5s", []byte("日本語日本語"), "日本語日本"},
+	{"%.5q", "abcdefghijklmnopqrstuvwxyz", `"abcde"`},
+	{"%.5x", "abcdefghijklmnopqrstuvwxyz", `6162636465`},
+	{"%.5q", []byte("abcdefghijklmnopqrstuvwxyz"), `"abcde"`},
+	{"%.5x", []byte("abcdefghijklmnopqrstuvwxyz"), `6162636465`},
+	{"%.3q", "日本語日本語", `"日本語"`},
+	{"%.3q", []byte("日本語日本語"), `"日本語"`},
+	{"%.1q", "日本語", `"日"`},
+	{"%.1q", []byte("日本語"), `"日"`},
+	{"%.1x", "日本語", `e6`},
+	{"%.1X", []byte("日本語"), `E6`},
+	{"%10.1q", "日本語日本語", `       "日"`},
+	{"%3c", '⌘', "  ⌘"},
+	{"%5q", '\u2026', `  '…'`},
+	{"%10v", nil, "     <nil>"},
+	{"%-10v", nil, "<nil>     "},
+
+	// integers
+	{"%d", 12345, "12345"},
+	{"%d", -12345, "-12345"},
+	{"%10d", 12345, "     12345"},
+	{"%10d", -12345, "    -12345"},
+	{"%+10d", 12345, "    +12345"},
+	{"%010d", 12345, "0000012345"},
+	{"%010d", -12345, "-000012345"},
+	{"%-10d", 12345, "12345     "},
+	{"%010.3d", 1, "       001"},
+	{"%010.3d", -1, "      -001"},
+	{"%+d", 12345, "+12345"},
+	{"%+d", -12345, "-12345"},
+	{"%+d", 0, "+0"},
+	{"% d", 0, " 0"},
+	{"% d", 12345, " 12345"},
+	{"%.0d", 0, ""},
+	{"%.d", 0, ""},
+
+	// unicode format
+	{"%U", 0x1, "U+0001"},
+	{"%U", uint(0x1), "U+0001"},
+	{"%.8U", 0x2, "U+00000002"},
+	{"%U", 0x1234, "U+1234"},
+	{"%U", 0x12345, "U+12345"},
+	{"%10.6U", 0xABC, "  U+000ABC"},
+	{"%-10.6U", 0xABC, "U+000ABC  "},
+	{"%U", '\n', `U+000A`},
+	{"%#U", '\n', `U+000A`},
+	{"%U", 'x', `U+0078`},
+	{"%#U", 'x', `U+0078 'x'`},
+	{"%U", '\u263a', `U+263A`},
+	{"%#U", '\u263a', `U+263A '☺'`},
+
+	// floats
+	{"%+.3e", 0.0, "+0.000e+00"},
+	{"%+.3e", 1.0, "+1.000e+00"},
+	{"%+.3f", -1.0, "-1.000"},
+	{"%+.3F", -1.0, "-1.000"},
+	{"%+.3F", float32(-1.0), "-1.000"},
+	{"%+07.2f", 1.0, "+001.00"},
+	{"%+07.2f", -1.0, "-001.00"},
+	{"%+10.2f", +1.0, "     +1.00"},
+	{"%+10.2f", -1.0, "     -1.00"},
+	{"% .3E", -1.0, "-1.000E+00"},
+	{"% .3e", 1.0, " 1.000e+00"},
+	{"%+.3g", 0.0, "+0"},
+	{"%+.3g", 1.0, "+1"},
+	{"%+.3g", -1.0, "-1"},
+	{"% .3g", -1.0, "-1"},
+	{"% .3g", 1.0, " 1"},
+	{"%b", float32(1.0), "8388608p-23"},
+	{"%b", 1.0, "4503599627370496p-52"},
+
+	// complex values
+	{"%+.3e", 0i, "(+0.000e+00+0.000e+00i)"},
+	{"%+.3f", 0i, "(+0.000+0.000i)"},
+	{"%+.3g", 0i, "(+0+0i)"},
+	{"%+.3e", 1 + 2i, "(+1.000e+00+2.000e+00i)"},
+	{"%+.3f", 1 + 2i, "(+1.000+2.000i)"},
+	{"%+.3g", 1 + 2i, "(+1+2i)"},
+	{"%.3e", 0i, "(0.000e+00+0.000e+00i)"},
+	{"%.3f", 0i, "(0.000+0.000i)"},
+	{"%.3F", 0i, "(0.000+0.000i)"},
+	{"%.3F", complex64(0i), "(0.000+0.000i)"},
+	{"%.3g", 0i, "(0+0i)"},
+	{"%.3e", 1 + 2i, "(1.000e+00+2.000e+00i)"},
+	{"%.3f", 1 + 2i, "(1.000+2.000i)"},
+	{"%.3g", 1 + 2i, "(1+2i)"},
+	{"%.3e", -1 - 2i, "(-1.000e+00-2.000e+00i)"},
+	{"%.3f", -1 - 2i, "(-1.000-2.000i)"},
+	{"%.3g", -1 - 2i, "(-1-2i)"},
+	{"% .3E", -1 - 2i, "(-1.000E+00-2.000E+00i)"},
+	{"%+.3g", complex64(1 + 2i), "(+1+2i)"},
+	{"%+.3g", complex128(1 + 2i), "(+1+2i)"},
+	{"%b", complex64(1 + 2i), "(8388608p-23+8388608p-22i)"},
+	{"%b", 1 + 2i, "(4503599627370496p-52+4503599627370496p-51i)"},
+
+	// erroneous formats
+	{"", 2, "%!(EXTRA int=2)"},
+	{"%d", "hello", "%!d(string=hello)"},
+
+	// old test/fmt_test.go
+	{"%d", 1234, "1234"},
+	{"%d", -1234, "-1234"},
+	{"%d", uint(1234), "1234"},
+	{"%d", uint32(b32), "4294967295"},
+	{"%d", uint64(b64), "18446744073709551615"},
+	{"%o", 01234, "1234"},
+	{"%#o", 01234, "01234"},
+	{"%o", uint32(b32), "37777777777"},
+	{"%o", uint64(b64), "1777777777777777777777"},
+	{"%x", 0x1234abcd, "1234abcd"},
+	{"%#x", 0x1234abcd, "0x1234abcd"},
+	{"%x", b32 - 0x1234567, "fedcba98"},
+	{"%X", 0x1234abcd, "1234ABCD"},
+	{"%X", b32 - 0x1234567, "FEDCBA98"},
+	{"%#X", 0, "0X0"},
+	{"%x", b64, "ffffffffffffffff"},
+	{"%b", 7, "111"},
+	{"%b", b64, "1111111111111111111111111111111111111111111111111111111111111111"},
+	{"%b", -6, "-110"},
+	{"%e", 1.0, "1.000000e+00"},
+	{"%e", 1234.5678e3, "1.234568e+06"},
+	{"%e", 1234.5678e-8, "1.234568e-05"},
+	{"%e", -7.0, "-7.000000e+00"},
+	{"%e", -1e-9, "-1.000000e-09"},
+	{"%f", 1234.5678e3, "1234567.800000"},
+	{"%f", 1234.5678e-8, "0.000012"},
+	{"%f", -7.0, "-7.000000"},
+	{"%f", -1e-9, "-0.000000"},
+	{"%g", 1234.5678e3, "1.2345678e+06"},
+	{"%g", float32(1234.5678e3), "1.2345678e+06"},
+	{"%g", 1234.5678e-8, "1.2345678e-05"},
+	{"%g", -7.0, "-7"},
+	{"%g", -1e-9, "-1e-09"},
+	{"%g", float32(-1e-9), "-1e-09"},
+	{"%E", 1.0, "1.000000E+00"},
+	{"%E", 1234.5678e3, "1.234568E+06"},
+	{"%E", 1234.5678e-8, "1.234568E-05"},
+	{"%E", -7.0, "-7.000000E+00"},
+	{"%E", -1e-9, "-1.000000E-09"},
+	{"%G", 1234.5678e3, "1.2345678E+06"},
+	{"%G", float32(1234.5678e3), "1.2345678E+06"},
+	{"%G", 1234.5678e-8, "1.2345678E-05"},
+	{"%G", -7.0, "-7"},
+	{"%G", -1e-9, "-1E-09"},
+	{"%G", float32(-1e-9), "-1E-09"},
+	{"%c", 'x', "x"},
+	{"%c", 0xe4, "ä"},
+	{"%c", 0x672c, "本"},
+	{"%c", '日', "日"},
+	{"%20.8d", 1234, "            00001234"},
+	{"%20.8d", -1234, "           -00001234"},
+	{"%20d", 1234, "                1234"},
+	{"%-20.8d", 1234, "00001234            "},
+	{"%-20.8d", -1234, "-00001234           "},
+	{"%-#20.8x", 0x1234abc, "0x01234abc          "},
+	{"%-#20.8X", 0x1234abc, "0X01234ABC          "},
+	{"%-#20.8o", 01234, "00001234            "},
+	{"%.20b", 7, "00000000000000000111"},
+	{"%20.5s", "qwertyuiop", "               qwert"},
+	{"%.5s", "qwertyuiop", "qwert"},
+	{"%-20.5s", "qwertyuiop", "qwert               "},
+	{"%20c", 'x', "                   x"},
+	{"%-20c", 'x', "x                   "},
+	{"%20.6e", 1.2345e3, "        1.234500e+03"},
+	{"%20.6e", 1.2345e-3, "        1.234500e-03"},
+	{"%20e", 1.2345e3, "        1.234500e+03"},
+	{"%20e", 1.2345e-3, "        1.234500e-03"},
+	{"%20.8e", 1.2345e3, "      1.23450000e+03"},
+	{"%20f", 1.23456789e3, "         1234.567890"},
+	{"%20f", 1.23456789e-3, "            0.001235"},
+	{"%20f", 12345678901.23456789, "  12345678901.234568"},
+	{"%-20f", 1.23456789e3, "1234.567890         "},
+	{"%20.8f", 1.23456789e3, "       1234.56789000"},
+	{"%20.8f", 1.23456789e-3, "          0.00123457"},
+	{"%g", 1.23456789e3, "1234.56789"},
+	{"%g", 1.23456789e-3, "0.00123456789"},
+	{"%g", 1.23456789e20, "1.23456789e+20"},
+	{"%20e", math.Inf(1), "                +Inf"},
+	{"%-20f", math.Inf(-1), "-Inf                "},
+	{"%20g", math.NaN(), "                 NaN"},
+
+	// arrays
+	{"%v", array, "[1 2 3 4 5]"},
+	{"%v", iarray, "[1 hello 2.5 <nil>]"},
+	{"%v", barray, "[1 2 3 4 5]"},
+	{"%v", &array, "&[1 2 3 4 5]"},
+	{"%v", &iarray, "&[1 hello 2.5 <nil>]"},
+	{"%v", &barray, "&[1 2 3 4 5]"},
+
+	// slices
+	{"%v", slice, "[1 2 3 4 5]"},
+	{"%v", islice, "[1 hello 2.5 <nil>]"},
+	{"%v", bslice, "[1 2 3 4 5]"},
+	{"%v", &slice, "&[1 2 3 4 5]"},
+	{"%v", &islice, "&[1 hello 2.5 <nil>]"},
+	{"%v", &bslice, "&[1 2 3 4 5]"},
+
+	// complexes with %v
+	{"%v", 1 + 2i, "(1+2i)"},
+	{"%v", complex64(1 + 2i), "(1+2i)"},
+	{"%v", complex128(1 + 2i), "(1+2i)"},
+
+	// structs
+	{"%v", A{1, 2, "a", []int{1, 2}}, `{1 2 a [1 2]}`},
+	{"%+v", A{1, 2, "a", []int{1, 2}}, `{i:1 j:2 s:a x:[1 2]}`},
+
+	// +v on structs with Stringable items
+	{"%+v", B{1, 2}, `{I:<1> j:2}`},
+	{"%+v", C{1, B{2, 3}}, `{i:1 B:{I:<2> j:3}}`},
+
+	// other formats on Stringable items
+	{"%s", I(23), `<23>`},
+	{"%q", I(23), `"<23>"`},
+	{"%x", I(23), `3c32333e`},
+	{"%#x", I(23), `0x3c32333e`},
+	{"%# x", I(23), `0x3c 0x32 0x33 0x3e`},
+	{"%d", I(23), `23`}, // Stringer applies only to string formats.
+
+	// go syntax
+	{"%#v", A{1, 2, "a", []int{1, 2}}, `fmt_test.A{i:1, j:0x2, s:"a", x:[]int{1, 2}}`},
+	{"%#v", &b, "(*uint8)(0xPTR)"},
+	{"%#v", TestFmtInterface, "(func(*testing.T))(0xPTR)"},
+	{"%#v", make(chan int), "(chan int)(0xPTR)"},
+	{"%#v", uint64(1<<64 - 1), "0xffffffffffffffff"},
+	{"%#v", 1000000000, "1000000000"},
+	{"%#v", map[string]int{"a": 1}, `map[string]int{"a":1}`},
+	{"%#v", map[string]B{"a": {1, 2}}, `map[string]fmt_test.B{"a":fmt_test.B{I:1, j:2}}`},
+	{"%#v", []string{"a", "b"}, `[]string{"a", "b"}`},
+	{"%#v", SI{}, `fmt_test.SI{I:interface {}(nil)}`},
+	{"%#v", []int(nil), `[]int(nil)`},
+	{"%#v", []int{}, `[]int{}`},
+	{"%#v", array, `[5]int{1, 2, 3, 4, 5}`},
+	{"%#v", &array, `&[5]int{1, 2, 3, 4, 5}`},
+	{"%#v", iarray, `[4]interface {}{1, "hello", 2.5, interface {}(nil)}`},
+	{"%#v", &iarray, `&[4]interface {}{1, "hello", 2.5, interface {}(nil)}`},
+	{"%#v", map[int]byte(nil), `map[int]uint8(nil)`},
+	{"%#v", map[int]byte{}, `map[int]uint8{}`},
+	{"%#v", "foo", `"foo"`},
+	{"%#v", barray, `[5]fmt_test.renamedUint8{0x1, 0x2, 0x3, 0x4, 0x5}`},
+	{"%#v", bslice, `[]fmt_test.renamedUint8{0x1, 0x2, 0x3, 0x4, 0x5}`},
+	{"%#v", []byte(nil), "[]byte(nil)"},
+	{"%#v", []int32(nil), "[]int32(nil)"},
+
+	// slices with other formats
+	{"%#x", []int{1, 2, 15}, `[0x1 0x2 0xf]`},
+	{"%x", []int{1, 2, 15}, `[1 2 f]`},
+	{"%d", []int{1, 2, 15}, `[1 2 15]`},
+	{"%d", []byte{1, 2, 15}, `[1 2 15]`},
+	{"%q", []string{"a", "b"}, `["a" "b"]`},
+
+	// renamings
+	{"%v", renamedBool(true), "true"},
+	{"%d", renamedBool(true), "%!d(fmt_test.renamedBool=true)"},
+	{"%o", renamedInt(8), "10"},
+	{"%d", renamedInt8(-9), "-9"},
+	{"%v", renamedInt16(10), "10"},
+	{"%v", renamedInt32(-11), "-11"},
+	{"%X", renamedInt64(255), "FF"},
+	{"%v", renamedUint(13), "13"},
+	{"%o", renamedUint8(14), "16"},
+	{"%X", renamedUint16(15), "F"},
+	{"%d", renamedUint32(16), "16"},
+	{"%X", renamedUint64(17), "11"},
+	{"%o", renamedUintptr(18), "22"},
+	{"%x", renamedString("thing"), "7468696e67"},
+	{"%d", renamedBytes([]byte{1, 2, 15}), `[1 2 15]`},
+	{"%q", renamedBytes([]byte("hello")), `"hello"`},
+	{"%x", []renamedUint8{'a', 'b', 'c'}, "616263"},
+	{"%s", []renamedUint8{'h', 'e', 'l', 'l', 'o'}, "hello"},
+	{"%q", []renamedUint8{'h', 'e', 'l', 'l', 'o'}, `"hello"`},
+	{"%v", renamedFloat32(22), "22"},
+	{"%v", renamedFloat64(33), "33"},
+	{"%v", renamedComplex64(3 + 4i), "(3+4i)"},
+	{"%v", renamedComplex128(4 - 3i), "(4-3i)"},
+
+	// Formatter
+	{"%x", F(1), "<x=F(1)>"},
+	{"%x", G(2), "2"},
+	{"%+v", S{F(4), G(5)}, "{F:<v=F(4)> G:5}"},
+
+	// GoStringer
+	{"%#v", G(6), "GoString(6)"},
+	{"%#v", S{F(7), G(8)}, "fmt_test.S{F:<v=F(7)>, G:GoString(8)}"},
+
+	// %T
+	{"%T", (4 - 3i), "complex128"},
+	{"%T", renamedComplex128(4 - 3i), "fmt_test.renamedComplex128"},
+	{"%T", intVal, "int"},
+	{"%6T", &intVal, "  *int"},
+	{"%10T", nil, "     <nil>"},
+	{"%-10T", nil, "<nil>     "},
+
+	// %p
+	{"p0=%p", new(int), "p0=0xPTR"},
+	{"p1=%s", &pValue, "p1=String(p)"}, // String method...
+	{"p2=%p", &pValue, "p2=0xPTR"},     // ... not called with %p
+	{"p3=%p", (*int)(nil), "p3=0x0"},
+	{"p4=%#p", new(int), "p4=PTR"},
+
+	// %p on non-pointers
+	{"%p", make(chan int), "0xPTR"},
+	{"%p", make(map[int]int), "0xPTR"},
+	{"%p", make([]int, 1), "0xPTR"},
+	{"%p", 27, "%!p(int=27)"}, // not a pointer at all
+
+	// %q on pointers
+	{"%q", (*int)(nil), "%!q(*int=<nil>)"},
+	{"%q", new(int), "%!q(*int=0xPTR)"},
+
+	// %v on pointers formats 0 as <nil>
+	{"%v", (*int)(nil), "<nil>"},
+	{"%v", new(int), "0xPTR"},
+
+	// %d etc. pointers use specified base.
+	{"%d", new(int), "PTR_d"},
+	{"%o", new(int), "PTR_o"},
+	{"%x", new(int), "PTR_x"},
+
+	// %d on Stringer should give integer if possible
+	{"%s", time.Time{}.Month(), "January"},
+	{"%d", time.Time{}.Month(), "1"},
+
+	// erroneous things
+	{"%s %", "hello", "hello %!(NOVERB)"},
+	{"%s %.2", "hello", "hello %!(NOVERB)"},
+	{"%d", "hello", "%!d(string=hello)"},
+	{"no args", "hello", "no args%!(EXTRA string=hello)"},
+	{"%s", nil, "%!s(<nil>)"},
+	{"%T", nil, "<nil>"},
+	{"%-1", 100, "%!(NOVERB)%!(EXTRA int=100)"},
+
+	// The "<nil>" show up because maps are printed by
+	// first obtaining a list of keys and then looking up
+	// each key.  Since NaNs can be map keys but cannot
+	// be fetched directly, the lookup fails and returns a
+	// zero reflect.Value, which formats as <nil>.
+	// This test is just to check that it shows the two NaNs at all.
+	{"%v", map[float64]int{math.NaN(): 1, math.NaN(): 2}, "map[NaN:<nil> NaN:<nil>]"},
+
+	// Used to crash because nByte didn't allow for a sign.
+	{"%b", int64(-1 << 63), zeroFill("-1", 63, "")},
+
+	// Used to panic.
+	{"%0100d", 1, zeroFill("", 100, "1")},
+	{"%0100d", -1, zeroFill("-", 99, "1")},
+	{"%0.100f", 1.0, zeroFill("1.", 100, "")},
+	{"%0.100f", -1.0, zeroFill("-1.", 100, "")},
+
+	// Comparison of padding rules with C printf.
+	/*
+		C program:
+		#include <stdio.h>
+
+		char *format[] = {
+			"[%.2f]",
+			"[% .2f]",
+			"[%+.2f]",
+			"[%7.2f]",
+			"[% 7.2f]",
+			"[%+7.2f]",
+			"[%07.2f]",
+			"[% 07.2f]",
+			"[%+07.2f]",
+		};
+
+		int main(void) {
+			int i;
+			for(i = 0; i < 9; i++) {
+				printf("%s: ", format[i]);
+				printf(format[i], 1.0);
+				printf(" ");
+				printf(format[i], -1.0);
+				printf("\n");
+			}
+		}
+
+		Output:
+			[%.2f]: [1.00] [-1.00]
+			[% .2f]: [ 1.00] [-1.00]
+			[%+.2f]: [+1.00] [-1.00]
+			[%7.2f]: [   1.00] [  -1.00]
+			[% 7.2f]: [   1.00] [  -1.00]
+			[%+7.2f]: [  +1.00] [  -1.00]
+			[%07.2f]: [0001.00] [-001.00]
+			[% 07.2f]: [ 001.00] [-001.00]
+			[%+07.2f]: [+001.00] [-001.00]
+	*/
+	{"%.2f", 1.0, "1.00"},
+	{"%.2f", -1.0, "-1.00"},
+	{"% .2f", 1.0, " 1.00"},
+	{"% .2f", -1.0, "-1.00"},
+	{"%+.2f", 1.0, "+1.00"},
+	{"%+.2f", -1.0, "-1.00"},
+	{"%7.2f", 1.0, "   1.00"},
+	{"%7.2f", -1.0, "  -1.00"},
+	{"% 7.2f", 1.0, "   1.00"},
+	{"% 7.2f", -1.0, "  -1.00"},
+	{"%+7.2f", 1.0, "  +1.00"},
+	{"%+7.2f", -1.0, "  -1.00"},
+	{"%07.2f", 1.0, "0001.00"},
+	{"%07.2f", -1.0, "-001.00"},
+	{"% 07.2f", 1.0, " 001.00"},
+	{"% 07.2f", -1.0, "-001.00"},
+	{"%+07.2f", 1.0, "+001.00"},
+	{"%+07.2f", -1.0, "-001.00"},
+
+	// Complex numbers: exhaustively tested in TestComplexFormatting.
+	{"%7.2f", 1 + 2i, "(   1.00  +2.00i)"},
+	{"%+07.2f", -1 - 2i, "(-001.00-002.00i)"},
+	// Zero padding does not apply to infinities.
+	{"%020f", math.Inf(-1), "                -Inf"},
+	{"%020f", math.Inf(+1), "                +Inf"},
+	{"% 020f", math.Inf(-1), "                -Inf"},
+	{"% 020f", math.Inf(+1), "                 Inf"},
+	{"%+020f", math.Inf(-1), "                -Inf"},
+	{"%+020f", math.Inf(+1), "                +Inf"},
+	{"%20f", -1.0, "           -1.000000"},
+	// Make sure we can handle very large widths.
+	{"%0100f", -1.0, zeroFill("-", 99, "1.000000")},
+
+	// Complex fmt used to leave the plus flag set for future entries in the array
+	// causing +2+0i and +3+0i instead of 2+0i and 3+0i.
+	{"%v", []complex64{1, 2, 3}, "[(1+0i) (2+0i) (3+0i)]"},
+	{"%v", []complex128{1, 2, 3}, "[(1+0i) (2+0i) (3+0i)]"},
+
+	// Incomplete format specification caused crash.
+	{"%.", 3, "%!.(int=3)"},
+
+	// Used to panic with out-of-bounds for very large numeric representations.
+	// nByte is set to handle one bit per uint64 in %b format, with a negative number.
+	// See issue 6777.
+	{"%#064x", 1, zeroFill("0x", 64, "1")},
+	{"%#064x", -1, zeroFill("-0x", 63, "1")},
+	{"%#064b", 1, zeroFill("", 64, "1")},
+	{"%#064b", -1, zeroFill("-", 63, "1")},
+	{"%#064o", 1, zeroFill("", 64, "1")},
+	{"%#064o", -1, zeroFill("-", 63, "1")},
+	{"%#064d", 1, zeroFill("", 64, "1")},
+	{"%#064d", -1, zeroFill("-", 63, "1")},
+	// Test that we handle the crossover above the size of uint64
+	{"%#072x", 1, zeroFill("0x", 72, "1")},
+	{"%#072x", -1, zeroFill("-0x", 71, "1")},
+	{"%#072b", 1, zeroFill("", 72, "1")},
+	{"%#072b", -1, zeroFill("-", 71, "1")},
+	{"%#072o", 1, zeroFill("", 72, "1")},
+	{"%#072o", -1, zeroFill("-", 71, "1")},
+	{"%#072d", 1, zeroFill("", 72, "1")},
+	{"%#072d", -1, zeroFill("-", 71, "1")},
+
+	// Padding for complex numbers. Has been bad, then fixed, then bad again.
+	{"%+10.2f", +104.66 + 440.51i, "(   +104.66   +440.51i)"},
+	{"%+10.2f", -104.66 + 440.51i, "(   -104.66   +440.51i)"},
+	{"%+10.2f", +104.66 - 440.51i, "(   +104.66   -440.51i)"},
+	{"%+10.2f", -104.66 - 440.51i, "(   -104.66   -440.51i)"},
+	{"%+010.2f", +104.66 + 440.51i, "(+000104.66+000440.51i)"},
+	{"%+010.2f", -104.66 + 440.51i, "(-000104.66+000440.51i)"},
+	{"%+010.2f", +104.66 - 440.51i, "(+000104.66-000440.51i)"},
+	{"%+010.2f", -104.66 - 440.51i, "(-000104.66-000440.51i)"},
+
+	// []T where type T is a byte with a Stringer method.
+	{"%v", byteStringerSlice, "[X X X X]"},
+	{"%s", byteStringerSlice, "abcd"},
+	{"%q", byteStringerSlice, "\"abcd\""},
+	{"%x", byteStringerSlice, "61626364"},
+	{"%#v", byteStringerSlice, "[]fmt_test.byteStringer{0x61, 0x62, 0x63, 0x64}"},
+
+	// And the same for Formatter.
+	{"%v", byteFormatterSlice, "[X X X X]"},
+	{"%s", byteFormatterSlice, "abcd"},
+	{"%q", byteFormatterSlice, "\"abcd\""},
+	{"%x", byteFormatterSlice, "61626364"},
+	// This next case seems wrong, but the docs say the Formatter wins here.
+	{"%#v", byteFormatterSlice, "[]fmt_test.byteFormatter{X, X, X, X}"},
+}
+
+// zeroFill generates zero-filled strings of the specified width. The length
+// of the suffix (but not the prefix) is compensated for in the width calculation.
+func zeroFill(prefix string, width int, suffix string) string {
+	return prefix + strings.Repeat("0", width-len(suffix)) + suffix
+}
+
+func TestSprintf(t *testing.T) {
+	for _, tt := range fmtTests {
+		s := Sprintf(tt.fmt, tt.val)
+		if i := strings.Index(tt.out, "PTR"); i >= 0 {
+			pattern := "PTR"
+			chars := "0123456789abcdefABCDEF"
+			switch {
+			case strings.HasPrefix(tt.out[i:], "PTR_d"):
+				pattern = "PTR_d"
+				chars = chars[:10]
+			case strings.HasPrefix(tt.out[i:], "PTR_o"):
+				pattern = "PTR_o"
+				chars = chars[:8]
+			case strings.HasPrefix(tt.out[i:], "PTR_x"):
+				pattern = "PTR_x"
+			}
+			j := i
+			for ; j < len(s); j++ {
+				c := s[j]
+				if !strings.ContainsRune(chars, rune(c)) {
+					break
+				}
+			}
+			s = s[0:i] + pattern + s[j:]
+		}
+		if s != tt.out {
+			if _, ok := tt.val.(string); ok {
+				// Don't requote the already-quoted strings.
+				// It's too confusing to read the errors.
+				t.Errorf("Sprintf(%q, %q) = <%s> want <%s>", tt.fmt, tt.val, s, tt.out)
+			} else {
+				t.Errorf("Sprintf(%q, %v) = %q want %q", tt.fmt, tt.val, s, tt.out)
+			}
+		}
+	}
+}
+
+// TestComplexFormatting checks that a complex always formats to the same
+// thing as if done by hand with two singleton prints.
+func TestComplexFormatting(t *testing.T) {
+	var yesNo = []bool{true, false}
+	var values = []float64{1, 0, -1, math.Inf(1), math.Inf(-1), math.NaN()}
+	for _, plus := range yesNo {
+		for _, zero := range yesNo {
+			for _, space := range yesNo {
+				for _, char := range "fFeEgG" {
+					realFmt := "%"
+					if zero {
+						realFmt += "0"
+					}
+					if space {
+						realFmt += " "
+					}
+					if plus {
+						realFmt += "+"
+					}
+					realFmt += "10.2"
+					realFmt += string(char)
+					// Imaginary part always has a sign, so force + and ignore space.
+					imagFmt := "%"
+					if zero {
+						imagFmt += "0"
+					}
+					imagFmt += "+"
+					imagFmt += "10.2"
+					imagFmt += string(char)
+					for _, realValue := range values {
+						for _, imagValue := range values {
+							one := Sprintf(realFmt, complex(realValue, imagValue))
+							two := Sprintf("("+realFmt+imagFmt+"i)", realValue, imagValue)
+							if one != two {
+								t.Error(f, one, two)
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+}
+
+type SE []interface{} // slice of empty; notational compactness.
+
+var reorderTests = []struct {
+	fmt string
+	val SE
+	out string
+}{
+	{"%[1]d", SE{1}, "1"},
+	{"%[2]d", SE{2, 1}, "1"},
+	{"%[2]d %[1]d", SE{1, 2}, "2 1"},
+	{"%[2]*[1]d", SE{2, 5}, "    2"},
+	{"%6.2f", SE{12.0}, " 12.00"}, // Explicit version of next line.
+	{"%[3]*.[2]*[1]f", SE{12.0, 2, 6}, " 12.00"},
+	{"%[1]*.[2]*[3]f", SE{6, 2, 12.0}, " 12.00"},
+	{"%10f", SE{12.0}, " 12.000000"},
+	{"%[1]*[3]f", SE{10, 99, 12.0}, " 12.000000"},
+	{"%.6f", SE{12.0}, "12.000000"}, // Explicit version of next line.
+	{"%.[1]*[3]f", SE{6, 99, 12.0}, "12.000000"},
+	{"%6.f", SE{12.0}, "    12"}, //  // Explicit version of next line; empty precision means zero.
+	{"%[1]*.[3]f", SE{6, 3, 12.0}, "    12"},
+	// An actual use! Print the same arguments twice.
+	{"%d %d %d %#[1]o %#o %#o", SE{11, 12, 13}, "11 12 13 013 014 015"},
+
+	// Erroneous cases.
+	{"%[d", SE{2, 1}, "%!d(BADINDEX)"},
+	{"%]d", SE{2, 1}, "%!](int=2)d%!(EXTRA int=1)"},
+	{"%[]d", SE{2, 1}, "%!d(BADINDEX)"},
+	{"%[-3]d", SE{2, 1}, "%!d(BADINDEX)"},
+	{"%[99]d", SE{2, 1}, "%!d(BADINDEX)"},
+	{"%[3]", SE{2, 1}, "%!(NOVERB)"},
+	{"%[1].2d", SE{5, 6}, "%!d(BADINDEX)"},
+	{"%[1]2d", SE{2, 1}, "%!d(BADINDEX)"},
+	{"%3.[2]d", SE{7}, "%!d(BADINDEX)"},
+	{"%.[2]d", SE{7}, "%!d(BADINDEX)"},
+	{"%d %d %d %#[1]o %#o %#o %#o", SE{11, 12, 13}, "11 12 13 013 014 015 %!o(MISSING)"},
+	{"%[5]d %[2]d %d", SE{1, 2, 3}, "%!d(BADINDEX) 2 3"},
+	{"%d %[3]d %d", SE{1, 2}, "1 %!d(BADINDEX) 2"}, // Erroneous index does not affect sequence.
+}
+
+func TestReorder(t *testing.T) {
+	for _, tt := range reorderTests {
+		s := Sprintf(tt.fmt, tt.val...)
+		if s != tt.out {
+			t.Errorf("Sprintf(%q, %v) = <%s> want <%s>", tt.fmt, tt.val, s, tt.out)
+		} else {
+		}
+	}
+}
+
+func BenchmarkSprintfEmpty(b *testing.B) {
+	b.RunParallel(func(pb *testing.PB) {
+		for pb.Next() {
+			Sprintf("")
+		}
+	})
+}
+
+func BenchmarkSprintfString(b *testing.B) {
+	b.RunParallel(func(pb *testing.PB) {
+		for pb.Next() {
+			Sprintf("%s", "hello")
+		}
+	})
+}
+
+func BenchmarkSprintfInt(b *testing.B) {
+	b.RunParallel(func(pb *testing.PB) {
+		for pb.Next() {
+			Sprintf("%d", 5)
+		}
+	})
+}
+
+func BenchmarkSprintfIntInt(b *testing.B) {
+	b.RunParallel(func(pb *testing.PB) {
+		for pb.Next() {
+			Sprintf("%d %d", 5, 6)
+		}
+	})
+}
+
+func BenchmarkSprintfPrefixedInt(b *testing.B) {
+	b.RunParallel(func(pb *testing.PB) {
+		for pb.Next() {
+			Sprintf("This is some meaningless prefix text that needs to be scanned %d", 6)
+		}
+	})
+}
+
+func BenchmarkSprintfFloat(b *testing.B) {
+	b.RunParallel(func(pb *testing.PB) {
+		for pb.Next() {
+			Sprintf("%g", 5.23184)
+		}
+	})
+}
+
+func BenchmarkManyArgs(b *testing.B) {
+	b.RunParallel(func(pb *testing.PB) {
+		var buf bytes.Buffer
+		for pb.Next() {
+			buf.Reset()
+			Fprintf(&buf, "%2d/%2d/%2d %d:%d:%d %s %s\n", 3, 4, 5, 11, 12, 13, "hello", "world")
+		}
+	})
+}
+
+func BenchmarkFprintInt(b *testing.B) {
+	var buf bytes.Buffer
+	for i := 0; i < b.N; i++ {
+		buf.Reset()
+		Fprint(&buf, 123456)
+	}
+}
+
+func BenchmarkFprintIntNoAlloc(b *testing.B) {
+	var x interface{} = 123456
+	var buf bytes.Buffer
+	for i := 0; i < b.N; i++ {
+		buf.Reset()
+		Fprint(&buf, x)
+	}
+}
+
+var mallocBuf bytes.Buffer
+var mallocPointer *int // A pointer so we know the interface value won't allocate.
+
+var mallocTest = []struct {
+	count int
+	desc  string
+	fn    func()
+}{
+	{0, `Sprintf("")`, func() { Sprintf("") }},
+	{1, `Sprintf("xxx")`, func() { Sprintf("xxx") }},
+	{2, `Sprintf("%x")`, func() { Sprintf("%x", 7) }},
+	{2, `Sprintf("%s")`, func() { Sprintf("%s", "hello") }},
+	{3, `Sprintf("%x %x")`, func() { Sprintf("%x %x", 7, 112) }},
+	{2, `Sprintf("%g")`, func() { Sprintf("%g", float32(3.14159)) }}, // TODO: Can this be 1?
+	{1, `Fprintf(buf, "%s")`, func() { mallocBuf.Reset(); Fprintf(&mallocBuf, "%s", "hello") }},
+	// If the interface value doesn't need to allocate, amortized allocation overhead should be zero.
+	{0, `Fprintf(buf, "%x %x %x")`, func() {
+		mallocBuf.Reset()
+		Fprintf(&mallocBuf, "%x %x %x", mallocPointer, mallocPointer, mallocPointer)
+	}},
+}
+
+var _ bytes.Buffer
+
+func TestCountMallocs(t *testing.T) {
+	if testing.Short() {
+		t.Skip("skipping malloc count in short mode")
+	}
+	if runtime.GOMAXPROCS(0) > 1 {
+		t.Skip("skipping; GOMAXPROCS>1")
+	}
+	for _, mt := range mallocTest {
+		mallocs := testing.AllocsPerRun(100, mt.fn)
+		if got, max := mallocs, float64(mt.count); got > max {
+			t.Errorf("%s: got %v allocs, want <=%v", mt.desc, got, max)
+		}
+	}
+}
+
+type flagPrinter struct{}
+
+func (flagPrinter) Format(f State, c rune) {
+	s := "%"
+	for i := 0; i < 128; i++ {
+		if f.Flag(i) {
+			s += string(i)
+		}
+	}
+	if w, ok := f.Width(); ok {
+		s += Sprintf("%d", w)
+	}
+	if p, ok := f.Precision(); ok {
+		s += Sprintf(".%d", p)
+	}
+	s += string(c)
+	io.WriteString(f, "["+s+"]")
+}
+
+var flagtests = []struct {
+	in  string
+	out string
+}{
+	{"%a", "[%a]"},
+	{"%-a", "[%-a]"},
+	{"%+a", "[%+a]"},
+	{"%#a", "[%#a]"},
+	{"% a", "[% a]"},
+	{"%0a", "[%0a]"},
+	{"%1.2a", "[%1.2a]"},
+	{"%-1.2a", "[%-1.2a]"},
+	{"%+1.2a", "[%+1.2a]"},
+	{"%-+1.2a", "[%+-1.2a]"},
+	{"%-+1.2abc", "[%+-1.2a]bc"},
+	{"%-1.2abc", "[%-1.2a]bc"},
+}
+
+func TestFlagParser(t *testing.T) {
+	var flagprinter flagPrinter
+	for _, tt := range flagtests {
+		s := Sprintf(tt.in, &flagprinter)
+		if s != tt.out {
+			t.Errorf("Sprintf(%q, &flagprinter) => %q, want %q", tt.in, s, tt.out)
+		}
+	}
+}
+
+func TestStructPrinter(t *testing.T) {
+	type T struct {
+		a string
+		b string
+		c int
+	}
+	var s T
+	s.a = "abc"
+	s.b = "def"
+	s.c = 123
+	var tests = []struct {
+		fmt string
+		out string
+	}{
+		{"%v", "{abc def 123}"},
+		{"%+v", "{a:abc b:def c:123}"},
+		{"%#v", `fmt_test.T{a:"abc", b:"def", c:123}`},
+	}
+	for _, tt := range tests {
+		out := Sprintf(tt.fmt, s)
+		if out != tt.out {
+			t.Errorf("Sprintf(%q, s) = %#q, want %#q", tt.fmt, out, tt.out)
+		}
+		// The same but with a pointer.
+		out = Sprintf(tt.fmt, &s)
+		if out != "&"+tt.out {
+			t.Errorf("Sprintf(%q, &s) = %#q, want %#q", tt.fmt, out, "&"+tt.out)
+		}
+	}
+}
+
+func TestSlicePrinter(t *testing.T) {
+	slice := []int{}
+	s := Sprint(slice)
+	if s != "[]" {
+		t.Errorf("empty slice printed as %q not %q", s, "[]")
+	}
+	slice = []int{1, 2, 3}
+	s = Sprint(slice)
+	if s != "[1 2 3]" {
+		t.Errorf("slice: got %q expected %q", s, "[1 2 3]")
+	}
+	s = Sprint(&slice)
+	if s != "&[1 2 3]" {
+		t.Errorf("&slice: got %q expected %q", s, "&[1 2 3]")
+	}
+}
+
+// presentInMap checks map printing using substrings so we don't depend on the
+// print order.
+func presentInMap(s string, a []string, t *testing.T) {
+	for i := 0; i < len(a); i++ {
+		loc := strings.Index(s, a[i])
+		if loc < 0 {
+			t.Errorf("map print: expected to find %q in %q", a[i], s)
+		}
+		// make sure the match ends here
+		loc += len(a[i])
+		if loc >= len(s) || (s[loc] != ' ' && s[loc] != ']') {
+			t.Errorf("map print: %q not properly terminated in %q", a[i], s)
+		}
+	}
+}
+
+func TestMapPrinter(t *testing.T) {
+	m0 := make(map[int]string)
+	s := Sprint(m0)
+	if s != "map[]" {
+		t.Errorf("empty map printed as %q not %q", s, "map[]")
+	}
+	m1 := map[int]string{1: "one", 2: "two", 3: "three"}
+	a := []string{"1:one", "2:two", "3:three"}
+	presentInMap(Sprintf("%v", m1), a, t)
+	presentInMap(Sprint(m1), a, t)
+	// Pointer to map prints the same but with initial &.
+	if !strings.HasPrefix(Sprint(&m1), "&") {
+		t.Errorf("no initial & for address of map")
+	}
+	presentInMap(Sprintf("%v", &m1), a, t)
+	presentInMap(Sprint(&m1), a, t)
+}
+
+func TestEmptyMap(t *testing.T) {
+	const emptyMapStr = "map[]"
+	var m map[string]int
+	s := Sprint(m)
+	if s != emptyMapStr {
+		t.Errorf("nil map printed as %q not %q", s, emptyMapStr)
+	}
+	m = make(map[string]int)
+	s = Sprint(m)
+	if s != emptyMapStr {
+		t.Errorf("empty map printed as %q not %q", s, emptyMapStr)
+	}
+}
+
+// TestBlank checks that Sprint (and hence Print, Fprint) puts spaces in the
+// right places, that is, between arg pairs in which neither is a string.
+func TestBlank(t *testing.T) {
+	got := Sprint("<", 1, ">:", 1, 2, 3, "!")
+	expect := "<1>:1 2 3!"
+	if got != expect {
+		t.Errorf("got %q expected %q", got, expect)
+	}
+}
+
+// TestBlankln checks that Sprintln (and hence Println, Fprintln) puts spaces in
+// the right places, that is, between all arg pairs.
+func TestBlankln(t *testing.T) {
+	got := Sprintln("<", 1, ">:", 1, 2, 3, "!")
+	expect := "< 1 >: 1 2 3 !\n"
+	if got != expect {
+		t.Errorf("got %q expected %q", got, expect)
+	}
+}
+
+// TestFormatterPrintln checks Formatter with Sprint, Sprintln, Sprintf.
+func TestFormatterPrintln(t *testing.T) {
+	f := F(1)
+	expect := "<v=F(1)>\n"
+	s := Sprint(f, "\n")
+	if s != expect {
+		t.Errorf("Sprint wrong with Formatter: expected %q got %q", expect, s)
+	}
+	s = Sprintln(f)
+	if s != expect {
+		t.Errorf("Sprintln wrong with Formatter: expected %q got %q", expect, s)
+	}
+	s = Sprintf("%v\n", f)
+	if s != expect {
+		t.Errorf("Sprintf wrong with Formatter: expected %q got %q", expect, s)
+	}
+}
+
+func args(a ...interface{}) []interface{} { return a }
+
+var startests = []struct {
+	fmt string
+	in  []interface{}
+	out string
+}{
+	{"%*d", args(4, 42), "  42"},
+	{"%.*d", args(4, 42), "0042"},
+	{"%*.*d", args(8, 4, 42), "    0042"},
+	{"%0*d", args(4, 42), "0042"},
+	{"%-*d", args(4, 42), "42  "},
+
+	// erroneous
+	{"%*d", args(nil, 42), "%!(BADWIDTH)42"},
+	{"%.*d", args(nil, 42), "%!(BADPREC)42"},
+	{"%*d", args(5, "foo"), "%!d(string=  foo)"},
+	{"%*% %d", args(20, 5), "% 5"},
+	{"%*", args(4), "%!(NOVERB)"},
+	{"%*d", args(int32(4), 42), "%!(BADWIDTH)42"},
+}
+
+func TestWidthAndPrecision(t *testing.T) {
+	for _, tt := range startests {
+		s := Sprintf(tt.fmt, tt.in...)
+		if s != tt.out {
+			t.Errorf("%q: got %q expected %q", tt.fmt, s, tt.out)
+		}
+	}
+}
+
+// Panic is a type that panics in String.
+type Panic struct {
+	message interface{}
+}
+
+// Value receiver.
+func (p Panic) GoString() string {
+	panic(p.message)
+}
+
+// Value receiver.
+func (p Panic) String() string {
+	panic(p.message)
+}
+
+// PanicF is a type that panics in Format.
+type PanicF struct {
+	message interface{}
+}
+
+// Value receiver.
+func (p PanicF) Format(f State, c rune) {
+	panic(p.message)
+}
+
+var panictests = []struct {
+	fmt string
+	in  interface{}
+	out string
+}{
+	// String
+	{"%s", (*Panic)(nil), "<nil>"}, // nil pointer special case
+	{"%s", Panic{io.ErrUnexpectedEOF}, "%!s(PANIC=unexpected EOF)"},
+	{"%s", Panic{3}, "%!s(PANIC=3)"},
+	// GoString
+	{"%#v", (*Panic)(nil), "<nil>"}, // nil pointer special case
+	{"%#v", Panic{io.ErrUnexpectedEOF}, "%!v(PANIC=unexpected EOF)"},
+	{"%#v", Panic{3}, "%!v(PANIC=3)"},
+	// Format
+	{"%s", (*PanicF)(nil), "<nil>"}, // nil pointer special case
+	{"%s", PanicF{io.ErrUnexpectedEOF}, "%!s(PANIC=unexpected EOF)"},
+	{"%s", PanicF{3}, "%!s(PANIC=3)"},
+}
+
+func TestPanics(t *testing.T) {
+	for i, tt := range panictests {
+		s := Sprintf(tt.fmt, tt.in)
+		if s != tt.out {
+			t.Errorf("%d: %q: got %q expected %q", i, tt.fmt, s, tt.out)
+		}
+	}
+}
+
+// recurCount tests that erroneous String routine doesn't cause fatal recursion.
+var recurCount = 0
+
+type Recur struct {
+	i      int
+	failed *bool
+}
+
+func (r *Recur) String() string {
+	if recurCount++; recurCount > 10 {
+		*r.failed = true
+		return "FAIL"
+	}
+	// This will call badVerb. Before the fix, that would cause us to recur into
+	// this routine to print %!p(value). Now we don't call the user's method
+	// during an error.
+	return Sprintf("recur@%p value: %d", r, r.i)
+}
+
+func TestBadVerbRecursion(t *testing.T) {
+	failed := false
+	r := &Recur{3, &failed}
+	Sprintf("recur@%p value: %d\n", &r, r.i)
+	if failed {
+		t.Error("fail with pointer")
+	}
+	failed = false
+	r = &Recur{4, &failed}
+	Sprintf("recur@%p, value: %d\n", r, r.i)
+	if failed {
+		t.Error("fail with value")
+	}
+}
+
+func TestIsSpace(t *testing.T) {
+	// This tests the internal isSpace function.
+	// IsSpace = isSpace is defined in export_test.go.
+	for i := rune(0); i <= unicode.MaxRune; i++ {
+		if IsSpace(i) != unicode.IsSpace(i) {
+			t.Errorf("isSpace(%U) = %v, want %v", i, IsSpace(i), unicode.IsSpace(i))
+		}
+	}
+}
+
+func TestNilDoesNotBecomeTyped(t *testing.T) {
+	type A struct{}
+	type B struct{}
+	var a *A = nil
+	var b B = B{}
+	got := Sprintf("%s %s %s %s %s", nil, a, nil, b, nil)
+	const expect = "%!s(<nil>) %!s(*fmt_test.A=<nil>) %!s(<nil>) {} %!s(<nil>)"
+	if got != expect {
+		t.Errorf("expected:\n\t%q\ngot:\n\t%q", expect, got)
+	}
+}
+
+var formatterFlagTests = []struct {
+	in  string
+	val interface{}
+	out string
+}{
+	// scalar values with the (unused by fmt) 'a' verb.
+	{"%a", flagPrinter{}, "[%a]"},
+	{"%-a", flagPrinter{}, "[%-a]"},
+	{"%+a", flagPrinter{}, "[%+a]"},
+	{"%#a", flagPrinter{}, "[%#a]"},
+	{"% a", flagPrinter{}, "[% a]"},
+	{"%0a", flagPrinter{}, "[%0a]"},
+	{"%1.2a", flagPrinter{}, "[%1.2a]"},
+	{"%-1.2a", flagPrinter{}, "[%-1.2a]"},
+	{"%+1.2a", flagPrinter{}, "[%+1.2a]"},
+	{"%-+1.2a", flagPrinter{}, "[%+-1.2a]"},
+	{"%-+1.2abc", flagPrinter{}, "[%+-1.2a]bc"},
+	{"%-1.2abc", flagPrinter{}, "[%-1.2a]bc"},
+
+	// composite values with the 'a' verb
+	{"%a", [1]flagPrinter{}, "[[%a]]"},
+	{"%-a", [1]flagPrinter{}, "[[%-a]]"},
+	{"%+a", [1]flagPrinter{}, "[[%+a]]"},
+	{"%#a", [1]flagPrinter{}, "[[%#a]]"},
+	{"% a", [1]flagPrinter{}, "[[% a]]"},
+	{"%0a", [1]flagPrinter{}, "[[%0a]]"},
+	{"%1.2a", [1]flagPrinter{}, "[[%1.2a]]"},
+	{"%-1.2a", [1]flagPrinter{}, "[[%-1.2a]]"},
+	{"%+1.2a", [1]flagPrinter{}, "[[%+1.2a]]"},
+	{"%-+1.2a", [1]flagPrinter{}, "[[%+-1.2a]]"},
+	{"%-+1.2abc", [1]flagPrinter{}, "[[%+-1.2a]]bc"},
+	{"%-1.2abc", [1]flagPrinter{}, "[[%-1.2a]]bc"},
+
+	// simple values with the 'v' verb
+	{"%v", flagPrinter{}, "[%v]"},
+	{"%-v", flagPrinter{}, "[%-v]"},
+	{"%+v", flagPrinter{}, "[%+v]"},
+	{"%#v", flagPrinter{}, "[%#v]"},
+	{"% v", flagPrinter{}, "[% v]"},
+	{"%0v", flagPrinter{}, "[%0v]"},
+	{"%1.2v", flagPrinter{}, "[%1.2v]"},
+	{"%-1.2v", flagPrinter{}, "[%-1.2v]"},
+	{"%+1.2v", flagPrinter{}, "[%+1.2v]"},
+	{"%-+1.2v", flagPrinter{}, "[%+-1.2v]"},
+	{"%-+1.2vbc", flagPrinter{}, "[%+-1.2v]bc"},
+	{"%-1.2vbc", flagPrinter{}, "[%-1.2v]bc"},
+
+	// composite values with the 'v' verb.
+	{"%v", [1]flagPrinter{}, "[[%v]]"},
+	{"%-v", [1]flagPrinter{}, "[[%-v]]"},
+	{"%+v", [1]flagPrinter{}, "[[%+v]]"},
+	{"%#v", [1]flagPrinter{}, "[1]fmt_test.flagPrinter{[%#v]}"},
+	{"% v", [1]flagPrinter{}, "[[% v]]"},
+	{"%0v", [1]flagPrinter{}, "[[%0v]]"},
+	{"%1.2v", [1]flagPrinter{}, "[[%1.2v]]"},
+	{"%-1.2v", [1]flagPrinter{}, "[[%-1.2v]]"},
+	{"%+1.2v", [1]flagPrinter{}, "[[%+1.2v]]"},
+	{"%-+1.2v", [1]flagPrinter{}, "[[%+-1.2v]]"},
+	{"%-+1.2vbc", [1]flagPrinter{}, "[[%+-1.2v]]bc"},
+	{"%-1.2vbc", [1]flagPrinter{}, "[[%-1.2v]]bc"},
+}
+
+func TestFormatterFlags(t *testing.T) {
+	for _, tt := range formatterFlagTests {
+		s := Sprintf(tt.in, tt.val)
+		if s != tt.out {
+			t.Errorf("Sprintf(%q, %T) = %q, want %q", tt.in, tt.val, s, tt.out)
+		}
+	}
+}
diff --git a/src/fmt/format.go b/src/fmt/format.go
new file mode 100644
index 0000000..4d97d14
--- /dev/null
+++ b/src/fmt/format.go
@@ -0,0 +1,524 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package fmt
+
+import (
+	"math"
+	"strconv"
+	"unicode/utf8"
+)
+
+const (
+	// %b of an int64, plus a sign.
+	// Hex can add 0x and we handle it specially.
+	nByte = 65
+
+	ldigits = "0123456789abcdef"
+	udigits = "0123456789ABCDEF"
+)
+
+const (
+	signed   = true
+	unsigned = false
+)
+
+var padZeroBytes = make([]byte, nByte)
+var padSpaceBytes = make([]byte, nByte)
+
+func init() {
+	for i := 0; i < nByte; i++ {
+		padZeroBytes[i] = '0'
+		padSpaceBytes[i] = ' '
+	}
+}
+
+// flags placed in a separate struct for easy clearing.
+type fmtFlags struct {
+	widPresent  bool
+	precPresent bool
+	minus       bool
+	plus        bool
+	sharp       bool
+	space       bool
+	unicode     bool
+	uniQuote    bool // Use 'x'= prefix for %U if printable.
+	zero        bool
+
+	// For the formats %+v %#v, we set the plusV/sharpV flags
+	// and clear the plus/sharp flags since %+v and %#v are in effect
+	// different, flagless formats set at the top level.
+	plusV  bool
+	sharpV bool
+}
+
+// A fmt is the raw formatter used by Printf etc.
+// It prints into a buffer that must be set up separately.
+type fmt struct {
+	intbuf [nByte]byte
+	buf    *buffer
+	// width, precision
+	wid  int
+	prec int
+	fmtFlags
+}
+
+func (f *fmt) clearflags() {
+	f.fmtFlags = fmtFlags{}
+}
+
+func (f *fmt) init(buf *buffer) {
+	f.buf = buf
+	f.clearflags()
+}
+
+// computePadding computes left and right padding widths (only one will be non-zero).
+func (f *fmt) computePadding(width int) (padding []byte, leftWidth, rightWidth int) {
+	left := !f.minus
+	w := f.wid
+	if w < 0 {
+		left = false
+		w = -w
+	}
+	w -= width
+	if w > 0 {
+		if left && f.zero {
+			return padZeroBytes, w, 0
+		}
+		if left {
+			return padSpaceBytes, w, 0
+		} else {
+			// can't be zero padding on the right
+			return padSpaceBytes, 0, w
+		}
+	}
+	return
+}
+
+// writePadding generates n bytes of padding.
+func (f *fmt) writePadding(n int, padding []byte) {
+	for n > 0 {
+		m := n
+		if m > nByte {
+			m = nByte
+		}
+		f.buf.Write(padding[0:m])
+		n -= m
+	}
+}
+
+// pad appends b to f.buf, padded on left (w > 0) or right (w < 0 or f.minus).
+func (f *fmt) pad(b []byte) {
+	if !f.widPresent || f.wid == 0 {
+		f.buf.Write(b)
+		return
+	}
+	padding, left, right := f.computePadding(utf8.RuneCount(b))
+	if left > 0 {
+		f.writePadding(left, padding)
+	}
+	f.buf.Write(b)
+	if right > 0 {
+		f.writePadding(right, padding)
+	}
+}
+
+// padString appends s to buf, padded on left (w > 0) or right (w < 0 or f.minus).
+func (f *fmt) padString(s string) {
+	if !f.widPresent || f.wid == 0 {
+		f.buf.WriteString(s)
+		return
+	}
+	padding, left, right := f.computePadding(utf8.RuneCountInString(s))
+	if left > 0 {
+		f.writePadding(left, padding)
+	}
+	f.buf.WriteString(s)
+	if right > 0 {
+		f.writePadding(right, padding)
+	}
+}
+
+var (
+	trueBytes  = []byte("true")
+	falseBytes = []byte("false")
+)
+
+// fmt_boolean formats a boolean.
+func (f *fmt) fmt_boolean(v bool) {
+	if v {
+		f.pad(trueBytes)
+	} else {
+		f.pad(falseBytes)
+	}
+}
+
+// integer; interprets prec but not wid.  Once formatted, result is sent to pad()
+// and then flags are cleared.
+func (f *fmt) integer(a int64, base uint64, signedness bool, digits string) {
+	// precision of 0 and value of 0 means "print nothing"
+	if f.precPresent && f.prec == 0 && a == 0 {
+		return
+	}
+
+	var buf []byte = f.intbuf[0:]
+	if f.widPresent {
+		width := f.wid
+		if base == 16 && f.sharp {
+			// Also adds "0x".
+			width += 2
+		}
+		if width > nByte {
+			// We're going to need a bigger boat.
+			buf = make([]byte, width)
+		}
+	}
+
+	negative := signedness == signed && a < 0
+	if negative {
+		a = -a
+	}
+
+	// two ways to ask for extra leading zero digits: %.3d or %03d.
+	// apparently the first cancels the second.
+	prec := 0
+	if f.precPresent {
+		prec = f.prec
+		f.zero = false
+	} else if f.zero && f.widPresent && !f.minus && f.wid > 0 {
+		prec = f.wid
+		if negative || f.plus || f.space {
+			prec-- // leave room for sign
+		}
+	}
+
+	// format a into buf, ending at buf[i].  (printing is easier right-to-left.)
+	// a is made into unsigned ua.  we could make things
+	// marginally faster by splitting the 32-bit case out into a separate
+	// block but it's not worth the duplication, so ua has 64 bits.
+	i := len(buf)
+	ua := uint64(a)
+	// use constants for the division and modulo for more efficient code.
+	// switch cases ordered by popularity.
+	switch base {
+	case 10:
+		for ua >= 10 {
+			i--
+			next := ua / 10
+			buf[i] = byte('0' + ua - next*10)
+			ua = next
+		}
+	case 16:
+		for ua >= 16 {
+			i--
+			buf[i] = digits[ua&0xF]
+			ua >>= 4
+		}
+	case 8:
+		for ua >= 8 {
+			i--
+			buf[i] = byte('0' + ua&7)
+			ua >>= 3
+		}
+	case 2:
+		for ua >= 2 {
+			i--
+			buf[i] = byte('0' + ua&1)
+			ua >>= 1
+		}
+	default:
+		panic("fmt: unknown base; can't happen")
+	}
+	i--
+	buf[i] = digits[ua]
+	for i > 0 && prec > len(buf)-i {
+		i--
+		buf[i] = '0'
+	}
+
+	// Various prefixes: 0x, -, etc.
+	if f.sharp {
+		switch base {
+		case 8:
+			if buf[i] != '0' {
+				i--
+				buf[i] = '0'
+			}
+		case 16:
+			i--
+			buf[i] = 'x' + digits[10] - 'a'
+			i--
+			buf[i] = '0'
+		}
+	}
+	if f.unicode {
+		i--
+		buf[i] = '+'
+		i--
+		buf[i] = 'U'
+	}
+
+	if negative {
+		i--
+		buf[i] = '-'
+	} else if f.plus {
+		i--
+		buf[i] = '+'
+	} else if f.space {
+		i--
+		buf[i] = ' '
+	}
+
+	// If we want a quoted char for %#U, move the data up to make room.
+	if f.unicode && f.uniQuote && a >= 0 && a <= utf8.MaxRune && strconv.IsPrint(rune(a)) {
+		runeWidth := utf8.RuneLen(rune(a))
+		width := 1 + 1 + runeWidth + 1 // space, quote, rune, quote
+		copy(buf[i-width:], buf[i:])   // guaranteed to have enough room.
+		i -= width
+		// Now put " 'x'" at the end.
+		j := len(buf) - width
+		buf[j] = ' '
+		j++
+		buf[j] = '\''
+		j++
+		utf8.EncodeRune(buf[j:], rune(a))
+		j += runeWidth
+		buf[j] = '\''
+	}
+
+	f.pad(buf[i:])
+}
+
+// truncate truncates the string to the specified precision, if present.
+func (f *fmt) truncate(s string) string {
+	if f.precPresent && f.prec < utf8.RuneCountInString(s) {
+		n := f.prec
+		for i := range s {
+			if n == 0 {
+				s = s[:i]
+				break
+			}
+			n--
+		}
+	}
+	return s
+}
+
+// fmt_s formats a string.
+func (f *fmt) fmt_s(s string) {
+	s = f.truncate(s)
+	f.padString(s)
+}
+
+// fmt_sbx formats a string or byte slice as a hexadecimal encoding of its bytes.
+func (f *fmt) fmt_sbx(s string, b []byte, digits string) {
+	n := len(b)
+	if b == nil {
+		n = len(s)
+	}
+	x := digits[10] - 'a' + 'x'
+	// TODO: Avoid buffer by pre-padding.
+	var buf []byte
+	for i := 0; i < n; i++ {
+		if i > 0 && f.space {
+			buf = append(buf, ' ')
+		}
+		if f.sharp && (f.space || i == 0) {
+			buf = append(buf, '0', x)
+		}
+		var c byte
+		if b == nil {
+			c = s[i]
+		} else {
+			c = b[i]
+		}
+		buf = append(buf, digits[c>>4], digits[c&0xF])
+	}
+	f.pad(buf)
+}
+
+// fmt_sx formats a string as a hexadecimal encoding of its bytes.
+func (f *fmt) fmt_sx(s, digits string) {
+	if f.precPresent && f.prec < len(s) {
+		s = s[:f.prec]
+	}
+	f.fmt_sbx(s, nil, digits)
+}
+
+// fmt_bx formats a byte slice as a hexadecimal encoding of its bytes.
+func (f *fmt) fmt_bx(b []byte, digits string) {
+	if f.precPresent && f.prec < len(b) {
+		b = b[:f.prec]
+	}
+	f.fmt_sbx("", b, digits)
+}
+
+// fmt_q formats a string as a double-quoted, escaped Go string constant.
+func (f *fmt) fmt_q(s string) {
+	s = f.truncate(s)
+	var quoted string
+	if f.sharp && strconv.CanBackquote(s) {
+		quoted = "`" + s + "`"
+	} else {
+		if f.plus {
+			quoted = strconv.QuoteToASCII(s)
+		} else {
+			quoted = strconv.Quote(s)
+		}
+	}
+	f.padString(quoted)
+}
+
+// fmt_qc formats the integer as a single-quoted, escaped Go character constant.
+// If the character is not valid Unicode, it will print '\ufffd'.
+func (f *fmt) fmt_qc(c int64) {
+	var quoted []byte
+	if f.plus {
+		quoted = strconv.AppendQuoteRuneToASCII(f.intbuf[0:0], rune(c))
+	} else {
+		quoted = strconv.AppendQuoteRune(f.intbuf[0:0], rune(c))
+	}
+	f.pad(quoted)
+}
+
+// floating-point
+
+func doPrec(f *fmt, def int) int {
+	if f.precPresent {
+		return f.prec
+	}
+	return def
+}
+
+// formatFloat formats a float64; it is an efficient equivalent to  f.pad(strconv.FormatFloat()...).
+func (f *fmt) formatFloat(v float64, verb byte, prec, n int) {
+	// Format number, reserving space for leading + sign if needed.
+	num := strconv.AppendFloat(f.intbuf[0:1], v, verb, prec, n)
+	if num[1] == '-' || num[1] == '+' {
+		num = num[1:]
+	} else {
+		num[0] = '+'
+	}
+	// Special handling for infinity, which doesn't look like a number so shouldn't be padded with zeros.
+	if math.IsInf(v, 0) {
+		if f.zero {
+			defer func() { f.zero = true }()
+			f.zero = false
+		}
+	}
+	// num is now a signed version of the number.
+	// If we're zero padding, want the sign before the leading zeros.
+	// Achieve this by writing the sign out and then padding the unsigned number.
+	if f.zero && f.widPresent && f.wid > len(num) {
+		if f.space && v >= 0 {
+			f.buf.WriteByte(' ') // This is what C does: even with zero, f.space means space.
+			f.wid--
+		} else if f.plus || v < 0 {
+			f.buf.WriteByte(num[0])
+			f.wid--
+		}
+		f.pad(num[1:])
+		return
+	}
+	// f.space says to replace a leading + with a space.
+	if f.space && num[0] == '+' {
+		num[0] = ' '
+		f.pad(num)
+		return
+	}
+	// Now we know the sign is attached directly to the number, if present at all.
+	// We want a sign if asked for, if it's negative, or if it's infinity (+Inf vs. -Inf).
+	if f.plus || num[0] == '-' || math.IsInf(v, 0) {
+		f.pad(num)
+		return
+	}
+	// No sign to show and the number is positive; just print the unsigned number.
+	f.pad(num[1:])
+}
+
+// fmt_e64 formats a float64 in the form -1.23e+12.
+func (f *fmt) fmt_e64(v float64) { f.formatFloat(v, 'e', doPrec(f, 6), 64) }
+
+// fmt_E64 formats a float64 in the form -1.23E+12.
+func (f *fmt) fmt_E64(v float64) { f.formatFloat(v, 'E', doPrec(f, 6), 64) }
+
+// fmt_f64 formats a float64 in the form -1.23.
+func (f *fmt) fmt_f64(v float64) { f.formatFloat(v, 'f', doPrec(f, 6), 64) }
+
+// fmt_g64 formats a float64 in the 'f' or 'e' form according to size.
+func (f *fmt) fmt_g64(v float64) { f.formatFloat(v, 'g', doPrec(f, -1), 64) }
+
+// fmt_G64 formats a float64 in the 'f' or 'E' form according to size.
+func (f *fmt) fmt_G64(v float64) { f.formatFloat(v, 'G', doPrec(f, -1), 64) }
+
+// fmt_fb64 formats a float64 in the form -123p3 (exponent is power of 2).
+func (f *fmt) fmt_fb64(v float64) { f.formatFloat(v, 'b', 0, 64) }
+
+// float32
+// cannot defer to float64 versions
+// because it will get rounding wrong in corner cases.
+
+// fmt_e32 formats a float32 in the form -1.23e+12.
+func (f *fmt) fmt_e32(v float32) { f.formatFloat(float64(v), 'e', doPrec(f, 6), 32) }
+
+// fmt_E32 formats a float32 in the form -1.23E+12.
+func (f *fmt) fmt_E32(v float32) { f.formatFloat(float64(v), 'E', doPrec(f, 6), 32) }
+
+// fmt_f32 formats a float32 in the form -1.23.
+func (f *fmt) fmt_f32(v float32) { f.formatFloat(float64(v), 'f', doPrec(f, 6), 32) }
+
+// fmt_g32 formats a float32 in the 'f' or 'e' form according to size.
+func (f *fmt) fmt_g32(v float32) { f.formatFloat(float64(v), 'g', doPrec(f, -1), 32) }
+
+// fmt_G32 formats a float32 in the 'f' or 'E' form according to size.
+func (f *fmt) fmt_G32(v float32) { f.formatFloat(float64(v), 'G', doPrec(f, -1), 32) }
+
+// fmt_fb32 formats a float32 in the form -123p3 (exponent is power of 2).
+func (f *fmt) fmt_fb32(v float32) { f.formatFloat(float64(v), 'b', 0, 32) }
+
+// fmt_c64 formats a complex64 according to the verb.
+func (f *fmt) fmt_c64(v complex64, verb rune) {
+	f.fmt_complex(float64(real(v)), float64(imag(v)), 32, verb)
+}
+
+// fmt_c128 formats a complex128 according to the verb.
+func (f *fmt) fmt_c128(v complex128, verb rune) {
+	f.fmt_complex(real(v), imag(v), 64, verb)
+}
+
+// fmt_complex formats a complex number as (r+ji).
+func (f *fmt) fmt_complex(r, j float64, size int, verb rune) {
+	f.buf.WriteByte('(')
+	oldPlus := f.plus
+	oldSpace := f.space
+	oldWid := f.wid
+	for i := 0; ; i++ {
+		switch verb {
+		case 'b':
+			f.formatFloat(r, 'b', 0, size)
+		case 'e':
+			f.formatFloat(r, 'e', doPrec(f, 6), size)
+		case 'E':
+			f.formatFloat(r, 'E', doPrec(f, 6), size)
+		case 'f', 'F':
+			f.formatFloat(r, 'f', doPrec(f, 6), size)
+		case 'g':
+			f.formatFloat(r, 'g', doPrec(f, -1), size)
+		case 'G':
+			f.formatFloat(r, 'G', doPrec(f, -1), size)
+		}
+		if i != 0 {
+			break
+		}
+		// Imaginary part always has a sign.
+		f.plus = true
+		f.space = false
+		f.wid = oldWid
+		r = j
+	}
+	f.space = oldSpace
+	f.plus = oldPlus
+	f.wid = oldWid
+	f.buf.Write(irparenBytes)
+}
diff --git a/src/fmt/print.go b/src/fmt/print.go
new file mode 100644
index 0000000..59a30d2
--- /dev/null
+++ b/src/fmt/print.go
@@ -0,0 +1,1223 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package fmt
+
+import (
+	"errors"
+	"io"
+	"os"
+	"reflect"
+	"sync"
+	"unicode/utf8"
+)
+
+// Some constants in the form of bytes, to avoid string overhead.
+// Needlessly fastidious, I suppose.
+var (
+	commaSpaceBytes  = []byte(", ")
+	nilAngleBytes    = []byte("<nil>")
+	nilParenBytes    = []byte("(nil)")
+	nilBytes         = []byte("nil")
+	mapBytes         = []byte("map[")
+	percentBangBytes = []byte("%!")
+	missingBytes     = []byte("(MISSING)")
+	badIndexBytes    = []byte("(BADINDEX)")
+	panicBytes       = []byte("(PANIC=")
+	extraBytes       = []byte("%!(EXTRA ")
+	irparenBytes     = []byte("i)")
+	bytesBytes       = []byte("[]byte{")
+	badWidthBytes    = []byte("%!(BADWIDTH)")
+	badPrecBytes     = []byte("%!(BADPREC)")
+	noVerbBytes      = []byte("%!(NOVERB)")
+)
+
+// State represents the printer state passed to custom formatters.
+// It provides access to the io.Writer interface plus information about
+// the flags and options for the operand's format specifier.
+type State interface {
+	// Write is the function to call to emit formatted output to be printed.
+	Write(b []byte) (ret int, err error)
+	// Width returns the value of the width option and whether it has been set.
+	Width() (wid int, ok bool)
+	// Precision returns the value of the precision option and whether it has been set.
+	Precision() (prec int, ok bool)
+
+	// Flag reports whether the flag c, a character, has been set.
+	Flag(c int) bool
+}
+
+// Formatter is the interface implemented by values with a custom formatter.
+// The implementation of Format may call Sprint(f) or Fprint(f) etc.
+// to generate its output.
+type Formatter interface {
+	Format(f State, c rune)
+}
+
+// Stringer is implemented by any value that has a String method,
+// which defines the ``native'' format for that value.
+// The String method is used to print values passed as an operand
+// to any format that accepts a string or to an unformatted printer
+// such as Print.
+type Stringer interface {
+	String() string
+}
+
+// GoStringer is implemented by any value that has a GoString method,
+// which defines the Go syntax for that value.
+// The GoString method is used to print values passed as an operand
+// to a %#v format.
+type GoStringer interface {
+	GoString() string
+}
+
+// Use simple []byte instead of bytes.Buffer to avoid large dependency.
+type buffer []byte
+
+func (b *buffer) Write(p []byte) (n int, err error) {
+	*b = append(*b, p...)
+	return len(p), nil
+}
+
+func (b *buffer) WriteString(s string) (n int, err error) {
+	*b = append(*b, s...)
+	return len(s), nil
+}
+
+func (b *buffer) WriteByte(c byte) error {
+	*b = append(*b, c)
+	return nil
+}
+
+func (bp *buffer) WriteRune(r rune) error {
+	if r < utf8.RuneSelf {
+		*bp = append(*bp, byte(r))
+		return nil
+	}
+
+	b := *bp
+	n := len(b)
+	for n+utf8.UTFMax > cap(b) {
+		b = append(b, 0)
+	}
+	w := utf8.EncodeRune(b[n:n+utf8.UTFMax], r)
+	*bp = b[:n+w]
+	return nil
+}
+
+type pp struct {
+	n         int
+	panicking bool
+	erroring  bool // printing an error condition
+	buf       buffer
+	// arg holds the current item, as an interface{}.
+	arg interface{}
+	// value holds the current item, as a reflect.Value, and will be
+	// the zero Value if the item has not been reflected.
+	value reflect.Value
+	// reordered records whether the format string used argument reordering.
+	reordered bool
+	// goodArgNum records whether the most recent reordering directive was valid.
+	goodArgNum bool
+	runeBuf    [utf8.UTFMax]byte
+	fmt        fmt
+}
+
+var ppFree = sync.Pool{
+	New: func() interface{} { return new(pp) },
+}
+
+// newPrinter allocates a new pp struct or grabs a cached one.
+func newPrinter() *pp {
+	p := ppFree.Get().(*pp)
+	p.panicking = false
+	p.erroring = false
+	p.fmt.init(&p.buf)
+	return p
+}
+
+// free saves used pp structs in ppFree; avoids an allocation per invocation.
+func (p *pp) free() {
+	// Don't hold on to pp structs with large buffers.
+	if cap(p.buf) > 1024 {
+		return
+	}
+	p.buf = p.buf[:0]
+	p.arg = nil
+	p.value = reflect.Value{}
+	ppFree.Put(p)
+}
+
+func (p *pp) Width() (wid int, ok bool) { return p.fmt.wid, p.fmt.widPresent }
+
+func (p *pp) Precision() (prec int, ok bool) { return p.fmt.prec, p.fmt.precPresent }
+
+func (p *pp) Flag(b int) bool {
+	switch b {
+	case '-':
+		return p.fmt.minus
+	case '+':
+		return p.fmt.plus
+	case '#':
+		return p.fmt.sharp
+	case ' ':
+		return p.fmt.space
+	case '0':
+		return p.fmt.zero
+	}
+	return false
+}
+
+func (p *pp) add(c rune) {
+	p.buf.WriteRune(c)
+}
+
+// Implement Write so we can call Fprintf on a pp (through State), for
+// recursive use in custom verbs.
+func (p *pp) Write(b []byte) (ret int, err error) {
+	return p.buf.Write(b)
+}
+
+// These routines end in 'f' and take a format string.
+
+// Fprintf formats according to a format specifier and writes to w.
+// It returns the number of bytes written and any write error encountered.
+func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) {
+	p := newPrinter()
+	p.doPrintf(format, a)
+	n, err = w.Write(p.buf)
+	p.free()
+	return
+}
+
+// Printf formats according to a format specifier and writes to standard output.
+// It returns the number of bytes written and any write error encountered.
+func Printf(format string, a ...interface{}) (n int, err error) {
+	return Fprintf(os.Stdout, format, a...)
+}
+
+// Sprintf formats according to a format specifier and returns the resulting string.
+func Sprintf(format string, a ...interface{}) string {
+	p := newPrinter()
+	p.doPrintf(format, a)
+	s := string(p.buf)
+	p.free()
+	return s
+}
+
+// Errorf formats according to a format specifier and returns the string
+// as a value that satisfies error.
+func Errorf(format string, a ...interface{}) error {
+	return errors.New(Sprintf(format, a...))
+}
+
+// These routines do not take a format string
+
+// Fprint formats using the default formats for its operands and writes to w.
+// Spaces are added between operands when neither is a string.
+// It returns the number of bytes written and any write error encountered.
+func Fprint(w io.Writer, a ...interface{}) (n int, err error) {
+	p := newPrinter()
+	p.doPrint(a, false, false)
+	n, err = w.Write(p.buf)
+	p.free()
+	return
+}
+
+// Print formats using the default formats for its operands and writes to standard output.
+// Spaces are added between operands when neither is a string.
+// It returns the number of bytes written and any write error encountered.
+func Print(a ...interface{}) (n int, err error) {
+	return Fprint(os.Stdout, a...)
+}
+
+// Sprint formats using the default formats for its operands and returns the resulting string.
+// Spaces are added between operands when neither is a string.
+func Sprint(a ...interface{}) string {
+	p := newPrinter()
+	p.doPrint(a, false, false)
+	s := string(p.buf)
+	p.free()
+	return s
+}
+
+// These routines end in 'ln', do not take a format string,
+// always add spaces between operands, and add a newline
+// after the last operand.
+
+// Fprintln formats using the default formats for its operands and writes to w.
+// Spaces are always added between operands and a newline is appended.
+// It returns the number of bytes written and any write error encountered.
+func Fprintln(w io.Writer, a ...interface{}) (n int, err error) {
+	p := newPrinter()
+	p.doPrint(a, true, true)
+	n, err = w.Write(p.buf)
+	p.free()
+	return
+}
+
+// Println formats using the default formats for its operands and writes to standard output.
+// Spaces are always added between operands and a newline is appended.
+// It returns the number of bytes written and any write error encountered.
+func Println(a ...interface{}) (n int, err error) {
+	return Fprintln(os.Stdout, a...)
+}
+
+// Sprintln formats using the default formats for its operands and returns the resulting string.
+// Spaces are always added between operands and a newline is appended.
+func Sprintln(a ...interface{}) string {
+	p := newPrinter()
+	p.doPrint(a, true, true)
+	s := string(p.buf)
+	p.free()
+	return s
+}
+
+// getField gets the i'th field of the struct value.
+// If the field is itself is an interface, return a value for
+// the thing inside the interface, not the interface itself.
+func getField(v reflect.Value, i int) reflect.Value {
+	val := v.Field(i)
+	if val.Kind() == reflect.Interface && !val.IsNil() {
+		val = val.Elem()
+	}
+	return val
+}
+
+// parsenum converts ASCII to integer.  num is 0 (and isnum is false) if no number present.
+func parsenum(s string, start, end int) (num int, isnum bool, newi int) {
+	if start >= end {
+		return 0, false, end
+	}
+	for newi = start; newi < end && '0' <= s[newi] && s[newi] <= '9'; newi++ {
+		num = num*10 + int(s[newi]-'0')
+		isnum = true
+	}
+	return
+}
+
+func (p *pp) unknownType(v reflect.Value) {
+	if !v.IsValid() {
+		p.buf.Write(nilAngleBytes)
+		return
+	}
+	p.buf.WriteByte('?')
+	p.buf.WriteString(v.Type().String())
+	p.buf.WriteByte('?')
+}
+
+func (p *pp) badVerb(verb rune) {
+	p.erroring = true
+	p.add('%')
+	p.add('!')
+	p.add(verb)
+	p.add('(')
+	switch {
+	case p.arg != nil:
+		p.buf.WriteString(reflect.TypeOf(p.arg).String())
+		p.add('=')
+		p.printArg(p.arg, 'v', 0)
+	case p.value.IsValid():
+		p.buf.WriteString(p.value.Type().String())
+		p.add('=')
+		p.printValue(p.value, 'v', 0)
+	default:
+		p.buf.Write(nilAngleBytes)
+	}
+	p.add(')')
+	p.erroring = false
+}
+
+func (p *pp) fmtBool(v bool, verb rune) {
+	switch verb {
+	case 't', 'v':
+		p.fmt.fmt_boolean(v)
+	default:
+		p.badVerb(verb)
+	}
+}
+
+// fmtC formats a rune for the 'c' format.
+func (p *pp) fmtC(c int64) {
+	r := rune(c) // Check for overflow.
+	if int64(r) != c {
+		r = utf8.RuneError
+	}
+	w := utf8.EncodeRune(p.runeBuf[0:utf8.UTFMax], r)
+	p.fmt.pad(p.runeBuf[0:w])
+}
+
+func (p *pp) fmtInt64(v int64, verb rune) {
+	switch verb {
+	case 'b':
+		p.fmt.integer(v, 2, signed, ldigits)
+	case 'c':
+		p.fmtC(v)
+	case 'd', 'v':
+		p.fmt.integer(v, 10, signed, ldigits)
+	case 'o':
+		p.fmt.integer(v, 8, signed, ldigits)
+	case 'q':
+		if 0 <= v && v <= utf8.MaxRune {
+			p.fmt.fmt_qc(v)
+		} else {
+			p.badVerb(verb)
+		}
+	case 'x':
+		p.fmt.integer(v, 16, signed, ldigits)
+	case 'U':
+		p.fmtUnicode(v)
+	case 'X':
+		p.fmt.integer(v, 16, signed, udigits)
+	default:
+		p.badVerb(verb)
+	}
+}
+
+// fmt0x64 formats a uint64 in hexadecimal and prefixes it with 0x or
+// not, as requested, by temporarily setting the sharp flag.
+func (p *pp) fmt0x64(v uint64, leading0x bool) {
+	sharp := p.fmt.sharp
+	p.fmt.sharp = leading0x
+	p.fmt.integer(int64(v), 16, unsigned, ldigits)
+	p.fmt.sharp = sharp
+}
+
+// fmtUnicode formats a uint64 in U+1234 form by
+// temporarily turning on the unicode flag and tweaking the precision.
+func (p *pp) fmtUnicode(v int64) {
+	precPresent := p.fmt.precPresent
+	sharp := p.fmt.sharp
+	p.fmt.sharp = false
+	prec := p.fmt.prec
+	if !precPresent {
+		// If prec is already set, leave it alone; otherwise 4 is minimum.
+		p.fmt.prec = 4
+		p.fmt.precPresent = true
+	}
+	p.fmt.unicode = true // turn on U+
+	p.fmt.uniQuote = sharp
+	p.fmt.integer(int64(v), 16, unsigned, udigits)
+	p.fmt.unicode = false
+	p.fmt.uniQuote = false
+	p.fmt.prec = prec
+	p.fmt.precPresent = precPresent
+	p.fmt.sharp = sharp
+}
+
+func (p *pp) fmtUint64(v uint64, verb rune) {
+	switch verb {
+	case 'b':
+		p.fmt.integer(int64(v), 2, unsigned, ldigits)
+	case 'c':
+		p.fmtC(int64(v))
+	case 'd':
+		p.fmt.integer(int64(v), 10, unsigned, ldigits)
+	case 'v':
+		if p.fmt.sharpV {
+			p.fmt0x64(v, true)
+		} else {
+			p.fmt.integer(int64(v), 10, unsigned, ldigits)
+		}
+	case 'o':
+		p.fmt.integer(int64(v), 8, unsigned, ldigits)
+	case 'q':
+		if 0 <= v && v <= utf8.MaxRune {
+			p.fmt.fmt_qc(int64(v))
+		} else {
+			p.badVerb(verb)
+		}
+	case 'x':
+		p.fmt.integer(int64(v), 16, unsigned, ldigits)
+	case 'X':
+		p.fmt.integer(int64(v), 16, unsigned, udigits)
+	case 'U':
+		p.fmtUnicode(int64(v))
+	default:
+		p.badVerb(verb)
+	}
+}
+
+func (p *pp) fmtFloat32(v float32, verb rune) {
+	switch verb {
+	case 'b':
+		p.fmt.fmt_fb32(v)
+	case 'e':
+		p.fmt.fmt_e32(v)
+	case 'E':
+		p.fmt.fmt_E32(v)
+	case 'f', 'F':
+		p.fmt.fmt_f32(v)
+	case 'g', 'v':
+		p.fmt.fmt_g32(v)
+	case 'G':
+		p.fmt.fmt_G32(v)
+	default:
+		p.badVerb(verb)
+	}
+}
+
+func (p *pp) fmtFloat64(v float64, verb rune) {
+	switch verb {
+	case 'b':
+		p.fmt.fmt_fb64(v)
+	case 'e':
+		p.fmt.fmt_e64(v)
+	case 'E':
+		p.fmt.fmt_E64(v)
+	case 'f', 'F':
+		p.fmt.fmt_f64(v)
+	case 'g', 'v':
+		p.fmt.fmt_g64(v)
+	case 'G':
+		p.fmt.fmt_G64(v)
+	default:
+		p.badVerb(verb)
+	}
+}
+
+func (p *pp) fmtComplex64(v complex64, verb rune) {
+	switch verb {
+	case 'b', 'e', 'E', 'f', 'F', 'g', 'G':
+		p.fmt.fmt_c64(v, verb)
+	case 'v':
+		p.fmt.fmt_c64(v, 'g')
+	default:
+		p.badVerb(verb)
+	}
+}
+
+func (p *pp) fmtComplex128(v complex128, verb rune) {
+	switch verb {
+	case 'b', 'e', 'E', 'f', 'F', 'g', 'G':
+		p.fmt.fmt_c128(v, verb)
+	case 'v':
+		p.fmt.fmt_c128(v, 'g')
+	default:
+		p.badVerb(verb)
+	}
+}
+
+func (p *pp) fmtString(v string, verb rune) {
+	switch verb {
+	case 'v':
+		if p.fmt.sharpV {
+			p.fmt.fmt_q(v)
+		} else {
+			p.fmt.fmt_s(v)
+		}
+	case 's':
+		p.fmt.fmt_s(v)
+	case 'x':
+		p.fmt.fmt_sx(v, ldigits)
+	case 'X':
+		p.fmt.fmt_sx(v, udigits)
+	case 'q':
+		p.fmt.fmt_q(v)
+	default:
+		p.badVerb(verb)
+	}
+}
+
+func (p *pp) fmtBytes(v []byte, verb rune, typ reflect.Type, depth int) {
+	if verb == 'v' || verb == 'd' {
+		if p.fmt.sharpV {
+			if v == nil {
+				if typ == nil {
+					p.buf.WriteString("[]byte(nil)")
+				} else {
+					p.buf.WriteString(typ.String())
+					p.buf.Write(nilParenBytes)
+				}
+				return
+			}
+			if typ == nil {
+				p.buf.Write(bytesBytes)
+			} else {
+				p.buf.WriteString(typ.String())
+				p.buf.WriteByte('{')
+			}
+		} else {
+			p.buf.WriteByte('[')
+		}
+		for i, c := range v {
+			if i > 0 {
+				if p.fmt.sharpV {
+					p.buf.Write(commaSpaceBytes)
+				} else {
+					p.buf.WriteByte(' ')
+				}
+			}
+			p.printArg(c, 'v', depth+1)
+		}
+		if p.fmt.sharpV {
+			p.buf.WriteByte('}')
+		} else {
+			p.buf.WriteByte(']')
+		}
+		return
+	}
+	switch verb {
+	case 's':
+		p.fmt.fmt_s(string(v))
+	case 'x':
+		p.fmt.fmt_bx(v, ldigits)
+	case 'X':
+		p.fmt.fmt_bx(v, udigits)
+	case 'q':
+		p.fmt.fmt_q(string(v))
+	default:
+		p.badVerb(verb)
+	}
+}
+
+func (p *pp) fmtPointer(value reflect.Value, verb rune) {
+	use0x64 := true
+	switch verb {
+	case 'p', 'v':
+		// ok
+	case 'b', 'd', 'o', 'x', 'X':
+		use0x64 = false
+		// ok
+	default:
+		p.badVerb(verb)
+		return
+	}
+
+	var u uintptr
+	switch value.Kind() {
+	case reflect.Chan, reflect.Func, reflect.Map, reflect.Ptr, reflect.Slice, reflect.UnsafePointer:
+		u = value.Pointer()
+	default:
+		p.badVerb(verb)
+		return
+	}
+
+	if p.fmt.sharpV {
+		p.add('(')
+		p.buf.WriteString(value.Type().String())
+		p.add(')')
+		p.add('(')
+		if u == 0 {
+			p.buf.Write(nilBytes)
+		} else {
+			p.fmt0x64(uint64(u), true)
+		}
+		p.add(')')
+	} else if verb == 'v' && u == 0 {
+		p.buf.Write(nilAngleBytes)
+	} else {
+		if use0x64 {
+			p.fmt0x64(uint64(u), !p.fmt.sharp)
+		} else {
+			p.fmtUint64(uint64(u), verb)
+		}
+	}
+}
+
+var (
+	intBits     = reflect.TypeOf(0).Bits()
+	uintptrBits = reflect.TypeOf(uintptr(0)).Bits()
+)
+
+func (p *pp) catchPanic(arg interface{}, verb rune) {
+	if err := recover(); err != nil {
+		// If it's a nil pointer, just say "<nil>". The likeliest causes are a
+		// Stringer that fails to guard against nil or a nil pointer for a
+		// value receiver, and in either case, "<nil>" is a nice result.
+		if v := reflect.ValueOf(arg); v.Kind() == reflect.Ptr && v.IsNil() {
+			p.buf.Write(nilAngleBytes)
+			return
+		}
+		// Otherwise print a concise panic message. Most of the time the panic
+		// value will print itself nicely.
+		if p.panicking {
+			// Nested panics; the recursion in printArg cannot succeed.
+			panic(err)
+		}
+		p.fmt.clearflags() // We are done, and for this output we want default behavior.
+		p.buf.Write(percentBangBytes)
+		p.add(verb)
+		p.buf.Write(panicBytes)
+		p.panicking = true
+		p.printArg(err, 'v', 0)
+		p.panicking = false
+		p.buf.WriteByte(')')
+	}
+}
+
+// clearSpecialFlags pushes %#v back into the regular flags and returns their old state.
+func (p *pp) clearSpecialFlags() (plusV, sharpV bool) {
+	plusV = p.fmt.plusV
+	if plusV {
+		p.fmt.plus = true
+		p.fmt.plusV = false
+	}
+	sharpV = p.fmt.sharpV
+	if sharpV {
+		p.fmt.sharp = true
+		p.fmt.sharpV = false
+	}
+	return
+}
+
+// restoreSpecialFlags, whose argument should be a call to clearSpecialFlags,
+// restores the setting of the plusV and sharpV flags.
+func (p *pp) restoreSpecialFlags(plusV, sharpV bool) {
+	if plusV {
+		p.fmt.plus = false
+		p.fmt.plusV = true
+	}
+	if sharpV {
+		p.fmt.sharp = false
+		p.fmt.sharpV = true
+	}
+}
+
+func (p *pp) handleMethods(verb rune, depth int) (handled bool) {
+	if p.erroring {
+		return
+	}
+	// Is it a Formatter?
+	if formatter, ok := p.arg.(Formatter); ok {
+		handled = true
+		defer p.restoreSpecialFlags(p.clearSpecialFlags())
+		defer p.catchPanic(p.arg, verb)
+		formatter.Format(p, verb)
+		return
+	}
+
+	// If we're doing Go syntax and the argument knows how to supply it, take care of it now.
+	if p.fmt.sharpV {
+		if stringer, ok := p.arg.(GoStringer); ok {
+			handled = true
+			defer p.catchPanic(p.arg, verb)
+			// Print the result of GoString unadorned.
+			p.fmt.fmt_s(stringer.GoString())
+			return
+		}
+	} else {
+		// If a string is acceptable according to the format, see if
+		// the value satisfies one of the string-valued interfaces.
+		// Println etc. set verb to %v, which is "stringable".
+		switch verb {
+		case 'v', 's', 'x', 'X', 'q':
+			// Is it an error or Stringer?
+			// The duplication in the bodies is necessary:
+			// setting handled and deferring catchPanic
+			// must happen before calling the method.
+			switch v := p.arg.(type) {
+			case error:
+				handled = true
+				defer p.catchPanic(p.arg, verb)
+				p.printArg(v.Error(), verb, depth)
+				return
+
+			case Stringer:
+				handled = true
+				defer p.catchPanic(p.arg, verb)
+				p.printArg(v.String(), verb, depth)
+				return
+			}
+		}
+	}
+	return false
+}
+
+func (p *pp) printArg(arg interface{}, verb rune, depth int) (wasString bool) {
+	p.arg = arg
+	p.value = reflect.Value{}
+
+	if arg == nil {
+		if verb == 'T' || verb == 'v' {
+			p.fmt.pad(nilAngleBytes)
+		} else {
+			p.badVerb(verb)
+		}
+		return false
+	}
+
+	// Special processing considerations.
+	// %T (the value's type) and %p (its address) are special; we always do them first.
+	switch verb {
+	case 'T':
+		p.printArg(reflect.TypeOf(arg).String(), 's', 0)
+		return false
+	case 'p':
+		p.fmtPointer(reflect.ValueOf(arg), verb)
+		return false
+	}
+
+	// Some types can be done without reflection.
+	switch f := arg.(type) {
+	case bool:
+		p.fmtBool(f, verb)
+	case float32:
+		p.fmtFloat32(f, verb)
+	case float64:
+		p.fmtFloat64(f, verb)
+	case complex64:
+		p.fmtComplex64(f, verb)
+	case complex128:
+		p.fmtComplex128(f, verb)
+	case int:
+		p.fmtInt64(int64(f), verb)
+	case int8:
+		p.fmtInt64(int64(f), verb)
+	case int16:
+		p.fmtInt64(int64(f), verb)
+	case int32:
+		p.fmtInt64(int64(f), verb)
+	case int64:
+		p.fmtInt64(f, verb)
+	case uint:
+		p.fmtUint64(uint64(f), verb)
+	case uint8:
+		p.fmtUint64(uint64(f), verb)
+	case uint16:
+		p.fmtUint64(uint64(f), verb)
+	case uint32:
+		p.fmtUint64(uint64(f), verb)
+	case uint64:
+		p.fmtUint64(f, verb)
+	case uintptr:
+		p.fmtUint64(uint64(f), verb)
+	case string:
+		p.fmtString(f, verb)
+		wasString = verb == 's' || verb == 'v'
+	case []byte:
+		p.fmtBytes(f, verb, nil, depth)
+		wasString = verb == 's'
+	default:
+		// If the type is not simple, it might have methods.
+		if handled := p.handleMethods(verb, depth); handled {
+			return false
+		}
+		// Need to use reflection
+		return p.printReflectValue(reflect.ValueOf(arg), verb, depth)
+	}
+	p.arg = nil
+	return
+}
+
+// printValue is like printArg but starts with a reflect value, not an interface{} value.
+func (p *pp) printValue(value reflect.Value, verb rune, depth int) (wasString bool) {
+	if !value.IsValid() {
+		if verb == 'T' || verb == 'v' {
+			p.buf.Write(nilAngleBytes)
+		} else {
+			p.badVerb(verb)
+		}
+		return false
+	}
+
+	// Special processing considerations.
+	// %T (the value's type) and %p (its address) are special; we always do them first.
+	switch verb {
+	case 'T':
+		p.printArg(value.Type().String(), 's', 0)
+		return false
+	case 'p':
+		p.fmtPointer(value, verb)
+		return false
+	}
+
+	// Handle values with special methods.
+	// Call always, even when arg == nil, because handleMethods clears p.fmt.plus for us.
+	p.arg = nil // Make sure it's cleared, for safety.
+	if value.CanInterface() {
+		p.arg = value.Interface()
+	}
+	if handled := p.handleMethods(verb, depth); handled {
+		return false
+	}
+
+	return p.printReflectValue(value, verb, depth)
+}
+
+var byteType = reflect.TypeOf(byte(0))
+
+// printReflectValue is the fallback for both printArg and printValue.
+// It uses reflect to print the value.
+func (p *pp) printReflectValue(value reflect.Value, verb rune, depth int) (wasString bool) {
+	oldValue := p.value
+	p.value = value
+BigSwitch:
+	switch f := value; f.Kind() {
+	case reflect.Bool:
+		p.fmtBool(f.Bool(), verb)
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		p.fmtInt64(f.Int(), verb)
+	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+		p.fmtUint64(f.Uint(), verb)
+	case reflect.Float32, reflect.Float64:
+		if f.Type().Size() == 4 {
+			p.fmtFloat32(float32(f.Float()), verb)
+		} else {
+			p.fmtFloat64(f.Float(), verb)
+		}
+	case reflect.Complex64, reflect.Complex128:
+		if f.Type().Size() == 8 {
+			p.fmtComplex64(complex64(f.Complex()), verb)
+		} else {
+			p.fmtComplex128(f.Complex(), verb)
+		}
+	case reflect.String:
+		p.fmtString(f.String(), verb)
+	case reflect.Map:
+		if p.fmt.sharpV {
+			p.buf.WriteString(f.Type().String())
+			if f.IsNil() {
+				p.buf.WriteString("(nil)")
+				break
+			}
+			p.buf.WriteByte('{')
+		} else {
+			p.buf.Write(mapBytes)
+		}
+		keys := f.MapKeys()
+		for i, key := range keys {
+			if i > 0 {
+				if p.fmt.sharpV {
+					p.buf.Write(commaSpaceBytes)
+				} else {
+					p.buf.WriteByte(' ')
+				}
+			}
+			p.printValue(key, verb, depth+1)
+			p.buf.WriteByte(':')
+			p.printValue(f.MapIndex(key), verb, depth+1)
+		}
+		if p.fmt.sharpV {
+			p.buf.WriteByte('}')
+		} else {
+			p.buf.WriteByte(']')
+		}
+	case reflect.Struct:
+		if p.fmt.sharpV {
+			p.buf.WriteString(value.Type().String())
+		}
+		p.add('{')
+		v := f
+		t := v.Type()
+		for i := 0; i < v.NumField(); i++ {
+			if i > 0 {
+				if p.fmt.sharpV {
+					p.buf.Write(commaSpaceBytes)
+				} else {
+					p.buf.WriteByte(' ')
+				}
+			}
+			if p.fmt.plusV || p.fmt.sharpV {
+				if f := t.Field(i); f.Name != "" {
+					p.buf.WriteString(f.Name)
+					p.buf.WriteByte(':')
+				}
+			}
+			p.printValue(getField(v, i), verb, depth+1)
+		}
+		p.buf.WriteByte('}')
+	case reflect.Interface:
+		value := f.Elem()
+		if !value.IsValid() {
+			if p.fmt.sharpV {
+				p.buf.WriteString(f.Type().String())
+				p.buf.Write(nilParenBytes)
+			} else {
+				p.buf.Write(nilAngleBytes)
+			}
+		} else {
+			wasString = p.printValue(value, verb, depth+1)
+		}
+	case reflect.Array, reflect.Slice:
+		// Byte slices are special:
+		// - Handle []byte (== []uint8) with fmtBytes.
+		// - Handle []T, where T is a named byte type, with fmtBytes only
+		//   for the s, q, an x verbs. For other verbs, T might be a
+		//   Stringer, so we use printValue to print each element.
+		if typ := f.Type(); typ.Elem().Kind() == reflect.Uint8 && (typ.Elem() == byteType || verb == 's' || verb == 'q' || verb == 'x') {
+			var bytes []byte
+			if f.Kind() == reflect.Slice {
+				bytes = f.Bytes()
+			} else if f.CanAddr() {
+				bytes = f.Slice(0, f.Len()).Bytes()
+			} else {
+				// We have an array, but we cannot Slice() a non-addressable array,
+				// so we build a slice by hand. This is a rare case but it would be nice
+				// if reflection could help a little more.
+				bytes = make([]byte, f.Len())
+				for i := range bytes {
+					bytes[i] = byte(f.Index(i).Uint())
+				}
+			}
+			p.fmtBytes(bytes, verb, typ, depth)
+			wasString = verb == 's'
+			break
+		}
+		if p.fmt.sharpV {
+			p.buf.WriteString(value.Type().String())
+			if f.Kind() == reflect.Slice && f.IsNil() {
+				p.buf.WriteString("(nil)")
+				break
+			}
+			p.buf.WriteByte('{')
+		} else {
+			p.buf.WriteByte('[')
+		}
+		for i := 0; i < f.Len(); i++ {
+			if i > 0 {
+				if p.fmt.sharpV {
+					p.buf.Write(commaSpaceBytes)
+				} else {
+					p.buf.WriteByte(' ')
+				}
+			}
+			p.printValue(f.Index(i), verb, depth+1)
+		}
+		if p.fmt.sharpV {
+			p.buf.WriteByte('}')
+		} else {
+			p.buf.WriteByte(']')
+		}
+	case reflect.Ptr:
+		v := f.Pointer()
+		// pointer to array or slice or struct?  ok at top level
+		// but not embedded (avoid loops)
+		if v != 0 && depth == 0 {
+			switch a := f.Elem(); a.Kind() {
+			case reflect.Array, reflect.Slice:
+				p.buf.WriteByte('&')
+				p.printValue(a, verb, depth+1)
+				break BigSwitch
+			case reflect.Struct:
+				p.buf.WriteByte('&')
+				p.printValue(a, verb, depth+1)
+				break BigSwitch
+			case reflect.Map:
+				p.buf.WriteByte('&')
+				p.printValue(a, verb, depth+1)
+				break BigSwitch
+			}
+		}
+		fallthrough
+	case reflect.Chan, reflect.Func, reflect.UnsafePointer:
+		p.fmtPointer(value, verb)
+	default:
+		p.unknownType(f)
+	}
+	p.value = oldValue
+	return wasString
+}
+
+// intFromArg gets the argNumth element of a. On return, isInt reports whether the argument has type int.
+func intFromArg(a []interface{}, argNum int) (num int, isInt bool, newArgNum int) {
+	newArgNum = argNum
+	if argNum < len(a) {
+		num, isInt = a[argNum].(int)
+		newArgNum = argNum + 1
+	}
+	return
+}
+
+// parseArgNumber returns the value of the bracketed number, minus 1
+// (explicit argument numbers are one-indexed but we want zero-indexed).
+// The opening bracket is known to be present at format[0].
+// The returned values are the index, the number of bytes to consume
+// up to the closing paren, if present, and whether the number parsed
+// ok. The bytes to consume will be 1 if no closing paren is present.
+func parseArgNumber(format string) (index int, wid int, ok bool) {
+	// Find closing bracket.
+	for i := 1; i < len(format); i++ {
+		if format[i] == ']' {
+			width, ok, newi := parsenum(format, 1, i)
+			if !ok || newi != i {
+				return 0, i + 1, false
+			}
+			return width - 1, i + 1, true // arg numbers are one-indexed and skip paren.
+		}
+	}
+	return 0, 1, false
+}
+
+// argNumber returns the next argument to evaluate, which is either the value of the passed-in
+// argNum or the value of the bracketed integer that begins format[i:]. It also returns
+// the new value of i, that is, the index of the next byte of the format to process.
+func (p *pp) argNumber(argNum int, format string, i int, numArgs int) (newArgNum, newi int, found bool) {
+	if len(format) <= i || format[i] != '[' {
+		return argNum, i, false
+	}
+	p.reordered = true
+	index, wid, ok := parseArgNumber(format[i:])
+	if ok && 0 <= index && index < numArgs {
+		return index, i + wid, true
+	}
+	p.goodArgNum = false
+	return argNum, i + wid, true
+}
+
+func (p *pp) doPrintf(format string, a []interface{}) {
+	end := len(format)
+	argNum := 0         // we process one argument per non-trivial format
+	afterIndex := false // previous item in format was an index like [3].
+	p.reordered = false
+	for i := 0; i < end; {
+		p.goodArgNum = true
+		lasti := i
+		for i < end && format[i] != '%' {
+			i++
+		}
+		if i > lasti {
+			p.buf.WriteString(format[lasti:i])
+		}
+		if i >= end {
+			// done processing format string
+			break
+		}
+
+		// Process one verb
+		i++
+
+		// Do we have flags?
+		p.fmt.clearflags()
+	F:
+		for ; i < end; i++ {
+			switch format[i] {
+			case '#':
+				p.fmt.sharp = true
+			case '0':
+				p.fmt.zero = true
+			case '+':
+				p.fmt.plus = true
+			case '-':
+				p.fmt.minus = true
+			case ' ':
+				p.fmt.space = true
+			default:
+				break F
+			}
+		}
+
+		// Do we have an explicit argument index?
+		argNum, i, afterIndex = p.argNumber(argNum, format, i, len(a))
+
+		// Do we have width?
+		if i < end && format[i] == '*' {
+			i++
+			p.fmt.wid, p.fmt.widPresent, argNum = intFromArg(a, argNum)
+			if !p.fmt.widPresent {
+				p.buf.Write(badWidthBytes)
+			}
+			afterIndex = false
+		} else {
+			p.fmt.wid, p.fmt.widPresent, i = parsenum(format, i, end)
+			if afterIndex && p.fmt.widPresent { // "%[3]2d"
+				p.goodArgNum = false
+			}
+		}
+
+		// Do we have precision?
+		if i+1 < end && format[i] == '.' {
+			i++
+			if afterIndex { // "%[3].2d"
+				p.goodArgNum = false
+			}
+			argNum, i, afterIndex = p.argNumber(argNum, format, i, len(a))
+			if format[i] == '*' {
+				i++
+				p.fmt.prec, p.fmt.precPresent, argNum = intFromArg(a, argNum)
+				if !p.fmt.precPresent {
+					p.buf.Write(badPrecBytes)
+				}
+				afterIndex = false
+			} else {
+				p.fmt.prec, p.fmt.precPresent, i = parsenum(format, i, end)
+				if !p.fmt.precPresent {
+					p.fmt.prec = 0
+					p.fmt.precPresent = true
+				}
+			}
+		}
+
+		if !afterIndex {
+			argNum, i, afterIndex = p.argNumber(argNum, format, i, len(a))
+		}
+
+		if i >= end {
+			p.buf.Write(noVerbBytes)
+			continue
+		}
+		c, w := utf8.DecodeRuneInString(format[i:])
+		i += w
+		// percent is special - absorbs no operand
+		if c == '%' {
+			p.buf.WriteByte('%') // We ignore width and prec.
+			continue
+		}
+		if !p.goodArgNum {
+			p.buf.Write(percentBangBytes)
+			p.add(c)
+			p.buf.Write(badIndexBytes)
+			continue
+		} else if argNum >= len(a) { // out of operands
+			p.buf.Write(percentBangBytes)
+			p.add(c)
+			p.buf.Write(missingBytes)
+			continue
+		}
+		arg := a[argNum]
+		argNum++
+
+		if c == 'v' {
+			if p.fmt.sharp {
+				// Go syntax. Set the flag in the fmt and clear the sharp flag.
+				p.fmt.sharp = false
+				p.fmt.sharpV = true
+			}
+			if p.fmt.plus {
+				// Struct-field syntax. Set the flag in the fmt and clear the plus flag.
+				p.fmt.plus = false
+				p.fmt.plusV = true
+			}
+		}
+		p.printArg(arg, c, 0)
+	}
+
+	// Check for extra arguments unless the call accessed the arguments
+	// out of order, in which case it's too expensive to detect if they've all
+	// been used and arguably OK if they're not.
+	if !p.reordered && argNum < len(a) {
+		p.buf.Write(extraBytes)
+		for ; argNum < len(a); argNum++ {
+			arg := a[argNum]
+			if arg != nil {
+				p.buf.WriteString(reflect.TypeOf(arg).String())
+				p.buf.WriteByte('=')
+			}
+			p.printArg(arg, 'v', 0)
+			if argNum+1 < len(a) {
+				p.buf.Write(commaSpaceBytes)
+			}
+		}
+		p.buf.WriteByte(')')
+	}
+}
+
+func (p *pp) doPrint(a []interface{}, addspace, addnewline bool) {
+	prevString := false
+	for argNum := 0; argNum < len(a); argNum++ {
+		p.fmt.clearflags()
+		// always add spaces if we're doing Println
+		arg := a[argNum]
+		if argNum > 0 {
+			isString := arg != nil && reflect.TypeOf(arg).Kind() == reflect.String
+			if addspace || !isString && !prevString {
+				p.buf.WriteByte(' ')
+			}
+		}
+		prevString = p.printArg(arg, 'v', 0)
+	}
+	if addnewline {
+		p.buf.WriteByte('\n')
+	}
+}
diff --git a/src/fmt/scan.go b/src/fmt/scan.go
new file mode 100644
index 0000000..d7befea
--- /dev/null
+++ b/src/fmt/scan.go
@@ -0,0 +1,1169 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package fmt
+
+import (
+	"errors"
+	"io"
+	"math"
+	"os"
+	"reflect"
+	"strconv"
+	"sync"
+	"unicode/utf8"
+)
+
+// runeUnreader is the interface to something that can unread runes.
+// If the object provided to Scan does not satisfy this interface,
+// a local buffer will be used to back up the input, but its contents
+// will be lost when Scan returns.
+type runeUnreader interface {
+	UnreadRune() error
+}
+
+// ScanState represents the scanner state passed to custom scanners.
+// Scanners may do rune-at-a-time scanning or ask the ScanState
+// to discover the next space-delimited token.
+type ScanState interface {
+	// ReadRune reads the next rune (Unicode code point) from the input.
+	// If invoked during Scanln, Fscanln, or Sscanln, ReadRune() will
+	// return EOF after returning the first '\n' or when reading beyond
+	// the specified width.
+	ReadRune() (r rune, size int, err error)
+	// UnreadRune causes the next call to ReadRune to return the same rune.
+	UnreadRune() error
+	// SkipSpace skips space in the input. Newlines are treated as space
+	// unless the scan operation is Scanln, Fscanln or Sscanln, in which case
+	// a newline is treated as EOF.
+	SkipSpace()
+	// Token skips space in the input if skipSpace is true, then returns the
+	// run of Unicode code points c satisfying f(c).  If f is nil,
+	// !unicode.IsSpace(c) is used; that is, the token will hold non-space
+	// characters.  Newlines are treated as space unless the scan operation
+	// is Scanln, Fscanln or Sscanln, in which case a newline is treated as
+	// EOF.  The returned slice points to shared data that may be overwritten
+	// by the next call to Token, a call to a Scan function using the ScanState
+	// as input, or when the calling Scan method returns.
+	Token(skipSpace bool, f func(rune) bool) (token []byte, err error)
+	// Width returns the value of the width option and whether it has been set.
+	// The unit is Unicode code points.
+	Width() (wid int, ok bool)
+	// Because ReadRune is implemented by the interface, Read should never be
+	// called by the scanning routines and a valid implementation of
+	// ScanState may choose always to return an error from Read.
+	Read(buf []byte) (n int, err error)
+}
+
+// Scanner is implemented by any value that has a Scan method, which scans
+// the input for the representation of a value and stores the result in the
+// receiver, which must be a pointer to be useful.  The Scan method is called
+// for any argument to Scan, Scanf, or Scanln that implements it.
+type Scanner interface {
+	Scan(state ScanState, verb rune) error
+}
+
+// Scan scans text read from standard input, storing successive
+// space-separated values into successive arguments.  Newlines count
+// as space.  It returns the number of items successfully scanned.
+// If that is less than the number of arguments, err will report why.
+func Scan(a ...interface{}) (n int, err error) {
+	return Fscan(os.Stdin, a...)
+}
+
+// Scanln is similar to Scan, but stops scanning at a newline and
+// after the final item there must be a newline or EOF.
+func Scanln(a ...interface{}) (n int, err error) {
+	return Fscanln(os.Stdin, a...)
+}
+
+// Scanf scans text read from standard input, storing successive
+// space-separated values into successive arguments as determined by
+// the format.  It returns the number of items successfully scanned.
+func Scanf(format string, a ...interface{}) (n int, err error) {
+	return Fscanf(os.Stdin, format, a...)
+}
+
+type stringReader string
+
+func (r *stringReader) Read(b []byte) (n int, err error) {
+	n = copy(b, *r)
+	*r = (*r)[n:]
+	if n == 0 {
+		err = io.EOF
+	}
+	return
+}
+
+// Sscan scans the argument string, storing successive space-separated
+// values into successive arguments.  Newlines count as space.  It
+// returns the number of items successfully scanned.  If that is less
+// than the number of arguments, err will report why.
+func Sscan(str string, a ...interface{}) (n int, err error) {
+	return Fscan((*stringReader)(&str), a...)
+}
+
+// Sscanln is similar to Sscan, but stops scanning at a newline and
+// after the final item there must be a newline or EOF.
+func Sscanln(str string, a ...interface{}) (n int, err error) {
+	return Fscanln((*stringReader)(&str), a...)
+}
+
+// Sscanf scans the argument string, storing successive space-separated
+// values into successive arguments as determined by the format.  It
+// returns the number of items successfully parsed.
+func Sscanf(str string, format string, a ...interface{}) (n int, err error) {
+	return Fscanf((*stringReader)(&str), format, a...)
+}
+
+// Fscan scans text read from r, storing successive space-separated
+// values into successive arguments.  Newlines count as space.  It
+// returns the number of items successfully scanned.  If that is less
+// than the number of arguments, err will report why.
+func Fscan(r io.Reader, a ...interface{}) (n int, err error) {
+	s, old := newScanState(r, true, false)
+	n, err = s.doScan(a)
+	s.free(old)
+	return
+}
+
+// Fscanln is similar to Fscan, but stops scanning at a newline and
+// after the final item there must be a newline or EOF.
+func Fscanln(r io.Reader, a ...interface{}) (n int, err error) {
+	s, old := newScanState(r, false, true)
+	n, err = s.doScan(a)
+	s.free(old)
+	return
+}
+
+// Fscanf scans text read from r, storing successive space-separated
+// values into successive arguments as determined by the format.  It
+// returns the number of items successfully parsed.
+func Fscanf(r io.Reader, format string, a ...interface{}) (n int, err error) {
+	s, old := newScanState(r, false, false)
+	n, err = s.doScanf(format, a)
+	s.free(old)
+	return
+}
+
+// scanError represents an error generated by the scanning software.
+// It's used as a unique signature to identify such errors when recovering.
+type scanError struct {
+	err error
+}
+
+const eof = -1
+
+// ss is the internal implementation of ScanState.
+type ss struct {
+	rr       io.RuneReader // where to read input
+	buf      buffer        // token accumulator
+	peekRune rune          // one-rune lookahead
+	prevRune rune          // last rune returned by ReadRune
+	count    int           // runes consumed so far.
+	atEOF    bool          // already read EOF
+	ssave
+}
+
+// ssave holds the parts of ss that need to be
+// saved and restored on recursive scans.
+type ssave struct {
+	validSave bool // is or was a part of an actual ss.
+	nlIsEnd   bool // whether newline terminates scan
+	nlIsSpace bool // whether newline counts as white space
+	argLimit  int  // max value of ss.count for this arg; argLimit <= limit
+	limit     int  // max value of ss.count.
+	maxWid    int  // width of this arg.
+}
+
+// The Read method is only in ScanState so that ScanState
+// satisfies io.Reader. It will never be called when used as
+// intended, so there is no need to make it actually work.
+func (s *ss) Read(buf []byte) (n int, err error) {
+	return 0, errors.New("ScanState's Read should not be called. Use ReadRune")
+}
+
+func (s *ss) ReadRune() (r rune, size int, err error) {
+	if s.peekRune >= 0 {
+		s.count++
+		r = s.peekRune
+		size = utf8.RuneLen(r)
+		s.prevRune = r
+		s.peekRune = -1
+		return
+	}
+	if s.atEOF || s.nlIsEnd && s.prevRune == '\n' || s.count >= s.argLimit {
+		err = io.EOF
+		return
+	}
+
+	r, size, err = s.rr.ReadRune()
+	if err == nil {
+		s.count++
+		s.prevRune = r
+	} else if err == io.EOF {
+		s.atEOF = true
+	}
+	return
+}
+
+func (s *ss) Width() (wid int, ok bool) {
+	if s.maxWid == hugeWid {
+		return 0, false
+	}
+	return s.maxWid, true
+}
+
+// The public method returns an error; this private one panics.
+// If getRune reaches EOF, the return value is EOF (-1).
+func (s *ss) getRune() (r rune) {
+	r, _, err := s.ReadRune()
+	if err != nil {
+		if err == io.EOF {
+			return eof
+		}
+		s.error(err)
+	}
+	return
+}
+
+// mustReadRune turns io.EOF into a panic(io.ErrUnexpectedEOF).
+// It is called in cases such as string scanning where an EOF is a
+// syntax error.
+func (s *ss) mustReadRune() (r rune) {
+	r = s.getRune()
+	if r == eof {
+		s.error(io.ErrUnexpectedEOF)
+	}
+	return
+}
+
+func (s *ss) UnreadRune() error {
+	if u, ok := s.rr.(runeUnreader); ok {
+		u.UnreadRune()
+	} else {
+		s.peekRune = s.prevRune
+	}
+	s.prevRune = -1
+	s.count--
+	return nil
+}
+
+func (s *ss) error(err error) {
+	panic(scanError{err})
+}
+
+func (s *ss) errorString(err string) {
+	panic(scanError{errors.New(err)})
+}
+
+func (s *ss) Token(skipSpace bool, f func(rune) bool) (tok []byte, err error) {
+	defer func() {
+		if e := recover(); e != nil {
+			if se, ok := e.(scanError); ok {
+				err = se.err
+			} else {
+				panic(e)
+			}
+		}
+	}()
+	if f == nil {
+		f = notSpace
+	}
+	s.buf = s.buf[:0]
+	tok = s.token(skipSpace, f)
+	return
+}
+
+// space is a copy of the unicode.White_Space ranges,
+// to avoid depending on package unicode.
+var space = [][2]uint16{
+	{0x0009, 0x000d},
+	{0x0020, 0x0020},
+	{0x0085, 0x0085},
+	{0x00a0, 0x00a0},
+	{0x1680, 0x1680},
+	{0x2000, 0x200a},
+	{0x2028, 0x2029},
+	{0x202f, 0x202f},
+	{0x205f, 0x205f},
+	{0x3000, 0x3000},
+}
+
+func isSpace(r rune) bool {
+	if r >= 1<<16 {
+		return false
+	}
+	rx := uint16(r)
+	for _, rng := range space {
+		if rx < rng[0] {
+			return false
+		}
+		if rx <= rng[1] {
+			return true
+		}
+	}
+	return false
+}
+
+// notSpace is the default scanning function used in Token.
+func notSpace(r rune) bool {
+	return !isSpace(r)
+}
+
+// SkipSpace provides Scan methods the ability to skip space and newline
+// characters in keeping with the current scanning mode set by format strings
+// and Scan/Scanln.
+func (s *ss) SkipSpace() {
+	s.skipSpace(false)
+}
+
+// readRune is a structure to enable reading UTF-8 encoded code points
+// from an io.Reader.  It is used if the Reader given to the scanner does
+// not already implement io.RuneReader.
+type readRune struct {
+	reader  io.Reader
+	buf     [utf8.UTFMax]byte // used only inside ReadRune
+	pending int               // number of bytes in pendBuf; only >0 for bad UTF-8
+	pendBuf [utf8.UTFMax]byte // bytes left over
+}
+
+// readByte returns the next byte from the input, which may be
+// left over from a previous read if the UTF-8 was ill-formed.
+func (r *readRune) readByte() (b byte, err error) {
+	if r.pending > 0 {
+		b = r.pendBuf[0]
+		copy(r.pendBuf[0:], r.pendBuf[1:])
+		r.pending--
+		return
+	}
+	n, err := io.ReadFull(r.reader, r.pendBuf[0:1])
+	if n != 1 {
+		return 0, err
+	}
+	return r.pendBuf[0], err
+}
+
+// unread saves the bytes for the next read.
+func (r *readRune) unread(buf []byte) {
+	copy(r.pendBuf[r.pending:], buf)
+	r.pending += len(buf)
+}
+
+// ReadRune returns the next UTF-8 encoded code point from the
+// io.Reader inside r.
+func (r *readRune) ReadRune() (rr rune, size int, err error) {
+	r.buf[0], err = r.readByte()
+	if err != nil {
+		return 0, 0, err
+	}
+	if r.buf[0] < utf8.RuneSelf { // fast check for common ASCII case
+		rr = rune(r.buf[0])
+		size = 1 // Known to be 1.
+		return
+	}
+	var n int
+	for n = 1; !utf8.FullRune(r.buf[0:n]); n++ {
+		r.buf[n], err = r.readByte()
+		if err != nil {
+			if err == io.EOF {
+				err = nil
+				break
+			}
+			return
+		}
+	}
+	rr, size = utf8.DecodeRune(r.buf[0:n])
+	if size < n { // an error
+		r.unread(r.buf[size:n])
+	}
+	return
+}
+
+var ssFree = sync.Pool{
+	New: func() interface{} { return new(ss) },
+}
+
+// newScanState allocates a new ss struct or grab a cached one.
+func newScanState(r io.Reader, nlIsSpace, nlIsEnd bool) (s *ss, old ssave) {
+	// If the reader is a *ss, then we've got a recursive
+	// call to Scan, so re-use the scan state.
+	s, ok := r.(*ss)
+	if ok {
+		old = s.ssave
+		s.limit = s.argLimit
+		s.nlIsEnd = nlIsEnd || s.nlIsEnd
+		s.nlIsSpace = nlIsSpace
+		return
+	}
+
+	s = ssFree.Get().(*ss)
+	if rr, ok := r.(io.RuneReader); ok {
+		s.rr = rr
+	} else {
+		s.rr = &readRune{reader: r}
+	}
+	s.nlIsSpace = nlIsSpace
+	s.nlIsEnd = nlIsEnd
+	s.prevRune = -1
+	s.peekRune = -1
+	s.atEOF = false
+	s.limit = hugeWid
+	s.argLimit = hugeWid
+	s.maxWid = hugeWid
+	s.validSave = true
+	s.count = 0
+	return
+}
+
+// free saves used ss structs in ssFree; avoid an allocation per invocation.
+func (s *ss) free(old ssave) {
+	// If it was used recursively, just restore the old state.
+	if old.validSave {
+		s.ssave = old
+		return
+	}
+	// Don't hold on to ss structs with large buffers.
+	if cap(s.buf) > 1024 {
+		return
+	}
+	s.buf = s.buf[:0]
+	s.rr = nil
+	ssFree.Put(s)
+}
+
+// skipSpace skips spaces and maybe newlines.
+func (s *ss) skipSpace(stopAtNewline bool) {
+	for {
+		r := s.getRune()
+		if r == eof {
+			return
+		}
+		if r == '\r' && s.peek("\n") {
+			continue
+		}
+		if r == '\n' {
+			if stopAtNewline {
+				break
+			}
+			if s.nlIsSpace {
+				continue
+			}
+			s.errorString("unexpected newline")
+			return
+		}
+		if !isSpace(r) {
+			s.UnreadRune()
+			break
+		}
+	}
+}
+
+// token returns the next space-delimited string from the input.  It
+// skips white space.  For Scanln, it stops at newlines.  For Scan,
+// newlines are treated as spaces.
+func (s *ss) token(skipSpace bool, f func(rune) bool) []byte {
+	if skipSpace {
+		s.skipSpace(false)
+	}
+	// read until white space or newline
+	for {
+		r := s.getRune()
+		if r == eof {
+			break
+		}
+		if !f(r) {
+			s.UnreadRune()
+			break
+		}
+		s.buf.WriteRune(r)
+	}
+	return s.buf
+}
+
+var complexError = errors.New("syntax error scanning complex number")
+var boolError = errors.New("syntax error scanning boolean")
+
+func indexRune(s string, r rune) int {
+	for i, c := range s {
+		if c == r {
+			return i
+		}
+	}
+	return -1
+}
+
+// consume reads the next rune in the input and reports whether it is in the ok string.
+// If accept is true, it puts the character into the input token.
+func (s *ss) consume(ok string, accept bool) bool {
+	r := s.getRune()
+	if r == eof {
+		return false
+	}
+	if indexRune(ok, r) >= 0 {
+		if accept {
+			s.buf.WriteRune(r)
+		}
+		return true
+	}
+	if r != eof && accept {
+		s.UnreadRune()
+	}
+	return false
+}
+
+// peek reports whether the next character is in the ok string, without consuming it.
+func (s *ss) peek(ok string) bool {
+	r := s.getRune()
+	if r != eof {
+		s.UnreadRune()
+	}
+	return indexRune(ok, r) >= 0
+}
+
+func (s *ss) notEOF() {
+	// Guarantee there is data to be read.
+	if r := s.getRune(); r == eof {
+		panic(io.EOF)
+	}
+	s.UnreadRune()
+}
+
+// accept checks the next rune in the input.  If it's a byte (sic) in the string, it puts it in the
+// buffer and returns true. Otherwise it return false.
+func (s *ss) accept(ok string) bool {
+	return s.consume(ok, true)
+}
+
+// okVerb verifies that the verb is present in the list, setting s.err appropriately if not.
+func (s *ss) okVerb(verb rune, okVerbs, typ string) bool {
+	for _, v := range okVerbs {
+		if v == verb {
+			return true
+		}
+	}
+	s.errorString("bad verb %" + string(verb) + " for " + typ)
+	return false
+}
+
+// scanBool returns the value of the boolean represented by the next token.
+func (s *ss) scanBool(verb rune) bool {
+	s.skipSpace(false)
+	s.notEOF()
+	if !s.okVerb(verb, "tv", "boolean") {
+		return false
+	}
+	// Syntax-checking a boolean is annoying.  We're not fastidious about case.
+	switch s.getRune() {
+	case '0':
+		return false
+	case '1':
+		return true
+	case 't', 'T':
+		if s.accept("rR") && (!s.accept("uU") || !s.accept("eE")) {
+			s.error(boolError)
+		}
+		return true
+	case 'f', 'F':
+		if s.accept("aA") && (!s.accept("lL") || !s.accept("sS") || !s.accept("eE")) {
+			s.error(boolError)
+		}
+		return false
+	}
+	return false
+}
+
+// Numerical elements
+const (
+	binaryDigits      = "01"
+	octalDigits       = "01234567"
+	decimalDigits     = "0123456789"
+	hexadecimalDigits = "0123456789aAbBcCdDeEfF"
+	sign              = "+-"
+	period            = "."
+	exponent          = "eEp"
+)
+
+// getBase returns the numeric base represented by the verb and its digit string.
+func (s *ss) getBase(verb rune) (base int, digits string) {
+	s.okVerb(verb, "bdoUxXv", "integer") // sets s.err
+	base = 10
+	digits = decimalDigits
+	switch verb {
+	case 'b':
+		base = 2
+		digits = binaryDigits
+	case 'o':
+		base = 8
+		digits = octalDigits
+	case 'x', 'X', 'U':
+		base = 16
+		digits = hexadecimalDigits
+	}
+	return
+}
+
+// scanNumber returns the numerical string with specified digits starting here.
+func (s *ss) scanNumber(digits string, haveDigits bool) string {
+	if !haveDigits {
+		s.notEOF()
+		if !s.accept(digits) {
+			s.errorString("expected integer")
+		}
+	}
+	for s.accept(digits) {
+	}
+	return string(s.buf)
+}
+
+// scanRune returns the next rune value in the input.
+func (s *ss) scanRune(bitSize int) int64 {
+	s.notEOF()
+	r := int64(s.getRune())
+	n := uint(bitSize)
+	x := (r << (64 - n)) >> (64 - n)
+	if x != r {
+		s.errorString("overflow on character value " + string(r))
+	}
+	return r
+}
+
+// scanBasePrefix reports whether the integer begins with a 0 or 0x,
+// and returns the base, digit string, and whether a zero was found.
+// It is called only if the verb is %v.
+func (s *ss) scanBasePrefix() (base int, digits string, found bool) {
+	if !s.peek("0") {
+		return 10, decimalDigits, false
+	}
+	s.accept("0")
+	found = true // We've put a digit into the token buffer.
+	// Special cases for '0' && '0x'
+	base, digits = 8, octalDigits
+	if s.peek("xX") {
+		s.consume("xX", false)
+		base, digits = 16, hexadecimalDigits
+	}
+	return
+}
+
+// scanInt returns the value of the integer represented by the next
+// token, checking for overflow.  Any error is stored in s.err.
+func (s *ss) scanInt(verb rune, bitSize int) int64 {
+	if verb == 'c' {
+		return s.scanRune(bitSize)
+	}
+	s.skipSpace(false)
+	s.notEOF()
+	base, digits := s.getBase(verb)
+	haveDigits := false
+	if verb == 'U' {
+		if !s.consume("U", false) || !s.consume("+", false) {
+			s.errorString("bad unicode format ")
+		}
+	} else {
+		s.accept(sign) // If there's a sign, it will be left in the token buffer.
+		if verb == 'v' {
+			base, digits, haveDigits = s.scanBasePrefix()
+		}
+	}
+	tok := s.scanNumber(digits, haveDigits)
+	i, err := strconv.ParseInt(tok, base, 64)
+	if err != nil {
+		s.error(err)
+	}
+	n := uint(bitSize)
+	x := (i << (64 - n)) >> (64 - n)
+	if x != i {
+		s.errorString("integer overflow on token " + tok)
+	}
+	return i
+}
+
+// scanUint returns the value of the unsigned integer represented
+// by the next token, checking for overflow.  Any error is stored in s.err.
+func (s *ss) scanUint(verb rune, bitSize int) uint64 {
+	if verb == 'c' {
+		return uint64(s.scanRune(bitSize))
+	}
+	s.skipSpace(false)
+	s.notEOF()
+	base, digits := s.getBase(verb)
+	haveDigits := false
+	if verb == 'U' {
+		if !s.consume("U", false) || !s.consume("+", false) {
+			s.errorString("bad unicode format ")
+		}
+	} else if verb == 'v' {
+		base, digits, haveDigits = s.scanBasePrefix()
+	}
+	tok := s.scanNumber(digits, haveDigits)
+	i, err := strconv.ParseUint(tok, base, 64)
+	if err != nil {
+		s.error(err)
+	}
+	n := uint(bitSize)
+	x := (i << (64 - n)) >> (64 - n)
+	if x != i {
+		s.errorString("unsigned integer overflow on token " + tok)
+	}
+	return i
+}
+
+// floatToken returns the floating-point number starting here, no longer than swid
+// if the width is specified. It's not rigorous about syntax because it doesn't check that
+// we have at least some digits, but Atof will do that.
+func (s *ss) floatToken() string {
+	s.buf = s.buf[:0]
+	// NaN?
+	if s.accept("nN") && s.accept("aA") && s.accept("nN") {
+		return string(s.buf)
+	}
+	// leading sign?
+	s.accept(sign)
+	// Inf?
+	if s.accept("iI") && s.accept("nN") && s.accept("fF") {
+		return string(s.buf)
+	}
+	// digits?
+	for s.accept(decimalDigits) {
+	}
+	// decimal point?
+	if s.accept(period) {
+		// fraction?
+		for s.accept(decimalDigits) {
+		}
+	}
+	// exponent?
+	if s.accept(exponent) {
+		// leading sign?
+		s.accept(sign)
+		// digits?
+		for s.accept(decimalDigits) {
+		}
+	}
+	return string(s.buf)
+}
+
+// complexTokens returns the real and imaginary parts of the complex number starting here.
+// The number might be parenthesized and has the format (N+Ni) where N is a floating-point
+// number and there are no spaces within.
+func (s *ss) complexTokens() (real, imag string) {
+	// TODO: accept N and Ni independently?
+	parens := s.accept("(")
+	real = s.floatToken()
+	s.buf = s.buf[:0]
+	// Must now have a sign.
+	if !s.accept("+-") {
+		s.error(complexError)
+	}
+	// Sign is now in buffer
+	imagSign := string(s.buf)
+	imag = s.floatToken()
+	if !s.accept("i") {
+		s.error(complexError)
+	}
+	if parens && !s.accept(")") {
+		s.error(complexError)
+	}
+	return real, imagSign + imag
+}
+
+// convertFloat converts the string to a float64value.
+func (s *ss) convertFloat(str string, n int) float64 {
+	if p := indexRune(str, 'p'); p >= 0 {
+		// Atof doesn't handle power-of-2 exponents,
+		// but they're easy to evaluate.
+		f, err := strconv.ParseFloat(str[:p], n)
+		if err != nil {
+			// Put full string into error.
+			if e, ok := err.(*strconv.NumError); ok {
+				e.Num = str
+			}
+			s.error(err)
+		}
+		m, err := strconv.Atoi(str[p+1:])
+		if err != nil {
+			// Put full string into error.
+			if e, ok := err.(*strconv.NumError); ok {
+				e.Num = str
+			}
+			s.error(err)
+		}
+		return math.Ldexp(f, m)
+	}
+	f, err := strconv.ParseFloat(str, n)
+	if err != nil {
+		s.error(err)
+	}
+	return f
+}
+
+// convertComplex converts the next token to a complex128 value.
+// The atof argument is a type-specific reader for the underlying type.
+// If we're reading complex64, atof will parse float32s and convert them
+// to float64's to avoid reproducing this code for each complex type.
+func (s *ss) scanComplex(verb rune, n int) complex128 {
+	if !s.okVerb(verb, floatVerbs, "complex") {
+		return 0
+	}
+	s.skipSpace(false)
+	s.notEOF()
+	sreal, simag := s.complexTokens()
+	real := s.convertFloat(sreal, n/2)
+	imag := s.convertFloat(simag, n/2)
+	return complex(real, imag)
+}
+
+// convertString returns the string represented by the next input characters.
+// The format of the input is determined by the verb.
+func (s *ss) convertString(verb rune) (str string) {
+	if !s.okVerb(verb, "svqx", "string") {
+		return ""
+	}
+	s.skipSpace(false)
+	s.notEOF()
+	switch verb {
+	case 'q':
+		str = s.quotedString()
+	case 'x':
+		str = s.hexString()
+	default:
+		str = string(s.token(true, notSpace)) // %s and %v just return the next word
+	}
+	return
+}
+
+// quotedString returns the double- or back-quoted string represented by the next input characters.
+func (s *ss) quotedString() string {
+	s.notEOF()
+	quote := s.getRune()
+	switch quote {
+	case '`':
+		// Back-quoted: Anything goes until EOF or back quote.
+		for {
+			r := s.mustReadRune()
+			if r == quote {
+				break
+			}
+			s.buf.WriteRune(r)
+		}
+		return string(s.buf)
+	case '"':
+		// Double-quoted: Include the quotes and let strconv.Unquote do the backslash escapes.
+		s.buf.WriteRune(quote)
+		for {
+			r := s.mustReadRune()
+			s.buf.WriteRune(r)
+			if r == '\\' {
+				// In a legal backslash escape, no matter how long, only the character
+				// immediately after the escape can itself be a backslash or quote.
+				// Thus we only need to protect the first character after the backslash.
+				s.buf.WriteRune(s.mustReadRune())
+			} else if r == '"' {
+				break
+			}
+		}
+		result, err := strconv.Unquote(string(s.buf))
+		if err != nil {
+			s.error(err)
+		}
+		return result
+	default:
+		s.errorString("expected quoted string")
+	}
+	return ""
+}
+
+// hexDigit returns the value of the hexadecimal digit
+func (s *ss) hexDigit(d rune) int {
+	digit := int(d)
+	switch digit {
+	case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
+		return digit - '0'
+	case 'a', 'b', 'c', 'd', 'e', 'f':
+		return 10 + digit - 'a'
+	case 'A', 'B', 'C', 'D', 'E', 'F':
+		return 10 + digit - 'A'
+	}
+	s.errorString("illegal hex digit")
+	return 0
+}
+
+// hexByte returns the next hex-encoded (two-character) byte from the input.
+// There must be either two hexadecimal digits or a space character in the input.
+func (s *ss) hexByte() (b byte, ok bool) {
+	rune1 := s.getRune()
+	if rune1 == eof {
+		return
+	}
+	if isSpace(rune1) {
+		s.UnreadRune()
+		return
+	}
+	rune2 := s.mustReadRune()
+	return byte(s.hexDigit(rune1)<<4 | s.hexDigit(rune2)), true
+}
+
+// hexString returns the space-delimited hexpair-encoded string.
+func (s *ss) hexString() string {
+	s.notEOF()
+	for {
+		b, ok := s.hexByte()
+		if !ok {
+			break
+		}
+		s.buf.WriteByte(b)
+	}
+	if len(s.buf) == 0 {
+		s.errorString("no hex data for %x string")
+		return ""
+	}
+	return string(s.buf)
+}
+
+const floatVerbs = "beEfFgGv"
+
+const hugeWid = 1 << 30
+
+// scanOne scans a single value, deriving the scanner from the type of the argument.
+func (s *ss) scanOne(verb rune, arg interface{}) {
+	s.buf = s.buf[:0]
+	var err error
+	// If the parameter has its own Scan method, use that.
+	if v, ok := arg.(Scanner); ok {
+		err = v.Scan(s, verb)
+		if err != nil {
+			if err == io.EOF {
+				err = io.ErrUnexpectedEOF
+			}
+			s.error(err)
+		}
+		return
+	}
+
+	switch v := arg.(type) {
+	case *bool:
+		*v = s.scanBool(verb)
+	case *complex64:
+		*v = complex64(s.scanComplex(verb, 64))
+	case *complex128:
+		*v = s.scanComplex(verb, 128)
+	case *int:
+		*v = int(s.scanInt(verb, intBits))
+	case *int8:
+		*v = int8(s.scanInt(verb, 8))
+	case *int16:
+		*v = int16(s.scanInt(verb, 16))
+	case *int32:
+		*v = int32(s.scanInt(verb, 32))
+	case *int64:
+		*v = s.scanInt(verb, 64)
+	case *uint:
+		*v = uint(s.scanUint(verb, intBits))
+	case *uint8:
+		*v = uint8(s.scanUint(verb, 8))
+	case *uint16:
+		*v = uint16(s.scanUint(verb, 16))
+	case *uint32:
+		*v = uint32(s.scanUint(verb, 32))
+	case *uint64:
+		*v = s.scanUint(verb, 64)
+	case *uintptr:
+		*v = uintptr(s.scanUint(verb, uintptrBits))
+	// Floats are tricky because you want to scan in the precision of the result, not
+	// scan in high precision and convert, in order to preserve the correct error condition.
+	case *float32:
+		if s.okVerb(verb, floatVerbs, "float32") {
+			s.skipSpace(false)
+			s.notEOF()
+			*v = float32(s.convertFloat(s.floatToken(), 32))
+		}
+	case *float64:
+		if s.okVerb(verb, floatVerbs, "float64") {
+			s.skipSpace(false)
+			s.notEOF()
+			*v = s.convertFloat(s.floatToken(), 64)
+		}
+	case *string:
+		*v = s.convertString(verb)
+	case *[]byte:
+		// We scan to string and convert so we get a copy of the data.
+		// If we scanned to bytes, the slice would point at the buffer.
+		*v = []byte(s.convertString(verb))
+	default:
+		val := reflect.ValueOf(v)
+		ptr := val
+		if ptr.Kind() != reflect.Ptr {
+			s.errorString("type not a pointer: " + val.Type().String())
+			return
+		}
+		switch v := ptr.Elem(); v.Kind() {
+		case reflect.Bool:
+			v.SetBool(s.scanBool(verb))
+		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+			v.SetInt(s.scanInt(verb, v.Type().Bits()))
+		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+			v.SetUint(s.scanUint(verb, v.Type().Bits()))
+		case reflect.String:
+			v.SetString(s.convertString(verb))
+		case reflect.Slice:
+			// For now, can only handle (renamed) []byte.
+			typ := v.Type()
+			if typ.Elem().Kind() != reflect.Uint8 {
+				s.errorString("can't scan type: " + val.Type().String())
+			}
+			str := s.convertString(verb)
+			v.Set(reflect.MakeSlice(typ, len(str), len(str)))
+			for i := 0; i < len(str); i++ {
+				v.Index(i).SetUint(uint64(str[i]))
+			}
+		case reflect.Float32, reflect.Float64:
+			s.skipSpace(false)
+			s.notEOF()
+			v.SetFloat(s.convertFloat(s.floatToken(), v.Type().Bits()))
+		case reflect.Complex64, reflect.Complex128:
+			v.SetComplex(s.scanComplex(verb, v.Type().Bits()))
+		default:
+			s.errorString("can't scan type: " + val.Type().String())
+		}
+	}
+}
+
+// errorHandler turns local panics into error returns.
+func errorHandler(errp *error) {
+	if e := recover(); e != nil {
+		if se, ok := e.(scanError); ok { // catch local error
+			*errp = se.err
+		} else if eof, ok := e.(error); ok && eof == io.EOF { // out of input
+			*errp = eof
+		} else {
+			panic(e)
+		}
+	}
+}
+
+// doScan does the real work for scanning without a format string.
+func (s *ss) doScan(a []interface{}) (numProcessed int, err error) {
+	defer errorHandler(&err)
+	for _, arg := range a {
+		s.scanOne('v', arg)
+		numProcessed++
+	}
+	// Check for newline if required.
+	if !s.nlIsSpace {
+		for {
+			r := s.getRune()
+			if r == '\n' || r == eof {
+				break
+			}
+			if !isSpace(r) {
+				s.errorString("expected newline")
+				break
+			}
+		}
+	}
+	return
+}
+
+// advance determines whether the next characters in the input match
+// those of the format.  It returns the number of bytes (sic) consumed
+// in the format. Newlines included, all runs of space characters in
+// either input or format behave as a single space. This routine also
+// handles the %% case.  If the return value is zero, either format
+// starts with a % (with no following %) or the input is empty.
+// If it is negative, the input did not match the string.
+func (s *ss) advance(format string) (i int) {
+	for i < len(format) {
+		fmtc, w := utf8.DecodeRuneInString(format[i:])
+		if fmtc == '%' {
+			// %% acts like a real percent
+			nextc, _ := utf8.DecodeRuneInString(format[i+w:]) // will not match % if string is empty
+			if nextc != '%' {
+				return
+			}
+			i += w // skip the first %
+		}
+		sawSpace := false
+		for isSpace(fmtc) && i < len(format) {
+			sawSpace = true
+			i += w
+			fmtc, w = utf8.DecodeRuneInString(format[i:])
+		}
+		if sawSpace {
+			// There was space in the format, so there should be space (EOF)
+			// in the input.
+			inputc := s.getRune()
+			if inputc == eof || inputc == '\n' {
+				// If we've reached a newline, stop now; don't read ahead.
+				return
+			}
+			if !isSpace(inputc) {
+				// Space in format but not in input: error
+				s.errorString("expected space in input to match format")
+			}
+			s.skipSpace(true)
+			continue
+		}
+		inputc := s.mustReadRune()
+		if fmtc != inputc {
+			s.UnreadRune()
+			return -1
+		}
+		i += w
+	}
+	return
+}
+
+// doScanf does the real work when scanning with a format string.
+//  At the moment, it handles only pointers to basic types.
+func (s *ss) doScanf(format string, a []interface{}) (numProcessed int, err error) {
+	defer errorHandler(&err)
+	end := len(format) - 1
+	// We process one item per non-trivial format
+	for i := 0; i <= end; {
+		w := s.advance(format[i:])
+		if w > 0 {
+			i += w
+			continue
+		}
+		// Either we failed to advance, we have a percent character, or we ran out of input.
+		if format[i] != '%' {
+			// Can't advance format.  Why not?
+			if w < 0 {
+				s.errorString("input does not match format")
+			}
+			// Otherwise at EOF; "too many operands" error handled below
+			break
+		}
+		i++ // % is one byte
+
+		// do we have 20 (width)?
+		var widPresent bool
+		s.maxWid, widPresent, i = parsenum(format, i, end)
+		if !widPresent {
+			s.maxWid = hugeWid
+		}
+		s.argLimit = s.limit
+		if f := s.count + s.maxWid; f < s.argLimit {
+			s.argLimit = f
+		}
+
+		c, w := utf8.DecodeRuneInString(format[i:])
+		i += w
+
+		if numProcessed >= len(a) { // out of operands
+			s.errorString("too few operands for format %" + format[i-w:])
+			break
+		}
+		arg := a[numProcessed]
+
+		s.scanOne(c, arg)
+		numProcessed++
+		s.argLimit = s.limit
+	}
+	if numProcessed < len(a) {
+		s.errorString("too many operands")
+	}
+	return
+}
diff --git a/src/fmt/scan_test.go b/src/fmt/scan_test.go
new file mode 100644
index 0000000..541e12d
--- /dev/null
+++ b/src/fmt/scan_test.go
@@ -0,0 +1,992 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package fmt_test
+
+import (
+	"bufio"
+	"bytes"
+	"errors"
+	. "fmt"
+	"io"
+	"math"
+	"reflect"
+	"regexp"
+	"strings"
+	"testing"
+	"unicode/utf8"
+)
+
+type ScanTest struct {
+	text string
+	in   interface{}
+	out  interface{}
+}
+
+type ScanfTest struct {
+	format string
+	text   string
+	in     interface{}
+	out    interface{}
+}
+
+type ScanfMultiTest struct {
+	format string
+	text   string
+	in     []interface{}
+	out    []interface{}
+	err    string
+}
+
+var (
+	boolVal              bool
+	intVal               int
+	int8Val              int8
+	int16Val             int16
+	int32Val             int32
+	int64Val             int64
+	uintVal              uint
+	uint8Val             uint8
+	uint16Val            uint16
+	uint32Val            uint32
+	uint64Val            uint64
+	float32Val           float32
+	float64Val           float64
+	stringVal            string
+	bytesVal             []byte
+	runeVal              rune
+	complex64Val         complex64
+	complex128Val        complex128
+	renamedBoolVal       renamedBool
+	renamedIntVal        renamedInt
+	renamedInt8Val       renamedInt8
+	renamedInt16Val      renamedInt16
+	renamedInt32Val      renamedInt32
+	renamedInt64Val      renamedInt64
+	renamedUintVal       renamedUint
+	renamedUint8Val      renamedUint8
+	renamedUint16Val     renamedUint16
+	renamedUint32Val     renamedUint32
+	renamedUint64Val     renamedUint64
+	renamedUintptrVal    renamedUintptr
+	renamedStringVal     renamedString
+	renamedBytesVal      renamedBytes
+	renamedFloat32Val    renamedFloat32
+	renamedFloat64Val    renamedFloat64
+	renamedComplex64Val  renamedComplex64
+	renamedComplex128Val renamedComplex128
+)
+
+type FloatTest struct {
+	text string
+	in   float64
+	out  float64
+}
+
+// Xs accepts any non-empty run of the verb character
+type Xs string
+
+func (x *Xs) Scan(state ScanState, verb rune) error {
+	tok, err := state.Token(true, func(r rune) bool { return r == verb })
+	if err != nil {
+		return err
+	}
+	s := string(tok)
+	if !regexp.MustCompile("^" + string(verb) + "+$").MatchString(s) {
+		return errors.New("syntax error for xs")
+	}
+	*x = Xs(s)
+	return nil
+}
+
+var xVal Xs
+
+// IntString accepts an integer followed immediately by a string.
+// It tests the embedding of a scan within a scan.
+type IntString struct {
+	i int
+	s string
+}
+
+func (s *IntString) Scan(state ScanState, verb rune) error {
+	if _, err := Fscan(state, &s.i); err != nil {
+		return err
+	}
+
+	tok, err := state.Token(true, nil)
+	if err != nil {
+		return err
+	}
+	s.s = string(tok)
+	return nil
+}
+
+var intStringVal IntString
+
+// myStringReader implements Read but not ReadRune, allowing us to test our readRune wrapper
+// type that creates something that can read runes given only Read().
+type myStringReader struct {
+	r *strings.Reader
+}
+
+func (s *myStringReader) Read(p []byte) (n int, err error) {
+	return s.r.Read(p)
+}
+
+func newReader(s string) *myStringReader {
+	return &myStringReader{strings.NewReader(s)}
+}
+
+var scanTests = []ScanTest{
+	// Basic types
+	{"T\n", &boolVal, true},  // boolean test vals toggle to be sure they are written
+	{"F\n", &boolVal, false}, // restored to zero value
+	{"21\n", &intVal, 21},
+	{"0\n", &intVal, 0},
+	{"000\n", &intVal, 0},
+	{"0x10\n", &intVal, 0x10},
+	{"-0x10\n", &intVal, -0x10},
+	{"0377\n", &intVal, 0377},
+	{"-0377\n", &intVal, -0377},
+	{"0\n", &uintVal, uint(0)},
+	{"000\n", &uintVal, uint(0)},
+	{"0x10\n", &uintVal, uint(0x10)},
+	{"0377\n", &uintVal, uint(0377)},
+	{"22\n", &int8Val, int8(22)},
+	{"23\n", &int16Val, int16(23)},
+	{"24\n", &int32Val, int32(24)},
+	{"25\n", &int64Val, int64(25)},
+	{"127\n", &int8Val, int8(127)},
+	{"-21\n", &intVal, -21},
+	{"-22\n", &int8Val, int8(-22)},
+	{"-23\n", &int16Val, int16(-23)},
+	{"-24\n", &int32Val, int32(-24)},
+	{"-25\n", &int64Val, int64(-25)},
+	{"-128\n", &int8Val, int8(-128)},
+	{"+21\n", &intVal, +21},
+	{"+22\n", &int8Val, int8(+22)},
+	{"+23\n", &int16Val, int16(+23)},
+	{"+24\n", &int32Val, int32(+24)},
+	{"+25\n", &int64Val, int64(+25)},
+	{"+127\n", &int8Val, int8(+127)},
+	{"26\n", &uintVal, uint(26)},
+	{"27\n", &uint8Val, uint8(27)},
+	{"28\n", &uint16Val, uint16(28)},
+	{"29\n", &uint32Val, uint32(29)},
+	{"30\n", &uint64Val, uint64(30)},
+	{"255\n", &uint8Val, uint8(255)},
+	{"32767\n", &int16Val, int16(32767)},
+	{"2.3\n", &float64Val, 2.3},
+	{"2.3e1\n", &float32Val, float32(2.3e1)},
+	{"2.3e2\n", &float64Val, 2.3e2},
+	{"2.3p2\n", &float64Val, 2.3 * 4},
+	{"2.3p+2\n", &float64Val, 2.3 * 4},
+	{"2.3p+66\n", &float64Val, 2.3 * (1 << 32) * (1 << 32) * 4},
+	{"2.3p-66\n", &float64Val, 2.3 / ((1 << 32) * (1 << 32) * 4)},
+	{"2.35\n", &stringVal, "2.35"},
+	{"2345678\n", &bytesVal, []byte("2345678")},
+	{"(3.4e1-2i)\n", &complex128Val, 3.4e1 - 2i},
+	{"-3.45e1-3i\n", &complex64Val, complex64(-3.45e1 - 3i)},
+	{"-.45e1-1e2i\n", &complex128Val, complex128(-.45e1 - 100i)},
+	{"hello\n", &stringVal, "hello"},
+
+	// Carriage-return followed by newline. (We treat \r\n as \n always.)
+	{"hello\r\n", &stringVal, "hello"},
+	{"27\r\n", &uint8Val, uint8(27)},
+
+	// Renamed types
+	{"true\n", &renamedBoolVal, renamedBool(true)},
+	{"F\n", &renamedBoolVal, renamedBool(false)},
+	{"101\n", &renamedIntVal, renamedInt(101)},
+	{"102\n", &renamedIntVal, renamedInt(102)},
+	{"103\n", &renamedUintVal, renamedUint(103)},
+	{"104\n", &renamedUintVal, renamedUint(104)},
+	{"105\n", &renamedInt8Val, renamedInt8(105)},
+	{"106\n", &renamedInt16Val, renamedInt16(106)},
+	{"107\n", &renamedInt32Val, renamedInt32(107)},
+	{"108\n", &renamedInt64Val, renamedInt64(108)},
+	{"109\n", &renamedUint8Val, renamedUint8(109)},
+	{"110\n", &renamedUint16Val, renamedUint16(110)},
+	{"111\n", &renamedUint32Val, renamedUint32(111)},
+	{"112\n", &renamedUint64Val, renamedUint64(112)},
+	{"113\n", &renamedUintptrVal, renamedUintptr(113)},
+	{"114\n", &renamedStringVal, renamedString("114")},
+	{"115\n", &renamedBytesVal, renamedBytes([]byte("115"))},
+
+	// Custom scanners.
+	{"  vvv ", &xVal, Xs("vvv")},
+	{" 1234hello", &intStringVal, IntString{1234, "hello"}},
+
+	// Fixed bugs
+	{"2147483648\n", &int64Val, int64(2147483648)}, // was: integer overflow
+}
+
+var scanfTests = []ScanfTest{
+	{"%v", "TRUE\n", &boolVal, true},
+	{"%t", "false\n", &boolVal, false},
+	{"%v", "-71\n", &intVal, -71},
+	{"%v", "0377\n", &intVal, 0377},
+	{"%v", "0x44\n", &intVal, 0x44},
+	{"%d", "72\n", &intVal, 72},
+	{"%c", "a\n", &runeVal, 'a'},
+	{"%c", "\u5072\n", &runeVal, '\u5072'},
+	{"%c", "\u1234\n", &runeVal, '\u1234'},
+	{"%d", "73\n", &int8Val, int8(73)},
+	{"%d", "+74\n", &int16Val, int16(74)},
+	{"%d", "75\n", &int32Val, int32(75)},
+	{"%d", "76\n", &int64Val, int64(76)},
+	{"%b", "1001001\n", &intVal, 73},
+	{"%o", "075\n", &intVal, 075},
+	{"%x", "a75\n", &intVal, 0xa75},
+	{"%v", "71\n", &uintVal, uint(71)},
+	{"%d", "72\n", &uintVal, uint(72)},
+	{"%d", "73\n", &uint8Val, uint8(73)},
+	{"%d", "74\n", &uint16Val, uint16(74)},
+	{"%d", "75\n", &uint32Val, uint32(75)},
+	{"%d", "76\n", &uint64Val, uint64(76)},
+	{"%b", "1001001\n", &uintVal, uint(73)},
+	{"%o", "075\n", &uintVal, uint(075)},
+	{"%x", "a75\n", &uintVal, uint(0xa75)},
+	{"%x", "A75\n", &uintVal, uint(0xa75)},
+	{"%U", "U+1234\n", &intVal, int(0x1234)},
+	{"%U", "U+4567\n", &uintVal, uint(0x4567)},
+
+	// Strings
+	{"%s", "using-%s\n", &stringVal, "using-%s"},
+	{"%x", "7573696e672d2578\n", &stringVal, "using-%x"},
+	{"%q", `"quoted\twith\\do\u0075bl\x65s"` + "\n", &stringVal, "quoted\twith\\doubles"},
+	{"%q", "`quoted with backs`\n", &stringVal, "quoted with backs"},
+
+	// Byte slices
+	{"%s", "bytes-%s\n", &bytesVal, []byte("bytes-%s")},
+	{"%x", "62797465732d2578\n", &bytesVal, []byte("bytes-%x")},
+	{"%q", `"bytes\rwith\vdo\u0075bl\x65s"` + "\n", &bytesVal, []byte("bytes\rwith\vdoubles")},
+	{"%q", "`bytes with backs`\n", &bytesVal, []byte("bytes with backs")},
+
+	// Renamed types
+	{"%v\n", "true\n", &renamedBoolVal, renamedBool(true)},
+	{"%t\n", "F\n", &renamedBoolVal, renamedBool(false)},
+	{"%v", "101\n", &renamedIntVal, renamedInt(101)},
+	{"%c", "\u0101\n", &renamedIntVal, renamedInt('\u0101')},
+	{"%o", "0146\n", &renamedIntVal, renamedInt(102)},
+	{"%v", "103\n", &renamedUintVal, renamedUint(103)},
+	{"%d", "104\n", &renamedUintVal, renamedUint(104)},
+	{"%d", "105\n", &renamedInt8Val, renamedInt8(105)},
+	{"%d", "106\n", &renamedInt16Val, renamedInt16(106)},
+	{"%d", "107\n", &renamedInt32Val, renamedInt32(107)},
+	{"%d", "108\n", &renamedInt64Val, renamedInt64(108)},
+	{"%x", "6D\n", &renamedUint8Val, renamedUint8(109)},
+	{"%o", "0156\n", &renamedUint16Val, renamedUint16(110)},
+	{"%d", "111\n", &renamedUint32Val, renamedUint32(111)},
+	{"%d", "112\n", &renamedUint64Val, renamedUint64(112)},
+	{"%d", "113\n", &renamedUintptrVal, renamedUintptr(113)},
+	{"%s", "114\n", &renamedStringVal, renamedString("114")},
+	{"%q", "\"1155\"\n", &renamedBytesVal, renamedBytes([]byte("1155"))},
+	{"%g", "116e1\n", &renamedFloat32Val, renamedFloat32(116e1)},
+	{"%g", "-11.7e+1", &renamedFloat64Val, renamedFloat64(-11.7e+1)},
+	{"%g", "11+6e1i\n", &renamedComplex64Val, renamedComplex64(11 + 6e1i)},
+	{"%g", "-11.+7e+1i", &renamedComplex128Val, renamedComplex128(-11. + 7e+1i)},
+
+	// Interesting formats
+	{"here is\tthe value:%d", "here is   the\tvalue:118\n", &intVal, 118},
+	{"%% %%:%d", "% %:119\n", &intVal, 119},
+
+	// Corner cases
+	{"%x", "FFFFFFFF\n", &uint32Val, uint32(0xFFFFFFFF)},
+
+	// Custom scanner.
+	{"%s", "  sss ", &xVal, Xs("sss")},
+	{"%2s", "sssss", &xVal, Xs("ss")},
+
+	// Fixed bugs
+	{"%d\n", "27\n", &intVal, 27},  // ok
+	{"%d\n", "28 \n", &intVal, 28}, // was: "unexpected newline"
+	{"%v", "0", &intVal, 0},        // was: "EOF"; 0 was taken as base prefix and not counted.
+	{"%v", "0", &uintVal, uint(0)}, // was: "EOF"; 0 was taken as base prefix and not counted.
+}
+
+var overflowTests = []ScanTest{
+	{"128", &int8Val, 0},
+	{"32768", &int16Val, 0},
+	{"-129", &int8Val, 0},
+	{"-32769", &int16Val, 0},
+	{"256", &uint8Val, 0},
+	{"65536", &uint16Val, 0},
+	{"1e100", &float32Val, 0},
+	{"1e500", &float64Val, 0},
+	{"(1e100+0i)", &complex64Val, 0},
+	{"(1+1e100i)", &complex64Val, 0},
+	{"(1-1e500i)", &complex128Val, 0},
+}
+
+var truth bool
+var i, j, k int
+var f float64
+var s, t string
+var c complex128
+var x, y Xs
+var z IntString
+var r1, r2, r3 rune
+
+var multiTests = []ScanfMultiTest{
+	{"", "", []interface{}{}, []interface{}{}, ""},
+	{"%d", "23", args(&i), args(23), ""},
+	{"%2s%3s", "22333", args(&s, &t), args("22", "333"), ""},
+	{"%2d%3d", "44555", args(&i, &j), args(44, 555), ""},
+	{"%2d.%3d", "66.777", args(&i, &j), args(66, 777), ""},
+	{"%d, %d", "23, 18", args(&i, &j), args(23, 18), ""},
+	{"%3d22%3d", "33322333", args(&i, &j), args(333, 333), ""},
+	{"%6vX=%3fY", "3+2iX=2.5Y", args(&c, &f), args((3 + 2i), 2.5), ""},
+	{"%d%s", "123abc", args(&i, &s), args(123, "abc"), ""},
+	{"%c%c%c", "2\u50c2X", args(&r1, &r2, &r3), args('2', '\u50c2', 'X'), ""},
+
+	// Custom scanners.
+	{"%e%f", "eefffff", args(&x, &y), args(Xs("ee"), Xs("fffff")), ""},
+	{"%4v%s", "12abcd", args(&z, &s), args(IntString{12, "ab"}, "cd"), ""},
+
+	// Errors
+	{"%t", "23 18", args(&i), nil, "bad verb"},
+	{"%d %d %d", "23 18", args(&i, &j), args(23, 18), "too few operands"},
+	{"%d %d", "23 18 27", args(&i, &j, &k), args(23, 18), "too many operands"},
+	{"%c", "\u0100", args(&int8Val), nil, "overflow"},
+	{"X%d", "10X", args(&intVal), nil, "input does not match format"},
+
+	// Bad UTF-8: should see every byte.
+	{"%c%c%c", "\xc2X\xc2", args(&r1, &r2, &r3), args(utf8.RuneError, 'X', utf8.RuneError), ""},
+
+	// Fixed bugs
+	{"%v%v", "FALSE23", args(&truth, &i), args(false, 23), ""},
+}
+
+func testScan(name string, t *testing.T, scan func(r io.Reader, a ...interface{}) (int, error)) {
+	for _, test := range scanTests {
+		var r io.Reader
+		if name == "StringReader" {
+			r = strings.NewReader(test.text)
+		} else {
+			r = newReader(test.text)
+		}
+		n, err := scan(r, test.in)
+		if err != nil {
+			m := ""
+			if n > 0 {
+				m = Sprintf(" (%d fields ok)", n)
+			}
+			t.Errorf("%s got error scanning %q: %s%s", name, test.text, err, m)
+			continue
+		}
+		if n != 1 {
+			t.Errorf("%s count error on entry %q: got %d", name, test.text, n)
+			continue
+		}
+		// The incoming value may be a pointer
+		v := reflect.ValueOf(test.in)
+		if p := v; p.Kind() == reflect.Ptr {
+			v = p.Elem()
+		}
+		val := v.Interface()
+		if !reflect.DeepEqual(val, test.out) {
+			t.Errorf("%s scanning %q: expected %#v got %#v, type %T", name, test.text, test.out, val, val)
+		}
+	}
+}
+
+func TestScan(t *testing.T) {
+	testScan("StringReader", t, Fscan)
+}
+
+func TestMyReaderScan(t *testing.T) {
+	testScan("myStringReader", t, Fscan)
+}
+
+func TestScanln(t *testing.T) {
+	testScan("StringReader", t, Fscanln)
+}
+
+func TestMyReaderScanln(t *testing.T) {
+	testScan("myStringReader", t, Fscanln)
+}
+
+func TestScanf(t *testing.T) {
+	for _, test := range scanfTests {
+		n, err := Sscanf(test.text, test.format, test.in)
+		if err != nil {
+			t.Errorf("got error scanning (%q, %q): %s", test.format, test.text, err)
+			continue
+		}
+		if n != 1 {
+			t.Errorf("count error on entry (%q, %q): got %d", test.format, test.text, n)
+			continue
+		}
+		// The incoming value may be a pointer
+		v := reflect.ValueOf(test.in)
+		if p := v; p.Kind() == reflect.Ptr {
+			v = p.Elem()
+		}
+		val := v.Interface()
+		if !reflect.DeepEqual(val, test.out) {
+			t.Errorf("scanning (%q, %q): expected %#v got %#v, type %T", test.format, test.text, test.out, val, val)
+		}
+	}
+}
+
+func TestScanOverflow(t *testing.T) {
+	// different machines and different types report errors with different strings.
+	re := regexp.MustCompile("overflow|too large|out of range|not representable")
+	for _, test := range overflowTests {
+		_, err := Sscan(test.text, test.in)
+		if err == nil {
+			t.Errorf("expected overflow scanning %q", test.text)
+			continue
+		}
+		if !re.MatchString(err.Error()) {
+			t.Errorf("expected overflow error scanning %q: %s", test.text, err)
+		}
+	}
+}
+
+func verifyNaN(str string, t *testing.T) {
+	var f float64
+	var f32 float32
+	var f64 float64
+	text := str + " " + str + " " + str
+	n, err := Fscan(strings.NewReader(text), &f, &f32, &f64)
+	if err != nil {
+		t.Errorf("got error scanning %q: %s", text, err)
+	}
+	if n != 3 {
+		t.Errorf("count error scanning %q: got %d", text, n)
+	}
+	if !math.IsNaN(float64(f)) || !math.IsNaN(float64(f32)) || !math.IsNaN(f64) {
+		t.Errorf("didn't get NaNs scanning %q: got %g %g %g", text, f, f32, f64)
+	}
+}
+
+func TestNaN(t *testing.T) {
+	for _, s := range []string{"nan", "NAN", "NaN"} {
+		verifyNaN(s, t)
+	}
+}
+
+func verifyInf(str string, t *testing.T) {
+	var f float64
+	var f32 float32
+	var f64 float64
+	text := str + " " + str + " " + str
+	n, err := Fscan(strings.NewReader(text), &f, &f32, &f64)
+	if err != nil {
+		t.Errorf("got error scanning %q: %s", text, err)
+	}
+	if n != 3 {
+		t.Errorf("count error scanning %q: got %d", text, n)
+	}
+	sign := 1
+	if str[0] == '-' {
+		sign = -1
+	}
+	if !math.IsInf(float64(f), sign) || !math.IsInf(float64(f32), sign) || !math.IsInf(f64, sign) {
+		t.Errorf("didn't get right Infs scanning %q: got %g %g %g", text, f, f32, f64)
+	}
+}
+
+func TestInf(t *testing.T) {
+	for _, s := range []string{"inf", "+inf", "-inf", "INF", "-INF", "+INF", "Inf", "-Inf", "+Inf"} {
+		verifyInf(s, t)
+	}
+}
+
+func testScanfMulti(name string, t *testing.T) {
+	sliceType := reflect.TypeOf(make([]interface{}, 1))
+	for _, test := range multiTests {
+		var r io.Reader
+		if name == "StringReader" {
+			r = strings.NewReader(test.text)
+		} else {
+			r = newReader(test.text)
+		}
+		n, err := Fscanf(r, test.format, test.in...)
+		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 {
+				t.Errorf("got wrong error scanning (%q, %q): %q; expected %q", test.format, test.text, err, test.err)
+			}
+			continue
+		}
+		if test.err != "" {
+			t.Errorf("expected error %q error scanning (%q, %q)", test.err, test.format, test.text)
+		}
+		if n != len(test.out) {
+			t.Errorf("count error on entry (%q, %q): expected %d got %d", test.format, test.text, len(test.out), n)
+			continue
+		}
+		// Convert the slice of pointers into a slice of values
+		resultVal := reflect.MakeSlice(sliceType, n, n)
+		for i := 0; i < n; i++ {
+			v := reflect.ValueOf(test.in[i]).Elem()
+			resultVal.Index(i).Set(v)
+		}
+		result := resultVal.Interface()
+		if !reflect.DeepEqual(result, test.out) {
+			t.Errorf("scanning (%q, %q): expected %#v got %#v", test.format, test.text, test.out, result)
+		}
+	}
+}
+
+func TestScanfMulti(t *testing.T) {
+	testScanfMulti("StringReader", t)
+}
+
+func TestMyReaderScanfMulti(t *testing.T) {
+	testScanfMulti("myStringReader", t)
+}
+
+func TestScanMultiple(t *testing.T) {
+	var a int
+	var s string
+	n, err := Sscan("123abc", &a, &s)
+	if n != 2 {
+		t.Errorf("Sscan count error: expected 2: got %d", n)
+	}
+	if err != nil {
+		t.Errorf("Sscan expected no error; got %s", err)
+	}
+	if a != 123 || s != "abc" {
+		t.Errorf("Sscan wrong values: got (%d %q) expected (123 \"abc\")", a, s)
+	}
+	n, err = Sscan("asdf", &s, &a)
+	if n != 1 {
+		t.Errorf("Sscan count error: expected 1: got %d", n)
+	}
+	if err == nil {
+		t.Errorf("Sscan expected error; got none: %s", err)
+	}
+	if s != "asdf" {
+		t.Errorf("Sscan wrong values: got %q expected \"asdf\"", s)
+	}
+}
+
+// Empty strings are not valid input when scanning a string.
+func TestScanEmpty(t *testing.T) {
+	var s1, s2 string
+	n, err := Sscan("abc", &s1, &s2)
+	if n != 1 {
+		t.Errorf("Sscan count error: expected 1: got %d", n)
+	}
+	if err == nil {
+		t.Error("Sscan <one item> expected error; got none")
+	}
+	if s1 != "abc" {
+		t.Errorf("Sscan wrong values: got %q expected \"abc\"", s1)
+	}
+	n, err = Sscan("", &s1, &s2)
+	if n != 0 {
+		t.Errorf("Sscan count error: expected 0: got %d", n)
+	}
+	if err == nil {
+		t.Error("Sscan <empty> expected error; got none")
+	}
+	// Quoted empty string is OK.
+	n, err = Sscanf(`""`, "%q", &s1)
+	if n != 1 {
+		t.Errorf("Sscanf count error: expected 1: got %d", n)
+	}
+	if err != nil {
+		t.Errorf("Sscanf <empty> expected no error with quoted string; got %s", err)
+	}
+}
+
+func TestScanNotPointer(t *testing.T) {
+	r := strings.NewReader("1")
+	var a int
+	_, err := Fscan(r, a)
+	if err == nil {
+		t.Error("expected error scanning non-pointer")
+	} else if strings.Index(err.Error(), "pointer") < 0 {
+		t.Errorf("expected pointer error scanning non-pointer, got: %s", err)
+	}
+}
+
+func TestScanlnNoNewline(t *testing.T) {
+	var a int
+	_, 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 {
+		t.Errorf("expected newline error scanning string missing newline, got: %s", err)
+	}
+}
+
+func TestScanlnWithMiddleNewline(t *testing.T) {
+	r := strings.NewReader("123\n456\n")
+	var a, b int
+	_, 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 {
+		t.Errorf("expected newline error scanning string with extra newline, got: %s", err)
+	}
+}
+
+// eofCounter is a special Reader that counts reads at end of file.
+type eofCounter struct {
+	reader   *strings.Reader
+	eofCount int
+}
+
+func (ec *eofCounter) Read(b []byte) (n int, err error) {
+	n, err = ec.reader.Read(b)
+	if n == 0 {
+		ec.eofCount++
+	}
+	return
+}
+
+// TestEOF verifies that when we scan, we see at most EOF once per call to a
+// Scan function, and then only when it's really an EOF.
+func TestEOF(t *testing.T) {
+	ec := &eofCounter{strings.NewReader("123\n"), 0}
+	var a int
+	n, err := Fscanln(ec, &a)
+	if err != nil {
+		t.Error("unexpected error", err)
+	}
+	if n != 1 {
+		t.Error("expected to scan one item, got", n)
+	}
+	if ec.eofCount != 0 {
+		t.Error("expected zero EOFs", ec.eofCount)
+		ec.eofCount = 0 // reset for next test
+	}
+	n, err = Fscanln(ec, &a)
+	if err == nil {
+		t.Error("expected error scanning empty string")
+	}
+	if n != 0 {
+		t.Error("expected to scan zero items, got", n)
+	}
+	if ec.eofCount != 1 {
+		t.Error("expected one EOF, got", ec.eofCount)
+	}
+}
+
+// TestEOFAtEndOfInput verifies that we see an EOF error if we run out of input.
+// This was a buglet: we used to get "expected integer".
+func TestEOFAtEndOfInput(t *testing.T) {
+	var i, j int
+	n, err := Sscanf("23", "%d %d", &i, &j)
+	if n != 1 || i != 23 {
+		t.Errorf("Sscanf expected one value of 23; got %d %d", n, i)
+	}
+	if err != io.EOF {
+		t.Errorf("Sscanf expected EOF; got %q", err)
+	}
+	n, err = Sscan("234", &i, &j)
+	if n != 1 || i != 234 {
+		t.Errorf("Sscan expected one value of 234; got %d %d", n, i)
+	}
+	if err != io.EOF {
+		t.Errorf("Sscan expected EOF; got %q", err)
+	}
+	// Trailing space is tougher.
+	n, err = Sscan("234 ", &i, &j)
+	if n != 1 || i != 234 {
+		t.Errorf("Sscan expected one value of 234; got %d %d", n, i)
+	}
+	if err != io.EOF {
+		t.Errorf("Sscan expected EOF; got %q", err)
+	}
+}
+
+var eofTests = []struct {
+	format string
+	v      interface{}
+}{
+	{"%s", &stringVal},
+	{"%q", &stringVal},
+	{"%x", &stringVal},
+	{"%v", &stringVal},
+	{"%v", &bytesVal},
+	{"%v", &intVal},
+	{"%v", &uintVal},
+	{"%v", &boolVal},
+	{"%v", &float32Val},
+	{"%v", &complex64Val},
+	{"%v", &renamedStringVal},
+	{"%v", &renamedBytesVal},
+	{"%v", &renamedIntVal},
+	{"%v", &renamedUintVal},
+	{"%v", &renamedBoolVal},
+	{"%v", &renamedFloat32Val},
+	{"%v", &renamedComplex64Val},
+}
+
+func TestEOFAllTypes(t *testing.T) {
+	for i, test := range eofTests {
+		if _, err := Sscanf("", test.format, test.v); err != io.EOF {
+			t.Errorf("#%d: %s %T not eof on empty string: %s", i, test.format, test.v, err)
+		}
+		if _, err := Sscanf("   ", test.format, test.v); err != io.EOF {
+			t.Errorf("#%d: %s %T not eof on trailing blanks: %s", i, test.format, test.v, err)
+		}
+	}
+}
+
+// TestUnreadRuneWithBufio verifies that, at least when using bufio, successive
+// calls to Fscan do not lose runes.
+func TestUnreadRuneWithBufio(t *testing.T) {
+	r := bufio.NewReader(strings.NewReader("123αb"))
+	var i int
+	var a string
+	n, err := Fscanf(r, "%d", &i)
+	if n != 1 || err != nil {
+		t.Errorf("reading int expected one item, no errors; got %d %q", n, err)
+	}
+	if i != 123 {
+		t.Errorf("expected 123; got %d", i)
+	}
+	n, err = Fscanf(r, "%s", &a)
+	if n != 1 || err != nil {
+		t.Errorf("reading string expected one item, no errors; got %d %q", n, err)
+	}
+	if a != "αb" {
+		t.Errorf("expected αb; got %q", a)
+	}
+}
+
+type TwoLines string
+
+// Scan attempts to read two lines into the object.  Scanln should prevent this
+// because it stops at newline; Scan and Scanf should be fine.
+func (t *TwoLines) Scan(state ScanState, verb rune) error {
+	chars := make([]rune, 0, 100)
+	for nlCount := 0; nlCount < 2; {
+		c, _, err := state.ReadRune()
+		if err != nil {
+			return err
+		}
+		chars = append(chars, c)
+		if c == '\n' {
+			nlCount++
+		}
+	}
+	*t = TwoLines(string(chars))
+	return nil
+}
+
+func TestMultiLine(t *testing.T) {
+	input := "abc\ndef\n"
+	// Sscan should work
+	var tscan TwoLines
+	n, err := Sscan(input, &tscan)
+	if n != 1 {
+		t.Errorf("Sscan: expected 1 item; got %d", n)
+	}
+	if err != nil {
+		t.Errorf("Sscan: expected no error; got %s", err)
+	}
+	if string(tscan) != input {
+		t.Errorf("Sscan: expected %q; got %q", input, tscan)
+	}
+	// Sscanf should work
+	var tscanf TwoLines
+	n, err = Sscanf(input, "%s", &tscanf)
+	if n != 1 {
+		t.Errorf("Sscanf: expected 1 item; got %d", n)
+	}
+	if err != nil {
+		t.Errorf("Sscanf: expected no error; got %s", err)
+	}
+	if string(tscanf) != input {
+		t.Errorf("Sscanf: expected %q; got %q", input, tscanf)
+	}
+	// Sscanln should not work
+	var tscanln TwoLines
+	n, err = Sscanln(input, &tscanln)
+	if n != 0 {
+		t.Errorf("Sscanln: expected 0 items; got %d: %q", n, tscanln)
+	}
+	if err == nil {
+		t.Error("Sscanln: expected error; got none")
+	} else if err != io.ErrUnexpectedEOF {
+		t.Errorf("Sscanln: expected io.ErrUnexpectedEOF (ha!); got %s", err)
+	}
+}
+
+// simpleReader is a strings.Reader that implements only Read, not ReadRune.
+// Good for testing readahead.
+type simpleReader struct {
+	sr *strings.Reader
+}
+
+func (s *simpleReader) Read(b []byte) (n int, err error) {
+	return s.sr.Read(b)
+}
+
+// TestLineByLineFscanf tests that Fscanf does not read past newline. Issue
+// 3481.
+func TestLineByLineFscanf(t *testing.T) {
+	r := &simpleReader{strings.NewReader("1\n2\n")}
+	var i, j int
+	n, err := Fscanf(r, "%v\n", &i)
+	if n != 1 || err != nil {
+		t.Fatalf("first read: %d %q", n, err)
+	}
+	n, err = Fscanf(r, "%v\n", &j)
+	if n != 1 || err != nil {
+		t.Fatalf("second read: %d %q", n, err)
+	}
+	if i != 1 || j != 2 {
+		t.Errorf("wrong values; wanted 1 2 got %d %d", i, j)
+	}
+}
+
+// TestScanStateCount verifies the correct byte count is returned. Issue 8512.
+
+// runeScanner implements the Scanner interface for TestScanStateCount.
+type runeScanner struct {
+	rune rune
+	size int
+}
+
+func (rs *runeScanner) Scan(state ScanState, verb rune) error {
+	r, size, err := state.ReadRune()
+	rs.rune = r
+	rs.size = size
+	return err
+}
+
+func TestScanStateCount(t *testing.T) {
+	var a, b, c runeScanner
+	n, err := Sscanf("12➂", "%c%c%c", &a, &b, &c)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if n != 3 {
+		t.Fatalf("expected 3 items consumed, got %d")
+	}
+	if a.rune != '1' || b.rune != '2' || c.rune != '➂' {
+		t.Errorf("bad scan rune: %q %q %q should be '1' '2' '➂'", a.rune, b.rune, c.rune)
+	}
+	if a.size != 1 || b.size != 1 || c.size != 3 {
+		t.Errorf("bad scan size: %q %q %q should be 1 1 3", a.size, b.size, c.size)
+	}
+}
+
+// RecursiveInt accepts a string matching %d.%d.%d....
+// and parses it into a linked list.
+// It allows us to benchmark recursive descent style scanners.
+type RecursiveInt struct {
+	i    int
+	next *RecursiveInt
+}
+
+func (r *RecursiveInt) Scan(state ScanState, verb rune) (err error) {
+	_, err = Fscan(state, &r.i)
+	if err != nil {
+		return
+	}
+	next := new(RecursiveInt)
+	_, err = Fscanf(state, ".%v", next)
+	if err != nil {
+		if err == io.ErrUnexpectedEOF {
+			err = nil
+		}
+		return
+	}
+	r.next = next
+	return
+}
+
+// scanInts performs the same scanning task as RecursiveInt.Scan
+// but without recurring through scanner, so we can compare
+// performance more directly.
+func scanInts(r *RecursiveInt, b *bytes.Buffer) (err error) {
+	r.next = nil
+	_, err = Fscan(b, &r.i)
+	if err != nil {
+		return
+	}
+	c, _, err := b.ReadRune()
+	if err != nil {
+		if err == io.EOF {
+			err = nil
+		}
+		return
+	}
+	if c != '.' {
+		return
+	}
+	next := new(RecursiveInt)
+	err = scanInts(next, b)
+	if err == nil {
+		r.next = next
+	}
+	return
+}
+
+func makeInts(n int) []byte {
+	var buf bytes.Buffer
+	Fprintf(&buf, "1")
+	for i := 1; i < n; i++ {
+		Fprintf(&buf, ".%d", i+1)
+	}
+	return buf.Bytes()
+}
+
+func TestScanInts(t *testing.T) {
+	testScanInts(t, scanInts)
+	testScanInts(t, func(r *RecursiveInt, b *bytes.Buffer) (err error) {
+		_, err = Fscan(b, r)
+		return
+	})
+}
+
+// 800 is small enough to not overflow the stack when using gccgo on a
+// platform that does not support split stack.
+const intCount = 800
+
+func testScanInts(t *testing.T, scan func(*RecursiveInt, *bytes.Buffer) error) {
+	r := new(RecursiveInt)
+	ints := makeInts(intCount)
+	buf := bytes.NewBuffer(ints)
+	err := scan(r, buf)
+	if err != nil {
+		t.Error("unexpected error", err)
+	}
+	i := 1
+	for ; r != nil; r = r.next {
+		if r.i != i {
+			t.Fatalf("bad scan: expected %d got %d", i, r.i)
+		}
+		i++
+	}
+	if i-1 != intCount {
+		t.Fatalf("bad scan count: expected %d got %d", intCount, i-1)
+	}
+}
+
+func BenchmarkScanInts(b *testing.B) {
+	b.ResetTimer()
+	ints := makeInts(intCount)
+	var r RecursiveInt
+	for i := b.N - 1; i >= 0; i-- {
+		buf := bytes.NewBuffer(ints)
+		b.StartTimer()
+		scanInts(&r, buf)
+		b.StopTimer()
+	}
+}
+
+func BenchmarkScanRecursiveInt(b *testing.B) {
+	b.ResetTimer()
+	ints := makeInts(intCount)
+	var r RecursiveInt
+	for i := b.N - 1; i >= 0; i-- {
+		buf := bytes.NewBuffer(ints)
+		b.StartTimer()
+		Fscan(buf, &r)
+		b.StopTimer()
+	}
+}
diff --git a/src/pkg/fmt/stringer_test.go b/src/fmt/stringer_test.go
similarity index 100%
rename from src/pkg/fmt/stringer_test.go
rename to src/fmt/stringer_test.go
diff --git a/src/go/ast/ast.go b/src/go/ast/ast.go
new file mode 100644
index 0000000..312e3d1
--- /dev/null
+++ b/src/go/ast/ast.go
@@ -0,0 +1,995 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package ast declares the types used to represent syntax trees for Go
+// packages.
+//
+package ast
+
+import (
+	"go/token"
+	"strings"
+	"unicode"
+	"unicode/utf8"
+)
+
+// ----------------------------------------------------------------------------
+// Interfaces
+//
+// There are 3 main classes of nodes: Expressions and type nodes,
+// statement nodes, and declaration nodes. The node names usually
+// match the corresponding Go spec production names to which they
+// correspond. The node fields correspond to the individual parts
+// of the respective productions.
+//
+// All nodes contain position information marking the beginning of
+// the corresponding source text segment; it is accessible via the
+// Pos accessor method. Nodes may contain additional position info
+// for language constructs where comments may be found between parts
+// of the construct (typically any larger, parenthesized subpart).
+// That position information is needed to properly position comments
+// when printing the construct.
+
+// All node types implement the Node interface.
+type Node interface {
+	Pos() token.Pos // position of first character belonging to the node
+	End() token.Pos // position of first character immediately after the node
+}
+
+// All expression nodes implement the Expr interface.
+type Expr interface {
+	Node
+	exprNode()
+}
+
+// All statement nodes implement the Stmt interface.
+type Stmt interface {
+	Node
+	stmtNode()
+}
+
+// All declaration nodes implement the Decl interface.
+type Decl interface {
+	Node
+	declNode()
+}
+
+// ----------------------------------------------------------------------------
+// Comments
+
+// A Comment node represents a single //-style or /*-style comment.
+type Comment struct {
+	Slash token.Pos // position of "/" starting the comment
+	Text  string    // comment text (excluding '\n' for //-style comments)
+}
+
+func (c *Comment) Pos() token.Pos { return c.Slash }
+func (c *Comment) End() token.Pos { return token.Pos(int(c.Slash) + len(c.Text)) }
+
+// A CommentGroup represents a sequence of comments
+// with no other tokens and no empty lines between.
+//
+type CommentGroup struct {
+	List []*Comment // len(List) > 0
+}
+
+func (g *CommentGroup) Pos() token.Pos { return g.List[0].Pos() }
+func (g *CommentGroup) End() token.Pos { return g.List[len(g.List)-1].End() }
+
+func isWhitespace(ch byte) bool { return ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r' }
+
+func stripTrailingWhitespace(s string) string {
+	i := len(s)
+	for i > 0 && isWhitespace(s[i-1]) {
+		i--
+	}
+	return s[0:i]
+}
+
+// Text returns the text of the comment.
+// Comment markers (//, /*, and */), the first space of a line comment, and
+// leading and trailing empty lines are removed. Multiple empty lines are
+// reduced to one, and trailing space on lines is trimmed. Unless the result
+// is empty, it is newline-terminated.
+//
+func (g *CommentGroup) Text() string {
+	if g == nil {
+		return ""
+	}
+	comments := make([]string, len(g.List))
+	for i, c := range g.List {
+		comments[i] = string(c.Text)
+	}
+
+	lines := make([]string, 0, 10) // most comments are less than 10 lines
+	for _, c := range comments {
+		// Remove comment markers.
+		// The parser has given us exactly the comment text.
+		switch c[1] {
+		case '/':
+			//-style comment (no newline at the end)
+			c = c[2:]
+			// strip first space - required for Example tests
+			if len(c) > 0 && c[0] == ' ' {
+				c = c[1:]
+			}
+		case '*':
+			/*-style comment */
+			c = c[2 : len(c)-2]
+		}
+
+		// Split on newlines.
+		cl := strings.Split(c, "\n")
+
+		// Walk lines, stripping trailing white space and adding to list.
+		for _, l := range cl {
+			lines = append(lines, stripTrailingWhitespace(l))
+		}
+	}
+
+	// Remove leading blank lines; convert runs of
+	// interior blank lines to a single blank line.
+	n := 0
+	for _, line := range lines {
+		if line != "" || n > 0 && lines[n-1] != "" {
+			lines[n] = line
+			n++
+		}
+	}
+	lines = lines[0:n]
+
+	// Add final "" entry to get trailing newline from Join.
+	if n > 0 && lines[n-1] != "" {
+		lines = append(lines, "")
+	}
+
+	return strings.Join(lines, "\n")
+}
+
+// ----------------------------------------------------------------------------
+// Expressions and types
+
+// A Field represents a Field declaration list in a struct type,
+// a method list in an interface type, or a parameter/result declaration
+// in a signature.
+//
+type Field struct {
+	Doc     *CommentGroup // associated documentation; or nil
+	Names   []*Ident      // field/method/parameter names; or nil if anonymous field
+	Type    Expr          // field/method/parameter type
+	Tag     *BasicLit     // field tag; or nil
+	Comment *CommentGroup // line comments; or nil
+}
+
+func (f *Field) Pos() token.Pos {
+	if len(f.Names) > 0 {
+		return f.Names[0].Pos()
+	}
+	return f.Type.Pos()
+}
+
+func (f *Field) End() token.Pos {
+	if f.Tag != nil {
+		return f.Tag.End()
+	}
+	return f.Type.End()
+}
+
+// A FieldList represents a list of Fields, enclosed by parentheses or braces.
+type FieldList struct {
+	Opening token.Pos // position of opening parenthesis/brace, if any
+	List    []*Field  // field list; or nil
+	Closing token.Pos // position of closing parenthesis/brace, if any
+}
+
+func (f *FieldList) Pos() token.Pos {
+	if f.Opening.IsValid() {
+		return f.Opening
+	}
+	// the list should not be empty in this case;
+	// be conservative and guard against bad ASTs
+	if len(f.List) > 0 {
+		return f.List[0].Pos()
+	}
+	return token.NoPos
+}
+
+func (f *FieldList) End() token.Pos {
+	if f.Closing.IsValid() {
+		return f.Closing + 1
+	}
+	// the list should not be empty in this case;
+	// be conservative and guard against bad ASTs
+	if n := len(f.List); n > 0 {
+		return f.List[n-1].End()
+	}
+	return token.NoPos
+}
+
+// NumFields returns the number of (named and anonymous fields) in a FieldList.
+func (f *FieldList) NumFields() int {
+	n := 0
+	if f != nil {
+		for _, g := range f.List {
+			m := len(g.Names)
+			if m == 0 {
+				m = 1 // anonymous field
+			}
+			n += m
+		}
+	}
+	return n
+}
+
+// An expression is represented by a tree consisting of one
+// or more of the following concrete expression nodes.
+//
+type (
+	// A BadExpr node is a placeholder for expressions containing
+	// syntax errors for which no correct expression nodes can be
+	// created.
+	//
+	BadExpr struct {
+		From, To token.Pos // position range of bad expression
+	}
+
+	// An Ident node represents an identifier.
+	Ident struct {
+		NamePos token.Pos // identifier position
+		Name    string    // identifier name
+		Obj     *Object   // denoted object; or nil
+	}
+
+	// An Ellipsis node stands for the "..." type in a
+	// parameter list or the "..." length in an array type.
+	//
+	Ellipsis struct {
+		Ellipsis token.Pos // position of "..."
+		Elt      Expr      // ellipsis element type (parameter lists only); or nil
+	}
+
+	// A BasicLit node represents a literal of basic type.
+	BasicLit struct {
+		ValuePos token.Pos   // literal position
+		Kind     token.Token // token.INT, token.FLOAT, token.IMAG, token.CHAR, or token.STRING
+		Value    string      // literal string; e.g. 42, 0x7f, 3.14, 1e-9, 2.4i, 'a', '\x7f', "foo" or `\m\n\o`
+	}
+
+	// A FuncLit node represents a function literal.
+	FuncLit struct {
+		Type *FuncType  // function type
+		Body *BlockStmt // function body
+	}
+
+	// A CompositeLit node represents a composite literal.
+	CompositeLit struct {
+		Type   Expr      // literal type; or nil
+		Lbrace token.Pos // position of "{"
+		Elts   []Expr    // list of composite elements; or nil
+		Rbrace token.Pos // position of "}"
+	}
+
+	// A ParenExpr node represents a parenthesized expression.
+	ParenExpr struct {
+		Lparen token.Pos // position of "("
+		X      Expr      // parenthesized expression
+		Rparen token.Pos // position of ")"
+	}
+
+	// A SelectorExpr node represents an expression followed by a selector.
+	SelectorExpr struct {
+		X   Expr   // expression
+		Sel *Ident // field selector
+	}
+
+	// An IndexExpr node represents an expression followed by an index.
+	IndexExpr struct {
+		X      Expr      // expression
+		Lbrack token.Pos // position of "["
+		Index  Expr      // index expression
+		Rbrack token.Pos // position of "]"
+	}
+
+	// An SliceExpr node represents an expression followed by slice indices.
+	SliceExpr struct {
+		X      Expr      // expression
+		Lbrack token.Pos // position of "["
+		Low    Expr      // begin of slice range; or nil
+		High   Expr      // end of slice range; or nil
+		Max    Expr      // maximum capacity of slice; or nil
+		Slice3 bool      // true if 3-index slice (2 colons present)
+		Rbrack token.Pos // position of "]"
+	}
+
+	// A TypeAssertExpr node represents an expression followed by a
+	// type assertion.
+	//
+	TypeAssertExpr struct {
+		X      Expr      // expression
+		Lparen token.Pos // position of "("
+		Type   Expr      // asserted type; nil means type switch X.(type)
+		Rparen token.Pos // position of ")"
+	}
+
+	// A CallExpr node represents an expression followed by an argument list.
+	CallExpr struct {
+		Fun      Expr      // function expression
+		Lparen   token.Pos // position of "("
+		Args     []Expr    // function arguments; or nil
+		Ellipsis token.Pos // position of "...", if any
+		Rparen   token.Pos // position of ")"
+	}
+
+	// A StarExpr node represents an expression of the form "*" Expression.
+	// Semantically it could be a unary "*" expression, or a pointer type.
+	//
+	StarExpr struct {
+		Star token.Pos // position of "*"
+		X    Expr      // operand
+	}
+
+	// A UnaryExpr node represents a unary expression.
+	// Unary "*" expressions are represented via StarExpr nodes.
+	//
+	UnaryExpr struct {
+		OpPos token.Pos   // position of Op
+		Op    token.Token // operator
+		X     Expr        // operand
+	}
+
+	// A BinaryExpr node represents a binary expression.
+	BinaryExpr struct {
+		X     Expr        // left operand
+		OpPos token.Pos   // position of Op
+		Op    token.Token // operator
+		Y     Expr        // right operand
+	}
+
+	// A KeyValueExpr node represents (key : value) pairs
+	// in composite literals.
+	//
+	KeyValueExpr struct {
+		Key   Expr
+		Colon token.Pos // position of ":"
+		Value Expr
+	}
+)
+
+// The direction of a channel type is indicated by one
+// of the following constants.
+//
+type ChanDir int
+
+const (
+	SEND ChanDir = 1 << iota
+	RECV
+)
+
+// A type is represented by a tree consisting of one
+// or more of the following type-specific expression
+// nodes.
+//
+type (
+	// An ArrayType node represents an array or slice type.
+	ArrayType struct {
+		Lbrack token.Pos // position of "["
+		Len    Expr      // Ellipsis node for [...]T array types, nil for slice types
+		Elt    Expr      // element type
+	}
+
+	// A StructType node represents a struct type.
+	StructType struct {
+		Struct     token.Pos  // position of "struct" keyword
+		Fields     *FieldList // list of field declarations
+		Incomplete bool       // true if (source) fields are missing in the Fields list
+	}
+
+	// Pointer types are represented via StarExpr nodes.
+
+	// A FuncType node represents a function type.
+	FuncType struct {
+		Func    token.Pos  // position of "func" keyword (token.NoPos if there is no "func")
+		Params  *FieldList // (incoming) parameters; non-nil
+		Results *FieldList // (outgoing) results; or nil
+	}
+
+	// An InterfaceType node represents an interface type.
+	InterfaceType struct {
+		Interface  token.Pos  // position of "interface" keyword
+		Methods    *FieldList // list of methods
+		Incomplete bool       // true if (source) methods are missing in the Methods list
+	}
+
+	// A MapType node represents a map type.
+	MapType struct {
+		Map   token.Pos // position of "map" keyword
+		Key   Expr
+		Value Expr
+	}
+
+	// A ChanType node represents a channel type.
+	ChanType struct {
+		Begin token.Pos // position of "chan" keyword or "<-" (whichever comes first)
+		Arrow token.Pos // position of "<-" (token.NoPos if there is no "<-")
+		Dir   ChanDir   // channel direction
+		Value Expr      // value type
+	}
+)
+
+// Pos and End implementations for expression/type nodes.
+//
+func (x *BadExpr) Pos() token.Pos  { return x.From }
+func (x *Ident) Pos() token.Pos    { return x.NamePos }
+func (x *Ellipsis) Pos() token.Pos { return x.Ellipsis }
+func (x *BasicLit) Pos() token.Pos { return x.ValuePos }
+func (x *FuncLit) Pos() token.Pos  { return x.Type.Pos() }
+func (x *CompositeLit) Pos() token.Pos {
+	if x.Type != nil {
+		return x.Type.Pos()
+	}
+	return x.Lbrace
+}
+func (x *ParenExpr) Pos() token.Pos      { return x.Lparen }
+func (x *SelectorExpr) Pos() token.Pos   { return x.X.Pos() }
+func (x *IndexExpr) Pos() token.Pos      { return x.X.Pos() }
+func (x *SliceExpr) Pos() token.Pos      { return x.X.Pos() }
+func (x *TypeAssertExpr) Pos() token.Pos { return x.X.Pos() }
+func (x *CallExpr) Pos() token.Pos       { return x.Fun.Pos() }
+func (x *StarExpr) Pos() token.Pos       { return x.Star }
+func (x *UnaryExpr) Pos() token.Pos      { return x.OpPos }
+func (x *BinaryExpr) Pos() token.Pos     { return x.X.Pos() }
+func (x *KeyValueExpr) Pos() token.Pos   { return x.Key.Pos() }
+func (x *ArrayType) Pos() token.Pos      { return x.Lbrack }
+func (x *StructType) Pos() token.Pos     { return x.Struct }
+func (x *FuncType) Pos() token.Pos {
+	if x.Func.IsValid() || x.Params == nil { // see issue 3870
+		return x.Func
+	}
+	return x.Params.Pos() // interface method declarations have no "func" keyword
+}
+func (x *InterfaceType) Pos() token.Pos { return x.Interface }
+func (x *MapType) Pos() token.Pos       { return x.Map }
+func (x *ChanType) Pos() token.Pos      { return x.Begin }
+
+func (x *BadExpr) End() token.Pos { return x.To }
+func (x *Ident) End() token.Pos   { return token.Pos(int(x.NamePos) + len(x.Name)) }
+func (x *Ellipsis) End() token.Pos {
+	if x.Elt != nil {
+		return x.Elt.End()
+	}
+	return x.Ellipsis + 3 // len("...")
+}
+func (x *BasicLit) End() token.Pos       { return token.Pos(int(x.ValuePos) + len(x.Value)) }
+func (x *FuncLit) End() token.Pos        { return x.Body.End() }
+func (x *CompositeLit) End() token.Pos   { return x.Rbrace + 1 }
+func (x *ParenExpr) End() token.Pos      { return x.Rparen + 1 }
+func (x *SelectorExpr) End() token.Pos   { return x.Sel.End() }
+func (x *IndexExpr) End() token.Pos      { return x.Rbrack + 1 }
+func (x *SliceExpr) End() token.Pos      { return x.Rbrack + 1 }
+func (x *TypeAssertExpr) End() token.Pos { return x.Rparen + 1 }
+func (x *CallExpr) End() token.Pos       { return x.Rparen + 1 }
+func (x *StarExpr) End() token.Pos       { return x.X.End() }
+func (x *UnaryExpr) End() token.Pos      { return x.X.End() }
+func (x *BinaryExpr) End() token.Pos     { return x.Y.End() }
+func (x *KeyValueExpr) End() token.Pos   { return x.Value.End() }
+func (x *ArrayType) End() token.Pos      { return x.Elt.End() }
+func (x *StructType) End() token.Pos     { return x.Fields.End() }
+func (x *FuncType) End() token.Pos {
+	if x.Results != nil {
+		return x.Results.End()
+	}
+	return x.Params.End()
+}
+func (x *InterfaceType) End() token.Pos { return x.Methods.End() }
+func (x *MapType) End() token.Pos       { return x.Value.End() }
+func (x *ChanType) End() token.Pos      { return x.Value.End() }
+
+// exprNode() ensures that only expression/type nodes can be
+// assigned to an ExprNode.
+//
+func (*BadExpr) exprNode()        {}
+func (*Ident) exprNode()          {}
+func (*Ellipsis) exprNode()       {}
+func (*BasicLit) exprNode()       {}
+func (*FuncLit) exprNode()        {}
+func (*CompositeLit) exprNode()   {}
+func (*ParenExpr) exprNode()      {}
+func (*SelectorExpr) exprNode()   {}
+func (*IndexExpr) exprNode()      {}
+func (*SliceExpr) exprNode()      {}
+func (*TypeAssertExpr) exprNode() {}
+func (*CallExpr) exprNode()       {}
+func (*StarExpr) exprNode()       {}
+func (*UnaryExpr) exprNode()      {}
+func (*BinaryExpr) exprNode()     {}
+func (*KeyValueExpr) exprNode()   {}
+
+func (*ArrayType) exprNode()     {}
+func (*StructType) exprNode()    {}
+func (*FuncType) exprNode()      {}
+func (*InterfaceType) exprNode() {}
+func (*MapType) exprNode()       {}
+func (*ChanType) exprNode()      {}
+
+// ----------------------------------------------------------------------------
+// Convenience functions for Idents
+
+// NewIdent creates a new Ident without position.
+// Useful for ASTs generated by code other than the Go parser.
+//
+func NewIdent(name string) *Ident { return &Ident{token.NoPos, name, nil} }
+
+// IsExported reports whether name is an exported Go symbol
+// (that is, whether it begins with an upper-case letter).
+//
+func IsExported(name string) bool {
+	ch, _ := utf8.DecodeRuneInString(name)
+	return unicode.IsUpper(ch)
+}
+
+// IsExported reports whether id is an exported Go symbol
+// (that is, whether it begins with an uppercase letter).
+//
+func (id *Ident) IsExported() bool { return IsExported(id.Name) }
+
+func (id *Ident) String() string {
+	if id != nil {
+		return id.Name
+	}
+	return "<nil>"
+}
+
+// ----------------------------------------------------------------------------
+// Statements
+
+// A statement is represented by a tree consisting of one
+// or more of the following concrete statement nodes.
+//
+type (
+	// A BadStmt node is a placeholder for statements containing
+	// syntax errors for which no correct statement nodes can be
+	// created.
+	//
+	BadStmt struct {
+		From, To token.Pos // position range of bad statement
+	}
+
+	// A DeclStmt node represents a declaration in a statement list.
+	DeclStmt struct {
+		Decl Decl // *GenDecl with CONST, TYPE, or VAR token
+	}
+
+	// An EmptyStmt node represents an empty statement.
+	// The "position" of the empty statement is the position
+	// of the immediately preceding semicolon.
+	//
+	EmptyStmt struct {
+		Semicolon token.Pos // position of preceding ";"
+	}
+
+	// A LabeledStmt node represents a labeled statement.
+	LabeledStmt struct {
+		Label *Ident
+		Colon token.Pos // position of ":"
+		Stmt  Stmt
+	}
+
+	// An ExprStmt node represents a (stand-alone) expression
+	// in a statement list.
+	//
+	ExprStmt struct {
+		X Expr // expression
+	}
+
+	// A SendStmt node represents a send statement.
+	SendStmt struct {
+		Chan  Expr
+		Arrow token.Pos // position of "<-"
+		Value Expr
+	}
+
+	// An IncDecStmt node represents an increment or decrement statement.
+	IncDecStmt struct {
+		X      Expr
+		TokPos token.Pos   // position of Tok
+		Tok    token.Token // INC or DEC
+	}
+
+	// An AssignStmt node represents an assignment or
+	// a short variable declaration.
+	//
+	AssignStmt struct {
+		Lhs    []Expr
+		TokPos token.Pos   // position of Tok
+		Tok    token.Token // assignment token, DEFINE
+		Rhs    []Expr
+	}
+
+	// A GoStmt node represents a go statement.
+	GoStmt struct {
+		Go   token.Pos // position of "go" keyword
+		Call *CallExpr
+	}
+
+	// A DeferStmt node represents a defer statement.
+	DeferStmt struct {
+		Defer token.Pos // position of "defer" keyword
+		Call  *CallExpr
+	}
+
+	// A ReturnStmt node represents a return statement.
+	ReturnStmt struct {
+		Return  token.Pos // position of "return" keyword
+		Results []Expr    // result expressions; or nil
+	}
+
+	// A BranchStmt node represents a break, continue, goto,
+	// or fallthrough statement.
+	//
+	BranchStmt struct {
+		TokPos token.Pos   // position of Tok
+		Tok    token.Token // keyword token (BREAK, CONTINUE, GOTO, FALLTHROUGH)
+		Label  *Ident      // label name; or nil
+	}
+
+	// A BlockStmt node represents a braced statement list.
+	BlockStmt struct {
+		Lbrace token.Pos // position of "{"
+		List   []Stmt
+		Rbrace token.Pos // position of "}"
+	}
+
+	// An IfStmt node represents an if statement.
+	IfStmt struct {
+		If   token.Pos // position of "if" keyword
+		Init Stmt      // initialization statement; or nil
+		Cond Expr      // condition
+		Body *BlockStmt
+		Else Stmt // else branch; or nil
+	}
+
+	// A CaseClause represents a case of an expression or type switch statement.
+	CaseClause struct {
+		Case  token.Pos // position of "case" or "default" keyword
+		List  []Expr    // list of expressions or types; nil means default case
+		Colon token.Pos // position of ":"
+		Body  []Stmt    // statement list; or nil
+	}
+
+	// A SwitchStmt node represents an expression switch statement.
+	SwitchStmt struct {
+		Switch token.Pos  // position of "switch" keyword
+		Init   Stmt       // initialization statement; or nil
+		Tag    Expr       // tag expression; or nil
+		Body   *BlockStmt // CaseClauses only
+	}
+
+	// An TypeSwitchStmt node represents a type switch statement.
+	TypeSwitchStmt struct {
+		Switch token.Pos  // position of "switch" keyword
+		Init   Stmt       // initialization statement; or nil
+		Assign Stmt       // x := y.(type) or y.(type)
+		Body   *BlockStmt // CaseClauses only
+	}
+
+	// A CommClause node represents a case of a select statement.
+	CommClause struct {
+		Case  token.Pos // position of "case" or "default" keyword
+		Comm  Stmt      // send or receive statement; nil means default case
+		Colon token.Pos // position of ":"
+		Body  []Stmt    // statement list; or nil
+	}
+
+	// An SelectStmt node represents a select statement.
+	SelectStmt struct {
+		Select token.Pos  // position of "select" keyword
+		Body   *BlockStmt // CommClauses only
+	}
+
+	// A ForStmt represents a for statement.
+	ForStmt struct {
+		For  token.Pos // position of "for" keyword
+		Init Stmt      // initialization statement; or nil
+		Cond Expr      // condition; or nil
+		Post Stmt      // post iteration statement; or nil
+		Body *BlockStmt
+	}
+
+	// A RangeStmt represents a for statement with a range clause.
+	RangeStmt struct {
+		For        token.Pos   // position of "for" keyword
+		Key, Value Expr        // Key, Value may be nil
+		TokPos     token.Pos   // position of Tok; invalid if Key == nil
+		Tok        token.Token // ILLEGAL if Key == nil, ASSIGN, DEFINE
+		X          Expr        // value to range over
+		Body       *BlockStmt
+	}
+)
+
+// Pos and End implementations for statement nodes.
+//
+func (s *BadStmt) Pos() token.Pos        { return s.From }
+func (s *DeclStmt) Pos() token.Pos       { return s.Decl.Pos() }
+func (s *EmptyStmt) Pos() token.Pos      { return s.Semicolon }
+func (s *LabeledStmt) Pos() token.Pos    { return s.Label.Pos() }
+func (s *ExprStmt) Pos() token.Pos       { return s.X.Pos() }
+func (s *SendStmt) Pos() token.Pos       { return s.Chan.Pos() }
+func (s *IncDecStmt) Pos() token.Pos     { return s.X.Pos() }
+func (s *AssignStmt) Pos() token.Pos     { return s.Lhs[0].Pos() }
+func (s *GoStmt) Pos() token.Pos         { return s.Go }
+func (s *DeferStmt) Pos() token.Pos      { return s.Defer }
+func (s *ReturnStmt) Pos() token.Pos     { return s.Return }
+func (s *BranchStmt) Pos() token.Pos     { return s.TokPos }
+func (s *BlockStmt) Pos() token.Pos      { return s.Lbrace }
+func (s *IfStmt) Pos() token.Pos         { return s.If }
+func (s *CaseClause) Pos() token.Pos     { return s.Case }
+func (s *SwitchStmt) Pos() token.Pos     { return s.Switch }
+func (s *TypeSwitchStmt) Pos() token.Pos { return s.Switch }
+func (s *CommClause) Pos() token.Pos     { return s.Case }
+func (s *SelectStmt) Pos() token.Pos     { return s.Select }
+func (s *ForStmt) Pos() token.Pos        { return s.For }
+func (s *RangeStmt) Pos() token.Pos      { return s.For }
+
+func (s *BadStmt) End() token.Pos  { return s.To }
+func (s *DeclStmt) End() token.Pos { return s.Decl.End() }
+func (s *EmptyStmt) End() token.Pos {
+	return s.Semicolon + 1 /* len(";") */
+}
+func (s *LabeledStmt) End() token.Pos { return s.Stmt.End() }
+func (s *ExprStmt) End() token.Pos    { return s.X.End() }
+func (s *SendStmt) End() token.Pos    { return s.Value.End() }
+func (s *IncDecStmt) End() token.Pos {
+	return s.TokPos + 2 /* len("++") */
+}
+func (s *AssignStmt) End() token.Pos { return s.Rhs[len(s.Rhs)-1].End() }
+func (s *GoStmt) End() token.Pos     { return s.Call.End() }
+func (s *DeferStmt) End() token.Pos  { return s.Call.End() }
+func (s *ReturnStmt) End() token.Pos {
+	if n := len(s.Results); n > 0 {
+		return s.Results[n-1].End()
+	}
+	return s.Return + 6 // len("return")
+}
+func (s *BranchStmt) End() token.Pos {
+	if s.Label != nil {
+		return s.Label.End()
+	}
+	return token.Pos(int(s.TokPos) + len(s.Tok.String()))
+}
+func (s *BlockStmt) End() token.Pos { return s.Rbrace + 1 }
+func (s *IfStmt) End() token.Pos {
+	if s.Else != nil {
+		return s.Else.End()
+	}
+	return s.Body.End()
+}
+func (s *CaseClause) End() token.Pos {
+	if n := len(s.Body); n > 0 {
+		return s.Body[n-1].End()
+	}
+	return s.Colon + 1
+}
+func (s *SwitchStmt) End() token.Pos     { return s.Body.End() }
+func (s *TypeSwitchStmt) End() token.Pos { return s.Body.End() }
+func (s *CommClause) End() token.Pos {
+	if n := len(s.Body); n > 0 {
+		return s.Body[n-1].End()
+	}
+	return s.Colon + 1
+}
+func (s *SelectStmt) End() token.Pos { return s.Body.End() }
+func (s *ForStmt) End() token.Pos    { return s.Body.End() }
+func (s *RangeStmt) End() token.Pos  { return s.Body.End() }
+
+// stmtNode() ensures that only statement nodes can be
+// assigned to a StmtNode.
+//
+func (*BadStmt) stmtNode()        {}
+func (*DeclStmt) stmtNode()       {}
+func (*EmptyStmt) stmtNode()      {}
+func (*LabeledStmt) stmtNode()    {}
+func (*ExprStmt) stmtNode()       {}
+func (*SendStmt) stmtNode()       {}
+func (*IncDecStmt) stmtNode()     {}
+func (*AssignStmt) stmtNode()     {}
+func (*GoStmt) stmtNode()         {}
+func (*DeferStmt) stmtNode()      {}
+func (*ReturnStmt) stmtNode()     {}
+func (*BranchStmt) stmtNode()     {}
+func (*BlockStmt) stmtNode()      {}
+func (*IfStmt) stmtNode()         {}
+func (*CaseClause) stmtNode()     {}
+func (*SwitchStmt) stmtNode()     {}
+func (*TypeSwitchStmt) stmtNode() {}
+func (*CommClause) stmtNode()     {}
+func (*SelectStmt) stmtNode()     {}
+func (*ForStmt) stmtNode()        {}
+func (*RangeStmt) stmtNode()      {}
+
+// ----------------------------------------------------------------------------
+// Declarations
+
+// A Spec node represents a single (non-parenthesized) import,
+// constant, type, or variable declaration.
+//
+type (
+	// The Spec type stands for any of *ImportSpec, *ValueSpec, and *TypeSpec.
+	Spec interface {
+		Node
+		specNode()
+	}
+
+	// An ImportSpec node represents a single package import.
+	ImportSpec struct {
+		Doc     *CommentGroup // associated documentation; or nil
+		Name    *Ident        // local package name (including "."); or nil
+		Path    *BasicLit     // import path
+		Comment *CommentGroup // line comments; or nil
+		EndPos  token.Pos     // end of spec (overrides Path.Pos if nonzero)
+	}
+
+	// A ValueSpec node represents a constant or variable declaration
+	// (ConstSpec or VarSpec production).
+	//
+	ValueSpec struct {
+		Doc     *CommentGroup // associated documentation; or nil
+		Names   []*Ident      // value names (len(Names) > 0)
+		Type    Expr          // value type; or nil
+		Values  []Expr        // initial values; or nil
+		Comment *CommentGroup // line comments; or nil
+	}
+
+	// A TypeSpec node represents a type declaration (TypeSpec production).
+	TypeSpec struct {
+		Doc     *CommentGroup // associated documentation; or nil
+		Name    *Ident        // type name
+		Type    Expr          // *Ident, *ParenExpr, *SelectorExpr, *StarExpr, or any of the *XxxTypes
+		Comment *CommentGroup // line comments; or nil
+	}
+)
+
+// Pos and End implementations for spec nodes.
+//
+func (s *ImportSpec) Pos() token.Pos {
+	if s.Name != nil {
+		return s.Name.Pos()
+	}
+	return s.Path.Pos()
+}
+func (s *ValueSpec) Pos() token.Pos { return s.Names[0].Pos() }
+func (s *TypeSpec) Pos() token.Pos  { return s.Name.Pos() }
+
+func (s *ImportSpec) End() token.Pos {
+	if s.EndPos != 0 {
+		return s.EndPos
+	}
+	return s.Path.End()
+}
+
+func (s *ValueSpec) End() token.Pos {
+	if n := len(s.Values); n > 0 {
+		return s.Values[n-1].End()
+	}
+	if s.Type != nil {
+		return s.Type.End()
+	}
+	return s.Names[len(s.Names)-1].End()
+}
+func (s *TypeSpec) End() token.Pos { return s.Type.End() }
+
+// specNode() ensures that only spec nodes can be
+// assigned to a Spec.
+//
+func (*ImportSpec) specNode() {}
+func (*ValueSpec) specNode()  {}
+func (*TypeSpec) specNode()   {}
+
+// A declaration is represented by one of the following declaration nodes.
+//
+type (
+	// A BadDecl node is a placeholder for declarations containing
+	// syntax errors for which no correct declaration nodes can be
+	// created.
+	//
+	BadDecl struct {
+		From, To token.Pos // position range of bad declaration
+	}
+
+	// A GenDecl node (generic declaration node) represents an import,
+	// constant, type or variable declaration. A valid Lparen position
+	// (Lparen.Line > 0) indicates a parenthesized declaration.
+	//
+	// Relationship between Tok value and Specs element type:
+	//
+	//	token.IMPORT  *ImportSpec
+	//	token.CONST   *ValueSpec
+	//	token.TYPE    *TypeSpec
+	//	token.VAR     *ValueSpec
+	//
+	GenDecl struct {
+		Doc    *CommentGroup // associated documentation; or nil
+		TokPos token.Pos     // position of Tok
+		Tok    token.Token   // IMPORT, CONST, TYPE, VAR
+		Lparen token.Pos     // position of '(', if any
+		Specs  []Spec
+		Rparen token.Pos // position of ')', if any
+	}
+
+	// A FuncDecl node represents a function declaration.
+	FuncDecl struct {
+		Doc  *CommentGroup // associated documentation; or nil
+		Recv *FieldList    // receiver (methods); or nil (functions)
+		Name *Ident        // function/method name
+		Type *FuncType     // function signature: parameters, results, and position of "func" keyword
+		Body *BlockStmt    // function body; or nil (forward declaration)
+	}
+)
+
+// Pos and End implementations for declaration nodes.
+//
+func (d *BadDecl) Pos() token.Pos  { return d.From }
+func (d *GenDecl) Pos() token.Pos  { return d.TokPos }
+func (d *FuncDecl) Pos() token.Pos { return d.Type.Pos() }
+
+func (d *BadDecl) End() token.Pos { return d.To }
+func (d *GenDecl) End() token.Pos {
+	if d.Rparen.IsValid() {
+		return d.Rparen + 1
+	}
+	return d.Specs[0].End()
+}
+func (d *FuncDecl) End() token.Pos {
+	if d.Body != nil {
+		return d.Body.End()
+	}
+	return d.Type.End()
+}
+
+// declNode() ensures that only declaration nodes can be
+// assigned to a DeclNode.
+//
+func (*BadDecl) declNode()  {}
+func (*GenDecl) declNode()  {}
+func (*FuncDecl) declNode() {}
+
+// ----------------------------------------------------------------------------
+// Files and packages
+
+// A File node represents a Go source file.
+//
+// The Comments list contains all comments in the source file in order of
+// appearance, including the comments that are pointed to from other nodes
+// via Doc and Comment fields.
+//
+type File struct {
+	Doc        *CommentGroup   // associated documentation; or nil
+	Package    token.Pos       // position of "package" keyword
+	Name       *Ident          // package name
+	Decls      []Decl          // top-level declarations; or nil
+	Scope      *Scope          // package scope (this file only)
+	Imports    []*ImportSpec   // imports in this file
+	Unresolved []*Ident        // unresolved identifiers in this file
+	Comments   []*CommentGroup // list of all comments in the source file
+}
+
+func (f *File) Pos() token.Pos { return f.Package }
+func (f *File) End() token.Pos {
+	if n := len(f.Decls); n > 0 {
+		return f.Decls[n-1].End()
+	}
+	return f.Name.End()
+}
+
+// A Package node represents a set of source files
+// collectively building a Go package.
+//
+type Package struct {
+	Name    string             // package name
+	Scope   *Scope             // package scope across all files
+	Imports map[string]*Object // map of package id -> package object
+	Files   map[string]*File   // Go source files by filename
+}
+
+func (p *Package) Pos() token.Pos { return token.NoPos }
+func (p *Package) End() token.Pos { return token.NoPos }
diff --git a/src/pkg/go/ast/ast_test.go b/src/go/ast/ast_test.go
similarity index 100%
rename from src/pkg/go/ast/ast_test.go
rename to src/go/ast/ast_test.go
diff --git a/src/pkg/go/ast/commentmap.go b/src/go/ast/commentmap.go
similarity index 100%
rename from src/pkg/go/ast/commentmap.go
rename to src/go/ast/commentmap.go
diff --git a/src/pkg/go/ast/commentmap_test.go b/src/go/ast/commentmap_test.go
similarity index 100%
rename from src/pkg/go/ast/commentmap_test.go
rename to src/go/ast/commentmap_test.go
diff --git a/src/pkg/go/ast/example_test.go b/src/go/ast/example_test.go
similarity index 100%
rename from src/pkg/go/ast/example_test.go
rename to src/go/ast/example_test.go
diff --git a/src/pkg/go/ast/filter.go b/src/go/ast/filter.go
similarity index 100%
rename from src/pkg/go/ast/filter.go
rename to src/go/ast/filter.go
diff --git a/src/pkg/go/ast/filter_test.go b/src/go/ast/filter_test.go
similarity index 100%
rename from src/pkg/go/ast/filter_test.go
rename to src/go/ast/filter_test.go
diff --git a/src/pkg/go/ast/import.go b/src/go/ast/import.go
similarity index 100%
rename from src/pkg/go/ast/import.go
rename to src/go/ast/import.go
diff --git a/src/pkg/go/ast/print.go b/src/go/ast/print.go
similarity index 100%
rename from src/pkg/go/ast/print.go
rename to src/go/ast/print.go
diff --git a/src/pkg/go/ast/print_test.go b/src/go/ast/print_test.go
similarity index 100%
rename from src/pkg/go/ast/print_test.go
rename to src/go/ast/print_test.go
diff --git a/src/pkg/go/ast/resolve.go b/src/go/ast/resolve.go
similarity index 100%
rename from src/pkg/go/ast/resolve.go
rename to src/go/ast/resolve.go
diff --git a/src/go/ast/scope.go b/src/go/ast/scope.go
new file mode 100644
index 0000000..df1529d
--- /dev/null
+++ b/src/go/ast/scope.go
@@ -0,0 +1,162 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file implements scopes and the objects they contain.
+
+package ast
+
+import (
+	"bytes"
+	"fmt"
+	"go/token"
+)
+
+// A Scope maintains the set of named language entities declared
+// in the scope and a link to the immediately surrounding (outer)
+// scope.
+//
+type Scope struct {
+	Outer   *Scope
+	Objects map[string]*Object
+}
+
+// NewScope creates a new scope nested in the outer scope.
+func NewScope(outer *Scope) *Scope {
+	const n = 4 // initial scope capacity
+	return &Scope{outer, make(map[string]*Object, n)}
+}
+
+// Lookup returns the object with the given name if it is
+// found in scope s, otherwise it returns nil. Outer scopes
+// are ignored.
+//
+func (s *Scope) Lookup(name string) *Object {
+	return s.Objects[name]
+}
+
+// Insert attempts to insert a named object obj into the scope s.
+// If the scope already contains an object alt with the same name,
+// Insert leaves the scope unchanged and returns alt. Otherwise
+// it inserts obj and returns nil."
+//
+func (s *Scope) Insert(obj *Object) (alt *Object) {
+	if alt = s.Objects[obj.Name]; alt == nil {
+		s.Objects[obj.Name] = obj
+	}
+	return
+}
+
+// Debugging support
+func (s *Scope) String() string {
+	var buf bytes.Buffer
+	fmt.Fprintf(&buf, "scope %p {", s)
+	if s != nil && len(s.Objects) > 0 {
+		fmt.Fprintln(&buf)
+		for _, obj := range s.Objects {
+			fmt.Fprintf(&buf, "\t%s %s\n", obj.Kind, obj.Name)
+		}
+	}
+	fmt.Fprintf(&buf, "}\n")
+	return buf.String()
+}
+
+// ----------------------------------------------------------------------------
+// Objects
+
+// An Object describes a named language entity such as a package,
+// constant, type, variable, function (incl. methods), or label.
+//
+// The Data fields contains object-specific data:
+//
+//	Kind    Data type         Data value
+//	Pkg	*types.Package    package scope
+//	Con     int               iota for the respective declaration
+//	Con     != nil            constant value
+//	Typ     *Scope            (used as method scope during type checking - transient)
+//
+type Object struct {
+	Kind ObjKind
+	Name string      // declared name
+	Decl interface{} // corresponding Field, XxxSpec, FuncDecl, LabeledStmt, AssignStmt, Scope; or nil
+	Data interface{} // object-specific data; or nil
+	Type interface{} // placeholder for type information; may be nil
+}
+
+// NewObj creates a new object of a given kind and name.
+func NewObj(kind ObjKind, name string) *Object {
+	return &Object{Kind: kind, Name: name}
+}
+
+// Pos computes the source position of the declaration of an object name.
+// The result may be an invalid position if it cannot be computed
+// (obj.Decl may be nil or not correct).
+func (obj *Object) Pos() token.Pos {
+	name := obj.Name
+	switch d := obj.Decl.(type) {
+	case *Field:
+		for _, n := range d.Names {
+			if n.Name == name {
+				return n.Pos()
+			}
+		}
+	case *ImportSpec:
+		if d.Name != nil && d.Name.Name == name {
+			return d.Name.Pos()
+		}
+		return d.Path.Pos()
+	case *ValueSpec:
+		for _, n := range d.Names {
+			if n.Name == name {
+				return n.Pos()
+			}
+		}
+	case *TypeSpec:
+		if d.Name.Name == name {
+			return d.Name.Pos()
+		}
+	case *FuncDecl:
+		if d.Name.Name == name {
+			return d.Name.Pos()
+		}
+	case *LabeledStmt:
+		if d.Label.Name == name {
+			return d.Label.Pos()
+		}
+	case *AssignStmt:
+		for _, x := range d.Lhs {
+			if ident, isIdent := x.(*Ident); isIdent && ident.Name == name {
+				return ident.Pos()
+			}
+		}
+	case *Scope:
+		// predeclared object - nothing to do for now
+	}
+	return token.NoPos
+}
+
+// ObjKind describes what an object represents.
+type ObjKind int
+
+// The list of possible Object kinds.
+const (
+	Bad ObjKind = iota // for error handling
+	Pkg                // package
+	Con                // constant
+	Typ                // type
+	Var                // variable
+	Fun                // function or method
+	Lbl                // label
+)
+
+var objKindStrings = [...]string{
+	Bad: "bad",
+	Pkg: "package",
+	Con: "const",
+	Typ: "type",
+	Var: "var",
+	Fun: "func",
+	Lbl: "label",
+}
+
+func (kind ObjKind) String() string { return objKindStrings[kind] }
diff --git a/src/go/ast/walk.go b/src/go/ast/walk.go
new file mode 100644
index 0000000..73ac386
--- /dev/null
+++ b/src/go/ast/walk.go
@@ -0,0 +1,386 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ast
+
+import "fmt"
+
+// A Visitor's Visit method is invoked for each node encountered by Walk.
+// If the result visitor w is not nil, Walk visits each of the children
+// of node with the visitor w, followed by a call of w.Visit(nil).
+type Visitor interface {
+	Visit(node Node) (w Visitor)
+}
+
+// Helper functions for common node lists. They may be empty.
+
+func walkIdentList(v Visitor, list []*Ident) {
+	for _, x := range list {
+		Walk(v, x)
+	}
+}
+
+func walkExprList(v Visitor, list []Expr) {
+	for _, x := range list {
+		Walk(v, x)
+	}
+}
+
+func walkStmtList(v Visitor, list []Stmt) {
+	for _, x := range list {
+		Walk(v, x)
+	}
+}
+
+func walkDeclList(v Visitor, list []Decl) {
+	for _, x := range list {
+		Walk(v, x)
+	}
+}
+
+// TODO(gri): Investigate if providing a closure to Walk leads to
+//            simpler use (and may help eliminate Inspect in turn).
+
+// Walk traverses an AST in depth-first order: It starts by calling
+// v.Visit(node); node must not be nil. If the visitor w returned by
+// v.Visit(node) is not nil, Walk is invoked recursively with visitor
+// w for each of the non-nil children of node, followed by a call of
+// w.Visit(nil).
+//
+func Walk(v Visitor, node Node) {
+	if v = v.Visit(node); v == nil {
+		return
+	}
+
+	// walk children
+	// (the order of the cases matches the order
+	// of the corresponding node types in ast.go)
+	switch n := node.(type) {
+	// Comments and fields
+	case *Comment:
+		// nothing to do
+
+	case *CommentGroup:
+		for _, c := range n.List {
+			Walk(v, c)
+		}
+
+	case *Field:
+		if n.Doc != nil {
+			Walk(v, n.Doc)
+		}
+		walkIdentList(v, n.Names)
+		Walk(v, n.Type)
+		if n.Tag != nil {
+			Walk(v, n.Tag)
+		}
+		if n.Comment != nil {
+			Walk(v, n.Comment)
+		}
+
+	case *FieldList:
+		for _, f := range n.List {
+			Walk(v, f)
+		}
+
+	// Expressions
+	case *BadExpr, *Ident, *BasicLit:
+		// nothing to do
+
+	case *Ellipsis:
+		if n.Elt != nil {
+			Walk(v, n.Elt)
+		}
+
+	case *FuncLit:
+		Walk(v, n.Type)
+		Walk(v, n.Body)
+
+	case *CompositeLit:
+		if n.Type != nil {
+			Walk(v, n.Type)
+		}
+		walkExprList(v, n.Elts)
+
+	case *ParenExpr:
+		Walk(v, n.X)
+
+	case *SelectorExpr:
+		Walk(v, n.X)
+		Walk(v, n.Sel)
+
+	case *IndexExpr:
+		Walk(v, n.X)
+		Walk(v, n.Index)
+
+	case *SliceExpr:
+		Walk(v, n.X)
+		if n.Low != nil {
+			Walk(v, n.Low)
+		}
+		if n.High != nil {
+			Walk(v, n.High)
+		}
+		if n.Max != nil {
+			Walk(v, n.Max)
+		}
+
+	case *TypeAssertExpr:
+		Walk(v, n.X)
+		if n.Type != nil {
+			Walk(v, n.Type)
+		}
+
+	case *CallExpr:
+		Walk(v, n.Fun)
+		walkExprList(v, n.Args)
+
+	case *StarExpr:
+		Walk(v, n.X)
+
+	case *UnaryExpr:
+		Walk(v, n.X)
+
+	case *BinaryExpr:
+		Walk(v, n.X)
+		Walk(v, n.Y)
+
+	case *KeyValueExpr:
+		Walk(v, n.Key)
+		Walk(v, n.Value)
+
+	// Types
+	case *ArrayType:
+		if n.Len != nil {
+			Walk(v, n.Len)
+		}
+		Walk(v, n.Elt)
+
+	case *StructType:
+		Walk(v, n.Fields)
+
+	case *FuncType:
+		if n.Params != nil {
+			Walk(v, n.Params)
+		}
+		if n.Results != nil {
+			Walk(v, n.Results)
+		}
+
+	case *InterfaceType:
+		Walk(v, n.Methods)
+
+	case *MapType:
+		Walk(v, n.Key)
+		Walk(v, n.Value)
+
+	case *ChanType:
+		Walk(v, n.Value)
+
+	// Statements
+	case *BadStmt:
+		// nothing to do
+
+	case *DeclStmt:
+		Walk(v, n.Decl)
+
+	case *EmptyStmt:
+		// nothing to do
+
+	case *LabeledStmt:
+		Walk(v, n.Label)
+		Walk(v, n.Stmt)
+
+	case *ExprStmt:
+		Walk(v, n.X)
+
+	case *SendStmt:
+		Walk(v, n.Chan)
+		Walk(v, n.Value)
+
+	case *IncDecStmt:
+		Walk(v, n.X)
+
+	case *AssignStmt:
+		walkExprList(v, n.Lhs)
+		walkExprList(v, n.Rhs)
+
+	case *GoStmt:
+		Walk(v, n.Call)
+
+	case *DeferStmt:
+		Walk(v, n.Call)
+
+	case *ReturnStmt:
+		walkExprList(v, n.Results)
+
+	case *BranchStmt:
+		if n.Label != nil {
+			Walk(v, n.Label)
+		}
+
+	case *BlockStmt:
+		walkStmtList(v, n.List)
+
+	case *IfStmt:
+		if n.Init != nil {
+			Walk(v, n.Init)
+		}
+		Walk(v, n.Cond)
+		Walk(v, n.Body)
+		if n.Else != nil {
+			Walk(v, n.Else)
+		}
+
+	case *CaseClause:
+		walkExprList(v, n.List)
+		walkStmtList(v, n.Body)
+
+	case *SwitchStmt:
+		if n.Init != nil {
+			Walk(v, n.Init)
+		}
+		if n.Tag != nil {
+			Walk(v, n.Tag)
+		}
+		Walk(v, n.Body)
+
+	case *TypeSwitchStmt:
+		if n.Init != nil {
+			Walk(v, n.Init)
+		}
+		Walk(v, n.Assign)
+		Walk(v, n.Body)
+
+	case *CommClause:
+		if n.Comm != nil {
+			Walk(v, n.Comm)
+		}
+		walkStmtList(v, n.Body)
+
+	case *SelectStmt:
+		Walk(v, n.Body)
+
+	case *ForStmt:
+		if n.Init != nil {
+			Walk(v, n.Init)
+		}
+		if n.Cond != nil {
+			Walk(v, n.Cond)
+		}
+		if n.Post != nil {
+			Walk(v, n.Post)
+		}
+		Walk(v, n.Body)
+
+	case *RangeStmt:
+		if n.Key != nil {
+			Walk(v, n.Key)
+		}
+		if n.Value != nil {
+			Walk(v, n.Value)
+		}
+		Walk(v, n.X)
+		Walk(v, n.Body)
+
+	// Declarations
+	case *ImportSpec:
+		if n.Doc != nil {
+			Walk(v, n.Doc)
+		}
+		if n.Name != nil {
+			Walk(v, n.Name)
+		}
+		Walk(v, n.Path)
+		if n.Comment != nil {
+			Walk(v, n.Comment)
+		}
+
+	case *ValueSpec:
+		if n.Doc != nil {
+			Walk(v, n.Doc)
+		}
+		walkIdentList(v, n.Names)
+		if n.Type != nil {
+			Walk(v, n.Type)
+		}
+		walkExprList(v, n.Values)
+		if n.Comment != nil {
+			Walk(v, n.Comment)
+		}
+
+	case *TypeSpec:
+		if n.Doc != nil {
+			Walk(v, n.Doc)
+		}
+		Walk(v, n.Name)
+		Walk(v, n.Type)
+		if n.Comment != nil {
+			Walk(v, n.Comment)
+		}
+
+	case *BadDecl:
+		// nothing to do
+
+	case *GenDecl:
+		if n.Doc != nil {
+			Walk(v, n.Doc)
+		}
+		for _, s := range n.Specs {
+			Walk(v, s)
+		}
+
+	case *FuncDecl:
+		if n.Doc != nil {
+			Walk(v, n.Doc)
+		}
+		if n.Recv != nil {
+			Walk(v, n.Recv)
+		}
+		Walk(v, n.Name)
+		Walk(v, n.Type)
+		if n.Body != nil {
+			Walk(v, n.Body)
+		}
+
+	// Files and packages
+	case *File:
+		if n.Doc != nil {
+			Walk(v, n.Doc)
+		}
+		Walk(v, n.Name)
+		walkDeclList(v, n.Decls)
+		// don't walk n.Comments - they have been
+		// visited already through the individual
+		// nodes
+
+	case *Package:
+		for _, f := range n.Files {
+			Walk(v, f)
+		}
+
+	default:
+		fmt.Printf("ast.Walk: unexpected node type %T", n)
+		panic("ast.Walk")
+	}
+
+	v.Visit(nil)
+}
+
+type inspector func(Node) bool
+
+func (f inspector) Visit(node Node) Visitor {
+	if f(node) {
+		return f
+	}
+	return nil
+}
+
+// Inspect traverses an AST in depth-first order: It starts by calling
+// f(node); node must not be nil. If f returns true, Inspect invokes f
+// for all the non-nil children of node, recursively.
+//
+func Inspect(node Node, f func(Node) bool) {
+	Walk(inspector(f), node)
+}
diff --git a/src/go/build/build.go b/src/go/build/build.go
new file mode 100644
index 0000000..311ecb0
--- /dev/null
+++ b/src/go/build/build.go
@@ -0,0 +1,1391 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package build
+
+import (
+	"bytes"
+	"errors"
+	"fmt"
+	"go/ast"
+	"go/doc"
+	"go/parser"
+	"go/token"
+	"io"
+	"io/ioutil"
+	"log"
+	"os"
+	pathpkg "path"
+	"path/filepath"
+	"runtime"
+	"sort"
+	"strconv"
+	"strings"
+	"unicode"
+	"unicode/utf8"
+)
+
+// A Context specifies the supporting context for a build.
+type Context struct {
+	GOARCH      string // target architecture
+	GOOS        string // target operating system
+	GOROOT      string // Go root
+	GOPATH      string // Go path
+	CgoEnabled  bool   // whether cgo can be used
+	UseAllFiles bool   // use files regardless of +build lines, file names
+	Compiler    string // compiler to assume when computing target paths
+
+	// The build and release tags specify build constraints
+	// that should be considered satisfied when processing +build lines.
+	// Clients creating a new context may customize BuildTags, which
+	// defaults to empty, but it is usually an error to customize ReleaseTags,
+	// which defaults to the list of Go releases the current release is compatible with.
+	// In addition to the BuildTags and ReleaseTags, build constraints
+	// consider the values of GOARCH and GOOS as satisfied tags.
+	BuildTags   []string
+	ReleaseTags []string
+
+	// The install suffix specifies a suffix to use in the name of the installation
+	// directory. By default it is empty, but custom builds that need to keep
+	// their outputs separate can set InstallSuffix to do so. For example, when
+	// using the race detector, the go command uses InstallSuffix = "race", so
+	// that on a Linux/386 system, packages are written to a directory named
+	// "linux_386_race" instead of the usual "linux_386".
+	InstallSuffix string
+
+	// By default, Import uses the operating system's file system calls
+	// to read directories and files.  To read from other sources,
+	// callers can set the following functions.  They all have default
+	// behaviors that use the local file system, so clients need only set
+	// the functions whose behaviors they wish to change.
+
+	// JoinPath joins the sequence of path fragments into a single path.
+	// If JoinPath is nil, Import uses filepath.Join.
+	JoinPath func(elem ...string) string
+
+	// SplitPathList splits the path list into a slice of individual paths.
+	// If SplitPathList is nil, Import uses filepath.SplitList.
+	SplitPathList func(list string) []string
+
+	// IsAbsPath reports whether path is an absolute path.
+	// If IsAbsPath is nil, Import uses filepath.IsAbs.
+	IsAbsPath func(path string) bool
+
+	// IsDir reports whether the path names a directory.
+	// If IsDir is nil, Import calls os.Stat and uses the result's IsDir method.
+	IsDir func(path string) bool
+
+	// HasSubdir reports whether dir is a subdirectory of
+	// (perhaps multiple levels below) root.
+	// If so, HasSubdir sets rel to a slash-separated path that
+	// can be joined to root to produce a path equivalent to dir.
+	// If HasSubdir is nil, Import uses an implementation built on
+	// filepath.EvalSymlinks.
+	HasSubdir func(root, dir string) (rel string, ok bool)
+
+	// ReadDir returns a slice of os.FileInfo, sorted by Name,
+	// describing the content of the named directory.
+	// If ReadDir is nil, Import uses ioutil.ReadDir.
+	ReadDir func(dir string) (fi []os.FileInfo, err error)
+
+	// OpenFile opens a file (not a directory) for reading.
+	// If OpenFile is nil, Import uses os.Open.
+	OpenFile func(path string) (r io.ReadCloser, err error)
+}
+
+// joinPath calls ctxt.JoinPath (if not nil) or else filepath.Join.
+func (ctxt *Context) joinPath(elem ...string) string {
+	if f := ctxt.JoinPath; f != nil {
+		return f(elem...)
+	}
+	return filepath.Join(elem...)
+}
+
+// splitPathList calls ctxt.SplitPathList (if not nil) or else filepath.SplitList.
+func (ctxt *Context) splitPathList(s string) []string {
+	if f := ctxt.SplitPathList; f != nil {
+		return f(s)
+	}
+	return filepath.SplitList(s)
+}
+
+// isAbsPath calls ctxt.IsAbsSPath (if not nil) or else filepath.IsAbs.
+func (ctxt *Context) isAbsPath(path string) bool {
+	if f := ctxt.IsAbsPath; f != nil {
+		return f(path)
+	}
+	return filepath.IsAbs(path)
+}
+
+// isDir calls ctxt.IsDir (if not nil) or else uses os.Stat.
+func (ctxt *Context) isDir(path string) bool {
+	if f := ctxt.IsDir; f != nil {
+		return f(path)
+	}
+	fi, err := os.Stat(path)
+	return err == nil && fi.IsDir()
+}
+
+// hasSubdir calls ctxt.HasSubdir (if not nil) or else uses
+// the local file system to answer the question.
+func (ctxt *Context) hasSubdir(root, dir string) (rel string, ok bool) {
+	if f := ctxt.HasSubdir; f != nil {
+		return f(root, dir)
+	}
+
+	// Try using paths we received.
+	if rel, ok = hasSubdir(root, dir); ok {
+		return
+	}
+
+	// Try expanding symlinks and comparing
+	// expanded against unexpanded and
+	// expanded against expanded.
+	rootSym, _ := filepath.EvalSymlinks(root)
+	dirSym, _ := filepath.EvalSymlinks(dir)
+
+	if rel, ok = hasSubdir(rootSym, dir); ok {
+		return
+	}
+	if rel, ok = hasSubdir(root, dirSym); ok {
+		return
+	}
+	return hasSubdir(rootSym, dirSym)
+}
+
+func hasSubdir(root, dir string) (rel string, ok bool) {
+	const sep = string(filepath.Separator)
+	root = filepath.Clean(root)
+	if !strings.HasSuffix(root, sep) {
+		root += sep
+	}
+	dir = filepath.Clean(dir)
+	if !strings.HasPrefix(dir, root) {
+		return "", false
+	}
+	return filepath.ToSlash(dir[len(root):]), true
+}
+
+// readDir calls ctxt.ReadDir (if not nil) or else ioutil.ReadDir.
+func (ctxt *Context) readDir(path string) ([]os.FileInfo, error) {
+	if f := ctxt.ReadDir; f != nil {
+		return f(path)
+	}
+	return ioutil.ReadDir(path)
+}
+
+// openFile calls ctxt.OpenFile (if not nil) or else os.Open.
+func (ctxt *Context) openFile(path string) (io.ReadCloser, error) {
+	if fn := ctxt.OpenFile; fn != nil {
+		return fn(path)
+	}
+
+	f, err := os.Open(path)
+	if err != nil {
+		return nil, err // nil interface
+	}
+	return f, nil
+}
+
+// isFile determines whether path is a file by trying to open it.
+// It reuses openFile instead of adding another function to the
+// list in Context.
+func (ctxt *Context) isFile(path string) bool {
+	f, err := ctxt.openFile(path)
+	if err != nil {
+		return false
+	}
+	f.Close()
+	return true
+}
+
+// gopath returns the list of Go path directories.
+func (ctxt *Context) gopath() []string {
+	var all []string
+	for _, p := range ctxt.splitPathList(ctxt.GOPATH) {
+		if p == "" || p == ctxt.GOROOT {
+			// Empty paths are uninteresting.
+			// If the path is the GOROOT, ignore it.
+			// People sometimes set GOPATH=$GOROOT.
+			// Do not get confused by this common mistake.
+			continue
+		}
+		if strings.HasPrefix(p, "~") {
+			// Path segments starting with ~ on Unix are almost always
+			// users who have incorrectly quoted ~ while setting GOPATH,
+			// preventing it from expanding to $HOME.
+			// The situation is made more confusing by the fact that
+			// bash allows quoted ~ in $PATH (most shells do not).
+			// Do not get confused by this, and do not try to use the path.
+			// It does not exist, and printing errors about it confuses
+			// those users even more, because they think "sure ~ exists!".
+			// The go command diagnoses this situation and prints a
+			// useful error.
+			// On Windows, ~ is used in short names, such as c:\progra~1
+			// for c:\program files.
+			continue
+		}
+		all = append(all, p)
+	}
+	return all
+}
+
+// SrcDirs returns a list of package source root directories.
+// It draws from the current Go root and Go path but omits directories
+// that do not exist.
+func (ctxt *Context) SrcDirs() []string {
+	var all []string
+	if ctxt.GOROOT != "" {
+		dir := ctxt.joinPath(ctxt.GOROOT, "src")
+		if ctxt.isDir(dir) {
+			all = append(all, dir)
+		}
+	}
+	for _, p := range ctxt.gopath() {
+		dir := ctxt.joinPath(p, "src")
+		if ctxt.isDir(dir) {
+			all = append(all, dir)
+		}
+	}
+	return all
+}
+
+// Default is the default Context for builds.
+// It uses the GOARCH, GOOS, GOROOT, and GOPATH environment variables
+// if set, or else the compiled code's GOARCH, GOOS, and GOROOT.
+var Default Context = defaultContext()
+
+var cgoEnabled = map[string]bool{
+	"darwin/386":      true,
+	"darwin/amd64":    true,
+	"dragonfly/386":   true,
+	"dragonfly/amd64": true,
+	"freebsd/386":     true,
+	"freebsd/amd64":   true,
+	"freebsd/arm":     true,
+	"linux/386":       true,
+	"linux/amd64":     true,
+	"linux/arm":       true,
+	"android/386":     true,
+	"android/amd64":   true,
+	"android/arm":     true,
+	"netbsd/386":      true,
+	"netbsd/amd64":    true,
+	"netbsd/arm":      true,
+	"openbsd/386":     true,
+	"openbsd/amd64":   true,
+	"windows/386":     true,
+	"windows/amd64":   true,
+}
+
+func defaultContext() Context {
+	var c Context
+
+	c.GOARCH = envOr("GOARCH", runtime.GOARCH)
+	c.GOOS = envOr("GOOS", runtime.GOOS)
+	c.GOROOT = runtime.GOROOT()
+	c.GOPATH = envOr("GOPATH", "")
+	c.Compiler = runtime.Compiler
+
+	// Each major Go release in the Go 1.x series should add a tag here.
+	// Old tags should not be removed. That is, the go1.x tag is present
+	// in all releases >= Go 1.x. Code that requires Go 1.x or later should
+	// say "+build go1.x", and code that should only be built before Go 1.x
+	// (perhaps it is the stub to use in that case) should say "+build !go1.x".
+	//
+	// When we reach Go 1.5 the line will read
+	//	c.ReleaseTags = []string{"go1.1", "go1.2", "go1.3", "go1.4", "go1.5"}
+	// and so on.
+	c.ReleaseTags = []string{"go1.1", "go1.2", "go1.3", "go1.4"}
+
+	switch os.Getenv("CGO_ENABLED") {
+	case "1":
+		c.CgoEnabled = true
+	case "0":
+		c.CgoEnabled = false
+	default:
+		// cgo must be explicitly enabled for cross compilation builds
+		if runtime.GOARCH == c.GOARCH && runtime.GOOS == c.GOOS {
+			c.CgoEnabled = cgoEnabled[c.GOOS+"/"+c.GOARCH]
+			break
+		}
+		c.CgoEnabled = false
+	}
+
+	return c
+}
+
+func envOr(name, def string) string {
+	s := os.Getenv(name)
+	if s == "" {
+		return def
+	}
+	return s
+}
+
+// An ImportMode controls the behavior of the Import method.
+type ImportMode uint
+
+const (
+	// If FindOnly is set, Import stops after locating the directory
+	// that should contain the sources for a package.  It does not
+	// read any files in the directory.
+	FindOnly ImportMode = 1 << iota
+
+	// If AllowBinary is set, Import can be satisfied by a compiled
+	// package object without corresponding sources.
+	AllowBinary
+
+	// If ImportComment is set, parse import comments on package statements.
+	// Import returns an error if it finds a comment it cannot understand
+	// or finds conflicting comments in multiple source files.
+	// See golang.org/s/go14customimport for more information.
+	ImportComment
+)
+
+// A Package describes the Go package found in a directory.
+type Package struct {
+	Dir           string   // directory containing package sources
+	Name          string   // package name
+	ImportComment string   // path in import comment on package statement
+	Doc           string   // documentation synopsis
+	ImportPath    string   // import path of package ("" if unknown)
+	Root          string   // root of Go tree where this package lives
+	SrcRoot       string   // package source root directory ("" if unknown)
+	PkgRoot       string   // package install root directory ("" if unknown)
+	BinDir        string   // command install directory ("" if unknown)
+	Goroot        bool     // package found in Go root
+	PkgObj        string   // installed .a file
+	AllTags       []string // tags that can influence file selection in this directory
+	ConflictDir   string   // this directory shadows Dir in $GOPATH
+
+	// Source files
+	GoFiles        []string // .go source files (excluding CgoFiles, TestGoFiles, XTestGoFiles)
+	CgoFiles       []string // .go source files that import "C"
+	IgnoredGoFiles []string // .go source files ignored for this build
+	CFiles         []string // .c source files
+	CXXFiles       []string // .cc, .cpp and .cxx source files
+	MFiles         []string // .m (Objective-C) source files
+	HFiles         []string // .h, .hh, .hpp and .hxx source files
+	SFiles         []string // .s source files
+	SwigFiles      []string // .swig files
+	SwigCXXFiles   []string // .swigcxx files
+	SysoFiles      []string // .syso system object files to add to archive
+
+	// Cgo directives
+	CgoCFLAGS    []string // Cgo CFLAGS directives
+	CgoCPPFLAGS  []string // Cgo CPPFLAGS directives
+	CgoCXXFLAGS  []string // Cgo CXXFLAGS directives
+	CgoLDFLAGS   []string // Cgo LDFLAGS directives
+	CgoPkgConfig []string // Cgo pkg-config directives
+
+	// Dependency information
+	Imports   []string                    // imports from GoFiles, CgoFiles
+	ImportPos map[string][]token.Position // line information for Imports
+
+	// Test information
+	TestGoFiles    []string                    // _test.go files in package
+	TestImports    []string                    // imports from TestGoFiles
+	TestImportPos  map[string][]token.Position // line information for TestImports
+	XTestGoFiles   []string                    // _test.go files outside package
+	XTestImports   []string                    // imports from XTestGoFiles
+	XTestImportPos map[string][]token.Position // line information for XTestImports
+}
+
+// IsCommand reports whether the package is considered a
+// command to be installed (not just a library).
+// Packages named "main" are treated as commands.
+func (p *Package) IsCommand() bool {
+	return p.Name == "main"
+}
+
+// ImportDir is like Import but processes the Go package found in
+// the named directory.
+func (ctxt *Context) ImportDir(dir string, mode ImportMode) (*Package, error) {
+	return ctxt.Import(".", dir, mode)
+}
+
+// NoGoError is the error used by Import to describe a directory
+// containing no buildable Go source files. (It may still contain
+// test files, files hidden by build tags, and so on.)
+type NoGoError struct {
+	Dir string
+}
+
+func (e *NoGoError) Error() string {
+	return "no buildable Go source files in " + e.Dir
+}
+
+// MultiplePackageError describes a directory containing
+// multiple buildable Go source files for multiple packages.
+type MultiplePackageError struct {
+	Dir      string   // directory containing files
+	Packages []string // package names found
+	Files    []string // corresponding files: Files[i] declares package Packages[i]
+}
+
+func (e *MultiplePackageError) Error() string {
+	// Error string limited to two entries for compatibility.
+	return fmt.Sprintf("found packages %s (%s) and %s (%s) in %s", e.Packages[0], e.Files[0], e.Packages[1], e.Files[1], e.Dir)
+}
+
+func nameExt(name string) string {
+	i := strings.LastIndex(name, ".")
+	if i < 0 {
+		return ""
+	}
+	return name[i:]
+}
+
+// Import returns details about the Go package named by the import path,
+// interpreting local import paths relative to the srcDir directory.
+// If the path is a local import path naming a package that can be imported
+// using a standard import path, the returned package will set p.ImportPath
+// to that path.
+//
+// In the directory containing the package, .go, .c, .h, and .s files are
+// considered part of the package except for:
+//
+//	- .go files in package documentation
+//	- files starting with _ or . (likely editor temporary files)
+//	- files with build constraints not satisfied by the context
+//
+// If an error occurs, Import returns a non-nil error and a non-nil
+// *Package containing partial information.
+//
+func (ctxt *Context) Import(path string, srcDir string, mode ImportMode) (*Package, error) {
+	p := &Package{
+		ImportPath: path,
+	}
+	if path == "" {
+		return p, fmt.Errorf("import %q: invalid import path", path)
+	}
+
+	var pkga string
+	var pkgerr error
+	switch ctxt.Compiler {
+	case "gccgo":
+		dir, elem := pathpkg.Split(p.ImportPath)
+		pkga = "pkg/gccgo_" + ctxt.GOOS + "_" + ctxt.GOARCH + "/" + dir + "lib" + elem + ".a"
+	case "gc":
+		suffix := ""
+		if ctxt.InstallSuffix != "" {
+			suffix = "_" + ctxt.InstallSuffix
+		}
+		pkga = "pkg/" + ctxt.GOOS + "_" + ctxt.GOARCH + suffix + "/" + p.ImportPath + ".a"
+	default:
+		// Save error for end of function.
+		pkgerr = fmt.Errorf("import %q: unknown compiler %q", path, ctxt.Compiler)
+	}
+
+	binaryOnly := false
+	if IsLocalImport(path) {
+		pkga = "" // local imports have no installed path
+		if srcDir == "" {
+			return p, fmt.Errorf("import %q: import relative to unknown directory", path)
+		}
+		if !ctxt.isAbsPath(path) {
+			p.Dir = ctxt.joinPath(srcDir, path)
+		}
+		// Determine canonical import path, if any.
+		if ctxt.GOROOT != "" {
+			root := ctxt.joinPath(ctxt.GOROOT, "src")
+			if sub, ok := ctxt.hasSubdir(root, p.Dir); ok {
+				p.Goroot = true
+				p.ImportPath = sub
+				p.Root = ctxt.GOROOT
+				goto Found
+			}
+		}
+		all := ctxt.gopath()
+		for i, root := range all {
+			rootsrc := ctxt.joinPath(root, "src")
+			if sub, ok := ctxt.hasSubdir(rootsrc, p.Dir); ok {
+				// We found a potential import path for dir,
+				// but check that using it wouldn't find something
+				// else first.
+				if ctxt.GOROOT != "" {
+					if dir := ctxt.joinPath(ctxt.GOROOT, "src", sub); ctxt.isDir(dir) {
+						p.ConflictDir = dir
+						goto Found
+					}
+				}
+				for _, earlyRoot := range all[:i] {
+					if dir := ctxt.joinPath(earlyRoot, "src", sub); ctxt.isDir(dir) {
+						p.ConflictDir = dir
+						goto Found
+					}
+				}
+
+				// sub would not name some other directory instead of this one.
+				// Record it.
+				p.ImportPath = sub
+				p.Root = root
+				goto Found
+			}
+		}
+		// It's okay that we didn't find a root containing dir.
+		// Keep going with the information we have.
+	} else {
+		if strings.HasPrefix(path, "/") {
+			return p, fmt.Errorf("import %q: cannot import absolute path", path)
+		}
+
+		// tried records the location of unsuccessful package lookups
+		var tried struct {
+			goroot string
+			gopath []string
+		}
+
+		// Determine directory from import path.
+		if ctxt.GOROOT != "" {
+			dir := ctxt.joinPath(ctxt.GOROOT, "src", path)
+			isDir := ctxt.isDir(dir)
+			binaryOnly = !isDir && mode&AllowBinary != 0 && pkga != "" && ctxt.isFile(ctxt.joinPath(ctxt.GOROOT, pkga))
+			if isDir || binaryOnly {
+				p.Dir = dir
+				p.Goroot = true
+				p.Root = ctxt.GOROOT
+				goto Found
+			}
+			tried.goroot = dir
+		}
+		for _, root := range ctxt.gopath() {
+			dir := ctxt.joinPath(root, "src", path)
+			isDir := ctxt.isDir(dir)
+			binaryOnly = !isDir && mode&AllowBinary != 0 && pkga != "" && ctxt.isFile(ctxt.joinPath(root, pkga))
+			if isDir || binaryOnly {
+				p.Dir = dir
+				p.Root = root
+				goto Found
+			}
+			tried.gopath = append(tried.gopath, dir)
+		}
+
+		// package was not found
+		var paths []string
+		if tried.goroot != "" {
+			paths = append(paths, fmt.Sprintf("\t%s (from $GOROOT)", tried.goroot))
+		} else {
+			paths = append(paths, "\t($GOROOT not set)")
+		}
+		var i int
+		var format = "\t%s (from $GOPATH)"
+		for ; i < len(tried.gopath); i++ {
+			if i > 0 {
+				format = "\t%s"
+			}
+			paths = append(paths, fmt.Sprintf(format, tried.gopath[i]))
+		}
+		if i == 0 {
+			paths = append(paths, "\t($GOPATH not set)")
+		}
+		return p, fmt.Errorf("cannot find package %q in any of:\n%s", path, strings.Join(paths, "\n"))
+	}
+
+Found:
+	if p.Root != "" {
+		p.SrcRoot = ctxt.joinPath(p.Root, "src")
+		p.PkgRoot = ctxt.joinPath(p.Root, "pkg")
+		p.BinDir = ctxt.joinPath(p.Root, "bin")
+		if pkga != "" {
+			p.PkgObj = ctxt.joinPath(p.Root, pkga)
+		}
+	}
+
+	if mode&FindOnly != 0 {
+		return p, pkgerr
+	}
+	if binaryOnly && (mode&AllowBinary) != 0 {
+		return p, pkgerr
+	}
+
+	dirs, err := ctxt.readDir(p.Dir)
+	if err != nil {
+		return p, err
+	}
+
+	var Sfiles []string // files with ".S" (capital S)
+	var firstFile, firstCommentFile string
+	imported := make(map[string][]token.Position)
+	testImported := make(map[string][]token.Position)
+	xTestImported := make(map[string][]token.Position)
+	allTags := make(map[string]bool)
+	fset := token.NewFileSet()
+	for _, d := range dirs {
+		if d.IsDir() {
+			continue
+		}
+
+		name := d.Name()
+		ext := nameExt(name)
+
+		match, data, filename, err := ctxt.matchFile(p.Dir, name, true, allTags)
+		if err != nil {
+			return p, err
+		}
+		if !match {
+			if ext == ".go" {
+				p.IgnoredGoFiles = append(p.IgnoredGoFiles, name)
+			}
+			continue
+		}
+
+		// Going to save the file.  For non-Go files, can stop here.
+		switch ext {
+		case ".c":
+			p.CFiles = append(p.CFiles, name)
+			continue
+		case ".cc", ".cpp", ".cxx":
+			p.CXXFiles = append(p.CXXFiles, name)
+			continue
+		case ".m":
+			p.MFiles = append(p.MFiles, name)
+			continue
+		case ".h", ".hh", ".hpp", ".hxx":
+			p.HFiles = append(p.HFiles, name)
+			continue
+		case ".s":
+			p.SFiles = append(p.SFiles, name)
+			continue
+		case ".S":
+			Sfiles = append(Sfiles, name)
+			continue
+		case ".swig":
+			p.SwigFiles = append(p.SwigFiles, name)
+			continue
+		case ".swigcxx":
+			p.SwigCXXFiles = append(p.SwigCXXFiles, name)
+			continue
+		case ".syso":
+			// binary objects to add to package archive
+			// Likely of the form foo_windows.syso, but
+			// the name was vetted above with goodOSArchFile.
+			p.SysoFiles = append(p.SysoFiles, name)
+			continue
+		}
+
+		pf, err := parser.ParseFile(fset, filename, data, parser.ImportsOnly|parser.ParseComments)
+		if err != nil {
+			return p, err
+		}
+
+		pkg := pf.Name.Name
+		if pkg == "documentation" {
+			p.IgnoredGoFiles = append(p.IgnoredGoFiles, name)
+			continue
+		}
+
+		isTest := strings.HasSuffix(name, "_test.go")
+		isXTest := false
+		if isTest && strings.HasSuffix(pkg, "_test") {
+			isXTest = true
+			pkg = pkg[:len(pkg)-len("_test")]
+		}
+
+		if p.Name == "" {
+			p.Name = pkg
+			firstFile = name
+		} else if pkg != p.Name {
+			return p, &MultiplePackageError{p.Dir, []string{firstFile, name}, []string{p.Name, pkg}}
+		}
+		if pf.Doc != nil && p.Doc == "" {
+			p.Doc = doc.Synopsis(pf.Doc.Text())
+		}
+
+		if mode&ImportComment != 0 {
+			qcom, line := findImportComment(data)
+			if line != 0 {
+				com, err := strconv.Unquote(qcom)
+				if err != nil {
+					return p, fmt.Errorf("%s:%d: cannot parse import comment", filename, line)
+				}
+				if p.ImportComment == "" {
+					p.ImportComment = com
+					firstCommentFile = name
+				} else if p.ImportComment != com {
+					return p, fmt.Errorf("found import comments %q (%s) and %q (%s) in %s", p.ImportComment, firstCommentFile, com, name, p.Dir)
+				}
+			}
+		}
+
+		// Record imports and information about cgo.
+		isCgo := false
+		for _, decl := range pf.Decls {
+			d, ok := decl.(*ast.GenDecl)
+			if !ok {
+				continue
+			}
+			for _, dspec := range d.Specs {
+				spec, ok := dspec.(*ast.ImportSpec)
+				if !ok {
+					continue
+				}
+				quoted := spec.Path.Value
+				path, err := strconv.Unquote(quoted)
+				if err != nil {
+					log.Panicf("%s: parser returned invalid quoted string: <%s>", filename, quoted)
+				}
+				if isXTest {
+					xTestImported[path] = append(xTestImported[path], fset.Position(spec.Pos()))
+				} else if isTest {
+					testImported[path] = append(testImported[path], fset.Position(spec.Pos()))
+				} else {
+					imported[path] = append(imported[path], fset.Position(spec.Pos()))
+				}
+				if path == "C" {
+					if isTest {
+						return p, fmt.Errorf("use of cgo in test %s not supported", filename)
+					}
+					cg := spec.Doc
+					if cg == nil && len(d.Specs) == 1 {
+						cg = d.Doc
+					}
+					if cg != nil {
+						if err := ctxt.saveCgo(filename, p, cg); err != nil {
+							return p, err
+						}
+					}
+					isCgo = true
+				}
+			}
+		}
+		if isCgo {
+			allTags["cgo"] = true
+			if ctxt.CgoEnabled {
+				p.CgoFiles = append(p.CgoFiles, name)
+			} else {
+				p.IgnoredGoFiles = append(p.IgnoredGoFiles, name)
+			}
+		} else if isXTest {
+			p.XTestGoFiles = append(p.XTestGoFiles, name)
+		} else if isTest {
+			p.TestGoFiles = append(p.TestGoFiles, name)
+		} else {
+			p.GoFiles = append(p.GoFiles, name)
+		}
+	}
+	if len(p.GoFiles)+len(p.CgoFiles)+len(p.TestGoFiles)+len(p.XTestGoFiles) == 0 {
+		return p, &NoGoError{p.Dir}
+	}
+
+	for tag := range allTags {
+		p.AllTags = append(p.AllTags, tag)
+	}
+	sort.Strings(p.AllTags)
+
+	p.Imports, p.ImportPos = cleanImports(imported)
+	p.TestImports, p.TestImportPos = cleanImports(testImported)
+	p.XTestImports, p.XTestImportPos = cleanImports(xTestImported)
+
+	// add the .S files only if we are using cgo
+	// (which means gcc will compile them).
+	// The standard assemblers expect .s files.
+	if len(p.CgoFiles) > 0 {
+		p.SFiles = append(p.SFiles, Sfiles...)
+		sort.Strings(p.SFiles)
+	}
+
+	return p, pkgerr
+}
+
+func findImportComment(data []byte) (s string, line int) {
+	// expect keyword package
+	word, data := parseWord(data)
+	if string(word) != "package" {
+		return "", 0
+	}
+
+	// expect package name
+	_, data = parseWord(data)
+
+	// now ready for import comment, a // or /* */ comment
+	// beginning and ending on the current line.
+	for len(data) > 0 && (data[0] == ' ' || data[0] == '\t' || data[0] == '\r') {
+		data = data[1:]
+	}
+
+	var comment []byte
+	switch {
+	case bytes.HasPrefix(data, slashSlash):
+		i := bytes.Index(data, newline)
+		if i < 0 {
+			i = len(data)
+		}
+		comment = data[2:i]
+	case bytes.HasPrefix(data, slashStar):
+		data = data[2:]
+		i := bytes.Index(data, starSlash)
+		if i < 0 {
+			// malformed comment
+			return "", 0
+		}
+		comment = data[:i]
+		if bytes.Contains(comment, newline) {
+			return "", 0
+		}
+	}
+	comment = bytes.TrimSpace(comment)
+
+	// split comment into `import`, `"pkg"`
+	word, arg := parseWord(comment)
+	if string(word) != "import" {
+		return "", 0
+	}
+
+	line = 1 + bytes.Count(data[:cap(data)-cap(arg)], newline)
+	return strings.TrimSpace(string(arg)), line
+}
+
+var (
+	slashSlash = []byte("//")
+	slashStar  = []byte("/*")
+	starSlash  = []byte("*/")
+	newline    = []byte("\n")
+)
+
+// skipSpaceOrComment returns data with any leading spaces or comments removed.
+func skipSpaceOrComment(data []byte) []byte {
+	for len(data) > 0 {
+		switch data[0] {
+		case ' ', '\t', '\r', '\n':
+			data = data[1:]
+			continue
+		case '/':
+			if bytes.HasPrefix(data, slashSlash) {
+				i := bytes.Index(data, newline)
+				if i < 0 {
+					return nil
+				}
+				data = data[i+1:]
+				continue
+			}
+			if bytes.HasPrefix(data, slashStar) {
+				data = data[2:]
+				i := bytes.Index(data, starSlash)
+				if i < 0 {
+					return nil
+				}
+				data = data[i+2:]
+				continue
+			}
+		}
+		break
+	}
+	return data
+}
+
+// parseWord skips any leading spaces or comments in data
+// and then parses the beginning of data as an identifier or keyword,
+// returning that word and what remains after the word.
+func parseWord(data []byte) (word, rest []byte) {
+	data = skipSpaceOrComment(data)
+
+	// Parse past leading word characters.
+	rest = data
+	for {
+		r, size := utf8.DecodeRune(rest)
+		if unicode.IsLetter(r) || '0' <= r && r <= '9' || r == '_' {
+			rest = rest[size:]
+			continue
+		}
+		break
+	}
+
+	word = data[:len(data)-len(rest)]
+	if len(word) == 0 {
+		return nil, nil
+	}
+
+	return word, rest
+}
+
+// MatchFile reports whether the file with the given name in the given directory
+// matches the context and would be included in a Package created by ImportDir
+// of that directory.
+//
+// MatchFile considers the name of the file and may use ctxt.OpenFile to
+// read some or all of the file's content.
+func (ctxt *Context) MatchFile(dir, name string) (match bool, err error) {
+	match, _, _, err = ctxt.matchFile(dir, name, false, nil)
+	return
+}
+
+// matchFile determines whether the file with the given name in the given directory
+// should be included in the package being constructed.
+// It returns the data read from the file.
+// If returnImports is true and name denotes a Go program, matchFile reads
+// until the end of the imports (and returns that data) even though it only
+// considers text until the first non-comment.
+// If allTags is non-nil, matchFile records any encountered build tag
+// by setting allTags[tag] = true.
+func (ctxt *Context) matchFile(dir, name string, returnImports bool, allTags map[string]bool) (match bool, data []byte, filename string, err error) {
+	if strings.HasPrefix(name, "_") ||
+		strings.HasPrefix(name, ".") {
+		return
+	}
+
+	i := strings.LastIndex(name, ".")
+	if i < 0 {
+		i = len(name)
+	}
+	ext := name[i:]
+
+	if !ctxt.goodOSArchFile(name, allTags) && !ctxt.UseAllFiles {
+		return
+	}
+
+	switch ext {
+	case ".go", ".c", ".cc", ".cxx", ".cpp", ".m", ".s", ".h", ".hh", ".hpp", ".hxx", ".S", ".swig", ".swigcxx":
+		// tentatively okay - read to make sure
+	case ".syso":
+		// binary, no reading
+		match = true
+		return
+	default:
+		// skip
+		return
+	}
+
+	filename = ctxt.joinPath(dir, name)
+	f, err := ctxt.openFile(filename)
+	if err != nil {
+		return
+	}
+
+	if strings.HasSuffix(filename, ".go") {
+		data, err = readImports(f, false)
+	} else {
+		data, err = readComments(f)
+	}
+	f.Close()
+	if err != nil {
+		err = fmt.Errorf("read %s: %v", filename, err)
+		return
+	}
+
+	// Look for +build comments to accept or reject the file.
+	if !ctxt.shouldBuild(data, allTags) && !ctxt.UseAllFiles {
+		return
+	}
+
+	match = true
+	return
+}
+
+func cleanImports(m map[string][]token.Position) ([]string, map[string][]token.Position) {
+	all := make([]string, 0, len(m))
+	for path := range m {
+		all = append(all, path)
+	}
+	sort.Strings(all)
+	return all, m
+}
+
+// Import is shorthand for Default.Import.
+func Import(path, srcDir string, mode ImportMode) (*Package, error) {
+	return Default.Import(path, srcDir, mode)
+}
+
+// ImportDir is shorthand for Default.ImportDir.
+func ImportDir(dir string, mode ImportMode) (*Package, error) {
+	return Default.ImportDir(dir, mode)
+}
+
+var slashslash = []byte("//")
+
+// shouldBuild reports whether it is okay to use this file,
+// The rule is that in the file's leading run of // comments
+// and blank lines, which must be followed by a blank line
+// (to avoid including a Go package clause doc comment),
+// lines beginning with '// +build' are taken as build directives.
+//
+// The file is accepted only if each such line lists something
+// matching the file.  For example:
+//
+//	// +build windows linux
+//
+// marks the file as applicable only on Windows and Linux.
+//
+func (ctxt *Context) shouldBuild(content []byte, allTags map[string]bool) bool {
+	// Pass 1. Identify leading run of // comments and blank lines,
+	// which must be followed by a blank line.
+	end := 0
+	p := content
+	for len(p) > 0 {
+		line := p
+		if i := bytes.IndexByte(line, '\n'); i >= 0 {
+			line, p = line[:i], p[i+1:]
+		} else {
+			p = p[len(p):]
+		}
+		line = bytes.TrimSpace(line)
+		if len(line) == 0 { // Blank line
+			end = len(content) - len(p)
+			continue
+		}
+		if !bytes.HasPrefix(line, slashslash) { // Not comment line
+			break
+		}
+	}
+	content = content[:end]
+
+	// Pass 2.  Process each line in the run.
+	p = content
+	allok := true
+	for len(p) > 0 {
+		line := p
+		if i := bytes.IndexByte(line, '\n'); i >= 0 {
+			line, p = line[:i], p[i+1:]
+		} else {
+			p = p[len(p):]
+		}
+		line = bytes.TrimSpace(line)
+		if bytes.HasPrefix(line, slashslash) {
+			line = bytes.TrimSpace(line[len(slashslash):])
+			if len(line) > 0 && line[0] == '+' {
+				// Looks like a comment +line.
+				f := strings.Fields(string(line))
+				if f[0] == "+build" {
+					ok := false
+					for _, tok := range f[1:] {
+						if ctxt.match(tok, allTags) {
+							ok = true
+						}
+					}
+					if !ok {
+						allok = false
+					}
+				}
+			}
+		}
+	}
+
+	return allok
+}
+
+// saveCgo saves the information from the #cgo lines in the import "C" comment.
+// These lines set CFLAGS, CPPFLAGS, CXXFLAGS and LDFLAGS and pkg-config directives
+// that affect the way cgo's C code is built.
+//
+// TODO(rsc): This duplicates code in cgo.
+// Once the dust settles, remove this code from cgo.
+func (ctxt *Context) saveCgo(filename string, di *Package, cg *ast.CommentGroup) error {
+	text := cg.Text()
+	for _, line := range strings.Split(text, "\n") {
+		orig := line
+
+		// Line is
+		//	#cgo [GOOS/GOARCH...] LDFLAGS: stuff
+		//
+		line = strings.TrimSpace(line)
+		if len(line) < 5 || line[:4] != "#cgo" || (line[4] != ' ' && line[4] != '\t') {
+			continue
+		}
+
+		// Split at colon.
+		line = strings.TrimSpace(line[4:])
+		i := strings.Index(line, ":")
+		if i < 0 {
+			return fmt.Errorf("%s: invalid #cgo line: %s", filename, orig)
+		}
+		line, argstr := line[:i], line[i+1:]
+
+		// Parse GOOS/GOARCH stuff.
+		f := strings.Fields(line)
+		if len(f) < 1 {
+			return fmt.Errorf("%s: invalid #cgo line: %s", filename, orig)
+		}
+
+		cond, verb := f[:len(f)-1], f[len(f)-1]
+		if len(cond) > 0 {
+			ok := false
+			for _, c := range cond {
+				if ctxt.match(c, nil) {
+					ok = true
+					break
+				}
+			}
+			if !ok {
+				continue
+			}
+		}
+
+		args, err := splitQuoted(argstr)
+		if err != nil {
+			return fmt.Errorf("%s: invalid #cgo line: %s", filename, orig)
+		}
+		for _, arg := range args {
+			if !safeCgoName(arg) {
+				return fmt.Errorf("%s: malformed #cgo argument: %s", filename, arg)
+			}
+		}
+
+		switch verb {
+		case "CFLAGS":
+			di.CgoCFLAGS = append(di.CgoCFLAGS, args...)
+		case "CPPFLAGS":
+			di.CgoCPPFLAGS = append(di.CgoCPPFLAGS, args...)
+		case "CXXFLAGS":
+			di.CgoCXXFLAGS = append(di.CgoCXXFLAGS, args...)
+		case "LDFLAGS":
+			di.CgoLDFLAGS = append(di.CgoLDFLAGS, args...)
+		case "pkg-config":
+			di.CgoPkgConfig = append(di.CgoPkgConfig, args...)
+		default:
+			return fmt.Errorf("%s: invalid #cgo verb: %s", filename, orig)
+		}
+	}
+	return nil
+}
+
+// NOTE: $ is not safe for the shell, but it is allowed here because of linker options like -Wl,$ORIGIN.
+// We never pass these arguments to a shell (just to programs we construct argv for), so this should be okay.
+// See golang.org/issue/6038.
+var safeBytes = []byte("+-.,/0123456789=ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz:$")
+
+func safeCgoName(s string) bool {
+	if s == "" {
+		return false
+	}
+	for i := 0; i < len(s); i++ {
+		if c := s[i]; c < 0x80 && bytes.IndexByte(safeBytes, c) < 0 {
+			return false
+		}
+	}
+	return true
+}
+
+// splitQuoted splits the string s around each instance of one or more consecutive
+// white space characters while taking into account quotes and escaping, and
+// returns an array of substrings of s or an empty list if s contains only white space.
+// Single quotes and double quotes are recognized to prevent splitting within the
+// quoted region, and are removed from the resulting substrings. If a quote in s
+// isn't closed err will be set and r will have the unclosed argument as the
+// last element.  The backslash is used for escaping.
+//
+// For example, the following string:
+//
+//     a b:"c d" 'e''f'  "g\""
+//
+// Would be parsed as:
+//
+//     []string{"a", "b:c d", "ef", `g"`}
+//
+func splitQuoted(s string) (r []string, err error) {
+	var args []string
+	arg := make([]rune, len(s))
+	escaped := false
+	quoted := false
+	quote := '\x00'
+	i := 0
+	for _, rune := range s {
+		switch {
+		case escaped:
+			escaped = false
+		case rune == '\\':
+			escaped = true
+			continue
+		case quote != '\x00':
+			if rune == quote {
+				quote = '\x00'
+				continue
+			}
+		case rune == '"' || rune == '\'':
+			quoted = true
+			quote = rune
+			continue
+		case unicode.IsSpace(rune):
+			if quoted || i > 0 {
+				quoted = false
+				args = append(args, string(arg[:i]))
+				i = 0
+			}
+			continue
+		}
+		arg[i] = rune
+		i++
+	}
+	if quoted || i > 0 {
+		args = append(args, string(arg[:i]))
+	}
+	if quote != 0 {
+		err = errors.New("unclosed quote")
+	} else if escaped {
+		err = errors.New("unfinished escaping")
+	}
+	return args, err
+}
+
+// match returns true if the name is one of:
+//
+//	$GOOS
+//	$GOARCH
+//	cgo (if cgo is enabled)
+//	!cgo (if cgo is disabled)
+//	ctxt.Compiler
+//	!ctxt.Compiler
+//	tag (if tag is listed in ctxt.BuildTags or ctxt.ReleaseTags)
+//	!tag (if tag is not listed in ctxt.BuildTags or ctxt.ReleaseTags)
+//	a comma-separated list of any of these
+//
+func (ctxt *Context) match(name string, allTags map[string]bool) bool {
+	if name == "" {
+		if allTags != nil {
+			allTags[name] = true
+		}
+		return false
+	}
+	if i := strings.Index(name, ","); i >= 0 {
+		// comma-separated list
+		ok1 := ctxt.match(name[:i], allTags)
+		ok2 := ctxt.match(name[i+1:], allTags)
+		return ok1 && ok2
+	}
+	if strings.HasPrefix(name, "!!") { // bad syntax, reject always
+		return false
+	}
+	if strings.HasPrefix(name, "!") { // negation
+		return len(name) > 1 && !ctxt.match(name[1:], allTags)
+	}
+
+	if allTags != nil {
+		allTags[name] = true
+	}
+
+	// Tags must be letters, digits, underscores or dots.
+	// Unlike in Go identifiers, all digits are fine (e.g., "386").
+	for _, c := range name {
+		if !unicode.IsLetter(c) && !unicode.IsDigit(c) && c != '_' && c != '.' {
+			return false
+		}
+	}
+
+	// special tags
+	if ctxt.CgoEnabled && name == "cgo" {
+		return true
+	}
+	if name == ctxt.GOOS || name == ctxt.GOARCH || name == ctxt.Compiler {
+		return true
+	}
+	if ctxt.GOOS == "android" && name == "linux" {
+		return true
+	}
+
+	// other tags
+	for _, tag := range ctxt.BuildTags {
+		if tag == name {
+			return true
+		}
+	}
+	for _, tag := range ctxt.ReleaseTags {
+		if tag == name {
+			return true
+		}
+	}
+
+	return false
+}
+
+// goodOSArchFile returns false if the name contains a $GOOS or $GOARCH
+// suffix which does not match the current system.
+// The recognized name formats are:
+//
+//     name_$(GOOS).*
+//     name_$(GOARCH).*
+//     name_$(GOOS)_$(GOARCH).*
+//     name_$(GOOS)_test.*
+//     name_$(GOARCH)_test.*
+//     name_$(GOOS)_$(GOARCH)_test.*
+//
+// An exception: if GOOS=android, then files with GOOS=linux are also matched.
+func (ctxt *Context) goodOSArchFile(name string, allTags map[string]bool) bool {
+	if dot := strings.Index(name, "."); dot != -1 {
+		name = name[:dot]
+	}
+
+	// Before Go 1.4, a file called "linux.go" would be equivalent to having a
+	// build tag "linux" in that file. For Go 1.4 and beyond, we require this
+	// auto-tagging to apply only to files with a non-empty prefix, so
+	// "foo_linux.go" is tagged but "linux.go" is not. This allows new operating
+	// sytems, such as android, to arrive without breaking existing code with
+	// innocuous source code in "android.go". The easiest fix: cut everything
+	// in the name before the initial _.
+	i := strings.Index(name, "_")
+	if i < 0 {
+		return true
+	}
+	name = name[i:] // ignore everything before first _
+
+	l := strings.Split(name, "_")
+	if n := len(l); n > 0 && l[n-1] == "test" {
+		l = l[:n-1]
+	}
+	n := len(l)
+	if n >= 2 && knownOS[l[n-2]] && knownArch[l[n-1]] {
+		if allTags != nil {
+			allTags[l[n-2]] = true
+			allTags[l[n-1]] = true
+		}
+		if l[n-1] != ctxt.GOARCH {
+			return false
+		}
+		if ctxt.GOOS == "android" && l[n-2] == "linux" {
+			return true
+		}
+		return l[n-2] == ctxt.GOOS
+	}
+	if n >= 1 && knownOS[l[n-1]] {
+		if allTags != nil {
+			allTags[l[n-1]] = true
+		}
+		if ctxt.GOOS == "android" && l[n-1] == "linux" {
+			return true
+		}
+		return l[n-1] == ctxt.GOOS
+	}
+	if n >= 1 && knownArch[l[n-1]] {
+		if allTags != nil {
+			allTags[l[n-1]] = true
+		}
+		return l[n-1] == ctxt.GOARCH
+	}
+	return true
+}
+
+var knownOS = make(map[string]bool)
+var knownArch = make(map[string]bool)
+
+func init() {
+	for _, v := range strings.Fields(goosList) {
+		knownOS[v] = true
+	}
+	for _, v := range strings.Fields(goarchList) {
+		knownArch[v] = true
+	}
+}
+
+// ToolDir is the directory containing build tools.
+var ToolDir = filepath.Join(runtime.GOROOT(), "pkg/tool/"+runtime.GOOS+"_"+runtime.GOARCH)
+
+// IsLocalImport reports whether the import path is
+// a local import path, like ".", "..", "./foo", or "../foo".
+func IsLocalImport(path string) bool {
+	return path == "." || path == ".." ||
+		strings.HasPrefix(path, "./") || strings.HasPrefix(path, "../")
+}
+
+// ArchChar returns the architecture character for the given goarch.
+// For example, ArchChar("amd64") returns "6".
+func ArchChar(goarch string) (string, error) {
+	switch goarch {
+	case "386":
+		return "8", nil
+	case "amd64", "amd64p32":
+		return "6", nil
+	case "arm":
+		return "5", nil
+	}
+	return "", errors.New("unsupported GOARCH " + goarch)
+}
diff --git a/src/go/build/build_test.go b/src/go/build/build_test.go
new file mode 100644
index 0000000..a40def0
--- /dev/null
+++ b/src/go/build/build_test.go
@@ -0,0 +1,224 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package build
+
+import (
+	"io"
+	"os"
+	"path/filepath"
+	"reflect"
+	"runtime"
+	"strings"
+	"testing"
+)
+
+func TestMatch(t *testing.T) {
+	ctxt := Default
+	what := "default"
+	match := func(tag string, want map[string]bool) {
+		m := make(map[string]bool)
+		if !ctxt.match(tag, m) {
+			t.Errorf("%s context should match %s, does not", what, tag)
+		}
+		if !reflect.DeepEqual(m, want) {
+			t.Errorf("%s tags = %v, want %v", tag, m, want)
+		}
+	}
+	nomatch := func(tag string, want map[string]bool) {
+		m := make(map[string]bool)
+		if ctxt.match(tag, m) {
+			t.Errorf("%s context should NOT match %s, does", what, tag)
+		}
+		if !reflect.DeepEqual(m, want) {
+			t.Errorf("%s tags = %v, want %v", tag, m, want)
+		}
+	}
+
+	match(runtime.GOOS+","+runtime.GOARCH, map[string]bool{runtime.GOOS: true, runtime.GOARCH: true})
+	match(runtime.GOOS+","+runtime.GOARCH+",!foo", map[string]bool{runtime.GOOS: true, runtime.GOARCH: true, "foo": true})
+	nomatch(runtime.GOOS+","+runtime.GOARCH+",foo", map[string]bool{runtime.GOOS: true, runtime.GOARCH: true, "foo": true})
+
+	what = "modified"
+	ctxt.BuildTags = []string{"foo"}
+	match(runtime.GOOS+","+runtime.GOARCH, map[string]bool{runtime.GOOS: true, runtime.GOARCH: true})
+	match(runtime.GOOS+","+runtime.GOARCH+",foo", map[string]bool{runtime.GOOS: true, runtime.GOARCH: true, "foo": true})
+	nomatch(runtime.GOOS+","+runtime.GOARCH+",!foo", map[string]bool{runtime.GOOS: true, runtime.GOARCH: true, "foo": true})
+	match(runtime.GOOS+","+runtime.GOARCH+",!bar", map[string]bool{runtime.GOOS: true, runtime.GOARCH: true, "bar": true})
+	nomatch(runtime.GOOS+","+runtime.GOARCH+",bar", map[string]bool{runtime.GOOS: true, runtime.GOARCH: true, "bar": true})
+	nomatch("!", map[string]bool{})
+}
+
+func TestDotSlashImport(t *testing.T) {
+	p, err := ImportDir("testdata/other", 0)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if len(p.Imports) != 1 || p.Imports[0] != "./file" {
+		t.Fatalf("testdata/other: Imports=%v, want [./file]", p.Imports)
+	}
+
+	p1, err := Import("./file", "testdata/other", 0)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if p1.Name != "file" {
+		t.Fatalf("./file: Name=%q, want %q", p1.Name, "file")
+	}
+	dir := filepath.Clean("testdata/other/file") // Clean to use \ on Windows
+	if p1.Dir != dir {
+		t.Fatalf("./file: Dir=%q, want %q", p1.Name, dir)
+	}
+}
+
+func TestEmptyImport(t *testing.T) {
+	p, err := Import("", Default.GOROOT, FindOnly)
+	if err == nil {
+		t.Fatal(`Import("") returned nil error.`)
+	}
+	if p == nil {
+		t.Fatal(`Import("") returned nil package.`)
+	}
+	if p.ImportPath != "" {
+		t.Fatalf("ImportPath=%q, want %q.", p.ImportPath, "")
+	}
+}
+
+func TestEmptyFolderImport(t *testing.T) {
+	_, err := Import(".", "testdata/empty", 0)
+	if _, ok := err.(*NoGoError); !ok {
+		t.Fatal(`Import("testdata/empty") did not return NoGoError.`)
+	}
+}
+
+func TestMultiplePackageImport(t *testing.T) {
+	_, err := Import(".", "testdata/multi", 0)
+	if _, ok := err.(*MultiplePackageError); !ok {
+		t.Fatal(`Import("testdata/multi") did not return MultiplePackageError.`)
+	}
+}
+
+func TestLocalDirectory(t *testing.T) {
+	cwd, err := os.Getwd()
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	p, err := ImportDir(cwd, 0)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if p.ImportPath != "go/build" {
+		t.Fatalf("ImportPath=%q, want %q", p.ImportPath, "go/build")
+	}
+}
+
+func TestShouldBuild(t *testing.T) {
+	const file1 = "// +build tag1\n\n" +
+		"package main\n"
+	want1 := map[string]bool{"tag1": true}
+
+	const file2 = "// +build cgo\n\n" +
+		"// This package implements parsing of tags like\n" +
+		"// +build tag1\n" +
+		"package build"
+	want2 := map[string]bool{"cgo": true}
+
+	const file3 = "// Copyright The Go Authors.\n\n" +
+		"package build\n\n" +
+		"// shouldBuild checks tags given by lines of the form\n" +
+		"// +build tag\n" +
+		"func shouldBuild(content []byte)\n"
+	want3 := map[string]bool{}
+
+	ctx := &Context{BuildTags: []string{"tag1"}}
+	m := map[string]bool{}
+	if !ctx.shouldBuild([]byte(file1), m) {
+		t.Errorf("shouldBuild(file1) = false, want true")
+	}
+	if !reflect.DeepEqual(m, want1) {
+		t.Errorf("shoudBuild(file1) tags = %v, want %v", m, want1)
+	}
+
+	m = map[string]bool{}
+	if ctx.shouldBuild([]byte(file2), m) {
+		t.Errorf("shouldBuild(file2) = true, want fakse")
+	}
+	if !reflect.DeepEqual(m, want2) {
+		t.Errorf("shoudBuild(file2) tags = %v, want %v", m, want2)
+	}
+
+	m = map[string]bool{}
+	ctx = &Context{BuildTags: nil}
+	if !ctx.shouldBuild([]byte(file3), m) {
+		t.Errorf("shouldBuild(file3) = false, want true")
+	}
+	if !reflect.DeepEqual(m, want3) {
+		t.Errorf("shoudBuild(file3) tags = %v, want %v", m, want3)
+	}
+}
+
+type readNopCloser struct {
+	io.Reader
+}
+
+func (r readNopCloser) Close() error {
+	return nil
+}
+
+var (
+	ctxtP9      = Context{GOARCH: "arm", GOOS: "plan9"}
+	ctxtAndroid = Context{GOARCH: "arm", GOOS: "android"}
+)
+
+var matchFileTests = []struct {
+	ctxt  Context
+	name  string
+	data  string
+	match bool
+}{
+	{ctxtP9, "foo_arm.go", "", true},
+	{ctxtP9, "foo1_arm.go", "// +build linux\n\npackage main\n", false},
+	{ctxtP9, "foo_darwin.go", "", false},
+	{ctxtP9, "foo.go", "", true},
+	{ctxtP9, "foo1.go", "// +build linux\n\npackage main\n", false},
+	{ctxtP9, "foo.badsuffix", "", false},
+	{ctxtAndroid, "foo_linux.go", "", true},
+	{ctxtAndroid, "foo_android.go", "", true},
+	{ctxtAndroid, "foo_plan9.go", "", false},
+	{ctxtAndroid, "android.go", "", true},
+	{ctxtAndroid, "plan9.go", "", true},
+	{ctxtAndroid, "plan9_test.go", "", true},
+	{ctxtAndroid, "arm.s", "", true},
+	{ctxtAndroid, "amd64.s", "", true},
+}
+
+func TestMatchFile(t *testing.T) {
+	for _, tt := range matchFileTests {
+		ctxt := tt.ctxt
+		ctxt.OpenFile = func(path string) (r io.ReadCloser, err error) {
+			if path != "x+"+tt.name {
+				t.Fatalf("OpenFile asked for %q, expected %q", path, "x+"+tt.name)
+			}
+			return &readNopCloser{strings.NewReader(tt.data)}, nil
+		}
+		ctxt.JoinPath = func(elem ...string) string {
+			return strings.Join(elem, "+")
+		}
+		match, err := ctxt.MatchFile("x", tt.name)
+		if match != tt.match || err != nil {
+			t.Fatalf("MatchFile(%q) = %v, %v, want %v, nil", tt.name, match, err, tt.match)
+		}
+	}
+}
+
+func TestImportCmd(t *testing.T) {
+	p, err := Import("cmd/internal/objfile", "", 0)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if !strings.HasSuffix(filepath.ToSlash(p.Dir), "src/cmd/internal/objfile") {
+		t.Fatalf("Import cmd/internal/objfile returned Dir=%q, want %q", filepath.ToSlash(p.Dir), ".../src/cmd/internal/objfile")
+	}
+}
diff --git a/src/go/build/deps_test.go b/src/go/build/deps_test.go
new file mode 100644
index 0000000..b74595e
--- /dev/null
+++ b/src/go/build/deps_test.go
@@ -0,0 +1,443 @@
+// Copyright 2012 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file exercises the import parser but also checks that
+// some low-level packages do not have new dependencies added.
+
+package build
+
+import (
+	"runtime"
+	"sort"
+	"testing"
+)
+
+// pkgDeps defines the expected dependencies between packages in
+// the Go source tree.  It is a statement of policy.
+// Changes should not be made to this map without prior discussion.
+//
+// The map contains two kinds of entries:
+// 1) Lower-case keys are standard import paths and list the
+// allowed imports in that package.
+// 2) Upper-case keys define aliases for package sets, which can then
+// be used as dependencies by other rules.
+//
+// DO NOT CHANGE THIS DATA TO FIX BUILDS.
+//
+var pkgDeps = map[string][]string{
+	// L0 is the lowest level, core, nearly unavoidable packages.
+	"errors":      {},
+	"io":          {"errors", "sync"},
+	"runtime":     {"unsafe"},
+	"sync":        {"runtime", "sync/atomic", "unsafe"},
+	"sync/atomic": {"unsafe"},
+	"unsafe":      {},
+
+	"L0": {
+		"errors",
+		"io",
+		"runtime",
+		"sync",
+		"sync/atomic",
+		"unsafe",
+	},
+
+	// L1 adds simple functions and strings processing,
+	// but not Unicode tables.
+	"math":          {"unsafe"},
+	"math/cmplx":    {"math"},
+	"math/rand":     {"L0", "math"},
+	"sort":          {},
+	"strconv":       {"L0", "unicode/utf8", "math"},
+	"unicode/utf16": {},
+	"unicode/utf8":  {},
+
+	"L1": {
+		"L0",
+		"math",
+		"math/cmplx",
+		"math/rand",
+		"sort",
+		"strconv",
+		"unicode/utf16",
+		"unicode/utf8",
+	},
+
+	// L2 adds Unicode and strings processing.
+	"bufio":   {"L0", "unicode/utf8", "bytes"},
+	"bytes":   {"L0", "unicode", "unicode/utf8"},
+	"path":    {"L0", "unicode/utf8", "strings"},
+	"strings": {"L0", "unicode", "unicode/utf8"},
+	"unicode": {},
+
+	"L2": {
+		"L1",
+		"bufio",
+		"bytes",
+		"path",
+		"strings",
+		"unicode",
+	},
+
+	// L3 adds reflection and some basic utility packages
+	// and interface definitions, but nothing that makes
+	// system calls.
+	"crypto":              {"L2", "hash"},          // interfaces
+	"crypto/cipher":       {"L2", "crypto/subtle"}, // interfaces
+	"crypto/subtle":       {},
+	"encoding/base32":     {"L2"},
+	"encoding/base64":     {"L2"},
+	"encoding/binary":     {"L2", "reflect"},
+	"hash":                {"L2"}, // interfaces
+	"hash/adler32":        {"L2", "hash"},
+	"hash/crc32":          {"L2", "hash"},
+	"hash/crc64":          {"L2", "hash"},
+	"hash/fnv":            {"L2", "hash"},
+	"image":               {"L2", "image/color"}, // interfaces
+	"image/color":         {"L2"},                // interfaces
+	"image/color/palette": {"L2", "image/color"},
+	"reflect":             {"L2"},
+
+	"L3": {
+		"L2",
+		"crypto",
+		"crypto/cipher",
+		"crypto/subtle",
+		"encoding/base32",
+		"encoding/base64",
+		"encoding/binary",
+		"hash",
+		"hash/adler32",
+		"hash/crc32",
+		"hash/crc64",
+		"hash/fnv",
+		"image",
+		"image/color",
+		"image/color/palette",
+		"reflect",
+	},
+
+	// End of linear dependency definitions.
+
+	// Operating system access.
+	"syscall":       {"L0", "unicode/utf16"},
+	"time":          {"L0", "syscall"},
+	"os":            {"L1", "os", "syscall", "time"},
+	"path/filepath": {"L2", "os", "syscall"},
+	"io/ioutil":     {"L2", "os", "path/filepath", "time"},
+	"os/exec":       {"L2", "os", "path/filepath", "syscall"},
+	"os/signal":     {"L2", "os", "syscall"},
+
+	// OS enables basic operating system functionality,
+	// but not direct use of package syscall, nor os/signal.
+	"OS": {
+		"io/ioutil",
+		"os",
+		"os/exec",
+		"path/filepath",
+		"time",
+	},
+
+	// Formatted I/O: few dependencies (L1) but we must add reflect.
+	"fmt": {"L1", "os", "reflect"},
+	"log": {"L1", "os", "fmt", "time"},
+
+	// Packages used by testing must be low-level (L2+fmt).
+	"regexp":         {"L2", "regexp/syntax"},
+	"regexp/syntax":  {"L2"},
+	"runtime/debug":  {"L2", "fmt", "io/ioutil", "os", "time"},
+	"runtime/pprof":  {"L2", "fmt", "text/tabwriter"},
+	"text/tabwriter": {"L2"},
+
+	"testing":        {"L2", "flag", "fmt", "os", "runtime/pprof", "time"},
+	"testing/iotest": {"L2", "log"},
+	"testing/quick":  {"L2", "flag", "fmt", "reflect"},
+
+	// L4 is defined as L3+fmt+log+time, because in general once
+	// you're using L3 packages, use of fmt, log, or time is not a big deal.
+	"L4": {
+		"L3",
+		"fmt",
+		"log",
+		"time",
+	},
+
+	// Go parser.
+	"go/ast":     {"L4", "OS", "go/scanner", "go/token"},
+	"go/doc":     {"L4", "go/ast", "go/token", "regexp", "text/template"},
+	"go/parser":  {"L4", "OS", "go/ast", "go/scanner", "go/token"},
+	"go/printer": {"L4", "OS", "go/ast", "go/scanner", "go/token", "text/tabwriter"},
+	"go/scanner": {"L4", "OS", "go/token"},
+	"go/token":   {"L4"},
+
+	"GOPARSER": {
+		"go/ast",
+		"go/doc",
+		"go/parser",
+		"go/printer",
+		"go/scanner",
+		"go/token",
+	},
+
+	// One of a kind.
+	"archive/tar":         {"L4", "OS", "syscall"},
+	"archive/zip":         {"L4", "OS", "compress/flate"},
+	"compress/bzip2":      {"L4"},
+	"compress/flate":      {"L4"},
+	"compress/gzip":       {"L4", "compress/flate"},
+	"compress/lzw":        {"L4"},
+	"compress/zlib":       {"L4", "compress/flate"},
+	"database/sql":        {"L4", "container/list", "database/sql/driver"},
+	"database/sql/driver": {"L4", "time"},
+	"debug/dwarf":         {"L4"},
+	"debug/elf":           {"L4", "OS", "debug/dwarf"},
+	"debug/gosym":         {"L4"},
+	"debug/macho":         {"L4", "OS", "debug/dwarf"},
+	"debug/pe":            {"L4", "OS", "debug/dwarf"},
+	"encoding":            {"L4"},
+	"encoding/ascii85":    {"L4"},
+	"encoding/asn1":       {"L4", "math/big"},
+	"encoding/csv":        {"L4"},
+	"encoding/gob":        {"L4", "OS", "encoding"},
+	"encoding/hex":        {"L4"},
+	"encoding/json":       {"L4", "encoding"},
+	"encoding/pem":        {"L4"},
+	"encoding/xml":        {"L4", "encoding"},
+	"flag":                {"L4", "OS"},
+	"go/build":            {"L4", "OS", "GOPARSER"},
+	"html":                {"L4"},
+	"image/draw":          {"L4"},
+	"image/gif":           {"L4", "compress/lzw", "image/color/palette", "image/draw"},
+	"image/jpeg":          {"L4"},
+	"image/png":           {"L4", "compress/zlib"},
+	"index/suffixarray":   {"L4", "regexp"},
+	"math/big":            {"L4"},
+	"mime":                {"L4", "OS", "syscall"},
+	"net/url":             {"L4"},
+	"text/scanner":        {"L4", "OS"},
+	"text/template/parse": {"L4"},
+
+	"html/template": {
+		"L4", "OS", "encoding/json", "html", "text/template",
+		"text/template/parse",
+	},
+	"text/template": {
+		"L4", "OS", "net/url", "text/template/parse",
+	},
+
+	// Cgo.
+	"runtime/cgo": {"L0", "C"},
+	"CGO":         {"C", "runtime/cgo"},
+
+	// Fake entry to satisfy the pseudo-import "C"
+	// that shows up in programs that use cgo.
+	"C": {},
+
+	// Plan 9 alone needs io/ioutil and os.
+	"os/user": {"L4", "CGO", "io/ioutil", "os", "syscall"},
+
+	// Basic networking.
+	// Because net must be used by any package that wants to
+	// do networking portably, it must have a small dependency set: just L1+basic os.
+	"net": {"L1", "CGO", "os", "syscall", "time"},
+
+	// NET enables use of basic network-related packages.
+	"NET": {
+		"net",
+		"mime",
+		"net/textproto",
+		"net/url",
+	},
+
+	// Uses of networking.
+	"log/syslog":    {"L4", "OS", "net"},
+	"net/mail":      {"L4", "NET", "OS"},
+	"net/textproto": {"L4", "OS", "net"},
+
+	// Core crypto.
+	"crypto/aes":    {"L3"},
+	"crypto/des":    {"L3"},
+	"crypto/hmac":   {"L3"},
+	"crypto/md5":    {"L3"},
+	"crypto/rc4":    {"L3"},
+	"crypto/sha1":   {"L3"},
+	"crypto/sha256": {"L3"},
+	"crypto/sha512": {"L3"},
+
+	"CRYPTO": {
+		"crypto/aes",
+		"crypto/des",
+		"crypto/hmac",
+		"crypto/md5",
+		"crypto/rc4",
+		"crypto/sha1",
+		"crypto/sha256",
+		"crypto/sha512",
+	},
+
+	// Random byte, number generation.
+	// This would be part of core crypto except that it imports
+	// math/big, which imports fmt.
+	"crypto/rand": {"L4", "CRYPTO", "OS", "math/big", "syscall", "internal/syscall"},
+
+	// Mathematical crypto: dependencies on fmt (L4) and math/big.
+	// We could avoid some of the fmt, but math/big imports fmt anyway.
+	"crypto/dsa":      {"L4", "CRYPTO", "math/big"},
+	"crypto/ecdsa":    {"L4", "CRYPTO", "crypto/elliptic", "math/big", "encoding/asn1"},
+	"crypto/elliptic": {"L4", "CRYPTO", "math/big"},
+	"crypto/rsa":      {"L4", "CRYPTO", "crypto/rand", "math/big"},
+
+	"CRYPTO-MATH": {
+		"CRYPTO",
+		"crypto/dsa",
+		"crypto/ecdsa",
+		"crypto/elliptic",
+		"crypto/rand",
+		"crypto/rsa",
+		"encoding/asn1",
+		"math/big",
+	},
+
+	// SSL/TLS.
+	"crypto/tls": {
+		"L4", "CRYPTO-MATH", "CGO", "OS",
+		"container/list", "crypto/x509", "encoding/pem", "net", "syscall",
+	},
+	"crypto/x509": {
+		"L4", "CRYPTO-MATH", "OS", "CGO",
+		"crypto/x509/pkix", "encoding/pem", "encoding/hex", "net", "syscall",
+	},
+	"crypto/x509/pkix": {"L4", "CRYPTO-MATH"},
+
+	// Simple net+crypto-aware packages.
+	"mime/multipart": {"L4", "OS", "mime", "crypto/rand", "net/textproto"},
+	"net/smtp":       {"L4", "CRYPTO", "NET", "crypto/tls"},
+
+	// HTTP, kingpin of dependencies.
+	"net/http": {
+		"L4", "NET", "OS",
+		"compress/gzip", "crypto/tls", "mime/multipart", "runtime/debug",
+		"net/http/internal",
+	},
+
+	// HTTP-using packages.
+	"expvar":            {"L4", "OS", "encoding/json", "net/http"},
+	"net/http/cgi":      {"L4", "NET", "OS", "crypto/tls", "net/http", "regexp"},
+	"net/http/fcgi":     {"L4", "NET", "OS", "net/http", "net/http/cgi"},
+	"net/http/httptest": {"L4", "NET", "OS", "crypto/tls", "flag", "net/http"},
+	"net/http/httputil": {"L4", "NET", "OS", "net/http", "net/http/internal"},
+	"net/http/pprof":    {"L4", "OS", "html/template", "net/http", "runtime/pprof"},
+	"net/rpc":           {"L4", "NET", "encoding/gob", "html/template", "net/http"},
+	"net/rpc/jsonrpc":   {"L4", "NET", "encoding/json", "net/rpc"},
+}
+
+// isMacro reports whether p is a package dependency macro
+// (uppercase name).
+func isMacro(p string) bool {
+	return 'A' <= p[0] && p[0] <= 'Z'
+}
+
+func allowed(pkg string) map[string]bool {
+	m := map[string]bool{}
+	var allow func(string)
+	allow = func(p string) {
+		if m[p] {
+			return
+		}
+		m[p] = true // set even for macros, to avoid loop on cycle
+
+		// Upper-case names are macro-expanded.
+		if isMacro(p) {
+			for _, pp := range pkgDeps[p] {
+				allow(pp)
+			}
+		}
+	}
+	for _, pp := range pkgDeps[pkg] {
+		allow(pp)
+	}
+	return m
+}
+
+var bools = []bool{false, true}
+var geese = []string{"android", "darwin", "dragonfly", "freebsd", "linux", "nacl", "netbsd", "openbsd", "plan9", "solaris", "windows"}
+var goarches = []string{"386", "amd64", "arm"}
+
+type osPkg struct {
+	goos, pkg string
+}
+
+// allowedErrors are the operating systems and packages known to contain errors
+// (currently just "no Go source files")
+var allowedErrors = map[osPkg]bool{
+	osPkg{"windows", "log/syslog"}: true,
+	osPkg{"plan9", "log/syslog"}:   true,
+}
+
+func TestDependencies(t *testing.T) {
+	if runtime.GOOS == "nacl" {
+		// NaCl tests run in a limited file system and we do not
+		// provide access to every source file.
+		t.Skip("skipping on NaCl")
+	}
+	var all []string
+
+	for k := range pkgDeps {
+		all = append(all, k)
+	}
+	sort.Strings(all)
+
+	ctxt := Default
+	test := func(mustImport bool) {
+		for _, pkg := range all {
+			if isMacro(pkg) {
+				continue
+			}
+			if pkg == "runtime/cgo" && !ctxt.CgoEnabled {
+				continue
+			}
+			p, err := ctxt.Import(pkg, "", 0)
+			if err != nil {
+				if allowedErrors[osPkg{ctxt.GOOS, pkg}] {
+					continue
+				}
+				if !ctxt.CgoEnabled && pkg == "runtime/cgo" {
+					continue
+				}
+				// Some of the combinations we try might not
+				// be reasonable (like arm,plan9,cgo), so ignore
+				// errors for the auto-generated combinations.
+				if !mustImport {
+					continue
+				}
+				t.Errorf("%s/%s/cgo=%v %v", ctxt.GOOS, ctxt.GOARCH, ctxt.CgoEnabled, err)
+				continue
+			}
+			ok := allowed(pkg)
+			var bad []string
+			for _, imp := range p.Imports {
+				if !ok[imp] {
+					bad = append(bad, imp)
+				}
+			}
+			if bad != nil {
+				t.Errorf("%s/%s/cgo=%v unexpected dependency: %s imports %v", ctxt.GOOS, ctxt.GOARCH, ctxt.CgoEnabled, pkg, bad)
+			}
+		}
+	}
+	test(true)
+
+	if testing.Short() {
+		t.Logf("skipping other systems")
+		return
+	}
+
+	for _, ctxt.GOOS = range geese {
+		for _, ctxt.GOARCH = range goarches {
+			for _, ctxt.CgoEnabled = range bools {
+				test(false)
+			}
+		}
+	}
+}
diff --git a/src/go/build/doc.go b/src/go/build/doc.go
new file mode 100644
index 0000000..75a827b
--- /dev/null
+++ b/src/go/build/doc.go
@@ -0,0 +1,139 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package build gathers information about Go packages.
+//
+// Go Path
+//
+// The Go path is a list of directory trees containing Go source code.
+// It is consulted to resolve imports that cannot be found in the standard
+// Go tree.  The default path is the value of the GOPATH environment
+// variable, interpreted as a path list appropriate to the operating system
+// (on Unix, the variable is a colon-separated string;
+// on Windows, a semicolon-separated string;
+// on Plan 9, a list).
+//
+// Each directory listed in the Go path must have a prescribed structure:
+//
+// The src/ directory holds source code.  The path below 'src' determines
+// the import path or executable name.
+//
+// The pkg/ directory holds installed package objects.
+// As in the Go tree, each target operating system and
+// architecture pair has its own subdirectory of pkg
+// (pkg/GOOS_GOARCH).
+//
+// If DIR is a directory listed in the Go path, a package with
+// source in DIR/src/foo/bar can be imported as "foo/bar" and
+// has its compiled form installed to "DIR/pkg/GOOS_GOARCH/foo/bar.a"
+// (or, for gccgo, "DIR/pkg/gccgo/foo/libbar.a").
+//
+// The bin/ directory holds compiled commands.
+// Each command is named for its source directory, but only
+// using the final element, not the entire path.  That is, the
+// command with source in DIR/src/foo/quux is installed into
+// DIR/bin/quux, not DIR/bin/foo/quux.  The foo/ is stripped
+// so that you can add DIR/bin to your PATH to get at the
+// installed commands.
+//
+// Here's an example directory layout:
+//
+//	GOPATH=/home/user/gocode
+//
+//	/home/user/gocode/
+//	    src/
+//	        foo/
+//	            bar/               (go code in package bar)
+//	                x.go
+//	            quux/              (go code in package main)
+//	                y.go
+//	    bin/
+//	        quux                   (installed command)
+//	    pkg/
+//	        linux_amd64/
+//	            foo/
+//	                bar.a          (installed package object)
+//
+// Build Constraints
+//
+// A build constraint, also known as a build tag, is a line comment that begins
+//
+//	// +build
+//
+// that lists the conditions under which a file should be included in the package.
+// Constraints may appear in any kind of source file (not just Go), but
+// they must appear near the top of the file, preceded
+// only by blank lines and other line comments. These rules mean that in Go
+// files a build constraint must appear before the package clause.
+//
+// To distinguish build constraints from package documentation, a series of
+// build constraints must be followed by a blank line.
+//
+// A build constraint is evaluated as the OR of space-separated options;
+// each option evaluates as the AND of its comma-separated terms;
+// and each term is an alphanumeric word or, preceded by !, its negation.
+// That is, the build constraint:
+//
+//	// +build linux,386 darwin,!cgo
+//
+// corresponds to the boolean formula:
+//
+//	(linux AND 386) OR (darwin AND (NOT cgo))
+//
+// A file may have multiple build constraints. The overall constraint is the AND
+// of the individual constraints. That is, the build constraints:
+//
+//	// +build linux darwin
+//	// +build 386
+//
+// corresponds to the boolean formula:
+//
+//	(linux OR darwin) AND 386
+//
+// During a particular build, the following words are satisfied:
+//
+//	- the target operating system, as spelled by runtime.GOOS
+//	- the target architecture, as spelled by runtime.GOARCH
+//	- the compiler being used, either "gc" or "gccgo"
+//	- "cgo", if ctxt.CgoEnabled is true
+//	- "go1.1", from Go version 1.1 onward
+//	- "go1.2", from Go version 1.2 onward
+//	- "go1.3", from Go version 1.3 onward
+//	- "go1.4", from Go version 1.4 onward
+//	- any additional words listed in ctxt.BuildTags
+//
+// If a file's name, after stripping the extension and a possible _test suffix,
+// matches any of the following patterns:
+//	*_GOOS
+// 	*_GOARCH
+// 	*_GOOS_GOARCH
+// (example: source_windows_amd64.go) where GOOS and GOARCH represent
+// any known operating system and architecture values respectively, then
+// the file is considered to have an implicit build constraint requiring
+// those terms.
+//
+// To keep a file from being considered for the build:
+//
+//	// +build ignore
+//
+// (any other unsatisfied word will work as well, but ``ignore'' is conventional.)
+//
+// To build a file only when using cgo, and only on Linux and OS X:
+//
+//	// +build linux,cgo darwin,cgo
+//
+// Such a file is usually paired with another file implementing the
+// default functionality for other systems, which in this case would
+// carry the constraint:
+//
+//	// +build !linux,!darwin !cgo
+//
+// Naming a file dns_windows.go will cause it to be included only when
+// building the package for Windows; similarly, math_386.s will be included
+// only when building the package for 32-bit x86.
+//
+// Using GOOS=android matches build tags and files as for GOOS=linux
+// in addition to android tags and files.
+//
+package build
diff --git a/src/pkg/go/build/read.go b/src/go/build/read.go
similarity index 100%
rename from src/pkg/go/build/read.go
rename to src/go/build/read.go
diff --git a/src/pkg/go/build/read_test.go b/src/go/build/read_test.go
similarity index 100%
rename from src/pkg/go/build/read_test.go
rename to src/go/build/read_test.go
diff --git a/src/go/build/syslist.go b/src/go/build/syslist.go
new file mode 100644
index 0000000..965f873
--- /dev/null
+++ b/src/go/build/syslist.go
@@ -0,0 +1,8 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package build
+
+const goosList = "android darwin dragonfly freebsd linux nacl netbsd openbsd plan9 solaris windows "
+const goarchList = "386 amd64 amd64p32 arm "
diff --git a/src/pkg/go/build/syslist_test.go b/src/go/build/syslist_test.go
similarity index 100%
rename from src/pkg/go/build/syslist_test.go
rename to src/go/build/syslist_test.go
diff --git a/src/go/build/testdata/empty/dummy b/src/go/build/testdata/empty/dummy
new file mode 100644
index 0000000..e69de29
diff --git a/src/go/build/testdata/multi/file.go b/src/go/build/testdata/multi/file.go
new file mode 100644
index 0000000..ee946eb
--- /dev/null
+++ b/src/go/build/testdata/multi/file.go
@@ -0,0 +1,5 @@
+// Test data - not compiled.
+
+package main
+
+func main() {}
diff --git a/src/go/build/testdata/multi/file_appengine.go b/src/go/build/testdata/multi/file_appengine.go
new file mode 100644
index 0000000..4ea31e7
--- /dev/null
+++ b/src/go/build/testdata/multi/file_appengine.go
@@ -0,0 +1,5 @@
+// Test data - not compiled.
+
+package test_package
+
+func init() {}
diff --git a/src/pkg/go/build/testdata/other/file/file.go b/src/go/build/testdata/other/file/file.go
similarity index 100%
rename from src/pkg/go/build/testdata/other/file/file.go
rename to src/go/build/testdata/other/file/file.go
diff --git a/src/pkg/go/build/testdata/other/main.go b/src/go/build/testdata/other/main.go
similarity index 100%
rename from src/pkg/go/build/testdata/other/main.go
rename to src/go/build/testdata/other/main.go
diff --git a/src/pkg/go/doc/Makefile b/src/go/doc/Makefile
similarity index 100%
rename from src/pkg/go/doc/Makefile
rename to src/go/doc/Makefile
diff --git a/src/pkg/go/doc/comment.go b/src/go/doc/comment.go
similarity index 100%
rename from src/pkg/go/doc/comment.go
rename to src/go/doc/comment.go
diff --git a/src/pkg/go/doc/comment_test.go b/src/go/doc/comment_test.go
similarity index 100%
rename from src/pkg/go/doc/comment_test.go
rename to src/go/doc/comment_test.go
diff --git a/src/pkg/go/doc/doc.go b/src/go/doc/doc.go
similarity index 100%
rename from src/pkg/go/doc/doc.go
rename to src/go/doc/doc.go
diff --git a/src/pkg/go/doc/doc_test.go b/src/go/doc/doc_test.go
similarity index 100%
rename from src/pkg/go/doc/doc_test.go
rename to src/go/doc/doc_test.go
diff --git a/src/pkg/go/doc/example.go b/src/go/doc/example.go
similarity index 100%
rename from src/pkg/go/doc/example.go
rename to src/go/doc/example.go
diff --git a/src/pkg/go/doc/example_test.go b/src/go/doc/example_test.go
similarity index 100%
rename from src/pkg/go/doc/example_test.go
rename to src/go/doc/example_test.go
diff --git a/src/go/doc/exports.go b/src/go/doc/exports.go
new file mode 100644
index 0000000..1d3b466
--- /dev/null
+++ b/src/go/doc/exports.go
@@ -0,0 +1,205 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file implements export filtering of an AST.
+
+package doc
+
+import (
+	"go/ast"
+	"go/token"
+)
+
+// filterIdentList removes unexported names from list in place
+// and returns the resulting list. If blankOk is set, blank
+// identifiers are considered exported names.
+//
+func filterIdentList(list []*ast.Ident, blankOk bool) []*ast.Ident {
+	j := 0
+	for _, x := range list {
+		if ast.IsExported(x.Name) || (blankOk && x.Name == "_") {
+			list[j] = x
+			j++
+		}
+	}
+	return list[0:j]
+}
+
+// removeErrorField removes anonymous fields named "error" from an interface.
+// This is called when "error" has been determined to be a local name,
+// not the predeclared type.
+//
+func removeErrorField(ityp *ast.InterfaceType) {
+	list := ityp.Methods.List // we know that ityp.Methods != nil
+	j := 0
+	for _, field := range list {
+		keepField := true
+		if n := len(field.Names); n == 0 {
+			// anonymous field
+			if fname, _ := baseTypeName(field.Type); fname == "error" {
+				keepField = false
+			}
+		}
+		if keepField {
+			list[j] = field
+			j++
+		}
+	}
+	if j < len(list) {
+		ityp.Incomplete = true
+	}
+	ityp.Methods.List = list[0:j]
+}
+
+// filterFieldList removes unexported fields (field names) from the field list
+// in place and returns true if fields were removed. Anonymous fields are
+// recorded with the parent type. filterType is called with the types of
+// all remaining fields.
+//
+func (r *reader) filterFieldList(parent *namedType, fields *ast.FieldList, ityp *ast.InterfaceType) (removedFields bool) {
+	if fields == nil {
+		return
+	}
+	list := fields.List
+	j := 0
+	for _, field := range list {
+		keepField := false
+		if n := len(field.Names); n == 0 {
+			// anonymous field
+			fname := r.recordAnonymousField(parent, field.Type)
+			if ast.IsExported(fname) {
+				keepField = true
+			} else if ityp != nil && fname == "error" {
+				// possibly the predeclared error interface; keep
+				// it for now but remember this interface so that
+				// it can be fixed if error is also defined locally
+				keepField = true
+				r.remember(ityp)
+			}
+		} else {
+			field.Names = filterIdentList(field.Names, false)
+			if len(field.Names) < n {
+				removedFields = true
+			}
+			if len(field.Names) > 0 {
+				keepField = true
+			}
+		}
+		if keepField {
+			r.filterType(nil, field.Type)
+			list[j] = field
+			j++
+		}
+	}
+	if j < len(list) {
+		removedFields = true
+	}
+	fields.List = list[0:j]
+	return
+}
+
+// filterParamList applies filterType to each parameter type in fields.
+//
+func (r *reader) filterParamList(fields *ast.FieldList) {
+	if fields != nil {
+		for _, f := range fields.List {
+			r.filterType(nil, f.Type)
+		}
+	}
+}
+
+// filterType strips any unexported struct fields or method types from typ
+// in place. If fields (or methods) have been removed, the corresponding
+// struct or interface type has the Incomplete field set to true.
+//
+func (r *reader) filterType(parent *namedType, typ ast.Expr) {
+	switch t := typ.(type) {
+	case *ast.Ident:
+		// nothing to do
+	case *ast.ParenExpr:
+		r.filterType(nil, t.X)
+	case *ast.ArrayType:
+		r.filterType(nil, t.Elt)
+	case *ast.StructType:
+		if r.filterFieldList(parent, t.Fields, nil) {
+			t.Incomplete = true
+		}
+	case *ast.FuncType:
+		r.filterParamList(t.Params)
+		r.filterParamList(t.Results)
+	case *ast.InterfaceType:
+		if r.filterFieldList(parent, t.Methods, t) {
+			t.Incomplete = true
+		}
+	case *ast.MapType:
+		r.filterType(nil, t.Key)
+		r.filterType(nil, t.Value)
+	case *ast.ChanType:
+		r.filterType(nil, t.Value)
+	}
+}
+
+func (r *reader) filterSpec(spec ast.Spec, tok token.Token) bool {
+	switch s := spec.(type) {
+	case *ast.ImportSpec:
+		// always keep imports so we can collect them
+		return true
+	case *ast.ValueSpec:
+		// special case: consider blank constants as exported
+		// (work-around for issue 5397)
+		s.Names = filterIdentList(s.Names, tok == token.CONST)
+		if len(s.Names) > 0 {
+			r.filterType(nil, s.Type)
+			return true
+		}
+	case *ast.TypeSpec:
+		if name := s.Name.Name; ast.IsExported(name) {
+			r.filterType(r.lookupType(s.Name.Name), s.Type)
+			return true
+		} else if name == "error" {
+			// special case: remember that error is declared locally
+			r.errorDecl = true
+		}
+	}
+	return false
+}
+
+func (r *reader) filterSpecList(list []ast.Spec, tok token.Token) []ast.Spec {
+	j := 0
+	for _, s := range list {
+		if r.filterSpec(s, tok) {
+			list[j] = s
+			j++
+		}
+	}
+	return list[0:j]
+}
+
+func (r *reader) filterDecl(decl ast.Decl) bool {
+	switch d := decl.(type) {
+	case *ast.GenDecl:
+		d.Specs = r.filterSpecList(d.Specs, d.Tok)
+		return len(d.Specs) > 0
+	case *ast.FuncDecl:
+		// ok to filter these methods early because any
+		// conflicting method will be filtered here, too -
+		// thus, removing these methods early will not lead
+		// to the false removal of possible conflicts
+		return ast.IsExported(d.Name.Name)
+	}
+	return false
+}
+
+// fileExports removes unexported declarations from src in place.
+//
+func (r *reader) fileExports(src *ast.File) {
+	j := 0
+	for _, d := range src.Decls {
+		if r.filterDecl(d) {
+			src.Decls[j] = d
+			j++
+		}
+	}
+	src.Decls = src.Decls[0:j]
+}
diff --git a/src/pkg/go/doc/filter.go b/src/go/doc/filter.go
similarity index 100%
rename from src/pkg/go/doc/filter.go
rename to src/go/doc/filter.go
diff --git a/src/go/doc/headscan.go b/src/go/doc/headscan.go
new file mode 100644
index 0000000..1ccaa15
--- /dev/null
+++ b/src/go/doc/headscan.go
@@ -0,0 +1,114 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build ignore
+
+/*
+	The headscan command extracts comment headings from package files;
+	it is used to detect false positives which may require an adjustment
+	to the comment formatting heuristics in comment.go.
+
+	Usage: headscan [-root root_directory]
+
+	By default, the $GOROOT/src directory is scanned.
+*/
+package main
+
+import (
+	"bytes"
+	"flag"
+	"fmt"
+	"go/doc"
+	"go/parser"
+	"go/token"
+	"os"
+	"path/filepath"
+	"regexp"
+	"runtime"
+	"strings"
+)
+
+var (
+	root    = flag.String("root", filepath.Join(runtime.GOROOT(), "src"), "root of filesystem tree to scan")
+	verbose = flag.Bool("v", false, "verbose mode")
+)
+
+// ToHTML in comment.go assigns a (possibly blank) ID to each heading
+var html_h = regexp.MustCompile(`<h3 id="[^"]*">`)
+
+const html_endh = "</h3>\n"
+
+func isGoFile(fi os.FileInfo) bool {
+	return strings.HasSuffix(fi.Name(), ".go") &&
+		!strings.HasSuffix(fi.Name(), "_test.go")
+}
+
+func appendHeadings(list []string, comment string) []string {
+	var buf bytes.Buffer
+	doc.ToHTML(&buf, comment, nil)
+	for s := buf.String(); ; {
+		loc := html_h.FindStringIndex(s)
+		if len(loc) == 0 {
+			break
+		}
+		i := loc[1]
+		j := strings.Index(s, html_endh)
+		if j < 0 {
+			list = append(list, s[i:]) // incorrect HTML
+			break
+		}
+		list = append(list, s[i:j])
+		s = s[j+len(html_endh):]
+	}
+	return list
+}
+
+func main() {
+	flag.Parse()
+	fset := token.NewFileSet()
+	nheadings := 0
+	err := filepath.Walk(*root, func(path string, fi os.FileInfo, err error) error {
+		if !fi.IsDir() {
+			return nil
+		}
+		pkgs, err := parser.ParseDir(fset, path, isGoFile, parser.ParseComments)
+		if err != nil {
+			if *verbose {
+				fmt.Fprintln(os.Stderr, err)
+			}
+			return nil
+		}
+		for _, pkg := range pkgs {
+			d := doc.New(pkg, path, doc.Mode(0))
+			list := appendHeadings(nil, d.Doc)
+			for _, d := range d.Consts {
+				list = appendHeadings(list, d.Doc)
+			}
+			for _, d := range d.Types {
+				list = appendHeadings(list, d.Doc)
+			}
+			for _, d := range d.Vars {
+				list = appendHeadings(list, d.Doc)
+			}
+			for _, d := range d.Funcs {
+				list = appendHeadings(list, d.Doc)
+			}
+			if len(list) > 0 {
+				// directories may contain multiple packages;
+				// print path and package name
+				fmt.Printf("%s (package %s)\n", path, pkg.Name)
+				for _, h := range list {
+					fmt.Printf("\t%s\n", h)
+				}
+				nheadings += len(list)
+			}
+		}
+		return nil
+	})
+	if err != nil {
+		fmt.Fprintln(os.Stderr, err)
+		os.Exit(1)
+	}
+	fmt.Println(nheadings, "headings found")
+}
diff --git a/src/pkg/go/doc/reader.go b/src/go/doc/reader.go
similarity index 100%
rename from src/pkg/go/doc/reader.go
rename to src/go/doc/reader.go
diff --git a/src/pkg/go/doc/synopsis.go b/src/go/doc/synopsis.go
similarity index 100%
rename from src/pkg/go/doc/synopsis.go
rename to src/go/doc/synopsis.go
diff --git a/src/pkg/go/doc/synopsis_test.go b/src/go/doc/synopsis_test.go
similarity index 100%
rename from src/pkg/go/doc/synopsis_test.go
rename to src/go/doc/synopsis_test.go
diff --git a/src/pkg/go/doc/testdata/a.0.golden b/src/go/doc/testdata/a.0.golden
similarity index 100%
rename from src/pkg/go/doc/testdata/a.0.golden
rename to src/go/doc/testdata/a.0.golden
diff --git a/src/pkg/go/doc/testdata/a.1.golden b/src/go/doc/testdata/a.1.golden
similarity index 100%
rename from src/pkg/go/doc/testdata/a.1.golden
rename to src/go/doc/testdata/a.1.golden
diff --git a/src/pkg/go/doc/testdata/a.2.golden b/src/go/doc/testdata/a.2.golden
similarity index 100%
rename from src/pkg/go/doc/testdata/a.2.golden
rename to src/go/doc/testdata/a.2.golden
diff --git a/src/pkg/go/doc/testdata/a0.go b/src/go/doc/testdata/a0.go
similarity index 100%
rename from src/pkg/go/doc/testdata/a0.go
rename to src/go/doc/testdata/a0.go
diff --git a/src/pkg/go/doc/testdata/a1.go b/src/go/doc/testdata/a1.go
similarity index 100%
rename from src/pkg/go/doc/testdata/a1.go
rename to src/go/doc/testdata/a1.go
diff --git a/src/pkg/go/doc/testdata/b.0.golden b/src/go/doc/testdata/b.0.golden
similarity index 100%
rename from src/pkg/go/doc/testdata/b.0.golden
rename to src/go/doc/testdata/b.0.golden
diff --git a/src/pkg/go/doc/testdata/b.1.golden b/src/go/doc/testdata/b.1.golden
similarity index 100%
rename from src/pkg/go/doc/testdata/b.1.golden
rename to src/go/doc/testdata/b.1.golden
diff --git a/src/pkg/go/doc/testdata/b.2.golden b/src/go/doc/testdata/b.2.golden
similarity index 100%
rename from src/pkg/go/doc/testdata/b.2.golden
rename to src/go/doc/testdata/b.2.golden
diff --git a/src/pkg/go/doc/testdata/b.go b/src/go/doc/testdata/b.go
similarity index 100%
rename from src/pkg/go/doc/testdata/b.go
rename to src/go/doc/testdata/b.go
diff --git a/src/pkg/go/doc/testdata/benchmark.go b/src/go/doc/testdata/benchmark.go
similarity index 100%
rename from src/pkg/go/doc/testdata/benchmark.go
rename to src/go/doc/testdata/benchmark.go
diff --git a/src/go/doc/testdata/blank.0.golden b/src/go/doc/testdata/blank.0.golden
new file mode 100644
index 0000000..dae3ab2
--- /dev/null
+++ b/src/go/doc/testdata/blank.0.golden
@@ -0,0 +1,37 @@
+// Package blank is a go/doc test for the handling of _. See issue ...
+PACKAGE blank
+
+IMPORTPATH
+	testdata/blank
+
+FILENAMES
+	testdata/blank.go
+
+CONSTANTS
+	// Package constants. 
+	const (
+		_	int	= iota
+		I1
+		I2
+	)
+
+
+TYPES
+	// S has a padding field. 
+	type S struct {
+		H	uint32
+	
+		A	uint8
+		// contains filtered or unexported fields
+	}
+
+	// 
+	type T int
+
+	// T constants. 
+	const (
+		_	T	= iota
+		T1
+		T2
+	)
+
diff --git a/src/go/doc/testdata/blank.1.golden b/src/go/doc/testdata/blank.1.golden
new file mode 100644
index 0000000..333d7e5
--- /dev/null
+++ b/src/go/doc/testdata/blank.1.golden
@@ -0,0 +1,46 @@
+// Package blank is a go/doc test for the handling of _. See issue ...
+PACKAGE blank
+
+IMPORTPATH
+	testdata/blank
+
+FILENAMES
+	testdata/blank.go
+
+CONSTANTS
+	// Package constants. 
+	const (
+		_	int	= iota
+		I1
+		I2
+	)
+
+
+VARIABLES
+	// 
+	var _ = T(55)
+
+
+FUNCTIONS
+	// 
+	func _()
+
+
+TYPES
+	// S has a padding field. 
+	type S struct {
+		H	uint32
+		_	uint8
+		A	uint8
+	}
+
+	// 
+	type T int
+
+	// T constants. 
+	const (
+		_	T	= iota
+		T1
+		T2
+	)
+
diff --git a/src/go/doc/testdata/blank.2.golden b/src/go/doc/testdata/blank.2.golden
new file mode 100644
index 0000000..dae3ab2
--- /dev/null
+++ b/src/go/doc/testdata/blank.2.golden
@@ -0,0 +1,37 @@
+// Package blank is a go/doc test for the handling of _. See issue ...
+PACKAGE blank
+
+IMPORTPATH
+	testdata/blank
+
+FILENAMES
+	testdata/blank.go
+
+CONSTANTS
+	// Package constants. 
+	const (
+		_	int	= iota
+		I1
+		I2
+	)
+
+
+TYPES
+	// S has a padding field. 
+	type S struct {
+		H	uint32
+	
+		A	uint8
+		// contains filtered or unexported fields
+	}
+
+	// 
+	type T int
+
+	// T constants. 
+	const (
+		_	T	= iota
+		T1
+		T2
+	)
+
diff --git a/src/go/doc/testdata/blank.go b/src/go/doc/testdata/blank.go
new file mode 100644
index 0000000..f812c77
--- /dev/null
+++ b/src/go/doc/testdata/blank.go
@@ -0,0 +1,38 @@
+// 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 blank is a go/doc test for the handling of _.
+// See issue 5397.
+package blank
+
+type T int
+
+// T constants.
+const (
+	_ T = iota
+	T1
+	T2
+)
+
+// Package constants.
+const (
+	_ int = iota
+	I1
+	I2
+)
+
+// Blanks not in doc output:
+
+// S has a padding field.
+type S struct {
+	H uint32
+	_ uint8
+	A uint8
+}
+
+func _() {}
+
+type _ T
+
+var _ = T(55)
diff --git a/src/pkg/go/doc/testdata/bugpara.0.golden b/src/go/doc/testdata/bugpara.0.golden
similarity index 100%
rename from src/pkg/go/doc/testdata/bugpara.0.golden
rename to src/go/doc/testdata/bugpara.0.golden
diff --git a/src/pkg/go/doc/testdata/bugpara.1.golden b/src/go/doc/testdata/bugpara.1.golden
similarity index 100%
rename from src/pkg/go/doc/testdata/bugpara.1.golden
rename to src/go/doc/testdata/bugpara.1.golden
diff --git a/src/pkg/go/doc/testdata/bugpara.2.golden b/src/go/doc/testdata/bugpara.2.golden
similarity index 100%
rename from src/pkg/go/doc/testdata/bugpara.2.golden
rename to src/go/doc/testdata/bugpara.2.golden
diff --git a/src/pkg/go/doc/testdata/bugpara.go b/src/go/doc/testdata/bugpara.go
similarity index 100%
rename from src/pkg/go/doc/testdata/bugpara.go
rename to src/go/doc/testdata/bugpara.go
diff --git a/src/pkg/go/doc/testdata/c.0.golden b/src/go/doc/testdata/c.0.golden
similarity index 100%
rename from src/pkg/go/doc/testdata/c.0.golden
rename to src/go/doc/testdata/c.0.golden
diff --git a/src/pkg/go/doc/testdata/c.1.golden b/src/go/doc/testdata/c.1.golden
similarity index 100%
rename from src/pkg/go/doc/testdata/c.1.golden
rename to src/go/doc/testdata/c.1.golden
diff --git a/src/pkg/go/doc/testdata/c.2.golden b/src/go/doc/testdata/c.2.golden
similarity index 100%
rename from src/pkg/go/doc/testdata/c.2.golden
rename to src/go/doc/testdata/c.2.golden
diff --git a/src/pkg/go/doc/testdata/c.go b/src/go/doc/testdata/c.go
similarity index 100%
rename from src/pkg/go/doc/testdata/c.go
rename to src/go/doc/testdata/c.go
diff --git a/src/pkg/go/doc/testdata/d.0.golden b/src/go/doc/testdata/d.0.golden
similarity index 100%
rename from src/pkg/go/doc/testdata/d.0.golden
rename to src/go/doc/testdata/d.0.golden
diff --git a/src/pkg/go/doc/testdata/d.1.golden b/src/go/doc/testdata/d.1.golden
similarity index 100%
rename from src/pkg/go/doc/testdata/d.1.golden
rename to src/go/doc/testdata/d.1.golden
diff --git a/src/pkg/go/doc/testdata/d.2.golden b/src/go/doc/testdata/d.2.golden
similarity index 100%
rename from src/pkg/go/doc/testdata/d.2.golden
rename to src/go/doc/testdata/d.2.golden
diff --git a/src/pkg/go/doc/testdata/d1.go b/src/go/doc/testdata/d1.go
similarity index 100%
rename from src/pkg/go/doc/testdata/d1.go
rename to src/go/doc/testdata/d1.go
diff --git a/src/pkg/go/doc/testdata/d2.go b/src/go/doc/testdata/d2.go
similarity index 100%
rename from src/pkg/go/doc/testdata/d2.go
rename to src/go/doc/testdata/d2.go
diff --git a/src/pkg/go/doc/testdata/e.0.golden b/src/go/doc/testdata/e.0.golden
similarity index 100%
rename from src/pkg/go/doc/testdata/e.0.golden
rename to src/go/doc/testdata/e.0.golden
diff --git a/src/pkg/go/doc/testdata/e.1.golden b/src/go/doc/testdata/e.1.golden
similarity index 100%
rename from src/pkg/go/doc/testdata/e.1.golden
rename to src/go/doc/testdata/e.1.golden
diff --git a/src/pkg/go/doc/testdata/e.2.golden b/src/go/doc/testdata/e.2.golden
similarity index 100%
rename from src/pkg/go/doc/testdata/e.2.golden
rename to src/go/doc/testdata/e.2.golden
diff --git a/src/pkg/go/doc/testdata/e.go b/src/go/doc/testdata/e.go
similarity index 100%
rename from src/pkg/go/doc/testdata/e.go
rename to src/go/doc/testdata/e.go
diff --git a/src/pkg/go/doc/testdata/error1.0.golden b/src/go/doc/testdata/error1.0.golden
similarity index 100%
rename from src/pkg/go/doc/testdata/error1.0.golden
rename to src/go/doc/testdata/error1.0.golden
diff --git a/src/pkg/go/doc/testdata/error1.1.golden b/src/go/doc/testdata/error1.1.golden
similarity index 100%
rename from src/pkg/go/doc/testdata/error1.1.golden
rename to src/go/doc/testdata/error1.1.golden
diff --git a/src/pkg/go/doc/testdata/error1.2.golden b/src/go/doc/testdata/error1.2.golden
similarity index 100%
rename from src/pkg/go/doc/testdata/error1.2.golden
rename to src/go/doc/testdata/error1.2.golden
diff --git a/src/pkg/go/doc/testdata/error1.go b/src/go/doc/testdata/error1.go
similarity index 100%
rename from src/pkg/go/doc/testdata/error1.go
rename to src/go/doc/testdata/error1.go
diff --git a/src/pkg/go/doc/testdata/error2.0.golden b/src/go/doc/testdata/error2.0.golden
similarity index 100%
rename from src/pkg/go/doc/testdata/error2.0.golden
rename to src/go/doc/testdata/error2.0.golden
diff --git a/src/pkg/go/doc/testdata/error2.1.golden b/src/go/doc/testdata/error2.1.golden
similarity index 100%
rename from src/pkg/go/doc/testdata/error2.1.golden
rename to src/go/doc/testdata/error2.1.golden
diff --git a/src/pkg/go/doc/testdata/error2.2.golden b/src/go/doc/testdata/error2.2.golden
similarity index 100%
rename from src/pkg/go/doc/testdata/error2.2.golden
rename to src/go/doc/testdata/error2.2.golden
diff --git a/src/pkg/go/doc/testdata/error2.go b/src/go/doc/testdata/error2.go
similarity index 100%
rename from src/pkg/go/doc/testdata/error2.go
rename to src/go/doc/testdata/error2.go
diff --git a/src/pkg/go/doc/testdata/example.go b/src/go/doc/testdata/example.go
similarity index 100%
rename from src/pkg/go/doc/testdata/example.go
rename to src/go/doc/testdata/example.go
diff --git a/src/pkg/go/doc/testdata/f.0.golden b/src/go/doc/testdata/f.0.golden
similarity index 100%
rename from src/pkg/go/doc/testdata/f.0.golden
rename to src/go/doc/testdata/f.0.golden
diff --git a/src/pkg/go/doc/testdata/f.1.golden b/src/go/doc/testdata/f.1.golden
similarity index 100%
rename from src/pkg/go/doc/testdata/f.1.golden
rename to src/go/doc/testdata/f.1.golden
diff --git a/src/pkg/go/doc/testdata/f.2.golden b/src/go/doc/testdata/f.2.golden
similarity index 100%
rename from src/pkg/go/doc/testdata/f.2.golden
rename to src/go/doc/testdata/f.2.golden
diff --git a/src/pkg/go/doc/testdata/f.go b/src/go/doc/testdata/f.go
similarity index 100%
rename from src/pkg/go/doc/testdata/f.go
rename to src/go/doc/testdata/f.go
diff --git a/src/pkg/go/doc/testdata/template.txt b/src/go/doc/testdata/template.txt
similarity index 100%
rename from src/pkg/go/doc/testdata/template.txt
rename to src/go/doc/testdata/template.txt
diff --git a/src/pkg/go/doc/testdata/testing.0.golden b/src/go/doc/testdata/testing.0.golden
similarity index 100%
rename from src/pkg/go/doc/testdata/testing.0.golden
rename to src/go/doc/testdata/testing.0.golden
diff --git a/src/pkg/go/doc/testdata/testing.1.golden b/src/go/doc/testdata/testing.1.golden
similarity index 100%
rename from src/pkg/go/doc/testdata/testing.1.golden
rename to src/go/doc/testdata/testing.1.golden
diff --git a/src/pkg/go/doc/testdata/testing.2.golden b/src/go/doc/testdata/testing.2.golden
similarity index 100%
rename from src/pkg/go/doc/testdata/testing.2.golden
rename to src/go/doc/testdata/testing.2.golden
diff --git a/src/pkg/go/doc/testdata/testing.go b/src/go/doc/testdata/testing.go
similarity index 100%
rename from src/pkg/go/doc/testdata/testing.go
rename to src/go/doc/testdata/testing.go
diff --git a/src/go/format/format.go b/src/go/format/format.go
new file mode 100644
index 0000000..668a42d
--- /dev/null
+++ b/src/go/format/format.go
@@ -0,0 +1,266 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package format implements standard formatting of Go source.
+package format
+
+import (
+	"bytes"
+	"fmt"
+	"go/ast"
+	"go/parser"
+	"go/printer"
+	"go/token"
+	"io"
+	"strings"
+)
+
+var config = printer.Config{Mode: printer.UseSpaces | printer.TabIndent, Tabwidth: 8}
+
+const parserMode = parser.ParseComments
+
+// Node formats node in canonical gofmt style and writes the result to dst.
+//
+// The node type must be *ast.File, *printer.CommentedNode, []ast.Decl,
+// []ast.Stmt, or assignment-compatible to ast.Expr, ast.Decl, ast.Spec,
+// or ast.Stmt. Node does not modify node. Imports are not sorted for
+// nodes representing partial source files (i.e., if the node is not an
+// *ast.File or a *printer.CommentedNode not wrapping an *ast.File).
+//
+// The function may return early (before the entire result is written)
+// and return a formatting error, for instance due to an incorrect AST.
+//
+func Node(dst io.Writer, fset *token.FileSet, node interface{}) error {
+	// Determine if we have a complete source file (file != nil).
+	var file *ast.File
+	var cnode *printer.CommentedNode
+	switch n := node.(type) {
+	case *ast.File:
+		file = n
+	case *printer.CommentedNode:
+		if f, ok := n.Node.(*ast.File); ok {
+			file = f
+			cnode = n
+		}
+	}
+
+	// Sort imports if necessary.
+	if file != nil && hasUnsortedImports(file) {
+		// Make a copy of the AST because ast.SortImports is destructive.
+		// TODO(gri) Do this more efficiently.
+		var buf bytes.Buffer
+		err := config.Fprint(&buf, fset, file)
+		if err != nil {
+			return err
+		}
+		file, err = parser.ParseFile(fset, "", buf.Bytes(), parserMode)
+		if err != nil {
+			// We should never get here. If we do, provide good diagnostic.
+			return fmt.Errorf("format.Node internal error (%s)", err)
+		}
+		ast.SortImports(fset, file)
+
+		// Use new file with sorted imports.
+		node = file
+		if cnode != nil {
+			node = &printer.CommentedNode{Node: file, Comments: cnode.Comments}
+		}
+	}
+
+	return config.Fprint(dst, fset, node)
+}
+
+// Source formats src in canonical gofmt style and returns the result
+// or an (I/O or syntax) error. src is expected to be a syntactically
+// correct Go source file, or a list of Go declarations or statements.
+//
+// If src is a partial source file, the leading and trailing space of src
+// is applied to the result (such that it has the same leading and trailing
+// space as src), and the result is indented by the same amount as the first
+// line of src containing code. Imports are not sorted for partial source files.
+//
+func Source(src []byte) ([]byte, error) {
+	fset := token.NewFileSet()
+	file, sourceAdj, indentAdj, err := parse(fset, "", src, true)
+	if err != nil {
+		return nil, err
+	}
+
+	if sourceAdj == nil {
+		// Complete source file.
+		// TODO(gri) consider doing this always.
+		ast.SortImports(fset, file)
+	}
+
+	return format(fset, file, sourceAdj, indentAdj, src, config)
+}
+
+func hasUnsortedImports(file *ast.File) bool {
+	for _, d := range file.Decls {
+		d, ok := d.(*ast.GenDecl)
+		if !ok || d.Tok != token.IMPORT {
+			// Not an import declaration, so we're done.
+			// Imports are always first.
+			return false
+		}
+		if d.Lparen.IsValid() {
+			// For now assume all grouped imports are unsorted.
+			// TODO(gri) Should check if they are sorted already.
+			return true
+		}
+		// Ungrouped imports are sorted by default.
+	}
+	return false
+}
+
+// ----------------------------------------------------------------------------
+// Support functions
+//
+// The functions parse, format, and isSpace below are identical to the
+// respective functions in cmd/gofmt/gofmt.go - keep them in sync!
+//
+// TODO(gri) Factor out this functionality, eventually.
+
+// parse parses src, which was read from the named file,
+// as a Go source file, declaration, or statement list.
+func parse(fset *token.FileSet, filename string, src []byte, fragmentOk bool) (
+	file *ast.File,
+	sourceAdj func(src []byte, indent int) []byte,
+	indentAdj int,
+	err error,
+) {
+	// Try as whole source file.
+	file, err = parser.ParseFile(fset, filename, src, parserMode)
+	// If there's no error, return.  If the error is that the source file didn't begin with a
+	// package line and source fragments are ok, fall through to
+	// try as a source fragment.  Stop and return on any other error.
+	if err == nil || !fragmentOk || !strings.Contains(err.Error(), "expected 'package'") {
+		return
+	}
+
+	// If this is a declaration list, make it a source file
+	// by inserting a package clause.
+	// Insert using a ;, not a newline, so that the line numbers
+	// in psrc match the ones in src.
+	psrc := append([]byte("package p;"), src...)
+	file, err = parser.ParseFile(fset, filename, psrc, parserMode)
+	if err == nil {
+		sourceAdj = func(src []byte, indent int) []byte {
+			// Remove the package clause.
+			// Gofmt has turned the ; into a \n.
+			src = src[indent+len("package p\n"):]
+			return bytes.TrimSpace(src)
+		}
+		return
+	}
+	// If the error is that the source file didn't begin with a
+	// declaration, fall through to try as a statement list.
+	// Stop and return on any other error.
+	if !strings.Contains(err.Error(), "expected declaration") {
+		return
+	}
+
+	// If this is a statement list, make it a source file
+	// by inserting a package clause and turning the list
+	// into a function body.  This handles expressions too.
+	// Insert using a ;, not a newline, so that the line numbers
+	// in fsrc match the ones in src.
+	fsrc := append(append([]byte("package p; func _() {"), src...), '\n', '}')
+	file, err = parser.ParseFile(fset, filename, fsrc, parserMode)
+	if err == nil {
+		sourceAdj = func(src []byte, indent int) []byte {
+			// Cap adjusted indent to zero.
+			if indent < 0 {
+				indent = 0
+			}
+			// Remove the wrapping.
+			// Gofmt has turned the ; into a \n\n.
+			// There will be two non-blank lines with indent, hence 2*indent.
+			src = src[2*indent+len("package p\n\nfunc _() {"):]
+			src = src[:len(src)-(indent+len("\n}\n"))]
+			return bytes.TrimSpace(src)
+		}
+		// Gofmt has also indented the function body one level.
+		// Adjust that with indentAdj.
+		indentAdj = -1
+	}
+
+	// Succeeded, or out of options.
+	return
+}
+
+// format formats the given package file originally obtained from src
+// and adjusts the result based on the original source via sourceAdj
+// and indentAdj.
+func format(
+	fset *token.FileSet,
+	file *ast.File,
+	sourceAdj func(src []byte, indent int) []byte,
+	indentAdj int,
+	src []byte,
+	cfg printer.Config,
+) ([]byte, error) {
+	if sourceAdj == nil {
+		// Complete source file.
+		var buf bytes.Buffer
+		err := cfg.Fprint(&buf, fset, file)
+		if err != nil {
+			return nil, err
+		}
+		return buf.Bytes(), nil
+	}
+
+	// Partial source file.
+	// Determine and prepend leading space.
+	i, j := 0, 0
+	for j < len(src) && isSpace(src[j]) {
+		if src[j] == '\n' {
+			i = j + 1 // byte offset of last line in leading space
+		}
+		j++
+	}
+	var res []byte
+	res = append(res, src[:i]...)
+
+	// Determine and prepend indentation of first code line.
+	// Spaces are ignored unless there are no tabs,
+	// in which case spaces count as one tab.
+	indent := 0
+	hasSpace := false
+	for _, b := range src[i:j] {
+		switch b {
+		case ' ':
+			hasSpace = true
+		case '\t':
+			indent++
+		}
+	}
+	if indent == 0 && hasSpace {
+		indent = 1
+	}
+	for i := 0; i < indent; i++ {
+		res = append(res, '\t')
+	}
+
+	// Format the source.
+	// Write it without any leading and trailing space.
+	cfg.Indent = indent + indentAdj
+	var buf bytes.Buffer
+	err := cfg.Fprint(&buf, fset, file)
+	if err != nil {
+		return nil, err
+	}
+	res = append(res, sourceAdj(buf.Bytes(), cfg.Indent)...)
+
+	// Determine and append trailing space.
+	i = len(src)
+	for i > 0 && isSpace(src[i-1]) {
+		i--
+	}
+	return append(res, src[i:]...), nil
+}
+
+func isSpace(b byte) bool {
+	return b == ' ' || b == '\t' || b == '\n' || b == '\r'
+}
diff --git a/src/go/format/format_test.go b/src/go/format/format_test.go
new file mode 100644
index 0000000..d7846be
--- /dev/null
+++ b/src/go/format/format_test.go
@@ -0,0 +1,128 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package format
+
+import (
+	"bytes"
+	"go/parser"
+	"go/token"
+	"io/ioutil"
+	"strings"
+	"testing"
+)
+
+const testfile = "format_test.go"
+
+func diff(t *testing.T, dst, src []byte) {
+	line := 1
+	offs := 0 // line offset
+	for i := 0; i < len(dst) && i < len(src); i++ {
+		d := dst[i]
+		s := src[i]
+		if d != s {
+			t.Errorf("dst:%d: %s\n", line, dst[offs:i+1])
+			t.Errorf("src:%d: %s\n", line, src[offs:i+1])
+			return
+		}
+		if s == '\n' {
+			line++
+			offs = i + 1
+		}
+	}
+	if len(dst) != len(src) {
+		t.Errorf("len(dst) = %d, len(src) = %d\nsrc = %q", len(dst), len(src), src)
+	}
+}
+
+func TestNode(t *testing.T) {
+	src, err := ioutil.ReadFile(testfile)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	fset := token.NewFileSet()
+	file, err := parser.ParseFile(fset, testfile, src, parser.ParseComments)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	var buf bytes.Buffer
+
+	if err = Node(&buf, fset, file); err != nil {
+		t.Fatal("Node failed:", err)
+	}
+
+	diff(t, buf.Bytes(), src)
+}
+
+func TestSource(t *testing.T) {
+	src, err := ioutil.ReadFile(testfile)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	res, err := Source(src)
+	if err != nil {
+		t.Fatal("Source failed:", err)
+	}
+
+	diff(t, res, src)
+}
+
+// Test cases that are expected to fail are marked by the prefix "ERROR".
+var tests = []string{
+	// declaration lists
+	`import "go/format"`,
+	"var x int",
+	"var x int\n\ntype T struct{}",
+
+	// statement lists
+	"x := 0",
+	"f(a, b, c)\nvar x int = f(1, 2, 3)",
+
+	// indentation, leading and trailing space
+	"\tx := 0\n\tgo f()",
+	"\tx := 0\n\tgo f()\n\n\n",
+	"\n\t\t\n\n\tx := 0\n\tgo f()\n\n\n",
+	"\n\t\t\n\n\t\t\tx := 0\n\t\t\tgo f()\n\n\n",
+	"\n\t\t\n\n\t\t\tx := 0\n\t\t\tconst s = `\nfoo\n`\n\n\n",     // no indentation added inside raw strings
+	"\n\t\t\n\n\t\t\tx := 0\n\t\t\tconst s = `\n\t\tfoo\n`\n\n\n", // no indentation removed inside raw strings
+
+	// comments
+	"i := 5 /* Comment */", // Issue 5551.
+
+	// erroneous programs
+	"ERROR1 + 2 +",
+	"ERRORx :=  0",
+}
+
+func String(s string) (string, error) {
+	res, err := Source([]byte(s))
+	if err != nil {
+		return "", err
+	}
+	return string(res), nil
+}
+
+func TestPartial(t *testing.T) {
+	for _, src := range tests {
+		if strings.HasPrefix(src, "ERROR") {
+			// test expected to fail
+			src = src[5:] // remove ERROR prefix
+			res, err := String(src)
+			if err == nil && res == src {
+				t.Errorf("formatting succeeded but was expected to fail:\n%q", src)
+			}
+		} else {
+			// test expected to succeed
+			res, err := String(src)
+			if err != nil {
+				t.Errorf("formatting failed (%s):\n%q", err, src)
+			} else if res != src {
+				t.Errorf("formatting incorrect:\nsource: %q\nresult: %q", src, res)
+			}
+		}
+	}
+}
diff --git a/src/go/parser/error_test.go b/src/go/parser/error_test.go
new file mode 100644
index 0000000..48fb53e
--- /dev/null
+++ b/src/go/parser/error_test.go
@@ -0,0 +1,182 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file implements a parser test harness. The files in the testdata
+// directory are parsed and the errors reported are compared against the
+// error messages expected in the test files. The test files must end in
+// .src rather than .go so that they are not disturbed by gofmt runs.
+//
+// Expected errors are indicated in the test files by putting a comment
+// of the form /* ERROR "rx" */ immediately following an offending token.
+// The harness will verify that an error matching the regular expression
+// rx is reported at that source position.
+//
+// For instance, the following test file indicates that a "not declared"
+// error should be reported for the undeclared variable x:
+//
+//	package p
+//	func f() {
+//		_ = x /* ERROR "not declared" */ + 1
+//	}
+
+package parser
+
+import (
+	"go/scanner"
+	"go/token"
+	"io/ioutil"
+	"path/filepath"
+	"regexp"
+	"strings"
+	"testing"
+)
+
+const testdata = "testdata"
+
+var fsetErrs = token.NewFileSet()
+
+// getFile assumes that each filename occurs at most once
+func getFile(filename string) (file *token.File) {
+	fsetErrs.Iterate(func(f *token.File) bool {
+		if f.Name() == filename {
+			if file != nil {
+				panic(filename + " used multiple times")
+			}
+			file = f
+		}
+		return true
+	})
+	return file
+}
+
+func getPos(filename string, offset int) token.Pos {
+	if f := getFile(filename); f != nil {
+		return f.Pos(offset)
+	}
+	return token.NoPos
+}
+
+// ERROR comments must be of the form /* ERROR "rx" */ and rx is
+// a regular expression that matches the expected error message.
+// The special form /* ERROR HERE "rx" */ must be used for error
+// messages that appear immediately after a token, rather than at
+// a token's position.
+//
+var errRx = regexp.MustCompile(`^/\* *ERROR *(HERE)? *"([^"]*)" *\*/$`)
+
+// expectedErrors collects the regular expressions of ERROR comments found
+// in files and returns them as a map of error positions to error messages.
+//
+func expectedErrors(t *testing.T, filename string, src []byte) map[token.Pos]string {
+	errors := make(map[token.Pos]string)
+
+	var s scanner.Scanner
+	// file was parsed already - do not add it again to the file
+	// set otherwise the position information returned here will
+	// not match the position information collected by the parser
+	s.Init(getFile(filename), src, nil, scanner.ScanComments)
+	var prev token.Pos // position of last non-comment, non-semicolon token
+	var here token.Pos // position immediately after the token at position prev
+
+	for {
+		pos, tok, lit := s.Scan()
+		switch tok {
+		case token.EOF:
+			return errors
+		case token.COMMENT:
+			s := errRx.FindStringSubmatch(lit)
+			if len(s) == 3 {
+				pos := prev
+				if s[1] == "HERE" {
+					pos = here
+				}
+				errors[pos] = string(s[2])
+			}
+		default:
+			prev = pos
+			var l int // token length
+			if tok.IsLiteral() {
+				l = len(lit)
+			} else {
+				l = len(tok.String())
+			}
+			here = prev + token.Pos(l)
+		}
+	}
+}
+
+// compareErrors compares the map of expected error messages with the list
+// of found errors and reports discrepancies.
+//
+func compareErrors(t *testing.T, expected map[token.Pos]string, found scanner.ErrorList) {
+	for _, error := range found {
+		// error.Pos is a token.Position, but we want
+		// a token.Pos so we can do a map lookup
+		pos := getPos(error.Pos.Filename, error.Pos.Offset)
+		if msg, found := expected[pos]; found {
+			// we expect a message at pos; check if it matches
+			rx, err := regexp.Compile(msg)
+			if err != nil {
+				t.Errorf("%s: %v", error.Pos, err)
+				continue
+			}
+			if match := rx.MatchString(error.Msg); !match {
+				t.Errorf("%s: %q does not match %q", error.Pos, error.Msg, msg)
+				continue
+			}
+			// we have a match - eliminate this error
+			delete(expected, pos)
+		} else {
+			// To keep in mind when analyzing failed test output:
+			// If the same error position occurs multiple times in errors,
+			// this message will be triggered (because the first error at
+			// the position removes this position from the expected errors).
+			t.Errorf("%s: unexpected error: %s", error.Pos, error.Msg)
+		}
+	}
+
+	// there should be no expected errors left
+	if len(expected) > 0 {
+		t.Errorf("%d errors not reported:", len(expected))
+		for pos, msg := range expected {
+			t.Errorf("%s: %s\n", fsetErrs.Position(pos), msg)
+		}
+	}
+}
+
+func checkErrors(t *testing.T, filename string, input interface{}) {
+	src, err := readSource(filename, input)
+	if err != nil {
+		t.Error(err)
+		return
+	}
+
+	_, err = ParseFile(fsetErrs, filename, src, DeclarationErrors|AllErrors)
+	found, ok := err.(scanner.ErrorList)
+	if err != nil && !ok {
+		t.Error(err)
+		return
+	}
+	found.RemoveMultiples()
+
+	// we are expecting the following errors
+	// (collect these after parsing a file so that it is found in the file set)
+	expected := expectedErrors(t, filename, src)
+
+	// verify errors returned by the parser
+	compareErrors(t, expected, found)
+}
+
+func TestErrors(t *testing.T) {
+	list, err := ioutil.ReadDir(testdata)
+	if err != nil {
+		t.Fatal(err)
+	}
+	for _, fi := range list {
+		name := fi.Name()
+		if !fi.IsDir() && !strings.HasPrefix(name, ".") && strings.HasSuffix(name, ".src") {
+			checkErrors(t, filepath.Join(testdata, name), nil)
+		}
+	}
+}
diff --git a/src/pkg/go/parser/example_test.go b/src/go/parser/example_test.go
similarity index 100%
rename from src/pkg/go/parser/example_test.go
rename to src/go/parser/example_test.go
diff --git a/src/go/parser/interface.go b/src/go/parser/interface.go
new file mode 100644
index 0000000..4910305
--- /dev/null
+++ b/src/go/parser/interface.go
@@ -0,0 +1,198 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file contains the exported entry points for invoking the parser.
+
+package parser
+
+import (
+	"bytes"
+	"errors"
+	"go/ast"
+	"go/token"
+	"io"
+	"io/ioutil"
+	"os"
+	"path/filepath"
+	"strings"
+)
+
+// If src != nil, readSource converts src to a []byte if possible;
+// otherwise it returns an error. If src == nil, readSource returns
+// the result of reading the file specified by filename.
+//
+func readSource(filename string, src interface{}) ([]byte, error) {
+	if src != nil {
+		switch s := src.(type) {
+		case string:
+			return []byte(s), nil
+		case []byte:
+			return s, nil
+		case *bytes.Buffer:
+			// is io.Reader, but src is already available in []byte form
+			if s != nil {
+				return s.Bytes(), nil
+			}
+		case io.Reader:
+			var buf bytes.Buffer
+			if _, err := io.Copy(&buf, s); err != nil {
+				return nil, err
+			}
+			return buf.Bytes(), nil
+		}
+		return nil, errors.New("invalid source")
+	}
+	return ioutil.ReadFile(filename)
+}
+
+// A Mode value is a set of flags (or 0).
+// They control the amount of source code parsed and other optional
+// parser functionality.
+//
+type Mode uint
+
+const (
+	PackageClauseOnly Mode             = 1 << iota // stop parsing after package clause
+	ImportsOnly                                    // stop parsing after import declarations
+	ParseComments                                  // parse comments and add them to AST
+	Trace                                          // print a trace of parsed productions
+	DeclarationErrors                              // report declaration errors
+	SpuriousErrors                                 // same as AllErrors, for backward-compatibility
+	AllErrors         = SpuriousErrors             // report all errors (not just the first 10 on different lines)
+)
+
+// ParseFile parses the source code of a single Go source file and returns
+// the corresponding ast.File node. The source code may be provided via
+// the filename of the source file, or via the src parameter.
+//
+// If src != nil, ParseFile parses the source from src and the filename is
+// only used when recording position information. The type of the argument
+// for the src parameter must be string, []byte, or io.Reader.
+// If src == nil, ParseFile parses the file specified by filename.
+//
+// The mode parameter controls the amount of source text parsed and other
+// optional parser functionality. Position information is recorded in the
+// file set fset.
+//
+// If the source couldn't be read, the returned AST is nil and the error
+// indicates the specific failure. If the source was read but syntax
+// errors were found, the result is a partial AST (with ast.Bad* nodes
+// representing the fragments of erroneous source code). Multiple errors
+// are returned via a scanner.ErrorList which is sorted by file position.
+//
+func ParseFile(fset *token.FileSet, filename string, src interface{}, mode Mode) (f *ast.File, err error) {
+	// get source
+	text, err := readSource(filename, src)
+	if err != nil {
+		return nil, err
+	}
+
+	var p parser
+	defer func() {
+		if e := recover(); e != nil {
+			_ = e.(bailout) // re-panics if it's not a bailout
+		}
+
+		// set result values
+		if f == nil {
+			// source is not a valid Go source file - satisfy
+			// ParseFile API and return a valid (but) empty
+			// *ast.File
+			f = &ast.File{
+				Name:  new(ast.Ident),
+				Scope: ast.NewScope(nil),
+			}
+		}
+
+		p.errors.Sort()
+		err = p.errors.Err()
+	}()
+
+	// parse source
+	p.init(fset, filename, text, mode)
+	f = p.parseFile()
+
+	return
+}
+
+// ParseDir calls ParseFile for all files with names ending in ".go" in the
+// directory specified by path and returns a map of package name -> package
+// AST with all the packages found.
+//
+// If filter != nil, only the files with os.FileInfo entries passing through
+// the filter (and ending in ".go") are considered. The mode bits are passed
+// to ParseFile unchanged. Position information is recorded in fset.
+//
+// If the directory couldn't be read, a nil map and the respective error are
+// returned. If a parse error occurred, a non-nil but incomplete map and the
+// first error encountered are returned.
+//
+func ParseDir(fset *token.FileSet, path string, filter func(os.FileInfo) bool, mode Mode) (pkgs map[string]*ast.Package, first error) {
+	fd, err := os.Open(path)
+	if err != nil {
+		return nil, err
+	}
+	defer fd.Close()
+
+	list, err := fd.Readdir(-1)
+	if err != nil {
+		return nil, err
+	}
+
+	pkgs = make(map[string]*ast.Package)
+	for _, d := range list {
+		if strings.HasSuffix(d.Name(), ".go") && (filter == nil || filter(d)) {
+			filename := filepath.Join(path, d.Name())
+			if src, err := ParseFile(fset, filename, nil, mode); err == nil {
+				name := src.Name.Name
+				pkg, found := pkgs[name]
+				if !found {
+					pkg = &ast.Package{
+						Name:  name,
+						Files: make(map[string]*ast.File),
+					}
+					pkgs[name] = pkg
+				}
+				pkg.Files[filename] = src
+			} else if first == nil {
+				first = err
+			}
+		}
+	}
+
+	return
+}
+
+// ParseExpr is a convenience function for obtaining the AST of an expression x.
+// The position information recorded in the AST is undefined. The filename used
+// in error messages is the empty string.
+//
+func ParseExpr(x string) (ast.Expr, error) {
+	var p parser
+	p.init(token.NewFileSet(), "", []byte(x), 0)
+
+	// Set up pkg-level scopes to avoid nil-pointer errors.
+	// This is not needed for a correct expression x as the
+	// parser will be ok with a nil topScope, but be cautious
+	// in case of an erroneous x.
+	p.openScope()
+	p.pkgScope = p.topScope
+	e := p.parseRhsOrType()
+	p.closeScope()
+	assert(p.topScope == nil, "unbalanced scopes")
+
+	// If a semicolon was inserted, consume it;
+	// report an error if there's more tokens.
+	if p.tok == token.SEMICOLON && p.lit == "\n" {
+		p.next()
+	}
+	p.expect(token.EOF)
+
+	if p.errors.Len() > 0 {
+		p.errors.Sort()
+		return nil, p.errors.Err()
+	}
+
+	return e, nil
+}
diff --git a/src/go/parser/parser.go b/src/go/parser/parser.go
new file mode 100644
index 0000000..4a005d8
--- /dev/null
+++ b/src/go/parser/parser.go
@@ -0,0 +1,2462 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package parser implements a parser for Go source files. Input may be
+// provided in a variety of forms (see the various Parse* functions); the
+// output is an abstract syntax tree (AST) representing the Go source. The
+// parser is invoked through one of the Parse* functions.
+//
+package parser
+
+import (
+	"fmt"
+	"go/ast"
+	"go/scanner"
+	"go/token"
+	"strconv"
+	"strings"
+	"unicode"
+)
+
+// The parser structure holds the parser's internal state.
+type parser struct {
+	file    *token.File
+	errors  scanner.ErrorList
+	scanner scanner.Scanner
+
+	// Tracing/debugging
+	mode   Mode // parsing mode
+	trace  bool // == (mode & Trace != 0)
+	indent int  // indentation used for tracing output
+
+	// Comments
+	comments    []*ast.CommentGroup
+	leadComment *ast.CommentGroup // last lead comment
+	lineComment *ast.CommentGroup // last line comment
+
+	// Next token
+	pos token.Pos   // token position
+	tok token.Token // one token look-ahead
+	lit string      // token literal
+
+	// Error recovery
+	// (used to limit the number of calls to syncXXX functions
+	// w/o making scanning progress - avoids potential endless
+	// loops across multiple parser functions during error recovery)
+	syncPos token.Pos // last synchronization position
+	syncCnt int       // number of calls to syncXXX without progress
+
+	// Non-syntactic parser control
+	exprLev int  // < 0: in control clause, >= 0: in expression
+	inRhs   bool // if set, the parser is parsing a rhs expression
+
+	// Ordinary identifier scopes
+	pkgScope   *ast.Scope        // pkgScope.Outer == nil
+	topScope   *ast.Scope        // top-most scope; may be pkgScope
+	unresolved []*ast.Ident      // unresolved identifiers
+	imports    []*ast.ImportSpec // list of imports
+
+	// Label scopes
+	// (maintained by open/close LabelScope)
+	labelScope  *ast.Scope     // label scope for current function
+	targetStack [][]*ast.Ident // stack of unresolved labels
+}
+
+func (p *parser) init(fset *token.FileSet, filename string, src []byte, mode Mode) {
+	p.file = fset.AddFile(filename, -1, len(src))
+	var m scanner.Mode
+	if mode&ParseComments != 0 {
+		m = scanner.ScanComments
+	}
+	eh := func(pos token.Position, msg string) { p.errors.Add(pos, msg) }
+	p.scanner.Init(p.file, src, eh, m)
+
+	p.mode = mode
+	p.trace = mode&Trace != 0 // for convenience (p.trace is used frequently)
+
+	p.next()
+}
+
+// ----------------------------------------------------------------------------
+// Scoping support
+
+func (p *parser) openScope() {
+	p.topScope = ast.NewScope(p.topScope)
+}
+
+func (p *parser) closeScope() {
+	p.topScope = p.topScope.Outer
+}
+
+func (p *parser) openLabelScope() {
+	p.labelScope = ast.NewScope(p.labelScope)
+	p.targetStack = append(p.targetStack, nil)
+}
+
+func (p *parser) closeLabelScope() {
+	// resolve labels
+	n := len(p.targetStack) - 1
+	scope := p.labelScope
+	for _, ident := range p.targetStack[n] {
+		ident.Obj = scope.Lookup(ident.Name)
+		if ident.Obj == nil && p.mode&DeclarationErrors != 0 {
+			p.error(ident.Pos(), fmt.Sprintf("label %s undefined", ident.Name))
+		}
+	}
+	// pop label scope
+	p.targetStack = p.targetStack[0:n]
+	p.labelScope = p.labelScope.Outer
+}
+
+func (p *parser) declare(decl, data interface{}, scope *ast.Scope, kind ast.ObjKind, idents ...*ast.Ident) {
+	for _, ident := range idents {
+		assert(ident.Obj == nil, "identifier already declared or resolved")
+		obj := ast.NewObj(kind, ident.Name)
+		// remember the corresponding declaration for redeclaration
+		// errors and global variable resolution/typechecking phase
+		obj.Decl = decl
+		obj.Data = data
+		ident.Obj = obj
+		if ident.Name != "_" {
+			if alt := scope.Insert(obj); alt != nil && p.mode&DeclarationErrors != 0 {
+				prevDecl := ""
+				if pos := alt.Pos(); pos.IsValid() {
+					prevDecl = fmt.Sprintf("\n\tprevious declaration at %s", p.file.Position(pos))
+				}
+				p.error(ident.Pos(), fmt.Sprintf("%s redeclared in this block%s", ident.Name, prevDecl))
+			}
+		}
+	}
+}
+
+func (p *parser) shortVarDecl(decl *ast.AssignStmt, list []ast.Expr) {
+	// Go spec: A short variable declaration may redeclare variables
+	// provided they were originally declared in the same block with
+	// the same type, and at least one of the non-blank variables is new.
+	n := 0 // number of new variables
+	for _, x := range list {
+		if ident, isIdent := x.(*ast.Ident); isIdent {
+			assert(ident.Obj == nil, "identifier already declared or resolved")
+			obj := ast.NewObj(ast.Var, ident.Name)
+			// remember corresponding assignment for other tools
+			obj.Decl = decl
+			ident.Obj = obj
+			if ident.Name != "_" {
+				if alt := p.topScope.Insert(obj); alt != nil {
+					ident.Obj = alt // redeclaration
+				} else {
+					n++ // new declaration
+				}
+			}
+		} else {
+			p.errorExpected(x.Pos(), "identifier on left side of :=")
+		}
+	}
+	if n == 0 && p.mode&DeclarationErrors != 0 {
+		p.error(list[0].Pos(), "no new variables on left side of :=")
+	}
+}
+
+// The unresolved object is a sentinel to mark identifiers that have been added
+// to the list of unresolved identifiers. The sentinel is only used for verifying
+// internal consistency.
+var unresolved = new(ast.Object)
+
+// If x is an identifier, tryResolve attempts to resolve x by looking up
+// the object it denotes. If no object is found and collectUnresolved is
+// set, x is marked as unresolved and collected in the list of unresolved
+// identifiers.
+//
+func (p *parser) tryResolve(x ast.Expr, collectUnresolved bool) {
+	// nothing to do if x is not an identifier or the blank identifier
+	ident, _ := x.(*ast.Ident)
+	if ident == nil {
+		return
+	}
+	assert(ident.Obj == nil, "identifier already declared or resolved")
+	if ident.Name == "_" {
+		return
+	}
+	// try to resolve the identifier
+	for s := p.topScope; s != nil; s = s.Outer {
+		if obj := s.Lookup(ident.Name); obj != nil {
+			ident.Obj = obj
+			return
+		}
+	}
+	// all local scopes are known, so any unresolved identifier
+	// must be found either in the file scope, package scope
+	// (perhaps in another file), or universe scope --- collect
+	// them so that they can be resolved later
+	if collectUnresolved {
+		ident.Obj = unresolved
+		p.unresolved = append(p.unresolved, ident)
+	}
+}
+
+func (p *parser) resolve(x ast.Expr) {
+	p.tryResolve(x, true)
+}
+
+// ----------------------------------------------------------------------------
+// Parsing support
+
+func (p *parser) printTrace(a ...interface{}) {
+	const dots = ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . "
+	const n = len(dots)
+	pos := p.file.Position(p.pos)
+	fmt.Printf("%5d:%3d: ", pos.Line, pos.Column)
+	i := 2 * p.indent
+	for i > n {
+		fmt.Print(dots)
+		i -= n
+	}
+	// i <= n
+	fmt.Print(dots[0:i])
+	fmt.Println(a...)
+}
+
+func trace(p *parser, msg string) *parser {
+	p.printTrace(msg, "(")
+	p.indent++
+	return p
+}
+
+// Usage pattern: defer un(trace(p, "..."))
+func un(p *parser) {
+	p.indent--
+	p.printTrace(")")
+}
+
+// Advance to the next token.
+func (p *parser) next0() {
+	// Because of one-token look-ahead, print the previous token
+	// when tracing as it provides a more readable output. The
+	// very first token (!p.pos.IsValid()) is not initialized
+	// (it is token.ILLEGAL), so don't print it .
+	if p.trace && p.pos.IsValid() {
+		s := p.tok.String()
+		switch {
+		case p.tok.IsLiteral():
+			p.printTrace(s, p.lit)
+		case p.tok.IsOperator(), p.tok.IsKeyword():
+			p.printTrace("\"" + s + "\"")
+		default:
+			p.printTrace(s)
+		}
+	}
+
+	p.pos, p.tok, p.lit = p.scanner.Scan()
+}
+
+// Consume a comment and return it and the line on which it ends.
+func (p *parser) consumeComment() (comment *ast.Comment, endline int) {
+	// /*-style comments may end on a different line than where they start.
+	// Scan the comment for '\n' chars and adjust endline accordingly.
+	endline = p.file.Line(p.pos)
+	if p.lit[1] == '*' {
+		// don't use range here - no need to decode Unicode code points
+		for i := 0; i < len(p.lit); i++ {
+			if p.lit[i] == '\n' {
+				endline++
+			}
+		}
+	}
+
+	comment = &ast.Comment{Slash: p.pos, Text: p.lit}
+	p.next0()
+
+	return
+}
+
+// Consume a group of adjacent comments, add it to the parser's
+// comments list, and return it together with the line at which
+// the last comment in the group ends. A non-comment token or n
+// empty lines terminate a comment group.
+//
+func (p *parser) consumeCommentGroup(n int) (comments *ast.CommentGroup, endline int) {
+	var list []*ast.Comment
+	endline = p.file.Line(p.pos)
+	for p.tok == token.COMMENT && p.file.Line(p.pos) <= endline+n {
+		var comment *ast.Comment
+		comment, endline = p.consumeComment()
+		list = append(list, comment)
+	}
+
+	// add comment group to the comments list
+	comments = &ast.CommentGroup{List: list}
+	p.comments = append(p.comments, comments)
+
+	return
+}
+
+// Advance to the next non-comment token. In the process, collect
+// any comment groups encountered, and remember the last lead and
+// and line comments.
+//
+// A lead comment is a comment group that starts and ends in a
+// line without any other tokens and that is followed by a non-comment
+// token on the line immediately after the comment group.
+//
+// A line comment is a comment group that follows a non-comment
+// token on the same line, and that has no tokens after it on the line
+// where it ends.
+//
+// Lead and line comments may be considered documentation that is
+// stored in the AST.
+//
+func (p *parser) next() {
+	p.leadComment = nil
+	p.lineComment = nil
+	prev := p.pos
+	p.next0()
+
+	if p.tok == token.COMMENT {
+		var comment *ast.CommentGroup
+		var endline int
+
+		if p.file.Line(p.pos) == p.file.Line(prev) {
+			// The comment is on same line as the previous token; it
+			// cannot be a lead comment but may be a line comment.
+			comment, endline = p.consumeCommentGroup(0)
+			if p.file.Line(p.pos) != endline {
+				// The next token is on a different line, thus
+				// the last comment group is a line comment.
+				p.lineComment = comment
+			}
+		}
+
+		// consume successor comments, if any
+		endline = -1
+		for p.tok == token.COMMENT {
+			comment, endline = p.consumeCommentGroup(1)
+		}
+
+		if endline+1 == p.file.Line(p.pos) {
+			// The next token is following on the line immediately after the
+			// comment group, thus the last comment group is a lead comment.
+			p.leadComment = comment
+		}
+	}
+}
+
+// A bailout panic is raised to indicate early termination.
+type bailout struct{}
+
+func (p *parser) error(pos token.Pos, msg string) {
+	epos := p.file.Position(pos)
+
+	// If AllErrors is not set, discard errors reported on the same line
+	// as the last recorded error and stop parsing if there are more than
+	// 10 errors.
+	if p.mode&AllErrors == 0 {
+		n := len(p.errors)
+		if n > 0 && p.errors[n-1].Pos.Line == epos.Line {
+			return // discard - likely a spurious error
+		}
+		if n > 10 {
+			panic(bailout{})
+		}
+	}
+
+	p.errors.Add(epos, msg)
+}
+
+func (p *parser) errorExpected(pos token.Pos, msg string) {
+	msg = "expected " + msg
+	if pos == p.pos {
+		// the error happened at the current position;
+		// make the error message more specific
+		if p.tok == token.SEMICOLON && p.lit == "\n" {
+			msg += ", found newline"
+		} else {
+			msg += ", found '" + p.tok.String() + "'"
+			if p.tok.IsLiteral() {
+				msg += " " + p.lit
+			}
+		}
+	}
+	p.error(pos, msg)
+}
+
+func (p *parser) expect(tok token.Token) token.Pos {
+	pos := p.pos
+	if p.tok != tok {
+		p.errorExpected(pos, "'"+tok.String()+"'")
+	}
+	p.next() // make progress
+	return pos
+}
+
+// expectClosing is like expect but provides a better error message
+// for the common case of a missing comma before a newline.
+//
+func (p *parser) expectClosing(tok token.Token, context string) token.Pos {
+	if p.tok != tok && p.tok == token.SEMICOLON && p.lit == "\n" {
+		p.error(p.pos, "missing ',' before newline in "+context)
+		p.next()
+	}
+	return p.expect(tok)
+}
+
+func (p *parser) expectSemi() {
+	// semicolon is optional before a closing ')' or '}'
+	if p.tok != token.RPAREN && p.tok != token.RBRACE {
+		if p.tok == token.SEMICOLON {
+			p.next()
+		} else {
+			p.errorExpected(p.pos, "';'")
+			syncStmt(p)
+		}
+	}
+}
+
+func (p *parser) atComma(context string) bool {
+	if p.tok == token.COMMA {
+		return true
+	}
+	if p.tok == token.SEMICOLON && p.lit == "\n" {
+		p.error(p.pos, "missing ',' before newline in "+context)
+		return true // "insert" the comma and continue
+
+	}
+	return false
+}
+
+func assert(cond bool, msg string) {
+	if !cond {
+		panic("go/parser internal error: " + msg)
+	}
+}
+
+// syncStmt advances to the next statement.
+// Used for synchronization after an error.
+//
+func syncStmt(p *parser) {
+	for {
+		switch p.tok {
+		case token.BREAK, token.CONST, token.CONTINUE, token.DEFER,
+			token.FALLTHROUGH, token.FOR, token.GO, token.GOTO,
+			token.IF, token.RETURN, token.SELECT, token.SWITCH,
+			token.TYPE, token.VAR:
+			// Return only if parser made some progress since last
+			// sync or if it has not reached 10 sync calls without
+			// progress. Otherwise consume at least one token to
+			// avoid an endless parser loop (it is possible that
+			// both parseOperand and parseStmt call syncStmt and
+			// correctly do not advance, thus the need for the
+			// invocation limit p.syncCnt).
+			if p.pos == p.syncPos && p.syncCnt < 10 {
+				p.syncCnt++
+				return
+			}
+			if p.pos > p.syncPos {
+				p.syncPos = p.pos
+				p.syncCnt = 0
+				return
+			}
+			// Reaching here indicates a parser bug, likely an
+			// incorrect token list in this function, but it only
+			// leads to skipping of possibly correct code if a
+			// previous error is present, and thus is preferred
+			// over a non-terminating parse.
+		case token.EOF:
+			return
+		}
+		p.next()
+	}
+}
+
+// syncDecl advances to the next declaration.
+// Used for synchronization after an error.
+//
+func syncDecl(p *parser) {
+	for {
+		switch p.tok {
+		case token.CONST, token.TYPE, token.VAR:
+			// see comments in syncStmt
+			if p.pos == p.syncPos && p.syncCnt < 10 {
+				p.syncCnt++
+				return
+			}
+			if p.pos > p.syncPos {
+				p.syncPos = p.pos
+				p.syncCnt = 0
+				return
+			}
+		case token.EOF:
+			return
+		}
+		p.next()
+	}
+}
+
+// safePos returns a valid file position for a given position: If pos
+// is valid to begin with, safePos returns pos. If pos is out-of-range,
+// safePos returns the EOF position.
+//
+// This is hack to work around "artificial" end positions in the AST which
+// are computed by adding 1 to (presumably valid) token positions. If the
+// token positions are invalid due to parse errors, the resulting end position
+// may be past the file's EOF position, which would lead to panics if used
+// later on.
+//
+func (p *parser) safePos(pos token.Pos) (res token.Pos) {
+	defer func() {
+		if recover() != nil {
+			res = token.Pos(p.file.Base() + p.file.Size()) // EOF position
+		}
+	}()
+	_ = p.file.Offset(pos) // trigger a panic if position is out-of-range
+	return pos
+}
+
+// ----------------------------------------------------------------------------
+// Identifiers
+
+func (p *parser) parseIdent() *ast.Ident {
+	pos := p.pos
+	name := "_"
+	if p.tok == token.IDENT {
+		name = p.lit
+		p.next()
+	} else {
+		p.expect(token.IDENT) // use expect() error handling
+	}
+	return &ast.Ident{NamePos: pos, Name: name}
+}
+
+func (p *parser) parseIdentList() (list []*ast.Ident) {
+	if p.trace {
+		defer un(trace(p, "IdentList"))
+	}
+
+	list = append(list, p.parseIdent())
+	for p.tok == token.COMMA {
+		p.next()
+		list = append(list, p.parseIdent())
+	}
+
+	return
+}
+
+// ----------------------------------------------------------------------------
+// Common productions
+
+// If lhs is set, result list elements which are identifiers are not resolved.
+func (p *parser) parseExprList(lhs bool) (list []ast.Expr) {
+	if p.trace {
+		defer un(trace(p, "ExpressionList"))
+	}
+
+	list = append(list, p.checkExpr(p.parseExpr(lhs)))
+	for p.tok == token.COMMA {
+		p.next()
+		list = append(list, p.checkExpr(p.parseExpr(lhs)))
+	}
+
+	return
+}
+
+func (p *parser) parseLhsList() []ast.Expr {
+	old := p.inRhs
+	p.inRhs = false
+	list := p.parseExprList(true)
+	switch p.tok {
+	case token.DEFINE:
+		// lhs of a short variable declaration
+		// but doesn't enter scope until later:
+		// caller must call p.shortVarDecl(p.makeIdentList(list))
+		// at appropriate time.
+	case token.COLON:
+		// lhs of a label declaration or a communication clause of a select
+		// statement (parseLhsList is not called when parsing the case clause
+		// of a switch statement):
+		// - labels are declared by the caller of parseLhsList
+		// - for communication clauses, if there is a stand-alone identifier
+		//   followed by a colon, we have a syntax error; there is no need
+		//   to resolve the identifier in that case
+	default:
+		// identifiers must be declared elsewhere
+		for _, x := range list {
+			p.resolve(x)
+		}
+	}
+	p.inRhs = old
+	return list
+}
+
+func (p *parser) parseRhsList() []ast.Expr {
+	old := p.inRhs
+	p.inRhs = true
+	list := p.parseExprList(false)
+	p.inRhs = old
+	return list
+}
+
+// ----------------------------------------------------------------------------
+// Types
+
+func (p *parser) parseType() ast.Expr {
+	if p.trace {
+		defer un(trace(p, "Type"))
+	}
+
+	typ := p.tryType()
+
+	if typ == nil {
+		pos := p.pos
+		p.errorExpected(pos, "type")
+		p.next() // make progress
+		return &ast.BadExpr{From: pos, To: p.pos}
+	}
+
+	return typ
+}
+
+// If the result is an identifier, it is not resolved.
+func (p *parser) parseTypeName() ast.Expr {
+	if p.trace {
+		defer un(trace(p, "TypeName"))
+	}
+
+	ident := p.parseIdent()
+	// don't resolve ident yet - it may be a parameter or field name
+
+	if p.tok == token.PERIOD {
+		// ident is a package name
+		p.next()
+		p.resolve(ident)
+		sel := p.parseIdent()
+		return &ast.SelectorExpr{X: ident, Sel: sel}
+	}
+
+	return ident
+}
+
+func (p *parser) parseArrayType() ast.Expr {
+	if p.trace {
+		defer un(trace(p, "ArrayType"))
+	}
+
+	lbrack := p.expect(token.LBRACK)
+	p.exprLev++
+	var len ast.Expr
+	// always permit ellipsis for more fault-tolerant parsing
+	if p.tok == token.ELLIPSIS {
+		len = &ast.Ellipsis{Ellipsis: p.pos}
+		p.next()
+	} else if p.tok != token.RBRACK {
+		len = p.parseRhs()
+	}
+	p.exprLev--
+	p.expect(token.RBRACK)
+	elt := p.parseType()
+
+	return &ast.ArrayType{Lbrack: lbrack, Len: len, Elt: elt}
+}
+
+func (p *parser) makeIdentList(list []ast.Expr) []*ast.Ident {
+	idents := make([]*ast.Ident, len(list))
+	for i, x := range list {
+		ident, isIdent := x.(*ast.Ident)
+		if !isIdent {
+			if _, isBad := x.(*ast.BadExpr); !isBad {
+				// only report error if it's a new one
+				p.errorExpected(x.Pos(), "identifier")
+			}
+			ident = &ast.Ident{NamePos: x.Pos(), Name: "_"}
+		}
+		idents[i] = ident
+	}
+	return idents
+}
+
+func (p *parser) parseFieldDecl(scope *ast.Scope) *ast.Field {
+	if p.trace {
+		defer un(trace(p, "FieldDecl"))
+	}
+
+	doc := p.leadComment
+
+	// FieldDecl
+	list, typ := p.parseVarList(false)
+
+	// Tag
+	var tag *ast.BasicLit
+	if p.tok == token.STRING {
+		tag = &ast.BasicLit{ValuePos: p.pos, Kind: p.tok, Value: p.lit}
+		p.next()
+	}
+
+	// analyze case
+	var idents []*ast.Ident
+	if typ != nil {
+		// IdentifierList Type
+		idents = p.makeIdentList(list)
+	} else {
+		// ["*"] TypeName (AnonymousField)
+		typ = list[0] // we always have at least one element
+		if n := len(list); n > 1 || !isTypeName(deref(typ)) {
+			pos := typ.Pos()
+			p.errorExpected(pos, "anonymous field")
+			typ = &ast.BadExpr{From: pos, To: p.safePos(list[n-1].End())}
+		}
+	}
+
+	p.expectSemi() // call before accessing p.linecomment
+
+	field := &ast.Field{Doc: doc, Names: idents, Type: typ, Tag: tag, Comment: p.lineComment}
+	p.declare(field, nil, scope, ast.Var, idents...)
+	p.resolve(typ)
+
+	return field
+}
+
+func (p *parser) parseStructType() *ast.StructType {
+	if p.trace {
+		defer un(trace(p, "StructType"))
+	}
+
+	pos := p.expect(token.STRUCT)
+	lbrace := p.expect(token.LBRACE)
+	scope := ast.NewScope(nil) // struct scope
+	var list []*ast.Field
+	for p.tok == token.IDENT || p.tok == token.MUL || p.tok == token.LPAREN {
+		// a field declaration cannot start with a '(' but we accept
+		// it here for more robust parsing and better error messages
+		// (parseFieldDecl will check and complain if necessary)
+		list = append(list, p.parseFieldDecl(scope))
+	}
+	rbrace := p.expect(token.RBRACE)
+
+	return &ast.StructType{
+		Struct: pos,
+		Fields: &ast.FieldList{
+			Opening: lbrace,
+			List:    list,
+			Closing: rbrace,
+		},
+	}
+}
+
+func (p *parser) parsePointerType() *ast.StarExpr {
+	if p.trace {
+		defer un(trace(p, "PointerType"))
+	}
+
+	star := p.expect(token.MUL)
+	base := p.parseType()
+
+	return &ast.StarExpr{Star: star, X: base}
+}
+
+// If the result is an identifier, it is not resolved.
+func (p *parser) tryVarType(isParam bool) ast.Expr {
+	if isParam && p.tok == token.ELLIPSIS {
+		pos := p.pos
+		p.next()
+		typ := p.tryIdentOrType() // don't use parseType so we can provide better error message
+		if typ != nil {
+			p.resolve(typ)
+		} else {
+			p.error(pos, "'...' parameter is missing type")
+			typ = &ast.BadExpr{From: pos, To: p.pos}
+		}
+		return &ast.Ellipsis{Ellipsis: pos, Elt: typ}
+	}
+	return p.tryIdentOrType()
+}
+
+// If the result is an identifier, it is not resolved.
+func (p *parser) parseVarType(isParam bool) ast.Expr {
+	typ := p.tryVarType(isParam)
+	if typ == nil {
+		pos := p.pos
+		p.errorExpected(pos, "type")
+		p.next() // make progress
+		typ = &ast.BadExpr{From: pos, To: p.pos}
+	}
+	return typ
+}
+
+// If any of the results are identifiers, they are not resolved.
+func (p *parser) parseVarList(isParam bool) (list []ast.Expr, typ ast.Expr) {
+	if p.trace {
+		defer un(trace(p, "VarList"))
+	}
+
+	// a list of identifiers looks like a list of type names
+	//
+	// parse/tryVarType accepts any type (including parenthesized
+	// ones) even though the syntax does not permit them here: we
+	// accept them all for more robust parsing and complain later
+	for typ := p.parseVarType(isParam); typ != nil; {
+		list = append(list, typ)
+		if p.tok != token.COMMA {
+			break
+		}
+		p.next()
+		typ = p.tryVarType(isParam) // maybe nil as in: func f(int,) {}
+	}
+
+	// if we had a list of identifiers, it must be followed by a type
+	typ = p.tryVarType(isParam)
+
+	return
+}
+
+func (p *parser) parseParameterList(scope *ast.Scope, ellipsisOk bool) (params []*ast.Field) {
+	if p.trace {
+		defer un(trace(p, "ParameterList"))
+	}
+
+	// ParameterDecl
+	list, typ := p.parseVarList(ellipsisOk)
+
+	// analyze case
+	if typ != nil {
+		// IdentifierList Type
+		idents := p.makeIdentList(list)
+		field := &ast.Field{Names: idents, Type: typ}
+		params = append(params, field)
+		// Go spec: The scope of an identifier denoting a function
+		// parameter or result variable is the function body.
+		p.declare(field, nil, scope, ast.Var, idents...)
+		p.resolve(typ)
+		if !p.atComma("parameter list") {
+			return
+		}
+		p.next()
+		for p.tok != token.RPAREN && p.tok != token.EOF {
+			idents := p.parseIdentList()
+			typ := p.parseVarType(ellipsisOk)
+			field := &ast.Field{Names: idents, Type: typ}
+			params = append(params, field)
+			// Go spec: The scope of an identifier denoting a function
+			// parameter or result variable is the function body.
+			p.declare(field, nil, scope, ast.Var, idents...)
+			p.resolve(typ)
+			if !p.atComma("parameter list") {
+				break
+			}
+			p.next()
+		}
+		return
+	}
+
+	// Type { "," Type } (anonymous parameters)
+	params = make([]*ast.Field, len(list))
+	for i, typ := range list {
+		p.resolve(typ)
+		params[i] = &ast.Field{Type: typ}
+	}
+	return
+}
+
+func (p *parser) parseParameters(scope *ast.Scope, ellipsisOk bool) *ast.FieldList {
+	if p.trace {
+		defer un(trace(p, "Parameters"))
+	}
+
+	var params []*ast.Field
+	lparen := p.expect(token.LPAREN)
+	if p.tok != token.RPAREN {
+		params = p.parseParameterList(scope, ellipsisOk)
+	}
+	rparen := p.expect(token.RPAREN)
+
+	return &ast.FieldList{Opening: lparen, List: params, Closing: rparen}
+}
+
+func (p *parser) parseResult(scope *ast.Scope) *ast.FieldList {
+	if p.trace {
+		defer un(trace(p, "Result"))
+	}
+
+	if p.tok == token.LPAREN {
+		return p.parseParameters(scope, false)
+	}
+
+	typ := p.tryType()
+	if typ != nil {
+		list := make([]*ast.Field, 1)
+		list[0] = &ast.Field{Type: typ}
+		return &ast.FieldList{List: list}
+	}
+
+	return nil
+}
+
+func (p *parser) parseSignature(scope *ast.Scope) (params, results *ast.FieldList) {
+	if p.trace {
+		defer un(trace(p, "Signature"))
+	}
+
+	params = p.parseParameters(scope, true)
+	results = p.parseResult(scope)
+
+	return
+}
+
+func (p *parser) parseFuncType() (*ast.FuncType, *ast.Scope) {
+	if p.trace {
+		defer un(trace(p, "FuncType"))
+	}
+
+	pos := p.expect(token.FUNC)
+	scope := ast.NewScope(p.topScope) // function scope
+	params, results := p.parseSignature(scope)
+
+	return &ast.FuncType{Func: pos, Params: params, Results: results}, scope
+}
+
+func (p *parser) parseMethodSpec(scope *ast.Scope) *ast.Field {
+	if p.trace {
+		defer un(trace(p, "MethodSpec"))
+	}
+
+	doc := p.leadComment
+	var idents []*ast.Ident
+	var typ ast.Expr
+	x := p.parseTypeName()
+	if ident, isIdent := x.(*ast.Ident); isIdent && p.tok == token.LPAREN {
+		// method
+		idents = []*ast.Ident{ident}
+		scope := ast.NewScope(nil) // method scope
+		params, results := p.parseSignature(scope)
+		typ = &ast.FuncType{Func: token.NoPos, Params: params, Results: results}
+	} else {
+		// embedded interface
+		typ = x
+		p.resolve(typ)
+	}
+	p.expectSemi() // call before accessing p.linecomment
+
+	spec := &ast.Field{Doc: doc, Names: idents, Type: typ, Comment: p.lineComment}
+	p.declare(spec, nil, scope, ast.Fun, idents...)
+
+	return spec
+}
+
+func (p *parser) parseInterfaceType() *ast.InterfaceType {
+	if p.trace {
+		defer un(trace(p, "InterfaceType"))
+	}
+
+	pos := p.expect(token.INTERFACE)
+	lbrace := p.expect(token.LBRACE)
+	scope := ast.NewScope(nil) // interface scope
+	var list []*ast.Field
+	for p.tok == token.IDENT {
+		list = append(list, p.parseMethodSpec(scope))
+	}
+	rbrace := p.expect(token.RBRACE)
+
+	return &ast.InterfaceType{
+		Interface: pos,
+		Methods: &ast.FieldList{
+			Opening: lbrace,
+			List:    list,
+			Closing: rbrace,
+		},
+	}
+}
+
+func (p *parser) parseMapType() *ast.MapType {
+	if p.trace {
+		defer un(trace(p, "MapType"))
+	}
+
+	pos := p.expect(token.MAP)
+	p.expect(token.LBRACK)
+	key := p.parseType()
+	p.expect(token.RBRACK)
+	value := p.parseType()
+
+	return &ast.MapType{Map: pos, Key: key, Value: value}
+}
+
+func (p *parser) parseChanType() *ast.ChanType {
+	if p.trace {
+		defer un(trace(p, "ChanType"))
+	}
+
+	pos := p.pos
+	dir := ast.SEND | ast.RECV
+	var arrow token.Pos
+	if p.tok == token.CHAN {
+		p.next()
+		if p.tok == token.ARROW {
+			arrow = p.pos
+			p.next()
+			dir = ast.SEND
+		}
+	} else {
+		arrow = p.expect(token.ARROW)
+		p.expect(token.CHAN)
+		dir = ast.RECV
+	}
+	value := p.parseType()
+
+	return &ast.ChanType{Begin: pos, Arrow: arrow, Dir: dir, Value: value}
+}
+
+// If the result is an identifier, it is not resolved.
+func (p *parser) tryIdentOrType() ast.Expr {
+	switch p.tok {
+	case token.IDENT:
+		return p.parseTypeName()
+	case token.LBRACK:
+		return p.parseArrayType()
+	case token.STRUCT:
+		return p.parseStructType()
+	case token.MUL:
+		return p.parsePointerType()
+	case token.FUNC:
+		typ, _ := p.parseFuncType()
+		return typ
+	case token.INTERFACE:
+		return p.parseInterfaceType()
+	case token.MAP:
+		return p.parseMapType()
+	case token.CHAN, token.ARROW:
+		return p.parseChanType()
+	case token.LPAREN:
+		lparen := p.pos
+		p.next()
+		typ := p.parseType()
+		rparen := p.expect(token.RPAREN)
+		return &ast.ParenExpr{Lparen: lparen, X: typ, Rparen: rparen}
+	}
+
+	// no type found
+	return nil
+}
+
+func (p *parser) tryType() ast.Expr {
+	typ := p.tryIdentOrType()
+	if typ != nil {
+		p.resolve(typ)
+	}
+	return typ
+}
+
+// ----------------------------------------------------------------------------
+// Blocks
+
+func (p *parser) parseStmtList() (list []ast.Stmt) {
+	if p.trace {
+		defer un(trace(p, "StatementList"))
+	}
+
+	for p.tok != token.CASE && p.tok != token.DEFAULT && p.tok != token.RBRACE && p.tok != token.EOF {
+		list = append(list, p.parseStmt())
+	}
+
+	return
+}
+
+func (p *parser) parseBody(scope *ast.Scope) *ast.BlockStmt {
+	if p.trace {
+		defer un(trace(p, "Body"))
+	}
+
+	lbrace := p.expect(token.LBRACE)
+	p.topScope = scope // open function scope
+	p.openLabelScope()
+	list := p.parseStmtList()
+	p.closeLabelScope()
+	p.closeScope()
+	rbrace := p.expect(token.RBRACE)
+
+	return &ast.BlockStmt{Lbrace: lbrace, List: list, Rbrace: rbrace}
+}
+
+func (p *parser) parseBlockStmt() *ast.BlockStmt {
+	if p.trace {
+		defer un(trace(p, "BlockStmt"))
+	}
+
+	lbrace := p.expect(token.LBRACE)
+	p.openScope()
+	list := p.parseStmtList()
+	p.closeScope()
+	rbrace := p.expect(token.RBRACE)
+
+	return &ast.BlockStmt{Lbrace: lbrace, List: list, Rbrace: rbrace}
+}
+
+// ----------------------------------------------------------------------------
+// Expressions
+
+func (p *parser) parseFuncTypeOrLit() ast.Expr {
+	if p.trace {
+		defer un(trace(p, "FuncTypeOrLit"))
+	}
+
+	typ, scope := p.parseFuncType()
+	if p.tok != token.LBRACE {
+		// function type only
+		return typ
+	}
+
+	p.exprLev++
+	body := p.parseBody(scope)
+	p.exprLev--
+
+	return &ast.FuncLit{Type: typ, Body: body}
+}
+
+// parseOperand may return an expression or a raw type (incl. array
+// types of the form [...]T. Callers must verify the result.
+// If lhs is set and the result is an identifier, it is not resolved.
+//
+func (p *parser) parseOperand(lhs bool) ast.Expr {
+	if p.trace {
+		defer un(trace(p, "Operand"))
+	}
+
+	switch p.tok {
+	case token.IDENT:
+		x := p.parseIdent()
+		if !lhs {
+			p.resolve(x)
+		}
+		return x
+
+	case token.INT, token.FLOAT, token.IMAG, token.CHAR, token.STRING:
+		x := &ast.BasicLit{ValuePos: p.pos, Kind: p.tok, Value: p.lit}
+		p.next()
+		return x
+
+	case token.LPAREN:
+		lparen := p.pos
+		p.next()
+		p.exprLev++
+		x := p.parseRhsOrType() // types may be parenthesized: (some type)
+		p.exprLev--
+		rparen := p.expect(token.RPAREN)
+		return &ast.ParenExpr{Lparen: lparen, X: x, Rparen: rparen}
+
+	case token.FUNC:
+		return p.parseFuncTypeOrLit()
+	}
+
+	if typ := p.tryIdentOrType(); typ != nil {
+		// could be type for composite literal or conversion
+		_, isIdent := typ.(*ast.Ident)
+		assert(!isIdent, "type cannot be identifier")
+		return typ
+	}
+
+	// we have an error
+	pos := p.pos
+	p.errorExpected(pos, "operand")
+	syncStmt(p)
+	return &ast.BadExpr{From: pos, To: p.pos}
+}
+
+func (p *parser) parseSelector(x ast.Expr) ast.Expr {
+	if p.trace {
+		defer un(trace(p, "Selector"))
+	}
+
+	sel := p.parseIdent()
+
+	return &ast.SelectorExpr{X: x, Sel: sel}
+}
+
+func (p *parser) parseTypeAssertion(x ast.Expr) ast.Expr {
+	if p.trace {
+		defer un(trace(p, "TypeAssertion"))
+	}
+
+	lparen := p.expect(token.LPAREN)
+	var typ ast.Expr
+	if p.tok == token.TYPE {
+		// type switch: typ == nil
+		p.next()
+	} else {
+		typ = p.parseType()
+	}
+	rparen := p.expect(token.RPAREN)
+
+	return &ast.TypeAssertExpr{X: x, Type: typ, Lparen: lparen, Rparen: rparen}
+}
+
+func (p *parser) parseIndexOrSlice(x ast.Expr) ast.Expr {
+	if p.trace {
+		defer un(trace(p, "IndexOrSlice"))
+	}
+
+	const N = 3 // change the 3 to 2 to disable 3-index slices
+	lbrack := p.expect(token.LBRACK)
+	p.exprLev++
+	var index [N]ast.Expr
+	var colons [N - 1]token.Pos
+	if p.tok != token.COLON {
+		index[0] = p.parseRhs()
+	}
+	ncolons := 0
+	for p.tok == token.COLON && ncolons < len(colons) {
+		colons[ncolons] = p.pos
+		ncolons++
+		p.next()
+		if p.tok != token.COLON && p.tok != token.RBRACK && p.tok != token.EOF {
+			index[ncolons] = p.parseRhs()
+		}
+	}
+	p.exprLev--
+	rbrack := p.expect(token.RBRACK)
+
+	if ncolons > 0 {
+		// slice expression
+		slice3 := false
+		if ncolons == 2 {
+			slice3 = true
+			// Check presence of 2nd and 3rd index here rather than during type-checking
+			// to prevent erroneous programs from passing through gofmt (was issue 7305).
+			if index[1] == nil {
+				p.error(colons[0], "2nd index required in 3-index slice")
+				index[1] = &ast.BadExpr{From: colons[0] + 1, To: colons[1]}
+			}
+			if index[2] == nil {
+				p.error(colons[1], "3rd index required in 3-index slice")
+				index[2] = &ast.BadExpr{From: colons[1] + 1, To: rbrack}
+			}
+		}
+		return &ast.SliceExpr{X: x, Lbrack: lbrack, Low: index[0], High: index[1], Max: index[2], Slice3: slice3, Rbrack: rbrack}
+	}
+
+	return &ast.IndexExpr{X: x, Lbrack: lbrack, Index: index[0], Rbrack: rbrack}
+}
+
+func (p *parser) parseCallOrConversion(fun ast.Expr) *ast.CallExpr {
+	if p.trace {
+		defer un(trace(p, "CallOrConversion"))
+	}
+
+	lparen := p.expect(token.LPAREN)
+	p.exprLev++
+	var list []ast.Expr
+	var ellipsis token.Pos
+	for p.tok != token.RPAREN && p.tok != token.EOF && !ellipsis.IsValid() {
+		list = append(list, p.parseRhsOrType()) // builtins may expect a type: make(some type, ...)
+		if p.tok == token.ELLIPSIS {
+			ellipsis = p.pos
+			p.next()
+		}
+		if !p.atComma("argument list") {
+			break
+		}
+		p.next()
+	}
+	p.exprLev--
+	rparen := p.expectClosing(token.RPAREN, "argument list")
+
+	return &ast.CallExpr{Fun: fun, Lparen: lparen, Args: list, Ellipsis: ellipsis, Rparen: rparen}
+}
+
+func (p *parser) parseElement(keyOk bool) ast.Expr {
+	if p.trace {
+		defer un(trace(p, "Element"))
+	}
+
+	if p.tok == token.LBRACE {
+		return p.parseLiteralValue(nil)
+	}
+
+	// Because the parser doesn't know the composite literal type, it cannot
+	// know if a key that's an identifier is a struct field name or a name
+	// denoting a value. The former is not resolved by the parser or the
+	// resolver.
+	//
+	// Instead, _try_ to resolve such a key if possible. If it resolves,
+	// it a) has correctly resolved, or b) incorrectly resolved because
+	// the key is a struct field with a name matching another identifier.
+	// In the former case we are done, and in the latter case we don't
+	// care because the type checker will do a separate field lookup.
+	//
+	// If the key does not resolve, it a) must be defined at the top
+	// level in another file of the same package, the universe scope, or be
+	// undeclared; or b) it is a struct field. In the former case, the type
+	// checker can do a top-level lookup, and in the latter case it will do
+	// a separate field lookup.
+	x := p.checkExpr(p.parseExpr(keyOk))
+	if keyOk {
+		if p.tok == token.COLON {
+			colon := p.pos
+			p.next()
+			// Try to resolve the key but don't collect it
+			// as unresolved identifier if it fails so that
+			// we don't get (possibly false) errors about
+			// undeclared names.
+			p.tryResolve(x, false)
+			return &ast.KeyValueExpr{Key: x, Colon: colon, Value: p.parseElement(false)}
+		}
+		p.resolve(x) // not a key
+	}
+
+	return x
+}
+
+func (p *parser) parseElementList() (list []ast.Expr) {
+	if p.trace {
+		defer un(trace(p, "ElementList"))
+	}
+
+	for p.tok != token.RBRACE && p.tok != token.EOF {
+		list = append(list, p.parseElement(true))
+		if !p.atComma("composite literal") {
+			break
+		}
+		p.next()
+	}
+
+	return
+}
+
+func (p *parser) parseLiteralValue(typ ast.Expr) ast.Expr {
+	if p.trace {
+		defer un(trace(p, "LiteralValue"))
+	}
+
+	lbrace := p.expect(token.LBRACE)
+	var elts []ast.Expr
+	p.exprLev++
+	if p.tok != token.RBRACE {
+		elts = p.parseElementList()
+	}
+	p.exprLev--
+	rbrace := p.expectClosing(token.RBRACE, "composite literal")
+	return &ast.CompositeLit{Type: typ, Lbrace: lbrace, Elts: elts, Rbrace: rbrace}
+}
+
+// checkExpr checks that x is an expression (and not a type).
+func (p *parser) checkExpr(x ast.Expr) ast.Expr {
+	switch unparen(x).(type) {
+	case *ast.BadExpr:
+	case *ast.Ident:
+	case *ast.BasicLit:
+	case *ast.FuncLit:
+	case *ast.CompositeLit:
+	case *ast.ParenExpr:
+		panic("unreachable")
+	case *ast.SelectorExpr:
+	case *ast.IndexExpr:
+	case *ast.SliceExpr:
+	case *ast.TypeAssertExpr:
+		// If t.Type == nil we have a type assertion of the form
+		// y.(type), which is only allowed in type switch expressions.
+		// It's hard to exclude those but for the case where we are in
+		// a type switch. Instead be lenient and test this in the type
+		// checker.
+	case *ast.CallExpr:
+	case *ast.StarExpr:
+	case *ast.UnaryExpr:
+	case *ast.BinaryExpr:
+	default:
+		// all other nodes are not proper expressions
+		p.errorExpected(x.Pos(), "expression")
+		x = &ast.BadExpr{From: x.Pos(), To: p.safePos(x.End())}
+	}
+	return x
+}
+
+// isTypeName returns true iff x is a (qualified) TypeName.
+func isTypeName(x ast.Expr) bool {
+	switch t := x.(type) {
+	case *ast.BadExpr:
+	case *ast.Ident:
+	case *ast.SelectorExpr:
+		_, isIdent := t.X.(*ast.Ident)
+		return isIdent
+	default:
+		return false // all other nodes are not type names
+	}
+	return true
+}
+
+// isLiteralType returns true iff x is a legal composite literal type.
+func isLiteralType(x ast.Expr) bool {
+	switch t := x.(type) {
+	case *ast.BadExpr:
+	case *ast.Ident:
+	case *ast.SelectorExpr:
+		_, isIdent := t.X.(*ast.Ident)
+		return isIdent
+	case *ast.ArrayType:
+	case *ast.StructType:
+	case *ast.MapType:
+	default:
+		return false // all other nodes are not legal composite literal types
+	}
+	return true
+}
+
+// If x is of the form *T, deref returns T, otherwise it returns x.
+func deref(x ast.Expr) ast.Expr {
+	if p, isPtr := x.(*ast.StarExpr); isPtr {
+		x = p.X
+	}
+	return x
+}
+
+// If x is of the form (T), unparen returns unparen(T), otherwise it returns x.
+func unparen(x ast.Expr) ast.Expr {
+	if p, isParen := x.(*ast.ParenExpr); isParen {
+		x = unparen(p.X)
+	}
+	return x
+}
+
+// checkExprOrType checks that x is an expression or a type
+// (and not a raw type such as [...]T).
+//
+func (p *parser) checkExprOrType(x ast.Expr) ast.Expr {
+	switch t := unparen(x).(type) {
+	case *ast.ParenExpr:
+		panic("unreachable")
+	case *ast.UnaryExpr:
+	case *ast.ArrayType:
+		if len, isEllipsis := t.Len.(*ast.Ellipsis); isEllipsis {
+			p.error(len.Pos(), "expected array length, found '...'")
+			x = &ast.BadExpr{From: x.Pos(), To: p.safePos(x.End())}
+		}
+	}
+
+	// all other nodes are expressions or types
+	return x
+}
+
+// If lhs is set and the result is an identifier, it is not resolved.
+func (p *parser) parsePrimaryExpr(lhs bool) ast.Expr {
+	if p.trace {
+		defer un(trace(p, "PrimaryExpr"))
+	}
+
+	x := p.parseOperand(lhs)
+L:
+	for {
+		switch p.tok {
+		case token.PERIOD:
+			p.next()
+			if lhs {
+				p.resolve(x)
+			}
+			switch p.tok {
+			case token.IDENT:
+				x = p.parseSelector(p.checkExprOrType(x))
+			case token.LPAREN:
+				x = p.parseTypeAssertion(p.checkExpr(x))
+			default:
+				pos := p.pos
+				p.errorExpected(pos, "selector or type assertion")
+				p.next() // make progress
+				x = &ast.BadExpr{From: pos, To: p.pos}
+			}
+		case token.LBRACK:
+			if lhs {
+				p.resolve(x)
+			}
+			x = p.parseIndexOrSlice(p.checkExpr(x))
+		case token.LPAREN:
+			if lhs {
+				p.resolve(x)
+			}
+			x = p.parseCallOrConversion(p.checkExprOrType(x))
+		case token.LBRACE:
+			if isLiteralType(x) && (p.exprLev >= 0 || !isTypeName(x)) {
+				if lhs {
+					p.resolve(x)
+				}
+				x = p.parseLiteralValue(x)
+			} else {
+				break L
+			}
+		default:
+			break L
+		}
+		lhs = false // no need to try to resolve again
+	}
+
+	return x
+}
+
+// If lhs is set and the result is an identifier, it is not resolved.
+func (p *parser) parseUnaryExpr(lhs bool) ast.Expr {
+	if p.trace {
+		defer un(trace(p, "UnaryExpr"))
+	}
+
+	switch p.tok {
+	case token.ADD, token.SUB, token.NOT, token.XOR, token.AND:
+		pos, op := p.pos, p.tok
+		p.next()
+		x := p.parseUnaryExpr(false)
+		return &ast.UnaryExpr{OpPos: pos, Op: op, X: p.checkExpr(x)}
+
+	case token.ARROW:
+		// channel type or receive expression
+		arrow := p.pos
+		p.next()
+
+		// If the next token is token.CHAN we still don't know if it
+		// is a channel type or a receive operation - we only know
+		// once we have found the end of the unary expression. There
+		// are two cases:
+		//
+		//   <- type  => (<-type) must be channel type
+		//   <- expr  => <-(expr) is a receive from an expression
+		//
+		// In the first case, the arrow must be re-associated with
+		// the channel type parsed already:
+		//
+		//   <- (chan type)    =>  (<-chan type)
+		//   <- (chan<- type)  =>  (<-chan (<-type))
+
+		x := p.parseUnaryExpr(false)
+
+		// determine which case we have
+		if typ, ok := x.(*ast.ChanType); ok {
+			// (<-type)
+
+			// re-associate position info and <-
+			dir := ast.SEND
+			for ok && dir == ast.SEND {
+				if typ.Dir == ast.RECV {
+					// error: (<-type) is (<-(<-chan T))
+					p.errorExpected(typ.Arrow, "'chan'")
+				}
+				arrow, typ.Begin, typ.Arrow = typ.Arrow, arrow, arrow
+				dir, typ.Dir = typ.Dir, ast.RECV
+				typ, ok = typ.Value.(*ast.ChanType)
+			}
+			if dir == ast.SEND {
+				p.errorExpected(arrow, "channel type")
+			}
+
+			return x
+		}
+
+		// <-(expr)
+		return &ast.UnaryExpr{OpPos: arrow, Op: token.ARROW, X: p.checkExpr(x)}
+
+	case token.MUL:
+		// pointer type or unary "*" expression
+		pos := p.pos
+		p.next()
+		x := p.parseUnaryExpr(false)
+		return &ast.StarExpr{Star: pos, X: p.checkExprOrType(x)}
+	}
+
+	return p.parsePrimaryExpr(lhs)
+}
+
+func (p *parser) tokPrec() (token.Token, int) {
+	tok := p.tok
+	if p.inRhs && tok == token.ASSIGN {
+		tok = token.EQL
+	}
+	return tok, tok.Precedence()
+}
+
+// If lhs is set and the result is an identifier, it is not resolved.
+func (p *parser) parseBinaryExpr(lhs bool, prec1 int) ast.Expr {
+	if p.trace {
+		defer un(trace(p, "BinaryExpr"))
+	}
+
+	x := p.parseUnaryExpr(lhs)
+	for _, prec := p.tokPrec(); prec >= prec1; prec-- {
+		for {
+			op, oprec := p.tokPrec()
+			if oprec != prec {
+				break
+			}
+			pos := p.expect(op)
+			if lhs {
+				p.resolve(x)
+				lhs = false
+			}
+			y := p.parseBinaryExpr(false, prec+1)
+			x = &ast.BinaryExpr{X: p.checkExpr(x), OpPos: pos, Op: op, Y: p.checkExpr(y)}
+		}
+	}
+
+	return x
+}
+
+// If lhs is set and the result is an identifier, it is not resolved.
+// The result may be a type or even a raw type ([...]int). Callers must
+// check the result (using checkExpr or checkExprOrType), depending on
+// context.
+func (p *parser) parseExpr(lhs bool) ast.Expr {
+	if p.trace {
+		defer un(trace(p, "Expression"))
+	}
+
+	return p.parseBinaryExpr(lhs, token.LowestPrec+1)
+}
+
+func (p *parser) parseRhs() ast.Expr {
+	old := p.inRhs
+	p.inRhs = true
+	x := p.checkExpr(p.parseExpr(false))
+	p.inRhs = old
+	return x
+}
+
+func (p *parser) parseRhsOrType() ast.Expr {
+	old := p.inRhs
+	p.inRhs = true
+	x := p.checkExprOrType(p.parseExpr(false))
+	p.inRhs = old
+	return x
+}
+
+// ----------------------------------------------------------------------------
+// Statements
+
+// Parsing modes for parseSimpleStmt.
+const (
+	basic = iota
+	labelOk
+	rangeOk
+)
+
+// parseSimpleStmt returns true as 2nd result if it parsed the assignment
+// of a range clause (with mode == rangeOk). The returned statement is an
+// assignment with a right-hand side that is a single unary expression of
+// the form "range x". No guarantees are given for the left-hand side.
+func (p *parser) parseSimpleStmt(mode int) (ast.Stmt, bool) {
+	if p.trace {
+		defer un(trace(p, "SimpleStmt"))
+	}
+
+	x := p.parseLhsList()
+
+	switch p.tok {
+	case
+		token.DEFINE, token.ASSIGN, token.ADD_ASSIGN,
+		token.SUB_ASSIGN, token.MUL_ASSIGN, token.QUO_ASSIGN,
+		token.REM_ASSIGN, token.AND_ASSIGN, token.OR_ASSIGN,
+		token.XOR_ASSIGN, token.SHL_ASSIGN, token.SHR_ASSIGN, token.AND_NOT_ASSIGN:
+		// assignment statement, possibly part of a range clause
+		pos, tok := p.pos, p.tok
+		p.next()
+		var y []ast.Expr
+		isRange := false
+		if mode == rangeOk && p.tok == token.RANGE && (tok == token.DEFINE || tok == token.ASSIGN) {
+			pos := p.pos
+			p.next()
+			y = []ast.Expr{&ast.UnaryExpr{OpPos: pos, Op: token.RANGE, X: p.parseRhs()}}
+			isRange = true
+		} else {
+			y = p.parseRhsList()
+		}
+		as := &ast.AssignStmt{Lhs: x, TokPos: pos, Tok: tok, Rhs: y}
+		if tok == token.DEFINE {
+			p.shortVarDecl(as, x)
+		}
+		return as, isRange
+	}
+
+	if len(x) > 1 {
+		p.errorExpected(x[0].Pos(), "1 expression")
+		// continue with first expression
+	}
+
+	switch p.tok {
+	case token.COLON:
+		// labeled statement
+		colon := p.pos
+		p.next()
+		if label, isIdent := x[0].(*ast.Ident); mode == labelOk && isIdent {
+			// Go spec: The scope of a label is the body of the function
+			// in which it is declared and excludes the body of any nested
+			// function.
+			stmt := &ast.LabeledStmt{Label: label, Colon: colon, Stmt: p.parseStmt()}
+			p.declare(stmt, nil, p.labelScope, ast.Lbl, label)
+			return stmt, false
+		}
+		// The label declaration typically starts at x[0].Pos(), but the label
+		// declaration may be erroneous due to a token after that position (and
+		// before the ':'). If SpuriousErrors is not set, the (only) error re-
+		// ported for the line is the illegal label error instead of the token
+		// before the ':' that caused the problem. Thus, use the (latest) colon
+		// position for error reporting.
+		p.error(colon, "illegal label declaration")
+		return &ast.BadStmt{From: x[0].Pos(), To: colon + 1}, false
+
+	case token.ARROW:
+		// send statement
+		arrow := p.pos
+		p.next()
+		y := p.parseRhs()
+		return &ast.SendStmt{Chan: x[0], Arrow: arrow, Value: y}, false
+
+	case token.INC, token.DEC:
+		// increment or decrement
+		s := &ast.IncDecStmt{X: x[0], TokPos: p.pos, Tok: p.tok}
+		p.next()
+		return s, false
+	}
+
+	// expression
+	return &ast.ExprStmt{X: x[0]}, false
+}
+
+func (p *parser) parseCallExpr(callType string) *ast.CallExpr {
+	x := p.parseRhsOrType() // could be a conversion: (some type)(x)
+	if call, isCall := x.(*ast.CallExpr); isCall {
+		return call
+	}
+	if _, isBad := x.(*ast.BadExpr); !isBad {
+		// only report error if it's a new one
+		p.error(p.safePos(x.End()), fmt.Sprintf("function must be invoked in %s statement", callType))
+	}
+	return nil
+}
+
+func (p *parser) parseGoStmt() ast.Stmt {
+	if p.trace {
+		defer un(trace(p, "GoStmt"))
+	}
+
+	pos := p.expect(token.GO)
+	call := p.parseCallExpr("go")
+	p.expectSemi()
+	if call == nil {
+		return &ast.BadStmt{From: pos, To: pos + 2} // len("go")
+	}
+
+	return &ast.GoStmt{Go: pos, Call: call}
+}
+
+func (p *parser) parseDeferStmt() ast.Stmt {
+	if p.trace {
+		defer un(trace(p, "DeferStmt"))
+	}
+
+	pos := p.expect(token.DEFER)
+	call := p.parseCallExpr("defer")
+	p.expectSemi()
+	if call == nil {
+		return &ast.BadStmt{From: pos, To: pos + 5} // len("defer")
+	}
+
+	return &ast.DeferStmt{Defer: pos, Call: call}
+}
+
+func (p *parser) parseReturnStmt() *ast.ReturnStmt {
+	if p.trace {
+		defer un(trace(p, "ReturnStmt"))
+	}
+
+	pos := p.pos
+	p.expect(token.RETURN)
+	var x []ast.Expr
+	if p.tok != token.SEMICOLON && p.tok != token.RBRACE {
+		x = p.parseRhsList()
+	}
+	p.expectSemi()
+
+	return &ast.ReturnStmt{Return: pos, Results: x}
+}
+
+func (p *parser) parseBranchStmt(tok token.Token) *ast.BranchStmt {
+	if p.trace {
+		defer un(trace(p, "BranchStmt"))
+	}
+
+	pos := p.expect(tok)
+	var label *ast.Ident
+	if tok != token.FALLTHROUGH && p.tok == token.IDENT {
+		label = p.parseIdent()
+		// add to list of unresolved targets
+		n := len(p.targetStack) - 1
+		p.targetStack[n] = append(p.targetStack[n], label)
+	}
+	p.expectSemi()
+
+	return &ast.BranchStmt{TokPos: pos, Tok: tok, Label: label}
+}
+
+func (p *parser) makeExpr(s ast.Stmt, kind string) ast.Expr {
+	if s == nil {
+		return nil
+	}
+	if es, isExpr := s.(*ast.ExprStmt); isExpr {
+		return p.checkExpr(es.X)
+	}
+	p.error(s.Pos(), fmt.Sprintf("expected %s, found simple statement (missing parentheses around composite literal?)", kind))
+	return &ast.BadExpr{From: s.Pos(), To: p.safePos(s.End())}
+}
+
+func (p *parser) parseIfStmt() *ast.IfStmt {
+	if p.trace {
+		defer un(trace(p, "IfStmt"))
+	}
+
+	pos := p.expect(token.IF)
+	p.openScope()
+	defer p.closeScope()
+
+	var s ast.Stmt
+	var x ast.Expr
+	{
+		prevLev := p.exprLev
+		p.exprLev = -1
+		if p.tok == token.SEMICOLON {
+			p.next()
+			x = p.parseRhs()
+		} else {
+			s, _ = p.parseSimpleStmt(basic)
+			if p.tok == token.SEMICOLON {
+				p.next()
+				x = p.parseRhs()
+			} else {
+				x = p.makeExpr(s, "boolean expression")
+				s = nil
+			}
+		}
+		p.exprLev = prevLev
+	}
+
+	body := p.parseBlockStmt()
+	var else_ ast.Stmt
+	if p.tok == token.ELSE {
+		p.next()
+		else_ = p.parseStmt()
+	} else {
+		p.expectSemi()
+	}
+
+	return &ast.IfStmt{If: pos, Init: s, Cond: x, Body: body, Else: else_}
+}
+
+func (p *parser) parseTypeList() (list []ast.Expr) {
+	if p.trace {
+		defer un(trace(p, "TypeList"))
+	}
+
+	list = append(list, p.parseType())
+	for p.tok == token.COMMA {
+		p.next()
+		list = append(list, p.parseType())
+	}
+
+	return
+}
+
+func (p *parser) parseCaseClause(typeSwitch bool) *ast.CaseClause {
+	if p.trace {
+		defer un(trace(p, "CaseClause"))
+	}
+
+	pos := p.pos
+	var list []ast.Expr
+	if p.tok == token.CASE {
+		p.next()
+		if typeSwitch {
+			list = p.parseTypeList()
+		} else {
+			list = p.parseRhsList()
+		}
+	} else {
+		p.expect(token.DEFAULT)
+	}
+
+	colon := p.expect(token.COLON)
+	p.openScope()
+	body := p.parseStmtList()
+	p.closeScope()
+
+	return &ast.CaseClause{Case: pos, List: list, Colon: colon, Body: body}
+}
+
+func isTypeSwitchAssert(x ast.Expr) bool {
+	a, ok := x.(*ast.TypeAssertExpr)
+	return ok && a.Type == nil
+}
+
+func isTypeSwitchGuard(s ast.Stmt) bool {
+	switch t := s.(type) {
+	case *ast.ExprStmt:
+		// x.(nil)
+		return isTypeSwitchAssert(t.X)
+	case *ast.AssignStmt:
+		// v := x.(nil)
+		return len(t.Lhs) == 1 && t.Tok == token.DEFINE && len(t.Rhs) == 1 && isTypeSwitchAssert(t.Rhs[0])
+	}
+	return false
+}
+
+func (p *parser) parseSwitchStmt() ast.Stmt {
+	if p.trace {
+		defer un(trace(p, "SwitchStmt"))
+	}
+
+	pos := p.expect(token.SWITCH)
+	p.openScope()
+	defer p.closeScope()
+
+	var s1, s2 ast.Stmt
+	if p.tok != token.LBRACE {
+		prevLev := p.exprLev
+		p.exprLev = -1
+		if p.tok != token.SEMICOLON {
+			s2, _ = p.parseSimpleStmt(basic)
+		}
+		if p.tok == token.SEMICOLON {
+			p.next()
+			s1 = s2
+			s2 = nil
+			if p.tok != token.LBRACE {
+				// A TypeSwitchGuard may declare a variable in addition
+				// to the variable declared in the initial SimpleStmt.
+				// Introduce extra scope to avoid redeclaration errors:
+				//
+				//	switch t := 0; t := x.(T) { ... }
+				//
+				// (this code is not valid Go because the first t
+				// cannot be accessed and thus is never used, the extra
+				// scope is needed for the correct error message).
+				//
+				// If we don't have a type switch, s2 must be an expression.
+				// Having the extra nested but empty scope won't affect it.
+				p.openScope()
+				defer p.closeScope()
+				s2, _ = p.parseSimpleStmt(basic)
+			}
+		}
+		p.exprLev = prevLev
+	}
+
+	typeSwitch := isTypeSwitchGuard(s2)
+	lbrace := p.expect(token.LBRACE)
+	var list []ast.Stmt
+	for p.tok == token.CASE || p.tok == token.DEFAULT {
+		list = append(list, p.parseCaseClause(typeSwitch))
+	}
+	rbrace := p.expect(token.RBRACE)
+	p.expectSemi()
+	body := &ast.BlockStmt{Lbrace: lbrace, List: list, Rbrace: rbrace}
+
+	if typeSwitch {
+		return &ast.TypeSwitchStmt{Switch: pos, Init: s1, Assign: s2, Body: body}
+	}
+
+	return &ast.SwitchStmt{Switch: pos, Init: s1, Tag: p.makeExpr(s2, "switch expression"), Body: body}
+}
+
+func (p *parser) parseCommClause() *ast.CommClause {
+	if p.trace {
+		defer un(trace(p, "CommClause"))
+	}
+
+	p.openScope()
+	pos := p.pos
+	var comm ast.Stmt
+	if p.tok == token.CASE {
+		p.next()
+		lhs := p.parseLhsList()
+		if p.tok == token.ARROW {
+			// SendStmt
+			if len(lhs) > 1 {
+				p.errorExpected(lhs[0].Pos(), "1 expression")
+				// continue with first expression
+			}
+			arrow := p.pos
+			p.next()
+			rhs := p.parseRhs()
+			comm = &ast.SendStmt{Chan: lhs[0], Arrow: arrow, Value: rhs}
+		} else {
+			// RecvStmt
+			if tok := p.tok; tok == token.ASSIGN || tok == token.DEFINE {
+				// RecvStmt with assignment
+				if len(lhs) > 2 {
+					p.errorExpected(lhs[0].Pos(), "1 or 2 expressions")
+					// continue with first two expressions
+					lhs = lhs[0:2]
+				}
+				pos := p.pos
+				p.next()
+				rhs := p.parseRhs()
+				as := &ast.AssignStmt{Lhs: lhs, TokPos: pos, Tok: tok, Rhs: []ast.Expr{rhs}}
+				if tok == token.DEFINE {
+					p.shortVarDecl(as, lhs)
+				}
+				comm = as
+			} else {
+				// lhs must be single receive operation
+				if len(lhs) > 1 {
+					p.errorExpected(lhs[0].Pos(), "1 expression")
+					// continue with first expression
+				}
+				comm = &ast.ExprStmt{X: lhs[0]}
+			}
+		}
+	} else {
+		p.expect(token.DEFAULT)
+	}
+
+	colon := p.expect(token.COLON)
+	body := p.parseStmtList()
+	p.closeScope()
+
+	return &ast.CommClause{Case: pos, Comm: comm, Colon: colon, Body: body}
+}
+
+func (p *parser) parseSelectStmt() *ast.SelectStmt {
+	if p.trace {
+		defer un(trace(p, "SelectStmt"))
+	}
+
+	pos := p.expect(token.SELECT)
+	lbrace := p.expect(token.LBRACE)
+	var list []ast.Stmt
+	for p.tok == token.CASE || p.tok == token.DEFAULT {
+		list = append(list, p.parseCommClause())
+	}
+	rbrace := p.expect(token.RBRACE)
+	p.expectSemi()
+	body := &ast.BlockStmt{Lbrace: lbrace, List: list, Rbrace: rbrace}
+
+	return &ast.SelectStmt{Select: pos, Body: body}
+}
+
+func (p *parser) parseForStmt() ast.Stmt {
+	if p.trace {
+		defer un(trace(p, "ForStmt"))
+	}
+
+	pos := p.expect(token.FOR)
+	p.openScope()
+	defer p.closeScope()
+
+	var s1, s2, s3 ast.Stmt
+	var isRange bool
+	if p.tok != token.LBRACE {
+		prevLev := p.exprLev
+		p.exprLev = -1
+		if p.tok != token.SEMICOLON {
+			if p.tok == token.RANGE {
+				// "for range x" (nil lhs in assignment)
+				pos := p.pos
+				p.next()
+				y := []ast.Expr{&ast.UnaryExpr{OpPos: pos, Op: token.RANGE, X: p.parseRhs()}}
+				s2 = &ast.AssignStmt{Rhs: y}
+				isRange = true
+			} else {
+				s2, isRange = p.parseSimpleStmt(rangeOk)
+			}
+		}
+		if !isRange && p.tok == token.SEMICOLON {
+			p.next()
+			s1 = s2
+			s2 = nil
+			if p.tok != token.SEMICOLON {
+				s2, _ = p.parseSimpleStmt(basic)
+			}
+			p.expectSemi()
+			if p.tok != token.LBRACE {
+				s3, _ = p.parseSimpleStmt(basic)
+			}
+		}
+		p.exprLev = prevLev
+	}
+
+	body := p.parseBlockStmt()
+	p.expectSemi()
+
+	if isRange {
+		as := s2.(*ast.AssignStmt)
+		// check lhs
+		var key, value ast.Expr
+		switch len(as.Lhs) {
+		case 0:
+			// nothing to do
+		case 1:
+			key = as.Lhs[0]
+		case 2:
+			key, value = as.Lhs[0], as.Lhs[1]
+		default:
+			p.errorExpected(as.Lhs[len(as.Lhs)-1].Pos(), "at most 2 expressions")
+			return &ast.BadStmt{From: pos, To: p.safePos(body.End())}
+		}
+		// parseSimpleStmt returned a right-hand side that
+		// is a single unary expression of the form "range x"
+		x := as.Rhs[0].(*ast.UnaryExpr).X
+		return &ast.RangeStmt{
+			For:    pos,
+			Key:    key,
+			Value:  value,
+			TokPos: as.TokPos,
+			Tok:    as.Tok,
+			X:      x,
+			Body:   body,
+		}
+	}
+
+	// regular for statement
+	return &ast.ForStmt{
+		For:  pos,
+		Init: s1,
+		Cond: p.makeExpr(s2, "boolean or range expression"),
+		Post: s3,
+		Body: body,
+	}
+}
+
+func (p *parser) parseStmt() (s ast.Stmt) {
+	if p.trace {
+		defer un(trace(p, "Statement"))
+	}
+
+	switch p.tok {
+	case token.CONST, token.TYPE, token.VAR:
+		s = &ast.DeclStmt{Decl: p.parseDecl(syncStmt)}
+	case
+		// tokens that may start an expression
+		token.IDENT, token.INT, token.FLOAT, token.IMAG, token.CHAR, token.STRING, token.FUNC, token.LPAREN, // operands
+		token.LBRACK, token.STRUCT, // composite types
+		token.ADD, token.SUB, token.MUL, token.AND, token.XOR, token.ARROW, token.NOT: // unary operators
+		s, _ = p.parseSimpleStmt(labelOk)
+		// because of the required look-ahead, labeled statements are
+		// parsed by parseSimpleStmt - don't expect a semicolon after
+		// them
+		if _, isLabeledStmt := s.(*ast.LabeledStmt); !isLabeledStmt {
+			p.expectSemi()
+		}
+	case token.GO:
+		s = p.parseGoStmt()
+	case token.DEFER:
+		s = p.parseDeferStmt()
+	case token.RETURN:
+		s = p.parseReturnStmt()
+	case token.BREAK, token.CONTINUE, token.GOTO, token.FALLTHROUGH:
+		s = p.parseBranchStmt(p.tok)
+	case token.LBRACE:
+		s = p.parseBlockStmt()
+		p.expectSemi()
+	case token.IF:
+		s = p.parseIfStmt()
+	case token.SWITCH:
+		s = p.parseSwitchStmt()
+	case token.SELECT:
+		s = p.parseSelectStmt()
+	case token.FOR:
+		s = p.parseForStmt()
+	case token.SEMICOLON:
+		s = &ast.EmptyStmt{Semicolon: p.pos}
+		p.next()
+	case token.RBRACE:
+		// a semicolon may be omitted before a closing "}"
+		s = &ast.EmptyStmt{Semicolon: p.pos}
+	default:
+		// no statement found
+		pos := p.pos
+		p.errorExpected(pos, "statement")
+		syncStmt(p)
+		s = &ast.BadStmt{From: pos, To: p.pos}
+	}
+
+	return
+}
+
+// ----------------------------------------------------------------------------
+// Declarations
+
+type parseSpecFunction func(doc *ast.CommentGroup, keyword token.Token, iota int) ast.Spec
+
+func isValidImport(lit string) bool {
+	const illegalChars = `!"#$%&'()*,:;<=>?[\]^{|}` + "`\uFFFD"
+	s, _ := strconv.Unquote(lit) // go/scanner returns a legal string literal
+	for _, r := range s {
+		if !unicode.IsGraphic(r) || unicode.IsSpace(r) || strings.ContainsRune(illegalChars, r) {
+			return false
+		}
+	}
+	return s != ""
+}
+
+func (p *parser) parseImportSpec(doc *ast.CommentGroup, _ token.Token, _ int) ast.Spec {
+	if p.trace {
+		defer un(trace(p, "ImportSpec"))
+	}
+
+	var ident *ast.Ident
+	switch p.tok {
+	case token.PERIOD:
+		ident = &ast.Ident{NamePos: p.pos, Name: "."}
+		p.next()
+	case token.IDENT:
+		ident = p.parseIdent()
+	}
+
+	pos := p.pos
+	var path string
+	if p.tok == token.STRING {
+		path = p.lit
+		if !isValidImport(path) {
+			p.error(pos, "invalid import path: "+path)
+		}
+		p.next()
+	} else {
+		p.expect(token.STRING) // use expect() error handling
+	}
+	p.expectSemi() // call before accessing p.linecomment
+
+	// collect imports
+	spec := &ast.ImportSpec{
+		Doc:     doc,
+		Name:    ident,
+		Path:    &ast.BasicLit{ValuePos: pos, Kind: token.STRING, Value: path},
+		Comment: p.lineComment,
+	}
+	p.imports = append(p.imports, spec)
+
+	return spec
+}
+
+func (p *parser) parseValueSpec(doc *ast.CommentGroup, keyword token.Token, iota int) ast.Spec {
+	if p.trace {
+		defer un(trace(p, keyword.String()+"Spec"))
+	}
+
+	idents := p.parseIdentList()
+	typ := p.tryType()
+	var values []ast.Expr
+	// always permit optional initialization for more tolerant parsing
+	if p.tok == token.ASSIGN {
+		p.next()
+		values = p.parseRhsList()
+	}
+	p.expectSemi() // call before accessing p.linecomment
+
+	// Go spec: The scope of a constant or variable identifier declared inside
+	// a function begins at the end of the ConstSpec or VarSpec and ends at
+	// the end of the innermost containing block.
+	// (Global identifiers are resolved in a separate phase after parsing.)
+	spec := &ast.ValueSpec{
+		Doc:     doc,
+		Names:   idents,
+		Type:    typ,
+		Values:  values,
+		Comment: p.lineComment,
+	}
+	kind := ast.Con
+	if keyword == token.VAR {
+		kind = ast.Var
+	}
+	p.declare(spec, iota, p.topScope, kind, idents...)
+
+	return spec
+}
+
+func (p *parser) parseTypeSpec(doc *ast.CommentGroup, _ token.Token, _ int) ast.Spec {
+	if p.trace {
+		defer un(trace(p, "TypeSpec"))
+	}
+
+	ident := p.parseIdent()
+
+	// Go spec: The scope of a type identifier declared inside a function begins
+	// at the identifier in the TypeSpec and ends at the end of the innermost
+	// containing block.
+	// (Global identifiers are resolved in a separate phase after parsing.)
+	spec := &ast.TypeSpec{Doc: doc, Name: ident}
+	p.declare(spec, nil, p.topScope, ast.Typ, ident)
+
+	spec.Type = p.parseType()
+	p.expectSemi() // call before accessing p.linecomment
+	spec.Comment = p.lineComment
+
+	return spec
+}
+
+func (p *parser) parseGenDecl(keyword token.Token, f parseSpecFunction) *ast.GenDecl {
+	if p.trace {
+		defer un(trace(p, "GenDecl("+keyword.String()+")"))
+	}
+
+	doc := p.leadComment
+	pos := p.expect(keyword)
+	var lparen, rparen token.Pos
+	var list []ast.Spec
+	if p.tok == token.LPAREN {
+		lparen = p.pos
+		p.next()
+		for iota := 0; p.tok != token.RPAREN && p.tok != token.EOF; iota++ {
+			list = append(list, f(p.leadComment, keyword, iota))
+		}
+		rparen = p.expect(token.RPAREN)
+		p.expectSemi()
+	} else {
+		list = append(list, f(nil, keyword, 0))
+	}
+
+	return &ast.GenDecl{
+		Doc:    doc,
+		TokPos: pos,
+		Tok:    keyword,
+		Lparen: lparen,
+		Specs:  list,
+		Rparen: rparen,
+	}
+}
+
+func (p *parser) parseFuncDecl() *ast.FuncDecl {
+	if p.trace {
+		defer un(trace(p, "FunctionDecl"))
+	}
+
+	doc := p.leadComment
+	pos := p.expect(token.FUNC)
+	scope := ast.NewScope(p.topScope) // function scope
+
+	var recv *ast.FieldList
+	if p.tok == token.LPAREN {
+		recv = p.parseParameters(scope, false)
+	}
+
+	ident := p.parseIdent()
+
+	params, results := p.parseSignature(scope)
+
+	var body *ast.BlockStmt
+	if p.tok == token.LBRACE {
+		body = p.parseBody(scope)
+	}
+	p.expectSemi()
+
+	decl := &ast.FuncDecl{
+		Doc:  doc,
+		Recv: recv,
+		Name: ident,
+		Type: &ast.FuncType{
+			Func:    pos,
+			Params:  params,
+			Results: results,
+		},
+		Body: body,
+	}
+	if recv == nil {
+		// Go spec: The scope of an identifier denoting a constant, type,
+		// variable, or function (but not method) declared at top level
+		// (outside any function) is the package block.
+		//
+		// init() functions cannot be referred to and there may
+		// be more than one - don't put them in the pkgScope
+		if ident.Name != "init" {
+			p.declare(decl, nil, p.pkgScope, ast.Fun, ident)
+		}
+	}
+
+	return decl
+}
+
+func (p *parser) parseDecl(sync func(*parser)) ast.Decl {
+	if p.trace {
+		defer un(trace(p, "Declaration"))
+	}
+
+	var f parseSpecFunction
+	switch p.tok {
+	case token.CONST, token.VAR:
+		f = p.parseValueSpec
+
+	case token.TYPE:
+		f = p.parseTypeSpec
+
+	case token.FUNC:
+		return p.parseFuncDecl()
+
+	default:
+		pos := p.pos
+		p.errorExpected(pos, "declaration")
+		sync(p)
+		return &ast.BadDecl{From: pos, To: p.pos}
+	}
+
+	return p.parseGenDecl(p.tok, f)
+}
+
+// ----------------------------------------------------------------------------
+// Source files
+
+func (p *parser) parseFile() *ast.File {
+	if p.trace {
+		defer un(trace(p, "File"))
+	}
+
+	// Don't bother parsing the rest if we had errors scanning the first token.
+	// Likely not a Go source file at all.
+	if p.errors.Len() != 0 {
+		return nil
+	}
+
+	// package clause
+	doc := p.leadComment
+	pos := p.expect(token.PACKAGE)
+	// Go spec: The package clause is not a declaration;
+	// the package name does not appear in any scope.
+	ident := p.parseIdent()
+	if ident.Name == "_" && p.mode&DeclarationErrors != 0 {
+		p.error(p.pos, "invalid package name _")
+	}
+	p.expectSemi()
+
+	// Don't bother parsing the rest if we had errors parsing the package clause.
+	// Likely not a Go source file at all.
+	if p.errors.Len() != 0 {
+		return nil
+	}
+
+	p.openScope()
+	p.pkgScope = p.topScope
+	var decls []ast.Decl
+	if p.mode&PackageClauseOnly == 0 {
+		// import decls
+		for p.tok == token.IMPORT {
+			decls = append(decls, p.parseGenDecl(token.IMPORT, p.parseImportSpec))
+		}
+
+		if p.mode&ImportsOnly == 0 {
+			// rest of package body
+			for p.tok != token.EOF {
+				decls = append(decls, p.parseDecl(syncDecl))
+			}
+		}
+	}
+	p.closeScope()
+	assert(p.topScope == nil, "unbalanced scopes")
+	assert(p.labelScope == nil, "unbalanced label scopes")
+
+	// resolve global identifiers within the same file
+	i := 0
+	for _, ident := range p.unresolved {
+		// i <= index for current ident
+		assert(ident.Obj == unresolved, "object already resolved")
+		ident.Obj = p.pkgScope.Lookup(ident.Name) // also removes unresolved sentinel
+		if ident.Obj == nil {
+			p.unresolved[i] = ident
+			i++
+		}
+	}
+
+	return &ast.File{
+		Doc:        doc,
+		Package:    pos,
+		Name:       ident,
+		Decls:      decls,
+		Scope:      p.pkgScope,
+		Imports:    p.imports,
+		Unresolved: p.unresolved[0:i],
+		Comments:   p.comments,
+	}
+}
diff --git a/src/go/parser/parser_test.go b/src/go/parser/parser_test.go
new file mode 100644
index 0000000..85065fd
--- /dev/null
+++ b/src/go/parser/parser_test.go
@@ -0,0 +1,449 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package parser
+
+import (
+	"bytes"
+	"fmt"
+	"go/ast"
+	"go/token"
+	"os"
+	"strings"
+	"testing"
+)
+
+var fset = token.NewFileSet()
+
+var validFiles = []string{
+	"parser.go",
+	"parser_test.go",
+	"error_test.go",
+	"short_test.go",
+}
+
+func TestParse(t *testing.T) {
+	for _, filename := range validFiles {
+		_, err := ParseFile(fset, filename, nil, DeclarationErrors)
+		if err != nil {
+			t.Fatalf("ParseFile(%s): %v", filename, err)
+		}
+	}
+}
+
+func nameFilter(filename string) bool {
+	switch filename {
+	case "parser.go", "interface.go", "parser_test.go":
+		return true
+	case "parser.go.orig":
+		return true // permit but should be ignored by ParseDir
+	}
+	return false
+}
+
+func dirFilter(f os.FileInfo) bool { return nameFilter(f.Name()) }
+
+func TestParseDir(t *testing.T) {
+	path := "."
+	pkgs, err := ParseDir(fset, path, dirFilter, 0)
+	if err != nil {
+		t.Fatalf("ParseDir(%s): %v", path, err)
+	}
+	if n := len(pkgs); n != 1 {
+		t.Errorf("got %d packages; want 1", n)
+	}
+	pkg := pkgs["parser"]
+	if pkg == nil {
+		t.Errorf(`package "parser" not found`)
+		return
+	}
+	if n := len(pkg.Files); n != 3 {
+		t.Errorf("got %d package files; want 3", n)
+	}
+	for filename := range pkg.Files {
+		if !nameFilter(filename) {
+			t.Errorf("unexpected package file: %s", filename)
+		}
+	}
+}
+
+func TestParseExpr(t *testing.T) {
+	// just kicking the tires:
+	// a valid arithmetic expression
+	src := "a + b"
+	x, err := ParseExpr(src)
+	if err != nil {
+		t.Errorf("ParseExpr(%q): %v", src, err)
+	}
+	// sanity check
+	if _, ok := x.(*ast.BinaryExpr); !ok {
+		t.Errorf("ParseExpr(%q): got %T, want *ast.BinaryExpr", src, x)
+	}
+
+	// a valid type expression
+	src = "struct{x *int}"
+	x, err = ParseExpr(src)
+	if err != nil {
+		t.Errorf("ParseExpr(%q): %v", src, err)
+	}
+	// sanity check
+	if _, ok := x.(*ast.StructType); !ok {
+		t.Errorf("ParseExpr(%q): got %T, want *ast.StructType", src, x)
+	}
+
+	// an invalid expression
+	src = "a + *"
+	if _, err := ParseExpr(src); err == nil {
+		t.Errorf("ParseExpr(%q): got no error", src)
+	}
+
+	// a valid expression followed by extra tokens is invalid
+	src = "a[i] := x"
+	if _, err := ParseExpr(src); err == nil {
+		t.Errorf("ParseExpr(%q): got no error", src)
+	}
+
+	// a semicolon is not permitted unless automatically inserted
+	src = "a + b\n"
+	if _, err := ParseExpr(src); err != nil {
+		t.Errorf("ParseExpr(%q): got error %s", src, err)
+	}
+	src = "a + b;"
+	if _, err := ParseExpr(src); err == nil {
+		t.Errorf("ParseExpr(%q): got no error", src)
+	}
+
+	// various other stuff following a valid expression
+	const validExpr = "a + b"
+	const anything = "dh3*#D)#_"
+	for _, c := range "!)]};," {
+		src := validExpr + string(c) + anything
+		if _, err := ParseExpr(src); err == nil {
+			t.Errorf("ParseExpr(%q): got no error", src)
+		}
+	}
+
+	// ParseExpr must not crash
+	for _, src := range valids {
+		ParseExpr(src)
+	}
+}
+
+func TestColonEqualsScope(t *testing.T) {
+	f, err := ParseFile(fset, "", `package p; func f() { x, y, z := x, y, z }`, 0)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	// RHS refers to undefined globals; LHS does not.
+	as := f.Decls[0].(*ast.FuncDecl).Body.List[0].(*ast.AssignStmt)
+	for _, v := range as.Rhs {
+		id := v.(*ast.Ident)
+		if id.Obj != nil {
+			t.Errorf("rhs %s has Obj, should not", id.Name)
+		}
+	}
+	for _, v := range as.Lhs {
+		id := v.(*ast.Ident)
+		if id.Obj == nil {
+			t.Errorf("lhs %s does not have Obj, should", id.Name)
+		}
+	}
+}
+
+func TestVarScope(t *testing.T) {
+	f, err := ParseFile(fset, "", `package p; func f() { var x, y, z = x, y, z }`, 0)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	// RHS refers to undefined globals; LHS does not.
+	as := f.Decls[0].(*ast.FuncDecl).Body.List[0].(*ast.DeclStmt).Decl.(*ast.GenDecl).Specs[0].(*ast.ValueSpec)
+	for _, v := range as.Values {
+		id := v.(*ast.Ident)
+		if id.Obj != nil {
+			t.Errorf("rhs %s has Obj, should not", id.Name)
+		}
+	}
+	for _, id := range as.Names {
+		if id.Obj == nil {
+			t.Errorf("lhs %s does not have Obj, should", id.Name)
+		}
+	}
+}
+
+func TestObjects(t *testing.T) {
+	const src = `
+package p
+import fmt "fmt"
+const pi = 3.14
+type T struct{}
+var x int
+func f() { L: }
+`
+
+	f, err := ParseFile(fset, "", src, 0)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	objects := map[string]ast.ObjKind{
+		"p":   ast.Bad, // not in a scope
+		"fmt": ast.Bad, // not resolved yet
+		"pi":  ast.Con,
+		"T":   ast.Typ,
+		"x":   ast.Var,
+		"int": ast.Bad, // not resolved yet
+		"f":   ast.Fun,
+		"L":   ast.Lbl,
+	}
+
+	ast.Inspect(f, func(n ast.Node) bool {
+		if ident, ok := n.(*ast.Ident); ok {
+			obj := ident.Obj
+			if obj == nil {
+				if objects[ident.Name] != ast.Bad {
+					t.Errorf("no object for %s", ident.Name)
+				}
+				return true
+			}
+			if obj.Name != ident.Name {
+				t.Errorf("names don't match: obj.Name = %s, ident.Name = %s", obj.Name, ident.Name)
+			}
+			kind := objects[ident.Name]
+			if obj.Kind != kind {
+				t.Errorf("%s: obj.Kind = %s; want %s", ident.Name, obj.Kind, kind)
+			}
+		}
+		return true
+	})
+}
+
+func TestUnresolved(t *testing.T) {
+	f, err := ParseFile(fset, "", `
+package p
+//
+func f1a(int)
+func f2a(byte, int, float)
+func f3a(a, b int, c float)
+func f4a(...complex)
+func f5a(a s1a, b ...complex)
+//
+func f1b(*int)
+func f2b([]byte, (int), *float)
+func f3b(a, b *int, c []float)
+func f4b(...*complex)
+func f5b(a s1a, b ...[]complex)
+//
+type s1a struct { int }
+type s2a struct { byte; int; s1a }
+type s3a struct { a, b int; c float }
+//
+type s1b struct { *int }
+type s2b struct { byte; int; *float }
+type s3b struct { a, b *s3b; c []float }
+`, 0)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	want := "int " + // f1a
+		"byte int float " + // f2a
+		"int float " + // f3a
+		"complex " + // f4a
+		"complex " + // f5a
+		//
+		"int " + // f1b
+		"byte int float " + // f2b
+		"int float " + // f3b
+		"complex " + // f4b
+		"complex " + // f5b
+		//
+		"int " + // s1a
+		"byte int " + // s2a
+		"int float " + // s3a
+		//
+		"int " + // s1a
+		"byte int float " + // s2a
+		"float " // s3a
+
+	// collect unresolved identifiers
+	var buf bytes.Buffer
+	for _, u := range f.Unresolved {
+		buf.WriteString(u.Name)
+		buf.WriteByte(' ')
+	}
+	got := buf.String()
+
+	if got != want {
+		t.Errorf("\ngot:  %s\nwant: %s", got, want)
+	}
+}
+
+var imports = map[string]bool{
+	`"a"`:        true,
+	"`a`":        true,
+	`"a/b"`:      true,
+	`"a.b"`:      true,
+	`"m\x61th"`:  true,
+	`"greek/αβ"`: true,
+	`""`:         false,
+
+	// Each of these pairs tests both `` vs "" strings
+	// and also use of invalid characters spelled out as
+	// escape sequences and written directly.
+	// For example `"\x00"` tests import "\x00"
+	// while "`\x00`" tests import `<actual-NUL-byte>`.
+	`"\x00"`:     false,
+	"`\x00`":     false,
+	`"\x7f"`:     false,
+	"`\x7f`":     false,
+	`"a!"`:       false,
+	"`a!`":       false,
+	`"a b"`:      false,
+	"`a b`":      false,
+	`"a\\b"`:     false,
+	"`a\\b`":     false,
+	"\"`a`\"":    false,
+	"`\"a\"`":    false,
+	`"\x80\x80"`: false,
+	"`\x80\x80`": false,
+	`"\xFFFD"`:   false,
+	"`\xFFFD`":   false,
+}
+
+func TestImports(t *testing.T) {
+	for path, isValid := range imports {
+		src := fmt.Sprintf("package p; import %s", path)
+		_, err := ParseFile(fset, "", src, 0)
+		switch {
+		case err != nil && isValid:
+			t.Errorf("ParseFile(%s): got %v; expected no error", src, err)
+		case err == nil && !isValid:
+			t.Errorf("ParseFile(%s): got no error; expected one", src)
+		}
+	}
+}
+
+func TestCommentGroups(t *testing.T) {
+	f, err := ParseFile(fset, "", `
+package p /* 1a */ /* 1b */      /* 1c */ // 1d
+/* 2a
+*/
+// 2b
+const pi = 3.1415
+/* 3a */ // 3b
+/* 3c */ const e = 2.7182
+
+// Example from issue 3139
+func ExampleCount() {
+	fmt.Println(strings.Count("cheese", "e"))
+	fmt.Println(strings.Count("five", "")) // before & after each rune
+	// Output:
+	// 3
+	// 5
+}
+`, ParseComments)
+	if err != nil {
+		t.Fatal(err)
+	}
+	expected := [][]string{
+		{"/* 1a */", "/* 1b */", "/* 1c */", "// 1d"},
+		{"/* 2a\n*/", "// 2b"},
+		{"/* 3a */", "// 3b", "/* 3c */"},
+		{"// Example from issue 3139"},
+		{"// before & after each rune"},
+		{"// Output:", "// 3", "// 5"},
+	}
+	if len(f.Comments) != len(expected) {
+		t.Fatalf("got %d comment groups; expected %d", len(f.Comments), len(expected))
+	}
+	for i, exp := range expected {
+		got := f.Comments[i].List
+		if len(got) != len(exp) {
+			t.Errorf("got %d comments in group %d; expected %d", len(got), i, len(exp))
+			continue
+		}
+		for j, exp := range exp {
+			got := got[j].Text
+			if got != exp {
+				t.Errorf("got %q in group %d; expected %q", got, i, exp)
+			}
+		}
+	}
+}
+
+func getField(file *ast.File, fieldname string) *ast.Field {
+	parts := strings.Split(fieldname, ".")
+	for _, d := range file.Decls {
+		if d, ok := d.(*ast.GenDecl); ok && d.Tok == token.TYPE {
+			for _, s := range d.Specs {
+				if s, ok := s.(*ast.TypeSpec); ok && s.Name.Name == parts[0] {
+					if s, ok := s.Type.(*ast.StructType); ok {
+						for _, f := range s.Fields.List {
+							for _, name := range f.Names {
+								if name.Name == parts[1] {
+									return f
+								}
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+	return nil
+}
+
+// Don't use ast.CommentGroup.Text() - we want to see exact comment text.
+func commentText(c *ast.CommentGroup) string {
+	var buf bytes.Buffer
+	if c != nil {
+		for _, c := range c.List {
+			buf.WriteString(c.Text)
+		}
+	}
+	return buf.String()
+}
+
+func checkFieldComments(t *testing.T, file *ast.File, fieldname, lead, line string) {
+	f := getField(file, fieldname)
+	if f == nil {
+		t.Fatalf("field not found: %s", fieldname)
+	}
+	if got := commentText(f.Doc); got != lead {
+		t.Errorf("got lead comment %q; expected %q", got, lead)
+	}
+	if got := commentText(f.Comment); got != line {
+		t.Errorf("got line comment %q; expected %q", got, line)
+	}
+}
+
+func TestLeadAndLineComments(t *testing.T) {
+	f, err := ParseFile(fset, "", `
+package p
+type T struct {
+	/* F1 lead comment */
+	//
+	F1 int  /* F1 */ // line comment
+	// F2 lead
+	// comment
+	F2 int  // F2 line comment
+	// f3 lead comment
+	f3 int  // f3 line comment
+}
+`, ParseComments)
+	if err != nil {
+		t.Fatal(err)
+	}
+	checkFieldComments(t, f, "T.F1", "/* F1 lead comment *///", "/* F1 */// line comment")
+	checkFieldComments(t, f, "T.F2", "// F2 lead// comment", "// F2 line comment")
+	checkFieldComments(t, f, "T.f3", "// f3 lead comment", "// f3 line comment")
+	ast.FileExports(f)
+	checkFieldComments(t, f, "T.F1", "/* F1 lead comment *///", "/* F1 */// line comment")
+	checkFieldComments(t, f, "T.F2", "// F2 lead// comment", "// F2 line comment")
+	if getField(f, "T.f3") != nil {
+		t.Error("not expected to find T.f3")
+	}
+}
diff --git a/src/pkg/go/parser/performance_test.go b/src/go/parser/performance_test.go
similarity index 100%
rename from src/pkg/go/parser/performance_test.go
rename to src/go/parser/performance_test.go
diff --git a/src/go/parser/short_test.go b/src/go/parser/short_test.go
new file mode 100644
index 0000000..05e44de
--- /dev/null
+++ b/src/go/parser/short_test.go
@@ -0,0 +1,104 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file contains test cases for short valid and invalid programs.
+
+package parser
+
+import "testing"
+
+var valids = []string{
+	"package p\n",
+	`package p;`,
+	`package p; import "fmt"; func f() { fmt.Println("Hello, World!") };`,
+	`package p; func f() { if f(T{}) {} };`,
+	`package p; func f() { _ = <-chan int(nil) };`,
+	`package p; func f() { _ = (<-chan int)(nil) };`,
+	`package p; func f() { _ = (<-chan <-chan int)(nil) };`,
+	`package p; func f() { _ = <-chan <-chan <-chan <-chan <-int(nil) };`,
+	`package p; func f(func() func() func());`,
+	`package p; func f(...T);`,
+	`package p; func f(float, ...int);`,
+	`package p; func f(x int, a ...int) { f(0, a...); f(1, a...,) };`,
+	`package p; func f(int,) {};`,
+	`package p; func f(...int,) {};`,
+	`package p; func f(x ...int,) {};`,
+	`package p; type T []int; var a []bool; func f() { if a[T{42}[0]] {} };`,
+	`package p; type T []int; func g(int) bool { return true }; func f() { if g(T{42}[0]) {} };`,
+	`package p; type T []int; func f() { for _ = range []int{T{42}[0]} {} };`,
+	`package p; var a = T{{1, 2}, {3, 4}}`,
+	`package p; func f() { select { case <- c: case c <- d: case c <- <- d: case <-c <- d: } };`,
+	`package p; func f() { select { case x := (<-c): } };`,
+	`package p; func f() { if ; true {} };`,
+	`package p; func f() { switch ; {} };`,
+	`package p; func f() { for _ = range "foo" + "bar" {} };`,
+	`package p; func f() { var s []int; g(s[:], s[i:], s[:j], s[i:j], s[i:j:k], s[:j:k]) };`,
+	`package p; var ( _ = (struct {*T}).m; _ = (interface {T}).m )`,
+	`package p; func ((T),) m() {}`,
+	`package p; func ((*T),) m() {}`,
+	`package p; func (*(T),) m() {}`,
+	`package p; func _(x []int) { for range x {} }`,
+	`package p; func _() { if [T{}.n]int{} {} }`,
+}
+
+func TestValid(t *testing.T) {
+	for _, src := range valids {
+		checkErrors(t, src, src)
+	}
+}
+
+var invalids = []string{
+	`foo /* ERROR "expected 'package'" */ !`,
+	`package p; func f() { if { /* ERROR "expected operand" */ } };`,
+	`package p; func f() { if ; { /* ERROR "expected operand" */ } };`,
+	`package p; func f() { if f(); { /* ERROR "expected operand" */ } };`,
+	`package p; func f() { if _ /* ERROR "expected boolean expression" */ = range x; true {} };`,
+	`package p; func f() { switch _ /* ERROR "expected switch expression" */ = range x; true {} };`,
+	`package p; func f() { for _ = range x ; /* ERROR "expected '{'" */ ; {} };`,
+	`package p; func f() { for ; ; _ = range /* ERROR "expected operand" */ x {} };`,
+	`package p; func f() { for ; _ /* ERROR "expected boolean or range expression" */ = range x ; {} };`,
+	`package p; func f() { switch t /* ERROR "expected switch expression" */ = t.(type) {} };`,
+	`package p; func f() { switch t /* ERROR "expected switch expression" */ , t = t.(type) {} };`,
+	`package p; func f() { switch t /* ERROR "expected switch expression" */ = t.(type), t {} };`,
+	`package p; var a = [ /* ERROR "expected expression" */ 1]int;`,
+	`package p; var a = [ /* ERROR "expected expression" */ ...]int;`,
+	`package p; var a = struct /* ERROR "expected expression" */ {}`,
+	`package p; var a = func /* ERROR "expected expression" */ ();`,
+	`package p; var a = interface /* ERROR "expected expression" */ {}`,
+	`package p; var a = [ /* ERROR "expected expression" */ ]int`,
+	`package p; var a = map /* ERROR "expected expression" */ [int]int`,
+	`package p; var a = chan /* ERROR "expected expression" */ int;`,
+	`package p; var a = []int{[ /* ERROR "expected expression" */ ]int};`,
+	`package p; var a = ( /* ERROR "expected expression" */ []int);`,
+	`package p; var a = a[[ /* ERROR "expected expression" */ ]int:[]int];`,
+	`package p; var a = <- /* ERROR "expected expression" */ chan int;`,
+	`package p; func f() { select { case _ <- chan /* ERROR "expected expression" */ int: } };`,
+	`package p; func f() { _ = (<-<- /* ERROR "expected 'chan'" */ chan int)(nil) };`,
+	`package p; func f() { _ = (<-chan<-chan<-chan<-chan<-chan<- /* ERROR "expected channel type" */ int)(nil) };`,
+	`package p; func f() { var t []int; t /* ERROR "expected identifier on left side of :=" */ [0] := 0 };`,
+	`package p; func f() { if x := g(); x = /* ERROR "expected '=='" */ 0 {}};`,
+	`package p; func f() { _ = x = /* ERROR "expected '=='" */ 0 {}};`,
+	`package p; func f() { _ = 1 == func()int { var x bool; x = x = /* ERROR "expected '=='" */ true; return x }() };`,
+	`package p; func f() { var s []int; _ = s[] /* ERROR "expected operand" */ };`,
+	`package p; func f() { var s []int; _ = s[i:j: /* ERROR "3rd index required" */ ] };`,
+	`package p; func f() { var s []int; _ = s[i: /* ERROR "2nd index required" */ :k] };`,
+	`package p; func f() { var s []int; _ = s[i: /* ERROR "2nd index required" */ :] };`,
+	`package p; func f() { var s []int; _ = s[: /* ERROR "2nd index required" */ :] };`,
+	`package p; func f() { var s []int; _ = s[: /* ERROR "2nd index required" */ ::] };`,
+	`package p; func f() { var s []int; _ = s[i:j:k: /* ERROR "expected ']'" */ l] };`,
+	`package p; func f() { for x /* ERROR "boolean or range expression" */ = []string {} }`,
+	`package p; func f() { for x /* ERROR "boolean or range expression" */ := []string {} }`,
+	`package p; func f() { for i /* ERROR "boolean or range expression" */ , x = []string {} }`,
+	`package p; func f() { for i /* ERROR "boolean or range expression" */ , x := []string {} }`,
+	`package p; func f() { go f /* ERROR HERE "function must be invoked" */ }`,
+	`package p; func f() { defer func() {} /* ERROR HERE "function must be invoked" */ }`,
+	`package p; func f() { go func() { func() { f(x func /* ERROR "expected '\)'" */ (){}) } } }`,
+	`package p; func f() (a b string /* ERROR "expected '\)'" */ , ok bool) // issue 8656`,
+}
+
+func TestInvalid(t *testing.T) {
+	for _, src := range invalids {
+		checkErrors(t, src, src)
+	}
+}
diff --git a/src/pkg/go/parser/testdata/commas.src b/src/go/parser/testdata/commas.src
similarity index 100%
rename from src/pkg/go/parser/testdata/commas.src
rename to src/go/parser/testdata/commas.src
diff --git a/src/pkg/go/parser/testdata/issue3106.src b/src/go/parser/testdata/issue3106.src
similarity index 100%
rename from src/pkg/go/parser/testdata/issue3106.src
rename to src/go/parser/testdata/issue3106.src
diff --git a/src/pkg/go/printer/example_test.go b/src/go/printer/example_test.go
similarity index 100%
rename from src/pkg/go/printer/example_test.go
rename to src/go/printer/example_test.go
diff --git a/src/go/printer/nodes.go b/src/go/printer/nodes.go
new file mode 100644
index 0000000..d5a6934
--- /dev/null
+++ b/src/go/printer/nodes.go
@@ -0,0 +1,1606 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file implements printing of AST nodes; specifically
+// expressions, statements, declarations, and files. It uses
+// the print functionality implemented in printer.go.
+
+package printer
+
+import (
+	"bytes"
+	"go/ast"
+	"go/token"
+	"unicode/utf8"
+)
+
+// Formatting issues:
+// - better comment formatting for /*-style comments at the end of a line (e.g. a declaration)
+//   when the comment spans multiple lines; if such a comment is just two lines, formatting is
+//   not idempotent
+// - formatting of expression lists
+// - should use blank instead of tab to separate one-line function bodies from
+//   the function header unless there is a group of consecutive one-liners
+
+// ----------------------------------------------------------------------------
+// Common AST nodes.
+
+// Print as many newlines as necessary (but at least min newlines) to get to
+// the current line. ws is printed before the first line break. If newSection
+// is set, the first line break is printed as formfeed. Returns true if any
+// line break was printed; returns false otherwise.
+//
+// TODO(gri): linebreak may add too many lines if the next statement at "line"
+//            is preceded by comments because the computation of n assumes
+//            the current position before the comment and the target position
+//            after the comment. Thus, after interspersing such comments, the
+//            space taken up by them is not considered to reduce the number of
+//            linebreaks. At the moment there is no easy way to know about
+//            future (not yet interspersed) comments in this function.
+//
+func (p *printer) linebreak(line, min int, ws whiteSpace, newSection bool) (printedBreak bool) {
+	n := nlimit(line - p.pos.Line)
+	if n < min {
+		n = min
+	}
+	if n > 0 {
+		p.print(ws)
+		if newSection {
+			p.print(formfeed)
+			n--
+		}
+		for ; n > 0; n-- {
+			p.print(newline)
+		}
+		printedBreak = true
+	}
+	return
+}
+
+// setComment sets g as the next comment if g != nil and if node comments
+// are enabled - this mode is used when printing source code fragments such
+// as exports only. It assumes that there is no pending comment in p.comments
+// and at most one pending comment in the p.comment cache.
+func (p *printer) setComment(g *ast.CommentGroup) {
+	if g == nil || !p.useNodeComments {
+		return
+	}
+	if p.comments == nil {
+		// initialize p.comments lazily
+		p.comments = make([]*ast.CommentGroup, 1)
+	} else if p.cindex < len(p.comments) {
+		// for some reason there are pending comments; this
+		// should never happen - handle gracefully and flush
+		// all comments up to g, ignore anything after that
+		p.flush(p.posFor(g.List[0].Pos()), token.ILLEGAL)
+		p.comments = p.comments[0:1]
+		// in debug mode, report error
+		p.internalError("setComment found pending comments")
+	}
+	p.comments[0] = g
+	p.cindex = 0
+	// don't overwrite any pending comment in the p.comment cache
+	// (there may be a pending comment when a line comment is
+	// immediately followed by a lead comment with no other
+	// tokens between)
+	if p.commentOffset == infinity {
+		p.nextComment() // get comment ready for use
+	}
+}
+
+type exprListMode uint
+
+const (
+	commaTerm exprListMode = 1 << iota // list is optionally terminated by a comma
+	noIndent                           // no extra indentation in multi-line lists
+)
+
+// If indent is set, a multi-line identifier list is indented after the
+// first linebreak encountered.
+func (p *printer) identList(list []*ast.Ident, indent bool) {
+	// convert into an expression list so we can re-use exprList formatting
+	xlist := make([]ast.Expr, len(list))
+	for i, x := range list {
+		xlist[i] = x
+	}
+	var mode exprListMode
+	if !indent {
+		mode = noIndent
+	}
+	p.exprList(token.NoPos, xlist, 1, mode, token.NoPos)
+}
+
+// Print a list of expressions. If the list spans multiple
+// source lines, the original line breaks are respected between
+// expressions.
+//
+// TODO(gri) Consider rewriting this to be independent of []ast.Expr
+//           so that we can use the algorithm for any kind of list
+//           (e.g., pass list via a channel over which to range).
+func (p *printer) exprList(prev0 token.Pos, list []ast.Expr, depth int, mode exprListMode, next0 token.Pos) {
+	if len(list) == 0 {
+		return
+	}
+
+	prev := p.posFor(prev0)
+	next := p.posFor(next0)
+	line := p.lineFor(list[0].Pos())
+	endLine := p.lineFor(list[len(list)-1].End())
+
+	if prev.IsValid() && prev.Line == line && line == endLine {
+		// all list entries on a single line
+		for i, x := range list {
+			if i > 0 {
+				// use position of expression following the comma as
+				// comma position for correct comment placement
+				p.print(x.Pos(), token.COMMA, blank)
+			}
+			p.expr0(x, depth)
+		}
+		return
+	}
+
+	// list entries span multiple lines;
+	// use source code positions to guide line breaks
+
+	// don't add extra indentation if noIndent is set;
+	// i.e., pretend that the first line is already indented
+	ws := ignore
+	if mode&noIndent == 0 {
+		ws = indent
+	}
+
+	// the first linebreak is always a formfeed since this section must not
+	// depend on any previous formatting
+	prevBreak := -1 // index of last expression that was followed by a linebreak
+	if prev.IsValid() && prev.Line < line && p.linebreak(line, 0, ws, true) {
+		ws = ignore
+		prevBreak = 0
+	}
+
+	// initialize expression/key size: a zero value indicates expr/key doesn't fit on a single line
+	size := 0
+
+	// print all list elements
+	prevLine := prev.Line
+	for i, x := range list {
+		line = p.lineFor(x.Pos())
+
+		// determine if the next linebreak, if any, needs to use formfeed:
+		// in general, use the entire node size to make the decision; for
+		// key:value expressions, use the key size
+		// TODO(gri) for a better result, should probably incorporate both
+		//           the key and the node size into the decision process
+		useFF := true
+
+		// determine element size: all bets are off if we don't have
+		// position information for the previous and next token (likely
+		// generated code - simply ignore the size in this case by setting
+		// it to 0)
+		prevSize := size
+		const infinity = 1e6 // larger than any source line
+		size = p.nodeSize(x, infinity)
+		pair, isPair := x.(*ast.KeyValueExpr)
+		if size <= infinity && prev.IsValid() && next.IsValid() {
+			// x fits on a single line
+			if isPair {
+				size = p.nodeSize(pair.Key, infinity) // size <= infinity
+			}
+		} else {
+			// size too large or we don't have good layout information
+			size = 0
+		}
+
+		// if the previous line and the current line had single-
+		// line-expressions and the key sizes are small or the
+		// the ratio between the key sizes does not exceed a
+		// threshold, align columns and do not use formfeed
+		if prevSize > 0 && size > 0 {
+			const smallSize = 20
+			if prevSize <= smallSize && size <= smallSize {
+				useFF = false
+			} else {
+				const r = 4 // threshold
+				ratio := float64(size) / float64(prevSize)
+				useFF = ratio <= 1.0/r || r <= ratio
+			}
+		}
+
+		needsLinebreak := 0 < prevLine && prevLine < line
+		if i > 0 {
+			// use position of expression following the comma as
+			// comma position for correct comment placement, but
+			// only if the expression is on the same line
+			if !needsLinebreak {
+				p.print(x.Pos())
+			}
+			p.print(token.COMMA)
+			needsBlank := true
+			if needsLinebreak {
+				// lines are broken using newlines so comments remain aligned
+				// unless forceFF is set or there are multiple expressions on
+				// the same line in which case formfeed is used
+				if p.linebreak(line, 0, ws, useFF || prevBreak+1 < i) {
+					ws = ignore
+					prevBreak = i
+					needsBlank = false // we got a line break instead
+				}
+			}
+			if needsBlank {
+				p.print(blank)
+			}
+		}
+
+		if len(list) > 1 && isPair && size > 0 && needsLinebreak {
+			// we have a key:value expression that fits onto one line
+			// and it's not on the same line as the prior expression:
+			// use a column for the key such that consecutive entries
+			// can align if possible
+			// (needsLinebreak is set if we started a new line before)
+			p.expr(pair.Key)
+			p.print(pair.Colon, token.COLON, vtab)
+			p.expr(pair.Value)
+		} else {
+			p.expr0(x, depth)
+		}
+
+		prevLine = line
+	}
+
+	if mode&commaTerm != 0 && next.IsValid() && p.pos.Line < next.Line {
+		// print a terminating comma if the next token is on a new line
+		p.print(token.COMMA)
+		if ws == ignore && mode&noIndent == 0 {
+			// unindent if we indented
+			p.print(unindent)
+		}
+		p.print(formfeed) // terminating comma needs a line break to look good
+		return
+	}
+
+	if ws == ignore && mode&noIndent == 0 {
+		// unindent if we indented
+		p.print(unindent)
+	}
+}
+
+func (p *printer) parameters(fields *ast.FieldList) {
+	p.print(fields.Opening, token.LPAREN)
+	if len(fields.List) > 0 {
+		prevLine := p.lineFor(fields.Opening)
+		ws := indent
+		for i, par := range fields.List {
+			// determine par begin and end line (may be different
+			// if there are multiple parameter names for this par
+			// or the type is on a separate line)
+			var parLineBeg int
+			if len(par.Names) > 0 {
+				parLineBeg = p.lineFor(par.Names[0].Pos())
+			} else {
+				parLineBeg = p.lineFor(par.Type.Pos())
+			}
+			var parLineEnd = p.lineFor(par.Type.End())
+			// separating "," if needed
+			needsLinebreak := 0 < prevLine && prevLine < parLineBeg
+			if i > 0 {
+				// use position of parameter following the comma as
+				// comma position for correct comma placement, but
+				// only if the next parameter is on the same line
+				if !needsLinebreak {
+					p.print(par.Pos())
+				}
+				p.print(token.COMMA)
+			}
+			// separator if needed (linebreak or blank)
+			if needsLinebreak && p.linebreak(parLineBeg, 0, ws, true) {
+				// break line if the opening "(" or previous parameter ended on a different line
+				ws = ignore
+			} else if i > 0 {
+				p.print(blank)
+			}
+			// parameter names
+			if len(par.Names) > 0 {
+				// Very subtle: If we indented before (ws == ignore), identList
+				// won't indent again. If we didn't (ws == indent), identList will
+				// indent if the identList spans multiple lines, and it will outdent
+				// again at the end (and still ws == indent). Thus, a subsequent indent
+				// by a linebreak call after a type, or in the next multi-line identList
+				// will do the right thing.
+				p.identList(par.Names, ws == indent)
+				p.print(blank)
+			}
+			// parameter type
+			p.expr(stripParensAlways(par.Type))
+			prevLine = parLineEnd
+		}
+		// if the closing ")" is on a separate line from the last parameter,
+		// print an additional "," and line break
+		if closing := p.lineFor(fields.Closing); 0 < prevLine && prevLine < closing {
+			p.print(token.COMMA)
+			p.linebreak(closing, 0, ignore, true)
+		}
+		// unindent if we indented
+		if ws == ignore {
+			p.print(unindent)
+		}
+	}
+	p.print(fields.Closing, token.RPAREN)
+}
+
+func (p *printer) signature(params, result *ast.FieldList) {
+	if params != nil {
+		p.parameters(params)
+	} else {
+		p.print(token.LPAREN, token.RPAREN)
+	}
+	n := result.NumFields()
+	if n > 0 {
+		// result != nil
+		p.print(blank)
+		if n == 1 && result.List[0].Names == nil {
+			// single anonymous result; no ()'s
+			p.expr(stripParensAlways(result.List[0].Type))
+			return
+		}
+		p.parameters(result)
+	}
+}
+
+func identListSize(list []*ast.Ident, maxSize int) (size int) {
+	for i, x := range list {
+		if i > 0 {
+			size += len(", ")
+		}
+		size += utf8.RuneCountInString(x.Name)
+		if size >= maxSize {
+			break
+		}
+	}
+	return
+}
+
+func (p *printer) isOneLineFieldList(list []*ast.Field) bool {
+	if len(list) != 1 {
+		return false // allow only one field
+	}
+	f := list[0]
+	if f.Tag != nil || f.Comment != nil {
+		return false // don't allow tags or comments
+	}
+	// only name(s) and type
+	const maxSize = 30 // adjust as appropriate, this is an approximate value
+	namesSize := identListSize(f.Names, maxSize)
+	if namesSize > 0 {
+		namesSize = 1 // blank between names and types
+	}
+	typeSize := p.nodeSize(f.Type, maxSize)
+	return namesSize+typeSize <= maxSize
+}
+
+func (p *printer) setLineComment(text string) {
+	p.setComment(&ast.CommentGroup{List: []*ast.Comment{{Slash: token.NoPos, Text: text}}})
+}
+
+func (p *printer) fieldList(fields *ast.FieldList, isStruct, isIncomplete bool) {
+	lbrace := fields.Opening
+	list := fields.List
+	rbrace := fields.Closing
+	hasComments := isIncomplete || p.commentBefore(p.posFor(rbrace))
+	srcIsOneLine := lbrace.IsValid() && rbrace.IsValid() && p.lineFor(lbrace) == p.lineFor(rbrace)
+
+	if !hasComments && srcIsOneLine {
+		// possibly a one-line struct/interface
+		if len(list) == 0 {
+			// no blank between keyword and {} in this case
+			p.print(lbrace, token.LBRACE, rbrace, token.RBRACE)
+			return
+		} else if isStruct && p.isOneLineFieldList(list) { // for now ignore interfaces
+			// small enough - print on one line
+			// (don't use identList and ignore source line breaks)
+			p.print(lbrace, token.LBRACE, blank)
+			f := list[0]
+			for i, x := range f.Names {
+				if i > 0 {
+					// no comments so no need for comma position
+					p.print(token.COMMA, blank)
+				}
+				p.expr(x)
+			}
+			if len(f.Names) > 0 {
+				p.print(blank)
+			}
+			p.expr(f.Type)
+			p.print(blank, rbrace, token.RBRACE)
+			return
+		}
+	}
+	// hasComments || !srcIsOneLine
+
+	p.print(blank, lbrace, token.LBRACE, indent)
+	if hasComments || len(list) > 0 {
+		p.print(formfeed)
+	}
+
+	if isStruct {
+
+		sep := vtab
+		if len(list) == 1 {
+			sep = blank
+		}
+		var line int
+		for i, f := range list {
+			if i > 0 {
+				p.linebreak(p.lineFor(f.Pos()), 1, ignore, p.linesFrom(line) > 0)
+			}
+			extraTabs := 0
+			p.setComment(f.Doc)
+			p.recordLine(&line)
+			if len(f.Names) > 0 {
+				// named fields
+				p.identList(f.Names, false)
+				p.print(sep)
+				p.expr(f.Type)
+				extraTabs = 1
+			} else {
+				// anonymous field
+				p.expr(f.Type)
+				extraTabs = 2
+			}
+			if f.Tag != nil {
+				if len(f.Names) > 0 && sep == vtab {
+					p.print(sep)
+				}
+				p.print(sep)
+				p.expr(f.Tag)
+				extraTabs = 0
+			}
+			if f.Comment != nil {
+				for ; extraTabs > 0; extraTabs-- {
+					p.print(sep)
+				}
+				p.setComment(f.Comment)
+			}
+		}
+		if isIncomplete {
+			if len(list) > 0 {
+				p.print(formfeed)
+			}
+			p.flush(p.posFor(rbrace), token.RBRACE) // make sure we don't lose the last line comment
+			p.setLineComment("// contains filtered or unexported fields")
+		}
+
+	} else { // interface
+
+		var line int
+		for i, f := range list {
+			if i > 0 {
+				p.linebreak(p.lineFor(f.Pos()), 1, ignore, p.linesFrom(line) > 0)
+			}
+			p.setComment(f.Doc)
+			p.recordLine(&line)
+			if ftyp, isFtyp := f.Type.(*ast.FuncType); isFtyp {
+				// method
+				p.expr(f.Names[0])
+				p.signature(ftyp.Params, ftyp.Results)
+			} else {
+				// embedded interface
+				p.expr(f.Type)
+			}
+			p.setComment(f.Comment)
+		}
+		if isIncomplete {
+			if len(list) > 0 {
+				p.print(formfeed)
+			}
+			p.flush(p.posFor(rbrace), token.RBRACE) // make sure we don't lose the last line comment
+			p.setLineComment("// contains filtered or unexported methods")
+		}
+
+	}
+	p.print(unindent, formfeed, rbrace, token.RBRACE)
+}
+
+// ----------------------------------------------------------------------------
+// Expressions
+
+func walkBinary(e *ast.BinaryExpr) (has4, has5 bool, maxProblem int) {
+	switch e.Op.Precedence() {
+	case 4:
+		has4 = true
+	case 5:
+		has5 = true
+	}
+
+	switch l := e.X.(type) {
+	case *ast.BinaryExpr:
+		if l.Op.Precedence() < e.Op.Precedence() {
+			// parens will be inserted.
+			// pretend this is an *ast.ParenExpr and do nothing.
+			break
+		}
+		h4, h5, mp := walkBinary(l)
+		has4 = has4 || h4
+		has5 = has5 || h5
+		if maxProblem < mp {
+			maxProblem = mp
+		}
+	}
+
+	switch r := e.Y.(type) {
+	case *ast.BinaryExpr:
+		if r.Op.Precedence() <= e.Op.Precedence() {
+			// parens will be inserted.
+			// pretend this is an *ast.ParenExpr and do nothing.
+			break
+		}
+		h4, h5, mp := walkBinary(r)
+		has4 = has4 || h4
+		has5 = has5 || h5
+		if maxProblem < mp {
+			maxProblem = mp
+		}
+
+	case *ast.StarExpr:
+		if e.Op == token.QUO { // `*/`
+			maxProblem = 5
+		}
+
+	case *ast.UnaryExpr:
+		switch e.Op.String() + r.Op.String() {
+		case "/*", "&&", "&^":
+			maxProblem = 5
+		case "++", "--":
+			if maxProblem < 4 {
+				maxProblem = 4
+			}
+		}
+	}
+	return
+}
+
+func cutoff(e *ast.BinaryExpr, depth int) int {
+	has4, has5, maxProblem := walkBinary(e)
+	if maxProblem > 0 {
+		return maxProblem + 1
+	}
+	if has4 && has5 {
+		if depth == 1 {
+			return 5
+		}
+		return 4
+	}
+	if depth == 1 {
+		return 6
+	}
+	return 4
+}
+
+func diffPrec(expr ast.Expr, prec int) int {
+	x, ok := expr.(*ast.BinaryExpr)
+	if !ok || prec != x.Op.Precedence() {
+		return 1
+	}
+	return 0
+}
+
+func reduceDepth(depth int) int {
+	depth--
+	if depth < 1 {
+		depth = 1
+	}
+	return depth
+}
+
+// Format the binary expression: decide the cutoff and then format.
+// Let's call depth == 1 Normal mode, and depth > 1 Compact mode.
+// (Algorithm suggestion by Russ Cox.)
+//
+// The precedences are:
+//	5             *  /  %  <<  >>  &  &^
+//	4             +  -  |  ^
+//	3             ==  !=  <  <=  >  >=
+//	2             &&
+//	1             ||
+//
+// The only decision is whether there will be spaces around levels 4 and 5.
+// There are never spaces at level 6 (unary), and always spaces at levels 3 and below.
+//
+// To choose the cutoff, look at the whole expression but excluding primary
+// expressions (function calls, parenthesized exprs), and apply these rules:
+//
+//	1) If there is a binary operator with a right side unary operand
+//	   that would clash without a space, the cutoff must be (in order):
+//
+//		/*	6
+//		&&	6
+//		&^	6
+//		++	5
+//		--	5
+//
+//         (Comparison operators always have spaces around them.)
+//
+//	2) If there is a mix of level 5 and level 4 operators, then the cutoff
+//	   is 5 (use spaces to distinguish precedence) in Normal mode
+//	   and 4 (never use spaces) in Compact mode.
+//
+//	3) If there are no level 4 operators or no level 5 operators, then the
+//	   cutoff is 6 (always use spaces) in Normal mode
+//	   and 4 (never use spaces) in Compact mode.
+//
+func (p *printer) binaryExpr(x *ast.BinaryExpr, prec1, cutoff, depth int) {
+	prec := x.Op.Precedence()
+	if prec < prec1 {
+		// parenthesis needed
+		// Note: The parser inserts an ast.ParenExpr node; thus this case
+		//       can only occur if the AST is created in a different way.
+		p.print(token.LPAREN)
+		p.expr0(x, reduceDepth(depth)) // parentheses undo one level of depth
+		p.print(token.RPAREN)
+		return
+	}
+
+	printBlank := prec < cutoff
+
+	ws := indent
+	p.expr1(x.X, prec, depth+diffPrec(x.X, prec))
+	if printBlank {
+		p.print(blank)
+	}
+	xline := p.pos.Line // before the operator (it may be on the next line!)
+	yline := p.lineFor(x.Y.Pos())
+	p.print(x.OpPos, x.Op)
+	if xline != yline && xline > 0 && yline > 0 {
+		// at least one line break, but respect an extra empty line
+		// in the source
+		if p.linebreak(yline, 1, ws, true) {
+			ws = ignore
+			printBlank = false // no blank after line break
+		}
+	}
+	if printBlank {
+		p.print(blank)
+	}
+	p.expr1(x.Y, prec+1, depth+1)
+	if ws == ignore {
+		p.print(unindent)
+	}
+}
+
+func isBinary(expr ast.Expr) bool {
+	_, ok := expr.(*ast.BinaryExpr)
+	return ok
+}
+
+func (p *printer) expr1(expr ast.Expr, prec1, depth int) {
+	p.print(expr.Pos())
+
+	switch x := expr.(type) {
+	case *ast.BadExpr:
+		p.print("BadExpr")
+
+	case *ast.Ident:
+		p.print(x)
+
+	case *ast.BinaryExpr:
+		if depth < 1 {
+			p.internalError("depth < 1:", depth)
+			depth = 1
+		}
+		p.binaryExpr(x, prec1, cutoff(x, depth), depth)
+
+	case *ast.KeyValueExpr:
+		p.expr(x.Key)
+		p.print(x.Colon, token.COLON, blank)
+		p.expr(x.Value)
+
+	case *ast.StarExpr:
+		const prec = token.UnaryPrec
+		if prec < prec1 {
+			// parenthesis needed
+			p.print(token.LPAREN)
+			p.print(token.MUL)
+			p.expr(x.X)
+			p.print(token.RPAREN)
+		} else {
+			// no parenthesis needed
+			p.print(token.MUL)
+			p.expr(x.X)
+		}
+
+	case *ast.UnaryExpr:
+		const prec = token.UnaryPrec
+		if prec < prec1 {
+			// parenthesis needed
+			p.print(token.LPAREN)
+			p.expr(x)
+			p.print(token.RPAREN)
+		} else {
+			// no parenthesis needed
+			p.print(x.Op)
+			if x.Op == token.RANGE {
+				// TODO(gri) Remove this code if it cannot be reached.
+				p.print(blank)
+			}
+			p.expr1(x.X, prec, depth)
+		}
+
+	case *ast.BasicLit:
+		p.print(x)
+
+	case *ast.FuncLit:
+		p.expr(x.Type)
+		p.adjBlock(p.distanceFrom(x.Type.Pos()), blank, x.Body)
+
+	case *ast.ParenExpr:
+		if _, hasParens := x.X.(*ast.ParenExpr); hasParens {
+			// don't print parentheses around an already parenthesized expression
+			// TODO(gri) consider making this more general and incorporate precedence levels
+			p.expr0(x.X, depth)
+		} else {
+			p.print(token.LPAREN)
+			p.expr0(x.X, reduceDepth(depth)) // parentheses undo one level of depth
+			p.print(x.Rparen, token.RPAREN)
+		}
+
+	case *ast.SelectorExpr:
+		p.expr1(x.X, token.HighestPrec, depth)
+		p.print(token.PERIOD)
+		if line := p.lineFor(x.Sel.Pos()); p.pos.IsValid() && p.pos.Line < line {
+			p.print(indent, newline, x.Sel.Pos(), x.Sel, unindent)
+		} else {
+			p.print(x.Sel.Pos(), x.Sel)
+		}
+
+	case *ast.TypeAssertExpr:
+		p.expr1(x.X, token.HighestPrec, depth)
+		p.print(token.PERIOD, x.Lparen, token.LPAREN)
+		if x.Type != nil {
+			p.expr(x.Type)
+		} else {
+			p.print(token.TYPE)
+		}
+		p.print(x.Rparen, token.RPAREN)
+
+	case *ast.IndexExpr:
+		// TODO(gri): should treat[] like parentheses and undo one level of depth
+		p.expr1(x.X, token.HighestPrec, 1)
+		p.print(x.Lbrack, token.LBRACK)
+		p.expr0(x.Index, depth+1)
+		p.print(x.Rbrack, token.RBRACK)
+
+	case *ast.SliceExpr:
+		// TODO(gri): should treat[] like parentheses and undo one level of depth
+		p.expr1(x.X, token.HighestPrec, 1)
+		p.print(x.Lbrack, token.LBRACK)
+		indices := []ast.Expr{x.Low, x.High}
+		if x.Max != nil {
+			indices = append(indices, x.Max)
+		}
+		for i, y := range indices {
+			if i > 0 {
+				// blanks around ":" if both sides exist and either side is a binary expression
+				// TODO(gri) once we have committed a variant of a[i:j:k] we may want to fine-
+				//           tune the formatting here
+				x := indices[i-1]
+				if depth <= 1 && x != nil && y != nil && (isBinary(x) || isBinary(y)) {
+					p.print(blank, token.COLON, blank)
+				} else {
+					p.print(token.COLON)
+				}
+			}
+			if y != nil {
+				p.expr0(y, depth+1)
+			}
+		}
+		p.print(x.Rbrack, token.RBRACK)
+
+	case *ast.CallExpr:
+		if len(x.Args) > 1 {
+			depth++
+		}
+		if _, ok := x.Fun.(*ast.FuncType); ok {
+			// conversions to literal function types require parentheses around the type
+			p.print(token.LPAREN)
+			p.expr1(x.Fun, token.HighestPrec, depth)
+			p.print(token.RPAREN)
+		} else {
+			p.expr1(x.Fun, token.HighestPrec, depth)
+		}
+		p.print(x.Lparen, token.LPAREN)
+		if x.Ellipsis.IsValid() {
+			p.exprList(x.Lparen, x.Args, depth, 0, x.Ellipsis)
+			p.print(x.Ellipsis, token.ELLIPSIS)
+			if x.Rparen.IsValid() && p.lineFor(x.Ellipsis) < p.lineFor(x.Rparen) {
+				p.print(token.COMMA, formfeed)
+			}
+		} else {
+			p.exprList(x.Lparen, x.Args, depth, commaTerm, x.Rparen)
+		}
+		p.print(x.Rparen, token.RPAREN)
+
+	case *ast.CompositeLit:
+		// composite literal elements that are composite literals themselves may have the type omitted
+		if x.Type != nil {
+			p.expr1(x.Type, token.HighestPrec, depth)
+		}
+		p.print(x.Lbrace, token.LBRACE)
+		p.exprList(x.Lbrace, x.Elts, 1, commaTerm, x.Rbrace)
+		// do not insert extra line break following a /*-style comment
+		// before the closing '}' as it might break the code if there
+		// is no trailing ','
+		mode := noExtraLinebreak
+		// do not insert extra blank following a /*-style comment
+		// before the closing '}' unless the literal is empty
+		if len(x.Elts) > 0 {
+			mode |= noExtraBlank
+		}
+		p.print(mode, x.Rbrace, token.RBRACE, mode)
+
+	case *ast.Ellipsis:
+		p.print(token.ELLIPSIS)
+		if x.Elt != nil {
+			p.expr(x.Elt)
+		}
+
+	case *ast.ArrayType:
+		p.print(token.LBRACK)
+		if x.Len != nil {
+			p.expr(x.Len)
+		}
+		p.print(token.RBRACK)
+		p.expr(x.Elt)
+
+	case *ast.StructType:
+		p.print(token.STRUCT)
+		p.fieldList(x.Fields, true, x.Incomplete)
+
+	case *ast.FuncType:
+		p.print(token.FUNC)
+		p.signature(x.Params, x.Results)
+
+	case *ast.InterfaceType:
+		p.print(token.INTERFACE)
+		p.fieldList(x.Methods, false, x.Incomplete)
+
+	case *ast.MapType:
+		p.print(token.MAP, token.LBRACK)
+		p.expr(x.Key)
+		p.print(token.RBRACK)
+		p.expr(x.Value)
+
+	case *ast.ChanType:
+		switch x.Dir {
+		case ast.SEND | ast.RECV:
+			p.print(token.CHAN)
+		case ast.RECV:
+			p.print(token.ARROW, token.CHAN) // x.Arrow and x.Pos() are the same
+		case ast.SEND:
+			p.print(token.CHAN, x.Arrow, token.ARROW)
+		}
+		p.print(blank)
+		p.expr(x.Value)
+
+	default:
+		panic("unreachable")
+	}
+
+	return
+}
+
+func (p *printer) expr0(x ast.Expr, depth int) {
+	p.expr1(x, token.LowestPrec, depth)
+}
+
+func (p *printer) expr(x ast.Expr) {
+	const depth = 1
+	p.expr1(x, token.LowestPrec, depth)
+}
+
+// ----------------------------------------------------------------------------
+// Statements
+
+// Print the statement list indented, but without a newline after the last statement.
+// Extra line breaks between statements in the source are respected but at most one
+// empty line is printed between statements.
+func (p *printer) stmtList(list []ast.Stmt, nindent int, nextIsRBrace bool) {
+	if nindent > 0 {
+		p.print(indent)
+	}
+	var line int
+	i := 0
+	for _, s := range list {
+		// ignore empty statements (was issue 3466)
+		if _, isEmpty := s.(*ast.EmptyStmt); !isEmpty {
+			// nindent == 0 only for lists of switch/select case clauses;
+			// in those cases each clause is a new section
+			if len(p.output) > 0 {
+				// only print line break if we are not at the beginning of the output
+				// (i.e., we are not printing only a partial program)
+				p.linebreak(p.lineFor(s.Pos()), 1, ignore, i == 0 || nindent == 0 || p.linesFrom(line) > 0)
+			}
+			p.recordLine(&line)
+			p.stmt(s, nextIsRBrace && i == len(list)-1)
+			// labeled statements put labels on a separate line, but here
+			// we only care about the start line of the actual statement
+			// without label - correct line for each label
+			for t := s; ; {
+				lt, _ := t.(*ast.LabeledStmt)
+				if lt == nil {
+					break
+				}
+				line++
+				t = lt.Stmt
+			}
+			i++
+		}
+	}
+	if nindent > 0 {
+		p.print(unindent)
+	}
+}
+
+// block prints an *ast.BlockStmt; it always spans at least two lines.
+func (p *printer) block(b *ast.BlockStmt, nindent int) {
+	p.print(b.Lbrace, token.LBRACE)
+	p.stmtList(b.List, nindent, true)
+	p.linebreak(p.lineFor(b.Rbrace), 1, ignore, true)
+	p.print(b.Rbrace, token.RBRACE)
+}
+
+func isTypeName(x ast.Expr) bool {
+	switch t := x.(type) {
+	case *ast.Ident:
+		return true
+	case *ast.SelectorExpr:
+		return isTypeName(t.X)
+	}
+	return false
+}
+
+func stripParens(x ast.Expr) ast.Expr {
+	if px, strip := x.(*ast.ParenExpr); strip {
+		// parentheses must not be stripped if there are any
+		// unparenthesized composite literals starting with
+		// a type name
+		ast.Inspect(px.X, func(node ast.Node) bool {
+			switch x := node.(type) {
+			case *ast.ParenExpr:
+				// parentheses protect enclosed composite literals
+				return false
+			case *ast.CompositeLit:
+				if isTypeName(x.Type) {
+					strip = false // do not strip parentheses
+				}
+				return false
+			}
+			// in all other cases, keep inspecting
+			return true
+		})
+		if strip {
+			return stripParens(px.X)
+		}
+	}
+	return x
+}
+
+func stripParensAlways(x ast.Expr) ast.Expr {
+	if x, ok := x.(*ast.ParenExpr); ok {
+		return stripParensAlways(x.X)
+	}
+	return x
+}
+
+func (p *printer) controlClause(isForStmt bool, init ast.Stmt, expr ast.Expr, post ast.Stmt) {
+	p.print(blank)
+	needsBlank := false
+	if init == nil && post == nil {
+		// no semicolons required
+		if expr != nil {
+			p.expr(stripParens(expr))
+			needsBlank = true
+		}
+	} else {
+		// all semicolons required
+		// (they are not separators, print them explicitly)
+		if init != nil {
+			p.stmt(init, false)
+		}
+		p.print(token.SEMICOLON, blank)
+		if expr != nil {
+			p.expr(stripParens(expr))
+			needsBlank = true
+		}
+		if isForStmt {
+			p.print(token.SEMICOLON, blank)
+			needsBlank = false
+			if post != nil {
+				p.stmt(post, false)
+				needsBlank = true
+			}
+		}
+	}
+	if needsBlank {
+		p.print(blank)
+	}
+}
+
+// indentList reports whether an expression list would look better if it
+// were indented wholesale (starting with the very first element, rather
+// than starting at the first line break).
+//
+func (p *printer) indentList(list []ast.Expr) bool {
+	// Heuristic: indentList returns true if there are more than one multi-
+	// line element in the list, or if there is any element that is not
+	// starting on the same line as the previous one ends.
+	if len(list) >= 2 {
+		var b = p.lineFor(list[0].Pos())
+		var e = p.lineFor(list[len(list)-1].End())
+		if 0 < b && b < e {
+			// list spans multiple lines
+			n := 0 // multi-line element count
+			line := b
+			for _, x := range list {
+				xb := p.lineFor(x.Pos())
+				xe := p.lineFor(x.End())
+				if line < xb {
+					// x is not starting on the same
+					// line as the previous one ended
+					return true
+				}
+				if xb < xe {
+					// x is a multi-line element
+					n++
+				}
+				line = xe
+			}
+			return n > 1
+		}
+	}
+	return false
+}
+
+func (p *printer) stmt(stmt ast.Stmt, nextIsRBrace bool) {
+	p.print(stmt.Pos())
+
+	switch s := stmt.(type) {
+	case *ast.BadStmt:
+		p.print("BadStmt")
+
+	case *ast.DeclStmt:
+		p.decl(s.Decl)
+
+	case *ast.EmptyStmt:
+		// nothing to do
+
+	case *ast.LabeledStmt:
+		// a "correcting" unindent immediately following a line break
+		// is applied before the line break if there is no comment
+		// between (see writeWhitespace)
+		p.print(unindent)
+		p.expr(s.Label)
+		p.print(s.Colon, token.COLON, indent)
+		if e, isEmpty := s.Stmt.(*ast.EmptyStmt); isEmpty {
+			if !nextIsRBrace {
+				p.print(newline, e.Pos(), token.SEMICOLON)
+				break
+			}
+		} else {
+			p.linebreak(p.lineFor(s.Stmt.Pos()), 1, ignore, true)
+		}
+		p.stmt(s.Stmt, nextIsRBrace)
+
+	case *ast.ExprStmt:
+		const depth = 1
+		p.expr0(s.X, depth)
+
+	case *ast.SendStmt:
+		const depth = 1
+		p.expr0(s.Chan, depth)
+		p.print(blank, s.Arrow, token.ARROW, blank)
+		p.expr0(s.Value, depth)
+
+	case *ast.IncDecStmt:
+		const depth = 1
+		p.expr0(s.X, depth+1)
+		p.print(s.TokPos, s.Tok)
+
+	case *ast.AssignStmt:
+		var depth = 1
+		if len(s.Lhs) > 1 && len(s.Rhs) > 1 {
+			depth++
+		}
+		p.exprList(s.Pos(), s.Lhs, depth, 0, s.TokPos)
+		p.print(blank, s.TokPos, s.Tok, blank)
+		p.exprList(s.TokPos, s.Rhs, depth, 0, token.NoPos)
+
+	case *ast.GoStmt:
+		p.print(token.GO, blank)
+		p.expr(s.Call)
+
+	case *ast.DeferStmt:
+		p.print(token.DEFER, blank)
+		p.expr(s.Call)
+
+	case *ast.ReturnStmt:
+		p.print(token.RETURN)
+		if s.Results != nil {
+			p.print(blank)
+			// Use indentList heuristic to make corner cases look
+			// better (issue 1207). A more systematic approach would
+			// always indent, but this would cause significant
+			// reformatting of the code base and not necessarily
+			// lead to more nicely formatted code in general.
+			if p.indentList(s.Results) {
+				p.print(indent)
+				p.exprList(s.Pos(), s.Results, 1, noIndent, token.NoPos)
+				p.print(unindent)
+			} else {
+				p.exprList(s.Pos(), s.Results, 1, 0, token.NoPos)
+			}
+		}
+
+	case *ast.BranchStmt:
+		p.print(s.Tok)
+		if s.Label != nil {
+			p.print(blank)
+			p.expr(s.Label)
+		}
+
+	case *ast.BlockStmt:
+		p.block(s, 1)
+
+	case *ast.IfStmt:
+		p.print(token.IF)
+		p.controlClause(false, s.Init, s.Cond, nil)
+		p.block(s.Body, 1)
+		if s.Else != nil {
+			p.print(blank, token.ELSE, blank)
+			switch s.Else.(type) {
+			case *ast.BlockStmt, *ast.IfStmt:
+				p.stmt(s.Else, nextIsRBrace)
+			default:
+				p.print(token.LBRACE, indent, formfeed)
+				p.stmt(s.Else, true)
+				p.print(unindent, formfeed, token.RBRACE)
+			}
+		}
+
+	case *ast.CaseClause:
+		if s.List != nil {
+			p.print(token.CASE, blank)
+			p.exprList(s.Pos(), s.List, 1, 0, s.Colon)
+		} else {
+			p.print(token.DEFAULT)
+		}
+		p.print(s.Colon, token.COLON)
+		p.stmtList(s.Body, 1, nextIsRBrace)
+
+	case *ast.SwitchStmt:
+		p.print(token.SWITCH)
+		p.controlClause(false, s.Init, s.Tag, nil)
+		p.block(s.Body, 0)
+
+	case *ast.TypeSwitchStmt:
+		p.print(token.SWITCH)
+		if s.Init != nil {
+			p.print(blank)
+			p.stmt(s.Init, false)
+			p.print(token.SEMICOLON)
+		}
+		p.print(blank)
+		p.stmt(s.Assign, false)
+		p.print(blank)
+		p.block(s.Body, 0)
+
+	case *ast.CommClause:
+		if s.Comm != nil {
+			p.print(token.CASE, blank)
+			p.stmt(s.Comm, false)
+		} else {
+			p.print(token.DEFAULT)
+		}
+		p.print(s.Colon, token.COLON)
+		p.stmtList(s.Body, 1, nextIsRBrace)
+
+	case *ast.SelectStmt:
+		p.print(token.SELECT, blank)
+		body := s.Body
+		if len(body.List) == 0 && !p.commentBefore(p.posFor(body.Rbrace)) {
+			// print empty select statement w/o comments on one line
+			p.print(body.Lbrace, token.LBRACE, body.Rbrace, token.RBRACE)
+		} else {
+			p.block(body, 0)
+		}
+
+	case *ast.ForStmt:
+		p.print(token.FOR)
+		p.controlClause(true, s.Init, s.Cond, s.Post)
+		p.block(s.Body, 1)
+
+	case *ast.RangeStmt:
+		p.print(token.FOR, blank)
+		if s.Key != nil {
+			p.expr(s.Key)
+			if s.Value != nil {
+				// use position of value following the comma as
+				// comma position for correct comment placement
+				p.print(s.Value.Pos(), token.COMMA, blank)
+				p.expr(s.Value)
+			}
+			p.print(blank, s.TokPos, s.Tok, blank)
+		}
+		p.print(token.RANGE, blank)
+		p.expr(stripParens(s.X))
+		p.print(blank)
+		p.block(s.Body, 1)
+
+	default:
+		panic("unreachable")
+	}
+
+	return
+}
+
+// ----------------------------------------------------------------------------
+// Declarations
+
+// The keepTypeColumn function determines if the type column of a series of
+// consecutive const or var declarations must be kept, or if initialization
+// values (V) can be placed in the type column (T) instead. The i'th entry
+// in the result slice is true if the type column in spec[i] must be kept.
+//
+// For example, the declaration:
+//
+//	const (
+//		foobar int = 42 // comment
+//		x          = 7  // comment
+//		foo
+//              bar = 991
+//	)
+//
+// leads to the type/values matrix below. A run of value columns (V) can
+// be moved into the type column if there is no type for any of the values
+// in that column (we only move entire columns so that they align properly).
+//
+//	matrix        formatted     result
+//                    matrix
+//	T  V    ->    T  V     ->   true      there is a T and so the type
+//	-  V          -  V          true      column must be kept
+//	-  -          -  -          false
+//	-  V          V  -          false     V is moved into T column
+//
+func keepTypeColumn(specs []ast.Spec) []bool {
+	m := make([]bool, len(specs))
+
+	populate := func(i, j int, keepType bool) {
+		if keepType {
+			for ; i < j; i++ {
+				m[i] = true
+			}
+		}
+	}
+
+	i0 := -1 // if i0 >= 0 we are in a run and i0 is the start of the run
+	var keepType bool
+	for i, s := range specs {
+		t := s.(*ast.ValueSpec)
+		if t.Values != nil {
+			if i0 < 0 {
+				// start of a run of ValueSpecs with non-nil Values
+				i0 = i
+				keepType = false
+			}
+		} else {
+			if i0 >= 0 {
+				// end of a run
+				populate(i0, i, keepType)
+				i0 = -1
+			}
+		}
+		if t.Type != nil {
+			keepType = true
+		}
+	}
+	if i0 >= 0 {
+		// end of a run
+		populate(i0, len(specs), keepType)
+	}
+
+	return m
+}
+
+func (p *printer) valueSpec(s *ast.ValueSpec, keepType bool) {
+	p.setComment(s.Doc)
+	p.identList(s.Names, false) // always present
+	extraTabs := 3
+	if s.Type != nil || keepType {
+		p.print(vtab)
+		extraTabs--
+	}
+	if s.Type != nil {
+		p.expr(s.Type)
+	}
+	if s.Values != nil {
+		p.print(vtab, token.ASSIGN, blank)
+		p.exprList(token.NoPos, s.Values, 1, 0, token.NoPos)
+		extraTabs--
+	}
+	if s.Comment != nil {
+		for ; extraTabs > 0; extraTabs-- {
+			p.print(vtab)
+		}
+		p.setComment(s.Comment)
+	}
+}
+
+// The parameter n is the number of specs in the group. If doIndent is set,
+// multi-line identifier lists in the spec are indented when the first
+// linebreak is encountered.
+//
+func (p *printer) spec(spec ast.Spec, n int, doIndent bool) {
+	switch s := spec.(type) {
+	case *ast.ImportSpec:
+		p.setComment(s.Doc)
+		if s.Name != nil {
+			p.expr(s.Name)
+			p.print(blank)
+		}
+		p.expr(s.Path)
+		p.setComment(s.Comment)
+		p.print(s.EndPos)
+
+	case *ast.ValueSpec:
+		if n != 1 {
+			p.internalError("expected n = 1; got", n)
+		}
+		p.setComment(s.Doc)
+		p.identList(s.Names, doIndent) // always present
+		if s.Type != nil {
+			p.print(blank)
+			p.expr(s.Type)
+		}
+		if s.Values != nil {
+			p.print(blank, token.ASSIGN, blank)
+			p.exprList(token.NoPos, s.Values, 1, 0, token.NoPos)
+		}
+		p.setComment(s.Comment)
+
+	case *ast.TypeSpec:
+		p.setComment(s.Doc)
+		p.expr(s.Name)
+		if n == 1 {
+			p.print(blank)
+		} else {
+			p.print(vtab)
+		}
+		p.expr(s.Type)
+		p.setComment(s.Comment)
+
+	default:
+		panic("unreachable")
+	}
+}
+
+func (p *printer) genDecl(d *ast.GenDecl) {
+	p.setComment(d.Doc)
+	p.print(d.Pos(), d.Tok, blank)
+
+	if d.Lparen.IsValid() {
+		// group of parenthesized declarations
+		p.print(d.Lparen, token.LPAREN)
+		if n := len(d.Specs); n > 0 {
+			p.print(indent, formfeed)
+			if n > 1 && (d.Tok == token.CONST || d.Tok == token.VAR) {
+				// two or more grouped const/var declarations:
+				// determine if the type column must be kept
+				keepType := keepTypeColumn(d.Specs)
+				var line int
+				for i, s := range d.Specs {
+					if i > 0 {
+						p.linebreak(p.lineFor(s.Pos()), 1, ignore, p.linesFrom(line) > 0)
+					}
+					p.recordLine(&line)
+					p.valueSpec(s.(*ast.ValueSpec), keepType[i])
+				}
+			} else {
+				var line int
+				for i, s := range d.Specs {
+					if i > 0 {
+						p.linebreak(p.lineFor(s.Pos()), 1, ignore, p.linesFrom(line) > 0)
+					}
+					p.recordLine(&line)
+					p.spec(s, n, false)
+				}
+			}
+			p.print(unindent, formfeed)
+		}
+		p.print(d.Rparen, token.RPAREN)
+
+	} else {
+		// single declaration
+		p.spec(d.Specs[0], 1, true)
+	}
+}
+
+// nodeSize determines the size of n in chars after formatting.
+// The result is <= maxSize if the node fits on one line with at
+// most maxSize chars and the formatted output doesn't contain
+// any control chars. Otherwise, the result is > maxSize.
+//
+func (p *printer) nodeSize(n ast.Node, maxSize int) (size int) {
+	// nodeSize invokes the printer, which may invoke nodeSize
+	// recursively. For deep composite literal nests, this can
+	// lead to an exponential algorithm. Remember previous
+	// results to prune the recursion (was issue 1628).
+	if size, found := p.nodeSizes[n]; found {
+		return size
+	}
+
+	size = maxSize + 1 // assume n doesn't fit
+	p.nodeSizes[n] = size
+
+	// nodeSize computation must be independent of particular
+	// style so that we always get the same decision; print
+	// in RawFormat
+	cfg := Config{Mode: RawFormat}
+	var buf bytes.Buffer
+	if err := cfg.fprint(&buf, p.fset, n, p.nodeSizes); err != nil {
+		return
+	}
+	if buf.Len() <= maxSize {
+		for _, ch := range buf.Bytes() {
+			if ch < ' ' {
+				return
+			}
+		}
+		size = buf.Len() // n fits
+		p.nodeSizes[n] = size
+	}
+	return
+}
+
+// bodySize is like nodeSize but it is specialized for *ast.BlockStmt's.
+func (p *printer) bodySize(b *ast.BlockStmt, maxSize int) int {
+	pos1 := b.Pos()
+	pos2 := b.Rbrace
+	if pos1.IsValid() && pos2.IsValid() && p.lineFor(pos1) != p.lineFor(pos2) {
+		// opening and closing brace are on different lines - don't make it a one-liner
+		return maxSize + 1
+	}
+	if len(b.List) > 5 {
+		// too many statements - don't make it a one-liner
+		return maxSize + 1
+	}
+	// otherwise, estimate body size
+	bodySize := p.commentSizeBefore(p.posFor(pos2))
+	for i, s := range b.List {
+		if bodySize > maxSize {
+			break // no need to continue
+		}
+		if i > 0 {
+			bodySize += 2 // space for a semicolon and blank
+		}
+		bodySize += p.nodeSize(s, maxSize)
+	}
+	return bodySize
+}
+
+// adjBlock prints an "adjacent" block (e.g., a for-loop or function body) following
+// a header (e.g., a for-loop control clause or function signature) of given headerSize.
+// If the header's and block's size are "small enough" and the block is "simple enough",
+// the block is printed on the current line, without line breaks, spaced from the header
+// by sep. Otherwise the block's opening "{" is printed on the current line, followed by
+// lines for the block's statements and its closing "}".
+//
+func (p *printer) adjBlock(headerSize int, sep whiteSpace, b *ast.BlockStmt) {
+	if b == nil {
+		return
+	}
+
+	const maxSize = 100
+	if headerSize+p.bodySize(b, maxSize) <= maxSize {
+		p.print(sep, b.Lbrace, token.LBRACE)
+		if len(b.List) > 0 {
+			p.print(blank)
+			for i, s := range b.List {
+				if i > 0 {
+					p.print(token.SEMICOLON, blank)
+				}
+				p.stmt(s, i == len(b.List)-1)
+			}
+			p.print(blank)
+		}
+		p.print(noExtraLinebreak, b.Rbrace, token.RBRACE, noExtraLinebreak)
+		return
+	}
+
+	if sep != ignore {
+		p.print(blank) // always use blank
+	}
+	p.block(b, 1)
+}
+
+// distanceFrom returns the column difference between from and p.pos (the current
+// estimated position) if both are on the same line; if they are on different lines
+// (or unknown) the result is infinity.
+func (p *printer) distanceFrom(from token.Pos) int {
+	if from.IsValid() && p.pos.IsValid() {
+		if f := p.posFor(from); f.Line == p.pos.Line {
+			return p.pos.Column - f.Column
+		}
+	}
+	return infinity
+}
+
+func (p *printer) funcDecl(d *ast.FuncDecl) {
+	p.setComment(d.Doc)
+	p.print(d.Pos(), token.FUNC, blank)
+	if d.Recv != nil {
+		p.parameters(d.Recv) // method: print receiver
+		p.print(blank)
+	}
+	p.expr(d.Name)
+	p.signature(d.Type.Params, d.Type.Results)
+	p.adjBlock(p.distanceFrom(d.Pos()), vtab, d.Body)
+}
+
+func (p *printer) decl(decl ast.Decl) {
+	switch d := decl.(type) {
+	case *ast.BadDecl:
+		p.print(d.Pos(), "BadDecl")
+	case *ast.GenDecl:
+		p.genDecl(d)
+	case *ast.FuncDecl:
+		p.funcDecl(d)
+	default:
+		panic("unreachable")
+	}
+}
+
+// ----------------------------------------------------------------------------
+// Files
+
+func declToken(decl ast.Decl) (tok token.Token) {
+	tok = token.ILLEGAL
+	switch d := decl.(type) {
+	case *ast.GenDecl:
+		tok = d.Tok
+	case *ast.FuncDecl:
+		tok = token.FUNC
+	}
+	return
+}
+
+func (p *printer) declList(list []ast.Decl) {
+	tok := token.ILLEGAL
+	for _, d := range list {
+		prev := tok
+		tok = declToken(d)
+		// If the declaration token changed (e.g., from CONST to TYPE)
+		// or the next declaration has documentation associated with it,
+		// print an empty line between top-level declarations.
+		// (because p.linebreak is called with the position of d, which
+		// is past any documentation, the minimum requirement is satisfied
+		// even w/o the extra getDoc(d) nil-check - leave it in case the
+		// linebreak logic improves - there's already a TODO).
+		if len(p.output) > 0 {
+			// only print line break if we are not at the beginning of the output
+			// (i.e., we are not printing only a partial program)
+			min := 1
+			if prev != tok || getDoc(d) != nil {
+				min = 2
+			}
+			p.linebreak(p.lineFor(d.Pos()), min, ignore, false)
+		}
+		p.decl(d)
+	}
+}
+
+func (p *printer) file(src *ast.File) {
+	p.setComment(src.Doc)
+	p.print(src.Pos(), token.PACKAGE, blank)
+	p.expr(src.Name)
+	p.declList(src.Decls)
+	p.print(newline)
+}
diff --git a/src/pkg/go/printer/performance_test.go b/src/go/printer/performance_test.go
similarity index 100%
rename from src/pkg/go/printer/performance_test.go
rename to src/go/printer/performance_test.go
diff --git a/src/pkg/go/printer/printer.go b/src/go/printer/printer.go
similarity index 100%
rename from src/pkg/go/printer/printer.go
rename to src/go/printer/printer.go
diff --git a/src/go/printer/printer_test.go b/src/go/printer/printer_test.go
new file mode 100644
index 0000000..3b0570e
--- /dev/null
+++ b/src/go/printer/printer_test.go
@@ -0,0 +1,562 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package printer
+
+import (
+	"bytes"
+	"errors"
+	"flag"
+	"fmt"
+	"go/ast"
+	"go/parser"
+	"go/token"
+	"io/ioutil"
+	"path/filepath"
+	"testing"
+	"time"
+)
+
+const (
+	dataDir  = "testdata"
+	tabwidth = 8
+)
+
+var update = flag.Bool("update", false, "update golden files")
+
+var fset = token.NewFileSet()
+
+type checkMode uint
+
+const (
+	export checkMode = 1 << iota
+	rawFormat
+	idempotent
+)
+
+// format parses src, prints the corresponding AST, verifies the resulting
+// src is syntactically correct, and returns the resulting src or an error
+// if any.
+func format(src []byte, mode checkMode) ([]byte, error) {
+	// parse src
+	f, err := parser.ParseFile(fset, "", src, parser.ParseComments)
+	if err != nil {
+		return nil, fmt.Errorf("parse: %s\n%s", err, src)
+	}
+
+	// filter exports if necessary
+	if mode&export != 0 {
+		ast.FileExports(f) // ignore result
+		f.Comments = nil   // don't print comments that are not in AST
+	}
+
+	// determine printer configuration
+	cfg := Config{Tabwidth: tabwidth}
+	if mode&rawFormat != 0 {
+		cfg.Mode |= RawFormat
+	}
+
+	// print AST
+	var buf bytes.Buffer
+	if err := cfg.Fprint(&buf, fset, f); err != nil {
+		return nil, fmt.Errorf("print: %s", err)
+	}
+
+	// make sure formatted output is syntactically correct
+	res := buf.Bytes()
+	if _, err := parser.ParseFile(fset, "", res, 0); err != nil {
+		return nil, fmt.Errorf("re-parse: %s\n%s", err, buf.Bytes())
+	}
+
+	return res, nil
+}
+
+// lineAt returns the line in text starting at offset offs.
+func lineAt(text []byte, offs int) []byte {
+	i := offs
+	for i < len(text) && text[i] != '\n' {
+		i++
+	}
+	return text[offs:i]
+}
+
+// diff compares a and b.
+func diff(aname, bname string, a, b []byte) error {
+	var buf bytes.Buffer // holding long error message
+
+	// compare lengths
+	if len(a) != len(b) {
+		fmt.Fprintf(&buf, "\nlength changed: len(%s) = %d, len(%s) = %d", aname, len(a), bname, len(b))
+	}
+
+	// compare contents
+	line := 1
+	offs := 1
+	for i := 0; i < len(a) && i < len(b); i++ {
+		ch := a[i]
+		if ch != b[i] {
+			fmt.Fprintf(&buf, "\n%s:%d:%d: %s", aname, line, i-offs+1, lineAt(a, offs))
+			fmt.Fprintf(&buf, "\n%s:%d:%d: %s", bname, line, i-offs+1, lineAt(b, offs))
+			fmt.Fprintf(&buf, "\n\n")
+			break
+		}
+		if ch == '\n' {
+			line++
+			offs = i + 1
+		}
+	}
+
+	if buf.Len() > 0 {
+		return errors.New(buf.String())
+	}
+	return nil
+}
+
+func runcheck(t *testing.T, source, golden string, mode checkMode) {
+	src, err := ioutil.ReadFile(source)
+	if err != nil {
+		t.Error(err)
+		return
+	}
+
+	res, err := format(src, mode)
+	if err != nil {
+		t.Error(err)
+		return
+	}
+
+	// update golden files if necessary
+	if *update {
+		if err := ioutil.WriteFile(golden, res, 0644); err != nil {
+			t.Error(err)
+		}
+		return
+	}
+
+	// get golden
+	gld, err := ioutil.ReadFile(golden)
+	if err != nil {
+		t.Error(err)
+		return
+	}
+
+	// formatted source and golden must be the same
+	if err := diff(source, golden, res, gld); err != nil {
+		t.Error(err)
+		return
+	}
+
+	if mode&idempotent != 0 {
+		// formatting golden must be idempotent
+		// (This is very difficult to achieve in general and for now
+		// it is only checked for files explicitly marked as such.)
+		res, err = format(gld, mode)
+		if err := diff(golden, fmt.Sprintf("format(%s)", golden), gld, res); err != nil {
+			t.Errorf("golden is not idempotent: %s", err)
+		}
+	}
+}
+
+func check(t *testing.T, source, golden string, mode checkMode) {
+	// run the test
+	cc := make(chan int)
+	go func() {
+		runcheck(t, source, golden, mode)
+		cc <- 0
+	}()
+
+	// wait with timeout
+	select {
+	case <-time.After(10 * time.Second): // plenty of a safety margin, even for very slow machines
+		// test running past time out
+		t.Errorf("%s: running too slowly", source)
+	case <-cc:
+		// test finished within allotted time margin
+	}
+}
+
+type entry struct {
+	source, golden string
+	mode           checkMode
+}
+
+// Use go test -update to create/update the respective golden files.
+var data = []entry{
+	{"empty.input", "empty.golden", idempotent},
+	{"comments.input", "comments.golden", 0},
+	{"comments.input", "comments.x", export},
+	{"comments2.input", "comments2.golden", idempotent},
+	{"linebreaks.input", "linebreaks.golden", idempotent},
+	{"expressions.input", "expressions.golden", idempotent},
+	{"expressions.input", "expressions.raw", rawFormat | idempotent},
+	{"declarations.input", "declarations.golden", 0},
+	{"statements.input", "statements.golden", 0},
+	{"slow.input", "slow.golden", idempotent},
+}
+
+func TestFiles(t *testing.T) {
+	for _, e := range data {
+		source := filepath.Join(dataDir, e.source)
+		golden := filepath.Join(dataDir, e.golden)
+		check(t, source, golden, e.mode)
+		// TODO(gri) check that golden is idempotent
+		//check(t, golden, golden, e.mode)
+	}
+}
+
+// TestLineComments, using a simple test case, checks that consecutive line
+// comments are properly terminated with a newline even if the AST position
+// information is incorrect.
+//
+func TestLineComments(t *testing.T) {
+	const src = `// comment 1
+	// comment 2
+	// comment 3
+	package main
+	`
+
+	fset := token.NewFileSet()
+	f, err := parser.ParseFile(fset, "", src, parser.ParseComments)
+	if err != nil {
+		panic(err) // error in test
+	}
+
+	var buf bytes.Buffer
+	fset = token.NewFileSet() // use the wrong file set
+	Fprint(&buf, fset, f)
+
+	nlines := 0
+	for _, ch := range buf.Bytes() {
+		if ch == '\n' {
+			nlines++
+		}
+	}
+
+	const expected = 3
+	if nlines < expected {
+		t.Errorf("got %d, expected %d\n", nlines, expected)
+		t.Errorf("result:\n%s", buf.Bytes())
+	}
+}
+
+// Verify that the printer can be invoked during initialization.
+func init() {
+	const name = "foobar"
+	var buf bytes.Buffer
+	if err := Fprint(&buf, fset, &ast.Ident{Name: name}); err != nil {
+		panic(err) // error in test
+	}
+	// in debug mode, the result contains additional information;
+	// ignore it
+	if s := buf.String(); !debug && s != name {
+		panic("got " + s + ", want " + name)
+	}
+}
+
+// Verify that the printer doesn't crash if the AST contains BadXXX nodes.
+func TestBadNodes(t *testing.T) {
+	const src = "package p\n("
+	const res = "package p\nBadDecl\n"
+	f, err := parser.ParseFile(fset, "", src, parser.ParseComments)
+	if err == nil {
+		t.Error("expected illegal program") // error in test
+	}
+	var buf bytes.Buffer
+	Fprint(&buf, fset, f)
+	if buf.String() != res {
+		t.Errorf("got %q, expected %q", buf.String(), res)
+	}
+}
+
+// testComment verifies that f can be parsed again after printing it
+// with its first comment set to comment at any possible source offset.
+func testComment(t *testing.T, f *ast.File, srclen int, comment *ast.Comment) {
+	f.Comments[0].List[0] = comment
+	var buf bytes.Buffer
+	for offs := 0; offs <= srclen; offs++ {
+		buf.Reset()
+		// Printing f should result in a correct program no
+		// matter what the (incorrect) comment position is.
+		if err := Fprint(&buf, fset, f); err != nil {
+			t.Error(err)
+		}
+		if _, err := parser.ParseFile(fset, "", buf.Bytes(), 0); err != nil {
+			t.Fatalf("incorrect program for pos = %d:\n%s", comment.Slash, buf.String())
+		}
+		// Position information is just an offset.
+		// Move comment one byte down in the source.
+		comment.Slash++
+	}
+}
+
+// Verify that the printer produces a correct program
+// even if the position information of comments introducing newlines
+// is incorrect.
+func TestBadComments(t *testing.T) {
+	const src = `
+// first comment - text and position changed by test
+package p
+import "fmt"
+const pi = 3.14 // rough circle
+var (
+	x, y, z int = 1, 2, 3
+	u, v float64
+)
+func fibo(n int) {
+	if n < 2 {
+		return n /* seed values */
+	}
+	return fibo(n-1) + fibo(n-2)
+}
+`
+
+	f, err := parser.ParseFile(fset, "", src, parser.ParseComments)
+	if err != nil {
+		t.Error(err) // error in test
+	}
+
+	comment := f.Comments[0].List[0]
+	pos := comment.Pos()
+	if fset.Position(pos).Offset != 1 {
+		t.Error("expected offset 1") // error in test
+	}
+
+	testComment(t, f, len(src), &ast.Comment{Slash: pos, Text: "//-style comment"})
+	testComment(t, f, len(src), &ast.Comment{Slash: pos, Text: "/*-style comment */"})
+	testComment(t, f, len(src), &ast.Comment{Slash: pos, Text: "/*-style \n comment */"})
+	testComment(t, f, len(src), &ast.Comment{Slash: pos, Text: "/*-style comment \n\n\n */"})
+}
+
+type visitor chan *ast.Ident
+
+func (v visitor) Visit(n ast.Node) (w ast.Visitor) {
+	if ident, ok := n.(*ast.Ident); ok {
+		v <- ident
+	}
+	return v
+}
+
+// idents is an iterator that returns all idents in f via the result channel.
+func idents(f *ast.File) <-chan *ast.Ident {
+	v := make(visitor)
+	go func() {
+		ast.Walk(v, f)
+		close(v)
+	}()
+	return v
+}
+
+// identCount returns the number of identifiers found in f.
+func identCount(f *ast.File) int {
+	n := 0
+	for range idents(f) {
+		n++
+	}
+	return n
+}
+
+// Verify that the SourcePos mode emits correct //line comments
+// by testing that position information for matching identifiers
+// is maintained.
+func TestSourcePos(t *testing.T) {
+	const src = `
+package p
+import ( "go/printer"; "math" )
+const pi = 3.14; var x = 0
+type t struct{ x, y, z int; u, v, w float32 }
+func (t *t) foo(a, b, c int) int {
+	return a*t.x + b*t.y +
+		// two extra lines here
+		// ...
+		c*t.z
+}
+`
+
+	// parse original
+	f1, err := parser.ParseFile(fset, "src", src, parser.ParseComments)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	// pretty-print original
+	var buf bytes.Buffer
+	err = (&Config{Mode: UseSpaces | SourcePos, Tabwidth: 8}).Fprint(&buf, fset, f1)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	// parse pretty printed original
+	// (//line comments must be interpreted even w/o parser.ParseComments set)
+	f2, err := parser.ParseFile(fset, "", buf.Bytes(), 0)
+	if err != nil {
+		t.Fatalf("%s\n%s", err, buf.Bytes())
+	}
+
+	// At this point the position information of identifiers in f2 should
+	// match the position information of corresponding identifiers in f1.
+
+	// number of identifiers must be > 0 (test should run) and must match
+	n1 := identCount(f1)
+	n2 := identCount(f2)
+	if n1 == 0 {
+		t.Fatal("got no idents")
+	}
+	if n2 != n1 {
+		t.Errorf("got %d idents; want %d", n2, n1)
+	}
+
+	// verify that all identifiers have correct line information
+	i2range := idents(f2)
+	for i1 := range idents(f1) {
+		i2 := <-i2range
+
+		if i2.Name != i1.Name {
+			t.Errorf("got ident %s; want %s", i2.Name, i1.Name)
+		}
+
+		l1 := fset.Position(i1.Pos()).Line
+		l2 := fset.Position(i2.Pos()).Line
+		if l2 != l1 {
+			t.Errorf("got line %d; want %d for %s", l2, l1, i1.Name)
+		}
+	}
+
+	if t.Failed() {
+		t.Logf("\n%s", buf.Bytes())
+	}
+}
+
+var decls = []string{
+	`import "fmt"`,
+	"const pi = 3.1415\nconst e = 2.71828\n\nvar x = pi",
+	"func sum(x, y int) int\t{ return x + y }",
+}
+
+func TestDeclLists(t *testing.T) {
+	for _, src := range decls {
+		file, err := parser.ParseFile(fset, "", "package p;"+src, parser.ParseComments)
+		if err != nil {
+			panic(err) // error in test
+		}
+
+		var buf bytes.Buffer
+		err = Fprint(&buf, fset, file.Decls) // only print declarations
+		if err != nil {
+			panic(err) // error in test
+		}
+
+		out := buf.String()
+		if out != src {
+			t.Errorf("\ngot : %q\nwant: %q\n", out, src)
+		}
+	}
+}
+
+var stmts = []string{
+	"i := 0",
+	"select {}\nvar a, b = 1, 2\nreturn a + b",
+	"go f()\ndefer func() {}()",
+}
+
+func TestStmtLists(t *testing.T) {
+	for _, src := range stmts {
+		file, err := parser.ParseFile(fset, "", "package p; func _() {"+src+"}", parser.ParseComments)
+		if err != nil {
+			panic(err) // error in test
+		}
+
+		var buf bytes.Buffer
+		err = Fprint(&buf, fset, file.Decls[0].(*ast.FuncDecl).Body.List) // only print statements
+		if err != nil {
+			panic(err) // error in test
+		}
+
+		out := buf.String()
+		if out != src {
+			t.Errorf("\ngot : %q\nwant: %q\n", out, src)
+		}
+	}
+}
+
+func TestBaseIndent(t *testing.T) {
+	// The testfile must not contain multi-line raw strings since those
+	// are not indented (because their values must not change) and make
+	// this test fail.
+	const filename = "printer.go"
+	src, err := ioutil.ReadFile(filename)
+	if err != nil {
+		panic(err) // error in test
+	}
+
+	file, err := parser.ParseFile(fset, filename, src, 0)
+	if err != nil {
+		panic(err) // error in test
+	}
+
+	var buf bytes.Buffer
+	for indent := 0; indent < 4; indent++ {
+		buf.Reset()
+		(&Config{Tabwidth: tabwidth, Indent: indent}).Fprint(&buf, fset, file)
+		// all code must be indented by at least 'indent' tabs
+		lines := bytes.Split(buf.Bytes(), []byte{'\n'})
+		for i, line := range lines {
+			if len(line) == 0 {
+				continue // empty lines don't have indentation
+			}
+			n := 0
+			for j, b := range line {
+				if b != '\t' {
+					// end of indentation
+					n = j
+					break
+				}
+			}
+			if n < indent {
+				t.Errorf("line %d: got only %d tabs; want at least %d: %q", i, n, indent, line)
+			}
+		}
+	}
+}
+
+// TestFuncType tests that an ast.FuncType with a nil Params field
+// can be printed (per go/ast specification). Test case for issue 3870.
+func TestFuncType(t *testing.T) {
+	src := &ast.File{
+		Name: &ast.Ident{Name: "p"},
+		Decls: []ast.Decl{
+			&ast.FuncDecl{
+				Name: &ast.Ident{Name: "f"},
+				Type: &ast.FuncType{},
+			},
+		},
+	}
+
+	var buf bytes.Buffer
+	if err := Fprint(&buf, fset, src); err != nil {
+		t.Fatal(err)
+	}
+	got := buf.String()
+
+	const want = `package p
+
+func f()
+`
+
+	if got != want {
+		t.Fatalf("got:\n%s\nwant:\n%s\n", got, want)
+	}
+}
+
+// TextX is a skeleton test that can be filled in for debugging one-off cases.
+// Do not remove.
+func TestX(t *testing.T) {
+	const src = `
+package p
+func _() {}
+`
+	_, err := format([]byte(src), 0)
+	if err != nil {
+		t.Error(err)
+	}
+}
diff --git a/src/pkg/go/printer/testdata/comments.golden b/src/go/printer/testdata/comments.golden
similarity index 100%
rename from src/pkg/go/printer/testdata/comments.golden
rename to src/go/printer/testdata/comments.golden
diff --git a/src/pkg/go/printer/testdata/comments.input b/src/go/printer/testdata/comments.input
similarity index 100%
rename from src/pkg/go/printer/testdata/comments.input
rename to src/go/printer/testdata/comments.input
diff --git a/src/pkg/go/printer/testdata/comments.x b/src/go/printer/testdata/comments.x
similarity index 100%
rename from src/pkg/go/printer/testdata/comments.x
rename to src/go/printer/testdata/comments.x
diff --git a/src/pkg/go/printer/testdata/comments2.golden b/src/go/printer/testdata/comments2.golden
similarity index 100%
rename from src/pkg/go/printer/testdata/comments2.golden
rename to src/go/printer/testdata/comments2.golden
diff --git a/src/pkg/go/printer/testdata/comments2.input b/src/go/printer/testdata/comments2.input
similarity index 100%
rename from src/pkg/go/printer/testdata/comments2.input
rename to src/go/printer/testdata/comments2.input
diff --git a/src/go/printer/testdata/declarations.golden b/src/go/printer/testdata/declarations.golden
new file mode 100644
index 0000000..9acd41b
--- /dev/null
+++ b/src/go/printer/testdata/declarations.golden
@@ -0,0 +1,978 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package imports
+
+import "io"
+
+import (
+	_ "io"
+)
+
+import _ "io"
+
+import (
+	"io"
+	"io"
+	"io"
+)
+
+import (
+	"io"
+	aLongRename "io"
+
+	b "io"
+)
+
+import (
+	"unrenamed"
+	renamed "renameMe"
+	. "io"
+	_ "io"
+	"io"
+	. "os"
+)
+
+// no newlines between consecutive single imports, but
+// respect extra line breaks in the source (at most one empty line)
+import _ "io"
+import _ "io"
+import _ "io"
+
+import _ "os"
+import _ "os"
+import _ "os"
+
+import _ "fmt"
+import _ "fmt"
+import _ "fmt"
+
+import "foo"	// a comment
+import "bar"	// a comment
+
+import (
+	_ "foo"
+	// a comment
+	"bar"
+	"foo"	// a comment
+	"bar"	// a comment
+)
+
+// comments + renames
+import (
+	"unrenamed"	// a comment
+	renamed "renameMe"
+	. "io"		/* a comment */
+	_ "io/ioutil"	// a comment
+	"io"		// testing alignment
+	. "os"
+	// a comment
+)
+
+// a case that caused problems in the past (comment placement)
+import (
+	. "fmt"
+	"io"
+	"malloc"	// for the malloc count test only
+	"math"
+	"strings"
+	"testing"
+)
+
+// more import examples
+import (
+	"xxx"
+	"much_longer_name"	// comment
+	"short_name"		// comment
+)
+
+import (
+	_ "xxx"
+	"much_longer_name"	// comment
+)
+
+import (
+	mymath "math"
+	"/foo/bar/long_package_path"	// a comment
+)
+
+import (
+	"package_a"	// comment
+	"package_b"
+	my_better_c "package_c"	// comment
+	"package_d"		// comment
+	my_e "package_e"	// comment
+
+	"package_a"	// comment
+	"package_bb"
+	"package_ccc"	// comment
+	"package_dddd"	// comment
+)
+
+// at least one empty line between declarations of different kind
+import _ "io"
+
+var _ int
+
+// at least one empty line between declarations of the same kind
+// if there is associated documentation (was issue 2570)
+type T1 struct{}
+
+// T2 comment
+type T2 struct {
+}	// should be a two-line struct
+
+// T3 comment
+type T2 struct {
+}	// should be a two-line struct
+
+// printing of constant literals
+const (
+	_	= "foobar"
+	_	= "a۰۱۸"
+	_	= "foo६४"
+	_	= "bar9876"
+	_	= 0
+	_	= 1
+	_	= 123456789012345678890
+	_	= 01234567
+	_	= 0xcafebabe
+	_	= 0.
+	_	= .0
+	_	= 3.14159265
+	_	= 1e0
+	_	= 1e+100
+	_	= 1e-100
+	_	= 2.71828e-1000
+	_	= 0i
+	_	= 1i
+	_	= 012345678901234567889i
+	_	= 123456789012345678890i
+	_	= 0.i
+	_	= .0i
+	_	= 3.14159265i
+	_	= 1e0i
+	_	= 1e+100i
+	_	= 1e-100i
+	_	= 2.71828e-1000i
+	_	= 'a'
+	_	= '\000'
+	_	= '\xFF'
+	_	= '\uff16'
+	_	= '\U0000ff16'
+	_	= `foobar`
+	_	= `foo
+---
+---
+bar`
+)
+
+func _() {
+	type _ int
+	type _ *int
+	type _ []int
+	type _ map[string]int
+	type _ chan int
+	type _ func() int
+
+	var _ int
+	var _ *int
+	var _ []int
+	var _ map[string]int
+	var _ chan int
+	var _ func() int
+
+	type _ struct{}
+	type _ *struct{}
+	type _ []struct{}
+	type _ map[string]struct{}
+	type _ chan struct{}
+	type _ func() struct{}
+
+	type _ interface{}
+	type _ *interface{}
+	type _ []interface{}
+	type _ map[string]interface{}
+	type _ chan interface{}
+	type _ func() interface{}
+
+	var _ struct{}
+	var _ *struct{}
+	var _ []struct{}
+	var _ map[string]struct{}
+	var _ chan struct{}
+	var _ func() struct{}
+
+	var _ interface{}
+	var _ *interface{}
+	var _ []interface{}
+	var _ map[string]interface{}
+	var _ chan interface{}
+	var _ func() interface{}
+}
+
+// don't lose blank lines in grouped declarations
+const (
+	_	int	= 0
+	_	float	= 1
+
+	_	string	= "foo"
+
+	_	= iota
+	_
+
+	// a comment
+	_
+
+	_
+)
+
+type (
+	_	int
+	_	struct{}
+
+	_	interface{}
+
+	// a comment
+	_	map[string]int
+)
+
+var (
+	_	int	= 0
+	_	float	= 1
+
+	_	string	= "foo"
+
+	_	bool
+
+	// a comment
+	_	bool
+)
+
+// don't lose blank lines in this struct
+type _ struct {
+	String	struct {
+		Str, Len int
+	}
+	Slice	struct {
+		Array, Len, Cap int
+	}
+	Eface	struct {
+		Typ, Ptr int
+	}
+
+	UncommonType	struct {
+		Name, PkgPath int
+	}
+	CommonType	struct {
+		Size, Hash, Alg, Align, FieldAlign, String, UncommonType int
+	}
+	Type	struct {
+		Typ, Ptr int
+	}
+	StructField	struct {
+		Name, PkgPath, Typ, Tag, Offset int
+	}
+	StructType	struct {
+		Fields int
+	}
+	PtrType	struct {
+		Elem int
+	}
+	SliceType	struct {
+		Elem int
+	}
+	ArrayType	struct {
+		Elem, Len int
+	}
+
+	Stktop	struct {
+		Stackguard, Stackbase, Gobuf int
+	}
+	Gobuf	struct {
+		Sp, Pc, G int
+	}
+	G	struct {
+		Stackbase, Sched, Status, Alllink int
+	}
+}
+
+// no blank lines in empty structs and interfaces, but leave 1- or 2-line layout alone
+type _ struct{}
+type _ struct {
+}
+
+type _ interface{}
+type _ interface {
+}
+
+// no tabs for single or ungrouped decls
+func _() {
+	const xxxxxx = 0
+	type x int
+	var xxx int
+	var yyyy float = 3.14
+	var zzzzz = "bar"
+
+	const (
+		xxxxxx = 0
+	)
+	type (
+		x int
+	)
+	var (
+		xxx int
+	)
+	var (
+		yyyy float = 3.14
+	)
+	var (
+		zzzzz = "bar"
+	)
+}
+
+// tabs for multiple or grouped decls
+func _() {
+	// no entry has a type
+	const (
+		zzzzzz	= 1
+		z	= 2
+		zzz	= 3
+	)
+	// some entries have a type
+	const (
+		xxxxxx			= 1
+		x			= 2
+		xxx			= 3
+		yyyyyyyy	float	= iota
+		yyyy			= "bar"
+		yyy
+		yy	= 2
+	)
+}
+
+func _() {
+	// no entry has a type
+	var (
+		zzzzzz	= 1
+		z	= 2
+		zzz	= 3
+	)
+	// no entry has a value
+	var (
+		_	int
+		_	float
+		_	string
+
+		_	int	// comment
+		_	float	// comment
+		_	string	// comment
+	)
+	// some entries have a type
+	var (
+		xxxxxx		int
+		x		float
+		xxx		string
+		yyyyyyyy	int	= 1234
+		y		float	= 3.14
+		yyyy			= "bar"
+		yyy		string	= "foo"
+	)
+	// mixed entries - all comments should be aligned
+	var (
+		a, b, c			int
+		x			= 10
+		d			int			// comment
+		y				= 20		// comment
+		f, ff, fff, ffff	int	= 0, 1, 2, 3	// comment
+	)
+	// respect original line breaks
+	var _ = []T{
+		T{0x20, "Telugu"},
+	}
+	var _ = []T{
+		// respect original line breaks
+		T{0x20, "Telugu"},
+	}
+}
+
+// use the formatted output rather than the input to decide when to align
+// (was issue 4505)
+const (
+	short		= 2 * (1 + 2)
+	aMuchLongerName	= 3
+)
+
+var (
+	short		= X{}
+	aMuchLongerName	= X{}
+
+	x1	= X{}	// foo
+	x2	= X{}	// foo
+)
+
+func _() {
+	type (
+		xxxxxx	int
+		x	float
+		xxx	string
+		xxxxx	[]x
+		xx	struct{}
+		xxxxxxx	struct {
+			_, _	int
+			_	float
+		}
+		xxxx	chan<- string
+	)
+}
+
+// alignment of "=" in consecutive lines (extended example from issue 1414)
+const (
+	umax	uint	= ^uint(0)		// maximum value for a uint
+	bpu		= 1 << (5 + umax>>63)	// bits per uint
+	foo
+	bar	= -1
+)
+
+// typical enum
+const (
+	a	MyType	= iota
+	abcd
+	b
+	c
+	def
+)
+
+// excerpt from godoc.go
+var (
+	goroot		= flag.String("goroot", runtime.GOROOT(), "Go root directory")
+	testDir		= flag.String("testdir", "", "Go root subdirectory - for testing only (faster startups)")
+	pkgPath		= flag.String("path", "", "additional package directories (colon-separated)")
+	filter		= flag.String("filter", "", "filter file containing permitted package directory paths")
+	filterMin	= flag.Int("filter_minutes", 0, "filter file update interval in minutes; disabled if <= 0")
+	filterDelay	delayTime	// actual filter update interval in minutes; usually filterDelay == filterMin, but filterDelay may back off exponentially
+)
+
+// formatting of structs
+type _ struct{}
+
+type _ struct { /* this comment should be visible */
+}
+
+type _ struct {
+	// this comment should be visible and properly indented
+}
+
+type _ struct {	// this comment must not change indentation
+	f			int
+	f, ff, fff, ffff	int
+}
+
+type _ struct {
+	string
+}
+
+type _ struct {
+	string	// comment
+}
+
+type _ struct {
+	string "tag"
+}
+
+type _ struct {
+	string "tag"	// comment
+}
+
+type _ struct {
+	f int
+}
+
+type _ struct {
+	f int	// comment
+}
+
+type _ struct {
+	f int "tag"
+}
+
+type _ struct {
+	f int "tag"	// comment
+}
+
+type _ struct {
+	bool
+	a, b, c			int
+	int			"tag"
+	ES				// comment
+	float			"tag"	// comment
+	f			int	// comment
+	f, ff, fff, ffff	int	// comment
+	g			float	"tag"
+	h			float	"tag"	// comment
+}
+
+type _ struct {
+	a, b,
+	c, d	int	// this line should be indented
+	u, v, w, x	float	// this line should be indented
+	p, q,
+	r, s	float	// this line should be indented
+}
+
+// difficult cases
+type _ struct {
+	bool		// comment
+	text	[]byte	// comment
+}
+
+// formatting of interfaces
+type EI interface{}
+
+type _ interface {
+	EI
+}
+
+type _ interface {
+	f()
+	fffff()
+}
+
+type _ interface {
+	EI
+	f()
+	fffffg()
+}
+
+type _ interface {	// this comment must not change indentation
+	EI				// here's a comment
+	f()				// no blank between identifier and ()
+	fffff()				// no blank between identifier and ()
+	gggggggggggg(x, y, z int)	// hurray
+}
+
+// formatting of variable declarations
+func _() {
+	type day struct {
+		n		int
+		short, long	string
+	}
+	var (
+		Sunday		= day{0, "SUN", "Sunday"}
+		Monday		= day{1, "MON", "Monday"}
+		Tuesday		= day{2, "TUE", "Tuesday"}
+		Wednesday	= day{3, "WED", "Wednesday"}
+		Thursday	= day{4, "THU", "Thursday"}
+		Friday		= day{5, "FRI", "Friday"}
+		Saturday	= day{6, "SAT", "Saturday"}
+	)
+}
+
+// formatting of multi-line variable declarations
+var a1, b1, c1 int	// all on one line
+
+var a2, b2,
+	c2 int	// this line should be indented
+
+var (
+	a3, b3,
+	c3, d3	int	// this line should be indented
+	a4, b4, c4	int	// this line should be indented
+)
+
+// Test case from issue 3304: multi-line declarations must end
+// a formatting section and not influence indentation of the
+// next line.
+var (
+	minRefreshTimeSec	= flag.Int64("min_refresh_time_sec", 604800,
+		"minimum time window between two refreshes for a given user.")
+	x	= flag.Int64("refresh_user_rollout_percent", 100,
+		"temporary flag to ramp up the refresh user rpc")
+	aVeryLongVariableName	= stats.GetVarInt("refresh-user-count")
+)
+
+func _() {
+	var privateKey2 = &Block{Type: "RSA PRIVATE KEY",
+		Headers:	map[string]string{},
+		Bytes: []uint8{0x30, 0x82, 0x1, 0x3a, 0x2, 0x1, 0x0, 0x2,
+			0x41, 0x0, 0xb2, 0x99, 0xf, 0x49, 0xc4, 0x7d, 0xfa, 0x8c,
+			0xd4, 0x0, 0xae, 0x6a, 0x4d, 0x1b, 0x8a, 0x3b, 0x6a, 0x13,
+			0x64, 0x2b, 0x23, 0xf2, 0x8b, 0x0, 0x3b, 0xfb, 0x97, 0x79,
+		},
+	}
+}
+
+func _() {
+	var Universe = Scope{
+		Names: map[string]*Ident{
+			// basic types
+			"bool":		nil,
+			"byte":		nil,
+			"int8":		nil,
+			"int16":	nil,
+			"int32":	nil,
+			"int64":	nil,
+			"uint8":	nil,
+			"uint16":	nil,
+			"uint32":	nil,
+			"uint64":	nil,
+			"float32":	nil,
+			"float64":	nil,
+			"string":	nil,
+
+			// convenience types
+			"int":		nil,
+			"uint":		nil,
+			"uintptr":	nil,
+			"float":	nil,
+
+			// constants
+			"false":	nil,
+			"true":		nil,
+			"iota":		nil,
+			"nil":		nil,
+
+			// functions
+			"cap":		nil,
+			"len":		nil,
+			"new":		nil,
+			"make":		nil,
+			"panic":	nil,
+			"panicln":	nil,
+			"print":	nil,
+			"println":	nil,
+		},
+	}
+}
+
+// alignment of map composite entries
+var _ = map[int]int{
+	// small key sizes: always align even if size ratios are large
+	a:			a,
+	abcdefghabcdefgh:	a,
+	ab:			a,
+	abc:			a,
+	abcdefgabcdefg:		a,
+	abcd:			a,
+	abcde:			a,
+	abcdef:			a,
+
+	// mixed key sizes: align when key sizes change within accepted ratio
+	abcdefgh:		a,
+	abcdefghabcdefg:	a,
+	abcdefghij:		a,
+	abcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghij:	a,	// outlier - do not align with previous line
+	abcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghij:		a,	// align with previous line
+
+	ab:	a,	// do not align with previous line
+	abcde:	a,	// align with previous line
+}
+
+// alignment of map composite entries: test cases from issue 3965
+// aligned
+var _ = T1{
+	a:			x,
+	b:			y,
+	cccccccccccccccccccc:	z,
+}
+
+// not aligned
+var _ = T2{
+	a:	x,
+	b:	y,
+	ccccccccccccccccccccc:	z,
+}
+
+// aligned
+var _ = T3{
+	aaaaaaaaaaaaaaaaaaaa:	x,
+	b:			y,
+	c:			z,
+}
+
+// not aligned
+var _ = T4{
+	aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:	x,
+	b:	y,
+	c:	z,
+}
+
+// no alignment of map composite entries if they are not the first entry on a line
+var _ = T{0: 0}	// not aligned
+var _ = T{0: 0,	// not aligned
+	1:	1,				// aligned
+	22:	22,				// aligned
+	333:	333, 1234: 12, 12345: 0,	// first on line aligned
+}
+
+// test cases form issue 8685
+// not aligned
+var _ = map[int]string{1: "spring", 2: "summer",
+	3:	"autumn", 4: "winter"}
+
+// not aligned
+var _ = map[string]string{"a": "spring", "b": "summer",
+	"c":	"autumn", "d": "winter"}
+
+// aligned
+var _ = map[string]string{"a": "spring",
+	"b":	"summer",
+	"c":	"autumn",
+	"d":	"winter"}
+
+func _() {
+	var _ = T{
+		a,	// must introduce trailing comma
+	}
+}
+
+// formatting of function results
+func _() func()				{}
+func _() func(int)			{ return nil }
+func _() func(int) int			{ return nil }
+func _() func(int) func(int) func()	{ return nil }
+
+// formatting of consecutive single-line functions
+func _()	{}
+func _()	{}
+func _()	{}
+
+func _()	{}	// an empty line before this function
+func _()	{}
+func _()	{}
+
+func _()		{ f(1, 2, 3) }
+func _(x int) int	{ y := x; return y + 1 }
+func _() int		{ type T struct{}; var x T; return x }
+
+// these must remain multi-line since they are multi-line in the source
+func _() {
+	f(1, 2, 3)
+}
+func _(x int) int {
+	y := x
+	return y + 1
+}
+func _() int {
+	type T struct{}
+	var x T
+	return x
+}
+
+// making function declarations safe for new semicolon rules
+func _()	{ /* single-line function because of "short-ish" comment */ }
+func _() { /* multi-line function because of "long-ish" comment - much more comment text is following here */ /* and more */
+}
+
+func _() {
+	/* multi-line func because block is on multiple lines */
+}
+
+// ellipsis parameters
+func _(...int)
+func _(...*int)
+func _(...[]int)
+func _(...struct{})
+func _(bool, ...interface{})
+func _(bool, ...func())
+func _(bool, ...func(...int))
+func _(bool, ...map[string]int)
+func _(bool, ...chan int)
+
+func _(b bool, x ...int)
+func _(b bool, x ...*int)
+func _(b bool, x ...[]int)
+func _(b bool, x ...struct{})
+func _(x ...interface{})
+func _(x ...func())
+func _(x ...func(...int))
+func _(x ...map[string]int)
+func _(x ...chan int)
+
+// these parameter lists must remain multi-line since they are multi-line in the source
+func _(bool,
+	int) {
+}
+func _(x bool,
+	y int) {
+}
+func _(x,
+	y bool) {
+}
+func _(bool,	// comment
+	int) {
+}
+func _(x bool,	// comment
+	y int) {
+}
+func _(x,	// comment
+	y bool) {
+}
+func _(bool,	// comment
+	// comment
+	int) {
+}
+func _(x bool,	// comment
+	// comment
+	y int) {
+}
+func _(x,	// comment
+	// comment
+	y bool) {
+}
+func _(bool,
+	// comment
+	int) {
+}
+func _(x bool,
+	// comment
+	y int) {
+}
+func _(x,
+	// comment
+	y bool) {
+}
+func _(x,	// comment
+	y,	// comment
+	z bool) {
+}
+func _(x,	// comment
+	y,	// comment
+	z bool) {
+}
+func _(x int,	// comment
+	y float,	// comment
+	z bool) {
+}
+
+// properly indent multi-line signatures
+func ManageStatus(in <-chan *Status, req <-chan Request,
+	stat chan<- *TargetInfo,
+	TargetHistorySize int) {
+}
+
+func MultiLineSignature0(
+	a, b, c int,
+) {
+}
+
+func MultiLineSignature1(
+	a, b, c int,
+	u, v, w float,
+) {
+}
+
+func MultiLineSignature2(
+	a, b,
+	c int,
+) {
+}
+
+func MultiLineSignature3(
+	a, b,
+	c int, u, v,
+	w float,
+	x ...int) {
+}
+
+func MultiLineSignature4(
+	a, b, c int,
+	u, v,
+	w float,
+	x ...int) {
+}
+
+func MultiLineSignature5(
+	a, b, c int,
+	u, v, w float,
+	p, q,
+	r string,
+	x ...int) {
+}
+
+// make sure it also works for methods in interfaces
+type _ interface {
+	MultiLineSignature0(
+		a, b, c int,
+	)
+
+	MultiLineSignature1(
+		a, b, c int,
+		u, v, w float,
+	)
+
+	MultiLineSignature2(
+		a, b,
+		c int,
+	)
+
+	MultiLineSignature3(
+		a, b,
+		c int, u, v,
+		w float,
+		x ...int)
+
+	MultiLineSignature4(
+		a, b, c int,
+		u, v,
+		w float,
+		x ...int)
+
+	MultiLineSignature5(
+		a, b, c int,
+		u, v, w float,
+		p, q,
+		r string,
+		x ...int)
+}
+
+// omit superfluous parentheses in parameter lists
+func _(int)
+func _(int)
+func _(x int)
+func _(x int)
+func _(x, y int)
+func _(x, y int)
+
+func _() int
+func _() int
+func _() int
+
+func _() (x int)
+func _() (x int)
+func _() (x int)
+
+// special cases: some channel types require parentheses
+func _(x chan (<-chan int))
+func _(x chan (<-chan int))
+func _(x chan (<-chan int))
+
+func _(x chan<- (chan int))
+func _(x chan<- (chan int))
+func _(x chan<- (chan int))
+
+// don't introduce comma after last parameter if the closing ) is on the same line
+// even if the parameter type itself is multi-line (test cases from issue 4533)
+func _(...interface{})
+func _(...interface {
+	m()
+	n()
+})	// no extra comma between } and )
+
+func (t *T) _(...interface{})
+func (t *T) _(...interface {
+	m()
+	n()
+})	// no extra comma between } and )
+
+func _(interface{})
+func _(interface {
+	m()
+})	// no extra comma between } and )
+
+func _(struct{})
+func _(struct {
+	x	int
+	y	int
+})	// no extra comma between } and )
diff --git a/src/go/printer/testdata/declarations.input b/src/go/printer/testdata/declarations.input
new file mode 100644
index 0000000..45beec2
--- /dev/null
+++ b/src/go/printer/testdata/declarations.input
@@ -0,0 +1,992 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package imports
+
+import "io"
+
+import (
+	_ "io"
+)
+
+import _ "io"
+
+import (
+	"io"
+	"io"
+	"io"
+)
+
+import (
+	"io"
+	aLongRename "io"
+
+	b "io"
+)
+
+import (
+       "unrenamed"
+       renamed "renameMe"
+       . "io"
+       _ "io"
+       "io"
+       . "os"
+)
+
+// no newlines between consecutive single imports, but
+// respect extra line breaks in the source (at most one empty line)
+import _ "io"
+import _ "io"
+import _ "io"
+
+import _ "os"
+import _ "os"
+import _ "os"
+
+
+import _ "fmt"
+import _ "fmt"
+import _ "fmt"
+
+import "foo"  // a comment
+import "bar"  // a comment
+
+import (
+	_ "foo"
+	// a comment
+	"bar"
+	"foo"  // a comment
+	"bar"  // a comment
+)
+
+// comments + renames
+import (
+       "unrenamed" // a comment
+       renamed "renameMe"
+       . "io" /* a comment */
+       _ "io/ioutil" // a comment
+       "io" // testing alignment
+       . "os"
+       // a comment
+)
+
+// a case that caused problems in the past (comment placement)
+import (
+	. "fmt"
+	"io"
+	"malloc"	// for the malloc count test only
+	"math"
+	"strings"
+	"testing"
+)
+
+// more import examples
+import (
+	"xxx"
+	"much_longer_name" // comment
+	"short_name" // comment
+)
+
+import (
+	_ "xxx"
+	"much_longer_name" // comment
+)
+
+import (
+	mymath "math"
+	"/foo/bar/long_package_path" // a comment
+)
+
+import (
+	"package_a" // comment
+	"package_b"
+	my_better_c "package_c" // comment
+	"package_d" // comment
+	my_e "package_e" // comment
+
+	"package_a"    // comment
+	"package_bb"
+	"package_ccc"  // comment
+	"package_dddd" // comment
+)
+
+// at least one empty line between declarations of different kind
+import _ "io"
+var _ int
+
+// at least one empty line between declarations of the same kind
+// if there is associated documentation (was issue 2570)
+type T1 struct{}
+// T2 comment
+type T2 struct {
+} // should be a two-line struct
+
+
+// T3 comment
+type T2 struct {
+
+
+} // should be a two-line struct
+
+
+// printing of constant literals
+const (
+	_ = "foobar"
+	_ = "a۰۱۸"
+	_ = "foo६४"
+	_ = "bar9876"
+	_ = 0
+	_ = 1
+	_ = 123456789012345678890
+	_ = 01234567
+	_ = 0xcafebabe
+	_ = 0.
+	_ = .0
+	_ = 3.14159265
+	_ = 1e0
+	_ = 1e+100
+	_ = 1e-100
+	_ = 2.71828e-1000
+	_ = 0i
+	_ = 1i
+	_ = 012345678901234567889i
+	_ = 123456789012345678890i
+	_ = 0.i
+	_ = .0i
+	_ = 3.14159265i
+	_ = 1e0i
+	_ = 1e+100i
+	_ = 1e-100i
+	_ = 2.71828e-1000i
+	_ = 'a'
+	_ = '\000'
+	_ = '\xFF'
+	_ = '\uff16'
+	_ = '\U0000ff16'
+	_ = `foobar`
+	_ = `foo
+---
+---
+bar`
+)
+
+
+func _() {
+	type _ int
+	type _ *int
+	type _ []int
+	type _ map[string]int
+	type _ chan int
+	type _ func() int
+
+	var _ int
+	var _ *int
+	var _ []int
+	var _ map[string]int
+	var _ chan int
+	var _ func() int
+
+	type _ struct{}
+	type _ *struct{}
+	type _ []struct{}
+	type _ map[string]struct{}
+	type _ chan struct{}
+	type _ func() struct{}
+
+	type _ interface{}
+	type _ *interface{}
+	type _ []interface{}
+	type _ map[string]interface{}
+	type _ chan interface{}
+	type _ func() interface{}
+
+	var _ struct{}
+	var _ *struct{}
+	var _ []struct{}
+	var _ map[string]struct{}
+	var _ chan struct{}
+	var _ func() struct{}
+
+	var _ interface{}
+	var _ *interface{}
+	var _ []interface{}
+	var _ map[string]interface{}
+	var _ chan interface{}
+	var _ func() interface{}
+}
+
+
+// don't lose blank lines in grouped declarations
+const (
+	_ int = 0
+	_ float = 1
+
+	_ string = "foo"
+
+	_ = iota
+	_
+	
+	// a comment
+	_
+
+	_
+)
+
+
+type (
+	_ int
+	_ struct {}
+	
+	_ interface{}
+	
+	// a comment
+	_ map[string]int
+)
+
+
+var (
+	_ int = 0
+	_ float = 1
+
+	_ string = "foo"
+
+	_ bool
+	
+	// a comment
+	_ bool
+)
+
+
+// don't lose blank lines in this struct
+type _ struct {
+	String struct {
+		Str, Len int
+	}
+	Slice struct {
+		Array, Len, Cap int
+	}
+	Eface struct {
+		Typ, Ptr int
+	}
+
+	UncommonType struct {
+		Name, PkgPath int
+	}
+	CommonType struct {
+		Size, Hash, Alg, Align, FieldAlign, String, UncommonType int
+	}
+	Type struct {
+		Typ, Ptr int
+	}
+	StructField struct {
+		Name, PkgPath, Typ, Tag, Offset int
+	}
+	StructType struct {
+		Fields int
+	}
+	PtrType struct {
+		Elem int
+	}
+	SliceType struct {
+		Elem int
+	}
+	ArrayType struct {
+		Elem, Len int
+	}
+
+	Stktop struct {
+		Stackguard, Stackbase, Gobuf int
+	}
+	Gobuf struct {
+		Sp, Pc, G int
+	}
+	G struct {
+		Stackbase, Sched, Status, Alllink int
+	}
+}
+
+
+// no blank lines in empty structs and interfaces, but leave 1- or 2-line layout alone
+type _ struct{            }
+type _ struct {
+
+}
+
+type _ interface{            }
+type _ interface {
+
+}
+
+
+// no tabs for single or ungrouped decls
+func _() {
+	const xxxxxx = 0
+	type x int
+	var xxx int
+	var yyyy float = 3.14
+	var zzzzz = "bar"
+
+	const (
+		xxxxxx = 0
+	)
+	type (
+		x int
+	)
+	var (
+		xxx int
+	)
+	var (
+		yyyy float = 3.14
+	)
+	var (
+		zzzzz = "bar"
+	)
+}
+
+// tabs for multiple or grouped decls
+func _() {
+	// no entry has a type
+	const (
+		zzzzzz = 1
+		z = 2
+		zzz = 3
+	)
+	// some entries have a type
+	const (
+		xxxxxx = 1
+		x = 2
+		xxx = 3
+		yyyyyyyy float = iota
+		yyyy = "bar"
+		yyy
+		yy = 2
+	)
+}
+
+func _() {
+	// no entry has a type
+	var (
+		zzzzzz = 1
+		z = 2
+		zzz = 3
+	)
+	// no entry has a value
+	var (
+		_ int
+		_ float
+		_ string
+
+		_ int  // comment
+		_ float  // comment
+		_ string  // comment
+	)
+	// some entries have a type
+	var (
+		xxxxxx int
+		x float
+		xxx string
+		yyyyyyyy int = 1234
+		y float = 3.14
+		yyyy = "bar"
+		yyy string = "foo"
+	)
+	// mixed entries - all comments should be aligned
+	var (
+		a, b, c int
+		x = 10
+		d int  // comment
+		y = 20  // comment
+		f, ff, fff, ffff int = 0, 1, 2, 3  // comment
+	)
+	// respect original line breaks
+	var _ = []T {
+		T{0x20,	"Telugu"},
+	}
+	var _ = []T {
+		// respect original line breaks
+		T{0x20,	"Telugu"},
+	}
+}
+
+// use the formatted output rather than the input to decide when to align
+// (was issue 4505)
+const (
+	short = 2 * (
+	1 + 2)
+	aMuchLongerName = 3
+)
+
+var (
+	short = X{
+	}
+	aMuchLongerName = X{}
+
+	x1 = X{} // foo
+	x2 = X{
+	} // foo
+)
+
+func _() {
+	type (
+		xxxxxx int
+		x float
+		xxx string
+		xxxxx []x
+		xx struct{}
+		xxxxxxx struct {
+			_, _ int
+			_ float
+		}
+		xxxx chan<- string
+	)
+}
+
+// alignment of "=" in consecutive lines (extended example from issue 1414)
+const (
+	umax uint                  = ^uint(0) // maximum value for a uint
+	bpu  = 1 << (5 + umax>>63)            // bits per uint
+	foo
+	bar  = -1
+)
+
+// typical enum
+const (
+	a MyType = iota
+	abcd
+	b
+	c
+	def
+)
+
+// excerpt from godoc.go
+var (
+	goroot = flag.String("goroot", runtime.GOROOT(), "Go root directory")
+	testDir = flag.String("testdir", "", "Go root subdirectory - for testing only (faster startups)")
+	pkgPath = flag.String("path", "", "additional package directories (colon-separated)")
+	filter = flag.String("filter", "", "filter file containing permitted package directory paths")
+	filterMin = flag.Int("filter_minutes", 0, "filter file update interval in minutes; disabled if <= 0")
+	filterDelay delayTime // actual filter update interval in minutes; usually filterDelay == filterMin, but filterDelay may back off exponentially
+)
+
+
+// formatting of structs
+type _ struct{}
+
+type _ struct{ /* this comment should be visible */ }
+
+type _ struct{
+	// this comment should be visible and properly indented
+}
+
+type _ struct {  // this comment must not change indentation
+	f int
+	f, ff, fff, ffff int
+}
+
+type _ struct {
+	string
+}
+
+type _ struct {
+	string  // comment
+}
+
+type _ struct {
+	string "tag"
+}
+
+type _ struct {
+	string "tag"  // comment
+}
+
+type _ struct {
+	f int
+}
+
+type _ struct {
+	f int  // comment
+}
+
+type _ struct {
+	f int "tag"
+}
+
+type _ struct {
+	f int "tag"  // comment
+}
+
+type _ struct {
+	bool
+	a, b, c int
+	int "tag"
+	ES // comment
+	float "tag"  // comment
+	f int  // comment
+	f, ff, fff, ffff int  // comment
+	g float "tag"
+	h float "tag"  // comment
+}
+
+type _ struct { a, b,
+c, d int  // this line should be indented
+u, v, w, x float // this line should be indented
+p, q,
+r, s float // this line should be indented
+}
+
+
+// difficult cases
+type _ struct {
+	bool  // comment
+	text []byte  // comment
+}
+
+
+// formatting of interfaces
+type EI interface{}
+
+type _ interface {
+	EI
+}
+
+type _ interface {
+	f()
+	fffff()
+}
+
+type _ interface {
+	EI
+	f()
+	fffffg()
+}
+
+type _ interface {  // this comment must not change indentation
+	EI  // here's a comment
+	f()  // no blank between identifier and ()
+	fffff()  // no blank between identifier and ()
+	gggggggggggg(x, y, z int) ()  // hurray
+}
+
+
+// formatting of variable declarations
+func _() {
+	type day struct { n int; short, long string }
+	var (
+		Sunday = day{ 0, "SUN", "Sunday" }
+		Monday = day{ 1, "MON", "Monday" }
+		Tuesday = day{ 2, "TUE", "Tuesday" }
+		Wednesday = day{ 3, "WED", "Wednesday" }
+		Thursday = day{ 4, "THU", "Thursday" }
+		Friday = day{ 5, "FRI", "Friday" }
+		Saturday = day{ 6, "SAT", "Saturday" }
+	)
+}
+
+
+// formatting of multi-line variable declarations
+var a1, b1, c1 int  // all on one line
+
+var a2, b2,
+c2 int  // this line should be indented
+
+var (a3, b3,
+c3, d3 int  // this line should be indented
+a4, b4, c4 int  // this line should be indented
+)
+
+// Test case from issue 3304: multi-line declarations must end
+// a formatting section and not influence indentation of the
+// next line.
+var (
+	minRefreshTimeSec = flag.Int64("min_refresh_time_sec", 604800,
+		"minimum time window between two refreshes for a given user.")
+	x = flag.Int64("refresh_user_rollout_percent", 100,
+		"temporary flag to ramp up the refresh user rpc")
+	aVeryLongVariableName = stats.GetVarInt("refresh-user-count")
+)
+
+func _() {
+	var privateKey2 = &Block{Type: "RSA PRIVATE KEY",
+					Headers: map[string]string{},
+					Bytes: []uint8{0x30, 0x82, 0x1, 0x3a, 0x2, 0x1, 0x0, 0x2,
+			0x41, 0x0, 0xb2, 0x99, 0xf, 0x49, 0xc4, 0x7d, 0xfa, 0x8c,
+			0xd4, 0x0, 0xae, 0x6a, 0x4d, 0x1b, 0x8a, 0x3b, 0x6a, 0x13,
+			0x64, 0x2b, 0x23, 0xf2, 0x8b, 0x0, 0x3b, 0xfb, 0x97, 0x79,
+		},
+	}
+}
+
+
+func _() {
+	var Universe = Scope {
+		Names: map[string]*Ident {
+			// basic types
+			"bool": nil,
+			"byte": nil,
+			"int8": nil,
+			"int16": nil,
+			"int32": nil,
+			"int64": nil,
+			"uint8": nil,
+			"uint16": nil,
+			"uint32": nil,
+			"uint64": nil,
+			"float32": nil,
+			"float64": nil,
+			"string": nil,
+
+			// convenience types
+			"int": nil,
+			"uint": nil,
+			"uintptr": nil,
+			"float": nil,
+
+			// constants
+			"false": nil,
+			"true": nil,
+			"iota": nil,
+			"nil": nil,
+
+			// functions
+			"cap": nil,
+			"len": nil,
+			"new": nil,
+			"make": nil,
+			"panic": nil,
+			"panicln": nil,
+			"print": nil,
+			"println": nil,
+		},
+	}
+}
+
+
+// alignment of map composite entries
+var _ = map[int]int{
+	// small key sizes: always align even if size ratios are large
+	a: a,
+	abcdefghabcdefgh: a,
+	ab: a,
+	abc: a,
+	abcdefgabcdefg: a,
+	abcd: a,
+	abcde: a,
+	abcdef: a,
+
+	// mixed key sizes: align when key sizes change within accepted ratio
+	abcdefgh: a,
+	abcdefghabcdefg: a,
+	abcdefghij: a,
+	abcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghij: a, // outlier - do not align with previous line
+	abcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghij: a, // align with previous line
+
+	ab: a, // do not align with previous line
+	abcde: a, // align with previous line
+}
+
+// alignment of map composite entries: test cases from issue 3965
+// aligned
+var _ = T1{
+	a:                    x,
+	b:                    y,
+	cccccccccccccccccccc: z,
+}
+
+// not aligned
+var _ = T2{
+	a: x,
+	b: y,
+	ccccccccccccccccccccc: z,
+}
+
+// aligned
+var _ = T3{
+	aaaaaaaaaaaaaaaaaaaa: x,
+	b:                    y,
+	c:                    z,
+}
+
+// not aligned
+var _ = T4{
+	aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: x,
+	b:                                       y,
+	c:                                       z,
+}
+
+
+// no alignment of map composite entries if they are not the first entry on a line
+var _ = T{0: 0} // not aligned
+var _ = T{0: 0, // not aligned
+	1: 1, // aligned
+	22: 22, // aligned
+	333: 333, 1234: 12, 12345: 0, // first on line aligned
+}
+
+
+// test cases form issue 8685
+// not aligned
+var _ = map[int]string{1: "spring", 2: "summer",
+					3:             "autumn", 4: "winter"}
+
+// not aligned
+var _ = map[string]string{"a": "spring", "b": "summer",
+	"c": "autumn", "d": "winter"}
+
+// aligned
+var _ = map[string]string{"a": "spring",
+"b": "summer",
+	"c": "autumn",
+"d": "winter"}
+
+
+func _() {
+	var _ = T{
+		a,	// must introduce trailing comma
+	}
+}
+
+
+// formatting of function results
+func _() func() {}
+func _() func(int) { return nil }
+func _() func(int) int { return nil }
+func _() func(int) func(int) func() { return nil }
+
+
+// formatting of consecutive single-line functions
+func _() {}
+func _() {}
+func _() {}
+
+func _() {}  // an empty line before this function
+func _() {}
+func _() {}
+
+func _() { f(1, 2, 3) }
+func _(x int) int { y := x; return y+1 }
+func _() int { type T struct{}; var x T; return x }
+
+// these must remain multi-line since they are multi-line in the source
+func _() {
+	f(1, 2, 3)
+}
+func _(x int) int {
+	y := x; return y+1
+}
+func _() int {
+	type T struct{}; var x T; return x
+}
+
+
+// making function declarations safe for new semicolon rules
+func _() { /* single-line function because of "short-ish" comment */ }
+func _() { /* multi-line function because of "long-ish" comment - much more comment text is following here */ /* and more */ }
+
+func _() {
+/* multi-line func because block is on multiple lines */ }
+
+
+// ellipsis parameters
+func _(...int)
+func _(...*int)
+func _(...[]int)
+func _(...struct{})
+func _(bool, ...interface{})
+func _(bool, ...func())
+func _(bool, ...func(...int))
+func _(bool, ...map[string]int)
+func _(bool, ...chan int)
+
+func _(b bool, x ...int)
+func _(b bool, x ...*int)
+func _(b bool, x ...[]int)
+func _(b bool, x ...struct{})
+func _(x ...interface{})
+func _(x ...func())
+func _(x ...func(...int))
+func _(x ...map[string]int)
+func _(x ...chan int)
+
+
+// these parameter lists must remain multi-line since they are multi-line in the source
+func _(bool,
+int) {
+}
+func _(x bool,
+y int) {
+}
+func _(x,
+y bool) {
+}
+func _(bool, // comment
+int) {
+}
+func _(x bool, // comment
+y int) {
+}
+func _(x, // comment
+y bool) {
+}
+func _(bool, // comment
+// comment
+int) {
+}
+func _(x bool, // comment
+// comment
+y int) {
+}
+func _(x, // comment
+// comment
+y bool) {
+}
+func _(bool,
+// comment
+int) {
+}
+func _(x bool,
+// comment
+y int) {
+}
+func _(x,
+// comment
+y bool) {
+}
+func _(x, // comment
+y,// comment
+z bool) {
+}
+func _(x, // comment
+	y,// comment
+	z bool) {
+}
+func _(x int,	// comment
+	y float,	// comment
+	z bool) {
+}
+
+
+// properly indent multi-line signatures
+func ManageStatus(in <-chan *Status, req <-chan Request,
+stat chan<- *TargetInfo,
+TargetHistorySize int) {
+}
+
+func MultiLineSignature0(
+a, b, c int,
+) {}
+
+func MultiLineSignature1(
+a, b, c int,
+u, v, w float,
+) {}
+
+func MultiLineSignature2(
+a, b,
+c int,
+) {}
+
+func MultiLineSignature3(
+a, b,
+c int, u, v,
+w float,
+		x ...int) {}
+
+func MultiLineSignature4(
+a, b, c int,
+u, v,
+w float,
+		x ...int) {}
+
+func MultiLineSignature5(
+a, b, c int,
+u, v, w float,
+p, q,
+r string,
+		x ...int) {}
+
+// make sure it also works for methods in interfaces
+type _ interface {
+MultiLineSignature0(
+a, b, c int,
+)
+
+MultiLineSignature1(
+a, b, c int,
+u, v, w float,
+)
+
+MultiLineSignature2(
+a, b,
+c int,
+)
+
+MultiLineSignature3(
+a, b,
+c int, u, v,
+w float,
+		x ...int)
+
+MultiLineSignature4(
+a, b, c int,
+u, v,
+w float,
+		x ...int)
+
+MultiLineSignature5(
+a, b, c int,
+u, v, w float,
+p, q,
+r string,
+		x ...int)
+}
+
+// omit superfluous parentheses in parameter lists
+func _((int))
+func _((((((int))))))
+func _(x (int))
+func _(x (((((int))))))
+func _(x, y (int))
+func _(x, y (((((int))))))
+
+func _() (int)
+func _() ((int))
+func _() ((((((int))))))
+
+func _() (x int)
+func _() (x (int))
+func _() (x (((((int))))))
+
+// special cases: some channel types require parentheses
+func _(x chan(<-chan int))
+func _(x (chan(<-chan int)))
+func _(x ((((chan(<-chan int))))))
+
+func _(x chan<-(chan int))
+func _(x (chan<-(chan int)))
+func _(x ((((chan<-(chan int))))))
+
+// don't introduce comma after last parameter if the closing ) is on the same line
+// even if the parameter type itself is multi-line (test cases from issue 4533)
+func _(...interface{})
+func _(...interface {
+	m()
+	n()
+}) // no extra comma between } and )
+
+func (t *T) _(...interface{})
+func (t *T) _(...interface {
+	m()
+	n()
+}) // no extra comma between } and )
+
+func _(interface{})
+func _(interface {
+	m()
+}) // no extra comma between } and )
+
+func _(struct{})
+func _(struct {
+	x int
+	y int
+}) // no extra comma between } and )
diff --git a/src/pkg/go/printer/testdata/empty.golden b/src/go/printer/testdata/empty.golden
similarity index 100%
rename from src/pkg/go/printer/testdata/empty.golden
rename to src/go/printer/testdata/empty.golden
diff --git a/src/pkg/go/printer/testdata/empty.input b/src/go/printer/testdata/empty.input
similarity index 100%
rename from src/pkg/go/printer/testdata/empty.input
rename to src/go/printer/testdata/empty.input
diff --git a/src/go/printer/testdata/expressions.golden b/src/go/printer/testdata/expressions.golden
new file mode 100644
index 0000000..e3d17a4
--- /dev/null
+++ b/src/go/printer/testdata/expressions.golden
@@ -0,0 +1,686 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package expressions
+
+type T struct {
+	x, y, z int
+}
+
+var (
+	a, b, c, d, e						int
+	under_bar						int
+	longIdentifier1, longIdentifier2, longIdentifier3	int
+	t0, t1, t2						T
+	s							string
+	p							*int
+)
+
+func _() {
+	// no spaces around simple or parenthesized expressions
+	_ = (a + 0)
+	_ = a + b
+	_ = a + b + c
+	_ = a + b - c
+	_ = a - b - c
+	_ = a + (b * c)
+	_ = a + (b / c)
+	_ = a - (b % c)
+	_ = 1 + a
+	_ = a + 1
+	_ = a + b + 1
+	_ = s[a]
+	_ = s[a:]
+	_ = s[:b]
+	_ = s[1:2]
+	_ = s[a:b]
+	_ = s[0:len(s)]
+	_ = s[0] << 1
+	_ = (s[0] << 1) & 0xf
+	_ = s[0]<<2 | s[1]>>4
+	_ = "foo" + s
+	_ = s + "foo"
+	_ = 'a' + 'b'
+	_ = len(s) / 2
+	_ = len(t0.x) / a
+
+	// spaces around expressions of different precedence or expressions containing spaces
+	_ = a + -b
+	_ = a - ^b
+	_ = a / *p
+	_ = a + b*c
+	_ = 1 + b*c
+	_ = a + 2*c
+	_ = a + c*2
+	_ = 1 + 2*3
+	_ = s[1 : 2*3]
+	_ = s[a : b-c]
+	_ = s[0:]
+	_ = s[a+b]
+	_ = s[:b-c]
+	_ = s[a+b:]
+	_ = a[a<<b+1]
+	_ = a[a<<b+1:]
+	_ = s[a+b : len(s)]
+	_ = s[len(s):-a]
+	_ = s[a : len(s)+1]
+	_ = s[a:len(s)+1] + s
+
+	// spaces around operators with equal or lower precedence than comparisons
+	_ = a == b
+	_ = a != b
+	_ = a > b
+	_ = a >= b
+	_ = a < b
+	_ = a <= b
+	_ = a < b && c > d
+	_ = a < b || c > d
+
+	// spaces around "long" operands
+	_ = a + longIdentifier1
+	_ = longIdentifier1 + a
+	_ = longIdentifier1 + longIdentifier2*longIdentifier3
+	_ = s + "a longer string"
+
+	// some selected cases
+	_ = a + t0.x
+	_ = a + t0.x + t1.x*t2.x
+	_ = a + b + c + d + e + 2*3
+	_ = a + b + c + 2*3 + d + e
+	_ = (a + b + c) * 2
+	_ = a - b + c - d + (a + b + c) + d&e
+	_ = under_bar - 1
+	_ = Open(dpath+"/file", O_WRONLY|O_CREAT, 0666)
+	_ = int(c0&_Mask4)<<18 | int(c1&_Maskx)<<12 | int(c2&_Maskx)<<6 | int(c3&_Maskx)
+
+	// test case for issue 8021
+	// want:
+	//  ([]bool{})[([]int{})[((1)+(((1)+((((1)*(((1)+(1))+(1)))+(1))*(1)))+(1)))]]
+	_ = ([]bool{})[([]int{})[((1)+(((1)+((((1)*(((1)+(1))+(1)))+(1))*(1)))+(1)))]]
+
+	// the parser does not restrict expressions that may appear as statements
+	true
+	42
+	"foo"
+	x
+	(x)
+	a + b
+	a + b + c
+	a + (b * c)
+	a + (b / c)
+	1 + a
+	a + 1
+	s[a]
+	x << 1
+	(s[0] << 1) & 0xf
+	"foo" + s
+	x == y
+	x < y || z > 42
+}
+
+// slice expressions with cap
+func _() {
+	_ = x[a:b:c]
+	_ = x[a:b : c+d]
+	_ = x[a : b+d : c]
+	_ = x[a : b+d : c+d]
+	_ = x[a+d : b:c]
+	_ = x[a+d : b : c+d]
+	_ = x[a+d : b+d : c]
+	_ = x[a+d : b+d : c+d]
+
+	_ = x[:b:c]
+	_ = x[:b : c+d]
+	_ = x[:b+d : c]
+	_ = x[:b+d : c+d]
+}
+
+func _() {
+	_ = a + b
+	_ = a + b + c
+	_ = a + b*c
+	_ = a + (b * c)
+	_ = (a + b) * c
+	_ = a + (b * c * d)
+	_ = a + (b*c + d)
+
+	_ = 1 << x
+	_ = -1 << x
+	_ = 1<<x - 1
+	_ = -1<<x - 1
+
+	_ = f(a + b)
+	_ = f(a + b + c)
+	_ = f(a + b*c)
+	_ = f(a + (b * c))
+	_ = f(1<<x-1, 1<<x-2)
+
+	_ = 1<<d.logWindowSize - 1
+
+	buf = make(x, 2*cap(b.buf)+n)
+
+	dst[i*3+2] = dbuf[0] << 2
+	dst[i*3+2] = dbuf[0]<<2 | dbuf[1]>>4
+
+	b.buf = b.buf[0 : b.off+m+n]
+	b.buf = b.buf[0 : b.off+m*n]
+	f(b.buf[0 : b.off+m+n])
+
+	signed += ' ' * 8
+	tw.octal(header[148:155], chksum)
+
+	_ = x > 0 && i >= 0
+
+	x1, x0 := x>>w2, x&m2
+	z0 = t1<<w2 + t0
+	z1 = (t1 + t0>>w2) >> w2
+	q1, r1 := x1/d1, x1%d1
+	r1 = r1*b2 | x0>>w2
+	x1 = (x1 << z) | (x0 >> (uint(w) - z))
+	x1 = x1<<z | x0>>(uint(w)-z)
+
+	_ = buf[0 : len(buf)+1]
+	_ = buf[0 : n+1]
+
+	a, b = b, a
+	a = b + c
+	a = b*c + d
+	_ = a*b + c
+	_ = a - b - c
+	_ = a - (b - c)
+	_ = a - b*c
+	_ = a - (b * c)
+	_ = a * b / c
+	_ = a / *b
+	_ = x[a|^b]
+	_ = x[a / *b]
+	_ = a & ^b
+	_ = a + +b
+	_ = a - -b
+	_ = x[a*-b]
+	_ = x[a + +b]
+	_ = x ^ y ^ z
+	_ = b[a>>24] ^ b[(a>>16)&0xFF] ^ b[(a>>8)&0xFF] ^ b[a&0xFF]
+	_ = len(longVariableName) * 2
+
+	_ = token(matchType + xlength<<lengthShift + xoffset)
+}
+
+func f(x int, args ...int) {
+	f(0, args...)
+	f(1, args)
+	f(2, args[0])
+
+	// make sure syntactically legal code remains syntactically legal
+	f(3, 42 ...)	// a blank must remain between 42 and ...
+	f(4, 42....)
+	f(5, 42....)
+	f(6, 42.0...)
+	f(7, 42.0...)
+	f(8, .42...)
+	f(9, .42...)
+	f(10, 42e0...)
+	f(11, 42e0...)
+
+	_ = 42 .x	// a blank must remain between 42 and .x
+	_ = 42..x
+	_ = 42..x
+	_ = 42.0.x
+	_ = 42.0.x
+	_ = .42.x
+	_ = .42.x
+	_ = 42e0.x
+	_ = 42e0.x
+
+	// a blank must remain between the binary operator and the 2nd operand
+	_ = x / *y
+	_ = x < -1
+	_ = x < <-1
+	_ = x + +1
+	_ = x - -1
+	_ = x & &x
+	_ = x & ^x
+
+	_ = f(x / *y, x < -1, x < <-1, x + +1, x - -1, x & &x, x & ^x)
+}
+
+func _() {
+	_ = T{}
+	_ = struct{}{}
+	_ = [10]T{}
+	_ = [...]T{}
+	_ = []T{}
+	_ = map[int]T{}
+}
+
+// one-line structs/interfaces in composite literals (up to a threshold)
+func _() {
+	_ = struct{}{}
+	_ = struct{ x int }{0}
+	_ = struct{ x, y, z int }{0, 1, 2}
+	_ = struct{ int }{0}
+	_ = struct{ s struct{ int } }{struct{ int }{0}}
+}
+
+func _() {
+	// do not modify literals
+	_ = "tab1	tab2	tab3	end"	// string contains 3 tabs
+	_ = "tab1 tab2 tab3 end"	// same string with 3 blanks - may be unaligned because editors see tabs in strings
+	_ = ""				// this comment should be aligned with the one on the previous line
+	_ = ``
+	_ = `
+`
+	_ = `foo
+		bar`
+	_ = `three spaces before the end of the line starting here:   
+they must not be removed`
+}
+
+func _() {
+	// smart handling of indentation for multi-line raw strings
+	var _ = ``
+	var _ = `foo`
+	var _ = `foo
+bar`
+
+	var _ = ``
+	var _ = `foo`
+	var _ =
+	// the next line should remain indented
+	`foo
+bar`
+
+	var _ =	// comment
+	``
+	var _ =	// comment
+	`foo`
+	var _ =	// comment
+	// the next line should remain indented
+	`foo
+bar`
+
+	var _ = /* comment */ ``
+	var _ = /* comment */ `foo`
+	var _ = /* comment */ `foo
+bar`
+
+	var _ =	/* comment */
+	``
+	var _ =	/* comment */
+	`foo`
+	var _ =	/* comment */
+	// the next line should remain indented
+	`foo
+bar`
+
+	var board = []int(
+		`...........
+...........
+....●●●....
+....●●●....
+..●●●●●●●..
+..●●●○●●●..
+..●●●●●●●..
+....●●●....
+....●●●....
+...........
+...........
+`)
+
+	var state = S{
+		"foo",
+		// the next line should remain indented
+		`...........
+...........
+....●●●....
+....●●●....
+..●●●●●●●..
+..●●●○●●●..
+..●●●●●●●..
+....●●●....
+....●●●....
+...........
+...........
+`,
+		"bar",
+	}
+}
+
+func _() {
+	// one-line function literals (body is on a single line)
+	_ = func() {}
+	_ = func() int { return 0 }
+	_ = func(x, y int) bool { m := (x + y) / 2; return m < 0 }
+
+	// multi-line function literals (body is not on one line)
+	_ = func() {
+	}
+	_ = func() int {
+		return 0
+	}
+	_ = func(x, y int) bool {
+		m := (x + y) / 2
+		return x < y
+	}
+
+	f(func() {
+	})
+	f(func() int {
+		return 0
+	})
+	f(func(x, y int) bool {
+		m := (x + y) / 2
+		return x < y
+	})
+}
+
+func _() {
+	_ = [][]int{
+		[]int{1},
+		[]int{1, 2},
+		[]int{1, 2, 3},
+	}
+	_ = [][]int{
+		{1},
+		[]int{1, 2},
+		[]int{1, 2, 3},
+	}
+	_ = [][]int{
+		{1},
+		{1, 2},
+		{1, 2, 3},
+	}
+	_ = [][]int{{1}, {1, 2}, {1, 2, 3}}
+}
+
+// various multi-line expressions
+func _() {
+	// do not add extra indentation to multi-line string lists
+	_ = "foo" + "bar"
+	_ = "foo" +
+		"bar" +
+		"bah"
+	_ = []string{
+		"abc" +
+			"def",
+		"foo" +
+			"bar",
+	}
+}
+
+const _ = F1 +
+	`string = "%s";` +
+	`ptr = *;` +
+	`datafmt.T2 = s ["-" p "-"];`
+
+const _ = `datafmt "datafmt";` +
+	`default = "%v";` +
+	`array = *;` +
+	`datafmt.T3 = s  {" " a a / ","};`
+
+const _ = `datafmt "datafmt";` +
+	`default = "%v";` +
+	`array = *;` +
+	`datafmt.T3 = s  {" " a a / ","};`
+
+func _() {
+	_ = F1 +
+		`string = "%s";` +
+		`ptr = *;` +
+		`datafmt.T2 = s ["-" p "-"];`
+
+	_ =
+		`datafmt "datafmt";` +
+			`default = "%v";` +
+			`array = *;` +
+			`datafmt.T3 = s  {" " a a / ","};`
+
+	_ = `datafmt "datafmt";` +
+		`default = "%v";` +
+		`array = *;` +
+		`datafmt.T3 = s  {" " a a / ","};`
+}
+
+func _() {
+	// respect source lines in multi-line expressions
+	_ = a +
+		b +
+		c
+	_ = a < b ||
+		b < a
+	_ = "933262154439441526816992388562667004907159682643816214685929" +
+		"638952175999932299156089414639761565182862536979208272237582" +
+		"51185210916864000000000000000000000000"	// 100!
+	_ = "170141183460469231731687303715884105727"	// prime
+}
+
+// Alignment after overlong lines
+const (
+	_	= "991"
+	_	= "2432902008176640000"	// 20!
+	_	= "933262154439441526816992388562667004907159682643816214685929" +
+		"638952175999932299156089414639761565182862536979208272237582" +
+		"51185210916864000000000000000000000000"	// 100!
+	_	= "170141183460469231731687303715884105727"	// prime
+)
+
+// Correct placement of operators and comments in multi-line expressions
+func _() {
+	_ = a +	// comment
+		b +	// comment
+		c
+	_ = "a" +
+		"b" +	// comment
+		"c"
+	_ = "ba0408" + "7265717569726564"	// field 71, encoding 2, string "required"
+}
+
+// Correct placement of terminating comma/closing parentheses in multi-line calls.
+func _() {
+	f(1,
+		2,
+		3)
+	f(1,
+		2,
+		3,
+	)
+	f(1,
+		2,
+		3)	// comment
+	f(1,
+		2,
+		3,	// comment
+	)
+	f(1,
+		2,
+		3)	// comment
+	f(1,
+		2,
+		3,	// comment
+	)
+}
+
+// Align comments in multi-line lists of single-line expressions.
+var txpix = [NCOL]draw.Color{
+	draw.Yellow,		// yellow
+	draw.Cyan,		// cyan
+	draw.Green,		// lime green
+	draw.GreyBlue,		// slate
+	draw.Red,		/* red */
+	draw.GreyGreen,		/* olive green */
+	draw.Blue,		/* blue */
+	draw.Color(0xFF55AAFF),	/* pink */
+	draw.Color(0xFFAAFFFF),	/* lavender */
+	draw.Color(0xBB005DFF),	/* maroon */
+}
+
+func same(t, u *Time) bool {
+	// respect source lines in multi-line expressions
+	return t.Year == u.Year &&
+		t.Month == u.Month &&
+		t.Day == u.Day &&
+		t.Hour == u.Hour &&
+		t.Minute == u.Minute &&
+		t.Second == u.Second &&
+		t.Weekday == u.Weekday &&
+		t.ZoneOffset == u.ZoneOffset &&
+		t.Zone == u.Zone
+}
+
+func (p *parser) charClass() {
+	// respect source lines in multi-line expressions
+	if cc.negate && len(cc.ranges) == 2 &&
+		cc.ranges[0] == '\n' && cc.ranges[1] == '\n' {
+		nl := new(_NotNl)
+		p.re.add(nl)
+	}
+}
+
+func addState(s []state, inst instr, match []int) {
+	// handle comments correctly in multi-line expressions
+	for i := 0; i < l; i++ {
+		if s[i].inst.index() == index &&	// same instruction
+			s[i].match[0] < pos {	// earlier match already going; leftmost wins
+			return s
+		}
+	}
+}
+
+func (self *T) foo(x int) *T	{ return self }
+
+func _()	{ module.Func1().Func2() }
+
+func _() {
+	_ = new(T).
+		foo(1).
+		foo(2).
+		foo(3)
+
+	_ = new(T).
+		foo(1).
+		foo(2).	// inline comments
+		foo(3)
+
+	_ = new(T).foo(1).foo(2).foo(3)
+
+	// handle multiline argument list correctly
+	_ = new(T).
+		foo(
+		1).
+		foo(2)
+
+	_ = new(T).foo(
+		1).foo(2)
+
+	_ = Array[3+
+		4]
+
+	_ = Method(1, 2,
+		3)
+
+	_ = new(T).
+		foo().
+		bar().(*Type)
+
+	_ = new(T).
+		foo().
+		bar().(*Type).
+		baz()
+
+	_ = new(T).
+		foo().
+		bar()["idx"]
+
+	_ = new(T).
+		foo().
+		bar()["idx"].
+		baz()
+
+	_ = new(T).
+		foo().
+		bar()[1:2]
+
+	_ = new(T).
+		foo().
+		bar()[1:2].
+		baz()
+
+	_ = new(T).
+		Field.
+		Array[3+
+		4].
+		Table["foo"].
+		Blob.(*Type).
+		Slices[1:4].
+		Method(1, 2,
+		3).
+		Thingy
+
+	_ = a.b.c
+	_ = a.
+		b.
+		c
+	_ = a.b().c
+	_ = a.
+		b().
+		c
+	_ = a.b[0].c
+	_ = a.
+		b[0].
+		c
+	_ = a.b[0:].c
+	_ = a.
+		b[0:].
+		c
+	_ = a.b.(T).c
+	_ = a.
+		b.(T).
+		c
+}
+
+// Don't introduce extra newlines in strangely formatted expression lists.
+func f() {
+	// os.Open parameters should remain on two lines
+	if writer, err = os.Open(outfile, s.O_WRONLY|os.O_CREATE|
+		os.O_TRUNC, 0666); err != nil {
+		log.Fatal(err)
+	}
+}
+
+// Handle multi-line argument lists ending in ... correctly.
+// Was issue 3130.
+func _() {
+	_ = append(s, a...)
+	_ = append(
+		s, a...)
+	_ = append(s,
+		a...)
+	_ = append(
+		s,
+		a...)
+	_ = append(s, a...,
+	)
+	_ = append(s,
+		a...,
+	)
+	_ = append(
+		s,
+		a...,
+	)
+}
+
+// Literal function types in conversions must be parenthesized;
+// for now go/parser accepts the unparenthesized form where it
+// is non-ambiguous.
+func _() {
+	// these conversions should be rewritten to look
+	// the same as the parenthesized conversions below
+	_ = (func())(nil)
+	_ = (func(x int) float)(nil)
+	_ = (func() func() func())(nil)
+
+	_ = (func())(nil)
+	_ = (func(x int) float)(nil)
+	_ = (func() func() func())(nil)
+}
diff --git a/src/go/printer/testdata/expressions.input b/src/go/printer/testdata/expressions.input
new file mode 100644
index 0000000..d20a593
--- /dev/null
+++ b/src/go/printer/testdata/expressions.input
@@ -0,0 +1,715 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package expressions
+
+type T struct {
+	x, y, z int
+}
+
+var (
+	a, b, c, d, e int
+	under_bar int
+	longIdentifier1, longIdentifier2, longIdentifier3 int
+	t0, t1, t2 T
+	s string
+	p *int
+)
+
+
+func _() {
+	// no spaces around simple or parenthesized expressions
+	_ = (a+0)
+	_ = a+b
+	_ = a+b+c
+	_ = a+b-c
+	_ = a-b-c
+	_ = a+(b*c)
+	_ = a+(b/c)
+	_ = a-(b%c)
+	_ = 1+a
+	_ = a+1
+	_ = a+b+1
+	_ = s[a]
+	_ = s[a:]
+	_ = s[:b]
+	_ = s[1:2]
+	_ = s[a:b]
+	_ = s[0:len(s)]
+	_ = s[0]<<1
+	_ = (s[0]<<1)&0xf
+	_ = s[0] << 2 | s[1] >> 4
+	_ = "foo"+s
+	_ = s+"foo"
+	_ = 'a'+'b'
+	_ = len(s)/2
+	_ = len(t0.x)/a
+
+	// spaces around expressions of different precedence or expressions containing spaces
+	_ = a + -b
+	_ = a - ^b
+	_ = a / *p
+	_ = a + b*c
+	_ = 1 + b*c
+	_ = a + 2*c
+	_ = a + c*2
+	_ = 1 + 2*3
+	_ = s[1 : 2*3]
+	_ = s[a : b-c]
+	_ = s[0:]
+	_ = s[a+b]
+	_ = s[: b-c]
+	_ = s[a+b :]
+	_ = a[a<<b+1]
+	_ = a[a<<b+1 :]
+	_ = s[a+b : len(s)]
+	_ = s[len(s) : -a]
+	_ = s[a : len(s)+1]
+	_ = s[a : len(s)+1]+s
+
+	// spaces around operators with equal or lower precedence than comparisons
+	_ = a == b
+	_ = a != b
+	_ = a > b
+	_ = a >= b
+	_ = a < b
+	_ = a <= b
+	_ = a < b && c > d
+	_ = a < b || c > d
+
+	// spaces around "long" operands
+	_ = a + longIdentifier1
+	_ = longIdentifier1 + a
+	_ = longIdentifier1 + longIdentifier2 * longIdentifier3
+	_ = s + "a longer string"
+
+	// some selected cases
+	_ = a + t0.x
+	_ = a + t0.x + t1.x * t2.x
+	_ = a + b + c + d + e + 2*3
+	_ = a + b + c + 2*3 + d + e
+	_ = (a+b+c)*2
+	_ = a - b + c - d + (a+b+c) + d&e
+	_ = under_bar-1
+	_ = Open(dpath + "/file", O_WRONLY | O_CREAT, 0666)
+	_ = int(c0&_Mask4)<<18 | int(c1&_Maskx)<<12 | int(c2&_Maskx)<<6 | int(c3&_Maskx)
+
+	// test case for issue 8021
+	// want:
+	//  ([]bool{})[([]int{})[((1)+(((1)+((((1)*(((1)+(1))+(1)))+(1))*(1)))+(1)))]]
+	_ = ([]bool{})[([]int{})[((1) + (((((1) + (((((((1) * (((((1) + (1))) + (1))))) + (1))) * (1))))) + (1))))]]
+
+	// the parser does not restrict expressions that may appear as statements
+	true
+	42
+	"foo"
+	x
+	(x)
+	a+b
+	a+b+c
+	a+(b*c)
+	a+(b/c)
+	1+a
+	a+1
+	s[a]
+	x<<1
+	(s[0]<<1)&0xf
+	"foo"+s
+	x == y
+	x < y || z > 42
+}
+
+
+// slice expressions with cap
+func _() {
+	_ = x[a:b:c]
+	_ = x[a:b:c+d]
+	_ = x[a:b+d:c]
+	_ = x[a:b+d:c+d]
+	_ = x[a+d:b:c]
+	_ = x[a+d:b:c+d]
+	_ = x[a+d:b+d:c]
+	_ = x[a+d:b+d:c+d]
+
+	_ = x[:b:c]
+	_ = x[:b:c+d]
+	_ = x[:b+d:c]
+	_ = x[:b+d:c+d]
+}
+
+func _() {
+	_ = a+b
+	_ = a+b+c
+	_ = a+b*c
+	_ = a+(b*c)
+	_ = (a+b)*c
+	_ = a+(b*c*d)
+	_ = a+(b*c+d)
+
+	_ = 1<<x
+	_ = -1<<x
+	_ = 1<<x-1
+	_ = -1<<x-1
+
+	_ = f(a+b)
+	_ = f(a+b+c)
+	_ = f(a+b*c)
+	_ = f(a+(b*c))
+	_ = f(1<<x-1, 1<<x-2)
+
+	_ = 1<<d.logWindowSize-1
+
+	buf = make(x, 2*cap(b.buf) + n)
+
+	dst[i*3+2] = dbuf[0]<<2
+	dst[i*3+2] = dbuf[0]<<2 | dbuf[1]>>4
+
+	b.buf = b.buf[0:b.off+m+n]
+	b.buf = b.buf[0:b.off+m*n]
+	f(b.buf[0:b.off+m+n])
+
+	signed += ' '*8
+	tw.octal(header[148:155], chksum)
+
+	_ = x > 0 && i >= 0
+
+	x1, x0 := x>>w2, x&m2
+	z0 = t1<<w2+t0
+	z1 = (t1+t0>>w2)>>w2
+	q1, r1 := x1/d1, x1%d1
+	r1 = r1*b2 | x0>>w2
+	x1 = (x1<<z)|(x0>>(uint(w)-z))
+	x1 = x1<<z | x0>>(uint(w)-z)
+
+	_ = buf[0:len(buf)+1]
+	_ = buf[0:n+1]
+
+	a,b = b,a
+	a = b+c
+	a = b*c+d
+	_ = a*b+c
+	_ = a-b-c
+	_ = a-(b-c)
+	_ = a-b*c
+	_ = a-(b*c)
+	_ = a*b/c
+	_ = a/ *b
+	_ = x[a|^b]
+	_ = x[a/ *b]
+	_ = a& ^b
+	_ = a+ +b
+	_ = a- -b
+	_ = x[a*-b]
+	_ = x[a+ +b]
+	_ = x^y^z
+	_ = b[a>>24] ^ b[(a>>16)&0xFF] ^ b[(a>>8)&0xFF] ^ b[a&0xFF]
+	_ = len(longVariableName)*2
+
+	_ = token(matchType + xlength<<lengthShift + xoffset)
+}
+
+
+func f(x int, args ...int) {
+	f(0, args...)
+	f(1, args)
+	f(2, args[0])
+
+	// make sure syntactically legal code remains syntactically legal
+	f(3, 42 ...) // a blank must remain between 42 and ...
+	f(4, 42. ...)
+	f(5, 42....)
+	f(6, 42.0 ...)
+	f(7, 42.0...)
+	f(8, .42 ...)
+	f(9, .42...)
+	f(10, 42e0 ...)
+	f(11, 42e0...)
+
+	_ = 42 .x // a blank must remain between 42 and .x
+	_ = 42. .x
+	_ = 42..x
+	_ = 42.0 .x
+	_ = 42.0.x
+	_ = .42 .x
+	_ = .42.x
+	_ = 42e0 .x
+	_ = 42e0.x
+
+	// a blank must remain between the binary operator and the 2nd operand
+	_ = x/ *y
+	_ = x< -1
+	_ = x< <-1
+	_ = x+ +1
+	_ = x- -1
+	_ = x& &x
+	_ = x& ^x
+
+	_ = f(x/ *y, x< -1, x< <-1, x+ +1, x- -1, x& &x, x& ^x)
+}
+
+
+func _() {
+	_ = T{}
+	_ = struct{}{}
+	_ = [10]T{}
+	_ = [...]T{}
+	_ = []T{}
+	_ = map[int]T{}
+}
+
+
+// one-line structs/interfaces in composite literals (up to a threshold)
+func _() {
+	_ = struct{}{}
+	_ = struct{ x int }{0}
+	_ = struct{ x, y, z int }{0, 1, 2}
+	_ = struct{ int }{0}
+	_ = struct{ s struct { int } }{struct{ int}{0} }
+}
+
+
+func _() {
+	// do not modify literals
+	_ = "tab1	tab2	tab3	end"  // string contains 3 tabs
+	_ = "tab1 tab2 tab3 end"  // same string with 3 blanks - may be unaligned because editors see tabs in strings
+	_ = ""  // this comment should be aligned with the one on the previous line
+	_ = ``
+	_ = `
+`
+_ = `foo
+		bar`
+	_ = `three spaces before the end of the line starting here:   
+they must not be removed`
+}
+
+
+func _() {
+	// smart handling of indentation for multi-line raw strings
+	var _ = ``
+	var _ = `foo`
+	var _ = `foo
+bar`
+
+
+var _ =
+	``
+var _ =
+	`foo`
+var _ =
+	// the next line should remain indented
+	`foo
+bar`
+
+
+	var _ = // comment
+		``
+	var _ = // comment
+		`foo`
+	var _ = // comment
+		// the next line should remain indented
+		`foo
+bar`
+
+
+var _ = /* comment */ ``
+var _ = /* comment */ `foo`
+var _ = /* comment */ `foo
+bar`
+
+
+	var _ = /* comment */
+		``
+	var _ = /* comment */
+		`foo`
+	var _ = /* comment */
+		// the next line should remain indented
+		`foo
+bar`
+
+
+var board = []int(
+	`...........
+...........
+....●●●....
+....●●●....
+..●●●●●●●..
+..●●●○●●●..
+..●●●●●●●..
+....●●●....
+....●●●....
+...........
+...........
+`)
+
+
+	var state = S{
+		"foo",
+		// the next line should remain indented
+		`...........
+...........
+....●●●....
+....●●●....
+..●●●●●●●..
+..●●●○●●●..
+..●●●●●●●..
+....●●●....
+....●●●....
+...........
+...........
+`,
+		"bar",
+	}
+}
+
+
+func _() {
+	// one-line function literals (body is on a single line)
+	_ = func() {}
+	_ = func() int { return 0 }
+	_ = func(x, y int) bool { m := (x+y)/2; return m < 0 }
+
+	// multi-line function literals (body is not on one line)
+	_ = func() {
+	}
+	_ = func() int {
+		return 0
+	}
+	_ = func(x, y int) bool {
+		m := (x+y)/2; return x < y }
+
+	f(func() {
+	})
+	f(func() int {
+		return 0
+	})
+	f(func(x, y int) bool {
+		m := (x+y)/2; return x < y })
+}
+
+
+func _() {
+	_ = [][]int {
+		[]int{1},
+		[]int{1, 2},
+		[]int{1, 2, 3},
+	}
+	_ = [][]int {
+		{1},
+		[]int{1, 2},
+		[]int{1, 2, 3},
+	}
+	_ = [][]int {
+		{1},
+		{1, 2},
+		{1, 2, 3},
+	}
+	_ = [][]int {{1}, {1, 2}, {1, 2, 3}}
+}
+
+
+// various multi-line expressions
+func _() {
+	// do not add extra indentation to multi-line string lists
+	_ = "foo" + "bar"
+	_ = "foo" +
+	"bar" +
+	"bah"
+	_ = []string {
+		"abc" +
+		"def",
+		"foo" +
+		"bar",
+	}
+}
+
+
+const _ = F1 +
+	`string = "%s";` +
+	`ptr = *;` +
+	`datafmt.T2 = s ["-" p "-"];`
+
+
+const _ =
+	`datafmt "datafmt";` +
+	`default = "%v";` +
+	`array = *;` +
+	`datafmt.T3 = s  {" " a a / ","};`
+
+
+const _ = `datafmt "datafmt";` +
+`default = "%v";` +
+`array = *;` +
+`datafmt.T3 = s  {" " a a / ","};`
+
+
+func _() {
+	_ = F1 +
+		`string = "%s";` +
+		`ptr = *;` +
+		`datafmt.T2 = s ["-" p "-"];`
+
+	_ =
+		`datafmt "datafmt";` +
+		`default = "%v";` +
+		`array = *;` +
+		`datafmt.T3 = s  {" " a a / ","};`
+
+	_ = `datafmt "datafmt";` +
+	`default = "%v";` +
+	`array = *;` +
+	`datafmt.T3 = s  {" " a a / ","};`
+}
+
+
+func _() {
+	// respect source lines in multi-line expressions
+	_ = a+
+	b+
+	c
+	_ = a < b ||
+		b < a
+	_ = "933262154439441526816992388562667004907159682643816214685929" +
+	"638952175999932299156089414639761565182862536979208272237582" +
+	"51185210916864000000000000000000000000"  // 100!
+	_ = "170141183460469231731687303715884105727"  // prime
+}
+
+
+// Alignment after overlong lines
+const (
+	_ = "991"
+	_ = "2432902008176640000"  // 20!
+	_ = "933262154439441526816992388562667004907159682643816214685929" +
+	"638952175999932299156089414639761565182862536979208272237582" +
+	"51185210916864000000000000000000000000"  // 100!
+	_ = "170141183460469231731687303715884105727"  // prime
+)
+
+
+// Correct placement of operators and comments in multi-line expressions
+func _() {
+	_ = a +  // comment
+		b +  // comment
+		c
+	_ = "a"	+
+		"b" +	// comment
+		"c"
+	_ = "ba0408" + "7265717569726564"     // field 71, encoding 2, string "required"
+}
+
+
+// Correct placement of terminating comma/closing parentheses in multi-line calls.
+func _() {
+	f(1,
+		2,
+		3)
+	f(1,
+		2,
+		3,
+	)
+	f(1,
+		2,
+		3)  // comment
+	f(1,
+		2,
+		3,  // comment
+	)
+	f(1,
+		2,
+		3)// comment
+	f(1,
+		2,
+		3,// comment
+	)
+}
+
+
+// Align comments in multi-line lists of single-line expressions.
+var txpix = [NCOL]draw.Color{
+	draw.Yellow, // yellow
+	draw.Cyan, // cyan
+	draw.Green, // lime green
+	draw.GreyBlue, // slate
+	draw.Red, /* red */
+	draw.GreyGreen, /* olive green */
+	draw.Blue, /* blue */
+	draw.Color(0xFF55AAFF), /* pink */
+	draw.Color(0xFFAAFFFF), /* lavender */
+	draw.Color(0xBB005DFF), /* maroon */
+}
+
+
+func same(t, u *Time) bool {
+	// respect source lines in multi-line expressions
+	return t.Year == u.Year &&
+		t.Month == u.Month &&
+		t.Day == u.Day &&
+		t.Hour == u.Hour &&
+		t.Minute == u.Minute &&
+		t.Second == u.Second &&
+		t.Weekday == u.Weekday &&
+		t.ZoneOffset == u.ZoneOffset &&
+		t.Zone == u.Zone
+}
+
+
+func (p *parser) charClass() {
+	// respect source lines in multi-line expressions
+	if cc.negate && len(cc.ranges) == 2 &&
+		cc.ranges[0] == '\n' && cc.ranges[1] == '\n' {
+		nl := new(_NotNl)
+		p.re.add(nl)
+	}
+}
+
+
+func addState(s []state, inst instr, match []int) {
+	// handle comments correctly in multi-line expressions
+	for i := 0; i < l; i++ {
+		if s[i].inst.index() == index && // same instruction
+		   s[i].match[0] < pos {	// earlier match already going; leftmost wins
+		   	return s
+		 }
+	}
+}
+
+func (self *T) foo(x int) *T { return self }
+
+func _() { module.Func1().Func2() }
+
+func _() {
+	_ = new(T).
+		foo(1).
+			foo(2).
+		foo(3)
+
+	_ = new(T).
+	foo(1).
+	foo(2). // inline comments
+	foo(3)
+
+	_ = new(T).foo(1).foo(2).foo(3)
+
+	// handle multiline argument list correctly
+	_ = new(T).
+	foo(
+		1).
+		foo(2)
+
+	_ = new(T).foo(
+		1).foo(2)
+
+	_ = Array[3 +
+4]
+
+	_ = Method(1, 2,
+		3)
+
+	_ = new(T).
+   foo().
+   bar() . (*Type)
+
+	_ = new(T).
+foo().
+bar().(*Type).
+baz()
+
+	_ = new(T).
+	foo().
+	bar()["idx"]
+
+	_ = new(T).
+	foo().
+	bar()["idx"]	.
+	baz()
+
+	_ = new(T).
+	foo().
+	bar()[1:2]
+
+	_ = new(T).
+	foo().
+	bar()[1:2].
+	baz()
+
+	_ = new(T).
+		Field.
+		Array[3+
+       		4].
+		Table ["foo"].
+		Blob. (*Type).
+	Slices[1:4].
+	Method(1, 2,
+	3).
+		Thingy
+
+	_ = a.b.c
+	_ = a.
+	b.
+	c
+	_ = a.b().c
+	_ = a.
+	b().
+	c
+	_ = a.b[0].c
+	_ = a.
+	b[0].
+	c
+	_ = a.b[0:].c
+	_ = a.
+	b[0:].
+	c
+	_ = a.b.(T).c
+	_ = a.
+	b.
+	(T).
+	c
+}
+
+
+// Don't introduce extra newlines in strangely formatted expression lists.
+func f() {
+	// os.Open parameters should remain on two lines
+	if writer, err = os.Open(outfile, s.O_WRONLY|os.O_CREATE|
+		os.O_TRUNC, 0666); err != nil {
+	    log.Fatal(err)
+	}
+}
+
+// Handle multi-line argument lists ending in ... correctly.
+// Was issue 3130.
+func _() {
+	_ = append(s, a...)
+	_ = append(
+		s, a...)
+	_ = append(s,
+		a...)
+	_ = append(
+		s,
+		a...)
+	_ = append(s, a...,
+	)
+	_ = append(s,
+		a...,
+	)
+	_ = append(
+		s,
+		a...,
+	)
+}
+
+// Literal function types in conversions must be parenthesized;
+// for now go/parser accepts the unparenthesized form where it
+// is non-ambiguous.
+func _() {
+	// these conversions should be rewritten to look
+	// the same as the parenthesized conversions below
+	_ = func()()(nil)
+	_ = func(x int)(float)(nil)
+	_ = func() func() func()()(nil)
+
+	_ = (func()())(nil)
+	_ = (func(x int)(float))(nil)
+	_ = (func() func() func()())(nil)
+}
diff --git a/src/go/printer/testdata/expressions.raw b/src/go/printer/testdata/expressions.raw
new file mode 100644
index 0000000..2357336
--- /dev/null
+++ b/src/go/printer/testdata/expressions.raw
@@ -0,0 +1,686 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package expressions
+
+type T struct {
+	x, y, z int
+}
+
+var (
+	a, b, c, d, e	int
+	under_bar	int
+	longIdentifier1, longIdentifier2, longIdentifier3	int
+	t0, t1, t2	T
+	s	string
+	p	*int
+)
+
+func _() {
+	// no spaces around simple or parenthesized expressions
+	_ = (a + 0)
+	_ = a + b
+	_ = a + b + c
+	_ = a + b - c
+	_ = a - b - c
+	_ = a + (b * c)
+	_ = a + (b / c)
+	_ = a - (b % c)
+	_ = 1 + a
+	_ = a + 1
+	_ = a + b + 1
+	_ = s[a]
+	_ = s[a:]
+	_ = s[:b]
+	_ = s[1:2]
+	_ = s[a:b]
+	_ = s[0:len(s)]
+	_ = s[0] << 1
+	_ = (s[0] << 1) & 0xf
+	_ = s[0]<<2 | s[1]>>4
+	_ = "foo" + s
+	_ = s + "foo"
+	_ = 'a' + 'b'
+	_ = len(s) / 2
+	_ = len(t0.x) / a
+
+	// spaces around expressions of different precedence or expressions containing spaces
+	_ = a + -b
+	_ = a - ^b
+	_ = a / *p
+	_ = a + b*c
+	_ = 1 + b*c
+	_ = a + 2*c
+	_ = a + c*2
+	_ = 1 + 2*3
+	_ = s[1 : 2*3]
+	_ = s[a : b-c]
+	_ = s[0:]
+	_ = s[a+b]
+	_ = s[:b-c]
+	_ = s[a+b:]
+	_ = a[a<<b+1]
+	_ = a[a<<b+1:]
+	_ = s[a+b : len(s)]
+	_ = s[len(s):-a]
+	_ = s[a : len(s)+1]
+	_ = s[a:len(s)+1] + s
+
+	// spaces around operators with equal or lower precedence than comparisons
+	_ = a == b
+	_ = a != b
+	_ = a > b
+	_ = a >= b
+	_ = a < b
+	_ = a <= b
+	_ = a < b && c > d
+	_ = a < b || c > d
+
+	// spaces around "long" operands
+	_ = a + longIdentifier1
+	_ = longIdentifier1 + a
+	_ = longIdentifier1 + longIdentifier2*longIdentifier3
+	_ = s + "a longer string"
+
+	// some selected cases
+	_ = a + t0.x
+	_ = a + t0.x + t1.x*t2.x
+	_ = a + b + c + d + e + 2*3
+	_ = a + b + c + 2*3 + d + e
+	_ = (a + b + c) * 2
+	_ = a - b + c - d + (a + b + c) + d&e
+	_ = under_bar - 1
+	_ = Open(dpath+"/file", O_WRONLY|O_CREAT, 0666)
+	_ = int(c0&_Mask4)<<18 | int(c1&_Maskx)<<12 | int(c2&_Maskx)<<6 | int(c3&_Maskx)
+
+	// test case for issue 8021
+	// want:
+	//  ([]bool{})[([]int{})[((1)+(((1)+((((1)*(((1)+(1))+(1)))+(1))*(1)))+(1)))]]
+	_ = ([]bool{})[([]int{})[((1)+(((1)+((((1)*(((1)+(1))+(1)))+(1))*(1)))+(1)))]]
+
+	// the parser does not restrict expressions that may appear as statements
+	true
+	42
+	"foo"
+	x
+	(x)
+	a + b
+	a + b + c
+	a + (b * c)
+	a + (b / c)
+	1 + a
+	a + 1
+	s[a]
+	x << 1
+	(s[0] << 1) & 0xf
+	"foo" + s
+	x == y
+	x < y || z > 42
+}
+
+// slice expressions with cap
+func _() {
+	_ = x[a:b:c]
+	_ = x[a:b : c+d]
+	_ = x[a : b+d : c]
+	_ = x[a : b+d : c+d]
+	_ = x[a+d : b:c]
+	_ = x[a+d : b : c+d]
+	_ = x[a+d : b+d : c]
+	_ = x[a+d : b+d : c+d]
+
+	_ = x[:b:c]
+	_ = x[:b : c+d]
+	_ = x[:b+d : c]
+	_ = x[:b+d : c+d]
+}
+
+func _() {
+	_ = a + b
+	_ = a + b + c
+	_ = a + b*c
+	_ = a + (b * c)
+	_ = (a + b) * c
+	_ = a + (b * c * d)
+	_ = a + (b*c + d)
+
+	_ = 1 << x
+	_ = -1 << x
+	_ = 1<<x - 1
+	_ = -1<<x - 1
+
+	_ = f(a + b)
+	_ = f(a + b + c)
+	_ = f(a + b*c)
+	_ = f(a + (b * c))
+	_ = f(1<<x-1, 1<<x-2)
+
+	_ = 1<<d.logWindowSize - 1
+
+	buf = make(x, 2*cap(b.buf)+n)
+
+	dst[i*3+2] = dbuf[0] << 2
+	dst[i*3+2] = dbuf[0]<<2 | dbuf[1]>>4
+
+	b.buf = b.buf[0 : b.off+m+n]
+	b.buf = b.buf[0 : b.off+m*n]
+	f(b.buf[0 : b.off+m+n])
+
+	signed += ' ' * 8
+	tw.octal(header[148:155], chksum)
+
+	_ = x > 0 && i >= 0
+
+	x1, x0 := x>>w2, x&m2
+	z0 = t1<<w2 + t0
+	z1 = (t1 + t0>>w2) >> w2
+	q1, r1 := x1/d1, x1%d1
+	r1 = r1*b2 | x0>>w2
+	x1 = (x1 << z) | (x0 >> (uint(w) - z))
+	x1 = x1<<z | x0>>(uint(w)-z)
+
+	_ = buf[0 : len(buf)+1]
+	_ = buf[0 : n+1]
+
+	a, b = b, a
+	a = b + c
+	a = b*c + d
+	_ = a*b + c
+	_ = a - b - c
+	_ = a - (b - c)
+	_ = a - b*c
+	_ = a - (b * c)
+	_ = a * b / c
+	_ = a / *b
+	_ = x[a|^b]
+	_ = x[a / *b]
+	_ = a & ^b
+	_ = a + +b
+	_ = a - -b
+	_ = x[a*-b]
+	_ = x[a + +b]
+	_ = x ^ y ^ z
+	_ = b[a>>24] ^ b[(a>>16)&0xFF] ^ b[(a>>8)&0xFF] ^ b[a&0xFF]
+	_ = len(longVariableName) * 2
+
+	_ = token(matchType + xlength<<lengthShift + xoffset)
+}
+
+func f(x int, args ...int) {
+	f(0, args...)
+	f(1, args)
+	f(2, args[0])
+
+	// make sure syntactically legal code remains syntactically legal
+	f(3, 42 ...)	// a blank must remain between 42 and ...
+	f(4, 42....)
+	f(5, 42....)
+	f(6, 42.0...)
+	f(7, 42.0...)
+	f(8, .42...)
+	f(9, .42...)
+	f(10, 42e0...)
+	f(11, 42e0...)
+
+	_ = 42 .x	// a blank must remain between 42 and .x
+	_ = 42..x
+	_ = 42..x
+	_ = 42.0.x
+	_ = 42.0.x
+	_ = .42.x
+	_ = .42.x
+	_ = 42e0.x
+	_ = 42e0.x
+
+	// a blank must remain between the binary operator and the 2nd operand
+	_ = x / *y
+	_ = x < -1
+	_ = x < <-1
+	_ = x + +1
+	_ = x - -1
+	_ = x & &x
+	_ = x & ^x
+
+	_ = f(x / *y, x < -1, x < <-1, x + +1, x - -1, x & &x, x & ^x)
+}
+
+func _() {
+	_ = T{}
+	_ = struct{}{}
+	_ = [10]T{}
+	_ = [...]T{}
+	_ = []T{}
+	_ = map[int]T{}
+}
+
+// one-line structs/interfaces in composite literals (up to a threshold)
+func _() {
+	_ = struct{}{}
+	_ = struct{ x int }{0}
+	_ = struct{ x, y, z int }{0, 1, 2}
+	_ = struct{ int }{0}
+	_ = struct{ s struct{ int } }{struct{ int }{0}}
+}
+
+func _() {
+	// do not modify literals
+	_ = "tab1	tab2	tab3	end"	// string contains 3 tabs
+	_ = "tab1 tab2 tab3 end"	// same string with 3 blanks - may be unaligned because editors see tabs in strings
+	_ = ""	// this comment should be aligned with the one on the previous line
+	_ = ``
+	_ = `
+`
+	_ = `foo
+		bar`
+	_ = `three spaces before the end of the line starting here:   
+they must not be removed`
+}
+
+func _() {
+	// smart handling of indentation for multi-line raw strings
+	var _ = ``
+	var _ = `foo`
+	var _ = `foo
+bar`
+
+	var _ = ``
+	var _ = `foo`
+	var _ =
+	// the next line should remain indented
+	`foo
+bar`
+
+	var _ =	// comment
+	``
+	var _ =	// comment
+	`foo`
+	var _ =	// comment
+	// the next line should remain indented
+	`foo
+bar`
+
+	var _ = /* comment */ ``
+	var _ = /* comment */ `foo`
+	var _ = /* comment */ `foo
+bar`
+
+	var _ =	/* comment */
+	``
+	var _ =	/* comment */
+	`foo`
+	var _ =	/* comment */
+	// the next line should remain indented
+	`foo
+bar`
+
+	var board = []int(
+		`...........
+...........
+....●●●....
+....●●●....
+..●●●●●●●..
+..●●●○●●●..
+..●●●●●●●..
+....●●●....
+....●●●....
+...........
+...........
+`)
+
+	var state = S{
+		"foo",
+		// the next line should remain indented
+		`...........
+...........
+....●●●....
+....●●●....
+..●●●●●●●..
+..●●●○●●●..
+..●●●●●●●..
+....●●●....
+....●●●....
+...........
+...........
+`,
+		"bar",
+	}
+}
+
+func _() {
+	// one-line function literals (body is on a single line)
+	_ = func() {}
+	_ = func() int { return 0 }
+	_ = func(x, y int) bool { m := (x + y) / 2; return m < 0 }
+
+	// multi-line function literals (body is not on one line)
+	_ = func() {
+	}
+	_ = func() int {
+		return 0
+	}
+	_ = func(x, y int) bool {
+		m := (x + y) / 2
+		return x < y
+	}
+
+	f(func() {
+	})
+	f(func() int {
+		return 0
+	})
+	f(func(x, y int) bool {
+		m := (x + y) / 2
+		return x < y
+	})
+}
+
+func _() {
+	_ = [][]int{
+		[]int{1},
+		[]int{1, 2},
+		[]int{1, 2, 3},
+	}
+	_ = [][]int{
+		{1},
+		[]int{1, 2},
+		[]int{1, 2, 3},
+	}
+	_ = [][]int{
+		{1},
+		{1, 2},
+		{1, 2, 3},
+	}
+	_ = [][]int{{1}, {1, 2}, {1, 2, 3}}
+}
+
+// various multi-line expressions
+func _() {
+	// do not add extra indentation to multi-line string lists
+	_ = "foo" + "bar"
+	_ = "foo" +
+		"bar" +
+		"bah"
+	_ = []string{
+		"abc" +
+			"def",
+		"foo" +
+			"bar",
+	}
+}
+
+const _ = F1 +
+	`string = "%s";` +
+	`ptr = *;` +
+	`datafmt.T2 = s ["-" p "-"];`
+
+const _ = `datafmt "datafmt";` +
+	`default = "%v";` +
+	`array = *;` +
+	`datafmt.T3 = s  {" " a a / ","};`
+
+const _ = `datafmt "datafmt";` +
+	`default = "%v";` +
+	`array = *;` +
+	`datafmt.T3 = s  {" " a a / ","};`
+
+func _() {
+	_ = F1 +
+		`string = "%s";` +
+		`ptr = *;` +
+		`datafmt.T2 = s ["-" p "-"];`
+
+	_ =
+		`datafmt "datafmt";` +
+			`default = "%v";` +
+			`array = *;` +
+			`datafmt.T3 = s  {" " a a / ","};`
+
+	_ = `datafmt "datafmt";` +
+		`default = "%v";` +
+		`array = *;` +
+		`datafmt.T3 = s  {" " a a / ","};`
+}
+
+func _() {
+	// respect source lines in multi-line expressions
+	_ = a +
+		b +
+		c
+	_ = a < b ||
+		b < a
+	_ = "933262154439441526816992388562667004907159682643816214685929" +
+		"638952175999932299156089414639761565182862536979208272237582" +
+		"51185210916864000000000000000000000000"	// 100!
+	_ = "170141183460469231731687303715884105727"	// prime
+}
+
+// Alignment after overlong lines
+const (
+	_	= "991"
+	_	= "2432902008176640000"		// 20!
+	_	= "933262154439441526816992388562667004907159682643816214685929" +
+		"638952175999932299156089414639761565182862536979208272237582" +
+		"51185210916864000000000000000000000000"	// 100!
+	_	= "170141183460469231731687303715884105727"		// prime
+)
+
+// Correct placement of operators and comments in multi-line expressions
+func _() {
+	_ = a +	// comment
+		b +	// comment
+		c
+	_ = "a" +
+		"b" +	// comment
+		"c"
+	_ = "ba0408" + "7265717569726564"	// field 71, encoding 2, string "required"
+}
+
+// Correct placement of terminating comma/closing parentheses in multi-line calls.
+func _() {
+	f(1,
+		2,
+		3)
+	f(1,
+		2,
+		3,
+	)
+	f(1,
+		2,
+		3)	// comment
+	f(1,
+		2,
+		3,	// comment
+	)
+	f(1,
+		2,
+		3)	// comment
+	f(1,
+		2,
+		3,	// comment
+	)
+}
+
+// Align comments in multi-line lists of single-line expressions.
+var txpix = [NCOL]draw.Color{
+	draw.Yellow,	// yellow
+	draw.Cyan,	// cyan
+	draw.Green,	// lime green
+	draw.GreyBlue,	// slate
+	draw.Red,	/* red */
+	draw.GreyGreen,	/* olive green */
+	draw.Blue,	/* blue */
+	draw.Color(0xFF55AAFF),	/* pink */
+	draw.Color(0xFFAAFFFF),	/* lavender */
+	draw.Color(0xBB005DFF),	/* maroon */
+}
+
+func same(t, u *Time) bool {
+	// respect source lines in multi-line expressions
+	return t.Year == u.Year &&
+		t.Month == u.Month &&
+		t.Day == u.Day &&
+		t.Hour == u.Hour &&
+		t.Minute == u.Minute &&
+		t.Second == u.Second &&
+		t.Weekday == u.Weekday &&
+		t.ZoneOffset == u.ZoneOffset &&
+		t.Zone == u.Zone
+}
+
+func (p *parser) charClass() {
+	// respect source lines in multi-line expressions
+	if cc.negate && len(cc.ranges) == 2 &&
+		cc.ranges[0] == '\n' && cc.ranges[1] == '\n' {
+		nl := new(_NotNl)
+		p.re.add(nl)
+	}
+}
+
+func addState(s []state, inst instr, match []int) {
+	// handle comments correctly in multi-line expressions
+	for i := 0; i < l; i++ {
+		if s[i].inst.index() == index &&	// same instruction
+			s[i].match[0] < pos {	// earlier match already going; leftmost wins
+			return s
+		}
+	}
+}
+
+func (self *T) foo(x int) *T	{ return self }
+
+func _()	{ module.Func1().Func2() }
+
+func _() {
+	_ = new(T).
+		foo(1).
+		foo(2).
+		foo(3)
+
+	_ = new(T).
+		foo(1).
+		foo(2).	// inline comments
+		foo(3)
+
+	_ = new(T).foo(1).foo(2).foo(3)
+
+	// handle multiline argument list correctly
+	_ = new(T).
+		foo(
+		1).
+		foo(2)
+
+	_ = new(T).foo(
+		1).foo(2)
+
+	_ = Array[3+
+		4]
+
+	_ = Method(1, 2,
+		3)
+
+	_ = new(T).
+		foo().
+		bar().(*Type)
+
+	_ = new(T).
+		foo().
+		bar().(*Type).
+		baz()
+
+	_ = new(T).
+		foo().
+		bar()["idx"]
+
+	_ = new(T).
+		foo().
+		bar()["idx"].
+		baz()
+
+	_ = new(T).
+		foo().
+		bar()[1:2]
+
+	_ = new(T).
+		foo().
+		bar()[1:2].
+		baz()
+
+	_ = new(T).
+		Field.
+		Array[3+
+		4].
+		Table["foo"].
+		Blob.(*Type).
+		Slices[1:4].
+		Method(1, 2,
+		3).
+		Thingy
+
+	_ = a.b.c
+	_ = a.
+		b.
+		c
+	_ = a.b().c
+	_ = a.
+		b().
+		c
+	_ = a.b[0].c
+	_ = a.
+		b[0].
+		c
+	_ = a.b[0:].c
+	_ = a.
+		b[0:].
+		c
+	_ = a.b.(T).c
+	_ = a.
+		b.(T).
+		c
+}
+
+// Don't introduce extra newlines in strangely formatted expression lists.
+func f() {
+	// os.Open parameters should remain on two lines
+	if writer, err = os.Open(outfile, s.O_WRONLY|os.O_CREATE|
+		os.O_TRUNC, 0666); err != nil {
+		log.Fatal(err)
+	}
+}
+
+// Handle multi-line argument lists ending in ... correctly.
+// Was issue 3130.
+func _() {
+	_ = append(s, a...)
+	_ = append(
+		s, a...)
+	_ = append(s,
+		a...)
+	_ = append(
+		s,
+		a...)
+	_ = append(s, a...,
+	)
+	_ = append(s,
+		a...,
+	)
+	_ = append(
+		s,
+		a...,
+	)
+}
+
+// Literal function types in conversions must be parenthesized;
+// for now go/parser accepts the unparenthesized form where it
+// is non-ambiguous.
+func _() {
+	// these conversions should be rewritten to look
+	// the same as the parenthesized conversions below
+	_ = (func())(nil)
+	_ = (func(x int) float)(nil)
+	_ = (func() func() func())(nil)
+
+	_ = (func())(nil)
+	_ = (func(x int) float)(nil)
+	_ = (func() func() func())(nil)
+}
diff --git a/src/pkg/go/printer/testdata/linebreaks.golden b/src/go/printer/testdata/linebreaks.golden
similarity index 100%
rename from src/pkg/go/printer/testdata/linebreaks.golden
rename to src/go/printer/testdata/linebreaks.golden
diff --git a/src/pkg/go/printer/testdata/linebreaks.input b/src/go/printer/testdata/linebreaks.input
similarity index 100%
rename from src/pkg/go/printer/testdata/linebreaks.input
rename to src/go/printer/testdata/linebreaks.input
diff --git a/src/pkg/go/printer/testdata/parser.go b/src/go/printer/testdata/parser.go
similarity index 100%
rename from src/pkg/go/printer/testdata/parser.go
rename to src/go/printer/testdata/parser.go
diff --git a/src/pkg/go/printer/testdata/slow.golden b/src/go/printer/testdata/slow.golden
similarity index 100%
rename from src/pkg/go/printer/testdata/slow.golden
rename to src/go/printer/testdata/slow.golden
diff --git a/src/pkg/go/printer/testdata/slow.input b/src/go/printer/testdata/slow.input
similarity index 100%
rename from src/pkg/go/printer/testdata/slow.input
rename to src/go/printer/testdata/slow.input
diff --git a/src/go/printer/testdata/statements.golden b/src/go/printer/testdata/statements.golden
new file mode 100644
index 0000000..4b13460
--- /dev/null
+++ b/src/go/printer/testdata/statements.golden
@@ -0,0 +1,644 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package statements
+
+var expr bool
+
+func use(x interface{})	{}
+
+// Formatting of multi-line return statements.
+func _f() {
+	return
+	return x, y, z
+	return T{}
+	return T{1, 2, 3},
+		x, y, z
+	return T{1, 2, 3},
+		x, y,
+		z
+	return T{1,
+		2,
+		3}
+	return T{1,
+		2,
+		3,
+	}
+	return T{
+		1,
+		2,
+		3}
+	return T{
+		1,
+		2,
+		3,
+	}
+	return T{
+		1,
+		T{1, 2, 3},
+		3,
+	}
+	return T{
+		1,
+		T{1,
+			2, 3},
+		3,
+	}
+	return T{
+		1,
+		T{1,
+			2,
+			3},
+		3,
+	}
+	return T{
+		1,
+		2,
+	}, nil
+	return T{
+			1,
+			2,
+		},
+		T{
+			x:	3,
+			y:	4,
+		}, nil
+	return T{
+			1,
+			2,
+		},
+		nil
+	return T{
+			1,
+			2,
+		},
+		T{
+			x:	3,
+			y:	4,
+		},
+		nil
+	return x + y +
+		z
+	return func() {}
+	return func() {
+			_ = 0
+		}, T{
+			1, 2,
+		}
+	return func() {
+		_ = 0
+	}
+	return func() T {
+		return T{
+			1, 2,
+		}
+	}
+}
+
+// Formatting of multi-line returns: test cases from issue 1207.
+func F() (*T, os.Error) {
+	return &T{
+			X:	1,
+			Y:	2,
+		},
+		nil
+}
+
+func G() (*T, *T, os.Error) {
+	return &T{
+			X:	1,
+			Y:	2,
+		},
+		&T{
+			X:	3,
+			Y:	4,
+		},
+		nil
+}
+
+func _() interface{} {
+	return &fileStat{
+		name:		basename(file.name),
+		size:		mkSize(d.FileSizeHigh, d.FileSizeLow),
+		modTime:	mkModTime(d.LastWriteTime),
+		mode:		mkMode(d.FileAttributes),
+		sys:		mkSysFromFI(&d),
+	}, nil
+}
+
+// Formatting of if-statement headers.
+func _() {
+	if true {
+	}
+	if true {
+	}	// no semicolon printed
+	if expr {
+	}
+	if expr {
+	}	// no semicolon printed
+	if expr {
+	}	// no parens printed
+	if expr {
+	}	// no semicolon and parens printed
+	if x := expr; true {
+		use(x)
+	}
+	if x := expr; expr {
+		use(x)
+	}
+}
+
+// Formatting of switch-statement headers.
+func _() {
+	switch {
+	}
+	switch {
+	}	// no semicolon printed
+	switch expr {
+	}
+	switch expr {
+	}	// no semicolon printed
+	switch expr {
+	}	// no parens printed
+	switch expr {
+	}	// no semicolon and parens printed
+	switch x := expr; {
+	default:
+		use(
+			x)
+	}
+	switch x := expr; expr {
+	default:
+		use(x)
+	}
+}
+
+// Formatting of switch statement bodies.
+func _() {
+	switch {
+	}
+
+	switch x := 0; x {
+	case 1:
+		use(x)
+		use(x)	// followed by an empty line
+
+	case 2:	// followed by an empty line
+
+		use(x)	// followed by an empty line
+
+	case 3:	// no empty lines
+		use(x)
+		use(x)
+	}
+
+	switch x {
+	case 0:
+		use(x)
+	case 1:	// this comment should have no effect on the previous or next line
+		use(x)
+	}
+
+	switch x := 0; x {
+	case 1:
+		x = 0
+		// this comment should be indented
+	case 2:
+		x = 0
+	// this comment should not be indented, it is aligned with the next case
+	case 3:
+		x = 0
+		/* indented comment
+		   aligned
+		   aligned
+		*/
+		// bla
+		/* and more */
+	case 4:
+		x = 0
+	/* not indented comment
+	   aligned
+	   aligned
+	*/
+	// bla
+	/* and more */
+	case 5:
+	}
+}
+
+// Formatting of selected select statements.
+func _() {
+	select {}
+	select { /* this comment should not be tab-aligned because the closing } is on the same line */
+	}
+	select {	/* this comment should be tab-aligned */
+	}
+	select {	// this comment should be tab-aligned
+	}
+	select {
+	case <-c:
+	}
+}
+
+// Formatting of for-statement headers for single-line for-loops.
+func _() {
+	for {
+	}
+	for expr {
+	}
+	for expr {
+	}	// no parens printed
+	for {
+	}	// no semicolons printed
+	for x := expr; ; {
+		use(x)
+	}
+	for expr {
+	}	// no semicolons printed
+	for expr {
+	}	// no semicolons and parens printed
+	for ; ; expr = false {
+	}
+	for x := expr; expr; {
+		use(x)
+	}
+	for x := expr; ; expr = false {
+		use(x)
+	}
+	for ; expr; expr = false {
+	}
+	for x := expr; expr; expr = false {
+		use(x)
+	}
+	for x := range []int{} {
+		use(x)
+	}
+	for x := range []int{} {
+		use(x)
+	}	// no parens printed
+}
+
+// Formatting of for-statement headers for multi-line for-loops.
+func _() {
+	for {
+	}
+	for expr {
+	}
+	for expr {
+	}	// no parens printed
+	for {
+	}	// no semicolons printed
+	for x := expr; ; {
+		use(x)
+	}
+	for expr {
+	}	// no semicolons printed
+	for expr {
+	}	// no semicolons and parens printed
+	for ; ; expr = false {
+	}
+	for x := expr; expr; {
+		use(x)
+	}
+	for x := expr; ; expr = false {
+		use(x)
+	}
+	for ; expr; expr = false {
+	}
+	for x := expr; expr; expr = false {
+		use(x)
+	}
+	for range []int{} {
+		println("foo")
+	}
+	for x := range []int{} {
+		use(x)
+	}
+	for x := range []int{} {
+		use(x)
+	}	// no parens printed
+}
+
+// Formatting of selected short single- and multi-line statements.
+func _() {
+	if cond {
+	}
+	if cond {
+	}	// multiple lines
+	if cond {
+	} else {
+	}	// else clause always requires multiple lines
+
+	for {
+	}
+	for i := 0; i < len(a); 1++ {
+	}
+	for i := 0; i < len(a); 1++ {
+		a[i] = i
+	}
+	for i := 0; i < len(a); 1++ {
+		a[i] = i
+	}	// multiple lines
+
+	for range a {
+	}
+	for _ = range a {
+	}
+	for _, _ = range a {
+	}
+	for i := range a {
+	}
+	for i := range a {
+		a[i] = i
+	}
+	for i := range a {
+		a[i] = i
+	}	// multiple lines
+
+	go func() {
+		for {
+			a <- <-b
+		}
+	}()
+	defer func() {
+		if x := recover(); x != nil {
+			err = fmt.Sprintf("error: %s", x.msg)
+		}
+	}()
+}
+
+// Don't remove mandatory parentheses around composite literals in control clauses.
+func _() {
+	// strip parentheses - no composite literals or composite literals don't start with a type name
+	if x {
+	}
+	if x {
+	}
+	if []T{} {
+	}
+	if []T{} {
+	}
+	if []T{} {
+	}
+
+	for x {
+	}
+	for x {
+	}
+	for []T{} {
+	}
+	for []T{} {
+	}
+	for []T{} {
+	}
+
+	switch x {
+	}
+	switch x {
+	}
+	switch []T{} {
+	}
+	switch []T{} {
+	}
+
+	for _ = range []T{T{42}} {
+	}
+
+	// leave parentheses - composite literals start with a type name
+	if (T{}) {
+	}
+	if (T{}) {
+	}
+	if (T{}) {
+	}
+
+	for (T{}) {
+	}
+	for (T{}) {
+	}
+	for (T{}) {
+	}
+
+	switch (T{}) {
+	}
+	switch (T{}) {
+	}
+
+	for _ = range (T1{T{42}}) {
+	}
+
+	if x == (T{42}[0]) {
+	}
+	if (x == T{42}[0]) {
+	}
+	if x == (T{42}[0]) {
+	}
+	if x == (T{42}[0]) {
+	}
+	if x == (T{42}[0]) {
+	}
+	if x == a+b*(T{42}[0]) {
+	}
+	if (x == a+b*T{42}[0]) {
+	}
+	if x == a+b*(T{42}[0]) {
+	}
+	if x == a+(b*(T{42}[0])) {
+	}
+	if x == a+b*(T{42}[0]) {
+	}
+	if (a + b*(T{42}[0])) == x {
+	}
+	if (a + b*(T{42}[0])) == x {
+	}
+
+	if struct{ x bool }{false}.x {
+	}
+	if (struct{ x bool }{false}.x) == false {
+	}
+	if struct{ x bool }{false}.x == false {
+	}
+}
+
+// Extra empty lines inside functions. Do respect source code line
+// breaks between statement boundaries but print at most one empty
+// line at a time.
+func _() {
+
+	const _ = 0
+
+	const _ = 1
+	type _ int
+	type _ float
+
+	var _ = 0
+	var x = 1
+
+	// Each use(x) call below should have at most one empty line before and after.
+	// Known bug: The first use call may have more than one empty line before
+	//            (see go/printer/nodes.go, func linebreak).
+
+	use(x)
+
+	if x < x {
+
+		use(x)
+
+	} else {
+
+		use(x)
+
+	}
+}
+
+// Formatting around labels.
+func _() {
+L:
+}
+
+func _() {
+	// this comment should be indented
+L:	// no semicolon needed
+}
+
+func _() {
+	switch 0 {
+	case 0:
+	L0:
+		;	// semicolon required
+	case 1:
+	L1:
+		;	// semicolon required
+	default:
+	L2:	// no semicolon needed
+	}
+}
+
+func _() {
+	f()
+L1:
+	f()
+L2:
+	;
+L3:
+}
+
+func _() {
+	// this comment should be indented
+L:
+}
+
+func _() {
+L:
+	_ = 0
+}
+
+func _() {
+	// this comment should be indented
+L:
+	_ = 0
+}
+
+func _() {
+	for {
+	L1:
+		_ = 0
+	L2:
+		_ = 0
+	}
+}
+
+func _() {
+	// this comment should be indented
+	for {
+	L1:
+		_ = 0
+	L2:
+		_ = 0
+	}
+}
+
+func _() {
+	if true {
+		_ = 0
+	}
+	_ = 0	// the indentation here should not be affected by the long label name
+AnOverlongLabel:
+	_ = 0
+
+	if true {
+		_ = 0
+	}
+	_ = 0
+
+L:
+	_ = 0
+}
+
+func _() {
+	for {
+		goto L
+	}
+L:
+
+	MoreCode()
+}
+
+func _() {
+	for {
+		goto L
+	}
+L:	// A comment on the same line as the label, followed by a single empty line.
+	// Known bug: There may be more than one empty line before MoreCode()
+	//            (see go/printer/nodes.go, func linebreak).
+
+	MoreCode()
+}
+
+func _() {
+	for {
+		goto L
+	}
+L:
+
+	// There should be a single empty line before this comment.
+	MoreCode()
+}
+
+func _() {
+	for {
+		goto AVeryLongLabelThatShouldNotAffectFormatting
+	}
+AVeryLongLabelThatShouldNotAffectFormatting:
+	// There should be a single empty line after this comment.
+
+	// There should be a single empty line before this comment.
+	MoreCode()
+}
+
+// Formatting of empty statements.
+func _() {
+
+}
+
+func _() {
+}
+
+func _() {
+}
+
+func _() {
+	f()
+}
+
+func _() {
+L:
+	;
+}
+
+func _() {
+L:
+	;
+	f()
+}
diff --git a/src/go/printer/testdata/statements.input b/src/go/printer/testdata/statements.input
new file mode 100644
index 0000000..cade157
--- /dev/null
+++ b/src/go/printer/testdata/statements.input
@@ -0,0 +1,555 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package statements
+
+var expr bool
+
+func use(x interface{}) {}
+
+// Formatting of multi-line return statements.
+func _f() {
+	return
+	return x, y, z
+	return T{}
+	return T{1, 2, 3},
+		x, y, z
+	return T{1, 2, 3},
+		x, y,
+		z
+	return T{1,
+		2,
+		3}
+	return T{1,
+		2,
+		3,
+	}
+	return T{
+		1,
+		2,
+		3}
+	return T{
+		1,
+		2,
+		3,
+	}
+	return T{
+		1,
+		T{1, 2, 3},
+		3,
+	}
+	return T{
+		1,
+		T{1,
+			2, 3},
+		3,
+	}
+	return T{
+		1,
+		T{1,
+			2,
+			3},
+		3,
+	}
+	return T{
+			1,
+			2,
+		}, nil
+	return T{
+			1,
+			2,
+		},
+		T{
+			x: 3,
+			y: 4,
+		}, nil
+	return T{
+			1,
+			2,
+		},
+		nil
+	return T{
+			1,
+			2,
+		},
+		T{
+			x: 3,
+			y: 4,
+		},
+		nil
+	return x + y +
+		z
+	return func() {}
+	return func() {
+		_ = 0
+	}, T{
+		1, 2,
+	}
+	return func() {
+		_ = 0
+	}
+	return func() T {
+		return T {
+			1, 2,
+		}
+	}
+}
+
+// Formatting of multi-line returns: test cases from issue 1207.
+func F() (*T, os.Error) {
+       return &T{
+               X: 1,
+               Y: 2,
+       },
+               nil
+}
+
+func G() (*T, *T, os.Error) {
+       return &T{
+               X: 1,
+               Y: 2,
+       },
+               &T{
+                       X: 3,
+                       Y: 4,
+               },
+               nil
+}
+
+func _() interface{} {
+	return &fileStat{
+			name:    basename(file.name),
+			size:    mkSize(d.FileSizeHigh, d.FileSizeLow),
+			modTime: mkModTime(d.LastWriteTime),
+			mode:    mkMode(d.FileAttributes),
+			sys:     mkSysFromFI(&d),
+		}, nil
+}
+
+// Formatting of if-statement headers.
+func _() {
+	if true {}
+	if; true {}  // no semicolon printed
+	if expr{}
+	if;expr{}  // no semicolon printed
+	if (expr){}  // no parens printed
+	if;((expr)){}  // no semicolon and parens printed
+	if x:=expr;true{
+	use(x)}
+	if x:=expr; expr {use(x)}
+}
+
+
+// Formatting of switch-statement headers.
+func _() {
+	switch {}
+	switch;{}  // no semicolon printed
+	switch expr {}
+	switch;expr{}  // no semicolon printed
+	switch (expr) {}  // no parens printed
+	switch;((expr)){}  // no semicolon and parens printed
+	switch x := expr; { default:use(
+x)
+	}
+	switch x := expr; expr {default:use(x)}
+}
+
+
+// Formatting of switch statement bodies.
+func _() {
+	switch {
+	}
+
+	switch x := 0; x {
+	case 1:
+		use(x)
+		use(x)  // followed by an empty line
+
+	case 2:  // followed by an empty line
+
+		use(x)  // followed by an empty line
+
+	case 3:  // no empty lines
+		use(x)
+		use(x)
+	}
+
+	switch x {
+	case 0:
+		use(x)
+	case 1:  // this comment should have no effect on the previous or next line
+		use(x)
+	}
+
+	switch x := 0; x {
+	case 1:
+		x = 0
+		// this comment should be indented
+	case 2:
+		x = 0
+	// this comment should not be indented, it is aligned with the next case
+	case 3:
+		x = 0
+		/* indented comment
+		   aligned
+		   aligned
+		*/
+		// bla
+		/* and more */
+	case 4:
+		x = 0
+	/* not indented comment
+	   aligned
+	   aligned
+	*/
+	// bla
+	/* and more */
+	case 5:
+	}
+}
+
+
+// Formatting of selected select statements.
+func _() {
+	select {
+	}
+	select { /* this comment should not be tab-aligned because the closing } is on the same line */ }
+	select { /* this comment should be tab-aligned */
+	}
+	select { // this comment should be tab-aligned
+	}
+	select { case <-c: }
+}
+
+
+// Formatting of for-statement headers for single-line for-loops.
+func _() {
+	for{}
+	for expr {}
+	for (expr) {}  // no parens printed
+	for;;{}  // no semicolons printed
+	for x :=expr;; {use( x)}
+	for; expr;{}  // no semicolons printed
+	for; ((expr));{}  // no semicolons and parens printed
+	for; ; expr = false {}
+	for x :=expr; expr; {use(x)}
+	for x := expr;; expr=false {use(x)}
+	for;expr;expr =false {}
+	for x := expr;expr;expr = false { use(x) }
+	for x := range []int{} { use(x) }
+	for x := range (([]int{})) { use(x) }  // no parens printed
+}
+
+
+// Formatting of for-statement headers for multi-line for-loops.
+func _() {
+	for{
+	}
+	for expr {
+	}
+	for (expr) {
+	}  // no parens printed
+	for;;{
+	}  // no semicolons printed
+	for x :=expr;; {use( x)
+	}
+	for; expr;{
+	}  // no semicolons printed
+	for; ((expr));{
+	}  // no semicolons and parens printed
+	for; ; expr = false {
+	}
+	for x :=expr; expr; {use(x)
+	}
+	for x := expr;; expr=false {use(x)
+	}
+	for;expr;expr =false {
+	}
+	for x := expr;expr;expr = false {
+	use(x)
+	}
+	for range []int{} {
+	println("foo")}
+	for x := range []int{} {
+	use(x) }
+	for x := range (([]int{})) {
+	use(x) }  // no parens printed
+}
+
+
+// Formatting of selected short single- and multi-line statements.
+func _() {
+	if cond {}
+	if cond {
+	} // multiple lines
+	if cond {} else {} // else clause always requires multiple lines
+
+	for {}
+	for i := 0; i < len(a); 1++ {}
+	for i := 0; i < len(a); 1++ { a[i] = i }
+	for i := 0; i < len(a); 1++ { a[i] = i
+	} // multiple lines
+
+	for range a{}
+	for _ = range a{}
+	for _, _ = range a{}
+	for i := range a {}
+	for i := range a { a[i] = i }
+	for i := range a { a[i] = i
+	} // multiple lines
+
+	go func() { for { a <- <-b } }()
+	defer func() { if x := recover(); x != nil { err = fmt.Sprintf("error: %s", x.msg) } }()
+}
+
+
+// Don't remove mandatory parentheses around composite literals in control clauses.
+func _() {
+	// strip parentheses - no composite literals or composite literals don't start with a type name
+	if (x) {}
+	if (((x))) {}
+	if ([]T{}) {}
+	if (([]T{})) {}
+	if ; (((([]T{})))) {}
+
+	for (x) {}
+	for (((x))) {}
+	for ([]T{}) {}
+	for (([]T{})) {}
+	for ; (((([]T{})))) ; {}
+
+	switch (x) {}
+	switch (((x))) {}
+	switch ([]T{}) {}
+	switch ; (((([]T{})))) {}
+
+	for _ = range ((([]T{T{42}}))) {}
+
+	// leave parentheses - composite literals start with a type name
+	if (T{}) {}
+	if ((T{})) {}
+	if ; ((((T{})))) {}
+
+	for (T{}) {}
+	for ((T{})) {}
+	for ; ((((T{})))) ; {}
+
+	switch (T{}) {}
+	switch ; ((((T{})))) {}
+
+	for _ = range (((T1{T{42}}))) {}
+
+	if x == (T{42}[0]) {}
+	if (x == T{42}[0]) {}
+	if (x == (T{42}[0])) {}
+	if (x == (((T{42}[0])))) {}
+	if (((x == (T{42}[0])))) {}
+	if x == a + b*(T{42}[0]) {}
+	if (x == a + b*T{42}[0]) {}
+	if (x == a + b*(T{42}[0])) {}
+	if (x == a + ((b * (T{42}[0])))) {}
+	if (((x == a + b * (T{42}[0])))) {}
+	if (((a + b * (T{42}[0])) == x)) {}
+	if (((a + b * (T{42}[0])))) == x {}
+
+	if (struct{x bool}{false}.x) {}
+	if (struct{x bool}{false}.x) == false {}
+	if (struct{x bool}{false}.x == false) {}
+}
+
+
+// Extra empty lines inside functions. Do respect source code line
+// breaks between statement boundaries but print at most one empty
+// line at a time.
+func _() {
+
+	const _ = 0
+
+	const _ = 1
+	type _ int
+	type _ float
+
+	var _ = 0
+	var x = 1
+
+	// Each use(x) call below should have at most one empty line before and after.
+	// Known bug: The first use call may have more than one empty line before
+	//            (see go/printer/nodes.go, func linebreak).
+
+
+
+	use(x)
+
+	if x < x {
+
+		use(x)
+
+	} else {
+
+		use(x)
+
+	}
+}
+
+
+// Formatting around labels.
+func _() {
+	L:
+}
+
+
+func _() {
+	// this comment should be indented
+	L: ;  // no semicolon needed
+}
+
+
+func _() {
+	switch 0 {
+	case 0:
+		L0: ;  // semicolon required
+	case 1:
+		L1: ;  // semicolon required
+	default:
+		L2: ;  // no semicolon needed
+	}
+}
+
+
+func _() {
+	f()
+L1:
+	f()
+L2:
+	;
+L3:
+}
+
+
+func _() {
+	// this comment should be indented
+	L:
+}
+
+
+func _() {
+	L: _ = 0
+}
+
+
+func _() {
+	// this comment should be indented
+	L: _ = 0
+}
+
+
+func _() {
+	for {
+	L1: _ = 0
+	L2:
+		_ = 0
+	}
+}
+
+
+func _() {
+		// this comment should be indented
+	for {
+	L1: _ = 0
+	L2:
+		_ = 0
+	}
+}
+
+
+func _() {
+	if true {
+		_ = 0
+	}
+	_ = 0  // the indentation here should not be affected by the long label name
+AnOverlongLabel:
+	_ = 0
+	
+	if true {
+		_ = 0
+	}
+	_ = 0
+
+L:	_ = 0
+}
+
+
+func _() {
+	for {
+		goto L
+	}
+L:
+
+	MoreCode()
+}
+
+
+func _() {
+	for {
+		goto L
+	}
+L:	// A comment on the same line as the label, followed by a single empty line.
+	// Known bug: There may be more than one empty line before MoreCode()
+	//            (see go/printer/nodes.go, func linebreak).
+
+
+
+
+	MoreCode()
+}
+
+
+func _() {
+	for {
+		goto L
+	}
+L:
+
+
+
+
+	// There should be a single empty line before this comment.
+	MoreCode()
+}
+
+
+func _() {
+	for {
+		goto AVeryLongLabelThatShouldNotAffectFormatting
+	}
+AVeryLongLabelThatShouldNotAffectFormatting:
+	// There should be a single empty line after this comment.
+
+	// There should be a single empty line before this comment.
+	MoreCode()
+}
+
+
+// Formatting of empty statements.
+func _() {
+	;;;;;;;;;;;;;;;;;;;;;;;;;
+}
+
+func _() {;;;;;;;;;;;;;;;;;;;;;;;;;
+}
+
+func _() {;;;;;;;;;;;;;;;;;;;;;;;;;}
+
+func _() {
+f();;;;;;;;;;;;;;;;;;;;;;;;;
+}
+
+func _() {
+L:;;;;;;;;;;;;
+}
+
+func _() {
+L:;;;;;;;;;;;;
+	f()
+}
diff --git a/src/pkg/go/scanner/errors.go b/src/go/scanner/errors.go
similarity index 100%
rename from src/pkg/go/scanner/errors.go
rename to src/go/scanner/errors.go
diff --git a/src/pkg/go/scanner/example_test.go b/src/go/scanner/example_test.go
similarity index 100%
rename from src/pkg/go/scanner/example_test.go
rename to src/go/scanner/example_test.go
diff --git a/src/pkg/go/scanner/scanner.go b/src/go/scanner/scanner.go
similarity index 100%
rename from src/pkg/go/scanner/scanner.go
rename to src/go/scanner/scanner.go
diff --git a/src/pkg/go/scanner/scanner_test.go b/src/go/scanner/scanner_test.go
similarity index 100%
rename from src/pkg/go/scanner/scanner_test.go
rename to src/go/scanner/scanner_test.go
diff --git a/src/go/token/position.go b/src/go/token/position.go
new file mode 100644
index 0000000..82d90ee
--- /dev/null
+++ b/src/go/token/position.go
@@ -0,0 +1,485 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package token
+
+import (
+	"fmt"
+	"sort"
+	"sync"
+)
+
+// -----------------------------------------------------------------------------
+// Positions
+
+// Position describes an arbitrary source position
+// including the file, line, and column location.
+// A Position is valid if the line number is > 0.
+//
+type Position struct {
+	Filename string // filename, if any
+	Offset   int    // offset, starting at 0
+	Line     int    // line number, starting at 1
+	Column   int    // column number, starting at 1 (character count)
+}
+
+// IsValid returns true if the position is valid.
+func (pos *Position) IsValid() bool { return pos.Line > 0 }
+
+// String returns a string in one of several forms:
+//
+//	file:line:column    valid position with file name
+//	line:column         valid position without file name
+//	file                invalid position with file name
+//	-                   invalid position without file name
+//
+func (pos Position) String() string {
+	s := pos.Filename
+	if pos.IsValid() {
+		if s != "" {
+			s += ":"
+		}
+		s += fmt.Sprintf("%d:%d", pos.Line, pos.Column)
+	}
+	if s == "" {
+		s = "-"
+	}
+	return s
+}
+
+// Pos is a compact encoding of a source position within a file set.
+// It can be converted into a Position for a more convenient, but much
+// larger, representation.
+//
+// The Pos value for a given file is a number in the range [base, base+size],
+// where base and size are specified when adding the file to the file set via
+// AddFile.
+//
+// To create the Pos value for a specific source offset, first add
+// the respective file to the current file set (via FileSet.AddFile)
+// and then call File.Pos(offset) for that file. Given a Pos value p
+// for a specific file set fset, the corresponding Position value is
+// obtained by calling fset.Position(p).
+//
+// Pos values can be compared directly with the usual comparison operators:
+// If two Pos values p and q are in the same file, comparing p and q is
+// equivalent to comparing the respective source file offsets. If p and q
+// are in different files, p < q is true if the file implied by p was added
+// to the respective file set before the file implied by q.
+//
+type Pos int
+
+// The zero value for Pos is NoPos; there is no file and line information
+// associated with it, and NoPos().IsValid() is false. NoPos is always
+// smaller than any other Pos value. The corresponding Position value
+// for NoPos is the zero value for Position.
+//
+const NoPos Pos = 0
+
+// IsValid returns true if the position is valid.
+func (p Pos) IsValid() bool {
+	return p != NoPos
+}
+
+// -----------------------------------------------------------------------------
+// File
+
+// A File is a handle for a file belonging to a FileSet.
+// A File has a name, size, and line offset table.
+//
+type File struct {
+	set  *FileSet
+	name string // file name as provided to AddFile
+	base int    // Pos value range for this file is [base...base+size]
+	size int    // file size as provided to AddFile
+
+	// lines and infos are protected by set.mutex
+	lines []int // lines contains the offset of the first character for each line (the first entry is always 0)
+	infos []lineInfo
+}
+
+// Name returns the file name of file f as registered with AddFile.
+func (f *File) Name() string {
+	return f.name
+}
+
+// Base returns the base offset of file f as registered with AddFile.
+func (f *File) Base() int {
+	return f.base
+}
+
+// Size returns the size of file f as registered with AddFile.
+func (f *File) Size() int {
+	return f.size
+}
+
+// LineCount returns the number of lines in file f.
+func (f *File) LineCount() int {
+	f.set.mutex.RLock()
+	n := len(f.lines)
+	f.set.mutex.RUnlock()
+	return n
+}
+
+// AddLine adds the line offset for a new line.
+// The line offset must be larger than the offset for the previous line
+// and smaller than the file size; otherwise the line offset is ignored.
+//
+func (f *File) AddLine(offset int) {
+	f.set.mutex.Lock()
+	if i := len(f.lines); (i == 0 || f.lines[i-1] < offset) && offset < f.size {
+		f.lines = append(f.lines, offset)
+	}
+	f.set.mutex.Unlock()
+}
+
+// MergeLine merges a line with the following line. It is akin to replacing
+// the newline character at the end of the line with a space (to not change the
+// remaining offsets). To obtain the line number, consult e.g. Position.Line.
+// MergeLine will panic if given an invalid line number.
+//
+func (f *File) MergeLine(line int) {
+	if line <= 0 {
+		panic("illegal line number (line numbering starts at 1)")
+	}
+	f.set.mutex.Lock()
+	defer f.set.mutex.Unlock()
+	if line >= len(f.lines) {
+		panic("illegal line number")
+	}
+	// To merge the line numbered <line> with the line numbered <line+1>,
+	// we need to remove the entry in lines corresponding to the line
+	// numbered <line+1>. The entry in lines corresponding to the line
+	// numbered <line+1> is located at index <line>, since indices in lines
+	// are 0-based and line numbers are 1-based.
+	copy(f.lines[line:], f.lines[line+1:])
+	f.lines = f.lines[:len(f.lines)-1]
+}
+
+// SetLines sets the line offsets for a file and returns true if successful.
+// The line offsets are the offsets of the first character of each line;
+// for instance for the content "ab\nc\n" the line offsets are {0, 3}.
+// An empty file has an empty line offset table.
+// Each line offset must be larger than the offset for the previous line
+// and smaller than the file size; otherwise SetLines fails and returns
+// false.
+//
+func (f *File) SetLines(lines []int) bool {
+	// verify validity of lines table
+	size := f.size
+	for i, offset := range lines {
+		if i > 0 && offset <= lines[i-1] || size <= offset {
+			return false
+		}
+	}
+
+	// set lines table
+	f.set.mutex.Lock()
+	f.lines = lines
+	f.set.mutex.Unlock()
+	return true
+}
+
+// SetLinesForContent sets the line offsets for the given file content.
+// It ignores position-altering //line comments.
+func (f *File) SetLinesForContent(content []byte) {
+	var lines []int
+	line := 0
+	for offset, b := range content {
+		if line >= 0 {
+			lines = append(lines, line)
+		}
+		line = -1
+		if b == '\n' {
+			line = offset + 1
+		}
+	}
+
+	// set lines table
+	f.set.mutex.Lock()
+	f.lines = lines
+	f.set.mutex.Unlock()
+}
+
+// A lineInfo object describes alternative file and line number
+// information (such as provided via a //line comment in a .go
+// file) for a given file offset.
+type lineInfo struct {
+	// fields are exported to make them accessible to gob
+	Offset   int
+	Filename string
+	Line     int
+}
+
+// AddLineInfo adds alternative file and line number information for
+// a given file offset. The offset must be larger than the offset for
+// the previously added alternative line info and smaller than the
+// file size; otherwise the information is ignored.
+//
+// AddLineInfo is typically used to register alternative position
+// information for //line filename:line comments in source files.
+//
+func (f *File) AddLineInfo(offset int, filename string, line int) {
+	f.set.mutex.Lock()
+	if i := len(f.infos); i == 0 || f.infos[i-1].Offset < offset && offset < f.size {
+		f.infos = append(f.infos, lineInfo{offset, filename, line})
+	}
+	f.set.mutex.Unlock()
+}
+
+// Pos returns the Pos value for the given file offset;
+// the offset must be <= f.Size().
+// f.Pos(f.Offset(p)) == p.
+//
+func (f *File) Pos(offset int) Pos {
+	if offset > f.size {
+		panic("illegal file offset")
+	}
+	return Pos(f.base + offset)
+}
+
+// Offset returns the offset for the given file position p;
+// p must be a valid Pos value in that file.
+// f.Offset(f.Pos(offset)) == offset.
+//
+func (f *File) Offset(p Pos) int {
+	if int(p) < f.base || int(p) > f.base+f.size {
+		panic("illegal Pos value")
+	}
+	return int(p) - f.base
+}
+
+// Line returns the line number for the given file position p;
+// p must be a Pos value in that file or NoPos.
+//
+func (f *File) Line(p Pos) int {
+	return f.Position(p).Line
+}
+
+func searchLineInfos(a []lineInfo, x int) int {
+	return sort.Search(len(a), func(i int) bool { return a[i].Offset > x }) - 1
+}
+
+// unpack returns the filename and line and column number for a file offset.
+// If adjusted is set, unpack will return the filename and line information
+// possibly adjusted by //line comments; otherwise those comments are ignored.
+//
+func (f *File) unpack(offset int, adjusted bool) (filename string, line, column int) {
+	filename = f.name
+	if i := searchInts(f.lines, offset); i >= 0 {
+		line, column = i+1, offset-f.lines[i]+1
+	}
+	if adjusted && len(f.infos) > 0 {
+		// almost no files have extra line infos
+		if i := searchLineInfos(f.infos, offset); i >= 0 {
+			alt := &f.infos[i]
+			filename = alt.Filename
+			if i := searchInts(f.lines, alt.Offset); i >= 0 {
+				line += alt.Line - i - 1
+			}
+		}
+	}
+	return
+}
+
+func (f *File) position(p Pos, adjusted bool) (pos Position) {
+	offset := int(p) - f.base
+	pos.Offset = offset
+	pos.Filename, pos.Line, pos.Column = f.unpack(offset, adjusted)
+	return
+}
+
+// PositionFor returns the Position value for the given file position p.
+// If adjusted is set, the position may be adjusted by position-altering
+// //line comments; otherwise those comments are ignored.
+// p must be a Pos value in f or NoPos.
+//
+func (f *File) PositionFor(p Pos, adjusted bool) (pos Position) {
+	if p != NoPos {
+		if int(p) < f.base || int(p) > f.base+f.size {
+			panic("illegal Pos value")
+		}
+		pos = f.position(p, adjusted)
+	}
+	return
+}
+
+// Position returns the Position value for the given file position p.
+// Calling f.Position(p) is equivalent to calling f.PositionFor(p, true).
+//
+func (f *File) Position(p Pos) (pos Position) {
+	return f.PositionFor(p, true)
+}
+
+// -----------------------------------------------------------------------------
+// FileSet
+
+// A FileSet represents a set of source files.
+// Methods of file sets are synchronized; multiple goroutines
+// may invoke them concurrently.
+//
+type FileSet struct {
+	mutex sync.RWMutex // protects the file set
+	base  int          // base offset for the next file
+	files []*File      // list of files in the order added to the set
+	last  *File        // cache of last file looked up
+}
+
+// NewFileSet creates a new file set.
+func NewFileSet() *FileSet {
+	return &FileSet{
+		base: 1, // 0 == NoPos
+	}
+}
+
+// Base returns the minimum base offset that must be provided to
+// AddFile when adding the next file.
+//
+func (s *FileSet) Base() int {
+	s.mutex.RLock()
+	b := s.base
+	s.mutex.RUnlock()
+	return b
+
+}
+
+// AddFile adds a new file with a given filename, base offset, and file size
+// to the file set s and returns the file. Multiple files may have the same
+// name. The base offset must not be smaller than the FileSet's Base(), and
+// size must not be negative. As a special case, if a negative base is provided,
+// the current value of the FileSet's Base() is used instead.
+//
+// Adding the file will set the file set's Base() value to base + size + 1
+// as the minimum base value for the next file. The following relationship
+// exists between a Pos value p for a given file offset offs:
+//
+//	int(p) = base + offs
+//
+// with offs in the range [0, size] and thus p in the range [base, base+size].
+// For convenience, File.Pos may be used to create file-specific position
+// values from a file offset.
+//
+func (s *FileSet) AddFile(filename string, base, size int) *File {
+	s.mutex.Lock()
+	defer s.mutex.Unlock()
+	if base < 0 {
+		base = s.base
+	}
+	if base < s.base || size < 0 {
+		panic("illegal base or size")
+	}
+	// base >= s.base && size >= 0
+	f := &File{s, filename, base, size, []int{0}, nil}
+	base += size + 1 // +1 because EOF also has a position
+	if base < 0 {
+		panic("token.Pos offset overflow (> 2G of source code in file set)")
+	}
+	// add the file to the file set
+	s.base = base
+	s.files = append(s.files, f)
+	s.last = f
+	return f
+}
+
+// Iterate calls f for the files in the file set in the order they were added
+// until f returns false.
+//
+func (s *FileSet) Iterate(f func(*File) bool) {
+	for i := 0; ; i++ {
+		var file *File
+		s.mutex.RLock()
+		if i < len(s.files) {
+			file = s.files[i]
+		}
+		s.mutex.RUnlock()
+		if file == nil || !f(file) {
+			break
+		}
+	}
+}
+
+func searchFiles(a []*File, x int) int {
+	return sort.Search(len(a), func(i int) bool { return a[i].base > x }) - 1
+}
+
+func (s *FileSet) file(p Pos) *File {
+	s.mutex.RLock()
+	// common case: p is in last file
+	if f := s.last; f != nil && f.base <= int(p) && int(p) <= f.base+f.size {
+		s.mutex.RUnlock()
+		return f
+	}
+	// p is not in last file - search all files
+	if i := searchFiles(s.files, int(p)); i >= 0 {
+		f := s.files[i]
+		// f.base <= int(p) by definition of searchFiles
+		if int(p) <= f.base+f.size {
+			s.mutex.RUnlock()
+			s.mutex.Lock()
+			s.last = f // race is ok - s.last is only a cache
+			s.mutex.Unlock()
+			return f
+		}
+	}
+	s.mutex.RUnlock()
+	return nil
+}
+
+// File returns the file that contains the position p.
+// If no such file is found (for instance for p == NoPos),
+// the result is nil.
+//
+func (s *FileSet) File(p Pos) (f *File) {
+	if p != NoPos {
+		f = s.file(p)
+	}
+	return
+}
+
+// PositionFor converts a Pos p in the fileset into a Position value.
+// If adjusted is set, the position may be adjusted by position-altering
+// //line comments; otherwise those comments are ignored.
+// p must be a Pos value in s or NoPos.
+//
+func (s *FileSet) PositionFor(p Pos, adjusted bool) (pos Position) {
+	if p != NoPos {
+		if f := s.file(p); f != nil {
+			pos = f.position(p, adjusted)
+		}
+	}
+	return
+}
+
+// Position converts a Pos p in the fileset into a Position value.
+// Calling s.Position(p) is equivalent to calling s.PositionFor(p, true).
+//
+func (s *FileSet) Position(p Pos) (pos Position) {
+	return s.PositionFor(p, true)
+}
+
+// -----------------------------------------------------------------------------
+// Helper functions
+
+func searchInts(a []int, x int) int {
+	// This function body is a manually inlined version of:
+	//
+	//   return sort.Search(len(a), func(i int) bool { return a[i] > x }) - 1
+	//
+	// With better compiler optimizations, this may not be needed in the
+	// future, but at the moment this change improves the go/printer
+	// benchmark performance by ~30%. This has a direct impact on the
+	// speed of gofmt and thus seems worthwhile (2011-04-29).
+	// TODO(gri): Remove this when compilers have caught up.
+	i, j := 0, len(a)
+	for i < j {
+		h := i + (j-i)/2 // avoid overflow when computing h
+		// i ≤ h < j
+		if a[h] <= x {
+			i = h + 1
+		} else {
+			j = h
+		}
+	}
+	return i - 1
+}
diff --git a/src/go/token/position_test.go b/src/go/token/position_test.go
new file mode 100644
index 0000000..d26939c
--- /dev/null
+++ b/src/go/token/position_test.go
@@ -0,0 +1,297 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package token
+
+import (
+	"fmt"
+	"math/rand"
+	"sync"
+	"testing"
+)
+
+func checkPos(t *testing.T, msg string, got, want Position) {
+	if got.Filename != want.Filename {
+		t.Errorf("%s: got filename = %q; want %q", msg, got.Filename, want.Filename)
+	}
+	if got.Offset != want.Offset {
+		t.Errorf("%s: got offset = %d; want %d", msg, got.Offset, want.Offset)
+	}
+	if got.Line != want.Line {
+		t.Errorf("%s: got line = %d; want %d", msg, got.Line, want.Line)
+	}
+	if got.Column != want.Column {
+		t.Errorf("%s: got column = %d; want %d", msg, got.Column, want.Column)
+	}
+}
+
+func TestNoPos(t *testing.T) {
+	if NoPos.IsValid() {
+		t.Errorf("NoPos should not be valid")
+	}
+	var fset *FileSet
+	checkPos(t, "nil NoPos", fset.Position(NoPos), Position{})
+	fset = NewFileSet()
+	checkPos(t, "fset NoPos", fset.Position(NoPos), Position{})
+}
+
+var tests = []struct {
+	filename string
+	source   []byte // may be nil
+	size     int
+	lines    []int
+}{
+	{"a", []byte{}, 0, []int{}},
+	{"b", []byte("01234"), 5, []int{0}},
+	{"c", []byte("\n\n\n\n\n\n\n\n\n"), 9, []int{0, 1, 2, 3, 4, 5, 6, 7, 8}},
+	{"d", nil, 100, []int{0, 5, 10, 20, 30, 70, 71, 72, 80, 85, 90, 99}},
+	{"e", nil, 777, []int{0, 80, 100, 120, 130, 180, 267, 455, 500, 567, 620}},
+	{"f", []byte("package p\n\nimport \"fmt\""), 23, []int{0, 10, 11}},
+	{"g", []byte("package p\n\nimport \"fmt\"\n"), 24, []int{0, 10, 11}},
+	{"h", []byte("package p\n\nimport \"fmt\"\n "), 25, []int{0, 10, 11, 24}},
+}
+
+func linecol(lines []int, offs int) (int, int) {
+	prevLineOffs := 0
+	for line, lineOffs := range lines {
+		if offs < lineOffs {
+			return line, offs - prevLineOffs + 1
+		}
+		prevLineOffs = lineOffs
+	}
+	return len(lines), offs - prevLineOffs + 1
+}
+
+func verifyPositions(t *testing.T, fset *FileSet, f *File, lines []int) {
+	for offs := 0; offs < f.Size(); offs++ {
+		p := f.Pos(offs)
+		offs2 := f.Offset(p)
+		if offs2 != offs {
+			t.Errorf("%s, Offset: got offset %d; want %d", f.Name(), offs2, offs)
+		}
+		line, col := linecol(lines, offs)
+		msg := fmt.Sprintf("%s (offs = %d, p = %d)", f.Name(), offs, p)
+		checkPos(t, msg, f.Position(f.Pos(offs)), Position{f.Name(), offs, line, col})
+		checkPos(t, msg, fset.Position(p), Position{f.Name(), offs, line, col})
+	}
+}
+
+func makeTestSource(size int, lines []int) []byte {
+	src := make([]byte, size)
+	for _, offs := range lines {
+		if offs > 0 {
+			src[offs-1] = '\n'
+		}
+	}
+	return src
+}
+
+func TestPositions(t *testing.T) {
+	const delta = 7 // a non-zero base offset increment
+	fset := NewFileSet()
+	for _, test := range tests {
+		// verify consistency of test case
+		if test.source != nil && len(test.source) != test.size {
+			t.Errorf("%s: inconsistent test case: got file size %d; want %d", test.filename, len(test.source), test.size)
+		}
+
+		// add file and verify name and size
+		f := fset.AddFile(test.filename, fset.Base()+delta, test.size)
+		if f.Name() != test.filename {
+			t.Errorf("got filename %q; want %q", f.Name(), test.filename)
+		}
+		if f.Size() != test.size {
+			t.Errorf("%s: got file size %d; want %d", f.Name(), f.Size(), test.size)
+		}
+		if fset.File(f.Pos(0)) != f {
+			t.Errorf("%s: f.Pos(0) was not found in f", f.Name())
+		}
+
+		// add lines individually and verify all positions
+		for i, offset := range test.lines {
+			f.AddLine(offset)
+			if f.LineCount() != i+1 {
+				t.Errorf("%s, AddLine: got line count %d; want %d", f.Name(), f.LineCount(), i+1)
+			}
+			// adding the same offset again should be ignored
+			f.AddLine(offset)
+			if f.LineCount() != i+1 {
+				t.Errorf("%s, AddLine: got unchanged line count %d; want %d", f.Name(), f.LineCount(), i+1)
+			}
+			verifyPositions(t, fset, f, test.lines[0:i+1])
+		}
+
+		// add lines with SetLines and verify all positions
+		if ok := f.SetLines(test.lines); !ok {
+			t.Errorf("%s: SetLines failed", f.Name())
+		}
+		if f.LineCount() != len(test.lines) {
+			t.Errorf("%s, SetLines: got line count %d; want %d", f.Name(), f.LineCount(), len(test.lines))
+		}
+		verifyPositions(t, fset, f, test.lines)
+
+		// add lines with SetLinesForContent and verify all positions
+		src := test.source
+		if src == nil {
+			// no test source available - create one from scratch
+			src = makeTestSource(test.size, test.lines)
+		}
+		f.SetLinesForContent(src)
+		if f.LineCount() != len(test.lines) {
+			t.Errorf("%s, SetLinesForContent: got line count %d; want %d", f.Name(), f.LineCount(), len(test.lines))
+		}
+		verifyPositions(t, fset, f, test.lines)
+	}
+}
+
+func TestLineInfo(t *testing.T) {
+	fset := NewFileSet()
+	f := fset.AddFile("foo", fset.Base(), 500)
+	lines := []int{0, 42, 77, 100, 210, 220, 277, 300, 333, 401}
+	// add lines individually and provide alternative line information
+	for _, offs := range lines {
+		f.AddLine(offs)
+		f.AddLineInfo(offs, "bar", 42)
+	}
+	// verify positions for all offsets
+	for offs := 0; offs <= f.Size(); offs++ {
+		p := f.Pos(offs)
+		_, col := linecol(lines, offs)
+		msg := fmt.Sprintf("%s (offs = %d, p = %d)", f.Name(), offs, p)
+		checkPos(t, msg, f.Position(f.Pos(offs)), Position{"bar", offs, 42, col})
+		checkPos(t, msg, fset.Position(p), Position{"bar", offs, 42, col})
+	}
+}
+
+func TestFiles(t *testing.T) {
+	fset := NewFileSet()
+	for i, test := range tests {
+		base := fset.Base()
+		if i%2 == 1 {
+			// Setting a negative base is equivalent to
+			// fset.Base(), so test some of each.
+			base = -1
+		}
+		fset.AddFile(test.filename, base, test.size)
+		j := 0
+		fset.Iterate(func(f *File) bool {
+			if f.Name() != tests[j].filename {
+				t.Errorf("got filename = %s; want %s", f.Name(), tests[j].filename)
+			}
+			j++
+			return true
+		})
+		if j != i+1 {
+			t.Errorf("got %d files; want %d", j, i+1)
+		}
+	}
+}
+
+// FileSet.File should return nil if Pos is past the end of the FileSet.
+func TestFileSetPastEnd(t *testing.T) {
+	fset := NewFileSet()
+	for _, test := range tests {
+		fset.AddFile(test.filename, fset.Base(), test.size)
+	}
+	if f := fset.File(Pos(fset.Base())); f != nil {
+		t.Errorf("got %v, want nil", f)
+	}
+}
+
+func TestFileSetCacheUnlikely(t *testing.T) {
+	fset := NewFileSet()
+	offsets := make(map[string]int)
+	for _, test := range tests {
+		offsets[test.filename] = fset.Base()
+		fset.AddFile(test.filename, fset.Base(), test.size)
+	}
+	for file, pos := range offsets {
+		f := fset.File(Pos(pos))
+		if f.Name() != file {
+			t.Errorf("got %q at position %d, want %q", f.Name(), pos, file)
+		}
+	}
+}
+
+// issue 4345. Test concurrent use of FileSet.Pos does not trigger a
+// race in the FileSet position cache.
+func TestFileSetRace(t *testing.T) {
+	fset := NewFileSet()
+	for i := 0; i < 100; i++ {
+		fset.AddFile(fmt.Sprintf("file-%d", i), fset.Base(), 1031)
+	}
+	max := int32(fset.Base())
+	var stop sync.WaitGroup
+	r := rand.New(rand.NewSource(7))
+	for i := 0; i < 2; i++ {
+		r := rand.New(rand.NewSource(r.Int63()))
+		stop.Add(1)
+		go func() {
+			for i := 0; i < 1000; i++ {
+				fset.Position(Pos(r.Int31n(max)))
+			}
+			stop.Done()
+		}()
+	}
+	stop.Wait()
+}
+
+func TestPositionFor(t *testing.T) {
+	src := []byte(`
+foo
+b
+ar
+//line :100
+foobar
+//line bar:3
+done
+`)
+
+	const filename = "foo"
+	fset := NewFileSet()
+	f := fset.AddFile(filename, fset.Base(), len(src))
+	f.SetLinesForContent(src)
+
+	// verify position info
+	for i, offs := range f.lines {
+		got1 := f.PositionFor(f.Pos(offs), false)
+		got2 := f.PositionFor(f.Pos(offs), true)
+		got3 := f.Position(f.Pos(offs))
+		want := Position{filename, offs, i + 1, 1}
+		checkPos(t, "1. PositionFor unadjusted", got1, want)
+		checkPos(t, "1. PositionFor adjusted", got2, want)
+		checkPos(t, "1. Position", got3, want)
+	}
+
+	// manually add //line info on lines l1, l2
+	const l1, l2 = 5, 7
+	f.AddLineInfo(f.lines[l1-1], "", 100)
+	f.AddLineInfo(f.lines[l2-1], "bar", 3)
+
+	// unadjusted position info must remain unchanged
+	for i, offs := range f.lines {
+		got1 := f.PositionFor(f.Pos(offs), false)
+		want := Position{filename, offs, i + 1, 1}
+		checkPos(t, "2. PositionFor unadjusted", got1, want)
+	}
+
+	// adjusted position info should have changed
+	for i, offs := range f.lines {
+		got2 := f.PositionFor(f.Pos(offs), true)
+		got3 := f.Position(f.Pos(offs))
+		want := Position{filename, offs, i + 1, 1}
+		// manually compute wanted filename and line
+		line := want.Line
+		if i+1 >= l1 {
+			want.Filename = ""
+			want.Line = line - l1 + 100
+		}
+		if i+1 >= l2 {
+			want.Filename = "bar"
+			want.Line = line - l2 + 3
+		}
+		checkPos(t, "3. PositionFor adjusted", got2, want)
+		checkPos(t, "3. Position", got3, want)
+	}
+}
diff --git a/src/pkg/go/token/serialize.go b/src/go/token/serialize.go
similarity index 100%
rename from src/pkg/go/token/serialize.go
rename to src/go/token/serialize.go
diff --git a/src/pkg/go/token/serialize_test.go b/src/go/token/serialize_test.go
similarity index 100%
rename from src/pkg/go/token/serialize_test.go
rename to src/go/token/serialize_test.go
diff --git a/src/pkg/go/token/token.go b/src/go/token/token.go
similarity index 100%
rename from src/pkg/go/token/token.go
rename to src/go/token/token.go
diff --git a/src/pkg/hash/adler32/adler32.go b/src/hash/adler32/adler32.go
similarity index 100%
rename from src/pkg/hash/adler32/adler32.go
rename to src/hash/adler32/adler32.go
diff --git a/src/pkg/hash/adler32/adler32_test.go b/src/hash/adler32/adler32_test.go
similarity index 100%
rename from src/pkg/hash/adler32/adler32_test.go
rename to src/hash/adler32/adler32_test.go
diff --git a/src/hash/crc32/crc32.go b/src/hash/crc32/crc32.go
new file mode 100644
index 0000000..6a6b947
--- /dev/null
+++ b/src/hash/crc32/crc32.go
@@ -0,0 +1,135 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package crc32 implements the 32-bit cyclic redundancy check, or CRC-32,
+// checksum. See http://en.wikipedia.org/wiki/Cyclic_redundancy_check for
+// information.
+package crc32
+
+import (
+	"hash"
+	"sync"
+)
+
+// The size of a CRC-32 checksum in bytes.
+const Size = 4
+
+// Predefined polynomials.
+const (
+	// IEEE is by far and away the most common CRC-32 polynomial.
+	// Used by ethernet (IEEE 802.3), v.42, fddi, gzip, zip, png, ...
+	IEEE = 0xedb88320
+
+	// Castagnoli's polynomial, used in iSCSI.
+	// Has better error detection characteristics than IEEE.
+	// http://dx.doi.org/10.1109/26.231911
+	Castagnoli = 0x82f63b78
+
+	// Koopman's polynomial.
+	// Also has better error detection characteristics than IEEE.
+	// http://dx.doi.org/10.1109/DSN.2002.1028931
+	Koopman = 0xeb31d82e
+)
+
+// Table is a 256-word table representing the polynomial for efficient processing.
+type Table [256]uint32
+
+// castagnoliTable points to a lazily initialized Table for the Castagnoli
+// polynomial. MakeTable will always return this value when asked to make a
+// Castagnoli table so we can compare against it to find when the caller is
+// using this polynomial.
+var castagnoliTable *Table
+var castagnoliOnce sync.Once
+
+func castagnoliInit() {
+	castagnoliTable = makeTable(Castagnoli)
+}
+
+// IEEETable is the table for the IEEE polynomial.
+var IEEETable = makeTable(IEEE)
+
+// MakeTable returns the Table constructed from the specified polynomial.
+func MakeTable(poly uint32) *Table {
+	switch poly {
+	case IEEE:
+		return IEEETable
+	case Castagnoli:
+		castagnoliOnce.Do(castagnoliInit)
+		return castagnoliTable
+	}
+	return makeTable(poly)
+}
+
+// makeTable returns the Table constructed from the specified polynomial.
+func makeTable(poly uint32) *Table {
+	t := new(Table)
+	for i := 0; i < 256; i++ {
+		crc := uint32(i)
+		for j := 0; j < 8; j++ {
+			if crc&1 == 1 {
+				crc = (crc >> 1) ^ poly
+			} else {
+				crc >>= 1
+			}
+		}
+		t[i] = crc
+	}
+	return t
+}
+
+// digest represents the partial evaluation of a checksum.
+type digest struct {
+	crc uint32
+	tab *Table
+}
+
+// New creates a new hash.Hash32 computing the CRC-32 checksum
+// using the polynomial represented by the Table.
+func New(tab *Table) hash.Hash32 { return &digest{0, tab} }
+
+// NewIEEE creates a new hash.Hash32 computing the CRC-32 checksum
+// using the IEEE polynomial.
+func NewIEEE() hash.Hash32 { return New(IEEETable) }
+
+func (d *digest) Size() int { return Size }
+
+func (d *digest) BlockSize() int { return 1 }
+
+func (d *digest) Reset() { d.crc = 0 }
+
+func update(crc uint32, tab *Table, p []byte) uint32 {
+	crc = ^crc
+	for _, v := range p {
+		crc = tab[byte(crc)^v] ^ (crc >> 8)
+	}
+	return ^crc
+}
+
+// Update returns the result of adding the bytes in p to the crc.
+func Update(crc uint32, tab *Table, p []byte) uint32 {
+	if tab == castagnoliTable {
+		return updateCastagnoli(crc, p)
+	}
+	return update(crc, tab, p)
+}
+
+func (d *digest) Write(p []byte) (n int, err error) {
+	d.crc = Update(d.crc, d.tab, p)
+	return len(p), nil
+}
+
+func (d *digest) Sum32() uint32 { return d.crc }
+
+func (d *digest) Sum(in []byte) []byte {
+	s := d.Sum32()
+	return append(in, byte(s>>24), byte(s>>16), byte(s>>8), byte(s))
+}
+
+// Checksum returns the CRC-32 checksum of data
+// using the polynomial represented by the Table.
+func Checksum(data []byte, tab *Table) uint32 { return Update(0, tab, data) }
+
+// ChecksumIEEE returns the CRC-32 checksum of data
+// using the IEEE polynomial.
+func ChecksumIEEE(data []byte) uint32 { return update(0, IEEETable, data) }
diff --git a/src/hash/crc32/crc32_amd64.s b/src/hash/crc32/crc32_amd64.s
new file mode 100644
index 0000000..30b0d06
--- /dev/null
+++ b/src/hash/crc32/crc32_amd64.s
@@ -0,0 +1,64 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+// func castagnoliSSE42(crc uint32, p []byte) uint32
+TEXT ·castagnoliSSE42(SB),NOSPLIT,$0
+	MOVL crc+0(FP), AX  // CRC value
+	MOVQ p+8(FP), SI  // data pointer
+	MOVQ p_len+16(FP), CX  // len(p)
+
+	NOTL AX
+
+	/* If there's less than 8 bytes to process, we do it byte-by-byte. */
+	CMPQ CX, $8
+	JL cleanup
+
+	/* Process individual bytes until the input is 8-byte aligned. */
+startup:
+	MOVQ SI, BX
+	ANDQ $7, BX
+	JZ aligned
+
+	CRC32B (SI), AX
+	DECQ CX
+	INCQ SI
+	JMP startup
+
+aligned:
+	/* The input is now 8-byte aligned and we can process 8-byte chunks. */
+	CMPQ CX, $8
+	JL cleanup
+
+	CRC32Q (SI), AX
+	ADDQ $8, SI
+	SUBQ $8, CX
+	JMP aligned
+
+cleanup:
+	/* We may have some bytes left over that we process one at a time. */
+	CMPQ CX, $0
+	JE done
+
+	CRC32B (SI), AX
+	INCQ SI
+	DECQ CX
+	JMP cleanup
+
+done:
+	NOTL AX
+	MOVL AX, ret+32(FP)
+	RET
+
+// func haveSSE42() bool
+TEXT ·haveSSE42(SB),NOSPLIT,$0
+	XORQ AX, AX
+	INCL AX
+	CPUID
+	SHRQ $20, CX
+	ANDQ $1, CX
+	MOVB CX, ret+0(FP)
+	RET
+
diff --git a/src/hash/crc32/crc32_amd64p32.s b/src/hash/crc32/crc32_amd64p32.s
new file mode 100644
index 0000000..b6770eb
--- /dev/null
+++ b/src/hash/crc32/crc32_amd64p32.s
@@ -0,0 +1,64 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+// func castagnoliSSE42(crc uint32, p []byte) uint32
+TEXT ·castagnoliSSE42(SB),NOSPLIT,$0
+	MOVL crc+0(FP), AX  // CRC value
+	MOVL p+4(FP), SI  // data pointer
+	MOVL p_len+8(FP), CX  // len(p)
+
+	NOTL AX
+
+	/* If there's less than 8 bytes to process, we do it byte-by-byte. */
+	CMPQ CX, $8
+	JL cleanup
+
+	/* Process individual bytes until the input is 8-byte aligned. */
+startup:
+	MOVQ SI, BX
+	ANDQ $7, BX
+	JZ aligned
+
+	CRC32B (SI), AX
+	DECQ CX
+	INCQ SI
+	JMP startup
+
+aligned:
+	/* The input is now 8-byte aligned and we can process 8-byte chunks. */
+	CMPQ CX, $8
+	JL cleanup
+
+	CRC32Q (SI), AX
+	ADDQ $8, SI
+	SUBQ $8, CX
+	JMP aligned
+
+cleanup:
+	/* We may have some bytes left over that we process one at a time. */
+	CMPQ CX, $0
+	JE done
+
+	CRC32B (SI), AX
+	INCQ SI
+	DECQ CX
+	JMP cleanup
+
+done:
+	NOTL AX
+	MOVL AX, ret+16(FP)
+	RET
+
+// func haveSSE42() bool
+TEXT ·haveSSE42(SB),NOSPLIT,$0
+	XORQ AX, AX
+	INCL AX
+	CPUID
+	SHRQ $20, CX
+	ANDQ $1, CX
+	MOVB CX, ret+0(FP)
+	RET
+
diff --git a/src/pkg/hash/crc32/crc32_amd64x.go b/src/hash/crc32/crc32_amd64x.go
similarity index 100%
rename from src/pkg/hash/crc32/crc32_amd64x.go
rename to src/hash/crc32/crc32_amd64x.go
diff --git a/src/pkg/hash/crc32/crc32_generic.go b/src/hash/crc32/crc32_generic.go
similarity index 100%
rename from src/pkg/hash/crc32/crc32_generic.go
rename to src/hash/crc32/crc32_generic.go
diff --git a/src/pkg/hash/crc32/crc32_test.go b/src/hash/crc32/crc32_test.go
similarity index 100%
rename from src/pkg/hash/crc32/crc32_test.go
rename to src/hash/crc32/crc32_test.go
diff --git a/src/pkg/hash/crc64/crc64.go b/src/hash/crc64/crc64.go
similarity index 100%
rename from src/pkg/hash/crc64/crc64.go
rename to src/hash/crc64/crc64.go
diff --git a/src/pkg/hash/crc64/crc64_test.go b/src/hash/crc64/crc64_test.go
similarity index 100%
rename from src/pkg/hash/crc64/crc64_test.go
rename to src/hash/crc64/crc64_test.go
diff --git a/src/pkg/hash/fnv/fnv.go b/src/hash/fnv/fnv.go
similarity index 100%
rename from src/pkg/hash/fnv/fnv.go
rename to src/hash/fnv/fnv.go
diff --git a/src/pkg/hash/fnv/fnv_test.go b/src/hash/fnv/fnv_test.go
similarity index 100%
rename from src/pkg/hash/fnv/fnv_test.go
rename to src/hash/fnv/fnv_test.go
diff --git a/src/pkg/hash/hash.go b/src/hash/hash.go
similarity index 100%
rename from src/pkg/hash/hash.go
rename to src/hash/hash.go
diff --git a/src/pkg/hash/test_cases.txt b/src/hash/test_cases.txt
similarity index 100%
rename from src/pkg/hash/test_cases.txt
rename to src/hash/test_cases.txt
diff --git a/src/pkg/hash/test_gen.awk b/src/hash/test_gen.awk
similarity index 100%
rename from src/pkg/hash/test_gen.awk
rename to src/hash/test_gen.awk
diff --git a/src/pkg/html/entity.go b/src/html/entity.go
similarity index 100%
rename from src/pkg/html/entity.go
rename to src/html/entity.go
diff --git a/src/pkg/html/entity_test.go b/src/html/entity_test.go
similarity index 100%
rename from src/pkg/html/entity_test.go
rename to src/html/entity_test.go
diff --git a/src/pkg/html/escape.go b/src/html/escape.go
similarity index 100%
rename from src/pkg/html/escape.go
rename to src/html/escape.go
diff --git a/src/pkg/html/escape_test.go b/src/html/escape_test.go
similarity index 100%
rename from src/pkg/html/escape_test.go
rename to src/html/escape_test.go
diff --git a/src/pkg/html/template/attr.go b/src/html/template/attr.go
similarity index 100%
rename from src/pkg/html/template/attr.go
rename to src/html/template/attr.go
diff --git a/src/pkg/html/template/clone_test.go b/src/html/template/clone_test.go
similarity index 100%
rename from src/pkg/html/template/clone_test.go
rename to src/html/template/clone_test.go
diff --git a/src/pkg/html/template/content.go b/src/html/template/content.go
similarity index 100%
rename from src/pkg/html/template/content.go
rename to src/html/template/content.go
diff --git a/src/pkg/html/template/content_test.go b/src/html/template/content_test.go
similarity index 100%
rename from src/pkg/html/template/content_test.go
rename to src/html/template/content_test.go
diff --git a/src/pkg/html/template/context.go b/src/html/template/context.go
similarity index 100%
rename from src/pkg/html/template/context.go
rename to src/html/template/context.go
diff --git a/src/pkg/html/template/css.go b/src/html/template/css.go
similarity index 100%
rename from src/pkg/html/template/css.go
rename to src/html/template/css.go
diff --git a/src/pkg/html/template/css_test.go b/src/html/template/css_test.go
similarity index 100%
rename from src/pkg/html/template/css_test.go
rename to src/html/template/css_test.go
diff --git a/src/pkg/html/template/doc.go b/src/html/template/doc.go
similarity index 100%
rename from src/pkg/html/template/doc.go
rename to src/html/template/doc.go
diff --git a/src/html/template/error.go b/src/html/template/error.go
new file mode 100644
index 0000000..8f99e1b
--- /dev/null
+++ b/src/html/template/error.go
@@ -0,0 +1,205 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package template
+
+import (
+	"fmt"
+	"text/template/parse"
+)
+
+// Error describes a problem encountered during template Escaping.
+type Error struct {
+	// ErrorCode describes the kind of error.
+	ErrorCode ErrorCode
+	// Node is the node that caused the problem, if known.
+	// If not nil, it overrides Name and Line.
+	Node parse.Node
+	// Name is the name of the template in which the error was encountered.
+	Name string
+	// Line is the line number of the error in the template source or 0.
+	Line int
+	// Description is a human-readable description of the problem.
+	Description string
+}
+
+// ErrorCode is a code for a kind of error.
+type ErrorCode int
+
+// We define codes for each error that manifests while escaping templates, but
+// escaped templates may also fail at runtime.
+//
+// Output: "ZgotmplZ"
+// Example:
+//   <img src="{{.X}}">
+//   where {{.X}} evaluates to `javascript:...`
+// Discussion:
+//   "ZgotmplZ" is a special value that indicates that unsafe content reached a
+//   CSS or URL context at runtime. The output of the example will be
+//     <img src="#ZgotmplZ">
+//   If the data comes from a trusted source, use content types to exempt it
+//   from filtering: URL(`javascript:...`).
+const (
+	// OK indicates the lack of an error.
+	OK ErrorCode = iota
+
+	// ErrAmbigContext: "... appears in an ambiguous URL context"
+	// Example:
+	//   <a href="
+	//      {{if .C}}
+	//        /path/
+	//      {{else}}
+	//        /search?q=
+	//      {{end}}
+	//      {{.X}}
+	//   ">
+	// Discussion:
+	//   {{.X}} is in an ambiguous URL context since, depending on {{.C}},
+	//  it may be either a URL suffix or a query parameter.
+	//   Moving {{.X}} into the condition removes the ambiguity:
+	//   <a href="{{if .C}}/path/{{.X}}{{else}}/search?q={{.X}}">
+	ErrAmbigContext
+
+	// ErrBadHTML: "expected space, attr name, or end of tag, but got ...",
+	//   "... in unquoted attr", "... in attribute name"
+	// Example:
+	//   <a href = /search?q=foo>
+	//   <href=foo>
+	//   <form na<e=...>
+	//   <option selected<
+	// Discussion:
+	//   This is often due to a typo in an HTML element, but some runes
+	//   are banned in tag names, attribute names, and unquoted attribute
+	//   values because they can tickle parser ambiguities.
+	//   Quoting all attributes is the best policy.
+	ErrBadHTML
+
+	// ErrBranchEnd: "{{if}} branches end in different contexts"
+	// Example:
+	//   {{if .C}}<a href="{{end}}{{.X}}
+	// Discussion:
+	//   Package html/template statically examines each path through an
+	//   {{if}}, {{range}}, or {{with}} to escape any following pipelines.
+	//   The example is ambiguous since {{.X}} might be an HTML text node,
+	//   or a URL prefix in an HTML attribute. The context of {{.X}} is
+	//   used to figure out how to escape it, but that context depends on
+	//   the run-time value of {{.C}} which is not statically known.
+	//
+	//   The problem is usually something like missing quotes or angle
+	//   brackets, or can be avoided by refactoring to put the two contexts
+	//   into different branches of an if, range or with. If the problem
+	//   is in a {{range}} over a collection that should never be empty,
+	//   adding a dummy {{else}} can help.
+	ErrBranchEnd
+
+	// ErrEndContext: "... ends in a non-text context: ..."
+	// Examples:
+	//   <div
+	//   <div title="no close quote>
+	//   <script>f()
+	// Discussion:
+	//   Executed templates should produce a DocumentFragment of HTML.
+	//   Templates that end without closing tags will trigger this error.
+	//   Templates that should not be used in an HTML context or that
+	//   produce incomplete Fragments should not be executed directly.
+	//
+	//   {{define "main"}} <script>{{template "helper"}}</script> {{end}}
+	//   {{define "helper"}} document.write(' <div title=" ') {{end}}
+	//
+	//   "helper" does not produce a valid document fragment, so should
+	//   not be Executed directly.
+	ErrEndContext
+
+	// ErrNoSuchTemplate: "no such template ..."
+	// Examples:
+	//   {{define "main"}}<div {{template "attrs"}}>{{end}}
+	//   {{define "attrs"}}href="{{.URL}}"{{end}}
+	// Discussion:
+	//   Package html/template looks through template calls to compute the
+	//   context.
+	//   Here the {{.URL}} in "attrs" must be treated as a URL when called
+	//   from "main", but you will get this error if "attrs" is not defined
+	//   when "main" is parsed.
+	ErrNoSuchTemplate
+
+	// ErrOutputContext: "cannot compute output context for template ..."
+	// Examples:
+	//   {{define "t"}}{{if .T}}{{template "t" .T}}{{end}}{{.H}}",{{end}}
+	// Discussion:
+	//   A recursive template does not end in the same context in which it
+	//   starts, and a reliable output context cannot be computed.
+	//   Look for typos in the named template.
+	//   If the template should not be called in the named start context,
+	//   look for calls to that template in unexpected contexts.
+	//   Maybe refactor recursive templates to not be recursive.
+	ErrOutputContext
+
+	// ErrPartialCharset: "unfinished JS regexp charset in ..."
+	// Example:
+	//     <script>var pattern = /foo[{{.Chars}}]/</script>
+	// Discussion:
+	//   Package html/template does not support interpolation into regular
+	//   expression literal character sets.
+	ErrPartialCharset
+
+	// ErrPartialEscape: "unfinished escape sequence in ..."
+	// Example:
+	//   <script>alert("\{{.X}}")</script>
+	// Discussion:
+	//   Package html/template does not support actions following a
+	//   backslash.
+	//   This is usually an error and there are better solutions; for
+	//   example
+	//     <script>alert("{{.X}}")</script>
+	//   should work, and if {{.X}} is a partial escape sequence such as
+	//   "xA0", mark the whole sequence as safe content: JSStr(`\xA0`)
+	ErrPartialEscape
+
+	// ErrRangeLoopReentry: "on range loop re-entry: ..."
+	// Example:
+	//   <script>var x = [{{range .}}'{{.}},{{end}}]</script>
+	// Discussion:
+	//   If an iteration through a range would cause it to end in a
+	//   different context than an earlier pass, there is no single context.
+	//   In the example, there is missing a quote, so it is not clear
+	//   whether {{.}} is meant to be inside a JS string or in a JS value
+	//   context.  The second iteration would produce something like
+	//
+	//     <script>var x = ['firstValue,'secondValue]</script>
+	ErrRangeLoopReentry
+
+	// ErrSlashAmbig: '/' could start a division or regexp.
+	// Example:
+	//   <script>
+	//     {{if .C}}var x = 1{{end}}
+	//     /-{{.N}}/i.test(x) ? doThis : doThat();
+	//   </script>
+	// Discussion:
+	//   The example above could produce `var x = 1/-2/i.test(s)...`
+	//   in which the first '/' is a mathematical division operator or it
+	//   could produce `/-2/i.test(s)` in which the first '/' starts a
+	//   regexp literal.
+	//   Look for missing semicolons inside branches, and maybe add
+	//   parentheses to make it clear which interpretation you intend.
+	ErrSlashAmbig
+)
+
+func (e *Error) Error() string {
+	switch {
+	case e.Node != nil:
+		loc, _ := (*parse.Tree)(nil).ErrorContext(e.Node)
+		return fmt.Sprintf("html/template:%s: %s", loc, e.Description)
+	case e.Line != 0:
+		return fmt.Sprintf("html/template:%s:%d: %s", e.Name, e.Line, e.Description)
+	case e.Name != "":
+		return fmt.Sprintf("html/template:%s: %s", e.Name, e.Description)
+	}
+	return "html/template: " + e.Description
+}
+
+// errorf creates an error given a format string f and args.
+// The template Name still needs to be supplied.
+func errorf(k ErrorCode, node parse.Node, line int, f string, args ...interface{}) *Error {
+	return &Error{k, node, "", line, fmt.Sprintf(f, args...)}
+}
diff --git a/src/html/template/escape.go b/src/html/template/escape.go
new file mode 100644
index 0000000..ee01fb1
--- /dev/null
+++ b/src/html/template/escape.go
@@ -0,0 +1,807 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package template
+
+import (
+	"bytes"
+	"fmt"
+	"html"
+	"io"
+	"text/template"
+	"text/template/parse"
+)
+
+// escapeTemplate rewrites the named template, which must be
+// associated with t, to guarantee that the output of any of the named
+// templates is properly escaped.  If no error is returned, then the named templates have
+// been modified.  Otherwise the named templates have been rendered
+// unusable.
+func escapeTemplate(tmpl *Template, node parse.Node, name string) error {
+	e := newEscaper(tmpl)
+	c, _ := e.escapeTree(context{}, node, name, 0)
+	var err error
+	if c.err != nil {
+		err, c.err.Name = c.err, name
+	} else if c.state != stateText {
+		err = &Error{ErrEndContext, nil, name, 0, fmt.Sprintf("ends in a non-text context: %v", c)}
+	}
+	if err != nil {
+		// Prevent execution of unsafe templates.
+		if t := tmpl.set[name]; t != nil {
+			t.escapeErr = err
+			t.text.Tree = nil
+			t.Tree = nil
+		}
+		return err
+	}
+	e.commit()
+	if t := tmpl.set[name]; t != nil {
+		t.escapeErr = escapeOK
+		t.Tree = t.text.Tree
+	}
+	return nil
+}
+
+// funcMap maps command names to functions that render their inputs safe.
+var funcMap = template.FuncMap{
+	"html_template_attrescaper":     attrEscaper,
+	"html_template_commentescaper":  commentEscaper,
+	"html_template_cssescaper":      cssEscaper,
+	"html_template_cssvaluefilter":  cssValueFilter,
+	"html_template_htmlnamefilter":  htmlNameFilter,
+	"html_template_htmlescaper":     htmlEscaper,
+	"html_template_jsregexpescaper": jsRegexpEscaper,
+	"html_template_jsstrescaper":    jsStrEscaper,
+	"html_template_jsvalescaper":    jsValEscaper,
+	"html_template_nospaceescaper":  htmlNospaceEscaper,
+	"html_template_rcdataescaper":   rcdataEscaper,
+	"html_template_urlescaper":      urlEscaper,
+	"html_template_urlfilter":       urlFilter,
+	"html_template_urlnormalizer":   urlNormalizer,
+}
+
+// equivEscapers matches contextual escapers to equivalent template builtins.
+var equivEscapers = map[string]string{
+	"html_template_attrescaper":    "html",
+	"html_template_htmlescaper":    "html",
+	"html_template_nospaceescaper": "html",
+	"html_template_rcdataescaper":  "html",
+	"html_template_urlescaper":     "urlquery",
+	"html_template_urlnormalizer":  "urlquery",
+}
+
+// escaper collects type inferences about templates and changes needed to make
+// templates injection safe.
+type escaper struct {
+	tmpl *Template
+	// output[templateName] is the output context for a templateName that
+	// has been mangled to include its input context.
+	output map[string]context
+	// derived[c.mangle(name)] maps to a template derived from the template
+	// named name templateName for the start context c.
+	derived map[string]*template.Template
+	// called[templateName] is a set of called mangled template names.
+	called map[string]bool
+	// xxxNodeEdits are the accumulated edits to apply during commit.
+	// Such edits are not applied immediately in case a template set
+	// executes a given template in different escaping contexts.
+	actionNodeEdits   map[*parse.ActionNode][]string
+	templateNodeEdits map[*parse.TemplateNode]string
+	textNodeEdits     map[*parse.TextNode][]byte
+}
+
+// newEscaper creates a blank escaper for the given set.
+func newEscaper(t *Template) *escaper {
+	return &escaper{
+		t,
+		map[string]context{},
+		map[string]*template.Template{},
+		map[string]bool{},
+		map[*parse.ActionNode][]string{},
+		map[*parse.TemplateNode]string{},
+		map[*parse.TextNode][]byte{},
+	}
+}
+
+// filterFailsafe is an innocuous word that is emitted in place of unsafe values
+// by sanitizer functions. It is not a keyword in any programming language,
+// contains no special characters, is not empty, and when it appears in output
+// it is distinct enough that a developer can find the source of the problem
+// via a search engine.
+const filterFailsafe = "ZgotmplZ"
+
+// escape escapes a template node.
+func (e *escaper) escape(c context, n parse.Node) context {
+	switch n := n.(type) {
+	case *parse.ActionNode:
+		return e.escapeAction(c, n)
+	case *parse.IfNode:
+		return e.escapeBranch(c, &n.BranchNode, "if")
+	case *parse.ListNode:
+		return e.escapeList(c, n)
+	case *parse.RangeNode:
+		return e.escapeBranch(c, &n.BranchNode, "range")
+	case *parse.TemplateNode:
+		return e.escapeTemplate(c, n)
+	case *parse.TextNode:
+		return e.escapeText(c, n)
+	case *parse.WithNode:
+		return e.escapeBranch(c, &n.BranchNode, "with")
+	}
+	panic("escaping " + n.String() + " is unimplemented")
+}
+
+// escapeAction escapes an action template node.
+func (e *escaper) escapeAction(c context, n *parse.ActionNode) context {
+	if len(n.Pipe.Decl) != 0 {
+		// A local variable assignment, not an interpolation.
+		return c
+	}
+	c = nudge(c)
+	s := make([]string, 0, 3)
+	switch c.state {
+	case stateError:
+		return c
+	case stateURL, stateCSSDqStr, stateCSSSqStr, stateCSSDqURL, stateCSSSqURL, stateCSSURL:
+		switch c.urlPart {
+		case urlPartNone:
+			s = append(s, "html_template_urlfilter")
+			fallthrough
+		case urlPartPreQuery:
+			switch c.state {
+			case stateCSSDqStr, stateCSSSqStr:
+				s = append(s, "html_template_cssescaper")
+			default:
+				s = append(s, "html_template_urlnormalizer")
+			}
+		case urlPartQueryOrFrag:
+			s = append(s, "html_template_urlescaper")
+		case urlPartUnknown:
+			return context{
+				state: stateError,
+				err:   errorf(ErrAmbigContext, n, n.Line, "%s appears in an ambiguous URL context", n),
+			}
+		default:
+			panic(c.urlPart.String())
+		}
+	case stateJS:
+		s = append(s, "html_template_jsvalescaper")
+		// A slash after a value starts a div operator.
+		c.jsCtx = jsCtxDivOp
+	case stateJSDqStr, stateJSSqStr:
+		s = append(s, "html_template_jsstrescaper")
+	case stateJSRegexp:
+		s = append(s, "html_template_jsregexpescaper")
+	case stateCSS:
+		s = append(s, "html_template_cssvaluefilter")
+	case stateText:
+		s = append(s, "html_template_htmlescaper")
+	case stateRCDATA:
+		s = append(s, "html_template_rcdataescaper")
+	case stateAttr:
+		// Handled below in delim check.
+	case stateAttrName, stateTag:
+		c.state = stateAttrName
+		s = append(s, "html_template_htmlnamefilter")
+	default:
+		if isComment(c.state) {
+			s = append(s, "html_template_commentescaper")
+		} else {
+			panic("unexpected state " + c.state.String())
+		}
+	}
+	switch c.delim {
+	case delimNone:
+		// No extra-escaping needed for raw text content.
+	case delimSpaceOrTagEnd:
+		s = append(s, "html_template_nospaceescaper")
+	default:
+		s = append(s, "html_template_attrescaper")
+	}
+	e.editActionNode(n, s)
+	return c
+}
+
+// allIdents returns the names of the identifiers under the Ident field of the node,
+// which might be a singleton (Identifier) or a slice (Field).
+func allIdents(node parse.Node) []string {
+	switch node := node.(type) {
+	case *parse.IdentifierNode:
+		return []string{node.Ident}
+	case *parse.FieldNode:
+		return node.Ident
+	}
+	panic("unidentified node type in allIdents")
+}
+
+// ensurePipelineContains ensures that the pipeline has commands with
+// the identifiers in s in order.
+// If the pipeline already has some of the sanitizers, do not interfere.
+// For example, if p is (.X | html) and s is ["escapeJSVal", "html"] then it
+// has one matching, "html", and one to insert, "escapeJSVal", to produce
+// (.X | escapeJSVal | html).
+func ensurePipelineContains(p *parse.PipeNode, s []string) {
+	if len(s) == 0 {
+		return
+	}
+	n := len(p.Cmds)
+	// Find the identifiers at the end of the command chain.
+	idents := p.Cmds
+	for i := n - 1; i >= 0; i-- {
+		if cmd := p.Cmds[i]; len(cmd.Args) != 0 {
+			if _, ok := cmd.Args[0].(*parse.IdentifierNode); ok {
+				continue
+			}
+		}
+		idents = p.Cmds[i+1:]
+	}
+	dups := 0
+	for _, idNode := range idents {
+		for _, ident := range allIdents(idNode.Args[0]) {
+			if escFnsEq(s[dups], ident) {
+				dups++
+				if dups == len(s) {
+					return
+				}
+			}
+		}
+	}
+	newCmds := make([]*parse.CommandNode, n-len(idents), n+len(s)-dups)
+	copy(newCmds, p.Cmds)
+	// Merge existing identifier commands with the sanitizers needed.
+	for _, idNode := range idents {
+		pos := idNode.Args[0].Position()
+		for _, ident := range allIdents(idNode.Args[0]) {
+			i := indexOfStr(ident, s, escFnsEq)
+			if i != -1 {
+				for _, name := range s[:i] {
+					newCmds = appendCmd(newCmds, newIdentCmd(name, pos))
+				}
+				s = s[i+1:]
+			}
+		}
+		newCmds = appendCmd(newCmds, idNode)
+	}
+	// Create any remaining sanitizers.
+	for _, name := range s {
+		newCmds = appendCmd(newCmds, newIdentCmd(name, p.Position()))
+	}
+	p.Cmds = newCmds
+}
+
+// redundantFuncs[a][b] implies that funcMap[b](funcMap[a](x)) == funcMap[a](x)
+// for all x.
+var redundantFuncs = map[string]map[string]bool{
+	"html_template_commentescaper": {
+		"html_template_attrescaper":    true,
+		"html_template_nospaceescaper": true,
+		"html_template_htmlescaper":    true,
+	},
+	"html_template_cssescaper": {
+		"html_template_attrescaper": true,
+	},
+	"html_template_jsregexpescaper": {
+		"html_template_attrescaper": true,
+	},
+	"html_template_jsstrescaper": {
+		"html_template_attrescaper": true,
+	},
+	"html_template_urlescaper": {
+		"html_template_urlnormalizer": true,
+	},
+}
+
+// appendCmd appends the given command to the end of the command pipeline
+// unless it is redundant with the last command.
+func appendCmd(cmds []*parse.CommandNode, cmd *parse.CommandNode) []*parse.CommandNode {
+	if n := len(cmds); n != 0 {
+		last, ok := cmds[n-1].Args[0].(*parse.IdentifierNode)
+		next, _ := cmd.Args[0].(*parse.IdentifierNode)
+		if ok && redundantFuncs[last.Ident][next.Ident] {
+			return cmds
+		}
+	}
+	return append(cmds, cmd)
+}
+
+// indexOfStr is the first i such that eq(s, strs[i]) or -1 if s was not found.
+func indexOfStr(s string, strs []string, eq func(a, b string) bool) int {
+	for i, t := range strs {
+		if eq(s, t) {
+			return i
+		}
+	}
+	return -1
+}
+
+// escFnsEq reports whether the two escaping functions are equivalent.
+func escFnsEq(a, b string) bool {
+	if e := equivEscapers[a]; e != "" {
+		a = e
+	}
+	if e := equivEscapers[b]; e != "" {
+		b = e
+	}
+	return a == b
+}
+
+// newIdentCmd produces a command containing a single identifier node.
+func newIdentCmd(identifier string, pos parse.Pos) *parse.CommandNode {
+	return &parse.CommandNode{
+		NodeType: parse.NodeCommand,
+		Args:     []parse.Node{parse.NewIdentifier(identifier).SetTree(nil).SetPos(pos)}, // TODO: SetTree.
+	}
+}
+
+// nudge returns the context that would result from following empty string
+// transitions from the input context.
+// For example, parsing:
+//     `<a href=`
+// will end in context{stateBeforeValue, attrURL}, but parsing one extra rune:
+//     `<a href=x`
+// will end in context{stateURL, delimSpaceOrTagEnd, ...}.
+// There are two transitions that happen when the 'x' is seen:
+// (1) Transition from a before-value state to a start-of-value state without
+//     consuming any character.
+// (2) Consume 'x' and transition past the first value character.
+// In this case, nudging produces the context after (1) happens.
+func nudge(c context) context {
+	switch c.state {
+	case stateTag:
+		// In `<foo {{.}}`, the action should emit an attribute.
+		c.state = stateAttrName
+	case stateBeforeValue:
+		// In `<foo bar={{.}}`, the action is an undelimited value.
+		c.state, c.delim, c.attr = attrStartStates[c.attr], delimSpaceOrTagEnd, attrNone
+	case stateAfterName:
+		// In `<foo bar {{.}}`, the action is an attribute name.
+		c.state, c.attr = stateAttrName, attrNone
+	}
+	return c
+}
+
+// join joins the two contexts of a branch template node. The result is an
+// error context if either of the input contexts are error contexts, or if the
+// the input contexts differ.
+func join(a, b context, node parse.Node, nodeName string) context {
+	if a.state == stateError {
+		return a
+	}
+	if b.state == stateError {
+		return b
+	}
+	if a.eq(b) {
+		return a
+	}
+
+	c := a
+	c.urlPart = b.urlPart
+	if c.eq(b) {
+		// The contexts differ only by urlPart.
+		c.urlPart = urlPartUnknown
+		return c
+	}
+
+	c = a
+	c.jsCtx = b.jsCtx
+	if c.eq(b) {
+		// The contexts differ only by jsCtx.
+		c.jsCtx = jsCtxUnknown
+		return c
+	}
+
+	// Allow a nudged context to join with an unnudged one.
+	// This means that
+	//   <p title={{if .C}}{{.}}{{end}}
+	// ends in an unquoted value state even though the else branch
+	// ends in stateBeforeValue.
+	if c, d := nudge(a), nudge(b); !(c.eq(a) && d.eq(b)) {
+		if e := join(c, d, node, nodeName); e.state != stateError {
+			return e
+		}
+	}
+
+	return context{
+		state: stateError,
+		err:   errorf(ErrBranchEnd, node, 0, "{{%s}} branches end in different contexts: %v, %v", nodeName, a, b),
+	}
+}
+
+// escapeBranch escapes a branch template node: "if", "range" and "with".
+func (e *escaper) escapeBranch(c context, n *parse.BranchNode, nodeName string) context {
+	c0 := e.escapeList(c, n.List)
+	if nodeName == "range" && c0.state != stateError {
+		// The "true" branch of a "range" node can execute multiple times.
+		// We check that executing n.List once results in the same context
+		// as executing n.List twice.
+		c1, _ := e.escapeListConditionally(c0, n.List, nil)
+		c0 = join(c0, c1, n, nodeName)
+		if c0.state == stateError {
+			// Make clear that this is a problem on loop re-entry
+			// since developers tend to overlook that branch when
+			// debugging templates.
+			c0.err.Line = n.Line
+			c0.err.Description = "on range loop re-entry: " + c0.err.Description
+			return c0
+		}
+	}
+	c1 := e.escapeList(c, n.ElseList)
+	return join(c0, c1, n, nodeName)
+}
+
+// escapeList escapes a list template node.
+func (e *escaper) escapeList(c context, n *parse.ListNode) context {
+	if n == nil {
+		return c
+	}
+	for _, m := range n.Nodes {
+		c = e.escape(c, m)
+	}
+	return c
+}
+
+// escapeListConditionally escapes a list node but only preserves edits and
+// inferences in e if the inferences and output context satisfy filter.
+// It returns the best guess at an output context, and the result of the filter
+// which is the same as whether e was updated.
+func (e *escaper) escapeListConditionally(c context, n *parse.ListNode, filter func(*escaper, context) bool) (context, bool) {
+	e1 := newEscaper(e.tmpl)
+	// Make type inferences available to f.
+	for k, v := range e.output {
+		e1.output[k] = v
+	}
+	c = e1.escapeList(c, n)
+	ok := filter != nil && filter(e1, c)
+	if ok {
+		// Copy inferences and edits from e1 back into e.
+		for k, v := range e1.output {
+			e.output[k] = v
+		}
+		for k, v := range e1.derived {
+			e.derived[k] = v
+		}
+		for k, v := range e1.called {
+			e.called[k] = v
+		}
+		for k, v := range e1.actionNodeEdits {
+			e.editActionNode(k, v)
+		}
+		for k, v := range e1.templateNodeEdits {
+			e.editTemplateNode(k, v)
+		}
+		for k, v := range e1.textNodeEdits {
+			e.editTextNode(k, v)
+		}
+	}
+	return c, ok
+}
+
+// escapeTemplate escapes a {{template}} call node.
+func (e *escaper) escapeTemplate(c context, n *parse.TemplateNode) context {
+	c, name := e.escapeTree(c, n, n.Name, n.Line)
+	if name != n.Name {
+		e.editTemplateNode(n, name)
+	}
+	return c
+}
+
+// escapeTree escapes the named template starting in the given context as
+// necessary and returns its output context.
+func (e *escaper) escapeTree(c context, node parse.Node, name string, line int) (context, string) {
+	// Mangle the template name with the input context to produce a reliable
+	// identifier.
+	dname := c.mangle(name)
+	e.called[dname] = true
+	if out, ok := e.output[dname]; ok {
+		// Already escaped.
+		return out, dname
+	}
+	t := e.template(name)
+	if t == nil {
+		// Two cases: The template exists but is empty, or has never been mentioned at
+		// all. Distinguish the cases in the error messages.
+		if e.tmpl.set[name] != nil {
+			return context{
+				state: stateError,
+				err:   errorf(ErrNoSuchTemplate, node, line, "%q is an incomplete or empty template", name),
+			}, dname
+		}
+		return context{
+			state: stateError,
+			err:   errorf(ErrNoSuchTemplate, node, line, "no such template %q", name),
+		}, dname
+	}
+	if dname != name {
+		// Use any template derived during an earlier call to escapeTemplate
+		// with different top level templates, or clone if necessary.
+		dt := e.template(dname)
+		if dt == nil {
+			dt = template.New(dname)
+			dt.Tree = &parse.Tree{Name: dname, Root: t.Root.CopyList()}
+			e.derived[dname] = dt
+		}
+		t = dt
+	}
+	return e.computeOutCtx(c, t), dname
+}
+
+// computeOutCtx takes a template and its start context and computes the output
+// context while storing any inferences in e.
+func (e *escaper) computeOutCtx(c context, t *template.Template) context {
+	// Propagate context over the body.
+	c1, ok := e.escapeTemplateBody(c, t)
+	if !ok {
+		// Look for a fixed point by assuming c1 as the output context.
+		if c2, ok2 := e.escapeTemplateBody(c1, t); ok2 {
+			c1, ok = c2, true
+		}
+		// Use c1 as the error context if neither assumption worked.
+	}
+	if !ok && c1.state != stateError {
+		return context{
+			state: stateError,
+			err:   errorf(ErrOutputContext, t.Tree.Root, 0, "cannot compute output context for template %s", t.Name()),
+		}
+	}
+	return c1
+}
+
+// escapeTemplateBody escapes the given template assuming the given output
+// context, and returns the best guess at the output context and whether the
+// assumption was correct.
+func (e *escaper) escapeTemplateBody(c context, t *template.Template) (context, bool) {
+	filter := func(e1 *escaper, c1 context) bool {
+		if c1.state == stateError {
+			// Do not update the input escaper, e.
+			return false
+		}
+		if !e1.called[t.Name()] {
+			// If t is not recursively called, then c1 is an
+			// accurate output context.
+			return true
+		}
+		// c1 is accurate if it matches our assumed output context.
+		return c.eq(c1)
+	}
+	// We need to assume an output context so that recursive template calls
+	// take the fast path out of escapeTree instead of infinitely recursing.
+	// Naively assuming that the input context is the same as the output
+	// works >90% of the time.
+	e.output[t.Name()] = c
+	return e.escapeListConditionally(c, t.Tree.Root, filter)
+}
+
+// delimEnds maps each delim to a string of characters that terminate it.
+var delimEnds = [...]string{
+	delimDoubleQuote: `"`,
+	delimSingleQuote: "'",
+	// Determined empirically by running the below in various browsers.
+	// var div = document.createElement("DIV");
+	// for (var i = 0; i < 0x10000; ++i) {
+	//   div.innerHTML = "<span title=x" + String.fromCharCode(i) + "-bar>";
+	//   if (div.getElementsByTagName("SPAN")[0].title.indexOf("bar") < 0)
+	//     document.write("<p>U+" + i.toString(16));
+	// }
+	delimSpaceOrTagEnd: " \t\n\f\r>",
+}
+
+var doctypeBytes = []byte("<!DOCTYPE")
+
+// escapeText escapes a text template node.
+func (e *escaper) escapeText(c context, n *parse.TextNode) context {
+	s, written, i, b := n.Text, 0, 0, new(bytes.Buffer)
+	for i != len(s) {
+		c1, nread := contextAfterText(c, s[i:])
+		i1 := i + nread
+		if c.state == stateText || c.state == stateRCDATA {
+			end := i1
+			if c1.state != c.state {
+				for j := end - 1; j >= i; j-- {
+					if s[j] == '<' {
+						end = j
+						break
+					}
+				}
+			}
+			for j := i; j < end; j++ {
+				if s[j] == '<' && !bytes.HasPrefix(bytes.ToUpper(s[j:]), doctypeBytes) {
+					b.Write(s[written:j])
+					b.WriteString("<")
+					written = j + 1
+				}
+			}
+		} else if isComment(c.state) && c.delim == delimNone {
+			switch c.state {
+			case stateJSBlockCmt:
+				// http://es5.github.com/#x7.4:
+				// "Comments behave like white space and are
+				// discarded except that, if a MultiLineComment
+				// contains a line terminator character, then
+				// the entire comment is considered to be a
+				// LineTerminator for purposes of parsing by
+				// the syntactic grammar."
+				if bytes.IndexAny(s[written:i1], "\n\r\u2028\u2029") != -1 {
+					b.WriteByte('\n')
+				} else {
+					b.WriteByte(' ')
+				}
+			case stateCSSBlockCmt:
+				b.WriteByte(' ')
+			}
+			written = i1
+		}
+		if c.state != c1.state && isComment(c1.state) && c1.delim == delimNone {
+			// Preserve the portion between written and the comment start.
+			cs := i1 - 2
+			if c1.state == stateHTMLCmt {
+				// "<!--" instead of "/*" or "//"
+				cs -= 2
+			}
+			b.Write(s[written:cs])
+			written = i1
+		}
+		if i == i1 && c.state == c1.state {
+			panic(fmt.Sprintf("infinite loop from %v to %v on %q..%q", c, c1, s[:i], s[i:]))
+		}
+		c, i = c1, i1
+	}
+
+	if written != 0 && c.state != stateError {
+		if !isComment(c.state) || c.delim != delimNone {
+			b.Write(n.Text[written:])
+		}
+		e.editTextNode(n, b.Bytes())
+	}
+	return c
+}
+
+// contextAfterText starts in context c, consumes some tokens from the front of
+// s, then returns the context after those tokens and the unprocessed suffix.
+func contextAfterText(c context, s []byte) (context, int) {
+	if c.delim == delimNone {
+		c1, i := tSpecialTagEnd(c, s)
+		if i == 0 {
+			// A special end tag (`</script>`) has been seen and
+			// all content preceding it has been consumed.
+			return c1, 0
+		}
+		// Consider all content up to any end tag.
+		return transitionFunc[c.state](c, s[:i])
+	}
+
+	i := bytes.IndexAny(s, delimEnds[c.delim])
+	if i == -1 {
+		i = len(s)
+	}
+	if c.delim == delimSpaceOrTagEnd {
+		// http://www.w3.org/TR/html5/syntax.html#attribute-value-(unquoted)-state
+		// lists the runes below as error characters.
+		// Error out because HTML parsers may differ on whether
+		// "<a id= onclick=f("     ends inside id's or onclick's value,
+		// "<a class=`foo "        ends inside a value,
+		// "<a style=font:'Arial'" needs open-quote fixup.
+		// IE treats '`' as a quotation character.
+		if j := bytes.IndexAny(s[:i], "\"'<=`"); j >= 0 {
+			return context{
+				state: stateError,
+				err:   errorf(ErrBadHTML, nil, 0, "%q in unquoted attr: %q", s[j:j+1], s[:i]),
+			}, len(s)
+		}
+	}
+	if i == len(s) {
+		// Remain inside the attribute.
+		// Decode the value so non-HTML rules can easily handle
+		//     <button onclick="alert("Hi!")">
+		// without having to entity decode token boundaries.
+		for u := []byte(html.UnescapeString(string(s))); len(u) != 0; {
+			c1, i1 := transitionFunc[c.state](c, u)
+			c, u = c1, u[i1:]
+		}
+		return c, len(s)
+	}
+	if c.delim != delimSpaceOrTagEnd {
+		// Consume any quote.
+		i++
+	}
+	// On exiting an attribute, we discard all state information
+	// except the state and element.
+	return context{state: stateTag, element: c.element}, i
+}
+
+// editActionNode records a change to an action pipeline for later commit.
+func (e *escaper) editActionNode(n *parse.ActionNode, cmds []string) {
+	if _, ok := e.actionNodeEdits[n]; ok {
+		panic(fmt.Sprintf("node %s shared between templates", n))
+	}
+	e.actionNodeEdits[n] = cmds
+}
+
+// editTemplateNode records a change to a {{template}} callee for later commit.
+func (e *escaper) editTemplateNode(n *parse.TemplateNode, callee string) {
+	if _, ok := e.templateNodeEdits[n]; ok {
+		panic(fmt.Sprintf("node %s shared between templates", n))
+	}
+	e.templateNodeEdits[n] = callee
+}
+
+// editTextNode records a change to a text node for later commit.
+func (e *escaper) editTextNode(n *parse.TextNode, text []byte) {
+	if _, ok := e.textNodeEdits[n]; ok {
+		panic(fmt.Sprintf("node %s shared between templates", n))
+	}
+	e.textNodeEdits[n] = text
+}
+
+// commit applies changes to actions and template calls needed to contextually
+// autoescape content and adds any derived templates to the set.
+func (e *escaper) commit() {
+	for name := range e.output {
+		e.template(name).Funcs(funcMap)
+	}
+	for _, t := range e.derived {
+		if _, err := e.tmpl.text.AddParseTree(t.Name(), t.Tree); err != nil {
+			panic("error adding derived template")
+		}
+	}
+	for n, s := range e.actionNodeEdits {
+		ensurePipelineContains(n.Pipe, s)
+	}
+	for n, name := range e.templateNodeEdits {
+		n.Name = name
+	}
+	for n, s := range e.textNodeEdits {
+		n.Text = s
+	}
+}
+
+// template returns the named template given a mangled template name.
+func (e *escaper) template(name string) *template.Template {
+	t := e.tmpl.text.Lookup(name)
+	if t == nil {
+		t = e.derived[name]
+	}
+	return t
+}
+
+// Forwarding functions so that clients need only import this package
+// to reach the general escaping functions of text/template.
+
+// HTMLEscape writes to w the escaped HTML equivalent of the plain text data b.
+func HTMLEscape(w io.Writer, b []byte) {
+	template.HTMLEscape(w, b)
+}
+
+// HTMLEscapeString returns the escaped HTML equivalent of the plain text data s.
+func HTMLEscapeString(s string) string {
+	return template.HTMLEscapeString(s)
+}
+
+// HTMLEscaper returns the escaped HTML equivalent of the textual
+// representation of its arguments.
+func HTMLEscaper(args ...interface{}) string {
+	return template.HTMLEscaper(args...)
+}
+
+// JSEscape writes to w the escaped JavaScript equivalent of the plain text data b.
+func JSEscape(w io.Writer, b []byte) {
+	template.JSEscape(w, b)
+}
+
+// JSEscapeString returns the escaped JavaScript equivalent of the plain text data s.
+func JSEscapeString(s string) string {
+	return template.JSEscapeString(s)
+}
+
+// JSEscaper returns the escaped JavaScript equivalent of the textual
+// representation of its arguments.
+func JSEscaper(args ...interface{}) string {
+	return template.JSEscaper(args...)
+}
+
+// URLQueryEscaper returns the escaped value of the textual representation of
+// its arguments in a form suitable for embedding in a URL query.
+func URLQueryEscaper(args ...interface{}) string {
+	return template.URLQueryEscaper(args...)
+}
diff --git a/src/html/template/escape_test.go b/src/html/template/escape_test.go
new file mode 100644
index 0000000..ef7b877
--- /dev/null
+++ b/src/html/template/escape_test.go
@@ -0,0 +1,1697 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package template
+
+import (
+	"bytes"
+	"encoding/json"
+	"fmt"
+	"os"
+	"strings"
+	"testing"
+	"text/template"
+	"text/template/parse"
+)
+
+type badMarshaler struct{}
+
+func (x *badMarshaler) MarshalJSON() ([]byte, error) {
+	// Keys in valid JSON must be double quoted as must all strings.
+	return []byte("{ foo: 'not quite valid JSON' }"), nil
+}
+
+type goodMarshaler struct{}
+
+func (x *goodMarshaler) MarshalJSON() ([]byte, error) {
+	return []byte(`{ "<foo>": "O'Reilly" }`), nil
+}
+
+func TestEscape(t *testing.T) {
+	data := struct {
+		F, T    bool
+		C, G, H string
+		A, E    []string
+		B, M    json.Marshaler
+		N       int
+		Z       *int
+		W       HTML
+	}{
+		F: false,
+		T: true,
+		C: "<Cincinatti>",
+		G: "<Goodbye>",
+		H: "<Hello>",
+		A: []string{"<a>", "<b>"},
+		E: []string{},
+		N: 42,
+		B: &badMarshaler{},
+		M: &goodMarshaler{},
+		Z: nil,
+		W: HTML(`¡<b class="foo">Hello</b>, <textarea>O'World</textarea>!`),
+	}
+	pdata := &data
+
+	tests := []struct {
+		name   string
+		input  string
+		output string
+	}{
+		{
+			"if",
+			"{{if .T}}Hello{{end}}, {{.C}}!",
+			"Hello, <Cincinatti>!",
+		},
+		{
+			"else",
+			"{{if .F}}{{.H}}{{else}}{{.G}}{{end}}!",
+			"<Goodbye>!",
+		},
+		{
+			"overescaping1",
+			"Hello, {{.C | html}}!",
+			"Hello, <Cincinatti>!",
+		},
+		{
+			"overescaping2",
+			"Hello, {{html .C}}!",
+			"Hello, <Cincinatti>!",
+		},
+		{
+			"overescaping3",
+			"{{with .C}}{{$msg := .}}Hello, {{$msg}}!{{end}}",
+			"Hello, <Cincinatti>!",
+		},
+		{
+			"assignment",
+			"{{if $x := .H}}{{$x}}{{end}}",
+			"<Hello>",
+		},
+		{
+			"withBody",
+			"{{with .H}}{{.}}{{end}}",
+			"<Hello>",
+		},
+		{
+			"withElse",
+			"{{with .E}}{{.}}{{else}}{{.H}}{{end}}",
+			"<Hello>",
+		},
+		{
+			"rangeBody",
+			"{{range .A}}{{.}}{{end}}",
+			"<a><b>",
+		},
+		{
+			"rangeElse",
+			"{{range .E}}{{.}}{{else}}{{.H}}{{end}}",
+			"<Hello>",
+		},
+		{
+			"nonStringValue",
+			"{{.T}}",
+			"true",
+		},
+		{
+			"constant",
+			`<a href="/search?q={{"'a<b'"}}">`,
+			`<a href="/search?q=%27a%3cb%27">`,
+		},
+		{
+			"multipleAttrs",
+			"<a b=1 c={{.H}}>",
+			"<a b=1 c=<Hello>>",
+		},
+		{
+			"urlStartRel",
+			`<a href='{{"/foo/bar?a=b&c=d"}}'>`,
+			`<a href='/foo/bar?a=b&c=d'>`,
+		},
+		{
+			"urlStartAbsOk",
+			`<a href='{{"http://example.com/foo/bar?a=b&c=d"}}'>`,
+			`<a href='http://example.com/foo/bar?a=b&c=d'>`,
+		},
+		{
+			"protocolRelativeURLStart",
+			`<a href='{{"//example.com:8000/foo/bar?a=b&c=d"}}'>`,
+			`<a href='//example.com:8000/foo/bar?a=b&c=d'>`,
+		},
+		{
+			"pathRelativeURLStart",
+			`<a href="{{"/javascript:80/foo/bar"}}">`,
+			`<a href="/javascript:80/foo/bar">`,
+		},
+		{
+			"dangerousURLStart",
+			`<a href='{{"javascript:alert(%22pwned%22)"}}'>`,
+			`<a href='#ZgotmplZ'>`,
+		},
+		{
+			"dangerousURLStart2",
+			`<a href='  {{"javascript:alert(%22pwned%22)"}}'>`,
+			`<a href='  #ZgotmplZ'>`,
+		},
+		{
+			"nonHierURL",
+			`<a href={{"mailto:Muhammed \"The Greatest\" Ali <m.ali at example.com>"}}>`,
+			`<a href=mailto:Muhammed%20%22The%20Greatest%22%20Ali%20%3cm.ali at example.com%3e>`,
+		},
+		{
+			"urlPath",
+			`<a href='http://{{"javascript:80"}}/foo'>`,
+			`<a href='http://javascript:80/foo'>`,
+		},
+		{
+			"urlQuery",
+			`<a href='/search?q={{.H}}'>`,
+			`<a href='/search?q=%3cHello%3e'>`,
+		},
+		{
+			"urlFragment",
+			`<a href='/faq#{{.H}}'>`,
+			`<a href='/faq#%3cHello%3e'>`,
+		},
+		{
+			"urlBranch",
+			`<a href="{{if .F}}/foo?a=b{{else}}/bar{{end}}">`,
+			`<a href="/bar">`,
+		},
+		{
+			"urlBranchConflictMoot",
+			`<a href="{{if .T}}/foo?a={{else}}/bar#{{end}}{{.C}}">`,
+			`<a href="/foo?a=%3cCincinatti%3e">`,
+		},
+		{
+			"jsStrValue",
+			"<button onclick='alert({{.H}})'>",
+			`<button onclick='alert("\u003cHello\u003e")'>`,
+		},
+		{
+			"jsNumericValue",
+			"<button onclick='alert({{.N}})'>",
+			`<button onclick='alert( 42 )'>`,
+		},
+		{
+			"jsBoolValue",
+			"<button onclick='alert({{.T}})'>",
+			`<button onclick='alert( true )'>`,
+		},
+		{
+			"jsNilValue",
+			"<button onclick='alert(typeof{{.Z}})'>",
+			`<button onclick='alert(typeof null )'>`,
+		},
+		{
+			"jsObjValue",
+			"<button onclick='alert({{.A}})'>",
+			`<button onclick='alert(["\u003ca\u003e","\u003cb\u003e"])'>`,
+		},
+		{
+			"jsObjValueScript",
+			"<script>alert({{.A}})</script>",
+			`<script>alert(["\u003ca\u003e","\u003cb\u003e"])</script>`,
+		},
+		{
+			"jsObjValueNotOverEscaped",
+			"<button onclick='alert({{.A | html}})'>",
+			`<button onclick='alert(["\u003ca\u003e","\u003cb\u003e"])'>`,
+		},
+		{
+			"jsStr",
+			"<button onclick='alert("{{.H}}")'>",
+			`<button onclick='alert("\x3cHello\x3e")'>`,
+		},
+		{
+			"badMarshaler",
+			`<button onclick='alert(1/{{.B}}in numbers)'>`,
+			`<button onclick='alert(1/ /* json: error calling MarshalJSON for type *template.badMarshaler: invalid character 'f' looking for beginning of object key string */null in numbers)'>`,
+		},
+		{
+			"jsMarshaler",
+			`<button onclick='alert({{.M}})'>`,
+			`<button onclick='alert({"\u003cfoo\u003e":"O'Reilly"})'>`,
+		},
+		{
+			"jsStrNotUnderEscaped",
+			"<button onclick='alert({{.C | urlquery}})'>",
+			// URL escaped, then quoted for JS.
+			`<button onclick='alert("%3CCincinatti%3E")'>`,
+		},
+		{
+			"jsRe",
+			`<button onclick='alert(/{{"foo+bar"}}/.test(""))'>`,
+			`<button onclick='alert(/foo\x2bbar/.test(""))'>`,
+		},
+		{
+			"jsReBlank",
+			`<script>alert(/{{""}}/.test(""));</script>`,
+			`<script>alert(/(?:)/.test(""));</script>`,
+		},
+		{
+			"jsReAmbigOk",
+			`<script>{{if true}}var x = 1{{end}}</script>`,
+			// The {if} ends in an ambiguous jsCtx but there is
+			// no slash following so we shouldn't care.
+			`<script>var x = 1</script>`,
+		},
+		{
+			"styleBidiKeywordPassed",
+			`<p style="dir: {{"ltr"}}">`,
+			`<p style="dir: ltr">`,
+		},
+		{
+			"styleBidiPropNamePassed",
+			`<p style="border-{{"left"}}: 0; border-{{"right"}}: 1in">`,
+			`<p style="border-left: 0; border-right: 1in">`,
+		},
+		{
+			"styleExpressionBlocked",
+			`<p style="width: {{"expression(alert(1337))"}}">`,
+			`<p style="width: ZgotmplZ">`,
+		},
+		{
+			"styleTagSelectorPassed",
+			`<style>{{"p"}} { color: pink }</style>`,
+			`<style>p { color: pink }</style>`,
+		},
+		{
+			"styleIDPassed",
+			`<style>p{{"#my-ID"}} { font: Arial }</style>`,
+			`<style>p#my-ID { font: Arial }</style>`,
+		},
+		{
+			"styleClassPassed",
+			`<style>p{{".my_class"}} { font: Arial }</style>`,
+			`<style>p.my_class { font: Arial }</style>`,
+		},
+		{
+			"styleQuantityPassed",
+			`<a style="left: {{"2em"}}; top: {{0}}">`,
+			`<a style="left: 2em; top: 0">`,
+		},
+		{
+			"stylePctPassed",
+			`<table style=width:{{"100%"}}>`,
+			`<table style=width:100%>`,
+		},
+		{
+			"styleColorPassed",
+			`<p style="color: {{"#8ff"}}; background: {{"#000"}}">`,
+			`<p style="color: #8ff; background: #000">`,
+		},
+		{
+			"styleObfuscatedExpressionBlocked",
+			`<p style="width: {{"  e\\78preS\x00Sio/**/n(alert(1337))"}}">`,
+			`<p style="width: ZgotmplZ">`,
+		},
+		{
+			"styleMozBindingBlocked",
+			`<p style="{{"-moz-binding(alert(1337))"}}: ...">`,
+			`<p style="ZgotmplZ: ...">`,
+		},
+		{
+			"styleObfuscatedMozBindingBlocked",
+			`<p style="{{"  -mo\\7a-B\x00I/**/nding(alert(1337))"}}: ...">`,
+			`<p style="ZgotmplZ: ...">`,
+		},
+		{
+			"styleFontNameString",
+			`<p style='font-family: "{{"Times New Roman"}}"'>`,
+			`<p style='font-family: "Times New Roman"'>`,
+		},
+		{
+			"styleFontNameString",
+			`<p style='font-family: "{{"Times New Roman"}}", "{{"sans-serif"}}"'>`,
+			`<p style='font-family: "Times New Roman", "sans-serif"'>`,
+		},
+		{
+			"styleFontNameUnquoted",
+			`<p style='font-family: {{"Times New Roman"}}'>`,
+			`<p style='font-family: Times New Roman'>`,
+		},
+		{
+			"styleURLQueryEncoded",
+			`<p style="background: url(/img?name={{"O'Reilly Animal(1)<2>.png"}})">`,
+			`<p style="background: url(/img?name=O%27Reilly%20Animal%281%29%3c2%3e.png)">`,
+		},
+		{
+			"styleQuotedURLQueryEncoded",
+			`<p style="background: url('/img?name={{"O'Reilly Animal(1)<2>.png"}}')">`,
+			`<p style="background: url('/img?name=O%27Reilly%20Animal%281%29%3c2%3e.png')">`,
+		},
+		{
+			"styleStrQueryEncoded",
+			`<p style="background: '/img?name={{"O'Reilly Animal(1)<2>.png"}}'">`,
+			`<p style="background: '/img?name=O%27Reilly%20Animal%281%29%3c2%3e.png'">`,
+		},
+		{
+			"styleURLBadProtocolBlocked",
+			`<a style="background: url('{{"javascript:alert(1337)"}}')">`,
+			`<a style="background: url('#ZgotmplZ')">`,
+		},
+		{
+			"styleStrBadProtocolBlocked",
+			`<a style="background: '{{"vbscript:alert(1337)"}}'">`,
+			`<a style="background: '#ZgotmplZ'">`,
+		},
+		{
+			"styleStrEncodedProtocolEncoded",
+			`<a style="background: '{{"javascript\\3a alert(1337)"}}'">`,
+			// The CSS string 'javascript\\3a alert(1337)' does not contains a colon.
+			`<a style="background: 'javascript\\3a alert\28 1337\29 '">`,
+		},
+		{
+			"styleURLGoodProtocolPassed",
+			`<a style="background: url('{{"http://oreilly.com/O'Reilly Animals(1)<2>;{}.html"}}')">`,
+			`<a style="background: url('http://oreilly.com/O%27Reilly%20Animals%281%29%3c2%3e;%7b%7d.html')">`,
+		},
+		{
+			"styleStrGoodProtocolPassed",
+			`<a style="background: '{{"http://oreilly.com/O'Reilly Animals(1)<2>;{}.html"}}'">`,
+			`<a style="background: 'http\3a\2f\2foreilly.com\2fO\27Reilly Animals\28 1\29\3c 2\3e\3b\7b\7d.html'">`,
+		},
+		{
+			"styleURLEncodedForHTMLInAttr",
+			`<a style="background: url('{{"/search?img=foo&size=icon"}}')">`,
+			`<a style="background: url('/search?img=foo&size=icon')">`,
+		},
+		{
+			"styleURLNotEncodedForHTMLInCdata",
+			`<style>body { background: url('{{"/search?img=foo&size=icon"}}') }</style>`,
+			`<style>body { background: url('/search?img=foo&size=icon') }</style>`,
+		},
+		{
+			"styleURLMixedCase",
+			`<p style="background: URL(#{{.H}})">`,
+			`<p style="background: URL(#%3cHello%3e)">`,
+		},
+		{
+			"stylePropertyPairPassed",
+			`<a style='{{"color: red"}}'>`,
+			`<a style='color: red'>`,
+		},
+		{
+			"styleStrSpecialsEncoded",
+			`<a style="font-family: '{{"/**/'\";:// \\"}}', "{{"/**/'\";:// \\"}}"">`,
+			`<a style="font-family: '\2f**\2f\27\22\3b\3a\2f\2f  \\', "\2f**\2f\27\22\3b\3a\2f\2f  \\"">`,
+		},
+		{
+			"styleURLSpecialsEncoded",
+			`<a style="border-image: url({{"/**/'\";:// \\"}}), url("{{"/**/'\";:// \\"}}"), url('{{"/**/'\";:// \\"}}'), 'http://www.example.com/?q={{"/**/'\";:// \\"}}''">`,
+			`<a style="border-image: url(/**/%27%22;://%20%5c), url("/**/%27%22;://%20%5c"), url('/**/%27%22;://%20%5c'), 'http://www.example.com/?q=%2f%2a%2a%2f%27%22%3b%3a%2f%2f%20%5c''">`,
+		},
+		{
+			"HTML comment",
+			"<b>Hello, <!-- name of world -->{{.C}}</b>",
+			"<b>Hello, <Cincinatti></b>",
+		},
+		{
+			"HTML comment not first < in text node.",
+			"<<!-- -->!--",
+			"<!--",
+		},
+		{
+			"HTML normalization 1",
+			"a < b",
+			"a < b",
+		},
+		{
+			"HTML normalization 2",
+			"a << b",
+			"a << b",
+		},
+		{
+			"HTML normalization 3",
+			"a<<!-- --><!-- -->b",
+			"a<b",
+		},
+		{
+			"HTML doctype not normalized",
+			"<!DOCTYPE html>Hello, World!",
+			"<!DOCTYPE html>Hello, World!",
+		},
+		{
+			"HTML doctype not case-insensitive",
+			"<!doCtYPE htMl>Hello, World!",
+			"<!doCtYPE htMl>Hello, World!",
+		},
+		{
+			"No doctype injection",
+			`<!{{"DOCTYPE"}}`,
+			"<!DOCTYPE",
+		},
+		{
+			"Split HTML comment",
+			"<b>Hello, <!-- name of {{if .T}}city -->{{.C}}{{else}}world -->{{.W}}{{end}}</b>",
+			"<b>Hello, <Cincinatti></b>",
+		},
+		{
+			"JS line comment",
+			"<script>for (;;) { if (c()) break// foo not a label\n" +
+				"foo({{.T}});}</script>",
+			"<script>for (;;) { if (c()) break\n" +
+				"foo( true );}</script>",
+		},
+		{
+			"JS multiline block comment",
+			"<script>for (;;) { if (c()) break/* foo not a label\n" +
+				" */foo({{.T}});}</script>",
+			// Newline separates break from call. If newline
+			// removed, then break will consume label leaving
+			// code invalid.
+			"<script>for (;;) { if (c()) break\n" +
+				"foo( true );}</script>",
+		},
+		{
+			"JS single-line block comment",
+			"<script>for (;;) {\n" +
+				"if (c()) break/* foo a label */foo;" +
+				"x({{.T}});}</script>",
+			// Newline separates break from call. If newline
+			// removed, then break will consume label leaving
+			// code invalid.
+			"<script>for (;;) {\n" +
+				"if (c()) break foo;" +
+				"x( true );}</script>",
+		},
+		{
+			"JS block comment flush with mathematical division",
+			"<script>var a/*b*//c\nd</script>",
+			"<script>var a /c\nd</script>",
+		},
+		{
+			"JS mixed comments",
+			"<script>var a/*b*///c\nd</script>",
+			"<script>var a \nd</script>",
+		},
+		{
+			"CSS comments",
+			"<style>p// paragraph\n" +
+				`{border: 1px/* color */{{"#00f"}}}</style>`,
+			"<style>p\n" +
+				"{border: 1px #00f}</style>",
+		},
+		{
+			"JS attr block comment",
+			`<a onclick="f(""); /* alert({{.H}}) */">`,
+			// Attribute comment tests should pass if the comments
+			// are successfully elided.
+			`<a onclick="f(""); /* alert() */">`,
+		},
+		{
+			"JS attr line comment",
+			`<a onclick="// alert({{.G}})">`,
+			`<a onclick="// alert()">`,
+		},
+		{
+			"CSS attr block comment",
+			`<a style="/* color: {{.H}} */">`,
+			`<a style="/* color:  */">`,
+		},
+		{
+			"CSS attr line comment",
+			`<a style="// color: {{.G}}">`,
+			`<a style="// color: ">`,
+		},
+		{
+			"HTML substitution commented out",
+			"<p><!-- {{.H}} --></p>",
+			"<p></p>",
+		},
+		{
+			"Comment ends flush with start",
+			"<!--{{.}}--><script>/*{{.}}*///{{.}}\n</script><style>/*{{.}}*///{{.}}\n</style><a onclick='/*{{.}}*///{{.}}' style='/*{{.}}*///{{.}}'>",
+			"<script> \n</script><style> \n</style><a onclick='/**///' style='/**///'>",
+		},
+		{
+			"typed HTML in text",
+			`{{.W}}`,
+			`¡<b class="foo">Hello</b>, <textarea>O'World</textarea>!`,
+		},
+		{
+			"typed HTML in attribute",
+			`<div title="{{.W}}">`,
+			`<div title="¡Hello, O'World!">`,
+		},
+		{
+			"typed HTML in script",
+			`<button onclick="alert({{.W}})">`,
+			`<button onclick="alert("\u0026iexcl;\u003cb class=\"foo\"\u003eHello\u003c/b\u003e, \u003ctextarea\u003eO'World\u003c/textarea\u003e!")">`,
+		},
+		{
+			"typed HTML in RCDATA",
+			`<textarea>{{.W}}</textarea>`,
+			`<textarea>¡<b class="foo">Hello</b>, <textarea>O'World</textarea>!</textarea>`,
+		},
+		{
+			"range in textarea",
+			"<textarea>{{range .A}}{{.}}{{end}}</textarea>",
+			"<textarea><a><b></textarea>",
+		},
+		{
+			"No tag injection",
+			`{{"10$"}}<{{"script src,evil.org/pwnd.js"}}...`,
+			`10$<script src,evil.org/pwnd.js...`,
+		},
+		{
+			"No comment injection",
+			`<{{"!--"}}`,
+			`<!--`,
+		},
+		{
+			"No RCDATA end tag injection",
+			`<textarea><{{"/textarea "}}...</textarea>`,
+			`<textarea></textarea ...</textarea>`,
+		},
+		{
+			"optional attrs",
+			`<img class="{{"iconClass"}}"` +
+				`{{if .T}} id="{{"<iconId>"}}"{{end}}` +
+				// Double quotes inside if/else.
+				` src=` +
+				`{{if .T}}"?{{"<iconPath>"}}"` +
+				`{{else}}"images/cleardot.gif"{{end}}` +
+				// Missing space before title, but it is not a
+				// part of the src attribute.
+				`{{if .T}}title="{{"<title>"}}"{{end}}` +
+				// Quotes outside if/else.
+				` alt="` +
+				`{{if .T}}{{"<alt>"}}` +
+				`{{else}}{{if .F}}{{"<title>"}}{{end}}` +
+				`{{end}}"` +
+				`>`,
+			`<img class="iconClass" id="<iconId>" src="?%3ciconPath%3e"title="<title>" alt="<alt>">`,
+		},
+		{
+			"conditional valueless attr name",
+			`<input{{if .T}} checked{{end}} name=n>`,
+			`<input checked name=n>`,
+		},
+		{
+			"conditional dynamic valueless attr name 1",
+			`<input{{if .T}} {{"checked"}}{{end}} name=n>`,
+			`<input checked name=n>`,
+		},
+		{
+			"conditional dynamic valueless attr name 2",
+			`<input {{if .T}}{{"checked"}} {{end}}name=n>`,
+			`<input checked name=n>`,
+		},
+		{
+			"dynamic attribute name",
+			`<img on{{"load"}}="alert({{"loaded"}})">`,
+			// Treated as JS since quotes are inserted.
+			`<img onload="alert("loaded")">`,
+		},
+		{
+			"bad dynamic attribute name 1",
+			// Allow checked, selected, disabled, but not JS or
+			// CSS attributes.
+			`<input {{"onchange"}}="{{"doEvil()"}}">`,
+			`<input ZgotmplZ="doEvil()">`,
+		},
+		{
+			"bad dynamic attribute name 2",
+			`<div {{"sTyle"}}="{{"color: expression(alert(1337))"}}">`,
+			`<div ZgotmplZ="color: expression(alert(1337))">`,
+		},
+		{
+			"bad dynamic attribute name 3",
+			// Allow title or alt, but not a URL.
+			`<img {{"src"}}="{{"javascript:doEvil()"}}">`,
+			`<img ZgotmplZ="javascript:doEvil()">`,
+		},
+		{
+			"bad dynamic attribute name 4",
+			// Structure preservation requires values to associate
+			// with a consistent attribute.
+			`<input checked {{""}}="Whose value am I?">`,
+			`<input checked ZgotmplZ="Whose value am I?">`,
+		},
+		{
+			"dynamic element name",
+			`<h{{3}}><table><t{{"head"}}>...</h{{3}}>`,
+			`<h3><table><thead>...</h3>`,
+		},
+		{
+			"bad dynamic element name",
+			// Dynamic element names are typically used to switch
+			// between (thead, tfoot, tbody), (ul, ol), (th, td),
+			// and other replaceable sets.
+			// We do not currently easily support (ul, ol).
+			// If we do change to support that, this test should
+			// catch failures to filter out special tag names which
+			// would violate the structure preservation property --
+			// if any special tag name could be substituted, then
+			// the content could be raw text/RCDATA for some inputs
+			// and regular HTML content for others.
+			`<{{"script"}}>{{"doEvil()"}}</{{"script"}}>`,
+			`<script>doEvil()</script>`,
+		},
+	}
+
+	for _, test := range tests {
+		tmpl := New(test.name)
+		tmpl = Must(tmpl.Parse(test.input))
+		// Check for bug 6459: Tree field was not set in Parse.
+		if tmpl.Tree != tmpl.text.Tree {
+			t.Errorf("%s: tree not set properly", test.name)
+			continue
+		}
+		b := new(bytes.Buffer)
+		if err := tmpl.Execute(b, data); err != nil {
+			t.Errorf("%s: template execution failed: %s", test.name, err)
+			continue
+		}
+		if w, g := test.output, b.String(); w != g {
+			t.Errorf("%s: escaped output: want\n\t%q\ngot\n\t%q", test.name, w, g)
+			continue
+		}
+		b.Reset()
+		if err := tmpl.Execute(b, pdata); err != nil {
+			t.Errorf("%s: template execution failed for pointer: %s", test.name, err)
+			continue
+		}
+		if w, g := test.output, b.String(); w != g {
+			t.Errorf("%s: escaped output for pointer: want\n\t%q\ngot\n\t%q", test.name, w, g)
+			continue
+		}
+		if tmpl.Tree != tmpl.text.Tree {
+			t.Errorf("%s: tree mismatch", test.name)
+			continue
+		}
+	}
+}
+
+func TestEscapeSet(t *testing.T) {
+	type dataItem struct {
+		Children []*dataItem
+		X        string
+	}
+
+	data := dataItem{
+		Children: []*dataItem{
+			{X: "foo"},
+			{X: "<bar>"},
+			{
+				Children: []*dataItem{
+					{X: "baz"},
+				},
+			},
+		},
+	}
+
+	tests := []struct {
+		inputs map[string]string
+		want   string
+	}{
+		// The trivial set.
+		{
+			map[string]string{
+				"main": ``,
+			},
+			``,
+		},
+		// A template called in the start context.
+		{
+			map[string]string{
+				"main": `Hello, {{template "helper"}}!`,
+				// Not a valid top level HTML template.
+				// "<b" is not a full tag.
+				"helper": `{{"<World>"}}`,
+			},
+			`Hello, <World>!`,
+		},
+		// A template called in a context other than the start.
+		{
+			map[string]string{
+				"main": `<a onclick='a = {{template "helper"}};'>`,
+				// Not a valid top level HTML template.
+				// "<b" is not a full tag.
+				"helper": `{{"<a>"}}<b`,
+			},
+			`<a onclick='a = "\u003ca\u003e"<b;'>`,
+		},
+		// A recursive template that ends in its start context.
+		{
+			map[string]string{
+				"main": `{{range .Children}}{{template "main" .}}{{else}}{{.X}} {{end}}`,
+			},
+			`foo <bar> baz `,
+		},
+		// A recursive helper template that ends in its start context.
+		{
+			map[string]string{
+				"main":   `{{template "helper" .}}`,
+				"helper": `{{if .Children}}<ul>{{range .Children}}<li>{{template "main" .}}</li>{{end}}</ul>{{else}}{{.X}}{{end}}`,
+			},
+			`<ul><li>foo</li><li><bar></li><li><ul><li>baz</li></ul></li></ul>`,
+		},
+		// Co-recursive templates that end in its start context.
+		{
+			map[string]string{
+				"main":   `<blockquote>{{range .Children}}{{template "helper" .}}{{end}}</blockquote>`,
+				"helper": `{{if .Children}}{{template "main" .}}{{else}}{{.X}}<br>{{end}}`,
+			},
+			`<blockquote>foo<br><bar><br><blockquote>baz<br></blockquote></blockquote>`,
+		},
+		// A template that is called in two different contexts.
+		{
+			map[string]string{
+				"main":   `<button onclick="title='{{template "helper"}}'; ...">{{template "helper"}}</button>`,
+				"helper": `{{11}} of {{"<100>"}}`,
+			},
+			`<button onclick="title='11 of \x3c100\x3e'; ...">11 of <100></button>`,
+		},
+		// A non-recursive template that ends in a different context.
+		// helper starts in jsCtxRegexp and ends in jsCtxDivOp.
+		{
+			map[string]string{
+				"main":   `<script>var x={{template "helper"}}/{{"42"}};</script>`,
+				"helper": "{{126}}",
+			},
+			`<script>var x= 126 /"42";</script>`,
+		},
+		// A recursive template that ends in a similar context.
+		{
+			map[string]string{
+				"main":      `<script>var x=[{{template "countdown" 4}}];</script>`,
+				"countdown": `{{.}}{{if .}},{{template "countdown" . | pred}}{{end}}`,
+			},
+			`<script>var x=[ 4 , 3 , 2 , 1 , 0 ];</script>`,
+		},
+		// A recursive template that ends in a different context.
+		/*
+			{
+				map[string]string{
+					"main":   `<a href="/foo{{template "helper" .}}">`,
+					"helper": `{{if .Children}}{{range .Children}}{{template "helper" .}}{{end}}{{else}}?x={{.X}}{{end}}`,
+				},
+				`<a href="/foo?x=foo?x=%3cbar%3e?x=baz">`,
+			},
+		*/
+	}
+
+	// pred is a template function that returns the predecessor of a
+	// natural number for testing recursive templates.
+	fns := FuncMap{"pred": func(a ...interface{}) (interface{}, error) {
+		if len(a) == 1 {
+			if i, _ := a[0].(int); i > 0 {
+				return i - 1, nil
+			}
+		}
+		return nil, fmt.Errorf("undefined pred(%v)", a)
+	}}
+
+	for _, test := range tests {
+		source := ""
+		for name, body := range test.inputs {
+			source += fmt.Sprintf("{{define %q}}%s{{end}} ", name, body)
+		}
+		tmpl, err := New("root").Funcs(fns).Parse(source)
+		if err != nil {
+			t.Errorf("error parsing %q: %v", source, err)
+			continue
+		}
+		var b bytes.Buffer
+
+		if err := tmpl.ExecuteTemplate(&b, "main", data); err != nil {
+			t.Errorf("%q executing %v", err.Error(), tmpl.Lookup("main"))
+			continue
+		}
+		if got := b.String(); test.want != got {
+			t.Errorf("want\n\t%q\ngot\n\t%q", test.want, got)
+		}
+	}
+
+}
+
+func TestErrors(t *testing.T) {
+	tests := []struct {
+		input string
+		err   string
+	}{
+		// Non-error cases.
+		{
+			"{{if .Cond}}<a>{{else}}<b>{{end}}",
+			"",
+		},
+		{
+			"{{if .Cond}}<a>{{end}}",
+			"",
+		},
+		{
+			"{{if .Cond}}{{else}}<b>{{end}}",
+			"",
+		},
+		{
+			"{{with .Cond}}<div>{{end}}",
+			"",
+		},
+		{
+			"{{range .Items}}<a>{{end}}",
+			"",
+		},
+		{
+			"<a href='/foo?{{range .Items}}&{{.K}}={{.V}}{{end}}'>",
+			"",
+		},
+		// Error cases.
+		{
+			"{{if .Cond}}<a{{end}}",
+			"z:1:5: {{if}} branches",
+		},
+		{
+			"{{if .Cond}}\n{{else}}\n<a{{end}}",
+			"z:1:5: {{if}} branches",
+		},
+		{
+			// Missing quote in the else branch.
+			`{{if .Cond}}<a href="foo">{{else}}<a href="bar>{{end}}`,
+			"z:1:5: {{if}} branches",
+		},
+		{
+			// Different kind of attribute: href implies a URL.
+			"<a {{if .Cond}}href='{{else}}title='{{end}}{{.X}}'>",
+			"z:1:8: {{if}} branches",
+		},
+		{
+			"\n{{with .X}}<a{{end}}",
+			"z:2:7: {{with}} branches",
+		},
+		{
+			"\n{{with .X}}<a>{{else}}<a{{end}}",
+			"z:2:7: {{with}} branches",
+		},
+		{
+			"{{range .Items}}<a{{end}}",
+			`z:1: on range loop re-entry: "<" in attribute name: "<a"`,
+		},
+		{
+			"\n{{range .Items}} x='<a{{end}}",
+			"z:2:8: on range loop re-entry: {{range}} branches",
+		},
+		{
+			"<a b=1 c={{.H}}",
+			"z: ends in a non-text context: {stateAttr delimSpaceOrTagEnd",
+		},
+		{
+			"<script>foo();",
+			"z: ends in a non-text context: {stateJS",
+		},
+		{
+			`<a href="{{if .F}}/foo?a={{else}}/bar/{{end}}{{.H}}">`,
+			"z:1:47: {{.H}} appears in an ambiguous URL context",
+		},
+		{
+			`<a onclick="alert('Hello \`,
+			`unfinished escape sequence in JS string: "Hello \\"`,
+		},
+		{
+			`<a onclick='alert("Hello\, World\`,
+			`unfinished escape sequence in JS string: "Hello\\, World\\"`,
+		},
+		{
+			`<a onclick='alert(/x+\`,
+			`unfinished escape sequence in JS string: "x+\\"`,
+		},
+		{
+			`<a onclick="/foo[\]/`,
+			`unfinished JS regexp charset: "foo[\\]/"`,
+		},
+		{
+			// It is ambiguous whether 1.5 should be 1\.5 or 1.5.
+			// Either `var x = 1/- 1.5 /i.test(x)`
+			// where `i.test(x)` is a method call of reference i,
+			// or `/-1\.5/i.test(x)` which is a method call on a
+			// case insensitive regular expression.
+			`<script>{{if false}}var x = 1{{end}}/-{{"1.5"}}/i.test(x)</script>`,
+			`'/' could start a division or regexp: "/-"`,
+		},
+		{
+			`{{template "foo"}}`,
+			"z:1:11: no such template \"foo\"",
+		},
+		{
+			`<div{{template "y"}}>` +
+				// Illegal starting in stateTag but not in stateText.
+				`{{define "y"}} foo<b{{end}}`,
+			`"<" in attribute name: " foo<b"`,
+		},
+		{
+			`<script>reverseList = [{{template "t"}}]</script>` +
+				// Missing " after recursive call.
+				`{{define "t"}}{{if .Tail}}{{template "t" .Tail}}{{end}}{{.Head}}",{{end}}`,
+			`: cannot compute output context for template t$htmltemplate_stateJS_elementScript`,
+		},
+		{
+			`<input type=button value=onclick=>`,
+			`html/template:z: "=" in unquoted attr: "onclick="`,
+		},
+		{
+			`<input type=button value= onclick=>`,
+			`html/template:z: "=" in unquoted attr: "onclick="`,
+		},
+		{
+			`<input type=button value= 1+1=2>`,
+			`html/template:z: "=" in unquoted attr: "1+1=2"`,
+		},
+		{
+			"<a class=`foo>",
+			"html/template:z: \"`\" in unquoted attr: \"`foo\"",
+		},
+		{
+			`<a style=font:'Arial'>`,
+			`html/template:z: "'" in unquoted attr: "font:'Arial'"`,
+		},
+		{
+			`<a=foo>`,
+			`: expected space, attr name, or end of tag, but got "=foo>"`,
+		},
+	}
+
+	for _, test := range tests {
+		buf := new(bytes.Buffer)
+		tmpl, err := New("z").Parse(test.input)
+		if err != nil {
+			t.Errorf("input=%q: unexpected parse error %s\n", test.input, err)
+			continue
+		}
+		err = tmpl.Execute(buf, nil)
+		var got string
+		if err != nil {
+			got = err.Error()
+		}
+		if test.err == "" {
+			if got != "" {
+				t.Errorf("input=%q: unexpected error %q", test.input, got)
+			}
+			continue
+		}
+		if strings.Index(got, test.err) == -1 {
+			t.Errorf("input=%q: error\n\t%q\ndoes not contain expected string\n\t%q", test.input, got, test.err)
+			continue
+		}
+		// Check that we get the same error if we call Execute again.
+		if err := tmpl.Execute(buf, nil); err == nil || err.Error() != got {
+			t.Errorf("input=%q: unexpected error on second call %q", test.input, err)
+
+		}
+	}
+}
+
+func TestEscapeText(t *testing.T) {
+	tests := []struct {
+		input  string
+		output context
+	}{
+		{
+			``,
+			context{},
+		},
+		{
+			`Hello, World!`,
+			context{},
+		},
+		{
+			// An orphaned "<" is OK.
+			`I <3 Ponies!`,
+			context{},
+		},
+		{
+			`<a`,
+			context{state: stateTag},
+		},
+		{
+			`<a `,
+			context{state: stateTag},
+		},
+		{
+			`<a>`,
+			context{state: stateText},
+		},
+		{
+			`<a href`,
+			context{state: stateAttrName, attr: attrURL},
+		},
+		{
+			`<a on`,
+			context{state: stateAttrName, attr: attrScript},
+		},
+		{
+			`<a href `,
+			context{state: stateAfterName, attr: attrURL},
+		},
+		{
+			`<a style  =  `,
+			context{state: stateBeforeValue, attr: attrStyle},
+		},
+		{
+			`<a href=`,
+			context{state: stateBeforeValue, attr: attrURL},
+		},
+		{
+			`<a href=x`,
+			context{state: stateURL, delim: delimSpaceOrTagEnd, urlPart: urlPartPreQuery},
+		},
+		{
+			`<a href=x `,
+			context{state: stateTag},
+		},
+		{
+			`<a href=>`,
+			context{state: stateText},
+		},
+		{
+			`<a href=x>`,
+			context{state: stateText},
+		},
+		{
+			`<a href ='`,
+			context{state: stateURL, delim: delimSingleQuote},
+		},
+		{
+			`<a href=''`,
+			context{state: stateTag},
+		},
+		{
+			`<a href= "`,
+			context{state: stateURL, delim: delimDoubleQuote},
+		},
+		{
+			`<a href=""`,
+			context{state: stateTag},
+		},
+		{
+			`<a title="`,
+			context{state: stateAttr, delim: delimDoubleQuote},
+		},
+		{
+			`<a HREF='http:`,
+			context{state: stateURL, delim: delimSingleQuote, urlPart: urlPartPreQuery},
+		},
+		{
+			`<a Href='/`,
+			context{state: stateURL, delim: delimSingleQuote, urlPart: urlPartPreQuery},
+		},
+		{
+			`<a href='"`,
+			context{state: stateURL, delim: delimSingleQuote, urlPart: urlPartPreQuery},
+		},
+		{
+			`<a href="'`,
+			context{state: stateURL, delim: delimDoubleQuote, urlPart: urlPartPreQuery},
+		},
+		{
+			`<a href=''`,
+			context{state: stateURL, delim: delimSingleQuote, urlPart: urlPartPreQuery},
+		},
+		{
+			`<a href=""`,
+			context{state: stateURL, delim: delimDoubleQuote, urlPart: urlPartPreQuery},
+		},
+		{
+			`<a href=""`,
+			context{state: stateURL, delim: delimDoubleQuote, urlPart: urlPartPreQuery},
+		},
+		{
+			`<a href="`,
+			context{state: stateURL, delim: delimSpaceOrTagEnd, urlPart: urlPartPreQuery},
+		},
+		{
+			`<img alt="1">`,
+			context{state: stateText},
+		},
+		{
+			`<img alt="1>"`,
+			context{state: stateTag},
+		},
+		{
+			`<img alt="1>">`,
+			context{state: stateText},
+		},
+		{
+			`<input checked type="checkbox"`,
+			context{state: stateTag},
+		},
+		{
+			`<a onclick="`,
+			context{state: stateJS, delim: delimDoubleQuote},
+		},
+		{
+			`<a onclick="//foo`,
+			context{state: stateJSLineCmt, delim: delimDoubleQuote},
+		},
+		{
+			"<a onclick='//\n",
+			context{state: stateJS, delim: delimSingleQuote},
+		},
+		{
+			"<a onclick='//\r\n",
+			context{state: stateJS, delim: delimSingleQuote},
+		},
+		{
+			"<a onclick='//\u2028",
+			context{state: stateJS, delim: delimSingleQuote},
+		},
+		{
+			`<a onclick="/*`,
+			context{state: stateJSBlockCmt, delim: delimDoubleQuote},
+		},
+		{
+			`<a onclick="/*/`,
+			context{state: stateJSBlockCmt, delim: delimDoubleQuote},
+		},
+		{
+			`<a onclick="/**/`,
+			context{state: stateJS, delim: delimDoubleQuote},
+		},
+		{
+			`<a onkeypress=""`,
+			context{state: stateJSDqStr, delim: delimDoubleQuote},
+		},
+		{
+			`<a onclick='"foo"`,
+			context{state: stateJS, delim: delimSingleQuote, jsCtx: jsCtxDivOp},
+		},
+		{
+			`<a onclick='foo'`,
+			context{state: stateJS, delim: delimSpaceOrTagEnd, jsCtx: jsCtxDivOp},
+		},
+		{
+			`<a onclick='foo`,
+			context{state: stateJSSqStr, delim: delimSpaceOrTagEnd},
+		},
+		{
+			`<a onclick=""foo'`,
+			context{state: stateJSDqStr, delim: delimDoubleQuote},
+		},
+		{
+			`<a onclick="'foo"`,
+			context{state: stateJSSqStr, delim: delimDoubleQuote},
+		},
+		{
+			`<A ONCLICK="'`,
+			context{state: stateJSSqStr, delim: delimDoubleQuote},
+		},
+		{
+			`<a onclick="/`,
+			context{state: stateJSRegexp, delim: delimDoubleQuote},
+		},
+		{
+			`<a onclick="'foo'`,
+			context{state: stateJS, delim: delimDoubleQuote, jsCtx: jsCtxDivOp},
+		},
+		{
+			`<a onclick="'foo\'`,
+			context{state: stateJSSqStr, delim: delimDoubleQuote},
+		},
+		{
+			`<a onclick="'foo\'`,
+			context{state: stateJSSqStr, delim: delimDoubleQuote},
+		},
+		{
+			`<a onclick="/foo/`,
+			context{state: stateJS, delim: delimDoubleQuote, jsCtx: jsCtxDivOp},
+		},
+		{
+			`<script>/foo/ /=`,
+			context{state: stateJS, element: elementScript},
+		},
+		{
+			`<a onclick="1 /foo`,
+			context{state: stateJS, delim: delimDoubleQuote, jsCtx: jsCtxDivOp},
+		},
+		{
+			`<a onclick="1 /*c*/ /foo`,
+			context{state: stateJS, delim: delimDoubleQuote, jsCtx: jsCtxDivOp},
+		},
+		{
+			`<a onclick="/foo[/]`,
+			context{state: stateJSRegexp, delim: delimDoubleQuote},
+		},
+		{
+			`<a onclick="/foo\/`,
+			context{state: stateJSRegexp, delim: delimDoubleQuote},
+		},
+		{
+			`<a onclick="/foo/`,
+			context{state: stateJS, delim: delimDoubleQuote, jsCtx: jsCtxDivOp},
+		},
+		{
+			`<input checked style="`,
+			context{state: stateCSS, delim: delimDoubleQuote},
+		},
+		{
+			`<a style="//`,
+			context{state: stateCSSLineCmt, delim: delimDoubleQuote},
+		},
+		{
+			`<a style="//</script>`,
+			context{state: stateCSSLineCmt, delim: delimDoubleQuote},
+		},
+		{
+			"<a style='//\n",
+			context{state: stateCSS, delim: delimSingleQuote},
+		},
+		{
+			"<a style='//\r",
+			context{state: stateCSS, delim: delimSingleQuote},
+		},
+		{
+			`<a style="/*`,
+			context{state: stateCSSBlockCmt, delim: delimDoubleQuote},
+		},
+		{
+			`<a style="/*/`,
+			context{state: stateCSSBlockCmt, delim: delimDoubleQuote},
+		},
+		{
+			`<a style="/**/`,
+			context{state: stateCSS, delim: delimDoubleQuote},
+		},
+		{
+			`<a style="background: '`,
+			context{state: stateCSSSqStr, delim: delimDoubleQuote},
+		},
+		{
+			`<a style="background: "`,
+			context{state: stateCSSDqStr, delim: delimDoubleQuote},
+		},
+		{
+			`<a style="background: '/foo?img=`,
+			context{state: stateCSSSqStr, delim: delimDoubleQuote, urlPart: urlPartQueryOrFrag},
+		},
+		{
+			`<a style="background: '/`,
+			context{state: stateCSSSqStr, delim: delimDoubleQuote, urlPart: urlPartPreQuery},
+		},
+		{
+			`<a style="background: url(&#x22;/`,
+			context{state: stateCSSDqURL, delim: delimDoubleQuote, urlPart: urlPartPreQuery},
+		},
+		{
+			`<a style="background: url('/`,
+			context{state: stateCSSSqURL, delim: delimDoubleQuote, urlPart: urlPartPreQuery},
+		},
+		{
+			`<a style="background: url('/)`,
+			context{state: stateCSSSqURL, delim: delimDoubleQuote, urlPart: urlPartPreQuery},
+		},
+		{
+			`<a style="background: url('/ `,
+			context{state: stateCSSSqURL, delim: delimDoubleQuote, urlPart: urlPartPreQuery},
+		},
+		{
+			`<a style="background: url(/`,
+			context{state: stateCSSURL, delim: delimDoubleQuote, urlPart: urlPartPreQuery},
+		},
+		{
+			`<a style="background: url( `,
+			context{state: stateCSSURL, delim: delimDoubleQuote},
+		},
+		{
+			`<a style="background: url( /image?name=`,
+			context{state: stateCSSURL, delim: delimDoubleQuote, urlPart: urlPartQueryOrFrag},
+		},
+		{
+			`<a style="background: url(x)`,
+			context{state: stateCSS, delim: delimDoubleQuote},
+		},
+		{
+			`<a style="background: url('x'`,
+			context{state: stateCSS, delim: delimDoubleQuote},
+		},
+		{
+			`<a style="background: url( x `,
+			context{state: stateCSS, delim: delimDoubleQuote},
+		},
+		{
+			`<!-- foo`,
+			context{state: stateHTMLCmt},
+		},
+		{
+			`<!-->`,
+			context{state: stateHTMLCmt},
+		},
+		{
+			`<!--->`,
+			context{state: stateHTMLCmt},
+		},
+		{
+			`<!-- foo -->`,
+			context{state: stateText},
+		},
+		{
+			`<script`,
+			context{state: stateTag, element: elementScript},
+		},
+		{
+			`<script `,
+			context{state: stateTag, element: elementScript},
+		},
+		{
+			`<script src="foo.js" `,
+			context{state: stateTag, element: elementScript},
+		},
+		{
+			`<script src='foo.js' `,
+			context{state: stateTag, element: elementScript},
+		},
+		{
+			`<script type=text/javascript `,
+			context{state: stateTag, element: elementScript},
+		},
+		{
+			`<script>foo`,
+			context{state: stateJS, jsCtx: jsCtxDivOp, element: elementScript},
+		},
+		{
+			`<script>foo</script>`,
+			context{state: stateText},
+		},
+		{
+			`<script>foo</script><!--`,
+			context{state: stateHTMLCmt},
+		},
+		{
+			`<script>document.write("<p>foo</p>");`,
+			context{state: stateJS, element: elementScript},
+		},
+		{
+			`<script>document.write("<p>foo<\/script>");`,
+			context{state: stateJS, element: elementScript},
+		},
+		{
+			`<script>document.write("<script>alert(1)</script>");`,
+			context{state: stateText},
+		},
+		{
+			`<Script>`,
+			context{state: stateJS, element: elementScript},
+		},
+		{
+			`<SCRIPT>foo`,
+			context{state: stateJS, jsCtx: jsCtxDivOp, element: elementScript},
+		},
+		{
+			`<textarea>value`,
+			context{state: stateRCDATA, element: elementTextarea},
+		},
+		{
+			`<textarea>value</TEXTAREA>`,
+			context{state: stateText},
+		},
+		{
+			`<textarea name=html><b`,
+			context{state: stateRCDATA, element: elementTextarea},
+		},
+		{
+			`<title>value`,
+			context{state: stateRCDATA, element: elementTitle},
+		},
+		{
+			`<style>value`,
+			context{state: stateCSS, element: elementStyle},
+		},
+		{
+			`<a xlink:href`,
+			context{state: stateAttrName, attr: attrURL},
+		},
+		{
+			`<a xmlns`,
+			context{state: stateAttrName, attr: attrURL},
+		},
+		{
+			`<a xmlns:foo`,
+			context{state: stateAttrName, attr: attrURL},
+		},
+		{
+			`<a xmlnsxyz`,
+			context{state: stateAttrName},
+		},
+		{
+			`<a data-url`,
+			context{state: stateAttrName, attr: attrURL},
+		},
+		{
+			`<a data-iconUri`,
+			context{state: stateAttrName, attr: attrURL},
+		},
+		{
+			`<a data-urlItem`,
+			context{state: stateAttrName, attr: attrURL},
+		},
+		{
+			`<a g:`,
+			context{state: stateAttrName},
+		},
+		{
+			`<a g:url`,
+			context{state: stateAttrName, attr: attrURL},
+		},
+		{
+			`<a g:iconUri`,
+			context{state: stateAttrName, attr: attrURL},
+		},
+		{
+			`<a g:urlItem`,
+			context{state: stateAttrName, attr: attrURL},
+		},
+		{
+			`<a g:value`,
+			context{state: stateAttrName},
+		},
+		{
+			`<a svg:style='`,
+			context{state: stateCSS, delim: delimSingleQuote},
+		},
+		{
+			`<svg:font-face`,
+			context{state: stateTag},
+		},
+		{
+			`<svg:a svg:onclick="`,
+			context{state: stateJS, delim: delimDoubleQuote},
+		},
+	}
+
+	for _, test := range tests {
+		b, e := []byte(test.input), newEscaper(nil)
+		c := e.escapeText(context{}, &parse.TextNode{NodeType: parse.NodeText, Text: b})
+		if !test.output.eq(c) {
+			t.Errorf("input %q: want context\n\t%v\ngot\n\t%v", test.input, test.output, c)
+			continue
+		}
+		if test.input != string(b) {
+			t.Errorf("input %q: text node was modified: want %q got %q", test.input, test.input, b)
+			continue
+		}
+	}
+}
+
+func TestEnsurePipelineContains(t *testing.T) {
+	tests := []struct {
+		input, output string
+		ids           []string
+	}{
+		{
+			"{{.X}}",
+			".X",
+			[]string{},
+		},
+		{
+			"{{.X | html}}",
+			".X | html",
+			[]string{},
+		},
+		{
+			"{{.X}}",
+			".X | html",
+			[]string{"html"},
+		},
+		{
+			"{{.X | html}}",
+			".X | html | urlquery",
+			[]string{"urlquery"},
+		},
+		{
+			"{{.X | html | urlquery}}",
+			".X | html | urlquery",
+			[]string{"urlquery"},
+		},
+		{
+			"{{.X | html | urlquery}}",
+			".X | html | urlquery",
+			[]string{"html", "urlquery"},
+		},
+		{
+			"{{.X | html | urlquery}}",
+			".X | html | urlquery",
+			[]string{"html"},
+		},
+		{
+			"{{.X | urlquery}}",
+			".X | html | urlquery",
+			[]string{"html", "urlquery"},
+		},
+		{
+			"{{.X | html | print}}",
+			".X | urlquery | html | print",
+			[]string{"urlquery", "html"},
+		},
+		{
+			"{{($).X | html | print}}",
+			"($).X | urlquery | html | print",
+			[]string{"urlquery", "html"},
+		},
+	}
+	for i, test := range tests {
+		tmpl := template.Must(template.New("test").Parse(test.input))
+		action, ok := (tmpl.Tree.Root.Nodes[0].(*parse.ActionNode))
+		if !ok {
+			t.Errorf("#%d: First node is not an action: %s", i, test.input)
+			continue
+		}
+		pipe := action.Pipe
+		ensurePipelineContains(pipe, test.ids)
+		got := pipe.String()
+		if got != test.output {
+			t.Errorf("#%d: %s, %v: want\n\t%s\ngot\n\t%s", i, test.input, test.ids, test.output, got)
+		}
+	}
+}
+
+func TestEscapeErrorsNotIgnorable(t *testing.T) {
+	var b bytes.Buffer
+	tmpl, _ := New("dangerous").Parse("<a")
+	err := tmpl.Execute(&b, nil)
+	if err == nil {
+		t.Errorf("Expected error")
+	} else if b.Len() != 0 {
+		t.Errorf("Emitted output despite escaping failure")
+	}
+}
+
+func TestEscapeSetErrorsNotIgnorable(t *testing.T) {
+	var b bytes.Buffer
+	tmpl, err := New("root").Parse(`{{define "t"}}<a{{end}}`)
+	if err != nil {
+		t.Errorf("failed to parse set: %q", err)
+	}
+	err = tmpl.ExecuteTemplate(&b, "t", nil)
+	if err == nil {
+		t.Errorf("Expected error")
+	} else if b.Len() != 0 {
+		t.Errorf("Emitted output despite escaping failure")
+	}
+}
+
+func TestRedundantFuncs(t *testing.T) {
+	inputs := []interface{}{
+		"\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f" +
+			"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" +
+			` !"#$%&'()*+,-./` +
+			`0123456789:;<=>?` +
+			`@ABCDEFGHIJKLMNO` +
+			`PQRSTUVWXYZ[\]^_` +
+			"`abcdefghijklmno" +
+			"pqrstuvwxyz{|}~\x7f" +
+			"\u00A0\u0100\u2028\u2029\ufeff\ufdec\ufffd\uffff\U0001D11E" +
+			"&%22\\",
+		CSS(`a[href =~ "//example.com"]#foo`),
+		HTML(`Hello, <b>World</b> &tc!`),
+		HTMLAttr(` dir="ltr"`),
+		JS(`c && alert("Hello, World!");`),
+		JSStr(`Hello, World & O'Reilly\x21`),
+		URL(`greeting=H%69&addressee=(World)`),
+	}
+
+	for n0, m := range redundantFuncs {
+		f0 := funcMap[n0].(func(...interface{}) string)
+		for n1 := range m {
+			f1 := funcMap[n1].(func(...interface{}) string)
+			for _, input := range inputs {
+				want := f0(input)
+				if got := f1(want); want != got {
+					t.Errorf("%s %s with %T %q: want\n\t%q,\ngot\n\t%q", n0, n1, input, input, want, got)
+				}
+			}
+		}
+	}
+}
+
+func TestIndirectPrint(t *testing.T) {
+	a := 3
+	ap := &a
+	b := "hello"
+	bp := &b
+	bpp := &bp
+	tmpl := Must(New("t").Parse(`{{.}}`))
+	var buf bytes.Buffer
+	err := tmpl.Execute(&buf, ap)
+	if err != nil {
+		t.Errorf("Unexpected error: %s", err)
+	} else if buf.String() != "3" {
+		t.Errorf(`Expected "3"; got %q`, buf.String())
+	}
+	buf.Reset()
+	err = tmpl.Execute(&buf, bpp)
+	if err != nil {
+		t.Errorf("Unexpected error: %s", err)
+	} else if buf.String() != "hello" {
+		t.Errorf(`Expected "hello"; got %q`, buf.String())
+	}
+}
+
+// This is a test for issue 3272.
+func TestEmptyTemplate(t *testing.T) {
+	page := Must(New("page").ParseFiles(os.DevNull))
+	if err := page.ExecuteTemplate(os.Stdout, "page", "nothing"); err == nil {
+		t.Fatal("expected error")
+	}
+}
+
+type Issue7379 int
+
+func (Issue7379) SomeMethod(x int) string {
+	return fmt.Sprintf("<%d>", x)
+}
+
+// This is a test for issue 7379: type assertion error caused panic, and then
+// the code to handle the panic breaks escaping. It's hard to see the second
+// problem once the first is fixed, but its fix is trivial so we let that go. See
+// the discussion for issue 7379.
+func TestPipeToMethodIsEscaped(t *testing.T) {
+	tmpl := Must(New("x").Parse("<html>{{0 | .SomeMethod}}</html>\n"))
+	tryExec := func() string {
+		defer func() {
+			panicValue := recover()
+			if panicValue != nil {
+				t.Errorf("panicked: %v\n", panicValue)
+			}
+		}()
+		var b bytes.Buffer
+		tmpl.Execute(&b, Issue7379(0))
+		return b.String()
+	}
+	for i := 0; i < 3; i++ {
+		str := tryExec()
+		const expect = "<html><0></html>\n"
+		if str != expect {
+			t.Errorf("expected %q got %q", expect, str)
+		}
+	}
+}
+
+func BenchmarkEscapedExecute(b *testing.B) {
+	tmpl := Must(New("t").Parse(`<a onclick="alert('{{.}}')">{{.}}</a>`))
+	var buf bytes.Buffer
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		tmpl.Execute(&buf, "foo & 'bar' & baz")
+		buf.Reset()
+	}
+}
diff --git a/src/pkg/html/template/html.go b/src/html/template/html.go
similarity index 100%
rename from src/pkg/html/template/html.go
rename to src/html/template/html.go
diff --git a/src/pkg/html/template/html_test.go b/src/html/template/html_test.go
similarity index 100%
rename from src/pkg/html/template/html_test.go
rename to src/html/template/html_test.go
diff --git a/src/pkg/html/template/js.go b/src/html/template/js.go
similarity index 100%
rename from src/pkg/html/template/js.go
rename to src/html/template/js.go
diff --git a/src/html/template/js_test.go b/src/html/template/js_test.go
new file mode 100644
index 0000000..7af7997
--- /dev/null
+++ b/src/html/template/js_test.go
@@ -0,0 +1,401 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package template
+
+import (
+	"bytes"
+	"math"
+	"strings"
+	"testing"
+)
+
+func TestNextJsCtx(t *testing.T) {
+	tests := []struct {
+		jsCtx jsCtx
+		s     string
+	}{
+		// Statement terminators precede regexps.
+		{jsCtxRegexp, ";"},
+		// This is not airtight.
+		//     ({ valueOf: function () { return 1 } } / 2)
+		// is valid JavaScript but in practice, devs do not do this.
+		// A block followed by a statement starting with a RegExp is
+		// much more common:
+		//     while (x) {...} /foo/.test(x) || panic()
+		{jsCtxRegexp, "}"},
+		// But member, call, grouping, and array expression terminators
+		// precede div ops.
+		{jsCtxDivOp, ")"},
+		{jsCtxDivOp, "]"},
+		// At the start of a primary expression, array, or expression
+		// statement, expect a regexp.
+		{jsCtxRegexp, "("},
+		{jsCtxRegexp, "["},
+		{jsCtxRegexp, "{"},
+		// Assignment operators precede regexps as do all exclusively
+		// prefix and binary operators.
+		{jsCtxRegexp, "="},
+		{jsCtxRegexp, "+="},
+		{jsCtxRegexp, "*="},
+		{jsCtxRegexp, "*"},
+		{jsCtxRegexp, "!"},
+		// Whether the + or - is infix or prefix, it cannot precede a
+		// div op.
+		{jsCtxRegexp, "+"},
+		{jsCtxRegexp, "-"},
+		// An incr/decr op precedes a div operator.
+		// This is not airtight. In (g = ++/h/i) a regexp follows a
+		// pre-increment operator, but in practice devs do not try to
+		// increment or decrement regular expressions.
+		// (g++/h/i) where ++ is a postfix operator on g is much more
+		// common.
+		{jsCtxDivOp, "--"},
+		{jsCtxDivOp, "++"},
+		{jsCtxDivOp, "x--"},
+		// When we have many dashes or pluses, then they are grouped
+		// left to right.
+		{jsCtxRegexp, "x---"}, // A postfix -- then a -.
+		// return followed by a slash returns the regexp literal or the
+		// slash starts a regexp literal in an expression statement that
+		// is dead code.
+		{jsCtxRegexp, "return"},
+		{jsCtxRegexp, "return "},
+		{jsCtxRegexp, "return\t"},
+		{jsCtxRegexp, "return\n"},
+		{jsCtxRegexp, "return\u2028"},
+		// Identifiers can be divided and cannot validly be preceded by
+		// a regular expressions. Semicolon insertion cannot happen
+		// between an identifier and a regular expression on a new line
+		// because the one token lookahead for semicolon insertion has
+		// to conclude that it could be a div binary op and treat it as
+		// such.
+		{jsCtxDivOp, "x"},
+		{jsCtxDivOp, "x "},
+		{jsCtxDivOp, "x\t"},
+		{jsCtxDivOp, "x\n"},
+		{jsCtxDivOp, "x\u2028"},
+		{jsCtxDivOp, "preturn"},
+		// Numbers precede div ops.
+		{jsCtxDivOp, "0"},
+		// Dots that are part of a number are div preceders.
+		{jsCtxDivOp, "0."},
+	}
+
+	for _, test := range tests {
+		if nextJSCtx([]byte(test.s), jsCtxRegexp) != test.jsCtx {
+			t.Errorf("want %s got %q", test.jsCtx, test.s)
+		}
+		if nextJSCtx([]byte(test.s), jsCtxDivOp) != test.jsCtx {
+			t.Errorf("want %s got %q", test.jsCtx, test.s)
+		}
+	}
+
+	if nextJSCtx([]byte("   "), jsCtxRegexp) != jsCtxRegexp {
+		t.Error("Blank tokens")
+	}
+
+	if nextJSCtx([]byte("   "), jsCtxDivOp) != jsCtxDivOp {
+		t.Error("Blank tokens")
+	}
+}
+
+func TestJSValEscaper(t *testing.T) {
+	tests := []struct {
+		x  interface{}
+		js string
+	}{
+		{int(42), " 42 "},
+		{uint(42), " 42 "},
+		{int16(42), " 42 "},
+		{uint16(42), " 42 "},
+		{int32(-42), " -42 "},
+		{uint32(42), " 42 "},
+		{int16(-42), " -42 "},
+		{uint16(42), " 42 "},
+		{int64(-42), " -42 "},
+		{uint64(42), " 42 "},
+		{uint64(1) << 53, " 9007199254740992 "},
+		// ulp(1 << 53) > 1 so this loses precision in JS
+		// but it is still a representable integer literal.
+		{uint64(1)<<53 + 1, " 9007199254740993 "},
+		{float32(1.0), " 1 "},
+		{float32(-1.0), " -1 "},
+		{float32(0.5), " 0.5 "},
+		{float32(-0.5), " -0.5 "},
+		{float32(1.0) / float32(256), " 0.00390625 "},
+		{float32(0), " 0 "},
+		{math.Copysign(0, -1), " -0 "},
+		{float64(1.0), " 1 "},
+		{float64(-1.0), " -1 "},
+		{float64(0.5), " 0.5 "},
+		{float64(-0.5), " -0.5 "},
+		{float64(0), " 0 "},
+		{math.Copysign(0, -1), " -0 "},
+		{"", `""`},
+		{"foo", `"foo"`},
+		// Newlines.
+		{"\r\n\u2028\u2029", `"\r\n\u2028\u2029"`},
+		// "\v" == "v" on IE 6 so use "\x0b" instead.
+		{"\t\x0b", `"\t\u000b"`},
+		{struct{ X, Y int }{1, 2}, `{"X":1,"Y":2}`},
+		{[]interface{}{}, "[]"},
+		{[]interface{}{42, "foo", nil}, `[42,"foo",null]`},
+		{[]string{"<!--", "</script>", "-->"}, `["\u003c!--","\u003c/script\u003e","--\u003e"]`},
+		{"<!--", `"\u003c!--"`},
+		{"-->", `"--\u003e"`},
+		{"<![CDATA[", `"\u003c![CDATA["`},
+		{"]]>", `"]]\u003e"`},
+		{"</script", `"\u003c/script"`},
+		{"\U0001D11E", "\"\U0001D11E\""}, // or "\uD834\uDD1E"
+	}
+
+	for _, test := range tests {
+		if js := jsValEscaper(test.x); js != test.js {
+			t.Errorf("%+v: want\n\t%q\ngot\n\t%q", test.x, test.js, js)
+		}
+		// Make sure that escaping corner cases are not broken
+		// by nesting.
+		a := []interface{}{test.x}
+		want := "[" + strings.TrimSpace(test.js) + "]"
+		if js := jsValEscaper(a); js != want {
+			t.Errorf("%+v: want\n\t%q\ngot\n\t%q", a, want, js)
+		}
+	}
+}
+
+func TestJSStrEscaper(t *testing.T) {
+	tests := []struct {
+		x   interface{}
+		esc string
+	}{
+		{"", ``},
+		{"foo", `foo`},
+		{"\u0000", `\0`},
+		{"\t", `\t`},
+		{"\n", `\n`},
+		{"\r", `\r`},
+		{"\u2028", `\u2028`},
+		{"\u2029", `\u2029`},
+		{"\\", `\\`},
+		{"\\n", `\\n`},
+		{"foo\r\nbar", `foo\r\nbar`},
+		// Preserve attribute boundaries.
+		{`"`, `\x22`},
+		{`'`, `\x27`},
+		// Allow embedding in HTML without further escaping.
+		{`&`, `\x26amp;`},
+		// Prevent breaking out of text node and element boundaries.
+		{"</script>", `\x3c\/script\x3e`},
+		{"<![CDATA[", `\x3c![CDATA[`},
+		{"]]>", `]]\x3e`},
+		// http://dev.w3.org/html5/markup/aria/syntax.html#escaping-text-span
+		//   "The text in style, script, title, and textarea elements
+		//   must not have an escaping text span start that is not
+		//   followed by an escaping text span end."
+		// Furthermore, spoofing an escaping text span end could lead
+		// to different interpretation of a </script> sequence otherwise
+		// masked by the escaping text span, and spoofing a start could
+		// allow regular text content to be interpreted as script
+		// allowing script execution via a combination of a JS string
+		// injection followed by an HTML text injection.
+		{"<!--", `\x3c!--`},
+		{"-->", `--\x3e`},
+		// From http://code.google.com/p/doctype/wiki/ArticleUtf7
+		{"+ADw-script+AD4-alert(1)+ADw-/script+AD4-",
+			`\x2bADw-script\x2bAD4-alert(1)\x2bADw-\/script\x2bAD4-`,
+		},
+		// Invalid UTF-8 sequence
+		{"foo\xA0bar", "foo\xA0bar"},
+		// Invalid unicode scalar value.
+		{"foo\xed\xa0\x80bar", "foo\xed\xa0\x80bar"},
+	}
+
+	for _, test := range tests {
+		esc := jsStrEscaper(test.x)
+		if esc != test.esc {
+			t.Errorf("%q: want %q got %q", test.x, test.esc, esc)
+		}
+	}
+}
+
+func TestJSRegexpEscaper(t *testing.T) {
+	tests := []struct {
+		x   interface{}
+		esc string
+	}{
+		{"", `(?:)`},
+		{"foo", `foo`},
+		{"\u0000", `\0`},
+		{"\t", `\t`},
+		{"\n", `\n`},
+		{"\r", `\r`},
+		{"\u2028", `\u2028`},
+		{"\u2029", `\u2029`},
+		{"\\", `\\`},
+		{"\\n", `\\n`},
+		{"foo\r\nbar", `foo\r\nbar`},
+		// Preserve attribute boundaries.
+		{`"`, `\x22`},
+		{`'`, `\x27`},
+		// Allow embedding in HTML without further escaping.
+		{`&`, `\x26amp;`},
+		// Prevent breaking out of text node and element boundaries.
+		{"</script>", `\x3c\/script\x3e`},
+		{"<![CDATA[", `\x3c!\[CDATA\[`},
+		{"]]>", `\]\]\x3e`},
+		// Escaping text spans.
+		{"<!--", `\x3c!\-\-`},
+		{"-->", `\-\-\x3e`},
+		{"*", `\*`},
+		{"+", `\x2b`},
+		{"?", `\?`},
+		{"[](){}", `\[\]\(\)\{\}`},
+		{"$foo|x.y", `\$foo\|x\.y`},
+		{"x^y", `x\^y`},
+	}
+
+	for _, test := range tests {
+		esc := jsRegexpEscaper(test.x)
+		if esc != test.esc {
+			t.Errorf("%q: want %q got %q", test.x, test.esc, esc)
+		}
+	}
+}
+
+func TestEscapersOnLower7AndSelectHighCodepoints(t *testing.T) {
+	input := ("\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f" +
+		"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" +
+		` !"#$%&'()*+,-./` +
+		`0123456789:;<=>?` +
+		`@ABCDEFGHIJKLMNO` +
+		`PQRSTUVWXYZ[\]^_` +
+		"`abcdefghijklmno" +
+		"pqrstuvwxyz{|}~\x7f" +
+		"\u00A0\u0100\u2028\u2029\ufeff\U0001D11E")
+
+	tests := []struct {
+		name    string
+		escaper func(...interface{}) string
+		escaped string
+	}{
+		{
+			"jsStrEscaper",
+			jsStrEscaper,
+			"\\0\x01\x02\x03\x04\x05\x06\x07" +
+				"\x08\\t\\n\\x0b\\f\\r\x0E\x0F" +
+				"\x10\x11\x12\x13\x14\x15\x16\x17" +
+				"\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" +
+				` !\x22#$%\x26\x27()*\x2b,-.\/` +
+				`0123456789:;\x3c=\x3e?` +
+				`@ABCDEFGHIJKLMNO` +
+				`PQRSTUVWXYZ[\\]^_` +
+				"`abcdefghijklmno" +
+				"pqrstuvwxyz{|}~\x7f" +
+				"\u00A0\u0100\\u2028\\u2029\ufeff\U0001D11E",
+		},
+		{
+			"jsRegexpEscaper",
+			jsRegexpEscaper,
+			"\\0\x01\x02\x03\x04\x05\x06\x07" +
+				"\x08\\t\\n\\x0b\\f\\r\x0E\x0F" +
+				"\x10\x11\x12\x13\x14\x15\x16\x17" +
+				"\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" +
+				` !\x22#\$%\x26\x27\(\)\*\x2b,\-\.\/` +
+				`0123456789:;\x3c=\x3e\?` +
+				`@ABCDEFGHIJKLMNO` +
+				`PQRSTUVWXYZ\[\\\]\^_` +
+				"`abcdefghijklmno" +
+				`pqrstuvwxyz\{\|\}~` + "\u007f" +
+				"\u00A0\u0100\\u2028\\u2029\ufeff\U0001D11E",
+		},
+	}
+
+	for _, test := range tests {
+		if s := test.escaper(input); s != test.escaped {
+			t.Errorf("%s once: want\n\t%q\ngot\n\t%q", test.name, test.escaped, s)
+			continue
+		}
+
+		// Escape it rune by rune to make sure that any
+		// fast-path checking does not break escaping.
+		var buf bytes.Buffer
+		for _, c := range input {
+			buf.WriteString(test.escaper(string(c)))
+		}
+
+		if s := buf.String(); s != test.escaped {
+			t.Errorf("%s rune-wise: want\n\t%q\ngot\n\t%q", test.name, test.escaped, s)
+			continue
+		}
+	}
+}
+
+func BenchmarkJSValEscaperWithNum(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		jsValEscaper(3.141592654)
+	}
+}
+
+func BenchmarkJSValEscaperWithStr(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		jsValEscaper("The <i>quick</i>,\r\n<span style='color:brown'>brown</span> fox jumps\u2028over the <canine class=\"lazy\">dog</canine>")
+	}
+}
+
+func BenchmarkJSValEscaperWithStrNoSpecials(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		jsValEscaper("The quick, brown fox jumps over the lazy dog")
+	}
+}
+
+func BenchmarkJSValEscaperWithObj(b *testing.B) {
+	o := struct {
+		S string
+		N int
+	}{
+		"The <i>quick</i>,\r\n<span style='color:brown'>brown</span> fox jumps\u2028over the <canine class=\"lazy\">dog</canine>\u2028",
+		42,
+	}
+	for i := 0; i < b.N; i++ {
+		jsValEscaper(o)
+	}
+}
+
+func BenchmarkJSValEscaperWithObjNoSpecials(b *testing.B) {
+	o := struct {
+		S string
+		N int
+	}{
+		"The quick, brown fox jumps over the lazy dog",
+		42,
+	}
+	for i := 0; i < b.N; i++ {
+		jsValEscaper(o)
+	}
+}
+
+func BenchmarkJSStrEscaperNoSpecials(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		jsStrEscaper("The quick, brown fox jumps over the lazy dog.")
+	}
+}
+
+func BenchmarkJSStrEscaper(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		jsStrEscaper("The <i>quick</i>,\r\n<span style='color:brown'>brown</span> fox jumps\u2028over the <canine class=\"lazy\">dog</canine>")
+	}
+}
+
+func BenchmarkJSRegexpEscaperNoSpecials(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		jsRegexpEscaper("The quick, brown fox jumps over the lazy dog")
+	}
+}
+
+func BenchmarkJSRegexpEscaper(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		jsRegexpEscaper("The <i>quick</i>,\r\n<span style='color:brown'>brown</span> fox jumps\u2028over the <canine class=\"lazy\">dog</canine>")
+	}
+}
diff --git a/src/html/template/template.go b/src/html/template/template.go
new file mode 100644
index 0000000..ce61701
--- /dev/null
+++ b/src/html/template/template.go
@@ -0,0 +1,389 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package template
+
+import (
+	"fmt"
+	"io"
+	"io/ioutil"
+	"path/filepath"
+	"sync"
+	"text/template"
+	"text/template/parse"
+)
+
+// Template is a specialized Template from "text/template" that produces a safe
+// HTML document fragment.
+type Template struct {
+	// Sticky error if escaping fails.
+	escapeErr error
+	// We could embed the text/template field, but it's safer not to because
+	// we need to keep our version of the name space and the underlying
+	// template's in sync.
+	text *template.Template
+	// The underlying template's parse tree, updated to be HTML-safe.
+	Tree       *parse.Tree
+	*nameSpace // common to all associated templates
+}
+
+// escapeOK is a sentinel value used to indicate valid escaping.
+var escapeOK = fmt.Errorf("template escaped correctly")
+
+// nameSpace is the data structure shared by all templates in an association.
+type nameSpace struct {
+	mu  sync.Mutex
+	set map[string]*Template
+}
+
+// Templates returns a slice of the templates associated with t, including t
+// itself.
+func (t *Template) Templates() []*Template {
+	ns := t.nameSpace
+	ns.mu.Lock()
+	defer ns.mu.Unlock()
+	// Return a slice so we don't expose the map.
+	m := make([]*Template, 0, len(ns.set))
+	for _, v := range ns.set {
+		m = append(m, v)
+	}
+	return m
+}
+
+// escape escapes all associated templates.
+func (t *Template) escape() error {
+	t.nameSpace.mu.Lock()
+	defer t.nameSpace.mu.Unlock()
+	if t.escapeErr == nil {
+		if err := escapeTemplate(t, t.text.Root, t.Name()); err != nil {
+			return err
+		}
+	} else if t.escapeErr != escapeOK {
+		return t.escapeErr
+	}
+	return nil
+}
+
+// Execute applies a parsed template to the specified data object,
+// writing the output to wr.
+// If an error occurs executing the template or writing its output,
+// execution stops, but partial results may already have been written to
+// the output writer.
+// A template may be executed safely in parallel.
+func (t *Template) Execute(wr io.Writer, data interface{}) error {
+	if err := t.escape(); err != nil {
+		return err
+	}
+	return t.text.Execute(wr, data)
+}
+
+// ExecuteTemplate applies the template associated with t that has the given
+// name to the specified data object and writes the output to wr.
+// If an error occurs executing the template or writing its output,
+// execution stops, but partial results may already have been written to
+// the output writer.
+// A template may be executed safely in parallel.
+func (t *Template) ExecuteTemplate(wr io.Writer, name string, data interface{}) error {
+	tmpl, err := t.lookupAndEscapeTemplate(name)
+	if err != nil {
+		return err
+	}
+	return tmpl.text.Execute(wr, data)
+}
+
+// lookupAndEscapeTemplate guarantees that the template with the given name
+// is escaped, or returns an error if it cannot be. It returns the named
+// template.
+func (t *Template) lookupAndEscapeTemplate(name string) (tmpl *Template, err error) {
+	t.nameSpace.mu.Lock()
+	defer t.nameSpace.mu.Unlock()
+	tmpl = t.set[name]
+	if tmpl == nil {
+		return nil, fmt.Errorf("html/template: %q is undefined", name)
+	}
+	if tmpl.escapeErr != nil && tmpl.escapeErr != escapeOK {
+		return nil, tmpl.escapeErr
+	}
+	if tmpl.text.Tree == nil || tmpl.text.Root == nil {
+		return nil, fmt.Errorf("html/template: %q is an incomplete template", name)
+	}
+	if t.text.Lookup(name) == nil {
+		panic("html/template internal error: template escaping out of sync")
+	}
+	if tmpl.escapeErr == nil {
+		err = escapeTemplate(tmpl, tmpl.text.Root, name)
+	}
+	return tmpl, err
+}
+
+// Parse parses a string into a template. Nested template definitions
+// will be associated with the top-level template t. Parse may be
+// called multiple times to parse definitions of templates to associate
+// with t. It is an error if a resulting template is non-empty (contains
+// content other than template definitions) and would replace a
+// non-empty template with the same name.  (In multiple calls to Parse
+// with the same receiver template, only one call can contain text
+// other than space, comments, and template definitions.)
+func (t *Template) Parse(src string) (*Template, error) {
+	t.nameSpace.mu.Lock()
+	t.escapeErr = nil
+	t.nameSpace.mu.Unlock()
+	ret, err := t.text.Parse(src)
+	if err != nil {
+		return nil, err
+	}
+	// In general, all the named templates might have changed underfoot.
+	// Regardless, some new ones may have been defined.
+	// The template.Template set has been updated; update ours.
+	t.nameSpace.mu.Lock()
+	defer t.nameSpace.mu.Unlock()
+	for _, v := range ret.Templates() {
+		name := v.Name()
+		tmpl := t.set[name]
+		if tmpl == nil {
+			tmpl = t.new(name)
+		}
+		// Restore our record of this text/template to its unescaped original state.
+		tmpl.escapeErr = nil
+		tmpl.text = v
+		tmpl.Tree = v.Tree
+	}
+	return t, nil
+}
+
+// AddParseTree creates a new template with the name and parse tree
+// and associates it with t.
+//
+// It returns an error if t has already been executed.
+func (t *Template) AddParseTree(name string, tree *parse.Tree) (*Template, error) {
+	t.nameSpace.mu.Lock()
+	defer t.nameSpace.mu.Unlock()
+	if t.escapeErr != nil {
+		return nil, fmt.Errorf("html/template: cannot AddParseTree to %q after it has executed", t.Name())
+	}
+	text, err := t.text.AddParseTree(name, tree)
+	if err != nil {
+		return nil, err
+	}
+	ret := &Template{
+		nil,
+		text,
+		text.Tree,
+		t.nameSpace,
+	}
+	t.set[name] = ret
+	return ret, nil
+}
+
+// Clone returns a duplicate of the template, including all associated
+// templates. The actual representation is not copied, but the name space of
+// associated templates is, so further calls to Parse in the copy will add
+// templates to the copy but not to the original. Clone can be used to prepare
+// common templates and use them with variant definitions for other templates
+// by adding the variants after the clone is made.
+//
+// It returns an error if t has already been executed.
+func (t *Template) Clone() (*Template, error) {
+	t.nameSpace.mu.Lock()
+	defer t.nameSpace.mu.Unlock()
+	if t.escapeErr != nil {
+		return nil, fmt.Errorf("html/template: cannot Clone %q after it has executed", t.Name())
+	}
+	textClone, err := t.text.Clone()
+	if err != nil {
+		return nil, err
+	}
+	ret := &Template{
+		nil,
+		textClone,
+		textClone.Tree,
+		&nameSpace{
+			set: make(map[string]*Template),
+		},
+	}
+	for _, x := range textClone.Templates() {
+		name := x.Name()
+		src := t.set[name]
+		if src == nil || src.escapeErr != nil {
+			return nil, fmt.Errorf("html/template: cannot Clone %q after it has executed", t.Name())
+		}
+		x.Tree = x.Tree.Copy()
+		ret.set[name] = &Template{
+			nil,
+			x,
+			x.Tree,
+			ret.nameSpace,
+		}
+	}
+	return ret, nil
+}
+
+// New allocates a new HTML template with the given name.
+func New(name string) *Template {
+	tmpl := &Template{
+		nil,
+		template.New(name),
+		nil,
+		&nameSpace{
+			set: make(map[string]*Template),
+		},
+	}
+	tmpl.set[name] = tmpl
+	return tmpl
+}
+
+// New allocates a new HTML template associated with the given one
+// and with the same delimiters. The association, which is transitive,
+// allows one template to invoke another with a {{template}} action.
+func (t *Template) New(name string) *Template {
+	t.nameSpace.mu.Lock()
+	defer t.nameSpace.mu.Unlock()
+	return t.new(name)
+}
+
+// new is the implementation of New, without the lock.
+func (t *Template) new(name string) *Template {
+	tmpl := &Template{
+		nil,
+		t.text.New(name),
+		nil,
+		t.nameSpace,
+	}
+	tmpl.set[name] = tmpl
+	return tmpl
+}
+
+// Name returns the name of the template.
+func (t *Template) Name() string {
+	return t.text.Name()
+}
+
+// FuncMap is the type of the map defining the mapping from names to
+// functions. Each function must have either a single return value, or two
+// return values of which the second has type error. In that case, if the
+// second (error) argument evaluates to non-nil during execution, execution
+// terminates and Execute returns that error. FuncMap has the same base type
+// as FuncMap in "text/template", copied here so clients need not import
+// "text/template".
+type FuncMap map[string]interface{}
+
+// Funcs adds the elements of the argument map to the template's function map.
+// It panics if a value in the map is not a function with appropriate return
+// type. However, it is legal to overwrite elements of the map. The return
+// value is the template, so calls can be chained.
+func (t *Template) Funcs(funcMap FuncMap) *Template {
+	t.text.Funcs(template.FuncMap(funcMap))
+	return t
+}
+
+// Delims sets the action delimiters to the specified strings, to be used in
+// subsequent calls to Parse, ParseFiles, or ParseGlob. Nested template
+// definitions will inherit the settings. An empty delimiter stands for the
+// corresponding default: {{ or }}.
+// The return value is the template, so calls can be chained.
+func (t *Template) Delims(left, right string) *Template {
+	t.text.Delims(left, right)
+	return t
+}
+
+// Lookup returns the template with the given name that is associated with t,
+// or nil if there is no such template.
+func (t *Template) Lookup(name string) *Template {
+	t.nameSpace.mu.Lock()
+	defer t.nameSpace.mu.Unlock()
+	return t.set[name]
+}
+
+// Must is a helper that wraps a call to a function returning (*Template, error)
+// and panics if the error is non-nil. It is intended for use in variable initializations
+// such as
+//	var t = template.Must(template.New("name").Parse("html"))
+func Must(t *Template, err error) *Template {
+	if err != nil {
+		panic(err)
+	}
+	return t
+}
+
+// ParseFiles creates a new Template and parses the template definitions from
+// the named files. The returned template's name will have the (base) name and
+// (parsed) contents of the first file. There must be at least one file.
+// If an error occurs, parsing stops and the returned *Template is nil.
+func ParseFiles(filenames ...string) (*Template, error) {
+	return parseFiles(nil, filenames...)
+}
+
+// ParseFiles parses the named files and associates the resulting templates with
+// t. If an error occurs, parsing stops and the returned template is nil;
+// otherwise it is t. There must be at least one file.
+func (t *Template) ParseFiles(filenames ...string) (*Template, error) {
+	return parseFiles(t, filenames...)
+}
+
+// parseFiles is the helper for the method and function. If the argument
+// template is nil, it is created from the first file.
+func parseFiles(t *Template, filenames ...string) (*Template, error) {
+	if len(filenames) == 0 {
+		// Not really a problem, but be consistent.
+		return nil, fmt.Errorf("html/template: no files named in call to ParseFiles")
+	}
+	for _, filename := range filenames {
+		b, err := ioutil.ReadFile(filename)
+		if err != nil {
+			return nil, err
+		}
+		s := string(b)
+		name := filepath.Base(filename)
+		// First template becomes return value if not already defined,
+		// and we use that one for subsequent New calls to associate
+		// all the templates together. Also, if this file has the same name
+		// as t, this file becomes the contents of t, so
+		//  t, err := New(name).Funcs(xxx).ParseFiles(name)
+		// works. Otherwise we create a new template associated with t.
+		var tmpl *Template
+		if t == nil {
+			t = New(name)
+		}
+		if name == t.Name() {
+			tmpl = t
+		} else {
+			tmpl = t.New(name)
+		}
+		_, err = tmpl.Parse(s)
+		if err != nil {
+			return nil, err
+		}
+	}
+	return t, nil
+}
+
+// ParseGlob creates a new Template and parses the template definitions from the
+// files identified by the pattern, which must match at least one file. The
+// returned template will have the (base) name and (parsed) contents of the
+// first file matched by the pattern. ParseGlob is equivalent to calling
+// ParseFiles with the list of files matched by the pattern.
+func ParseGlob(pattern string) (*Template, error) {
+	return parseGlob(nil, pattern)
+}
+
+// ParseGlob parses the template definitions in the files identified by the
+// pattern and associates the resulting templates with t. The pattern is
+// processed by filepath.Glob and must match at least one file. ParseGlob is
+// equivalent to calling t.ParseFiles with the list of files matched by the
+// pattern.
+func (t *Template) ParseGlob(pattern string) (*Template, error) {
+	return parseGlob(t, pattern)
+}
+
+// parseGlob is the implementation of the function and method ParseGlob.
+func parseGlob(t *Template, pattern string) (*Template, error) {
+	filenames, err := filepath.Glob(pattern)
+	if err != nil {
+		return nil, err
+	}
+	if len(filenames) == 0 {
+		return nil, fmt.Errorf("html/template: pattern matches no files: %#q", pattern)
+	}
+	return parseFiles(t, filenames...)
+}
diff --git a/src/html/template/transition.go b/src/html/template/transition.go
new file mode 100644
index 0000000..b486fcd
--- /dev/null
+++ b/src/html/template/transition.go
@@ -0,0 +1,550 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package template
+
+import (
+	"bytes"
+	"strings"
+)
+
+// transitionFunc is the array of context transition functions for text nodes.
+// A transition function takes a context and template text input, and returns
+// the updated context and the number of bytes consumed from the front of the
+// input.
+var transitionFunc = [...]func(context, []byte) (context, int){
+	stateText:        tText,
+	stateTag:         tTag,
+	stateAttrName:    tAttrName,
+	stateAfterName:   tAfterName,
+	stateBeforeValue: tBeforeValue,
+	stateHTMLCmt:     tHTMLCmt,
+	stateRCDATA:      tSpecialTagEnd,
+	stateAttr:        tAttr,
+	stateURL:         tURL,
+	stateJS:          tJS,
+	stateJSDqStr:     tJSDelimited,
+	stateJSSqStr:     tJSDelimited,
+	stateJSRegexp:    tJSDelimited,
+	stateJSBlockCmt:  tBlockCmt,
+	stateJSLineCmt:   tLineCmt,
+	stateCSS:         tCSS,
+	stateCSSDqStr:    tCSSStr,
+	stateCSSSqStr:    tCSSStr,
+	stateCSSDqURL:    tCSSStr,
+	stateCSSSqURL:    tCSSStr,
+	stateCSSURL:      tCSSStr,
+	stateCSSBlockCmt: tBlockCmt,
+	stateCSSLineCmt:  tLineCmt,
+	stateError:       tError,
+}
+
+var commentStart = []byte("<!--")
+var commentEnd = []byte("-->")
+
+// tText is the context transition function for the text state.
+func tText(c context, s []byte) (context, int) {
+	k := 0
+	for {
+		i := k + bytes.IndexByte(s[k:], '<')
+		if i < k || i+1 == len(s) {
+			return c, len(s)
+		} else if i+4 <= len(s) && bytes.Equal(commentStart, s[i:i+4]) {
+			return context{state: stateHTMLCmt}, i + 4
+		}
+		i++
+		end := false
+		if s[i] == '/' {
+			if i+1 == len(s) {
+				return c, len(s)
+			}
+			end, i = true, i+1
+		}
+		j, e := eatTagName(s, i)
+		if j != i {
+			if end {
+				e = elementNone
+			}
+			// We've found an HTML tag.
+			return context{state: stateTag, element: e}, j
+		}
+		k = j
+	}
+}
+
+var elementContentType = [...]state{
+	elementNone:     stateText,
+	elementScript:   stateJS,
+	elementStyle:    stateCSS,
+	elementTextarea: stateRCDATA,
+	elementTitle:    stateRCDATA,
+}
+
+// tTag is the context transition function for the tag state.
+func tTag(c context, s []byte) (context, int) {
+	// Find the attribute name.
+	i := eatWhiteSpace(s, 0)
+	if i == len(s) {
+		return c, len(s)
+	}
+	if s[i] == '>' {
+		return context{
+			state:   elementContentType[c.element],
+			element: c.element,
+		}, i + 1
+	}
+	j, err := eatAttrName(s, i)
+	if err != nil {
+		return context{state: stateError, err: err}, len(s)
+	}
+	state, attr := stateTag, attrNone
+	if i == j {
+		return context{
+			state: stateError,
+			err:   errorf(ErrBadHTML, nil, 0, "expected space, attr name, or end of tag, but got %q", s[i:]),
+		}, len(s)
+	}
+	switch attrType(string(s[i:j])) {
+	case contentTypeURL:
+		attr = attrURL
+	case contentTypeCSS:
+		attr = attrStyle
+	case contentTypeJS:
+		attr = attrScript
+	}
+	if j == len(s) {
+		state = stateAttrName
+	} else {
+		state = stateAfterName
+	}
+	return context{state: state, element: c.element, attr: attr}, j
+}
+
+// tAttrName is the context transition function for stateAttrName.
+func tAttrName(c context, s []byte) (context, int) {
+	i, err := eatAttrName(s, 0)
+	if err != nil {
+		return context{state: stateError, err: err}, len(s)
+	} else if i != len(s) {
+		c.state = stateAfterName
+	}
+	return c, i
+}
+
+// tAfterName is the context transition function for stateAfterName.
+func tAfterName(c context, s []byte) (context, int) {
+	// Look for the start of the value.
+	i := eatWhiteSpace(s, 0)
+	if i == len(s) {
+		return c, len(s)
+	} else if s[i] != '=' {
+		// Occurs due to tag ending '>', and valueless attribute.
+		c.state = stateTag
+		return c, i
+	}
+	c.state = stateBeforeValue
+	// Consume the "=".
+	return c, i + 1
+}
+
+var attrStartStates = [...]state{
+	attrNone:   stateAttr,
+	attrScript: stateJS,
+	attrStyle:  stateCSS,
+	attrURL:    stateURL,
+}
+
+// tBeforeValue is the context transition function for stateBeforeValue.
+func tBeforeValue(c context, s []byte) (context, int) {
+	i := eatWhiteSpace(s, 0)
+	if i == len(s) {
+		return c, len(s)
+	}
+	// Find the attribute delimiter.
+	delim := delimSpaceOrTagEnd
+	switch s[i] {
+	case '\'':
+		delim, i = delimSingleQuote, i+1
+	case '"':
+		delim, i = delimDoubleQuote, i+1
+	}
+	c.state, c.delim, c.attr = attrStartStates[c.attr], delim, attrNone
+	return c, i
+}
+
+// tHTMLCmt is the context transition function for stateHTMLCmt.
+func tHTMLCmt(c context, s []byte) (context, int) {
+	if i := bytes.Index(s, commentEnd); i != -1 {
+		return context{}, i + 3
+	}
+	return c, len(s)
+}
+
+// specialTagEndMarkers maps element types to the character sequence that
+// case-insensitively signals the end of the special tag body.
+var specialTagEndMarkers = [...]string{
+	elementScript:   "</script",
+	elementStyle:    "</style",
+	elementTextarea: "</textarea",
+	elementTitle:    "</title",
+}
+
+// tSpecialTagEnd is the context transition function for raw text and RCDATA
+// element states.
+func tSpecialTagEnd(c context, s []byte) (context, int) {
+	if c.element != elementNone {
+		if i := strings.Index(strings.ToLower(string(s)), specialTagEndMarkers[c.element]); i != -1 {
+			return context{}, i
+		}
+	}
+	return c, len(s)
+}
+
+// tAttr is the context transition function for the attribute state.
+func tAttr(c context, s []byte) (context, int) {
+	return c, len(s)
+}
+
+// tURL is the context transition function for the URL state.
+func tURL(c context, s []byte) (context, int) {
+	if bytes.IndexAny(s, "#?") >= 0 {
+		c.urlPart = urlPartQueryOrFrag
+	} else if len(s) != eatWhiteSpace(s, 0) && c.urlPart == urlPartNone {
+		// HTML5 uses "Valid URL potentially surrounded by spaces" for
+		// attrs: http://www.w3.org/TR/html5/index.html#attributes-1
+		c.urlPart = urlPartPreQuery
+	}
+	return c, len(s)
+}
+
+// tJS is the context transition function for the JS state.
+func tJS(c context, s []byte) (context, int) {
+	i := bytes.IndexAny(s, `"'/`)
+	if i == -1 {
+		// Entire input is non string, comment, regexp tokens.
+		c.jsCtx = nextJSCtx(s, c.jsCtx)
+		return c, len(s)
+	}
+	c.jsCtx = nextJSCtx(s[:i], c.jsCtx)
+	switch s[i] {
+	case '"':
+		c.state, c.jsCtx = stateJSDqStr, jsCtxRegexp
+	case '\'':
+		c.state, c.jsCtx = stateJSSqStr, jsCtxRegexp
+	case '/':
+		switch {
+		case i+1 < len(s) && s[i+1] == '/':
+			c.state, i = stateJSLineCmt, i+1
+		case i+1 < len(s) && s[i+1] == '*':
+			c.state, i = stateJSBlockCmt, i+1
+		case c.jsCtx == jsCtxRegexp:
+			c.state = stateJSRegexp
+		case c.jsCtx == jsCtxDivOp:
+			c.jsCtx = jsCtxRegexp
+		default:
+			return context{
+				state: stateError,
+				err:   errorf(ErrSlashAmbig, nil, 0, "'/' could start a division or regexp: %.32q", s[i:]),
+			}, len(s)
+		}
+	default:
+		panic("unreachable")
+	}
+	return c, i + 1
+}
+
+// tJSDelimited is the context transition function for the JS string and regexp
+// states.
+func tJSDelimited(c context, s []byte) (context, int) {
+	specials := `\"`
+	switch c.state {
+	case stateJSSqStr:
+		specials = `\'`
+	case stateJSRegexp:
+		specials = `\/[]`
+	}
+
+	k, inCharset := 0, false
+	for {
+		i := k + bytes.IndexAny(s[k:], specials)
+		if i < k {
+			break
+		}
+		switch s[i] {
+		case '\\':
+			i++
+			if i == len(s) {
+				return context{
+					state: stateError,
+					err:   errorf(ErrPartialEscape, nil, 0, "unfinished escape sequence in JS string: %q", s),
+				}, len(s)
+			}
+		case '[':
+			inCharset = true
+		case ']':
+			inCharset = false
+		default:
+			// end delimiter
+			if !inCharset {
+				c.state, c.jsCtx = stateJS, jsCtxDivOp
+				return c, i + 1
+			}
+		}
+		k = i + 1
+	}
+
+	if inCharset {
+		// This can be fixed by making context richer if interpolation
+		// into charsets is desired.
+		return context{
+			state: stateError,
+			err:   errorf(ErrPartialCharset, nil, 0, "unfinished JS regexp charset: %q", s),
+		}, len(s)
+	}
+
+	return c, len(s)
+}
+
+var blockCommentEnd = []byte("*/")
+
+// tBlockCmt is the context transition function for /*comment*/ states.
+func tBlockCmt(c context, s []byte) (context, int) {
+	i := bytes.Index(s, blockCommentEnd)
+	if i == -1 {
+		return c, len(s)
+	}
+	switch c.state {
+	case stateJSBlockCmt:
+		c.state = stateJS
+	case stateCSSBlockCmt:
+		c.state = stateCSS
+	default:
+		panic(c.state.String())
+	}
+	return c, i + 2
+}
+
+// tLineCmt is the context transition function for //comment states.
+func tLineCmt(c context, s []byte) (context, int) {
+	var lineTerminators string
+	var endState state
+	switch c.state {
+	case stateJSLineCmt:
+		lineTerminators, endState = "\n\r\u2028\u2029", stateJS
+	case stateCSSLineCmt:
+		lineTerminators, endState = "\n\f\r", stateCSS
+		// Line comments are not part of any published CSS standard but
+		// are supported by the 4 major browsers.
+		// This defines line comments as
+		//     LINECOMMENT ::= "//" [^\n\f\d]*
+		// since http://www.w3.org/TR/css3-syntax/#SUBTOK-nl defines
+		// newlines:
+		//     nl ::= #xA | #xD #xA | #xD | #xC
+	default:
+		panic(c.state.String())
+	}
+
+	i := bytes.IndexAny(s, lineTerminators)
+	if i == -1 {
+		return c, len(s)
+	}
+	c.state = endState
+	// Per section 7.4 of EcmaScript 5 : http://es5.github.com/#x7.4
+	// "However, the LineTerminator at the end of the line is not
+	// considered to be part of the single-line comment; it is
+	// recognized separately by the lexical grammar and becomes part
+	// of the stream of input elements for the syntactic grammar."
+	return c, i
+}
+
+// tCSS is the context transition function for the CSS state.
+func tCSS(c context, s []byte) (context, int) {
+	// CSS quoted strings are almost never used except for:
+	// (1) URLs as in background: "/foo.png"
+	// (2) Multiword font-names as in font-family: "Times New Roman"
+	// (3) List separators in content values as in inline-lists:
+	//    <style>
+	//    ul.inlineList { list-style: none; padding:0 }
+	//    ul.inlineList > li { display: inline }
+	//    ul.inlineList > li:before { content: ", " }
+	//    ul.inlineList > li:first-child:before { content: "" }
+	//    </style>
+	//    <ul class=inlineList><li>One<li>Two<li>Three</ul>
+	// (4) Attribute value selectors as in a[href="http://example.com/"]
+	//
+	// We conservatively treat all strings as URLs, but make some
+	// allowances to avoid confusion.
+	//
+	// In (1), our conservative assumption is justified.
+	// In (2), valid font names do not contain ':', '?', or '#', so our
+	// conservative assumption is fine since we will never transition past
+	// urlPartPreQuery.
+	// In (3), our protocol heuristic should not be tripped, and there
+	// should not be non-space content after a '?' or '#', so as long as
+	// we only %-encode RFC 3986 reserved characters we are ok.
+	// In (4), we should URL escape for URL attributes, and for others we
+	// have the attribute name available if our conservative assumption
+	// proves problematic for real code.
+
+	k := 0
+	for {
+		i := k + bytes.IndexAny(s[k:], `("'/`)
+		if i < k {
+			return c, len(s)
+		}
+		switch s[i] {
+		case '(':
+			// Look for url to the left.
+			p := bytes.TrimRight(s[:i], "\t\n\f\r ")
+			if endsWithCSSKeyword(p, "url") {
+				j := len(s) - len(bytes.TrimLeft(s[i+1:], "\t\n\f\r "))
+				switch {
+				case j != len(s) && s[j] == '"':
+					c.state, j = stateCSSDqURL, j+1
+				case j != len(s) && s[j] == '\'':
+					c.state, j = stateCSSSqURL, j+1
+				default:
+					c.state = stateCSSURL
+				}
+				return c, j
+			}
+		case '/':
+			if i+1 < len(s) {
+				switch s[i+1] {
+				case '/':
+					c.state = stateCSSLineCmt
+					return c, i + 2
+				case '*':
+					c.state = stateCSSBlockCmt
+					return c, i + 2
+				}
+			}
+		case '"':
+			c.state = stateCSSDqStr
+			return c, i + 1
+		case '\'':
+			c.state = stateCSSSqStr
+			return c, i + 1
+		}
+		k = i + 1
+	}
+}
+
+// tCSSStr is the context transition function for the CSS string and URL states.
+func tCSSStr(c context, s []byte) (context, int) {
+	var endAndEsc string
+	switch c.state {
+	case stateCSSDqStr, stateCSSDqURL:
+		endAndEsc = `\"`
+	case stateCSSSqStr, stateCSSSqURL:
+		endAndEsc = `\'`
+	case stateCSSURL:
+		// Unquoted URLs end with a newline or close parenthesis.
+		// The below includes the wc (whitespace character) and nl.
+		endAndEsc = "\\\t\n\f\r )"
+	default:
+		panic(c.state.String())
+	}
+
+	k := 0
+	for {
+		i := k + bytes.IndexAny(s[k:], endAndEsc)
+		if i < k {
+			c, nread := tURL(c, decodeCSS(s[k:]))
+			return c, k + nread
+		}
+		if s[i] == '\\' {
+			i++
+			if i == len(s) {
+				return context{
+					state: stateError,
+					err:   errorf(ErrPartialEscape, nil, 0, "unfinished escape sequence in CSS string: %q", s),
+				}, len(s)
+			}
+		} else {
+			c.state = stateCSS
+			return c, i + 1
+		}
+		c, _ = tURL(c, decodeCSS(s[:i+1]))
+		k = i + 1
+	}
+}
+
+// tError is the context transition function for the error state.
+func tError(c context, s []byte) (context, int) {
+	return c, len(s)
+}
+
+// eatAttrName returns the largest j such that s[i:j] is an attribute name.
+// It returns an error if s[i:] does not look like it begins with an
+// attribute name, such as encountering a quote mark without a preceding
+// equals sign.
+func eatAttrName(s []byte, i int) (int, *Error) {
+	for j := i; j < len(s); j++ {
+		switch s[j] {
+		case ' ', '\t', '\n', '\f', '\r', '=', '>':
+			return j, nil
+		case '\'', '"', '<':
+			// These result in a parse warning in HTML5 and are
+			// indicative of serious problems if seen in an attr
+			// name in a template.
+			return -1, errorf(ErrBadHTML, nil, 0, "%q in attribute name: %.32q", s[j:j+1], s)
+		default:
+			// No-op.
+		}
+	}
+	return len(s), nil
+}
+
+var elementNameMap = map[string]element{
+	"script":   elementScript,
+	"style":    elementStyle,
+	"textarea": elementTextarea,
+	"title":    elementTitle,
+}
+
+// asciiAlpha reports whether c is an ASCII letter.
+func asciiAlpha(c byte) bool {
+	return 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z'
+}
+
+// asciiAlphaNum reports whether c is an ASCII letter or digit.
+func asciiAlphaNum(c byte) bool {
+	return asciiAlpha(c) || '0' <= c && c <= '9'
+}
+
+// eatTagName returns the largest j such that s[i:j] is a tag name and the tag type.
+func eatTagName(s []byte, i int) (int, element) {
+	if i == len(s) || !asciiAlpha(s[i]) {
+		return i, elementNone
+	}
+	j := i + 1
+	for j < len(s) {
+		x := s[j]
+		if asciiAlphaNum(x) {
+			j++
+			continue
+		}
+		// Allow "x-y" or "x:y" but not "x-", "-y", or "x--y".
+		if (x == ':' || x == '-') && j+1 < len(s) && asciiAlphaNum(s[j+1]) {
+			j += 2
+			continue
+		}
+		break
+	}
+	return j, elementNameMap[strings.ToLower(string(s[i:j]))]
+}
+
+// eatWhiteSpace returns the largest j such that s[i:j] is white space.
+func eatWhiteSpace(s []byte, i int) int {
+	for j := i; j < len(s); j++ {
+		switch s[j] {
+		case ' ', '\t', '\n', '\f', '\r':
+			// No-op.
+		default:
+			return j
+		}
+	}
+	return len(s)
+}
diff --git a/src/pkg/html/template/url.go b/src/html/template/url.go
similarity index 100%
rename from src/pkg/html/template/url.go
rename to src/html/template/url.go
diff --git a/src/pkg/html/template/url_test.go b/src/html/template/url_test.go
similarity index 100%
rename from src/pkg/html/template/url_test.go
rename to src/html/template/url_test.go
diff --git a/src/pkg/image/color/color.go b/src/image/color/color.go
similarity index 100%
rename from src/pkg/image/color/color.go
rename to src/image/color/color.go
diff --git a/src/image/color/palette/gen.go b/src/image/color/palette/gen.go
new file mode 100644
index 0000000..2b5fdaa
--- /dev/null
+++ b/src/image/color/palette/gen.go
@@ -0,0 +1,121 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build ignore
+
+package main
+
+// This program generates palette.go. Invoke it as
+//	go run gen.go -output palette.go
+
+import (
+	"bytes"
+	"flag"
+	"fmt"
+	"go/format"
+	"io"
+	"io/ioutil"
+	"log"
+)
+
+var filename = flag.String("output", "palette.go", "output file name")
+
+func main() {
+	flag.Parse()
+
+	var buf bytes.Buffer
+
+	fmt.Fprintln(&buf, `// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.`)
+	fmt.Fprintln(&buf)
+	fmt.Fprintln(&buf, "// generated by go run gen.go -output palette.go; DO NOT EDIT")
+	fmt.Fprintln(&buf)
+	fmt.Fprintln(&buf, "package palette")
+	fmt.Fprintln(&buf)
+	fmt.Fprintln(&buf, `import "image/color"`)
+	fmt.Fprintln(&buf)
+	printPlan9(&buf)
+	printWebSafe(&buf)
+
+	data, err := format.Source(buf.Bytes())
+	if err != nil {
+		log.Fatal(err)
+	}
+	err = ioutil.WriteFile(*filename, data, 0644)
+	if err != nil {
+		log.Fatal(err)
+	}
+}
+
+func printPlan9(w io.Writer) {
+	c, lines := [3]int{}, [256]string{}
+	for r, i := 0, 0; r != 4; r++ {
+		for v := 0; v != 4; v, i = v+1, i+16 {
+			for g, j := 0, v-r; g != 4; g++ {
+				for b := 0; b != 4; b, j = b+1, j+1 {
+					den := r
+					if g > den {
+						den = g
+					}
+					if b > den {
+						den = b
+					}
+					if den == 0 {
+						c[0] = 0x11 * v
+						c[1] = 0x11 * v
+						c[2] = 0x11 * v
+					} else {
+						num := 17 * (4*den + v)
+						c[0] = r * num / den
+						c[1] = g * num / den
+						c[2] = b * num / den
+					}
+					lines[i+(j&0x0f)] =
+						fmt.Sprintf("\tcolor.RGBA{0x%02x, 0x%02x, 0x%02x, 0xff},", c[0], c[1], c[2])
+				}
+			}
+		}
+	}
+	fmt.Fprintln(w, "// Plan9 is a 256-color palette that partitions the 24-bit RGB space")
+	fmt.Fprintln(w, "// into 4×4×4 subdivision, with 4 shades in each subcube. Compared to the")
+	fmt.Fprintln(w, "// WebSafe, the idea is to reduce the color resolution by dicing the")
+	fmt.Fprintln(w, "// color cube into fewer cells, and to use the extra space to increase the")
+	fmt.Fprintln(w, "// intensity resolution. This results in 16 gray shades (4 gray subcubes with")
+	fmt.Fprintln(w, "// 4 samples in each), 13 shades of each primary and secondary color (3")
+	fmt.Fprintln(w, "// subcubes with 4 samples plus black) and a reasonable selection of colors")
+	fmt.Fprintln(w, "// covering the rest of the color cube. The advantage is better representation")
+	fmt.Fprintln(w, "// of continuous tones.")
+	fmt.Fprintln(w, "//")
+	fmt.Fprintln(w, "// This palette was used in the Plan 9 Operating System, described at")
+	fmt.Fprintln(w, "// http://plan9.bell-labs.com/magic/man2html/6/color")
+	fmt.Fprintln(w, "var Plan9 = []color.Color{")
+	for _, line := range lines {
+		fmt.Fprintln(w, line)
+	}
+	fmt.Fprintln(w, "}")
+	fmt.Fprintln(w)
+}
+
+func printWebSafe(w io.Writer) {
+	lines := [6 * 6 * 6]string{}
+	for r := 0; r < 6; r++ {
+		for g := 0; g < 6; g++ {
+			for b := 0; b < 6; b++ {
+				lines[36*r+6*g+b] =
+					fmt.Sprintf("\tcolor.RGBA{0x%02x, 0x%02x, 0x%02x, 0xff},", 0x33*r, 0x33*g, 0x33*b)
+			}
+		}
+	}
+	fmt.Fprintln(w, "// WebSafe is a 216-color palette that was popularized by early versions")
+	fmt.Fprintln(w, "// of Netscape Navigator. It is also known as the Netscape Color Cube.")
+	fmt.Fprintln(w, "//")
+	fmt.Fprintln(w, "// See http://en.wikipedia.org/wiki/Web_colors#Web-safe_colors for details.")
+	fmt.Fprintln(w, "var WebSafe = []color.Color{")
+	for _, line := range lines {
+		fmt.Fprintln(w, line)
+	}
+	fmt.Fprintln(w, "}")
+	fmt.Fprintln(w)
+}
diff --git a/src/image/color/palette/generate.go b/src/image/color/palette/generate.go
new file mode 100644
index 0000000..64c2ec0
--- /dev/null
+++ b/src/image/color/palette/generate.go
@@ -0,0 +1,8 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:generate go run gen.go -output palette.go
+
+// Package palette provides standard color palettes.
+package palette
diff --git a/src/image/color/palette/palette.go b/src/image/color/palette/palette.go
new file mode 100644
index 0000000..0bf2c8e
--- /dev/null
+++ b/src/image/color/palette/palette.go
@@ -0,0 +1,503 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// generated by go run gen.go -output palette.go; DO NOT EDIT
+
+package palette
+
+import "image/color"
+
+// Plan9 is a 256-color palette that partitions the 24-bit RGB space
+// into 4×4×4 subdivision, with 4 shades in each subcube. Compared to the
+// WebSafe, the idea is to reduce the color resolution by dicing the
+// color cube into fewer cells, and to use the extra space to increase the
+// intensity resolution. This results in 16 gray shades (4 gray subcubes with
+// 4 samples in each), 13 shades of each primary and secondary color (3
+// subcubes with 4 samples plus black) and a reasonable selection of colors
+// covering the rest of the color cube. The advantage is better representation
+// of continuous tones.
+//
+// This palette was used in the Plan 9 Operating System, described at
+// http://plan9.bell-labs.com/magic/man2html/6/color
+var Plan9 = []color.Color{
+	color.RGBA{0x00, 0x00, 0x00, 0xff},
+	color.RGBA{0x00, 0x00, 0x44, 0xff},
+	color.RGBA{0x00, 0x00, 0x88, 0xff},
+	color.RGBA{0x00, 0x00, 0xcc, 0xff},
+	color.RGBA{0x00, 0x44, 0x00, 0xff},
+	color.RGBA{0x00, 0x44, 0x44, 0xff},
+	color.RGBA{0x00, 0x44, 0x88, 0xff},
+	color.RGBA{0x00, 0x44, 0xcc, 0xff},
+	color.RGBA{0x00, 0x88, 0x00, 0xff},
+	color.RGBA{0x00, 0x88, 0x44, 0xff},
+	color.RGBA{0x00, 0x88, 0x88, 0xff},
+	color.RGBA{0x00, 0x88, 0xcc, 0xff},
+	color.RGBA{0x00, 0xcc, 0x00, 0xff},
+	color.RGBA{0x00, 0xcc, 0x44, 0xff},
+	color.RGBA{0x00, 0xcc, 0x88, 0xff},
+	color.RGBA{0x00, 0xcc, 0xcc, 0xff},
+	color.RGBA{0x00, 0xdd, 0xdd, 0xff},
+	color.RGBA{0x11, 0x11, 0x11, 0xff},
+	color.RGBA{0x00, 0x00, 0x55, 0xff},
+	color.RGBA{0x00, 0x00, 0x99, 0xff},
+	color.RGBA{0x00, 0x00, 0xdd, 0xff},
+	color.RGBA{0x00, 0x55, 0x00, 0xff},
+	color.RGBA{0x00, 0x55, 0x55, 0xff},
+	color.RGBA{0x00, 0x4c, 0x99, 0xff},
+	color.RGBA{0x00, 0x49, 0xdd, 0xff},
+	color.RGBA{0x00, 0x99, 0x00, 0xff},
+	color.RGBA{0x00, 0x99, 0x4c, 0xff},
+	color.RGBA{0x00, 0x99, 0x99, 0xff},
+	color.RGBA{0x00, 0x93, 0xdd, 0xff},
+	color.RGBA{0x00, 0xdd, 0x00, 0xff},
+	color.RGBA{0x00, 0xdd, 0x49, 0xff},
+	color.RGBA{0x00, 0xdd, 0x93, 0xff},
+	color.RGBA{0x00, 0xee, 0x9e, 0xff},
+	color.RGBA{0x00, 0xee, 0xee, 0xff},
+	color.RGBA{0x22, 0x22, 0x22, 0xff},
+	color.RGBA{0x00, 0x00, 0x66, 0xff},
+	color.RGBA{0x00, 0x00, 0xaa, 0xff},
+	color.RGBA{0x00, 0x00, 0xee, 0xff},
+	color.RGBA{0x00, 0x66, 0x00, 0xff},
+	color.RGBA{0x00, 0x66, 0x66, 0xff},
+	color.RGBA{0x00, 0x55, 0xaa, 0xff},
+	color.RGBA{0x00, 0x4f, 0xee, 0xff},
+	color.RGBA{0x00, 0xaa, 0x00, 0xff},
+	color.RGBA{0x00, 0xaa, 0x55, 0xff},
+	color.RGBA{0x00, 0xaa, 0xaa, 0xff},
+	color.RGBA{0x00, 0x9e, 0xee, 0xff},
+	color.RGBA{0x00, 0xee, 0x00, 0xff},
+	color.RGBA{0x00, 0xee, 0x4f, 0xff},
+	color.RGBA{0x00, 0xff, 0x55, 0xff},
+	color.RGBA{0x00, 0xff, 0xaa, 0xff},
+	color.RGBA{0x00, 0xff, 0xff, 0xff},
+	color.RGBA{0x33, 0x33, 0x33, 0xff},
+	color.RGBA{0x00, 0x00, 0x77, 0xff},
+	color.RGBA{0x00, 0x00, 0xbb, 0xff},
+	color.RGBA{0x00, 0x00, 0xff, 0xff},
+	color.RGBA{0x00, 0x77, 0x00, 0xff},
+	color.RGBA{0x00, 0x77, 0x77, 0xff},
+	color.RGBA{0x00, 0x5d, 0xbb, 0xff},
+	color.RGBA{0x00, 0x55, 0xff, 0xff},
+	color.RGBA{0x00, 0xbb, 0x00, 0xff},
+	color.RGBA{0x00, 0xbb, 0x5d, 0xff},
+	color.RGBA{0x00, 0xbb, 0xbb, 0xff},
+	color.RGBA{0x00, 0xaa, 0xff, 0xff},
+	color.RGBA{0x00, 0xff, 0x00, 0xff},
+	color.RGBA{0x44, 0x00, 0x44, 0xff},
+	color.RGBA{0x44, 0x00, 0x88, 0xff},
+	color.RGBA{0x44, 0x00, 0xcc, 0xff},
+	color.RGBA{0x44, 0x44, 0x00, 0xff},
+	color.RGBA{0x44, 0x44, 0x44, 0xff},
+	color.RGBA{0x44, 0x44, 0x88, 0xff},
+	color.RGBA{0x44, 0x44, 0xcc, 0xff},
+	color.RGBA{0x44, 0x88, 0x00, 0xff},
+	color.RGBA{0x44, 0x88, 0x44, 0xff},
+	color.RGBA{0x44, 0x88, 0x88, 0xff},
+	color.RGBA{0x44, 0x88, 0xcc, 0xff},
+	color.RGBA{0x44, 0xcc, 0x00, 0xff},
+	color.RGBA{0x44, 0xcc, 0x44, 0xff},
+	color.RGBA{0x44, 0xcc, 0x88, 0xff},
+	color.RGBA{0x44, 0xcc, 0xcc, 0xff},
+	color.RGBA{0x44, 0x00, 0x00, 0xff},
+	color.RGBA{0x55, 0x00, 0x00, 0xff},
+	color.RGBA{0x55, 0x00, 0x55, 0xff},
+	color.RGBA{0x4c, 0x00, 0x99, 0xff},
+	color.RGBA{0x49, 0x00, 0xdd, 0xff},
+	color.RGBA{0x55, 0x55, 0x00, 0xff},
+	color.RGBA{0x55, 0x55, 0x55, 0xff},
+	color.RGBA{0x4c, 0x4c, 0x99, 0xff},
+	color.RGBA{0x49, 0x49, 0xdd, 0xff},
+	color.RGBA{0x4c, 0x99, 0x00, 0xff},
+	color.RGBA{0x4c, 0x99, 0x4c, 0xff},
+	color.RGBA{0x4c, 0x99, 0x99, 0xff},
+	color.RGBA{0x49, 0x93, 0xdd, 0xff},
+	color.RGBA{0x49, 0xdd, 0x00, 0xff},
+	color.RGBA{0x49, 0xdd, 0x49, 0xff},
+	color.RGBA{0x49, 0xdd, 0x93, 0xff},
+	color.RGBA{0x49, 0xdd, 0xdd, 0xff},
+	color.RGBA{0x4f, 0xee, 0xee, 0xff},
+	color.RGBA{0x66, 0x00, 0x00, 0xff},
+	color.RGBA{0x66, 0x00, 0x66, 0xff},
+	color.RGBA{0x55, 0x00, 0xaa, 0xff},
+	color.RGBA{0x4f, 0x00, 0xee, 0xff},
+	color.RGBA{0x66, 0x66, 0x00, 0xff},
+	color.RGBA{0x66, 0x66, 0x66, 0xff},
+	color.RGBA{0x55, 0x55, 0xaa, 0xff},
+	color.RGBA{0x4f, 0x4f, 0xee, 0xff},
+	color.RGBA{0x55, 0xaa, 0x00, 0xff},
+	color.RGBA{0x55, 0xaa, 0x55, 0xff},
+	color.RGBA{0x55, 0xaa, 0xaa, 0xff},
+	color.RGBA{0x4f, 0x9e, 0xee, 0xff},
+	color.RGBA{0x4f, 0xee, 0x00, 0xff},
+	color.RGBA{0x4f, 0xee, 0x4f, 0xff},
+	color.RGBA{0x4f, 0xee, 0x9e, 0xff},
+	color.RGBA{0x55, 0xff, 0xaa, 0xff},
+	color.RGBA{0x55, 0xff, 0xff, 0xff},
+	color.RGBA{0x77, 0x00, 0x00, 0xff},
+	color.RGBA{0x77, 0x00, 0x77, 0xff},
+	color.RGBA{0x5d, 0x00, 0xbb, 0xff},
+	color.RGBA{0x55, 0x00, 0xff, 0xff},
+	color.RGBA{0x77, 0x77, 0x00, 0xff},
+	color.RGBA{0x77, 0x77, 0x77, 0xff},
+	color.RGBA{0x5d, 0x5d, 0xbb, 0xff},
+	color.RGBA{0x55, 0x55, 0xff, 0xff},
+	color.RGBA{0x5d, 0xbb, 0x00, 0xff},
+	color.RGBA{0x5d, 0xbb, 0x5d, 0xff},
+	color.RGBA{0x5d, 0xbb, 0xbb, 0xff},
+	color.RGBA{0x55, 0xaa, 0xff, 0xff},
+	color.RGBA{0x55, 0xff, 0x00, 0xff},
+	color.RGBA{0x55, 0xff, 0x55, 0xff},
+	color.RGBA{0x88, 0x00, 0x88, 0xff},
+	color.RGBA{0x88, 0x00, 0xcc, 0xff},
+	color.RGBA{0x88, 0x44, 0x00, 0xff},
+	color.RGBA{0x88, 0x44, 0x44, 0xff},
+	color.RGBA{0x88, 0x44, 0x88, 0xff},
+	color.RGBA{0x88, 0x44, 0xcc, 0xff},
+	color.RGBA{0x88, 0x88, 0x00, 0xff},
+	color.RGBA{0x88, 0x88, 0x44, 0xff},
+	color.RGBA{0x88, 0x88, 0x88, 0xff},
+	color.RGBA{0x88, 0x88, 0xcc, 0xff},
+	color.RGBA{0x88, 0xcc, 0x00, 0xff},
+	color.RGBA{0x88, 0xcc, 0x44, 0xff},
+	color.RGBA{0x88, 0xcc, 0x88, 0xff},
+	color.RGBA{0x88, 0xcc, 0xcc, 0xff},
+	color.RGBA{0x88, 0x00, 0x00, 0xff},
+	color.RGBA{0x88, 0x00, 0x44, 0xff},
+	color.RGBA{0x99, 0x00, 0x4c, 0xff},
+	color.RGBA{0x99, 0x00, 0x99, 0xff},
+	color.RGBA{0x93, 0x00, 0xdd, 0xff},
+	color.RGBA{0x99, 0x4c, 0x00, 0xff},
+	color.RGBA{0x99, 0x4c, 0x4c, 0xff},
+	color.RGBA{0x99, 0x4c, 0x99, 0xff},
+	color.RGBA{0x93, 0x49, 0xdd, 0xff},
+	color.RGBA{0x99, 0x99, 0x00, 0xff},
+	color.RGBA{0x99, 0x99, 0x4c, 0xff},
+	color.RGBA{0x99, 0x99, 0x99, 0xff},
+	color.RGBA{0x93, 0x93, 0xdd, 0xff},
+	color.RGBA{0x93, 0xdd, 0x00, 0xff},
+	color.RGBA{0x93, 0xdd, 0x49, 0xff},
+	color.RGBA{0x93, 0xdd, 0x93, 0xff},
+	color.RGBA{0x93, 0xdd, 0xdd, 0xff},
+	color.RGBA{0x99, 0x00, 0x00, 0xff},
+	color.RGBA{0xaa, 0x00, 0x00, 0xff},
+	color.RGBA{0xaa, 0x00, 0x55, 0xff},
+	color.RGBA{0xaa, 0x00, 0xaa, 0xff},
+	color.RGBA{0x9e, 0x00, 0xee, 0xff},
+	color.RGBA{0xaa, 0x55, 0x00, 0xff},
+	color.RGBA{0xaa, 0x55, 0x55, 0xff},
+	color.RGBA{0xaa, 0x55, 0xaa, 0xff},
+	color.RGBA{0x9e, 0x4f, 0xee, 0xff},
+	color.RGBA{0xaa, 0xaa, 0x00, 0xff},
+	color.RGBA{0xaa, 0xaa, 0x55, 0xff},
+	color.RGBA{0xaa, 0xaa, 0xaa, 0xff},
+	color.RGBA{0x9e, 0x9e, 0xee, 0xff},
+	color.RGBA{0x9e, 0xee, 0x00, 0xff},
+	color.RGBA{0x9e, 0xee, 0x4f, 0xff},
+	color.RGBA{0x9e, 0xee, 0x9e, 0xff},
+	color.RGBA{0x9e, 0xee, 0xee, 0xff},
+	color.RGBA{0xaa, 0xff, 0xff, 0xff},
+	color.RGBA{0xbb, 0x00, 0x00, 0xff},
+	color.RGBA{0xbb, 0x00, 0x5d, 0xff},
+	color.RGBA{0xbb, 0x00, 0xbb, 0xff},
+	color.RGBA{0xaa, 0x00, 0xff, 0xff},
+	color.RGBA{0xbb, 0x5d, 0x00, 0xff},
+	color.RGBA{0xbb, 0x5d, 0x5d, 0xff},
+	color.RGBA{0xbb, 0x5d, 0xbb, 0xff},
+	color.RGBA{0xaa, 0x55, 0xff, 0xff},
+	color.RGBA{0xbb, 0xbb, 0x00, 0xff},
+	color.RGBA{0xbb, 0xbb, 0x5d, 0xff},
+	color.RGBA{0xbb, 0xbb, 0xbb, 0xff},
+	color.RGBA{0xaa, 0xaa, 0xff, 0xff},
+	color.RGBA{0xaa, 0xff, 0x00, 0xff},
+	color.RGBA{0xaa, 0xff, 0x55, 0xff},
+	color.RGBA{0xaa, 0xff, 0xaa, 0xff},
+	color.RGBA{0xcc, 0x00, 0xcc, 0xff},
+	color.RGBA{0xcc, 0x44, 0x00, 0xff},
+	color.RGBA{0xcc, 0x44, 0x44, 0xff},
+	color.RGBA{0xcc, 0x44, 0x88, 0xff},
+	color.RGBA{0xcc, 0x44, 0xcc, 0xff},
+	color.RGBA{0xcc, 0x88, 0x00, 0xff},
+	color.RGBA{0xcc, 0x88, 0x44, 0xff},
+	color.RGBA{0xcc, 0x88, 0x88, 0xff},
+	color.RGBA{0xcc, 0x88, 0xcc, 0xff},
+	color.RGBA{0xcc, 0xcc, 0x00, 0xff},
+	color.RGBA{0xcc, 0xcc, 0x44, 0xff},
+	color.RGBA{0xcc, 0xcc, 0x88, 0xff},
+	color.RGBA{0xcc, 0xcc, 0xcc, 0xff},
+	color.RGBA{0xcc, 0x00, 0x00, 0xff},
+	color.RGBA{0xcc, 0x00, 0x44, 0xff},
+	color.RGBA{0xcc, 0x00, 0x88, 0xff},
+	color.RGBA{0xdd, 0x00, 0x93, 0xff},
+	color.RGBA{0xdd, 0x00, 0xdd, 0xff},
+	color.RGBA{0xdd, 0x49, 0x00, 0xff},
+	color.RGBA{0xdd, 0x49, 0x49, 0xff},
+	color.RGBA{0xdd, 0x49, 0x93, 0xff},
+	color.RGBA{0xdd, 0x49, 0xdd, 0xff},
+	color.RGBA{0xdd, 0x93, 0x00, 0xff},
+	color.RGBA{0xdd, 0x93, 0x49, 0xff},
+	color.RGBA{0xdd, 0x93, 0x93, 0xff},
+	color.RGBA{0xdd, 0x93, 0xdd, 0xff},
+	color.RGBA{0xdd, 0xdd, 0x00, 0xff},
+	color.RGBA{0xdd, 0xdd, 0x49, 0xff},
+	color.RGBA{0xdd, 0xdd, 0x93, 0xff},
+	color.RGBA{0xdd, 0xdd, 0xdd, 0xff},
+	color.RGBA{0xdd, 0x00, 0x00, 0xff},
+	color.RGBA{0xdd, 0x00, 0x49, 0xff},
+	color.RGBA{0xee, 0x00, 0x4f, 0xff},
+	color.RGBA{0xee, 0x00, 0x9e, 0xff},
+	color.RGBA{0xee, 0x00, 0xee, 0xff},
+	color.RGBA{0xee, 0x4f, 0x00, 0xff},
+	color.RGBA{0xee, 0x4f, 0x4f, 0xff},
+	color.RGBA{0xee, 0x4f, 0x9e, 0xff},
+	color.RGBA{0xee, 0x4f, 0xee, 0xff},
+	color.RGBA{0xee, 0x9e, 0x00, 0xff},
+	color.RGBA{0xee, 0x9e, 0x4f, 0xff},
+	color.RGBA{0xee, 0x9e, 0x9e, 0xff},
+	color.RGBA{0xee, 0x9e, 0xee, 0xff},
+	color.RGBA{0xee, 0xee, 0x00, 0xff},
+	color.RGBA{0xee, 0xee, 0x4f, 0xff},
+	color.RGBA{0xee, 0xee, 0x9e, 0xff},
+	color.RGBA{0xee, 0xee, 0xee, 0xff},
+	color.RGBA{0xee, 0x00, 0x00, 0xff},
+	color.RGBA{0xff, 0x00, 0x00, 0xff},
+	color.RGBA{0xff, 0x00, 0x55, 0xff},
+	color.RGBA{0xff, 0x00, 0xaa, 0xff},
+	color.RGBA{0xff, 0x00, 0xff, 0xff},
+	color.RGBA{0xff, 0x55, 0x00, 0xff},
+	color.RGBA{0xff, 0x55, 0x55, 0xff},
+	color.RGBA{0xff, 0x55, 0xaa, 0xff},
+	color.RGBA{0xff, 0x55, 0xff, 0xff},
+	color.RGBA{0xff, 0xaa, 0x00, 0xff},
+	color.RGBA{0xff, 0xaa, 0x55, 0xff},
+	color.RGBA{0xff, 0xaa, 0xaa, 0xff},
+	color.RGBA{0xff, 0xaa, 0xff, 0xff},
+	color.RGBA{0xff, 0xff, 0x00, 0xff},
+	color.RGBA{0xff, 0xff, 0x55, 0xff},
+	color.RGBA{0xff, 0xff, 0xaa, 0xff},
+	color.RGBA{0xff, 0xff, 0xff, 0xff},
+}
+
+// WebSafe is a 216-color palette that was popularized by early versions
+// of Netscape Navigator. It is also known as the Netscape Color Cube.
+//
+// See http://en.wikipedia.org/wiki/Web_colors#Web-safe_colors for details.
+var WebSafe = []color.Color{
+	color.RGBA{0x00, 0x00, 0x00, 0xff},
+	color.RGBA{0x00, 0x00, 0x33, 0xff},
+	color.RGBA{0x00, 0x00, 0x66, 0xff},
+	color.RGBA{0x00, 0x00, 0x99, 0xff},
+	color.RGBA{0x00, 0x00, 0xcc, 0xff},
+	color.RGBA{0x00, 0x00, 0xff, 0xff},
+	color.RGBA{0x00, 0x33, 0x00, 0xff},
+	color.RGBA{0x00, 0x33, 0x33, 0xff},
+	color.RGBA{0x00, 0x33, 0x66, 0xff},
+	color.RGBA{0x00, 0x33, 0x99, 0xff},
+	color.RGBA{0x00, 0x33, 0xcc, 0xff},
+	color.RGBA{0x00, 0x33, 0xff, 0xff},
+	color.RGBA{0x00, 0x66, 0x00, 0xff},
+	color.RGBA{0x00, 0x66, 0x33, 0xff},
+	color.RGBA{0x00, 0x66, 0x66, 0xff},
+	color.RGBA{0x00, 0x66, 0x99, 0xff},
+	color.RGBA{0x00, 0x66, 0xcc, 0xff},
+	color.RGBA{0x00, 0x66, 0xff, 0xff},
+	color.RGBA{0x00, 0x99, 0x00, 0xff},
+	color.RGBA{0x00, 0x99, 0x33, 0xff},
+	color.RGBA{0x00, 0x99, 0x66, 0xff},
+	color.RGBA{0x00, 0x99, 0x99, 0xff},
+	color.RGBA{0x00, 0x99, 0xcc, 0xff},
+	color.RGBA{0x00, 0x99, 0xff, 0xff},
+	color.RGBA{0x00, 0xcc, 0x00, 0xff},
+	color.RGBA{0x00, 0xcc, 0x33, 0xff},
+	color.RGBA{0x00, 0xcc, 0x66, 0xff},
+	color.RGBA{0x00, 0xcc, 0x99, 0xff},
+	color.RGBA{0x00, 0xcc, 0xcc, 0xff},
+	color.RGBA{0x00, 0xcc, 0xff, 0xff},
+	color.RGBA{0x00, 0xff, 0x00, 0xff},
+	color.RGBA{0x00, 0xff, 0x33, 0xff},
+	color.RGBA{0x00, 0xff, 0x66, 0xff},
+	color.RGBA{0x00, 0xff, 0x99, 0xff},
+	color.RGBA{0x00, 0xff, 0xcc, 0xff},
+	color.RGBA{0x00, 0xff, 0xff, 0xff},
+	color.RGBA{0x33, 0x00, 0x00, 0xff},
+	color.RGBA{0x33, 0x00, 0x33, 0xff},
+	color.RGBA{0x33, 0x00, 0x66, 0xff},
+	color.RGBA{0x33, 0x00, 0x99, 0xff},
+	color.RGBA{0x33, 0x00, 0xcc, 0xff},
+	color.RGBA{0x33, 0x00, 0xff, 0xff},
+	color.RGBA{0x33, 0x33, 0x00, 0xff},
+	color.RGBA{0x33, 0x33, 0x33, 0xff},
+	color.RGBA{0x33, 0x33, 0x66, 0xff},
+	color.RGBA{0x33, 0x33, 0x99, 0xff},
+	color.RGBA{0x33, 0x33, 0xcc, 0xff},
+	color.RGBA{0x33, 0x33, 0xff, 0xff},
+	color.RGBA{0x33, 0x66, 0x00, 0xff},
+	color.RGBA{0x33, 0x66, 0x33, 0xff},
+	color.RGBA{0x33, 0x66, 0x66, 0xff},
+	color.RGBA{0x33, 0x66, 0x99, 0xff},
+	color.RGBA{0x33, 0x66, 0xcc, 0xff},
+	color.RGBA{0x33, 0x66, 0xff, 0xff},
+	color.RGBA{0x33, 0x99, 0x00, 0xff},
+	color.RGBA{0x33, 0x99, 0x33, 0xff},
+	color.RGBA{0x33, 0x99, 0x66, 0xff},
+	color.RGBA{0x33, 0x99, 0x99, 0xff},
+	color.RGBA{0x33, 0x99, 0xcc, 0xff},
+	color.RGBA{0x33, 0x99, 0xff, 0xff},
+	color.RGBA{0x33, 0xcc, 0x00, 0xff},
+	color.RGBA{0x33, 0xcc, 0x33, 0xff},
+	color.RGBA{0x33, 0xcc, 0x66, 0xff},
+	color.RGBA{0x33, 0xcc, 0x99, 0xff},
+	color.RGBA{0x33, 0xcc, 0xcc, 0xff},
+	color.RGBA{0x33, 0xcc, 0xff, 0xff},
+	color.RGBA{0x33, 0xff, 0x00, 0xff},
+	color.RGBA{0x33, 0xff, 0x33, 0xff},
+	color.RGBA{0x33, 0xff, 0x66, 0xff},
+	color.RGBA{0x33, 0xff, 0x99, 0xff},
+	color.RGBA{0x33, 0xff, 0xcc, 0xff},
+	color.RGBA{0x33, 0xff, 0xff, 0xff},
+	color.RGBA{0x66, 0x00, 0x00, 0xff},
+	color.RGBA{0x66, 0x00, 0x33, 0xff},
+	color.RGBA{0x66, 0x00, 0x66, 0xff},
+	color.RGBA{0x66, 0x00, 0x99, 0xff},
+	color.RGBA{0x66, 0x00, 0xcc, 0xff},
+	color.RGBA{0x66, 0x00, 0xff, 0xff},
+	color.RGBA{0x66, 0x33, 0x00, 0xff},
+	color.RGBA{0x66, 0x33, 0x33, 0xff},
+	color.RGBA{0x66, 0x33, 0x66, 0xff},
+	color.RGBA{0x66, 0x33, 0x99, 0xff},
+	color.RGBA{0x66, 0x33, 0xcc, 0xff},
+	color.RGBA{0x66, 0x33, 0xff, 0xff},
+	color.RGBA{0x66, 0x66, 0x00, 0xff},
+	color.RGBA{0x66, 0x66, 0x33, 0xff},
+	color.RGBA{0x66, 0x66, 0x66, 0xff},
+	color.RGBA{0x66, 0x66, 0x99, 0xff},
+	color.RGBA{0x66, 0x66, 0xcc, 0xff},
+	color.RGBA{0x66, 0x66, 0xff, 0xff},
+	color.RGBA{0x66, 0x99, 0x00, 0xff},
+	color.RGBA{0x66, 0x99, 0x33, 0xff},
+	color.RGBA{0x66, 0x99, 0x66, 0xff},
+	color.RGBA{0x66, 0x99, 0x99, 0xff},
+	color.RGBA{0x66, 0x99, 0xcc, 0xff},
+	color.RGBA{0x66, 0x99, 0xff, 0xff},
+	color.RGBA{0x66, 0xcc, 0x00, 0xff},
+	color.RGBA{0x66, 0xcc, 0x33, 0xff},
+	color.RGBA{0x66, 0xcc, 0x66, 0xff},
+	color.RGBA{0x66, 0xcc, 0x99, 0xff},
+	color.RGBA{0x66, 0xcc, 0xcc, 0xff},
+	color.RGBA{0x66, 0xcc, 0xff, 0xff},
+	color.RGBA{0x66, 0xff, 0x00, 0xff},
+	color.RGBA{0x66, 0xff, 0x33, 0xff},
+	color.RGBA{0x66, 0xff, 0x66, 0xff},
+	color.RGBA{0x66, 0xff, 0x99, 0xff},
+	color.RGBA{0x66, 0xff, 0xcc, 0xff},
+	color.RGBA{0x66, 0xff, 0xff, 0xff},
+	color.RGBA{0x99, 0x00, 0x00, 0xff},
+	color.RGBA{0x99, 0x00, 0x33, 0xff},
+	color.RGBA{0x99, 0x00, 0x66, 0xff},
+	color.RGBA{0x99, 0x00, 0x99, 0xff},
+	color.RGBA{0x99, 0x00, 0xcc, 0xff},
+	color.RGBA{0x99, 0x00, 0xff, 0xff},
+	color.RGBA{0x99, 0x33, 0x00, 0xff},
+	color.RGBA{0x99, 0x33, 0x33, 0xff},
+	color.RGBA{0x99, 0x33, 0x66, 0xff},
+	color.RGBA{0x99, 0x33, 0x99, 0xff},
+	color.RGBA{0x99, 0x33, 0xcc, 0xff},
+	color.RGBA{0x99, 0x33, 0xff, 0xff},
+	color.RGBA{0x99, 0x66, 0x00, 0xff},
+	color.RGBA{0x99, 0x66, 0x33, 0xff},
+	color.RGBA{0x99, 0x66, 0x66, 0xff},
+	color.RGBA{0x99, 0x66, 0x99, 0xff},
+	color.RGBA{0x99, 0x66, 0xcc, 0xff},
+	color.RGBA{0x99, 0x66, 0xff, 0xff},
+	color.RGBA{0x99, 0x99, 0x00, 0xff},
+	color.RGBA{0x99, 0x99, 0x33, 0xff},
+	color.RGBA{0x99, 0x99, 0x66, 0xff},
+	color.RGBA{0x99, 0x99, 0x99, 0xff},
+	color.RGBA{0x99, 0x99, 0xcc, 0xff},
+	color.RGBA{0x99, 0x99, 0xff, 0xff},
+	color.RGBA{0x99, 0xcc, 0x00, 0xff},
+	color.RGBA{0x99, 0xcc, 0x33, 0xff},
+	color.RGBA{0x99, 0xcc, 0x66, 0xff},
+	color.RGBA{0x99, 0xcc, 0x99, 0xff},
+	color.RGBA{0x99, 0xcc, 0xcc, 0xff},
+	color.RGBA{0x99, 0xcc, 0xff, 0xff},
+	color.RGBA{0x99, 0xff, 0x00, 0xff},
+	color.RGBA{0x99, 0xff, 0x33, 0xff},
+	color.RGBA{0x99, 0xff, 0x66, 0xff},
+	color.RGBA{0x99, 0xff, 0x99, 0xff},
+	color.RGBA{0x99, 0xff, 0xcc, 0xff},
+	color.RGBA{0x99, 0xff, 0xff, 0xff},
+	color.RGBA{0xcc, 0x00, 0x00, 0xff},
+	color.RGBA{0xcc, 0x00, 0x33, 0xff},
+	color.RGBA{0xcc, 0x00, 0x66, 0xff},
+	color.RGBA{0xcc, 0x00, 0x99, 0xff},
+	color.RGBA{0xcc, 0x00, 0xcc, 0xff},
+	color.RGBA{0xcc, 0x00, 0xff, 0xff},
+	color.RGBA{0xcc, 0x33, 0x00, 0xff},
+	color.RGBA{0xcc, 0x33, 0x33, 0xff},
+	color.RGBA{0xcc, 0x33, 0x66, 0xff},
+	color.RGBA{0xcc, 0x33, 0x99, 0xff},
+	color.RGBA{0xcc, 0x33, 0xcc, 0xff},
+	color.RGBA{0xcc, 0x33, 0xff, 0xff},
+	color.RGBA{0xcc, 0x66, 0x00, 0xff},
+	color.RGBA{0xcc, 0x66, 0x33, 0xff},
+	color.RGBA{0xcc, 0x66, 0x66, 0xff},
+	color.RGBA{0xcc, 0x66, 0x99, 0xff},
+	color.RGBA{0xcc, 0x66, 0xcc, 0xff},
+	color.RGBA{0xcc, 0x66, 0xff, 0xff},
+	color.RGBA{0xcc, 0x99, 0x00, 0xff},
+	color.RGBA{0xcc, 0x99, 0x33, 0xff},
+	color.RGBA{0xcc, 0x99, 0x66, 0xff},
+	color.RGBA{0xcc, 0x99, 0x99, 0xff},
+	color.RGBA{0xcc, 0x99, 0xcc, 0xff},
+	color.RGBA{0xcc, 0x99, 0xff, 0xff},
+	color.RGBA{0xcc, 0xcc, 0x00, 0xff},
+	color.RGBA{0xcc, 0xcc, 0x33, 0xff},
+	color.RGBA{0xcc, 0xcc, 0x66, 0xff},
+	color.RGBA{0xcc, 0xcc, 0x99, 0xff},
+	color.RGBA{0xcc, 0xcc, 0xcc, 0xff},
+	color.RGBA{0xcc, 0xcc, 0xff, 0xff},
+	color.RGBA{0xcc, 0xff, 0x00, 0xff},
+	color.RGBA{0xcc, 0xff, 0x33, 0xff},
+	color.RGBA{0xcc, 0xff, 0x66, 0xff},
+	color.RGBA{0xcc, 0xff, 0x99, 0xff},
+	color.RGBA{0xcc, 0xff, 0xcc, 0xff},
+	color.RGBA{0xcc, 0xff, 0xff, 0xff},
+	color.RGBA{0xff, 0x00, 0x00, 0xff},
+	color.RGBA{0xff, 0x00, 0x33, 0xff},
+	color.RGBA{0xff, 0x00, 0x66, 0xff},
+	color.RGBA{0xff, 0x00, 0x99, 0xff},
+	color.RGBA{0xff, 0x00, 0xcc, 0xff},
+	color.RGBA{0xff, 0x00, 0xff, 0xff},
+	color.RGBA{0xff, 0x33, 0x00, 0xff},
+	color.RGBA{0xff, 0x33, 0x33, 0xff},
+	color.RGBA{0xff, 0x33, 0x66, 0xff},
+	color.RGBA{0xff, 0x33, 0x99, 0xff},
+	color.RGBA{0xff, 0x33, 0xcc, 0xff},
+	color.RGBA{0xff, 0x33, 0xff, 0xff},
+	color.RGBA{0xff, 0x66, 0x00, 0xff},
+	color.RGBA{0xff, 0x66, 0x33, 0xff},
+	color.RGBA{0xff, 0x66, 0x66, 0xff},
+	color.RGBA{0xff, 0x66, 0x99, 0xff},
+	color.RGBA{0xff, 0x66, 0xcc, 0xff},
+	color.RGBA{0xff, 0x66, 0xff, 0xff},
+	color.RGBA{0xff, 0x99, 0x00, 0xff},
+	color.RGBA{0xff, 0x99, 0x33, 0xff},
+	color.RGBA{0xff, 0x99, 0x66, 0xff},
+	color.RGBA{0xff, 0x99, 0x99, 0xff},
+	color.RGBA{0xff, 0x99, 0xcc, 0xff},
+	color.RGBA{0xff, 0x99, 0xff, 0xff},
+	color.RGBA{0xff, 0xcc, 0x00, 0xff},
+	color.RGBA{0xff, 0xcc, 0x33, 0xff},
+	color.RGBA{0xff, 0xcc, 0x66, 0xff},
+	color.RGBA{0xff, 0xcc, 0x99, 0xff},
+	color.RGBA{0xff, 0xcc, 0xcc, 0xff},
+	color.RGBA{0xff, 0xcc, 0xff, 0xff},
+	color.RGBA{0xff, 0xff, 0x00, 0xff},
+	color.RGBA{0xff, 0xff, 0x33, 0xff},
+	color.RGBA{0xff, 0xff, 0x66, 0xff},
+	color.RGBA{0xff, 0xff, 0x99, 0xff},
+	color.RGBA{0xff, 0xff, 0xcc, 0xff},
+	color.RGBA{0xff, 0xff, 0xff, 0xff},
+}
diff --git a/src/pkg/image/color/ycbcr.go b/src/image/color/ycbcr.go
similarity index 100%
rename from src/pkg/image/color/ycbcr.go
rename to src/image/color/ycbcr.go
diff --git a/src/pkg/image/color/ycbcr_test.go b/src/image/color/ycbcr_test.go
similarity index 100%
rename from src/pkg/image/color/ycbcr_test.go
rename to src/image/color/ycbcr_test.go
diff --git a/src/pkg/image/decode_example_test.go b/src/image/decode_example_test.go
similarity index 100%
rename from src/pkg/image/decode_example_test.go
rename to src/image/decode_example_test.go
diff --git a/src/pkg/image/decode_test.go b/src/image/decode_test.go
similarity index 100%
rename from src/pkg/image/decode_test.go
rename to src/image/decode_test.go
diff --git a/src/pkg/image/draw/bench_test.go b/src/image/draw/bench_test.go
similarity index 100%
rename from src/pkg/image/draw/bench_test.go
rename to src/image/draw/bench_test.go
diff --git a/src/pkg/image/draw/clip_test.go b/src/image/draw/clip_test.go
similarity index 100%
rename from src/pkg/image/draw/clip_test.go
rename to src/image/draw/clip_test.go
diff --git a/src/pkg/image/draw/draw.go b/src/image/draw/draw.go
similarity index 100%
rename from src/pkg/image/draw/draw.go
rename to src/image/draw/draw.go
diff --git a/src/pkg/image/draw/draw_test.go b/src/image/draw/draw_test.go
similarity index 100%
rename from src/pkg/image/draw/draw_test.go
rename to src/image/draw/draw_test.go
diff --git a/src/pkg/image/format.go b/src/image/format.go
similarity index 100%
rename from src/pkg/image/format.go
rename to src/image/format.go
diff --git a/src/pkg/image/geom.go b/src/image/geom.go
similarity index 100%
rename from src/pkg/image/geom.go
rename to src/image/geom.go
diff --git a/src/image/gif/reader.go b/src/image/gif/reader.go
new file mode 100644
index 0000000..5a863e2
--- /dev/null
+++ b/src/image/gif/reader.go
@@ -0,0 +1,465 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package gif implements a GIF image decoder and encoder.
+//
+// The GIF specification is at http://www.w3.org/Graphics/GIF/spec-gif89a.txt.
+package gif
+
+import (
+	"bufio"
+	"compress/lzw"
+	"errors"
+	"fmt"
+	"image"
+	"image/color"
+	"io"
+)
+
+var (
+	errNotEnough = errors.New("gif: not enough image data")
+	errTooMuch   = errors.New("gif: too much image data")
+	errBadPixel  = errors.New("gif: invalid pixel value")
+)
+
+// If the io.Reader does not also have ReadByte, then decode will introduce its own buffering.
+type reader interface {
+	io.Reader
+	io.ByteReader
+}
+
+// Masks etc.
+const (
+	// Fields.
+	fColorMapFollows = 1 << 7
+
+	// Image fields.
+	ifLocalColorTable = 1 << 7
+	ifInterlace       = 1 << 6
+	ifPixelSizeMask   = 7
+
+	// Graphic control flags.
+	gcTransparentColorSet = 1 << 0
+)
+
+// Section indicators.
+const (
+	sExtension       = 0x21
+	sImageDescriptor = 0x2C
+	sTrailer         = 0x3B
+)
+
+// Extensions.
+const (
+	eText           = 0x01 // Plain Text
+	eGraphicControl = 0xF9 // Graphic Control
+	eComment        = 0xFE // Comment
+	eApplication    = 0xFF // Application
+)
+
+// decoder is the type used to decode a GIF file.
+type decoder struct {
+	r reader
+
+	// From header.
+	vers            string
+	width           int
+	height          int
+	flags           byte
+	headerFields    byte
+	backgroundIndex byte
+	loopCount       int
+	delayTime       int
+
+	// Unused from header.
+	aspect byte
+
+	// From image descriptor.
+	imageFields byte
+
+	// From graphics control.
+	transparentIndex    byte
+	hasTransparentIndex bool
+
+	// Computed.
+	pixelSize      uint
+	globalColorMap color.Palette
+
+	// Used when decoding.
+	delay []int
+	image []*image.Paletted
+	tmp   [1024]byte // must be at least 768 so we can read color map
+}
+
+// blockReader parses the block structure of GIF image data, which
+// comprises (n, (n bytes)) blocks, with 1 <= n <= 255.  It is the
+// reader given to the LZW decoder, which is thus immune to the
+// blocking.  After the LZW decoder completes, there will be a 0-byte
+// block remaining (0, ()), which is consumed when checking that the
+// blockReader is exhausted.
+type blockReader struct {
+	r     reader
+	slice []byte
+	err   error
+	tmp   [256]byte
+}
+
+func (b *blockReader) Read(p []byte) (int, error) {
+	if b.err != nil {
+		return 0, b.err
+	}
+	if len(p) == 0 {
+		return 0, nil
+	}
+	if len(b.slice) == 0 {
+		var blockLen uint8
+		blockLen, b.err = b.r.ReadByte()
+		if b.err != nil {
+			return 0, b.err
+		}
+		if blockLen == 0 {
+			b.err = io.EOF
+			return 0, b.err
+		}
+		b.slice = b.tmp[0:blockLen]
+		if _, b.err = io.ReadFull(b.r, b.slice); b.err != nil {
+			return 0, b.err
+		}
+	}
+	n := copy(p, b.slice)
+	b.slice = b.slice[n:]
+	return n, nil
+}
+
+// decode reads a GIF image from r and stores the result in d.
+func (d *decoder) decode(r io.Reader, configOnly bool) error {
+	// Add buffering if r does not provide ReadByte.
+	if rr, ok := r.(reader); ok {
+		d.r = rr
+	} else {
+		d.r = bufio.NewReader(r)
+	}
+
+	err := d.readHeaderAndScreenDescriptor()
+	if err != nil {
+		return err
+	}
+	if configOnly {
+		return nil
+	}
+
+	if d.headerFields&fColorMapFollows != 0 {
+		if d.globalColorMap, err = d.readColorMap(); err != nil {
+			return err
+		}
+	}
+
+	for {
+		c, err := d.r.ReadByte()
+		if err != nil {
+			return err
+		}
+		switch c {
+		case sExtension:
+			if err = d.readExtension(); err != nil {
+				return err
+			}
+
+		case sImageDescriptor:
+			m, err := d.newImageFromDescriptor()
+			if err != nil {
+				return err
+			}
+			useLocalColorMap := d.imageFields&fColorMapFollows != 0
+			if useLocalColorMap {
+				m.Palette, err = d.readColorMap()
+				if err != nil {
+					return err
+				}
+			} else {
+				m.Palette = d.globalColorMap
+			}
+			if d.hasTransparentIndex && int(d.transparentIndex) < len(m.Palette) {
+				if !useLocalColorMap {
+					// Clone the global color map.
+					m.Palette = append(color.Palette(nil), d.globalColorMap...)
+				}
+				m.Palette[d.transparentIndex] = color.RGBA{}
+			}
+			litWidth, err := d.r.ReadByte()
+			if err != nil {
+				return err
+			}
+			if litWidth < 2 || litWidth > 8 {
+				return fmt.Errorf("gif: pixel size in decode out of range: %d", litWidth)
+			}
+			// A wonderfully Go-like piece of magic.
+			br := &blockReader{r: d.r}
+			lzwr := lzw.NewReader(br, lzw.LSB, int(litWidth))
+			defer lzwr.Close()
+			if _, err = io.ReadFull(lzwr, m.Pix); err != nil {
+				if err != io.ErrUnexpectedEOF {
+					return err
+				}
+				return errNotEnough
+			}
+			// Both lzwr and br should be exhausted. Reading from them
+			// should yield (0, io.EOF).
+			if n, err := lzwr.Read(d.tmp[:1]); n != 0 || err != io.EOF {
+				if err != nil {
+					return err
+				}
+				return errTooMuch
+			}
+			if n, err := br.Read(d.tmp[:1]); n != 0 || err != io.EOF {
+				if err != nil {
+					return err
+				}
+				return errTooMuch
+			}
+
+			// Check that the color indexes are inside the palette.
+			if len(m.Palette) < 256 {
+				for _, pixel := range m.Pix {
+					if int(pixel) >= len(m.Palette) {
+						return errBadPixel
+					}
+				}
+			}
+
+			// Undo the interlacing if necessary.
+			if d.imageFields&ifInterlace != 0 {
+				uninterlace(m)
+			}
+
+			d.image = append(d.image, m)
+			d.delay = append(d.delay, d.delayTime)
+			// The GIF89a spec, Section 23 (Graphic Control Extension) says:
+			// "The scope of this extension is the first graphic rendering block
+			// to follow." We therefore reset the GCE fields to zero.
+			d.delayTime = 0
+			d.hasTransparentIndex = false
+
+		case sTrailer:
+			if len(d.image) == 0 {
+				return io.ErrUnexpectedEOF
+			}
+			return nil
+
+		default:
+			return fmt.Errorf("gif: unknown block type: 0x%.2x", c)
+		}
+	}
+}
+
+func (d *decoder) readHeaderAndScreenDescriptor() error {
+	_, err := io.ReadFull(d.r, d.tmp[0:13])
+	if err != nil {
+		return err
+	}
+	d.vers = string(d.tmp[0:6])
+	if d.vers != "GIF87a" && d.vers != "GIF89a" {
+		return fmt.Errorf("gif: can't recognize format %s", d.vers)
+	}
+	d.width = int(d.tmp[6]) + int(d.tmp[7])<<8
+	d.height = int(d.tmp[8]) + int(d.tmp[9])<<8
+	d.headerFields = d.tmp[10]
+	d.backgroundIndex = d.tmp[11]
+	d.aspect = d.tmp[12]
+	d.loopCount = -1
+	d.pixelSize = uint(d.headerFields&7) + 1
+	return nil
+}
+
+func (d *decoder) readColorMap() (color.Palette, error) {
+	if d.pixelSize > 8 {
+		return nil, fmt.Errorf("gif: can't handle %d bits per pixel", d.pixelSize)
+	}
+	numColors := 1 << d.pixelSize
+	if d.imageFields&ifLocalColorTable != 0 {
+		numColors = 1 << ((d.imageFields & ifPixelSizeMask) + 1)
+	}
+	numValues := 3 * numColors
+	_, err := io.ReadFull(d.r, d.tmp[0:numValues])
+	if err != nil {
+		return nil, fmt.Errorf("gif: short read on color map: %s", err)
+	}
+	colorMap := make(color.Palette, numColors)
+	j := 0
+	for i := range colorMap {
+		colorMap[i] = color.RGBA{d.tmp[j+0], d.tmp[j+1], d.tmp[j+2], 0xFF}
+		j += 3
+	}
+	return colorMap, nil
+}
+
+func (d *decoder) readExtension() error {
+	extension, err := d.r.ReadByte()
+	if err != nil {
+		return err
+	}
+	size := 0
+	switch extension {
+	case eText:
+		size = 13
+	case eGraphicControl:
+		return d.readGraphicControl()
+	case eComment:
+		// nothing to do but read the data.
+	case eApplication:
+		b, err := d.r.ReadByte()
+		if err != nil {
+			return err
+		}
+		// The spec requires size be 11, but Adobe sometimes uses 10.
+		size = int(b)
+	default:
+		return fmt.Errorf("gif: unknown extension 0x%.2x", extension)
+	}
+	if size > 0 {
+		if _, err := io.ReadFull(d.r, d.tmp[0:size]); err != nil {
+			return err
+		}
+	}
+
+	// Application Extension with "NETSCAPE2.0" as string and 1 in data means
+	// this extension defines a loop count.
+	if extension == eApplication && string(d.tmp[:size]) == "NETSCAPE2.0" {
+		n, err := d.readBlock()
+		if n == 0 || err != nil {
+			return err
+		}
+		if n == 3 && d.tmp[0] == 1 {
+			d.loopCount = int(d.tmp[1]) | int(d.tmp[2])<<8
+		}
+	}
+	for {
+		n, err := d.readBlock()
+		if n == 0 || err != nil {
+			return err
+		}
+	}
+}
+
+func (d *decoder) readGraphicControl() error {
+	if _, err := io.ReadFull(d.r, d.tmp[0:6]); err != nil {
+		return fmt.Errorf("gif: can't read graphic control: %s", err)
+	}
+	d.flags = d.tmp[1]
+	d.delayTime = int(d.tmp[2]) | int(d.tmp[3])<<8
+	if d.flags&gcTransparentColorSet != 0 {
+		d.transparentIndex = d.tmp[4]
+		d.hasTransparentIndex = true
+	}
+	return nil
+}
+
+func (d *decoder) newImageFromDescriptor() (*image.Paletted, error) {
+	if _, err := io.ReadFull(d.r, d.tmp[0:9]); err != nil {
+		return nil, fmt.Errorf("gif: can't read image descriptor: %s", err)
+	}
+	left := int(d.tmp[0]) + int(d.tmp[1])<<8
+	top := int(d.tmp[2]) + int(d.tmp[3])<<8
+	width := int(d.tmp[4]) + int(d.tmp[5])<<8
+	height := int(d.tmp[6]) + int(d.tmp[7])<<8
+	d.imageFields = d.tmp[8]
+
+	// The GIF89a spec, Section 20 (Image Descriptor) says:
+	// "Each image must fit within the boundaries of the Logical
+	// Screen, as defined in the Logical Screen Descriptor."
+	bounds := image.Rect(left, top, left+width, top+height)
+	if bounds != bounds.Intersect(image.Rect(0, 0, d.width, d.height)) {
+		return nil, errors.New("gif: frame bounds larger than image bounds")
+	}
+	return image.NewPaletted(bounds, nil), nil
+}
+
+func (d *decoder) readBlock() (int, error) {
+	n, err := d.r.ReadByte()
+	if n == 0 || err != nil {
+		return 0, err
+	}
+	return io.ReadFull(d.r, d.tmp[0:n])
+}
+
+// interlaceScan defines the ordering for a pass of the interlace algorithm.
+type interlaceScan struct {
+	skip, start int
+}
+
+// interlacing represents the set of scans in an interlaced GIF image.
+var interlacing = []interlaceScan{
+	{8, 0}, // Group 1 : Every 8th. row, starting with row 0.
+	{8, 4}, // Group 2 : Every 8th. row, starting with row 4.
+	{4, 2}, // Group 3 : Every 4th. row, starting with row 2.
+	{2, 1}, // Group 4 : Every 2nd. row, starting with row 1.
+}
+
+// uninterlace rearranges the pixels in m to account for interlaced input.
+func uninterlace(m *image.Paletted) {
+	var nPix []uint8
+	dx := m.Bounds().Dx()
+	dy := m.Bounds().Dy()
+	nPix = make([]uint8, dx*dy)
+	offset := 0 // steps through the input by sequential scan lines.
+	for _, pass := range interlacing {
+		nOffset := pass.start * dx // steps through the output as defined by pass.
+		for y := pass.start; y < dy; y += pass.skip {
+			copy(nPix[nOffset:nOffset+dx], m.Pix[offset:offset+dx])
+			offset += dx
+			nOffset += dx * pass.skip
+		}
+	}
+	m.Pix = nPix
+}
+
+// Decode reads a GIF image from r and returns the first embedded
+// image as an image.Image.
+func Decode(r io.Reader) (image.Image, error) {
+	var d decoder
+	if err := d.decode(r, false); err != nil {
+		return nil, err
+	}
+	return d.image[0], nil
+}
+
+// GIF represents the possibly multiple images stored in a GIF file.
+type GIF struct {
+	Image     []*image.Paletted // The successive images.
+	Delay     []int             // The successive delay times, one per frame, in 100ths of a second.
+	LoopCount int               // The loop count.
+}
+
+// DecodeAll reads a GIF image from r and returns the sequential frames
+// and timing information.
+func DecodeAll(r io.Reader) (*GIF, error) {
+	var d decoder
+	if err := d.decode(r, false); err != nil {
+		return nil, err
+	}
+	gif := &GIF{
+		Image:     d.image,
+		LoopCount: d.loopCount,
+		Delay:     d.delay,
+	}
+	return gif, nil
+}
+
+// DecodeConfig returns the global color model and dimensions of a GIF image
+// without decoding the entire image.
+func DecodeConfig(r io.Reader) (image.Config, error) {
+	var d decoder
+	if err := d.decode(r, true); err != nil {
+		return image.Config{}, err
+	}
+	return image.Config{
+		ColorModel: d.globalColorMap,
+		Width:      d.width,
+		Height:     d.height,
+	}, nil
+}
+
+func init() {
+	image.RegisterFormat("gif", "GIF8?a", Decode, DecodeConfig)
+}
diff --git a/src/image/gif/reader_test.go b/src/image/gif/reader_test.go
new file mode 100644
index 0000000..7b6f504
--- /dev/null
+++ b/src/image/gif/reader_test.go
@@ -0,0 +1,247 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package gif
+
+import (
+	"bytes"
+	"compress/lzw"
+	"image"
+	"image/color"
+	"reflect"
+	"testing"
+)
+
+// header, palette and trailer are parts of a valid 2x1 GIF image.
+const (
+	headerStr = "GIF89a" +
+		"\x02\x00\x01\x00" + // width=2, height=1
+		"\x80\x00\x00" // headerFields=(a color map of 2 pixels), backgroundIndex, aspect
+	paletteStr = "\x10\x20\x30\x40\x50\x60" // the color map, also known as a palette
+	trailerStr = "\x3b"
+)
+
+// lzwEncode returns an LZW encoding (with 2-bit literals) of n zeroes.
+func lzwEncode(n int) []byte {
+	b := &bytes.Buffer{}
+	w := lzw.NewWriter(b, lzw.LSB, 2)
+	w.Write(make([]byte, n))
+	w.Close()
+	return b.Bytes()
+}
+
+func TestDecode(t *testing.T) {
+	testCases := []struct {
+		nPix    int  // The number of pixels in the image data.
+		extra   bool // Whether to write an extra block after the LZW-encoded data.
+		wantErr error
+	}{
+		{0, false, errNotEnough},
+		{1, false, errNotEnough},
+		{2, false, nil},
+		{2, true, errTooMuch},
+		{3, false, errTooMuch},
+	}
+	for _, tc := range testCases {
+		b := &bytes.Buffer{}
+		b.WriteString(headerStr)
+		b.WriteString(paletteStr)
+		// Write an image with bounds 2x1 but tc.nPix pixels. If tc.nPix != 2
+		// then this should result in an invalid GIF image. First, write a
+		// magic 0x2c (image descriptor) byte, bounds=(0,0)-(2,1), a flags
+		// byte, and 2-bit LZW literals.
+		b.WriteString("\x2c\x00\x00\x00\x00\x02\x00\x01\x00\x00\x02")
+		if tc.nPix > 0 {
+			enc := lzwEncode(tc.nPix)
+			if len(enc) > 0xff {
+				t.Errorf("nPix=%d, extra=%t: compressed length %d is too large", tc.nPix, tc.extra, len(enc))
+				continue
+			}
+			b.WriteByte(byte(len(enc)))
+			b.Write(enc)
+		}
+		if tc.extra {
+			b.WriteString("\x01\x02") // A 1-byte payload with an 0x02 byte.
+		}
+		b.WriteByte(0x00) // An empty block signifies the end of the image data.
+		b.WriteString(trailerStr)
+
+		got, err := Decode(b)
+		if err != tc.wantErr {
+			t.Errorf("nPix=%d, extra=%t\ngot  %v\nwant %v", tc.nPix, tc.extra, err, tc.wantErr)
+		}
+
+		if tc.wantErr != nil {
+			continue
+		}
+		want := &image.Paletted{
+			Pix:    []uint8{0, 0},
+			Stride: 2,
+			Rect:   image.Rect(0, 0, 2, 1),
+			Palette: color.Palette{
+				color.RGBA{0x10, 0x20, 0x30, 0xff},
+				color.RGBA{0x40, 0x50, 0x60, 0xff},
+			},
+		}
+		if !reflect.DeepEqual(got, want) {
+			t.Errorf("nPix=%d, extra=%t\ngot  %v\nwant %v", tc.nPix, tc.extra, got, want)
+		}
+	}
+}
+
+func TestTransparentIndex(t *testing.T) {
+	b := &bytes.Buffer{}
+	b.WriteString(headerStr)
+	b.WriteString(paletteStr)
+	for transparentIndex := 0; transparentIndex < 3; transparentIndex++ {
+		if transparentIndex < 2 {
+			// Write the graphic control for the transparent index.
+			b.WriteString("\x21\xf9\x00\x01\x00\x00")
+			b.WriteByte(byte(transparentIndex))
+			b.WriteByte(0)
+		}
+		// Write an image with bounds 2x1, as per TestDecode.
+		b.WriteString("\x2c\x00\x00\x00\x00\x02\x00\x01\x00\x00\x02")
+		enc := lzwEncode(2)
+		if len(enc) > 0xff {
+			t.Fatalf("compressed length %d is too large", len(enc))
+		}
+		b.WriteByte(byte(len(enc)))
+		b.Write(enc)
+		b.WriteByte(0x00)
+	}
+	b.WriteString(trailerStr)
+
+	g, err := DecodeAll(b)
+	if err != nil {
+		t.Fatalf("DecodeAll: %v", err)
+	}
+	c0 := color.RGBA{paletteStr[0], paletteStr[1], paletteStr[2], 0xff}
+	c1 := color.RGBA{paletteStr[3], paletteStr[4], paletteStr[5], 0xff}
+	cz := color.RGBA{}
+	wants := []color.Palette{
+		{cz, c1},
+		{c0, cz},
+		{c0, c1},
+	}
+	if len(g.Image) != len(wants) {
+		t.Fatalf("got %d images, want %d", len(g.Image), len(wants))
+	}
+	for i, want := range wants {
+		got := g.Image[i].Palette
+		if !reflect.DeepEqual(got, want) {
+			t.Errorf("palette #%d:\ngot  %v\nwant %v", i, got, want)
+		}
+	}
+}
+
+// testGIF is a simple GIF that we can modify to test different scenarios.
+var testGIF = []byte{
+	'G', 'I', 'F', '8', '9', 'a',
+	1, 0, 1, 0, // w=1, h=1 (6)
+	128, 0, 0, // headerFields, bg, aspect (10)
+	0, 0, 0, 1, 1, 1, // color map and graphics control (13)
+	0x21, 0xf9, 0x04, 0x00, 0x00, 0x00, 0xff, 0x00, // (19)
+	// frame 1 (0,0 - 1,1)
+	0x2c,
+	0x00, 0x00, 0x00, 0x00,
+	0x01, 0x00, 0x01, 0x00, // (32)
+	0x00,
+	0x02, 0x02, 0x4c, 0x01, 0x00, // lzw pixels
+	// trailer
+	0x3b,
+}
+
+func try(t *testing.T, b []byte, want string) {
+	_, err := DecodeAll(bytes.NewReader(b))
+	var got string
+	if err != nil {
+		got = err.Error()
+	}
+	if got != want {
+		t.Fatalf("got %v, want %v", got, want)
+	}
+}
+
+func TestBounds(t *testing.T) {
+	// Make a local copy of testGIF.
+	gif := make([]byte, len(testGIF))
+	copy(gif, testGIF)
+	// Make the bounds too big, just by one.
+	gif[32] = 2
+	want := "gif: frame bounds larger than image bounds"
+	try(t, gif, want)
+
+	// Make the bounds too small; does not trigger bounds
+	// check, but now there's too much data.
+	gif[32] = 0
+	want = "gif: too much image data"
+	try(t, gif, want)
+	gif[32] = 1
+
+	// Make the bounds really big, expect an error.
+	want = "gif: frame bounds larger than image bounds"
+	for i := 0; i < 4; i++ {
+		gif[32+i] = 0xff
+	}
+	try(t, gif, want)
+}
+
+func TestNoPalette(t *testing.T) {
+	b := &bytes.Buffer{}
+
+	// Manufacture a GIF with no palette, so any pixel at all
+	// will be invalid.
+	b.WriteString(headerStr[:len(headerStr)-3])
+	b.WriteString("\x00\x00\x00") // No global palette.
+
+	// Image descriptor: 2x1, no local palette.
+	b.WriteString("\x2c\x00\x00\x00\x00\x02\x00\x01\x00\x00\x02")
+
+	// Encode the pixels: neither is in range, because there is no palette.
+	pix := []byte{0, 128}
+	enc := &bytes.Buffer{}
+	w := lzw.NewWriter(enc, lzw.LSB, 2)
+	w.Write(pix)
+	w.Close()
+	b.WriteByte(byte(len(enc.Bytes())))
+	b.Write(enc.Bytes())
+	b.WriteByte(0x00) // An empty block signifies the end of the image data.
+
+	b.WriteString(trailerStr)
+
+	try(t, b.Bytes(), "gif: invalid pixel value")
+}
+
+func TestPixelOutsidePaletteRange(t *testing.T) {
+	for _, pval := range []byte{0, 1, 2, 3, 255} {
+		b := &bytes.Buffer{}
+
+		// Manufacture a GIF with a 2 color palette.
+		b.WriteString(headerStr)
+		b.WriteString(paletteStr)
+
+		// Image descriptor: 2x1, no local palette.
+		b.WriteString("\x2c\x00\x00\x00\x00\x02\x00\x01\x00\x00\x02")
+
+		// Encode the pixels; some pvals trigger the expected error.
+		pix := []byte{pval, pval}
+		enc := &bytes.Buffer{}
+		w := lzw.NewWriter(enc, lzw.LSB, 2)
+		w.Write(pix)
+		w.Close()
+		b.WriteByte(byte(len(enc.Bytes())))
+		b.Write(enc.Bytes())
+		b.WriteByte(0x00) // An empty block signifies the end of the image data.
+
+		b.WriteString(trailerStr)
+
+		// No error expected, unless the pixels are beyond the 2 color palette.
+		want := ""
+		if pval >= 2 {
+			want = "gif: invalid pixel value"
+		}
+		try(t, b.Bytes(), want)
+	}
+}
diff --git a/src/image/gif/writer.go b/src/image/gif/writer.go
new file mode 100644
index 0000000..49abde7
--- /dev/null
+++ b/src/image/gif/writer.go
@@ -0,0 +1,333 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package gif
+
+import (
+	"bufio"
+	"compress/lzw"
+	"errors"
+	"image"
+	"image/color"
+	"image/color/palette"
+	"image/draw"
+	"io"
+)
+
+// Graphic control extension fields.
+const (
+	gcLabel     = 0xF9
+	gcBlockSize = 0x04
+)
+
+var log2Lookup = [8]int{2, 4, 8, 16, 32, 64, 128, 256}
+
+func log2(x int) int {
+	for i, v := range log2Lookup {
+		if x <= v {
+			return i
+		}
+	}
+	return -1
+}
+
+// Little-endian.
+func writeUint16(b []uint8, u uint16) {
+	b[0] = uint8(u)
+	b[1] = uint8(u >> 8)
+}
+
+// writer is a buffered writer.
+type writer interface {
+	Flush() error
+	io.Writer
+	io.ByteWriter
+}
+
+// encoder encodes an image to the GIF format.
+type encoder struct {
+	// w is the writer to write to. err is the first error encountered during
+	// writing. All attempted writes after the first error become no-ops.
+	w   writer
+	err error
+	// g is a reference to the data that is being encoded.
+	g *GIF
+	// buf is a scratch buffer. It must be at least 768 so we can write the color map.
+	buf [1024]byte
+}
+
+// blockWriter writes the block structure of GIF image data, which
+// comprises (n, (n bytes)) blocks, with 1 <= n <= 255. It is the
+// writer given to the LZW encoder, which is thus immune to the
+// blocking.
+type blockWriter struct {
+	e *encoder
+}
+
+func (b blockWriter) Write(data []byte) (int, error) {
+	if b.e.err != nil {
+		return 0, b.e.err
+	}
+	if len(data) == 0 {
+		return 0, nil
+	}
+	total := 0
+	for total < len(data) {
+		n := copy(b.e.buf[1:256], data[total:])
+		total += n
+		b.e.buf[0] = uint8(n)
+
+		n, b.e.err = b.e.w.Write(b.e.buf[:n+1])
+		if b.e.err != nil {
+			return 0, b.e.err
+		}
+	}
+	return total, b.e.err
+}
+
+func (e *encoder) flush() {
+	if e.err != nil {
+		return
+	}
+	e.err = e.w.Flush()
+}
+
+func (e *encoder) write(p []byte) {
+	if e.err != nil {
+		return
+	}
+	_, e.err = e.w.Write(p)
+}
+
+func (e *encoder) writeByte(b byte) {
+	if e.err != nil {
+		return
+	}
+	e.err = e.w.WriteByte(b)
+}
+
+func (e *encoder) writeHeader() {
+	if e.err != nil {
+		return
+	}
+	_, e.err = io.WriteString(e.w, "GIF89a")
+	if e.err != nil {
+		return
+	}
+
+	pm := e.g.Image[0]
+	// Logical screen width and height.
+	writeUint16(e.buf[0:2], uint16(pm.Bounds().Dx()))
+	writeUint16(e.buf[2:4], uint16(pm.Bounds().Dy()))
+	e.write(e.buf[:4])
+
+	// All frames have a local color table, so a global color table
+	// is not needed.
+	e.buf[0] = 0x00
+	e.buf[1] = 0x00 // Background Color Index.
+	e.buf[2] = 0x00 // Pixel Aspect Ratio.
+	e.write(e.buf[:3])
+
+	// Add animation info if necessary.
+	if len(e.g.Image) > 1 {
+		e.buf[0] = 0x21 // Extension Introducer.
+		e.buf[1] = 0xff // Application Label.
+		e.buf[2] = 0x0b // Block Size.
+		e.write(e.buf[:3])
+		_, e.err = io.WriteString(e.w, "NETSCAPE2.0") // Application Identifier.
+		if e.err != nil {
+			return
+		}
+		e.buf[0] = 0x03 // Block Size.
+		e.buf[1] = 0x01 // Sub-block Index.
+		writeUint16(e.buf[2:4], uint16(e.g.LoopCount))
+		e.buf[4] = 0x00 // Block Terminator.
+		e.write(e.buf[:5])
+	}
+}
+
+func (e *encoder) writeColorTable(p color.Palette, size int) {
+	if e.err != nil {
+		return
+	}
+
+	for i := 0; i < log2Lookup[size]; i++ {
+		if i < len(p) {
+			r, g, b, _ := p[i].RGBA()
+			e.buf[3*i+0] = uint8(r >> 8)
+			e.buf[3*i+1] = uint8(g >> 8)
+			e.buf[3*i+2] = uint8(b >> 8)
+		} else {
+			// Pad with black.
+			e.buf[3*i+0] = 0x00
+			e.buf[3*i+1] = 0x00
+			e.buf[3*i+2] = 0x00
+		}
+	}
+	e.write(e.buf[:3*log2Lookup[size]])
+}
+
+func (e *encoder) writeImageBlock(pm *image.Paletted, delay int) {
+	if e.err != nil {
+		return
+	}
+
+	if len(pm.Palette) == 0 {
+		e.err = errors.New("gif: cannot encode image block with empty palette")
+		return
+	}
+
+	b := pm.Bounds()
+	if b.Dx() >= 1<<16 || b.Dy() >= 1<<16 || b.Min.X < 0 || b.Min.X >= 1<<16 || b.Min.Y < 0 || b.Min.Y >= 1<<16 {
+		e.err = errors.New("gif: image block is too large to encode")
+		return
+	}
+
+	transparentIndex := -1
+	for i, c := range pm.Palette {
+		if _, _, _, a := c.RGBA(); a == 0 {
+			transparentIndex = i
+			break
+		}
+	}
+
+	if delay > 0 || transparentIndex != -1 {
+		e.buf[0] = sExtension  // Extension Introducer.
+		e.buf[1] = gcLabel     // Graphic Control Label.
+		e.buf[2] = gcBlockSize // Block Size.
+		if transparentIndex != -1 {
+			e.buf[3] = 0x01
+		} else {
+			e.buf[3] = 0x00
+		}
+		writeUint16(e.buf[4:6], uint16(delay)) // Delay Time (1/100ths of a second)
+
+		// Transparent color index.
+		if transparentIndex != -1 {
+			e.buf[6] = uint8(transparentIndex)
+		} else {
+			e.buf[6] = 0x00
+		}
+		e.buf[7] = 0x00 // Block Terminator.
+		e.write(e.buf[:8])
+	}
+	e.buf[0] = sImageDescriptor
+	writeUint16(e.buf[1:3], uint16(b.Min.X))
+	writeUint16(e.buf[3:5], uint16(b.Min.Y))
+	writeUint16(e.buf[5:7], uint16(b.Dx()))
+	writeUint16(e.buf[7:9], uint16(b.Dy()))
+	e.write(e.buf[:9])
+
+	paddedSize := log2(len(pm.Palette)) // Size of Local Color Table: 2^(1+n).
+	// Interlacing is not supported.
+	e.writeByte(0x80 | uint8(paddedSize))
+
+	// Local Color Table.
+	e.writeColorTable(pm.Palette, paddedSize)
+
+	litWidth := paddedSize + 1
+	if litWidth < 2 {
+		litWidth = 2
+	}
+	e.writeByte(uint8(litWidth)) // LZW Minimum Code Size.
+
+	lzww := lzw.NewWriter(blockWriter{e: e}, lzw.LSB, litWidth)
+	if dx := b.Dx(); dx == pm.Stride {
+		_, e.err = lzww.Write(pm.Pix)
+		if e.err != nil {
+			lzww.Close()
+			return
+		}
+	} else {
+		for i, y := 0, b.Min.Y; y < b.Max.Y; i, y = i+pm.Stride, y+1 {
+			_, e.err = lzww.Write(pm.Pix[i : i+dx])
+			if e.err != nil {
+				lzww.Close()
+				return
+			}
+		}
+	}
+	lzww.Close()
+	e.writeByte(0x00) // Block Terminator.
+}
+
+// Options are the encoding parameters.
+type Options struct {
+	// NumColors is the maximum number of colors used in the image.
+	// It ranges from 1 to 256.
+	NumColors int
+
+	// Quantizer is used to produce a palette with size NumColors.
+	// palette.Plan9 is used in place of a nil Quantizer.
+	Quantizer draw.Quantizer
+
+	// Drawer is used to convert the source image to the desired palette.
+	// draw.FloydSteinberg is used in place of a nil Drawer.
+	Drawer draw.Drawer
+}
+
+// EncodeAll writes the images in g to w in GIF format with the
+// given loop count and delay between frames.
+func EncodeAll(w io.Writer, g *GIF) error {
+	if len(g.Image) == 0 {
+		return errors.New("gif: must provide at least one image")
+	}
+
+	if len(g.Image) != len(g.Delay) {
+		return errors.New("gif: mismatched image and delay lengths")
+	}
+	if g.LoopCount < 0 {
+		g.LoopCount = 0
+	}
+
+	e := encoder{g: g}
+	if ww, ok := w.(writer); ok {
+		e.w = ww
+	} else {
+		e.w = bufio.NewWriter(w)
+	}
+
+	e.writeHeader()
+	for i, pm := range g.Image {
+		e.writeImageBlock(pm, g.Delay[i])
+	}
+	e.writeByte(sTrailer)
+	e.flush()
+	return e.err
+}
+
+// Encode writes the Image m to w in GIF format.
+func Encode(w io.Writer, m image.Image, o *Options) error {
+	// Check for bounds and size restrictions.
+	b := m.Bounds()
+	if b.Dx() >= 1<<16 || b.Dy() >= 1<<16 {
+		return errors.New("gif: image is too large to encode")
+	}
+
+	opts := Options{}
+	if o != nil {
+		opts = *o
+	}
+	if opts.NumColors < 1 || 256 < opts.NumColors {
+		opts.NumColors = 256
+	}
+	if opts.Drawer == nil {
+		opts.Drawer = draw.FloydSteinberg
+	}
+
+	pm, ok := m.(*image.Paletted)
+	if !ok || len(pm.Palette) > opts.NumColors {
+		// TODO: Pick a better sub-sample of the Plan 9 palette.
+		pm = image.NewPaletted(b, palette.Plan9[:opts.NumColors])
+		if opts.Quantizer != nil {
+			pm.Palette = opts.Quantizer.Quantize(make(color.Palette, 0, opts.NumColors), m)
+		}
+		opts.Drawer.Draw(pm, b, m, image.ZP)
+	}
+
+	return EncodeAll(w, &GIF{
+		Image: []*image.Paletted{pm},
+		Delay: []int{0},
+	})
+}
diff --git a/src/image/gif/writer_test.go b/src/image/gif/writer_test.go
new file mode 100644
index 0000000..93306ff
--- /dev/null
+++ b/src/image/gif/writer_test.go
@@ -0,0 +1,227 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package gif
+
+import (
+	"bytes"
+	"image"
+	"image/color"
+	_ "image/png"
+	"io/ioutil"
+	"math/rand"
+	"os"
+	"testing"
+)
+
+func readImg(filename string) (image.Image, error) {
+	f, err := os.Open(filename)
+	if err != nil {
+		return nil, err
+	}
+	defer f.Close()
+	m, _, err := image.Decode(f)
+	return m, err
+}
+
+func readGIF(filename string) (*GIF, error) {
+	f, err := os.Open(filename)
+	if err != nil {
+		return nil, err
+	}
+	defer f.Close()
+	return DecodeAll(f)
+}
+
+func delta(u0, u1 uint32) int64 {
+	d := int64(u0) - int64(u1)
+	if d < 0 {
+		return -d
+	}
+	return d
+}
+
+// averageDelta returns the average delta in RGB space. The two images must
+// have the same bounds.
+func averageDelta(m0, m1 image.Image) int64 {
+	b := m0.Bounds()
+	var sum, n int64
+	for y := b.Min.Y; y < b.Max.Y; y++ {
+		for x := b.Min.X; x < b.Max.X; x++ {
+			c0 := m0.At(x, y)
+			c1 := m1.At(x, y)
+			r0, g0, b0, _ := c0.RGBA()
+			r1, g1, b1, _ := c1.RGBA()
+			sum += delta(r0, r1)
+			sum += delta(g0, g1)
+			sum += delta(b0, b1)
+			n += 3
+		}
+	}
+	return sum / n
+}
+
+var testCase = []struct {
+	filename  string
+	tolerance int64
+}{
+	{"../testdata/video-001.png", 1 << 12},
+	{"../testdata/video-001.gif", 0},
+	{"../testdata/video-001.interlaced.gif", 0},
+}
+
+func TestWriter(t *testing.T) {
+	for _, tc := range testCase {
+		m0, err := readImg(tc.filename)
+		if err != nil {
+			t.Error(tc.filename, err)
+			continue
+		}
+		var buf bytes.Buffer
+		err = Encode(&buf, m0, nil)
+		if err != nil {
+			t.Error(tc.filename, err)
+			continue
+		}
+		m1, err := Decode(&buf)
+		if err != nil {
+			t.Error(tc.filename, err)
+			continue
+		}
+		if m0.Bounds() != m1.Bounds() {
+			t.Errorf("%s, bounds differ: %v and %v", tc.filename, m0.Bounds(), m1.Bounds())
+			continue
+		}
+		// Compare the average delta to the tolerance level.
+		avgDelta := averageDelta(m0, m1)
+		if avgDelta > tc.tolerance {
+			t.Errorf("%s: average delta is too high. expected: %d, got %d", tc.filename, tc.tolerance, avgDelta)
+			continue
+		}
+	}
+}
+
+func TestSubImage(t *testing.T) {
+	m0, err := readImg("../testdata/video-001.gif")
+	if err != nil {
+		t.Fatalf("readImg: %v", err)
+	}
+	m0 = m0.(*image.Paletted).SubImage(image.Rect(0, 0, 50, 30))
+	var buf bytes.Buffer
+	err = Encode(&buf, m0, nil)
+	if err != nil {
+		t.Fatalf("Encode: %v", err)
+	}
+	m1, err := Decode(&buf)
+	if err != nil {
+		t.Fatalf("Decode: %v", err)
+	}
+	if m0.Bounds() != m1.Bounds() {
+		t.Fatalf("bounds differ: %v and %v", m0.Bounds(), m1.Bounds())
+	}
+	if averageDelta(m0, m1) != 0 {
+		t.Fatalf("images differ")
+	}
+}
+
+var frames = []string{
+	"../testdata/video-001.gif",
+	"../testdata/video-005.gray.gif",
+}
+
+func TestEncodeAll(t *testing.T) {
+	g0 := &GIF{
+		Image:     make([]*image.Paletted, len(frames)),
+		Delay:     make([]int, len(frames)),
+		LoopCount: 5,
+	}
+	for i, f := range frames {
+		m, err := readGIF(f)
+		if err != nil {
+			t.Fatal(f, err)
+		}
+		g0.Image[i] = m.Image[0]
+	}
+	var buf bytes.Buffer
+	if err := EncodeAll(&buf, g0); err != nil {
+		t.Fatal("EncodeAll:", err)
+	}
+	g1, err := DecodeAll(&buf)
+	if err != nil {
+		t.Fatal("DecodeAll:", err)
+	}
+	if g0.LoopCount != g1.LoopCount {
+		t.Errorf("loop counts differ: %d and %d", g0.LoopCount, g1.LoopCount)
+	}
+	for i := range g0.Image {
+		m0, m1 := g0.Image[i], g1.Image[i]
+		if m0.Bounds() != m1.Bounds() {
+			t.Errorf("%s, bounds differ: %v and %v", frames[i], m0.Bounds(), m1.Bounds())
+		}
+		d0, d1 := g0.Delay[i], g1.Delay[i]
+		if d0 != d1 {
+			t.Errorf("%s: delay values differ: %d and %d", frames[i], d0, d1)
+		}
+	}
+
+	g1.Delay = make([]int, 1)
+	if err := EncodeAll(ioutil.Discard, g1); err == nil {
+		t.Error("expected error from mismatched delay and image slice lengths")
+	}
+	if err := EncodeAll(ioutil.Discard, &GIF{}); err == nil {
+		t.Error("expected error from providing empty gif")
+	}
+}
+
+func BenchmarkEncode(b *testing.B) {
+	b.StopTimer()
+
+	bo := image.Rect(0, 0, 640, 480)
+	rnd := rand.New(rand.NewSource(123))
+
+	// Restrict to a 256-color paletted image to avoid quantization path.
+	palette := make(color.Palette, 256)
+	for i := range palette {
+		palette[i] = color.RGBA{
+			uint8(rnd.Intn(256)),
+			uint8(rnd.Intn(256)),
+			uint8(rnd.Intn(256)),
+			255,
+		}
+	}
+	img := image.NewPaletted(image.Rect(0, 0, 640, 480), palette)
+	for y := bo.Min.Y; y < bo.Max.Y; y++ {
+		for x := bo.Min.X; x < bo.Max.X; x++ {
+			img.Set(x, y, palette[rnd.Intn(256)])
+		}
+	}
+
+	b.SetBytes(640 * 480 * 4)
+	b.StartTimer()
+	for i := 0; i < b.N; i++ {
+		Encode(ioutil.Discard, img, nil)
+	}
+}
+
+func BenchmarkQuantizedEncode(b *testing.B) {
+	b.StopTimer()
+	img := image.NewRGBA(image.Rect(0, 0, 640, 480))
+	bo := img.Bounds()
+	rnd := rand.New(rand.NewSource(123))
+	for y := bo.Min.Y; y < bo.Max.Y; y++ {
+		for x := bo.Min.X; x < bo.Max.X; x++ {
+			img.SetRGBA(x, y, color.RGBA{
+				uint8(rnd.Intn(256)),
+				uint8(rnd.Intn(256)),
+				uint8(rnd.Intn(256)),
+				255,
+			})
+		}
+	}
+	b.SetBytes(640 * 480 * 4)
+	b.StartTimer()
+	for i := 0; i < b.N; i++ {
+		Encode(ioutil.Discard, img, nil)
+	}
+}
diff --git a/src/image/image.go b/src/image/image.go
new file mode 100644
index 0000000..6b8e5c4
--- /dev/null
+++ b/src/image/image.go
@@ -0,0 +1,936 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package image implements a basic 2-D image library.
+//
+// The fundamental interface is called Image. An Image contains colors, which
+// are described in the image/color package.
+//
+// Values of the Image interface are created either by calling functions such
+// as NewRGBA and NewPaletted, or by calling Decode on an io.Reader containing
+// image data in a format such as GIF, JPEG or PNG. Decoding any particular
+// image format requires the prior registration of a decoder function.
+// Registration is typically automatic as a side effect of initializing that
+// format's package so that, to decode a PNG image, it suffices to have
+//	import _ "image/png"
+// in a program's main package. The _ means to import a package purely for its
+// initialization side effects.
+//
+// See "The Go image package" for more details:
+// http://golang.org/doc/articles/image_package.html
+package image
+
+import (
+	"image/color"
+)
+
+// Config holds an image's color model and dimensions.
+type Config struct {
+	ColorModel    color.Model
+	Width, Height int
+}
+
+// Image is a finite rectangular grid of color.Color values taken from a color
+// model.
+type Image interface {
+	// ColorModel returns the Image's color model.
+	ColorModel() color.Model
+	// Bounds returns the domain for which At can return non-zero color.
+	// The bounds do not necessarily contain the point (0, 0).
+	Bounds() Rectangle
+	// At returns the color of the pixel at (x, y).
+	// At(Bounds().Min.X, Bounds().Min.Y) returns the upper-left pixel of the grid.
+	// At(Bounds().Max.X-1, Bounds().Max.Y-1) returns the lower-right one.
+	At(x, y int) color.Color
+}
+
+// PalettedImage is an image whose colors may come from a limited palette.
+// If m is a PalettedImage and m.ColorModel() returns a PalettedColorModel p,
+// then m.At(x, y) should be equivalent to p[m.ColorIndexAt(x, y)]. If m's
+// color model is not a PalettedColorModel, then ColorIndexAt's behavior is
+// undefined.
+type PalettedImage interface {
+	// ColorIndexAt returns the palette index of the pixel at (x, y).
+	ColorIndexAt(x, y int) uint8
+	Image
+}
+
+// RGBA is an in-memory image whose At method returns color.RGBA values.
+type RGBA struct {
+	// Pix holds the image's pixels, in R, G, B, A order. The pixel at
+	// (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*4].
+	Pix []uint8
+	// Stride is the Pix stride (in bytes) between vertically adjacent pixels.
+	Stride int
+	// Rect is the image's bounds.
+	Rect Rectangle
+}
+
+func (p *RGBA) ColorModel() color.Model { return color.RGBAModel }
+
+func (p *RGBA) Bounds() Rectangle { return p.Rect }
+
+func (p *RGBA) At(x, y int) color.Color {
+	return p.RGBAAt(x, y)
+}
+
+func (p *RGBA) RGBAAt(x, y int) color.RGBA {
+	if !(Point{x, y}.In(p.Rect)) {
+		return color.RGBA{}
+	}
+	i := p.PixOffset(x, y)
+	return color.RGBA{p.Pix[i+0], p.Pix[i+1], p.Pix[i+2], p.Pix[i+3]}
+}
+
+// PixOffset returns the index of the first element of Pix that corresponds to
+// the pixel at (x, y).
+func (p *RGBA) PixOffset(x, y int) int {
+	return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*4
+}
+
+func (p *RGBA) Set(x, y int, c color.Color) {
+	if !(Point{x, y}.In(p.Rect)) {
+		return
+	}
+	i := p.PixOffset(x, y)
+	c1 := color.RGBAModel.Convert(c).(color.RGBA)
+	p.Pix[i+0] = c1.R
+	p.Pix[i+1] = c1.G
+	p.Pix[i+2] = c1.B
+	p.Pix[i+3] = c1.A
+}
+
+func (p *RGBA) SetRGBA(x, y int, c color.RGBA) {
+	if !(Point{x, y}.In(p.Rect)) {
+		return
+	}
+	i := p.PixOffset(x, y)
+	p.Pix[i+0] = c.R
+	p.Pix[i+1] = c.G
+	p.Pix[i+2] = c.B
+	p.Pix[i+3] = c.A
+}
+
+// SubImage returns an image representing the portion of the image p visible
+// through r. The returned value shares pixels with the original image.
+func (p *RGBA) SubImage(r Rectangle) Image {
+	r = r.Intersect(p.Rect)
+	// If r1 and r2 are Rectangles, r1.Intersect(r2) is not guaranteed to be inside
+	// either r1 or r2 if the intersection is empty. Without explicitly checking for
+	// this, the Pix[i:] expression below can panic.
+	if r.Empty() {
+		return &RGBA{}
+	}
+	i := p.PixOffset(r.Min.X, r.Min.Y)
+	return &RGBA{
+		Pix:    p.Pix[i:],
+		Stride: p.Stride,
+		Rect:   r,
+	}
+}
+
+// Opaque scans the entire image and reports whether it is fully opaque.
+func (p *RGBA) Opaque() bool {
+	if p.Rect.Empty() {
+		return true
+	}
+	i0, i1 := 3, p.Rect.Dx()*4
+	for y := p.Rect.Min.Y; y < p.Rect.Max.Y; y++ {
+		for i := i0; i < i1; i += 4 {
+			if p.Pix[i] != 0xff {
+				return false
+			}
+		}
+		i0 += p.Stride
+		i1 += p.Stride
+	}
+	return true
+}
+
+// NewRGBA returns a new RGBA with the given bounds.
+func NewRGBA(r Rectangle) *RGBA {
+	w, h := r.Dx(), r.Dy()
+	buf := make([]uint8, 4*w*h)
+	return &RGBA{buf, 4 * w, r}
+}
+
+// RGBA64 is an in-memory image whose At method returns color.RGBA64 values.
+type RGBA64 struct {
+	// Pix holds the image's pixels, in R, G, B, A order and big-endian format. The pixel at
+	// (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*8].
+	Pix []uint8
+	// Stride is the Pix stride (in bytes) between vertically adjacent pixels.
+	Stride int
+	// Rect is the image's bounds.
+	Rect Rectangle
+}
+
+func (p *RGBA64) ColorModel() color.Model { return color.RGBA64Model }
+
+func (p *RGBA64) Bounds() Rectangle { return p.Rect }
+
+func (p *RGBA64) At(x, y int) color.Color {
+	return p.RGBA64At(x, y)
+}
+
+func (p *RGBA64) RGBA64At(x, y int) color.RGBA64 {
+	if !(Point{x, y}.In(p.Rect)) {
+		return color.RGBA64{}
+	}
+	i := p.PixOffset(x, y)
+	return color.RGBA64{
+		uint16(p.Pix[i+0])<<8 | uint16(p.Pix[i+1]),
+		uint16(p.Pix[i+2])<<8 | uint16(p.Pix[i+3]),
+		uint16(p.Pix[i+4])<<8 | uint16(p.Pix[i+5]),
+		uint16(p.Pix[i+6])<<8 | uint16(p.Pix[i+7]),
+	}
+}
+
+// PixOffset returns the index of the first element of Pix that corresponds to
+// the pixel at (x, y).
+func (p *RGBA64) PixOffset(x, y int) int {
+	return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*8
+}
+
+func (p *RGBA64) Set(x, y int, c color.Color) {
+	if !(Point{x, y}.In(p.Rect)) {
+		return
+	}
+	i := p.PixOffset(x, y)
+	c1 := color.RGBA64Model.Convert(c).(color.RGBA64)
+	p.Pix[i+0] = uint8(c1.R >> 8)
+	p.Pix[i+1] = uint8(c1.R)
+	p.Pix[i+2] = uint8(c1.G >> 8)
+	p.Pix[i+3] = uint8(c1.G)
+	p.Pix[i+4] = uint8(c1.B >> 8)
+	p.Pix[i+5] = uint8(c1.B)
+	p.Pix[i+6] = uint8(c1.A >> 8)
+	p.Pix[i+7] = uint8(c1.A)
+}
+
+func (p *RGBA64) SetRGBA64(x, y int, c color.RGBA64) {
+	if !(Point{x, y}.In(p.Rect)) {
+		return
+	}
+	i := p.PixOffset(x, y)
+	p.Pix[i+0] = uint8(c.R >> 8)
+	p.Pix[i+1] = uint8(c.R)
+	p.Pix[i+2] = uint8(c.G >> 8)
+	p.Pix[i+3] = uint8(c.G)
+	p.Pix[i+4] = uint8(c.B >> 8)
+	p.Pix[i+5] = uint8(c.B)
+	p.Pix[i+6] = uint8(c.A >> 8)
+	p.Pix[i+7] = uint8(c.A)
+}
+
+// SubImage returns an image representing the portion of the image p visible
+// through r. The returned value shares pixels with the original image.
+func (p *RGBA64) SubImage(r Rectangle) Image {
+	r = r.Intersect(p.Rect)
+	// If r1 and r2 are Rectangles, r1.Intersect(r2) is not guaranteed to be inside
+	// either r1 or r2 if the intersection is empty. Without explicitly checking for
+	// this, the Pix[i:] expression below can panic.
+	if r.Empty() {
+		return &RGBA64{}
+	}
+	i := p.PixOffset(r.Min.X, r.Min.Y)
+	return &RGBA64{
+		Pix:    p.Pix[i:],
+		Stride: p.Stride,
+		Rect:   r,
+	}
+}
+
+// Opaque scans the entire image and reports whether it is fully opaque.
+func (p *RGBA64) Opaque() bool {
+	if p.Rect.Empty() {
+		return true
+	}
+	i0, i1 := 6, p.Rect.Dx()*8
+	for y := p.Rect.Min.Y; y < p.Rect.Max.Y; y++ {
+		for i := i0; i < i1; i += 8 {
+			if p.Pix[i+0] != 0xff || p.Pix[i+1] != 0xff {
+				return false
+			}
+		}
+		i0 += p.Stride
+		i1 += p.Stride
+	}
+	return true
+}
+
+// NewRGBA64 returns a new RGBA64 with the given bounds.
+func NewRGBA64(r Rectangle) *RGBA64 {
+	w, h := r.Dx(), r.Dy()
+	pix := make([]uint8, 8*w*h)
+	return &RGBA64{pix, 8 * w, r}
+}
+
+// NRGBA is an in-memory image whose At method returns color.NRGBA values.
+type NRGBA struct {
+	// Pix holds the image's pixels, in R, G, B, A order. The pixel at
+	// (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*4].
+	Pix []uint8
+	// Stride is the Pix stride (in bytes) between vertically adjacent pixels.
+	Stride int
+	// Rect is the image's bounds.
+	Rect Rectangle
+}
+
+func (p *NRGBA) ColorModel() color.Model { return color.NRGBAModel }
+
+func (p *NRGBA) Bounds() Rectangle { return p.Rect }
+
+func (p *NRGBA) At(x, y int) color.Color {
+	return p.NRGBAAt(x, y)
+}
+
+func (p *NRGBA) NRGBAAt(x, y int) color.NRGBA {
+	if !(Point{x, y}.In(p.Rect)) {
+		return color.NRGBA{}
+	}
+	i := p.PixOffset(x, y)
+	return color.NRGBA{p.Pix[i+0], p.Pix[i+1], p.Pix[i+2], p.Pix[i+3]}
+}
+
+// PixOffset returns the index of the first element of Pix that corresponds to
+// the pixel at (x, y).
+func (p *NRGBA) PixOffset(x, y int) int {
+	return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*4
+}
+
+func (p *NRGBA) Set(x, y int, c color.Color) {
+	if !(Point{x, y}.In(p.Rect)) {
+		return
+	}
+	i := p.PixOffset(x, y)
+	c1 := color.NRGBAModel.Convert(c).(color.NRGBA)
+	p.Pix[i+0] = c1.R
+	p.Pix[i+1] = c1.G
+	p.Pix[i+2] = c1.B
+	p.Pix[i+3] = c1.A
+}
+
+func (p *NRGBA) SetNRGBA(x, y int, c color.NRGBA) {
+	if !(Point{x, y}.In(p.Rect)) {
+		return
+	}
+	i := p.PixOffset(x, y)
+	p.Pix[i+0] = c.R
+	p.Pix[i+1] = c.G
+	p.Pix[i+2] = c.B
+	p.Pix[i+3] = c.A
+}
+
+// SubImage returns an image representing the portion of the image p visible
+// through r. The returned value shares pixels with the original image.
+func (p *NRGBA) SubImage(r Rectangle) Image {
+	r = r.Intersect(p.Rect)
+	// If r1 and r2 are Rectangles, r1.Intersect(r2) is not guaranteed to be inside
+	// either r1 or r2 if the intersection is empty. Without explicitly checking for
+	// this, the Pix[i:] expression below can panic.
+	if r.Empty() {
+		return &NRGBA{}
+	}
+	i := p.PixOffset(r.Min.X, r.Min.Y)
+	return &NRGBA{
+		Pix:    p.Pix[i:],
+		Stride: p.Stride,
+		Rect:   r,
+	}
+}
+
+// Opaque scans the entire image and reports whether it is fully opaque.
+func (p *NRGBA) Opaque() bool {
+	if p.Rect.Empty() {
+		return true
+	}
+	i0, i1 := 3, p.Rect.Dx()*4
+	for y := p.Rect.Min.Y; y < p.Rect.Max.Y; y++ {
+		for i := i0; i < i1; i += 4 {
+			if p.Pix[i] != 0xff {
+				return false
+			}
+		}
+		i0 += p.Stride
+		i1 += p.Stride
+	}
+	return true
+}
+
+// NewNRGBA returns a new NRGBA with the given bounds.
+func NewNRGBA(r Rectangle) *NRGBA {
+	w, h := r.Dx(), r.Dy()
+	pix := make([]uint8, 4*w*h)
+	return &NRGBA{pix, 4 * w, r}
+}
+
+// NRGBA64 is an in-memory image whose At method returns color.NRGBA64 values.
+type NRGBA64 struct {
+	// Pix holds the image's pixels, in R, G, B, A order and big-endian format. The pixel at
+	// (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*8].
+	Pix []uint8
+	// Stride is the Pix stride (in bytes) between vertically adjacent pixels.
+	Stride int
+	// Rect is the image's bounds.
+	Rect Rectangle
+}
+
+func (p *NRGBA64) ColorModel() color.Model { return color.NRGBA64Model }
+
+func (p *NRGBA64) Bounds() Rectangle { return p.Rect }
+
+func (p *NRGBA64) At(x, y int) color.Color {
+	return p.NRGBA64At(x, y)
+}
+
+func (p *NRGBA64) NRGBA64At(x, y int) color.NRGBA64 {
+	if !(Point{x, y}.In(p.Rect)) {
+		return color.NRGBA64{}
+	}
+	i := p.PixOffset(x, y)
+	return color.NRGBA64{
+		uint16(p.Pix[i+0])<<8 | uint16(p.Pix[i+1]),
+		uint16(p.Pix[i+2])<<8 | uint16(p.Pix[i+3]),
+		uint16(p.Pix[i+4])<<8 | uint16(p.Pix[i+5]),
+		uint16(p.Pix[i+6])<<8 | uint16(p.Pix[i+7]),
+	}
+}
+
+// PixOffset returns the index of the first element of Pix that corresponds to
+// the pixel at (x, y).
+func (p *NRGBA64) PixOffset(x, y int) int {
+	return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*8
+}
+
+func (p *NRGBA64) Set(x, y int, c color.Color) {
+	if !(Point{x, y}.In(p.Rect)) {
+		return
+	}
+	i := p.PixOffset(x, y)
+	c1 := color.NRGBA64Model.Convert(c).(color.NRGBA64)
+	p.Pix[i+0] = uint8(c1.R >> 8)
+	p.Pix[i+1] = uint8(c1.R)
+	p.Pix[i+2] = uint8(c1.G >> 8)
+	p.Pix[i+3] = uint8(c1.G)
+	p.Pix[i+4] = uint8(c1.B >> 8)
+	p.Pix[i+5] = uint8(c1.B)
+	p.Pix[i+6] = uint8(c1.A >> 8)
+	p.Pix[i+7] = uint8(c1.A)
+}
+
+func (p *NRGBA64) SetNRGBA64(x, y int, c color.NRGBA64) {
+	if !(Point{x, y}.In(p.Rect)) {
+		return
+	}
+	i := p.PixOffset(x, y)
+	p.Pix[i+0] = uint8(c.R >> 8)
+	p.Pix[i+1] = uint8(c.R)
+	p.Pix[i+2] = uint8(c.G >> 8)
+	p.Pix[i+3] = uint8(c.G)
+	p.Pix[i+4] = uint8(c.B >> 8)
+	p.Pix[i+5] = uint8(c.B)
+	p.Pix[i+6] = uint8(c.A >> 8)
+	p.Pix[i+7] = uint8(c.A)
+}
+
+// SubImage returns an image representing the portion of the image p visible
+// through r. The returned value shares pixels with the original image.
+func (p *NRGBA64) SubImage(r Rectangle) Image {
+	r = r.Intersect(p.Rect)
+	// If r1 and r2 are Rectangles, r1.Intersect(r2) is not guaranteed to be inside
+	// either r1 or r2 if the intersection is empty. Without explicitly checking for
+	// this, the Pix[i:] expression below can panic.
+	if r.Empty() {
+		return &NRGBA64{}
+	}
+	i := p.PixOffset(r.Min.X, r.Min.Y)
+	return &NRGBA64{
+		Pix:    p.Pix[i:],
+		Stride: p.Stride,
+		Rect:   r,
+	}
+}
+
+// Opaque scans the entire image and reports whether it is fully opaque.
+func (p *NRGBA64) Opaque() bool {
+	if p.Rect.Empty() {
+		return true
+	}
+	i0, i1 := 6, p.Rect.Dx()*8
+	for y := p.Rect.Min.Y; y < p.Rect.Max.Y; y++ {
+		for i := i0; i < i1; i += 8 {
+			if p.Pix[i+0] != 0xff || p.Pix[i+1] != 0xff {
+				return false
+			}
+		}
+		i0 += p.Stride
+		i1 += p.Stride
+	}
+	return true
+}
+
+// NewNRGBA64 returns a new NRGBA64 with the given bounds.
+func NewNRGBA64(r Rectangle) *NRGBA64 {
+	w, h := r.Dx(), r.Dy()
+	pix := make([]uint8, 8*w*h)
+	return &NRGBA64{pix, 8 * w, r}
+}
+
+// Alpha is an in-memory image whose At method returns color.Alpha values.
+type Alpha struct {
+	// Pix holds the image's pixels, as alpha values. The pixel at
+	// (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*1].
+	Pix []uint8
+	// Stride is the Pix stride (in bytes) between vertically adjacent pixels.
+	Stride int
+	// Rect is the image's bounds.
+	Rect Rectangle
+}
+
+func (p *Alpha) ColorModel() color.Model { return color.AlphaModel }
+
+func (p *Alpha) Bounds() Rectangle { return p.Rect }
+
+func (p *Alpha) At(x, y int) color.Color {
+	return p.AlphaAt(x, y)
+}
+
+func (p *Alpha) AlphaAt(x, y int) color.Alpha {
+	if !(Point{x, y}.In(p.Rect)) {
+		return color.Alpha{}
+	}
+	i := p.PixOffset(x, y)
+	return color.Alpha{p.Pix[i]}
+}
+
+// PixOffset returns the index of the first element of Pix that corresponds to
+// the pixel at (x, y).
+func (p *Alpha) PixOffset(x, y int) int {
+	return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*1
+}
+
+func (p *Alpha) Set(x, y int, c color.Color) {
+	if !(Point{x, y}.In(p.Rect)) {
+		return
+	}
+	i := p.PixOffset(x, y)
+	p.Pix[i] = color.AlphaModel.Convert(c).(color.Alpha).A
+}
+
+func (p *Alpha) SetAlpha(x, y int, c color.Alpha) {
+	if !(Point{x, y}.In(p.Rect)) {
+		return
+	}
+	i := p.PixOffset(x, y)
+	p.Pix[i] = c.A
+}
+
+// SubImage returns an image representing the portion of the image p visible
+// through r. The returned value shares pixels with the original image.
+func (p *Alpha) SubImage(r Rectangle) Image {
+	r = r.Intersect(p.Rect)
+	// If r1 and r2 are Rectangles, r1.Intersect(r2) is not guaranteed to be inside
+	// either r1 or r2 if the intersection is empty. Without explicitly checking for
+	// this, the Pix[i:] expression below can panic.
+	if r.Empty() {
+		return &Alpha{}
+	}
+	i := p.PixOffset(r.Min.X, r.Min.Y)
+	return &Alpha{
+		Pix:    p.Pix[i:],
+		Stride: p.Stride,
+		Rect:   r,
+	}
+}
+
+// Opaque scans the entire image and reports whether it is fully opaque.
+func (p *Alpha) Opaque() bool {
+	if p.Rect.Empty() {
+		return true
+	}
+	i0, i1 := 0, p.Rect.Dx()
+	for y := p.Rect.Min.Y; y < p.Rect.Max.Y; y++ {
+		for i := i0; i < i1; i++ {
+			if p.Pix[i] != 0xff {
+				return false
+			}
+		}
+		i0 += p.Stride
+		i1 += p.Stride
+	}
+	return true
+}
+
+// NewAlpha returns a new Alpha with the given bounds.
+func NewAlpha(r Rectangle) *Alpha {
+	w, h := r.Dx(), r.Dy()
+	pix := make([]uint8, 1*w*h)
+	return &Alpha{pix, 1 * w, r}
+}
+
+// Alpha16 is an in-memory image whose At method returns color.Alpha64 values.
+type Alpha16 struct {
+	// Pix holds the image's pixels, as alpha values in big-endian format. The pixel at
+	// (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*2].
+	Pix []uint8
+	// Stride is the Pix stride (in bytes) between vertically adjacent pixels.
+	Stride int
+	// Rect is the image's bounds.
+	Rect Rectangle
+}
+
+func (p *Alpha16) ColorModel() color.Model { return color.Alpha16Model }
+
+func (p *Alpha16) Bounds() Rectangle { return p.Rect }
+
+func (p *Alpha16) At(x, y int) color.Color {
+	return p.Alpha16At(x, y)
+}
+
+func (p *Alpha16) Alpha16At(x, y int) color.Alpha16 {
+	if !(Point{x, y}.In(p.Rect)) {
+		return color.Alpha16{}
+	}
+	i := p.PixOffset(x, y)
+	return color.Alpha16{uint16(p.Pix[i+0])<<8 | uint16(p.Pix[i+1])}
+}
+
+// PixOffset returns the index of the first element of Pix that corresponds to
+// the pixel at (x, y).
+func (p *Alpha16) PixOffset(x, y int) int {
+	return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*2
+}
+
+func (p *Alpha16) Set(x, y int, c color.Color) {
+	if !(Point{x, y}.In(p.Rect)) {
+		return
+	}
+	i := p.PixOffset(x, y)
+	c1 := color.Alpha16Model.Convert(c).(color.Alpha16)
+	p.Pix[i+0] = uint8(c1.A >> 8)
+	p.Pix[i+1] = uint8(c1.A)
+}
+
+func (p *Alpha16) SetAlpha16(x, y int, c color.Alpha16) {
+	if !(Point{x, y}.In(p.Rect)) {
+		return
+	}
+	i := p.PixOffset(x, y)
+	p.Pix[i+0] = uint8(c.A >> 8)
+	p.Pix[i+1] = uint8(c.A)
+}
+
+// SubImage returns an image representing the portion of the image p visible
+// through r. The returned value shares pixels with the original image.
+func (p *Alpha16) SubImage(r Rectangle) Image {
+	r = r.Intersect(p.Rect)
+	// If r1 and r2 are Rectangles, r1.Intersect(r2) is not guaranteed to be inside
+	// either r1 or r2 if the intersection is empty. Without explicitly checking for
+	// this, the Pix[i:] expression below can panic.
+	if r.Empty() {
+		return &Alpha16{}
+	}
+	i := p.PixOffset(r.Min.X, r.Min.Y)
+	return &Alpha16{
+		Pix:    p.Pix[i:],
+		Stride: p.Stride,
+		Rect:   r,
+	}
+}
+
+// Opaque scans the entire image and reports whether it is fully opaque.
+func (p *Alpha16) Opaque() bool {
+	if p.Rect.Empty() {
+		return true
+	}
+	i0, i1 := 0, p.Rect.Dx()*2
+	for y := p.Rect.Min.Y; y < p.Rect.Max.Y; y++ {
+		for i := i0; i < i1; i += 2 {
+			if p.Pix[i+0] != 0xff || p.Pix[i+1] != 0xff {
+				return false
+			}
+		}
+		i0 += p.Stride
+		i1 += p.Stride
+	}
+	return true
+}
+
+// NewAlpha16 returns a new Alpha16 with the given bounds.
+func NewAlpha16(r Rectangle) *Alpha16 {
+	w, h := r.Dx(), r.Dy()
+	pix := make([]uint8, 2*w*h)
+	return &Alpha16{pix, 2 * w, r}
+}
+
+// Gray is an in-memory image whose At method returns color.Gray values.
+type Gray struct {
+	// Pix holds the image's pixels, as gray values. The pixel at
+	// (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*1].
+	Pix []uint8
+	// Stride is the Pix stride (in bytes) between vertically adjacent pixels.
+	Stride int
+	// Rect is the image's bounds.
+	Rect Rectangle
+}
+
+func (p *Gray) ColorModel() color.Model { return color.GrayModel }
+
+func (p *Gray) Bounds() Rectangle { return p.Rect }
+
+func (p *Gray) At(x, y int) color.Color {
+	return p.GrayAt(x, y)
+}
+
+func (p *Gray) GrayAt(x, y int) color.Gray {
+	if !(Point{x, y}.In(p.Rect)) {
+		return color.Gray{}
+	}
+	i := p.PixOffset(x, y)
+	return color.Gray{p.Pix[i]}
+}
+
+// PixOffset returns the index of the first element of Pix that corresponds to
+// the pixel at (x, y).
+func (p *Gray) PixOffset(x, y int) int {
+	return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*1
+}
+
+func (p *Gray) Set(x, y int, c color.Color) {
+	if !(Point{x, y}.In(p.Rect)) {
+		return
+	}
+	i := p.PixOffset(x, y)
+	p.Pix[i] = color.GrayModel.Convert(c).(color.Gray).Y
+}
+
+func (p *Gray) SetGray(x, y int, c color.Gray) {
+	if !(Point{x, y}.In(p.Rect)) {
+		return
+	}
+	i := p.PixOffset(x, y)
+	p.Pix[i] = c.Y
+}
+
+// SubImage returns an image representing the portion of the image p visible
+// through r. The returned value shares pixels with the original image.
+func (p *Gray) SubImage(r Rectangle) Image {
+	r = r.Intersect(p.Rect)
+	// If r1 and r2 are Rectangles, r1.Intersect(r2) is not guaranteed to be inside
+	// either r1 or r2 if the intersection is empty. Without explicitly checking for
+	// this, the Pix[i:] expression below can panic.
+	if r.Empty() {
+		return &Gray{}
+	}
+	i := p.PixOffset(r.Min.X, r.Min.Y)
+	return &Gray{
+		Pix:    p.Pix[i:],
+		Stride: p.Stride,
+		Rect:   r,
+	}
+}
+
+// Opaque scans the entire image and reports whether it is fully opaque.
+func (p *Gray) Opaque() bool {
+	return true
+}
+
+// NewGray returns a new Gray with the given bounds.
+func NewGray(r Rectangle) *Gray {
+	w, h := r.Dx(), r.Dy()
+	pix := make([]uint8, 1*w*h)
+	return &Gray{pix, 1 * w, r}
+}
+
+// Gray16 is an in-memory image whose At method returns color.Gray16 values.
+type Gray16 struct {
+	// Pix holds the image's pixels, as gray values in big-endian format. The pixel at
+	// (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*2].
+	Pix []uint8
+	// Stride is the Pix stride (in bytes) between vertically adjacent pixels.
+	Stride int
+	// Rect is the image's bounds.
+	Rect Rectangle
+}
+
+func (p *Gray16) ColorModel() color.Model { return color.Gray16Model }
+
+func (p *Gray16) Bounds() Rectangle { return p.Rect }
+
+func (p *Gray16) At(x, y int) color.Color {
+	return p.Gray16At(x, y)
+}
+
+func (p *Gray16) Gray16At(x, y int) color.Gray16 {
+	if !(Point{x, y}.In(p.Rect)) {
+		return color.Gray16{}
+	}
+	i := p.PixOffset(x, y)
+	return color.Gray16{uint16(p.Pix[i+0])<<8 | uint16(p.Pix[i+1])}
+}
+
+// PixOffset returns the index of the first element of Pix that corresponds to
+// the pixel at (x, y).
+func (p *Gray16) PixOffset(x, y int) int {
+	return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*2
+}
+
+func (p *Gray16) Set(x, y int, c color.Color) {
+	if !(Point{x, y}.In(p.Rect)) {
+		return
+	}
+	i := p.PixOffset(x, y)
+	c1 := color.Gray16Model.Convert(c).(color.Gray16)
+	p.Pix[i+0] = uint8(c1.Y >> 8)
+	p.Pix[i+1] = uint8(c1.Y)
+}
+
+func (p *Gray16) SetGray16(x, y int, c color.Gray16) {
+	if !(Point{x, y}.In(p.Rect)) {
+		return
+	}
+	i := p.PixOffset(x, y)
+	p.Pix[i+0] = uint8(c.Y >> 8)
+	p.Pix[i+1] = uint8(c.Y)
+}
+
+// SubImage returns an image representing the portion of the image p visible
+// through r. The returned value shares pixels with the original image.
+func (p *Gray16) SubImage(r Rectangle) Image {
+	r = r.Intersect(p.Rect)
+	// If r1 and r2 are Rectangles, r1.Intersect(r2) is not guaranteed to be inside
+	// either r1 or r2 if the intersection is empty. Without explicitly checking for
+	// this, the Pix[i:] expression below can panic.
+	if r.Empty() {
+		return &Gray16{}
+	}
+	i := p.PixOffset(r.Min.X, r.Min.Y)
+	return &Gray16{
+		Pix:    p.Pix[i:],
+		Stride: p.Stride,
+		Rect:   r,
+	}
+}
+
+// Opaque scans the entire image and reports whether it is fully opaque.
+func (p *Gray16) Opaque() bool {
+	return true
+}
+
+// NewGray16 returns a new Gray16 with the given bounds.
+func NewGray16(r Rectangle) *Gray16 {
+	w, h := r.Dx(), r.Dy()
+	pix := make([]uint8, 2*w*h)
+	return &Gray16{pix, 2 * w, r}
+}
+
+// Paletted is an in-memory image of uint8 indices into a given palette.
+type Paletted struct {
+	// Pix holds the image's pixels, as palette indices. The pixel at
+	// (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*1].
+	Pix []uint8
+	// Stride is the Pix stride (in bytes) between vertically adjacent pixels.
+	Stride int
+	// Rect is the image's bounds.
+	Rect Rectangle
+	// Palette is the image's palette.
+	Palette color.Palette
+}
+
+func (p *Paletted) ColorModel() color.Model { return p.Palette }
+
+func (p *Paletted) Bounds() Rectangle { return p.Rect }
+
+func (p *Paletted) At(x, y int) color.Color {
+	if len(p.Palette) == 0 {
+		return nil
+	}
+	if !(Point{x, y}.In(p.Rect)) {
+		return p.Palette[0]
+	}
+	i := p.PixOffset(x, y)
+	return p.Palette[p.Pix[i]]
+}
+
+// PixOffset returns the index of the first element of Pix that corresponds to
+// the pixel at (x, y).
+func (p *Paletted) PixOffset(x, y int) int {
+	return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*1
+}
+
+func (p *Paletted) Set(x, y int, c color.Color) {
+	if !(Point{x, y}.In(p.Rect)) {
+		return
+	}
+	i := p.PixOffset(x, y)
+	p.Pix[i] = uint8(p.Palette.Index(c))
+}
+
+func (p *Paletted) ColorIndexAt(x, y int) uint8 {
+	if !(Point{x, y}.In(p.Rect)) {
+		return 0
+	}
+	i := p.PixOffset(x, y)
+	return p.Pix[i]
+}
+
+func (p *Paletted) SetColorIndex(x, y int, index uint8) {
+	if !(Point{x, y}.In(p.Rect)) {
+		return
+	}
+	i := p.PixOffset(x, y)
+	p.Pix[i] = index
+}
+
+// SubImage returns an image representing the portion of the image p visible
+// through r. The returned value shares pixels with the original image.
+func (p *Paletted) SubImage(r Rectangle) Image {
+	r = r.Intersect(p.Rect)
+	// If r1 and r2 are Rectangles, r1.Intersect(r2) is not guaranteed to be inside
+	// either r1 or r2 if the intersection is empty. Without explicitly checking for
+	// this, the Pix[i:] expression below can panic.
+	if r.Empty() {
+		return &Paletted{
+			Palette: p.Palette,
+		}
+	}
+	i := p.PixOffset(r.Min.X, r.Min.Y)
+	return &Paletted{
+		Pix:     p.Pix[i:],
+		Stride:  p.Stride,
+		Rect:    p.Rect.Intersect(r),
+		Palette: p.Palette,
+	}
+}
+
+// Opaque scans the entire image and reports whether it is fully opaque.
+func (p *Paletted) Opaque() bool {
+	var present [256]bool
+	i0, i1 := 0, p.Rect.Dx()
+	for y := p.Rect.Min.Y; y < p.Rect.Max.Y; y++ {
+		for _, c := range p.Pix[i0:i1] {
+			present[c] = true
+		}
+		i0 += p.Stride
+		i1 += p.Stride
+	}
+	for i, c := range p.Palette {
+		if !present[i] {
+			continue
+		}
+		_, _, _, a := c.RGBA()
+		if a != 0xffff {
+			return false
+		}
+	}
+	return true
+}
+
+// NewPaletted returns a new Paletted with the given width, height and palette.
+func NewPaletted(r Rectangle, p color.Palette) *Paletted {
+	w, h := r.Dx(), r.Dy()
+	pix := make([]uint8, 1*w*h)
+	return &Paletted{pix, 1 * w, r, p}
+}
diff --git a/src/pkg/image/image_test.go b/src/image/image_test.go
similarity index 100%
rename from src/pkg/image/image_test.go
rename to src/image/image_test.go
diff --git a/src/pkg/image/jpeg/dct_test.go b/src/image/jpeg/dct_test.go
similarity index 100%
rename from src/pkg/image/jpeg/dct_test.go
rename to src/image/jpeg/dct_test.go
diff --git a/src/pkg/image/jpeg/fdct.go b/src/image/jpeg/fdct.go
similarity index 100%
rename from src/pkg/image/jpeg/fdct.go
rename to src/image/jpeg/fdct.go
diff --git a/src/image/jpeg/huffman.go b/src/image/jpeg/huffman.go
new file mode 100644
index 0000000..d4ff4cf
--- /dev/null
+++ b/src/image/jpeg/huffman.go
@@ -0,0 +1,244 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package jpeg
+
+import (
+	"io"
+)
+
+// maxCodeLength is the maximum (inclusive) number of bits in a Huffman code.
+const maxCodeLength = 16
+
+// maxNCodes is the maximum (inclusive) number of codes in a Huffman tree.
+const maxNCodes = 256
+
+// lutSize is the log-2 size of the Huffman decoder's look-up table.
+const lutSize = 8
+
+// huffman is a Huffman decoder, specified in section C.
+type huffman struct {
+	// length is the number of codes in the tree.
+	nCodes int32
+	// lut is the look-up table for the next lutSize bits in the bit-stream.
+	// The high 8 bits of the uint16 are the encoded value. The low 8 bits
+	// are 1 plus the code length, or 0 if the value is too large to fit in
+	// lutSize bits.
+	lut [1 << lutSize]uint16
+	// vals are the decoded values, sorted by their encoding.
+	vals [maxNCodes]uint8
+	// minCodes[i] is the minimum code of length i, or -1 if there are no
+	// codes of that length.
+	minCodes [maxCodeLength]int32
+	// maxCodes[i] is the maximum code of length i, or -1 if there are no
+	// codes of that length.
+	maxCodes [maxCodeLength]int32
+	// valsIndices[i] is the index into vals of minCodes[i].
+	valsIndices [maxCodeLength]int32
+}
+
+// errShortHuffmanData means that an unexpected EOF occurred while decoding
+// Huffman data.
+var errShortHuffmanData = FormatError("short Huffman data")
+
+// ensureNBits reads bytes from the byte buffer to ensure that d.bits.n is at
+// least n. For best performance (avoiding function calls inside hot loops),
+// the caller is the one responsible for first checking that d.bits.n < n.
+func (d *decoder) ensureNBits(n int32) error {
+	for {
+		c, err := d.readByteStuffedByte()
+		if err != nil {
+			if err == io.EOF {
+				return errShortHuffmanData
+			}
+			return err
+		}
+		d.bits.a = d.bits.a<<8 | uint32(c)
+		d.bits.n += 8
+		if d.bits.m == 0 {
+			d.bits.m = 1 << 7
+		} else {
+			d.bits.m <<= 8
+		}
+		if d.bits.n >= n {
+			break
+		}
+	}
+	return nil
+}
+
+// receiveExtend is the composition of RECEIVE and EXTEND, specified in section
+// F.2.2.1.
+func (d *decoder) receiveExtend(t uint8) (int32, error) {
+	if d.bits.n < int32(t) {
+		if err := d.ensureNBits(int32(t)); err != nil {
+			return 0, err
+		}
+	}
+	d.bits.n -= int32(t)
+	d.bits.m >>= t
+	s := int32(1) << t
+	x := int32(d.bits.a>>uint8(d.bits.n)) & (s - 1)
+	if x < s>>1 {
+		x += ((-1) << t) + 1
+	}
+	return x, nil
+}
+
+// processDHT processes a Define Huffman Table marker, and initializes a huffman
+// struct from its contents. Specified in section B.2.4.2.
+func (d *decoder) processDHT(n int) error {
+	for n > 0 {
+		if n < 17 {
+			return FormatError("DHT has wrong length")
+		}
+		if err := d.readFull(d.tmp[:17]); err != nil {
+			return err
+		}
+		tc := d.tmp[0] >> 4
+		if tc > maxTc {
+			return FormatError("bad Tc value")
+		}
+		th := d.tmp[0] & 0x0f
+		if th > maxTh || !d.progressive && th > 1 {
+			return FormatError("bad Th value")
+		}
+		h := &d.huff[tc][th]
+
+		// Read nCodes and h.vals (and derive h.nCodes).
+		// nCodes[i] is the number of codes with code length i.
+		// h.nCodes is the total number of codes.
+		h.nCodes = 0
+		var nCodes [maxCodeLength]int32
+		for i := range nCodes {
+			nCodes[i] = int32(d.tmp[i+1])
+			h.nCodes += nCodes[i]
+		}
+		if h.nCodes == 0 {
+			return FormatError("Huffman table has zero length")
+		}
+		if h.nCodes > maxNCodes {
+			return FormatError("Huffman table has excessive length")
+		}
+		n -= int(h.nCodes) + 17
+		if n < 0 {
+			return FormatError("DHT has wrong length")
+		}
+		if err := d.readFull(h.vals[:h.nCodes]); err != nil {
+			return err
+		}
+
+		// Derive the look-up table.
+		for i := range h.lut {
+			h.lut[i] = 0
+		}
+		var x, code uint32
+		for i := uint32(0); i < lutSize; i++ {
+			code <<= 1
+			for j := int32(0); j < nCodes[i]; j++ {
+				// The codeLength is 1+i, so shift code by 8-(1+i) to
+				// calculate the high bits for every 8-bit sequence
+				// whose codeLength's high bits matches code.
+				// The high 8 bits of lutValue are the encoded value.
+				// The low 8 bits are 1 plus the codeLength.
+				base := uint8(code << (7 - i))
+				lutValue := uint16(h.vals[x])<<8 | uint16(2+i)
+				for k := uint8(0); k < 1<<(7-i); k++ {
+					h.lut[base|k] = lutValue
+				}
+				code++
+				x++
+			}
+		}
+
+		// Derive minCodes, maxCodes, and valsIndices.
+		var c, index int32
+		for i, n := range nCodes {
+			if n == 0 {
+				h.minCodes[i] = -1
+				h.maxCodes[i] = -1
+				h.valsIndices[i] = -1
+			} else {
+				h.minCodes[i] = c
+				h.maxCodes[i] = c + n - 1
+				h.valsIndices[i] = index
+				c += n
+				index += n
+			}
+			c <<= 1
+		}
+	}
+	return nil
+}
+
+// decodeHuffman returns the next Huffman-coded value from the bit-stream,
+// decoded according to h.
+func (d *decoder) decodeHuffman(h *huffman) (uint8, error) {
+	if h.nCodes == 0 {
+		return 0, FormatError("uninitialized Huffman table")
+	}
+
+	if d.bits.n < 8 {
+		if err := d.ensureNBits(8); err != nil {
+			if err != errMissingFF00 && err != errShortHuffmanData {
+				return 0, err
+			}
+			// There are no more bytes of data in this segment, but we may still
+			// be able to read the next symbol out of the previously read bits.
+			// First, undo the readByte that the ensureNBits call made.
+			d.unreadByteStuffedByte()
+			goto slowPath
+		}
+	}
+	if v := h.lut[(d.bits.a>>uint32(d.bits.n-lutSize))&0xff]; v != 0 {
+		n := (v & 0xff) - 1
+		d.bits.n -= int32(n)
+		d.bits.m >>= n
+		return uint8(v >> 8), nil
+	}
+
+slowPath:
+	for i, code := 0, int32(0); i < maxCodeLength; i++ {
+		if d.bits.n == 0 {
+			if err := d.ensureNBits(1); err != nil {
+				return 0, err
+			}
+		}
+		if d.bits.a&d.bits.m != 0 {
+			code |= 1
+		}
+		d.bits.n--
+		d.bits.m >>= 1
+		if code <= h.maxCodes[i] {
+			return h.vals[h.valsIndices[i]+code-h.minCodes[i]], nil
+		}
+		code <<= 1
+	}
+	return 0, FormatError("bad Huffman code")
+}
+
+func (d *decoder) decodeBit() (bool, error) {
+	if d.bits.n == 0 {
+		if err := d.ensureNBits(1); err != nil {
+			return false, err
+		}
+	}
+	ret := d.bits.a&d.bits.m != 0
+	d.bits.n--
+	d.bits.m >>= 1
+	return ret, nil
+}
+
+func (d *decoder) decodeBits(n int32) (uint32, error) {
+	if d.bits.n < n {
+		if err := d.ensureNBits(n); err != nil {
+			return 0, err
+		}
+	}
+	ret := d.bits.a >> uint32(d.bits.n-n)
+	ret &= (1 << uint32(n)) - 1
+	d.bits.n -= n
+	d.bits.m >>= uint32(n)
+	return ret, nil
+}
diff --git a/src/pkg/image/jpeg/idct.go b/src/image/jpeg/idct.go
similarity index 100%
rename from src/pkg/image/jpeg/idct.go
rename to src/image/jpeg/idct.go
diff --git a/src/image/jpeg/reader.go b/src/image/jpeg/reader.go
new file mode 100644
index 0000000..6d8b1d1
--- /dev/null
+++ b/src/image/jpeg/reader.go
@@ -0,0 +1,527 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package jpeg implements a JPEG image decoder and encoder.
+//
+// JPEG is defined in ITU-T T.81: http://www.w3.org/Graphics/JPEG/itu-t81.pdf.
+package jpeg
+
+import (
+	"image"
+	"image/color"
+	"io"
+)
+
+// TODO(nigeltao): fix up the doc comment style so that sentences start with
+// the name of the type or function that they annotate.
+
+// A FormatError reports that the input is not a valid JPEG.
+type FormatError string
+
+func (e FormatError) Error() string { return "invalid JPEG format: " + string(e) }
+
+// An UnsupportedError reports that the input uses a valid but unimplemented JPEG feature.
+type UnsupportedError string
+
+func (e UnsupportedError) Error() string { return "unsupported JPEG feature: " + string(e) }
+
+// Component specification, specified in section B.2.2.
+type component struct {
+	h  int   // Horizontal sampling factor.
+	v  int   // Vertical sampling factor.
+	c  uint8 // Component identifier.
+	tq uint8 // Quantization table destination selector.
+}
+
+const (
+	dcTable = 0
+	acTable = 1
+	maxTc   = 1
+	maxTh   = 3
+	maxTq   = 3
+
+	// A grayscale JPEG image has only a Y component.
+	nGrayComponent = 1
+	// A color JPEG image has Y, Cb and Cr components.
+	nColorComponent = 3
+
+	// We only support 4:4:4, 4:4:0, 4:2:2 and 4:2:0 downsampling, and therefore the
+	// number of luma samples per chroma sample is at most 2 in the horizontal
+	// and 2 in the vertical direction.
+	maxH = 2
+	maxV = 2
+)
+
+const (
+	soiMarker   = 0xd8 // Start Of Image.
+	eoiMarker   = 0xd9 // End Of Image.
+	sof0Marker  = 0xc0 // Start Of Frame (Baseline).
+	sof2Marker  = 0xc2 // Start Of Frame (Progressive).
+	dhtMarker   = 0xc4 // Define Huffman Table.
+	dqtMarker   = 0xdb // Define Quantization Table.
+	sosMarker   = 0xda // Start Of Scan.
+	driMarker   = 0xdd // Define Restart Interval.
+	rst0Marker  = 0xd0 // ReSTart (0).
+	rst7Marker  = 0xd7 // ReSTart (7).
+	app0Marker  = 0xe0 // APPlication specific (0).
+	app15Marker = 0xef // APPlication specific (15).
+	comMarker   = 0xfe // COMment.
+)
+
+// unzig maps from the zig-zag ordering to the natural ordering. For example,
+// unzig[3] is the column and row of the fourth element in zig-zag order. The
+// value is 16, which means first column (16%8 == 0) and third row (16/8 == 2).
+var unzig = [blockSize]int{
+	0, 1, 8, 16, 9, 2, 3, 10,
+	17, 24, 32, 25, 18, 11, 4, 5,
+	12, 19, 26, 33, 40, 48, 41, 34,
+	27, 20, 13, 6, 7, 14, 21, 28,
+	35, 42, 49, 56, 57, 50, 43, 36,
+	29, 22, 15, 23, 30, 37, 44, 51,
+	58, 59, 52, 45, 38, 31, 39, 46,
+	53, 60, 61, 54, 47, 55, 62, 63,
+}
+
+// Reader is deprecated.
+type Reader interface {
+	io.ByteReader
+	io.Reader
+}
+
+// bits holds the unprocessed bits that have been taken from the byte-stream.
+// The n least significant bits of a form the unread bits, to be read in MSB to
+// LSB order.
+type bits struct {
+	a uint32 // accumulator.
+	m uint32 // mask. m==1<<(n-1) when n>0, with m==0 when n==0.
+	n int32  // the number of unread bits in a.
+}
+
+type decoder struct {
+	r    io.Reader
+	bits bits
+	// bytes is a byte buffer, similar to a bufio.Reader, except that it
+	// has to be able to unread more than 1 byte, due to byte stuffing.
+	// Byte stuffing is specified in section F.1.2.3.
+	bytes struct {
+		// buf[i:j] are the buffered bytes read from the underlying
+		// io.Reader that haven't yet been passed further on.
+		buf  [4096]byte
+		i, j int
+		// nUnreadable is the number of bytes to back up i after
+		// overshooting. It can be 0, 1 or 2.
+		nUnreadable int
+	}
+	width, height int
+	img1          *image.Gray
+	img3          *image.YCbCr
+	ri            int // Restart Interval.
+	nComp         int
+	progressive   bool
+	eobRun        uint16 // End-of-Band run, specified in section G.1.2.2.
+	comp          [nColorComponent]component
+	progCoeffs    [nColorComponent][]block // Saved state between progressive-mode scans.
+	huff          [maxTc + 1][maxTh + 1]huffman
+	quant         [maxTq + 1]block // Quantization tables, in zig-zag order.
+	tmp           [blockSize + 1]byte
+}
+
+// fill fills up the d.bytes.buf buffer from the underlying io.Reader. It
+// should only be called when there are no unread bytes in d.bytes.
+func (d *decoder) fill() error {
+	if d.bytes.i != d.bytes.j {
+		panic("jpeg: fill called when unread bytes exist")
+	}
+	// Move the last 2 bytes to the start of the buffer, in case we need
+	// to call unreadByteStuffedByte.
+	if d.bytes.j > 2 {
+		d.bytes.buf[0] = d.bytes.buf[d.bytes.j-2]
+		d.bytes.buf[1] = d.bytes.buf[d.bytes.j-1]
+		d.bytes.i, d.bytes.j = 2, 2
+	}
+	// Fill in the rest of the buffer.
+	n, err := d.r.Read(d.bytes.buf[d.bytes.j:])
+	d.bytes.j += n
+	if n > 0 {
+		err = nil
+	}
+	return err
+}
+
+// unreadByteStuffedByte undoes the most recent readByteStuffedByte call,
+// giving a byte of data back from d.bits to d.bytes. The Huffman look-up table
+// requires at least 8 bits for look-up, which means that Huffman decoding can
+// sometimes overshoot and read one or two too many bytes. Two-byte overshoot
+// can happen when expecting to read a 0xff 0x00 byte-stuffed byte.
+func (d *decoder) unreadByteStuffedByte() {
+	if d.bytes.nUnreadable == 0 {
+		panic("jpeg: unreadByteStuffedByte call cannot be fulfilled")
+	}
+	d.bytes.i -= d.bytes.nUnreadable
+	d.bytes.nUnreadable = 0
+	if d.bits.n >= 8 {
+		d.bits.a >>= 8
+		d.bits.n -= 8
+		d.bits.m >>= 8
+	}
+}
+
+// readByte returns the next byte, whether buffered or not buffered. It does
+// not care about byte stuffing.
+func (d *decoder) readByte() (x byte, err error) {
+	for d.bytes.i == d.bytes.j {
+		if err = d.fill(); err != nil {
+			return 0, err
+		}
+	}
+	x = d.bytes.buf[d.bytes.i]
+	d.bytes.i++
+	d.bytes.nUnreadable = 0
+	return x, nil
+}
+
+// errMissingFF00 means that readByteStuffedByte encountered an 0xff byte (a
+// marker byte) that wasn't the expected byte-stuffed sequence 0xff, 0x00.
+var errMissingFF00 = FormatError("missing 0xff00 sequence")
+
+// readByteStuffedByte is like readByte but is for byte-stuffed Huffman data.
+func (d *decoder) readByteStuffedByte() (x byte, err error) {
+	// Take the fast path if d.bytes.buf contains at least two bytes.
+	if d.bytes.i+2 <= d.bytes.j {
+		x = d.bytes.buf[d.bytes.i]
+		d.bytes.i++
+		d.bytes.nUnreadable = 1
+		if x != 0xff {
+			return x, err
+		}
+		if d.bytes.buf[d.bytes.i] != 0x00 {
+			return 0, errMissingFF00
+		}
+		d.bytes.i++
+		d.bytes.nUnreadable = 2
+		return 0xff, nil
+	}
+
+	x, err = d.readByte()
+	if err != nil {
+		return 0, err
+	}
+	if x != 0xff {
+		d.bytes.nUnreadable = 1
+		return x, nil
+	}
+
+	x, err = d.readByte()
+	if err != nil {
+		d.bytes.nUnreadable = 1
+		return 0, err
+	}
+	d.bytes.nUnreadable = 2
+	if x != 0x00 {
+		return 0, errMissingFF00
+	}
+	return 0xff, nil
+}
+
+// readFull reads exactly len(p) bytes into p. It does not care about byte
+// stuffing.
+func (d *decoder) readFull(p []byte) error {
+	// Unread the overshot bytes, if any.
+	if d.bytes.nUnreadable != 0 {
+		if d.bits.n >= 8 {
+			d.unreadByteStuffedByte()
+		}
+		d.bytes.nUnreadable = 0
+	}
+
+	for {
+		n := copy(p, d.bytes.buf[d.bytes.i:d.bytes.j])
+		p = p[n:]
+		d.bytes.i += n
+		if len(p) == 0 {
+			break
+		}
+		if err := d.fill(); err != nil {
+			if err == io.EOF {
+				err = io.ErrUnexpectedEOF
+			}
+			return err
+		}
+	}
+	return nil
+}
+
+// ignore ignores the next n bytes.
+func (d *decoder) ignore(n int) error {
+	// Unread the overshot bytes, if any.
+	if d.bytes.nUnreadable != 0 {
+		if d.bits.n >= 8 {
+			d.unreadByteStuffedByte()
+		}
+		d.bytes.nUnreadable = 0
+	}
+
+	for {
+		m := d.bytes.j - d.bytes.i
+		if m > n {
+			m = n
+		}
+		d.bytes.i += m
+		n -= m
+		if n == 0 {
+			break
+		}
+		if err := d.fill(); err != nil {
+			if err == io.EOF {
+				err = io.ErrUnexpectedEOF
+			}
+			return err
+		}
+	}
+	return nil
+}
+
+// Specified in section B.2.2.
+func (d *decoder) processSOF(n int) error {
+	switch n {
+	case 6 + 3*nGrayComponent:
+		d.nComp = nGrayComponent
+	case 6 + 3*nColorComponent:
+		d.nComp = nColorComponent
+	default:
+		return UnsupportedError("SOF has wrong length")
+	}
+	if err := d.readFull(d.tmp[:n]); err != nil {
+		return err
+	}
+	// We only support 8-bit precision.
+	if d.tmp[0] != 8 {
+		return UnsupportedError("precision")
+	}
+	d.height = int(d.tmp[1])<<8 + int(d.tmp[2])
+	d.width = int(d.tmp[3])<<8 + int(d.tmp[4])
+	if int(d.tmp[5]) != d.nComp {
+		return UnsupportedError("SOF has wrong number of image components")
+	}
+	for i := 0; i < d.nComp; i++ {
+		d.comp[i].c = d.tmp[6+3*i]
+		d.comp[i].tq = d.tmp[8+3*i]
+		if d.nComp == nGrayComponent {
+			// If a JPEG image has only one component, section A.2 says "this data
+			// is non-interleaved by definition" and section A.2.2 says "[in this
+			// case...] the order of data units within a scan shall be left-to-right
+			// and top-to-bottom... regardless of the values of H_1 and V_1". Section
+			// 4.8.2 also says "[for non-interleaved data], the MCU is defined to be
+			// one data unit". Similarly, section A.1.1 explains that it is the ratio
+			// of H_i to max_j(H_j) that matters, and similarly for V. For grayscale
+			// images, H_1 is the maximum H_j for all components j, so that ratio is
+			// always 1. The component's (h, v) is effectively always (1, 1): even if
+			// the nominal (h, v) is (2, 1), a 20x5 image is encoded in three 8x8
+			// MCUs, not two 16x8 MCUs.
+			d.comp[i].h = 1
+			d.comp[i].v = 1
+			continue
+		}
+		hv := d.tmp[7+3*i]
+		d.comp[i].h = int(hv >> 4)
+		d.comp[i].v = int(hv & 0x0f)
+		// For color images, we only support 4:4:4, 4:4:0, 4:2:2 or 4:2:0 chroma
+		// downsampling ratios. This implies that the (h, v) values for the Y
+		// component are either (1, 1), (1, 2), (2, 1) or (2, 2), and the (h, v)
+		// values for the Cr and Cb components must be (1, 1).
+		if i == 0 {
+			if hv != 0x11 && hv != 0x21 && hv != 0x22 && hv != 0x12 {
+				return UnsupportedError("luma/chroma downsample ratio")
+			}
+		} else if hv != 0x11 {
+			return UnsupportedError("luma/chroma downsample ratio")
+		}
+	}
+	return nil
+}
+
+// Specified in section B.2.4.1.
+func (d *decoder) processDQT(n int) error {
+	const qtLength = 1 + blockSize
+	for ; n >= qtLength; n -= qtLength {
+		if err := d.readFull(d.tmp[:qtLength]); err != nil {
+			return err
+		}
+		pq := d.tmp[0] >> 4
+		if pq != 0 {
+			return UnsupportedError("bad Pq value")
+		}
+		tq := d.tmp[0] & 0x0f
+		if tq > maxTq {
+			return FormatError("bad Tq value")
+		}
+		for i := range d.quant[tq] {
+			d.quant[tq][i] = int32(d.tmp[i+1])
+		}
+	}
+	if n != 0 {
+		return FormatError("DQT has wrong length")
+	}
+	return nil
+}
+
+// Specified in section B.2.4.4.
+func (d *decoder) processDRI(n int) error {
+	if n != 2 {
+		return FormatError("DRI has wrong length")
+	}
+	if err := d.readFull(d.tmp[:2]); err != nil {
+		return err
+	}
+	d.ri = int(d.tmp[0])<<8 + int(d.tmp[1])
+	return nil
+}
+
+// decode reads a JPEG image from r and returns it as an image.Image.
+func (d *decoder) decode(r io.Reader, configOnly bool) (image.Image, error) {
+	d.r = r
+
+	// Check for the Start Of Image marker.
+	if err := d.readFull(d.tmp[:2]); err != nil {
+		return nil, err
+	}
+	if d.tmp[0] != 0xff || d.tmp[1] != soiMarker {
+		return nil, FormatError("missing SOI marker")
+	}
+
+	// Process the remaining segments until the End Of Image marker.
+	for {
+		err := d.readFull(d.tmp[:2])
+		if err != nil {
+			return nil, err
+		}
+		for d.tmp[0] != 0xff {
+			// Strictly speaking, this is a format error. However, libjpeg is
+			// liberal in what it accepts. As of version 9, next_marker in
+			// jdmarker.c treats this as a warning (JWRN_EXTRANEOUS_DATA) and
+			// continues to decode the stream. Even before next_marker sees
+			// extraneous data, jpeg_fill_bit_buffer in jdhuff.c reads as many
+			// bytes as it can, possibly past the end of a scan's data. It
+			// effectively puts back any markers that it overscanned (e.g. an
+			// "\xff\xd9" EOI marker), but it does not put back non-marker data,
+			// and thus it can silently ignore a small number of extraneous
+			// non-marker bytes before next_marker has a chance to see them (and
+			// print a warning).
+			//
+			// We are therefore also liberal in what we accept. Extraneous data
+			// is silently ignored.
+			//
+			// This is similar to, but not exactly the same as, the restart
+			// mechanism within a scan (the RST[0-7] markers).
+			//
+			// Note that extraneous 0xff bytes in e.g. SOS data are escaped as
+			// "\xff\x00", and so are detected a little further down below.
+			d.tmp[0] = d.tmp[1]
+			d.tmp[1], err = d.readByte()
+			if err != nil {
+				return nil, err
+			}
+		}
+		marker := d.tmp[1]
+		if marker == 0 {
+			// Treat "\xff\x00" as extraneous data.
+			continue
+		}
+		for marker == 0xff {
+			// Section B.1.1.2 says, "Any marker may optionally be preceded by any
+			// number of fill bytes, which are bytes assigned code X'FF'".
+			marker, err = d.readByte()
+			if err != nil {
+				return nil, err
+			}
+		}
+		if marker == eoiMarker { // End Of Image.
+			break
+		}
+		if rst0Marker <= marker && marker <= rst7Marker {
+			// Figures B.2 and B.16 of the specification suggest that restart markers should
+			// only occur between Entropy Coded Segments and not after the final ECS.
+			// However, some encoders may generate incorrect JPEGs with a final restart
+			// marker. That restart marker will be seen here instead of inside the processSOS
+			// method, and is ignored as a harmless error. Restart markers have no extra data,
+			// so we check for this before we read the 16-bit length of the segment.
+			continue
+		}
+
+		// Read the 16-bit length of the segment. The value includes the 2 bytes for the
+		// length itself, so we subtract 2 to get the number of remaining bytes.
+		if err = d.readFull(d.tmp[:2]); err != nil {
+			return nil, err
+		}
+		n := int(d.tmp[0])<<8 + int(d.tmp[1]) - 2
+		if n < 0 {
+			return nil, FormatError("short segment length")
+		}
+
+		switch {
+		case marker == sof0Marker || marker == sof2Marker: // Start Of Frame.
+			d.progressive = marker == sof2Marker
+			err = d.processSOF(n)
+			if configOnly {
+				return nil, err
+			}
+		case marker == dhtMarker: // Define Huffman Table.
+			err = d.processDHT(n)
+		case marker == dqtMarker: // Define Quantization Table.
+			err = d.processDQT(n)
+		case marker == sosMarker: // Start Of Scan.
+			err = d.processSOS(n)
+		case marker == driMarker: // Define Restart Interval.
+			err = d.processDRI(n)
+		case app0Marker <= marker && marker <= app15Marker || marker == comMarker: // APPlication specific, or COMment.
+			err = d.ignore(n)
+		default:
+			err = UnsupportedError("unknown marker")
+		}
+		if err != nil {
+			return nil, err
+		}
+	}
+	if d.img1 != nil {
+		return d.img1, nil
+	}
+	if d.img3 != nil {
+		return d.img3, nil
+	}
+	return nil, FormatError("missing SOS marker")
+}
+
+// Decode reads a JPEG image from r and returns it as an image.Image.
+func Decode(r io.Reader) (image.Image, error) {
+	var d decoder
+	return d.decode(r, false)
+}
+
+// DecodeConfig returns the color model and dimensions of a JPEG image without
+// decoding the entire image.
+func DecodeConfig(r io.Reader) (image.Config, error) {
+	var d decoder
+	if _, err := d.decode(r, true); err != nil {
+		return image.Config{}, err
+	}
+	switch d.nComp {
+	case nGrayComponent:
+		return image.Config{
+			ColorModel: color.GrayModel,
+			Width:      d.width,
+			Height:     d.height,
+		}, nil
+	case nColorComponent:
+		return image.Config{
+			ColorModel: color.YCbCrModel,
+			Width:      d.width,
+			Height:     d.height,
+		}, nil
+	}
+	return image.Config{}, FormatError("missing SOF marker")
+}
+
+func init() {
+	image.RegisterFormat("jpeg", "\xff\xd8", Decode, DecodeConfig)
+}
diff --git a/src/image/jpeg/reader_test.go b/src/image/jpeg/reader_test.go
new file mode 100644
index 0000000..4de2e8e
--- /dev/null
+++ b/src/image/jpeg/reader_test.go
@@ -0,0 +1,270 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package jpeg
+
+import (
+	"bytes"
+	"fmt"
+	"image"
+	"image/color"
+	"io"
+	"io/ioutil"
+	"math/rand"
+	"os"
+	"strings"
+	"testing"
+)
+
+// TestDecodeProgressive tests that decoding the baseline and progressive
+// versions of the same image result in exactly the same pixel data, in YCbCr
+// space for color images, and Y space for grayscale images.
+func TestDecodeProgressive(t *testing.T) {
+	testCases := []string{
+		"../testdata/video-001",
+		"../testdata/video-001.q50.420",
+		"../testdata/video-001.q50.422",
+		"../testdata/video-001.q50.440",
+		"../testdata/video-001.q50.444",
+		"../testdata/video-005.gray.q50",
+		"../testdata/video-005.gray.q50.2x2",
+		"../testdata/video-001.separate.dc.progression",
+	}
+	for _, tc := range testCases {
+		m0, err := decodeFile(tc + ".jpeg")
+		if err != nil {
+			t.Errorf("%s: %v", tc+".jpeg", err)
+			continue
+		}
+		m1, err := decodeFile(tc + ".progressive.jpeg")
+		if err != nil {
+			t.Errorf("%s: %v", tc+".progressive.jpeg", err)
+			continue
+		}
+		if m0.Bounds() != m1.Bounds() {
+			t.Errorf("%s: bounds differ: %v and %v", tc, m0.Bounds(), m1.Bounds())
+			continue
+		}
+		// All of the video-*.jpeg files are 150x103.
+		if m0.Bounds() != image.Rect(0, 0, 150, 103) {
+			t.Errorf("%s: bad bounds: %v", tc, m0.Bounds())
+			continue
+		}
+
+		switch m0 := m0.(type) {
+		case *image.YCbCr:
+			m1 := m1.(*image.YCbCr)
+			if err := check(m0.Bounds(), m0.Y, m1.Y, m0.YStride, m1.YStride); err != nil {
+				t.Errorf("%s (Y): %v", tc, err)
+				continue
+			}
+			if err := check(m0.Bounds(), m0.Cb, m1.Cb, m0.CStride, m1.CStride); err != nil {
+				t.Errorf("%s (Cb): %v", tc, err)
+				continue
+			}
+			if err := check(m0.Bounds(), m0.Cr, m1.Cr, m0.CStride, m1.CStride); err != nil {
+				t.Errorf("%s (Cr): %v", tc, err)
+				continue
+			}
+		case *image.Gray:
+			m1 := m1.(*image.Gray)
+			if err := check(m0.Bounds(), m0.Pix, m1.Pix, m0.Stride, m1.Stride); err != nil {
+				t.Errorf("%s: %v", tc, err)
+				continue
+			}
+		default:
+			t.Errorf("%s: unexpected image type %T", tc, m0)
+			continue
+		}
+	}
+}
+
+func decodeFile(filename string) (image.Image, error) {
+	f, err := os.Open(filename)
+	if err != nil {
+		return nil, err
+	}
+	defer f.Close()
+	return Decode(f)
+}
+
+type eofReader struct {
+	data     []byte // deliver from Read without EOF
+	dataEOF  []byte // then deliver from Read with EOF on last chunk
+	lenAtEOF int
+}
+
+func (r *eofReader) Read(b []byte) (n int, err error) {
+	if len(r.data) > 0 {
+		n = copy(b, r.data)
+		r.data = r.data[n:]
+	} else {
+		n = copy(b, r.dataEOF)
+		r.dataEOF = r.dataEOF[n:]
+		if len(r.dataEOF) == 0 {
+			err = io.EOF
+			if r.lenAtEOF == -1 {
+				r.lenAtEOF = n
+			}
+		}
+	}
+	return
+}
+
+func TestDecodeEOF(t *testing.T) {
+	// Check that if reader returns final data and EOF at same time, jpeg handles it.
+	data, err := ioutil.ReadFile("../testdata/video-001.jpeg")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	n := len(data)
+	for i := 0; i < n; {
+		r := &eofReader{data[:n-i], data[n-i:], -1}
+		_, err := Decode(r)
+		if err != nil {
+			t.Errorf("Decode with Read() = %d, EOF: %v", r.lenAtEOF, err)
+		}
+		if i == 0 {
+			i = 1
+		} else {
+			i *= 2
+		}
+	}
+}
+
+// check checks that the two pix data are equal, within the given bounds.
+func check(bounds image.Rectangle, pix0, pix1 []byte, stride0, stride1 int) error {
+	if stride0 <= 0 || stride0%8 != 0 {
+		return fmt.Errorf("bad stride %d", stride0)
+	}
+	if stride1 <= 0 || stride1%8 != 0 {
+		return fmt.Errorf("bad stride %d", stride1)
+	}
+	// Compare the two pix data, one 8x8 block at a time.
+	for y := 0; y < len(pix0)/stride0 && y < len(pix1)/stride1; y += 8 {
+		for x := 0; x < stride0 && x < stride1; x += 8 {
+			if x >= bounds.Max.X || y >= bounds.Max.Y {
+				// We don't care if the two pix data differ if the 8x8 block is
+				// entirely outside of the image's bounds. For example, this can
+				// occur with a 4:2:0 chroma subsampling and a 1x1 image. Baseline
+				// decoding works on the one 16x16 MCU as a whole; progressive
+				// decoding's first pass works on that 16x16 MCU as a whole but
+				// refinement passes only process one 8x8 block within the MCU.
+				continue
+			}
+
+			for j := 0; j < 8; j++ {
+				for i := 0; i < 8; i++ {
+					index0 := (y+j)*stride0 + (x + i)
+					index1 := (y+j)*stride1 + (x + i)
+					if pix0[index0] != pix1[index1] {
+						return fmt.Errorf("blocks at (%d, %d) differ:\n%sand\n%s", x, y,
+							pixString(pix0, stride0, x, y),
+							pixString(pix1, stride1, x, y),
+						)
+					}
+				}
+			}
+		}
+	}
+	return nil
+}
+
+func pixString(pix []byte, stride, x, y int) string {
+	s := bytes.NewBuffer(nil)
+	for j := 0; j < 8; j++ {
+		fmt.Fprintf(s, "\t")
+		for i := 0; i < 8; i++ {
+			fmt.Fprintf(s, "%02x ", pix[(y+j)*stride+(x+i)])
+		}
+		fmt.Fprintf(s, "\n")
+	}
+	return s.String()
+}
+
+func TestExtraneousData(t *testing.T) {
+	// Encode a 1x1 red image.
+	src := image.NewRGBA(image.Rect(0, 0, 1, 1))
+	src.Set(0, 0, color.RGBA{0xff, 0x00, 0x00, 0xff})
+	buf := new(bytes.Buffer)
+	if err := Encode(buf, src, nil); err != nil {
+		t.Fatalf("encode: %v", err)
+	}
+	enc := buf.String()
+	// Sanity check that the encoded JPEG is long enough, that it ends in a
+	// "\xff\xd9" EOI marker, and that it contains a "\xff\xda" SOS marker
+	// somewhere in the final 64 bytes.
+	if len(enc) < 64 {
+		t.Fatalf("encoded JPEG is too short: %d bytes", len(enc))
+	}
+	if got, want := enc[len(enc)-2:], "\xff\xd9"; got != want {
+		t.Fatalf("encoded JPEG ends with %q, want %q", got, want)
+	}
+	if s := enc[len(enc)-64:]; !strings.Contains(s, "\xff\xda") {
+		t.Fatalf("encoded JPEG does not contain a SOS marker (ff da) near the end: % x", s)
+	}
+	// Test that adding some random junk between the SOS marker and the
+	// EOI marker does not affect the decoding.
+	rnd := rand.New(rand.NewSource(1))
+	for i, nerr := 0, 0; i < 1000 && nerr < 10; i++ {
+		buf.Reset()
+		// Write all but the trailing "\xff\xd9" EOI marker.
+		buf.WriteString(enc[:len(enc)-2])
+		// Write some random extraneous data.
+		for n := rnd.Intn(10); n > 0; n-- {
+			if x := byte(rnd.Intn(256)); x != 0xff {
+				buf.WriteByte(x)
+			} else {
+				// The JPEG format escapes a SOS 0xff data byte as "\xff\x00".
+				buf.WriteString("\xff\x00")
+			}
+		}
+		// Write the "\xff\xd9" EOI marker.
+		buf.WriteString("\xff\xd9")
+
+		// Check that we can still decode the resultant image.
+		got, err := Decode(buf)
+		if err != nil {
+			t.Errorf("could not decode image #%d: %v", i, err)
+			nerr++
+			continue
+		}
+		if got.Bounds() != src.Bounds() {
+			t.Errorf("image #%d, bounds differ: %v and %v", i, got.Bounds(), src.Bounds())
+			nerr++
+			continue
+		}
+		if averageDelta(got, src) > 2<<8 {
+			t.Errorf("image #%d changed too much after a round trip", i)
+			nerr++
+			continue
+		}
+	}
+}
+
+func benchmarkDecode(b *testing.B, filename string) {
+	b.StopTimer()
+	data, err := ioutil.ReadFile(filename)
+	if err != nil {
+		b.Fatal(err)
+	}
+	cfg, err := DecodeConfig(bytes.NewReader(data))
+	if err != nil {
+		b.Fatal(err)
+	}
+	b.SetBytes(int64(cfg.Width * cfg.Height * 4))
+	b.StartTimer()
+	for i := 0; i < b.N; i++ {
+		Decode(bytes.NewReader(data))
+	}
+}
+
+func BenchmarkDecodeBaseline(b *testing.B) {
+	benchmarkDecode(b, "../testdata/video-001.jpeg")
+}
+
+func BenchmarkDecodeProgressive(b *testing.B) {
+	benchmarkDecode(b, "../testdata/video-001.progressive.jpeg")
+}
diff --git a/src/image/jpeg/scan.go b/src/image/jpeg/scan.go
new file mode 100644
index 0000000..2bd1d9d
--- /dev/null
+++ b/src/image/jpeg/scan.go
@@ -0,0 +1,442 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package jpeg
+
+import (
+	"image"
+)
+
+// makeImg allocates and initializes the destination image.
+func (d *decoder) makeImg(h0, v0, mxx, myy int) {
+	if d.nComp == nGrayComponent {
+		m := image.NewGray(image.Rect(0, 0, 8*mxx, 8*myy))
+		d.img1 = m.SubImage(image.Rect(0, 0, d.width, d.height)).(*image.Gray)
+		return
+	}
+	var subsampleRatio image.YCbCrSubsampleRatio
+	switch {
+	case h0 == 1 && v0 == 1:
+		subsampleRatio = image.YCbCrSubsampleRatio444
+	case h0 == 1 && v0 == 2:
+		subsampleRatio = image.YCbCrSubsampleRatio440
+	case h0 == 2 && v0 == 1:
+		subsampleRatio = image.YCbCrSubsampleRatio422
+	case h0 == 2 && v0 == 2:
+		subsampleRatio = image.YCbCrSubsampleRatio420
+	default:
+		panic("unreachable")
+	}
+	m := image.NewYCbCr(image.Rect(0, 0, 8*h0*mxx, 8*v0*myy), subsampleRatio)
+	d.img3 = m.SubImage(image.Rect(0, 0, d.width, d.height)).(*image.YCbCr)
+}
+
+// Specified in section B.2.3.
+func (d *decoder) processSOS(n int) error {
+	if d.nComp == 0 {
+		return FormatError("missing SOF marker")
+	}
+	if n < 6 || 4+2*d.nComp < n || n%2 != 0 {
+		return FormatError("SOS has wrong length")
+	}
+	if err := d.readFull(d.tmp[:n]); err != nil {
+		return err
+	}
+	nComp := int(d.tmp[0])
+	if n != 4+2*nComp {
+		return FormatError("SOS length inconsistent with number of components")
+	}
+	var scan [nColorComponent]struct {
+		compIndex uint8
+		td        uint8 // DC table selector.
+		ta        uint8 // AC table selector.
+	}
+	for i := 0; i < nComp; i++ {
+		cs := d.tmp[1+2*i] // Component selector.
+		compIndex := -1
+		for j, comp := range d.comp {
+			if cs == comp.c {
+				compIndex = j
+			}
+		}
+		if compIndex < 0 {
+			return FormatError("unknown component selector")
+		}
+		scan[i].compIndex = uint8(compIndex)
+		scan[i].td = d.tmp[2+2*i] >> 4
+		if scan[i].td > maxTh {
+			return FormatError("bad Td value")
+		}
+		scan[i].ta = d.tmp[2+2*i] & 0x0f
+		if scan[i].ta > maxTh {
+			return FormatError("bad Ta value")
+		}
+	}
+
+	// zigStart and zigEnd are the spectral selection bounds.
+	// ah and al are the successive approximation high and low values.
+	// The spec calls these values Ss, Se, Ah and Al.
+	//
+	// For progressive JPEGs, these are the two more-or-less independent
+	// aspects of progression. Spectral selection progression is when not
+	// all of a block's 64 DCT coefficients are transmitted in one pass.
+	// For example, three passes could transmit coefficient 0 (the DC
+	// component), coefficients 1-5, and coefficients 6-63, in zig-zag
+	// order. Successive approximation is when not all of the bits of a
+	// band of coefficients are transmitted in one pass. For example,
+	// three passes could transmit the 6 most significant bits, followed
+	// by the second-least significant bit, followed by the least
+	// significant bit.
+	//
+	// For baseline JPEGs, these parameters are hard-coded to 0/63/0/0.
+	zigStart, zigEnd, ah, al := int32(0), int32(blockSize-1), uint32(0), uint32(0)
+	if d.progressive {
+		zigStart = int32(d.tmp[1+2*nComp])
+		zigEnd = int32(d.tmp[2+2*nComp])
+		ah = uint32(d.tmp[3+2*nComp] >> 4)
+		al = uint32(d.tmp[3+2*nComp] & 0x0f)
+		if (zigStart == 0 && zigEnd != 0) || zigStart > zigEnd || blockSize <= zigEnd {
+			return FormatError("bad spectral selection bounds")
+		}
+		if zigStart != 0 && nComp != 1 {
+			return FormatError("progressive AC coefficients for more than one component")
+		}
+		if ah != 0 && ah != al+1 {
+			return FormatError("bad successive approximation values")
+		}
+	}
+
+	// mxx and myy are the number of MCUs (Minimum Coded Units) in the image.
+	h0, v0 := d.comp[0].h, d.comp[0].v // The h and v values from the Y components.
+	mxx := (d.width + 8*h0 - 1) / (8 * h0)
+	myy := (d.height + 8*v0 - 1) / (8 * v0)
+	if d.img1 == nil && d.img3 == nil {
+		d.makeImg(h0, v0, mxx, myy)
+	}
+	if d.progressive {
+		for i := 0; i < nComp; i++ {
+			compIndex := scan[i].compIndex
+			if d.progCoeffs[compIndex] == nil {
+				d.progCoeffs[compIndex] = make([]block, mxx*myy*d.comp[compIndex].h*d.comp[compIndex].v)
+			}
+		}
+	}
+
+	d.bits = bits{}
+	mcu, expectedRST := 0, uint8(rst0Marker)
+	var (
+		// b is the decoded coefficients, in natural (not zig-zag) order.
+		b  block
+		dc [nColorComponent]int32
+		// bx and by are the location of the current (in terms of 8x8 blocks).
+		// For example, with 4:2:0 chroma subsampling, the block whose top left
+		// pixel co-ordinates are (16, 8) is the third block in the first row:
+		// bx is 2 and by is 0, even though the pixel is in the second MCU.
+		bx, by     int
+		blockCount int
+	)
+	for my := 0; my < myy; my++ {
+		for mx := 0; mx < mxx; mx++ {
+			for i := 0; i < nComp; i++ {
+				compIndex := scan[i].compIndex
+				qt := &d.quant[d.comp[compIndex].tq]
+				for j := 0; j < d.comp[compIndex].h*d.comp[compIndex].v; j++ {
+					// The blocks are traversed one MCU at a time. For 4:2:0 chroma
+					// subsampling, there are four Y 8x8 blocks in every 16x16 MCU.
+					//
+					// For a baseline 32x16 pixel image, the Y blocks visiting order is:
+					//	0 1 4 5
+					//	2 3 6 7
+					//
+					// For progressive images, the interleaved scans (those with nComp > 1)
+					// are traversed as above, but non-interleaved scans are traversed left
+					// to right, top to bottom:
+					//	0 1 2 3
+					//	4 5 6 7
+					// Only DC scans (zigStart == 0) can be interleaved. AC scans must have
+					// only one component.
+					//
+					// To further complicate matters, for non-interleaved scans, there is no
+					// data for any blocks that are inside the image at the MCU level but
+					// outside the image at the pixel level. For example, a 24x16 pixel 4:2:0
+					// progressive image consists of two 16x16 MCUs. The interleaved scans
+					// will process 8 Y blocks:
+					//	0 1 4 5
+					//	2 3 6 7
+					// The non-interleaved scans will process only 6 Y blocks:
+					//	0 1 2
+					//	3 4 5
+					if nComp != 1 {
+						bx, by = d.comp[compIndex].h*mx, d.comp[compIndex].v*my
+						if h0 == 1 {
+							by += j
+						} else {
+							bx += j % 2
+							by += j / 2
+						}
+					} else {
+						q := mxx * d.comp[compIndex].h
+						bx = blockCount % q
+						by = blockCount / q
+						blockCount++
+						if bx*8 >= d.width || by*8 >= d.height {
+							continue
+						}
+					}
+
+					// Load the previous partially decoded coefficients, if applicable.
+					if d.progressive {
+						b = d.progCoeffs[compIndex][by*mxx*d.comp[compIndex].h+bx]
+					} else {
+						b = block{}
+					}
+
+					if ah != 0 {
+						if err := d.refine(&b, &d.huff[acTable][scan[i].ta], zigStart, zigEnd, 1<<al); err != nil {
+							return err
+						}
+					} else {
+						zig := zigStart
+						if zig == 0 {
+							zig++
+							// Decode the DC coefficient, as specified in section F.2.2.1.
+							value, err := d.decodeHuffman(&d.huff[dcTable][scan[i].td])
+							if err != nil {
+								return err
+							}
+							if value > 16 {
+								return UnsupportedError("excessive DC component")
+							}
+							dcDelta, err := d.receiveExtend(value)
+							if err != nil {
+								return err
+							}
+							dc[compIndex] += dcDelta
+							b[0] = dc[compIndex] << al
+						}
+
+						if zig <= zigEnd && d.eobRun > 0 {
+							d.eobRun--
+						} else {
+							// Decode the AC coefficients, as specified in section F.2.2.2.
+							huff := &d.huff[acTable][scan[i].ta]
+							for ; zig <= zigEnd; zig++ {
+								value, err := d.decodeHuffman(huff)
+								if err != nil {
+									return err
+								}
+								val0 := value >> 4
+								val1 := value & 0x0f
+								if val1 != 0 {
+									zig += int32(val0)
+									if zig > zigEnd {
+										break
+									}
+									ac, err := d.receiveExtend(val1)
+									if err != nil {
+										return err
+									}
+									b[unzig[zig]] = ac << al
+								} else {
+									if val0 != 0x0f {
+										d.eobRun = uint16(1 << val0)
+										if val0 != 0 {
+											bits, err := d.decodeBits(int32(val0))
+											if err != nil {
+												return err
+											}
+											d.eobRun |= uint16(bits)
+										}
+										d.eobRun--
+										break
+									}
+									zig += 0x0f
+								}
+							}
+						}
+					}
+
+					if d.progressive {
+						if zigEnd != blockSize-1 || al != 0 {
+							// We haven't completely decoded this 8x8 block. Save the coefficients.
+							d.progCoeffs[compIndex][by*mxx*d.comp[compIndex].h+bx] = b
+							// At this point, we could execute the rest of the loop body to dequantize and
+							// perform the inverse DCT, to save early stages of a progressive image to the
+							// *image.YCbCr buffers (the whole point of progressive encoding), but in Go,
+							// the jpeg.Decode function does not return until the entire image is decoded,
+							// so we "continue" here to avoid wasted computation.
+							continue
+						}
+					}
+
+					// Dequantize, perform the inverse DCT and store the block to the image.
+					for zig := 0; zig < blockSize; zig++ {
+						b[unzig[zig]] *= qt[zig]
+					}
+					idct(&b)
+					dst, stride := []byte(nil), 0
+					if d.nComp == nGrayComponent {
+						dst, stride = d.img1.Pix[8*(by*d.img1.Stride+bx):], d.img1.Stride
+					} else {
+						switch compIndex {
+						case 0:
+							dst, stride = d.img3.Y[8*(by*d.img3.YStride+bx):], d.img3.YStride
+						case 1:
+							dst, stride = d.img3.Cb[8*(by*d.img3.CStride+bx):], d.img3.CStride
+						case 2:
+							dst, stride = d.img3.Cr[8*(by*d.img3.CStride+bx):], d.img3.CStride
+						default:
+							return UnsupportedError("too many components")
+						}
+					}
+					// Level shift by +128, clip to [0, 255], and write to dst.
+					for y := 0; y < 8; y++ {
+						y8 := y * 8
+						yStride := y * stride
+						for x := 0; x < 8; x++ {
+							c := b[y8+x]
+							if c < -128 {
+								c = 0
+							} else if c > 127 {
+								c = 255
+							} else {
+								c += 128
+							}
+							dst[yStride+x] = uint8(c)
+						}
+					}
+				} // for j
+			} // for i
+			mcu++
+			if d.ri > 0 && mcu%d.ri == 0 && mcu < mxx*myy {
+				// A more sophisticated decoder could use RST[0-7] markers to resynchronize from corrupt input,
+				// but this one assumes well-formed input, and hence the restart marker follows immediately.
+				if err := d.readFull(d.tmp[:2]); err != nil {
+					return err
+				}
+				if d.tmp[0] != 0xff || d.tmp[1] != expectedRST {
+					return FormatError("bad RST marker")
+				}
+				expectedRST++
+				if expectedRST == rst7Marker+1 {
+					expectedRST = rst0Marker
+				}
+				// Reset the Huffman decoder.
+				d.bits = bits{}
+				// Reset the DC components, as per section F.2.1.3.1.
+				dc = [nColorComponent]int32{}
+				// Reset the progressive decoder state, as per section G.1.2.2.
+				d.eobRun = 0
+			}
+		} // for mx
+	} // for my
+
+	return nil
+}
+
+// refine decodes a successive approximation refinement block, as specified in
+// section G.1.2.
+func (d *decoder) refine(b *block, h *huffman, zigStart, zigEnd, delta int32) error {
+	// Refining a DC component is trivial.
+	if zigStart == 0 {
+		if zigEnd != 0 {
+			panic("unreachable")
+		}
+		bit, err := d.decodeBit()
+		if err != nil {
+			return err
+		}
+		if bit {
+			b[0] |= delta
+		}
+		return nil
+	}
+
+	// Refining AC components is more complicated; see sections G.1.2.2 and G.1.2.3.
+	zig := zigStart
+	if d.eobRun == 0 {
+	loop:
+		for ; zig <= zigEnd; zig++ {
+			z := int32(0)
+			value, err := d.decodeHuffman(h)
+			if err != nil {
+				return err
+			}
+			val0 := value >> 4
+			val1 := value & 0x0f
+
+			switch val1 {
+			case 0:
+				if val0 != 0x0f {
+					d.eobRun = uint16(1 << val0)
+					if val0 != 0 {
+						bits, err := d.decodeBits(int32(val0))
+						if err != nil {
+							return err
+						}
+						d.eobRun |= uint16(bits)
+					}
+					break loop
+				}
+			case 1:
+				z = delta
+				bit, err := d.decodeBit()
+				if err != nil {
+					return err
+				}
+				if !bit {
+					z = -z
+				}
+			default:
+				return FormatError("unexpected Huffman code")
+			}
+
+			zig, err = d.refineNonZeroes(b, zig, zigEnd, int32(val0), delta)
+			if err != nil {
+				return err
+			}
+			if zig > zigEnd {
+				return FormatError("too many coefficients")
+			}
+			if z != 0 {
+				b[unzig[zig]] = z
+			}
+		}
+	}
+	if d.eobRun > 0 {
+		d.eobRun--
+		if _, err := d.refineNonZeroes(b, zig, zigEnd, -1, delta); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+// refineNonZeroes refines non-zero entries of b in zig-zag order. If nz >= 0,
+// the first nz zero entries are skipped over.
+func (d *decoder) refineNonZeroes(b *block, zig, zigEnd, nz, delta int32) (int32, error) {
+	for ; zig <= zigEnd; zig++ {
+		u := unzig[zig]
+		if b[u] == 0 {
+			if nz == 0 {
+				break
+			}
+			nz--
+			continue
+		}
+		bit, err := d.decodeBit()
+		if err != nil {
+			return 0, err
+		}
+		if !bit {
+			continue
+		}
+		if b[u] >= 0 {
+			b[u] += delta
+		} else {
+			b[u] -= delta
+		}
+	}
+	return zig, nil
+}
diff --git a/src/image/jpeg/writer.go b/src/image/jpeg/writer.go
new file mode 100644
index 0000000..91bbde3
--- /dev/null
+++ b/src/image/jpeg/writer.go
@@ -0,0 +1,614 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package jpeg
+
+import (
+	"bufio"
+	"errors"
+	"image"
+	"image/color"
+	"io"
+)
+
+// min returns the minimum of two integers.
+func min(x, y int) int {
+	if x < y {
+		return x
+	}
+	return y
+}
+
+// div returns a/b rounded to the nearest integer, instead of rounded to zero.
+func div(a, b int32) int32 {
+	if a >= 0 {
+		return (a + (b >> 1)) / b
+	}
+	return -((-a + (b >> 1)) / b)
+}
+
+// bitCount counts the number of bits needed to hold an integer.
+var bitCount = [256]byte{
+	0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
+	5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+	6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+	6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+	7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+	7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+	7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+	7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+	8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+	8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+	8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+	8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+	8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+	8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+	8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+	8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+}
+
+type quantIndex int
+
+const (
+	quantIndexLuminance quantIndex = iota
+	quantIndexChrominance
+	nQuantIndex
+)
+
+// unscaledQuant are the unscaled quantization tables in zig-zag order. Each
+// encoder copies and scales the tables according to its quality parameter.
+// The values are derived from section K.1 after converting from natural to
+// zig-zag order.
+var unscaledQuant = [nQuantIndex][blockSize]byte{
+	// Luminance.
+	{
+		16, 11, 12, 14, 12, 10, 16, 14,
+		13, 14, 18, 17, 16, 19, 24, 40,
+		26, 24, 22, 22, 24, 49, 35, 37,
+		29, 40, 58, 51, 61, 60, 57, 51,
+		56, 55, 64, 72, 92, 78, 64, 68,
+		87, 69, 55, 56, 80, 109, 81, 87,
+		95, 98, 103, 104, 103, 62, 77, 113,
+		121, 112, 100, 120, 92, 101, 103, 99,
+	},
+	// Chrominance.
+	{
+		17, 18, 18, 24, 21, 24, 47, 26,
+		26, 47, 99, 66, 56, 66, 99, 99,
+		99, 99, 99, 99, 99, 99, 99, 99,
+		99, 99, 99, 99, 99, 99, 99, 99,
+		99, 99, 99, 99, 99, 99, 99, 99,
+		99, 99, 99, 99, 99, 99, 99, 99,
+		99, 99, 99, 99, 99, 99, 99, 99,
+		99, 99, 99, 99, 99, 99, 99, 99,
+	},
+}
+
+type huffIndex int
+
+const (
+	huffIndexLuminanceDC huffIndex = iota
+	huffIndexLuminanceAC
+	huffIndexChrominanceDC
+	huffIndexChrominanceAC
+	nHuffIndex
+)
+
+// huffmanSpec specifies a Huffman encoding.
+type huffmanSpec struct {
+	// count[i] is the number of codes of length i bits.
+	count [16]byte
+	// value[i] is the decoded value of the i'th codeword.
+	value []byte
+}
+
+// theHuffmanSpec is the Huffman encoding specifications.
+// This encoder uses the same Huffman encoding for all images.
+var theHuffmanSpec = [nHuffIndex]huffmanSpec{
+	// Luminance DC.
+	{
+		[16]byte{0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0},
+		[]byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11},
+	},
+	// Luminance AC.
+	{
+		[16]byte{0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 125},
+		[]byte{
+			0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
+			0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
+			0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
+			0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
+			0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
+			0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
+			0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+			0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
+			0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
+			0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
+			0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
+			0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
+			0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
+			0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
+			0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
+			0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
+			0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
+			0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
+			0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
+			0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
+			0xf9, 0xfa,
+		},
+	},
+	// Chrominance DC.
+	{
+		[16]byte{0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0},
+		[]byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11},
+	},
+	// Chrominance AC.
+	{
+		[16]byte{0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 119},
+		[]byte{
+			0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
+			0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
+			0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
+			0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
+			0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,
+			0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
+			0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
+			0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
+			0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
+			0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
+			0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
+			0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+			0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
+			0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
+			0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
+			0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
+			0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
+			0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
+			0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
+			0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
+			0xf9, 0xfa,
+		},
+	},
+}
+
+// huffmanLUT is a compiled look-up table representation of a huffmanSpec.
+// Each value maps to a uint32 of which the 8 most significant bits hold the
+// codeword size in bits and the 24 least significant bits hold the codeword.
+// The maximum codeword size is 16 bits.
+type huffmanLUT []uint32
+
+func (h *huffmanLUT) init(s huffmanSpec) {
+	maxValue := 0
+	for _, v := range s.value {
+		if int(v) > maxValue {
+			maxValue = int(v)
+		}
+	}
+	*h = make([]uint32, maxValue+1)
+	code, k := uint32(0), 0
+	for i := 0; i < len(s.count); i++ {
+		nBits := uint32(i+1) << 24
+		for j := uint8(0); j < s.count[i]; j++ {
+			(*h)[s.value[k]] = nBits | code
+			code++
+			k++
+		}
+		code <<= 1
+	}
+}
+
+// theHuffmanLUT are compiled representations of theHuffmanSpec.
+var theHuffmanLUT [4]huffmanLUT
+
+func init() {
+	for i, s := range theHuffmanSpec {
+		theHuffmanLUT[i].init(s)
+	}
+}
+
+// writer is a buffered writer.
+type writer interface {
+	Flush() error
+	io.Writer
+	io.ByteWriter
+}
+
+// encoder encodes an image to the JPEG format.
+type encoder struct {
+	// w is the writer to write to. err is the first error encountered during
+	// writing. All attempted writes after the first error become no-ops.
+	w   writer
+	err error
+	// buf is a scratch buffer.
+	buf [16]byte
+	// bits and nBits are accumulated bits to write to w.
+	bits, nBits uint32
+	// quant is the scaled quantization tables, in zig-zag order.
+	quant [nQuantIndex][blockSize]byte
+}
+
+func (e *encoder) flush() {
+	if e.err != nil {
+		return
+	}
+	e.err = e.w.Flush()
+}
+
+func (e *encoder) write(p []byte) {
+	if e.err != nil {
+		return
+	}
+	_, e.err = e.w.Write(p)
+}
+
+func (e *encoder) writeByte(b byte) {
+	if e.err != nil {
+		return
+	}
+	e.err = e.w.WriteByte(b)
+}
+
+// emit emits the least significant nBits bits of bits to the bit-stream.
+// The precondition is bits < 1<<nBits && nBits <= 16.
+func (e *encoder) emit(bits, nBits uint32) {
+	nBits += e.nBits
+	bits <<= 32 - nBits
+	bits |= e.bits
+	for nBits >= 8 {
+		b := uint8(bits >> 24)
+		e.writeByte(b)
+		if b == 0xff {
+			e.writeByte(0x00)
+		}
+		bits <<= 8
+		nBits -= 8
+	}
+	e.bits, e.nBits = bits, nBits
+}
+
+// emitHuff emits the given value with the given Huffman encoder.
+func (e *encoder) emitHuff(h huffIndex, value int32) {
+	x := theHuffmanLUT[h][value]
+	e.emit(x&(1<<24-1), x>>24)
+}
+
+// emitHuffRLE emits a run of runLength copies of value encoded with the given
+// Huffman encoder.
+func (e *encoder) emitHuffRLE(h huffIndex, runLength, value int32) {
+	a, b := value, value
+	if a < 0 {
+		a, b = -value, value-1
+	}
+	var nBits uint32
+	if a < 0x100 {
+		nBits = uint32(bitCount[a])
+	} else {
+		nBits = 8 + uint32(bitCount[a>>8])
+	}
+	e.emitHuff(h, runLength<<4|int32(nBits))
+	if nBits > 0 {
+		e.emit(uint32(b)&(1<<nBits-1), nBits)
+	}
+}
+
+// writeMarkerHeader writes the header for a marker with the given length.
+func (e *encoder) writeMarkerHeader(marker uint8, markerlen int) {
+	e.buf[0] = 0xff
+	e.buf[1] = marker
+	e.buf[2] = uint8(markerlen >> 8)
+	e.buf[3] = uint8(markerlen & 0xff)
+	e.write(e.buf[:4])
+}
+
+// writeDQT writes the Define Quantization Table marker.
+func (e *encoder) writeDQT() {
+	const markerlen = 2 + int(nQuantIndex)*(1+blockSize)
+	e.writeMarkerHeader(dqtMarker, markerlen)
+	for i := range e.quant {
+		e.writeByte(uint8(i))
+		e.write(e.quant[i][:])
+	}
+}
+
+// writeSOF0 writes the Start Of Frame (Baseline) marker.
+func (e *encoder) writeSOF0(size image.Point, nComponent int) {
+	markerlen := 8 + 3*nComponent
+	e.writeMarkerHeader(sof0Marker, markerlen)
+	e.buf[0] = 8 // 8-bit color.
+	e.buf[1] = uint8(size.Y >> 8)
+	e.buf[2] = uint8(size.Y & 0xff)
+	e.buf[3] = uint8(size.X >> 8)
+	e.buf[4] = uint8(size.X & 0xff)
+	e.buf[5] = uint8(nComponent)
+	if nComponent == 1 {
+		e.buf[6] = 1
+		// No subsampling for grayscale image.
+		e.buf[7] = 0x11
+		e.buf[8] = 0x00
+	} else {
+		for i := 0; i < nComponent; i++ {
+			e.buf[3*i+6] = uint8(i + 1)
+			// We use 4:2:0 chroma subsampling.
+			e.buf[3*i+7] = "\x22\x11\x11"[i]
+			e.buf[3*i+8] = "\x00\x01\x01"[i]
+		}
+	}
+	e.write(e.buf[:3*(nComponent-1)+9])
+}
+
+// writeDHT writes the Define Huffman Table marker.
+func (e *encoder) writeDHT(nComponent int) {
+	markerlen := 2
+	specs := theHuffmanSpec[:]
+	if nComponent == 1 {
+		// Drop the Chrominance tables.
+		specs = specs[:2]
+	}
+	for _, s := range specs {
+		markerlen += 1 + 16 + len(s.value)
+	}
+	e.writeMarkerHeader(dhtMarker, markerlen)
+	for i, s := range specs {
+		e.writeByte("\x00\x10\x01\x11"[i])
+		e.write(s.count[:])
+		e.write(s.value)
+	}
+}
+
+// writeBlock writes a block of pixel data using the given quantization table,
+// returning the post-quantized DC value of the DCT-transformed block. b is in
+// natural (not zig-zag) order.
+func (e *encoder) writeBlock(b *block, q quantIndex, prevDC int32) int32 {
+	fdct(b)
+	// Emit the DC delta.
+	dc := div(b[0], 8*int32(e.quant[q][0]))
+	e.emitHuffRLE(huffIndex(2*q+0), 0, dc-prevDC)
+	// Emit the AC components.
+	h, runLength := huffIndex(2*q+1), int32(0)
+	for zig := 1; zig < blockSize; zig++ {
+		ac := div(b[unzig[zig]], 8*int32(e.quant[q][zig]))
+		if ac == 0 {
+			runLength++
+		} else {
+			for runLength > 15 {
+				e.emitHuff(h, 0xf0)
+				runLength -= 16
+			}
+			e.emitHuffRLE(h, runLength, ac)
+			runLength = 0
+		}
+	}
+	if runLength > 0 {
+		e.emitHuff(h, 0x00)
+	}
+	return dc
+}
+
+// toYCbCr converts the 8x8 region of m whose top-left corner is p to its
+// YCbCr values.
+func toYCbCr(m image.Image, p image.Point, yBlock, cbBlock, crBlock *block) {
+	b := m.Bounds()
+	xmax := b.Max.X - 1
+	ymax := b.Max.Y - 1
+	for j := 0; j < 8; j++ {
+		for i := 0; i < 8; i++ {
+			r, g, b, _ := m.At(min(p.X+i, xmax), min(p.Y+j, ymax)).RGBA()
+			yy, cb, cr := color.RGBToYCbCr(uint8(r>>8), uint8(g>>8), uint8(b>>8))
+			yBlock[8*j+i] = int32(yy)
+			cbBlock[8*j+i] = int32(cb)
+			crBlock[8*j+i] = int32(cr)
+		}
+	}
+}
+
+// grayToY stores the 8x8 region of m whose top-left corner is p in yBlock.
+func grayToY(m *image.Gray, p image.Point, yBlock *block) {
+	b := m.Bounds()
+	xmax := b.Max.X - 1
+	ymax := b.Max.Y - 1
+	pix := m.Pix
+	for j := 0; j < 8; j++ {
+		for i := 0; i < 8; i++ {
+			idx := m.PixOffset(min(p.X+i, xmax), min(p.Y+j, ymax))
+			yBlock[8*j+i] = int32(pix[idx])
+		}
+	}
+}
+
+// rgbaToYCbCr is a specialized version of toYCbCr for image.RGBA images.
+func rgbaToYCbCr(m *image.RGBA, p image.Point, yBlock, cbBlock, crBlock *block) {
+	b := m.Bounds()
+	xmax := b.Max.X - 1
+	ymax := b.Max.Y - 1
+	for j := 0; j < 8; j++ {
+		sj := p.Y + j
+		if sj > ymax {
+			sj = ymax
+		}
+		offset := (sj-b.Min.Y)*m.Stride - b.Min.X*4
+		for i := 0; i < 8; i++ {
+			sx := p.X + i
+			if sx > xmax {
+				sx = xmax
+			}
+			pix := m.Pix[offset+sx*4:]
+			yy, cb, cr := color.RGBToYCbCr(pix[0], pix[1], pix[2])
+			yBlock[8*j+i] = int32(yy)
+			cbBlock[8*j+i] = int32(cb)
+			crBlock[8*j+i] = int32(cr)
+		}
+	}
+}
+
+// scale scales the 16x16 region represented by the 4 src blocks to the 8x8
+// dst block.
+func scale(dst *block, src *[4]block) {
+	for i := 0; i < 4; i++ {
+		dstOff := (i&2)<<4 | (i&1)<<2
+		for y := 0; y < 4; y++ {
+			for x := 0; x < 4; x++ {
+				j := 16*y + 2*x
+				sum := src[i][j] + src[i][j+1] + src[i][j+8] + src[i][j+9]
+				dst[8*y+x+dstOff] = (sum + 2) >> 2
+			}
+		}
+	}
+}
+
+// sosHeaderY is the SOS marker "\xff\xda" followed by 8 bytes:
+//	- the marker length "\x00\x08",
+//	- the number of components "\x01",
+//	- component 1 uses DC table 0 and AC table 0 "\x01\x00",
+//	- the bytes "\x00\x3f\x00". Section B.2.3 of the spec says that for
+//	  sequential DCTs, those bytes (8-bit Ss, 8-bit Se, 4-bit Ah, 4-bit Al)
+//	  should be 0x00, 0x3f, 0x00<<4 | 0x00.
+var sosHeaderY = []byte{
+	0xff, 0xda, 0x00, 0x08, 0x01, 0x01, 0x00, 0x00, 0x3f, 0x00,
+}
+
+// sosHeaderYCbCr is the SOS marker "\xff\xda" followed by 12 bytes:
+//	- the marker length "\x00\x0c",
+//	- the number of components "\x03",
+//	- component 1 uses DC table 0 and AC table 0 "\x01\x00",
+//	- component 2 uses DC table 1 and AC table 1 "\x02\x11",
+//	- component 3 uses DC table 1 and AC table 1 "\x03\x11",
+//	- the bytes "\x00\x3f\x00". Section B.2.3 of the spec says that for
+//	  sequential DCTs, those bytes (8-bit Ss, 8-bit Se, 4-bit Ah, 4-bit Al)
+//	  should be 0x00, 0x3f, 0x00<<4 | 0x00.
+var sosHeaderYCbCr = []byte{
+	0xff, 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02,
+	0x11, 0x03, 0x11, 0x00, 0x3f, 0x00,
+}
+
+// writeSOS writes the StartOfScan marker.
+func (e *encoder) writeSOS(m image.Image) {
+	switch m.(type) {
+	case *image.Gray:
+		e.write(sosHeaderY)
+	default:
+		e.write(sosHeaderYCbCr)
+	}
+	var (
+		// Scratch buffers to hold the YCbCr values.
+		// The blocks are in natural (not zig-zag) order.
+		b      block
+		cb, cr [4]block
+		// DC components are delta-encoded.
+		prevDCY, prevDCCb, prevDCCr int32
+	)
+	bounds := m.Bounds()
+	switch m := m.(type) {
+	// TODO(wathiede): switch on m.ColorModel() instead of type.
+	case *image.Gray:
+		for y := bounds.Min.Y; y < bounds.Max.Y; y += 8 {
+			for x := bounds.Min.X; x < bounds.Max.X; x += 8 {
+				p := image.Pt(x, y)
+				grayToY(m, p, &b)
+				prevDCY = e.writeBlock(&b, 0, prevDCY)
+			}
+		}
+	default:
+		rgba, _ := m.(*image.RGBA)
+		for y := bounds.Min.Y; y < bounds.Max.Y; y += 16 {
+			for x := bounds.Min.X; x < bounds.Max.X; x += 16 {
+				for i := 0; i < 4; i++ {
+					xOff := (i & 1) * 8
+					yOff := (i & 2) * 4
+					p := image.Pt(x+xOff, y+yOff)
+					if rgba != nil {
+						rgbaToYCbCr(rgba, p, &b, &cb[i], &cr[i])
+					} else {
+						toYCbCr(m, p, &b, &cb[i], &cr[i])
+					}
+					prevDCY = e.writeBlock(&b, 0, prevDCY)
+				}
+				scale(&b, &cb)
+				prevDCCb = e.writeBlock(&b, 1, prevDCCb)
+				scale(&b, &cr)
+				prevDCCr = e.writeBlock(&b, 1, prevDCCr)
+			}
+		}
+	}
+	// Pad the last byte with 1's.
+	e.emit(0x7f, 7)
+}
+
+// DefaultQuality is the default quality encoding parameter.
+const DefaultQuality = 75
+
+// Options are the encoding parameters.
+// Quality ranges from 1 to 100 inclusive, higher is better.
+type Options struct {
+	Quality int
+}
+
+// Encode writes the Image m to w in JPEG 4:2:0 baseline format with the given
+// options. Default parameters are used if a nil *Options is passed.
+func Encode(w io.Writer, m image.Image, o *Options) error {
+	b := m.Bounds()
+	if b.Dx() >= 1<<16 || b.Dy() >= 1<<16 {
+		return errors.New("jpeg: image is too large to encode")
+	}
+	var e encoder
+	if ww, ok := w.(writer); ok {
+		e.w = ww
+	} else {
+		e.w = bufio.NewWriter(w)
+	}
+	// Clip quality to [1, 100].
+	quality := DefaultQuality
+	if o != nil {
+		quality = o.Quality
+		if quality < 1 {
+			quality = 1
+		} else if quality > 100 {
+			quality = 100
+		}
+	}
+	// Convert from a quality rating to a scaling factor.
+	var scale int
+	if quality < 50 {
+		scale = 5000 / quality
+	} else {
+		scale = 200 - quality*2
+	}
+	// Initialize the quantization tables.
+	for i := range e.quant {
+		for j := range e.quant[i] {
+			x := int(unscaledQuant[i][j])
+			x = (x*scale + 50) / 100
+			if x < 1 {
+				x = 1
+			} else if x > 255 {
+				x = 255
+			}
+			e.quant[i][j] = uint8(x)
+		}
+	}
+	// Compute number of components based on input image type.
+	nComponent := 3
+	switch m.(type) {
+	// TODO(wathiede): switch on m.ColorModel() instead of type.
+	case *image.Gray:
+		nComponent = 1
+	}
+	// Write the Start Of Image marker.
+	e.buf[0] = 0xff
+	e.buf[1] = 0xd8
+	e.write(e.buf[:2])
+	// Write the quantization tables.
+	e.writeDQT()
+	// Write the image dimensions.
+	e.writeSOF0(b.Size(), nComponent)
+	// Write the Huffman tables.
+	e.writeDHT(nComponent)
+	// Write the image data.
+	e.writeSOS(m)
+	// Write the End Of Image marker.
+	e.buf[0] = 0xff
+	e.buf[1] = 0xd9
+	e.write(e.buf[:2])
+	e.flush()
+	return e.err
+}
diff --git a/src/image/jpeg/writer_test.go b/src/image/jpeg/writer_test.go
new file mode 100644
index 0000000..3df3cfc
--- /dev/null
+++ b/src/image/jpeg/writer_test.go
@@ -0,0 +1,232 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package jpeg
+
+import (
+	"bytes"
+	"fmt"
+	"image"
+	"image/color"
+	"image/png"
+	"io/ioutil"
+	"math/rand"
+	"os"
+	"testing"
+)
+
+// zigzag maps from the natural ordering to the zig-zag ordering. For example,
+// zigzag[0*8 + 3] is the zig-zag sequence number of the element in the fourth
+// column and first row.
+var zigzag = [blockSize]int{
+	0, 1, 5, 6, 14, 15, 27, 28,
+	2, 4, 7, 13, 16, 26, 29, 42,
+	3, 8, 12, 17, 25, 30, 41, 43,
+	9, 11, 18, 24, 31, 40, 44, 53,
+	10, 19, 23, 32, 39, 45, 52, 54,
+	20, 22, 33, 38, 46, 51, 55, 60,
+	21, 34, 37, 47, 50, 56, 59, 61,
+	35, 36, 48, 49, 57, 58, 62, 63,
+}
+
+func TestZigUnzig(t *testing.T) {
+	for i := 0; i < blockSize; i++ {
+		if unzig[zigzag[i]] != i {
+			t.Errorf("unzig[zigzag[%d]] == %d", i, unzig[zigzag[i]])
+		}
+		if zigzag[unzig[i]] != i {
+			t.Errorf("zigzag[unzig[%d]] == %d", i, zigzag[unzig[i]])
+		}
+	}
+}
+
+// unscaledQuantInNaturalOrder are the unscaled quantization tables in
+// natural (not zig-zag) order, as specified in section K.1.
+var unscaledQuantInNaturalOrder = [nQuantIndex][blockSize]byte{
+	// Luminance.
+	{
+		16, 11, 10, 16, 24, 40, 51, 61,
+		12, 12, 14, 19, 26, 58, 60, 55,
+		14, 13, 16, 24, 40, 57, 69, 56,
+		14, 17, 22, 29, 51, 87, 80, 62,
+		18, 22, 37, 56, 68, 109, 103, 77,
+		24, 35, 55, 64, 81, 104, 113, 92,
+		49, 64, 78, 87, 103, 121, 120, 101,
+		72, 92, 95, 98, 112, 100, 103, 99,
+	},
+	// Chrominance.
+	{
+		17, 18, 24, 47, 99, 99, 99, 99,
+		18, 21, 26, 66, 99, 99, 99, 99,
+		24, 26, 56, 99, 99, 99, 99, 99,
+		47, 66, 99, 99, 99, 99, 99, 99,
+		99, 99, 99, 99, 99, 99, 99, 99,
+		99, 99, 99, 99, 99, 99, 99, 99,
+		99, 99, 99, 99, 99, 99, 99, 99,
+		99, 99, 99, 99, 99, 99, 99, 99,
+	},
+}
+
+func TestUnscaledQuant(t *testing.T) {
+	bad := false
+	for i := quantIndex(0); i < nQuantIndex; i++ {
+		for zig := 0; zig < blockSize; zig++ {
+			got := unscaledQuant[i][zig]
+			want := unscaledQuantInNaturalOrder[i][unzig[zig]]
+			if got != want {
+				t.Errorf("i=%d, zig=%d: got %d, want %d", i, zig, got, want)
+				bad = true
+			}
+		}
+	}
+	if bad {
+		names := [nQuantIndex]string{"Luminance", "Chrominance"}
+		buf := &bytes.Buffer{}
+		for i, name := range names {
+			fmt.Fprintf(buf, "// %s.\n{\n", name)
+			for zig := 0; zig < blockSize; zig++ {
+				fmt.Fprintf(buf, "%d, ", unscaledQuantInNaturalOrder[i][unzig[zig]])
+				if zig%8 == 7 {
+					buf.WriteString("\n")
+				}
+			}
+			buf.WriteString("},\n")
+		}
+		t.Logf("expected unscaledQuant values:\n%s", buf.String())
+	}
+}
+
+var testCase = []struct {
+	filename  string
+	quality   int
+	tolerance int64
+}{
+	{"../testdata/video-001.png", 1, 24 << 8},
+	{"../testdata/video-001.png", 20, 12 << 8},
+	{"../testdata/video-001.png", 60, 8 << 8},
+	{"../testdata/video-001.png", 80, 6 << 8},
+	{"../testdata/video-001.png", 90, 4 << 8},
+	{"../testdata/video-001.png", 100, 2 << 8},
+}
+
+func delta(u0, u1 uint32) int64 {
+	d := int64(u0) - int64(u1)
+	if d < 0 {
+		return -d
+	}
+	return d
+}
+
+func readPng(filename string) (image.Image, error) {
+	f, err := os.Open(filename)
+	if err != nil {
+		return nil, err
+	}
+	defer f.Close()
+	return png.Decode(f)
+}
+
+func TestWriter(t *testing.T) {
+	for _, tc := range testCase {
+		// Read the image.
+		m0, err := readPng(tc.filename)
+		if err != nil {
+			t.Error(tc.filename, err)
+			continue
+		}
+		// Encode that image as JPEG.
+		var buf bytes.Buffer
+		err = Encode(&buf, m0, &Options{Quality: tc.quality})
+		if err != nil {
+			t.Error(tc.filename, err)
+			continue
+		}
+		// Decode that JPEG.
+		m1, err := Decode(&buf)
+		if err != nil {
+			t.Error(tc.filename, err)
+			continue
+		}
+		if m0.Bounds() != m1.Bounds() {
+			t.Errorf("%s, bounds differ: %v and %v", tc.filename, m0.Bounds(), m1.Bounds())
+			continue
+		}
+		// Compare the average delta to the tolerance level.
+		if averageDelta(m0, m1) > tc.tolerance {
+			t.Errorf("%s, quality=%d: average delta is too high", tc.filename, tc.quality)
+			continue
+		}
+	}
+}
+
+// TestWriteGrayscale tests that a grayscale images survives a round-trip
+// through encode/decode cycle.
+func TestWriteGrayscale(t *testing.T) {
+	m0 := image.NewGray(image.Rect(0, 0, 32, 32))
+	for i := range m0.Pix {
+		m0.Pix[i] = uint8(i)
+	}
+	var buf bytes.Buffer
+	if err := Encode(&buf, m0, nil); err != nil {
+		t.Fatal(err)
+	}
+	m1, err := Decode(&buf)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if m0.Bounds() != m1.Bounds() {
+		t.Fatalf("bounds differ: %v and %v", m0.Bounds(), m1.Bounds())
+	}
+	if _, ok := m1.(*image.Gray); !ok {
+		t.Errorf("got %T, want *image.Gray", m1)
+	}
+	// Compare the average delta to the tolerance level.
+	want := int64(2 << 8)
+	if got := averageDelta(m0, m1); got > want {
+		t.Errorf("average delta too high; got %d, want <= %d", got, want)
+	}
+}
+
+// averageDelta returns the average delta in RGB space. The two images must
+// have the same bounds.
+func averageDelta(m0, m1 image.Image) int64 {
+	b := m0.Bounds()
+	var sum, n int64
+	for y := b.Min.Y; y < b.Max.Y; y++ {
+		for x := b.Min.X; x < b.Max.X; x++ {
+			c0 := m0.At(x, y)
+			c1 := m1.At(x, y)
+			r0, g0, b0, _ := c0.RGBA()
+			r1, g1, b1, _ := c1.RGBA()
+			sum += delta(r0, r1)
+			sum += delta(g0, g1)
+			sum += delta(b0, b1)
+			n += 3
+		}
+	}
+	return sum / n
+}
+
+func BenchmarkEncode(b *testing.B) {
+	b.StopTimer()
+	img := image.NewRGBA(image.Rect(0, 0, 640, 480))
+	bo := img.Bounds()
+	rnd := rand.New(rand.NewSource(123))
+	for y := bo.Min.Y; y < bo.Max.Y; y++ {
+		for x := bo.Min.X; x < bo.Max.X; x++ {
+			img.SetRGBA(x, y, color.RGBA{
+				uint8(rnd.Intn(256)),
+				uint8(rnd.Intn(256)),
+				uint8(rnd.Intn(256)),
+				255,
+			})
+		}
+	}
+	b.SetBytes(640 * 480 * 4)
+	b.StartTimer()
+	options := &Options{Quality: 90}
+	for i := 0; i < b.N; i++ {
+		Encode(ioutil.Discard, img, options)
+	}
+}
diff --git a/src/pkg/image/names.go b/src/image/names.go
similarity index 100%
rename from src/pkg/image/names.go
rename to src/image/names.go
diff --git a/src/image/png/paeth.go b/src/image/png/paeth.go
new file mode 100644
index 0000000..9ed6300
--- /dev/null
+++ b/src/image/png/paeth.go
@@ -0,0 +1,71 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package png
+
+// intSize is either 32 or 64.
+const intSize = 32 << (^uint(0) >> 63)
+
+func abs(x int) int {
+	// m := -1 if x < 0. m := 0 otherwise.
+	m := x >> (intSize - 1)
+
+	// In two's complement representation, the negative number
+	// of any number (except the smallest one) can be computed
+	// by flipping all the bits and add 1. This is faster than
+	// code with a branch.
+	// See Hacker's Delight, section 2-4.
+	return (x ^ m) - m
+}
+
+// paeth implements the Paeth filter function, as per the PNG specification.
+func paeth(a, b, c uint8) uint8 {
+	// This is an optimized version of the sample code in the PNG spec.
+	// For example, the sample code starts with:
+	//	p := int(a) + int(b) - int(c)
+	//	pa := abs(p - int(a))
+	// but the optimized form uses fewer arithmetic operations:
+	//	pa := int(b) - int(c)
+	//	pa = abs(pa)
+	pc := int(c)
+	pa := int(b) - pc
+	pb := int(a) - pc
+	pc = abs(pa + pb)
+	pa = abs(pa)
+	pb = abs(pb)
+	if pa <= pb && pa <= pc {
+		return a
+	} else if pb <= pc {
+		return b
+	}
+	return c
+}
+
+// filterPaeth applies the Paeth filter to the cdat slice.
+// cdat is the current row's data, pdat is the previous row's data.
+func filterPaeth(cdat, pdat []byte, bytesPerPixel int) {
+	var a, b, c, pa, pb, pc int
+	for i := 0; i < bytesPerPixel; i++ {
+		a, c = 0, 0
+		for j := i; j < len(cdat); j += bytesPerPixel {
+			b = int(pdat[j])
+			pa = b - c
+			pb = a - c
+			pc = abs(pa + pb)
+			pa = abs(pa)
+			pb = abs(pb)
+			if pa <= pb && pa <= pc {
+				// No-op.
+			} else if pb <= pc {
+				a = b
+			} else {
+				a = c
+			}
+			a += int(cdat[j])
+			a &= 0xff
+			cdat[j] = uint8(a)
+			c = b
+		}
+	}
+}
diff --git a/src/image/png/paeth_test.go b/src/image/png/paeth_test.go
new file mode 100644
index 0000000..cfc1896
--- /dev/null
+++ b/src/image/png/paeth_test.go
@@ -0,0 +1,91 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package png
+
+import (
+	"bytes"
+	"math/rand"
+	"testing"
+)
+
+func slowAbs(x int) int {
+	if x < 0 {
+		return -x
+	}
+	return x
+}
+
+// slowPaeth is a slow but simple implementation of the Paeth function.
+// It is a straight port of the sample code in the PNG spec, section 9.4.
+func slowPaeth(a, b, c uint8) uint8 {
+	p := int(a) + int(b) - int(c)
+	pa := slowAbs(p - int(a))
+	pb := slowAbs(p - int(b))
+	pc := slowAbs(p - int(c))
+	if pa <= pb && pa <= pc {
+		return a
+	} else if pb <= pc {
+		return b
+	}
+	return c
+}
+
+// slowFilterPaeth is a slow but simple implementation of func filterPaeth.
+func slowFilterPaeth(cdat, pdat []byte, bytesPerPixel int) {
+	for i := 0; i < bytesPerPixel; i++ {
+		cdat[i] += paeth(0, pdat[i], 0)
+	}
+	for i := bytesPerPixel; i < len(cdat); i++ {
+		cdat[i] += paeth(cdat[i-bytesPerPixel], pdat[i], pdat[i-bytesPerPixel])
+	}
+}
+
+func TestPaeth(t *testing.T) {
+	for a := 0; a < 256; a += 15 {
+		for b := 0; b < 256; b += 15 {
+			for c := 0; c < 256; c += 15 {
+				got := paeth(uint8(a), uint8(b), uint8(c))
+				want := slowPaeth(uint8(a), uint8(b), uint8(c))
+				if got != want {
+					t.Errorf("a, b, c = %d, %d, %d: got %d, want %d", a, b, c, got, want)
+				}
+			}
+		}
+	}
+}
+
+func BenchmarkPaeth(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		paeth(uint8(i>>16), uint8(i>>8), uint8(i))
+	}
+}
+
+func TestPaethDecode(t *testing.T) {
+	pdat0 := make([]byte, 32)
+	pdat1 := make([]byte, 32)
+	pdat2 := make([]byte, 32)
+	cdat0 := make([]byte, 32)
+	cdat1 := make([]byte, 32)
+	cdat2 := make([]byte, 32)
+	r := rand.New(rand.NewSource(1))
+	for bytesPerPixel := 1; bytesPerPixel <= 8; bytesPerPixel++ {
+		for i := 0; i < 100; i++ {
+			for j := range pdat0 {
+				pdat0[j] = uint8(r.Uint32())
+				cdat0[j] = uint8(r.Uint32())
+			}
+			copy(pdat1, pdat0)
+			copy(pdat2, pdat0)
+			copy(cdat1, cdat0)
+			copy(cdat2, cdat0)
+			filterPaeth(cdat1, pdat1, bytesPerPixel)
+			slowFilterPaeth(cdat2, pdat2, bytesPerPixel)
+			if !bytes.Equal(cdat1, cdat2) {
+				t.Errorf("bytesPerPixel: %d\npdat0: % x\ncdat0: % x\ngot:   % x\nwant:  % x", bytesPerPixel, pdat0, cdat0, cdat1, cdat2)
+				break
+			}
+		}
+	}
+}
diff --git a/src/image/png/reader.go b/src/image/png/reader.go
new file mode 100644
index 0000000..0a40ca1
--- /dev/null
+++ b/src/image/png/reader.go
@@ -0,0 +1,820 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package png implements a PNG image decoder and encoder.
+//
+// The PNG specification is at http://www.w3.org/TR/PNG/.
+package png
+
+import (
+	"compress/zlib"
+	"encoding/binary"
+	"fmt"
+	"hash"
+	"hash/crc32"
+	"image"
+	"image/color"
+	"io"
+)
+
+// Color type, as per the PNG spec.
+const (
+	ctGrayscale      = 0
+	ctTrueColor      = 2
+	ctPaletted       = 3
+	ctGrayscaleAlpha = 4
+	ctTrueColorAlpha = 6
+)
+
+// A cb is a combination of color type and bit depth.
+const (
+	cbInvalid = iota
+	cbG1
+	cbG2
+	cbG4
+	cbG8
+	cbGA8
+	cbTC8
+	cbP1
+	cbP2
+	cbP4
+	cbP8
+	cbTCA8
+	cbG16
+	cbGA16
+	cbTC16
+	cbTCA16
+)
+
+// Filter type, as per the PNG spec.
+const (
+	ftNone    = 0
+	ftSub     = 1
+	ftUp      = 2
+	ftAverage = 3
+	ftPaeth   = 4
+	nFilter   = 5
+)
+
+// Interlace type.
+const (
+	itNone  = 0
+	itAdam7 = 1
+)
+
+// interlaceScan defines the placement and size of a pass for Adam7 interlacing.
+type interlaceScan struct {
+	xFactor, yFactor, xOffset, yOffset int
+}
+
+// interlacing defines Adam7 interlacing, with 7 passes of reduced images.
+// See http://www.w3.org/TR/PNG/#8Interlace
+var interlacing = []interlaceScan{
+	{8, 8, 0, 0},
+	{8, 8, 4, 0},
+	{4, 8, 0, 4},
+	{4, 4, 2, 0},
+	{2, 4, 0, 2},
+	{2, 2, 1, 0},
+	{1, 2, 0, 1},
+}
+
+// Decoding stage.
+// The PNG specification says that the IHDR, PLTE (if present), IDAT and IEND
+// chunks must appear in that order. There may be multiple IDAT chunks, and
+// IDAT chunks must be sequential (i.e. they may not have any other chunks
+// between them).
+// http://www.w3.org/TR/PNG/#5ChunkOrdering
+const (
+	dsStart = iota
+	dsSeenIHDR
+	dsSeenPLTE
+	dsSeenIDAT
+	dsSeenIEND
+)
+
+const pngHeader = "\x89PNG\r\n\x1a\n"
+
+type decoder struct {
+	r             io.Reader
+	img           image.Image
+	crc           hash.Hash32
+	width, height int
+	depth         int
+	palette       color.Palette
+	cb            int
+	stage         int
+	idatLength    uint32
+	tmp           [3 * 256]byte
+	interlace     int
+}
+
+// A FormatError reports that the input is not a valid PNG.
+type FormatError string
+
+func (e FormatError) Error() string { return "png: invalid format: " + string(e) }
+
+var chunkOrderError = FormatError("chunk out of order")
+
+// An UnsupportedError reports that the input uses a valid but unimplemented PNG feature.
+type UnsupportedError string
+
+func (e UnsupportedError) Error() string { return "png: unsupported feature: " + string(e) }
+
+func min(a, b int) int {
+	if a < b {
+		return a
+	}
+	return b
+}
+
+func (d *decoder) parseIHDR(length uint32) error {
+	if length != 13 {
+		return FormatError("bad IHDR length")
+	}
+	if _, err := io.ReadFull(d.r, d.tmp[:13]); err != nil {
+		return err
+	}
+	d.crc.Write(d.tmp[:13])
+	if d.tmp[10] != 0 {
+		return UnsupportedError("compression method")
+	}
+	if d.tmp[11] != 0 {
+		return UnsupportedError("filter method")
+	}
+	if d.tmp[12] != itNone && d.tmp[12] != itAdam7 {
+		return FormatError("invalid interlace method")
+	}
+	d.interlace = int(d.tmp[12])
+	w := int32(binary.BigEndian.Uint32(d.tmp[0:4]))
+	h := int32(binary.BigEndian.Uint32(d.tmp[4:8]))
+	if w < 0 || h < 0 {
+		return FormatError("negative dimension")
+	}
+	nPixels := int64(w) * int64(h)
+	if nPixels != int64(int(nPixels)) {
+		return UnsupportedError("dimension overflow")
+	}
+	d.cb = cbInvalid
+	d.depth = int(d.tmp[8])
+	switch d.depth {
+	case 1:
+		switch d.tmp[9] {
+		case ctGrayscale:
+			d.cb = cbG1
+		case ctPaletted:
+			d.cb = cbP1
+		}
+	case 2:
+		switch d.tmp[9] {
+		case ctGrayscale:
+			d.cb = cbG2
+		case ctPaletted:
+			d.cb = cbP2
+		}
+	case 4:
+		switch d.tmp[9] {
+		case ctGrayscale:
+			d.cb = cbG4
+		case ctPaletted:
+			d.cb = cbP4
+		}
+	case 8:
+		switch d.tmp[9] {
+		case ctGrayscale:
+			d.cb = cbG8
+		case ctTrueColor:
+			d.cb = cbTC8
+		case ctPaletted:
+			d.cb = cbP8
+		case ctGrayscaleAlpha:
+			d.cb = cbGA8
+		case ctTrueColorAlpha:
+			d.cb = cbTCA8
+		}
+	case 16:
+		switch d.tmp[9] {
+		case ctGrayscale:
+			d.cb = cbG16
+		case ctTrueColor:
+			d.cb = cbTC16
+		case ctGrayscaleAlpha:
+			d.cb = cbGA16
+		case ctTrueColorAlpha:
+			d.cb = cbTCA16
+		}
+	}
+	if d.cb == cbInvalid {
+		return UnsupportedError(fmt.Sprintf("bit depth %d, color type %d", d.tmp[8], d.tmp[9]))
+	}
+	d.width, d.height = int(w), int(h)
+	return d.verifyChecksum()
+}
+
+func (d *decoder) parsePLTE(length uint32) error {
+	np := int(length / 3) // The number of palette entries.
+	if length%3 != 0 || np <= 0 || np > 256 || np > 1<<uint(d.depth) {
+		return FormatError("bad PLTE length")
+	}
+	n, err := io.ReadFull(d.r, d.tmp[:3*np])
+	if err != nil {
+		return err
+	}
+	d.crc.Write(d.tmp[:n])
+	switch d.cb {
+	case cbP1, cbP2, cbP4, cbP8:
+		d.palette = make(color.Palette, 256)
+		for i := 0; i < np; i++ {
+			d.palette[i] = color.RGBA{d.tmp[3*i+0], d.tmp[3*i+1], d.tmp[3*i+2], 0xff}
+		}
+		for i := np; i < 256; i++ {
+			// Initialize the rest of the palette to opaque black. The spec (section
+			// 11.2.3) says that "any out-of-range pixel value found in the image data
+			// is an error", but some real-world PNG files have out-of-range pixel
+			// values. We fall back to opaque black, the same as libpng 1.5.13;
+			// ImageMagick 6.5.7 returns an error.
+			d.palette[i] = color.RGBA{0x00, 0x00, 0x00, 0xff}
+		}
+		d.palette = d.palette[:np]
+	case cbTC8, cbTCA8, cbTC16, cbTCA16:
+		// As per the PNG spec, a PLTE chunk is optional (and for practical purposes,
+		// ignorable) for the ctTrueColor and ctTrueColorAlpha color types (section 4.1.2).
+	default:
+		return FormatError("PLTE, color type mismatch")
+	}
+	return d.verifyChecksum()
+}
+
+func (d *decoder) parsetRNS(length uint32) error {
+	if length > 256 {
+		return FormatError("bad tRNS length")
+	}
+	n, err := io.ReadFull(d.r, d.tmp[:length])
+	if err != nil {
+		return err
+	}
+	d.crc.Write(d.tmp[:n])
+	switch d.cb {
+	case cbG8, cbG16:
+		return UnsupportedError("grayscale transparency")
+	case cbTC8, cbTC16:
+		return UnsupportedError("truecolor transparency")
+	case cbP1, cbP2, cbP4, cbP8:
+		if len(d.palette) < n {
+			d.palette = d.palette[:n]
+		}
+		for i := 0; i < n; i++ {
+			rgba := d.palette[i].(color.RGBA)
+			d.palette[i] = color.NRGBA{rgba.R, rgba.G, rgba.B, d.tmp[i]}
+		}
+	case cbGA8, cbGA16, cbTCA8, cbTCA16:
+		return FormatError("tRNS, color type mismatch")
+	}
+	return d.verifyChecksum()
+}
+
+// Read presents one or more IDAT chunks as one continuous stream (minus the
+// intermediate chunk headers and footers). If the PNG data looked like:
+//   ... len0 IDAT xxx crc0 len1 IDAT yy crc1 len2 IEND crc2
+// then this reader presents xxxyy. For well-formed PNG data, the decoder state
+// immediately before the first Read call is that d.r is positioned between the
+// first IDAT and xxx, and the decoder state immediately after the last Read
+// call is that d.r is positioned between yy and crc1.
+func (d *decoder) Read(p []byte) (int, error) {
+	if len(p) == 0 {
+		return 0, nil
+	}
+	for d.idatLength == 0 {
+		// We have exhausted an IDAT chunk. Verify the checksum of that chunk.
+		if err := d.verifyChecksum(); err != nil {
+			return 0, err
+		}
+		// Read the length and chunk type of the next chunk, and check that
+		// it is an IDAT chunk.
+		if _, err := io.ReadFull(d.r, d.tmp[:8]); err != nil {
+			return 0, err
+		}
+		d.idatLength = binary.BigEndian.Uint32(d.tmp[:4])
+		if string(d.tmp[4:8]) != "IDAT" {
+			return 0, FormatError("not enough pixel data")
+		}
+		d.crc.Reset()
+		d.crc.Write(d.tmp[4:8])
+	}
+	if int(d.idatLength) < 0 {
+		return 0, UnsupportedError("IDAT chunk length overflow")
+	}
+	n, err := d.r.Read(p[:min(len(p), int(d.idatLength))])
+	d.crc.Write(p[:n])
+	d.idatLength -= uint32(n)
+	return n, err
+}
+
+// decode decodes the IDAT data into an image.
+func (d *decoder) decode() (image.Image, error) {
+	r, err := zlib.NewReader(d)
+	if err != nil {
+		return nil, err
+	}
+	defer r.Close()
+	var img image.Image
+	if d.interlace == itNone {
+		img, err = d.readImagePass(r, 0, false)
+	} else if d.interlace == itAdam7 {
+		// Allocate a blank image of the full size.
+		img, err = d.readImagePass(nil, 0, true)
+		for pass := 0; pass < 7; pass++ {
+			imagePass, err := d.readImagePass(r, pass, false)
+			if err != nil {
+				return nil, err
+			}
+			d.mergePassInto(img, imagePass, pass)
+		}
+	}
+
+	// Check for EOF, to verify the zlib checksum.
+	n := 0
+	for i := 0; n == 0 && err == nil; i++ {
+		if i == 100 {
+			return nil, io.ErrNoProgress
+		}
+		n, err = r.Read(d.tmp[:1])
+	}
+	if err != nil && err != io.EOF {
+		return nil, FormatError(err.Error())
+	}
+	if n != 0 || d.idatLength != 0 {
+		return nil, FormatError("too much pixel data")
+	}
+
+	return img, nil
+}
+
+// readImagePass reads a single image pass, sized according to the pass number.
+func (d *decoder) readImagePass(r io.Reader, pass int, allocateOnly bool) (image.Image, error) {
+	var bitsPerPixel int = 0
+	pixOffset := 0
+	var (
+		gray     *image.Gray
+		rgba     *image.RGBA
+		paletted *image.Paletted
+		nrgba    *image.NRGBA
+		gray16   *image.Gray16
+		rgba64   *image.RGBA64
+		nrgba64  *image.NRGBA64
+		img      image.Image
+	)
+	width, height := d.width, d.height
+	if d.interlace == itAdam7 && !allocateOnly {
+		p := interlacing[pass]
+		// Add the multiplication factor and subtract one, effectively rounding up.
+		width = (width - p.xOffset + p.xFactor - 1) / p.xFactor
+		height = (height - p.yOffset + p.yFactor - 1) / p.yFactor
+	}
+	switch d.cb {
+	case cbG1, cbG2, cbG4, cbG8:
+		bitsPerPixel = d.depth
+		gray = image.NewGray(image.Rect(0, 0, width, height))
+		img = gray
+	case cbGA8:
+		bitsPerPixel = 16
+		nrgba = image.NewNRGBA(image.Rect(0, 0, width, height))
+		img = nrgba
+	case cbTC8:
+		bitsPerPixel = 24
+		rgba = image.NewRGBA(image.Rect(0, 0, width, height))
+		img = rgba
+	case cbP1, cbP2, cbP4, cbP8:
+		bitsPerPixel = d.depth
+		paletted = image.NewPaletted(image.Rect(0, 0, width, height), d.palette)
+		img = paletted
+	case cbTCA8:
+		bitsPerPixel = 32
+		nrgba = image.NewNRGBA(image.Rect(0, 0, width, height))
+		img = nrgba
+	case cbG16:
+		bitsPerPixel = 16
+		gray16 = image.NewGray16(image.Rect(0, 0, width, height))
+		img = gray16
+	case cbGA16:
+		bitsPerPixel = 32
+		nrgba64 = image.NewNRGBA64(image.Rect(0, 0, width, height))
+		img = nrgba64
+	case cbTC16:
+		bitsPerPixel = 48
+		rgba64 = image.NewRGBA64(image.Rect(0, 0, width, height))
+		img = rgba64
+	case cbTCA16:
+		bitsPerPixel = 64
+		nrgba64 = image.NewNRGBA64(image.Rect(0, 0, width, height))
+		img = nrgba64
+	}
+	if allocateOnly {
+		return img, nil
+	}
+	bytesPerPixel := (bitsPerPixel + 7) / 8
+
+	// The +1 is for the per-row filter type, which is at cr[0].
+	rowSize := 1 + (bitsPerPixel*width+7)/8
+	// cr and pr are the bytes for the current and previous row.
+	cr := make([]uint8, rowSize)
+	pr := make([]uint8, rowSize)
+
+	for y := 0; y < height; y++ {
+		// Read the decompressed bytes.
+		_, err := io.ReadFull(r, cr)
+		if err != nil {
+			return nil, err
+		}
+
+		// Apply the filter.
+		cdat := cr[1:]
+		pdat := pr[1:]
+		switch cr[0] {
+		case ftNone:
+			// No-op.
+		case ftSub:
+			for i := bytesPerPixel; i < len(cdat); i++ {
+				cdat[i] += cdat[i-bytesPerPixel]
+			}
+		case ftUp:
+			for i, p := range pdat {
+				cdat[i] += p
+			}
+		case ftAverage:
+			for i := 0; i < bytesPerPixel; i++ {
+				cdat[i] += pdat[i] / 2
+			}
+			for i := bytesPerPixel; i < len(cdat); i++ {
+				cdat[i] += uint8((int(cdat[i-bytesPerPixel]) + int(pdat[i])) / 2)
+			}
+		case ftPaeth:
+			filterPaeth(cdat, pdat, bytesPerPixel)
+		default:
+			return nil, FormatError("bad filter type")
+		}
+
+		// Convert from bytes to colors.
+		switch d.cb {
+		case cbG1:
+			for x := 0; x < width; x += 8 {
+				b := cdat[x/8]
+				for x2 := 0; x2 < 8 && x+x2 < width; x2++ {
+					gray.SetGray(x+x2, y, color.Gray{(b >> 7) * 0xff})
+					b <<= 1
+				}
+			}
+		case cbG2:
+			for x := 0; x < width; x += 4 {
+				b := cdat[x/4]
+				for x2 := 0; x2 < 4 && x+x2 < width; x2++ {
+					gray.SetGray(x+x2, y, color.Gray{(b >> 6) * 0x55})
+					b <<= 2
+				}
+			}
+		case cbG4:
+			for x := 0; x < width; x += 2 {
+				b := cdat[x/2]
+				for x2 := 0; x2 < 2 && x+x2 < width; x2++ {
+					gray.SetGray(x+x2, y, color.Gray{(b >> 4) * 0x11})
+					b <<= 4
+				}
+			}
+		case cbG8:
+			copy(gray.Pix[pixOffset:], cdat)
+			pixOffset += gray.Stride
+		case cbGA8:
+			for x := 0; x < width; x++ {
+				ycol := cdat[2*x+0]
+				nrgba.SetNRGBA(x, y, color.NRGBA{ycol, ycol, ycol, cdat[2*x+1]})
+			}
+		case cbTC8:
+			pix, i, j := rgba.Pix, pixOffset, 0
+			for x := 0; x < width; x++ {
+				pix[i+0] = cdat[j+0]
+				pix[i+1] = cdat[j+1]
+				pix[i+2] = cdat[j+2]
+				pix[i+3] = 0xff
+				i += 4
+				j += 3
+			}
+			pixOffset += rgba.Stride
+		case cbP1:
+			for x := 0; x < width; x += 8 {
+				b := cdat[x/8]
+				for x2 := 0; x2 < 8 && x+x2 < width; x2++ {
+					idx := b >> 7
+					if len(paletted.Palette) <= int(idx) {
+						paletted.Palette = paletted.Palette[:int(idx)+1]
+					}
+					paletted.SetColorIndex(x+x2, y, idx)
+					b <<= 1
+				}
+			}
+		case cbP2:
+			for x := 0; x < width; x += 4 {
+				b := cdat[x/4]
+				for x2 := 0; x2 < 4 && x+x2 < width; x2++ {
+					idx := b >> 6
+					if len(paletted.Palette) <= int(idx) {
+						paletted.Palette = paletted.Palette[:int(idx)+1]
+					}
+					paletted.SetColorIndex(x+x2, y, idx)
+					b <<= 2
+				}
+			}
+		case cbP4:
+			for x := 0; x < width; x += 2 {
+				b := cdat[x/2]
+				for x2 := 0; x2 < 2 && x+x2 < width; x2++ {
+					idx := b >> 4
+					if len(paletted.Palette) <= int(idx) {
+						paletted.Palette = paletted.Palette[:int(idx)+1]
+					}
+					paletted.SetColorIndex(x+x2, y, idx)
+					b <<= 4
+				}
+			}
+		case cbP8:
+			if len(paletted.Palette) != 255 {
+				for x := 0; x < width; x++ {
+					if len(paletted.Palette) <= int(cdat[x]) {
+						paletted.Palette = paletted.Palette[:int(cdat[x])+1]
+					}
+				}
+			}
+			copy(paletted.Pix[pixOffset:], cdat)
+			pixOffset += paletted.Stride
+		case cbTCA8:
+			copy(nrgba.Pix[pixOffset:], cdat)
+			pixOffset += nrgba.Stride
+		case cbG16:
+			for x := 0; x < width; x++ {
+				ycol := uint16(cdat[2*x+0])<<8 | uint16(cdat[2*x+1])
+				gray16.SetGray16(x, y, color.Gray16{ycol})
+			}
+		case cbGA16:
+			for x := 0; x < width; x++ {
+				ycol := uint16(cdat[4*x+0])<<8 | uint16(cdat[4*x+1])
+				acol := uint16(cdat[4*x+2])<<8 | uint16(cdat[4*x+3])
+				nrgba64.SetNRGBA64(x, y, color.NRGBA64{ycol, ycol, ycol, acol})
+			}
+		case cbTC16:
+			for x := 0; x < width; x++ {
+				rcol := uint16(cdat[6*x+0])<<8 | uint16(cdat[6*x+1])
+				gcol := uint16(cdat[6*x+2])<<8 | uint16(cdat[6*x+3])
+				bcol := uint16(cdat[6*x+4])<<8 | uint16(cdat[6*x+5])
+				rgba64.SetRGBA64(x, y, color.RGBA64{rcol, gcol, bcol, 0xffff})
+			}
+		case cbTCA16:
+			for x := 0; x < width; x++ {
+				rcol := uint16(cdat[8*x+0])<<8 | uint16(cdat[8*x+1])
+				gcol := uint16(cdat[8*x+2])<<8 | uint16(cdat[8*x+3])
+				bcol := uint16(cdat[8*x+4])<<8 | uint16(cdat[8*x+5])
+				acol := uint16(cdat[8*x+6])<<8 | uint16(cdat[8*x+7])
+				nrgba64.SetNRGBA64(x, y, color.NRGBA64{rcol, gcol, bcol, acol})
+			}
+		}
+
+		// The current row for y is the previous row for y+1.
+		pr, cr = cr, pr
+	}
+
+	return img, nil
+}
+
+// mergePassInto merges a single pass into a full sized image.
+func (d *decoder) mergePassInto(dst image.Image, src image.Image, pass int) {
+	p := interlacing[pass]
+	var (
+		srcPix        []uint8
+		dstPix        []uint8
+		stride        int
+		rect          image.Rectangle
+		bytesPerPixel int
+	)
+	switch target := dst.(type) {
+	case *image.Alpha:
+		srcPix = src.(*image.Alpha).Pix
+		dstPix, stride, rect = target.Pix, target.Stride, target.Rect
+		bytesPerPixel = 1
+	case *image.Alpha16:
+		srcPix = src.(*image.Alpha16).Pix
+		dstPix, stride, rect = target.Pix, target.Stride, target.Rect
+		bytesPerPixel = 2
+	case *image.Gray:
+		srcPix = src.(*image.Gray).Pix
+		dstPix, stride, rect = target.Pix, target.Stride, target.Rect
+		bytesPerPixel = 1
+	case *image.Gray16:
+		srcPix = src.(*image.Gray16).Pix
+		dstPix, stride, rect = target.Pix, target.Stride, target.Rect
+		bytesPerPixel = 2
+	case *image.NRGBA:
+		srcPix = src.(*image.NRGBA).Pix
+		dstPix, stride, rect = target.Pix, target.Stride, target.Rect
+		bytesPerPixel = 4
+	case *image.NRGBA64:
+		srcPix = src.(*image.NRGBA64).Pix
+		dstPix, stride, rect = target.Pix, target.Stride, target.Rect
+		bytesPerPixel = 8
+	case *image.Paletted:
+		srcPix = src.(*image.Paletted).Pix
+		dstPix, stride, rect = target.Pix, target.Stride, target.Rect
+		bytesPerPixel = 1
+	case *image.RGBA:
+		srcPix = src.(*image.RGBA).Pix
+		dstPix, stride, rect = target.Pix, target.Stride, target.Rect
+		bytesPerPixel = 4
+	case *image.RGBA64:
+		srcPix = src.(*image.RGBA64).Pix
+		dstPix, stride, rect = target.Pix, target.Stride, target.Rect
+		bytesPerPixel = 8
+	}
+	s, bounds := 0, src.Bounds()
+	for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
+		dBase := (y*p.yFactor+p.yOffset-rect.Min.Y)*stride + (p.xOffset-rect.Min.X)*bytesPerPixel
+		for x := bounds.Min.X; x < bounds.Max.X; x++ {
+			d := dBase + x*p.xFactor*bytesPerPixel
+			copy(dstPix[d:], srcPix[s:s+bytesPerPixel])
+			s += bytesPerPixel
+		}
+	}
+}
+
+func (d *decoder) parseIDAT(length uint32) (err error) {
+	d.idatLength = length
+	d.img, err = d.decode()
+	if err != nil {
+		return err
+	}
+	return d.verifyChecksum()
+}
+
+func (d *decoder) parseIEND(length uint32) error {
+	if length != 0 {
+		return FormatError("bad IEND length")
+	}
+	return d.verifyChecksum()
+}
+
+func (d *decoder) parseChunk() error {
+	// Read the length and chunk type.
+	n, err := io.ReadFull(d.r, d.tmp[:8])
+	if err != nil {
+		return err
+	}
+	length := binary.BigEndian.Uint32(d.tmp[:4])
+	d.crc.Reset()
+	d.crc.Write(d.tmp[4:8])
+
+	// Read the chunk data.
+	switch string(d.tmp[4:8]) {
+	case "IHDR":
+		if d.stage != dsStart {
+			return chunkOrderError
+		}
+		d.stage = dsSeenIHDR
+		return d.parseIHDR(length)
+	case "PLTE":
+		if d.stage != dsSeenIHDR {
+			return chunkOrderError
+		}
+		d.stage = dsSeenPLTE
+		return d.parsePLTE(length)
+	case "tRNS":
+		if d.stage != dsSeenPLTE {
+			return chunkOrderError
+		}
+		return d.parsetRNS(length)
+	case "IDAT":
+		if d.stage < dsSeenIHDR || d.stage > dsSeenIDAT || (d.cb == cbP8 && d.stage == dsSeenIHDR) {
+			return chunkOrderError
+		}
+		d.stage = dsSeenIDAT
+		return d.parseIDAT(length)
+	case "IEND":
+		if d.stage != dsSeenIDAT {
+			return chunkOrderError
+		}
+		d.stage = dsSeenIEND
+		return d.parseIEND(length)
+	}
+	// Ignore this chunk (of a known length).
+	var ignored [4096]byte
+	for length > 0 {
+		n, err = io.ReadFull(d.r, ignored[:min(len(ignored), int(length))])
+		if err != nil {
+			return err
+		}
+		d.crc.Write(ignored[:n])
+		length -= uint32(n)
+	}
+	return d.verifyChecksum()
+}
+
+func (d *decoder) verifyChecksum() error {
+	if _, err := io.ReadFull(d.r, d.tmp[:4]); err != nil {
+		return err
+	}
+	if binary.BigEndian.Uint32(d.tmp[:4]) != d.crc.Sum32() {
+		return FormatError("invalid checksum")
+	}
+	return nil
+}
+
+func (d *decoder) checkHeader() error {
+	_, err := io.ReadFull(d.r, d.tmp[:len(pngHeader)])
+	if err != nil {
+		return err
+	}
+	if string(d.tmp[:len(pngHeader)]) != pngHeader {
+		return FormatError("not a PNG file")
+	}
+	return nil
+}
+
+// Decode reads a PNG image from r and returns it as an image.Image.
+// The type of Image returned depends on the PNG contents.
+func Decode(r io.Reader) (image.Image, error) {
+	d := &decoder{
+		r:   r,
+		crc: crc32.NewIEEE(),
+	}
+	if err := d.checkHeader(); err != nil {
+		if err == io.EOF {
+			err = io.ErrUnexpectedEOF
+		}
+		return nil, err
+	}
+	for d.stage != dsSeenIEND {
+		if err := d.parseChunk(); err != nil {
+			if err == io.EOF {
+				err = io.ErrUnexpectedEOF
+			}
+			return nil, err
+		}
+	}
+	return d.img, nil
+}
+
+// DecodeConfig returns the color model and dimensions of a PNG image without
+// decoding the entire image.
+func DecodeConfig(r io.Reader) (image.Config, error) {
+	d := &decoder{
+		r:   r,
+		crc: crc32.NewIEEE(),
+	}
+	if err := d.checkHeader(); err != nil {
+		if err == io.EOF {
+			err = io.ErrUnexpectedEOF
+		}
+		return image.Config{}, err
+	}
+	for {
+		if err := d.parseChunk(); err != nil {
+			if err == io.EOF {
+				err = io.ErrUnexpectedEOF
+			}
+			return image.Config{}, err
+		}
+		paletted := d.cb == cbP8 || d.cb == cbP4 || d.cb == cbP2 || d.cb == cbP1
+		if d.stage == dsSeenIHDR && !paletted {
+			break
+		}
+		if d.stage == dsSeenPLTE && paletted {
+			break
+		}
+	}
+	var cm color.Model
+	switch d.cb {
+	case cbG1, cbG2, cbG4, cbG8:
+		cm = color.GrayModel
+	case cbGA8:
+		cm = color.NRGBAModel
+	case cbTC8:
+		cm = color.RGBAModel
+	case cbP1, cbP2, cbP4, cbP8:
+		cm = d.palette
+	case cbTCA8:
+		cm = color.NRGBAModel
+	case cbG16:
+		cm = color.Gray16Model
+	case cbGA16:
+		cm = color.NRGBA64Model
+	case cbTC16:
+		cm = color.RGBA64Model
+	case cbTCA16:
+		cm = color.NRGBA64Model
+	}
+	return image.Config{
+		ColorModel: cm,
+		Width:      d.width,
+		Height:     d.height,
+	}, nil
+}
+
+func init() {
+	image.RegisterFormat("png", pngHeader, Decode, DecodeConfig)
+}
diff --git a/src/image/png/reader_test.go b/src/image/png/reader_test.go
new file mode 100644
index 0000000..ce772eb
--- /dev/null
+++ b/src/image/png/reader_test.go
@@ -0,0 +1,362 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package png
+
+import (
+	"bufio"
+	"fmt"
+	"image"
+	"image/color"
+	"io"
+	"io/ioutil"
+	"os"
+	"strings"
+	"testing"
+)
+
+var filenames = []string{
+	"basn0g01",
+	"basn0g01-30",
+	"basn0g02",
+	"basn0g02-29",
+	"basn0g04",
+	"basn0g04-31",
+	"basn0g08",
+	"basn0g16",
+	"basn2c08",
+	"basn2c16",
+	"basn3p01",
+	"basn3p02",
+	"basn3p04",
+	"basn3p04-31i",
+	"basn3p08",
+	"basn3p08-trns",
+	"basn4a08",
+	"basn4a16",
+	"basn6a08",
+	"basn6a16",
+}
+
+var filenamesPaletted = []string{
+	"basn3p01",
+	"basn3p02",
+	"basn3p04",
+	"basn3p08",
+	"basn3p08-trns",
+}
+
+var filenamesShort = []string{
+	"basn0g01",
+	"basn0g04-31",
+	"basn6a16",
+}
+
+func readPNG(filename string) (image.Image, error) {
+	f, err := os.Open(filename)
+	if err != nil {
+		return nil, err
+	}
+	defer f.Close()
+	return Decode(f)
+}
+
+// An approximation of the sng command-line tool.
+func sng(w io.WriteCloser, filename string, png image.Image) {
+	defer w.Close()
+	bounds := png.Bounds()
+	cm := png.ColorModel()
+	var bitdepth int
+	switch cm {
+	case color.RGBAModel, color.NRGBAModel, color.AlphaModel, color.GrayModel:
+		bitdepth = 8
+	default:
+		bitdepth = 16
+	}
+	cpm, _ := cm.(color.Palette)
+	var paletted *image.Paletted
+	if cpm != nil {
+		switch {
+		case len(cpm) <= 2:
+			bitdepth = 1
+		case len(cpm) <= 4:
+			bitdepth = 2
+		case len(cpm) <= 16:
+			bitdepth = 4
+		default:
+			bitdepth = 8
+		}
+		paletted = png.(*image.Paletted)
+	}
+
+	// Write the filename and IHDR.
+	io.WriteString(w, "#SNG: from "+filename+".png\nIHDR {\n")
+	fmt.Fprintf(w, "    width: %d; height: %d; bitdepth: %d;\n", bounds.Dx(), bounds.Dy(), bitdepth)
+	switch {
+	case cm == color.RGBAModel, cm == color.RGBA64Model:
+		io.WriteString(w, "    using color;\n")
+	case cm == color.NRGBAModel, cm == color.NRGBA64Model:
+		io.WriteString(w, "    using color alpha;\n")
+	case cm == color.GrayModel, cm == color.Gray16Model:
+		io.WriteString(w, "    using grayscale;\n")
+	case cpm != nil:
+		io.WriteString(w, "    using color palette;\n")
+	default:
+		io.WriteString(w, "unknown PNG decoder color model\n")
+	}
+	io.WriteString(w, "}\n")
+
+	// We fake a gAMA output. The test files have a gAMA chunk but the go PNG parser ignores it
+	// (the PNG spec section 11.3 says "Ancillary chunks may be ignored by a decoder").
+	io.WriteString(w, "gAMA {1.0000}\n")
+
+	// Write the PLTE and tRNS (if applicable).
+	if cpm != nil {
+		lastAlpha := -1
+		io.WriteString(w, "PLTE {\n")
+		for i, c := range cpm {
+			var r, g, b, a uint8
+			switch c := c.(type) {
+			case color.RGBA:
+				r, g, b, a = c.R, c.G, c.B, 0xff
+			case color.NRGBA:
+				r, g, b, a = c.R, c.G, c.B, c.A
+			default:
+				panic("unknown palette color type")
+			}
+			if a != 0xff {
+				lastAlpha = i
+			}
+			fmt.Fprintf(w, "    (%3d,%3d,%3d)     # rgb = (0x%02x,0x%02x,0x%02x)\n", r, g, b, r, g, b)
+		}
+		io.WriteString(w, "}\n")
+		if lastAlpha != -1 {
+			io.WriteString(w, "tRNS {\n")
+			for i := 0; i <= lastAlpha; i++ {
+				_, _, _, a := cpm[i].RGBA()
+				a >>= 8
+				fmt.Fprintf(w, " %d", a)
+			}
+			io.WriteString(w, "}\n")
+		}
+	}
+
+	// Write the IMAGE.
+	io.WriteString(w, "IMAGE {\n    pixels hex\n")
+	for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
+		switch {
+		case cm == color.GrayModel:
+			for x := bounds.Min.X; x < bounds.Max.X; x++ {
+				gray := png.At(x, y).(color.Gray)
+				fmt.Fprintf(w, "%02x", gray.Y)
+			}
+		case cm == color.Gray16Model:
+			for x := bounds.Min.X; x < bounds.Max.X; x++ {
+				gray16 := png.At(x, y).(color.Gray16)
+				fmt.Fprintf(w, "%04x ", gray16.Y)
+			}
+		case cm == color.RGBAModel:
+			for x := bounds.Min.X; x < bounds.Max.X; x++ {
+				rgba := png.At(x, y).(color.RGBA)
+				fmt.Fprintf(w, "%02x%02x%02x ", rgba.R, rgba.G, rgba.B)
+			}
+		case cm == color.RGBA64Model:
+			for x := bounds.Min.X; x < bounds.Max.X; x++ {
+				rgba64 := png.At(x, y).(color.RGBA64)
+				fmt.Fprintf(w, "%04x%04x%04x ", rgba64.R, rgba64.G, rgba64.B)
+			}
+		case cm == color.NRGBAModel:
+			for x := bounds.Min.X; x < bounds.Max.X; x++ {
+				nrgba := png.At(x, y).(color.NRGBA)
+				fmt.Fprintf(w, "%02x%02x%02x%02x ", nrgba.R, nrgba.G, nrgba.B, nrgba.A)
+			}
+		case cm == color.NRGBA64Model:
+			for x := bounds.Min.X; x < bounds.Max.X; x++ {
+				nrgba64 := png.At(x, y).(color.NRGBA64)
+				fmt.Fprintf(w, "%04x%04x%04x%04x ", nrgba64.R, nrgba64.G, nrgba64.B, nrgba64.A)
+			}
+		case cpm != nil:
+			var b, c int
+			for x := bounds.Min.X; x < bounds.Max.X; x++ {
+				b = b<<uint(bitdepth) | int(paletted.ColorIndexAt(x, y))
+				c++
+				if c == 8/bitdepth {
+					fmt.Fprintf(w, "%02x", b)
+					b = 0
+					c = 0
+				}
+			}
+			if c != 0 {
+				for c != 8/bitdepth {
+					b = b << uint(bitdepth)
+					c++
+				}
+				fmt.Fprintf(w, "%02x", b)
+			}
+		}
+		io.WriteString(w, "\n")
+	}
+	io.WriteString(w, "}\n")
+}
+
+func TestReader(t *testing.T) {
+	names := filenames
+	if testing.Short() {
+		names = filenamesShort
+	}
+	for _, fn := range names {
+		// Read the .png file.
+		img, err := readPNG("testdata/pngsuite/" + fn + ".png")
+		if err != nil {
+			t.Error(fn, err)
+			continue
+		}
+
+		if fn == "basn4a16" {
+			// basn4a16.sng is gray + alpha but sng() will produce true color + alpha
+			// so we just check a single random pixel.
+			c := img.At(2, 1).(color.NRGBA64)
+			if c.R != 0x11a7 || c.G != 0x11a7 || c.B != 0x11a7 || c.A != 0x1085 {
+				t.Error(fn, fmt.Errorf("wrong pixel value at (2, 1): %x", c))
+			}
+			continue
+		}
+
+		piper, pipew := io.Pipe()
+		pb := bufio.NewScanner(piper)
+		go sng(pipew, fn, img)
+		defer piper.Close()
+
+		// Read the .sng file.
+		sf, err := os.Open("testdata/pngsuite/" + fn + ".sng")
+		if err != nil {
+			t.Error(fn, err)
+			continue
+		}
+		defer sf.Close()
+		sb := bufio.NewScanner(sf)
+		if err != nil {
+			t.Error(fn, err)
+			continue
+		}
+
+		// Compare the two, in SNG format, line by line.
+		for {
+			pdone := !pb.Scan()
+			sdone := !sb.Scan()
+			if pdone && sdone {
+				break
+			}
+			if pdone || sdone {
+				t.Errorf("%s: Different sizes", fn)
+				break
+			}
+			ps := pb.Text()
+			ss := sb.Text()
+			if ps != ss {
+				t.Errorf("%s: Mismatch\n%sversus\n%s\n", fn, ps, ss)
+				break
+			}
+		}
+		if pb.Err() != nil {
+			t.Error(fn, pb.Err())
+		}
+		if sb.Err() != nil {
+			t.Error(fn, sb.Err())
+		}
+	}
+}
+
+var readerErrors = []struct {
+	file string
+	err  string
+}{
+	{"invalid-zlib.png", "zlib: invalid checksum"},
+	{"invalid-crc32.png", "invalid checksum"},
+	{"invalid-noend.png", "unexpected EOF"},
+	{"invalid-trunc.png", "unexpected EOF"},
+}
+
+func TestReaderError(t *testing.T) {
+	for _, tt := range readerErrors {
+		img, err := readPNG("testdata/" + tt.file)
+		if err == nil {
+			t.Errorf("decoding %s: missing error", tt.file)
+			continue
+		}
+		if !strings.Contains(err.Error(), tt.err) {
+			t.Errorf("decoding %s: %s, want %s", tt.file, err, tt.err)
+		}
+		if img != nil {
+			t.Errorf("decoding %s: have image + error", tt.file)
+		}
+	}
+}
+
+func TestPalettedDecodeConfig(t *testing.T) {
+	for _, fn := range filenamesPaletted {
+		f, err := os.Open("testdata/pngsuite/" + fn + ".png")
+		if err != nil {
+			t.Errorf("%s: open failed: %v", fn, err)
+			continue
+		}
+		defer f.Close()
+		cfg, err := DecodeConfig(f)
+		if err != nil {
+			t.Errorf("%s: %v", fn, err)
+			continue
+		}
+		pal, ok := cfg.ColorModel.(color.Palette)
+		if !ok {
+			t.Errorf("%s: expected paletted color model", fn)
+			continue
+		}
+		if pal == nil {
+			t.Errorf("%s: palette not initialized", fn)
+			continue
+		}
+	}
+}
+
+func benchmarkDecode(b *testing.B, filename string, bytesPerPixel int) {
+	b.StopTimer()
+	data, err := ioutil.ReadFile(filename)
+	if err != nil {
+		b.Fatal(err)
+	}
+	s := string(data)
+	cfg, err := DecodeConfig(strings.NewReader(s))
+	if err != nil {
+		b.Fatal(err)
+	}
+	b.SetBytes(int64(cfg.Width * cfg.Height * bytesPerPixel))
+	b.StartTimer()
+	for i := 0; i < b.N; i++ {
+		Decode(strings.NewReader(s))
+	}
+}
+
+func BenchmarkDecodeGray(b *testing.B) {
+	benchmarkDecode(b, "testdata/benchGray.png", 1)
+}
+
+func BenchmarkDecodeNRGBAGradient(b *testing.B) {
+	benchmarkDecode(b, "testdata/benchNRGBA-gradient.png", 4)
+}
+
+func BenchmarkDecodeNRGBAOpaque(b *testing.B) {
+	benchmarkDecode(b, "testdata/benchNRGBA-opaque.png", 4)
+}
+
+func BenchmarkDecodePaletted(b *testing.B) {
+	benchmarkDecode(b, "testdata/benchPaletted.png", 1)
+}
+
+func BenchmarkDecodeRGB(b *testing.B) {
+	benchmarkDecode(b, "testdata/benchRGB.png", 4)
+}
+
+func BenchmarkDecodeInterlacing(b *testing.B) {
+	benchmarkDecode(b, "testdata/benchRGB-interlace.png", 4)
+}
diff --git a/src/pkg/image/png/testdata/benchGray.png b/src/image/png/testdata/benchGray.png
similarity index 100%
rename from src/pkg/image/png/testdata/benchGray.png
rename to src/image/png/testdata/benchGray.png
diff --git a/src/pkg/image/png/testdata/benchNRGBA-gradient.png b/src/image/png/testdata/benchNRGBA-gradient.png
similarity index 100%
rename from src/pkg/image/png/testdata/benchNRGBA-gradient.png
rename to src/image/png/testdata/benchNRGBA-gradient.png
diff --git a/src/pkg/image/png/testdata/benchNRGBA-opaque.png b/src/image/png/testdata/benchNRGBA-opaque.png
similarity index 100%
rename from src/pkg/image/png/testdata/benchNRGBA-opaque.png
rename to src/image/png/testdata/benchNRGBA-opaque.png
diff --git a/src/pkg/image/png/testdata/benchPaletted.png b/src/image/png/testdata/benchPaletted.png
similarity index 100%
rename from src/pkg/image/png/testdata/benchPaletted.png
rename to src/image/png/testdata/benchPaletted.png
diff --git a/src/image/png/testdata/benchRGB-interlace.png b/src/image/png/testdata/benchRGB-interlace.png
new file mode 100644
index 0000000..b4b5dab
Binary files /dev/null and b/src/image/png/testdata/benchRGB-interlace.png differ
diff --git a/src/pkg/image/png/testdata/benchRGB.png b/src/image/png/testdata/benchRGB.png
similarity index 100%
rename from src/pkg/image/png/testdata/benchRGB.png
rename to src/image/png/testdata/benchRGB.png
diff --git a/src/pkg/image/png/testdata/invalid-crc32.png b/src/image/png/testdata/invalid-crc32.png
similarity index 100%
rename from src/pkg/image/png/testdata/invalid-crc32.png
rename to src/image/png/testdata/invalid-crc32.png
diff --git a/src/pkg/image/png/testdata/invalid-noend.png b/src/image/png/testdata/invalid-noend.png
similarity index 100%
rename from src/pkg/image/png/testdata/invalid-noend.png
rename to src/image/png/testdata/invalid-noend.png
diff --git a/src/pkg/image/png/testdata/invalid-trunc.png b/src/image/png/testdata/invalid-trunc.png
similarity index 100%
rename from src/pkg/image/png/testdata/invalid-trunc.png
rename to src/image/png/testdata/invalid-trunc.png
diff --git a/src/pkg/image/png/testdata/invalid-zlib.png b/src/image/png/testdata/invalid-zlib.png
similarity index 100%
rename from src/pkg/image/png/testdata/invalid-zlib.png
rename to src/image/png/testdata/invalid-zlib.png
diff --git a/src/pkg/image/png/testdata/pngsuite/README b/src/image/png/testdata/pngsuite/README
similarity index 100%
rename from src/pkg/image/png/testdata/pngsuite/README
rename to src/image/png/testdata/pngsuite/README
diff --git a/src/pkg/image/png/testdata/pngsuite/README.original b/src/image/png/testdata/pngsuite/README.original
similarity index 100%
rename from src/pkg/image/png/testdata/pngsuite/README.original
rename to src/image/png/testdata/pngsuite/README.original
diff --git a/src/pkg/image/png/testdata/pngsuite/basn0g01-30.png b/src/image/png/testdata/pngsuite/basn0g01-30.png
similarity index 100%
rename from src/pkg/image/png/testdata/pngsuite/basn0g01-30.png
rename to src/image/png/testdata/pngsuite/basn0g01-30.png
diff --git a/src/pkg/image/png/testdata/pngsuite/basn0g01-30.sng b/src/image/png/testdata/pngsuite/basn0g01-30.sng
similarity index 100%
rename from src/pkg/image/png/testdata/pngsuite/basn0g01-30.sng
rename to src/image/png/testdata/pngsuite/basn0g01-30.sng
diff --git a/src/pkg/image/png/testdata/pngsuite/basn0g01.png b/src/image/png/testdata/pngsuite/basn0g01.png
similarity index 100%
rename from src/pkg/image/png/testdata/pngsuite/basn0g01.png
rename to src/image/png/testdata/pngsuite/basn0g01.png
diff --git a/src/pkg/image/png/testdata/pngsuite/basn0g01.sng b/src/image/png/testdata/pngsuite/basn0g01.sng
similarity index 100%
rename from src/pkg/image/png/testdata/pngsuite/basn0g01.sng
rename to src/image/png/testdata/pngsuite/basn0g01.sng
diff --git a/src/pkg/image/png/testdata/pngsuite/basn0g02-29.png b/src/image/png/testdata/pngsuite/basn0g02-29.png
similarity index 100%
rename from src/pkg/image/png/testdata/pngsuite/basn0g02-29.png
rename to src/image/png/testdata/pngsuite/basn0g02-29.png
diff --git a/src/pkg/image/png/testdata/pngsuite/basn0g02-29.sng b/src/image/png/testdata/pngsuite/basn0g02-29.sng
similarity index 100%
rename from src/pkg/image/png/testdata/pngsuite/basn0g02-29.sng
rename to src/image/png/testdata/pngsuite/basn0g02-29.sng
diff --git a/src/pkg/image/png/testdata/pngsuite/basn0g02.png b/src/image/png/testdata/pngsuite/basn0g02.png
similarity index 100%
rename from src/pkg/image/png/testdata/pngsuite/basn0g02.png
rename to src/image/png/testdata/pngsuite/basn0g02.png
diff --git a/src/pkg/image/png/testdata/pngsuite/basn0g02.sng b/src/image/png/testdata/pngsuite/basn0g02.sng
similarity index 100%
rename from src/pkg/image/png/testdata/pngsuite/basn0g02.sng
rename to src/image/png/testdata/pngsuite/basn0g02.sng
diff --git a/src/pkg/image/png/testdata/pngsuite/basn0g04-31.png b/src/image/png/testdata/pngsuite/basn0g04-31.png
similarity index 100%
rename from src/pkg/image/png/testdata/pngsuite/basn0g04-31.png
rename to src/image/png/testdata/pngsuite/basn0g04-31.png
diff --git a/src/pkg/image/png/testdata/pngsuite/basn0g04-31.sng b/src/image/png/testdata/pngsuite/basn0g04-31.sng
similarity index 100%
rename from src/pkg/image/png/testdata/pngsuite/basn0g04-31.sng
rename to src/image/png/testdata/pngsuite/basn0g04-31.sng
diff --git a/src/pkg/image/png/testdata/pngsuite/basn0g04.png b/src/image/png/testdata/pngsuite/basn0g04.png
similarity index 100%
rename from src/pkg/image/png/testdata/pngsuite/basn0g04.png
rename to src/image/png/testdata/pngsuite/basn0g04.png
diff --git a/src/pkg/image/png/testdata/pngsuite/basn0g04.sng b/src/image/png/testdata/pngsuite/basn0g04.sng
similarity index 100%
rename from src/pkg/image/png/testdata/pngsuite/basn0g04.sng
rename to src/image/png/testdata/pngsuite/basn0g04.sng
diff --git a/src/pkg/image/png/testdata/pngsuite/basn0g08.png b/src/image/png/testdata/pngsuite/basn0g08.png
similarity index 100%
rename from src/pkg/image/png/testdata/pngsuite/basn0g08.png
rename to src/image/png/testdata/pngsuite/basn0g08.png
diff --git a/src/pkg/image/png/testdata/pngsuite/basn0g08.sng b/src/image/png/testdata/pngsuite/basn0g08.sng
similarity index 100%
rename from src/pkg/image/png/testdata/pngsuite/basn0g08.sng
rename to src/image/png/testdata/pngsuite/basn0g08.sng
diff --git a/src/pkg/image/png/testdata/pngsuite/basn0g16.png b/src/image/png/testdata/pngsuite/basn0g16.png
similarity index 100%
rename from src/pkg/image/png/testdata/pngsuite/basn0g16.png
rename to src/image/png/testdata/pngsuite/basn0g16.png
diff --git a/src/pkg/image/png/testdata/pngsuite/basn0g16.sng b/src/image/png/testdata/pngsuite/basn0g16.sng
similarity index 100%
rename from src/pkg/image/png/testdata/pngsuite/basn0g16.sng
rename to src/image/png/testdata/pngsuite/basn0g16.sng
diff --git a/src/pkg/image/png/testdata/pngsuite/basn2c08.png b/src/image/png/testdata/pngsuite/basn2c08.png
similarity index 100%
rename from src/pkg/image/png/testdata/pngsuite/basn2c08.png
rename to src/image/png/testdata/pngsuite/basn2c08.png
diff --git a/src/pkg/image/png/testdata/pngsuite/basn2c08.sng b/src/image/png/testdata/pngsuite/basn2c08.sng
similarity index 100%
rename from src/pkg/image/png/testdata/pngsuite/basn2c08.sng
rename to src/image/png/testdata/pngsuite/basn2c08.sng
diff --git a/src/pkg/image/png/testdata/pngsuite/basn2c16.png b/src/image/png/testdata/pngsuite/basn2c16.png
similarity index 100%
rename from src/pkg/image/png/testdata/pngsuite/basn2c16.png
rename to src/image/png/testdata/pngsuite/basn2c16.png
diff --git a/src/pkg/image/png/testdata/pngsuite/basn2c16.sng b/src/image/png/testdata/pngsuite/basn2c16.sng
similarity index 100%
rename from src/pkg/image/png/testdata/pngsuite/basn2c16.sng
rename to src/image/png/testdata/pngsuite/basn2c16.sng
diff --git a/src/pkg/image/png/testdata/pngsuite/basn3p01.png b/src/image/png/testdata/pngsuite/basn3p01.png
similarity index 100%
rename from src/pkg/image/png/testdata/pngsuite/basn3p01.png
rename to src/image/png/testdata/pngsuite/basn3p01.png
diff --git a/src/pkg/image/png/testdata/pngsuite/basn3p01.sng b/src/image/png/testdata/pngsuite/basn3p01.sng
similarity index 100%
rename from src/pkg/image/png/testdata/pngsuite/basn3p01.sng
rename to src/image/png/testdata/pngsuite/basn3p01.sng
diff --git a/src/pkg/image/png/testdata/pngsuite/basn3p02.png b/src/image/png/testdata/pngsuite/basn3p02.png
similarity index 100%
rename from src/pkg/image/png/testdata/pngsuite/basn3p02.png
rename to src/image/png/testdata/pngsuite/basn3p02.png
diff --git a/src/pkg/image/png/testdata/pngsuite/basn3p02.sng b/src/image/png/testdata/pngsuite/basn3p02.sng
similarity index 100%
rename from src/pkg/image/png/testdata/pngsuite/basn3p02.sng
rename to src/image/png/testdata/pngsuite/basn3p02.sng
diff --git a/src/image/png/testdata/pngsuite/basn3p04-31i.png b/src/image/png/testdata/pngsuite/basn3p04-31i.png
new file mode 100644
index 0000000..540137c
Binary files /dev/null and b/src/image/png/testdata/pngsuite/basn3p04-31i.png differ
diff --git a/src/image/png/testdata/pngsuite/basn3p04-31i.sng b/src/image/png/testdata/pngsuite/basn3p04-31i.sng
new file mode 100644
index 0000000..31b87c7
--- /dev/null
+++ b/src/image/png/testdata/pngsuite/basn3p04-31i.sng
@@ -0,0 +1,57 @@
+#SNG: from basn3p04-31i.png
+IHDR {
+    width: 31; height: 31; bitdepth: 4;
+    using color palette;
+}
+gAMA {1.0000}
+PLTE {
+    ( 34,  0,255)     # rgb = (0x22,0x00,0xff)
+    (  0,255,255)     # rgb = (0x00,0xff,0xff)
+    (136,  0,255)     # rgb = (0x88,0x00,0xff)
+    ( 34,255,  0)     # rgb = (0x22,0xff,0x00)
+    (  0,153,255)     # rgb = (0x00,0x99,0xff)
+    (255,102,  0)     # rgb = (0xff,0x66,0x00)
+    (221,  0,255)     # rgb = (0xdd,0x00,0xff)
+    (119,255,  0)     # rgb = (0x77,0xff,0x00)
+    (255,  0,  0)     # rgb = (0xff,0x00,0x00)
+    (  0,255,153)     # rgb = (0x00,0xff,0x99)
+    (221,255,  0)     # rgb = (0xdd,0xff,0x00)
+    (255,  0,187)     # rgb = (0xff,0x00,0xbb)
+    (255,187,  0)     # rgb = (0xff,0xbb,0x00)
+    (  0, 68,255)     # rgb = (0x00,0x44,0xff)
+    (  0,255, 68)     # rgb = (0x00,0xff,0x44)
+}
+IMAGE {
+    pixels hex
+88885555ccccaaaa77773333eeee9990
+88885555ccccaaaa77773333eeee9990
+88885555ccccaaaa77773333eeee9990
+88885555ccccaaaa77773333eeee9990
+5555ccccaaaa77773333eeee99991110
+5555ccccaaaa77773333eeee99991110
+5555ccccaaaa77773333eeee99991110
+5555ccccaaaa77773333eeee99991110
+ccccaaaa77773333eeee999911114440
+ccccaaaa77773333eeee999911114440
+ccccaaaa77773333eeee999911114440
+ccccaaaa77773333eeee999911114440
+aaaa77773333eeee999911114444ddd0
+aaaa77773333eeee999911114444ddd0
+aaaa77773333eeee999911114444ddd0
+aaaa77773333eeee999911114444ddd0
+77773333eeee999911114444dddd0000
+77773333eeee999911114444dddd0000
+77773333eeee999911114444dddd0000
+77773333eeee999911114444dddd0000
+3333eeee999911114444dddd00002220
+3333eeee999911114444dddd00002220
+3333eeee999911114444dddd00002220
+3333eeee999911114444dddd00002220
+eeee999911114444dddd000022226660
+eeee999911114444dddd000022226660
+eeee999911114444dddd000022226660
+eeee999911114444dddd000022226660
+999911114444dddd000022226666bbb0
+999911114444dddd000022226666bbb0
+999911114444dddd000022226666bbb0
+}
diff --git a/src/pkg/image/png/testdata/pngsuite/basn3p04.png b/src/image/png/testdata/pngsuite/basn3p04.png
similarity index 100%
rename from src/pkg/image/png/testdata/pngsuite/basn3p04.png
rename to src/image/png/testdata/pngsuite/basn3p04.png
diff --git a/src/pkg/image/png/testdata/pngsuite/basn3p04.sng b/src/image/png/testdata/pngsuite/basn3p04.sng
similarity index 100%
rename from src/pkg/image/png/testdata/pngsuite/basn3p04.sng
rename to src/image/png/testdata/pngsuite/basn3p04.sng
diff --git a/src/pkg/image/png/testdata/pngsuite/basn3p08-trns.png b/src/image/png/testdata/pngsuite/basn3p08-trns.png
similarity index 100%
rename from src/pkg/image/png/testdata/pngsuite/basn3p08-trns.png
rename to src/image/png/testdata/pngsuite/basn3p08-trns.png
diff --git a/src/pkg/image/png/testdata/pngsuite/basn3p08-trns.sng b/src/image/png/testdata/pngsuite/basn3p08-trns.sng
similarity index 100%
rename from src/pkg/image/png/testdata/pngsuite/basn3p08-trns.sng
rename to src/image/png/testdata/pngsuite/basn3p08-trns.sng
diff --git a/src/pkg/image/png/testdata/pngsuite/basn3p08.png b/src/image/png/testdata/pngsuite/basn3p08.png
similarity index 100%
rename from src/pkg/image/png/testdata/pngsuite/basn3p08.png
rename to src/image/png/testdata/pngsuite/basn3p08.png
diff --git a/src/pkg/image/png/testdata/pngsuite/basn3p08.sng b/src/image/png/testdata/pngsuite/basn3p08.sng
similarity index 100%
rename from src/pkg/image/png/testdata/pngsuite/basn3p08.sng
rename to src/image/png/testdata/pngsuite/basn3p08.sng
diff --git a/src/pkg/image/png/testdata/pngsuite/basn4a08.png b/src/image/png/testdata/pngsuite/basn4a08.png
similarity index 100%
rename from src/pkg/image/png/testdata/pngsuite/basn4a08.png
rename to src/image/png/testdata/pngsuite/basn4a08.png
diff --git a/src/pkg/image/png/testdata/pngsuite/basn4a08.sng b/src/image/png/testdata/pngsuite/basn4a08.sng
similarity index 100%
rename from src/pkg/image/png/testdata/pngsuite/basn4a08.sng
rename to src/image/png/testdata/pngsuite/basn4a08.sng
diff --git a/src/pkg/image/png/testdata/pngsuite/basn4a16.png b/src/image/png/testdata/pngsuite/basn4a16.png
similarity index 100%
rename from src/pkg/image/png/testdata/pngsuite/basn4a16.png
rename to src/image/png/testdata/pngsuite/basn4a16.png
diff --git a/src/pkg/image/png/testdata/pngsuite/basn4a16.sng b/src/image/png/testdata/pngsuite/basn4a16.sng
similarity index 100%
rename from src/pkg/image/png/testdata/pngsuite/basn4a16.sng
rename to src/image/png/testdata/pngsuite/basn4a16.sng
diff --git a/src/pkg/image/png/testdata/pngsuite/basn6a08.png b/src/image/png/testdata/pngsuite/basn6a08.png
similarity index 100%
rename from src/pkg/image/png/testdata/pngsuite/basn6a08.png
rename to src/image/png/testdata/pngsuite/basn6a08.png
diff --git a/src/pkg/image/png/testdata/pngsuite/basn6a08.sng b/src/image/png/testdata/pngsuite/basn6a08.sng
similarity index 100%
rename from src/pkg/image/png/testdata/pngsuite/basn6a08.sng
rename to src/image/png/testdata/pngsuite/basn6a08.sng
diff --git a/src/pkg/image/png/testdata/pngsuite/basn6a16.png b/src/image/png/testdata/pngsuite/basn6a16.png
similarity index 100%
rename from src/pkg/image/png/testdata/pngsuite/basn6a16.png
rename to src/image/png/testdata/pngsuite/basn6a16.png
diff --git a/src/pkg/image/png/testdata/pngsuite/basn6a16.sng b/src/image/png/testdata/pngsuite/basn6a16.sng
similarity index 100%
rename from src/pkg/image/png/testdata/pngsuite/basn6a16.sng
rename to src/image/png/testdata/pngsuite/basn6a16.sng
diff --git a/src/image/png/writer.go b/src/image/png/writer.go
new file mode 100644
index 0000000..df23270
--- /dev/null
+++ b/src/image/png/writer.go
@@ -0,0 +1,530 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package png
+
+import (
+	"bufio"
+	"compress/zlib"
+	"hash/crc32"
+	"image"
+	"image/color"
+	"io"
+	"strconv"
+)
+
+// Encoder configures encoding PNG images.
+type Encoder struct {
+	CompressionLevel CompressionLevel
+}
+
+type encoder struct {
+	enc    *Encoder
+	w      io.Writer
+	m      image.Image
+	cb     int
+	err    error
+	header [8]byte
+	footer [4]byte
+	tmp    [4 * 256]byte
+}
+
+type CompressionLevel int
+
+const (
+	DefaultCompression CompressionLevel = 0
+	NoCompression      CompressionLevel = -1
+	BestSpeed          CompressionLevel = -2
+	BestCompression    CompressionLevel = -3
+
+	// Positive CompressionLevel values are reserved to mean a numeric zlib
+	// compression level, although that is not implemented yet.
+)
+
+// Big-endian.
+func writeUint32(b []uint8, u uint32) {
+	b[0] = uint8(u >> 24)
+	b[1] = uint8(u >> 16)
+	b[2] = uint8(u >> 8)
+	b[3] = uint8(u >> 0)
+}
+
+type opaquer interface {
+	Opaque() bool
+}
+
+// Returns whether or not the image is fully opaque.
+func opaque(m image.Image) bool {
+	if o, ok := m.(opaquer); ok {
+		return o.Opaque()
+	}
+	b := m.Bounds()
+	for y := b.Min.Y; y < b.Max.Y; y++ {
+		for x := b.Min.X; x < b.Max.X; x++ {
+			_, _, _, a := m.At(x, y).RGBA()
+			if a != 0xffff {
+				return false
+			}
+		}
+	}
+	return true
+}
+
+// The absolute value of a byte interpreted as a signed int8.
+func abs8(d uint8) int {
+	if d < 128 {
+		return int(d)
+	}
+	return 256 - int(d)
+}
+
+func (e *encoder) writeChunk(b []byte, name string) {
+	if e.err != nil {
+		return
+	}
+	n := uint32(len(b))
+	if int(n) != len(b) {
+		e.err = UnsupportedError(name + " chunk is too large: " + strconv.Itoa(len(b)))
+		return
+	}
+	writeUint32(e.header[:4], n)
+	e.header[4] = name[0]
+	e.header[5] = name[1]
+	e.header[6] = name[2]
+	e.header[7] = name[3]
+	crc := crc32.NewIEEE()
+	crc.Write(e.header[4:8])
+	crc.Write(b)
+	writeUint32(e.footer[:4], crc.Sum32())
+
+	_, e.err = e.w.Write(e.header[:8])
+	if e.err != nil {
+		return
+	}
+	_, e.err = e.w.Write(b)
+	if e.err != nil {
+		return
+	}
+	_, e.err = e.w.Write(e.footer[:4])
+}
+
+func (e *encoder) writeIHDR() {
+	b := e.m.Bounds()
+	writeUint32(e.tmp[0:4], uint32(b.Dx()))
+	writeUint32(e.tmp[4:8], uint32(b.Dy()))
+	// Set bit depth and color type.
+	switch e.cb {
+	case cbG8:
+		e.tmp[8] = 8
+		e.tmp[9] = ctGrayscale
+	case cbTC8:
+		e.tmp[8] = 8
+		e.tmp[9] = ctTrueColor
+	case cbP8:
+		e.tmp[8] = 8
+		e.tmp[9] = ctPaletted
+	case cbTCA8:
+		e.tmp[8] = 8
+		e.tmp[9] = ctTrueColorAlpha
+	case cbG16:
+		e.tmp[8] = 16
+		e.tmp[9] = ctGrayscale
+	case cbTC16:
+		e.tmp[8] = 16
+		e.tmp[9] = ctTrueColor
+	case cbTCA16:
+		e.tmp[8] = 16
+		e.tmp[9] = ctTrueColorAlpha
+	}
+	e.tmp[10] = 0 // default compression method
+	e.tmp[11] = 0 // default filter method
+	e.tmp[12] = 0 // non-interlaced
+	e.writeChunk(e.tmp[:13], "IHDR")
+}
+
+func (e *encoder) writePLTEAndTRNS(p color.Palette) {
+	if len(p) < 1 || len(p) > 256 {
+		e.err = FormatError("bad palette length: " + strconv.Itoa(len(p)))
+		return
+	}
+	last := -1
+	for i, c := range p {
+		c1 := color.NRGBAModel.Convert(c).(color.NRGBA)
+		e.tmp[3*i+0] = c1.R
+		e.tmp[3*i+1] = c1.G
+		e.tmp[3*i+2] = c1.B
+		if c1.A != 0xff {
+			last = i
+		}
+		e.tmp[3*256+i] = c1.A
+	}
+	e.writeChunk(e.tmp[:3*len(p)], "PLTE")
+	if last != -1 {
+		e.writeChunk(e.tmp[3*256:3*256+1+last], "tRNS")
+	}
+}
+
+// An encoder is an io.Writer that satisfies writes by writing PNG IDAT chunks,
+// including an 8-byte header and 4-byte CRC checksum per Write call. Such calls
+// should be relatively infrequent, since writeIDATs uses a bufio.Writer.
+//
+// This method should only be called from writeIDATs (via writeImage).
+// No other code should treat an encoder as an io.Writer.
+func (e *encoder) Write(b []byte) (int, error) {
+	e.writeChunk(b, "IDAT")
+	if e.err != nil {
+		return 0, e.err
+	}
+	return len(b), nil
+}
+
+// Chooses the filter to use for encoding the current row, and applies it.
+// The return value is the index of the filter and also of the row in cr that has had it applied.
+func filter(cr *[nFilter][]byte, pr []byte, bpp int) int {
+	// We try all five filter types, and pick the one that minimizes the sum of absolute differences.
+	// This is the same heuristic that libpng uses, although the filters are attempted in order of
+	// estimated most likely to be minimal (ftUp, ftPaeth, ftNone, ftSub, ftAverage), rather than
+	// in their enumeration order (ftNone, ftSub, ftUp, ftAverage, ftPaeth).
+	cdat0 := cr[0][1:]
+	cdat1 := cr[1][1:]
+	cdat2 := cr[2][1:]
+	cdat3 := cr[3][1:]
+	cdat4 := cr[4][1:]
+	pdat := pr[1:]
+	n := len(cdat0)
+
+	// The up filter.
+	sum := 0
+	for i := 0; i < n; i++ {
+		cdat2[i] = cdat0[i] - pdat[i]
+		sum += abs8(cdat2[i])
+	}
+	best := sum
+	filter := ftUp
+
+	// The Paeth filter.
+	sum = 0
+	for i := 0; i < bpp; i++ {
+		cdat4[i] = cdat0[i] - pdat[i]
+		sum += abs8(cdat4[i])
+	}
+	for i := bpp; i < n; i++ {
+		cdat4[i] = cdat0[i] - paeth(cdat0[i-bpp], pdat[i], pdat[i-bpp])
+		sum += abs8(cdat4[i])
+		if sum >= best {
+			break
+		}
+	}
+	if sum < best {
+		best = sum
+		filter = ftPaeth
+	}
+
+	// The none filter.
+	sum = 0
+	for i := 0; i < n; i++ {
+		sum += abs8(cdat0[i])
+		if sum >= best {
+			break
+		}
+	}
+	if sum < best {
+		best = sum
+		filter = ftNone
+	}
+
+	// The sub filter.
+	sum = 0
+	for i := 0; i < bpp; i++ {
+		cdat1[i] = cdat0[i]
+		sum += abs8(cdat1[i])
+	}
+	for i := bpp; i < n; i++ {
+		cdat1[i] = cdat0[i] - cdat0[i-bpp]
+		sum += abs8(cdat1[i])
+		if sum >= best {
+			break
+		}
+	}
+	if sum < best {
+		best = sum
+		filter = ftSub
+	}
+
+	// The average filter.
+	sum = 0
+	for i := 0; i < bpp; i++ {
+		cdat3[i] = cdat0[i] - pdat[i]/2
+		sum += abs8(cdat3[i])
+	}
+	for i := bpp; i < n; i++ {
+		cdat3[i] = cdat0[i] - uint8((int(cdat0[i-bpp])+int(pdat[i]))/2)
+		sum += abs8(cdat3[i])
+		if sum >= best {
+			break
+		}
+	}
+	if sum < best {
+		best = sum
+		filter = ftAverage
+	}
+
+	return filter
+}
+
+func writeImage(w io.Writer, m image.Image, cb int, level int) error {
+	zw, err := zlib.NewWriterLevel(w, level)
+	if err != nil {
+		return err
+	}
+	defer zw.Close()
+
+	bpp := 0 // Bytes per pixel.
+
+	switch cb {
+	case cbG8:
+		bpp = 1
+	case cbTC8:
+		bpp = 3
+	case cbP8:
+		bpp = 1
+	case cbTCA8:
+		bpp = 4
+	case cbTC16:
+		bpp = 6
+	case cbTCA16:
+		bpp = 8
+	case cbG16:
+		bpp = 2
+	}
+	// cr[*] and pr are the bytes for the current and previous row.
+	// cr[0] is unfiltered (or equivalently, filtered with the ftNone filter).
+	// cr[ft], for non-zero filter types ft, are buffers for transforming cr[0] under the
+	// other PNG filter types. These buffers are allocated once and re-used for each row.
+	// The +1 is for the per-row filter type, which is at cr[*][0].
+	b := m.Bounds()
+	var cr [nFilter][]uint8
+	for i := range cr {
+		cr[i] = make([]uint8, 1+bpp*b.Dx())
+		cr[i][0] = uint8(i)
+	}
+	pr := make([]uint8, 1+bpp*b.Dx())
+
+	gray, _ := m.(*image.Gray)
+	rgba, _ := m.(*image.RGBA)
+	paletted, _ := m.(*image.Paletted)
+	nrgba, _ := m.(*image.NRGBA)
+
+	for y := b.Min.Y; y < b.Max.Y; y++ {
+		// Convert from colors to bytes.
+		i := 1
+		switch cb {
+		case cbG8:
+			if gray != nil {
+				offset := (y - b.Min.Y) * gray.Stride
+				copy(cr[0][1:], gray.Pix[offset:offset+b.Dx()])
+			} else {
+				for x := b.Min.X; x < b.Max.X; x++ {
+					c := color.GrayModel.Convert(m.At(x, y)).(color.Gray)
+					cr[0][i] = c.Y
+					i++
+				}
+			}
+		case cbTC8:
+			// We have previously verified that the alpha value is fully opaque.
+			cr0 := cr[0]
+			stride, pix := 0, []byte(nil)
+			if rgba != nil {
+				stride, pix = rgba.Stride, rgba.Pix
+			} else if nrgba != nil {
+				stride, pix = nrgba.Stride, nrgba.Pix
+			}
+			if stride != 0 {
+				j0 := (y - b.Min.Y) * stride
+				j1 := j0 + b.Dx()*4
+				for j := j0; j < j1; j += 4 {
+					cr0[i+0] = pix[j+0]
+					cr0[i+1] = pix[j+1]
+					cr0[i+2] = pix[j+2]
+					i += 3
+				}
+			} else {
+				for x := b.Min.X; x < b.Max.X; x++ {
+					r, g, b, _ := m.At(x, y).RGBA()
+					cr0[i+0] = uint8(r >> 8)
+					cr0[i+1] = uint8(g >> 8)
+					cr0[i+2] = uint8(b >> 8)
+					i += 3
+				}
+			}
+		case cbP8:
+			if paletted != nil {
+				offset := (y - b.Min.Y) * paletted.Stride
+				copy(cr[0][1:], paletted.Pix[offset:offset+b.Dx()])
+			} else {
+				pi := m.(image.PalettedImage)
+				for x := b.Min.X; x < b.Max.X; x++ {
+					cr[0][i] = pi.ColorIndexAt(x, y)
+					i += 1
+				}
+			}
+		case cbTCA8:
+			if nrgba != nil {
+				offset := (y - b.Min.Y) * nrgba.Stride
+				copy(cr[0][1:], nrgba.Pix[offset:offset+b.Dx()*4])
+			} else {
+				// Convert from image.Image (which is alpha-premultiplied) to PNG's non-alpha-premultiplied.
+				for x := b.Min.X; x < b.Max.X; x++ {
+					c := color.NRGBAModel.Convert(m.At(x, y)).(color.NRGBA)
+					cr[0][i+0] = c.R
+					cr[0][i+1] = c.G
+					cr[0][i+2] = c.B
+					cr[0][i+3] = c.A
+					i += 4
+				}
+			}
+		case cbG16:
+			for x := b.Min.X; x < b.Max.X; x++ {
+				c := color.Gray16Model.Convert(m.At(x, y)).(color.Gray16)
+				cr[0][i+0] = uint8(c.Y >> 8)
+				cr[0][i+1] = uint8(c.Y)
+				i += 2
+			}
+		case cbTC16:
+			// We have previously verified that the alpha value is fully opaque.
+			for x := b.Min.X; x < b.Max.X; x++ {
+				r, g, b, _ := m.At(x, y).RGBA()
+				cr[0][i+0] = uint8(r >> 8)
+				cr[0][i+1] = uint8(r)
+				cr[0][i+2] = uint8(g >> 8)
+				cr[0][i+3] = uint8(g)
+				cr[0][i+4] = uint8(b >> 8)
+				cr[0][i+5] = uint8(b)
+				i += 6
+			}
+		case cbTCA16:
+			// Convert from image.Image (which is alpha-premultiplied) to PNG's non-alpha-premultiplied.
+			for x := b.Min.X; x < b.Max.X; x++ {
+				c := color.NRGBA64Model.Convert(m.At(x, y)).(color.NRGBA64)
+				cr[0][i+0] = uint8(c.R >> 8)
+				cr[0][i+1] = uint8(c.R)
+				cr[0][i+2] = uint8(c.G >> 8)
+				cr[0][i+3] = uint8(c.G)
+				cr[0][i+4] = uint8(c.B >> 8)
+				cr[0][i+5] = uint8(c.B)
+				cr[0][i+6] = uint8(c.A >> 8)
+				cr[0][i+7] = uint8(c.A)
+				i += 8
+			}
+		}
+
+		// Apply the filter.
+		f := ftNone
+		if level != zlib.NoCompression {
+			f = filter(&cr, pr, bpp)
+		}
+
+		// Write the compressed bytes.
+		if _, err := zw.Write(cr[f]); err != nil {
+			return err
+		}
+
+		// The current row for y is the previous row for y+1.
+		pr, cr[0] = cr[0], pr
+	}
+	return nil
+}
+
+// Write the actual image data to one or more IDAT chunks.
+func (e *encoder) writeIDATs() {
+	if e.err != nil {
+		return
+	}
+	var bw *bufio.Writer
+	bw = bufio.NewWriterSize(e, 1<<15)
+	e.err = writeImage(bw, e.m, e.cb, levelToZlib(e.enc.CompressionLevel))
+	if e.err != nil {
+		return
+	}
+	e.err = bw.Flush()
+}
+
+// This function is required because we want the zero value of
+// Encoder.CompressionLevel to map to zlib.DefaultCompression.
+func levelToZlib(l CompressionLevel) int {
+	switch l {
+	case DefaultCompression:
+		return zlib.DefaultCompression
+	case NoCompression:
+		return zlib.NoCompression
+	case BestSpeed:
+		return zlib.BestSpeed
+	case BestCompression:
+		return zlib.BestCompression
+	default:
+		return zlib.DefaultCompression
+	}
+}
+
+func (e *encoder) writeIEND() { e.writeChunk(nil, "IEND") }
+
+// Encode writes the Image m to w in PNG format. Any Image may be
+// encoded, but images that are not image.NRGBA might be encoded lossily.
+func Encode(w io.Writer, m image.Image) error {
+	var e Encoder
+	return e.Encode(w, m)
+}
+
+// Encode writes the Image m to w in PNG format.
+func (enc *Encoder) Encode(w io.Writer, m image.Image) error {
+	// Obviously, negative widths and heights are invalid. Furthermore, the PNG
+	// spec section 11.2.2 says that zero is invalid. Excessively large images are
+	// also rejected.
+	mw, mh := int64(m.Bounds().Dx()), int64(m.Bounds().Dy())
+	if mw <= 0 || mh <= 0 || mw >= 1<<32 || mh >= 1<<32 {
+		return FormatError("invalid image size: " + strconv.FormatInt(mw, 10) + "x" + strconv.FormatInt(mh, 10))
+	}
+
+	var e encoder
+	e.enc = enc
+	e.w = w
+	e.m = m
+
+	var pal color.Palette
+	// cbP8 encoding needs PalettedImage's ColorIndexAt method.
+	if _, ok := m.(image.PalettedImage); ok {
+		pal, _ = m.ColorModel().(color.Palette)
+	}
+	if pal != nil {
+		e.cb = cbP8
+	} else {
+		switch m.ColorModel() {
+		case color.GrayModel:
+			e.cb = cbG8
+		case color.Gray16Model:
+			e.cb = cbG16
+		case color.RGBAModel, color.NRGBAModel, color.AlphaModel:
+			if opaque(m) {
+				e.cb = cbTC8
+			} else {
+				e.cb = cbTCA8
+			}
+		default:
+			if opaque(m) {
+				e.cb = cbTC16
+			} else {
+				e.cb = cbTCA16
+			}
+		}
+	}
+
+	_, e.err = io.WriteString(w, pngHeader)
+	e.writeIHDR()
+	if pal != nil {
+		e.writePLTEAndTRNS(pal)
+	}
+	e.writeIDATs()
+	e.writeIEND()
+	return e.err
+}
diff --git a/src/image/png/writer_test.go b/src/image/png/writer_test.go
new file mode 100644
index 0000000..d67a815
--- /dev/null
+++ b/src/image/png/writer_test.go
@@ -0,0 +1,210 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package png
+
+import (
+	"bytes"
+	"fmt"
+	"image"
+	"image/color"
+	"io/ioutil"
+	"testing"
+)
+
+func diff(m0, m1 image.Image) error {
+	b0, b1 := m0.Bounds(), m1.Bounds()
+	if !b0.Size().Eq(b1.Size()) {
+		return fmt.Errorf("dimensions differ: %v vs %v", b0, b1)
+	}
+	dx := b1.Min.X - b0.Min.X
+	dy := b1.Min.Y - b0.Min.Y
+	for y := b0.Min.Y; y < b0.Max.Y; y++ {
+		for x := b0.Min.X; x < b0.Max.X; x++ {
+			c0 := m0.At(x, y)
+			c1 := m1.At(x+dx, y+dy)
+			r0, g0, b0, a0 := c0.RGBA()
+			r1, g1, b1, a1 := c1.RGBA()
+			if r0 != r1 || g0 != g1 || b0 != b1 || a0 != a1 {
+				return fmt.Errorf("colors differ at (%d, %d): %v vs %v", x, y, c0, c1)
+			}
+		}
+	}
+	return nil
+}
+
+func encodeDecode(m image.Image) (image.Image, error) {
+	var b bytes.Buffer
+	err := Encode(&b, m)
+	if err != nil {
+		return nil, err
+	}
+	return Decode(&b)
+}
+
+func TestWriter(t *testing.T) {
+	// The filenames variable is declared in reader_test.go.
+	names := filenames
+	if testing.Short() {
+		names = filenamesShort
+	}
+	for _, fn := range names {
+		qfn := "testdata/pngsuite/" + fn + ".png"
+		// Read the image.
+		m0, err := readPNG(qfn)
+		if err != nil {
+			t.Error(fn, err)
+			continue
+		}
+		// Read the image again, encode it, and decode it.
+		m1, err := readPNG(qfn)
+		if err != nil {
+			t.Error(fn, err)
+			return
+		}
+		m2, err := encodeDecode(m1)
+		if err != nil {
+			t.Error(fn, err)
+			return
+		}
+		// Compare the two.
+		err = diff(m0, m2)
+		if err != nil {
+			t.Error(fn, err)
+			continue
+		}
+	}
+}
+
+func TestWriterLevels(t *testing.T) {
+	m := image.NewNRGBA(image.Rect(0, 0, 100, 100))
+
+	var b1, b2 bytes.Buffer
+	if err := (&Encoder{}).Encode(&b1, m); err != nil {
+		t.Fatal(err)
+	}
+	noenc := &Encoder{CompressionLevel: NoCompression}
+	if err := noenc.Encode(&b2, m); err != nil {
+		t.Fatal(err)
+	}
+
+	if b2.Len() <= b1.Len() {
+		t.Error("DefaultCompression encoding was larger than NoCompression encoding")
+	}
+	if _, err := Decode(&b1); err != nil {
+		t.Error("cannot decode DefaultCompression")
+	}
+	if _, err := Decode(&b2); err != nil {
+		t.Error("cannot decode NoCompression")
+	}
+}
+
+func TestSubImage(t *testing.T) {
+	m0 := image.NewRGBA(image.Rect(0, 0, 256, 256))
+	for y := 0; y < 256; y++ {
+		for x := 0; x < 256; x++ {
+			m0.Set(x, y, color.RGBA{uint8(x), uint8(y), 0, 255})
+		}
+	}
+	m0 = m0.SubImage(image.Rect(50, 30, 250, 130)).(*image.RGBA)
+	m1, err := encodeDecode(m0)
+	if err != nil {
+		t.Error(err)
+		return
+	}
+	err = diff(m0, m1)
+	if err != nil {
+		t.Error(err)
+		return
+	}
+}
+
+func BenchmarkEncodeGray(b *testing.B) {
+	b.StopTimer()
+	img := image.NewGray(image.Rect(0, 0, 640, 480))
+	b.SetBytes(640 * 480 * 1)
+	b.StartTimer()
+	for i := 0; i < b.N; i++ {
+		Encode(ioutil.Discard, img)
+	}
+}
+
+func BenchmarkEncodeNRGBOpaque(b *testing.B) {
+	b.StopTimer()
+	img := image.NewNRGBA(image.Rect(0, 0, 640, 480))
+	// Set all pixels to 0xFF alpha to force opaque mode.
+	bo := img.Bounds()
+	for y := bo.Min.Y; y < bo.Max.Y; y++ {
+		for x := bo.Min.X; x < bo.Max.X; x++ {
+			img.Set(x, y, color.NRGBA{0, 0, 0, 255})
+		}
+	}
+	if !img.Opaque() {
+		b.Fatal("expected image to be opaque")
+	}
+	b.SetBytes(640 * 480 * 4)
+	b.StartTimer()
+	for i := 0; i < b.N; i++ {
+		Encode(ioutil.Discard, img)
+	}
+}
+
+func BenchmarkEncodeNRGBA(b *testing.B) {
+	b.StopTimer()
+	img := image.NewNRGBA(image.Rect(0, 0, 640, 480))
+	if img.Opaque() {
+		b.Fatal("expected image not to be opaque")
+	}
+	b.SetBytes(640 * 480 * 4)
+	b.StartTimer()
+	for i := 0; i < b.N; i++ {
+		Encode(ioutil.Discard, img)
+	}
+}
+
+func BenchmarkEncodePaletted(b *testing.B) {
+	b.StopTimer()
+	img := image.NewPaletted(image.Rect(0, 0, 640, 480), color.Palette{
+		color.RGBA{0, 0, 0, 255},
+		color.RGBA{255, 255, 255, 255},
+	})
+	b.SetBytes(640 * 480 * 1)
+	b.StartTimer()
+	for i := 0; i < b.N; i++ {
+		Encode(ioutil.Discard, img)
+	}
+}
+
+func BenchmarkEncodeRGBOpaque(b *testing.B) {
+	b.StopTimer()
+	img := image.NewRGBA(image.Rect(0, 0, 640, 480))
+	// Set all pixels to 0xFF alpha to force opaque mode.
+	bo := img.Bounds()
+	for y := bo.Min.Y; y < bo.Max.Y; y++ {
+		for x := bo.Min.X; x < bo.Max.X; x++ {
+			img.Set(x, y, color.RGBA{0, 0, 0, 255})
+		}
+	}
+	if !img.Opaque() {
+		b.Fatal("expected image to be opaque")
+	}
+	b.SetBytes(640 * 480 * 4)
+	b.StartTimer()
+	for i := 0; i < b.N; i++ {
+		Encode(ioutil.Discard, img)
+	}
+}
+
+func BenchmarkEncodeRGBA(b *testing.B) {
+	b.StopTimer()
+	img := image.NewRGBA(image.Rect(0, 0, 640, 480))
+	if img.Opaque() {
+		b.Fatal("expected image not to be opaque")
+	}
+	b.SetBytes(640 * 480 * 4)
+	b.StartTimer()
+	for i := 0; i < b.N; i++ {
+		Encode(ioutil.Discard, img)
+	}
+}
diff --git a/src/pkg/image/testdata/video-001.5bpp.gif b/src/image/testdata/video-001.5bpp.gif
similarity index 100%
rename from src/pkg/image/testdata/video-001.5bpp.gif
rename to src/image/testdata/video-001.5bpp.gif
diff --git a/src/pkg/image/testdata/video-001.gif b/src/image/testdata/video-001.gif
similarity index 100%
rename from src/pkg/image/testdata/video-001.gif
rename to src/image/testdata/video-001.gif
diff --git a/src/pkg/image/testdata/video-001.interlaced.gif b/src/image/testdata/video-001.interlaced.gif
similarity index 100%
rename from src/pkg/image/testdata/video-001.interlaced.gif
rename to src/image/testdata/video-001.interlaced.gif
diff --git a/src/pkg/image/testdata/video-001.jpeg b/src/image/testdata/video-001.jpeg
similarity index 100%
rename from src/pkg/image/testdata/video-001.jpeg
rename to src/image/testdata/video-001.jpeg
diff --git a/src/pkg/image/testdata/video-001.png b/src/image/testdata/video-001.png
similarity index 100%
rename from src/pkg/image/testdata/video-001.png
rename to src/image/testdata/video-001.png
diff --git a/src/pkg/image/testdata/video-001.progressive.jpeg b/src/image/testdata/video-001.progressive.jpeg
similarity index 100%
rename from src/pkg/image/testdata/video-001.progressive.jpeg
rename to src/image/testdata/video-001.progressive.jpeg
diff --git a/src/pkg/image/testdata/video-001.q50.420.jpeg b/src/image/testdata/video-001.q50.420.jpeg
similarity index 100%
rename from src/pkg/image/testdata/video-001.q50.420.jpeg
rename to src/image/testdata/video-001.q50.420.jpeg
diff --git a/src/pkg/image/testdata/video-001.q50.420.progressive.jpeg b/src/image/testdata/video-001.q50.420.progressive.jpeg
similarity index 100%
rename from src/pkg/image/testdata/video-001.q50.420.progressive.jpeg
rename to src/image/testdata/video-001.q50.420.progressive.jpeg
diff --git a/src/pkg/image/testdata/video-001.q50.422.jpeg b/src/image/testdata/video-001.q50.422.jpeg
similarity index 100%
rename from src/pkg/image/testdata/video-001.q50.422.jpeg
rename to src/image/testdata/video-001.q50.422.jpeg
diff --git a/src/pkg/image/testdata/video-001.q50.422.progressive.jpeg b/src/image/testdata/video-001.q50.422.progressive.jpeg
similarity index 100%
rename from src/pkg/image/testdata/video-001.q50.422.progressive.jpeg
rename to src/image/testdata/video-001.q50.422.progressive.jpeg
diff --git a/src/pkg/image/testdata/video-001.q50.440.jpeg b/src/image/testdata/video-001.q50.440.jpeg
similarity index 100%
rename from src/pkg/image/testdata/video-001.q50.440.jpeg
rename to src/image/testdata/video-001.q50.440.jpeg
diff --git a/src/pkg/image/testdata/video-001.q50.440.progressive.jpeg b/src/image/testdata/video-001.q50.440.progressive.jpeg
similarity index 100%
rename from src/pkg/image/testdata/video-001.q50.440.progressive.jpeg
rename to src/image/testdata/video-001.q50.440.progressive.jpeg
diff --git a/src/pkg/image/testdata/video-001.q50.444.jpeg b/src/image/testdata/video-001.q50.444.jpeg
similarity index 100%
rename from src/pkg/image/testdata/video-001.q50.444.jpeg
rename to src/image/testdata/video-001.q50.444.jpeg
diff --git a/src/pkg/image/testdata/video-001.q50.444.progressive.jpeg b/src/image/testdata/video-001.q50.444.progressive.jpeg
similarity index 100%
rename from src/pkg/image/testdata/video-001.q50.444.progressive.jpeg
rename to src/image/testdata/video-001.q50.444.progressive.jpeg
diff --git a/src/pkg/image/testdata/video-001.separate.dc.progression.jpeg b/src/image/testdata/video-001.separate.dc.progression.jpeg
similarity index 100%
rename from src/pkg/image/testdata/video-001.separate.dc.progression.jpeg
rename to src/image/testdata/video-001.separate.dc.progression.jpeg
diff --git a/src/pkg/image/testdata/video-001.separate.dc.progression.progressive.jpeg b/src/image/testdata/video-001.separate.dc.progression.progressive.jpeg
similarity index 100%
rename from src/pkg/image/testdata/video-001.separate.dc.progression.progressive.jpeg
rename to src/image/testdata/video-001.separate.dc.progression.progressive.jpeg
diff --git a/src/pkg/image/testdata/video-005.gray.gif b/src/image/testdata/video-005.gray.gif
similarity index 100%
rename from src/pkg/image/testdata/video-005.gray.gif
rename to src/image/testdata/video-005.gray.gif
diff --git a/src/pkg/image/testdata/video-005.gray.jpeg b/src/image/testdata/video-005.gray.jpeg
similarity index 100%
rename from src/pkg/image/testdata/video-005.gray.jpeg
rename to src/image/testdata/video-005.gray.jpeg
diff --git a/src/pkg/image/testdata/video-005.gray.png b/src/image/testdata/video-005.gray.png
similarity index 100%
rename from src/pkg/image/testdata/video-005.gray.png
rename to src/image/testdata/video-005.gray.png
diff --git a/src/pkg/image/testdata/video-005.gray.q50.2x2.jpeg b/src/image/testdata/video-005.gray.q50.2x2.jpeg
similarity index 100%
rename from src/pkg/image/testdata/video-005.gray.q50.2x2.jpeg
rename to src/image/testdata/video-005.gray.q50.2x2.jpeg
diff --git a/src/pkg/image/testdata/video-005.gray.q50.2x2.progressive.jpeg b/src/image/testdata/video-005.gray.q50.2x2.progressive.jpeg
similarity index 100%
rename from src/pkg/image/testdata/video-005.gray.q50.2x2.progressive.jpeg
rename to src/image/testdata/video-005.gray.q50.2x2.progressive.jpeg
diff --git a/src/pkg/image/testdata/video-005.gray.q50.jpeg b/src/image/testdata/video-005.gray.q50.jpeg
similarity index 100%
rename from src/pkg/image/testdata/video-005.gray.q50.jpeg
rename to src/image/testdata/video-005.gray.q50.jpeg
diff --git a/src/pkg/image/testdata/video-005.gray.q50.progressive.jpeg b/src/image/testdata/video-005.gray.q50.progressive.jpeg
similarity index 100%
rename from src/pkg/image/testdata/video-005.gray.q50.progressive.jpeg
rename to src/image/testdata/video-005.gray.q50.progressive.jpeg
diff --git a/src/image/ycbcr.go b/src/image/ycbcr.go
new file mode 100644
index 0000000..7c773f2
--- /dev/null
+++ b/src/image/ycbcr.go
@@ -0,0 +1,157 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package image
+
+import (
+	"image/color"
+)
+
+// YCbCrSubsampleRatio is the chroma subsample ratio used in a YCbCr image.
+type YCbCrSubsampleRatio int
+
+const (
+	YCbCrSubsampleRatio444 YCbCrSubsampleRatio = iota
+	YCbCrSubsampleRatio422
+	YCbCrSubsampleRatio420
+	YCbCrSubsampleRatio440
+)
+
+func (s YCbCrSubsampleRatio) String() string {
+	switch s {
+	case YCbCrSubsampleRatio444:
+		return "YCbCrSubsampleRatio444"
+	case YCbCrSubsampleRatio422:
+		return "YCbCrSubsampleRatio422"
+	case YCbCrSubsampleRatio420:
+		return "YCbCrSubsampleRatio420"
+	case YCbCrSubsampleRatio440:
+		return "YCbCrSubsampleRatio440"
+	}
+	return "YCbCrSubsampleRatioUnknown"
+}
+
+// YCbCr is an in-memory image of Y'CbCr colors. There is one Y sample per
+// pixel, but each Cb and Cr sample can span one or more pixels.
+// YStride is the Y slice index delta between vertically adjacent pixels.
+// CStride is the Cb and Cr slice index delta between vertically adjacent pixels
+// that map to separate chroma samples.
+// It is not an absolute requirement, but YStride and len(Y) are typically
+// multiples of 8, and:
+//	For 4:4:4, CStride == YStride/1 && len(Cb) == len(Cr) == len(Y)/1.
+//	For 4:2:2, CStride == YStride/2 && len(Cb) == len(Cr) == len(Y)/2.
+//	For 4:2:0, CStride == YStride/2 && len(Cb) == len(Cr) == len(Y)/4.
+//	For 4:4:0, CStride == YStride/1 && len(Cb) == len(Cr) == len(Y)/2.
+type YCbCr struct {
+	Y, Cb, Cr      []uint8
+	YStride        int
+	CStride        int
+	SubsampleRatio YCbCrSubsampleRatio
+	Rect           Rectangle
+}
+
+func (p *YCbCr) ColorModel() color.Model {
+	return color.YCbCrModel
+}
+
+func (p *YCbCr) Bounds() Rectangle {
+	return p.Rect
+}
+
+func (p *YCbCr) At(x, y int) color.Color {
+	return p.YCbCrAt(x, y)
+}
+
+func (p *YCbCr) YCbCrAt(x, y int) color.YCbCr {
+	if !(Point{x, y}.In(p.Rect)) {
+		return color.YCbCr{}
+	}
+	yi := p.YOffset(x, y)
+	ci := p.COffset(x, y)
+	return color.YCbCr{
+		p.Y[yi],
+		p.Cb[ci],
+		p.Cr[ci],
+	}
+}
+
+// YOffset returns the index of the first element of Y that corresponds to
+// the pixel at (x, y).
+func (p *YCbCr) YOffset(x, y int) int {
+	return (y-p.Rect.Min.Y)*p.YStride + (x - p.Rect.Min.X)
+}
+
+// COffset returns the index of the first element of Cb or Cr that corresponds
+// to the pixel at (x, y).
+func (p *YCbCr) COffset(x, y int) int {
+	switch p.SubsampleRatio {
+	case YCbCrSubsampleRatio422:
+		return (y-p.Rect.Min.Y)*p.CStride + (x/2 - p.Rect.Min.X/2)
+	case YCbCrSubsampleRatio420:
+		return (y/2-p.Rect.Min.Y/2)*p.CStride + (x/2 - p.Rect.Min.X/2)
+	case YCbCrSubsampleRatio440:
+		return (y/2-p.Rect.Min.Y/2)*p.CStride + (x - p.Rect.Min.X)
+	}
+	// Default to 4:4:4 subsampling.
+	return (y-p.Rect.Min.Y)*p.CStride + (x - p.Rect.Min.X)
+}
+
+// SubImage returns an image representing the portion of the image p visible
+// through r. The returned value shares pixels with the original image.
+func (p *YCbCr) SubImage(r Rectangle) Image {
+	r = r.Intersect(p.Rect)
+	// If r1 and r2 are Rectangles, r1.Intersect(r2) is not guaranteed to be inside
+	// either r1 or r2 if the intersection is empty. Without explicitly checking for
+	// this, the Pix[i:] expression below can panic.
+	if r.Empty() {
+		return &YCbCr{
+			SubsampleRatio: p.SubsampleRatio,
+		}
+	}
+	yi := p.YOffset(r.Min.X, r.Min.Y)
+	ci := p.COffset(r.Min.X, r.Min.Y)
+	return &YCbCr{
+		Y:              p.Y[yi:],
+		Cb:             p.Cb[ci:],
+		Cr:             p.Cr[ci:],
+		SubsampleRatio: p.SubsampleRatio,
+		YStride:        p.YStride,
+		CStride:        p.CStride,
+		Rect:           r,
+	}
+}
+
+func (p *YCbCr) Opaque() bool {
+	return true
+}
+
+// NewYCbCr returns a new YCbCr with the given bounds and subsample ratio.
+func NewYCbCr(r Rectangle, subsampleRatio YCbCrSubsampleRatio) *YCbCr {
+	w, h, cw, ch := r.Dx(), r.Dy(), 0, 0
+	switch subsampleRatio {
+	case YCbCrSubsampleRatio422:
+		cw = (r.Max.X+1)/2 - r.Min.X/2
+		ch = h
+	case YCbCrSubsampleRatio420:
+		cw = (r.Max.X+1)/2 - r.Min.X/2
+		ch = (r.Max.Y+1)/2 - r.Min.Y/2
+	case YCbCrSubsampleRatio440:
+		cw = w
+		ch = (r.Max.Y+1)/2 - r.Min.Y/2
+	default:
+		// Default to 4:4:4 subsampling.
+		cw = w
+		ch = h
+	}
+	b := make([]byte, w*h+2*cw*ch)
+	return &YCbCr{
+		Y:              b[:w*h],
+		Cb:             b[w*h+0*cw*ch : w*h+1*cw*ch],
+		Cr:             b[w*h+1*cw*ch : w*h+2*cw*ch],
+		SubsampleRatio: subsampleRatio,
+		YStride:        w,
+		CStride:        cw,
+		Rect:           r,
+	}
+}
diff --git a/src/pkg/image/ycbcr_test.go b/src/image/ycbcr_test.go
similarity index 100%
rename from src/pkg/image/ycbcr_test.go
rename to src/image/ycbcr_test.go
diff --git a/src/pkg/index/suffixarray/qsufsort.go b/src/index/suffixarray/qsufsort.go
similarity index 100%
rename from src/pkg/index/suffixarray/qsufsort.go
rename to src/index/suffixarray/qsufsort.go
diff --git a/src/pkg/index/suffixarray/suffixarray.go b/src/index/suffixarray/suffixarray.go
similarity index 100%
rename from src/pkg/index/suffixarray/suffixarray.go
rename to src/index/suffixarray/suffixarray.go
diff --git a/src/index/suffixarray/suffixarray_test.go b/src/index/suffixarray/suffixarray_test.go
new file mode 100644
index 0000000..644f00c
--- /dev/null
+++ b/src/index/suffixarray/suffixarray_test.go
@@ -0,0 +1,304 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package suffixarray
+
+import (
+	"bytes"
+	"math/rand"
+	"regexp"
+	"sort"
+	"strings"
+	"testing"
+)
+
+type testCase struct {
+	name     string   // name of test case
+	source   string   // source to index
+	patterns []string // patterns to lookup
+}
+
+var testCases = []testCase{
+	{
+		"empty string",
+		"",
+		[]string{
+			"",
+			"foo",
+			"(foo)",
+			".*",
+			"a*",
+		},
+	},
+
+	{
+		"all a's",
+		"aaaaaaaaaa", // 10 a's
+		[]string{
+			"",
+			"a",
+			"aa",
+			"aaa",
+			"aaaa",
+			"aaaaa",
+			"aaaaaa",
+			"aaaaaaa",
+			"aaaaaaaa",
+			"aaaaaaaaa",
+			"aaaaaaaaaa",
+			"aaaaaaaaaaa", // 11 a's
+			".",
+			".*",
+			"a+",
+			"aa+",
+			"aaaa[b]?",
+			"aaa*",
+		},
+	},
+
+	{
+		"abc",
+		"abc",
+		[]string{
+			"a",
+			"b",
+			"c",
+			"ab",
+			"bc",
+			"abc",
+			"a.c",
+			"a(b|c)",
+			"abc?",
+		},
+	},
+
+	{
+		"barbara*3",
+		"barbarabarbarabarbara",
+		[]string{
+			"a",
+			"bar",
+			"rab",
+			"arab",
+			"barbar",
+			"bara?bar",
+		},
+	},
+
+	{
+		"typing drill",
+		"Now is the time for all good men to come to the aid of their country.",
+		[]string{
+			"Now",
+			"the time",
+			"to come the aid",
+			"is the time for all good men to come to the aid of their",
+			"to (come|the)?",
+		},
+	},
+
+	{
+		"godoc simulation",
+		"package main\n\nimport(\n    \"rand\"\n    ",
+		[]string{},
+	},
+}
+
+// find all occurrences of s in source; report at most n occurrences
+func find(src, s string, n int) []int {
+	var res []int
+	if s != "" && n != 0 {
+		// find at most n occurrences of s in src
+		for i := -1; n < 0 || len(res) < n; {
+			j := strings.Index(src[i+1:], s)
+			if j < 0 {
+				break
+			}
+			i += j + 1
+			res = append(res, i)
+		}
+	}
+	return res
+}
+
+func testLookup(t *testing.T, tc *testCase, x *Index, s string, n int) {
+	res := x.Lookup([]byte(s), n)
+	exp := find(tc.source, s, n)
+
+	// check that the lengths match
+	if len(res) != len(exp) {
+		t.Errorf("test %q, lookup %q (n = %d): expected %d results; got %d", tc.name, s, n, len(exp), len(res))
+	}
+
+	// if n >= 0 the number of results is limited --- unless n >= all results,
+	// we may obtain different positions from the Index and from find (because
+	// Index may not find the results in the same order as find) => in general
+	// we cannot simply check that the res and exp lists are equal
+
+	// check that each result is in fact a correct match and there are no duplicates
+	sort.Ints(res)
+	for i, r := range res {
+		if r < 0 || len(tc.source) <= r {
+			t.Errorf("test %q, lookup %q, result %d (n = %d): index %d out of range [0, %d[", tc.name, s, i, n, r, len(tc.source))
+		} else if !strings.HasPrefix(tc.source[r:], s) {
+			t.Errorf("test %q, lookup %q, result %d (n = %d): index %d not a match", tc.name, s, i, n, r)
+		}
+		if i > 0 && res[i-1] == r {
+			t.Errorf("test %q, lookup %q, result %d (n = %d): found duplicate index %d", tc.name, s, i, n, r)
+		}
+	}
+
+	if n < 0 {
+		// all results computed - sorted res and exp must be equal
+		for i, r := range res {
+			e := exp[i]
+			if r != e {
+				t.Errorf("test %q, lookup %q, result %d: expected index %d; got %d", tc.name, s, i, e, r)
+			}
+		}
+	}
+}
+
+func testFindAllIndex(t *testing.T, tc *testCase, x *Index, rx *regexp.Regexp, n int) {
+	res := x.FindAllIndex(rx, n)
+	exp := rx.FindAllStringIndex(tc.source, n)
+
+	// check that the lengths match
+	if len(res) != len(exp) {
+		t.Errorf("test %q, FindAllIndex %q (n = %d): expected %d results; got %d", tc.name, rx, n, len(exp), len(res))
+	}
+
+	// if n >= 0 the number of results is limited --- unless n >= all results,
+	// we may obtain different positions from the Index and from regexp (because
+	// Index may not find the results in the same order as regexp) => in general
+	// we cannot simply check that the res and exp lists are equal
+
+	// check that each result is in fact a correct match and the result is sorted
+	for i, r := range res {
+		if r[0] < 0 || r[0] > r[1] || len(tc.source) < r[1] {
+			t.Errorf("test %q, FindAllIndex %q, result %d (n == %d): illegal match [%d, %d]", tc.name, rx, i, n, r[0], r[1])
+		} else if !rx.MatchString(tc.source[r[0]:r[1]]) {
+			t.Errorf("test %q, FindAllIndex %q, result %d (n = %d): [%d, %d] not a match", tc.name, rx, i, n, r[0], r[1])
+		}
+	}
+
+	if n < 0 {
+		// all results computed - sorted res and exp must be equal
+		for i, r := range res {
+			e := exp[i]
+			if r[0] != e[0] || r[1] != e[1] {
+				t.Errorf("test %q, FindAllIndex %q, result %d: expected match [%d, %d]; got [%d, %d]",
+					tc.name, rx, i, e[0], e[1], r[0], r[1])
+			}
+		}
+	}
+}
+
+func testLookups(t *testing.T, tc *testCase, x *Index, n int) {
+	for _, pat := range tc.patterns {
+		testLookup(t, tc, x, pat, n)
+		if rx, err := regexp.Compile(pat); err == nil {
+			testFindAllIndex(t, tc, x, rx, n)
+		}
+	}
+}
+
+// index is used to hide the sort.Interface
+type index Index
+
+func (x *index) Len() int           { return len(x.sa) }
+func (x *index) Less(i, j int) bool { return bytes.Compare(x.at(i), x.at(j)) < 0 }
+func (x *index) Swap(i, j int)      { x.sa[i], x.sa[j] = x.sa[j], x.sa[i] }
+func (a *index) at(i int) []byte    { return a.data[a.sa[i]:] }
+
+func testConstruction(t *testing.T, tc *testCase, x *Index) {
+	if !sort.IsSorted((*index)(x)) {
+		t.Errorf("failed testConstruction %s", tc.name)
+	}
+}
+
+func equal(x, y *Index) bool {
+	if !bytes.Equal(x.data, y.data) {
+		return false
+	}
+	for i, j := range x.sa {
+		if j != y.sa[i] {
+			return false
+		}
+	}
+	return true
+}
+
+// returns the serialized index size
+func testSaveRestore(t *testing.T, tc *testCase, x *Index) int {
+	var buf bytes.Buffer
+	if err := x.Write(&buf); err != nil {
+		t.Errorf("failed writing index %s (%s)", tc.name, err)
+	}
+	size := buf.Len()
+	var y Index
+	if err := y.Read(&buf); err != nil {
+		t.Errorf("failed reading index %s (%s)", tc.name, err)
+	}
+	if !equal(x, &y) {
+		t.Errorf("restored index doesn't match saved index %s", tc.name)
+	}
+	return size
+}
+
+func TestIndex(t *testing.T) {
+	for _, tc := range testCases {
+		x := New([]byte(tc.source))
+		testConstruction(t, &tc, x)
+		testSaveRestore(t, &tc, x)
+		testLookups(t, &tc, x, 0)
+		testLookups(t, &tc, x, 1)
+		testLookups(t, &tc, x, 10)
+		testLookups(t, &tc, x, 2e9)
+		testLookups(t, &tc, x, -1)
+	}
+}
+
+// Of all possible inputs, the random bytes have the least amount of substring
+// repetition, and the repeated bytes have the most. For most algorithms,
+// the running time of every input will be between these two.
+func benchmarkNew(b *testing.B, random bool) {
+	b.StopTimer()
+	data := make([]byte, 1e6)
+	if random {
+		for i := range data {
+			data[i] = byte(rand.Intn(256))
+		}
+	}
+	b.StartTimer()
+	for i := 0; i < b.N; i++ {
+		New(data)
+	}
+}
+
+func BenchmarkNewIndexRandom(b *testing.B) {
+	benchmarkNew(b, true)
+}
+func BenchmarkNewIndexRepeat(b *testing.B) {
+	benchmarkNew(b, false)
+}
+
+func BenchmarkSaveRestore(b *testing.B) {
+	b.StopTimer()
+	r := rand.New(rand.NewSource(0x5a77a1)) // guarantee always same sequence
+	data := make([]byte, 1<<20)             // 1MB of data to index
+	for i := range data {
+		data[i] = byte(r.Intn(256))
+	}
+	x := New(data)
+	size := testSaveRestore(nil, nil, x)       // verify correctness
+	buf := bytes.NewBuffer(make([]byte, size)) // avoid growing
+	b.SetBytes(int64(size))
+	b.StartTimer()
+	for i := 0; i < b.N; i++ {
+		x.Write(buf)
+		var y Index
+		y.Read(buf)
+	}
+}
diff --git a/src/internal/syscall/getrandom_linux.go b/src/internal/syscall/getrandom_linux.go
new file mode 100644
index 0000000..944bab3
--- /dev/null
+++ b/src/internal/syscall/getrandom_linux.go
@@ -0,0 +1,56 @@
+// Copyright 2014 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package syscall
+
+import (
+	"runtime"
+	"sync/atomic"
+	stdsyscall "syscall"
+	"unsafe"
+)
+
+var randomTrap = map[string]uintptr{
+	"386":   355,
+	"amd64": 318,
+	"arm":   384,
+}[runtime.GOARCH]
+
+var randomUnsupported int32 // atomic
+
+// GetRandomFlag is a flag supported by the getrandom system call.
+type GetRandomFlag uintptr
+
+const (
+	// GRND_NONBLOCK means return EAGAIN rather than blocking.
+	GRND_NONBLOCK GetRandomFlag = 0x0001
+
+	// GRND_RANDOM means use the /dev/random pool instead of /dev/urandom.
+	GRND_RANDOM GetRandomFlag = 0x0002
+)
+
+// GetRandom calls the Linux getrandom system call.
+// See https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=c6e9d6f38894798696f23c8084ca7edbf16ee895
+func GetRandom(p []byte, flags GetRandomFlag) (n int, err error) {
+	if randomTrap == 0 {
+		return 0, stdsyscall.ENOSYS
+	}
+	if len(p) == 0 {
+		return 0, nil
+	}
+	if atomic.LoadInt32(&randomUnsupported) != 0 {
+		return 0, stdsyscall.ENOSYS
+	}
+	r1, _, errno := stdsyscall.Syscall(randomTrap,
+		uintptr(unsafe.Pointer(&p[0])),
+		uintptr(len(p)),
+		uintptr(flags))
+	if errno != 0 {
+		if errno == stdsyscall.ENOSYS {
+			atomic.StoreInt32(&randomUnsupported, 1)
+		}
+		return 0, errno
+	}
+	return int(r1), nil
+}
diff --git a/src/io/io.go b/src/io/io.go
new file mode 100644
index 0000000..7507a84
--- /dev/null
+++ b/src/io/io.go
@@ -0,0 +1,502 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package io provides basic interfaces to I/O primitives.
+// Its primary job is to wrap existing implementations of such primitives,
+// such as those in package os, into shared public interfaces that
+// abstract the functionality, plus some other related primitives.
+//
+// Because these interfaces and primitives wrap lower-level operations with
+// various implementations, unless otherwise informed clients should not
+// assume they are safe for parallel execution.
+package io
+
+import (
+	"errors"
+)
+
+// ErrShortWrite means that a write accepted fewer bytes than requested
+// but failed to return an explicit error.
+var ErrShortWrite = errors.New("short write")
+
+// ErrShortBuffer means that a read required a longer buffer than was provided.
+var ErrShortBuffer = errors.New("short buffer")
+
+// EOF is the error returned by Read when no more input is available.
+// Functions should return EOF only to signal a graceful end of input.
+// If the EOF occurs unexpectedly in a structured data stream,
+// the appropriate error is either ErrUnexpectedEOF or some other error
+// giving more detail.
+var EOF = errors.New("EOF")
+
+// ErrUnexpectedEOF means that EOF was encountered in the
+// middle of reading a fixed-size block or data structure.
+var ErrUnexpectedEOF = errors.New("unexpected EOF")
+
+// ErrNoProgress is returned by some clients of an io.Reader when
+// many calls to Read have failed to return any data or error,
+// usually the sign of a broken io.Reader implementation.
+var ErrNoProgress = errors.New("multiple Read calls return no data or error")
+
+// Reader is the interface that wraps the basic Read method.
+//
+// Read reads up to len(p) bytes into p.  It returns the number of bytes
+// read (0 <= n <= len(p)) and any error encountered.  Even if Read
+// returns n < len(p), it may use all of p as scratch space during the call.
+// If some data is available but not len(p) bytes, Read conventionally
+// returns what is available instead of waiting for more.
+//
+// When Read encounters an error or end-of-file condition after
+// successfully reading n > 0 bytes, it returns the number of
+// bytes read.  It may return the (non-nil) error from the same call
+// or return the error (and n == 0) from a subsequent call.
+// An instance of this general case is that a Reader returning
+// a non-zero number of bytes at the end of the input stream may
+// return either err == EOF or err == nil.  The next Read should
+// return 0, EOF regardless.
+//
+// Callers should always process the n > 0 bytes returned before
+// considering the error err.  Doing so correctly handles I/O errors
+// that happen after reading some bytes and also both of the
+// allowed EOF behaviors.
+//
+// Implementations of Read are discouraged from returning a
+// zero byte count with a nil error, except when len(p) == 0.
+// Callers should treat a return of 0 and nil as indicating that
+// nothing happened; in particular it does not indicate EOF.
+//
+// Implementations must not retain p.
+type Reader interface {
+	Read(p []byte) (n int, err error)
+}
+
+// Writer is the interface that wraps the basic Write method.
+//
+// Write writes len(p) bytes from p to the underlying data stream.
+// It returns the number of bytes written from p (0 <= n <= len(p))
+// and any error encountered that caused the write to stop early.
+// Write must return a non-nil error if it returns n < len(p).
+// Write must not modify the slice data, even temporarily.
+//
+// Implementations must not retain p.
+type Writer interface {
+	Write(p []byte) (n int, err error)
+}
+
+// Closer is the interface that wraps the basic Close method.
+//
+// The behavior of Close after the first call is undefined.
+// Specific implementations may document their own behavior.
+type Closer interface {
+	Close() error
+}
+
+// Seeker is the interface that wraps the basic Seek method.
+//
+// Seek sets the offset for the next Read or Write to offset,
+// interpreted according to whence: 0 means relative to the origin of
+// the file, 1 means relative to the current offset, and 2 means
+// relative to the end.  Seek returns the new offset and an error, if
+// any.
+//
+// Seeking to a negative offset is an error. Seeking to any positive
+// offset is legal, but the behavior of subsequent I/O operations on
+// the underlying object is implementation-dependent.
+type Seeker interface {
+	Seek(offset int64, whence int) (int64, error)
+}
+
+// ReadWriter is the interface that groups the basic Read and Write methods.
+type ReadWriter interface {
+	Reader
+	Writer
+}
+
+// ReadCloser is the interface that groups the basic Read and Close methods.
+type ReadCloser interface {
+	Reader
+	Closer
+}
+
+// WriteCloser is the interface that groups the basic Write and Close methods.
+type WriteCloser interface {
+	Writer
+	Closer
+}
+
+// ReadWriteCloser is the interface that groups the basic Read, Write and Close methods.
+type ReadWriteCloser interface {
+	Reader
+	Writer
+	Closer
+}
+
+// ReadSeeker is the interface that groups the basic Read and Seek methods.
+type ReadSeeker interface {
+	Reader
+	Seeker
+}
+
+// WriteSeeker is the interface that groups the basic Write and Seek methods.
+type WriteSeeker interface {
+	Writer
+	Seeker
+}
+
+// ReadWriteSeeker is the interface that groups the basic Read, Write and Seek methods.
+type ReadWriteSeeker interface {
+	Reader
+	Writer
+	Seeker
+}
+
+// ReaderFrom is the interface that wraps the ReadFrom method.
+//
+// ReadFrom reads data from r until EOF or error.
+// The return value n is the number of bytes read.
+// Any error except io.EOF encountered during the read is also returned.
+//
+// The Copy function uses ReaderFrom if available.
+type ReaderFrom interface {
+	ReadFrom(r Reader) (n int64, err error)
+}
+
+// WriterTo is the interface that wraps the WriteTo method.
+//
+// WriteTo writes data to w until there's no more data to write or
+// when an error occurs. The return value n is the number of bytes
+// written. Any error encountered during the write is also returned.
+//
+// The Copy function uses WriterTo if available.
+type WriterTo interface {
+	WriteTo(w Writer) (n int64, err error)
+}
+
+// ReaderAt is the interface that wraps the basic ReadAt method.
+//
+// ReadAt reads len(p) bytes into p starting at offset off in the
+// underlying input source.  It returns the number of bytes
+// read (0 <= n <= len(p)) and any error encountered.
+//
+// When ReadAt returns n < len(p), it returns a non-nil error
+// explaining why more bytes were not returned.  In this respect,
+// ReadAt is stricter than Read.
+//
+// Even if ReadAt returns n < len(p), it may use all of p as scratch
+// space during the call.  If some data is available but not len(p) bytes,
+// ReadAt blocks until either all the data is available or an error occurs.
+// In this respect ReadAt is different from Read.
+//
+// If the n = len(p) bytes returned by ReadAt are at the end of the
+// input source, ReadAt may return either err == EOF or err == nil.
+//
+// If ReadAt is reading from an input source with a seek offset,
+// ReadAt should not affect nor be affected by the underlying
+// seek offset.
+//
+// Clients of ReadAt can execute parallel ReadAt calls on the
+// same input source.
+//
+// Implementations must not retain p.
+type ReaderAt interface {
+	ReadAt(p []byte, off int64) (n int, err error)
+}
+
+// WriterAt is the interface that wraps the basic WriteAt method.
+//
+// WriteAt writes len(p) bytes from p to the underlying data stream
+// at offset off.  It returns the number of bytes written from p (0 <= n <= len(p))
+// and any error encountered that caused the write to stop early.
+// WriteAt must return a non-nil error if it returns n < len(p).
+//
+// If WriteAt is writing to a destination with a seek offset,
+// WriteAt should not affect nor be affected by the underlying
+// seek offset.
+//
+// Clients of WriteAt can execute parallel WriteAt calls on the same
+// destination if the ranges do not overlap.
+//
+// Implementations must not retain p.
+type WriterAt interface {
+	WriteAt(p []byte, off int64) (n int, err error)
+}
+
+// ByteReader is the interface that wraps the ReadByte method.
+//
+// ReadByte reads and returns the next byte from the input.
+// If no byte is available, err will be set.
+type ByteReader interface {
+	ReadByte() (c byte, err error)
+}
+
+// ByteScanner is the interface that adds the UnreadByte method to the
+// basic ReadByte method.
+//
+// UnreadByte causes the next call to ReadByte to return the same byte
+// as the previous call to ReadByte.
+// It may be an error to call UnreadByte twice without an intervening
+// call to ReadByte.
+type ByteScanner interface {
+	ByteReader
+	UnreadByte() error
+}
+
+// ByteWriter is the interface that wraps the WriteByte method.
+type ByteWriter interface {
+	WriteByte(c byte) error
+}
+
+// RuneReader is the interface that wraps the ReadRune method.
+//
+// ReadRune reads a single UTF-8 encoded Unicode character
+// and returns the rune and its size in bytes. If no character is
+// available, err will be set.
+type RuneReader interface {
+	ReadRune() (r rune, size int, err error)
+}
+
+// RuneScanner is the interface that adds the UnreadRune method to the
+// basic ReadRune method.
+//
+// UnreadRune causes the next call to ReadRune to return the same rune
+// as the previous call to ReadRune.
+// It may be an error to call UnreadRune twice without an intervening
+// call to ReadRune.
+type RuneScanner interface {
+	RuneReader
+	UnreadRune() error
+}
+
+// stringWriter is the interface that wraps the WriteString method.
+type stringWriter interface {
+	WriteString(s string) (n int, err error)
+}
+
+// WriteString writes the contents of the string s to w, which accepts an array of bytes.
+// If w already implements a WriteString method, it is invoked directly.
+func WriteString(w Writer, s string) (n int, err error) {
+	if sw, ok := w.(stringWriter); ok {
+		return sw.WriteString(s)
+	}
+	return w.Write([]byte(s))
+}
+
+// ReadAtLeast reads from r into buf until it has read at least min bytes.
+// It returns the number of bytes copied and an error if fewer bytes were read.
+// The error is EOF only if no bytes were read.
+// If an EOF happens after reading fewer than min bytes,
+// ReadAtLeast returns ErrUnexpectedEOF.
+// If min is greater than the length of buf, ReadAtLeast returns ErrShortBuffer.
+// On return, n >= min if and only if err == nil.
+func ReadAtLeast(r Reader, buf []byte, min int) (n int, err error) {
+	if len(buf) < min {
+		return 0, ErrShortBuffer
+	}
+	for n < min && err == nil {
+		var nn int
+		nn, err = r.Read(buf[n:])
+		n += nn
+	}
+	if n >= min {
+		err = nil
+	} else if n > 0 && err == EOF {
+		err = ErrUnexpectedEOF
+	}
+	return
+}
+
+// ReadFull reads exactly len(buf) bytes from r into buf.
+// It returns the number of bytes copied and an error if fewer bytes were read.
+// The error is EOF only if no bytes were read.
+// If an EOF happens after reading some but not all the bytes,
+// ReadFull returns ErrUnexpectedEOF.
+// On return, n == len(buf) if and only if err == nil.
+func ReadFull(r Reader, buf []byte) (n int, err error) {
+	return ReadAtLeast(r, buf, len(buf))
+}
+
+// CopyN copies n bytes (or until an error) from src to dst.
+// It returns the number of bytes copied and the earliest
+// error encountered while copying.
+// On return, written == n if and only if err == nil.
+//
+// If dst implements the ReaderFrom interface,
+// the copy is implemented using it.
+func CopyN(dst Writer, src Reader, n int64) (written int64, err error) {
+	written, err = Copy(dst, LimitReader(src, n))
+	if written == n {
+		return n, nil
+	}
+	if written < n && err == nil {
+		// src stopped early; must have been EOF.
+		err = EOF
+	}
+	return
+}
+
+// Copy copies from src to dst until either EOF is reached
+// on src or an error occurs.  It returns the number of bytes
+// copied and the first error encountered while copying, if any.
+//
+// A successful Copy returns err == nil, not err == EOF.
+// Because Copy is defined to read from src until EOF, it does
+// not treat an EOF from Read as an error to be reported.
+//
+// If src implements the WriterTo interface,
+// the copy is implemented by calling src.WriteTo(dst).
+// Otherwise, if dst implements the ReaderFrom interface,
+// the copy is implemented by calling dst.ReadFrom(src).
+func Copy(dst Writer, src Reader) (written int64, err error) {
+	// If the reader has a WriteTo method, use it to do the copy.
+	// Avoids an allocation and a copy.
+	if wt, ok := src.(WriterTo); ok {
+		return wt.WriteTo(dst)
+	}
+	// Similarly, if the writer has a ReadFrom method, use it to do the copy.
+	if rt, ok := dst.(ReaderFrom); ok {
+		return rt.ReadFrom(src)
+	}
+	buf := make([]byte, 32*1024)
+	for {
+		nr, er := src.Read(buf)
+		if nr > 0 {
+			nw, ew := dst.Write(buf[0:nr])
+			if nw > 0 {
+				written += int64(nw)
+			}
+			if ew != nil {
+				err = ew
+				break
+			}
+			if nr != nw {
+				err = ErrShortWrite
+				break
+			}
+		}
+		if er == EOF {
+			break
+		}
+		if er != nil {
+			err = er
+			break
+		}
+	}
+	return written, err
+}
+
+// LimitReader returns a Reader that reads from r
+// but stops with EOF after n bytes.
+// The underlying implementation is a *LimitedReader.
+func LimitReader(r Reader, n int64) Reader { return &LimitedReader{r, n} }
+
+// A LimitedReader reads from R but limits the amount of
+// data returned to just N bytes. Each call to Read
+// updates N to reflect the new amount remaining.
+type LimitedReader struct {
+	R Reader // underlying reader
+	N int64  // max bytes remaining
+}
+
+func (l *LimitedReader) Read(p []byte) (n int, err error) {
+	if l.N <= 0 {
+		return 0, EOF
+	}
+	if int64(len(p)) > l.N {
+		p = p[0:l.N]
+	}
+	n, err = l.R.Read(p)
+	l.N -= int64(n)
+	return
+}
+
+// NewSectionReader returns a SectionReader that reads from r
+// starting at offset off and stops with EOF after n bytes.
+func NewSectionReader(r ReaderAt, off int64, n int64) *SectionReader {
+	return &SectionReader{r, off, off, off + n}
+}
+
+// SectionReader implements Read, Seek, and ReadAt on a section
+// of an underlying ReaderAt.
+type SectionReader struct {
+	r     ReaderAt
+	base  int64
+	off   int64
+	limit int64
+}
+
+func (s *SectionReader) Read(p []byte) (n int, err error) {
+	if s.off >= s.limit {
+		return 0, EOF
+	}
+	if max := s.limit - s.off; int64(len(p)) > max {
+		p = p[0:max]
+	}
+	n, err = s.r.ReadAt(p, s.off)
+	s.off += int64(n)
+	return
+}
+
+var errWhence = errors.New("Seek: invalid whence")
+var errOffset = errors.New("Seek: invalid offset")
+
+func (s *SectionReader) Seek(offset int64, whence int) (int64, error) {
+	switch whence {
+	default:
+		return 0, errWhence
+	case 0:
+		offset += s.base
+	case 1:
+		offset += s.off
+	case 2:
+		offset += s.limit
+	}
+	if offset < s.base {
+		return 0, errOffset
+	}
+	s.off = offset
+	return offset - s.base, nil
+}
+
+func (s *SectionReader) ReadAt(p []byte, off int64) (n int, err error) {
+	if off < 0 || off >= s.limit-s.base {
+		return 0, EOF
+	}
+	off += s.base
+	if max := s.limit - off; int64(len(p)) > max {
+		p = p[0:max]
+		n, err = s.r.ReadAt(p, off)
+		if err == nil {
+			err = EOF
+		}
+		return n, err
+	}
+	return s.r.ReadAt(p, off)
+}
+
+// Size returns the size of the section in bytes.
+func (s *SectionReader) Size() int64 { return s.limit - s.base }
+
+// TeeReader returns a Reader that writes to w what it reads from r.
+// All reads from r performed through it are matched with
+// corresponding writes to w.  There is no internal buffering -
+// the write must complete before the read completes.
+// Any error encountered while writing is reported as a read error.
+func TeeReader(r Reader, w Writer) Reader {
+	return &teeReader{r, w}
+}
+
+type teeReader struct {
+	r Reader
+	w Writer
+}
+
+func (t *teeReader) Read(p []byte) (n int, err error) {
+	n, err = t.r.Read(p)
+	if n > 0 {
+		if n, err := t.w.Write(p[:n]); err != nil {
+			return n, err
+		}
+	}
+	return
+}
diff --git a/src/pkg/io/io_test.go b/src/io/io_test.go
similarity index 100%
rename from src/pkg/io/io_test.go
rename to src/io/io_test.go
diff --git a/src/pkg/io/ioutil/ioutil.go b/src/io/ioutil/ioutil.go
similarity index 100%
rename from src/pkg/io/ioutil/ioutil.go
rename to src/io/ioutil/ioutil.go
diff --git a/src/pkg/io/ioutil/ioutil_test.go b/src/io/ioutil/ioutil_test.go
similarity index 100%
rename from src/pkg/io/ioutil/ioutil_test.go
rename to src/io/ioutil/ioutil_test.go
diff --git a/src/pkg/io/ioutil/tempfile.go b/src/io/ioutil/tempfile.go
similarity index 100%
rename from src/pkg/io/ioutil/tempfile.go
rename to src/io/ioutil/tempfile.go
diff --git a/src/pkg/io/ioutil/tempfile_test.go b/src/io/ioutil/tempfile_test.go
similarity index 100%
rename from src/pkg/io/ioutil/tempfile_test.go
rename to src/io/ioutil/tempfile_test.go
diff --git a/src/pkg/io/multi.go b/src/io/multi.go
similarity index 100%
rename from src/pkg/io/multi.go
rename to src/io/multi.go
diff --git a/src/pkg/io/multi_test.go b/src/io/multi_test.go
similarity index 100%
rename from src/pkg/io/multi_test.go
rename to src/io/multi_test.go
diff --git a/src/pkg/io/pipe.go b/src/io/pipe.go
similarity index 100%
rename from src/pkg/io/pipe.go
rename to src/io/pipe.go
diff --git a/src/pkg/io/pipe_test.go b/src/io/pipe_test.go
similarity index 100%
rename from src/pkg/io/pipe_test.go
rename to src/io/pipe_test.go
diff --git a/src/lib9/fmt/dofmt.c b/src/lib9/fmt/dofmt.c
index 94a91a2..3b9dc36 100644
--- a/src/lib9/fmt/dofmt.c
+++ b/src/lib9/fmt/dofmt.c
@@ -491,12 +491,6 @@ __ifmt(Fmt *f)
 			if(fl & FmtApost)
 				__needsep(&ndig, &grouping);
 		}
-
-		/*
-		 * Zero values don't get 0x.
-		 */
-		if(f->r == 'x' || f->r == 'X')
-			fl &= ~(ulong)FmtSharp;
 	}
 	for(w = f->prec; n < w && p > buf+3; n++){
 		if((fl & FmtApost) && __needsep(&ndig, &grouping)){
diff --git a/src/lib9/tempdir_windows.c b/src/lib9/tempdir_windows.c
index 1a53005..4c3df7c 100644
--- a/src/lib9/tempdir_windows.c
+++ b/src/lib9/tempdir_windows.c
@@ -70,7 +70,7 @@ removeall(char *p)
 {
 	WinRune *r, *r1;
 	DWORD attr;
-	char *q, *elem;
+	char *q, *qt, *elem;
 	HANDLE h;
 	WIN32_FIND_DATAW data;
 	
@@ -91,15 +91,18 @@ removeall(char *p)
 	do{
 		q = toutf(data.cFileName);
 		elem = strrchr(q, '\\');
-		if(elem != nil) {
+		if(elem != nil)
 			elem++;
-			if(strcmp(elem, ".") == 0 || strcmp(elem, "..") == 0) {
-				free(q);
-				continue;
-			}
+		else
+			elem = q;
+		if(strcmp(elem, ".") == 0 || strcmp(elem, "..") == 0) {
+			free(q);
+			continue;
 		}
-		removeall(q);
-		free(q);		
+		qt = smprint("%s\\%s", p, q);
+		free(q);
+		removeall(qt);
+		free(qt);
 	}while(FindNextFileW(h, &data));
 	FindClose(h);
 
diff --git a/src/liblink/asm5.c b/src/liblink/asm5.c
index 465b645..96df9f7 100644
--- a/src/liblink/asm5.c
+++ b/src/liblink/asm5.c
@@ -35,7 +35,7 @@
 #include <bio.h>
 #include <link.h>
 #include "../cmd/5l/5.out.h"
-#include "../pkg/runtime/stack.h"
+#include "../runtime/stack.h"
 
 typedef	struct	Optab	Optab;
 typedef	struct	Oprang	Oprang;
@@ -43,7 +43,7 @@ typedef	uchar	Opcross[32][2][32];
 
 struct	Optab
 {
-	char	as;
+	uchar	as;
 	uchar	a1;
 	char	a2;
 	uchar	a3;
@@ -65,52 +65,6 @@ enum
 	LTO		= 1<<1,
 	LPOOL		= 1<<2,
 	LPCREL		= 1<<3,
-
-	C_NONE		= 0,
-	C_REG,
-	C_REGREG,
-	C_REGREG2,
-	C_SHIFT,
-	C_FREG,
-	C_PSR,
-	C_FCR,
-
-	C_RCON,		/* 0xff rotated */
-	C_NCON,		/* ~RCON */
-	C_SCON,		/* 0xffff */
-	C_LCON,
-	C_LCONADDR,
-	C_ZFCON,
-	C_SFCON,
-	C_LFCON,
-
-	C_RACON,
-	C_LACON,
-
-	C_SBRA,
-	C_LBRA,
-
-	C_HAUTO,	/* halfword insn offset (-0xff to 0xff) */
-	C_FAUTO,	/* float insn offset (0 to 0x3fc, word aligned) */
-	C_HFAUTO,	/* both H and F */
-	C_SAUTO,	/* -0xfff to 0xfff */
-	C_LAUTO,
-
-	C_HOREG,
-	C_FOREG,
-	C_HFOREG,
-	C_SOREG,
-	C_ROREG,
-	C_SROREG,	/* both nil and R */
-	C_LOREG,
-
-	C_PC,
-	C_SP,
-	C_HREG,
-
-	C_ADDR,		/* reference to relocatable address */
-
-	C_GOK,
 };
 
 static Optab	optab[] =
@@ -355,10 +309,14 @@ static Optab	optab[] =
 	{ AUSEFIELD,	C_ADDR,	C_NONE,	C_NONE, 	 0, 0, 0 },
 	{ APCDATA,	C_LCON,	C_NONE,	C_LCON,		0, 0, 0 },
 	{ AFUNCDATA,	C_LCON,	C_NONE,	C_ADDR,	0, 0, 0 },
+	{ ANOP,		C_NONE,	C_NONE,	C_NONE,		0, 0, 0 },
 
 	{ ADUFFZERO,	C_NONE,	C_NONE,	C_SBRA,		 5, 4, 0 },  // same as ABL
 	{ ADUFFCOPY,	C_NONE,	C_NONE,	C_SBRA,		 5, 4, 0 },  // same as ABL
 
+	{ ADATABUNDLE,	C_NONE, C_NONE, C_NONE,		100, 4, 0 },
+	{ ADATABUNDLEEND,	C_NONE, C_NONE, C_NONE,		100, 0, 0 },
+
 	{ AXXX,		C_NONE,	C_NONE,	C_NONE,		 0, 4, 0 },
 };
 
@@ -372,6 +330,7 @@ static int	checkpool(Link*, Prog*, int);
 static int 	flushpool(Link*, Prog*, int, int);
 static void	addpool(Link*, Prog*, Addr*);
 static void	asmout(Link*, Prog*, Optab*, int32*);
+static int	asmoutnacl(Link*, int32, Prog*, Optab*, int32 *);
 static Optab*	oplook(Link*, Prog*);
 static int32	oprrr(Link*, int, int);
 static int32	olr(Link*, int32, int, int, int);
@@ -390,10 +349,8 @@ static int32	immrot(uint32);
 static int32	immaddr(int32);
 static int32	opbra(Link*, int, int);
 
-static	Opcross	opcross[8];
 static	Oprang	oprange[ALAST];
-static	char	xcmp[C_GOK+1][C_GOK+1];
-static	uchar	repop[ALAST];
+static	uchar	xcmp[C_GOK+1][C_GOK+1];
 
 static Prog zprg = {
 	.as = AGOK,
@@ -411,6 +368,8 @@ static Prog zprg = {
 	},
 };
 
+static LSym *deferreturn;
+
 static void
 nocache(Prog *p)
 {
@@ -419,19 +378,6 @@ nocache(Prog *p)
 	p->to.class = 0;
 }
 
-static int
-scan(Link *ctxt, Prog *op, Prog *p, int c)
-{
-	Prog *q;
-
-	for(q = op->link; q != p && q != nil; q = q->link){
-		q->pc = c;
-		c += oplook(ctxt, q)->size;
-		nocache(q);
-	}
-	return c;
-}
-
 /* size of a case statement including jump table */
 static int32
 casesz(Link *ctxt, Prog *p)
@@ -453,13 +399,250 @@ casesz(Link *ctxt, Prog *p)
 
 static void buildop(Link*);
 
+// asmoutnacl assembles the instruction p. It replaces asmout for NaCl.
+// It returns the total number of bytes put in out, and it can change
+// p->pc if extra padding is necessary.
+// In rare cases, asmoutnacl might split p into two instructions.
+// origPC is the PC for this Prog (no padding is taken into account).
+static int
+asmoutnacl(Link *ctxt, int32 origPC, Prog *p, Optab *o, int32 *out)
+{
+	int size, reg;
+	Prog *q;
+	Addr *a, *a2;
+
+	size = o->size;
+
+	// instruction specific
+	switch(p->as) {
+	default:
+		if(out != nil)
+			asmout(ctxt, p, o, out);
+		break;
+	case ADATABUNDLE: // align to 16-byte boundary
+	case ADATABUNDLEEND: // zero width instruction, just to align next instruction to 16-byte boundary
+		p->pc = (p->pc+15) & ~15;
+		if(out != nil)
+			asmout(ctxt, p, o, out);
+		break;
+	case AUNDEF:
+	case APLD:
+		size = 4;
+		if(out != nil) {
+			switch(p->as) {
+			case AUNDEF:
+				out[0] = 0xe7fedef0; // NACL_INSTR_ARM_ABORT_NOW (UDF #0xEDE0)
+				break;
+			case APLD:
+				out[0] = 0xe1a01001; // (MOVW R1, R1)
+				break;
+			}
+		}
+		break;
+	case AB:
+	case ABL:
+		if(p->to.type != D_OREG) {
+			if(out != nil)
+				asmout(ctxt, p, o, out);
+		} else {
+			if(p->to.offset != 0 || size != 4 || p->to.reg >= 16 || p->to.reg < 0)
+				ctxt->diag("unsupported instruction: %P", p);
+			if((p->pc&15) == 12)
+				p->pc += 4;
+			if(out != nil) {
+				out[0] = ((p->scond&C_SCOND)<<28) | 0x03c0013f | (p->to.reg << 12) | (p->to.reg << 16); // BIC $0xc000000f, Rx
+				if(p->as == AB)
+					out[1] = ((p->scond&C_SCOND)<<28) | 0x012fff10 | p->to.reg; // BX Rx
+				else // ABL
+					out[1] = ((p->scond&C_SCOND)<<28) | 0x012fff30 | p->to.reg; // BLX Rx
+			}
+			size = 8;
+		}
+		// align the last instruction (the actual BL) to the last instruction in a bundle
+		if(p->as == ABL) {
+			if(deferreturn == nil)
+				deferreturn = linklookup(ctxt, "runtime.deferreturn", 0);
+			if(p->to.sym == deferreturn)
+				p->pc = ((origPC+15) & ~15) + 16 - size;
+			else
+				p->pc += (16 - ((p->pc+size)&15)) & 15;
+		}
+		break;
+	case ALDREX:
+	case ALDREXD:
+	case AMOVB:
+	case AMOVBS:
+	case AMOVBU:
+	case AMOVD:
+	case AMOVF:
+	case AMOVH:
+	case AMOVHS:
+	case AMOVHU:
+	case AMOVM:
+	case AMOVW:
+	case ASTREX:
+	case ASTREXD:
+		if(p->to.type == D_REG && p->to.reg == 15 && p->from.reg == 13) { // MOVW.W x(R13), PC
+			if(out != nil)
+				asmout(ctxt, p, o, out);
+			if(size == 4) {
+				if(out != nil) {
+					// Note: 5c and 5g reg.c know that DIV/MOD smashes R12
+					// so that this return instruction expansion is valid.
+					out[0] = out[0] & ~0x3000; // change PC to R12
+					out[1] = ((p->scond&C_SCOND)<<28) | 0x03ccc13f; // BIC $0xc000000f, R12
+					out[2] = ((p->scond&C_SCOND)<<28) | 0x012fff1c; // BX R12
+				}
+				size += 8;
+				if(((p->pc+size) & 15) == 4)
+					p->pc += 4;
+				break;
+			} else {
+				// if the instruction used more than 4 bytes, then it must have used a very large
+				// offset to update R13, so we need to additionally mask R13.
+				if(out != nil) {
+					out[size/4-1] &= ~0x3000; // change PC to R12
+					out[size/4] = ((p->scond&C_SCOND)<<28) | 0x03cdd103; // BIC $0xc0000000, R13
+					out[size/4+1] = ((p->scond&C_SCOND)<<28) | 0x03ccc13f; // BIC $0xc000000f, R12
+					out[size/4+2] = ((p->scond&C_SCOND)<<28) | 0x012fff1c; // BX R12
+				}
+				// p->pc+size is only ok at 4 or 12 mod 16.
+				if((p->pc+size)%8 == 0)
+					p->pc += 4;
+				size += 12;
+				break;
+			}
+		}
+
+		if(p->to.type == D_REG && p->to.reg == 15)
+			ctxt->diag("unsupported instruction (move to another register and use indirect jump instead): %P", p);
+
+		if(p->to.type == D_OREG && p->to.reg == 13 && (p->scond & C_WBIT) && size > 4) {
+			// function prolog with very large frame size: MOVW.W R14,-100004(R13)
+			// split it into two instructions:
+			// 	ADD $-100004, R13
+			// 	MOVW R14, 0(R13)
+			q = ctxt->arch->prg();
+			p->scond &= ~C_WBIT;
+			*q = *p;
+			a = &p->to;
+			if(p->to.type == D_OREG)
+				a2 = &q->to;
+			else
+				a2 = &q->from;
+			nocache(q);
+			nocache(p);
+			// insert q after p
+			q->link = p->link;
+			p->link = q;
+			q->pcond = nil;
+			// make p into ADD $X, R13
+			p->as = AADD;
+			p->from = *a;
+			p->from.reg = NREG;
+			p->from.type = D_CONST;
+			p->to = zprg.to;
+			p->to.type = D_REG;
+			p->to.reg = 13;
+			// make q into p but load/store from 0(R13)
+			q->spadj = 0;
+			*a2 = zprg.from;
+			a2->type = D_OREG;
+			a2->reg = 13;
+			a2->sym = nil;
+			a2->offset = 0;
+			size = oplook(ctxt, p)->size;
+			break;
+		}
+
+		if((p->to.type == D_OREG && p->to.reg != 13 && p->to.reg != 9) || // MOVW Rx, X(Ry), y != 13 && y != 9
+		   (p->from.type == D_OREG && p->from.reg != 13 && p->from.reg != 9)) { // MOVW X(Rx), Ry, x != 13 && x != 9
+			if(p->to.type == D_OREG)
+				a = &p->to;
+			else
+				a = &p->from;
+			reg = a->reg;
+			if(size == 4) {
+				// if addr.reg == NREG, then it is probably load from x(FP) with small x, no need to modify.
+				if(reg == NREG) {
+					if(out != nil)
+						asmout(ctxt, p, o, out);
+				} else {
+					if(out != nil)
+						out[0] = ((p->scond&C_SCOND)<<28) | 0x03c00103 | (reg << 16) | (reg << 12); // BIC $0xc0000000, Rx
+					if((p->pc&15) == 12)
+						p->pc += 4;
+					size += 4;
+					if(out != nil)
+						asmout(ctxt, p, o, &out[1]);
+				}
+				break;
+			} else {
+				// if a load/store instruction takes more than 1 word to implement, then
+				// we need to seperate the instruction into two:
+				// 1. explicitly load the address into R11.
+				// 2. load/store from R11.
+				// This won't handle .W/.P, so we should reject such code.
+				if(p->scond & (C_PBIT|C_WBIT))
+					ctxt->diag("unsupported instruction (.P/.W): %P", p);
+				q = ctxt->arch->prg();
+				*q = *p;
+				if(p->to.type == D_OREG)
+					a2 = &q->to;
+				else
+					a2 = &q->from;
+				nocache(q);
+				nocache(p);
+				// insert q after p
+				q->link = p->link;
+				p->link = q;
+				q->pcond = nil;
+				// make p into MOVW $X(R), R11
+				p->as = AMOVW;
+				p->from = *a;
+				p->from.type = D_CONST;
+				p->to = zprg.to;
+				p->to.type = D_REG;
+				p->to.reg = 11;
+				// make q into p but load/store from 0(R11)
+				*a2 = zprg.from;
+				a2->type = D_OREG;
+				a2->reg = 11;
+				a2->sym = nil;
+				a2->offset = 0;
+				size = oplook(ctxt, p)->size;
+				break;
+			}
+		} else if(out != nil)
+			asmout(ctxt, p, o, out);
+		break;
+	}
+
+	// destination register specific
+	if(p->to.type == D_REG) {
+		switch(p->to.reg) {
+		case 9:
+			ctxt->diag("invalid instruction, cannot write to R9: %P", p);
+			break;
+		case 13:
+			if(out != nil)
+				out[size/4] = 0xe3cdd103; // BIC $0xc0000000, R13
+			if(((p->pc+size) & 15) == 0)
+				p->pc += 4;
+			size += 4;
+			break;
+		}
+	}
+	return size;
+}
+
 void
 span5(Link *ctxt, LSym *cursym)
 {
 	Prog *p, *op;
 	Optab *o;
-	int m, bflag, i, v;
-	int32 c, out[6];
+	int m, bflag, i, v, times;
+	int32 c, opc, out[6+3];
 	uchar *bp;
 
 	p = cursym->text;
@@ -472,21 +655,39 @@ span5(Link *ctxt, LSym *cursym)
  	ctxt->cursym = cursym;
 
 	ctxt->autosize = p->to.offset + 4;
-	c = 0;	
+	c = 0;
 
-	for(op = p, p = p->link; p != nil; op = p, p = p->link) {
+	for(op = p, p = p->link; p != nil || ctxt->blitrl != nil; op = p, p = p->link) {
+		if(p == nil) {
+		       	if(checkpool(ctxt, op, 0)) {
+				p = op;
+				continue;
+			}
+			// can't happen: blitrl is not nil, but checkpool didn't flushpool
+			ctxt->diag("internal inconsistency");
+			break;
+		}
 		ctxt->curp = p;
 		p->pc = c;
 		o = oplook(ctxt, p);
-		m = o->size;
+		if(ctxt->headtype != Hnacl) {
+			m = o->size;
+		} else {
+			m = asmoutnacl(ctxt, c, p, o, nil);
+			c = p->pc; // asmoutnacl might change pc for alignment
+			o = oplook(ctxt, p); // asmoutnacl might change p in rare cases
+		}
+		if(m % 4 != 0 || p->pc % 4 != 0) {
+			ctxt->diag("!pc invalid: %P size=%d", p, m);
+		}
 		// must check literal pool here in case p generates many instructions
 		if(ctxt->blitrl){
 			if(checkpool(ctxt, op, p->as == ACASE ? casesz(ctxt, p) : m)) {
-				p->pc = scan(ctxt, op, p, c);
-				c = p->pc;
+				p = op;
+				continue;
 			}
 		}
-		if(m == 0 && (p->as != AFUNCDATA && p->as != APCDATA)) {
+		if(m == 0 && (p->as != AFUNCDATA && p->as != APCDATA && p->as != ADATABUNDLEEND && p->as != ANOP)) {
 			ctxt->diag("zero-width instruction\n%P", p);
 			continue;
 		}
@@ -506,10 +707,6 @@ span5(Link *ctxt, LSym *cursym)
 			flushpool(ctxt, p, 0, 0);
 		c += m;
 	}
-	if(ctxt->blitrl){
-		if(checkpool(ctxt, op, 0))
-			c = scan(ctxt, op, nil, c);
-	}
 	cursym->size = c;
 
 	/*
@@ -518,15 +715,19 @@ span5(Link *ctxt, LSym *cursym)
 	 * generate extra passes putting branches
 	 * around jmps to fix. this is rare.
 	 */
+	times = 0;
 	do {
 		if(ctxt->debugvlog)
 			Bprint(ctxt->bso, "%5.2f span1\n", cputime());
 		bflag = 0;
 		c = 0;
+		times++;
+		cursym->text->pc = 0; // force re-layout the code.
 		for(p = cursym->text; p != nil; p = p->link) {
 			ctxt->curp = p;
-			p->pc = c;
 			o = oplook(ctxt,p);
+			if(c > p->pc)
+				p->pc = c;
 /* very large branches
 			if(o->type == 6 && p->pcond) {
 				otxt = p->pcond->pc - c;
@@ -550,8 +751,22 @@ span5(Link *ctxt, LSym *cursym)
 				}
 			}
  */
-			m = o->size;
-			if(m == 0 && (p->as != AFUNCDATA && p->as != APCDATA)) {
+			opc = p->pc;
+			if(ctxt->headtype != Hnacl)
+				m = o->size;
+			else
+				m = asmoutnacl(ctxt, c, p, o, nil);
+			if(p->pc != opc) {
+				bflag = 1;
+				//print("%P pc changed %d to %d in iter. %d\n", p, opc, (int32)p->pc, times);
+			}
+			c = p->pc + m;
+			if(m % 4 != 0 || p->pc % 4 != 0) {
+				ctxt->diag("pc invalid: %P size=%d", p, m);
+			}
+			if(m/4 > nelem(out))
+				ctxt->diag("instruction size too large: %d > %d", m/4, nelem(out));
+			if(m == 0 && (p->as != AFUNCDATA && p->as != APCDATA && p->as != ADATABUNDLEEND && p->as != ANOP)) {
 				if(p->as == ATEXT) {
 					ctxt->autosize = p->to.offset + 4;
 					continue;
@@ -559,10 +774,12 @@ span5(Link *ctxt, LSym *cursym)
 				ctxt->diag("zero-width instruction\n%P", p);
 				continue;
 			}
-			c += m;
 		}
 		cursym->size = c;
 	} while(bflag);
+	if(c % 4 != 0) {
+		ctxt->diag("sym->size=%d, invalid", c);
+	}
 
 	/*
 	 * lay out the code.  all the pc-relative code references,
@@ -572,26 +789,49 @@ span5(Link *ctxt, LSym *cursym)
 	 * code references to be relocated too, and then
 	 * perhaps we'd be able to parallelize the span loop above.
 	 */
-	if(ctxt->gmsym == nil)
-		ctxt->gmsym = linklookup(ctxt, "runtime.tlsgm", 0);
+	if(ctxt->tlsg == nil)
+		ctxt->tlsg = linklookup(ctxt, "runtime.tlsg", 0);
 
 	p = cursym->text;
 	ctxt->autosize = p->to.offset + 4;
 	symgrow(ctxt, cursym, cursym->size);
 
 	bp = cursym->p;
+	c = p->pc; // even p->link might need extra padding
 	for(p = p->link; p != nil; p = p->link) {
 		ctxt->pc = p->pc;
 		ctxt->curp = p;
 		o = oplook(ctxt, p);
-		asmout(ctxt, p, o, out);
-		for(i=0; i<o->size/4; i++) {
+		opc = p->pc;
+		if(ctxt->headtype != Hnacl) {
+			asmout(ctxt, p, o, out);
+			m = o->size;
+		} else {
+			m = asmoutnacl(ctxt, c, p, o, out);
+			if(opc != p->pc)
+				ctxt->diag("asmoutnacl broken: pc changed (%d->%d) in last stage: %P", opc, (int32)p->pc, p);
+		}
+		if(m % 4 != 0 || p->pc % 4 != 0) {
+			ctxt->diag("final stage: pc invalid: %P size=%d", p, m);
+		}
+		if(c > p->pc)
+			ctxt->diag("PC padding invalid: want %#lld, has %#d: %P", p->pc, c, p);
+		while(c != p->pc) {
+			// emit 0xe1a00000 (MOVW R0, R0)
+			*bp++ = 0x00;
+			*bp++ = 0x00;
+			*bp++ = 0xa0;
+			*bp++ = 0xe1;
+			c += 4;
+		}
+		for(i=0; i<m/4; i++) {
 			v = out[i];
 			*bp++ = v;
 			*bp++ = v>>8;
 			*bp++ = v>>16;
 			*bp++ = v>>24;
 		}
+		c += m;
 	}
 }
 
@@ -604,7 +844,7 @@ span5(Link *ctxt, LSym *cursym)
 static int
 checkpool(Link *ctxt, Prog *p, int sz)
 {
-	if(pool.size >= 0xffc || immaddr((p->pc+sz+4)+4+pool.size - pool.start+8) == 0)
+	if(pool.size >= 0xff0 || immaddr((p->pc+sz+4)+4+(12+pool.size) - (pool.start+8)) == 0)
 		return flushpool(ctxt, p, 1, 0);
 	else if(p->link == nil)
 		return flushpool(ctxt, p, 2, 0);
@@ -627,8 +867,15 @@ flushpool(Link *ctxt, Prog *p, int skip, int force)
 			q->lineno = p->lineno;
 			ctxt->blitrl = q;
 		}
-		else if(!force && (p->pc+pool.size-pool.start < 2048))
+		else if(!force && (p->pc+(12+pool.size)-pool.start < 2048)) // 12 take into account the maximum nacl literal pool alignment padding size
 			return 0;
+		if(ctxt->headtype == Hnacl && pool.size % 16 != 0) {
+			// if pool is not multiple of 16 bytes, add an alignment marker
+			q = ctxt->arch->prg();
+			q->as = ADATABUNDLEEND;
+			ctxt->elitrl->link = q;
+			ctxt->elitrl = q;
+		}
 		ctxt->elitrl->link = p->link;
 		p->link = ctxt->blitrl;
 		// BUG(minux): how to correctly handle line number for constant pool entries?
@@ -661,7 +908,11 @@ addpool(Link *ctxt, Prog *p, Addr *a)
 
 	switch(c) {
 	default:
-		t.to = *a;
+		t.to.offset = a->offset;
+		t.to.sym = a->sym;
+		t.to.type = a->type;
+		t.to.name = a->name;
+		
 		if(ctxt->flag_shared && t.to.sym != nil)
 			t.pcrel = p;
 		break;
@@ -689,6 +940,22 @@ addpool(Link *ctxt, Prog *p, Addr *a)
 			}
 	}
 
+	if(ctxt->headtype == Hnacl && pool.size%16 == 0) {
+		// start a new data bundle
+		q = ctxt->arch->prg();
+		*q = zprg;
+		q->as = ADATABUNDLE;
+		q->pc = pool.size;
+		pool.size += 4;
+		if(ctxt->blitrl == nil) {
+			ctxt->blitrl = q;
+			pool.start = p->pc;
+		} else {
+			ctxt->elitrl->link = q;
+		}
+		ctxt->elitrl = q;
+	}
+
 	q = ctxt->arch->prg();
 	*q = t;
 	q->pc = pool.size;
@@ -758,6 +1025,8 @@ immhalf(int32 v)
 	return 0;
 }
 
+static int aconsize(Link *ctxt);
+
 static int
 aclass(Link *ctxt, Addr *a)
 {
@@ -792,7 +1061,6 @@ aclass(Link *ctxt, Addr *a)
 		case D_STATIC:
 			if(a->sym == 0 || a->sym->name == 0) {
 				print("null sym external\n");
-				print("%D\n", a);
 				return C_GOK;
 			}
 			ctxt->instoffset = 0;	// s.b. unused but just in case
@@ -869,7 +1137,7 @@ aclass(Link *ctxt, Addr *a)
 		case D_NONE:
 			ctxt->instoffset = a->offset;
 			if(a->reg != NREG)
-				goto aconsize;
+				return aconsize(ctxt);
 
 			t = immrot(ctxt->instoffset);
 			if(t)
@@ -889,15 +1157,11 @@ aclass(Link *ctxt, Addr *a)
 
 		case D_AUTO:
 			ctxt->instoffset = ctxt->autosize + a->offset;
-			goto aconsize;
+			return aconsize(ctxt);
 
 		case D_PARAM:
 			ctxt->instoffset = ctxt->autosize + a->offset + 4L;
-		aconsize:
-			t = immrot(ctxt->instoffset);
-			if(t)
-				return C_RACON;
-			return C_LACON;
+			return aconsize(ctxt);
 		}
 		return C_GOK;
 
@@ -907,6 +1171,17 @@ aclass(Link *ctxt, Addr *a)
 	return C_GOK;
 }
 
+static int
+aconsize(Link *ctxt)
+{
+	int t;
+
+	t = immrot(ctxt->instoffset);
+	if(t)
+		return C_RACON;
+	return C_LACON;
+}
+
 static void
 prasm(Prog *p)
 {
@@ -917,7 +1192,7 @@ static Optab*
 oplook(Link *ctxt, Prog *p)
 {
 	int a1, a2, a3, r;
-	char *c1, *c3;
+	uchar *c1, *c3;
 	Optab *o, *e;
 
 	a1 = p->optab;
@@ -941,15 +1216,10 @@ oplook(Link *ctxt, Prog *p)
 	r = p->as;
 	o = oprange[r].start;
 	if(o == 0) {
-		a1 = opcross[repop[r]][a1][a2][a3];
-		if(a1) {
-			p->optab = a1+1;
-			return optab+a1;
-		}
 		o = oprange[r].stop; /* just generate an error */
 	}
 	if(0 /*debug['O']*/) {
-		print("oplook %A %d %d %d\n",
+		print("oplook %A %^ %^ %^\n",
 			(int)p->as, a1, a2, a3);
 		print("		%d %d\n", p->from.type, p->to.type);
 	}
@@ -963,7 +1233,7 @@ oplook(Link *ctxt, Prog *p)
 			p->optab = (o-optab)+1;
 			return o;
 		}
-	ctxt->diag("illegal combination %P; %d %d %d, %d %d",
+	ctxt->diag("illegal combination %P; %^ %^ %^, %d %d",
 		p, a1, a2, a3, p->from.type, p->to.type);
 	ctxt->diag("from %d %d to %d %d\n", p->from.type, p->from.name, p->to.type, p->to.name);
 	prasm(p);
@@ -1210,11 +1480,16 @@ buildop(Link *ctxt)
 		case ACLZ:
 		case AFUNCDATA:
 		case APCDATA:
+		case ANOP:
+		case ADATABUNDLE:
+		case ADATABUNDLEEND:
 			break;
 		}
 	}
 }
 
+static int32 mov(Link*, Prog*);
+
 static void
 asmout(Link *ctxt, Prog *p, Optab *o, int32 *out)
 {
@@ -1272,19 +1547,7 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
 		break;
 
 	case 3:		/* add R<<[IR],[R],R */
-	mov:
-		aclass(ctxt, &p->from);
-		o1 = oprrr(ctxt, p->as, p->scond);
-		o1 |= p->from.offset;
-		rt = p->to.reg;
-		r = p->reg;
-		if(p->to.type == D_NONE)
-			rt = 0;
-		if(p->as == AMOVW || p->as == AMVN)
-			r = 0;
-		else if(r == NREG)
-			r = rt;
-		o1 |= (r<<16) | (rt<<12);
+		o1 = mov(ctxt, p);
 		break;
 
 	case 4:		/* add $I,[R],R */
@@ -1377,11 +1640,11 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
 			rel->sym = p->to.sym;
 			rel->add = p->to.offset;
 			
-			// runtime.tlsgm (aka gmsym) is special.
+			// runtime.tlsg is special.
 			// Its "address" is the offset from the TLS thread pointer
 			// to the thread-local g and m pointers.
 			// Emit a TLS relocation instead of a standard one.
-			if(rel->sym == ctxt->gmsym) {
+			if(rel->sym == ctxt->tlsg) {
 				rel->type = R_TLS;
 				if(ctxt->flag_shared)
 					rel->add += ctxt->pc - p->pcrel->pc - 8 - rel->siz;
@@ -1557,19 +1820,23 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
 		o1 |= p->from.reg << 0;
 		break;
 
-	case 38:	/* movm $con,oreg -> stm */
-		o1 = (0x4 << 25);
-		o1 |= p->from.offset & 0xffff;
-		o1 |= p->to.reg << 16;
-		aclass(ctxt, &p->to);
-		goto movm;
-
-	case 39:	/* movm oreg,$con -> ldm */
-		o1 = (0x4 << 25) | (1 << 20);
-		o1 |= p->to.offset & 0xffff;
-		o1 |= p->from.reg << 16;
-		aclass(ctxt, &p->from);
-	movm:
+	case 38:
+	case 39:
+		switch(o->type) {
+		case 38:	/* movm $con,oreg -> stm */
+			o1 = (0x4 << 25);
+			o1 |= p->from.offset & 0xffff;
+			o1 |= p->to.reg << 16;
+			aclass(ctxt, &p->to);
+			break;
+	
+		case 39:	/* movm oreg,$con -> ldm */
+			o1 = (0x4 << 25) | (1 << 20);
+			o1 |= p->to.offset & 0xffff;
+			o1 |= p->from.reg << 16;
+			aclass(ctxt, &p->from);
+			break;
+		}
 		if(ctxt->instoffset != 0)
 			ctxt->diag("offset must be zero in MOVM; %P", p);
 		o1 |= (p->scond & C_SCOND) << 28;
@@ -1677,7 +1944,8 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
 		if(p->from.reg == NREG) {
 			if(p->as != AMOVW)
 				ctxt->diag("byte MOV from shifter operand");
-			goto mov;
+			o1 = mov(ctxt, p);
+			break;
 		}
 		if(p->from.offset&(1<<4))
 			ctxt->diag("bad shift in LDR");
@@ -1689,7 +1957,8 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
 	case 60:	/* movb R(R),R -> ldrsb indexed */
 		if(p->from.reg == NREG) {
 			ctxt->diag("byte MOV from shifter operand");
-			goto mov;
+			o1 = mov(ctxt, p);
+			break;
 		}
 		if(p->from.offset&(~0xf))
 			ctxt->diag("bad shift in LDRSB");
@@ -2029,6 +2298,12 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
 		o1 |= p->reg;
 		o1 |= p->to.offset << 16;
 		break;
+	case 100:
+		// DATABUNDLE: BKPT $0x5be0, signify the start of NaCl data bundle;
+		// DATABUNDLEEND: zero width alignment marker
+		if(p->as == ADATABUNDLE)
+			o1 = 0xe125be70;
+		break;
 	}
 	
 	out[0] = o1;
@@ -2038,64 +2313,27 @@ if(0 /*debug['G']*/) print("%ux: %s: arm %d\n", (uint32)(p->pc), p->from.sym->na
 	out[4] = o5;
 	out[5] = o6;
 	return;
+}
 
-#ifdef NOTDEF
-	v = p->pc;
-	switch(o->size) {
-	default:
-		if(debug['a'])
-			Bprint(&bso, " %.8ux:\t\t%P\n", v, p);
-		break;
-	case 4:
-		if(debug['a'])
-			Bprint(&bso, " %.8ux: %.8ux\t%P\n", v, o1, p);
-		lputl(o1);
-		break;
-	case 8:
-		if(debug['a'])
-			Bprint(&bso, " %.8ux: %.8ux %.8ux%P\n", v, o1, o2, p);
-		lputl(o1);
-		lputl(o2);
-		break;
-	case 12:
-		if(debug['a'])
-			Bprint(&bso, " %.8ux: %.8ux %.8ux %.8ux%P\n", v, o1, o2, o3, p);
-		lputl(o1);
-		lputl(o2);
-		lputl(o3);
-		break;
-	case 16:
-		if(debug['a'])
-			Bprint(&bso, " %.8ux: %.8ux %.8ux %.8ux %.8ux%P\n",
-				v, o1, o2, o3, o4, p);
-		lputl(o1);
-		lputl(o2);
-		lputl(o3);
-		lputl(o4);
-		break;
-	case 20:
-		if(debug['a'])
-			Bprint(&bso, " %.8ux: %.8ux %.8ux %.8ux %.8ux %.8ux%P\n",
-				v, o1, o2, o3, o4, o5, p);
-		lputl(o1);
-		lputl(o2);
-		lputl(o3);
-		lputl(o4);
-		lputl(o5);
-		break;
-	case 24:
-		if(debug['a'])
-			Bprint(&bso, " %.8ux: %.8ux %.8ux %.8ux %.8ux %.8ux %.8ux%P\n",
-				v, o1, o2, o3, o4, o5, o6, p);
-		lputl(o1);
-		lputl(o2);
-		lputl(o3);
-		lputl(o4);
-		lputl(o5);
-		lputl(o6);
-		break;
-	}
-#endif
+static int32
+mov(Link *ctxt, Prog *p)
+{
+	int32 o1;
+	int rt, r;
+
+	aclass(ctxt, &p->from);
+	o1 = oprrr(ctxt, p->as, p->scond);
+	o1 |= p->from.offset;
+	rt = p->to.reg;
+	r = p->reg;
+	if(p->to.type == D_NONE)
+		rt = 0;
+	if(p->as == AMOVW || p->as == AMVN)
+		r = 0;
+	else if(r == NREG)
+		r = rt;
+	o1 |= (r<<16) | (rt<<12);
+	return o1;
 }
 
 static int32
diff --git a/src/liblink/asm6.c b/src/liblink/asm6.c
index 66afc7a..428eb94 100644
--- a/src/liblink/asm6.c
+++ b/src/liblink/asm6.c
@@ -35,7 +35,7 @@
 #include <bio.h>
 #include <link.h>
 #include "../cmd/6l/6.out.h"
-#include "../pkg/runtime/stack.h"
+#include "../runtime/stack.h"
 
 enum
 {
@@ -60,8 +60,6 @@ enum
 	FuncAlign = 16
 };
 
-extern char *anames6[];
-
 typedef	struct	Optab	Optab;
 typedef	struct	Movtab	Movtab;
 
@@ -187,7 +185,7 @@ enum
 	Maxand	= 10,		/* in -a output width of the byte codes */
 };
 
-static char ycover[Ymax*Ymax];
+static uchar ycover[Ymax*Ymax];
 static	int	reg[D_NONE];
 static	int	regrex[D_NONE+1];
 static	void	asmins(Link *ctxt, Prog *p);
@@ -821,722 +819,735 @@ static uchar	yaes2[] =
  * encoded addressing mode for the Yml arg), and then a single immediate byte.
  * Zilo_m is the same but a long (32-bit) immediate.
  */
-Optab optab[] =
+static Optab optab[] =
 /*	as, ytab, andproto, opcode */
 {
 	{ AXXX },
-	{ AAAA,		ynone,	P32, 0x37 },
-	{ AAAD,		ynone,	P32, 0xd5,0x0a },
-	{ AAAM,		ynone,	P32, 0xd4,0x0a },
-	{ AAAS,		ynone,	P32, 0x3f },
-	{ AADCB,	yxorb,	Pb, 0x14,0x80,(02),0x10,0x10 },
-	{ AADCL,	yxorl,	Px, 0x83,(02),0x15,0x81,(02),0x11,0x13 },
-	{ AADCQ,	yxorl,	Pw, 0x83,(02),0x15,0x81,(02),0x11,0x13 },
-	{ AADCW,	yxorl,	Pe, 0x83,(02),0x15,0x81,(02),0x11,0x13 },
-	{ AADDB,	yxorb,	Pb, 0x04,0x80,(00),0x00,0x02 },
-	{ AADDL,	yaddl,	Px, 0x83,(00),0x05,0x81,(00),0x01,0x03 },
-	{ AADDPD,	yxm,	Pq, 0x58 },
-	{ AADDPS,	yxm,	Pm, 0x58 },
-	{ AADDQ,	yaddl,	Pw, 0x83,(00),0x05,0x81,(00),0x01,0x03 },
-	{ AADDSD,	yxm,	Pf2, 0x58 },
-	{ AADDSS,	yxm,	Pf3, 0x58 },
-	{ AADDW,	yaddl,	Pe, 0x83,(00),0x05,0x81,(00),0x01,0x03 },
+	{ AAAA,		ynone,	P32, {0x37} },
+	{ AAAD,		ynone,	P32, {0xd5,0x0a} },
+	{ AAAM,		ynone,	P32, {0xd4,0x0a} },
+	{ AAAS,		ynone,	P32, {0x3f} },
+	{ AADCB,	yxorb,	Pb, {0x14,0x80,(02),0x10,0x10} },
+	{ AADCL,	yxorl,	Px, {0x83,(02),0x15,0x81,(02),0x11,0x13} },
+	{ AADCQ,	yxorl,	Pw, {0x83,(02),0x15,0x81,(02),0x11,0x13} },
+	{ AADCW,	yxorl,	Pe, {0x83,(02),0x15,0x81,(02),0x11,0x13} },
+	{ AADDB,	yxorb,	Pb, {0x04,0x80,(00),0x00,0x02} },
+	{ AADDL,	yaddl,	Px, {0x83,(00),0x05,0x81,(00),0x01,0x03} },
+	{ AADDPD,	yxm,	Pq, {0x58} },
+	{ AADDPS,	yxm,	Pm, {0x58} },
+	{ AADDQ,	yaddl,	Pw, {0x83,(00),0x05,0x81,(00),0x01,0x03} },
+	{ AADDSD,	yxm,	Pf2, {0x58} },
+	{ AADDSS,	yxm,	Pf3, {0x58} },
+	{ AADDW,	yaddl,	Pe, {0x83,(00),0x05,0x81,(00),0x01,0x03} },
 	{ AADJSP },
-	{ AANDB,	yxorb,	Pb, 0x24,0x80,(04),0x20,0x22 },
-	{ AANDL,	yxorl,	Px, 0x83,(04),0x25,0x81,(04),0x21,0x23 },
-	{ AANDNPD,	yxm,	Pq, 0x55 },
-	{ AANDNPS,	yxm,	Pm, 0x55 },
-	{ AANDPD,	yxm,	Pq, 0x54 },
-	{ AANDPS,	yxm,	Pq, 0x54 },
-	{ AANDQ,	yxorl,	Pw, 0x83,(04),0x25,0x81,(04),0x21,0x23 },
-	{ AANDW,	yxorl,	Pe, 0x83,(04),0x25,0x81,(04),0x21,0x23 },
-	{ AARPL,	yrl_ml,	P32, 0x63 },
-	{ ABOUNDL,	yrl_m,	P32, 0x62 },
-	{ ABOUNDW,	yrl_m,	Pe, 0x62 },
-	{ ABSFL,	yml_rl,	Pm, 0xbc },
-	{ ABSFQ,	yml_rl,	Pw, 0x0f,0xbc },
-	{ ABSFW,	yml_rl,	Pq, 0xbc },
-	{ ABSRL,	yml_rl,	Pm, 0xbd },
-	{ ABSRQ,	yml_rl,	Pw, 0x0f,0xbd },
-	{ ABSRW,	yml_rl,	Pq, 0xbd },
-	{ ABSWAPL,	ybswap,	Px, 0x0f,0xc8 },
-	{ ABSWAPQ,	ybswap,	Pw, 0x0f,0xc8 },
-	{ ABTCL,	ybtl,	Pm, 0xba,(07),0xbb },
-	{ ABTCQ,	ybtl,	Pw, 0x0f,0xba,(07),0x0f,0xbb },
-	{ ABTCW,	ybtl,	Pq, 0xba,(07),0xbb },
-	{ ABTL,		ybtl,	Pm, 0xba,(04),0xa3 },
-	{ ABTQ,		ybtl,	Pw, 0x0f,0xba,(04),0x0f,0xa3},
-	{ ABTRL,	ybtl,	Pm, 0xba,(06),0xb3 },
-	{ ABTRQ,	ybtl,	Pw, 0x0f,0xba,(06),0x0f,0xb3 },
-	{ ABTRW,	ybtl,	Pq, 0xba,(06),0xb3 },
-	{ ABTSL,	ybtl,	Pm, 0xba,(05),0xab  },
-	{ ABTSQ,	ybtl,	Pw, 0x0f,0xba,(05),0x0f,0xab },
-	{ ABTSW,	ybtl,	Pq, 0xba,(05),0xab  },
-	{ ABTW,		ybtl,	Pq, 0xba,(04),0xa3 },
-	{ ABYTE,	ybyte,	Px, 1 },
-	{ ACALL,	ycall,	Px, 0xff,(02),0xe8 },
-	{ ACDQ,		ynone,	Px, 0x99 },
-	{ ACLC,		ynone,	Px, 0xf8 },
-	{ ACLD,		ynone,	Px, 0xfc },
-	{ ACLI,		ynone,	Px, 0xfa },
-	{ ACLTS,	ynone,	Pm, 0x06 },
-	{ ACMC,		ynone,	Px, 0xf5 },
-	{ ACMOVLCC,	yml_rl,	Pm, 0x43 },
-	{ ACMOVLCS,	yml_rl,	Pm, 0x42 },
-	{ ACMOVLEQ,	yml_rl,	Pm, 0x44 },
-	{ ACMOVLGE,	yml_rl,	Pm, 0x4d },
-	{ ACMOVLGT,	yml_rl,	Pm, 0x4f },
-	{ ACMOVLHI,	yml_rl,	Pm, 0x47 },
-	{ ACMOVLLE,	yml_rl,	Pm, 0x4e },
-	{ ACMOVLLS,	yml_rl,	Pm, 0x46 },
-	{ ACMOVLLT,	yml_rl,	Pm, 0x4c },
-	{ ACMOVLMI,	yml_rl,	Pm, 0x48 },
-	{ ACMOVLNE,	yml_rl,	Pm, 0x45 },
-	{ ACMOVLOC,	yml_rl,	Pm, 0x41 },
-	{ ACMOVLOS,	yml_rl,	Pm, 0x40 },
-	{ ACMOVLPC,	yml_rl,	Pm, 0x4b },
-	{ ACMOVLPL,	yml_rl,	Pm, 0x49 },
-	{ ACMOVLPS,	yml_rl,	Pm, 0x4a },
-	{ ACMOVQCC,	yml_rl,	Pw, 0x0f,0x43 },
-	{ ACMOVQCS,	yml_rl,	Pw, 0x0f,0x42 },
-	{ ACMOVQEQ,	yml_rl,	Pw, 0x0f,0x44 },
-	{ ACMOVQGE,	yml_rl,	Pw, 0x0f,0x4d },
-	{ ACMOVQGT,	yml_rl,	Pw, 0x0f,0x4f },
-	{ ACMOVQHI,	yml_rl,	Pw, 0x0f,0x47 },
-	{ ACMOVQLE,	yml_rl,	Pw, 0x0f,0x4e },
-	{ ACMOVQLS,	yml_rl,	Pw, 0x0f,0x46 },
-	{ ACMOVQLT,	yml_rl,	Pw, 0x0f,0x4c },
-	{ ACMOVQMI,	yml_rl,	Pw, 0x0f,0x48 },
-	{ ACMOVQNE,	yml_rl,	Pw, 0x0f,0x45 },
-	{ ACMOVQOC,	yml_rl,	Pw, 0x0f,0x41 },
-	{ ACMOVQOS,	yml_rl,	Pw, 0x0f,0x40 },
-	{ ACMOVQPC,	yml_rl,	Pw, 0x0f,0x4b },
-	{ ACMOVQPL,	yml_rl,	Pw, 0x0f,0x49 },
-	{ ACMOVQPS,	yml_rl,	Pw, 0x0f,0x4a },
-	{ ACMOVWCC,	yml_rl,	Pq, 0x43 },
-	{ ACMOVWCS,	yml_rl,	Pq, 0x42 },
-	{ ACMOVWEQ,	yml_rl,	Pq, 0x44 },
-	{ ACMOVWGE,	yml_rl,	Pq, 0x4d },
-	{ ACMOVWGT,	yml_rl,	Pq, 0x4f },
-	{ ACMOVWHI,	yml_rl,	Pq, 0x47 },
-	{ ACMOVWLE,	yml_rl,	Pq, 0x4e },
-	{ ACMOVWLS,	yml_rl,	Pq, 0x46 },
-	{ ACMOVWLT,	yml_rl,	Pq, 0x4c },
-	{ ACMOVWMI,	yml_rl,	Pq, 0x48 },
-	{ ACMOVWNE,	yml_rl,	Pq, 0x45 },
-	{ ACMOVWOC,	yml_rl,	Pq, 0x41 },
-	{ ACMOVWOS,	yml_rl,	Pq, 0x40 },
-	{ ACMOVWPC,	yml_rl,	Pq, 0x4b },
-	{ ACMOVWPL,	yml_rl,	Pq, 0x49 },
-	{ ACMOVWPS,	yml_rl,	Pq, 0x4a },
-	{ ACMPB,	ycmpb,	Pb, 0x3c,0x80,(07),0x38,0x3a },
-	{ ACMPL,	ycmpl,	Px, 0x83,(07),0x3d,0x81,(07),0x39,0x3b },
-	{ ACMPPD,	yxcmpi,	Px, Pe,0xc2 },
-	{ ACMPPS,	yxcmpi,	Pm, 0xc2,0 },
-	{ ACMPQ,	ycmpl,	Pw, 0x83,(07),0x3d,0x81,(07),0x39,0x3b },
-	{ ACMPSB,	ynone,	Pb, 0xa6 },
-	{ ACMPSD,	yxcmpi,	Px, Pf2,0xc2 },
-	{ ACMPSL,	ynone,	Px, 0xa7 },
-	{ ACMPSQ,	ynone,	Pw, 0xa7 },
-	{ ACMPSS,	yxcmpi,	Px, Pf3,0xc2 },
-	{ ACMPSW,	ynone,	Pe, 0xa7 },
-	{ ACMPW,	ycmpl,	Pe, 0x83,(07),0x3d,0x81,(07),0x39,0x3b },
-	{ ACOMISD,	yxcmp,	Pe, 0x2f },
-	{ ACOMISS,	yxcmp,	Pm, 0x2f },
-	{ ACPUID,	ynone,	Pm, 0xa2 },
-	{ ACVTPL2PD,	yxcvm2,	Px, Pf3,0xe6,Pe,0x2a },
-	{ ACVTPL2PS,	yxcvm2,	Pm, 0x5b,0,0x2a,0, },
-	{ ACVTPD2PL,	yxcvm1,	Px, Pf2,0xe6,Pe,0x2d },
-	{ ACVTPD2PS,	yxm,	Pe, 0x5a },
-	{ ACVTPS2PL,	yxcvm1, Px, Pe,0x5b,Pm,0x2d },
-	{ ACVTPS2PD,	yxm,	Pm, 0x5a },
-	{ API2FW,	ymfp,	Px, 0x0c },
-	{ ACVTSD2SL,	yxcvfl, Pf2, 0x2d },
-	{ ACVTSD2SQ,	yxcvfq, Pw, Pf2,0x2d },
-	{ ACVTSD2SS,	yxm,	Pf2, 0x5a },
-	{ ACVTSL2SD,	yxcvlf, Pf2, 0x2a },
-	{ ACVTSQ2SD,	yxcvqf, Pw, Pf2,0x2a },
-	{ ACVTSL2SS,	yxcvlf, Pf3, 0x2a },
-	{ ACVTSQ2SS,	yxcvqf, Pw, Pf3,0x2a },
-	{ ACVTSS2SD,	yxm,	Pf3, 0x5a },
-	{ ACVTSS2SL,	yxcvfl, Pf3, 0x2d },
-	{ ACVTSS2SQ,	yxcvfq, Pw, Pf3,0x2d },
-	{ ACVTTPD2PL,	yxcvm1,	Px, Pe,0xe6,Pe,0x2c },
-	{ ACVTTPS2PL,	yxcvm1,	Px, Pf3,0x5b,Pm,0x2c },
-	{ ACVTTSD2SL,	yxcvfl, Pf2, 0x2c },
-	{ ACVTTSD2SQ,	yxcvfq, Pw, Pf2,0x2c },
-	{ ACVTTSS2SL,	yxcvfl,	Pf3, 0x2c },
-	{ ACVTTSS2SQ,	yxcvfq, Pw, Pf3,0x2c },
-	{ ACWD,		ynone,	Pe, 0x99 },
-	{ ACQO,		ynone,	Pw, 0x99 },
-	{ ADAA,		ynone,	P32, 0x27 },
-	{ ADAS,		ynone,	P32, 0x2f },
+	{ AANDB,	yxorb,	Pb, {0x24,0x80,(04),0x20,0x22} },
+	{ AANDL,	yxorl,	Px, {0x83,(04),0x25,0x81,(04),0x21,0x23} },
+	{ AANDNPD,	yxm,	Pq, {0x55} },
+	{ AANDNPS,	yxm,	Pm, {0x55} },
+	{ AANDPD,	yxm,	Pq, {0x54} },
+	{ AANDPS,	yxm,	Pq, {0x54} },
+	{ AANDQ,	yxorl,	Pw, {0x83,(04),0x25,0x81,(04),0x21,0x23} },
+	{ AANDW,	yxorl,	Pe, {0x83,(04),0x25,0x81,(04),0x21,0x23} },
+	{ AARPL,	yrl_ml,	P32, {0x63} },
+	{ ABOUNDL,	yrl_m,	P32, {0x62} },
+	{ ABOUNDW,	yrl_m,	Pe, {0x62} },
+	{ ABSFL,	yml_rl,	Pm, {0xbc} },
+	{ ABSFQ,	yml_rl,	Pw, {0x0f,0xbc} },
+	{ ABSFW,	yml_rl,	Pq, {0xbc} },
+	{ ABSRL,	yml_rl,	Pm, {0xbd} },
+	{ ABSRQ,	yml_rl,	Pw, {0x0f,0xbd} },
+	{ ABSRW,	yml_rl,	Pq, {0xbd} },
+	{ ABSWAPL,	ybswap,	Px, {0x0f,0xc8} },
+	{ ABSWAPQ,	ybswap,	Pw, {0x0f,0xc8} },
+	{ ABTCL,	ybtl,	Pm, {0xba,(07),0xbb} },
+	{ ABTCQ,	ybtl,	Pw, {0x0f,0xba,(07),0x0f,0xbb} },
+	{ ABTCW,	ybtl,	Pq, {0xba,(07),0xbb} },
+	{ ABTL,		ybtl,	Pm, {0xba,(04),0xa3} },
+	{ ABTQ,		ybtl,	Pw, {0x0f,0xba,(04),0x0f,0xa3}},
+	{ ABTRL,	ybtl,	Pm, {0xba,(06),0xb3} },
+	{ ABTRQ,	ybtl,	Pw, {0x0f,0xba,(06),0x0f,0xb3} },
+	{ ABTRW,	ybtl,	Pq, {0xba,(06),0xb3} },
+	{ ABTSL,	ybtl,	Pm, {0xba,(05),0xab } },
+	{ ABTSQ,	ybtl,	Pw, {0x0f,0xba,(05),0x0f,0xab} },
+	{ ABTSW,	ybtl,	Pq, {0xba,(05),0xab } },
+	{ ABTW,		ybtl,	Pq, {0xba,(04),0xa3} },
+	{ ABYTE,	ybyte,	Px, {1} },
+	{ ACALL,	ycall,	Px, {0xff,(02),0xe8} },
+	{ ACDQ,		ynone,	Px, {0x99} },
+	{ ACLC,		ynone,	Px, {0xf8} },
+	{ ACLD,		ynone,	Px, {0xfc} },
+	{ ACLI,		ynone,	Px, {0xfa} },
+	{ ACLTS,	ynone,	Pm, {0x06} },
+	{ ACMC,		ynone,	Px, {0xf5} },
+	{ ACMOVLCC,	yml_rl,	Pm, {0x43} },
+	{ ACMOVLCS,	yml_rl,	Pm, {0x42} },
+	{ ACMOVLEQ,	yml_rl,	Pm, {0x44} },
+	{ ACMOVLGE,	yml_rl,	Pm, {0x4d} },
+	{ ACMOVLGT,	yml_rl,	Pm, {0x4f} },
+	{ ACMOVLHI,	yml_rl,	Pm, {0x47} },
+	{ ACMOVLLE,	yml_rl,	Pm, {0x4e} },
+	{ ACMOVLLS,	yml_rl,	Pm, {0x46} },
+	{ ACMOVLLT,	yml_rl,	Pm, {0x4c} },
+	{ ACMOVLMI,	yml_rl,	Pm, {0x48} },
+	{ ACMOVLNE,	yml_rl,	Pm, {0x45} },
+	{ ACMOVLOC,	yml_rl,	Pm, {0x41} },
+	{ ACMOVLOS,	yml_rl,	Pm, {0x40} },
+	{ ACMOVLPC,	yml_rl,	Pm, {0x4b} },
+	{ ACMOVLPL,	yml_rl,	Pm, {0x49} },
+	{ ACMOVLPS,	yml_rl,	Pm, {0x4a} },
+	{ ACMOVQCC,	yml_rl,	Pw, {0x0f,0x43} },
+	{ ACMOVQCS,	yml_rl,	Pw, {0x0f,0x42} },
+	{ ACMOVQEQ,	yml_rl,	Pw, {0x0f,0x44} },
+	{ ACMOVQGE,	yml_rl,	Pw, {0x0f,0x4d} },
+	{ ACMOVQGT,	yml_rl,	Pw, {0x0f,0x4f} },
+	{ ACMOVQHI,	yml_rl,	Pw, {0x0f,0x47} },
+	{ ACMOVQLE,	yml_rl,	Pw, {0x0f,0x4e} },
+	{ ACMOVQLS,	yml_rl,	Pw, {0x0f,0x46} },
+	{ ACMOVQLT,	yml_rl,	Pw, {0x0f,0x4c} },
+	{ ACMOVQMI,	yml_rl,	Pw, {0x0f,0x48} },
+	{ ACMOVQNE,	yml_rl,	Pw, {0x0f,0x45} },
+	{ ACMOVQOC,	yml_rl,	Pw, {0x0f,0x41} },
+	{ ACMOVQOS,	yml_rl,	Pw, {0x0f,0x40} },
+	{ ACMOVQPC,	yml_rl,	Pw, {0x0f,0x4b} },
+	{ ACMOVQPL,	yml_rl,	Pw, {0x0f,0x49} },
+	{ ACMOVQPS,	yml_rl,	Pw, {0x0f,0x4a} },
+	{ ACMOVWCC,	yml_rl,	Pq, {0x43} },
+	{ ACMOVWCS,	yml_rl,	Pq, {0x42} },
+	{ ACMOVWEQ,	yml_rl,	Pq, {0x44} },
+	{ ACMOVWGE,	yml_rl,	Pq, {0x4d} },
+	{ ACMOVWGT,	yml_rl,	Pq, {0x4f} },
+	{ ACMOVWHI,	yml_rl,	Pq, {0x47} },
+	{ ACMOVWLE,	yml_rl,	Pq, {0x4e} },
+	{ ACMOVWLS,	yml_rl,	Pq, {0x46} },
+	{ ACMOVWLT,	yml_rl,	Pq, {0x4c} },
+	{ ACMOVWMI,	yml_rl,	Pq, {0x48} },
+	{ ACMOVWNE,	yml_rl,	Pq, {0x45} },
+	{ ACMOVWOC,	yml_rl,	Pq, {0x41} },
+	{ ACMOVWOS,	yml_rl,	Pq, {0x40} },
+	{ ACMOVWPC,	yml_rl,	Pq, {0x4b} },
+	{ ACMOVWPL,	yml_rl,	Pq, {0x49} },
+	{ ACMOVWPS,	yml_rl,	Pq, {0x4a} },
+	{ ACMPB,	ycmpb,	Pb, {0x3c,0x80,(07),0x38,0x3a} },
+	{ ACMPL,	ycmpl,	Px, {0x83,(07),0x3d,0x81,(07),0x39,0x3b} },
+	{ ACMPPD,	yxcmpi,	Px, {Pe,0xc2} },
+	{ ACMPPS,	yxcmpi,	Pm, {0xc2,0} },
+	{ ACMPQ,	ycmpl,	Pw, {0x83,(07),0x3d,0x81,(07),0x39,0x3b} },
+	{ ACMPSB,	ynone,	Pb, {0xa6} },
+	{ ACMPSD,	yxcmpi,	Px, {Pf2,0xc2} },
+	{ ACMPSL,	ynone,	Px, {0xa7} },
+	{ ACMPSQ,	ynone,	Pw, {0xa7} },
+	{ ACMPSS,	yxcmpi,	Px, {Pf3,0xc2} },
+	{ ACMPSW,	ynone,	Pe, {0xa7} },
+	{ ACMPW,	ycmpl,	Pe, {0x83,(07),0x3d,0x81,(07),0x39,0x3b} },
+	{ ACOMISD,	yxcmp,	Pe, {0x2f} },
+	{ ACOMISS,	yxcmp,	Pm, {0x2f} },
+	{ ACPUID,	ynone,	Pm, {0xa2} },
+	{ ACVTPL2PD,	yxcvm2,	Px, {Pf3,0xe6,Pe,0x2a} },
+	{ ACVTPL2PS,	yxcvm2,	Pm, {0x5b,0,0x2a,0,} },
+	{ ACVTPD2PL,	yxcvm1,	Px, {Pf2,0xe6,Pe,0x2d} },
+	{ ACVTPD2PS,	yxm,	Pe, {0x5a} },
+	{ ACVTPS2PL,	yxcvm1, Px, {Pe,0x5b,Pm,0x2d} },
+	{ ACVTPS2PD,	yxm,	Pm, {0x5a} },
+	{ API2FW,	ymfp,	Px, {0x0c} },
+	{ ACVTSD2SL,	yxcvfl, Pf2, {0x2d} },
+	{ ACVTSD2SQ,	yxcvfq, Pw, {Pf2,0x2d} },
+	{ ACVTSD2SS,	yxm,	Pf2, {0x5a} },
+	{ ACVTSL2SD,	yxcvlf, Pf2, {0x2a} },
+	{ ACVTSQ2SD,	yxcvqf, Pw, {Pf2,0x2a} },
+	{ ACVTSL2SS,	yxcvlf, Pf3, {0x2a} },
+	{ ACVTSQ2SS,	yxcvqf, Pw, {Pf3,0x2a} },
+	{ ACVTSS2SD,	yxm,	Pf3, {0x5a} },
+	{ ACVTSS2SL,	yxcvfl, Pf3, {0x2d} },
+	{ ACVTSS2SQ,	yxcvfq, Pw, {Pf3,0x2d} },
+	{ ACVTTPD2PL,	yxcvm1,	Px, {Pe,0xe6,Pe,0x2c} },
+	{ ACVTTPS2PL,	yxcvm1,	Px, {Pf3,0x5b,Pm,0x2c} },
+	{ ACVTTSD2SL,	yxcvfl, Pf2, {0x2c} },
+	{ ACVTTSD2SQ,	yxcvfq, Pw, {Pf2,0x2c} },
+	{ ACVTTSS2SL,	yxcvfl,	Pf3, {0x2c} },
+	{ ACVTTSS2SQ,	yxcvfq, Pw, {Pf3,0x2c} },
+	{ ACWD,		ynone,	Pe, {0x99} },
+	{ ACQO,		ynone,	Pw, {0x99} },
+	{ ADAA,		ynone,	P32, {0x27} },
+	{ ADAS,		ynone,	P32, {0x2f} },
 	{ ADATA },
-	{ ADECB,	yincb,	Pb, 0xfe,(01) },
-	{ ADECL,	yincl,	Px, 0xff,(01) },
-	{ ADECQ,	yincl,	Pw, 0xff,(01) },
-	{ ADECW,	yincw,	Pe, 0xff,(01) },
-	{ ADIVB,	ydivb,	Pb, 0xf6,(06) },
-	{ ADIVL,	ydivl,	Px, 0xf7,(06) },
-	{ ADIVPD,	yxm,	Pe, 0x5e },
-	{ ADIVPS,	yxm,	Pm, 0x5e },
-	{ ADIVQ,	ydivl,	Pw, 0xf7,(06) },
-	{ ADIVSD,	yxm,	Pf2, 0x5e },
-	{ ADIVSS,	yxm,	Pf3, 0x5e },
-	{ ADIVW,	ydivl,	Pe, 0xf7,(06) },
-	{ AEMMS,	ynone,	Pm, 0x77 },
+	{ ADECB,	yincb,	Pb, {0xfe,(01)} },
+	{ ADECL,	yincl,	Px, {0xff,(01)} },
+	{ ADECQ,	yincl,	Pw, {0xff,(01)} },
+	{ ADECW,	yincw,	Pe, {0xff,(01)} },
+	{ ADIVB,	ydivb,	Pb, {0xf6,(06)} },
+	{ ADIVL,	ydivl,	Px, {0xf7,(06)} },
+	{ ADIVPD,	yxm,	Pe, {0x5e} },
+	{ ADIVPS,	yxm,	Pm, {0x5e} },
+	{ ADIVQ,	ydivl,	Pw, {0xf7,(06)} },
+	{ ADIVSD,	yxm,	Pf2, {0x5e} },
+	{ ADIVSS,	yxm,	Pf3, {0x5e} },
+	{ ADIVW,	ydivl,	Pe, {0xf7,(06)} },
+	{ AEMMS,	ynone,	Pm, {0x77} },
 	{ AENTER },				/* botch */
-	{ AFXRSTOR,	ysvrs,	Pm, 0xae,(01),0xae,(01) },
-	{ AFXSAVE,	ysvrs,	Pm, 0xae,(00),0xae,(00) },
-	{ AFXRSTOR64,	ysvrs,	Pw, 0x0f,0xae,(01),0x0f,0xae,(01) },
-	{ AFXSAVE64,	ysvrs,	Pw, 0x0f,0xae,(00),0x0f,0xae,(00) },
+	{ AFXRSTOR,	ysvrs,	Pm, {0xae,(01),0xae,(01)} },
+	{ AFXSAVE,	ysvrs,	Pm, {0xae,(00),0xae,(00)} },
+	{ AFXRSTOR64,	ysvrs,	Pw, {0x0f,0xae,(01),0x0f,0xae,(01)} },
+	{ AFXSAVE64,	ysvrs,	Pw, {0x0f,0xae,(00),0x0f,0xae,(00)} },
 	{ AGLOBL },
 	{ AGOK },
 	{ AHISTORY },
-	{ AHLT,		ynone,	Px, 0xf4 },
-	{ AIDIVB,	ydivb,	Pb, 0xf6,(07) },
-	{ AIDIVL,	ydivl,	Px, 0xf7,(07) },
-	{ AIDIVQ,	ydivl,	Pw, 0xf7,(07) },
-	{ AIDIVW,	ydivl,	Pe, 0xf7,(07) },
-	{ AIMULB,	ydivb,	Pb, 0xf6,(05) },
-	{ AIMULL,	yimul,	Px, 0xf7,(05),0x6b,0x69,Pm,0xaf },
-	{ AIMULQ,	yimul,	Pw, 0xf7,(05),0x6b,0x69,Pm,0xaf },
-	{ AIMULW,	yimul,	Pe, 0xf7,(05),0x6b,0x69,Pm,0xaf },
-	{ AIMUL3Q,	yimul3,	Pw, 0x6b,(00) },
-	{ AINB,		yin,	Pb, 0xe4,0xec },
-	{ AINCB,	yincb,	Pb, 0xfe,(00) },
-	{ AINCL,	yincl,	Px, 0xff,(00) },
-	{ AINCQ,	yincl,	Pw, 0xff,(00) },
-	{ AINCW,	yincw,	Pe, 0xff,(00) },
-	{ AINL,		yin,	Px, 0xe5,0xed },
-	{ AINSB,	ynone,	Pb, 0x6c },
-	{ AINSL,	ynone,	Px, 0x6d },
-	{ AINSW,	ynone,	Pe, 0x6d },
-	{ AINT,		yint,	Px, 0xcd },
-	{ AINTO,	ynone,	P32, 0xce },
-	{ AINW,		yin,	Pe, 0xe5,0xed },
-	{ AIRETL,	ynone,	Px, 0xcf },
-	{ AIRETQ,	ynone,	Pw, 0xcf },
-	{ AIRETW,	ynone,	Pe, 0xcf },
-	{ AJCC,		yjcond,	Px, 0x73,0x83,(00) },
-	{ AJCS,		yjcond,	Px, 0x72,0x82 },
-	{ AJCXZL,	yloop,	Px, 0xe3 },
-	{ AJCXZQ,	yloop,	Px, 0xe3 },
-	{ AJEQ,		yjcond,	Px, 0x74,0x84 },
-	{ AJGE,		yjcond,	Px, 0x7d,0x8d },
-	{ AJGT,		yjcond,	Px, 0x7f,0x8f },
-	{ AJHI,		yjcond,	Px, 0x77,0x87 },
-	{ AJLE,		yjcond,	Px, 0x7e,0x8e },
-	{ AJLS,		yjcond,	Px, 0x76,0x86 },
-	{ AJLT,		yjcond,	Px, 0x7c,0x8c },
-	{ AJMI,		yjcond,	Px, 0x78,0x88 },
-	{ AJMP,		yjmp,	Px, 0xff,(04),0xeb,0xe9 },
-	{ AJNE,		yjcond,	Px, 0x75,0x85 },
-	{ AJOC,		yjcond,	Px, 0x71,0x81,(00) },
-	{ AJOS,		yjcond,	Px, 0x70,0x80,(00) },
-	{ AJPC,		yjcond,	Px, 0x7b,0x8b },
-	{ AJPL,		yjcond,	Px, 0x79,0x89 },
-	{ AJPS,		yjcond,	Px, 0x7a,0x8a },
-	{ ALAHF,	ynone,	Px, 0x9f },
-	{ ALARL,	yml_rl,	Pm, 0x02 },
-	{ ALARW,	yml_rl,	Pq, 0x02 },
-	{ ALDMXCSR,	ysvrs,	Pm, 0xae,(02),0xae,(02) },
-	{ ALEAL,	ym_rl,	Px, 0x8d },
-	{ ALEAQ,	ym_rl,	Pw, 0x8d },
-	{ ALEAVEL,	ynone,	P32, 0xc9 },
-	{ ALEAVEQ,	ynone,	Py, 0xc9 },
-	{ ALEAVEW,	ynone,	Pe, 0xc9 },
-	{ ALEAW,	ym_rl,	Pe, 0x8d },
-	{ ALOCK,	ynone,	Px, 0xf0 },
-	{ ALODSB,	ynone,	Pb, 0xac },
-	{ ALODSL,	ynone,	Px, 0xad },
-	{ ALODSQ,	ynone,	Pw, 0xad },
-	{ ALODSW,	ynone,	Pe, 0xad },
-	{ ALONG,	ybyte,	Px, 4 },
-	{ ALOOP,	yloop,	Px, 0xe2 },
-	{ ALOOPEQ,	yloop,	Px, 0xe1 },
-	{ ALOOPNE,	yloop,	Px, 0xe0 },
-	{ ALSLL,	yml_rl,	Pm, 0x03  },
-	{ ALSLW,	yml_rl,	Pq, 0x03  },
-	{ AMASKMOVOU,	yxr,	Pe, 0xf7 },
-	{ AMASKMOVQ,	ymr,	Pm, 0xf7 },
-	{ AMAXPD,	yxm,	Pe, 0x5f },
-	{ AMAXPS,	yxm,	Pm, 0x5f },
-	{ AMAXSD,	yxm,	Pf2, 0x5f },
-	{ AMAXSS,	yxm,	Pf3, 0x5f },
-	{ AMINPD,	yxm,	Pe, 0x5d },
-	{ AMINPS,	yxm,	Pm, 0x5d },
-	{ AMINSD,	yxm,	Pf2, 0x5d },
-	{ AMINSS,	yxm,	Pf3, 0x5d },
-	{ AMOVAPD,	yxmov,	Pe, 0x28,0x29 },
-	{ AMOVAPS,	yxmov,	Pm, 0x28,0x29 },
-	{ AMOVB,	ymovb,	Pb, 0x88,0x8a,0xb0,0xc6,(00) },
-	{ AMOVBLSX,	ymb_rl,	Pm, 0xbe },
-	{ AMOVBLZX,	ymb_rl,	Pm, 0xb6 },
-	{ AMOVBQSX,	ymb_rl,	Pw, 0x0f,0xbe },
-	{ AMOVBQZX,	ymb_rl,	Pw, 0x0f,0xb6 },
-	{ AMOVBWSX,	ymb_rl,	Pq, 0xbe },
-	{ AMOVBWZX,	ymb_rl,	Pq, 0xb6 },
-	{ AMOVO,	yxmov,	Pe, 0x6f,0x7f },
-	{ AMOVOU,	yxmov,	Pf3, 0x6f,0x7f },
-	{ AMOVHLPS,	yxr,	Pm, 0x12 },
-	{ AMOVHPD,	yxmov,	Pe, 0x16,0x17 },
-	{ AMOVHPS,	yxmov,	Pm, 0x16,0x17 },
-	{ AMOVL,	ymovl,	Px, 0x89,0x8b,0x31,0xb8,0xc7,(00),0x6e,0x7e,Pe,0x6e,Pe,0x7e,0 },
-	{ AMOVLHPS,	yxr,	Pm, 0x16 },
-	{ AMOVLPD,	yxmov,	Pe, 0x12,0x13 },
-	{ AMOVLPS,	yxmov,	Pm, 0x12,0x13 },
-	{ AMOVLQSX,	yml_rl,	Pw, 0x63 },
-	{ AMOVLQZX,	yml_rl,	Px, 0x8b },
-	{ AMOVMSKPD,	yxrrl,	Pq, 0x50 },
-	{ AMOVMSKPS,	yxrrl,	Pm, 0x50 },
-	{ AMOVNTO,	yxr_ml,	Pe, 0xe7 },
-	{ AMOVNTPD,	yxr_ml,	Pe, 0x2b },
-	{ AMOVNTPS,	yxr_ml,	Pm, 0x2b },
-	{ AMOVNTQ,	ymr_ml,	Pm, 0xe7 },
-	{ AMOVQ,	ymovq,	Pw, 0x89, 0x8b, 0x31, 0xc7,(00), 0xb8, 0xc7,(00), 0x6f, 0x7f, 0x6e, 0x7e, Pf2,0xd6, Pf3,0x7e, Pe,0xd6, Pe,0x6e, Pe,0x7e,0 },
-	{ AMOVQOZX,	ymrxr,	Pf3, 0xd6,0x7e },
-	{ AMOVSB,	ynone,	Pb, 0xa4 },
-	{ AMOVSD,	yxmov,	Pf2, 0x10,0x11 },
-	{ AMOVSL,	ynone,	Px, 0xa5 },
-	{ AMOVSQ,	ynone,	Pw, 0xa5 },
-	{ AMOVSS,	yxmov,	Pf3, 0x10,0x11 },
-	{ AMOVSW,	ynone,	Pe, 0xa5 },
-	{ AMOVUPD,	yxmov,	Pe, 0x10,0x11 },
-	{ AMOVUPS,	yxmov,	Pm, 0x10,0x11 },
-	{ AMOVW,	ymovw,	Pe, 0x89,0x8b,0x31,0xb8,0xc7,(00),0 },
-	{ AMOVWLSX,	yml_rl,	Pm, 0xbf },
-	{ AMOVWLZX,	yml_rl,	Pm, 0xb7 },
-	{ AMOVWQSX,	yml_rl,	Pw, 0x0f,0xbf },
-	{ AMOVWQZX,	yml_rl,	Pw, 0x0f,0xb7 },
-	{ AMULB,	ydivb,	Pb, 0xf6,(04) },
-	{ AMULL,	ydivl,	Px, 0xf7,(04) },
-	{ AMULPD,	yxm,	Pe, 0x59 },
-	{ AMULPS,	yxm,	Ym, 0x59 },
-	{ AMULQ,	ydivl,	Pw, 0xf7,(04) },
-	{ AMULSD,	yxm,	Pf2, 0x59 },
-	{ AMULSS,	yxm,	Pf3, 0x59 },
-	{ AMULW,	ydivl,	Pe, 0xf7,(04) },
+	{ AHLT,		ynone,	Px, {0xf4} },
+	{ AIDIVB,	ydivb,	Pb, {0xf6,(07)} },
+	{ AIDIVL,	ydivl,	Px, {0xf7,(07)} },
+	{ AIDIVQ,	ydivl,	Pw, {0xf7,(07)} },
+	{ AIDIVW,	ydivl,	Pe, {0xf7,(07)} },
+	{ AIMULB,	ydivb,	Pb, {0xf6,(05)} },
+	{ AIMULL,	yimul,	Px, {0xf7,(05),0x6b,0x69,Pm,0xaf} },
+	{ AIMULQ,	yimul,	Pw, {0xf7,(05),0x6b,0x69,Pm,0xaf} },
+	{ AIMULW,	yimul,	Pe, {0xf7,(05),0x6b,0x69,Pm,0xaf} },
+	{ AIMUL3Q,	yimul3,	Pw, {0x6b,(00)} },
+	{ AINB,		yin,	Pb, {0xe4,0xec} },
+	{ AINCB,	yincb,	Pb, {0xfe,(00)} },
+	{ AINCL,	yincl,	Px, {0xff,(00)} },
+	{ AINCQ,	yincl,	Pw, {0xff,(00)} },
+	{ AINCW,	yincw,	Pe, {0xff,(00)} },
+	{ AINL,		yin,	Px, {0xe5,0xed} },
+	{ AINSB,	ynone,	Pb, {0x6c} },
+	{ AINSL,	ynone,	Px, {0x6d} },
+	{ AINSW,	ynone,	Pe, {0x6d} },
+	{ AINT,		yint,	Px, {0xcd} },
+	{ AINTO,	ynone,	P32, {0xce} },
+	{ AINW,		yin,	Pe, {0xe5,0xed} },
+	{ AIRETL,	ynone,	Px, {0xcf} },
+	{ AIRETQ,	ynone,	Pw, {0xcf} },
+	{ AIRETW,	ynone,	Pe, {0xcf} },
+	{ AJCC,		yjcond,	Px, {0x73,0x83,(00)} },
+	{ AJCS,		yjcond,	Px, {0x72,0x82} },
+	{ AJCXZL,	yloop,	Px, {0xe3} },
+	{ AJCXZQ,	yloop,	Px, {0xe3} },
+	{ AJEQ,		yjcond,	Px, {0x74,0x84} },
+	{ AJGE,		yjcond,	Px, {0x7d,0x8d} },
+	{ AJGT,		yjcond,	Px, {0x7f,0x8f} },
+	{ AJHI,		yjcond,	Px, {0x77,0x87} },
+	{ AJLE,		yjcond,	Px, {0x7e,0x8e} },
+	{ AJLS,		yjcond,	Px, {0x76,0x86} },
+	{ AJLT,		yjcond,	Px, {0x7c,0x8c} },
+	{ AJMI,		yjcond,	Px, {0x78,0x88} },
+	{ AJMP,		yjmp,	Px, {0xff,(04),0xeb,0xe9} },
+	{ AJNE,		yjcond,	Px, {0x75,0x85} },
+	{ AJOC,		yjcond,	Px, {0x71,0x81,(00)} },
+	{ AJOS,		yjcond,	Px, {0x70,0x80,(00)} },
+	{ AJPC,		yjcond,	Px, {0x7b,0x8b} },
+	{ AJPL,		yjcond,	Px, {0x79,0x89} },
+	{ AJPS,		yjcond,	Px, {0x7a,0x8a} },
+	{ ALAHF,	ynone,	Px, {0x9f} },
+	{ ALARL,	yml_rl,	Pm, {0x02} },
+	{ ALARW,	yml_rl,	Pq, {0x02} },
+	{ ALDMXCSR,	ysvrs,	Pm, {0xae,(02),0xae,(02)} },
+	{ ALEAL,	ym_rl,	Px, {0x8d} },
+	{ ALEAQ,	ym_rl,	Pw, {0x8d} },
+	{ ALEAVEL,	ynone,	P32, {0xc9} },
+	{ ALEAVEQ,	ynone,	Py, {0xc9} },
+	{ ALEAVEW,	ynone,	Pe, {0xc9} },
+	{ ALEAW,	ym_rl,	Pe, {0x8d} },
+	{ ALOCK,	ynone,	Px, {0xf0} },
+	{ ALODSB,	ynone,	Pb, {0xac} },
+	{ ALODSL,	ynone,	Px, {0xad} },
+	{ ALODSQ,	ynone,	Pw, {0xad} },
+	{ ALODSW,	ynone,	Pe, {0xad} },
+	{ ALONG,	ybyte,	Px, {4} },
+	{ ALOOP,	yloop,	Px, {0xe2} },
+	{ ALOOPEQ,	yloop,	Px, {0xe1} },
+	{ ALOOPNE,	yloop,	Px, {0xe0} },
+	{ ALSLL,	yml_rl,	Pm, {0x03 } },
+	{ ALSLW,	yml_rl,	Pq, {0x03 } },
+	{ AMASKMOVOU,	yxr,	Pe, {0xf7} },
+	{ AMASKMOVQ,	ymr,	Pm, {0xf7} },
+	{ AMAXPD,	yxm,	Pe, {0x5f} },
+	{ AMAXPS,	yxm,	Pm, {0x5f} },
+	{ AMAXSD,	yxm,	Pf2, {0x5f} },
+	{ AMAXSS,	yxm,	Pf3, {0x5f} },
+	{ AMINPD,	yxm,	Pe, {0x5d} },
+	{ AMINPS,	yxm,	Pm, {0x5d} },
+	{ AMINSD,	yxm,	Pf2, {0x5d} },
+	{ AMINSS,	yxm,	Pf3, {0x5d} },
+	{ AMOVAPD,	yxmov,	Pe, {0x28,0x29} },
+	{ AMOVAPS,	yxmov,	Pm, {0x28,0x29} },
+	{ AMOVB,	ymovb,	Pb, {0x88,0x8a,0xb0,0xc6,(00)} },
+	{ AMOVBLSX,	ymb_rl,	Pm, {0xbe} },
+	{ AMOVBLZX,	ymb_rl,	Pm, {0xb6} },
+	{ AMOVBQSX,	ymb_rl,	Pw, {0x0f,0xbe} },
+	{ AMOVBQZX,	ymb_rl,	Pm, {0xb6} },
+	{ AMOVBWSX,	ymb_rl,	Pq, {0xbe} },
+	{ AMOVBWZX,	ymb_rl,	Pq, {0xb6} },
+	{ AMOVO,	yxmov,	Pe, {0x6f,0x7f} },
+	{ AMOVOU,	yxmov,	Pf3, {0x6f,0x7f} },
+	{ AMOVHLPS,	yxr,	Pm, {0x12} },
+	{ AMOVHPD,	yxmov,	Pe, {0x16,0x17} },
+	{ AMOVHPS,	yxmov,	Pm, {0x16,0x17} },
+	{ AMOVL,	ymovl,	Px, {0x89,0x8b,0x31,0xb8,0xc7,(00),0x6e,0x7e,Pe,0x6e,Pe,0x7e,0} },
+	{ AMOVLHPS,	yxr,	Pm, {0x16} },
+	{ AMOVLPD,	yxmov,	Pe, {0x12,0x13} },
+	{ AMOVLPS,	yxmov,	Pm, {0x12,0x13} },
+	{ AMOVLQSX,	yml_rl,	Pw, {0x63} },
+	{ AMOVLQZX,	yml_rl,	Px, {0x8b} },
+	{ AMOVMSKPD,	yxrrl,	Pq, {0x50} },
+	{ AMOVMSKPS,	yxrrl,	Pm, {0x50} },
+	{ AMOVNTO,	yxr_ml,	Pe, {0xe7} },
+	{ AMOVNTPD,	yxr_ml,	Pe, {0x2b} },
+	{ AMOVNTPS,	yxr_ml,	Pm, {0x2b} },
+	{ AMOVNTQ,	ymr_ml,	Pm, {0xe7} },
+	{ AMOVQ,	ymovq,	Pw, {0x89, 0x8b, 0x31, 0xc7,(00), 0xb8, 0xc7,(00), 0x6f, 0x7f, 0x6e, 0x7e, Pf2,0xd6, Pf3,0x7e, Pe,0xd6, Pe,0x6e, Pe,0x7e,0} },
+	{ AMOVQOZX,	ymrxr,	Pf3, {0xd6,0x7e} },
+	{ AMOVSB,	ynone,	Pb, {0xa4} },
+	{ AMOVSD,	yxmov,	Pf2, {0x10,0x11} },
+	{ AMOVSL,	ynone,	Px, {0xa5} },
+	{ AMOVSQ,	ynone,	Pw, {0xa5} },
+	{ AMOVSS,	yxmov,	Pf3, {0x10,0x11} },
+	{ AMOVSW,	ynone,	Pe, {0xa5} },
+	{ AMOVUPD,	yxmov,	Pe, {0x10,0x11} },
+	{ AMOVUPS,	yxmov,	Pm, {0x10,0x11} },
+	{ AMOVW,	ymovw,	Pe, {0x89,0x8b,0x31,0xb8,0xc7,(00),0} },
+	{ AMOVWLSX,	yml_rl,	Pm, {0xbf} },
+	{ AMOVWLZX,	yml_rl,	Pm, {0xb7} },
+	{ AMOVWQSX,	yml_rl,	Pw, {0x0f,0xbf} },
+	{ AMOVWQZX,	yml_rl,	Pw, {0x0f,0xb7} },
+	{ AMULB,	ydivb,	Pb, {0xf6,(04)} },
+	{ AMULL,	ydivl,	Px, {0xf7,(04)} },
+	{ AMULPD,	yxm,	Pe, {0x59} },
+	{ AMULPS,	yxm,	Ym, {0x59} },
+	{ AMULQ,	ydivl,	Pw, {0xf7,(04)} },
+	{ AMULSD,	yxm,	Pf2, {0x59} },
+	{ AMULSS,	yxm,	Pf3, {0x59} },
+	{ AMULW,	ydivl,	Pe, {0xf7,(04)} },
 	{ ANAME },
-	{ ANEGB,	yscond,	Pb, 0xf6,(03) },
-	{ ANEGL,	yscond,	Px, 0xf7,(03) },
-	{ ANEGQ,	yscond,	Pw, 0xf7,(03) },
-	{ ANEGW,	yscond,	Pe, 0xf7,(03) },
-	{ ANOP,		ynop,	Px, 0,0 },
-	{ ANOTB,	yscond,	Pb, 0xf6,(02) },
-	{ ANOTL,	yscond,	Px, 0xf7,(02) },
-	{ ANOTQ,	yscond,	Pw, 0xf7,(02) },
-	{ ANOTW,	yscond,	Pe, 0xf7,(02) },
-	{ AORB,		yxorb,	Pb, 0x0c,0x80,(01),0x08,0x0a },
-	{ AORL,		yxorl,	Px, 0x83,(01),0x0d,0x81,(01),0x09,0x0b },
-	{ AORPD,	yxm,	Pq, 0x56 },
-	{ AORPS,	yxm,	Pm, 0x56 },
-	{ AORQ,		yxorl,	Pw, 0x83,(01),0x0d,0x81,(01),0x09,0x0b },
-	{ AORW,		yxorl,	Pe, 0x83,(01),0x0d,0x81,(01),0x09,0x0b },
-	{ AOUTB,	yin,	Pb, 0xe6,0xee },
-	{ AOUTL,	yin,	Px, 0xe7,0xef },
-	{ AOUTSB,	ynone,	Pb, 0x6e },
-	{ AOUTSL,	ynone,	Px, 0x6f },
-	{ AOUTSW,	ynone,	Pe, 0x6f },
-	{ AOUTW,	yin,	Pe, 0xe7,0xef },
-	{ APACKSSLW,	ymm,	Py, 0x6b,Pe,0x6b },
-	{ APACKSSWB,	ymm,	Py, 0x63,Pe,0x63 },
-	{ APACKUSWB,	ymm,	Py, 0x67,Pe,0x67 },
-	{ APADDB,	ymm,	Py, 0xfc,Pe,0xfc },
-	{ APADDL,	ymm,	Py, 0xfe,Pe,0xfe },
-	{ APADDQ,	yxm,	Pe, 0xd4 },
-	{ APADDSB,	ymm,	Py, 0xec,Pe,0xec },
-	{ APADDSW,	ymm,	Py, 0xed,Pe,0xed },
-	{ APADDUSB,	ymm,	Py, 0xdc,Pe,0xdc },
-	{ APADDUSW,	ymm,	Py, 0xdd,Pe,0xdd },
-	{ APADDW,	ymm,	Py, 0xfd,Pe,0xfd },
-	{ APAND,	ymm,	Py, 0xdb,Pe,0xdb },
-	{ APANDN,	ymm,	Py, 0xdf,Pe,0xdf },
-	{ APAUSE,	ynone,	Px, 0xf3,0x90 },
-	{ APAVGB,	ymm,	Py, 0xe0,Pe,0xe0 },
-	{ APAVGW,	ymm,	Py, 0xe3,Pe,0xe3 },
-	{ APCMPEQB,	ymm,	Py, 0x74,Pe,0x74 },
-	{ APCMPEQL,	ymm,	Py, 0x76,Pe,0x76 },
-	{ APCMPEQW,	ymm,	Py, 0x75,Pe,0x75 },
-	{ APCMPGTB,	ymm,	Py, 0x64,Pe,0x64 },
-	{ APCMPGTL,	ymm,	Py, 0x66,Pe,0x66 },
-	{ APCMPGTW,	ymm,	Py, 0x65,Pe,0x65 },
-	{ APEXTRW,	yextrw,	Pq, 0xc5,(00) },
-	{ APF2IL,	ymfp,	Px, 0x1d },
-	{ APF2IW,	ymfp,	Px, 0x1c },
-	{ API2FL,	ymfp,	Px, 0x0d },
-	{ APFACC,	ymfp,	Px, 0xae },
-	{ APFADD,	ymfp,	Px, 0x9e },
-	{ APFCMPEQ,	ymfp,	Px, 0xb0 },
-	{ APFCMPGE,	ymfp,	Px, 0x90 },
-	{ APFCMPGT,	ymfp,	Px, 0xa0 },
-	{ APFMAX,	ymfp,	Px, 0xa4 },
-	{ APFMIN,	ymfp,	Px, 0x94 },
-	{ APFMUL,	ymfp,	Px, 0xb4 },
-	{ APFNACC,	ymfp,	Px, 0x8a },
-	{ APFPNACC,	ymfp,	Px, 0x8e },
-	{ APFRCP,	ymfp,	Px, 0x96 },
-	{ APFRCPIT1,	ymfp,	Px, 0xa6 },
-	{ APFRCPI2T,	ymfp,	Px, 0xb6 },
-	{ APFRSQIT1,	ymfp,	Px, 0xa7 },
-	{ APFRSQRT,	ymfp,	Px, 0x97 },
-	{ APFSUB,	ymfp,	Px, 0x9a },
-	{ APFSUBR,	ymfp,	Px, 0xaa },
-	{ APINSRW,	yinsrw,	Pq, 0xc4,(00) },
-	{ APINSRD,	yinsr,	Pq, 0x3a, 0x22, (00) },
-	{ APINSRQ,	yinsr,	Pq3, 0x3a, 0x22, (00) },
-	{ APMADDWL,	ymm,	Py, 0xf5,Pe,0xf5 },
-	{ APMAXSW,	yxm,	Pe, 0xee },
-	{ APMAXUB,	yxm,	Pe, 0xde },
-	{ APMINSW,	yxm,	Pe, 0xea },
-	{ APMINUB,	yxm,	Pe, 0xda },
-	{ APMOVMSKB,	ymskb,	Px, Pe,0xd7,0xd7 },
-	{ APMULHRW,	ymfp,	Px, 0xb7 },
-	{ APMULHUW,	ymm,	Py, 0xe4,Pe,0xe4 },
-	{ APMULHW,	ymm,	Py, 0xe5,Pe,0xe5 },
-	{ APMULLW,	ymm,	Py, 0xd5,Pe,0xd5 },
-	{ APMULULQ,	ymm,	Py, 0xf4,Pe,0xf4 },
-	{ APOPAL,	ynone,	P32, 0x61 },
-	{ APOPAW,	ynone,	Pe, 0x61 },
-	{ APOPFL,	ynone,	P32, 0x9d },
-	{ APOPFQ,	ynone,	Py, 0x9d },
-	{ APOPFW,	ynone,	Pe, 0x9d },
-	{ APOPL,	ypopl,	P32, 0x58,0x8f,(00) },
-	{ APOPQ,	ypopl,	Py, 0x58,0x8f,(00) },
-	{ APOPW,	ypopl,	Pe, 0x58,0x8f,(00) },
-	{ APOR,		ymm,	Py, 0xeb,Pe,0xeb },
-	{ APSADBW,	yxm,	Pq, 0xf6 },
-	{ APSHUFHW,	yxshuf,	Pf3, 0x70,(00) },
-	{ APSHUFL,	yxshuf,	Pq, 0x70,(00) },
-	{ APSHUFLW,	yxshuf,	Pf2, 0x70,(00) },
-	{ APSHUFW,	ymshuf,	Pm, 0x70,(00) },
-	{ APSHUFB,	ymshufb,Pq, 0x38, 0x00 },
-	{ APSLLO,	ypsdq,	Pq, 0x73,(07) },
-	{ APSLLL,	yps,	Py, 0xf2, 0x72,(06), Pe,0xf2, Pe,0x72,(06) },
-	{ APSLLQ,	yps,	Py, 0xf3, 0x73,(06), Pe,0xf3, Pe,0x73,(06) },
-	{ APSLLW,	yps,	Py, 0xf1, 0x71,(06), Pe,0xf1, Pe,0x71,(06) },
-	{ APSRAL,	yps,	Py, 0xe2, 0x72,(04), Pe,0xe2, Pe,0x72,(04) },
-	{ APSRAW,	yps,	Py, 0xe1, 0x71,(04), Pe,0xe1, Pe,0x71,(04) },
-	{ APSRLO,	ypsdq,	Pq, 0x73,(03) },
-	{ APSRLL,	yps,	Py, 0xd2, 0x72,(02), Pe,0xd2, Pe,0x72,(02) },
-	{ APSRLQ,	yps,	Py, 0xd3, 0x73,(02), Pe,0xd3, Pe,0x73,(02) },
-	{ APSRLW,	yps,	Py, 0xd1, 0x71,(02), Pe,0xe1, Pe,0x71,(02) },
-	{ APSUBB,	yxm,	Pe, 0xf8 },
-	{ APSUBL,	yxm,	Pe, 0xfa },
-	{ APSUBQ,	yxm,	Pe, 0xfb },
-	{ APSUBSB,	yxm,	Pe, 0xe8 },
-	{ APSUBSW,	yxm,	Pe, 0xe9 },
-	{ APSUBUSB,	yxm,	Pe, 0xd8 },
-	{ APSUBUSW,	yxm,	Pe, 0xd9 },
-	{ APSUBW,	yxm,	Pe, 0xf9 },
-	{ APSWAPL,	ymfp,	Px, 0xbb },
-	{ APUNPCKHBW,	ymm,	Py, 0x68,Pe,0x68 },
-	{ APUNPCKHLQ,	ymm,	Py, 0x6a,Pe,0x6a },
-	{ APUNPCKHQDQ,	yxm,	Pe, 0x6d },
-	{ APUNPCKHWL,	ymm,	Py, 0x69,Pe,0x69 },
-	{ APUNPCKLBW,	ymm,	Py, 0x60,Pe,0x60 },
-	{ APUNPCKLLQ,	ymm,	Py, 0x62,Pe,0x62 },
-	{ APUNPCKLQDQ,	yxm,	Pe, 0x6c },
-	{ APUNPCKLWL,	ymm,	Py, 0x61,Pe,0x61 },
-	{ APUSHAL,	ynone,	P32, 0x60 },
-	{ APUSHAW,	ynone,	Pe, 0x60 },
-	{ APUSHFL,	ynone,	P32, 0x9c },
-	{ APUSHFQ,	ynone,	Py, 0x9c },
-	{ APUSHFW,	ynone,	Pe, 0x9c },
-	{ APUSHL,	ypushl,	P32, 0x50,0xff,(06),0x6a,0x68 },
-	{ APUSHQ,	ypushl,	Py, 0x50,0xff,(06),0x6a,0x68 },
-	{ APUSHW,	ypushl,	Pe, 0x50,0xff,(06),0x6a,0x68 },
-	{ APXOR,	ymm,	Py, 0xef,Pe,0xef },
-	{ AQUAD,	ybyte,	Px, 8 },
-	{ ARCLB,	yshb,	Pb, 0xd0,(02),0xc0,(02),0xd2,(02) },
-	{ ARCLL,	yshl,	Px, 0xd1,(02),0xc1,(02),0xd3,(02),0xd3,(02) },
-	{ ARCLQ,	yshl,	Pw, 0xd1,(02),0xc1,(02),0xd3,(02),0xd3,(02) },
-	{ ARCLW,	yshl,	Pe, 0xd1,(02),0xc1,(02),0xd3,(02),0xd3,(02) },
-	{ ARCPPS,	yxm,	Pm, 0x53 },
-	{ ARCPSS,	yxm,	Pf3, 0x53 },
-	{ ARCRB,	yshb,	Pb, 0xd0,(03),0xc0,(03),0xd2,(03) },
-	{ ARCRL,	yshl,	Px, 0xd1,(03),0xc1,(03),0xd3,(03),0xd3,(03) },
-	{ ARCRQ,	yshl,	Pw, 0xd1,(03),0xc1,(03),0xd3,(03),0xd3,(03) },
-	{ ARCRW,	yshl,	Pe, 0xd1,(03),0xc1,(03),0xd3,(03),0xd3,(03) },
-	{ AREP,		ynone,	Px, 0xf3 },
-	{ AREPN,	ynone,	Px, 0xf2 },
-	{ ARET,		ynone,	Px, 0xc3 },
-	{ ARETFW,	yret,	Pe, 0xcb,0xca },
-	{ ARETFL,	yret,	Px, 0xcb,0xca },
-	{ ARETFQ,	yret,	Pw, 0xcb,0xca },
-	{ AROLB,	yshb,	Pb, 0xd0,(00),0xc0,(00),0xd2,(00) },
-	{ AROLL,	yshl,	Px, 0xd1,(00),0xc1,(00),0xd3,(00),0xd3,(00) },
-	{ AROLQ,	yshl,	Pw, 0xd1,(00),0xc1,(00),0xd3,(00),0xd3,(00) },
-	{ AROLW,	yshl,	Pe, 0xd1,(00),0xc1,(00),0xd3,(00),0xd3,(00) },
-	{ ARORB,	yshb,	Pb, 0xd0,(01),0xc0,(01),0xd2,(01) },
-	{ ARORL,	yshl,	Px, 0xd1,(01),0xc1,(01),0xd3,(01),0xd3,(01) },
-	{ ARORQ,	yshl,	Pw, 0xd1,(01),0xc1,(01),0xd3,(01),0xd3,(01) },
-	{ ARORW,	yshl,	Pe, 0xd1,(01),0xc1,(01),0xd3,(01),0xd3,(01) },
-	{ ARSQRTPS,	yxm,	Pm, 0x52 },
-	{ ARSQRTSS,	yxm,	Pf3, 0x52 },
-	{ ASAHF,	ynone,	Px, 0x86,0xe0,0x50,0x9d },	/* XCHGB AH,AL; PUSH AX; POPFL */
-	{ ASALB,	yshb,	Pb, 0xd0,(04),0xc0,(04),0xd2,(04) },
-	{ ASALL,	yshl,	Px, 0xd1,(04),0xc1,(04),0xd3,(04),0xd3,(04) },
-	{ ASALQ,	yshl,	Pw, 0xd1,(04),0xc1,(04),0xd3,(04),0xd3,(04) },
-	{ ASALW,	yshl,	Pe, 0xd1,(04),0xc1,(04),0xd3,(04),0xd3,(04) },
-	{ ASARB,	yshb,	Pb, 0xd0,(07),0xc0,(07),0xd2,(07) },
-	{ ASARL,	yshl,	Px, 0xd1,(07),0xc1,(07),0xd3,(07),0xd3,(07) },
-	{ ASARQ,	yshl,	Pw, 0xd1,(07),0xc1,(07),0xd3,(07),0xd3,(07) },
-	{ ASARW,	yshl,	Pe, 0xd1,(07),0xc1,(07),0xd3,(07),0xd3,(07) },
-	{ ASBBB,	yxorb,	Pb, 0x1c,0x80,(03),0x18,0x1a },
-	{ ASBBL,	yxorl,	Px, 0x83,(03),0x1d,0x81,(03),0x19,0x1b },
-	{ ASBBQ,	yxorl,	Pw, 0x83,(03),0x1d,0x81,(03),0x19,0x1b },
-	{ ASBBW,	yxorl,	Pe, 0x83,(03),0x1d,0x81,(03),0x19,0x1b },
-	{ ASCASB,	ynone,	Pb, 0xae },
-	{ ASCASL,	ynone,	Px, 0xaf },
-	{ ASCASQ,	ynone,	Pw, 0xaf },
-	{ ASCASW,	ynone,	Pe, 0xaf },
-	{ ASETCC,	yscond,	Pm, 0x93,(00) },
-	{ ASETCS,	yscond,	Pm, 0x92,(00) },
-	{ ASETEQ,	yscond,	Pm, 0x94,(00) },
-	{ ASETGE,	yscond,	Pm, 0x9d,(00) },
-	{ ASETGT,	yscond,	Pm, 0x9f,(00) },
-	{ ASETHI,	yscond,	Pm, 0x97,(00) },
-	{ ASETLE,	yscond,	Pm, 0x9e,(00) },
-	{ ASETLS,	yscond,	Pm, 0x96,(00) },
-	{ ASETLT,	yscond,	Pm, 0x9c,(00) },
-	{ ASETMI,	yscond,	Pm, 0x98,(00) },
-	{ ASETNE,	yscond,	Pm, 0x95,(00) },
-	{ ASETOC,	yscond,	Pm, 0x91,(00) },
-	{ ASETOS,	yscond,	Pm, 0x90,(00) },
-	{ ASETPC,	yscond,	Pm, 0x96,(00) },
-	{ ASETPL,	yscond,	Pm, 0x99,(00) },
-	{ ASETPS,	yscond,	Pm, 0x9a,(00) },
-	{ ASHLB,	yshb,	Pb, 0xd0,(04),0xc0,(04),0xd2,(04) },
-	{ ASHLL,	yshl,	Px, 0xd1,(04),0xc1,(04),0xd3,(04),0xd3,(04) },
-	{ ASHLQ,	yshl,	Pw, 0xd1,(04),0xc1,(04),0xd3,(04),0xd3,(04) },
-	{ ASHLW,	yshl,	Pe, 0xd1,(04),0xc1,(04),0xd3,(04),0xd3,(04) },
-	{ ASHRB,	yshb,	Pb, 0xd0,(05),0xc0,(05),0xd2,(05) },
-	{ ASHRL,	yshl,	Px, 0xd1,(05),0xc1,(05),0xd3,(05),0xd3,(05) },
-	{ ASHRQ,	yshl,	Pw, 0xd1,(05),0xc1,(05),0xd3,(05),0xd3,(05) },
-	{ ASHRW,	yshl,	Pe, 0xd1,(05),0xc1,(05),0xd3,(05),0xd3,(05) },
-	{ ASHUFPD,	yxshuf,	Pq, 0xc6,(00) },
-	{ ASHUFPS,	yxshuf,	Pm, 0xc6,(00) },
-	{ ASQRTPD,	yxm,	Pe, 0x51 },
-	{ ASQRTPS,	yxm,	Pm, 0x51 },
-	{ ASQRTSD,	yxm,	Pf2, 0x51 },
-	{ ASQRTSS,	yxm,	Pf3, 0x51 },
-	{ ASTC,		ynone,	Px, 0xf9 },
-	{ ASTD,		ynone,	Px, 0xfd },
-	{ ASTI,		ynone,	Px, 0xfb },
-	{ ASTMXCSR,	ysvrs,	Pm, 0xae,(03),0xae,(03) },
-	{ ASTOSB,	ynone,	Pb, 0xaa },
-	{ ASTOSL,	ynone,	Px, 0xab },
-	{ ASTOSQ,	ynone,	Pw, 0xab },
-	{ ASTOSW,	ynone,	Pe, 0xab },
-	{ ASUBB,	yxorb,	Pb, 0x2c,0x80,(05),0x28,0x2a },
-	{ ASUBL,	yaddl,	Px, 0x83,(05),0x2d,0x81,(05),0x29,0x2b },
-	{ ASUBPD,	yxm,	Pe, 0x5c },
-	{ ASUBPS,	yxm,	Pm, 0x5c },
-	{ ASUBQ,	yaddl,	Pw, 0x83,(05),0x2d,0x81,(05),0x29,0x2b },
-	{ ASUBSD,	yxm,	Pf2, 0x5c },
-	{ ASUBSS,	yxm,	Pf3, 0x5c },
-	{ ASUBW,	yaddl,	Pe, 0x83,(05),0x2d,0x81,(05),0x29,0x2b },
-	{ ASWAPGS,	ynone,	Pm, 0x01,0xf8 },
-	{ ASYSCALL,	ynone,	Px, 0x0f,0x05 },	/* fast syscall */
-	{ ATESTB,	ytestb,	Pb, 0xa8,0xf6,(00),0x84,0x84 },
-	{ ATESTL,	ytestl,	Px, 0xa9,0xf7,(00),0x85,0x85 },
-	{ ATESTQ,	ytestl,	Pw, 0xa9,0xf7,(00),0x85,0x85 },
-	{ ATESTW,	ytestl,	Pe, 0xa9,0xf7,(00),0x85,0x85 },
+	{ ANEGB,	yscond,	Pb, {0xf6,(03)} },
+	{ ANEGL,	yscond,	Px, {0xf7,(03)} },
+	{ ANEGQ,	yscond,	Pw, {0xf7,(03)} },
+	{ ANEGW,	yscond,	Pe, {0xf7,(03)} },
+	{ ANOP,		ynop,	Px, {0,0} },
+	{ ANOTB,	yscond,	Pb, {0xf6,(02)} },
+	{ ANOTL,	yscond,	Px, {0xf7,(02)} },
+	{ ANOTQ,	yscond,	Pw, {0xf7,(02)} },
+	{ ANOTW,	yscond,	Pe, {0xf7,(02)} },
+	{ AORB,		yxorb,	Pb, {0x0c,0x80,(01),0x08,0x0a} },
+	{ AORL,		yxorl,	Px, {0x83,(01),0x0d,0x81,(01),0x09,0x0b} },
+	{ AORPD,	yxm,	Pq, {0x56} },
+	{ AORPS,	yxm,	Pm, {0x56} },
+	{ AORQ,		yxorl,	Pw, {0x83,(01),0x0d,0x81,(01),0x09,0x0b} },
+	{ AORW,		yxorl,	Pe, {0x83,(01),0x0d,0x81,(01),0x09,0x0b} },
+	{ AOUTB,	yin,	Pb, {0xe6,0xee} },
+	{ AOUTL,	yin,	Px, {0xe7,0xef} },
+	{ AOUTSB,	ynone,	Pb, {0x6e} },
+	{ AOUTSL,	ynone,	Px, {0x6f} },
+	{ AOUTSW,	ynone,	Pe, {0x6f} },
+	{ AOUTW,	yin,	Pe, {0xe7,0xef} },
+	{ APACKSSLW,	ymm,	Py, {0x6b,Pe,0x6b} },
+	{ APACKSSWB,	ymm,	Py, {0x63,Pe,0x63} },
+	{ APACKUSWB,	ymm,	Py, {0x67,Pe,0x67} },
+	{ APADDB,	ymm,	Py, {0xfc,Pe,0xfc} },
+	{ APADDL,	ymm,	Py, {0xfe,Pe,0xfe} },
+	{ APADDQ,	yxm,	Pe, {0xd4} },
+	{ APADDSB,	ymm,	Py, {0xec,Pe,0xec} },
+	{ APADDSW,	ymm,	Py, {0xed,Pe,0xed} },
+	{ APADDUSB,	ymm,	Py, {0xdc,Pe,0xdc} },
+	{ APADDUSW,	ymm,	Py, {0xdd,Pe,0xdd} },
+	{ APADDW,	ymm,	Py, {0xfd,Pe,0xfd} },
+	{ APAND,	ymm,	Py, {0xdb,Pe,0xdb} },
+	{ APANDN,	ymm,	Py, {0xdf,Pe,0xdf} },
+	{ APAUSE,	ynone,	Px, {0xf3,0x90} },
+	{ APAVGB,	ymm,	Py, {0xe0,Pe,0xe0} },
+	{ APAVGW,	ymm,	Py, {0xe3,Pe,0xe3} },
+	{ APCMPEQB,	ymm,	Py, {0x74,Pe,0x74} },
+	{ APCMPEQL,	ymm,	Py, {0x76,Pe,0x76} },
+	{ APCMPEQW,	ymm,	Py, {0x75,Pe,0x75} },
+	{ APCMPGTB,	ymm,	Py, {0x64,Pe,0x64} },
+	{ APCMPGTL,	ymm,	Py, {0x66,Pe,0x66} },
+	{ APCMPGTW,	ymm,	Py, {0x65,Pe,0x65} },
+	{ APEXTRW,	yextrw,	Pq, {0xc5,(00)} },
+	{ APF2IL,	ymfp,	Px, {0x1d} },
+	{ APF2IW,	ymfp,	Px, {0x1c} },
+	{ API2FL,	ymfp,	Px, {0x0d} },
+	{ APFACC,	ymfp,	Px, {0xae} },
+	{ APFADD,	ymfp,	Px, {0x9e} },
+	{ APFCMPEQ,	ymfp,	Px, {0xb0} },
+	{ APFCMPGE,	ymfp,	Px, {0x90} },
+	{ APFCMPGT,	ymfp,	Px, {0xa0} },
+	{ APFMAX,	ymfp,	Px, {0xa4} },
+	{ APFMIN,	ymfp,	Px, {0x94} },
+	{ APFMUL,	ymfp,	Px, {0xb4} },
+	{ APFNACC,	ymfp,	Px, {0x8a} },
+	{ APFPNACC,	ymfp,	Px, {0x8e} },
+	{ APFRCP,	ymfp,	Px, {0x96} },
+	{ APFRCPIT1,	ymfp,	Px, {0xa6} },
+	{ APFRCPI2T,	ymfp,	Px, {0xb6} },
+	{ APFRSQIT1,	ymfp,	Px, {0xa7} },
+	{ APFRSQRT,	ymfp,	Px, {0x97} },
+	{ APFSUB,	ymfp,	Px, {0x9a} },
+	{ APFSUBR,	ymfp,	Px, {0xaa} },
+	{ APINSRW,	yinsrw,	Pq, {0xc4,(00)} },
+	{ APINSRD,	yinsr,	Pq, {0x3a, 0x22, (00)} },
+	{ APINSRQ,	yinsr,	Pq3, {0x3a, 0x22, (00)} },
+	{ APMADDWL,	ymm,	Py, {0xf5,Pe,0xf5} },
+	{ APMAXSW,	yxm,	Pe, {0xee} },
+	{ APMAXUB,	yxm,	Pe, {0xde} },
+	{ APMINSW,	yxm,	Pe, {0xea} },
+	{ APMINUB,	yxm,	Pe, {0xda} },
+	{ APMOVMSKB,	ymskb,	Px, {Pe,0xd7,0xd7} },
+	{ APMULHRW,	ymfp,	Px, {0xb7} },
+	{ APMULHUW,	ymm,	Py, {0xe4,Pe,0xe4} },
+	{ APMULHW,	ymm,	Py, {0xe5,Pe,0xe5} },
+	{ APMULLW,	ymm,	Py, {0xd5,Pe,0xd5} },
+	{ APMULULQ,	ymm,	Py, {0xf4,Pe,0xf4} },
+	{ APOPAL,	ynone,	P32, {0x61} },
+	{ APOPAW,	ynone,	Pe, {0x61} },
+	{ APOPFL,	ynone,	P32, {0x9d} },
+	{ APOPFQ,	ynone,	Py, {0x9d} },
+	{ APOPFW,	ynone,	Pe, {0x9d} },
+	{ APOPL,	ypopl,	P32, {0x58,0x8f,(00)} },
+	{ APOPQ,	ypopl,	Py, {0x58,0x8f,(00)} },
+	{ APOPW,	ypopl,	Pe, {0x58,0x8f,(00)} },
+	{ APOR,		ymm,	Py, {0xeb,Pe,0xeb} },
+	{ APSADBW,	yxm,	Pq, {0xf6} },
+	{ APSHUFHW,	yxshuf,	Pf3, {0x70,(00)} },
+	{ APSHUFL,	yxshuf,	Pq, {0x70,(00)} },
+	{ APSHUFLW,	yxshuf,	Pf2, {0x70,(00)} },
+	{ APSHUFW,	ymshuf,	Pm, {0x70,(00)} },
+	{ APSHUFB,	ymshufb,Pq, {0x38, 0x00} },
+	{ APSLLO,	ypsdq,	Pq, {0x73,(07)} },
+	{ APSLLL,	yps,	Py, {0xf2, 0x72,(06), Pe,0xf2, Pe,0x72,(06)} },
+	{ APSLLQ,	yps,	Py, {0xf3, 0x73,(06), Pe,0xf3, Pe,0x73,(06)} },
+	{ APSLLW,	yps,	Py, {0xf1, 0x71,(06), Pe,0xf1, Pe,0x71,(06)} },
+	{ APSRAL,	yps,	Py, {0xe2, 0x72,(04), Pe,0xe2, Pe,0x72,(04)} },
+	{ APSRAW,	yps,	Py, {0xe1, 0x71,(04), Pe,0xe1, Pe,0x71,(04)} },
+	{ APSRLO,	ypsdq,	Pq, {0x73,(03)} },
+	{ APSRLL,	yps,	Py, {0xd2, 0x72,(02), Pe,0xd2, Pe,0x72,(02)} },
+	{ APSRLQ,	yps,	Py, {0xd3, 0x73,(02), Pe,0xd3, Pe,0x73,(02)} },
+	{ APSRLW,	yps,	Py, {0xd1, 0x71,(02), Pe,0xe1, Pe,0x71,(02)} },
+	{ APSUBB,	yxm,	Pe, {0xf8} },
+	{ APSUBL,	yxm,	Pe, {0xfa} },
+	{ APSUBQ,	yxm,	Pe, {0xfb} },
+	{ APSUBSB,	yxm,	Pe, {0xe8} },
+	{ APSUBSW,	yxm,	Pe, {0xe9} },
+	{ APSUBUSB,	yxm,	Pe, {0xd8} },
+	{ APSUBUSW,	yxm,	Pe, {0xd9} },
+	{ APSUBW,	yxm,	Pe, {0xf9} },
+	{ APSWAPL,	ymfp,	Px, {0xbb} },
+	{ APUNPCKHBW,	ymm,	Py, {0x68,Pe,0x68} },
+	{ APUNPCKHLQ,	ymm,	Py, {0x6a,Pe,0x6a} },
+	{ APUNPCKHQDQ,	yxm,	Pe, {0x6d} },
+	{ APUNPCKHWL,	ymm,	Py, {0x69,Pe,0x69} },
+	{ APUNPCKLBW,	ymm,	Py, {0x60,Pe,0x60} },
+	{ APUNPCKLLQ,	ymm,	Py, {0x62,Pe,0x62} },
+	{ APUNPCKLQDQ,	yxm,	Pe, {0x6c} },
+	{ APUNPCKLWL,	ymm,	Py, {0x61,Pe,0x61} },
+	{ APUSHAL,	ynone,	P32, {0x60} },
+	{ APUSHAW,	ynone,	Pe, {0x60} },
+	{ APUSHFL,	ynone,	P32, {0x9c} },
+	{ APUSHFQ,	ynone,	Py, {0x9c} },
+	{ APUSHFW,	ynone,	Pe, {0x9c} },
+	{ APUSHL,	ypushl,	P32, {0x50,0xff,(06),0x6a,0x68} },
+	{ APUSHQ,	ypushl,	Py, {0x50,0xff,(06),0x6a,0x68} },
+	{ APUSHW,	ypushl,	Pe, {0x50,0xff,(06),0x6a,0x68} },
+	{ APXOR,	ymm,	Py, {0xef,Pe,0xef} },
+	{ AQUAD,	ybyte,	Px, {8} },
+	{ ARCLB,	yshb,	Pb, {0xd0,(02),0xc0,(02),0xd2,(02)} },
+	{ ARCLL,	yshl,	Px, {0xd1,(02),0xc1,(02),0xd3,(02),0xd3,(02)} },
+	{ ARCLQ,	yshl,	Pw, {0xd1,(02),0xc1,(02),0xd3,(02),0xd3,(02)} },
+	{ ARCLW,	yshl,	Pe, {0xd1,(02),0xc1,(02),0xd3,(02),0xd3,(02)} },
+	{ ARCPPS,	yxm,	Pm, {0x53} },
+	{ ARCPSS,	yxm,	Pf3, {0x53} },
+	{ ARCRB,	yshb,	Pb, {0xd0,(03),0xc0,(03),0xd2,(03)} },
+	{ ARCRL,	yshl,	Px, {0xd1,(03),0xc1,(03),0xd3,(03),0xd3,(03)} },
+	{ ARCRQ,	yshl,	Pw, {0xd1,(03),0xc1,(03),0xd3,(03),0xd3,(03)} },
+	{ ARCRW,	yshl,	Pe, {0xd1,(03),0xc1,(03),0xd3,(03),0xd3,(03)} },
+	{ AREP,		ynone,	Px, {0xf3} },
+	{ AREPN,	ynone,	Px, {0xf2} },
+	{ ARET,		ynone,	Px, {0xc3} },
+	{ ARETFW,	yret,	Pe, {0xcb,0xca} },
+	{ ARETFL,	yret,	Px, {0xcb,0xca} },
+	{ ARETFQ,	yret,	Pw, {0xcb,0xca} },
+	{ AROLB,	yshb,	Pb, {0xd0,(00),0xc0,(00),0xd2,(00)} },
+	{ AROLL,	yshl,	Px, {0xd1,(00),0xc1,(00),0xd3,(00),0xd3,(00)} },
+	{ AROLQ,	yshl,	Pw, {0xd1,(00),0xc1,(00),0xd3,(00),0xd3,(00)} },
+	{ AROLW,	yshl,	Pe, {0xd1,(00),0xc1,(00),0xd3,(00),0xd3,(00)} },
+	{ ARORB,	yshb,	Pb, {0xd0,(01),0xc0,(01),0xd2,(01)} },
+	{ ARORL,	yshl,	Px, {0xd1,(01),0xc1,(01),0xd3,(01),0xd3,(01)} },
+	{ ARORQ,	yshl,	Pw, {0xd1,(01),0xc1,(01),0xd3,(01),0xd3,(01)} },
+	{ ARORW,	yshl,	Pe, {0xd1,(01),0xc1,(01),0xd3,(01),0xd3,(01)} },
+	{ ARSQRTPS,	yxm,	Pm, {0x52} },
+	{ ARSQRTSS,	yxm,	Pf3, {0x52} },
+	{ ASAHF,	ynone,	Px, {0x86,0xe0,0x50,0x9d} },	/* XCHGB AH,AL; PUSH AX; POPFL */
+	{ ASALB,	yshb,	Pb, {0xd0,(04),0xc0,(04),0xd2,(04)} },
+	{ ASALL,	yshl,	Px, {0xd1,(04),0xc1,(04),0xd3,(04),0xd3,(04)} },
+	{ ASALQ,	yshl,	Pw, {0xd1,(04),0xc1,(04),0xd3,(04),0xd3,(04)} },
+	{ ASALW,	yshl,	Pe, {0xd1,(04),0xc1,(04),0xd3,(04),0xd3,(04)} },
+	{ ASARB,	yshb,	Pb, {0xd0,(07),0xc0,(07),0xd2,(07)} },
+	{ ASARL,	yshl,	Px, {0xd1,(07),0xc1,(07),0xd3,(07),0xd3,(07)} },
+	{ ASARQ,	yshl,	Pw, {0xd1,(07),0xc1,(07),0xd3,(07),0xd3,(07)} },
+	{ ASARW,	yshl,	Pe, {0xd1,(07),0xc1,(07),0xd3,(07),0xd3,(07)} },
+	{ ASBBB,	yxorb,	Pb, {0x1c,0x80,(03),0x18,0x1a} },
+	{ ASBBL,	yxorl,	Px, {0x83,(03),0x1d,0x81,(03),0x19,0x1b} },
+	{ ASBBQ,	yxorl,	Pw, {0x83,(03),0x1d,0x81,(03),0x19,0x1b} },
+	{ ASBBW,	yxorl,	Pe, {0x83,(03),0x1d,0x81,(03),0x19,0x1b} },
+	{ ASCASB,	ynone,	Pb, {0xae} },
+	{ ASCASL,	ynone,	Px, {0xaf} },
+	{ ASCASQ,	ynone,	Pw, {0xaf} },
+	{ ASCASW,	ynone,	Pe, {0xaf} },
+	{ ASETCC,	yscond,	Pm, {0x93,(00)} },
+	{ ASETCS,	yscond,	Pm, {0x92,(00)} },
+	{ ASETEQ,	yscond,	Pm, {0x94,(00)} },
+	{ ASETGE,	yscond,	Pm, {0x9d,(00)} },
+	{ ASETGT,	yscond,	Pm, {0x9f,(00)} },
+	{ ASETHI,	yscond,	Pm, {0x97,(00)} },
+	{ ASETLE,	yscond,	Pm, {0x9e,(00)} },
+	{ ASETLS,	yscond,	Pm, {0x96,(00)} },
+	{ ASETLT,	yscond,	Pm, {0x9c,(00)} },
+	{ ASETMI,	yscond,	Pm, {0x98,(00)} },
+	{ ASETNE,	yscond,	Pm, {0x95,(00)} },
+	{ ASETOC,	yscond,	Pm, {0x91,(00)} },
+	{ ASETOS,	yscond,	Pm, {0x90,(00)} },
+	{ ASETPC,	yscond,	Pm, {0x9b,(00)} },
+	{ ASETPL,	yscond,	Pm, {0x99,(00)} },
+	{ ASETPS,	yscond,	Pm, {0x9a,(00)} },
+	{ ASHLB,	yshb,	Pb, {0xd0,(04),0xc0,(04),0xd2,(04)} },
+	{ ASHLL,	yshl,	Px, {0xd1,(04),0xc1,(04),0xd3,(04),0xd3,(04)} },
+	{ ASHLQ,	yshl,	Pw, {0xd1,(04),0xc1,(04),0xd3,(04),0xd3,(04)} },
+	{ ASHLW,	yshl,	Pe, {0xd1,(04),0xc1,(04),0xd3,(04),0xd3,(04)} },
+	{ ASHRB,	yshb,	Pb, {0xd0,(05),0xc0,(05),0xd2,(05)} },
+	{ ASHRL,	yshl,	Px, {0xd1,(05),0xc1,(05),0xd3,(05),0xd3,(05)} },
+	{ ASHRQ,	yshl,	Pw, {0xd1,(05),0xc1,(05),0xd3,(05),0xd3,(05)} },
+	{ ASHRW,	yshl,	Pe, {0xd1,(05),0xc1,(05),0xd3,(05),0xd3,(05)} },
+	{ ASHUFPD,	yxshuf,	Pq, {0xc6,(00)} },
+	{ ASHUFPS,	yxshuf,	Pm, {0xc6,(00)} },
+	{ ASQRTPD,	yxm,	Pe, {0x51} },
+	{ ASQRTPS,	yxm,	Pm, {0x51} },
+	{ ASQRTSD,	yxm,	Pf2, {0x51} },
+	{ ASQRTSS,	yxm,	Pf3, {0x51} },
+	{ ASTC,		ynone,	Px, {0xf9} },
+	{ ASTD,		ynone,	Px, {0xfd} },
+	{ ASTI,		ynone,	Px, {0xfb} },
+	{ ASTMXCSR,	ysvrs,	Pm, {0xae,(03),0xae,(03)} },
+	{ ASTOSB,	ynone,	Pb, {0xaa} },
+	{ ASTOSL,	ynone,	Px, {0xab} },
+	{ ASTOSQ,	ynone,	Pw, {0xab} },
+	{ ASTOSW,	ynone,	Pe, {0xab} },
+	{ ASUBB,	yxorb,	Pb, {0x2c,0x80,(05),0x28,0x2a} },
+	{ ASUBL,	yaddl,	Px, {0x83,(05),0x2d,0x81,(05),0x29,0x2b} },
+	{ ASUBPD,	yxm,	Pe, {0x5c} },
+	{ ASUBPS,	yxm,	Pm, {0x5c} },
+	{ ASUBQ,	yaddl,	Pw, {0x83,(05),0x2d,0x81,(05),0x29,0x2b} },
+	{ ASUBSD,	yxm,	Pf2, {0x5c} },
+	{ ASUBSS,	yxm,	Pf3, {0x5c} },
+	{ ASUBW,	yaddl,	Pe, {0x83,(05),0x2d,0x81,(05),0x29,0x2b} },
+	{ ASWAPGS,	ynone,	Pm, {0x01,0xf8} },
+	{ ASYSCALL,	ynone,	Px, {0x0f,0x05} },	/* fast syscall */
+	{ ATESTB,	ytestb,	Pb, {0xa8,0xf6,(00),0x84,0x84} },
+	{ ATESTL,	ytestl,	Px, {0xa9,0xf7,(00),0x85,0x85} },
+	{ ATESTQ,	ytestl,	Pw, {0xa9,0xf7,(00),0x85,0x85} },
+	{ ATESTW,	ytestl,	Pe, {0xa9,0xf7,(00),0x85,0x85} },
 	{ ATEXT,	ytext,	Px },
-	{ AUCOMISD,	yxcmp,	Pe, 0x2e },
-	{ AUCOMISS,	yxcmp,	Pm, 0x2e },
-	{ AUNPCKHPD,	yxm,	Pe, 0x15 },
-	{ AUNPCKHPS,	yxm,	Pm, 0x15 },
-	{ AUNPCKLPD,	yxm,	Pe, 0x14 },
-	{ AUNPCKLPS,	yxm,	Pm, 0x14 },
-	{ AVERR,	ydivl,	Pm, 0x00,(04) },
-	{ AVERW,	ydivl,	Pm, 0x00,(05) },
-	{ AWAIT,	ynone,	Px, 0x9b },
-	{ AWORD,	ybyte,	Px, 2 },
-	{ AXCHGB,	yml_mb,	Pb, 0x86,0x86 },
-	{ AXCHGL,	yxchg,	Px, 0x90,0x90,0x87,0x87 },
-	{ AXCHGQ,	yxchg,	Pw, 0x90,0x90,0x87,0x87 },
-	{ AXCHGW,	yxchg,	Pe, 0x90,0x90,0x87,0x87 },
-	{ AXLAT,	ynone,	Px, 0xd7 },
-	{ AXORB,	yxorb,	Pb, 0x34,0x80,(06),0x30,0x32 },
-	{ AXORL,	yxorl,	Px, 0x83,(06),0x35,0x81,(06),0x31,0x33 },
-	{ AXORPD,	yxm,	Pe, 0x57 },
-	{ AXORPS,	yxm,	Pm, 0x57 },
-	{ AXORQ,	yxorl,	Pw, 0x83,(06),0x35,0x81,(06),0x31,0x33 },
-	{ AXORW,	yxorl,	Pe, 0x83,(06),0x35,0x81,(06),0x31,0x33 },
-
-	{ AFMOVB,	yfmvx,	Px, 0xdf,(04) },
-	{ AFMOVBP,	yfmvp,	Px, 0xdf,(06) },
-	{ AFMOVD,	yfmvd,	Px, 0xdd,(00),0xdd,(02),0xd9,(00),0xdd,(02) },
-	{ AFMOVDP,	yfmvdp,	Px, 0xdd,(03),0xdd,(03) },
-	{ AFMOVF,	yfmvf,	Px, 0xd9,(00),0xd9,(02) },
-	{ AFMOVFP,	yfmvp,	Px, 0xd9,(03) },
-	{ AFMOVL,	yfmvf,	Px, 0xdb,(00),0xdb,(02) },
-	{ AFMOVLP,	yfmvp,	Px, 0xdb,(03) },
-	{ AFMOVV,	yfmvx,	Px, 0xdf,(05) },
-	{ AFMOVVP,	yfmvp,	Px, 0xdf,(07) },
-	{ AFMOVW,	yfmvf,	Px, 0xdf,(00),0xdf,(02) },
-	{ AFMOVWP,	yfmvp,	Px, 0xdf,(03) },
-	{ AFMOVX,	yfmvx,	Px, 0xdb,(05) },
-	{ AFMOVXP,	yfmvp,	Px, 0xdb,(07) },
+	{ AUCOMISD,	yxcmp,	Pe, {0x2e} },
+	{ AUCOMISS,	yxcmp,	Pm, {0x2e} },
+	{ AUNPCKHPD,	yxm,	Pe, {0x15} },
+	{ AUNPCKHPS,	yxm,	Pm, {0x15} },
+	{ AUNPCKLPD,	yxm,	Pe, {0x14} },
+	{ AUNPCKLPS,	yxm,	Pm, {0x14} },
+	{ AVERR,	ydivl,	Pm, {0x00,(04)} },
+	{ AVERW,	ydivl,	Pm, {0x00,(05)} },
+	{ AWAIT,	ynone,	Px, {0x9b} },
+	{ AWORD,	ybyte,	Px, {2} },
+	{ AXCHGB,	yml_mb,	Pb, {0x86,0x86} },
+	{ AXCHGL,	yxchg,	Px, {0x90,0x90,0x87,0x87} },
+	{ AXCHGQ,	yxchg,	Pw, {0x90,0x90,0x87,0x87} },
+	{ AXCHGW,	yxchg,	Pe, {0x90,0x90,0x87,0x87} },
+	{ AXLAT,	ynone,	Px, {0xd7} },
+	{ AXORB,	yxorb,	Pb, {0x34,0x80,(06),0x30,0x32} },
+	{ AXORL,	yxorl,	Px, {0x83,(06),0x35,0x81,(06),0x31,0x33} },
+	{ AXORPD,	yxm,	Pe, {0x57} },
+	{ AXORPS,	yxm,	Pm, {0x57} },
+	{ AXORQ,	yxorl,	Pw, {0x83,(06),0x35,0x81,(06),0x31,0x33} },
+	{ AXORW,	yxorl,	Pe, {0x83,(06),0x35,0x81,(06),0x31,0x33} },
+
+	{ AFMOVB,	yfmvx,	Px, {0xdf,(04)} },
+	{ AFMOVBP,	yfmvp,	Px, {0xdf,(06)} },
+	{ AFMOVD,	yfmvd,	Px, {0xdd,(00),0xdd,(02),0xd9,(00),0xdd,(02)} },
+	{ AFMOVDP,	yfmvdp,	Px, {0xdd,(03),0xdd,(03)} },
+	{ AFMOVF,	yfmvf,	Px, {0xd9,(00),0xd9,(02)} },
+	{ AFMOVFP,	yfmvp,	Px, {0xd9,(03)} },
+	{ AFMOVL,	yfmvf,	Px, {0xdb,(00),0xdb,(02)} },
+	{ AFMOVLP,	yfmvp,	Px, {0xdb,(03)} },
+	{ AFMOVV,	yfmvx,	Px, {0xdf,(05)} },
+	{ AFMOVVP,	yfmvp,	Px, {0xdf,(07)} },
+	{ AFMOVW,	yfmvf,	Px, {0xdf,(00),0xdf,(02)} },
+	{ AFMOVWP,	yfmvp,	Px, {0xdf,(03)} },
+	{ AFMOVX,	yfmvx,	Px, {0xdb,(05)} },
+	{ AFMOVXP,	yfmvp,	Px, {0xdb,(07)} },
 
 	{ AFCOMB },
 	{ AFCOMBP },
-	{ AFCOMD,	yfadd,	Px, 0xdc,(02),0xd8,(02),0xdc,(02) },	/* botch */
-	{ AFCOMDP,	yfadd,	Px, 0xdc,(03),0xd8,(03),0xdc,(03) },	/* botch */
-	{ AFCOMDPP,	ycompp,	Px, 0xde,(03) },
-	{ AFCOMF,	yfmvx,	Px, 0xd8,(02) },
-	{ AFCOMFP,	yfmvx,	Px, 0xd8,(03) },
-	{ AFCOML,	yfmvx,	Px, 0xda,(02) },
-	{ AFCOMLP,	yfmvx,	Px, 0xda,(03) },
-	{ AFCOMW,	yfmvx,	Px, 0xde,(02) },
-	{ AFCOMWP,	yfmvx,	Px, 0xde,(03) },
-
-	{ AFUCOM,	ycompp,	Px, 0xdd,(04) },
-	{ AFUCOMP,	ycompp, Px, 0xdd,(05) },
-	{ AFUCOMPP,	ycompp,	Px, 0xda,(13) },
-
-	{ AFADDDP,	yfaddp,	Px, 0xde,(00) },
-	{ AFADDW,	yfmvx,	Px, 0xde,(00) },
-	{ AFADDL,	yfmvx,	Px, 0xda,(00) },
-	{ AFADDF,	yfmvx,	Px, 0xd8,(00) },
-	{ AFADDD,	yfadd,	Px, 0xdc,(00),0xd8,(00),0xdc,(00) },
-
-	{ AFMULDP,	yfaddp,	Px, 0xde,(01) },
-	{ AFMULW,	yfmvx,	Px, 0xde,(01) },
-	{ AFMULL,	yfmvx,	Px, 0xda,(01) },
-	{ AFMULF,	yfmvx,	Px, 0xd8,(01) },
-	{ AFMULD,	yfadd,	Px, 0xdc,(01),0xd8,(01),0xdc,(01) },
-
-	{ AFSUBDP,	yfaddp,	Px, 0xde,(05) },
-	{ AFSUBW,	yfmvx,	Px, 0xde,(04) },
-	{ AFSUBL,	yfmvx,	Px, 0xda,(04) },
-	{ AFSUBF,	yfmvx,	Px, 0xd8,(04) },
-	{ AFSUBD,	yfadd,	Px, 0xdc,(04),0xd8,(04),0xdc,(05) },
-
-	{ AFSUBRDP,	yfaddp,	Px, 0xde,(04) },
-	{ AFSUBRW,	yfmvx,	Px, 0xde,(05) },
-	{ AFSUBRL,	yfmvx,	Px, 0xda,(05) },
-	{ AFSUBRF,	yfmvx,	Px, 0xd8,(05) },
-	{ AFSUBRD,	yfadd,	Px, 0xdc,(05),0xd8,(05),0xdc,(04) },
-
-	{ AFDIVDP,	yfaddp,	Px, 0xde,(07) },
-	{ AFDIVW,	yfmvx,	Px, 0xde,(06) },
-	{ AFDIVL,	yfmvx,	Px, 0xda,(06) },
-	{ AFDIVF,	yfmvx,	Px, 0xd8,(06) },
-	{ AFDIVD,	yfadd,	Px, 0xdc,(06),0xd8,(06),0xdc,(07) },
-
-	{ AFDIVRDP,	yfaddp,	Px, 0xde,(06) },
-	{ AFDIVRW,	yfmvx,	Px, 0xde,(07) },
-	{ AFDIVRL,	yfmvx,	Px, 0xda,(07) },
-	{ AFDIVRF,	yfmvx,	Px, 0xd8,(07) },
-	{ AFDIVRD,	yfadd,	Px, 0xdc,(07),0xd8,(07),0xdc,(06) },
-
-	{ AFXCHD,	yfxch,	Px, 0xd9,(01),0xd9,(01) },
+	{ AFCOMD,	yfadd,	Px, {0xdc,(02),0xd8,(02),0xdc,(02)} },	/* botch */
+	{ AFCOMDP,	yfadd,	Px, {0xdc,(03),0xd8,(03),0xdc,(03)} },	/* botch */
+	{ AFCOMDPP,	ycompp,	Px, {0xde,(03)} },
+	{ AFCOMF,	yfmvx,	Px, {0xd8,(02)} },
+	{ AFCOMFP,	yfmvx,	Px, {0xd8,(03)} },
+	{ AFCOML,	yfmvx,	Px, {0xda,(02)} },
+	{ AFCOMLP,	yfmvx,	Px, {0xda,(03)} },
+	{ AFCOMW,	yfmvx,	Px, {0xde,(02)} },
+	{ AFCOMWP,	yfmvx,	Px, {0xde,(03)} },
+
+	{ AFUCOM,	ycompp,	Px, {0xdd,(04)} },
+	{ AFUCOMP,	ycompp, Px, {0xdd,(05)} },
+	{ AFUCOMPP,	ycompp,	Px, {0xda,(13)} },
+
+	{ AFADDDP,	yfaddp,	Px, {0xde,(00)} },
+	{ AFADDW,	yfmvx,	Px, {0xde,(00)} },
+	{ AFADDL,	yfmvx,	Px, {0xda,(00)} },
+	{ AFADDF,	yfmvx,	Px, {0xd8,(00)} },
+	{ AFADDD,	yfadd,	Px, {0xdc,(00),0xd8,(00),0xdc,(00)} },
+
+	{ AFMULDP,	yfaddp,	Px, {0xde,(01)} },
+	{ AFMULW,	yfmvx,	Px, {0xde,(01)} },
+	{ AFMULL,	yfmvx,	Px, {0xda,(01)} },
+	{ AFMULF,	yfmvx,	Px, {0xd8,(01)} },
+	{ AFMULD,	yfadd,	Px, {0xdc,(01),0xd8,(01),0xdc,(01)} },
+
+	{ AFSUBDP,	yfaddp,	Px, {0xde,(05)} },
+	{ AFSUBW,	yfmvx,	Px, {0xde,(04)} },
+	{ AFSUBL,	yfmvx,	Px, {0xda,(04)} },
+	{ AFSUBF,	yfmvx,	Px, {0xd8,(04)} },
+	{ AFSUBD,	yfadd,	Px, {0xdc,(04),0xd8,(04),0xdc,(05)} },
+
+	{ AFSUBRDP,	yfaddp,	Px, {0xde,(04)} },
+	{ AFSUBRW,	yfmvx,	Px, {0xde,(05)} },
+	{ AFSUBRL,	yfmvx,	Px, {0xda,(05)} },
+	{ AFSUBRF,	yfmvx,	Px, {0xd8,(05)} },
+	{ AFSUBRD,	yfadd,	Px, {0xdc,(05),0xd8,(05),0xdc,(04)} },
+
+	{ AFDIVDP,	yfaddp,	Px, {0xde,(07)} },
+	{ AFDIVW,	yfmvx,	Px, {0xde,(06)} },
+	{ AFDIVL,	yfmvx,	Px, {0xda,(06)} },
+	{ AFDIVF,	yfmvx,	Px, {0xd8,(06)} },
+	{ AFDIVD,	yfadd,	Px, {0xdc,(06),0xd8,(06),0xdc,(07)} },
+
+	{ AFDIVRDP,	yfaddp,	Px, {0xde,(06)} },
+	{ AFDIVRW,	yfmvx,	Px, {0xde,(07)} },
+	{ AFDIVRL,	yfmvx,	Px, {0xda,(07)} },
+	{ AFDIVRF,	yfmvx,	Px, {0xd8,(07)} },
+	{ AFDIVRD,	yfadd,	Px, {0xdc,(07),0xd8,(07),0xdc,(06)} },
+
+	{ AFXCHD,	yfxch,	Px, {0xd9,(01),0xd9,(01)} },
 	{ AFFREE },
-	{ AFLDCW,	ystcw,	Px, 0xd9,(05),0xd9,(05) },
-	{ AFLDENV,	ystcw,	Px, 0xd9,(04),0xd9,(04) },
-	{ AFRSTOR,	ysvrs,	Px, 0xdd,(04),0xdd,(04) },
-	{ AFSAVE,	ysvrs,	Px, 0xdd,(06),0xdd,(06) },
-	{ AFSTCW,	ystcw,	Px, 0xd9,(07),0xd9,(07) },
-	{ AFSTENV,	ystcw,	Px, 0xd9,(06),0xd9,(06) },
-	{ AFSTSW,	ystsw,	Px, 0xdd,(07),0xdf,0xe0 },
-	{ AF2XM1,	ynone,	Px, 0xd9, 0xf0 },
-	{ AFABS,	ynone,	Px, 0xd9, 0xe1 },
-	{ AFCHS,	ynone,	Px, 0xd9, 0xe0 },
-	{ AFCLEX,	ynone,	Px, 0xdb, 0xe2 },
-	{ AFCOS,	ynone,	Px, 0xd9, 0xff },
-	{ AFDECSTP,	ynone,	Px, 0xd9, 0xf6 },
-	{ AFINCSTP,	ynone,	Px, 0xd9, 0xf7 },
-	{ AFINIT,	ynone,	Px, 0xdb, 0xe3 },
-	{ AFLD1,	ynone,	Px, 0xd9, 0xe8 },
-	{ AFLDL2E,	ynone,	Px, 0xd9, 0xea },
-	{ AFLDL2T,	ynone,	Px, 0xd9, 0xe9 },
-	{ AFLDLG2,	ynone,	Px, 0xd9, 0xec },
-	{ AFLDLN2,	ynone,	Px, 0xd9, 0xed },
-	{ AFLDPI,	ynone,	Px, 0xd9, 0xeb },
-	{ AFLDZ,	ynone,	Px, 0xd9, 0xee },
-	{ AFNOP,	ynone,	Px, 0xd9, 0xd0 },
-	{ AFPATAN,	ynone,	Px, 0xd9, 0xf3 },
-	{ AFPREM,	ynone,	Px, 0xd9, 0xf8 },
-	{ AFPREM1,	ynone,	Px, 0xd9, 0xf5 },
-	{ AFPTAN,	ynone,	Px, 0xd9, 0xf2 },
-	{ AFRNDINT,	ynone,	Px, 0xd9, 0xfc },
-	{ AFSCALE,	ynone,	Px, 0xd9, 0xfd },
-	{ AFSIN,	ynone,	Px, 0xd9, 0xfe },
-	{ AFSINCOS,	ynone,	Px, 0xd9, 0xfb },
-	{ AFSQRT,	ynone,	Px, 0xd9, 0xfa },
-	{ AFTST,	ynone,	Px, 0xd9, 0xe4 },
-	{ AFXAM,	ynone,	Px, 0xd9, 0xe5 },
-	{ AFXTRACT,	ynone,	Px, 0xd9, 0xf4 },
-	{ AFYL2X,	ynone,	Px, 0xd9, 0xf1 },
-	{ AFYL2XP1,	ynone,	Px, 0xd9, 0xf9 },
-
-	{ ACMPXCHGB,	yrb_mb,	Pb, 0x0f,0xb0 },
-	{ ACMPXCHGL,	yrl_ml,	Px, 0x0f,0xb1 },
-	{ ACMPXCHGW,	yrl_ml,	Pe, 0x0f,0xb1 },
-	{ ACMPXCHGQ,	yrl_ml,	Pw, 0x0f,0xb1 },
-	{ ACMPXCHG8B,	yscond,	Pm, 0xc7,(01) },
-	{ AINVD,	ynone,	Pm, 0x08 },
-	{ AINVLPG,	ymbs,	Pm, 0x01,(07) },
-	{ ALFENCE,	ynone,	Pm, 0xae,0xe8 },
-	{ AMFENCE,	ynone,	Pm, 0xae,0xf0 },
-	{ AMOVNTIL,	yrl_ml,	Pm, 0xc3 },
-	{ AMOVNTIQ,	yrl_ml, Pw, 0x0f,0xc3 },
-	{ ARDMSR,	ynone,	Pm, 0x32 },
-	{ ARDPMC,	ynone,	Pm, 0x33 },
-	{ ARDTSC,	ynone,	Pm, 0x31 },
-	{ ARSM,		ynone,	Pm, 0xaa },
-	{ ASFENCE,	ynone,	Pm, 0xae,0xf8 },
-	{ ASYSRET,	ynone,	Pm, 0x07 },
-	{ AWBINVD,	ynone,	Pm, 0x09 },
-	{ AWRMSR,	ynone,	Pm, 0x30 },
-
-	{ AXADDB,	yrb_mb,	Pb, 0x0f,0xc0 },
-	{ AXADDL,	yrl_ml,	Px, 0x0f,0xc1 },
-	{ AXADDQ,	yrl_ml,	Pw, 0x0f,0xc1 },
-	{ AXADDW,	yrl_ml,	Pe, 0x0f,0xc1 },
-
-	{ ACRC32B,       ycrc32l,Px, 0xf2,0x0f,0x38,0xf0,0 },
-	{ ACRC32Q,       ycrc32l,Pw, 0xf2,0x0f,0x38,0xf1,0 },
+	{ AFLDCW,	ystcw,	Px, {0xd9,(05),0xd9,(05)} },
+	{ AFLDENV,	ystcw,	Px, {0xd9,(04),0xd9,(04)} },
+	{ AFRSTOR,	ysvrs,	Px, {0xdd,(04),0xdd,(04)} },
+	{ AFSAVE,	ysvrs,	Px, {0xdd,(06),0xdd,(06)} },
+	{ AFSTCW,	ystcw,	Px, {0xd9,(07),0xd9,(07)} },
+	{ AFSTENV,	ystcw,	Px, {0xd9,(06),0xd9,(06)} },
+	{ AFSTSW,	ystsw,	Px, {0xdd,(07),0xdf,0xe0} },
+	{ AF2XM1,	ynone,	Px, {0xd9, 0xf0} },
+	{ AFABS,	ynone,	Px, {0xd9, 0xe1} },
+	{ AFCHS,	ynone,	Px, {0xd9, 0xe0} },
+	{ AFCLEX,	ynone,	Px, {0xdb, 0xe2} },
+	{ AFCOS,	ynone,	Px, {0xd9, 0xff} },
+	{ AFDECSTP,	ynone,	Px, {0xd9, 0xf6} },
+	{ AFINCSTP,	ynone,	Px, {0xd9, 0xf7} },
+	{ AFINIT,	ynone,	Px, {0xdb, 0xe3} },
+	{ AFLD1,	ynone,	Px, {0xd9, 0xe8} },
+	{ AFLDL2E,	ynone,	Px, {0xd9, 0xea} },
+	{ AFLDL2T,	ynone,	Px, {0xd9, 0xe9} },
+	{ AFLDLG2,	ynone,	Px, {0xd9, 0xec} },
+	{ AFLDLN2,	ynone,	Px, {0xd9, 0xed} },
+	{ AFLDPI,	ynone,	Px, {0xd9, 0xeb} },
+	{ AFLDZ,	ynone,	Px, {0xd9, 0xee} },
+	{ AFNOP,	ynone,	Px, {0xd9, 0xd0} },
+	{ AFPATAN,	ynone,	Px, {0xd9, 0xf3} },
+	{ AFPREM,	ynone,	Px, {0xd9, 0xf8} },
+	{ AFPREM1,	ynone,	Px, {0xd9, 0xf5} },
+	{ AFPTAN,	ynone,	Px, {0xd9, 0xf2} },
+	{ AFRNDINT,	ynone,	Px, {0xd9, 0xfc} },
+	{ AFSCALE,	ynone,	Px, {0xd9, 0xfd} },
+	{ AFSIN,	ynone,	Px, {0xd9, 0xfe} },
+	{ AFSINCOS,	ynone,	Px, {0xd9, 0xfb} },
+	{ AFSQRT,	ynone,	Px, {0xd9, 0xfa} },
+	{ AFTST,	ynone,	Px, {0xd9, 0xe4} },
+	{ AFXAM,	ynone,	Px, {0xd9, 0xe5} },
+	{ AFXTRACT,	ynone,	Px, {0xd9, 0xf4} },
+	{ AFYL2X,	ynone,	Px, {0xd9, 0xf1} },
+	{ AFYL2XP1,	ynone,	Px, {0xd9, 0xf9} },
+
+	{ ACMPXCHGB,	yrb_mb,	Pb, {0x0f,0xb0} },
+	{ ACMPXCHGL,	yrl_ml,	Px, {0x0f,0xb1} },
+	{ ACMPXCHGW,	yrl_ml,	Pe, {0x0f,0xb1} },
+	{ ACMPXCHGQ,	yrl_ml,	Pw, {0x0f,0xb1} },
+	{ ACMPXCHG8B,	yscond,	Pm, {0xc7,(01)} },
+	{ AINVD,	ynone,	Pm, {0x08} },
+	{ AINVLPG,	ymbs,	Pm, {0x01,(07)} },
+	{ ALFENCE,	ynone,	Pm, {0xae,0xe8} },
+	{ AMFENCE,	ynone,	Pm, {0xae,0xf0} },
+	{ AMOVNTIL,	yrl_ml,	Pm, {0xc3} },
+	{ AMOVNTIQ,	yrl_ml, Pw, {0x0f,0xc3} },
+	{ ARDMSR,	ynone,	Pm, {0x32} },
+	{ ARDPMC,	ynone,	Pm, {0x33} },
+	{ ARDTSC,	ynone,	Pm, {0x31} },
+	{ ARSM,		ynone,	Pm, {0xaa} },
+	{ ASFENCE,	ynone,	Pm, {0xae,0xf8} },
+	{ ASYSRET,	ynone,	Pm, {0x07} },
+	{ AWBINVD,	ynone,	Pm, {0x09} },
+	{ AWRMSR,	ynone,	Pm, {0x30} },
+
+	{ AXADDB,	yrb_mb,	Pb, {0x0f,0xc0} },
+	{ AXADDL,	yrl_ml,	Px, {0x0f,0xc1} },
+	{ AXADDQ,	yrl_ml,	Pw, {0x0f,0xc1} },
+	{ AXADDW,	yrl_ml,	Pe, {0x0f,0xc1} },
+
+	{ ACRC32B,       ycrc32l,Px, {0xf2,0x0f,0x38,0xf0,0} },
+	{ ACRC32Q,       ycrc32l,Pw, {0xf2,0x0f,0x38,0xf1,0} },
 	
-	{ APREFETCHT0,	yprefetch,	Pm,	0x18,(01) },
-	{ APREFETCHT1,	yprefetch,	Pm,	0x18,(02) },
-	{ APREFETCHT2,	yprefetch,	Pm,	0x18,(03) },
-	{ APREFETCHNTA,	yprefetch,	Pm,	0x18,(00) },
+	{ APREFETCHT0,	yprefetch,	Pm,	{0x18,(01)} },
+	{ APREFETCHT1,	yprefetch,	Pm,	{0x18,(02)} },
+	{ APREFETCHT2,	yprefetch,	Pm,	{0x18,(03)} },
+	{ APREFETCHNTA,	yprefetch,	Pm,	{0x18,(00)} },
 	
-	{ AMOVQL,	yrl_ml,	Px, 0x89 },
+	{ AMOVQL,	yrl_ml,	Px, {0x89} },
 
-	{ AUNDEF,		ynone,	Px, 0x0f, 0x0b },
+	{ AUNDEF,		ynone,	Px, {0x0f, 0x0b} },
 
-	{ AAESENC,	yaes,	Pq, 0x38,0xdc,(0) },
-	{ AAESENCLAST,	yaes,	Pq, 0x38,0xdd,(0) },
-	{ AAESDEC,	yaes,	Pq, 0x38,0xde,(0) },
-	{ AAESDECLAST,	yaes,	Pq, 0x38,0xdf,(0) },
-	{ AAESIMC,	yaes,	Pq, 0x38,0xdb,(0) },
-	{ AAESKEYGENASSIST,	yaes2,	Pq, 0x3a,0xdf,(0) },
+	{ AAESENC,	yaes,	Pq, {0x38,0xdc,(0)} },
+	{ AAESENCLAST,	yaes,	Pq, {0x38,0xdd,(0)} },
+	{ AAESDEC,	yaes,	Pq, {0x38,0xde,(0)} },
+	{ AAESDECLAST,	yaes,	Pq, {0x38,0xdf,(0)} },
+	{ AAESIMC,	yaes,	Pq, {0x38,0xdb,(0)} },
+	{ AAESKEYGENASSIST,	yaes2,	Pq, {0x3a,0xdf,(0)} },
 
-	{ APSHUFD,	yaes2,	Pq,	0x70,(0) },
-	{ APCLMULQDQ,	yxshuf,	Pq, 0x3a,0x44,0 },
+	{ APSHUFD,	yaes2,	Pq,	{0x70,(0)} },
+	{ APCLMULQDQ,	yxshuf,	Pq, {0x3a,0x44,0} },
 
-	{ AUSEFIELD,	ynop,	Px, 0,0 },
+	{ AUSEFIELD,	ynop,	Px, {0,0} },
 	{ ATYPE },
-	{ AFUNCDATA,	yfuncdata,	Px, 0,0 },
-	{ APCDATA,	ypcdata,	Px, 0,0 },
+	{ AFUNCDATA,	yfuncdata,	Px, {0,0} },
+	{ APCDATA,	ypcdata,	Px, {0,0} },
 	{ ACHECKNIL },
 	{ AVARDEF },
 	{ AVARKILL },
-	{ ADUFFCOPY,	yduff,	Px, 0xe8 },
-	{ ADUFFZERO,	yduff,	Px, 0xe8 },
+	{ ADUFFCOPY,	yduff,	Px, {0xe8} },
+	{ ADUFFZERO,	yduff,	Px, {0xe8} },
 
 	{ AEND },
-	0
+	{0}
 };
 
 static Optab*	opindex[ALAST+1];
 static vlong	vaddr(Link*, Addr*, Reloc*);
 
+// isextern reports whether s describes an external symbol that must avoid pc-relative addressing.
+// This happens on systems like Solaris that call .so functions instead of system calls.
+// It does not seem to be necessary for any other systems. This is probably working
+// around a Solaris-specific bug that should be fixed differently, but we don't know
+// what that bug is. And this does fix it.
+static int
+isextern(LSym *s)
+{
+	// All the Solaris dynamic imports from libc.so begin with "libc·", which
+	// the compiler rewrites to "libc." by the time liblink gets it.
+	return strncmp(s->name, "libc.", 5) == 0;
+}
+
 // single-instruction no-ops of various lengths.
 // constructed by hand and disassembled with gdb to verify.
 // see http://www.agner.org/optimize/optimizing_assembly.pdf for discussion.
@@ -1901,7 +1912,6 @@ prefixof(Link *ctxt, Addr *a)
 		case Hlinux:
 		case Hnetbsd:
 		case Hopenbsd:
-		case Hplan9:
 		case Hsolaris:
 			return 0x64; // FS
 		case Hdarwin:
@@ -1935,10 +1945,9 @@ oclass(Link *ctxt, Addr *a)
 				switch(a->index) {
 				case D_EXTERN:
 				case D_STATIC:
-					if(ctxt->flag_shared || ctxt->headtype == Hnacl)
-						return Yiauto;
-					else
-						return Yi32;	/* TO DO: Yi64 */
+					if(a->sym != nil && isextern(a->sym))
+						return Yi32;
+					return Yiauto; // use pc-relative addressing
 				case D_AUTO:
 				case D_PARAM:
 					return Yiauto;
@@ -2115,7 +2124,7 @@ oclass(Link *ctxt, Addr *a)
 				return Yi32;	/* unsigned */
 			return Yi64;
 		}
-		return Yi32;	/* TO DO: D_ADDR as Yi64 */
+		return Yi32;
 
 	case D_BRANCH:
 		return Ybr;
@@ -2288,20 +2297,22 @@ vaddr(Link *ctxt, Addr *a, Reloc *r)
 			ctxt->diag("need reloc for %D", a);
 			sysfatal("reloc");
 		}
-		r->siz = 4;	// TODO: 8 for external symbols
+		if(isextern(s)) {
+			r->siz = 4;
+			r->type = R_ADDR;
+		} else {
+			r->siz = 4;
+			r->type = R_PCREL;
+		}
 		r->off = -1;	// caller must fill in
 		r->sym = s;
 		r->add = v;
 		v = 0;
-		if(ctxt->flag_shared || ctxt->headtype == Hnacl) {
-			if(s->type == STLSBSS) {
-				r->xadd = r->add - r->siz;
-				r->type = R_TLS;
-				r->xsym = s;
-			} else
-				r->type = R_PCREL;
-		} else
-			r->type = R_ADDR;
+		if(s->type == STLSBSS) {
+			r->xadd = r->add - r->siz;
+			r->type = R_TLS;
+			r->xsym = s;
+		}
 		break;
 	
 	case D_INDIR+D_TLS:
@@ -2336,9 +2347,9 @@ asmandsz(Link *ctxt, Addr *a, int r, int rex, int m64)
 			switch(t) {
 			default:
 				goto bad;
-			case D_STATIC:
 			case D_EXTERN:
-				if(ctxt->flag_shared || ctxt->headtype == Hnacl)
+			case D_STATIC:
+				if(!isextern(a->sym))
 					goto bad;
 				t = D_NONE;
 				v = vaddr(ctxt, a, &rel);
@@ -2402,7 +2413,7 @@ asmandsz(Link *ctxt, Addr *a, int r, int rex, int m64)
 
 	ctxt->rexflag |= (regrex[t] & Rxb) | rex;
 	if(t == D_NONE || (D_CS <= t && t <= D_GS) || t == D_TLS) {
-		if((ctxt->flag_shared || ctxt->headtype == Hnacl) && t == D_NONE && (a->type == D_STATIC || a->type == D_EXTERN) || ctxt->asmode != 64) {
+		if((a->sym == nil || !isextern(a->sym)) && t == D_NONE && (a->type == D_STATIC || a->type == D_EXTERN) || ctxt->asmode != 64) {
 			*ctxt->andptr++ = (0 << 6) | (5 << 0) | (r << 3);
 			goto putrelv;
 		}
@@ -2485,7 +2496,7 @@ asmando(Link *ctxt, Addr *a, int o)
 }
 
 static void
-bytereg(Addr *a, char *t)
+bytereg(Addr *a, uint8 *t)
 {
 	if(a->index == D_NONE && (a->type >= D_AX && a->type <= D_R15)) {
 		a->type = D_AL + (a->type-D_AX);
@@ -2493,139 +2504,141 @@ bytereg(Addr *a, char *t)
 	}
 }
 
-#define	E	0xff
+enum {
+	E = 0xff,
+};
 static Movtab	ymovtab[] =
 {
 /* push */
-	{APUSHL,	Ycs,	Ynone,	0,	0x0e,E,0,0},
-	{APUSHL,	Yss,	Ynone,	0,	0x16,E,0,0},
-	{APUSHL,	Yds,	Ynone,	0,	0x1e,E,0,0},
-	{APUSHL,	Yes,	Ynone,	0,	0x06,E,0,0},
-	{APUSHL,	Yfs,	Ynone,	0,	0x0f,0xa0,E,0},
-	{APUSHL,	Ygs,	Ynone,	0,	0x0f,0xa8,E,0},
-	{APUSHQ,	Yfs,	Ynone,	0,	0x0f,0xa0,E,0},
-	{APUSHQ,	Ygs,	Ynone,	0,	0x0f,0xa8,E,0},
-
-	{APUSHW,	Ycs,	Ynone,	0,	Pe,0x0e,E,0},
-	{APUSHW,	Yss,	Ynone,	0,	Pe,0x16,E,0},
-	{APUSHW,	Yds,	Ynone,	0,	Pe,0x1e,E,0},
-	{APUSHW,	Yes,	Ynone,	0,	Pe,0x06,E,0},
-	{APUSHW,	Yfs,	Ynone,	0,	Pe,0x0f,0xa0,E},
-	{APUSHW,	Ygs,	Ynone,	0,	Pe,0x0f,0xa8,E},
+	{APUSHL,	Ycs,	Ynone,	0,	{0x0e,E,0,0}},
+	{APUSHL,	Yss,	Ynone,	0,	{0x16,E,0,0}},
+	{APUSHL,	Yds,	Ynone,	0,	{0x1e,E,0,0}},
+	{APUSHL,	Yes,	Ynone,	0,	{0x06,E,0,0}},
+	{APUSHL,	Yfs,	Ynone,	0,	{0x0f,0xa0,E,0}},
+	{APUSHL,	Ygs,	Ynone,	0,	{0x0f,0xa8,E,0}},
+	{APUSHQ,	Yfs,	Ynone,	0,	{0x0f,0xa0,E,0}},
+	{APUSHQ,	Ygs,	Ynone,	0,	{0x0f,0xa8,E,0}},
+
+	{APUSHW,	Ycs,	Ynone,	0,	{Pe,0x0e,E,0}},
+	{APUSHW,	Yss,	Ynone,	0,	{Pe,0x16,E,0}},
+	{APUSHW,	Yds,	Ynone,	0,	{Pe,0x1e,E,0}},
+	{APUSHW,	Yes,	Ynone,	0,	{Pe,0x06,E,0}},
+	{APUSHW,	Yfs,	Ynone,	0,	{Pe,0x0f,0xa0,E}},
+	{APUSHW,	Ygs,	Ynone,	0,	{Pe,0x0f,0xa8,E}},
 
 /* pop */
-	{APOPL,	Ynone,	Yds,	0,	0x1f,E,0,0},
-	{APOPL,	Ynone,	Yes,	0,	0x07,E,0,0},
-	{APOPL,	Ynone,	Yss,	0,	0x17,E,0,0},
-	{APOPL,	Ynone,	Yfs,	0,	0x0f,0xa1,E,0},
-	{APOPL,	Ynone,	Ygs,	0,	0x0f,0xa9,E,0},
-	{APOPQ,	Ynone,	Yfs,	0,	0x0f,0xa1,E,0},
-	{APOPQ,	Ynone,	Ygs,	0,	0x0f,0xa9,E,0},
-
-	{APOPW,	Ynone,	Yds,	0,	Pe,0x1f,E,0},
-	{APOPW,	Ynone,	Yes,	0,	Pe,0x07,E,0},
-	{APOPW,	Ynone,	Yss,	0,	Pe,0x17,E,0},
-	{APOPW,	Ynone,	Yfs,	0,	Pe,0x0f,0xa1,E},
-	{APOPW,	Ynone,	Ygs,	0,	Pe,0x0f,0xa9,E},
+	{APOPL,	Ynone,	Yds,	0,	{0x1f,E,0,0}},
+	{APOPL,	Ynone,	Yes,	0,	{0x07,E,0,0}},
+	{APOPL,	Ynone,	Yss,	0,	{0x17,E,0,0}},
+	{APOPL,	Ynone,	Yfs,	0,	{0x0f,0xa1,E,0}},
+	{APOPL,	Ynone,	Ygs,	0,	{0x0f,0xa9,E,0}},
+	{APOPQ,	Ynone,	Yfs,	0,	{0x0f,0xa1,E,0}},
+	{APOPQ,	Ynone,	Ygs,	0,	{0x0f,0xa9,E,0}},
+
+	{APOPW,	Ynone,	Yds,	0,	{Pe,0x1f,E,0}},
+	{APOPW,	Ynone,	Yes,	0,	{Pe,0x07,E,0}},
+	{APOPW,	Ynone,	Yss,	0,	{Pe,0x17,E,0}},
+	{APOPW,	Ynone,	Yfs,	0,	{Pe,0x0f,0xa1,E}},
+	{APOPW,	Ynone,	Ygs,	0,	{Pe,0x0f,0xa9,E}},
 
 /* mov seg */
-	{AMOVW,	Yes,	Yml,	1,	0x8c,0,0,0},
-	{AMOVW,	Ycs,	Yml,	1,	0x8c,1,0,0},
-	{AMOVW,	Yss,	Yml,	1,	0x8c,2,0,0},
-	{AMOVW,	Yds,	Yml,	1,	0x8c,3,0,0},
-	{AMOVW,	Yfs,	Yml,	1,	0x8c,4,0,0},
-	{AMOVW,	Ygs,	Yml,	1,	0x8c,5,0,0},
-
-	{AMOVW,	Yml,	Yes,	2,	0x8e,0,0,0},
-	{AMOVW,	Yml,	Ycs,	2,	0x8e,1,0,0},
-	{AMOVW,	Yml,	Yss,	2,	0x8e,2,0,0},
-	{AMOVW,	Yml,	Yds,	2,	0x8e,3,0,0},
-	{AMOVW,	Yml,	Yfs,	2,	0x8e,4,0,0},
-	{AMOVW,	Yml,	Ygs,	2,	0x8e,5,0,0},
+	{AMOVW,	Yes,	Yml,	1,	{0x8c,0,0,0}},
+	{AMOVW,	Ycs,	Yml,	1,	{0x8c,1,0,0}},
+	{AMOVW,	Yss,	Yml,	1,	{0x8c,2,0,0}},
+	{AMOVW,	Yds,	Yml,	1,	{0x8c,3,0,0}},
+	{AMOVW,	Yfs,	Yml,	1,	{0x8c,4,0,0}},
+	{AMOVW,	Ygs,	Yml,	1,	{0x8c,5,0,0}},
+
+	{AMOVW,	Yml,	Yes,	2,	{0x8e,0,0,0}},
+	{AMOVW,	Yml,	Ycs,	2,	{0x8e,1,0,0}},
+	{AMOVW,	Yml,	Yss,	2,	{0x8e,2,0,0}},
+	{AMOVW,	Yml,	Yds,	2,	{0x8e,3,0,0}},
+	{AMOVW,	Yml,	Yfs,	2,	{0x8e,4,0,0}},
+	{AMOVW,	Yml,	Ygs,	2,	{0x8e,5,0,0}},
 
 /* mov cr */
-	{AMOVL,	Ycr0,	Yml,	3,	0x0f,0x20,0,0},
-	{AMOVL,	Ycr2,	Yml,	3,	0x0f,0x20,2,0},
-	{AMOVL,	Ycr3,	Yml,	3,	0x0f,0x20,3,0},
-	{AMOVL,	Ycr4,	Yml,	3,	0x0f,0x20,4,0},
-	{AMOVL,	Ycr8,	Yml,	3,	0x0f,0x20,8,0},
-	{AMOVQ,	Ycr0,	Yml,	3,	0x0f,0x20,0,0},
-	{AMOVQ,	Ycr2,	Yml,	3,	0x0f,0x20,2,0},
-	{AMOVQ,	Ycr3,	Yml,	3,	0x0f,0x20,3,0},
-	{AMOVQ,	Ycr4,	Yml,	3,	0x0f,0x20,4,0},
-	{AMOVQ,	Ycr8,	Yml,	3,	0x0f,0x20,8,0},
-
-	{AMOVL,	Yml,	Ycr0,	4,	0x0f,0x22,0,0},
-	{AMOVL,	Yml,	Ycr2,	4,	0x0f,0x22,2,0},
-	{AMOVL,	Yml,	Ycr3,	4,	0x0f,0x22,3,0},
-	{AMOVL,	Yml,	Ycr4,	4,	0x0f,0x22,4,0},
-	{AMOVL,	Yml,	Ycr8,	4,	0x0f,0x22,8,0},
-	{AMOVQ,	Yml,	Ycr0,	4,	0x0f,0x22,0,0},
-	{AMOVQ,	Yml,	Ycr2,	4,	0x0f,0x22,2,0},
-	{AMOVQ,	Yml,	Ycr3,	4,	0x0f,0x22,3,0},
-	{AMOVQ,	Yml,	Ycr4,	4,	0x0f,0x22,4,0},
-	{AMOVQ,	Yml,	Ycr8,	4,	0x0f,0x22,8,0},
+	{AMOVL,	Ycr0,	Yml,	3,	{0x0f,0x20,0,0}},
+	{AMOVL,	Ycr2,	Yml,	3,	{0x0f,0x20,2,0}},
+	{AMOVL,	Ycr3,	Yml,	3,	{0x0f,0x20,3,0}},
+	{AMOVL,	Ycr4,	Yml,	3,	{0x0f,0x20,4,0}},
+	{AMOVL,	Ycr8,	Yml,	3,	{0x0f,0x20,8,0}},
+	{AMOVQ,	Ycr0,	Yml,	3,	{0x0f,0x20,0,0}},
+	{AMOVQ,	Ycr2,	Yml,	3,	{0x0f,0x20,2,0}},
+	{AMOVQ,	Ycr3,	Yml,	3,	{0x0f,0x20,3,0}},
+	{AMOVQ,	Ycr4,	Yml,	3,	{0x0f,0x20,4,0}},
+	{AMOVQ,	Ycr8,	Yml,	3,	{0x0f,0x20,8,0}},
+
+	{AMOVL,	Yml,	Ycr0,	4,	{0x0f,0x22,0,0}},
+	{AMOVL,	Yml,	Ycr2,	4,	{0x0f,0x22,2,0}},
+	{AMOVL,	Yml,	Ycr3,	4,	{0x0f,0x22,3,0}},
+	{AMOVL,	Yml,	Ycr4,	4,	{0x0f,0x22,4,0}},
+	{AMOVL,	Yml,	Ycr8,	4,	{0x0f,0x22,8,0}},
+	{AMOVQ,	Yml,	Ycr0,	4,	{0x0f,0x22,0,0}},
+	{AMOVQ,	Yml,	Ycr2,	4,	{0x0f,0x22,2,0}},
+	{AMOVQ,	Yml,	Ycr3,	4,	{0x0f,0x22,3,0}},
+	{AMOVQ,	Yml,	Ycr4,	4,	{0x0f,0x22,4,0}},
+	{AMOVQ,	Yml,	Ycr8,	4,	{0x0f,0x22,8,0}},
 
 /* mov dr */
-	{AMOVL,	Ydr0,	Yml,	3,	0x0f,0x21,0,0},
-	{AMOVL,	Ydr6,	Yml,	3,	0x0f,0x21,6,0},
-	{AMOVL,	Ydr7,	Yml,	3,	0x0f,0x21,7,0},
-	{AMOVQ,	Ydr0,	Yml,	3,	0x0f,0x21,0,0},
-	{AMOVQ,	Ydr6,	Yml,	3,	0x0f,0x21,6,0},
-	{AMOVQ,	Ydr7,	Yml,	3,	0x0f,0x21,7,0},
-
-	{AMOVL,	Yml,	Ydr0,	4,	0x0f,0x23,0,0},
-	{AMOVL,	Yml,	Ydr6,	4,	0x0f,0x23,6,0},
-	{AMOVL,	Yml,	Ydr7,	4,	0x0f,0x23,7,0},
-	{AMOVQ,	Yml,	Ydr0,	4,	0x0f,0x23,0,0},
-	{AMOVQ,	Yml,	Ydr6,	4,	0x0f,0x23,6,0},
-	{AMOVQ,	Yml,	Ydr7,	4,	0x0f,0x23,7,0},
+	{AMOVL,	Ydr0,	Yml,	3,	{0x0f,0x21,0,0}},
+	{AMOVL,	Ydr6,	Yml,	3,	{0x0f,0x21,6,0}},
+	{AMOVL,	Ydr7,	Yml,	3,	{0x0f,0x21,7,0}},
+	{AMOVQ,	Ydr0,	Yml,	3,	{0x0f,0x21,0,0}},
+	{AMOVQ,	Ydr6,	Yml,	3,	{0x0f,0x21,6,0}},
+	{AMOVQ,	Ydr7,	Yml,	3,	{0x0f,0x21,7,0}},
+
+	{AMOVL,	Yml,	Ydr0,	4,	{0x0f,0x23,0,0}},
+	{AMOVL,	Yml,	Ydr6,	4,	{0x0f,0x23,6,0}},
+	{AMOVL,	Yml,	Ydr7,	4,	{0x0f,0x23,7,0}},
+	{AMOVQ,	Yml,	Ydr0,	4,	{0x0f,0x23,0,0}},
+	{AMOVQ,	Yml,	Ydr6,	4,	{0x0f,0x23,6,0}},
+	{AMOVQ,	Yml,	Ydr7,	4,	{0x0f,0x23,7,0}},
 
 /* mov tr */
-	{AMOVL,	Ytr6,	Yml,	3,	0x0f,0x24,6,0},
-	{AMOVL,	Ytr7,	Yml,	3,	0x0f,0x24,7,0},
+	{AMOVL,	Ytr6,	Yml,	3,	{0x0f,0x24,6,0}},
+	{AMOVL,	Ytr7,	Yml,	3,	{0x0f,0x24,7,0}},
 
-	{AMOVL,	Yml,	Ytr6,	4,	0x0f,0x26,6,E},
-	{AMOVL,	Yml,	Ytr7,	4,	0x0f,0x26,7,E},
+	{AMOVL,	Yml,	Ytr6,	4,	{0x0f,0x26,6,E}},
+	{AMOVL,	Yml,	Ytr7,	4,	{0x0f,0x26,7,E}},
 
 /* lgdt, sgdt, lidt, sidt */
-	{AMOVL,	Ym,	Ygdtr,	4,	0x0f,0x01,2,0},
-	{AMOVL,	Ygdtr,	Ym,	3,	0x0f,0x01,0,0},
-	{AMOVL,	Ym,	Yidtr,	4,	0x0f,0x01,3,0},
-	{AMOVL,	Yidtr,	Ym,	3,	0x0f,0x01,1,0},
-	{AMOVQ,	Ym,	Ygdtr,	4,	0x0f,0x01,2,0},
-	{AMOVQ,	Ygdtr,	Ym,	3,	0x0f,0x01,0,0},
-	{AMOVQ,	Ym,	Yidtr,	4,	0x0f,0x01,3,0},
-	{AMOVQ,	Yidtr,	Ym,	3,	0x0f,0x01,1,0},
+	{AMOVL,	Ym,	Ygdtr,	4,	{0x0f,0x01,2,0}},
+	{AMOVL,	Ygdtr,	Ym,	3,	{0x0f,0x01,0,0}},
+	{AMOVL,	Ym,	Yidtr,	4,	{0x0f,0x01,3,0}},
+	{AMOVL,	Yidtr,	Ym,	3,	{0x0f,0x01,1,0}},
+	{AMOVQ,	Ym,	Ygdtr,	4,	{0x0f,0x01,2,0}},
+	{AMOVQ,	Ygdtr,	Ym,	3,	{0x0f,0x01,0,0}},
+	{AMOVQ,	Ym,	Yidtr,	4,	{0x0f,0x01,3,0}},
+	{AMOVQ,	Yidtr,	Ym,	3,	{0x0f,0x01,1,0}},
 
 /* lldt, sldt */
-	{AMOVW,	Yml,	Yldtr,	4,	0x0f,0x00,2,0},
-	{AMOVW,	Yldtr,	Yml,	3,	0x0f,0x00,0,0},
+	{AMOVW,	Yml,	Yldtr,	4,	{0x0f,0x00,2,0}},
+	{AMOVW,	Yldtr,	Yml,	3,	{0x0f,0x00,0,0}},
 
 /* lmsw, smsw */
-	{AMOVW,	Yml,	Ymsw,	4,	0x0f,0x01,6,0},
-	{AMOVW,	Ymsw,	Yml,	3,	0x0f,0x01,4,0},
+	{AMOVW,	Yml,	Ymsw,	4,	{0x0f,0x01,6,0}},
+	{AMOVW,	Ymsw,	Yml,	3,	{0x0f,0x01,4,0}},
 
 /* ltr, str */
-	{AMOVW,	Yml,	Ytask,	4,	0x0f,0x00,3,0},
-	{AMOVW,	Ytask,	Yml,	3,	0x0f,0x00,1,0},
+	{AMOVW,	Yml,	Ytask,	4,	{0x0f,0x00,3,0}},
+	{AMOVW,	Ytask,	Yml,	3,	{0x0f,0x00,1,0}},
 
 /* load full pointer */
-	{AMOVL,	Yml,	Ycol,	5,	0,0,0,0},
-	{AMOVW,	Yml,	Ycol,	5,	Pe,0,0,0},
+	{AMOVL,	Yml,	Ycol,	5,	{0,0,0,0}},
+	{AMOVW,	Yml,	Ycol,	5,	{Pe,0,0,0}},
 
 /* double shift */
-	{ASHLL,	Ycol,	Yml,	6,	0xa4,0xa5,0,0},
-	{ASHRL,	Ycol,	Yml,	6,	0xac,0xad,0,0},
-	{ASHLQ,	Ycol,	Yml,	6,	Pw,0xa4,0xa5,0},
-	{ASHRQ,	Ycol,	Yml,	6,	Pw,0xac,0xad,0},
-	{ASHLW,	Ycol,	Yml,	6,	Pe,0xa4,0xa5,0},
-	{ASHRW,	Ycol,	Yml,	6,	Pe,0xac,0xad,0},
+	{ASHLL,	Ycol,	Yml,	6,	{0xa4,0xa5,0,0}},
+	{ASHRL,	Ycol,	Yml,	6,	{0xac,0xad,0,0}},
+	{ASHLQ,	Ycol,	Yml,	6,	{Pw,0xa4,0xa5,0}},
+	{ASHRQ,	Ycol,	Yml,	6,	{Pw,0xac,0xad,0}},
+	{ASHLW,	Ycol,	Yml,	6,	{Pe,0xa4,0xa5,0}},
+	{ASHRW,	Ycol,	Yml,	6,	{Pe,0xac,0xad,0}},
 
 /* load TLS base */
-	{AMOVQ,	Ytls,	Yrl,	7,	0,0,0,0},
+	{AMOVQ,	Ytls,	Yrl,	7,	{0,0,0,0}},
 
-	0
+	{0}
 };
 
 static int
@@ -2687,7 +2700,7 @@ mediaop(Link *ctxt, Optab *o, int op, int osize, int z)
 			break;
 		}
 	default:
-		if(ctxt->andptr == ctxt->and || ctxt->andptr[-1] != Pm)
+		if(ctxt->andptr == ctxt->and || ctxt->and[ctxt->andptr - ctxt->and - 1] != Pm)
 			*ctxt->andptr++ = Pm;
 		break;
 	}
@@ -2903,8 +2916,13 @@ found:
 		asmando(ctxt, &p->to, o->op[z+1]);
 		break;
 
+	case Zcallindreg:
+		r = addrel(ctxt->cursym);
+		r->off = p->pc;
+		r->type = R_CALLIND;
+		r->siz = 0;
+		// fallthrough
 	case Zo_m64:
-	case_Zo_m64:
 		*ctxt->andptr++ = op;
 		asmandsz(ctxt, &p->to, o->op[z+1], 0, 1);
 		break;
@@ -3062,6 +3080,7 @@ found:
 		break;
 
 	case Zclr:
+		ctxt->rexflag &= ~Pw;
 		*ctxt->andptr++ = op;
 		asmand(ctxt, &p->to, &p->to);
 		break;
@@ -3081,13 +3100,6 @@ found:
 		put4(ctxt, 0);
 		break;
 
-	case Zcallindreg:
-		r = addrel(ctxt->cursym);
-		r->off = p->pc;
-		r->type = R_CALLIND;
-		r->siz = 0;
-		goto case_Zo_m64;
-
 	case Zbr:
 	case Zjmp:
 	case Zloop:
@@ -3365,6 +3377,19 @@ mfound:
 		default:
 			sysfatal("unknown TLS base location for %s", headstr(ctxt->headtype));
 
+		case Hplan9:
+			if(ctxt->plan9privates == nil)
+				ctxt->plan9privates = linklookup(ctxt, "_privates", 0);
+			memset(&pp.from, 0, sizeof pp.from);
+			pp.from.type = D_EXTERN;
+			pp.from.sym = ctxt->plan9privates;
+			pp.from.offset = 0;
+			pp.from.index = D_NONE;
+			ctxt->rexflag |= Pw;
+			*ctxt->andptr++ = 0x8B;
+			asmand(ctxt, &pp.from, &p->to);
+			break;
+
 		case Hsolaris: // TODO(rsc): Delete Hsolaris from list. Should not use this code. See progedit in obj6.c.
 			// TLS base is 0(FS).
 			pp.from = p->from;
@@ -3436,7 +3461,7 @@ nacltrunc(Link *ctxt, int reg)
 static void
 asmins(Link *ctxt, Prog *p)
 {
-	int n, np, c;
+	int i, n, np, c;
 	uchar *and0;
 	Reloc *r;
 	
@@ -3561,7 +3586,8 @@ asmins(Link *ctxt, Prog *p)
 		ctxt->andptr++;
 	}
 	n = ctxt->andptr - ctxt->and;
-	for(r=ctxt->cursym->r+ctxt->cursym->nr; r-- > ctxt->cursym->r; ) {
+	for(i=ctxt->cursym->nr-1; i>=0; i--) {
+		r = ctxt->cursym->r+i;
 		if(r->off < p->pc)
 			break;
 		if(ctxt->rexflag)
diff --git a/src/liblink/asm8.c b/src/liblink/asm8.c
index 3ab527c..b6627d5 100644
--- a/src/liblink/asm8.c
+++ b/src/liblink/asm8.c
@@ -35,7 +35,7 @@
 #include <bio.h>
 #include <link.h>
 #include "../cmd/8l/8.out.h"
-#include "../pkg/runtime/stack.h"
+#include "../runtime/stack.h"
 
 enum
 {
@@ -43,8 +43,6 @@ enum
 	FuncAlign = 16
 };
 
-extern char *anames6[];
-
 typedef	struct	Optab	Optab;
 
 struct	Optab
@@ -142,7 +140,7 @@ enum
 };
 
 static	uchar	ycover[Ymax*Ymax];
-static	char	reg[D_NONE];
+static	int	reg[D_NONE];
 static	void	asmins(Link *ctxt, Prog *p);
 
 static uchar	ynone[] =
@@ -617,548 +615,548 @@ static Optab optab[] =
 /*	as, ytab, andproto, opcode */
 {
 	{ AXXX },
-	{ AAAA,		ynone,	Px, 0x37 },
-	{ AAAD,		ynone,	Px, 0xd5,0x0a },
-	{ AAAM,		ynone,	Px, 0xd4,0x0a },
-	{ AAAS,		ynone,	Px, 0x3f },
-	{ AADCB,	yxorb,	Pb, 0x14,0x80,(02),0x10,0x10 },
-	{ AADCL,	yxorl,	Px, 0x83,(02),0x15,0x81,(02),0x11,0x13 },
-	{ AADCW,	yxorl,	Pe, 0x83,(02),0x15,0x81,(02),0x11,0x13 },
-	{ AADDB,	yxorb,	Px, 0x04,0x80,(00),0x00,0x02 },
-	{ AADDL,	yaddl,	Px, 0x83,(00),0x05,0x81,(00),0x01,0x03 },
-	{ AADDW,	yaddl,	Pe, 0x83,(00),0x05,0x81,(00),0x01,0x03 },
+	{ AAAA,		ynone,	Px, {0x37} },
+	{ AAAD,		ynone,	Px, {0xd5,0x0a} },
+	{ AAAM,		ynone,	Px, {0xd4,0x0a} },
+	{ AAAS,		ynone,	Px, {0x3f} },
+	{ AADCB,	yxorb,	Pb, {0x14,0x80,(02),0x10,0x10} },
+	{ AADCL,	yxorl,	Px, {0x83,(02),0x15,0x81,(02),0x11,0x13} },
+	{ AADCW,	yxorl,	Pe, {0x83,(02),0x15,0x81,(02),0x11,0x13} },
+	{ AADDB,	yxorb,	Px, {0x04,0x80,(00),0x00,0x02} },
+	{ AADDL,	yaddl,	Px, {0x83,(00),0x05,0x81,(00),0x01,0x03} },
+	{ AADDW,	yaddl,	Pe, {0x83,(00),0x05,0x81,(00),0x01,0x03} },
 	{ AADJSP },
-	{ AANDB,	yxorb,	Pb, 0x24,0x80,(04),0x20,0x22 },
-	{ AANDL,	yxorl,	Px, 0x83,(04),0x25,0x81,(04),0x21,0x23 },
-	{ AANDW,	yxorl,	Pe, 0x83,(04),0x25,0x81,(04),0x21,0x23 },
-	{ AARPL,	yrl_ml,	Px, 0x63 },
-	{ ABOUNDL,	yrl_m,	Px, 0x62 },
-	{ ABOUNDW,	yrl_m,	Pe, 0x62 },
-	{ ABSFL,	yml_rl,	Pm, 0xbc },
-	{ ABSFW,	yml_rl,	Pq, 0xbc },
-	{ ABSRL,	yml_rl,	Pm, 0xbd },
-	{ ABSRW,	yml_rl,	Pq, 0xbd },
-	{ ABTL,		yml_rl,	Pm, 0xa3 },
-	{ ABTW,		yml_rl,	Pq, 0xa3 },
-	{ ABTCL,	yml_rl,	Pm, 0xbb },
-	{ ABTCW,	yml_rl,	Pq, 0xbb },
-	{ ABTRL,	yml_rl,	Pm, 0xb3 },
-	{ ABTRW,	yml_rl,	Pq, 0xb3 },
-	{ ABTSL,	yml_rl,	Pm, 0xab },
-	{ ABTSW,	yml_rl,	Pq, 0xab },
-	{ ABYTE,	ybyte,	Px, 1 },
-	{ ACALL,	ycall,	Px, 0xff,(02),0xff,(0x15),0xe8 },
-	{ ACLC,		ynone,	Px, 0xf8 },
-	{ ACLD,		ynone,	Px, 0xfc },
-	{ ACLI,		ynone,	Px, 0xfa },
-	{ ACLTS,	ynone,	Pm, 0x06 },
-	{ ACMC,		ynone,	Px, 0xf5 },
-	{ ACMPB,	ycmpb,	Pb, 0x3c,0x80,(07),0x38,0x3a },
-	{ ACMPL,	ycmpl,	Px, 0x83,(07),0x3d,0x81,(07),0x39,0x3b },
-	{ ACMPW,	ycmpl,	Pe, 0x83,(07),0x3d,0x81,(07),0x39,0x3b },
-	{ ACMPSB,	ynone,	Pb, 0xa6 },
-	{ ACMPSL,	ynone,	Px, 0xa7 },
-	{ ACMPSW,	ynone,	Pe, 0xa7 },
-	{ ADAA,		ynone,	Px, 0x27 },
-	{ ADAS,		ynone,	Px, 0x2f },
+	{ AANDB,	yxorb,	Pb, {0x24,0x80,(04),0x20,0x22} },
+	{ AANDL,	yxorl,	Px, {0x83,(04),0x25,0x81,(04),0x21,0x23} },
+	{ AANDW,	yxorl,	Pe, {0x83,(04),0x25,0x81,(04),0x21,0x23} },
+	{ AARPL,	yrl_ml,	Px, {0x63} },
+	{ ABOUNDL,	yrl_m,	Px, {0x62} },
+	{ ABOUNDW,	yrl_m,	Pe, {0x62} },
+	{ ABSFL,	yml_rl,	Pm, {0xbc} },
+	{ ABSFW,	yml_rl,	Pq, {0xbc} },
+	{ ABSRL,	yml_rl,	Pm, {0xbd} },
+	{ ABSRW,	yml_rl,	Pq, {0xbd} },
+	{ ABTL,		yml_rl,	Pm, {0xa3} },
+	{ ABTW,		yml_rl,	Pq, {0xa3} },
+	{ ABTCL,	yml_rl,	Pm, {0xbb} },
+	{ ABTCW,	yml_rl,	Pq, {0xbb} },
+	{ ABTRL,	yml_rl,	Pm, {0xb3} },
+	{ ABTRW,	yml_rl,	Pq, {0xb3} },
+	{ ABTSL,	yml_rl,	Pm, {0xab} },
+	{ ABTSW,	yml_rl,	Pq, {0xab} },
+	{ ABYTE,	ybyte,	Px, {1} },
+	{ ACALL,	ycall,	Px, {0xff,(02),0xff,(0x15),0xe8} },
+	{ ACLC,		ynone,	Px, {0xf8} },
+	{ ACLD,		ynone,	Px, {0xfc} },
+	{ ACLI,		ynone,	Px, {0xfa} },
+	{ ACLTS,	ynone,	Pm, {0x06} },
+	{ ACMC,		ynone,	Px, {0xf5} },
+	{ ACMPB,	ycmpb,	Pb, {0x3c,0x80,(07),0x38,0x3a} },
+	{ ACMPL,	ycmpl,	Px, {0x83,(07),0x3d,0x81,(07),0x39,0x3b} },
+	{ ACMPW,	ycmpl,	Pe, {0x83,(07),0x3d,0x81,(07),0x39,0x3b} },
+	{ ACMPSB,	ynone,	Pb, {0xa6} },
+	{ ACMPSL,	ynone,	Px, {0xa7} },
+	{ ACMPSW,	ynone,	Pe, {0xa7} },
+	{ ADAA,		ynone,	Px, {0x27} },
+	{ ADAS,		ynone,	Px, {0x2f} },
 	{ ADATA },
-	{ ADECB,	yincb,	Pb, 0xfe,(01) },
-	{ ADECL,	yincl,	Px, 0x48,0xff,(01) },
-	{ ADECW,	yincl,	Pe, 0x48,0xff,(01) },
-	{ ADIVB,	ydivb,	Pb, 0xf6,(06) },
-	{ ADIVL,	ydivl,	Px, 0xf7,(06) },
-	{ ADIVW,	ydivl,	Pe, 0xf7,(06) },
+	{ ADECB,	yincb,	Pb, {0xfe,(01)} },
+	{ ADECL,	yincl,	Px, {0x48,0xff,(01)} },
+	{ ADECW,	yincl,	Pe, {0x48,0xff,(01)} },
+	{ ADIVB,	ydivb,	Pb, {0xf6,(06)} },
+	{ ADIVL,	ydivl,	Px, {0xf7,(06)} },
+	{ ADIVW,	ydivl,	Pe, {0xf7,(06)} },
 	{ AENTER },				/* botch */
 	{ AGLOBL },
 	{ AGOK },
 	{ AHISTORY },
-	{ AHLT,		ynone,	Px, 0xf4 },
-	{ AIDIVB,	ydivb,	Pb, 0xf6,(07) },
-	{ AIDIVL,	ydivl,	Px, 0xf7,(07) },
-	{ AIDIVW,	ydivl,	Pe, 0xf7,(07) },
-	{ AIMULB,	ydivb,	Pb, 0xf6,(05) },
-	{ AIMULL,	yimul,	Px, 0xf7,(05),0x6b,0x69 },
-	{ AIMULW,	yimul,	Pe, 0xf7,(05),0x6b,0x69 },
-	{ AINB,		yin,	Pb, 0xe4,0xec },
-	{ AINL,		yin,	Px, 0xe5,0xed },
-	{ AINW,		yin,	Pe, 0xe5,0xed },
-	{ AINCB,	yincb,	Pb, 0xfe,(00) },
-	{ AINCL,	yincl,	Px, 0x40,0xff,(00) },
-	{ AINCW,	yincl,	Pe, 0x40,0xff,(00) },
-	{ AINSB,	ynone,	Pb, 0x6c },
-	{ AINSL,	ynone,	Px, 0x6d },
-	{ AINSW,	ynone,	Pe, 0x6d },
-	{ AINT,		yint,	Px, 0xcd },
-	{ AINTO,	ynone,	Px, 0xce },
-	{ AIRETL,	ynone,	Px, 0xcf },
-	{ AIRETW,	ynone,	Pe, 0xcf },
-	{ AJCC,		yjcond,	Px, 0x73,0x83,(00) },
-	{ AJCS,		yjcond,	Px, 0x72,0x82 },
-	{ AJCXZL,	yloop,	Px, 0xe3 },
-	{ AJCXZW,	yloop,	Px, 0xe3 },
-	{ AJEQ,		yjcond,	Px, 0x74,0x84 },
-	{ AJGE,		yjcond,	Px, 0x7d,0x8d },
-	{ AJGT,		yjcond,	Px, 0x7f,0x8f },
-	{ AJHI,		yjcond,	Px, 0x77,0x87 },
-	{ AJLE,		yjcond,	Px, 0x7e,0x8e },
-	{ AJLS,		yjcond,	Px, 0x76,0x86 },
-	{ AJLT,		yjcond,	Px, 0x7c,0x8c },
-	{ AJMI,		yjcond,	Px, 0x78,0x88 },
-	{ AJMP,		yjmp,	Px, 0xff,(04),0xeb,0xe9 },
-	{ AJNE,		yjcond,	Px, 0x75,0x85 },
-	{ AJOC,		yjcond,	Px, 0x71,0x81,(00) },
-	{ AJOS,		yjcond,	Px, 0x70,0x80,(00) },
-	{ AJPC,		yjcond,	Px, 0x7b,0x8b },
-	{ AJPL,		yjcond,	Px, 0x79,0x89 },
-	{ AJPS,		yjcond,	Px, 0x7a,0x8a },
-	{ ALAHF,	ynone,	Px, 0x9f },
-	{ ALARL,	yml_rl,	Pm, 0x02 },
-	{ ALARW,	yml_rl,	Pq, 0x02 },
-	{ ALEAL,	ym_rl,	Px, 0x8d },
-	{ ALEAW,	ym_rl,	Pe, 0x8d },
-	{ ALEAVEL,	ynone,	Px, 0xc9 },
-	{ ALEAVEW,	ynone,	Pe, 0xc9 },
-	{ ALOCK,	ynone,	Px, 0xf0 },
-	{ ALODSB,	ynone,	Pb, 0xac },
-	{ ALODSL,	ynone,	Px, 0xad },
-	{ ALODSW,	ynone,	Pe, 0xad },
-	{ ALONG,	ybyte,	Px, 4 },
-	{ ALOOP,	yloop,	Px, 0xe2 },
-	{ ALOOPEQ,	yloop,	Px, 0xe1 },
-	{ ALOOPNE,	yloop,	Px, 0xe0 },
-	{ ALSLL,	yml_rl,	Pm, 0x03  },
-	{ ALSLW,	yml_rl,	Pq, 0x03  },
-	{ AMOVB,	ymovb,	Pb, 0x88,0x8a,0xb0,0xc6,(00) },
-	{ AMOVL,	ymovl,	Px, 0x89,0x8b,0x31,0x83,(04),0xb8,0xc7,(00),Pe,0x6e,Pe,0x7e,0 },
-	{ AMOVW,	ymovw,	Pe, 0x89,0x8b,0x31,0x83,(04),0xb8,0xc7,(00),0 },
-	{ AMOVQ,	ymovq,	Pf3, 0x7e },
-	{ AMOVBLSX,	ymb_rl,	Pm, 0xbe },
-	{ AMOVBLZX,	ymb_rl,	Pm, 0xb6 },
-	{ AMOVBWSX,	ymb_rl,	Pq, 0xbe },
-	{ AMOVBWZX,	ymb_rl,	Pq, 0xb6 },
-	{ AMOVWLSX,	yml_rl,	Pm, 0xbf },
-	{ AMOVWLZX,	yml_rl,	Pm, 0xb7 },
-	{ AMOVSB,	ynone,	Pb, 0xa4 },
-	{ AMOVSL,	ynone,	Px, 0xa5 },
-	{ AMOVSW,	ynone,	Pe, 0xa5 },
-	{ AMULB,	ydivb,	Pb, 0xf6,(04) },
-	{ AMULL,	ydivl,	Px, 0xf7,(04) },
-	{ AMULW,	ydivl,	Pe, 0xf7,(04) },
+	{ AHLT,		ynone,	Px, {0xf4} },
+	{ AIDIVB,	ydivb,	Pb, {0xf6,(07)} },
+	{ AIDIVL,	ydivl,	Px, {0xf7,(07)} },
+	{ AIDIVW,	ydivl,	Pe, {0xf7,(07)} },
+	{ AIMULB,	ydivb,	Pb, {0xf6,(05)} },
+	{ AIMULL,	yimul,	Px, {0xf7,(05),0x6b,0x69} },
+	{ AIMULW,	yimul,	Pe, {0xf7,(05),0x6b,0x69} },
+	{ AINB,		yin,	Pb, {0xe4,0xec} },
+	{ AINL,		yin,	Px, {0xe5,0xed} },
+	{ AINW,		yin,	Pe, {0xe5,0xed} },
+	{ AINCB,	yincb,	Pb, {0xfe,(00)} },
+	{ AINCL,	yincl,	Px, {0x40,0xff,(00)} },
+	{ AINCW,	yincl,	Pe, {0x40,0xff,(00)} },
+	{ AINSB,	ynone,	Pb, {0x6c} },
+	{ AINSL,	ynone,	Px, {0x6d} },
+	{ AINSW,	ynone,	Pe, {0x6d} },
+	{ AINT,		yint,	Px, {0xcd} },
+	{ AINTO,	ynone,	Px, {0xce} },
+	{ AIRETL,	ynone,	Px, {0xcf} },
+	{ AIRETW,	ynone,	Pe, {0xcf} },
+	{ AJCC,		yjcond,	Px, {0x73,0x83,(00)} },
+	{ AJCS,		yjcond,	Px, {0x72,0x82} },
+	{ AJCXZL,	yloop,	Px, {0xe3} },
+	{ AJCXZW,	yloop,	Px, {0xe3} },
+	{ AJEQ,		yjcond,	Px, {0x74,0x84} },
+	{ AJGE,		yjcond,	Px, {0x7d,0x8d} },
+	{ AJGT,		yjcond,	Px, {0x7f,0x8f} },
+	{ AJHI,		yjcond,	Px, {0x77,0x87} },
+	{ AJLE,		yjcond,	Px, {0x7e,0x8e} },
+	{ AJLS,		yjcond,	Px, {0x76,0x86} },
+	{ AJLT,		yjcond,	Px, {0x7c,0x8c} },
+	{ AJMI,		yjcond,	Px, {0x78,0x88} },
+	{ AJMP,		yjmp,	Px, {0xff,(04),0xeb,0xe9} },
+	{ AJNE,		yjcond,	Px, {0x75,0x85} },
+	{ AJOC,		yjcond,	Px, {0x71,0x81,(00)} },
+	{ AJOS,		yjcond,	Px, {0x70,0x80,(00)} },
+	{ AJPC,		yjcond,	Px, {0x7b,0x8b} },
+	{ AJPL,		yjcond,	Px, {0x79,0x89} },
+	{ AJPS,		yjcond,	Px, {0x7a,0x8a} },
+	{ ALAHF,	ynone,	Px, {0x9f} },
+	{ ALARL,	yml_rl,	Pm, {0x02} },
+	{ ALARW,	yml_rl,	Pq, {0x02} },
+	{ ALEAL,	ym_rl,	Px, {0x8d} },
+	{ ALEAW,	ym_rl,	Pe, {0x8d} },
+	{ ALEAVEL,	ynone,	Px, {0xc9} },
+	{ ALEAVEW,	ynone,	Pe, {0xc9} },
+	{ ALOCK,	ynone,	Px, {0xf0} },
+	{ ALODSB,	ynone,	Pb, {0xac} },
+	{ ALODSL,	ynone,	Px, {0xad} },
+	{ ALODSW,	ynone,	Pe, {0xad} },
+	{ ALONG,	ybyte,	Px, {4} },
+	{ ALOOP,	yloop,	Px, {0xe2} },
+	{ ALOOPEQ,	yloop,	Px, {0xe1} },
+	{ ALOOPNE,	yloop,	Px, {0xe0} },
+	{ ALSLL,	yml_rl,	Pm, {0x03 } },
+	{ ALSLW,	yml_rl,	Pq, {0x03 } },
+	{ AMOVB,	ymovb,	Pb, {0x88,0x8a,0xb0,0xc6,(00)} },
+	{ AMOVL,	ymovl,	Px, {0x89,0x8b,0x31,0x83,(04),0xb8,0xc7,(00),Pe,0x6e,Pe,0x7e,0} },
+	{ AMOVW,	ymovw,	Pe, {0x89,0x8b,0x31,0x83,(04),0xb8,0xc7,(00),0} },
+	{ AMOVQ,	ymovq,	Pf3, {0x7e} },
+	{ AMOVBLSX,	ymb_rl,	Pm, {0xbe} },
+	{ AMOVBLZX,	ymb_rl,	Pm, {0xb6} },
+	{ AMOVBWSX,	ymb_rl,	Pq, {0xbe} },
+	{ AMOVBWZX,	ymb_rl,	Pq, {0xb6} },
+	{ AMOVWLSX,	yml_rl,	Pm, {0xbf} },
+	{ AMOVWLZX,	yml_rl,	Pm, {0xb7} },
+	{ AMOVSB,	ynone,	Pb, {0xa4} },
+	{ AMOVSL,	ynone,	Px, {0xa5} },
+	{ AMOVSW,	ynone,	Pe, {0xa5} },
+	{ AMULB,	ydivb,	Pb, {0xf6,(04)} },
+	{ AMULL,	ydivl,	Px, {0xf7,(04)} },
+	{ AMULW,	ydivl,	Pe, {0xf7,(04)} },
 	{ ANAME },
-	{ ANEGB,	yscond,	Px, 0xf6,(03) },
-	{ ANEGL,	yscond,	Px, 0xf7,(03) },
-	{ ANEGW,	yscond,	Pe, 0xf7,(03) },
-	{ ANOP,		ynop,	Px,0,0 },
-	{ ANOTB,	yscond,	Px, 0xf6,(02) },
-	{ ANOTL,	yscond,	Px, 0xf7,(02) },
-	{ ANOTW,	yscond,	Pe, 0xf7,(02) },
-	{ AORB,		yxorb,	Pb, 0x0c,0x80,(01),0x08,0x0a },
-	{ AORL,		yxorl,	Px, 0x83,(01),0x0d,0x81,(01),0x09,0x0b },
-	{ AORW,		yxorl,	Pe, 0x83,(01),0x0d,0x81,(01),0x09,0x0b },
-	{ AOUTB,	yin,	Pb, 0xe6,0xee },
-	{ AOUTL,	yin,	Px, 0xe7,0xef },
-	{ AOUTW,	yin,	Pe, 0xe7,0xef },
-	{ AOUTSB,	ynone,	Pb, 0x6e },
-	{ AOUTSL,	ynone,	Px, 0x6f },
-	{ AOUTSW,	ynone,	Pe, 0x6f },
-	{ APAUSE,	ynone,	Px, 0xf3,0x90 },
-	{ APOPAL,	ynone,	Px, 0x61 },
-	{ APOPAW,	ynone,	Pe, 0x61 },
-	{ APOPFL,	ynone,	Px, 0x9d },
-	{ APOPFW,	ynone,	Pe, 0x9d },
-	{ APOPL,	ypopl,	Px, 0x58,0x8f,(00) },
-	{ APOPW,	ypopl,	Pe, 0x58,0x8f,(00) },
-	{ APUSHAL,	ynone,	Px, 0x60 },
-	{ APUSHAW,	ynone,	Pe, 0x60 },
-	{ APUSHFL,	ynone,	Px, 0x9c },
-	{ APUSHFW,	ynone,	Pe, 0x9c },
-	{ APUSHL,	ypushl,	Px, 0x50,0xff,(06),0x6a,0x68 },
-	{ APUSHW,	ypushl,	Pe, 0x50,0xff,(06),0x6a,0x68 },
-	{ ARCLB,	yshb,	Pb, 0xd0,(02),0xc0,(02),0xd2,(02) },
-	{ ARCLL,	yshl,	Px, 0xd1,(02),0xc1,(02),0xd3,(02),0xd3,(02) },
-	{ ARCLW,	yshl,	Pe, 0xd1,(02),0xc1,(02),0xd3,(02),0xd3,(02) },
-	{ ARCRB,	yshb,	Pb, 0xd0,(03),0xc0,(03),0xd2,(03) },
-	{ ARCRL,	yshl,	Px, 0xd1,(03),0xc1,(03),0xd3,(03),0xd3,(03) },
-	{ ARCRW,	yshl,	Pe, 0xd1,(03),0xc1,(03),0xd3,(03),0xd3,(03) },
-	{ AREP,		ynone,	Px, 0xf3 },
-	{ AREPN,	ynone,	Px, 0xf2 },
-	{ ARET,		ynone,	Px, 0xc3 },
-	{ AROLB,	yshb,	Pb, 0xd0,(00),0xc0,(00),0xd2,(00) },
-	{ AROLL,	yshl,	Px, 0xd1,(00),0xc1,(00),0xd3,(00),0xd3,(00) },
-	{ AROLW,	yshl,	Pe, 0xd1,(00),0xc1,(00),0xd3,(00),0xd3,(00) },
-	{ ARORB,	yshb,	Pb, 0xd0,(01),0xc0,(01),0xd2,(01) },
-	{ ARORL,	yshl,	Px, 0xd1,(01),0xc1,(01),0xd3,(01),0xd3,(01) },
-	{ ARORW,	yshl,	Pe, 0xd1,(01),0xc1,(01),0xd3,(01),0xd3,(01) },
-	{ ASAHF,	ynone,	Px, 0x9e },
-	{ ASALB,	yshb,	Pb, 0xd0,(04),0xc0,(04),0xd2,(04) },
-	{ ASALL,	yshl,	Px, 0xd1,(04),0xc1,(04),0xd3,(04),0xd3,(04) },
-	{ ASALW,	yshl,	Pe, 0xd1,(04),0xc1,(04),0xd3,(04),0xd3,(04) },
-	{ ASARB,	yshb,	Pb, 0xd0,(07),0xc0,(07),0xd2,(07) },
-	{ ASARL,	yshl,	Px, 0xd1,(07),0xc1,(07),0xd3,(07),0xd3,(07) },
-	{ ASARW,	yshl,	Pe, 0xd1,(07),0xc1,(07),0xd3,(07),0xd3,(07) },
-	{ ASBBB,	yxorb,	Pb, 0x1c,0x80,(03),0x18,0x1a },
-	{ ASBBL,	yxorl,	Px, 0x83,(03),0x1d,0x81,(03),0x19,0x1b },
-	{ ASBBW,	yxorl,	Pe, 0x83,(03),0x1d,0x81,(03),0x19,0x1b },
-	{ ASCASB,	ynone,	Pb, 0xae },
-	{ ASCASL,	ynone,	Px, 0xaf },
-	{ ASCASW,	ynone,	Pe, 0xaf },
-	{ ASETCC,	yscond,	Pm, 0x93,(00) },
-	{ ASETCS,	yscond,	Pm, 0x92,(00) },
-	{ ASETEQ,	yscond,	Pm, 0x94,(00) },
-	{ ASETGE,	yscond,	Pm, 0x9d,(00) },
-	{ ASETGT,	yscond,	Pm, 0x9f,(00) },
-	{ ASETHI,	yscond,	Pm, 0x97,(00) },
-	{ ASETLE,	yscond,	Pm, 0x9e,(00) },
-	{ ASETLS,	yscond,	Pm, 0x96,(00) },
-	{ ASETLT,	yscond,	Pm, 0x9c,(00) },
-	{ ASETMI,	yscond,	Pm, 0x98,(00) },
-	{ ASETNE,	yscond,	Pm, 0x95,(00) },
-	{ ASETOC,	yscond,	Pm, 0x91,(00) },
-	{ ASETOS,	yscond,	Pm, 0x90,(00) },
-	{ ASETPC,	yscond,	Pm, 0x96,(00) },
-	{ ASETPL,	yscond,	Pm, 0x99,(00) },
-	{ ASETPS,	yscond,	Pm, 0x9a,(00) },
-	{ ACDQ,		ynone,	Px, 0x99 },
-	{ ACWD,		ynone,	Pe, 0x99 },
-	{ ASHLB,	yshb,	Pb, 0xd0,(04),0xc0,(04),0xd2,(04) },
-	{ ASHLL,	yshl,	Px, 0xd1,(04),0xc1,(04),0xd3,(04),0xd3,(04) },
-	{ ASHLW,	yshl,	Pe, 0xd1,(04),0xc1,(04),0xd3,(04),0xd3,(04) },
-	{ ASHRB,	yshb,	Pb, 0xd0,(05),0xc0,(05),0xd2,(05) },
-	{ ASHRL,	yshl,	Px, 0xd1,(05),0xc1,(05),0xd3,(05),0xd3,(05) },
-	{ ASHRW,	yshl,	Pe, 0xd1,(05),0xc1,(05),0xd3,(05),0xd3,(05) },
-	{ ASTC,		ynone,	Px, 0xf9 },
-	{ ASTD,		ynone,	Px, 0xfd },
-	{ ASTI,		ynone,	Px, 0xfb },
-	{ ASTOSB,	ynone,	Pb, 0xaa },
-	{ ASTOSL,	ynone,	Px, 0xab },
-	{ ASTOSW,	ynone,	Pe, 0xab },
-	{ ASUBB,	yxorb,	Pb, 0x2c,0x80,(05),0x28,0x2a },
-	{ ASUBL,	yaddl,	Px, 0x83,(05),0x2d,0x81,(05),0x29,0x2b },
-	{ ASUBW,	yaddl,	Pe, 0x83,(05),0x2d,0x81,(05),0x29,0x2b },
-	{ ASYSCALL,	ynone,	Px, 0xcd,100 },
-	{ ATESTB,	ytestb,	Pb, 0xa8,0xf6,(00),0x84,0x84 },
-	{ ATESTL,	ytestl,	Px, 0xa9,0xf7,(00),0x85,0x85 },
-	{ ATESTW,	ytestl,	Pe, 0xa9,0xf7,(00),0x85,0x85 },
+	{ ANEGB,	yscond,	Px, {0xf6,(03)} },
+	{ ANEGL,	yscond,	Px, {0xf7,(03)} },
+	{ ANEGW,	yscond,	Pe, {0xf7,(03)} },
+	{ ANOP,		ynop,	Px, {0,0} },
+	{ ANOTB,	yscond,	Px, {0xf6,(02)} },
+	{ ANOTL,	yscond,	Px, {0xf7,(02)} },
+	{ ANOTW,	yscond,	Pe, {0xf7,(02)} },
+	{ AORB,		yxorb,	Pb, {0x0c,0x80,(01),0x08,0x0a} },
+	{ AORL,		yxorl,	Px, {0x83,(01),0x0d,0x81,(01),0x09,0x0b} },
+	{ AORW,		yxorl,	Pe, {0x83,(01),0x0d,0x81,(01),0x09,0x0b} },
+	{ AOUTB,	yin,	Pb, {0xe6,0xee} },
+	{ AOUTL,	yin,	Px, {0xe7,0xef} },
+	{ AOUTW,	yin,	Pe, {0xe7,0xef} },
+	{ AOUTSB,	ynone,	Pb, {0x6e} },
+	{ AOUTSL,	ynone,	Px, {0x6f} },
+	{ AOUTSW,	ynone,	Pe, {0x6f} },
+	{ APAUSE,	ynone,	Px, {0xf3,0x90} },
+	{ APOPAL,	ynone,	Px, {0x61} },
+	{ APOPAW,	ynone,	Pe, {0x61} },
+	{ APOPFL,	ynone,	Px, {0x9d} },
+	{ APOPFW,	ynone,	Pe, {0x9d} },
+	{ APOPL,	ypopl,	Px, {0x58,0x8f,(00)} },
+	{ APOPW,	ypopl,	Pe, {0x58,0x8f,(00)} },
+	{ APUSHAL,	ynone,	Px, {0x60} },
+	{ APUSHAW,	ynone,	Pe, {0x60} },
+	{ APUSHFL,	ynone,	Px, {0x9c} },
+	{ APUSHFW,	ynone,	Pe, {0x9c} },
+	{ APUSHL,	ypushl,	Px, {0x50,0xff,(06),0x6a,0x68} },
+	{ APUSHW,	ypushl,	Pe, {0x50,0xff,(06),0x6a,0x68} },
+	{ ARCLB,	yshb,	Pb, {0xd0,(02),0xc0,(02),0xd2,(02)} },
+	{ ARCLL,	yshl,	Px, {0xd1,(02),0xc1,(02),0xd3,(02),0xd3,(02)} },
+	{ ARCLW,	yshl,	Pe, {0xd1,(02),0xc1,(02),0xd3,(02),0xd3,(02)} },
+	{ ARCRB,	yshb,	Pb, {0xd0,(03),0xc0,(03),0xd2,(03)} },
+	{ ARCRL,	yshl,	Px, {0xd1,(03),0xc1,(03),0xd3,(03),0xd3,(03)} },
+	{ ARCRW,	yshl,	Pe, {0xd1,(03),0xc1,(03),0xd3,(03),0xd3,(03)} },
+	{ AREP,		ynone,	Px, {0xf3} },
+	{ AREPN,	ynone,	Px, {0xf2} },
+	{ ARET,		ynone,	Px, {0xc3} },
+	{ AROLB,	yshb,	Pb, {0xd0,(00),0xc0,(00),0xd2,(00)} },
+	{ AROLL,	yshl,	Px, {0xd1,(00),0xc1,(00),0xd3,(00),0xd3,(00)} },
+	{ AROLW,	yshl,	Pe, {0xd1,(00),0xc1,(00),0xd3,(00),0xd3,(00)} },
+	{ ARORB,	yshb,	Pb, {0xd0,(01),0xc0,(01),0xd2,(01)} },
+	{ ARORL,	yshl,	Px, {0xd1,(01),0xc1,(01),0xd3,(01),0xd3,(01)} },
+	{ ARORW,	yshl,	Pe, {0xd1,(01),0xc1,(01),0xd3,(01),0xd3,(01)} },
+	{ ASAHF,	ynone,	Px, {0x9e} },
+	{ ASALB,	yshb,	Pb, {0xd0,(04),0xc0,(04),0xd2,(04)} },
+	{ ASALL,	yshl,	Px, {0xd1,(04),0xc1,(04),0xd3,(04),0xd3,(04)} },
+	{ ASALW,	yshl,	Pe, {0xd1,(04),0xc1,(04),0xd3,(04),0xd3,(04)} },
+	{ ASARB,	yshb,	Pb, {0xd0,(07),0xc0,(07),0xd2,(07)} },
+	{ ASARL,	yshl,	Px, {0xd1,(07),0xc1,(07),0xd3,(07),0xd3,(07)} },
+	{ ASARW,	yshl,	Pe, {0xd1,(07),0xc1,(07),0xd3,(07),0xd3,(07)} },
+	{ ASBBB,	yxorb,	Pb, {0x1c,0x80,(03),0x18,0x1a} },
+	{ ASBBL,	yxorl,	Px, {0x83,(03),0x1d,0x81,(03),0x19,0x1b} },
+	{ ASBBW,	yxorl,	Pe, {0x83,(03),0x1d,0x81,(03),0x19,0x1b} },
+	{ ASCASB,	ynone,	Pb, {0xae} },
+	{ ASCASL,	ynone,	Px, {0xaf} },
+	{ ASCASW,	ynone,	Pe, {0xaf} },
+	{ ASETCC,	yscond,	Pm, {0x93,(00)} },
+	{ ASETCS,	yscond,	Pm, {0x92,(00)} },
+	{ ASETEQ,	yscond,	Pm, {0x94,(00)} },
+	{ ASETGE,	yscond,	Pm, {0x9d,(00)} },
+	{ ASETGT,	yscond,	Pm, {0x9f,(00)} },
+	{ ASETHI,	yscond,	Pm, {0x97,(00)} },
+	{ ASETLE,	yscond,	Pm, {0x9e,(00)} },
+	{ ASETLS,	yscond,	Pm, {0x96,(00)} },
+	{ ASETLT,	yscond,	Pm, {0x9c,(00)} },
+	{ ASETMI,	yscond,	Pm, {0x98,(00)} },
+	{ ASETNE,	yscond,	Pm, {0x95,(00)} },
+	{ ASETOC,	yscond,	Pm, {0x91,(00)} },
+	{ ASETOS,	yscond,	Pm, {0x90,(00)} },
+	{ ASETPC,	yscond,	Pm, {0x9b,(00)} },
+	{ ASETPL,	yscond,	Pm, {0x99,(00)} },
+	{ ASETPS,	yscond,	Pm, {0x9a,(00)} },
+	{ ACDQ,		ynone,	Px, {0x99} },
+	{ ACWD,		ynone,	Pe, {0x99} },
+	{ ASHLB,	yshb,	Pb, {0xd0,(04),0xc0,(04),0xd2,(04)} },
+	{ ASHLL,	yshl,	Px, {0xd1,(04),0xc1,(04),0xd3,(04),0xd3,(04)} },
+	{ ASHLW,	yshl,	Pe, {0xd1,(04),0xc1,(04),0xd3,(04),0xd3,(04)} },
+	{ ASHRB,	yshb,	Pb, {0xd0,(05),0xc0,(05),0xd2,(05)} },
+	{ ASHRL,	yshl,	Px, {0xd1,(05),0xc1,(05),0xd3,(05),0xd3,(05)} },
+	{ ASHRW,	yshl,	Pe, {0xd1,(05),0xc1,(05),0xd3,(05),0xd3,(05)} },
+	{ ASTC,		ynone,	Px, {0xf9} },
+	{ ASTD,		ynone,	Px, {0xfd} },
+	{ ASTI,		ynone,	Px, {0xfb} },
+	{ ASTOSB,	ynone,	Pb, {0xaa} },
+	{ ASTOSL,	ynone,	Px, {0xab} },
+	{ ASTOSW,	ynone,	Pe, {0xab} },
+	{ ASUBB,	yxorb,	Pb, {0x2c,0x80,(05),0x28,0x2a} },
+	{ ASUBL,	yaddl,	Px, {0x83,(05),0x2d,0x81,(05),0x29,0x2b} },
+	{ ASUBW,	yaddl,	Pe, {0x83,(05),0x2d,0x81,(05),0x29,0x2b} },
+	{ ASYSCALL,	ynone,	Px, {0xcd,100} },
+	{ ATESTB,	ytestb,	Pb, {0xa8,0xf6,(00),0x84,0x84} },
+	{ ATESTL,	ytestl,	Px, {0xa9,0xf7,(00),0x85,0x85} },
+	{ ATESTW,	ytestl,	Pe, {0xa9,0xf7,(00),0x85,0x85} },
 	{ ATEXT,	ytext,	Px },
-	{ AVERR,	ydivl,	Pm, 0x00,(04) },
-	{ AVERW,	ydivl,	Pm, 0x00,(05) },
-	{ AWAIT,	ynone,	Px, 0x9b },
-	{ AWORD,	ybyte,	Px, 2 },
-	{ AXCHGB,	yml_mb,	Pb, 0x86,0x86 },
-	{ AXCHGL,	yxchg,	Px, 0x90,0x90,0x87,0x87 },
-	{ AXCHGW,	yxchg,	Pe, 0x90,0x90,0x87,0x87 },
-	{ AXLAT,	ynone,	Px, 0xd7 },
-	{ AXORB,	yxorb,	Pb, 0x34,0x80,(06),0x30,0x32 },
-	{ AXORL,	yxorl,	Px, 0x83,(06),0x35,0x81,(06),0x31,0x33 },
-	{ AXORW,	yxorl,	Pe, 0x83,(06),0x35,0x81,(06),0x31,0x33 },
-
-	{ AFMOVB,	yfmvx,	Px, 0xdf,(04) },
-	{ AFMOVBP,	yfmvp,	Px, 0xdf,(06) },
-	{ AFMOVD,	yfmvd,	Px, 0xdd,(00),0xdd,(02),0xd9,(00),0xdd,(02) },
-	{ AFMOVDP,	yfmvdp,	Px, 0xdd,(03),0xdd,(03) },
-	{ AFMOVF,	yfmvf,	Px, 0xd9,(00),0xd9,(02) },
-	{ AFMOVFP,	yfmvp,	Px, 0xd9,(03) },
-	{ AFMOVL,	yfmvf,	Px, 0xdb,(00),0xdb,(02) },
-	{ AFMOVLP,	yfmvp,	Px, 0xdb,(03) },
-	{ AFMOVV,	yfmvx,	Px, 0xdf,(05) },
-	{ AFMOVVP,	yfmvp,	Px, 0xdf,(07) },
-	{ AFMOVW,	yfmvf,	Px, 0xdf,(00),0xdf,(02) },
-	{ AFMOVWP,	yfmvp,	Px, 0xdf,(03) },
-	{ AFMOVX,	yfmvx,	Px, 0xdb,(05) },
-	{ AFMOVXP,	yfmvp,	Px, 0xdb,(07) },
+	{ AVERR,	ydivl,	Pm, {0x00,(04)} },
+	{ AVERW,	ydivl,	Pm, {0x00,(05)} },
+	{ AWAIT,	ynone,	Px, {0x9b} },
+	{ AWORD,	ybyte,	Px, {2} },
+	{ AXCHGB,	yml_mb,	Pb, {0x86,0x86} },
+	{ AXCHGL,	yxchg,	Px, {0x90,0x90,0x87,0x87} },
+	{ AXCHGW,	yxchg,	Pe, {0x90,0x90,0x87,0x87} },
+	{ AXLAT,	ynone,	Px, {0xd7} },
+	{ AXORB,	yxorb,	Pb, {0x34,0x80,(06),0x30,0x32} },
+	{ AXORL,	yxorl,	Px, {0x83,(06),0x35,0x81,(06),0x31,0x33} },
+	{ AXORW,	yxorl,	Pe, {0x83,(06),0x35,0x81,(06),0x31,0x33} },
+
+	{ AFMOVB,	yfmvx,	Px, {0xdf,(04)} },
+	{ AFMOVBP,	yfmvp,	Px, {0xdf,(06)} },
+	{ AFMOVD,	yfmvd,	Px, {0xdd,(00),0xdd,(02),0xd9,(00),0xdd,(02)} },
+	{ AFMOVDP,	yfmvdp,	Px, {0xdd,(03),0xdd,(03)} },
+	{ AFMOVF,	yfmvf,	Px, {0xd9,(00),0xd9,(02)} },
+	{ AFMOVFP,	yfmvp,	Px, {0xd9,(03)} },
+	{ AFMOVL,	yfmvf,	Px, {0xdb,(00),0xdb,(02)} },
+	{ AFMOVLP,	yfmvp,	Px, {0xdb,(03)} },
+	{ AFMOVV,	yfmvx,	Px, {0xdf,(05)} },
+	{ AFMOVVP,	yfmvp,	Px, {0xdf,(07)} },
+	{ AFMOVW,	yfmvf,	Px, {0xdf,(00),0xdf,(02)} },
+	{ AFMOVWP,	yfmvp,	Px, {0xdf,(03)} },
+	{ AFMOVX,	yfmvx,	Px, {0xdb,(05)} },
+	{ AFMOVXP,	yfmvp,	Px, {0xdb,(07)} },
 
 	{ AFCOMB },
 	{ AFCOMBP },
-	{ AFCOMD,	yfadd,	Px, 0xdc,(02),0xd8,(02),0xdc,(02) },	/* botch */
-	{ AFCOMDP,	yfadd,	Px, 0xdc,(03),0xd8,(03),0xdc,(03) },	/* botch */
-	{ AFCOMDPP,	ycompp,	Px, 0xde,(03) },
-	{ AFCOMF,	yfmvx,	Px, 0xd8,(02) },
-	{ AFCOMFP,	yfmvx,	Px, 0xd8,(03) },
-	{ AFCOMI,	yfmvx,	Px, 0xdb,(06) },
-	{ AFCOMIP,	yfmvx,	Px, 0xdf,(06) },
-	{ AFCOML,	yfmvx,	Px, 0xda,(02) },
-	{ AFCOMLP,	yfmvx,	Px, 0xda,(03) },
-	{ AFCOMW,	yfmvx,	Px, 0xde,(02) },
-	{ AFCOMWP,	yfmvx,	Px, 0xde,(03) },
-
-	{ AFUCOM,	ycompp,	Px, 0xdd,(04) },
-	{ AFUCOMI,	ycompp,	Px, 0xdb,(05) },
-	{ AFUCOMIP,	ycompp,	Px, 0xdf,(05) },
-	{ AFUCOMP,	ycompp,	Px, 0xdd,(05) },
-	{ AFUCOMPP,	ycompp,	Px, 0xda,(13) },
-
-	{ AFADDDP,	yfaddp,	Px, 0xde,(00) },
-	{ AFADDW,	yfmvx,	Px, 0xde,(00) },
-	{ AFADDL,	yfmvx,	Px, 0xda,(00) },
-	{ AFADDF,	yfmvx,	Px, 0xd8,(00) },
-	{ AFADDD,	yfadd,	Px, 0xdc,(00),0xd8,(00),0xdc,(00) },
-
-	{ AFMULDP,	yfaddp,	Px, 0xde,(01) },
-	{ AFMULW,	yfmvx,	Px, 0xde,(01) },
-	{ AFMULL,	yfmvx,	Px, 0xda,(01) },
-	{ AFMULF,	yfmvx,	Px, 0xd8,(01) },
-	{ AFMULD,	yfadd,	Px, 0xdc,(01),0xd8,(01),0xdc,(01) },
-
-	{ AFSUBDP,	yfaddp,	Px, 0xde,(05) },
-	{ AFSUBW,	yfmvx,	Px, 0xde,(04) },
-	{ AFSUBL,	yfmvx,	Px, 0xda,(04) },
-	{ AFSUBF,	yfmvx,	Px, 0xd8,(04) },
-	{ AFSUBD,	yfadd,	Px, 0xdc,(04),0xd8,(04),0xdc,(05) },
-
-	{ AFSUBRDP,	yfaddp,	Px, 0xde,(04) },
-	{ AFSUBRW,	yfmvx,	Px, 0xde,(05) },
-	{ AFSUBRL,	yfmvx,	Px, 0xda,(05) },
-	{ AFSUBRF,	yfmvx,	Px, 0xd8,(05) },
-	{ AFSUBRD,	yfadd,	Px, 0xdc,(05),0xd8,(05),0xdc,(04) },
-
-	{ AFDIVDP,	yfaddp,	Px, 0xde,(07) },
-	{ AFDIVW,	yfmvx,	Px, 0xde,(06) },
-	{ AFDIVL,	yfmvx,	Px, 0xda,(06) },
-	{ AFDIVF,	yfmvx,	Px, 0xd8,(06) },
-	{ AFDIVD,	yfadd,	Px, 0xdc,(06),0xd8,(06),0xdc,(07) },
-
-	{ AFDIVRDP,	yfaddp,	Px, 0xde,(06) },
-	{ AFDIVRW,	yfmvx,	Px, 0xde,(07) },
-	{ AFDIVRL,	yfmvx,	Px, 0xda,(07) },
-	{ AFDIVRF,	yfmvx,	Px, 0xd8,(07) },
-	{ AFDIVRD,	yfadd,	Px, 0xdc,(07),0xd8,(07),0xdc,(06) },
-
-	{ AFXCHD,	yfxch,	Px, 0xd9,(01),0xd9,(01) },
+	{ AFCOMD,	yfadd,	Px, {0xdc,(02),0xd8,(02),0xdc,(02)} },	/* botch */
+	{ AFCOMDP,	yfadd,	Px, {0xdc,(03),0xd8,(03),0xdc,(03)} },	/* botch */
+	{ AFCOMDPP,	ycompp,	Px, {0xde,(03)} },
+	{ AFCOMF,	yfmvx,	Px, {0xd8,(02)} },
+	{ AFCOMFP,	yfmvx,	Px, {0xd8,(03)} },
+	{ AFCOMI,	yfmvx,	Px, {0xdb,(06)} },
+	{ AFCOMIP,	yfmvx,	Px, {0xdf,(06)} },
+	{ AFCOML,	yfmvx,	Px, {0xda,(02)} },
+	{ AFCOMLP,	yfmvx,	Px, {0xda,(03)} },
+	{ AFCOMW,	yfmvx,	Px, {0xde,(02)} },
+	{ AFCOMWP,	yfmvx,	Px, {0xde,(03)} },
+
+	{ AFUCOM,	ycompp,	Px, {0xdd,(04)} },
+	{ AFUCOMI,	ycompp,	Px, {0xdb,(05)} },
+	{ AFUCOMIP,	ycompp,	Px, {0xdf,(05)} },
+	{ AFUCOMP,	ycompp,	Px, {0xdd,(05)} },
+	{ AFUCOMPP,	ycompp,	Px, {0xda,(13)} },
+
+	{ AFADDDP,	yfaddp,	Px, {0xde,(00)} },
+	{ AFADDW,	yfmvx,	Px, {0xde,(00)} },
+	{ AFADDL,	yfmvx,	Px, {0xda,(00)} },
+	{ AFADDF,	yfmvx,	Px, {0xd8,(00)} },
+	{ AFADDD,	yfadd,	Px, {0xdc,(00),0xd8,(00),0xdc,(00)} },
+
+	{ AFMULDP,	yfaddp,	Px, {0xde,(01)} },
+	{ AFMULW,	yfmvx,	Px, {0xde,(01)} },
+	{ AFMULL,	yfmvx,	Px, {0xda,(01)} },
+	{ AFMULF,	yfmvx,	Px, {0xd8,(01)} },
+	{ AFMULD,	yfadd,	Px, {0xdc,(01),0xd8,(01),0xdc,(01)} },
+
+	{ AFSUBDP,	yfaddp,	Px, {0xde,(05)} },
+	{ AFSUBW,	yfmvx,	Px, {0xde,(04)} },
+	{ AFSUBL,	yfmvx,	Px, {0xda,(04)} },
+	{ AFSUBF,	yfmvx,	Px, {0xd8,(04)} },
+	{ AFSUBD,	yfadd,	Px, {0xdc,(04),0xd8,(04),0xdc,(05)} },
+
+	{ AFSUBRDP,	yfaddp,	Px, {0xde,(04)} },
+	{ AFSUBRW,	yfmvx,	Px, {0xde,(05)} },
+	{ AFSUBRL,	yfmvx,	Px, {0xda,(05)} },
+	{ AFSUBRF,	yfmvx,	Px, {0xd8,(05)} },
+	{ AFSUBRD,	yfadd,	Px, {0xdc,(05),0xd8,(05),0xdc,(04)} },
+
+	{ AFDIVDP,	yfaddp,	Px, {0xde,(07)} },
+	{ AFDIVW,	yfmvx,	Px, {0xde,(06)} },
+	{ AFDIVL,	yfmvx,	Px, {0xda,(06)} },
+	{ AFDIVF,	yfmvx,	Px, {0xd8,(06)} },
+	{ AFDIVD,	yfadd,	Px, {0xdc,(06),0xd8,(06),0xdc,(07)} },
+
+	{ AFDIVRDP,	yfaddp,	Px, {0xde,(06)} },
+	{ AFDIVRW,	yfmvx,	Px, {0xde,(07)} },
+	{ AFDIVRL,	yfmvx,	Px, {0xda,(07)} },
+	{ AFDIVRF,	yfmvx,	Px, {0xd8,(07)} },
+	{ AFDIVRD,	yfadd,	Px, {0xdc,(07),0xd8,(07),0xdc,(06)} },
+
+	{ AFXCHD,	yfxch,	Px, {0xd9,(01),0xd9,(01)} },
 	{ AFFREE },
-	{ AFLDCW,	ystcw,	Px, 0xd9,(05),0xd9,(05) },
-	{ AFLDENV,	ystcw,	Px, 0xd9,(04),0xd9,(04) },
-	{ AFRSTOR,	ysvrs,	Px, 0xdd,(04),0xdd,(04) },
-	{ AFSAVE,	ysvrs,	Px, 0xdd,(06),0xdd,(06) },
-	{ AFSTCW,	ystcw,	Px, 0xd9,(07),0xd9,(07) },
-	{ AFSTENV,	ystcw,	Px, 0xd9,(06),0xd9,(06) },
-	{ AFSTSW,	ystsw,	Px, 0xdd,(07),0xdf,0xe0 },
-	{ AF2XM1,	ynone,	Px, 0xd9, 0xf0 },
-	{ AFABS,	ynone,	Px, 0xd9, 0xe1 },
-	{ AFCHS,	ynone,	Px, 0xd9, 0xe0 },
-	{ AFCLEX,	ynone,	Px, 0xdb, 0xe2 },
-	{ AFCOS,	ynone,	Px, 0xd9, 0xff },
-	{ AFDECSTP,	ynone,	Px, 0xd9, 0xf6 },
-	{ AFINCSTP,	ynone,	Px, 0xd9, 0xf7 },
-	{ AFINIT,	ynone,	Px, 0xdb, 0xe3 },
-	{ AFLD1,	ynone,	Px, 0xd9, 0xe8 },
-	{ AFLDL2E,	ynone,	Px, 0xd9, 0xea },
-	{ AFLDL2T,	ynone,	Px, 0xd9, 0xe9 },
-	{ AFLDLG2,	ynone,	Px, 0xd9, 0xec },
-	{ AFLDLN2,	ynone,	Px, 0xd9, 0xed },
-	{ AFLDPI,	ynone,	Px, 0xd9, 0xeb },
-	{ AFLDZ,	ynone,	Px, 0xd9, 0xee },
-	{ AFNOP,	ynone,	Px, 0xd9, 0xd0 },
-	{ AFPATAN,	ynone,	Px, 0xd9, 0xf3 },
-	{ AFPREM,	ynone,	Px, 0xd9, 0xf8 },
-	{ AFPREM1,	ynone,	Px, 0xd9, 0xf5 },
-	{ AFPTAN,	ynone,	Px, 0xd9, 0xf2 },
-	{ AFRNDINT,	ynone,	Px, 0xd9, 0xfc },
-	{ AFSCALE,	ynone,	Px, 0xd9, 0xfd },
-	{ AFSIN,	ynone,	Px, 0xd9, 0xfe },
-	{ AFSINCOS,	ynone,	Px, 0xd9, 0xfb },
-	{ AFSQRT,	ynone,	Px, 0xd9, 0xfa },
-	{ AFTST,	ynone,	Px, 0xd9, 0xe4 },
-	{ AFXAM,	ynone,	Px, 0xd9, 0xe5 },
-	{ AFXTRACT,	ynone,	Px, 0xd9, 0xf4 },
-	{ AFYL2X,	ynone,	Px, 0xd9, 0xf1 },
-	{ AFYL2XP1,	ynone,	Px, 0xd9, 0xf9 },
+	{ AFLDCW,	ystcw,	Px, {0xd9,(05),0xd9,(05)} },
+	{ AFLDENV,	ystcw,	Px, {0xd9,(04),0xd9,(04)} },
+	{ AFRSTOR,	ysvrs,	Px, {0xdd,(04),0xdd,(04)} },
+	{ AFSAVE,	ysvrs,	Px, {0xdd,(06),0xdd,(06)} },
+	{ AFSTCW,	ystcw,	Px, {0xd9,(07),0xd9,(07)} },
+	{ AFSTENV,	ystcw,	Px, {0xd9,(06),0xd9,(06)} },
+	{ AFSTSW,	ystsw,	Px, {0xdd,(07),0xdf,0xe0} },
+	{ AF2XM1,	ynone,	Px, {0xd9, 0xf0} },
+	{ AFABS,	ynone,	Px, {0xd9, 0xe1} },
+	{ AFCHS,	ynone,	Px, {0xd9, 0xe0} },
+	{ AFCLEX,	ynone,	Px, {0xdb, 0xe2} },
+	{ AFCOS,	ynone,	Px, {0xd9, 0xff} },
+	{ AFDECSTP,	ynone,	Px, {0xd9, 0xf6} },
+	{ AFINCSTP,	ynone,	Px, {0xd9, 0xf7} },
+	{ AFINIT,	ynone,	Px, {0xdb, 0xe3} },
+	{ AFLD1,	ynone,	Px, {0xd9, 0xe8} },
+	{ AFLDL2E,	ynone,	Px, {0xd9, 0xea} },
+	{ AFLDL2T,	ynone,	Px, {0xd9, 0xe9} },
+	{ AFLDLG2,	ynone,	Px, {0xd9, 0xec} },
+	{ AFLDLN2,	ynone,	Px, {0xd9, 0xed} },
+	{ AFLDPI,	ynone,	Px, {0xd9, 0xeb} },
+	{ AFLDZ,	ynone,	Px, {0xd9, 0xee} },
+	{ AFNOP,	ynone,	Px, {0xd9, 0xd0} },
+	{ AFPATAN,	ynone,	Px, {0xd9, 0xf3} },
+	{ AFPREM,	ynone,	Px, {0xd9, 0xf8} },
+	{ AFPREM1,	ynone,	Px, {0xd9, 0xf5} },
+	{ AFPTAN,	ynone,	Px, {0xd9, 0xf2} },
+	{ AFRNDINT,	ynone,	Px, {0xd9, 0xfc} },
+	{ AFSCALE,	ynone,	Px, {0xd9, 0xfd} },
+	{ AFSIN,	ynone,	Px, {0xd9, 0xfe} },
+	{ AFSINCOS,	ynone,	Px, {0xd9, 0xfb} },
+	{ AFSQRT,	ynone,	Px, {0xd9, 0xfa} },
+	{ AFTST,	ynone,	Px, {0xd9, 0xe4} },
+	{ AFXAM,	ynone,	Px, {0xd9, 0xe5} },
+	{ AFXTRACT,	ynone,	Px, {0xd9, 0xf4} },
+	{ AFYL2X,	ynone,	Px, {0xd9, 0xf1} },
+	{ AFYL2XP1,	ynone,	Px, {0xd9, 0xf9} },
 	{ AEND },
 	{ ADYNT_ },
 	{ AINIT_ },
 	{ ASIGNAME },
-	{ ACMPXCHGB,	yrb_mb,	Pm, 0xb0 },
-	{ ACMPXCHGL,	yrl_ml,	Pm, 0xb1 },
-	{ ACMPXCHGW,	yrl_ml,	Pm, 0xb1 },
-	{ ACMPXCHG8B,	yscond,	Pm, 0xc7,(01) },
-
-	{ ACPUID,	ynone,	Pm, 0xa2 },
-	{ ARDTSC,	ynone,	Pm, 0x31 },
-
-	{ AXADDB,	yrb_mb,	Pb, 0x0f,0xc0 },
-	{ AXADDL,	yrl_ml,	Pm, 0xc1 },
-	{ AXADDW,	yrl_ml,	Pe, 0x0f,0xc1 },
-
-	{ ACMOVLCC,	yml_rl,	Pm, 0x43 },
-	{ ACMOVLCS,	yml_rl,	Pm, 0x42 },
-	{ ACMOVLEQ,	yml_rl,	Pm, 0x44 },
-	{ ACMOVLGE,	yml_rl,	Pm, 0x4d },
-	{ ACMOVLGT,	yml_rl,	Pm, 0x4f },
-	{ ACMOVLHI,	yml_rl,	Pm, 0x47 },
-	{ ACMOVLLE,	yml_rl,	Pm, 0x4e },
-	{ ACMOVLLS,	yml_rl,	Pm, 0x46 },
-	{ ACMOVLLT,	yml_rl,	Pm, 0x4c },
-	{ ACMOVLMI,	yml_rl,	Pm, 0x48 },
-	{ ACMOVLNE,	yml_rl,	Pm, 0x45 },
-	{ ACMOVLOC,	yml_rl,	Pm, 0x41 },
-	{ ACMOVLOS,	yml_rl,	Pm, 0x40 },
-	{ ACMOVLPC,	yml_rl,	Pm, 0x4b },
-	{ ACMOVLPL,	yml_rl,	Pm, 0x49 },
-	{ ACMOVLPS,	yml_rl,	Pm, 0x4a },
-	{ ACMOVWCC,	yml_rl,	Pq, 0x43 },
-	{ ACMOVWCS,	yml_rl,	Pq, 0x42 },
-	{ ACMOVWEQ,	yml_rl,	Pq, 0x44 },
-	{ ACMOVWGE,	yml_rl,	Pq, 0x4d },
-	{ ACMOVWGT,	yml_rl,	Pq, 0x4f },
-	{ ACMOVWHI,	yml_rl,	Pq, 0x47 },
-	{ ACMOVWLE,	yml_rl,	Pq, 0x4e },
-	{ ACMOVWLS,	yml_rl,	Pq, 0x46 },
-	{ ACMOVWLT,	yml_rl,	Pq, 0x4c },
-	{ ACMOVWMI,	yml_rl,	Pq, 0x48 },
-	{ ACMOVWNE,	yml_rl,	Pq, 0x45 },
-	{ ACMOVWOC,	yml_rl,	Pq, 0x41 },
-	{ ACMOVWOS,	yml_rl,	Pq, 0x40 },
-	{ ACMOVWPC,	yml_rl,	Pq, 0x4b },
-	{ ACMOVWPL,	yml_rl,	Pq, 0x49 },
-	{ ACMOVWPS,	yml_rl,	Pq, 0x4a },
-
-	{ AFCMOVCC,	yfcmv,	Px, 0xdb,(00) },
-	{ AFCMOVCS,	yfcmv,	Px, 0xda,(00) },
-	{ AFCMOVEQ,	yfcmv,	Px, 0xda,(01) },
-	{ AFCMOVHI,	yfcmv,	Px, 0xdb,(02) },
-	{ AFCMOVLS,	yfcmv,	Px, 0xda,(02) },
-	{ AFCMOVNE,	yfcmv,	Px, 0xdb,(01) },
-	{ AFCMOVNU,	yfcmv,	Px, 0xdb,(03) },
-	{ AFCMOVUN,	yfcmv,	Px, 0xda,(03) },
-
-	{ ALFENCE, ynone, Pm, 0xae,0xe8 },
-	{ AMFENCE, ynone, Pm, 0xae,0xf0 },
-	{ ASFENCE, ynone, Pm, 0xae,0xf8 },
-
-	{ AEMMS, ynone, Pm, 0x77 },
-
-	{ APREFETCHT0,	yprefetch,	Pm,	0x18,(01) },
-	{ APREFETCHT1,	yprefetch,	Pm,	0x18,(02) },
-	{ APREFETCHT2,	yprefetch,	Pm,	0x18,(03) },
-	{ APREFETCHNTA,	yprefetch,	Pm,	0x18,(00) },
-
-	{ ABSWAPL,	ybswap,	Pm,	0xc8 },
+	{ ACMPXCHGB,	yrb_mb,	Pm, {0xb0} },
+	{ ACMPXCHGL,	yrl_ml,	Pm, {0xb1} },
+	{ ACMPXCHGW,	yrl_ml,	Pm, {0xb1} },
+	{ ACMPXCHG8B,	yscond,	Pm, {0xc7,(01)} },
+
+	{ ACPUID,	ynone,	Pm, {0xa2} },
+	{ ARDTSC,	ynone,	Pm, {0x31} },
+
+	{ AXADDB,	yrb_mb,	Pb, {0x0f,0xc0} },
+	{ AXADDL,	yrl_ml,	Pm, {0xc1} },
+	{ AXADDW,	yrl_ml,	Pe, {0x0f,0xc1} },
+
+	{ ACMOVLCC,	yml_rl,	Pm, {0x43} },
+	{ ACMOVLCS,	yml_rl,	Pm, {0x42} },
+	{ ACMOVLEQ,	yml_rl,	Pm, {0x44} },
+	{ ACMOVLGE,	yml_rl,	Pm, {0x4d} },
+	{ ACMOVLGT,	yml_rl,	Pm, {0x4f} },
+	{ ACMOVLHI,	yml_rl,	Pm, {0x47} },
+	{ ACMOVLLE,	yml_rl,	Pm, {0x4e} },
+	{ ACMOVLLS,	yml_rl,	Pm, {0x46} },
+	{ ACMOVLLT,	yml_rl,	Pm, {0x4c} },
+	{ ACMOVLMI,	yml_rl,	Pm, {0x48} },
+	{ ACMOVLNE,	yml_rl,	Pm, {0x45} },
+	{ ACMOVLOC,	yml_rl,	Pm, {0x41} },
+	{ ACMOVLOS,	yml_rl,	Pm, {0x40} },
+	{ ACMOVLPC,	yml_rl,	Pm, {0x4b} },
+	{ ACMOVLPL,	yml_rl,	Pm, {0x49} },
+	{ ACMOVLPS,	yml_rl,	Pm, {0x4a} },
+	{ ACMOVWCC,	yml_rl,	Pq, {0x43} },
+	{ ACMOVWCS,	yml_rl,	Pq, {0x42} },
+	{ ACMOVWEQ,	yml_rl,	Pq, {0x44} },
+	{ ACMOVWGE,	yml_rl,	Pq, {0x4d} },
+	{ ACMOVWGT,	yml_rl,	Pq, {0x4f} },
+	{ ACMOVWHI,	yml_rl,	Pq, {0x47} },
+	{ ACMOVWLE,	yml_rl,	Pq, {0x4e} },
+	{ ACMOVWLS,	yml_rl,	Pq, {0x46} },
+	{ ACMOVWLT,	yml_rl,	Pq, {0x4c} },
+	{ ACMOVWMI,	yml_rl,	Pq, {0x48} },
+	{ ACMOVWNE,	yml_rl,	Pq, {0x45} },
+	{ ACMOVWOC,	yml_rl,	Pq, {0x41} },
+	{ ACMOVWOS,	yml_rl,	Pq, {0x40} },
+	{ ACMOVWPC,	yml_rl,	Pq, {0x4b} },
+	{ ACMOVWPL,	yml_rl,	Pq, {0x49} },
+	{ ACMOVWPS,	yml_rl,	Pq, {0x4a} },
+
+	{ AFCMOVCC,	yfcmv,	Px, {0xdb,(00)} },
+	{ AFCMOVCS,	yfcmv,	Px, {0xda,(00)} },
+	{ AFCMOVEQ,	yfcmv,	Px, {0xda,(01)} },
+	{ AFCMOVHI,	yfcmv,	Px, {0xdb,(02)} },
+	{ AFCMOVLS,	yfcmv,	Px, {0xda,(02)} },
+	{ AFCMOVNE,	yfcmv,	Px, {0xdb,(01)} },
+	{ AFCMOVNU,	yfcmv,	Px, {0xdb,(03)} },
+	{ AFCMOVUN,	yfcmv,	Px, {0xda,(03)} },
+
+	{ ALFENCE, ynone, Pm, {0xae,0xe8} },
+	{ AMFENCE, ynone, Pm, {0xae,0xf0} },
+	{ ASFENCE, ynone, Pm, {0xae,0xf8} },
+
+	{ AEMMS, ynone, Pm, {0x77} },
+
+	{ APREFETCHT0,	yprefetch,	Pm,	{0x18,(01)} },
+	{ APREFETCHT1,	yprefetch,	Pm,	{0x18,(02)} },
+	{ APREFETCHT2,	yprefetch,	Pm,	{0x18,(03)} },
+	{ APREFETCHNTA,	yprefetch,	Pm,	{0x18,(00)} },
+
+	{ ABSWAPL,	ybswap,	Pm,	{0xc8} },
 	
-	{ AUNDEF,		ynone,	Px,	0x0f, 0x0b },
-
-	{ AADDPD,	yxm,	Pq, 0x58 },
-	{ AADDPS,	yxm,	Pm, 0x58 },
-	{ AADDSD,	yxm,	Pf2, 0x58 },
-	{ AADDSS,	yxm,	Pf3, 0x58 },
-	{ AANDNPD,	yxm,	Pq, 0x55 },
-	{ AANDNPS,	yxm,	Pm, 0x55 },
-	{ AANDPD,	yxm,	Pq, 0x54 },
-	{ AANDPS,	yxm,	Pq, 0x54 },
-	{ ACMPPD,	yxcmpi,	Px, Pe,0xc2 },
-	{ ACMPPS,	yxcmpi,	Pm, 0xc2,0 },
-	{ ACMPSD,	yxcmpi,	Px, Pf2,0xc2 },
-	{ ACMPSS,	yxcmpi,	Px, Pf3,0xc2 },
-	{ ACOMISD,	yxcmp,	Pe, 0x2f },
-	{ ACOMISS,	yxcmp,	Pm, 0x2f },
-	{ ACVTPL2PD,	yxcvm2,	Px, Pf3,0xe6,Pe,0x2a },
-	{ ACVTPL2PS,	yxcvm2,	Pm, 0x5b,0,0x2a,0, },
-	{ ACVTPD2PL,	yxcvm1,	Px, Pf2,0xe6,Pe,0x2d },
-	{ ACVTPD2PS,	yxm,	Pe, 0x5a },
-	{ ACVTPS2PL,	yxcvm1, Px, Pe,0x5b,Pm,0x2d },
-	{ ACVTPS2PD,	yxm,	Pm, 0x5a },
-	{ ACVTSD2SL,	yxcvfl, Pf2, 0x2d },
- 	{ ACVTSD2SS,	yxm,	Pf2, 0x5a },
-	{ ACVTSL2SD,	yxcvlf, Pf2, 0x2a },
-	{ ACVTSL2SS,	yxcvlf, Pf3, 0x2a },
-	{ ACVTSS2SD,	yxm,	Pf3, 0x5a },
-	{ ACVTSS2SL,	yxcvfl, Pf3, 0x2d },
-	{ ACVTTPD2PL,	yxcvm1,	Px, Pe,0xe6,Pe,0x2c },
-	{ ACVTTPS2PL,	yxcvm1,	Px, Pf3,0x5b,Pm,0x2c },
-	{ ACVTTSD2SL,	yxcvfl, Pf2, 0x2c },
-	{ ACVTTSS2SL,	yxcvfl,	Pf3, 0x2c },
-	{ ADIVPD,	yxm,	Pe, 0x5e },
-	{ ADIVPS,	yxm,	Pm, 0x5e },
-	{ ADIVSD,	yxm,	Pf2, 0x5e },
-	{ ADIVSS,	yxm,	Pf3, 0x5e },
-	{ AMASKMOVOU,	yxr,	Pe, 0xf7 },
-	{ AMAXPD,	yxm,	Pe, 0x5f },
-	{ AMAXPS,	yxm,	Pm, 0x5f },
-	{ AMAXSD,	yxm,	Pf2, 0x5f },
-	{ AMAXSS,	yxm,	Pf3, 0x5f },
-	{ AMINPD,	yxm,	Pe, 0x5d },
-	{ AMINPS,	yxm,	Pm, 0x5d },
-	{ AMINSD,	yxm,	Pf2, 0x5d },
-	{ AMINSS,	yxm,	Pf3, 0x5d },
-	{ AMOVAPD,	yxmov,	Pe, 0x28,0x29 },
-	{ AMOVAPS,	yxmov,	Pm, 0x28,0x29 },
-	{ AMOVO,	yxmov,	Pe, 0x6f,0x7f },
-	{ AMOVOU,	yxmov,	Pf3, 0x6f,0x7f },
-	{ AMOVHLPS,	yxr,	Pm, 0x12 },
-	{ AMOVHPD,	yxmov,	Pe, 0x16,0x17 },
-	{ AMOVHPS,	yxmov,	Pm, 0x16,0x17 },
-	{ AMOVLHPS,	yxr,	Pm, 0x16 },
-	{ AMOVLPD,	yxmov,	Pe, 0x12,0x13 },
-	{ AMOVLPS,	yxmov,	Pm, 0x12,0x13 },
-	{ AMOVMSKPD,	yxrrl,	Pq, 0x50 },
-	{ AMOVMSKPS,	yxrrl,	Pm, 0x50 },
-	{ AMOVNTO,	yxr_ml,	Pe, 0xe7 },
-	{ AMOVNTPD,	yxr_ml,	Pe, 0x2b },
-	{ AMOVNTPS,	yxr_ml,	Pm, 0x2b },
-	{ AMOVSD,	yxmov,	Pf2, 0x10,0x11 },
-	{ AMOVSS,	yxmov,	Pf3, 0x10,0x11 },
-	{ AMOVUPD,	yxmov,	Pe, 0x10,0x11 },
-	{ AMOVUPS,	yxmov,	Pm, 0x10,0x11 },
-	{ AMULPD,	yxm,	Pe, 0x59 },
-	{ AMULPS,	yxm,	Ym, 0x59 },
-	{ AMULSD,	yxm,	Pf2, 0x59 },
-	{ AMULSS,	yxm,	Pf3, 0x59 },
-	{ AORPD,	yxm,	Pq, 0x56 },
-	{ AORPS,	yxm,	Pm, 0x56 },
-	{ APADDQ,	yxm,	Pe, 0xd4 },
-	{ APAND,	yxm,	Pe, 0xdb },
-	{ APCMPEQB,	yxmq,	Pe ,0x74 },
-	{ APMAXSW,	yxm,	Pe, 0xee },
-	{ APMAXUB,	yxm,	Pe, 0xde },
-	{ APMINSW,	yxm,	Pe, 0xea },
-	{ APMINUB,	yxm,	Pe, 0xda },
-	{ APMOVMSKB,	ymskb,	Px, Pe,0xd7,0xd7 },
-	{ APSADBW,	yxm,	Pq, 0xf6 },
-	{ APSUBB,	yxm,	Pe, 0xf8 },
-	{ APSUBL,	yxm,	Pe, 0xfa },
-	{ APSUBQ,	yxm,	Pe, 0xfb },
-	{ APSUBSB,	yxm,	Pe, 0xe8 },
-	{ APSUBSW,	yxm,	Pe, 0xe9 },
-	{ APSUBUSB,	yxm,	Pe, 0xd8 },
-	{ APSUBUSW,	yxm,	Pe, 0xd9 },
-	{ APSUBW,	yxm,	Pe, 0xf9 },
-	{ APUNPCKHQDQ,	yxm,	Pe, 0x6d },
-	{ APUNPCKLQDQ,	yxm,	Pe, 0x6c },
-	{ APXOR,	yxm,	Pe, 0xef },
-	{ ARCPPS,	yxm,	Pm, 0x53 },
-	{ ARCPSS,	yxm,	Pf3, 0x53 },
-	{ ARSQRTPS,	yxm,	Pm, 0x52 },
-	{ ARSQRTSS,	yxm,	Pf3, 0x52 },
-	{ ASQRTPD,	yxm,	Pe, 0x51 },
-	{ ASQRTPS,	yxm,	Pm, 0x51 },
-	{ ASQRTSD,	yxm,	Pf2, 0x51 },
-	{ ASQRTSS,	yxm,	Pf3, 0x51 },
-	{ ASUBPD,	yxm,	Pe, 0x5c },
-	{ ASUBPS,	yxm,	Pm, 0x5c },
-	{ ASUBSD,	yxm,	Pf2, 0x5c },
-	{ ASUBSS,	yxm,	Pf3, 0x5c },
-	{ AUCOMISD,	yxcmp,	Pe, 0x2e },
-	{ AUCOMISS,	yxcmp,	Pm, 0x2e },
-	{ AUNPCKHPD,	yxm,	Pe, 0x15 },
-	{ AUNPCKHPS,	yxm,	Pm, 0x15 },
-	{ AUNPCKLPD,	yxm,	Pe, 0x14 },
-	{ AUNPCKLPS,	yxm,	Pm, 0x14 },
-	{ AXORPD,	yxm,	Pe, 0x57 },
-	{ AXORPS,	yxm,	Pm, 0x57 },
-
-	{ AAESENC,	yaes,	Pq, 0x38,0xdc,(0) },
-	{ APINSRD,	yinsrd,	Pq, 0x3a, 0x22, (00) },
-	{ APSHUFB,	ymshufb,Pq, 0x38, 0x00 },
-
-	{ AUSEFIELD,	ynop,	Px, 0,0 },
+	{ AUNDEF,		ynone,	Px,	{0x0f, 0x0b} },
+
+	{ AADDPD,	yxm,	Pq, {0x58} },
+	{ AADDPS,	yxm,	Pm, {0x58} },
+	{ AADDSD,	yxm,	Pf2, {0x58} },
+	{ AADDSS,	yxm,	Pf3, {0x58} },
+	{ AANDNPD,	yxm,	Pq, {0x55} },
+	{ AANDNPS,	yxm,	Pm, {0x55} },
+	{ AANDPD,	yxm,	Pq, {0x54} },
+	{ AANDPS,	yxm,	Pq, {0x54} },
+	{ ACMPPD,	yxcmpi,	Px, {Pe,0xc2} },
+	{ ACMPPS,	yxcmpi,	Pm, {0xc2,0} },
+	{ ACMPSD,	yxcmpi,	Px, {Pf2,0xc2} },
+	{ ACMPSS,	yxcmpi,	Px, {Pf3,0xc2} },
+	{ ACOMISD,	yxcmp,	Pe, {0x2f} },
+	{ ACOMISS,	yxcmp,	Pm, {0x2f} },
+	{ ACVTPL2PD,	yxcvm2,	Px, {Pf3,0xe6,Pe,0x2a} },
+	{ ACVTPL2PS,	yxcvm2,	Pm, {0x5b,0,0x2a,0,} },
+	{ ACVTPD2PL,	yxcvm1,	Px, {Pf2,0xe6,Pe,0x2d} },
+	{ ACVTPD2PS,	yxm,	Pe, {0x5a} },
+	{ ACVTPS2PL,	yxcvm1, Px, {Pe,0x5b,Pm,0x2d} },
+	{ ACVTPS2PD,	yxm,	Pm, {0x5a} },
+	{ ACVTSD2SL,	yxcvfl, Pf2, {0x2d} },
+ 	{ ACVTSD2SS,	yxm,	Pf2, {0x5a} },
+	{ ACVTSL2SD,	yxcvlf, Pf2, {0x2a} },
+	{ ACVTSL2SS,	yxcvlf, Pf3, {0x2a} },
+	{ ACVTSS2SD,	yxm,	Pf3, {0x5a} },
+	{ ACVTSS2SL,	yxcvfl, Pf3, {0x2d} },
+	{ ACVTTPD2PL,	yxcvm1,	Px, {Pe,0xe6,Pe,0x2c} },
+	{ ACVTTPS2PL,	yxcvm1,	Px, {Pf3,0x5b,Pm,0x2c} },
+	{ ACVTTSD2SL,	yxcvfl, Pf2, {0x2c} },
+	{ ACVTTSS2SL,	yxcvfl,	Pf3, {0x2c} },
+	{ ADIVPD,	yxm,	Pe, {0x5e} },
+	{ ADIVPS,	yxm,	Pm, {0x5e} },
+	{ ADIVSD,	yxm,	Pf2, {0x5e} },
+	{ ADIVSS,	yxm,	Pf3, {0x5e} },
+	{ AMASKMOVOU,	yxr,	Pe, {0xf7} },
+	{ AMAXPD,	yxm,	Pe, {0x5f} },
+	{ AMAXPS,	yxm,	Pm, {0x5f} },
+	{ AMAXSD,	yxm,	Pf2, {0x5f} },
+	{ AMAXSS,	yxm,	Pf3, {0x5f} },
+	{ AMINPD,	yxm,	Pe, {0x5d} },
+	{ AMINPS,	yxm,	Pm, {0x5d} },
+	{ AMINSD,	yxm,	Pf2, {0x5d} },
+	{ AMINSS,	yxm,	Pf3, {0x5d} },
+	{ AMOVAPD,	yxmov,	Pe, {0x28,0x29} },
+	{ AMOVAPS,	yxmov,	Pm, {0x28,0x29} },
+	{ AMOVO,	yxmov,	Pe, {0x6f,0x7f} },
+	{ AMOVOU,	yxmov,	Pf3, {0x6f,0x7f} },
+	{ AMOVHLPS,	yxr,	Pm, {0x12} },
+	{ AMOVHPD,	yxmov,	Pe, {0x16,0x17} },
+	{ AMOVHPS,	yxmov,	Pm, {0x16,0x17} },
+	{ AMOVLHPS,	yxr,	Pm, {0x16} },
+	{ AMOVLPD,	yxmov,	Pe, {0x12,0x13} },
+	{ AMOVLPS,	yxmov,	Pm, {0x12,0x13} },
+	{ AMOVMSKPD,	yxrrl,	Pq, {0x50} },
+	{ AMOVMSKPS,	yxrrl,	Pm, {0x50} },
+	{ AMOVNTO,	yxr_ml,	Pe, {0xe7} },
+	{ AMOVNTPD,	yxr_ml,	Pe, {0x2b} },
+	{ AMOVNTPS,	yxr_ml,	Pm, {0x2b} },
+	{ AMOVSD,	yxmov,	Pf2, {0x10,0x11} },
+	{ AMOVSS,	yxmov,	Pf3, {0x10,0x11} },
+	{ AMOVUPD,	yxmov,	Pe, {0x10,0x11} },
+	{ AMOVUPS,	yxmov,	Pm, {0x10,0x11} },
+	{ AMULPD,	yxm,	Pe, {0x59} },
+	{ AMULPS,	yxm,	Ym, {0x59} },
+	{ AMULSD,	yxm,	Pf2, {0x59} },
+	{ AMULSS,	yxm,	Pf3, {0x59} },
+	{ AORPD,	yxm,	Pq, {0x56} },
+	{ AORPS,	yxm,	Pm, {0x56} },
+	{ APADDQ,	yxm,	Pe, {0xd4} },
+	{ APAND,	yxm,	Pe, {0xdb} },
+	{ APCMPEQB,	yxmq,	Pe, {0x74} },
+	{ APMAXSW,	yxm,	Pe, {0xee} },
+	{ APMAXUB,	yxm,	Pe, {0xde} },
+	{ APMINSW,	yxm,	Pe, {0xea} },
+	{ APMINUB,	yxm,	Pe, {0xda} },
+	{ APMOVMSKB,	ymskb,	Px, {Pe,0xd7,0xd7} },
+	{ APSADBW,	yxm,	Pq, {0xf6} },
+	{ APSUBB,	yxm,	Pe, {0xf8} },
+	{ APSUBL,	yxm,	Pe, {0xfa} },
+	{ APSUBQ,	yxm,	Pe, {0xfb} },
+	{ APSUBSB,	yxm,	Pe, {0xe8} },
+	{ APSUBSW,	yxm,	Pe, {0xe9} },
+	{ APSUBUSB,	yxm,	Pe, {0xd8} },
+	{ APSUBUSW,	yxm,	Pe, {0xd9} },
+	{ APSUBW,	yxm,	Pe, {0xf9} },
+	{ APUNPCKHQDQ,	yxm,	Pe, {0x6d} },
+	{ APUNPCKLQDQ,	yxm,	Pe, {0x6c} },
+	{ APXOR,	yxm,	Pe, {0xef} },
+	{ ARCPPS,	yxm,	Pm, {0x53} },
+	{ ARCPSS,	yxm,	Pf3, {0x53} },
+	{ ARSQRTPS,	yxm,	Pm, {0x52} },
+	{ ARSQRTSS,	yxm,	Pf3, {0x52} },
+	{ ASQRTPD,	yxm,	Pe, {0x51} },
+	{ ASQRTPS,	yxm,	Pm, {0x51} },
+	{ ASQRTSD,	yxm,	Pf2, {0x51} },
+	{ ASQRTSS,	yxm,	Pf3, {0x51} },
+	{ ASUBPD,	yxm,	Pe, {0x5c} },
+	{ ASUBPS,	yxm,	Pm, {0x5c} },
+	{ ASUBSD,	yxm,	Pf2, {0x5c} },
+	{ ASUBSS,	yxm,	Pf3, {0x5c} },
+	{ AUCOMISD,	yxcmp,	Pe, {0x2e} },
+	{ AUCOMISS,	yxcmp,	Pm, {0x2e} },
+	{ AUNPCKHPD,	yxm,	Pe, {0x15} },
+	{ AUNPCKHPS,	yxm,	Pm, {0x15} },
+	{ AUNPCKLPD,	yxm,	Pe, {0x14} },
+	{ AUNPCKLPS,	yxm,	Pm, {0x14} },
+	{ AXORPD,	yxm,	Pe, {0x57} },
+	{ AXORPS,	yxm,	Pm, {0x57} },
+
+	{ AAESENC,	yaes,	Pq, {0x38,0xdc,(0)} },
+	{ APINSRD,	yinsrd,	Pq, {0x3a, 0x22, (00)} },
+	{ APSHUFB,	ymshufb,Pq, {0x38, 0x00} },
+
+	{ AUSEFIELD,	ynop,	Px, {0,0} },
 	{ ATYPE },
-	{ AFUNCDATA,	yfuncdata,	Px, 0,0 },
-	{ APCDATA,	ypcdata,	Px, 0,0 },
+	{ AFUNCDATA,	yfuncdata,	Px, {0,0} },
+	{ APCDATA,	ypcdata,	Px, {0,0} },
 	{ ACHECKNIL },
 	{ AVARDEF },
 	{ AVARKILL },
-	{ ADUFFCOPY,	yduff,	Px, 0xe8 },
-	{ ADUFFZERO,	yduff,	Px, 0xe8 },
+	{ ADUFFCOPY,	yduff,	Px, {0xe8} },
+	{ ADUFFZERO,	yduff,	Px, {0xe8} },
 
-	0
+	{0}
 };
 
 static int32	vaddr(Link*, Addr*, Reloc*);
@@ -1902,7 +1900,11 @@ bad:
 	return;
 }
 
-#define	E	0xff
+enum
+{
+	E = 0xff,
+};
+
 static uchar	ymovtab[] =
 {
 /* push */
@@ -2134,7 +2136,7 @@ mediaop(Link *ctxt, Optab *o, int op, int osize, int z)
 			break;
 		}
 	default:
-		if(ctxt->andptr == ctxt->and || ctxt->andptr[-1] != Pm)
+		if(ctxt->andptr == ctxt->and || ctxt->and[ctxt->andptr - ctxt->and - 1] != Pm)
 			*ctxt->andptr++ = Pm;
 		break;
 	}
@@ -2289,8 +2291,13 @@ found:
 		*ctxt->andptr++ = p->from.offset;
 		break;
 
+	case Zcallindreg:
+		r = addrel(ctxt->cursym);
+		r->off = p->pc;
+		r->type = R_CALLIND;
+		r->siz = 0;
+		// fallthrough
 	case Zo_m:
-	case_Zo_m:
 		*ctxt->andptr++ = op;
 		asmand(ctxt, &p->to, o->op[z+1]);
 		break;
@@ -2511,13 +2518,6 @@ found:
 		put4(ctxt, 0);
 		break;
 
-	case Zcallindreg:
-		r = addrel(ctxt->cursym);
-		r->off = p->pc;
-		r->type = R_CALLIND;
-		r->siz = 0;
-		goto case_Zo_m;
-
 	case Zbyte:
 		v = vaddr(ctxt, &p->from, &rel);
 		if(rel.siz != 0) {
@@ -2707,11 +2707,11 @@ mfound:
 			break;
 		
 		case Hplan9:
-			if(ctxt->plan9tos == nil)
-				ctxt->plan9tos = linklookup(ctxt, "_tos", 0);
+			if(ctxt->plan9privates == nil)
+				ctxt->plan9privates = linklookup(ctxt, "_privates", 0);
 			memset(&pp.from, 0, sizeof pp.from);
 			pp.from.type = D_EXTERN;
-			pp.from.sym = ctxt->plan9tos;
+			pp.from.sym = ctxt->plan9privates;
 			pp.from.offset = 0;
 			pp.from.index = D_NONE;
 			*ctxt->andptr++ = 0x8B;
diff --git a/src/liblink/data.c b/src/liblink/data.c
index 4504f41..e5efa2e 100644
--- a/src/liblink/data.c
+++ b/src/liblink/data.c
@@ -83,6 +83,8 @@ savedata(Link *ctxt, LSym *s, Prog *p, char *pn)
 	siz = ctxt->arch->datasize(p);
 	if(off < 0 || siz < 0 || off >= 1<<30 || siz >= 100)
 		mangle(pn);
+	if(ctxt->enforce_data_order && off < s->np)
+		ctxt->diag("data out of order (already have %d)\n%P", p);
 	symgrow(ctxt, s, off+siz);
 
 	if(p->to.type == ctxt->arch->D_FCONST) {
diff --git a/src/liblink/ld.c b/src/liblink/ld.c
index 9ea0e9a..6d0fe4a 100644
--- a/src/liblink/ld.c
+++ b/src/liblink/ld.c
@@ -130,16 +130,26 @@ find1(int32 l, int c)
 }
 
 void
-nuxiinit(void)
+nuxiinit(LinkArch *arch)
 {
 	int i, c;
 
+	if(arch->endian != BigEndian && arch->endian != LittleEndian)
+		sysfatal("unknown endian (%#x) for arch %s", arch->endian, arch->name);
+
 	for(i=0; i<4; i++) {
-		c = find1(0x04030201L, i+1);
-		if(i < 2)
-			inuxi2[i] = c;
-		if(i < 1)
-			inuxi1[i] = c;
+		c = find1(arch->endian, i+1);
+		if(arch->endian == LittleEndian) {
+			if(i < 2)
+				inuxi2[i] = c;
+			if(i < 1)
+				inuxi1[i] = c;
+		} else {
+			if(i >= 2)
+				inuxi2[i-2] = c;
+			if(i >= 3)
+				inuxi1[i-3] = c;
+		}
 		inuxi4[i] = c;
 		if(c == i) {
 			inuxi8[i] = c;
@@ -149,8 +159,13 @@ nuxiinit(void)
 			inuxi8[i+4] = c;
 		}
 		fnuxi4[i] = c;
-		fnuxi8[i] = c;
-		fnuxi8[i+4] = c+4;
+		if(c == i) {
+			fnuxi8[i] = c;
+			fnuxi8[i+4] = c+4;
+		} else {
+			fnuxi8[i] = c+4;
+			fnuxi8[i+4] = c;
+		}
 	}
 }
 
@@ -161,7 +176,10 @@ uchar	inuxi2[2];
 uchar	inuxi4[4];
 uchar	inuxi8[8];
 
-#define	LOG	5
+enum
+{
+	LOG = 5,
+};
 void
 mkfwd(LSym *sym)
 {
diff --git a/src/liblink/list5.c b/src/liblink/list5.c
index 4a4e8c7..a91df55 100644
--- a/src/liblink/list5.c
+++ b/src/liblink/list5.c
@@ -46,6 +46,7 @@ static int	Pconv(Fmt *fp);
 static int	Rconv(Fmt *fp);
 static int	RAconv(Fmt *fp);
 static int	DSconv(Fmt *fp);
+static int	DRconv(Fmt*);
 
 #pragma	varargck	type	"$"	char*
 #pragma	varargck	type	"M"	Addr*
@@ -59,6 +60,9 @@ listinit5(void)
 	fmtinstall('P', Pconv);
 	fmtinstall('R', Rconv);
 
+	// for liblink internal use
+	fmtinstall('^', DRconv);
+
 	// for internal use
 	fmtinstall('$', DSconv);
 	fmtinstall('M', Mconv);
@@ -314,6 +318,19 @@ Rconv(Fmt *fp)
 }
 
 static int
+DRconv(Fmt *fp)
+{
+	char *s;
+	int a;
+
+	a = va_arg(fp->args, int);
+	s = "C_??";
+	if(a >= C_NONE && a <= C_NCLASS)
+		s = cnames5[a];
+	return fmtstrcpy(fp, s);
+}
+
+static int
 Mconv(Fmt *fp)
 {
 	char str[STRINGSZ];
diff --git a/src/liblink/list6.c b/src/liblink/list6.c
index fe708d8..0635fdf 100644
--- a/src/liblink/list6.c
+++ b/src/liblink/list6.c
@@ -217,7 +217,7 @@ conv:
 	return fmtstrcpy(fp, str);
 }
 
-char*	regstr[] =
+static char*	regstr[] =
 {
 	"AL",	/* [D_AL] */
 	"CL",
diff --git a/src/liblink/list8.c b/src/liblink/list8.c
index 7866924..63d96b9 100644
--- a/src/liblink/list8.c
+++ b/src/liblink/list8.c
@@ -211,7 +211,7 @@ conv:
 	return fmtstrcpy(fp, str);
 }
 
-char*	regstr[] =
+static char*	regstr[] =
 {
 	"AL",	/* [D_AL] */
 	"CL",
diff --git a/src/liblink/obj5.c b/src/liblink/obj5.c
index ccd4c81..d7f2714 100644
--- a/src/liblink/obj5.c
+++ b/src/liblink/obj5.c
@@ -33,7 +33,7 @@
 #include <bio.h>
 #include <link.h>
 #include "../cmd/5l/5.out.h"
-#include "../pkg/runtime/stack.h"
+#include "../runtime/stack.h"
 
 static Prog zprg = {
 	.as = AGOK,
@@ -92,7 +92,7 @@ progedit(Link *ctxt, Prog *p)
 {
 	char literal[64];
 	LSym *s;
-	LSym *tlsfallback;
+	static LSym *tlsfallback;
 
 	p->from.class = 0;
 	p->to.class = 0;
@@ -111,19 +111,43 @@ progedit(Link *ctxt, Prog *p)
 	// Replace TLS register fetches on older ARM procesors.
 	switch(p->as) {
 	case AMRC:
-		// If the instruction matches MRC 15, 0, <reg>, C13, C0, 3, replace it.
-		if(ctxt->goarm < 7 && (p->to.offset & 0xffff0fff) == 0xee1d0f70) {
-			tlsfallback = linklookup(ctxt, "runtime.read_tls_fallback", 0);
+		// Treat MRC 15, 0, <reg>, C13, C0, 3 specially.
+		if((p->to.offset & 0xffff0fff) == 0xee1d0f70) {
+			// Because the instruction might be rewriten to a BL which returns in R0
+			// the register must be zero.
+		       	if ((p->to.offset & 0xf000) != 0)
+				ctxt->diag("%L: TLS MRC instruction must write to R0 as it might get translated into a BL instruction", p->lineno);
+
+			if(ctxt->goarm < 7) {
+				// Replace it with BL runtime.read_tls_fallback(SB) for ARM CPUs that lack the tls extension.
+				if(tlsfallback == nil)
+					tlsfallback = linklookup(ctxt, "runtime.read_tls_fallback", 0);
+				// MOVW	LR, R11
+				p->as = AMOVW;
+				p->from.type = D_REG;
+				p->from.reg = REGLINK;
+				p->to.type = D_REG;
+				p->to.reg = REGTMP;
 
-			// BL runtime.read_tls_fallback(SB)
-			p->as = ABL;
-			p->to.type = D_BRANCH;
-			p->to.sym = tlsfallback;
-			p->to.offset = 0;
-		} else {
-			// Otherwise, MRC/MCR instructions need no further treatment.
-			p->as = AWORD;
+				// BL	runtime.read_tls_fallback(SB)
+				p = appendp(ctxt, p);
+				p->as = ABL;
+				p->to.type = D_BRANCH;
+				p->to.sym = tlsfallback;
+				p->to.offset = 0;
+
+				// MOVW	R11, LR
+				p = appendp(ctxt, p);
+				p->as = AMOVW;
+				p->from.type = D_REG;
+				p->from.reg = REGTMP;
+				p->to.type = D_REG;
+				p->to.reg = REGLINK;
+				break;
+			}
 		}
+		// Otherwise, MRC/MCR instructions need no further treatment.
+		p->as = AWORD;
 		break;
 	}
 
@@ -173,15 +197,15 @@ progedit(Link *ctxt, Prog *p)
 	if(ctxt->flag_shared) {
 		// Shared libraries use R_ARM_TLS_IE32 instead of 
 		// R_ARM_TLS_LE32, replacing the link time constant TLS offset in
-		// runtime.tlsgm with an address to a GOT entry containing the 
-		// offset. Rewrite $runtime.tlsgm(SB) to runtime.tlsgm(SB) to
+		// runtime.tlsg with an address to a GOT entry containing the 
+		// offset. Rewrite $runtime.tlsg(SB) to runtime.tlsg(SB) to
 		// compensate.
-		if(ctxt->gmsym == nil)
-			ctxt->gmsym = linklookup(ctxt, "runtime.tlsgm", 0);
+		if(ctxt->tlsg == nil)
+			ctxt->tlsg = linklookup(ctxt, "runtime.tlsg", 0);
 
-		if(p->from.type == D_CONST && p->from.name == D_EXTERN && p->from.sym == ctxt->gmsym)
+		if(p->from.type == D_CONST && p->from.name == D_EXTERN && p->from.sym == ctxt->tlsg)
 			p->from.type = D_OREG;
-		if(p->to.type == D_CONST && p->to.name == D_EXTERN && p->to.sym == ctxt->gmsym)
+		if(p->to.type == D_CONST && p->to.name == D_EXTERN && p->to.sym == ctxt->tlsg)
 			p->to.type = D_OREG;
 	}
 }
@@ -233,7 +257,7 @@ nocache(Prog *p)
 static void
 addstacksplit(Link *ctxt, LSym *cursym)
 {
-	Prog *p, *pl, *q, *q1, *q2;
+	Prog *p, *pl, *p1, *p2, *q, *q1, *q2;
 	int o;
 	int32 autosize, autoffset;
 	
@@ -429,32 +453,89 @@ addstacksplit(Link *ctxt, LSym *cursym)
 			p->spadj = autosize;
 			
 			if(cursym->text->reg & WRAPPER) {
-				// g->panicwrap += autosize;
-				// MOVW panicwrap_offset(g), R3
-				// ADD $autosize, R3
-				// MOVW R3 panicwrap_offset(g)
+				// if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame
+				//
+				//	MOVW g_panic(g), R1
+				//	CMP $0, R1
+				//	B.EQ end
+				//	MOVW panic_argp(R1), R2
+				//	ADD $(autosize+4), R13, R3
+				//	CMP R2, R3
+				//	B.NE end
+				//	ADD $4, R13, R4
+				//	MOVW R4, panic_argp(R1)
+				// end:
+				//	NOP
+				//
+				// The NOP is needed to give the jumps somewhere to land.
+				// It is a liblink NOP, not an ARM NOP: it encodes to 0 instruction bytes.
+
 				p = appendp(ctxt, p);
 				p->as = AMOVW;
 				p->from.type = D_OREG;
 				p->from.reg = REGG;
-				p->from.offset = 2*ctxt->arch->ptrsize;
+				p->from.offset = 4*ctxt->arch->ptrsize; // G.panic
 				p->to.type = D_REG;
-				p->to.reg = 3;
+				p->to.reg = 1;
+			
+				p = appendp(ctxt, p);
+				p->as = ACMP;
+				p->from.type = D_CONST;
+				p->from.offset = 0;
+				p->reg = 1;
+			
+				p = appendp(ctxt, p);
+				p->as = ABEQ;
+				p->to.type = D_BRANCH;
+				p1 = p;
+				
+				p = appendp(ctxt, p);
+				p->as = AMOVW;
+				p->from.type = D_OREG;
+				p->from.reg = 1;
+				p->from.offset = 0; // Panic.argp
+				p->to.type = D_REG;
+				p->to.reg = 2;
 			
 				p = appendp(ctxt, p);
 				p->as = AADD;
 				p->from.type = D_CONST;
-				p->from.offset = autosize;
+				p->from.offset = autosize+4;
+				p->reg = 13;
 				p->to.type = D_REG;
 				p->to.reg = 3;
-				
+
+				p = appendp(ctxt, p);
+				p->as = ACMP;
+				p->from.type = D_REG;
+				p->from.reg = 2;
+				p->reg = 3;
+
+				p = appendp(ctxt, p);
+				p->as = ABNE;
+				p->to.type = D_BRANCH;
+				p2 = p;
+			
+				p = appendp(ctxt, p);
+				p->as = AADD;
+				p->from.type = D_CONST;
+				p->from.offset = 4;
+				p->reg = 13;
+				p->to.type = D_REG;
+				p->to.reg = 4;
+
 				p = appendp(ctxt, p);
 				p->as = AMOVW;
 				p->from.type = D_REG;
-				p->from.reg = 3;
+				p->from.reg = 4;
 				p->to.type = D_OREG;
-				p->to.reg = REGG;
-				p->to.offset = 2*ctxt->arch->ptrsize;
+				p->to.reg = 1;
+				p->to.offset = 0; // Panic.argp
+
+				p = appendp(ctxt, p);
+				p->as = ANOP;
+				p1->pcond = p;
+				p2->pcond = p;
 			}
 			break;
 
@@ -475,44 +556,6 @@ addstacksplit(Link *ctxt, LSym *cursym)
 				}
 			}
 
-			if(cursym->text->reg & WRAPPER) {
-				int scond;
-				
-				// Preserve original RET's cond, to allow RET.EQ
-				// in the implementation of reflect.call.
-				scond = p->scond;
-				p->scond = C_SCOND_NONE;
-
-				// g->panicwrap -= autosize;
-				// MOVW panicwrap_offset(g), R3
-				// SUB $autosize, R3
-				// MOVW R3 panicwrap_offset(g)
-				p->as = AMOVW;
-				p->from.type = D_OREG;
-				p->from.reg = REGG;
-				p->from.offset = 2*ctxt->arch->ptrsize;
-				p->to.type = D_REG;
-				p->to.reg = 3;
-				p = appendp(ctxt, p);
-			
-				p->as = ASUB;
-				p->from.type = D_CONST;
-				p->from.offset = autosize;
-				p->to.type = D_REG;
-				p->to.reg = 3;
-				p = appendp(ctxt, p);
-
-				p->as = AMOVW;
-				p->from.type = D_REG;
-				p->from.reg = 3;
-				p->to.type = D_OREG;
-				p->to.reg = REGG;
-				p->to.offset = 2*ctxt->arch->ptrsize;
-				p = appendp(ctxt, p);
-
-				p->scond = scond;
-			}
-
 			p->as = AMOVW;
 			p->scond |= C_PBIT;
 			p->from.type = D_OREG;
@@ -707,41 +750,42 @@ softfloat(Link *ctxt, LSym *cursym)
 
 		default:
 			goto notsoft;
+		}
 
-		soft:
-			if (!wasfloat || (p->mark&LABEL)) {
-				next = ctxt->arch->prg();
-				*next = *p;
+	soft:
+		if (!wasfloat || (p->mark&LABEL)) {
+			next = ctxt->arch->prg();
+			*next = *p;
 
-				// BL _sfloat(SB)
-				*p = zprg;
-				p->link = next;
-				p->as = ABL;
+			// BL _sfloat(SB)
+			*p = zprg;
+			p->link = next;
+			p->as = ABL;
  				p->to.type = D_BRANCH;
-				p->to.sym = symsfloat;
-				p->lineno = next->lineno;
-
-				p = next;
-				wasfloat = 1;
-			}
-			break;
+			p->to.sym = symsfloat;
+			p->lineno = next->lineno;
 
-		notsoft:
-			wasfloat = 0;
+			p = next;
+			wasfloat = 1;
 		}
+		continue;
+
+	notsoft:
+		wasfloat = 0;
 	}
 }
 
 static Prog*
 stacksplit(Link *ctxt, Prog *p, int32 framesize, int noctxt)
 {
-	int32 arg;
-
 	// MOVW			g_stackguard(g), R1
 	p = appendp(ctxt, p);
 	p->as = AMOVW;
 	p->from.type = D_OREG;
 	p->from.reg = REGG;
+	p->from.offset = 2*ctxt->arch->ptrsize;	// G.stackguard0
+	if(ctxt->cursym->cfunc)
+		p->from.offset = 3*ctxt->arch->ptrsize;	// G.stackguard1
 	p->to.type = D_REG;
 	p->to.reg = 1;
 	
@@ -820,29 +864,6 @@ stacksplit(Link *ctxt, Prog *p, int32 framesize, int noctxt)
 		p->scond = C_SCOND_NE;
 	}
 	
-	// MOVW.LS		$framesize, R1
-	p = appendp(ctxt, p);
-	p->as = AMOVW;
-	p->scond = C_SCOND_LS;
-	p->from.type = D_CONST;
-	p->from.offset = framesize;
-	p->to.type = D_REG;
-	p->to.reg = 1;
-
-	// MOVW.LS		$args, R2
-	p = appendp(ctxt, p);
-	p->as = AMOVW;
-	p->scond = C_SCOND_LS;
-	p->from.type = D_CONST;
-	arg = ctxt->cursym->text->to.offset2;
-	if(arg == 1) // special marker for known 0
-		arg = 0;
-	if(arg&3)
-		ctxt->diag("misaligned argument size in stack split");
-	p->from.offset = arg;
-	p->to.type = D_REG;
-	p->to.reg = 2;
-
 	// MOVW.LS	R14, R3
 	p = appendp(ctxt, p);
 	p->as = AMOVW;
@@ -857,7 +878,10 @@ stacksplit(Link *ctxt, Prog *p, int32 framesize, int noctxt)
 	p->as = ABL;
 	p->scond = C_SCOND_LS;
 	p->to.type = D_BRANCH;
-	p->to.sym = ctxt->symmorestack[noctxt];
+	if(ctxt->cursym->cfunc)
+		p->to.sym = linklookup(ctxt, "runtime.morestackc", 0);
+	else
+		p->to.sym = ctxt->symmorestack[noctxt];
 	
 	// BLS	start
 	p = appendp(ctxt, p);
@@ -1025,6 +1049,7 @@ loop:
 LinkArch linkarm = {
 	.name = "arm",
 	.thechar = '5',
+	.endian = LittleEndian,
 
 	.addstacksplit = addstacksplit,
 	.assemble = span5,
@@ -1052,6 +1077,7 @@ LinkArch linkarm = {
 	.D_PARAM = D_PARAM,
 	.D_SCONST = D_SCONST,
 	.D_STATIC = D_STATIC,
+	.D_OREG = D_OREG,
 
 	.ACALL = ABL,
 	.ADATA = ADATA,
diff --git a/src/liblink/obj6.c b/src/liblink/obj6.c
index b1bcd0d..2acfd2f 100644
--- a/src/liblink/obj6.c
+++ b/src/liblink/obj6.c
@@ -33,7 +33,7 @@
 #include <bio.h>
 #include <link.h>
 #include "../cmd/6l/6.out.h"
-#include "../pkg/runtime/stack.h"
+#include "../runtime/stack.h"
 
 static Prog zprg = {
 	.back = 2,
@@ -103,7 +103,7 @@ static int
 canuselocaltls(Link *ctxt)
 {
 	switch(ctxt->headtype) {
-//	case Hlinux:
+	case Hplan9:
 	case Hwindows:
 		return 0;
 	}
@@ -342,32 +342,6 @@ nacladdr(Link *ctxt, Prog *p, Addr *a)
 	}
 }
 
-static char*
-morename[] =
-{
-	"runtime.morestack00",
-	"runtime.morestack00_noctxt",
-	"runtime.morestack10",
-	"runtime.morestack10_noctxt",
-	"runtime.morestack01",
-	"runtime.morestack01_noctxt",
-	"runtime.morestack11",
-	"runtime.morestack11_noctxt",
-
-	"runtime.morestack8",
-	"runtime.morestack8_noctxt",
-	"runtime.morestack16",
-	"runtime.morestack16_noctxt",
-	"runtime.morestack24",
-	"runtime.morestack24_noctxt",
-	"runtime.morestack32",
-	"runtime.morestack32_noctxt",
-	"runtime.morestack40",
-	"runtime.morestack40_noctxt",
-	"runtime.morestack48",
-	"runtime.morestack48_noctxt",
-};
-
 static Prog*	load_g_cx(Link*, Prog*);
 static Prog*	stacksplit(Link*, Prog*, int32, int32, int, Prog**);
 static void	indir_cx(Link*, Addr*);
@@ -388,20 +362,21 @@ parsetextconst(vlong arg, vlong *textstksiz, vlong *textarg)
 static void
 addstacksplit(Link *ctxt, LSym *cursym)
 {
-	Prog *p, *q, *q1;
+	Prog *p, *q, *p1, *p2;
 	int32 autoffset, deltasp;
 	int a, pcsize;
-	uint32 i;
 	vlong textstksiz, textarg;
 
-	if(ctxt->gmsym == nil)
-		ctxt->gmsym = linklookup(ctxt, "runtime.tlsgm", 0);
+	if(ctxt->tlsg == nil)
+		ctxt->tlsg = linklookup(ctxt, "runtime.tlsg", 0);
 	if(ctxt->symmorestack[0] == nil) {
-		if(nelem(morename) > nelem(ctxt->symmorestack))
-			sysfatal("Link.symmorestack needs at least %d elements", nelem(morename));
-		for(i=0; i<nelem(morename); i++)
-			ctxt->symmorestack[i] = linklookup(ctxt, morename[i], 0);
+		ctxt->symmorestack[0] = linklookup(ctxt, "runtime.morestack", 0);
+		ctxt->symmorestack[1] = linklookup(ctxt, "runtime.morestack_noctxt", 0);
 	}
+
+	if(ctxt->headtype == Hplan9 && ctxt->plan9privates == nil)
+		ctxt->plan9privates = linklookup(ctxt, "_privates", 0);
+
 	ctxt->cursym = cursym;
 
 	if(cursym->text == nil || cursym->text->link == nil)
@@ -459,51 +434,88 @@ addstacksplit(Link *ctxt, LSym *cursym)
 	deltasp = autoffset;
 	
 	if(cursym->text->from.scale & WRAPPER) {
-		// g->panicwrap += autoffset + ctxt->arch->regsize;
-		p = appendp(ctxt, p);
-		p->as = AADDL;
-		p->from.type = D_CONST;
-		p->from.offset = autoffset + ctxt->arch->regsize;
-		indir_cx(ctxt, &p->to);
-		p->to.offset = 2*ctxt->arch->ptrsize;
-	}
+		// if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame
+		//
+		//	MOVQ g_panic(CX), BX
+		//	TESTQ BX, BX
+		//	JEQ end
+		//	LEAQ (autoffset+8)(SP), DI
+		//	CMPQ panic_argp(BX), DI
+		//	JNE end
+		//	MOVQ SP, panic_argp(BX)
+		// end:
+		//	NOP
+		//
+		// The NOP is needed to give the jumps somewhere to land.
+		// It is a liblink NOP, not an x86 NOP: it encodes to 0 instruction bytes.
 
-	if(ctxt->debugstack > 1 && autoffset) {
-		// 6l -K -K means double-check for stack overflow
-		// even after calling morestack and even if the
-		// function is marked as nosplit.
 		p = appendp(ctxt, p);
 		p->as = AMOVQ;
-		indir_cx(ctxt, &p->from);
-		p->from.offset = 0;
+		p->from.type = D_INDIR+D_CX;
+		p->from.offset = 4*ctxt->arch->ptrsize; // G.panic
 		p->to.type = D_BX;
+		if(ctxt->headtype == Hnacl) {
+			p->as = AMOVL;
+			p->from.type = D_INDIR+D_R15;
+			p->from.scale = 1;
+			p->from.index = D_CX;
+		}
 
 		p = appendp(ctxt, p);
-		p->as = ASUBQ;
-		p->from.type = D_CONST;
-		p->from.offset = StackSmall+32;
+		p->as = ATESTQ;
+		p->from.type = D_BX;
 		p->to.type = D_BX;
+		if(ctxt->headtype == Hnacl)
+			p->as = ATESTL;
+
+		p = appendp(ctxt, p);
+		p->as = AJEQ;
+		p->to.type = D_BRANCH;
+		p1 = p;
+
+		p = appendp(ctxt, p);
+		p->as = ALEAQ;
+		p->from.type = D_INDIR+D_SP;
+		p->from.offset = autoffset+8;
+		p->to.type = D_DI;
+		if(ctxt->headtype == Hnacl)
+			p->as = ALEAL;
 
 		p = appendp(ctxt, p);
 		p->as = ACMPQ;
-		p->from.type = D_SP;
-		p->to.type = D_BX;
+		p->from.type = D_INDIR+D_BX;
+		p->from.offset = 0; // Panic.argp
+		p->to.type = D_DI;
+		if(ctxt->headtype == Hnacl) {
+			p->as = ACMPL;
+			p->from.type = D_INDIR+D_R15;
+			p->from.scale = 1;
+			p->from.index = D_BX;
+		}
 
 		p = appendp(ctxt, p);
-		p->as = AJHI;
+		p->as = AJNE;
 		p->to.type = D_BRANCH;
-		q1 = p;
+		p2 = p;
 
 		p = appendp(ctxt, p);
-		p->as = AINT;
-		p->from.type = D_CONST;
-		p->from.offset = 3;
+		p->as = AMOVQ;
+		p->from.type = D_SP;
+		p->to.type = D_INDIR+D_BX;
+		p->to.offset = 0; // Panic.argp
+		if(ctxt->headtype == Hnacl) {
+			p->as = AMOVL;
+			p->to.type = D_INDIR+D_R15;
+			p->to.scale = 1;
+			p->to.index = D_BX;
+		}
 
 		p = appendp(ctxt, p);
 		p->as = ANOP;
-		q1->pcond = p;
+		p1->pcond = p;
+		p2->pcond = p;
 	}
-	
+
 	if(ctxt->debugzerostack && autoffset && !(cursym->text->from.scale&NOSPLIT)) {
 		// 6l -Z means zero the stack frame on entry.
 		// This slows down function calls but can help avoid
@@ -585,19 +597,6 @@ addstacksplit(Link *ctxt, LSym *cursym)
 		if(autoffset != deltasp)
 			ctxt->diag("unbalanced PUSH/POP");
 
-		if(cursym->text->from.scale & WRAPPER) {
-			p = load_g_cx(ctxt, p);
-			p = appendp(ctxt, p);
-			// g->panicwrap -= autoffset + ctxt->arch->regsize;
-			p->as = ASUBL;
-			p->from.type = D_CONST;
-			p->from.offset = autoffset + ctxt->arch->regsize;
-			indir_cx(ctxt, &p->to);
-			p->to.offset = 2*ctxt->arch->ptrsize;
-			p = appendp(ctxt, p);
-			p->as = ARET;
-		}
-
 		if(autoffset) {
 			p->as = AADJSP;
 			p->from.type = D_CONST;
@@ -667,9 +666,9 @@ static Prog*
 stacksplit(Link *ctxt, Prog *p, int32 framesize, int32 textarg, int noctxt, Prog **jmpok)
 {
 	Prog *q, *q1;
-	uint32 moreconst1, moreconst2, i;
 	int cmp, lea, mov, sub;
 
+	USED(textarg);
 	cmp = ACMPQ;
 	lea = ALEAQ;
 	mov = AMOVQ;
@@ -682,35 +681,6 @@ stacksplit(Link *ctxt, Prog *p, int32 framesize, int32 textarg, int noctxt, Prog
 		sub = ASUBL;
 	}
 
-	if(ctxt->debugstack) {
-		// 6l -K means check not only for stack
-		// overflow but stack underflow.
-		// On underflow, INT 3 (breakpoint).
-		// Underflow itself is rare but this also
-		// catches out-of-sync stack guard info
-
-		p = appendp(ctxt, p);
-		p->as = cmp;
-		indir_cx(ctxt, &p->from);
-		p->from.offset = 8;
-		p->to.type = D_SP;
-
-		p = appendp(ctxt, p);
-		p->as = AJHI;
-		p->to.type = D_BRANCH;
-		p->to.offset = 4;
-		q1 = p;
-
-		p = appendp(ctxt, p);
-		p->as = AINT;
-		p->from.type = D_CONST;
-		p->from.offset = 3;
-
-		p = appendp(ctxt, p);
-		p->as = ANOP;
-		q1->pcond = p;
-	}
-
 	q1 = nil;
 	if(framesize <= StackSmall) {
 		// small stack: SP <= stackguard
@@ -719,6 +689,9 @@ stacksplit(Link *ctxt, Prog *p, int32 framesize, int32 textarg, int noctxt, Prog
 		p->as = cmp;
 		p->from.type = D_SP;
 		indir_cx(ctxt, &p->to);
+		p->to.offset = 2*ctxt->arch->ptrsize;	// G.stackguard0
+		if(ctxt->cursym->cfunc)
+			p->to.offset = 3*ctxt->arch->ptrsize;	// G.stackguard1
 	} else if(framesize <= StackBig) {
 		// large stack: SP-framesize <= stackguard-StackSmall
 		//	LEAQ -xxx(SP), AX
@@ -733,6 +706,9 @@ stacksplit(Link *ctxt, Prog *p, int32 framesize, int32 textarg, int noctxt, Prog
 		p->as = cmp;
 		p->from.type = D_AX;
 		indir_cx(ctxt, &p->to);
+		p->to.offset = 2*ctxt->arch->ptrsize;	// G.stackguard0
+		if(ctxt->cursym->cfunc)
+			p->to.offset = 3*ctxt->arch->ptrsize;	// G.stackguard1
 	} else {
 		// Such a large stack we need to protect against wraparound.
 		// If SP is close to zero:
@@ -752,7 +728,9 @@ stacksplit(Link *ctxt, Prog *p, int32 framesize, int32 textarg, int noctxt, Prog
 		p = appendp(ctxt, p);
 		p->as = mov;
 		indir_cx(ctxt, &p->from);
-		p->from.offset = 0;
+		p->from.offset = 2*ctxt->arch->ptrsize;	// G.stackguard0
+		if(ctxt->cursym->cfunc)
+			p->from.offset = 3*ctxt->arch->ptrsize;	// G.stackguard1
 		p->to.type = D_SI;
 
 		p = appendp(ctxt, p);
@@ -790,70 +768,13 @@ stacksplit(Link *ctxt, Prog *p, int32 framesize, int32 textarg, int noctxt, Prog
 	p->to.type = D_BRANCH;
 	q = p;
 
-	// If we ask for more stack, we'll get a minimum of StackMin bytes.
-	// We need a stack frame large enough to hold the top-of-stack data,
-	// the function arguments+results, our caller's PC, our frame,
-	// a word for the return PC of the next call, and then the StackLimit bytes
-	// that must be available on entry to any function called from a function
-	// that did a stack check.  If StackMin is enough, don't ask for a specific
-	// amount: then we can use the custom functions and save a few
-	// instructions.
-	moreconst1 = 0;
-	if(StackTop + textarg + ctxt->arch->ptrsize + framesize + ctxt->arch->ptrsize + StackLimit >= StackMin)
-		moreconst1 = framesize;
-	moreconst2 = textarg;
-	if(moreconst2 == 1) // special marker
-		moreconst2 = 0;
-	if((moreconst2&7) != 0)
-		ctxt->diag("misaligned argument size in stack split");
-	// 4 varieties varieties (const1==0 cross const2==0)
-	// and 6 subvarieties of (const1==0 and const2!=0)
 	p = appendp(ctxt, p);
-	if(moreconst1 == 0 && moreconst2 == 0) {
-		p->as = ACALL;
-		p->to.type = D_BRANCH;
-		p->to.sym = ctxt->symmorestack[0*2+noctxt];
-	} else
-	if(moreconst1 != 0 && moreconst2 == 0) {
-		p->as = AMOVL;
-		p->from.type = D_CONST;
-		p->from.offset = moreconst1;
-		p->to.type = D_AX;
-
-		p = appendp(ctxt, p);
-		p->as = ACALL;
-		p->to.type = D_BRANCH;
-		p->to.sym = ctxt->symmorestack[1*2+noctxt];
-	} else
-	if(moreconst1 == 0 && moreconst2 <= 48 && moreconst2%8 == 0) {
-		i = moreconst2/8 + 3;
-		p->as = ACALL;
-		p->to.type = D_BRANCH;
-		p->to.sym = ctxt->symmorestack[i*2+noctxt];
-	} else
-	if(moreconst1 == 0 && moreconst2 != 0) {
-		p->as = AMOVL;
-		p->from.type = D_CONST;
-		p->from.offset = moreconst2;
-		p->to.type = D_AX;
-
-		p = appendp(ctxt, p);
-		p->as = ACALL;
-		p->to.type = D_BRANCH;
-		p->to.sym = ctxt->symmorestack[2*2+noctxt];
-	} else {
-		// Pass framesize and argsize.
-		p->as = AMOVQ;
-		p->from.type = D_CONST;
-		p->from.offset = (uint64)moreconst2 << 32;
-		p->from.offset |= moreconst1;
-		p->to.type = D_AX;
-
-		p = appendp(ctxt, p);
-		p->as = ACALL;
-		p->to.type = D_BRANCH;
-		p->to.sym = ctxt->symmorestack[3*2+noctxt];
-	}
+	p->as = ACALL;
+	p->to.type = D_BRANCH;
+	if(ctxt->cursym->cfunc)
+		p->to.sym = linklookup(ctxt, "runtime.morestackc", 0);
+	else
+		p->to.sym = ctxt->symmorestack[noctxt];
 	
 	p = appendp(ctxt, p);
 	p->as = AJMP;
@@ -954,7 +875,7 @@ xfol(Link *ctxt, Prog *p, Prog **last)
 {
 	Prog *q;
 	int i;
-	enum as a;
+	int a;
 
 loop:
 	if(p == nil)
@@ -1083,6 +1004,7 @@ prg(void)
 LinkArch linkamd64 = {
 	.name = "amd64",
 	.thechar = '6',
+	.endian = LittleEndian,
 
 	.addstacksplit = addstacksplit,
 	.assemble = span6,
@@ -1128,6 +1050,7 @@ LinkArch linkamd64 = {
 LinkArch linkamd64p32 = {
 	.name = "amd64p32",
 	.thechar = '6',
+	.endian = LittleEndian,
 
 	.addstacksplit = addstacksplit,
 	.assemble = span6,
diff --git a/src/liblink/obj8.c b/src/liblink/obj8.c
index 72934c1..f54153a 100644
--- a/src/liblink/obj8.c
+++ b/src/liblink/obj8.c
@@ -33,7 +33,7 @@
 #include <bio.h>
 #include <link.h>
 #include "../cmd/8l/8.out.h"
-#include "../pkg/runtime/stack.h"
+#include "../runtime/stack.h"
 
 static Prog zprg = {
 	.back = 2,
@@ -261,7 +261,7 @@ static Prog*	stacksplit(Link*, Prog*, int32, int, Prog**);
 static void
 addstacksplit(Link *ctxt, LSym *cursym)
 {
-	Prog *p, *q;
+	Prog *p, *q, *p1, *p2;
 	int32 autoffset, deltasp;
 	int a;
 
@@ -270,8 +270,8 @@ addstacksplit(Link *ctxt, LSym *cursym)
 		ctxt->symmorestack[1] = linklookup(ctxt, "runtime.morestack_noctxt", 0);
 	}
 
-	if(ctxt->headtype == Hplan9 && ctxt->plan9tos == nil)
-		ctxt->plan9tos = linklookup(ctxt, "_tos", 0);
+	if(ctxt->headtype == Hplan9 && ctxt->plan9privates == nil)
+		ctxt->plan9privates = linklookup(ctxt, "_privates", 0);
 
 	ctxt->cursym = cursym;
 
@@ -317,13 +317,64 @@ addstacksplit(Link *ctxt, LSym *cursym)
 	deltasp = autoffset;
 	
 	if(cursym->text->from.scale & WRAPPER) {
-		// g->panicwrap += autoffset + ctxt->arch->ptrsize;
+		// if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame
+		//
+		//	MOVL g_panic(CX), BX
+		//	TESTL BX, BX
+		//	JEQ end
+		//	LEAL (autoffset+4)(SP), DI
+		//	CMPL panic_argp(BX), DI
+		//	JNE end
+		//	MOVL SP, panic_argp(BX)
+		// end:
+		//	NOP
+		//
+		// The NOP is needed to give the jumps somewhere to land.
+		// It is a liblink NOP, not an x86 NOP: it encodes to 0 instruction bytes.
+
 		p = appendp(ctxt, p);
-		p->as = AADDL;
-		p->from.type = D_CONST;
-		p->from.offset = autoffset + ctxt->arch->ptrsize;
-		p->to.type = D_INDIR+D_CX;
-		p->to.offset = 2*ctxt->arch->ptrsize;
+		p->as = AMOVL;
+		p->from.type = D_INDIR+D_CX;
+		p->from.offset = 4*ctxt->arch->ptrsize; // G.panic
+		p->to.type = D_BX;
+
+		p = appendp(ctxt, p);
+		p->as = ATESTL;
+		p->from.type = D_BX;
+		p->to.type = D_BX;
+
+		p = appendp(ctxt, p);
+		p->as = AJEQ;
+		p->to.type = D_BRANCH;
+		p1 = p;
+
+		p = appendp(ctxt, p);
+		p->as = ALEAL;
+		p->from.type = D_INDIR+D_SP;
+		p->from.offset = autoffset+4;
+		p->to.type = D_DI;
+
+		p = appendp(ctxt, p);
+		p->as = ACMPL;
+		p->from.type = D_INDIR+D_BX;
+		p->from.offset = 0; // Panic.argp
+		p->to.type = D_DI;
+
+		p = appendp(ctxt, p);
+		p->as = AJNE;
+		p->to.type = D_BRANCH;
+		p2 = p;
+
+		p = appendp(ctxt, p);
+		p->as = AMOVL;
+		p->from.type = D_SP;
+		p->to.type = D_INDIR+D_BX;
+		p->to.offset = 0; // Panic.argp
+
+		p = appendp(ctxt, p);
+		p->as = ANOP;
+		p1->pcond = p;
+		p2->pcond = p;
 	}
 	
 	if(ctxt->debugzerostack && autoffset && !(cursym->text->from.scale&NOSPLIT)) {
@@ -396,19 +447,6 @@ addstacksplit(Link *ctxt, LSym *cursym)
 		if(autoffset != deltasp)
 			ctxt->diag("unbalanced PUSH/POP");
 
-		if(cursym->text->from.scale & WRAPPER) {
-			p = load_g_cx(ctxt, p);
-			p = appendp(ctxt, p);
-			// g->panicwrap -= autoffset + ctxt->arch->ptrsize;
-			p->as = ASUBL;
-			p->from.type = D_CONST;
-			p->from.offset = autoffset + ctxt->arch->ptrsize;
-			p->to.type = D_INDIR+D_CX;
-			p->to.offset = 2*ctxt->arch->ptrsize;
-			p = appendp(ctxt, p);
-			p->as = ARET;
-		}
-
 		if(autoffset) {
 			p->as = AADJSP;
 			p->from.type = D_CONST;
@@ -463,7 +501,6 @@ static Prog*
 stacksplit(Link *ctxt, Prog *p, int32 framesize, int noctxt, Prog **jmpok)
 {
 	Prog *q, *q1;
-	int arg;
 
 	if(ctxt->debugstack) {
 		// 8l -K means check not only for stack
@@ -501,6 +538,9 @@ stacksplit(Link *ctxt, Prog *p, int32 framesize, int noctxt, Prog **jmpok)
 		p->as = ACMPL;
 		p->from.type = D_SP;
 		p->to.type = D_INDIR+D_CX;
+		p->to.offset = 2*ctxt->arch->ptrsize;	// G.stackguard0
+		if(ctxt->cursym->cfunc)
+			p->to.offset = 3*ctxt->arch->ptrsize;	// G.stackguard1
 	} else if(framesize <= StackBig) {
 		// large stack: SP-framesize <= stackguard-StackSmall
 		//	LEAL -(framesize-StackSmall)(SP), AX
@@ -515,6 +555,9 @@ stacksplit(Link *ctxt, Prog *p, int32 framesize, int noctxt, Prog **jmpok)
 		p->as = ACMPL;
 		p->from.type = D_AX;
 		p->to.type = D_INDIR+D_CX;
+		p->to.offset = 2*ctxt->arch->ptrsize;	// G.stackguard0
+		if(ctxt->cursym->cfunc)
+			p->to.offset = 3*ctxt->arch->ptrsize;	// G.stackguard1
 	} else {
 		// Such a large stack we need to protect against wraparound
 		// if SP is close to zero.
@@ -534,6 +577,9 @@ stacksplit(Link *ctxt, Prog *p, int32 framesize, int noctxt, Prog **jmpok)
 		p->as = AMOVL;
 		p->from.type = D_INDIR+D_CX;
 		p->from.offset = 0;
+		p->from.offset = 2*ctxt->arch->ptrsize;	// G.stackguard0
+		if(ctxt->cursym->cfunc)
+			p->from.offset = 3*ctxt->arch->ptrsize;	// G.stackguard1
 		p->to.type = D_SI;
 
 		p = appendp(ctxt, p);
@@ -573,37 +619,13 @@ stacksplit(Link *ctxt, Prog *p, int32 framesize, int noctxt, Prog **jmpok)
 	p->to.offset = 4;
 	q = p;
 
-	p = appendp(ctxt, p);	// save frame size in DI
-	p->as = AMOVL;
-	p->to.type = D_DI;
-	p->from.type = D_CONST;
-
-	// If we ask for more stack, we'll get a minimum of StackMin bytes.
-	// We need a stack frame large enough to hold the top-of-stack data,
-	// the function arguments+results, our caller's PC, our frame,
-	// a word for the return PC of the next call, and then the StackLimit bytes
-	// that must be available on entry to any function called from a function
-	// that did a stack check.  If StackMin is enough, don't ask for a specific
-	// amount: then we can use the custom functions and save a few
-	// instructions.
-	if(StackTop + ctxt->cursym->text->to.offset2 + ctxt->arch->ptrsize + framesize + ctxt->arch->ptrsize + StackLimit >= StackMin)
-		p->from.offset = (framesize+7) & ~7LL;
-
-	arg = ctxt->cursym->text->to.offset2;
-	if(arg == 1) // special marker for known 0
-		arg = 0;
-	if(arg&3)
-		ctxt->diag("misaligned argument size in stack split");
-	p = appendp(ctxt, p);	// save arg size in AX
-	p->as = AMOVL;
-	p->to.type = D_AX;
-	p->from.type = D_CONST;
-	p->from.offset = arg;
-
 	p = appendp(ctxt, p);
 	p->as = ACALL;
 	p->to.type = D_BRANCH;
-	p->to.sym = ctxt->symmorestack[noctxt];
+	if(ctxt->cursym->cfunc)
+		p->to.sym = linklookup(ctxt, "runtime.morestackc", 0);
+	else
+		p->to.sym = ctxt->symmorestack[noctxt];
 
 	p = appendp(ctxt, p);
 	p->as = AJMP;
@@ -697,7 +719,7 @@ xfol(Link *ctxt, Prog *p, Prog **last)
 {
 	Prog *q;
 	int i;
-	enum as a;
+	int a;
 
 loop:
 	if(p == nil)
@@ -816,6 +838,7 @@ loop:
 LinkArch link386 = {
 	.name = "386",
 	.thechar = '8',
+	.endian = LittleEndian,
 
 	.addstacksplit = addstacksplit,
 	.assemble = span8,
diff --git a/src/liblink/objfile.c b/src/liblink/objfile.c
index 610f879..b2478ec 100644
--- a/src/liblink/objfile.c
+++ b/src/liblink/objfile.c
@@ -38,7 +38,8 @@
 //	- type [int]
 //	- name [string]
 //	- version [int]
-//	- dupok [int]
+//	- flags [int]
+//		1 dupok
 //	- size [int]
 //	- gotype [symbol reference]
 //	- p [data block]
@@ -50,7 +51,9 @@
 //	- args [int]
 //	- locals [int]
 //	- nosplit [int]
-//	- leaf [int]
+//	- flags [int]
+//		1 leaf
+//		2 C function
 //	- nlocal [int]
 //	- local [nlocal automatics]
 //	- pcln [pcln table]
@@ -100,6 +103,7 @@
 #include <bio.h>
 #include <link.h>
 #include "../cmd/ld/textflag.h"
+#include "../runtime/funcdata.h"
 
 static void writesym(Link*, Biobuf*, LSym*);
 static void wrint(Biobuf*, int64);
@@ -121,7 +125,7 @@ static LSym *rdsym(Link*, Biobuf*, char*);
 void
 writeobj(Link *ctxt, Biobuf *b)
 {
-	int flag;
+	int flag, found;
 	Hist *h;
 	LSym *s, *text, *etext, *curtext, *data, *edata;
 	Plist *pl;
@@ -183,12 +187,7 @@ writeobj(Link *ctxt, Biobuf *b)
 				s->size = p->to.offset;
 				if(s->type == 0 || s->type == SXREF)
 					s->type = SBSS;
-				
-				if(ctxt->arch->thechar == '5')
-					flag = p->reg;
-				else
-					flag = p->from.scale;
-					
+				flag = ctxt->arch->textflag(p);
 				if(flag & DUPOK)
 					s->dupok = 1;
 				if(flag & RODATA)
@@ -221,10 +220,7 @@ writeobj(Link *ctxt, Biobuf *b)
 				else
 					etext->next = s;
 				etext = s;
-				if(ctxt->arch->thechar == '5')
-					flag = p->reg;
-				else
-					flag = p->from.scale;
+				flag = ctxt->arch->textflag(p);
 				if(flag & DUPOK)
 					s->dupok = 1;
 				if(flag & NOSPLIT)
@@ -237,6 +233,17 @@ writeobj(Link *ctxt, Biobuf *b)
 				continue;
 			}
 			
+			if(p->as == ctxt->arch->AFUNCDATA) {
+				// Rewrite reference to go_args_stackmap(SB) to the Go-provided declaration information.
+				if(curtext == nil) // func _() {}
+					continue;
+				if(strcmp(p->to.sym->name, "go_args_stackmap") == 0) {
+					if(p->from.type != ctxt->arch->D_CONST || p->from.offset != FUNCDATA_ArgsPointerMaps)
+						ctxt->diag("FUNCDATA use of go_args_stackmap(SB) without FUNCDATA_ArgsPointerMaps");
+					p->to.sym = linklookup(ctxt, smprint("%s.args_stackmap", curtext->name), curtext->version);
+				}
+			}
+			
 			if(curtext == nil)
 				continue;
 			s = curtext;
@@ -244,6 +251,32 @@ writeobj(Link *ctxt, Biobuf *b)
 			s->etext = p;
 		}
 	}
+	
+	// Add reference to Go arguments for C or assembly functions without them.
+	for(s = text; s != nil; s = s->next) {
+		if(strncmp(s->name, "\"\".", 3) != 0)
+			continue;
+		found = 0;
+		for(p = s->text; p != nil; p = p->link) {
+			if(p->as == ctxt->arch->AFUNCDATA && p->from.type == ctxt->arch->D_CONST && p->from.offset == FUNCDATA_ArgsPointerMaps) {
+				found = 1;
+				break;
+			}
+		}
+		if(!found) {
+			p = appendp(ctxt, s->text);
+			p->as = ctxt->arch->AFUNCDATA;
+			p->from.type = ctxt->arch->D_CONST;
+			p->from.offset = FUNCDATA_ArgsPointerMaps;
+			if(ctxt->arch->thechar == '6' || ctxt->arch->thechar == '8')
+				p->to.type = ctxt->arch->D_EXTERN;
+			else {
+				p->to.type = ctxt->arch->D_OREG;
+				p->to.name = ctxt->arch->D_EXTERN;
+			}
+			p->to.sym = linklookup(ctxt, smprint("%s.args_stackmap", s->name), s->version);
+		}
+	}
 
 	// Turn functions into machine code images.
 	for(s = text; s != nil; s = s->next) {
@@ -297,6 +330,8 @@ writesym(Link *ctxt, Biobuf *b, LSym *s)
 			Bprint(ctxt->bso, "t=%d ", s->type);
 		if(s->dupok)
 			Bprint(ctxt->bso, "dupok ");
+		if(s->cfunc)
+			Bprint(ctxt->bso, "cfunc ");
 		if(s->nosplit)
 			Bprint(ctxt->bso, "nosplit ");
 		Bprint(ctxt->bso, "size=%lld value=%lld", (vlong)s->size, (vlong)s->value);
@@ -359,7 +394,7 @@ writesym(Link *ctxt, Biobuf *b, LSym *s)
 		wrint(b, s->args);
 		wrint(b, s->locals);
 		wrint(b, s->nosplit);
-		wrint(b, s->leaf);
+		wrint(b, s->leaf | s->cfunc<<1);
 		n = 0;
 		for(a = s->autom; a != nil; a = a->link)
 			n++;
@@ -515,7 +550,7 @@ readsym(Link *ctxt, Biobuf *f, char *pkg, char *pn)
 	static int ndup;
 	char *name;
 	Reloc *r;
-	LSym *s, *dup;
+	LSym *s, *dup, *typ;
 	Pcln *pc;
 	Auto *a;
 	
@@ -527,6 +562,7 @@ readsym(Link *ctxt, Biobuf *f, char *pkg, char *pn)
 	if(v != 0 && v != 1)
 		sysfatal("invalid symbol version %d", v);
 	dupok = rdint(f);
+	dupok &= 1;
 	size = rdint(f);
 	
 	if(v != 0)
@@ -550,7 +586,11 @@ readsym(Link *ctxt, Biobuf *f, char *pkg, char *pn)
 	s->type = t;
 	if(s->size < size)
 		s->size = size;
-	s->gotype = rdsym(ctxt, f, pkg);
+	typ = rdsym(ctxt, f, pkg);
+	if(typ != nil) // if bss sym defined multiple times, take type from any one def
+		s->gotype = typ;
+	if(dup != nil && typ != nil)
+		dup->gotype = typ;
 	rddata(f, &s->p, &s->np);
 	s->maxp = s->np;
 	n = rdint(f);
@@ -581,7 +621,9 @@ readsym(Link *ctxt, Biobuf *f, char *pkg, char *pn)
 		s->args = rdint(f);
 		s->locals = rdint(f);
 		s->nosplit = rdint(f);
-		s->leaf = rdint(f);
+		v = rdint(f);
+		s->leaf = v&1;
+		s->cfunc = v&2;
 		n = rdint(f);
 		for(i=0; i<n; i++) {
 			a = emallocz(sizeof *a);
@@ -637,6 +679,8 @@ readsym(Link *ctxt, Biobuf *f, char *pkg, char *pn)
 			Bprint(ctxt->bso, "t=%d ", s->type);
 		if(s->dupok)
 			Bprint(ctxt->bso, "dupok ");
+		if(s->cfunc)
+			Bprint(ctxt->bso, "cfunc ");
 		if(s->nosplit)
 			Bprint(ctxt->bso, "nosplit ");
 		Bprint(ctxt->bso, "size=%lld value=%lld", (vlong)s->size, (vlong)s->value);
diff --git a/src/liblink/pcln.c b/src/liblink/pcln.c
index 4b2b855..f0ee1dc 100644
--- a/src/liblink/pcln.c
+++ b/src/liblink/pcln.c
@@ -279,7 +279,7 @@ linkpcln(Link *ctxt, LSym *cursym)
 	}
 	// pcdata.
 	for(i=0; i<npcdata; i++) {
-		if(!(havepc[i/32]>>(i%32))&1) 
+		if(((havepc[i/32]>>(i%32))&1) == 0) 
 			continue;
 		funcpctab(ctxt, &pcln->pcdata[i], cursym, "pctopcdata", pctopcdata, (void*)(uintptr)i);
 	}
diff --git a/src/liblink/sym.c b/src/liblink/sym.c
index cba50e9..bd85518 100644
--- a/src/liblink/sym.c
+++ b/src/liblink/sym.c
@@ -44,19 +44,20 @@ static struct {
 	char *name;
 	int val;
 } headers[] = {
-	"darwin",	Hdarwin,
-	"dragonfly",	Hdragonfly,
-	"elf",		Helf,
-	"freebsd",	Hfreebsd,
-	"linux",	Hlinux,
-	"nacl",		Hnacl,
-	"netbsd",	Hnetbsd,
-	"openbsd",	Hopenbsd,
-	"plan9",	Hplan9,
-	"solaris",	Hsolaris,
-	"windows",	Hwindows,
-	"windowsgui",	Hwindows,
-	0, 0
+	{"android",	Hlinux},
+	{"darwin",	Hdarwin},
+	{"dragonfly",	Hdragonfly},
+	{"elf",		Helf},
+	{"freebsd",	Hfreebsd},
+	{"linux",	Hlinux},
+	{"nacl",		Hnacl},
+	{"netbsd",	Hnetbsd},
+	{"openbsd",	Hopenbsd},
+	{"plan9",	Hplan9},
+	{"solaris",	Hsolaris},
+	{"windows",	Hwindows},
+	{"windowsgui",	Hwindows},
+	{0, 0},
 };
 
 int
@@ -90,7 +91,7 @@ linknew(LinkArch *arch)
 	char *p;
 	char buf[1024];
 
-	nuxiinit();
+	nuxiinit(arch);
 	
 	ctxt = emallocz(sizeof *ctxt);
 	ctxt->arch = arch;
@@ -127,8 +128,6 @@ linknew(LinkArch *arch)
 	default:
 		sysfatal("unknown thread-local storage offset for %s", headstr(ctxt->headtype));
 	case Hplan9:
-		ctxt->tlsoffset = -2*ctxt->arch->ptrsize;
-		break;
 	case Hwindows:
 		break;
 	case Hlinux:
@@ -155,13 +154,16 @@ linknew(LinkArch *arch)
 		case '8':
 			ctxt->tlsoffset = -8;
 			break;
+		case '5':
+			ctxt->tlsoffset = 0;
+			break;
 		}
 		break;
 
 	case Hdarwin:
 		/*
 		 * OS X system constants - offset from 0(GS) to our TLS.
-		 * Explained in ../../pkg/runtime/cgo/gcc_darwin_*.c.
+		 * Explained in ../../runtime/cgo/gcc_darwin_*.c.
 		 */
 		switch(ctxt->arch->thechar) {
 		default:
@@ -192,19 +194,14 @@ LSym*
 linknewsym(Link *ctxt, char *symb, int v)
 {
 	LSym *s;
-	int l;
 
-	l = strlen(symb) + 1;
 	s = malloc(sizeof(*s));
 	memset(s, 0, sizeof(*s));
 
 	s->dynid = -1;
 	s->plt = -1;
 	s->got = -1;
-	s->name = malloc(l + 1);
-	memmove(s->name, symb, l);
-	s->name[l] = '\0';
-
+	s->name = estrdup(symb);
 	s->type = 0;
 	s->version = v;
 	s->value = 0;
diff --git a/src/pkg/log/example_test.go b/src/log/example_test.go
similarity index 100%
rename from src/pkg/log/example_test.go
rename to src/log/example_test.go
diff --git a/src/pkg/log/log.go b/src/log/log.go
similarity index 100%
rename from src/pkg/log/log.go
rename to src/log/log.go
diff --git a/src/pkg/log/log_test.go b/src/log/log_test.go
similarity index 100%
rename from src/pkg/log/log_test.go
rename to src/log/log_test.go
diff --git a/src/pkg/log/syslog/syslog.go b/src/log/syslog/syslog.go
similarity index 100%
rename from src/pkg/log/syslog/syslog.go
rename to src/log/syslog/syslog.go
diff --git a/src/pkg/log/syslog/syslog_plan9.go b/src/log/syslog/syslog_plan9.go
similarity index 100%
rename from src/pkg/log/syslog/syslog_plan9.go
rename to src/log/syslog/syslog_plan9.go
diff --git a/src/log/syslog/syslog_test.go b/src/log/syslog/syslog_test.go
new file mode 100644
index 0000000..6a863fe
--- /dev/null
+++ b/src/log/syslog/syslog_test.go
@@ -0,0 +1,358 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !windows,!nacl,!plan9
+
+package syslog
+
+import (
+	"bufio"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"log"
+	"net"
+	"os"
+	"sync"
+	"testing"
+	"time"
+)
+
+func runPktSyslog(c net.PacketConn, done chan<- string) {
+	var buf [4096]byte
+	var rcvd string
+	ct := 0
+	for {
+		var n int
+		var err error
+
+		c.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
+		n, _, err = c.ReadFrom(buf[:])
+		rcvd += string(buf[:n])
+		if err != nil {
+			if oe, ok := err.(*net.OpError); ok {
+				if ct < 3 && oe.Temporary() {
+					ct++
+					continue
+				}
+			}
+			break
+		}
+	}
+	c.Close()
+	done <- rcvd
+}
+
+var crashy = false
+
+func runStreamSyslog(l net.Listener, done chan<- string, wg *sync.WaitGroup) {
+	for {
+		var c net.Conn
+		var err error
+		if c, err = l.Accept(); err != nil {
+			return
+		}
+		wg.Add(1)
+		go func(c net.Conn) {
+			defer wg.Done()
+			c.SetReadDeadline(time.Now().Add(5 * time.Second))
+			b := bufio.NewReader(c)
+			for ct := 1; !crashy || ct&7 != 0; ct++ {
+				s, err := b.ReadString('\n')
+				if err != nil {
+					break
+				}
+				done <- s
+			}
+			c.Close()
+		}(c)
+	}
+}
+
+func startServer(n, la string, done chan<- string) (addr string, sock io.Closer, wg *sync.WaitGroup) {
+	if n == "udp" || n == "tcp" {
+		la = "127.0.0.1:0"
+	} else {
+		// unix and unixgram: choose an address if none given
+		if la == "" {
+			// use ioutil.TempFile to get a name that is unique
+			f, err := ioutil.TempFile("", "syslogtest")
+			if err != nil {
+				log.Fatal("TempFile: ", err)
+			}
+			f.Close()
+			la = f.Name()
+		}
+		os.Remove(la)
+	}
+
+	wg = new(sync.WaitGroup)
+	if n == "udp" || n == "unixgram" {
+		l, e := net.ListenPacket(n, la)
+		if e != nil {
+			log.Fatalf("startServer failed: %v", e)
+		}
+		addr = l.LocalAddr().String()
+		sock = l
+		wg.Add(1)
+		go func() {
+			defer wg.Done()
+			runPktSyslog(l, done)
+		}()
+	} else {
+		l, e := net.Listen(n, la)
+		if e != nil {
+			log.Fatalf("startServer failed: %v", e)
+		}
+		addr = l.Addr().String()
+		sock = l
+		wg.Add(1)
+		go func() {
+			defer wg.Done()
+			runStreamSyslog(l, done, wg)
+		}()
+	}
+	return
+}
+
+func TestWithSimulated(t *testing.T) {
+	msg := "Test 123"
+	transport := []string{"unix", "unixgram", "udp", "tcp"}
+
+	for _, tr := range transport {
+		done := make(chan string)
+		addr, sock, srvWG := startServer(tr, "", done)
+		defer srvWG.Wait()
+		defer sock.Close()
+		if tr == "unix" || tr == "unixgram" {
+			defer os.Remove(addr)
+		}
+		s, err := Dial(tr, addr, LOG_INFO|LOG_USER, "syslog_test")
+		if err != nil {
+			t.Fatalf("Dial() failed: %v", err)
+		}
+		err = s.Info(msg)
+		if err != nil {
+			t.Fatalf("log failed: %v", err)
+		}
+		check(t, msg, <-done)
+		s.Close()
+	}
+}
+
+func TestFlap(t *testing.T) {
+	net := "unix"
+	done := make(chan string)
+	addr, sock, srvWG := startServer(net, "", done)
+	defer srvWG.Wait()
+	defer os.Remove(addr)
+	defer sock.Close()
+
+	s, err := Dial(net, addr, LOG_INFO|LOG_USER, "syslog_test")
+	if err != nil {
+		t.Fatalf("Dial() failed: %v", err)
+	}
+	msg := "Moo 2"
+	err = s.Info(msg)
+	if err != nil {
+		t.Fatalf("log failed: %v", err)
+	}
+	check(t, msg, <-done)
+
+	// restart the server
+	_, sock2, srvWG2 := startServer(net, addr, done)
+	defer srvWG2.Wait()
+	defer sock2.Close()
+
+	// and try retransmitting
+	msg = "Moo 3"
+	err = s.Info(msg)
+	if err != nil {
+		t.Fatalf("log failed: %v", err)
+	}
+	check(t, msg, <-done)
+
+	s.Close()
+}
+
+func TestNew(t *testing.T) {
+	if LOG_LOCAL7 != 23<<3 {
+		t.Fatalf("LOG_LOCAL7 has wrong value")
+	}
+	if testing.Short() {
+		// Depends on syslog daemon running, and sometimes it's not.
+		t.Skip("skipping syslog test during -short")
+	}
+
+	s, err := New(LOG_INFO|LOG_USER, "the_tag")
+	if err != nil {
+		t.Fatalf("New() failed: %s", err)
+	}
+	// Don't send any messages.
+	s.Close()
+}
+
+func TestNewLogger(t *testing.T) {
+	if testing.Short() {
+		t.Skip("skipping syslog test during -short")
+	}
+	f, err := NewLogger(LOG_USER|LOG_INFO, 0)
+	if f == nil {
+		t.Error(err)
+	}
+}
+
+func TestDial(t *testing.T) {
+	if testing.Short() {
+		t.Skip("skipping syslog test during -short")
+	}
+	f, err := Dial("", "", (LOG_LOCAL7|LOG_DEBUG)+1, "syslog_test")
+	if f != nil {
+		t.Fatalf("Should have trapped bad priority")
+	}
+	f, err = Dial("", "", -1, "syslog_test")
+	if f != nil {
+		t.Fatalf("Should have trapped bad priority")
+	}
+	l, err := Dial("", "", LOG_USER|LOG_ERR, "syslog_test")
+	if err != nil {
+		t.Fatalf("Dial() failed: %s", err)
+	}
+	l.Close()
+}
+
+func check(t *testing.T, in, out string) {
+	tmpl := fmt.Sprintf("<%d>%%s %%s syslog_test[%%d]: %s\n", LOG_USER+LOG_INFO, in)
+	if hostname, err := os.Hostname(); err != nil {
+		t.Error("Error retrieving hostname")
+	} else {
+		var parsedHostname, timestamp string
+		var pid int
+		if n, err := fmt.Sscanf(out, tmpl, &timestamp, &parsedHostname, &pid); n != 3 || err != nil || hostname != parsedHostname {
+			t.Errorf("Got %q, does not match template %q (%d %s)", out, tmpl, n, err)
+		}
+	}
+}
+
+func TestWrite(t *testing.T) {
+	tests := []struct {
+		pri Priority
+		pre string
+		msg string
+		exp string
+	}{
+		{LOG_USER | LOG_ERR, "syslog_test", "", "%s %s syslog_test[%d]: \n"},
+		{LOG_USER | LOG_ERR, "syslog_test", "write test", "%s %s syslog_test[%d]: write test\n"},
+		// Write should not add \n if there already is one
+		{LOG_USER | LOG_ERR, "syslog_test", "write test 2\n", "%s %s syslog_test[%d]: write test 2\n"},
+	}
+
+	if hostname, err := os.Hostname(); err != nil {
+		t.Fatalf("Error retrieving hostname")
+	} else {
+		for _, test := range tests {
+			done := make(chan string)
+			addr, sock, srvWG := startServer("udp", "", done)
+			defer srvWG.Wait()
+			defer sock.Close()
+			l, err := Dial("udp", addr, test.pri, test.pre)
+			if err != nil {
+				t.Fatalf("syslog.Dial() failed: %v", err)
+			}
+			defer l.Close()
+			_, err = io.WriteString(l, test.msg)
+			if err != nil {
+				t.Fatalf("WriteString() failed: %v", err)
+			}
+			rcvd := <-done
+			test.exp = fmt.Sprintf("<%d>", test.pri) + test.exp
+			var parsedHostname, timestamp string
+			var pid int
+			if n, err := fmt.Sscanf(rcvd, test.exp, &timestamp, &parsedHostname, &pid); n != 3 || err != nil || hostname != parsedHostname {
+				t.Errorf("s.Info() = '%q', didn't match '%q' (%d %s)", rcvd, test.exp, n, err)
+			}
+		}
+	}
+}
+
+func TestConcurrentWrite(t *testing.T) {
+	addr, sock, srvWG := startServer("udp", "", make(chan string, 1))
+	defer srvWG.Wait()
+	defer sock.Close()
+	w, err := Dial("udp", addr, LOG_USER|LOG_ERR, "how's it going?")
+	if err != nil {
+		t.Fatalf("syslog.Dial() failed: %v", err)
+	}
+	var wg sync.WaitGroup
+	for i := 0; i < 10; i++ {
+		wg.Add(1)
+		go func() {
+			defer wg.Done()
+			err := w.Info("test")
+			if err != nil {
+				t.Errorf("Info() failed: %v", err)
+				return
+			}
+		}()
+	}
+	wg.Wait()
+}
+
+func TestConcurrentReconnect(t *testing.T) {
+	crashy = true
+	defer func() { crashy = false }()
+
+	const N = 10
+	const M = 100
+	net := "unix"
+	done := make(chan string, N*M)
+	addr, sock, srvWG := startServer(net, "", done)
+	defer os.Remove(addr)
+
+	// count all the messages arriving
+	count := make(chan int)
+	go func() {
+		ct := 0
+		for range done {
+			ct++
+			// we are looking for 500 out of 1000 events
+			// here because lots of log messages are lost
+			// in buffers (kernel and/or bufio)
+			if ct > N*M/2 {
+				break
+			}
+		}
+		count <- ct
+	}()
+
+	var wg sync.WaitGroup
+	wg.Add(N)
+	for i := 0; i < N; i++ {
+		go func() {
+			defer wg.Done()
+			w, err := Dial(net, addr, LOG_USER|LOG_ERR, "tag")
+			if err != nil {
+				t.Fatalf("syslog.Dial() failed: %v", err)
+			}
+			defer w.Close()
+			for i := 0; i < M; i++ {
+				err := w.Info("test")
+				if err != nil {
+					t.Errorf("Info() failed: %v", err)
+					return
+				}
+			}
+		}()
+	}
+	wg.Wait()
+	sock.Close()
+	srvWG.Wait()
+	close(done)
+
+	select {
+	case <-count:
+	case <-time.After(100 * time.Millisecond):
+		t.Error("timeout in concurrent reconnect")
+	}
+}
diff --git a/src/log/syslog/syslog_unix.go b/src/log/syslog/syslog_unix.go
new file mode 100644
index 0000000..1cdabec
--- /dev/null
+++ b/src/log/syslog/syslog_unix.go
@@ -0,0 +1,31 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !windows,!nacl,!plan9
+
+package syslog
+
+import (
+	"errors"
+	"net"
+)
+
+// unixSyslog opens a connection to the syslog daemon running on the
+// local machine using a Unix domain socket.
+
+func unixSyslog() (conn serverConn, err error) {
+	logTypes := []string{"unixgram", "unix"}
+	logPaths := []string{"/dev/log", "/var/run/syslog", "/var/run/log"}
+	for _, network := range logTypes {
+		for _, path := range logPaths {
+			conn, err := net.Dial(network, path)
+			if err != nil {
+				continue
+			} else {
+				return &netConn{conn: conn, local: true}, nil
+			}
+		}
+	}
+	return nil, errors.New("Unix syslog delivery error")
+}
diff --git a/src/pkg/log/syslog/syslog_windows.go b/src/log/syslog/syslog_windows.go
similarity index 100%
rename from src/pkg/log/syslog/syslog_windows.go
rename to src/log/syslog/syslog_windows.go
diff --git a/src/make.bash b/src/make.bash
index d7b63ff..fbc6f5d 100755
--- a/src/make.bash
+++ b/src/make.bash
@@ -106,7 +106,7 @@ if [ "$(uname -s)" == "GNU/kFreeBSD" ]; then
 fi
 
 # Clean old generated file that will cause problems in the build.
-rm -f ./pkg/runtime/runtime_defs.go
+rm -f ./runtime/runtime_defs.go
 
 # Finally!  Run the build.
 
diff --git a/src/make.bat b/src/make.bat
index 23b799e..fff1eb6 100644
--- a/src/make.bat
+++ b/src/make.bat
@@ -60,7 +60,7 @@ echo # Building C bootstrap tool.
 echo cmd/dist
 if not exist ..\bin\tool mkdir ..\bin\tool
 :: Windows has no glob expansion, so spell out cmd/dist/*.c.
-gcc -O2 -Wall -Werror -o cmd/dist/dist.exe -Icmd/dist %DEFGOROOT% cmd/dist/buf.c cmd/dist/build.c cmd/dist/buildgc.c cmd/dist/buildgo.c cmd/dist/buildruntime.c cmd/dist/goc2c.c cmd/dist/main.c cmd/dist/windows.c cmd/dist/arm.c
+gcc -O2 -Wall -Werror -o cmd/dist/dist.exe -Icmd/dist %DEFGOROOT% cmd/dist/buf.c cmd/dist/build.c cmd/dist/buildgc.c cmd/dist/buildgo.c cmd/dist/buildruntime.c cmd/dist/main.c cmd/dist/windows.c cmd/dist/arm.c
 if errorlevel 1 goto fail
 .\cmd\dist\dist env -wp >env.bat
 if errorlevel 1 goto fail
@@ -115,5 +115,6 @@ goto end
 
 :fail
 set GOBUILDFAIL=1
+if x%GOBUILDEXIT%==x1 exit %GOBUILDFAIL%
 
 :end
diff --git a/src/make.rc b/src/make.rc
index ab152c0..7a62d6a 100755
--- a/src/make.rc
+++ b/src/make.rc
@@ -40,7 +40,7 @@ if(! test -f run.rc){
 ../include/plan9/mklibc.rc > ../include/plan9/libc_plan9.h
 
 # Clean old generated file that will cause problems in the build.
-rm -f ./pkg/runtime/runtime_defs.go
+rm -f ./runtime/runtime_defs.go
 
 # Determine the host compiler toolchain.
 eval `{grep '^(CC|LD|O)=' /$objtype/mkfile}
diff --git a/src/pkg/math/abs.go b/src/math/abs.go
similarity index 100%
rename from src/pkg/math/abs.go
rename to src/math/abs.go
diff --git a/src/math/abs_386.s b/src/math/abs_386.s
new file mode 100644
index 0000000..f30a439
--- /dev/null
+++ b/src/math/abs_386.s
@@ -0,0 +1,12 @@
+// Copyright 2010 The Go 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 Abs(x float64) float64
+TEXT ·Abs(SB),NOSPLIT,$0
+	FMOVD   x+0(FP), F0  // F0=x
+	FABS                 // F0=|x|
+	FMOVDP  F0, ret+8(FP)
+	RET
diff --git a/src/math/abs_amd64.s b/src/math/abs_amd64.s
new file mode 100644
index 0000000..0424eb5
--- /dev/null
+++ b/src/math/abs_amd64.s
@@ -0,0 +1,14 @@
+// Copyright 2010 The Go 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 Abs(x float64) float64
+TEXT ·Abs(SB),NOSPLIT,$0
+	MOVQ   $(1<<63), BX
+	MOVQ   BX, X0 // movsd $(-0.0), x0
+	MOVSD  x+0(FP), X1
+	ANDNPD X1, X0
+	MOVSD  X0, ret+8(FP)
+	RET
diff --git a/src/pkg/math/abs_amd64p32.s b/src/math/abs_amd64p32.s
similarity index 100%
rename from src/pkg/math/abs_amd64p32.s
rename to src/math/abs_amd64p32.s
diff --git a/src/math/abs_arm.s b/src/math/abs_arm.s
new file mode 100644
index 0000000..bfa77eb
--- /dev/null
+++ b/src/math/abs_arm.s
@@ -0,0 +1,13 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+TEXT ·Abs(SB),NOSPLIT,$0
+	MOVW	x_lo+0(FP), R0
+	MOVW	x_hi+4(FP), R1
+	AND 	$((1<<31)-1), R1
+	MOVW	R0, ret_lo+8(FP)
+	MOVW	R1, ret_hi+12(FP)
+	RET
diff --git a/src/pkg/math/acosh.go b/src/math/acosh.go
similarity index 100%
rename from src/pkg/math/acosh.go
rename to src/math/acosh.go
diff --git a/src/math/all_test.go b/src/math/all_test.go
new file mode 100644
index 0000000..763efb2
--- /dev/null
+++ b/src/math/all_test.go
@@ -0,0 +1,2992 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package math_test
+
+import (
+	"fmt"
+	. "math"
+	"testing"
+)
+
+var vf = []float64{
+	4.9790119248836735e+00,
+	7.7388724745781045e+00,
+	-2.7688005719200159e-01,
+	-5.0106036182710749e+00,
+	9.6362937071984173e+00,
+	2.9263772392439646e+00,
+	5.2290834314593066e+00,
+	2.7279399104360102e+00,
+	1.8253080916808550e+00,
+	-8.6859247685756013e+00,
+}
+
+// The expected results below were computed by the high precision calculators
+// at http://keisan.casio.com/.  More exact input values (array vf[], above)
+// were obtained by printing them with "%.26f".  The answers were calculated
+// to 26 digits (by using the "Digit number" drop-down control of each
+// calculator).
+var acos = []float64{
+	1.0496193546107222142571536e+00,
+	6.8584012813664425171660692e-01,
+	1.5984878714577160325521819e+00,
+	2.0956199361475859327461799e+00,
+	2.7053008467824138592616927e-01,
+	1.2738121680361776018155625e+00,
+	1.0205369421140629186287407e+00,
+	1.2945003481781246062157835e+00,
+	1.3872364345374451433846657e+00,
+	2.6231510803970463967294145e+00,
+}
+var acosh = []float64{
+	2.4743347004159012494457618e+00,
+	2.8576385344292769649802701e+00,
+	7.2796961502981066190593175e-01,
+	2.4796794418831451156471977e+00,
+	3.0552020742306061857212962e+00,
+	2.044238592688586588942468e+00,
+	2.5158701513104513595766636e+00,
+	1.99050839282411638174299e+00,
+	1.6988625798424034227205445e+00,
+	2.9611454842470387925531875e+00,
+}
+var asin = []float64{
+	5.2117697218417440497416805e-01,
+	8.8495619865825236751471477e-01,
+	-02.769154466281941332086016e-02,
+	-5.2482360935268931351485822e-01,
+	1.3002662421166552333051524e+00,
+	2.9698415875871901741575922e-01,
+	5.5025938468083370060258102e-01,
+	2.7629597861677201301553823e-01,
+	1.83559892257451475846656e-01,
+	-1.0523547536021497774980928e+00,
+}
+var asinh = []float64{
+	2.3083139124923523427628243e+00,
+	2.743551594301593620039021e+00,
+	-2.7345908534880091229413487e-01,
+	-2.3145157644718338650499085e+00,
+	2.9613652154015058521951083e+00,
+	1.7949041616585821933067568e+00,
+	2.3564032905983506405561554e+00,
+	1.7287118790768438878045346e+00,
+	1.3626658083714826013073193e+00,
+	-2.8581483626513914445234004e+00,
+}
+var atan = []float64{
+	1.372590262129621651920085e+00,
+	1.442290609645298083020664e+00,
+	-2.7011324359471758245192595e-01,
+	-1.3738077684543379452781531e+00,
+	1.4673921193587666049154681e+00,
+	1.2415173565870168649117764e+00,
+	1.3818396865615168979966498e+00,
+	1.2194305844639670701091426e+00,
+	1.0696031952318783760193244e+00,
+	-1.4561721938838084990898679e+00,
+}
+var atanh = []float64{
+	5.4651163712251938116878204e-01,
+	1.0299474112843111224914709e+00,
+	-2.7695084420740135145234906e-02,
+	-5.5072096119207195480202529e-01,
+	1.9943940993171843235906642e+00,
+	3.01448604578089708203017e-01,
+	5.8033427206942188834370595e-01,
+	2.7987997499441511013958297e-01,
+	1.8459947964298794318714228e-01,
+	-1.3273186910532645867272502e+00,
+}
+var atan2 = []float64{
+	1.1088291730037004444527075e+00,
+	9.1218183188715804018797795e-01,
+	1.5984772603216203736068915e+00,
+	2.0352918654092086637227327e+00,
+	8.0391819139044720267356014e-01,
+	1.2861075249894661588866752e+00,
+	1.0889904479131695712182587e+00,
+	1.3044821793397925293797357e+00,
+	1.3902530903455392306872261e+00,
+	2.2859857424479142655411058e+00,
+}
+var cbrt = []float64{
+	1.7075799841925094446722675e+00,
+	1.9779982212970353936691498e+00,
+	-6.5177429017779910853339447e-01,
+	-1.7111838886544019873338113e+00,
+	2.1279920909827937423960472e+00,
+	1.4303536770460741452312367e+00,
+	1.7357021059106154902341052e+00,
+	1.3972633462554328350552916e+00,
+	1.2221149580905388454977636e+00,
+	-2.0556003730500069110343596e+00,
+}
+var ceil = []float64{
+	5.0000000000000000e+00,
+	8.0000000000000000e+00,
+	0.0000000000000000e+00,
+	-5.0000000000000000e+00,
+	1.0000000000000000e+01,
+	3.0000000000000000e+00,
+	6.0000000000000000e+00,
+	3.0000000000000000e+00,
+	2.0000000000000000e+00,
+	-8.0000000000000000e+00,
+}
+var copysign = []float64{
+	-4.9790119248836735e+00,
+	-7.7388724745781045e+00,
+	-2.7688005719200159e-01,
+	-5.0106036182710749e+00,
+	-9.6362937071984173e+00,
+	-2.9263772392439646e+00,
+	-5.2290834314593066e+00,
+	-2.7279399104360102e+00,
+	-1.8253080916808550e+00,
+	-8.6859247685756013e+00,
+}
+var cos = []float64{
+	2.634752140995199110787593e-01,
+	1.148551260848219865642039e-01,
+	9.6191297325640768154550453e-01,
+	2.938141150061714816890637e-01,
+	-9.777138189897924126294461e-01,
+	-9.7693041344303219127199518e-01,
+	4.940088096948647263961162e-01,
+	-9.1565869021018925545016502e-01,
+	-2.517729313893103197176091e-01,
+	-7.39241351595676573201918e-01,
+}
+
+// Results for 100000 * Pi + vf[i]
+var cosLarge = []float64{
+	2.634752141185559426744e-01,
+	1.14855126055543100712e-01,
+	9.61912973266488928113e-01,
+	2.9381411499556122552e-01,
+	-9.777138189880161924641e-01,
+	-9.76930413445147608049e-01,
+	4.940088097314976789841e-01,
+	-9.15658690217517835002e-01,
+	-2.51772931436786954751e-01,
+	-7.3924135157173099849e-01,
+}
+var cosh = []float64{
+	7.2668796942212842775517446e+01,
+	1.1479413465659254502011135e+03,
+	1.0385767908766418550935495e+00,
+	7.5000957789658051428857788e+01,
+	7.655246669605357888468613e+03,
+	9.3567491758321272072888257e+00,
+	9.331351599270605471131735e+01,
+	7.6833430994624643209296404e+00,
+	3.1829371625150718153881164e+00,
+	2.9595059261916188501640911e+03,
+}
+var erf = []float64{
+	5.1865354817738701906913566e-01,
+	7.2623875834137295116929844e-01,
+	-3.123458688281309990629839e-02,
+	-5.2143121110253302920437013e-01,
+	8.2704742671312902508629582e-01,
+	3.2101767558376376743993945e-01,
+	5.403990312223245516066252e-01,
+	3.0034702916738588551174831e-01,
+	2.0369924417882241241559589e-01,
+	-7.8069386968009226729944677e-01,
+}
+var erfc = []float64{
+	4.8134645182261298093086434e-01,
+	2.7376124165862704883070156e-01,
+	1.0312345868828130999062984e+00,
+	1.5214312111025330292043701e+00,
+	1.7295257328687097491370418e-01,
+	6.7898232441623623256006055e-01,
+	4.596009687776754483933748e-01,
+	6.9965297083261411448825169e-01,
+	7.9630075582117758758440411e-01,
+	1.7806938696800922672994468e+00,
+}
+var exp = []float64{
+	1.4533071302642137507696589e+02,
+	2.2958822575694449002537581e+03,
+	7.5814542574851666582042306e-01,
+	6.6668778421791005061482264e-03,
+	1.5310493273896033740861206e+04,
+	1.8659907517999328638667732e+01,
+	1.8662167355098714543942057e+02,
+	1.5301332413189378961665788e+01,
+	6.2047063430646876349125085e+00,
+	1.6894712385826521111610438e-04,
+}
+var expm1 = []float64{
+	5.105047796122957327384770212e-02,
+	8.046199708567344080562675439e-02,
+	-2.764970978891639815187418703e-03,
+	-4.8871434888875355394330300273e-02,
+	1.0115864277221467777117227494e-01,
+	2.969616407795910726014621657e-02,
+	5.368214487944892300914037972e-02,
+	2.765488851131274068067445335e-02,
+	1.842068661871398836913874273e-02,
+	-8.3193870863553801814961137573e-02,
+}
+var exp2 = []float64{
+	3.1537839463286288034313104e+01,
+	2.1361549283756232296144849e+02,
+	8.2537402562185562902577219e-01,
+	3.1021158628740294833424229e-02,
+	7.9581744110252191462569661e+02,
+	7.6019905892596359262696423e+00,
+	3.7506882048388096973183084e+01,
+	6.6250893439173561733216375e+00,
+	3.5438267900243941544605339e+00,
+	2.4281533133513300984289196e-03,
+}
+var fabs = []float64{
+	4.9790119248836735e+00,
+	7.7388724745781045e+00,
+	2.7688005719200159e-01,
+	5.0106036182710749e+00,
+	9.6362937071984173e+00,
+	2.9263772392439646e+00,
+	5.2290834314593066e+00,
+	2.7279399104360102e+00,
+	1.8253080916808550e+00,
+	8.6859247685756013e+00,
+}
+var fdim = []float64{
+	4.9790119248836735e+00,
+	7.7388724745781045e+00,
+	0.0000000000000000e+00,
+	0.0000000000000000e+00,
+	9.6362937071984173e+00,
+	2.9263772392439646e+00,
+	5.2290834314593066e+00,
+	2.7279399104360102e+00,
+	1.8253080916808550e+00,
+	0.0000000000000000e+00,
+}
+var floor = []float64{
+	4.0000000000000000e+00,
+	7.0000000000000000e+00,
+	-1.0000000000000000e+00,
+	-6.0000000000000000e+00,
+	9.0000000000000000e+00,
+	2.0000000000000000e+00,
+	5.0000000000000000e+00,
+	2.0000000000000000e+00,
+	1.0000000000000000e+00,
+	-9.0000000000000000e+00,
+}
+var fmod = []float64{
+	4.197615023265299782906368e-02,
+	2.261127525421895434476482e+00,
+	3.231794108794261433104108e-02,
+	4.989396381728925078391512e+00,
+	3.637062928015826201999516e-01,
+	1.220868282268106064236690e+00,
+	4.770916568540693347699744e+00,
+	1.816180268691969246219742e+00,
+	8.734595415957246977711748e-01,
+	1.314075231424398637614104e+00,
+}
+
+type fi struct {
+	f float64
+	i int
+}
+
+var frexp = []fi{
+	{6.2237649061045918750e-01, 3},
+	{9.6735905932226306250e-01, 3},
+	{-5.5376011438400318000e-01, -1},
+	{-6.2632545228388436250e-01, 3},
+	{6.02268356699901081250e-01, 4},
+	{7.3159430981099115000e-01, 2},
+	{6.5363542893241332500e-01, 3},
+	{6.8198497760900255000e-01, 2},
+	{9.1265404584042750000e-01, 1},
+	{-5.4287029803597508250e-01, 4},
+}
+var gamma = []float64{
+	2.3254348370739963835386613898e+01,
+	2.991153837155317076427529816e+03,
+	-4.561154336726758060575129109e+00,
+	7.719403468842639065959210984e-01,
+	1.6111876618855418534325755566e+05,
+	1.8706575145216421164173224946e+00,
+	3.4082787447257502836734201635e+01,
+	1.579733951448952054898583387e+00,
+	9.3834586598354592860187267089e-01,
+	-2.093995902923148389186189429e-05,
+}
+var j0 = []float64{
+	-1.8444682230601672018219338e-01,
+	2.27353668906331975435892e-01,
+	9.809259936157051116270273e-01,
+	-1.741170131426226587841181e-01,
+	-2.1389448451144143352039069e-01,
+	-2.340905848928038763337414e-01,
+	-1.0029099691890912094586326e-01,
+	-1.5466726714884328135358907e-01,
+	3.252650187653420388714693e-01,
+	-8.72218484409407250005360235e-03,
+}
+var j1 = []float64{
+	-3.251526395295203422162967e-01,
+	1.893581711430515718062564e-01,
+	-1.3711761352467242914491514e-01,
+	3.287486536269617297529617e-01,
+	1.3133899188830978473849215e-01,
+	3.660243417832986825301766e-01,
+	-3.4436769271848174665420672e-01,
+	4.329481396640773768835036e-01,
+	5.8181350531954794639333955e-01,
+	-2.7030574577733036112996607e-01,
+}
+var j2 = []float64{
+	5.3837518920137802565192769e-02,
+	-1.7841678003393207281244667e-01,
+	9.521746934916464142495821e-03,
+	4.28958355470987397983072e-02,
+	2.4115371837854494725492872e-01,
+	4.842458532394520316844449e-01,
+	-3.142145220618633390125946e-02,
+	4.720849184745124761189957e-01,
+	3.122312022520957042957497e-01,
+	7.096213118930231185707277e-02,
+}
+var jM3 = []float64{
+	-3.684042080996403091021151e-01,
+	2.8157665936340887268092661e-01,
+	4.401005480841948348343589e-04,
+	3.629926999056814081597135e-01,
+	3.123672198825455192489266e-02,
+	-2.958805510589623607540455e-01,
+	-3.2033177696533233403289416e-01,
+	-2.592737332129663376736604e-01,
+	-1.0241334641061485092351251e-01,
+	-2.3762660886100206491674503e-01,
+}
+var lgamma = []fi{
+	{3.146492141244545774319734e+00, 1},
+	{8.003414490659126375852113e+00, 1},
+	{1.517575735509779707488106e+00, -1},
+	{-2.588480028182145853558748e-01, 1},
+	{1.1989897050205555002007985e+01, 1},
+	{6.262899811091257519386906e-01, 1},
+	{3.5287924899091566764846037e+00, 1},
+	{4.5725644770161182299423372e-01, 1},
+	{-6.363667087767961257654854e-02, 1},
+	{-1.077385130910300066425564e+01, -1},
+}
+var log = []float64{
+	1.605231462693062999102599e+00,
+	2.0462560018708770653153909e+00,
+	-1.2841708730962657801275038e+00,
+	1.6115563905281545116286206e+00,
+	2.2655365644872016636317461e+00,
+	1.0737652208918379856272735e+00,
+	1.6542360106073546632707956e+00,
+	1.0035467127723465801264487e+00,
+	6.0174879014578057187016475e-01,
+	2.161703872847352815363655e+00,
+}
+var logb = []float64{
+	2.0000000000000000e+00,
+	2.0000000000000000e+00,
+	-2.0000000000000000e+00,
+	2.0000000000000000e+00,
+	3.0000000000000000e+00,
+	1.0000000000000000e+00,
+	2.0000000000000000e+00,
+	1.0000000000000000e+00,
+	0.0000000000000000e+00,
+	3.0000000000000000e+00,
+}
+var log10 = []float64{
+	6.9714316642508290997617083e-01,
+	8.886776901739320576279124e-01,
+	-5.5770832400658929815908236e-01,
+	6.998900476822994346229723e-01,
+	9.8391002850684232013281033e-01,
+	4.6633031029295153334285302e-01,
+	7.1842557117242328821552533e-01,
+	4.3583479968917773161304553e-01,
+	2.6133617905227038228626834e-01,
+	9.3881606348649405716214241e-01,
+}
+var log1p = []float64{
+	4.8590257759797794104158205e-02,
+	7.4540265965225865330849141e-02,
+	-2.7726407903942672823234024e-03,
+	-5.1404917651627649094953380e-02,
+	9.1998280672258624681335010e-02,
+	2.8843762576593352865894824e-02,
+	5.0969534581863707268992645e-02,
+	2.6913947602193238458458594e-02,
+	1.8088493239630770262045333e-02,
+	-9.0865245631588989681559268e-02,
+}
+var log2 = []float64{
+	2.3158594707062190618898251e+00,
+	2.9521233862883917703341018e+00,
+	-1.8526669502700329984917062e+00,
+	2.3249844127278861543568029e+00,
+	3.268478366538305087466309e+00,
+	1.5491157592596970278166492e+00,
+	2.3865580889631732407886495e+00,
+	1.447811865817085365540347e+00,
+	8.6813999540425116282815557e-01,
+	3.118679457227342224364709e+00,
+}
+var modf = [][2]float64{
+	{4.0000000000000000e+00, 9.7901192488367350108546816e-01},
+	{7.0000000000000000e+00, 7.3887247457810456552351752e-01},
+	{0.0000000000000000e+00, -2.7688005719200159404635997e-01},
+	{-5.0000000000000000e+00, -1.060361827107492160848778e-02},
+	{9.0000000000000000e+00, 6.3629370719841737980004837e-01},
+	{2.0000000000000000e+00, 9.2637723924396464525443662e-01},
+	{5.0000000000000000e+00, 2.2908343145930665230025625e-01},
+	{2.0000000000000000e+00, 7.2793991043601025126008608e-01},
+	{1.0000000000000000e+00, 8.2530809168085506044576505e-01},
+	{-8.0000000000000000e+00, -6.8592476857560136238589621e-01},
+}
+var nextafter32 = []float32{
+	4.979012489318848e+00,
+	7.738873004913330e+00,
+	-2.768800258636475e-01,
+	-5.010602951049805e+00,
+	9.636294364929199e+00,
+	2.926377534866333e+00,
+	5.229084014892578e+00,
+	2.727940082550049e+00,
+	1.825308203697205e+00,
+	-8.685923576354980e+00,
+}
+var nextafter64 = []float64{
+	4.97901192488367438926388786e+00,
+	7.73887247457810545370193722e+00,
+	-2.7688005719200153853520874e-01,
+	-5.01060361827107403343006808e+00,
+	9.63629370719841915615688777e+00,
+	2.92637723924396508934364647e+00,
+	5.22908343145930754047867595e+00,
+	2.72793991043601069534929593e+00,
+	1.82530809168085528249036997e+00,
+	-8.68592476857559958602905681e+00,
+}
+var pow = []float64{
+	9.5282232631648411840742957e+04,
+	5.4811599352999901232411871e+07,
+	5.2859121715894396531132279e-01,
+	9.7587991957286474464259698e-06,
+	4.328064329346044846740467e+09,
+	8.4406761805034547437659092e+02,
+	1.6946633276191194947742146e+05,
+	5.3449040147551939075312879e+02,
+	6.688182138451414936380374e+01,
+	2.0609869004248742886827439e-09,
+}
+var remainder = []float64{
+	4.197615023265299782906368e-02,
+	2.261127525421895434476482e+00,
+	3.231794108794261433104108e-02,
+	-2.120723654214984321697556e-02,
+	3.637062928015826201999516e-01,
+	1.220868282268106064236690e+00,
+	-4.581668629186133046005125e-01,
+	-9.117596417440410050403443e-01,
+	8.734595415957246977711748e-01,
+	1.314075231424398637614104e+00,
+}
+var signbit = []bool{
+	false,
+	false,
+	true,
+	true,
+	false,
+	false,
+	false,
+	false,
+	false,
+	true,
+}
+var sin = []float64{
+	-9.6466616586009283766724726e-01,
+	9.9338225271646545763467022e-01,
+	-2.7335587039794393342449301e-01,
+	9.5586257685042792878173752e-01,
+	-2.099421066779969164496634e-01,
+	2.135578780799860532750616e-01,
+	-8.694568971167362743327708e-01,
+	4.019566681155577786649878e-01,
+	9.6778633541687993721617774e-01,
+	-6.734405869050344734943028e-01,
+}
+
+// Results for 100000 * Pi + vf[i]
+var sinLarge = []float64{
+	-9.646661658548936063912e-01,
+	9.933822527198506903752e-01,
+	-2.7335587036246899796e-01,
+	9.55862576853689321268e-01,
+	-2.099421066862688873691e-01,
+	2.13557878070308981163e-01,
+	-8.694568970959221300497e-01,
+	4.01956668098863248917e-01,
+	9.67786335404528727927e-01,
+	-6.7344058693131973066e-01,
+}
+var sinh = []float64{
+	7.2661916084208532301448439e+01,
+	1.1479409110035194500526446e+03,
+	-2.8043136512812518927312641e-01,
+	-7.499429091181587232835164e+01,
+	7.6552466042906758523925934e+03,
+	9.3031583421672014313789064e+00,
+	9.330815755828109072810322e+01,
+	7.6179893137269146407361477e+00,
+	3.021769180549615819524392e+00,
+	-2.95950575724449499189888e+03,
+}
+var sqrt = []float64{
+	2.2313699659365484748756904e+00,
+	2.7818829009464263511285458e+00,
+	5.2619393496314796848143251e-01,
+	2.2384377628763938724244104e+00,
+	3.1042380236055381099288487e+00,
+	1.7106657298385224403917771e+00,
+	2.286718922705479046148059e+00,
+	1.6516476350711159636222979e+00,
+	1.3510396336454586262419247e+00,
+	2.9471892997524949215723329e+00,
+}
+var tan = []float64{
+	-3.661316565040227801781974e+00,
+	8.64900232648597589369854e+00,
+	-2.8417941955033612725238097e-01,
+	3.253290185974728640827156e+00,
+	2.147275640380293804770778e-01,
+	-2.18600910711067004921551e-01,
+	-1.760002817872367935518928e+00,
+	-4.389808914752818126249079e-01,
+	-3.843885560201130679995041e+00,
+	9.10988793377685105753416e-01,
+}
+
+// Results for 100000 * Pi + vf[i]
+var tanLarge = []float64{
+	-3.66131656475596512705e+00,
+	8.6490023287202547927e+00,
+	-2.841794195104782406e-01,
+	3.2532901861033120983e+00,
+	2.14727564046880001365e-01,
+	-2.18600910700688062874e-01,
+	-1.760002817699722747043e+00,
+	-4.38980891453536115952e-01,
+	-3.84388555942723509071e+00,
+	9.1098879344275101051e-01,
+}
+var tanh = []float64{
+	9.9990531206936338549262119e-01,
+	9.9999962057085294197613294e-01,
+	-2.7001505097318677233756845e-01,
+	-9.9991110943061718603541401e-01,
+	9.9999999146798465745022007e-01,
+	9.9427249436125236705001048e-01,
+	9.9994257600983138572705076e-01,
+	9.9149409509772875982054701e-01,
+	9.4936501296239685514466577e-01,
+	-9.9999994291374030946055701e-01,
+}
+var trunc = []float64{
+	4.0000000000000000e+00,
+	7.0000000000000000e+00,
+	-0.0000000000000000e+00,
+	-5.0000000000000000e+00,
+	9.0000000000000000e+00,
+	2.0000000000000000e+00,
+	5.0000000000000000e+00,
+	2.0000000000000000e+00,
+	1.0000000000000000e+00,
+	-8.0000000000000000e+00,
+}
+var y0 = []float64{
+	-3.053399153780788357534855e-01,
+	1.7437227649515231515503649e-01,
+	-8.6221781263678836910392572e-01,
+	-3.100664880987498407872839e-01,
+	1.422200649300982280645377e-01,
+	4.000004067997901144239363e-01,
+	-3.3340749753099352392332536e-01,
+	4.5399790746668954555205502e-01,
+	4.8290004112497761007536522e-01,
+	2.7036697826604756229601611e-01,
+}
+var y1 = []float64{
+	0.15494213737457922210218611,
+	-0.2165955142081145245075746,
+	-2.4644949631241895201032829,
+	0.1442740489541836405154505,
+	0.2215379960518984777080163,
+	0.3038800915160754150565448,
+	0.0691107642452362383808547,
+	0.2380116417809914424860165,
+	-0.20849492979459761009678934,
+	0.0242503179793232308250804,
+}
+var y2 = []float64{
+	0.3675780219390303613394936,
+	-0.23034826393250119879267257,
+	-16.939677983817727205631397,
+	0.367653980523052152867791,
+	-0.0962401471767804440353136,
+	-0.1923169356184851105200523,
+	0.35984072054267882391843766,
+	-0.2794987252299739821654982,
+	-0.7113490692587462579757954,
+	-0.2647831587821263302087457,
+}
+var yM3 = []float64{
+	-0.14035984421094849100895341,
+	-0.097535139617792072703973,
+	242.25775994555580176377379,
+	-0.1492267014802818619511046,
+	0.26148702629155918694500469,
+	0.56675383593895176530394248,
+	-0.206150264009006981070575,
+	0.64784284687568332737963658,
+	1.3503631555901938037008443,
+	0.1461869756579956803341844,
+}
+
+// arguments and expected results for special cases
+var vfacosSC = []float64{
+	-Pi,
+	1,
+	Pi,
+	NaN(),
+}
+var acosSC = []float64{
+	NaN(),
+	0,
+	NaN(),
+	NaN(),
+}
+
+var vfacoshSC = []float64{
+	Inf(-1),
+	0.5,
+	1,
+	Inf(1),
+	NaN(),
+}
+var acoshSC = []float64{
+	NaN(),
+	NaN(),
+	0,
+	Inf(1),
+	NaN(),
+}
+
+var vfasinSC = []float64{
+	-Pi,
+	Copysign(0, -1),
+	0,
+	Pi,
+	NaN(),
+}
+var asinSC = []float64{
+	NaN(),
+	Copysign(0, -1),
+	0,
+	NaN(),
+	NaN(),
+}
+
+var vfasinhSC = []float64{
+	Inf(-1),
+	Copysign(0, -1),
+	0,
+	Inf(1),
+	NaN(),
+}
+var asinhSC = []float64{
+	Inf(-1),
+	Copysign(0, -1),
+	0,
+	Inf(1),
+	NaN(),
+}
+
+var vfatanSC = []float64{
+	Inf(-1),
+	Copysign(0, -1),
+	0,
+	Inf(1),
+	NaN(),
+}
+var atanSC = []float64{
+	-Pi / 2,
+	Copysign(0, -1),
+	0,
+	Pi / 2,
+	NaN(),
+}
+
+var vfatanhSC = []float64{
+	Inf(-1),
+	-Pi,
+	-1,
+	Copysign(0, -1),
+	0,
+	1,
+	Pi,
+	Inf(1),
+	NaN(),
+}
+var atanhSC = []float64{
+	NaN(),
+	NaN(),
+	Inf(-1),
+	Copysign(0, -1),
+	0,
+	Inf(1),
+	NaN(),
+	NaN(),
+	NaN(),
+}
+var vfatan2SC = [][2]float64{
+	{Inf(-1), Inf(-1)},
+	{Inf(-1), -Pi},
+	{Inf(-1), 0},
+	{Inf(-1), +Pi},
+	{Inf(-1), Inf(1)},
+	{Inf(-1), NaN()},
+	{-Pi, Inf(-1)},
+	{-Pi, 0},
+	{-Pi, Inf(1)},
+	{-Pi, NaN()},
+	{Copysign(0, -1), Inf(-1)},
+	{Copysign(0, -1), -Pi},
+	{Copysign(0, -1), Copysign(0, -1)},
+	{Copysign(0, -1), 0},
+	{Copysign(0, -1), +Pi},
+	{Copysign(0, -1), Inf(1)},
+	{Copysign(0, -1), NaN()},
+	{0, Inf(-1)},
+	{0, -Pi},
+	{0, Copysign(0, -1)},
+	{0, 0},
+	{0, +Pi},
+	{0, Inf(1)},
+	{0, NaN()},
+	{+Pi, Inf(-1)},
+	{+Pi, 0},
+	{+Pi, Inf(1)},
+	{+Pi, NaN()},
+	{Inf(1), Inf(-1)},
+	{Inf(1), -Pi},
+	{Inf(1), 0},
+	{Inf(1), +Pi},
+	{Inf(1), Inf(1)},
+	{Inf(1), NaN()},
+	{NaN(), NaN()},
+}
+var atan2SC = []float64{
+	-3 * Pi / 4,     // atan2(-Inf, -Inf)
+	-Pi / 2,         // atan2(-Inf, -Pi)
+	-Pi / 2,         // atan2(-Inf, +0)
+	-Pi / 2,         // atan2(-Inf, +Pi)
+	-Pi / 4,         // atan2(-Inf, +Inf)
+	NaN(),           // atan2(-Inf, NaN)
+	-Pi,             // atan2(-Pi, -Inf)
+	-Pi / 2,         // atan2(-Pi, +0)
+	Copysign(0, -1), // atan2(-Pi, Inf)
+	NaN(),           // atan2(-Pi, NaN)
+	-Pi,             // atan2(-0, -Inf)
+	-Pi,             // atan2(-0, -Pi)
+	-Pi,             // atan2(-0, -0)
+	Copysign(0, -1), // atan2(-0, +0)
+	Copysign(0, -1), // atan2(-0, +Pi)
+	Copysign(0, -1), // atan2(-0, +Inf)
+	NaN(),           // atan2(-0, NaN)
+	Pi,              // atan2(+0, -Inf)
+	Pi,              // atan2(+0, -Pi)
+	Pi,              // atan2(+0, -0)
+	0,               // atan2(+0, +0)
+	0,               // atan2(+0, +Pi)
+	0,               // atan2(+0, +Inf)
+	NaN(),           // atan2(+0, NaN)
+	Pi,              // atan2(+Pi, -Inf)
+	Pi / 2,          // atan2(+Pi, +0)
+	0,               // atan2(+Pi, +Inf)
+	NaN(),           // atan2(+Pi, NaN)
+	3 * Pi / 4,      // atan2(+Inf, -Inf)
+	Pi / 2,          // atan2(+Inf, -Pi)
+	Pi / 2,          // atan2(+Inf, +0)
+	Pi / 2,          // atan2(+Inf, +Pi)
+	Pi / 4,          // atan2(+Inf, +Inf)
+	NaN(),           // atan2(+Inf, NaN)
+	NaN(),           // atan2(NaN, NaN)
+}
+
+var vfcbrtSC = []float64{
+	Inf(-1),
+	Copysign(0, -1),
+	0,
+	Inf(1),
+	NaN(),
+}
+var cbrtSC = []float64{
+	Inf(-1),
+	Copysign(0, -1),
+	0,
+	Inf(1),
+	NaN(),
+}
+
+var vfceilSC = []float64{
+	Inf(-1),
+	Copysign(0, -1),
+	0,
+	Inf(1),
+	NaN(),
+}
+var ceilSC = []float64{
+	Inf(-1),
+	Copysign(0, -1),
+	0,
+	Inf(1),
+	NaN(),
+}
+
+var vfcopysignSC = []float64{
+	Inf(-1),
+	Inf(1),
+	NaN(),
+}
+var copysignSC = []float64{
+	Inf(-1),
+	Inf(-1),
+	NaN(),
+}
+
+var vfcosSC = []float64{
+	Inf(-1),
+	Inf(1),
+	NaN(),
+}
+var cosSC = []float64{
+	NaN(),
+	NaN(),
+	NaN(),
+}
+
+var vfcoshSC = []float64{
+	Inf(-1),
+	Copysign(0, -1),
+	0,
+	Inf(1),
+	NaN(),
+}
+var coshSC = []float64{
+	Inf(1),
+	1,
+	1,
+	Inf(1),
+	NaN(),
+}
+
+var vferfSC = []float64{
+	Inf(-1),
+	Copysign(0, -1),
+	0,
+	Inf(1),
+	NaN(),
+}
+var erfSC = []float64{
+	-1,
+	Copysign(0, -1),
+	0,
+	1,
+	NaN(),
+}
+
+var vferfcSC = []float64{
+	Inf(-1),
+	Inf(1),
+	NaN(),
+}
+var erfcSC = []float64{
+	2,
+	0,
+	NaN(),
+}
+
+var vfexpSC = []float64{
+	Inf(-1),
+	-2000,
+	2000,
+	Inf(1),
+	NaN(),
+}
+var expSC = []float64{
+	0,
+	0,
+	Inf(1),
+	Inf(1),
+	NaN(),
+}
+
+var vfexpm1SC = []float64{
+	Inf(-1),
+	Copysign(0, -1),
+	0,
+	Inf(1),
+	NaN(),
+}
+var expm1SC = []float64{
+	-1,
+	Copysign(0, -1),
+	0,
+	Inf(1),
+	NaN(),
+}
+
+var vffabsSC = []float64{
+	Inf(-1),
+	Copysign(0, -1),
+	0,
+	Inf(1),
+	NaN(),
+}
+var fabsSC = []float64{
+	Inf(1),
+	0,
+	0,
+	Inf(1),
+	NaN(),
+}
+
+var vffdimSC = [][2]float64{
+	{Inf(-1), Inf(-1)},
+	{Inf(-1), Inf(1)},
+	{Inf(-1), NaN()},
+	{Copysign(0, -1), Copysign(0, -1)},
+	{Copysign(0, -1), 0},
+	{0, Copysign(0, -1)},
+	{0, 0},
+	{Inf(1), Inf(-1)},
+	{Inf(1), Inf(1)},
+	{Inf(1), NaN()},
+	{NaN(), Inf(-1)},
+	{NaN(), Copysign(0, -1)},
+	{NaN(), 0},
+	{NaN(), Inf(1)},
+	{NaN(), NaN()},
+}
+var fdimSC = []float64{
+	NaN(),
+	0,
+	NaN(),
+	0,
+	0,
+	0,
+	0,
+	Inf(1),
+	NaN(),
+	NaN(),
+	NaN(),
+	NaN(),
+	NaN(),
+	NaN(),
+	NaN(),
+}
+var fmaxSC = []float64{
+	Inf(-1),
+	Inf(1),
+	NaN(),
+	Copysign(0, -1),
+	0,
+	0,
+	0,
+	Inf(1),
+	Inf(1),
+	Inf(1),
+	NaN(),
+	NaN(),
+	NaN(),
+	Inf(1),
+	NaN(),
+}
+var fminSC = []float64{
+	Inf(-1),
+	Inf(-1),
+	Inf(-1),
+	Copysign(0, -1),
+	Copysign(0, -1),
+	Copysign(0, -1),
+	0,
+	Inf(-1),
+	Inf(1),
+	NaN(),
+	Inf(-1),
+	NaN(),
+	NaN(),
+	NaN(),
+	NaN(),
+}
+
+var vffmodSC = [][2]float64{
+	{Inf(-1), Inf(-1)},
+	{Inf(-1), -Pi},
+	{Inf(-1), 0},
+	{Inf(-1), Pi},
+	{Inf(-1), Inf(1)},
+	{Inf(-1), NaN()},
+	{-Pi, Inf(-1)},
+	{-Pi, 0},
+	{-Pi, Inf(1)},
+	{-Pi, NaN()},
+	{Copysign(0, -1), Inf(-1)},
+	{Copysign(0, -1), 0},
+	{Copysign(0, -1), Inf(1)},
+	{Copysign(0, -1), NaN()},
+	{0, Inf(-1)},
+	{0, 0},
+	{0, Inf(1)},
+	{0, NaN()},
+	{Pi, Inf(-1)},
+	{Pi, 0},
+	{Pi, Inf(1)},
+	{Pi, NaN()},
+	{Inf(1), Inf(-1)},
+	{Inf(1), -Pi},
+	{Inf(1), 0},
+	{Inf(1), Pi},
+	{Inf(1), Inf(1)},
+	{Inf(1), NaN()},
+	{NaN(), Inf(-1)},
+	{NaN(), -Pi},
+	{NaN(), 0},
+	{NaN(), Pi},
+	{NaN(), Inf(1)},
+	{NaN(), NaN()},
+}
+var fmodSC = []float64{
+	NaN(),           // fmod(-Inf, -Inf)
+	NaN(),           // fmod(-Inf, -Pi)
+	NaN(),           // fmod(-Inf, 0)
+	NaN(),           // fmod(-Inf, Pi)
+	NaN(),           // fmod(-Inf, +Inf)
+	NaN(),           // fmod(-Inf, NaN)
+	-Pi,             // fmod(-Pi, -Inf)
+	NaN(),           // fmod(-Pi, 0)
+	-Pi,             // fmod(-Pi, +Inf)
+	NaN(),           // fmod(-Pi, NaN)
+	Copysign(0, -1), // fmod(-0, -Inf)
+	NaN(),           // fmod(-0, 0)
+	Copysign(0, -1), // fmod(-0, Inf)
+	NaN(),           // fmod(-0, NaN)
+	0,               // fmod(0, -Inf)
+	NaN(),           // fmod(0, 0)
+	0,               // fmod(0, +Inf)
+	NaN(),           // fmod(0, NaN)
+	Pi,              // fmod(Pi, -Inf)
+	NaN(),           // fmod(Pi, 0)
+	Pi,              // fmod(Pi, +Inf)
+	NaN(),           // fmod(Pi, NaN)
+	NaN(),           // fmod(+Inf, -Inf)
+	NaN(),           // fmod(+Inf, -Pi)
+	NaN(),           // fmod(+Inf, 0)
+	NaN(),           // fmod(+Inf, Pi)
+	NaN(),           // fmod(+Inf, +Inf)
+	NaN(),           // fmod(+Inf, NaN)
+	NaN(),           // fmod(NaN, -Inf)
+	NaN(),           // fmod(NaN, -Pi)
+	NaN(),           // fmod(NaN, 0)
+	NaN(),           // fmod(NaN, Pi)
+	NaN(),           // fmod(NaN, +Inf)
+	NaN(),           // fmod(NaN, NaN)
+}
+
+var vffrexpSC = []float64{
+	Inf(-1),
+	Copysign(0, -1),
+	0,
+	Inf(1),
+	NaN(),
+}
+var frexpSC = []fi{
+	{Inf(-1), 0},
+	{Copysign(0, -1), 0},
+	{0, 0},
+	{Inf(1), 0},
+	{NaN(), 0},
+}
+
+var vfgammaSC = []float64{
+	Inf(-1),
+	-3,
+	Copysign(0, -1),
+	0,
+	Inf(1),
+	NaN(),
+}
+var gammaSC = []float64{
+	NaN(),
+	NaN(),
+	Inf(-1),
+	Inf(1),
+	Inf(1),
+	NaN(),
+}
+
+var vfhypotSC = [][2]float64{
+	{Inf(-1), Inf(-1)},
+	{Inf(-1), 0},
+	{Inf(-1), Inf(1)},
+	{Inf(-1), NaN()},
+	{Copysign(0, -1), Copysign(0, -1)},
+	{Copysign(0, -1), 0},
+	{0, Copysign(0, -1)},
+	{0, 0}, // +0, +0
+	{0, Inf(-1)},
+	{0, Inf(1)},
+	{0, NaN()},
+	{Inf(1), Inf(-1)},
+	{Inf(1), 0},
+	{Inf(1), Inf(1)},
+	{Inf(1), NaN()},
+	{NaN(), Inf(-1)},
+	{NaN(), 0},
+	{NaN(), Inf(1)},
+	{NaN(), NaN()},
+}
+var hypotSC = []float64{
+	Inf(1),
+	Inf(1),
+	Inf(1),
+	Inf(1),
+	0,
+	0,
+	0,
+	0,
+	Inf(1),
+	Inf(1),
+	NaN(),
+	Inf(1),
+	Inf(1),
+	Inf(1),
+	Inf(1),
+	Inf(1),
+	NaN(),
+	Inf(1),
+	NaN(),
+}
+
+var vfilogbSC = []float64{
+	Inf(-1),
+	0,
+	Inf(1),
+	NaN(),
+}
+var ilogbSC = []int{
+	MaxInt32,
+	MinInt32,
+	MaxInt32,
+	MaxInt32,
+}
+
+var vfj0SC = []float64{
+	Inf(-1),
+	0,
+	Inf(1),
+	NaN(),
+}
+var j0SC = []float64{
+	0,
+	1,
+	0,
+	NaN(),
+}
+var j1SC = []float64{
+	0,
+	0,
+	0,
+	NaN(),
+}
+var j2SC = []float64{
+	0,
+	0,
+	0,
+	NaN(),
+}
+var jM3SC = []float64{
+	0,
+	0,
+	0,
+	NaN(),
+}
+
+var vfldexpSC = []fi{
+	{0, 0},
+	{0, -1075},
+	{0, 1024},
+	{Copysign(0, -1), 0},
+	{Copysign(0, -1), -1075},
+	{Copysign(0, -1), 1024},
+	{Inf(1), 0},
+	{Inf(1), -1024},
+	{Inf(-1), 0},
+	{Inf(-1), -1024},
+	{NaN(), -1024},
+}
+var ldexpSC = []float64{
+	0,
+	0,
+	0,
+	Copysign(0, -1),
+	Copysign(0, -1),
+	Copysign(0, -1),
+	Inf(1),
+	Inf(1),
+	Inf(-1),
+	Inf(-1),
+	NaN(),
+}
+
+var vflgammaSC = []float64{
+	Inf(-1),
+	-3,
+	0,
+	1,
+	2,
+	Inf(1),
+	NaN(),
+}
+var lgammaSC = []fi{
+	{Inf(-1), 1},
+	{Inf(1), 1},
+	{Inf(1), 1},
+	{0, 1},
+	{0, 1},
+	{Inf(1), 1},
+	{NaN(), 1},
+}
+
+var vflogSC = []float64{
+	Inf(-1),
+	-Pi,
+	Copysign(0, -1),
+	0,
+	1,
+	Inf(1),
+	NaN(),
+}
+var logSC = []float64{
+	NaN(),
+	NaN(),
+	Inf(-1),
+	Inf(-1),
+	0,
+	Inf(1),
+	NaN(),
+}
+
+var vflogbSC = []float64{
+	Inf(-1),
+	0,
+	Inf(1),
+	NaN(),
+}
+var logbSC = []float64{
+	Inf(1),
+	Inf(-1),
+	Inf(1),
+	NaN(),
+}
+
+var vflog1pSC = []float64{
+	Inf(-1),
+	-Pi,
+	-1,
+	Copysign(0, -1),
+	0,
+	Inf(1),
+	NaN(),
+}
+var log1pSC = []float64{
+	NaN(),
+	NaN(),
+	Inf(-1),
+	Copysign(0, -1),
+	0,
+	Inf(1),
+	NaN(),
+}
+
+var vfmodfSC = []float64{
+	Inf(-1),
+	Inf(1),
+	NaN(),
+}
+var modfSC = [][2]float64{
+	{Inf(-1), NaN()}, // [2]float64{Copysign(0, -1), Inf(-1)},
+	{Inf(1), NaN()},  // [2]float64{0, Inf(1)},
+	{NaN(), NaN()},
+}
+
+var vfnextafter32SC = [][2]float32{
+	{0, 0},
+	{0, float32(Copysign(0, -1))},
+	{0, -1},
+	{0, float32(NaN())},
+	{float32(Copysign(0, -1)), 1},
+	{float32(Copysign(0, -1)), 0},
+	{float32(Copysign(0, -1)), float32(Copysign(0, -1))},
+	{float32(Copysign(0, -1)), -1},
+	{float32(NaN()), 0},
+	{float32(NaN()), float32(NaN())},
+}
+var nextafter32SC = []float32{
+	0,
+	0,
+	-1.401298464e-45, // Float32frombits(0x80000001)
+	float32(NaN()),
+	1.401298464e-45, // Float32frombits(0x00000001)
+	float32(Copysign(0, -1)),
+	float32(Copysign(0, -1)),
+	-1.401298464e-45, // Float32frombits(0x80000001)
+	float32(NaN()),
+	float32(NaN()),
+}
+
+var vfnextafter64SC = [][2]float64{
+	{0, 0},
+	{0, Copysign(0, -1)},
+	{0, -1},
+	{0, NaN()},
+	{Copysign(0, -1), 1},
+	{Copysign(0, -1), 0},
+	{Copysign(0, -1), Copysign(0, -1)},
+	{Copysign(0, -1), -1},
+	{NaN(), 0},
+	{NaN(), NaN()},
+}
+var nextafter64SC = []float64{
+	0,
+	0,
+	-4.9406564584124654418e-324, // Float64frombits(0x8000000000000001)
+	NaN(),
+	4.9406564584124654418e-324, // Float64frombits(0x0000000000000001)
+	Copysign(0, -1),
+	Copysign(0, -1),
+	-4.9406564584124654418e-324, // Float64frombits(0x8000000000000001)
+	NaN(),
+	NaN(),
+}
+
+var vfpowSC = [][2]float64{
+	{Inf(-1), -Pi},
+	{Inf(-1), -3},
+	{Inf(-1), Copysign(0, -1)},
+	{Inf(-1), 0},
+	{Inf(-1), 1},
+	{Inf(-1), 3},
+	{Inf(-1), Pi},
+	{Inf(-1), NaN()},
+
+	{-Pi, Inf(-1)},
+	{-Pi, -Pi},
+	{-Pi, Copysign(0, -1)},
+	{-Pi, 0},
+	{-Pi, 1},
+	{-Pi, Pi},
+	{-Pi, Inf(1)},
+	{-Pi, NaN()},
+
+	{-1, Inf(-1)},
+	{-1, Inf(1)},
+	{-1, NaN()},
+	{-1 / 2, Inf(-1)},
+	{-1 / 2, Inf(1)},
+	{Copysign(0, -1), Inf(-1)},
+	{Copysign(0, -1), -Pi},
+	{Copysign(0, -1), -3},
+	{Copysign(0, -1), 3},
+	{Copysign(0, -1), Pi},
+	{Copysign(0, -1), Inf(1)},
+
+	{0, Inf(-1)},
+	{0, -Pi},
+	{0, -3},
+	{0, Copysign(0, -1)},
+	{0, 0},
+	{0, 3},
+	{0, Pi},
+	{0, Inf(1)},
+	{0, NaN()},
+
+	{1 / 2, Inf(-1)},
+	{1 / 2, Inf(1)},
+	{1, Inf(-1)},
+	{1, Inf(1)},
+	{1, NaN()},
+
+	{Pi, Inf(-1)},
+	{Pi, Copysign(0, -1)},
+	{Pi, 0},
+	{Pi, 1},
+	{Pi, Inf(1)},
+	{Pi, NaN()},
+	{Inf(1), -Pi},
+	{Inf(1), Copysign(0, -1)},
+	{Inf(1), 0},
+	{Inf(1), 1},
+	{Inf(1), Pi},
+	{Inf(1), NaN()},
+	{NaN(), -Pi},
+	{NaN(), Copysign(0, -1)},
+	{NaN(), 0},
+	{NaN(), 1},
+	{NaN(), Pi},
+	{NaN(), NaN()},
+}
+var powSC = []float64{
+	0,               // pow(-Inf, -Pi)
+	Copysign(0, -1), // pow(-Inf, -3)
+	1,               // pow(-Inf, -0)
+	1,               // pow(-Inf, +0)
+	Inf(-1),         // pow(-Inf, 1)
+	Inf(-1),         // pow(-Inf, 3)
+	Inf(1),          // pow(-Inf, Pi)
+	NaN(),           // pow(-Inf, NaN)
+	0,               // pow(-Pi, -Inf)
+	NaN(),           // pow(-Pi, -Pi)
+	1,               // pow(-Pi, -0)
+	1,               // pow(-Pi, +0)
+	-Pi,             // pow(-Pi, 1)
+	NaN(),           // pow(-Pi, Pi)
+	Inf(1),          // pow(-Pi, +Inf)
+	NaN(),           // pow(-Pi, NaN)
+	1,               // pow(-1, -Inf) IEEE 754-2008
+	1,               // pow(-1, +Inf) IEEE 754-2008
+	NaN(),           // pow(-1, NaN)
+	Inf(1),          // pow(-1/2, -Inf)
+	0,               // pow(-1/2, +Inf)
+	Inf(1),          // pow(-0, -Inf)
+	Inf(1),          // pow(-0, -Pi)
+	Inf(-1),         // pow(-0, -3) IEEE 754-2008
+	Copysign(0, -1), // pow(-0, 3) IEEE 754-2008
+	0,               // pow(-0, +Pi)
+	0,               // pow(-0, +Inf)
+	Inf(1),          // pow(+0, -Inf)
+	Inf(1),          // pow(+0, -Pi)
+	Inf(1),          // pow(+0, -3)
+	1,               // pow(+0, -0)
+	1,               // pow(+0, +0)
+	0,               // pow(+0, 3)
+	0,               // pow(+0, +Pi)
+	0,               // pow(+0, +Inf)
+	NaN(),           // pow(+0, NaN)
+	Inf(1),          // pow(1/2, -Inf)
+	0,               // pow(1/2, +Inf)
+	1,               // pow(1, -Inf) IEEE 754-2008
+	1,               // pow(1, +Inf) IEEE 754-2008
+	1,               // pow(1, NaN) IEEE 754-2008
+	0,               // pow(+Pi, -Inf)
+	1,               // pow(+Pi, -0)
+	1,               // pow(+Pi, +0)
+	Pi,              // pow(+Pi, 1)
+	Inf(1),          // pow(+Pi, +Inf)
+	NaN(),           // pow(+Pi, NaN)
+	0,               // pow(+Inf, -Pi)
+	1,               // pow(+Inf, -0)
+	1,               // pow(+Inf, +0)
+	Inf(1),          // pow(+Inf, 1)
+	Inf(1),          // pow(+Inf, Pi)
+	NaN(),           // pow(+Inf, NaN)
+	NaN(),           // pow(NaN, -Pi)
+	1,               // pow(NaN, -0)
+	1,               // pow(NaN, +0)
+	NaN(),           // pow(NaN, 1)
+	NaN(),           // pow(NaN, +Pi)
+	NaN(),           // pow(NaN, NaN)
+}
+
+var vfpow10SC = []int{
+	MinInt32,
+	MaxInt32,
+	-325,
+	309,
+}
+
+var pow10SC = []float64{
+	0,      // pow10(MinInt32)
+	Inf(1), // pow10(MaxInt32)
+	0,      // pow10(-325)
+	Inf(1), // pow10(309)
+}
+
+var vfsignbitSC = []float64{
+	Inf(-1),
+	Copysign(0, -1),
+	0,
+	Inf(1),
+	NaN(),
+}
+var signbitSC = []bool{
+	true,
+	true,
+	false,
+	false,
+	false,
+}
+
+var vfsinSC = []float64{
+	Inf(-1),
+	Copysign(0, -1),
+	0,
+	Inf(1),
+	NaN(),
+}
+var sinSC = []float64{
+	NaN(),
+	Copysign(0, -1),
+	0,
+	NaN(),
+	NaN(),
+}
+
+var vfsinhSC = []float64{
+	Inf(-1),
+	Copysign(0, -1),
+	0,
+	Inf(1),
+	NaN(),
+}
+var sinhSC = []float64{
+	Inf(-1),
+	Copysign(0, -1),
+	0,
+	Inf(1),
+	NaN(),
+}
+
+var vfsqrtSC = []float64{
+	Inf(-1),
+	-Pi,
+	Copysign(0, -1),
+	0,
+	Inf(1),
+	NaN(),
+}
+var sqrtSC = []float64{
+	NaN(),
+	NaN(),
+	Copysign(0, -1),
+	0,
+	Inf(1),
+	NaN(),
+}
+
+var vftanhSC = []float64{
+	Inf(-1),
+	Copysign(0, -1),
+	0,
+	Inf(1),
+	NaN(),
+}
+var tanhSC = []float64{
+	-1,
+	Copysign(0, -1),
+	0,
+	1,
+	NaN(),
+}
+
+var vfy0SC = []float64{
+	Inf(-1),
+	0,
+	Inf(1),
+	NaN(),
+}
+var y0SC = []float64{
+	NaN(),
+	Inf(-1),
+	0,
+	NaN(),
+}
+var y1SC = []float64{
+	NaN(),
+	Inf(-1),
+	0,
+	NaN(),
+}
+var y2SC = []float64{
+	NaN(),
+	Inf(-1),
+	0,
+	NaN(),
+}
+var yM3SC = []float64{
+	NaN(),
+	Inf(1),
+	0,
+	NaN(),
+}
+
+// arguments and expected results for boundary cases
+const (
+	SmallestNormalFloat64   = 2.2250738585072014e-308 // 2**-1022
+	LargestSubnormalFloat64 = SmallestNormalFloat64 - SmallestNonzeroFloat64
+)
+
+var vffrexpBC = []float64{
+	SmallestNormalFloat64,
+	LargestSubnormalFloat64,
+	SmallestNonzeroFloat64,
+	MaxFloat64,
+	-SmallestNormalFloat64,
+	-LargestSubnormalFloat64,
+	-SmallestNonzeroFloat64,
+	-MaxFloat64,
+}
+var frexpBC = []fi{
+	{0.5, -1021},
+	{0.99999999999999978, -1022},
+	{0.5, -1073},
+	{0.99999999999999989, 1024},
+	{-0.5, -1021},
+	{-0.99999999999999978, -1022},
+	{-0.5, -1073},
+	{-0.99999999999999989, 1024},
+}
+
+var vfldexpBC = []fi{
+	{SmallestNormalFloat64, -52},
+	{LargestSubnormalFloat64, -51},
+	{SmallestNonzeroFloat64, 1074},
+	{MaxFloat64, -(1023 + 1074)},
+	{1, -1075},
+	{-1, -1075},
+	{1, 1024},
+	{-1, 1024},
+}
+var ldexpBC = []float64{
+	SmallestNonzeroFloat64,
+	1e-323, // 2**-1073
+	1,
+	1e-323, // 2**-1073
+	0,
+	Copysign(0, -1),
+	Inf(1),
+	Inf(-1),
+}
+
+var logbBC = []float64{
+	-1022,
+	-1023,
+	-1074,
+	1023,
+	-1022,
+	-1023,
+	-1074,
+	1023,
+}
+
+func tolerance(a, b, e float64) bool {
+	d := a - b
+	if d < 0 {
+		d = -d
+	}
+
+	if a != 0 {
+		e = e * a
+		if e < 0 {
+			e = -e
+		}
+	}
+	return d < e
+}
+func kindaclose(a, b float64) bool { return tolerance(a, b, 1e-8) }
+func close(a, b float64) bool      { return tolerance(a, b, 1e-14) }
+func veryclose(a, b float64) bool  { return tolerance(a, b, 4e-16) }
+func soclose(a, b, e float64) bool { return tolerance(a, b, e) }
+func alike(a, b float64) bool {
+	switch {
+	case IsNaN(a) && IsNaN(b):
+		return true
+	case a == b:
+		return Signbit(a) == Signbit(b)
+	}
+	return false
+}
+
+func TestNaN(t *testing.T) {
+	f64 := NaN()
+	if f64 == f64 {
+		t.Fatalf("NaN() returns %g, expected NaN", f64)
+	}
+	f32 := float32(f64)
+	if f32 == f32 {
+		t.Fatalf("float32(NaN()) is %g, expected NaN", f32)
+	}
+}
+
+func TestAcos(t *testing.T) {
+	for i := 0; i < len(vf); i++ {
+		a := vf[i] / 10
+		if f := Acos(a); !close(acos[i], f) {
+			t.Errorf("Acos(%g) = %g, want %g", a, f, acos[i])
+		}
+	}
+	for i := 0; i < len(vfacosSC); i++ {
+		if f := Acos(vfacosSC[i]); !alike(acosSC[i], f) {
+			t.Errorf("Acos(%g) = %g, want %g", vfacosSC[i], f, acosSC[i])
+		}
+	}
+}
+
+func TestAcosh(t *testing.T) {
+	for i := 0; i < len(vf); i++ {
+		a := 1 + Abs(vf[i])
+		if f := Acosh(a); !veryclose(acosh[i], f) {
+			t.Errorf("Acosh(%g) = %g, want %g", a, f, acosh[i])
+		}
+	}
+	for i := 0; i < len(vfacoshSC); i++ {
+		if f := Acosh(vfacoshSC[i]); !alike(acoshSC[i], f) {
+			t.Errorf("Acosh(%g) = %g, want %g", vfacoshSC[i], f, acoshSC[i])
+		}
+	}
+}
+
+func TestAsin(t *testing.T) {
+	for i := 0; i < len(vf); i++ {
+		a := vf[i] / 10
+		if f := Asin(a); !veryclose(asin[i], f) {
+			t.Errorf("Asin(%g) = %g, want %g", a, f, asin[i])
+		}
+	}
+	for i := 0; i < len(vfasinSC); i++ {
+		if f := Asin(vfasinSC[i]); !alike(asinSC[i], f) {
+			t.Errorf("Asin(%g) = %g, want %g", vfasinSC[i], f, asinSC[i])
+		}
+	}
+}
+
+func TestAsinh(t *testing.T) {
+	for i := 0; i < len(vf); i++ {
+		if f := Asinh(vf[i]); !veryclose(asinh[i], f) {
+			t.Errorf("Asinh(%g) = %g, want %g", vf[i], f, asinh[i])
+		}
+	}
+	for i := 0; i < len(vfasinhSC); i++ {
+		if f := Asinh(vfasinhSC[i]); !alike(asinhSC[i], f) {
+			t.Errorf("Asinh(%g) = %g, want %g", vfasinhSC[i], f, asinhSC[i])
+		}
+	}
+}
+
+func TestAtan(t *testing.T) {
+	for i := 0; i < len(vf); i++ {
+		if f := Atan(vf[i]); !veryclose(atan[i], f) {
+			t.Errorf("Atan(%g) = %g, want %g", vf[i], f, atan[i])
+		}
+	}
+	for i := 0; i < len(vfatanSC); i++ {
+		if f := Atan(vfatanSC[i]); !alike(atanSC[i], f) {
+			t.Errorf("Atan(%g) = %g, want %g", vfatanSC[i], f, atanSC[i])
+		}
+	}
+}
+
+func TestAtanh(t *testing.T) {
+	for i := 0; i < len(vf); i++ {
+		a := vf[i] / 10
+		if f := Atanh(a); !veryclose(atanh[i], f) {
+			t.Errorf("Atanh(%g) = %g, want %g", a, f, atanh[i])
+		}
+	}
+	for i := 0; i < len(vfatanhSC); i++ {
+		if f := Atanh(vfatanhSC[i]); !alike(atanhSC[i], f) {
+			t.Errorf("Atanh(%g) = %g, want %g", vfatanhSC[i], f, atanhSC[i])
+		}
+	}
+}
+
+func TestAtan2(t *testing.T) {
+	for i := 0; i < len(vf); i++ {
+		if f := Atan2(10, vf[i]); !veryclose(atan2[i], f) {
+			t.Errorf("Atan2(10, %g) = %g, want %g", vf[i], f, atan2[i])
+		}
+	}
+	for i := 0; i < len(vfatan2SC); i++ {
+		if f := Atan2(vfatan2SC[i][0], vfatan2SC[i][1]); !alike(atan2SC[i], f) {
+			t.Errorf("Atan2(%g, %g) = %g, want %g", vfatan2SC[i][0], vfatan2SC[i][1], f, atan2SC[i])
+		}
+	}
+}
+
+func TestCbrt(t *testing.T) {
+	for i := 0; i < len(vf); i++ {
+		if f := Cbrt(vf[i]); !veryclose(cbrt[i], f) {
+			t.Errorf("Cbrt(%g) = %g, want %g", vf[i], f, cbrt[i])
+		}
+	}
+	for i := 0; i < len(vfcbrtSC); i++ {
+		if f := Cbrt(vfcbrtSC[i]); !alike(cbrtSC[i], f) {
+			t.Errorf("Cbrt(%g) = %g, want %g", vfcbrtSC[i], f, cbrtSC[i])
+		}
+	}
+}
+
+func TestCeil(t *testing.T) {
+	for i := 0; i < len(vf); i++ {
+		if f := Ceil(vf[i]); ceil[i] != f {
+			t.Errorf("Ceil(%g) = %g, want %g", vf[i], f, ceil[i])
+		}
+	}
+	for i := 0; i < len(vfceilSC); i++ {
+		if f := Ceil(vfceilSC[i]); !alike(ceilSC[i], f) {
+			t.Errorf("Ceil(%g) = %g, want %g", vfceilSC[i], f, ceilSC[i])
+		}
+	}
+}
+
+func TestCopysign(t *testing.T) {
+	for i := 0; i < len(vf); i++ {
+		if f := Copysign(vf[i], -1); copysign[i] != f {
+			t.Errorf("Copysign(%g, -1) = %g, want %g", vf[i], f, copysign[i])
+		}
+	}
+	for i := 0; i < len(vf); i++ {
+		if f := Copysign(vf[i], 1); -copysign[i] != f {
+			t.Errorf("Copysign(%g, 1) = %g, want %g", vf[i], f, -copysign[i])
+		}
+	}
+	for i := 0; i < len(vfcopysignSC); i++ {
+		if f := Copysign(vfcopysignSC[i], -1); !alike(copysignSC[i], f) {
+			t.Errorf("Copysign(%g, -1) = %g, want %g", vfcopysignSC[i], f, copysignSC[i])
+		}
+	}
+}
+
+func TestCos(t *testing.T) {
+	for i := 0; i < len(vf); i++ {
+		if f := Cos(vf[i]); !veryclose(cos[i], f) {
+			t.Errorf("Cos(%g) = %g, want %g", vf[i], f, cos[i])
+		}
+	}
+	for i := 0; i < len(vfcosSC); i++ {
+		if f := Cos(vfcosSC[i]); !alike(cosSC[i], f) {
+			t.Errorf("Cos(%g) = %g, want %g", vfcosSC[i], f, cosSC[i])
+		}
+	}
+}
+
+func TestCosh(t *testing.T) {
+	for i := 0; i < len(vf); i++ {
+		if f := Cosh(vf[i]); !close(cosh[i], f) {
+			t.Errorf("Cosh(%g) = %g, want %g", vf[i], f, cosh[i])
+		}
+	}
+	for i := 0; i < len(vfcoshSC); i++ {
+		if f := Cosh(vfcoshSC[i]); !alike(coshSC[i], f) {
+			t.Errorf("Cosh(%g) = %g, want %g", vfcoshSC[i], f, coshSC[i])
+		}
+	}
+}
+
+func TestErf(t *testing.T) {
+	for i := 0; i < len(vf); i++ {
+		a := vf[i] / 10
+		if f := Erf(a); !veryclose(erf[i], f) {
+			t.Errorf("Erf(%g) = %g, want %g", a, f, erf[i])
+		}
+	}
+	for i := 0; i < len(vferfSC); i++ {
+		if f := Erf(vferfSC[i]); !alike(erfSC[i], f) {
+			t.Errorf("Erf(%g) = %g, want %g", vferfSC[i], f, erfSC[i])
+		}
+	}
+}
+
+func TestErfc(t *testing.T) {
+	for i := 0; i < len(vf); i++ {
+		a := vf[i] / 10
+		if f := Erfc(a); !veryclose(erfc[i], f) {
+			t.Errorf("Erfc(%g) = %g, want %g", a, f, erfc[i])
+		}
+	}
+	for i := 0; i < len(vferfcSC); i++ {
+		if f := Erfc(vferfcSC[i]); !alike(erfcSC[i], f) {
+			t.Errorf("Erfc(%g) = %g, want %g", vferfcSC[i], f, erfcSC[i])
+		}
+	}
+}
+
+func TestExp(t *testing.T) {
+	testExp(t, Exp, "Exp")
+	testExp(t, ExpGo, "ExpGo")
+}
+
+func testExp(t *testing.T, Exp func(float64) float64, name string) {
+	for i := 0; i < len(vf); i++ {
+		if f := Exp(vf[i]); !close(exp[i], f) {
+			t.Errorf("%s(%g) = %g, want %g", name, vf[i], f, exp[i])
+		}
+	}
+	for i := 0; i < len(vfexpSC); i++ {
+		if f := Exp(vfexpSC[i]); !alike(expSC[i], f) {
+			t.Errorf("%s(%g) = %g, want %g", name, vfexpSC[i], f, expSC[i])
+		}
+	}
+}
+
+func TestExpm1(t *testing.T) {
+	for i := 0; i < len(vf); i++ {
+		a := vf[i] / 100
+		if f := Expm1(a); !veryclose(expm1[i], f) {
+			t.Errorf("Expm1(%g) = %g, want %g", a, f, expm1[i])
+		}
+	}
+	for i := 0; i < len(vfexpm1SC); i++ {
+		if f := Expm1(vfexpm1SC[i]); !alike(expm1SC[i], f) {
+			t.Errorf("Expm1(%g) = %g, want %g", vfexpm1SC[i], f, expm1SC[i])
+		}
+	}
+}
+
+func TestExp2(t *testing.T) {
+	testExp2(t, Exp2, "Exp2")
+	testExp2(t, Exp2Go, "Exp2Go")
+}
+
+func testExp2(t *testing.T, Exp2 func(float64) float64, name string) {
+	for i := 0; i < len(vf); i++ {
+		if f := Exp2(vf[i]); !close(exp2[i], f) {
+			t.Errorf("%s(%g) = %g, want %g", name, vf[i], f, exp2[i])
+		}
+	}
+	for i := 0; i < len(vfexpSC); i++ {
+		if f := Exp2(vfexpSC[i]); !alike(expSC[i], f) {
+			t.Errorf("%s(%g) = %g, want %g", name, vfexpSC[i], f, expSC[i])
+		}
+	}
+	for n := -1074; n < 1024; n++ {
+		f := Exp2(float64(n))
+		vf := Ldexp(1, n)
+		if f != vf {
+			t.Errorf("%s(%d) = %g, want %g", name, n, f, vf)
+		}
+	}
+}
+
+func TestAbs(t *testing.T) {
+	for i := 0; i < len(vf); i++ {
+		if f := Abs(vf[i]); fabs[i] != f {
+			t.Errorf("Abs(%g) = %g, want %g", vf[i], f, fabs[i])
+		}
+	}
+	for i := 0; i < len(vffabsSC); i++ {
+		if f := Abs(vffabsSC[i]); !alike(fabsSC[i], f) {
+			t.Errorf("Abs(%g) = %g, want %g", vffabsSC[i], f, fabsSC[i])
+		}
+	}
+}
+
+func TestDim(t *testing.T) {
+	for i := 0; i < len(vf); i++ {
+		if f := Dim(vf[i], 0); fdim[i] != f {
+			t.Errorf("Dim(%g, %g) = %g, want %g", vf[i], 0.0, f, fdim[i])
+		}
+	}
+	for i := 0; i < len(vffdimSC); i++ {
+		if f := Dim(vffdimSC[i][0], vffdimSC[i][1]); !alike(fdimSC[i], f) {
+			t.Errorf("Dim(%g, %g) = %g, want %g", vffdimSC[i][0], vffdimSC[i][1], f, fdimSC[i])
+		}
+	}
+}
+
+func TestFloor(t *testing.T) {
+	for i := 0; i < len(vf); i++ {
+		if f := Floor(vf[i]); floor[i] != f {
+			t.Errorf("Floor(%g) = %g, want %g", vf[i], f, floor[i])
+		}
+	}
+	for i := 0; i < len(vfceilSC); i++ {
+		if f := Floor(vfceilSC[i]); !alike(ceilSC[i], f) {
+			t.Errorf("Floor(%g) = %g, want %g", vfceilSC[i], f, ceilSC[i])
+		}
+	}
+}
+
+func TestMax(t *testing.T) {
+	for i := 0; i < len(vf); i++ {
+		if f := Max(vf[i], ceil[i]); ceil[i] != f {
+			t.Errorf("Max(%g, %g) = %g, want %g", vf[i], ceil[i], f, ceil[i])
+		}
+	}
+	for i := 0; i < len(vffdimSC); i++ {
+		if f := Max(vffdimSC[i][0], vffdimSC[i][1]); !alike(fmaxSC[i], f) {
+			t.Errorf("Max(%g, %g) = %g, want %g", vffdimSC[i][0], vffdimSC[i][1], f, fmaxSC[i])
+		}
+	}
+}
+
+func TestMin(t *testing.T) {
+	for i := 0; i < len(vf); i++ {
+		if f := Min(vf[i], floor[i]); floor[i] != f {
+			t.Errorf("Min(%g, %g) = %g, want %g", vf[i], floor[i], f, floor[i])
+		}
+	}
+	for i := 0; i < len(vffdimSC); i++ {
+		if f := Min(vffdimSC[i][0], vffdimSC[i][1]); !alike(fminSC[i], f) {
+			t.Errorf("Min(%g, %g) = %g, want %g", vffdimSC[i][0], vffdimSC[i][1], f, fminSC[i])
+		}
+	}
+}
+
+func TestMod(t *testing.T) {
+	for i := 0; i < len(vf); i++ {
+		if f := Mod(10, vf[i]); fmod[i] != f {
+			t.Errorf("Mod(10, %g) = %g, want %g", vf[i], f, fmod[i])
+		}
+	}
+	for i := 0; i < len(vffmodSC); i++ {
+		if f := Mod(vffmodSC[i][0], vffmodSC[i][1]); !alike(fmodSC[i], f) {
+			t.Errorf("Mod(%g, %g) = %g, want %g", vffmodSC[i][0], vffmodSC[i][1], f, fmodSC[i])
+		}
+	}
+}
+
+func TestFrexp(t *testing.T) {
+	for i := 0; i < len(vf); i++ {
+		if f, j := Frexp(vf[i]); !veryclose(frexp[i].f, f) || frexp[i].i != j {
+			t.Errorf("Frexp(%g) = %g, %d, want %g, %d", vf[i], f, j, frexp[i].f, frexp[i].i)
+		}
+	}
+	for i := 0; i < len(vffrexpSC); i++ {
+		if f, j := Frexp(vffrexpSC[i]); !alike(frexpSC[i].f, f) || frexpSC[i].i != j {
+			t.Errorf("Frexp(%g) = %g, %d, want %g, %d", vffrexpSC[i], f, j, frexpSC[i].f, frexpSC[i].i)
+		}
+	}
+	for i := 0; i < len(vffrexpBC); i++ {
+		if f, j := Frexp(vffrexpBC[i]); !alike(frexpBC[i].f, f) || frexpBC[i].i != j {
+			t.Errorf("Frexp(%g) = %g, %d, want %g, %d", vffrexpBC[i], f, j, frexpBC[i].f, frexpBC[i].i)
+		}
+	}
+}
+
+func TestGamma(t *testing.T) {
+	for i := 0; i < len(vf); i++ {
+		if f := Gamma(vf[i]); !close(gamma[i], f) {
+			t.Errorf("Gamma(%g) = %g, want %g", vf[i], f, gamma[i])
+		}
+	}
+	for i := 0; i < len(vfgammaSC); i++ {
+		if f := Gamma(vfgammaSC[i]); !alike(gammaSC[i], f) {
+			t.Errorf("Gamma(%g) = %g, want %g", vfgammaSC[i], f, gammaSC[i])
+		}
+	}
+}
+
+func TestHypot(t *testing.T) {
+	for i := 0; i < len(vf); i++ {
+		a := Abs(1e200 * tanh[i] * Sqrt(2))
+		if f := Hypot(1e200*tanh[i], 1e200*tanh[i]); !veryclose(a, f) {
+			t.Errorf("Hypot(%g, %g) = %g, want %g", 1e200*tanh[i], 1e200*tanh[i], f, a)
+		}
+	}
+	for i := 0; i < len(vfhypotSC); i++ {
+		if f := Hypot(vfhypotSC[i][0], vfhypotSC[i][1]); !alike(hypotSC[i], f) {
+			t.Errorf("Hypot(%g, %g) = %g, want %g", vfhypotSC[i][0], vfhypotSC[i][1], f, hypotSC[i])
+		}
+	}
+}
+
+func TestHypotGo(t *testing.T) {
+	for i := 0; i < len(vf); i++ {
+		a := Abs(1e200 * tanh[i] * Sqrt(2))
+		if f := HypotGo(1e200*tanh[i], 1e200*tanh[i]); !veryclose(a, f) {
+			t.Errorf("HypotGo(%g, %g) = %g, want %g", 1e200*tanh[i], 1e200*tanh[i], f, a)
+		}
+	}
+	for i := 0; i < len(vfhypotSC); i++ {
+		if f := HypotGo(vfhypotSC[i][0], vfhypotSC[i][1]); !alike(hypotSC[i], f) {
+			t.Errorf("HypotGo(%g, %g) = %g, want %g", vfhypotSC[i][0], vfhypotSC[i][1], f, hypotSC[i])
+		}
+	}
+}
+
+func TestIlogb(t *testing.T) {
+	for i := 0; i < len(vf); i++ {
+		a := frexp[i].i - 1 // adjust because fr in the interval [½, 1)
+		if e := Ilogb(vf[i]); a != e {
+			t.Errorf("Ilogb(%g) = %d, want %d", vf[i], e, a)
+		}
+	}
+	for i := 0; i < len(vflogbSC); i++ {
+		if e := Ilogb(vflogbSC[i]); ilogbSC[i] != e {
+			t.Errorf("Ilogb(%g) = %d, want %d", vflogbSC[i], e, ilogbSC[i])
+		}
+	}
+	for i := 0; i < len(vffrexpBC); i++ {
+		if e := Ilogb(vffrexpBC[i]); int(logbBC[i]) != e {
+			t.Errorf("Ilogb(%g) = %d, want %d", vffrexpBC[i], e, int(logbBC[i]))
+		}
+	}
+}
+
+func TestJ0(t *testing.T) {
+	for i := 0; i < len(vf); i++ {
+		if f := J0(vf[i]); !soclose(j0[i], f, 4e-14) {
+			t.Errorf("J0(%g) = %g, want %g", vf[i], f, j0[i])
+		}
+	}
+	for i := 0; i < len(vfj0SC); i++ {
+		if f := J0(vfj0SC[i]); !alike(j0SC[i], f) {
+			t.Errorf("J0(%g) = %g, want %g", vfj0SC[i], f, j0SC[i])
+		}
+	}
+}
+
+func TestJ1(t *testing.T) {
+	for i := 0; i < len(vf); i++ {
+		if f := J1(vf[i]); !close(j1[i], f) {
+			t.Errorf("J1(%g) = %g, want %g", vf[i], f, j1[i])
+		}
+	}
+	for i := 0; i < len(vfj0SC); i++ {
+		if f := J1(vfj0SC[i]); !alike(j1SC[i], f) {
+			t.Errorf("J1(%g) = %g, want %g", vfj0SC[i], f, j1SC[i])
+		}
+	}
+}
+
+func TestJn(t *testing.T) {
+	for i := 0; i < len(vf); i++ {
+		if f := Jn(2, vf[i]); !close(j2[i], f) {
+			t.Errorf("Jn(2, %g) = %g, want %g", vf[i], f, j2[i])
+		}
+		if f := Jn(-3, vf[i]); !close(jM3[i], f) {
+			t.Errorf("Jn(-3, %g) = %g, want %g", vf[i], f, jM3[i])
+		}
+	}
+	for i := 0; i < len(vfj0SC); i++ {
+		if f := Jn(2, vfj0SC[i]); !alike(j2SC[i], f) {
+			t.Errorf("Jn(2, %g) = %g, want %g", vfj0SC[i], f, j2SC[i])
+		}
+		if f := Jn(-3, vfj0SC[i]); !alike(jM3SC[i], f) {
+			t.Errorf("Jn(-3, %g) = %g, want %g", vfj0SC[i], f, jM3SC[i])
+		}
+	}
+}
+
+func TestLdexp(t *testing.T) {
+	for i := 0; i < len(vf); i++ {
+		if f := Ldexp(frexp[i].f, frexp[i].i); !veryclose(vf[i], f) {
+			t.Errorf("Ldexp(%g, %d) = %g, want %g", frexp[i].f, frexp[i].i, f, vf[i])
+		}
+	}
+	for i := 0; i < len(vffrexpSC); i++ {
+		if f := Ldexp(frexpSC[i].f, frexpSC[i].i); !alike(vffrexpSC[i], f) {
+			t.Errorf("Ldexp(%g, %d) = %g, want %g", frexpSC[i].f, frexpSC[i].i, f, vffrexpSC[i])
+		}
+	}
+	for i := 0; i < len(vfldexpSC); i++ {
+		if f := Ldexp(vfldexpSC[i].f, vfldexpSC[i].i); !alike(ldexpSC[i], f) {
+			t.Errorf("Ldexp(%g, %d) = %g, want %g", vfldexpSC[i].f, vfldexpSC[i].i, f, ldexpSC[i])
+		}
+	}
+	for i := 0; i < len(vffrexpBC); i++ {
+		if f := Ldexp(frexpBC[i].f, frexpBC[i].i); !alike(vffrexpBC[i], f) {
+			t.Errorf("Ldexp(%g, %d) = %g, want %g", frexpBC[i].f, frexpBC[i].i, f, vffrexpBC[i])
+		}
+	}
+	for i := 0; i < len(vfldexpBC); i++ {
+		if f := Ldexp(vfldexpBC[i].f, vfldexpBC[i].i); !alike(ldexpBC[i], f) {
+			t.Errorf("Ldexp(%g, %d) = %g, want %g", vfldexpBC[i].f, vfldexpBC[i].i, f, ldexpBC[i])
+		}
+	}
+}
+
+func TestLgamma(t *testing.T) {
+	for i := 0; i < len(vf); i++ {
+		if f, s := Lgamma(vf[i]); !close(lgamma[i].f, f) || lgamma[i].i != s {
+			t.Errorf("Lgamma(%g) = %g, %d, want %g, %d", vf[i], f, s, lgamma[i].f, lgamma[i].i)
+		}
+	}
+	for i := 0; i < len(vflgammaSC); i++ {
+		if f, s := Lgamma(vflgammaSC[i]); !alike(lgammaSC[i].f, f) || lgammaSC[i].i != s {
+			t.Errorf("Lgamma(%g) = %g, %d, want %g, %d", vflgammaSC[i], f, s, lgammaSC[i].f, lgammaSC[i].i)
+		}
+	}
+}
+
+func TestLog(t *testing.T) {
+	for i := 0; i < len(vf); i++ {
+		a := Abs(vf[i])
+		if f := Log(a); log[i] != f {
+			t.Errorf("Log(%g) = %g, want %g", a, f, log[i])
+		}
+	}
+	if f := Log(10); f != Ln10 {
+		t.Errorf("Log(%g) = %g, want %g", 10.0, f, Ln10)
+	}
+	for i := 0; i < len(vflogSC); i++ {
+		if f := Log(vflogSC[i]); !alike(logSC[i], f) {
+			t.Errorf("Log(%g) = %g, want %g", vflogSC[i], f, logSC[i])
+		}
+	}
+}
+
+func TestLogb(t *testing.T) {
+	for i := 0; i < len(vf); i++ {
+		if f := Logb(vf[i]); logb[i] != f {
+			t.Errorf("Logb(%g) = %g, want %g", vf[i], f, logb[i])
+		}
+	}
+	for i := 0; i < len(vflogbSC); i++ {
+		if f := Logb(vflogbSC[i]); !alike(logbSC[i], f) {
+			t.Errorf("Logb(%g) = %g, want %g", vflogbSC[i], f, logbSC[i])
+		}
+	}
+	for i := 0; i < len(vffrexpBC); i++ {
+		if f := Logb(vffrexpBC[i]); !alike(logbBC[i], f) {
+			t.Errorf("Logb(%g) = %g, want %g", vffrexpBC[i], f, logbBC[i])
+		}
+	}
+}
+
+func TestLog10(t *testing.T) {
+	for i := 0; i < len(vf); i++ {
+		a := Abs(vf[i])
+		if f := Log10(a); !veryclose(log10[i], f) {
+			t.Errorf("Log10(%g) = %g, want %g", a, f, log10[i])
+		}
+	}
+	if f := Log10(E); f != Log10E {
+		t.Errorf("Log10(%g) = %g, want %g", E, f, Log10E)
+	}
+	for i := 0; i < len(vflogSC); i++ {
+		if f := Log10(vflogSC[i]); !alike(logSC[i], f) {
+			t.Errorf("Log10(%g) = %g, want %g", vflogSC[i], f, logSC[i])
+		}
+	}
+}
+
+func TestLog1p(t *testing.T) {
+	for i := 0; i < len(vf); i++ {
+		a := vf[i] / 100
+		if f := Log1p(a); !veryclose(log1p[i], f) {
+			t.Errorf("Log1p(%g) = %g, want %g", a, f, log1p[i])
+		}
+	}
+	a := 9.0
+	if f := Log1p(a); f != Ln10 {
+		t.Errorf("Log1p(%g) = %g, want %g", a, f, Ln10)
+	}
+	for i := 0; i < len(vflogSC); i++ {
+		if f := Log1p(vflog1pSC[i]); !alike(log1pSC[i], f) {
+			t.Errorf("Log1p(%g) = %g, want %g", vflog1pSC[i], f, log1pSC[i])
+		}
+	}
+}
+
+func TestLog2(t *testing.T) {
+	for i := 0; i < len(vf); i++ {
+		a := Abs(vf[i])
+		if f := Log2(a); !veryclose(log2[i], f) {
+			t.Errorf("Log2(%g) = %g, want %g", a, f, log2[i])
+		}
+	}
+	if f := Log2(E); f != Log2E {
+		t.Errorf("Log2(%g) = %g, want %g", E, f, Log2E)
+	}
+	for i := 0; i < len(vflogSC); i++ {
+		if f := Log2(vflogSC[i]); !alike(logSC[i], f) {
+			t.Errorf("Log2(%g) = %g, want %g", vflogSC[i], f, logSC[i])
+		}
+	}
+	for i := -1074; i <= 1023; i++ {
+		f := Ldexp(1, i)
+		l := Log2(f)
+		if l != float64(i) {
+			t.Errorf("Log2(2**%d) = %g, want %d", i, l, i)
+		}
+	}
+}
+
+func TestModf(t *testing.T) {
+	for i := 0; i < len(vf); i++ {
+		if f, g := Modf(vf[i]); !veryclose(modf[i][0], f) || !veryclose(modf[i][1], g) {
+			t.Errorf("Modf(%g) = %g, %g, want %g, %g", vf[i], f, g, modf[i][0], modf[i][1])
+		}
+	}
+	for i := 0; i < len(vfmodfSC); i++ {
+		if f, g := Modf(vfmodfSC[i]); !alike(modfSC[i][0], f) || !alike(modfSC[i][1], g) {
+			t.Errorf("Modf(%g) = %g, %g, want %g, %g", vfmodfSC[i], f, g, modfSC[i][0], modfSC[i][1])
+		}
+	}
+}
+
+func TestNextafter32(t *testing.T) {
+	for i := 0; i < len(vf); i++ {
+		vfi := float32(vf[i])
+		if f := Nextafter32(vfi, 10); nextafter32[i] != f {
+			t.Errorf("Nextafter32(%g, %g) = %g want %g", vfi, 10.0, f, nextafter32[i])
+		}
+	}
+	for i := 0; i < len(vfnextafter32SC); i++ {
+		if f := Nextafter32(vfnextafter32SC[i][0], vfnextafter32SC[i][1]); !alike(float64(nextafter32SC[i]), float64(f)) {
+			t.Errorf("Nextafter32(%g, %g) = %g want %g", vfnextafter32SC[i][0], vfnextafter32SC[i][1], f, nextafter32SC[i])
+		}
+	}
+}
+
+func TestNextafter64(t *testing.T) {
+	for i := 0; i < len(vf); i++ {
+		if f := Nextafter(vf[i], 10); nextafter64[i] != f {
+			t.Errorf("Nextafter64(%g, %g) = %g want %g", vf[i], 10.0, f, nextafter64[i])
+		}
+	}
+	for i := 0; i < len(vfnextafter64SC); i++ {
+		if f := Nextafter(vfnextafter64SC[i][0], vfnextafter64SC[i][1]); !alike(nextafter64SC[i], f) {
+			t.Errorf("Nextafter64(%g, %g) = %g want %g", vfnextafter64SC[i][0], vfnextafter64SC[i][1], f, nextafter64SC[i])
+		}
+	}
+}
+
+func TestPow(t *testing.T) {
+	for i := 0; i < len(vf); i++ {
+		if f := Pow(10, vf[i]); !close(pow[i], f) {
+			t.Errorf("Pow(10, %g) = %g, want %g", vf[i], f, pow[i])
+		}
+	}
+	for i := 0; i < len(vfpowSC); i++ {
+		if f := Pow(vfpowSC[i][0], vfpowSC[i][1]); !alike(powSC[i], f) {
+			t.Errorf("Pow(%g, %g) = %g, want %g", vfpowSC[i][0], vfpowSC[i][1], f, powSC[i])
+		}
+	}
+}
+
+func TestPow10(t *testing.T) {
+	for i := 0; i < len(vfpow10SC); i++ {
+		if f := Pow10(vfpow10SC[i]); !alike(pow10SC[i], f) {
+			t.Errorf("Pow10(%d) = %g, want %g", vfpow10SC[i], f, pow10SC[i])
+		}
+	}
+}
+
+func TestRemainder(t *testing.T) {
+	for i := 0; i < len(vf); i++ {
+		if f := Remainder(10, vf[i]); remainder[i] != f {
+			t.Errorf("Remainder(10, %g) = %g, want %g", vf[i], f, remainder[i])
+		}
+	}
+	for i := 0; i < len(vffmodSC); i++ {
+		if f := Remainder(vffmodSC[i][0], vffmodSC[i][1]); !alike(fmodSC[i], f) {
+			t.Errorf("Remainder(%g, %g) = %g, want %g", vffmodSC[i][0], vffmodSC[i][1], f, fmodSC[i])
+		}
+	}
+}
+
+func TestSignbit(t *testing.T) {
+	for i := 0; i < len(vf); i++ {
+		if f := Signbit(vf[i]); signbit[i] != f {
+			t.Errorf("Signbit(%g) = %t, want %t", vf[i], f, signbit[i])
+		}
+	}
+	for i := 0; i < len(vfsignbitSC); i++ {
+		if f := Signbit(vfsignbitSC[i]); signbitSC[i] != f {
+			t.Errorf("Signbit(%g) = %t, want %t", vfsignbitSC[i], f, signbitSC[i])
+		}
+	}
+}
+func TestSin(t *testing.T) {
+	for i := 0; i < len(vf); i++ {
+		if f := Sin(vf[i]); !veryclose(sin[i], f) {
+			t.Errorf("Sin(%g) = %g, want %g", vf[i], f, sin[i])
+		}
+	}
+	for i := 0; i < len(vfsinSC); i++ {
+		if f := Sin(vfsinSC[i]); !alike(sinSC[i], f) {
+			t.Errorf("Sin(%g) = %g, want %g", vfsinSC[i], f, sinSC[i])
+		}
+	}
+}
+
+func TestSincos(t *testing.T) {
+	for i := 0; i < len(vf); i++ {
+		if s, c := Sincos(vf[i]); !veryclose(sin[i], s) || !veryclose(cos[i], c) {
+			t.Errorf("Sincos(%g) = %g, %g want %g, %g", vf[i], s, c, sin[i], cos[i])
+		}
+	}
+}
+
+func TestSinh(t *testing.T) {
+	for i := 0; i < len(vf); i++ {
+		if f := Sinh(vf[i]); !close(sinh[i], f) {
+			t.Errorf("Sinh(%g) = %g, want %g", vf[i], f, sinh[i])
+		}
+	}
+	for i := 0; i < len(vfsinhSC); i++ {
+		if f := Sinh(vfsinhSC[i]); !alike(sinhSC[i], f) {
+			t.Errorf("Sinh(%g) = %g, want %g", vfsinhSC[i], f, sinhSC[i])
+		}
+	}
+}
+
+func TestSqrt(t *testing.T) {
+	for i := 0; i < len(vf); i++ {
+		a := Abs(vf[i])
+		if f := SqrtGo(a); sqrt[i] != f {
+			t.Errorf("SqrtGo(%g) = %g, want %g", a, f, sqrt[i])
+		}
+		a = Abs(vf[i])
+		if f := Sqrt(a); sqrt[i] != f {
+			t.Errorf("Sqrt(%g) = %g, want %g", a, f, sqrt[i])
+		}
+	}
+	for i := 0; i < len(vfsqrtSC); i++ {
+		if f := SqrtGo(vfsqrtSC[i]); !alike(sqrtSC[i], f) {
+			t.Errorf("SqrtGo(%g) = %g, want %g", vfsqrtSC[i], f, sqrtSC[i])
+		}
+		if f := Sqrt(vfsqrtSC[i]); !alike(sqrtSC[i], f) {
+			t.Errorf("Sqrt(%g) = %g, want %g", vfsqrtSC[i], f, sqrtSC[i])
+		}
+	}
+}
+
+func TestTan(t *testing.T) {
+	for i := 0; i < len(vf); i++ {
+		if f := Tan(vf[i]); !veryclose(tan[i], f) {
+			t.Errorf("Tan(%g) = %g, want %g", vf[i], f, tan[i])
+		}
+	}
+	// same special cases as Sin
+	for i := 0; i < len(vfsinSC); i++ {
+		if f := Tan(vfsinSC[i]); !alike(sinSC[i], f) {
+			t.Errorf("Tan(%g) = %g, want %g", vfsinSC[i], f, sinSC[i])
+		}
+	}
+}
+
+func TestTanh(t *testing.T) {
+	for i := 0; i < len(vf); i++ {
+		if f := Tanh(vf[i]); !veryclose(tanh[i], f) {
+			t.Errorf("Tanh(%g) = %g, want %g", vf[i], f, tanh[i])
+		}
+	}
+	for i := 0; i < len(vftanhSC); i++ {
+		if f := Tanh(vftanhSC[i]); !alike(tanhSC[i], f) {
+			t.Errorf("Tanh(%g) = %g, want %g", vftanhSC[i], f, tanhSC[i])
+		}
+	}
+}
+
+func TestTrunc(t *testing.T) {
+	for i := 0; i < len(vf); i++ {
+		if f := Trunc(vf[i]); trunc[i] != f {
+			t.Errorf("Trunc(%g) = %g, want %g", vf[i], f, trunc[i])
+		}
+	}
+	for i := 0; i < len(vfceilSC); i++ {
+		if f := Trunc(vfceilSC[i]); !alike(ceilSC[i], f) {
+			t.Errorf("Trunc(%g) = %g, want %g", vfceilSC[i], f, ceilSC[i])
+		}
+	}
+}
+
+func TestY0(t *testing.T) {
+	for i := 0; i < len(vf); i++ {
+		a := Abs(vf[i])
+		if f := Y0(a); !close(y0[i], f) {
+			t.Errorf("Y0(%g) = %g, want %g", a, f, y0[i])
+		}
+	}
+	for i := 0; i < len(vfy0SC); i++ {
+		if f := Y0(vfy0SC[i]); !alike(y0SC[i], f) {
+			t.Errorf("Y0(%g) = %g, want %g", vfy0SC[i], f, y0SC[i])
+		}
+	}
+}
+
+func TestY1(t *testing.T) {
+	for i := 0; i < len(vf); i++ {
+		a := Abs(vf[i])
+		if f := Y1(a); !soclose(y1[i], f, 2e-14) {
+			t.Errorf("Y1(%g) = %g, want %g", a, f, y1[i])
+		}
+	}
+	for i := 0; i < len(vfy0SC); i++ {
+		if f := Y1(vfy0SC[i]); !alike(y1SC[i], f) {
+			t.Errorf("Y1(%g) = %g, want %g", vfy0SC[i], f, y1SC[i])
+		}
+	}
+}
+
+func TestYn(t *testing.T) {
+	for i := 0; i < len(vf); i++ {
+		a := Abs(vf[i])
+		if f := Yn(2, a); !close(y2[i], f) {
+			t.Errorf("Yn(2, %g) = %g, want %g", a, f, y2[i])
+		}
+		if f := Yn(-3, a); !close(yM3[i], f) {
+			t.Errorf("Yn(-3, %g) = %g, want %g", a, f, yM3[i])
+		}
+	}
+	for i := 0; i < len(vfy0SC); i++ {
+		if f := Yn(2, vfy0SC[i]); !alike(y2SC[i], f) {
+			t.Errorf("Yn(2, %g) = %g, want %g", vfy0SC[i], f, y2SC[i])
+		}
+		if f := Yn(-3, vfy0SC[i]); !alike(yM3SC[i], f) {
+			t.Errorf("Yn(-3, %g) = %g, want %g", vfy0SC[i], f, yM3SC[i])
+		}
+	}
+}
+
+// Check that math functions of high angle values
+// return accurate results. [Since (vf[i] + large) - large != vf[i],
+// testing for Trig(vf[i] + large) == Trig(vf[i]), where large is
+// a multiple of 2*Pi, is misleading.]
+func TestLargeCos(t *testing.T) {
+	large := float64(100000 * Pi)
+	for i := 0; i < len(vf); i++ {
+		f1 := cosLarge[i]
+		f2 := Cos(vf[i] + large)
+		if !close(f1, f2) {
+			t.Errorf("Cos(%g) = %g, want %g", vf[i]+large, f2, f1)
+		}
+	}
+}
+
+func TestLargeSin(t *testing.T) {
+	large := float64(100000 * Pi)
+	for i := 0; i < len(vf); i++ {
+		f1 := sinLarge[i]
+		f2 := Sin(vf[i] + large)
+		if !close(f1, f2) {
+			t.Errorf("Sin(%g) = %g, want %g", vf[i]+large, f2, f1)
+		}
+	}
+}
+
+func TestLargeSincos(t *testing.T) {
+	large := float64(100000 * Pi)
+	for i := 0; i < len(vf); i++ {
+		f1, g1 := sinLarge[i], cosLarge[i]
+		f2, g2 := Sincos(vf[i] + large)
+		if !close(f1, f2) || !close(g1, g2) {
+			t.Errorf("Sincos(%g) = %g, %g, want %g, %g", vf[i]+large, f2, g2, f1, g1)
+		}
+	}
+}
+
+func TestLargeTan(t *testing.T) {
+	large := float64(100000 * Pi)
+	for i := 0; i < len(vf); i++ {
+		f1 := tanLarge[i]
+		f2 := Tan(vf[i] + large)
+		if !close(f1, f2) {
+			t.Errorf("Tan(%g) = %g, want %g", vf[i]+large, f2, f1)
+		}
+	}
+}
+
+// Check that math constants are accepted by compiler
+// and have right value (assumes strconv.ParseFloat works).
+// http://code.google.com/p/go/issues/detail?id=201
+
+type floatTest struct {
+	val  interface{}
+	name string
+	str  string
+}
+
+var floatTests = []floatTest{
+	{float64(MaxFloat64), "MaxFloat64", "1.7976931348623157e+308"},
+	{float64(SmallestNonzeroFloat64), "SmallestNonzeroFloat64", "5e-324"},
+	{float32(MaxFloat32), "MaxFloat32", "3.4028235e+38"},
+	{float32(SmallestNonzeroFloat32), "SmallestNonzeroFloat32", "1e-45"},
+}
+
+func TestFloatMinMax(t *testing.T) {
+	for _, tt := range floatTests {
+		s := fmt.Sprint(tt.val)
+		if s != tt.str {
+			t.Errorf("Sprint(%v) = %s, want %s", tt.name, s, tt.str)
+		}
+	}
+}
+
+// Benchmarks
+
+func BenchmarkAcos(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		Acos(.5)
+	}
+}
+
+func BenchmarkAcosh(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		Acosh(1.5)
+	}
+}
+
+func BenchmarkAsin(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		Asin(.5)
+	}
+}
+
+func BenchmarkAsinh(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		Asinh(.5)
+	}
+}
+
+func BenchmarkAtan(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		Atan(.5)
+	}
+}
+
+func BenchmarkAtanh(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		Atanh(.5)
+	}
+}
+
+func BenchmarkAtan2(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		Atan2(.5, 1)
+	}
+}
+
+func BenchmarkCbrt(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		Cbrt(10)
+	}
+}
+
+func BenchmarkCeil(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		Ceil(.5)
+	}
+}
+
+func BenchmarkCopysign(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		Copysign(.5, -1)
+	}
+}
+
+func BenchmarkCos(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		Cos(.5)
+	}
+}
+
+func BenchmarkCosh(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		Cosh(2.5)
+	}
+}
+
+func BenchmarkErf(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		Erf(.5)
+	}
+}
+
+func BenchmarkErfc(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		Erfc(.5)
+	}
+}
+
+func BenchmarkExp(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		Exp(.5)
+	}
+}
+
+func BenchmarkExpGo(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		ExpGo(.5)
+	}
+}
+
+func BenchmarkExpm1(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		Expm1(.5)
+	}
+}
+
+func BenchmarkExp2(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		Exp2(.5)
+	}
+}
+
+func BenchmarkExp2Go(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		Exp2Go(.5)
+	}
+}
+
+func BenchmarkAbs(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		Abs(.5)
+	}
+}
+
+func BenchmarkDim(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		Dim(10, 3)
+	}
+}
+
+func BenchmarkFloor(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		Floor(.5)
+	}
+}
+
+func BenchmarkMax(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		Max(10, 3)
+	}
+}
+
+func BenchmarkMin(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		Min(10, 3)
+	}
+}
+
+func BenchmarkMod(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		Mod(10, 3)
+	}
+}
+
+func BenchmarkFrexp(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		Frexp(8)
+	}
+}
+
+func BenchmarkGamma(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		Gamma(2.5)
+	}
+}
+
+func BenchmarkHypot(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		Hypot(3, 4)
+	}
+}
+
+func BenchmarkHypotGo(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		HypotGo(3, 4)
+	}
+}
+
+func BenchmarkIlogb(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		Ilogb(.5)
+	}
+}
+
+func BenchmarkJ0(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		J0(2.5)
+	}
+}
+
+func BenchmarkJ1(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		J1(2.5)
+	}
+}
+
+func BenchmarkJn(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		Jn(2, 2.5)
+	}
+}
+
+func BenchmarkLdexp(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		Ldexp(.5, 2)
+	}
+}
+
+func BenchmarkLgamma(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		Lgamma(2.5)
+	}
+}
+
+func BenchmarkLog(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		Log(.5)
+	}
+}
+
+func BenchmarkLogb(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		Logb(.5)
+	}
+}
+
+func BenchmarkLog1p(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		Log1p(.5)
+	}
+}
+
+func BenchmarkLog10(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		Log10(.5)
+	}
+}
+
+func BenchmarkLog2(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		Log2(.5)
+	}
+}
+
+func BenchmarkModf(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		Modf(1.5)
+	}
+}
+
+func BenchmarkNextafter32(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		Nextafter32(.5, 1)
+	}
+}
+
+func BenchmarkNextafter64(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		Nextafter(.5, 1)
+	}
+}
+
+func BenchmarkPowInt(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		Pow(2, 2)
+	}
+}
+
+func BenchmarkPowFrac(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		Pow(2.5, 1.5)
+	}
+}
+
+func BenchmarkPow10Pos(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		Pow10(300)
+	}
+}
+
+func BenchmarkPow10Neg(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		Pow10(-300)
+	}
+}
+
+func BenchmarkRemainder(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		Remainder(10, 3)
+	}
+}
+
+func BenchmarkSignbit(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		Signbit(2.5)
+	}
+}
+
+func BenchmarkSin(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		Sin(.5)
+	}
+}
+
+func BenchmarkSincos(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		Sincos(.5)
+	}
+}
+
+func BenchmarkSinh(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		Sinh(2.5)
+	}
+}
+
+func BenchmarkSqrt(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		Sqrt(10)
+	}
+}
+
+func BenchmarkSqrtGo(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		SqrtGo(10)
+	}
+}
+
+func BenchmarkTan(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		Tan(.5)
+	}
+}
+
+func BenchmarkTanh(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		Tanh(2.5)
+	}
+}
+func BenchmarkTrunc(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		Trunc(.5)
+	}
+}
+
+func BenchmarkY0(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		Y0(2.5)
+	}
+}
+
+func BenchmarkY1(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		Y1(2.5)
+	}
+}
+
+func BenchmarkYn(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		Yn(2, 2.5)
+	}
+}
diff --git a/src/pkg/math/asin.go b/src/math/asin.go
similarity index 100%
rename from src/pkg/math/asin.go
rename to src/math/asin.go
diff --git a/src/math/asin_386.s b/src/math/asin_386.s
new file mode 100644
index 0000000..4f34e12
--- /dev/null
+++ b/src/math/asin_386.s
@@ -0,0 +1,30 @@
+// Copyright 2010 The Go 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 Asin(x float64) float64
+TEXT ·Asin(SB),NOSPLIT,$0
+	FMOVD   x+0(FP), F0  // F0=sin(x)
+	FMOVD   F0, F1       // F0=sin(x), F1=sin(x)
+	FMULD   F0, F0       // F0=sin(x)*sin(x), F1=sin(x)
+	FLD1                 // F0=1, F1=sin(x)*sin(x), F2=sin(x)
+	FSUBRDP F0, F1       // F0=1-sin(x)*sin(x) (=cos(x)*cos(x)), F1=sin(x)
+	FSQRT                // F0=cos(x), F1=sin(x)
+	FPATAN               // F0=arcsin(sin(x))=x
+	FMOVDP  F0, ret+8(FP)
+	RET
+
+// func Acos(x float64) float64
+TEXT ·Acos(SB),NOSPLIT,$0
+	FMOVD   x+0(FP), F0  // F0=cos(x)
+	FMOVD   F0, F1       // F0=cos(x), F1=cos(x)
+	FMULD   F0, F0       // F0=cos(x)*cos(x), F1=cos(x)
+	FLD1                 // F0=1, F1=cos(x)*cos(x), F2=cos(x)
+	FSUBRDP F0, F1       // F0=1-cos(x)*cos(x) (=sin(x)*sin(x)), F1=cos(x)
+	FSQRT                // F0=sin(x), F1=cos(x)
+	FXCHD   F0, F1       // F0=cos(x), F1=sin(x)
+	FPATAN               // F0=arccos(cos(x))=x
+	FMOVDP	F0, ret+8(FP)
+	RET
diff --git a/src/math/asin_amd64.s b/src/math/asin_amd64.s
new file mode 100644
index 0000000..1a43d48
--- /dev/null
+++ b/src/math/asin_amd64.s
@@ -0,0 +1,11 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+TEXT ·Asin(SB),NOSPLIT,$0
+	JMP ·asin(SB)
+
+TEXT ·Acos(SB),NOSPLIT,$0
+	JMP ·acos(SB)
diff --git a/src/pkg/math/asin_amd64p32.s b/src/math/asin_amd64p32.s
similarity index 100%
rename from src/pkg/math/asin_amd64p32.s
rename to src/math/asin_amd64p32.s
diff --git a/src/math/asin_arm.s b/src/math/asin_arm.s
new file mode 100644
index 0000000..8fe03b6
--- /dev/null
+++ b/src/math/asin_arm.s
@@ -0,0 +1,11 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+TEXT ·Asin(SB),NOSPLIT,$0
+	B ·asin(SB)
+
+TEXT ·Acos(SB),NOSPLIT,$0
+	B ·acos(SB)
diff --git a/src/pkg/math/asinh.go b/src/math/asinh.go
similarity index 100%
rename from src/pkg/math/asinh.go
rename to src/math/asinh.go
diff --git a/src/pkg/math/atan.go b/src/math/atan.go
similarity index 100%
rename from src/pkg/math/atan.go
rename to src/math/atan.go
diff --git a/src/pkg/math/atan2.go b/src/math/atan2.go
similarity index 100%
rename from src/pkg/math/atan2.go
rename to src/math/atan2.go
diff --git a/src/math/atan2_386.s b/src/math/atan2_386.s
new file mode 100644
index 0000000..31a74e7
--- /dev/null
+++ b/src/math/atan2_386.s
@@ -0,0 +1,13 @@
+// Copyright 2010 The Go 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 Atan2(y, x float64) float64	// =atan(y/x)
+TEXT ·Atan2(SB),NOSPLIT,$0
+	FMOVD   y+0(FP), F0  // F0=y
+	FMOVD   x+8(FP), F0  // F0=x, F1=y
+	FPATAN               // F0=atan(F1/F0)
+	FMOVDP  F0, ret+16(FP)
+	RET
diff --git a/src/math/atan2_amd64.s b/src/math/atan2_amd64.s
new file mode 100644
index 0000000..fc471f7
--- /dev/null
+++ b/src/math/atan2_amd64.s
@@ -0,0 +1,8 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+TEXT ·Atan2(SB),NOSPLIT,$0
+	JMP ·atan2(SB)
diff --git a/src/pkg/math/atan2_amd64p32.s b/src/math/atan2_amd64p32.s
similarity index 100%
rename from src/pkg/math/atan2_amd64p32.s
rename to src/math/atan2_amd64p32.s
diff --git a/src/math/atan2_arm.s b/src/math/atan2_arm.s
new file mode 100644
index 0000000..06c12ec
--- /dev/null
+++ b/src/math/atan2_arm.s
@@ -0,0 +1,8 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+TEXT ·Atan2(SB),NOSPLIT,$0
+	B ·atan2(SB)
diff --git a/src/math/atan_386.s b/src/math/atan_386.s
new file mode 100644
index 0000000..f3976b1
--- /dev/null
+++ b/src/math/atan_386.s
@@ -0,0 +1,13 @@
+// Copyright 2010 The Go 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 Atan(x float64) float64
+TEXT ·Atan(SB),NOSPLIT,$0
+	FMOVD   x+0(FP), F0  // F0=x
+	FLD1                 // F0=1, F1=x
+	FPATAN               // F0=atan(F1/F0)
+	FMOVDP  F0, ret+8(FP)
+	RET
diff --git a/src/math/atan_amd64.s b/src/math/atan_amd64.s
new file mode 100644
index 0000000..b801ae9
--- /dev/null
+++ b/src/math/atan_amd64.s
@@ -0,0 +1,8 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+TEXT ·Atan(SB),NOSPLIT,$0
+	JMP ·atan(SB)
diff --git a/src/pkg/math/atan_amd64p32.s b/src/math/atan_amd64p32.s
similarity index 100%
rename from src/pkg/math/atan_amd64p32.s
rename to src/math/atan_amd64p32.s
diff --git a/src/math/atan_arm.s b/src/math/atan_arm.s
new file mode 100644
index 0000000..d190a8b
--- /dev/null
+++ b/src/math/atan_arm.s
@@ -0,0 +1,8 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+TEXT ·Atan(SB),NOSPLIT,$0
+	B ·atan(SB)
diff --git a/src/pkg/math/atanh.go b/src/math/atanh.go
similarity index 100%
rename from src/pkg/math/atanh.go
rename to src/math/atanh.go
diff --git a/src/pkg/math/big/arith.go b/src/math/big/arith.go
similarity index 100%
rename from src/pkg/math/big/arith.go
rename to src/math/big/arith.go
diff --git a/src/math/big/arith_386.s b/src/math/big/arith_386.s
new file mode 100644
index 0000000..1b47c89
--- /dev/null
+++ b/src/math/big/arith_386.s
@@ -0,0 +1,278 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+// This file provides fast assembly versions for the elementary
+// arithmetic operations on vectors implemented in arith.go.
+
+// func mulWW(x, y Word) (z1, z0 Word)
+TEXT ·mulWW(SB),NOSPLIT,$0
+	MOVL x+0(FP), AX
+	MULL y+4(FP)
+	MOVL DX, z1+8(FP)
+	MOVL AX, z0+12(FP)
+	RET
+
+
+// func divWW(x1, x0, y Word) (q, r Word)
+TEXT ·divWW(SB),NOSPLIT,$0
+	MOVL x1+0(FP), DX
+	MOVL x0+4(FP), AX
+	DIVL y+8(FP)
+	MOVL AX, q+12(FP)
+	MOVL DX, r+16(FP)
+	RET
+
+
+// func addVV(z, x, y []Word) (c Word)
+TEXT ·addVV(SB),NOSPLIT,$0
+	MOVL z+0(FP), DI
+	MOVL x+12(FP), SI
+	MOVL y+24(FP), CX
+	MOVL z_len+4(FP), BP
+	MOVL $0, BX		// i = 0
+	MOVL $0, DX		// c = 0
+	JMP E1
+
+L1:	MOVL (SI)(BX*4), AX
+	RCRL $1, DX
+	ADCL (CX)(BX*4), AX
+	RCLL $1, DX
+	MOVL AX, (DI)(BX*4)
+	ADDL $1, BX		// i++
+
+E1:	CMPL BX, BP		// i < n
+	JL L1
+
+	MOVL DX, c+36(FP)
+	RET
+
+
+// func subVV(z, x, y []Word) (c Word)
+// (same as addVV except for SBBL instead of ADCL and label names)
+TEXT ·subVV(SB),NOSPLIT,$0
+	MOVL z+0(FP), DI
+	MOVL x+12(FP), SI
+	MOVL y+24(FP), CX
+	MOVL z_len+4(FP), BP
+	MOVL $0, BX		// i = 0
+	MOVL $0, DX		// c = 0
+	JMP E2
+
+L2:	MOVL (SI)(BX*4), AX
+	RCRL $1, DX
+	SBBL (CX)(BX*4), AX
+	RCLL $1, DX
+	MOVL AX, (DI)(BX*4)
+	ADDL $1, BX		// i++
+
+E2:	CMPL BX, BP		// i < n
+	JL L2
+
+	MOVL DX, c+36(FP)
+	RET
+
+
+// func addVW(z, x []Word, y Word) (c Word)
+TEXT ·addVW(SB),NOSPLIT,$0
+	MOVL z+0(FP), DI
+	MOVL x+12(FP), SI
+	MOVL y+24(FP), AX	// c = y
+	MOVL z_len+4(FP), BP
+	MOVL $0, BX		// i = 0
+	JMP E3
+
+L3:	ADDL (SI)(BX*4), AX
+	MOVL AX, (DI)(BX*4)
+	RCLL $1, AX
+	ANDL $1, AX
+	ADDL $1, BX		// i++
+
+E3:	CMPL BX, BP		// i < n
+	JL L3
+
+	MOVL AX, c+28(FP)
+	RET
+
+
+// func subVW(z, x []Word, y Word) (c Word)
+TEXT ·subVW(SB),NOSPLIT,$0
+	MOVL z+0(FP), DI
+	MOVL x+12(FP), SI
+	MOVL y+24(FP), AX	// c = y
+	MOVL z_len+4(FP), BP
+	MOVL $0, BX		// i = 0
+	JMP E4
+
+L4:	MOVL (SI)(BX*4), DX	// TODO(gri) is there a reverse SUBL?
+	SUBL AX, DX
+	MOVL DX, (DI)(BX*4)
+	RCLL $1, AX
+	ANDL $1, AX
+	ADDL $1, BX		// i++
+
+E4:	CMPL BX, BP		// i < n
+	JL L4
+
+	MOVL AX, c+28(FP)
+	RET
+
+
+// func shlVU(z, x []Word, s uint) (c Word)
+TEXT ·shlVU(SB),NOSPLIT,$0
+	MOVL z_len+4(FP), BX	// i = z
+	SUBL $1, BX		// i--
+	JL X8b			// i < 0	(n <= 0)
+
+	// n > 0
+	MOVL z+0(FP), DI
+	MOVL x+12(FP), SI
+	MOVL s+24(FP), CX
+	MOVL (SI)(BX*4), AX	// w1 = x[n-1]
+	MOVL $0, DX
+	SHLL CX, DX:AX		// w1>>ŝ
+	MOVL DX, c+28(FP)
+
+	CMPL BX, $0
+	JLE X8a			// i <= 0
+
+	// i > 0
+L8:	MOVL AX, DX		// w = w1
+	MOVL -4(SI)(BX*4), AX	// w1 = x[i-1]
+	SHLL CX, DX:AX		// w<<s | w1>>ŝ
+	MOVL DX, (DI)(BX*4)	// z[i] = w<<s | w1>>ŝ
+	SUBL $1, BX		// i--
+	JG L8			// i > 0
+
+	// i <= 0
+X8a:	SHLL CX, AX		// w1<<s
+	MOVL AX, (DI)		// z[0] = w1<<s
+	RET
+
+X8b:	MOVL $0, c+28(FP)
+	RET
+
+
+// func shrVU(z, x []Word, s uint) (c Word)
+TEXT ·shrVU(SB),NOSPLIT,$0
+	MOVL z_len+4(FP), BP
+	SUBL $1, BP		// n--
+	JL X9b			// n < 0	(n <= 0)
+
+	// n > 0
+	MOVL z+0(FP), DI
+	MOVL x+12(FP), SI
+	MOVL s+24(FP), CX
+	MOVL (SI), AX		// w1 = x[0]
+	MOVL $0, DX
+	SHRL CX, DX:AX		// w1<<ŝ
+	MOVL DX, c+28(FP)
+
+	MOVL $0, BX		// i = 0
+	JMP E9
+
+	// i < n-1
+L9:	MOVL AX, DX		// w = w1
+	MOVL 4(SI)(BX*4), AX	// w1 = x[i+1]
+	SHRL CX, DX:AX		// w>>s | w1<<ŝ
+	MOVL DX, (DI)(BX*4)	// z[i] = w>>s | w1<<ŝ
+	ADDL $1, BX		// i++
+	
+E9:	CMPL BX, BP
+	JL L9			// i < n-1
+
+	// i >= n-1
+X9a:	SHRL CX, AX		// w1>>s
+	MOVL AX, (DI)(BP*4)	// z[n-1] = w1>>s
+	RET
+
+X9b:	MOVL $0, c+28(FP)
+	RET
+
+
+// func mulAddVWW(z, x []Word, y, r Word) (c Word)
+TEXT ·mulAddVWW(SB),NOSPLIT,$0
+	MOVL z+0(FP), DI
+	MOVL x+12(FP), SI
+	MOVL y+24(FP), BP
+	MOVL r+28(FP), CX	// c = r
+	MOVL z_len+4(FP), BX
+	LEAL (DI)(BX*4), DI
+	LEAL (SI)(BX*4), SI
+	NEGL BX			// i = -n
+	JMP E5
+
+L5:	MOVL (SI)(BX*4), AX
+	MULL BP
+	ADDL CX, AX
+	ADCL $0, DX
+	MOVL AX, (DI)(BX*4)
+	MOVL DX, CX
+	ADDL $1, BX		// i++
+
+E5:	CMPL BX, $0		// i < 0
+	JL L5
+
+	MOVL CX, c+32(FP)
+	RET
+
+
+// func addMulVVW(z, x []Word, y Word) (c Word)
+TEXT ·addMulVVW(SB),NOSPLIT,$0
+	MOVL z+0(FP), DI
+	MOVL x+12(FP), SI
+	MOVL y+24(FP), BP
+	MOVL z_len+4(FP), BX
+	LEAL (DI)(BX*4), DI
+	LEAL (SI)(BX*4), SI
+	NEGL BX			// i = -n
+	MOVL $0, CX		// c = 0
+	JMP E6
+
+L6:	MOVL (SI)(BX*4), AX
+	MULL BP
+	ADDL CX, AX
+	ADCL $0, DX
+	ADDL AX, (DI)(BX*4)
+	ADCL $0, DX
+	MOVL DX, CX
+	ADDL $1, BX		// i++
+
+E6:	CMPL BX, $0		// i < 0
+	JL L6
+
+	MOVL CX, c+28(FP)
+	RET
+
+
+// func divWVW(z* Word, xn Word, x []Word, y Word) (r Word)
+TEXT ·divWVW(SB),NOSPLIT,$0
+	MOVL z+0(FP), DI
+	MOVL xn+12(FP), DX	// r = xn
+	MOVL x+16(FP), SI
+	MOVL y+28(FP), CX
+	MOVL z_len+4(FP), BX	// i = z
+	JMP E7
+
+L7:	MOVL (SI)(BX*4), AX
+	DIVL CX
+	MOVL AX, (DI)(BX*4)
+
+E7:	SUBL $1, BX		// i--
+	JGE L7			// i >= 0
+
+	MOVL DX, r+32(FP)
+	RET
+
+// func bitLen(x Word) (n int)
+TEXT ·bitLen(SB),NOSPLIT,$0
+	BSRL x+0(FP), AX
+	JZ Z1
+	INCL AX
+	MOVL AX, n+4(FP)
+	RET
+
+Z1:	MOVL $0, n+4(FP)
+	RET
diff --git a/src/math/big/arith_amd64.s b/src/math/big/arith_amd64.s
new file mode 100644
index 0000000..56c4cb0
--- /dev/null
+++ b/src/math/big/arith_amd64.s
@@ -0,0 +1,401 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+// This file provides fast assembly versions for the elementary
+// arithmetic operations on vectors implemented in arith.go.
+
+// Literal instruction for MOVQ $0, CX.
+// (MOVQ $0, reg is translated to XORQ reg, reg and clears CF.)
+#define ZERO_CX BYTE $0x48; \
+		BYTE $0xc7; \
+		BYTE $0xc1; \
+		BYTE $0x00; \
+		BYTE $0x00; \
+		BYTE $0x00; \
+		BYTE $0x00
+
+// func mulWW(x, y Word) (z1, z0 Word)
+TEXT ·mulWW(SB),NOSPLIT,$0
+	MOVQ x+0(FP), AX
+	MULQ y+8(FP)
+	MOVQ DX, z1+16(FP)
+	MOVQ AX, z0+24(FP)
+	RET
+
+
+// func divWW(x1, x0, y Word) (q, r Word)
+TEXT ·divWW(SB),NOSPLIT,$0
+	MOVQ x1+0(FP), DX
+	MOVQ x0+8(FP), AX
+	DIVQ y+16(FP)
+	MOVQ AX, q+24(FP)
+	MOVQ DX, r+32(FP)
+	RET
+
+
+// func addVV(z, x, y []Word) (c Word)
+TEXT ·addVV(SB),NOSPLIT,$0
+	MOVQ z_len+8(FP), DI
+	MOVQ x+24(FP), R8
+	MOVQ y+48(FP), R9
+	MOVQ z+0(FP), R10
+
+	MOVQ $0, CX		// c = 0
+	MOVQ $0, SI		// i = 0
+
+	// s/JL/JMP/ below to disable the unrolled loop
+	SUBQ $4, DI		// n -= 4
+	JL V1			// if n < 0 goto V1
+
+U1:	// n >= 0
+	// regular loop body unrolled 4x
+	RCRQ $1, CX		// CF = c
+	MOVQ 0(R8)(SI*8), R11
+	MOVQ 8(R8)(SI*8), R12
+	MOVQ 16(R8)(SI*8), R13
+	MOVQ 24(R8)(SI*8), R14
+	ADCQ 0(R9)(SI*8), R11
+	ADCQ 8(R9)(SI*8), R12
+	ADCQ 16(R9)(SI*8), R13
+	ADCQ 24(R9)(SI*8), R14
+	MOVQ R11, 0(R10)(SI*8)
+	MOVQ R12, 8(R10)(SI*8)
+	MOVQ R13, 16(R10)(SI*8)
+	MOVQ R14, 24(R10)(SI*8)
+	RCLQ $1, CX		// c = CF
+
+	ADDQ $4, SI		// i += 4
+	SUBQ $4, DI		// n -= 4
+	JGE U1			// if n >= 0 goto U1
+
+V1:	ADDQ $4, DI		// n += 4
+	JLE E1			// if n <= 0 goto E1
+
+L1:	// n > 0
+	RCRQ $1, CX		// CF = c
+	MOVQ 0(R8)(SI*8), R11
+	ADCQ 0(R9)(SI*8), R11
+	MOVQ R11, 0(R10)(SI*8)
+	RCLQ $1, CX		// c = CF
+
+	ADDQ $1, SI		// i++
+	SUBQ $1, DI		// n--
+	JG L1			// if n > 0 goto L1
+
+E1:	MOVQ CX, c+72(FP)	// return c
+	RET
+
+
+// func subVV(z, x, y []Word) (c Word)
+// (same as addVV except for SBBQ instead of ADCQ and label names)
+TEXT ·subVV(SB),NOSPLIT,$0
+	MOVQ z_len+8(FP), DI
+	MOVQ x+24(FP), R8
+	MOVQ y+48(FP), R9
+	MOVQ z+0(FP), R10
+
+	MOVQ $0, CX		// c = 0
+	MOVQ $0, SI		// i = 0
+
+	// s/JL/JMP/ below to disable the unrolled loop
+	SUBQ $4, DI		// n -= 4
+	JL V2			// if n < 0 goto V2
+
+U2:	// n >= 0
+	// regular loop body unrolled 4x
+	RCRQ $1, CX		// CF = c
+	MOVQ 0(R8)(SI*8), R11
+	MOVQ 8(R8)(SI*8), R12
+	MOVQ 16(R8)(SI*8), R13
+	MOVQ 24(R8)(SI*8), R14
+	SBBQ 0(R9)(SI*8), R11
+	SBBQ 8(R9)(SI*8), R12
+	SBBQ 16(R9)(SI*8), R13
+	SBBQ 24(R9)(SI*8), R14
+	MOVQ R11, 0(R10)(SI*8)
+	MOVQ R12, 8(R10)(SI*8)
+	MOVQ R13, 16(R10)(SI*8)
+	MOVQ R14, 24(R10)(SI*8)
+	RCLQ $1, CX		// c = CF
+
+	ADDQ $4, SI		// i += 4
+	SUBQ $4, DI		// n -= 4
+	JGE U2			// if n >= 0 goto U2
+
+V2:	ADDQ $4, DI		// n += 4
+	JLE E2			// if n <= 0 goto E2
+
+L2:	// n > 0
+	RCRQ $1, CX		// CF = c
+	MOVQ 0(R8)(SI*8), R11
+	SBBQ 0(R9)(SI*8), R11
+	MOVQ R11, 0(R10)(SI*8)
+	RCLQ $1, CX		// c = CF
+
+	ADDQ $1, SI		// i++
+	SUBQ $1, DI		// n--
+	JG L2			// if n > 0 goto L2
+
+E2:	MOVQ CX, c+72(FP)	// return c
+	RET
+
+
+// func addVW(z, x []Word, y Word) (c Word)
+TEXT ·addVW(SB),NOSPLIT,$0
+	MOVQ z_len+8(FP), DI
+	MOVQ x+24(FP), R8
+	MOVQ y+48(FP), CX	// c = y
+	MOVQ z+0(FP), R10
+
+	MOVQ $0, SI		// i = 0
+
+	// s/JL/JMP/ below to disable the unrolled loop
+	SUBQ $4, DI		// n -= 4
+	JL V3			// if n < 4 goto V3
+
+U3:	// n >= 0
+	// regular loop body unrolled 4x
+	MOVQ 0(R8)(SI*8), R11
+	MOVQ 8(R8)(SI*8), R12
+	MOVQ 16(R8)(SI*8), R13
+	MOVQ 24(R8)(SI*8), R14
+	ADDQ CX, R11
+	ZERO_CX
+	ADCQ $0, R12
+	ADCQ $0, R13
+	ADCQ $0, R14
+	SETCS CX		// c = CF
+	MOVQ R11, 0(R10)(SI*8)
+	MOVQ R12, 8(R10)(SI*8)
+	MOVQ R13, 16(R10)(SI*8)
+	MOVQ R14, 24(R10)(SI*8)
+
+	ADDQ $4, SI		// i += 4
+	SUBQ $4, DI		// n -= 4
+	JGE U3			// if n >= 0 goto U3
+
+V3:	ADDQ $4, DI		// n += 4
+	JLE E3			// if n <= 0 goto E3
+
+L3:	// n > 0
+	ADDQ 0(R8)(SI*8), CX
+	MOVQ CX, 0(R10)(SI*8)
+	ZERO_CX
+	RCLQ $1, CX		// c = CF
+
+	ADDQ $1, SI		// i++
+	SUBQ $1, DI		// n--
+	JG L3			// if n > 0 goto L3
+
+E3:	MOVQ CX, c+56(FP)	// return c
+	RET
+
+
+// func subVW(z, x []Word, y Word) (c Word)
+// (same as addVW except for SUBQ/SBBQ instead of ADDQ/ADCQ and label names)
+TEXT ·subVW(SB),NOSPLIT,$0
+	MOVQ z_len+8(FP), DI
+	MOVQ x+24(FP), R8
+	MOVQ y+48(FP), CX	// c = y
+	MOVQ z+0(FP), R10
+	
+	MOVQ $0, SI		// i = 0
+
+	// s/JL/JMP/ below to disable the unrolled loop
+	SUBQ $4, DI		// n -= 4
+	JL V4			// if n < 4 goto V4
+
+U4:	// n >= 0
+	// regular loop body unrolled 4x
+	MOVQ 0(R8)(SI*8), R11
+	MOVQ 8(R8)(SI*8), R12
+	MOVQ 16(R8)(SI*8), R13
+	MOVQ 24(R8)(SI*8), R14
+	SUBQ CX, R11
+	ZERO_CX
+	SBBQ $0, R12
+	SBBQ $0, R13
+	SBBQ $0, R14
+	SETCS CX		// c = CF
+	MOVQ R11, 0(R10)(SI*8)
+	MOVQ R12, 8(R10)(SI*8)
+	MOVQ R13, 16(R10)(SI*8)
+	MOVQ R14, 24(R10)(SI*8)
+
+	ADDQ $4, SI		// i += 4
+	SUBQ $4, DI		// n -= 4
+	JGE U4			// if n >= 0 goto U4
+
+V4:	ADDQ $4, DI		// n += 4
+	JLE E4			// if n <= 0 goto E4
+
+L4:	// n > 0
+	MOVQ 0(R8)(SI*8), R11
+	SUBQ CX, R11
+	MOVQ R11, 0(R10)(SI*8)
+	ZERO_CX
+	RCLQ $1, CX		// c = CF
+
+	ADDQ $1, SI		// i++
+	SUBQ $1, DI		// n--
+	JG L4			// if n > 0 goto L4
+
+E4:	MOVQ CX, c+56(FP)	// return c
+	RET
+
+
+// func shlVU(z, x []Word, s uint) (c Word)
+TEXT ·shlVU(SB),NOSPLIT,$0
+	MOVQ z_len+8(FP), BX	// i = z
+	SUBQ $1, BX		// i--
+	JL X8b			// i < 0	(n <= 0)
+
+	// n > 0
+	MOVQ z+0(FP), R10
+	MOVQ x+24(FP), R8
+	MOVQ s+48(FP), CX
+	MOVQ (R8)(BX*8), AX	// w1 = x[n-1]
+	MOVQ $0, DX
+	SHLQ CX, DX:AX		// w1>>ŝ
+	MOVQ DX, c+56(FP)
+
+	CMPQ BX, $0
+	JLE X8a			// i <= 0
+
+	// i > 0
+L8:	MOVQ AX, DX		// w = w1
+	MOVQ -8(R8)(BX*8), AX	// w1 = x[i-1]
+	SHLQ CX, DX:AX		// w<<s | w1>>ŝ
+	MOVQ DX, (R10)(BX*8)	// z[i] = w<<s | w1>>ŝ
+	SUBQ $1, BX		// i--
+	JG L8			// i > 0
+
+	// i <= 0
+X8a:	SHLQ CX, AX		// w1<<s
+	MOVQ AX, (R10)		// z[0] = w1<<s
+	RET
+
+X8b:	MOVQ $0, c+56(FP)
+	RET
+
+
+// func shrVU(z, x []Word, s uint) (c Word)
+TEXT ·shrVU(SB),NOSPLIT,$0
+	MOVQ z_len+8(FP), R11
+	SUBQ $1, R11		// n--
+	JL X9b			// n < 0	(n <= 0)
+
+	// n > 0
+	MOVQ z+0(FP), R10
+	MOVQ x+24(FP), R8
+	MOVQ s+48(FP), CX
+	MOVQ (R8), AX		// w1 = x[0]
+	MOVQ $0, DX
+	SHRQ CX, DX:AX		// w1<<ŝ
+	MOVQ DX, c+56(FP)
+
+	MOVQ $0, BX		// i = 0
+	JMP E9
+
+	// i < n-1
+L9:	MOVQ AX, DX		// w = w1
+	MOVQ 8(R8)(BX*8), AX	// w1 = x[i+1]
+	SHRQ CX, DX:AX		// w>>s | w1<<ŝ
+	MOVQ DX, (R10)(BX*8)	// z[i] = w>>s | w1<<ŝ
+	ADDQ $1, BX		// i++
+	
+E9:	CMPQ BX, R11
+	JL L9			// i < n-1
+
+	// i >= n-1
+X9a:	SHRQ CX, AX		// w1>>s
+	MOVQ AX, (R10)(R11*8)	// z[n-1] = w1>>s
+	RET
+
+X9b:	MOVQ $0, c+56(FP)
+	RET
+
+
+// func mulAddVWW(z, x []Word, y, r Word) (c Word)
+TEXT ·mulAddVWW(SB),NOSPLIT,$0
+	MOVQ z+0(FP), R10
+	MOVQ x+24(FP), R8
+	MOVQ y+48(FP), R9
+	MOVQ r+56(FP), CX	// c = r
+	MOVQ z_len+8(FP), R11
+	MOVQ $0, BX		// i = 0
+	JMP E5
+
+L5:	MOVQ (R8)(BX*8), AX
+	MULQ R9
+	ADDQ CX, AX
+	ADCQ $0, DX
+	MOVQ AX, (R10)(BX*8)
+	MOVQ DX, CX
+	ADDQ $1, BX		// i++
+
+E5:	CMPQ BX, R11		// i < n
+	JL L5
+
+	MOVQ CX, c+64(FP)
+	RET
+
+
+// func addMulVVW(z, x []Word, y Word) (c Word)
+TEXT ·addMulVVW(SB),NOSPLIT,$0
+	MOVQ z+0(FP), R10
+	MOVQ x+24(FP), R8
+	MOVQ y+48(FP), R9
+	MOVQ z_len+8(FP), R11
+	MOVQ $0, BX		// i = 0
+	MOVQ $0, CX		// c = 0
+	JMP E6
+
+L6:	MOVQ (R8)(BX*8), AX
+	MULQ R9
+	ADDQ CX, AX
+	ADCQ $0, DX
+	ADDQ AX, (R10)(BX*8)
+	ADCQ $0, DX
+	MOVQ DX, CX
+	ADDQ $1, BX		// i++
+
+E6:	CMPQ BX, R11		// i < n
+	JL L6
+
+	MOVQ CX, c+56(FP)
+	RET
+
+
+// func divWVW(z []Word, xn Word, x []Word, y Word) (r Word)
+TEXT ·divWVW(SB),NOSPLIT,$0
+	MOVQ z+0(FP), R10
+	MOVQ xn+24(FP), DX	// r = xn
+	MOVQ x+32(FP), R8
+	MOVQ y+56(FP), R9
+	MOVQ z_len+8(FP), BX	// i = z
+	JMP E7
+
+L7:	MOVQ (R8)(BX*8), AX
+	DIVQ R9
+	MOVQ AX, (R10)(BX*8)
+
+E7:	SUBQ $1, BX		// i--
+	JGE L7			// i >= 0
+
+	MOVQ DX, r+64(FP)
+	RET
+
+// func bitLen(x Word) (n int)
+TEXT ·bitLen(SB),NOSPLIT,$0
+	BSRQ x+0(FP), AX
+	JZ Z1
+	ADDQ $1, AX
+	MOVQ AX, n+8(FP)
+	RET
+
+Z1:	MOVQ $0, n+8(FP)
+	RET
diff --git a/src/math/big/arith_amd64p32.s b/src/math/big/arith_amd64p32.s
new file mode 100644
index 0000000..908dbbd
--- /dev/null
+++ b/src/math/big/arith_amd64p32.s
@@ -0,0 +1,41 @@
+// Copyright 2013 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+TEXT ·mulWW(SB),NOSPLIT,$0
+	JMP ·mulWW_g(SB)
+
+TEXT ·divWW(SB),NOSPLIT,$0
+	JMP ·divWW_g(SB)
+
+TEXT ·addVV(SB),NOSPLIT,$0
+	JMP ·addVV_g(SB)
+
+TEXT ·subVV(SB),NOSPLIT,$0
+	JMP ·subVV_g(SB)
+
+TEXT ·addVW(SB),NOSPLIT,$0
+	JMP ·addVW_g(SB)
+
+TEXT ·subVW(SB),NOSPLIT,$0
+	JMP ·subVW_g(SB)
+
+TEXT ·shlVU(SB),NOSPLIT,$0
+	JMP ·shlVU_g(SB)
+
+TEXT ·shrVU(SB),NOSPLIT,$0
+	JMP ·shrVU_g(SB)
+
+TEXT ·mulAddVWW(SB),NOSPLIT,$0
+	JMP ·mulAddVWW_g(SB)
+
+TEXT ·addMulVVW(SB),NOSPLIT,$0
+	JMP ·addMulVVW_g(SB)
+
+TEXT ·divWVW(SB),NOSPLIT,$0
+	JMP ·divWVW_g(SB)
+
+TEXT ·bitLen(SB),NOSPLIT,$0
+	JMP ·bitLen_g(SB)
diff --git a/src/math/big/arith_arm.s b/src/math/big/arith_arm.s
new file mode 100644
index 0000000..a4c51c2
--- /dev/null
+++ b/src/math/big/arith_arm.s
@@ -0,0 +1,300 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+// This file provides fast assembly versions for the elementary
+// arithmetic operations on vectors implemented in arith.go.
+
+// func addVV(z, x, y []Word) (c Word)
+TEXT ·addVV(SB),NOSPLIT,$0
+	ADD.S	$0, R0		// clear carry flag
+	MOVW	z+0(FP), R1
+	MOVW	z_len+4(FP), R4
+	MOVW	x+12(FP), R2
+	MOVW	y+24(FP), R3
+	ADD	R4<<2, R1, R4
+	B E1
+L1:
+	MOVW.P	4(R2), R5
+	MOVW.P	4(R3), R6
+	ADC.S	R6, R5
+	MOVW.P	R5, 4(R1)
+E1:
+	TEQ	R1, R4
+	BNE L1
+
+	MOVW	$0, R0
+	MOVW.CS	$1, R0
+	MOVW	R0, c+36(FP)
+	RET
+
+
+// func subVV(z, x, y []Word) (c Word)
+// (same as addVV except for SBC instead of ADC and label names)
+TEXT ·subVV(SB),NOSPLIT,$0
+	SUB.S	$0, R0		// clear borrow flag
+	MOVW	z+0(FP), R1
+	MOVW	z_len+4(FP), R4
+	MOVW	x+12(FP), R2
+	MOVW	y+24(FP), R3
+	ADD	R4<<2, R1, R4
+	B E2
+L2:
+	MOVW.P	4(R2), R5
+	MOVW.P	4(R3), R6
+	SBC.S	R6, R5
+	MOVW.P	R5, 4(R1)
+E2:
+	TEQ	R1, R4
+	BNE L2
+
+	MOVW	$0, R0
+	MOVW.CC	$1, R0
+	MOVW	R0, c+36(FP)
+	RET
+
+
+// func addVW(z, x []Word, y Word) (c Word)
+TEXT ·addVW(SB),NOSPLIT,$0
+	MOVW	z+0(FP), R1
+	MOVW	z_len+4(FP), R4
+	MOVW	x+12(FP), R2
+	MOVW	y+24(FP), R3
+	ADD	R4<<2, R1, R4
+	TEQ	R1, R4
+	BNE L3a
+	MOVW	R3, c+28(FP)
+	RET
+L3a:
+	MOVW.P	4(R2), R5
+	ADD.S	R3, R5
+	MOVW.P	R5, 4(R1)
+	B	E3
+L3:
+	MOVW.P	4(R2), R5
+	ADC.S	$0, R5
+	MOVW.P	R5, 4(R1)
+E3:
+	TEQ	R1, R4
+	BNE	L3
+
+	MOVW	$0, R0
+	MOVW.CS	$1, R0
+	MOVW	R0, c+28(FP)
+	RET
+
+
+// func subVW(z, x []Word, y Word) (c Word)
+TEXT ·subVW(SB),NOSPLIT,$0
+	MOVW	z+0(FP), R1
+	MOVW	z_len+4(FP), R4
+	MOVW	x+12(FP), R2
+	MOVW	y+24(FP), R3
+	ADD	R4<<2, R1, R4
+	TEQ	R1, R4
+	BNE L4a
+	MOVW	R3, c+28(FP)
+	RET
+L4a:
+	MOVW.P	4(R2), R5
+	SUB.S	R3, R5
+	MOVW.P	R5, 4(R1)
+	B	E4
+L4:
+	MOVW.P	4(R2), R5
+	SBC.S	$0, R5
+	MOVW.P	R5, 4(R1)
+E4:
+	TEQ	R1, R4
+	BNE	L4
+
+	MOVW	$0, R0
+	MOVW.CC	$1, R0
+	MOVW	R0, c+28(FP)
+	RET
+
+
+// func shlVU(z, x []Word, s uint) (c Word)
+TEXT ·shlVU(SB),NOSPLIT,$0
+	MOVW	z_len+4(FP), R5
+	TEQ	$0, R5
+	BEQ	X7
+	
+	MOVW	z+0(FP), R1
+	MOVW	x+12(FP), R2
+	ADD	R5<<2, R2, R2
+	ADD	R5<<2, R1, R5
+	MOVW	s+24(FP), R3
+	TEQ	$0, R3	// shift 0 is special
+	BEQ	Y7
+	ADD	$4, R1	// stop one word early
+	MOVW	$32, R4
+	SUB	R3, R4
+	MOVW	$0, R7
+	
+	MOVW.W	-4(R2), R6
+	MOVW	R6<<R3, R7
+	MOVW	R6>>R4, R6
+	MOVW	R6, c+28(FP)
+	B E7
+
+L7:
+	MOVW.W	-4(R2), R6
+	ORR	R6>>R4, R7
+	MOVW.W	R7, -4(R5)
+	MOVW	R6<<R3, R7
+E7:
+	TEQ	R1, R5
+	BNE	L7
+
+	MOVW	R7, -4(R5)
+	RET
+
+Y7:	// copy loop, because shift 0 == shift 32
+	MOVW.W	-4(R2), R6
+	MOVW.W	R6, -4(R5)
+	TEQ	R1, R5
+	BNE Y7
+
+X7:
+	MOVW	$0, R1
+	MOVW	R1, c+28(FP)
+	RET
+
+
+// func shrVU(z, x []Word, s uint) (c Word)
+TEXT ·shrVU(SB),NOSPLIT,$0
+	MOVW	z_len+4(FP), R5
+	TEQ	$0, R5
+	BEQ	X6
+
+	MOVW	z+0(FP), R1
+	MOVW	x+12(FP), R2
+	ADD	R5<<2, R1, R5
+	MOVW	s+24(FP), R3
+	TEQ	$0, R3	// shift 0 is special
+	BEQ Y6
+	SUB	$4, R5	// stop one word early
+	MOVW	$32, R4
+	SUB	R3, R4
+	MOVW	$0, R7
+
+	// first word
+	MOVW.P	4(R2), R6
+	MOVW	R6>>R3, R7
+	MOVW	R6<<R4, R6
+	MOVW	R6, c+28(FP)
+	B E6
+
+	// word loop
+L6:
+	MOVW.P	4(R2), R6
+	ORR	R6<<R4, R7
+	MOVW.P	R7, 4(R1)
+	MOVW	R6>>R3, R7
+E6:
+	TEQ	R1, R5
+	BNE	L6
+
+	MOVW	R7, 0(R1)
+	RET
+
+Y6:	// copy loop, because shift 0 == shift 32
+	MOVW.P	4(R2), R6
+	MOVW.P	R6, 4(R1)
+	TEQ R1, R5
+	BNE Y6
+
+X6:
+	MOVW	$0, R1
+	MOVW	R1, c+28(FP)
+	RET
+
+
+// func mulAddVWW(z, x []Word, y, r Word) (c Word)
+TEXT ·mulAddVWW(SB),NOSPLIT,$0
+	MOVW	$0, R0
+	MOVW	z+0(FP), R1
+	MOVW	z_len+4(FP), R5
+	MOVW	x+12(FP), R2
+	MOVW	y+24(FP), R3
+	MOVW	r+28(FP), R4
+	ADD	R5<<2, R1, R5
+	B E8
+
+	// word loop
+L8:
+	MOVW.P	4(R2), R6
+	MULLU	R6, R3, (R7, R6)
+	ADD.S	R4, R6
+	ADC	R0, R7
+	MOVW.P	R6, 4(R1)
+	MOVW	R7, R4
+E8:
+	TEQ	R1, R5
+	BNE	L8
+
+	MOVW	R4, c+32(FP)
+	RET
+
+
+// func addMulVVW(z, x []Word, y Word) (c Word)
+TEXT ·addMulVVW(SB),NOSPLIT,$0
+	MOVW	$0, R0
+	MOVW	z+0(FP), R1
+	MOVW	z_len+4(FP), R5
+	MOVW	x+12(FP), R2
+	MOVW	y+24(FP), R3
+	ADD	R5<<2, R1, R5
+	MOVW	$0, R4
+	B E9
+
+	// word loop
+L9:
+	MOVW.P	4(R2), R6
+	MULLU	R6, R3, (R7, R6)
+	ADD.S	R4, R6
+	ADC	R0, R7
+	MOVW	0(R1), R4
+	ADD.S	R4, R6
+	ADC	R0, R7
+	MOVW.P	R6, 4(R1)
+	MOVW	R7, R4
+E9:
+	TEQ	R1, R5
+	BNE	L9
+
+	MOVW	R4, c+28(FP)
+	RET
+
+
+// func divWVW(z* Word, xn Word, x []Word, y Word) (r Word)
+TEXT ·divWVW(SB),NOSPLIT,$0
+	// ARM has no multiword division, so use portable code.
+	B ·divWVW_g(SB)
+
+
+// func divWW(x1, x0, y Word) (q, r Word)
+TEXT ·divWW(SB),NOSPLIT,$0
+	// ARM has no multiword division, so use portable code.
+	B ·divWW_g(SB)
+
+
+// func mulWW(x, y Word) (z1, z0 Word)
+TEXT ·mulWW(SB),NOSPLIT,$0
+	MOVW	x+0(FP), R1
+	MOVW	y+4(FP), R2
+	MULLU	R1, R2, (R4, R3)
+	MOVW	R4, z1+8(FP)
+	MOVW	R3, z0+12(FP)
+	RET
+
+// func bitLen(x Word) (n int)
+TEXT ·bitLen(SB),NOSPLIT,$0
+	MOVW	x+0(FP), R0
+	CLZ 	R0, R0
+	RSB	$32, R0
+	MOVW	R0, n+4(FP)
+	RET
diff --git a/src/pkg/math/big/arith_decl.go b/src/math/big/arith_decl.go
similarity index 100%
rename from src/pkg/math/big/arith_decl.go
rename to src/math/big/arith_decl.go
diff --git a/src/pkg/math/big/arith_test.go b/src/math/big/arith_test.go
similarity index 100%
rename from src/pkg/math/big/arith_test.go
rename to src/math/big/arith_test.go
diff --git a/src/pkg/math/big/calibrate_test.go b/src/math/big/calibrate_test.go
similarity index 100%
rename from src/pkg/math/big/calibrate_test.go
rename to src/math/big/calibrate_test.go
diff --git a/src/pkg/math/big/example_test.go b/src/math/big/example_test.go
similarity index 100%
rename from src/pkg/math/big/example_test.go
rename to src/math/big/example_test.go
diff --git a/src/pkg/math/big/gcd_test.go b/src/math/big/gcd_test.go
similarity index 100%
rename from src/pkg/math/big/gcd_test.go
rename to src/math/big/gcd_test.go
diff --git a/src/pkg/math/big/hilbert_test.go b/src/math/big/hilbert_test.go
similarity index 100%
rename from src/pkg/math/big/hilbert_test.go
rename to src/math/big/hilbert_test.go
diff --git a/src/math/big/int.go b/src/math/big/int.go
new file mode 100644
index 0000000..d22e39e
--- /dev/null
+++ b/src/math/big/int.go
@@ -0,0 +1,1031 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file implements signed multi-precision integers.
+
+package big
+
+import (
+	"errors"
+	"fmt"
+	"io"
+	"math/rand"
+	"strings"
+)
+
+// An Int represents a signed multi-precision integer.
+// The zero value for an Int represents the value 0.
+type Int struct {
+	neg bool // sign
+	abs nat  // absolute value of the integer
+}
+
+var intOne = &Int{false, natOne}
+
+// Sign returns:
+//
+//	-1 if x <  0
+//	 0 if x == 0
+//	+1 if x >  0
+//
+func (x *Int) Sign() int {
+	if len(x.abs) == 0 {
+		return 0
+	}
+	if x.neg {
+		return -1
+	}
+	return 1
+}
+
+// SetInt64 sets z to x and returns z.
+func (z *Int) SetInt64(x int64) *Int {
+	neg := false
+	if x < 0 {
+		neg = true
+		x = -x
+	}
+	z.abs = z.abs.setUint64(uint64(x))
+	z.neg = neg
+	return z
+}
+
+// SetUint64 sets z to x and returns z.
+func (z *Int) SetUint64(x uint64) *Int {
+	z.abs = z.abs.setUint64(x)
+	z.neg = false
+	return z
+}
+
+// NewInt allocates and returns a new Int set to x.
+func NewInt(x int64) *Int {
+	return new(Int).SetInt64(x)
+}
+
+// Set sets z to x and returns z.
+func (z *Int) Set(x *Int) *Int {
+	if z != x {
+		z.abs = z.abs.set(x.abs)
+		z.neg = x.neg
+	}
+	return z
+}
+
+// Bits provides raw (unchecked but fast) access to x by returning its
+// absolute value as a little-endian Word slice. The result and x share
+// the same underlying array.
+// Bits is intended to support implementation of missing low-level Int
+// functionality outside this package; it should be avoided otherwise.
+func (x *Int) Bits() []Word {
+	return x.abs
+}
+
+// SetBits provides raw (unchecked but fast) access to z by setting its
+// value to abs, interpreted as a little-endian Word slice, and returning
+// z. The result and abs share the same underlying array.
+// SetBits is intended to support implementation of missing low-level Int
+// functionality outside this package; it should be avoided otherwise.
+func (z *Int) SetBits(abs []Word) *Int {
+	z.abs = nat(abs).norm()
+	z.neg = false
+	return z
+}
+
+// Abs sets z to |x| (the absolute value of x) and returns z.
+func (z *Int) Abs(x *Int) *Int {
+	z.Set(x)
+	z.neg = false
+	return z
+}
+
+// Neg sets z to -x and returns z.
+func (z *Int) Neg(x *Int) *Int {
+	z.Set(x)
+	z.neg = len(z.abs) > 0 && !z.neg // 0 has no sign
+	return z
+}
+
+// Add sets z to the sum x+y and returns z.
+func (z *Int) Add(x, y *Int) *Int {
+	neg := x.neg
+	if x.neg == y.neg {
+		// x + y == x + y
+		// (-x) + (-y) == -(x + y)
+		z.abs = z.abs.add(x.abs, y.abs)
+	} else {
+		// x + (-y) == x - y == -(y - x)
+		// (-x) + y == y - x == -(x - y)
+		if x.abs.cmp(y.abs) >= 0 {
+			z.abs = z.abs.sub(x.abs, y.abs)
+		} else {
+			neg = !neg
+			z.abs = z.abs.sub(y.abs, x.abs)
+		}
+	}
+	z.neg = len(z.abs) > 0 && neg // 0 has no sign
+	return z
+}
+
+// Sub sets z to the difference x-y and returns z.
+func (z *Int) Sub(x, y *Int) *Int {
+	neg := x.neg
+	if x.neg != y.neg {
+		// x - (-y) == x + y
+		// (-x) - y == -(x + y)
+		z.abs = z.abs.add(x.abs, y.abs)
+	} else {
+		// x - y == x - y == -(y - x)
+		// (-x) - (-y) == y - x == -(x - y)
+		if x.abs.cmp(y.abs) >= 0 {
+			z.abs = z.abs.sub(x.abs, y.abs)
+		} else {
+			neg = !neg
+			z.abs = z.abs.sub(y.abs, x.abs)
+		}
+	}
+	z.neg = len(z.abs) > 0 && neg // 0 has no sign
+	return z
+}
+
+// Mul sets z to the product x*y and returns z.
+func (z *Int) Mul(x, y *Int) *Int {
+	// x * y == x * y
+	// x * (-y) == -(x * y)
+	// (-x) * y == -(x * y)
+	// (-x) * (-y) == x * y
+	z.abs = z.abs.mul(x.abs, y.abs)
+	z.neg = len(z.abs) > 0 && x.neg != y.neg // 0 has no sign
+	return z
+}
+
+// MulRange sets z to the product of all integers
+// in the range [a, b] inclusively and returns z.
+// If a > b (empty range), the result is 1.
+func (z *Int) MulRange(a, b int64) *Int {
+	switch {
+	case a > b:
+		return z.SetInt64(1) // empty range
+	case a <= 0 && b >= 0:
+		return z.SetInt64(0) // range includes 0
+	}
+	// a <= b && (b < 0 || a > 0)
+
+	neg := false
+	if a < 0 {
+		neg = (b-a)&1 == 0
+		a, b = -b, -a
+	}
+
+	z.abs = z.abs.mulRange(uint64(a), uint64(b))
+	z.neg = neg
+	return z
+}
+
+// Binomial sets z to the binomial coefficient of (n, k) and returns z.
+func (z *Int) Binomial(n, k int64) *Int {
+	var a, b Int
+	a.MulRange(n-k+1, n)
+	b.MulRange(1, k)
+	return z.Quo(&a, &b)
+}
+
+// Quo sets z to the quotient x/y for y != 0 and returns z.
+// If y == 0, a division-by-zero run-time panic occurs.
+// Quo implements truncated division (like Go); see QuoRem for more details.
+func (z *Int) Quo(x, y *Int) *Int {
+	z.abs, _ = z.abs.div(nil, x.abs, y.abs)
+	z.neg = len(z.abs) > 0 && x.neg != y.neg // 0 has no sign
+	return z
+}
+
+// Rem sets z to the remainder x%y for y != 0 and returns z.
+// If y == 0, a division-by-zero run-time panic occurs.
+// Rem implements truncated modulus (like Go); see QuoRem for more details.
+func (z *Int) Rem(x, y *Int) *Int {
+	_, z.abs = nat(nil).div(z.abs, x.abs, y.abs)
+	z.neg = len(z.abs) > 0 && x.neg // 0 has no sign
+	return z
+}
+
+// QuoRem sets z to the quotient x/y and r to the remainder x%y
+// and returns the pair (z, r) for y != 0.
+// If y == 0, a division-by-zero run-time panic occurs.
+//
+// QuoRem implements T-division and modulus (like Go):
+//
+//	q = x/y      with the result truncated to zero
+//	r = x - y*q
+//
+// (See Daan Leijen, ``Division and Modulus for Computer Scientists''.)
+// See DivMod for Euclidean division and modulus (unlike Go).
+//
+func (z *Int) QuoRem(x, y, r *Int) (*Int, *Int) {
+	z.abs, r.abs = z.abs.div(r.abs, x.abs, y.abs)
+	z.neg, r.neg = len(z.abs) > 0 && x.neg != y.neg, len(r.abs) > 0 && x.neg // 0 has no sign
+	return z, r
+}
+
+// Div sets z to the quotient x/y for y != 0 and returns z.
+// If y == 0, a division-by-zero run-time panic occurs.
+// Div implements Euclidean division (unlike Go); see DivMod for more details.
+func (z *Int) Div(x, y *Int) *Int {
+	y_neg := y.neg // z may be an alias for y
+	var r Int
+	z.QuoRem(x, y, &r)
+	if r.neg {
+		if y_neg {
+			z.Add(z, intOne)
+		} else {
+			z.Sub(z, intOne)
+		}
+	}
+	return z
+}
+
+// Mod sets z to the modulus x%y for y != 0 and returns z.
+// If y == 0, a division-by-zero run-time panic occurs.
+// Mod implements Euclidean modulus (unlike Go); see DivMod for more details.
+func (z *Int) Mod(x, y *Int) *Int {
+	y0 := y // save y
+	if z == y || alias(z.abs, y.abs) {
+		y0 = new(Int).Set(y)
+	}
+	var q Int
+	q.QuoRem(x, y, z)
+	if z.neg {
+		if y0.neg {
+			z.Sub(z, y0)
+		} else {
+			z.Add(z, y0)
+		}
+	}
+	return z
+}
+
+// DivMod sets z to the quotient x div y and m to the modulus x mod y
+// and returns the pair (z, m) for y != 0.
+// If y == 0, a division-by-zero run-time panic occurs.
+//
+// DivMod implements Euclidean division and modulus (unlike Go):
+//
+//	q = x div y  such that
+//	m = x - y*q  with 0 <= m < |q|
+//
+// (See Raymond T. Boute, ``The Euclidean definition of the functions
+// div and mod''. ACM Transactions on Programming Languages and
+// Systems (TOPLAS), 14(2):127-144, New York, NY, USA, 4/1992.
+// ACM press.)
+// See QuoRem for T-division and modulus (like Go).
+//
+func (z *Int) DivMod(x, y, m *Int) (*Int, *Int) {
+	y0 := y // save y
+	if z == y || alias(z.abs, y.abs) {
+		y0 = new(Int).Set(y)
+	}
+	z.QuoRem(x, y, m)
+	if m.neg {
+		if y0.neg {
+			z.Add(z, intOne)
+			m.Sub(m, y0)
+		} else {
+			z.Sub(z, intOne)
+			m.Add(m, y0)
+		}
+	}
+	return z, m
+}
+
+// Cmp compares x and y and returns:
+//
+//   -1 if x <  y
+//    0 if x == y
+//   +1 if x >  y
+//
+func (x *Int) Cmp(y *Int) (r int) {
+	// x cmp y == x cmp y
+	// x cmp (-y) == x
+	// (-x) cmp y == y
+	// (-x) cmp (-y) == -(x cmp y)
+	switch {
+	case x.neg == y.neg:
+		r = x.abs.cmp(y.abs)
+		if x.neg {
+			r = -r
+		}
+	case x.neg:
+		r = -1
+	default:
+		r = 1
+	}
+	return
+}
+
+func (x *Int) String() string {
+	switch {
+	case x == nil:
+		return "<nil>"
+	case x.neg:
+		return "-" + x.abs.decimalString()
+	}
+	return x.abs.decimalString()
+}
+
+func charset(ch rune) string {
+	switch ch {
+	case 'b':
+		return lowercaseDigits[0:2]
+	case 'o':
+		return lowercaseDigits[0:8]
+	case 'd', 's', 'v':
+		return lowercaseDigits[0:10]
+	case 'x':
+		return lowercaseDigits[0:16]
+	case 'X':
+		return uppercaseDigits[0:16]
+	}
+	return "" // unknown format
+}
+
+// write count copies of text to s
+func writeMultiple(s fmt.State, text string, count int) {
+	if len(text) > 0 {
+		b := []byte(text)
+		for ; count > 0; count-- {
+			s.Write(b)
+		}
+	}
+}
+
+// Format is a support routine for fmt.Formatter. It accepts
+// the formats 'b' (binary), 'o' (octal), 'd' (decimal), 'x'
+// (lowercase hexadecimal), and 'X' (uppercase hexadecimal).
+// Also supported are the full suite of package fmt's format
+// verbs for integral types, including '+', '-', and ' '
+// for sign control, '#' for leading zero in octal and for
+// hexadecimal, a leading "0x" or "0X" for "%#x" and "%#X"
+// respectively, specification of minimum digits precision,
+// output field width, space or zero padding, and left or
+// right justification.
+//
+func (x *Int) Format(s fmt.State, ch rune) {
+	cs := charset(ch)
+
+	// special cases
+	switch {
+	case cs == "":
+		// unknown format
+		fmt.Fprintf(s, "%%!%c(big.Int=%s)", ch, x.String())
+		return
+	case x == nil:
+		fmt.Fprint(s, "<nil>")
+		return
+	}
+
+	// determine sign character
+	sign := ""
+	switch {
+	case x.neg:
+		sign = "-"
+	case s.Flag('+'): // supersedes ' ' when both specified
+		sign = "+"
+	case s.Flag(' '):
+		sign = " "
+	}
+
+	// determine prefix characters for indicating output base
+	prefix := ""
+	if s.Flag('#') {
+		switch ch {
+		case 'o': // octal
+			prefix = "0"
+		case 'x': // hexadecimal
+			prefix = "0x"
+		case 'X':
+			prefix = "0X"
+		}
+	}
+
+	// determine digits with base set by len(cs) and digit characters from cs
+	digits := x.abs.string(cs)
+
+	// number of characters for the three classes of number padding
+	var left int   // space characters to left of digits for right justification ("%8d")
+	var zeroes int // zero characters (actually cs[0]) as left-most digits ("%.8d")
+	var right int  // space characters to right of digits for left justification ("%-8d")
+
+	// determine number padding from precision: the least number of digits to output
+	precision, precisionSet := s.Precision()
+	if precisionSet {
+		switch {
+		case len(digits) < precision:
+			zeroes = precision - len(digits) // count of zero padding
+		case digits == "0" && precision == 0:
+			return // print nothing if zero value (x == 0) and zero precision ("." or ".0")
+		}
+	}
+
+	// determine field pad from width: the least number of characters to output
+	length := len(sign) + len(prefix) + zeroes + len(digits)
+	if width, widthSet := s.Width(); widthSet && length < width { // pad as specified
+		switch d := width - length; {
+		case s.Flag('-'):
+			// pad on the right with spaces; supersedes '0' when both specified
+			right = d
+		case s.Flag('0') && !precisionSet:
+			// pad with zeroes unless precision also specified
+			zeroes = d
+		default:
+			// pad on the left with spaces
+			left = d
+		}
+	}
+
+	// print number as [left pad][sign][prefix][zero pad][digits][right pad]
+	writeMultiple(s, " ", left)
+	writeMultiple(s, sign, 1)
+	writeMultiple(s, prefix, 1)
+	writeMultiple(s, "0", zeroes)
+	writeMultiple(s, digits, 1)
+	writeMultiple(s, " ", right)
+}
+
+// scan sets z to the integer value corresponding to the longest possible prefix
+// read from r representing a signed integer number in a given conversion base.
+// It returns z, the actual conversion base used, and an error, if any. In the
+// error case, the value of z is undefined but the returned value is nil. The
+// syntax follows the syntax of integer literals in Go.
+//
+// The base argument must be 0 or a value from 2 through MaxBase. If the base
+// is 0, the string prefix determines the actual conversion base. A prefix of
+// ``0x'' or ``0X'' selects base 16; the ``0'' prefix selects base 8, and a
+// ``0b'' or ``0B'' prefix selects base 2. Otherwise the selected base is 10.
+//
+func (z *Int) scan(r io.RuneScanner, base int) (*Int, int, error) {
+	// determine sign
+	ch, _, err := r.ReadRune()
+	if err != nil {
+		return nil, 0, err
+	}
+	neg := false
+	switch ch {
+	case '-':
+		neg = true
+	case '+': // nothing to do
+	default:
+		r.UnreadRune()
+	}
+
+	// determine mantissa
+	z.abs, base, err = z.abs.scan(r, base)
+	if err != nil {
+		return nil, base, err
+	}
+	z.neg = len(z.abs) > 0 && neg // 0 has no sign
+
+	return z, base, nil
+}
+
+// Scan is a support routine for fmt.Scanner; it sets z to the value of
+// the scanned number. It accepts the formats 'b' (binary), 'o' (octal),
+// 'd' (decimal), 'x' (lowercase hexadecimal), and 'X' (uppercase hexadecimal).
+func (z *Int) Scan(s fmt.ScanState, ch rune) error {
+	s.SkipSpace() // skip leading space characters
+	base := 0
+	switch ch {
+	case 'b':
+		base = 2
+	case 'o':
+		base = 8
+	case 'd':
+		base = 10
+	case 'x', 'X':
+		base = 16
+	case 's', 'v':
+		// let scan determine the base
+	default:
+		return errors.New("Int.Scan: invalid verb")
+	}
+	_, _, err := z.scan(s, base)
+	return err
+}
+
+// low32 returns the least significant 32 bits of z.
+func low32(z nat) uint32 {
+	if len(z) == 0 {
+		return 0
+	}
+	return uint32(z[0])
+}
+
+// low64 returns the least significant 64 bits of z.
+func low64(z nat) uint64 {
+	if len(z) == 0 {
+		return 0
+	}
+	v := uint64(z[0])
+	if _W == 32 && len(z) > 1 {
+		v |= uint64(z[1]) << 32
+	}
+	return v
+}
+
+// Int64 returns the int64 representation of x.
+// If x cannot be represented in an int64, the result is undefined.
+func (x *Int) Int64() int64 {
+	v := int64(low64(x.abs))
+	if x.neg {
+		v = -v
+	}
+	return v
+}
+
+// Uint64 returns the uint64 representation of x.
+// If x cannot be represented in a uint64, the result is undefined.
+func (x *Int) Uint64() uint64 {
+	return low64(x.abs)
+}
+
+// SetString sets z to the value of s, interpreted in the given base,
+// and returns z and a boolean indicating success. If SetString fails,
+// the value of z is undefined but the returned value is nil.
+//
+// The base argument must be 0 or a value from 2 through MaxBase. If the base
+// is 0, the string prefix determines the actual conversion base. A prefix of
+// ``0x'' or ``0X'' selects base 16; the ``0'' prefix selects base 8, and a
+// ``0b'' or ``0B'' prefix selects base 2. Otherwise the selected base is 10.
+//
+func (z *Int) SetString(s string, base int) (*Int, bool) {
+	r := strings.NewReader(s)
+	_, _, err := z.scan(r, base)
+	if err != nil {
+		return nil, false
+	}
+	_, _, err = r.ReadRune()
+	if err != io.EOF {
+		return nil, false
+	}
+	return z, true // err == io.EOF => scan consumed all of s
+}
+
+// SetBytes interprets buf as the bytes of a big-endian unsigned
+// integer, sets z to that value, and returns z.
+func (z *Int) SetBytes(buf []byte) *Int {
+	z.abs = z.abs.setBytes(buf)
+	z.neg = false
+	return z
+}
+
+// Bytes returns the absolute value of x as a big-endian byte slice.
+func (x *Int) Bytes() []byte {
+	buf := make([]byte, len(x.abs)*_S)
+	return buf[x.abs.bytes(buf):]
+}
+
+// BitLen returns the length of the absolute value of x in bits.
+// The bit length of 0 is 0.
+func (x *Int) BitLen() int {
+	return x.abs.bitLen()
+}
+
+// Exp sets z = x**y mod |m| (i.e. the sign of m is ignored), and returns z.
+// If y <= 0, the result is 1 mod |m|; if m == nil or m == 0, z = x**y.
+// See Knuth, volume 2, section 4.6.3.
+func (z *Int) Exp(x, y, m *Int) *Int {
+	var yWords nat
+	if !y.neg {
+		yWords = y.abs
+	}
+	// y >= 0
+
+	var mWords nat
+	if m != nil {
+		mWords = m.abs // m.abs may be nil for m == 0
+	}
+
+	z.abs = z.abs.expNN(x.abs, yWords, mWords)
+	z.neg = len(z.abs) > 0 && x.neg && len(yWords) > 0 && yWords[0]&1 == 1 // 0 has no sign
+	if z.neg && len(mWords) > 0 {
+		// make modulus result positive
+		z.abs = z.abs.sub(mWords, z.abs) // z == x**y mod |m| && 0 <= z < |m|
+		z.neg = false
+	}
+
+	return z
+}
+
+// GCD sets z to the greatest common divisor of a and b, which both must
+// be > 0, and returns z.
+// If x and y are not nil, GCD sets x and y such that z = a*x + b*y.
+// If either a or b is <= 0, GCD sets z = x = y = 0.
+func (z *Int) GCD(x, y, a, b *Int) *Int {
+	if a.Sign() <= 0 || b.Sign() <= 0 {
+		z.SetInt64(0)
+		if x != nil {
+			x.SetInt64(0)
+		}
+		if y != nil {
+			y.SetInt64(0)
+		}
+		return z
+	}
+	if x == nil && y == nil {
+		return z.binaryGCD(a, b)
+	}
+
+	A := new(Int).Set(a)
+	B := new(Int).Set(b)
+
+	X := new(Int)
+	Y := new(Int).SetInt64(1)
+
+	lastX := new(Int).SetInt64(1)
+	lastY := new(Int)
+
+	q := new(Int)
+	temp := new(Int)
+
+	for len(B.abs) > 0 {
+		r := new(Int)
+		q, r = q.QuoRem(A, B, r)
+
+		A, B = B, r
+
+		temp.Set(X)
+		X.Mul(X, q)
+		X.neg = !X.neg
+		X.Add(X, lastX)
+		lastX.Set(temp)
+
+		temp.Set(Y)
+		Y.Mul(Y, q)
+		Y.neg = !Y.neg
+		Y.Add(Y, lastY)
+		lastY.Set(temp)
+	}
+
+	if x != nil {
+		*x = *lastX
+	}
+
+	if y != nil {
+		*y = *lastY
+	}
+
+	*z = *A
+	return z
+}
+
+// binaryGCD sets z to the greatest common divisor of a and b, which both must
+// be > 0, and returns z.
+// See Knuth, The Art of Computer Programming, Vol. 2, Section 4.5.2, Algorithm B.
+func (z *Int) binaryGCD(a, b *Int) *Int {
+	u := z
+	v := new(Int)
+
+	// use one Euclidean iteration to ensure that u and v are approx. the same size
+	switch {
+	case len(a.abs) > len(b.abs):
+		u.Set(b)
+		v.Rem(a, b)
+	case len(a.abs) < len(b.abs):
+		u.Set(a)
+		v.Rem(b, a)
+	default:
+		u.Set(a)
+		v.Set(b)
+	}
+
+	// v might be 0 now
+	if len(v.abs) == 0 {
+		return u
+	}
+	// u > 0 && v > 0
+
+	// determine largest k such that u = u' << k, v = v' << k
+	k := u.abs.trailingZeroBits()
+	if vk := v.abs.trailingZeroBits(); vk < k {
+		k = vk
+	}
+	u.Rsh(u, k)
+	v.Rsh(v, k)
+
+	// determine t (we know that u > 0)
+	t := new(Int)
+	if u.abs[0]&1 != 0 {
+		// u is odd
+		t.Neg(v)
+	} else {
+		t.Set(u)
+	}
+
+	for len(t.abs) > 0 {
+		// reduce t
+		t.Rsh(t, t.abs.trailingZeroBits())
+		if t.neg {
+			v, t = t, v
+			v.neg = len(v.abs) > 0 && !v.neg // 0 has no sign
+		} else {
+			u, t = t, u
+		}
+		t.Sub(u, v)
+	}
+
+	return z.Lsh(u, k)
+}
+
+// ProbablyPrime performs n Miller-Rabin tests to check whether x is prime.
+// If it returns true, x is prime with probability 1 - 1/4^n.
+// If it returns false, x is not prime.
+func (x *Int) ProbablyPrime(n int) bool {
+	return !x.neg && x.abs.probablyPrime(n)
+}
+
+// Rand sets z to a pseudo-random number in [0, n) and returns z.
+func (z *Int) Rand(rnd *rand.Rand, n *Int) *Int {
+	z.neg = false
+	if n.neg == true || len(n.abs) == 0 {
+		z.abs = nil
+		return z
+	}
+	z.abs = z.abs.random(rnd, n.abs, n.abs.bitLen())
+	return z
+}
+
+// ModInverse sets z to the multiplicative inverse of g in the ring ℤ/nℤ
+// and returns z. If g and n are not relatively prime, the result is undefined.
+func (z *Int) ModInverse(g, n *Int) *Int {
+	var d Int
+	d.GCD(z, nil, g, n)
+	// x and y are such that g*x + n*y = d. Since g and n are
+	// relatively prime, d = 1. Taking that modulo n results in
+	// g*x = 1, therefore x is the inverse element.
+	if z.neg {
+		z.Add(z, n)
+	}
+	return z
+}
+
+// Lsh sets z = x << n and returns z.
+func (z *Int) Lsh(x *Int, n uint) *Int {
+	z.abs = z.abs.shl(x.abs, n)
+	z.neg = x.neg
+	return z
+}
+
+// Rsh sets z = x >> n and returns z.
+func (z *Int) Rsh(x *Int, n uint) *Int {
+	if x.neg {
+		// (-x) >> s == ^(x-1) >> s == ^((x-1) >> s) == -(((x-1) >> s) + 1)
+		t := z.abs.sub(x.abs, natOne) // no underflow because |x| > 0
+		t = t.shr(t, n)
+		z.abs = t.add(t, natOne)
+		z.neg = true // z cannot be zero if x is negative
+		return z
+	}
+
+	z.abs = z.abs.shr(x.abs, n)
+	z.neg = false
+	return z
+}
+
+// Bit returns the value of the i'th bit of x. That is, it
+// returns (x>>i)&1. The bit index i must be >= 0.
+func (x *Int) Bit(i int) uint {
+	if i == 0 {
+		// optimization for common case: odd/even test of x
+		if len(x.abs) > 0 {
+			return uint(x.abs[0] & 1) // bit 0 is same for -x
+		}
+		return 0
+	}
+	if i < 0 {
+		panic("negative bit index")
+	}
+	if x.neg {
+		t := nat(nil).sub(x.abs, natOne)
+		return t.bit(uint(i)) ^ 1
+	}
+
+	return x.abs.bit(uint(i))
+}
+
+// SetBit sets z to x, with x's i'th bit set to b (0 or 1).
+// That is, if b is 1 SetBit sets z = x | (1 << i);
+// if b is 0 SetBit sets z = x &^ (1 << i). If b is not 0 or 1,
+// SetBit will panic.
+func (z *Int) SetBit(x *Int, i int, b uint) *Int {
+	if i < 0 {
+		panic("negative bit index")
+	}
+	if x.neg {
+		t := z.abs.sub(x.abs, natOne)
+		t = t.setBit(t, uint(i), b^1)
+		z.abs = t.add(t, natOne)
+		z.neg = len(z.abs) > 0
+		return z
+	}
+	z.abs = z.abs.setBit(x.abs, uint(i), b)
+	z.neg = false
+	return z
+}
+
+// And sets z = x & y and returns z.
+func (z *Int) And(x, y *Int) *Int {
+	if x.neg == y.neg {
+		if x.neg {
+			// (-x) & (-y) == ^(x-1) & ^(y-1) == ^((x-1) | (y-1)) == -(((x-1) | (y-1)) + 1)
+			x1 := nat(nil).sub(x.abs, natOne)
+			y1 := nat(nil).sub(y.abs, natOne)
+			z.abs = z.abs.add(z.abs.or(x1, y1), natOne)
+			z.neg = true // z cannot be zero if x and y are negative
+			return z
+		}
+
+		// x & y == x & y
+		z.abs = z.abs.and(x.abs, y.abs)
+		z.neg = false
+		return z
+	}
+
+	// x.neg != y.neg
+	if x.neg {
+		x, y = y, x // & is symmetric
+	}
+
+	// x & (-y) == x & ^(y-1) == x &^ (y-1)
+	y1 := nat(nil).sub(y.abs, natOne)
+	z.abs = z.abs.andNot(x.abs, y1)
+	z.neg = false
+	return z
+}
+
+// AndNot sets z = x &^ y and returns z.
+func (z *Int) AndNot(x, y *Int) *Int {
+	if x.neg == y.neg {
+		if x.neg {
+			// (-x) &^ (-y) == ^(x-1) &^ ^(y-1) == ^(x-1) & (y-1) == (y-1) &^ (x-1)
+			x1 := nat(nil).sub(x.abs, natOne)
+			y1 := nat(nil).sub(y.abs, natOne)
+			z.abs = z.abs.andNot(y1, x1)
+			z.neg = false
+			return z
+		}
+
+		// x &^ y == x &^ y
+		z.abs = z.abs.andNot(x.abs, y.abs)
+		z.neg = false
+		return z
+	}
+
+	if x.neg {
+		// (-x) &^ y == ^(x-1) &^ y == ^(x-1) & ^y == ^((x-1) | y) == -(((x-1) | y) + 1)
+		x1 := nat(nil).sub(x.abs, natOne)
+		z.abs = z.abs.add(z.abs.or(x1, y.abs), natOne)
+		z.neg = true // z cannot be zero if x is negative and y is positive
+		return z
+	}
+
+	// x &^ (-y) == x &^ ^(y-1) == x & (y-1)
+	y1 := nat(nil).add(y.abs, natOne)
+	z.abs = z.abs.and(x.abs, y1)
+	z.neg = false
+	return z
+}
+
+// Or sets z = x | y and returns z.
+func (z *Int) Or(x, y *Int) *Int {
+	if x.neg == y.neg {
+		if x.neg {
+			// (-x) | (-y) == ^(x-1) | ^(y-1) == ^((x-1) & (y-1)) == -(((x-1) & (y-1)) + 1)
+			x1 := nat(nil).sub(x.abs, natOne)
+			y1 := nat(nil).sub(y.abs, natOne)
+			z.abs = z.abs.add(z.abs.and(x1, y1), natOne)
+			z.neg = true // z cannot be zero if x and y are negative
+			return z
+		}
+
+		// x | y == x | y
+		z.abs = z.abs.or(x.abs, y.abs)
+		z.neg = false
+		return z
+	}
+
+	// x.neg != y.neg
+	if x.neg {
+		x, y = y, x // | is symmetric
+	}
+
+	// x | (-y) == x | ^(y-1) == ^((y-1) &^ x) == -(^((y-1) &^ x) + 1)
+	y1 := nat(nil).sub(y.abs, natOne)
+	z.abs = z.abs.add(z.abs.andNot(y1, x.abs), natOne)
+	z.neg = true // z cannot be zero if one of x or y is negative
+	return z
+}
+
+// Xor sets z = x ^ y and returns z.
+func (z *Int) Xor(x, y *Int) *Int {
+	if x.neg == y.neg {
+		if x.neg {
+			// (-x) ^ (-y) == ^(x-1) ^ ^(y-1) == (x-1) ^ (y-1)
+			x1 := nat(nil).sub(x.abs, natOne)
+			y1 := nat(nil).sub(y.abs, natOne)
+			z.abs = z.abs.xor(x1, y1)
+			z.neg = false
+			return z
+		}
+
+		// x ^ y == x ^ y
+		z.abs = z.abs.xor(x.abs, y.abs)
+		z.neg = false
+		return z
+	}
+
+	// x.neg != y.neg
+	if x.neg {
+		x, y = y, x // ^ is symmetric
+	}
+
+	// x ^ (-y) == x ^ ^(y-1) == ^(x ^ (y-1)) == -((x ^ (y-1)) + 1)
+	y1 := nat(nil).sub(y.abs, natOne)
+	z.abs = z.abs.add(z.abs.xor(x.abs, y1), natOne)
+	z.neg = true // z cannot be zero if only one of x or y is negative
+	return z
+}
+
+// Not sets z = ^x and returns z.
+func (z *Int) Not(x *Int) *Int {
+	if x.neg {
+		// ^(-x) == ^(^(x-1)) == x-1
+		z.abs = z.abs.sub(x.abs, natOne)
+		z.neg = false
+		return z
+	}
+
+	// ^x == -x-1 == -(x+1)
+	z.abs = z.abs.add(x.abs, natOne)
+	z.neg = true // z cannot be zero if x is positive
+	return z
+}
+
+// Gob codec version. Permits backward-compatible changes to the encoding.
+const intGobVersion byte = 1
+
+// GobEncode implements the gob.GobEncoder interface.
+func (x *Int) GobEncode() ([]byte, error) {
+	if x == nil {
+		return nil, nil
+	}
+	buf := make([]byte, 1+len(x.abs)*_S) // extra byte for version and sign bit
+	i := x.abs.bytes(buf) - 1            // i >= 0
+	b := intGobVersion << 1              // make space for sign bit
+	if x.neg {
+		b |= 1
+	}
+	buf[i] = b
+	return buf[i:], nil
+}
+
+// GobDecode implements the gob.GobDecoder interface.
+func (z *Int) GobDecode(buf []byte) error {
+	if len(buf) == 0 {
+		// Other side sent a nil or default value.
+		*z = Int{}
+		return nil
+	}
+	b := buf[0]
+	if b>>1 != intGobVersion {
+		return errors.New(fmt.Sprintf("Int.GobDecode: encoding version %d not supported", b>>1))
+	}
+	z.neg = b&1 != 0
+	z.abs = z.abs.setBytes(buf[1:])
+	return nil
+}
+
+// MarshalJSON implements the json.Marshaler interface.
+func (z *Int) MarshalJSON() ([]byte, error) {
+	// TODO(gri): get rid of the []byte/string conversions
+	return []byte(z.String()), nil
+}
+
+// UnmarshalJSON implements the json.Unmarshaler interface.
+func (z *Int) UnmarshalJSON(text []byte) error {
+	// TODO(gri): get rid of the []byte/string conversions
+	if _, ok := z.SetString(string(text), 0); !ok {
+		return fmt.Errorf("math/big: cannot unmarshal %q into a *big.Int", text)
+	}
+	return nil
+}
+
+// MarshalText implements the encoding.TextMarshaler interface.
+func (z *Int) MarshalText() (text []byte, err error) {
+	return []byte(z.String()), nil
+}
+
+// UnmarshalText implements the encoding.TextUnmarshaler interface.
+func (z *Int) UnmarshalText(text []byte) error {
+	if _, ok := z.SetString(string(text), 0); !ok {
+		return fmt.Errorf("math/big: cannot unmarshal %q into a *big.Int", text)
+	}
+	return nil
+}
diff --git a/src/math/big/int_test.go b/src/math/big/int_test.go
new file mode 100644
index 0000000..6070cf3
--- /dev/null
+++ b/src/math/big/int_test.go
@@ -0,0 +1,1625 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package big
+
+import (
+	"bytes"
+	"encoding/gob"
+	"encoding/hex"
+	"encoding/json"
+	"encoding/xml"
+	"fmt"
+	"math/rand"
+	"testing"
+	"testing/quick"
+)
+
+func isNormalized(x *Int) bool {
+	if len(x.abs) == 0 {
+		return !x.neg
+	}
+	// len(x.abs) > 0
+	return x.abs[len(x.abs)-1] != 0
+}
+
+type funZZ func(z, x, y *Int) *Int
+type argZZ struct {
+	z, x, y *Int
+}
+
+var sumZZ = []argZZ{
+	{NewInt(0), NewInt(0), NewInt(0)},
+	{NewInt(1), NewInt(1), NewInt(0)},
+	{NewInt(1111111110), NewInt(123456789), NewInt(987654321)},
+	{NewInt(-1), NewInt(-1), NewInt(0)},
+	{NewInt(864197532), NewInt(-123456789), NewInt(987654321)},
+	{NewInt(-1111111110), NewInt(-123456789), NewInt(-987654321)},
+}
+
+var prodZZ = []argZZ{
+	{NewInt(0), NewInt(0), NewInt(0)},
+	{NewInt(0), NewInt(1), NewInt(0)},
+	{NewInt(1), NewInt(1), NewInt(1)},
+	{NewInt(-991 * 991), NewInt(991), NewInt(-991)},
+	// TODO(gri) add larger products
+}
+
+func TestSignZ(t *testing.T) {
+	var zero Int
+	for _, a := range sumZZ {
+		s := a.z.Sign()
+		e := a.z.Cmp(&zero)
+		if s != e {
+			t.Errorf("got %d; want %d for z = %v", s, e, a.z)
+		}
+	}
+}
+
+func TestSetZ(t *testing.T) {
+	for _, a := range sumZZ {
+		var z Int
+		z.Set(a.z)
+		if !isNormalized(&z) {
+			t.Errorf("%v is not normalized", z)
+		}
+		if (&z).Cmp(a.z) != 0 {
+			t.Errorf("got z = %v; want %v", z, a.z)
+		}
+	}
+}
+
+func TestAbsZ(t *testing.T) {
+	var zero Int
+	for _, a := range sumZZ {
+		var z Int
+		z.Abs(a.z)
+		var e Int
+		e.Set(a.z)
+		if e.Cmp(&zero) < 0 {
+			e.Sub(&zero, &e)
+		}
+		if z.Cmp(&e) != 0 {
+			t.Errorf("got z = %v; want %v", z, e)
+		}
+	}
+}
+
+func testFunZZ(t *testing.T, msg string, f funZZ, a argZZ) {
+	var z Int
+	f(&z, a.x, a.y)
+	if !isNormalized(&z) {
+		t.Errorf("%s%v is not normalized", msg, z)
+	}
+	if (&z).Cmp(a.z) != 0 {
+		t.Errorf("%s%+v\n\tgot z = %v; want %v", msg, a, &z, a.z)
+	}
+}
+
+func TestSumZZ(t *testing.T) {
+	AddZZ := func(z, x, y *Int) *Int { return z.Add(x, y) }
+	SubZZ := func(z, x, y *Int) *Int { return z.Sub(x, y) }
+	for _, a := range sumZZ {
+		arg := a
+		testFunZZ(t, "AddZZ", AddZZ, arg)
+
+		arg = argZZ{a.z, a.y, a.x}
+		testFunZZ(t, "AddZZ symmetric", AddZZ, arg)
+
+		arg = argZZ{a.x, a.z, a.y}
+		testFunZZ(t, "SubZZ", SubZZ, arg)
+
+		arg = argZZ{a.y, a.z, a.x}
+		testFunZZ(t, "SubZZ symmetric", SubZZ, arg)
+	}
+}
+
+func TestProdZZ(t *testing.T) {
+	MulZZ := func(z, x, y *Int) *Int { return z.Mul(x, y) }
+	for _, a := range prodZZ {
+		arg := a
+		testFunZZ(t, "MulZZ", MulZZ, arg)
+
+		arg = argZZ{a.z, a.y, a.x}
+		testFunZZ(t, "MulZZ symmetric", MulZZ, arg)
+	}
+}
+
+// mulBytes returns x*y via grade school multiplication. Both inputs
+// and the result are assumed to be in big-endian representation (to
+// match the semantics of Int.Bytes and Int.SetBytes).
+func mulBytes(x, y []byte) []byte {
+	z := make([]byte, len(x)+len(y))
+
+	// multiply
+	k0 := len(z) - 1
+	for j := len(y) - 1; j >= 0; j-- {
+		d := int(y[j])
+		if d != 0 {
+			k := k0
+			carry := 0
+			for i := len(x) - 1; i >= 0; i-- {
+				t := int(z[k]) + int(x[i])*d + carry
+				z[k], carry = byte(t), t>>8
+				k--
+			}
+			z[k] = byte(carry)
+		}
+		k0--
+	}
+
+	// normalize (remove leading 0's)
+	i := 0
+	for i < len(z) && z[i] == 0 {
+		i++
+	}
+
+	return z[i:]
+}
+
+func checkMul(a, b []byte) bool {
+	var x, y, z1 Int
+	x.SetBytes(a)
+	y.SetBytes(b)
+	z1.Mul(&x, &y)
+
+	var z2 Int
+	z2.SetBytes(mulBytes(a, b))
+
+	return z1.Cmp(&z2) == 0
+}
+
+func TestMul(t *testing.T) {
+	if err := quick.Check(checkMul, nil); err != nil {
+		t.Error(err)
+	}
+}
+
+var mulRangesZ = []struct {
+	a, b int64
+	prod string
+}{
+	// entirely positive ranges are covered by mulRangesN
+	{-1, 1, "0"},
+	{-2, -1, "2"},
+	{-3, -2, "6"},
+	{-3, -1, "-6"},
+	{1, 3, "6"},
+	{-10, -10, "-10"},
+	{0, -1, "1"},                      // empty range
+	{-1, -100, "1"},                   // empty range
+	{-1, 1, "0"},                      // range includes 0
+	{-1e9, 0, "0"},                    // range includes 0
+	{-1e9, 1e9, "0"},                  // range includes 0
+	{-10, -1, "3628800"},              // 10!
+	{-20, -2, "-2432902008176640000"}, // -20!
+	{-99, -1,
+		"-933262154439441526816992388562667004907159682643816214685929" +
+			"638952175999932299156089414639761565182862536979208272237582" +
+			"511852109168640000000000000000000000", // -99!
+	},
+}
+
+func TestMulRangeZ(t *testing.T) {
+	var tmp Int
+	// test entirely positive ranges
+	for i, r := range mulRangesN {
+		prod := tmp.MulRange(int64(r.a), int64(r.b)).String()
+		if prod != r.prod {
+			t.Errorf("#%da: got %s; want %s", i, prod, r.prod)
+		}
+	}
+	// test other ranges
+	for i, r := range mulRangesZ {
+		prod := tmp.MulRange(r.a, r.b).String()
+		if prod != r.prod {
+			t.Errorf("#%db: got %s; want %s", i, prod, r.prod)
+		}
+	}
+}
+
+var stringTests = []struct {
+	in   string
+	out  string
+	base int
+	val  int64
+	ok   bool
+}{
+	{in: "", ok: false},
+	{in: "a", ok: false},
+	{in: "z", ok: false},
+	{in: "+", ok: false},
+	{in: "-", ok: false},
+	{in: "0b", ok: false},
+	{in: "0x", ok: false},
+	{in: "2", base: 2, ok: false},
+	{in: "0b2", base: 0, ok: false},
+	{in: "08", ok: false},
+	{in: "8", base: 8, ok: false},
+	{in: "0xg", base: 0, ok: false},
+	{in: "g", base: 16, ok: false},
+	{"0", "0", 0, 0, true},
+	{"0", "0", 10, 0, true},
+	{"0", "0", 16, 0, true},
+	{"+0", "0", 0, 0, true},
+	{"-0", "0", 0, 0, true},
+	{"10", "10", 0, 10, true},
+	{"10", "10", 10, 10, true},
+	{"10", "10", 16, 16, true},
+	{"-10", "-10", 16, -16, true},
+	{"+10", "10", 16, 16, true},
+	{"0x10", "16", 0, 16, true},
+	{in: "0x10", base: 16, ok: false},
+	{"-0x10", "-16", 0, -16, true},
+	{"+0x10", "16", 0, 16, true},
+	{"00", "0", 0, 0, true},
+	{"0", "0", 8, 0, true},
+	{"07", "7", 0, 7, true},
+	{"7", "7", 8, 7, true},
+	{"023", "19", 0, 19, true},
+	{"23", "23", 8, 19, true},
+	{"cafebabe", "cafebabe", 16, 0xcafebabe, true},
+	{"0b0", "0", 0, 0, true},
+	{"-111", "-111", 2, -7, true},
+	{"-0b111", "-7", 0, -7, true},
+	{"0b1001010111", "599", 0, 0x257, true},
+	{"1001010111", "1001010111", 2, 0x257, true},
+}
+
+func format(base int) string {
+	switch base {
+	case 2:
+		return "%b"
+	case 8:
+		return "%o"
+	case 16:
+		return "%x"
+	}
+	return "%d"
+}
+
+func TestGetString(t *testing.T) {
+	z := new(Int)
+	for i, test := range stringTests {
+		if !test.ok {
+			continue
+		}
+		z.SetInt64(test.val)
+
+		if test.base == 10 {
+			s := z.String()
+			if s != test.out {
+				t.Errorf("#%da got %s; want %s", i, s, test.out)
+			}
+		}
+
+		s := fmt.Sprintf(format(test.base), z)
+		if s != test.out {
+			t.Errorf("#%db got %s; want %s", i, s, test.out)
+		}
+	}
+}
+
+func TestSetString(t *testing.T) {
+	tmp := new(Int)
+	for i, test := range stringTests {
+		// initialize to a non-zero value so that issues with parsing
+		// 0 are detected
+		tmp.SetInt64(1234567890)
+		n1, ok1 := new(Int).SetString(test.in, test.base)
+		n2, ok2 := tmp.SetString(test.in, test.base)
+		expected := NewInt(test.val)
+		if ok1 != test.ok || ok2 != test.ok {
+			t.Errorf("#%d (input '%s') ok incorrect (should be %t)", i, test.in, test.ok)
+			continue
+		}
+		if !ok1 {
+			if n1 != nil {
+				t.Errorf("#%d (input '%s') n1 != nil", i, test.in)
+			}
+			continue
+		}
+		if !ok2 {
+			if n2 != nil {
+				t.Errorf("#%d (input '%s') n2 != nil", i, test.in)
+			}
+			continue
+		}
+
+		if ok1 && !isNormalized(n1) {
+			t.Errorf("#%d (input '%s'): %v is not normalized", i, test.in, *n1)
+		}
+		if ok2 && !isNormalized(n2) {
+			t.Errorf("#%d (input '%s'): %v is not normalized", i, test.in, *n2)
+		}
+
+		if n1.Cmp(expected) != 0 {
+			t.Errorf("#%d (input '%s') got: %s want: %d", i, test.in, n1, test.val)
+		}
+		if n2.Cmp(expected) != 0 {
+			t.Errorf("#%d (input '%s') got: %s want: %d", i, test.in, n2, test.val)
+		}
+	}
+}
+
+var formatTests = []struct {
+	input  string
+	format string
+	output string
+}{
+	{"<nil>", "%x", "<nil>"},
+	{"<nil>", "%#x", "<nil>"},
+	{"<nil>", "%#y", "%!y(big.Int=<nil>)"},
+
+	{"10", "%b", "1010"},
+	{"10", "%o", "12"},
+	{"10", "%d", "10"},
+	{"10", "%v", "10"},
+	{"10", "%x", "a"},
+	{"10", "%X", "A"},
+	{"-10", "%X", "-A"},
+	{"10", "%y", "%!y(big.Int=10)"},
+	{"-10", "%y", "%!y(big.Int=-10)"},
+
+	{"10", "%#b", "1010"},
+	{"10", "%#o", "012"},
+	{"10", "%#d", "10"},
+	{"10", "%#v", "10"},
+	{"10", "%#x", "0xa"},
+	{"10", "%#X", "0XA"},
+	{"-10", "%#X", "-0XA"},
+	{"10", "%#y", "%!y(big.Int=10)"},
+	{"-10", "%#y", "%!y(big.Int=-10)"},
+
+	{"1234", "%d", "1234"},
+	{"1234", "%3d", "1234"},
+	{"1234", "%4d", "1234"},
+	{"-1234", "%d", "-1234"},
+	{"1234", "% 5d", " 1234"},
+	{"1234", "%+5d", "+1234"},
+	{"1234", "%-5d", "1234 "},
+	{"1234", "%x", "4d2"},
+	{"1234", "%X", "4D2"},
+	{"-1234", "%3x", "-4d2"},
+	{"-1234", "%4x", "-4d2"},
+	{"-1234", "%5x", " -4d2"},
+	{"-1234", "%-5x", "-4d2 "},
+	{"1234", "%03d", "1234"},
+	{"1234", "%04d", "1234"},
+	{"1234", "%05d", "01234"},
+	{"1234", "%06d", "001234"},
+	{"-1234", "%06d", "-01234"},
+	{"1234", "%+06d", "+01234"},
+	{"1234", "% 06d", " 01234"},
+	{"1234", "%-6d", "1234  "},
+	{"1234", "%-06d", "1234  "},
+	{"-1234", "%-06d", "-1234 "},
+
+	{"1234", "%.3d", "1234"},
+	{"1234", "%.4d", "1234"},
+	{"1234", "%.5d", "01234"},
+	{"1234", "%.6d", "001234"},
+	{"-1234", "%.3d", "-1234"},
+	{"-1234", "%.4d", "-1234"},
+	{"-1234", "%.5d", "-01234"},
+	{"-1234", "%.6d", "-001234"},
+
+	{"1234", "%8.3d", "    1234"},
+	{"1234", "%8.4d", "    1234"},
+	{"1234", "%8.5d", "   01234"},
+	{"1234", "%8.6d", "  001234"},
+	{"-1234", "%8.3d", "   -1234"},
+	{"-1234", "%8.4d", "   -1234"},
+	{"-1234", "%8.5d", "  -01234"},
+	{"-1234", "%8.6d", " -001234"},
+
+	{"1234", "%+8.3d", "   +1234"},
+	{"1234", "%+8.4d", "   +1234"},
+	{"1234", "%+8.5d", "  +01234"},
+	{"1234", "%+8.6d", " +001234"},
+	{"-1234", "%+8.3d", "   -1234"},
+	{"-1234", "%+8.4d", "   -1234"},
+	{"-1234", "%+8.5d", "  -01234"},
+	{"-1234", "%+8.6d", " -001234"},
+
+	{"1234", "% 8.3d", "    1234"},
+	{"1234", "% 8.4d", "    1234"},
+	{"1234", "% 8.5d", "   01234"},
+	{"1234", "% 8.6d", "  001234"},
+	{"-1234", "% 8.3d", "   -1234"},
+	{"-1234", "% 8.4d", "   -1234"},
+	{"-1234", "% 8.5d", "  -01234"},
+	{"-1234", "% 8.6d", " -001234"},
+
+	{"1234", "%.3x", "4d2"},
+	{"1234", "%.4x", "04d2"},
+	{"1234", "%.5x", "004d2"},
+	{"1234", "%.6x", "0004d2"},
+	{"-1234", "%.3x", "-4d2"},
+	{"-1234", "%.4x", "-04d2"},
+	{"-1234", "%.5x", "-004d2"},
+	{"-1234", "%.6x", "-0004d2"},
+
+	{"1234", "%8.3x", "     4d2"},
+	{"1234", "%8.4x", "    04d2"},
+	{"1234", "%8.5x", "   004d2"},
+	{"1234", "%8.6x", "  0004d2"},
+	{"-1234", "%8.3x", "    -4d2"},
+	{"-1234", "%8.4x", "   -04d2"},
+	{"-1234", "%8.5x", "  -004d2"},
+	{"-1234", "%8.6x", " -0004d2"},
+
+	{"1234", "%+8.3x", "    +4d2"},
+	{"1234", "%+8.4x", "   +04d2"},
+	{"1234", "%+8.5x", "  +004d2"},
+	{"1234", "%+8.6x", " +0004d2"},
+	{"-1234", "%+8.3x", "    -4d2"},
+	{"-1234", "%+8.4x", "   -04d2"},
+	{"-1234", "%+8.5x", "  -004d2"},
+	{"-1234", "%+8.6x", " -0004d2"},
+
+	{"1234", "% 8.3x", "     4d2"},
+	{"1234", "% 8.4x", "    04d2"},
+	{"1234", "% 8.5x", "   004d2"},
+	{"1234", "% 8.6x", "  0004d2"},
+	{"1234", "% 8.7x", " 00004d2"},
+	{"1234", "% 8.8x", " 000004d2"},
+	{"-1234", "% 8.3x", "    -4d2"},
+	{"-1234", "% 8.4x", "   -04d2"},
+	{"-1234", "% 8.5x", "  -004d2"},
+	{"-1234", "% 8.6x", " -0004d2"},
+	{"-1234", "% 8.7x", "-00004d2"},
+	{"-1234", "% 8.8x", "-000004d2"},
+
+	{"1234", "%-8.3d", "1234    "},
+	{"1234", "%-8.4d", "1234    "},
+	{"1234", "%-8.5d", "01234   "},
+	{"1234", "%-8.6d", "001234  "},
+	{"1234", "%-8.7d", "0001234 "},
+	{"1234", "%-8.8d", "00001234"},
+	{"-1234", "%-8.3d", "-1234   "},
+	{"-1234", "%-8.4d", "-1234   "},
+	{"-1234", "%-8.5d", "-01234  "},
+	{"-1234", "%-8.6d", "-001234 "},
+	{"-1234", "%-8.7d", "-0001234"},
+	{"-1234", "%-8.8d", "-00001234"},
+
+	{"16777215", "%b", "111111111111111111111111"}, // 2**24 - 1
+
+	{"0", "%.d", ""},
+	{"0", "%.0d", ""},
+	{"0", "%3.d", ""},
+}
+
+func TestFormat(t *testing.T) {
+	for i, test := range formatTests {
+		var x *Int
+		if test.input != "<nil>" {
+			var ok bool
+			x, ok = new(Int).SetString(test.input, 0)
+			if !ok {
+				t.Errorf("#%d failed reading input %s", i, test.input)
+			}
+		}
+		output := fmt.Sprintf(test.format, x)
+		if output != test.output {
+			t.Errorf("#%d got %q; want %q, {%q, %q, %q}", i, output, test.output, test.input, test.format, test.output)
+		}
+	}
+}
+
+var scanTests = []struct {
+	input     string
+	format    string
+	output    string
+	remaining int
+}{
+	{"1010", "%b", "10", 0},
+	{"0b1010", "%v", "10", 0},
+	{"12", "%o", "10", 0},
+	{"012", "%v", "10", 0},
+	{"10", "%d", "10", 0},
+	{"10", "%v", "10", 0},
+	{"a", "%x", "10", 0},
+	{"0xa", "%v", "10", 0},
+	{"A", "%X", "10", 0},
+	{"-A", "%X", "-10", 0},
+	{"+0b1011001", "%v", "89", 0},
+	{"0xA", "%v", "10", 0},
+	{"0 ", "%v", "0", 1},
+	{"2+3", "%v", "2", 2},
+	{"0XABC 12", "%v", "2748", 3},
+}
+
+func TestScan(t *testing.T) {
+	var buf bytes.Buffer
+	for i, test := range scanTests {
+		x := new(Int)
+		buf.Reset()
+		buf.WriteString(test.input)
+		if _, err := fmt.Fscanf(&buf, test.format, x); err != nil {
+			t.Errorf("#%d error: %s", i, err)
+		}
+		if x.String() != test.output {
+			t.Errorf("#%d got %s; want %s", i, x.String(), test.output)
+		}
+		if buf.Len() != test.remaining {
+			t.Errorf("#%d got %d bytes remaining; want %d", i, buf.Len(), test.remaining)
+		}
+	}
+}
+
+// Examples from the Go Language Spec, section "Arithmetic operators"
+var divisionSignsTests = []struct {
+	x, y int64
+	q, r int64 // T-division
+	d, m int64 // Euclidian division
+}{
+	{5, 3, 1, 2, 1, 2},
+	{-5, 3, -1, -2, -2, 1},
+	{5, -3, -1, 2, -1, 2},
+	{-5, -3, 1, -2, 2, 1},
+	{1, 2, 0, 1, 0, 1},
+	{8, 4, 2, 0, 2, 0},
+}
+
+func TestDivisionSigns(t *testing.T) {
+	for i, test := range divisionSignsTests {
+		x := NewInt(test.x)
+		y := NewInt(test.y)
+		q := NewInt(test.q)
+		r := NewInt(test.r)
+		d := NewInt(test.d)
+		m := NewInt(test.m)
+
+		q1 := new(Int).Quo(x, y)
+		r1 := new(Int).Rem(x, y)
+		if !isNormalized(q1) {
+			t.Errorf("#%d Quo: %v is not normalized", i, *q1)
+		}
+		if !isNormalized(r1) {
+			t.Errorf("#%d Rem: %v is not normalized", i, *r1)
+		}
+		if q1.Cmp(q) != 0 || r1.Cmp(r) != 0 {
+			t.Errorf("#%d QuoRem: got (%s, %s), want (%s, %s)", i, q1, r1, q, r)
+		}
+
+		q2, r2 := new(Int).QuoRem(x, y, new(Int))
+		if !isNormalized(q2) {
+			t.Errorf("#%d Quo: %v is not normalized", i, *q2)
+		}
+		if !isNormalized(r2) {
+			t.Errorf("#%d Rem: %v is not normalized", i, *r2)
+		}
+		if q2.Cmp(q) != 0 || r2.Cmp(r) != 0 {
+			t.Errorf("#%d QuoRem: got (%s, %s), want (%s, %s)", i, q2, r2, q, r)
+		}
+
+		d1 := new(Int).Div(x, y)
+		m1 := new(Int).Mod(x, y)
+		if !isNormalized(d1) {
+			t.Errorf("#%d Div: %v is not normalized", i, *d1)
+		}
+		if !isNormalized(m1) {
+			t.Errorf("#%d Mod: %v is not normalized", i, *m1)
+		}
+		if d1.Cmp(d) != 0 || m1.Cmp(m) != 0 {
+			t.Errorf("#%d DivMod: got (%s, %s), want (%s, %s)", i, d1, m1, d, m)
+		}
+
+		d2, m2 := new(Int).DivMod(x, y, new(Int))
+		if !isNormalized(d2) {
+			t.Errorf("#%d Div: %v is not normalized", i, *d2)
+		}
+		if !isNormalized(m2) {
+			t.Errorf("#%d Mod: %v is not normalized", i, *m2)
+		}
+		if d2.Cmp(d) != 0 || m2.Cmp(m) != 0 {
+			t.Errorf("#%d DivMod: got (%s, %s), want (%s, %s)", i, d2, m2, d, m)
+		}
+	}
+}
+
+func checkSetBytes(b []byte) bool {
+	hex1 := hex.EncodeToString(new(Int).SetBytes(b).Bytes())
+	hex2 := hex.EncodeToString(b)
+
+	for len(hex1) < len(hex2) {
+		hex1 = "0" + hex1
+	}
+
+	for len(hex1) > len(hex2) {
+		hex2 = "0" + hex2
+	}
+
+	return hex1 == hex2
+}
+
+func TestSetBytes(t *testing.T) {
+	if err := quick.Check(checkSetBytes, nil); err != nil {
+		t.Error(err)
+	}
+}
+
+func checkBytes(b []byte) bool {
+	b2 := new(Int).SetBytes(b).Bytes()
+	return bytes.Equal(b, b2)
+}
+
+func TestBytes(t *testing.T) {
+	if err := quick.Check(checkSetBytes, nil); err != nil {
+		t.Error(err)
+	}
+}
+
+func checkQuo(x, y []byte) bool {
+	u := new(Int).SetBytes(x)
+	v := new(Int).SetBytes(y)
+
+	if len(v.abs) == 0 {
+		return true
+	}
+
+	r := new(Int)
+	q, r := new(Int).QuoRem(u, v, r)
+
+	if r.Cmp(v) >= 0 {
+		return false
+	}
+
+	uprime := new(Int).Set(q)
+	uprime.Mul(uprime, v)
+	uprime.Add(uprime, r)
+
+	return uprime.Cmp(u) == 0
+}
+
+var quoTests = []struct {
+	x, y string
+	q, r string
+}{
+	{
+		"476217953993950760840509444250624797097991362735329973741718102894495832294430498335824897858659711275234906400899559094370964723884706254265559534144986498357",
+		"9353930466774385905609975137998169297361893554149986716853295022578535724979483772383667534691121982974895531435241089241440253066816724367338287092081996",
+		"50911",
+		"1",
+	},
+	{
+		"11510768301994997771168",
+		"1328165573307167369775",
+		"8",
+		"885443715537658812968",
+	},
+}
+
+func TestQuo(t *testing.T) {
+	if err := quick.Check(checkQuo, nil); err != nil {
+		t.Error(err)
+	}
+
+	for i, test := range quoTests {
+		x, _ := new(Int).SetString(test.x, 10)
+		y, _ := new(Int).SetString(test.y, 10)
+		expectedQ, _ := new(Int).SetString(test.q, 10)
+		expectedR, _ := new(Int).SetString(test.r, 10)
+
+		r := new(Int)
+		q, r := new(Int).QuoRem(x, y, r)
+
+		if q.Cmp(expectedQ) != 0 || r.Cmp(expectedR) != 0 {
+			t.Errorf("#%d got (%s, %s) want (%s, %s)", i, q, r, expectedQ, expectedR)
+		}
+	}
+}
+
+func TestQuoStepD6(t *testing.T) {
+	// See Knuth, Volume 2, section 4.3.1, exercise 21. This code exercises
+	// a code path which only triggers 1 in 10^{-19} cases.
+
+	u := &Int{false, nat{0, 0, 1 + 1<<(_W-1), _M ^ (1 << (_W - 1))}}
+	v := &Int{false, nat{5, 2 + 1<<(_W-1), 1 << (_W - 1)}}
+
+	r := new(Int)
+	q, r := new(Int).QuoRem(u, v, r)
+	const expectedQ64 = "18446744073709551613"
+	const expectedR64 = "3138550867693340382088035895064302439801311770021610913807"
+	const expectedQ32 = "4294967293"
+	const expectedR32 = "39614081266355540837921718287"
+	if q.String() != expectedQ64 && q.String() != expectedQ32 ||
+		r.String() != expectedR64 && r.String() != expectedR32 {
+		t.Errorf("got (%s, %s) want (%s, %s) or (%s, %s)", q, r, expectedQ64, expectedR64, expectedQ32, expectedR32)
+	}
+}
+
+var bitLenTests = []struct {
+	in  string
+	out int
+}{
+	{"-1", 1},
+	{"0", 0},
+	{"1", 1},
+	{"2", 2},
+	{"4", 3},
+	{"0xabc", 12},
+	{"0x8000", 16},
+	{"0x80000000", 32},
+	{"0x800000000000", 48},
+	{"0x8000000000000000", 64},
+	{"0x80000000000000000000", 80},
+	{"-0x4000000000000000000000", 87},
+}
+
+func TestBitLen(t *testing.T) {
+	for i, test := range bitLenTests {
+		x, ok := new(Int).SetString(test.in, 0)
+		if !ok {
+			t.Errorf("#%d test input invalid: %s", i, test.in)
+			continue
+		}
+
+		if n := x.BitLen(); n != test.out {
+			t.Errorf("#%d got %d want %d", i, n, test.out)
+		}
+	}
+}
+
+var expTests = []struct {
+	x, y, m string
+	out     string
+}{
+	// y <= 0
+	{"0", "0", "", "1"},
+	{"1", "0", "", "1"},
+	{"-10", "0", "", "1"},
+	{"1234", "-1", "", "1"},
+
+	// m == 1
+	{"0", "0", "1", "0"},
+	{"1", "0", "1", "0"},
+	{"-10", "0", "1", "0"},
+	{"1234", "-1", "1", "0"},
+
+	// misc
+	{"5", "-7", "", "1"},
+	{"-5", "-7", "", "1"},
+	{"5", "0", "", "1"},
+	{"-5", "0", "", "1"},
+	{"5", "1", "", "5"},
+	{"-5", "1", "", "-5"},
+	{"-5", "1", "7", "2"},
+	{"-2", "3", "2", "0"},
+	{"5", "2", "", "25"},
+	{"1", "65537", "2", "1"},
+	{"0x8000000000000000", "2", "", "0x40000000000000000000000000000000"},
+	{"0x8000000000000000", "2", "6719", "4944"},
+	{"0x8000000000000000", "3", "6719", "5447"},
+	{"0x8000000000000000", "1000", "6719", "1603"},
+	{"0x8000000000000000", "1000000", "6719", "3199"},
+	{"0x8000000000000000", "-1000000", "6719", "1"},
+	{
+		"2938462938472983472983659726349017249287491026512746239764525612965293865296239471239874193284792387498274256129746192347",
+		"298472983472983471903246121093472394872319615612417471234712061",
+		"29834729834729834729347290846729561262544958723956495615629569234729836259263598127342374289365912465901365498236492183464",
+		"23537740700184054162508175125554701713153216681790245129157191391322321508055833908509185839069455749219131480588829346291",
+	},
+	// test case for issue 8822
+	{
+		"-0x1BCE04427D8032319A89E5C4136456671AC620883F2C4139E57F91307C485AD2D6204F4F87A58262652DB5DBBAC72B0613E51B835E7153BEC6068F5C8D696B74DBD18FEC316AEF73985CF0475663208EB46B4F17DD9DA55367B03323E5491A70997B90C059FB34809E6EE55BCFBD5F2F52233BFE62E6AA9E4E26A1D4C2439883D14F2633D55D8AA66A1ACD5595E778AC3A280517F1157989E70C1A437B849F1877B779CC3CDDEDE2DAA6594A6C66D181A00A5F777EE60596D8773998F6E988DEAE4CCA60E4DDCF9590543C89F74F603259FCAD71660D30294FBBE6490300F78A9D63FA660DC9417B8B9DDA28BEB3977B621B98 [...]
+		"0xB08FFB20760FFED58FADA86DFEF71AD72AA0FA763219618FE022C197E54708BB1191C66470250FCE8879487507CEE41381CA4D932F81C2B3F1AB20B539D50DCD",
+		"0xAC6BDB41324A9A9BF166DE5E1389582FAF72B6651987EE07FC3192943DB56050A37329CBB4A099ED8193E0757767A13DD52312AB4B03310DCD7F48A9DA04FD50E8083969EDB767B0CF6095179A163AB3661A05FBD5FAAAE82918A9962F0B93B855F97993EC975EEAA80D740ADBF4FF747359D041D5C33EA71D281E446B14773BCA97B43A23FB801676BD207A436C6481F1D2B9078717461A5B9D32E688F87748544523B524B0D57D5EA77A2775D2ECFA032CFBDBF52FB3786160279004E57AE6AF874E7303CE53299CCC041C7BC308D82A5698F3A8D0C38271AE35F8E9DBFBB694B5C803D89F7AE435DE236D525F54759B65E37 [...]
+		"214842521977763024996399388837777103219931130979872010505011829095813593576185795667465563725893853616836105247305090413288550665149633855225708948390358847130516401714741865487135466864767613064364341464751401562843891818086750165768458333404948482836810888865842197505544080605567694866280290287207273932931116788263564804554339092335205041120744013761330771504712375494741491902420104695390064495966115766125739557543490423291306311282346379247864665857034884605402284774408534933920862 [...]
+	},
+}
+
+func TestExp(t *testing.T) {
+	for i, test := range expTests {
+		x, ok1 := new(Int).SetString(test.x, 0)
+		y, ok2 := new(Int).SetString(test.y, 0)
+		out, ok3 := new(Int).SetString(test.out, 0)
+
+		var ok4 bool
+		var m *Int
+
+		if len(test.m) == 0 {
+			m, ok4 = nil, true
+		} else {
+			m, ok4 = new(Int).SetString(test.m, 0)
+		}
+
+		if !ok1 || !ok2 || !ok3 || !ok4 {
+			t.Errorf("#%d: error in input", i)
+			continue
+		}
+
+		z1 := new(Int).Exp(x, y, m)
+		if !isNormalized(z1) {
+			t.Errorf("#%d: %v is not normalized", i, *z1)
+		}
+		if z1.Cmp(out) != 0 {
+			t.Errorf("#%d: got %s want %s", i, z1, out)
+		}
+
+		if m == nil {
+			// The result should be the same as for m == 0;
+			// specifically, there should be no div-zero panic.
+			m = &Int{abs: nat{}} // m != nil && len(m.abs) == 0
+			z2 := new(Int).Exp(x, y, m)
+			if z2.Cmp(z1) != 0 {
+				t.Errorf("#%d: got %s want %s", i, z2, z1)
+			}
+		}
+	}
+}
+
+func checkGcd(aBytes, bBytes []byte) bool {
+	x := new(Int)
+	y := new(Int)
+	a := new(Int).SetBytes(aBytes)
+	b := new(Int).SetBytes(bBytes)
+
+	d := new(Int).GCD(x, y, a, b)
+	x.Mul(x, a)
+	y.Mul(y, b)
+	x.Add(x, y)
+
+	return x.Cmp(d) == 0
+}
+
+var gcdTests = []struct {
+	d, x, y, a, b string
+}{
+	// a <= 0 || b <= 0
+	{"0", "0", "0", "0", "0"},
+	{"0", "0", "0", "0", "7"},
+	{"0", "0", "0", "11", "0"},
+	{"0", "0", "0", "-77", "35"},
+	{"0", "0", "0", "64515", "-24310"},
+	{"0", "0", "0", "-64515", "-24310"},
+
+	{"1", "-9", "47", "120", "23"},
+	{"7", "1", "-2", "77", "35"},
+	{"935", "-3", "8", "64515", "24310"},
+	{"935000000000000000", "-3", "8", "64515000000000000000", "24310000000000000000"},
+	{"1", "-221", "22059940471369027483332068679400581064239780177629666810348940098015901108344", "98920366548084643601728869055592650835572950932266967461790948584315647051443", "991"},
+
+	// test early exit (after one Euclidean iteration) in binaryGCD
+	{"1", "", "", "1", "98920366548084643601728869055592650835572950932266967461790948584315647051443"},
+}
+
+func testGcd(t *testing.T, d, x, y, a, b *Int) {
+	var X *Int
+	if x != nil {
+		X = new(Int)
+	}
+	var Y *Int
+	if y != nil {
+		Y = new(Int)
+	}
+
+	D := new(Int).GCD(X, Y, a, b)
+	if D.Cmp(d) != 0 {
+		t.Errorf("GCD(%s, %s): got d = %s, want %s", a, b, D, d)
+	}
+	if x != nil && X.Cmp(x) != 0 {
+		t.Errorf("GCD(%s, %s): got x = %s, want %s", a, b, X, x)
+	}
+	if y != nil && Y.Cmp(y) != 0 {
+		t.Errorf("GCD(%s, %s): got y = %s, want %s", a, b, Y, y)
+	}
+
+	// binaryGCD requires a > 0 && b > 0
+	if a.Sign() <= 0 || b.Sign() <= 0 {
+		return
+	}
+
+	D.binaryGCD(a, b)
+	if D.Cmp(d) != 0 {
+		t.Errorf("binaryGcd(%s, %s): got d = %s, want %s", a, b, D, d)
+	}
+}
+
+func TestGcd(t *testing.T) {
+	for _, test := range gcdTests {
+		d, _ := new(Int).SetString(test.d, 0)
+		x, _ := new(Int).SetString(test.x, 0)
+		y, _ := new(Int).SetString(test.y, 0)
+		a, _ := new(Int).SetString(test.a, 0)
+		b, _ := new(Int).SetString(test.b, 0)
+
+		testGcd(t, d, nil, nil, a, b)
+		testGcd(t, d, x, nil, a, b)
+		testGcd(t, d, nil, y, a, b)
+		testGcd(t, d, x, y, a, b)
+	}
+
+	quick.Check(checkGcd, nil)
+}
+
+var primes = []string{
+	"2",
+	"3",
+	"5",
+	"7",
+	"11",
+
+	"13756265695458089029",
+	"13496181268022124907",
+	"10953742525620032441",
+	"17908251027575790097",
+
+	// http://code.google.com/p/go/issues/detail?id=638
+	"18699199384836356663",
+
+	"98920366548084643601728869055592650835572950932266967461790948584315647051443",
+	"94560208308847015747498523884063394671606671904944666360068158221458669711639",
+
+	// http://primes.utm.edu/lists/small/small3.html
+	"449417999055441493994709297093108513015373787049558499205492347871729927573118262811508386655998299074566974373711472560655026288668094291699357843464363003144674940345912431129144354948751003607115263071543163",
+	"230975859993204150666423538988557839555560243929065415434980904258310530753006723857139742334640122533598517597674807096648905501653461687601339782814316124971547968912893214002992086353183070342498989426570593",
+	"5521712099665906221540423207019333379125265462121169655563495403888449493493629943498064604536961775110765377745550377067893607246020694972959780839151452457728855382113555867743022746090187341871655890805971735385789993",
+	"203956878356401977405765866929034577280193993314348263094772646453283062722701277632936616063144088173312372882677123879538709400158306567338328279154499698366071906766440037074217117805690872792848149112022286332144876183376326512083574821647933992961249917319836219304274280243803104015000563790123",
+}
+
+var composites = []string{
+	"21284175091214687912771199898307297748211672914763848041968395774954376176754",
+	"6084766654921918907427900243509372380954290099172559290432744450051395395951",
+	"84594350493221918389213352992032324280367711247940675652888030554255915464401",
+	"82793403787388584738507275144194252681",
+}
+
+func TestProbablyPrime(t *testing.T) {
+	nreps := 20
+	if testing.Short() {
+		nreps = 1
+	}
+	for i, s := range primes {
+		p, _ := new(Int).SetString(s, 10)
+		if !p.ProbablyPrime(nreps) {
+			t.Errorf("#%d prime found to be non-prime (%s)", i, s)
+		}
+	}
+
+	for i, s := range composites {
+		c, _ := new(Int).SetString(s, 10)
+		if c.ProbablyPrime(nreps) {
+			t.Errorf("#%d composite found to be prime (%s)", i, s)
+		}
+		if testing.Short() {
+			break
+		}
+	}
+}
+
+type intShiftTest struct {
+	in    string
+	shift uint
+	out   string
+}
+
+var rshTests = []intShiftTest{
+	{"0", 0, "0"},
+	{"-0", 0, "0"},
+	{"0", 1, "0"},
+	{"0", 2, "0"},
+	{"1", 0, "1"},
+	{"1", 1, "0"},
+	{"1", 2, "0"},
+	{"2", 0, "2"},
+	{"2", 1, "1"},
+	{"-1", 0, "-1"},
+	{"-1", 1, "-1"},
+	{"-1", 10, "-1"},
+	{"-100", 2, "-25"},
+	{"-100", 3, "-13"},
+	{"-100", 100, "-1"},
+	{"4294967296", 0, "4294967296"},
+	{"4294967296", 1, "2147483648"},
+	{"4294967296", 2, "1073741824"},
+	{"18446744073709551616", 0, "18446744073709551616"},
+	{"18446744073709551616", 1, "9223372036854775808"},
+	{"18446744073709551616", 2, "4611686018427387904"},
+	{"18446744073709551616", 64, "1"},
+	{"340282366920938463463374607431768211456", 64, "18446744073709551616"},
+	{"340282366920938463463374607431768211456", 128, "1"},
+}
+
+func TestRsh(t *testing.T) {
+	for i, test := range rshTests {
+		in, _ := new(Int).SetString(test.in, 10)
+		expected, _ := new(Int).SetString(test.out, 10)
+		out := new(Int).Rsh(in, test.shift)
+
+		if !isNormalized(out) {
+			t.Errorf("#%d: %v is not normalized", i, *out)
+		}
+		if out.Cmp(expected) != 0 {
+			t.Errorf("#%d: got %s want %s", i, out, expected)
+		}
+	}
+}
+
+func TestRshSelf(t *testing.T) {
+	for i, test := range rshTests {
+		z, _ := new(Int).SetString(test.in, 10)
+		expected, _ := new(Int).SetString(test.out, 10)
+		z.Rsh(z, test.shift)
+
+		if !isNormalized(z) {
+			t.Errorf("#%d: %v is not normalized", i, *z)
+		}
+		if z.Cmp(expected) != 0 {
+			t.Errorf("#%d: got %s want %s", i, z, expected)
+		}
+	}
+}
+
+var lshTests = []intShiftTest{
+	{"0", 0, "0"},
+	{"0", 1, "0"},
+	{"0", 2, "0"},
+	{"1", 0, "1"},
+	{"1", 1, "2"},
+	{"1", 2, "4"},
+	{"2", 0, "2"},
+	{"2", 1, "4"},
+	{"2", 2, "8"},
+	{"-87", 1, "-174"},
+	{"4294967296", 0, "4294967296"},
+	{"4294967296", 1, "8589934592"},
+	{"4294967296", 2, "17179869184"},
+	{"18446744073709551616", 0, "18446744073709551616"},
+	{"9223372036854775808", 1, "18446744073709551616"},
+	{"4611686018427387904", 2, "18446744073709551616"},
+	{"1", 64, "18446744073709551616"},
+	{"18446744073709551616", 64, "340282366920938463463374607431768211456"},
+	{"1", 128, "340282366920938463463374607431768211456"},
+}
+
+func TestLsh(t *testing.T) {
+	for i, test := range lshTests {
+		in, _ := new(Int).SetString(test.in, 10)
+		expected, _ := new(Int).SetString(test.out, 10)
+		out := new(Int).Lsh(in, test.shift)
+
+		if !isNormalized(out) {
+			t.Errorf("#%d: %v is not normalized", i, *out)
+		}
+		if out.Cmp(expected) != 0 {
+			t.Errorf("#%d: got %s want %s", i, out, expected)
+		}
+	}
+}
+
+func TestLshSelf(t *testing.T) {
+	for i, test := range lshTests {
+		z, _ := new(Int).SetString(test.in, 10)
+		expected, _ := new(Int).SetString(test.out, 10)
+		z.Lsh(z, test.shift)
+
+		if !isNormalized(z) {
+			t.Errorf("#%d: %v is not normalized", i, *z)
+		}
+		if z.Cmp(expected) != 0 {
+			t.Errorf("#%d: got %s want %s", i, z, expected)
+		}
+	}
+}
+
+func TestLshRsh(t *testing.T) {
+	for i, test := range rshTests {
+		in, _ := new(Int).SetString(test.in, 10)
+		out := new(Int).Lsh(in, test.shift)
+		out = out.Rsh(out, test.shift)
+
+		if !isNormalized(out) {
+			t.Errorf("#%d: %v is not normalized", i, *out)
+		}
+		if in.Cmp(out) != 0 {
+			t.Errorf("#%d: got %s want %s", i, out, in)
+		}
+	}
+	for i, test := range lshTests {
+		in, _ := new(Int).SetString(test.in, 10)
+		out := new(Int).Lsh(in, test.shift)
+		out.Rsh(out, test.shift)
+
+		if !isNormalized(out) {
+			t.Errorf("#%d: %v is not normalized", i, *out)
+		}
+		if in.Cmp(out) != 0 {
+			t.Errorf("#%d: got %s want %s", i, out, in)
+		}
+	}
+}
+
+var int64Tests = []int64{
+	0,
+	1,
+	-1,
+	4294967295,
+	-4294967295,
+	4294967296,
+	-4294967296,
+	9223372036854775807,
+	-9223372036854775807,
+	-9223372036854775808,
+}
+
+func TestInt64(t *testing.T) {
+	for i, testVal := range int64Tests {
+		in := NewInt(testVal)
+		out := in.Int64()
+
+		if out != testVal {
+			t.Errorf("#%d got %d want %d", i, out, testVal)
+		}
+	}
+}
+
+var uint64Tests = []uint64{
+	0,
+	1,
+	4294967295,
+	4294967296,
+	8589934591,
+	8589934592,
+	9223372036854775807,
+	9223372036854775808,
+	18446744073709551615, // 1<<64 - 1
+}
+
+func TestUint64(t *testing.T) {
+	in := new(Int)
+	for i, testVal := range uint64Tests {
+		in.SetUint64(testVal)
+		out := in.Uint64()
+
+		if out != testVal {
+			t.Errorf("#%d got %d want %d", i, out, testVal)
+		}
+
+		str := fmt.Sprint(testVal)
+		strOut := in.String()
+		if strOut != str {
+			t.Errorf("#%d.String got %s want %s", i, strOut, str)
+		}
+	}
+}
+
+var bitwiseTests = []struct {
+	x, y                 string
+	and, or, xor, andNot string
+}{
+	{"0x00", "0x00", "0x00", "0x00", "0x00", "0x00"},
+	{"0x00", "0x01", "0x00", "0x01", "0x01", "0x00"},
+	{"0x01", "0x00", "0x00", "0x01", "0x01", "0x01"},
+	{"-0x01", "0x00", "0x00", "-0x01", "-0x01", "-0x01"},
+	{"-0xaf", "-0x50", "-0xf0", "-0x0f", "0xe1", "0x41"},
+	{"0x00", "-0x01", "0x00", "-0x01", "-0x01", "0x00"},
+	{"0x01", "0x01", "0x01", "0x01", "0x00", "0x00"},
+	{"-0x01", "-0x01", "-0x01", "-0x01", "0x00", "0x00"},
+	{"0x07", "0x08", "0x00", "0x0f", "0x0f", "0x07"},
+	{"0x05", "0x0f", "0x05", "0x0f", "0x0a", "0x00"},
+	{"0x013ff6", "0x9a4e", "0x1a46", "0x01bffe", "0x01a5b8", "0x0125b0"},
+	{"-0x013ff6", "0x9a4e", "0x800a", "-0x0125b2", "-0x01a5bc", "-0x01c000"},
+	{"-0x013ff6", "-0x9a4e", "-0x01bffe", "-0x1a46", "0x01a5b8", "0x8008"},
+	{
+		"0x1000009dc6e3d9822cba04129bcbe3401",
+		"0xb9bd7d543685789d57cb918e833af352559021483cdb05cc21fd",
+		"0x1000001186210100001000009048c2001",
+		"0xb9bd7d543685789d57cb918e8bfeff7fddb2ebe87dfbbdfe35fd",
+		"0xb9bd7d543685789d57ca918e8ae69d6fcdb2eae87df2b97215fc",
+		"0x8c40c2d8822caa04120b8321400",
+	},
+	{
+		"0x1000009dc6e3d9822cba04129bcbe3401",
+		"-0xb9bd7d543685789d57cb918e833af352559021483cdb05cc21fd",
+		"0x8c40c2d8822caa04120b8321401",
+		"-0xb9bd7d543685789d57ca918e82229142459020483cd2014001fd",
+		"-0xb9bd7d543685789d57ca918e8ae69d6fcdb2eae87df2b97215fe",
+		"0x1000001186210100001000009048c2000",
+	},
+	{
+		"-0x1000009dc6e3d9822cba04129bcbe3401",
+		"-0xb9bd7d543685789d57cb918e833af352559021483cdb05cc21fd",
+		"-0xb9bd7d543685789d57cb918e8bfeff7fddb2ebe87dfbbdfe35fd",
+		"-0x1000001186210100001000009048c2001",
+		"0xb9bd7d543685789d57ca918e8ae69d6fcdb2eae87df2b97215fc",
+		"0xb9bd7d543685789d57ca918e82229142459020483cd2014001fc",
+	},
+}
+
+type bitFun func(z, x, y *Int) *Int
+
+func testBitFun(t *testing.T, msg string, f bitFun, x, y *Int, exp string) {
+	expected := new(Int)
+	expected.SetString(exp, 0)
+
+	out := f(new(Int), x, y)
+	if out.Cmp(expected) != 0 {
+		t.Errorf("%s: got %s want %s", msg, out, expected)
+	}
+}
+
+func testBitFunSelf(t *testing.T, msg string, f bitFun, x, y *Int, exp string) {
+	self := new(Int)
+	self.Set(x)
+	expected := new(Int)
+	expected.SetString(exp, 0)
+
+	self = f(self, self, y)
+	if self.Cmp(expected) != 0 {
+		t.Errorf("%s: got %s want %s", msg, self, expected)
+	}
+}
+
+func altBit(x *Int, i int) uint {
+	z := new(Int).Rsh(x, uint(i))
+	z = z.And(z, NewInt(1))
+	if z.Cmp(new(Int)) != 0 {
+		return 1
+	}
+	return 0
+}
+
+func altSetBit(z *Int, x *Int, i int, b uint) *Int {
+	one := NewInt(1)
+	m := one.Lsh(one, uint(i))
+	switch b {
+	case 1:
+		return z.Or(x, m)
+	case 0:
+		return z.AndNot(x, m)
+	}
+	panic("set bit is not 0 or 1")
+}
+
+func testBitset(t *testing.T, x *Int) {
+	n := x.BitLen()
+	z := new(Int).Set(x)
+	z1 := new(Int).Set(x)
+	for i := 0; i < n+10; i++ {
+		old := z.Bit(i)
+		old1 := altBit(z1, i)
+		if old != old1 {
+			t.Errorf("bitset: inconsistent value for Bit(%s, %d), got %v want %v", z1, i, old, old1)
+		}
+		z := new(Int).SetBit(z, i, 1)
+		z1 := altSetBit(new(Int), z1, i, 1)
+		if z.Bit(i) == 0 {
+			t.Errorf("bitset: bit %d of %s got 0 want 1", i, x)
+		}
+		if z.Cmp(z1) != 0 {
+			t.Errorf("bitset: inconsistent value after SetBit 1, got %s want %s", z, z1)
+		}
+		z.SetBit(z, i, 0)
+		altSetBit(z1, z1, i, 0)
+		if z.Bit(i) != 0 {
+			t.Errorf("bitset: bit %d of %s got 1 want 0", i, x)
+		}
+		if z.Cmp(z1) != 0 {
+			t.Errorf("bitset: inconsistent value after SetBit 0, got %s want %s", z, z1)
+		}
+		altSetBit(z1, z1, i, old)
+		z.SetBit(z, i, old)
+		if z.Cmp(z1) != 0 {
+			t.Errorf("bitset: inconsistent value after SetBit old, got %s want %s", z, z1)
+		}
+	}
+	if z.Cmp(x) != 0 {
+		t.Errorf("bitset: got %s want %s", z, x)
+	}
+}
+
+var bitsetTests = []struct {
+	x string
+	i int
+	b uint
+}{
+	{"0", 0, 0},
+	{"0", 200, 0},
+	{"1", 0, 1},
+	{"1", 1, 0},
+	{"-1", 0, 1},
+	{"-1", 200, 1},
+	{"0x2000000000000000000000000000", 108, 0},
+	{"0x2000000000000000000000000000", 109, 1},
+	{"0x2000000000000000000000000000", 110, 0},
+	{"-0x2000000000000000000000000001", 108, 1},
+	{"-0x2000000000000000000000000001", 109, 0},
+	{"-0x2000000000000000000000000001", 110, 1},
+}
+
+func TestBitSet(t *testing.T) {
+	for _, test := range bitwiseTests {
+		x := new(Int)
+		x.SetString(test.x, 0)
+		testBitset(t, x)
+		x = new(Int)
+		x.SetString(test.y, 0)
+		testBitset(t, x)
+	}
+	for i, test := range bitsetTests {
+		x := new(Int)
+		x.SetString(test.x, 0)
+		b := x.Bit(test.i)
+		if b != test.b {
+			t.Errorf("#%d got %v want %v", i, b, test.b)
+		}
+	}
+	z := NewInt(1)
+	z.SetBit(NewInt(0), 2, 1)
+	if z.Cmp(NewInt(4)) != 0 {
+		t.Errorf("destination leaked into result; got %s want 4", z)
+	}
+}
+
+func BenchmarkBitset(b *testing.B) {
+	z := new(Int)
+	z.SetBit(z, 512, 1)
+	b.ResetTimer()
+	b.StartTimer()
+	for i := b.N - 1; i >= 0; i-- {
+		z.SetBit(z, i&512, 1)
+	}
+}
+
+func BenchmarkBitsetNeg(b *testing.B) {
+	z := NewInt(-1)
+	z.SetBit(z, 512, 0)
+	b.ResetTimer()
+	b.StartTimer()
+	for i := b.N - 1; i >= 0; i-- {
+		z.SetBit(z, i&512, 0)
+	}
+}
+
+func BenchmarkBitsetOrig(b *testing.B) {
+	z := new(Int)
+	altSetBit(z, z, 512, 1)
+	b.ResetTimer()
+	b.StartTimer()
+	for i := b.N - 1; i >= 0; i-- {
+		altSetBit(z, z, i&512, 1)
+	}
+}
+
+func BenchmarkBitsetNegOrig(b *testing.B) {
+	z := NewInt(-1)
+	altSetBit(z, z, 512, 0)
+	b.ResetTimer()
+	b.StartTimer()
+	for i := b.N - 1; i >= 0; i-- {
+		altSetBit(z, z, i&512, 0)
+	}
+}
+
+func TestBitwise(t *testing.T) {
+	x := new(Int)
+	y := new(Int)
+	for _, test := range bitwiseTests {
+		x.SetString(test.x, 0)
+		y.SetString(test.y, 0)
+
+		testBitFun(t, "and", (*Int).And, x, y, test.and)
+		testBitFunSelf(t, "and", (*Int).And, x, y, test.and)
+		testBitFun(t, "andNot", (*Int).AndNot, x, y, test.andNot)
+		testBitFunSelf(t, "andNot", (*Int).AndNot, x, y, test.andNot)
+		testBitFun(t, "or", (*Int).Or, x, y, test.or)
+		testBitFunSelf(t, "or", (*Int).Or, x, y, test.or)
+		testBitFun(t, "xor", (*Int).Xor, x, y, test.xor)
+		testBitFunSelf(t, "xor", (*Int).Xor, x, y, test.xor)
+	}
+}
+
+var notTests = []struct {
+	in  string
+	out string
+}{
+	{"0", "-1"},
+	{"1", "-2"},
+	{"7", "-8"},
+	{"0", "-1"},
+	{"-81910", "81909"},
+	{
+		"298472983472983471903246121093472394872319615612417471234712061",
+		"-298472983472983471903246121093472394872319615612417471234712062",
+	},
+}
+
+func TestNot(t *testing.T) {
+	in := new(Int)
+	out := new(Int)
+	expected := new(Int)
+	for i, test := range notTests {
+		in.SetString(test.in, 10)
+		expected.SetString(test.out, 10)
+		out = out.Not(in)
+		if out.Cmp(expected) != 0 {
+			t.Errorf("#%d: got %s want %s", i, out, expected)
+		}
+		out = out.Not(out)
+		if out.Cmp(in) != 0 {
+			t.Errorf("#%d: got %s want %s", i, out, in)
+		}
+	}
+}
+
+var modInverseTests = []struct {
+	element string
+	modulus string
+}{
+	{"1234567", "458948883992"},
+	{"239487239847", "2410312426921032588552076022197566074856950548502459942654116941958108831682612228890093858261341614673227141477904012196503648957050582631942730706805009223062734745341073406696246014589361659774041027169249453200378729434170325843778659198143763193776859869524088940195577346119843545301547043747207749969763750084308926339295559968882457872412993810129130294592999947926365264059284647209730384947211681434464714438488520940127459844288859336526896320919633919"},
+}
+
+func TestModInverse(t *testing.T) {
+	var element, modulus, gcd, inverse Int
+	one := NewInt(1)
+	for i, test := range modInverseTests {
+		(&element).SetString(test.element, 10)
+		(&modulus).SetString(test.modulus, 10)
+		(&inverse).ModInverse(&element, &modulus)
+		(&inverse).Mul(&inverse, &element)
+		(&inverse).Mod(&inverse, &modulus)
+		if (&inverse).Cmp(one) != 0 {
+			t.Errorf("#%d: failed (e·e^(-1)=%s)", i, &inverse)
+		}
+	}
+	// exhaustive test for small values
+	for n := 2; n < 100; n++ {
+		(&modulus).SetInt64(int64(n))
+		for x := 1; x < n; x++ {
+			(&element).SetInt64(int64(x))
+			(&gcd).GCD(nil, nil, &element, &modulus)
+			if (&gcd).Cmp(one) != 0 {
+				continue
+			}
+			(&inverse).ModInverse(&element, &modulus)
+			(&inverse).Mul(&inverse, &element)
+			(&inverse).Mod(&inverse, &modulus)
+			if (&inverse).Cmp(one) != 0 {
+				t.Errorf("ModInverse(%d,%d)*%d%%%d=%d, not 1", &element, &modulus, &element, &modulus, &inverse)
+			}
+		}
+	}
+}
+
+var encodingTests = []string{
+	"-539345864568634858364538753846587364875430589374589",
+	"-678645873",
+	"-100",
+	"-2",
+	"-1",
+	"0",
+	"1",
+	"2",
+	"10",
+	"42",
+	"1234567890",
+	"298472983472983471903246121093472394872319615612417471234712061",
+}
+
+func TestIntGobEncoding(t *testing.T) {
+	var medium bytes.Buffer
+	enc := gob.NewEncoder(&medium)
+	dec := gob.NewDecoder(&medium)
+	for _, test := range encodingTests {
+		medium.Reset() // empty buffer for each test case (in case of failures)
+		var tx Int
+		tx.SetString(test, 10)
+		if err := enc.Encode(&tx); err != nil {
+			t.Errorf("encoding of %s failed: %s", &tx, err)
+		}
+		var rx Int
+		if err := dec.Decode(&rx); err != nil {
+			t.Errorf("decoding of %s failed: %s", &tx, err)
+		}
+		if rx.Cmp(&tx) != 0 {
+			t.Errorf("transmission of %s failed: got %s want %s", &tx, &rx, &tx)
+		}
+	}
+}
+
+// Sending a nil Int pointer (inside a slice) on a round trip through gob should yield a zero.
+// TODO: top-level nils.
+func TestGobEncodingNilIntInSlice(t *testing.T) {
+	buf := new(bytes.Buffer)
+	enc := gob.NewEncoder(buf)
+	dec := gob.NewDecoder(buf)
+
+	var in = make([]*Int, 1)
+	err := enc.Encode(&in)
+	if err != nil {
+		t.Errorf("gob encode failed: %q", err)
+	}
+	var out []*Int
+	err = dec.Decode(&out)
+	if err != nil {
+		t.Fatalf("gob decode failed: %q", err)
+	}
+	if len(out) != 1 {
+		t.Fatalf("wrong len; want 1 got %d", len(out))
+	}
+	var zero Int
+	if out[0].Cmp(&zero) != 0 {
+		t.Errorf("transmission of (*Int)(nill) failed: got %s want 0", out)
+	}
+}
+
+func TestIntJSONEncoding(t *testing.T) {
+	for _, test := range encodingTests {
+		var tx Int
+		tx.SetString(test, 10)
+		b, err := json.Marshal(&tx)
+		if err != nil {
+			t.Errorf("marshaling of %s failed: %s", &tx, err)
+		}
+		var rx Int
+		if err := json.Unmarshal(b, &rx); err != nil {
+			t.Errorf("unmarshaling of %s failed: %s", &tx, err)
+		}
+		if rx.Cmp(&tx) != 0 {
+			t.Errorf("JSON encoding of %s failed: got %s want %s", &tx, &rx, &tx)
+		}
+	}
+}
+
+var intVals = []string{
+	"-141592653589793238462643383279502884197169399375105820974944592307816406286",
+	"-1415926535897932384626433832795028841971",
+	"-141592653589793",
+	"-1",
+	"0",
+	"1",
+	"141592653589793",
+	"1415926535897932384626433832795028841971",
+	"141592653589793238462643383279502884197169399375105820974944592307816406286",
+}
+
+func TestIntJSONEncodingTextMarshaller(t *testing.T) {
+	for _, num := range intVals {
+		var tx Int
+		tx.SetString(num, 0)
+		b, err := json.Marshal(&tx)
+		if err != nil {
+			t.Errorf("marshaling of %s failed: %s", &tx, err)
+			continue
+		}
+		var rx Int
+		if err := json.Unmarshal(b, &rx); err != nil {
+			t.Errorf("unmarshaling of %s failed: %s", &tx, err)
+			continue
+		}
+		if rx.Cmp(&tx) != 0 {
+			t.Errorf("JSON encoding of %s failed: got %s want %s", &tx, &rx, &tx)
+		}
+	}
+}
+
+func TestIntXMLEncodingTextMarshaller(t *testing.T) {
+	for _, num := range intVals {
+		var tx Int
+		tx.SetString(num, 0)
+		b, err := xml.Marshal(&tx)
+		if err != nil {
+			t.Errorf("marshaling of %s failed: %s", &tx, err)
+			continue
+		}
+		var rx Int
+		if err := xml.Unmarshal(b, &rx); err != nil {
+			t.Errorf("unmarshaling of %s failed: %s", &tx, err)
+			continue
+		}
+		if rx.Cmp(&tx) != 0 {
+			t.Errorf("XML encoding of %s failed: got %s want %s", &tx, &rx, &tx)
+		}
+	}
+}
+
+func TestIssue2607(t *testing.T) {
+	// This code sequence used to hang.
+	n := NewInt(10)
+	n.Rand(rand.New(rand.NewSource(9)), n)
+}
diff --git a/src/pkg/math/big/nat.go b/src/math/big/nat.go
similarity index 100%
rename from src/pkg/math/big/nat.go
rename to src/math/big/nat.go
diff --git a/src/pkg/math/big/nat_test.go b/src/math/big/nat_test.go
similarity index 100%
rename from src/pkg/math/big/nat_test.go
rename to src/math/big/nat_test.go
diff --git a/src/math/big/rat.go b/src/math/big/rat.go
new file mode 100644
index 0000000..c5339fe
--- /dev/null
+++ b/src/math/big/rat.go
@@ -0,0 +1,716 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file implements multi-precision rational numbers.
+
+package big
+
+import (
+	"encoding/binary"
+	"errors"
+	"fmt"
+	"math"
+	"strings"
+)
+
+// A Rat represents a quotient a/b of arbitrary precision.
+// The zero value for a Rat represents the value 0.
+type Rat struct {
+	// To make zero values for Rat work w/o initialization,
+	// a zero value of b (len(b) == 0) acts like b == 1.
+	// a.neg determines the sign of the Rat, b.neg is ignored.
+	a, b Int
+}
+
+// NewRat creates a new Rat with numerator a and denominator b.
+func NewRat(a, b int64) *Rat {
+	return new(Rat).SetFrac64(a, b)
+}
+
+// SetFloat64 sets z to exactly f and returns z.
+// If f is not finite, SetFloat returns nil.
+func (z *Rat) SetFloat64(f float64) *Rat {
+	const expMask = 1<<11 - 1
+	bits := math.Float64bits(f)
+	mantissa := bits & (1<<52 - 1)
+	exp := int((bits >> 52) & expMask)
+	switch exp {
+	case expMask: // non-finite
+		return nil
+	case 0: // denormal
+		exp -= 1022
+	default: // normal
+		mantissa |= 1 << 52
+		exp -= 1023
+	}
+
+	shift := 52 - exp
+
+	// Optimization (?): partially pre-normalise.
+	for mantissa&1 == 0 && shift > 0 {
+		mantissa >>= 1
+		shift--
+	}
+
+	z.a.SetUint64(mantissa)
+	z.a.neg = f < 0
+	z.b.Set(intOne)
+	if shift > 0 {
+		z.b.Lsh(&z.b, uint(shift))
+	} else {
+		z.a.Lsh(&z.a, uint(-shift))
+	}
+	return z.norm()
+}
+
+// quotToFloat32 returns the non-negative float32 value
+// nearest to the quotient a/b, using round-to-even in
+// halfway cases.  It does not mutate its arguments.
+// Preconditions: b is non-zero; a and b have no common factors.
+func quotToFloat32(a, b nat) (f float32, exact bool) {
+	const (
+		// float size in bits
+		Fsize = 32
+
+		// mantissa
+		Msize  = 23
+		Msize1 = Msize + 1 // incl. implicit 1
+		Msize2 = Msize1 + 1
+
+		// exponent
+		Esize = Fsize - Msize1
+		Ebias = 1<<(Esize-1) - 1
+		Emin  = 1 - Ebias
+		Emax  = Ebias
+	)
+
+	// TODO(adonovan): specialize common degenerate cases: 1.0, integers.
+	alen := a.bitLen()
+	if alen == 0 {
+		return 0, true
+	}
+	blen := b.bitLen()
+	if blen == 0 {
+		panic("division by zero")
+	}
+
+	// 1. Left-shift A or B such that quotient A/B is in [1<<Msize1, 1<<(Msize2+1)
+	// (Msize2 bits if A < B when they are left-aligned, Msize2+1 bits if A >= B).
+	// This is 2 or 3 more than the float32 mantissa field width of Msize:
+	// - the optional extra bit is shifted away in step 3 below.
+	// - the high-order 1 is omitted in "normal" representation;
+	// - the low-order 1 will be used during rounding then discarded.
+	exp := alen - blen
+	var a2, b2 nat
+	a2 = a2.set(a)
+	b2 = b2.set(b)
+	if shift := Msize2 - exp; shift > 0 {
+		a2 = a2.shl(a2, uint(shift))
+	} else if shift < 0 {
+		b2 = b2.shl(b2, uint(-shift))
+	}
+
+	// 2. Compute quotient and remainder (q, r).  NB: due to the
+	// extra shift, the low-order bit of q is logically the
+	// high-order bit of r.
+	var q nat
+	q, r := q.div(a2, a2, b2) // (recycle a2)
+	mantissa := low32(q)
+	haveRem := len(r) > 0 // mantissa&1 && !haveRem => remainder is exactly half
+
+	// 3. If quotient didn't fit in Msize2 bits, redo division by b2<<1
+	// (in effect---we accomplish this incrementally).
+	if mantissa>>Msize2 == 1 {
+		if mantissa&1 == 1 {
+			haveRem = true
+		}
+		mantissa >>= 1
+		exp++
+	}
+	if mantissa>>Msize1 != 1 {
+		panic(fmt.Sprintf("expected exactly %d bits of result", Msize2))
+	}
+
+	// 4. Rounding.
+	if Emin-Msize <= exp && exp <= Emin {
+		// Denormal case; lose 'shift' bits of precision.
+		shift := uint(Emin - (exp - 1)) // [1..Esize1)
+		lostbits := mantissa & (1<<shift - 1)
+		haveRem = haveRem || lostbits != 0
+		mantissa >>= shift
+		exp = 2 - Ebias // == exp + shift
+	}
+	// Round q using round-half-to-even.
+	exact = !haveRem
+	if mantissa&1 != 0 {
+		exact = false
+		if haveRem || mantissa&2 != 0 {
+			if mantissa++; mantissa >= 1<<Msize2 {
+				// Complete rollover 11...1 => 100...0, so shift is safe
+				mantissa >>= 1
+				exp++
+			}
+		}
+	}
+	mantissa >>= 1 // discard rounding bit.  Mantissa now scaled by 1<<Msize1.
+
+	f = float32(math.Ldexp(float64(mantissa), exp-Msize1))
+	if math.IsInf(float64(f), 0) {
+		exact = false
+	}
+	return
+}
+
+// quotToFloat64 returns the non-negative float64 value
+// nearest to the quotient a/b, using round-to-even in
+// halfway cases.  It does not mutate its arguments.
+// Preconditions: b is non-zero; a and b have no common factors.
+func quotToFloat64(a, b nat) (f float64, exact bool) {
+	const (
+		// float size in bits
+		Fsize = 64
+
+		// mantissa
+		Msize  = 52
+		Msize1 = Msize + 1 // incl. implicit 1
+		Msize2 = Msize1 + 1
+
+		// exponent
+		Esize = Fsize - Msize1
+		Ebias = 1<<(Esize-1) - 1
+		Emin  = 1 - Ebias
+		Emax  = Ebias
+	)
+
+	// TODO(adonovan): specialize common degenerate cases: 1.0, integers.
+	alen := a.bitLen()
+	if alen == 0 {
+		return 0, true
+	}
+	blen := b.bitLen()
+	if blen == 0 {
+		panic("division by zero")
+	}
+
+	// 1. Left-shift A or B such that quotient A/B is in [1<<Msize1, 1<<(Msize2+1)
+	// (Msize2 bits if A < B when they are left-aligned, Msize2+1 bits if A >= B).
+	// This is 2 or 3 more than the float64 mantissa field width of Msize:
+	// - the optional extra bit is shifted away in step 3 below.
+	// - the high-order 1 is omitted in "normal" representation;
+	// - the low-order 1 will be used during rounding then discarded.
+	exp := alen - blen
+	var a2, b2 nat
+	a2 = a2.set(a)
+	b2 = b2.set(b)
+	if shift := Msize2 - exp; shift > 0 {
+		a2 = a2.shl(a2, uint(shift))
+	} else if shift < 0 {
+		b2 = b2.shl(b2, uint(-shift))
+	}
+
+	// 2. Compute quotient and remainder (q, r).  NB: due to the
+	// extra shift, the low-order bit of q is logically the
+	// high-order bit of r.
+	var q nat
+	q, r := q.div(a2, a2, b2) // (recycle a2)
+	mantissa := low64(q)
+	haveRem := len(r) > 0 // mantissa&1 && !haveRem => remainder is exactly half
+
+	// 3. If quotient didn't fit in Msize2 bits, redo division by b2<<1
+	// (in effect---we accomplish this incrementally).
+	if mantissa>>Msize2 == 1 {
+		if mantissa&1 == 1 {
+			haveRem = true
+		}
+		mantissa >>= 1
+		exp++
+	}
+	if mantissa>>Msize1 != 1 {
+		panic(fmt.Sprintf("expected exactly %d bits of result", Msize2))
+	}
+
+	// 4. Rounding.
+	if Emin-Msize <= exp && exp <= Emin {
+		// Denormal case; lose 'shift' bits of precision.
+		shift := uint(Emin - (exp - 1)) // [1..Esize1)
+		lostbits := mantissa & (1<<shift - 1)
+		haveRem = haveRem || lostbits != 0
+		mantissa >>= shift
+		exp = 2 - Ebias // == exp + shift
+	}
+	// Round q using round-half-to-even.
+	exact = !haveRem
+	if mantissa&1 != 0 {
+		exact = false
+		if haveRem || mantissa&2 != 0 {
+			if mantissa++; mantissa >= 1<<Msize2 {
+				// Complete rollover 11...1 => 100...0, so shift is safe
+				mantissa >>= 1
+				exp++
+			}
+		}
+	}
+	mantissa >>= 1 // discard rounding bit.  Mantissa now scaled by 1<<Msize1.
+
+	f = math.Ldexp(float64(mantissa), exp-Msize1)
+	if math.IsInf(f, 0) {
+		exact = false
+	}
+	return
+}
+
+// Float32 returns the nearest float32 value for x and a bool indicating
+// whether f represents x exactly. If the magnitude of x is too large to
+// be represented by a float32, f is an infinity and exact is false.
+// The sign of f always matches the sign of x, even if f == 0.
+func (x *Rat) Float32() (f float32, exact bool) {
+	b := x.b.abs
+	if len(b) == 0 {
+		b = b.set(natOne) // materialize denominator
+	}
+	f, exact = quotToFloat32(x.a.abs, b)
+	if x.a.neg {
+		f = -f
+	}
+	return
+}
+
+// Float64 returns the nearest float64 value for x and a bool indicating
+// whether f represents x exactly. If the magnitude of x is too large to
+// be represented by a float64, f is an infinity and exact is false.
+// The sign of f always matches the sign of x, even if f == 0.
+func (x *Rat) Float64() (f float64, exact bool) {
+	b := x.b.abs
+	if len(b) == 0 {
+		b = b.set(natOne) // materialize denominator
+	}
+	f, exact = quotToFloat64(x.a.abs, b)
+	if x.a.neg {
+		f = -f
+	}
+	return
+}
+
+// SetFrac sets z to a/b and returns z.
+func (z *Rat) SetFrac(a, b *Int) *Rat {
+	z.a.neg = a.neg != b.neg
+	babs := b.abs
+	if len(babs) == 0 {
+		panic("division by zero")
+	}
+	if &z.a == b || alias(z.a.abs, babs) {
+		babs = nat(nil).set(babs) // make a copy
+	}
+	z.a.abs = z.a.abs.set(a.abs)
+	z.b.abs = z.b.abs.set(babs)
+	return z.norm()
+}
+
+// SetFrac64 sets z to a/b and returns z.
+func (z *Rat) SetFrac64(a, b int64) *Rat {
+	z.a.SetInt64(a)
+	if b == 0 {
+		panic("division by zero")
+	}
+	if b < 0 {
+		b = -b
+		z.a.neg = !z.a.neg
+	}
+	z.b.abs = z.b.abs.setUint64(uint64(b))
+	return z.norm()
+}
+
+// SetInt sets z to x (by making a copy of x) and returns z.
+func (z *Rat) SetInt(x *Int) *Rat {
+	z.a.Set(x)
+	z.b.abs = z.b.abs.make(0)
+	return z
+}
+
+// SetInt64 sets z to x and returns z.
+func (z *Rat) SetInt64(x int64) *Rat {
+	z.a.SetInt64(x)
+	z.b.abs = z.b.abs.make(0)
+	return z
+}
+
+// Set sets z to x (by making a copy of x) and returns z.
+func (z *Rat) Set(x *Rat) *Rat {
+	if z != x {
+		z.a.Set(&x.a)
+		z.b.Set(&x.b)
+	}
+	return z
+}
+
+// Abs sets z to |x| (the absolute value of x) and returns z.
+func (z *Rat) Abs(x *Rat) *Rat {
+	z.Set(x)
+	z.a.neg = false
+	return z
+}
+
+// Neg sets z to -x and returns z.
+func (z *Rat) Neg(x *Rat) *Rat {
+	z.Set(x)
+	z.a.neg = len(z.a.abs) > 0 && !z.a.neg // 0 has no sign
+	return z
+}
+
+// Inv sets z to 1/x and returns z.
+func (z *Rat) Inv(x *Rat) *Rat {
+	if len(x.a.abs) == 0 {
+		panic("division by zero")
+	}
+	z.Set(x)
+	a := z.b.abs
+	if len(a) == 0 {
+		a = a.set(natOne) // materialize numerator
+	}
+	b := z.a.abs
+	if b.cmp(natOne) == 0 {
+		b = b.make(0) // normalize denominator
+	}
+	z.a.abs, z.b.abs = a, b // sign doesn't change
+	return z
+}
+
+// Sign returns:
+//
+//	-1 if x <  0
+//	 0 if x == 0
+//	+1 if x >  0
+//
+func (x *Rat) Sign() int {
+	return x.a.Sign()
+}
+
+// IsInt returns true if the denominator of x is 1.
+func (x *Rat) IsInt() bool {
+	return len(x.b.abs) == 0 || x.b.abs.cmp(natOne) == 0
+}
+
+// Num returns the numerator of x; it may be <= 0.
+// The result is a reference to x's numerator; it
+// may change if a new value is assigned to x, and vice versa.
+// The sign of the numerator corresponds to the sign of x.
+func (x *Rat) Num() *Int {
+	return &x.a
+}
+
+// Denom returns the denominator of x; it is always > 0.
+// The result is a reference to x's denominator; it
+// may change if a new value is assigned to x, and vice versa.
+func (x *Rat) Denom() *Int {
+	x.b.neg = false // the result is always >= 0
+	if len(x.b.abs) == 0 {
+		x.b.abs = x.b.abs.set(natOne) // materialize denominator
+	}
+	return &x.b
+}
+
+func (z *Rat) norm() *Rat {
+	switch {
+	case len(z.a.abs) == 0:
+		// z == 0 - normalize sign and denominator
+		z.a.neg = false
+		z.b.abs = z.b.abs.make(0)
+	case len(z.b.abs) == 0:
+		// z is normalized int - nothing to do
+	case z.b.abs.cmp(natOne) == 0:
+		// z is int - normalize denominator
+		z.b.abs = z.b.abs.make(0)
+	default:
+		neg := z.a.neg
+		z.a.neg = false
+		z.b.neg = false
+		if f := NewInt(0).binaryGCD(&z.a, &z.b); f.Cmp(intOne) != 0 {
+			z.a.abs, _ = z.a.abs.div(nil, z.a.abs, f.abs)
+			z.b.abs, _ = z.b.abs.div(nil, z.b.abs, f.abs)
+			if z.b.abs.cmp(natOne) == 0 {
+				// z is int - normalize denominator
+				z.b.abs = z.b.abs.make(0)
+			}
+		}
+		z.a.neg = neg
+	}
+	return z
+}
+
+// mulDenom sets z to the denominator product x*y (by taking into
+// account that 0 values for x or y must be interpreted as 1) and
+// returns z.
+func mulDenom(z, x, y nat) nat {
+	switch {
+	case len(x) == 0:
+		return z.set(y)
+	case len(y) == 0:
+		return z.set(x)
+	}
+	return z.mul(x, y)
+}
+
+// scaleDenom computes x*f.
+// If f == 0 (zero value of denominator), the result is (a copy of) x.
+func scaleDenom(x *Int, f nat) *Int {
+	var z Int
+	if len(f) == 0 {
+		return z.Set(x)
+	}
+	z.abs = z.abs.mul(x.abs, f)
+	z.neg = x.neg
+	return &z
+}
+
+// Cmp compares x and y and returns:
+//
+//   -1 if x <  y
+//    0 if x == y
+//   +1 if x >  y
+//
+func (x *Rat) Cmp(y *Rat) int {
+	return scaleDenom(&x.a, y.b.abs).Cmp(scaleDenom(&y.a, x.b.abs))
+}
+
+// Add sets z to the sum x+y and returns z.
+func (z *Rat) Add(x, y *Rat) *Rat {
+	a1 := scaleDenom(&x.a, y.b.abs)
+	a2 := scaleDenom(&y.a, x.b.abs)
+	z.a.Add(a1, a2)
+	z.b.abs = mulDenom(z.b.abs, x.b.abs, y.b.abs)
+	return z.norm()
+}
+
+// Sub sets z to the difference x-y and returns z.
+func (z *Rat) Sub(x, y *Rat) *Rat {
+	a1 := scaleDenom(&x.a, y.b.abs)
+	a2 := scaleDenom(&y.a, x.b.abs)
+	z.a.Sub(a1, a2)
+	z.b.abs = mulDenom(z.b.abs, x.b.abs, y.b.abs)
+	return z.norm()
+}
+
+// Mul sets z to the product x*y and returns z.
+func (z *Rat) Mul(x, y *Rat) *Rat {
+	z.a.Mul(&x.a, &y.a)
+	z.b.abs = mulDenom(z.b.abs, x.b.abs, y.b.abs)
+	return z.norm()
+}
+
+// Quo sets z to the quotient x/y and returns z.
+// If y == 0, a division-by-zero run-time panic occurs.
+func (z *Rat) Quo(x, y *Rat) *Rat {
+	if len(y.a.abs) == 0 {
+		panic("division by zero")
+	}
+	a := scaleDenom(&x.a, y.b.abs)
+	b := scaleDenom(&y.a, x.b.abs)
+	z.a.abs = a.abs
+	z.b.abs = b.abs
+	z.a.neg = a.neg != b.neg
+	return z.norm()
+}
+
+func ratTok(ch rune) bool {
+	return strings.IndexRune("+-/0123456789.eE", ch) >= 0
+}
+
+// Scan is a support routine for fmt.Scanner. It accepts the formats
+// 'e', 'E', 'f', 'F', 'g', 'G', and 'v'. All formats are equivalent.
+func (z *Rat) Scan(s fmt.ScanState, ch rune) error {
+	tok, err := s.Token(true, ratTok)
+	if err != nil {
+		return err
+	}
+	if strings.IndexRune("efgEFGv", ch) < 0 {
+		return errors.New("Rat.Scan: invalid verb")
+	}
+	if _, ok := z.SetString(string(tok)); !ok {
+		return errors.New("Rat.Scan: invalid syntax")
+	}
+	return nil
+}
+
+// SetString sets z to the value of s and returns z and a boolean indicating
+// success. s can be given as a fraction "a/b" or as a floating-point number
+// optionally followed by an exponent. If the operation failed, the value of
+// z is undefined but the returned value is nil.
+func (z *Rat) SetString(s string) (*Rat, bool) {
+	if len(s) == 0 {
+		return nil, false
+	}
+
+	// check for a quotient
+	sep := strings.Index(s, "/")
+	if sep >= 0 {
+		if _, ok := z.a.SetString(s[0:sep], 10); !ok {
+			return nil, false
+		}
+		s = s[sep+1:]
+		var err error
+		if z.b.abs, _, err = z.b.abs.scan(strings.NewReader(s), 10); err != nil {
+			return nil, false
+		}
+		if len(z.b.abs) == 0 {
+			return nil, false
+		}
+		return z.norm(), true
+	}
+
+	// check for a decimal point
+	sep = strings.Index(s, ".")
+	// check for an exponent
+	e := strings.IndexAny(s, "eE")
+	var exp Int
+	if e >= 0 {
+		if e < sep {
+			// The E must come after the decimal point.
+			return nil, false
+		}
+		if _, ok := exp.SetString(s[e+1:], 10); !ok {
+			return nil, false
+		}
+		s = s[0:e]
+	}
+	if sep >= 0 {
+		s = s[0:sep] + s[sep+1:]
+		exp.Sub(&exp, NewInt(int64(len(s)-sep)))
+	}
+
+	if _, ok := z.a.SetString(s, 10); !ok {
+		return nil, false
+	}
+	powTen := nat(nil).expNN(natTen, exp.abs, nil)
+	if exp.neg {
+		z.b.abs = powTen
+		z.norm()
+	} else {
+		z.a.abs = z.a.abs.mul(z.a.abs, powTen)
+		z.b.abs = z.b.abs.make(0)
+	}
+
+	return z, true
+}
+
+// String returns a string representation of x in the form "a/b" (even if b == 1).
+func (x *Rat) String() string {
+	s := "/1"
+	if len(x.b.abs) != 0 {
+		s = "/" + x.b.abs.decimalString()
+	}
+	return x.a.String() + s
+}
+
+// RatString returns a string representation of x in the form "a/b" if b != 1,
+// and in the form "a" if b == 1.
+func (x *Rat) RatString() string {
+	if x.IsInt() {
+		return x.a.String()
+	}
+	return x.String()
+}
+
+// FloatString returns a string representation of x in decimal form with prec
+// digits of precision after the decimal point and the last digit rounded.
+func (x *Rat) FloatString(prec int) string {
+	if x.IsInt() {
+		s := x.a.String()
+		if prec > 0 {
+			s += "." + strings.Repeat("0", prec)
+		}
+		return s
+	}
+	// x.b.abs != 0
+
+	q, r := nat(nil).div(nat(nil), x.a.abs, x.b.abs)
+
+	p := natOne
+	if prec > 0 {
+		p = nat(nil).expNN(natTen, nat(nil).setUint64(uint64(prec)), nil)
+	}
+
+	r = r.mul(r, p)
+	r, r2 := r.div(nat(nil), r, x.b.abs)
+
+	// see if we need to round up
+	r2 = r2.add(r2, r2)
+	if x.b.abs.cmp(r2) <= 0 {
+		r = r.add(r, natOne)
+		if r.cmp(p) >= 0 {
+			q = nat(nil).add(q, natOne)
+			r = nat(nil).sub(r, p)
+		}
+	}
+
+	s := q.decimalString()
+	if x.a.neg {
+		s = "-" + s
+	}
+
+	if prec > 0 {
+		rs := r.decimalString()
+		leadingZeros := prec - len(rs)
+		s += "." + strings.Repeat("0", leadingZeros) + rs
+	}
+
+	return s
+}
+
+// Gob codec version. Permits backward-compatible changes to the encoding.
+const ratGobVersion byte = 1
+
+// GobEncode implements the gob.GobEncoder interface.
+func (x *Rat) GobEncode() ([]byte, error) {
+	if x == nil {
+		return nil, nil
+	}
+	buf := make([]byte, 1+4+(len(x.a.abs)+len(x.b.abs))*_S) // extra bytes for version and sign bit (1), and numerator length (4)
+	i := x.b.abs.bytes(buf)
+	j := x.a.abs.bytes(buf[0:i])
+	n := i - j
+	if int(uint32(n)) != n {
+		// this should never happen
+		return nil, errors.New("Rat.GobEncode: numerator too large")
+	}
+	binary.BigEndian.PutUint32(buf[j-4:j], uint32(n))
+	j -= 1 + 4
+	b := ratGobVersion << 1 // make space for sign bit
+	if x.a.neg {
+		b |= 1
+	}
+	buf[j] = b
+	return buf[j:], nil
+}
+
+// GobDecode implements the gob.GobDecoder interface.
+func (z *Rat) GobDecode(buf []byte) error {
+	if len(buf) == 0 {
+		// Other side sent a nil or default value.
+		*z = Rat{}
+		return nil
+	}
+	b := buf[0]
+	if b>>1 != ratGobVersion {
+		return errors.New(fmt.Sprintf("Rat.GobDecode: encoding version %d not supported", b>>1))
+	}
+	const j = 1 + 4
+	i := j + binary.BigEndian.Uint32(buf[j-4:j])
+	z.a.neg = b&1 != 0
+	z.a.abs = z.a.abs.setBytes(buf[j:i])
+	z.b.abs = z.b.abs.setBytes(buf[i:])
+	return nil
+}
+
+// MarshalText implements the encoding.TextMarshaler interface.
+func (r *Rat) MarshalText() (text []byte, err error) {
+	return []byte(r.RatString()), nil
+}
+
+// UnmarshalText implements the encoding.TextUnmarshaler interface.
+func (r *Rat) UnmarshalText(text []byte) error {
+	if _, ok := r.SetString(string(text)); !ok {
+		return fmt.Errorf("math/big: cannot unmarshal %q into a *big.Rat", text)
+	}
+	return nil
+}
diff --git a/src/math/big/rat_test.go b/src/math/big/rat_test.go
new file mode 100644
index 0000000..5dbbb35
--- /dev/null
+++ b/src/math/big/rat_test.go
@@ -0,0 +1,1160 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package big
+
+import (
+	"bytes"
+	"encoding/gob"
+	"encoding/json"
+	"encoding/xml"
+	"fmt"
+	"math"
+	"strconv"
+	"strings"
+	"testing"
+)
+
+func TestZeroRat(t *testing.T) {
+	var x, y, z Rat
+	y.SetFrac64(0, 42)
+
+	if x.Cmp(&y) != 0 {
+		t.Errorf("x and y should be both equal and zero")
+	}
+
+	if s := x.String(); s != "0/1" {
+		t.Errorf("got x = %s, want 0/1", s)
+	}
+
+	if s := x.RatString(); s != "0" {
+		t.Errorf("got x = %s, want 0", s)
+	}
+
+	z.Add(&x, &y)
+	if s := z.RatString(); s != "0" {
+		t.Errorf("got x+y = %s, want 0", s)
+	}
+
+	z.Sub(&x, &y)
+	if s := z.RatString(); s != "0" {
+		t.Errorf("got x-y = %s, want 0", s)
+	}
+
+	z.Mul(&x, &y)
+	if s := z.RatString(); s != "0" {
+		t.Errorf("got x*y = %s, want 0", s)
+	}
+
+	// check for division by zero
+	defer func() {
+		if s := recover(); s == nil || s.(string) != "division by zero" {
+			panic(s)
+		}
+	}()
+	z.Quo(&x, &y)
+}
+
+var setStringTests = []struct {
+	in, out string
+	ok      bool
+}{
+	{"0", "0", true},
+	{"-0", "0", true},
+	{"1", "1", true},
+	{"-1", "-1", true},
+	{"1.", "1", true},
+	{"1e0", "1", true},
+	{"1.e1", "10", true},
+	{in: "1e", ok: false},
+	{in: "1.e", ok: false},
+	{in: "1e+14e-5", ok: false},
+	{in: "1e4.5", ok: false},
+	{in: "r", ok: false},
+	{in: "a/b", ok: false},
+	{in: "a.b", ok: false},
+	{"-0.1", "-1/10", true},
+	{"-.1", "-1/10", true},
+	{"2/4", "1/2", true},
+	{".25", "1/4", true},
+	{"-1/5", "-1/5", true},
+	{"8129567.7690E14", "812956776900000000000", true},
+	{"78189e+4", "781890000", true},
+	{"553019.8935e+8", "55301989350000", true},
+	{"98765432109876543210987654321e-10", "98765432109876543210987654321/10000000000", true},
+	{"9877861857500000E-7", "3951144743/4", true},
+	{"2169378.417e-3", "2169378417/1000000", true},
+	{"884243222337379604041632732738665534", "884243222337379604041632732738665534", true},
+	{"53/70893980658822810696", "53/70893980658822810696", true},
+	{"106/141787961317645621392", "53/70893980658822810696", true},
+	{"204211327800791583.81095", "4084226556015831676219/20000", true},
+	{in: "1/0", ok: false},
+}
+
+func TestRatSetString(t *testing.T) {
+	for i, test := range setStringTests {
+		x, ok := new(Rat).SetString(test.in)
+
+		if ok {
+			if !test.ok {
+				t.Errorf("#%d SetString(%q) expected failure", i, test.in)
+			} else if x.RatString() != test.out {
+				t.Errorf("#%d SetString(%q) got %s want %s", i, test.in, x.RatString(), test.out)
+			}
+		} else if x != nil {
+			t.Errorf("#%d SetString(%q) got %p want nil", i, test.in, x)
+		}
+	}
+}
+
+func TestRatScan(t *testing.T) {
+	var buf bytes.Buffer
+	for i, test := range setStringTests {
+		x := new(Rat)
+		buf.Reset()
+		buf.WriteString(test.in)
+
+		_, err := fmt.Fscanf(&buf, "%v", x)
+		if err == nil != test.ok {
+			if test.ok {
+				t.Errorf("#%d error: %s", i, err)
+			} else {
+				t.Errorf("#%d expected error", i)
+			}
+			continue
+		}
+		if err == nil && x.RatString() != test.out {
+			t.Errorf("#%d got %s want %s", i, x.RatString(), test.out)
+		}
+	}
+}
+
+var floatStringTests = []struct {
+	in   string
+	prec int
+	out  string
+}{
+	{"0", 0, "0"},
+	{"0", 4, "0.0000"},
+	{"1", 0, "1"},
+	{"1", 2, "1.00"},
+	{"-1", 0, "-1"},
+	{".25", 2, "0.25"},
+	{".25", 1, "0.3"},
+	{".25", 3, "0.250"},
+	{"-1/3", 3, "-0.333"},
+	{"-2/3", 4, "-0.6667"},
+	{"0.96", 1, "1.0"},
+	{"0.999", 2, "1.00"},
+	{"0.9", 0, "1"},
+	{".25", -1, "0"},
+	{".55", -1, "1"},
+}
+
+func TestFloatString(t *testing.T) {
+	for i, test := range floatStringTests {
+		x, _ := new(Rat).SetString(test.in)
+
+		if x.FloatString(test.prec) != test.out {
+			t.Errorf("#%d got %s want %s", i, x.FloatString(test.prec), test.out)
+		}
+	}
+}
+
+func TestRatSign(t *testing.T) {
+	zero := NewRat(0, 1)
+	for _, a := range setStringTests {
+		x, ok := new(Rat).SetString(a.in)
+		if !ok {
+			continue
+		}
+		s := x.Sign()
+		e := x.Cmp(zero)
+		if s != e {
+			t.Errorf("got %d; want %d for z = %v", s, e, &x)
+		}
+	}
+}
+
+var ratCmpTests = []struct {
+	rat1, rat2 string
+	out        int
+}{
+	{"0", "0/1", 0},
+	{"1/1", "1", 0},
+	{"-1", "-2/2", 0},
+	{"1", "0", 1},
+	{"0/1", "1/1", -1},
+	{"-5/1434770811533343057144", "-5/1434770811533343057145", -1},
+	{"49832350382626108453/8964749413", "49832350382626108454/8964749413", -1},
+	{"-37414950961700930/7204075375675961", "37414950961700930/7204075375675961", -1},
+	{"37414950961700930/7204075375675961", "74829901923401860/14408150751351922", 0},
+}
+
+func TestRatCmp(t *testing.T) {
+	for i, test := range ratCmpTests {
+		x, _ := new(Rat).SetString(test.rat1)
+		y, _ := new(Rat).SetString(test.rat2)
+
+		out := x.Cmp(y)
+		if out != test.out {
+			t.Errorf("#%d got out = %v; want %v", i, out, test.out)
+		}
+	}
+}
+
+func TestIsInt(t *testing.T) {
+	one := NewInt(1)
+	for _, a := range setStringTests {
+		x, ok := new(Rat).SetString(a.in)
+		if !ok {
+			continue
+		}
+		i := x.IsInt()
+		e := x.Denom().Cmp(one) == 0
+		if i != e {
+			t.Errorf("got IsInt(%v) == %v; want %v", x, i, e)
+		}
+	}
+}
+
+func TestRatAbs(t *testing.T) {
+	zero := new(Rat)
+	for _, a := range setStringTests {
+		x, ok := new(Rat).SetString(a.in)
+		if !ok {
+			continue
+		}
+		e := new(Rat).Set(x)
+		if e.Cmp(zero) < 0 {
+			e.Sub(zero, e)
+		}
+		z := new(Rat).Abs(x)
+		if z.Cmp(e) != 0 {
+			t.Errorf("got Abs(%v) = %v; want %v", x, z, e)
+		}
+	}
+}
+
+func TestRatNeg(t *testing.T) {
+	zero := new(Rat)
+	for _, a := range setStringTests {
+		x, ok := new(Rat).SetString(a.in)
+		if !ok {
+			continue
+		}
+		e := new(Rat).Sub(zero, x)
+		z := new(Rat).Neg(x)
+		if z.Cmp(e) != 0 {
+			t.Errorf("got Neg(%v) = %v; want %v", x, z, e)
+		}
+	}
+}
+
+func TestRatInv(t *testing.T) {
+	zero := new(Rat)
+	for _, a := range setStringTests {
+		x, ok := new(Rat).SetString(a.in)
+		if !ok {
+			continue
+		}
+		if x.Cmp(zero) == 0 {
+			continue // avoid division by zero
+		}
+		e := new(Rat).SetFrac(x.Denom(), x.Num())
+		z := new(Rat).Inv(x)
+		if z.Cmp(e) != 0 {
+			t.Errorf("got Inv(%v) = %v; want %v", x, z, e)
+		}
+	}
+}
+
+type ratBinFun func(z, x, y *Rat) *Rat
+type ratBinArg struct {
+	x, y, z string
+}
+
+func testRatBin(t *testing.T, i int, name string, f ratBinFun, a ratBinArg) {
+	x, _ := new(Rat).SetString(a.x)
+	y, _ := new(Rat).SetString(a.y)
+	z, _ := new(Rat).SetString(a.z)
+	out := f(new(Rat), x, y)
+
+	if out.Cmp(z) != 0 {
+		t.Errorf("%s #%d got %s want %s", name, i, out, z)
+	}
+}
+
+var ratBinTests = []struct {
+	x, y      string
+	sum, prod string
+}{
+	{"0", "0", "0", "0"},
+	{"0", "1", "1", "0"},
+	{"-1", "0", "-1", "0"},
+	{"-1", "1", "0", "-1"},
+	{"1", "1", "2", "1"},
+	{"1/2", "1/2", "1", "1/4"},
+	{"1/4", "1/3", "7/12", "1/12"},
+	{"2/5", "-14/3", "-64/15", "-28/15"},
+	{"4707/49292519774798173060", "-3367/70976135186689855734", "84058377121001851123459/1749296273614329067191168098769082663020", "-1760941/388732505247628681598037355282018369560"},
+	{"-61204110018146728334/3", "-31052192278051565633/2", "-215564796870448153567/6", "950260896245257153059642991192710872711/3"},
+	{"-854857841473707320655/4237645934602118692642972629634714039", "-18/31750379913563777419", "-27/133467566250814981", "15387441146526731771790/134546868362786310073779084329032722548987800600710485341"},
+	{"618575745270541348005638912139/19198433543745179392300736", "-19948846211000086/637313996471", "27674141753240653/30123979153216", "-6169936206128396568797607742807090270137721977/6117715203873571641674006593837351328"},
+	{"-3/26206484091896184128", "5/2848423294177090248", "15310893822118706237/9330894968229805033368778458685147968", "-5/24882386581946146755650075889827061248"},
+	{"26946729/330400702820", "41563965/225583428284", "1238218672302860271/4658307703098666660055", "224002580204097/14906584649915733312176"},
+	{"-8259900599013409474/7", "-84829337473700364773/56707961321161574960", "-468402123685491748914621885145127724451/396955729248131024720", "350340947706464153265156004876107029701/198477864624065512360"},
+	{"575775209696864/1320203974639986246357", "29/712593081308", "410331716733912717985762465/940768218243776489278275419794956", "808/45524274987585732633"},
+	{"1786597389946320496771/2066653520653241", "6269770/1992362624741777", "3559549865190272133656109052308126637/4117523232840525481453983149257", "8967230/3296219033"},
+	{"-36459180403360509753/32150500941194292113930", "9381566963714/9633539", "301622077145533298008420642898530153/309723104686531919656937098270", "-3784609207827/3426986245"},
+}
+
+func TestRatBin(t *testing.T) {
+	for i, test := range ratBinTests {
+		arg := ratBinArg{test.x, test.y, test.sum}
+		testRatBin(t, i, "Add", (*Rat).Add, arg)
+
+		arg = ratBinArg{test.y, test.x, test.sum}
+		testRatBin(t, i, "Add symmetric", (*Rat).Add, arg)
+
+		arg = ratBinArg{test.sum, test.x, test.y}
+		testRatBin(t, i, "Sub", (*Rat).Sub, arg)
+
+		arg = ratBinArg{test.sum, test.y, test.x}
+		testRatBin(t, i, "Sub symmetric", (*Rat).Sub, arg)
+
+		arg = ratBinArg{test.x, test.y, test.prod}
+		testRatBin(t, i, "Mul", (*Rat).Mul, arg)
+
+		arg = ratBinArg{test.y, test.x, test.prod}
+		testRatBin(t, i, "Mul symmetric", (*Rat).Mul, arg)
+
+		if test.x != "0" {
+			arg = ratBinArg{test.prod, test.x, test.y}
+			testRatBin(t, i, "Quo", (*Rat).Quo, arg)
+		}
+
+		if test.y != "0" {
+			arg = ratBinArg{test.prod, test.y, test.x}
+			testRatBin(t, i, "Quo symmetric", (*Rat).Quo, arg)
+		}
+	}
+}
+
+func TestIssue820(t *testing.T) {
+	x := NewRat(3, 1)
+	y := NewRat(2, 1)
+	z := y.Quo(x, y)
+	q := NewRat(3, 2)
+	if z.Cmp(q) != 0 {
+		t.Errorf("got %s want %s", z, q)
+	}
+
+	y = NewRat(3, 1)
+	x = NewRat(2, 1)
+	z = y.Quo(x, y)
+	q = NewRat(2, 3)
+	if z.Cmp(q) != 0 {
+		t.Errorf("got %s want %s", z, q)
+	}
+
+	x = NewRat(3, 1)
+	z = x.Quo(x, x)
+	q = NewRat(3, 3)
+	if z.Cmp(q) != 0 {
+		t.Errorf("got %s want %s", z, q)
+	}
+}
+
+var setFrac64Tests = []struct {
+	a, b int64
+	out  string
+}{
+	{0, 1, "0"},
+	{0, -1, "0"},
+	{1, 1, "1"},
+	{-1, 1, "-1"},
+	{1, -1, "-1"},
+	{-1, -1, "1"},
+	{-9223372036854775808, -9223372036854775808, "1"},
+}
+
+func TestRatSetFrac64Rat(t *testing.T) {
+	for i, test := range setFrac64Tests {
+		x := new(Rat).SetFrac64(test.a, test.b)
+		if x.RatString() != test.out {
+			t.Errorf("#%d got %s want %s", i, x.RatString(), test.out)
+		}
+	}
+}
+
+func TestRatGobEncoding(t *testing.T) {
+	var medium bytes.Buffer
+	enc := gob.NewEncoder(&medium)
+	dec := gob.NewDecoder(&medium)
+	for _, test := range encodingTests {
+		medium.Reset() // empty buffer for each test case (in case of failures)
+		var tx Rat
+		tx.SetString(test + ".14159265")
+		if err := enc.Encode(&tx); err != nil {
+			t.Errorf("encoding of %s failed: %s", &tx, err)
+		}
+		var rx Rat
+		if err := dec.Decode(&rx); err != nil {
+			t.Errorf("decoding of %s failed: %s", &tx, err)
+		}
+		if rx.Cmp(&tx) != 0 {
+			t.Errorf("transmission of %s failed: got %s want %s", &tx, &rx, &tx)
+		}
+	}
+}
+
+// Sending a nil Rat pointer (inside a slice) on a round trip through gob should yield a zero.
+// TODO: top-level nils.
+func TestGobEncodingNilRatInSlice(t *testing.T) {
+	buf := new(bytes.Buffer)
+	enc := gob.NewEncoder(buf)
+	dec := gob.NewDecoder(buf)
+
+	var in = make([]*Rat, 1)
+	err := enc.Encode(&in)
+	if err != nil {
+		t.Errorf("gob encode failed: %q", err)
+	}
+	var out []*Rat
+	err = dec.Decode(&out)
+	if err != nil {
+		t.Fatalf("gob decode failed: %q", err)
+	}
+	if len(out) != 1 {
+		t.Fatalf("wrong len; want 1 got %d", len(out))
+	}
+	var zero Rat
+	if out[0].Cmp(&zero) != 0 {
+		t.Errorf("transmission of (*Int)(nill) failed: got %s want 0", out)
+	}
+}
+
+var ratNums = []string{
+	"-141592653589793238462643383279502884197169399375105820974944592307816406286",
+	"-1415926535897932384626433832795028841971",
+	"-141592653589793",
+	"-1",
+	"0",
+	"1",
+	"141592653589793",
+	"1415926535897932384626433832795028841971",
+	"141592653589793238462643383279502884197169399375105820974944592307816406286",
+}
+
+var ratDenoms = []string{
+	"1",
+	"718281828459045",
+	"7182818284590452353602874713526624977572",
+	"718281828459045235360287471352662497757247093699959574966967627724076630353",
+}
+
+func TestRatJSONEncoding(t *testing.T) {
+	for _, num := range ratNums {
+		for _, denom := range ratDenoms {
+			var tx Rat
+			tx.SetString(num + "/" + denom)
+			b, err := json.Marshal(&tx)
+			if err != nil {
+				t.Errorf("marshaling of %s failed: %s", &tx, err)
+				continue
+			}
+			var rx Rat
+			if err := json.Unmarshal(b, &rx); err != nil {
+				t.Errorf("unmarshaling of %s failed: %s", &tx, err)
+				continue
+			}
+			if rx.Cmp(&tx) != 0 {
+				t.Errorf("JSON encoding of %s failed: got %s want %s", &tx, &rx, &tx)
+			}
+		}
+	}
+}
+
+func TestRatXMLEncoding(t *testing.T) {
+	for _, num := range ratNums {
+		for _, denom := range ratDenoms {
+			var tx Rat
+			tx.SetString(num + "/" + denom)
+			b, err := xml.Marshal(&tx)
+			if err != nil {
+				t.Errorf("marshaling of %s failed: %s", &tx, err)
+				continue
+			}
+			var rx Rat
+			if err := xml.Unmarshal(b, &rx); err != nil {
+				t.Errorf("unmarshaling of %s failed: %s", &tx, err)
+				continue
+			}
+			if rx.Cmp(&tx) != 0 {
+				t.Errorf("XML encoding of %s failed: got %s want %s", &tx, &rx, &tx)
+			}
+		}
+	}
+}
+
+func TestIssue2379(t *testing.T) {
+	// 1) no aliasing
+	q := NewRat(3, 2)
+	x := new(Rat)
+	x.SetFrac(NewInt(3), NewInt(2))
+	if x.Cmp(q) != 0 {
+		t.Errorf("1) got %s want %s", x, q)
+	}
+
+	// 2) aliasing of numerator
+	x = NewRat(2, 3)
+	x.SetFrac(NewInt(3), x.Num())
+	if x.Cmp(q) != 0 {
+		t.Errorf("2) got %s want %s", x, q)
+	}
+
+	// 3) aliasing of denominator
+	x = NewRat(2, 3)
+	x.SetFrac(x.Denom(), NewInt(2))
+	if x.Cmp(q) != 0 {
+		t.Errorf("3) got %s want %s", x, q)
+	}
+
+	// 4) aliasing of numerator and denominator
+	x = NewRat(2, 3)
+	x.SetFrac(x.Denom(), x.Num())
+	if x.Cmp(q) != 0 {
+		t.Errorf("4) got %s want %s", x, q)
+	}
+
+	// 5) numerator and denominator are the same
+	q = NewRat(1, 1)
+	x = new(Rat)
+	n := NewInt(7)
+	x.SetFrac(n, n)
+	if x.Cmp(q) != 0 {
+		t.Errorf("5) got %s want %s", x, q)
+	}
+}
+
+func TestIssue3521(t *testing.T) {
+	a := new(Int)
+	b := new(Int)
+	a.SetString("64375784358435883458348587", 0)
+	b.SetString("4789759874531", 0)
+
+	// 0) a raw zero value has 1 as denominator
+	zero := new(Rat)
+	one := NewInt(1)
+	if zero.Denom().Cmp(one) != 0 {
+		t.Errorf("0) got %s want %s", zero.Denom(), one)
+	}
+
+	// 1a) a zero value remains zero independent of denominator
+	x := new(Rat)
+	x.Denom().Set(new(Int).Neg(b))
+	if x.Cmp(zero) != 0 {
+		t.Errorf("1a) got %s want %s", x, zero)
+	}
+
+	// 1b) a zero value may have a denominator != 0 and != 1
+	x.Num().Set(a)
+	qab := new(Rat).SetFrac(a, b)
+	if x.Cmp(qab) != 0 {
+		t.Errorf("1b) got %s want %s", x, qab)
+	}
+
+	// 2a) an integral value becomes a fraction depending on denominator
+	x.SetFrac64(10, 2)
+	x.Denom().SetInt64(3)
+	q53 := NewRat(5, 3)
+	if x.Cmp(q53) != 0 {
+		t.Errorf("2a) got %s want %s", x, q53)
+	}
+
+	// 2b) an integral value becomes a fraction depending on denominator
+	x = NewRat(10, 2)
+	x.Denom().SetInt64(3)
+	if x.Cmp(q53) != 0 {
+		t.Errorf("2b) got %s want %s", x, q53)
+	}
+
+	// 3) changing the numerator/denominator of a Rat changes the Rat
+	x.SetFrac(a, b)
+	a = x.Num()
+	b = x.Denom()
+	a.SetInt64(5)
+	b.SetInt64(3)
+	if x.Cmp(q53) != 0 {
+		t.Errorf("3) got %s want %s", x, q53)
+	}
+}
+
+// Test inputs to Rat.SetString.  The prefix "long:" causes the test
+// to be skipped in --test.short mode.  (The threshold is about 500us.)
+var float64inputs = []string{
+	// Constants plundered from strconv/testfp.txt.
+
+	// Table 1: Stress Inputs for Conversion to 53-bit Binary, < 1/2 ULP
+	"5e+125",
+	"69e+267",
+	"999e-026",
+	"7861e-034",
+	"75569e-254",
+	"928609e-261",
+	"9210917e+080",
+	"84863171e+114",
+	"653777767e+273",
+	"5232604057e-298",
+	"27235667517e-109",
+	"653532977297e-123",
+	"3142213164987e-294",
+	"46202199371337e-072",
+	"231010996856685e-073",
+	"9324754620109615e+212",
+	"78459735791271921e+049",
+	"272104041512242479e+200",
+	"6802601037806061975e+198",
+	"20505426358836677347e-221",
+	"836168422905420598437e-234",
+	"4891559871276714924261e+222",
+
+	// Table 2: Stress Inputs for Conversion to 53-bit Binary, > 1/2 ULP
+	"9e-265",
+	"85e-037",
+	"623e+100",
+	"3571e+263",
+	"81661e+153",
+	"920657e-023",
+	"4603285e-024",
+	"87575437e-309",
+	"245540327e+122",
+	"6138508175e+120",
+	"83356057653e+193",
+	"619534293513e+124",
+	"2335141086879e+218",
+	"36167929443327e-159",
+	"609610927149051e-255",
+	"3743626360493413e-165",
+	"94080055902682397e-242",
+	"899810892172646163e+283",
+	"7120190517612959703e+120",
+	"25188282901709339043e-252",
+	"308984926168550152811e-052",
+	"6372891218502368041059e+064",
+
+	// Table 14: Stress Inputs for Conversion to 24-bit Binary, <1/2 ULP
+	"5e-20",
+	"67e+14",
+	"985e+15",
+	"7693e-42",
+	"55895e-16",
+	"996622e-44",
+	"7038531e-32",
+	"60419369e-46",
+	"702990899e-20",
+	"6930161142e-48",
+	"25933168707e+13",
+	"596428896559e+20",
+
+	// Table 15: Stress Inputs for Conversion to 24-bit Binary, >1/2 ULP
+	"3e-23",
+	"57e+18",
+	"789e-35",
+	"2539e-18",
+	"76173e+28",
+	"887745e-11",
+	"5382571e-37",
+	"82381273e-35",
+	"750486563e-38",
+	"3752432815e-39",
+	"75224575729e-45",
+	"459926601011e+15",
+
+	// Constants plundered from strconv/atof_test.go.
+
+	"0",
+	"1",
+	"+1",
+	"1e23",
+	"1E23",
+	"100000000000000000000000",
+	"1e-100",
+	"123456700",
+	"99999999999999974834176",
+	"100000000000000000000001",
+	"100000000000000008388608",
+	"100000000000000016777215",
+	"100000000000000016777216",
+	"-1",
+	"-0.1",
+	"-0", // NB: exception made for this input
+	"1e-20",
+	"625e-3",
+
+	// largest float64
+	"1.7976931348623157e308",
+	"-1.7976931348623157e308",
+	// next float64 - too large
+	"1.7976931348623159e308",
+	"-1.7976931348623159e308",
+	// the border is ...158079
+	// borderline - okay
+	"1.7976931348623158e308",
+	"-1.7976931348623158e308",
+	// borderline - too large
+	"1.797693134862315808e308",
+	"-1.797693134862315808e308",
+
+	// a little too large
+	"1e308",
+	"2e308",
+	"1e309",
+
+	// way too large
+	"1e310",
+	"-1e310",
+	"1e400",
+	"-1e400",
+	"long:1e400000",
+	"long:-1e400000",
+
+	// denormalized
+	"1e-305",
+	"1e-306",
+	"1e-307",
+	"1e-308",
+	"1e-309",
+	"1e-310",
+	"1e-322",
+	// smallest denormal
+	"5e-324",
+	"4e-324",
+	"3e-324",
+	// too small
+	"2e-324",
+	// way too small
+	"1e-350",
+	"long:1e-400000",
+	// way too small, negative
+	"-1e-350",
+	"long:-1e-400000",
+
+	// try to overflow exponent
+	// [Disabled: too slow and memory-hungry with rationals.]
+	// "1e-4294967296",
+	// "1e+4294967296",
+	// "1e-18446744073709551616",
+	// "1e+18446744073709551616",
+
+	// http://www.exploringbinary.com/java-hangs-when-converting-2-2250738585072012e-308/
+	"2.2250738585072012e-308",
+	// http://www.exploringbinary.com/php-hangs-on-numeric-value-2-2250738585072011e-308/
+	"2.2250738585072011e-308",
+
+	// A very large number (initially wrongly parsed by the fast algorithm).
+	"4.630813248087435e+307",
+
+	// A different kind of very large number.
+	"22.222222222222222",
+	"long:2." + strings.Repeat("2", 4000) + "e+1",
+
+	// Exactly halfway between 1 and math.Nextafter(1, 2).
+	// Round to even (down).
+	"1.00000000000000011102230246251565404236316680908203125",
+	// Slightly lower; still round down.
+	"1.00000000000000011102230246251565404236316680908203124",
+	// Slightly higher; round up.
+	"1.00000000000000011102230246251565404236316680908203126",
+	// Slightly higher, but you have to read all the way to the end.
+	"long:1.00000000000000011102230246251565404236316680908203125" + strings.Repeat("0", 10000) + "1",
+
+	// Smallest denormal, 2^(-1022-52)
+	"4.940656458412465441765687928682213723651e-324",
+	// Half of smallest denormal, 2^(-1022-53)
+	"2.470328229206232720882843964341106861825e-324",
+	// A little more than the exact half of smallest denormal
+	// 2^-1075 + 2^-1100.  (Rounds to 1p-1074.)
+	"2.470328302827751011111470718709768633275e-324",
+	// The exact halfway between smallest normal and largest denormal:
+	// 2^-1022 - 2^-1075.  (Rounds to 2^-1022.)
+	"2.225073858507201136057409796709131975935e-308",
+
+	"1152921504606846975",  //   1<<60 - 1
+	"-1152921504606846975", // -(1<<60 - 1)
+	"1152921504606846977",  //   1<<60 + 1
+	"-1152921504606846977", // -(1<<60 + 1)
+
+	"1/3",
+}
+
+// isFinite reports whether f represents a finite rational value.
+// It is equivalent to !math.IsNan(f) && !math.IsInf(f, 0).
+func isFinite(f float64) bool {
+	return math.Abs(f) <= math.MaxFloat64
+}
+
+func TestFloat32SpecialCases(t *testing.T) {
+	for _, input := range float64inputs {
+		if strings.HasPrefix(input, "long:") {
+			if testing.Short() {
+				continue
+			}
+			input = input[len("long:"):]
+		}
+
+		r, ok := new(Rat).SetString(input)
+		if !ok {
+			t.Errorf("Rat.SetString(%q) failed", input)
+			continue
+		}
+		f, exact := r.Float32()
+
+		// 1. Check string -> Rat -> float32 conversions are
+		// consistent with strconv.ParseFloat.
+		// Skip this check if the input uses "a/b" rational syntax.
+		if !strings.Contains(input, "/") {
+			e64, _ := strconv.ParseFloat(input, 32)
+			e := float32(e64)
+
+			// Careful: negative Rats too small for
+			// float64 become -0, but Rat obviously cannot
+			// preserve the sign from SetString("-0").
+			switch {
+			case math.Float32bits(e) == math.Float32bits(f):
+				// Ok: bitwise equal.
+			case f == 0 && r.Num().BitLen() == 0:
+				// Ok: Rat(0) is equivalent to both +/- float64(0).
+			default:
+				t.Errorf("strconv.ParseFloat(%q) = %g (%b), want %g (%b); delta = %g", input, e, e, f, f, f-e)
+			}
+		}
+
+		if !isFinite(float64(f)) {
+			continue
+		}
+
+		// 2. Check f is best approximation to r.
+		if !checkIsBestApprox32(t, f, r) {
+			// Append context information.
+			t.Errorf("(input was %q)", input)
+		}
+
+		// 3. Check f->R->f roundtrip is non-lossy.
+		checkNonLossyRoundtrip32(t, f)
+
+		// 4. Check exactness using slow algorithm.
+		if wasExact := new(Rat).SetFloat64(float64(f)).Cmp(r) == 0; wasExact != exact {
+			t.Errorf("Rat.SetString(%q).Float32().exact = %t, want %t", input, exact, wasExact)
+		}
+	}
+}
+
+func TestFloat64SpecialCases(t *testing.T) {
+	for _, input := range float64inputs {
+		if strings.HasPrefix(input, "long:") {
+			if testing.Short() {
+				continue
+			}
+			input = input[len("long:"):]
+		}
+
+		r, ok := new(Rat).SetString(input)
+		if !ok {
+			t.Errorf("Rat.SetString(%q) failed", input)
+			continue
+		}
+		f, exact := r.Float64()
+
+		// 1. Check string -> Rat -> float64 conversions are
+		// consistent with strconv.ParseFloat.
+		// Skip this check if the input uses "a/b" rational syntax.
+		if !strings.Contains(input, "/") {
+			e, _ := strconv.ParseFloat(input, 64)
+
+			// Careful: negative Rats too small for
+			// float64 become -0, but Rat obviously cannot
+			// preserve the sign from SetString("-0").
+			switch {
+			case math.Float64bits(e) == math.Float64bits(f):
+				// Ok: bitwise equal.
+			case f == 0 && r.Num().BitLen() == 0:
+				// Ok: Rat(0) is equivalent to both +/- float64(0).
+			default:
+				t.Errorf("strconv.ParseFloat(%q) = %g (%b), want %g (%b); delta = %g", input, e, e, f, f, f-e)
+			}
+		}
+
+		if !isFinite(f) {
+			continue
+		}
+
+		// 2. Check f is best approximation to r.
+		if !checkIsBestApprox64(t, f, r) {
+			// Append context information.
+			t.Errorf("(input was %q)", input)
+		}
+
+		// 3. Check f->R->f roundtrip is non-lossy.
+		checkNonLossyRoundtrip64(t, f)
+
+		// 4. Check exactness using slow algorithm.
+		if wasExact := new(Rat).SetFloat64(f).Cmp(r) == 0; wasExact != exact {
+			t.Errorf("Rat.SetString(%q).Float64().exact = %t, want %t", input, exact, wasExact)
+		}
+	}
+}
+
+func TestFloat32Distribution(t *testing.T) {
+	// Generate a distribution of (sign, mantissa, exp) values
+	// broader than the float32 range, and check Rat.Float32()
+	// always picks the closest float32 approximation.
+	var add = []int64{
+		0,
+		1,
+		3,
+		5,
+		7,
+		9,
+		11,
+	}
+	var winc, einc = uint64(1), 1 // soak test (~1.5s on x86-64)
+	if testing.Short() {
+		winc, einc = 5, 15 // quick test (~60ms on x86-64)
+	}
+
+	for _, sign := range "+-" {
+		for _, a := range add {
+			for wid := uint64(0); wid < 30; wid += winc {
+				b := 1<<wid + a
+				if sign == '-' {
+					b = -b
+				}
+				for exp := -150; exp < 150; exp += einc {
+					num, den := NewInt(b), NewInt(1)
+					if exp > 0 {
+						num.Lsh(num, uint(exp))
+					} else {
+						den.Lsh(den, uint(-exp))
+					}
+					r := new(Rat).SetFrac(num, den)
+					f, _ := r.Float32()
+
+					if !checkIsBestApprox32(t, f, r) {
+						// Append context information.
+						t.Errorf("(input was mantissa %#x, exp %d; f = %g (%b); f ~ %g; r = %v)",
+							b, exp, f, f, math.Ldexp(float64(b), exp), r)
+					}
+
+					checkNonLossyRoundtrip32(t, f)
+				}
+			}
+		}
+	}
+}
+
+func TestFloat64Distribution(t *testing.T) {
+	// Generate a distribution of (sign, mantissa, exp) values
+	// broader than the float64 range, and check Rat.Float64()
+	// always picks the closest float64 approximation.
+	var add = []int64{
+		0,
+		1,
+		3,
+		5,
+		7,
+		9,
+		11,
+	}
+	var winc, einc = uint64(1), 1 // soak test (~75s on x86-64)
+	if testing.Short() {
+		winc, einc = 10, 500 // quick test (~12ms on x86-64)
+	}
+
+	for _, sign := range "+-" {
+		for _, a := range add {
+			for wid := uint64(0); wid < 60; wid += winc {
+				b := 1<<wid + a
+				if sign == '-' {
+					b = -b
+				}
+				for exp := -1100; exp < 1100; exp += einc {
+					num, den := NewInt(b), NewInt(1)
+					if exp > 0 {
+						num.Lsh(num, uint(exp))
+					} else {
+						den.Lsh(den, uint(-exp))
+					}
+					r := new(Rat).SetFrac(num, den)
+					f, _ := r.Float64()
+
+					if !checkIsBestApprox64(t, f, r) {
+						// Append context information.
+						t.Errorf("(input was mantissa %#x, exp %d; f = %g (%b); f ~ %g; r = %v)",
+							b, exp, f, f, math.Ldexp(float64(b), exp), r)
+					}
+
+					checkNonLossyRoundtrip64(t, f)
+				}
+			}
+		}
+	}
+}
+
+// TestSetFloat64NonFinite checks that SetFloat64 of a non-finite value
+// returns nil.
+func TestSetFloat64NonFinite(t *testing.T) {
+	for _, f := range []float64{math.NaN(), math.Inf(+1), math.Inf(-1)} {
+		var r Rat
+		if r2 := r.SetFloat64(f); r2 != nil {
+			t.Errorf("SetFloat64(%g) was %v, want nil", f, r2)
+		}
+	}
+}
+
+// checkNonLossyRoundtrip32 checks that a float->Rat->float roundtrip is
+// non-lossy for finite f.
+func checkNonLossyRoundtrip32(t *testing.T, f float32) {
+	if !isFinite(float64(f)) {
+		return
+	}
+	r := new(Rat).SetFloat64(float64(f))
+	if r == nil {
+		t.Errorf("Rat.SetFloat64(float64(%g) (%b)) == nil", f, f)
+		return
+	}
+	f2, exact := r.Float32()
+	if f != f2 || !exact {
+		t.Errorf("Rat.SetFloat64(float64(%g)).Float32() = %g (%b), %v, want %g (%b), %v; delta = %b",
+			f, f2, f2, exact, f, f, true, f2-f)
+	}
+}
+
+// checkNonLossyRoundtrip64 checks that a float->Rat->float roundtrip is
+// non-lossy for finite f.
+func checkNonLossyRoundtrip64(t *testing.T, f float64) {
+	if !isFinite(f) {
+		return
+	}
+	r := new(Rat).SetFloat64(f)
+	if r == nil {
+		t.Errorf("Rat.SetFloat64(%g (%b)) == nil", f, f)
+		return
+	}
+	f2, exact := r.Float64()
+	if f != f2 || !exact {
+		t.Errorf("Rat.SetFloat64(%g).Float64() = %g (%b), %v, want %g (%b), %v; delta = %b",
+			f, f2, f2, exact, f, f, true, f2-f)
+	}
+}
+
+// delta returns the absolute difference between r and f.
+func delta(r *Rat, f float64) *Rat {
+	d := new(Rat).Sub(r, new(Rat).SetFloat64(f))
+	return d.Abs(d)
+}
+
+// checkIsBestApprox32 checks that f is the best possible float32
+// approximation of r.
+// Returns true on success.
+func checkIsBestApprox32(t *testing.T, f float32, r *Rat) bool {
+	if math.Abs(float64(f)) >= math.MaxFloat32 {
+		// Cannot check +Inf, -Inf, nor the float next to them (MaxFloat32).
+		// But we have tests for these special cases.
+		return true
+	}
+
+	// r must be strictly between f0 and f1, the floats bracketing f.
+	f0 := math.Nextafter32(f, float32(math.Inf(-1)))
+	f1 := math.Nextafter32(f, float32(math.Inf(+1)))
+
+	// For f to be correct, r must be closer to f than to f0 or f1.
+	df := delta(r, float64(f))
+	df0 := delta(r, float64(f0))
+	df1 := delta(r, float64(f1))
+	if df.Cmp(df0) > 0 {
+		t.Errorf("Rat(%v).Float32() = %g (%b), but previous float32 %g (%b) is closer", r, f, f, f0, f0)
+		return false
+	}
+	if df.Cmp(df1) > 0 {
+		t.Errorf("Rat(%v).Float32() = %g (%b), but next float32 %g (%b) is closer", r, f, f, f1, f1)
+		return false
+	}
+	if df.Cmp(df0) == 0 && !isEven32(f) {
+		t.Errorf("Rat(%v).Float32() = %g (%b); halfway should have rounded to %g (%b) instead", r, f, f, f0, f0)
+		return false
+	}
+	if df.Cmp(df1) == 0 && !isEven32(f) {
+		t.Errorf("Rat(%v).Float32() = %g (%b); halfway should have rounded to %g (%b) instead", r, f, f, f1, f1)
+		return false
+	}
+	return true
+}
+
+// checkIsBestApprox64 checks that f is the best possible float64
+// approximation of r.
+// Returns true on success.
+func checkIsBestApprox64(t *testing.T, f float64, r *Rat) bool {
+	if math.Abs(f) >= math.MaxFloat64 {
+		// Cannot check +Inf, -Inf, nor the float next to them (MaxFloat64).
+		// But we have tests for these special cases.
+		return true
+	}
+
+	// r must be strictly between f0 and f1, the floats bracketing f.
+	f0 := math.Nextafter(f, math.Inf(-1))
+	f1 := math.Nextafter(f, math.Inf(+1))
+
+	// For f to be correct, r must be closer to f than to f0 or f1.
+	df := delta(r, f)
+	df0 := delta(r, f0)
+	df1 := delta(r, f1)
+	if df.Cmp(df0) > 0 {
+		t.Errorf("Rat(%v).Float64() = %g (%b), but previous float64 %g (%b) is closer", r, f, f, f0, f0)
+		return false
+	}
+	if df.Cmp(df1) > 0 {
+		t.Errorf("Rat(%v).Float64() = %g (%b), but next float64 %g (%b) is closer", r, f, f, f1, f1)
+		return false
+	}
+	if df.Cmp(df0) == 0 && !isEven64(f) {
+		t.Errorf("Rat(%v).Float64() = %g (%b); halfway should have rounded to %g (%b) instead", r, f, f, f0, f0)
+		return false
+	}
+	if df.Cmp(df1) == 0 && !isEven64(f) {
+		t.Errorf("Rat(%v).Float64() = %g (%b); halfway should have rounded to %g (%b) instead", r, f, f, f1, f1)
+		return false
+	}
+	return true
+}
+
+func isEven32(f float32) bool { return math.Float32bits(f)&1 == 0 }
+func isEven64(f float64) bool { return math.Float64bits(f)&1 == 0 }
+
+func TestIsFinite(t *testing.T) {
+	finites := []float64{
+		1.0 / 3,
+		4891559871276714924261e+222,
+		math.MaxFloat64,
+		math.SmallestNonzeroFloat64,
+		-math.MaxFloat64,
+		-math.SmallestNonzeroFloat64,
+	}
+	for _, f := range finites {
+		if !isFinite(f) {
+			t.Errorf("!IsFinite(%g (%b))", f, f)
+		}
+	}
+	nonfinites := []float64{
+		math.NaN(),
+		math.Inf(-1),
+		math.Inf(+1),
+	}
+	for _, f := range nonfinites {
+		if isFinite(f) {
+			t.Errorf("IsFinite(%g, (%b))", f, f)
+		}
+	}
+}
diff --git a/src/pkg/math/bits.go b/src/math/bits.go
similarity index 100%
rename from src/pkg/math/bits.go
rename to src/math/bits.go
diff --git a/src/pkg/math/cbrt.go b/src/math/cbrt.go
similarity index 100%
rename from src/pkg/math/cbrt.go
rename to src/math/cbrt.go
diff --git a/src/pkg/math/cmplx/abs.go b/src/math/cmplx/abs.go
similarity index 100%
rename from src/pkg/math/cmplx/abs.go
rename to src/math/cmplx/abs.go
diff --git a/src/pkg/math/cmplx/asin.go b/src/math/cmplx/asin.go
similarity index 100%
rename from src/pkg/math/cmplx/asin.go
rename to src/math/cmplx/asin.go
diff --git a/src/pkg/math/cmplx/cmath_test.go b/src/math/cmplx/cmath_test.go
similarity index 100%
rename from src/pkg/math/cmplx/cmath_test.go
rename to src/math/cmplx/cmath_test.go
diff --git a/src/pkg/math/cmplx/conj.go b/src/math/cmplx/conj.go
similarity index 100%
rename from src/pkg/math/cmplx/conj.go
rename to src/math/cmplx/conj.go
diff --git a/src/pkg/math/cmplx/exp.go b/src/math/cmplx/exp.go
similarity index 100%
rename from src/pkg/math/cmplx/exp.go
rename to src/math/cmplx/exp.go
diff --git a/src/pkg/math/cmplx/isinf.go b/src/math/cmplx/isinf.go
similarity index 100%
rename from src/pkg/math/cmplx/isinf.go
rename to src/math/cmplx/isinf.go
diff --git a/src/pkg/math/cmplx/isnan.go b/src/math/cmplx/isnan.go
similarity index 100%
rename from src/pkg/math/cmplx/isnan.go
rename to src/math/cmplx/isnan.go
diff --git a/src/pkg/math/cmplx/log.go b/src/math/cmplx/log.go
similarity index 100%
rename from src/pkg/math/cmplx/log.go
rename to src/math/cmplx/log.go
diff --git a/src/pkg/math/cmplx/phase.go b/src/math/cmplx/phase.go
similarity index 100%
rename from src/pkg/math/cmplx/phase.go
rename to src/math/cmplx/phase.go
diff --git a/src/pkg/math/cmplx/polar.go b/src/math/cmplx/polar.go
similarity index 100%
rename from src/pkg/math/cmplx/polar.go
rename to src/math/cmplx/polar.go
diff --git a/src/pkg/math/cmplx/pow.go b/src/math/cmplx/pow.go
similarity index 100%
rename from src/pkg/math/cmplx/pow.go
rename to src/math/cmplx/pow.go
diff --git a/src/pkg/math/cmplx/rect.go b/src/math/cmplx/rect.go
similarity index 100%
rename from src/pkg/math/cmplx/rect.go
rename to src/math/cmplx/rect.go
diff --git a/src/pkg/math/cmplx/sin.go b/src/math/cmplx/sin.go
similarity index 100%
rename from src/pkg/math/cmplx/sin.go
rename to src/math/cmplx/sin.go
diff --git a/src/pkg/math/cmplx/sqrt.go b/src/math/cmplx/sqrt.go
similarity index 100%
rename from src/pkg/math/cmplx/sqrt.go
rename to src/math/cmplx/sqrt.go
diff --git a/src/pkg/math/cmplx/tan.go b/src/math/cmplx/tan.go
similarity index 100%
rename from src/pkg/math/cmplx/tan.go
rename to src/math/cmplx/tan.go
diff --git a/src/pkg/math/const.go b/src/math/const.go
similarity index 100%
rename from src/pkg/math/const.go
rename to src/math/const.go
diff --git a/src/pkg/math/copysign.go b/src/math/copysign.go
similarity index 100%
rename from src/pkg/math/copysign.go
rename to src/math/copysign.go
diff --git a/src/pkg/math/dim.go b/src/math/dim.go
similarity index 100%
rename from src/pkg/math/dim.go
rename to src/math/dim.go
diff --git a/src/math/dim_386.s b/src/math/dim_386.s
new file mode 100644
index 0000000..c8194fe
--- /dev/null
+++ b/src/math/dim_386.s
@@ -0,0 +1,14 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+TEXT ·Dim(SB),NOSPLIT,$0
+	JMP ·dim(SB)
+
+TEXT ·Max(SB),NOSPLIT,$0
+	JMP ·max(SB)
+
+TEXT ·Min(SB),NOSPLIT,$0
+	JMP ·min(SB)
diff --git a/src/math/dim_amd64.s b/src/math/dim_amd64.s
new file mode 100644
index 0000000..622cc3f
--- /dev/null
+++ b/src/math/dim_amd64.s
@@ -0,0 +1,144 @@
+// Copyright 2010 The Go 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"
+
+#define PosInf 0x7FF0000000000000
+#define NaN    0x7FF8000000000001
+#define NegInf 0xFFF0000000000000
+
+// func Dim(x, y float64) float64
+TEXT ·Dim(SB),NOSPLIT,$0
+	// (+Inf, +Inf) special case
+	MOVQ    x+0(FP), BX
+	MOVQ    y+8(FP), CX
+	MOVQ    $PosInf, AX
+	CMPQ    AX, BX
+	JNE     dim2
+	CMPQ    AX, CX
+	JEQ     bothInf
+dim2:	// (-Inf, -Inf) special case
+	MOVQ    $NegInf, AX
+	CMPQ    AX, BX
+	JNE     dim3
+	CMPQ    AX, CX
+	JEQ     bothInf
+dim3:	// (NaN, x) or (x, NaN)
+	MOVQ    $~(1<<63), DX
+	MOVQ    $NaN, AX
+	ANDQ    DX, BX // x = |x|
+	CMPQ    AX, BX
+	JLE     isDimNaN
+	ANDQ    DX, CX // y = |y|
+	CMPQ    AX, CX
+	JLE     isDimNaN
+
+	MOVSD x+0(FP), X0
+	SUBSD y+8(FP), X0
+	MOVSD $(0.0), X1
+	MAXSD X1, X0
+	MOVSD X0, ret+16(FP)
+	RET
+bothInf: // Dim(-Inf, -Inf) or Dim(+Inf, +Inf)
+	MOVQ    $NaN, AX
+isDimNaN:
+	MOVQ    AX, ret+16(FP)
+	RET
+
+// func ·Max(x, y float64) float64
+TEXT ·Max(SB),NOSPLIT,$0
+	// +Inf special cases
+	MOVQ    $PosInf, AX
+	MOVQ    x+0(FP), R8
+	CMPQ    AX, R8
+	JEQ     isPosInf
+	MOVQ    y+8(FP), R9
+	CMPQ    AX, R9
+	JEQ     isPosInf
+	// NaN special cases
+	MOVQ    $~(1<<63), DX // bit mask
+	MOVQ    $NaN, AX
+	MOVQ    R8, BX
+	ANDQ    DX, BX // x = |x|
+	CMPQ    AX, BX
+	JLE     isMaxNaN
+	MOVQ    R9, CX
+	ANDQ    DX, CX // y = |y|
+	CMPQ    AX, CX
+	JLE     isMaxNaN
+	// ±0 special cases
+	ORQ     CX, BX
+	JEQ     isMaxZero
+
+	MOVQ    R8, X0
+	MOVQ    R9, X1
+	MAXSD   X1, X0
+	MOVSD   X0, ret+16(FP)
+	RET
+isMaxNaN: // return NaN
+isPosInf: // return +Inf
+	MOVQ    AX, ret+16(FP)
+	RET
+isMaxZero:
+	MOVQ    $(1<<63), AX // -0.0
+	CMPQ    AX, R8
+	JEQ     +3(PC)
+	MOVQ    R8, ret+16(FP) // return 0
+	RET
+	MOVQ    R9, ret+16(FP) // return other 0
+	RET
+
+/*
+	MOVQ    $0, AX
+	CMPQ    AX, R8
+	JNE     +3(PC)
+	MOVQ    R8, ret+16(FP) // return 0
+	RET
+	MOVQ    R9, ret+16(FP) // return other 0
+	RET
+*/
+
+// func Min(x, y float64) float64
+TEXT ·Min(SB),NOSPLIT,$0
+	// -Inf special cases
+	MOVQ    $NegInf, AX
+	MOVQ    x+0(FP), R8
+	CMPQ    AX, R8
+	JEQ     isNegInf
+	MOVQ    y+8(FP), R9
+	CMPQ    AX, R9
+	JEQ     isNegInf
+	// NaN special cases
+	MOVQ    $~(1<<63), DX
+	MOVQ    $NaN, AX
+	MOVQ    R8, BX
+	ANDQ    DX, BX // x = |x|
+	CMPQ    AX, BX
+	JLE     isMinNaN
+	MOVQ    R9, CX
+	ANDQ    DX, CX // y = |y|
+	CMPQ    AX, CX
+	JLE     isMinNaN
+	// ±0 special cases
+	ORQ     CX, BX
+	JEQ     isMinZero
+
+	MOVQ    R8, X0
+	MOVQ    R9, X1
+	MINSD   X1, X0
+	MOVSD X0, ret+16(FP)
+	RET
+isMinNaN: // return NaN
+isNegInf: // return -Inf
+	MOVQ    AX, ret+16(FP)
+	RET
+isMinZero:
+	MOVQ    $(1<<63), AX // -0.0
+	CMPQ    AX, R8
+	JEQ     +3(PC)
+	MOVQ    R9, ret+16(FP) // return other 0
+	RET
+	MOVQ    R8, ret+16(FP) // return -0
+	RET
+
diff --git a/src/pkg/math/dim_amd64p32.s b/src/math/dim_amd64p32.s
similarity index 100%
rename from src/pkg/math/dim_amd64p32.s
rename to src/math/dim_amd64p32.s
diff --git a/src/math/dim_arm.s b/src/math/dim_arm.s
new file mode 100644
index 0000000..be66950
--- /dev/null
+++ b/src/math/dim_arm.s
@@ -0,0 +1,14 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+TEXT ·Dim(SB),NOSPLIT,$0
+	B ·dim(SB)
+
+TEXT ·Min(SB),NOSPLIT,$0
+	B ·min(SB)
+
+TEXT ·Max(SB),NOSPLIT,$0
+	B ·max(SB)
diff --git a/src/pkg/math/erf.go b/src/math/erf.go
similarity index 100%
rename from src/pkg/math/erf.go
rename to src/math/erf.go
diff --git a/src/pkg/math/exp.go b/src/math/exp.go
similarity index 100%
rename from src/pkg/math/exp.go
rename to src/math/exp.go
diff --git a/src/math/exp2_386.s b/src/math/exp2_386.s
new file mode 100644
index 0000000..7d11920
--- /dev/null
+++ b/src/math/exp2_386.s
@@ -0,0 +1,40 @@
+// Copyright 2010 The Go 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 Exp2(x float64) float64
+TEXT ·Exp2(SB),NOSPLIT,$0
+// test bits for not-finite
+	MOVL    x_hi+4(FP), AX
+	ANDL    $0x7ff00000, AX
+	CMPL    AX, $0x7ff00000
+	JEQ     not_finite
+	FMOVD   x+0(FP), F0   // F0=x
+	FMOVD   F0, F1        // F0=x, F1=x
+	FRNDINT               // F0=int(x), F1=x
+	FSUBD   F0, F1        // F0=int(x), F1=x-int(x)
+	FXCHD   F0, F1        // F0=x-int(x), F1=int(x)
+	F2XM1                 // F0=2**(x-int(x))-1, F1=int(x)
+	FLD1                  // F0=1, F1=2**(x-int(x))-1, F2=int(x)
+	FADDDP  F0, F1        // F0=2**(x-int(x)), F1=int(x)
+	FSCALE                // F0=2**x, F1=int(x)
+	FMOVDP  F0, F1        // F0=2**x
+	FMOVDP  F0, ret+8(FP)
+	RET
+not_finite:
+// test bits for -Inf
+	MOVL    x_hi+4(FP), BX
+	MOVL    x_lo+0(FP), CX
+	CMPL    BX, $0xfff00000
+	JNE     not_neginf
+	CMPL    CX, $0
+	JNE     not_neginf
+	MOVL    $0, ret_lo+8(FP)
+	MOVL    $0, ret_hi+12(FP)
+	RET
+not_neginf:
+	MOVL    CX, ret_lo+8(FP)
+	MOVL    BX, ret_hi+12(FP)
+	RET
diff --git a/src/math/exp2_amd64.s b/src/math/exp2_amd64.s
new file mode 100644
index 0000000..903c835
--- /dev/null
+++ b/src/math/exp2_amd64.s
@@ -0,0 +1,8 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+TEXT ·Exp2(SB),NOSPLIT,$0
+	JMP ·exp2(SB)
diff --git a/src/pkg/math/exp2_amd64p32.s b/src/math/exp2_amd64p32.s
similarity index 100%
rename from src/pkg/math/exp2_amd64p32.s
rename to src/math/exp2_amd64p32.s
diff --git a/src/math/exp2_arm.s b/src/math/exp2_arm.s
new file mode 100644
index 0000000..58283cd
--- /dev/null
+++ b/src/math/exp2_arm.s
@@ -0,0 +1,8 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+TEXT ·Exp2(SB),NOSPLIT,$0
+	B ·exp2(SB)
diff --git a/src/math/exp_386.s b/src/math/exp_386.s
new file mode 100644
index 0000000..6a478a5
--- /dev/null
+++ b/src/math/exp_386.s
@@ -0,0 +1,41 @@
+// Copyright 2010 The Go 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 Exp(x float64) float64
+TEXT ·Exp(SB),NOSPLIT,$0
+// test bits for not-finite
+	MOVL    x_hi+4(FP), AX
+	ANDL    $0x7ff00000, AX
+	CMPL    AX, $0x7ff00000
+	JEQ     not_finite
+	FLDL2E                // F0=log2(e)
+	FMULD   x+0(FP), F0   // F0=x*log2(e)
+	FMOVD   F0, F1        // F0=x*log2(e), F1=x*log2(e)
+	FRNDINT               // F0=int(x*log2(e)), F1=x*log2(e)
+	FSUBD   F0, F1        // F0=int(x*log2(e)), F1=x*log2(e)-int(x*log2(e))
+	FXCHD   F0, F1        // F0=x*log2(e)-int(x*log2(e)), F1=int(x*log2(e))
+	F2XM1                 // F0=2**(x*log2(e)-int(x*log2(e)))-1, F1=int(x*log2(e))
+	FLD1                  // F0=1, F1=2**(x*log2(e)-int(x*log2(e)))-1, F2=int(x*log2(e))
+	FADDDP  F0, F1        // F0=2**(x*log2(e)-int(x*log2(e))), F1=int(x*log2(e))
+	FSCALE                // F0=e**x, F1=int(x*log2(e))
+	FMOVDP  F0, F1        // F0=e**x
+	FMOVDP  F0, ret+8(FP)
+	RET
+not_finite:
+// test bits for -Inf
+	MOVL    x_hi+4(FP), BX
+	MOVL    x_lo+0(FP), CX
+	CMPL    BX, $0xfff00000
+	JNE     not_neginf
+	CMPL    CX, $0
+	JNE     not_neginf
+	FLDZ                  // F0=0
+	FMOVDP  F0, ret+8(FP)
+	RET
+not_neginf:
+	MOVL    CX, ret_lo+8(FP)
+	MOVL    BX, ret_hi+12(FP)
+	RET
diff --git a/src/math/exp_amd64.s b/src/math/exp_amd64.s
new file mode 100644
index 0000000..d9cf8fd
--- /dev/null
+++ b/src/math/exp_amd64.s
@@ -0,0 +1,114 @@
+// Copyright 2010 The Go 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"
+
+// The method is based on a paper by Naoki Shibata: "Efficient evaluation
+// methods of elementary functions suitable for SIMD computation", Proc.
+// of International Supercomputing Conference 2010 (ISC'10), pp. 25 -- 32
+// (May 2010). The paper is available at
+// http://www.springerlink.com/content/340228x165742104/
+//
+// The original code and the constants below are from the author's
+// implementation available at http://freshmeat.net/projects/sleef.
+// The README file says, "The software is in public domain.
+// You can use the software without any obligation."
+//
+// This code is a simplified version of the original.
+
+#define LN2 0.6931471805599453094172321214581766 // log_e(2)
+#define LOG2E 1.4426950408889634073599246810018920 // 1/LN2
+#define LN2U 0.69314718055966295651160180568695068359375 // upper half LN2
+#define LN2L 0.28235290563031577122588448175013436025525412068e-12 // lower half LN2
+#define T0 1.0
+#define T1 0.5
+#define T2 1.6666666666666666667e-1
+#define T3 4.1666666666666666667e-2
+#define T4 8.3333333333333333333e-3
+#define T5 1.3888888888888888889e-3
+#define T6 1.9841269841269841270e-4
+#define T7 2.4801587301587301587e-5
+#define PosInf 0x7FF0000000000000
+#define NegInf 0xFFF0000000000000
+
+// func Exp(x float64) float64
+TEXT ·Exp(SB),NOSPLIT,$0
+// test bits for not-finite
+	MOVQ    x+0(FP), BX
+	MOVQ    $~(1<<63), AX // sign bit mask
+	MOVQ    BX, DX
+	ANDQ    AX, DX
+	MOVQ    $PosInf, AX
+	CMPQ    AX, DX
+	JLE     notFinite
+	MOVQ    BX, X0
+	MOVSD   $LOG2E, X1
+	MULSD   X0, X1
+	CVTSD2SL X1, BX // BX = exponent
+	CVTSL2SD BX, X1
+	MOVSD   $LN2U, X2
+	MULSD   X1, X2
+	SUBSD   X2, X0
+	MOVSD   $LN2L, X2
+	MULSD   X1, X2
+	SUBSD   X2, X0
+	// reduce argument
+	MULSD   $0.0625, X0
+	// Taylor series evaluation
+	MOVSD   $T7, X1
+	MULSD   X0, X1
+	ADDSD   $T6, X1
+	MULSD   X0, X1
+	ADDSD   $T5, X1
+	MULSD   X0, X1
+	ADDSD   $T4, X1
+	MULSD   X0, X1
+	ADDSD   $T3, X1
+	MULSD   X0, X1
+	ADDSD   $T2, X1
+	MULSD   X0, X1
+	ADDSD   $T1, X1
+	MULSD   X0, X1
+	ADDSD   $T0, X1
+	MULSD   X1, X0
+	MOVSD   $2.0, X1
+	ADDSD   X0, X1
+	MULSD   X1, X0
+	MOVSD   $2.0, X1
+	ADDSD   X0, X1
+	MULSD   X1, X0
+	MOVSD   $2.0, X1
+	ADDSD   X0, X1
+	MULSD   X1, X0
+	MOVSD   $2.0, X1
+	ADDSD   X0, X1
+	MULSD   X1, X0
+	ADDSD   $1.0, X0
+	// return fr * 2**exponent
+	MOVL    $0x3FF, AX // bias
+	ADDL    AX, BX
+	JLE     underflow
+	CMPL    BX, $0x7FF
+	JGE     overflow
+	MOVL    $52, CX
+	SHLQ    CX, BX
+	MOVQ    BX, X1
+	MULSD   X1, X0
+	MOVSD   X0, ret+8(FP)
+	RET
+notFinite:
+	// test bits for -Inf
+	MOVQ    $NegInf, AX
+	CMPQ    AX, BX
+	JNE     notNegInf
+	// -Inf, return 0
+underflow: // return 0
+	MOVQ    $0, AX
+	MOVQ    AX, ret+8(FP)
+	RET
+overflow: // return +Inf
+	MOVQ    $PosInf, BX
+notNegInf: // NaN or +Inf, return x
+	MOVQ    BX, ret+8(FP)
+	RET
diff --git a/src/pkg/math/exp_amd64p32.s b/src/math/exp_amd64p32.s
similarity index 100%
rename from src/pkg/math/exp_amd64p32.s
rename to src/math/exp_amd64p32.s
diff --git a/src/math/exp_arm.s b/src/math/exp_arm.s
new file mode 100644
index 0000000..ce36d03
--- /dev/null
+++ b/src/math/exp_arm.s
@@ -0,0 +1,8 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+TEXT ·Exp(SB),NOSPLIT,$0
+	B ·exp(SB)
diff --git a/src/pkg/math/expm1.go b/src/math/expm1.go
similarity index 100%
rename from src/pkg/math/expm1.go
rename to src/math/expm1.go
diff --git a/src/math/expm1_386.s b/src/math/expm1_386.s
new file mode 100644
index 0000000..a48ca8a
--- /dev/null
+++ b/src/math/expm1_386.s
@@ -0,0 +1,57 @@
+// Copyright 2010 The Go 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 Expm1(x float64) float64
+TEXT ·Expm1(SB),NOSPLIT,$0
+	FLDLN2               // F0=log(2) = 1/log2(e) ~ 0.693147
+	FMOVD   x+0(FP), F0  // F0=x, F1=1/log2(e)
+	FABS                 // F0=|x|, F1=1/log2(e) 
+	FUCOMPP F0, F1       // compare F0 to F1
+	FSTSW   AX
+	SAHF
+	JCC     use_exp      // jump if F0 >= F1
+	FLDL2E                // F0=log2(e)
+	FMULD   x+0(FP), F0   // F0=x*log2(e) (-1<F0<1)
+	F2XM1                 // F0=e**x-1 = 2**(x*log2(e))-1
+	FMOVDP  F0, ret+8(FP)
+	RET
+use_exp:
+// test bits for not-finite
+	MOVL    x_hi+4(FP), AX
+	ANDL    $0x7ff00000, AX
+	CMPL    AX, $0x7ff00000
+	JEQ     not_finite
+	FLDL2E                // F0=log2(e)
+	FMULD   x+0(FP), F0   // F0=x*log2(e)
+	FMOVD   F0, F1        // F0=x*log2(e), F1=x*log2(e)
+	FRNDINT               // F0=int(x*log2(e)), F1=x*log2(e)
+	FSUBD   F0, F1        // F0=int(x*log2(e)), F1=x*log2(e)-int(x*log2(e))
+	FXCHD   F0, F1        // F0=x*log2(e)-int(x*log2(e)), F1=int(x*log2(e))
+	F2XM1                 // F0=2**(x*log2(e)-int(x*log2(e)))-1, F1=int(x*log2(e))
+	FLD1                  // F0=1, F1=2**(x*log2(e)-int(x*log2(e)))-1, F2=int(x*log2(e))
+	FADDDP  F0, F1        // F0=2**(x*log2(e)-int(x*log2(e))), F1=int(x*log2(e))
+	FSCALE                // F0=e**x, F1=int(x*log2(e))
+	FMOVDP  F0, F1        // F0=e**x
+	FLD1                  // F0=1, F1=e**x
+	FSUBDP  F0, F1        // F0=e**x-1 
+	FMOVDP  F0, ret+8(FP)
+	RET
+not_finite:
+// test bits for -Inf
+	MOVL    x_hi+4(FP), BX
+	MOVL    x_lo+0(FP), CX
+	CMPL    BX, $0xfff00000
+	JNE     not_neginf
+	CMPL    CX, $0
+	JNE     not_neginf
+	FLD1                 // F0=1
+	FCHS                 // F0=-1
+	FMOVDP  F0, ret+8(FP)
+	RET
+not_neginf:
+	MOVL    CX, ret_lo+8(FP)
+	MOVL    BX, ret_hi+12(FP)
+	RET
diff --git a/src/math/expm1_amd64.s b/src/math/expm1_amd64.s
new file mode 100644
index 0000000..b7d5a3b
--- /dev/null
+++ b/src/math/expm1_amd64.s
@@ -0,0 +1,8 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+TEXT ·Expm1(SB),NOSPLIT,$0
+	JMP ·expm1(SB)
diff --git a/src/pkg/math/expm1_amd64p32.s b/src/math/expm1_amd64p32.s
similarity index 100%
rename from src/pkg/math/expm1_amd64p32.s
rename to src/math/expm1_amd64p32.s
diff --git a/src/math/expm1_arm.s b/src/math/expm1_arm.s
new file mode 100644
index 0000000..5f80d87
--- /dev/null
+++ b/src/math/expm1_arm.s
@@ -0,0 +1,8 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+TEXT ·Expm1(SB),NOSPLIT,$0
+	B ·expm1(SB)
diff --git a/src/pkg/math/export_test.go b/src/math/export_test.go
similarity index 100%
rename from src/pkg/math/export_test.go
rename to src/math/export_test.go
diff --git a/src/pkg/math/floor.go b/src/math/floor.go
similarity index 100%
rename from src/pkg/math/floor.go
rename to src/math/floor.go
diff --git a/src/math/floor_386.s b/src/math/floor_386.s
new file mode 100644
index 0000000..31c9b17
--- /dev/null
+++ b/src/math/floor_386.s
@@ -0,0 +1,46 @@
+// Copyright 2010 The Go 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 Ceil(x float64) float64
+TEXT ·Ceil(SB),NOSPLIT,$0
+	FMOVD   x+0(FP), F0  // F0=x
+	FSTCW   -2(SP)       // save old Control Word
+	MOVW    -2(SP), AX
+	ANDW    $0xf3ff, AX
+	ORW     $0x0800, AX  // Rounding Control set to +Inf
+	MOVW    AX, -4(SP)   // store new Control Word
+	FLDCW   -4(SP)       // load new Control Word
+	FRNDINT              // F0=Ceil(x)
+	FLDCW   -2(SP)       // load old Control Word
+	FMOVDP  F0, ret+8(FP)
+	RET
+
+// func Floor(x float64) float64
+TEXT ·Floor(SB),NOSPLIT,$0
+	FMOVD   x+0(FP), F0  // F0=x
+	FSTCW   -2(SP)       // save old Control Word
+	MOVW    -2(SP), AX
+	ANDW    $0xf3ff, AX
+	ORW     $0x0400, AX  // Rounding Control set to -Inf
+	MOVW    AX, -4(SP)   // store new Control Word
+	FLDCW   -4(SP)       // load new Control Word
+	FRNDINT              // F0=Floor(x)
+	FLDCW   -2(SP)       // load old Control Word
+	FMOVDP  F0, ret+8(FP)
+	RET
+
+// func Trunc(x float64) float64
+TEXT ·Trunc(SB),NOSPLIT,$0
+	FMOVD   x+0(FP), F0  // F0=x
+	FSTCW   -2(SP)       // save old Control Word
+	MOVW    -2(SP), AX
+	ORW     $0x0c00, AX  // Rounding Control set to truncate
+	MOVW    AX, -4(SP)   // store new Control Word
+	FLDCW   -4(SP)       // load new Control Word
+	FRNDINT              // F0=Trunc(x)
+	FLDCW   -2(SP)       // load old Control Word
+	FMOVDP  F0, ret+8(FP)
+	RET
diff --git a/src/math/floor_amd64.s b/src/math/floor_amd64.s
new file mode 100644
index 0000000..67b7cde
--- /dev/null
+++ b/src/math/floor_amd64.s
@@ -0,0 +1,76 @@
+// Copyright 2012 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+#define Big		0x4330000000000000 // 2**52
+
+// func Floor(x float64) float64
+TEXT ·Floor(SB),NOSPLIT,$0
+	MOVQ	x+0(FP), AX
+	MOVQ	$~(1<<63), DX // sign bit mask
+	ANDQ	AX,DX // DX = |x|
+	SUBQ	$1,DX
+	MOVQ    $(Big - 1), CX // if |x| >= 2**52-1 or IsNaN(x) or |x| == 0, return x
+	CMPQ	DX,CX
+	JAE     isBig_floor
+	MOVQ	AX, X0 // X0 = x
+	CVTTSD2SQ	X0, AX
+	CVTSQ2SD	AX, X1 // X1 = float(int(x))
+	CMPSD	X1, X0, 1 // compare LT; X0 = 0xffffffffffffffff or 0
+	MOVSD	$(-1.0), X2
+	ANDPD	X2, X0 // if x < float(int(x)) {X0 = -1} else {X0 = 0}
+	ADDSD	X1, X0
+	MOVSD	X0, ret+8(FP)
+	RET
+isBig_floor:
+	MOVQ    AX, ret+8(FP) // return x
+	RET
+
+// func Ceil(x float64) float64
+TEXT ·Ceil(SB),NOSPLIT,$0
+	MOVQ	x+0(FP), AX
+	MOVQ	$~(1<<63), DX // sign bit mask
+	MOVQ	AX, BX // BX = copy of x
+	ANDQ    DX, BX // BX = |x|
+	MOVQ    $Big, CX // if |x| >= 2**52 or IsNaN(x), return x
+	CMPQ    BX, CX
+	JAE     isBig_ceil
+	MOVQ	AX, X0 // X0 = x
+	MOVQ	DX, X2 // X2 = sign bit mask
+	CVTTSD2SQ	X0, AX
+	ANDNPD	X0, X2 // X2 = sign
+	CVTSQ2SD	AX, X1	// X1 = float(int(x))
+	CMPSD	X1, X0, 2 // compare LE; X0 = 0xffffffffffffffff or 0
+	ORPD	X2, X1 // if X1 = 0.0, incorporate sign
+	MOVSD	$1.0, X3
+	ANDNPD	X3, X0
+	ORPD	X2, X0 // if float(int(x)) <= x {X0 = 1} else {X0 = -0}
+	ADDSD	X1, X0
+	MOVSD	X0, ret+8(FP)
+	RET
+isBig_ceil:
+	MOVQ	AX, ret+8(FP)
+	RET
+
+// func Trunc(x float64) float64
+TEXT ·Trunc(SB),NOSPLIT,$0
+	MOVQ	x+0(FP), AX
+	MOVQ	$~(1<<63), DX // sign bit mask
+	MOVQ	AX, BX // BX = copy of x
+	ANDQ    DX, BX // BX = |x|
+	MOVQ    $Big, CX // if |x| >= 2**52 or IsNaN(x), return x
+	CMPQ    BX, CX
+	JAE     isBig_trunc
+	MOVQ	AX, X0
+	MOVQ	DX, X2 // X2 = sign bit mask
+	CVTTSD2SQ	X0, AX
+	ANDNPD	X0, X2 // X2 = sign
+	CVTSQ2SD	AX, X0 // X0 = float(int(x))
+	ORPD	X2, X0 // if X0 = 0.0, incorporate sign
+	MOVSD	X0, ret+8(FP)
+	RET
+isBig_trunc:
+	MOVQ    AX, ret+8(FP) // return x
+	RET
diff --git a/src/pkg/math/floor_amd64p32.s b/src/math/floor_amd64p32.s
similarity index 100%
rename from src/pkg/math/floor_amd64p32.s
rename to src/math/floor_amd64p32.s
diff --git a/src/math/floor_arm.s b/src/math/floor_arm.s
new file mode 100644
index 0000000..5909176
--- /dev/null
+++ b/src/math/floor_arm.s
@@ -0,0 +1,14 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+TEXT ·Floor(SB),NOSPLIT,$0
+	B	·floor(SB)
+
+TEXT ·Ceil(SB),NOSPLIT,$0
+	B	·ceil(SB)
+
+TEXT ·Trunc(SB),NOSPLIT,$0
+	B	·trunc(SB)
diff --git a/src/pkg/math/frexp.go b/src/math/frexp.go
similarity index 100%
rename from src/pkg/math/frexp.go
rename to src/math/frexp.go
diff --git a/src/math/frexp_386.s b/src/math/frexp_386.s
new file mode 100644
index 0000000..5bff7e2
--- /dev/null
+++ b/src/math/frexp_386.s
@@ -0,0 +1,25 @@
+// Copyright 2010 The Go 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 Frexp(f float64) (frac float64, exp int)
+TEXT ·Frexp(SB),NOSPLIT,$0
+	FMOVD   f+0(FP), F0   // F0=f
+	FXAM
+	FSTSW   AX
+	SAHF
+	JNP     nan_zero_inf
+	JCS     nan_zero_inf
+	FXTRACT               // F0=f (0<=f<1), F1=e
+	FMULD  $(0.5), F0     // F0=f (0.5<=f<1), F1=e
+	FMOVDP  F0, frac+8(FP)   // F0=e
+	FLD1                  // F0=1, F1=e
+	FADDDP  F0, F1        // F0=e+1
+	FMOVLP  F0, exp+16(FP)  // (int=int32)
+	RET
+nan_zero_inf:
+	FMOVDP  F0, frac+8(FP)   // F0=e
+	MOVL    $0, exp+16(FP)  // exp=0
+	RET
diff --git a/src/math/frexp_amd64.s b/src/math/frexp_amd64.s
new file mode 100644
index 0000000..93a3210
--- /dev/null
+++ b/src/math/frexp_amd64.s
@@ -0,0 +1,8 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+TEXT ·Frexp(SB),NOSPLIT,$0
+	JMP ·frexp(SB)
diff --git a/src/pkg/math/frexp_amd64p32.s b/src/math/frexp_amd64p32.s
similarity index 100%
rename from src/pkg/math/frexp_amd64p32.s
rename to src/math/frexp_amd64p32.s
diff --git a/src/math/frexp_arm.s b/src/math/frexp_arm.s
new file mode 100644
index 0000000..7842eca
--- /dev/null
+++ b/src/math/frexp_arm.s
@@ -0,0 +1,8 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+TEXT ·Frexp(SB),NOSPLIT,$0
+	B ·frexp(SB)
diff --git a/src/pkg/math/gamma.go b/src/math/gamma.go
similarity index 100%
rename from src/pkg/math/gamma.go
rename to src/math/gamma.go
diff --git a/src/pkg/math/hypot.go b/src/math/hypot.go
similarity index 100%
rename from src/pkg/math/hypot.go
rename to src/math/hypot.go
diff --git a/src/math/hypot_386.s b/src/math/hypot_386.s
new file mode 100644
index 0000000..d321f46
--- /dev/null
+++ b/src/math/hypot_386.s
@@ -0,0 +1,59 @@
+// Copyright 2010 The Go 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 Hypot(p, q float64) float64
+TEXT ·Hypot(SB),NOSPLIT,$0
+// test bits for not-finite
+	MOVL    p_hi+4(FP), AX   // high word p
+	ANDL    $0x7ff00000, AX
+	CMPL    AX, $0x7ff00000
+	JEQ     not_finite
+	MOVL    q_hi+12(FP), AX   // high word q
+	ANDL    $0x7ff00000, AX
+	CMPL    AX, $0x7ff00000
+	JEQ     not_finite
+	FMOVD   p+0(FP), F0  // F0=p
+	FABS                 // F0=|p|
+	FMOVD   q+8(FP), F0  // F0=q, F1=|p|
+	FABS                 // F0=|q|, F1=|p|
+	FUCOMI  F0, F1       // compare F0 to F1
+	JCC     2(PC)        // jump if F0 >= F1
+	FXCHD   F0, F1       // F0=|p| (larger), F1=|q| (smaller)
+	FTST                 // compare F0 to 0
+	FSTSW	AX
+	ANDW    $0x4000, AX
+	JNE     10(PC)       // jump if F0 = 0
+	FXCHD   F0, F1       // F0=q (smaller), F1=p (larger)
+	FDIVD   F1, F0       // F0=q(=q/p), F1=p
+	FMULD   F0, F0       // F0=q*q, F1=p
+	FLD1                 // F0=1, F1=q*q, F2=p
+	FADDDP  F0, F1       // F0=1+q*q, F1=p
+	FSQRT                // F0=sqrt(1+q*q), F1=p
+	FMULDP  F0, F1       // F0=p*sqrt(1+q*q)
+	FMOVDP  F0, ret+16(FP)
+	RET
+	FMOVDP  F0, F1       // F0=0
+	FMOVDP  F0, ret+16(FP)
+	RET
+not_finite:
+// test bits for -Inf or +Inf
+	MOVL    p_hi+4(FP), AX  // high word p
+	ORL     p_lo+0(FP), AX  // low word p
+	ANDL    $0x7fffffff, AX
+	CMPL    AX, $0x7ff00000
+	JEQ     is_inf
+	MOVL    q_hi+12(FP), AX  // high word q
+	ORL     q_lo+8(FP), AX   // low word q
+	ANDL    $0x7fffffff, AX
+	CMPL    AX, $0x7ff00000
+	JEQ     is_inf
+	MOVL    $0x7ff80000, ret_hi+20(FP)  // return NaN = 0x7FF8000000000001
+	MOVL    $0x00000001, ret_lo+16(FP)
+	RET
+is_inf:
+	MOVL    AX, ret_hi+20(FP)  // return +Inf = 0x7FF0000000000000
+	MOVL    $0x00000000, ret_lo+16(FP)
+	RET
diff --git a/src/math/hypot_amd64.s b/src/math/hypot_amd64.s
new file mode 100644
index 0000000..a68eebc
--- /dev/null
+++ b/src/math/hypot_amd64.s
@@ -0,0 +1,52 @@
+// Copyright 2010 The Go 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"
+
+#define PosInf 0x7FF0000000000000
+#define NaN 0x7FF8000000000001
+
+// func Hypot(p, q float64) float64
+TEXT ·Hypot(SB),NOSPLIT,$0
+	// test bits for special cases
+	MOVQ    p+0(FP), BX
+	MOVQ    $~(1<<63), AX
+	ANDQ    AX, BX // p = |p|
+	MOVQ    q+8(FP), CX
+	ANDQ    AX, CX // q = |q|
+	MOVQ    $PosInf, AX
+	CMPQ    AX, BX
+	JLE     isInfOrNaN
+	CMPQ    AX, CX
+	JLE     isInfOrNaN
+	// hypot = max * sqrt(1 + (min/max)**2)
+	MOVQ    BX, X0
+	MOVQ    CX, X1
+	ORQ     CX, BX
+	JEQ     isZero
+	MOVAPD  X0, X2
+	MAXSD   X1, X0
+	MINSD   X2, X1
+	DIVSD   X0, X1
+	MULSD   X1, X1
+	ADDSD   $1.0, X1
+	SQRTSD  X1, X1
+	MULSD   X1, X0
+	MOVSD   X0, ret+16(FP)
+	RET
+isInfOrNaN:
+	CMPQ    AX, BX
+	JEQ     isInf
+	CMPQ    AX, CX
+	JEQ     isInf
+	MOVQ    $NaN, AX
+	MOVQ    AX, ret+16(FP) // return NaN
+	RET
+isInf:
+	MOVQ    AX, ret+16(FP) // return +Inf
+	RET
+isZero:
+	MOVQ    $0, AX
+	MOVQ    AX, ret+16(FP) // return 0
+	RET
diff --git a/src/pkg/math/hypot_amd64p32.s b/src/math/hypot_amd64p32.s
similarity index 100%
rename from src/pkg/math/hypot_amd64p32.s
rename to src/math/hypot_amd64p32.s
diff --git a/src/math/hypot_arm.s b/src/math/hypot_arm.s
new file mode 100644
index 0000000..9c8abca
--- /dev/null
+++ b/src/math/hypot_arm.s
@@ -0,0 +1,8 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+TEXT ·Hypot(SB),NOSPLIT,$0
+	B ·hypot(SB)
diff --git a/src/pkg/math/j0.go b/src/math/j0.go
similarity index 100%
rename from src/pkg/math/j0.go
rename to src/math/j0.go
diff --git a/src/pkg/math/j1.go b/src/math/j1.go
similarity index 100%
rename from src/pkg/math/j1.go
rename to src/math/j1.go
diff --git a/src/pkg/math/jn.go b/src/math/jn.go
similarity index 100%
rename from src/pkg/math/jn.go
rename to src/math/jn.go
diff --git a/src/pkg/math/ldexp.go b/src/math/ldexp.go
similarity index 100%
rename from src/pkg/math/ldexp.go
rename to src/math/ldexp.go
diff --git a/src/math/ldexp_386.s b/src/math/ldexp_386.s
new file mode 100644
index 0000000..ac8e8ba
--- /dev/null
+++ b/src/math/ldexp_386.s
@@ -0,0 +1,14 @@
+// Copyright 2010 The Go 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 Ldexp(frac float64, exp int) float64
+TEXT ·Ldexp(SB),NOSPLIT,$0
+	FMOVL   exp+8(FP), F0   // F0=exp
+	FMOVD   frac+0(FP), F0   // F0=frac, F1=e
+	FSCALE                // F0=x*2**e, F1=e
+	FMOVDP  F0, F1        // F0=x*2**e
+	FMOVDP  F0, ret+12(FP)
+	RET
diff --git a/src/math/ldexp_amd64.s b/src/math/ldexp_amd64.s
new file mode 100644
index 0000000..6063a64
--- /dev/null
+++ b/src/math/ldexp_amd64.s
@@ -0,0 +1,8 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+TEXT ·Ldexp(SB),NOSPLIT,$0
+	JMP ·ldexp(SB)
diff --git a/src/pkg/math/ldexp_amd64p32.s b/src/math/ldexp_amd64p32.s
similarity index 100%
rename from src/pkg/math/ldexp_amd64p32.s
rename to src/math/ldexp_amd64p32.s
diff --git a/src/math/ldexp_arm.s b/src/math/ldexp_arm.s
new file mode 100644
index 0000000..fcffa2e
--- /dev/null
+++ b/src/math/ldexp_arm.s
@@ -0,0 +1,8 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+TEXT ·Ldexp(SB),NOSPLIT,$0
+	B ·ldexp(SB)
diff --git a/src/pkg/math/lgamma.go b/src/math/lgamma.go
similarity index 100%
rename from src/pkg/math/lgamma.go
rename to src/math/lgamma.go
diff --git a/src/pkg/math/log.go b/src/math/log.go
similarity index 100%
rename from src/pkg/math/log.go
rename to src/math/log.go
diff --git a/src/pkg/math/log10.go b/src/math/log10.go
similarity index 100%
rename from src/pkg/math/log10.go
rename to src/math/log10.go
diff --git a/src/math/log10_386.s b/src/math/log10_386.s
new file mode 100644
index 0000000..2897f3c
--- /dev/null
+++ b/src/math/log10_386.s
@@ -0,0 +1,21 @@
+// Copyright 2010 The Go 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 Log10(x float64) float64
+TEXT ·Log10(SB),NOSPLIT,$0
+	FLDLG2               // F0=log10(2)
+	FMOVD   x+0(FP), F0  // F0=x, F1=log10(2)
+	FYL2X                // F0=log10(x)=log2(x)*log10(2)
+	FMOVDP  F0, ret+8(FP)
+	RET
+
+// func Log2(x float64) float64
+TEXT ·Log2(SB),NOSPLIT,$0
+	FLD1                 // F0=1
+	FMOVD   x+0(FP), F0  // F0=x, F1=1
+	FYL2X                // F0=log2(x)
+	FMOVDP  F0, ret+8(FP)
+	RET
diff --git a/src/math/log10_amd64.s b/src/math/log10_amd64.s
new file mode 100644
index 0000000..8382ba7
--- /dev/null
+++ b/src/math/log10_amd64.s
@@ -0,0 +1,11 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+TEXT ·Log10(SB),NOSPLIT,$0
+	JMP ·log10(SB)
+
+TEXT ·Log2(SB),NOSPLIT,$0
+	JMP ·log2(SB)
diff --git a/src/pkg/math/log10_amd64p32.s b/src/math/log10_amd64p32.s
similarity index 100%
rename from src/pkg/math/log10_amd64p32.s
rename to src/math/log10_amd64p32.s
diff --git a/src/math/log10_arm.s b/src/math/log10_arm.s
new file mode 100644
index 0000000..dbcb835
--- /dev/null
+++ b/src/math/log10_arm.s
@@ -0,0 +1,11 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+TEXT ·Log10(SB),NOSPLIT,$0
+	B ·log10(SB)
+
+TEXT ·Log2(SB),NOSPLIT,$0
+	B ·log2(SB)
diff --git a/src/pkg/math/log1p.go b/src/math/log1p.go
similarity index 100%
rename from src/pkg/math/log1p.go
rename to src/math/log1p.go
diff --git a/src/math/log1p_386.s b/src/math/log1p_386.s
new file mode 100644
index 0000000..1c2d683
--- /dev/null
+++ b/src/math/log1p_386.s
@@ -0,0 +1,27 @@
+// Copyright 2010 The Go 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 Log1p(x float64) float64
+TEXT ·Log1p(SB),NOSPLIT,$0
+	FMOVD   $(2.928932188134524e-01), F0
+	FMOVD   x+0(FP), F0  // F0=x, F1=1-sqrt(2)/2 = 0.29289321881345247559915564
+	FABS                 // F0=|x|, F1=1-sqrt(2)/2
+	FUCOMPP F0, F1       // compare F0 to F1
+	FSTSW   AX
+	FLDLN2               // F0=log(2)
+	ANDW    $0x0100, AX
+	JEQ     use_fyl2x    // jump if F0 >= F1
+	FMOVD   x+0(FP), F0  // F0=x, F1=log(2)
+	FYL2XP1              // F0=log(1+x)=log2(1+x)*log(2)
+	FMOVDP  F0, ret+8(FP)
+	RET
+use_fyl2x:
+	FLD1                 // F0=1, F2=log(2)
+	FADDD   x+0(FP), F0  // F0=1+x, F1=log(2)
+	FYL2X                // F0=log(1+x)=log2(1+x)*log(2)
+	FMOVDP  F0, ret+8(FP)
+	RET
+
diff --git a/src/math/log1p_amd64.s b/src/math/log1p_amd64.s
new file mode 100644
index 0000000..1e58fb1
--- /dev/null
+++ b/src/math/log1p_amd64.s
@@ -0,0 +1,8 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+TEXT ·Log1p(SB),NOSPLIT,$0
+	JMP ·log1p(SB)
diff --git a/src/pkg/math/log1p_amd64p32.s b/src/math/log1p_amd64p32.s
similarity index 100%
rename from src/pkg/math/log1p_amd64p32.s
rename to src/math/log1p_amd64p32.s
diff --git a/src/math/log1p_arm.s b/src/math/log1p_arm.s
new file mode 100644
index 0000000..95d5496
--- /dev/null
+++ b/src/math/log1p_arm.s
@@ -0,0 +1,8 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+TEXT ·Log1p(SB),NOSPLIT,$0
+	B ·log1p(SB)
diff --git a/src/math/log_386.s b/src/math/log_386.s
new file mode 100644
index 0000000..ff998af
--- /dev/null
+++ b/src/math/log_386.s
@@ -0,0 +1,13 @@
+// Copyright 2010 The Go 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 Log(x float64) float64
+TEXT ·Log(SB),NOSPLIT,$0
+	FLDLN2               // F0=log(2)
+	FMOVD   x+0(FP), F0  // F0=x, F1=log(2)
+	FYL2X                // F0=log(x)=log2(x)*log(2)
+	FMOVDP  F0, ret+8(FP)
+	RET
diff --git a/src/math/log_amd64.s b/src/math/log_amd64.s
new file mode 100644
index 0000000..84c60ab
--- /dev/null
+++ b/src/math/log_amd64.s
@@ -0,0 +1,111 @@
+// Copyright 2010 The Go 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"
+
+#define HSqrt2 7.07106781186547524401e-01 // sqrt(2)/2
+#define Ln2Hi  6.93147180369123816490e-01 // 0x3fe62e42fee00000
+#define Ln2Lo  1.90821492927058770002e-10 // 0x3dea39ef35793c76
+#define L1     6.666666666666735130e-01   // 0x3FE5555555555593
+#define L2     3.999999999940941908e-01   // 0x3FD999999997FA04
+#define L3     2.857142874366239149e-01   // 0x3FD2492494229359
+#define L4     2.222219843214978396e-01   // 0x3FCC71C51D8E78AF
+#define L5     1.818357216161805012e-01   // 0x3FC7466496CB03DE
+#define L6     1.531383769920937332e-01   // 0x3FC39A09D078C69F
+#define L7     1.479819860511658591e-01   // 0x3FC2F112DF3E5244
+#define NaN    0x7FF8000000000001
+#define NegInf 0xFFF0000000000000
+#define PosInf 0x7FF0000000000000
+
+// func Log(x float64) float64
+TEXT ·Log(SB),NOSPLIT,$0
+	// test bits for special cases
+	MOVQ    x+0(FP), BX
+	MOVQ    $~(1<<63), AX // sign bit mask
+	ANDQ    BX, AX
+	JEQ     isZero
+	MOVQ    $0, AX
+	CMPQ    AX, BX
+	JGT     isNegative
+	MOVQ    $PosInf, AX
+	CMPQ    AX, BX
+	JLE     isInfOrNaN
+	// f1, ki := math.Frexp(x); k := float64(ki)
+	MOVQ    BX, X0
+	MOVQ    $0x000FFFFFFFFFFFFF, AX
+	MOVQ    AX, X2
+	ANDPD   X0, X2
+	MOVSD   $0.5, X0 // 0x3FE0000000000000
+	ORPD    X0, X2 // X2= f1
+	SHRQ    $52, BX
+	ANDL    $0x7FF, BX
+	SUBL    $0x3FE, BX
+	CVTSL2SD BX, X1 // x1= k, x2= f1
+	// if f1 < math.Sqrt2/2 { k -= 1; f1 *= 2 }
+	MOVSD   $HSqrt2, X0 // x0= 0.7071, x1= k, x2= f1
+	CMPSD   X2, X0, 5 // cmpnlt; x0= 0 or ^0, x1= k, x2 = f1
+	MOVSD   $1.0, X3 // x0= 0 or ^0, x1= k, x2 = f1, x3= 1
+	ANDPD   X0, X3 // x0= 0 or ^0, x1= k, x2 = f1, x3= 0 or 1
+	SUBSD   X3, X1 // x0= 0 or ^0, x1= k, x2 = f1, x3= 0 or 1
+	MOVSD   $1.0, X0 // x0= 1, x1= k, x2= f1, x3= 0 or 1
+	ADDSD   X0, X3 // x0= 1, x1= k, x2= f1, x3= 1 or 2
+	MULSD   X3, X2 // x0= 1, x1= k, x2= f1
+	// f := f1 - 1
+	SUBSD   X0, X2 // x1= k, x2= f
+	// s := f / (2 + f)
+	MOVSD   $2.0, X0
+	ADDSD   X2, X0
+	MOVAPD  X2, X3
+	DIVSD   X0, X3 // x1=k, x2= f, x3= s
+	// s2 := s * s
+	MOVAPD  X3, X4 // x1= k, x2= f, x3= s
+	MULSD   X4, X4 // x1= k, x2= f, x3= s, x4= s2
+	// s4 := s2 * s2
+	MOVAPD  X4, X5 // x1= k, x2= f, x3= s, x4= s2
+	MULSD   X5, X5 // x1= k, x2= f, x3= s, x4= s2, x5= s4
+	// t1 := s2 * (L1 + s4*(L3+s4*(L5+s4*L7)))
+	MOVSD   $L7, X6
+	MULSD   X5, X6
+	ADDSD   $L5, X6
+	MULSD   X5, X6
+	ADDSD   $L3, X6
+	MULSD   X5, X6
+	ADDSD   $L1, X6
+	MULSD   X6, X4 // x1= k, x2= f, x3= s, x4= t1, x5= s4
+	// t2 := s4 * (L2 + s4*(L4+s4*L6))
+	MOVSD   $L6, X6
+	MULSD   X5, X6
+	ADDSD   $L4, X6
+	MULSD   X5, X6
+	ADDSD   $L2, X6
+	MULSD   X6, X5 // x1= k, x2= f, x3= s, x4= t1, x5= t2
+	// R := t1 + t2
+	ADDSD   X5, X4 // x1= k, x2= f, x3= s, x4= R
+	// hfsq := 0.5 * f * f
+	MOVSD   $0.5, X0
+	MULSD   X2, X0
+	MULSD   X2, X0 // x0= hfsq, x1= k, x2= f, x3= s, x4= R
+	// return k*Ln2Hi - ((hfsq - (s*(hfsq+R) + k*Ln2Lo)) - f)
+	ADDSD   X0, X4 // x0= hfsq, x1= k, x2= f, x3= s, x4= hfsq+R
+	MULSD   X4, X3 // x0= hfsq, x1= k, x2= f, x3= s*(hfsq+R)
+	MOVSD   $Ln2Lo, X4
+	MULSD   X1, X4 // x4= k*Ln2Lo
+	ADDSD   X4, X3 // x0= hfsq, x1= k, x2= f, x3= s*(hfsq+R)+k*Ln2Lo
+	SUBSD   X3, X0 // x0= hfsq-(s*(hfsq+R)+k*Ln2Lo), x1= k, x2= f
+	SUBSD   X2, X0 // x0= (hfsq-(s*(hfsq+R)+k*Ln2Lo))-f, x1= k
+	MULSD   $Ln2Hi, X1 // x0= (hfsq-(s*(hfsq+R)+k*Ln2Lo))-f, x1= k*Ln2Hi
+	SUBSD   X0, X1 // x1= k*Ln2Hi-((hfsq-(s*(hfsq+R)+k*Ln2Lo))-f)
+  	MOVSD   X1, ret+8(FP)
+	RET
+isInfOrNaN:
+	MOVQ    BX, ret+8(FP) // +Inf or NaN, return x
+	RET
+isNegative:
+	MOVQ    $NaN, AX
+	MOVQ    AX, ret+8(FP) // return NaN
+	RET
+isZero:
+	MOVQ    $NegInf, AX
+	MOVQ    AX, ret+8(FP) // return -Inf
+	RET
diff --git a/src/pkg/math/log_amd64p32.s b/src/math/log_amd64p32.s
similarity index 100%
rename from src/pkg/math/log_amd64p32.s
rename to src/math/log_amd64p32.s
diff --git a/src/math/log_arm.s b/src/math/log_arm.s
new file mode 100644
index 0000000..e21d036
--- /dev/null
+++ b/src/math/log_arm.s
@@ -0,0 +1,8 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+TEXT ·Log(SB),NOSPLIT,$0
+	B ·log(SB)
diff --git a/src/pkg/math/logb.go b/src/math/logb.go
similarity index 100%
rename from src/pkg/math/logb.go
rename to src/math/logb.go
diff --git a/src/pkg/math/mod.go b/src/math/mod.go
similarity index 100%
rename from src/pkg/math/mod.go
rename to src/math/mod.go
diff --git a/src/math/mod_386.s b/src/math/mod_386.s
new file mode 100644
index 0000000..10ad98b
--- /dev/null
+++ b/src/math/mod_386.s
@@ -0,0 +1,17 @@
+// Copyright 2010 The Go 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 Mod(x, y float64) float64
+TEXT ·Mod(SB),NOSPLIT,$0
+	FMOVD   y+8(FP), F0  // F0=y
+	FMOVD   x+0(FP), F0  // F0=x, F1=y
+	FPREM                // F0=reduced_x, F1=y
+	FSTSW   AX           // AX=status word
+	ANDW    $0x0400, AX
+	JNE     -3(PC)       // jump if reduction incomplete
+	FMOVDP  F0, F1       // F0=x-q*y
+	FMOVDP  F0, ret+16(FP)
+	RET
diff --git a/src/math/mod_amd64.s b/src/math/mod_amd64.s
new file mode 100644
index 0000000..f99dbe2
--- /dev/null
+++ b/src/math/mod_amd64.s
@@ -0,0 +1,8 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+TEXT ·Mod(SB),NOSPLIT,$0
+	JMP ·mod(SB)
diff --git a/src/pkg/math/mod_amd64p32.s b/src/math/mod_amd64p32.s
similarity index 100%
rename from src/pkg/math/mod_amd64p32.s
rename to src/math/mod_amd64p32.s
diff --git a/src/math/mod_arm.s b/src/math/mod_arm.s
new file mode 100644
index 0000000..5afb359
--- /dev/null
+++ b/src/math/mod_arm.s
@@ -0,0 +1,8 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+TEXT ·Mod(SB),NOSPLIT,$0
+	B ·mod(SB)
diff --git a/src/pkg/math/modf.go b/src/math/modf.go
similarity index 100%
rename from src/pkg/math/modf.go
rename to src/math/modf.go
diff --git a/src/math/modf_386.s b/src/math/modf_386.s
new file mode 100644
index 0000000..3debd3b
--- /dev/null
+++ b/src/math/modf_386.s
@@ -0,0 +1,21 @@
+// Copyright 2010 The Go 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 Modf(f float64) (int float64, frac float64)
+TEXT ·Modf(SB),NOSPLIT,$0
+	FMOVD   f+0(FP), F0  // F0=f
+	FMOVD   F0, F1       // F0=f, F1=f
+	FSTCW   -2(SP)       // save old Control Word
+	MOVW    -2(SP), AX
+	ORW     $0x0c00, AX  // Rounding Control set to truncate
+	MOVW    AX, -4(SP)   // store new Control Word
+	FLDCW   -4(SP)       // load new Control Word
+	FRNDINT              // F0=trunc(f), F1=f
+	FLDCW   -2(SP)       // load old Control Word
+	FSUBD   F0, F1       // F0=trunc(f), F1=f-trunc(f)
+	FMOVDP  F0, int+8(FP)  // F0=f-trunc(f)
+	FMOVDP  F0, frac+16(FP)
+	RET
diff --git a/src/math/modf_amd64.s b/src/math/modf_amd64.s
new file mode 100644
index 0000000..701cf72
--- /dev/null
+++ b/src/math/modf_amd64.s
@@ -0,0 +1,8 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+TEXT ·Modf(SB),NOSPLIT,$0
+	JMP ·modf(SB)
diff --git a/src/pkg/math/modf_amd64p32.s b/src/math/modf_amd64p32.s
similarity index 100%
rename from src/pkg/math/modf_amd64p32.s
rename to src/math/modf_amd64p32.s
diff --git a/src/math/modf_arm.s b/src/math/modf_arm.s
new file mode 100644
index 0000000..ea3c8dc
--- /dev/null
+++ b/src/math/modf_arm.s
@@ -0,0 +1,8 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+TEXT ·Modf(SB),NOSPLIT,$0
+	B ·modf(SB)
diff --git a/src/math/nextafter.go b/src/math/nextafter.go
new file mode 100644
index 0000000..bbb1399
--- /dev/null
+++ b/src/math/nextafter.go
@@ -0,0 +1,47 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package math
+
+// Nextafter32 returns the next representable float32 value after x towards y.
+// Special cases:
+//	Nextafter32(x, x)   = x
+//      Nextafter32(NaN, y) = NaN
+//      Nextafter32(x, NaN) = NaN
+func Nextafter32(x, y float32) (r float32) {
+	switch {
+	case IsNaN(float64(x)) || IsNaN(float64(y)): // special case
+		r = float32(NaN())
+	case x == y:
+		r = x
+	case x == 0:
+		r = float32(Copysign(float64(Float32frombits(1)), float64(y)))
+	case (y > x) == (x > 0):
+		r = Float32frombits(Float32bits(x) + 1)
+	default:
+		r = Float32frombits(Float32bits(x) - 1)
+	}
+	return
+}
+
+// Nextafter returns the next representable float64 value after x towards y.
+// Special cases:
+//	Nextafter64(x, x)   = x
+//      Nextafter64(NaN, y) = NaN
+//      Nextafter64(x, NaN) = NaN
+func Nextafter(x, y float64) (r float64) {
+	switch {
+	case IsNaN(x) || IsNaN(y): // special case
+		r = NaN()
+	case x == y:
+		r = x
+	case x == 0:
+		r = Copysign(Float64frombits(1), y)
+	case (y > x) == (x > 0):
+		r = Float64frombits(Float64bits(x) + 1)
+	default:
+		r = Float64frombits(Float64bits(x) - 1)
+	}
+	return
+}
diff --git a/src/pkg/math/pow.go b/src/math/pow.go
similarity index 100%
rename from src/pkg/math/pow.go
rename to src/math/pow.go
diff --git a/src/pkg/math/pow10.go b/src/math/pow10.go
similarity index 100%
rename from src/pkg/math/pow10.go
rename to src/math/pow10.go
diff --git a/src/pkg/math/rand/example_test.go b/src/math/rand/example_test.go
similarity index 100%
rename from src/pkg/math/rand/example_test.go
rename to src/math/rand/example_test.go
diff --git a/src/pkg/math/rand/exp.go b/src/math/rand/exp.go
similarity index 100%
rename from src/pkg/math/rand/exp.go
rename to src/math/rand/exp.go
diff --git a/src/pkg/math/rand/normal.go b/src/math/rand/normal.go
similarity index 100%
rename from src/pkg/math/rand/normal.go
rename to src/math/rand/normal.go
diff --git a/src/pkg/math/rand/rand.go b/src/math/rand/rand.go
similarity index 100%
rename from src/pkg/math/rand/rand.go
rename to src/math/rand/rand.go
diff --git a/src/pkg/math/rand/rand_test.go b/src/math/rand/rand_test.go
similarity index 100%
rename from src/pkg/math/rand/rand_test.go
rename to src/math/rand/rand_test.go
diff --git a/src/pkg/math/rand/regress_test.go b/src/math/rand/regress_test.go
similarity index 100%
rename from src/pkg/math/rand/regress_test.go
rename to src/math/rand/regress_test.go
diff --git a/src/pkg/math/rand/rng.go b/src/math/rand/rng.go
similarity index 100%
rename from src/pkg/math/rand/rng.go
rename to src/math/rand/rng.go
diff --git a/src/pkg/math/rand/zipf.go b/src/math/rand/zipf.go
similarity index 100%
rename from src/pkg/math/rand/zipf.go
rename to src/math/rand/zipf.go
diff --git a/src/pkg/math/remainder.go b/src/math/remainder.go
similarity index 100%
rename from src/pkg/math/remainder.go
rename to src/math/remainder.go
diff --git a/src/math/remainder_386.s b/src/math/remainder_386.s
new file mode 100644
index 0000000..318fa2c
--- /dev/null
+++ b/src/math/remainder_386.s
@@ -0,0 +1,17 @@
+// Copyright 2010 The Go 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 Remainder(x, y float64) float64
+TEXT ·Remainder(SB),NOSPLIT,$0
+	FMOVD   y+8(FP), F0  // F0=y
+	FMOVD   x+0(FP), F0  // F0=x, F1=y
+	FPREM1               // F0=reduced_x, F1=y
+	FSTSW   AX           // AX=status word
+	ANDW    $0x0400, AX
+	JNE     -3(PC)       // jump if reduction incomplete
+	FMOVDP  F0, F1       // F0=x-q*y
+	FMOVDP  F0, ret+16(FP)
+	RET
diff --git a/src/math/remainder_amd64.s b/src/math/remainder_amd64.s
new file mode 100644
index 0000000..f7fda99
--- /dev/null
+++ b/src/math/remainder_amd64.s
@@ -0,0 +1,8 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+TEXT ·Remainder(SB),NOSPLIT,$0
+	JMP ·remainder(SB)
diff --git a/src/pkg/math/remainder_amd64p32.s b/src/math/remainder_amd64p32.s
similarity index 100%
rename from src/pkg/math/remainder_amd64p32.s
rename to src/math/remainder_amd64p32.s
diff --git a/src/math/remainder_arm.s b/src/math/remainder_arm.s
new file mode 100644
index 0000000..1ae597a
--- /dev/null
+++ b/src/math/remainder_arm.s
@@ -0,0 +1,8 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+TEXT ·Remainder(SB),NOSPLIT,$0
+	B ·remainder(SB)
diff --git a/src/pkg/math/signbit.go b/src/math/signbit.go
similarity index 100%
rename from src/pkg/math/signbit.go
rename to src/math/signbit.go
diff --git a/src/pkg/math/sin.go b/src/math/sin.go
similarity index 100%
rename from src/pkg/math/sin.go
rename to src/math/sin.go
diff --git a/src/math/sin_386.s b/src/math/sin_386.s
new file mode 100644
index 0000000..ccc8e64
--- /dev/null
+++ b/src/math/sin_386.s
@@ -0,0 +1,47 @@
+// Copyright 2009 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+// func Cos(x float64) float64
+TEXT ·Cos(SB),NOSPLIT,$0
+	FMOVD   x+0(FP), F0  // F0=x
+	FCOS                 // F0=cos(x) if -2**63 < x < 2**63
+	FSTSW   AX           // AX=status word
+	ANDW    $0x0400, AX
+	JNE     3(PC)        // jump if x outside range
+	FMOVDP  F0, ret+8(FP)
+	RET
+	FLDPI                // F0=Pi, F1=x
+	FADDD   F0, F0       // F0=2*Pi, F1=x
+	FXCHD   F0, F1       // F0=x, F1=2*Pi
+	FPREM1               // F0=reduced_x, F1=2*Pi
+	FSTSW   AX           // AX=status word
+	ANDW    $0x0400, AX
+	JNE     -3(PC)       // jump if reduction incomplete
+	FMOVDP  F0, F1       // F0=reduced_x
+	FCOS                 // F0=cos(reduced_x)
+	FMOVDP  F0, ret+8(FP)
+	RET
+	
+// func Sin(x float64) float64
+TEXT ·Sin(SB),NOSPLIT,$0
+	FMOVD   x+0(FP), F0  // F0=x
+	FSIN                 // F0=sin(x) if -2**63 < x < 2**63
+	FSTSW   AX           // AX=status word
+	ANDW    $0x0400, AX
+	JNE     3(PC)        // jump if x outside range
+	FMOVDP  F0, ret+8(FP)
+	RET
+	FLDPI                // F0=Pi, F1=x
+	FADDD   F0, F0       // F0=2*Pi, F1=x
+	FXCHD   F0, F1       // F0=x, F1=2*Pi
+	FPREM1               // F0=reduced_x, F1=2*Pi
+	FSTSW   AX           // AX=status word
+	ANDW    $0x0400, AX
+	JNE     -3(PC)       // jump if reduction incomplete
+	FMOVDP  F0, F1       // F0=reduced_x
+	FSIN                 // F0=sin(reduced_x)
+	FMOVDP  F0, ret+8(FP)
+	RET
diff --git a/src/math/sin_amd64.s b/src/math/sin_amd64.s
new file mode 100644
index 0000000..0c33cec
--- /dev/null
+++ b/src/math/sin_amd64.s
@@ -0,0 +1,11 @@
+// Copyright 2010 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+TEXT ·Sin(SB),NOSPLIT,$0
+	JMP	·sin(SB)
+
+TEXT ·Cos(SB),NOSPLIT,$0
+	JMP	·cos(SB)
diff --git a/src/pkg/math/sin_amd64p32.s b/src/math/sin_amd64p32.s
similarity index 100%
rename from src/pkg/math/sin_amd64p32.s
rename to src/math/sin_amd64p32.s
diff --git a/src/math/sin_arm.s b/src/math/sin_arm.s
new file mode 100644
index 0000000..467af3d
--- /dev/null
+++ b/src/math/sin_arm.s
@@ -0,0 +1,11 @@
+// Copyright 2010 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+TEXT ·Sin(SB),NOSPLIT,$0
+	B	·sin(SB)
+
+TEXT ·Cos(SB),NOSPLIT,$0
+	B	·cos(SB)
diff --git a/src/pkg/math/sincos.go b/src/math/sincos.go
similarity index 100%
rename from src/pkg/math/sincos.go
rename to src/math/sincos.go
diff --git a/src/math/sincos_386.s b/src/math/sincos_386.s
new file mode 100644
index 0000000..83af501
--- /dev/null
+++ b/src/math/sincos_386.s
@@ -0,0 +1,28 @@
+// Copyright 2010 The Go 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 Sincos(x float64) (sin, cos float64)
+TEXT ·Sincos(SB),NOSPLIT,$0
+	FMOVD   x+0(FP), F0  // F0=x
+	FSINCOS              // F0=cos(x), F1=sin(x) if -2**63 < x < 2**63
+	FSTSW   AX           // AX=status word
+	ANDW    $0x0400, AX
+	JNE     4(PC)        // jump if x outside range
+	FMOVDP  F0, cos+16(FP) // F0=sin(x)
+	FMOVDP  F0, sin+8(FP)
+	RET
+	FLDPI                // F0=Pi, F1=x
+	FADDD   F0, F0       // F0=2*Pi, F1=x
+	FXCHD   F0, F1       // F0=x, F1=2*Pi
+	FPREM1               // F0=reduced_x, F1=2*Pi
+	FSTSW   AX           // AX=status word
+	ANDW    $0x0400, AX
+	JNE     -3(PC)       // jump if reduction incomplete
+	FMOVDP  F0, F1       // F0=reduced_x
+	FSINCOS              // F0=cos(reduced_x), F1=sin(reduced_x)
+	FMOVDP  F0, cos+16(FP) // F0=sin(reduced_x)
+	FMOVDP  F0, sin+8(FP)
+	RET
diff --git a/src/math/sincos_amd64.s b/src/math/sincos_amd64.s
new file mode 100644
index 0000000..59bf55f
--- /dev/null
+++ b/src/math/sincos_amd64.s
@@ -0,0 +1,142 @@
+// Copyright 2010 The Go 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"
+
+// The method is based on a paper by Naoki Shibata: "Efficient evaluation
+// methods of elementary functions suitable for SIMD computation", Proc.
+// of International Supercomputing Conference 2010 (ISC'10), pp. 25 -- 32
+// (May 2010). The paper is available at
+// http://www.springerlink.com/content/340228x165742104/
+//
+// The original code and the constants below are from the author's
+// implementation available at http://freshmeat.net/projects/sleef.
+// The README file says, "The software is in public domain.
+// You can use the software without any obligation."
+//
+// This code is a simplified version of the original.
+
+#define PosOne 0x3FF0000000000000
+#define PosInf 0x7FF0000000000000
+#define NaN    0x7FF8000000000001
+#define PI4A 0.7853981554508209228515625 // pi/4 split into three parts
+#define PI4B 0.794662735614792836713604629039764404296875e-8
+#define PI4C 0.306161699786838294306516483068750264552437361480769e-16
+#define M4PI 1.273239544735162542821171882678754627704620361328125 // 4/pi
+#define T0 1.0
+#define T1 -8.33333333333333333333333e-02 // (-1.0/12)
+#define T2 2.77777777777777777777778e-03 // (+1.0/360)
+#define T3 -4.96031746031746031746032e-05 // (-1.0/20160)
+#define T4 5.51146384479717813051146e-07 // (+1.0/1814400)
+
+// func Sincos(d float64) (sin, cos float64)
+TEXT ·Sincos(SB),NOSPLIT,$0
+	// test for special cases
+	MOVQ    $~(1<<63), DX // sign bit mask
+	MOVQ    x+0(FP), BX
+	ANDQ    BX, DX
+	JEQ     isZero
+	MOVQ    $PosInf, AX
+	CMPQ    AX, DX
+	JLE     isInfOrNaN
+	// Reduce argument
+	MOVQ    BX, X7 // x7= d
+	MOVQ    DX, X0 // x0= |d|
+	MOVSD   $M4PI, X2
+	MULSD   X0, X2
+	CVTTSD2SQ X2, BX // bx= q
+	MOVQ    $1, AX
+	ANDQ    BX, AX
+	ADDQ    BX, AX
+	CVTSQ2SD AX, X2
+	MOVSD   $PI4A, X3
+	MULSD   X2, X3
+	SUBSD   X3, X0
+	MOVSD   $PI4B, X3
+	MULSD   X2, X3
+	SUBSD   X3, X0
+	MOVSD   $PI4C, X3
+	MULSD   X2, X3
+	SUBSD   X3, X0
+	MULSD   $0.125, X0 // x0= x, x7= d, bx= q
+	// Evaluate Taylor series
+	MULSD   X0, X0
+	MOVSD   $T4, X2
+	MULSD   X0, X2
+	ADDSD   $T3, X2
+	MULSD   X0, X2
+	ADDSD   $T2, X2
+	MULSD   X0, X2
+	ADDSD   $T1, X2
+	MULSD   X0, X2
+	ADDSD   $T0, X2
+	MULSD   X2, X0 // x0= x, x7= d, bx= q
+	// Apply double angle formula
+	MOVSD   $4.0, X2
+	SUBSD   X0, X2
+	MULSD   X2, X0
+	MOVSD   $4.0, X2
+	SUBSD   X0, X2
+	MULSD   X2, X0
+	MOVSD   $4.0, X2
+	SUBSD   X0, X2
+	MULSD   X2, X0
+	MULSD   $0.5, X0 // x0= x, x7= d, bx= q
+	// sin = sqrt((2 - x) * x)
+	MOVSD   $2.0, X2
+	SUBSD   X0, X2
+	MULSD   X0, X2
+	SQRTSD  X2, X2 // x0= x, x2= z, x7= d, bx= q
+	// cos = 1 - x
+	MOVSD   $1.0, X1
+	SUBSD   X0, X1 // x1= x, x2= z, x7= d, bx= q
+	// if ((q + 1) & 2) != 0 { sin, cos = cos, sin }
+	MOVQ    $1, DX
+	ADDQ    BX, DX
+	ANDQ    $2, DX
+	SHRQ    $1, DX
+	SUBQ	$1, DX
+	MOVQ    DX, X3
+	// sin = (y & z) | (^y & x)
+	MOVAPD  X2, X0
+	ANDPD   X3, X0 // x0= sin
+	MOVAPD  X3, X4
+	ANDNPD  X1, X4
+	ORPD    X4, X0 // x0= sin, x1= x, x2= z, x3= y, x7= d, bx= q
+	// cos = (y & x) | (^y & z)
+	ANDPD   X3, X1 // x1= cos
+	ANDNPD  X2, X3
+	ORPD    X3, X1 // x0= sin, x1= cos, x7= d, bx= q
+	// if ((q & 4) != 0) != (d < 0) { sin = -sin }
+	MOVQ    BX, AX
+	MOVQ    $61, CX
+	SHLQ    CX, AX
+	MOVQ    AX, X3
+	XORPD   X7, X3
+	MOVQ    $(1<<63), AX
+	MOVQ    AX, X2 // x2= -0.0
+	ANDPD   X2, X3
+	ORPD    X3, X0 // x0= sin, x1= cos, x2= -0.0, bx= q
+	// if ((q + 2) & 4) != 0 { cos = -cos }
+	MOVQ    $2, AX
+	ADDQ    AX, BX
+	MOVQ    $61, CX
+	SHLQ    CX, BX
+	MOVQ    BX, X3
+	ANDPD   X2, X3
+	ORPD    X3, X1 // x0= sin, x1= cos
+	// return (sin, cos)
+	MOVSD   X0, sin+8(FP)
+	MOVSD   X1, cos+16(FP)
+	RET
+isZero: // return (±0.0, 1.0)
+	MOVQ    BX, sin+8(FP)
+	MOVQ    $PosOne, AX
+	MOVQ    AX, cos+16(FP)
+	RET
+isInfOrNaN: // return (NaN, NaN)
+	MOVQ    $NaN, AX
+	MOVQ    AX, sin+8(FP)
+	MOVQ    AX, cos+16(FP)
+	RET
diff --git a/src/pkg/math/sincos_amd64p32.s b/src/math/sincos_amd64p32.s
similarity index 100%
rename from src/pkg/math/sincos_amd64p32.s
rename to src/math/sincos_amd64p32.s
diff --git a/src/math/sincos_arm.s b/src/math/sincos_arm.s
new file mode 100644
index 0000000..9fe0482
--- /dev/null
+++ b/src/math/sincos_arm.s
@@ -0,0 +1,8 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+TEXT ·Sincos(SB),NOSPLIT,$0
+	B ·sincos(SB)
diff --git a/src/pkg/math/sinh.go b/src/math/sinh.go
similarity index 100%
rename from src/pkg/math/sinh.go
rename to src/math/sinh.go
diff --git a/src/math/sqrt.go b/src/math/sqrt.go
new file mode 100644
index 0000000..fdc8699
--- /dev/null
+++ b/src/math/sqrt.go
@@ -0,0 +1,143 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package math
+
+// The original C code and the long comment below are
+// from FreeBSD's /usr/src/lib/msun/src/e_sqrt.c and
+// came with this notice.  The go code is a simplified
+// version of the original C.
+//
+// ====================================================
+// Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
+//
+// Developed at SunPro, a Sun Microsystems, Inc. business.
+// Permission to use, copy, modify, and distribute this
+// software is freely granted, provided that this notice
+// is preserved.
+// ====================================================
+//
+// __ieee754_sqrt(x)
+// Return correctly rounded sqrt.
+//           -----------------------------------------
+//           | Use the hardware sqrt if you have one |
+//           -----------------------------------------
+// Method:
+//   Bit by bit method using integer arithmetic. (Slow, but portable)
+//   1. Normalization
+//      Scale x to y in [1,4) with even powers of 2:
+//      find an integer k such that  1 <= (y=x*2**(2k)) < 4, then
+//              sqrt(x) = 2**k * sqrt(y)
+//   2. Bit by bit computation
+//      Let q  = sqrt(y) truncated to i bit after binary point (q = 1),
+//           i                                                   0
+//                                     i+1         2
+//          s  = 2*q , and      y  =  2   * ( y - q  ).          (1)
+//           i      i            i                 i
+//
+//      To compute q    from q , one checks whether
+//                  i+1       i
+//
+//                            -(i+1) 2
+//                      (q + 2      )  <= y.                     (2)
+//                        i
+//                                                            -(i+1)
+//      If (2) is false, then q   = q ; otherwise q   = q  + 2      .
+//                             i+1   i             i+1   i
+//
+//      With some algebraic manipulation, it is not difficult to see
+//      that (2) is equivalent to
+//                             -(i+1)
+//                      s  +  2       <= y                       (3)
+//                       i                i
+//
+//      The advantage of (3) is that s  and y  can be computed by
+//                                    i      i
+//      the following recurrence formula:
+//          if (3) is false
+//
+//          s     =  s  ,       y    = y   ;                     (4)
+//           i+1      i          i+1    i
+//
+//      otherwise,
+//                         -i                      -(i+1)
+//          s     =  s  + 2  ,  y    = y  -  s  - 2              (5)
+//           i+1      i          i+1    i     i
+//
+//      One may easily use induction to prove (4) and (5).
+//      Note. Since the left hand side of (3) contain only i+2 bits,
+//            it does not necessary to do a full (53-bit) comparison
+//            in (3).
+//   3. Final rounding
+//      After generating the 53 bits result, we compute one more bit.
+//      Together with the remainder, we can decide whether the
+//      result is exact, bigger than 1/2ulp, or less than 1/2ulp
+//      (it will never equal to 1/2ulp).
+//      The rounding mode can be detected by checking whether
+//      huge + tiny is equal to huge, and whether huge - tiny is
+//      equal to huge for some floating point number "huge" and "tiny".
+//
+//
+// Notes:  Rounding mode detection omitted.  The constants "mask", "shift",
+// and "bias" are found in src/math/bits.go
+
+// Sqrt returns the square root of x.
+//
+// Special cases are:
+//	Sqrt(+Inf) = +Inf
+//	Sqrt(±0) = ±0
+//	Sqrt(x < 0) = NaN
+//	Sqrt(NaN) = NaN
+func Sqrt(x float64) float64
+
+func sqrt(x float64) float64 {
+	// special cases
+	switch {
+	case x == 0 || IsNaN(x) || IsInf(x, 1):
+		return x
+	case x < 0:
+		return NaN()
+	}
+	ix := Float64bits(x)
+	// normalize x
+	exp := int((ix >> shift) & mask)
+	if exp == 0 { // subnormal x
+		for ix&1<<shift == 0 {
+			ix <<= 1
+			exp--
+		}
+		exp++
+	}
+	exp -= bias // unbias exponent
+	ix &^= mask << shift
+	ix |= 1 << shift
+	if exp&1 == 1 { // odd exp, double x to make it even
+		ix <<= 1
+	}
+	exp >>= 1 // exp = exp/2, exponent of square root
+	// generate sqrt(x) bit by bit
+	ix <<= 1
+	var q, s uint64               // q = sqrt(x)
+	r := uint64(1 << (shift + 1)) // r = moving bit from MSB to LSB
+	for r != 0 {
+		t := s + r
+		if t <= ix {
+			s = t + r
+			ix -= t
+			q += r
+		}
+		ix <<= 1
+		r >>= 1
+	}
+	// final rounding
+	if ix != 0 { // remainder, result not exact
+		q += q & 1 // round according to extra bit
+	}
+	ix = q>>1 + uint64(exp-1+bias)<<shift // significand + biased exponent
+	return Float64frombits(ix)
+}
+
+func sqrtC(f float64, r *float64) {
+	*r = sqrt(f)
+}
diff --git a/src/math/sqrt_386.s b/src/math/sqrt_386.s
new file mode 100644
index 0000000..5234a1e
--- /dev/null
+++ b/src/math/sqrt_386.s
@@ -0,0 +1,12 @@
+// Copyright 2009 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+// func Sqrt(x float64) float64	
+TEXT ·Sqrt(SB),NOSPLIT,$0
+	FMOVD   x+0(FP),F0
+	FSQRT
+	FMOVDP  F0,ret+8(FP)
+	RET
diff --git a/src/math/sqrt_amd64.s b/src/math/sqrt_amd64.s
new file mode 100644
index 0000000..443d83f
--- /dev/null
+++ b/src/math/sqrt_amd64.s
@@ -0,0 +1,11 @@
+// Copyright 2009 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+// func Sqrt(x float64) float64
+TEXT ·Sqrt(SB),NOSPLIT,$0
+	SQRTSD x+0(FP), X0
+	MOVSD X0, ret+8(FP)
+	RET
diff --git a/src/pkg/math/sqrt_amd64p32.s b/src/math/sqrt_amd64p32.s
similarity index 100%
rename from src/pkg/math/sqrt_amd64p32.s
rename to src/math/sqrt_amd64p32.s
diff --git a/src/math/sqrt_arm.s b/src/math/sqrt_arm.s
new file mode 100644
index 0000000..4f9dc2e
--- /dev/null
+++ b/src/math/sqrt_arm.s
@@ -0,0 +1,12 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+// func Sqrt(x float64) float64	
+TEXT ·Sqrt(SB),NOSPLIT,$0
+	MOVD   x+0(FP),F0
+	SQRTD  F0,F0
+	MOVD  F0,ret+8(FP)
+	RET
diff --git a/src/pkg/math/tan.go b/src/math/tan.go
similarity index 100%
rename from src/pkg/math/tan.go
rename to src/math/tan.go
diff --git a/src/math/tan_386.s b/src/math/tan_386.s
new file mode 100644
index 0000000..f1bdae1
--- /dev/null
+++ b/src/math/tan_386.s
@@ -0,0 +1,28 @@
+// Copyright 2010 The Go 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 Tan(x float64) float64
+TEXT ·Tan(SB),NOSPLIT,$0
+	FMOVD   x+0(FP), F0  // F0=x
+	FPTAN                // F0=1, F1=tan(x) if -2**63 < x < 2**63
+	FSTSW   AX           // AX=status word
+	ANDW    $0x0400, AX
+	JNE     4(PC)        // jump if x outside range
+	FMOVDP  F0, F0       // F0=tan(x)
+	FMOVDP  F0, ret+8(FP)
+	RET
+	FLDPI                // F0=Pi, F1=x
+	FADDD   F0, F0       // F0=2*Pi, F1=x
+	FXCHD   F0, F1       // F0=x, F1=2*Pi
+	FPREM1               // F0=reduced_x, F1=2*Pi
+	FSTSW   AX           // AX=status word
+	ANDW    $0x0400, AX
+	JNE     -3(PC)       // jump if reduction incomplete
+	FMOVDP  F0, F1       // F0=reduced_x
+	FPTAN                // F0=1, F1=tan(reduced_x)
+	FMOVDP  F0, F0       // F0=tan(reduced_x)
+	FMOVDP  F0, ret+8(FP)
+	RET
diff --git a/src/math/tan_amd64.s b/src/math/tan_amd64.s
new file mode 100644
index 0000000..39aa080
--- /dev/null
+++ b/src/math/tan_amd64.s
@@ -0,0 +1,8 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+TEXT ·Tan(SB),NOSPLIT,$0
+	JMP ·tan(SB)
diff --git a/src/pkg/math/tan_amd64p32.s b/src/math/tan_amd64p32.s
similarity index 100%
rename from src/pkg/math/tan_amd64p32.s
rename to src/math/tan_amd64p32.s
diff --git a/src/math/tan_arm.s b/src/math/tan_arm.s
new file mode 100644
index 0000000..36c7c12
--- /dev/null
+++ b/src/math/tan_arm.s
@@ -0,0 +1,8 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+TEXT ·Tan(SB),NOSPLIT,$0
+	B ·tan(SB)
diff --git a/src/pkg/math/tanh.go b/src/math/tanh.go
similarity index 100%
rename from src/pkg/math/tanh.go
rename to src/math/tanh.go
diff --git a/src/pkg/math/unsafe.go b/src/math/unsafe.go
similarity index 100%
rename from src/pkg/math/unsafe.go
rename to src/math/unsafe.go
diff --git a/src/pkg/mime/grammar.go b/src/mime/grammar.go
similarity index 100%
rename from src/pkg/mime/grammar.go
rename to src/mime/grammar.go
diff --git a/src/pkg/mime/mediatype.go b/src/mime/mediatype.go
similarity index 100%
rename from src/pkg/mime/mediatype.go
rename to src/mime/mediatype.go
diff --git a/src/pkg/mime/mediatype_test.go b/src/mime/mediatype_test.go
similarity index 100%
rename from src/pkg/mime/mediatype_test.go
rename to src/mime/mediatype_test.go
diff --git a/src/mime/multipart/example_test.go b/src/mime/multipart/example_test.go
new file mode 100644
index 0000000..6d6ba81
--- /dev/null
+++ b/src/mime/multipart/example_test.go
@@ -0,0 +1,53 @@
+// 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 multipart_test
+
+import (
+	"fmt"
+	"io"
+	"io/ioutil"
+	"log"
+	"mime"
+	"mime/multipart"
+	"net/mail"
+	"strings"
+)
+
+func ExampleNewReader() {
+	msg := &mail.Message{
+		Header: map[string][]string{
+			"Content-Type": {"multipart/mixed; boundary=foo"},
+		},
+		Body: strings.NewReader(
+			"--foo\r\nFoo: one\r\n\r\nA section\r\n" +
+				"--foo\r\nFoo: two\r\n\r\nAnd another\r\n" +
+				"--foo--\r\n"),
+	}
+	mediaType, params, err := mime.ParseMediaType(msg.Header.Get("Content-Type"))
+	if err != nil {
+		log.Fatal(err)
+	}
+	if strings.HasPrefix(mediaType, "multipart/") {
+		mr := multipart.NewReader(msg.Body, params["boundary"])
+		for {
+			p, err := mr.NextPart()
+			if err == io.EOF {
+				return
+			}
+			if err != nil {
+				log.Fatal(err)
+			}
+			slurp, err := ioutil.ReadAll(p)
+			if err != nil {
+				log.Fatal(err)
+			}
+			fmt.Printf("Part %q: %q\n", p.Header.Get("Foo"), slurp)
+		}
+	}
+
+	// Output:
+	// Part "one": "A section"
+	// Part "two": "And another"
+}
diff --git a/src/pkg/mime/multipart/formdata.go b/src/mime/multipart/formdata.go
similarity index 100%
rename from src/pkg/mime/multipart/formdata.go
rename to src/mime/multipart/formdata.go
diff --git a/src/pkg/mime/multipart/formdata_test.go b/src/mime/multipart/formdata_test.go
similarity index 100%
rename from src/pkg/mime/multipart/formdata_test.go
rename to src/mime/multipart/formdata_test.go
diff --git a/src/mime/multipart/multipart.go b/src/mime/multipart/multipart.go
new file mode 100644
index 0000000..01a667d
--- /dev/null
+++ b/src/mime/multipart/multipart.go
@@ -0,0 +1,348 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+//
+
+/*
+Package multipart implements MIME multipart parsing, as defined in RFC
+2046.
+
+The implementation is sufficient for HTTP (RFC 2388) and the multipart
+bodies generated by popular browsers.
+*/
+package multipart
+
+import (
+	"bufio"
+	"bytes"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"mime"
+	"net/textproto"
+)
+
+var emptyParams = make(map[string]string)
+
+// A Part represents a single part in a multipart body.
+type Part struct {
+	// The headers of the body, if any, with the keys canonicalized
+	// in the same fashion that the Go http.Request headers are.
+	// For example, "foo-bar" changes case to "Foo-Bar"
+	//
+	// As a special case, if the "Content-Transfer-Encoding" header
+	// has a value of "quoted-printable", that header is instead
+	// hidden from this map and the body is transparently decoded
+	// during Read calls.
+	Header textproto.MIMEHeader
+
+	buffer    *bytes.Buffer
+	mr        *Reader
+	bytesRead int
+
+	disposition       string
+	dispositionParams map[string]string
+
+	// r is either a reader directly reading from mr, or it's a
+	// wrapper around such a reader, decoding the
+	// Content-Transfer-Encoding
+	r io.Reader
+}
+
+// FormName returns the name parameter if p has a Content-Disposition
+// of type "form-data".  Otherwise it returns the empty string.
+func (p *Part) FormName() string {
+	// See http://tools.ietf.org/html/rfc2183 section 2 for EBNF
+	// of Content-Disposition value format.
+	if p.dispositionParams == nil {
+		p.parseContentDisposition()
+	}
+	if p.disposition != "form-data" {
+		return ""
+	}
+	return p.dispositionParams["name"]
+}
+
+// FileName returns the filename parameter of the Part's
+// Content-Disposition header.
+func (p *Part) FileName() string {
+	if p.dispositionParams == nil {
+		p.parseContentDisposition()
+	}
+	return p.dispositionParams["filename"]
+}
+
+func (p *Part) parseContentDisposition() {
+	v := p.Header.Get("Content-Disposition")
+	var err error
+	p.disposition, p.dispositionParams, err = mime.ParseMediaType(v)
+	if err != nil {
+		p.dispositionParams = emptyParams
+	}
+}
+
+// NewReader creates a new multipart Reader reading from r using the
+// given MIME boundary.
+//
+// The boundary is usually obtained from the "boundary" parameter of
+// the message's "Content-Type" header. Use mime.ParseMediaType to
+// parse such headers.
+func NewReader(r io.Reader, boundary string) *Reader {
+	b := []byte("\r\n--" + boundary + "--")
+	return &Reader{
+		bufReader:        bufio.NewReader(r),
+		nl:               b[:2],
+		nlDashBoundary:   b[:len(b)-2],
+		dashBoundaryDash: b[2:],
+		dashBoundary:     b[2 : len(b)-2],
+	}
+}
+
+func newPart(mr *Reader) (*Part, error) {
+	bp := &Part{
+		Header: make(map[string][]string),
+		mr:     mr,
+		buffer: new(bytes.Buffer),
+	}
+	if err := bp.populateHeaders(); err != nil {
+		return nil, err
+	}
+	bp.r = partReader{bp}
+	const cte = "Content-Transfer-Encoding"
+	if bp.Header.Get(cte) == "quoted-printable" {
+		bp.Header.Del(cte)
+		bp.r = newQuotedPrintableReader(bp.r)
+	}
+	return bp, nil
+}
+
+func (bp *Part) populateHeaders() error {
+	r := textproto.NewReader(bp.mr.bufReader)
+	header, err := r.ReadMIMEHeader()
+	if err == nil {
+		bp.Header = header
+	}
+	return err
+}
+
+// Read reads the body of a part, after its headers and before the
+// next part (if any) begins.
+func (p *Part) Read(d []byte) (n int, err error) {
+	return p.r.Read(d)
+}
+
+// partReader implements io.Reader by reading raw bytes directly from the
+// wrapped *Part, without doing any Transfer-Encoding decoding.
+type partReader struct {
+	p *Part
+}
+
+func (pr partReader) Read(d []byte) (n int, err error) {
+	p := pr.p
+	defer func() {
+		p.bytesRead += n
+	}()
+	if p.buffer.Len() >= len(d) {
+		// Internal buffer of unconsumed data is large enough for
+		// the read request.  No need to parse more at the moment.
+		return p.buffer.Read(d)
+	}
+	peek, err := p.mr.bufReader.Peek(4096) // TODO(bradfitz): add buffer size accessor
+
+	// Look for an immediate empty part without a leading \r\n
+	// before the boundary separator.  Some MIME code makes empty
+	// parts like this. Most browsers, however, write the \r\n
+	// before the subsequent boundary even for empty parts and
+	// won't hit this path.
+	if p.bytesRead == 0 && p.mr.peekBufferIsEmptyPart(peek) {
+		return 0, io.EOF
+	}
+	unexpectedEOF := err == io.EOF
+	if err != nil && !unexpectedEOF {
+		return 0, fmt.Errorf("multipart: Part Read: %v", err)
+	}
+	if peek == nil {
+		panic("nil peek buf")
+	}
+
+	// Search the peek buffer for "\r\n--boundary". If found,
+	// consume everything up to the boundary. If not, consume only
+	// as much of the peek buffer as cannot hold the boundary
+	// string.
+	nCopy := 0
+	foundBoundary := false
+	if idx := bytes.Index(peek, p.mr.nlDashBoundary); idx != -1 {
+		nCopy = idx
+		foundBoundary = true
+	} else if safeCount := len(peek) - len(p.mr.nlDashBoundary); safeCount > 0 {
+		nCopy = safeCount
+	} else if unexpectedEOF {
+		// If we've run out of peek buffer and the boundary
+		// wasn't found (and can't possibly fit), we must have
+		// hit the end of the file unexpectedly.
+		return 0, io.ErrUnexpectedEOF
+	}
+	if nCopy > 0 {
+		if _, err := io.CopyN(p.buffer, p.mr.bufReader, int64(nCopy)); err != nil {
+			return 0, err
+		}
+	}
+	n, err = p.buffer.Read(d)
+	if err == io.EOF && !foundBoundary {
+		// If the boundary hasn't been reached there's more to
+		// read, so don't pass through an EOF from the buffer
+		err = nil
+	}
+	return
+}
+
+func (p *Part) Close() error {
+	io.Copy(ioutil.Discard, p)
+	return nil
+}
+
+// Reader is an iterator over parts in a MIME multipart body.
+// Reader's underlying parser consumes its input as needed.  Seeking
+// isn't supported.
+type Reader struct {
+	bufReader *bufio.Reader
+
+	currentPart *Part
+	partsRead   int
+
+	nl               []byte // "\r\n" or "\n" (set after seeing first boundary line)
+	nlDashBoundary   []byte // nl + "--boundary"
+	dashBoundaryDash []byte // "--boundary--"
+	dashBoundary     []byte // "--boundary"
+}
+
+// NextPart returns the next part in the multipart or an error.
+// When there are no more parts, the error io.EOF is returned.
+func (r *Reader) NextPart() (*Part, error) {
+	if r.currentPart != nil {
+		r.currentPart.Close()
+	}
+
+	expectNewPart := false
+	for {
+		line, err := r.bufReader.ReadSlice('\n')
+		if err == io.EOF && r.isFinalBoundary(line) {
+			// If the buffer ends in "--boundary--" without the
+			// trailing "\r\n", ReadSlice will return an error
+			// (since it's missing the '\n'), but this is a valid
+			// multipart EOF so we need to return io.EOF instead of
+			// a fmt-wrapped one.
+			return nil, io.EOF
+		}
+		if err != nil {
+			return nil, fmt.Errorf("multipart: NextPart: %v", err)
+		}
+
+		if r.isBoundaryDelimiterLine(line) {
+			r.partsRead++
+			bp, err := newPart(r)
+			if err != nil {
+				return nil, err
+			}
+			r.currentPart = bp
+			return bp, nil
+		}
+
+		if r.isFinalBoundary(line) {
+			// Expected EOF
+			return nil, io.EOF
+		}
+
+		if expectNewPart {
+			return nil, fmt.Errorf("multipart: expecting a new Part; got line %q", string(line))
+		}
+
+		if r.partsRead == 0 {
+			// skip line
+			continue
+		}
+
+		// Consume the "\n" or "\r\n" separator between the
+		// body of the previous part and the boundary line we
+		// now expect will follow. (either a new part or the
+		// end boundary)
+		if bytes.Equal(line, r.nl) {
+			expectNewPart = true
+			continue
+		}
+
+		return nil, fmt.Errorf("multipart: unexpected line in Next(): %q", line)
+	}
+}
+
+// isFinalBoundary reports whether line is the final boundary line
+// indicating that all parts are over.
+// It matches `^--boundary--[ \t]*(\r\n)?$`
+func (mr *Reader) isFinalBoundary(line []byte) bool {
+	if !bytes.HasPrefix(line, mr.dashBoundaryDash) {
+		return false
+	}
+	rest := line[len(mr.dashBoundaryDash):]
+	rest = skipLWSPChar(rest)
+	return len(rest) == 0 || bytes.Equal(rest, mr.nl)
+}
+
+func (mr *Reader) isBoundaryDelimiterLine(line []byte) (ret bool) {
+	// http://tools.ietf.org/html/rfc2046#section-5.1
+	//   The boundary delimiter line is then defined as a line
+	//   consisting entirely of two hyphen characters ("-",
+	//   decimal value 45) followed by the boundary parameter
+	//   value from the Content-Type header field, optional linear
+	//   whitespace, and a terminating CRLF.
+	if !bytes.HasPrefix(line, mr.dashBoundary) {
+		return false
+	}
+	rest := line[len(mr.dashBoundary):]
+	rest = skipLWSPChar(rest)
+
+	// On the first part, see our lines are ending in \n instead of \r\n
+	// and switch into that mode if so.  This is a violation of the spec,
+	// but occurs in practice.
+	if mr.partsRead == 0 && len(rest) == 1 && rest[0] == '\n' {
+		mr.nl = mr.nl[1:]
+		mr.nlDashBoundary = mr.nlDashBoundary[1:]
+	}
+	return bytes.Equal(rest, mr.nl)
+}
+
+// peekBufferIsEmptyPart reports whether the provided peek-ahead
+// buffer represents an empty part. It is called only if we've not
+// already read any bytes in this part and checks for the case of MIME
+// software not writing the \r\n on empty parts. Some does, some
+// doesn't.
+//
+// This checks that what follows the "--boundary" is actually the end
+// ("--boundary--" with optional whitespace) or optional whitespace
+// and then a newline, so we don't catch "--boundaryFAKE", in which
+// case the whole line is part of the data.
+func (mr *Reader) peekBufferIsEmptyPart(peek []byte) bool {
+	// End of parts case.
+	// Test whether peek matches `^--boundary--[ \t]*(?:\r\n|$)`
+	if bytes.HasPrefix(peek, mr.dashBoundaryDash) {
+		rest := peek[len(mr.dashBoundaryDash):]
+		rest = skipLWSPChar(rest)
+		return bytes.HasPrefix(rest, mr.nl) || len(rest) == 0
+	}
+	if !bytes.HasPrefix(peek, mr.dashBoundary) {
+		return false
+	}
+	// Test whether rest matches `^[ \t]*\r\n`)
+	rest := peek[len(mr.dashBoundary):]
+	rest = skipLWSPChar(rest)
+	return bytes.HasPrefix(rest, mr.nl)
+}
+
+// skipLWSPChar returns b with leading spaces and tabs removed.
+// RFC 822 defines:
+//    LWSP-char = SPACE / HTAB
+func skipLWSPChar(b []byte) []byte {
+	for len(b) > 0 && (b[0] == ' ' || b[0] == '\t') {
+		b = b[1:]
+	}
+	return b
+}
diff --git a/src/pkg/mime/multipart/multipart_test.go b/src/mime/multipart/multipart_test.go
similarity index 100%
rename from src/pkg/mime/multipart/multipart_test.go
rename to src/mime/multipart/multipart_test.go
diff --git a/src/pkg/mime/multipart/quotedprintable.go b/src/mime/multipart/quotedprintable.go
similarity index 100%
rename from src/pkg/mime/multipart/quotedprintable.go
rename to src/mime/multipart/quotedprintable.go
diff --git a/src/pkg/mime/multipart/quotedprintable_test.go b/src/mime/multipart/quotedprintable_test.go
similarity index 100%
rename from src/pkg/mime/multipart/quotedprintable_test.go
rename to src/mime/multipart/quotedprintable_test.go
diff --git a/src/pkg/mime/multipart/testdata/nested-mime b/src/mime/multipart/testdata/nested-mime
similarity index 100%
rename from src/pkg/mime/multipart/testdata/nested-mime
rename to src/mime/multipart/testdata/nested-mime
diff --git a/src/pkg/mime/multipart/writer.go b/src/mime/multipart/writer.go
similarity index 100%
rename from src/pkg/mime/multipart/writer.go
rename to src/mime/multipart/writer.go
diff --git a/src/mime/multipart/writer_test.go b/src/mime/multipart/writer_test.go
new file mode 100644
index 0000000..ba00c97
--- /dev/null
+++ b/src/mime/multipart/writer_test.go
@@ -0,0 +1,128 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package multipart
+
+import (
+	"bytes"
+	"io/ioutil"
+	"strings"
+	"testing"
+)
+
+func TestWriter(t *testing.T) {
+	fileContents := []byte("my file contents")
+
+	var b bytes.Buffer
+	w := NewWriter(&b)
+	{
+		part, err := w.CreateFormFile("myfile", "my-file.txt")
+		if err != nil {
+			t.Fatalf("CreateFormFile: %v", err)
+		}
+		part.Write(fileContents)
+		err = w.WriteField("key", "val")
+		if err != nil {
+			t.Fatalf("WriteField: %v", err)
+		}
+		part.Write([]byte("val"))
+		err = w.Close()
+		if err != nil {
+			t.Fatalf("Close: %v", err)
+		}
+		s := b.String()
+		if len(s) == 0 {
+			t.Fatal("String: unexpected empty result")
+		}
+		if s[0] == '\r' || s[0] == '\n' {
+			t.Fatal("String: unexpected newline")
+		}
+	}
+
+	r := NewReader(&b, w.Boundary())
+
+	part, err := r.NextPart()
+	if err != nil {
+		t.Fatalf("part 1: %v", err)
+	}
+	if g, e := part.FormName(), "myfile"; g != e {
+		t.Errorf("part 1: want form name %q, got %q", e, g)
+	}
+	slurp, err := ioutil.ReadAll(part)
+	if err != nil {
+		t.Fatalf("part 1: ReadAll: %v", err)
+	}
+	if e, g := string(fileContents), string(slurp); e != g {
+		t.Errorf("part 1: want contents %q, got %q", e, g)
+	}
+
+	part, err = r.NextPart()
+	if err != nil {
+		t.Fatalf("part 2: %v", err)
+	}
+	if g, e := part.FormName(), "key"; g != e {
+		t.Errorf("part 2: want form name %q, got %q", e, g)
+	}
+	slurp, err = ioutil.ReadAll(part)
+	if err != nil {
+		t.Fatalf("part 2: ReadAll: %v", err)
+	}
+	if e, g := "val", string(slurp); e != g {
+		t.Errorf("part 2: want contents %q, got %q", e, g)
+	}
+
+	part, err = r.NextPart()
+	if part != nil || err == nil {
+		t.Fatalf("expected end of parts; got %v, %v", part, err)
+	}
+}
+
+func TestWriterSetBoundary(t *testing.T) {
+	var b bytes.Buffer
+	w := NewWriter(&b)
+	tests := []struct {
+		b  string
+		ok bool
+	}{
+		{"abc", true},
+		{"", false},
+		{"ungültig", false},
+		{"!", false},
+		{strings.Repeat("x", 69), true},
+		{strings.Repeat("x", 70), false},
+		{"bad!ascii!", false},
+		{"my-separator", true},
+	}
+	for i, tt := range tests {
+		err := w.SetBoundary(tt.b)
+		got := err == nil
+		if got != tt.ok {
+			t.Errorf("%d. boundary %q = %v (%v); want %v", i, tt.b, got, err, tt.ok)
+		} else if tt.ok {
+			got := w.Boundary()
+			if got != tt.b {
+				t.Errorf("boundary = %q; want %q", got, tt.b)
+			}
+		}
+	}
+	w.Close()
+	if got := b.String(); !strings.Contains(got, "\r\n--my-separator--\r\n") {
+		t.Errorf("expected my-separator in output. got: %q", got)
+	}
+}
+
+func TestWriterBoundaryGoroutines(t *testing.T) {
+	// Verify there's no data race accessing any lazy boundary if it's used by
+	// different goroutines. This was previously broken by
+	// https://codereview.appspot.com/95760043/ and reverted in
+	// https://codereview.appspot.com/117600043/
+	w := NewWriter(ioutil.Discard)
+	done := make(chan int)
+	go func() {
+		w.CreateFormField("foo")
+		done <- 1
+	}()
+	w.Boundary()
+	<-done
+}
diff --git a/src/pkg/mime/testdata/test.types b/src/mime/testdata/test.types
similarity index 100%
rename from src/pkg/mime/testdata/test.types
rename to src/mime/testdata/test.types
diff --git a/src/pkg/mime/testdata/test.types.plan9 b/src/mime/testdata/test.types.plan9
similarity index 100%
rename from src/pkg/mime/testdata/test.types.plan9
rename to src/mime/testdata/test.types.plan9
diff --git a/src/mime/type.go b/src/mime/type.go
new file mode 100644
index 0000000..ffda1f0
--- /dev/null
+++ b/src/mime/type.go
@@ -0,0 +1,121 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package mime implements parts of the MIME spec.
+package mime
+
+import (
+	"fmt"
+	"strings"
+	"sync"
+)
+
+var (
+	mimeLock       sync.RWMutex
+	mimeTypesLower = map[string]string{
+		".css":  "text/css; charset=utf-8",
+		".gif":  "image/gif",
+		".htm":  "text/html; charset=utf-8",
+		".html": "text/html; charset=utf-8",
+		".jpg":  "image/jpeg",
+		".js":   "application/x-javascript",
+		".pdf":  "application/pdf",
+		".png":  "image/png",
+		".xml":  "text/xml; charset=utf-8",
+	}
+	mimeTypes = clone(mimeTypesLower)
+)
+
+func clone(m map[string]string) map[string]string {
+	m2 := make(map[string]string, len(m))
+	for k, v := range m {
+		m2[k] = v
+		if strings.ToLower(k) != k {
+			panic("keys in mimeTypesLower must be lowercase")
+		}
+	}
+	return m2
+}
+
+var once sync.Once // guards initMime
+
+// TypeByExtension returns the MIME type associated with the file extension ext.
+// The extension ext should begin with a leading dot, as in ".html".
+// When ext has no associated type, TypeByExtension returns "".
+//
+// Extensions are looked up first case-sensitively, then case-insensitively.
+//
+// The built-in table is small but on unix it is augmented by the local
+// system's mime.types file(s) if available under one or more of these
+// names:
+//
+//   /etc/mime.types
+//   /etc/apache2/mime.types
+//   /etc/apache/mime.types
+//
+// On Windows, MIME types are extracted from the registry.
+//
+// Text types have the charset parameter set to "utf-8" by default.
+func TypeByExtension(ext string) string {
+	once.Do(initMime)
+	mimeLock.RLock()
+	defer mimeLock.RUnlock()
+
+	// Case-sensitive lookup.
+	v := mimeTypes[ext]
+	if v != "" {
+		return v
+	}
+
+	// Case-insensitive lookup.
+	// Optimistically assume a short ASCII extension and be
+	// allocation-free in that case.
+	var buf [10]byte
+	lower := buf[:0]
+	const utf8RuneSelf = 0x80 // from utf8 package, but not importing it.
+	for i := 0; i < len(ext); i++ {
+		c := ext[i]
+		if c >= utf8RuneSelf {
+			// Slow path.
+			return mimeTypesLower[strings.ToLower(ext)]
+		}
+		if 'A' <= c && c <= 'Z' {
+			lower = append(lower, c+('a'-'A'))
+		} else {
+			lower = append(lower, c)
+		}
+	}
+	// The conversion from []byte to string doesn't allocate in
+	// a map lookup.
+	return mimeTypesLower[string(lower)]
+}
+
+// AddExtensionType sets the MIME type associated with
+// the extension ext to typ. The extension should begin with
+// a leading dot, as in ".html".
+func AddExtensionType(ext, typ string) error {
+	if !strings.HasPrefix(ext, ".") {
+		return fmt.Errorf(`mime: extension %q misses dot`, ext)
+	}
+	once.Do(initMime)
+	return setExtensionType(ext, typ)
+}
+
+func setExtensionType(extension, mimeType string) error {
+	_, param, err := ParseMediaType(mimeType)
+	if err != nil {
+		return err
+	}
+	if strings.HasPrefix(mimeType, "text/") && param["charset"] == "" {
+		param["charset"] = "utf-8"
+		mimeType = FormatMediaType(mimeType, param)
+	}
+	extLower := strings.ToLower(extension)
+
+	mimeLock.Lock()
+	mimeTypes[extension] = mimeType
+	mimeTypesLower[extLower] = mimeType
+	mimeLock.Unlock()
+	return nil
+}
diff --git a/src/mime/type_plan9.go b/src/mime/type_plan9.go
new file mode 100644
index 0000000..8cbf677
--- /dev/null
+++ b/src/mime/type_plan9.go
@@ -0,0 +1,53 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package mime
+
+import (
+	"bufio"
+	"os"
+	"strings"
+)
+
+var typeFiles = []string{
+	"/sys/lib/mimetypes",
+}
+
+func loadMimeFile(filename string) {
+	f, err := os.Open(filename)
+	if err != nil {
+		return
+	}
+	defer f.Close()
+
+	scanner := bufio.NewScanner(f)
+	for scanner.Scan() {
+		fields := strings.Fields(scanner.Text())
+		if len(fields) <= 2 || fields[0][0] != '.' {
+			continue
+		}
+		if fields[1] == "-" || fields[2] == "-" {
+			continue
+		}
+		setExtensionType(fields[0], fields[1]+"/"+fields[2])
+	}
+	if err := scanner.Err(); err != nil {
+		panic(err)
+	}
+}
+
+func initMime() {
+	for _, filename := range typeFiles {
+		loadMimeFile(filename)
+	}
+}
+
+func initMimeForTests() map[string]string {
+	typeFiles = []string{"testdata/test.types.plan9"}
+	return map[string]string{
+		".t1":  "application/test",
+		".t2":  "text/test; charset=utf-8",
+		".pNg": "image/png",
+	}
+}
diff --git a/src/mime/type_test.go b/src/mime/type_test.go
new file mode 100644
index 0000000..d2d254a
--- /dev/null
+++ b/src/mime/type_test.go
@@ -0,0 +1,54 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package mime
+
+import (
+	"testing"
+)
+
+var typeTests = initMimeForTests()
+
+func TestTypeByExtension(t *testing.T) {
+	for ext, want := range typeTests {
+		val := TypeByExtension(ext)
+		if val != want {
+			t.Errorf("TypeByExtension(%q) = %q, want %q", ext, val, want)
+		}
+	}
+}
+
+func TestTypeByExtensionCase(t *testing.T) {
+	const custom = "test/test; charset=iso-8859-1"
+	const caps = "test/test; WAS=ALLCAPS"
+	if err := AddExtensionType(".TEST", caps); err != nil {
+		t.Fatalf("error %s for AddExtension(%s)", err, custom)
+	}
+	if err := AddExtensionType(".tesT", custom); err != nil {
+		t.Fatalf("error %s for AddExtension(%s)", err, custom)
+	}
+
+	// case-sensitive lookup
+	if got := TypeByExtension(".tesT"); got != custom {
+		t.Fatalf("for .tesT, got %q; want %q", got, custom)
+	}
+	if got := TypeByExtension(".TEST"); got != caps {
+		t.Fatalf("for .TEST, got %q; want %s", got, caps)
+	}
+
+	// case-insensitive
+	if got := TypeByExtension(".TesT"); got != custom {
+		t.Fatalf("for .TesT, got %q; want %q", got, custom)
+	}
+}
+
+func TestLookupMallocs(t *testing.T) {
+	n := testing.AllocsPerRun(10000, func() {
+		TypeByExtension(".html")
+		TypeByExtension(".HtML")
+	})
+	if n > 0 {
+		t.Errorf("allocs = %v; want 0", n)
+	}
+}
diff --git a/src/mime/type_unix.go b/src/mime/type_unix.go
new file mode 100644
index 0000000..3e404cf
--- /dev/null
+++ b/src/mime/type_unix.go
@@ -0,0 +1,60 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris
+
+package mime
+
+import (
+	"bufio"
+	"os"
+	"strings"
+)
+
+var typeFiles = []string{
+	"/etc/mime.types",
+	"/etc/apache2/mime.types",
+	"/etc/apache/mime.types",
+}
+
+func loadMimeFile(filename string) {
+	f, err := os.Open(filename)
+	if err != nil {
+		return
+	}
+	defer f.Close()
+
+	scanner := bufio.NewScanner(f)
+	for scanner.Scan() {
+		fields := strings.Fields(scanner.Text())
+		if len(fields) <= 1 || fields[0][0] == '#' {
+			continue
+		}
+		mimeType := fields[0]
+		for _, ext := range fields[1:] {
+			if ext[0] == '#' {
+				break
+			}
+			setExtensionType("."+ext, mimeType)
+		}
+	}
+	if err := scanner.Err(); err != nil {
+		panic(err)
+	}
+}
+
+func initMime() {
+	for _, filename := range typeFiles {
+		loadMimeFile(filename)
+	}
+}
+
+func initMimeForTests() map[string]string {
+	typeFiles = []string{"testdata/test.types"}
+	return map[string]string{
+		".T1":  "application/test",
+		".t2":  "text/test; charset=utf-8",
+		".png": "image/png",
+	}
+}
diff --git a/src/mime/type_windows.go b/src/mime/type_windows.go
new file mode 100644
index 0000000..ae758d7
--- /dev/null
+++ b/src/mime/type_windows.go
@@ -0,0 +1,63 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package mime
+
+import (
+	"syscall"
+	"unsafe"
+)
+
+func initMime() {
+	var root syscall.Handle
+	rootpathp, _ := syscall.UTF16PtrFromString(`\`)
+	if syscall.RegOpenKeyEx(syscall.HKEY_CLASSES_ROOT, rootpathp,
+		0, syscall.KEY_READ, &root) != nil {
+		return
+	}
+	defer syscall.RegCloseKey(root)
+	var count uint32
+	if syscall.RegQueryInfoKey(root, nil, nil, nil, &count, nil, nil, nil, nil, nil, nil, nil) != nil {
+		return
+	}
+	var buf [1 << 10]uint16
+	for i := uint32(0); i < count; i++ {
+		n := uint32(len(buf))
+		if syscall.RegEnumKeyEx(root, i, &buf[0], &n, nil, nil, nil, nil) != nil {
+			continue
+		}
+		ext := syscall.UTF16ToString(buf[:])
+		if len(ext) < 2 || ext[0] != '.' { // looking for extensions only
+			continue
+		}
+		var h syscall.Handle
+		extpathp, _ := syscall.UTF16PtrFromString(`\` + ext)
+		if syscall.RegOpenKeyEx(
+			syscall.HKEY_CLASSES_ROOT, extpathp,
+			0, syscall.KEY_READ, &h) != nil {
+			continue
+		}
+		var typ uint32
+		n = uint32(len(buf) * 2) // api expects array of bytes, not uint16
+		contenttypep, _ := syscall.UTF16PtrFromString("Content Type")
+		if syscall.RegQueryValueEx(
+			h, contenttypep,
+			nil, &typ, (*byte)(unsafe.Pointer(&buf[0])), &n) != nil {
+			syscall.RegCloseKey(h)
+			continue
+		}
+		syscall.RegCloseKey(h)
+		if typ != syscall.REG_SZ { // null terminated strings only
+			continue
+		}
+		mimeType := syscall.UTF16ToString(buf[:])
+		setExtensionType(ext, mimeType)
+	}
+}
+
+func initMimeForTests() map[string]string {
+	return map[string]string{
+		".PnG": "image/png",
+	}
+}
diff --git a/src/nacltest.bash b/src/nacltest.bash
index e5bbb4b..6220d39 100755
--- a/src/nacltest.bash
+++ b/src/nacltest.bash
@@ -13,8 +13,23 @@
 set -e
 ulimit -c 0
 
+# guess GOARCH if not set
+naclGOARCH=$GOARCH
+if [ -z "$naclGOARCH" ]; then
+	case "$(uname -m)" in
+	x86_64)
+		naclGOARCH=amd64p32
+		;;
+	armv7l) # NativeClient on ARM only supports ARMv7A.
+		naclGOARCH=arm
+		;;
+	i?86)
+		naclGOARCH=386
+		;;
+	esac
+fi
+
 # Check GOARCH.
-naclGOARCH=${GOARCH:-386}
 case "$naclGOARCH" in
 amd64p32)
 	if ! which sel_ldr_x86_64 >/dev/null; then
@@ -28,6 +43,12 @@ amd64p32)
 		exit 1
 	fi
 	;;
+arm)
+	if ! which sel_ldr_arm >/dev/null; then
+		echo 'cannot find sel_ldr_arm' 1>&2
+		exit 1
+	fi
+	;;
 *)
 	echo 'unsupported $GOARCH for nacl: '"$naclGOARCH" 1>&2
 	exit 1
@@ -45,12 +66,14 @@ if [ ! -f make.bash ]; then
 	exit 1
 fi
 GOOS=$GOHOSTOS GOARCH=$GOHOSTARCH ./make.bash
-unset GOROOT
+
+# the builder might have set GOROOT_FINAL.
+export GOROOT=$(pwd)/..
 
 # Build zip file embedded in package syscall.
 gobin=${GOBIN:-$(pwd)/../bin}
-rm -f pkg/syscall/fstest_nacl.go
-GOOS=$GOHOSTOS GOARCH=$GOHOSTARCH $gobin/go run ../misc/nacl/mkzip.go -p syscall -r .. ../misc/nacl/testzip.proto pkg/syscall/fstest_nacl.go
+rm -f syscall/fstest_nacl.go
+GOOS=$GOHOSTOS GOARCH=$GOHOSTARCH $gobin/go run ../misc/nacl/mkzip.go -p syscall -r .. ../misc/nacl/testzip.proto syscall/fstest_nacl.go
 
 # Run standard build and tests.
 export PATH=$(pwd)/../misc/nacl:$PATH
diff --git a/src/net/cgo_android.go b/src/net/cgo_android.go
new file mode 100644
index 0000000..3819ce5
--- /dev/null
+++ b/src/net/cgo_android.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.
+
+// +build cgo,!netgo
+
+package net
+
+//#include <netdb.h>
+import "C"
+
+func cgoAddrInfoFlags() C.int {
+	return C.AI_CANONNAME
+}
diff --git a/src/pkg/net/cgo_bsd.go b/src/net/cgo_bsd.go
similarity index 100%
rename from src/pkg/net/cgo_bsd.go
rename to src/net/cgo_bsd.go
diff --git a/src/net/cgo_linux.go b/src/net/cgo_linux.go
new file mode 100644
index 0000000..4ef2d0c
--- /dev/null
+++ b/src/net/cgo_linux.go
@@ -0,0 +1,22 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !android,cgo,!netgo
+
+package net
+
+/*
+#include <netdb.h>
+*/
+import "C"
+
+func cgoAddrInfoFlags() C.int {
+	// NOTE(rsc): In theory there are approximately balanced
+	// arguments for and against including AI_ADDRCONFIG
+	// in the flags (it includes IPv4 results only on IPv4 systems,
+	// and similarly for IPv6), but in practice setting it causes
+	// getaddrinfo to return the wrong canonical name on Linux.
+	// So definitely leave it out.
+	return C.AI_CANONNAME | C.AI_V4MAPPED | C.AI_ALL
+}
diff --git a/src/pkg/net/cgo_netbsd.go b/src/net/cgo_netbsd.go
similarity index 100%
rename from src/pkg/net/cgo_netbsd.go
rename to src/net/cgo_netbsd.go
diff --git a/src/pkg/net/cgo_openbsd.go b/src/net/cgo_openbsd.go
similarity index 100%
rename from src/pkg/net/cgo_openbsd.go
rename to src/net/cgo_openbsd.go
diff --git a/src/pkg/net/cgo_stub.go b/src/net/cgo_stub.go
similarity index 100%
rename from src/pkg/net/cgo_stub.go
rename to src/net/cgo_stub.go
diff --git a/src/pkg/net/cgo_unix.go b/src/net/cgo_unix.go
similarity index 100%
rename from src/pkg/net/cgo_unix.go
rename to src/net/cgo_unix.go
diff --git a/src/pkg/net/cgo_unix_test.go b/src/net/cgo_unix_test.go
similarity index 100%
rename from src/pkg/net/cgo_unix_test.go
rename to src/net/cgo_unix_test.go
diff --git a/src/net/conn_test.go b/src/net/conn_test.go
new file mode 100644
index 0000000..9c9d1a8
--- /dev/null
+++ b/src/net/conn_test.go
@@ -0,0 +1,124 @@
+// Copyright 2012 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file implements API tests across platforms and will never have a build
+// tag.
+
+package net
+
+import (
+	"os"
+	"runtime"
+	"testing"
+	"time"
+)
+
+var connTests = []struct {
+	net  string
+	addr string
+}{
+	{"tcp", "127.0.0.1:0"},
+	{"unix", testUnixAddr()},
+	{"unixpacket", testUnixAddr()},
+}
+
+// someTimeout is used just to test that net.Conn implementations
+// don't explode when their SetFooDeadline methods are called.
+// It isn't actually used for testing timeouts.
+const someTimeout = 10 * time.Second
+
+func TestConnAndListener(t *testing.T) {
+	for _, tt := range connTests {
+		switch tt.net {
+		case "unix":
+			switch runtime.GOOS {
+			case "nacl", "plan9", "windows":
+				continue
+			}
+		case "unixpacket":
+			switch runtime.GOOS {
+			case "android", "darwin", "nacl", "openbsd", "plan9", "windows":
+				continue
+			case "freebsd": // FreeBSD 8 doesn't support unixpacket
+				continue
+			}
+		}
+
+		ln, err := Listen(tt.net, tt.addr)
+		if err != nil {
+			t.Fatalf("Listen failed: %v", err)
+		}
+		defer func(ln Listener, net, addr string) {
+			ln.Close()
+			switch net {
+			case "unix", "unixpacket":
+				os.Remove(addr)
+			}
+		}(ln, tt.net, tt.addr)
+		if ln.Addr().Network() != tt.net {
+			t.Fatalf("got %v; expected %v", ln.Addr().Network(), tt.net)
+		}
+
+		done := make(chan int)
+		go transponder(t, ln, done)
+
+		c, err := Dial(tt.net, ln.Addr().String())
+		if err != nil {
+			t.Fatalf("Dial failed: %v", err)
+		}
+		defer c.Close()
+		if c.LocalAddr().Network() != tt.net || c.LocalAddr().Network() != tt.net {
+			t.Fatalf("got %v->%v; expected %v->%v", c.LocalAddr().Network(), c.RemoteAddr().Network(), tt.net, tt.net)
+		}
+		c.SetDeadline(time.Now().Add(someTimeout))
+		c.SetReadDeadline(time.Now().Add(someTimeout))
+		c.SetWriteDeadline(time.Now().Add(someTimeout))
+
+		if _, err := c.Write([]byte("CONN TEST")); err != nil {
+			t.Fatalf("Conn.Write failed: %v", err)
+		}
+		rb := make([]byte, 128)
+		if _, err := c.Read(rb); err != nil {
+			t.Fatalf("Conn.Read failed: %v", err)
+		}
+
+		<-done
+	}
+}
+
+func transponder(t *testing.T, ln Listener, done chan<- int) {
+	defer func() { done <- 1 }()
+
+	switch ln := ln.(type) {
+	case *TCPListener:
+		ln.SetDeadline(time.Now().Add(someTimeout))
+	case *UnixListener:
+		ln.SetDeadline(time.Now().Add(someTimeout))
+	}
+	c, err := ln.Accept()
+	if err != nil {
+		t.Errorf("Listener.Accept failed: %v", err)
+		return
+	}
+	defer c.Close()
+	network := ln.Addr().Network()
+	if c.LocalAddr().Network() != network || c.LocalAddr().Network() != network {
+		t.Errorf("got %v->%v; expected %v->%v", c.LocalAddr().Network(), c.RemoteAddr().Network(), network, network)
+		return
+	}
+	c.SetDeadline(time.Now().Add(someTimeout))
+	c.SetReadDeadline(time.Now().Add(someTimeout))
+	c.SetWriteDeadline(time.Now().Add(someTimeout))
+
+	b := make([]byte, 128)
+	n, err := c.Read(b)
+	if err != nil {
+		t.Errorf("Conn.Read failed: %v", err)
+		return
+	}
+	if _, err := c.Write(b[:n]); err != nil {
+		t.Errorf("Conn.Write failed: %v", err)
+		return
+	}
+}
diff --git a/src/net/dial.go b/src/net/dial.go
new file mode 100644
index 0000000..e6f0436
--- /dev/null
+++ b/src/net/dial.go
@@ -0,0 +1,302 @@
+// Copyright 2010 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package net
+
+import (
+	"errors"
+	"time"
+)
+
+// A Dialer contains options for connecting to an address.
+//
+// The zero value for each field is equivalent to dialing
+// without that option. Dialing with the zero value of Dialer
+// is therefore equivalent to just calling the Dial function.
+type Dialer struct {
+	// Timeout is the maximum amount of time a dial will wait for
+	// a connect to complete. If Deadline is also set, it may fail
+	// earlier.
+	//
+	// The default is no timeout.
+	//
+	// With or without a timeout, the operating system may impose
+	// its own earlier timeout. For instance, TCP timeouts are
+	// often around 3 minutes.
+	Timeout time.Duration
+
+	// Deadline is the absolute point in time after which dials
+	// will fail. If Timeout is set, it may fail earlier.
+	// Zero means no deadline, or dependent on the operating system
+	// as with the Timeout option.
+	Deadline time.Time
+
+	// LocalAddr is the local address to use when dialing an
+	// address. The address must be of a compatible type for the
+	// network being dialed.
+	// If nil, a local address is automatically chosen.
+	LocalAddr Addr
+
+	// DualStack allows a single dial to attempt to establish
+	// multiple IPv4 and IPv6 connections and to return the first
+	// established connection when the network is "tcp" and the
+	// destination is a host name that has multiple address family
+	// DNS records.
+	DualStack bool
+
+	// KeepAlive specifies the keep-alive period for an active
+	// network connection.
+	// If zero, keep-alives are not enabled. Network protocols
+	// that do not support keep-alives ignore this field.
+	KeepAlive time.Duration
+}
+
+// Return either now+Timeout or Deadline, whichever comes first.
+// Or zero, if neither is set.
+func (d *Dialer) deadline() time.Time {
+	if d.Timeout == 0 {
+		return d.Deadline
+	}
+	timeoutDeadline := time.Now().Add(d.Timeout)
+	if d.Deadline.IsZero() || timeoutDeadline.Before(d.Deadline) {
+		return timeoutDeadline
+	} else {
+		return d.Deadline
+	}
+}
+
+func parseNetwork(net string) (afnet string, proto int, err error) {
+	i := last(net, ':')
+	if i < 0 { // no colon
+		switch net {
+		case "tcp", "tcp4", "tcp6":
+		case "udp", "udp4", "udp6":
+		case "ip", "ip4", "ip6":
+		case "unix", "unixgram", "unixpacket":
+		default:
+			return "", 0, UnknownNetworkError(net)
+		}
+		return net, 0, nil
+	}
+	afnet = net[:i]
+	switch afnet {
+	case "ip", "ip4", "ip6":
+		protostr := net[i+1:]
+		proto, i, ok := dtoi(protostr, 0)
+		if !ok || i != len(protostr) {
+			proto, err = lookupProtocol(protostr)
+			if err != nil {
+				return "", 0, err
+			}
+		}
+		return afnet, proto, nil
+	}
+	return "", 0, UnknownNetworkError(net)
+}
+
+func resolveAddr(op, net, addr string, deadline time.Time) (netaddr, error) {
+	afnet, _, err := parseNetwork(net)
+	if err != nil {
+		return nil, err
+	}
+	if op == "dial" && addr == "" {
+		return nil, errMissingAddress
+	}
+	switch afnet {
+	case "unix", "unixgram", "unixpacket":
+		return ResolveUnixAddr(afnet, addr)
+	}
+	return resolveInternetAddr(afnet, addr, deadline)
+}
+
+// Dial connects to the address on the named network.
+//
+// Known networks are "tcp", "tcp4" (IPv4-only), "tcp6" (IPv6-only),
+// "udp", "udp4" (IPv4-only), "udp6" (IPv6-only), "ip", "ip4"
+// (IPv4-only), "ip6" (IPv6-only), "unix", "unixgram" and
+// "unixpacket".
+//
+// For TCP and UDP networks, addresses have the form host:port.
+// If host is a literal IPv6 address it must be enclosed
+// in square brackets as in "[::1]:80" or "[ipv6-host%zone]:80".
+// The functions JoinHostPort and SplitHostPort manipulate addresses
+// in this form.
+//
+// Examples:
+//	Dial("tcp", "12.34.56.78:80")
+//	Dial("tcp", "google.com:http")
+//	Dial("tcp", "[2001:db8::1]:http")
+//	Dial("tcp", "[fe80::1%lo0]:80")
+//
+// For IP networks, the network must be "ip", "ip4" or "ip6" followed
+// by a colon and a protocol number or name and the addr must be a
+// literal IP address.
+//
+// Examples:
+//	Dial("ip4:1", "127.0.0.1")
+//	Dial("ip6:ospf", "::1")
+//
+// For Unix networks, the address must be a file system path.
+func Dial(network, address string) (Conn, error) {
+	var d Dialer
+	return d.Dial(network, address)
+}
+
+// DialTimeout acts like Dial but takes a timeout.
+// The timeout includes name resolution, if required.
+func DialTimeout(network, address string, timeout time.Duration) (Conn, error) {
+	d := Dialer{Timeout: timeout}
+	return d.Dial(network, address)
+}
+
+// Dial connects to the address on the named network.
+//
+// See func Dial for a description of the network and address
+// parameters.
+func (d *Dialer) Dial(network, address string) (Conn, error) {
+	ra, err := resolveAddr("dial", network, address, d.deadline())
+	if err != nil {
+		return nil, &OpError{Op: "dial", Net: network, Addr: nil, Err: err}
+	}
+	dialer := func(deadline time.Time) (Conn, error) {
+		return dialSingle(network, address, d.LocalAddr, ra.toAddr(), deadline)
+	}
+	if ras, ok := ra.(addrList); ok && d.DualStack && network == "tcp" {
+		dialer = func(deadline time.Time) (Conn, error) {
+			return dialMulti(network, address, d.LocalAddr, ras, deadline)
+		}
+	}
+	c, err := dial(network, ra.toAddr(), dialer, d.deadline())
+	if d.KeepAlive > 0 && err == nil {
+		if tc, ok := c.(*TCPConn); ok {
+			tc.SetKeepAlive(true)
+			tc.SetKeepAlivePeriod(d.KeepAlive)
+			testHookSetKeepAlive()
+		}
+	}
+	return c, err
+}
+
+var testHookSetKeepAlive = func() {} // changed by dial_test.go
+
+// dialMulti attempts to establish connections to each destination of
+// the list of addresses. It will return the first established
+// connection and close the other connections. Otherwise it returns
+// error on the last attempt.
+func dialMulti(net, addr string, la Addr, ras addrList, deadline time.Time) (Conn, error) {
+	type racer struct {
+		Conn
+		error
+	}
+	// Sig controls the flow of dial results on lane. It passes a
+	// token to the next racer and also indicates the end of flow
+	// by using closed channel.
+	sig := make(chan bool, 1)
+	lane := make(chan racer, 1)
+	for _, ra := range ras {
+		go func(ra Addr) {
+			c, err := dialSingle(net, addr, la, ra, deadline)
+			if _, ok := <-sig; ok {
+				lane <- racer{c, err}
+			} else if err == nil {
+				// We have to return the resources
+				// that belong to the other
+				// connections here for avoiding
+				// unnecessary resource starvation.
+				c.Close()
+			}
+		}(ra.toAddr())
+	}
+	defer close(sig)
+	lastErr := errTimeout
+	nracers := len(ras)
+	for nracers > 0 {
+		sig <- true
+		racer := <-lane
+		if racer.error == nil {
+			return racer.Conn, nil
+		}
+		lastErr = racer.error
+		nracers--
+	}
+	return nil, lastErr
+}
+
+// dialSingle attempts to establish and returns a single connection to
+// the destination address.
+func dialSingle(net, addr string, la, ra Addr, deadline time.Time) (c Conn, err error) {
+	if la != nil && la.Network() != ra.Network() {
+		return nil, &OpError{Op: "dial", Net: net, Addr: ra, Err: errors.New("mismatched local address type " + la.Network())}
+	}
+	switch ra := ra.(type) {
+	case *TCPAddr:
+		la, _ := la.(*TCPAddr)
+		c, err = dialTCP(net, la, ra, deadline)
+	case *UDPAddr:
+		la, _ := la.(*UDPAddr)
+		c, err = dialUDP(net, la, ra, deadline)
+	case *IPAddr:
+		la, _ := la.(*IPAddr)
+		c, err = dialIP(net, la, ra, deadline)
+	case *UnixAddr:
+		la, _ := la.(*UnixAddr)
+		c, err = dialUnix(net, la, ra, deadline)
+	default:
+		return nil, &OpError{Op: "dial", Net: net, Addr: ra, Err: &AddrError{Err: "unexpected address type", Addr: addr}}
+	}
+	if err != nil {
+		return nil, err // c is non-nil interface containing nil pointer
+	}
+	return c, nil
+}
+
+// Listen announces on the local network address laddr.
+// The network net must be a stream-oriented network: "tcp", "tcp4",
+// "tcp6", "unix" or "unixpacket".
+// See Dial for the syntax of laddr.
+func Listen(net, laddr string) (Listener, error) {
+	la, err := resolveAddr("listen", net, laddr, noDeadline)
+	if err != nil {
+		return nil, &OpError{Op: "listen", Net: net, Addr: nil, Err: err}
+	}
+	var l Listener
+	switch la := la.toAddr().(type) {
+	case *TCPAddr:
+		l, err = ListenTCP(net, la)
+	case *UnixAddr:
+		l, err = ListenUnix(net, la)
+	default:
+		return nil, &OpError{Op: "listen", Net: net, Addr: la, Err: &AddrError{Err: "unexpected address type", Addr: laddr}}
+	}
+	if err != nil {
+		return nil, err // l is non-nil interface containing nil pointer
+	}
+	return l, nil
+}
+
+// ListenPacket announces on the local network address laddr.
+// The network net must be a packet-oriented network: "udp", "udp4",
+// "udp6", "ip", "ip4", "ip6" or "unixgram".
+// See Dial for the syntax of laddr.
+func ListenPacket(net, laddr string) (PacketConn, error) {
+	la, err := resolveAddr("listen", net, laddr, noDeadline)
+	if err != nil {
+		return nil, &OpError{Op: "listen", Net: net, Addr: nil, Err: err}
+	}
+	var l PacketConn
+	switch la := la.toAddr().(type) {
+	case *UDPAddr:
+		l, err = ListenUDP(net, la)
+	case *IPAddr:
+		l, err = ListenIP(net, la)
+	case *UnixAddr:
+		l, err = ListenUnixgram(net, la)
+	default:
+		return nil, &OpError{Op: "listen", Net: net, Addr: la, Err: &AddrError{Err: "unexpected address type", Addr: laddr}}
+	}
+	if err != nil {
+		return nil, err // l is non-nil interface containing nil pointer
+	}
+	return l, nil
+}
diff --git a/src/pkg/net/dial_gen.go b/src/net/dial_gen.go
similarity index 100%
rename from src/pkg/net/dial_gen.go
rename to src/net/dial_gen.go
diff --git a/src/pkg/net/dial_gen_test.go b/src/net/dial_gen_test.go
similarity index 100%
rename from src/pkg/net/dial_gen_test.go
rename to src/net/dial_gen_test.go
diff --git a/src/net/dial_test.go b/src/net/dial_test.go
new file mode 100644
index 0000000..42898d6
--- /dev/null
+++ b/src/net/dial_test.go
@@ -0,0 +1,548 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package net
+
+import (
+	"bytes"
+	"flag"
+	"fmt"
+	"io"
+	"os"
+	"os/exec"
+	"reflect"
+	"regexp"
+	"runtime"
+	"strconv"
+	"sync"
+	"testing"
+	"time"
+)
+
+func newLocalListener(t *testing.T) Listener {
+	ln, err := Listen("tcp", "127.0.0.1:0")
+	if err != nil {
+		ln, err = Listen("tcp6", "[::1]:0")
+	}
+	if err != nil {
+		t.Fatal(err)
+	}
+	return ln
+}
+
+func TestDialTimeout(t *testing.T) {
+	origBacklog := listenerBacklog
+	defer func() {
+		listenerBacklog = origBacklog
+	}()
+	listenerBacklog = 1
+
+	ln := newLocalListener(t)
+	defer ln.Close()
+
+	errc := make(chan error)
+
+	numConns := listenerBacklog + 100
+
+	// TODO(bradfitz): It's hard to test this in a portable
+	// way. This is unfortunate, but works for now.
+	switch runtime.GOOS {
+	case "linux":
+		// The kernel will start accepting TCP connections before userspace
+		// gets a chance to not accept them, so fire off a bunch to fill up
+		// the kernel's backlog.  Then we test we get a failure after that.
+		for i := 0; i < numConns; i++ {
+			go func() {
+				_, err := DialTimeout("tcp", ln.Addr().String(), 200*time.Millisecond)
+				errc <- err
+			}()
+		}
+	case "darwin", "plan9", "windows":
+		// At least OS X 10.7 seems to accept any number of
+		// connections, ignoring listen's backlog, so resort
+		// to connecting to a hopefully-dead 127/8 address.
+		// Same for windows.
+		//
+		// Use an IANA reserved port (49151) instead of 80, because
+		// on our 386 builder, this Dial succeeds, connecting
+		// to an IIS web server somewhere.  The data center
+		// or VM or firewall must be stealing the TCP connection.
+		//
+		// IANA Service Name and Transport Protocol Port Number Registry
+		// <http://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xml>
+		go func() {
+			c, err := DialTimeout("tcp", "127.0.71.111:49151", 200*time.Millisecond)
+			if err == nil {
+				err = fmt.Errorf("unexpected: connected to %s!", c.RemoteAddr())
+				c.Close()
+			}
+			errc <- err
+		}()
+	default:
+		// TODO(bradfitz):
+		// OpenBSD may have a reject route to 127/8 except 127.0.0.1/32
+		// by default. FreeBSD likely works, but is untested.
+		// TODO(rsc):
+		// The timeout never happens on Windows.  Why?  Issue 3016.
+		t.Skipf("skipping test on %q; untested.", runtime.GOOS)
+	}
+
+	connected := 0
+	for {
+		select {
+		case <-time.After(15 * time.Second):
+			t.Fatal("too slow")
+		case err := <-errc:
+			if err == nil {
+				connected++
+				if connected == numConns {
+					t.Fatal("all connections connected; expected some to time out")
+				}
+			} else {
+				terr, ok := err.(timeout)
+				if !ok {
+					t.Fatalf("got error %q; want error with timeout interface", err)
+				}
+				if !terr.Timeout() {
+					t.Fatalf("got error %q; not a timeout", err)
+				}
+				// Pass. We saw a timeout error.
+				return
+			}
+		}
+	}
+}
+
+func TestSelfConnect(t *testing.T) {
+	if runtime.GOOS == "windows" {
+		// TODO(brainman): do not know why it hangs.
+		t.Skip("skipping known-broken test on windows")
+	}
+
+	// Test that Dial does not honor self-connects.
+	// See the comment in DialTCP.
+
+	// Find a port that would be used as a local address.
+	l, err := Listen("tcp", "127.0.0.1:0")
+	if err != nil {
+		t.Fatal(err)
+	}
+	c, err := Dial("tcp", l.Addr().String())
+	if err != nil {
+		t.Fatal(err)
+	}
+	addr := c.LocalAddr().String()
+	c.Close()
+	l.Close()
+
+	// Try to connect to that address repeatedly.
+	n := 100000
+	if testing.Short() {
+		n = 1000
+	}
+	switch runtime.GOOS {
+	case "darwin", "dragonfly", "freebsd", "netbsd", "openbsd", "plan9", "solaris", "windows":
+		// Non-Linux systems take a long time to figure
+		// out that there is nothing listening on localhost.
+		n = 100
+	}
+	for i := 0; i < n; i++ {
+		c, err := DialTimeout("tcp", addr, time.Millisecond)
+		if err == nil {
+			if c.LocalAddr().String() == addr {
+				t.Errorf("#%d: Dial %q self-connect", i, addr)
+			} else {
+				t.Logf("#%d: Dial %q succeeded - possibly racing with other listener", i, addr)
+			}
+			c.Close()
+		}
+	}
+}
+
+var runErrorTest = flag.Bool("run_error_test", false, "let TestDialError check for dns errors")
+
+type DialErrorTest struct {
+	Net     string
+	Raddr   string
+	Pattern string
+}
+
+var dialErrorTests = []DialErrorTest{
+	{
+		"datakit", "mh/astro/r70",
+		"dial datakit mh/astro/r70: unknown network datakit",
+	},
+	{
+		"tcp", "127.0.0.1:☺",
+		"dial tcp 127.0.0.1:☺: unknown port tcp/☺",
+	},
+	{
+		"tcp", "no-such-name.google.com.:80",
+		"dial tcp no-such-name.google.com.:80: lookup no-such-name.google.com.( on .*)?: no (.*)",
+	},
+	{
+		"tcp", "no-such-name.no-such-top-level-domain.:80",
+		"dial tcp no-such-name.no-such-top-level-domain.:80: lookup no-such-name.no-such-top-level-domain.( on .*)?: no (.*)",
+	},
+	{
+		"tcp", "no-such-name:80",
+		`dial tcp no-such-name:80: lookup no-such-name\.(.*\.)?( on .*)?: no (.*)`,
+	},
+	{
+		"tcp", "mh/astro/r70:http",
+		"dial tcp mh/astro/r70:http: lookup mh/astro/r70: invalid domain name",
+	},
+	{
+		"unix", "/etc/file-not-found",
+		"dial unix /etc/file-not-found: no such file or directory",
+	},
+	{
+		"unix", "/etc/",
+		"dial unix /etc/: (permission denied|socket operation on non-socket|connection refused)",
+	},
+	{
+		"unixpacket", "/etc/file-not-found",
+		"dial unixpacket /etc/file-not-found: no such file or directory",
+	},
+	{
+		"unixpacket", "/etc/",
+		"dial unixpacket /etc/: (permission denied|socket operation on non-socket|connection refused)",
+	},
+}
+
+var duplicateErrorPattern = `dial (.*) dial (.*)`
+
+func TestDialError(t *testing.T) {
+	if !*runErrorTest {
+		t.Logf("test disabled; use -run_error_test to enable")
+		return
+	}
+	for i, tt := range dialErrorTests {
+		c, err := Dial(tt.Net, tt.Raddr)
+		if c != nil {
+			c.Close()
+		}
+		if err == nil {
+			t.Errorf("#%d: nil error, want match for %#q", i, tt.Pattern)
+			continue
+		}
+		s := err.Error()
+		match, _ := regexp.MatchString(tt.Pattern, s)
+		if !match {
+			t.Errorf("#%d: %q, want match for %#q", i, s, tt.Pattern)
+		}
+		match, _ = regexp.MatchString(duplicateErrorPattern, s)
+		if match {
+			t.Errorf("#%d: %q, duplicate error return from Dial", i, s)
+		}
+	}
+}
+
+var invalidDialAndListenArgTests = []struct {
+	net  string
+	addr string
+	err  error
+}{
+	{"foo", "bar", &OpError{Op: "dial", Net: "foo", Addr: nil, Err: UnknownNetworkError("foo")}},
+	{"baz", "", &OpError{Op: "listen", Net: "baz", Addr: nil, Err: UnknownNetworkError("baz")}},
+	{"tcp", "", &OpError{Op: "dial", Net: "tcp", Addr: nil, Err: errMissingAddress}},
+}
+
+func TestInvalidDialAndListenArgs(t *testing.T) {
+	for _, tt := range invalidDialAndListenArgTests {
+		var err error
+		switch tt.err.(*OpError).Op {
+		case "dial":
+			_, err = Dial(tt.net, tt.addr)
+		case "listen":
+			_, err = Listen(tt.net, tt.addr)
+		}
+		if !reflect.DeepEqual(tt.err, err) {
+			t.Fatalf("got %#v; expected %#v", err, tt.err)
+		}
+	}
+}
+
+func TestDialTimeoutFDLeak(t *testing.T) {
+	if runtime.GOOS != "linux" {
+		// TODO(bradfitz): test on other platforms
+		t.Skipf("skipping test on %q", runtime.GOOS)
+	}
+
+	ln := newLocalListener(t)
+	defer ln.Close()
+
+	type connErr struct {
+		conn Conn
+		err  error
+	}
+	dials := listenerBacklog + 100
+	// used to be listenerBacklog + 5, but was found to be unreliable, issue 4384.
+	maxGoodConnect := listenerBacklog + runtime.NumCPU()*10
+	resc := make(chan connErr)
+	for i := 0; i < dials; i++ {
+		go func() {
+			conn, err := DialTimeout("tcp", ln.Addr().String(), 500*time.Millisecond)
+			resc <- connErr{conn, err}
+		}()
+	}
+
+	var firstErr string
+	var ngood int
+	var toClose []io.Closer
+	for i := 0; i < dials; i++ {
+		ce := <-resc
+		if ce.err == nil {
+			ngood++
+			if ngood > maxGoodConnect {
+				t.Errorf("%d good connects; expected at most %d", ngood, maxGoodConnect)
+			}
+			toClose = append(toClose, ce.conn)
+			continue
+		}
+		err := ce.err
+		if firstErr == "" {
+			firstErr = err.Error()
+		} else if err.Error() != firstErr {
+			t.Fatalf("inconsistent error messages: first was %q, then later %q", firstErr, err)
+		}
+	}
+	for _, c := range toClose {
+		c.Close()
+	}
+	for i := 0; i < 100; i++ {
+		if got := numFD(); got < dials {
+			// Test passes.
+			return
+		}
+		time.Sleep(10 * time.Millisecond)
+	}
+	if got := numFD(); got >= dials {
+		t.Errorf("num fds after %d timeouts = %d; want <%d", dials, got, dials)
+	}
+}
+
+func numTCP() (ntcp, nopen, nclose int, err error) {
+	lsof, err := exec.Command("lsof", "-n", "-p", strconv.Itoa(os.Getpid())).Output()
+	if err != nil {
+		return 0, 0, 0, err
+	}
+	ntcp += bytes.Count(lsof, []byte("TCP"))
+	for _, state := range []string{"LISTEN", "SYN_SENT", "SYN_RECEIVED", "ESTABLISHED"} {
+		nopen += bytes.Count(lsof, []byte(state))
+	}
+	for _, state := range []string{"CLOSED", "CLOSE_WAIT", "LAST_ACK", "FIN_WAIT_1", "FIN_WAIT_2", "CLOSING", "TIME_WAIT"} {
+		nclose += bytes.Count(lsof, []byte(state))
+	}
+	return ntcp, nopen, nclose, nil
+}
+
+func TestDialMultiFDLeak(t *testing.T) {
+	t.Skip("flaky test - golang.org/issue/8764")
+
+	if !supportsIPv4 || !supportsIPv6 {
+		t.Skip("neither ipv4 nor ipv6 is supported")
+	}
+
+	halfDeadServer := func(dss *dualStackServer, ln Listener) {
+		for {
+			if c, err := ln.Accept(); err != nil {
+				return
+			} else {
+				// It just keeps established
+				// connections like a half-dead server
+				// does.
+				dss.putConn(c)
+			}
+		}
+	}
+	dss, err := newDualStackServer([]streamListener{
+		{net: "tcp4", addr: "127.0.0.1"},
+		{net: "tcp6", addr: "[::1]"},
+	})
+	if err != nil {
+		t.Fatalf("newDualStackServer failed: %v", err)
+	}
+	defer dss.teardown()
+	if err := dss.buildup(halfDeadServer); err != nil {
+		t.Fatalf("dualStackServer.buildup failed: %v", err)
+	}
+
+	_, before, _, err := numTCP()
+	if err != nil {
+		t.Skipf("skipping test; error finding or running lsof: %v", err)
+	}
+
+	var wg sync.WaitGroup
+	portnum, _, _ := dtoi(dss.port, 0)
+	ras := addrList{
+		// Losers that will fail to connect, see RFC 6890.
+		&TCPAddr{IP: IPv4(198, 18, 0, 254), Port: portnum},
+		&TCPAddr{IP: ParseIP("2001:2::254"), Port: portnum},
+
+		// Winner candidates of this race.
+		&TCPAddr{IP: IPv4(127, 0, 0, 1), Port: portnum},
+		&TCPAddr{IP: IPv6loopback, Port: portnum},
+
+		// Losers that will have established connections.
+		&TCPAddr{IP: IPv4(127, 0, 0, 1), Port: portnum},
+		&TCPAddr{IP: IPv6loopback, Port: portnum},
+	}
+	const T1 = 10 * time.Millisecond
+	const T2 = 2 * T1
+	const N = 10
+	for i := 0; i < N; i++ {
+		wg.Add(1)
+		go func() {
+			defer wg.Done()
+			if c, err := dialMulti("tcp", "fast failover test", nil, ras, time.Now().Add(T1)); err == nil {
+				c.Close()
+			}
+		}()
+	}
+	wg.Wait()
+	time.Sleep(T2)
+
+	ntcp, after, nclose, err := numTCP()
+	if err != nil {
+		t.Skipf("skipping test; error finding or running lsof: %v", err)
+	}
+	t.Logf("tcp sessions: %v, open sessions: %v, closing sessions: %v", ntcp, after, nclose)
+
+	if after != before {
+		t.Fatalf("got %v open sessions; expected %v", after, before)
+	}
+}
+
+func numFD() int {
+	if runtime.GOOS == "linux" {
+		f, err := os.Open("/proc/self/fd")
+		if err != nil {
+			panic(err)
+		}
+		defer f.Close()
+		names, err := f.Readdirnames(0)
+		if err != nil {
+			panic(err)
+		}
+		return len(names)
+	}
+	// All tests using this should be skipped anyway, but:
+	panic("numFDs not implemented on " + runtime.GOOS)
+}
+
+func TestDialer(t *testing.T) {
+	ln, err := Listen("tcp4", "127.0.0.1:0")
+	if err != nil {
+		t.Fatalf("Listen failed: %v", err)
+	}
+	defer ln.Close()
+	ch := make(chan error, 1)
+	go func() {
+		c, err := ln.Accept()
+		if err != nil {
+			ch <- fmt.Errorf("Accept failed: %v", err)
+			return
+		}
+		defer c.Close()
+		ch <- nil
+	}()
+
+	laddr, err := ResolveTCPAddr("tcp4", "127.0.0.1:0")
+	if err != nil {
+		t.Fatalf("ResolveTCPAddr failed: %v", err)
+	}
+	d := &Dialer{LocalAddr: laddr}
+	c, err := d.Dial("tcp4", ln.Addr().String())
+	if err != nil {
+		t.Fatalf("Dial failed: %v", err)
+	}
+	defer c.Close()
+	c.Read(make([]byte, 1))
+	err = <-ch
+	if err != nil {
+		t.Error(err)
+	}
+}
+
+func TestDialDualStackLocalhost(t *testing.T) {
+	switch runtime.GOOS {
+	case "nacl":
+		t.Skipf("skipping test on %q", runtime.GOOS)
+	}
+
+	if ips, err := LookupIP("localhost"); err != nil {
+		t.Fatalf("LookupIP failed: %v", err)
+	} else if len(ips) < 2 || !supportsIPv4 || !supportsIPv6 {
+		t.Skip("localhost doesn't have a pair of different address family IP addresses")
+	}
+
+	touchAndByeServer := func(dss *dualStackServer, ln Listener) {
+		for {
+			if c, err := ln.Accept(); err != nil {
+				return
+			} else {
+				c.Close()
+			}
+		}
+	}
+	dss, err := newDualStackServer([]streamListener{
+		{net: "tcp4", addr: "127.0.0.1"},
+		{net: "tcp6", addr: "[::1]"},
+	})
+	if err != nil {
+		t.Fatalf("newDualStackServer failed: %v", err)
+	}
+	defer dss.teardown()
+	if err := dss.buildup(touchAndByeServer); err != nil {
+		t.Fatalf("dualStackServer.buildup failed: %v", err)
+	}
+
+	d := &Dialer{DualStack: true}
+	for range dss.lns {
+		if c, err := d.Dial("tcp", "localhost:"+dss.port); err != nil {
+			t.Errorf("Dial failed: %v", err)
+		} else {
+			if addr := c.LocalAddr().(*TCPAddr); addr.IP.To4() != nil {
+				dss.teardownNetwork("tcp4")
+			} else if addr.IP.To16() != nil && addr.IP.To4() == nil {
+				dss.teardownNetwork("tcp6")
+			}
+			c.Close()
+		}
+	}
+}
+
+func TestDialerKeepAlive(t *testing.T) {
+	ln := newLocalListener(t)
+	defer ln.Close()
+	defer func() {
+		testHookSetKeepAlive = func() {}
+	}()
+	go func() {
+		for {
+			c, err := ln.Accept()
+			if err != nil {
+				return
+			}
+			c.Close()
+		}
+	}()
+	for _, keepAlive := range []bool{false, true} {
+		got := false
+		testHookSetKeepAlive = func() { got = true }
+		var d Dialer
+		if keepAlive {
+			d.KeepAlive = 30 * time.Second
+		}
+		c, err := d.Dial("tcp", ln.Addr().String())
+		if err != nil {
+			t.Fatal(err)
+		}
+		c.Close()
+		if got != keepAlive {
+			t.Errorf("Dialer.KeepAlive = %v: SetKeepAlive called = %v, want %v", d.KeepAlive, got, !got)
+		}
+	}
+}
diff --git a/src/pkg/net/dialgoogle_test.go b/src/net/dialgoogle_test.go
similarity index 100%
rename from src/pkg/net/dialgoogle_test.go
rename to src/net/dialgoogle_test.go
diff --git a/src/net/dnsclient.go b/src/net/dnsclient.go
new file mode 100644
index 0000000..e8014e4
--- /dev/null
+++ b/src/net/dnsclient.go
@@ -0,0 +1,249 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package net
+
+import (
+	"math/rand"
+	"sort"
+)
+
+// DNSError represents a DNS lookup error.
+type DNSError struct {
+	Err       string // description of the error
+	Name      string // name looked for
+	Server    string // server used
+	IsTimeout bool
+}
+
+func (e *DNSError) Error() string {
+	if e == nil {
+		return "<nil>"
+	}
+	s := "lookup " + e.Name
+	if e.Server != "" {
+		s += " on " + e.Server
+	}
+	s += ": " + e.Err
+	return s
+}
+
+func (e *DNSError) Timeout() bool   { return e.IsTimeout }
+func (e *DNSError) Temporary() bool { return e.IsTimeout }
+
+const noSuchHost = "no such host"
+
+// reverseaddr returns the in-addr.arpa. or ip6.arpa. hostname of the IP
+// address addr suitable for rDNS (PTR) record lookup or an error if it fails
+// to parse the IP address.
+func reverseaddr(addr string) (arpa string, err error) {
+	ip := ParseIP(addr)
+	if ip == nil {
+		return "", &DNSError{Err: "unrecognized address", Name: addr}
+	}
+	if ip.To4() != nil {
+		return itoa(int(ip[15])) + "." + itoa(int(ip[14])) + "." + itoa(int(ip[13])) + "." +
+			itoa(int(ip[12])) + ".in-addr.arpa.", nil
+	}
+	// Must be IPv6
+	buf := make([]byte, 0, len(ip)*4+len("ip6.arpa."))
+	// Add it, in reverse, to the buffer
+	for i := len(ip) - 1; i >= 0; i-- {
+		v := ip[i]
+		buf = append(buf, hexDigit[v&0xF])
+		buf = append(buf, '.')
+		buf = append(buf, hexDigit[v>>4])
+		buf = append(buf, '.')
+	}
+	// Append "ip6.arpa." and return (buf already has the final .)
+	buf = append(buf, "ip6.arpa."...)
+	return string(buf), nil
+}
+
+// Find answer for name in dns message.
+// On return, if err == nil, addrs != nil.
+func answer(name, server string, dns *dnsMsg, qtype uint16) (cname string, addrs []dnsRR, err error) {
+	addrs = make([]dnsRR, 0, len(dns.answer))
+
+	if dns.rcode == dnsRcodeNameError && dns.recursion_available {
+		return "", nil, &DNSError{Err: noSuchHost, Name: name}
+	}
+	if dns.rcode != dnsRcodeSuccess {
+		// None of the error codes make sense
+		// for the query we sent.  If we didn't get
+		// a name error and we didn't get success,
+		// the server is behaving incorrectly.
+		return "", nil, &DNSError{Err: "server misbehaving", Name: name, Server: server}
+	}
+
+	// Look for the name.
+	// Presotto says it's okay to assume that servers listed in
+	// /etc/resolv.conf are recursive resolvers.
+	// We asked for recursion, so it should have included
+	// all the answers we need in this one packet.
+Cname:
+	for cnameloop := 0; cnameloop < 10; cnameloop++ {
+		addrs = addrs[0:0]
+		for _, rr := range dns.answer {
+			if _, justHeader := rr.(*dnsRR_Header); justHeader {
+				// Corrupt record: we only have a
+				// header. That header might say it's
+				// of type qtype, but we don't
+				// actually have it. Skip.
+				continue
+			}
+			h := rr.Header()
+			if h.Class == dnsClassINET && h.Name == name {
+				switch h.Rrtype {
+				case qtype:
+					addrs = append(addrs, rr)
+				case dnsTypeCNAME:
+					// redirect to cname
+					name = rr.(*dnsRR_CNAME).Cname
+					continue Cname
+				}
+			}
+		}
+		if len(addrs) == 0 {
+			return "", nil, &DNSError{Err: noSuchHost, Name: name, Server: server}
+		}
+		return name, addrs, nil
+	}
+
+	return "", nil, &DNSError{Err: "too many redirects", Name: name, Server: server}
+}
+
+func isDomainName(s string) bool {
+	// See RFC 1035, RFC 3696.
+	if len(s) == 0 {
+		return false
+	}
+	if len(s) > 255 {
+		return false
+	}
+
+	last := byte('.')
+	ok := false // Ok once we've seen a letter.
+	partlen := 0
+	for i := 0; i < len(s); i++ {
+		c := s[i]
+		switch {
+		default:
+			return false
+		case 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' || c == '_':
+			ok = true
+			partlen++
+		case '0' <= c && c <= '9':
+			// fine
+			partlen++
+		case c == '-':
+			// Byte before dash cannot be dot.
+			if last == '.' {
+				return false
+			}
+			partlen++
+		case c == '.':
+			// Byte before dot cannot be dot, dash.
+			if last == '.' || last == '-' {
+				return false
+			}
+			if partlen > 63 || partlen == 0 {
+				return false
+			}
+			partlen = 0
+		}
+		last = c
+	}
+	if last == '-' || partlen > 63 {
+		return false
+	}
+
+	return ok
+}
+
+// An SRV represents a single DNS SRV record.
+type SRV struct {
+	Target   string
+	Port     uint16
+	Priority uint16
+	Weight   uint16
+}
+
+// byPriorityWeight sorts SRV records by ascending priority and weight.
+type byPriorityWeight []*SRV
+
+func (s byPriorityWeight) Len() int { return len(s) }
+
+func (s byPriorityWeight) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
+
+func (s byPriorityWeight) Less(i, j int) bool {
+	return s[i].Priority < s[j].Priority ||
+		(s[i].Priority == s[j].Priority && s[i].Weight < s[j].Weight)
+}
+
+// shuffleByWeight shuffles SRV records by weight using the algorithm
+// described in RFC 2782.
+func (addrs byPriorityWeight) shuffleByWeight() {
+	sum := 0
+	for _, addr := range addrs {
+		sum += int(addr.Weight)
+	}
+	for sum > 0 && len(addrs) > 1 {
+		s := 0
+		n := rand.Intn(sum)
+		for i := range addrs {
+			s += int(addrs[i].Weight)
+			if s > n {
+				if i > 0 {
+					addrs[0], addrs[i] = addrs[i], addrs[0]
+				}
+				break
+			}
+		}
+		sum -= int(addrs[0].Weight)
+		addrs = addrs[1:]
+	}
+}
+
+// sort reorders SRV records as specified in RFC 2782.
+func (addrs byPriorityWeight) sort() {
+	sort.Sort(addrs)
+	i := 0
+	for j := 1; j < len(addrs); j++ {
+		if addrs[i].Priority != addrs[j].Priority {
+			addrs[i:j].shuffleByWeight()
+			i = j
+		}
+	}
+	addrs[i:].shuffleByWeight()
+}
+
+// An MX represents a single DNS MX record.
+type MX struct {
+	Host string
+	Pref uint16
+}
+
+// byPref implements sort.Interface to sort MX records by preference
+type byPref []*MX
+
+func (s byPref) Len() int { return len(s) }
+
+func (s byPref) Less(i, j int) bool { return s[i].Pref < s[j].Pref }
+
+func (s byPref) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
+
+// sort reorders MX records as specified in RFC 5321.
+func (s byPref) sort() {
+	for i := range s {
+		j := rand.Intn(i + 1)
+		s[i], s[j] = s[j], s[i]
+	}
+	sort.Sort(s)
+}
+
+// An NS represents a single DNS NS record.
+type NS struct {
+	Host string
+}
diff --git a/src/pkg/net/dnsclient_test.go b/src/net/dnsclient_test.go
similarity index 100%
rename from src/pkg/net/dnsclient_test.go
rename to src/net/dnsclient_test.go
diff --git a/src/net/dnsclient_unix.go b/src/net/dnsclient_unix.go
new file mode 100644
index 0000000..7511083
--- /dev/null
+++ b/src/net/dnsclient_unix.go
@@ -0,0 +1,423 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin dragonfly freebsd linux netbsd openbsd solaris
+
+// DNS client: see RFC 1035.
+// Has to be linked into package net for Dial.
+
+// TODO(rsc):
+//	Could potentially handle many outstanding lookups faster.
+//	Could have a small cache.
+//	Random UDP source port (net.Dial should do that for us).
+//	Random request IDs.
+
+package net
+
+import (
+	"errors"
+	"io"
+	"math/rand"
+	"os"
+	"sync"
+	"time"
+)
+
+// A dnsConn represents a DNS transport endpoint.
+type dnsConn interface {
+	Conn
+
+	// readDNSResponse reads a DNS response message from the DNS
+	// transport endpoint and returns the received DNS response
+	// message.
+	readDNSResponse() (*dnsMsg, error)
+
+	// writeDNSQuery writes a DNS query message to the DNS
+	// connection endpoint.
+	writeDNSQuery(*dnsMsg) error
+}
+
+func (c *UDPConn) readDNSResponse() (*dnsMsg, error) {
+	b := make([]byte, 512) // see RFC 1035
+	n, err := c.Read(b)
+	if err != nil {
+		return nil, err
+	}
+	msg := &dnsMsg{}
+	if !msg.Unpack(b[:n]) {
+		return nil, errors.New("cannot unmarshal DNS message")
+	}
+	return msg, nil
+}
+
+func (c *UDPConn) writeDNSQuery(msg *dnsMsg) error {
+	b, ok := msg.Pack()
+	if !ok {
+		return errors.New("cannot marshal DNS message")
+	}
+	if _, err := c.Write(b); err != nil {
+		return err
+	}
+	return nil
+}
+
+func (c *TCPConn) readDNSResponse() (*dnsMsg, error) {
+	b := make([]byte, 1280) // 1280 is a reasonable initial size for IP over Ethernet, see RFC 4035
+	if _, err := io.ReadFull(c, b[:2]); err != nil {
+		return nil, err
+	}
+	l := int(b[0])<<8 | int(b[1])
+	if l > len(b) {
+		b = make([]byte, l)
+	}
+	n, err := io.ReadFull(c, b[:l])
+	if err != nil {
+		return nil, err
+	}
+	msg := &dnsMsg{}
+	if !msg.Unpack(b[:n]) {
+		return nil, errors.New("cannot unmarshal DNS message")
+	}
+	return msg, nil
+}
+
+func (c *TCPConn) writeDNSQuery(msg *dnsMsg) error {
+	b, ok := msg.Pack()
+	if !ok {
+		return errors.New("cannot marshal DNS message")
+	}
+	l := uint16(len(b))
+	b = append([]byte{byte(l >> 8), byte(l)}, b...)
+	if _, err := c.Write(b); err != nil {
+		return err
+	}
+	return nil
+}
+
+func (d *Dialer) dialDNS(network, server string) (dnsConn, error) {
+	switch network {
+	case "tcp", "tcp4", "tcp6", "udp", "udp4", "udp6":
+	default:
+		return nil, UnknownNetworkError(network)
+	}
+	// Calling Dial here is scary -- we have to be sure not to
+	// dial a name that will require a DNS lookup, or Dial will
+	// call back here to translate it. The DNS config parser has
+	// already checked that all the cfg.servers[i] are IP
+	// addresses, which Dial will use without a DNS lookup.
+	c, err := d.Dial(network, server)
+	if err != nil {
+		return nil, err
+	}
+	switch network {
+	case "tcp", "tcp4", "tcp6":
+		return c.(*TCPConn), nil
+	case "udp", "udp4", "udp6":
+		return c.(*UDPConn), nil
+	}
+	panic("unreachable")
+}
+
+// exchange sends a query on the connection and hopes for a response.
+func exchange(server, name string, qtype uint16, timeout time.Duration) (*dnsMsg, error) {
+	d := Dialer{Timeout: timeout}
+	out := dnsMsg{
+		dnsMsgHdr: dnsMsgHdr{
+			recursion_desired: true,
+		},
+		question: []dnsQuestion{
+			{name, qtype, dnsClassINET},
+		},
+	}
+	for _, network := range []string{"udp", "tcp"} {
+		c, err := d.dialDNS(network, server)
+		if err != nil {
+			return nil, err
+		}
+		defer c.Close()
+		if timeout > 0 {
+			c.SetDeadline(time.Now().Add(timeout))
+		}
+		out.id = uint16(rand.Int()) ^ uint16(time.Now().UnixNano())
+		if err := c.writeDNSQuery(&out); err != nil {
+			return nil, err
+		}
+		in, err := c.readDNSResponse()
+		if err != nil {
+			return nil, err
+		}
+		if in.id != out.id {
+			return nil, errors.New("DNS message ID mismatch")
+		}
+		if in.truncated { // see RFC 5966
+			continue
+		}
+		return in, nil
+	}
+	return nil, errors.New("no answer from DNS server")
+}
+
+// Do a lookup for a single name, which must be rooted
+// (otherwise answer will not find the answers).
+func tryOneName(cfg *dnsConfig, name string, qtype uint16) (string, []dnsRR, error) {
+	if len(cfg.servers) == 0 {
+		return "", nil, &DNSError{Err: "no DNS servers", Name: name}
+	}
+	if len(name) >= 256 {
+		return "", nil, &DNSError{Err: "DNS name too long", Name: name}
+	}
+	timeout := time.Duration(cfg.timeout) * time.Second
+	var lastErr error
+	for i := 0; i < cfg.attempts; i++ {
+		for _, server := range cfg.servers {
+			server = JoinHostPort(server, "53")
+			msg, err := exchange(server, name, qtype, timeout)
+			if err != nil {
+				lastErr = &DNSError{
+					Err:    err.Error(),
+					Name:   name,
+					Server: server,
+				}
+				if nerr, ok := err.(Error); ok && nerr.Timeout() {
+					lastErr.(*DNSError).IsTimeout = true
+				}
+				continue
+			}
+			cname, addrs, err := answer(name, server, msg, qtype)
+			if err == nil || err.(*DNSError).Err == noSuchHost {
+				return cname, addrs, err
+			}
+			lastErr = err
+		}
+	}
+	return "", nil, lastErr
+}
+
+func convertRR_A(records []dnsRR) []IP {
+	addrs := make([]IP, len(records))
+	for i, rr := range records {
+		a := rr.(*dnsRR_A).A
+		addrs[i] = IPv4(byte(a>>24), byte(a>>16), byte(a>>8), byte(a))
+	}
+	return addrs
+}
+
+func convertRR_AAAA(records []dnsRR) []IP {
+	addrs := make([]IP, len(records))
+	for i, rr := range records {
+		a := make(IP, IPv6len)
+		copy(a, rr.(*dnsRR_AAAA).AAAA[:])
+		addrs[i] = a
+	}
+	return addrs
+}
+
+var cfg struct {
+	ch        chan struct{}
+	mu        sync.RWMutex // protects dnsConfig and dnserr
+	dnsConfig *dnsConfig
+	dnserr    error
+}
+var onceLoadConfig sync.Once
+
+// Assume dns config file is /etc/resolv.conf here
+func loadDefaultConfig() {
+	loadConfig("/etc/resolv.conf", 5*time.Second, nil)
+}
+
+func loadConfig(resolvConfPath string, reloadTime time.Duration, quit <-chan chan struct{}) {
+	var mtime time.Time
+	cfg.ch = make(chan struct{}, 1)
+	if fi, err := os.Stat(resolvConfPath); err != nil {
+		cfg.dnserr = err
+	} else {
+		mtime = fi.ModTime()
+		cfg.dnsConfig, cfg.dnserr = dnsReadConfig(resolvConfPath)
+	}
+	go func() {
+		for {
+			time.Sleep(reloadTime)
+			select {
+			case qresp := <-quit:
+				qresp <- struct{}{}
+				return
+			case <-cfg.ch:
+			}
+
+			// In case of error, we keep the previous config
+			fi, err := os.Stat(resolvConfPath)
+			if err != nil {
+				continue
+			}
+			// If the resolv.conf mtime didn't change, do not reload
+			m := fi.ModTime()
+			if m.Equal(mtime) {
+				continue
+			}
+			mtime = m
+			// In case of error, we keep the previous config
+			ncfg, err := dnsReadConfig(resolvConfPath)
+			if err != nil || len(ncfg.servers) == 0 {
+				continue
+			}
+			cfg.mu.Lock()
+			cfg.dnsConfig = ncfg
+			cfg.dnserr = nil
+			cfg.mu.Unlock()
+		}
+	}()
+}
+
+func lookup(name string, qtype uint16) (cname string, addrs []dnsRR, err error) {
+	if !isDomainName(name) {
+		return name, nil, &DNSError{Err: "invalid domain name", Name: name}
+	}
+	onceLoadConfig.Do(loadDefaultConfig)
+
+	select {
+	case cfg.ch <- struct{}{}:
+	default:
+	}
+
+	cfg.mu.RLock()
+	defer cfg.mu.RUnlock()
+
+	if cfg.dnserr != nil || cfg.dnsConfig == nil {
+		err = cfg.dnserr
+		return
+	}
+	// If name is rooted (trailing dot) or has enough dots,
+	// try it by itself first.
+	rooted := len(name) > 0 && name[len(name)-1] == '.'
+	if rooted || count(name, '.') >= cfg.dnsConfig.ndots {
+		rname := name
+		if !rooted {
+			rname += "."
+		}
+		// Can try as ordinary name.
+		cname, addrs, err = tryOneName(cfg.dnsConfig, rname, qtype)
+		if rooted || err == nil {
+			return
+		}
+	}
+
+	// Otherwise, try suffixes.
+	for i := 0; i < len(cfg.dnsConfig.search); i++ {
+		rname := name + "." + cfg.dnsConfig.search[i]
+		if rname[len(rname)-1] != '.' {
+			rname += "."
+		}
+		cname, addrs, err = tryOneName(cfg.dnsConfig, rname, qtype)
+		if err == nil {
+			return
+		}
+	}
+
+	// Last ditch effort: try unsuffixed only if we haven't already,
+	// that is, name is not rooted and has less than ndots dots.
+	if count(name, '.') < cfg.dnsConfig.ndots {
+		cname, addrs, err = tryOneName(cfg.dnsConfig, name+".", qtype)
+		if err == nil {
+			return
+		}
+	}
+
+	if e, ok := err.(*DNSError); ok {
+		// Show original name passed to lookup, not suffixed one.
+		// In general we might have tried many suffixes; showing
+		// just one is misleading. See also golang.org/issue/6324.
+		e.Name = name
+	}
+	return
+}
+
+// goLookupHost is the native Go implementation of LookupHost.
+// Used only if cgoLookupHost refuses to handle the request
+// (that is, only if cgoLookupHost is the stub in cgo_stub.go).
+// Normally we let cgo use the C library resolver instead of
+// depending on our lookup code, so that Go and C get the same
+// answers.
+func goLookupHost(name string) (addrs []string, err error) {
+	// Use entries from /etc/hosts if they match.
+	addrs = lookupStaticHost(name)
+	if len(addrs) > 0 {
+		return
+	}
+	ips, err := goLookupIP(name)
+	if err != nil {
+		return
+	}
+	addrs = make([]string, 0, len(ips))
+	for _, ip := range ips {
+		addrs = append(addrs, ip.String())
+	}
+	return
+}
+
+// goLookupIP is the native Go implementation of LookupIP.
+// Used only if cgoLookupIP refuses to handle the request
+// (that is, only if cgoLookupIP is the stub in cgo_stub.go).
+// Normally we let cgo use the C library resolver instead of
+// depending on our lookup code, so that Go and C get the same
+// answers.
+func goLookupIP(name string) (addrs []IP, err error) {
+	// Use entries from /etc/hosts if possible.
+	haddrs := lookupStaticHost(name)
+	if len(haddrs) > 0 {
+		for _, haddr := range haddrs {
+			if ip := ParseIP(haddr); ip != nil {
+				addrs = append(addrs, ip)
+			}
+		}
+		if len(addrs) > 0 {
+			return
+		}
+	}
+	type racer struct {
+		qtype uint16
+		rrs   []dnsRR
+		error
+	}
+	lane := make(chan racer, 1)
+	qtypes := [...]uint16{dnsTypeA, dnsTypeAAAA}
+	for _, qtype := range qtypes {
+		go func(qtype uint16) {
+			_, rrs, err := lookup(name, qtype)
+			lane <- racer{qtype, rrs, err}
+		}(qtype)
+	}
+	var lastErr error
+	for range qtypes {
+		racer := <-lane
+		if racer.error != nil {
+			lastErr = racer.error
+			continue
+		}
+		switch racer.qtype {
+		case dnsTypeA:
+			addrs = append(addrs, convertRR_A(racer.rrs)...)
+		case dnsTypeAAAA:
+			addrs = append(addrs, convertRR_AAAA(racer.rrs)...)
+		}
+	}
+	if len(addrs) == 0 && lastErr != nil {
+		return nil, lastErr
+	}
+	return addrs, nil
+}
+
+// goLookupCNAME is the native Go implementation of LookupCNAME.
+// Used only if cgoLookupCNAME refuses to handle the request
+// (that is, only if cgoLookupCNAME is the stub in cgo_stub.go).
+// Normally we let cgo use the C library resolver instead of
+// depending on our lookup code, so that Go and C get the same
+// answers.
+func goLookupCNAME(name string) (cname string, err error) {
+	_, rr, err := lookup(name, dnsTypeCNAME)
+	if err != nil {
+		return
+	}
+	cname = rr[0].(*dnsRR_CNAME).Cname
+	return
+}
diff --git a/src/net/dnsclient_unix_test.go b/src/net/dnsclient_unix_test.go
new file mode 100644
index 0000000..1167c26
--- /dev/null
+++ b/src/net/dnsclient_unix_test.go
@@ -0,0 +1,246 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin dragonfly freebsd linux netbsd openbsd solaris
+
+package net
+
+import (
+	"io"
+	"io/ioutil"
+	"os"
+	"path"
+	"reflect"
+	"testing"
+	"time"
+)
+
+var dnsTransportFallbackTests = []struct {
+	server  string
+	name    string
+	qtype   uint16
+	timeout int
+	rcode   int
+}{
+	// Querying "com." with qtype=255 usually makes an answer
+	// which requires more than 512 bytes.
+	{"8.8.8.8:53", "com.", dnsTypeALL, 2, dnsRcodeSuccess},
+	{"8.8.4.4:53", "com.", dnsTypeALL, 4, dnsRcodeSuccess},
+}
+
+func TestDNSTransportFallback(t *testing.T) {
+	if testing.Short() || !*testExternal {
+		t.Skip("skipping test to avoid external network")
+	}
+
+	for _, tt := range dnsTransportFallbackTests {
+		timeout := time.Duration(tt.timeout) * time.Second
+		msg, err := exchange(tt.server, tt.name, tt.qtype, timeout)
+		if err != nil {
+			t.Error(err)
+			continue
+		}
+		switch msg.rcode {
+		case tt.rcode, dnsRcodeServerFailure:
+		default:
+			t.Errorf("got %v from %v; want %v", msg.rcode, tt.server, tt.rcode)
+			continue
+		}
+	}
+}
+
+// See RFC 6761 for further information about the reserved, pseudo
+// domain names.
+var specialDomainNameTests = []struct {
+	name  string
+	qtype uint16
+	rcode int
+}{
+	// Name resoltion APIs and libraries should not recongnize the
+	// followings as special.
+	{"1.0.168.192.in-addr.arpa.", dnsTypePTR, dnsRcodeNameError},
+	{"test.", dnsTypeALL, dnsRcodeNameError},
+	{"example.com.", dnsTypeALL, dnsRcodeSuccess},
+
+	// Name resoltion APIs and libraries should recongnize the
+	// followings as special and should not send any queries.
+	// Though, we test those names here for verifying nagative
+	// answers at DNS query-response interaction level.
+	{"localhost.", dnsTypeALL, dnsRcodeNameError},
+	{"invalid.", dnsTypeALL, dnsRcodeNameError},
+}
+
+func TestSpecialDomainName(t *testing.T) {
+	if testing.Short() || !*testExternal {
+		t.Skip("skipping test to avoid external network")
+	}
+
+	server := "8.8.8.8:53"
+	for _, tt := range specialDomainNameTests {
+		msg, err := exchange(server, tt.name, tt.qtype, 0)
+		if err != nil {
+			t.Error(err)
+			continue
+		}
+		switch msg.rcode {
+		case tt.rcode, dnsRcodeServerFailure:
+		default:
+			t.Errorf("got %v from %v; want %v", msg.rcode, server, tt.rcode)
+			continue
+		}
+	}
+}
+
+type resolvConfTest struct {
+	*testing.T
+	dir     string
+	path    string
+	started bool
+	quitc   chan chan struct{}
+}
+
+func newResolvConfTest(t *testing.T) *resolvConfTest {
+	dir, err := ioutil.TempDir("", "resolvConfTest")
+	if err != nil {
+		t.Fatalf("could not create temp dir: %v", err)
+	}
+
+	// Disable the default loadConfig
+	onceLoadConfig.Do(func() {})
+
+	r := &resolvConfTest{
+		T:     t,
+		dir:   dir,
+		path:  path.Join(dir, "resolv.conf"),
+		quitc: make(chan chan struct{}),
+	}
+
+	return r
+}
+
+func (r *resolvConfTest) Start() {
+	loadConfig(r.path, 100*time.Millisecond, r.quitc)
+	r.started = true
+}
+
+func (r *resolvConfTest) SetConf(s string) {
+	// Make sure the file mtime will be different once we're done here,
+	// even on systems with coarse (1s) mtime resolution.
+	time.Sleep(time.Second)
+
+	f, err := os.OpenFile(r.path, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0600)
+	if err != nil {
+		r.Fatalf("failed to create temp file %s: %v", r.path, err)
+	}
+	if _, err := io.WriteString(f, s); err != nil {
+		f.Close()
+		r.Fatalf("failed to write temp file: %v", err)
+	}
+	f.Close()
+
+	if r.started {
+		cfg.ch <- struct{}{} // fill buffer
+		cfg.ch <- struct{}{} // wait for reload to begin
+		cfg.ch <- struct{}{} // wait for reload to complete
+	}
+}
+
+func (r *resolvConfTest) WantServers(want []string) {
+	cfg.mu.RLock()
+	defer cfg.mu.RUnlock()
+	if got := cfg.dnsConfig.servers; !reflect.DeepEqual(got, want) {
+		r.Fatalf("Unexpected dns server loaded, got %v want %v", got, want)
+	}
+}
+
+func (r *resolvConfTest) Close() {
+	resp := make(chan struct{})
+	r.quitc <- resp
+	<-resp
+	if err := os.RemoveAll(r.dir); err != nil {
+		r.Logf("failed to remove temp dir %s: %v", r.dir, err)
+	}
+}
+
+func TestReloadResolvConfFail(t *testing.T) {
+	if testing.Short() || !*testExternal {
+		t.Skip("skipping test to avoid external network")
+	}
+
+	r := newResolvConfTest(t)
+	defer r.Close()
+
+	// resolv.conf.tmp does not exist yet
+	r.Start()
+	if _, err := goLookupIP("golang.org"); err == nil {
+		t.Fatal("goLookupIP(missing) succeeded")
+	}
+
+	r.SetConf("nameserver 8.8.8.8")
+	if _, err := goLookupIP("golang.org"); err != nil {
+		t.Fatalf("goLookupIP(missing; good) failed: %v", err)
+	}
+
+	// Using a bad resolv.conf while we had a good
+	// one before should not update the config
+	r.SetConf("")
+	if _, err := goLookupIP("golang.org"); err != nil {
+		t.Fatalf("goLookupIP(missing; good; bad) failed: %v", err)
+	}
+}
+
+func TestReloadResolvConfChange(t *testing.T) {
+	if testing.Short() || !*testExternal {
+		t.Skip("skipping test to avoid external network")
+	}
+
+	r := newResolvConfTest(t)
+	defer r.Close()
+
+	r.SetConf("nameserver 8.8.8.8")
+	r.Start()
+
+	if _, err := goLookupIP("golang.org"); err != nil {
+		t.Fatalf("goLookupIP(good) failed: %v", err)
+	}
+	r.WantServers([]string{"8.8.8.8"})
+
+	// Using a bad resolv.conf when we had a good one
+	// before should not update the config
+	r.SetConf("")
+	if _, err := goLookupIP("golang.org"); err != nil {
+		t.Fatalf("goLookupIP(good; bad) failed: %v", err)
+	}
+
+	// A new good config should get picked up
+	r.SetConf("nameserver 8.8.4.4")
+	r.WantServers([]string{"8.8.4.4"})
+}
+
+func BenchmarkGoLookupIP(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		goLookupIP("www.example.com")
+	}
+}
+
+func BenchmarkGoLookupIPNoSuchHost(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		goLookupIP("some.nonexistent")
+	}
+}
+
+func BenchmarkGoLookupIPWithBrokenNameServer(b *testing.B) {
+	onceLoadConfig.Do(loadDefaultConfig)
+	if cfg.dnserr != nil || cfg.dnsConfig == nil {
+		b.Fatalf("loadConfig failed: %v", cfg.dnserr)
+	}
+	// This looks ugly but it's safe as long as benchmarks are run
+	// sequentially in package testing.
+	orig := cfg.dnsConfig
+	cfg.dnsConfig.servers = append([]string{"203.0.113.254"}, cfg.dnsConfig.servers...) // use TEST-NET-3 block, see RFC 5737
+	for i := 0; i < b.N; i++ {
+		goLookupIP("www.example.com")
+	}
+	cfg.dnsConfig = orig
+}
diff --git a/src/net/dnsconfig_unix.go b/src/net/dnsconfig_unix.go
new file mode 100644
index 0000000..66ab7c4
--- /dev/null
+++ b/src/net/dnsconfig_unix.go
@@ -0,0 +1,96 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin dragonfly freebsd linux netbsd openbsd solaris
+
+// Read system DNS config from /etc/resolv.conf
+
+package net
+
+type dnsConfig struct {
+	servers  []string // servers to use
+	search   []string // suffixes to append to local name
+	ndots    int      // number of dots in name to trigger absolute lookup
+	timeout  int      // seconds before giving up on packet
+	attempts int      // lost packets before giving up on server
+	rotate   bool     // round robin among servers
+}
+
+// See resolv.conf(5) on a Linux machine.
+// TODO(rsc): Supposed to call uname() and chop the beginning
+// of the host name to get the default search domain.
+func dnsReadConfig(filename string) (*dnsConfig, error) {
+	file, err := open(filename)
+	if err != nil {
+		return nil, &DNSConfigError{err}
+	}
+	defer file.close()
+	conf := &dnsConfig{
+		ndots:    1,
+		timeout:  5,
+		attempts: 2,
+	}
+	for line, ok := file.readLine(); ok; line, ok = file.readLine() {
+		f := getFields(line)
+		if len(f) < 1 {
+			continue
+		}
+		switch f[0] {
+		case "nameserver": // add one name server
+			if len(f) > 1 && len(conf.servers) < 3 { // small, but the standard limit
+				// One more check: make sure server name is
+				// just an IP address.  Otherwise we need DNS
+				// to look it up.
+				if parseIPv4(f[1]) != nil {
+					conf.servers = append(conf.servers, f[1])
+				} else if ip, _ := parseIPv6(f[1], true); ip != nil {
+					conf.servers = append(conf.servers, f[1])
+				}
+			}
+
+		case "domain": // set search path to just this domain
+			if len(f) > 1 {
+				conf.search = []string{f[1]}
+			}
+
+		case "search": // set search path to given servers
+			conf.search = make([]string, len(f)-1)
+			for i := 0; i < len(conf.search); i++ {
+				conf.search[i] = f[i+1]
+			}
+
+		case "options": // magic options
+			for i := 1; i < len(f); i++ {
+				s := f[i]
+				switch {
+				case hasPrefix(s, "ndots:"):
+					n, _, _ := dtoi(s, 6)
+					if n < 1 {
+						n = 1
+					}
+					conf.ndots = n
+				case hasPrefix(s, "timeout:"):
+					n, _, _ := dtoi(s, 8)
+					if n < 1 {
+						n = 1
+					}
+					conf.timeout = n
+				case hasPrefix(s, "attempts:"):
+					n, _, _ := dtoi(s, 9)
+					if n < 1 {
+						n = 1
+					}
+					conf.attempts = n
+				case s == "rotate":
+					conf.rotate = true
+				}
+			}
+		}
+	}
+	return conf, nil
+}
+
+func hasPrefix(s, prefix string) bool {
+	return len(s) >= len(prefix) && s[:len(prefix)] == prefix
+}
diff --git a/src/net/dnsconfig_unix_test.go b/src/net/dnsconfig_unix_test.go
new file mode 100644
index 0000000..94fb0c3
--- /dev/null
+++ b/src/net/dnsconfig_unix_test.go
@@ -0,0 +1,69 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin dragonfly freebsd linux netbsd openbsd solaris
+
+package net
+
+import (
+	"reflect"
+	"testing"
+)
+
+var dnsReadConfigTests = []struct {
+	name string
+	conf dnsConfig
+}{
+	{
+		name: "testdata/resolv.conf",
+		conf: dnsConfig{
+			servers:  []string{"8.8.8.8", "2001:4860:4860::8888", "fe80::1%lo0"},
+			search:   []string{"localdomain"},
+			ndots:    5,
+			timeout:  10,
+			attempts: 3,
+			rotate:   true,
+		},
+	},
+	{
+		name: "testdata/domain-resolv.conf",
+		conf: dnsConfig{
+			servers:  []string{"8.8.8.8"},
+			search:   []string{"localdomain"},
+			ndots:    1,
+			timeout:  5,
+			attempts: 2,
+		},
+	},
+	{
+		name: "testdata/search-resolv.conf",
+		conf: dnsConfig{
+			servers:  []string{"8.8.8.8"},
+			search:   []string{"test", "invalid"},
+			ndots:    1,
+			timeout:  5,
+			attempts: 2,
+		},
+	},
+	{
+		name: "testdata/empty-resolv.conf",
+		conf: dnsConfig{
+			ndots:    1,
+			timeout:  5,
+			attempts: 2,
+		},
+	},
+}
+
+func TestDNSReadConfig(t *testing.T) {
+	for _, tt := range dnsReadConfigTests {
+		conf, err := dnsReadConfig(tt.name)
+		if err != nil {
+			t.Fatal(err)
+		}
+		if !reflect.DeepEqual(conf, &tt.conf) {
+			t.Errorf("got %v; want %v", conf, &tt.conf)
+		}
+	}
+}
diff --git a/src/pkg/net/dnsmsg.go b/src/net/dnsmsg.go
similarity index 100%
rename from src/pkg/net/dnsmsg.go
rename to src/net/dnsmsg.go
diff --git a/src/pkg/net/dnsmsg_test.go b/src/net/dnsmsg_test.go
similarity index 100%
rename from src/pkg/net/dnsmsg_test.go
rename to src/net/dnsmsg_test.go
diff --git a/src/pkg/net/dnsname_test.go b/src/net/dnsname_test.go
similarity index 100%
rename from src/pkg/net/dnsname_test.go
rename to src/net/dnsname_test.go
diff --git a/src/pkg/net/example_test.go b/src/net/example_test.go
similarity index 100%
rename from src/pkg/net/example_test.go
rename to src/net/example_test.go
diff --git a/src/pkg/net/fd_mutex.go b/src/net/fd_mutex.go
similarity index 100%
rename from src/pkg/net/fd_mutex.go
rename to src/net/fd_mutex.go
diff --git a/src/pkg/net/fd_mutex_test.go b/src/net/fd_mutex_test.go
similarity index 100%
rename from src/pkg/net/fd_mutex_test.go
rename to src/net/fd_mutex_test.go
diff --git a/src/pkg/net/fd_plan9.go b/src/net/fd_plan9.go
similarity index 100%
rename from src/pkg/net/fd_plan9.go
rename to src/net/fd_plan9.go
diff --git a/src/pkg/net/fd_poll_nacl.go b/src/net/fd_poll_nacl.go
similarity index 100%
rename from src/pkg/net/fd_poll_nacl.go
rename to src/net/fd_poll_nacl.go
diff --git a/src/pkg/net/fd_poll_runtime.go b/src/net/fd_poll_runtime.go
similarity index 100%
rename from src/pkg/net/fd_poll_runtime.go
rename to src/net/fd_poll_runtime.go
diff --git a/src/net/fd_unix.go b/src/net/fd_unix.go
new file mode 100644
index 0000000..7fa43f6
--- /dev/null
+++ b/src/net/fd_unix.go
@@ -0,0 +1,518 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris
+
+package net
+
+import (
+	"io"
+	"os"
+	"runtime"
+	"sync/atomic"
+	"syscall"
+	"time"
+)
+
+// Network file descriptor.
+type netFD struct {
+	// locking/lifetime of sysfd + serialize access to Read and Write methods
+	fdmu fdMutex
+
+	// immutable until Close
+	sysfd       int
+	family      int
+	sotype      int
+	isConnected bool
+	net         string
+	laddr       Addr
+	raddr       Addr
+
+	// wait server
+	pd pollDesc
+}
+
+func sysInit() {
+}
+
+func dial(network string, ra Addr, dialer func(time.Time) (Conn, error), deadline time.Time) (Conn, error) {
+	return dialer(deadline)
+}
+
+func newFD(sysfd, family, sotype int, net string) (*netFD, error) {
+	return &netFD{sysfd: sysfd, family: family, sotype: sotype, net: net}, nil
+}
+
+func (fd *netFD) init() error {
+	if err := fd.pd.Init(fd); err != nil {
+		return err
+	}
+	return nil
+}
+
+func (fd *netFD) setAddr(laddr, raddr Addr) {
+	fd.laddr = laddr
+	fd.raddr = raddr
+	runtime.SetFinalizer(fd, (*netFD).Close)
+}
+
+func (fd *netFD) name() string {
+	var ls, rs string
+	if fd.laddr != nil {
+		ls = fd.laddr.String()
+	}
+	if fd.raddr != nil {
+		rs = fd.raddr.String()
+	}
+	return fd.net + ":" + ls + "->" + rs
+}
+
+func (fd *netFD) connect(la, ra syscall.Sockaddr, deadline time.Time) error {
+	// Do not need to call fd.writeLock here,
+	// because fd is not yet accessible to user,
+	// so no concurrent operations are possible.
+	switch err := syscall.Connect(fd.sysfd, ra); err {
+	case syscall.EINPROGRESS, syscall.EALREADY, syscall.EINTR:
+	case nil, syscall.EISCONN:
+		if !deadline.IsZero() && deadline.Before(time.Now()) {
+			return errTimeout
+		}
+		if err := fd.init(); err != nil {
+			return err
+		}
+		return nil
+	case syscall.EINVAL:
+		// On Solaris we can see EINVAL if the socket has
+		// already been accepted and closed by the server.
+		// Treat this as a successful connection--writes to
+		// the socket will see EOF.  For details and a test
+		// case in C see http://golang.org/issue/6828.
+		if runtime.GOOS == "solaris" {
+			return nil
+		}
+		fallthrough
+	default:
+		return err
+	}
+	if err := fd.init(); err != nil {
+		return err
+	}
+	if !deadline.IsZero() {
+		fd.setWriteDeadline(deadline)
+		defer fd.setWriteDeadline(noDeadline)
+	}
+	for {
+		// Performing multiple connect system calls on a
+		// non-blocking socket under Unix variants does not
+		// necessarily result in earlier errors being
+		// returned. Instead, once runtime-integrated network
+		// poller tells us that the socket is ready, get the
+		// SO_ERROR socket option to see if the connection
+		// succeeded or failed. See issue 7474 for further
+		// details.
+		if err := fd.pd.WaitWrite(); err != nil {
+			return err
+		}
+		nerr, err := syscall.GetsockoptInt(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_ERROR)
+		if err != nil {
+			return err
+		}
+		switch err := syscall.Errno(nerr); err {
+		case syscall.EINPROGRESS, syscall.EALREADY, syscall.EINTR:
+		case syscall.Errno(0), syscall.EISCONN:
+			return nil
+		default:
+			return err
+		}
+	}
+}
+
+func (fd *netFD) destroy() {
+	// Poller may want to unregister fd in readiness notification mechanism,
+	// so this must be executed before closesocket.
+	fd.pd.Close()
+	closesocket(fd.sysfd)
+	fd.sysfd = -1
+	runtime.SetFinalizer(fd, nil)
+}
+
+// Add a reference to this fd.
+// Returns an error if the fd cannot be used.
+func (fd *netFD) incref() error {
+	if !fd.fdmu.Incref() {
+		return errClosing
+	}
+	return nil
+}
+
+// Remove a reference to this FD and close if we've been asked to do so
+// (and there are no references left).
+func (fd *netFD) decref() {
+	if fd.fdmu.Decref() {
+		fd.destroy()
+	}
+}
+
+// Add a reference to this fd and lock for reading.
+// Returns an error if the fd cannot be used.
+func (fd *netFD) readLock() error {
+	if !fd.fdmu.RWLock(true) {
+		return errClosing
+	}
+	return nil
+}
+
+// Unlock for reading and remove a reference to this FD.
+func (fd *netFD) readUnlock() {
+	if fd.fdmu.RWUnlock(true) {
+		fd.destroy()
+	}
+}
+
+// Add a reference to this fd and lock for writing.
+// Returns an error if the fd cannot be used.
+func (fd *netFD) writeLock() error {
+	if !fd.fdmu.RWLock(false) {
+		return errClosing
+	}
+	return nil
+}
+
+// Unlock for writing and remove a reference to this FD.
+func (fd *netFD) writeUnlock() {
+	if fd.fdmu.RWUnlock(false) {
+		fd.destroy()
+	}
+}
+
+func (fd *netFD) Close() error {
+	fd.pd.Lock() // needed for both fd.incref(true) and pollDesc.Evict
+	if !fd.fdmu.IncrefAndClose() {
+		fd.pd.Unlock()
+		return errClosing
+	}
+	// Unblock any I/O.  Once it all unblocks and returns,
+	// so that it cannot be referring to fd.sysfd anymore,
+	// the final decref will close fd.sysfd.  This should happen
+	// fairly quickly, since all the I/O is non-blocking, and any
+	// attempts to block in the pollDesc will return errClosing.
+	doWakeup := fd.pd.Evict()
+	fd.pd.Unlock()
+	fd.decref()
+	if doWakeup {
+		fd.pd.Wakeup()
+	}
+	return nil
+}
+
+func (fd *netFD) shutdown(how int) error {
+	if err := fd.incref(); err != nil {
+		return err
+	}
+	defer fd.decref()
+	err := syscall.Shutdown(fd.sysfd, how)
+	if err != nil {
+		return &OpError{"shutdown", fd.net, fd.laddr, err}
+	}
+	return nil
+}
+
+func (fd *netFD) closeRead() error {
+	return fd.shutdown(syscall.SHUT_RD)
+}
+
+func (fd *netFD) closeWrite() error {
+	return fd.shutdown(syscall.SHUT_WR)
+}
+
+func (fd *netFD) Read(p []byte) (n int, err error) {
+	if err := fd.readLock(); err != nil {
+		return 0, err
+	}
+	defer fd.readUnlock()
+	if err := fd.pd.PrepareRead(); err != nil {
+		return 0, &OpError{"read", fd.net, fd.raddr, err}
+	}
+	for {
+		n, err = syscall.Read(int(fd.sysfd), p)
+		if err != nil {
+			n = 0
+			if err == syscall.EAGAIN {
+				if err = fd.pd.WaitRead(); err == nil {
+					continue
+				}
+			}
+		}
+		err = chkReadErr(n, err, fd)
+		break
+	}
+	if err != nil && err != io.EOF {
+		err = &OpError{"read", fd.net, fd.raddr, err}
+	}
+	return
+}
+
+func (fd *netFD) readFrom(p []byte) (n int, sa syscall.Sockaddr, err error) {
+	if err := fd.readLock(); err != nil {
+		return 0, nil, err
+	}
+	defer fd.readUnlock()
+	if err := fd.pd.PrepareRead(); err != nil {
+		return 0, nil, &OpError{"read", fd.net, fd.laddr, err}
+	}
+	for {
+		n, sa, err = syscall.Recvfrom(fd.sysfd, p, 0)
+		if err != nil {
+			n = 0
+			if err == syscall.EAGAIN {
+				if err = fd.pd.WaitRead(); err == nil {
+					continue
+				}
+			}
+		}
+		err = chkReadErr(n, err, fd)
+		break
+	}
+	if err != nil && err != io.EOF {
+		err = &OpError{"read", fd.net, fd.laddr, err}
+	}
+	return
+}
+
+func (fd *netFD) readMsg(p []byte, oob []byte) (n, oobn, flags int, sa syscall.Sockaddr, err error) {
+	if err := fd.readLock(); err != nil {
+		return 0, 0, 0, nil, err
+	}
+	defer fd.readUnlock()
+	if err := fd.pd.PrepareRead(); err != nil {
+		return 0, 0, 0, nil, &OpError{"read", fd.net, fd.laddr, err}
+	}
+	for {
+		n, oobn, flags, sa, err = syscall.Recvmsg(fd.sysfd, p, oob, 0)
+		if err != nil {
+			// TODO(dfc) should n and oobn be set to 0
+			if err == syscall.EAGAIN {
+				if err = fd.pd.WaitRead(); err == nil {
+					continue
+				}
+			}
+		}
+		err = chkReadErr(n, err, fd)
+		break
+	}
+	if err != nil && err != io.EOF {
+		err = &OpError{"read", fd.net, fd.laddr, err}
+	}
+	return
+}
+
+func chkReadErr(n int, err error, fd *netFD) error {
+	if n == 0 && err == nil && fd.sotype != syscall.SOCK_DGRAM && fd.sotype != syscall.SOCK_RAW {
+		return io.EOF
+	}
+	return err
+}
+
+func (fd *netFD) Write(p []byte) (nn int, err error) {
+	if err := fd.writeLock(); err != nil {
+		return 0, err
+	}
+	defer fd.writeUnlock()
+	if err := fd.pd.PrepareWrite(); err != nil {
+		return 0, &OpError{"write", fd.net, fd.raddr, err}
+	}
+	for {
+		var n int
+		n, err = syscall.Write(int(fd.sysfd), p[nn:])
+		if n > 0 {
+			nn += n
+		}
+		if nn == len(p) {
+			break
+		}
+		if err == syscall.EAGAIN {
+			if err = fd.pd.WaitWrite(); err == nil {
+				continue
+			}
+		}
+		if err != nil {
+			n = 0
+			break
+		}
+		if n == 0 {
+			err = io.ErrUnexpectedEOF
+			break
+		}
+	}
+	if err != nil {
+		err = &OpError{"write", fd.net, fd.raddr, err}
+	}
+	return nn, err
+}
+
+func (fd *netFD) writeTo(p []byte, sa syscall.Sockaddr) (n int, err error) {
+	if err := fd.writeLock(); err != nil {
+		return 0, err
+	}
+	defer fd.writeUnlock()
+	if err := fd.pd.PrepareWrite(); err != nil {
+		return 0, &OpError{"write", fd.net, fd.raddr, err}
+	}
+	for {
+		err = syscall.Sendto(fd.sysfd, p, 0, sa)
+		if err == syscall.EAGAIN {
+			if err = fd.pd.WaitWrite(); err == nil {
+				continue
+			}
+		}
+		break
+	}
+	if err == nil {
+		n = len(p)
+	} else {
+		err = &OpError{"write", fd.net, fd.raddr, err}
+	}
+	return
+}
+
+func (fd *netFD) writeMsg(p []byte, oob []byte, sa syscall.Sockaddr) (n int, oobn int, err error) {
+	if err := fd.writeLock(); err != nil {
+		return 0, 0, err
+	}
+	defer fd.writeUnlock()
+	if err := fd.pd.PrepareWrite(); err != nil {
+		return 0, 0, &OpError{"write", fd.net, fd.raddr, err}
+	}
+	for {
+		n, err = syscall.SendmsgN(fd.sysfd, p, oob, sa, 0)
+		if err == syscall.EAGAIN {
+			if err = fd.pd.WaitWrite(); err == nil {
+				continue
+			}
+		}
+		break
+	}
+	if err == nil {
+		oobn = len(oob)
+	} else {
+		err = &OpError{"write", fd.net, fd.raddr, err}
+	}
+	return
+}
+
+func (fd *netFD) accept() (netfd *netFD, err error) {
+	if err := fd.readLock(); err != nil {
+		return nil, err
+	}
+	defer fd.readUnlock()
+
+	var s int
+	var rsa syscall.Sockaddr
+	if err = fd.pd.PrepareRead(); err != nil {
+		return nil, &OpError{"accept", fd.net, fd.laddr, err}
+	}
+	for {
+		s, rsa, err = accept(fd.sysfd)
+		if err != nil {
+			if err == syscall.EAGAIN {
+				if err = fd.pd.WaitRead(); err == nil {
+					continue
+				}
+			} else if err == syscall.ECONNABORTED {
+				// This means that a socket on the listen queue was closed
+				// before we Accept()ed it; it's a silly error, so try again.
+				continue
+			}
+			return nil, &OpError{"accept", fd.net, fd.laddr, err}
+		}
+		break
+	}
+
+	if netfd, err = newFD(s, fd.family, fd.sotype, fd.net); err != nil {
+		closesocket(s)
+		return nil, err
+	}
+	if err = netfd.init(); err != nil {
+		fd.Close()
+		return nil, err
+	}
+	lsa, _ := syscall.Getsockname(netfd.sysfd)
+	netfd.setAddr(netfd.addrFunc()(lsa), netfd.addrFunc()(rsa))
+	return netfd, nil
+}
+
+// tryDupCloexec indicates whether F_DUPFD_CLOEXEC should be used.
+// If the kernel doesn't support it, this is set to 0.
+var tryDupCloexec = int32(1)
+
+func dupCloseOnExec(fd int) (newfd int, err error) {
+	if atomic.LoadInt32(&tryDupCloexec) == 1 {
+		r0, _, e1 := syscall.Syscall(syscall.SYS_FCNTL, uintptr(fd), syscall.F_DUPFD_CLOEXEC, 0)
+		if runtime.GOOS == "darwin" && e1 == syscall.EBADF {
+			// On OS X 10.6 and below (but we only support
+			// >= 10.6), F_DUPFD_CLOEXEC is unsupported
+			// and fcntl there falls back (undocumented)
+			// to doing an ioctl instead, returning EBADF
+			// in this case because fd is not of the
+			// expected device fd type.  Treat it as
+			// EINVAL instead, so we fall back to the
+			// normal dup path.
+			// TODO: only do this on 10.6 if we can detect 10.6
+			// cheaply.
+			e1 = syscall.EINVAL
+		}
+		switch e1 {
+		case 0:
+			return int(r0), nil
+		case syscall.EINVAL:
+			// Old kernel. Fall back to the portable way
+			// from now on.
+			atomic.StoreInt32(&tryDupCloexec, 0)
+		default:
+			return -1, e1
+		}
+	}
+	return dupCloseOnExecOld(fd)
+}
+
+// dupCloseOnExecUnixOld is the traditional way to dup an fd and
+// set its O_CLOEXEC bit, using two system calls.
+func dupCloseOnExecOld(fd int) (newfd int, err error) {
+	syscall.ForkLock.RLock()
+	defer syscall.ForkLock.RUnlock()
+	newfd, err = syscall.Dup(fd)
+	if err != nil {
+		return -1, err
+	}
+	syscall.CloseOnExec(newfd)
+	return
+}
+
+func (fd *netFD) dup() (f *os.File, err error) {
+	ns, err := dupCloseOnExec(fd.sysfd)
+	if err != nil {
+		return nil, &OpError{"dup", fd.net, fd.laddr, err}
+	}
+
+	// We want blocking mode for the new fd, hence the double negative.
+	// This also puts the old fd into blocking mode, meaning that
+	// I/O will block the thread instead of letting us use the epoll server.
+	// Everything will still work, just with more threads.
+	if err = syscall.SetNonblock(ns, false); err != nil {
+		return nil, &OpError{"setnonblock", fd.net, fd.laddr, err}
+	}
+
+	return os.NewFile(uintptr(ns), fd.name()), nil
+}
+
+func closesocket(s int) error {
+	return syscall.Close(s)
+}
+
+func skipRawSocketTests() (skip bool, skipmsg string, err error) {
+	if os.Getuid() != 0 {
+		return true, "skipping test; must be root", nil
+	}
+	return false, "", nil
+}
diff --git a/src/pkg/net/fd_unix_test.go b/src/net/fd_unix_test.go
similarity index 100%
rename from src/pkg/net/fd_unix_test.go
rename to src/net/fd_unix_test.go
diff --git a/src/net/fd_windows.go b/src/net/fd_windows.go
new file mode 100644
index 0000000..f3a534a
--- /dev/null
+++ b/src/net/fd_windows.go
@@ -0,0 +1,656 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package net
+
+import (
+	"errors"
+	"io"
+	"os"
+	"runtime"
+	"sync"
+	"syscall"
+	"time"
+	"unsafe"
+)
+
+var (
+	initErr error
+	ioSync  uint64
+)
+
+// CancelIo Windows API cancels all outstanding IO for a particular
+// socket on current thread. To overcome that limitation, we run
+// special goroutine, locked to OS single thread, that both starts
+// and cancels IO. It means, there are 2 unavoidable thread switches
+// for every IO.
+// Some newer versions of Windows has new CancelIoEx API, that does
+// not have that limitation and can be used from any thread. This
+// package uses CancelIoEx API, if present, otherwise it fallback
+// to CancelIo.
+
+var (
+	canCancelIO                               bool // determines if CancelIoEx API is present
+	skipSyncNotif                             bool
+	hasLoadSetFileCompletionNotificationModes bool
+)
+
+func sysInit() {
+	var d syscall.WSAData
+	e := syscall.WSAStartup(uint32(0x202), &d)
+	if e != nil {
+		initErr = os.NewSyscallError("WSAStartup", e)
+	}
+	canCancelIO = syscall.LoadCancelIoEx() == nil
+	if syscall.LoadGetAddrInfo() == nil {
+		lookupPort = newLookupPort
+		lookupIP = newLookupIP
+	}
+
+	hasLoadSetFileCompletionNotificationModes = syscall.LoadSetFileCompletionNotificationModes() == nil
+	if hasLoadSetFileCompletionNotificationModes {
+		// It's not safe to use FILE_SKIP_COMPLETION_PORT_ON_SUCCESS if non IFS providers are installed:
+		// http://support.microsoft.com/kb/2568167
+		skipSyncNotif = true
+		protos := [2]int32{syscall.IPPROTO_TCP, 0}
+		var buf [32]syscall.WSAProtocolInfo
+		len := uint32(unsafe.Sizeof(buf))
+		n, err := syscall.WSAEnumProtocols(&protos[0], &buf[0], &len)
+		if err != nil {
+			skipSyncNotif = false
+		} else {
+			for i := int32(0); i < n; i++ {
+				if buf[i].ServiceFlags1&syscall.XP1_IFS_HANDLES == 0 {
+					skipSyncNotif = false
+					break
+				}
+			}
+		}
+	}
+}
+
+func closesocket(s syscall.Handle) error {
+	return syscall.Closesocket(s)
+}
+
+func canUseConnectEx(net string) bool {
+	switch net {
+	case "udp", "udp4", "udp6", "ip", "ip4", "ip6":
+		// ConnectEx windows API does not support connectionless sockets.
+		return false
+	}
+	return syscall.LoadConnectEx() == nil
+}
+
+func dial(net string, ra Addr, dialer func(time.Time) (Conn, error), deadline time.Time) (Conn, error) {
+	if !canUseConnectEx(net) {
+		// Use the relatively inefficient goroutine-racing
+		// implementation of DialTimeout.
+		return dialChannel(net, ra, dialer, deadline)
+	}
+	return dialer(deadline)
+}
+
+// operation contains superset of data necessary to perform all async IO.
+type operation struct {
+	// Used by IOCP interface, it must be first field
+	// of the struct, as our code rely on it.
+	o syscall.Overlapped
+
+	// fields used by runtime.netpoll
+	runtimeCtx uintptr
+	mode       int32
+	errno      int32
+	qty        uint32
+
+	// fields used only by net package
+	fd     *netFD
+	errc   chan error
+	buf    syscall.WSABuf
+	sa     syscall.Sockaddr
+	rsa    *syscall.RawSockaddrAny
+	rsan   int32
+	handle syscall.Handle
+	flags  uint32
+}
+
+func (o *operation) InitBuf(buf []byte) {
+	o.buf.Len = uint32(len(buf))
+	o.buf.Buf = nil
+	if len(buf) != 0 {
+		o.buf.Buf = &buf[0]
+	}
+}
+
+// ioSrv executes net IO requests.
+type ioSrv struct {
+	req chan ioSrvReq
+}
+
+type ioSrvReq struct {
+	o      *operation
+	submit func(o *operation) error // if nil, cancel the operation
+}
+
+// ProcessRemoteIO will execute submit IO requests on behalf
+// of other goroutines, all on a single os thread, so it can
+// cancel them later. Results of all operations will be sent
+// back to their requesters via channel supplied in request.
+// It is used only when the CancelIoEx API is unavailable.
+func (s *ioSrv) ProcessRemoteIO() {
+	runtime.LockOSThread()
+	defer runtime.UnlockOSThread()
+	for r := range s.req {
+		if r.submit != nil {
+			r.o.errc <- r.submit(r.o)
+		} else {
+			r.o.errc <- syscall.CancelIo(r.o.fd.sysfd)
+		}
+	}
+}
+
+// ExecIO executes a single IO operation o. It submits and cancels
+// IO in the current thread for systems where Windows CancelIoEx API
+// is available. Alternatively, it passes the request onto
+// runtime netpoll and waits for completion or cancels request.
+func (s *ioSrv) ExecIO(o *operation, name string, submit func(o *operation) error) (int, error) {
+	fd := o.fd
+	// Notify runtime netpoll about starting IO.
+	err := fd.pd.Prepare(int(o.mode))
+	if err != nil {
+		return 0, &OpError{name, fd.net, fd.laddr, err}
+	}
+	// Start IO.
+	if canCancelIO {
+		err = submit(o)
+	} else {
+		// Send request to a special dedicated thread,
+		// so it can stop the IO with CancelIO later.
+		s.req <- ioSrvReq{o, submit}
+		err = <-o.errc
+	}
+	switch err {
+	case nil:
+		// IO completed immediately
+		if o.fd.skipSyncNotif {
+			// No completion message will follow, so return immediately.
+			return int(o.qty), nil
+		}
+		// Need to get our completion message anyway.
+	case syscall.ERROR_IO_PENDING:
+		// IO started, and we have to wait for its completion.
+		err = nil
+	default:
+		return 0, &OpError{name, fd.net, fd.laddr, err}
+	}
+	// Wait for our request to complete.
+	err = fd.pd.Wait(int(o.mode))
+	if err == nil {
+		// All is good. Extract our IO results and return.
+		if o.errno != 0 {
+			err = syscall.Errno(o.errno)
+			return 0, &OpError{name, fd.net, fd.laddr, err}
+		}
+		return int(o.qty), nil
+	}
+	// IO is interrupted by "close" or "timeout"
+	netpollErr := err
+	switch netpollErr {
+	case errClosing, errTimeout:
+		// will deal with those.
+	default:
+		panic("net: unexpected runtime.netpoll error: " + netpollErr.Error())
+	}
+	// Cancel our request.
+	if canCancelIO {
+		err := syscall.CancelIoEx(fd.sysfd, &o.o)
+		// Assuming ERROR_NOT_FOUND is returned, if IO is completed.
+		if err != nil && err != syscall.ERROR_NOT_FOUND {
+			// TODO(brainman): maybe do something else, but panic.
+			panic(err)
+		}
+	} else {
+		s.req <- ioSrvReq{o, nil}
+		<-o.errc
+	}
+	// Wait for cancellation to complete.
+	fd.pd.WaitCanceled(int(o.mode))
+	if o.errno != 0 {
+		err = syscall.Errno(o.errno)
+		if err == syscall.ERROR_OPERATION_ABORTED { // IO Canceled
+			err = netpollErr
+		}
+		return 0, &OpError{name, fd.net, fd.laddr, err}
+	}
+	// We issued cancellation request. But, it seems, IO operation succeeded
+	// before cancellation request run. We need to treat IO operation as
+	// succeeded (the bytes are actually sent/recv from network).
+	return int(o.qty), nil
+}
+
+// Start helper goroutines.
+var rsrv, wsrv *ioSrv
+var onceStartServer sync.Once
+
+func startServer() {
+	rsrv = new(ioSrv)
+	wsrv = new(ioSrv)
+	if !canCancelIO {
+		// Only CancelIo API is available. Lets start two special goroutines
+		// locked to an OS thread, that both starts and cancels IO. One will
+		// process read requests, while other will do writes.
+		rsrv.req = make(chan ioSrvReq)
+		go rsrv.ProcessRemoteIO()
+		wsrv.req = make(chan ioSrvReq)
+		go wsrv.ProcessRemoteIO()
+	}
+}
+
+// Network file descriptor.
+type netFD struct {
+	// locking/lifetime of sysfd + serialize access to Read and Write methods
+	fdmu fdMutex
+
+	// immutable until Close
+	sysfd         syscall.Handle
+	family        int
+	sotype        int
+	isConnected   bool
+	skipSyncNotif bool
+	net           string
+	laddr         Addr
+	raddr         Addr
+
+	rop operation // read operation
+	wop operation // write operation
+
+	// wait server
+	pd pollDesc
+}
+
+func newFD(sysfd syscall.Handle, family, sotype int, net string) (*netFD, error) {
+	if initErr != nil {
+		return nil, initErr
+	}
+	onceStartServer.Do(startServer)
+	return &netFD{sysfd: sysfd, family: family, sotype: sotype, net: net}, nil
+}
+
+func (fd *netFD) init() error {
+	if err := fd.pd.Init(fd); err != nil {
+		return err
+	}
+	if hasLoadSetFileCompletionNotificationModes {
+		// We do not use events, so we can skip them always.
+		flags := uint8(syscall.FILE_SKIP_SET_EVENT_ON_HANDLE)
+		// It's not safe to skip completion notifications for UDP:
+		// http://blogs.technet.com/b/winserverperformance/archive/2008/06/26/designing-applications-for-high-performance-part-iii.aspx
+		if skipSyncNotif && fd.net == "tcp" {
+			flags |= syscall.FILE_SKIP_COMPLETION_PORT_ON_SUCCESS
+		}
+		err := syscall.SetFileCompletionNotificationModes(fd.sysfd, flags)
+		if err == nil && flags&syscall.FILE_SKIP_COMPLETION_PORT_ON_SUCCESS != 0 {
+			fd.skipSyncNotif = true
+		}
+	}
+	// Disable SIO_UDP_CONNRESET behavior.
+	// http://support.microsoft.com/kb/263823
+	switch fd.net {
+	case "udp", "udp4", "udp6":
+		ret := uint32(0)
+		flag := uint32(0)
+		size := uint32(unsafe.Sizeof(flag))
+		err := syscall.WSAIoctl(fd.sysfd, syscall.SIO_UDP_CONNRESET, (*byte)(unsafe.Pointer(&flag)), size, nil, 0, &ret, nil, 0)
+		if err != nil {
+			return os.NewSyscallError("WSAIoctl", err)
+		}
+	}
+	fd.rop.mode = 'r'
+	fd.wop.mode = 'w'
+	fd.rop.fd = fd
+	fd.wop.fd = fd
+	fd.rop.runtimeCtx = fd.pd.runtimeCtx
+	fd.wop.runtimeCtx = fd.pd.runtimeCtx
+	if !canCancelIO {
+		fd.rop.errc = make(chan error)
+		fd.wop.errc = make(chan error)
+	}
+	return nil
+}
+
+func (fd *netFD) setAddr(laddr, raddr Addr) {
+	fd.laddr = laddr
+	fd.raddr = raddr
+	runtime.SetFinalizer(fd, (*netFD).Close)
+}
+
+func (fd *netFD) connect(la, ra syscall.Sockaddr, deadline time.Time) error {
+	// Do not need to call fd.writeLock here,
+	// because fd is not yet accessible to user,
+	// so no concurrent operations are possible.
+	if err := fd.init(); err != nil {
+		return err
+	}
+	if !deadline.IsZero() {
+		fd.setWriteDeadline(deadline)
+		defer fd.setWriteDeadline(noDeadline)
+	}
+	if !canUseConnectEx(fd.net) {
+		return syscall.Connect(fd.sysfd, ra)
+	}
+	// ConnectEx windows API requires an unconnected, previously bound socket.
+	if la == nil {
+		switch ra.(type) {
+		case *syscall.SockaddrInet4:
+			la = &syscall.SockaddrInet4{}
+		case *syscall.SockaddrInet6:
+			la = &syscall.SockaddrInet6{}
+		default:
+			panic("unexpected type in connect")
+		}
+		if err := syscall.Bind(fd.sysfd, la); err != nil {
+			return err
+		}
+	}
+	// Call ConnectEx API.
+	o := &fd.wop
+	o.sa = ra
+	_, err := wsrv.ExecIO(o, "ConnectEx", func(o *operation) error {
+		return syscall.ConnectEx(o.fd.sysfd, o.sa, nil, 0, nil, &o.o)
+	})
+	if err != nil {
+		return err
+	}
+	// Refresh socket properties.
+	return syscall.Setsockopt(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_UPDATE_CONNECT_CONTEXT, (*byte)(unsafe.Pointer(&fd.sysfd)), int32(unsafe.Sizeof(fd.sysfd)))
+}
+
+func (fd *netFD) destroy() {
+	if fd.sysfd == syscall.InvalidHandle {
+		return
+	}
+	// Poller may want to unregister fd in readiness notification mechanism,
+	// so this must be executed before closesocket.
+	fd.pd.Close()
+	closesocket(fd.sysfd)
+	fd.sysfd = syscall.InvalidHandle
+	// no need for a finalizer anymore
+	runtime.SetFinalizer(fd, nil)
+}
+
+// Add a reference to this fd.
+// Returns an error if the fd cannot be used.
+func (fd *netFD) incref() error {
+	if !fd.fdmu.Incref() {
+		return errClosing
+	}
+	return nil
+}
+
+// Remove a reference to this FD and close if we've been asked to do so
+// (and there are no references left).
+func (fd *netFD) decref() {
+	if fd.fdmu.Decref() {
+		fd.destroy()
+	}
+}
+
+// Add a reference to this fd and lock for reading.
+// Returns an error if the fd cannot be used.
+func (fd *netFD) readLock() error {
+	if !fd.fdmu.RWLock(true) {
+		return errClosing
+	}
+	return nil
+}
+
+// Unlock for reading and remove a reference to this FD.
+func (fd *netFD) readUnlock() {
+	if fd.fdmu.RWUnlock(true) {
+		fd.destroy()
+	}
+}
+
+// Add a reference to this fd and lock for writing.
+// Returns an error if the fd cannot be used.
+func (fd *netFD) writeLock() error {
+	if !fd.fdmu.RWLock(false) {
+		return errClosing
+	}
+	return nil
+}
+
+// Unlock for writing and remove a reference to this FD.
+func (fd *netFD) writeUnlock() {
+	if fd.fdmu.RWUnlock(false) {
+		fd.destroy()
+	}
+}
+
+func (fd *netFD) Close() error {
+	if !fd.fdmu.IncrefAndClose() {
+		return errClosing
+	}
+	// unblock pending reader and writer
+	fd.pd.Evict()
+	fd.decref()
+	return nil
+}
+
+func (fd *netFD) shutdown(how int) error {
+	if err := fd.incref(); err != nil {
+		return err
+	}
+	defer fd.decref()
+	err := syscall.Shutdown(fd.sysfd, how)
+	if err != nil {
+		return &OpError{"shutdown", fd.net, fd.laddr, err}
+	}
+	return nil
+}
+
+func (fd *netFD) closeRead() error {
+	return fd.shutdown(syscall.SHUT_RD)
+}
+
+func (fd *netFD) closeWrite() error {
+	return fd.shutdown(syscall.SHUT_WR)
+}
+
+func (fd *netFD) Read(buf []byte) (int, error) {
+	if err := fd.readLock(); err != nil {
+		return 0, err
+	}
+	defer fd.readUnlock()
+	o := &fd.rop
+	o.InitBuf(buf)
+	n, err := rsrv.ExecIO(o, "WSARecv", func(o *operation) error {
+		return syscall.WSARecv(o.fd.sysfd, &o.buf, 1, &o.qty, &o.flags, &o.o, nil)
+	})
+	if err == nil && n == 0 {
+		err = io.EOF
+	}
+	if raceenabled {
+		raceAcquire(unsafe.Pointer(&ioSync))
+	}
+	return n, err
+}
+
+func (fd *netFD) readFrom(buf []byte) (n int, sa syscall.Sockaddr, err error) {
+	if len(buf) == 0 {
+		return 0, nil, nil
+	}
+	if err := fd.readLock(); err != nil {
+		return 0, nil, err
+	}
+	defer fd.readUnlock()
+	o := &fd.rop
+	o.InitBuf(buf)
+	n, err = rsrv.ExecIO(o, "WSARecvFrom", func(o *operation) error {
+		if o.rsa == nil {
+			o.rsa = new(syscall.RawSockaddrAny)
+		}
+		o.rsan = int32(unsafe.Sizeof(*o.rsa))
+		return syscall.WSARecvFrom(o.fd.sysfd, &o.buf, 1, &o.qty, &o.flags, o.rsa, &o.rsan, &o.o, nil)
+	})
+	if err != nil {
+		return 0, nil, err
+	}
+	sa, _ = o.rsa.Sockaddr()
+	return
+}
+
+func (fd *netFD) Write(buf []byte) (int, error) {
+	if err := fd.writeLock(); err != nil {
+		return 0, err
+	}
+	defer fd.writeUnlock()
+	if raceenabled {
+		raceReleaseMerge(unsafe.Pointer(&ioSync))
+	}
+	o := &fd.wop
+	o.InitBuf(buf)
+	return wsrv.ExecIO(o, "WSASend", func(o *operation) error {
+		return syscall.WSASend(o.fd.sysfd, &o.buf, 1, &o.qty, 0, &o.o, nil)
+	})
+}
+
+func (fd *netFD) writeTo(buf []byte, sa syscall.Sockaddr) (int, error) {
+	if len(buf) == 0 {
+		return 0, nil
+	}
+	if err := fd.writeLock(); err != nil {
+		return 0, err
+	}
+	defer fd.writeUnlock()
+	o := &fd.wop
+	o.InitBuf(buf)
+	o.sa = sa
+	return wsrv.ExecIO(o, "WSASendto", func(o *operation) error {
+		return syscall.WSASendto(o.fd.sysfd, &o.buf, 1, &o.qty, 0, o.sa, &o.o, nil)
+	})
+}
+
+func (fd *netFD) acceptOne(rawsa []syscall.RawSockaddrAny, o *operation) (*netFD, error) {
+	// Get new socket.
+	s, err := sysSocket(fd.family, fd.sotype, 0)
+	if err != nil {
+		return nil, &OpError{"socket", fd.net, fd.laddr, err}
+	}
+
+	// Associate our new socket with IOCP.
+	netfd, err := newFD(s, fd.family, fd.sotype, fd.net)
+	if err != nil {
+		closesocket(s)
+		return nil, &OpError{"accept", fd.net, fd.laddr, err}
+	}
+	if err := netfd.init(); err != nil {
+		fd.Close()
+		return nil, err
+	}
+
+	// Submit accept request.
+	o.handle = s
+	o.rsan = int32(unsafe.Sizeof(rawsa[0]))
+	_, err = rsrv.ExecIO(o, "AcceptEx", func(o *operation) error {
+		return syscall.AcceptEx(o.fd.sysfd, o.handle, (*byte)(unsafe.Pointer(&rawsa[0])), 0, uint32(o.rsan), uint32(o.rsan), &o.qty, &o.o)
+	})
+	if err != nil {
+		netfd.Close()
+		return nil, err
+	}
+
+	// Inherit properties of the listening socket.
+	err = syscall.Setsockopt(s, syscall.SOL_SOCKET, syscall.SO_UPDATE_ACCEPT_CONTEXT, (*byte)(unsafe.Pointer(&fd.sysfd)), int32(unsafe.Sizeof(fd.sysfd)))
+	if err != nil {
+		netfd.Close()
+		return nil, &OpError{"Setsockopt", fd.net, fd.laddr, err}
+	}
+
+	return netfd, nil
+}
+
+func (fd *netFD) accept() (*netFD, error) {
+	if err := fd.readLock(); err != nil {
+		return nil, err
+	}
+	defer fd.readUnlock()
+
+	o := &fd.rop
+	var netfd *netFD
+	var err error
+	var rawsa [2]syscall.RawSockaddrAny
+	for {
+		netfd, err = fd.acceptOne(rawsa[:], o)
+		if err == nil {
+			break
+		}
+		// Sometimes we see WSAECONNRESET and ERROR_NETNAME_DELETED is
+		// returned here. These happen if connection reset is received
+		// before AcceptEx could complete. These errors relate to new
+		// connection, not to AcceptEx, so ignore broken connection and
+		// try AcceptEx again for more connections.
+		operr, ok := err.(*OpError)
+		if !ok {
+			return nil, err
+		}
+		errno, ok := operr.Err.(syscall.Errno)
+		if !ok {
+			return nil, err
+		}
+		switch errno {
+		case syscall.ERROR_NETNAME_DELETED, syscall.WSAECONNRESET:
+			// ignore these and try again
+		default:
+			return nil, err
+		}
+	}
+
+	// Get local and peer addr out of AcceptEx buffer.
+	var lrsa, rrsa *syscall.RawSockaddrAny
+	var llen, rlen int32
+	syscall.GetAcceptExSockaddrs((*byte)(unsafe.Pointer(&rawsa[0])),
+		0, uint32(o.rsan), uint32(o.rsan), &lrsa, &llen, &rrsa, &rlen)
+	lsa, _ := lrsa.Sockaddr()
+	rsa, _ := rrsa.Sockaddr()
+
+	netfd.setAddr(netfd.addrFunc()(lsa), netfd.addrFunc()(rsa))
+	return netfd, nil
+}
+
+func skipRawSocketTests() (skip bool, skipmsg string, err error) {
+	// From http://msdn.microsoft.com/en-us/library/windows/desktop/ms740548.aspx:
+	// Note: To use a socket of type SOCK_RAW requires administrative privileges.
+	// Users running Winsock applications that use raw sockets must be a member of
+	// the Administrators group on the local computer, otherwise raw socket calls
+	// will fail with an error code of WSAEACCES. On Windows Vista and later, access
+	// for raw sockets is enforced at socket creation. In earlier versions of Windows,
+	// access for raw sockets is enforced during other socket operations.
+	s, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_RAW, 0)
+	if err == syscall.WSAEACCES {
+		return true, "skipping test; no access to raw socket allowed", nil
+	}
+	if err != nil {
+		return true, "", err
+	}
+	defer syscall.Closesocket(s)
+	return false, "", nil
+}
+
+// Unimplemented functions.
+
+func (fd *netFD) dup() (*os.File, error) {
+	// TODO: Implement this
+	return nil, os.NewSyscallError("dup", syscall.EWINDOWS)
+}
+
+var errNoSupport = errors.New("address family not supported")
+
+func (fd *netFD) readMsg(p []byte, oob []byte) (n, oobn, flags int, sa syscall.Sockaddr, err error) {
+	return 0, 0, 0, nil, errNoSupport
+}
+
+func (fd *netFD) writeMsg(p []byte, oob []byte, sa syscall.Sockaddr) (n int, oobn int, err error) {
+	return 0, 0, errNoSupport
+}
diff --git a/src/pkg/net/file_plan9.go b/src/net/file_plan9.go
similarity index 100%
rename from src/pkg/net/file_plan9.go
rename to src/net/file_plan9.go
diff --git a/src/net/file_stub.go b/src/net/file_stub.go
new file mode 100644
index 0000000..4281072
--- /dev/null
+++ b/src/net/file_stub.go
@@ -0,0 +1,38 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build nacl
+
+package net
+
+import (
+	"os"
+	"syscall"
+)
+
+// FileConn returns a copy of the network connection corresponding to
+// the open file f.  It is the caller's responsibility to close f when
+// finished.  Closing c does not affect f, and closing f does not
+// affect c.
+func FileConn(f *os.File) (c Conn, err error) {
+	return nil, syscall.ENOPROTOOPT
+
+}
+
+// FileListener returns a copy of the network listener corresponding
+// to the open file f.  It is the caller's responsibility to close l
+// when finished.  Closing l does not affect f, and closing f does not
+// affect l.
+func FileListener(f *os.File) (l Listener, err error) {
+	return nil, syscall.ENOPROTOOPT
+
+}
+
+// FilePacketConn returns a copy of the packet network connection
+// corresponding to the open file f.  It is the caller's
+// responsibility to close f when finished.  Closing c does not affect
+// f, and closing f does not affect c.
+func FilePacketConn(f *os.File) (c PacketConn, err error) {
+	return nil, syscall.ENOPROTOOPT
+}
diff --git a/src/net/file_test.go b/src/net/file_test.go
new file mode 100644
index 0000000..6fab06a
--- /dev/null
+++ b/src/net/file_test.go
@@ -0,0 +1,205 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package net
+
+import (
+	"os"
+	"reflect"
+	"runtime"
+	"testing"
+)
+
+type listenerFile interface {
+	Listener
+	File() (f *os.File, err error)
+}
+
+type packetConnFile interface {
+	PacketConn
+	File() (f *os.File, err error)
+}
+
+type connFile interface {
+	Conn
+	File() (f *os.File, err error)
+}
+
+func testFileListener(t *testing.T, net, laddr string) {
+	switch net {
+	case "tcp", "tcp4", "tcp6":
+		laddr += ":0" // any available port
+	}
+	l, err := Listen(net, laddr)
+	if err != nil {
+		t.Fatalf("Listen failed: %v", err)
+	}
+	defer l.Close()
+	lf := l.(listenerFile)
+	f, err := lf.File()
+	if err != nil {
+		t.Fatalf("File failed: %v", err)
+	}
+	c, err := FileListener(f)
+	if err != nil {
+		t.Fatalf("FileListener failed: %v", err)
+	}
+	if !reflect.DeepEqual(l.Addr(), c.Addr()) {
+		t.Fatalf("Addrs not equal: %#v != %#v", l.Addr(), c.Addr())
+	}
+	if err := c.Close(); err != nil {
+		t.Fatalf("Close failed: %v", err)
+	}
+	if err := f.Close(); err != nil {
+		t.Fatalf("Close failed: %v", err)
+	}
+}
+
+var fileListenerTests = []struct {
+	net   string
+	laddr string
+	ipv6  bool // test with underlying AF_INET6 socket
+	linux bool // test with abstract unix domain socket, a Linux-ism
+}{
+	{net: "tcp", laddr: ""},
+	{net: "tcp", laddr: "0.0.0.0"},
+	{net: "tcp", laddr: "[::ffff:0.0.0.0]"},
+	{net: "tcp", laddr: "[::]", ipv6: true},
+
+	{net: "tcp", laddr: "127.0.0.1"},
+	{net: "tcp", laddr: "[::ffff:127.0.0.1]"},
+	{net: "tcp", laddr: "[::1]", ipv6: true},
+
+	{net: "tcp4", laddr: ""},
+	{net: "tcp4", laddr: "0.0.0.0"},
+	{net: "tcp4", laddr: "[::ffff:0.0.0.0]"},
+
+	{net: "tcp4", laddr: "127.0.0.1"},
+	{net: "tcp4", laddr: "[::ffff:127.0.0.1]"},
+
+	{net: "tcp6", laddr: "", ipv6: true},
+	{net: "tcp6", laddr: "[::]", ipv6: true},
+
+	{net: "tcp6", laddr: "[::1]", ipv6: true},
+
+	{net: "unix", laddr: "@gotest/net", linux: true},
+	{net: "unixpacket", laddr: "@gotest/net", linux: true},
+}
+
+func TestFileListener(t *testing.T) {
+	switch runtime.GOOS {
+	case "nacl", "windows":
+		t.Skipf("skipping test on %q", runtime.GOOS)
+	}
+
+	for _, tt := range fileListenerTests {
+		if skipServerTest(tt.net, "unix", tt.laddr, tt.ipv6, false, tt.linux) {
+			continue
+		}
+		if skipServerTest(tt.net, "unixpacket", tt.laddr, tt.ipv6, false, tt.linux) {
+			continue
+		}
+		testFileListener(t, tt.net, tt.laddr)
+	}
+}
+
+func testFilePacketConn(t *testing.T, pcf packetConnFile, listen bool) {
+	f, err := pcf.File()
+	if err != nil {
+		t.Fatalf("File failed: %v", err)
+	}
+	c, err := FilePacketConn(f)
+	if err != nil {
+		t.Fatalf("FilePacketConn failed: %v", err)
+	}
+	if !reflect.DeepEqual(pcf.LocalAddr(), c.LocalAddr()) {
+		t.Fatalf("LocalAddrs not equal: %#v != %#v", pcf.LocalAddr(), c.LocalAddr())
+	}
+	if listen {
+		if _, err := c.WriteTo([]byte{}, c.LocalAddr()); err != nil {
+			t.Fatalf("WriteTo failed: %v", err)
+		}
+	}
+	if err := c.Close(); err != nil {
+		t.Fatalf("Close failed: %v", err)
+	}
+	if err := f.Close(); err != nil {
+		t.Fatalf("Close failed: %v", err)
+	}
+}
+
+func testFilePacketConnListen(t *testing.T, net, laddr string) {
+	switch net {
+	case "udp", "udp4", "udp6":
+		laddr += ":0" // any available port
+	}
+	l, err := ListenPacket(net, laddr)
+	if err != nil {
+		t.Fatalf("ListenPacket failed: %v", err)
+	}
+	testFilePacketConn(t, l.(packetConnFile), true)
+	if err := l.Close(); err != nil {
+		t.Fatalf("Close failed: %v", err)
+	}
+}
+
+func testFilePacketConnDial(t *testing.T, net, raddr string) {
+	switch net {
+	case "udp", "udp4", "udp6":
+		raddr += ":12345"
+	}
+	c, err := Dial(net, raddr)
+	if err != nil {
+		t.Fatalf("Dial failed: %v", err)
+	}
+	testFilePacketConn(t, c.(packetConnFile), false)
+	if err := c.Close(); err != nil {
+		t.Fatalf("Close failed: %v", err)
+	}
+}
+
+var filePacketConnTests = []struct {
+	net   string
+	addr  string
+	ipv6  bool // test with underlying AF_INET6 socket
+	linux bool // test with abstract unix domain socket, a Linux-ism
+}{
+	{net: "udp", addr: "127.0.0.1"},
+	{net: "udp", addr: "[::ffff:127.0.0.1]"},
+	{net: "udp", addr: "[::1]", ipv6: true},
+
+	{net: "udp4", addr: "127.0.0.1"},
+	{net: "udp4", addr: "[::ffff:127.0.0.1]"},
+
+	{net: "udp6", addr: "[::1]", ipv6: true},
+
+	{net: "ip4:icmp", addr: "127.0.0.1"},
+
+	{net: "unixgram", addr: "@gotest3/net", linux: true},
+}
+
+func TestFilePacketConn(t *testing.T) {
+	switch runtime.GOOS {
+	case "nacl", "plan9", "windows":
+		t.Skipf("skipping test on %q", runtime.GOOS)
+	}
+
+	for _, tt := range filePacketConnTests {
+		if skipServerTest(tt.net, "unixgram", tt.addr, tt.ipv6, false, tt.linux) {
+			continue
+		}
+		if os.Getuid() != 0 && tt.net == "ip4:icmp" {
+			t.Log("skipping test; must be root")
+			continue
+		}
+		testFilePacketConnListen(t, tt.net, tt.addr)
+		switch tt.addr {
+		case "", "0.0.0.0", "[::ffff:0.0.0.0]", "[::]":
+		default:
+			if tt.net != "unixgram" {
+				testFilePacketConnDial(t, tt.net, tt.addr)
+			}
+		}
+	}
+}
diff --git a/src/net/file_unix.go b/src/net/file_unix.go
new file mode 100644
index 0000000..214a419
--- /dev/null
+++ b/src/net/file_unix.go
@@ -0,0 +1,139 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin dragonfly freebsd linux netbsd openbsd solaris
+
+package net
+
+import (
+	"os"
+	"syscall"
+)
+
+func newFileFD(f *os.File) (*netFD, error) {
+	fd, err := dupCloseOnExec(int(f.Fd()))
+	if err != nil {
+		return nil, os.NewSyscallError("dup", err)
+	}
+
+	if err = syscall.SetNonblock(fd, true); err != nil {
+		closesocket(fd)
+		return nil, err
+	}
+
+	sotype, err := syscall.GetsockoptInt(fd, syscall.SOL_SOCKET, syscall.SO_TYPE)
+	if err != nil {
+		closesocket(fd)
+		return nil, os.NewSyscallError("getsockopt", err)
+	}
+
+	family := syscall.AF_UNSPEC
+	toAddr := sockaddrToTCP
+	lsa, _ := syscall.Getsockname(fd)
+	switch lsa.(type) {
+	default:
+		closesocket(fd)
+		return nil, syscall.EINVAL
+	case *syscall.SockaddrInet4:
+		family = syscall.AF_INET
+		if sotype == syscall.SOCK_DGRAM {
+			toAddr = sockaddrToUDP
+		} else if sotype == syscall.SOCK_RAW {
+			toAddr = sockaddrToIP
+		}
+	case *syscall.SockaddrInet6:
+		family = syscall.AF_INET6
+		if sotype == syscall.SOCK_DGRAM {
+			toAddr = sockaddrToUDP
+		} else if sotype == syscall.SOCK_RAW {
+			toAddr = sockaddrToIP
+		}
+	case *syscall.SockaddrUnix:
+		family = syscall.AF_UNIX
+		toAddr = sockaddrToUnix
+		if sotype == syscall.SOCK_DGRAM {
+			toAddr = sockaddrToUnixgram
+		} else if sotype == syscall.SOCK_SEQPACKET {
+			toAddr = sockaddrToUnixpacket
+		}
+	}
+	laddr := toAddr(lsa)
+	rsa, _ := syscall.Getpeername(fd)
+	raddr := toAddr(rsa)
+
+	netfd, err := newFD(fd, family, sotype, laddr.Network())
+	if err != nil {
+		closesocket(fd)
+		return nil, err
+	}
+	if err := netfd.init(); err != nil {
+		netfd.Close()
+		return nil, err
+	}
+	netfd.setAddr(laddr, raddr)
+	return netfd, nil
+}
+
+// FileConn returns a copy of the network connection corresponding to
+// the open file f.  It is the caller's responsibility to close f when
+// finished.  Closing c does not affect f, and closing f does not
+// affect c.
+func FileConn(f *os.File) (c Conn, err error) {
+	fd, err := newFileFD(f)
+	if err != nil {
+		return nil, err
+	}
+	switch fd.laddr.(type) {
+	case *TCPAddr:
+		return newTCPConn(fd), nil
+	case *UDPAddr:
+		return newUDPConn(fd), nil
+	case *IPAddr:
+		return newIPConn(fd), nil
+	case *UnixAddr:
+		return newUnixConn(fd), nil
+	}
+	fd.Close()
+	return nil, syscall.EINVAL
+}
+
+// FileListener returns a copy of the network listener corresponding
+// to the open file f.  It is the caller's responsibility to close l
+// when finished.  Closing l does not affect f, and closing f does not
+// affect l.
+func FileListener(f *os.File) (l Listener, err error) {
+	fd, err := newFileFD(f)
+	if err != nil {
+		return nil, err
+	}
+	switch laddr := fd.laddr.(type) {
+	case *TCPAddr:
+		return &TCPListener{fd}, nil
+	case *UnixAddr:
+		return &UnixListener{fd, laddr.Name}, nil
+	}
+	fd.Close()
+	return nil, syscall.EINVAL
+}
+
+// FilePacketConn returns a copy of the packet network connection
+// corresponding to the open file f.  It is the caller's
+// responsibility to close f when finished.  Closing c does not affect
+// f, and closing f does not affect c.
+func FilePacketConn(f *os.File) (c PacketConn, err error) {
+	fd, err := newFileFD(f)
+	if err != nil {
+		return nil, err
+	}
+	switch fd.laddr.(type) {
+	case *UDPAddr:
+		return newUDPConn(fd), nil
+	case *IPAddr:
+		return newIPConn(fd), nil
+	case *UnixAddr:
+		return newUnixConn(fd), nil
+	}
+	fd.Close()
+	return nil, syscall.EINVAL
+}
diff --git a/src/pkg/net/file_windows.go b/src/net/file_windows.go
similarity index 100%
rename from src/pkg/net/file_windows.go
rename to src/net/file_windows.go
diff --git a/src/net/hosts.go b/src/net/hosts.go
new file mode 100644
index 0000000..9400503
--- /dev/null
+++ b/src/net/hosts.go
@@ -0,0 +1,86 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Read static host/IP entries from /etc/hosts.
+
+package net
+
+import (
+	"sync"
+	"time"
+)
+
+const cacheMaxAge = 5 * time.Minute
+
+// hostsPath points to the file with static IP/address entries.
+var hostsPath = "/etc/hosts"
+
+// Simple cache.
+var hosts struct {
+	sync.Mutex
+	byName map[string][]string
+	byAddr map[string][]string
+	expire time.Time
+	path   string
+}
+
+func readHosts() {
+	now := time.Now()
+	hp := hostsPath
+	if len(hosts.byName) == 0 || now.After(hosts.expire) || hosts.path != hp {
+		hs := make(map[string][]string)
+		is := make(map[string][]string)
+		var file *file
+		if file, _ = open(hp); file == nil {
+			return
+		}
+		for line, ok := file.readLine(); ok; line, ok = file.readLine() {
+			if i := byteIndex(line, '#'); i >= 0 {
+				// Discard comments.
+				line = line[0:i]
+			}
+			f := getFields(line)
+			if len(f) < 2 || ParseIP(f[0]) == nil {
+				continue
+			}
+			for i := 1; i < len(f); i++ {
+				h := f[i]
+				hs[h] = append(hs[h], f[0])
+				is[f[0]] = append(is[f[0]], h)
+			}
+		}
+		// Update the data cache.
+		hosts.expire = now.Add(cacheMaxAge)
+		hosts.path = hp
+		hosts.byName = hs
+		hosts.byAddr = is
+		file.close()
+	}
+}
+
+// lookupStaticHost looks up the addresses for the given host from /etc/hosts.
+func lookupStaticHost(host string) []string {
+	hosts.Lock()
+	defer hosts.Unlock()
+	readHosts()
+	if len(hosts.byName) != 0 {
+		if ips, ok := hosts.byName[host]; ok {
+			return ips
+		}
+	}
+	return nil
+}
+
+// lookupStaticAddr looks up the hosts for the given address from /etc/hosts.
+func lookupStaticAddr(addr string) []string {
+	hosts.Lock()
+	defer hosts.Unlock()
+	readHosts()
+	if len(hosts.byAddr) != 0 {
+		if hosts, ok := hosts.byAddr[addr]; ok {
+			return hosts
+		}
+	}
+	return nil
+}
diff --git a/src/pkg/net/hosts_test.go b/src/net/hosts_test.go
similarity index 100%
rename from src/pkg/net/hosts_test.go
rename to src/net/hosts_test.go
diff --git a/src/pkg/net/http/cgi/child.go b/src/net/http/cgi/child.go
similarity index 100%
rename from src/pkg/net/http/cgi/child.go
rename to src/net/http/cgi/child.go
diff --git a/src/pkg/net/http/cgi/child_test.go b/src/net/http/cgi/child_test.go
similarity index 100%
rename from src/pkg/net/http/cgi/child_test.go
rename to src/net/http/cgi/child_test.go
diff --git a/src/pkg/net/http/cgi/host.go b/src/net/http/cgi/host.go
similarity index 100%
rename from src/pkg/net/http/cgi/host.go
rename to src/net/http/cgi/host.go
diff --git a/src/pkg/net/http/cgi/host_test.go b/src/net/http/cgi/host_test.go
similarity index 100%
rename from src/pkg/net/http/cgi/host_test.go
rename to src/net/http/cgi/host_test.go
diff --git a/src/pkg/net/http/cgi/matryoshka_test.go b/src/net/http/cgi/matryoshka_test.go
similarity index 100%
rename from src/pkg/net/http/cgi/matryoshka_test.go
rename to src/net/http/cgi/matryoshka_test.go
diff --git a/src/pkg/net/http/cgi/plan9_test.go b/src/net/http/cgi/plan9_test.go
similarity index 100%
rename from src/pkg/net/http/cgi/plan9_test.go
rename to src/net/http/cgi/plan9_test.go
diff --git a/src/pkg/net/http/cgi/posix_test.go b/src/net/http/cgi/posix_test.go
similarity index 100%
rename from src/pkg/net/http/cgi/posix_test.go
rename to src/net/http/cgi/posix_test.go
diff --git a/src/pkg/net/http/cgi/testdata/test.cgi b/src/net/http/cgi/testdata/test.cgi
similarity index 100%
rename from src/pkg/net/http/cgi/testdata/test.cgi
rename to src/net/http/cgi/testdata/test.cgi
diff --git a/src/net/http/client.go b/src/net/http/client.go
new file mode 100644
index 0000000..ce884d1
--- /dev/null
+++ b/src/net/http/client.go
@@ -0,0 +1,511 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// HTTP client. See RFC 2616.
+//
+// This is the high-level Client interface.
+// The low-level implementation is in transport.go.
+
+package http
+
+import (
+	"encoding/base64"
+	"errors"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"log"
+	"net/url"
+	"strings"
+	"sync"
+	"time"
+)
+
+// A Client is an HTTP client. Its zero value (DefaultClient) is a
+// usable client that uses DefaultTransport.
+//
+// The Client's Transport typically has internal state (cached TCP
+// connections), so Clients should be reused instead of created as
+// needed. Clients are safe for concurrent use by multiple goroutines.
+//
+// A Client is higher-level than a RoundTripper (such as Transport)
+// and additionally handles HTTP details such as cookies and
+// redirects.
+type Client struct {
+	// Transport specifies the mechanism by which individual
+	// HTTP requests are made.
+	// If nil, DefaultTransport is used.
+	Transport RoundTripper
+
+	// CheckRedirect specifies the policy for handling redirects.
+	// If CheckRedirect is not nil, the client calls it before
+	// following an HTTP redirect. The arguments req and via are
+	// the upcoming request and the requests made already, oldest
+	// first. If CheckRedirect returns an error, the Client's Get
+	// method returns both the previous Response and
+	// CheckRedirect's error (wrapped in a url.Error) instead of
+	// issuing the Request req.
+	//
+	// If CheckRedirect is nil, the Client uses its default policy,
+	// which is to stop after 10 consecutive requests.
+	CheckRedirect func(req *Request, via []*Request) error
+
+	// Jar specifies the cookie jar.
+	// If Jar is nil, cookies are not sent in requests and ignored
+	// in responses.
+	Jar CookieJar
+
+	// Timeout specifies a time limit for requests made by this
+	// Client. The timeout includes connection time, any
+	// redirects, and reading the response body. The timer remains
+	// running after Get, Head, Post, or Do return and will
+	// interrupt reading of the Response.Body.
+	//
+	// A Timeout of zero means no timeout.
+	//
+	// The Client's Transport must support the CancelRequest
+	// method or Client will return errors when attempting to make
+	// a request with Get, Head, Post, or Do. Client's default
+	// Transport (DefaultTransport) supports CancelRequest.
+	Timeout time.Duration
+}
+
+// DefaultClient is the default Client and is used by Get, Head, and Post.
+var DefaultClient = &Client{}
+
+// RoundTripper is an interface representing the ability to execute a
+// single HTTP transaction, obtaining the Response for a given Request.
+//
+// A RoundTripper must be safe for concurrent use by multiple
+// goroutines.
+type RoundTripper interface {
+	// RoundTrip executes a single HTTP transaction, returning
+	// the Response for the request req.  RoundTrip should not
+	// attempt to interpret the response.  In particular,
+	// RoundTrip must return err == nil if it obtained a response,
+	// regardless of the response's HTTP status code.  A non-nil
+	// err should be reserved for failure to obtain a response.
+	// Similarly, RoundTrip should not attempt to handle
+	// higher-level protocol details such as redirects,
+	// authentication, or cookies.
+	//
+	// RoundTrip should not modify the request, except for
+	// consuming and closing the Body, including on errors. The
+	// request's URL and Header fields are guaranteed to be
+	// initialized.
+	RoundTrip(*Request) (*Response, error)
+}
+
+// Given a string of the form "host", "host:port", or "[ipv6::address]:port",
+// return true if the string includes a port.
+func hasPort(s string) bool { return strings.LastIndex(s, ":") > strings.LastIndex(s, "]") }
+
+// refererForURL returns a referer without any authentication info or
+// an empty string if lastReq scheme is https and newReq scheme is http.
+func refererForURL(lastReq, newReq *url.URL) string {
+	// https://tools.ietf.org/html/rfc7231#section-5.5.2
+	//   "Clients SHOULD NOT include a Referer header field in a
+	//    (non-secure) HTTP request if the referring page was
+	//    transferred with a secure protocol."
+	if lastReq.Scheme == "https" && newReq.Scheme == "http" {
+		return ""
+	}
+	referer := lastReq.String()
+	if lastReq.User != nil {
+		// This is not very efficient, but is the best we can
+		// do without:
+		// - introducing a new method on URL
+		// - creating a race condition
+		// - copying the URL struct manually, which would cause
+		//   maintenance problems down the line
+		auth := lastReq.User.String() + "@"
+		referer = strings.Replace(referer, auth, "", 1)
+	}
+	return referer
+}
+
+// Used in Send to implement io.ReadCloser by bundling together the
+// bufio.Reader through which we read the response, and the underlying
+// network connection.
+type readClose struct {
+	io.Reader
+	io.Closer
+}
+
+func (c *Client) send(req *Request) (*Response, error) {
+	if c.Jar != nil {
+		for _, cookie := range c.Jar.Cookies(req.URL) {
+			req.AddCookie(cookie)
+		}
+	}
+	resp, err := send(req, c.transport())
+	if err != nil {
+		return nil, err
+	}
+	if c.Jar != nil {
+		if rc := resp.Cookies(); len(rc) > 0 {
+			c.Jar.SetCookies(req.URL, rc)
+		}
+	}
+	return resp, err
+}
+
+// Do sends an HTTP request and returns an HTTP response, following
+// policy (e.g. redirects, cookies, auth) as configured on the client.
+//
+// An error is returned if caused by client policy (such as
+// CheckRedirect), or if there was an HTTP protocol error.
+// A non-2xx response doesn't cause an error.
+//
+// When err is nil, resp always contains a non-nil resp.Body.
+//
+// Callers should close resp.Body when done reading from it. If
+// resp.Body is not closed, the Client's underlying RoundTripper
+// (typically Transport) may not be able to re-use a persistent TCP
+// connection to the server for a subsequent "keep-alive" request.
+//
+// The request Body, if non-nil, will be closed by the underlying
+// Transport, even on errors.
+//
+// Generally Get, Post, or PostForm will be used instead of Do.
+func (c *Client) Do(req *Request) (resp *Response, err error) {
+	if req.Method == "GET" || req.Method == "HEAD" {
+		return c.doFollowingRedirects(req, shouldRedirectGet)
+	}
+	if req.Method == "POST" || req.Method == "PUT" {
+		return c.doFollowingRedirects(req, shouldRedirectPost)
+	}
+	return c.send(req)
+}
+
+func (c *Client) transport() RoundTripper {
+	if c.Transport != nil {
+		return c.Transport
+	}
+	return DefaultTransport
+}
+
+// send issues an HTTP request.
+// Caller should close resp.Body when done reading from it.
+func send(req *Request, t RoundTripper) (resp *Response, err error) {
+	if t == nil {
+		req.closeBody()
+		return nil, errors.New("http: no Client.Transport or DefaultTransport")
+	}
+
+	if req.URL == nil {
+		req.closeBody()
+		return nil, errors.New("http: nil Request.URL")
+	}
+
+	if req.RequestURI != "" {
+		req.closeBody()
+		return nil, errors.New("http: Request.RequestURI can't be set in client requests.")
+	}
+
+	// Most the callers of send (Get, Post, et al) don't need
+	// Headers, leaving it uninitialized.  We guarantee to the
+	// Transport that this has been initialized, though.
+	if req.Header == nil {
+		req.Header = make(Header)
+	}
+
+	if u := req.URL.User; u != nil {
+		username := u.Username()
+		password, _ := u.Password()
+		req.Header.Set("Authorization", "Basic "+basicAuth(username, password))
+	}
+	resp, err = t.RoundTrip(req)
+	if err != nil {
+		if resp != nil {
+			log.Printf("RoundTripper returned a response & error; ignoring response")
+		}
+		return nil, err
+	}
+	return resp, nil
+}
+
+// See 2 (end of page 4) http://www.ietf.org/rfc/rfc2617.txt
+// "To receive authorization, the client sends the userid and password,
+// separated by a single colon (":") character, within a base64
+// encoded string in the credentials."
+// It is not meant to be urlencoded.
+func basicAuth(username, password string) string {
+	auth := username + ":" + password
+	return base64.StdEncoding.EncodeToString([]byte(auth))
+}
+
+// True if the specified HTTP status code is one for which the Get utility should
+// automatically redirect.
+func shouldRedirectGet(statusCode int) bool {
+	switch statusCode {
+	case StatusMovedPermanently, StatusFound, StatusSeeOther, StatusTemporaryRedirect:
+		return true
+	}
+	return false
+}
+
+// True if the specified HTTP status code is one for which the Post utility should
+// automatically redirect.
+func shouldRedirectPost(statusCode int) bool {
+	switch statusCode {
+	case StatusFound, StatusSeeOther:
+		return true
+	}
+	return false
+}
+
+// Get issues a GET to the specified URL.  If the response is one of the following
+// redirect codes, Get follows the redirect, up to a maximum of 10 redirects:
+//
+//    301 (Moved Permanently)
+//    302 (Found)
+//    303 (See Other)
+//    307 (Temporary Redirect)
+//
+// An error is returned if there were too many redirects or if there
+// was an HTTP protocol error. A non-2xx response doesn't cause an
+// error.
+//
+// When err is nil, resp always contains a non-nil resp.Body.
+// Caller should close resp.Body when done reading from it.
+//
+// Get is a wrapper around DefaultClient.Get.
+func Get(url string) (resp *Response, err error) {
+	return DefaultClient.Get(url)
+}
+
+// Get issues a GET to the specified URL.  If the response is one of the
+// following redirect codes, Get follows the redirect after calling the
+// Client's CheckRedirect function.
+//
+//    301 (Moved Permanently)
+//    302 (Found)
+//    303 (See Other)
+//    307 (Temporary Redirect)
+//
+// An error is returned if the Client's CheckRedirect function fails
+// or if there was an HTTP protocol error. A non-2xx response doesn't
+// cause an error.
+//
+// When err is nil, resp always contains a non-nil resp.Body.
+// Caller should close resp.Body when done reading from it.
+func (c *Client) Get(url string) (resp *Response, err error) {
+	req, err := NewRequest("GET", url, nil)
+	if err != nil {
+		return nil, err
+	}
+	return c.doFollowingRedirects(req, shouldRedirectGet)
+}
+
+func (c *Client) doFollowingRedirects(ireq *Request, shouldRedirect func(int) bool) (resp *Response, err error) {
+	var base *url.URL
+	redirectChecker := c.CheckRedirect
+	if redirectChecker == nil {
+		redirectChecker = defaultCheckRedirect
+	}
+	var via []*Request
+
+	if ireq.URL == nil {
+		ireq.closeBody()
+		return nil, errors.New("http: nil Request.URL")
+	}
+
+	var reqmu sync.Mutex // guards req
+	req := ireq
+
+	var timer *time.Timer
+	if c.Timeout > 0 {
+		type canceler interface {
+			CancelRequest(*Request)
+		}
+		tr, ok := c.transport().(canceler)
+		if !ok {
+			return nil, fmt.Errorf("net/http: Client Transport of type %T doesn't support CancelRequest; Timeout not supported", c.transport())
+		}
+		timer = time.AfterFunc(c.Timeout, func() {
+			reqmu.Lock()
+			defer reqmu.Unlock()
+			tr.CancelRequest(req)
+		})
+	}
+
+	urlStr := "" // next relative or absolute URL to fetch (after first request)
+	redirectFailed := false
+	for redirect := 0; ; redirect++ {
+		if redirect != 0 {
+			nreq := new(Request)
+			nreq.Method = ireq.Method
+			if ireq.Method == "POST" || ireq.Method == "PUT" {
+				nreq.Method = "GET"
+			}
+			nreq.Header = make(Header)
+			nreq.URL, err = base.Parse(urlStr)
+			if err != nil {
+				break
+			}
+			if len(via) > 0 {
+				// Add the Referer header.
+				lastReq := via[len(via)-1]
+				if ref := refererForURL(lastReq.URL, nreq.URL); ref != "" {
+					nreq.Header.Set("Referer", ref)
+				}
+
+				err = redirectChecker(nreq, via)
+				if err != nil {
+					redirectFailed = true
+					break
+				}
+			}
+			reqmu.Lock()
+			req = nreq
+			reqmu.Unlock()
+		}
+
+		urlStr = req.URL.String()
+		if resp, err = c.send(req); err != nil {
+			break
+		}
+
+		if shouldRedirect(resp.StatusCode) {
+			// Read the body if small so underlying TCP connection will be re-used.
+			// No need to check for errors: if it fails, Transport won't reuse it anyway.
+			const maxBodySlurpSize = 2 << 10
+			if resp.ContentLength == -1 || resp.ContentLength <= maxBodySlurpSize {
+				io.CopyN(ioutil.Discard, resp.Body, maxBodySlurpSize)
+			}
+			resp.Body.Close()
+			if urlStr = resp.Header.Get("Location"); urlStr == "" {
+				err = errors.New(fmt.Sprintf("%d response missing Location header", resp.StatusCode))
+				break
+			}
+			base = req.URL
+			via = append(via, req)
+			continue
+		}
+		if timer != nil {
+			resp.Body = &cancelTimerBody{timer, resp.Body}
+		}
+		return resp, nil
+	}
+
+	method := ireq.Method
+	urlErr := &url.Error{
+		Op:  method[0:1] + strings.ToLower(method[1:]),
+		URL: urlStr,
+		Err: err,
+	}
+
+	if redirectFailed {
+		// Special case for Go 1 compatibility: return both the response
+		// and an error if the CheckRedirect function failed.
+		// See http://golang.org/issue/3795
+		return resp, urlErr
+	}
+
+	if resp != nil {
+		resp.Body.Close()
+	}
+	return nil, urlErr
+}
+
+func defaultCheckRedirect(req *Request, via []*Request) error {
+	if len(via) >= 10 {
+		return errors.New("stopped after 10 redirects")
+	}
+	return nil
+}
+
+// Post issues a POST to the specified URL.
+//
+// Caller should close resp.Body when done reading from it.
+//
+// Post is a wrapper around DefaultClient.Post
+func Post(url string, bodyType string, body io.Reader) (resp *Response, err error) {
+	return DefaultClient.Post(url, bodyType, body)
+}
+
+// Post issues a POST to the specified URL.
+//
+// Caller should close resp.Body when done reading from it.
+//
+// If the provided body is also an io.Closer, it is closed after the
+// request.
+func (c *Client) Post(url string, bodyType string, body io.Reader) (resp *Response, err error) {
+	req, err := NewRequest("POST", url, body)
+	if err != nil {
+		return nil, err
+	}
+	req.Header.Set("Content-Type", bodyType)
+	return c.doFollowingRedirects(req, shouldRedirectPost)
+}
+
+// PostForm issues a POST to the specified URL, with data's keys and
+// values URL-encoded as the request body.
+//
+// When err is nil, resp always contains a non-nil resp.Body.
+// Caller should close resp.Body when done reading from it.
+//
+// PostForm is a wrapper around DefaultClient.PostForm
+func PostForm(url string, data url.Values) (resp *Response, err error) {
+	return DefaultClient.PostForm(url, data)
+}
+
+// PostForm issues a POST to the specified URL,
+// with data's keys and values urlencoded as the request body.
+//
+// When err is nil, resp always contains a non-nil resp.Body.
+// Caller should close resp.Body when done reading from it.
+func (c *Client) PostForm(url string, data url.Values) (resp *Response, err error) {
+	return c.Post(url, "application/x-www-form-urlencoded", strings.NewReader(data.Encode()))
+}
+
+// Head issues a HEAD to the specified URL.  If the response is one of the
+// following redirect codes, Head follows the redirect after calling the
+// Client's CheckRedirect function.
+//
+//    301 (Moved Permanently)
+//    302 (Found)
+//    303 (See Other)
+//    307 (Temporary Redirect)
+//
+// Head is a wrapper around DefaultClient.Head
+func Head(url string) (resp *Response, err error) {
+	return DefaultClient.Head(url)
+}
+
+// Head issues a HEAD to the specified URL.  If the response is one of the
+// following redirect codes, Head follows the redirect after calling the
+// Client's CheckRedirect function.
+//
+//    301 (Moved Permanently)
+//    302 (Found)
+//    303 (See Other)
+//    307 (Temporary Redirect)
+func (c *Client) Head(url string) (resp *Response, err error) {
+	req, err := NewRequest("HEAD", url, nil)
+	if err != nil {
+		return nil, err
+	}
+	return c.doFollowingRedirects(req, shouldRedirectGet)
+}
+
+type cancelTimerBody struct {
+	t  *time.Timer
+	rc io.ReadCloser
+}
+
+func (b *cancelTimerBody) Read(p []byte) (n int, err error) {
+	n, err = b.rc.Read(p)
+	if err == io.EOF {
+		b.t.Stop()
+	}
+	return
+}
+
+func (b *cancelTimerBody) Close() error {
+	err := b.rc.Close()
+	b.t.Stop()
+	return err
+}
diff --git a/src/net/http/client_test.go b/src/net/http/client_test.go
new file mode 100644
index 0000000..56b6563
--- /dev/null
+++ b/src/net/http/client_test.go
@@ -0,0 +1,1075 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Tests for client.go
+
+package http_test
+
+import (
+	"bytes"
+	"crypto/tls"
+	"crypto/x509"
+	"encoding/base64"
+	"errors"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"log"
+	"net"
+	. "net/http"
+	"net/http/httptest"
+	"net/url"
+	"reflect"
+	"sort"
+	"strconv"
+	"strings"
+	"sync"
+	"testing"
+	"time"
+)
+
+var robotsTxtHandler = HandlerFunc(func(w ResponseWriter, r *Request) {
+	w.Header().Set("Last-Modified", "sometime")
+	fmt.Fprintf(w, "User-agent: go\nDisallow: /something/")
+})
+
+// pedanticReadAll works like ioutil.ReadAll but additionally
+// verifies that r obeys the documented io.Reader contract.
+func pedanticReadAll(r io.Reader) (b []byte, err error) {
+	var bufa [64]byte
+	buf := bufa[:]
+	for {
+		n, err := r.Read(buf)
+		if n == 0 && err == nil {
+			return nil, fmt.Errorf("Read: n=0 with err=nil")
+		}
+		b = append(b, buf[:n]...)
+		if err == io.EOF {
+			n, err := r.Read(buf)
+			if n != 0 || err != io.EOF {
+				return nil, fmt.Errorf("Read: n=%d err=%#v after EOF", n, err)
+			}
+			return b, nil
+		}
+		if err != nil {
+			return b, err
+		}
+	}
+}
+
+type chanWriter chan string
+
+func (w chanWriter) Write(p []byte) (n int, err error) {
+	w <- string(p)
+	return len(p), nil
+}
+
+func TestClient(t *testing.T) {
+	defer afterTest(t)
+	ts := httptest.NewServer(robotsTxtHandler)
+	defer ts.Close()
+
+	r, err := Get(ts.URL)
+	var b []byte
+	if err == nil {
+		b, err = pedanticReadAll(r.Body)
+		r.Body.Close()
+	}
+	if err != nil {
+		t.Error(err)
+	} else if s := string(b); !strings.HasPrefix(s, "User-agent:") {
+		t.Errorf("Incorrect page body (did not begin with User-agent): %q", s)
+	}
+}
+
+func TestClientHead(t *testing.T) {
+	defer afterTest(t)
+	ts := httptest.NewServer(robotsTxtHandler)
+	defer ts.Close()
+
+	r, err := Head(ts.URL)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if _, ok := r.Header["Last-Modified"]; !ok {
+		t.Error("Last-Modified header not found.")
+	}
+}
+
+type recordingTransport struct {
+	req *Request
+}
+
+func (t *recordingTransport) RoundTrip(req *Request) (resp *Response, err error) {
+	t.req = req
+	return nil, errors.New("dummy impl")
+}
+
+func TestGetRequestFormat(t *testing.T) {
+	defer afterTest(t)
+	tr := &recordingTransport{}
+	client := &Client{Transport: tr}
+	url := "http://dummy.faketld/"
+	client.Get(url) // Note: doesn't hit network
+	if tr.req.Method != "GET" {
+		t.Errorf("expected method %q; got %q", "GET", tr.req.Method)
+	}
+	if tr.req.URL.String() != url {
+		t.Errorf("expected URL %q; got %q", url, tr.req.URL.String())
+	}
+	if tr.req.Header == nil {
+		t.Errorf("expected non-nil request Header")
+	}
+}
+
+func TestPostRequestFormat(t *testing.T) {
+	defer afterTest(t)
+	tr := &recordingTransport{}
+	client := &Client{Transport: tr}
+
+	url := "http://dummy.faketld/"
+	json := `{"key":"value"}`
+	b := strings.NewReader(json)
+	client.Post(url, "application/json", b) // Note: doesn't hit network
+
+	if tr.req.Method != "POST" {
+		t.Errorf("got method %q, want %q", tr.req.Method, "POST")
+	}
+	if tr.req.URL.String() != url {
+		t.Errorf("got URL %q, want %q", tr.req.URL.String(), url)
+	}
+	if tr.req.Header == nil {
+		t.Fatalf("expected non-nil request Header")
+	}
+	if tr.req.Close {
+		t.Error("got Close true, want false")
+	}
+	if g, e := tr.req.ContentLength, int64(len(json)); g != e {
+		t.Errorf("got ContentLength %d, want %d", g, e)
+	}
+}
+
+func TestPostFormRequestFormat(t *testing.T) {
+	defer afterTest(t)
+	tr := &recordingTransport{}
+	client := &Client{Transport: tr}
+
+	urlStr := "http://dummy.faketld/"
+	form := make(url.Values)
+	form.Set("foo", "bar")
+	form.Add("foo", "bar2")
+	form.Set("bar", "baz")
+	client.PostForm(urlStr, form) // Note: doesn't hit network
+
+	if tr.req.Method != "POST" {
+		t.Errorf("got method %q, want %q", tr.req.Method, "POST")
+	}
+	if tr.req.URL.String() != urlStr {
+		t.Errorf("got URL %q, want %q", tr.req.URL.String(), urlStr)
+	}
+	if tr.req.Header == nil {
+		t.Fatalf("expected non-nil request Header")
+	}
+	if g, e := tr.req.Header.Get("Content-Type"), "application/x-www-form-urlencoded"; g != e {
+		t.Errorf("got Content-Type %q, want %q", g, e)
+	}
+	if tr.req.Close {
+		t.Error("got Close true, want false")
+	}
+	// Depending on map iteration, body can be either of these.
+	expectedBody := "foo=bar&foo=bar2&bar=baz"
+	expectedBody1 := "bar=baz&foo=bar&foo=bar2"
+	if g, e := tr.req.ContentLength, int64(len(expectedBody)); g != e {
+		t.Errorf("got ContentLength %d, want %d", g, e)
+	}
+	bodyb, err := ioutil.ReadAll(tr.req.Body)
+	if err != nil {
+		t.Fatalf("ReadAll on req.Body: %v", err)
+	}
+	if g := string(bodyb); g != expectedBody && g != expectedBody1 {
+		t.Errorf("got body %q, want %q or %q", g, expectedBody, expectedBody1)
+	}
+}
+
+func TestClientRedirects(t *testing.T) {
+	defer afterTest(t)
+	var ts *httptest.Server
+	ts = httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+		n, _ := strconv.Atoi(r.FormValue("n"))
+		// Test Referer header. (7 is arbitrary position to test at)
+		if n == 7 {
+			if g, e := r.Referer(), ts.URL+"/?n=6"; e != g {
+				t.Errorf("on request ?n=7, expected referer of %q; got %q", e, g)
+			}
+		}
+		if n < 15 {
+			Redirect(w, r, fmt.Sprintf("/?n=%d", n+1), StatusFound)
+			return
+		}
+		fmt.Fprintf(w, "n=%d", n)
+	}))
+	defer ts.Close()
+
+	c := &Client{}
+	_, err := c.Get(ts.URL)
+	if e, g := "Get /?n=10: stopped after 10 redirects", fmt.Sprintf("%v", err); e != g {
+		t.Errorf("with default client Get, expected error %q, got %q", e, g)
+	}
+
+	// HEAD request should also have the ability to follow redirects.
+	_, err = c.Head(ts.URL)
+	if e, g := "Head /?n=10: stopped after 10 redirects", fmt.Sprintf("%v", err); e != g {
+		t.Errorf("with default client Head, expected error %q, got %q", e, g)
+	}
+
+	// Do should also follow redirects.
+	greq, _ := NewRequest("GET", ts.URL, nil)
+	_, err = c.Do(greq)
+	if e, g := "Get /?n=10: stopped after 10 redirects", fmt.Sprintf("%v", err); e != g {
+		t.Errorf("with default client Do, expected error %q, got %q", e, g)
+	}
+
+	var checkErr error
+	var lastVia []*Request
+	c = &Client{CheckRedirect: func(_ *Request, via []*Request) error {
+		lastVia = via
+		return checkErr
+	}}
+	res, err := c.Get(ts.URL)
+	if err != nil {
+		t.Fatalf("Get error: %v", err)
+	}
+	res.Body.Close()
+	finalUrl := res.Request.URL.String()
+	if e, g := "<nil>", fmt.Sprintf("%v", err); e != g {
+		t.Errorf("with custom client, expected error %q, got %q", e, g)
+	}
+	if !strings.HasSuffix(finalUrl, "/?n=15") {
+		t.Errorf("expected final url to end in /?n=15; got url %q", finalUrl)
+	}
+	if e, g := 15, len(lastVia); e != g {
+		t.Errorf("expected lastVia to have contained %d elements; got %d", e, g)
+	}
+
+	checkErr = errors.New("no redirects allowed")
+	res, err = c.Get(ts.URL)
+	if urlError, ok := err.(*url.Error); !ok || urlError.Err != checkErr {
+		t.Errorf("with redirects forbidden, expected a *url.Error with our 'no redirects allowed' error inside; got %#v (%q)", err, err)
+	}
+	if res == nil {
+		t.Fatalf("Expected a non-nil Response on CheckRedirect failure (http://golang.org/issue/3795)")
+	}
+	res.Body.Close()
+	if res.Header.Get("Location") == "" {
+		t.Errorf("no Location header in Response")
+	}
+}
+
+func TestPostRedirects(t *testing.T) {
+	defer afterTest(t)
+	var log struct {
+		sync.Mutex
+		bytes.Buffer
+	}
+	var ts *httptest.Server
+	ts = httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+		log.Lock()
+		fmt.Fprintf(&log.Buffer, "%s %s ", r.Method, r.RequestURI)
+		log.Unlock()
+		if v := r.URL.Query().Get("code"); v != "" {
+			code, _ := strconv.Atoi(v)
+			if code/100 == 3 {
+				w.Header().Set("Location", ts.URL)
+			}
+			w.WriteHeader(code)
+		}
+	}))
+	defer ts.Close()
+	tests := []struct {
+		suffix string
+		want   int // response code
+	}{
+		{"/", 200},
+		{"/?code=301", 301},
+		{"/?code=302", 200},
+		{"/?code=303", 200},
+		{"/?code=404", 404},
+	}
+	for _, tt := range tests {
+		res, err := Post(ts.URL+tt.suffix, "text/plain", strings.NewReader("Some content"))
+		if err != nil {
+			t.Fatal(err)
+		}
+		if res.StatusCode != tt.want {
+			t.Errorf("POST %s: status code = %d; want %d", tt.suffix, res.StatusCode, tt.want)
+		}
+	}
+	log.Lock()
+	got := log.String()
+	log.Unlock()
+	want := "POST / POST /?code=301 POST /?code=302 GET / POST /?code=303 GET / POST /?code=404 "
+	if got != want {
+		t.Errorf("Log differs.\n Got: %q\nWant: %q", got, want)
+	}
+}
+
+var expectedCookies = []*Cookie{
+	{Name: "ChocolateChip", Value: "tasty"},
+	{Name: "First", Value: "Hit"},
+	{Name: "Second", Value: "Hit"},
+}
+
+var echoCookiesRedirectHandler = HandlerFunc(func(w ResponseWriter, r *Request) {
+	for _, cookie := range r.Cookies() {
+		SetCookie(w, cookie)
+	}
+	if r.URL.Path == "/" {
+		SetCookie(w, expectedCookies[1])
+		Redirect(w, r, "/second", StatusMovedPermanently)
+	} else {
+		SetCookie(w, expectedCookies[2])
+		w.Write([]byte("hello"))
+	}
+})
+
+func TestClientSendsCookieFromJar(t *testing.T) {
+	tr := &recordingTransport{}
+	client := &Client{Transport: tr}
+	client.Jar = &TestJar{perURL: make(map[string][]*Cookie)}
+	us := "http://dummy.faketld/"
+	u, _ := url.Parse(us)
+	client.Jar.SetCookies(u, expectedCookies)
+
+	client.Get(us) // Note: doesn't hit network
+	matchReturnedCookies(t, expectedCookies, tr.req.Cookies())
+
+	client.Head(us) // Note: doesn't hit network
+	matchReturnedCookies(t, expectedCookies, tr.req.Cookies())
+
+	client.Post(us, "text/plain", strings.NewReader("body")) // Note: doesn't hit network
+	matchReturnedCookies(t, expectedCookies, tr.req.Cookies())
+
+	client.PostForm(us, url.Values{}) // Note: doesn't hit network
+	matchReturnedCookies(t, expectedCookies, tr.req.Cookies())
+
+	req, _ := NewRequest("GET", us, nil)
+	client.Do(req) // Note: doesn't hit network
+	matchReturnedCookies(t, expectedCookies, tr.req.Cookies())
+
+	req, _ = NewRequest("POST", us, nil)
+	client.Do(req) // Note: doesn't hit network
+	matchReturnedCookies(t, expectedCookies, tr.req.Cookies())
+}
+
+// Just enough correctness for our redirect tests. Uses the URL.Host as the
+// scope of all cookies.
+type TestJar struct {
+	m      sync.Mutex
+	perURL map[string][]*Cookie
+}
+
+func (j *TestJar) SetCookies(u *url.URL, cookies []*Cookie) {
+	j.m.Lock()
+	defer j.m.Unlock()
+	if j.perURL == nil {
+		j.perURL = make(map[string][]*Cookie)
+	}
+	j.perURL[u.Host] = cookies
+}
+
+func (j *TestJar) Cookies(u *url.URL) []*Cookie {
+	j.m.Lock()
+	defer j.m.Unlock()
+	return j.perURL[u.Host]
+}
+
+func TestRedirectCookiesJar(t *testing.T) {
+	defer afterTest(t)
+	var ts *httptest.Server
+	ts = httptest.NewServer(echoCookiesRedirectHandler)
+	defer ts.Close()
+	c := &Client{
+		Jar: new(TestJar),
+	}
+	u, _ := url.Parse(ts.URL)
+	c.Jar.SetCookies(u, []*Cookie{expectedCookies[0]})
+	resp, err := c.Get(ts.URL)
+	if err != nil {
+		t.Fatalf("Get: %v", err)
+	}
+	resp.Body.Close()
+	matchReturnedCookies(t, expectedCookies, resp.Cookies())
+}
+
+func matchReturnedCookies(t *testing.T, expected, given []*Cookie) {
+	if len(given) != len(expected) {
+		t.Logf("Received cookies: %v", given)
+		t.Errorf("Expected %d cookies, got %d", len(expected), len(given))
+	}
+	for _, ec := range expected {
+		foundC := false
+		for _, c := range given {
+			if ec.Name == c.Name && ec.Value == c.Value {
+				foundC = true
+				break
+			}
+		}
+		if !foundC {
+			t.Errorf("Missing cookie %v", ec)
+		}
+	}
+}
+
+func TestJarCalls(t *testing.T) {
+	defer afterTest(t)
+	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+		pathSuffix := r.RequestURI[1:]
+		if r.RequestURI == "/nosetcookie" {
+			return // dont set cookies for this path
+		}
+		SetCookie(w, &Cookie{Name: "name" + pathSuffix, Value: "val" + pathSuffix})
+		if r.RequestURI == "/" {
+			Redirect(w, r, "http://secondhost.fake/secondpath", 302)
+		}
+	}))
+	defer ts.Close()
+	jar := new(RecordingJar)
+	c := &Client{
+		Jar: jar,
+		Transport: &Transport{
+			Dial: func(_ string, _ string) (net.Conn, error) {
+				return net.Dial("tcp", ts.Listener.Addr().String())
+			},
+		},
+	}
+	_, err := c.Get("http://firsthost.fake/")
+	if err != nil {
+		t.Fatal(err)
+	}
+	_, err = c.Get("http://firsthost.fake/nosetcookie")
+	if err != nil {
+		t.Fatal(err)
+	}
+	got := jar.log.String()
+	want := `Cookies("http://firsthost.fake/")
+SetCookie("http://firsthost.fake/", [name=val])
+Cookies("http://secondhost.fake/secondpath")
+SetCookie("http://secondhost.fake/secondpath", [namesecondpath=valsecondpath])
+Cookies("http://firsthost.fake/nosetcookie")
+`
+	if got != want {
+		t.Errorf("Got Jar calls:\n%s\nWant:\n%s", got, want)
+	}
+}
+
+// RecordingJar keeps a log of calls made to it, without
+// tracking any cookies.
+type RecordingJar struct {
+	mu  sync.Mutex
+	log bytes.Buffer
+}
+
+func (j *RecordingJar) SetCookies(u *url.URL, cookies []*Cookie) {
+	j.logf("SetCookie(%q, %v)\n", u, cookies)
+}
+
+func (j *RecordingJar) Cookies(u *url.URL) []*Cookie {
+	j.logf("Cookies(%q)\n", u)
+	return nil
+}
+
+func (j *RecordingJar) logf(format string, args ...interface{}) {
+	j.mu.Lock()
+	defer j.mu.Unlock()
+	fmt.Fprintf(&j.log, format, args...)
+}
+
+func TestStreamingGet(t *testing.T) {
+	defer afterTest(t)
+	say := make(chan string)
+	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+		w.(Flusher).Flush()
+		for str := range say {
+			w.Write([]byte(str))
+			w.(Flusher).Flush()
+		}
+	}))
+	defer ts.Close()
+
+	c := &Client{}
+	res, err := c.Get(ts.URL)
+	if err != nil {
+		t.Fatal(err)
+	}
+	var buf [10]byte
+	for _, str := range []string{"i", "am", "also", "known", "as", "comet"} {
+		say <- str
+		n, err := io.ReadFull(res.Body, buf[0:len(str)])
+		if err != nil {
+			t.Fatalf("ReadFull on %q: %v", str, err)
+		}
+		if n != len(str) {
+			t.Fatalf("Receiving %q, only read %d bytes", str, n)
+		}
+		got := string(buf[0:n])
+		if got != str {
+			t.Fatalf("Expected %q, got %q", str, got)
+		}
+	}
+	close(say)
+	_, err = io.ReadFull(res.Body, buf[0:1])
+	if err != io.EOF {
+		t.Fatalf("at end expected EOF, got %v", err)
+	}
+}
+
+type writeCountingConn struct {
+	net.Conn
+	count *int
+}
+
+func (c *writeCountingConn) Write(p []byte) (int, error) {
+	*c.count++
+	return c.Conn.Write(p)
+}
+
+// TestClientWrites verifies that client requests are buffered and we
+// don't send a TCP packet per line of the http request + body.
+func TestClientWrites(t *testing.T) {
+	defer afterTest(t)
+	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+	}))
+	defer ts.Close()
+
+	writes := 0
+	dialer := func(netz string, addr string) (net.Conn, error) {
+		c, err := net.Dial(netz, addr)
+		if err == nil {
+			c = &writeCountingConn{c, &writes}
+		}
+		return c, err
+	}
+	c := &Client{Transport: &Transport{Dial: dialer}}
+
+	_, err := c.Get(ts.URL)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if writes != 1 {
+		t.Errorf("Get request did %d Write calls, want 1", writes)
+	}
+
+	writes = 0
+	_, err = c.PostForm(ts.URL, url.Values{"foo": {"bar"}})
+	if err != nil {
+		t.Fatal(err)
+	}
+	if writes != 1 {
+		t.Errorf("Post request did %d Write calls, want 1", writes)
+	}
+}
+
+func TestClientInsecureTransport(t *testing.T) {
+	defer afterTest(t)
+	ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+		w.Write([]byte("Hello"))
+	}))
+	errc := make(chanWriter, 10) // but only expecting 1
+	ts.Config.ErrorLog = log.New(errc, "", 0)
+	defer ts.Close()
+
+	// TODO(bradfitz): add tests for skipping hostname checks too?
+	// would require a new cert for testing, and probably
+	// redundant with these tests.
+	for _, insecure := range []bool{true, false} {
+		tr := &Transport{
+			TLSClientConfig: &tls.Config{
+				InsecureSkipVerify: insecure,
+			},
+		}
+		defer tr.CloseIdleConnections()
+		c := &Client{Transport: tr}
+		res, err := c.Get(ts.URL)
+		if (err == nil) != insecure {
+			t.Errorf("insecure=%v: got unexpected err=%v", insecure, err)
+		}
+		if res != nil {
+			res.Body.Close()
+		}
+	}
+
+	select {
+	case v := <-errc:
+		if !strings.Contains(v, "TLS handshake error") {
+			t.Errorf("expected an error log message containing 'TLS handshake error'; got %q", v)
+		}
+	case <-time.After(5 * time.Second):
+		t.Errorf("timeout waiting for logged error")
+	}
+
+}
+
+func TestClientErrorWithRequestURI(t *testing.T) {
+	defer afterTest(t)
+	req, _ := NewRequest("GET", "http://localhost:1234/", nil)
+	req.RequestURI = "/this/field/is/illegal/and/should/error/"
+	_, err := DefaultClient.Do(req)
+	if err == nil {
+		t.Fatalf("expected an error")
+	}
+	if !strings.Contains(err.Error(), "RequestURI") {
+		t.Errorf("wanted error mentioning RequestURI; got error: %v", err)
+	}
+}
+
+func newTLSTransport(t *testing.T, ts *httptest.Server) *Transport {
+	certs := x509.NewCertPool()
+	for _, c := range ts.TLS.Certificates {
+		roots, err := x509.ParseCertificates(c.Certificate[len(c.Certificate)-1])
+		if err != nil {
+			t.Fatalf("error parsing server's root cert: %v", err)
+		}
+		for _, root := range roots {
+			certs.AddCert(root)
+		}
+	}
+	return &Transport{
+		TLSClientConfig: &tls.Config{RootCAs: certs},
+	}
+}
+
+func TestClientWithCorrectTLSServerName(t *testing.T) {
+	defer afterTest(t)
+	ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+		if r.TLS.ServerName != "127.0.0.1" {
+			t.Errorf("expected client to set ServerName 127.0.0.1, got: %q", r.TLS.ServerName)
+		}
+	}))
+	defer ts.Close()
+
+	c := &Client{Transport: newTLSTransport(t, ts)}
+	if _, err := c.Get(ts.URL); err != nil {
+		t.Fatalf("expected successful TLS connection, got error: %v", err)
+	}
+}
+
+func TestClientWithIncorrectTLSServerName(t *testing.T) {
+	defer afterTest(t)
+	ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) {}))
+	defer ts.Close()
+	errc := make(chanWriter, 10) // but only expecting 1
+	ts.Config.ErrorLog = log.New(errc, "", 0)
+
+	trans := newTLSTransport(t, ts)
+	trans.TLSClientConfig.ServerName = "badserver"
+	c := &Client{Transport: trans}
+	_, err := c.Get(ts.URL)
+	if err == nil {
+		t.Fatalf("expected an error")
+	}
+	if !strings.Contains(err.Error(), "127.0.0.1") || !strings.Contains(err.Error(), "badserver") {
+		t.Errorf("wanted error mentioning 127.0.0.1 and badserver; got error: %v", err)
+	}
+	select {
+	case v := <-errc:
+		if !strings.Contains(v, "TLS handshake error") {
+			t.Errorf("expected an error log message containing 'TLS handshake error'; got %q", v)
+		}
+	case <-time.After(5 * time.Second):
+		t.Errorf("timeout waiting for logged error")
+	}
+}
+
+// Test for golang.org/issue/5829; the Transport should respect TLSClientConfig.ServerName
+// when not empty.
+//
+// tls.Config.ServerName (non-empty, set to "example.com") takes
+// precedence over "some-other-host.tld" which previously incorrectly
+// took precedence. We don't actually connect to (or even resolve)
+// "some-other-host.tld", though, because of the Transport.Dial hook.
+//
+// The httptest.Server has a cert with "example.com" as its name.
+func TestTransportUsesTLSConfigServerName(t *testing.T) {
+	defer afterTest(t)
+	ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+		w.Write([]byte("Hello"))
+	}))
+	defer ts.Close()
+
+	tr := newTLSTransport(t, ts)
+	tr.TLSClientConfig.ServerName = "example.com" // one of httptest's Server cert names
+	tr.Dial = func(netw, addr string) (net.Conn, error) {
+		return net.Dial(netw, ts.Listener.Addr().String())
+	}
+	defer tr.CloseIdleConnections()
+	c := &Client{Transport: tr}
+	res, err := c.Get("https://some-other-host.tld/")
+	if err != nil {
+		t.Fatal(err)
+	}
+	res.Body.Close()
+}
+
+func TestResponseSetsTLSConnectionState(t *testing.T) {
+	defer afterTest(t)
+	ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+		w.Write([]byte("Hello"))
+	}))
+	defer ts.Close()
+
+	tr := newTLSTransport(t, ts)
+	tr.TLSClientConfig.CipherSuites = []uint16{tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA}
+	tr.Dial = func(netw, addr string) (net.Conn, error) {
+		return net.Dial(netw, ts.Listener.Addr().String())
+	}
+	defer tr.CloseIdleConnections()
+	c := &Client{Transport: tr}
+	res, err := c.Get("https://example.com/")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer res.Body.Close()
+	if res.TLS == nil {
+		t.Fatal("Response didn't set TLS Connection State.")
+	}
+	if got, want := res.TLS.CipherSuite, tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA; got != want {
+		t.Errorf("TLS Cipher Suite = %d; want %d", got, want)
+	}
+}
+
+// Verify Response.ContentLength is populated. http://golang.org/issue/4126
+func TestClientHeadContentLength(t *testing.T) {
+	defer afterTest(t)
+	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+		if v := r.FormValue("cl"); v != "" {
+			w.Header().Set("Content-Length", v)
+		}
+	}))
+	defer ts.Close()
+	tests := []struct {
+		suffix string
+		want   int64
+	}{
+		{"/?cl=1234", 1234},
+		{"/?cl=0", 0},
+		{"", -1},
+	}
+	for _, tt := range tests {
+		req, _ := NewRequest("HEAD", ts.URL+tt.suffix, nil)
+		res, err := DefaultClient.Do(req)
+		if err != nil {
+			t.Fatal(err)
+		}
+		if res.ContentLength != tt.want {
+			t.Errorf("Content-Length = %d; want %d", res.ContentLength, tt.want)
+		}
+		bs, err := ioutil.ReadAll(res.Body)
+		if err != nil {
+			t.Fatal(err)
+		}
+		if len(bs) != 0 {
+			t.Errorf("Unexpected content: %q", bs)
+		}
+	}
+}
+
+func TestEmptyPasswordAuth(t *testing.T) {
+	defer afterTest(t)
+	gopher := "gopher"
+	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+		auth := r.Header.Get("Authorization")
+		if strings.HasPrefix(auth, "Basic ") {
+			encoded := auth[6:]
+			decoded, err := base64.StdEncoding.DecodeString(encoded)
+			if err != nil {
+				t.Fatal(err)
+			}
+			expected := gopher + ":"
+			s := string(decoded)
+			if expected != s {
+				t.Errorf("Invalid Authorization header. Got %q, wanted %q", s, expected)
+			}
+		} else {
+			t.Errorf("Invalid auth %q", auth)
+		}
+	}))
+	defer ts.Close()
+	c := &Client{}
+	req, err := NewRequest("GET", ts.URL, nil)
+	if err != nil {
+		t.Fatal(err)
+	}
+	req.URL.User = url.User(gopher)
+	resp, err := c.Do(req)
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer resp.Body.Close()
+}
+
+func TestBasicAuth(t *testing.T) {
+	defer afterTest(t)
+	tr := &recordingTransport{}
+	client := &Client{Transport: tr}
+
+	url := "http://My%20User:My%20Pass@dummy.faketld/"
+	expected := "My User:My Pass"
+	client.Get(url)
+
+	if tr.req.Method != "GET" {
+		t.Errorf("got method %q, want %q", tr.req.Method, "GET")
+	}
+	if tr.req.URL.String() != url {
+		t.Errorf("got URL %q, want %q", tr.req.URL.String(), url)
+	}
+	if tr.req.Header == nil {
+		t.Fatalf("expected non-nil request Header")
+	}
+	auth := tr.req.Header.Get("Authorization")
+	if strings.HasPrefix(auth, "Basic ") {
+		encoded := auth[6:]
+		decoded, err := base64.StdEncoding.DecodeString(encoded)
+		if err != nil {
+			t.Fatal(err)
+		}
+		s := string(decoded)
+		if expected != s {
+			t.Errorf("Invalid Authorization header. Got %q, wanted %q", s, expected)
+		}
+	} else {
+		t.Errorf("Invalid auth %q", auth)
+	}
+}
+
+func TestClientTimeout(t *testing.T) {
+	if testing.Short() {
+		t.Skip("skipping in short mode")
+	}
+	defer afterTest(t)
+	sawRoot := make(chan bool, 1)
+	sawSlow := make(chan bool, 1)
+	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+		if r.URL.Path == "/" {
+			sawRoot <- true
+			Redirect(w, r, "/slow", StatusFound)
+			return
+		}
+		if r.URL.Path == "/slow" {
+			w.Write([]byte("Hello"))
+			w.(Flusher).Flush()
+			sawSlow <- true
+			time.Sleep(2 * time.Second)
+			return
+		}
+	}))
+	defer ts.Close()
+	const timeout = 500 * time.Millisecond
+	c := &Client{
+		Timeout: timeout,
+	}
+
+	res, err := c.Get(ts.URL)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	select {
+	case <-sawRoot:
+		// good.
+	default:
+		t.Fatal("handler never got / request")
+	}
+
+	select {
+	case <-sawSlow:
+		// good.
+	default:
+		t.Fatal("handler never got /slow request")
+	}
+
+	errc := make(chan error, 1)
+	go func() {
+		_, err := ioutil.ReadAll(res.Body)
+		errc <- err
+		res.Body.Close()
+	}()
+
+	const failTime = timeout * 2
+	select {
+	case err := <-errc:
+		if err == nil {
+			t.Error("expected error from ReadAll")
+		}
+		// Expected error.
+	case <-time.After(failTime):
+		t.Errorf("timeout after %v waiting for timeout of %v", failTime, timeout)
+	}
+}
+
+func TestClientRedirectEatsBody(t *testing.T) {
+	defer afterTest(t)
+	saw := make(chan string, 2)
+	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+		saw <- r.RemoteAddr
+		if r.URL.Path == "/" {
+			Redirect(w, r, "/foo", StatusFound) // which includes a body
+		}
+	}))
+	defer ts.Close()
+
+	res, err := Get(ts.URL)
+	if err != nil {
+		t.Fatal(err)
+	}
+	_, err = ioutil.ReadAll(res.Body)
+	if err != nil {
+		t.Fatal(err)
+	}
+	res.Body.Close()
+
+	var first string
+	select {
+	case first = <-saw:
+	default:
+		t.Fatal("server didn't see a request")
+	}
+
+	var second string
+	select {
+	case second = <-saw:
+	default:
+		t.Fatal("server didn't see a second request")
+	}
+
+	if first != second {
+		t.Fatal("server saw different client ports before & after the redirect")
+	}
+}
+
+// eofReaderFunc is an io.Reader that runs itself, and then returns io.EOF.
+type eofReaderFunc func()
+
+func (f eofReaderFunc) Read(p []byte) (n int, err error) {
+	f()
+	return 0, io.EOF
+}
+
+func TestClientTrailers(t *testing.T) {
+	defer afterTest(t)
+	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+		w.Header().Set("Connection", "close")
+		w.Header().Set("Trailer", "Server-Trailer-A, Server-Trailer-B")
+		w.Header().Add("Trailer", "Server-Trailer-C")
+
+		var decl []string
+		for k := range r.Trailer {
+			decl = append(decl, k)
+		}
+		sort.Strings(decl)
+
+		slurp, err := ioutil.ReadAll(r.Body)
+		if err != nil {
+			t.Errorf("Server reading request body: %v", err)
+		}
+		if string(slurp) != "foo" {
+			t.Errorf("Server read request body %q; want foo", slurp)
+		}
+		if r.Trailer == nil {
+			io.WriteString(w, "nil Trailer")
+		} else {
+			fmt.Fprintf(w, "decl: %v, vals: %s, %s",
+				decl,
+				r.Trailer.Get("Client-Trailer-A"),
+				r.Trailer.Get("Client-Trailer-B"))
+		}
+
+		// TODO: golang.org/issue/7759: there's no way yet for
+		// the server to set trailers without hijacking, so do
+		// that for now, just to test the client.  Later, in
+		// Go 1.4, it should be implicit that any mutations
+		// to w.Header() after the initial write are the
+		// trailers to be sent, if and only if they were
+		// previously declared with w.Header().Set("Trailer",
+		// ..keys..)
+		w.(Flusher).Flush()
+		conn, buf, _ := w.(Hijacker).Hijack()
+		t := Header{}
+		t.Set("Server-Trailer-A", "valuea")
+		t.Set("Server-Trailer-C", "valuec") // skipping B
+		buf.WriteString("0\r\n")            // eof
+		t.Write(buf)
+		buf.WriteString("\r\n") // end of trailers
+		buf.Flush()
+		conn.Close()
+	}))
+	defer ts.Close()
+
+	var req *Request
+	req, _ = NewRequest("POST", ts.URL, io.MultiReader(
+		eofReaderFunc(func() {
+			req.Trailer["Client-Trailer-A"] = []string{"valuea"}
+		}),
+		strings.NewReader("foo"),
+		eofReaderFunc(func() {
+			req.Trailer["Client-Trailer-B"] = []string{"valueb"}
+		}),
+	))
+	req.Trailer = Header{
+		"Client-Trailer-A": nil, //  to be set later
+		"Client-Trailer-B": nil, //  to be set later
+	}
+	req.ContentLength = -1
+	res, err := DefaultClient.Do(req)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if err := wantBody(res, err, "decl: [Client-Trailer-A Client-Trailer-B], vals: valuea, valueb"); err != nil {
+		t.Error(err)
+	}
+	want := Header{
+		"Server-Trailer-A": []string{"valuea"},
+		"Server-Trailer-B": nil,
+		"Server-Trailer-C": []string{"valuec"},
+	}
+	if !reflect.DeepEqual(res.Trailer, want) {
+		t.Errorf("Response trailers = %#v; want %#v", res.Trailer, want)
+	}
+}
+
+func TestReferer(t *testing.T) {
+	tests := []struct {
+		lastReq, newReq string // from -> to URLs
+		want            string
+	}{
+		// don't send user:
+		{"http://gopher@test.com", "http://link.com", "http://test.com"},
+		{"https://gopher@test.com", "https://link.com", "https://test.com"},
+
+		// don't send a user and password:
+		{"http://gopher:go@test.com", "http://link.com", "http://test.com"},
+		{"https://gopher:go@test.com", "https://link.com", "https://test.com"},
+
+		// nothing to do:
+		{"http://test.com", "http://link.com", "http://test.com"},
+		{"https://test.com", "https://link.com", "https://test.com"},
+
+		// https to http doesn't send a referer:
+		{"https://test.com", "http://link.com", ""},
+		{"https://gopher:go@test.com", "http://link.com", ""},
+	}
+	for _, tt := range tests {
+		l, err := url.Parse(tt.lastReq)
+		if err != nil {
+			t.Fatal(err)
+		}
+		n, err := url.Parse(tt.newReq)
+		if err != nil {
+			t.Fatal(err)
+		}
+		r := ExportRefererForURL(l, n)
+		if r != tt.want {
+			t.Errorf("refererForURL(%q, %q) = %q; want %q", tt.lastReq, tt.newReq, r, tt.want)
+		}
+	}
+}
diff --git a/src/net/http/cookie.go b/src/net/http/cookie.go
new file mode 100644
index 0000000..a0d0fdb
--- /dev/null
+++ b/src/net/http/cookie.go
@@ -0,0 +1,363 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package http
+
+import (
+	"bytes"
+	"fmt"
+	"log"
+	"net"
+	"strconv"
+	"strings"
+	"time"
+)
+
+// This implementation is done according to RFC 6265:
+//
+//    http://tools.ietf.org/html/rfc6265
+
+// A Cookie represents an HTTP cookie as sent in the Set-Cookie header of an
+// HTTP response or the Cookie header of an HTTP request.
+type Cookie struct {
+	Name       string
+	Value      string
+	Path       string
+	Domain     string
+	Expires    time.Time
+	RawExpires string
+
+	// MaxAge=0 means no 'Max-Age' attribute specified.
+	// MaxAge<0 means delete cookie now, equivalently 'Max-Age: 0'
+	// MaxAge>0 means Max-Age attribute present and given in seconds
+	MaxAge   int
+	Secure   bool
+	HttpOnly bool
+	Raw      string
+	Unparsed []string // Raw text of unparsed attribute-value pairs
+}
+
+// readSetCookies parses all "Set-Cookie" values from
+// the header h and returns the successfully parsed Cookies.
+func readSetCookies(h Header) []*Cookie {
+	cookies := []*Cookie{}
+	for _, line := range h["Set-Cookie"] {
+		parts := strings.Split(strings.TrimSpace(line), ";")
+		if len(parts) == 1 && parts[0] == "" {
+			continue
+		}
+		parts[0] = strings.TrimSpace(parts[0])
+		j := strings.Index(parts[0], "=")
+		if j < 0 {
+			continue
+		}
+		name, value := parts[0][:j], parts[0][j+1:]
+		if !isCookieNameValid(name) {
+			continue
+		}
+		value, success := parseCookieValue(value, true)
+		if !success {
+			continue
+		}
+		c := &Cookie{
+			Name:  name,
+			Value: value,
+			Raw:   line,
+		}
+		for i := 1; i < len(parts); i++ {
+			parts[i] = strings.TrimSpace(parts[i])
+			if len(parts[i]) == 0 {
+				continue
+			}
+
+			attr, val := parts[i], ""
+			if j := strings.Index(attr, "="); j >= 0 {
+				attr, val = attr[:j], attr[j+1:]
+			}
+			lowerAttr := strings.ToLower(attr)
+			val, success = parseCookieValue(val, false)
+			if !success {
+				c.Unparsed = append(c.Unparsed, parts[i])
+				continue
+			}
+			switch lowerAttr {
+			case "secure":
+				c.Secure = true
+				continue
+			case "httponly":
+				c.HttpOnly = true
+				continue
+			case "domain":
+				c.Domain = val
+				continue
+			case "max-age":
+				secs, err := strconv.Atoi(val)
+				if err != nil || secs != 0 && val[0] == '0' {
+					break
+				}
+				if secs <= 0 {
+					c.MaxAge = -1
+				} else {
+					c.MaxAge = secs
+				}
+				continue
+			case "expires":
+				c.RawExpires = val
+				exptime, err := time.Parse(time.RFC1123, val)
+				if err != nil {
+					exptime, err = time.Parse("Mon, 02-Jan-2006 15:04:05 MST", val)
+					if err != nil {
+						c.Expires = time.Time{}
+						break
+					}
+				}
+				c.Expires = exptime.UTC()
+				continue
+			case "path":
+				c.Path = val
+				continue
+			}
+			c.Unparsed = append(c.Unparsed, parts[i])
+		}
+		cookies = append(cookies, c)
+	}
+	return cookies
+}
+
+// SetCookie adds a Set-Cookie header to the provided ResponseWriter's headers.
+func SetCookie(w ResponseWriter, cookie *Cookie) {
+	w.Header().Add("Set-Cookie", cookie.String())
+}
+
+// String returns the serialization of the cookie for use in a Cookie
+// header (if only Name and Value are set) or a Set-Cookie response
+// header (if other fields are set).
+func (c *Cookie) String() string {
+	var b bytes.Buffer
+	fmt.Fprintf(&b, "%s=%s", sanitizeCookieName(c.Name), sanitizeCookieValue(c.Value))
+	if len(c.Path) > 0 {
+		fmt.Fprintf(&b, "; Path=%s", sanitizeCookiePath(c.Path))
+	}
+	if len(c.Domain) > 0 {
+		if validCookieDomain(c.Domain) {
+			// A c.Domain containing illegal characters is not
+			// sanitized but simply dropped which turns the cookie
+			// into a host-only cookie. A leading dot is okay
+			// but won't be sent.
+			d := c.Domain
+			if d[0] == '.' {
+				d = d[1:]
+			}
+			fmt.Fprintf(&b, "; Domain=%s", d)
+		} else {
+			log.Printf("net/http: invalid Cookie.Domain %q; dropping domain attribute",
+				c.Domain)
+		}
+	}
+	if c.Expires.Unix() > 0 {
+		fmt.Fprintf(&b, "; Expires=%s", c.Expires.UTC().Format(time.RFC1123))
+	}
+	if c.MaxAge > 0 {
+		fmt.Fprintf(&b, "; Max-Age=%d", c.MaxAge)
+	} else if c.MaxAge < 0 {
+		fmt.Fprintf(&b, "; Max-Age=0")
+	}
+	if c.HttpOnly {
+		fmt.Fprintf(&b, "; HttpOnly")
+	}
+	if c.Secure {
+		fmt.Fprintf(&b, "; Secure")
+	}
+	return b.String()
+}
+
+// readCookies parses all "Cookie" values from the header h and
+// returns the successfully parsed Cookies.
+//
+// if filter isn't empty, only cookies of that name are returned
+func readCookies(h Header, filter string) []*Cookie {
+	cookies := []*Cookie{}
+	lines, ok := h["Cookie"]
+	if !ok {
+		return cookies
+	}
+
+	for _, line := range lines {
+		parts := strings.Split(strings.TrimSpace(line), ";")
+		if len(parts) == 1 && parts[0] == "" {
+			continue
+		}
+		// Per-line attributes
+		parsedPairs := 0
+		for i := 0; i < len(parts); i++ {
+			parts[i] = strings.TrimSpace(parts[i])
+			if len(parts[i]) == 0 {
+				continue
+			}
+			name, val := parts[i], ""
+			if j := strings.Index(name, "="); j >= 0 {
+				name, val = name[:j], name[j+1:]
+			}
+			if !isCookieNameValid(name) {
+				continue
+			}
+			if filter != "" && filter != name {
+				continue
+			}
+			val, success := parseCookieValue(val, true)
+			if !success {
+				continue
+			}
+			cookies = append(cookies, &Cookie{Name: name, Value: val})
+			parsedPairs++
+		}
+	}
+	return cookies
+}
+
+// validCookieDomain returns wheter v is a valid cookie domain-value.
+func validCookieDomain(v string) bool {
+	if isCookieDomainName(v) {
+		return true
+	}
+	if net.ParseIP(v) != nil && !strings.Contains(v, ":") {
+		return true
+	}
+	return false
+}
+
+// isCookieDomainName returns whether s is a valid domain name or a valid
+// domain name with a leading dot '.'.  It is almost a direct copy of
+// package net's isDomainName.
+func isCookieDomainName(s string) bool {
+	if len(s) == 0 {
+		return false
+	}
+	if len(s) > 255 {
+		return false
+	}
+
+	if s[0] == '.' {
+		// A cookie a domain attribute may start with a leading dot.
+		s = s[1:]
+	}
+	last := byte('.')
+	ok := false // Ok once we've seen a letter.
+	partlen := 0
+	for i := 0; i < len(s); i++ {
+		c := s[i]
+		switch {
+		default:
+			return false
+		case 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z':
+			// No '_' allowed here (in contrast to package net).
+			ok = true
+			partlen++
+		case '0' <= c && c <= '9':
+			// fine
+			partlen++
+		case c == '-':
+			// Byte before dash cannot be dot.
+			if last == '.' {
+				return false
+			}
+			partlen++
+		case c == '.':
+			// Byte before dot cannot be dot, dash.
+			if last == '.' || last == '-' {
+				return false
+			}
+			if partlen > 63 || partlen == 0 {
+				return false
+			}
+			partlen = 0
+		}
+		last = c
+	}
+	if last == '-' || partlen > 63 {
+		return false
+	}
+
+	return ok
+}
+
+var cookieNameSanitizer = strings.NewReplacer("\n", "-", "\r", "-")
+
+func sanitizeCookieName(n string) string {
+	return cookieNameSanitizer.Replace(n)
+}
+
+// http://tools.ietf.org/html/rfc6265#section-4.1.1
+// cookie-value      = *cookie-octet / ( DQUOTE *cookie-octet DQUOTE )
+// cookie-octet      = %x21 / %x23-2B / %x2D-3A / %x3C-5B / %x5D-7E
+//           ; US-ASCII characters excluding CTLs,
+//           ; whitespace DQUOTE, comma, semicolon,
+//           ; and backslash
+// We loosen this as spaces and commas are common in cookie values
+// but we produce a quoted cookie-value in when value starts or ends
+// with a comma or space.
+// See http://golang.org/issue/7243 for the discussion.
+func sanitizeCookieValue(v string) string {
+	v = sanitizeOrWarn("Cookie.Value", validCookieValueByte, v)
+	if len(v) == 0 {
+		return v
+	}
+	if v[0] == ' ' || v[0] == ',' || v[len(v)-1] == ' ' || v[len(v)-1] == ',' {
+		return `"` + v + `"`
+	}
+	return v
+}
+
+func validCookieValueByte(b byte) bool {
+	return 0x20 <= b && b < 0x7f && b != '"' && b != ';' && b != '\\'
+}
+
+// path-av           = "Path=" path-value
+// path-value        = <any CHAR except CTLs or ";">
+func sanitizeCookiePath(v string) string {
+	return sanitizeOrWarn("Cookie.Path", validCookiePathByte, v)
+}
+
+func validCookiePathByte(b byte) bool {
+	return 0x20 <= b && b < 0x7f && b != ';'
+}
+
+func sanitizeOrWarn(fieldName string, valid func(byte) bool, v string) string {
+	ok := true
+	for i := 0; i < len(v); i++ {
+		if valid(v[i]) {
+			continue
+		}
+		log.Printf("net/http: invalid byte %q in %s; dropping invalid bytes", v[i], fieldName)
+		ok = false
+		break
+	}
+	if ok {
+		return v
+	}
+	buf := make([]byte, 0, len(v))
+	for i := 0; i < len(v); i++ {
+		if b := v[i]; valid(b) {
+			buf = append(buf, b)
+		}
+	}
+	return string(buf)
+}
+
+func parseCookieValue(raw string, allowDoubleQuote bool) (string, bool) {
+	// Strip the quotes, if present.
+	if allowDoubleQuote && len(raw) > 1 && raw[0] == '"' && raw[len(raw)-1] == '"' {
+		raw = raw[1 : len(raw)-1]
+	}
+	for i := 0; i < len(raw); i++ {
+		if !validCookieValueByte(raw[i]) {
+			return "", false
+		}
+	}
+	return raw, true
+}
+
+func isCookieNameValid(raw string) bool {
+	return strings.IndexFunc(raw, isNotToken) < 0
+}
diff --git a/src/net/http/cookie_test.go b/src/net/http/cookie_test.go
new file mode 100644
index 0000000..98dc2fa
--- /dev/null
+++ b/src/net/http/cookie_test.go
@@ -0,0 +1,412 @@
+// Copyright 2010 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package http
+
+import (
+	"bytes"
+	"encoding/json"
+	"fmt"
+	"log"
+	"os"
+	"reflect"
+	"strings"
+	"testing"
+	"time"
+)
+
+var writeSetCookiesTests = []struct {
+	Cookie *Cookie
+	Raw    string
+}{
+	{
+		&Cookie{Name: "cookie-1", Value: "v$1"},
+		"cookie-1=v$1",
+	},
+	{
+		&Cookie{Name: "cookie-2", Value: "two", MaxAge: 3600},
+		"cookie-2=two; Max-Age=3600",
+	},
+	{
+		&Cookie{Name: "cookie-3", Value: "three", Domain: ".example.com"},
+		"cookie-3=three; Domain=example.com",
+	},
+	{
+		&Cookie{Name: "cookie-4", Value: "four", Path: "/restricted/"},
+		"cookie-4=four; Path=/restricted/",
+	},
+	{
+		&Cookie{Name: "cookie-5", Value: "five", Domain: "wrong;bad.abc"},
+		"cookie-5=five",
+	},
+	{
+		&Cookie{Name: "cookie-6", Value: "six", Domain: "bad-.abc"},
+		"cookie-6=six",
+	},
+	{
+		&Cookie{Name: "cookie-7", Value: "seven", Domain: "127.0.0.1"},
+		"cookie-7=seven; Domain=127.0.0.1",
+	},
+	{
+		&Cookie{Name: "cookie-8", Value: "eight", Domain: "::1"},
+		"cookie-8=eight",
+	},
+	// The "special" cookies have values containing commas or spaces which
+	// are disallowed by RFC 6265 but are common in the wild.
+	{
+		&Cookie{Name: "special-1", Value: "a z"},
+		`special-1=a z`,
+	},
+	{
+		&Cookie{Name: "special-2", Value: " z"},
+		`special-2=" z"`,
+	},
+	{
+		&Cookie{Name: "special-3", Value: "a "},
+		`special-3="a "`,
+	},
+	{
+		&Cookie{Name: "special-4", Value: " "},
+		`special-4=" "`,
+	},
+	{
+		&Cookie{Name: "special-5", Value: "a,z"},
+		`special-5=a,z`,
+	},
+	{
+		&Cookie{Name: "special-6", Value: ",z"},
+		`special-6=",z"`,
+	},
+	{
+		&Cookie{Name: "special-7", Value: "a,"},
+		`special-7="a,"`,
+	},
+	{
+		&Cookie{Name: "special-8", Value: ","},
+		`special-8=","`,
+	},
+	{
+		&Cookie{Name: "empty-value", Value: ""},
+		`empty-value=`,
+	},
+}
+
+func TestWriteSetCookies(t *testing.T) {
+	defer log.SetOutput(os.Stderr)
+	var logbuf bytes.Buffer
+	log.SetOutput(&logbuf)
+
+	for i, tt := range writeSetCookiesTests {
+		if g, e := tt.Cookie.String(), tt.Raw; g != e {
+			t.Errorf("Test %d, expecting:\n%s\nGot:\n%s\n", i, e, g)
+			continue
+		}
+	}
+
+	if got, sub := logbuf.String(), "dropping domain attribute"; !strings.Contains(got, sub) {
+		t.Errorf("Expected substring %q in log output. Got:\n%s", sub, got)
+	}
+}
+
+type headerOnlyResponseWriter Header
+
+func (ho headerOnlyResponseWriter) Header() Header {
+	return Header(ho)
+}
+
+func (ho headerOnlyResponseWriter) Write([]byte) (int, error) {
+	panic("NOIMPL")
+}
+
+func (ho headerOnlyResponseWriter) WriteHeader(int) {
+	panic("NOIMPL")
+}
+
+func TestSetCookie(t *testing.T) {
+	m := make(Header)
+	SetCookie(headerOnlyResponseWriter(m), &Cookie{Name: "cookie-1", Value: "one", Path: "/restricted/"})
+	SetCookie(headerOnlyResponseWriter(m), &Cookie{Name: "cookie-2", Value: "two", MaxAge: 3600})
+	if l := len(m["Set-Cookie"]); l != 2 {
+		t.Fatalf("expected %d cookies, got %d", 2, l)
+	}
+	if g, e := m["Set-Cookie"][0], "cookie-1=one; Path=/restricted/"; g != e {
+		t.Errorf("cookie #1: want %q, got %q", e, g)
+	}
+	if g, e := m["Set-Cookie"][1], "cookie-2=two; Max-Age=3600"; g != e {
+		t.Errorf("cookie #2: want %q, got %q", e, g)
+	}
+}
+
+var addCookieTests = []struct {
+	Cookies []*Cookie
+	Raw     string
+}{
+	{
+		[]*Cookie{},
+		"",
+	},
+	{
+		[]*Cookie{{Name: "cookie-1", Value: "v$1"}},
+		"cookie-1=v$1",
+	},
+	{
+		[]*Cookie{
+			{Name: "cookie-1", Value: "v$1"},
+			{Name: "cookie-2", Value: "v$2"},
+			{Name: "cookie-3", Value: "v$3"},
+		},
+		"cookie-1=v$1; cookie-2=v$2; cookie-3=v$3",
+	},
+}
+
+func TestAddCookie(t *testing.T) {
+	for i, tt := range addCookieTests {
+		req, _ := NewRequest("GET", "http://example.com/", nil)
+		for _, c := range tt.Cookies {
+			req.AddCookie(c)
+		}
+		if g := req.Header.Get("Cookie"); g != tt.Raw {
+			t.Errorf("Test %d:\nwant: %s\n got: %s\n", i, tt.Raw, g)
+			continue
+		}
+	}
+}
+
+var readSetCookiesTests = []struct {
+	Header  Header
+	Cookies []*Cookie
+}{
+	{
+		Header{"Set-Cookie": {"Cookie-1=v$1"}},
+		[]*Cookie{{Name: "Cookie-1", Value: "v$1", Raw: "Cookie-1=v$1"}},
+	},
+	{
+		Header{"Set-Cookie": {"NID=99=YsDT5i3E-CXax-; expires=Wed, 23-Nov-2011 01:05:03 GMT; path=/; domain=.google.ch; HttpOnly"}},
+		[]*Cookie{{
+			Name:       "NID",
+			Value:      "99=YsDT5i3E-CXax-",
+			Path:       "/",
+			Domain:     ".google.ch",
+			HttpOnly:   true,
+			Expires:    time.Date(2011, 11, 23, 1, 5, 3, 0, time.UTC),
+			RawExpires: "Wed, 23-Nov-2011 01:05:03 GMT",
+			Raw:        "NID=99=YsDT5i3E-CXax-; expires=Wed, 23-Nov-2011 01:05:03 GMT; path=/; domain=.google.ch; HttpOnly",
+		}},
+	},
+	{
+		Header{"Set-Cookie": {".ASPXAUTH=7E3AA; expires=Wed, 07-Mar-2012 14:25:06 GMT; path=/; HttpOnly"}},
+		[]*Cookie{{
+			Name:       ".ASPXAUTH",
+			Value:      "7E3AA",
+			Path:       "/",
+			Expires:    time.Date(2012, 3, 7, 14, 25, 6, 0, time.UTC),
+			RawExpires: "Wed, 07-Mar-2012 14:25:06 GMT",
+			HttpOnly:   true,
+			Raw:        ".ASPXAUTH=7E3AA; expires=Wed, 07-Mar-2012 14:25:06 GMT; path=/; HttpOnly",
+		}},
+	},
+	{
+		Header{"Set-Cookie": {"ASP.NET_SessionId=foo; path=/; HttpOnly"}},
+		[]*Cookie{{
+			Name:     "ASP.NET_SessionId",
+			Value:    "foo",
+			Path:     "/",
+			HttpOnly: true,
+			Raw:      "ASP.NET_SessionId=foo; path=/; HttpOnly",
+		}},
+	},
+	// Make sure we can properly read back the Set-Cookie headers we create
+	// for values containing spaces or commas:
+	{
+		Header{"Set-Cookie": {`special-1=a z`}},
+		[]*Cookie{{Name: "special-1", Value: "a z", Raw: `special-1=a z`}},
+	},
+	{
+		Header{"Set-Cookie": {`special-2=" z"`}},
+		[]*Cookie{{Name: "special-2", Value: " z", Raw: `special-2=" z"`}},
+	},
+	{
+		Header{"Set-Cookie": {`special-3="a "`}},
+		[]*Cookie{{Name: "special-3", Value: "a ", Raw: `special-3="a "`}},
+	},
+	{
+		Header{"Set-Cookie": {`special-4=" "`}},
+		[]*Cookie{{Name: "special-4", Value: " ", Raw: `special-4=" "`}},
+	},
+	{
+		Header{"Set-Cookie": {`special-5=a,z`}},
+		[]*Cookie{{Name: "special-5", Value: "a,z", Raw: `special-5=a,z`}},
+	},
+	{
+		Header{"Set-Cookie": {`special-6=",z"`}},
+		[]*Cookie{{Name: "special-6", Value: ",z", Raw: `special-6=",z"`}},
+	},
+	{
+		Header{"Set-Cookie": {`special-7=a,`}},
+		[]*Cookie{{Name: "special-7", Value: "a,", Raw: `special-7=a,`}},
+	},
+	{
+		Header{"Set-Cookie": {`special-8=","`}},
+		[]*Cookie{{Name: "special-8", Value: ",", Raw: `special-8=","`}},
+	},
+
+	// TODO(bradfitz): users have reported seeing this in the
+	// wild, but do browsers handle it? RFC 6265 just says "don't
+	// do that" (section 3) and then never mentions header folding
+	// again.
+	// Header{"Set-Cookie": {"ASP.NET_SessionId=foo; path=/; HttpOnly, .ASPXAUTH=7E3AA; expires=Wed, 07-Mar-2012 14:25:06 GMT; path=/; HttpOnly"}},
+}
+
+func toJSON(v interface{}) string {
+	b, err := json.Marshal(v)
+	if err != nil {
+		return fmt.Sprintf("%#v", v)
+	}
+	return string(b)
+}
+
+func TestReadSetCookies(t *testing.T) {
+	for i, tt := range readSetCookiesTests {
+		for n := 0; n < 2; n++ { // to verify readSetCookies doesn't mutate its input
+			c := readSetCookies(tt.Header)
+			if !reflect.DeepEqual(c, tt.Cookies) {
+				t.Errorf("#%d readSetCookies: have\n%s\nwant\n%s\n", i, toJSON(c), toJSON(tt.Cookies))
+				continue
+			}
+		}
+	}
+}
+
+var readCookiesTests = []struct {
+	Header  Header
+	Filter  string
+	Cookies []*Cookie
+}{
+	{
+		Header{"Cookie": {"Cookie-1=v$1", "c2=v2"}},
+		"",
+		[]*Cookie{
+			{Name: "Cookie-1", Value: "v$1"},
+			{Name: "c2", Value: "v2"},
+		},
+	},
+	{
+		Header{"Cookie": {"Cookie-1=v$1", "c2=v2"}},
+		"c2",
+		[]*Cookie{
+			{Name: "c2", Value: "v2"},
+		},
+	},
+	{
+		Header{"Cookie": {"Cookie-1=v$1; c2=v2"}},
+		"",
+		[]*Cookie{
+			{Name: "Cookie-1", Value: "v$1"},
+			{Name: "c2", Value: "v2"},
+		},
+	},
+	{
+		Header{"Cookie": {"Cookie-1=v$1; c2=v2"}},
+		"c2",
+		[]*Cookie{
+			{Name: "c2", Value: "v2"},
+		},
+	},
+	{
+		Header{"Cookie": {`Cookie-1="v$1"; c2="v2"`}},
+		"",
+		[]*Cookie{
+			{Name: "Cookie-1", Value: "v$1"},
+			{Name: "c2", Value: "v2"},
+		},
+	},
+}
+
+func TestReadCookies(t *testing.T) {
+	for i, tt := range readCookiesTests {
+		for n := 0; n < 2; n++ { // to verify readCookies doesn't mutate its input
+			c := readCookies(tt.Header, tt.Filter)
+			if !reflect.DeepEqual(c, tt.Cookies) {
+				t.Errorf("#%d readCookies:\nhave: %s\nwant: %s\n", i, toJSON(c), toJSON(tt.Cookies))
+				continue
+			}
+		}
+	}
+}
+
+func TestSetCookieDoubleQuotes(t *testing.T) {
+	res := &Response{Header: Header{}}
+	res.Header.Add("Set-Cookie", `quoted0=none; max-age=30`)
+	res.Header.Add("Set-Cookie", `quoted1="cookieValue"; max-age=31`)
+	res.Header.Add("Set-Cookie", `quoted2=cookieAV; max-age="32"`)
+	res.Header.Add("Set-Cookie", `quoted3="both"; max-age="33"`)
+	got := res.Cookies()
+	want := []*Cookie{
+		{Name: "quoted0", Value: "none", MaxAge: 30},
+		{Name: "quoted1", Value: "cookieValue", MaxAge: 31},
+		{Name: "quoted2", Value: "cookieAV"},
+		{Name: "quoted3", Value: "both"},
+	}
+	if len(got) != len(want) {
+		t.Fatal("got %d cookies, want %d", len(got), len(want))
+	}
+	for i, w := range want {
+		g := got[i]
+		if g.Name != w.Name || g.Value != w.Value || g.MaxAge != w.MaxAge {
+			t.Errorf("cookie #%d:\ngot  %v\nwant %v", i, g, w)
+		}
+	}
+}
+
+func TestCookieSanitizeValue(t *testing.T) {
+	defer log.SetOutput(os.Stderr)
+	var logbuf bytes.Buffer
+	log.SetOutput(&logbuf)
+
+	tests := []struct {
+		in, want string
+	}{
+		{"foo", "foo"},
+		{"foo;bar", "foobar"},
+		{"foo\\bar", "foobar"},
+		{"foo\"bar", "foobar"},
+		{"\x00\x7e\x7f\x80", "\x7e"},
+		{`"withquotes"`, "withquotes"},
+		{"a z", "a z"},
+		{" z", `" z"`},
+		{"a ", `"a "`},
+	}
+	for _, tt := range tests {
+		if got := sanitizeCookieValue(tt.in); got != tt.want {
+			t.Errorf("sanitizeCookieValue(%q) = %q; want %q", tt.in, got, tt.want)
+		}
+	}
+
+	if got, sub := logbuf.String(), "dropping invalid bytes"; !strings.Contains(got, sub) {
+		t.Errorf("Expected substring %q in log output. Got:\n%s", sub, got)
+	}
+}
+
+func TestCookieSanitizePath(t *testing.T) {
+	defer log.SetOutput(os.Stderr)
+	var logbuf bytes.Buffer
+	log.SetOutput(&logbuf)
+
+	tests := []struct {
+		in, want string
+	}{
+		{"/path", "/path"},
+		{"/path with space/", "/path with space/"},
+		{"/just;no;semicolon\x00orstuff/", "/justnosemicolonorstuff/"},
+	}
+	for _, tt := range tests {
+		if got := sanitizeCookiePath(tt.in); got != tt.want {
+			t.Errorf("sanitizeCookiePath(%q) = %q; want %q", tt.in, got, tt.want)
+		}
+	}
+
+	if got, sub := logbuf.String(), "dropping invalid bytes"; !strings.Contains(got, sub) {
+		t.Errorf("Expected substring %q in log output. Got:\n%s", sub, got)
+	}
+}
diff --git a/src/net/http/cookiejar/jar.go b/src/net/http/cookiejar/jar.go
new file mode 100644
index 0000000..0e0fac9
--- /dev/null
+++ b/src/net/http/cookiejar/jar.go
@@ -0,0 +1,497 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package cookiejar implements an in-memory RFC 6265-compliant http.CookieJar.
+package cookiejar
+
+import (
+	"errors"
+	"fmt"
+	"net"
+	"net/http"
+	"net/url"
+	"sort"
+	"strings"
+	"sync"
+	"time"
+)
+
+// PublicSuffixList provides the public suffix of a domain. For example:
+//      - the public suffix of "example.com" is "com",
+//      - the public suffix of "foo1.foo2.foo3.co.uk" is "co.uk", and
+//      - the public suffix of "bar.pvt.k12.ma.us" is "pvt.k12.ma.us".
+//
+// Implementations of PublicSuffixList must be safe for concurrent use by
+// multiple goroutines.
+//
+// An implementation that always returns "" is valid and may be useful for
+// testing but it is not secure: it means that the HTTP server for foo.com can
+// set a cookie for bar.com.
+//
+// A public suffix list implementation is in the package
+// golang.org/x/net/publicsuffix.
+type PublicSuffixList interface {
+	// PublicSuffix returns the public suffix of domain.
+	//
+	// TODO: specify which of the caller and callee is responsible for IP
+	// addresses, for leading and trailing dots, for case sensitivity, and
+	// for IDN/Punycode.
+	PublicSuffix(domain string) string
+
+	// String returns a description of the source of this public suffix
+	// list. The description will typically contain something like a time
+	// stamp or version number.
+	String() string
+}
+
+// Options are the options for creating a new Jar.
+type Options struct {
+	// PublicSuffixList is the public suffix list that determines whether
+	// an HTTP server can set a cookie for a domain.
+	//
+	// A nil value is valid and may be useful for testing but it is not
+	// secure: it means that the HTTP server for foo.co.uk can set a cookie
+	// for bar.co.uk.
+	PublicSuffixList PublicSuffixList
+}
+
+// Jar implements the http.CookieJar interface from the net/http package.
+type Jar struct {
+	psList PublicSuffixList
+
+	// mu locks the remaining fields.
+	mu sync.Mutex
+
+	// entries is a set of entries, keyed by their eTLD+1 and subkeyed by
+	// their name/domain/path.
+	entries map[string]map[string]entry
+
+	// nextSeqNum is the next sequence number assigned to a new cookie
+	// created SetCookies.
+	nextSeqNum uint64
+}
+
+// New returns a new cookie jar. A nil *Options is equivalent to a zero
+// Options.
+func New(o *Options) (*Jar, error) {
+	jar := &Jar{
+		entries: make(map[string]map[string]entry),
+	}
+	if o != nil {
+		jar.psList = o.PublicSuffixList
+	}
+	return jar, nil
+}
+
+// entry is the internal representation of a cookie.
+//
+// This struct type is not used outside of this package per se, but the exported
+// fields are those of RFC 6265.
+type entry struct {
+	Name       string
+	Value      string
+	Domain     string
+	Path       string
+	Secure     bool
+	HttpOnly   bool
+	Persistent bool
+	HostOnly   bool
+	Expires    time.Time
+	Creation   time.Time
+	LastAccess time.Time
+
+	// seqNum is a sequence number so that Cookies returns cookies in a
+	// deterministic order, even for cookies that have equal Path length and
+	// equal Creation time. This simplifies testing.
+	seqNum uint64
+}
+
+// Id returns the domain;path;name triple of e as an id.
+func (e *entry) id() string {
+	return fmt.Sprintf("%s;%s;%s", e.Domain, e.Path, e.Name)
+}
+
+// shouldSend determines whether e's cookie qualifies to be included in a
+// request to host/path. It is the caller's responsibility to check if the
+// cookie is expired.
+func (e *entry) shouldSend(https bool, host, path string) bool {
+	return e.domainMatch(host) && e.pathMatch(path) && (https || !e.Secure)
+}
+
+// domainMatch implements "domain-match" of RFC 6265 section 5.1.3.
+func (e *entry) domainMatch(host string) bool {
+	if e.Domain == host {
+		return true
+	}
+	return !e.HostOnly && hasDotSuffix(host, e.Domain)
+}
+
+// pathMatch implements "path-match" according to RFC 6265 section 5.1.4.
+func (e *entry) pathMatch(requestPath string) bool {
+	if requestPath == e.Path {
+		return true
+	}
+	if strings.HasPrefix(requestPath, e.Path) {
+		if e.Path[len(e.Path)-1] == '/' {
+			return true // The "/any/" matches "/any/path" case.
+		} else if requestPath[len(e.Path)] == '/' {
+			return true // The "/any" matches "/any/path" case.
+		}
+	}
+	return false
+}
+
+// hasDotSuffix reports whether s ends in "."+suffix.
+func hasDotSuffix(s, suffix string) bool {
+	return len(s) > len(suffix) && s[len(s)-len(suffix)-1] == '.' && s[len(s)-len(suffix):] == suffix
+}
+
+// byPathLength is a []entry sort.Interface that sorts according to RFC 6265
+// section 5.4 point 2: by longest path and then by earliest creation time.
+type byPathLength []entry
+
+func (s byPathLength) Len() int { return len(s) }
+
+func (s byPathLength) Less(i, j int) bool {
+	if len(s[i].Path) != len(s[j].Path) {
+		return len(s[i].Path) > len(s[j].Path)
+	}
+	if !s[i].Creation.Equal(s[j].Creation) {
+		return s[i].Creation.Before(s[j].Creation)
+	}
+	return s[i].seqNum < s[j].seqNum
+}
+
+func (s byPathLength) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
+
+// Cookies implements the Cookies method of the http.CookieJar interface.
+//
+// It returns an empty slice if the URL's scheme is not HTTP or HTTPS.
+func (j *Jar) Cookies(u *url.URL) (cookies []*http.Cookie) {
+	return j.cookies(u, time.Now())
+}
+
+// cookies is like Cookies but takes the current time as a parameter.
+func (j *Jar) cookies(u *url.URL, now time.Time) (cookies []*http.Cookie) {
+	if u.Scheme != "http" && u.Scheme != "https" {
+		return cookies
+	}
+	host, err := canonicalHost(u.Host)
+	if err != nil {
+		return cookies
+	}
+	key := jarKey(host, j.psList)
+
+	j.mu.Lock()
+	defer j.mu.Unlock()
+
+	submap := j.entries[key]
+	if submap == nil {
+		return cookies
+	}
+
+	https := u.Scheme == "https"
+	path := u.Path
+	if path == "" {
+		path = "/"
+	}
+
+	modified := false
+	var selected []entry
+	for id, e := range submap {
+		if e.Persistent && !e.Expires.After(now) {
+			delete(submap, id)
+			modified = true
+			continue
+		}
+		if !e.shouldSend(https, host, path) {
+			continue
+		}
+		e.LastAccess = now
+		submap[id] = e
+		selected = append(selected, e)
+		modified = true
+	}
+	if modified {
+		if len(submap) == 0 {
+			delete(j.entries, key)
+		} else {
+			j.entries[key] = submap
+		}
+	}
+
+	sort.Sort(byPathLength(selected))
+	for _, e := range selected {
+		cookies = append(cookies, &http.Cookie{Name: e.Name, Value: e.Value})
+	}
+
+	return cookies
+}
+
+// SetCookies implements the SetCookies method of the http.CookieJar interface.
+//
+// It does nothing if the URL's scheme is not HTTP or HTTPS.
+func (j *Jar) SetCookies(u *url.URL, cookies []*http.Cookie) {
+	j.setCookies(u, cookies, time.Now())
+}
+
+// setCookies is like SetCookies but takes the current time as parameter.
+func (j *Jar) setCookies(u *url.URL, cookies []*http.Cookie, now time.Time) {
+	if len(cookies) == 0 {
+		return
+	}
+	if u.Scheme != "http" && u.Scheme != "https" {
+		return
+	}
+	host, err := canonicalHost(u.Host)
+	if err != nil {
+		return
+	}
+	key := jarKey(host, j.psList)
+	defPath := defaultPath(u.Path)
+
+	j.mu.Lock()
+	defer j.mu.Unlock()
+
+	submap := j.entries[key]
+
+	modified := false
+	for _, cookie := range cookies {
+		e, remove, err := j.newEntry(cookie, now, defPath, host)
+		if err != nil {
+			continue
+		}
+		id := e.id()
+		if remove {
+			if submap != nil {
+				if _, ok := submap[id]; ok {
+					delete(submap, id)
+					modified = true
+				}
+			}
+			continue
+		}
+		if submap == nil {
+			submap = make(map[string]entry)
+		}
+
+		if old, ok := submap[id]; ok {
+			e.Creation = old.Creation
+			e.seqNum = old.seqNum
+		} else {
+			e.Creation = now
+			e.seqNum = j.nextSeqNum
+			j.nextSeqNum++
+		}
+		e.LastAccess = now
+		submap[id] = e
+		modified = true
+	}
+
+	if modified {
+		if len(submap) == 0 {
+			delete(j.entries, key)
+		} else {
+			j.entries[key] = submap
+		}
+	}
+}
+
+// canonicalHost strips port from host if present and returns the canonicalized
+// host name.
+func canonicalHost(host string) (string, error) {
+	var err error
+	host = strings.ToLower(host)
+	if hasPort(host) {
+		host, _, err = net.SplitHostPort(host)
+		if err != nil {
+			return "", err
+		}
+	}
+	if strings.HasSuffix(host, ".") {
+		// Strip trailing dot from fully qualified domain names.
+		host = host[:len(host)-1]
+	}
+	return toASCII(host)
+}
+
+// hasPort reports whether host contains a port number. host may be a host
+// name, an IPv4 or an IPv6 address.
+func hasPort(host string) bool {
+	colons := strings.Count(host, ":")
+	if colons == 0 {
+		return false
+	}
+	if colons == 1 {
+		return true
+	}
+	return host[0] == '[' && strings.Contains(host, "]:")
+}
+
+// jarKey returns the key to use for a jar.
+func jarKey(host string, psl PublicSuffixList) string {
+	if isIP(host) {
+		return host
+	}
+
+	var i int
+	if psl == nil {
+		i = strings.LastIndex(host, ".")
+		if i == -1 {
+			return host
+		}
+	} else {
+		suffix := psl.PublicSuffix(host)
+		if suffix == host {
+			return host
+		}
+		i = len(host) - len(suffix)
+		if i <= 0 || host[i-1] != '.' {
+			// The provided public suffix list psl is broken.
+			// Storing cookies under host is a safe stopgap.
+			return host
+		}
+	}
+	prevDot := strings.LastIndex(host[:i-1], ".")
+	return host[prevDot+1:]
+}
+
+// isIP reports whether host is an IP address.
+func isIP(host string) bool {
+	return net.ParseIP(host) != nil
+}
+
+// defaultPath returns the directory part of an URL's path according to
+// RFC 6265 section 5.1.4.
+func defaultPath(path string) string {
+	if len(path) == 0 || path[0] != '/' {
+		return "/" // Path is empty or malformed.
+	}
+
+	i := strings.LastIndex(path, "/") // Path starts with "/", so i != -1.
+	if i == 0 {
+		return "/" // Path has the form "/abc".
+	}
+	return path[:i] // Path is either of form "/abc/xyz" or "/abc/xyz/".
+}
+
+// newEntry creates an entry from a http.Cookie c. now is the current time and
+// is compared to c.Expires to determine deletion of c. defPath and host are the
+// default-path and the canonical host name of the URL c was received from.
+//
+// remove records whether the jar should delete this cookie, as it has already
+// expired with respect to now. In this case, e may be incomplete, but it will
+// be valid to call e.id (which depends on e's Name, Domain and Path).
+//
+// A malformed c.Domain will result in an error.
+func (j *Jar) newEntry(c *http.Cookie, now time.Time, defPath, host string) (e entry, remove bool, err error) {
+	e.Name = c.Name
+
+	if c.Path == "" || c.Path[0] != '/' {
+		e.Path = defPath
+	} else {
+		e.Path = c.Path
+	}
+
+	e.Domain, e.HostOnly, err = j.domainAndType(host, c.Domain)
+	if err != nil {
+		return e, false, err
+	}
+
+	// MaxAge takes precedence over Expires.
+	if c.MaxAge < 0 {
+		return e, true, nil
+	} else if c.MaxAge > 0 {
+		e.Expires = now.Add(time.Duration(c.MaxAge) * time.Second)
+		e.Persistent = true
+	} else {
+		if c.Expires.IsZero() {
+			e.Expires = endOfTime
+			e.Persistent = false
+		} else {
+			if !c.Expires.After(now) {
+				return e, true, nil
+			}
+			e.Expires = c.Expires
+			e.Persistent = true
+		}
+	}
+
+	e.Value = c.Value
+	e.Secure = c.Secure
+	e.HttpOnly = c.HttpOnly
+
+	return e, false, nil
+}
+
+var (
+	errIllegalDomain   = errors.New("cookiejar: illegal cookie domain attribute")
+	errMalformedDomain = errors.New("cookiejar: malformed cookie domain attribute")
+	errNoHostname      = errors.New("cookiejar: no host name available (IP only)")
+)
+
+// endOfTime is the time when session (non-persistent) cookies expire.
+// This instant is representable in most date/time formats (not just
+// Go's time.Time) and should be far enough in the future.
+var endOfTime = time.Date(9999, 12, 31, 23, 59, 59, 0, time.UTC)
+
+// domainAndType determines the cookie's domain and hostOnly attribute.
+func (j *Jar) domainAndType(host, domain string) (string, bool, error) {
+	if domain == "" {
+		// No domain attribute in the SetCookie header indicates a
+		// host cookie.
+		return host, true, nil
+	}
+
+	if isIP(host) {
+		// According to RFC 6265 domain-matching includes not being
+		// an IP address.
+		// TODO: This might be relaxed as in common browsers.
+		return "", false, errNoHostname
+	}
+
+	// From here on: If the cookie is valid, it is a domain cookie (with
+	// the one exception of a public suffix below).
+	// See RFC 6265 section 5.2.3.
+	if domain[0] == '.' {
+		domain = domain[1:]
+	}
+
+	if len(domain) == 0 || domain[0] == '.' {
+		// Received either "Domain=." or "Domain=..some.thing",
+		// both are illegal.
+		return "", false, errMalformedDomain
+	}
+	domain = strings.ToLower(domain)
+
+	if domain[len(domain)-1] == '.' {
+		// We received stuff like "Domain=www.example.com.".
+		// Browsers do handle such stuff (actually differently) but
+		// RFC 6265 seems to be clear here (e.g. section 4.1.2.3) in
+		// requiring a reject.  4.1.2.3 is not normative, but
+		// "Domain Matching" (5.1.3) and "Canonicalized Host Names"
+		// (5.1.2) are.
+		return "", false, errMalformedDomain
+	}
+
+	// See RFC 6265 section 5.3 #5.
+	if j.psList != nil {
+		if ps := j.psList.PublicSuffix(domain); ps != "" && !hasDotSuffix(domain, ps) {
+			if host == domain {
+				// This is the one exception in which a cookie
+				// with a domain attribute is a host cookie.
+				return host, true, nil
+			}
+			return "", false, errIllegalDomain
+		}
+	}
+
+	// The domain must domain-match host: www.mycompany.com cannot
+	// set cookies for .ourcompetitors.com.
+	if host != domain && !hasDotSuffix(host, domain) {
+		return "", false, errIllegalDomain
+	}
+
+	return domain, false, nil
+}
diff --git a/src/pkg/net/http/cookiejar/jar_test.go b/src/net/http/cookiejar/jar_test.go
similarity index 100%
rename from src/pkg/net/http/cookiejar/jar_test.go
rename to src/net/http/cookiejar/jar_test.go
diff --git a/src/pkg/net/http/cookiejar/punycode.go b/src/net/http/cookiejar/punycode.go
similarity index 100%
rename from src/pkg/net/http/cookiejar/punycode.go
rename to src/net/http/cookiejar/punycode.go
diff --git a/src/pkg/net/http/cookiejar/punycode_test.go b/src/net/http/cookiejar/punycode_test.go
similarity index 100%
rename from src/pkg/net/http/cookiejar/punycode_test.go
rename to src/net/http/cookiejar/punycode_test.go
diff --git a/src/pkg/net/http/doc.go b/src/net/http/doc.go
similarity index 100%
rename from src/pkg/net/http/doc.go
rename to src/net/http/doc.go
diff --git a/src/pkg/net/http/example_test.go b/src/net/http/example_test.go
similarity index 100%
rename from src/pkg/net/http/example_test.go
rename to src/net/http/example_test.go
diff --git a/src/net/http/export_test.go b/src/net/http/export_test.go
new file mode 100644
index 0000000..87b6c07
--- /dev/null
+++ b/src/net/http/export_test.go
@@ -0,0 +1,108 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Bridge package to expose http internals to tests in the http_test
+// package.
+
+package http
+
+import (
+	"net"
+	"net/url"
+	"time"
+)
+
+func NewLoggingConn(baseName string, c net.Conn) net.Conn {
+	return newLoggingConn(baseName, c)
+}
+
+var ExportAppendTime = appendTime
+
+func (t *Transport) NumPendingRequestsForTesting() int {
+	t.reqMu.Lock()
+	defer t.reqMu.Unlock()
+	return len(t.reqCanceler)
+}
+
+func (t *Transport) IdleConnKeysForTesting() (keys []string) {
+	keys = make([]string, 0)
+	t.idleMu.Lock()
+	defer t.idleMu.Unlock()
+	if t.idleConn == nil {
+		return
+	}
+	for key := range t.idleConn {
+		keys = append(keys, key.String())
+	}
+	return
+}
+
+func (t *Transport) IdleConnCountForTesting(cacheKey string) int {
+	t.idleMu.Lock()
+	defer t.idleMu.Unlock()
+	if t.idleConn == nil {
+		return 0
+	}
+	for k, conns := range t.idleConn {
+		if k.String() == cacheKey {
+			return len(conns)
+		}
+	}
+	return 0
+}
+
+func (t *Transport) IdleConnChMapSizeForTesting() int {
+	t.idleMu.Lock()
+	defer t.idleMu.Unlock()
+	return len(t.idleConnCh)
+}
+
+func (t *Transport) IsIdleForTesting() bool {
+	t.idleMu.Lock()
+	defer t.idleMu.Unlock()
+	return t.wantIdle
+}
+
+func (t *Transport) RequestIdleConnChForTesting() {
+	t.getIdleConnCh(connectMethod{nil, "http", "example.com"})
+}
+
+func (t *Transport) PutIdleTestConn() bool {
+	c, _ := net.Pipe()
+	return t.putIdleConn(&persistConn{
+		t:        t,
+		conn:     c,                   // dummy
+		closech:  make(chan struct{}), // so it can be closed
+		cacheKey: connectMethodKey{"", "http", "example.com"},
+	})
+}
+
+func NewTestTimeoutHandler(handler Handler, ch <-chan time.Time) Handler {
+	f := func() <-chan time.Time {
+		return ch
+	}
+	return &timeoutHandler{handler, f, ""}
+}
+
+func ResetCachedEnvironment() {
+	httpProxyEnv.reset()
+	httpsProxyEnv.reset()
+	noProxyEnv.reset()
+}
+
+var DefaultUserAgent = defaultUserAgent
+
+func ExportRefererForURL(lastReq, newReq *url.URL) string {
+	return refererForURL(lastReq, newReq)
+}
+
+// SetPendingDialHooks sets the hooks that run before and after handling
+// pending dials.
+func SetPendingDialHooks(before, after func()) {
+	prePendingDial, postPendingDial = before, after
+}
+
+var ExportServerNewConn = (*Server).newConn
+
+var ExportCloseWriteAndWait = (*conn).closeWriteAndWait
diff --git a/src/pkg/net/http/fcgi/child.go b/src/net/http/fcgi/child.go
similarity index 100%
rename from src/pkg/net/http/fcgi/child.go
rename to src/net/http/fcgi/child.go
diff --git a/src/pkg/net/http/fcgi/fcgi.go b/src/net/http/fcgi/fcgi.go
similarity index 100%
rename from src/pkg/net/http/fcgi/fcgi.go
rename to src/net/http/fcgi/fcgi.go
diff --git a/src/pkg/net/http/fcgi/fcgi_test.go b/src/net/http/fcgi/fcgi_test.go
similarity index 100%
rename from src/pkg/net/http/fcgi/fcgi_test.go
rename to src/net/http/fcgi/fcgi_test.go
diff --git a/src/pkg/net/http/filetransport.go b/src/net/http/filetransport.go
similarity index 100%
rename from src/pkg/net/http/filetransport.go
rename to src/net/http/filetransport.go
diff --git a/src/pkg/net/http/filetransport_test.go b/src/net/http/filetransport_test.go
similarity index 100%
rename from src/pkg/net/http/filetransport_test.go
rename to src/net/http/filetransport_test.go
diff --git a/src/net/http/fs.go b/src/net/http/fs.go
new file mode 100644
index 0000000..e322f71
--- /dev/null
+++ b/src/net/http/fs.go
@@ -0,0 +1,556 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// HTTP file system request handler
+
+package http
+
+import (
+	"errors"
+	"fmt"
+	"io"
+	"mime"
+	"mime/multipart"
+	"net/textproto"
+	"net/url"
+	"os"
+	"path"
+	"path/filepath"
+	"strconv"
+	"strings"
+	"time"
+)
+
+// A Dir implements FileSystem using the native file system restricted to a
+// specific directory tree.
+//
+// While the FileSystem.Open method takes '/'-separated paths, a Dir's string
+// value is a filename on the native file system, not a URL, so it is separated
+// by filepath.Separator, which isn't necessarily '/'.
+//
+// An empty Dir is treated as ".".
+type Dir string
+
+func (d Dir) Open(name string) (File, error) {
+	if filepath.Separator != '/' && strings.IndexRune(name, filepath.Separator) >= 0 ||
+		strings.Contains(name, "\x00") {
+		return nil, errors.New("http: invalid character in file path")
+	}
+	dir := string(d)
+	if dir == "" {
+		dir = "."
+	}
+	f, err := os.Open(filepath.Join(dir, filepath.FromSlash(path.Clean("/"+name))))
+	if err != nil {
+		return nil, err
+	}
+	return f, nil
+}
+
+// A FileSystem implements access to a collection of named files.
+// The elements in a file path are separated by slash ('/', U+002F)
+// characters, regardless of host operating system convention.
+type FileSystem interface {
+	Open(name string) (File, error)
+}
+
+// A File is returned by a FileSystem's Open method and can be
+// served by the FileServer implementation.
+//
+// The methods should behave the same as those on an *os.File.
+type File interface {
+	io.Closer
+	io.Reader
+	Readdir(count int) ([]os.FileInfo, error)
+	Seek(offset int64, whence int) (int64, error)
+	Stat() (os.FileInfo, error)
+}
+
+func dirList(w ResponseWriter, f File) {
+	w.Header().Set("Content-Type", "text/html; charset=utf-8")
+	fmt.Fprintf(w, "<pre>\n")
+	for {
+		dirs, err := f.Readdir(100)
+		if err != nil || len(dirs) == 0 {
+			break
+		}
+		for _, d := range dirs {
+			name := d.Name()
+			if d.IsDir() {
+				name += "/"
+			}
+			// name may contain '?' or '#', which must be escaped to remain
+			// part of the URL path, and not indicate the start of a query
+			// string or fragment.
+			url := url.URL{Path: name}
+			fmt.Fprintf(w, "<a href=\"%s\">%s</a>\n", url.String(), htmlReplacer.Replace(name))
+		}
+	}
+	fmt.Fprintf(w, "</pre>\n")
+}
+
+// ServeContent replies to the request using the content in the
+// provided ReadSeeker.  The main benefit of ServeContent over io.Copy
+// is that it handles Range requests properly, sets the MIME type, and
+// handles If-Modified-Since requests.
+//
+// If the response's Content-Type header is not set, ServeContent
+// first tries to deduce the type from name's file extension and,
+// if that fails, falls back to reading the first block of the content
+// and passing it to DetectContentType.
+// The name is otherwise unused; in particular it can be empty and is
+// never sent in the response.
+//
+// If modtime is not the zero time, ServeContent includes it in a
+// Last-Modified header in the response.  If the request includes an
+// If-Modified-Since header, ServeContent uses modtime to decide
+// whether the content needs to be sent at all.
+//
+// The content's Seek method must work: ServeContent uses
+// a seek to the end of the content to determine its size.
+//
+// If the caller has set w's ETag header, ServeContent uses it to
+// handle requests using If-Range and If-None-Match.
+//
+// Note that *os.File implements the io.ReadSeeker interface.
+func ServeContent(w ResponseWriter, req *Request, name string, modtime time.Time, content io.ReadSeeker) {
+	sizeFunc := func() (int64, error) {
+		size, err := content.Seek(0, os.SEEK_END)
+		if err != nil {
+			return 0, errSeeker
+		}
+		_, err = content.Seek(0, os.SEEK_SET)
+		if err != nil {
+			return 0, errSeeker
+		}
+		return size, nil
+	}
+	serveContent(w, req, name, modtime, sizeFunc, content)
+}
+
+// errSeeker is returned by ServeContent's sizeFunc when the content
+// doesn't seek properly. The underlying Seeker's error text isn't
+// included in the sizeFunc reply so it's not sent over HTTP to end
+// users.
+var errSeeker = errors.New("seeker can't seek")
+
+// if name is empty, filename is unknown. (used for mime type, before sniffing)
+// if modtime.IsZero(), modtime is unknown.
+// content must be seeked to the beginning of the file.
+// The sizeFunc is called at most once. Its error, if any, is sent in the HTTP response.
+func serveContent(w ResponseWriter, r *Request, name string, modtime time.Time, sizeFunc func() (int64, error), content io.ReadSeeker) {
+	if checkLastModified(w, r, modtime) {
+		return
+	}
+	rangeReq, done := checkETag(w, r, modtime)
+	if done {
+		return
+	}
+
+	code := StatusOK
+
+	// If Content-Type isn't set, use the file's extension to find it, but
+	// if the Content-Type is unset explicitly, do not sniff the type.
+	ctypes, haveType := w.Header()["Content-Type"]
+	var ctype string
+	if !haveType {
+		ctype = mime.TypeByExtension(filepath.Ext(name))
+		if ctype == "" {
+			// read a chunk to decide between utf-8 text and binary
+			var buf [sniffLen]byte
+			n, _ := io.ReadFull(content, buf[:])
+			ctype = DetectContentType(buf[:n])
+			_, err := content.Seek(0, os.SEEK_SET) // rewind to output whole file
+			if err != nil {
+				Error(w, "seeker can't seek", StatusInternalServerError)
+				return
+			}
+		}
+		w.Header().Set("Content-Type", ctype)
+	} else if len(ctypes) > 0 {
+		ctype = ctypes[0]
+	}
+
+	size, err := sizeFunc()
+	if err != nil {
+		Error(w, err.Error(), StatusInternalServerError)
+		return
+	}
+
+	// handle Content-Range header.
+	sendSize := size
+	var sendContent io.Reader = content
+	if size >= 0 {
+		ranges, err := parseRange(rangeReq, size)
+		if err != nil {
+			Error(w, err.Error(), StatusRequestedRangeNotSatisfiable)
+			return
+		}
+		if sumRangesSize(ranges) > size {
+			// The total number of bytes in all the ranges
+			// is larger than the size of the file by
+			// itself, so this is probably an attack, or a
+			// dumb client.  Ignore the range request.
+			ranges = nil
+		}
+		switch {
+		case len(ranges) == 1:
+			// RFC 2616, Section 14.16:
+			// "When an HTTP message includes the content of a single
+			// range (for example, a response to a request for a
+			// single range, or to a request for a set of ranges
+			// that overlap without any holes), this content is
+			// transmitted with a Content-Range header, and a
+			// Content-Length header showing the number of bytes
+			// actually transferred.
+			// ...
+			// A response to a request for a single range MUST NOT
+			// be sent using the multipart/byteranges media type."
+			ra := ranges[0]
+			if _, err := content.Seek(ra.start, os.SEEK_SET); err != nil {
+				Error(w, err.Error(), StatusRequestedRangeNotSatisfiable)
+				return
+			}
+			sendSize = ra.length
+			code = StatusPartialContent
+			w.Header().Set("Content-Range", ra.contentRange(size))
+		case len(ranges) > 1:
+			sendSize = rangesMIMESize(ranges, ctype, size)
+			code = StatusPartialContent
+
+			pr, pw := io.Pipe()
+			mw := multipart.NewWriter(pw)
+			w.Header().Set("Content-Type", "multipart/byteranges; boundary="+mw.Boundary())
+			sendContent = pr
+			defer pr.Close() // cause writing goroutine to fail and exit if CopyN doesn't finish.
+			go func() {
+				for _, ra := range ranges {
+					part, err := mw.CreatePart(ra.mimeHeader(ctype, size))
+					if err != nil {
+						pw.CloseWithError(err)
+						return
+					}
+					if _, err := content.Seek(ra.start, os.SEEK_SET); err != nil {
+						pw.CloseWithError(err)
+						return
+					}
+					if _, err := io.CopyN(part, content, ra.length); err != nil {
+						pw.CloseWithError(err)
+						return
+					}
+				}
+				mw.Close()
+				pw.Close()
+			}()
+		}
+
+		w.Header().Set("Accept-Ranges", "bytes")
+		if w.Header().Get("Content-Encoding") == "" {
+			w.Header().Set("Content-Length", strconv.FormatInt(sendSize, 10))
+		}
+	}
+
+	w.WriteHeader(code)
+
+	if r.Method != "HEAD" {
+		io.CopyN(w, sendContent, sendSize)
+	}
+}
+
+// modtime is the modification time of the resource to be served, or IsZero().
+// return value is whether this request is now complete.
+func checkLastModified(w ResponseWriter, r *Request, modtime time.Time) bool {
+	if modtime.IsZero() {
+		return false
+	}
+
+	// The Date-Modified header truncates sub-second precision, so
+	// use mtime < t+1s instead of mtime <= t to check for unmodified.
+	if t, err := time.Parse(TimeFormat, r.Header.Get("If-Modified-Since")); err == nil && modtime.Before(t.Add(1*time.Second)) {
+		h := w.Header()
+		delete(h, "Content-Type")
+		delete(h, "Content-Length")
+		w.WriteHeader(StatusNotModified)
+		return true
+	}
+	w.Header().Set("Last-Modified", modtime.UTC().Format(TimeFormat))
+	return false
+}
+
+// checkETag implements If-None-Match and If-Range checks.
+//
+// The ETag or modtime must have been previously set in the
+// ResponseWriter's headers.  The modtime is only compared at second
+// granularity and may be the zero value to mean unknown.
+//
+// The return value is the effective request "Range" header to use and
+// whether this request is now considered done.
+func checkETag(w ResponseWriter, r *Request, modtime time.Time) (rangeReq string, done bool) {
+	etag := w.Header().get("Etag")
+	rangeReq = r.Header.get("Range")
+
+	// Invalidate the range request if the entity doesn't match the one
+	// the client was expecting.
+	// "If-Range: version" means "ignore the Range: header unless version matches the
+	// current file."
+	// We only support ETag versions.
+	// The caller must have set the ETag on the response already.
+	if ir := r.Header.get("If-Range"); ir != "" && ir != etag {
+		// The If-Range value is typically the ETag value, but it may also be
+		// the modtime date. See golang.org/issue/8367.
+		timeMatches := false
+		if !modtime.IsZero() {
+			if t, err := ParseTime(ir); err == nil && t.Unix() == modtime.Unix() {
+				timeMatches = true
+			}
+		}
+		if !timeMatches {
+			rangeReq = ""
+		}
+	}
+
+	if inm := r.Header.get("If-None-Match"); inm != "" {
+		// Must know ETag.
+		if etag == "" {
+			return rangeReq, false
+		}
+
+		// TODO(bradfitz): non-GET/HEAD requests require more work:
+		// sending a different status code on matches, and
+		// also can't use weak cache validators (those with a "W/
+		// prefix).  But most users of ServeContent will be using
+		// it on GET or HEAD, so only support those for now.
+		if r.Method != "GET" && r.Method != "HEAD" {
+			return rangeReq, false
+		}
+
+		// TODO(bradfitz): deal with comma-separated or multiple-valued
+		// list of If-None-match values.  For now just handle the common
+		// case of a single item.
+		if inm == etag || inm == "*" {
+			h := w.Header()
+			delete(h, "Content-Type")
+			delete(h, "Content-Length")
+			w.WriteHeader(StatusNotModified)
+			return "", true
+		}
+	}
+	return rangeReq, false
+}
+
+// name is '/'-separated, not filepath.Separator.
+func serveFile(w ResponseWriter, r *Request, fs FileSystem, name string, redirect bool) {
+	const indexPage = "/index.html"
+
+	// redirect .../index.html to .../
+	// can't use Redirect() because that would make the path absolute,
+	// which would be a problem running under StripPrefix
+	if strings.HasSuffix(r.URL.Path, indexPage) {
+		localRedirect(w, r, "./")
+		return
+	}
+
+	f, err := fs.Open(name)
+	if err != nil {
+		// TODO expose actual error?
+		NotFound(w, r)
+		return
+	}
+	defer f.Close()
+
+	d, err1 := f.Stat()
+	if err1 != nil {
+		// TODO expose actual error?
+		NotFound(w, r)
+		return
+	}
+
+	if redirect {
+		// redirect to canonical path: / at end of directory url
+		// r.URL.Path always begins with /
+		url := r.URL.Path
+		if d.IsDir() {
+			if url[len(url)-1] != '/' {
+				localRedirect(w, r, path.Base(url)+"/")
+				return
+			}
+		} else {
+			if url[len(url)-1] == '/' {
+				localRedirect(w, r, "../"+path.Base(url))
+				return
+			}
+		}
+	}
+
+	// use contents of index.html for directory, if present
+	if d.IsDir() {
+		index := strings.TrimSuffix(name, "/") + indexPage
+		ff, err := fs.Open(index)
+		if err == nil {
+			defer ff.Close()
+			dd, err := ff.Stat()
+			if err == nil {
+				name = index
+				d = dd
+				f = ff
+			}
+		}
+	}
+
+	// Still a directory? (we didn't find an index.html file)
+	if d.IsDir() {
+		if checkLastModified(w, r, d.ModTime()) {
+			return
+		}
+		dirList(w, f)
+		return
+	}
+
+	// serveContent will check modification time
+	sizeFunc := func() (int64, error) { return d.Size(), nil }
+	serveContent(w, r, d.Name(), d.ModTime(), sizeFunc, f)
+}
+
+// localRedirect gives a Moved Permanently response.
+// It does not convert relative paths to absolute paths like Redirect does.
+func localRedirect(w ResponseWriter, r *Request, newPath string) {
+	if q := r.URL.RawQuery; q != "" {
+		newPath += "?" + q
+	}
+	w.Header().Set("Location", newPath)
+	w.WriteHeader(StatusMovedPermanently)
+}
+
+// ServeFile replies to the request with the contents of the named file or directory.
+func ServeFile(w ResponseWriter, r *Request, name string) {
+	dir, file := filepath.Split(name)
+	serveFile(w, r, Dir(dir), file, false)
+}
+
+type fileHandler struct {
+	root FileSystem
+}
+
+// FileServer returns a handler that serves HTTP requests
+// with the contents of the file system rooted at root.
+//
+// To use the operating system's file system implementation,
+// use http.Dir:
+//
+//     http.Handle("/", http.FileServer(http.Dir("/tmp")))
+func FileServer(root FileSystem) Handler {
+	return &fileHandler{root}
+}
+
+func (f *fileHandler) ServeHTTP(w ResponseWriter, r *Request) {
+	upath := r.URL.Path
+	if !strings.HasPrefix(upath, "/") {
+		upath = "/" + upath
+		r.URL.Path = upath
+	}
+	serveFile(w, r, f.root, path.Clean(upath), true)
+}
+
+// httpRange specifies the byte range to be sent to the client.
+type httpRange struct {
+	start, length int64
+}
+
+func (r httpRange) contentRange(size int64) string {
+	return fmt.Sprintf("bytes %d-%d/%d", r.start, r.start+r.length-1, size)
+}
+
+func (r httpRange) mimeHeader(contentType string, size int64) textproto.MIMEHeader {
+	return textproto.MIMEHeader{
+		"Content-Range": {r.contentRange(size)},
+		"Content-Type":  {contentType},
+	}
+}
+
+// parseRange parses a Range header string as per RFC 2616.
+func parseRange(s string, size int64) ([]httpRange, error) {
+	if s == "" {
+		return nil, nil // header not present
+	}
+	const b = "bytes="
+	if !strings.HasPrefix(s, b) {
+		return nil, errors.New("invalid range")
+	}
+	var ranges []httpRange
+	for _, ra := range strings.Split(s[len(b):], ",") {
+		ra = strings.TrimSpace(ra)
+		if ra == "" {
+			continue
+		}
+		i := strings.Index(ra, "-")
+		if i < 0 {
+			return nil, errors.New("invalid range")
+		}
+		start, end := strings.TrimSpace(ra[:i]), strings.TrimSpace(ra[i+1:])
+		var r httpRange
+		if start == "" {
+			// If no start is specified, end specifies the
+			// range start relative to the end of the file.
+			i, err := strconv.ParseInt(end, 10, 64)
+			if err != nil {
+				return nil, errors.New("invalid range")
+			}
+			if i > size {
+				i = size
+			}
+			r.start = size - i
+			r.length = size - r.start
+		} else {
+			i, err := strconv.ParseInt(start, 10, 64)
+			if err != nil || i > size || i < 0 {
+				return nil, errors.New("invalid range")
+			}
+			r.start = i
+			if end == "" {
+				// If no end is specified, range extends to end of the file.
+				r.length = size - r.start
+			} else {
+				i, err := strconv.ParseInt(end, 10, 64)
+				if err != nil || r.start > i {
+					return nil, errors.New("invalid range")
+				}
+				if i >= size {
+					i = size - 1
+				}
+				r.length = i - r.start + 1
+			}
+		}
+		ranges = append(ranges, r)
+	}
+	return ranges, nil
+}
+
+// countingWriter counts how many bytes have been written to it.
+type countingWriter int64
+
+func (w *countingWriter) Write(p []byte) (n int, err error) {
+	*w += countingWriter(len(p))
+	return len(p), nil
+}
+
+// rangesMIMESize returns the number of bytes it takes to encode the
+// provided ranges as a multipart response.
+func rangesMIMESize(ranges []httpRange, contentType string, contentSize int64) (encSize int64) {
+	var w countingWriter
+	mw := multipart.NewWriter(&w)
+	for _, ra := range ranges {
+		mw.CreatePart(ra.mimeHeader(contentType, contentSize))
+		encSize += ra.length
+	}
+	mw.Close()
+	encSize += int64(w)
+	return
+}
+
+func sumRangesSize(ranges []httpRange) (size int64) {
+	for _, ra := range ranges {
+		size += ra.length
+	}
+	return
+}
diff --git a/src/net/http/fs_test.go b/src/net/http/fs_test.go
new file mode 100644
index 0000000..8770d9b
--- /dev/null
+++ b/src/net/http/fs_test.go
@@ -0,0 +1,917 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package http_test
+
+import (
+	"bytes"
+	"errors"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"mime"
+	"mime/multipart"
+	"net"
+	. "net/http"
+	"net/http/httptest"
+	"net/url"
+	"os"
+	"os/exec"
+	"path"
+	"path/filepath"
+	"reflect"
+	"regexp"
+	"runtime"
+	"strconv"
+	"strings"
+	"testing"
+	"time"
+)
+
+const (
+	testFile    = "testdata/file"
+	testFileLen = 11
+)
+
+type wantRange struct {
+	start, end int64 // range [start,end)
+}
+
+var itoa = strconv.Itoa
+
+var ServeFileRangeTests = []struct {
+	r      string
+	code   int
+	ranges []wantRange
+}{
+	{r: "", code: StatusOK},
+	{r: "bytes=0-4", code: StatusPartialContent, ranges: []wantRange{{0, 5}}},
+	{r: "bytes=2-", code: StatusPartialContent, ranges: []wantRange{{2, testFileLen}}},
+	{r: "bytes=-5", code: StatusPartialContent, ranges: []wantRange{{testFileLen - 5, testFileLen}}},
+	{r: "bytes=3-7", code: StatusPartialContent, ranges: []wantRange{{3, 8}}},
+	{r: "bytes=20-", code: StatusRequestedRangeNotSatisfiable},
+	{r: "bytes=0-0,-2", code: StatusPartialContent, ranges: []wantRange{{0, 1}, {testFileLen - 2, testFileLen}}},
+	{r: "bytes=0-1,5-8", code: StatusPartialContent, ranges: []wantRange{{0, 2}, {5, 9}}},
+	{r: "bytes=0-1,5-", code: StatusPartialContent, ranges: []wantRange{{0, 2}, {5, testFileLen}}},
+	{r: "bytes=5-1000", code: StatusPartialContent, ranges: []wantRange{{5, testFileLen}}},
+	{r: "bytes=0-,1-,2-,3-,4-", code: StatusOK}, // ignore wasteful range request
+	{r: "bytes=0-" + itoa(testFileLen-2), code: StatusPartialContent, ranges: []wantRange{{0, testFileLen - 1}}},
+	{r: "bytes=0-" + itoa(testFileLen-1), code: StatusPartialContent, ranges: []wantRange{{0, testFileLen}}},
+	{r: "bytes=0-" + itoa(testFileLen), code: StatusPartialContent, ranges: []wantRange{{0, testFileLen}}},
+}
+
+func TestServeFile(t *testing.T) {
+	defer afterTest(t)
+	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+		ServeFile(w, r, "testdata/file")
+	}))
+	defer ts.Close()
+
+	var err error
+
+	file, err := ioutil.ReadFile(testFile)
+	if err != nil {
+		t.Fatal("reading file:", err)
+	}
+
+	// set up the Request (re-used for all tests)
+	var req Request
+	req.Header = make(Header)
+	if req.URL, err = url.Parse(ts.URL); err != nil {
+		t.Fatal("ParseURL:", err)
+	}
+	req.Method = "GET"
+
+	// straight GET
+	_, body := getBody(t, "straight get", req)
+	if !bytes.Equal(body, file) {
+		t.Fatalf("body mismatch: got %q, want %q", body, file)
+	}
+
+	// Range tests
+Cases:
+	for _, rt := range ServeFileRangeTests {
+		if rt.r != "" {
+			req.Header.Set("Range", rt.r)
+		}
+		resp, body := getBody(t, fmt.Sprintf("range test %q", rt.r), req)
+		if resp.StatusCode != rt.code {
+			t.Errorf("range=%q: StatusCode=%d, want %d", rt.r, resp.StatusCode, rt.code)
+		}
+		if rt.code == StatusRequestedRangeNotSatisfiable {
+			continue
+		}
+		wantContentRange := ""
+		if len(rt.ranges) == 1 {
+			rng := rt.ranges[0]
+			wantContentRange = fmt.Sprintf("bytes %d-%d/%d", rng.start, rng.end-1, testFileLen)
+		}
+		cr := resp.Header.Get("Content-Range")
+		if cr != wantContentRange {
+			t.Errorf("range=%q: Content-Range = %q, want %q", rt.r, cr, wantContentRange)
+		}
+		ct := resp.Header.Get("Content-Type")
+		if len(rt.ranges) == 1 {
+			rng := rt.ranges[0]
+			wantBody := file[rng.start:rng.end]
+			if !bytes.Equal(body, wantBody) {
+				t.Errorf("range=%q: body = %q, want %q", rt.r, body, wantBody)
+			}
+			if strings.HasPrefix(ct, "multipart/byteranges") {
+				t.Errorf("range=%q content-type = %q; unexpected multipart/byteranges", rt.r, ct)
+			}
+		}
+		if len(rt.ranges) > 1 {
+			typ, params, err := mime.ParseMediaType(ct)
+			if err != nil {
+				t.Errorf("range=%q content-type = %q; %v", rt.r, ct, err)
+				continue
+			}
+			if typ != "multipart/byteranges" {
+				t.Errorf("range=%q content-type = %q; want multipart/byteranges", rt.r, typ)
+				continue
+			}
+			if params["boundary"] == "" {
+				t.Errorf("range=%q content-type = %q; lacks boundary", rt.r, ct)
+				continue
+			}
+			if g, w := resp.ContentLength, int64(len(body)); g != w {
+				t.Errorf("range=%q Content-Length = %d; want %d", rt.r, g, w)
+				continue
+			}
+			mr := multipart.NewReader(bytes.NewReader(body), params["boundary"])
+			for ri, rng := range rt.ranges {
+				part, err := mr.NextPart()
+				if err != nil {
+					t.Errorf("range=%q, reading part index %d: %v", rt.r, ri, err)
+					continue Cases
+				}
+				wantContentRange = fmt.Sprintf("bytes %d-%d/%d", rng.start, rng.end-1, testFileLen)
+				if g, w := part.Header.Get("Content-Range"), wantContentRange; g != w {
+					t.Errorf("range=%q: part Content-Range = %q; want %q", rt.r, g, w)
+				}
+				body, err := ioutil.ReadAll(part)
+				if err != nil {
+					t.Errorf("range=%q, reading part index %d body: %v", rt.r, ri, err)
+					continue Cases
+				}
+				wantBody := file[rng.start:rng.end]
+				if !bytes.Equal(body, wantBody) {
+					t.Errorf("range=%q: body = %q, want %q", rt.r, body, wantBody)
+				}
+			}
+			_, err = mr.NextPart()
+			if err != io.EOF {
+				t.Errorf("range=%q; expected final error io.EOF; got %v", rt.r, err)
+			}
+		}
+	}
+}
+
+var fsRedirectTestData = []struct {
+	original, redirect string
+}{
+	{"/test/index.html", "/test/"},
+	{"/test/testdata", "/test/testdata/"},
+	{"/test/testdata/file/", "/test/testdata/file"},
+}
+
+func TestFSRedirect(t *testing.T) {
+	defer afterTest(t)
+	ts := httptest.NewServer(StripPrefix("/test", FileServer(Dir("."))))
+	defer ts.Close()
+
+	for _, data := range fsRedirectTestData {
+		res, err := Get(ts.URL + data.original)
+		if err != nil {
+			t.Fatal(err)
+		}
+		res.Body.Close()
+		if g, e := res.Request.URL.Path, data.redirect; g != e {
+			t.Errorf("redirect from %s: got %s, want %s", data.original, g, e)
+		}
+	}
+}
+
+type testFileSystem struct {
+	open func(name string) (File, error)
+}
+
+func (fs *testFileSystem) Open(name string) (File, error) {
+	return fs.open(name)
+}
+
+func TestFileServerCleans(t *testing.T) {
+	defer afterTest(t)
+	ch := make(chan string, 1)
+	fs := FileServer(&testFileSystem{func(name string) (File, error) {
+		ch <- name
+		return nil, errors.New("file does not exist")
+	}})
+	tests := []struct {
+		reqPath, openArg string
+	}{
+		{"/foo.txt", "/foo.txt"},
+		{"//foo.txt", "/foo.txt"},
+		{"/../foo.txt", "/foo.txt"},
+	}
+	req, _ := NewRequest("GET", "http://example.com", nil)
+	for n, test := range tests {
+		rec := httptest.NewRecorder()
+		req.URL.Path = test.reqPath
+		fs.ServeHTTP(rec, req)
+		if got := <-ch; got != test.openArg {
+			t.Errorf("test %d: got %q, want %q", n, got, test.openArg)
+		}
+	}
+}
+
+func TestFileServerEscapesNames(t *testing.T) {
+	defer afterTest(t)
+	const dirListPrefix = "<pre>\n"
+	const dirListSuffix = "\n</pre>\n"
+	tests := []struct {
+		name, escaped string
+	}{
+		{`simple_name`, `<a href="simple_name">simple_name</a>`},
+		{`"'<>&`, `<a href="%22%27%3C%3E&">"'<>&</a>`},
+		{`?foo=bar#baz`, `<a href="%3Ffoo=bar%23baz">?foo=bar#baz</a>`},
+		{`<combo>?foo`, `<a href="%3Ccombo%3E%3Ffoo"><combo>?foo</a>`},
+	}
+
+	// We put each test file in its own directory in the fakeFS so we can look at it in isolation.
+	fs := make(fakeFS)
+	for i, test := range tests {
+		testFile := &fakeFileInfo{basename: test.name}
+		fs[fmt.Sprintf("/%d", i)] = &fakeFileInfo{
+			dir:     true,
+			modtime: time.Unix(1000000000, 0).UTC(),
+			ents:    []*fakeFileInfo{testFile},
+		}
+		fs[fmt.Sprintf("/%d/%s", i, test.name)] = testFile
+	}
+
+	ts := httptest.NewServer(FileServer(&fs))
+	defer ts.Close()
+	for i, test := range tests {
+		url := fmt.Sprintf("%s/%d", ts.URL, i)
+		res, err := Get(url)
+		if err != nil {
+			t.Fatalf("test %q: Get: %v", test.name, err)
+		}
+		b, err := ioutil.ReadAll(res.Body)
+		if err != nil {
+			t.Fatalf("test %q: read Body: %v", test.name, err)
+		}
+		s := string(b)
+		if !strings.HasPrefix(s, dirListPrefix) || !strings.HasSuffix(s, dirListSuffix) {
+			t.Errorf("test %q: listing dir, full output is %q, want prefix %q and suffix %q", test.name, s, dirListPrefix, dirListSuffix)
+		}
+		if trimmed := strings.TrimSuffix(strings.TrimPrefix(s, dirListPrefix), dirListSuffix); trimmed != test.escaped {
+			t.Errorf("test %q: listing dir, filename escaped to %q, want %q", test.name, trimmed, test.escaped)
+		}
+		res.Body.Close()
+	}
+}
+
+func mustRemoveAll(dir string) {
+	err := os.RemoveAll(dir)
+	if err != nil {
+		panic(err)
+	}
+}
+
+func TestFileServerImplicitLeadingSlash(t *testing.T) {
+	defer afterTest(t)
+	tempDir, err := ioutil.TempDir("", "")
+	if err != nil {
+		t.Fatalf("TempDir: %v", err)
+	}
+	defer mustRemoveAll(tempDir)
+	if err := ioutil.WriteFile(filepath.Join(tempDir, "foo.txt"), []byte("Hello world"), 0644); err != nil {
+		t.Fatalf("WriteFile: %v", err)
+	}
+	ts := httptest.NewServer(StripPrefix("/bar/", FileServer(Dir(tempDir))))
+	defer ts.Close()
+	get := func(suffix string) string {
+		res, err := Get(ts.URL + suffix)
+		if err != nil {
+			t.Fatalf("Get %s: %v", suffix, err)
+		}
+		b, err := ioutil.ReadAll(res.Body)
+		if err != nil {
+			t.Fatalf("ReadAll %s: %v", suffix, err)
+		}
+		res.Body.Close()
+		return string(b)
+	}
+	if s := get("/bar/"); !strings.Contains(s, ">foo.txt<") {
+		t.Logf("expected a directory listing with foo.txt, got %q", s)
+	}
+	if s := get("/bar/foo.txt"); s != "Hello world" {
+		t.Logf("expected %q, got %q", "Hello world", s)
+	}
+}
+
+func TestDirJoin(t *testing.T) {
+	if runtime.GOOS == "windows" {
+		t.Skip("skipping test on windows")
+	}
+	wfi, err := os.Stat("/etc/hosts")
+	if err != nil {
+		t.Skip("skipping test; no /etc/hosts file")
+	}
+	test := func(d Dir, name string) {
+		f, err := d.Open(name)
+		if err != nil {
+			t.Fatalf("open of %s: %v", name, err)
+		}
+		defer f.Close()
+		gfi, err := f.Stat()
+		if err != nil {
+			t.Fatalf("stat of %s: %v", name, err)
+		}
+		if !os.SameFile(gfi, wfi) {
+			t.Errorf("%s got different file", name)
+		}
+	}
+	test(Dir("/etc/"), "/hosts")
+	test(Dir("/etc/"), "hosts")
+	test(Dir("/etc/"), "../../../../hosts")
+	test(Dir("/etc"), "/hosts")
+	test(Dir("/etc"), "hosts")
+	test(Dir("/etc"), "../../../../hosts")
+
+	// Not really directories, but since we use this trick in
+	// ServeFile, test it:
+	test(Dir("/etc/hosts"), "")
+	test(Dir("/etc/hosts"), "/")
+	test(Dir("/etc/hosts"), "../")
+}
+
+func TestEmptyDirOpenCWD(t *testing.T) {
+	test := func(d Dir) {
+		name := "fs_test.go"
+		f, err := d.Open(name)
+		if err != nil {
+			t.Fatalf("open of %s: %v", name, err)
+		}
+		defer f.Close()
+	}
+	test(Dir(""))
+	test(Dir("."))
+	test(Dir("./"))
+}
+
+func TestServeFileContentType(t *testing.T) {
+	defer afterTest(t)
+	const ctype = "icecream/chocolate"
+	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+		switch r.FormValue("override") {
+		case "1":
+			w.Header().Set("Content-Type", ctype)
+		case "2":
+			// Explicitly inhibit sniffing.
+			w.Header()["Content-Type"] = []string{}
+		}
+		ServeFile(w, r, "testdata/file")
+	}))
+	defer ts.Close()
+	get := func(override string, want []string) {
+		resp, err := Get(ts.URL + "?override=" + override)
+		if err != nil {
+			t.Fatal(err)
+		}
+		if h := resp.Header["Content-Type"]; !reflect.DeepEqual(h, want) {
+			t.Errorf("Content-Type mismatch: got %v, want %v", h, want)
+		}
+		resp.Body.Close()
+	}
+	get("0", []string{"text/plain; charset=utf-8"})
+	get("1", []string{ctype})
+	get("2", nil)
+}
+
+func TestServeFileMimeType(t *testing.T) {
+	defer afterTest(t)
+	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+		ServeFile(w, r, "testdata/style.css")
+	}))
+	defer ts.Close()
+	resp, err := Get(ts.URL)
+	if err != nil {
+		t.Fatal(err)
+	}
+	resp.Body.Close()
+	want := "text/css; charset=utf-8"
+	if h := resp.Header.Get("Content-Type"); h != want {
+		t.Errorf("Content-Type mismatch: got %q, want %q", h, want)
+	}
+}
+
+func TestServeFileFromCWD(t *testing.T) {
+	defer afterTest(t)
+	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+		ServeFile(w, r, "fs_test.go")
+	}))
+	defer ts.Close()
+	r, err := Get(ts.URL)
+	if err != nil {
+		t.Fatal(err)
+	}
+	r.Body.Close()
+	if r.StatusCode != 200 {
+		t.Fatalf("expected 200 OK, got %s", r.Status)
+	}
+}
+
+func TestServeFileWithContentEncoding(t *testing.T) {
+	defer afterTest(t)
+	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+		w.Header().Set("Content-Encoding", "foo")
+		ServeFile(w, r, "testdata/file")
+	}))
+	defer ts.Close()
+	resp, err := Get(ts.URL)
+	if err != nil {
+		t.Fatal(err)
+	}
+	resp.Body.Close()
+	if g, e := resp.ContentLength, int64(-1); g != e {
+		t.Errorf("Content-Length mismatch: got %d, want %d", g, e)
+	}
+}
+
+func TestServeIndexHtml(t *testing.T) {
+	defer afterTest(t)
+	const want = "index.html says hello\n"
+	ts := httptest.NewServer(FileServer(Dir(".")))
+	defer ts.Close()
+
+	for _, path := range []string{"/testdata/", "/testdata/index.html"} {
+		res, err := Get(ts.URL + path)
+		if err != nil {
+			t.Fatal(err)
+		}
+		b, err := ioutil.ReadAll(res.Body)
+		if err != nil {
+			t.Fatal("reading Body:", err)
+		}
+		if s := string(b); s != want {
+			t.Errorf("for path %q got %q, want %q", path, s, want)
+		}
+		res.Body.Close()
+	}
+}
+
+func TestFileServerZeroByte(t *testing.T) {
+	defer afterTest(t)
+	ts := httptest.NewServer(FileServer(Dir(".")))
+	defer ts.Close()
+
+	res, err := Get(ts.URL + "/..\x00")
+	if err != nil {
+		t.Fatal(err)
+	}
+	b, err := ioutil.ReadAll(res.Body)
+	if err != nil {
+		t.Fatal("reading Body:", err)
+	}
+	if res.StatusCode == 200 {
+		t.Errorf("got status 200; want an error. Body is:\n%s", string(b))
+	}
+}
+
+type fakeFileInfo struct {
+	dir      bool
+	basename string
+	modtime  time.Time
+	ents     []*fakeFileInfo
+	contents string
+}
+
+func (f *fakeFileInfo) Name() string       { return f.basename }
+func (f *fakeFileInfo) Sys() interface{}   { return nil }
+func (f *fakeFileInfo) ModTime() time.Time { return f.modtime }
+func (f *fakeFileInfo) IsDir() bool        { return f.dir }
+func (f *fakeFileInfo) Size() int64        { return int64(len(f.contents)) }
+func (f *fakeFileInfo) Mode() os.FileMode {
+	if f.dir {
+		return 0755 | os.ModeDir
+	}
+	return 0644
+}
+
+type fakeFile struct {
+	io.ReadSeeker
+	fi     *fakeFileInfo
+	path   string // as opened
+	entpos int
+}
+
+func (f *fakeFile) Close() error               { return nil }
+func (f *fakeFile) Stat() (os.FileInfo, error) { return f.fi, nil }
+func (f *fakeFile) Readdir(count int) ([]os.FileInfo, error) {
+	if !f.fi.dir {
+		return nil, os.ErrInvalid
+	}
+	var fis []os.FileInfo
+
+	limit := f.entpos + count
+	if count <= 0 || limit > len(f.fi.ents) {
+		limit = len(f.fi.ents)
+	}
+	for ; f.entpos < limit; f.entpos++ {
+		fis = append(fis, f.fi.ents[f.entpos])
+	}
+
+	if len(fis) == 0 && count > 0 {
+		return fis, io.EOF
+	} else {
+		return fis, nil
+	}
+}
+
+type fakeFS map[string]*fakeFileInfo
+
+func (fs fakeFS) Open(name string) (File, error) {
+	name = path.Clean(name)
+	f, ok := fs[name]
+	if !ok {
+		return nil, os.ErrNotExist
+	}
+	return &fakeFile{ReadSeeker: strings.NewReader(f.contents), fi: f, path: name}, nil
+}
+
+func TestDirectoryIfNotModified(t *testing.T) {
+	defer afterTest(t)
+	const indexContents = "I am a fake index.html file"
+	fileMod := time.Unix(1000000000, 0).UTC()
+	fileModStr := fileMod.Format(TimeFormat)
+	dirMod := time.Unix(123, 0).UTC()
+	indexFile := &fakeFileInfo{
+		basename: "index.html",
+		modtime:  fileMod,
+		contents: indexContents,
+	}
+	fs := fakeFS{
+		"/": &fakeFileInfo{
+			dir:     true,
+			modtime: dirMod,
+			ents:    []*fakeFileInfo{indexFile},
+		},
+		"/index.html": indexFile,
+	}
+
+	ts := httptest.NewServer(FileServer(fs))
+	defer ts.Close()
+
+	res, err := Get(ts.URL)
+	if err != nil {
+		t.Fatal(err)
+	}
+	b, err := ioutil.ReadAll(res.Body)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if string(b) != indexContents {
+		t.Fatalf("Got body %q; want %q", b, indexContents)
+	}
+	res.Body.Close()
+
+	lastMod := res.Header.Get("Last-Modified")
+	if lastMod != fileModStr {
+		t.Fatalf("initial Last-Modified = %q; want %q", lastMod, fileModStr)
+	}
+
+	req, _ := NewRequest("GET", ts.URL, nil)
+	req.Header.Set("If-Modified-Since", lastMod)
+
+	res, err = DefaultClient.Do(req)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if res.StatusCode != 304 {
+		t.Fatalf("Code after If-Modified-Since request = %v; want 304", res.StatusCode)
+	}
+	res.Body.Close()
+
+	// Advance the index.html file's modtime, but not the directory's.
+	indexFile.modtime = indexFile.modtime.Add(1 * time.Hour)
+
+	res, err = DefaultClient.Do(req)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if res.StatusCode != 200 {
+		t.Fatalf("Code after second If-Modified-Since request = %v; want 200; res is %#v", res.StatusCode, res)
+	}
+	res.Body.Close()
+}
+
+func mustStat(t *testing.T, fileName string) os.FileInfo {
+	fi, err := os.Stat(fileName)
+	if err != nil {
+		t.Fatal(err)
+	}
+	return fi
+}
+
+func TestServeContent(t *testing.T) {
+	defer afterTest(t)
+	type serveParam struct {
+		name        string
+		modtime     time.Time
+		content     io.ReadSeeker
+		contentType string
+		etag        string
+	}
+	servec := make(chan serveParam, 1)
+	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+		p := <-servec
+		if p.etag != "" {
+			w.Header().Set("ETag", p.etag)
+		}
+		if p.contentType != "" {
+			w.Header().Set("Content-Type", p.contentType)
+		}
+		ServeContent(w, r, p.name, p.modtime, p.content)
+	}))
+	defer ts.Close()
+
+	type testCase struct {
+		// One of file or content must be set:
+		file    string
+		content io.ReadSeeker
+
+		modtime          time.Time
+		serveETag        string // optional
+		serveContentType string // optional
+		reqHeader        map[string]string
+		wantLastMod      string
+		wantContentType  string
+		wantStatus       int
+	}
+	htmlModTime := mustStat(t, "testdata/index.html").ModTime()
+	tests := map[string]testCase{
+		"no_last_modified": {
+			file:            "testdata/style.css",
+			wantContentType: "text/css; charset=utf-8",
+			wantStatus:      200,
+		},
+		"with_last_modified": {
+			file:            "testdata/index.html",
+			wantContentType: "text/html; charset=utf-8",
+			modtime:         htmlModTime,
+			wantLastMod:     htmlModTime.UTC().Format(TimeFormat),
+			wantStatus:      200,
+		},
+		"not_modified_modtime": {
+			file:    "testdata/style.css",
+			modtime: htmlModTime,
+			reqHeader: map[string]string{
+				"If-Modified-Since": htmlModTime.UTC().Format(TimeFormat),
+			},
+			wantStatus: 304,
+		},
+		"not_modified_modtime_with_contenttype": {
+			file:             "testdata/style.css",
+			serveContentType: "text/css", // explicit content type
+			modtime:          htmlModTime,
+			reqHeader: map[string]string{
+				"If-Modified-Since": htmlModTime.UTC().Format(TimeFormat),
+			},
+			wantStatus: 304,
+		},
+		"not_modified_etag": {
+			file:      "testdata/style.css",
+			serveETag: `"foo"`,
+			reqHeader: map[string]string{
+				"If-None-Match": `"foo"`,
+			},
+			wantStatus: 304,
+		},
+		"not_modified_etag_no_seek": {
+			content:   panicOnSeek{nil}, // should never be called
+			serveETag: `"foo"`,
+			reqHeader: map[string]string{
+				"If-None-Match": `"foo"`,
+			},
+			wantStatus: 304,
+		},
+		"range_good": {
+			file:      "testdata/style.css",
+			serveETag: `"A"`,
+			reqHeader: map[string]string{
+				"Range": "bytes=0-4",
+			},
+			wantStatus:      StatusPartialContent,
+			wantContentType: "text/css; charset=utf-8",
+		},
+		// An If-Range resource for entity "A", but entity "B" is now current.
+		// The Range request should be ignored.
+		"range_no_match": {
+			file:      "testdata/style.css",
+			serveETag: `"A"`,
+			reqHeader: map[string]string{
+				"Range":    "bytes=0-4",
+				"If-Range": `"B"`,
+			},
+			wantStatus:      200,
+			wantContentType: "text/css; charset=utf-8",
+		},
+		"range_with_modtime": {
+			file:    "testdata/style.css",
+			modtime: time.Date(2014, 6, 25, 17, 12, 18, 0 /* nanos */, time.UTC),
+			reqHeader: map[string]string{
+				"Range":    "bytes=0-4",
+				"If-Range": "Wed, 25 Jun 2014 17:12:18 GMT",
+			},
+			wantStatus:      StatusPartialContent,
+			wantContentType: "text/css; charset=utf-8",
+			wantLastMod:     "Wed, 25 Jun 2014 17:12:18 GMT",
+		},
+		"range_with_modtime_nanos": {
+			file:    "testdata/style.css",
+			modtime: time.Date(2014, 6, 25, 17, 12, 18, 123 /* nanos */, time.UTC),
+			reqHeader: map[string]string{
+				"Range":    "bytes=0-4",
+				"If-Range": "Wed, 25 Jun 2014 17:12:18 GMT",
+			},
+			wantStatus:      StatusPartialContent,
+			wantContentType: "text/css; charset=utf-8",
+			wantLastMod:     "Wed, 25 Jun 2014 17:12:18 GMT",
+		},
+	}
+	for testName, tt := range tests {
+		var content io.ReadSeeker
+		if tt.file != "" {
+			f, err := os.Open(tt.file)
+			if err != nil {
+				t.Fatalf("test %q: %v", testName, err)
+			}
+			defer f.Close()
+			content = f
+		} else {
+			content = tt.content
+		}
+
+		servec <- serveParam{
+			name:        filepath.Base(tt.file),
+			content:     content,
+			modtime:     tt.modtime,
+			etag:        tt.serveETag,
+			contentType: tt.serveContentType,
+		}
+		req, err := NewRequest("GET", ts.URL, nil)
+		if err != nil {
+			t.Fatal(err)
+		}
+		for k, v := range tt.reqHeader {
+			req.Header.Set(k, v)
+		}
+		res, err := DefaultClient.Do(req)
+		if err != nil {
+			t.Fatal(err)
+		}
+		io.Copy(ioutil.Discard, res.Body)
+		res.Body.Close()
+		if res.StatusCode != tt.wantStatus {
+			t.Errorf("test %q: status = %d; want %d", testName, res.StatusCode, tt.wantStatus)
+		}
+		if g, e := res.Header.Get("Content-Type"), tt.wantContentType; g != e {
+			t.Errorf("test %q: content-type = %q, want %q", testName, g, e)
+		}
+		if g, e := res.Header.Get("Last-Modified"), tt.wantLastMod; g != e {
+			t.Errorf("test %q: last-modified = %q, want %q", testName, g, e)
+		}
+	}
+}
+
+// verifies that sendfile is being used on Linux
+func TestLinuxSendfile(t *testing.T) {
+	defer afterTest(t)
+	if runtime.GOOS != "linux" {
+		t.Skip("skipping; linux-only test")
+	}
+	if _, err := exec.LookPath("strace"); err != nil {
+		t.Skip("skipping; strace not found in path")
+	}
+
+	ln, err := net.Listen("tcp", "127.0.0.1:0")
+	if err != nil {
+		t.Fatal(err)
+	}
+	lnf, err := ln.(*net.TCPListener).File()
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer ln.Close()
+
+	var buf bytes.Buffer
+	child := exec.Command("strace", "-f", "-q", "-e", "trace=sendfile,sendfile64", os.Args[0], "-test.run=TestLinuxSendfileChild")
+	child.ExtraFiles = append(child.ExtraFiles, lnf)
+	child.Env = append([]string{"GO_WANT_HELPER_PROCESS=1"}, os.Environ()...)
+	child.Stdout = &buf
+	child.Stderr = &buf
+	if err := child.Start(); err != nil {
+		t.Skipf("skipping; failed to start straced child: %v", err)
+	}
+
+	res, err := Get(fmt.Sprintf("http://%s/", ln.Addr()))
+	if err != nil {
+		t.Fatalf("http client error: %v", err)
+	}
+	_, err = io.Copy(ioutil.Discard, res.Body)
+	if err != nil {
+		t.Fatalf("client body read error: %v", err)
+	}
+	res.Body.Close()
+
+	// Force child to exit cleanly.
+	Get(fmt.Sprintf("http://%s/quit", ln.Addr()))
+	child.Wait()
+
+	rx := regexp.MustCompile(`sendfile(64)?\(\d+,\s*\d+,\s*NULL,\s*\d+\)\s*=\s*\d+\s*\n`)
+	rxResume := regexp.MustCompile(`<\.\.\. sendfile(64)? resumed> \)\s*=\s*\d+\s*\n`)
+	out := buf.String()
+	if !rx.MatchString(out) && !rxResume.MatchString(out) {
+		t.Errorf("no sendfile system call found in:\n%s", out)
+	}
+}
+
+func getBody(t *testing.T, testName string, req Request) (*Response, []byte) {
+	r, err := DefaultClient.Do(&req)
+	if err != nil {
+		t.Fatalf("%s: for URL %q, send error: %v", testName, req.URL.String(), err)
+	}
+	b, err := ioutil.ReadAll(r.Body)
+	if err != nil {
+		t.Fatalf("%s: for URL %q, reading body: %v", testName, req.URL.String(), err)
+	}
+	return r, b
+}
+
+// TestLinuxSendfileChild isn't a real test. It's used as a helper process
+// for TestLinuxSendfile.
+func TestLinuxSendfileChild(*testing.T) {
+	if os.Getenv("GO_WANT_HELPER_PROCESS") != "1" {
+		return
+	}
+	defer os.Exit(0)
+	fd3 := os.NewFile(3, "ephemeral-port-listener")
+	ln, err := net.FileListener(fd3)
+	if err != nil {
+		panic(err)
+	}
+	mux := NewServeMux()
+	mux.Handle("/", FileServer(Dir("testdata")))
+	mux.HandleFunc("/quit", func(ResponseWriter, *Request) {
+		os.Exit(0)
+	})
+	s := &Server{Handler: mux}
+	err = s.Serve(ln)
+	if err != nil {
+		panic(err)
+	}
+}
+
+func TestFileServerCleanPath(t *testing.T) {
+	tests := []struct {
+		path     string
+		wantCode int
+		wantOpen []string
+	}{
+		{"/", 200, []string{"/", "/index.html"}},
+		{"/dir", 301, []string{"/dir"}},
+		{"/dir/", 200, []string{"/dir", "/dir/index.html"}},
+	}
+	for _, tt := range tests {
+		var log []string
+		rr := httptest.NewRecorder()
+		req, _ := NewRequest("GET", "http://foo.localhost"+tt.path, nil)
+		FileServer(fileServerCleanPathDir{&log}).ServeHTTP(rr, req)
+		if !reflect.DeepEqual(log, tt.wantOpen) {
+			t.Logf("For %s: Opens = %q; want %q", tt.path, log, tt.wantOpen)
+		}
+		if rr.Code != tt.wantCode {
+			t.Logf("For %s: Response code = %d; want %d", tt.path, rr.Code, tt.wantCode)
+		}
+	}
+}
+
+type fileServerCleanPathDir struct {
+	log *[]string
+}
+
+func (d fileServerCleanPathDir) Open(path string) (File, error) {
+	*(d.log) = append(*(d.log), path)
+	if path == "/" || path == "/dir" || path == "/dir/" {
+		// Just return back something that's a directory.
+		return Dir(".").Open(".")
+	}
+	return nil, os.ErrNotExist
+}
+
+type panicOnSeek struct{ io.ReadSeeker }
diff --git a/src/pkg/net/http/header.go b/src/net/http/header.go
similarity index 100%
rename from src/pkg/net/http/header.go
rename to src/net/http/header.go
diff --git a/src/pkg/net/http/header_test.go b/src/net/http/header_test.go
similarity index 100%
rename from src/pkg/net/http/header_test.go
rename to src/net/http/header_test.go
diff --git a/src/pkg/net/http/httptest/example_test.go b/src/net/http/httptest/example_test.go
similarity index 100%
rename from src/pkg/net/http/httptest/example_test.go
rename to src/net/http/httptest/example_test.go
diff --git a/src/pkg/net/http/httptest/recorder.go b/src/net/http/httptest/recorder.go
similarity index 100%
rename from src/pkg/net/http/httptest/recorder.go
rename to src/net/http/httptest/recorder.go
diff --git a/src/pkg/net/http/httptest/recorder_test.go b/src/net/http/httptest/recorder_test.go
similarity index 100%
rename from src/pkg/net/http/httptest/recorder_test.go
rename to src/net/http/httptest/recorder_test.go
diff --git a/src/net/http/httptest/server.go b/src/net/http/httptest/server.go
new file mode 100644
index 0000000..789e7bf
--- /dev/null
+++ b/src/net/http/httptest/server.go
@@ -0,0 +1,228 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Implementation of Server
+
+package httptest
+
+import (
+	"crypto/tls"
+	"flag"
+	"fmt"
+	"net"
+	"net/http"
+	"os"
+	"sync"
+)
+
+// A Server is an HTTP server listening on a system-chosen port on the
+// local loopback interface, for use in end-to-end HTTP tests.
+type Server struct {
+	URL      string // base URL of form http://ipaddr:port with no trailing slash
+	Listener net.Listener
+
+	// TLS is the optional TLS configuration, populated with a new config
+	// after TLS is started. If set on an unstarted server before StartTLS
+	// is called, existing fields are copied into the new config.
+	TLS *tls.Config
+
+	// Config may be changed after calling NewUnstartedServer and
+	// before Start or StartTLS.
+	Config *http.Server
+
+	// wg counts the number of outstanding HTTP requests on this server.
+	// Close blocks until all requests are finished.
+	wg sync.WaitGroup
+}
+
+// historyListener keeps track of all connections that it's ever
+// accepted.
+type historyListener struct {
+	net.Listener
+	sync.Mutex // protects history
+	history    []net.Conn
+}
+
+func (hs *historyListener) Accept() (c net.Conn, err error) {
+	c, err = hs.Listener.Accept()
+	if err == nil {
+		hs.Lock()
+		hs.history = append(hs.history, c)
+		hs.Unlock()
+	}
+	return
+}
+
+func newLocalListener() net.Listener {
+	if *serve != "" {
+		l, err := net.Listen("tcp", *serve)
+		if err != nil {
+			panic(fmt.Sprintf("httptest: failed to listen on %v: %v", *serve, err))
+		}
+		return l
+	}
+	l, err := net.Listen("tcp", "127.0.0.1:0")
+	if err != nil {
+		if l, err = net.Listen("tcp6", "[::1]:0"); err != nil {
+			panic(fmt.Sprintf("httptest: failed to listen on a port: %v", err))
+		}
+	}
+	return l
+}
+
+// When debugging a particular http server-based test,
+// this flag lets you run
+//	go test -run=BrokenTest -httptest.serve=127.0.0.1:8000
+// to start the broken server so you can interact with it manually.
+var serve = flag.String("httptest.serve", "", "if non-empty, httptest.NewServer serves on this address and blocks")
+
+// NewServer starts and returns a new Server.
+// The caller should call Close when finished, to shut it down.
+func NewServer(handler http.Handler) *Server {
+	ts := NewUnstartedServer(handler)
+	ts.Start()
+	return ts
+}
+
+// NewUnstartedServer returns a new Server but doesn't start it.
+//
+// After changing its configuration, the caller should call Start or
+// StartTLS.
+//
+// The caller should call Close when finished, to shut it down.
+func NewUnstartedServer(handler http.Handler) *Server {
+	return &Server{
+		Listener: newLocalListener(),
+		Config:   &http.Server{Handler: handler},
+	}
+}
+
+// Start starts a server from NewUnstartedServer.
+func (s *Server) Start() {
+	if s.URL != "" {
+		panic("Server already started")
+	}
+	s.Listener = &historyListener{Listener: s.Listener}
+	s.URL = "http://" + s.Listener.Addr().String()
+	s.wrapHandler()
+	go s.Config.Serve(s.Listener)
+	if *serve != "" {
+		fmt.Fprintln(os.Stderr, "httptest: serving on", s.URL)
+		select {}
+	}
+}
+
+// StartTLS starts TLS on a server from NewUnstartedServer.
+func (s *Server) StartTLS() {
+	if s.URL != "" {
+		panic("Server already started")
+	}
+	cert, err := tls.X509KeyPair(localhostCert, localhostKey)
+	if err != nil {
+		panic(fmt.Sprintf("httptest: NewTLSServer: %v", err))
+	}
+
+	existingConfig := s.TLS
+	s.TLS = new(tls.Config)
+	if existingConfig != nil {
+		*s.TLS = *existingConfig
+	}
+	if s.TLS.NextProtos == nil {
+		s.TLS.NextProtos = []string{"http/1.1"}
+	}
+	if len(s.TLS.Certificates) == 0 {
+		s.TLS.Certificates = []tls.Certificate{cert}
+	}
+	tlsListener := tls.NewListener(s.Listener, s.TLS)
+
+	s.Listener = &historyListener{Listener: tlsListener}
+	s.URL = "https://" + s.Listener.Addr().String()
+	s.wrapHandler()
+	go s.Config.Serve(s.Listener)
+}
+
+func (s *Server) wrapHandler() {
+	h := s.Config.Handler
+	if h == nil {
+		h = http.DefaultServeMux
+	}
+	s.Config.Handler = &waitGroupHandler{
+		s: s,
+		h: h,
+	}
+}
+
+// NewTLSServer starts and returns a new Server using TLS.
+// The caller should call Close when finished, to shut it down.
+func NewTLSServer(handler http.Handler) *Server {
+	ts := NewUnstartedServer(handler)
+	ts.StartTLS()
+	return ts
+}
+
+// Close shuts down the server and blocks until all outstanding
+// requests on this server have completed.
+func (s *Server) Close() {
+	s.Listener.Close()
+	s.wg.Wait()
+	s.CloseClientConnections()
+	if t, ok := http.DefaultTransport.(*http.Transport); ok {
+		t.CloseIdleConnections()
+	}
+}
+
+// CloseClientConnections closes any currently open HTTP connections
+// to the test Server.
+func (s *Server) CloseClientConnections() {
+	hl, ok := s.Listener.(*historyListener)
+	if !ok {
+		return
+	}
+	hl.Lock()
+	for _, conn := range hl.history {
+		conn.Close()
+	}
+	hl.Unlock()
+}
+
+// waitGroupHandler wraps a handler, incrementing and decrementing a
+// sync.WaitGroup on each request, to enable Server.Close to block
+// until outstanding requests are finished.
+type waitGroupHandler struct {
+	s *Server
+	h http.Handler // non-nil
+}
+
+func (h *waitGroupHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+	h.s.wg.Add(1)
+	defer h.s.wg.Done() // a defer, in case ServeHTTP below panics
+	h.h.ServeHTTP(w, r)
+}
+
+// localhostCert is a PEM-encoded TLS cert with SAN IPs
+// "127.0.0.1" and "[::1]", expiring at the last second of 2049 (the end
+// of ASN.1 time).
+// generated from src/crypto/tls:
+// go run generate_cert.go  --rsa-bits 512 --host 127.0.0.1,::1,example.com --ca --start-date "Jan 1 00:00:00 1970" --duration=1000000h
+var localhostCert = []byte(`-----BEGIN CERTIFICATE-----
+MIIBdzCCASOgAwIBAgIBADALBgkqhkiG9w0BAQUwEjEQMA4GA1UEChMHQWNtZSBD
+bzAeFw03MDAxMDEwMDAwMDBaFw00OTEyMzEyMzU5NTlaMBIxEDAOBgNVBAoTB0Fj
+bWUgQ28wWjALBgkqhkiG9w0BAQEDSwAwSAJBAN55NcYKZeInyTuhcCwFMhDHCmwa
+IUSdtXdcbItRB/yfXGBhiex00IaLXQnSU+QZPRZWYqeTEbFSgihqi1PUDy8CAwEA
+AaNoMGYwDgYDVR0PAQH/BAQDAgCkMBMGA1UdJQQMMAoGCCsGAQUFBwMBMA8GA1Ud
+EwEB/wQFMAMBAf8wLgYDVR0RBCcwJYILZXhhbXBsZS5jb22HBH8AAAGHEAAAAAAA
+AAAAAAAAAAAAAAEwCwYJKoZIhvcNAQEFA0EAAoQn/ytgqpiLcZu9XKbCJsJcvkgk
+Se6AbGXgSlq+ZCEVo0qIwSgeBqmsJxUu7NCSOwVJLYNEBO2DtIxoYVk+MA==
+-----END CERTIFICATE-----`)
+
+// localhostKey is the private key for localhostCert.
+var localhostKey = []byte(`-----BEGIN RSA PRIVATE KEY-----
+MIIBPAIBAAJBAN55NcYKZeInyTuhcCwFMhDHCmwaIUSdtXdcbItRB/yfXGBhiex0
+0IaLXQnSU+QZPRZWYqeTEbFSgihqi1PUDy8CAwEAAQJBAQdUx66rfh8sYsgfdcvV
+NoafYpnEcB5s4m/vSVe6SU7dCK6eYec9f9wpT353ljhDUHq3EbmE4foNzJngh35d
+AekCIQDhRQG5Li0Wj8TM4obOnnXUXf1jRv0UkzE9AHWLG5q3AwIhAPzSjpYUDjVW
+MCUXgckTpKCuGwbJk7424Nb8bLzf3kllAiA5mUBgjfr/WtFSJdWcPQ4Zt9KTMNKD
+EUO0ukpTwEIl6wIhAMbGqZK3zAAFdq8DD2jPx+UJXnh0rnOkZBzDtJ6/iN69AiEA
+1Aq8MJgTaYsDQWyU/hDq5YkDJc9e9DSCvUIzqxQWMQE=
+-----END RSA PRIVATE KEY-----`)
diff --git a/src/net/http/httptest/server_test.go b/src/net/http/httptest/server_test.go
new file mode 100644
index 0000000..500a9f0
--- /dev/null
+++ b/src/net/http/httptest/server_test.go
@@ -0,0 +1,29 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package httptest
+
+import (
+	"io/ioutil"
+	"net/http"
+	"testing"
+)
+
+func TestServer(t *testing.T) {
+	ts := NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+		w.Write([]byte("hello"))
+	}))
+	defer ts.Close()
+	res, err := http.Get(ts.URL)
+	if err != nil {
+		t.Fatal(err)
+	}
+	got, err := ioutil.ReadAll(res.Body)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if string(got) != "hello" {
+		t.Errorf("got %q, want hello", string(got))
+	}
+}
diff --git a/src/net/http/httputil/dump.go b/src/net/http/httputil/dump.go
new file mode 100644
index 0000000..ac8f103
--- /dev/null
+++ b/src/net/http/httputil/dump.go
@@ -0,0 +1,284 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package httputil
+
+import (
+	"bufio"
+	"bytes"
+	"errors"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"net"
+	"net/http"
+	"net/url"
+	"strings"
+	"time"
+)
+
+// One of the copies, say from b to r2, could be avoided by using a more
+// elaborate trick where the other copy is made during Request/Response.Write.
+// This would complicate things too much, given that these functions are for
+// debugging only.
+func drainBody(b io.ReadCloser) (r1, r2 io.ReadCloser, err error) {
+	var buf bytes.Buffer
+	if _, err = buf.ReadFrom(b); err != nil {
+		return nil, nil, err
+	}
+	if err = b.Close(); err != nil {
+		return nil, nil, err
+	}
+	return ioutil.NopCloser(&buf), ioutil.NopCloser(bytes.NewReader(buf.Bytes())), nil
+}
+
+// dumpConn is a net.Conn which writes to Writer and reads from Reader
+type dumpConn struct {
+	io.Writer
+	io.Reader
+}
+
+func (c *dumpConn) Close() error                       { return nil }
+func (c *dumpConn) LocalAddr() net.Addr                { return nil }
+func (c *dumpConn) RemoteAddr() net.Addr               { return nil }
+func (c *dumpConn) SetDeadline(t time.Time) error      { return nil }
+func (c *dumpConn) SetReadDeadline(t time.Time) error  { return nil }
+func (c *dumpConn) SetWriteDeadline(t time.Time) error { return nil }
+
+type neverEnding byte
+
+func (b neverEnding) Read(p []byte) (n int, err error) {
+	for i := range p {
+		p[i] = byte(b)
+	}
+	return len(p), nil
+}
+
+// DumpRequestOut is like DumpRequest but includes
+// headers that the standard http.Transport adds,
+// such as User-Agent.
+func DumpRequestOut(req *http.Request, body bool) ([]byte, error) {
+	save := req.Body
+	dummyBody := false
+	if !body || req.Body == nil {
+		req.Body = nil
+		if req.ContentLength != 0 {
+			req.Body = ioutil.NopCloser(io.LimitReader(neverEnding('x'), req.ContentLength))
+			dummyBody = true
+		}
+	} else {
+		var err error
+		save, req.Body, err = drainBody(req.Body)
+		if err != nil {
+			return nil, err
+		}
+	}
+
+	// Since we're using the actual Transport code to write the request,
+	// switch to http so the Transport doesn't try to do an SSL
+	// negotiation with our dumpConn and its bytes.Buffer & pipe.
+	// The wire format for https and http are the same, anyway.
+	reqSend := req
+	if req.URL.Scheme == "https" {
+		reqSend = new(http.Request)
+		*reqSend = *req
+		reqSend.URL = new(url.URL)
+		*reqSend.URL = *req.URL
+		reqSend.URL.Scheme = "http"
+	}
+
+	// Use the actual Transport code to record what we would send
+	// on the wire, but not using TCP.  Use a Transport with a
+	// custom dialer that returns a fake net.Conn that waits
+	// for the full input (and recording it), and then responds
+	// with a dummy response.
+	var buf bytes.Buffer // records the output
+	pr, pw := io.Pipe()
+	defer pr.Close()
+	defer pw.Close()
+	dr := &delegateReader{c: make(chan io.Reader)}
+	// Wait for the request before replying with a dummy response:
+	go func() {
+		req, err := http.ReadRequest(bufio.NewReader(pr))
+		if err == nil {
+			// Ensure all the body is read; otherwise
+			// we'll get a partial dump.
+			io.Copy(ioutil.Discard, req.Body)
+			req.Body.Close()
+		}
+		dr.c <- strings.NewReader("HTTP/1.1 204 No Content\r\n\r\n")
+	}()
+
+	t := &http.Transport{
+		DisableKeepAlives: true,
+		Dial: func(net, addr string) (net.Conn, error) {
+			return &dumpConn{io.MultiWriter(&buf, pw), dr}, nil
+		},
+	}
+
+	_, err := t.RoundTrip(reqSend)
+
+	req.Body = save
+	if err != nil {
+		return nil, err
+	}
+	dump := buf.Bytes()
+
+	// If we used a dummy body above, remove it now.
+	// TODO: if the req.ContentLength is large, we allocate memory
+	// unnecessarily just to slice it off here.  But this is just
+	// a debug function, so this is acceptable for now. We could
+	// discard the body earlier if this matters.
+	if dummyBody {
+		if i := bytes.Index(dump, []byte("\r\n\r\n")); i >= 0 {
+			dump = dump[:i+4]
+		}
+	}
+	return dump, nil
+}
+
+// delegateReader is a reader that delegates to another reader,
+// once it arrives on a channel.
+type delegateReader struct {
+	c chan io.Reader
+	r io.Reader // nil until received from c
+}
+
+func (r *delegateReader) Read(p []byte) (int, error) {
+	if r.r == nil {
+		r.r = <-r.c
+	}
+	return r.r.Read(p)
+}
+
+// Return value if nonempty, def otherwise.
+func valueOrDefault(value, def string) string {
+	if value != "" {
+		return value
+	}
+	return def
+}
+
+var reqWriteExcludeHeaderDump = map[string]bool{
+	"Host":              true, // not in Header map anyway
+	"Content-Length":    true,
+	"Transfer-Encoding": true,
+	"Trailer":           true,
+}
+
+// dumpAsReceived writes req to w in the form as it was received, or
+// at least as accurately as possible from the information retained in
+// the request.
+func dumpAsReceived(req *http.Request, w io.Writer) error {
+	return nil
+}
+
+// DumpRequest returns the as-received wire representation of req,
+// optionally including the request body, for debugging.
+// DumpRequest is semantically a no-op, but in order to
+// dump the body, it reads the body data into memory and
+// changes req.Body to refer to the in-memory copy.
+// The documentation for http.Request.Write details which fields
+// of req are used.
+func DumpRequest(req *http.Request, body bool) (dump []byte, err error) {
+	save := req.Body
+	if !body || req.Body == nil {
+		req.Body = nil
+	} else {
+		save, req.Body, err = drainBody(req.Body)
+		if err != nil {
+			return
+		}
+	}
+
+	var b bytes.Buffer
+
+	fmt.Fprintf(&b, "%s %s HTTP/%d.%d\r\n", valueOrDefault(req.Method, "GET"),
+		req.URL.RequestURI(), req.ProtoMajor, req.ProtoMinor)
+
+	host := req.Host
+	if host == "" && req.URL != nil {
+		host = req.URL.Host
+	}
+	if host != "" {
+		fmt.Fprintf(&b, "Host: %s\r\n", host)
+	}
+
+	chunked := len(req.TransferEncoding) > 0 && req.TransferEncoding[0] == "chunked"
+	if len(req.TransferEncoding) > 0 {
+		fmt.Fprintf(&b, "Transfer-Encoding: %s\r\n", strings.Join(req.TransferEncoding, ","))
+	}
+	if req.Close {
+		fmt.Fprintf(&b, "Connection: close\r\n")
+	}
+
+	err = req.Header.WriteSubset(&b, reqWriteExcludeHeaderDump)
+	if err != nil {
+		return
+	}
+
+	io.WriteString(&b, "\r\n")
+
+	if req.Body != nil {
+		var dest io.Writer = &b
+		if chunked {
+			dest = NewChunkedWriter(dest)
+		}
+		_, err = io.Copy(dest, req.Body)
+		if chunked {
+			dest.(io.Closer).Close()
+			io.WriteString(&b, "\r\n")
+		}
+	}
+
+	req.Body = save
+	if err != nil {
+		return
+	}
+	dump = b.Bytes()
+	return
+}
+
+// errNoBody is a sentinel error value used by failureToReadBody so we can detect
+// that the lack of body was intentional.
+var errNoBody = errors.New("sentinel error value")
+
+// failureToReadBody is a io.ReadCloser that just returns errNoBody on
+// Read.  It's swapped in when we don't actually want to consume the
+// body, but need a non-nil one, and want to distinguish the error
+// from reading the dummy body.
+type failureToReadBody struct{}
+
+func (failureToReadBody) Read([]byte) (int, error) { return 0, errNoBody }
+func (failureToReadBody) Close() error             { return nil }
+
+var emptyBody = ioutil.NopCloser(strings.NewReader(""))
+
+// DumpResponse is like DumpRequest but dumps a response.
+func DumpResponse(resp *http.Response, body bool) (dump []byte, err error) {
+	var b bytes.Buffer
+	save := resp.Body
+	savecl := resp.ContentLength
+
+	if !body {
+		resp.Body = failureToReadBody{}
+	} else if resp.Body == nil {
+		resp.Body = emptyBody
+	} else {
+		save, resp.Body, err = drainBody(resp.Body)
+		if err != nil {
+			return
+		}
+	}
+	err = resp.Write(&b)
+	if err == errNoBody {
+		err = nil
+	}
+	resp.Body = save
+	resp.ContentLength = savecl
+	if err != nil {
+		return nil, err
+	}
+	return b.Bytes(), nil
+}
diff --git a/src/net/http/httputil/dump_test.go b/src/net/http/httputil/dump_test.go
new file mode 100644
index 0000000..024ee5a
--- /dev/null
+++ b/src/net/http/httputil/dump_test.go
@@ -0,0 +1,291 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package httputil
+
+import (
+	"bytes"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"net/http"
+	"net/url"
+	"runtime"
+	"strings"
+	"testing"
+)
+
+type dumpTest struct {
+	Req  http.Request
+	Body interface{} // optional []byte or func() io.ReadCloser to populate Req.Body
+
+	WantDump    string
+	WantDumpOut string
+	NoBody      bool // if true, set DumpRequest{,Out} body to false
+}
+
+var dumpTests = []dumpTest{
+
+	// HTTP/1.1 => chunked coding; body; empty trailer
+	{
+		Req: http.Request{
+			Method: "GET",
+			URL: &url.URL{
+				Scheme: "http",
+				Host:   "www.google.com",
+				Path:   "/search",
+			},
+			ProtoMajor:       1,
+			ProtoMinor:       1,
+			TransferEncoding: []string{"chunked"},
+		},
+
+		Body: []byte("abcdef"),
+
+		WantDump: "GET /search HTTP/1.1\r\n" +
+			"Host: www.google.com\r\n" +
+			"Transfer-Encoding: chunked\r\n\r\n" +
+			chunk("abcdef") + chunk(""),
+	},
+
+	// Verify that DumpRequest preserves the HTTP version number, doesn't add a Host,
+	// and doesn't add a User-Agent.
+	{
+		Req: http.Request{
+			Method:     "GET",
+			URL:        mustParseURL("/foo"),
+			ProtoMajor: 1,
+			ProtoMinor: 0,
+			Header: http.Header{
+				"X-Foo": []string{"X-Bar"},
+			},
+		},
+
+		WantDump: "GET /foo HTTP/1.0\r\n" +
+			"X-Foo: X-Bar\r\n\r\n",
+	},
+
+	{
+		Req: *mustNewRequest("GET", "http://example.com/foo", nil),
+
+		WantDumpOut: "GET /foo HTTP/1.1\r\n" +
+			"Host: example.com\r\n" +
+			"User-Agent: Go 1.1 package http\r\n" +
+			"Accept-Encoding: gzip\r\n\r\n",
+	},
+
+	// Test that an https URL doesn't try to do an SSL negotiation
+	// with a bytes.Buffer and hang with all goroutines not
+	// runnable.
+	{
+		Req: *mustNewRequest("GET", "https://example.com/foo", nil),
+
+		WantDumpOut: "GET /foo HTTP/1.1\r\n" +
+			"Host: example.com\r\n" +
+			"User-Agent: Go 1.1 package http\r\n" +
+			"Accept-Encoding: gzip\r\n\r\n",
+	},
+
+	// Request with Body, but Dump requested without it.
+	{
+		Req: http.Request{
+			Method: "POST",
+			URL: &url.URL{
+				Scheme: "http",
+				Host:   "post.tld",
+				Path:   "/",
+			},
+			ContentLength: 6,
+			ProtoMajor:    1,
+			ProtoMinor:    1,
+		},
+
+		Body: []byte("abcdef"),
+
+		WantDumpOut: "POST / HTTP/1.1\r\n" +
+			"Host: post.tld\r\n" +
+			"User-Agent: Go 1.1 package http\r\n" +
+			"Content-Length: 6\r\n" +
+			"Accept-Encoding: gzip\r\n\r\n",
+
+		NoBody: true,
+	},
+
+	// Request with Body > 8196 (default buffer size)
+	{
+		Req: http.Request{
+			Method: "POST",
+			URL: &url.URL{
+				Scheme: "http",
+				Host:   "post.tld",
+				Path:   "/",
+			},
+			ContentLength: 8193,
+			ProtoMajor:    1,
+			ProtoMinor:    1,
+		},
+
+		Body: bytes.Repeat([]byte("a"), 8193),
+
+		WantDumpOut: "POST / HTTP/1.1\r\n" +
+			"Host: post.tld\r\n" +
+			"User-Agent: Go 1.1 package http\r\n" +
+			"Content-Length: 8193\r\n" +
+			"Accept-Encoding: gzip\r\n\r\n" +
+			strings.Repeat("a", 8193),
+	},
+}
+
+func TestDumpRequest(t *testing.T) {
+	numg0 := runtime.NumGoroutine()
+	for i, tt := range dumpTests {
+		setBody := func() {
+			if tt.Body == nil {
+				return
+			}
+			switch b := tt.Body.(type) {
+			case []byte:
+				tt.Req.Body = ioutil.NopCloser(bytes.NewReader(b))
+			case func() io.ReadCloser:
+				tt.Req.Body = b()
+			default:
+				t.Fatalf("Test %d: unsupported Body of %T", i, tt.Body)
+			}
+		}
+		setBody()
+		if tt.Req.Header == nil {
+			tt.Req.Header = make(http.Header)
+		}
+
+		if tt.WantDump != "" {
+			setBody()
+			dump, err := DumpRequest(&tt.Req, !tt.NoBody)
+			if err != nil {
+				t.Errorf("DumpRequest #%d: %s", i, err)
+				continue
+			}
+			if string(dump) != tt.WantDump {
+				t.Errorf("DumpRequest %d, expecting:\n%s\nGot:\n%s\n", i, tt.WantDump, string(dump))
+				continue
+			}
+		}
+
+		if tt.WantDumpOut != "" {
+			setBody()
+			dump, err := DumpRequestOut(&tt.Req, !tt.NoBody)
+			if err != nil {
+				t.Errorf("DumpRequestOut #%d: %s", i, err)
+				continue
+			}
+			if string(dump) != tt.WantDumpOut {
+				t.Errorf("DumpRequestOut %d, expecting:\n%s\nGot:\n%s\n", i, tt.WantDumpOut, string(dump))
+				continue
+			}
+		}
+	}
+	if dg := runtime.NumGoroutine() - numg0; dg > 4 {
+		buf := make([]byte, 4096)
+		buf = buf[:runtime.Stack(buf, true)]
+		t.Errorf("Unexpectedly large number of new goroutines: %d new: %s", dg, buf)
+	}
+}
+
+func chunk(s string) string {
+	return fmt.Sprintf("%x\r\n%s\r\n", len(s), s)
+}
+
+func mustParseURL(s string) *url.URL {
+	u, err := url.Parse(s)
+	if err != nil {
+		panic(fmt.Sprintf("Error parsing URL %q: %v", s, err))
+	}
+	return u
+}
+
+func mustNewRequest(method, url string, body io.Reader) *http.Request {
+	req, err := http.NewRequest(method, url, body)
+	if err != nil {
+		panic(fmt.Sprintf("NewRequest(%q, %q, %p) err = %v", method, url, body, err))
+	}
+	return req
+}
+
+var dumpResTests = []struct {
+	res  *http.Response
+	body bool
+	want string
+}{
+	{
+		res: &http.Response{
+			Status:        "200 OK",
+			StatusCode:    200,
+			Proto:         "HTTP/1.1",
+			ProtoMajor:    1,
+			ProtoMinor:    1,
+			ContentLength: 50,
+			Header: http.Header{
+				"Foo": []string{"Bar"},
+			},
+			Body: ioutil.NopCloser(strings.NewReader("foo")), // shouldn't be used
+		},
+		body: false, // to verify we see 50, not empty or 3.
+		want: `HTTP/1.1 200 OK
+Content-Length: 50
+Foo: Bar`,
+	},
+
+	{
+		res: &http.Response{
+			Status:        "200 OK",
+			StatusCode:    200,
+			Proto:         "HTTP/1.1",
+			ProtoMajor:    1,
+			ProtoMinor:    1,
+			ContentLength: 3,
+			Body:          ioutil.NopCloser(strings.NewReader("foo")),
+		},
+		body: true,
+		want: `HTTP/1.1 200 OK
+Content-Length: 3
+
+foo`,
+	},
+
+	{
+		res: &http.Response{
+			Status:           "200 OK",
+			StatusCode:       200,
+			Proto:            "HTTP/1.1",
+			ProtoMajor:       1,
+			ProtoMinor:       1,
+			ContentLength:    -1,
+			Body:             ioutil.NopCloser(strings.NewReader("foo")),
+			TransferEncoding: []string{"chunked"},
+		},
+		body: true,
+		want: `HTTP/1.1 200 OK
+Transfer-Encoding: chunked
+
+3
+foo
+0`,
+	},
+}
+
+func TestDumpResponse(t *testing.T) {
+	for i, tt := range dumpResTests {
+		gotb, err := DumpResponse(tt.res, tt.body)
+		if err != nil {
+			t.Errorf("%d. DumpResponse = %v", i, err)
+			continue
+		}
+		got := string(gotb)
+		got = strings.TrimSpace(got)
+		got = strings.Replace(got, "\r", "", -1)
+
+		if got != tt.want {
+			t.Errorf("%d.\nDumpResponse got:\n%s\n\nWant:\n%s\n", i, got, tt.want)
+		}
+	}
+}
diff --git a/src/net/http/httputil/httputil.go b/src/net/http/httputil/httputil.go
new file mode 100644
index 0000000..2e523e9
--- /dev/null
+++ b/src/net/http/httputil/httputil.go
@@ -0,0 +1,39 @@
+// 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 httputil provides HTTP utility functions, complementing the
+// more common ones in the net/http package.
+package httputil
+
+import (
+	"io"
+	"net/http/internal"
+)
+
+// NewChunkedReader returns a new chunkedReader that translates the data read from r
+// out of HTTP "chunked" format before returning it.
+// The chunkedReader returns io.EOF when the final 0-length chunk is read.
+//
+// NewChunkedReader is not needed by normal applications. The http package
+// automatically decodes chunking when reading response bodies.
+func NewChunkedReader(r io.Reader) io.Reader {
+	return internal.NewChunkedReader(r)
+}
+
+// NewChunkedWriter returns a new chunkedWriter that translates writes into HTTP
+// "chunked" format before writing them to w. Closing the returned chunkedWriter
+// sends the final 0-length chunk that marks the end of the stream.
+//
+// NewChunkedWriter is not needed by normal applications. The http
+// package adds chunking automatically if handlers don't set a
+// Content-Length header. Using NewChunkedWriter inside a handler
+// would result in double chunking or chunking with a Content-Length
+// length, both of which are wrong.
+func NewChunkedWriter(w io.Writer) io.WriteCloser {
+	return internal.NewChunkedWriter(w)
+}
+
+// ErrLineTooLong is returned when reading malformed chunked data
+// with lines that are too long.
+var ErrLineTooLong = internal.ErrLineTooLong
diff --git a/src/pkg/net/http/httputil/persist.go b/src/net/http/httputil/persist.go
similarity index 100%
rename from src/pkg/net/http/httputil/persist.go
rename to src/net/http/httputil/persist.go
diff --git a/src/net/http/httputil/reverseproxy.go b/src/net/http/httputil/reverseproxy.go
new file mode 100644
index 0000000..ab46370
--- /dev/null
+++ b/src/net/http/httputil/reverseproxy.go
@@ -0,0 +1,225 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// HTTP reverse proxy handler
+
+package httputil
+
+import (
+	"io"
+	"log"
+	"net"
+	"net/http"
+	"net/url"
+	"strings"
+	"sync"
+	"time"
+)
+
+// onExitFlushLoop is a callback set by tests to detect the state of the
+// flushLoop() goroutine.
+var onExitFlushLoop func()
+
+// ReverseProxy is an HTTP Handler that takes an incoming request and
+// sends it to another server, proxying the response back to the
+// client.
+type ReverseProxy struct {
+	// Director must be a function which modifies
+	// the request into a new request to be sent
+	// using Transport. Its response is then copied
+	// back to the original client unmodified.
+	Director func(*http.Request)
+
+	// The transport used to perform proxy requests.
+	// If nil, http.DefaultTransport is used.
+	Transport http.RoundTripper
+
+	// FlushInterval specifies the flush interval
+	// to flush to the client while copying the
+	// response body.
+	// If zero, no periodic flushing is done.
+	FlushInterval time.Duration
+
+	// ErrorLog specifies an optional logger for errors
+	// that occur when attempting to proxy the request.
+	// If nil, logging goes to os.Stderr via the log package's
+	// standard logger.
+	ErrorLog *log.Logger
+}
+
+func singleJoiningSlash(a, b string) string {
+	aslash := strings.HasSuffix(a, "/")
+	bslash := strings.HasPrefix(b, "/")
+	switch {
+	case aslash && bslash:
+		return a + b[1:]
+	case !aslash && !bslash:
+		return a + "/" + b
+	}
+	return a + b
+}
+
+// NewSingleHostReverseProxy returns a new ReverseProxy that rewrites
+// URLs to the scheme, host, and base path provided in target. If the
+// target's path is "/base" and the incoming request was for "/dir",
+// the target request will be for /base/dir.
+func NewSingleHostReverseProxy(target *url.URL) *ReverseProxy {
+	targetQuery := target.RawQuery
+	director := func(req *http.Request) {
+		req.URL.Scheme = target.Scheme
+		req.URL.Host = target.Host
+		req.URL.Path = singleJoiningSlash(target.Path, req.URL.Path)
+		if targetQuery == "" || req.URL.RawQuery == "" {
+			req.URL.RawQuery = targetQuery + req.URL.RawQuery
+		} else {
+			req.URL.RawQuery = targetQuery + "&" + req.URL.RawQuery
+		}
+	}
+	return &ReverseProxy{Director: director}
+}
+
+func copyHeader(dst, src http.Header) {
+	for k, vv := range src {
+		for _, v := range vv {
+			dst.Add(k, v)
+		}
+	}
+}
+
+// Hop-by-hop headers. These are removed when sent to the backend.
+// http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html
+var hopHeaders = []string{
+	"Connection",
+	"Keep-Alive",
+	"Proxy-Authenticate",
+	"Proxy-Authorization",
+	"Te", // canonicalized version of "TE"
+	"Trailers",
+	"Transfer-Encoding",
+	"Upgrade",
+}
+
+func (p *ReverseProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
+	transport := p.Transport
+	if transport == nil {
+		transport = http.DefaultTransport
+	}
+
+	outreq := new(http.Request)
+	*outreq = *req // includes shallow copies of maps, but okay
+
+	p.Director(outreq)
+	outreq.Proto = "HTTP/1.1"
+	outreq.ProtoMajor = 1
+	outreq.ProtoMinor = 1
+	outreq.Close = false
+
+	// Remove hop-by-hop headers to the backend.  Especially
+	// important is "Connection" because we want a persistent
+	// connection, regardless of what the client sent to us.  This
+	// is modifying the same underlying map from req (shallow
+	// copied above) so we only copy it if necessary.
+	copiedHeaders := false
+	for _, h := range hopHeaders {
+		if outreq.Header.Get(h) != "" {
+			if !copiedHeaders {
+				outreq.Header = make(http.Header)
+				copyHeader(outreq.Header, req.Header)
+				copiedHeaders = true
+			}
+			outreq.Header.Del(h)
+		}
+	}
+
+	if clientIP, _, err := net.SplitHostPort(req.RemoteAddr); err == nil {
+		// If we aren't the first proxy retain prior
+		// X-Forwarded-For information as a comma+space
+		// separated list and fold multiple headers into one.
+		if prior, ok := outreq.Header["X-Forwarded-For"]; ok {
+			clientIP = strings.Join(prior, ", ") + ", " + clientIP
+		}
+		outreq.Header.Set("X-Forwarded-For", clientIP)
+	}
+
+	res, err := transport.RoundTrip(outreq)
+	if err != nil {
+		p.logf("http: proxy error: %v", err)
+		rw.WriteHeader(http.StatusInternalServerError)
+		return
+	}
+	defer res.Body.Close()
+
+	for _, h := range hopHeaders {
+		res.Header.Del(h)
+	}
+
+	copyHeader(rw.Header(), res.Header)
+
+	rw.WriteHeader(res.StatusCode)
+	p.copyResponse(rw, res.Body)
+}
+
+func (p *ReverseProxy) copyResponse(dst io.Writer, src io.Reader) {
+	if p.FlushInterval != 0 {
+		if wf, ok := dst.(writeFlusher); ok {
+			mlw := &maxLatencyWriter{
+				dst:     wf,
+				latency: p.FlushInterval,
+				done:    make(chan bool),
+			}
+			go mlw.flushLoop()
+			defer mlw.stop()
+			dst = mlw
+		}
+	}
+
+	io.Copy(dst, src)
+}
+
+func (p *ReverseProxy) logf(format string, args ...interface{}) {
+	if p.ErrorLog != nil {
+		p.ErrorLog.Printf(format, args...)
+	} else {
+		log.Printf(format, args...)
+	}
+}
+
+type writeFlusher interface {
+	io.Writer
+	http.Flusher
+}
+
+type maxLatencyWriter struct {
+	dst     writeFlusher
+	latency time.Duration
+
+	lk   sync.Mutex // protects Write + Flush
+	done chan bool
+}
+
+func (m *maxLatencyWriter) Write(p []byte) (int, error) {
+	m.lk.Lock()
+	defer m.lk.Unlock()
+	return m.dst.Write(p)
+}
+
+func (m *maxLatencyWriter) flushLoop() {
+	t := time.NewTicker(m.latency)
+	defer t.Stop()
+	for {
+		select {
+		case <-m.done:
+			if onExitFlushLoop != nil {
+				onExitFlushLoop()
+			}
+			return
+		case <-t.C:
+			m.lk.Lock()
+			m.dst.Flush()
+			m.lk.Unlock()
+		}
+	}
+}
+
+func (m *maxLatencyWriter) stop() { m.done <- true }
diff --git a/src/pkg/net/http/httputil/reverseproxy_test.go b/src/net/http/httputil/reverseproxy_test.go
similarity index 100%
rename from src/pkg/net/http/httputil/reverseproxy_test.go
rename to src/net/http/httputil/reverseproxy_test.go
diff --git a/src/net/http/internal/chunked.go b/src/net/http/internal/chunked.go
new file mode 100644
index 0000000..9294deb
--- /dev/null
+++ b/src/net/http/internal/chunked.go
@@ -0,0 +1,202 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// The wire protocol for HTTP's "chunked" Transfer-Encoding.
+
+// Package internal contains HTTP internals shared by net/http and
+// net/http/httputil.
+package internal
+
+import (
+	"bufio"
+	"bytes"
+	"errors"
+	"fmt"
+	"io"
+)
+
+const maxLineLength = 4096 // assumed <= bufio.defaultBufSize
+
+var ErrLineTooLong = errors.New("header line too long")
+
+// NewChunkedReader returns a new chunkedReader that translates the data read from r
+// out of HTTP "chunked" format before returning it.
+// The chunkedReader returns io.EOF when the final 0-length chunk is read.
+//
+// NewChunkedReader is not needed by normal applications. The http package
+// automatically decodes chunking when reading response bodies.
+func NewChunkedReader(r io.Reader) io.Reader {
+	br, ok := r.(*bufio.Reader)
+	if !ok {
+		br = bufio.NewReader(r)
+	}
+	return &chunkedReader{r: br}
+}
+
+type chunkedReader struct {
+	r   *bufio.Reader
+	n   uint64 // unread bytes in chunk
+	err error
+	buf [2]byte
+}
+
+func (cr *chunkedReader) beginChunk() {
+	// chunk-size CRLF
+	var line []byte
+	line, cr.err = readLine(cr.r)
+	if cr.err != nil {
+		return
+	}
+	cr.n, cr.err = parseHexUint(line)
+	if cr.err != nil {
+		return
+	}
+	if cr.n == 0 {
+		cr.err = io.EOF
+	}
+}
+
+func (cr *chunkedReader) chunkHeaderAvailable() bool {
+	n := cr.r.Buffered()
+	if n > 0 {
+		peek, _ := cr.r.Peek(n)
+		return bytes.IndexByte(peek, '\n') >= 0
+	}
+	return false
+}
+
+func (cr *chunkedReader) Read(b []uint8) (n int, err error) {
+	for cr.err == nil {
+		if cr.n == 0 {
+			if n > 0 && !cr.chunkHeaderAvailable() {
+				// We've read enough. Don't potentially block
+				// reading a new chunk header.
+				break
+			}
+			cr.beginChunk()
+			continue
+		}
+		if len(b) == 0 {
+			break
+		}
+		rbuf := b
+		if uint64(len(rbuf)) > cr.n {
+			rbuf = rbuf[:cr.n]
+		}
+		var n0 int
+		n0, cr.err = cr.r.Read(rbuf)
+		n += n0
+		b = b[n0:]
+		cr.n -= uint64(n0)
+		// If we're at the end of a chunk, read the next two
+		// bytes to verify they are "\r\n".
+		if cr.n == 0 && cr.err == nil {
+			if _, cr.err = io.ReadFull(cr.r, cr.buf[:2]); cr.err == nil {
+				if cr.buf[0] != '\r' || cr.buf[1] != '\n' {
+					cr.err = errors.New("malformed chunked encoding")
+				}
+			}
+		}
+	}
+	return n, cr.err
+}
+
+// Read a line of bytes (up to \n) from b.
+// Give up if the line exceeds maxLineLength.
+// The returned bytes are a pointer into storage in
+// the bufio, so they are only valid until the next bufio read.
+func readLine(b *bufio.Reader) (p []byte, err error) {
+	if p, err = b.ReadSlice('\n'); err != nil {
+		// We always know when EOF is coming.
+		// If the caller asked for a line, there should be a line.
+		if err == io.EOF {
+			err = io.ErrUnexpectedEOF
+		} else if err == bufio.ErrBufferFull {
+			err = ErrLineTooLong
+		}
+		return nil, err
+	}
+	if len(p) >= maxLineLength {
+		return nil, ErrLineTooLong
+	}
+	return trimTrailingWhitespace(p), nil
+}
+
+func trimTrailingWhitespace(b []byte) []byte {
+	for len(b) > 0 && isASCIISpace(b[len(b)-1]) {
+		b = b[:len(b)-1]
+	}
+	return b
+}
+
+func isASCIISpace(b byte) bool {
+	return b == ' ' || b == '\t' || b == '\n' || b == '\r'
+}
+
+// NewChunkedWriter returns a new chunkedWriter that translates writes into HTTP
+// "chunked" format before writing them to w. Closing the returned chunkedWriter
+// sends the final 0-length chunk that marks the end of the stream.
+//
+// NewChunkedWriter is not needed by normal applications. The http
+// package adds chunking automatically if handlers don't set a
+// Content-Length header. Using newChunkedWriter inside a handler
+// would result in double chunking or chunking with a Content-Length
+// length, both of which are wrong.
+func NewChunkedWriter(w io.Writer) io.WriteCloser {
+	return &chunkedWriter{w}
+}
+
+// Writing to chunkedWriter translates to writing in HTTP chunked Transfer
+// Encoding wire format to the underlying Wire chunkedWriter.
+type chunkedWriter struct {
+	Wire io.Writer
+}
+
+// Write the contents of data as one chunk to Wire.
+// NOTE: Note that the corresponding chunk-writing procedure in Conn.Write has
+// a bug since it does not check for success of io.WriteString
+func (cw *chunkedWriter) Write(data []byte) (n int, err error) {
+
+	// Don't send 0-length data. It looks like EOF for chunked encoding.
+	if len(data) == 0 {
+		return 0, nil
+	}
+
+	if _, err = fmt.Fprintf(cw.Wire, "%x\r\n", len(data)); err != nil {
+		return 0, err
+	}
+	if n, err = cw.Wire.Write(data); err != nil {
+		return
+	}
+	if n != len(data) {
+		err = io.ErrShortWrite
+		return
+	}
+	_, err = io.WriteString(cw.Wire, "\r\n")
+
+	return
+}
+
+func (cw *chunkedWriter) Close() error {
+	_, err := io.WriteString(cw.Wire, "0\r\n")
+	return err
+}
+
+func parseHexUint(v []byte) (n uint64, err error) {
+	for _, b := range v {
+		n <<= 4
+		switch {
+		case '0' <= b && b <= '9':
+			b = b - '0'
+		case 'a' <= b && b <= 'f':
+			b = b - 'a' + 10
+		case 'A' <= b && b <= 'F':
+			b = b - 'A' + 10
+		default:
+			return 0, errors.New("invalid byte in chunk length")
+		}
+		n |= uint64(b)
+	}
+	return
+}
diff --git a/src/net/http/internal/chunked_test.go b/src/net/http/internal/chunked_test.go
new file mode 100644
index 0000000..ebc626e
--- /dev/null
+++ b/src/net/http/internal/chunked_test.go
@@ -0,0 +1,156 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package internal
+
+import (
+	"bufio"
+	"bytes"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"strings"
+	"testing"
+)
+
+func TestChunk(t *testing.T) {
+	var b bytes.Buffer
+
+	w := NewChunkedWriter(&b)
+	const chunk1 = "hello, "
+	const chunk2 = "world! 0123456789abcdef"
+	w.Write([]byte(chunk1))
+	w.Write([]byte(chunk2))
+	w.Close()
+
+	if g, e := b.String(), "7\r\nhello, \r\n17\r\nworld! 0123456789abcdef\r\n0\r\n"; g != e {
+		t.Fatalf("chunk writer wrote %q; want %q", g, e)
+	}
+
+	r := NewChunkedReader(&b)
+	data, err := ioutil.ReadAll(r)
+	if err != nil {
+		t.Logf(`data: "%s"`, data)
+		t.Fatalf("ReadAll from reader: %v", err)
+	}
+	if g, e := string(data), chunk1+chunk2; g != e {
+		t.Errorf("chunk reader read %q; want %q", g, e)
+	}
+}
+
+func TestChunkReadMultiple(t *testing.T) {
+	// Bunch of small chunks, all read together.
+	{
+		var b bytes.Buffer
+		w := NewChunkedWriter(&b)
+		w.Write([]byte("foo"))
+		w.Write([]byte("bar"))
+		w.Close()
+
+		r := NewChunkedReader(&b)
+		buf := make([]byte, 10)
+		n, err := r.Read(buf)
+		if n != 6 || err != io.EOF {
+			t.Errorf("Read = %d, %v; want 6, EOF", n, err)
+		}
+		buf = buf[:n]
+		if string(buf) != "foobar" {
+			t.Errorf("Read = %q; want %q", buf, "foobar")
+		}
+	}
+
+	// One big chunk followed by a little chunk, but the small bufio.Reader size
+	// should prevent the second chunk header from being read.
+	{
+		var b bytes.Buffer
+		w := NewChunkedWriter(&b)
+		// fillBufChunk is 11 bytes + 3 bytes header + 2 bytes footer = 16 bytes,
+		// the same as the bufio ReaderSize below (the minimum), so even
+		// though we're going to try to Read with a buffer larger enough to also
+		// receive "foo", the second chunk header won't be read yet.
+		const fillBufChunk = "0123456789a"
+		const shortChunk = "foo"
+		w.Write([]byte(fillBufChunk))
+		w.Write([]byte(shortChunk))
+		w.Close()
+
+		r := NewChunkedReader(bufio.NewReaderSize(&b, 16))
+		buf := make([]byte, len(fillBufChunk)+len(shortChunk))
+		n, err := r.Read(buf)
+		if n != len(fillBufChunk) || err != nil {
+			t.Errorf("Read = %d, %v; want %d, nil", n, err, len(fillBufChunk))
+		}
+		buf = buf[:n]
+		if string(buf) != fillBufChunk {
+			t.Errorf("Read = %q; want %q", buf, fillBufChunk)
+		}
+
+		n, err = r.Read(buf)
+		if n != len(shortChunk) || err != io.EOF {
+			t.Errorf("Read = %d, %v; want %d, EOF", n, err, len(shortChunk))
+		}
+	}
+
+	// And test that we see an EOF chunk, even though our buffer is already full:
+	{
+		r := NewChunkedReader(bufio.NewReader(strings.NewReader("3\r\nfoo\r\n0\r\n")))
+		buf := make([]byte, 3)
+		n, err := r.Read(buf)
+		if n != 3 || err != io.EOF {
+			t.Errorf("Read = %d, %v; want 3, EOF", n, err)
+		}
+		if string(buf) != "foo" {
+			t.Errorf("buf = %q; want foo", buf)
+		}
+	}
+}
+
+func TestChunkReaderAllocs(t *testing.T) {
+	if testing.Short() {
+		t.Skip("skipping in short mode")
+	}
+	var buf bytes.Buffer
+	w := NewChunkedWriter(&buf)
+	a, b, c := []byte("aaaaaa"), []byte("bbbbbbbbbbbb"), []byte("cccccccccccccccccccccccc")
+	w.Write(a)
+	w.Write(b)
+	w.Write(c)
+	w.Close()
+
+	readBuf := make([]byte, len(a)+len(b)+len(c)+1)
+	byter := bytes.NewReader(buf.Bytes())
+	bufr := bufio.NewReader(byter)
+	mallocs := testing.AllocsPerRun(100, func() {
+		byter.Seek(0, 0)
+		bufr.Reset(byter)
+		r := NewChunkedReader(bufr)
+		n, err := io.ReadFull(r, readBuf)
+		if n != len(readBuf)-1 {
+			t.Fatalf("read %d bytes; want %d", n, len(readBuf)-1)
+		}
+		if err != io.ErrUnexpectedEOF {
+			t.Fatalf("read error = %v; want ErrUnexpectedEOF", err)
+		}
+	})
+	if mallocs > 1.5 {
+		t.Errorf("mallocs = %v; want 1", mallocs)
+	}
+}
+
+func TestParseHexUint(t *testing.T) {
+	for i := uint64(0); i <= 1234; i++ {
+		line := []byte(fmt.Sprintf("%x", i))
+		got, err := parseHexUint(line)
+		if err != nil {
+			t.Fatalf("on %d: %v", i, err)
+		}
+		if got != i {
+			t.Errorf("for input %q = %d; want %d", line, got, i)
+		}
+	}
+	_, err := parseHexUint([]byte("bogus"))
+	if err == nil {
+		t.Error("expected error on bogus input")
+	}
+}
diff --git a/src/pkg/net/http/jar.go b/src/net/http/jar.go
similarity index 100%
rename from src/pkg/net/http/jar.go
rename to src/net/http/jar.go
diff --git a/src/pkg/net/http/lex.go b/src/net/http/lex.go
similarity index 100%
rename from src/pkg/net/http/lex.go
rename to src/net/http/lex.go
diff --git a/src/pkg/net/http/lex_test.go b/src/net/http/lex_test.go
similarity index 100%
rename from src/pkg/net/http/lex_test.go
rename to src/net/http/lex_test.go
diff --git a/src/net/http/main_test.go b/src/net/http/main_test.go
new file mode 100644
index 0000000..b8c71fd
--- /dev/null
+++ b/src/net/http/main_test.go
@@ -0,0 +1,109 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package http_test
+
+import (
+	"fmt"
+	"net/http"
+	"os"
+	"runtime"
+	"sort"
+	"strings"
+	"testing"
+	"time"
+)
+
+func TestMain(m *testing.M) {
+	v := m.Run()
+	if v == 0 && goroutineLeaked() {
+		os.Exit(1)
+	}
+	os.Exit(v)
+}
+
+func interestingGoroutines() (gs []string) {
+	buf := make([]byte, 2<<20)
+	buf = buf[:runtime.Stack(buf, true)]
+	for _, g := range strings.Split(string(buf), "\n\n") {
+		sl := strings.SplitN(g, "\n", 2)
+		if len(sl) != 2 {
+			continue
+		}
+		stack := strings.TrimSpace(sl[1])
+		if stack == "" ||
+			strings.Contains(stack, "created by net.startServer") ||
+			strings.Contains(stack, "created by testing.RunTests") ||
+			strings.Contains(stack, "closeWriteAndWait") ||
+			strings.Contains(stack, "testing.Main(") ||
+			// These only show up with GOTRACEBACK=2; Issue 5005 (comment 28)
+			strings.Contains(stack, "runtime.goexit") ||
+			strings.Contains(stack, "created by runtime.gc") ||
+			strings.Contains(stack, "net/http_test.interestingGoroutines") ||
+			strings.Contains(stack, "runtime.MHeap_Scavenger") {
+			continue
+		}
+		gs = append(gs, stack)
+	}
+	sort.Strings(gs)
+	return
+}
+
+// Verify the other tests didn't leave any goroutines running.
+func goroutineLeaked() bool {
+	if testing.Short() {
+		// not counting goroutines for leakage in -short mode
+		return false
+	}
+	gs := interestingGoroutines()
+
+	n := 0
+	stackCount := make(map[string]int)
+	for _, g := range gs {
+		stackCount[g]++
+		n++
+	}
+
+	if n == 0 {
+		return false
+	}
+	fmt.Fprintf(os.Stderr, "Too many goroutines running after net/http test(s).\n")
+	for stack, count := range stackCount {
+		fmt.Fprintf(os.Stderr, "%d instances of:\n%s\n", count, stack)
+	}
+	return true
+}
+
+func afterTest(t *testing.T) {
+	http.DefaultTransport.(*http.Transport).CloseIdleConnections()
+	if testing.Short() {
+		return
+	}
+	var bad string
+	badSubstring := map[string]string{
+		").readLoop(":                                  "a Transport",
+		").writeLoop(":                                 "a Transport",
+		"created by net/http/httptest.(*Server).Start": "an httptest.Server",
+		"timeoutHandler":                               "a TimeoutHandler",
+		"net.(*netFD).connect(":                        "a timing out dial",
+		").noteClientGone(":                            "a closenotifier sender",
+	}
+	var stacks string
+	for i := 0; i < 4; i++ {
+		bad = ""
+		stacks = strings.Join(interestingGoroutines(), "\n\n")
+		for substr, what := range badSubstring {
+			if strings.Contains(stacks, substr) {
+				bad = what
+			}
+		}
+		if bad == "" {
+			return
+		}
+		// Bad stuff found, but goroutines might just still be
+		// shutting down, so give it some time.
+		time.Sleep(250 * time.Millisecond)
+	}
+	t.Errorf("Test appears to have leaked %s:\n%s", bad, stacks)
+}
diff --git a/src/pkg/net/http/npn_test.go b/src/net/http/npn_test.go
similarity index 100%
rename from src/pkg/net/http/npn_test.go
rename to src/net/http/npn_test.go
diff --git a/src/net/http/pprof/pprof.go b/src/net/http/pprof/pprof.go
new file mode 100644
index 0000000..a23f1bc
--- /dev/null
+++ b/src/net/http/pprof/pprof.go
@@ -0,0 +1,209 @@
+// Copyright 2010 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package pprof serves via its HTTP server runtime profiling data
+// in the format expected by the pprof visualization tool.
+// For more information about pprof, see
+// http://code.google.com/p/google-perftools/.
+//
+// The package is typically only imported for the side effect of
+// registering its HTTP handlers.
+// The handled paths all begin with /debug/pprof/.
+//
+// To use pprof, link this package into your program:
+//	import _ "net/http/pprof"
+//
+// If your application is not already running an http server, you
+// need to start one.  Add "net/http" and "log" to your imports and
+// the following code to your main function:
+//
+// 	go func() {
+// 		log.Println(http.ListenAndServe("localhost:6060", nil))
+// 	}()
+//
+// Then use the pprof tool to look at the heap profile:
+//
+//	go tool pprof http://localhost:6060/debug/pprof/heap
+//
+// Or to look at a 30-second CPU profile:
+//
+//	go tool pprof http://localhost:6060/debug/pprof/profile
+//
+// Or to look at the goroutine blocking profile:
+//
+//	go tool pprof http://localhost:6060/debug/pprof/block
+//
+// To view all available profiles, open http://localhost:6060/debug/pprof/
+// in your browser.
+//
+// For a study of the facility in action, visit
+//
+//	http://blog.golang.org/2011/06/profiling-go-programs.html
+//
+package pprof
+
+import (
+	"bufio"
+	"bytes"
+	"fmt"
+	"html/template"
+	"io"
+	"log"
+	"net/http"
+	"os"
+	"runtime"
+	"runtime/pprof"
+	"strconv"
+	"strings"
+	"time"
+)
+
+func init() {
+	http.Handle("/debug/pprof/", http.HandlerFunc(Index))
+	http.Handle("/debug/pprof/cmdline", http.HandlerFunc(Cmdline))
+	http.Handle("/debug/pprof/profile", http.HandlerFunc(Profile))
+	http.Handle("/debug/pprof/symbol", http.HandlerFunc(Symbol))
+}
+
+// Cmdline responds with the running program's
+// command line, with arguments separated by NUL bytes.
+// The package initialization registers it as /debug/pprof/cmdline.
+func Cmdline(w http.ResponseWriter, r *http.Request) {
+	w.Header().Set("Content-Type", "text/plain; charset=utf-8")
+	fmt.Fprintf(w, strings.Join(os.Args, "\x00"))
+}
+
+// Profile responds with the pprof-formatted cpu profile.
+// The package initialization registers it as /debug/pprof/profile.
+func Profile(w http.ResponseWriter, r *http.Request) {
+	sec, _ := strconv.ParseInt(r.FormValue("seconds"), 10, 64)
+	if sec == 0 {
+		sec = 30
+	}
+
+	// Set Content Type assuming StartCPUProfile will work,
+	// because if it does it starts writing.
+	w.Header().Set("Content-Type", "application/octet-stream")
+	if err := pprof.StartCPUProfile(w); err != nil {
+		// StartCPUProfile failed, so no writes yet.
+		// Can change header back to text content
+		// and send error code.
+		w.Header().Set("Content-Type", "text/plain; charset=utf-8")
+		w.WriteHeader(http.StatusInternalServerError)
+		fmt.Fprintf(w, "Could not enable CPU profiling: %s\n", err)
+		return
+	}
+	time.Sleep(time.Duration(sec) * time.Second)
+	pprof.StopCPUProfile()
+}
+
+// Symbol looks up the program counters listed in the request,
+// responding with a table mapping program counters to function names.
+// The package initialization registers it as /debug/pprof/symbol.
+func Symbol(w http.ResponseWriter, r *http.Request) {
+	w.Header().Set("Content-Type", "text/plain; charset=utf-8")
+
+	// We have to read the whole POST body before
+	// writing any output.  Buffer the output here.
+	var buf bytes.Buffer
+
+	// We don't know how many symbols we have, but we
+	// do have symbol information.  Pprof only cares whether
+	// this number is 0 (no symbols available) or > 0.
+	fmt.Fprintf(&buf, "num_symbols: 1\n")
+
+	var b *bufio.Reader
+	if r.Method == "POST" {
+		b = bufio.NewReader(r.Body)
+	} else {
+		b = bufio.NewReader(strings.NewReader(r.URL.RawQuery))
+	}
+
+	for {
+		word, err := b.ReadSlice('+')
+		if err == nil {
+			word = word[0 : len(word)-1] // trim +
+		}
+		pc, _ := strconv.ParseUint(string(word), 0, 64)
+		if pc != 0 {
+			f := runtime.FuncForPC(uintptr(pc))
+			if f != nil {
+				fmt.Fprintf(&buf, "%#x %s\n", pc, f.Name())
+			}
+		}
+
+		// Wait until here to check for err; the last
+		// symbol will have an err because it doesn't end in +.
+		if err != nil {
+			if err != io.EOF {
+				fmt.Fprintf(&buf, "reading request: %v\n", err)
+			}
+			break
+		}
+	}
+
+	w.Write(buf.Bytes())
+}
+
+// Handler returns an HTTP handler that serves the named profile.
+func Handler(name string) http.Handler {
+	return handler(name)
+}
+
+type handler string
+
+func (name handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+	w.Header().Set("Content-Type", "text/plain; charset=utf-8")
+	debug, _ := strconv.Atoi(r.FormValue("debug"))
+	p := pprof.Lookup(string(name))
+	if p == nil {
+		w.WriteHeader(404)
+		fmt.Fprintf(w, "Unknown profile: %s\n", name)
+		return
+	}
+	gc, _ := strconv.Atoi(r.FormValue("gc"))
+	if name == "heap" && gc > 0 {
+		runtime.GC()
+	}
+	p.WriteTo(w, debug)
+	return
+}
+
+// Index responds with the pprof-formatted profile named by the request.
+// For example, "/debug/pprof/heap" serves the "heap" profile.
+// Index responds to a request for "/debug/pprof/" with an HTML page
+// listing the available profiles.
+func Index(w http.ResponseWriter, r *http.Request) {
+	if strings.HasPrefix(r.URL.Path, "/debug/pprof/") {
+		name := strings.TrimPrefix(r.URL.Path, "/debug/pprof/")
+		if name != "" {
+			handler(name).ServeHTTP(w, r)
+			return
+		}
+	}
+
+	profiles := pprof.Profiles()
+	if err := indexTmpl.Execute(w, profiles); err != nil {
+		log.Print(err)
+	}
+}
+
+var indexTmpl = template.Must(template.New("index").Parse(`<html>
+<head>
+<title>/debug/pprof/</title>
+</head>
+/debug/pprof/<br>
+<br>
+<body>
+profiles:<br>
+<table>
+{{range .}}
+<tr><td align=right>{{.Count}}<td><a href="/debug/pprof/{{.Name}}?debug=1">{{.Name}}</a>
+{{end}}
+</table>
+<br>
+<a href="/debug/pprof/goroutine?debug=2">full goroutine stack dump</a><br>
+</body>
+</html>
+`))
diff --git a/src/pkg/net/http/proxy_test.go b/src/net/http/proxy_test.go
similarity index 100%
rename from src/pkg/net/http/proxy_test.go
rename to src/net/http/proxy_test.go
diff --git a/src/pkg/net/http/race.go b/src/net/http/race.go
similarity index 100%
rename from src/pkg/net/http/race.go
rename to src/net/http/race.go
diff --git a/src/pkg/net/http/range_test.go b/src/net/http/range_test.go
similarity index 100%
rename from src/pkg/net/http/range_test.go
rename to src/net/http/range_test.go
diff --git a/src/net/http/readrequest_test.go b/src/net/http/readrequest_test.go
new file mode 100644
index 0000000..e930d99
--- /dev/null
+++ b/src/net/http/readrequest_test.go
@@ -0,0 +1,358 @@
+// Copyright 2010 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package http
+
+import (
+	"bufio"
+	"bytes"
+	"fmt"
+	"io"
+	"net/url"
+	"reflect"
+	"strings"
+	"testing"
+)
+
+type reqTest struct {
+	Raw     string
+	Req     *Request
+	Body    string
+	Trailer Header
+	Error   string
+}
+
+var noError = ""
+var noBody = ""
+var noTrailer Header = nil
+
+var reqTests = []reqTest{
+	// Baseline test; All Request fields included for template use
+	{
+		"GET http://www.techcrunch.com/ HTTP/1.1\r\n" +
+			"Host: www.techcrunch.com\r\n" +
+			"User-Agent: Fake\r\n" +
+			"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n" +
+			"Accept-Language: en-us,en;q=0.5\r\n" +
+			"Accept-Encoding: gzip,deflate\r\n" +
+			"Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n" +
+			"Keep-Alive: 300\r\n" +
+			"Content-Length: 7\r\n" +
+			"Proxy-Connection: keep-alive\r\n\r\n" +
+			"abcdef\n???",
+
+		&Request{
+			Method: "GET",
+			URL: &url.URL{
+				Scheme: "http",
+				Host:   "www.techcrunch.com",
+				Path:   "/",
+			},
+			Proto:      "HTTP/1.1",
+			ProtoMajor: 1,
+			ProtoMinor: 1,
+			Header: Header{
+				"Accept":           {"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"},
+				"Accept-Language":  {"en-us,en;q=0.5"},
+				"Accept-Encoding":  {"gzip,deflate"},
+				"Accept-Charset":   {"ISO-8859-1,utf-8;q=0.7,*;q=0.7"},
+				"Keep-Alive":       {"300"},
+				"Proxy-Connection": {"keep-alive"},
+				"Content-Length":   {"7"},
+				"User-Agent":       {"Fake"},
+			},
+			Close:         false,
+			ContentLength: 7,
+			Host:          "www.techcrunch.com",
+			RequestURI:    "http://www.techcrunch.com/",
+		},
+
+		"abcdef\n",
+
+		noTrailer,
+		noError,
+	},
+
+	// GET request with no body (the normal case)
+	{
+		"GET / HTTP/1.1\r\n" +
+			"Host: foo.com\r\n\r\n",
+
+		&Request{
+			Method: "GET",
+			URL: &url.URL{
+				Path: "/",
+			},
+			Proto:         "HTTP/1.1",
+			ProtoMajor:    1,
+			ProtoMinor:    1,
+			Header:        Header{},
+			Close:         false,
+			ContentLength: 0,
+			Host:          "foo.com",
+			RequestURI:    "/",
+		},
+
+		noBody,
+		noTrailer,
+		noError,
+	},
+
+	// Tests that we don't parse a path that looks like a
+	// scheme-relative URI as a scheme-relative URI.
+	{
+		"GET //user at host/is/actually/a/path/ HTTP/1.1\r\n" +
+			"Host: test\r\n\r\n",
+
+		&Request{
+			Method: "GET",
+			URL: &url.URL{
+				Path: "//user at host/is/actually/a/path/",
+			},
+			Proto:         "HTTP/1.1",
+			ProtoMajor:    1,
+			ProtoMinor:    1,
+			Header:        Header{},
+			Close:         false,
+			ContentLength: 0,
+			Host:          "test",
+			RequestURI:    "//user at host/is/actually/a/path/",
+		},
+
+		noBody,
+		noTrailer,
+		noError,
+	},
+
+	// Tests a bogus abs_path on the Request-Line (RFC 2616 section 5.1.2)
+	{
+		"GET ../../../../etc/passwd HTTP/1.1\r\n" +
+			"Host: test\r\n\r\n",
+		nil,
+		noBody,
+		noTrailer,
+		"parse ../../../../etc/passwd: invalid URI for request",
+	},
+
+	// Tests missing URL:
+	{
+		"GET  HTTP/1.1\r\n" +
+			"Host: test\r\n\r\n",
+		nil,
+		noBody,
+		noTrailer,
+		"parse : empty url",
+	},
+
+	// Tests chunked body with trailer:
+	{
+		"POST / HTTP/1.1\r\n" +
+			"Host: foo.com\r\n" +
+			"Transfer-Encoding: chunked\r\n\r\n" +
+			"3\r\nfoo\r\n" +
+			"3\r\nbar\r\n" +
+			"0\r\n" +
+			"Trailer-Key: Trailer-Value\r\n" +
+			"\r\n",
+		&Request{
+			Method: "POST",
+			URL: &url.URL{
+				Path: "/",
+			},
+			TransferEncoding: []string{"chunked"},
+			Proto:            "HTTP/1.1",
+			ProtoMajor:       1,
+			ProtoMinor:       1,
+			Header:           Header{},
+			ContentLength:    -1,
+			Host:             "foo.com",
+			RequestURI:       "/",
+		},
+
+		"foobar",
+		Header{
+			"Trailer-Key": {"Trailer-Value"},
+		},
+		noError,
+	},
+
+	// CONNECT request with domain name:
+	{
+		"CONNECT www.google.com:443 HTTP/1.1\r\n\r\n",
+
+		&Request{
+			Method: "CONNECT",
+			URL: &url.URL{
+				Host: "www.google.com:443",
+			},
+			Proto:         "HTTP/1.1",
+			ProtoMajor:    1,
+			ProtoMinor:    1,
+			Header:        Header{},
+			Close:         false,
+			ContentLength: 0,
+			Host:          "www.google.com:443",
+			RequestURI:    "www.google.com:443",
+		},
+
+		noBody,
+		noTrailer,
+		noError,
+	},
+
+	// CONNECT request with IP address:
+	{
+		"CONNECT 127.0.0.1:6060 HTTP/1.1\r\n\r\n",
+
+		&Request{
+			Method: "CONNECT",
+			URL: &url.URL{
+				Host: "127.0.0.1:6060",
+			},
+			Proto:         "HTTP/1.1",
+			ProtoMajor:    1,
+			ProtoMinor:    1,
+			Header:        Header{},
+			Close:         false,
+			ContentLength: 0,
+			Host:          "127.0.0.1:6060",
+			RequestURI:    "127.0.0.1:6060",
+		},
+
+		noBody,
+		noTrailer,
+		noError,
+	},
+
+	// CONNECT request for RPC:
+	{
+		"CONNECT /_goRPC_ HTTP/1.1\r\n\r\n",
+
+		&Request{
+			Method: "CONNECT",
+			URL: &url.URL{
+				Path: "/_goRPC_",
+			},
+			Proto:         "HTTP/1.1",
+			ProtoMajor:    1,
+			ProtoMinor:    1,
+			Header:        Header{},
+			Close:         false,
+			ContentLength: 0,
+			Host:          "",
+			RequestURI:    "/_goRPC_",
+		},
+
+		noBody,
+		noTrailer,
+		noError,
+	},
+
+	// SSDP Notify request. golang.org/issue/3692
+	{
+		"NOTIFY * HTTP/1.1\r\nServer: foo\r\n\r\n",
+		&Request{
+			Method: "NOTIFY",
+			URL: &url.URL{
+				Path: "*",
+			},
+			Proto:      "HTTP/1.1",
+			ProtoMajor: 1,
+			ProtoMinor: 1,
+			Header: Header{
+				"Server": []string{"foo"},
+			},
+			Close:         false,
+			ContentLength: 0,
+			RequestURI:    "*",
+		},
+
+		noBody,
+		noTrailer,
+		noError,
+	},
+
+	// OPTIONS request. Similar to golang.org/issue/3692
+	{
+		"OPTIONS * HTTP/1.1\r\nServer: foo\r\n\r\n",
+		&Request{
+			Method: "OPTIONS",
+			URL: &url.URL{
+				Path: "*",
+			},
+			Proto:      "HTTP/1.1",
+			ProtoMajor: 1,
+			ProtoMinor: 1,
+			Header: Header{
+				"Server": []string{"foo"},
+			},
+			Close:         false,
+			ContentLength: 0,
+			RequestURI:    "*",
+		},
+
+		noBody,
+		noTrailer,
+		noError,
+	},
+
+	// Connection: close. golang.org/issue/8261
+	{
+		"GET / HTTP/1.1\r\nHost: issue8261.com\r\nConnection: close\r\n\r\n",
+		&Request{
+			Method: "GET",
+			URL: &url.URL{
+				Path: "/",
+			},
+			Header: Header{
+				// This wasn't removed from Go 1.0 to
+				// Go 1.3, so locking it in that we
+				// keep this:
+				"Connection": []string{"close"},
+			},
+			Host:       "issue8261.com",
+			Proto:      "HTTP/1.1",
+			ProtoMajor: 1,
+			ProtoMinor: 1,
+			Close:      true,
+			RequestURI: "/",
+		},
+
+		noBody,
+		noTrailer,
+		noError,
+	},
+}
+
+func TestReadRequest(t *testing.T) {
+	for i := range reqTests {
+		tt := &reqTests[i]
+		req, err := ReadRequest(bufio.NewReader(strings.NewReader(tt.Raw)))
+		if err != nil {
+			if err.Error() != tt.Error {
+				t.Errorf("#%d: error %q, want error %q", i, err.Error(), tt.Error)
+			}
+			continue
+		}
+		rbody := req.Body
+		req.Body = nil
+		testName := fmt.Sprintf("Test %d (%q)", i, tt.Raw)
+		diff(t, testName, req, tt.Req)
+		var bout bytes.Buffer
+		if rbody != nil {
+			_, err := io.Copy(&bout, rbody)
+			if err != nil {
+				t.Fatalf("%s: copying body: %v", testName, err)
+			}
+			rbody.Close()
+		}
+		body := bout.String()
+		if body != tt.Body {
+			t.Errorf("%s: Body = %q want %q", testName, body, tt.Body)
+		}
+		if !reflect.DeepEqual(tt.Trailer, req.Trailer) {
+			t.Errorf("%s: Trailers differ.\n got: %v\nwant: %v", testName, req.Trailer, tt.Trailer)
+		}
+	}
+}
diff --git a/src/net/http/request.go b/src/net/http/request.go
new file mode 100644
index 0000000..487eebc
--- /dev/null
+++ b/src/net/http/request.go
@@ -0,0 +1,921 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// HTTP Request reading and parsing.
+
+package http
+
+import (
+	"bufio"
+	"bytes"
+	"crypto/tls"
+	"encoding/base64"
+	"errors"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"mime"
+	"mime/multipart"
+	"net/textproto"
+	"net/url"
+	"strconv"
+	"strings"
+	"sync"
+)
+
+const (
+	maxValueLength   = 4096
+	maxHeaderLines   = 1024
+	chunkSize        = 4 << 10  // 4 KB chunks
+	defaultMaxMemory = 32 << 20 // 32 MB
+)
+
+// ErrMissingFile is returned by FormFile when the provided file field name
+// is either not present in the request or not a file field.
+var ErrMissingFile = errors.New("http: no such file")
+
+// HTTP request parsing errors.
+type ProtocolError struct {
+	ErrorString string
+}
+
+func (err *ProtocolError) Error() string { return err.ErrorString }
+
+var (
+	ErrHeaderTooLong        = &ProtocolError{"header too long"}
+	ErrShortBody            = &ProtocolError{"entity body too short"}
+	ErrNotSupported         = &ProtocolError{"feature not supported"}
+	ErrUnexpectedTrailer    = &ProtocolError{"trailer header without chunked transfer encoding"}
+	ErrMissingContentLength = &ProtocolError{"missing ContentLength in HEAD response"}
+	ErrNotMultipart         = &ProtocolError{"request Content-Type isn't multipart/form-data"}
+	ErrMissingBoundary      = &ProtocolError{"no multipart boundary param in Content-Type"}
+)
+
+type badStringError struct {
+	what string
+	str  string
+}
+
+func (e *badStringError) Error() string { return fmt.Sprintf("%s %q", e.what, e.str) }
+
+// Headers that Request.Write handles itself and should be skipped.
+var reqWriteExcludeHeader = map[string]bool{
+	"Host":              true, // not in Header map anyway
+	"User-Agent":        true,
+	"Content-Length":    true,
+	"Transfer-Encoding": true,
+	"Trailer":           true,
+}
+
+// A Request represents an HTTP request received by a server
+// or to be sent by a client.
+//
+// The field semantics differ slightly between client and server
+// usage. In addition to the notes on the fields below, see the
+// documentation for Request.Write and RoundTripper.
+type Request struct {
+	// Method specifies the HTTP method (GET, POST, PUT, etc.).
+	// For client requests an empty string means GET.
+	Method string
+
+	// URL specifies either the URI being requested (for server
+	// requests) or the URL to access (for client requests).
+	//
+	// For server requests the URL is parsed from the URI
+	// supplied on the Request-Line as stored in RequestURI.  For
+	// most requests, fields other than Path and RawQuery will be
+	// empty. (See RFC 2616, Section 5.1.2)
+	//
+	// For client requests, the URL's Host specifies the server to
+	// connect to, while the Request's Host field optionally
+	// specifies the Host header value to send in the HTTP
+	// request.
+	URL *url.URL
+
+	// The protocol version for incoming requests.
+	// Client requests always use HTTP/1.1.
+	Proto      string // "HTTP/1.0"
+	ProtoMajor int    // 1
+	ProtoMinor int    // 0
+
+	// A header maps request lines to their values.
+	// If the header says
+	//
+	//	accept-encoding: gzip, deflate
+	//	Accept-Language: en-us
+	//	Connection: keep-alive
+	//
+	// then
+	//
+	//	Header = map[string][]string{
+	//		"Accept-Encoding": {"gzip, deflate"},
+	//		"Accept-Language": {"en-us"},
+	//		"Connection": {"keep-alive"},
+	//	}
+	//
+	// HTTP defines that header names are case-insensitive.
+	// The request parser implements this by canonicalizing the
+	// name, making the first character and any characters
+	// following a hyphen uppercase and the rest lowercase.
+	//
+	// For client requests certain headers are automatically
+	// added and may override values in Header.
+	//
+	// See the documentation for the Request.Write method.
+	Header Header
+
+	// Body is the request's body.
+	//
+	// For client requests a nil body means the request has no
+	// body, such as a GET request. The HTTP Client's Transport
+	// is responsible for calling the Close method.
+	//
+	// For server requests the Request Body is always non-nil
+	// but will return EOF immediately when no body is present.
+	// The Server will close the request body. The ServeHTTP
+	// Handler does not need to.
+	Body io.ReadCloser
+
+	// ContentLength records the length of the associated content.
+	// The value -1 indicates that the length is unknown.
+	// Values >= 0 indicate that the given number of bytes may
+	// be read from Body.
+	// For client requests, a value of 0 means unknown if Body is not nil.
+	ContentLength int64
+
+	// TransferEncoding lists the transfer encodings from outermost to
+	// innermost. An empty list denotes the "identity" encoding.
+	// TransferEncoding can usually be ignored; chunked encoding is
+	// automatically added and removed as necessary when sending and
+	// receiving requests.
+	TransferEncoding []string
+
+	// Close indicates whether to close the connection after
+	// replying to this request (for servers) or after sending
+	// the request (for clients).
+	Close bool
+
+	// For server requests Host specifies the host on which the
+	// URL is sought. Per RFC 2616, this is either the value of
+	// the "Host" header or the host name given in the URL itself.
+	// It may be of the form "host:port".
+	//
+	// For client requests Host optionally overrides the Host
+	// header to send. If empty, the Request.Write method uses
+	// the value of URL.Host.
+	Host string
+
+	// Form contains the parsed form data, including both the URL
+	// field's query parameters and the POST or PUT form data.
+	// This field is only available after ParseForm is called.
+	// The HTTP client ignores Form and uses Body instead.
+	Form url.Values
+
+	// PostForm contains the parsed form data from POST or PUT
+	// body parameters.
+	// This field is only available after ParseForm is called.
+	// The HTTP client ignores PostForm and uses Body instead.
+	PostForm url.Values
+
+	// MultipartForm is the parsed multipart form, including file uploads.
+	// This field is only available after ParseMultipartForm is called.
+	// The HTTP client ignores MultipartForm and uses Body instead.
+	MultipartForm *multipart.Form
+
+	// Trailer specifies additional headers that are sent after the request
+	// body.
+	//
+	// For server requests the Trailer map initially contains only the
+	// trailer keys, with nil values. (The client declares which trailers it
+	// will later send.)  While the handler is reading from Body, it must
+	// not reference Trailer. After reading from Body returns EOF, Trailer
+	// can be read again and will contain non-nil values, if they were sent
+	// by the client.
+	//
+	// For client requests Trailer must be initialized to a map containing
+	// the trailer keys to later send. The values may be nil or their final
+	// values. The ContentLength must be 0 or -1, to send a chunked request.
+	// After the HTTP request is sent the map values can be updated while
+	// the request body is read. Once the body returns EOF, the caller must
+	// not mutate Trailer.
+	//
+	// Few HTTP clients, servers, or proxies support HTTP trailers.
+	Trailer Header
+
+	// RemoteAddr allows HTTP servers and other software to record
+	// the network address that sent the request, usually for
+	// logging. This field is not filled in by ReadRequest and
+	// has no defined format. The HTTP server in this package
+	// sets RemoteAddr to an "IP:port" address before invoking a
+	// handler.
+	// This field is ignored by the HTTP client.
+	RemoteAddr string
+
+	// RequestURI is the unmodified Request-URI of the
+	// Request-Line (RFC 2616, Section 5.1) as sent by the client
+	// to a server. Usually the URL field should be used instead.
+	// It is an error to set this field in an HTTP client request.
+	RequestURI string
+
+	// TLS allows HTTP servers and other software to record
+	// information about the TLS connection on which the request
+	// was received. This field is not filled in by ReadRequest.
+	// The HTTP server in this package sets the field for
+	// TLS-enabled connections before invoking a handler;
+	// otherwise it leaves the field nil.
+	// This field is ignored by the HTTP client.
+	TLS *tls.ConnectionState
+}
+
+// ProtoAtLeast reports whether the HTTP protocol used
+// in the request is at least major.minor.
+func (r *Request) ProtoAtLeast(major, minor int) bool {
+	return r.ProtoMajor > major ||
+		r.ProtoMajor == major && r.ProtoMinor >= minor
+}
+
+// UserAgent returns the client's User-Agent, if sent in the request.
+func (r *Request) UserAgent() string {
+	return r.Header.Get("User-Agent")
+}
+
+// Cookies parses and returns the HTTP cookies sent with the request.
+func (r *Request) Cookies() []*Cookie {
+	return readCookies(r.Header, "")
+}
+
+var ErrNoCookie = errors.New("http: named cookie not present")
+
+// Cookie returns the named cookie provided in the request or
+// ErrNoCookie if not found.
+func (r *Request) Cookie(name string) (*Cookie, error) {
+	for _, c := range readCookies(r.Header, name) {
+		return c, nil
+	}
+	return nil, ErrNoCookie
+}
+
+// AddCookie adds a cookie to the request.  Per RFC 6265 section 5.4,
+// AddCookie does not attach more than one Cookie header field.  That
+// means all cookies, if any, are written into the same line,
+// separated by semicolon.
+func (r *Request) AddCookie(c *Cookie) {
+	s := fmt.Sprintf("%s=%s", sanitizeCookieName(c.Name), sanitizeCookieValue(c.Value))
+	if c := r.Header.Get("Cookie"); c != "" {
+		r.Header.Set("Cookie", c+"; "+s)
+	} else {
+		r.Header.Set("Cookie", s)
+	}
+}
+
+// Referer returns the referring URL, if sent in the request.
+//
+// Referer is misspelled as in the request itself, a mistake from the
+// earliest days of HTTP.  This value can also be fetched from the
+// Header map as Header["Referer"]; the benefit of making it available
+// as a method is that the compiler can diagnose programs that use the
+// alternate (correct English) spelling req.Referrer() but cannot
+// diagnose programs that use Header["Referrer"].
+func (r *Request) Referer() string {
+	return r.Header.Get("Referer")
+}
+
+// multipartByReader is a sentinel value.
+// Its presence in Request.MultipartForm indicates that parsing of the request
+// body has been handed off to a MultipartReader instead of ParseMultipartFrom.
+var multipartByReader = &multipart.Form{
+	Value: make(map[string][]string),
+	File:  make(map[string][]*multipart.FileHeader),
+}
+
+// MultipartReader returns a MIME multipart reader if this is a
+// multipart/form-data POST request, else returns nil and an error.
+// Use this function instead of ParseMultipartForm to
+// process the request body as a stream.
+func (r *Request) MultipartReader() (*multipart.Reader, error) {
+	if r.MultipartForm == multipartByReader {
+		return nil, errors.New("http: MultipartReader called twice")
+	}
+	if r.MultipartForm != nil {
+		return nil, errors.New("http: multipart handled by ParseMultipartForm")
+	}
+	r.MultipartForm = multipartByReader
+	return r.multipartReader()
+}
+
+func (r *Request) multipartReader() (*multipart.Reader, error) {
+	v := r.Header.Get("Content-Type")
+	if v == "" {
+		return nil, ErrNotMultipart
+	}
+	d, params, err := mime.ParseMediaType(v)
+	if err != nil || d != "multipart/form-data" {
+		return nil, ErrNotMultipart
+	}
+	boundary, ok := params["boundary"]
+	if !ok {
+		return nil, ErrMissingBoundary
+	}
+	return multipart.NewReader(r.Body, boundary), nil
+}
+
+// Return value if nonempty, def otherwise.
+func valueOrDefault(value, def string) string {
+	if value != "" {
+		return value
+	}
+	return def
+}
+
+// NOTE: This is not intended to reflect the actual Go version being used.
+// It was changed from "Go http package" to "Go 1.1 package http" at the
+// time of the Go 1.1 release because the former User-Agent had ended up
+// on a blacklist for some intrusion detection systems.
+// See https://codereview.appspot.com/7532043.
+const defaultUserAgent = "Go 1.1 package http"
+
+// Write writes an HTTP/1.1 request -- header and body -- in wire format.
+// This method consults the following fields of the request:
+//	Host
+//	URL
+//	Method (defaults to "GET")
+//	Header
+//	ContentLength
+//	TransferEncoding
+//	Body
+//
+// If Body is present, Content-Length is <= 0 and TransferEncoding
+// hasn't been set to "identity", Write adds "Transfer-Encoding:
+// chunked" to the header. Body is closed after it is sent.
+func (r *Request) Write(w io.Writer) error {
+	return r.write(w, false, nil)
+}
+
+// WriteProxy is like Write but writes the request in the form
+// expected by an HTTP proxy.  In particular, WriteProxy writes the
+// initial Request-URI line of the request with an absolute URI, per
+// section 5.1.2 of RFC 2616, including the scheme and host.
+// In either case, WriteProxy also writes a Host header, using
+// either r.Host or r.URL.Host.
+func (r *Request) WriteProxy(w io.Writer) error {
+	return r.write(w, true, nil)
+}
+
+// extraHeaders may be nil
+func (req *Request) write(w io.Writer, usingProxy bool, extraHeaders Header) error {
+	host := req.Host
+	if host == "" {
+		if req.URL == nil {
+			return errors.New("http: Request.Write on Request with no Host or URL set")
+		}
+		host = req.URL.Host
+	}
+
+	ruri := req.URL.RequestURI()
+	if usingProxy && req.URL.Scheme != "" && req.URL.Opaque == "" {
+		ruri = req.URL.Scheme + "://" + host + ruri
+	} else if req.Method == "CONNECT" && req.URL.Path == "" {
+		// CONNECT requests normally give just the host and port, not a full URL.
+		ruri = host
+	}
+	// TODO(bradfitz): escape at least newlines in ruri?
+
+	// Wrap the writer in a bufio Writer if it's not already buffered.
+	// Don't always call NewWriter, as that forces a bytes.Buffer
+	// and other small bufio Writers to have a minimum 4k buffer
+	// size.
+	var bw *bufio.Writer
+	if _, ok := w.(io.ByteWriter); !ok {
+		bw = bufio.NewWriter(w)
+		w = bw
+	}
+
+	_, err := fmt.Fprintf(w, "%s %s HTTP/1.1\r\n", valueOrDefault(req.Method, "GET"), ruri)
+	if err != nil {
+		return err
+	}
+
+	// Header lines
+	_, err = fmt.Fprintf(w, "Host: %s\r\n", host)
+	if err != nil {
+		return err
+	}
+
+	// Use the defaultUserAgent unless the Header contains one, which
+	// may be blank to not send the header.
+	userAgent := defaultUserAgent
+	if req.Header != nil {
+		if ua := req.Header["User-Agent"]; len(ua) > 0 {
+			userAgent = ua[0]
+		}
+	}
+	if userAgent != "" {
+		_, err = fmt.Fprintf(w, "User-Agent: %s\r\n", userAgent)
+		if err != nil {
+			return err
+		}
+	}
+
+	// Process Body,ContentLength,Close,Trailer
+	tw, err := newTransferWriter(req)
+	if err != nil {
+		return err
+	}
+	err = tw.WriteHeader(w)
+	if err != nil {
+		return err
+	}
+
+	err = req.Header.WriteSubset(w, reqWriteExcludeHeader)
+	if err != nil {
+		return err
+	}
+
+	if extraHeaders != nil {
+		err = extraHeaders.Write(w)
+		if err != nil {
+			return err
+		}
+	}
+
+	_, err = io.WriteString(w, "\r\n")
+	if err != nil {
+		return err
+	}
+
+	// Write body and trailer
+	err = tw.WriteBody(w)
+	if err != nil {
+		return err
+	}
+
+	if bw != nil {
+		return bw.Flush()
+	}
+	return nil
+}
+
+// ParseHTTPVersion parses a HTTP version string.
+// "HTTP/1.0" returns (1, 0, true).
+func ParseHTTPVersion(vers string) (major, minor int, ok bool) {
+	const Big = 1000000 // arbitrary upper bound
+	switch vers {
+	case "HTTP/1.1":
+		return 1, 1, true
+	case "HTTP/1.0":
+		return 1, 0, true
+	}
+	if !strings.HasPrefix(vers, "HTTP/") {
+		return 0, 0, false
+	}
+	dot := strings.Index(vers, ".")
+	if dot < 0 {
+		return 0, 0, false
+	}
+	major, err := strconv.Atoi(vers[5:dot])
+	if err != nil || major < 0 || major > Big {
+		return 0, 0, false
+	}
+	minor, err = strconv.Atoi(vers[dot+1:])
+	if err != nil || minor < 0 || minor > Big {
+		return 0, 0, false
+	}
+	return major, minor, true
+}
+
+// NewRequest returns a new Request given a method, URL, and optional body.
+//
+// If the provided body is also an io.Closer, the returned
+// Request.Body is set to body and will be closed by the Client
+// methods Do, Post, and PostForm, and Transport.RoundTrip.
+func NewRequest(method, urlStr string, body io.Reader) (*Request, error) {
+	u, err := url.Parse(urlStr)
+	if err != nil {
+		return nil, err
+	}
+	rc, ok := body.(io.ReadCloser)
+	if !ok && body != nil {
+		rc = ioutil.NopCloser(body)
+	}
+	req := &Request{
+		Method:     method,
+		URL:        u,
+		Proto:      "HTTP/1.1",
+		ProtoMajor: 1,
+		ProtoMinor: 1,
+		Header:     make(Header),
+		Body:       rc,
+		Host:       u.Host,
+	}
+	if body != nil {
+		switch v := body.(type) {
+		case *bytes.Buffer:
+			req.ContentLength = int64(v.Len())
+		case *bytes.Reader:
+			req.ContentLength = int64(v.Len())
+		case *strings.Reader:
+			req.ContentLength = int64(v.Len())
+		}
+	}
+
+	return req, nil
+}
+
+// BasicAuth returns the username and password provided in the request's
+// Authorization header, if the request uses HTTP Basic Authentication.
+// See RFC 2617, Section 2.
+func (r *Request) BasicAuth() (username, password string, ok bool) {
+	auth := r.Header.Get("Authorization")
+	if auth == "" {
+		return
+	}
+	return parseBasicAuth(auth)
+}
+
+// parseBasicAuth parses an HTTP Basic Authentication string.
+// "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==" returns ("Aladdin", "open sesame", true).
+func parseBasicAuth(auth string) (username, password string, ok bool) {
+	if !strings.HasPrefix(auth, "Basic ") {
+		return
+	}
+	c, err := base64.StdEncoding.DecodeString(strings.TrimPrefix(auth, "Basic "))
+	if err != nil {
+		return
+	}
+	cs := string(c)
+	s := strings.IndexByte(cs, ':')
+	if s < 0 {
+		return
+	}
+	return cs[:s], cs[s+1:], true
+}
+
+// SetBasicAuth sets the request's Authorization header to use HTTP
+// Basic Authentication with the provided username and password.
+//
+// With HTTP Basic Authentication the provided username and password
+// are not encrypted.
+func (r *Request) SetBasicAuth(username, password string) {
+	r.Header.Set("Authorization", "Basic "+basicAuth(username, password))
+}
+
+// parseRequestLine parses "GET /foo HTTP/1.1" into its three parts.
+func parseRequestLine(line string) (method, requestURI, proto string, ok bool) {
+	s1 := strings.Index(line, " ")
+	s2 := strings.Index(line[s1+1:], " ")
+	if s1 < 0 || s2 < 0 {
+		return
+	}
+	s2 += s1 + 1
+	return line[:s1], line[s1+1 : s2], line[s2+1:], true
+}
+
+var textprotoReaderPool sync.Pool
+
+func newTextprotoReader(br *bufio.Reader) *textproto.Reader {
+	if v := textprotoReaderPool.Get(); v != nil {
+		tr := v.(*textproto.Reader)
+		tr.R = br
+		return tr
+	}
+	return textproto.NewReader(br)
+}
+
+func putTextprotoReader(r *textproto.Reader) {
+	r.R = nil
+	textprotoReaderPool.Put(r)
+}
+
+// ReadRequest reads and parses a request from b.
+func ReadRequest(b *bufio.Reader) (req *Request, err error) {
+
+	tp := newTextprotoReader(b)
+	req = new(Request)
+
+	// First line: GET /index.html HTTP/1.0
+	var s string
+	if s, err = tp.ReadLine(); err != nil {
+		return nil, err
+	}
+	defer func() {
+		putTextprotoReader(tp)
+		if err == io.EOF {
+			err = io.ErrUnexpectedEOF
+		}
+	}()
+
+	var ok bool
+	req.Method, req.RequestURI, req.Proto, ok = parseRequestLine(s)
+	if !ok {
+		return nil, &badStringError{"malformed HTTP request", s}
+	}
+	rawurl := req.RequestURI
+	if req.ProtoMajor, req.ProtoMinor, ok = ParseHTTPVersion(req.Proto); !ok {
+		return nil, &badStringError{"malformed HTTP version", req.Proto}
+	}
+
+	// CONNECT requests are used two different ways, and neither uses a full URL:
+	// The standard use is to tunnel HTTPS through an HTTP proxy.
+	// It looks like "CONNECT www.google.com:443 HTTP/1.1", and the parameter is
+	// just the authority section of a URL. This information should go in req.URL.Host.
+	//
+	// The net/rpc package also uses CONNECT, but there the parameter is a path
+	// that starts with a slash. It can be parsed with the regular URL parser,
+	// and the path will end up in req.URL.Path, where it needs to be in order for
+	// RPC to work.
+	justAuthority := req.Method == "CONNECT" && !strings.HasPrefix(rawurl, "/")
+	if justAuthority {
+		rawurl = "http://" + rawurl
+	}
+
+	if req.URL, err = url.ParseRequestURI(rawurl); err != nil {
+		return nil, err
+	}
+
+	if justAuthority {
+		// Strip the bogus "http://" back off.
+		req.URL.Scheme = ""
+	}
+
+	// Subsequent lines: Key: value.
+	mimeHeader, err := tp.ReadMIMEHeader()
+	if err != nil {
+		return nil, err
+	}
+	req.Header = Header(mimeHeader)
+
+	// RFC2616: Must treat
+	//	GET /index.html HTTP/1.1
+	//	Host: www.google.com
+	// and
+	//	GET http://www.google.com/index.html HTTP/1.1
+	//	Host: doesntmatter
+	// the same.  In the second case, any Host line is ignored.
+	req.Host = req.URL.Host
+	if req.Host == "" {
+		req.Host = req.Header.get("Host")
+	}
+	delete(req.Header, "Host")
+
+	fixPragmaCacheControl(req.Header)
+
+	err = readTransfer(req, b)
+	if err != nil {
+		return nil, err
+	}
+
+	req.Close = shouldClose(req.ProtoMajor, req.ProtoMinor, req.Header, false)
+	return req, nil
+}
+
+// MaxBytesReader is similar to io.LimitReader but is intended for
+// limiting the size of incoming request bodies. In contrast to
+// io.LimitReader, MaxBytesReader's result is a ReadCloser, returns a
+// non-EOF error for a Read beyond the limit, and Closes the
+// underlying reader when its Close method is called.
+//
+// MaxBytesReader prevents clients from accidentally or maliciously
+// sending a large request and wasting server resources.
+func MaxBytesReader(w ResponseWriter, r io.ReadCloser, n int64) io.ReadCloser {
+	return &maxBytesReader{w: w, r: r, n: n}
+}
+
+type maxBytesReader struct {
+	w       ResponseWriter
+	r       io.ReadCloser // underlying reader
+	n       int64         // max bytes remaining
+	stopped bool
+}
+
+func (l *maxBytesReader) Read(p []byte) (n int, err error) {
+	if l.n <= 0 {
+		if !l.stopped {
+			l.stopped = true
+			if res, ok := l.w.(*response); ok {
+				res.requestTooLarge()
+			}
+		}
+		return 0, errors.New("http: request body too large")
+	}
+	if int64(len(p)) > l.n {
+		p = p[:l.n]
+	}
+	n, err = l.r.Read(p)
+	l.n -= int64(n)
+	return
+}
+
+func (l *maxBytesReader) Close() error {
+	return l.r.Close()
+}
+
+func copyValues(dst, src url.Values) {
+	for k, vs := range src {
+		for _, value := range vs {
+			dst.Add(k, value)
+		}
+	}
+}
+
+func parsePostForm(r *Request) (vs url.Values, err error) {
+	if r.Body == nil {
+		err = errors.New("missing form body")
+		return
+	}
+	ct := r.Header.Get("Content-Type")
+	// RFC 2616, section 7.2.1 - empty type
+	//   SHOULD be treated as application/octet-stream
+	if ct == "" {
+		ct = "application/octet-stream"
+	}
+	ct, _, err = mime.ParseMediaType(ct)
+	switch {
+	case ct == "application/x-www-form-urlencoded":
+		var reader io.Reader = r.Body
+		maxFormSize := int64(1<<63 - 1)
+		if _, ok := r.Body.(*maxBytesReader); !ok {
+			maxFormSize = int64(10 << 20) // 10 MB is a lot of text.
+			reader = io.LimitReader(r.Body, maxFormSize+1)
+		}
+		b, e := ioutil.ReadAll(reader)
+		if e != nil {
+			if err == nil {
+				err = e
+			}
+			break
+		}
+		if int64(len(b)) > maxFormSize {
+			err = errors.New("http: POST too large")
+			return
+		}
+		vs, e = url.ParseQuery(string(b))
+		if err == nil {
+			err = e
+		}
+	case ct == "multipart/form-data":
+		// handled by ParseMultipartForm (which is calling us, or should be)
+		// TODO(bradfitz): there are too many possible
+		// orders to call too many functions here.
+		// Clean this up and write more tests.
+		// request_test.go contains the start of this,
+		// in TestParseMultipartFormOrder and others.
+	}
+	return
+}
+
+// ParseForm parses the raw query from the URL and updates r.Form.
+//
+// For POST or PUT requests, it also parses the request body as a form and
+// put the results into both r.PostForm and r.Form.
+// POST and PUT body parameters take precedence over URL query string values
+// in r.Form.
+//
+// If the request Body's size has not already been limited by MaxBytesReader,
+// the size is capped at 10MB.
+//
+// ParseMultipartForm calls ParseForm automatically.
+// It is idempotent.
+func (r *Request) ParseForm() error {
+	var err error
+	if r.PostForm == nil {
+		if r.Method == "POST" || r.Method == "PUT" || r.Method == "PATCH" {
+			r.PostForm, err = parsePostForm(r)
+		}
+		if r.PostForm == nil {
+			r.PostForm = make(url.Values)
+		}
+	}
+	if r.Form == nil {
+		if len(r.PostForm) > 0 {
+			r.Form = make(url.Values)
+			copyValues(r.Form, r.PostForm)
+		}
+		var newValues url.Values
+		if r.URL != nil {
+			var e error
+			newValues, e = url.ParseQuery(r.URL.RawQuery)
+			if err == nil {
+				err = e
+			}
+		}
+		if newValues == nil {
+			newValues = make(url.Values)
+		}
+		if r.Form == nil {
+			r.Form = newValues
+		} else {
+			copyValues(r.Form, newValues)
+		}
+	}
+	return err
+}
+
+// ParseMultipartForm parses a request body as multipart/form-data.
+// The whole request body is parsed and up to a total of maxMemory bytes of
+// its file parts are stored in memory, with the remainder stored on
+// disk in temporary files.
+// ParseMultipartForm calls ParseForm if necessary.
+// After one call to ParseMultipartForm, subsequent calls have no effect.
+func (r *Request) ParseMultipartForm(maxMemory int64) error {
+	if r.MultipartForm == multipartByReader {
+		return errors.New("http: multipart handled by MultipartReader")
+	}
+	if r.Form == nil {
+		err := r.ParseForm()
+		if err != nil {
+			return err
+		}
+	}
+	if r.MultipartForm != nil {
+		return nil
+	}
+
+	mr, err := r.multipartReader()
+	if err != nil {
+		return err
+	}
+
+	f, err := mr.ReadForm(maxMemory)
+	if err != nil {
+		return err
+	}
+	for k, v := range f.Value {
+		r.Form[k] = append(r.Form[k], v...)
+	}
+	r.MultipartForm = f
+
+	return nil
+}
+
+// FormValue returns the first value for the named component of the query.
+// POST and PUT body parameters take precedence over URL query string values.
+// FormValue calls ParseMultipartForm and ParseForm if necessary and ignores
+// any errors returned by these functions.
+// To access multiple values of the same key, call ParseForm and
+// then inspect Request.Form directly.
+func (r *Request) FormValue(key string) string {
+	if r.Form == nil {
+		r.ParseMultipartForm(defaultMaxMemory)
+	}
+	if vs := r.Form[key]; len(vs) > 0 {
+		return vs[0]
+	}
+	return ""
+}
+
+// PostFormValue returns the first value for the named component of the POST
+// or PUT request body. URL query parameters are ignored.
+// PostFormValue calls ParseMultipartForm and ParseForm if necessary and ignores
+// any errors returned by these functions.
+func (r *Request) PostFormValue(key string) string {
+	if r.PostForm == nil {
+		r.ParseMultipartForm(defaultMaxMemory)
+	}
+	if vs := r.PostForm[key]; len(vs) > 0 {
+		return vs[0]
+	}
+	return ""
+}
+
+// FormFile returns the first file for the provided form key.
+// FormFile calls ParseMultipartForm and ParseForm if necessary.
+func (r *Request) FormFile(key string) (multipart.File, *multipart.FileHeader, error) {
+	if r.MultipartForm == multipartByReader {
+		return nil, nil, errors.New("http: multipart handled by MultipartReader")
+	}
+	if r.MultipartForm == nil {
+		err := r.ParseMultipartForm(defaultMaxMemory)
+		if err != nil {
+			return nil, nil, err
+		}
+	}
+	if r.MultipartForm != nil && r.MultipartForm.File != nil {
+		if fhs := r.MultipartForm.File[key]; len(fhs) > 0 {
+			f, err := fhs[0].Open()
+			return f, fhs[0], err
+		}
+	}
+	return nil, nil, ErrMissingFile
+}
+
+func (r *Request) expectsContinue() bool {
+	return hasToken(r.Header.get("Expect"), "100-continue")
+}
+
+func (r *Request) wantsHttp10KeepAlive() bool {
+	if r.ProtoMajor != 1 || r.ProtoMinor != 0 {
+		return false
+	}
+	return hasToken(r.Header.get("Connection"), "keep-alive")
+}
+
+func (r *Request) wantsClose() bool {
+	return hasToken(r.Header.get("Connection"), "close")
+}
+
+func (r *Request) closeBody() {
+	if r.Body != nil {
+		r.Body.Close()
+	}
+}
diff --git a/src/net/http/request_test.go b/src/net/http/request_test.go
new file mode 100644
index 0000000..759ea4e
--- /dev/null
+++ b/src/net/http/request_test.go
@@ -0,0 +1,680 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package http_test
+
+import (
+	"bufio"
+	"bytes"
+	"encoding/base64"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"mime/multipart"
+	. "net/http"
+	"net/http/httptest"
+	"net/url"
+	"os"
+	"reflect"
+	"regexp"
+	"strings"
+	"testing"
+)
+
+func TestQuery(t *testing.T) {
+	req := &Request{Method: "GET"}
+	req.URL, _ = url.Parse("http://www.google.com/search?q=foo&q=bar")
+	if q := req.FormValue("q"); q != "foo" {
+		t.Errorf(`req.FormValue("q") = %q, want "foo"`, q)
+	}
+}
+
+func TestPostQuery(t *testing.T) {
+	req, _ := NewRequest("POST", "http://www.google.com/search?q=foo&q=bar&both=x&prio=1&empty=not",
+		strings.NewReader("z=post&both=y&prio=2&empty="))
+	req.Header.Set("Content-Type", "application/x-www-form-urlencoded; param=value")
+
+	if q := req.FormValue("q"); q != "foo" {
+		t.Errorf(`req.FormValue("q") = %q, want "foo"`, q)
+	}
+	if z := req.FormValue("z"); z != "post" {
+		t.Errorf(`req.FormValue("z") = %q, want "post"`, z)
+	}
+	if bq, found := req.PostForm["q"]; found {
+		t.Errorf(`req.PostForm["q"] = %q, want no entry in map`, bq)
+	}
+	if bz := req.PostFormValue("z"); bz != "post" {
+		t.Errorf(`req.PostFormValue("z") = %q, want "post"`, bz)
+	}
+	if qs := req.Form["q"]; !reflect.DeepEqual(qs, []string{"foo", "bar"}) {
+		t.Errorf(`req.Form["q"] = %q, want ["foo", "bar"]`, qs)
+	}
+	if both := req.Form["both"]; !reflect.DeepEqual(both, []string{"y", "x"}) {
+		t.Errorf(`req.Form["both"] = %q, want ["y", "x"]`, both)
+	}
+	if prio := req.FormValue("prio"); prio != "2" {
+		t.Errorf(`req.FormValue("prio") = %q, want "2" (from body)`, prio)
+	}
+	if empty := req.FormValue("empty"); empty != "" {
+		t.Errorf(`req.FormValue("empty") = %q, want "" (from body)`, empty)
+	}
+}
+
+func TestPatchQuery(t *testing.T) {
+	req, _ := NewRequest("PATCH", "http://www.google.com/search?q=foo&q=bar&both=x&prio=1&empty=not",
+		strings.NewReader("z=post&both=y&prio=2&empty="))
+	req.Header.Set("Content-Type", "application/x-www-form-urlencoded; param=value")
+
+	if q := req.FormValue("q"); q != "foo" {
+		t.Errorf(`req.FormValue("q") = %q, want "foo"`, q)
+	}
+	if z := req.FormValue("z"); z != "post" {
+		t.Errorf(`req.FormValue("z") = %q, want "post"`, z)
+	}
+	if bq, found := req.PostForm["q"]; found {
+		t.Errorf(`req.PostForm["q"] = %q, want no entry in map`, bq)
+	}
+	if bz := req.PostFormValue("z"); bz != "post" {
+		t.Errorf(`req.PostFormValue("z") = %q, want "post"`, bz)
+	}
+	if qs := req.Form["q"]; !reflect.DeepEqual(qs, []string{"foo", "bar"}) {
+		t.Errorf(`req.Form["q"] = %q, want ["foo", "bar"]`, qs)
+	}
+	if both := req.Form["both"]; !reflect.DeepEqual(both, []string{"y", "x"}) {
+		t.Errorf(`req.Form["both"] = %q, want ["y", "x"]`, both)
+	}
+	if prio := req.FormValue("prio"); prio != "2" {
+		t.Errorf(`req.FormValue("prio") = %q, want "2" (from body)`, prio)
+	}
+	if empty := req.FormValue("empty"); empty != "" {
+		t.Errorf(`req.FormValue("empty") = %q, want "" (from body)`, empty)
+	}
+}
+
+type stringMap map[string][]string
+type parseContentTypeTest struct {
+	shouldError bool
+	contentType stringMap
+}
+
+var parseContentTypeTests = []parseContentTypeTest{
+	{false, stringMap{"Content-Type": {"text/plain"}}},
+	// Empty content type is legal - shoult be treated as
+	// application/octet-stream (RFC 2616, section 7.2.1)
+	{false, stringMap{}},
+	{true, stringMap{"Content-Type": {"text/plain; boundary="}}},
+	{false, stringMap{"Content-Type": {"application/unknown"}}},
+}
+
+func TestParseFormUnknownContentType(t *testing.T) {
+	for i, test := range parseContentTypeTests {
+		req := &Request{
+			Method: "POST",
+			Header: Header(test.contentType),
+			Body:   ioutil.NopCloser(strings.NewReader("body")),
+		}
+		err := req.ParseForm()
+		switch {
+		case err == nil && test.shouldError:
+			t.Errorf("test %d should have returned error", i)
+		case err != nil && !test.shouldError:
+			t.Errorf("test %d should not have returned error, got %v", i, err)
+		}
+	}
+}
+
+func TestParseFormInitializeOnError(t *testing.T) {
+	nilBody, _ := NewRequest("POST", "http://www.google.com/search?q=foo", nil)
+	tests := []*Request{
+		nilBody,
+		{Method: "GET", URL: nil},
+	}
+	for i, req := range tests {
+		err := req.ParseForm()
+		if req.Form == nil {
+			t.Errorf("%d. Form not initialized, error %v", i, err)
+		}
+		if req.PostForm == nil {
+			t.Errorf("%d. PostForm not initialized, error %v", i, err)
+		}
+	}
+}
+
+func TestMultipartReader(t *testing.T) {
+	req := &Request{
+		Method: "POST",
+		Header: Header{"Content-Type": {`multipart/form-data; boundary="foo123"`}},
+		Body:   ioutil.NopCloser(new(bytes.Buffer)),
+	}
+	multipart, err := req.MultipartReader()
+	if multipart == nil {
+		t.Errorf("expected multipart; error: %v", err)
+	}
+
+	req.Header = Header{"Content-Type": {"text/plain"}}
+	multipart, err = req.MultipartReader()
+	if multipart != nil {
+		t.Error("unexpected multipart for text/plain")
+	}
+}
+
+func TestParseMultipartForm(t *testing.T) {
+	req := &Request{
+		Method: "POST",
+		Header: Header{"Content-Type": {`multipart/form-data; boundary="foo123"`}},
+		Body:   ioutil.NopCloser(new(bytes.Buffer)),
+	}
+	err := req.ParseMultipartForm(25)
+	if err == nil {
+		t.Error("expected multipart EOF, got nil")
+	}
+
+	req.Header = Header{"Content-Type": {"text/plain"}}
+	err = req.ParseMultipartForm(25)
+	if err != ErrNotMultipart {
+		t.Error("expected ErrNotMultipart for text/plain")
+	}
+}
+
+func TestRedirect(t *testing.T) {
+	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+		switch r.URL.Path {
+		case "/":
+			w.Header().Set("Location", "/foo/")
+			w.WriteHeader(StatusSeeOther)
+		case "/foo/":
+			fmt.Fprintf(w, "foo")
+		default:
+			w.WriteHeader(StatusBadRequest)
+		}
+	}))
+	defer ts.Close()
+
+	var end = regexp.MustCompile("/foo/$")
+	r, err := Get(ts.URL)
+	if err != nil {
+		t.Fatal(err)
+	}
+	r.Body.Close()
+	url := r.Request.URL.String()
+	if r.StatusCode != 200 || !end.MatchString(url) {
+		t.Fatalf("Get got status %d at %q, want 200 matching /foo/$", r.StatusCode, url)
+	}
+}
+
+func TestSetBasicAuth(t *testing.T) {
+	r, _ := NewRequest("GET", "http://example.com/", nil)
+	r.SetBasicAuth("Aladdin", "open sesame")
+	if g, e := r.Header.Get("Authorization"), "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=="; g != e {
+		t.Errorf("got header %q, want %q", g, e)
+	}
+}
+
+func TestMultipartRequest(t *testing.T) {
+	// Test that we can read the values and files of a
+	// multipart request with FormValue and FormFile,
+	// and that ParseMultipartForm can be called multiple times.
+	req := newTestMultipartRequest(t)
+	if err := req.ParseMultipartForm(25); err != nil {
+		t.Fatal("ParseMultipartForm first call:", err)
+	}
+	defer req.MultipartForm.RemoveAll()
+	validateTestMultipartContents(t, req, false)
+	if err := req.ParseMultipartForm(25); err != nil {
+		t.Fatal("ParseMultipartForm second call:", err)
+	}
+	validateTestMultipartContents(t, req, false)
+}
+
+func TestMultipartRequestAuto(t *testing.T) {
+	// Test that FormValue and FormFile automatically invoke
+	// ParseMultipartForm and return the right values.
+	req := newTestMultipartRequest(t)
+	defer func() {
+		if req.MultipartForm != nil {
+			req.MultipartForm.RemoveAll()
+		}
+	}()
+	validateTestMultipartContents(t, req, true)
+}
+
+func TestMissingFileMultipartRequest(t *testing.T) {
+	// Test that FormFile returns an error if
+	// the named file is missing.
+	req := newTestMultipartRequest(t)
+	testMissingFile(t, req)
+}
+
+// Test that FormValue invokes ParseMultipartForm.
+func TestFormValueCallsParseMultipartForm(t *testing.T) {
+	req, _ := NewRequest("POST", "http://www.google.com/", strings.NewReader("z=post"))
+	req.Header.Set("Content-Type", "application/x-www-form-urlencoded; param=value")
+	if req.Form != nil {
+		t.Fatal("Unexpected request Form, want nil")
+	}
+	req.FormValue("z")
+	if req.Form == nil {
+		t.Fatal("ParseMultipartForm not called by FormValue")
+	}
+}
+
+// Test that FormFile invokes ParseMultipartForm.
+func TestFormFileCallsParseMultipartForm(t *testing.T) {
+	req := newTestMultipartRequest(t)
+	if req.Form != nil {
+		t.Fatal("Unexpected request Form, want nil")
+	}
+	req.FormFile("")
+	if req.Form == nil {
+		t.Fatal("ParseMultipartForm not called by FormFile")
+	}
+}
+
+// Test that ParseMultipartForm errors if called
+// after MultipartReader on the same request.
+func TestParseMultipartFormOrder(t *testing.T) {
+	req := newTestMultipartRequest(t)
+	if _, err := req.MultipartReader(); err != nil {
+		t.Fatalf("MultipartReader: %v", err)
+	}
+	if err := req.ParseMultipartForm(1024); err == nil {
+		t.Fatal("expected an error from ParseMultipartForm after call to MultipartReader")
+	}
+}
+
+// Test that MultipartReader errors if called
+// after ParseMultipartForm on the same request.
+func TestMultipartReaderOrder(t *testing.T) {
+	req := newTestMultipartRequest(t)
+	if err := req.ParseMultipartForm(25); err != nil {
+		t.Fatalf("ParseMultipartForm: %v", err)
+	}
+	defer req.MultipartForm.RemoveAll()
+	if _, err := req.MultipartReader(); err == nil {
+		t.Fatal("expected an error from MultipartReader after call to ParseMultipartForm")
+	}
+}
+
+// Test that FormFile errors if called after
+// MultipartReader on the same request.
+func TestFormFileOrder(t *testing.T) {
+	req := newTestMultipartRequest(t)
+	if _, err := req.MultipartReader(); err != nil {
+		t.Fatalf("MultipartReader: %v", err)
+	}
+	if _, _, err := req.FormFile(""); err == nil {
+		t.Fatal("expected an error from FormFile after call to MultipartReader")
+	}
+}
+
+var readRequestErrorTests = []struct {
+	in  string
+	err error
+}{
+	{"GET / HTTP/1.1\r\nheader:foo\r\n\r\n", nil},
+	{"GET / HTTP/1.1\r\nheader:foo\r\n", io.ErrUnexpectedEOF},
+	{"", io.EOF},
+}
+
+func TestReadRequestErrors(t *testing.T) {
+	for i, tt := range readRequestErrorTests {
+		_, err := ReadRequest(bufio.NewReader(strings.NewReader(tt.in)))
+		if err != tt.err {
+			t.Errorf("%d. got error = %v; want %v", i, err, tt.err)
+		}
+	}
+}
+
+func TestNewRequestHost(t *testing.T) {
+	req, err := NewRequest("GET", "http://localhost:1234/", nil)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if req.Host != "localhost:1234" {
+		t.Errorf("Host = %q; want localhost:1234", req.Host)
+	}
+}
+
+func TestNewRequestContentLength(t *testing.T) {
+	readByte := func(r io.Reader) io.Reader {
+		var b [1]byte
+		r.Read(b[:])
+		return r
+	}
+	tests := []struct {
+		r    io.Reader
+		want int64
+	}{
+		{bytes.NewReader([]byte("123")), 3},
+		{bytes.NewBuffer([]byte("1234")), 4},
+		{strings.NewReader("12345"), 5},
+		// Not detected:
+		{struct{ io.Reader }{strings.NewReader("xyz")}, 0},
+		{io.NewSectionReader(strings.NewReader("x"), 0, 6), 0},
+		{readByte(io.NewSectionReader(strings.NewReader("xy"), 0, 6)), 0},
+	}
+	for _, tt := range tests {
+		req, err := NewRequest("POST", "http://localhost/", tt.r)
+		if err != nil {
+			t.Fatal(err)
+		}
+		if req.ContentLength != tt.want {
+			t.Errorf("ContentLength(%T) = %d; want %d", tt.r, req.ContentLength, tt.want)
+		}
+	}
+}
+
+var parseHTTPVersionTests = []struct {
+	vers         string
+	major, minor int
+	ok           bool
+}{
+	{"HTTP/0.9", 0, 9, true},
+	{"HTTP/1.0", 1, 0, true},
+	{"HTTP/1.1", 1, 1, true},
+	{"HTTP/3.14", 3, 14, true},
+
+	{"HTTP", 0, 0, false},
+	{"HTTP/one.one", 0, 0, false},
+	{"HTTP/1.1/", 0, 0, false},
+	{"HTTP/-1,0", 0, 0, false},
+	{"HTTP/0,-1", 0, 0, false},
+	{"HTTP/", 0, 0, false},
+	{"HTTP/1,1", 0, 0, false},
+}
+
+func TestParseHTTPVersion(t *testing.T) {
+	for _, tt := range parseHTTPVersionTests {
+		major, minor, ok := ParseHTTPVersion(tt.vers)
+		if ok != tt.ok || major != tt.major || minor != tt.minor {
+			type version struct {
+				major, minor int
+				ok           bool
+			}
+			t.Errorf("failed to parse %q, expected: %#v, got %#v", tt.vers, version{tt.major, tt.minor, tt.ok}, version{major, minor, ok})
+		}
+	}
+}
+
+type getBasicAuthTest struct {
+	username, password string
+	ok                 bool
+}
+
+type parseBasicAuthTest getBasicAuthTest
+
+type basicAuthCredentialsTest struct {
+	username, password string
+}
+
+var getBasicAuthTests = []struct {
+	username, password string
+	ok                 bool
+}{
+	{"Aladdin", "open sesame", true},
+	{"Aladdin", "open:sesame", true},
+	{"", "", true},
+}
+
+func TestGetBasicAuth(t *testing.T) {
+	for _, tt := range getBasicAuthTests {
+		r, _ := NewRequest("GET", "http://example.com/", nil)
+		r.SetBasicAuth(tt.username, tt.password)
+		username, password, ok := r.BasicAuth()
+		if ok != tt.ok || username != tt.username || password != tt.password {
+			t.Errorf("BasicAuth() = %#v, want %#v", getBasicAuthTest{username, password, ok},
+				getBasicAuthTest{tt.username, tt.password, tt.ok})
+		}
+	}
+	// Unauthenticated request.
+	r, _ := NewRequest("GET", "http://example.com/", nil)
+	username, password, ok := r.BasicAuth()
+	if ok {
+		t.Errorf("expected false from BasicAuth when the request is unauthenticated")
+	}
+	want := basicAuthCredentialsTest{"", ""}
+	if username != want.username || password != want.password {
+		t.Errorf("expected credentials: %#v when the request is unauthenticated, got %#v",
+			want, basicAuthCredentialsTest{username, password})
+	}
+}
+
+var parseBasicAuthTests = []struct {
+	header, username, password string
+	ok                         bool
+}{
+	{"Basic " + base64.StdEncoding.EncodeToString([]byte("Aladdin:open sesame")), "Aladdin", "open sesame", true},
+	{"Basic " + base64.StdEncoding.EncodeToString([]byte("Aladdin:open:sesame")), "Aladdin", "open:sesame", true},
+	{"Basic " + base64.StdEncoding.EncodeToString([]byte(":")), "", "", true},
+	{"Basic" + base64.StdEncoding.EncodeToString([]byte("Aladdin:open sesame")), "", "", false},
+	{base64.StdEncoding.EncodeToString([]byte("Aladdin:open sesame")), "", "", false},
+	{"Basic ", "", "", false},
+	{"Basic Aladdin:open sesame", "", "", false},
+	{`Digest username="Aladdin"`, "", "", false},
+}
+
+func TestParseBasicAuth(t *testing.T) {
+	for _, tt := range parseBasicAuthTests {
+		r, _ := NewRequest("GET", "http://example.com/", nil)
+		r.Header.Set("Authorization", tt.header)
+		username, password, ok := r.BasicAuth()
+		if ok != tt.ok || username != tt.username || password != tt.password {
+			t.Errorf("BasicAuth() = %#v, want %#v", getBasicAuthTest{username, password, ok},
+				getBasicAuthTest{tt.username, tt.password, tt.ok})
+		}
+	}
+}
+
+type logWrites struct {
+	t   *testing.T
+	dst *[]string
+}
+
+func (l logWrites) WriteByte(c byte) error {
+	l.t.Fatalf("unexpected WriteByte call")
+	return nil
+}
+
+func (l logWrites) Write(p []byte) (n int, err error) {
+	*l.dst = append(*l.dst, string(p))
+	return len(p), nil
+}
+
+func TestRequestWriteBufferedWriter(t *testing.T) {
+	got := []string{}
+	req, _ := NewRequest("GET", "http://foo.com/", nil)
+	req.Write(logWrites{t, &got})
+	want := []string{
+		"GET / HTTP/1.1\r\n",
+		"Host: foo.com\r\n",
+		"User-Agent: " + DefaultUserAgent + "\r\n",
+		"\r\n",
+	}
+	if !reflect.DeepEqual(got, want) {
+		t.Errorf("Writes = %q\n  Want = %q", got, want)
+	}
+}
+
+func testMissingFile(t *testing.T, req *Request) {
+	f, fh, err := req.FormFile("missing")
+	if f != nil {
+		t.Errorf("FormFile file = %v, want nil", f)
+	}
+	if fh != nil {
+		t.Errorf("FormFile file header = %q, want nil", fh)
+	}
+	if err != ErrMissingFile {
+		t.Errorf("FormFile err = %q, want ErrMissingFile", err)
+	}
+}
+
+func newTestMultipartRequest(t *testing.T) *Request {
+	b := strings.NewReader(strings.Replace(message, "\n", "\r\n", -1))
+	req, err := NewRequest("POST", "/", b)
+	if err != nil {
+		t.Fatal("NewRequest:", err)
+	}
+	ctype := fmt.Sprintf(`multipart/form-data; boundary="%s"`, boundary)
+	req.Header.Set("Content-type", ctype)
+	return req
+}
+
+func validateTestMultipartContents(t *testing.T, req *Request, allMem bool) {
+	if g, e := req.FormValue("texta"), textaValue; g != e {
+		t.Errorf("texta value = %q, want %q", g, e)
+	}
+	if g, e := req.FormValue("textb"), textbValue; g != e {
+		t.Errorf("textb value = %q, want %q", g, e)
+	}
+	if g := req.FormValue("missing"); g != "" {
+		t.Errorf("missing value = %q, want empty string", g)
+	}
+
+	assertMem := func(n string, fd multipart.File) {
+		if _, ok := fd.(*os.File); ok {
+			t.Error(n, " is *os.File, should not be")
+		}
+	}
+	fda := testMultipartFile(t, req, "filea", "filea.txt", fileaContents)
+	defer fda.Close()
+	assertMem("filea", fda)
+	fdb := testMultipartFile(t, req, "fileb", "fileb.txt", filebContents)
+	defer fdb.Close()
+	if allMem {
+		assertMem("fileb", fdb)
+	} else {
+		if _, ok := fdb.(*os.File); !ok {
+			t.Errorf("fileb has unexpected underlying type %T", fdb)
+		}
+	}
+
+	testMissingFile(t, req)
+}
+
+func testMultipartFile(t *testing.T, req *Request, key, expectFilename, expectContent string) multipart.File {
+	f, fh, err := req.FormFile(key)
+	if err != nil {
+		t.Fatalf("FormFile(%q): %q", key, err)
+	}
+	if fh.Filename != expectFilename {
+		t.Errorf("filename = %q, want %q", fh.Filename, expectFilename)
+	}
+	var b bytes.Buffer
+	_, err = io.Copy(&b, f)
+	if err != nil {
+		t.Fatal("copying contents:", err)
+	}
+	if g := b.String(); g != expectContent {
+		t.Errorf("contents = %q, want %q", g, expectContent)
+	}
+	return f
+}
+
+const (
+	fileaContents = "This is a test file."
+	filebContents = "Another test file."
+	textaValue    = "foo"
+	textbValue    = "bar"
+	boundary      = `MyBoundary`
+)
+
+const message = `
+--MyBoundary
+Content-Disposition: form-data; name="filea"; filename="filea.txt"
+Content-Type: text/plain
+
+` + fileaContents + `
+--MyBoundary
+Content-Disposition: form-data; name="fileb"; filename="fileb.txt"
+Content-Type: text/plain
+
+` + filebContents + `
+--MyBoundary
+Content-Disposition: form-data; name="texta"
+
+` + textaValue + `
+--MyBoundary
+Content-Disposition: form-data; name="textb"
+
+` + textbValue + `
+--MyBoundary--
+`
+
+func benchmarkReadRequest(b *testing.B, request string) {
+	request = request + "\n"                             // final \n
+	request = strings.Replace(request, "\n", "\r\n", -1) // expand \n to \r\n
+	b.SetBytes(int64(len(request)))
+	r := bufio.NewReader(&infiniteReader{buf: []byte(request)})
+	b.ReportAllocs()
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		_, err := ReadRequest(r)
+		if err != nil {
+			b.Fatalf("failed to read request: %v", err)
+		}
+	}
+}
+
+// infiniteReader satisfies Read requests as if the contents of buf
+// loop indefinitely.
+type infiniteReader struct {
+	buf    []byte
+	offset int
+}
+
+func (r *infiniteReader) Read(b []byte) (int, error) {
+	n := copy(b, r.buf[r.offset:])
+	r.offset = (r.offset + n) % len(r.buf)
+	return n, nil
+}
+
+func BenchmarkReadRequestChrome(b *testing.B) {
+	// https://github.com/felixge/node-http-perf/blob/master/fixtures/get.http
+	benchmarkReadRequest(b, `GET / HTTP/1.1
+Host: localhost:8080
+Connection: keep-alive
+Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
+User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.52 Safari/537.17
+Accept-Encoding: gzip,deflate,sdch
+Accept-Language: en-US,en;q=0.8
+Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
+Cookie: __utma=1.1978842379.1323102373.1323102373.1323102373.1; EPi:NumberOfVisits=1,2012-02-28T13:42:18; CrmSession=5b707226b9563e1bc69084d07a107c98; plushContainerWidth=100%25; plushNoTopMenu=0; hudson_auto_refresh=false
+`)
+}
+
+func BenchmarkReadRequestCurl(b *testing.B) {
+	// curl http://localhost:8080/
+	benchmarkReadRequest(b, `GET / HTTP/1.1
+User-Agent: curl/7.27.0
+Host: localhost:8080
+Accept: */*
+`)
+}
+
+func BenchmarkReadRequestApachebench(b *testing.B) {
+	// ab -n 1 -c 1 http://localhost:8080/
+	benchmarkReadRequest(b, `GET / HTTP/1.0
+Host: localhost:8080
+User-Agent: ApacheBench/2.3
+Accept: */*
+`)
+}
+
+func BenchmarkReadRequestSiege(b *testing.B) {
+	// siege -r 1 -c 1 http://localhost:8080/
+	benchmarkReadRequest(b, `GET / HTTP/1.1
+Host: localhost:8080
+Accept: */*
+Accept-Encoding: gzip
+User-Agent: JoeDog/1.00 [en] (X11; I; Siege 2.70)
+Connection: keep-alive
+`)
+}
+
+func BenchmarkReadRequestWrk(b *testing.B) {
+	// wrk -t 1 -r 1 -c 1 http://localhost:8080/
+	benchmarkReadRequest(b, `GET / HTTP/1.1
+Host: localhost:8080
+`)
+}
diff --git a/src/net/http/requestwrite_test.go b/src/net/http/requestwrite_test.go
new file mode 100644
index 0000000..7a6bd58
--- /dev/null
+++ b/src/net/http/requestwrite_test.go
@@ -0,0 +1,623 @@
+// Copyright 2010 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package http
+
+import (
+	"bytes"
+	"errors"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"net/url"
+	"strings"
+	"testing"
+)
+
+type reqWriteTest struct {
+	Req  Request
+	Body interface{} // optional []byte or func() io.ReadCloser to populate Req.Body
+
+	// Any of these three may be empty to skip that test.
+	WantWrite string // Request.Write
+	WantProxy string // Request.WriteProxy
+
+	WantError error // wanted error from Request.Write
+}
+
+var reqWriteTests = []reqWriteTest{
+	// HTTP/1.1 => chunked coding; no body; no trailer
+	{
+		Req: Request{
+			Method: "GET",
+			URL: &url.URL{
+				Scheme: "http",
+				Host:   "www.techcrunch.com",
+				Path:   "/",
+			},
+			Proto:      "HTTP/1.1",
+			ProtoMajor: 1,
+			ProtoMinor: 1,
+			Header: Header{
+				"Accept":           {"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"},
+				"Accept-Charset":   {"ISO-8859-1,utf-8;q=0.7,*;q=0.7"},
+				"Accept-Encoding":  {"gzip,deflate"},
+				"Accept-Language":  {"en-us,en;q=0.5"},
+				"Keep-Alive":       {"300"},
+				"Proxy-Connection": {"keep-alive"},
+				"User-Agent":       {"Fake"},
+			},
+			Body:  nil,
+			Close: false,
+			Host:  "www.techcrunch.com",
+			Form:  map[string][]string{},
+		},
+
+		WantWrite: "GET / HTTP/1.1\r\n" +
+			"Host: www.techcrunch.com\r\n" +
+			"User-Agent: Fake\r\n" +
+			"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n" +
+			"Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n" +
+			"Accept-Encoding: gzip,deflate\r\n" +
+			"Accept-Language: en-us,en;q=0.5\r\n" +
+			"Keep-Alive: 300\r\n" +
+			"Proxy-Connection: keep-alive\r\n\r\n",
+
+		WantProxy: "GET http://www.techcrunch.com/ HTTP/1.1\r\n" +
+			"Host: www.techcrunch.com\r\n" +
+			"User-Agent: Fake\r\n" +
+			"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n" +
+			"Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n" +
+			"Accept-Encoding: gzip,deflate\r\n" +
+			"Accept-Language: en-us,en;q=0.5\r\n" +
+			"Keep-Alive: 300\r\n" +
+			"Proxy-Connection: keep-alive\r\n\r\n",
+	},
+	// HTTP/1.1 => chunked coding; body; empty trailer
+	{
+		Req: Request{
+			Method: "GET",
+			URL: &url.URL{
+				Scheme: "http",
+				Host:   "www.google.com",
+				Path:   "/search",
+			},
+			ProtoMajor:       1,
+			ProtoMinor:       1,
+			Header:           Header{},
+			TransferEncoding: []string{"chunked"},
+		},
+
+		Body: []byte("abcdef"),
+
+		WantWrite: "GET /search HTTP/1.1\r\n" +
+			"Host: www.google.com\r\n" +
+			"User-Agent: Go 1.1 package http\r\n" +
+			"Transfer-Encoding: chunked\r\n\r\n" +
+			chunk("abcdef") + chunk(""),
+
+		WantProxy: "GET http://www.google.com/search HTTP/1.1\r\n" +
+			"Host: www.google.com\r\n" +
+			"User-Agent: Go 1.1 package http\r\n" +
+			"Transfer-Encoding: chunked\r\n\r\n" +
+			chunk("abcdef") + chunk(""),
+	},
+	// HTTP/1.1 POST => chunked coding; body; empty trailer
+	{
+		Req: Request{
+			Method: "POST",
+			URL: &url.URL{
+				Scheme: "http",
+				Host:   "www.google.com",
+				Path:   "/search",
+			},
+			ProtoMajor:       1,
+			ProtoMinor:       1,
+			Header:           Header{},
+			Close:            true,
+			TransferEncoding: []string{"chunked"},
+		},
+
+		Body: []byte("abcdef"),
+
+		WantWrite: "POST /search HTTP/1.1\r\n" +
+			"Host: www.google.com\r\n" +
+			"User-Agent: Go 1.1 package http\r\n" +
+			"Connection: close\r\n" +
+			"Transfer-Encoding: chunked\r\n\r\n" +
+			chunk("abcdef") + chunk(""),
+
+		WantProxy: "POST http://www.google.com/search HTTP/1.1\r\n" +
+			"Host: www.google.com\r\n" +
+			"User-Agent: Go 1.1 package http\r\n" +
+			"Connection: close\r\n" +
+			"Transfer-Encoding: chunked\r\n\r\n" +
+			chunk("abcdef") + chunk(""),
+	},
+
+	// HTTP/1.1 POST with Content-Length, no chunking
+	{
+		Req: Request{
+			Method: "POST",
+			URL: &url.URL{
+				Scheme: "http",
+				Host:   "www.google.com",
+				Path:   "/search",
+			},
+			ProtoMajor:    1,
+			ProtoMinor:    1,
+			Header:        Header{},
+			Close:         true,
+			ContentLength: 6,
+		},
+
+		Body: []byte("abcdef"),
+
+		WantWrite: "POST /search HTTP/1.1\r\n" +
+			"Host: www.google.com\r\n" +
+			"User-Agent: Go 1.1 package http\r\n" +
+			"Connection: close\r\n" +
+			"Content-Length: 6\r\n" +
+			"\r\n" +
+			"abcdef",
+
+		WantProxy: "POST http://www.google.com/search HTTP/1.1\r\n" +
+			"Host: www.google.com\r\n" +
+			"User-Agent: Go 1.1 package http\r\n" +
+			"Connection: close\r\n" +
+			"Content-Length: 6\r\n" +
+			"\r\n" +
+			"abcdef",
+	},
+
+	// HTTP/1.1 POST with Content-Length in headers
+	{
+		Req: Request{
+			Method: "POST",
+			URL:    mustParseURL("http://example.com/"),
+			Host:   "example.com",
+			Header: Header{
+				"Content-Length": []string{"10"}, // ignored
+			},
+			ContentLength: 6,
+		},
+
+		Body: []byte("abcdef"),
+
+		WantWrite: "POST / HTTP/1.1\r\n" +
+			"Host: example.com\r\n" +
+			"User-Agent: Go 1.1 package http\r\n" +
+			"Content-Length: 6\r\n" +
+			"\r\n" +
+			"abcdef",
+
+		WantProxy: "POST http://example.com/ HTTP/1.1\r\n" +
+			"Host: example.com\r\n" +
+			"User-Agent: Go 1.1 package http\r\n" +
+			"Content-Length: 6\r\n" +
+			"\r\n" +
+			"abcdef",
+	},
+
+	// default to HTTP/1.1
+	{
+		Req: Request{
+			Method: "GET",
+			URL:    mustParseURL("/search"),
+			Host:   "www.google.com",
+		},
+
+		WantWrite: "GET /search HTTP/1.1\r\n" +
+			"Host: www.google.com\r\n" +
+			"User-Agent: Go 1.1 package http\r\n" +
+			"\r\n",
+	},
+
+	// Request with a 0 ContentLength and a 0 byte body.
+	{
+		Req: Request{
+			Method:        "POST",
+			URL:           mustParseURL("/"),
+			Host:          "example.com",
+			ProtoMajor:    1,
+			ProtoMinor:    1,
+			ContentLength: 0, // as if unset by user
+		},
+
+		Body: func() io.ReadCloser { return ioutil.NopCloser(io.LimitReader(strings.NewReader("xx"), 0)) },
+
+		// RFC 2616 Section 14.13 says Content-Length should be specified
+		// unless body is prohibited by the request method.
+		// Also, nginx expects it for POST and PUT.
+		WantWrite: "POST / HTTP/1.1\r\n" +
+			"Host: example.com\r\n" +
+			"User-Agent: Go 1.1 package http\r\n" +
+			"Content-Length: 0\r\n" +
+			"\r\n",
+
+		WantProxy: "POST / HTTP/1.1\r\n" +
+			"Host: example.com\r\n" +
+			"User-Agent: Go 1.1 package http\r\n" +
+			"Content-Length: 0\r\n" +
+			"\r\n",
+	},
+
+	// Request with a 0 ContentLength and a 1 byte body.
+	{
+		Req: Request{
+			Method:        "POST",
+			URL:           mustParseURL("/"),
+			Host:          "example.com",
+			ProtoMajor:    1,
+			ProtoMinor:    1,
+			ContentLength: 0, // as if unset by user
+		},
+
+		Body: func() io.ReadCloser { return ioutil.NopCloser(io.LimitReader(strings.NewReader("xx"), 1)) },
+
+		WantWrite: "POST / HTTP/1.1\r\n" +
+			"Host: example.com\r\n" +
+			"User-Agent: Go 1.1 package http\r\n" +
+			"Transfer-Encoding: chunked\r\n\r\n" +
+			chunk("x") + chunk(""),
+
+		WantProxy: "POST / HTTP/1.1\r\n" +
+			"Host: example.com\r\n" +
+			"User-Agent: Go 1.1 package http\r\n" +
+			"Transfer-Encoding: chunked\r\n\r\n" +
+			chunk("x") + chunk(""),
+	},
+
+	// Request with a ContentLength of 10 but a 5 byte body.
+	{
+		Req: Request{
+			Method:        "POST",
+			URL:           mustParseURL("/"),
+			Host:          "example.com",
+			ProtoMajor:    1,
+			ProtoMinor:    1,
+			ContentLength: 10, // but we're going to send only 5 bytes
+		},
+		Body:      []byte("12345"),
+		WantError: errors.New("http: ContentLength=10 with Body length 5"),
+	},
+
+	// Request with a ContentLength of 4 but an 8 byte body.
+	{
+		Req: Request{
+			Method:        "POST",
+			URL:           mustParseURL("/"),
+			Host:          "example.com",
+			ProtoMajor:    1,
+			ProtoMinor:    1,
+			ContentLength: 4, // but we're going to try to send 8 bytes
+		},
+		Body:      []byte("12345678"),
+		WantError: errors.New("http: ContentLength=4 with Body length 8"),
+	},
+
+	// Request with a 5 ContentLength and nil body.
+	{
+		Req: Request{
+			Method:        "POST",
+			URL:           mustParseURL("/"),
+			Host:          "example.com",
+			ProtoMajor:    1,
+			ProtoMinor:    1,
+			ContentLength: 5, // but we'll omit the body
+		},
+		WantError: errors.New("http: Request.ContentLength=5 with nil Body"),
+	},
+
+	// Request with a 0 ContentLength and a body with 1 byte content and an error.
+	{
+		Req: Request{
+			Method:        "POST",
+			URL:           mustParseURL("/"),
+			Host:          "example.com",
+			ProtoMajor:    1,
+			ProtoMinor:    1,
+			ContentLength: 0, // as if unset by user
+		},
+
+		Body: func() io.ReadCloser {
+			err := errors.New("Custom reader error")
+			errReader := &errorReader{err}
+			return ioutil.NopCloser(io.MultiReader(strings.NewReader("x"), errReader))
+		},
+
+		WantError: errors.New("Custom reader error"),
+	},
+
+	// Request with a 0 ContentLength and a body without content and an error.
+	{
+		Req: Request{
+			Method:        "POST",
+			URL:           mustParseURL("/"),
+			Host:          "example.com",
+			ProtoMajor:    1,
+			ProtoMinor:    1,
+			ContentLength: 0, // as if unset by user
+		},
+
+		Body: func() io.ReadCloser {
+			err := errors.New("Custom reader error")
+			errReader := &errorReader{err}
+			return ioutil.NopCloser(errReader)
+		},
+
+		WantError: errors.New("Custom reader error"),
+	},
+
+	// Verify that DumpRequest preserves the HTTP version number, doesn't add a Host,
+	// and doesn't add a User-Agent.
+	{
+		Req: Request{
+			Method:     "GET",
+			URL:        mustParseURL("/foo"),
+			ProtoMajor: 1,
+			ProtoMinor: 0,
+			Header: Header{
+				"X-Foo": []string{"X-Bar"},
+			},
+		},
+
+		WantWrite: "GET /foo HTTP/1.1\r\n" +
+			"Host: \r\n" +
+			"User-Agent: Go 1.1 package http\r\n" +
+			"X-Foo: X-Bar\r\n\r\n",
+	},
+
+	// If no Request.Host and no Request.URL.Host, we send
+	// an empty Host header, and don't use
+	// Request.Header["Host"]. This is just testing that
+	// we don't change Go 1.0 behavior.
+	{
+		Req: Request{
+			Method: "GET",
+			Host:   "",
+			URL: &url.URL{
+				Scheme: "http",
+				Host:   "",
+				Path:   "/search",
+			},
+			ProtoMajor: 1,
+			ProtoMinor: 1,
+			Header: Header{
+				"Host": []string{"bad.example.com"},
+			},
+		},
+
+		WantWrite: "GET /search HTTP/1.1\r\n" +
+			"Host: \r\n" +
+			"User-Agent: Go 1.1 package http\r\n\r\n",
+	},
+
+	// Opaque test #1 from golang.org/issue/4860
+	{
+		Req: Request{
+			Method: "GET",
+			URL: &url.URL{
+				Scheme: "http",
+				Host:   "www.google.com",
+				Opaque: "/%2F/%2F/",
+			},
+			ProtoMajor: 1,
+			ProtoMinor: 1,
+			Header:     Header{},
+		},
+
+		WantWrite: "GET /%2F/%2F/ HTTP/1.1\r\n" +
+			"Host: www.google.com\r\n" +
+			"User-Agent: Go 1.1 package http\r\n\r\n",
+	},
+
+	// Opaque test #2 from golang.org/issue/4860
+	{
+		Req: Request{
+			Method: "GET",
+			URL: &url.URL{
+				Scheme: "http",
+				Host:   "x.google.com",
+				Opaque: "//y.google.com/%2F/%2F/",
+			},
+			ProtoMajor: 1,
+			ProtoMinor: 1,
+			Header:     Header{},
+		},
+
+		WantWrite: "GET http://y.google.com/%2F/%2F/ HTTP/1.1\r\n" +
+			"Host: x.google.com\r\n" +
+			"User-Agent: Go 1.1 package http\r\n\r\n",
+	},
+
+	// Testing custom case in header keys. Issue 5022.
+	{
+		Req: Request{
+			Method: "GET",
+			URL: &url.URL{
+				Scheme: "http",
+				Host:   "www.google.com",
+				Path:   "/",
+			},
+			Proto:      "HTTP/1.1",
+			ProtoMajor: 1,
+			ProtoMinor: 1,
+			Header: Header{
+				"ALL-CAPS": {"x"},
+			},
+		},
+
+		WantWrite: "GET / HTTP/1.1\r\n" +
+			"Host: www.google.com\r\n" +
+			"User-Agent: Go 1.1 package http\r\n" +
+			"ALL-CAPS: x\r\n" +
+			"\r\n",
+	},
+}
+
+func TestRequestWrite(t *testing.T) {
+	for i := range reqWriteTests {
+		tt := &reqWriteTests[i]
+
+		setBody := func() {
+			if tt.Body == nil {
+				return
+			}
+			switch b := tt.Body.(type) {
+			case []byte:
+				tt.Req.Body = ioutil.NopCloser(bytes.NewReader(b))
+			case func() io.ReadCloser:
+				tt.Req.Body = b()
+			}
+		}
+		setBody()
+		if tt.Req.Header == nil {
+			tt.Req.Header = make(Header)
+		}
+
+		var braw bytes.Buffer
+		err := tt.Req.Write(&braw)
+		if g, e := fmt.Sprintf("%v", err), fmt.Sprintf("%v", tt.WantError); g != e {
+			t.Errorf("writing #%d, err = %q, want %q", i, g, e)
+			continue
+		}
+		if err != nil {
+			continue
+		}
+
+		if tt.WantWrite != "" {
+			sraw := braw.String()
+			if sraw != tt.WantWrite {
+				t.Errorf("Test %d, expecting:\n%s\nGot:\n%s\n", i, tt.WantWrite, sraw)
+				continue
+			}
+		}
+
+		if tt.WantProxy != "" {
+			setBody()
+			var praw bytes.Buffer
+			err = tt.Req.WriteProxy(&praw)
+			if err != nil {
+				t.Errorf("WriteProxy #%d: %s", i, err)
+				continue
+			}
+			sraw := praw.String()
+			if sraw != tt.WantProxy {
+				t.Errorf("Test Proxy %d, expecting:\n%s\nGot:\n%s\n", i, tt.WantProxy, sraw)
+				continue
+			}
+		}
+	}
+}
+
+type closeChecker struct {
+	io.Reader
+	closed bool
+}
+
+func (rc *closeChecker) Close() error {
+	rc.closed = true
+	return nil
+}
+
+// TestRequestWriteClosesBody tests that Request.Write does close its request.Body.
+// It also indirectly tests NewRequest and that it doesn't wrap an existing Closer
+// inside a NopCloser, and that it serializes it correctly.
+func TestRequestWriteClosesBody(t *testing.T) {
+	rc := &closeChecker{Reader: strings.NewReader("my body")}
+	req, _ := NewRequest("POST", "http://foo.com/", rc)
+	if req.ContentLength != 0 {
+		t.Errorf("got req.ContentLength %d, want 0", req.ContentLength)
+	}
+	buf := new(bytes.Buffer)
+	req.Write(buf)
+	if !rc.closed {
+		t.Error("body not closed after write")
+	}
+	expected := "POST / HTTP/1.1\r\n" +
+		"Host: foo.com\r\n" +
+		"User-Agent: Go 1.1 package http\r\n" +
+		"Transfer-Encoding: chunked\r\n\r\n" +
+		// TODO: currently we don't buffer before chunking, so we get a
+		// single "m" chunk before the other chunks, as this was the 1-byte
+		// read from our MultiReader where we stiched the Body back together
+		// after sniffing whether the Body was 0 bytes or not.
+		chunk("m") +
+		chunk("y body") +
+		chunk("")
+	if buf.String() != expected {
+		t.Errorf("write:\n got: %s\nwant: %s", buf.String(), expected)
+	}
+}
+
+func chunk(s string) string {
+	return fmt.Sprintf("%x\r\n%s\r\n", len(s), s)
+}
+
+func mustParseURL(s string) *url.URL {
+	u, err := url.Parse(s)
+	if err != nil {
+		panic(fmt.Sprintf("Error parsing URL %q: %v", s, err))
+	}
+	return u
+}
+
+type writerFunc func([]byte) (int, error)
+
+func (f writerFunc) Write(p []byte) (int, error) { return f(p) }
+
+// TestRequestWriteError tests the Write err != nil checks in (*Request).write.
+func TestRequestWriteError(t *testing.T) {
+	failAfter, writeCount := 0, 0
+	errFail := errors.New("fake write failure")
+
+	// w is the buffered io.Writer to write the request to.  It
+	// fails exactly once on its Nth Write call, as controlled by
+	// failAfter. It also tracks the number of calls in
+	// writeCount.
+	w := struct {
+		io.ByteWriter // to avoid being wrapped by a bufio.Writer
+		io.Writer
+	}{
+		nil,
+		writerFunc(func(p []byte) (n int, err error) {
+			writeCount++
+			if failAfter == 0 {
+				err = errFail
+			}
+			failAfter--
+			return len(p), err
+		}),
+	}
+
+	req, _ := NewRequest("GET", "http://example.com/", nil)
+	const writeCalls = 4 // number of Write calls in current implementation
+	sawGood := false
+	for n := 0; n <= writeCalls+2; n++ {
+		failAfter = n
+		writeCount = 0
+		err := req.Write(w)
+		var wantErr error
+		if n < writeCalls {
+			wantErr = errFail
+		}
+		if err != wantErr {
+			t.Errorf("for fail-after %d Writes, err = %v; want %v", n, err, wantErr)
+			continue
+		}
+		if err == nil {
+			sawGood = true
+			if writeCount != writeCalls {
+				t.Fatalf("writeCalls constant is outdated in test")
+			}
+		}
+		if writeCount > writeCalls || writeCount > n+1 {
+			t.Errorf("for fail-after %d, saw unexpectedly high (%d) write calls", n, writeCount)
+		}
+	}
+	if !sawGood {
+		t.Fatalf("writeCalls constant is outdated in test")
+	}
+}
diff --git a/src/pkg/net/http/response.go b/src/net/http/response.go
similarity index 100%
rename from src/pkg/net/http/response.go
rename to src/net/http/response.go
diff --git a/src/net/http/response_test.go b/src/net/http/response_test.go
new file mode 100644
index 0000000..06e940d
--- /dev/null
+++ b/src/net/http/response_test.go
@@ -0,0 +1,674 @@
+// Copyright 2010 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package http
+
+import (
+	"bufio"
+	"bytes"
+	"compress/gzip"
+	"crypto/rand"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"net/http/internal"
+	"net/url"
+	"reflect"
+	"regexp"
+	"strings"
+	"testing"
+)
+
+type respTest struct {
+	Raw  string
+	Resp Response
+	Body string
+}
+
+func dummyReq(method string) *Request {
+	return &Request{Method: method}
+}
+
+func dummyReq11(method string) *Request {
+	return &Request{Method: method, Proto: "HTTP/1.1", ProtoMajor: 1, ProtoMinor: 1}
+}
+
+var respTests = []respTest{
+	// Unchunked response without Content-Length.
+	{
+		"HTTP/1.0 200 OK\r\n" +
+			"Connection: close\r\n" +
+			"\r\n" +
+			"Body here\n",
+
+		Response{
+			Status:     "200 OK",
+			StatusCode: 200,
+			Proto:      "HTTP/1.0",
+			ProtoMajor: 1,
+			ProtoMinor: 0,
+			Request:    dummyReq("GET"),
+			Header: Header{
+				"Connection": {"close"}, // TODO(rsc): Delete?
+			},
+			Close:         true,
+			ContentLength: -1,
+		},
+
+		"Body here\n",
+	},
+
+	// Unchunked HTTP/1.1 response without Content-Length or
+	// Connection headers.
+	{
+		"HTTP/1.1 200 OK\r\n" +
+			"\r\n" +
+			"Body here\n",
+
+		Response{
+			Status:        "200 OK",
+			StatusCode:    200,
+			Proto:         "HTTP/1.1",
+			ProtoMajor:    1,
+			ProtoMinor:    1,
+			Header:        Header{},
+			Request:       dummyReq("GET"),
+			Close:         true,
+			ContentLength: -1,
+		},
+
+		"Body here\n",
+	},
+
+	// Unchunked HTTP/1.1 204 response without Content-Length.
+	{
+		"HTTP/1.1 204 No Content\r\n" +
+			"\r\n" +
+			"Body should not be read!\n",
+
+		Response{
+			Status:        "204 No Content",
+			StatusCode:    204,
+			Proto:         "HTTP/1.1",
+			ProtoMajor:    1,
+			ProtoMinor:    1,
+			Header:        Header{},
+			Request:       dummyReq("GET"),
+			Close:         false,
+			ContentLength: 0,
+		},
+
+		"",
+	},
+
+	// Unchunked response with Content-Length.
+	{
+		"HTTP/1.0 200 OK\r\n" +
+			"Content-Length: 10\r\n" +
+			"Connection: close\r\n" +
+			"\r\n" +
+			"Body here\n",
+
+		Response{
+			Status:     "200 OK",
+			StatusCode: 200,
+			Proto:      "HTTP/1.0",
+			ProtoMajor: 1,
+			ProtoMinor: 0,
+			Request:    dummyReq("GET"),
+			Header: Header{
+				"Connection":     {"close"},
+				"Content-Length": {"10"},
+			},
+			Close:         true,
+			ContentLength: 10,
+		},
+
+		"Body here\n",
+	},
+
+	// Chunked response without Content-Length.
+	{
+		"HTTP/1.1 200 OK\r\n" +
+			"Transfer-Encoding: chunked\r\n" +
+			"\r\n" +
+			"0a\r\n" +
+			"Body here\n\r\n" +
+			"09\r\n" +
+			"continued\r\n" +
+			"0\r\n" +
+			"\r\n",
+
+		Response{
+			Status:           "200 OK",
+			StatusCode:       200,
+			Proto:            "HTTP/1.1",
+			ProtoMajor:       1,
+			ProtoMinor:       1,
+			Request:          dummyReq("GET"),
+			Header:           Header{},
+			Close:            false,
+			ContentLength:    -1,
+			TransferEncoding: []string{"chunked"},
+		},
+
+		"Body here\ncontinued",
+	},
+
+	// Chunked response with Content-Length.
+	{
+		"HTTP/1.1 200 OK\r\n" +
+			"Transfer-Encoding: chunked\r\n" +
+			"Content-Length: 10\r\n" +
+			"\r\n" +
+			"0a\r\n" +
+			"Body here\n\r\n" +
+			"0\r\n" +
+			"\r\n",
+
+		Response{
+			Status:           "200 OK",
+			StatusCode:       200,
+			Proto:            "HTTP/1.1",
+			ProtoMajor:       1,
+			ProtoMinor:       1,
+			Request:          dummyReq("GET"),
+			Header:           Header{},
+			Close:            false,
+			ContentLength:    -1,
+			TransferEncoding: []string{"chunked"},
+		},
+
+		"Body here\n",
+	},
+
+	// Chunked response in response to a HEAD request
+	{
+		"HTTP/1.1 200 OK\r\n" +
+			"Transfer-Encoding: chunked\r\n" +
+			"\r\n",
+
+		Response{
+			Status:           "200 OK",
+			StatusCode:       200,
+			Proto:            "HTTP/1.1",
+			ProtoMajor:       1,
+			ProtoMinor:       1,
+			Request:          dummyReq("HEAD"),
+			Header:           Header{},
+			TransferEncoding: []string{"chunked"},
+			Close:            false,
+			ContentLength:    -1,
+		},
+
+		"",
+	},
+
+	// Content-Length in response to a HEAD request
+	{
+		"HTTP/1.0 200 OK\r\n" +
+			"Content-Length: 256\r\n" +
+			"\r\n",
+
+		Response{
+			Status:           "200 OK",
+			StatusCode:       200,
+			Proto:            "HTTP/1.0",
+			ProtoMajor:       1,
+			ProtoMinor:       0,
+			Request:          dummyReq("HEAD"),
+			Header:           Header{"Content-Length": {"256"}},
+			TransferEncoding: nil,
+			Close:            true,
+			ContentLength:    256,
+		},
+
+		"",
+	},
+
+	// Content-Length in response to a HEAD request with HTTP/1.1
+	{
+		"HTTP/1.1 200 OK\r\n" +
+			"Content-Length: 256\r\n" +
+			"\r\n",
+
+		Response{
+			Status:           "200 OK",
+			StatusCode:       200,
+			Proto:            "HTTP/1.1",
+			ProtoMajor:       1,
+			ProtoMinor:       1,
+			Request:          dummyReq("HEAD"),
+			Header:           Header{"Content-Length": {"256"}},
+			TransferEncoding: nil,
+			Close:            false,
+			ContentLength:    256,
+		},
+
+		"",
+	},
+
+	// No Content-Length or Chunked in response to a HEAD request
+	{
+		"HTTP/1.0 200 OK\r\n" +
+			"\r\n",
+
+		Response{
+			Status:           "200 OK",
+			StatusCode:       200,
+			Proto:            "HTTP/1.0",
+			ProtoMajor:       1,
+			ProtoMinor:       0,
+			Request:          dummyReq("HEAD"),
+			Header:           Header{},
+			TransferEncoding: nil,
+			Close:            true,
+			ContentLength:    -1,
+		},
+
+		"",
+	},
+
+	// explicit Content-Length of 0.
+	{
+		"HTTP/1.1 200 OK\r\n" +
+			"Content-Length: 0\r\n" +
+			"\r\n",
+
+		Response{
+			Status:     "200 OK",
+			StatusCode: 200,
+			Proto:      "HTTP/1.1",
+			ProtoMajor: 1,
+			ProtoMinor: 1,
+			Request:    dummyReq("GET"),
+			Header: Header{
+				"Content-Length": {"0"},
+			},
+			Close:         false,
+			ContentLength: 0,
+		},
+
+		"",
+	},
+
+	// Status line without a Reason-Phrase, but trailing space.
+	// (permitted by RFC 2616)
+	{
+		"HTTP/1.0 303 \r\n\r\n",
+		Response{
+			Status:        "303 ",
+			StatusCode:    303,
+			Proto:         "HTTP/1.0",
+			ProtoMajor:    1,
+			ProtoMinor:    0,
+			Request:       dummyReq("GET"),
+			Header:        Header{},
+			Close:         true,
+			ContentLength: -1,
+		},
+
+		"",
+	},
+
+	// Status line without a Reason-Phrase, and no trailing space.
+	// (not permitted by RFC 2616, but we'll accept it anyway)
+	{
+		"HTTP/1.0 303\r\n\r\n",
+		Response{
+			Status:        "303 ",
+			StatusCode:    303,
+			Proto:         "HTTP/1.0",
+			ProtoMajor:    1,
+			ProtoMinor:    0,
+			Request:       dummyReq("GET"),
+			Header:        Header{},
+			Close:         true,
+			ContentLength: -1,
+		},
+
+		"",
+	},
+
+	// golang.org/issue/4767: don't special-case multipart/byteranges responses
+	{
+		`HTTP/1.1 206 Partial Content
+Connection: close
+Content-Type: multipart/byteranges; boundary=18a75608c8f47cef
+
+some body`,
+		Response{
+			Status:     "206 Partial Content",
+			StatusCode: 206,
+			Proto:      "HTTP/1.1",
+			ProtoMajor: 1,
+			ProtoMinor: 1,
+			Request:    dummyReq("GET"),
+			Header: Header{
+				"Content-Type": []string{"multipart/byteranges; boundary=18a75608c8f47cef"},
+			},
+			Close:         true,
+			ContentLength: -1,
+		},
+
+		"some body",
+	},
+
+	// Unchunked response without Content-Length, Request is nil
+	{
+		"HTTP/1.0 200 OK\r\n" +
+			"Connection: close\r\n" +
+			"\r\n" +
+			"Body here\n",
+
+		Response{
+			Status:     "200 OK",
+			StatusCode: 200,
+			Proto:      "HTTP/1.0",
+			ProtoMajor: 1,
+			ProtoMinor: 0,
+			Header: Header{
+				"Connection": {"close"}, // TODO(rsc): Delete?
+			},
+			Close:         true,
+			ContentLength: -1,
+		},
+
+		"Body here\n",
+	},
+
+	// 206 Partial Content. golang.org/issue/8923
+	{
+		"HTTP/1.1 206 Partial Content\r\n" +
+			"Content-Type: text/plain; charset=utf-8\r\n" +
+			"Accept-Ranges: bytes\r\n" +
+			"Content-Range: bytes 0-5/1862\r\n" +
+			"Content-Length: 6\r\n\r\n" +
+			"foobar",
+
+		Response{
+			Status:     "206 Partial Content",
+			StatusCode: 206,
+			Proto:      "HTTP/1.1",
+			ProtoMajor: 1,
+			ProtoMinor: 1,
+			Request:    dummyReq("GET"),
+			Header: Header{
+				"Accept-Ranges":  []string{"bytes"},
+				"Content-Length": []string{"6"},
+				"Content-Type":   []string{"text/plain; charset=utf-8"},
+				"Content-Range":  []string{"bytes 0-5/1862"},
+			},
+			ContentLength: 6,
+		},
+
+		"foobar",
+	},
+}
+
+func TestReadResponse(t *testing.T) {
+	for i, tt := range respTests {
+		resp, err := ReadResponse(bufio.NewReader(strings.NewReader(tt.Raw)), tt.Resp.Request)
+		if err != nil {
+			t.Errorf("#%d: %v", i, err)
+			continue
+		}
+		rbody := resp.Body
+		resp.Body = nil
+		diff(t, fmt.Sprintf("#%d Response", i), resp, &tt.Resp)
+		var bout bytes.Buffer
+		if rbody != nil {
+			_, err = io.Copy(&bout, rbody)
+			if err != nil {
+				t.Errorf("#%d: %v", i, err)
+				continue
+			}
+			rbody.Close()
+		}
+		body := bout.String()
+		if body != tt.Body {
+			t.Errorf("#%d: Body = %q want %q", i, body, tt.Body)
+		}
+	}
+}
+
+func TestWriteResponse(t *testing.T) {
+	for i, tt := range respTests {
+		resp, err := ReadResponse(bufio.NewReader(strings.NewReader(tt.Raw)), tt.Resp.Request)
+		if err != nil {
+			t.Errorf("#%d: %v", i, err)
+			continue
+		}
+		err = resp.Write(ioutil.Discard)
+		if err != nil {
+			t.Errorf("#%d: %v", i, err)
+			continue
+		}
+	}
+}
+
+var readResponseCloseInMiddleTests = []struct {
+	chunked, compressed bool
+}{
+	{false, false},
+	{true, false},
+	{true, true},
+}
+
+// TestReadResponseCloseInMiddle tests that closing a body after
+// reading only part of its contents advances the read to the end of
+// the request, right up until the next request.
+func TestReadResponseCloseInMiddle(t *testing.T) {
+	for _, test := range readResponseCloseInMiddleTests {
+		fatalf := func(format string, args ...interface{}) {
+			args = append([]interface{}{test.chunked, test.compressed}, args...)
+			t.Fatalf("on test chunked=%v, compressed=%v: "+format, args...)
+		}
+		checkErr := func(err error, msg string) {
+			if err == nil {
+				return
+			}
+			fatalf(msg+": %v", err)
+		}
+		var buf bytes.Buffer
+		buf.WriteString("HTTP/1.1 200 OK\r\n")
+		if test.chunked {
+			buf.WriteString("Transfer-Encoding: chunked\r\n")
+		} else {
+			buf.WriteString("Content-Length: 1000000\r\n")
+		}
+		var wr io.Writer = &buf
+		if test.chunked {
+			wr = internal.NewChunkedWriter(wr)
+		}
+		if test.compressed {
+			buf.WriteString("Content-Encoding: gzip\r\n")
+			wr = gzip.NewWriter(wr)
+		}
+		buf.WriteString("\r\n")
+
+		chunk := bytes.Repeat([]byte{'x'}, 1000)
+		for i := 0; i < 1000; i++ {
+			if test.compressed {
+				// Otherwise this compresses too well.
+				_, err := io.ReadFull(rand.Reader, chunk)
+				checkErr(err, "rand.Reader ReadFull")
+			}
+			wr.Write(chunk)
+		}
+		if test.compressed {
+			err := wr.(*gzip.Writer).Close()
+			checkErr(err, "compressor close")
+		}
+		if test.chunked {
+			buf.WriteString("0\r\n\r\n")
+		}
+		buf.WriteString("Next Request Here")
+
+		bufr := bufio.NewReader(&buf)
+		resp, err := ReadResponse(bufr, dummyReq("GET"))
+		checkErr(err, "ReadResponse")
+		expectedLength := int64(-1)
+		if !test.chunked {
+			expectedLength = 1000000
+		}
+		if resp.ContentLength != expectedLength {
+			fatalf("expected response length %d, got %d", expectedLength, resp.ContentLength)
+		}
+		if resp.Body == nil {
+			fatalf("nil body")
+		}
+		if test.compressed {
+			gzReader, err := gzip.NewReader(resp.Body)
+			checkErr(err, "gzip.NewReader")
+			resp.Body = &readerAndCloser{gzReader, resp.Body}
+		}
+
+		rbuf := make([]byte, 2500)
+		n, err := io.ReadFull(resp.Body, rbuf)
+		checkErr(err, "2500 byte ReadFull")
+		if n != 2500 {
+			fatalf("ReadFull only read %d bytes", n)
+		}
+		if test.compressed == false && !bytes.Equal(bytes.Repeat([]byte{'x'}, 2500), rbuf) {
+			fatalf("ReadFull didn't read 2500 'x'; got %q", string(rbuf))
+		}
+		resp.Body.Close()
+
+		rest, err := ioutil.ReadAll(bufr)
+		checkErr(err, "ReadAll on remainder")
+		if e, g := "Next Request Here", string(rest); e != g {
+			g = regexp.MustCompile(`(xx+)`).ReplaceAllStringFunc(g, func(match string) string {
+				return fmt.Sprintf("x(repeated x%d)", len(match))
+			})
+			fatalf("remainder = %q, expected %q", g, e)
+		}
+	}
+}
+
+func diff(t *testing.T, prefix string, have, want interface{}) {
+	hv := reflect.ValueOf(have).Elem()
+	wv := reflect.ValueOf(want).Elem()
+	if hv.Type() != wv.Type() {
+		t.Errorf("%s: type mismatch %v want %v", prefix, hv.Type(), wv.Type())
+	}
+	for i := 0; i < hv.NumField(); i++ {
+		hf := hv.Field(i).Interface()
+		wf := wv.Field(i).Interface()
+		if !reflect.DeepEqual(hf, wf) {
+			t.Errorf("%s: %s = %v want %v", prefix, hv.Type().Field(i).Name, hf, wf)
+		}
+	}
+}
+
+type responseLocationTest struct {
+	location string // Response's Location header or ""
+	requrl   string // Response.Request.URL or ""
+	want     string
+	wantErr  error
+}
+
+var responseLocationTests = []responseLocationTest{
+	{"/foo", "http://bar.com/baz", "http://bar.com/foo", nil},
+	{"http://foo.com/", "http://bar.com/baz", "http://foo.com/", nil},
+	{"", "http://bar.com/baz", "", ErrNoLocation},
+}
+
+func TestLocationResponse(t *testing.T) {
+	for i, tt := range responseLocationTests {
+		res := new(Response)
+		res.Header = make(Header)
+		res.Header.Set("Location", tt.location)
+		if tt.requrl != "" {
+			res.Request = &Request{}
+			var err error
+			res.Request.URL, err = url.Parse(tt.requrl)
+			if err != nil {
+				t.Fatalf("bad test URL %q: %v", tt.requrl, err)
+			}
+		}
+
+		got, err := res.Location()
+		if tt.wantErr != nil {
+			if err == nil {
+				t.Errorf("%d. err=nil; want %q", i, tt.wantErr)
+				continue
+			}
+			if g, e := err.Error(), tt.wantErr.Error(); g != e {
+				t.Errorf("%d. err=%q; want %q", i, g, e)
+				continue
+			}
+			continue
+		}
+		if err != nil {
+			t.Errorf("%d. err=%q", i, err)
+			continue
+		}
+		if g, e := got.String(), tt.want; g != e {
+			t.Errorf("%d. Location=%q; want %q", i, g, e)
+		}
+	}
+}
+
+func TestResponseStatusStutter(t *testing.T) {
+	r := &Response{
+		Status:     "123 some status",
+		StatusCode: 123,
+		ProtoMajor: 1,
+		ProtoMinor: 3,
+	}
+	var buf bytes.Buffer
+	r.Write(&buf)
+	if strings.Contains(buf.String(), "123 123") {
+		t.Errorf("stutter in status: %s", buf.String())
+	}
+}
+
+func TestResponseContentLengthShortBody(t *testing.T) {
+	const shortBody = "Short body, not 123 bytes."
+	br := bufio.NewReader(strings.NewReader("HTTP/1.1 200 OK\r\n" +
+		"Content-Length: 123\r\n" +
+		"\r\n" +
+		shortBody))
+	res, err := ReadResponse(br, &Request{Method: "GET"})
+	if err != nil {
+		t.Fatal(err)
+	}
+	if res.ContentLength != 123 {
+		t.Fatalf("Content-Length = %d; want 123", res.ContentLength)
+	}
+	var buf bytes.Buffer
+	n, err := io.Copy(&buf, res.Body)
+	if n != int64(len(shortBody)) {
+		t.Errorf("Copied %d bytes; want %d, len(%q)", n, len(shortBody), shortBody)
+	}
+	if buf.String() != shortBody {
+		t.Errorf("Read body %q; want %q", buf.String(), shortBody)
+	}
+	if err != io.ErrUnexpectedEOF {
+		t.Errorf("io.Copy error = %#v; want io.ErrUnexpectedEOF", err)
+	}
+}
+
+func TestReadResponseUnexpectedEOF(t *testing.T) {
+	br := bufio.NewReader(strings.NewReader("HTTP/1.1 301 Moved Permanently\r\n" +
+		"Location: http://example.com"))
+	_, err := ReadResponse(br, nil)
+	if err != io.ErrUnexpectedEOF {
+		t.Errorf("ReadResponse = %v; want io.ErrUnexpectedEOF", err)
+	}
+}
+
+func TestNeedsSniff(t *testing.T) {
+	// needsSniff returns true with an empty response.
+	r := &response{}
+	if got, want := r.needsSniff(), true; got != want {
+		t.Errorf("needsSniff = %t; want %t", got, want)
+	}
+	// needsSniff returns false when Content-Type = nil.
+	r.handlerHeader = Header{"Content-Type": nil}
+	if got, want := r.needsSniff(), false; got != want {
+		t.Errorf("needsSniff empty Content-Type = %t; want %t", got, want)
+	}
+}
diff --git a/src/pkg/net/http/responsewrite_test.go b/src/net/http/responsewrite_test.go
similarity index 100%
rename from src/pkg/net/http/responsewrite_test.go
rename to src/net/http/responsewrite_test.go
diff --git a/src/net/http/serve_test.go b/src/net/http/serve_test.go
new file mode 100644
index 0000000..5e0a005
--- /dev/null
+++ b/src/net/http/serve_test.go
@@ -0,0 +1,3094 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// End-to-end serving tests
+
+package http_test
+
+import (
+	"bufio"
+	"bytes"
+	"crypto/tls"
+	"errors"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"log"
+	"math/rand"
+	"net"
+	. "net/http"
+	"net/http/httptest"
+	"net/http/httputil"
+	"net/url"
+	"os"
+	"os/exec"
+	"reflect"
+	"runtime"
+	"strconv"
+	"strings"
+	"sync"
+	"sync/atomic"
+	"syscall"
+	"testing"
+	"time"
+)
+
+type dummyAddr string
+type oneConnListener struct {
+	conn net.Conn
+}
+
+func (l *oneConnListener) Accept() (c net.Conn, err error) {
+	c = l.conn
+	if c == nil {
+		err = io.EOF
+		return
+	}
+	err = nil
+	l.conn = nil
+	return
+}
+
+func (l *oneConnListener) Close() error {
+	return nil
+}
+
+func (l *oneConnListener) Addr() net.Addr {
+	return dummyAddr("test-address")
+}
+
+func (a dummyAddr) Network() string {
+	return string(a)
+}
+
+func (a dummyAddr) String() string {
+	return string(a)
+}
+
+type noopConn struct{}
+
+func (noopConn) LocalAddr() net.Addr                { return dummyAddr("local-addr") }
+func (noopConn) RemoteAddr() net.Addr               { return dummyAddr("remote-addr") }
+func (noopConn) SetDeadline(t time.Time) error      { return nil }
+func (noopConn) SetReadDeadline(t time.Time) error  { return nil }
+func (noopConn) SetWriteDeadline(t time.Time) error { return nil }
+
+type rwTestConn struct {
+	io.Reader
+	io.Writer
+	noopConn
+
+	closeFunc func() error // called if non-nil
+	closec    chan bool    // else, if non-nil, send value to it on close
+}
+
+func (c *rwTestConn) Close() error {
+	if c.closeFunc != nil {
+		return c.closeFunc()
+	}
+	select {
+	case c.closec <- true:
+	default:
+	}
+	return nil
+}
+
+type testConn struct {
+	readBuf  bytes.Buffer
+	writeBuf bytes.Buffer
+	closec   chan bool // if non-nil, send value to it on close
+	noopConn
+}
+
+func (c *testConn) Read(b []byte) (int, error) {
+	return c.readBuf.Read(b)
+}
+
+func (c *testConn) Write(b []byte) (int, error) {
+	return c.writeBuf.Write(b)
+}
+
+func (c *testConn) Close() error {
+	select {
+	case c.closec <- true:
+	default:
+	}
+	return nil
+}
+
+// reqBytes treats req as a request (with \n delimiters) and returns it with \r\n delimiters,
+// ending in \r\n\r\n
+func reqBytes(req string) []byte {
+	return []byte(strings.Replace(strings.TrimSpace(req), "\n", "\r\n", -1) + "\r\n\r\n")
+}
+
+type handlerTest struct {
+	handler Handler
+}
+
+func newHandlerTest(h Handler) handlerTest {
+	return handlerTest{h}
+}
+
+func (ht handlerTest) rawResponse(req string) string {
+	reqb := reqBytes(req)
+	var output bytes.Buffer
+	conn := &rwTestConn{
+		Reader: bytes.NewReader(reqb),
+		Writer: &output,
+		closec: make(chan bool, 1),
+	}
+	ln := &oneConnListener{conn: conn}
+	go Serve(ln, ht.handler)
+	<-conn.closec
+	return output.String()
+}
+
+func TestConsumingBodyOnNextConn(t *testing.T) {
+	conn := new(testConn)
+	for i := 0; i < 2; i++ {
+		conn.readBuf.Write([]byte(
+			"POST / HTTP/1.1\r\n" +
+				"Host: test\r\n" +
+				"Content-Length: 11\r\n" +
+				"\r\n" +
+				"foo=1&bar=1"))
+	}
+
+	reqNum := 0
+	ch := make(chan *Request)
+	servech := make(chan error)
+	listener := &oneConnListener{conn}
+	handler := func(res ResponseWriter, req *Request) {
+		reqNum++
+		ch <- req
+	}
+
+	go func() {
+		servech <- Serve(listener, HandlerFunc(handler))
+	}()
+
+	var req *Request
+	req = <-ch
+	if req == nil {
+		t.Fatal("Got nil first request.")
+	}
+	if req.Method != "POST" {
+		t.Errorf("For request #1's method, got %q; expected %q",
+			req.Method, "POST")
+	}
+
+	req = <-ch
+	if req == nil {
+		t.Fatal("Got nil first request.")
+	}
+	if req.Method != "POST" {
+		t.Errorf("For request #2's method, got %q; expected %q",
+			req.Method, "POST")
+	}
+
+	if serveerr := <-servech; serveerr != io.EOF {
+		t.Errorf("Serve returned %q; expected EOF", serveerr)
+	}
+}
+
+type stringHandler string
+
+func (s stringHandler) ServeHTTP(w ResponseWriter, r *Request) {
+	w.Header().Set("Result", string(s))
+}
+
+var handlers = []struct {
+	pattern string
+	msg     string
+}{
+	{"/", "Default"},
+	{"/someDir/", "someDir"},
+	{"someHost.com/someDir/", "someHost.com/someDir"},
+}
+
+var vtests = []struct {
+	url      string
+	expected string
+}{
+	{"http://localhost/someDir/apage", "someDir"},
+	{"http://localhost/otherDir/apage", "Default"},
+	{"http://someHost.com/someDir/apage", "someHost.com/someDir"},
+	{"http://otherHost.com/someDir/apage", "someDir"},
+	{"http://otherHost.com/aDir/apage", "Default"},
+	// redirections for trees
+	{"http://localhost/someDir", "/someDir/"},
+	{"http://someHost.com/someDir", "/someDir/"},
+}
+
+func TestHostHandlers(t *testing.T) {
+	defer afterTest(t)
+	mux := NewServeMux()
+	for _, h := range handlers {
+		mux.Handle(h.pattern, stringHandler(h.msg))
+	}
+	ts := httptest.NewServer(mux)
+	defer ts.Close()
+
+	conn, err := net.Dial("tcp", ts.Listener.Addr().String())
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer conn.Close()
+	cc := httputil.NewClientConn(conn, nil)
+	for _, vt := range vtests {
+		var r *Response
+		var req Request
+		if req.URL, err = url.Parse(vt.url); err != nil {
+			t.Errorf("cannot parse url: %v", err)
+			continue
+		}
+		if err := cc.Write(&req); err != nil {
+			t.Errorf("writing request: %v", err)
+			continue
+		}
+		r, err := cc.Read(&req)
+		if err != nil {
+			t.Errorf("reading response: %v", err)
+			continue
+		}
+		switch r.StatusCode {
+		case StatusOK:
+			s := r.Header.Get("Result")
+			if s != vt.expected {
+				t.Errorf("Get(%q) = %q, want %q", vt.url, s, vt.expected)
+			}
+		case StatusMovedPermanently:
+			s := r.Header.Get("Location")
+			if s != vt.expected {
+				t.Errorf("Get(%q) = %q, want %q", vt.url, s, vt.expected)
+			}
+		default:
+			t.Errorf("Get(%q) unhandled status code %d", vt.url, r.StatusCode)
+		}
+	}
+}
+
+var serveMuxRegister = []struct {
+	pattern string
+	h       Handler
+}{
+	{"/dir/", serve(200)},
+	{"/search", serve(201)},
+	{"codesearch.google.com/search", serve(202)},
+	{"codesearch.google.com/", serve(203)},
+	{"example.com/", HandlerFunc(checkQueryStringHandler)},
+}
+
+// serve returns a handler that sends a response with the given code.
+func serve(code int) HandlerFunc {
+	return func(w ResponseWriter, r *Request) {
+		w.WriteHeader(code)
+	}
+}
+
+// checkQueryStringHandler checks if r.URL.RawQuery has the same value
+// as the URL excluding the scheme and the query string and sends 200
+// response code if it is, 500 otherwise.
+func checkQueryStringHandler(w ResponseWriter, r *Request) {
+	u := *r.URL
+	u.Scheme = "http"
+	u.Host = r.Host
+	u.RawQuery = ""
+	if "http://"+r.URL.RawQuery == u.String() {
+		w.WriteHeader(200)
+	} else {
+		w.WriteHeader(500)
+	}
+}
+
+var serveMuxTests = []struct {
+	method  string
+	host    string
+	path    string
+	code    int
+	pattern string
+}{
+	{"GET", "google.com", "/", 404, ""},
+	{"GET", "google.com", "/dir", 301, "/dir/"},
+	{"GET", "google.com", "/dir/", 200, "/dir/"},
+	{"GET", "google.com", "/dir/file", 200, "/dir/"},
+	{"GET", "google.com", "/search", 201, "/search"},
+	{"GET", "google.com", "/search/", 404, ""},
+	{"GET", "google.com", "/search/foo", 404, ""},
+	{"GET", "codesearch.google.com", "/search", 202, "codesearch.google.com/search"},
+	{"GET", "codesearch.google.com", "/search/", 203, "codesearch.google.com/"},
+	{"GET", "codesearch.google.com", "/search/foo", 203, "codesearch.google.com/"},
+	{"GET", "codesearch.google.com", "/", 203, "codesearch.google.com/"},
+	{"GET", "images.google.com", "/search", 201, "/search"},
+	{"GET", "images.google.com", "/search/", 404, ""},
+	{"GET", "images.google.com", "/search/foo", 404, ""},
+	{"GET", "google.com", "/../search", 301, "/search"},
+	{"GET", "google.com", "/dir/..", 301, ""},
+	{"GET", "google.com", "/dir/..", 301, ""},
+	{"GET", "google.com", "/dir/./file", 301, "/dir/"},
+
+	// The /foo -> /foo/ redirect applies to CONNECT requests
+	// but the path canonicalization does not.
+	{"CONNECT", "google.com", "/dir", 301, "/dir/"},
+	{"CONNECT", "google.com", "/../search", 404, ""},
+	{"CONNECT", "google.com", "/dir/..", 200, "/dir/"},
+	{"CONNECT", "google.com", "/dir/..", 200, "/dir/"},
+	{"CONNECT", "google.com", "/dir/./file", 200, "/dir/"},
+}
+
+func TestServeMuxHandler(t *testing.T) {
+	mux := NewServeMux()
+	for _, e := range serveMuxRegister {
+		mux.Handle(e.pattern, e.h)
+	}
+
+	for _, tt := range serveMuxTests {
+		r := &Request{
+			Method: tt.method,
+			Host:   tt.host,
+			URL: &url.URL{
+				Path: tt.path,
+			},
+		}
+		h, pattern := mux.Handler(r)
+		rr := httptest.NewRecorder()
+		h.ServeHTTP(rr, r)
+		if pattern != tt.pattern || rr.Code != tt.code {
+			t.Errorf("%s %s %s = %d, %q, want %d, %q", tt.method, tt.host, tt.path, rr.Code, pattern, tt.code, tt.pattern)
+		}
+	}
+}
+
+var serveMuxTests2 = []struct {
+	method  string
+	host    string
+	url     string
+	code    int
+	redirOk bool
+}{
+	{"GET", "google.com", "/", 404, false},
+	{"GET", "example.com", "/test/?example.com/test/", 200, false},
+	{"GET", "example.com", "test/?example.com/test/", 200, true},
+}
+
+// TestServeMuxHandlerRedirects tests that automatic redirects generated by
+// mux.Handler() shouldn't clear the request's query string.
+func TestServeMuxHandlerRedirects(t *testing.T) {
+	mux := NewServeMux()
+	for _, e := range serveMuxRegister {
+		mux.Handle(e.pattern, e.h)
+	}
+
+	for _, tt := range serveMuxTests2 {
+		tries := 1
+		turl := tt.url
+		for tries > 0 {
+			u, e := url.Parse(turl)
+			if e != nil {
+				t.Fatal(e)
+			}
+			r := &Request{
+				Method: tt.method,
+				Host:   tt.host,
+				URL:    u,
+			}
+			h, _ := mux.Handler(r)
+			rr := httptest.NewRecorder()
+			h.ServeHTTP(rr, r)
+			if rr.Code != 301 {
+				if rr.Code != tt.code {
+					t.Errorf("%s %s %s = %d, want %d", tt.method, tt.host, tt.url, rr.Code, tt.code)
+				}
+				break
+			}
+			if !tt.redirOk {
+				t.Errorf("%s %s %s, unexpected redirect", tt.method, tt.host, tt.url)
+				break
+			}
+			turl = rr.HeaderMap.Get("Location")
+			tries--
+		}
+		if tries < 0 {
+			t.Errorf("%s %s %s, too many redirects", tt.method, tt.host, tt.url)
+		}
+	}
+}
+
+// Tests for http://code.google.com/p/go/issues/detail?id=900
+func TestMuxRedirectLeadingSlashes(t *testing.T) {
+	paths := []string{"//foo.txt", "///foo.txt", "/../../foo.txt"}
+	for _, path := range paths {
+		req, err := ReadRequest(bufio.NewReader(strings.NewReader("GET " + path + " HTTP/1.1\r\nHost: test\r\n\r\n")))
+		if err != nil {
+			t.Errorf("%s", err)
+		}
+		mux := NewServeMux()
+		resp := httptest.NewRecorder()
+
+		mux.ServeHTTP(resp, req)
+
+		if loc, expected := resp.Header().Get("Location"), "/foo.txt"; loc != expected {
+			t.Errorf("Expected Location header set to %q; got %q", expected, loc)
+			return
+		}
+
+		if code, expected := resp.Code, StatusMovedPermanently; code != expected {
+			t.Errorf("Expected response code of StatusMovedPermanently; got %d", code)
+			return
+		}
+	}
+}
+
+func TestServerTimeouts(t *testing.T) {
+	if runtime.GOOS == "plan9" {
+		t.Skip("skipping test; see http://golang.org/issue/7237")
+	}
+	defer afterTest(t)
+	reqNum := 0
+	ts := httptest.NewUnstartedServer(HandlerFunc(func(res ResponseWriter, req *Request) {
+		reqNum++
+		fmt.Fprintf(res, "req=%d", reqNum)
+	}))
+	ts.Config.ReadTimeout = 250 * time.Millisecond
+	ts.Config.WriteTimeout = 250 * time.Millisecond
+	ts.Start()
+	defer ts.Close()
+
+	// Hit the HTTP server successfully.
+	tr := &Transport{DisableKeepAlives: true} // they interfere with this test
+	defer tr.CloseIdleConnections()
+	c := &Client{Transport: tr}
+	r, err := c.Get(ts.URL)
+	if err != nil {
+		t.Fatalf("http Get #1: %v", err)
+	}
+	got, _ := ioutil.ReadAll(r.Body)
+	expected := "req=1"
+	if string(got) != expected {
+		t.Errorf("Unexpected response for request #1; got %q; expected %q",
+			string(got), expected)
+	}
+
+	// Slow client that should timeout.
+	t1 := time.Now()
+	conn, err := net.Dial("tcp", ts.Listener.Addr().String())
+	if err != nil {
+		t.Fatalf("Dial: %v", err)
+	}
+	buf := make([]byte, 1)
+	n, err := conn.Read(buf)
+	latency := time.Since(t1)
+	if n != 0 || err != io.EOF {
+		t.Errorf("Read = %v, %v, wanted %v, %v", n, err, 0, io.EOF)
+	}
+	if latency < 200*time.Millisecond /* fudge from 250 ms above */ {
+		t.Errorf("got EOF after %s, want >= %s", latency, 200*time.Millisecond)
+	}
+
+	// Hit the HTTP server successfully again, verifying that the
+	// previous slow connection didn't run our handler.  (that we
+	// get "req=2", not "req=3")
+	r, err = Get(ts.URL)
+	if err != nil {
+		t.Fatalf("http Get #2: %v", err)
+	}
+	got, _ = ioutil.ReadAll(r.Body)
+	expected = "req=2"
+	if string(got) != expected {
+		t.Errorf("Get #2 got %q, want %q", string(got), expected)
+	}
+
+	if !testing.Short() {
+		conn, err := net.Dial("tcp", ts.Listener.Addr().String())
+		if err != nil {
+			t.Fatalf("Dial: %v", err)
+		}
+		defer conn.Close()
+		go io.Copy(ioutil.Discard, conn)
+		for i := 0; i < 5; i++ {
+			_, err := conn.Write([]byte("GET / HTTP/1.1\r\nHost: foo\r\n\r\n"))
+			if err != nil {
+				t.Fatalf("on write %d: %v", i, err)
+			}
+			time.Sleep(ts.Config.ReadTimeout / 2)
+		}
+	}
+}
+
+// golang.org/issue/4741 -- setting only a write timeout that triggers
+// shouldn't cause a handler to block forever on reads (next HTTP
+// request) that will never happen.
+func TestOnlyWriteTimeout(t *testing.T) {
+	if runtime.GOOS == "plan9" {
+		t.Skip("skipping test; see http://golang.org/issue/7237")
+	}
+	defer afterTest(t)
+	var conn net.Conn
+	var afterTimeoutErrc = make(chan error, 1)
+	ts := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, req *Request) {
+		buf := make([]byte, 512<<10)
+		_, err := w.Write(buf)
+		if err != nil {
+			t.Errorf("handler Write error: %v", err)
+			return
+		}
+		conn.SetWriteDeadline(time.Now().Add(-30 * time.Second))
+		_, err = w.Write(buf)
+		afterTimeoutErrc <- err
+	}))
+	ts.Listener = trackLastConnListener{ts.Listener, &conn}
+	ts.Start()
+	defer ts.Close()
+
+	tr := &Transport{DisableKeepAlives: false}
+	defer tr.CloseIdleConnections()
+	c := &Client{Transport: tr}
+
+	errc := make(chan error)
+	go func() {
+		res, err := c.Get(ts.URL)
+		if err != nil {
+			errc <- err
+			return
+		}
+		_, err = io.Copy(ioutil.Discard, res.Body)
+		errc <- err
+	}()
+	select {
+	case err := <-errc:
+		if err == nil {
+			t.Errorf("expected an error from Get request")
+		}
+	case <-time.After(5 * time.Second):
+		t.Fatal("timeout waiting for Get error")
+	}
+	if err := <-afterTimeoutErrc; err == nil {
+		t.Error("expected write error after timeout")
+	}
+}
+
+// trackLastConnListener tracks the last net.Conn that was accepted.
+type trackLastConnListener struct {
+	net.Listener
+	last *net.Conn // destination
+}
+
+func (l trackLastConnListener) Accept() (c net.Conn, err error) {
+	c, err = l.Listener.Accept()
+	*l.last = c
+	return
+}
+
+// TestIdentityResponse verifies that a handler can unset
+func TestIdentityResponse(t *testing.T) {
+	defer afterTest(t)
+	handler := HandlerFunc(func(rw ResponseWriter, req *Request) {
+		rw.Header().Set("Content-Length", "3")
+		rw.Header().Set("Transfer-Encoding", req.FormValue("te"))
+		switch {
+		case req.FormValue("overwrite") == "1":
+			_, err := rw.Write([]byte("foo TOO LONG"))
+			if err != ErrContentLength {
+				t.Errorf("expected ErrContentLength; got %v", err)
+			}
+		case req.FormValue("underwrite") == "1":
+			rw.Header().Set("Content-Length", "500")
+			rw.Write([]byte("too short"))
+		default:
+			rw.Write([]byte("foo"))
+		}
+	})
+
+	ts := httptest.NewServer(handler)
+	defer ts.Close()
+
+	// Note: this relies on the assumption (which is true) that
+	// Get sends HTTP/1.1 or greater requests.  Otherwise the
+	// server wouldn't have the choice to send back chunked
+	// responses.
+	for _, te := range []string{"", "identity"} {
+		url := ts.URL + "/?te=" + te
+		res, err := Get(url)
+		if err != nil {
+			t.Fatalf("error with Get of %s: %v", url, err)
+		}
+		if cl, expected := res.ContentLength, int64(3); cl != expected {
+			t.Errorf("for %s expected res.ContentLength of %d; got %d", url, expected, cl)
+		}
+		if cl, expected := res.Header.Get("Content-Length"), "3"; cl != expected {
+			t.Errorf("for %s expected Content-Length header of %q; got %q", url, expected, cl)
+		}
+		if tl, expected := len(res.TransferEncoding), 0; tl != expected {
+			t.Errorf("for %s expected len(res.TransferEncoding) of %d; got %d (%v)",
+				url, expected, tl, res.TransferEncoding)
+		}
+		res.Body.Close()
+	}
+
+	// Verify that ErrContentLength is returned
+	url := ts.URL + "/?overwrite=1"
+	res, err := Get(url)
+	if err != nil {
+		t.Fatalf("error with Get of %s: %v", url, err)
+	}
+	res.Body.Close()
+
+	// Verify that the connection is closed when the declared Content-Length
+	// is larger than what the handler wrote.
+	conn, err := net.Dial("tcp", ts.Listener.Addr().String())
+	if err != nil {
+		t.Fatalf("error dialing: %v", err)
+	}
+	_, err = conn.Write([]byte("GET /?underwrite=1 HTTP/1.1\r\nHost: foo\r\n\r\n"))
+	if err != nil {
+		t.Fatalf("error writing: %v", err)
+	}
+
+	// The ReadAll will hang for a failing test, so use a Timer to
+	// fail explicitly.
+	goTimeout(t, 2*time.Second, func() {
+		got, _ := ioutil.ReadAll(conn)
+		expectedSuffix := "\r\n\r\ntoo short"
+		if !strings.HasSuffix(string(got), expectedSuffix) {
+			t.Errorf("Expected output to end with %q; got response body %q",
+				expectedSuffix, string(got))
+		}
+	})
+}
+
+func testTCPConnectionCloses(t *testing.T, req string, h Handler) {
+	defer afterTest(t)
+	s := httptest.NewServer(h)
+	defer s.Close()
+
+	conn, err := net.Dial("tcp", s.Listener.Addr().String())
+	if err != nil {
+		t.Fatal("dial error:", err)
+	}
+	defer conn.Close()
+
+	_, err = fmt.Fprint(conn, req)
+	if err != nil {
+		t.Fatal("print error:", err)
+	}
+
+	r := bufio.NewReader(conn)
+	res, err := ReadResponse(r, &Request{Method: "GET"})
+	if err != nil {
+		t.Fatal("ReadResponse error:", err)
+	}
+
+	didReadAll := make(chan bool, 1)
+	go func() {
+		select {
+		case <-time.After(5 * time.Second):
+			t.Error("body not closed after 5s")
+			return
+		case <-didReadAll:
+		}
+	}()
+
+	_, err = ioutil.ReadAll(r)
+	if err != nil {
+		t.Fatal("read error:", err)
+	}
+	didReadAll <- true
+
+	if !res.Close {
+		t.Errorf("Response.Close = false; want true")
+	}
+}
+
+// TestServeHTTP10Close verifies that HTTP/1.0 requests won't be kept alive.
+func TestServeHTTP10Close(t *testing.T) {
+	testTCPConnectionCloses(t, "GET / HTTP/1.0\r\n\r\n", HandlerFunc(func(w ResponseWriter, r *Request) {
+		ServeFile(w, r, "testdata/file")
+	}))
+}
+
+// TestClientCanClose verifies that clients can also force a connection to close.
+func TestClientCanClose(t *testing.T) {
+	testTCPConnectionCloses(t, "GET / HTTP/1.1\r\nConnection: close\r\n\r\n", HandlerFunc(func(w ResponseWriter, r *Request) {
+		// Nothing.
+	}))
+}
+
+// TestHandlersCanSetConnectionClose verifies that handlers can force a connection to close,
+// even for HTTP/1.1 requests.
+func TestHandlersCanSetConnectionClose11(t *testing.T) {
+	testTCPConnectionCloses(t, "GET / HTTP/1.1\r\n\r\n", HandlerFunc(func(w ResponseWriter, r *Request) {
+		w.Header().Set("Connection", "close")
+	}))
+}
+
+func TestHandlersCanSetConnectionClose10(t *testing.T) {
+	testTCPConnectionCloses(t, "GET / HTTP/1.0\r\nConnection: keep-alive\r\n\r\n", HandlerFunc(func(w ResponseWriter, r *Request) {
+		w.Header().Set("Connection", "close")
+	}))
+}
+
+func TestSetsRemoteAddr(t *testing.T) {
+	defer afterTest(t)
+	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+		fmt.Fprintf(w, "%s", r.RemoteAddr)
+	}))
+	defer ts.Close()
+
+	res, err := Get(ts.URL)
+	if err != nil {
+		t.Fatalf("Get error: %v", err)
+	}
+	body, err := ioutil.ReadAll(res.Body)
+	if err != nil {
+		t.Fatalf("ReadAll error: %v", err)
+	}
+	ip := string(body)
+	if !strings.HasPrefix(ip, "127.0.0.1:") && !strings.HasPrefix(ip, "[::1]:") {
+		t.Fatalf("Expected local addr; got %q", ip)
+	}
+}
+
+func TestChunkedResponseHeaders(t *testing.T) {
+	defer afterTest(t)
+	log.SetOutput(ioutil.Discard) // is noisy otherwise
+	defer log.SetOutput(os.Stderr)
+
+	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+		w.Header().Set("Content-Length", "intentional gibberish") // we check that this is deleted
+		w.(Flusher).Flush()
+		fmt.Fprintf(w, "I am a chunked response.")
+	}))
+	defer ts.Close()
+
+	res, err := Get(ts.URL)
+	if err != nil {
+		t.Fatalf("Get error: %v", err)
+	}
+	defer res.Body.Close()
+	if g, e := res.ContentLength, int64(-1); g != e {
+		t.Errorf("expected ContentLength of %d; got %d", e, g)
+	}
+	if g, e := res.TransferEncoding, []string{"chunked"}; !reflect.DeepEqual(g, e) {
+		t.Errorf("expected TransferEncoding of %v; got %v", e, g)
+	}
+	if _, haveCL := res.Header["Content-Length"]; haveCL {
+		t.Errorf("Unexpected Content-Length")
+	}
+}
+
+func TestIdentityResponseHeaders(t *testing.T) {
+	defer afterTest(t)
+	log.SetOutput(ioutil.Discard) // is noisy otherwise
+	defer log.SetOutput(os.Stderr)
+
+	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+		w.Header().Set("Transfer-Encoding", "identity")
+		w.(Flusher).Flush()
+		fmt.Fprintf(w, "I am an identity response.")
+	}))
+	defer ts.Close()
+
+	res, err := Get(ts.URL)
+	if err != nil {
+		t.Fatalf("Get error: %v", err)
+	}
+	defer res.Body.Close()
+
+	if g, e := res.TransferEncoding, []string(nil); !reflect.DeepEqual(g, e) {
+		t.Errorf("expected TransferEncoding of %v; got %v", e, g)
+	}
+	if _, haveCL := res.Header["Content-Length"]; haveCL {
+		t.Errorf("Unexpected Content-Length")
+	}
+	if !res.Close {
+		t.Errorf("expected Connection: close; got %v", res.Close)
+	}
+}
+
+// Test304Responses verifies that 304s don't declare that they're
+// chunking in their response headers and aren't allowed to produce
+// output.
+func Test304Responses(t *testing.T) {
+	defer afterTest(t)
+	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+		w.WriteHeader(StatusNotModified)
+		_, err := w.Write([]byte("illegal body"))
+		if err != ErrBodyNotAllowed {
+			t.Errorf("on Write, expected ErrBodyNotAllowed, got %v", err)
+		}
+	}))
+	defer ts.Close()
+	res, err := Get(ts.URL)
+	if err != nil {
+		t.Error(err)
+	}
+	if len(res.TransferEncoding) > 0 {
+		t.Errorf("expected no TransferEncoding; got %v", res.TransferEncoding)
+	}
+	body, err := ioutil.ReadAll(res.Body)
+	if err != nil {
+		t.Error(err)
+	}
+	if len(body) > 0 {
+		t.Errorf("got unexpected body %q", string(body))
+	}
+}
+
+// TestHeadResponses verifies that all MIME type sniffing and Content-Length
+// counting of GET requests also happens on HEAD requests.
+func TestHeadResponses(t *testing.T) {
+	defer afterTest(t)
+	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+		_, err := w.Write([]byte("<html>"))
+		if err != nil {
+			t.Errorf("ResponseWriter.Write: %v", err)
+		}
+
+		// Also exercise the ReaderFrom path
+		_, err = io.Copy(w, strings.NewReader("789a"))
+		if err != nil {
+			t.Errorf("Copy(ResponseWriter, ...): %v", err)
+		}
+	}))
+	defer ts.Close()
+	res, err := Head(ts.URL)
+	if err != nil {
+		t.Error(err)
+	}
+	if len(res.TransferEncoding) > 0 {
+		t.Errorf("expected no TransferEncoding; got %v", res.TransferEncoding)
+	}
+	if ct := res.Header.Get("Content-Type"); ct != "text/html; charset=utf-8" {
+		t.Errorf("Content-Type: %q; want text/html; charset=utf-8", ct)
+	}
+	if v := res.ContentLength; v != 10 {
+		t.Errorf("Content-Length: %d; want 10", v)
+	}
+	body, err := ioutil.ReadAll(res.Body)
+	if err != nil {
+		t.Error(err)
+	}
+	if len(body) > 0 {
+		t.Errorf("got unexpected body %q", string(body))
+	}
+}
+
+func TestTLSHandshakeTimeout(t *testing.T) {
+	if runtime.GOOS == "plan9" {
+		t.Skip("skipping test; see http://golang.org/issue/7237")
+	}
+	defer afterTest(t)
+	ts := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, r *Request) {}))
+	errc := make(chanWriter, 10) // but only expecting 1
+	ts.Config.ReadTimeout = 250 * time.Millisecond
+	ts.Config.ErrorLog = log.New(errc, "", 0)
+	ts.StartTLS()
+	defer ts.Close()
+	conn, err := net.Dial("tcp", ts.Listener.Addr().String())
+	if err != nil {
+		t.Fatalf("Dial: %v", err)
+	}
+	defer conn.Close()
+	goTimeout(t, 10*time.Second, func() {
+		var buf [1]byte
+		n, err := conn.Read(buf[:])
+		if err == nil || n != 0 {
+			t.Errorf("Read = %d, %v; want an error and no bytes", n, err)
+		}
+	})
+	select {
+	case v := <-errc:
+		if !strings.Contains(v, "timeout") && !strings.Contains(v, "TLS handshake") {
+			t.Errorf("expected a TLS handshake timeout error; got %q", v)
+		}
+	case <-time.After(5 * time.Second):
+		t.Errorf("timeout waiting for logged error")
+	}
+}
+
+func TestTLSServer(t *testing.T) {
+	defer afterTest(t)
+	ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+		if r.TLS != nil {
+			w.Header().Set("X-TLS-Set", "true")
+			if r.TLS.HandshakeComplete {
+				w.Header().Set("X-TLS-HandshakeComplete", "true")
+			}
+		}
+	}))
+	ts.Config.ErrorLog = log.New(ioutil.Discard, "", 0)
+	defer ts.Close()
+
+	// Connect an idle TCP connection to this server before we run
+	// our real tests.  This idle connection used to block forever
+	// in the TLS handshake, preventing future connections from
+	// being accepted. It may prevent future accidental blocking
+	// in newConn.
+	idleConn, err := net.Dial("tcp", ts.Listener.Addr().String())
+	if err != nil {
+		t.Fatalf("Dial: %v", err)
+	}
+	defer idleConn.Close()
+	goTimeout(t, 10*time.Second, func() {
+		if !strings.HasPrefix(ts.URL, "https://") {
+			t.Errorf("expected test TLS server to start with https://, got %q", ts.URL)
+			return
+		}
+		noVerifyTransport := &Transport{
+			TLSClientConfig: &tls.Config{
+				InsecureSkipVerify: true,
+			},
+		}
+		client := &Client{Transport: noVerifyTransport}
+		res, err := client.Get(ts.URL)
+		if err != nil {
+			t.Error(err)
+			return
+		}
+		if res == nil {
+			t.Errorf("got nil Response")
+			return
+		}
+		defer res.Body.Close()
+		if res.Header.Get("X-TLS-Set") != "true" {
+			t.Errorf("expected X-TLS-Set response header")
+			return
+		}
+		if res.Header.Get("X-TLS-HandshakeComplete") != "true" {
+			t.Errorf("expected X-TLS-HandshakeComplete header")
+		}
+	})
+}
+
+type serverExpectTest struct {
+	contentLength    int // of request body
+	chunked          bool
+	expectation      string // e.g. "100-continue"
+	readBody         bool   // whether handler should read the body (if false, sends StatusUnauthorized)
+	expectedResponse string // expected substring in first line of http response
+}
+
+func expectTest(contentLength int, expectation string, readBody bool, expectedResponse string) serverExpectTest {
+	return serverExpectTest{
+		contentLength:    contentLength,
+		expectation:      expectation,
+		readBody:         readBody,
+		expectedResponse: expectedResponse,
+	}
+}
+
+var serverExpectTests = []serverExpectTest{
+	// Normal 100-continues, case-insensitive.
+	expectTest(100, "100-continue", true, "100 Continue"),
+	expectTest(100, "100-cOntInUE", true, "100 Continue"),
+
+	// No 100-continue.
+	expectTest(100, "", true, "200 OK"),
+
+	// 100-continue but requesting client to deny us,
+	// so it never reads the body.
+	expectTest(100, "100-continue", false, "401 Unauthorized"),
+	// Likewise without 100-continue:
+	expectTest(100, "", false, "401 Unauthorized"),
+
+	// Non-standard expectations are failures
+	expectTest(0, "a-pony", false, "417 Expectation Failed"),
+
+	// Expect-100 requested but no body (is apparently okay: Issue 7625)
+	expectTest(0, "100-continue", true, "200 OK"),
+	// Expect-100 requested but handler doesn't read the body
+	expectTest(0, "100-continue", false, "401 Unauthorized"),
+	// Expect-100 continue with no body, but a chunked body.
+	{
+		expectation:      "100-continue",
+		readBody:         true,
+		chunked:          true,
+		expectedResponse: "100 Continue",
+	},
+}
+
+// Tests that the server responds to the "Expect" request header
+// correctly.
+func TestServerExpect(t *testing.T) {
+	defer afterTest(t)
+	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+		// Note using r.FormValue("readbody") because for POST
+		// requests that would read from r.Body, which we only
+		// conditionally want to do.
+		if strings.Contains(r.URL.RawQuery, "readbody=true") {
+			ioutil.ReadAll(r.Body)
+			w.Write([]byte("Hi"))
+		} else {
+			w.WriteHeader(StatusUnauthorized)
+		}
+	}))
+	defer ts.Close()
+
+	runTest := func(test serverExpectTest) {
+		conn, err := net.Dial("tcp", ts.Listener.Addr().String())
+		if err != nil {
+			t.Fatalf("Dial: %v", err)
+		}
+		defer conn.Close()
+
+		// Only send the body immediately if we're acting like an HTTP client
+		// that doesn't send 100-continue expectations.
+		writeBody := test.contentLength != 0 && strings.ToLower(test.expectation) != "100-continue"
+
+		go func() {
+			contentLen := fmt.Sprintf("Content-Length: %d", test.contentLength)
+			if test.chunked {
+				contentLen = "Transfer-Encoding: chunked"
+			}
+			_, err := fmt.Fprintf(conn, "POST /?readbody=%v HTTP/1.1\r\n"+
+				"Connection: close\r\n"+
+				"%s\r\n"+
+				"Expect: %s\r\nHost: foo\r\n\r\n",
+				test.readBody, contentLen, test.expectation)
+			if err != nil {
+				t.Errorf("On test %#v, error writing request headers: %v", test, err)
+				return
+			}
+			if writeBody {
+				var targ io.WriteCloser = struct {
+					io.Writer
+					io.Closer
+				}{
+					conn,
+					ioutil.NopCloser(nil),
+				}
+				if test.chunked {
+					targ = httputil.NewChunkedWriter(conn)
+				}
+				body := strings.Repeat("A", test.contentLength)
+				_, err = fmt.Fprint(targ, body)
+				if err == nil {
+					err = targ.Close()
+				}
+				if err != nil {
+					if !test.readBody {
+						// Server likely already hung up on us.
+						// See larger comment below.
+						t.Logf("On test %#v, acceptable error writing request body: %v", test, err)
+						return
+					}
+					t.Errorf("On test %#v, error writing request body: %v", test, err)
+				}
+			}
+		}()
+		bufr := bufio.NewReader(conn)
+		line, err := bufr.ReadString('\n')
+		if err != nil {
+			if writeBody && !test.readBody {
+				// This is an acceptable failure due to a possible TCP race:
+				// We were still writing data and the server hung up on us. A TCP
+				// implementation may send a RST if our request body data was known
+				// to be lost, which may trigger our reads to fail.
+				// See RFC 1122 page 88.
+				t.Logf("On test %#v, acceptable error from ReadString: %v", test, err)
+				return
+			}
+			t.Fatalf("On test %#v, ReadString: %v", test, err)
+		}
+		if !strings.Contains(line, test.expectedResponse) {
+			t.Errorf("On test %#v, got first line = %q; want %q", test, line, test.expectedResponse)
+		}
+	}
+
+	for _, test := range serverExpectTests {
+		runTest(test)
+	}
+}
+
+// Under a ~256KB (maxPostHandlerReadBytes) threshold, the server
+// should consume client request bodies that a handler didn't read.
+func TestServerUnreadRequestBodyLittle(t *testing.T) {
+	conn := new(testConn)
+	body := strings.Repeat("x", 100<<10)
+	conn.readBuf.Write([]byte(fmt.Sprintf(
+		"POST / HTTP/1.1\r\n"+
+			"Host: test\r\n"+
+			"Content-Length: %d\r\n"+
+			"\r\n", len(body))))
+	conn.readBuf.Write([]byte(body))
+
+	done := make(chan bool)
+
+	ls := &oneConnListener{conn}
+	go Serve(ls, HandlerFunc(func(rw ResponseWriter, req *Request) {
+		defer close(done)
+		if conn.readBuf.Len() < len(body)/2 {
+			t.Errorf("on request, read buffer length is %d; expected about 100 KB", conn.readBuf.Len())
+		}
+		rw.WriteHeader(200)
+		rw.(Flusher).Flush()
+		if g, e := conn.readBuf.Len(), 0; g != e {
+			t.Errorf("after WriteHeader, read buffer length is %d; want %d", g, e)
+		}
+		if c := rw.Header().Get("Connection"); c != "" {
+			t.Errorf(`Connection header = %q; want ""`, c)
+		}
+	}))
+	<-done
+}
+
+// Over a ~256KB (maxPostHandlerReadBytes) threshold, the server
+// should ignore client request bodies that a handler didn't read
+// and close the connection.
+func TestServerUnreadRequestBodyLarge(t *testing.T) {
+	conn := new(testConn)
+	body := strings.Repeat("x", 1<<20)
+	conn.readBuf.Write([]byte(fmt.Sprintf(
+		"POST / HTTP/1.1\r\n"+
+			"Host: test\r\n"+
+			"Content-Length: %d\r\n"+
+			"\r\n", len(body))))
+	conn.readBuf.Write([]byte(body))
+	conn.closec = make(chan bool, 1)
+
+	ls := &oneConnListener{conn}
+	go Serve(ls, HandlerFunc(func(rw ResponseWriter, req *Request) {
+		if conn.readBuf.Len() < len(body)/2 {
+			t.Errorf("on request, read buffer length is %d; expected about 1MB", conn.readBuf.Len())
+		}
+		rw.WriteHeader(200)
+		rw.(Flusher).Flush()
+		if conn.readBuf.Len() < len(body)/2 {
+			t.Errorf("post-WriteHeader, read buffer length is %d; expected about 1MB", conn.readBuf.Len())
+		}
+	}))
+	<-conn.closec
+
+	if res := conn.writeBuf.String(); !strings.Contains(res, "Connection: close") {
+		t.Errorf("Expected a Connection: close header; got response: %s", res)
+	}
+}
+
+func TestTimeoutHandler(t *testing.T) {
+	defer afterTest(t)
+	sendHi := make(chan bool, 1)
+	writeErrors := make(chan error, 1)
+	sayHi := HandlerFunc(func(w ResponseWriter, r *Request) {
+		<-sendHi
+		_, werr := w.Write([]byte("hi"))
+		writeErrors <- werr
+	})
+	timeout := make(chan time.Time, 1) // write to this to force timeouts
+	ts := httptest.NewServer(NewTestTimeoutHandler(sayHi, timeout))
+	defer ts.Close()
+
+	// Succeed without timing out:
+	sendHi <- true
+	res, err := Get(ts.URL)
+	if err != nil {
+		t.Error(err)
+	}
+	if g, e := res.StatusCode, StatusOK; g != e {
+		t.Errorf("got res.StatusCode %d; expected %d", g, e)
+	}
+	body, _ := ioutil.ReadAll(res.Body)
+	if g, e := string(body), "hi"; g != e {
+		t.Errorf("got body %q; expected %q", g, e)
+	}
+	if g := <-writeErrors; g != nil {
+		t.Errorf("got unexpected Write error on first request: %v", g)
+	}
+
+	// Times out:
+	timeout <- time.Time{}
+	res, err = Get(ts.URL)
+	if err != nil {
+		t.Error(err)
+	}
+	if g, e := res.StatusCode, StatusServiceUnavailable; g != e {
+		t.Errorf("got res.StatusCode %d; expected %d", g, e)
+	}
+	body, _ = ioutil.ReadAll(res.Body)
+	if !strings.Contains(string(body), "<title>Timeout</title>") {
+		t.Errorf("expected timeout body; got %q", string(body))
+	}
+
+	// Now make the previously-timed out handler speak again,
+	// which verifies the panic is handled:
+	sendHi <- true
+	if g, e := <-writeErrors, ErrHandlerTimeout; g != e {
+		t.Errorf("expected Write error of %v; got %v", e, g)
+	}
+}
+
+// See issues 8209 and 8414.
+func TestTimeoutHandlerRace(t *testing.T) {
+	defer afterTest(t)
+
+	delayHi := HandlerFunc(func(w ResponseWriter, r *Request) {
+		ms, _ := strconv.Atoi(r.URL.Path[1:])
+		if ms == 0 {
+			ms = 1
+		}
+		for i := 0; i < ms; i++ {
+			w.Write([]byte("hi"))
+			time.Sleep(time.Millisecond)
+		}
+	})
+
+	ts := httptest.NewServer(TimeoutHandler(delayHi, 20*time.Millisecond, ""))
+	defer ts.Close()
+
+	var wg sync.WaitGroup
+	gate := make(chan bool, 10)
+	n := 50
+	if testing.Short() {
+		n = 10
+		gate = make(chan bool, 3)
+	}
+	for i := 0; i < n; i++ {
+		gate <- true
+		wg.Add(1)
+		go func() {
+			defer wg.Done()
+			defer func() { <-gate }()
+			res, err := Get(fmt.Sprintf("%s/%d", ts.URL, rand.Intn(50)))
+			if err == nil {
+				io.Copy(ioutil.Discard, res.Body)
+				res.Body.Close()
+			}
+		}()
+	}
+	wg.Wait()
+}
+
+// See issues 8209 and 8414.
+func TestTimeoutHandlerRaceHeader(t *testing.T) {
+	defer afterTest(t)
+
+	delay204 := HandlerFunc(func(w ResponseWriter, r *Request) {
+		w.WriteHeader(204)
+	})
+
+	ts := httptest.NewServer(TimeoutHandler(delay204, time.Nanosecond, ""))
+	defer ts.Close()
+
+	var wg sync.WaitGroup
+	gate := make(chan bool, 50)
+	n := 500
+	if testing.Short() {
+		n = 10
+	}
+	for i := 0; i < n; i++ {
+		gate <- true
+		wg.Add(1)
+		go func() {
+			defer wg.Done()
+			defer func() { <-gate }()
+			res, err := Get(ts.URL)
+			if err != nil {
+				t.Error(err)
+				return
+			}
+			defer res.Body.Close()
+			io.Copy(ioutil.Discard, res.Body)
+		}()
+	}
+	wg.Wait()
+}
+
+// Verifies we don't path.Clean() on the wrong parts in redirects.
+func TestRedirectMunging(t *testing.T) {
+	req, _ := NewRequest("GET", "http://example.com/", nil)
+
+	resp := httptest.NewRecorder()
+	Redirect(resp, req, "/foo?next=http://bar.com/", 302)
+	if g, e := resp.Header().Get("Location"), "/foo?next=http://bar.com/"; g != e {
+		t.Errorf("Location header was %q; want %q", g, e)
+	}
+
+	resp = httptest.NewRecorder()
+	Redirect(resp, req, "http://localhost:8080/_ah/login?continue=http://localhost:8080/", 302)
+	if g, e := resp.Header().Get("Location"), "http://localhost:8080/_ah/login?continue=http://localhost:8080/"; g != e {
+		t.Errorf("Location header was %q; want %q", g, e)
+	}
+}
+
+func TestRedirectBadPath(t *testing.T) {
+	// This used to crash. It's not valid input (bad path), but it
+	// shouldn't crash.
+	rr := httptest.NewRecorder()
+	req := &Request{
+		Method: "GET",
+		URL: &url.URL{
+			Scheme: "http",
+			Path:   "not-empty-but-no-leading-slash", // bogus
+		},
+	}
+	Redirect(rr, req, "", 304)
+	if rr.Code != 304 {
+		t.Errorf("Code = %d; want 304", rr.Code)
+	}
+}
+
+// TestZeroLengthPostAndResponse exercises an optimization done by the Transport:
+// when there is no body (either because the method doesn't permit a body, or an
+// explicit Content-Length of zero is present), then the transport can re-use the
+// connection immediately. But when it re-uses the connection, it typically closes
+// the previous request's body, which is not optimal for zero-lengthed bodies,
+// as the client would then see http.ErrBodyReadAfterClose and not 0, io.EOF.
+func TestZeroLengthPostAndResponse(t *testing.T) {
+	defer afterTest(t)
+	ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, r *Request) {
+		all, err := ioutil.ReadAll(r.Body)
+		if err != nil {
+			t.Fatalf("handler ReadAll: %v", err)
+		}
+		if len(all) != 0 {
+			t.Errorf("handler got %d bytes; expected 0", len(all))
+		}
+		rw.Header().Set("Content-Length", "0")
+	}))
+	defer ts.Close()
+
+	req, err := NewRequest("POST", ts.URL, strings.NewReader(""))
+	if err != nil {
+		t.Fatal(err)
+	}
+	req.ContentLength = 0
+
+	var resp [5]*Response
+	for i := range resp {
+		resp[i], err = DefaultClient.Do(req)
+		if err != nil {
+			t.Fatalf("client post #%d: %v", i, err)
+		}
+	}
+
+	for i := range resp {
+		all, err := ioutil.ReadAll(resp[i].Body)
+		if err != nil {
+			t.Fatalf("req #%d: client ReadAll: %v", i, err)
+		}
+		if len(all) != 0 {
+			t.Errorf("req #%d: client got %d bytes; expected 0", i, len(all))
+		}
+	}
+}
+
+func TestHandlerPanicNil(t *testing.T) {
+	testHandlerPanic(t, false, nil)
+}
+
+func TestHandlerPanic(t *testing.T) {
+	testHandlerPanic(t, false, "intentional death for testing")
+}
+
+func TestHandlerPanicWithHijack(t *testing.T) {
+	testHandlerPanic(t, true, "intentional death for testing")
+}
+
+func testHandlerPanic(t *testing.T, withHijack bool, panicValue interface{}) {
+	defer afterTest(t)
+	// Unlike the other tests that set the log output to ioutil.Discard
+	// to quiet the output, this test uses a pipe.  The pipe serves three
+	// purposes:
+	//
+	//   1) The log.Print from the http server (generated by the caught
+	//      panic) will go to the pipe instead of stderr, making the
+	//      output quiet.
+	//
+	//   2) We read from the pipe to verify that the handler
+	//      actually caught the panic and logged something.
+	//
+	//   3) The blocking Read call prevents this TestHandlerPanic
+	//      function from exiting before the HTTP server handler
+	//      finishes crashing. If this text function exited too
+	//      early (and its defer log.SetOutput(os.Stderr) ran),
+	//      then the crash output could spill into the next test.
+	pr, pw := io.Pipe()
+	log.SetOutput(pw)
+	defer log.SetOutput(os.Stderr)
+	defer pw.Close()
+
+	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+		if withHijack {
+			rwc, _, err := w.(Hijacker).Hijack()
+			if err != nil {
+				t.Logf("unexpected error: %v", err)
+			}
+			defer rwc.Close()
+		}
+		panic(panicValue)
+	}))
+	defer ts.Close()
+
+	// Do a blocking read on the log output pipe so its logging
+	// doesn't bleed into the next test.  But wait only 5 seconds
+	// for it.
+	done := make(chan bool, 1)
+	go func() {
+		buf := make([]byte, 4<<10)
+		_, err := pr.Read(buf)
+		pr.Close()
+		if err != nil && err != io.EOF {
+			t.Error(err)
+		}
+		done <- true
+	}()
+
+	_, err := Get(ts.URL)
+	if err == nil {
+		t.Logf("expected an error")
+	}
+
+	if panicValue == nil {
+		return
+	}
+
+	select {
+	case <-done:
+		return
+	case <-time.After(5 * time.Second):
+		t.Fatal("expected server handler to log an error")
+	}
+}
+
+func TestNoDate(t *testing.T) {
+	defer afterTest(t)
+	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+		w.Header()["Date"] = nil
+	}))
+	defer ts.Close()
+	res, err := Get(ts.URL)
+	if err != nil {
+		t.Fatal(err)
+	}
+	_, present := res.Header["Date"]
+	if present {
+		t.Fatalf("Expected no Date header; got %v", res.Header["Date"])
+	}
+}
+
+func TestStripPrefix(t *testing.T) {
+	defer afterTest(t)
+	h := HandlerFunc(func(w ResponseWriter, r *Request) {
+		w.Header().Set("X-Path", r.URL.Path)
+	})
+	ts := httptest.NewServer(StripPrefix("/foo", h))
+	defer ts.Close()
+
+	res, err := Get(ts.URL + "/foo/bar")
+	if err != nil {
+		t.Fatal(err)
+	}
+	if g, e := res.Header.Get("X-Path"), "/bar"; g != e {
+		t.Errorf("test 1: got %s, want %s", g, e)
+	}
+	res.Body.Close()
+
+	res, err = Get(ts.URL + "/bar")
+	if err != nil {
+		t.Fatal(err)
+	}
+	if g, e := res.StatusCode, 404; g != e {
+		t.Errorf("test 2: got status %v, want %v", g, e)
+	}
+	res.Body.Close()
+}
+
+func TestRequestLimit(t *testing.T) {
+	defer afterTest(t)
+	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+		t.Fatalf("didn't expect to get request in Handler")
+	}))
+	defer ts.Close()
+	req, _ := NewRequest("GET", ts.URL, nil)
+	var bytesPerHeader = len("header12345: val12345\r\n")
+	for i := 0; i < ((DefaultMaxHeaderBytes+4096)/bytesPerHeader)+1; i++ {
+		req.Header.Set(fmt.Sprintf("header%05d", i), fmt.Sprintf("val%05d", i))
+	}
+	res, err := DefaultClient.Do(req)
+	if err != nil {
+		// Some HTTP clients may fail on this undefined behavior (server replying and
+		// closing the connection while the request is still being written), but
+		// we do support it (at least currently), so we expect a response below.
+		t.Fatalf("Do: %v", err)
+	}
+	defer res.Body.Close()
+	if res.StatusCode != 413 {
+		t.Fatalf("expected 413 response status; got: %d %s", res.StatusCode, res.Status)
+	}
+}
+
+type neverEnding byte
+
+func (b neverEnding) Read(p []byte) (n int, err error) {
+	for i := range p {
+		p[i] = byte(b)
+	}
+	return len(p), nil
+}
+
+type countReader struct {
+	r io.Reader
+	n *int64
+}
+
+func (cr countReader) Read(p []byte) (n int, err error) {
+	n, err = cr.r.Read(p)
+	atomic.AddInt64(cr.n, int64(n))
+	return
+}
+
+func TestRequestBodyLimit(t *testing.T) {
+	defer afterTest(t)
+	const limit = 1 << 20
+	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+		r.Body = MaxBytesReader(w, r.Body, limit)
+		n, err := io.Copy(ioutil.Discard, r.Body)
+		if err == nil {
+			t.Errorf("expected error from io.Copy")
+		}
+		if n != limit {
+			t.Errorf("io.Copy = %d, want %d", n, limit)
+		}
+	}))
+	defer ts.Close()
+
+	nWritten := new(int64)
+	req, _ := NewRequest("POST", ts.URL, io.LimitReader(countReader{neverEnding('a'), nWritten}, limit*200))
+
+	// Send the POST, but don't care it succeeds or not.  The
+	// remote side is going to reply and then close the TCP
+	// connection, and HTTP doesn't really define if that's
+	// allowed or not.  Some HTTP clients will get the response
+	// and some (like ours, currently) will complain that the
+	// request write failed, without reading the response.
+	//
+	// But that's okay, since what we're really testing is that
+	// the remote side hung up on us before we wrote too much.
+	_, _ = DefaultClient.Do(req)
+
+	if atomic.LoadInt64(nWritten) > limit*100 {
+		t.Errorf("handler restricted the request body to %d bytes, but client managed to write %d",
+			limit, nWritten)
+	}
+}
+
+// TestClientWriteShutdown tests that if the client shuts down the write
+// side of their TCP connection, the server doesn't send a 400 Bad Request.
+func TestClientWriteShutdown(t *testing.T) {
+	if runtime.GOOS == "plan9" {
+		t.Skip("skipping test; see http://golang.org/issue/7237")
+	}
+	defer afterTest(t)
+	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {}))
+	defer ts.Close()
+	conn, err := net.Dial("tcp", ts.Listener.Addr().String())
+	if err != nil {
+		t.Fatalf("Dial: %v", err)
+	}
+	err = conn.(*net.TCPConn).CloseWrite()
+	if err != nil {
+		t.Fatalf("Dial: %v", err)
+	}
+	donec := make(chan bool)
+	go func() {
+		defer close(donec)
+		bs, err := ioutil.ReadAll(conn)
+		if err != nil {
+			t.Fatalf("ReadAll: %v", err)
+		}
+		got := string(bs)
+		if got != "" {
+			t.Errorf("read %q from server; want nothing", got)
+		}
+	}()
+	select {
+	case <-donec:
+	case <-time.After(10 * time.Second):
+		t.Fatalf("timeout")
+	}
+}
+
+// Tests that chunked server responses that write 1 byte at a time are
+// buffered before chunk headers are added, not after chunk headers.
+func TestServerBufferedChunking(t *testing.T) {
+	conn := new(testConn)
+	conn.readBuf.Write([]byte("GET / HTTP/1.1\r\n\r\n"))
+	conn.closec = make(chan bool, 1)
+	ls := &oneConnListener{conn}
+	go Serve(ls, HandlerFunc(func(rw ResponseWriter, req *Request) {
+		rw.(Flusher).Flush() // force the Header to be sent, in chunking mode, not counting the length
+		rw.Write([]byte{'x'})
+		rw.Write([]byte{'y'})
+		rw.Write([]byte{'z'})
+	}))
+	<-conn.closec
+	if !bytes.HasSuffix(conn.writeBuf.Bytes(), []byte("\r\n\r\n3\r\nxyz\r\n0\r\n\r\n")) {
+		t.Errorf("response didn't end with a single 3 byte 'xyz' chunk; got:\n%q",
+			conn.writeBuf.Bytes())
+	}
+}
+
+// Tests that the server flushes its response headers out when it's
+// ignoring the response body and waits a bit before forcefully
+// closing the TCP connection, causing the client to get a RST.
+// See http://golang.org/issue/3595
+func TestServerGracefulClose(t *testing.T) {
+	defer afterTest(t)
+	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+		Error(w, "bye", StatusUnauthorized)
+	}))
+	defer ts.Close()
+
+	conn, err := net.Dial("tcp", ts.Listener.Addr().String())
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer conn.Close()
+	const bodySize = 5 << 20
+	req := []byte(fmt.Sprintf("POST / HTTP/1.1\r\nHost: foo.com\r\nContent-Length: %d\r\n\r\n", bodySize))
+	for i := 0; i < bodySize; i++ {
+		req = append(req, 'x')
+	}
+	writeErr := make(chan error)
+	go func() {
+		_, err := conn.Write(req)
+		writeErr <- err
+	}()
+	br := bufio.NewReader(conn)
+	lineNum := 0
+	for {
+		line, err := br.ReadString('\n')
+		if err == io.EOF {
+			break
+		}
+		if err != nil {
+			t.Fatalf("ReadLine: %v", err)
+		}
+		lineNum++
+		if lineNum == 1 && !strings.Contains(line, "401 Unauthorized") {
+			t.Errorf("Response line = %q; want a 401", line)
+		}
+	}
+	// Wait for write to finish. This is a broken pipe on both
+	// Darwin and Linux, but checking this isn't the point of
+	// the test.
+	<-writeErr
+}
+
+func TestCaseSensitiveMethod(t *testing.T) {
+	defer afterTest(t)
+	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+		if r.Method != "get" {
+			t.Errorf(`Got method %q; want "get"`, r.Method)
+		}
+	}))
+	defer ts.Close()
+	req, _ := NewRequest("get", ts.URL, nil)
+	res, err := DefaultClient.Do(req)
+	if err != nil {
+		t.Error(err)
+		return
+	}
+	res.Body.Close()
+}
+
+// TestContentLengthZero tests that for both an HTTP/1.0 and HTTP/1.1
+// request (both keep-alive), when a Handler never writes any
+// response, the net/http package adds a "Content-Length: 0" response
+// header.
+func TestContentLengthZero(t *testing.T) {
+	ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) {}))
+	defer ts.Close()
+
+	for _, version := range []string{"HTTP/1.0", "HTTP/1.1"} {
+		conn, err := net.Dial("tcp", ts.Listener.Addr().String())
+		if err != nil {
+			t.Fatalf("error dialing: %v", err)
+		}
+		_, err = fmt.Fprintf(conn, "GET / %v\r\nConnection: keep-alive\r\nHost: foo\r\n\r\n", version)
+		if err != nil {
+			t.Fatalf("error writing: %v", err)
+		}
+		req, _ := NewRequest("GET", "/", nil)
+		res, err := ReadResponse(bufio.NewReader(conn), req)
+		if err != nil {
+			t.Fatalf("error reading response: %v", err)
+		}
+		if te := res.TransferEncoding; len(te) > 0 {
+			t.Errorf("For version %q, Transfer-Encoding = %q; want none", version, te)
+		}
+		if cl := res.ContentLength; cl != 0 {
+			t.Errorf("For version %q, Content-Length = %v; want 0", version, cl)
+		}
+		conn.Close()
+	}
+}
+
+func TestCloseNotifier(t *testing.T) {
+	defer afterTest(t)
+	gotReq := make(chan bool, 1)
+	sawClose := make(chan bool, 1)
+	ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) {
+		gotReq <- true
+		cc := rw.(CloseNotifier).CloseNotify()
+		<-cc
+		sawClose <- true
+	}))
+	conn, err := net.Dial("tcp", ts.Listener.Addr().String())
+	if err != nil {
+		t.Fatalf("error dialing: %v", err)
+	}
+	diec := make(chan bool)
+	go func() {
+		_, err = fmt.Fprintf(conn, "GET / HTTP/1.1\r\nConnection: keep-alive\r\nHost: foo\r\n\r\n")
+		if err != nil {
+			t.Fatal(err)
+		}
+		<-diec
+		conn.Close()
+	}()
+For:
+	for {
+		select {
+		case <-gotReq:
+			diec <- true
+		case <-sawClose:
+			break For
+		case <-time.After(5 * time.Second):
+			t.Fatal("timeout")
+		}
+	}
+	ts.Close()
+}
+
+func TestCloseNotifierChanLeak(t *testing.T) {
+	defer afterTest(t)
+	req := reqBytes("GET / HTTP/1.0\nHost: golang.org")
+	for i := 0; i < 20; i++ {
+		var output bytes.Buffer
+		conn := &rwTestConn{
+			Reader: bytes.NewReader(req),
+			Writer: &output,
+			closec: make(chan bool, 1),
+		}
+		ln := &oneConnListener{conn: conn}
+		handler := HandlerFunc(func(rw ResponseWriter, r *Request) {
+			// Ignore the return value and never read from
+			// it, testing that we don't leak goroutines
+			// on the sending side:
+			_ = rw.(CloseNotifier).CloseNotify()
+		})
+		go Serve(ln, handler)
+		<-conn.closec
+	}
+}
+
+func TestOptions(t *testing.T) {
+	uric := make(chan string, 2) // only expect 1, but leave space for 2
+	mux := NewServeMux()
+	mux.HandleFunc("/", func(w ResponseWriter, r *Request) {
+		uric <- r.RequestURI
+	})
+	ts := httptest.NewServer(mux)
+	defer ts.Close()
+
+	conn, err := net.Dial("tcp", ts.Listener.Addr().String())
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer conn.Close()
+
+	// An OPTIONS * request should succeed.
+	_, err = conn.Write([]byte("OPTIONS * HTTP/1.1\r\nHost: foo.com\r\n\r\n"))
+	if err != nil {
+		t.Fatal(err)
+	}
+	br := bufio.NewReader(conn)
+	res, err := ReadResponse(br, &Request{Method: "OPTIONS"})
+	if err != nil {
+		t.Fatal(err)
+	}
+	if res.StatusCode != 200 {
+		t.Errorf("Got non-200 response to OPTIONS *: %#v", res)
+	}
+
+	// A GET * request on a ServeMux should fail.
+	_, err = conn.Write([]byte("GET * HTTP/1.1\r\nHost: foo.com\r\n\r\n"))
+	if err != nil {
+		t.Fatal(err)
+	}
+	res, err = ReadResponse(br, &Request{Method: "GET"})
+	if err != nil {
+		t.Fatal(err)
+	}
+	if res.StatusCode != 400 {
+		t.Errorf("Got non-400 response to GET *: %#v", res)
+	}
+
+	res, err = Get(ts.URL + "/second")
+	if err != nil {
+		t.Fatal(err)
+	}
+	res.Body.Close()
+	if got := <-uric; got != "/second" {
+		t.Errorf("Handler saw request for %q; want /second", got)
+	}
+}
+
+// Tests regarding the ordering of Write, WriteHeader, Header, and
+// Flush calls.  In Go 1.0, rw.WriteHeader immediately flushed the
+// (*response).header to the wire. In Go 1.1, the actual wire flush is
+// delayed, so we could maybe tack on a Content-Length and better
+// Content-Type after we see more (or all) of the output. To preserve
+// compatibility with Go 1, we need to be careful to track which
+// headers were live at the time of WriteHeader, so we write the same
+// ones, even if the handler modifies them (~erroneously) after the
+// first Write.
+func TestHeaderToWire(t *testing.T) {
+	tests := []struct {
+		name    string
+		handler func(ResponseWriter, *Request)
+		check   func(output string) error
+	}{
+		{
+			name: "write without Header",
+			handler: func(rw ResponseWriter, r *Request) {
+				rw.Write([]byte("hello world"))
+			},
+			check: func(got string) error {
+				if !strings.Contains(got, "Content-Length:") {
+					return errors.New("no content-length")
+				}
+				if !strings.Contains(got, "Content-Type: text/plain") {
+					return errors.New("no content-length")
+				}
+				return nil
+			},
+		},
+		{
+			name: "Header mutation before write",
+			handler: func(rw ResponseWriter, r *Request) {
+				h := rw.Header()
+				h.Set("Content-Type", "some/type")
+				rw.Write([]byte("hello world"))
+				h.Set("Too-Late", "bogus")
+			},
+			check: func(got string) error {
+				if !strings.Contains(got, "Content-Length:") {
+					return errors.New("no content-length")
+				}
+				if !strings.Contains(got, "Content-Type: some/type") {
+					return errors.New("wrong content-type")
+				}
+				if strings.Contains(got, "Too-Late") {
+					return errors.New("don't want too-late header")
+				}
+				return nil
+			},
+		},
+		{
+			name: "write then useless Header mutation",
+			handler: func(rw ResponseWriter, r *Request) {
+				rw.Write([]byte("hello world"))
+				rw.Header().Set("Too-Late", "Write already wrote headers")
+			},
+			check: func(got string) error {
+				if strings.Contains(got, "Too-Late") {
+					return errors.New("header appeared from after WriteHeader")
+				}
+				return nil
+			},
+		},
+		{
+			name: "flush then write",
+			handler: func(rw ResponseWriter, r *Request) {
+				rw.(Flusher).Flush()
+				rw.Write([]byte("post-flush"))
+				rw.Header().Set("Too-Late", "Write already wrote headers")
+			},
+			check: func(got string) error {
+				if !strings.Contains(got, "Transfer-Encoding: chunked") {
+					return errors.New("not chunked")
+				}
+				if strings.Contains(got, "Too-Late") {
+					return errors.New("header appeared from after WriteHeader")
+				}
+				return nil
+			},
+		},
+		{
+			name: "header then flush",
+			handler: func(rw ResponseWriter, r *Request) {
+				rw.Header().Set("Content-Type", "some/type")
+				rw.(Flusher).Flush()
+				rw.Write([]byte("post-flush"))
+				rw.Header().Set("Too-Late", "Write already wrote headers")
+			},
+			check: func(got string) error {
+				if !strings.Contains(got, "Transfer-Encoding: chunked") {
+					return errors.New("not chunked")
+				}
+				if strings.Contains(got, "Too-Late") {
+					return errors.New("header appeared from after WriteHeader")
+				}
+				if !strings.Contains(got, "Content-Type: some/type") {
+					return errors.New("wrong content-length")
+				}
+				return nil
+			},
+		},
+		{
+			name: "sniff-on-first-write content-type",
+			handler: func(rw ResponseWriter, r *Request) {
+				rw.Write([]byte("<html><head></head><body>some html</body></html>"))
+				rw.Header().Set("Content-Type", "x/wrong")
+			},
+			check: func(got string) error {
+				if !strings.Contains(got, "Content-Type: text/html") {
+					return errors.New("wrong content-length; want html")
+				}
+				return nil
+			},
+		},
+		{
+			name: "explicit content-type wins",
+			handler: func(rw ResponseWriter, r *Request) {
+				rw.Header().Set("Content-Type", "some/type")
+				rw.Write([]byte("<html><head></head><body>some html</body></html>"))
+			},
+			check: func(got string) error {
+				if !strings.Contains(got, "Content-Type: some/type") {
+					return errors.New("wrong content-length; want html")
+				}
+				return nil
+			},
+		},
+		{
+			name: "empty handler",
+			handler: func(rw ResponseWriter, r *Request) {
+			},
+			check: func(got string) error {
+				if !strings.Contains(got, "Content-Type: text/plain") {
+					return errors.New("wrong content-length; want text/plain")
+				}
+				if !strings.Contains(got, "Content-Length: 0") {
+					return errors.New("want 0 content-length")
+				}
+				return nil
+			},
+		},
+		{
+			name: "only Header, no write",
+			handler: func(rw ResponseWriter, r *Request) {
+				rw.Header().Set("Some-Header", "some-value")
+			},
+			check: func(got string) error {
+				if !strings.Contains(got, "Some-Header") {
+					return errors.New("didn't get header")
+				}
+				return nil
+			},
+		},
+		{
+			name: "WriteHeader call",
+			handler: func(rw ResponseWriter, r *Request) {
+				rw.WriteHeader(404)
+				rw.Header().Set("Too-Late", "some-value")
+			},
+			check: func(got string) error {
+				if !strings.Contains(got, "404") {
+					return errors.New("wrong status")
+				}
+				if strings.Contains(got, "Some-Header") {
+					return errors.New("shouldn't have seen Too-Late")
+				}
+				return nil
+			},
+		},
+	}
+	for _, tc := range tests {
+		ht := newHandlerTest(HandlerFunc(tc.handler))
+		got := ht.rawResponse("GET / HTTP/1.1\nHost: golang.org")
+		if err := tc.check(got); err != nil {
+			t.Errorf("%s: %v\nGot response:\n%s", tc.name, err, got)
+		}
+	}
+}
+
+// goTimeout runs f, failing t if f takes more than ns to complete.
+func goTimeout(t *testing.T, d time.Duration, f func()) {
+	ch := make(chan bool, 2)
+	timer := time.AfterFunc(d, func() {
+		t.Errorf("Timeout expired after %v", d)
+		ch <- true
+	})
+	defer timer.Stop()
+	go func() {
+		defer func() { ch <- true }()
+		f()
+	}()
+	<-ch
+}
+
+type errorListener struct {
+	errs []error
+}
+
+func (l *errorListener) Accept() (c net.Conn, err error) {
+	if len(l.errs) == 0 {
+		return nil, io.EOF
+	}
+	err = l.errs[0]
+	l.errs = l.errs[1:]
+	return
+}
+
+func (l *errorListener) Close() error {
+	return nil
+}
+
+func (l *errorListener) Addr() net.Addr {
+	return dummyAddr("test-address")
+}
+
+func TestAcceptMaxFds(t *testing.T) {
+	log.SetOutput(ioutil.Discard) // is noisy otherwise
+	defer log.SetOutput(os.Stderr)
+
+	ln := &errorListener{[]error{
+		&net.OpError{
+			Op:  "accept",
+			Err: syscall.EMFILE,
+		}}}
+	err := Serve(ln, HandlerFunc(HandlerFunc(func(ResponseWriter, *Request) {})))
+	if err != io.EOF {
+		t.Errorf("got error %v, want EOF", err)
+	}
+}
+
+func TestWriteAfterHijack(t *testing.T) {
+	req := reqBytes("GET / HTTP/1.1\nHost: golang.org")
+	var buf bytes.Buffer
+	wrotec := make(chan bool, 1)
+	conn := &rwTestConn{
+		Reader: bytes.NewReader(req),
+		Writer: &buf,
+		closec: make(chan bool, 1),
+	}
+	handler := HandlerFunc(func(rw ResponseWriter, r *Request) {
+		conn, bufrw, err := rw.(Hijacker).Hijack()
+		if err != nil {
+			t.Error(err)
+			return
+		}
+		go func() {
+			bufrw.Write([]byte("[hijack-to-bufw]"))
+			bufrw.Flush()
+			conn.Write([]byte("[hijack-to-conn]"))
+			conn.Close()
+			wrotec <- true
+		}()
+	})
+	ln := &oneConnListener{conn: conn}
+	go Serve(ln, handler)
+	<-conn.closec
+	<-wrotec
+	if g, w := buf.String(), "[hijack-to-bufw][hijack-to-conn]"; g != w {
+		t.Errorf("wrote %q; want %q", g, w)
+	}
+}
+
+func TestDoubleHijack(t *testing.T) {
+	req := reqBytes("GET / HTTP/1.1\nHost: golang.org")
+	var buf bytes.Buffer
+	conn := &rwTestConn{
+		Reader: bytes.NewReader(req),
+		Writer: &buf,
+		closec: make(chan bool, 1),
+	}
+	handler := HandlerFunc(func(rw ResponseWriter, r *Request) {
+		conn, _, err := rw.(Hijacker).Hijack()
+		if err != nil {
+			t.Error(err)
+			return
+		}
+		_, _, err = rw.(Hijacker).Hijack()
+		if err == nil {
+			t.Errorf("got err = nil;  want err != nil")
+		}
+		conn.Close()
+	})
+	ln := &oneConnListener{conn: conn}
+	go Serve(ln, handler)
+	<-conn.closec
+}
+
+// http://code.google.com/p/go/issues/detail?id=5955
+// Note that this does not test the "request too large"
+// exit path from the http server. This is intentional;
+// not sending Connection: close is just a minor wire
+// optimization and is pointless if dealing with a
+// badly behaved client.
+func TestHTTP10ConnectionHeader(t *testing.T) {
+	defer afterTest(t)
+
+	mux := NewServeMux()
+	mux.Handle("/", HandlerFunc(func(resp ResponseWriter, req *Request) {}))
+	ts := httptest.NewServer(mux)
+	defer ts.Close()
+
+	// net/http uses HTTP/1.1 for requests, so write requests manually
+	tests := []struct {
+		req    string   // raw http request
+		expect []string // expected Connection header(s)
+	}{
+		{
+			req:    "GET / HTTP/1.0\r\n\r\n",
+			expect: nil,
+		},
+		{
+			req:    "OPTIONS * HTTP/1.0\r\n\r\n",
+			expect: nil,
+		},
+		{
+			req:    "GET / HTTP/1.0\r\nConnection: keep-alive\r\n\r\n",
+			expect: []string{"keep-alive"},
+		},
+	}
+
+	for _, tt := range tests {
+		conn, err := net.Dial("tcp", ts.Listener.Addr().String())
+		if err != nil {
+			t.Fatal("dial err:", err)
+		}
+
+		_, err = fmt.Fprint(conn, tt.req)
+		if err != nil {
+			t.Fatal("conn write err:", err)
+		}
+
+		resp, err := ReadResponse(bufio.NewReader(conn), &Request{Method: "GET"})
+		if err != nil {
+			t.Fatal("ReadResponse err:", err)
+		}
+		conn.Close()
+		resp.Body.Close()
+
+		got := resp.Header["Connection"]
+		if !reflect.DeepEqual(got, tt.expect) {
+			t.Errorf("wrong Connection headers for request %q. Got %q expect %q", tt.req, got, tt.expect)
+		}
+	}
+}
+
+// See golang.org/issue/5660
+func TestServerReaderFromOrder(t *testing.T) {
+	defer afterTest(t)
+	pr, pw := io.Pipe()
+	const size = 3 << 20
+	ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) {
+		rw.Header().Set("Content-Type", "text/plain") // prevent sniffing path
+		done := make(chan bool)
+		go func() {
+			io.Copy(rw, pr)
+			close(done)
+		}()
+		time.Sleep(25 * time.Millisecond) // give Copy a chance to break things
+		n, err := io.Copy(ioutil.Discard, req.Body)
+		if err != nil {
+			t.Errorf("handler Copy: %v", err)
+			return
+		}
+		if n != size {
+			t.Errorf("handler Copy = %d; want %d", n, size)
+		}
+		pw.Write([]byte("hi"))
+		pw.Close()
+		<-done
+	}))
+	defer ts.Close()
+
+	req, err := NewRequest("POST", ts.URL, io.LimitReader(neverEnding('a'), size))
+	if err != nil {
+		t.Fatal(err)
+	}
+	res, err := DefaultClient.Do(req)
+	if err != nil {
+		t.Fatal(err)
+	}
+	all, err := ioutil.ReadAll(res.Body)
+	if err != nil {
+		t.Fatal(err)
+	}
+	res.Body.Close()
+	if string(all) != "hi" {
+		t.Errorf("Body = %q; want hi", all)
+	}
+}
+
+// Issue 6157, Issue 6685
+func TestCodesPreventingContentTypeAndBody(t *testing.T) {
+	for _, code := range []int{StatusNotModified, StatusNoContent, StatusContinue} {
+		ht := newHandlerTest(HandlerFunc(func(w ResponseWriter, r *Request) {
+			if r.URL.Path == "/header" {
+				w.Header().Set("Content-Length", "123")
+			}
+			w.WriteHeader(code)
+			if r.URL.Path == "/more" {
+				w.Write([]byte("stuff"))
+			}
+		}))
+		for _, req := range []string{
+			"GET / HTTP/1.0",
+			"GET /header HTTP/1.0",
+			"GET /more HTTP/1.0",
+			"GET / HTTP/1.1",
+			"GET /header HTTP/1.1",
+			"GET /more HTTP/1.1",
+		} {
+			got := ht.rawResponse(req)
+			wantStatus := fmt.Sprintf("%d %s", code, StatusText(code))
+			if !strings.Contains(got, wantStatus) {
+				t.Errorf("Code %d: Wanted %q Modified for %q: %s", code, wantStatus, req, got)
+			} else if strings.Contains(got, "Content-Length") {
+				t.Errorf("Code %d: Got a Content-Length from %q: %s", code, req, got)
+			} else if strings.Contains(got, "stuff") {
+				t.Errorf("Code %d: Response contains a body from %q: %s", code, req, got)
+			}
+		}
+	}
+}
+
+func TestContentTypeOkayOn204(t *testing.T) {
+	ht := newHandlerTest(HandlerFunc(func(w ResponseWriter, r *Request) {
+		w.Header().Set("Content-Length", "123") // suppressed
+		w.Header().Set("Content-Type", "foo/bar")
+		w.WriteHeader(204)
+	}))
+	got := ht.rawResponse("GET / HTTP/1.1")
+	if !strings.Contains(got, "Content-Type: foo/bar") {
+		t.Errorf("Response = %q; want Content-Type: foo/bar", got)
+	}
+	if strings.Contains(got, "Content-Length: 123") {
+		t.Errorf("Response = %q; don't want a Content-Length", got)
+	}
+}
+
+// Issue 6995
+// A server Handler can receive a Request, and then turn around and
+// give a copy of that Request.Body out to the Transport (e.g. any
+// proxy).  So then two people own that Request.Body (both the server
+// and the http client), and both think they can close it on failure.
+// Therefore, all incoming server requests Bodies need to be thread-safe.
+func TestTransportAndServerSharedBodyRace(t *testing.T) {
+	defer afterTest(t)
+
+	const bodySize = 1 << 20
+
+	unblockBackend := make(chan bool)
+	backend := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) {
+		io.CopyN(rw, req.Body, bodySize/2)
+		<-unblockBackend
+	}))
+	defer backend.Close()
+
+	backendRespc := make(chan *Response, 1)
+	proxy := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) {
+		if req.RequestURI == "/foo" {
+			rw.Write([]byte("bar"))
+			return
+		}
+		req2, _ := NewRequest("POST", backend.URL, req.Body)
+		req2.ContentLength = bodySize
+
+		bresp, err := DefaultClient.Do(req2)
+		if err != nil {
+			t.Errorf("Proxy outbound request: %v", err)
+			return
+		}
+		_, err = io.CopyN(ioutil.Discard, bresp.Body, bodySize/4)
+		if err != nil {
+			t.Errorf("Proxy copy error: %v", err)
+			return
+		}
+		backendRespc <- bresp // to close later
+
+		// Try to cause a race: Both the DefaultTransport and the proxy handler's Server
+		// will try to read/close req.Body (aka req2.Body)
+		DefaultTransport.(*Transport).CancelRequest(req2)
+		rw.Write([]byte("OK"))
+	}))
+	defer proxy.Close()
+
+	req, _ := NewRequest("POST", proxy.URL, io.LimitReader(neverEnding('a'), bodySize))
+	res, err := DefaultClient.Do(req)
+	if err != nil {
+		t.Fatalf("Original request: %v", err)
+	}
+
+	// Cleanup, so we don't leak goroutines.
+	res.Body.Close()
+	close(unblockBackend)
+	(<-backendRespc).Body.Close()
+}
+
+// Test that a hanging Request.Body.Read from another goroutine can't
+// cause the Handler goroutine's Request.Body.Close to block.
+func TestRequestBodyCloseDoesntBlock(t *testing.T) {
+	t.Skipf("Skipping known issue; see golang.org/issue/7121")
+	if testing.Short() {
+		t.Skip("skipping in -short mode")
+	}
+	defer afterTest(t)
+
+	readErrCh := make(chan error, 1)
+	errCh := make(chan error, 2)
+
+	server := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) {
+		go func(body io.Reader) {
+			_, err := body.Read(make([]byte, 100))
+			readErrCh <- err
+		}(req.Body)
+		time.Sleep(500 * time.Millisecond)
+	}))
+	defer server.Close()
+
+	closeConn := make(chan bool)
+	defer close(closeConn)
+	go func() {
+		conn, err := net.Dial("tcp", server.Listener.Addr().String())
+		if err != nil {
+			errCh <- err
+			return
+		}
+		defer conn.Close()
+		_, err = conn.Write([]byte("POST / HTTP/1.1\r\nConnection: close\r\nHost: foo\r\nContent-Length: 100000\r\n\r\n"))
+		if err != nil {
+			errCh <- err
+			return
+		}
+		// And now just block, making the server block on our
+		// 100000 bytes of body that will never arrive.
+		<-closeConn
+	}()
+	select {
+	case err := <-readErrCh:
+		if err == nil {
+			t.Error("Read was nil. Expected error.")
+		}
+	case err := <-errCh:
+		t.Error(err)
+	case <-time.After(5 * time.Second):
+		t.Error("timeout")
+	}
+}
+
+func TestResponseWriterWriteStringAllocs(t *testing.T) {
+	ht := newHandlerTest(HandlerFunc(func(w ResponseWriter, r *Request) {
+		if r.URL.Path == "/s" {
+			io.WriteString(w, "Hello world")
+		} else {
+			w.Write([]byte("Hello world"))
+		}
+	}))
+	before := testing.AllocsPerRun(50, func() { ht.rawResponse("GET / HTTP/1.0") })
+	after := testing.AllocsPerRun(50, func() { ht.rawResponse("GET /s HTTP/1.0") })
+	if int(after) >= int(before) {
+		t.Errorf("WriteString allocs of %v >= Write allocs of %v", after, before)
+	}
+}
+
+func TestAppendTime(t *testing.T) {
+	var b [len(TimeFormat)]byte
+	t1 := time.Date(2013, 9, 21, 15, 41, 0, 0, time.FixedZone("CEST", 2*60*60))
+	res := ExportAppendTime(b[:0], t1)
+	t2, err := ParseTime(string(res))
+	if err != nil {
+		t.Fatalf("Error parsing time: %s", err)
+	}
+	if !t1.Equal(t2) {
+		t.Fatalf("Times differ; expected: %v, got %v (%s)", t1, t2, string(res))
+	}
+}
+
+func TestServerConnState(t *testing.T) {
+	defer afterTest(t)
+	handler := map[string]func(w ResponseWriter, r *Request){
+		"/": func(w ResponseWriter, r *Request) {
+			fmt.Fprintf(w, "Hello.")
+		},
+		"/close": func(w ResponseWriter, r *Request) {
+			w.Header().Set("Connection", "close")
+			fmt.Fprintf(w, "Hello.")
+		},
+		"/hijack": func(w ResponseWriter, r *Request) {
+			c, _, _ := w.(Hijacker).Hijack()
+			c.Write([]byte("HTTP/1.0 200 OK\r\nConnection: close\r\n\r\nHello."))
+			c.Close()
+		},
+		"/hijack-panic": func(w ResponseWriter, r *Request) {
+			c, _, _ := w.(Hijacker).Hijack()
+			c.Write([]byte("HTTP/1.0 200 OK\r\nConnection: close\r\n\r\nHello."))
+			c.Close()
+			panic("intentional panic")
+		},
+	}
+	ts := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+		handler[r.URL.Path](w, r)
+	}))
+	defer ts.Close()
+
+	var mu sync.Mutex // guard stateLog and connID
+	var stateLog = map[int][]ConnState{}
+	var connID = map[net.Conn]int{}
+
+	ts.Config.ErrorLog = log.New(ioutil.Discard, "", 0)
+	ts.Config.ConnState = func(c net.Conn, state ConnState) {
+		if c == nil {
+			t.Errorf("nil conn seen in state %s", state)
+			return
+		}
+		mu.Lock()
+		defer mu.Unlock()
+		id, ok := connID[c]
+		if !ok {
+			id = len(connID) + 1
+			connID[c] = id
+		}
+		stateLog[id] = append(stateLog[id], state)
+	}
+	ts.Start()
+
+	mustGet(t, ts.URL+"/")
+	mustGet(t, ts.URL+"/close")
+
+	mustGet(t, ts.URL+"/")
+	mustGet(t, ts.URL+"/", "Connection", "close")
+
+	mustGet(t, ts.URL+"/hijack")
+	mustGet(t, ts.URL+"/hijack-panic")
+
+	// New->Closed
+	{
+		c, err := net.Dial("tcp", ts.Listener.Addr().String())
+		if err != nil {
+			t.Fatal(err)
+		}
+		c.Close()
+	}
+
+	// New->Active->Closed
+	{
+		c, err := net.Dial("tcp", ts.Listener.Addr().String())
+		if err != nil {
+			t.Fatal(err)
+		}
+		if _, err := io.WriteString(c, "BOGUS REQUEST\r\n\r\n"); err != nil {
+			t.Fatal(err)
+		}
+		c.Close()
+	}
+
+	// New->Idle->Closed
+	{
+		c, err := net.Dial("tcp", ts.Listener.Addr().String())
+		if err != nil {
+			t.Fatal(err)
+		}
+		if _, err := io.WriteString(c, "GET / HTTP/1.1\r\nHost: foo\r\n\r\n"); err != nil {
+			t.Fatal(err)
+		}
+		res, err := ReadResponse(bufio.NewReader(c), nil)
+		if err != nil {
+			t.Fatal(err)
+		}
+		if _, err := io.Copy(ioutil.Discard, res.Body); err != nil {
+			t.Fatal(err)
+		}
+		c.Close()
+	}
+
+	want := map[int][]ConnState{
+		1: {StateNew, StateActive, StateIdle, StateActive, StateClosed},
+		2: {StateNew, StateActive, StateIdle, StateActive, StateClosed},
+		3: {StateNew, StateActive, StateHijacked},
+		4: {StateNew, StateActive, StateHijacked},
+		5: {StateNew, StateClosed},
+		6: {StateNew, StateActive, StateClosed},
+		7: {StateNew, StateActive, StateIdle, StateClosed},
+	}
+	logString := func(m map[int][]ConnState) string {
+		var b bytes.Buffer
+		for id, l := range m {
+			fmt.Fprintf(&b, "Conn %d: ", id)
+			for _, s := range l {
+				fmt.Fprintf(&b, "%s ", s)
+			}
+			b.WriteString("\n")
+		}
+		return b.String()
+	}
+
+	for i := 0; i < 5; i++ {
+		time.Sleep(time.Duration(i) * 50 * time.Millisecond)
+		mu.Lock()
+		match := reflect.DeepEqual(stateLog, want)
+		mu.Unlock()
+		if match {
+			return
+		}
+	}
+
+	mu.Lock()
+	t.Errorf("Unexpected events.\nGot log: %s\n   Want: %s\n", logString(stateLog), logString(want))
+	mu.Unlock()
+}
+
+func mustGet(t *testing.T, url string, headers ...string) {
+	req, err := NewRequest("GET", url, nil)
+	if err != nil {
+		t.Fatal(err)
+	}
+	for len(headers) > 0 {
+		req.Header.Add(headers[0], headers[1])
+		headers = headers[2:]
+	}
+	res, err := DefaultClient.Do(req)
+	if err != nil {
+		t.Errorf("Error fetching %s: %v", url, err)
+		return
+	}
+	_, err = ioutil.ReadAll(res.Body)
+	defer res.Body.Close()
+	if err != nil {
+		t.Errorf("Error reading %s: %v", url, err)
+	}
+}
+
+func TestServerKeepAlivesEnabled(t *testing.T) {
+	defer afterTest(t)
+	ts := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, r *Request) {}))
+	ts.Config.SetKeepAlivesEnabled(false)
+	ts.Start()
+	defer ts.Close()
+	res, err := Get(ts.URL)
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer res.Body.Close()
+	if !res.Close {
+		t.Errorf("Body.Close == false; want true")
+	}
+}
+
+// golang.org/issue/7856
+func TestServerEmptyBodyRace(t *testing.T) {
+	defer afterTest(t)
+	var n int32
+	ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) {
+		atomic.AddInt32(&n, 1)
+	}))
+	defer ts.Close()
+	var wg sync.WaitGroup
+	const reqs = 20
+	for i := 0; i < reqs; i++ {
+		wg.Add(1)
+		go func() {
+			defer wg.Done()
+			res, err := Get(ts.URL)
+			if err != nil {
+				t.Error(err)
+				return
+			}
+			defer res.Body.Close()
+			_, err = io.Copy(ioutil.Discard, res.Body)
+			if err != nil {
+				t.Error(err)
+				return
+			}
+		}()
+	}
+	wg.Wait()
+	if got := atomic.LoadInt32(&n); got != reqs {
+		t.Errorf("handler ran %d times; want %d", got, reqs)
+	}
+}
+
+func TestServerConnStateNew(t *testing.T) {
+	sawNew := false // if the test is buggy, we'll race on this variable.
+	srv := &Server{
+		ConnState: func(c net.Conn, state ConnState) {
+			if state == StateNew {
+				sawNew = true // testing that this write isn't racy
+			}
+		},
+		Handler: HandlerFunc(func(w ResponseWriter, r *Request) {}), // irrelevant
+	}
+	srv.Serve(&oneConnListener{
+		conn: &rwTestConn{
+			Reader: strings.NewReader("GET / HTTP/1.1\r\nHost: foo\r\n\r\n"),
+			Writer: ioutil.Discard,
+		},
+	})
+	if !sawNew { // testing that this read isn't racy
+		t.Error("StateNew not seen")
+	}
+}
+
+type closeWriteTestConn struct {
+	rwTestConn
+	didCloseWrite bool
+}
+
+func (c *closeWriteTestConn) CloseWrite() error {
+	c.didCloseWrite = true
+	return nil
+}
+
+func TestCloseWrite(t *testing.T) {
+	var srv Server
+	var testConn closeWriteTestConn
+	c, err := ExportServerNewConn(&srv, &testConn)
+	if err != nil {
+		t.Fatal(err)
+	}
+	ExportCloseWriteAndWait(c)
+	if !testConn.didCloseWrite {
+		t.Error("didn't see CloseWrite call")
+	}
+}
+
+// This verifies that a handler can Flush and then Hijack.
+//
+// An similar test crashed once during development, but it was only
+// testing this tangentially and temporarily until another TODO was
+// fixed.
+//
+// So add an explicit test for this.
+func TestServerFlushAndHijack(t *testing.T) {
+	defer afterTest(t)
+	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+		io.WriteString(w, "Hello, ")
+		w.(Flusher).Flush()
+		conn, buf, _ := w.(Hijacker).Hijack()
+		buf.WriteString("6\r\nworld!\r\n0\r\n\r\n")
+		if err := buf.Flush(); err != nil {
+			t.Error(err)
+		}
+		if err := conn.Close(); err != nil {
+			t.Error(err)
+		}
+	}))
+	defer ts.Close()
+	res, err := Get(ts.URL)
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer res.Body.Close()
+	all, err := ioutil.ReadAll(res.Body)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if want := "Hello, world!"; string(all) != want {
+		t.Errorf("Got %q; want %q", all, want)
+	}
+}
+
+// golang.org/issue/8534 -- the Server shouldn't reuse a connection
+// for keep-alive after it's seen any Write error (e.g. a timeout) on
+// that net.Conn.
+//
+// To test, verify we don't timeout or see fewer unique client
+// addresses (== unique connections) than requests.
+func TestServerKeepAliveAfterWriteError(t *testing.T) {
+	if testing.Short() {
+		t.Skip("skipping in -short mode")
+	}
+	defer afterTest(t)
+	const numReq = 3
+	addrc := make(chan string, numReq)
+	ts := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+		addrc <- r.RemoteAddr
+		time.Sleep(500 * time.Millisecond)
+		w.(Flusher).Flush()
+	}))
+	ts.Config.WriteTimeout = 250 * time.Millisecond
+	ts.Start()
+	defer ts.Close()
+
+	errc := make(chan error, numReq)
+	go func() {
+		defer close(errc)
+		for i := 0; i < numReq; i++ {
+			res, err := Get(ts.URL)
+			if res != nil {
+				res.Body.Close()
+			}
+			errc <- err
+		}
+	}()
+
+	timeout := time.NewTimer(numReq * 2 * time.Second) // 4x overkill
+	defer timeout.Stop()
+	addrSeen := map[string]bool{}
+	numOkay := 0
+	for {
+		select {
+		case v := <-addrc:
+			addrSeen[v] = true
+		case err, ok := <-errc:
+			if !ok {
+				if len(addrSeen) != numReq {
+					t.Errorf("saw %d unique client addresses; want %d", len(addrSeen), numReq)
+				}
+				if numOkay != 0 {
+					t.Errorf("got %d successful client requests; want 0", numOkay)
+				}
+				return
+			}
+			if err == nil {
+				numOkay++
+			}
+		case <-timeout.C:
+			t.Fatal("timeout waiting for requests to complete")
+		}
+	}
+}
+
+func BenchmarkClientServer(b *testing.B) {
+	b.ReportAllocs()
+	b.StopTimer()
+	ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, r *Request) {
+		fmt.Fprintf(rw, "Hello world.\n")
+	}))
+	defer ts.Close()
+	b.StartTimer()
+
+	for i := 0; i < b.N; i++ {
+		res, err := Get(ts.URL)
+		if err != nil {
+			b.Fatal("Get:", err)
+		}
+		all, err := ioutil.ReadAll(res.Body)
+		res.Body.Close()
+		if err != nil {
+			b.Fatal("ReadAll:", err)
+		}
+		body := string(all)
+		if body != "Hello world.\n" {
+			b.Fatal("Got body:", body)
+		}
+	}
+
+	b.StopTimer()
+}
+
+func BenchmarkClientServerParallel4(b *testing.B) {
+	benchmarkClientServerParallel(b, 4, false)
+}
+
+func BenchmarkClientServerParallel64(b *testing.B) {
+	benchmarkClientServerParallel(b, 64, false)
+}
+
+func BenchmarkClientServerParallelTLS4(b *testing.B) {
+	benchmarkClientServerParallel(b, 4, true)
+}
+
+func BenchmarkClientServerParallelTLS64(b *testing.B) {
+	benchmarkClientServerParallel(b, 64, true)
+}
+
+func benchmarkClientServerParallel(b *testing.B, parallelism int, useTLS bool) {
+	b.ReportAllocs()
+	ts := httptest.NewUnstartedServer(HandlerFunc(func(rw ResponseWriter, r *Request) {
+		fmt.Fprintf(rw, "Hello world.\n")
+	}))
+	if useTLS {
+		ts.StartTLS()
+	} else {
+		ts.Start()
+	}
+	defer ts.Close()
+	b.ResetTimer()
+	b.SetParallelism(parallelism)
+	b.RunParallel(func(pb *testing.PB) {
+		noVerifyTransport := &Transport{
+			TLSClientConfig: &tls.Config{
+				InsecureSkipVerify: true,
+			},
+		}
+		defer noVerifyTransport.CloseIdleConnections()
+		client := &Client{Transport: noVerifyTransport}
+		for pb.Next() {
+			res, err := client.Get(ts.URL)
+			if err != nil {
+				b.Logf("Get: %v", err)
+				continue
+			}
+			all, err := ioutil.ReadAll(res.Body)
+			res.Body.Close()
+			if err != nil {
+				b.Logf("ReadAll: %v", err)
+				continue
+			}
+			body := string(all)
+			if body != "Hello world.\n" {
+				panic("Got body: " + body)
+			}
+		}
+	})
+}
+
+// A benchmark for profiling the server without the HTTP client code.
+// The client code runs in a subprocess.
+//
+// For use like:
+//   $ go test -c
+//   $ ./http.test -test.run=XX -test.bench=BenchmarkServer -test.benchtime=15s -test.cpuprofile=http.prof
+//   $ go tool pprof http.test http.prof
+//   (pprof) web
+func BenchmarkServer(b *testing.B) {
+	b.ReportAllocs()
+	// Child process mode;
+	if url := os.Getenv("TEST_BENCH_SERVER_URL"); url != "" {
+		n, err := strconv.Atoi(os.Getenv("TEST_BENCH_CLIENT_N"))
+		if err != nil {
+			panic(err)
+		}
+		for i := 0; i < n; i++ {
+			res, err := Get(url)
+			if err != nil {
+				log.Panicf("Get: %v", err)
+			}
+			all, err := ioutil.ReadAll(res.Body)
+			res.Body.Close()
+			if err != nil {
+				log.Panicf("ReadAll: %v", err)
+			}
+			body := string(all)
+			if body != "Hello world.\n" {
+				log.Panicf("Got body: %q", body)
+			}
+		}
+		os.Exit(0)
+		return
+	}
+
+	var res = []byte("Hello world.\n")
+	b.StopTimer()
+	ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, r *Request) {
+		rw.Header().Set("Content-Type", "text/html; charset=utf-8")
+		rw.Write(res)
+	}))
+	defer ts.Close()
+	b.StartTimer()
+
+	cmd := exec.Command(os.Args[0], "-test.run=XXXX", "-test.bench=BenchmarkServer")
+	cmd.Env = append([]string{
+		fmt.Sprintf("TEST_BENCH_CLIENT_N=%d", b.N),
+		fmt.Sprintf("TEST_BENCH_SERVER_URL=%s", ts.URL),
+	}, os.Environ()...)
+	out, err := cmd.CombinedOutput()
+	if err != nil {
+		b.Errorf("Test failure: %v, with output: %s", err, out)
+	}
+}
+
+func BenchmarkServerFakeConnNoKeepAlive(b *testing.B) {
+	b.ReportAllocs()
+	req := reqBytes(`GET / HTTP/1.0
+Host: golang.org
+Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
+User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.52 Safari/537.17
+Accept-Encoding: gzip,deflate,sdch
+Accept-Language: en-US,en;q=0.8
+Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
+`)
+	res := []byte("Hello world!\n")
+
+	conn := &testConn{
+		// testConn.Close will not push into the channel
+		// if it's full.
+		closec: make(chan bool, 1),
+	}
+	handler := HandlerFunc(func(rw ResponseWriter, r *Request) {
+		rw.Header().Set("Content-Type", "text/html; charset=utf-8")
+		rw.Write(res)
+	})
+	ln := new(oneConnListener)
+	for i := 0; i < b.N; i++ {
+		conn.readBuf.Reset()
+		conn.writeBuf.Reset()
+		conn.readBuf.Write(req)
+		ln.conn = conn
+		Serve(ln, handler)
+		<-conn.closec
+	}
+}
+
+// repeatReader reads content count times, then EOFs.
+type repeatReader struct {
+	content []byte
+	count   int
+	off     int
+}
+
+func (r *repeatReader) Read(p []byte) (n int, err error) {
+	if r.count <= 0 {
+		return 0, io.EOF
+	}
+	n = copy(p, r.content[r.off:])
+	r.off += n
+	if r.off == len(r.content) {
+		r.count--
+		r.off = 0
+	}
+	return
+}
+
+func BenchmarkServerFakeConnWithKeepAlive(b *testing.B) {
+	b.ReportAllocs()
+
+	req := reqBytes(`GET / HTTP/1.1
+Host: golang.org
+Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
+User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.52 Safari/537.17
+Accept-Encoding: gzip,deflate,sdch
+Accept-Language: en-US,en;q=0.8
+Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
+`)
+	res := []byte("Hello world!\n")
+
+	conn := &rwTestConn{
+		Reader: &repeatReader{content: req, count: b.N},
+		Writer: ioutil.Discard,
+		closec: make(chan bool, 1),
+	}
+	handled := 0
+	handler := HandlerFunc(func(rw ResponseWriter, r *Request) {
+		handled++
+		rw.Header().Set("Content-Type", "text/html; charset=utf-8")
+		rw.Write(res)
+	})
+	ln := &oneConnListener{conn: conn}
+	go Serve(ln, handler)
+	<-conn.closec
+	if b.N != handled {
+		b.Errorf("b.N=%d but handled %d", b.N, handled)
+	}
+}
+
+// same as above, but representing the most simple possible request
+// and handler. Notably: the handler does not call rw.Header().
+func BenchmarkServerFakeConnWithKeepAliveLite(b *testing.B) {
+	b.ReportAllocs()
+
+	req := reqBytes(`GET / HTTP/1.1
+Host: golang.org
+`)
+	res := []byte("Hello world!\n")
+
+	conn := &rwTestConn{
+		Reader: &repeatReader{content: req, count: b.N},
+		Writer: ioutil.Discard,
+		closec: make(chan bool, 1),
+	}
+	handled := 0
+	handler := HandlerFunc(func(rw ResponseWriter, r *Request) {
+		handled++
+		rw.Write(res)
+	})
+	ln := &oneConnListener{conn: conn}
+	go Serve(ln, handler)
+	<-conn.closec
+	if b.N != handled {
+		b.Errorf("b.N=%d but handled %d", b.N, handled)
+	}
+}
+
+const someResponse = "<html>some response</html>"
+
+// A Response that's just no bigger than 2KB, the buffer-before-chunking threshold.
+var response = bytes.Repeat([]byte(someResponse), 2<<10/len(someResponse))
+
+// Both Content-Type and Content-Length set. Should be no buffering.
+func BenchmarkServerHandlerTypeLen(b *testing.B) {
+	benchmarkHandler(b, HandlerFunc(func(w ResponseWriter, r *Request) {
+		w.Header().Set("Content-Type", "text/html")
+		w.Header().Set("Content-Length", strconv.Itoa(len(response)))
+		w.Write(response)
+	}))
+}
+
+// A Content-Type is set, but no length. No sniffing, but will count the Content-Length.
+func BenchmarkServerHandlerNoLen(b *testing.B) {
+	benchmarkHandler(b, HandlerFunc(func(w ResponseWriter, r *Request) {
+		w.Header().Set("Content-Type", "text/html")
+		w.Write(response)
+	}))
+}
+
+// A Content-Length is set, but the Content-Type will be sniffed.
+func BenchmarkServerHandlerNoType(b *testing.B) {
+	benchmarkHandler(b, HandlerFunc(func(w ResponseWriter, r *Request) {
+		w.Header().Set("Content-Length", strconv.Itoa(len(response)))
+		w.Write(response)
+	}))
+}
+
+// Neither a Content-Type or Content-Length, so sniffed and counted.
+func BenchmarkServerHandlerNoHeader(b *testing.B) {
+	benchmarkHandler(b, HandlerFunc(func(w ResponseWriter, r *Request) {
+		w.Write(response)
+	}))
+}
+
+func benchmarkHandler(b *testing.B, h Handler) {
+	b.ReportAllocs()
+	req := reqBytes(`GET / HTTP/1.1
+Host: golang.org
+`)
+	conn := &rwTestConn{
+		Reader: &repeatReader{content: req, count: b.N},
+		Writer: ioutil.Discard,
+		closec: make(chan bool, 1),
+	}
+	handled := 0
+	handler := HandlerFunc(func(rw ResponseWriter, r *Request) {
+		handled++
+		h.ServeHTTP(rw, r)
+	})
+	ln := &oneConnListener{conn: conn}
+	go Serve(ln, handler)
+	<-conn.closec
+	if b.N != handled {
+		b.Errorf("b.N=%d but handled %d", b.N, handled)
+	}
+}
+
+func BenchmarkServerHijack(b *testing.B) {
+	b.ReportAllocs()
+	req := reqBytes(`GET / HTTP/1.1
+Host: golang.org
+`)
+	h := HandlerFunc(func(w ResponseWriter, r *Request) {
+		conn, _, err := w.(Hijacker).Hijack()
+		if err != nil {
+			panic(err)
+		}
+		conn.Close()
+	})
+	conn := &rwTestConn{
+		Writer: ioutil.Discard,
+		closec: make(chan bool, 1),
+	}
+	ln := &oneConnListener{conn: conn}
+	for i := 0; i < b.N; i++ {
+		conn.Reader = bytes.NewReader(req)
+		ln.conn = conn
+		Serve(ln, h)
+		<-conn.closec
+	}
+}
diff --git a/src/net/http/server.go b/src/net/http/server.go
new file mode 100644
index 0000000..008d5aa
--- /dev/null
+++ b/src/net/http/server.go
@@ -0,0 +1,2096 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// HTTP server.  See RFC 2616.
+
+package http
+
+import (
+	"bufio"
+	"crypto/tls"
+	"errors"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"log"
+	"net"
+	"net/url"
+	"os"
+	"path"
+	"runtime"
+	"strconv"
+	"strings"
+	"sync"
+	"sync/atomic"
+	"time"
+)
+
+// Errors introduced by the HTTP server.
+var (
+	ErrWriteAfterFlush = errors.New("Conn.Write called after Flush")
+	ErrBodyNotAllowed  = errors.New("http: request method or response status code does not allow body")
+	ErrHijacked        = errors.New("Conn has been hijacked")
+	ErrContentLength   = errors.New("Conn.Write wrote more than the declared Content-Length")
+)
+
+// Objects implementing the Handler interface can be
+// registered to serve a particular path or subtree
+// in the HTTP server.
+//
+// ServeHTTP should write reply headers and data to the ResponseWriter
+// and then return.  Returning signals that the request is finished
+// and that the HTTP server can move on to the next request on
+// the connection.
+//
+// If ServeHTTP panics, the server (the caller of ServeHTTP) assumes
+// that the effect of the panic was isolated to the active request.
+// It recovers the panic, logs a stack trace to the server error log,
+// and hangs up the connection.
+//
+type Handler interface {
+	ServeHTTP(ResponseWriter, *Request)
+}
+
+// A ResponseWriter interface is used by an HTTP handler to
+// construct an HTTP response.
+type ResponseWriter interface {
+	// Header returns the header map that will be sent by WriteHeader.
+	// Changing the header after a call to WriteHeader (or Write) has
+	// no effect.
+	Header() Header
+
+	// Write writes the data to the connection as part of an HTTP reply.
+	// If WriteHeader has not yet been called, Write calls WriteHeader(http.StatusOK)
+	// before writing the data.  If the Header does not contain a
+	// Content-Type line, Write adds a Content-Type set to the result of passing
+	// the initial 512 bytes of written data to DetectContentType.
+	Write([]byte) (int, error)
+
+	// WriteHeader sends an HTTP response header with status code.
+	// If WriteHeader is not called explicitly, the first call to Write
+	// will trigger an implicit WriteHeader(http.StatusOK).
+	// Thus explicit calls to WriteHeader are mainly used to
+	// send error codes.
+	WriteHeader(int)
+}
+
+// The Flusher interface is implemented by ResponseWriters that allow
+// an HTTP handler to flush buffered data to the client.
+//
+// Note that even for ResponseWriters that support Flush,
+// if the client is connected through an HTTP proxy,
+// the buffered data may not reach the client until the response
+// completes.
+type Flusher interface {
+	// Flush sends any buffered data to the client.
+	Flush()
+}
+
+// The Hijacker interface is implemented by ResponseWriters that allow
+// an HTTP handler to take over the connection.
+type Hijacker interface {
+	// Hijack lets the caller take over the connection.
+	// After a call to Hijack(), the HTTP server library
+	// will not do anything else with the connection.
+	// It becomes the caller's responsibility to manage
+	// and close the connection.
+	Hijack() (net.Conn, *bufio.ReadWriter, error)
+}
+
+// The CloseNotifier interface is implemented by ResponseWriters which
+// allow detecting when the underlying connection has gone away.
+//
+// This mechanism can be used to cancel long operations on the server
+// if the client has disconnected before the response is ready.
+type CloseNotifier interface {
+	// CloseNotify returns a channel that receives a single value
+	// when the client connection has gone away.
+	CloseNotify() <-chan bool
+}
+
+// A conn represents the server side of an HTTP connection.
+type conn struct {
+	remoteAddr string               // network address of remote side
+	server     *Server              // the Server on which the connection arrived
+	rwc        net.Conn             // i/o connection
+	w          io.Writer            // checkConnErrorWriter's copy of wrc, not zeroed on Hijack
+	werr       error                // any errors writing to w
+	sr         liveSwitchReader     // where the LimitReader reads from; usually the rwc
+	lr         *io.LimitedReader    // io.LimitReader(sr)
+	buf        *bufio.ReadWriter    // buffered(lr,rwc), reading from bufio->limitReader->sr->rwc
+	tlsState   *tls.ConnectionState // or nil when not using TLS
+
+	mu           sync.Mutex // guards the following
+	clientGone   bool       // if client has disconnected mid-request
+	closeNotifyc chan bool  // made lazily
+	hijackedv    bool       // connection has been hijacked by handler
+}
+
+func (c *conn) hijacked() bool {
+	c.mu.Lock()
+	defer c.mu.Unlock()
+	return c.hijackedv
+}
+
+func (c *conn) hijack() (rwc net.Conn, buf *bufio.ReadWriter, err error) {
+	c.mu.Lock()
+	defer c.mu.Unlock()
+	if c.hijackedv {
+		return nil, nil, ErrHijacked
+	}
+	if c.closeNotifyc != nil {
+		return nil, nil, errors.New("http: Hijack is incompatible with use of CloseNotifier")
+	}
+	c.hijackedv = true
+	rwc = c.rwc
+	buf = c.buf
+	c.rwc = nil
+	c.buf = nil
+	c.setState(rwc, StateHijacked)
+	return
+}
+
+func (c *conn) closeNotify() <-chan bool {
+	c.mu.Lock()
+	defer c.mu.Unlock()
+	if c.closeNotifyc == nil {
+		c.closeNotifyc = make(chan bool, 1)
+		if c.hijackedv {
+			// to obey the function signature, even though
+			// it'll never receive a value.
+			return c.closeNotifyc
+		}
+		pr, pw := io.Pipe()
+
+		readSource := c.sr.r
+		c.sr.Lock()
+		c.sr.r = pr
+		c.sr.Unlock()
+		go func() {
+			_, err := io.Copy(pw, readSource)
+			if err == nil {
+				err = io.EOF
+			}
+			pw.CloseWithError(err)
+			c.noteClientGone()
+		}()
+	}
+	return c.closeNotifyc
+}
+
+func (c *conn) noteClientGone() {
+	c.mu.Lock()
+	defer c.mu.Unlock()
+	if c.closeNotifyc != nil && !c.clientGone {
+		c.closeNotifyc <- true
+	}
+	c.clientGone = true
+}
+
+// A switchReader can have its Reader changed at runtime.
+// It's not safe for concurrent Reads and switches.
+type switchReader struct {
+	io.Reader
+}
+
+// A switchWriter can have its Writer changed at runtime.
+// It's not safe for concurrent Writes and switches.
+type switchWriter struct {
+	io.Writer
+}
+
+// A liveSwitchReader is a switchReader that's safe for concurrent
+// reads and switches, if its mutex is held.
+type liveSwitchReader struct {
+	sync.Mutex
+	r io.Reader
+}
+
+func (sr *liveSwitchReader) Read(p []byte) (n int, err error) {
+	sr.Lock()
+	r := sr.r
+	sr.Unlock()
+	return r.Read(p)
+}
+
+// This should be >= 512 bytes for DetectContentType,
+// but otherwise it's somewhat arbitrary.
+const bufferBeforeChunkingSize = 2048
+
+// chunkWriter writes to a response's conn buffer, and is the writer
+// wrapped by the response.bufw buffered writer.
+//
+// chunkWriter also is responsible for finalizing the Header, including
+// conditionally setting the Content-Type and setting a Content-Length
+// in cases where the handler's final output is smaller than the buffer
+// size. It also conditionally adds chunk headers, when in chunking mode.
+//
+// See the comment above (*response).Write for the entire write flow.
+type chunkWriter struct {
+	res *response
+
+	// header is either nil or a deep clone of res.handlerHeader
+	// at the time of res.WriteHeader, if res.WriteHeader is
+	// called and extra buffering is being done to calculate
+	// Content-Type and/or Content-Length.
+	header Header
+
+	// wroteHeader tells whether the header's been written to "the
+	// wire" (or rather: w.conn.buf). this is unlike
+	// (*response).wroteHeader, which tells only whether it was
+	// logically written.
+	wroteHeader bool
+
+	// set by the writeHeader method:
+	chunking bool // using chunked transfer encoding for reply body
+}
+
+var (
+	crlf       = []byte("\r\n")
+	colonSpace = []byte(": ")
+)
+
+func (cw *chunkWriter) Write(p []byte) (n int, err error) {
+	if !cw.wroteHeader {
+		cw.writeHeader(p)
+	}
+	if cw.res.req.Method == "HEAD" {
+		// Eat writes.
+		return len(p), nil
+	}
+	if cw.chunking {
+		_, err = fmt.Fprintf(cw.res.conn.buf, "%x\r\n", len(p))
+		if err != nil {
+			cw.res.conn.rwc.Close()
+			return
+		}
+	}
+	n, err = cw.res.conn.buf.Write(p)
+	if cw.chunking && err == nil {
+		_, err = cw.res.conn.buf.Write(crlf)
+	}
+	if err != nil {
+		cw.res.conn.rwc.Close()
+	}
+	return
+}
+
+func (cw *chunkWriter) flush() {
+	if !cw.wroteHeader {
+		cw.writeHeader(nil)
+	}
+	cw.res.conn.buf.Flush()
+}
+
+func (cw *chunkWriter) close() {
+	if !cw.wroteHeader {
+		cw.writeHeader(nil)
+	}
+	if cw.chunking {
+		// zero EOF chunk, trailer key/value pairs (currently
+		// unsupported in Go's server), followed by a blank
+		// line.
+		cw.res.conn.buf.WriteString("0\r\n\r\n")
+	}
+}
+
+// A response represents the server side of an HTTP response.
+type response struct {
+	conn          *conn
+	req           *Request // request for this response
+	wroteHeader   bool     // reply header has been (logically) written
+	wroteContinue bool     // 100 Continue response was written
+
+	w  *bufio.Writer // buffers output in chunks to chunkWriter
+	cw chunkWriter
+	sw *switchWriter // of the bufio.Writer, for return to putBufioWriter
+
+	// handlerHeader is the Header that Handlers get access to,
+	// which may be retained and mutated even after WriteHeader.
+	// handlerHeader is copied into cw.header at WriteHeader
+	// time, and privately mutated thereafter.
+	handlerHeader Header
+	calledHeader  bool // handler accessed handlerHeader via Header
+
+	written       int64 // number of bytes written in body
+	contentLength int64 // explicitly-declared Content-Length; or -1
+	status        int   // status code passed to WriteHeader
+
+	// close connection after this reply.  set on request and
+	// updated after response from handler if there's a
+	// "Connection: keep-alive" response header and a
+	// Content-Length.
+	closeAfterReply bool
+
+	// requestBodyLimitHit is set by requestTooLarge when
+	// maxBytesReader hits its max size. It is checked in
+	// WriteHeader, to make sure we don't consume the
+	// remaining request body to try to advance to the next HTTP
+	// request. Instead, when this is set, we stop reading
+	// subsequent requests on this connection and stop reading
+	// input from it.
+	requestBodyLimitHit bool
+
+	handlerDone bool // set true when the handler exits
+
+	// Buffers for Date and Content-Length
+	dateBuf [len(TimeFormat)]byte
+	clenBuf [10]byte
+}
+
+// requestTooLarge is called by maxBytesReader when too much input has
+// been read from the client.
+func (w *response) requestTooLarge() {
+	w.closeAfterReply = true
+	w.requestBodyLimitHit = true
+	if !w.wroteHeader {
+		w.Header().Set("Connection", "close")
+	}
+}
+
+// needsSniff reports whether a Content-Type still needs to be sniffed.
+func (w *response) needsSniff() bool {
+	_, haveType := w.handlerHeader["Content-Type"]
+	return !w.cw.wroteHeader && !haveType && w.written < sniffLen
+}
+
+// writerOnly hides an io.Writer value's optional ReadFrom method
+// from io.Copy.
+type writerOnly struct {
+	io.Writer
+}
+
+func srcIsRegularFile(src io.Reader) (isRegular bool, err error) {
+	switch v := src.(type) {
+	case *os.File:
+		fi, err := v.Stat()
+		if err != nil {
+			return false, err
+		}
+		return fi.Mode().IsRegular(), nil
+	case *io.LimitedReader:
+		return srcIsRegularFile(v.R)
+	default:
+		return
+	}
+}
+
+// ReadFrom is here to optimize copying from an *os.File regular file
+// to a *net.TCPConn with sendfile.
+func (w *response) ReadFrom(src io.Reader) (n int64, err error) {
+	// Our underlying w.conn.rwc is usually a *TCPConn (with its
+	// own ReadFrom method). If not, or if our src isn't a regular
+	// file, just fall back to the normal copy method.
+	rf, ok := w.conn.rwc.(io.ReaderFrom)
+	regFile, err := srcIsRegularFile(src)
+	if err != nil {
+		return 0, err
+	}
+	if !ok || !regFile {
+		return io.Copy(writerOnly{w}, src)
+	}
+
+	// sendfile path:
+
+	if !w.wroteHeader {
+		w.WriteHeader(StatusOK)
+	}
+
+	if w.needsSniff() {
+		n0, err := io.Copy(writerOnly{w}, io.LimitReader(src, sniffLen))
+		n += n0
+		if err != nil {
+			return n, err
+		}
+	}
+
+	w.w.Flush()  // get rid of any previous writes
+	w.cw.flush() // make sure Header is written; flush data to rwc
+
+	// Now that cw has been flushed, its chunking field is guaranteed initialized.
+	if !w.cw.chunking && w.bodyAllowed() {
+		n0, err := rf.ReadFrom(src)
+		n += n0
+		w.written += n0
+		return n, err
+	}
+
+	n0, err := io.Copy(writerOnly{w}, src)
+	n += n0
+	return n, err
+}
+
+// noLimit is an effective infinite upper bound for io.LimitedReader
+const noLimit int64 = (1 << 63) - 1
+
+// debugServerConnections controls whether all server connections are wrapped
+// with a verbose logging wrapper.
+const debugServerConnections = false
+
+// Create new connection from rwc.
+func (srv *Server) newConn(rwc net.Conn) (c *conn, err error) {
+	c = new(conn)
+	c.remoteAddr = rwc.RemoteAddr().String()
+	c.server = srv
+	c.rwc = rwc
+	c.w = rwc
+	if debugServerConnections {
+		c.rwc = newLoggingConn("server", c.rwc)
+	}
+	c.sr = liveSwitchReader{r: c.rwc}
+	c.lr = io.LimitReader(&c.sr, noLimit).(*io.LimitedReader)
+	br := newBufioReader(c.lr)
+	bw := newBufioWriterSize(checkConnErrorWriter{c}, 4<<10)
+	c.buf = bufio.NewReadWriter(br, bw)
+	return c, nil
+}
+
+var (
+	bufioReaderPool   sync.Pool
+	bufioWriter2kPool sync.Pool
+	bufioWriter4kPool sync.Pool
+)
+
+func bufioWriterPool(size int) *sync.Pool {
+	switch size {
+	case 2 << 10:
+		return &bufioWriter2kPool
+	case 4 << 10:
+		return &bufioWriter4kPool
+	}
+	return nil
+}
+
+func newBufioReader(r io.Reader) *bufio.Reader {
+	if v := bufioReaderPool.Get(); v != nil {
+		br := v.(*bufio.Reader)
+		br.Reset(r)
+		return br
+	}
+	return bufio.NewReader(r)
+}
+
+func putBufioReader(br *bufio.Reader) {
+	br.Reset(nil)
+	bufioReaderPool.Put(br)
+}
+
+func newBufioWriterSize(w io.Writer, size int) *bufio.Writer {
+	pool := bufioWriterPool(size)
+	if pool != nil {
+		if v := pool.Get(); v != nil {
+			bw := v.(*bufio.Writer)
+			bw.Reset(w)
+			return bw
+		}
+	}
+	return bufio.NewWriterSize(w, size)
+}
+
+func putBufioWriter(bw *bufio.Writer) {
+	bw.Reset(nil)
+	if pool := bufioWriterPool(bw.Available()); pool != nil {
+		pool.Put(bw)
+	}
+}
+
+// DefaultMaxHeaderBytes is the maximum permitted size of the headers
+// in an HTTP request.
+// This can be overridden by setting Server.MaxHeaderBytes.
+const DefaultMaxHeaderBytes = 1 << 20 // 1 MB
+
+func (srv *Server) maxHeaderBytes() int {
+	if srv.MaxHeaderBytes > 0 {
+		return srv.MaxHeaderBytes
+	}
+	return DefaultMaxHeaderBytes
+}
+
+func (srv *Server) initialLimitedReaderSize() int64 {
+	return int64(srv.maxHeaderBytes()) + 4096 // bufio slop
+}
+
+// wrapper around io.ReaderCloser which on first read, sends an
+// HTTP/1.1 100 Continue header
+type expectContinueReader struct {
+	resp       *response
+	readCloser io.ReadCloser
+	closed     bool
+}
+
+func (ecr *expectContinueReader) Read(p []byte) (n int, err error) {
+	if ecr.closed {
+		return 0, ErrBodyReadAfterClose
+	}
+	if !ecr.resp.wroteContinue && !ecr.resp.conn.hijacked() {
+		ecr.resp.wroteContinue = true
+		ecr.resp.conn.buf.WriteString("HTTP/1.1 100 Continue\r\n\r\n")
+		ecr.resp.conn.buf.Flush()
+	}
+	return ecr.readCloser.Read(p)
+}
+
+func (ecr *expectContinueReader) Close() error {
+	ecr.closed = true
+	return ecr.readCloser.Close()
+}
+
+// TimeFormat is the time format to use with
+// time.Parse and time.Time.Format when parsing
+// or generating times in HTTP headers.
+// It is like time.RFC1123 but hard codes GMT as the time zone.
+const TimeFormat = "Mon, 02 Jan 2006 15:04:05 GMT"
+
+// appendTime is a non-allocating version of []byte(t.UTC().Format(TimeFormat))
+func appendTime(b []byte, t time.Time) []byte {
+	const days = "SunMonTueWedThuFriSat"
+	const months = "JanFebMarAprMayJunJulAugSepOctNovDec"
+
+	t = t.UTC()
+	yy, mm, dd := t.Date()
+	hh, mn, ss := t.Clock()
+	day := days[3*t.Weekday():]
+	mon := months[3*(mm-1):]
+
+	return append(b,
+		day[0], day[1], day[2], ',', ' ',
+		byte('0'+dd/10), byte('0'+dd%10), ' ',
+		mon[0], mon[1], mon[2], ' ',
+		byte('0'+yy/1000), byte('0'+(yy/100)%10), byte('0'+(yy/10)%10), byte('0'+yy%10), ' ',
+		byte('0'+hh/10), byte('0'+hh%10), ':',
+		byte('0'+mn/10), byte('0'+mn%10), ':',
+		byte('0'+ss/10), byte('0'+ss%10), ' ',
+		'G', 'M', 'T')
+}
+
+var errTooLarge = errors.New("http: request too large")
+
+// Read next request from connection.
+func (c *conn) readRequest() (w *response, err error) {
+	if c.hijacked() {
+		return nil, ErrHijacked
+	}
+
+	if d := c.server.ReadTimeout; d != 0 {
+		c.rwc.SetReadDeadline(time.Now().Add(d))
+	}
+	if d := c.server.WriteTimeout; d != 0 {
+		defer func() {
+			c.rwc.SetWriteDeadline(time.Now().Add(d))
+		}()
+	}
+
+	c.lr.N = c.server.initialLimitedReaderSize()
+	var req *Request
+	if req, err = ReadRequest(c.buf.Reader); err != nil {
+		if c.lr.N == 0 {
+			return nil, errTooLarge
+		}
+		return nil, err
+	}
+	c.lr.N = noLimit
+
+	req.RemoteAddr = c.remoteAddr
+	req.TLS = c.tlsState
+
+	w = &response{
+		conn:          c,
+		req:           req,
+		handlerHeader: make(Header),
+		contentLength: -1,
+	}
+	w.cw.res = w
+	w.w = newBufioWriterSize(&w.cw, bufferBeforeChunkingSize)
+	return w, nil
+}
+
+func (w *response) Header() Header {
+	if w.cw.header == nil && w.wroteHeader && !w.cw.wroteHeader {
+		// Accessing the header between logically writing it
+		// and physically writing it means we need to allocate
+		// a clone to snapshot the logically written state.
+		w.cw.header = w.handlerHeader.clone()
+	}
+	w.calledHeader = true
+	return w.handlerHeader
+}
+
+// maxPostHandlerReadBytes is the max number of Request.Body bytes not
+// consumed by a handler that the server will read from the client
+// in order to keep a connection alive.  If there are more bytes than
+// this then the server to be paranoid instead sends a "Connection:
+// close" response.
+//
+// This number is approximately what a typical machine's TCP buffer
+// size is anyway.  (if we have the bytes on the machine, we might as
+// well read them)
+const maxPostHandlerReadBytes = 256 << 10
+
+func (w *response) WriteHeader(code int) {
+	if w.conn.hijacked() {
+		w.conn.server.logf("http: response.WriteHeader on hijacked connection")
+		return
+	}
+	if w.wroteHeader {
+		w.conn.server.logf("http: multiple response.WriteHeader calls")
+		return
+	}
+	w.wroteHeader = true
+	w.status = code
+
+	if w.calledHeader && w.cw.header == nil {
+		w.cw.header = w.handlerHeader.clone()
+	}
+
+	if cl := w.handlerHeader.get("Content-Length"); cl != "" {
+		v, err := strconv.ParseInt(cl, 10, 64)
+		if err == nil && v >= 0 {
+			w.contentLength = v
+		} else {
+			w.conn.server.logf("http: invalid Content-Length of %q", cl)
+			w.handlerHeader.Del("Content-Length")
+		}
+	}
+}
+
+// extraHeader is the set of headers sometimes added by chunkWriter.writeHeader.
+// This type is used to avoid extra allocations from cloning and/or populating
+// the response Header map and all its 1-element slices.
+type extraHeader struct {
+	contentType      string
+	connection       string
+	transferEncoding string
+	date             []byte // written if not nil
+	contentLength    []byte // written if not nil
+}
+
+// Sorted the same as extraHeader.Write's loop.
+var extraHeaderKeys = [][]byte{
+	[]byte("Content-Type"),
+	[]byte("Connection"),
+	[]byte("Transfer-Encoding"),
+}
+
+var (
+	headerContentLength = []byte("Content-Length: ")
+	headerDate          = []byte("Date: ")
+)
+
+// Write writes the headers described in h to w.
+//
+// This method has a value receiver, despite the somewhat large size
+// of h, because it prevents an allocation. The escape analysis isn't
+// smart enough to realize this function doesn't mutate h.
+func (h extraHeader) Write(w *bufio.Writer) {
+	if h.date != nil {
+		w.Write(headerDate)
+		w.Write(h.date)
+		w.Write(crlf)
+	}
+	if h.contentLength != nil {
+		w.Write(headerContentLength)
+		w.Write(h.contentLength)
+		w.Write(crlf)
+	}
+	for i, v := range []string{h.contentType, h.connection, h.transferEncoding} {
+		if v != "" {
+			w.Write(extraHeaderKeys[i])
+			w.Write(colonSpace)
+			w.WriteString(v)
+			w.Write(crlf)
+		}
+	}
+}
+
+// writeHeader finalizes the header sent to the client and writes it
+// to cw.res.conn.buf.
+//
+// p is not written by writeHeader, but is the first chunk of the body
+// that will be written.  It is sniffed for a Content-Type if none is
+// set explicitly.  It's also used to set the Content-Length, if the
+// total body size was small and the handler has already finished
+// running.
+func (cw *chunkWriter) writeHeader(p []byte) {
+	if cw.wroteHeader {
+		return
+	}
+	cw.wroteHeader = true
+
+	w := cw.res
+	keepAlivesEnabled := w.conn.server.doKeepAlives()
+	isHEAD := w.req.Method == "HEAD"
+
+	// header is written out to w.conn.buf below. Depending on the
+	// state of the handler, we either own the map or not. If we
+	// don't own it, the exclude map is created lazily for
+	// WriteSubset to remove headers. The setHeader struct holds
+	// headers we need to add.
+	header := cw.header
+	owned := header != nil
+	if !owned {
+		header = w.handlerHeader
+	}
+	var excludeHeader map[string]bool
+	delHeader := func(key string) {
+		if owned {
+			header.Del(key)
+			return
+		}
+		if _, ok := header[key]; !ok {
+			return
+		}
+		if excludeHeader == nil {
+			excludeHeader = make(map[string]bool)
+		}
+		excludeHeader[key] = true
+	}
+	var setHeader extraHeader
+
+	// If the handler is done but never sent a Content-Length
+	// response header and this is our first (and last) write, set
+	// it, even to zero. This helps HTTP/1.0 clients keep their
+	// "keep-alive" connections alive.
+	// Exceptions: 304/204/1xx responses never get Content-Length, and if
+	// it was a HEAD request, we don't know the difference between
+	// 0 actual bytes and 0 bytes because the handler noticed it
+	// was a HEAD request and chose not to write anything.  So for
+	// HEAD, the handler should either write the Content-Length or
+	// write non-zero bytes.  If it's actually 0 bytes and the
+	// handler never looked at the Request.Method, we just don't
+	// send a Content-Length header.
+	if w.handlerDone && bodyAllowedForStatus(w.status) && header.get("Content-Length") == "" && (!isHEAD || len(p) > 0) {
+		w.contentLength = int64(len(p))
+		setHeader.contentLength = strconv.AppendInt(cw.res.clenBuf[:0], int64(len(p)), 10)
+	}
+
+	// If this was an HTTP/1.0 request with keep-alive and we sent a
+	// Content-Length back, we can make this a keep-alive response ...
+	if w.req.wantsHttp10KeepAlive() && keepAlivesEnabled {
+		sentLength := header.get("Content-Length") != ""
+		if sentLength && header.get("Connection") == "keep-alive" {
+			w.closeAfterReply = false
+		}
+	}
+
+	// Check for a explicit (and valid) Content-Length header.
+	hasCL := w.contentLength != -1
+
+	if w.req.wantsHttp10KeepAlive() && (isHEAD || hasCL) {
+		_, connectionHeaderSet := header["Connection"]
+		if !connectionHeaderSet {
+			setHeader.connection = "keep-alive"
+		}
+	} else if !w.req.ProtoAtLeast(1, 1) || w.req.wantsClose() {
+		w.closeAfterReply = true
+	}
+
+	if header.get("Connection") == "close" || !keepAlivesEnabled {
+		w.closeAfterReply = true
+	}
+
+	// Per RFC 2616, we should consume the request body before
+	// replying, if the handler hasn't already done so.  But we
+	// don't want to do an unbounded amount of reading here for
+	// DoS reasons, so we only try up to a threshold.
+	if w.req.ContentLength != 0 && !w.closeAfterReply {
+		ecr, isExpecter := w.req.Body.(*expectContinueReader)
+		if !isExpecter || ecr.resp.wroteContinue {
+			n, _ := io.CopyN(ioutil.Discard, w.req.Body, maxPostHandlerReadBytes+1)
+			if n >= maxPostHandlerReadBytes {
+				w.requestTooLarge()
+				delHeader("Connection")
+				setHeader.connection = "close"
+			} else {
+				w.req.Body.Close()
+			}
+		}
+	}
+
+	code := w.status
+	if bodyAllowedForStatus(code) {
+		// If no content type, apply sniffing algorithm to body.
+		_, haveType := header["Content-Type"]
+		if !haveType {
+			setHeader.contentType = DetectContentType(p)
+		}
+	} else {
+		for _, k := range suppressedHeaders(code) {
+			delHeader(k)
+		}
+	}
+
+	if _, ok := header["Date"]; !ok {
+		setHeader.date = appendTime(cw.res.dateBuf[:0], time.Now())
+	}
+
+	te := header.get("Transfer-Encoding")
+	hasTE := te != ""
+	if hasCL && hasTE && te != "identity" {
+		// TODO: return an error if WriteHeader gets a return parameter
+		// For now just ignore the Content-Length.
+		w.conn.server.logf("http: WriteHeader called with both Transfer-Encoding of %q and a Content-Length of %d",
+			te, w.contentLength)
+		delHeader("Content-Length")
+		hasCL = false
+	}
+
+	if w.req.Method == "HEAD" || !bodyAllowedForStatus(code) {
+		// do nothing
+	} else if code == StatusNoContent {
+		delHeader("Transfer-Encoding")
+	} else if hasCL {
+		delHeader("Transfer-Encoding")
+	} else if w.req.ProtoAtLeast(1, 1) {
+		// HTTP/1.1 or greater: Transfer-Encoding has been set to identity,  and no
+		// content-length has been provided. The connection must be closed after the
+		// reply is written, and no chunking is to be done. This is the setup
+		// recommended in the Server-Sent Events candidate recommendation 11,
+		// section 8.
+		if hasTE && te == "identity" {
+			cw.chunking = false
+			w.closeAfterReply = true
+		} else {
+			// HTTP/1.1 or greater: use chunked transfer encoding
+			// to avoid closing the connection at EOF.
+			cw.chunking = true
+			setHeader.transferEncoding = "chunked"
+		}
+	} else {
+		// HTTP version < 1.1: cannot do chunked transfer
+		// encoding and we don't know the Content-Length so
+		// signal EOF by closing connection.
+		w.closeAfterReply = true
+		delHeader("Transfer-Encoding") // in case already set
+	}
+
+	// Cannot use Content-Length with non-identity Transfer-Encoding.
+	if cw.chunking {
+		delHeader("Content-Length")
+	}
+	if !w.req.ProtoAtLeast(1, 0) {
+		return
+	}
+
+	if w.closeAfterReply && (!keepAlivesEnabled || !hasToken(cw.header.get("Connection"), "close")) {
+		delHeader("Connection")
+		if w.req.ProtoAtLeast(1, 1) {
+			setHeader.connection = "close"
+		}
+	}
+
+	w.conn.buf.WriteString(statusLine(w.req, code))
+	cw.header.WriteSubset(w.conn.buf, excludeHeader)
+	setHeader.Write(w.conn.buf.Writer)
+	w.conn.buf.Write(crlf)
+}
+
+// statusLines is a cache of Status-Line strings, keyed by code (for
+// HTTP/1.1) or negative code (for HTTP/1.0). This is faster than a
+// map keyed by struct of two fields. This map's max size is bounded
+// by 2*len(statusText), two protocol types for each known official
+// status code in the statusText map.
+var (
+	statusMu    sync.RWMutex
+	statusLines = make(map[int]string)
+)
+
+// statusLine returns a response Status-Line (RFC 2616 Section 6.1)
+// for the given request and response status code.
+func statusLine(req *Request, code int) string {
+	// Fast path:
+	key := code
+	proto11 := req.ProtoAtLeast(1, 1)
+	if !proto11 {
+		key = -key
+	}
+	statusMu.RLock()
+	line, ok := statusLines[key]
+	statusMu.RUnlock()
+	if ok {
+		return line
+	}
+
+	// Slow path:
+	proto := "HTTP/1.0"
+	if proto11 {
+		proto = "HTTP/1.1"
+	}
+	codestring := strconv.Itoa(code)
+	text, ok := statusText[code]
+	if !ok {
+		text = "status code " + codestring
+	}
+	line = proto + " " + codestring + " " + text + "\r\n"
+	if ok {
+		statusMu.Lock()
+		defer statusMu.Unlock()
+		statusLines[key] = line
+	}
+	return line
+}
+
+// bodyAllowed returns true if a Write is allowed for this response type.
+// It's illegal to call this before the header has been flushed.
+func (w *response) bodyAllowed() bool {
+	if !w.wroteHeader {
+		panic("")
+	}
+	return bodyAllowedForStatus(w.status)
+}
+
+// The Life Of A Write is like this:
+//
+// Handler starts. No header has been sent. The handler can either
+// write a header, or just start writing.  Writing before sending a header
+// sends an implicitly empty 200 OK header.
+//
+// If the handler didn't declare a Content-Length up front, we either
+// go into chunking mode or, if the handler finishes running before
+// the chunking buffer size, we compute a Content-Length and send that
+// in the header instead.
+//
+// Likewise, if the handler didn't set a Content-Type, we sniff that
+// from the initial chunk of output.
+//
+// The Writers are wired together like:
+//
+// 1. *response (the ResponseWriter) ->
+// 2. (*response).w, a *bufio.Writer of bufferBeforeChunkingSize bytes
+// 3. chunkWriter.Writer (whose writeHeader finalizes Content-Length/Type)
+//    and which writes the chunk headers, if needed.
+// 4. conn.buf, a bufio.Writer of default (4kB) bytes, writing to ->
+// 5. checkConnErrorWriter{c}, which notes any non-nil error on Write
+//    and populates c.werr with it if so. but otherwise writes to:
+// 6. the rwc, the net.Conn.
+//
+// TODO(bradfitz): short-circuit some of the buffering when the
+// initial header contains both a Content-Type and Content-Length.
+// Also short-circuit in (1) when the header's been sent and not in
+// chunking mode, writing directly to (4) instead, if (2) has no
+// buffered data.  More generally, we could short-circuit from (1) to
+// (3) even in chunking mode if the write size from (1) is over some
+// threshold and nothing is in (2).  The answer might be mostly making
+// bufferBeforeChunkingSize smaller and having bufio's fast-paths deal
+// with this instead.
+func (w *response) Write(data []byte) (n int, err error) {
+	return w.write(len(data), data, "")
+}
+
+func (w *response) WriteString(data string) (n int, err error) {
+	return w.write(len(data), nil, data)
+}
+
+// either dataB or dataS is non-zero.
+func (w *response) write(lenData int, dataB []byte, dataS string) (n int, err error) {
+	if w.conn.hijacked() {
+		w.conn.server.logf("http: response.Write on hijacked connection")
+		return 0, ErrHijacked
+	}
+	if !w.wroteHeader {
+		w.WriteHeader(StatusOK)
+	}
+	if lenData == 0 {
+		return 0, nil
+	}
+	if !w.bodyAllowed() {
+		return 0, ErrBodyNotAllowed
+	}
+
+	w.written += int64(lenData) // ignoring errors, for errorKludge
+	if w.contentLength != -1 && w.written > w.contentLength {
+		return 0, ErrContentLength
+	}
+	if dataB != nil {
+		return w.w.Write(dataB)
+	} else {
+		return w.w.WriteString(dataS)
+	}
+}
+
+func (w *response) finishRequest() {
+	w.handlerDone = true
+
+	if !w.wroteHeader {
+		w.WriteHeader(StatusOK)
+	}
+
+	w.w.Flush()
+	putBufioWriter(w.w)
+	w.cw.close()
+	w.conn.buf.Flush()
+
+	// Close the body (regardless of w.closeAfterReply) so we can
+	// re-use its bufio.Reader later safely.
+	w.req.Body.Close()
+
+	if w.req.MultipartForm != nil {
+		w.req.MultipartForm.RemoveAll()
+	}
+
+	if w.req.Method != "HEAD" && w.contentLength != -1 && w.bodyAllowed() && w.contentLength != w.written {
+		// Did not write enough. Avoid getting out of sync.
+		w.closeAfterReply = true
+	}
+
+	// There was some error writing to the underlying connection
+	// during the request, so don't re-use this conn.
+	if w.conn.werr != nil {
+		w.closeAfterReply = true
+	}
+}
+
+func (w *response) Flush() {
+	if !w.wroteHeader {
+		w.WriteHeader(StatusOK)
+	}
+	w.w.Flush()
+	w.cw.flush()
+}
+
+func (c *conn) finalFlush() {
+	if c.buf != nil {
+		c.buf.Flush()
+
+		// Steal the bufio.Reader (~4KB worth of memory) and its associated
+		// reader for a future connection.
+		putBufioReader(c.buf.Reader)
+
+		// Steal the bufio.Writer (~4KB worth of memory) and its associated
+		// writer for a future connection.
+		putBufioWriter(c.buf.Writer)
+
+		c.buf = nil
+	}
+}
+
+// Close the connection.
+func (c *conn) close() {
+	c.finalFlush()
+	if c.rwc != nil {
+		c.rwc.Close()
+		c.rwc = nil
+	}
+}
+
+// rstAvoidanceDelay is the amount of time we sleep after closing the
+// write side of a TCP connection before closing the entire socket.
+// By sleeping, we increase the chances that the client sees our FIN
+// and processes its final data before they process the subsequent RST
+// from closing a connection with known unread data.
+// This RST seems to occur mostly on BSD systems. (And Windows?)
+// This timeout is somewhat arbitrary (~latency around the planet).
+const rstAvoidanceDelay = 500 * time.Millisecond
+
+type closeWriter interface {
+	CloseWrite() error
+}
+
+var _ closeWriter = (*net.TCPConn)(nil)
+
+// closeWrite flushes any outstanding data and sends a FIN packet (if
+// client is connected via TCP), signalling that we're done.  We then
+// pause for a bit, hoping the client processes it before any
+// subsequent RST.
+//
+// See http://golang.org/issue/3595
+func (c *conn) closeWriteAndWait() {
+	c.finalFlush()
+	if tcp, ok := c.rwc.(closeWriter); ok {
+		tcp.CloseWrite()
+	}
+	time.Sleep(rstAvoidanceDelay)
+}
+
+// validNPN reports whether the proto is not a blacklisted Next
+// Protocol Negotiation protocol.  Empty and built-in protocol types
+// are blacklisted and can't be overridden with alternate
+// implementations.
+func validNPN(proto string) bool {
+	switch proto {
+	case "", "http/1.1", "http/1.0":
+		return false
+	}
+	return true
+}
+
+func (c *conn) setState(nc net.Conn, state ConnState) {
+	if hook := c.server.ConnState; hook != nil {
+		hook(nc, state)
+	}
+}
+
+// Serve a new connection.
+func (c *conn) serve() {
+	origConn := c.rwc // copy it before it's set nil on Close or Hijack
+	defer func() {
+		if err := recover(); err != nil {
+			const size = 64 << 10
+			buf := make([]byte, size)
+			buf = buf[:runtime.Stack(buf, false)]
+			c.server.logf("http: panic serving %v: %v\n%s", c.remoteAddr, err, buf)
+		}
+		if !c.hijacked() {
+			c.close()
+			c.setState(origConn, StateClosed)
+		}
+	}()
+
+	if tlsConn, ok := c.rwc.(*tls.Conn); ok {
+		if d := c.server.ReadTimeout; d != 0 {
+			c.rwc.SetReadDeadline(time.Now().Add(d))
+		}
+		if d := c.server.WriteTimeout; d != 0 {
+			c.rwc.SetWriteDeadline(time.Now().Add(d))
+		}
+		if err := tlsConn.Handshake(); err != nil {
+			c.server.logf("http: TLS handshake error from %s: %v", c.rwc.RemoteAddr(), err)
+			return
+		}
+		c.tlsState = new(tls.ConnectionState)
+		*c.tlsState = tlsConn.ConnectionState()
+		if proto := c.tlsState.NegotiatedProtocol; validNPN(proto) {
+			if fn := c.server.TLSNextProto[proto]; fn != nil {
+				h := initNPNRequest{tlsConn, serverHandler{c.server}}
+				fn(c.server, tlsConn, h)
+			}
+			return
+		}
+	}
+
+	for {
+		w, err := c.readRequest()
+		if c.lr.N != c.server.initialLimitedReaderSize() {
+			// If we read any bytes off the wire, we're active.
+			c.setState(c.rwc, StateActive)
+		}
+		if err != nil {
+			if err == errTooLarge {
+				// Their HTTP client may or may not be
+				// able to read this if we're
+				// responding to them and hanging up
+				// while they're still writing their
+				// request.  Undefined behavior.
+				io.WriteString(c.rwc, "HTTP/1.1 413 Request Entity Too Large\r\n\r\n")
+				c.closeWriteAndWait()
+				break
+			} else if err == io.EOF {
+				break // Don't reply
+			} else if neterr, ok := err.(net.Error); ok && neterr.Timeout() {
+				break // Don't reply
+			}
+			io.WriteString(c.rwc, "HTTP/1.1 400 Bad Request\r\n\r\n")
+			break
+		}
+
+		// Expect 100 Continue support
+		req := w.req
+		if req.expectsContinue() {
+			if req.ProtoAtLeast(1, 1) && req.ContentLength != 0 {
+				// Wrap the Body reader with one that replies on the connection
+				req.Body = &expectContinueReader{readCloser: req.Body, resp: w}
+			}
+			req.Header.Del("Expect")
+		} else if req.Header.get("Expect") != "" {
+			w.sendExpectationFailed()
+			break
+		}
+
+		// HTTP cannot have multiple simultaneous active requests.[*]
+		// Until the server replies to this request, it can't read another,
+		// so we might as well run the handler in this goroutine.
+		// [*] Not strictly true: HTTP pipelining.  We could let them all process
+		// in parallel even if their responses need to be serialized.
+		serverHandler{c.server}.ServeHTTP(w, w.req)
+		if c.hijacked() {
+			return
+		}
+		w.finishRequest()
+		if w.closeAfterReply {
+			if w.requestBodyLimitHit {
+				c.closeWriteAndWait()
+			}
+			break
+		}
+		c.setState(c.rwc, StateIdle)
+	}
+}
+
+func (w *response) sendExpectationFailed() {
+	// TODO(bradfitz): let ServeHTTP handlers handle
+	// requests with non-standard expectation[s]? Seems
+	// theoretical at best, and doesn't fit into the
+	// current ServeHTTP model anyway.  We'd need to
+	// make the ResponseWriter an optional
+	// "ExpectReplier" interface or something.
+	//
+	// For now we'll just obey RFC 2616 14.20 which says
+	// "If a server receives a request containing an
+	// Expect field that includes an expectation-
+	// extension that it does not support, it MUST
+	// respond with a 417 (Expectation Failed) status."
+	w.Header().Set("Connection", "close")
+	w.WriteHeader(StatusExpectationFailed)
+	w.finishRequest()
+}
+
+// Hijack implements the Hijacker.Hijack method. Our response is both a ResponseWriter
+// and a Hijacker.
+func (w *response) Hijack() (rwc net.Conn, buf *bufio.ReadWriter, err error) {
+	if w.wroteHeader {
+		w.cw.flush()
+	}
+	// Release the bufioWriter that writes to the chunk writer, it is not
+	// used after a connection has been hijacked.
+	rwc, buf, err = w.conn.hijack()
+	if err == nil {
+		putBufioWriter(w.w)
+		w.w = nil
+	}
+	return rwc, buf, err
+}
+
+func (w *response) CloseNotify() <-chan bool {
+	return w.conn.closeNotify()
+}
+
+// The HandlerFunc type is an adapter to allow the use of
+// ordinary functions as HTTP handlers.  If f is a function
+// with the appropriate signature, HandlerFunc(f) is a
+// Handler object that calls f.
+type HandlerFunc func(ResponseWriter, *Request)
+
+// ServeHTTP calls f(w, r).
+func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
+	f(w, r)
+}
+
+// Helper handlers
+
+// Error replies to the request with the specified error message and HTTP code.
+// The error message should be plain text.
+func Error(w ResponseWriter, error string, code int) {
+	w.Header().Set("Content-Type", "text/plain; charset=utf-8")
+	w.WriteHeader(code)
+	fmt.Fprintln(w, error)
+}
+
+// NotFound replies to the request with an HTTP 404 not found error.
+func NotFound(w ResponseWriter, r *Request) { Error(w, "404 page not found", StatusNotFound) }
+
+// NotFoundHandler returns a simple request handler
+// that replies to each request with a ``404 page not found'' reply.
+func NotFoundHandler() Handler { return HandlerFunc(NotFound) }
+
+// StripPrefix returns a handler that serves HTTP requests
+// by removing the given prefix from the request URL's Path
+// and invoking the handler h. StripPrefix handles a
+// request for a path that doesn't begin with prefix by
+// replying with an HTTP 404 not found error.
+func StripPrefix(prefix string, h Handler) Handler {
+	if prefix == "" {
+		return h
+	}
+	return HandlerFunc(func(w ResponseWriter, r *Request) {
+		if p := strings.TrimPrefix(r.URL.Path, prefix); len(p) < len(r.URL.Path) {
+			r.URL.Path = p
+			h.ServeHTTP(w, r)
+		} else {
+			NotFound(w, r)
+		}
+	})
+}
+
+// Redirect replies to the request with a redirect to url,
+// which may be a path relative to the request path.
+func Redirect(w ResponseWriter, r *Request, urlStr string, code int) {
+	if u, err := url.Parse(urlStr); err == nil {
+		// If url was relative, make absolute by
+		// combining with request path.
+		// The browser would probably do this for us,
+		// but doing it ourselves is more reliable.
+
+		// NOTE(rsc): RFC 2616 says that the Location
+		// line must be an absolute URI, like
+		// "http://www.google.com/redirect/",
+		// not a path like "/redirect/".
+		// Unfortunately, we don't know what to
+		// put in the host name section to get the
+		// client to connect to us again, so we can't
+		// know the right absolute URI to send back.
+		// Because of this problem, no one pays attention
+		// to the RFC; they all send back just a new path.
+		// So do we.
+		oldpath := r.URL.Path
+		if oldpath == "" { // should not happen, but avoid a crash if it does
+			oldpath = "/"
+		}
+		if u.Scheme == "" {
+			// no leading http://server
+			if urlStr == "" || urlStr[0] != '/' {
+				// make relative path absolute
+				olddir, _ := path.Split(oldpath)
+				urlStr = olddir + urlStr
+			}
+
+			var query string
+			if i := strings.Index(urlStr, "?"); i != -1 {
+				urlStr, query = urlStr[:i], urlStr[i:]
+			}
+
+			// clean up but preserve trailing slash
+			trailing := strings.HasSuffix(urlStr, "/")
+			urlStr = path.Clean(urlStr)
+			if trailing && !strings.HasSuffix(urlStr, "/") {
+				urlStr += "/"
+			}
+			urlStr += query
+		}
+	}
+
+	w.Header().Set("Location", urlStr)
+	w.WriteHeader(code)
+
+	// RFC2616 recommends that a short note "SHOULD" be included in the
+	// response because older user agents may not understand 301/307.
+	// Shouldn't send the response for POST or HEAD; that leaves GET.
+	if r.Method == "GET" {
+		note := "<a href=\"" + htmlEscape(urlStr) + "\">" + statusText[code] + "</a>.\n"
+		fmt.Fprintln(w, note)
+	}
+}
+
+var htmlReplacer = strings.NewReplacer(
+	"&", "&",
+	"<", "<",
+	">", ">",
+	// """ is shorter than """.
+	`"`, """,
+	// "'" is shorter than "'" and apos was not in HTML until HTML5.
+	"'", "'",
+)
+
+func htmlEscape(s string) string {
+	return htmlReplacer.Replace(s)
+}
+
+// Redirect to a fixed URL
+type redirectHandler struct {
+	url  string
+	code int
+}
+
+func (rh *redirectHandler) ServeHTTP(w ResponseWriter, r *Request) {
+	Redirect(w, r, rh.url, rh.code)
+}
+
+// RedirectHandler returns a request handler that redirects
+// each request it receives to the given url using the given
+// status code.
+func RedirectHandler(url string, code int) Handler {
+	return &redirectHandler{url, code}
+}
+
+// ServeMux is an HTTP request multiplexer.
+// It matches the URL of each incoming request against a list of registered
+// patterns and calls the handler for the pattern that
+// most closely matches the URL.
+//
+// Patterns name fixed, rooted paths, like "/favicon.ico",
+// or rooted subtrees, like "/images/" (note the trailing slash).
+// Longer patterns take precedence over shorter ones, so that
+// if there are handlers registered for both "/images/"
+// and "/images/thumbnails/", the latter handler will be
+// called for paths beginning "/images/thumbnails/" and the
+// former will receive requests for any other paths in the
+// "/images/" subtree.
+//
+// Note that since a pattern ending in a slash names a rooted subtree,
+// the pattern "/" matches all paths not matched by other registered
+// patterns, not just the URL with Path == "/".
+//
+// Patterns may optionally begin with a host name, restricting matches to
+// URLs on that host only.  Host-specific patterns take precedence over
+// general patterns, so that a handler might register for the two patterns
+// "/codesearch" and "codesearch.google.com/" without also taking over
+// requests for "http://www.google.com/".
+//
+// ServeMux also takes care of sanitizing the URL request path,
+// redirecting any request containing . or .. elements to an
+// equivalent .- and ..-free URL.
+type ServeMux struct {
+	mu    sync.RWMutex
+	m     map[string]muxEntry
+	hosts bool // whether any patterns contain hostnames
+}
+
+type muxEntry struct {
+	explicit bool
+	h        Handler
+	pattern  string
+}
+
+// NewServeMux allocates and returns a new ServeMux.
+func NewServeMux() *ServeMux { return &ServeMux{m: make(map[string]muxEntry)} }
+
+// DefaultServeMux is the default ServeMux used by Serve.
+var DefaultServeMux = NewServeMux()
+
+// Does path match pattern?
+func pathMatch(pattern, path string) bool {
+	if len(pattern) == 0 {
+		// should not happen
+		return false
+	}
+	n := len(pattern)
+	if pattern[n-1] != '/' {
+		return pattern == path
+	}
+	return len(path) >= n && path[0:n] == pattern
+}
+
+// Return the canonical path for p, eliminating . and .. elements.
+func cleanPath(p string) string {
+	if p == "" {
+		return "/"
+	}
+	if p[0] != '/' {
+		p = "/" + p
+	}
+	np := path.Clean(p)
+	// path.Clean removes trailing slash except for root;
+	// put the trailing slash back if necessary.
+	if p[len(p)-1] == '/' && np != "/" {
+		np += "/"
+	}
+	return np
+}
+
+// Find a handler on a handler map given a path string
+// Most-specific (longest) pattern wins
+func (mux *ServeMux) match(path string) (h Handler, pattern string) {
+	var n = 0
+	for k, v := range mux.m {
+		if !pathMatch(k, path) {
+			continue
+		}
+		if h == nil || len(k) > n {
+			n = len(k)
+			h = v.h
+			pattern = v.pattern
+		}
+	}
+	return
+}
+
+// Handler returns the handler to use for the given request,
+// consulting r.Method, r.Host, and r.URL.Path. It always returns
+// a non-nil handler. If the path is not in its canonical form, the
+// handler will be an internally-generated handler that redirects
+// to the canonical path.
+//
+// Handler also returns the registered pattern that matches the
+// request or, in the case of internally-generated redirects,
+// the pattern that will match after following the redirect.
+//
+// If there is no registered handler that applies to the request,
+// Handler returns a ``page not found'' handler and an empty pattern.
+func (mux *ServeMux) Handler(r *Request) (h Handler, pattern string) {
+	if r.Method != "CONNECT" {
+		if p := cleanPath(r.URL.Path); p != r.URL.Path {
+			_, pattern = mux.handler(r.Host, p)
+			url := *r.URL
+			url.Path = p
+			return RedirectHandler(url.String(), StatusMovedPermanently), pattern
+		}
+	}
+
+	return mux.handler(r.Host, r.URL.Path)
+}
+
+// handler is the main implementation of Handler.
+// The path is known to be in canonical form, except for CONNECT methods.
+func (mux *ServeMux) handler(host, path string) (h Handler, pattern string) {
+	mux.mu.RLock()
+	defer mux.mu.RUnlock()
+
+	// Host-specific pattern takes precedence over generic ones
+	if mux.hosts {
+		h, pattern = mux.match(host + path)
+	}
+	if h == nil {
+		h, pattern = mux.match(path)
+	}
+	if h == nil {
+		h, pattern = NotFoundHandler(), ""
+	}
+	return
+}
+
+// ServeHTTP dispatches the request to the handler whose
+// pattern most closely matches the request URL.
+func (mux *ServeMux) ServeHTTP(w ResponseWriter, r *Request) {
+	if r.RequestURI == "*" {
+		if r.ProtoAtLeast(1, 1) {
+			w.Header().Set("Connection", "close")
+		}
+		w.WriteHeader(StatusBadRequest)
+		return
+	}
+	h, _ := mux.Handler(r)
+	h.ServeHTTP(w, r)
+}
+
+// Handle registers the handler for the given pattern.
+// If a handler already exists for pattern, Handle panics.
+func (mux *ServeMux) Handle(pattern string, handler Handler) {
+	mux.mu.Lock()
+	defer mux.mu.Unlock()
+
+	if pattern == "" {
+		panic("http: invalid pattern " + pattern)
+	}
+	if handler == nil {
+		panic("http: nil handler")
+	}
+	if mux.m[pattern].explicit {
+		panic("http: multiple registrations for " + pattern)
+	}
+
+	mux.m[pattern] = muxEntry{explicit: true, h: handler, pattern: pattern}
+
+	if pattern[0] != '/' {
+		mux.hosts = true
+	}
+
+	// Helpful behavior:
+	// If pattern is /tree/, insert an implicit permanent redirect for /tree.
+	// It can be overridden by an explicit registration.
+	n := len(pattern)
+	if n > 0 && pattern[n-1] == '/' && !mux.m[pattern[0:n-1]].explicit {
+		// If pattern contains a host name, strip it and use remaining
+		// path for redirect.
+		path := pattern
+		if pattern[0] != '/' {
+			// In pattern, at least the last character is a '/', so
+			// strings.Index can't be -1.
+			path = pattern[strings.Index(pattern, "/"):]
+		}
+		mux.m[pattern[0:n-1]] = muxEntry{h: RedirectHandler(path, StatusMovedPermanently), pattern: pattern}
+	}
+}
+
+// HandleFunc registers the handler function for the given pattern.
+func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
+	mux.Handle(pattern, HandlerFunc(handler))
+}
+
+// Handle registers the handler for the given pattern
+// in the DefaultServeMux.
+// The documentation for ServeMux explains how patterns are matched.
+func Handle(pattern string, handler Handler) { DefaultServeMux.Handle(pattern, handler) }
+
+// HandleFunc registers the handler function for the given pattern
+// in the DefaultServeMux.
+// The documentation for ServeMux explains how patterns are matched.
+func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
+	DefaultServeMux.HandleFunc(pattern, handler)
+}
+
+// Serve accepts incoming HTTP connections on the listener l,
+// creating a new service goroutine for each.  The service goroutines
+// read requests and then call handler to reply to them.
+// Handler is typically nil, in which case the DefaultServeMux is used.
+func Serve(l net.Listener, handler Handler) error {
+	srv := &Server{Handler: handler}
+	return srv.Serve(l)
+}
+
+// A Server defines parameters for running an HTTP server.
+// The zero value for Server is a valid configuration.
+type Server struct {
+	Addr           string        // TCP address to listen on, ":http" if empty
+	Handler        Handler       // handler to invoke, http.DefaultServeMux if nil
+	ReadTimeout    time.Duration // maximum duration before timing out read of the request
+	WriteTimeout   time.Duration // maximum duration before timing out write of the response
+	MaxHeaderBytes int           // maximum size of request headers, DefaultMaxHeaderBytes if 0
+	TLSConfig      *tls.Config   // optional TLS config, used by ListenAndServeTLS
+
+	// TLSNextProto optionally specifies a function to take over
+	// ownership of the provided TLS connection when an NPN
+	// protocol upgrade has occurred.  The map key is the protocol
+	// name negotiated. The Handler argument should be used to
+	// handle HTTP requests and will initialize the Request's TLS
+	// and RemoteAddr if not already set.  The connection is
+	// automatically closed when the function returns.
+	TLSNextProto map[string]func(*Server, *tls.Conn, Handler)
+
+	// ConnState specifies an optional callback function that is
+	// called when a client connection changes state. See the
+	// ConnState type and associated constants for details.
+	ConnState func(net.Conn, ConnState)
+
+	// ErrorLog specifies an optional logger for errors accepting
+	// connections and unexpected behavior from handlers.
+	// If nil, logging goes to os.Stderr via the log package's
+	// standard logger.
+	ErrorLog *log.Logger
+
+	disableKeepAlives int32 // accessed atomically.
+}
+
+// A ConnState represents the state of a client connection to a server.
+// It's used by the optional Server.ConnState hook.
+type ConnState int
+
+const (
+	// StateNew represents a new connection that is expected to
+	// send a request immediately. Connections begin at this
+	// state and then transition to either StateActive or
+	// StateClosed.
+	StateNew ConnState = iota
+
+	// StateActive represents a connection that has read 1 or more
+	// bytes of a request. The Server.ConnState hook for
+	// StateActive fires before the request has entered a handler
+	// and doesn't fire again until the request has been
+	// handled. After the request is handled, the state
+	// transitions to StateClosed, StateHijacked, or StateIdle.
+	StateActive
+
+	// StateIdle represents a connection that has finished
+	// handling a request and is in the keep-alive state, waiting
+	// for a new request. Connections transition from StateIdle
+	// to either StateActive or StateClosed.
+	StateIdle
+
+	// StateHijacked represents a hijacked connection.
+	// This is a terminal state. It does not transition to StateClosed.
+	StateHijacked
+
+	// StateClosed represents a closed connection.
+	// This is a terminal state. Hijacked connections do not
+	// transition to StateClosed.
+	StateClosed
+)
+
+var stateName = map[ConnState]string{
+	StateNew:      "new",
+	StateActive:   "active",
+	StateIdle:     "idle",
+	StateHijacked: "hijacked",
+	StateClosed:   "closed",
+}
+
+func (c ConnState) String() string {
+	return stateName[c]
+}
+
+// serverHandler delegates to either the server's Handler or
+// DefaultServeMux and also handles "OPTIONS *" requests.
+type serverHandler struct {
+	srv *Server
+}
+
+func (sh serverHandler) ServeHTTP(rw ResponseWriter, req *Request) {
+	handler := sh.srv.Handler
+	if handler == nil {
+		handler = DefaultServeMux
+	}
+	if req.RequestURI == "*" && req.Method == "OPTIONS" {
+		handler = globalOptionsHandler{}
+	}
+	handler.ServeHTTP(rw, req)
+}
+
+// ListenAndServe listens on the TCP network address srv.Addr and then
+// calls Serve to handle requests on incoming connections.  If
+// srv.Addr is blank, ":http" is used.
+func (srv *Server) ListenAndServe() error {
+	addr := srv.Addr
+	if addr == "" {
+		addr = ":http"
+	}
+	ln, err := net.Listen("tcp", addr)
+	if err != nil {
+		return err
+	}
+	return srv.Serve(tcpKeepAliveListener{ln.(*net.TCPListener)})
+}
+
+// Serve accepts incoming connections on the Listener l, creating a
+// new service goroutine for each.  The service goroutines read requests and
+// then call srv.Handler to reply to them.
+func (srv *Server) Serve(l net.Listener) error {
+	defer l.Close()
+	var tempDelay time.Duration // how long to sleep on accept failure
+	for {
+		rw, e := l.Accept()
+		if e != nil {
+			if ne, ok := e.(net.Error); ok && ne.Temporary() {
+				if tempDelay == 0 {
+					tempDelay = 5 * time.Millisecond
+				} else {
+					tempDelay *= 2
+				}
+				if max := 1 * time.Second; tempDelay > max {
+					tempDelay = max
+				}
+				srv.logf("http: Accept error: %v; retrying in %v", e, tempDelay)
+				time.Sleep(tempDelay)
+				continue
+			}
+			return e
+		}
+		tempDelay = 0
+		c, err := srv.newConn(rw)
+		if err != nil {
+			continue
+		}
+		c.setState(c.rwc, StateNew) // before Serve can return
+		go c.serve()
+	}
+}
+
+func (s *Server) doKeepAlives() bool {
+	return atomic.LoadInt32(&s.disableKeepAlives) == 0
+}
+
+// SetKeepAlivesEnabled controls whether HTTP keep-alives are enabled.
+// By default, keep-alives are always enabled. Only very
+// resource-constrained environments or servers in the process of
+// shutting down should disable them.
+func (s *Server) SetKeepAlivesEnabled(v bool) {
+	if v {
+		atomic.StoreInt32(&s.disableKeepAlives, 0)
+	} else {
+		atomic.StoreInt32(&s.disableKeepAlives, 1)
+	}
+}
+
+func (s *Server) logf(format string, args ...interface{}) {
+	if s.ErrorLog != nil {
+		s.ErrorLog.Printf(format, args...)
+	} else {
+		log.Printf(format, args...)
+	}
+}
+
+// ListenAndServe listens on the TCP network address addr
+// and then calls Serve with handler to handle requests
+// on incoming connections.  Handler is typically nil,
+// in which case the DefaultServeMux is used.
+//
+// A trivial example server is:
+//
+//	package main
+//
+//	import (
+//		"io"
+//		"net/http"
+//		"log"
+//	)
+//
+//	// hello world, the web server
+//	func HelloServer(w http.ResponseWriter, req *http.Request) {
+//		io.WriteString(w, "hello, world!\n")
+//	}
+//
+//	func main() {
+//		http.HandleFunc("/hello", HelloServer)
+//		err := http.ListenAndServe(":12345", nil)
+//		if err != nil {
+//			log.Fatal("ListenAndServe: ", err)
+//		}
+//	}
+func ListenAndServe(addr string, handler Handler) error {
+	server := &Server{Addr: addr, Handler: handler}
+	return server.ListenAndServe()
+}
+
+// ListenAndServeTLS acts identically to ListenAndServe, except that it
+// expects HTTPS connections. Additionally, files containing a certificate and
+// matching private key for the server must be provided. If the certificate
+// is signed by a certificate authority, the certFile should be the concatenation
+// of the server's certificate followed by the CA's certificate.
+//
+// A trivial example server is:
+//
+//	import (
+//		"log"
+//		"net/http"
+//	)
+//
+//	func handler(w http.ResponseWriter, req *http.Request) {
+//		w.Header().Set("Content-Type", "text/plain")
+//		w.Write([]byte("This is an example server.\n"))
+//	}
+//
+//	func main() {
+//		http.HandleFunc("/", handler)
+//		log.Printf("About to listen on 10443. Go to https://127.0.0.1:10443/")
+//		err := http.ListenAndServeTLS(":10443", "cert.pem", "key.pem", nil)
+//		if err != nil {
+//			log.Fatal(err)
+//		}
+//	}
+//
+// One can use generate_cert.go in crypto/tls to generate cert.pem and key.pem.
+func ListenAndServeTLS(addr string, certFile string, keyFile string, handler Handler) error {
+	server := &Server{Addr: addr, Handler: handler}
+	return server.ListenAndServeTLS(certFile, keyFile)
+}
+
+// ListenAndServeTLS listens on the TCP network address srv.Addr and
+// then calls Serve to handle requests on incoming TLS connections.
+//
+// Filenames containing a certificate and matching private key for
+// the server must be provided. If the certificate is signed by a
+// certificate authority, the certFile should be the concatenation
+// of the server's certificate followed by the CA's certificate.
+//
+// If srv.Addr is blank, ":https" is used.
+func (srv *Server) ListenAndServeTLS(certFile, keyFile string) error {
+	addr := srv.Addr
+	if addr == "" {
+		addr = ":https"
+	}
+	config := &tls.Config{}
+	if srv.TLSConfig != nil {
+		*config = *srv.TLSConfig
+	}
+	if config.NextProtos == nil {
+		config.NextProtos = []string{"http/1.1"}
+	}
+
+	var err error
+	config.Certificates = make([]tls.Certificate, 1)
+	config.Certificates[0], err = tls.LoadX509KeyPair(certFile, keyFile)
+	if err != nil {
+		return err
+	}
+
+	ln, err := net.Listen("tcp", addr)
+	if err != nil {
+		return err
+	}
+
+	tlsListener := tls.NewListener(tcpKeepAliveListener{ln.(*net.TCPListener)}, config)
+	return srv.Serve(tlsListener)
+}
+
+// TimeoutHandler returns a Handler that runs h with the given time limit.
+//
+// The new Handler calls h.ServeHTTP to handle each request, but if a
+// call runs for longer than its time limit, the handler responds with
+// a 503 Service Unavailable error and the given message in its body.
+// (If msg is empty, a suitable default message will be sent.)
+// After such a timeout, writes by h to its ResponseWriter will return
+// ErrHandlerTimeout.
+func TimeoutHandler(h Handler, dt time.Duration, msg string) Handler {
+	f := func() <-chan time.Time {
+		return time.After(dt)
+	}
+	return &timeoutHandler{h, f, msg}
+}
+
+// ErrHandlerTimeout is returned on ResponseWriter Write calls
+// in handlers which have timed out.
+var ErrHandlerTimeout = errors.New("http: Handler timeout")
+
+type timeoutHandler struct {
+	handler Handler
+	timeout func() <-chan time.Time // returns channel producing a timeout
+	body    string
+}
+
+func (h *timeoutHandler) errorBody() string {
+	if h.body != "" {
+		return h.body
+	}
+	return "<html><head><title>Timeout</title></head><body><h1>Timeout</h1></body></html>"
+}
+
+func (h *timeoutHandler) ServeHTTP(w ResponseWriter, r *Request) {
+	done := make(chan bool, 1)
+	tw := &timeoutWriter{w: w}
+	go func() {
+		h.handler.ServeHTTP(tw, r)
+		done <- true
+	}()
+	select {
+	case <-done:
+		return
+	case <-h.timeout():
+		tw.mu.Lock()
+		defer tw.mu.Unlock()
+		if !tw.wroteHeader {
+			tw.w.WriteHeader(StatusServiceUnavailable)
+			tw.w.Write([]byte(h.errorBody()))
+		}
+		tw.timedOut = true
+	}
+}
+
+type timeoutWriter struct {
+	w ResponseWriter
+
+	mu          sync.Mutex
+	timedOut    bool
+	wroteHeader bool
+}
+
+func (tw *timeoutWriter) Header() Header {
+	return tw.w.Header()
+}
+
+func (tw *timeoutWriter) Write(p []byte) (int, error) {
+	tw.mu.Lock()
+	defer tw.mu.Unlock()
+	tw.wroteHeader = true // implicitly at least
+	if tw.timedOut {
+		return 0, ErrHandlerTimeout
+	}
+	return tw.w.Write(p)
+}
+
+func (tw *timeoutWriter) WriteHeader(code int) {
+	tw.mu.Lock()
+	defer tw.mu.Unlock()
+	if tw.timedOut || tw.wroteHeader {
+		return
+	}
+	tw.wroteHeader = true
+	tw.w.WriteHeader(code)
+}
+
+// tcpKeepAliveListener sets TCP keep-alive timeouts on accepted
+// connections. It's used by ListenAndServe and ListenAndServeTLS so
+// dead TCP connections (e.g. closing laptop mid-download) eventually
+// go away.
+type tcpKeepAliveListener struct {
+	*net.TCPListener
+}
+
+func (ln tcpKeepAliveListener) Accept() (c net.Conn, err error) {
+	tc, err := ln.AcceptTCP()
+	if err != nil {
+		return
+	}
+	tc.SetKeepAlive(true)
+	tc.SetKeepAlivePeriod(3 * time.Minute)
+	return tc, nil
+}
+
+// globalOptionsHandler responds to "OPTIONS *" requests.
+type globalOptionsHandler struct{}
+
+func (globalOptionsHandler) ServeHTTP(w ResponseWriter, r *Request) {
+	w.Header().Set("Content-Length", "0")
+	if r.ContentLength != 0 {
+		// Read up to 4KB of OPTIONS body (as mentioned in the
+		// spec as being reserved for future use), but anything
+		// over that is considered a waste of server resources
+		// (or an attack) and we abort and close the connection,
+		// courtesy of MaxBytesReader's EOF behavior.
+		mb := MaxBytesReader(w, r.Body, 4<<10)
+		io.Copy(ioutil.Discard, mb)
+	}
+}
+
+type eofReaderWithWriteTo struct{}
+
+func (eofReaderWithWriteTo) WriteTo(io.Writer) (int64, error) { return 0, nil }
+func (eofReaderWithWriteTo) Read([]byte) (int, error)         { return 0, io.EOF }
+
+// eofReader is a non-nil io.ReadCloser that always returns EOF.
+// It has a WriteTo method so io.Copy won't need a buffer.
+var eofReader = &struct {
+	eofReaderWithWriteTo
+	io.Closer
+}{
+	eofReaderWithWriteTo{},
+	ioutil.NopCloser(nil),
+}
+
+// Verify that an io.Copy from an eofReader won't require a buffer.
+var _ io.WriterTo = eofReader
+
+// initNPNRequest is an HTTP handler that initializes certain
+// uninitialized fields in its *Request. Such partially-initialized
+// Requests come from NPN protocol handlers.
+type initNPNRequest struct {
+	c *tls.Conn
+	h serverHandler
+}
+
+func (h initNPNRequest) ServeHTTP(rw ResponseWriter, req *Request) {
+	if req.TLS == nil {
+		req.TLS = &tls.ConnectionState{}
+		*req.TLS = h.c.ConnectionState()
+	}
+	if req.Body == nil {
+		req.Body = eofReader
+	}
+	if req.RemoteAddr == "" {
+		req.RemoteAddr = h.c.RemoteAddr().String()
+	}
+	h.h.ServeHTTP(rw, req)
+}
+
+// loggingConn is used for debugging.
+type loggingConn struct {
+	name string
+	net.Conn
+}
+
+var (
+	uniqNameMu   sync.Mutex
+	uniqNameNext = make(map[string]int)
+)
+
+func newLoggingConn(baseName string, c net.Conn) net.Conn {
+	uniqNameMu.Lock()
+	defer uniqNameMu.Unlock()
+	uniqNameNext[baseName]++
+	return &loggingConn{
+		name: fmt.Sprintf("%s-%d", baseName, uniqNameNext[baseName]),
+		Conn: c,
+	}
+}
+
+func (c *loggingConn) Write(p []byte) (n int, err error) {
+	log.Printf("%s.Write(%d) = ....", c.name, len(p))
+	n, err = c.Conn.Write(p)
+	log.Printf("%s.Write(%d) = %d, %v", c.name, len(p), n, err)
+	return
+}
+
+func (c *loggingConn) Read(p []byte) (n int, err error) {
+	log.Printf("%s.Read(%d) = ....", c.name, len(p))
+	n, err = c.Conn.Read(p)
+	log.Printf("%s.Read(%d) = %d, %v", c.name, len(p), n, err)
+	return
+}
+
+func (c *loggingConn) Close() (err error) {
+	log.Printf("%s.Close() = ...", c.name)
+	err = c.Conn.Close()
+	log.Printf("%s.Close() = %v", c.name, err)
+	return
+}
+
+// checkConnErrorWriter writes to c.rwc and records any write errors to c.werr.
+// It only contains one field (and a pointer field at that), so it
+// fits in an interface value without an extra allocation.
+type checkConnErrorWriter struct {
+	c *conn
+}
+
+func (w checkConnErrorWriter) Write(p []byte) (n int, err error) {
+	n, err = w.c.w.Write(p) // c.w == c.rwc, except after a hijack, when rwc is nil.
+	if err != nil && w.c.werr == nil {
+		w.c.werr = err
+	}
+	return
+}
diff --git a/src/pkg/net/http/sniff.go b/src/net/http/sniff.go
similarity index 100%
rename from src/pkg/net/http/sniff.go
rename to src/net/http/sniff.go
diff --git a/src/pkg/net/http/sniff_test.go b/src/net/http/sniff_test.go
similarity index 100%
rename from src/pkg/net/http/sniff_test.go
rename to src/net/http/sniff_test.go
diff --git a/src/pkg/net/http/status.go b/src/net/http/status.go
similarity index 100%
rename from src/pkg/net/http/status.go
rename to src/net/http/status.go
diff --git a/src/pkg/net/http/testdata/file b/src/net/http/testdata/file
similarity index 100%
rename from src/pkg/net/http/testdata/file
rename to src/net/http/testdata/file
diff --git a/src/pkg/net/http/testdata/index.html b/src/net/http/testdata/index.html
similarity index 100%
rename from src/pkg/net/http/testdata/index.html
rename to src/net/http/testdata/index.html
diff --git a/src/pkg/net/http/testdata/style.css b/src/net/http/testdata/style.css
similarity index 100%
rename from src/pkg/net/http/testdata/style.css
rename to src/net/http/testdata/style.css
diff --git a/src/net/http/transfer.go b/src/net/http/transfer.go
new file mode 100644
index 0000000..5205003
--- /dev/null
+++ b/src/net/http/transfer.go
@@ -0,0 +1,737 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package http
+
+import (
+	"bufio"
+	"bytes"
+	"errors"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"net/http/internal"
+	"net/textproto"
+	"sort"
+	"strconv"
+	"strings"
+	"sync"
+)
+
+// ErrLineTooLong is returned when reading request or response bodies
+// with malformed chunked encoding.
+var ErrLineTooLong = internal.ErrLineTooLong
+
+type errorReader struct {
+	err error
+}
+
+func (r *errorReader) Read(p []byte) (n int, err error) {
+	return 0, r.err
+}
+
+// transferWriter inspects the fields of a user-supplied Request or Response,
+// sanitizes them without changing the user object and provides methods for
+// writing the respective header, body and trailer in wire format.
+type transferWriter struct {
+	Method           string
+	Body             io.Reader
+	BodyCloser       io.Closer
+	ResponseToHEAD   bool
+	ContentLength    int64 // -1 means unknown, 0 means exactly none
+	Close            bool
+	TransferEncoding []string
+	Trailer          Header
+}
+
+func newTransferWriter(r interface{}) (t *transferWriter, err error) {
+	t = &transferWriter{}
+
+	// Extract relevant fields
+	atLeastHTTP11 := false
+	switch rr := r.(type) {
+	case *Request:
+		if rr.ContentLength != 0 && rr.Body == nil {
+			return nil, fmt.Errorf("http: Request.ContentLength=%d with nil Body", rr.ContentLength)
+		}
+		t.Method = rr.Method
+		t.Body = rr.Body
+		t.BodyCloser = rr.Body
+		t.ContentLength = rr.ContentLength
+		t.Close = rr.Close
+		t.TransferEncoding = rr.TransferEncoding
+		t.Trailer = rr.Trailer
+		atLeastHTTP11 = rr.ProtoAtLeast(1, 1)
+		if t.Body != nil && len(t.TransferEncoding) == 0 && atLeastHTTP11 {
+			if t.ContentLength == 0 {
+				// Test to see if it's actually zero or just unset.
+				var buf [1]byte
+				n, rerr := io.ReadFull(t.Body, buf[:])
+				if rerr != nil && rerr != io.EOF {
+					t.ContentLength = -1
+					t.Body = &errorReader{rerr}
+				} else if n == 1 {
+					// Oh, guess there is data in this Body Reader after all.
+					// The ContentLength field just wasn't set.
+					// Stich the Body back together again, re-attaching our
+					// consumed byte.
+					t.ContentLength = -1
+					t.Body = io.MultiReader(bytes.NewReader(buf[:]), t.Body)
+				} else {
+					// Body is actually empty.
+					t.Body = nil
+					t.BodyCloser = nil
+				}
+			}
+			if t.ContentLength < 0 {
+				t.TransferEncoding = []string{"chunked"}
+			}
+		}
+	case *Response:
+		if rr.Request != nil {
+			t.Method = rr.Request.Method
+		}
+		t.Body = rr.Body
+		t.BodyCloser = rr.Body
+		t.ContentLength = rr.ContentLength
+		t.Close = rr.Close
+		t.TransferEncoding = rr.TransferEncoding
+		t.Trailer = rr.Trailer
+		atLeastHTTP11 = rr.ProtoAtLeast(1, 1)
+		t.ResponseToHEAD = noBodyExpected(t.Method)
+	}
+
+	// Sanitize Body,ContentLength,TransferEncoding
+	if t.ResponseToHEAD {
+		t.Body = nil
+		if chunked(t.TransferEncoding) {
+			t.ContentLength = -1
+		}
+	} else {
+		if !atLeastHTTP11 || t.Body == nil {
+			t.TransferEncoding = nil
+		}
+		if chunked(t.TransferEncoding) {
+			t.ContentLength = -1
+		} else if t.Body == nil { // no chunking, no body
+			t.ContentLength = 0
+		}
+	}
+
+	// Sanitize Trailer
+	if !chunked(t.TransferEncoding) {
+		t.Trailer = nil
+	}
+
+	return t, nil
+}
+
+func noBodyExpected(requestMethod string) bool {
+	return requestMethod == "HEAD"
+}
+
+func (t *transferWriter) shouldSendContentLength() bool {
+	if chunked(t.TransferEncoding) {
+		return false
+	}
+	if t.ContentLength > 0 {
+		return true
+	}
+	// Many servers expect a Content-Length for these methods
+	if t.Method == "POST" || t.Method == "PUT" {
+		return true
+	}
+	if t.ContentLength == 0 && isIdentity(t.TransferEncoding) {
+		return true
+	}
+
+	return false
+}
+
+func (t *transferWriter) WriteHeader(w io.Writer) error {
+	if t.Close {
+		if _, err := io.WriteString(w, "Connection: close\r\n"); err != nil {
+			return err
+		}
+	}
+
+	// Write Content-Length and/or Transfer-Encoding whose values are a
+	// function of the sanitized field triple (Body, ContentLength,
+	// TransferEncoding)
+	if t.shouldSendContentLength() {
+		if _, err := io.WriteString(w, "Content-Length: "); err != nil {
+			return err
+		}
+		if _, err := io.WriteString(w, strconv.FormatInt(t.ContentLength, 10)+"\r\n"); err != nil {
+			return err
+		}
+	} else if chunked(t.TransferEncoding) {
+		if _, err := io.WriteString(w, "Transfer-Encoding: chunked\r\n"); err != nil {
+			return err
+		}
+	}
+
+	// Write Trailer header
+	if t.Trailer != nil {
+		keys := make([]string, 0, len(t.Trailer))
+		for k := range t.Trailer {
+			k = CanonicalHeaderKey(k)
+			switch k {
+			case "Transfer-Encoding", "Trailer", "Content-Length":
+				return &badStringError{"invalid Trailer key", k}
+			}
+			keys = append(keys, k)
+		}
+		if len(keys) > 0 {
+			sort.Strings(keys)
+			// TODO: could do better allocation-wise here, but trailers are rare,
+			// so being lazy for now.
+			if _, err := io.WriteString(w, "Trailer: "+strings.Join(keys, ",")+"\r\n"); err != nil {
+				return err
+			}
+		}
+	}
+
+	return nil
+}
+
+func (t *transferWriter) WriteBody(w io.Writer) error {
+	var err error
+	var ncopy int64
+
+	// Write body
+	if t.Body != nil {
+		if chunked(t.TransferEncoding) {
+			cw := internal.NewChunkedWriter(w)
+			_, err = io.Copy(cw, t.Body)
+			if err == nil {
+				err = cw.Close()
+			}
+		} else if t.ContentLength == -1 {
+			ncopy, err = io.Copy(w, t.Body)
+		} else {
+			ncopy, err = io.Copy(w, io.LimitReader(t.Body, t.ContentLength))
+			if err != nil {
+				return err
+			}
+			var nextra int64
+			nextra, err = io.Copy(ioutil.Discard, t.Body)
+			ncopy += nextra
+		}
+		if err != nil {
+			return err
+		}
+		if err = t.BodyCloser.Close(); err != nil {
+			return err
+		}
+	}
+
+	if !t.ResponseToHEAD && t.ContentLength != -1 && t.ContentLength != ncopy {
+		return fmt.Errorf("http: ContentLength=%d with Body length %d",
+			t.ContentLength, ncopy)
+	}
+
+	// TODO(petar): Place trailer writer code here.
+	if chunked(t.TransferEncoding) {
+		// Write Trailer header
+		if t.Trailer != nil {
+			if err := t.Trailer.Write(w); err != nil {
+				return err
+			}
+		}
+		// Last chunk, empty trailer
+		_, err = io.WriteString(w, "\r\n")
+	}
+	return err
+}
+
+type transferReader struct {
+	// Input
+	Header        Header
+	StatusCode    int
+	RequestMethod string
+	ProtoMajor    int
+	ProtoMinor    int
+	// Output
+	Body             io.ReadCloser
+	ContentLength    int64
+	TransferEncoding []string
+	Close            bool
+	Trailer          Header
+}
+
+// bodyAllowedForStatus reports whether a given response status code
+// permits a body.  See RFC2616, section 4.4.
+func bodyAllowedForStatus(status int) bool {
+	switch {
+	case status >= 100 && status <= 199:
+		return false
+	case status == 204:
+		return false
+	case status == 304:
+		return false
+	}
+	return true
+}
+
+var (
+	suppressedHeaders304    = []string{"Content-Type", "Content-Length", "Transfer-Encoding"}
+	suppressedHeadersNoBody = []string{"Content-Length", "Transfer-Encoding"}
+)
+
+func suppressedHeaders(status int) []string {
+	switch {
+	case status == 304:
+		// RFC 2616 section 10.3.5: "the response MUST NOT include other entity-headers"
+		return suppressedHeaders304
+	case !bodyAllowedForStatus(status):
+		return suppressedHeadersNoBody
+	}
+	return nil
+}
+
+// msg is *Request or *Response.
+func readTransfer(msg interface{}, r *bufio.Reader) (err error) {
+	t := &transferReader{RequestMethod: "GET"}
+
+	// Unify input
+	isResponse := false
+	switch rr := msg.(type) {
+	case *Response:
+		t.Header = rr.Header
+		t.StatusCode = rr.StatusCode
+		t.ProtoMajor = rr.ProtoMajor
+		t.ProtoMinor = rr.ProtoMinor
+		t.Close = shouldClose(t.ProtoMajor, t.ProtoMinor, t.Header, true)
+		isResponse = true
+		if rr.Request != nil {
+			t.RequestMethod = rr.Request.Method
+		}
+	case *Request:
+		t.Header = rr.Header
+		t.ProtoMajor = rr.ProtoMajor
+		t.ProtoMinor = rr.ProtoMinor
+		// Transfer semantics for Requests are exactly like those for
+		// Responses with status code 200, responding to a GET method
+		t.StatusCode = 200
+	default:
+		panic("unexpected type")
+	}
+
+	// Default to HTTP/1.1
+	if t.ProtoMajor == 0 && t.ProtoMinor == 0 {
+		t.ProtoMajor, t.ProtoMinor = 1, 1
+	}
+
+	// Transfer encoding, content length
+	t.TransferEncoding, err = fixTransferEncoding(t.RequestMethod, t.Header)
+	if err != nil {
+		return err
+	}
+
+	realLength, err := fixLength(isResponse, t.StatusCode, t.RequestMethod, t.Header, t.TransferEncoding)
+	if err != nil {
+		return err
+	}
+	if isResponse && t.RequestMethod == "HEAD" {
+		if n, err := parseContentLength(t.Header.get("Content-Length")); err != nil {
+			return err
+		} else {
+			t.ContentLength = n
+		}
+	} else {
+		t.ContentLength = realLength
+	}
+
+	// Trailer
+	t.Trailer, err = fixTrailer(t.Header, t.TransferEncoding)
+	if err != nil {
+		return err
+	}
+
+	// If there is no Content-Length or chunked Transfer-Encoding on a *Response
+	// and the status is not 1xx, 204 or 304, then the body is unbounded.
+	// See RFC2616, section 4.4.
+	switch msg.(type) {
+	case *Response:
+		if realLength == -1 &&
+			!chunked(t.TransferEncoding) &&
+			bodyAllowedForStatus(t.StatusCode) {
+			// Unbounded body.
+			t.Close = true
+		}
+	}
+
+	// Prepare body reader.  ContentLength < 0 means chunked encoding
+	// or close connection when finished, since multipart is not supported yet
+	switch {
+	case chunked(t.TransferEncoding):
+		if noBodyExpected(t.RequestMethod) {
+			t.Body = eofReader
+		} else {
+			t.Body = &body{src: internal.NewChunkedReader(r), hdr: msg, r: r, closing: t.Close}
+		}
+	case realLength == 0:
+		t.Body = eofReader
+	case realLength > 0:
+		t.Body = &body{src: io.LimitReader(r, realLength), closing: t.Close}
+	default:
+		// realLength < 0, i.e. "Content-Length" not mentioned in header
+		if t.Close {
+			// Close semantics (i.e. HTTP/1.0)
+			t.Body = &body{src: r, closing: t.Close}
+		} else {
+			// Persistent connection (i.e. HTTP/1.1)
+			t.Body = eofReader
+		}
+	}
+
+	// Unify output
+	switch rr := msg.(type) {
+	case *Request:
+		rr.Body = t.Body
+		rr.ContentLength = t.ContentLength
+		rr.TransferEncoding = t.TransferEncoding
+		rr.Close = t.Close
+		rr.Trailer = t.Trailer
+	case *Response:
+		rr.Body = t.Body
+		rr.ContentLength = t.ContentLength
+		rr.TransferEncoding = t.TransferEncoding
+		rr.Close = t.Close
+		rr.Trailer = t.Trailer
+	}
+
+	return nil
+}
+
+// Checks whether chunked is part of the encodings stack
+func chunked(te []string) bool { return len(te) > 0 && te[0] == "chunked" }
+
+// Checks whether the encoding is explicitly "identity".
+func isIdentity(te []string) bool { return len(te) == 1 && te[0] == "identity" }
+
+// Sanitize transfer encoding
+func fixTransferEncoding(requestMethod string, header Header) ([]string, error) {
+	raw, present := header["Transfer-Encoding"]
+	if !present {
+		return nil, nil
+	}
+
+	delete(header, "Transfer-Encoding")
+
+	encodings := strings.Split(raw[0], ",")
+	te := make([]string, 0, len(encodings))
+	// TODO: Even though we only support "identity" and "chunked"
+	// encodings, the loop below is designed with foresight. One
+	// invariant that must be maintained is that, if present,
+	// chunked encoding must always come first.
+	for _, encoding := range encodings {
+		encoding = strings.ToLower(strings.TrimSpace(encoding))
+		// "identity" encoding is not recorded
+		if encoding == "identity" {
+			break
+		}
+		if encoding != "chunked" {
+			return nil, &badStringError{"unsupported transfer encoding", encoding}
+		}
+		te = te[0 : len(te)+1]
+		te[len(te)-1] = encoding
+	}
+	if len(te) > 1 {
+		return nil, &badStringError{"too many transfer encodings", strings.Join(te, ",")}
+	}
+	if len(te) > 0 {
+		// Chunked encoding trumps Content-Length. See RFC 2616
+		// Section 4.4. Currently len(te) > 0 implies chunked
+		// encoding.
+		delete(header, "Content-Length")
+		return te, nil
+	}
+
+	return nil, nil
+}
+
+// Determine the expected body length, using RFC 2616 Section 4.4. This
+// function is not a method, because ultimately it should be shared by
+// ReadResponse and ReadRequest.
+func fixLength(isResponse bool, status int, requestMethod string, header Header, te []string) (int64, error) {
+
+	// Logic based on response type or status
+	if noBodyExpected(requestMethod) {
+		return 0, nil
+	}
+	if status/100 == 1 {
+		return 0, nil
+	}
+	switch status {
+	case 204, 304:
+		return 0, nil
+	}
+
+	// Logic based on Transfer-Encoding
+	if chunked(te) {
+		return -1, nil
+	}
+
+	// Logic based on Content-Length
+	cl := strings.TrimSpace(header.get("Content-Length"))
+	if cl != "" {
+		n, err := parseContentLength(cl)
+		if err != nil {
+			return -1, err
+		}
+		return n, nil
+	} else {
+		header.Del("Content-Length")
+	}
+
+	if !isResponse && requestMethod == "GET" {
+		// RFC 2616 doesn't explicitly permit nor forbid an
+		// entity-body on a GET request so we permit one if
+		// declared, but we default to 0 here (not -1 below)
+		// if there's no mention of a body.
+		return 0, nil
+	}
+
+	// Body-EOF logic based on other methods (like closing, or chunked coding)
+	return -1, nil
+}
+
+// Determine whether to hang up after sending a request and body, or
+// receiving a response and body
+// 'header' is the request headers
+func shouldClose(major, minor int, header Header, removeCloseHeader bool) bool {
+	if major < 1 {
+		return true
+	} else if major == 1 && minor == 0 {
+		if !strings.Contains(strings.ToLower(header.get("Connection")), "keep-alive") {
+			return true
+		}
+		return false
+	} else {
+		// TODO: Should split on commas, toss surrounding white space,
+		// and check each field.
+		if strings.ToLower(header.get("Connection")) == "close" {
+			if removeCloseHeader {
+				header.Del("Connection")
+			}
+			return true
+		}
+	}
+	return false
+}
+
+// Parse the trailer header
+func fixTrailer(header Header, te []string) (Header, error) {
+	raw := header.get("Trailer")
+	if raw == "" {
+		return nil, nil
+	}
+
+	header.Del("Trailer")
+	trailer := make(Header)
+	keys := strings.Split(raw, ",")
+	for _, key := range keys {
+		key = CanonicalHeaderKey(strings.TrimSpace(key))
+		switch key {
+		case "Transfer-Encoding", "Trailer", "Content-Length":
+			return nil, &badStringError{"bad trailer key", key}
+		}
+		trailer[key] = nil
+	}
+	if len(trailer) == 0 {
+		return nil, nil
+	}
+	if !chunked(te) {
+		// Trailer and no chunking
+		return nil, ErrUnexpectedTrailer
+	}
+	return trailer, nil
+}
+
+// body turns a Reader into a ReadCloser.
+// Close ensures that the body has been fully read
+// and then reads the trailer if necessary.
+type body struct {
+	src     io.Reader
+	hdr     interface{}   // non-nil (Response or Request) value means read trailer
+	r       *bufio.Reader // underlying wire-format reader for the trailer
+	closing bool          // is the connection to be closed after reading body?
+
+	mu     sync.Mutex // guards closed, and calls to Read and Close
+	closed bool
+}
+
+// ErrBodyReadAfterClose is returned when reading a Request or Response
+// Body after the body has been closed. This typically happens when the body is
+// read after an HTTP Handler calls WriteHeader or Write on its
+// ResponseWriter.
+var ErrBodyReadAfterClose = errors.New("http: invalid Read on closed Body")
+
+func (b *body) Read(p []byte) (n int, err error) {
+	b.mu.Lock()
+	defer b.mu.Unlock()
+	if b.closed {
+		return 0, ErrBodyReadAfterClose
+	}
+	return b.readLocked(p)
+}
+
+// Must hold b.mu.
+func (b *body) readLocked(p []byte) (n int, err error) {
+	n, err = b.src.Read(p)
+
+	if err == io.EOF {
+		// Chunked case. Read the trailer.
+		if b.hdr != nil {
+			if e := b.readTrailer(); e != nil {
+				err = e
+			}
+			b.hdr = nil
+		} else {
+			// If the server declared the Content-Length, our body is a LimitedReader
+			// and we need to check whether this EOF arrived early.
+			if lr, ok := b.src.(*io.LimitedReader); ok && lr.N > 0 {
+				err = io.ErrUnexpectedEOF
+			}
+		}
+	}
+
+	// If we can return an EOF here along with the read data, do
+	// so. This is optional per the io.Reader contract, but doing
+	// so helps the HTTP transport code recycle its connection
+	// earlier (since it will see this EOF itself), even if the
+	// client doesn't do future reads or Close.
+	if err == nil && n > 0 {
+		if lr, ok := b.src.(*io.LimitedReader); ok && lr.N == 0 {
+			err = io.EOF
+		}
+	}
+
+	return n, err
+}
+
+var (
+	singleCRLF = []byte("\r\n")
+	doubleCRLF = []byte("\r\n\r\n")
+)
+
+func seeUpcomingDoubleCRLF(r *bufio.Reader) bool {
+	for peekSize := 4; ; peekSize++ {
+		// This loop stops when Peek returns an error,
+		// which it does when r's buffer has been filled.
+		buf, err := r.Peek(peekSize)
+		if bytes.HasSuffix(buf, doubleCRLF) {
+			return true
+		}
+		if err != nil {
+			break
+		}
+	}
+	return false
+}
+
+var errTrailerEOF = errors.New("http: unexpected EOF reading trailer")
+
+func (b *body) readTrailer() error {
+	// The common case, since nobody uses trailers.
+	buf, err := b.r.Peek(2)
+	if bytes.Equal(buf, singleCRLF) {
+		b.r.ReadByte()
+		b.r.ReadByte()
+		return nil
+	}
+	if len(buf) < 2 {
+		return errTrailerEOF
+	}
+	if err != nil {
+		return err
+	}
+
+	// Make sure there's a header terminator coming up, to prevent
+	// a DoS with an unbounded size Trailer.  It's not easy to
+	// slip in a LimitReader here, as textproto.NewReader requires
+	// a concrete *bufio.Reader.  Also, we can't get all the way
+	// back up to our conn's LimitedReader that *might* be backing
+	// this bufio.Reader.  Instead, a hack: we iteratively Peek up
+	// to the bufio.Reader's max size, looking for a double CRLF.
+	// This limits the trailer to the underlying buffer size, typically 4kB.
+	if !seeUpcomingDoubleCRLF(b.r) {
+		return errors.New("http: suspiciously long trailer after chunked body")
+	}
+
+	hdr, err := textproto.NewReader(b.r).ReadMIMEHeader()
+	if err != nil {
+		if err == io.EOF {
+			return errTrailerEOF
+		}
+		return err
+	}
+	switch rr := b.hdr.(type) {
+	case *Request:
+		mergeSetHeader(&rr.Trailer, Header(hdr))
+	case *Response:
+		mergeSetHeader(&rr.Trailer, Header(hdr))
+	}
+	return nil
+}
+
+func mergeSetHeader(dst *Header, src Header) {
+	if *dst == nil {
+		*dst = src
+		return
+	}
+	for k, vv := range src {
+		(*dst)[k] = vv
+	}
+}
+
+func (b *body) Close() error {
+	b.mu.Lock()
+	defer b.mu.Unlock()
+	if b.closed {
+		return nil
+	}
+	var err error
+	switch {
+	case b.hdr == nil && b.closing:
+		// no trailer and closing the connection next.
+		// no point in reading to EOF.
+	default:
+		// Fully consume the body, which will also lead to us reading
+		// the trailer headers after the body, if present.
+		_, err = io.Copy(ioutil.Discard, bodyLocked{b})
+	}
+	b.closed = true
+	return err
+}
+
+// bodyLocked is a io.Reader reading from a *body when its mutex is
+// already held.
+type bodyLocked struct {
+	b *body
+}
+
+func (bl bodyLocked) Read(p []byte) (n int, err error) {
+	if bl.b.closed {
+		return 0, ErrBodyReadAfterClose
+	}
+	return bl.b.readLocked(p)
+}
+
+// parseContentLength trims whitespace from s and returns -1 if no value
+// is set, or the value if it's >= 0.
+func parseContentLength(cl string) (int64, error) {
+	cl = strings.TrimSpace(cl)
+	if cl == "" {
+		return -1, nil
+	}
+	n, err := strconv.ParseInt(cl, 10, 64)
+	if err != nil || n < 0 {
+		return 0, &badStringError{"bad Content-Length", cl}
+	}
+	return n, nil
+
+}
diff --git a/src/pkg/net/http/transfer_test.go b/src/net/http/transfer_test.go
similarity index 100%
rename from src/pkg/net/http/transfer_test.go
rename to src/net/http/transfer_test.go
diff --git a/src/net/http/transport.go b/src/net/http/transport.go
new file mode 100644
index 0000000..782f7cd
--- /dev/null
+++ b/src/net/http/transport.go
@@ -0,0 +1,1275 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// HTTP client implementation. See RFC 2616.
+//
+// This is the low-level Transport implementation of RoundTripper.
+// The high-level interface is in client.go.
+
+package http
+
+import (
+	"bufio"
+	"compress/gzip"
+	"crypto/tls"
+	"errors"
+	"fmt"
+	"io"
+	"log"
+	"net"
+	"net/url"
+	"os"
+	"strings"
+	"sync"
+	"time"
+)
+
+// DefaultTransport is the default implementation of Transport and is
+// used by DefaultClient. It establishes network connections as needed
+// and caches them for reuse by subsequent calls. It uses HTTP proxies
+// as directed by the $HTTP_PROXY and $NO_PROXY (or $http_proxy and
+// $no_proxy) environment variables.
+var DefaultTransport RoundTripper = &Transport{
+	Proxy: ProxyFromEnvironment,
+	Dial: (&net.Dialer{
+		Timeout:   30 * time.Second,
+		KeepAlive: 30 * time.Second,
+	}).Dial,
+	TLSHandshakeTimeout: 10 * time.Second,
+}
+
+// DefaultMaxIdleConnsPerHost is the default value of Transport's
+// MaxIdleConnsPerHost.
+const DefaultMaxIdleConnsPerHost = 2
+
+// Transport is an implementation of RoundTripper that supports HTTP,
+// HTTPS, and HTTP proxies (for either HTTP or HTTPS with CONNECT).
+// Transport can also cache connections for future re-use.
+type Transport struct {
+	idleMu     sync.Mutex
+	wantIdle   bool // user has requested to close all idle conns
+	idleConn   map[connectMethodKey][]*persistConn
+	idleConnCh map[connectMethodKey]chan *persistConn
+
+	reqMu       sync.Mutex
+	reqCanceler map[*Request]func()
+
+	altMu    sync.RWMutex
+	altProto map[string]RoundTripper // nil or map of URI scheme => RoundTripper
+
+	// Proxy specifies a function to return a proxy for a given
+	// Request. If the function returns a non-nil error, the
+	// request is aborted with the provided error.
+	// If Proxy is nil or returns a nil *URL, no proxy is used.
+	Proxy func(*Request) (*url.URL, error)
+
+	// Dial specifies the dial function for creating unencrypted
+	// TCP connections.
+	// If Dial is nil, net.Dial is used.
+	Dial func(network, addr string) (net.Conn, error)
+
+	// DialTLS specifies an optional dial function for creating
+	// TLS connections for non-proxied HTTPS requests.
+	//
+	// If DialTLS is nil, Dial and TLSClientConfig are used.
+	//
+	// If DialTLS is set, the Dial hook is not used for HTTPS
+	// requests and the TLSClientConfig and TLSHandshakeTimeout
+	// are ignored. The returned net.Conn is assumed to already be
+	// past the TLS handshake.
+	DialTLS func(network, addr string) (net.Conn, error)
+
+	// TLSClientConfig specifies the TLS configuration to use with
+	// tls.Client. If nil, the default configuration is used.
+	TLSClientConfig *tls.Config
+
+	// TLSHandshakeTimeout specifies the maximum amount of time waiting to
+	// wait for a TLS handshake. Zero means no timeout.
+	TLSHandshakeTimeout time.Duration
+
+	// DisableKeepAlives, if true, prevents re-use of TCP connections
+	// between different HTTP requests.
+	DisableKeepAlives bool
+
+	// DisableCompression, if true, prevents the Transport from
+	// requesting compression with an "Accept-Encoding: gzip"
+	// request header when the Request contains no existing
+	// Accept-Encoding value. If the Transport requests gzip on
+	// its own and gets a gzipped response, it's transparently
+	// decoded in the Response.Body. However, if the user
+	// explicitly requested gzip it is not automatically
+	// uncompressed.
+	DisableCompression bool
+
+	// MaxIdleConnsPerHost, if non-zero, controls the maximum idle
+	// (keep-alive) to keep per-host.  If zero,
+	// DefaultMaxIdleConnsPerHost is used.
+	MaxIdleConnsPerHost int
+
+	// ResponseHeaderTimeout, if non-zero, specifies the amount of
+	// time to wait for a server's response headers after fully
+	// writing the request (including its body, if any). This
+	// time does not include the time to read the response body.
+	ResponseHeaderTimeout time.Duration
+
+	// TODO: tunable on global max cached connections
+	// TODO: tunable on timeout on cached connections
+}
+
+// ProxyFromEnvironment returns the URL of the proxy to use for a
+// given request, as indicated by the environment variables
+// HTTP_PROXY, HTTPS_PROXY and NO_PROXY (or the lowercase versions
+// thereof). HTTPS_PROXY takes precedence over HTTP_PROXY for https
+// requests.
+//
+// The environment values may be either a complete URL or a
+// "host[:port]", in which case the "http" scheme is assumed.
+// An error is returned if the value is a different form.
+//
+// A nil URL and nil error are returned if no proxy is defined in the
+// environment, or a proxy should not be used for the given request,
+// as defined by NO_PROXY.
+//
+// As a special case, if req.URL.Host is "localhost" (with or without
+// a port number), then a nil URL and nil error will be returned.
+func ProxyFromEnvironment(req *Request) (*url.URL, error) {
+	var proxy string
+	if req.URL.Scheme == "https" {
+		proxy = httpsProxyEnv.Get()
+	}
+	if proxy == "" {
+		proxy = httpProxyEnv.Get()
+	}
+	if proxy == "" {
+		return nil, nil
+	}
+	if !useProxy(canonicalAddr(req.URL)) {
+		return nil, nil
+	}
+	proxyURL, err := url.Parse(proxy)
+	if err != nil || !strings.HasPrefix(proxyURL.Scheme, "http") {
+		// proxy was bogus. Try prepending "http://" to it and
+		// see if that parses correctly. If not, we fall
+		// through and complain about the original one.
+		if proxyURL, err := url.Parse("http://" + proxy); err == nil {
+			return proxyURL, nil
+		}
+	}
+	if err != nil {
+		return nil, fmt.Errorf("invalid proxy address %q: %v", proxy, err)
+	}
+	return proxyURL, nil
+}
+
+// ProxyURL returns a proxy function (for use in a Transport)
+// that always returns the same URL.
+func ProxyURL(fixedURL *url.URL) func(*Request) (*url.URL, error) {
+	return func(*Request) (*url.URL, error) {
+		return fixedURL, nil
+	}
+}
+
+// transportRequest is a wrapper around a *Request that adds
+// optional extra headers to write.
+type transportRequest struct {
+	*Request        // original request, not to be mutated
+	extra    Header // extra headers to write, or nil
+}
+
+func (tr *transportRequest) extraHeaders() Header {
+	if tr.extra == nil {
+		tr.extra = make(Header)
+	}
+	return tr.extra
+}
+
+// RoundTrip implements the RoundTripper interface.
+//
+// For higher-level HTTP client support (such as handling of cookies
+// and redirects), see Get, Post, and the Client type.
+func (t *Transport) RoundTrip(req *Request) (resp *Response, err error) {
+	if req.URL == nil {
+		req.closeBody()
+		return nil, errors.New("http: nil Request.URL")
+	}
+	if req.Header == nil {
+		req.closeBody()
+		return nil, errors.New("http: nil Request.Header")
+	}
+	if req.URL.Scheme != "http" && req.URL.Scheme != "https" {
+		t.altMu.RLock()
+		var rt RoundTripper
+		if t.altProto != nil {
+			rt = t.altProto[req.URL.Scheme]
+		}
+		t.altMu.RUnlock()
+		if rt == nil {
+			req.closeBody()
+			return nil, &badStringError{"unsupported protocol scheme", req.URL.Scheme}
+		}
+		return rt.RoundTrip(req)
+	}
+	if req.URL.Host == "" {
+		req.closeBody()
+		return nil, errors.New("http: no Host in request URL")
+	}
+	treq := &transportRequest{Request: req}
+	cm, err := t.connectMethodForRequest(treq)
+	if err != nil {
+		req.closeBody()
+		return nil, err
+	}
+
+	// Get the cached or newly-created connection to either the
+	// host (for http or https), the http proxy, or the http proxy
+	// pre-CONNECTed to https server.  In any case, we'll be ready
+	// to send it requests.
+	pconn, err := t.getConn(req, cm)
+	if err != nil {
+		t.setReqCanceler(req, nil)
+		req.closeBody()
+		return nil, err
+	}
+
+	return pconn.roundTrip(treq)
+}
+
+// RegisterProtocol registers a new protocol with scheme.
+// The Transport will pass requests using the given scheme to rt.
+// It is rt's responsibility to simulate HTTP request semantics.
+//
+// RegisterProtocol can be used by other packages to provide
+// implementations of protocol schemes like "ftp" or "file".
+func (t *Transport) RegisterProtocol(scheme string, rt RoundTripper) {
+	if scheme == "http" || scheme == "https" {
+		panic("protocol " + scheme + " already registered")
+	}
+	t.altMu.Lock()
+	defer t.altMu.Unlock()
+	if t.altProto == nil {
+		t.altProto = make(map[string]RoundTripper)
+	}
+	if _, exists := t.altProto[scheme]; exists {
+		panic("protocol " + scheme + " already registered")
+	}
+	t.altProto[scheme] = rt
+}
+
+// CloseIdleConnections closes any connections which were previously
+// connected from previous requests but are now sitting idle in
+// a "keep-alive" state. It does not interrupt any connections currently
+// in use.
+func (t *Transport) CloseIdleConnections() {
+	t.idleMu.Lock()
+	m := t.idleConn
+	t.idleConn = nil
+	t.idleConnCh = nil
+	t.wantIdle = true
+	t.idleMu.Unlock()
+	for _, conns := range m {
+		for _, pconn := range conns {
+			pconn.close()
+		}
+	}
+}
+
+// CancelRequest cancels an in-flight request by closing its
+// connection.
+func (t *Transport) CancelRequest(req *Request) {
+	t.reqMu.Lock()
+	cancel := t.reqCanceler[req]
+	t.reqMu.Unlock()
+	if cancel != nil {
+		cancel()
+	}
+}
+
+//
+// Private implementation past this point.
+//
+
+var (
+	httpProxyEnv = &envOnce{
+		names: []string{"HTTP_PROXY", "http_proxy"},
+	}
+	httpsProxyEnv = &envOnce{
+		names: []string{"HTTPS_PROXY", "https_proxy"},
+	}
+	noProxyEnv = &envOnce{
+		names: []string{"NO_PROXY", "no_proxy"},
+	}
+)
+
+// envOnce looks up an environment variable (optionally by multiple
+// names) once. It mitigates expensive lookups on some platforms
+// (e.g. Windows).
+type envOnce struct {
+	names []string
+	once  sync.Once
+	val   string
+}
+
+func (e *envOnce) Get() string {
+	e.once.Do(e.init)
+	return e.val
+}
+
+func (e *envOnce) init() {
+	for _, n := range e.names {
+		e.val = os.Getenv(n)
+		if e.val != "" {
+			return
+		}
+	}
+}
+
+// reset is used by tests
+func (e *envOnce) reset() {
+	e.once = sync.Once{}
+	e.val = ""
+}
+
+func (t *Transport) connectMethodForRequest(treq *transportRequest) (cm connectMethod, err error) {
+	cm.targetScheme = treq.URL.Scheme
+	cm.targetAddr = canonicalAddr(treq.URL)
+	if t.Proxy != nil {
+		cm.proxyURL, err = t.Proxy(treq.Request)
+	}
+	return cm, err
+}
+
+// proxyAuth returns the Proxy-Authorization header to set
+// on requests, if applicable.
+func (cm *connectMethod) proxyAuth() string {
+	if cm.proxyURL == nil {
+		return ""
+	}
+	if u := cm.proxyURL.User; u != nil {
+		username := u.Username()
+		password, _ := u.Password()
+		return "Basic " + basicAuth(username, password)
+	}
+	return ""
+}
+
+// putIdleConn adds pconn to the list of idle persistent connections awaiting
+// a new request.
+// If pconn is no longer needed or not in a good state, putIdleConn
+// returns false.
+func (t *Transport) putIdleConn(pconn *persistConn) bool {
+	if t.DisableKeepAlives || t.MaxIdleConnsPerHost < 0 {
+		pconn.close()
+		return false
+	}
+	if pconn.isBroken() {
+		return false
+	}
+	key := pconn.cacheKey
+	max := t.MaxIdleConnsPerHost
+	if max == 0 {
+		max = DefaultMaxIdleConnsPerHost
+	}
+	t.idleMu.Lock()
+
+	waitingDialer := t.idleConnCh[key]
+	select {
+	case waitingDialer <- pconn:
+		// We're done with this pconn and somebody else is
+		// currently waiting for a conn of this type (they're
+		// actively dialing, but this conn is ready
+		// first). Chrome calls this socket late binding.  See
+		// https://insouciant.org/tech/connection-management-in-chromium/
+		t.idleMu.Unlock()
+		return true
+	default:
+		if waitingDialer != nil {
+			// They had populated this, but their dial won
+			// first, so we can clean up this map entry.
+			delete(t.idleConnCh, key)
+		}
+	}
+	if t.wantIdle {
+		t.idleMu.Unlock()
+		pconn.close()
+		return false
+	}
+	if t.idleConn == nil {
+		t.idleConn = make(map[connectMethodKey][]*persistConn)
+	}
+	if len(t.idleConn[key]) >= max {
+		t.idleMu.Unlock()
+		pconn.close()
+		return false
+	}
+	for _, exist := range t.idleConn[key] {
+		if exist == pconn {
+			log.Fatalf("dup idle pconn %p in freelist", pconn)
+		}
+	}
+	t.idleConn[key] = append(t.idleConn[key], pconn)
+	t.idleMu.Unlock()
+	return true
+}
+
+// getIdleConnCh returns a channel to receive and return idle
+// persistent connection for the given connectMethod.
+// It may return nil, if persistent connections are not being used.
+func (t *Transport) getIdleConnCh(cm connectMethod) chan *persistConn {
+	if t.DisableKeepAlives {
+		return nil
+	}
+	key := cm.key()
+	t.idleMu.Lock()
+	defer t.idleMu.Unlock()
+	t.wantIdle = false
+	if t.idleConnCh == nil {
+		t.idleConnCh = make(map[connectMethodKey]chan *persistConn)
+	}
+	ch, ok := t.idleConnCh[key]
+	if !ok {
+		ch = make(chan *persistConn)
+		t.idleConnCh[key] = ch
+	}
+	return ch
+}
+
+func (t *Transport) getIdleConn(cm connectMethod) (pconn *persistConn) {
+	key := cm.key()
+	t.idleMu.Lock()
+	defer t.idleMu.Unlock()
+	if t.idleConn == nil {
+		return nil
+	}
+	for {
+		pconns, ok := t.idleConn[key]
+		if !ok {
+			return nil
+		}
+		if len(pconns) == 1 {
+			pconn = pconns[0]
+			delete(t.idleConn, key)
+		} else {
+			// 2 or more cached connections; pop last
+			// TODO: queue?
+			pconn = pconns[len(pconns)-1]
+			t.idleConn[key] = pconns[:len(pconns)-1]
+		}
+		if !pconn.isBroken() {
+			return
+		}
+	}
+}
+
+func (t *Transport) setReqCanceler(r *Request, fn func()) {
+	t.reqMu.Lock()
+	defer t.reqMu.Unlock()
+	if t.reqCanceler == nil {
+		t.reqCanceler = make(map[*Request]func())
+	}
+	if fn != nil {
+		t.reqCanceler[r] = fn
+	} else {
+		delete(t.reqCanceler, r)
+	}
+}
+
+func (t *Transport) dial(network, addr string) (c net.Conn, err error) {
+	if t.Dial != nil {
+		return t.Dial(network, addr)
+	}
+	return net.Dial(network, addr)
+}
+
+// Testing hooks:
+var prePendingDial, postPendingDial func()
+
+// getConn dials and creates a new persistConn to the target as
+// specified in the connectMethod.  This includes doing a proxy CONNECT
+// and/or setting up TLS.  If this doesn't return an error, the persistConn
+// is ready to write requests to.
+func (t *Transport) getConn(req *Request, cm connectMethod) (*persistConn, error) {
+	if pc := t.getIdleConn(cm); pc != nil {
+		return pc, nil
+	}
+
+	type dialRes struct {
+		pc  *persistConn
+		err error
+	}
+	dialc := make(chan dialRes)
+
+	handlePendingDial := func() {
+		if prePendingDial != nil {
+			prePendingDial()
+		}
+		go func() {
+			if v := <-dialc; v.err == nil {
+				t.putIdleConn(v.pc)
+			}
+			if postPendingDial != nil {
+				postPendingDial()
+			}
+		}()
+	}
+
+	cancelc := make(chan struct{})
+	t.setReqCanceler(req, func() { close(cancelc) })
+
+	go func() {
+		pc, err := t.dialConn(cm)
+		dialc <- dialRes{pc, err}
+	}()
+
+	idleConnCh := t.getIdleConnCh(cm)
+	select {
+	case v := <-dialc:
+		// Our dial finished.
+		return v.pc, v.err
+	case pc := <-idleConnCh:
+		// Another request finished first and its net.Conn
+		// became available before our dial. Or somebody
+		// else's dial that they didn't use.
+		// But our dial is still going, so give it away
+		// when it finishes:
+		handlePendingDial()
+		return pc, nil
+	case <-cancelc:
+		handlePendingDial()
+		return nil, errors.New("net/http: request canceled while waiting for connection")
+	}
+}
+
+func (t *Transport) dialConn(cm connectMethod) (*persistConn, error) {
+	pconn := &persistConn{
+		t:          t,
+		cacheKey:   cm.key(),
+		reqch:      make(chan requestAndChan, 1),
+		writech:    make(chan writeRequest, 1),
+		closech:    make(chan struct{}),
+		writeErrCh: make(chan error, 1),
+	}
+	tlsDial := t.DialTLS != nil && cm.targetScheme == "https" && cm.proxyURL == nil
+	if tlsDial {
+		var err error
+		pconn.conn, err = t.DialTLS("tcp", cm.addr())
+		if err != nil {
+			return nil, err
+		}
+		if tc, ok := pconn.conn.(*tls.Conn); ok {
+			cs := tc.ConnectionState()
+			pconn.tlsState = &cs
+		}
+	} else {
+		conn, err := t.dial("tcp", cm.addr())
+		if err != nil {
+			if cm.proxyURL != nil {
+				err = fmt.Errorf("http: error connecting to proxy %s: %v", cm.proxyURL, err)
+			}
+			return nil, err
+		}
+		pconn.conn = conn
+	}
+
+	// Proxy setup.
+	switch {
+	case cm.proxyURL == nil:
+		// Do nothing. Not using a proxy.
+	case cm.targetScheme == "http":
+		pconn.isProxy = true
+		if pa := cm.proxyAuth(); pa != "" {
+			pconn.mutateHeaderFunc = func(h Header) {
+				h.Set("Proxy-Authorization", pa)
+			}
+		}
+	case cm.targetScheme == "https":
+		conn := pconn.conn
+		connectReq := &Request{
+			Method: "CONNECT",
+			URL:    &url.URL{Opaque: cm.targetAddr},
+			Host:   cm.targetAddr,
+			Header: make(Header),
+		}
+		if pa := cm.proxyAuth(); pa != "" {
+			connectReq.Header.Set("Proxy-Authorization", pa)
+		}
+		connectReq.Write(conn)
+
+		// Read response.
+		// Okay to use and discard buffered reader here, because
+		// TLS server will not speak until spoken to.
+		br := bufio.NewReader(conn)
+		resp, err := ReadResponse(br, connectReq)
+		if err != nil {
+			conn.Close()
+			return nil, err
+		}
+		if resp.StatusCode != 200 {
+			f := strings.SplitN(resp.Status, " ", 2)
+			conn.Close()
+			return nil, errors.New(f[1])
+		}
+	}
+
+	if cm.targetScheme == "https" && !tlsDial {
+		// Initiate TLS and check remote host name against certificate.
+		cfg := t.TLSClientConfig
+		if cfg == nil || cfg.ServerName == "" {
+			host := cm.tlsHost()
+			if cfg == nil {
+				cfg = &tls.Config{ServerName: host}
+			} else {
+				clone := *cfg // shallow clone
+				clone.ServerName = host
+				cfg = &clone
+			}
+		}
+		plainConn := pconn.conn
+		tlsConn := tls.Client(plainConn, cfg)
+		errc := make(chan error, 2)
+		var timer *time.Timer // for canceling TLS handshake
+		if d := t.TLSHandshakeTimeout; d != 0 {
+			timer = time.AfterFunc(d, func() {
+				errc <- tlsHandshakeTimeoutError{}
+			})
+		}
+		go func() {
+			err := tlsConn.Handshake()
+			if timer != nil {
+				timer.Stop()
+			}
+			errc <- err
+		}()
+		if err := <-errc; err != nil {
+			plainConn.Close()
+			return nil, err
+		}
+		if !cfg.InsecureSkipVerify {
+			if err := tlsConn.VerifyHostname(cfg.ServerName); err != nil {
+				plainConn.Close()
+				return nil, err
+			}
+		}
+		cs := tlsConn.ConnectionState()
+		pconn.tlsState = &cs
+		pconn.conn = tlsConn
+	}
+
+	pconn.br = bufio.NewReader(noteEOFReader{pconn.conn, &pconn.sawEOF})
+	pconn.bw = bufio.NewWriter(pconn.conn)
+	go pconn.readLoop()
+	go pconn.writeLoop()
+	return pconn, nil
+}
+
+// useProxy returns true if requests to addr should use a proxy,
+// according to the NO_PROXY or no_proxy environment variable.
+// addr is always a canonicalAddr with a host and port.
+func useProxy(addr string) bool {
+	if len(addr) == 0 {
+		return true
+	}
+	host, _, err := net.SplitHostPort(addr)
+	if err != nil {
+		return false
+	}
+	if host == "localhost" {
+		return false
+	}
+	if ip := net.ParseIP(host); ip != nil {
+		if ip.IsLoopback() {
+			return false
+		}
+	}
+
+	no_proxy := noProxyEnv.Get()
+	if no_proxy == "*" {
+		return false
+	}
+
+	addr = strings.ToLower(strings.TrimSpace(addr))
+	if hasPort(addr) {
+		addr = addr[:strings.LastIndex(addr, ":")]
+	}
+
+	for _, p := range strings.Split(no_proxy, ",") {
+		p = strings.ToLower(strings.TrimSpace(p))
+		if len(p) == 0 {
+			continue
+		}
+		if hasPort(p) {
+			p = p[:strings.LastIndex(p, ":")]
+		}
+		if addr == p {
+			return false
+		}
+		if p[0] == '.' && (strings.HasSuffix(addr, p) || addr == p[1:]) {
+			// no_proxy ".foo.com" matches "bar.foo.com" or "foo.com"
+			return false
+		}
+		if p[0] != '.' && strings.HasSuffix(addr, p) && addr[len(addr)-len(p)-1] == '.' {
+			// no_proxy "foo.com" matches "bar.foo.com"
+			return false
+		}
+	}
+	return true
+}
+
+// connectMethod is the map key (in its String form) for keeping persistent
+// TCP connections alive for subsequent HTTP requests.
+//
+// A connect method may be of the following types:
+//
+// Cache key form                Description
+// -----------------             -------------------------
+// |http|foo.com                 http directly to server, no proxy
+// |https|foo.com                https directly to server, no proxy
+// http://proxy.com|https|foo.com  http to proxy, then CONNECT to foo.com
+// http://proxy.com|http           http to proxy, http to anywhere after that
+//
+// Note: no support to https to the proxy yet.
+//
+type connectMethod struct {
+	proxyURL     *url.URL // nil for no proxy, else full proxy URL
+	targetScheme string   // "http" or "https"
+	targetAddr   string   // Not used if proxy + http targetScheme (4th example in table)
+}
+
+func (cm *connectMethod) key() connectMethodKey {
+	proxyStr := ""
+	targetAddr := cm.targetAddr
+	if cm.proxyURL != nil {
+		proxyStr = cm.proxyURL.String()
+		if cm.targetScheme == "http" {
+			targetAddr = ""
+		}
+	}
+	return connectMethodKey{
+		proxy:  proxyStr,
+		scheme: cm.targetScheme,
+		addr:   targetAddr,
+	}
+}
+
+// addr returns the first hop "host:port" to which we need to TCP connect.
+func (cm *connectMethod) addr() string {
+	if cm.proxyURL != nil {
+		return canonicalAddr(cm.proxyURL)
+	}
+	return cm.targetAddr
+}
+
+// tlsHost returns the host name to match against the peer's
+// TLS certificate.
+func (cm *connectMethod) tlsHost() string {
+	h := cm.targetAddr
+	if hasPort(h) {
+		h = h[:strings.LastIndex(h, ":")]
+	}
+	return h
+}
+
+// connectMethodKey is the map key version of connectMethod, with a
+// stringified proxy URL (or the empty string) instead of a pointer to
+// a URL.
+type connectMethodKey struct {
+	proxy, scheme, addr string
+}
+
+func (k connectMethodKey) String() string {
+	// Only used by tests.
+	return fmt.Sprintf("%s|%s|%s", k.proxy, k.scheme, k.addr)
+}
+
+// persistConn wraps a connection, usually a persistent one
+// (but may be used for non-keep-alive requests as well)
+type persistConn struct {
+	t        *Transport
+	cacheKey connectMethodKey
+	conn     net.Conn
+	tlsState *tls.ConnectionState
+	br       *bufio.Reader       // from conn
+	sawEOF   bool                // whether we've seen EOF from conn; owned by readLoop
+	bw       *bufio.Writer       // to conn
+	reqch    chan requestAndChan // written by roundTrip; read by readLoop
+	writech  chan writeRequest   // written by roundTrip; read by writeLoop
+	closech  chan struct{}       // closed when conn closed
+	isProxy  bool
+	// writeErrCh passes the request write error (usually nil)
+	// from the writeLoop goroutine to the readLoop which passes
+	// it off to the res.Body reader, which then uses it to decide
+	// whether or not a connection can be reused. Issue 7569.
+	writeErrCh chan error
+
+	lk                   sync.Mutex // guards following fields
+	numExpectedResponses int
+	closed               bool // whether conn has been closed
+	broken               bool // an error has happened on this connection; marked broken so it's not reused.
+	// mutateHeaderFunc is an optional func to modify extra
+	// headers on each outbound request before it's written. (the
+	// original Request given to RoundTrip is not modified)
+	mutateHeaderFunc func(Header)
+}
+
+// isBroken reports whether this connection is in a known broken state.
+func (pc *persistConn) isBroken() bool {
+	pc.lk.Lock()
+	b := pc.broken
+	pc.lk.Unlock()
+	return b
+}
+
+func (pc *persistConn) cancelRequest() {
+	pc.conn.Close()
+}
+
+var remoteSideClosedFunc func(error) bool // or nil to use default
+
+func remoteSideClosed(err error) bool {
+	if err == io.EOF {
+		return true
+	}
+	if remoteSideClosedFunc != nil {
+		return remoteSideClosedFunc(err)
+	}
+	return false
+}
+
+func (pc *persistConn) readLoop() {
+	alive := true
+
+	for alive {
+		pb, err := pc.br.Peek(1)
+
+		pc.lk.Lock()
+		if pc.numExpectedResponses == 0 {
+			if !pc.closed {
+				pc.closeLocked()
+				if len(pb) > 0 {
+					log.Printf("Unsolicited response received on idle HTTP channel starting with %q; err=%v",
+						string(pb), err)
+				}
+			}
+			pc.lk.Unlock()
+			return
+		}
+		pc.lk.Unlock()
+
+		rc := <-pc.reqch
+
+		var resp *Response
+		if err == nil {
+			resp, err = ReadResponse(pc.br, rc.req)
+			if err == nil && resp.StatusCode == 100 {
+				// Skip any 100-continue for now.
+				// TODO(bradfitz): if rc.req had "Expect: 100-continue",
+				// actually block the request body write and signal the
+				// writeLoop now to begin sending it. (Issue 2184) For now we
+				// eat it, since we're never expecting one.
+				resp, err = ReadResponse(pc.br, rc.req)
+			}
+		}
+
+		if resp != nil {
+			resp.TLS = pc.tlsState
+		}
+
+		hasBody := resp != nil && rc.req.Method != "HEAD" && resp.ContentLength != 0
+
+		if err != nil {
+			pc.close()
+		} else {
+			if rc.addedGzip && hasBody && resp.Header.Get("Content-Encoding") == "gzip" {
+				resp.Header.Del("Content-Encoding")
+				resp.Header.Del("Content-Length")
+				resp.ContentLength = -1
+				resp.Body = &gzipReader{body: resp.Body}
+			}
+			resp.Body = &bodyEOFSignal{body: resp.Body}
+		}
+
+		if err != nil || resp.Close || rc.req.Close || resp.StatusCode <= 199 {
+			// Don't do keep-alive on error if either party requested a close
+			// or we get an unexpected informational (1xx) response.
+			// StatusCode 100 is already handled above.
+			alive = false
+		}
+
+		var waitForBodyRead chan bool
+		if hasBody {
+			waitForBodyRead = make(chan bool, 2)
+			resp.Body.(*bodyEOFSignal).earlyCloseFn = func() error {
+				// Sending false here sets alive to
+				// false and closes the connection
+				// below.
+				waitForBodyRead <- false
+				return nil
+			}
+			resp.Body.(*bodyEOFSignal).fn = func(err error) {
+				waitForBodyRead <- alive &&
+					err == nil &&
+					!pc.sawEOF &&
+					pc.wroteRequest() &&
+					pc.t.putIdleConn(pc)
+			}
+		}
+
+		if alive && !hasBody {
+			alive = !pc.sawEOF &&
+				pc.wroteRequest() &&
+				pc.t.putIdleConn(pc)
+		}
+
+		rc.ch <- responseAndError{resp, err}
+
+		// Wait for the just-returned response body to be fully consumed
+		// before we race and peek on the underlying bufio reader.
+		if waitForBodyRead != nil {
+			select {
+			case alive = <-waitForBodyRead:
+			case <-pc.closech:
+				alive = false
+			}
+		}
+
+		pc.t.setReqCanceler(rc.req, nil)
+
+		if !alive {
+			pc.close()
+		}
+	}
+}
+
+func (pc *persistConn) writeLoop() {
+	for {
+		select {
+		case wr := <-pc.writech:
+			if pc.isBroken() {
+				wr.ch <- errors.New("http: can't write HTTP request on broken connection")
+				continue
+			}
+			err := wr.req.Request.write(pc.bw, pc.isProxy, wr.req.extra)
+			if err == nil {
+				err = pc.bw.Flush()
+			}
+			if err != nil {
+				pc.markBroken()
+				wr.req.Request.closeBody()
+			}
+			pc.writeErrCh <- err // to the body reader, which might recycle us
+			wr.ch <- err         // to the roundTrip function
+		case <-pc.closech:
+			return
+		}
+	}
+}
+
+// wroteRequest is a check before recycling a connection that the previous write
+// (from writeLoop above) happened and was successful.
+func (pc *persistConn) wroteRequest() bool {
+	select {
+	case err := <-pc.writeErrCh:
+		// Common case: the write happened well before the response, so
+		// avoid creating a timer.
+		return err == nil
+	default:
+		// Rare case: the request was written in writeLoop above but
+		// before it could send to pc.writeErrCh, the reader read it
+		// all, processed it, and called us here. In this case, give the
+		// write goroutine a bit of time to finish its send.
+		//
+		// Less rare case: We also get here in the legitimate case of
+		// Issue 7569, where the writer is still writing (or stalled),
+		// but the server has already replied. In this case, we don't
+		// want to wait too long, and we want to return false so this
+		// connection isn't re-used.
+		select {
+		case err := <-pc.writeErrCh:
+			return err == nil
+		case <-time.After(50 * time.Millisecond):
+			return false
+		}
+	}
+}
+
+type responseAndError struct {
+	res *Response
+	err error
+}
+
+type requestAndChan struct {
+	req *Request
+	ch  chan responseAndError
+
+	// did the Transport (as opposed to the client code) add an
+	// Accept-Encoding gzip header? only if it we set it do
+	// we transparently decode the gzip.
+	addedGzip bool
+}
+
+// A writeRequest is sent by the readLoop's goroutine to the
+// writeLoop's goroutine to write a request while the read loop
+// concurrently waits on both the write response and the server's
+// reply.
+type writeRequest struct {
+	req *transportRequest
+	ch  chan<- error
+}
+
+type httpError struct {
+	err     string
+	timeout bool
+}
+
+func (e *httpError) Error() string   { return e.err }
+func (e *httpError) Timeout() bool   { return e.timeout }
+func (e *httpError) Temporary() bool { return true }
+
+var errTimeout error = &httpError{err: "net/http: timeout awaiting response headers", timeout: true}
+var errClosed error = &httpError{err: "net/http: transport closed before response was received"}
+
+func (pc *persistConn) roundTrip(req *transportRequest) (resp *Response, err error) {
+	pc.t.setReqCanceler(req.Request, pc.cancelRequest)
+	pc.lk.Lock()
+	pc.numExpectedResponses++
+	headerFn := pc.mutateHeaderFunc
+	pc.lk.Unlock()
+
+	if headerFn != nil {
+		headerFn(req.extraHeaders())
+	}
+
+	// Ask for a compressed version if the caller didn't set their
+	// own value for Accept-Encoding. We only attempt to
+	// uncompress the gzip stream if we were the layer that
+	// requested it.
+	requestedGzip := false
+	if !pc.t.DisableCompression &&
+		req.Header.Get("Accept-Encoding") == "" &&
+		req.Header.Get("Range") == "" &&
+		req.Method != "HEAD" {
+		// Request gzip only, not deflate. Deflate is ambiguous and
+		// not as universally supported anyway.
+		// See: http://www.gzip.org/zlib/zlib_faq.html#faq38
+		//
+		// Note that we don't request this for HEAD requests,
+		// due to a bug in nginx:
+		//   http://trac.nginx.org/nginx/ticket/358
+		//   http://golang.org/issue/5522
+		//
+		// We don't request gzip if the request is for a range, since
+		// auto-decoding a portion of a gzipped document will just fail
+		// anyway. See http://golang.org/issue/8923
+		requestedGzip = true
+		req.extraHeaders().Set("Accept-Encoding", "gzip")
+	}
+
+	// Write the request concurrently with waiting for a response,
+	// in case the server decides to reply before reading our full
+	// request body.
+	writeErrCh := make(chan error, 1)
+	pc.writech <- writeRequest{req, writeErrCh}
+
+	resc := make(chan responseAndError, 1)
+	pc.reqch <- requestAndChan{req.Request, resc, requestedGzip}
+
+	var re responseAndError
+	var pconnDeadCh = pc.closech
+	var failTicker <-chan time.Time
+	var respHeaderTimer <-chan time.Time
+WaitResponse:
+	for {
+		select {
+		case err := <-writeErrCh:
+			if err != nil {
+				re = responseAndError{nil, err}
+				pc.close()
+				break WaitResponse
+			}
+			if d := pc.t.ResponseHeaderTimeout; d > 0 {
+				respHeaderTimer = time.After(d)
+			}
+		case <-pconnDeadCh:
+			// The persist connection is dead. This shouldn't
+			// usually happen (only with Connection: close responses
+			// with no response bodies), but if it does happen it
+			// means either a) the remote server hung up on us
+			// prematurely, or b) the readLoop sent us a response &
+			// closed its closech at roughly the same time, and we
+			// selected this case first, in which case a response
+			// might still be coming soon.
+			//
+			// We can't avoid the select race in b) by using a unbuffered
+			// resc channel instead, because then goroutines can
+			// leak if we exit due to other errors.
+			pconnDeadCh = nil                               // avoid spinning
+			failTicker = time.After(100 * time.Millisecond) // arbitrary time to wait for resc
+		case <-failTicker:
+			re = responseAndError{err: errClosed}
+			break WaitResponse
+		case <-respHeaderTimer:
+			pc.close()
+			re = responseAndError{err: errTimeout}
+			break WaitResponse
+		case re = <-resc:
+			break WaitResponse
+		}
+	}
+
+	pc.lk.Lock()
+	pc.numExpectedResponses--
+	pc.lk.Unlock()
+
+	if re.err != nil {
+		pc.t.setReqCanceler(req.Request, nil)
+	}
+	return re.res, re.err
+}
+
+// markBroken marks a connection as broken (so it's not reused).
+// It differs from close in that it doesn't close the underlying
+// connection for use when it's still being read.
+func (pc *persistConn) markBroken() {
+	pc.lk.Lock()
+	defer pc.lk.Unlock()
+	pc.broken = true
+}
+
+func (pc *persistConn) close() {
+	pc.lk.Lock()
+	defer pc.lk.Unlock()
+	pc.closeLocked()
+}
+
+func (pc *persistConn) closeLocked() {
+	pc.broken = true
+	if !pc.closed {
+		pc.conn.Close()
+		pc.closed = true
+		close(pc.closech)
+	}
+	pc.mutateHeaderFunc = nil
+}
+
+var portMap = map[string]string{
+	"http":  "80",
+	"https": "443",
+}
+
+// canonicalAddr returns url.Host but always with a ":port" suffix
+func canonicalAddr(url *url.URL) string {
+	addr := url.Host
+	if !hasPort(addr) {
+		return addr + ":" + portMap[url.Scheme]
+	}
+	return addr
+}
+
+// bodyEOFSignal wraps a ReadCloser but runs fn (if non-nil) at most
+// once, right before its final (error-producing) Read or Close call
+// returns. If earlyCloseFn is non-nil and Close is called before
+// io.EOF is seen, earlyCloseFn is called instead of fn, and its
+// return value is the return value from Close.
+type bodyEOFSignal struct {
+	body         io.ReadCloser
+	mu           sync.Mutex   // guards following 4 fields
+	closed       bool         // whether Close has been called
+	rerr         error        // sticky Read error
+	fn           func(error)  // error will be nil on Read io.EOF
+	earlyCloseFn func() error // optional alt Close func used if io.EOF not seen
+}
+
+func (es *bodyEOFSignal) Read(p []byte) (n int, err error) {
+	es.mu.Lock()
+	closed, rerr := es.closed, es.rerr
+	es.mu.Unlock()
+	if closed {
+		return 0, errors.New("http: read on closed response body")
+	}
+	if rerr != nil {
+		return 0, rerr
+	}
+
+	n, err = es.body.Read(p)
+	if err != nil {
+		es.mu.Lock()
+		defer es.mu.Unlock()
+		if es.rerr == nil {
+			es.rerr = err
+		}
+		es.condfn(err)
+	}
+	return
+}
+
+func (es *bodyEOFSignal) Close() error {
+	es.mu.Lock()
+	defer es.mu.Unlock()
+	if es.closed {
+		return nil
+	}
+	es.closed = true
+	if es.earlyCloseFn != nil && es.rerr != io.EOF {
+		return es.earlyCloseFn()
+	}
+	err := es.body.Close()
+	es.condfn(err)
+	return err
+}
+
+// caller must hold es.mu.
+func (es *bodyEOFSignal) condfn(err error) {
+	if es.fn == nil {
+		return
+	}
+	if err == io.EOF {
+		err = nil
+	}
+	es.fn(err)
+	es.fn = nil
+}
+
+// gzipReader wraps a response body so it can lazily
+// call gzip.NewReader on the first call to Read
+type gzipReader struct {
+	body io.ReadCloser // underlying Response.Body
+	zr   io.Reader     // lazily-initialized gzip reader
+}
+
+func (gz *gzipReader) Read(p []byte) (n int, err error) {
+	if gz.zr == nil {
+		gz.zr, err = gzip.NewReader(gz.body)
+		if err != nil {
+			return 0, err
+		}
+	}
+	return gz.zr.Read(p)
+}
+
+func (gz *gzipReader) Close() error {
+	return gz.body.Close()
+}
+
+type readerAndCloser struct {
+	io.Reader
+	io.Closer
+}
+
+type tlsHandshakeTimeoutError struct{}
+
+func (tlsHandshakeTimeoutError) Timeout() bool   { return true }
+func (tlsHandshakeTimeoutError) Temporary() bool { return true }
+func (tlsHandshakeTimeoutError) Error() string   { return "net/http: TLS handshake timeout" }
+
+type noteEOFReader struct {
+	r      io.Reader
+	sawEOF *bool
+}
+
+func (nr noteEOFReader) Read(p []byte) (n int, err error) {
+	n, err = nr.r.Read(p)
+	if err == io.EOF {
+		*nr.sawEOF = true
+	}
+	return
+}
diff --git a/src/net/http/transport_test.go b/src/net/http/transport_test.go
new file mode 100644
index 0000000..defa633
--- /dev/null
+++ b/src/net/http/transport_test.go
@@ -0,0 +1,2324 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Tests for transport.go
+
+package http_test
+
+import (
+	"bufio"
+	"bytes"
+	"compress/gzip"
+	"crypto/rand"
+	"crypto/tls"
+	"errors"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"log"
+	"net"
+	"net/http"
+	. "net/http"
+	"net/http/httptest"
+	"net/url"
+	"os"
+	"runtime"
+	"strconv"
+	"strings"
+	"sync"
+	"testing"
+	"time"
+)
+
+// TODO: test 5 pipelined requests with responses: 1) OK, 2) OK, Connection: Close
+//       and then verify that the final 2 responses get errors back.
+
+// hostPortHandler writes back the client's "host:port".
+var hostPortHandler = HandlerFunc(func(w ResponseWriter, r *Request) {
+	if r.FormValue("close") == "true" {
+		w.Header().Set("Connection", "close")
+	}
+	w.Write([]byte(r.RemoteAddr))
+})
+
+// testCloseConn is a net.Conn tracked by a testConnSet.
+type testCloseConn struct {
+	net.Conn
+	set *testConnSet
+}
+
+func (c *testCloseConn) Close() error {
+	c.set.remove(c)
+	return c.Conn.Close()
+}
+
+// testConnSet tracks a set of TCP connections and whether they've
+// been closed.
+type testConnSet struct {
+	t      *testing.T
+	mu     sync.Mutex // guards closed and list
+	closed map[net.Conn]bool
+	list   []net.Conn // in order created
+}
+
+func (tcs *testConnSet) insert(c net.Conn) {
+	tcs.mu.Lock()
+	defer tcs.mu.Unlock()
+	tcs.closed[c] = false
+	tcs.list = append(tcs.list, c)
+}
+
+func (tcs *testConnSet) remove(c net.Conn) {
+	tcs.mu.Lock()
+	defer tcs.mu.Unlock()
+	tcs.closed[c] = true
+}
+
+// some tests use this to manage raw tcp connections for later inspection
+func makeTestDial(t *testing.T) (*testConnSet, func(n, addr string) (net.Conn, error)) {
+	connSet := &testConnSet{
+		t:      t,
+		closed: make(map[net.Conn]bool),
+	}
+	dial := func(n, addr string) (net.Conn, error) {
+		c, err := net.Dial(n, addr)
+		if err != nil {
+			return nil, err
+		}
+		tc := &testCloseConn{c, connSet}
+		connSet.insert(tc)
+		return tc, nil
+	}
+	return connSet, dial
+}
+
+func (tcs *testConnSet) check(t *testing.T) {
+	tcs.mu.Lock()
+	defer tcs.mu.Unlock()
+	for i := 4; i >= 0; i-- {
+		for i, c := range tcs.list {
+			if tcs.closed[c] {
+				continue
+			}
+			if i != 0 {
+				tcs.mu.Unlock()
+				time.Sleep(50 * time.Millisecond)
+				tcs.mu.Lock()
+				continue
+			}
+			t.Errorf("TCP connection #%d, %p (of %d total) was not closed", i+1, c, len(tcs.list))
+		}
+	}
+}
+
+// Two subsequent requests and verify their response is the same.
+// The response from the server is our own IP:port
+func TestTransportKeepAlives(t *testing.T) {
+	defer afterTest(t)
+	ts := httptest.NewServer(hostPortHandler)
+	defer ts.Close()
+
+	for _, disableKeepAlive := range []bool{false, true} {
+		tr := &Transport{DisableKeepAlives: disableKeepAlive}
+		defer tr.CloseIdleConnections()
+		c := &Client{Transport: tr}
+
+		fetch := func(n int) string {
+			res, err := c.Get(ts.URL)
+			if err != nil {
+				t.Fatalf("error in disableKeepAlive=%v, req #%d, GET: %v", disableKeepAlive, n, err)
+			}
+			body, err := ioutil.ReadAll(res.Body)
+			if err != nil {
+				t.Fatalf("error in disableKeepAlive=%v, req #%d, ReadAll: %v", disableKeepAlive, n, err)
+			}
+			return string(body)
+		}
+
+		body1 := fetch(1)
+		body2 := fetch(2)
+
+		bodiesDiffer := body1 != body2
+		if bodiesDiffer != disableKeepAlive {
+			t.Errorf("error in disableKeepAlive=%v. unexpected bodiesDiffer=%v; body1=%q; body2=%q",
+				disableKeepAlive, bodiesDiffer, body1, body2)
+		}
+	}
+}
+
+func TestTransportConnectionCloseOnResponse(t *testing.T) {
+	defer afterTest(t)
+	ts := httptest.NewServer(hostPortHandler)
+	defer ts.Close()
+
+	connSet, testDial := makeTestDial(t)
+
+	for _, connectionClose := range []bool{false, true} {
+		tr := &Transport{
+			Dial: testDial,
+		}
+		c := &Client{Transport: tr}
+
+		fetch := func(n int) string {
+			req := new(Request)
+			var err error
+			req.URL, err = url.Parse(ts.URL + fmt.Sprintf("/?close=%v", connectionClose))
+			if err != nil {
+				t.Fatalf("URL parse error: %v", err)
+			}
+			req.Method = "GET"
+			req.Proto = "HTTP/1.1"
+			req.ProtoMajor = 1
+			req.ProtoMinor = 1
+
+			res, err := c.Do(req)
+			if err != nil {
+				t.Fatalf("error in connectionClose=%v, req #%d, Do: %v", connectionClose, n, err)
+			}
+			defer res.Body.Close()
+			body, err := ioutil.ReadAll(res.Body)
+			if err != nil {
+				t.Fatalf("error in connectionClose=%v, req #%d, ReadAll: %v", connectionClose, n, err)
+			}
+			return string(body)
+		}
+
+		body1 := fetch(1)
+		body2 := fetch(2)
+		bodiesDiffer := body1 != body2
+		if bodiesDiffer != connectionClose {
+			t.Errorf("error in connectionClose=%v. unexpected bodiesDiffer=%v; body1=%q; body2=%q",
+				connectionClose, bodiesDiffer, body1, body2)
+		}
+
+		tr.CloseIdleConnections()
+	}
+
+	connSet.check(t)
+}
+
+func TestTransportConnectionCloseOnRequest(t *testing.T) {
+	defer afterTest(t)
+	ts := httptest.NewServer(hostPortHandler)
+	defer ts.Close()
+
+	connSet, testDial := makeTestDial(t)
+
+	for _, connectionClose := range []bool{false, true} {
+		tr := &Transport{
+			Dial: testDial,
+		}
+		c := &Client{Transport: tr}
+
+		fetch := func(n int) string {
+			req := new(Request)
+			var err error
+			req.URL, err = url.Parse(ts.URL)
+			if err != nil {
+				t.Fatalf("URL parse error: %v", err)
+			}
+			req.Method = "GET"
+			req.Proto = "HTTP/1.1"
+			req.ProtoMajor = 1
+			req.ProtoMinor = 1
+			req.Close = connectionClose
+
+			res, err := c.Do(req)
+			if err != nil {
+				t.Fatalf("error in connectionClose=%v, req #%d, Do: %v", connectionClose, n, err)
+			}
+			body, err := ioutil.ReadAll(res.Body)
+			if err != nil {
+				t.Fatalf("error in connectionClose=%v, req #%d, ReadAll: %v", connectionClose, n, err)
+			}
+			return string(body)
+		}
+
+		body1 := fetch(1)
+		body2 := fetch(2)
+		bodiesDiffer := body1 != body2
+		if bodiesDiffer != connectionClose {
+			t.Errorf("error in connectionClose=%v. unexpected bodiesDiffer=%v; body1=%q; body2=%q",
+				connectionClose, bodiesDiffer, body1, body2)
+		}
+
+		tr.CloseIdleConnections()
+	}
+
+	connSet.check(t)
+}
+
+func TestTransportIdleCacheKeys(t *testing.T) {
+	defer afterTest(t)
+	ts := httptest.NewServer(hostPortHandler)
+	defer ts.Close()
+
+	tr := &Transport{DisableKeepAlives: false}
+	c := &Client{Transport: tr}
+
+	if e, g := 0, len(tr.IdleConnKeysForTesting()); e != g {
+		t.Errorf("After CloseIdleConnections expected %d idle conn cache keys; got %d", e, g)
+	}
+
+	resp, err := c.Get(ts.URL)
+	if err != nil {
+		t.Error(err)
+	}
+	ioutil.ReadAll(resp.Body)
+
+	keys := tr.IdleConnKeysForTesting()
+	if e, g := 1, len(keys); e != g {
+		t.Fatalf("After Get expected %d idle conn cache keys; got %d", e, g)
+	}
+
+	if e := "|http|" + ts.Listener.Addr().String(); keys[0] != e {
+		t.Errorf("Expected idle cache key %q; got %q", e, keys[0])
+	}
+
+	tr.CloseIdleConnections()
+	if e, g := 0, len(tr.IdleConnKeysForTesting()); e != g {
+		t.Errorf("After CloseIdleConnections expected %d idle conn cache keys; got %d", e, g)
+	}
+}
+
+// Tests that the HTTP transport re-uses connections when a client
+// reads to the end of a response Body without closing it.
+func TestTransportReadToEndReusesConn(t *testing.T) {
+	defer afterTest(t)
+	const msg = "foobar"
+
+	var addrSeen map[string]int
+	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+		addrSeen[r.RemoteAddr]++
+		if r.URL.Path == "/chunked/" {
+			w.WriteHeader(200)
+			w.(http.Flusher).Flush()
+		} else {
+			w.Header().Set("Content-Type", strconv.Itoa(len(msg)))
+			w.WriteHeader(200)
+		}
+		w.Write([]byte(msg))
+	}))
+	defer ts.Close()
+
+	buf := make([]byte, len(msg))
+
+	for pi, path := range []string{"/content-length/", "/chunked/"} {
+		wantLen := []int{len(msg), -1}[pi]
+		addrSeen = make(map[string]int)
+		for i := 0; i < 3; i++ {
+			res, err := http.Get(ts.URL + path)
+			if err != nil {
+				t.Errorf("Get %s: %v", path, err)
+				continue
+			}
+			// We want to close this body eventually (before the
+			// defer afterTest at top runs), but not before the
+			// len(addrSeen) check at the bottom of this test,
+			// since Closing this early in the loop would risk
+			// making connections be re-used for the wrong reason.
+			defer res.Body.Close()
+
+			if res.ContentLength != int64(wantLen) {
+				t.Errorf("%s res.ContentLength = %d; want %d", path, res.ContentLength, wantLen)
+			}
+			n, err := res.Body.Read(buf)
+			if n != len(msg) || err != io.EOF {
+				t.Errorf("%s Read = %v, %v; want %d, EOF", path, n, err, len(msg))
+			}
+		}
+		if len(addrSeen) != 1 {
+			t.Errorf("for %s, server saw %d distinct client addresses; want 1", path, len(addrSeen))
+		}
+	}
+}
+
+func TestTransportMaxPerHostIdleConns(t *testing.T) {
+	defer afterTest(t)
+	resch := make(chan string)
+	gotReq := make(chan bool)
+	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+		gotReq <- true
+		msg := <-resch
+		_, err := w.Write([]byte(msg))
+		if err != nil {
+			t.Fatalf("Write: %v", err)
+		}
+	}))
+	defer ts.Close()
+	maxIdleConns := 2
+	tr := &Transport{DisableKeepAlives: false, MaxIdleConnsPerHost: maxIdleConns}
+	c := &Client{Transport: tr}
+
+	// Start 3 outstanding requests and wait for the server to get them.
+	// Their responses will hang until we write to resch, though.
+	donech := make(chan bool)
+	doReq := func() {
+		resp, err := c.Get(ts.URL)
+		if err != nil {
+			t.Error(err)
+			return
+		}
+		if _, err := ioutil.ReadAll(resp.Body); err != nil {
+			t.Errorf("ReadAll: %v", err)
+			return
+		}
+		donech <- true
+	}
+	go doReq()
+	<-gotReq
+	go doReq()
+	<-gotReq
+	go doReq()
+	<-gotReq
+
+	if e, g := 0, len(tr.IdleConnKeysForTesting()); e != g {
+		t.Fatalf("Before writes, expected %d idle conn cache keys; got %d", e, g)
+	}
+
+	resch <- "res1"
+	<-donech
+	keys := tr.IdleConnKeysForTesting()
+	if e, g := 1, len(keys); e != g {
+		t.Fatalf("after first response, expected %d idle conn cache keys; got %d", e, g)
+	}
+	cacheKey := "|http|" + ts.Listener.Addr().String()
+	if keys[0] != cacheKey {
+		t.Fatalf("Expected idle cache key %q; got %q", cacheKey, keys[0])
+	}
+	if e, g := 1, tr.IdleConnCountForTesting(cacheKey); e != g {
+		t.Errorf("after first response, expected %d idle conns; got %d", e, g)
+	}
+
+	resch <- "res2"
+	<-donech
+	if e, g := 2, tr.IdleConnCountForTesting(cacheKey); e != g {
+		t.Errorf("after second response, expected %d idle conns; got %d", e, g)
+	}
+
+	resch <- "res3"
+	<-donech
+	if e, g := maxIdleConns, tr.IdleConnCountForTesting(cacheKey); e != g {
+		t.Errorf("after third response, still expected %d idle conns; got %d", e, g)
+	}
+}
+
+func TestTransportServerClosingUnexpectedly(t *testing.T) {
+	defer afterTest(t)
+	ts := httptest.NewServer(hostPortHandler)
+	defer ts.Close()
+
+	tr := &Transport{}
+	c := &Client{Transport: tr}
+
+	fetch := func(n, retries int) string {
+		condFatalf := func(format string, arg ...interface{}) {
+			if retries <= 0 {
+				t.Fatalf(format, arg...)
+			}
+			t.Logf("retrying shortly after expected error: "+format, arg...)
+			time.Sleep(time.Second / time.Duration(retries))
+		}
+		for retries >= 0 {
+			retries--
+			res, err := c.Get(ts.URL)
+			if err != nil {
+				condFatalf("error in req #%d, GET: %v", n, err)
+				continue
+			}
+			body, err := ioutil.ReadAll(res.Body)
+			if err != nil {
+				condFatalf("error in req #%d, ReadAll: %v", n, err)
+				continue
+			}
+			res.Body.Close()
+			return string(body)
+		}
+		panic("unreachable")
+	}
+
+	body1 := fetch(1, 0)
+	body2 := fetch(2, 0)
+
+	ts.CloseClientConnections() // surprise!
+
+	// This test has an expected race. Sleeping for 25 ms prevents
+	// it on most fast machines, causing the next fetch() call to
+	// succeed quickly.  But if we do get errors, fetch() will retry 5
+	// times with some delays between.
+	time.Sleep(25 * time.Millisecond)
+
+	body3 := fetch(3, 5)
+
+	if body1 != body2 {
+		t.Errorf("expected body1 and body2 to be equal")
+	}
+	if body2 == body3 {
+		t.Errorf("expected body2 and body3 to be different")
+	}
+}
+
+// Test for http://golang.org/issue/2616 (appropriate issue number)
+// This fails pretty reliably with GOMAXPROCS=100 or something high.
+func TestStressSurpriseServerCloses(t *testing.T) {
+	defer afterTest(t)
+	if testing.Short() {
+		t.Skip("skipping test in short mode")
+	}
+	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+		w.Header().Set("Content-Length", "5")
+		w.Header().Set("Content-Type", "text/plain")
+		w.Write([]byte("Hello"))
+		w.(Flusher).Flush()
+		conn, buf, _ := w.(Hijacker).Hijack()
+		buf.Flush()
+		conn.Close()
+	}))
+	defer ts.Close()
+
+	tr := &Transport{DisableKeepAlives: false}
+	c := &Client{Transport: tr}
+
+	// Do a bunch of traffic from different goroutines. Send to activityc
+	// after each request completes, regardless of whether it failed.
+	const (
+		numClients    = 50
+		reqsPerClient = 250
+	)
+	activityc := make(chan bool)
+	for i := 0; i < numClients; i++ {
+		go func() {
+			for i := 0; i < reqsPerClient; i++ {
+				res, err := c.Get(ts.URL)
+				if err == nil {
+					// We expect errors since the server is
+					// hanging up on us after telling us to
+					// send more requests, so we don't
+					// actually care what the error is.
+					// But we want to close the body in cases
+					// where we won the race.
+					res.Body.Close()
+				}
+				activityc <- true
+			}
+		}()
+	}
+
+	// Make sure all the request come back, one way or another.
+	for i := 0; i < numClients*reqsPerClient; i++ {
+		select {
+		case <-activityc:
+		case <-time.After(5 * time.Second):
+			t.Fatalf("presumed deadlock; no HTTP client activity seen in awhile")
+		}
+	}
+}
+
+// TestTransportHeadResponses verifies that we deal with Content-Lengths
+// with no bodies properly
+func TestTransportHeadResponses(t *testing.T) {
+	defer afterTest(t)
+	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+		if r.Method != "HEAD" {
+			panic("expected HEAD; got " + r.Method)
+		}
+		w.Header().Set("Content-Length", "123")
+		w.WriteHeader(200)
+	}))
+	defer ts.Close()
+
+	tr := &Transport{DisableKeepAlives: false}
+	c := &Client{Transport: tr}
+	for i := 0; i < 2; i++ {
+		res, err := c.Head(ts.URL)
+		if err != nil {
+			t.Errorf("error on loop %d: %v", i, err)
+			continue
+		}
+		if e, g := "123", res.Header.Get("Content-Length"); e != g {
+			t.Errorf("loop %d: expected Content-Length header of %q, got %q", i, e, g)
+		}
+		if e, g := int64(123), res.ContentLength; e != g {
+			t.Errorf("loop %d: expected res.ContentLength of %v, got %v", i, e, g)
+		}
+		if all, err := ioutil.ReadAll(res.Body); err != nil {
+			t.Errorf("loop %d: Body ReadAll: %v", i, err)
+		} else if len(all) != 0 {
+			t.Errorf("Bogus body %q", all)
+		}
+	}
+}
+
+// TestTransportHeadChunkedResponse verifies that we ignore chunked transfer-encoding
+// on responses to HEAD requests.
+func TestTransportHeadChunkedResponse(t *testing.T) {
+	defer afterTest(t)
+	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+		if r.Method != "HEAD" {
+			panic("expected HEAD; got " + r.Method)
+		}
+		w.Header().Set("Transfer-Encoding", "chunked") // client should ignore
+		w.Header().Set("x-client-ipport", r.RemoteAddr)
+		w.WriteHeader(200)
+	}))
+	defer ts.Close()
+
+	tr := &Transport{DisableKeepAlives: false}
+	c := &Client{Transport: tr}
+
+	res1, err := c.Head(ts.URL)
+	if err != nil {
+		t.Fatalf("request 1 error: %v", err)
+	}
+	res2, err := c.Head(ts.URL)
+	if err != nil {
+		t.Fatalf("request 2 error: %v", err)
+	}
+	if v1, v2 := res1.Header.Get("x-client-ipport"), res2.Header.Get("x-client-ipport"); v1 != v2 {
+		t.Errorf("ip/ports differed between head requests: %q vs %q", v1, v2)
+	}
+}
+
+var roundTripTests = []struct {
+	accept       string
+	expectAccept string
+	compressed   bool
+}{
+	// Requests with no accept-encoding header use transparent compression
+	{"", "gzip", false},
+	// Requests with other accept-encoding should pass through unmodified
+	{"foo", "foo", false},
+	// Requests with accept-encoding == gzip should be passed through
+	{"gzip", "gzip", true},
+}
+
+// Test that the modification made to the Request by the RoundTripper is cleaned up
+func TestRoundTripGzip(t *testing.T) {
+	defer afterTest(t)
+	const responseBody = "test response body"
+	ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) {
+		accept := req.Header.Get("Accept-Encoding")
+		if expect := req.FormValue("expect_accept"); accept != expect {
+			t.Errorf("in handler, test %v: Accept-Encoding = %q, want %q",
+				req.FormValue("testnum"), accept, expect)
+		}
+		if accept == "gzip" {
+			rw.Header().Set("Content-Encoding", "gzip")
+			gz := gzip.NewWriter(rw)
+			gz.Write([]byte(responseBody))
+			gz.Close()
+		} else {
+			rw.Header().Set("Content-Encoding", accept)
+			rw.Write([]byte(responseBody))
+		}
+	}))
+	defer ts.Close()
+
+	for i, test := range roundTripTests {
+		// Test basic request (no accept-encoding)
+		req, _ := NewRequest("GET", fmt.Sprintf("%s/?testnum=%d&expect_accept=%s", ts.URL, i, test.expectAccept), nil)
+		if test.accept != "" {
+			req.Header.Set("Accept-Encoding", test.accept)
+		}
+		res, err := DefaultTransport.RoundTrip(req)
+		var body []byte
+		if test.compressed {
+			var r *gzip.Reader
+			r, err = gzip.NewReader(res.Body)
+			if err != nil {
+				t.Errorf("%d. gzip NewReader: %v", i, err)
+				continue
+			}
+			body, err = ioutil.ReadAll(r)
+			res.Body.Close()
+		} else {
+			body, err = ioutil.ReadAll(res.Body)
+		}
+		if err != nil {
+			t.Errorf("%d. Error: %q", i, err)
+			continue
+		}
+		if g, e := string(body), responseBody; g != e {
+			t.Errorf("%d. body = %q; want %q", i, g, e)
+		}
+		if g, e := req.Header.Get("Accept-Encoding"), test.accept; g != e {
+			t.Errorf("%d. Accept-Encoding = %q; want %q (it was mutated, in violation of RoundTrip contract)", i, g, e)
+		}
+		if g, e := res.Header.Get("Content-Encoding"), test.accept; g != e {
+			t.Errorf("%d. Content-Encoding = %q; want %q", i, g, e)
+		}
+	}
+
+}
+
+func TestTransportGzip(t *testing.T) {
+	defer afterTest(t)
+	const testString = "The test string aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+	const nRandBytes = 1024 * 1024
+	ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) {
+		if req.Method == "HEAD" {
+			if g := req.Header.Get("Accept-Encoding"); g != "" {
+				t.Errorf("HEAD request sent with Accept-Encoding of %q; want none", g)
+			}
+			return
+		}
+		if g, e := req.Header.Get("Accept-Encoding"), "gzip"; g != e {
+			t.Errorf("Accept-Encoding = %q, want %q", g, e)
+		}
+		rw.Header().Set("Content-Encoding", "gzip")
+
+		var w io.Writer = rw
+		var buf bytes.Buffer
+		if req.FormValue("chunked") == "0" {
+			w = &buf
+			defer io.Copy(rw, &buf)
+			defer func() {
+				rw.Header().Set("Content-Length", strconv.Itoa(buf.Len()))
+			}()
+		}
+		gz := gzip.NewWriter(w)
+		gz.Write([]byte(testString))
+		if req.FormValue("body") == "large" {
+			io.CopyN(gz, rand.Reader, nRandBytes)
+		}
+		gz.Close()
+	}))
+	defer ts.Close()
+
+	for _, chunked := range []string{"1", "0"} {
+		c := &Client{Transport: &Transport{}}
+
+		// First fetch something large, but only read some of it.
+		res, err := c.Get(ts.URL + "/?body=large&chunked=" + chunked)
+		if err != nil {
+			t.Fatalf("large get: %v", err)
+		}
+		buf := make([]byte, len(testString))
+		n, err := io.ReadFull(res.Body, buf)
+		if err != nil {
+			t.Fatalf("partial read of large response: size=%d, %v", n, err)
+		}
+		if e, g := testString, string(buf); e != g {
+			t.Errorf("partial read got %q, expected %q", g, e)
+		}
+		res.Body.Close()
+		// Read on the body, even though it's closed
+		n, err = res.Body.Read(buf)
+		if n != 0 || err == nil {
+			t.Errorf("expected error post-closed large Read; got = %d, %v", n, err)
+		}
+
+		// Then something small.
+		res, err = c.Get(ts.URL + "/?chunked=" + chunked)
+		if err != nil {
+			t.Fatal(err)
+		}
+		body, err := ioutil.ReadAll(res.Body)
+		if err != nil {
+			t.Fatal(err)
+		}
+		if g, e := string(body), testString; g != e {
+			t.Fatalf("body = %q; want %q", g, e)
+		}
+		if g, e := res.Header.Get("Content-Encoding"), ""; g != e {
+			t.Fatalf("Content-Encoding = %q; want %q", g, e)
+		}
+
+		// Read on the body after it's been fully read:
+		n, err = res.Body.Read(buf)
+		if n != 0 || err == nil {
+			t.Errorf("expected Read error after exhausted reads; got %d, %v", n, err)
+		}
+		res.Body.Close()
+		n, err = res.Body.Read(buf)
+		if n != 0 || err == nil {
+			t.Errorf("expected Read error after Close; got %d, %v", n, err)
+		}
+	}
+
+	// And a HEAD request too, because they're always weird.
+	c := &Client{Transport: &Transport{}}
+	res, err := c.Head(ts.URL)
+	if err != nil {
+		t.Fatalf("Head: %v", err)
+	}
+	if res.StatusCode != 200 {
+		t.Errorf("Head status=%d; want=200", res.StatusCode)
+	}
+}
+
+func TestTransportProxy(t *testing.T) {
+	defer afterTest(t)
+	ch := make(chan string, 1)
+	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+		ch <- "real server"
+	}))
+	defer ts.Close()
+	proxy := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+		ch <- "proxy for " + r.URL.String()
+	}))
+	defer proxy.Close()
+
+	pu, err := url.Parse(proxy.URL)
+	if err != nil {
+		t.Fatal(err)
+	}
+	c := &Client{Transport: &Transport{Proxy: ProxyURL(pu)}}
+	c.Head(ts.URL)
+	got := <-ch
+	want := "proxy for " + ts.URL + "/"
+	if got != want {
+		t.Errorf("want %q, got %q", want, got)
+	}
+}
+
+// TestTransportGzipRecursive sends a gzip quine and checks that the
+// client gets the same value back. This is more cute than anything,
+// but checks that we don't recurse forever, and checks that
+// Content-Encoding is removed.
+func TestTransportGzipRecursive(t *testing.T) {
+	defer afterTest(t)
+	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+		w.Header().Set("Content-Encoding", "gzip")
+		w.Write(rgz)
+	}))
+	defer ts.Close()
+
+	c := &Client{Transport: &Transport{}}
+	res, err := c.Get(ts.URL)
+	if err != nil {
+		t.Fatal(err)
+	}
+	body, err := ioutil.ReadAll(res.Body)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if !bytes.Equal(body, rgz) {
+		t.Fatalf("Incorrect result from recursive gz:\nhave=%x\nwant=%x",
+			body, rgz)
+	}
+	if g, e := res.Header.Get("Content-Encoding"), ""; g != e {
+		t.Fatalf("Content-Encoding = %q; want %q", g, e)
+	}
+}
+
+// golang.org/issue/7750: request fails when server replies with
+// a short gzip body
+func TestTransportGzipShort(t *testing.T) {
+	defer afterTest(t)
+	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+		w.Header().Set("Content-Encoding", "gzip")
+		w.Write([]byte{0x1f, 0x8b})
+	}))
+	defer ts.Close()
+
+	tr := &Transport{}
+	defer tr.CloseIdleConnections()
+	c := &Client{Transport: tr}
+	res, err := c.Get(ts.URL)
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer res.Body.Close()
+	_, err = ioutil.ReadAll(res.Body)
+	if err == nil {
+		t.Fatal("Expect an error from reading a body.")
+	}
+	if err != io.ErrUnexpectedEOF {
+		t.Errorf("ReadAll error = %v; want io.ErrUnexpectedEOF", err)
+	}
+}
+
+// tests that persistent goroutine connections shut down when no longer desired.
+func TestTransportPersistConnLeak(t *testing.T) {
+	if runtime.GOOS == "plan9" {
+		t.Skip("skipping test; see http://golang.org/issue/7237")
+	}
+	defer afterTest(t)
+	gotReqCh := make(chan bool)
+	unblockCh := make(chan bool)
+	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+		gotReqCh <- true
+		<-unblockCh
+		w.Header().Set("Content-Length", "0")
+		w.WriteHeader(204)
+	}))
+	defer ts.Close()
+
+	tr := &Transport{}
+	c := &Client{Transport: tr}
+
+	n0 := runtime.NumGoroutine()
+
+	const numReq = 25
+	didReqCh := make(chan bool)
+	for i := 0; i < numReq; i++ {
+		go func() {
+			res, err := c.Get(ts.URL)
+			didReqCh <- true
+			if err != nil {
+				t.Errorf("client fetch error: %v", err)
+				return
+			}
+			res.Body.Close()
+		}()
+	}
+
+	// Wait for all goroutines to be stuck in the Handler.
+	for i := 0; i < numReq; i++ {
+		<-gotReqCh
+	}
+
+	nhigh := runtime.NumGoroutine()
+
+	// Tell all handlers to unblock and reply.
+	for i := 0; i < numReq; i++ {
+		unblockCh <- true
+	}
+
+	// Wait for all HTTP clients to be done.
+	for i := 0; i < numReq; i++ {
+		<-didReqCh
+	}
+
+	tr.CloseIdleConnections()
+	time.Sleep(100 * time.Millisecond)
+	runtime.GC()
+	runtime.GC() // even more.
+	nfinal := runtime.NumGoroutine()
+
+	growth := nfinal - n0
+
+	// We expect 0 or 1 extra goroutine, empirically.  Allow up to 5.
+	// Previously we were leaking one per numReq.
+	if int(growth) > 5 {
+		t.Logf("goroutine growth: %d -> %d -> %d (delta: %d)", n0, nhigh, nfinal, growth)
+		t.Error("too many new goroutines")
+	}
+}
+
+// golang.org/issue/4531: Transport leaks goroutines when
+// request.ContentLength is explicitly short
+func TestTransportPersistConnLeakShortBody(t *testing.T) {
+	if runtime.GOOS == "plan9" {
+		t.Skip("skipping test; see http://golang.org/issue/7237")
+	}
+	defer afterTest(t)
+	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+	}))
+	defer ts.Close()
+
+	tr := &Transport{}
+	c := &Client{Transport: tr}
+
+	n0 := runtime.NumGoroutine()
+	body := []byte("Hello")
+	for i := 0; i < 20; i++ {
+		req, err := NewRequest("POST", ts.URL, bytes.NewReader(body))
+		if err != nil {
+			t.Fatal(err)
+		}
+		req.ContentLength = int64(len(body) - 2) // explicitly short
+		_, err = c.Do(req)
+		if err == nil {
+			t.Fatal("Expect an error from writing too long of a body.")
+		}
+	}
+	nhigh := runtime.NumGoroutine()
+	tr.CloseIdleConnections()
+	time.Sleep(400 * time.Millisecond)
+	runtime.GC()
+	nfinal := runtime.NumGoroutine()
+
+	growth := nfinal - n0
+
+	// We expect 0 or 1 extra goroutine, empirically.  Allow up to 5.
+	// Previously we were leaking one per numReq.
+	t.Logf("goroutine growth: %d -> %d -> %d (delta: %d)", n0, nhigh, nfinal, growth)
+	if int(growth) > 5 {
+		t.Error("too many new goroutines")
+	}
+}
+
+// This used to crash; http://golang.org/issue/3266
+func TestTransportIdleConnCrash(t *testing.T) {
+	defer afterTest(t)
+	tr := &Transport{}
+	c := &Client{Transport: tr}
+
+	unblockCh := make(chan bool, 1)
+	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+		<-unblockCh
+		tr.CloseIdleConnections()
+	}))
+	defer ts.Close()
+
+	didreq := make(chan bool)
+	go func() {
+		res, err := c.Get(ts.URL)
+		if err != nil {
+			t.Error(err)
+		} else {
+			res.Body.Close() // returns idle conn
+		}
+		didreq <- true
+	}()
+	unblockCh <- true
+	<-didreq
+}
+
+// Test that the transport doesn't close the TCP connection early,
+// before the response body has been read.  This was a regression
+// which sadly lacked a triggering test.  The large response body made
+// the old race easier to trigger.
+func TestIssue3644(t *testing.T) {
+	defer afterTest(t)
+	const numFoos = 5000
+	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+		w.Header().Set("Connection", "close")
+		for i := 0; i < numFoos; i++ {
+			w.Write([]byte("foo "))
+		}
+	}))
+	defer ts.Close()
+	tr := &Transport{}
+	c := &Client{Transport: tr}
+	res, err := c.Get(ts.URL)
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer res.Body.Close()
+	bs, err := ioutil.ReadAll(res.Body)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if len(bs) != numFoos*len("foo ") {
+		t.Errorf("unexpected response length")
+	}
+}
+
+// Test that a client receives a server's reply, even if the server doesn't read
+// the entire request body.
+func TestIssue3595(t *testing.T) {
+	defer afterTest(t)
+	const deniedMsg = "sorry, denied."
+	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+		Error(w, deniedMsg, StatusUnauthorized)
+	}))
+	defer ts.Close()
+	tr := &Transport{}
+	c := &Client{Transport: tr}
+	res, err := c.Post(ts.URL, "application/octet-stream", neverEnding('a'))
+	if err != nil {
+		t.Errorf("Post: %v", err)
+		return
+	}
+	got, err := ioutil.ReadAll(res.Body)
+	if err != nil {
+		t.Fatalf("Body ReadAll: %v", err)
+	}
+	if !strings.Contains(string(got), deniedMsg) {
+		t.Errorf("Known bug: response %q does not contain %q", got, deniedMsg)
+	}
+}
+
+// From http://golang.org/issue/4454 ,
+// "client fails to handle requests with no body and chunked encoding"
+func TestChunkedNoContent(t *testing.T) {
+	defer afterTest(t)
+	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+		w.WriteHeader(StatusNoContent)
+	}))
+	defer ts.Close()
+
+	for _, closeBody := range []bool{true, false} {
+		c := &Client{Transport: &Transport{}}
+		const n = 4
+		for i := 1; i <= n; i++ {
+			res, err := c.Get(ts.URL)
+			if err != nil {
+				t.Errorf("closingBody=%v, req %d/%d: %v", closeBody, i, n, err)
+			} else {
+				if closeBody {
+					res.Body.Close()
+				}
+			}
+		}
+	}
+}
+
+func TestTransportConcurrency(t *testing.T) {
+	defer afterTest(t)
+	maxProcs, numReqs := 16, 500
+	if testing.Short() {
+		maxProcs, numReqs = 4, 50
+	}
+	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(maxProcs))
+	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+		fmt.Fprintf(w, "%v", r.FormValue("echo"))
+	}))
+	defer ts.Close()
+
+	var wg sync.WaitGroup
+	wg.Add(numReqs)
+
+	// Due to the Transport's "socket late binding" (see
+	// idleConnCh in transport.go), the numReqs HTTP requests
+	// below can finish with a dial still outstanding.  To keep
+	// the leak checker happy, keep track of pending dials and
+	// wait for them to finish (and be closed or returned to the
+	// idle pool) before we close idle connections.
+	SetPendingDialHooks(func() { wg.Add(1) }, wg.Done)
+	defer SetPendingDialHooks(nil, nil)
+
+	tr := &Transport{}
+	defer tr.CloseIdleConnections()
+
+	c := &Client{Transport: tr}
+	reqs := make(chan string)
+	defer close(reqs)
+
+	for i := 0; i < maxProcs*2; i++ {
+		go func() {
+			for req := range reqs {
+				res, err := c.Get(ts.URL + "/?echo=" + req)
+				if err != nil {
+					t.Errorf("error on req %s: %v", req, err)
+					wg.Done()
+					continue
+				}
+				all, err := ioutil.ReadAll(res.Body)
+				if err != nil {
+					t.Errorf("read error on req %s: %v", req, err)
+					wg.Done()
+					continue
+				}
+				if string(all) != req {
+					t.Errorf("body of req %s = %q; want %q", req, all, req)
+				}
+				res.Body.Close()
+				wg.Done()
+			}
+		}()
+	}
+	for i := 0; i < numReqs; i++ {
+		reqs <- fmt.Sprintf("request-%d", i)
+	}
+	wg.Wait()
+}
+
+func TestIssue4191_InfiniteGetTimeout(t *testing.T) {
+	if runtime.GOOS == "plan9" {
+		t.Skip("skipping test; see http://golang.org/issue/7237")
+	}
+	defer afterTest(t)
+	const debug = false
+	mux := NewServeMux()
+	mux.HandleFunc("/get", func(w ResponseWriter, r *Request) {
+		io.Copy(w, neverEnding('a'))
+	})
+	ts := httptest.NewServer(mux)
+	timeout := 100 * time.Millisecond
+
+	client := &Client{
+		Transport: &Transport{
+			Dial: func(n, addr string) (net.Conn, error) {
+				conn, err := net.Dial(n, addr)
+				if err != nil {
+					return nil, err
+				}
+				conn.SetDeadline(time.Now().Add(timeout))
+				if debug {
+					conn = NewLoggingConn("client", conn)
+				}
+				return conn, nil
+			},
+			DisableKeepAlives: true,
+		},
+	}
+
+	getFailed := false
+	nRuns := 5
+	if testing.Short() {
+		nRuns = 1
+	}
+	for i := 0; i < nRuns; i++ {
+		if debug {
+			println("run", i+1, "of", nRuns)
+		}
+		sres, err := client.Get(ts.URL + "/get")
+		if err != nil {
+			if !getFailed {
+				// Make the timeout longer, once.
+				getFailed = true
+				t.Logf("increasing timeout")
+				i--
+				timeout *= 10
+				continue
+			}
+			t.Errorf("Error issuing GET: %v", err)
+			break
+		}
+		_, err = io.Copy(ioutil.Discard, sres.Body)
+		if err == nil {
+			t.Errorf("Unexpected successful copy")
+			break
+		}
+	}
+	if debug {
+		println("tests complete; waiting for handlers to finish")
+	}
+	ts.Close()
+}
+
+func TestIssue4191_InfiniteGetToPutTimeout(t *testing.T) {
+	if runtime.GOOS == "plan9" {
+		t.Skip("skipping test; see http://golang.org/issue/7237")
+	}
+	defer afterTest(t)
+	const debug = false
+	mux := NewServeMux()
+	mux.HandleFunc("/get", func(w ResponseWriter, r *Request) {
+		io.Copy(w, neverEnding('a'))
+	})
+	mux.HandleFunc("/put", func(w ResponseWriter, r *Request) {
+		defer r.Body.Close()
+		io.Copy(ioutil.Discard, r.Body)
+	})
+	ts := httptest.NewServer(mux)
+	timeout := 100 * time.Millisecond
+
+	client := &Client{
+		Transport: &Transport{
+			Dial: func(n, addr string) (net.Conn, error) {
+				conn, err := net.Dial(n, addr)
+				if err != nil {
+					return nil, err
+				}
+				conn.SetDeadline(time.Now().Add(timeout))
+				if debug {
+					conn = NewLoggingConn("client", conn)
+				}
+				return conn, nil
+			},
+			DisableKeepAlives: true,
+		},
+	}
+
+	getFailed := false
+	nRuns := 5
+	if testing.Short() {
+		nRuns = 1
+	}
+	for i := 0; i < nRuns; i++ {
+		if debug {
+			println("run", i+1, "of", nRuns)
+		}
+		sres, err := client.Get(ts.URL + "/get")
+		if err != nil {
+			if !getFailed {
+				// Make the timeout longer, once.
+				getFailed = true
+				t.Logf("increasing timeout")
+				i--
+				timeout *= 10
+				continue
+			}
+			t.Errorf("Error issuing GET: %v", err)
+			break
+		}
+		req, _ := NewRequest("PUT", ts.URL+"/put", sres.Body)
+		_, err = client.Do(req)
+		if err == nil {
+			sres.Body.Close()
+			t.Errorf("Unexpected successful PUT")
+			break
+		}
+		sres.Body.Close()
+	}
+	if debug {
+		println("tests complete; waiting for handlers to finish")
+	}
+	ts.Close()
+}
+
+func TestTransportResponseHeaderTimeout(t *testing.T) {
+	defer afterTest(t)
+	if testing.Short() {
+		t.Skip("skipping timeout test in -short mode")
+	}
+	inHandler := make(chan bool, 1)
+	mux := NewServeMux()
+	mux.HandleFunc("/fast", func(w ResponseWriter, r *Request) {
+		inHandler <- true
+	})
+	mux.HandleFunc("/slow", func(w ResponseWriter, r *Request) {
+		inHandler <- true
+		time.Sleep(2 * time.Second)
+	})
+	ts := httptest.NewServer(mux)
+	defer ts.Close()
+
+	tr := &Transport{
+		ResponseHeaderTimeout: 500 * time.Millisecond,
+	}
+	defer tr.CloseIdleConnections()
+	c := &Client{Transport: tr}
+
+	tests := []struct {
+		path    string
+		want    int
+		wantErr string
+	}{
+		{path: "/fast", want: 200},
+		{path: "/slow", wantErr: "timeout awaiting response headers"},
+		{path: "/fast", want: 200},
+	}
+	for i, tt := range tests {
+		res, err := c.Get(ts.URL + tt.path)
+		select {
+		case <-inHandler:
+		case <-time.After(5 * time.Second):
+			t.Errorf("never entered handler for test index %d, %s", i, tt.path)
+			continue
+		}
+		if err != nil {
+			uerr, ok := err.(*url.Error)
+			if !ok {
+				t.Errorf("error is not an url.Error; got: %#v", err)
+				continue
+			}
+			nerr, ok := uerr.Err.(net.Error)
+			if !ok {
+				t.Errorf("error does not satisfy net.Error interface; got: %#v", err)
+				continue
+			}
+			if !nerr.Timeout() {
+				t.Errorf("want timeout error; got: %q", nerr)
+				continue
+			}
+			if strings.Contains(err.Error(), tt.wantErr) {
+				continue
+			}
+			t.Errorf("%d. unexpected error: %v", i, err)
+			continue
+		}
+		if tt.wantErr != "" {
+			t.Errorf("%d. no error. expected error: %v", i, tt.wantErr)
+			continue
+		}
+		if res.StatusCode != tt.want {
+			t.Errorf("%d for path %q status = %d; want %d", i, tt.path, res.StatusCode, tt.want)
+		}
+	}
+}
+
+func TestTransportCancelRequest(t *testing.T) {
+	defer afterTest(t)
+	if testing.Short() {
+		t.Skip("skipping test in -short mode")
+	}
+	unblockc := make(chan bool)
+	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+		fmt.Fprintf(w, "Hello")
+		w.(Flusher).Flush() // send headers and some body
+		<-unblockc
+	}))
+	defer ts.Close()
+	defer close(unblockc)
+
+	tr := &Transport{}
+	defer tr.CloseIdleConnections()
+	c := &Client{Transport: tr}
+
+	req, _ := NewRequest("GET", ts.URL, nil)
+	res, err := c.Do(req)
+	if err != nil {
+		t.Fatal(err)
+	}
+	go func() {
+		time.Sleep(1 * time.Second)
+		tr.CancelRequest(req)
+	}()
+	t0 := time.Now()
+	body, err := ioutil.ReadAll(res.Body)
+	d := time.Since(t0)
+
+	if err == nil {
+		t.Error("expected an error reading the body")
+	}
+	if string(body) != "Hello" {
+		t.Errorf("Body = %q; want Hello", body)
+	}
+	if d < 500*time.Millisecond {
+		t.Errorf("expected ~1 second delay; got %v", d)
+	}
+	// Verify no outstanding requests after readLoop/writeLoop
+	// goroutines shut down.
+	for tries := 3; tries > 0; tries-- {
+		n := tr.NumPendingRequestsForTesting()
+		if n == 0 {
+			break
+		}
+		time.Sleep(100 * time.Millisecond)
+		if tries == 1 {
+			t.Errorf("pending requests = %d; want 0", n)
+		}
+	}
+}
+
+func TestTransportCancelRequestInDial(t *testing.T) {
+	defer afterTest(t)
+	if testing.Short() {
+		t.Skip("skipping test in -short mode")
+	}
+	var logbuf bytes.Buffer
+	eventLog := log.New(&logbuf, "", 0)
+
+	unblockDial := make(chan bool)
+	defer close(unblockDial)
+
+	inDial := make(chan bool)
+	tr := &Transport{
+		Dial: func(network, addr string) (net.Conn, error) {
+			eventLog.Println("dial: blocking")
+			inDial <- true
+			<-unblockDial
+			return nil, errors.New("nope")
+		},
+	}
+	cl := &Client{Transport: tr}
+	gotres := make(chan bool)
+	req, _ := NewRequest("GET", "http://something.no-network.tld/", nil)
+	go func() {
+		_, err := cl.Do(req)
+		eventLog.Printf("Get = %v", err)
+		gotres <- true
+	}()
+
+	select {
+	case <-inDial:
+	case <-time.After(5 * time.Second):
+		t.Fatal("timeout; never saw blocking dial")
+	}
+
+	eventLog.Printf("canceling")
+	tr.CancelRequest(req)
+
+	select {
+	case <-gotres:
+	case <-time.After(5 * time.Second):
+		panic("hang. events are: " + logbuf.String())
+	}
+
+	got := logbuf.String()
+	want := `dial: blocking
+canceling
+Get = Get http://something.no-network.tld/: net/http: request canceled while waiting for connection
+`
+	if got != want {
+		t.Errorf("Got events:\n%s\nWant:\n%s", got, want)
+	}
+}
+
+// golang.org/issue/3672 -- Client can't close HTTP stream
+// Calling Close on a Response.Body used to just read until EOF.
+// Now it actually closes the TCP connection.
+func TestTransportCloseResponseBody(t *testing.T) {
+	defer afterTest(t)
+	writeErr := make(chan error, 1)
+	msg := []byte("young\n")
+	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+		for {
+			_, err := w.Write(msg)
+			if err != nil {
+				writeErr <- err
+				return
+			}
+			w.(Flusher).Flush()
+		}
+	}))
+	defer ts.Close()
+
+	tr := &Transport{}
+	defer tr.CloseIdleConnections()
+	c := &Client{Transport: tr}
+
+	req, _ := NewRequest("GET", ts.URL, nil)
+	defer tr.CancelRequest(req)
+
+	res, err := c.Do(req)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	const repeats = 3
+	buf := make([]byte, len(msg)*repeats)
+	want := bytes.Repeat(msg, repeats)
+
+	_, err = io.ReadFull(res.Body, buf)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if !bytes.Equal(buf, want) {
+		t.Fatalf("read %q; want %q", buf, want)
+	}
+	didClose := make(chan error, 1)
+	go func() {
+		didClose <- res.Body.Close()
+	}()
+	select {
+	case err := <-didClose:
+		if err != nil {
+			t.Errorf("Close = %v", err)
+		}
+	case <-time.After(10 * time.Second):
+		t.Fatal("too long waiting for close")
+	}
+	select {
+	case err := <-writeErr:
+		if err == nil {
+			t.Errorf("expected non-nil write error")
+		}
+	case <-time.After(10 * time.Second):
+		t.Fatal("too long waiting for write error")
+	}
+}
+
+type fooProto struct{}
+
+func (fooProto) RoundTrip(req *Request) (*Response, error) {
+	res := &Response{
+		Status:     "200 OK",
+		StatusCode: 200,
+		Header:     make(Header),
+		Body:       ioutil.NopCloser(strings.NewReader("You wanted " + req.URL.String())),
+	}
+	return res, nil
+}
+
+func TestTransportAltProto(t *testing.T) {
+	defer afterTest(t)
+	tr := &Transport{}
+	c := &Client{Transport: tr}
+	tr.RegisterProtocol("foo", fooProto{})
+	res, err := c.Get("foo://bar.com/path")
+	if err != nil {
+		t.Fatal(err)
+	}
+	bodyb, err := ioutil.ReadAll(res.Body)
+	if err != nil {
+		t.Fatal(err)
+	}
+	body := string(bodyb)
+	if e := "You wanted foo://bar.com/path"; body != e {
+		t.Errorf("got response %q, want %q", body, e)
+	}
+}
+
+func TestTransportNoHost(t *testing.T) {
+	defer afterTest(t)
+	tr := &Transport{}
+	_, err := tr.RoundTrip(&Request{
+		Header: make(Header),
+		URL: &url.URL{
+			Scheme: "http",
+		},
+	})
+	want := "http: no Host in request URL"
+	if got := fmt.Sprint(err); got != want {
+		t.Errorf("error = %v; want %q", err, want)
+	}
+}
+
+func TestTransportSocketLateBinding(t *testing.T) {
+	defer afterTest(t)
+
+	mux := NewServeMux()
+	fooGate := make(chan bool, 1)
+	mux.HandleFunc("/foo", func(w ResponseWriter, r *Request) {
+		w.Header().Set("foo-ipport", r.RemoteAddr)
+		w.(Flusher).Flush()
+		<-fooGate
+	})
+	mux.HandleFunc("/bar", func(w ResponseWriter, r *Request) {
+		w.Header().Set("bar-ipport", r.RemoteAddr)
+	})
+	ts := httptest.NewServer(mux)
+	defer ts.Close()
+
+	dialGate := make(chan bool, 1)
+	tr := &Transport{
+		Dial: func(n, addr string) (net.Conn, error) {
+			if <-dialGate {
+				return net.Dial(n, addr)
+			}
+			return nil, errors.New("manually closed")
+		},
+		DisableKeepAlives: false,
+	}
+	defer tr.CloseIdleConnections()
+	c := &Client{
+		Transport: tr,
+	}
+
+	dialGate <- true // only allow one dial
+	fooRes, err := c.Get(ts.URL + "/foo")
+	if err != nil {
+		t.Fatal(err)
+	}
+	fooAddr := fooRes.Header.Get("foo-ipport")
+	if fooAddr == "" {
+		t.Fatal("No addr on /foo request")
+	}
+	time.AfterFunc(200*time.Millisecond, func() {
+		// let the foo response finish so we can use its
+		// connection for /bar
+		fooGate <- true
+		io.Copy(ioutil.Discard, fooRes.Body)
+		fooRes.Body.Close()
+	})
+
+	barRes, err := c.Get(ts.URL + "/bar")
+	if err != nil {
+		t.Fatal(err)
+	}
+	barAddr := barRes.Header.Get("bar-ipport")
+	if barAddr != fooAddr {
+		t.Fatalf("/foo came from conn %q; /bar came from %q instead", fooAddr, barAddr)
+	}
+	barRes.Body.Close()
+	dialGate <- false
+}
+
+// Issue 2184
+func TestTransportReading100Continue(t *testing.T) {
+	defer afterTest(t)
+
+	const numReqs = 5
+	reqBody := func(n int) string { return fmt.Sprintf("request body %d", n) }
+	reqID := func(n int) string { return fmt.Sprintf("REQ-ID-%d", n) }
+
+	send100Response := func(w *io.PipeWriter, r *io.PipeReader) {
+		defer w.Close()
+		defer r.Close()
+		br := bufio.NewReader(r)
+		n := 0
+		for {
+			n++
+			req, err := ReadRequest(br)
+			if err == io.EOF {
+				return
+			}
+			if err != nil {
+				t.Error(err)
+				return
+			}
+			slurp, err := ioutil.ReadAll(req.Body)
+			if err != nil {
+				t.Errorf("Server request body slurp: %v", err)
+				return
+			}
+			id := req.Header.Get("Request-Id")
+			resCode := req.Header.Get("X-Want-Response-Code")
+			if resCode == "" {
+				resCode = "100 Continue"
+				if string(slurp) != reqBody(n) {
+					t.Errorf("Server got %q, %v; want %q", slurp, err, reqBody(n))
+				}
+			}
+			body := fmt.Sprintf("Response number %d", n)
+			v := []byte(strings.Replace(fmt.Sprintf(`HTTP/1.1 %s
+Date: Thu, 28 Feb 2013 17:55:41 GMT
+
+HTTP/1.1 200 OK
+Content-Type: text/html
+Echo-Request-Id: %s
+Content-Length: %d
+
+%s`, resCode, id, len(body), body), "\n", "\r\n", -1))
+			w.Write(v)
+			if id == reqID(numReqs) {
+				return
+			}
+		}
+
+	}
+
+	tr := &Transport{
+		Dial: func(n, addr string) (net.Conn, error) {
+			sr, sw := io.Pipe() // server read/write
+			cr, cw := io.Pipe() // client read/write
+			conn := &rwTestConn{
+				Reader: cr,
+				Writer: sw,
+				closeFunc: func() error {
+					sw.Close()
+					cw.Close()
+					return nil
+				},
+			}
+			go send100Response(cw, sr)
+			return conn, nil
+		},
+		DisableKeepAlives: false,
+	}
+	defer tr.CloseIdleConnections()
+	c := &Client{Transport: tr}
+
+	testResponse := func(req *Request, name string, wantCode int) {
+		res, err := c.Do(req)
+		if err != nil {
+			t.Fatalf("%s: Do: %v", name, err)
+		}
+		if res.StatusCode != wantCode {
+			t.Fatalf("%s: Response Statuscode=%d; want %d", name, res.StatusCode, wantCode)
+		}
+		if id, idBack := req.Header.Get("Request-Id"), res.Header.Get("Echo-Request-Id"); id != "" && id != idBack {
+			t.Errorf("%s: response id %q != request id %q", name, idBack, id)
+		}
+		_, err = ioutil.ReadAll(res.Body)
+		if err != nil {
+			t.Fatalf("%s: Slurp error: %v", name, err)
+		}
+	}
+
+	// Few 100 responses, making sure we're not off-by-one.
+	for i := 1; i <= numReqs; i++ {
+		req, _ := NewRequest("POST", "http://dummy.tld/", strings.NewReader(reqBody(i)))
+		req.Header.Set("Request-Id", reqID(i))
+		testResponse(req, fmt.Sprintf("100, %d/%d", i, numReqs), 200)
+	}
+
+	// And some other informational 1xx but non-100 responses, to test
+	// we return them but don't re-use the connection.
+	for i := 1; i <= numReqs; i++ {
+		req, _ := NewRequest("POST", "http://other.tld/", strings.NewReader(reqBody(i)))
+		req.Header.Set("X-Want-Response-Code", "123 Sesame Street")
+		testResponse(req, fmt.Sprintf("123, %d/%d", i, numReqs), 123)
+	}
+}
+
+type proxyFromEnvTest struct {
+	req string // URL to fetch; blank means "http://example.com"
+
+	env      string // HTTP_PROXY
+	httpsenv string // HTTPS_PROXY
+	noenv    string // NO_RPXY
+
+	want    string
+	wanterr error
+}
+
+func (t proxyFromEnvTest) String() string {
+	var buf bytes.Buffer
+	space := func() {
+		if buf.Len() > 0 {
+			buf.WriteByte(' ')
+		}
+	}
+	if t.env != "" {
+		fmt.Fprintf(&buf, "http_proxy=%q", t.env)
+	}
+	if t.httpsenv != "" {
+		space()
+		fmt.Fprintf(&buf, "https_proxy=%q", t.httpsenv)
+	}
+	if t.noenv != "" {
+		space()
+		fmt.Fprintf(&buf, "no_proxy=%q", t.noenv)
+	}
+	req := "http://example.com"
+	if t.req != "" {
+		req = t.req
+	}
+	space()
+	fmt.Fprintf(&buf, "req=%q", req)
+	return strings.TrimSpace(buf.String())
+}
+
+var proxyFromEnvTests = []proxyFromEnvTest{
+	{env: "127.0.0.1:8080", want: "http://127.0.0.1:8080"},
+	{env: "cache.corp.example.com:1234", want: "http://cache.corp.example.com:1234"},
+	{env: "cache.corp.example.com", want: "http://cache.corp.example.com"},
+	{env: "https://cache.corp.example.com", want: "https://cache.corp.example.com"},
+	{env: "http://127.0.0.1:8080", want: "http://127.0.0.1:8080"},
+	{env: "https://127.0.0.1:8080", want: "https://127.0.0.1:8080"},
+
+	// Don't use secure for http
+	{req: "http://insecure.tld/", env: "http.proxy.tld", httpsenv: "secure.proxy.tld", want: "http://http.proxy.tld"},
+	// Use secure for https.
+	{req: "https://secure.tld/", env: "http.proxy.tld", httpsenv: "secure.proxy.tld", want: "http://secure.proxy.tld"},
+	{req: "https://secure.tld/", env: "http.proxy.tld", httpsenv: "https://secure.proxy.tld", want: "https://secure.proxy.tld"},
+
+	{want: "<nil>"},
+
+	{noenv: "example.com", req: "http://example.com/", env: "proxy", want: "<nil>"},
+	{noenv: ".example.com", req: "http://example.com/", env: "proxy", want: "<nil>"},
+	{noenv: "ample.com", req: "http://example.com/", env: "proxy", want: "http://proxy"},
+	{noenv: "example.com", req: "http://foo.example.com/", env: "proxy", want: "<nil>"},
+	{noenv: ".foo.com", req: "http://example.com/", env: "proxy", want: "http://proxy"},
+}
+
+func TestProxyFromEnvironment(t *testing.T) {
+	ResetProxyEnv()
+	for _, tt := range proxyFromEnvTests {
+		os.Setenv("HTTP_PROXY", tt.env)
+		os.Setenv("HTTPS_PROXY", tt.httpsenv)
+		os.Setenv("NO_PROXY", tt.noenv)
+		ResetCachedEnvironment()
+		reqURL := tt.req
+		if reqURL == "" {
+			reqURL = "http://example.com"
+		}
+		req, _ := NewRequest("GET", reqURL, nil)
+		url, err := ProxyFromEnvironment(req)
+		if g, e := fmt.Sprintf("%v", err), fmt.Sprintf("%v", tt.wanterr); g != e {
+			t.Errorf("%v: got error = %q, want %q", tt, g, e)
+			continue
+		}
+		if got := fmt.Sprintf("%s", url); got != tt.want {
+			t.Errorf("%v: got URL = %q, want %q", tt, url, tt.want)
+		}
+	}
+}
+
+func TestIdleConnChannelLeak(t *testing.T) {
+	var mu sync.Mutex
+	var n int
+
+	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+		mu.Lock()
+		n++
+		mu.Unlock()
+	}))
+	defer ts.Close()
+
+	tr := &Transport{
+		Dial: func(netw, addr string) (net.Conn, error) {
+			return net.Dial(netw, ts.Listener.Addr().String())
+		},
+	}
+	defer tr.CloseIdleConnections()
+
+	c := &Client{Transport: tr}
+
+	// First, without keep-alives.
+	for _, disableKeep := range []bool{true, false} {
+		tr.DisableKeepAlives = disableKeep
+		for i := 0; i < 5; i++ {
+			_, err := c.Get(fmt.Sprintf("http://foo-host-%d.tld/", i))
+			if err != nil {
+				t.Fatal(err)
+			}
+		}
+		if got := tr.IdleConnChMapSizeForTesting(); got != 0 {
+			t.Fatalf("ForDisableKeepAlives = %v, map size = %d; want 0", disableKeep, got)
+		}
+	}
+}
+
+// Verify the status quo: that the Client.Post function coerces its
+// body into a ReadCloser if it's a Closer, and that the Transport
+// then closes it.
+func TestTransportClosesRequestBody(t *testing.T) {
+	defer afterTest(t)
+	ts := httptest.NewServer(http.HandlerFunc(func(w ResponseWriter, r *Request) {
+		io.Copy(ioutil.Discard, r.Body)
+	}))
+	defer ts.Close()
+
+	tr := &Transport{}
+	defer tr.CloseIdleConnections()
+	cl := &Client{Transport: tr}
+
+	closes := 0
+
+	res, err := cl.Post(ts.URL, "text/plain", countCloseReader{&closes, strings.NewReader("hello")})
+	if err != nil {
+		t.Fatal(err)
+	}
+	res.Body.Close()
+	if closes != 1 {
+		t.Errorf("closes = %d; want 1", closes)
+	}
+}
+
+func TestTransportTLSHandshakeTimeout(t *testing.T) {
+	defer afterTest(t)
+	if testing.Short() {
+		t.Skip("skipping in short mode")
+	}
+	ln := newLocalListener(t)
+	defer ln.Close()
+	testdonec := make(chan struct{})
+	defer close(testdonec)
+
+	go func() {
+		c, err := ln.Accept()
+		if err != nil {
+			t.Error(err)
+			return
+		}
+		<-testdonec
+		c.Close()
+	}()
+
+	getdonec := make(chan struct{})
+	go func() {
+		defer close(getdonec)
+		tr := &Transport{
+			Dial: func(_, _ string) (net.Conn, error) {
+				return net.Dial("tcp", ln.Addr().String())
+			},
+			TLSHandshakeTimeout: 250 * time.Millisecond,
+		}
+		cl := &Client{Transport: tr}
+		_, err := cl.Get("https://dummy.tld/")
+		if err == nil {
+			t.Error("expected error")
+			return
+		}
+		ue, ok := err.(*url.Error)
+		if !ok {
+			t.Errorf("expected url.Error; got %#v", err)
+			return
+		}
+		ne, ok := ue.Err.(net.Error)
+		if !ok {
+			t.Errorf("expected net.Error; got %#v", err)
+			return
+		}
+		if !ne.Timeout() {
+			t.Errorf("expected timeout error; got %v", err)
+		}
+		if !strings.Contains(err.Error(), "handshake timeout") {
+			t.Errorf("expected 'handshake timeout' in error; got %v", err)
+		}
+	}()
+	select {
+	case <-getdonec:
+	case <-time.After(5 * time.Second):
+		t.Error("test timeout; TLS handshake hung?")
+	}
+}
+
+// Trying to repro golang.org/issue/3514
+func TestTLSServerClosesConnection(t *testing.T) {
+	defer afterTest(t)
+	if runtime.GOOS == "windows" {
+		t.Skip("skipping flaky test on Windows; golang.org/issue/7634")
+	}
+	closedc := make(chan bool, 1)
+	ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+		if strings.Contains(r.URL.Path, "/keep-alive-then-die") {
+			conn, _, _ := w.(Hijacker).Hijack()
+			conn.Write([]byte("HTTP/1.1 200 OK\r\nContent-Length: 3\r\n\r\nfoo"))
+			conn.Close()
+			closedc <- true
+			return
+		}
+		fmt.Fprintf(w, "hello")
+	}))
+	defer ts.Close()
+	tr := &Transport{
+		TLSClientConfig: &tls.Config{
+			InsecureSkipVerify: true,
+		},
+	}
+	defer tr.CloseIdleConnections()
+	client := &Client{Transport: tr}
+
+	var nSuccess = 0
+	var errs []error
+	const trials = 20
+	for i := 0; i < trials; i++ {
+		tr.CloseIdleConnections()
+		res, err := client.Get(ts.URL + "/keep-alive-then-die")
+		if err != nil {
+			t.Fatal(err)
+		}
+		<-closedc
+		slurp, err := ioutil.ReadAll(res.Body)
+		if err != nil {
+			t.Fatal(err)
+		}
+		if string(slurp) != "foo" {
+			t.Errorf("Got %q, want foo", slurp)
+		}
+
+		// Now try again and see if we successfully
+		// pick a new connection.
+		res, err = client.Get(ts.URL + "/")
+		if err != nil {
+			errs = append(errs, err)
+			continue
+		}
+		slurp, err = ioutil.ReadAll(res.Body)
+		if err != nil {
+			errs = append(errs, err)
+			continue
+		}
+		nSuccess++
+	}
+	if nSuccess > 0 {
+		t.Logf("successes = %d of %d", nSuccess, trials)
+	} else {
+		t.Errorf("All runs failed:")
+	}
+	for _, err := range errs {
+		t.Logf("  err: %v", err)
+	}
+}
+
+// byteFromChanReader is an io.Reader that reads a single byte at a
+// time from the channel.  When the channel is closed, the reader
+// returns io.EOF.
+type byteFromChanReader chan byte
+
+func (c byteFromChanReader) Read(p []byte) (n int, err error) {
+	if len(p) == 0 {
+		return
+	}
+	b, ok := <-c
+	if !ok {
+		return 0, io.EOF
+	}
+	p[0] = b
+	return 1, nil
+}
+
+// Verifies that the Transport doesn't reuse a connection in the case
+// where the server replies before the request has been fully
+// written. We still honor that reply (see TestIssue3595), but don't
+// send future requests on the connection because it's then in a
+// questionable state.
+// golang.org/issue/7569
+func TestTransportNoReuseAfterEarlyResponse(t *testing.T) {
+	defer afterTest(t)
+	var sconn struct {
+		sync.Mutex
+		c net.Conn
+	}
+	var getOkay bool
+	closeConn := func() {
+		sconn.Lock()
+		defer sconn.Unlock()
+		if sconn.c != nil {
+			sconn.c.Close()
+			sconn.c = nil
+			if !getOkay {
+				t.Logf("Closed server connection")
+			}
+		}
+	}
+	defer closeConn()
+
+	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+		if r.Method == "GET" {
+			io.WriteString(w, "bar")
+			return
+		}
+		conn, _, _ := w.(Hijacker).Hijack()
+		sconn.Lock()
+		sconn.c = conn
+		sconn.Unlock()
+		conn.Write([]byte("HTTP/1.1 200 OK\r\nContent-Length: 3\r\n\r\nfoo")) // keep-alive
+		go io.Copy(ioutil.Discard, conn)
+	}))
+	defer ts.Close()
+	tr := &Transport{}
+	defer tr.CloseIdleConnections()
+	client := &Client{Transport: tr}
+
+	const bodySize = 256 << 10
+	finalBit := make(byteFromChanReader, 1)
+	req, _ := NewRequest("POST", ts.URL, io.MultiReader(io.LimitReader(neverEnding('x'), bodySize-1), finalBit))
+	req.ContentLength = bodySize
+	res, err := client.Do(req)
+	if err := wantBody(res, err, "foo"); err != nil {
+		t.Errorf("POST response: %v", err)
+	}
+	donec := make(chan bool)
+	go func() {
+		defer close(donec)
+		res, err = client.Get(ts.URL)
+		if err := wantBody(res, err, "bar"); err != nil {
+			t.Errorf("GET response: %v", err)
+			return
+		}
+		getOkay = true // suppress test noise
+	}()
+	time.AfterFunc(5*time.Second, closeConn)
+	select {
+	case <-donec:
+		finalBit <- 'x' // unblock the writeloop of the first Post
+		close(finalBit)
+	case <-time.After(7 * time.Second):
+		t.Fatal("timeout waiting for GET request to finish")
+	}
+}
+
+type errorReader struct {
+	err error
+}
+
+func (e errorReader) Read(p []byte) (int, error) { return 0, e.err }
+
+type closerFunc func() error
+
+func (f closerFunc) Close() error { return f() }
+
+// Issue 6981
+func TestTransportClosesBodyOnError(t *testing.T) {
+	if runtime.GOOS == "plan9" {
+		t.Skip("skipping test; see http://golang.org/issue/7782")
+	}
+	defer afterTest(t)
+	readBody := make(chan error, 1)
+	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+		_, err := ioutil.ReadAll(r.Body)
+		readBody <- err
+	}))
+	defer ts.Close()
+	fakeErr := errors.New("fake error")
+	didClose := make(chan bool, 1)
+	req, _ := NewRequest("POST", ts.URL, struct {
+		io.Reader
+		io.Closer
+	}{
+		io.MultiReader(io.LimitReader(neverEnding('x'), 1<<20), errorReader{fakeErr}),
+		closerFunc(func() error {
+			select {
+			case didClose <- true:
+			default:
+			}
+			return nil
+		}),
+	})
+	res, err := DefaultClient.Do(req)
+	if res != nil {
+		defer res.Body.Close()
+	}
+	if err == nil || !strings.Contains(err.Error(), fakeErr.Error()) {
+		t.Fatalf("Do error = %v; want something containing %q", err, fakeErr.Error())
+	}
+	select {
+	case err := <-readBody:
+		if err == nil {
+			t.Errorf("Unexpected success reading request body from handler; want 'unexpected EOF reading trailer'")
+		}
+	case <-time.After(5 * time.Second):
+		t.Error("timeout waiting for server handler to complete")
+	}
+	select {
+	case <-didClose:
+	default:
+		t.Errorf("didn't see Body.Close")
+	}
+}
+
+func TestTransportDialTLS(t *testing.T) {
+	var mu sync.Mutex // guards following
+	var gotReq, didDial bool
+
+	ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+		mu.Lock()
+		gotReq = true
+		mu.Unlock()
+	}))
+	defer ts.Close()
+	tr := &Transport{
+		DialTLS: func(netw, addr string) (net.Conn, error) {
+			mu.Lock()
+			didDial = true
+			mu.Unlock()
+			c, err := tls.Dial(netw, addr, &tls.Config{
+				InsecureSkipVerify: true,
+			})
+			if err != nil {
+				return nil, err
+			}
+			return c, c.Handshake()
+		},
+	}
+	defer tr.CloseIdleConnections()
+	client := &Client{Transport: tr}
+	res, err := client.Get(ts.URL)
+	if err != nil {
+		t.Fatal(err)
+	}
+	res.Body.Close()
+	mu.Lock()
+	if !gotReq {
+		t.Error("didn't get request")
+	}
+	if !didDial {
+		t.Error("didn't use dial hook")
+	}
+}
+
+// Test for issue 8755
+// Ensure that if a proxy returns an error, it is exposed by RoundTrip
+func TestRoundTripReturnsProxyError(t *testing.T) {
+	badProxy := func(*http.Request) (*url.URL, error) {
+		return nil, errors.New("errorMessage")
+	}
+
+	tr := &Transport{Proxy: badProxy}
+
+	req, _ := http.NewRequest("GET", "http://example.com", nil)
+
+	_, err := tr.RoundTrip(req)
+
+	if err == nil {
+		t.Error("Expected proxy error to be returned by RoundTrip")
+	}
+}
+
+// tests that putting an idle conn after a call to CloseIdleConns does return it
+func TestTransportCloseIdleConnsThenReturn(t *testing.T) {
+	tr := &Transport{}
+	wantIdle := func(when string, n int) bool {
+		got := tr.IdleConnCountForTesting("|http|example.com") // key used by PutIdleTestConn
+		if got == n {
+			return true
+		}
+		t.Errorf("%s: idle conns = %d; want %d", when, got, n)
+		return false
+	}
+	wantIdle("start", 0)
+	if !tr.PutIdleTestConn() {
+		t.Fatal("put failed")
+	}
+	if !tr.PutIdleTestConn() {
+		t.Fatal("second put failed")
+	}
+	wantIdle("after put", 2)
+	tr.CloseIdleConnections()
+	if !tr.IsIdleForTesting() {
+		t.Error("should be idle after CloseIdleConnections")
+	}
+	wantIdle("after close idle", 0)
+	if tr.PutIdleTestConn() {
+		t.Fatal("put didn't fail")
+	}
+	wantIdle("after second put", 0)
+
+	tr.RequestIdleConnChForTesting() // should toggle the transport out of idle mode
+	if tr.IsIdleForTesting() {
+		t.Error("shouldn't be idle after RequestIdleConnChForTesting")
+	}
+	if !tr.PutIdleTestConn() {
+		t.Fatal("after re-activation")
+	}
+	wantIdle("after final put", 1)
+}
+
+// This tests that an client requesting a content range won't also
+// implicitly ask for gzip support. If they want that, they need to do it
+// on their own.
+// golang.org/issue/8923
+func TestTransportRangeAndGzip(t *testing.T) {
+	defer afterTest(t)
+	reqc := make(chan *Request, 1)
+	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+		reqc <- r
+	}))
+	defer ts.Close()
+
+	req, _ := NewRequest("GET", ts.URL, nil)
+	req.Header.Set("Range", "bytes=7-11")
+	res, err := DefaultClient.Do(req)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	select {
+	case r := <-reqc:
+		if strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") {
+			t.Error("Transport advertised gzip support in the Accept header")
+		}
+		if r.Header.Get("Range") == "" {
+			t.Error("no Range in request")
+		}
+	case <-time.After(10 * time.Second):
+		t.Fatal("timeout")
+	}
+	res.Body.Close()
+}
+
+func wantBody(res *http.Response, err error, want string) error {
+	if err != nil {
+		return err
+	}
+	slurp, err := ioutil.ReadAll(res.Body)
+	if err != nil {
+		return fmt.Errorf("error reading body: %v", err)
+	}
+	if string(slurp) != want {
+		return fmt.Errorf("body = %q; want %q", slurp, want)
+	}
+	if err := res.Body.Close(); err != nil {
+		return fmt.Errorf("body Close = %v", err)
+	}
+	return nil
+}
+
+func newLocalListener(t *testing.T) net.Listener {
+	ln, err := net.Listen("tcp", "127.0.0.1:0")
+	if err != nil {
+		ln, err = net.Listen("tcp6", "[::1]:0")
+	}
+	if err != nil {
+		t.Fatal(err)
+	}
+	return ln
+}
+
+type countCloseReader struct {
+	n *int
+	io.Reader
+}
+
+func (cr countCloseReader) Close() error {
+	(*cr.n)++
+	return nil
+}
+
+// rgz is a gzip quine that uncompresses to itself.
+var rgz = []byte{
+	0x1f, 0x8b, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73,
+	0x69, 0x76, 0x65, 0x00, 0x92, 0xef, 0xe6, 0xe0,
+	0x60, 0x00, 0x83, 0xa2, 0xd4, 0xe4, 0xd2, 0xa2,
+	0xe2, 0xcc, 0xb2, 0x54, 0x06, 0x00, 0x00, 0x17,
+	0x00, 0xe8, 0xff, 0x92, 0xef, 0xe6, 0xe0, 0x60,
+	0x00, 0x83, 0xa2, 0xd4, 0xe4, 0xd2, 0xa2, 0xe2,
+	0xcc, 0xb2, 0x54, 0x06, 0x00, 0x00, 0x17, 0x00,
+	0xe8, 0xff, 0x42, 0x12, 0x46, 0x16, 0x06, 0x00,
+	0x05, 0x00, 0xfa, 0xff, 0x42, 0x12, 0x46, 0x16,
+	0x06, 0x00, 0x05, 0x00, 0xfa, 0xff, 0x00, 0x05,
+	0x00, 0xfa, 0xff, 0x00, 0x14, 0x00, 0xeb, 0xff,
+	0x42, 0x12, 0x46, 0x16, 0x06, 0x00, 0x05, 0x00,
+	0xfa, 0xff, 0x00, 0x05, 0x00, 0xfa, 0xff, 0x00,
+	0x14, 0x00, 0xeb, 0xff, 0x42, 0x88, 0x21, 0xc4,
+	0x00, 0x00, 0x14, 0x00, 0xeb, 0xff, 0x42, 0x88,
+	0x21, 0xc4, 0x00, 0x00, 0x14, 0x00, 0xeb, 0xff,
+	0x42, 0x88, 0x21, 0xc4, 0x00, 0x00, 0x14, 0x00,
+	0xeb, 0xff, 0x42, 0x88, 0x21, 0xc4, 0x00, 0x00,
+	0x14, 0x00, 0xeb, 0xff, 0x42, 0x88, 0x21, 0xc4,
+	0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
+	0x00, 0xff, 0xff, 0x00, 0x17, 0x00, 0xe8, 0xff,
+	0x42, 0x88, 0x21, 0xc4, 0x00, 0x00, 0x00, 0x00,
+	0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00,
+	0x17, 0x00, 0xe8, 0xff, 0x42, 0x12, 0x46, 0x16,
+	0x06, 0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x08,
+	0x00, 0xf7, 0xff, 0x3d, 0xb1, 0x20, 0x85, 0xfa,
+	0x00, 0x00, 0x00, 0x42, 0x12, 0x46, 0x16, 0x06,
+	0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x08, 0x00,
+	0xf7, 0xff, 0x3d, 0xb1, 0x20, 0x85, 0xfa, 0x00,
+	0x00, 0x00, 0x3d, 0xb1, 0x20, 0x85, 0xfa, 0x00,
+	0x00, 0x00,
+}
diff --git a/src/pkg/net/http/triv.go b/src/net/http/triv.go
similarity index 100%
rename from src/pkg/net/http/triv.go
rename to src/net/http/triv.go
diff --git a/src/pkg/net/interface.go b/src/net/interface.go
similarity index 100%
rename from src/pkg/net/interface.go
rename to src/net/interface.go
diff --git a/src/pkg/net/interface_bsd.go b/src/net/interface_bsd.go
similarity index 100%
rename from src/pkg/net/interface_bsd.go
rename to src/net/interface_bsd.go
diff --git a/src/pkg/net/interface_bsd_test.go b/src/net/interface_bsd_test.go
similarity index 100%
rename from src/pkg/net/interface_bsd_test.go
rename to src/net/interface_bsd_test.go
diff --git a/src/pkg/net/interface_darwin.go b/src/net/interface_darwin.go
similarity index 100%
rename from src/pkg/net/interface_darwin.go
rename to src/net/interface_darwin.go
diff --git a/src/pkg/net/interface_dragonfly.go b/src/net/interface_dragonfly.go
similarity index 100%
rename from src/pkg/net/interface_dragonfly.go
rename to src/net/interface_dragonfly.go
diff --git a/src/pkg/net/interface_freebsd.go b/src/net/interface_freebsd.go
similarity index 100%
rename from src/pkg/net/interface_freebsd.go
rename to src/net/interface_freebsd.go
diff --git a/src/pkg/net/interface_linux.go b/src/net/interface_linux.go
similarity index 100%
rename from src/pkg/net/interface_linux.go
rename to src/net/interface_linux.go
diff --git a/src/pkg/net/interface_linux_test.go b/src/net/interface_linux_test.go
similarity index 100%
rename from src/pkg/net/interface_linux_test.go
rename to src/net/interface_linux_test.go
diff --git a/src/pkg/net/interface_netbsd.go b/src/net/interface_netbsd.go
similarity index 100%
rename from src/pkg/net/interface_netbsd.go
rename to src/net/interface_netbsd.go
diff --git a/src/pkg/net/interface_openbsd.go b/src/net/interface_openbsd.go
similarity index 100%
rename from src/pkg/net/interface_openbsd.go
rename to src/net/interface_openbsd.go
diff --git a/src/pkg/net/interface_stub.go b/src/net/interface_stub.go
similarity index 100%
rename from src/pkg/net/interface_stub.go
rename to src/net/interface_stub.go
diff --git a/src/pkg/net/interface_test.go b/src/net/interface_test.go
similarity index 100%
rename from src/pkg/net/interface_test.go
rename to src/net/interface_test.go
diff --git a/src/pkg/net/interface_unix_test.go b/src/net/interface_unix_test.go
similarity index 100%
rename from src/pkg/net/interface_unix_test.go
rename to src/net/interface_unix_test.go
diff --git a/src/pkg/net/interface_windows.go b/src/net/interface_windows.go
similarity index 100%
rename from src/pkg/net/interface_windows.go
rename to src/net/interface_windows.go
diff --git a/src/net/ip.go b/src/net/ip.go
new file mode 100644
index 0000000..4a93e97
--- /dev/null
+++ b/src/net/ip.go
@@ -0,0 +1,689 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// IP address manipulations
+//
+// IPv4 addresses are 4 bytes; IPv6 addresses are 16 bytes.
+// An IPv4 address can be converted to an IPv6 address by
+// adding a canonical prefix (10 zeros, 2 0xFFs).
+// This library accepts either size of byte slice but always
+// returns 16-byte addresses.
+
+package net
+
+import "errors"
+
+// IP address lengths (bytes).
+const (
+	IPv4len = 4
+	IPv6len = 16
+)
+
+// An IP is a single IP address, a slice of bytes.
+// Functions in this package accept either 4-byte (IPv4)
+// or 16-byte (IPv6) slices as input.
+//
+// Note that in this documentation, referring to an
+// IP address as an IPv4 address or an IPv6 address
+// is a semantic property of the address, not just the
+// length of the byte slice: a 16-byte slice can still
+// be an IPv4 address.
+type IP []byte
+
+// An IP mask is an IP address.
+type IPMask []byte
+
+// An IPNet represents an IP network.
+type IPNet struct {
+	IP   IP     // network number
+	Mask IPMask // network mask
+}
+
+// IPv4 returns the IP address (in 16-byte form) of the
+// IPv4 address a.b.c.d.
+func IPv4(a, b, c, d byte) IP {
+	p := make(IP, IPv6len)
+	copy(p, v4InV6Prefix)
+	p[12] = a
+	p[13] = b
+	p[14] = c
+	p[15] = d
+	return p
+}
+
+var v4InV6Prefix = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff}
+
+// IPv4Mask returns the IP mask (in 4-byte form) of the
+// IPv4 mask a.b.c.d.
+func IPv4Mask(a, b, c, d byte) IPMask {
+	p := make(IPMask, IPv4len)
+	p[0] = a
+	p[1] = b
+	p[2] = c
+	p[3] = d
+	return p
+}
+
+// CIDRMask returns an IPMask consisting of `ones' 1 bits
+// followed by 0s up to a total length of `bits' bits.
+// For a mask of this form, CIDRMask is the inverse of IPMask.Size.
+func CIDRMask(ones, bits int) IPMask {
+	if bits != 8*IPv4len && bits != 8*IPv6len {
+		return nil
+	}
+	if ones < 0 || ones > bits {
+		return nil
+	}
+	l := bits / 8
+	m := make(IPMask, l)
+	n := uint(ones)
+	for i := 0; i < l; i++ {
+		if n >= 8 {
+			m[i] = 0xff
+			n -= 8
+			continue
+		}
+		m[i] = ^byte(0xff >> n)
+		n = 0
+	}
+	return m
+}
+
+// Well-known IPv4 addresses
+var (
+	IPv4bcast     = IPv4(255, 255, 255, 255) // broadcast
+	IPv4allsys    = IPv4(224, 0, 0, 1)       // all systems
+	IPv4allrouter = IPv4(224, 0, 0, 2)       // all routers
+	IPv4zero      = IPv4(0, 0, 0, 0)         // all zeros
+)
+
+// Well-known IPv6 addresses
+var (
+	IPv6zero                   = IP{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+	IPv6unspecified            = IP{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+	IPv6loopback               = IP{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}
+	IPv6interfacelocalallnodes = IP{0xff, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01}
+	IPv6linklocalallnodes      = IP{0xff, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01}
+	IPv6linklocalallrouters    = IP{0xff, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x02}
+)
+
+// IsUnspecified returns true if ip is an unspecified address.
+func (ip IP) IsUnspecified() bool {
+	if ip.Equal(IPv4zero) || ip.Equal(IPv6unspecified) {
+		return true
+	}
+	return false
+}
+
+// IsLoopback returns true if ip is a loopback address.
+func (ip IP) IsLoopback() bool {
+	if ip4 := ip.To4(); ip4 != nil && ip4[0] == 127 {
+		return true
+	}
+	return ip.Equal(IPv6loopback)
+}
+
+// IsMulticast returns true if ip is a multicast address.
+func (ip IP) IsMulticast() bool {
+	if ip4 := ip.To4(); ip4 != nil && ip4[0]&0xf0 == 0xe0 {
+		return true
+	}
+	return ip[0] == 0xff
+}
+
+// IsInterfaceLinkLocalMulticast returns true if ip is
+// an interface-local multicast address.
+func (ip IP) IsInterfaceLocalMulticast() bool {
+	return len(ip) == IPv6len && ip[0] == 0xff && ip[1]&0x0f == 0x01
+}
+
+// IsLinkLocalMulticast returns true if ip is a link-local
+// multicast address.
+func (ip IP) IsLinkLocalMulticast() bool {
+	if ip4 := ip.To4(); ip4 != nil && ip4[0] == 224 && ip4[1] == 0 && ip4[2] == 0 {
+		return true
+	}
+	return ip[0] == 0xff && ip[1]&0x0f == 0x02
+}
+
+// IsLinkLocalUnicast returns true if ip is a link-local
+// unicast address.
+func (ip IP) IsLinkLocalUnicast() bool {
+	if ip4 := ip.To4(); ip4 != nil && ip4[0] == 169 && ip4[1] == 254 {
+		return true
+	}
+	return ip[0] == 0xfe && ip[1]&0xc0 == 0x80
+}
+
+// IsGlobalUnicast returns true if ip is a global unicast
+// address.
+func (ip IP) IsGlobalUnicast() bool {
+	return !ip.IsUnspecified() &&
+		!ip.IsLoopback() &&
+		!ip.IsMulticast() &&
+		!ip.IsLinkLocalUnicast()
+}
+
+// Is p all zeros?
+func isZeros(p IP) bool {
+	for i := 0; i < len(p); i++ {
+		if p[i] != 0 {
+			return false
+		}
+	}
+	return true
+}
+
+// To4 converts the IPv4 address ip to a 4-byte representation.
+// If ip is not an IPv4 address, To4 returns nil.
+func (ip IP) To4() IP {
+	if len(ip) == IPv4len {
+		return ip
+	}
+	if len(ip) == IPv6len &&
+		isZeros(ip[0:10]) &&
+		ip[10] == 0xff &&
+		ip[11] == 0xff {
+		return ip[12:16]
+	}
+	return nil
+}
+
+// To16 converts the IP address ip to a 16-byte representation.
+// If ip is not an IP address (it is the wrong length), To16 returns nil.
+func (ip IP) To16() IP {
+	if len(ip) == IPv4len {
+		return IPv4(ip[0], ip[1], ip[2], ip[3])
+	}
+	if len(ip) == IPv6len {
+		return ip
+	}
+	return nil
+}
+
+// Default route masks for IPv4.
+var (
+	classAMask = IPv4Mask(0xff, 0, 0, 0)
+	classBMask = IPv4Mask(0xff, 0xff, 0, 0)
+	classCMask = IPv4Mask(0xff, 0xff, 0xff, 0)
+)
+
+// DefaultMask returns the default IP mask for the IP address ip.
+// Only IPv4 addresses have default masks; DefaultMask returns
+// nil if ip is not a valid IPv4 address.
+func (ip IP) DefaultMask() IPMask {
+	if ip = ip.To4(); ip == nil {
+		return nil
+	}
+	switch true {
+	case ip[0] < 0x80:
+		return classAMask
+	case ip[0] < 0xC0:
+		return classBMask
+	default:
+		return classCMask
+	}
+}
+
+func allFF(b []byte) bool {
+	for _, c := range b {
+		if c != 0xff {
+			return false
+		}
+	}
+	return true
+}
+
+// Mask returns the result of masking the IP address ip with mask.
+func (ip IP) Mask(mask IPMask) IP {
+	if len(mask) == IPv6len && len(ip) == IPv4len && allFF(mask[:12]) {
+		mask = mask[12:]
+	}
+	if len(mask) == IPv4len && len(ip) == IPv6len && bytesEqual(ip[:12], v4InV6Prefix) {
+		ip = ip[12:]
+	}
+	n := len(ip)
+	if n != len(mask) {
+		return nil
+	}
+	out := make(IP, n)
+	for i := 0; i < n; i++ {
+		out[i] = ip[i] & mask[i]
+	}
+	return out
+}
+
+// String returns the string form of the IP address ip.
+// If the address is an IPv4 address, the string representation
+// is dotted decimal ("74.125.19.99").  Otherwise the representation
+// is IPv6 ("2001:4860:0:2001::68").
+func (ip IP) String() string {
+	p := ip
+
+	if len(ip) == 0 {
+		return "<nil>"
+	}
+
+	// If IPv4, use dotted notation.
+	if p4 := p.To4(); len(p4) == IPv4len {
+		return itod(uint(p4[0])) + "." +
+			itod(uint(p4[1])) + "." +
+			itod(uint(p4[2])) + "." +
+			itod(uint(p4[3]))
+	}
+	if len(p) != IPv6len {
+		return "?"
+	}
+
+	// Find longest run of zeros.
+	e0 := -1
+	e1 := -1
+	for i := 0; i < IPv6len; i += 2 {
+		j := i
+		for j < IPv6len && p[j] == 0 && p[j+1] == 0 {
+			j += 2
+		}
+		if j > i && j-i > e1-e0 {
+			e0 = i
+			e1 = j
+			i = j
+		}
+	}
+	// The symbol "::" MUST NOT be used to shorten just one 16 bit 0 field.
+	if e1-e0 <= 2 {
+		e0 = -1
+		e1 = -1
+	}
+
+	const maxLen = len("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")
+	b := make([]byte, 0, maxLen)
+
+	// Print with possible :: in place of run of zeros
+	for i := 0; i < IPv6len; i += 2 {
+		if i == e0 {
+			b = append(b, ':', ':')
+			i = e1
+			if i >= IPv6len {
+				break
+			}
+		} else if i > 0 {
+			b = append(b, ':')
+		}
+		b = appendHex(b, (uint32(p[i])<<8)|uint32(p[i+1]))
+	}
+	return string(b)
+}
+
+// ipEmptyString is like ip.String except that it returns
+// an empty string when ip is unset.
+func ipEmptyString(ip IP) string {
+	if len(ip) == 0 {
+		return ""
+	}
+	return ip.String()
+}
+
+// MarshalText implements the encoding.TextMarshaler interface.
+// The encoding is the same as returned by String.
+func (ip IP) MarshalText() ([]byte, error) {
+	if len(ip) == 0 {
+		return []byte(""), nil
+	}
+	if len(ip) != IPv4len && len(ip) != IPv6len {
+		return nil, errors.New("invalid IP address")
+	}
+	return []byte(ip.String()), nil
+}
+
+// UnmarshalText implements the encoding.TextUnmarshaler interface.
+// The IP address is expected in a form accepted by ParseIP.
+func (ip *IP) UnmarshalText(text []byte) error {
+	if len(text) == 0 {
+		*ip = nil
+		return nil
+	}
+	s := string(text)
+	x := ParseIP(s)
+	if x == nil {
+		return &ParseError{"IP address", s}
+	}
+	*ip = x
+	return nil
+}
+
+// Equal returns true if ip and x are the same IP address.
+// An IPv4 address and that same address in IPv6 form are
+// considered to be equal.
+func (ip IP) Equal(x IP) bool {
+	if len(ip) == len(x) {
+		return bytesEqual(ip, x)
+	}
+	if len(ip) == IPv4len && len(x) == IPv6len {
+		return bytesEqual(x[0:12], v4InV6Prefix) && bytesEqual(ip, x[12:])
+	}
+	if len(ip) == IPv6len && len(x) == IPv4len {
+		return bytesEqual(ip[0:12], v4InV6Prefix) && bytesEqual(ip[12:], x)
+	}
+	return false
+}
+
+func bytesEqual(x, y []byte) bool {
+	if len(x) != len(y) {
+		return false
+	}
+	for i, b := range x {
+		if y[i] != b {
+			return false
+		}
+	}
+	return true
+}
+
+// If mask is a sequence of 1 bits followed by 0 bits,
+// return the number of 1 bits.
+func simpleMaskLength(mask IPMask) int {
+	var n int
+	for i, v := range mask {
+		if v == 0xff {
+			n += 8
+			continue
+		}
+		// found non-ff byte
+		// count 1 bits
+		for v&0x80 != 0 {
+			n++
+			v <<= 1
+		}
+		// rest must be 0 bits
+		if v != 0 {
+			return -1
+		}
+		for i++; i < len(mask); i++ {
+			if mask[i] != 0 {
+				return -1
+			}
+		}
+		break
+	}
+	return n
+}
+
+// Size returns the number of leading ones and total bits in the mask.
+// If the mask is not in the canonical form--ones followed by zeros--then
+// Size returns 0, 0.
+func (m IPMask) Size() (ones, bits int) {
+	ones, bits = simpleMaskLength(m), len(m)*8
+	if ones == -1 {
+		return 0, 0
+	}
+	return
+}
+
+// String returns the hexadecimal form of m, with no punctuation.
+func (m IPMask) String() string {
+	if len(m) == 0 {
+		return "<nil>"
+	}
+	buf := make([]byte, len(m)*2)
+	for i, b := range m {
+		buf[i*2], buf[i*2+1] = hexDigit[b>>4], hexDigit[b&0xf]
+	}
+	return string(buf)
+}
+
+func networkNumberAndMask(n *IPNet) (ip IP, m IPMask) {
+	if ip = n.IP.To4(); ip == nil {
+		ip = n.IP
+		if len(ip) != IPv6len {
+			return nil, nil
+		}
+	}
+	m = n.Mask
+	switch len(m) {
+	case IPv4len:
+		if len(ip) != IPv4len {
+			return nil, nil
+		}
+	case IPv6len:
+		if len(ip) == IPv4len {
+			m = m[12:]
+		}
+	default:
+		return nil, nil
+	}
+	return
+}
+
+// Contains reports whether the network includes ip.
+func (n *IPNet) Contains(ip IP) bool {
+	nn, m := networkNumberAndMask(n)
+	if x := ip.To4(); x != nil {
+		ip = x
+	}
+	l := len(ip)
+	if l != len(nn) {
+		return false
+	}
+	for i := 0; i < l; i++ {
+		if nn[i]&m[i] != ip[i]&m[i] {
+			return false
+		}
+	}
+	return true
+}
+
+// Network returns the address's network name, "ip+net".
+func (n *IPNet) Network() string { return "ip+net" }
+
+// String returns the CIDR notation of n like "192.168.100.1/24"
+// or "2001:DB8::/48" as defined in RFC 4632 and RFC 4291.
+// If the mask is not in the canonical form, it returns the
+// string which consists of an IP address, followed by a slash
+// character and a mask expressed as hexadecimal form with no
+// punctuation like "192.168.100.1/c000ff00".
+func (n *IPNet) String() string {
+	nn, m := networkNumberAndMask(n)
+	if nn == nil || m == nil {
+		return "<nil>"
+	}
+	l := simpleMaskLength(m)
+	if l == -1 {
+		return nn.String() + "/" + m.String()
+	}
+	return nn.String() + "/" + itod(uint(l))
+}
+
+// Parse IPv4 address (d.d.d.d).
+func parseIPv4(s string) IP {
+	var p [IPv4len]byte
+	i := 0
+	for j := 0; j < IPv4len; j++ {
+		if i >= len(s) {
+			// Missing octets.
+			return nil
+		}
+		if j > 0 {
+			if s[i] != '.' {
+				return nil
+			}
+			i++
+		}
+		var (
+			n  int
+			ok bool
+		)
+		n, i, ok = dtoi(s, i)
+		if !ok || n > 0xFF {
+			return nil
+		}
+		p[j] = byte(n)
+	}
+	if i != len(s) {
+		return nil
+	}
+	return IPv4(p[0], p[1], p[2], p[3])
+}
+
+// parseIPv6 parses s as a literal IPv6 address described in RFC 4291
+// and RFC 5952.  It can also parse a literal scoped IPv6 address with
+// zone identifier which is described in RFC 4007 when zoneAllowed is
+// true.
+func parseIPv6(s string, zoneAllowed bool) (ip IP, zone string) {
+	ip = make(IP, IPv6len)
+	ellipsis := -1 // position of ellipsis in p
+	i := 0         // index in string s
+
+	if zoneAllowed {
+		s, zone = splitHostZone(s)
+	}
+
+	// Might have leading ellipsis
+	if len(s) >= 2 && s[0] == ':' && s[1] == ':' {
+		ellipsis = 0
+		i = 2
+		// Might be only ellipsis
+		if i == len(s) {
+			return ip, zone
+		}
+	}
+
+	// Loop, parsing hex numbers followed by colon.
+	j := 0
+	for j < IPv6len {
+		// Hex number.
+		n, i1, ok := xtoi(s, i)
+		if !ok || n > 0xFFFF {
+			return nil, zone
+		}
+
+		// If followed by dot, might be in trailing IPv4.
+		if i1 < len(s) && s[i1] == '.' {
+			if ellipsis < 0 && j != IPv6len-IPv4len {
+				// Not the right place.
+				return nil, zone
+			}
+			if j+IPv4len > IPv6len {
+				// Not enough room.
+				return nil, zone
+			}
+			ip4 := parseIPv4(s[i:])
+			if ip4 == nil {
+				return nil, zone
+			}
+			ip[j] = ip4[12]
+			ip[j+1] = ip4[13]
+			ip[j+2] = ip4[14]
+			ip[j+3] = ip4[15]
+			i = len(s)
+			j += IPv4len
+			break
+		}
+
+		// Save this 16-bit chunk.
+		ip[j] = byte(n >> 8)
+		ip[j+1] = byte(n)
+		j += 2
+
+		// Stop at end of string.
+		i = i1
+		if i == len(s) {
+			break
+		}
+
+		// Otherwise must be followed by colon and more.
+		if s[i] != ':' || i+1 == len(s) {
+			return nil, zone
+		}
+		i++
+
+		// Look for ellipsis.
+		if s[i] == ':' {
+			if ellipsis >= 0 { // already have one
+				return nil, zone
+			}
+			ellipsis = j
+			if i++; i == len(s) { // can be at end
+				break
+			}
+		}
+	}
+
+	// Must have used entire string.
+	if i != len(s) {
+		return nil, zone
+	}
+
+	// If didn't parse enough, expand ellipsis.
+	if j < IPv6len {
+		if ellipsis < 0 {
+			return nil, zone
+		}
+		n := IPv6len - j
+		for k := j - 1; k >= ellipsis; k-- {
+			ip[k+n] = ip[k]
+		}
+		for k := ellipsis + n - 1; k >= ellipsis; k-- {
+			ip[k] = 0
+		}
+	} else if ellipsis >= 0 {
+		// Ellipsis must represent at least one 0 group.
+		return nil, zone
+	}
+	return ip, zone
+}
+
+// A ParseError represents a malformed text string and the type of string that was expected.
+type ParseError struct {
+	Type string
+	Text string
+}
+
+func (e *ParseError) Error() string {
+	return "invalid " + e.Type + ": " + e.Text
+}
+
+// ParseIP parses s as an IP address, returning the result.
+// The string s can be in dotted decimal ("74.125.19.99")
+// or IPv6 ("2001:4860:0:2001::68") form.
+// If s is not a valid textual representation of an IP address,
+// ParseIP returns nil.
+func ParseIP(s string) IP {
+	for i := 0; i < len(s); i++ {
+		switch s[i] {
+		case '.':
+			return parseIPv4(s)
+		case ':':
+			ip, _ := parseIPv6(s, false)
+			return ip
+		}
+	}
+	return nil
+}
+
+// ParseCIDR parses s as a CIDR notation IP address and mask,
+// like "192.168.100.1/24" or "2001:DB8::/48", as defined in
+// RFC 4632 and RFC 4291.
+//
+// It returns the IP address and the network implied by the IP
+// and mask.  For example, ParseCIDR("192.168.100.1/16") returns
+// the IP address 192.168.100.1 and the network 192.168.0.0/16.
+func ParseCIDR(s string) (IP, *IPNet, error) {
+	i := byteIndex(s, '/')
+	if i < 0 {
+		return nil, nil, &ParseError{"CIDR address", s}
+	}
+	addr, mask := s[:i], s[i+1:]
+	iplen := IPv4len
+	ip := parseIPv4(addr)
+	if ip == nil {
+		iplen = IPv6len
+		ip, _ = parseIPv6(addr, false)
+	}
+	n, i, ok := dtoi(mask, 0)
+	if ip == nil || !ok || i != len(mask) || n < 0 || n > 8*iplen {
+		return nil, nil, &ParseError{"CIDR address", s}
+	}
+	m := CIDRMask(n, 8*iplen)
+	return ip, &IPNet{IP: ip.Mask(m), Mask: m}, nil
+}
diff --git a/src/net/ip_test.go b/src/net/ip_test.go
new file mode 100644
index 0000000..485ff51
--- /dev/null
+++ b/src/net/ip_test.go
@@ -0,0 +1,465 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package net
+
+import (
+	"reflect"
+	"runtime"
+	"testing"
+)
+
+var parseIPTests = []struct {
+	in  string
+	out IP
+}{
+	{"127.0.1.2", IPv4(127, 0, 1, 2)},
+	{"127.0.0.1", IPv4(127, 0, 0, 1)},
+	{"127.0.0.256", nil},
+	{"abc", nil},
+	{"123:", nil},
+	{"::ffff:127.0.0.1", IPv4(127, 0, 0, 1)},
+	{"2001:4860:0:2001::68", IP{0x20, 0x01, 0x48, 0x60, 0, 0, 0x20, 0x01, 0, 0, 0, 0, 0, 0, 0x00, 0x68}},
+	{"::ffff:4a7d:1363", IPv4(74, 125, 19, 99)},
+	{"fe80::1%lo0", nil},
+	{"fe80::1%911", nil},
+	{"", nil},
+	{"a1:a2:a3:a4::b1:b2:b3:b4", nil}, // Issue 6628
+}
+
+func TestParseIP(t *testing.T) {
+	for _, tt := range parseIPTests {
+		if out := ParseIP(tt.in); !reflect.DeepEqual(out, tt.out) {
+			t.Errorf("ParseIP(%q) = %v, want %v", tt.in, out, tt.out)
+		}
+		if tt.in == "" {
+			// Tested in TestMarshalEmptyIP below.
+			continue
+		}
+		var out IP
+		if err := out.UnmarshalText([]byte(tt.in)); !reflect.DeepEqual(out, tt.out) || (tt.out == nil) != (err != nil) {
+			t.Errorf("IP.UnmarshalText(%q) = %v, %v, want %v", tt.in, out, err, tt.out)
+		}
+	}
+}
+
+func BenchmarkParseIP(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		for _, tt := range parseIPTests {
+			ParseIP(tt.in)
+		}
+	}
+}
+
+// Issue 6339
+func TestMarshalEmptyIP(t *testing.T) {
+	for _, in := range [][]byte{nil, []byte("")} {
+		var out = IP{1, 2, 3, 4}
+		if err := out.UnmarshalText(in); err != nil || out != nil {
+			t.Errorf("UnmarshalText(%v) = %v, %v; want nil, nil", in, out, err)
+		}
+	}
+	var ip IP
+	got, err := ip.MarshalText()
+	if err != nil {
+		t.Fatal(err)
+	}
+	if !reflect.DeepEqual(got, []byte("")) {
+		t.Errorf(`got %#v, want []byte("")`, got)
+	}
+}
+
+var ipStringTests = []struct {
+	in  IP
+	out string // see RFC 5952
+}{
+	{IP{0x20, 0x1, 0xd, 0xb8, 0, 0, 0, 0, 0, 0, 0x1, 0x23, 0, 0x12, 0, 0x1}, "2001:db8::123:12:1"},
+	{IP{0x20, 0x1, 0xd, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1}, "2001:db8::1"},
+	{IP{0x20, 0x1, 0xd, 0xb8, 0, 0, 0, 0x1, 0, 0, 0, 0x1, 0, 0, 0, 0x1}, "2001:db8:0:1:0:1:0:1"},
+	{IP{0x20, 0x1, 0xd, 0xb8, 0, 0x1, 0, 0, 0, 0x1, 0, 0, 0, 0x1, 0, 0}, "2001:db8:1:0:1:0:1:0"},
+	{IP{0x20, 0x1, 0, 0, 0, 0, 0, 0, 0, 0x1, 0, 0, 0, 0, 0, 0x1}, "2001::1:0:0:1"},
+	{IP{0x20, 0x1, 0xd, 0xb8, 0, 0, 0, 0, 0, 0x1, 0, 0, 0, 0, 0, 0}, "2001:db8:0:0:1::"},
+	{IP{0x20, 0x1, 0xd, 0xb8, 0, 0, 0, 0, 0, 0x1, 0, 0, 0, 0, 0, 0x1}, "2001:db8::1:0:0:1"},
+	{IP{0x20, 0x1, 0xD, 0xB8, 0, 0, 0, 0, 0, 0xA, 0, 0xB, 0, 0xC, 0, 0xD}, "2001:db8::a:b:c:d"},
+	{IPv4(192, 168, 0, 1), "192.168.0.1"},
+	{nil, ""},
+}
+
+func TestIPString(t *testing.T) {
+	for _, tt := range ipStringTests {
+		if tt.in != nil {
+			if out := tt.in.String(); out != tt.out {
+				t.Errorf("IP.String(%v) = %q, want %q", tt.in, out, tt.out)
+			}
+		}
+		if out, err := tt.in.MarshalText(); string(out) != tt.out || err != nil {
+			t.Errorf("IP.MarshalText(%v) = %q, %v, want %q, nil", tt.in, out, err, tt.out)
+		}
+	}
+}
+
+func BenchmarkIPString(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		for _, tt := range ipStringTests {
+			if tt.in != nil {
+				tt.in.String()
+			}
+		}
+	}
+}
+
+var ipMaskTests = []struct {
+	in   IP
+	mask IPMask
+	out  IP
+}{
+	{IPv4(192, 168, 1, 127), IPv4Mask(255, 255, 255, 128), IPv4(192, 168, 1, 0)},
+	{IPv4(192, 168, 1, 127), IPMask(ParseIP("255.255.255.192")), IPv4(192, 168, 1, 64)},
+	{IPv4(192, 168, 1, 127), IPMask(ParseIP("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffe0")), IPv4(192, 168, 1, 96)},
+	{IPv4(192, 168, 1, 127), IPv4Mask(255, 0, 255, 0), IPv4(192, 0, 1, 0)},
+	{ParseIP("2001:db8::1"), IPMask(ParseIP("ffff:ff80::")), ParseIP("2001:d80::")},
+	{ParseIP("2001:db8::1"), IPMask(ParseIP("f0f0:0f0f::")), ParseIP("2000:d08::")},
+}
+
+func TestIPMask(t *testing.T) {
+	for _, tt := range ipMaskTests {
+		if out := tt.in.Mask(tt.mask); out == nil || !tt.out.Equal(out) {
+			t.Errorf("IP(%v).Mask(%v) = %v, want %v", tt.in, tt.mask, out, tt.out)
+		}
+	}
+}
+
+var ipMaskStringTests = []struct {
+	in  IPMask
+	out string
+}{
+	{IPv4Mask(255, 255, 255, 240), "fffffff0"},
+	{IPv4Mask(255, 0, 128, 0), "ff008000"},
+	{IPMask(ParseIP("ffff:ff80::")), "ffffff80000000000000000000000000"},
+	{IPMask(ParseIP("ef00:ff80::cafe:0")), "ef00ff800000000000000000cafe0000"},
+	{nil, "<nil>"},
+}
+
+func TestIPMaskString(t *testing.T) {
+	for _, tt := range ipMaskStringTests {
+		if out := tt.in.String(); out != tt.out {
+			t.Errorf("IPMask.String(%v) = %q, want %q", tt.in, out, tt.out)
+		}
+	}
+}
+
+func BenchmarkIPMaskString(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		for _, tt := range ipMaskStringTests {
+			tt.in.String()
+		}
+	}
+}
+
+var parseCIDRTests = []struct {
+	in  string
+	ip  IP
+	net *IPNet
+	err error
+}{
+	{"135.104.0.0/32", IPv4(135, 104, 0, 0), &IPNet{IP: IPv4(135, 104, 0, 0), Mask: IPv4Mask(255, 255, 255, 255)}, nil},
+	{"0.0.0.0/24", IPv4(0, 0, 0, 0), &IPNet{IP: IPv4(0, 0, 0, 0), Mask: IPv4Mask(255, 255, 255, 0)}, nil},
+	{"135.104.0.0/24", IPv4(135, 104, 0, 0), &IPNet{IP: IPv4(135, 104, 0, 0), Mask: IPv4Mask(255, 255, 255, 0)}, nil},
+	{"135.104.0.1/32", IPv4(135, 104, 0, 1), &IPNet{IP: IPv4(135, 104, 0, 1), Mask: IPv4Mask(255, 255, 255, 255)}, nil},
+	{"135.104.0.1/24", IPv4(135, 104, 0, 1), &IPNet{IP: IPv4(135, 104, 0, 0), Mask: IPv4Mask(255, 255, 255, 0)}, nil},
+	{"::1/128", ParseIP("::1"), &IPNet{IP: ParseIP("::1"), Mask: IPMask(ParseIP("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"))}, nil},
+	{"abcd:2345::/127", ParseIP("abcd:2345::"), &IPNet{IP: ParseIP("abcd:2345::"), Mask: IPMask(ParseIP("ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffe"))}, nil},
+	{"abcd:2345::/65", ParseIP("abcd:2345::"), &IPNet{IP: ParseIP("abcd:2345::"), Mask: IPMask(ParseIP("ffff:ffff:ffff:ffff:8000::"))}, nil},
+	{"abcd:2345::/64", ParseIP("abcd:2345::"), &IPNet{IP: ParseIP("abcd:2345::"), Mask: IPMask(ParseIP("ffff:ffff:ffff:ffff::"))}, nil},
+	{"abcd:2345::/63", ParseIP("abcd:2345::"), &IPNet{IP: ParseIP("abcd:2345::"), Mask: IPMask(ParseIP("ffff:ffff:ffff:fffe::"))}, nil},
+	{"abcd:2345::/33", ParseIP("abcd:2345::"), &IPNet{IP: ParseIP("abcd:2345::"), Mask: IPMask(ParseIP("ffff:ffff:8000::"))}, nil},
+	{"abcd:2345::/32", ParseIP("abcd:2345::"), &IPNet{IP: ParseIP("abcd:2345::"), Mask: IPMask(ParseIP("ffff:ffff::"))}, nil},
+	{"abcd:2344::/31", ParseIP("abcd:2344::"), &IPNet{IP: ParseIP("abcd:2344::"), Mask: IPMask(ParseIP("ffff:fffe::"))}, nil},
+	{"abcd:2300::/24", ParseIP("abcd:2300::"), &IPNet{IP: ParseIP("abcd:2300::"), Mask: IPMask(ParseIP("ffff:ff00::"))}, nil},
+	{"abcd:2345::/24", ParseIP("abcd:2345::"), &IPNet{IP: ParseIP("abcd:2300::"), Mask: IPMask(ParseIP("ffff:ff00::"))}, nil},
+	{"2001:DB8::/48", ParseIP("2001:DB8::"), &IPNet{IP: ParseIP("2001:DB8::"), Mask: IPMask(ParseIP("ffff:ffff:ffff::"))}, nil},
+	{"2001:DB8::1/48", ParseIP("2001:DB8::1"), &IPNet{IP: ParseIP("2001:DB8::"), Mask: IPMask(ParseIP("ffff:ffff:ffff::"))}, nil},
+	{"192.168.1.1/255.255.255.0", nil, nil, &ParseError{"CIDR address", "192.168.1.1/255.255.255.0"}},
+	{"192.168.1.1/35", nil, nil, &ParseError{"CIDR address", "192.168.1.1/35"}},
+	{"2001:db8::1/-1", nil, nil, &ParseError{"CIDR address", "2001:db8::1/-1"}},
+	{"", nil, nil, &ParseError{"CIDR address", ""}},
+}
+
+func TestParseCIDR(t *testing.T) {
+	for _, tt := range parseCIDRTests {
+		ip, net, err := ParseCIDR(tt.in)
+		if !reflect.DeepEqual(err, tt.err) {
+			t.Errorf("ParseCIDR(%q) = %v, %v; want %v, %v", tt.in, ip, net, tt.ip, tt.net)
+		}
+		if err == nil && (!tt.ip.Equal(ip) || !tt.net.IP.Equal(net.IP) || !reflect.DeepEqual(net.Mask, tt.net.Mask)) {
+			t.Errorf("ParseCIDR(%q) = %v, {%v, %v}; want %v, {%v, %v}", tt.in, ip, net.IP, net.Mask, tt.ip, tt.net.IP, tt.net.Mask)
+		}
+	}
+}
+
+var ipNetContainsTests = []struct {
+	ip  IP
+	net *IPNet
+	ok  bool
+}{
+	{IPv4(172, 16, 1, 1), &IPNet{IP: IPv4(172, 16, 0, 0), Mask: CIDRMask(12, 32)}, true},
+	{IPv4(172, 24, 0, 1), &IPNet{IP: IPv4(172, 16, 0, 0), Mask: CIDRMask(13, 32)}, false},
+	{IPv4(192, 168, 0, 3), &IPNet{IP: IPv4(192, 168, 0, 0), Mask: IPv4Mask(0, 0, 255, 252)}, true},
+	{IPv4(192, 168, 0, 4), &IPNet{IP: IPv4(192, 168, 0, 0), Mask: IPv4Mask(0, 255, 0, 252)}, false},
+	{ParseIP("2001:db8:1:2::1"), &IPNet{IP: ParseIP("2001:db8:1::"), Mask: CIDRMask(47, 128)}, true},
+	{ParseIP("2001:db8:1:2::1"), &IPNet{IP: ParseIP("2001:db8:2::"), Mask: CIDRMask(47, 128)}, false},
+	{ParseIP("2001:db8:1:2::1"), &IPNet{IP: ParseIP("2001:db8:1::"), Mask: IPMask(ParseIP("ffff:0:ffff::"))}, true},
+	{ParseIP("2001:db8:1:2::1"), &IPNet{IP: ParseIP("2001:db8:1::"), Mask: IPMask(ParseIP("0:0:0:ffff::"))}, false},
+}
+
+func TestIPNetContains(t *testing.T) {
+	for _, tt := range ipNetContainsTests {
+		if ok := tt.net.Contains(tt.ip); ok != tt.ok {
+			t.Errorf("IPNet(%v).Contains(%v) = %v, want %v", tt.net, tt.ip, ok, tt.ok)
+		}
+	}
+}
+
+var ipNetStringTests = []struct {
+	in  *IPNet
+	out string
+}{
+	{&IPNet{IP: IPv4(192, 168, 1, 0), Mask: CIDRMask(26, 32)}, "192.168.1.0/26"},
+	{&IPNet{IP: IPv4(192, 168, 1, 0), Mask: IPv4Mask(255, 0, 255, 0)}, "192.168.1.0/ff00ff00"},
+	{&IPNet{IP: ParseIP("2001:db8::"), Mask: CIDRMask(55, 128)}, "2001:db8::/55"},
+	{&IPNet{IP: ParseIP("2001:db8::"), Mask: IPMask(ParseIP("8000:f123:0:cafe::"))}, "2001:db8::/8000f1230000cafe0000000000000000"},
+}
+
+func TestIPNetString(t *testing.T) {
+	for _, tt := range ipNetStringTests {
+		if out := tt.in.String(); out != tt.out {
+			t.Errorf("IPNet.String(%v) = %q, want %q", tt.in, out, tt.out)
+		}
+	}
+}
+
+var cidrMaskTests = []struct {
+	ones int
+	bits int
+	out  IPMask
+}{
+	{0, 32, IPv4Mask(0, 0, 0, 0)},
+	{12, 32, IPv4Mask(255, 240, 0, 0)},
+	{24, 32, IPv4Mask(255, 255, 255, 0)},
+	{32, 32, IPv4Mask(255, 255, 255, 255)},
+	{0, 128, IPMask{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
+	{4, 128, IPMask{0xf0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
+	{48, 128, IPMask{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
+	{128, 128, IPMask{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}},
+	{33, 32, nil},
+	{32, 33, nil},
+	{-1, 128, nil},
+	{128, -1, nil},
+}
+
+func TestCIDRMask(t *testing.T) {
+	for _, tt := range cidrMaskTests {
+		if out := CIDRMask(tt.ones, tt.bits); !reflect.DeepEqual(out, tt.out) {
+			t.Errorf("CIDRMask(%v, %v) = %v, want %v", tt.ones, tt.bits, out, tt.out)
+		}
+	}
+}
+
+var (
+	v4addr         = IP{192, 168, 0, 1}
+	v4mappedv6addr = IP{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 192, 168, 0, 1}
+	v6addr         = IP{0x20, 0x1, 0xd, 0xb8, 0, 0, 0, 0, 0, 0, 0x1, 0x23, 0, 0x12, 0, 0x1}
+	v4mask         = IPMask{255, 255, 255, 0}
+	v4mappedv6mask = IPMask{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 255, 255, 255, 0}
+	v6mask         = IPMask{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0}
+	badaddr        = IP{192, 168, 0}
+	badmask        = IPMask{255, 255, 0}
+	v4maskzero     = IPMask{0, 0, 0, 0}
+)
+
+var networkNumberAndMaskTests = []struct {
+	in  IPNet
+	out IPNet
+}{
+	{IPNet{IP: v4addr, Mask: v4mask}, IPNet{IP: v4addr, Mask: v4mask}},
+	{IPNet{IP: v4addr, Mask: v4mappedv6mask}, IPNet{IP: v4addr, Mask: v4mask}},
+	{IPNet{IP: v4mappedv6addr, Mask: v4mappedv6mask}, IPNet{IP: v4addr, Mask: v4mask}},
+	{IPNet{IP: v4mappedv6addr, Mask: v6mask}, IPNet{IP: v4addr, Mask: v4maskzero}},
+	{IPNet{IP: v4addr, Mask: v6mask}, IPNet{IP: v4addr, Mask: v4maskzero}},
+	{IPNet{IP: v6addr, Mask: v6mask}, IPNet{IP: v6addr, Mask: v6mask}},
+	{IPNet{IP: v6addr, Mask: v4mappedv6mask}, IPNet{IP: v6addr, Mask: v4mappedv6mask}},
+	{in: IPNet{IP: v6addr, Mask: v4mask}},
+	{in: IPNet{IP: v4addr, Mask: badmask}},
+	{in: IPNet{IP: v4mappedv6addr, Mask: badmask}},
+	{in: IPNet{IP: v6addr, Mask: badmask}},
+	{in: IPNet{IP: badaddr, Mask: v4mask}},
+	{in: IPNet{IP: badaddr, Mask: v4mappedv6mask}},
+	{in: IPNet{IP: badaddr, Mask: v6mask}},
+	{in: IPNet{IP: badaddr, Mask: badmask}},
+}
+
+func TestNetworkNumberAndMask(t *testing.T) {
+	for _, tt := range networkNumberAndMaskTests {
+		ip, m := networkNumberAndMask(&tt.in)
+		out := &IPNet{IP: ip, Mask: m}
+		if !reflect.DeepEqual(&tt.out, out) {
+			t.Errorf("networkNumberAndMask(%v) = %v, want %v", tt.in, out, &tt.out)
+		}
+	}
+}
+
+var splitJoinTests = []struct {
+	host string
+	port string
+	join string
+}{
+	{"www.google.com", "80", "www.google.com:80"},
+	{"127.0.0.1", "1234", "127.0.0.1:1234"},
+	{"::1", "80", "[::1]:80"},
+	{"fe80::1%lo0", "80", "[fe80::1%lo0]:80"},
+	{"localhost%lo0", "80", "[localhost%lo0]:80"},
+	{"", "0", ":0"},
+
+	{"google.com", "https%foo", "google.com:https%foo"}, // Go 1.0 behavior
+	{"127.0.0.1", "", "127.0.0.1:"},                     // Go 1.0 behaviour
+	{"www.google.com", "", "www.google.com:"},           // Go 1.0 behaviour
+}
+
+var splitFailureTests = []struct {
+	hostPort string
+	err      string
+}{
+	{"www.google.com", "missing port in address"},
+	{"127.0.0.1", "missing port in address"},
+	{"[::1]", "missing port in address"},
+	{"[fe80::1%lo0]", "missing port in address"},
+	{"[localhost%lo0]", "missing port in address"},
+	{"localhost%lo0", "missing port in address"},
+
+	{"::1", "too many colons in address"},
+	{"fe80::1%lo0", "too many colons in address"},
+	{"fe80::1%lo0:80", "too many colons in address"},
+
+	{"localhost%lo0:80", "missing brackets in address"},
+
+	// Test cases that didn't fail in Go 1.0
+
+	{"[foo:bar]", "missing port in address"},
+	{"[foo:bar]baz", "missing port in address"},
+	{"[foo]bar:baz", "missing port in address"},
+
+	{"[foo]:[bar]:baz", "too many colons in address"},
+
+	{"[foo]:[bar]baz", "unexpected '[' in address"},
+	{"foo[bar]:baz", "unexpected '[' in address"},
+
+	{"foo]bar:baz", "unexpected ']' in address"},
+}
+
+func TestSplitHostPort(t *testing.T) {
+	for _, tt := range splitJoinTests {
+		if host, port, err := SplitHostPort(tt.join); host != tt.host || port != tt.port || err != nil {
+			t.Errorf("SplitHostPort(%q) = %q, %q, %v; want %q, %q, nil", tt.join, host, port, err, tt.host, tt.port)
+		}
+	}
+	for _, tt := range splitFailureTests {
+		if _, _, err := SplitHostPort(tt.hostPort); err == nil {
+			t.Errorf("SplitHostPort(%q) should have failed", tt.hostPort)
+		} else {
+			e := err.(*AddrError)
+			if e.Err != tt.err {
+				t.Errorf("SplitHostPort(%q) = _, _, %q; want %q", tt.hostPort, e.Err, tt.err)
+			}
+		}
+	}
+}
+
+func TestJoinHostPort(t *testing.T) {
+	for _, tt := range splitJoinTests {
+		if join := JoinHostPort(tt.host, tt.port); join != tt.join {
+			t.Errorf("JoinHostPort(%q, %q) = %q; want %q", tt.host, tt.port, join, tt.join)
+		}
+	}
+}
+
+var ipAddrFamilyTests = []struct {
+	in  IP
+	af4 bool
+	af6 bool
+}{
+	{IPv4bcast, true, false},
+	{IPv4allsys, true, false},
+	{IPv4allrouter, true, false},
+	{IPv4zero, true, false},
+	{IPv4(224, 0, 0, 1), true, false},
+	{IPv4(127, 0, 0, 1), true, false},
+	{IPv4(240, 0, 0, 1), true, false},
+	{IPv6unspecified, false, true},
+	{IPv6loopback, false, true},
+	{IPv6interfacelocalallnodes, false, true},
+	{IPv6linklocalallnodes, false, true},
+	{IPv6linklocalallrouters, false, true},
+	{ParseIP("ff05::a:b:c:d"), false, true},
+	{ParseIP("fe80::1:2:3:4"), false, true},
+	{ParseIP("2001:db8::123:12:1"), false, true},
+}
+
+func TestIPAddrFamily(t *testing.T) {
+	for _, tt := range ipAddrFamilyTests {
+		if af := tt.in.To4() != nil; af != tt.af4 {
+			t.Errorf("verifying IPv4 address family for %q = %v, want %v", tt.in, af, tt.af4)
+		}
+		if af := len(tt.in) == IPv6len && tt.in.To4() == nil; af != tt.af6 {
+			t.Errorf("verifying IPv6 address family for %q = %v, want %v", tt.in, af, tt.af6)
+		}
+	}
+}
+
+var ipAddrScopeTests = []struct {
+	scope func(IP) bool
+	in    IP
+	ok    bool
+}{
+	{IP.IsUnspecified, IPv4zero, true},
+	{IP.IsUnspecified, IPv4(127, 0, 0, 1), false},
+	{IP.IsUnspecified, IPv6unspecified, true},
+	{IP.IsUnspecified, IPv6interfacelocalallnodes, false},
+	{IP.IsLoopback, IPv4(127, 0, 0, 1), true},
+	{IP.IsLoopback, IPv4(127, 255, 255, 254), true},
+	{IP.IsLoopback, IPv4(128, 1, 2, 3), false},
+	{IP.IsLoopback, IPv6loopback, true},
+	{IP.IsLoopback, IPv6linklocalallrouters, false},
+	{IP.IsMulticast, IPv4(224, 0, 0, 0), true},
+	{IP.IsMulticast, IPv4(239, 0, 0, 0), true},
+	{IP.IsMulticast, IPv4(240, 0, 0, 0), false},
+	{IP.IsMulticast, IPv6linklocalallnodes, true},
+	{IP.IsMulticast, IP{0xff, 0x05, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, true},
+	{IP.IsMulticast, IP{0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, false},
+	{IP.IsLinkLocalMulticast, IPv4(224, 0, 0, 0), true},
+	{IP.IsLinkLocalMulticast, IPv4(239, 0, 0, 0), false},
+	{IP.IsLinkLocalMulticast, IPv6linklocalallrouters, true},
+	{IP.IsLinkLocalMulticast, IP{0xff, 0x05, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, false},
+	{IP.IsLinkLocalUnicast, IPv4(169, 254, 0, 0), true},
+	{IP.IsLinkLocalUnicast, IPv4(169, 255, 0, 0), false},
+	{IP.IsLinkLocalUnicast, IP{0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, true},
+	{IP.IsLinkLocalUnicast, IP{0xfe, 0xc0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, false},
+	{IP.IsGlobalUnicast, IPv4(240, 0, 0, 0), true},
+	{IP.IsGlobalUnicast, IPv4(232, 0, 0, 0), false},
+	{IP.IsGlobalUnicast, IPv4(169, 254, 0, 0), false},
+	{IP.IsGlobalUnicast, IP{0x20, 0x1, 0xd, 0xb8, 0, 0, 0, 0, 0, 0, 0x1, 0x23, 0, 0x12, 0, 0x1}, true},
+	{IP.IsGlobalUnicast, IP{0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, false},
+	{IP.IsGlobalUnicast, IP{0xff, 0x05, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, false},
+}
+
+func name(f interface{}) string {
+	return runtime.FuncForPC(reflect.ValueOf(f).Pointer()).Name()
+}
+
+func TestIPAddrScope(t *testing.T) {
+	for _, tt := range ipAddrScopeTests {
+		if ok := tt.scope(tt.in); ok != tt.ok {
+			t.Errorf("%s(%q) = %v, want %v", name(tt.scope), tt.in, ok, tt.ok)
+		}
+	}
+}
diff --git a/src/net/ipraw_test.go b/src/net/ipraw_test.go
new file mode 100644
index 0000000..92dc8dc
--- /dev/null
+++ b/src/net/ipraw_test.go
@@ -0,0 +1,294 @@
+// Copyright 2009 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package net
+
+import (
+	"bytes"
+	"fmt"
+	"os"
+	"reflect"
+	"runtime"
+	"testing"
+	"time"
+)
+
+type resolveIPAddrTest struct {
+	net           string
+	litAddrOrName string
+	addr          *IPAddr
+	err           error
+}
+
+var resolveIPAddrTests = []resolveIPAddrTest{
+	{"ip", "127.0.0.1", &IPAddr{IP: IPv4(127, 0, 0, 1)}, nil},
+	{"ip4", "127.0.0.1", &IPAddr{IP: IPv4(127, 0, 0, 1)}, nil},
+	{"ip4:icmp", "127.0.0.1", &IPAddr{IP: IPv4(127, 0, 0, 1)}, nil},
+
+	{"ip", "::1", &IPAddr{IP: ParseIP("::1")}, nil},
+	{"ip6", "::1", &IPAddr{IP: ParseIP("::1")}, nil},
+	{"ip6:ipv6-icmp", "::1", &IPAddr{IP: ParseIP("::1")}, nil},
+	{"ip6:IPv6-ICMP", "::1", &IPAddr{IP: ParseIP("::1")}, nil},
+
+	{"ip", "::1%en0", &IPAddr{IP: ParseIP("::1"), Zone: "en0"}, nil},
+	{"ip6", "::1%911", &IPAddr{IP: ParseIP("::1"), Zone: "911"}, nil},
+
+	{"", "127.0.0.1", &IPAddr{IP: IPv4(127, 0, 0, 1)}, nil}, // Go 1.0 behavior
+	{"", "::1", &IPAddr{IP: ParseIP("::1")}, nil},           // Go 1.0 behavior
+
+	{"l2tp", "127.0.0.1", nil, UnknownNetworkError("l2tp")},
+	{"l2tp:gre", "127.0.0.1", nil, UnknownNetworkError("l2tp:gre")},
+	{"tcp", "1.2.3.4:123", nil, UnknownNetworkError("tcp")},
+}
+
+func init() {
+	if ifi := loopbackInterface(); ifi != nil {
+		index := fmt.Sprintf("%v", ifi.Index)
+		resolveIPAddrTests = append(resolveIPAddrTests, []resolveIPAddrTest{
+			{"ip6", "fe80::1%" + ifi.Name, &IPAddr{IP: ParseIP("fe80::1"), Zone: zoneToString(ifi.Index)}, nil},
+			{"ip6", "fe80::1%" + index, &IPAddr{IP: ParseIP("fe80::1"), Zone: index}, nil},
+		}...)
+	}
+	if ips, err := LookupIP("localhost"); err == nil && len(ips) > 1 && supportsIPv4 && supportsIPv6 {
+		resolveIPAddrTests = append(resolveIPAddrTests, []resolveIPAddrTest{
+			{"ip", "localhost", &IPAddr{IP: IPv4(127, 0, 0, 1)}, nil},
+			{"ip4", "localhost", &IPAddr{IP: IPv4(127, 0, 0, 1)}, nil},
+			{"ip6", "localhost", &IPAddr{IP: IPv6loopback}, nil},
+		}...)
+	}
+}
+
+func skipRawSocketTest(t *testing.T) (skip bool, skipmsg string) {
+	skip, skipmsg, err := skipRawSocketTests()
+	if err != nil {
+		t.Fatal(err)
+	}
+	return skip, skipmsg
+}
+
+func TestResolveIPAddr(t *testing.T) {
+	switch runtime.GOOS {
+	case "nacl":
+		t.Skipf("skipping test on %q", runtime.GOOS)
+	}
+
+	for _, tt := range resolveIPAddrTests {
+		addr, err := ResolveIPAddr(tt.net, tt.litAddrOrName)
+		if err != tt.err {
+			t.Fatalf("ResolveIPAddr(%v, %v) failed: %v", tt.net, tt.litAddrOrName, err)
+		} else if !reflect.DeepEqual(addr, tt.addr) {
+			t.Fatalf("got %#v; expected %#v", addr, tt.addr)
+		}
+	}
+}
+
+var icmpEchoTests = []struct {
+	net   string
+	laddr string
+	raddr string
+}{
+	{"ip4:icmp", "0.0.0.0", "127.0.0.1"},
+	{"ip6:ipv6-icmp", "::", "::1"},
+}
+
+func TestConnICMPEcho(t *testing.T) {
+	if skip, skipmsg := skipRawSocketTest(t); skip {
+		t.Skip(skipmsg)
+	}
+
+	for i, tt := range icmpEchoTests {
+		net, _, err := parseNetwork(tt.net)
+		if err != nil {
+			t.Fatalf("parseNetwork failed: %v", err)
+		}
+		if net == "ip6" && !supportsIPv6 {
+			continue
+		}
+
+		c, err := Dial(tt.net, tt.raddr)
+		if err != nil {
+			t.Fatalf("Dial failed: %v", err)
+		}
+		c.SetDeadline(time.Now().Add(100 * time.Millisecond))
+		defer c.Close()
+
+		typ := icmpv4EchoRequest
+		if net == "ip6" {
+			typ = icmpv6EchoRequest
+		}
+		xid, xseq := os.Getpid()&0xffff, i+1
+		wb, err := (&icmpMessage{
+			Type: typ, Code: 0,
+			Body: &icmpEcho{
+				ID: xid, Seq: xseq,
+				Data: bytes.Repeat([]byte("Go Go Gadget Ping!!!"), 3),
+			},
+		}).Marshal()
+		if err != nil {
+			t.Fatalf("icmpMessage.Marshal failed: %v", err)
+		}
+		if _, err := c.Write(wb); err != nil {
+			t.Fatalf("Conn.Write failed: %v", err)
+		}
+		var m *icmpMessage
+		rb := make([]byte, 20+len(wb))
+		for {
+			if _, err := c.Read(rb); err != nil {
+				t.Fatalf("Conn.Read failed: %v", err)
+			}
+			if net == "ip4" {
+				rb = ipv4Payload(rb)
+			}
+			if m, err = parseICMPMessage(rb); err != nil {
+				t.Fatalf("parseICMPMessage failed: %v", err)
+			}
+			switch m.Type {
+			case icmpv4EchoRequest, icmpv6EchoRequest:
+				continue
+			}
+			break
+		}
+		switch p := m.Body.(type) {
+		case *icmpEcho:
+			if p.ID != xid || p.Seq != xseq {
+				t.Fatalf("got id=%v, seqnum=%v; expected id=%v, seqnum=%v", p.ID, p.Seq, xid, xseq)
+			}
+		default:
+			t.Fatalf("got type=%v, code=%v; expected type=%v, code=%v", m.Type, m.Code, typ, 0)
+		}
+	}
+}
+
+func TestPacketConnICMPEcho(t *testing.T) {
+	if skip, skipmsg := skipRawSocketTest(t); skip {
+		t.Skip(skipmsg)
+	}
+
+	for i, tt := range icmpEchoTests {
+		net, _, err := parseNetwork(tt.net)
+		if err != nil {
+			t.Fatalf("parseNetwork failed: %v", err)
+		}
+		if net == "ip6" && !supportsIPv6 {
+			continue
+		}
+
+		c, err := ListenPacket(tt.net, tt.laddr)
+		if err != nil {
+			t.Fatalf("ListenPacket failed: %v", err)
+		}
+		c.SetDeadline(time.Now().Add(100 * time.Millisecond))
+		defer c.Close()
+
+		ra, err := ResolveIPAddr(tt.net, tt.raddr)
+		if err != nil {
+			t.Fatalf("ResolveIPAddr failed: %v", err)
+		}
+		typ := icmpv4EchoRequest
+		if net == "ip6" {
+			typ = icmpv6EchoRequest
+		}
+		xid, xseq := os.Getpid()&0xffff, i+1
+		wb, err := (&icmpMessage{
+			Type: typ, Code: 0,
+			Body: &icmpEcho{
+				ID: xid, Seq: xseq,
+				Data: bytes.Repeat([]byte("Go Go Gadget Ping!!!"), 3),
+			},
+		}).Marshal()
+		if err != nil {
+			t.Fatalf("icmpMessage.Marshal failed: %v", err)
+		}
+		if _, err := c.WriteTo(wb, ra); err != nil {
+			t.Fatalf("PacketConn.WriteTo failed: %v", err)
+		}
+		var m *icmpMessage
+		rb := make([]byte, 20+len(wb))
+		for {
+			if _, _, err := c.ReadFrom(rb); err != nil {
+				t.Fatalf("PacketConn.ReadFrom failed: %v", err)
+			}
+			// See BUG section.
+			//if net == "ip4" {
+			//	rb = ipv4Payload(rb)
+			//}
+			if m, err = parseICMPMessage(rb); err != nil {
+				t.Fatalf("parseICMPMessage failed: %v", err)
+			}
+			switch m.Type {
+			case icmpv4EchoRequest, icmpv6EchoRequest:
+				continue
+			}
+			break
+		}
+		switch p := m.Body.(type) {
+		case *icmpEcho:
+			if p.ID != xid || p.Seq != xseq {
+				t.Fatalf("got id=%v, seqnum=%v; expected id=%v, seqnum=%v", p.ID, p.Seq, xid, xseq)
+			}
+		default:
+			t.Fatalf("got type=%v, code=%v; expected type=%v, code=%v", m.Type, m.Code, typ, 0)
+		}
+	}
+}
+
+func ipv4Payload(b []byte) []byte {
+	if len(b) < 20 {
+		return b
+	}
+	hdrlen := int(b[0]&0x0f) << 2
+	return b[hdrlen:]
+}
+
+var ipConnLocalNameTests = []struct {
+	net   string
+	laddr *IPAddr
+}{
+	{"ip4:icmp", &IPAddr{IP: IPv4(127, 0, 0, 1)}},
+	{"ip4:icmp", &IPAddr{}},
+	{"ip4:icmp", nil},
+}
+
+func TestIPConnLocalName(t *testing.T) {
+	switch runtime.GOOS {
+	case "nacl", "plan9", "windows":
+		t.Skipf("skipping test on %q", runtime.GOOS)
+	default:
+		if os.Getuid() != 0 {
+			t.Skip("skipping test; must be root")
+		}
+	}
+
+	for _, tt := range ipConnLocalNameTests {
+		c, err := ListenIP(tt.net, tt.laddr)
+		if err != nil {
+			t.Fatalf("ListenIP failed: %v", err)
+		}
+		defer c.Close()
+		if la := c.LocalAddr(); la == nil {
+			t.Fatal("IPConn.LocalAddr failed")
+		}
+	}
+}
+
+func TestIPConnRemoteName(t *testing.T) {
+	switch runtime.GOOS {
+	case "plan9", "windows":
+		t.Skipf("skipping test on %q", runtime.GOOS)
+	default:
+		if os.Getuid() != 0 {
+			t.Skip("skipping test; must be root")
+		}
+	}
+
+	raddr := &IPAddr{IP: IPv4(127, 0, 0, 1).To4()}
+	c, err := DialIP("ip:tcp", &IPAddr{IP: IPv4(127, 0, 0, 1)}, raddr)
+	if err != nil {
+		t.Fatalf("DialIP failed: %v", err)
+	}
+	defer c.Close()
+	if !reflect.DeepEqual(raddr, c.RemoteAddr()) {
+		t.Fatalf("got %#v, expected %#v", c.RemoteAddr(), raddr)
+	}
+}
diff --git a/src/pkg/net/iprawsock.go b/src/net/iprawsock.go
similarity index 100%
rename from src/pkg/net/iprawsock.go
rename to src/net/iprawsock.go
diff --git a/src/pkg/net/iprawsock_plan9.go b/src/net/iprawsock_plan9.go
similarity index 100%
rename from src/pkg/net/iprawsock_plan9.go
rename to src/net/iprawsock_plan9.go
diff --git a/src/net/iprawsock_posix.go b/src/net/iprawsock_posix.go
new file mode 100644
index 0000000..99b081b
--- /dev/null
+++ b/src/net/iprawsock_posix.go
@@ -0,0 +1,227 @@
+// Copyright 2010 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris windows
+
+package net
+
+import (
+	"syscall"
+	"time"
+)
+
+// BUG(mikio): On every POSIX platform, reads from the "ip4" network
+// using the ReadFrom or ReadFromIP method might not return a complete
+// IPv4 packet, including its header, even if there is space
+// available. This can occur even in cases where Read or ReadMsgIP
+// could return a complete packet. For this reason, it is recommended
+// that you do not uses these methods if it is important to receive a
+// full packet.
+//
+// The Go 1 compatibility guidelines make it impossible for us to
+// change the behavior of these methods; use Read or ReadMsgIP
+// instead.
+
+func sockaddrToIP(sa syscall.Sockaddr) Addr {
+	switch sa := sa.(type) {
+	case *syscall.SockaddrInet4:
+		return &IPAddr{IP: sa.Addr[0:]}
+	case *syscall.SockaddrInet6:
+		return &IPAddr{IP: sa.Addr[0:], Zone: zoneToString(int(sa.ZoneId))}
+	}
+	return nil
+}
+
+func (a *IPAddr) family() int {
+	if a == nil || len(a.IP) <= IPv4len {
+		return syscall.AF_INET
+	}
+	if a.IP.To4() != nil {
+		return syscall.AF_INET
+	}
+	return syscall.AF_INET6
+}
+
+func (a *IPAddr) isWildcard() bool {
+	if a == nil || a.IP == nil {
+		return true
+	}
+	return a.IP.IsUnspecified()
+}
+
+func (a *IPAddr) sockaddr(family int) (syscall.Sockaddr, error) {
+	if a == nil {
+		return nil, nil
+	}
+	return ipToSockaddr(family, a.IP, 0, a.Zone)
+}
+
+// IPConn is the implementation of the Conn and PacketConn interfaces
+// for IP network connections.
+type IPConn struct {
+	conn
+}
+
+func newIPConn(fd *netFD) *IPConn { return &IPConn{conn{fd}} }
+
+// ReadFromIP reads an IP packet from c, copying the payload into b.
+// It returns the number of bytes copied into b and the return address
+// that was on the packet.
+//
+// ReadFromIP can be made to time out and return an error with
+// Timeout() == true after a fixed time limit; see SetDeadline and
+// SetReadDeadline.
+func (c *IPConn) ReadFromIP(b []byte) (int, *IPAddr, error) {
+	if !c.ok() {
+		return 0, nil, syscall.EINVAL
+	}
+	// TODO(cw,rsc): consider using readv if we know the family
+	// type to avoid the header trim/copy
+	var addr *IPAddr
+	n, sa, err := c.fd.readFrom(b)
+	switch sa := sa.(type) {
+	case *syscall.SockaddrInet4:
+		addr = &IPAddr{IP: sa.Addr[0:]}
+		if len(b) >= IPv4len { // discard ipv4 header
+			hsize := (int(b[0]) & 0xf) * 4
+			copy(b, b[hsize:])
+			n -= hsize
+		}
+	case *syscall.SockaddrInet6:
+		addr = &IPAddr{IP: sa.Addr[0:], Zone: zoneToString(int(sa.ZoneId))}
+	}
+	return n, addr, err
+}
+
+// ReadFrom implements the PacketConn ReadFrom method.
+func (c *IPConn) ReadFrom(b []byte) (int, Addr, error) {
+	if !c.ok() {
+		return 0, nil, syscall.EINVAL
+	}
+	n, addr, err := c.ReadFromIP(b)
+	return n, addr.toAddr(), err
+}
+
+// ReadMsgIP reads a packet from c, copying the payload into b and the
+// associated out-of-band data into oob.  It returns the number of
+// bytes copied into b, the number of bytes copied into oob, the flags
+// that were set on the packet and the source address of the packet.
+func (c *IPConn) ReadMsgIP(b, oob []byte) (n, oobn, flags int, addr *IPAddr, err error) {
+	if !c.ok() {
+		return 0, 0, 0, nil, syscall.EINVAL
+	}
+	var sa syscall.Sockaddr
+	n, oobn, flags, sa, err = c.fd.readMsg(b, oob)
+	switch sa := sa.(type) {
+	case *syscall.SockaddrInet4:
+		addr = &IPAddr{IP: sa.Addr[0:]}
+	case *syscall.SockaddrInet6:
+		addr = &IPAddr{IP: sa.Addr[0:], Zone: zoneToString(int(sa.ZoneId))}
+	}
+	return
+}
+
+// WriteToIP writes an IP packet to addr via c, copying the payload
+// from b.
+//
+// WriteToIP can be made to time out and return an error with
+// Timeout() == true after a fixed time limit; see SetDeadline and
+// SetWriteDeadline.  On packet-oriented connections, write timeouts
+// are rare.
+func (c *IPConn) WriteToIP(b []byte, addr *IPAddr) (int, error) {
+	if !c.ok() {
+		return 0, syscall.EINVAL
+	}
+	if c.fd.isConnected {
+		return 0, &OpError{Op: "write", Net: c.fd.net, Addr: addr, Err: ErrWriteToConnected}
+	}
+	if addr == nil {
+		return 0, &OpError{Op: "write", Net: c.fd.net, Addr: nil, Err: errMissingAddress}
+	}
+	sa, err := addr.sockaddr(c.fd.family)
+	if err != nil {
+		return 0, &OpError{"write", c.fd.net, addr, err}
+	}
+	return c.fd.writeTo(b, sa)
+}
+
+// WriteTo implements the PacketConn WriteTo method.
+func (c *IPConn) WriteTo(b []byte, addr Addr) (int, error) {
+	if !c.ok() {
+		return 0, syscall.EINVAL
+	}
+	a, ok := addr.(*IPAddr)
+	if !ok {
+		return 0, &OpError{"write", c.fd.net, addr, syscall.EINVAL}
+	}
+	return c.WriteToIP(b, a)
+}
+
+// WriteMsgIP writes a packet to addr via c, copying the payload from
+// b and the associated out-of-band data from oob.  It returns the
+// number of payload and out-of-band bytes written.
+func (c *IPConn) WriteMsgIP(b, oob []byte, addr *IPAddr) (n, oobn int, err error) {
+	if !c.ok() {
+		return 0, 0, syscall.EINVAL
+	}
+	if c.fd.isConnected {
+		return 0, 0, &OpError{Op: "write", Net: c.fd.net, Addr: addr, Err: ErrWriteToConnected}
+	}
+	if addr == nil {
+		return 0, 0, &OpError{Op: "write", Net: c.fd.net, Addr: nil, Err: errMissingAddress}
+	}
+	sa, err := addr.sockaddr(c.fd.family)
+	if err != nil {
+		return 0, 0, &OpError{"write", c.fd.net, addr, err}
+	}
+	return c.fd.writeMsg(b, oob, sa)
+}
+
+// DialIP connects to the remote address raddr on the network protocol
+// netProto, which must be "ip", "ip4", or "ip6" followed by a colon
+// and a protocol number or name.
+func DialIP(netProto string, laddr, raddr *IPAddr) (*IPConn, error) {
+	return dialIP(netProto, laddr, raddr, noDeadline)
+}
+
+func dialIP(netProto string, laddr, raddr *IPAddr, deadline time.Time) (*IPConn, error) {
+	net, proto, err := parseNetwork(netProto)
+	if err != nil {
+		return nil, &OpError{Op: "dial", Net: netProto, Addr: raddr, Err: err}
+	}
+	switch net {
+	case "ip", "ip4", "ip6":
+	default:
+		return nil, &OpError{Op: "dial", Net: netProto, Addr: raddr, Err: UnknownNetworkError(netProto)}
+	}
+	if raddr == nil {
+		return nil, &OpError{Op: "dial", Net: netProto, Addr: nil, Err: errMissingAddress}
+	}
+	fd, err := internetSocket(net, laddr, raddr, deadline, syscall.SOCK_RAW, proto, "dial")
+	if err != nil {
+		return nil, &OpError{Op: "dial", Net: netProto, Addr: raddr, Err: err}
+	}
+	return newIPConn(fd), nil
+}
+
+// ListenIP listens for incoming IP packets addressed to the local
+// address laddr.  The returned connection's ReadFrom and WriteTo
+// methods can be used to receive and send IP packets with per-packet
+// addressing.
+func ListenIP(netProto string, laddr *IPAddr) (*IPConn, error) {
+	net, proto, err := parseNetwork(netProto)
+	if err != nil {
+		return nil, &OpError{Op: "dial", Net: netProto, Addr: laddr, Err: err}
+	}
+	switch net {
+	case "ip", "ip4", "ip6":
+	default:
+		return nil, &OpError{Op: "listen", Net: netProto, Addr: laddr, Err: UnknownNetworkError(netProto)}
+	}
+	fd, err := internetSocket(net, laddr, nil, noDeadline, syscall.SOCK_RAW, proto, "listen")
+	if err != nil {
+		return nil, &OpError{Op: "listen", Net: netProto, Addr: laddr, Err: err}
+	}
+	return newIPConn(fd), nil
+}
diff --git a/src/pkg/net/ipsock.go b/src/net/ipsock.go
similarity index 100%
rename from src/pkg/net/ipsock.go
rename to src/net/ipsock.go
diff --git a/src/pkg/net/ipsock_plan9.go b/src/net/ipsock_plan9.go
similarity index 100%
rename from src/pkg/net/ipsock_plan9.go
rename to src/net/ipsock_plan9.go
diff --git a/src/net/ipsock_posix.go b/src/net/ipsock_posix.go
new file mode 100644
index 0000000..f9ebe40
--- /dev/null
+++ b/src/net/ipsock_posix.go
@@ -0,0 +1,177 @@
+// Copyright 2009 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris windows
+
+// Internet protocol family sockets for POSIX
+
+package net
+
+import (
+	"syscall"
+	"time"
+)
+
+func probeIPv4Stack() bool {
+	s, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_STREAM, syscall.IPPROTO_TCP)
+	switch err {
+	case syscall.EAFNOSUPPORT, syscall.EPROTONOSUPPORT:
+		return false
+	case nil:
+		closesocket(s)
+	}
+	return true
+}
+
+// Should we try to use the IPv4 socket interface if we're
+// only dealing with IPv4 sockets?  As long as the host system
+// understands IPv6, it's okay to pass IPv4 addresses to the IPv6
+// interface.  That simplifies our code and is most general.
+// Unfortunately, we need to run on kernels built without IPv6
+// support too.  So probe the kernel to figure it out.
+//
+// probeIPv6Stack probes both basic IPv6 capability and IPv6 IPv4-
+// mapping capability which is controlled by IPV6_V6ONLY socket
+// option and/or kernel state "net.inet6.ip6.v6only".
+// It returns two boolean values.  If the first boolean value is
+// true, kernel supports basic IPv6 functionality.  If the second
+// boolean value is true, kernel supports IPv6 IPv4-mapping.
+func probeIPv6Stack() (supportsIPv6, supportsIPv4map bool) {
+	var probes = []struct {
+		laddr TCPAddr
+		value int
+		ok    bool
+	}{
+		// IPv6 communication capability
+		{laddr: TCPAddr{IP: ParseIP("::1")}, value: 1},
+		// IPv6 IPv4-mapped address communication capability
+		{laddr: TCPAddr{IP: IPv4(127, 0, 0, 1)}, value: 0},
+	}
+
+	for i := range probes {
+		s, err := syscall.Socket(syscall.AF_INET6, syscall.SOCK_STREAM, syscall.IPPROTO_TCP)
+		if err != nil {
+			continue
+		}
+		defer closesocket(s)
+		syscall.SetsockoptInt(s, syscall.IPPROTO_IPV6, syscall.IPV6_V6ONLY, probes[i].value)
+		sa, err := probes[i].laddr.sockaddr(syscall.AF_INET6)
+		if err != nil {
+			continue
+		}
+		if err := syscall.Bind(s, sa); err != nil {
+			continue
+		}
+		probes[i].ok = true
+	}
+
+	return probes[0].ok, probes[1].ok
+}
+
+// favoriteAddrFamily returns the appropriate address family to
+// the given net, laddr, raddr and mode.  At first it figures
+// address family out from the net.  If mode indicates "listen"
+// and laddr is a wildcard, it assumes that the user wants to
+// make a passive connection with a wildcard address family, both
+// AF_INET and AF_INET6, and a wildcard address like following:
+//
+//	1. A wild-wild listen, "tcp" + ""
+//	If the platform supports both IPv6 and IPv6 IPv4-mapping
+//	capabilities, we assume that the user want to listen on
+//	both IPv4 and IPv6 wildcard address over an AF_INET6
+//	socket with IPV6_V6ONLY=0.  Otherwise we prefer an IPv4
+//	wildcard address listen over an AF_INET socket.
+//
+//	2. A wild-ipv4wild listen, "tcp" + "0.0.0.0"
+//	Same as 1.
+//
+//	3. A wild-ipv6wild listen, "tcp" + "[::]"
+//	Almost same as 1 but we prefer an IPv6 wildcard address
+//	listen over an AF_INET6 socket with IPV6_V6ONLY=0 when
+//	the platform supports IPv6 capability but not IPv6 IPv4-
+//	mapping capability.
+//
+//	4. A ipv4-ipv4wild listen, "tcp4" + "" or "0.0.0.0"
+//	We use an IPv4 (AF_INET) wildcard address listen.
+//
+//	5. A ipv6-ipv6wild listen, "tcp6" + "" or "[::]"
+//	We use an IPv6 (AF_INET6, IPV6_V6ONLY=1) wildcard address
+//	listen.
+//
+// Otherwise guess: if the addresses are IPv4 then returns AF_INET,
+// or else returns AF_INET6.  It also returns a boolean value what
+// designates IPV6_V6ONLY option.
+//
+// Note that OpenBSD allows neither "net.inet6.ip6.v6only=1" change
+// nor IPPROTO_IPV6 level IPV6_V6ONLY socket option setting.
+func favoriteAddrFamily(net string, laddr, raddr sockaddr, mode string) (family int, ipv6only bool) {
+	switch net[len(net)-1] {
+	case '4':
+		return syscall.AF_INET, false
+	case '6':
+		return syscall.AF_INET6, true
+	}
+
+	if mode == "listen" && (laddr == nil || laddr.isWildcard()) {
+		if supportsIPv4map {
+			return syscall.AF_INET6, false
+		}
+		if laddr == nil {
+			return syscall.AF_INET, false
+		}
+		return laddr.family(), false
+	}
+
+	if (laddr == nil || laddr.family() == syscall.AF_INET) &&
+		(raddr == nil || raddr.family() == syscall.AF_INET) {
+		return syscall.AF_INET, false
+	}
+	return syscall.AF_INET6, false
+}
+
+// Internet sockets (TCP, UDP, IP)
+
+func internetSocket(net string, laddr, raddr sockaddr, deadline time.Time, sotype, proto int, mode string) (fd *netFD, err error) {
+	family, ipv6only := favoriteAddrFamily(net, laddr, raddr, mode)
+	return socket(net, family, sotype, proto, ipv6only, laddr, raddr, deadline)
+}
+
+func ipToSockaddr(family int, ip IP, port int, zone string) (syscall.Sockaddr, error) {
+	switch family {
+	case syscall.AF_INET:
+		if len(ip) == 0 {
+			ip = IPv4zero
+		}
+		if ip = ip.To4(); ip == nil {
+			return nil, InvalidAddrError("non-IPv4 address")
+		}
+		sa := new(syscall.SockaddrInet4)
+		for i := 0; i < IPv4len; i++ {
+			sa.Addr[i] = ip[i]
+		}
+		sa.Port = port
+		return sa, nil
+	case syscall.AF_INET6:
+		if len(ip) == 0 {
+			ip = IPv6zero
+		}
+		// IPv4 callers use 0.0.0.0 to mean "announce on any available address".
+		// In IPv6 mode, Linux treats that as meaning "announce on 0.0.0.0",
+		// which it refuses to do.  Rewrite to the IPv6 unspecified address.
+		if ip.Equal(IPv4zero) {
+			ip = IPv6zero
+		}
+		if ip = ip.To16(); ip == nil {
+			return nil, InvalidAddrError("non-IPv6 address")
+		}
+		sa := new(syscall.SockaddrInet6)
+		for i := 0; i < IPv6len; i++ {
+			sa.Addr[i] = ip[i]
+		}
+		sa.Port = port
+		sa.ZoneId = uint32(zoneToInt(zone))
+		return sa, nil
+	}
+	return nil, InvalidAddrError("unexpected socket family")
+}
diff --git a/src/pkg/net/ipsock_test.go b/src/net/ipsock_test.go
similarity index 100%
rename from src/pkg/net/ipsock_test.go
rename to src/net/ipsock_test.go
diff --git a/src/net/lookup.go b/src/net/lookup.go
new file mode 100644
index 0000000..aeffe6c
--- /dev/null
+++ b/src/net/lookup.go
@@ -0,0 +1,142 @@
+// Copyright 2012 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package net
+
+import "time"
+
+// protocols contains minimal mappings between internet protocol
+// names and numbers for platforms that don't have a complete list of
+// protocol numbers.
+//
+// See http://www.iana.org/assignments/protocol-numbers
+var protocols = map[string]int{
+	"icmp": 1, "ICMP": 1,
+	"igmp": 2, "IGMP": 2,
+	"tcp": 6, "TCP": 6,
+	"udp": 17, "UDP": 17,
+	"ipv6-icmp": 58, "IPV6-ICMP": 58, "IPv6-ICMP": 58,
+}
+
+// LookupHost looks up the given host using the local resolver.
+// It returns an array of that host's addresses.
+func LookupHost(host string) (addrs []string, err error) {
+	return lookupHost(host)
+}
+
+// LookupIP looks up host using the local resolver.
+// It returns an array of that host's IPv4 and IPv6 addresses.
+func LookupIP(host string) (addrs []IP, err error) {
+	return lookupIPMerge(host)
+}
+
+var lookupGroup singleflight
+
+// lookupIPMerge wraps lookupIP, but makes sure that for any given
+// host, only one lookup is in-flight at a time. The returned memory
+// is always owned by the caller.
+func lookupIPMerge(host string) (addrs []IP, err error) {
+	addrsi, err, shared := lookupGroup.Do(host, func() (interface{}, error) {
+		return lookupIP(host)
+	})
+	return lookupIPReturn(addrsi, err, shared)
+}
+
+// lookupIPReturn turns the return values from singleflight.Do into
+// the return values from LookupIP.
+func lookupIPReturn(addrsi interface{}, err error, shared bool) ([]IP, error) {
+	if err != nil {
+		return nil, err
+	}
+	addrs := addrsi.([]IP)
+	if shared {
+		clone := make([]IP, len(addrs))
+		copy(clone, addrs)
+		addrs = clone
+	}
+	return addrs, nil
+}
+
+// lookupIPDeadline looks up a hostname with a deadline.
+func lookupIPDeadline(host string, deadline time.Time) (addrs []IP, err error) {
+	if deadline.IsZero() {
+		return lookupIPMerge(host)
+	}
+
+	// We could push the deadline down into the name resolution
+	// functions.  However, the most commonly used implementation
+	// calls getaddrinfo, which has no timeout.
+
+	timeout := deadline.Sub(time.Now())
+	if timeout <= 0 {
+		return nil, errTimeout
+	}
+	t := time.NewTimer(timeout)
+	defer t.Stop()
+
+	ch := lookupGroup.DoChan(host, func() (interface{}, error) {
+		return lookupIP(host)
+	})
+
+	select {
+	case <-t.C:
+		// The DNS lookup timed out for some reason.  Force
+		// future requests to start the DNS lookup again
+		// rather than waiting for the current lookup to
+		// complete.  See issue 8602.
+		lookupGroup.Forget(host)
+
+		return nil, errTimeout
+
+	case r := <-ch:
+		return lookupIPReturn(r.v, r.err, r.shared)
+	}
+}
+
+// LookupPort looks up the port for the given network and service.
+func LookupPort(network, service string) (port int, err error) {
+	return lookupPort(network, service)
+}
+
+// LookupCNAME returns the canonical DNS host for the given name.
+// Callers that do not care about the canonical name can call
+// LookupHost or LookupIP directly; both take care of resolving
+// the canonical name as part of the lookup.
+func LookupCNAME(name string) (cname string, err error) {
+	return lookupCNAME(name)
+}
+
+// LookupSRV tries to resolve an SRV query of the given service,
+// protocol, and domain name.  The proto is "tcp" or "udp".
+// The returned records are sorted by priority and randomized
+// by weight within a priority.
+//
+// LookupSRV constructs the DNS name to look up following RFC 2782.
+// That is, it looks up _service._proto.name.  To accommodate services
+// publishing SRV records under non-standard names, if both service
+// and proto are empty strings, LookupSRV looks up name directly.
+func LookupSRV(service, proto, name string) (cname string, addrs []*SRV, err error) {
+	return lookupSRV(service, proto, name)
+}
+
+// LookupMX returns the DNS MX records for the given domain name sorted by preference.
+func LookupMX(name string) (mx []*MX, err error) {
+	return lookupMX(name)
+}
+
+// LookupNS returns the DNS NS records for the given domain name.
+func LookupNS(name string) (ns []*NS, err error) {
+	return lookupNS(name)
+}
+
+// LookupTXT returns the DNS TXT records for the given domain name.
+func LookupTXT(name string) (txt []string, err error) {
+	return lookupTXT(name)
+}
+
+// LookupAddr performs a reverse lookup for the given address, returning a list
+// of names mapping to that address.
+func LookupAddr(addr string) (name []string, err error) {
+	return lookupAddr(addr)
+}
diff --git a/src/pkg/net/lookup_plan9.go b/src/net/lookup_plan9.go
similarity index 100%
rename from src/pkg/net/lookup_plan9.go
rename to src/net/lookup_plan9.go
diff --git a/src/net/lookup_stub.go b/src/net/lookup_stub.go
new file mode 100644
index 0000000..502aafb
--- /dev/null
+++ b/src/net/lookup_stub.go
@@ -0,0 +1,49 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build nacl
+
+package net
+
+import "syscall"
+
+func lookupProtocol(name string) (proto int, err error) {
+	return 0, syscall.ENOPROTOOPT
+}
+
+func lookupHost(host string) (addrs []string, err error) {
+	return nil, syscall.ENOPROTOOPT
+}
+
+func lookupIP(host string) (ips []IP, err error) {
+	return nil, syscall.ENOPROTOOPT
+}
+
+func lookupPort(network, service string) (port int, err error) {
+	return 0, syscall.ENOPROTOOPT
+}
+
+func lookupCNAME(name string) (cname string, err error) {
+	return "", syscall.ENOPROTOOPT
+}
+
+func lookupSRV(service, proto, name string) (cname string, srvs []*SRV, err error) {
+	return "", nil, syscall.ENOPROTOOPT
+}
+
+func lookupMX(name string) (mxs []*MX, err error) {
+	return nil, syscall.ENOPROTOOPT
+}
+
+func lookupNS(name string) (nss []*NS, err error) {
+	return nil, syscall.ENOPROTOOPT
+}
+
+func lookupTXT(name string) (txts []string, err error) {
+	return nil, syscall.ENOPROTOOPT
+}
+
+func lookupAddr(addr string) (ptrs []string, err error) {
+	return nil, syscall.ENOPROTOOPT
+}
diff --git a/src/net/lookup_test.go b/src/net/lookup_test.go
new file mode 100644
index 0000000..057e132
--- /dev/null
+++ b/src/net/lookup_test.go
@@ -0,0 +1,231 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// TODO It would be nice to use a mock DNS server, to eliminate
+// external dependencies.
+
+package net
+
+import (
+	"flag"
+	"strings"
+	"testing"
+)
+
+var testExternal = flag.Bool("external", true, "allow use of external networks during long test")
+
+var lookupGoogleSRVTests = []struct {
+	service, proto, name string
+	cname, target        string
+}{
+	{
+		"xmpp-server", "tcp", "google.com",
+		".google.com", ".google.com",
+	},
+	{
+		"", "", "_xmpp-server._tcp.google.com", // non-standard back door
+		".google.com", ".google.com",
+	},
+}
+
+func TestLookupGoogleSRV(t *testing.T) {
+	if testing.Short() || !*testExternal {
+		t.Skip("skipping test to avoid external network")
+	}
+
+	for _, tt := range lookupGoogleSRVTests {
+		cname, srvs, err := LookupSRV(tt.service, tt.proto, tt.name)
+		if err != nil {
+			t.Fatal(err)
+		}
+		if len(srvs) == 0 {
+			t.Error("got no record")
+		}
+		if !strings.Contains(cname, tt.cname) {
+			t.Errorf("got %q; want %q", cname, tt.cname)
+		}
+		for _, srv := range srvs {
+			if !strings.Contains(srv.Target, tt.target) {
+				t.Errorf("got %v; want a record containing %q", srv, tt.target)
+			}
+		}
+	}
+}
+
+func TestLookupGmailMX(t *testing.T) {
+	if testing.Short() || !*testExternal {
+		t.Skip("skipping test to avoid external network")
+	}
+
+	mxs, err := LookupMX("gmail.com")
+	if err != nil {
+		t.Fatal(err)
+	}
+	if len(mxs) == 0 {
+		t.Error("got no record")
+	}
+	for _, mx := range mxs {
+		if !strings.Contains(mx.Host, ".google.com") {
+			t.Errorf("got %v; want a record containing .google.com.", mx)
+		}
+	}
+}
+
+func TestLookupGmailNS(t *testing.T) {
+	if testing.Short() || !*testExternal {
+		t.Skip("skipping test to avoid external network")
+	}
+
+	nss, err := LookupNS("gmail.com")
+	if err != nil {
+		t.Fatal(err)
+	}
+	if len(nss) == 0 {
+		t.Error("got no record")
+	}
+	for _, ns := range nss {
+		if !strings.Contains(ns.Host, ".google.com") {
+			t.Errorf("got %v; want a record containing .google.com.", ns)
+		}
+	}
+}
+
+func TestLookupGmailTXT(t *testing.T) {
+	if testing.Short() || !*testExternal {
+		t.Skip("skipping test to avoid external network")
+	}
+
+	txts, err := LookupTXT("gmail.com")
+	if err != nil {
+		t.Fatal(err)
+	}
+	if len(txts) == 0 {
+		t.Error("got no record")
+	}
+	for _, txt := range txts {
+		if !strings.Contains(txt, "spf") {
+			t.Errorf("got %q; want a spf record", txt)
+		}
+	}
+}
+
+var lookupGooglePublicDNSAddrs = []struct {
+	addr string
+	name string
+}{
+	{"8.8.8.8", ".google.com."},
+	{"8.8.4.4", ".google.com."},
+	{"2001:4860:4860::8888", ".google.com."},
+	{"2001:4860:4860::8844", ".google.com."},
+}
+
+func TestLookupGooglePublicDNSAddr(t *testing.T) {
+	if testing.Short() || !*testExternal {
+		t.Skip("skipping test to avoid external network")
+	}
+
+	for _, tt := range lookupGooglePublicDNSAddrs {
+		names, err := LookupAddr(tt.addr)
+		if err != nil {
+			t.Fatal(err)
+		}
+		if len(names) == 0 {
+			t.Error("got no record")
+		}
+		for _, name := range names {
+			if !strings.HasSuffix(name, tt.name) {
+				t.Errorf("got %q; want a record containing %q", name, tt.name)
+			}
+		}
+	}
+}
+
+func TestLookupIANACNAME(t *testing.T) {
+	if testing.Short() || !*testExternal {
+		t.Skip("skipping test to avoid external network")
+	}
+
+	cname, err := LookupCNAME("www.iana.org")
+	if err != nil {
+		t.Fatal(err)
+	}
+	if !strings.HasSuffix(cname, ".icann.org.") {
+		t.Errorf("got %q; want a record containing .icann.org.", cname)
+	}
+}
+
+func TestLookupGoogleHost(t *testing.T) {
+	if testing.Short() || !*testExternal {
+		t.Skip("skipping test to avoid external network")
+	}
+
+	addrs, err := LookupHost("google.com")
+	if err != nil {
+		t.Fatal(err)
+	}
+	if len(addrs) == 0 {
+		t.Error("got no record")
+	}
+	for _, addr := range addrs {
+		if ParseIP(addr) == nil {
+			t.Errorf("got %q; want a literal ip address", addr)
+		}
+	}
+}
+
+func TestLookupGoogleIP(t *testing.T) {
+	if testing.Short() || !*testExternal {
+		t.Skip("skipping test to avoid external network")
+	}
+
+	ips, err := LookupIP("google.com")
+	if err != nil {
+		t.Fatal(err)
+	}
+	if len(ips) == 0 {
+		t.Error("got no record")
+	}
+	for _, ip := range ips {
+		if ip.To4() == nil && ip.To16() == nil {
+			t.Errorf("got %v; want an ip address", ip)
+		}
+	}
+}
+
+var revAddrTests = []struct {
+	Addr      string
+	Reverse   string
+	ErrPrefix string
+}{
+	{"1.2.3.4", "4.3.2.1.in-addr.arpa.", ""},
+	{"245.110.36.114", "114.36.110.245.in-addr.arpa.", ""},
+	{"::ffff:12.34.56.78", "78.56.34.12.in-addr.arpa.", ""},
+	{"::1", "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa.", ""},
+	{"1::", "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.1.0.0.0.ip6.arpa.", ""},
+	{"1234:567::89a:bcde", "e.d.c.b.a.9.8.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.7.6.5.0.4.3.2.1.ip6.arpa.", ""},
+	{"1234:567:fefe:bcbc:adad:9e4a:89a:bcde", "e.d.c.b.a.9.8.0.a.4.e.9.d.a.d.a.c.b.c.b.e.f.e.f.7.6.5.0.4.3.2.1.ip6.arpa.", ""},
+	{"1.2.3", "", "unrecognized address"},
+	{"1.2.3.4.5", "", "unrecognized address"},
+	{"1234:567:bcbca::89a:bcde", "", "unrecognized address"},
+	{"1234:567::bcbc:adad::89a:bcde", "", "unrecognized address"},
+}
+
+func TestReverseAddress(t *testing.T) {
+	for i, tt := range revAddrTests {
+		a, err := reverseaddr(tt.Addr)
+		if len(tt.ErrPrefix) > 0 && err == nil {
+			t.Errorf("#%d: expected %q, got <nil> (error)", i, tt.ErrPrefix)
+			continue
+		}
+		if len(tt.ErrPrefix) == 0 && err != nil {
+			t.Errorf("#%d: expected <nil>, got %q (error)", i, err)
+		}
+		if err != nil && err.(*DNSError).Err != tt.ErrPrefix {
+			t.Errorf("#%d: expected %q, got %q (mismatched error)", i, tt.ErrPrefix, err.(*DNSError).Err)
+		}
+		if a != tt.Reverse {
+			t.Errorf("#%d: expected %q, got %q (reverse address)", i, tt.Reverse, a)
+		}
+	}
+}
diff --git a/src/net/lookup_unix.go b/src/net/lookup_unix.go
new file mode 100644
index 0000000..a545784
--- /dev/null
+++ b/src/net/lookup_unix.go
@@ -0,0 +1,168 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin dragonfly freebsd linux netbsd openbsd solaris
+
+package net
+
+import (
+	"errors"
+	"sync"
+)
+
+var onceReadProtocols sync.Once
+
+// readProtocols loads contents of /etc/protocols into protocols map
+// for quick access.
+func readProtocols() {
+	if file, err := open("/etc/protocols"); err == nil {
+		for line, ok := file.readLine(); ok; line, ok = file.readLine() {
+			// tcp    6   TCP    # transmission control protocol
+			if i := byteIndex(line, '#'); i >= 0 {
+				line = line[0:i]
+			}
+			f := getFields(line)
+			if len(f) < 2 {
+				continue
+			}
+			if proto, _, ok := dtoi(f[1], 0); ok {
+				if _, ok := protocols[f[0]]; !ok {
+					protocols[f[0]] = proto
+				}
+				for _, alias := range f[2:] {
+					if _, ok := protocols[alias]; !ok {
+						protocols[alias] = proto
+					}
+				}
+			}
+		}
+		file.close()
+	}
+}
+
+// lookupProtocol looks up IP protocol name in /etc/protocols and
+// returns correspondent protocol number.
+func lookupProtocol(name string) (proto int, err error) {
+	onceReadProtocols.Do(readProtocols)
+	proto, found := protocols[name]
+	if !found {
+		return 0, errors.New("unknown IP protocol specified: " + name)
+	}
+	return
+}
+
+func lookupHost(host string) (addrs []string, err error) {
+	addrs, err, ok := cgoLookupHost(host)
+	if !ok {
+		addrs, err = goLookupHost(host)
+	}
+	return
+}
+
+func lookupIP(host string) (addrs []IP, err error) {
+	addrs, err, ok := cgoLookupIP(host)
+	if !ok {
+		addrs, err = goLookupIP(host)
+	}
+	return
+}
+
+func lookupPort(network, service string) (port int, err error) {
+	port, err, ok := cgoLookupPort(network, service)
+	if !ok {
+		port, err = goLookupPort(network, service)
+	}
+	return
+}
+
+func lookupCNAME(name string) (cname string, err error) {
+	cname, err, ok := cgoLookupCNAME(name)
+	if !ok {
+		cname, err = goLookupCNAME(name)
+	}
+	return
+}
+
+func lookupSRV(service, proto, name string) (cname string, addrs []*SRV, err error) {
+	var target string
+	if service == "" && proto == "" {
+		target = name
+	} else {
+		target = "_" + service + "._" + proto + "." + name
+	}
+	var records []dnsRR
+	cname, records, err = lookup(target, dnsTypeSRV)
+	if err != nil {
+		return
+	}
+	addrs = make([]*SRV, len(records))
+	for i, rr := range records {
+		r := rr.(*dnsRR_SRV)
+		addrs[i] = &SRV{r.Target, r.Port, r.Priority, r.Weight}
+	}
+	byPriorityWeight(addrs).sort()
+	return
+}
+
+func lookupMX(name string) (mx []*MX, err error) {
+	_, records, err := lookup(name, dnsTypeMX)
+	if err != nil {
+		return
+	}
+	mx = make([]*MX, len(records))
+	for i, rr := range records {
+		r := rr.(*dnsRR_MX)
+		mx[i] = &MX{r.Mx, r.Pref}
+	}
+	byPref(mx).sort()
+	return
+}
+
+func lookupNS(name string) (ns []*NS, err error) {
+	_, records, err := lookup(name, dnsTypeNS)
+	if err != nil {
+		return
+	}
+	ns = make([]*NS, len(records))
+	for i, r := range records {
+		r := r.(*dnsRR_NS)
+		ns[i] = &NS{r.Ns}
+	}
+	return
+}
+
+func lookupTXT(name string) (txt []string, err error) {
+	_, records, err := lookup(name, dnsTypeTXT)
+	if err != nil {
+		return
+	}
+	txt = make([]string, len(records))
+	for i, r := range records {
+		txt[i] = r.(*dnsRR_TXT).Txt
+	}
+	return
+}
+
+func lookupAddr(addr string) (name []string, err error) {
+	name = lookupStaticAddr(addr)
+	if len(name) > 0 {
+		return
+	}
+	var arpa string
+	arpa, err = reverseaddr(addr)
+	if err != nil {
+		return
+	}
+	var records []dnsRR
+	_, records, err = lookup(arpa, dnsTypePTR)
+	if err != nil {
+		return
+	}
+	name = make([]string, len(records))
+	for i := range records {
+		r := records[i].(*dnsRR_PTR)
+		name[i] = r.Ptr
+	}
+	return
+}
diff --git a/src/net/lookup_windows.go b/src/net/lookup_windows.go
new file mode 100644
index 0000000..6a925b0
--- /dev/null
+++ b/src/net/lookup_windows.go
@@ -0,0 +1,381 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package net
+
+import (
+	"os"
+	"runtime"
+	"syscall"
+	"unsafe"
+)
+
+var (
+	lookupPort = oldLookupPort
+	lookupIP   = oldLookupIP
+)
+
+func getprotobyname(name string) (proto int, err error) {
+	p, err := syscall.GetProtoByName(name)
+	if err != nil {
+		return 0, os.NewSyscallError("GetProtoByName", err)
+	}
+	return int(p.Proto), nil
+}
+
+// lookupProtocol looks up IP protocol name and returns correspondent protocol number.
+func lookupProtocol(name string) (proto int, err error) {
+	// GetProtoByName return value is stored in thread local storage.
+	// Start new os thread before the call to prevent races.
+	type result struct {
+		proto int
+		err   error
+	}
+	ch := make(chan result)
+	go func() {
+		acquireThread()
+		defer releaseThread()
+		runtime.LockOSThread()
+		defer runtime.UnlockOSThread()
+		proto, err := getprotobyname(name)
+		ch <- result{proto: proto, err: err}
+	}()
+	r := <-ch
+	if r.err != nil {
+		if proto, ok := protocols[name]; ok {
+			return proto, nil
+		}
+	}
+	return r.proto, r.err
+}
+
+func lookupHost(name string) (addrs []string, err error) {
+	ips, err := LookupIP(name)
+	if err != nil {
+		return
+	}
+	addrs = make([]string, 0, len(ips))
+	for _, ip := range ips {
+		addrs = append(addrs, ip.String())
+	}
+	return
+}
+
+func gethostbyname(name string) (addrs []IP, err error) {
+	// caller already acquired thread
+	h, err := syscall.GetHostByName(name)
+	if err != nil {
+		return nil, os.NewSyscallError("GetHostByName", err)
+	}
+	switch h.AddrType {
+	case syscall.AF_INET:
+		i := 0
+		addrs = make([]IP, 100) // plenty of room to grow
+		for p := (*[100](*[4]byte))(unsafe.Pointer(h.AddrList)); i < cap(addrs) && p[i] != nil; i++ {
+			addrs[i] = IPv4(p[i][0], p[i][1], p[i][2], p[i][3])
+		}
+		addrs = addrs[0:i]
+	default: // TODO(vcc): Implement non IPv4 address lookups.
+		return nil, os.NewSyscallError("LookupIP", syscall.EWINDOWS)
+	}
+	return addrs, nil
+}
+
+func oldLookupIP(name string) (addrs []IP, err error) {
+	// GetHostByName return value is stored in thread local storage.
+	// Start new os thread before the call to prevent races.
+	type result struct {
+		addrs []IP
+		err   error
+	}
+	ch := make(chan result)
+	go func() {
+		acquireThread()
+		defer releaseThread()
+		runtime.LockOSThread()
+		defer runtime.UnlockOSThread()
+		addrs, err := gethostbyname(name)
+		ch <- result{addrs: addrs, err: err}
+	}()
+	r := <-ch
+	return r.addrs, r.err
+}
+
+func newLookupIP(name string) (addrs []IP, err error) {
+	acquireThread()
+	defer releaseThread()
+	hints := syscall.AddrinfoW{
+		Family:   syscall.AF_UNSPEC,
+		Socktype: syscall.SOCK_STREAM,
+		Protocol: syscall.IPPROTO_IP,
+	}
+	var result *syscall.AddrinfoW
+	e := syscall.GetAddrInfoW(syscall.StringToUTF16Ptr(name), nil, &hints, &result)
+	if e != nil {
+		return nil, os.NewSyscallError("GetAddrInfoW", e)
+	}
+	defer syscall.FreeAddrInfoW(result)
+	addrs = make([]IP, 0, 5)
+	for ; result != nil; result = result.Next {
+		addr := unsafe.Pointer(result.Addr)
+		switch result.Family {
+		case syscall.AF_INET:
+			a := (*syscall.RawSockaddrInet4)(addr).Addr
+			addrs = append(addrs, IPv4(a[0], a[1], a[2], a[3]))
+		case syscall.AF_INET6:
+			a := (*syscall.RawSockaddrInet6)(addr).Addr
+			addrs = append(addrs, IP{a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]})
+		default:
+			return nil, os.NewSyscallError("LookupIP", syscall.EWINDOWS)
+		}
+	}
+	return addrs, nil
+}
+
+func getservbyname(network, service string) (port int, err error) {
+	acquireThread()
+	defer releaseThread()
+	switch network {
+	case "tcp4", "tcp6":
+		network = "tcp"
+	case "udp4", "udp6":
+		network = "udp"
+	}
+	s, err := syscall.GetServByName(service, network)
+	if err != nil {
+		return 0, os.NewSyscallError("GetServByName", err)
+	}
+	return int(syscall.Ntohs(s.Port)), nil
+}
+
+func oldLookupPort(network, service string) (port int, err error) {
+	// GetServByName return value is stored in thread local storage.
+	// Start new os thread before the call to prevent races.
+	type result struct {
+		port int
+		err  error
+	}
+	ch := make(chan result)
+	go func() {
+		acquireThread()
+		defer releaseThread()
+		runtime.LockOSThread()
+		defer runtime.UnlockOSThread()
+		port, err := getservbyname(network, service)
+		ch <- result{port: port, err: err}
+	}()
+	r := <-ch
+	return r.port, r.err
+}
+
+func newLookupPort(network, service string) (port int, err error) {
+	acquireThread()
+	defer releaseThread()
+	var stype int32
+	switch network {
+	case "tcp4", "tcp6":
+		stype = syscall.SOCK_STREAM
+	case "udp4", "udp6":
+		stype = syscall.SOCK_DGRAM
+	}
+	hints := syscall.AddrinfoW{
+		Family:   syscall.AF_UNSPEC,
+		Socktype: stype,
+		Protocol: syscall.IPPROTO_IP,
+	}
+	var result *syscall.AddrinfoW
+	e := syscall.GetAddrInfoW(nil, syscall.StringToUTF16Ptr(service), &hints, &result)
+	if e != nil {
+		return 0, os.NewSyscallError("GetAddrInfoW", e)
+	}
+	defer syscall.FreeAddrInfoW(result)
+	if result == nil {
+		return 0, os.NewSyscallError("LookupPort", syscall.EINVAL)
+	}
+	addr := unsafe.Pointer(result.Addr)
+	switch result.Family {
+	case syscall.AF_INET:
+		a := (*syscall.RawSockaddrInet4)(addr)
+		return int(syscall.Ntohs(a.Port)), nil
+	case syscall.AF_INET6:
+		a := (*syscall.RawSockaddrInet6)(addr)
+		return int(syscall.Ntohs(a.Port)), nil
+	}
+	return 0, os.NewSyscallError("LookupPort", syscall.EINVAL)
+}
+
+func lookupCNAME(name string) (cname string, err error) {
+	acquireThread()
+	defer releaseThread()
+	var r *syscall.DNSRecord
+	e := syscall.DnsQuery(name, syscall.DNS_TYPE_CNAME, 0, nil, &r, nil)
+	// windows returns DNS_INFO_NO_RECORDS if there are no CNAME-s
+	if errno, ok := e.(syscall.Errno); ok && errno == syscall.DNS_INFO_NO_RECORDS {
+		// if there are no aliases, the canonical name is the input name
+		if name == "" || name[len(name)-1] != '.' {
+			return name + ".", nil
+		}
+		return name, nil
+	}
+	if e != nil {
+		return "", os.NewSyscallError("LookupCNAME", e)
+	}
+	defer syscall.DnsRecordListFree(r, 1)
+
+	resolved := resolveCNAME(syscall.StringToUTF16Ptr(name), r)
+	cname = syscall.UTF16ToString((*[256]uint16)(unsafe.Pointer(resolved))[:]) + "."
+	return
+}
+
+func lookupSRV(service, proto, name string) (cname string, addrs []*SRV, err error) {
+	acquireThread()
+	defer releaseThread()
+	var target string
+	if service == "" && proto == "" {
+		target = name
+	} else {
+		target = "_" + service + "._" + proto + "." + name
+	}
+	var r *syscall.DNSRecord
+	e := syscall.DnsQuery(target, syscall.DNS_TYPE_SRV, 0, nil, &r, nil)
+	if e != nil {
+		return "", nil, os.NewSyscallError("LookupSRV", e)
+	}
+	defer syscall.DnsRecordListFree(r, 1)
+
+	addrs = make([]*SRV, 0, 10)
+	for _, p := range validRecs(r, syscall.DNS_TYPE_SRV, target) {
+		v := (*syscall.DNSSRVData)(unsafe.Pointer(&p.Data[0]))
+		addrs = append(addrs, &SRV{syscall.UTF16ToString((*[256]uint16)(unsafe.Pointer(v.Target))[:]), v.Port, v.Priority, v.Weight})
+	}
+	byPriorityWeight(addrs).sort()
+	return name, addrs, nil
+}
+
+func lookupMX(name string) (mx []*MX, err error) {
+	acquireThread()
+	defer releaseThread()
+	var r *syscall.DNSRecord
+	e := syscall.DnsQuery(name, syscall.DNS_TYPE_MX, 0, nil, &r, nil)
+	if e != nil {
+		return nil, os.NewSyscallError("LookupMX", e)
+	}
+	defer syscall.DnsRecordListFree(r, 1)
+
+	mx = make([]*MX, 0, 10)
+	for _, p := range validRecs(r, syscall.DNS_TYPE_MX, name) {
+		v := (*syscall.DNSMXData)(unsafe.Pointer(&p.Data[0]))
+		mx = append(mx, &MX{syscall.UTF16ToString((*[256]uint16)(unsafe.Pointer(v.NameExchange))[:]) + ".", v.Preference})
+	}
+	byPref(mx).sort()
+	return mx, nil
+}
+
+func lookupNS(name string) (ns []*NS, err error) {
+	acquireThread()
+	defer releaseThread()
+	var r *syscall.DNSRecord
+	e := syscall.DnsQuery(name, syscall.DNS_TYPE_NS, 0, nil, &r, nil)
+	if e != nil {
+		return nil, os.NewSyscallError("LookupNS", e)
+	}
+	defer syscall.DnsRecordListFree(r, 1)
+
+	ns = make([]*NS, 0, 10)
+	for _, p := range validRecs(r, syscall.DNS_TYPE_NS, name) {
+		v := (*syscall.DNSPTRData)(unsafe.Pointer(&p.Data[0]))
+		ns = append(ns, &NS{syscall.UTF16ToString((*[256]uint16)(unsafe.Pointer(v.Host))[:]) + "."})
+	}
+	return ns, nil
+}
+
+func lookupTXT(name string) (txt []string, err error) {
+	acquireThread()
+	defer releaseThread()
+	var r *syscall.DNSRecord
+	e := syscall.DnsQuery(name, syscall.DNS_TYPE_TEXT, 0, nil, &r, nil)
+	if e != nil {
+		return nil, os.NewSyscallError("LookupTXT", e)
+	}
+	defer syscall.DnsRecordListFree(r, 1)
+
+	txt = make([]string, 0, 10)
+	for _, p := range validRecs(r, syscall.DNS_TYPE_TEXT, name) {
+		d := (*syscall.DNSTXTData)(unsafe.Pointer(&p.Data[0]))
+		for _, v := range (*[1 << 10]*uint16)(unsafe.Pointer(&(d.StringArray[0])))[:d.StringCount] {
+			s := syscall.UTF16ToString((*[1 << 20]uint16)(unsafe.Pointer(v))[:])
+			txt = append(txt, s)
+		}
+	}
+	return
+}
+
+func lookupAddr(addr string) (name []string, err error) {
+	acquireThread()
+	defer releaseThread()
+	arpa, err := reverseaddr(addr)
+	if err != nil {
+		return nil, err
+	}
+	var r *syscall.DNSRecord
+	e := syscall.DnsQuery(arpa, syscall.DNS_TYPE_PTR, 0, nil, &r, nil)
+	if e != nil {
+		return nil, os.NewSyscallError("LookupAddr", e)
+	}
+	defer syscall.DnsRecordListFree(r, 1)
+
+	name = make([]string, 0, 10)
+	for _, p := range validRecs(r, syscall.DNS_TYPE_PTR, arpa) {
+		v := (*syscall.DNSPTRData)(unsafe.Pointer(&p.Data[0]))
+		name = append(name, syscall.UTF16ToString((*[256]uint16)(unsafe.Pointer(v.Host))[:]))
+	}
+	return name, nil
+}
+
+const dnsSectionMask = 0x0003
+
+// returns only results applicable to name and resolves CNAME entries
+func validRecs(r *syscall.DNSRecord, dnstype uint16, name string) []*syscall.DNSRecord {
+	cname := syscall.StringToUTF16Ptr(name)
+	if dnstype != syscall.DNS_TYPE_CNAME {
+		cname = resolveCNAME(cname, r)
+	}
+	rec := make([]*syscall.DNSRecord, 0, 10)
+	for p := r; p != nil; p = p.Next {
+		if p.Dw&dnsSectionMask != syscall.DnsSectionAnswer {
+			continue
+		}
+		if p.Type != dnstype {
+			continue
+		}
+		if !syscall.DnsNameCompare(cname, p.Name) {
+			continue
+		}
+		rec = append(rec, p)
+	}
+	return rec
+}
+
+// returns the last CNAME in chain
+func resolveCNAME(name *uint16, r *syscall.DNSRecord) *uint16 {
+	// limit cname resolving to 10 in case of a infinite CNAME loop
+Cname:
+	for cnameloop := 0; cnameloop < 10; cnameloop++ {
+		for p := r; p != nil; p = p.Next {
+			if p.Dw&dnsSectionMask != syscall.DnsSectionAnswer {
+				continue
+			}
+			if p.Type != syscall.DNS_TYPE_CNAME {
+				continue
+			}
+			if !syscall.DnsNameCompare(name, p.Name) {
+				continue
+			}
+			name = (*syscall.DNSPTRData)(unsafe.Pointer(&r.Data[0])).Host
+			continue Cname
+		}
+		break
+	}
+	return name
+}
diff --git a/src/net/lookup_windows_test.go b/src/net/lookup_windows_test.go
new file mode 100644
index 0000000..7495b5b
--- /dev/null
+++ b/src/net/lookup_windows_test.go
@@ -0,0 +1,243 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package net
+
+import (
+	"bytes"
+	"encoding/json"
+	"errors"
+	"os/exec"
+	"reflect"
+	"regexp"
+	"sort"
+	"strconv"
+	"strings"
+	"testing"
+)
+
+var nslookupTestServers = []string{"mail.golang.com", "gmail.com"}
+
+func toJson(v interface{}) string {
+	data, _ := json.Marshal(v)
+	return string(data)
+}
+
+func TestLookupMX(t *testing.T) {
+	if testing.Short() || !*testExternal {
+		t.Skip("skipping test to avoid external network")
+	}
+	for _, server := range nslookupTestServers {
+		mx, err := LookupMX(server)
+		if err != nil {
+			t.Errorf("failed %s: %s", server, err)
+			continue
+		}
+		if len(mx) == 0 {
+			t.Errorf("no results")
+			continue
+		}
+		expected, err := nslookupMX(server)
+		if err != nil {
+			t.Logf("skipping failed nslookup %s test: %s", server, err)
+		}
+		sort.Sort(byPrefAndHost(expected))
+		sort.Sort(byPrefAndHost(mx))
+		if !reflect.DeepEqual(expected, mx) {
+			t.Errorf("different results %s:\texp:%v\tgot:%v", server, toJson(expected), toJson(mx))
+		}
+	}
+}
+
+func TestLookupCNAME(t *testing.T) {
+	if testing.Short() || !*testExternal {
+		t.Skip("skipping test to avoid external network")
+	}
+	for _, server := range nslookupTestServers {
+		cname, err := LookupCNAME(server)
+		if err != nil {
+			t.Errorf("failed %s: %s", server, err)
+			continue
+		}
+		if cname == "" {
+			t.Errorf("no result %s", server)
+		}
+		expected, err := nslookupCNAME(server)
+		if err != nil {
+			t.Logf("skipping failed nslookup %s test: %s", server, err)
+			continue
+		}
+		if expected != cname {
+			t.Errorf("different results %s:\texp:%v\tgot:%v", server, expected, cname)
+		}
+	}
+}
+
+func TestLookupNS(t *testing.T) {
+	if testing.Short() || !*testExternal {
+		t.Skip("skipping test to avoid external network")
+	}
+	for _, server := range nslookupTestServers {
+		ns, err := LookupNS(server)
+		if err != nil {
+			t.Errorf("failed %s: %s", server, err)
+			continue
+		}
+		if len(ns) == 0 {
+			t.Errorf("no results")
+			continue
+		}
+		expected, err := nslookupNS(server)
+		if err != nil {
+			t.Logf("skipping failed nslookup %s test: %s", server, err)
+			continue
+		}
+		sort.Sort(byHost(expected))
+		sort.Sort(byHost(ns))
+		if !reflect.DeepEqual(expected, ns) {
+			t.Errorf("different results %s:\texp:%v\tgot:%v", toJson(server), toJson(expected), ns)
+		}
+	}
+}
+
+func TestLookupTXT(t *testing.T) {
+	if testing.Short() || !*testExternal {
+		t.Skip("skipping test to avoid external network")
+	}
+	for _, server := range nslookupTestServers {
+		txt, err := LookupTXT(server)
+		if err != nil {
+			t.Errorf("failed %s: %s", server, err)
+			continue
+		}
+		if len(txt) == 0 {
+			t.Errorf("no results")
+			continue
+		}
+		expected, err := nslookupTXT(server)
+		if err != nil {
+			t.Logf("skipping failed nslookup %s test: %s", server, err)
+			continue
+		}
+		sort.Strings(expected)
+		sort.Strings(txt)
+		if !reflect.DeepEqual(expected, txt) {
+			t.Errorf("different results %s:\texp:%v\tgot:%v", server, toJson(expected), toJson(txt))
+		}
+	}
+}
+
+type byPrefAndHost []*MX
+
+func (s byPrefAndHost) Len() int { return len(s) }
+func (s byPrefAndHost) Less(i, j int) bool {
+	if s[i].Pref != s[j].Pref {
+		return s[i].Pref < s[j].Pref
+	}
+	return s[i].Host < s[j].Host
+}
+func (s byPrefAndHost) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
+
+type byHost []*NS
+
+func (s byHost) Len() int           { return len(s) }
+func (s byHost) Less(i, j int) bool { return s[i].Host < s[j].Host }
+func (s byHost) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
+
+func fqdn(s string) string {
+	if len(s) == 0 || s[len(s)-1] != '.' {
+		return s + "."
+	}
+	return s
+}
+
+func nslookup(qtype, name string) (string, error) {
+	var out bytes.Buffer
+	var err bytes.Buffer
+	cmd := exec.Command("nslookup", "-querytype="+qtype, name)
+	cmd.Stdout = &out
+	cmd.Stderr = &err
+	if err := cmd.Run(); err != nil {
+		return "", err
+	}
+	r := strings.Replace(out.String(), "\r\n", "\n", -1)
+	// nslookup stderr output contains also debug information such as
+	// "Non-authoritative answer" and it doesn't return the correct errcode
+	if strings.Contains(err.String(), "can't find") {
+		return r, errors.New(err.String())
+	}
+	return r, nil
+}
+
+func nslookupMX(name string) (mx []*MX, err error) {
+	var r string
+	if r, err = nslookup("mx", name); err != nil {
+		return
+	}
+	mx = make([]*MX, 0, 10)
+	// linux nslookup syntax
+	// golang.org      mail exchanger = 2 alt1.aspmx.l.google.com.
+	rx := regexp.MustCompile(`(?m)^([a-z0-9.\-]+)\s+mail exchanger\s*=\s*([0-9]+)\s*([a-z0-9.\-]+)$`)
+	for _, ans := range rx.FindAllStringSubmatch(r, -1) {
+		pref, _ := strconv.Atoi(ans[2])
+		mx = append(mx, &MX{fqdn(ans[3]), uint16(pref)})
+	}
+	// windows nslookup syntax
+	// gmail.com       MX preference = 30, mail exchanger = alt3.gmail-smtp-in.l.google.com
+	rx = regexp.MustCompile(`(?m)^([a-z0-9.\-]+)\s+MX preference\s*=\s*([0-9]+)\s*,\s*mail exchanger\s*=\s*([a-z0-9.\-]+)$`)
+	for _, ans := range rx.FindAllStringSubmatch(r, -1) {
+		pref, _ := strconv.Atoi(ans[2])
+		mx = append(mx, &MX{fqdn(ans[3]), uint16(pref)})
+	}
+	return
+}
+
+func nslookupNS(name string) (ns []*NS, err error) {
+	var r string
+	if r, err = nslookup("ns", name); err != nil {
+		return
+	}
+	ns = make([]*NS, 0, 10)
+	// golang.org      nameserver = ns1.google.com.
+	rx := regexp.MustCompile(`(?m)^([a-z0-9.\-]+)\s+nameserver\s*=\s*([a-z0-9.\-]+)$`)
+	for _, ans := range rx.FindAllStringSubmatch(r, -1) {
+		ns = append(ns, &NS{fqdn(ans[2])})
+	}
+	return
+}
+
+func nslookupCNAME(name string) (cname string, err error) {
+	var r string
+	if r, err = nslookup("cname", name); err != nil {
+		return
+	}
+	// mail.golang.com canonical name = golang.org.
+	rx := regexp.MustCompile(`(?m)^([a-z0-9.\-]+)\s+canonical name\s*=\s*([a-z0-9.\-]+)$`)
+	// assumes the last CNAME is the correct one
+	last := name
+	for _, ans := range rx.FindAllStringSubmatch(r, -1) {
+		last = ans[2]
+	}
+	return fqdn(last), nil
+}
+
+func nslookupTXT(name string) (txt []string, err error) {
+	var r string
+	if r, err = nslookup("txt", name); err != nil {
+		return
+	}
+	txt = make([]string, 0, 10)
+	// linux
+	// golang.org      text = "v=spf1 redirect=_spf.google.com"
+
+	// windows
+	// golang.org      text =
+	//
+	//    "v=spf1 redirect=_spf.google.com"
+	rx := regexp.MustCompile(`(?m)^([a-z0-9.\-]+)\s+text\s*=\s*"(.*)"$`)
+	for _, ans := range rx.FindAllStringSubmatch(r, -1) {
+		txt = append(txt, ans[2])
+	}
+	return
+}
diff --git a/src/pkg/net/mac.go b/src/net/mac.go
similarity index 100%
rename from src/pkg/net/mac.go
rename to src/net/mac.go
diff --git a/src/pkg/net/mac_test.go b/src/net/mac_test.go
similarity index 100%
rename from src/pkg/net/mac_test.go
rename to src/net/mac_test.go
diff --git a/src/net/mail/message.go b/src/net/mail/message.go
new file mode 100644
index 0000000..19aa888
--- /dev/null
+++ b/src/net/mail/message.go
@@ -0,0 +1,556 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+/*
+Package mail implements parsing of mail messages.
+
+For the most part, this package follows the syntax as specified by RFC 5322.
+Notable divergences:
+	* Obsolete address formats are not parsed, including addresses with
+	  embedded route information.
+	* Group addresses are not parsed.
+	* The full range of spacing (the CFWS syntax element) is not supported,
+	  such as breaking addresses across lines.
+*/
+package mail
+
+import (
+	"bufio"
+	"bytes"
+	"encoding/base64"
+	"errors"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"log"
+	"net/textproto"
+	"strconv"
+	"strings"
+	"time"
+	"unicode"
+)
+
+var debug = debugT(false)
+
+type debugT bool
+
+func (d debugT) Printf(format string, args ...interface{}) {
+	if d {
+		log.Printf(format, args...)
+	}
+}
+
+// A Message represents a parsed mail message.
+type Message struct {
+	Header Header
+	Body   io.Reader
+}
+
+// ReadMessage reads a message from r.
+// The headers are parsed, and the body of the message will be available
+// for reading from r.
+func ReadMessage(r io.Reader) (msg *Message, err error) {
+	tp := textproto.NewReader(bufio.NewReader(r))
+
+	hdr, err := tp.ReadMIMEHeader()
+	if err != nil {
+		return nil, err
+	}
+
+	return &Message{
+		Header: Header(hdr),
+		Body:   tp.R,
+	}, nil
+}
+
+// Layouts suitable for passing to time.Parse.
+// These are tried in order.
+var dateLayouts []string
+
+func init() {
+	// Generate layouts based on RFC 5322, section 3.3.
+
+	dows := [...]string{"", "Mon, "}   // day-of-week
+	days := [...]string{"2", "02"}     // day = 1*2DIGIT
+	years := [...]string{"2006", "06"} // year = 4*DIGIT / 2*DIGIT
+	seconds := [...]string{":05", ""}  // second
+	// "-0700 (MST)" is not in RFC 5322, but is common.
+	zones := [...]string{"-0700", "MST", "-0700 (MST)"} // zone = (("+" / "-") 4DIGIT) / "GMT" / ...
+
+	for _, dow := range dows {
+		for _, day := range days {
+			for _, year := range years {
+				for _, second := range seconds {
+					for _, zone := range zones {
+						s := dow + day + " Jan " + year + " 15:04" + second + " " + zone
+						dateLayouts = append(dateLayouts, s)
+					}
+				}
+			}
+		}
+	}
+}
+
+func parseDate(date string) (time.Time, error) {
+	for _, layout := range dateLayouts {
+		t, err := time.Parse(layout, date)
+		if err == nil {
+			return t, nil
+		}
+	}
+	return time.Time{}, errors.New("mail: header could not be parsed")
+}
+
+// A Header represents the key-value pairs in a mail message header.
+type Header map[string][]string
+
+// Get gets the first value associated with the given key.
+// If there are no values associated with the key, Get returns "".
+func (h Header) Get(key string) string {
+	return textproto.MIMEHeader(h).Get(key)
+}
+
+var ErrHeaderNotPresent = errors.New("mail: header not in message")
+
+// Date parses the Date header field.
+func (h Header) Date() (time.Time, error) {
+	hdr := h.Get("Date")
+	if hdr == "" {
+		return time.Time{}, ErrHeaderNotPresent
+	}
+	return parseDate(hdr)
+}
+
+// AddressList parses the named header field as a list of addresses.
+func (h Header) AddressList(key string) ([]*Address, error) {
+	hdr := h.Get(key)
+	if hdr == "" {
+		return nil, ErrHeaderNotPresent
+	}
+	return ParseAddressList(hdr)
+}
+
+// Address represents a single mail address.
+// An address such as "Barry Gibbs <bg at example.com>" is represented
+// as Address{Name: "Barry Gibbs", Address: "bg at example.com"}.
+type Address struct {
+	Name    string // Proper name; may be empty.
+	Address string // user at domain
+}
+
+// Parses a single RFC 5322 address, e.g. "Barry Gibbs <bg at example.com>"
+func ParseAddress(address string) (*Address, error) {
+	return newAddrParser(address).parseAddress()
+}
+
+// ParseAddressList parses the given string as a list of addresses.
+func ParseAddressList(list string) ([]*Address, error) {
+	return newAddrParser(list).parseAddressList()
+}
+
+// String formats the address as a valid RFC 5322 address.
+// If the address's name contains non-ASCII characters
+// the name will be rendered according to RFC 2047.
+func (a *Address) String() string {
+	s := "<" + a.Address + ">"
+	if a.Name == "" {
+		return s
+	}
+	// If every character is printable ASCII, quoting is simple.
+	allPrintable := true
+	for i := 0; i < len(a.Name); i++ {
+		// isWSP here should actually be isFWS,
+		// but we don't support folding yet.
+		if !isVchar(a.Name[i]) && !isWSP(a.Name[i]) {
+			allPrintable = false
+			break
+		}
+	}
+	if allPrintable {
+		b := bytes.NewBufferString(`"`)
+		for i := 0; i < len(a.Name); i++ {
+			if !isQtext(a.Name[i]) && !isWSP(a.Name[i]) {
+				b.WriteByte('\\')
+			}
+			b.WriteByte(a.Name[i])
+		}
+		b.WriteString(`" `)
+		b.WriteString(s)
+		return b.String()
+	}
+
+	// UTF-8 "Q" encoding
+	b := bytes.NewBufferString("=?utf-8?q?")
+	for i := 0; i < len(a.Name); i++ {
+		switch c := a.Name[i]; {
+		case c == ' ':
+			b.WriteByte('_')
+		case isVchar(c) && c != '=' && c != '?' && c != '_':
+			b.WriteByte(c)
+		default:
+			fmt.Fprintf(b, "=%02X", c)
+		}
+	}
+	b.WriteString("?= ")
+	b.WriteString(s)
+	return b.String()
+}
+
+type addrParser []byte
+
+func newAddrParser(s string) *addrParser {
+	p := addrParser(s)
+	return &p
+}
+
+func (p *addrParser) parseAddressList() ([]*Address, error) {
+	var list []*Address
+	for {
+		p.skipSpace()
+		addr, err := p.parseAddress()
+		if err != nil {
+			return nil, err
+		}
+		list = append(list, addr)
+
+		p.skipSpace()
+		if p.empty() {
+			break
+		}
+		if !p.consume(',') {
+			return nil, errors.New("mail: expected comma")
+		}
+	}
+	return list, nil
+}
+
+// parseAddress parses a single RFC 5322 address at the start of p.
+func (p *addrParser) parseAddress() (addr *Address, err error) {
+	debug.Printf("parseAddress: %q", *p)
+	p.skipSpace()
+	if p.empty() {
+		return nil, errors.New("mail: no address")
+	}
+
+	// address = name-addr / addr-spec
+	// TODO(dsymonds): Support parsing group address.
+
+	// addr-spec has a more restricted grammar than name-addr,
+	// so try parsing it first, and fallback to name-addr.
+	// TODO(dsymonds): Is this really correct?
+	spec, err := p.consumeAddrSpec()
+	if err == nil {
+		return &Address{
+			Address: spec,
+		}, err
+	}
+	debug.Printf("parseAddress: not an addr-spec: %v", err)
+	debug.Printf("parseAddress: state is now %q", *p)
+
+	// display-name
+	var displayName string
+	if p.peek() != '<' {
+		displayName, err = p.consumePhrase()
+		if err != nil {
+			return nil, err
+		}
+	}
+	debug.Printf("parseAddress: displayName=%q", displayName)
+
+	// angle-addr = "<" addr-spec ">"
+	p.skipSpace()
+	if !p.consume('<') {
+		return nil, errors.New("mail: no angle-addr")
+	}
+	spec, err = p.consumeAddrSpec()
+	if err != nil {
+		return nil, err
+	}
+	if !p.consume('>') {
+		return nil, errors.New("mail: unclosed angle-addr")
+	}
+	debug.Printf("parseAddress: spec=%q", spec)
+
+	return &Address{
+		Name:    displayName,
+		Address: spec,
+	}, nil
+}
+
+// consumeAddrSpec parses a single RFC 5322 addr-spec at the start of p.
+func (p *addrParser) consumeAddrSpec() (spec string, err error) {
+	debug.Printf("consumeAddrSpec: %q", *p)
+
+	orig := *p
+	defer func() {
+		if err != nil {
+			*p = orig
+		}
+	}()
+
+	// local-part = dot-atom / quoted-string
+	var localPart string
+	p.skipSpace()
+	if p.empty() {
+		return "", errors.New("mail: no addr-spec")
+	}
+	if p.peek() == '"' {
+		// quoted-string
+		debug.Printf("consumeAddrSpec: parsing quoted-string")
+		localPart, err = p.consumeQuotedString()
+	} else {
+		// dot-atom
+		debug.Printf("consumeAddrSpec: parsing dot-atom")
+		localPart, err = p.consumeAtom(true)
+	}
+	if err != nil {
+		debug.Printf("consumeAddrSpec: failed: %v", err)
+		return "", err
+	}
+
+	if !p.consume('@') {
+		return "", errors.New("mail: missing @ in addr-spec")
+	}
+
+	// domain = dot-atom / domain-literal
+	var domain string
+	p.skipSpace()
+	if p.empty() {
+		return "", errors.New("mail: no domain in addr-spec")
+	}
+	// TODO(dsymonds): Handle domain-literal
+	domain, err = p.consumeAtom(true)
+	if err != nil {
+		return "", err
+	}
+
+	return localPart + "@" + domain, nil
+}
+
+// consumePhrase parses the RFC 5322 phrase at the start of p.
+func (p *addrParser) consumePhrase() (phrase string, err error) {
+	debug.Printf("consumePhrase: [%s]", *p)
+	// phrase = 1*word
+	var words []string
+	for {
+		// word = atom / quoted-string
+		var word string
+		p.skipSpace()
+		if p.empty() {
+			return "", errors.New("mail: missing phrase")
+		}
+		if p.peek() == '"' {
+			// quoted-string
+			word, err = p.consumeQuotedString()
+		} else {
+			// atom
+			// We actually parse dot-atom here to be more permissive
+			// than what RFC 5322 specifies.
+			word, err = p.consumeAtom(true)
+		}
+
+		// RFC 2047 encoded-word starts with =?, ends with ?=, and has two other ?s.
+		if err == nil && strings.HasPrefix(word, "=?") && strings.HasSuffix(word, "?=") && strings.Count(word, "?") == 4 {
+			word, err = decodeRFC2047Word(word)
+		}
+
+		if err != nil {
+			break
+		}
+		debug.Printf("consumePhrase: consumed %q", word)
+		words = append(words, word)
+	}
+	// Ignore any error if we got at least one word.
+	if err != nil && len(words) == 0 {
+		debug.Printf("consumePhrase: hit err: %v", err)
+		return "", fmt.Errorf("mail: missing word in phrase: %v", err)
+	}
+	phrase = strings.Join(words, " ")
+	return phrase, nil
+}
+
+// consumeQuotedString parses the quoted string at the start of p.
+func (p *addrParser) consumeQuotedString() (qs string, err error) {
+	// Assume first byte is '"'.
+	i := 1
+	qsb := make([]byte, 0, 10)
+Loop:
+	for {
+		if i >= p.len() {
+			return "", errors.New("mail: unclosed quoted-string")
+		}
+		switch c := (*p)[i]; {
+		case c == '"':
+			break Loop
+		case c == '\\':
+			if i+1 == p.len() {
+				return "", errors.New("mail: unclosed quoted-string")
+			}
+			qsb = append(qsb, (*p)[i+1])
+			i += 2
+		case isQtext(c), c == ' ' || c == '\t':
+			// qtext (printable US-ASCII excluding " and \), or
+			// FWS (almost; we're ignoring CRLF)
+			qsb = append(qsb, c)
+			i++
+		default:
+			return "", fmt.Errorf("mail: bad character in quoted-string: %q", c)
+		}
+	}
+	*p = (*p)[i+1:]
+	return string(qsb), nil
+}
+
+// consumeAtom parses an RFC 5322 atom at the start of p.
+// If dot is true, consumeAtom parses an RFC 5322 dot-atom instead.
+func (p *addrParser) consumeAtom(dot bool) (atom string, err error) {
+	if !isAtext(p.peek(), false) {
+		return "", errors.New("mail: invalid string")
+	}
+	i := 1
+	for ; i < p.len() && isAtext((*p)[i], dot); i++ {
+	}
+	atom, *p = string((*p)[:i]), (*p)[i:]
+	return atom, nil
+}
+
+func (p *addrParser) consume(c byte) bool {
+	if p.empty() || p.peek() != c {
+		return false
+	}
+	*p = (*p)[1:]
+	return true
+}
+
+// skipSpace skips the leading space and tab characters.
+func (p *addrParser) skipSpace() {
+	*p = bytes.TrimLeft(*p, " \t")
+}
+
+func (p *addrParser) peek() byte {
+	return (*p)[0]
+}
+
+func (p *addrParser) empty() bool {
+	return p.len() == 0
+}
+
+func (p *addrParser) len() int {
+	return len(*p)
+}
+
+func decodeRFC2047Word(s string) (string, error) {
+	fields := strings.Split(s, "?")
+	if len(fields) != 5 || fields[0] != "=" || fields[4] != "=" {
+		return "", errors.New("address not RFC 2047 encoded")
+	}
+	charset, enc := strings.ToLower(fields[1]), strings.ToLower(fields[2])
+	if charset != "us-ascii" && charset != "iso-8859-1" && charset != "utf-8" {
+		return "", fmt.Errorf("charset not supported: %q", charset)
+	}
+
+	in := bytes.NewBufferString(fields[3])
+	var r io.Reader
+	switch enc {
+	case "b":
+		r = base64.NewDecoder(base64.StdEncoding, in)
+	case "q":
+		r = qDecoder{r: in}
+	default:
+		return "", fmt.Errorf("RFC 2047 encoding not supported: %q", enc)
+	}
+
+	dec, err := ioutil.ReadAll(r)
+	if err != nil {
+		return "", err
+	}
+
+	switch charset {
+	case "us-ascii":
+		b := new(bytes.Buffer)
+		for _, c := range dec {
+			if c >= 0x80 {
+				b.WriteRune(unicode.ReplacementChar)
+			} else {
+				b.WriteRune(rune(c))
+			}
+		}
+		return b.String(), nil
+	case "iso-8859-1":
+		b := new(bytes.Buffer)
+		for _, c := range dec {
+			b.WriteRune(rune(c))
+		}
+		return b.String(), nil
+	case "utf-8":
+		return string(dec), nil
+	}
+	panic("unreachable")
+}
+
+type qDecoder struct {
+	r       io.Reader
+	scratch [2]byte
+}
+
+func (qd qDecoder) Read(p []byte) (n int, err error) {
+	// This method writes at most one byte into p.
+	if len(p) == 0 {
+		return 0, nil
+	}
+	if _, err := qd.r.Read(qd.scratch[:1]); err != nil {
+		return 0, err
+	}
+	switch c := qd.scratch[0]; {
+	case c == '=':
+		if _, err := io.ReadFull(qd.r, qd.scratch[:2]); err != nil {
+			return 0, err
+		}
+		x, err := strconv.ParseInt(string(qd.scratch[:2]), 16, 64)
+		if err != nil {
+			return 0, fmt.Errorf("mail: invalid RFC 2047 encoding: %q", qd.scratch[:2])
+		}
+		p[0] = byte(x)
+	case c == '_':
+		p[0] = ' '
+	default:
+		p[0] = c
+	}
+	return 1, nil
+}
+
+var atextChars = []byte("ABCDEFGHIJKLMNOPQRSTUVWXYZ" +
+	"abcdefghijklmnopqrstuvwxyz" +
+	"0123456789" +
+	"!#$%&'*+-/=?^_`{|}~")
+
+// isAtext returns true if c is an RFC 5322 atext character.
+// If dot is true, period is included.
+func isAtext(c byte, dot bool) bool {
+	if dot && c == '.' {
+		return true
+	}
+	return bytes.IndexByte(atextChars, c) >= 0
+}
+
+// isQtext returns true if c is an RFC 5322 qtext character.
+func isQtext(c byte) bool {
+	// Printable US-ASCII, excluding backslash or quote.
+	if c == '\\' || c == '"' {
+		return false
+	}
+	return '!' <= c && c <= '~'
+}
+
+// isVchar returns true if c is an RFC 5322 VCHAR character.
+func isVchar(c byte) bool {
+	// Visible (printing) characters.
+	return '!' <= c && c <= '~'
+}
+
+// isWSP returns true if c is a WSP (white space).
+// WSP is a space or horizontal tab (RFC5234 Appendix B).
+func isWSP(c byte) bool {
+	return c == ' ' || c == '\t'
+}
diff --git a/src/net/mail/message_test.go b/src/net/mail/message_test.go
new file mode 100644
index 0000000..6ba48be
--- /dev/null
+++ b/src/net/mail/message_test.go
@@ -0,0 +1,314 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package mail
+
+import (
+	"bytes"
+	"io/ioutil"
+	"reflect"
+	"strings"
+	"testing"
+	"time"
+)
+
+var parseTests = []struct {
+	in     string
+	header Header
+	body   string
+}{
+	{
+		// RFC 5322, Appendix A.1.1
+		in: `From: John Doe <jdoe at machine.example>
+To: Mary Smith <mary at example.net>
+Subject: Saying Hello
+Date: Fri, 21 Nov 1997 09:55:06 -0600
+Message-ID: <1234 at local.machine.example>
+
+This is a message just to say hello.
+So, "Hello".
+`,
+		header: Header{
+			"From":       []string{"John Doe <jdoe at machine.example>"},
+			"To":         []string{"Mary Smith <mary at example.net>"},
+			"Subject":    []string{"Saying Hello"},
+			"Date":       []string{"Fri, 21 Nov 1997 09:55:06 -0600"},
+			"Message-Id": []string{"<1234 at local.machine.example>"},
+		},
+		body: "This is a message just to say hello.\nSo, \"Hello\".\n",
+	},
+}
+
+func TestParsing(t *testing.T) {
+	for i, test := range parseTests {
+		msg, err := ReadMessage(bytes.NewBuffer([]byte(test.in)))
+		if err != nil {
+			t.Errorf("test #%d: Failed parsing message: %v", i, err)
+			continue
+		}
+		if !headerEq(msg.Header, test.header) {
+			t.Errorf("test #%d: Incorrectly parsed message header.\nGot:\n%+v\nWant:\n%+v",
+				i, msg.Header, test.header)
+		}
+		body, err := ioutil.ReadAll(msg.Body)
+		if err != nil {
+			t.Errorf("test #%d: Failed reading body: %v", i, err)
+			continue
+		}
+		bodyStr := string(body)
+		if bodyStr != test.body {
+			t.Errorf("test #%d: Incorrectly parsed message body.\nGot:\n%+v\nWant:\n%+v",
+				i, bodyStr, test.body)
+		}
+	}
+}
+
+func headerEq(a, b Header) bool {
+	if len(a) != len(b) {
+		return false
+	}
+	for k, as := range a {
+		bs, ok := b[k]
+		if !ok {
+			return false
+		}
+		if !reflect.DeepEqual(as, bs) {
+			return false
+		}
+	}
+	return true
+}
+
+func TestDateParsing(t *testing.T) {
+	tests := []struct {
+		dateStr string
+		exp     time.Time
+	}{
+		// RFC 5322, Appendix A.1.1
+		{
+			"Fri, 21 Nov 1997 09:55:06 -0600",
+			time.Date(1997, 11, 21, 9, 55, 6, 0, time.FixedZone("", -6*60*60)),
+		},
+		// RFC5322, Appendix A.6.2
+		// Obsolete date.
+		{
+			"21 Nov 97 09:55:06 GMT",
+			time.Date(1997, 11, 21, 9, 55, 6, 0, time.FixedZone("GMT", 0)),
+		},
+		// Commonly found format not specified by RFC 5322.
+		{
+			"Fri, 21 Nov 1997 09:55:06 -0600 (MDT)",
+			time.Date(1997, 11, 21, 9, 55, 6, 0, time.FixedZone("", -6*60*60)),
+		},
+	}
+	for _, test := range tests {
+		hdr := Header{
+			"Date": []string{test.dateStr},
+		}
+		date, err := hdr.Date()
+		if err != nil {
+			t.Errorf("Failed parsing %q: %v", test.dateStr, err)
+			continue
+		}
+		if !date.Equal(test.exp) {
+			t.Errorf("Parse of %q: got %+v, want %+v", test.dateStr, date, test.exp)
+		}
+	}
+}
+
+func TestAddressParsingError(t *testing.T) {
+	const txt = "=?iso-8859-2?Q?Bogl=E1rka_Tak=E1cs?= <unknown at gmail.com>"
+	_, err := ParseAddress(txt)
+	if err == nil || !strings.Contains(err.Error(), "charset not supported") {
+		t.Errorf(`mail.ParseAddress(%q) err: %q, want ".*charset not supported.*"`, txt, err)
+	}
+}
+
+func TestAddressParsing(t *testing.T) {
+	tests := []struct {
+		addrsStr string
+		exp      []*Address
+	}{
+		// Bare address
+		{
+			`jdoe at machine.example`,
+			[]*Address{{
+				Address: "jdoe at machine.example",
+			}},
+		},
+		// RFC 5322, Appendix A.1.1
+		{
+			`John Doe <jdoe at machine.example>`,
+			[]*Address{{
+				Name:    "John Doe",
+				Address: "jdoe at machine.example",
+			}},
+		},
+		// RFC 5322, Appendix A.1.2
+		{
+			`"Joe Q. Public" <john.q.public at example.com>`,
+			[]*Address{{
+				Name:    "Joe Q. Public",
+				Address: "john.q.public at example.com",
+			}},
+		},
+		{
+			`Mary Smith <mary at x.test>, jdoe at example.org, Who? <one at y.test>`,
+			[]*Address{
+				{
+					Name:    "Mary Smith",
+					Address: "mary at x.test",
+				},
+				{
+					Address: "jdoe at example.org",
+				},
+				{
+					Name:    "Who?",
+					Address: "one at y.test",
+				},
+			},
+		},
+		{
+			`<boss at nil.test>, "Giant; \"Big\" Box" <sysservices at example.net>`,
+			[]*Address{
+				{
+					Address: "boss at nil.test",
+				},
+				{
+					Name:    `Giant; "Big" Box`,
+					Address: "sysservices at example.net",
+				},
+			},
+		},
+		// RFC 5322, Appendix A.1.3
+		// TODO(dsymonds): Group addresses.
+
+		// RFC 2047 "Q"-encoded ISO-8859-1 address.
+		{
+			`=?iso-8859-1?q?J=F6rg_Doe?= <joerg at example.com>`,
+			[]*Address{
+				{
+					Name:    `Jörg Doe`,
+					Address: "joerg at example.com",
+				},
+			},
+		},
+		// RFC 2047 "Q"-encoded US-ASCII address. Dumb but legal.
+		{
+			`=?us-ascii?q?J=6Frg_Doe?= <joerg at example.com>`,
+			[]*Address{
+				{
+					Name:    `Jorg Doe`,
+					Address: "joerg at example.com",
+				},
+			},
+		},
+		// RFC 2047 "Q"-encoded UTF-8 address.
+		{
+			`=?utf-8?q?J=C3=B6rg_Doe?= <joerg at example.com>`,
+			[]*Address{
+				{
+					Name:    `Jörg Doe`,
+					Address: "joerg at example.com",
+				},
+			},
+		},
+		// RFC 2047, Section 8.
+		{
+			`=?ISO-8859-1?Q?Andr=E9?= Pirard <PIRARD at vm1.ulg.ac.be>`,
+			[]*Address{
+				{
+					Name:    `André Pirard`,
+					Address: "PIRARD at vm1.ulg.ac.be",
+				},
+			},
+		},
+		// Custom example of RFC 2047 "B"-encoded ISO-8859-1 address.
+		{
+			`=?ISO-8859-1?B?SvZyZw==?= <joerg at example.com>`,
+			[]*Address{
+				{
+					Name:    `Jörg`,
+					Address: "joerg at example.com",
+				},
+			},
+		},
+		// Custom example of RFC 2047 "B"-encoded UTF-8 address.
+		{
+			`=?UTF-8?B?SsO2cmc=?= <joerg at example.com>`,
+			[]*Address{
+				{
+					Name:    `Jörg`,
+					Address: "joerg at example.com",
+				},
+			},
+		},
+		// Custom example with "." in name. For issue 4938
+		{
+			`Asem H. <noreply at example.com>`,
+			[]*Address{
+				{
+					Name:    `Asem H.`,
+					Address: "noreply at example.com",
+				},
+			},
+		},
+	}
+	for _, test := range tests {
+		if len(test.exp) == 1 {
+			addr, err := ParseAddress(test.addrsStr)
+			if err != nil {
+				t.Errorf("Failed parsing (single) %q: %v", test.addrsStr, err)
+				continue
+			}
+			if !reflect.DeepEqual([]*Address{addr}, test.exp) {
+				t.Errorf("Parse (single) of %q: got %+v, want %+v", test.addrsStr, addr, test.exp)
+			}
+		}
+
+		addrs, err := ParseAddressList(test.addrsStr)
+		if err != nil {
+			t.Errorf("Failed parsing (list) %q: %v", test.addrsStr, err)
+			continue
+		}
+		if !reflect.DeepEqual(addrs, test.exp) {
+			t.Errorf("Parse (list) of %q: got %+v, want %+v", test.addrsStr, addrs, test.exp)
+		}
+	}
+}
+
+func TestAddressFormatting(t *testing.T) {
+	tests := []struct {
+		addr *Address
+		exp  string
+	}{
+		{
+			&Address{Address: "bob at example.com"},
+			"<bob at example.com>",
+		},
+		{
+			&Address{Name: "Bob", Address: "bob at example.com"},
+			`"Bob" <bob at example.com>`,
+		},
+		{
+			// note the ö (o with an umlaut)
+			&Address{Name: "Böb", Address: "bob at example.com"},
+			`=?utf-8?q?B=C3=B6b?= <bob at example.com>`,
+		},
+		{
+			&Address{Name: "Bob Jane", Address: "bob at example.com"},
+			`"Bob Jane" <bob at example.com>`,
+		},
+		{
+			&Address{Name: "Böb Jacöb", Address: "bob at example.com"},
+			`=?utf-8?q?B=C3=B6b_Jac=C3=B6b?= <bob at example.com>`,
+		},
+	}
+	for _, test := range tests {
+		s := test.addr.String()
+		if s != test.exp {
+			t.Errorf("Address%+v.String() = %v, want %v", *test.addr, s, test.exp)
+		}
+	}
+}
diff --git a/src/pkg/net/mockicmp_test.go b/src/net/mockicmp_test.go
similarity index 100%
rename from src/pkg/net/mockicmp_test.go
rename to src/net/mockicmp_test.go
diff --git a/src/pkg/net/mockserver_test.go b/src/net/mockserver_test.go
similarity index 100%
rename from src/pkg/net/mockserver_test.go
rename to src/net/mockserver_test.go
diff --git a/src/net/multicast_test.go b/src/net/multicast_test.go
new file mode 100644
index 0000000..5f253f4
--- /dev/null
+++ b/src/net/multicast_test.go
@@ -0,0 +1,188 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package net
+
+import (
+	"fmt"
+	"os"
+	"runtime"
+	"testing"
+)
+
+var ipv4MulticastListenerTests = []struct {
+	net   string
+	gaddr *UDPAddr // see RFC 4727
+}{
+	{"udp", &UDPAddr{IP: IPv4(224, 0, 0, 254), Port: 12345}},
+
+	{"udp4", &UDPAddr{IP: IPv4(224, 0, 0, 254), Port: 12345}},
+}
+
+// TestIPv4MulticastListener tests both single and double listen to a
+// test listener with same address family, same group address and same
+// port.
+func TestIPv4MulticastListener(t *testing.T) {
+	switch runtime.GOOS {
+	case "android", "nacl", "plan9":
+		t.Skipf("skipping test on %q", runtime.GOOS)
+	case "solaris":
+		t.Skipf("skipping test on solaris, see issue 7399")
+	}
+
+	closer := func(cs []*UDPConn) {
+		for _, c := range cs {
+			if c != nil {
+				c.Close()
+			}
+		}
+	}
+
+	for _, ifi := range []*Interface{loopbackInterface(), nil} {
+		// Note that multicast interface assignment by system
+		// is not recommended because it usually relies on
+		// routing stuff for finding out an appropriate
+		// nexthop containing both network and link layer
+		// adjacencies.
+		if ifi == nil && !*testExternal {
+			continue
+		}
+		for _, tt := range ipv4MulticastListenerTests {
+			var err error
+			cs := make([]*UDPConn, 2)
+			if cs[0], err = ListenMulticastUDP(tt.net, ifi, tt.gaddr); err != nil {
+				t.Fatalf("First ListenMulticastUDP on %v failed: %v", ifi, err)
+			}
+			if err := checkMulticastListener(cs[0], tt.gaddr.IP); err != nil {
+				closer(cs)
+				t.Fatal(err)
+			}
+			if cs[1], err = ListenMulticastUDP(tt.net, ifi, tt.gaddr); err != nil {
+				closer(cs)
+				t.Fatalf("Second ListenMulticastUDP on %v failed: %v", ifi, err)
+			}
+			if err := checkMulticastListener(cs[1], tt.gaddr.IP); err != nil {
+				closer(cs)
+				t.Fatal(err)
+			}
+			closer(cs)
+		}
+	}
+}
+
+var ipv6MulticastListenerTests = []struct {
+	net   string
+	gaddr *UDPAddr // see RFC 4727
+}{
+	{"udp", &UDPAddr{IP: ParseIP("ff01::114"), Port: 12345}},
+	{"udp", &UDPAddr{IP: ParseIP("ff02::114"), Port: 12345}},
+	{"udp", &UDPAddr{IP: ParseIP("ff04::114"), Port: 12345}},
+	{"udp", &UDPAddr{IP: ParseIP("ff05::114"), Port: 12345}},
+	{"udp", &UDPAddr{IP: ParseIP("ff08::114"), Port: 12345}},
+	{"udp", &UDPAddr{IP: ParseIP("ff0e::114"), Port: 12345}},
+
+	{"udp6", &UDPAddr{IP: ParseIP("ff01::114"), Port: 12345}},
+	{"udp6", &UDPAddr{IP: ParseIP("ff02::114"), Port: 12345}},
+	{"udp6", &UDPAddr{IP: ParseIP("ff04::114"), Port: 12345}},
+	{"udp6", &UDPAddr{IP: ParseIP("ff05::114"), Port: 12345}},
+	{"udp6", &UDPAddr{IP: ParseIP("ff08::114"), Port: 12345}},
+	{"udp6", &UDPAddr{IP: ParseIP("ff0e::114"), Port: 12345}},
+}
+
+// TestIPv6MulticastListener tests both single and double listen to a
+// test listener with same address family, same group address and same
+// port.
+func TestIPv6MulticastListener(t *testing.T) {
+	switch runtime.GOOS {
+	case "plan9":
+		t.Skipf("skipping test on %q", runtime.GOOS)
+	case "solaris":
+		t.Skipf("skipping test on solaris, see issue 7399")
+	}
+	if !supportsIPv6 {
+		t.Skip("ipv6 is not supported")
+	}
+	if os.Getuid() != 0 {
+		t.Skip("skipping test; must be root")
+	}
+
+	closer := func(cs []*UDPConn) {
+		for _, c := range cs {
+			if c != nil {
+				c.Close()
+			}
+		}
+	}
+
+	for _, ifi := range []*Interface{loopbackInterface(), nil} {
+		// Note that multicast interface assignment by system
+		// is not recommended because it usually relies on
+		// routing stuff for finding out an appropriate
+		// nexthop containing both network and link layer
+		// adjacencies.
+		if ifi == nil && (!*testExternal || !*testIPv6) {
+			continue
+		}
+		for _, tt := range ipv6MulticastListenerTests {
+			var err error
+			cs := make([]*UDPConn, 2)
+			if cs[0], err = ListenMulticastUDP(tt.net, ifi, tt.gaddr); err != nil {
+				t.Fatalf("First ListenMulticastUDP on %v failed: %v", ifi, err)
+			}
+			if err := checkMulticastListener(cs[0], tt.gaddr.IP); err != nil {
+				closer(cs)
+				t.Fatal(err)
+			}
+			if cs[1], err = ListenMulticastUDP(tt.net, ifi, tt.gaddr); err != nil {
+				closer(cs)
+				t.Fatalf("Second ListenMulticastUDP on %v failed: %v", ifi, err)
+			}
+			if err := checkMulticastListener(cs[1], tt.gaddr.IP); err != nil {
+				closer(cs)
+				t.Fatal(err)
+			}
+			closer(cs)
+		}
+	}
+}
+
+func checkMulticastListener(c *UDPConn, ip IP) error {
+	if ok, err := multicastRIBContains(ip); err != nil {
+		return err
+	} else if !ok {
+		return fmt.Errorf("%q not found in multicast RIB", ip.String())
+	}
+	la := c.LocalAddr()
+	if la, ok := la.(*UDPAddr); !ok || la.Port == 0 {
+		return fmt.Errorf("got %v; expected a proper address with non-zero port number", la)
+	}
+	return nil
+}
+
+func multicastRIBContains(ip IP) (bool, error) {
+	switch runtime.GOOS {
+	case "dragonfly", "netbsd", "openbsd", "plan9", "solaris", "windows":
+		return true, nil // not implemented yet
+	case "linux":
+		if runtime.GOARCH == "arm" || runtime.GOARCH == "alpha" {
+			return true, nil // not implemented yet
+		}
+	}
+	ift, err := Interfaces()
+	if err != nil {
+		return false, err
+	}
+	for _, ifi := range ift {
+		ifmat, err := ifi.MulticastAddrs()
+		if err != nil {
+			return false, err
+		}
+		for _, ifma := range ifmat {
+			if ifma.(*IPAddr).IP.Equal(ip) {
+				return true, nil
+			}
+		}
+	}
+	return false, nil
+}
diff --git a/src/net/net.go b/src/net/net.go
new file mode 100644
index 0000000..cb31af5
--- /dev/null
+++ b/src/net/net.go
@@ -0,0 +1,425 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+/*
+Package net provides a portable interface for network I/O, including
+TCP/IP, UDP, domain name resolution, and Unix domain sockets.
+
+Although the package provides access to low-level networking
+primitives, most clients will need only the basic interface provided
+by the Dial, Listen, and Accept functions and the associated
+Conn and Listener interfaces. The crypto/tls package uses
+the same interfaces and similar Dial and Listen functions.
+
+The Dial function connects to a server:
+
+	conn, err := net.Dial("tcp", "google.com:80")
+	if err != nil {
+		// handle error
+	}
+	fmt.Fprintf(conn, "GET / HTTP/1.0\r\n\r\n")
+	status, err := bufio.NewReader(conn).ReadString('\n')
+	// ...
+
+The Listen function creates servers:
+
+	ln, err := net.Listen("tcp", ":8080")
+	if err != nil {
+		// handle error
+	}
+	for {
+		conn, err := ln.Accept()
+		if err != nil {
+			// handle error
+		}
+		go handleConnection(conn)
+	}
+*/
+package net
+
+// TODO(rsc):
+//	support for raw ethernet sockets
+
+import (
+	"errors"
+	"io"
+	"os"
+	"syscall"
+	"time"
+)
+
+// Addr represents a network end point address.
+type Addr interface {
+	Network() string // name of the network
+	String() string  // string form of address
+}
+
+// Conn is a generic stream-oriented network connection.
+//
+// Multiple goroutines may invoke methods on a Conn simultaneously.
+type Conn interface {
+	// Read reads data from the connection.
+	// Read can be made to time out and return a Error with Timeout() == true
+	// after a fixed time limit; see SetDeadline and SetReadDeadline.
+	Read(b []byte) (n int, err error)
+
+	// Write writes data to the connection.
+	// Write can be made to time out and return a Error with Timeout() == true
+	// after a fixed time limit; see SetDeadline and SetWriteDeadline.
+	Write(b []byte) (n int, err error)
+
+	// Close closes the connection.
+	// Any blocked Read or Write operations will be unblocked and return errors.
+	Close() error
+
+	// LocalAddr returns the local network address.
+	LocalAddr() Addr
+
+	// RemoteAddr returns the remote network address.
+	RemoteAddr() Addr
+
+	// SetDeadline sets the read and write deadlines associated
+	// with the connection. It is equivalent to calling both
+	// SetReadDeadline and SetWriteDeadline.
+	//
+	// A deadline is an absolute time after which I/O operations
+	// fail with a timeout (see type Error) instead of
+	// blocking. The deadline applies to all future I/O, not just
+	// the immediately following call to Read or Write.
+	//
+	// An idle timeout can be implemented by repeatedly extending
+	// the deadline after successful Read or Write calls.
+	//
+	// A zero value for t means I/O operations will not time out.
+	SetDeadline(t time.Time) error
+
+	// SetReadDeadline sets the deadline for future Read calls.
+	// A zero value for t means Read will not time out.
+	SetReadDeadline(t time.Time) error
+
+	// SetWriteDeadline sets the deadline for future Write calls.
+	// Even if write times out, it may return n > 0, indicating that
+	// some of the data was successfully written.
+	// A zero value for t means Write will not time out.
+	SetWriteDeadline(t time.Time) error
+}
+
+type conn struct {
+	fd *netFD
+}
+
+func (c *conn) ok() bool { return c != nil && c.fd != nil }
+
+// Implementation of the Conn interface.
+
+// Read implements the Conn Read method.
+func (c *conn) Read(b []byte) (int, error) {
+	if !c.ok() {
+		return 0, syscall.EINVAL
+	}
+	return c.fd.Read(b)
+}
+
+// Write implements the Conn Write method.
+func (c *conn) Write(b []byte) (int, error) {
+	if !c.ok() {
+		return 0, syscall.EINVAL
+	}
+	return c.fd.Write(b)
+}
+
+// Close closes the connection.
+func (c *conn) Close() error {
+	if !c.ok() {
+		return syscall.EINVAL
+	}
+	return c.fd.Close()
+}
+
+// LocalAddr returns the local network address.
+func (c *conn) LocalAddr() Addr {
+	if !c.ok() {
+		return nil
+	}
+	return c.fd.laddr
+}
+
+// RemoteAddr returns the remote network address.
+func (c *conn) RemoteAddr() Addr {
+	if !c.ok() {
+		return nil
+	}
+	return c.fd.raddr
+}
+
+// SetDeadline implements the Conn SetDeadline method.
+func (c *conn) SetDeadline(t time.Time) error {
+	if !c.ok() {
+		return syscall.EINVAL
+	}
+	return c.fd.setDeadline(t)
+}
+
+// SetReadDeadline implements the Conn SetReadDeadline method.
+func (c *conn) SetReadDeadline(t time.Time) error {
+	if !c.ok() {
+		return syscall.EINVAL
+	}
+	return c.fd.setReadDeadline(t)
+}
+
+// SetWriteDeadline implements the Conn SetWriteDeadline method.
+func (c *conn) SetWriteDeadline(t time.Time) error {
+	if !c.ok() {
+		return syscall.EINVAL
+	}
+	return c.fd.setWriteDeadline(t)
+}
+
+// SetReadBuffer sets the size of the operating system's
+// receive buffer associated with the connection.
+func (c *conn) SetReadBuffer(bytes int) error {
+	if !c.ok() {
+		return syscall.EINVAL
+	}
+	return setReadBuffer(c.fd, bytes)
+}
+
+// SetWriteBuffer sets the size of the operating system's
+// transmit buffer associated with the connection.
+func (c *conn) SetWriteBuffer(bytes int) error {
+	if !c.ok() {
+		return syscall.EINVAL
+	}
+	return setWriteBuffer(c.fd, bytes)
+}
+
+// File sets the underlying os.File to blocking mode and returns a copy.
+// It is the caller's responsibility to close f when finished.
+// Closing c does not affect f, and closing f does not affect c.
+//
+// The returned os.File's file descriptor is different from the connection's.
+// Attempting to change properties of the original using this duplicate
+// may or may not have the desired effect.
+func (c *conn) File() (f *os.File, err error) { return c.fd.dup() }
+
+// An Error represents a network error.
+type Error interface {
+	error
+	Timeout() bool   // Is the error a timeout?
+	Temporary() bool // Is the error temporary?
+}
+
+// PacketConn is a generic packet-oriented network connection.
+//
+// Multiple goroutines may invoke methods on a PacketConn simultaneously.
+type PacketConn interface {
+	// ReadFrom reads a packet from the connection,
+	// copying the payload into b.  It returns the number of
+	// bytes copied into b and the return address that
+	// was on the packet.
+	// ReadFrom can be made to time out and return
+	// an error with Timeout() == true after a fixed time limit;
+	// see SetDeadline and SetReadDeadline.
+	ReadFrom(b []byte) (n int, addr Addr, err error)
+
+	// WriteTo writes a packet with payload b to addr.
+	// WriteTo can be made to time out and return
+	// an error with Timeout() == true after a fixed time limit;
+	// see SetDeadline and SetWriteDeadline.
+	// On packet-oriented connections, write timeouts are rare.
+	WriteTo(b []byte, addr Addr) (n int, err error)
+
+	// Close closes the connection.
+	// Any blocked ReadFrom or WriteTo operations will be unblocked and return errors.
+	Close() error
+
+	// LocalAddr returns the local network address.
+	LocalAddr() Addr
+
+	// SetDeadline sets the read and write deadlines associated
+	// with the connection.
+	SetDeadline(t time.Time) error
+
+	// SetReadDeadline sets the deadline for future Read calls.
+	// If the deadline is reached, Read will fail with a timeout
+	// (see type Error) instead of blocking.
+	// A zero value for t means Read will not time out.
+	SetReadDeadline(t time.Time) error
+
+	// SetWriteDeadline sets the deadline for future Write calls.
+	// If the deadline is reached, Write will fail with a timeout
+	// (see type Error) instead of blocking.
+	// A zero value for t means Write will not time out.
+	// Even if write times out, it may return n > 0, indicating that
+	// some of the data was successfully written.
+	SetWriteDeadline(t time.Time) error
+}
+
+var listenerBacklog = maxListenerBacklog()
+
+// A Listener is a generic network listener for stream-oriented protocols.
+//
+// Multiple goroutines may invoke methods on a Listener simultaneously.
+type Listener interface {
+	// Accept waits for and returns the next connection to the listener.
+	Accept() (c Conn, err error)
+
+	// Close closes the listener.
+	// Any blocked Accept operations will be unblocked and return errors.
+	Close() error
+
+	// Addr returns the listener's network address.
+	Addr() Addr
+}
+
+// Various errors contained in OpError.
+var (
+	// For connection setup and write operations.
+	errMissingAddress = errors.New("missing address")
+
+	// For both read and write operations.
+	errTimeout          error = &timeoutError{}
+	errClosing                = errors.New("use of closed network connection")
+	ErrWriteToConnected       = errors.New("use of WriteTo with pre-connected connection")
+)
+
+// OpError is the error type usually returned by functions in the net
+// package. It describes the operation, network type, and address of
+// an error.
+type OpError struct {
+	// Op is the operation which caused the error, such as
+	// "read" or "write".
+	Op string
+
+	// Net is the network type on which this error occurred,
+	// such as "tcp" or "udp6".
+	Net string
+
+	// Addr is the network address on which this error occurred.
+	Addr Addr
+
+	// Err is the error that occurred during the operation.
+	Err error
+}
+
+func (e *OpError) Error() string {
+	if e == nil {
+		return "<nil>"
+	}
+	s := e.Op
+	if e.Net != "" {
+		s += " " + e.Net
+	}
+	if e.Addr != nil {
+		s += " " + e.Addr.String()
+	}
+	s += ": " + e.Err.Error()
+	return s
+}
+
+type temporary interface {
+	Temporary() bool
+}
+
+func (e *OpError) Temporary() bool {
+	t, ok := e.Err.(temporary)
+	return ok && t.Temporary()
+}
+
+var noDeadline = time.Time{}
+
+type timeout interface {
+	Timeout() bool
+}
+
+func (e *OpError) Timeout() bool {
+	t, ok := e.Err.(timeout)
+	return ok && t.Timeout()
+}
+
+type timeoutError struct{}
+
+func (e *timeoutError) Error() string   { return "i/o timeout" }
+func (e *timeoutError) Timeout() bool   { return true }
+func (e *timeoutError) Temporary() bool { return true }
+
+type AddrError struct {
+	Err  string
+	Addr string
+}
+
+func (e *AddrError) Error() string {
+	if e == nil {
+		return "<nil>"
+	}
+	s := e.Err
+	if e.Addr != "" {
+		s += " " + e.Addr
+	}
+	return s
+}
+
+func (e *AddrError) Temporary() bool {
+	return false
+}
+
+func (e *AddrError) Timeout() bool {
+	return false
+}
+
+type UnknownNetworkError string
+
+func (e UnknownNetworkError) Error() string   { return "unknown network " + string(e) }
+func (e UnknownNetworkError) Temporary() bool { return false }
+func (e UnknownNetworkError) Timeout() bool   { return false }
+
+type InvalidAddrError string
+
+func (e InvalidAddrError) Error() string   { return string(e) }
+func (e InvalidAddrError) Timeout() bool   { return false }
+func (e InvalidAddrError) Temporary() bool { return false }
+
+// DNSConfigError represents an error reading the machine's DNS configuration.
+type DNSConfigError struct {
+	Err error
+}
+
+func (e *DNSConfigError) Error() string {
+	return "error reading DNS config: " + e.Err.Error()
+}
+
+func (e *DNSConfigError) Timeout() bool   { return false }
+func (e *DNSConfigError) Temporary() bool { return false }
+
+type writerOnly struct {
+	io.Writer
+}
+
+// Fallback implementation of io.ReaderFrom's ReadFrom, when sendfile isn't
+// applicable.
+func genericReadFrom(w io.Writer, r io.Reader) (n int64, err error) {
+	// Use wrapper to hide existing r.ReadFrom from io.Copy.
+	return io.Copy(writerOnly{w}, r)
+}
+
+// Limit the number of concurrent cgo-using goroutines, because
+// each will block an entire operating system thread. The usual culprit
+// is resolving many DNS names in separate goroutines but the DNS
+// server is not responding. Then the many lookups each use a different
+// thread, and the system or the program runs out of threads.
+
+var threadLimit = make(chan struct{}, 500)
+
+// Using send for acquire is fine here because we are not using this
+// to protect any memory. All we care about is the number of goroutines
+// making calls at a time.
+
+func acquireThread() {
+	threadLimit <- struct{}{}
+}
+
+func releaseThread() {
+	<-threadLimit
+}
diff --git a/src/pkg/net/net_test.go b/src/net/net_test.go
similarity index 100%
rename from src/pkg/net/net_test.go
rename to src/net/net_test.go
diff --git a/src/pkg/net/net_windows_test.go b/src/net/net_windows_test.go
similarity index 100%
rename from src/pkg/net/net_windows_test.go
rename to src/net/net_windows_test.go
diff --git a/src/pkg/net/netgo_unix_test.go b/src/net/netgo_unix_test.go
similarity index 100%
rename from src/pkg/net/netgo_unix_test.go
rename to src/net/netgo_unix_test.go
diff --git a/src/pkg/net/packetconn_test.go b/src/net/packetconn_test.go
similarity index 100%
rename from src/pkg/net/packetconn_test.go
rename to src/net/packetconn_test.go
diff --git a/src/net/parse.go b/src/net/parse.go
new file mode 100644
index 0000000..e1d0130
--- /dev/null
+++ b/src/net/parse.go
@@ -0,0 +1,247 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Simple file i/o and string manipulation, to avoid
+// depending on strconv and bufio and strings.
+
+package net
+
+import (
+	"io"
+	"os"
+)
+
+type file struct {
+	file  *os.File
+	data  []byte
+	atEOF bool
+}
+
+func (f *file) close() { f.file.Close() }
+
+func (f *file) getLineFromData() (s string, ok bool) {
+	data := f.data
+	i := 0
+	for i = 0; i < len(data); i++ {
+		if data[i] == '\n' {
+			s = string(data[0:i])
+			ok = true
+			// move data
+			i++
+			n := len(data) - i
+			copy(data[0:], data[i:])
+			f.data = data[0:n]
+			return
+		}
+	}
+	if f.atEOF && len(f.data) > 0 {
+		// EOF, return all we have
+		s = string(data)
+		f.data = f.data[0:0]
+		ok = true
+	}
+	return
+}
+
+func (f *file) readLine() (s string, ok bool) {
+	if s, ok = f.getLineFromData(); ok {
+		return
+	}
+	if len(f.data) < cap(f.data) {
+		ln := len(f.data)
+		n, err := io.ReadFull(f.file, f.data[ln:cap(f.data)])
+		if n >= 0 {
+			f.data = f.data[0 : ln+n]
+		}
+		if err == io.EOF || err == io.ErrUnexpectedEOF {
+			f.atEOF = true
+		}
+	}
+	s, ok = f.getLineFromData()
+	return
+}
+
+func open(name string) (*file, error) {
+	fd, err := os.Open(name)
+	if err != nil {
+		return nil, err
+	}
+	return &file{fd, make([]byte, 0, os.Getpagesize()), false}, nil
+}
+
+func byteIndex(s string, c byte) int {
+	for i := 0; i < len(s); i++ {
+		if s[i] == c {
+			return i
+		}
+	}
+	return -1
+}
+
+// Count occurrences in s of any bytes in t.
+func countAnyByte(s string, t string) int {
+	n := 0
+	for i := 0; i < len(s); i++ {
+		if byteIndex(t, s[i]) >= 0 {
+			n++
+		}
+	}
+	return n
+}
+
+// Split s at any bytes in t.
+func splitAtBytes(s string, t string) []string {
+	a := make([]string, 1+countAnyByte(s, t))
+	n := 0
+	last := 0
+	for i := 0; i < len(s); i++ {
+		if byteIndex(t, s[i]) >= 0 {
+			if last < i {
+				a[n] = string(s[last:i])
+				n++
+			}
+			last = i + 1
+		}
+	}
+	if last < len(s) {
+		a[n] = string(s[last:])
+		n++
+	}
+	return a[0:n]
+}
+
+func getFields(s string) []string { return splitAtBytes(s, " \r\t\n") }
+
+// Bigger than we need, not too big to worry about overflow
+const big = 0xFFFFFF
+
+// Decimal to integer starting at &s[i0].
+// Returns number, new offset, success.
+func dtoi(s string, i0 int) (n int, i int, ok bool) {
+	n = 0
+	for i = i0; i < len(s) && '0' <= s[i] && s[i] <= '9'; i++ {
+		n = n*10 + int(s[i]-'0')
+		if n >= big {
+			return 0, i, false
+		}
+	}
+	if i == i0 {
+		return 0, i, false
+	}
+	return n, i, true
+}
+
+// Hexadecimal to integer starting at &s[i0].
+// Returns number, new offset, success.
+func xtoi(s string, i0 int) (n int, i int, ok bool) {
+	n = 0
+	for i = i0; i < len(s); i++ {
+		if '0' <= s[i] && s[i] <= '9' {
+			n *= 16
+			n += int(s[i] - '0')
+		} else if 'a' <= s[i] && s[i] <= 'f' {
+			n *= 16
+			n += int(s[i]-'a') + 10
+		} else if 'A' <= s[i] && s[i] <= 'F' {
+			n *= 16
+			n += int(s[i]-'A') + 10
+		} else {
+			break
+		}
+		if n >= big {
+			return 0, i, false
+		}
+	}
+	if i == i0 {
+		return 0, i, false
+	}
+	return n, i, true
+}
+
+// xtoi2 converts the next two hex digits of s into a byte.
+// If s is longer than 2 bytes then the third byte must be e.
+// If the first two bytes of s are not hex digits or the third byte
+// does not match e, false is returned.
+func xtoi2(s string, e byte) (byte, bool) {
+	if len(s) > 2 && s[2] != e {
+		return 0, false
+	}
+	n, ei, ok := xtoi(s[:2], 0)
+	return byte(n), ok && ei == 2
+}
+
+// Integer to decimal.
+func itoa(i int) string {
+	var buf [30]byte
+	n := len(buf)
+	neg := false
+	if i < 0 {
+		i = -i
+		neg = true
+	}
+	ui := uint(i)
+	for ui > 0 || n == len(buf) {
+		n--
+		buf[n] = byte('0' + ui%10)
+		ui /= 10
+	}
+	if neg {
+		n--
+		buf[n] = '-'
+	}
+	return string(buf[n:])
+}
+
+// Convert i to decimal string.
+func itod(i uint) string {
+	if i == 0 {
+		return "0"
+	}
+
+	// Assemble decimal in reverse order.
+	var b [32]byte
+	bp := len(b)
+	for ; i > 0; i /= 10 {
+		bp--
+		b[bp] = byte(i%10) + '0'
+	}
+
+	return string(b[bp:])
+}
+
+// Convert i to a hexadecimal string. Leading zeros are not printed.
+func appendHex(dst []byte, i uint32) []byte {
+	if i == 0 {
+		return append(dst, '0')
+	}
+	for j := 7; j >= 0; j-- {
+		v := i >> uint(j*4)
+		if v > 0 {
+			dst = append(dst, hexDigit[v&0xf])
+		}
+	}
+	return dst
+}
+
+// Number of occurrences of b in s.
+func count(s string, b byte) int {
+	n := 0
+	for i := 0; i < len(s); i++ {
+		if s[i] == b {
+			n++
+		}
+	}
+	return n
+}
+
+// Index of rightmost occurrence of b in s.
+func last(s string, b byte) int {
+	i := len(s)
+	for i--; i >= 0; i-- {
+		if s[i] == b {
+			break
+		}
+	}
+	return i
+}
diff --git a/src/net/parse_test.go b/src/net/parse_test.go
new file mode 100644
index 0000000..7b213b7
--- /dev/null
+++ b/src/net/parse_test.go
@@ -0,0 +1,53 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package net
+
+import (
+	"bufio"
+	"os"
+	"runtime"
+	"testing"
+)
+
+func TestReadLine(t *testing.T) {
+	// /etc/services file does not exist on android, plan9, windows.
+	switch runtime.GOOS {
+	case "android", "plan9", "windows":
+		t.Skipf("skipping test on %q", runtime.GOOS)
+	}
+	filename := "/etc/services" // a nice big file
+
+	fd, err := os.Open(filename)
+	if err != nil {
+		t.Fatalf("open %s: %v", filename, err)
+	}
+	defer fd.Close()
+	br := bufio.NewReader(fd)
+
+	file, err := open(filename)
+	if file == nil {
+		t.Fatalf("net.open(%s) = nil", filename)
+	}
+	defer file.close()
+
+	lineno := 1
+	byteno := 0
+	for {
+		bline, berr := br.ReadString('\n')
+		if n := len(bline); n > 0 {
+			bline = bline[0 : n-1]
+		}
+		line, ok := file.readLine()
+		if (berr != nil) != !ok || bline != line {
+			t.Fatalf("%s:%d (#%d)\nbufio => %q, %v\nnet => %q, %v",
+				filename, lineno, byteno, bline, berr, line, ok)
+		}
+		if !ok {
+			break
+		}
+		lineno++
+		byteno += len(line) + 1
+	}
+}
diff --git a/src/pkg/net/pipe.go b/src/net/pipe.go
similarity index 100%
rename from src/pkg/net/pipe.go
rename to src/net/pipe.go
diff --git a/src/pkg/net/pipe_test.go b/src/net/pipe_test.go
similarity index 100%
rename from src/pkg/net/pipe_test.go
rename to src/net/pipe_test.go
diff --git a/src/pkg/net/port.go b/src/net/port.go
similarity index 100%
rename from src/pkg/net/port.go
rename to src/net/port.go
diff --git a/src/net/port_test.go b/src/net/port_test.go
new file mode 100644
index 0000000..4811ade
--- /dev/null
+++ b/src/net/port_test.go
@@ -0,0 +1,59 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package net
+
+import (
+	"runtime"
+	"testing"
+)
+
+type portTest struct {
+	netw string
+	name string
+	port int
+	ok   bool
+}
+
+var porttests = []portTest{
+	{"tcp", "echo", 7, true},
+	{"tcp", "discard", 9, true},
+	{"tcp", "systat", 11, true},
+	{"tcp", "daytime", 13, true},
+	{"tcp", "chargen", 19, true},
+	{"tcp", "ftp-data", 20, true},
+	{"tcp", "ftp", 21, true},
+	{"tcp", "telnet", 23, true},
+	{"tcp", "smtp", 25, true},
+	{"tcp", "time", 37, true},
+	{"tcp", "domain", 53, true},
+	{"tcp", "finger", 79, true},
+
+	{"udp", "echo", 7, true},
+	{"udp", "tftp", 69, true},
+	{"udp", "bootpc", 68, true},
+	{"udp", "bootps", 67, true},
+	{"udp", "domain", 53, true},
+	{"udp", "ntp", 123, true},
+	{"udp", "snmp", 161, true},
+	{"udp", "syslog", 514, true},
+
+	{"--badnet--", "zzz", 0, false},
+	{"tcp", "--badport--", 0, false},
+}
+
+func TestLookupPort(t *testing.T) {
+	switch runtime.GOOS {
+	case "nacl":
+		t.Skipf("skipping test on %q", runtime.GOOS)
+	}
+
+	for i := 0; i < len(porttests); i++ {
+		tt := porttests[i]
+		if port, err := LookupPort(tt.netw, tt.name); port != tt.port || (err == nil) != tt.ok {
+			t.Errorf("LookupPort(%q, %q) = %v, %v; want %v",
+				tt.netw, tt.name, port, err, tt.port)
+		}
+	}
+}
diff --git a/src/net/port_unix.go b/src/net/port_unix.go
new file mode 100644
index 0000000..348c771
--- /dev/null
+++ b/src/net/port_unix.go
@@ -0,0 +1,73 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin dragonfly freebsd linux netbsd openbsd solaris
+
+// Read system port mappings from /etc/services
+
+package net
+
+import "sync"
+
+// services contains minimal mappings between services names and port
+// numbers for platforms that don't have a complete list of port numbers
+// (some Solaris distros).
+var services = map[string]map[string]int{
+	"tcp": {"http": 80},
+}
+var servicesError error
+var onceReadServices sync.Once
+
+func readServices() {
+	var file *file
+	if file, servicesError = open("/etc/services"); servicesError != nil {
+		return
+	}
+	for line, ok := file.readLine(); ok; line, ok = file.readLine() {
+		// "http 80/tcp www www-http # World Wide Web HTTP"
+		if i := byteIndex(line, '#'); i >= 0 {
+			line = line[0:i]
+		}
+		f := getFields(line)
+		if len(f) < 2 {
+			continue
+		}
+		portnet := f[1] // "80/tcp"
+		port, j, ok := dtoi(portnet, 0)
+		if !ok || port <= 0 || j >= len(portnet) || portnet[j] != '/' {
+			continue
+		}
+		netw := portnet[j+1:] // "tcp"
+		m, ok1 := services[netw]
+		if !ok1 {
+			m = make(map[string]int)
+			services[netw] = m
+		}
+		for i := 0; i < len(f); i++ {
+			if i != 1 { // f[1] was port/net
+				m[f[i]] = port
+			}
+		}
+	}
+	file.close()
+}
+
+// goLookupPort is the native Go implementation of LookupPort.
+func goLookupPort(network, service string) (port int, err error) {
+	onceReadServices.Do(readServices)
+
+	switch network {
+	case "tcp4", "tcp6":
+		network = "tcp"
+	case "udp4", "udp6":
+		network = "udp"
+	}
+
+	if m, ok := services[network]; ok {
+		if port, ok = m[service]; ok {
+			return
+		}
+	}
+	return 0, &AddrError{"unknown port", network + "/" + service}
+}
diff --git a/src/pkg/net/protoconn_test.go b/src/net/protoconn_test.go
similarity index 100%
rename from src/pkg/net/protoconn_test.go
rename to src/net/protoconn_test.go
diff --git a/src/pkg/net/race.go b/src/net/race.go
similarity index 100%
rename from src/pkg/net/race.go
rename to src/net/race.go
diff --git a/src/pkg/net/race0.go b/src/net/race0.go
similarity index 100%
rename from src/pkg/net/race0.go
rename to src/net/race0.go
diff --git a/src/net/rpc/client.go b/src/net/rpc/client.go
new file mode 100644
index 0000000..d0c4a69
--- /dev/null
+++ b/src/net/rpc/client.go
@@ -0,0 +1,317 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package rpc
+
+import (
+	"bufio"
+	"encoding/gob"
+	"errors"
+	"io"
+	"log"
+	"net"
+	"net/http"
+	"sync"
+)
+
+// ServerError represents an error that has been returned from
+// the remote side of the RPC connection.
+type ServerError string
+
+func (e ServerError) Error() string {
+	return string(e)
+}
+
+var ErrShutdown = errors.New("connection is shut down")
+
+// Call represents an active RPC.
+type Call struct {
+	ServiceMethod string      // The name of the service and method to call.
+	Args          interface{} // The argument to the function (*struct).
+	Reply         interface{} // The reply from the function (*struct).
+	Error         error       // After completion, the error status.
+	Done          chan *Call  // Strobes when call is complete.
+}
+
+// Client represents an RPC Client.
+// There may be multiple outstanding Calls associated
+// with a single Client, and a Client may be used by
+// multiple goroutines simultaneously.
+type Client struct {
+	codec ClientCodec
+
+	reqMutex sync.Mutex // protects following
+	request  Request
+
+	mutex    sync.Mutex // protects following
+	seq      uint64
+	pending  map[uint64]*Call
+	closing  bool // user has called Close
+	shutdown bool // server has told us to stop
+}
+
+// A ClientCodec implements writing of RPC requests and
+// reading of RPC responses for the client side of an RPC session.
+// The client calls WriteRequest to write a request to the connection
+// and calls ReadResponseHeader and ReadResponseBody in pairs
+// to read responses.  The client calls Close when finished with the
+// connection. ReadResponseBody may be called with a nil
+// argument to force the body of the response to be read and then
+// discarded.
+type ClientCodec interface {
+	// WriteRequest must be safe for concurrent use by multiple goroutines.
+	WriteRequest(*Request, interface{}) error
+	ReadResponseHeader(*Response) error
+	ReadResponseBody(interface{}) error
+
+	Close() error
+}
+
+func (client *Client) send(call *Call) {
+	client.reqMutex.Lock()
+	defer client.reqMutex.Unlock()
+
+	// Register this call.
+	client.mutex.Lock()
+	if client.shutdown || client.closing {
+		call.Error = ErrShutdown
+		client.mutex.Unlock()
+		call.done()
+		return
+	}
+	seq := client.seq
+	client.seq++
+	client.pending[seq] = call
+	client.mutex.Unlock()
+
+	// Encode and send the request.
+	client.request.Seq = seq
+	client.request.ServiceMethod = call.ServiceMethod
+	err := client.codec.WriteRequest(&client.request, call.Args)
+	if err != nil {
+		client.mutex.Lock()
+		call = client.pending[seq]
+		delete(client.pending, seq)
+		client.mutex.Unlock()
+		if call != nil {
+			call.Error = err
+			call.done()
+		}
+	}
+}
+
+func (client *Client) input() {
+	var err error
+	var response Response
+	for err == nil {
+		response = Response{}
+		err = client.codec.ReadResponseHeader(&response)
+		if err != nil {
+			break
+		}
+		seq := response.Seq
+		client.mutex.Lock()
+		call := client.pending[seq]
+		delete(client.pending, seq)
+		client.mutex.Unlock()
+
+		switch {
+		case call == nil:
+			// We've got no pending call. That usually means that
+			// WriteRequest partially failed, and call was already
+			// removed; response is a server telling us about an
+			// error reading request body. We should still attempt
+			// to read error body, but there's no one to give it to.
+			err = client.codec.ReadResponseBody(nil)
+			if err != nil {
+				err = errors.New("reading error body: " + err.Error())
+			}
+		case response.Error != "":
+			// We've got an error response. Give this to the request;
+			// any subsequent requests will get the ReadResponseBody
+			// error if there is one.
+			call.Error = ServerError(response.Error)
+			err = client.codec.ReadResponseBody(nil)
+			if err != nil {
+				err = errors.New("reading error body: " + err.Error())
+			}
+			call.done()
+		default:
+			err = client.codec.ReadResponseBody(call.Reply)
+			if err != nil {
+				call.Error = errors.New("reading body " + err.Error())
+			}
+			call.done()
+		}
+	}
+	// Terminate pending calls.
+	client.reqMutex.Lock()
+	client.mutex.Lock()
+	client.shutdown = true
+	closing := client.closing
+	if err == io.EOF {
+		if closing {
+			err = ErrShutdown
+		} else {
+			err = io.ErrUnexpectedEOF
+		}
+	}
+	for _, call := range client.pending {
+		call.Error = err
+		call.done()
+	}
+	client.mutex.Unlock()
+	client.reqMutex.Unlock()
+	if debugLog && err != io.EOF && !closing {
+		log.Println("rpc: client protocol error:", err)
+	}
+}
+
+func (call *Call) done() {
+	select {
+	case call.Done <- call:
+		// ok
+	default:
+		// We don't want to block here.  It is the caller's responsibility to make
+		// sure the channel has enough buffer space. See comment in Go().
+		if debugLog {
+			log.Println("rpc: discarding Call reply due to insufficient Done chan capacity")
+		}
+	}
+}
+
+// NewClient returns a new Client to handle requests to the
+// set of services at the other end of the connection.
+// It adds a buffer to the write side of the connection so
+// the header and payload are sent as a unit.
+func NewClient(conn io.ReadWriteCloser) *Client {
+	encBuf := bufio.NewWriter(conn)
+	client := &gobClientCodec{conn, gob.NewDecoder(conn), gob.NewEncoder(encBuf), encBuf}
+	return NewClientWithCodec(client)
+}
+
+// NewClientWithCodec is like NewClient but uses the specified
+// codec to encode requests and decode responses.
+func NewClientWithCodec(codec ClientCodec) *Client {
+	client := &Client{
+		codec:   codec,
+		pending: make(map[uint64]*Call),
+	}
+	go client.input()
+	return client
+}
+
+type gobClientCodec struct {
+	rwc    io.ReadWriteCloser
+	dec    *gob.Decoder
+	enc    *gob.Encoder
+	encBuf *bufio.Writer
+}
+
+func (c *gobClientCodec) WriteRequest(r *Request, body interface{}) (err error) {
+	if err = c.enc.Encode(r); err != nil {
+		return
+	}
+	if err = c.enc.Encode(body); err != nil {
+		return
+	}
+	return c.encBuf.Flush()
+}
+
+func (c *gobClientCodec) ReadResponseHeader(r *Response) error {
+	return c.dec.Decode(r)
+}
+
+func (c *gobClientCodec) ReadResponseBody(body interface{}) error {
+	return c.dec.Decode(body)
+}
+
+func (c *gobClientCodec) Close() error {
+	return c.rwc.Close()
+}
+
+// DialHTTP connects to an HTTP RPC server at the specified network address
+// listening on the default HTTP RPC path.
+func DialHTTP(network, address string) (*Client, error) {
+	return DialHTTPPath(network, address, DefaultRPCPath)
+}
+
+// DialHTTPPath connects to an HTTP RPC server
+// at the specified network address and path.
+func DialHTTPPath(network, address, path string) (*Client, error) {
+	var err error
+	conn, err := net.Dial(network, address)
+	if err != nil {
+		return nil, err
+	}
+	io.WriteString(conn, "CONNECT "+path+" HTTP/1.0\n\n")
+
+	// Require successful HTTP response
+	// before switching to RPC protocol.
+	resp, err := http.ReadResponse(bufio.NewReader(conn), &http.Request{Method: "CONNECT"})
+	if err == nil && resp.Status == connected {
+		return NewClient(conn), nil
+	}
+	if err == nil {
+		err = errors.New("unexpected HTTP response: " + resp.Status)
+	}
+	conn.Close()
+	return nil, &net.OpError{
+		Op:   "dial-http",
+		Net:  network + " " + address,
+		Addr: nil,
+		Err:  err,
+	}
+}
+
+// Dial connects to an RPC server at the specified network address.
+func Dial(network, address string) (*Client, error) {
+	conn, err := net.Dial(network, address)
+	if err != nil {
+		return nil, err
+	}
+	return NewClient(conn), nil
+}
+
+func (client *Client) Close() error {
+	client.mutex.Lock()
+	if client.closing {
+		client.mutex.Unlock()
+		return ErrShutdown
+	}
+	client.closing = true
+	client.mutex.Unlock()
+	return client.codec.Close()
+}
+
+// Go invokes the function asynchronously.  It returns the Call structure representing
+// the invocation.  The done channel will signal when the call is complete by returning
+// the same Call object.  If done is nil, Go will allocate a new channel.
+// If non-nil, done must be buffered or Go will deliberately crash.
+func (client *Client) Go(serviceMethod string, args interface{}, reply interface{}, done chan *Call) *Call {
+	call := new(Call)
+	call.ServiceMethod = serviceMethod
+	call.Args = args
+	call.Reply = reply
+	if done == nil {
+		done = make(chan *Call, 10) // buffered.
+	} else {
+		// If caller passes done != nil, it must arrange that
+		// done has enough buffer for the number of simultaneous
+		// RPCs that will be using that channel.  If the channel
+		// is totally unbuffered, it's best not to run at all.
+		if cap(done) == 0 {
+			log.Panic("rpc: done channel is unbuffered")
+		}
+	}
+	call.Done = done
+	client.send(call)
+	return call
+}
+
+// Call invokes the named function, waits for it to complete, and returns its error status.
+func (client *Client) Call(serviceMethod string, args interface{}, reply interface{}) error {
+	call := <-client.Go(serviceMethod, args, reply, make(chan *Call, 1)).Done
+	return call.Error
+}
diff --git a/src/net/rpc/client_test.go b/src/net/rpc/client_test.go
new file mode 100644
index 0000000..5dd111b
--- /dev/null
+++ b/src/net/rpc/client_test.go
@@ -0,0 +1,91 @@
+// 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 rpc
+
+import (
+	"errors"
+	"fmt"
+	"net"
+	"runtime"
+	"strings"
+	"testing"
+)
+
+type shutdownCodec struct {
+	responded chan int
+	closed    bool
+}
+
+func (c *shutdownCodec) WriteRequest(*Request, interface{}) error { return nil }
+func (c *shutdownCodec) ReadResponseBody(interface{}) error       { return nil }
+func (c *shutdownCodec) ReadResponseHeader(*Response) error {
+	c.responded <- 1
+	return errors.New("shutdownCodec ReadResponseHeader")
+}
+func (c *shutdownCodec) Close() error {
+	c.closed = true
+	return nil
+}
+
+func TestCloseCodec(t *testing.T) {
+	codec := &shutdownCodec{responded: make(chan int)}
+	client := NewClientWithCodec(codec)
+	<-codec.responded
+	client.Close()
+	if !codec.closed {
+		t.Error("client.Close did not close codec")
+	}
+}
+
+// Test that errors in gob shut down the connection. Issue 7689.
+
+type R struct {
+	msg []byte // Not exported, so R does not work with gob.
+}
+
+type S struct{}
+
+func (s *S) Recv(nul *struct{}, reply *R) error {
+	*reply = R{[]byte("foo")}
+	return nil
+}
+
+func TestGobError(t *testing.T) {
+	if runtime.GOOS == "plan9" {
+		t.Skip("skipping test; see http://golang.org/issue/8908")
+	}
+	defer func() {
+		err := recover()
+		if err == nil {
+			t.Fatal("no error")
+		}
+		if !strings.Contains("reading body EOF", err.(error).Error()) {
+			t.Fatal("expected `reading body EOF', got", err)
+		}
+	}()
+	Register(new(S))
+
+	listen, err := net.Listen("tcp", "127.0.0.1:0")
+	if err != nil {
+		panic(err)
+	}
+	go Accept(listen)
+
+	client, err := Dial("tcp", listen.Addr().String())
+	if err != nil {
+		panic(err)
+	}
+
+	var reply Reply
+	err = client.Call("S.Recv", &struct{}{}, &reply)
+	if err != nil {
+		panic(err)
+	}
+
+	fmt.Printf("%#v\n", reply)
+	client.Close()
+
+	listen.Close()
+}
diff --git a/src/net/rpc/debug.go b/src/net/rpc/debug.go
new file mode 100644
index 0000000..98b2c1c
--- /dev/null
+++ b/src/net/rpc/debug.go
@@ -0,0 +1,93 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package rpc
+
+/*
+	Some HTML presented at http://machine:port/debug/rpc
+	Lists services, their methods, and some statistics, still rudimentary.
+*/
+
+import (
+	"fmt"
+	"html/template"
+	"net/http"
+	"sort"
+)
+
+const debugText = `<html>
+	<body>
+	<title>Services</title>
+	{{range .}}
+	<hr>
+	Service {{.Name}}
+	<hr>
+		<table>
+		<th align=center>Method</th><th align=center>Calls</th>
+		{{range .Method}}
+			<tr>
+			<td align=left font=fixed>{{.Name}}({{.Type.ArgType}}, {{.Type.ReplyType}}) error</td>
+			<td align=center>{{.Type.NumCalls}}</td>
+			</tr>
+		{{end}}
+		</table>
+	{{end}}
+	</body>
+	</html>`
+
+var debug = template.Must(template.New("RPC debug").Parse(debugText))
+
+// If set, print log statements for internal and I/O errors.
+var debugLog = false
+
+type debugMethod struct {
+	Type *methodType
+	Name string
+}
+
+type methodArray []debugMethod
+
+type debugService struct {
+	Service *service
+	Name    string
+	Method  methodArray
+}
+
+type serviceArray []debugService
+
+func (s serviceArray) Len() int           { return len(s) }
+func (s serviceArray) Less(i, j int) bool { return s[i].Name < s[j].Name }
+func (s serviceArray) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
+
+func (m methodArray) Len() int           { return len(m) }
+func (m methodArray) Less(i, j int) bool { return m[i].Name < m[j].Name }
+func (m methodArray) Swap(i, j int)      { m[i], m[j] = m[j], m[i] }
+
+type debugHTTP struct {
+	*Server
+}
+
+// Runs at /debug/rpc
+func (server debugHTTP) ServeHTTP(w http.ResponseWriter, req *http.Request) {
+	// Build a sorted version of the data.
+	var services = make(serviceArray, len(server.serviceMap))
+	i := 0
+	server.mu.Lock()
+	for sname, service := range server.serviceMap {
+		services[i] = debugService{service, sname, make(methodArray, len(service.method))}
+		j := 0
+		for mname, method := range service.method {
+			services[i].Method[j] = debugMethod{method, mname}
+			j++
+		}
+		sort.Sort(services[i].Method)
+		i++
+	}
+	server.mu.Unlock()
+	sort.Sort(services)
+	err := debug.Execute(w, services)
+	if err != nil {
+		fmt.Fprintln(w, "rpc: error executing template:", err.Error())
+	}
+}
diff --git a/src/pkg/net/rpc/jsonrpc/all_test.go b/src/net/rpc/jsonrpc/all_test.go
similarity index 100%
rename from src/pkg/net/rpc/jsonrpc/all_test.go
rename to src/net/rpc/jsonrpc/all_test.go
diff --git a/src/pkg/net/rpc/jsonrpc/client.go b/src/net/rpc/jsonrpc/client.go
similarity index 100%
rename from src/pkg/net/rpc/jsonrpc/client.go
rename to src/net/rpc/jsonrpc/client.go
diff --git a/src/pkg/net/rpc/jsonrpc/server.go b/src/net/rpc/jsonrpc/server.go
similarity index 100%
rename from src/pkg/net/rpc/jsonrpc/server.go
rename to src/net/rpc/jsonrpc/server.go
diff --git a/src/net/rpc/server.go b/src/net/rpc/server.go
new file mode 100644
index 0000000..83728d5
--- /dev/null
+++ b/src/net/rpc/server.go
@@ -0,0 +1,709 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+/*
+	Package rpc provides access to the exported methods of an object across a
+	network or other I/O connection.  A server registers an object, making it visible
+	as a service with the name of the type of the object.  After registration, exported
+	methods of the object will be accessible remotely.  A server may register multiple
+	objects (services) of different types but it is an error to register multiple
+	objects of the same type.
+
+	Only methods that satisfy these criteria will be made available for remote access;
+	other methods will be ignored:
+
+		- the method is exported.
+		- the method has two arguments, both exported (or builtin) types.
+		- the method's second argument is a pointer.
+		- the method has return type error.
+
+	In effect, the method must look schematically like
+
+		func (t *T) MethodName(argType T1, replyType *T2) error
+
+	where T, T1 and T2 can be marshaled by encoding/gob.
+	These requirements apply even if a different codec is used.
+	(In the future, these requirements may soften for custom codecs.)
+
+	The method's first argument represents the arguments provided by the caller; the
+	second argument represents the result parameters to be returned to the caller.
+	The method's return value, if non-nil, is passed back as a string that the client
+	sees as if created by errors.New.  If an error is returned, the reply parameter
+	will not be sent back to the client.
+
+	The server may handle requests on a single connection by calling ServeConn.  More
+	typically it will create a network listener and call Accept or, for an HTTP
+	listener, HandleHTTP and http.Serve.
+
+	A client wishing to use the service establishes a connection and then invokes
+	NewClient on the connection.  The convenience function Dial (DialHTTP) performs
+	both steps for a raw network connection (an HTTP connection).  The resulting
+	Client object has two methods, Call and Go, that specify the service and method to
+	call, a pointer containing the arguments, and a pointer to receive the result
+	parameters.
+
+	The Call method waits for the remote call to complete while the Go method
+	launches the call asynchronously and signals completion using the Call
+	structure's Done channel.
+
+	Unless an explicit codec is set up, package encoding/gob is used to
+	transport the data.
+
+	Here is a simple example.  A server wishes to export an object of type Arith:
+
+		package server
+
+		type Args struct {
+			A, B int
+		}
+
+		type Quotient struct {
+			Quo, Rem int
+		}
+
+		type Arith int
+
+		func (t *Arith) Multiply(args *Args, reply *int) error {
+			*reply = args.A * args.B
+			return nil
+		}
+
+		func (t *Arith) Divide(args *Args, quo *Quotient) error {
+			if args.B == 0 {
+				return errors.New("divide by zero")
+			}
+			quo.Quo = args.A / args.B
+			quo.Rem = args.A % args.B
+			return nil
+		}
+
+	The server calls (for HTTP service):
+
+		arith := new(Arith)
+		rpc.Register(arith)
+		rpc.HandleHTTP()
+		l, e := net.Listen("tcp", ":1234")
+		if e != nil {
+			log.Fatal("listen error:", e)
+		}
+		go http.Serve(l, nil)
+
+	At this point, clients can see a service "Arith" with methods "Arith.Multiply" and
+	"Arith.Divide".  To invoke one, a client first dials the server:
+
+		client, err := rpc.DialHTTP("tcp", serverAddress + ":1234")
+		if err != nil {
+			log.Fatal("dialing:", err)
+		}
+
+	Then it can make a remote call:
+
+		// Synchronous call
+		args := &server.Args{7,8}
+		var reply int
+		err = client.Call("Arith.Multiply", args, &reply)
+		if err != nil {
+			log.Fatal("arith error:", err)
+		}
+		fmt.Printf("Arith: %d*%d=%d", args.A, args.B, reply)
+
+	or
+
+		// Asynchronous call
+		quotient := new(Quotient)
+		divCall := client.Go("Arith.Divide", args, quotient, nil)
+		replyCall := <-divCall.Done	// will be equal to divCall
+		// check errors, print, etc.
+
+	A server implementation will often provide a simple, type-safe wrapper for the
+	client.
+*/
+package rpc
+
+import (
+	"bufio"
+	"encoding/gob"
+	"errors"
+	"io"
+	"log"
+	"net"
+	"net/http"
+	"reflect"
+	"strings"
+	"sync"
+	"unicode"
+	"unicode/utf8"
+)
+
+const (
+	// Defaults used by HandleHTTP
+	DefaultRPCPath   = "/_goRPC_"
+	DefaultDebugPath = "/debug/rpc"
+)
+
+// Precompute the reflect type for error.  Can't use error directly
+// because Typeof takes an empty interface value.  This is annoying.
+var typeOfError = reflect.TypeOf((*error)(nil)).Elem()
+
+type methodType struct {
+	sync.Mutex // protects counters
+	method     reflect.Method
+	ArgType    reflect.Type
+	ReplyType  reflect.Type
+	numCalls   uint
+}
+
+type service struct {
+	name   string                 // name of service
+	rcvr   reflect.Value          // receiver of methods for the service
+	typ    reflect.Type           // type of the receiver
+	method map[string]*methodType // registered methods
+}
+
+// Request is a header written before every RPC call.  It is used internally
+// but documented here as an aid to debugging, such as when analyzing
+// network traffic.
+type Request struct {
+	ServiceMethod string   // format: "Service.Method"
+	Seq           uint64   // sequence number chosen by client
+	next          *Request // for free list in Server
+}
+
+// Response is a header written before every RPC return.  It is used internally
+// but documented here as an aid to debugging, such as when analyzing
+// network traffic.
+type Response struct {
+	ServiceMethod string    // echoes that of the Request
+	Seq           uint64    // echoes that of the request
+	Error         string    // error, if any.
+	next          *Response // for free list in Server
+}
+
+// Server represents an RPC Server.
+type Server struct {
+	mu         sync.RWMutex // protects the serviceMap
+	serviceMap map[string]*service
+	reqLock    sync.Mutex // protects freeReq
+	freeReq    *Request
+	respLock   sync.Mutex // protects freeResp
+	freeResp   *Response
+}
+
+// NewServer returns a new Server.
+func NewServer() *Server {
+	return &Server{serviceMap: make(map[string]*service)}
+}
+
+// DefaultServer is the default instance of *Server.
+var DefaultServer = NewServer()
+
+// Is this an exported - upper case - name?
+func isExported(name string) bool {
+	rune, _ := utf8.DecodeRuneInString(name)
+	return unicode.IsUpper(rune)
+}
+
+// Is this type exported or a builtin?
+func isExportedOrBuiltinType(t reflect.Type) bool {
+	for t.Kind() == reflect.Ptr {
+		t = t.Elem()
+	}
+	// PkgPath will be non-empty even for an exported type,
+	// so we need to check the type name as well.
+	return isExported(t.Name()) || t.PkgPath() == ""
+}
+
+// Register publishes in the server the set of methods of the
+// receiver value that satisfy the following conditions:
+//	- exported method
+//	- two arguments, both of exported type
+//	- the second argument is a pointer
+//	- one return value, of type error
+// It returns an error if the receiver is not an exported type or has
+// no suitable methods. It also logs the error using package log.
+// The client accesses each method using a string of the form "Type.Method",
+// where Type is the receiver's concrete type.
+func (server *Server) Register(rcvr interface{}) error {
+	return server.register(rcvr, "", false)
+}
+
+// RegisterName is like Register but uses the provided name for the type
+// instead of the receiver's concrete type.
+func (server *Server) RegisterName(name string, rcvr interface{}) error {
+	return server.register(rcvr, name, true)
+}
+
+func (server *Server) register(rcvr interface{}, name string, useName bool) error {
+	server.mu.Lock()
+	defer server.mu.Unlock()
+	if server.serviceMap == nil {
+		server.serviceMap = make(map[string]*service)
+	}
+	s := new(service)
+	s.typ = reflect.TypeOf(rcvr)
+	s.rcvr = reflect.ValueOf(rcvr)
+	sname := reflect.Indirect(s.rcvr).Type().Name()
+	if useName {
+		sname = name
+	}
+	if sname == "" {
+		s := "rpc.Register: no service name for type " + s.typ.String()
+		log.Print(s)
+		return errors.New(s)
+	}
+	if !isExported(sname) && !useName {
+		s := "rpc.Register: type " + sname + " is not exported"
+		log.Print(s)
+		return errors.New(s)
+	}
+	if _, present := server.serviceMap[sname]; present {
+		return errors.New("rpc: service already defined: " + sname)
+	}
+	s.name = sname
+
+	// Install the methods
+	s.method = suitableMethods(s.typ, true)
+
+	if len(s.method) == 0 {
+		str := ""
+
+		// To help the user, see if a pointer receiver would work.
+		method := suitableMethods(reflect.PtrTo(s.typ), false)
+		if len(method) != 0 {
+			str = "rpc.Register: type " + sname + " has no exported methods of suitable type (hint: pass a pointer to value of that type)"
+		} else {
+			str = "rpc.Register: type " + sname + " has no exported methods of suitable type"
+		}
+		log.Print(str)
+		return errors.New(str)
+	}
+	server.serviceMap[s.name] = s
+	return nil
+}
+
+// suitableMethods returns suitable Rpc methods of typ, it will report
+// error using log if reportErr is true.
+func suitableMethods(typ reflect.Type, reportErr bool) map[string]*methodType {
+	methods := make(map[string]*methodType)
+	for m := 0; m < typ.NumMethod(); m++ {
+		method := typ.Method(m)
+		mtype := method.Type
+		mname := method.Name
+		// Method must be exported.
+		if method.PkgPath != "" {
+			continue
+		}
+		// Method needs three ins: receiver, *args, *reply.
+		if mtype.NumIn() != 3 {
+			if reportErr {
+				log.Println("method", mname, "has wrong number of ins:", mtype.NumIn())
+			}
+			continue
+		}
+		// First arg need not be a pointer.
+		argType := mtype.In(1)
+		if !isExportedOrBuiltinType(argType) {
+			if reportErr {
+				log.Println(mname, "argument type not exported:", argType)
+			}
+			continue
+		}
+		// Second arg must be a pointer.
+		replyType := mtype.In(2)
+		if replyType.Kind() != reflect.Ptr {
+			if reportErr {
+				log.Println("method", mname, "reply type not a pointer:", replyType)
+			}
+			continue
+		}
+		// Reply type must be exported.
+		if !isExportedOrBuiltinType(replyType) {
+			if reportErr {
+				log.Println("method", mname, "reply type not exported:", replyType)
+			}
+			continue
+		}
+		// Method needs one out.
+		if mtype.NumOut() != 1 {
+			if reportErr {
+				log.Println("method", mname, "has wrong number of outs:", mtype.NumOut())
+			}
+			continue
+		}
+		// The return type of the method must be error.
+		if returnType := mtype.Out(0); returnType != typeOfError {
+			if reportErr {
+				log.Println("method", mname, "returns", returnType.String(), "not error")
+			}
+			continue
+		}
+		methods[mname] = &methodType{method: method, ArgType: argType, ReplyType: replyType}
+	}
+	return methods
+}
+
+// A value sent as a placeholder for the server's response value when the server
+// receives an invalid request. It is never decoded by the client since the Response
+// contains an error when it is used.
+var invalidRequest = struct{}{}
+
+func (server *Server) sendResponse(sending *sync.Mutex, req *Request, reply interface{}, codec ServerCodec, errmsg string) {
+	resp := server.getResponse()
+	// Encode the response header
+	resp.ServiceMethod = req.ServiceMethod
+	if errmsg != "" {
+		resp.Error = errmsg
+		reply = invalidRequest
+	}
+	resp.Seq = req.Seq
+	sending.Lock()
+	err := codec.WriteResponse(resp, reply)
+	if debugLog && err != nil {
+		log.Println("rpc: writing response:", err)
+	}
+	sending.Unlock()
+	server.freeResponse(resp)
+}
+
+func (m *methodType) NumCalls() (n uint) {
+	m.Lock()
+	n = m.numCalls
+	m.Unlock()
+	return n
+}
+
+func (s *service) call(server *Server, sending *sync.Mutex, mtype *methodType, req *Request, argv, replyv reflect.Value, codec ServerCodec) {
+	mtype.Lock()
+	mtype.numCalls++
+	mtype.Unlock()
+	function := mtype.method.Func
+	// Invoke the method, providing a new value for the reply.
+	returnValues := function.Call([]reflect.Value{s.rcvr, argv, replyv})
+	// The return value for the method is an error.
+	errInter := returnValues[0].Interface()
+	errmsg := ""
+	if errInter != nil {
+		errmsg = errInter.(error).Error()
+	}
+	server.sendResponse(sending, req, replyv.Interface(), codec, errmsg)
+	server.freeRequest(req)
+}
+
+type gobServerCodec struct {
+	rwc    io.ReadWriteCloser
+	dec    *gob.Decoder
+	enc    *gob.Encoder
+	encBuf *bufio.Writer
+	closed bool
+}
+
+func (c *gobServerCodec) ReadRequestHeader(r *Request) error {
+	return c.dec.Decode(r)
+}
+
+func (c *gobServerCodec) ReadRequestBody(body interface{}) error {
+	return c.dec.Decode(body)
+}
+
+func (c *gobServerCodec) WriteResponse(r *Response, body interface{}) (err error) {
+	if err = c.enc.Encode(r); err != nil {
+		if c.encBuf.Flush() == nil {
+			// Gob couldn't encode the header. Should not happen, so if it does,
+			// shut down the connection to signal that the connection is broken.
+			log.Println("rpc: gob error encoding response:", err)
+			c.Close()
+		}
+		return
+	}
+	if err = c.enc.Encode(body); err != nil {
+		if c.encBuf.Flush() == nil {
+			// Was a gob problem encoding the body but the header has been written.
+			// Shut down the connection to signal that the connection is broken.
+			log.Println("rpc: gob error encoding body:", err)
+			c.Close()
+		}
+		return
+	}
+	return c.encBuf.Flush()
+}
+
+func (c *gobServerCodec) Close() error {
+	if c.closed {
+		// Only call c.rwc.Close once; otherwise the semantics are undefined.
+		return nil
+	}
+	c.closed = true
+	return c.rwc.Close()
+}
+
+// ServeConn runs the server on a single connection.
+// ServeConn blocks, serving the connection until the client hangs up.
+// The caller typically invokes ServeConn in a go statement.
+// ServeConn uses the gob wire format (see package gob) on the
+// connection.  To use an alternate codec, use ServeCodec.
+func (server *Server) ServeConn(conn io.ReadWriteCloser) {
+	buf := bufio.NewWriter(conn)
+	srv := &gobServerCodec{
+		rwc:    conn,
+		dec:    gob.NewDecoder(conn),
+		enc:    gob.NewEncoder(buf),
+		encBuf: buf,
+	}
+	server.ServeCodec(srv)
+}
+
+// ServeCodec is like ServeConn but uses the specified codec to
+// decode requests and encode responses.
+func (server *Server) ServeCodec(codec ServerCodec) {
+	sending := new(sync.Mutex)
+	for {
+		service, mtype, req, argv, replyv, keepReading, err := server.readRequest(codec)
+		if err != nil {
+			if debugLog && err != io.EOF {
+				log.Println("rpc:", err)
+			}
+			if !keepReading {
+				break
+			}
+			// send a response if we actually managed to read a header.
+			if req != nil {
+				server.sendResponse(sending, req, invalidRequest, codec, err.Error())
+				server.freeRequest(req)
+			}
+			continue
+		}
+		go service.call(server, sending, mtype, req, argv, replyv, codec)
+	}
+	codec.Close()
+}
+
+// ServeRequest is like ServeCodec but synchronously serves a single request.
+// It does not close the codec upon completion.
+func (server *Server) ServeRequest(codec ServerCodec) error {
+	sending := new(sync.Mutex)
+	service, mtype, req, argv, replyv, keepReading, err := server.readRequest(codec)
+	if err != nil {
+		if !keepReading {
+			return err
+		}
+		// send a response if we actually managed to read a header.
+		if req != nil {
+			server.sendResponse(sending, req, invalidRequest, codec, err.Error())
+			server.freeRequest(req)
+		}
+		return err
+	}
+	service.call(server, sending, mtype, req, argv, replyv, codec)
+	return nil
+}
+
+func (server *Server) getRequest() *Request {
+	server.reqLock.Lock()
+	req := server.freeReq
+	if req == nil {
+		req = new(Request)
+	} else {
+		server.freeReq = req.next
+		*req = Request{}
+	}
+	server.reqLock.Unlock()
+	return req
+}
+
+func (server *Server) freeRequest(req *Request) {
+	server.reqLock.Lock()
+	req.next = server.freeReq
+	server.freeReq = req
+	server.reqLock.Unlock()
+}
+
+func (server *Server) getResponse() *Response {
+	server.respLock.Lock()
+	resp := server.freeResp
+	if resp == nil {
+		resp = new(Response)
+	} else {
+		server.freeResp = resp.next
+		*resp = Response{}
+	}
+	server.respLock.Unlock()
+	return resp
+}
+
+func (server *Server) freeResponse(resp *Response) {
+	server.respLock.Lock()
+	resp.next = server.freeResp
+	server.freeResp = resp
+	server.respLock.Unlock()
+}
+
+func (server *Server) readRequest(codec ServerCodec) (service *service, mtype *methodType, req *Request, argv, replyv reflect.Value, keepReading bool, err error) {
+	service, mtype, req, keepReading, err = server.readRequestHeader(codec)
+	if err != nil {
+		if !keepReading {
+			return
+		}
+		// discard body
+		codec.ReadRequestBody(nil)
+		return
+	}
+
+	// Decode the argument value.
+	argIsValue := false // if true, need to indirect before calling.
+	if mtype.ArgType.Kind() == reflect.Ptr {
+		argv = reflect.New(mtype.ArgType.Elem())
+	} else {
+		argv = reflect.New(mtype.ArgType)
+		argIsValue = true
+	}
+	// argv guaranteed to be a pointer now.
+	if err = codec.ReadRequestBody(argv.Interface()); err != nil {
+		return
+	}
+	if argIsValue {
+		argv = argv.Elem()
+	}
+
+	replyv = reflect.New(mtype.ReplyType.Elem())
+	return
+}
+
+func (server *Server) readRequestHeader(codec ServerCodec) (service *service, mtype *methodType, req *Request, keepReading bool, err error) {
+	// Grab the request header.
+	req = server.getRequest()
+	err = codec.ReadRequestHeader(req)
+	if err != nil {
+		req = nil
+		if err == io.EOF || err == io.ErrUnexpectedEOF {
+			return
+		}
+		err = errors.New("rpc: server cannot decode request: " + err.Error())
+		return
+	}
+
+	// We read the header successfully.  If we see an error now,
+	// we can still recover and move on to the next request.
+	keepReading = true
+
+	dot := strings.LastIndex(req.ServiceMethod, ".")
+	if dot < 0 {
+		err = errors.New("rpc: service/method request ill-formed: " + req.ServiceMethod)
+		return
+	}
+	serviceName := req.ServiceMethod[:dot]
+	methodName := req.ServiceMethod[dot+1:]
+
+	// Look up the request.
+	server.mu.RLock()
+	service = server.serviceMap[serviceName]
+	server.mu.RUnlock()
+	if service == nil {
+		err = errors.New("rpc: can't find service " + req.ServiceMethod)
+		return
+	}
+	mtype = service.method[methodName]
+	if mtype == nil {
+		err = errors.New("rpc: can't find method " + req.ServiceMethod)
+	}
+	return
+}
+
+// Accept accepts connections on the listener and serves requests
+// for each incoming connection.  Accept blocks; the caller typically
+// invokes it in a go statement.
+func (server *Server) Accept(lis net.Listener) {
+	for {
+		conn, err := lis.Accept()
+		if err != nil {
+			log.Fatal("rpc.Serve: accept:", err.Error()) // TODO(r): exit?
+		}
+		go server.ServeConn(conn)
+	}
+}
+
+// Register publishes the receiver's methods in the DefaultServer.
+func Register(rcvr interface{}) error { return DefaultServer.Register(rcvr) }
+
+// RegisterName is like Register but uses the provided name for the type
+// instead of the receiver's concrete type.
+func RegisterName(name string, rcvr interface{}) error {
+	return DefaultServer.RegisterName(name, rcvr)
+}
+
+// A ServerCodec implements reading of RPC requests and writing of
+// RPC responses for the server side of an RPC session.
+// The server calls ReadRequestHeader and ReadRequestBody in pairs
+// to read requests from the connection, and it calls WriteResponse to
+// write a response back.  The server calls Close when finished with the
+// connection. ReadRequestBody may be called with a nil
+// argument to force the body of the request to be read and discarded.
+type ServerCodec interface {
+	ReadRequestHeader(*Request) error
+	ReadRequestBody(interface{}) error
+	// WriteResponse must be safe for concurrent use by multiple goroutines.
+	WriteResponse(*Response, interface{}) error
+
+	Close() error
+}
+
+// ServeConn runs the DefaultServer on a single connection.
+// ServeConn blocks, serving the connection until the client hangs up.
+// The caller typically invokes ServeConn in a go statement.
+// ServeConn uses the gob wire format (see package gob) on the
+// connection.  To use an alternate codec, use ServeCodec.
+func ServeConn(conn io.ReadWriteCloser) {
+	DefaultServer.ServeConn(conn)
+}
+
+// ServeCodec is like ServeConn but uses the specified codec to
+// decode requests and encode responses.
+func ServeCodec(codec ServerCodec) {
+	DefaultServer.ServeCodec(codec)
+}
+
+// ServeRequest is like ServeCodec but synchronously serves a single request.
+// It does not close the codec upon completion.
+func ServeRequest(codec ServerCodec) error {
+	return DefaultServer.ServeRequest(codec)
+}
+
+// Accept accepts connections on the listener and serves requests
+// to DefaultServer for each incoming connection.
+// Accept blocks; the caller typically invokes it in a go statement.
+func Accept(lis net.Listener) { DefaultServer.Accept(lis) }
+
+// Can connect to RPC service using HTTP CONNECT to rpcPath.
+var connected = "200 Connected to Go RPC"
+
+// ServeHTTP implements an http.Handler that answers RPC requests.
+func (server *Server) ServeHTTP(w http.ResponseWriter, req *http.Request) {
+	if req.Method != "CONNECT" {
+		w.Header().Set("Content-Type", "text/plain; charset=utf-8")
+		w.WriteHeader(http.StatusMethodNotAllowed)
+		io.WriteString(w, "405 must CONNECT\n")
+		return
+	}
+	conn, _, err := w.(http.Hijacker).Hijack()
+	if err != nil {
+		log.Print("rpc hijacking ", req.RemoteAddr, ": ", err.Error())
+		return
+	}
+	io.WriteString(conn, "HTTP/1.0 "+connected+"\n\n")
+	server.ServeConn(conn)
+}
+
+// HandleHTTP registers an HTTP handler for RPC messages on rpcPath,
+// and a debugging handler on debugPath.
+// It is still necessary to invoke http.Serve(), typically in a go statement.
+func (server *Server) HandleHTTP(rpcPath, debugPath string) {
+	http.Handle(rpcPath, server)
+	http.Handle(debugPath, debugHTTP{server})
+}
+
+// HandleHTTP registers an HTTP handler for RPC messages to DefaultServer
+// on DefaultRPCPath and a debugging handler on DefaultDebugPath.
+// It is still necessary to invoke http.Serve(), typically in a go statement.
+func HandleHTTP() {
+	DefaultServer.HandleHTTP(DefaultRPCPath, DefaultDebugPath)
+}
diff --git a/src/pkg/net/rpc/server_test.go b/src/net/rpc/server_test.go
similarity index 100%
rename from src/pkg/net/rpc/server_test.go
rename to src/net/rpc/server_test.go
diff --git a/src/pkg/net/sendfile_dragonfly.go b/src/net/sendfile_dragonfly.go
similarity index 100%
rename from src/pkg/net/sendfile_dragonfly.go
rename to src/net/sendfile_dragonfly.go
diff --git a/src/pkg/net/sendfile_freebsd.go b/src/net/sendfile_freebsd.go
similarity index 100%
rename from src/pkg/net/sendfile_freebsd.go
rename to src/net/sendfile_freebsd.go
diff --git a/src/pkg/net/sendfile_linux.go b/src/net/sendfile_linux.go
similarity index 100%
rename from src/pkg/net/sendfile_linux.go
rename to src/net/sendfile_linux.go
diff --git a/src/pkg/net/sendfile_stub.go b/src/net/sendfile_stub.go
similarity index 100%
rename from src/pkg/net/sendfile_stub.go
rename to src/net/sendfile_stub.go
diff --git a/src/pkg/net/sendfile_windows.go b/src/net/sendfile_windows.go
similarity index 100%
rename from src/pkg/net/sendfile_windows.go
rename to src/net/sendfile_windows.go
diff --git a/src/pkg/net/server_test.go b/src/net/server_test.go
similarity index 100%
rename from src/pkg/net/server_test.go
rename to src/net/server_test.go
diff --git a/src/net/singleflight.go b/src/net/singleflight.go
new file mode 100644
index 0000000..bf599f0
--- /dev/null
+++ b/src/net/singleflight.go
@@ -0,0 +1,109 @@
+// Copyright 2013 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package net
+
+import "sync"
+
+// call is an in-flight or completed singleflight.Do call
+type call struct {
+	wg sync.WaitGroup
+
+	// These fields are written once before the WaitGroup is done
+	// and are only read after the WaitGroup is done.
+	val interface{}
+	err error
+
+	// These fields are read and written with the singleflight
+	// mutex held before the WaitGroup is done, and are read but
+	// not written after the WaitGroup is done.
+	dups  int
+	chans []chan<- singleflightResult
+}
+
+// singleflight represents a class of work and forms a namespace in
+// which units of work can be executed with duplicate suppression.
+type singleflight struct {
+	mu sync.Mutex       // protects m
+	m  map[string]*call // lazily initialized
+}
+
+// singleflightResult holds the results of Do, so they can be passed
+// on a channel.
+type singleflightResult struct {
+	v      interface{}
+	err    error
+	shared bool
+}
+
+// Do executes and returns the results of the given function, making
+// sure that only one execution is in-flight for a given key at a
+// time. If a duplicate comes in, the duplicate caller waits for the
+// original to complete and receives the same results.
+// The return value shared indicates whether v was given to multiple callers.
+func (g *singleflight) Do(key string, fn func() (interface{}, error)) (v interface{}, err error, shared bool) {
+	g.mu.Lock()
+	if g.m == nil {
+		g.m = make(map[string]*call)
+	}
+	if c, ok := g.m[key]; ok {
+		c.dups++
+		g.mu.Unlock()
+		c.wg.Wait()
+		return c.val, c.err, true
+	}
+	c := new(call)
+	c.wg.Add(1)
+	g.m[key] = c
+	g.mu.Unlock()
+
+	g.doCall(c, key, fn)
+	return c.val, c.err, c.dups > 0
+}
+
+// DoChan is like Do but returns a channel that will receive the
+// results when they are ready.
+func (g *singleflight) DoChan(key string, fn func() (interface{}, error)) <-chan singleflightResult {
+	ch := make(chan singleflightResult, 1)
+	g.mu.Lock()
+	if g.m == nil {
+		g.m = make(map[string]*call)
+	}
+	if c, ok := g.m[key]; ok {
+		c.dups++
+		c.chans = append(c.chans, ch)
+		g.mu.Unlock()
+		return ch
+	}
+	c := &call{chans: []chan<- singleflightResult{ch}}
+	c.wg.Add(1)
+	g.m[key] = c
+	g.mu.Unlock()
+
+	go g.doCall(c, key, fn)
+
+	return ch
+}
+
+// doCall handles the single call for a key.
+func (g *singleflight) doCall(c *call, key string, fn func() (interface{}, error)) {
+	c.val, c.err = fn()
+	c.wg.Done()
+
+	g.mu.Lock()
+	delete(g.m, key)
+	for _, ch := range c.chans {
+		ch <- singleflightResult{c.val, c.err, c.dups > 0}
+	}
+	g.mu.Unlock()
+}
+
+// Forget tells the singleflight to forget about a key.  Future calls
+// to Do for this key will call the function rather than waiting for
+// an earlier call to complete.
+func (g *singleflight) Forget(key string) {
+	g.mu.Lock()
+	delete(g.m, key)
+	g.mu.Unlock()
+}
diff --git a/src/pkg/net/smtp/auth.go b/src/net/smtp/auth.go
similarity index 100%
rename from src/pkg/net/smtp/auth.go
rename to src/net/smtp/auth.go
diff --git a/src/pkg/net/smtp/example_test.go b/src/net/smtp/example_test.go
similarity index 100%
rename from src/pkg/net/smtp/example_test.go
rename to src/net/smtp/example_test.go
diff --git a/src/pkg/net/smtp/smtp.go b/src/net/smtp/smtp.go
similarity index 100%
rename from src/pkg/net/smtp/smtp.go
rename to src/net/smtp/smtp.go
diff --git a/src/net/smtp/smtp_test.go b/src/net/smtp/smtp_test.go
new file mode 100644
index 0000000..5c659e8
--- /dev/null
+++ b/src/net/smtp/smtp_test.go
@@ -0,0 +1,694 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package smtp
+
+import (
+	"bufio"
+	"bytes"
+	"crypto/tls"
+	"crypto/x509"
+	"io"
+	"net"
+	"net/textproto"
+	"strings"
+	"testing"
+	"time"
+)
+
+type authTest struct {
+	auth       Auth
+	challenges []string
+	name       string
+	responses  []string
+}
+
+var authTests = []authTest{
+	{PlainAuth("", "user", "pass", "testserver"), []string{}, "PLAIN", []string{"\x00user\x00pass"}},
+	{PlainAuth("foo", "bar", "baz", "testserver"), []string{}, "PLAIN", []string{"foo\x00bar\x00baz"}},
+	{CRAMMD5Auth("user", "pass"), []string{"<123456.1322876914 at testserver>"}, "CRAM-MD5", []string{"", "user 287eb355114cf5c471c26a875f1ca4ae"}},
+}
+
+func TestAuth(t *testing.T) {
+testLoop:
+	for i, test := range authTests {
+		name, resp, err := test.auth.Start(&ServerInfo{"testserver", true, nil})
+		if name != test.name {
+			t.Errorf("#%d got name %s, expected %s", i, name, test.name)
+		}
+		if !bytes.Equal(resp, []byte(test.responses[0])) {
+			t.Errorf("#%d got response %s, expected %s", i, resp, test.responses[0])
+		}
+		if err != nil {
+			t.Errorf("#%d error: %s", i, err)
+		}
+		for j := range test.challenges {
+			challenge := []byte(test.challenges[j])
+			expected := []byte(test.responses[j+1])
+			resp, err := test.auth.Next(challenge, true)
+			if err != nil {
+				t.Errorf("#%d error: %s", i, err)
+				continue testLoop
+			}
+			if !bytes.Equal(resp, expected) {
+				t.Errorf("#%d got %s, expected %s", i, resp, expected)
+				continue testLoop
+			}
+		}
+	}
+}
+
+func TestAuthPlain(t *testing.T) {
+	auth := PlainAuth("foo", "bar", "baz", "servername")
+
+	tests := []struct {
+		server *ServerInfo
+		err    string
+	}{
+		{
+			server: &ServerInfo{Name: "servername", TLS: true},
+		},
+		{
+			// Okay; explicitly advertised by server.
+			server: &ServerInfo{Name: "servername", Auth: []string{"PLAIN"}},
+		},
+		{
+			server: &ServerInfo{Name: "servername", Auth: []string{"CRAM-MD5"}},
+			err:    "unencrypted connection",
+		},
+		{
+			server: &ServerInfo{Name: "attacker", TLS: true},
+			err:    "wrong host name",
+		},
+	}
+	for i, tt := range tests {
+		_, _, err := auth.Start(tt.server)
+		got := ""
+		if err != nil {
+			got = err.Error()
+		}
+		if got != tt.err {
+			t.Errorf("%d. got error = %q; want %q", i, got, tt.err)
+		}
+	}
+}
+
+type faker struct {
+	io.ReadWriter
+}
+
+func (f faker) Close() error                     { return nil }
+func (f faker) LocalAddr() net.Addr              { return nil }
+func (f faker) RemoteAddr() net.Addr             { return nil }
+func (f faker) SetDeadline(time.Time) error      { return nil }
+func (f faker) SetReadDeadline(time.Time) error  { return nil }
+func (f faker) SetWriteDeadline(time.Time) error { return nil }
+
+func TestBasic(t *testing.T) {
+	server := strings.Join(strings.Split(basicServer, "\n"), "\r\n")
+	client := strings.Join(strings.Split(basicClient, "\n"), "\r\n")
+
+	var cmdbuf bytes.Buffer
+	bcmdbuf := bufio.NewWriter(&cmdbuf)
+	var fake faker
+	fake.ReadWriter = bufio.NewReadWriter(bufio.NewReader(strings.NewReader(server)), bcmdbuf)
+	c := &Client{Text: textproto.NewConn(fake), localName: "localhost"}
+
+	if err := c.helo(); err != nil {
+		t.Fatalf("HELO failed: %s", err)
+	}
+	if err := c.ehlo(); err == nil {
+		t.Fatalf("Expected first EHLO to fail")
+	}
+	if err := c.ehlo(); err != nil {
+		t.Fatalf("Second EHLO failed: %s", err)
+	}
+
+	c.didHello = true
+	if ok, args := c.Extension("aUtH"); !ok || args != "LOGIN PLAIN" {
+		t.Fatalf("Expected AUTH supported")
+	}
+	if ok, _ := c.Extension("DSN"); ok {
+		t.Fatalf("Shouldn't support DSN")
+	}
+
+	if err := c.Mail("user at gmail.com"); err == nil {
+		t.Fatalf("MAIL should require authentication")
+	}
+
+	if err := c.Verify("user1 at gmail.com"); err == nil {
+		t.Fatalf("First VRFY: expected no verification")
+	}
+	if err := c.Verify("user2 at gmail.com"); err != nil {
+		t.Fatalf("Second VRFY: expected verification, got %s", err)
+	}
+
+	// fake TLS so authentication won't complain
+	c.tls = true
+	c.serverName = "smtp.google.com"
+	if err := c.Auth(PlainAuth("", "user", "pass", "smtp.google.com")); err != nil {
+		t.Fatalf("AUTH failed: %s", err)
+	}
+
+	if err := c.Mail("user at gmail.com"); err != nil {
+		t.Fatalf("MAIL failed: %s", err)
+	}
+	if err := c.Rcpt("golang-nuts at googlegroups.com"); err != nil {
+		t.Fatalf("RCPT failed: %s", err)
+	}
+	msg := `From: user at gmail.com
+To: golang-nuts at googlegroups.com
+Subject: Hooray for Go
+
+Line 1
+.Leading dot line .
+Goodbye.`
+	w, err := c.Data()
+	if err != nil {
+		t.Fatalf("DATA failed: %s", err)
+	}
+	if _, err := w.Write([]byte(msg)); err != nil {
+		t.Fatalf("Data write failed: %s", err)
+	}
+	if err := w.Close(); err != nil {
+		t.Fatalf("Bad data response: %s", err)
+	}
+
+	if err := c.Quit(); err != nil {
+		t.Fatalf("QUIT failed: %s", err)
+	}
+
+	bcmdbuf.Flush()
+	actualcmds := cmdbuf.String()
+	if client != actualcmds {
+		t.Fatalf("Got:\n%s\nExpected:\n%s", actualcmds, client)
+	}
+}
+
+var basicServer = `250 mx.google.com at your service
+502 Unrecognized command.
+250-mx.google.com at your service
+250-SIZE 35651584
+250-AUTH LOGIN PLAIN
+250 8BITMIME
+530 Authentication required
+252 Send some mail, I'll try my best
+250 User is valid
+235 Accepted
+250 Sender OK
+250 Receiver OK
+354 Go ahead
+250 Data OK
+221 OK
+`
+
+var basicClient = `HELO localhost
+EHLO localhost
+EHLO localhost
+MAIL FROM:<user at gmail.com> BODY=8BITMIME
+VRFY user1 at gmail.com
+VRFY user2 at gmail.com
+AUTH PLAIN AHVzZXIAcGFzcw==
+MAIL FROM:<user at gmail.com> BODY=8BITMIME
+RCPT TO:<golang-nuts at googlegroups.com>
+DATA
+From: user at gmail.com
+To: golang-nuts at googlegroups.com
+Subject: Hooray for Go
+
+Line 1
+..Leading dot line .
+Goodbye.
+.
+QUIT
+`
+
+func TestNewClient(t *testing.T) {
+	server := strings.Join(strings.Split(newClientServer, "\n"), "\r\n")
+	client := strings.Join(strings.Split(newClientClient, "\n"), "\r\n")
+
+	var cmdbuf bytes.Buffer
+	bcmdbuf := bufio.NewWriter(&cmdbuf)
+	out := func() string {
+		bcmdbuf.Flush()
+		return cmdbuf.String()
+	}
+	var fake faker
+	fake.ReadWriter = bufio.NewReadWriter(bufio.NewReader(strings.NewReader(server)), bcmdbuf)
+	c, err := NewClient(fake, "fake.host")
+	if err != nil {
+		t.Fatalf("NewClient: %v\n(after %v)", err, out())
+	}
+	defer c.Close()
+	if ok, args := c.Extension("aUtH"); !ok || args != "LOGIN PLAIN" {
+		t.Fatalf("Expected AUTH supported")
+	}
+	if ok, _ := c.Extension("DSN"); ok {
+		t.Fatalf("Shouldn't support DSN")
+	}
+	if err := c.Quit(); err != nil {
+		t.Fatalf("QUIT failed: %s", err)
+	}
+
+	actualcmds := out()
+	if client != actualcmds {
+		t.Fatalf("Got:\n%s\nExpected:\n%s", actualcmds, client)
+	}
+}
+
+var newClientServer = `220 hello world
+250-mx.google.com at your service
+250-SIZE 35651584
+250-AUTH LOGIN PLAIN
+250 8BITMIME
+221 OK
+`
+
+var newClientClient = `EHLO localhost
+QUIT
+`
+
+func TestNewClient2(t *testing.T) {
+	server := strings.Join(strings.Split(newClient2Server, "\n"), "\r\n")
+	client := strings.Join(strings.Split(newClient2Client, "\n"), "\r\n")
+
+	var cmdbuf bytes.Buffer
+	bcmdbuf := bufio.NewWriter(&cmdbuf)
+	var fake faker
+	fake.ReadWriter = bufio.NewReadWriter(bufio.NewReader(strings.NewReader(server)), bcmdbuf)
+	c, err := NewClient(fake, "fake.host")
+	if err != nil {
+		t.Fatalf("NewClient: %v", err)
+	}
+	defer c.Close()
+	if ok, _ := c.Extension("DSN"); ok {
+		t.Fatalf("Shouldn't support DSN")
+	}
+	if err := c.Quit(); err != nil {
+		t.Fatalf("QUIT failed: %s", err)
+	}
+
+	bcmdbuf.Flush()
+	actualcmds := cmdbuf.String()
+	if client != actualcmds {
+		t.Fatalf("Got:\n%s\nExpected:\n%s", actualcmds, client)
+	}
+}
+
+var newClient2Server = `220 hello world
+502 EH?
+250-mx.google.com at your service
+250-SIZE 35651584
+250-AUTH LOGIN PLAIN
+250 8BITMIME
+221 OK
+`
+
+var newClient2Client = `EHLO localhost
+HELO localhost
+QUIT
+`
+
+func TestHello(t *testing.T) {
+
+	if len(helloServer) != len(helloClient) {
+		t.Fatalf("Hello server and client size mismatch")
+	}
+
+	for i := 0; i < len(helloServer); i++ {
+		server := strings.Join(strings.Split(baseHelloServer+helloServer[i], "\n"), "\r\n")
+		client := strings.Join(strings.Split(baseHelloClient+helloClient[i], "\n"), "\r\n")
+		var cmdbuf bytes.Buffer
+		bcmdbuf := bufio.NewWriter(&cmdbuf)
+		var fake faker
+		fake.ReadWriter = bufio.NewReadWriter(bufio.NewReader(strings.NewReader(server)), bcmdbuf)
+		c, err := NewClient(fake, "fake.host")
+		if err != nil {
+			t.Fatalf("NewClient: %v", err)
+		}
+		defer c.Close()
+		c.localName = "customhost"
+		err = nil
+
+		switch i {
+		case 0:
+			err = c.Hello("customhost")
+		case 1:
+			err = c.StartTLS(nil)
+			if err.Error() == "502 Not implemented" {
+				err = nil
+			}
+		case 2:
+			err = c.Verify("test at example.com")
+		case 3:
+			c.tls = true
+			c.serverName = "smtp.google.com"
+			err = c.Auth(PlainAuth("", "user", "pass", "smtp.google.com"))
+		case 4:
+			err = c.Mail("test at example.com")
+		case 5:
+			ok, _ := c.Extension("feature")
+			if ok {
+				t.Errorf("Expected FEATURE not to be supported")
+			}
+		case 6:
+			err = c.Reset()
+		case 7:
+			err = c.Quit()
+		case 8:
+			err = c.Verify("test at example.com")
+			if err != nil {
+				err = c.Hello("customhost")
+				if err != nil {
+					t.Errorf("Want error, got none")
+				}
+			}
+		default:
+			t.Fatalf("Unhandled command")
+		}
+
+		if err != nil {
+			t.Errorf("Command %d failed: %v", i, err)
+		}
+
+		bcmdbuf.Flush()
+		actualcmds := cmdbuf.String()
+		if client != actualcmds {
+			t.Errorf("Got:\n%s\nExpected:\n%s", actualcmds, client)
+		}
+	}
+}
+
+var baseHelloServer = `220 hello world
+502 EH?
+250-mx.google.com at your service
+250 FEATURE
+`
+
+var helloServer = []string{
+	"",
+	"502 Not implemented\n",
+	"250 User is valid\n",
+	"235 Accepted\n",
+	"250 Sender ok\n",
+	"",
+	"250 Reset ok\n",
+	"221 Goodbye\n",
+	"250 Sender ok\n",
+}
+
+var baseHelloClient = `EHLO customhost
+HELO customhost
+`
+
+var helloClient = []string{
+	"",
+	"STARTTLS\n",
+	"VRFY test at example.com\n",
+	"AUTH PLAIN AHVzZXIAcGFzcw==\n",
+	"MAIL FROM:<test at example.com>\n",
+	"",
+	"RSET\n",
+	"QUIT\n",
+	"VRFY test at example.com\n",
+}
+
+func TestSendMail(t *testing.T) {
+	server := strings.Join(strings.Split(sendMailServer, "\n"), "\r\n")
+	client := strings.Join(strings.Split(sendMailClient, "\n"), "\r\n")
+	var cmdbuf bytes.Buffer
+	bcmdbuf := bufio.NewWriter(&cmdbuf)
+	l, err := net.Listen("tcp", "127.0.0.1:0")
+	if err != nil {
+		t.Fatalf("Unable to to create listener: %v", err)
+	}
+	defer l.Close()
+
+	// prevent data race on bcmdbuf
+	var done = make(chan struct{})
+	go func(data []string) {
+
+		defer close(done)
+
+		conn, err := l.Accept()
+		if err != nil {
+			t.Errorf("Accept error: %v", err)
+			return
+		}
+		defer conn.Close()
+
+		tc := textproto.NewConn(conn)
+		for i := 0; i < len(data) && data[i] != ""; i++ {
+			tc.PrintfLine(data[i])
+			for len(data[i]) >= 4 && data[i][3] == '-' {
+				i++
+				tc.PrintfLine(data[i])
+			}
+			if data[i] == "221 Goodbye" {
+				return
+			}
+			read := false
+			for !read || data[i] == "354 Go ahead" {
+				msg, err := tc.ReadLine()
+				bcmdbuf.Write([]byte(msg + "\r\n"))
+				read = true
+				if err != nil {
+					t.Errorf("Read error: %v", err)
+					return
+				}
+				if data[i] == "354 Go ahead" && msg == "." {
+					break
+				}
+			}
+		}
+	}(strings.Split(server, "\r\n"))
+
+	err = SendMail(l.Addr().String(), nil, "test at example.com", []string{"other at example.com"}, []byte(strings.Replace(`From: test at example.com
+To: other at example.com
+Subject: SendMail test
+
+SendMail is working for me.
+`, "\n", "\r\n", -1)))
+
+	if err != nil {
+		t.Errorf("%v", err)
+	}
+
+	<-done
+	bcmdbuf.Flush()
+	actualcmds := cmdbuf.String()
+	if client != actualcmds {
+		t.Errorf("Got:\n%s\nExpected:\n%s", actualcmds, client)
+	}
+}
+
+var sendMailServer = `220 hello world
+502 EH?
+250 mx.google.com at your service
+250 Sender ok
+250 Receiver ok
+354 Go ahead
+250 Data ok
+221 Goodbye
+`
+
+var sendMailClient = `EHLO localhost
+HELO localhost
+MAIL FROM:<test at example.com>
+RCPT TO:<other at example.com>
+DATA
+From: test at example.com
+To: other at example.com
+Subject: SendMail test
+
+SendMail is working for me.
+.
+QUIT
+`
+
+func TestAuthFailed(t *testing.T) {
+	server := strings.Join(strings.Split(authFailedServer, "\n"), "\r\n")
+	client := strings.Join(strings.Split(authFailedClient, "\n"), "\r\n")
+	var cmdbuf bytes.Buffer
+	bcmdbuf := bufio.NewWriter(&cmdbuf)
+	var fake faker
+	fake.ReadWriter = bufio.NewReadWriter(bufio.NewReader(strings.NewReader(server)), bcmdbuf)
+	c, err := NewClient(fake, "fake.host")
+	if err != nil {
+		t.Fatalf("NewClient: %v", err)
+	}
+	defer c.Close()
+
+	c.tls = true
+	c.serverName = "smtp.google.com"
+	err = c.Auth(PlainAuth("", "user", "pass", "smtp.google.com"))
+
+	if err == nil {
+		t.Error("Auth: expected error; got none")
+	} else if err.Error() != "535 Invalid credentials\nplease see www.example.com" {
+		t.Errorf("Auth: got error: %v, want: %s", err, "535 Invalid credentials\nplease see www.example.com")
+	}
+
+	bcmdbuf.Flush()
+	actualcmds := cmdbuf.String()
+	if client != actualcmds {
+		t.Errorf("Got:\n%s\nExpected:\n%s", actualcmds, client)
+	}
+}
+
+var authFailedServer = `220 hello world
+250-mx.google.com at your service
+250 AUTH LOGIN PLAIN
+535-Invalid credentials
+535 please see www.example.com
+221 Goodbye
+`
+
+var authFailedClient = `EHLO localhost
+AUTH PLAIN AHVzZXIAcGFzcw==
+*
+QUIT
+`
+
+func TestTLSClient(t *testing.T) {
+	ln := newLocalListener(t)
+	defer ln.Close()
+	errc := make(chan error)
+	go func() {
+		errc <- sendMail(ln.Addr().String())
+	}()
+	conn, err := ln.Accept()
+	if err != nil {
+		t.Fatalf("failed to accept connection: %v", err)
+	}
+	defer conn.Close()
+	if err := serverHandle(conn, t); err != nil {
+		t.Fatalf("failed to handle connection: %v", err)
+	}
+	if err := <-errc; err != nil {
+		t.Fatalf("client error: %v", err)
+	}
+}
+
+func newLocalListener(t *testing.T) net.Listener {
+	ln, err := net.Listen("tcp", "127.0.0.1:0")
+	if err != nil {
+		ln, err = net.Listen("tcp6", "[::1]:0")
+	}
+	if err != nil {
+		t.Fatal(err)
+	}
+	return ln
+}
+
+type smtpSender struct {
+	w io.Writer
+}
+
+func (s smtpSender) send(f string) {
+	s.w.Write([]byte(f + "\r\n"))
+}
+
+// smtp server, finely tailored to deal with our own client only!
+func serverHandle(c net.Conn, t *testing.T) error {
+	send := smtpSender{c}.send
+	send("220 127.0.0.1 ESMTP service ready")
+	s := bufio.NewScanner(c)
+	for s.Scan() {
+		switch s.Text() {
+		case "EHLO localhost":
+			send("250-127.0.0.1 ESMTP offers a warm hug of welcome")
+			send("250-STARTTLS")
+			send("250 Ok")
+		case "STARTTLS":
+			send("220 Go ahead")
+			keypair, err := tls.X509KeyPair(localhostCert, localhostKey)
+			if err != nil {
+				return err
+			}
+			config := &tls.Config{Certificates: []tls.Certificate{keypair}}
+			c = tls.Server(c, config)
+			defer c.Close()
+			return serverHandleTLS(c, t)
+		default:
+			t.Fatalf("unrecognized command: %q", s.Text())
+		}
+	}
+	return s.Err()
+}
+
+func serverHandleTLS(c net.Conn, t *testing.T) error {
+	send := smtpSender{c}.send
+	s := bufio.NewScanner(c)
+	for s.Scan() {
+		switch s.Text() {
+		case "EHLO localhost":
+			send("250 Ok")
+		case "MAIL FROM:<joe1 at example.com>":
+			send("250 Ok")
+		case "RCPT TO:<joe2 at example.com>":
+			send("250 Ok")
+		case "DATA":
+			send("354 send the mail data, end with .")
+			send("250 Ok")
+		case "Subject: test":
+		case "":
+		case "howdy!":
+		case ".":
+		case "QUIT":
+			send("221 127.0.0.1 Service closing transmission channel")
+			return nil
+		default:
+			t.Fatalf("unrecognized command during TLS: %q", s.Text())
+		}
+	}
+	return s.Err()
+}
+
+func init() {
+	testRootCAs := x509.NewCertPool()
+	testRootCAs.AppendCertsFromPEM(localhostCert)
+	testHookStartTLS = func(config *tls.Config) {
+		config.RootCAs = testRootCAs
+	}
+}
+
+func sendMail(hostPort string) error {
+	host, _, err := net.SplitHostPort(hostPort)
+	if err != nil {
+		return err
+	}
+	auth := PlainAuth("", "", "", host)
+	from := "joe1 at example.com"
+	to := []string{"joe2 at example.com"}
+	return SendMail(hostPort, auth, from, to, []byte("Subject: test\n\nhowdy!"))
+}
+
+// (copied from net/http/httptest)
+// localhostCert is a PEM-encoded TLS cert with SAN IPs
+// "127.0.0.1" and "[::1]", expiring at the last second of 2049 (the end
+// of ASN.1 time).
+// generated from src/crypto/tls:
+// go run generate_cert.go  --rsa-bits 512 --host 127.0.0.1,::1,example.com --ca --start-date "Jan 1 00:00:00 1970" --duration=1000000h
+var localhostCert = []byte(`-----BEGIN CERTIFICATE-----
+MIIBdzCCASOgAwIBAgIBADALBgkqhkiG9w0BAQUwEjEQMA4GA1UEChMHQWNtZSBD
+bzAeFw03MDAxMDEwMDAwMDBaFw00OTEyMzEyMzU5NTlaMBIxEDAOBgNVBAoTB0Fj
+bWUgQ28wWjALBgkqhkiG9w0BAQEDSwAwSAJBAN55NcYKZeInyTuhcCwFMhDHCmwa
+IUSdtXdcbItRB/yfXGBhiex00IaLXQnSU+QZPRZWYqeTEbFSgihqi1PUDy8CAwEA
+AaNoMGYwDgYDVR0PAQH/BAQDAgCkMBMGA1UdJQQMMAoGCCsGAQUFBwMBMA8GA1Ud
+EwEB/wQFMAMBAf8wLgYDVR0RBCcwJYILZXhhbXBsZS5jb22HBH8AAAGHEAAAAAAA
+AAAAAAAAAAAAAAEwCwYJKoZIhvcNAQEFA0EAAoQn/ytgqpiLcZu9XKbCJsJcvkgk
+Se6AbGXgSlq+ZCEVo0qIwSgeBqmsJxUu7NCSOwVJLYNEBO2DtIxoYVk+MA==
+-----END CERTIFICATE-----`)
+
+// localhostKey is the private key for localhostCert.
+var localhostKey = []byte(`-----BEGIN RSA PRIVATE KEY-----
+MIIBPAIBAAJBAN55NcYKZeInyTuhcCwFMhDHCmwaIUSdtXdcbItRB/yfXGBhiex0
+0IaLXQnSU+QZPRZWYqeTEbFSgihqi1PUDy8CAwEAAQJBAQdUx66rfh8sYsgfdcvV
+NoafYpnEcB5s4m/vSVe6SU7dCK6eYec9f9wpT353ljhDUHq3EbmE4foNzJngh35d
+AekCIQDhRQG5Li0Wj8TM4obOnnXUXf1jRv0UkzE9AHWLG5q3AwIhAPzSjpYUDjVW
+MCUXgckTpKCuGwbJk7424Nb8bLzf3kllAiA5mUBgjfr/WtFSJdWcPQ4Zt9KTMNKD
+EUO0ukpTwEIl6wIhAMbGqZK3zAAFdq8DD2jPx+UJXnh0rnOkZBzDtJ6/iN69AiEA
+1Aq8MJgTaYsDQWyU/hDq5YkDJc9e9DSCvUIzqxQWMQE=
+-----END RSA PRIVATE KEY-----`)
diff --git a/src/net/sock_bsd.go b/src/net/sock_bsd.go
new file mode 100644
index 0000000..6c37109
--- /dev/null
+++ b/src/net/sock_bsd.go
@@ -0,0 +1,37 @@
+// Copyright 2009 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin dragonfly freebsd netbsd openbsd
+
+package net
+
+import (
+	"runtime"
+	"syscall"
+)
+
+func maxListenerBacklog() int {
+	var (
+		n   uint32
+		err error
+	)
+	switch runtime.GOOS {
+	case "darwin", "freebsd":
+		n, err = syscall.SysctlUint32("kern.ipc.somaxconn")
+	case "netbsd":
+		// NOTE: NetBSD has no somaxconn-like kernel state so far
+	case "openbsd":
+		n, err = syscall.SysctlUint32("kern.somaxconn")
+	}
+	if n == 0 || err != nil {
+		return syscall.SOMAXCONN
+	}
+	// FreeBSD stores the backlog in a uint16, as does Linux.
+	// Assume the other BSDs do too. Truncate number to avoid wrapping.
+	// See issue 5030.
+	if n > 1<<16-1 {
+		n = 1<<16 - 1
+	}
+	return int(n)
+}
diff --git a/src/pkg/net/sock_cloexec.go b/src/net/sock_cloexec.go
similarity index 100%
rename from src/pkg/net/sock_cloexec.go
rename to src/net/sock_cloexec.go
diff --git a/src/pkg/net/sock_linux.go b/src/net/sock_linux.go
similarity index 100%
rename from src/pkg/net/sock_linux.go
rename to src/net/sock_linux.go
diff --git a/src/pkg/net/sock_plan9.go b/src/net/sock_plan9.go
similarity index 100%
rename from src/pkg/net/sock_plan9.go
rename to src/net/sock_plan9.go
diff --git a/src/net/sock_posix.go b/src/net/sock_posix.go
new file mode 100644
index 0000000..3f956df
--- /dev/null
+++ b/src/net/sock_posix.go
@@ -0,0 +1,216 @@
+// Copyright 2009 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris windows
+
+package net
+
+import (
+	"os"
+	"syscall"
+	"time"
+)
+
+// A sockaddr represents a TCP, UDP, IP or Unix network endpoint
+// address that can be converted into a syscall.Sockaddr.
+type sockaddr interface {
+	Addr
+
+	netaddr
+
+	// family returns the platform-dependent address family
+	// identifier.
+	family() int
+
+	// isWildcard reports whether the address is a wildcard
+	// address.
+	isWildcard() bool
+
+	// sockaddr returns the address converted into a syscall
+	// sockaddr type that implements syscall.Sockaddr
+	// interface. It returns a nil interface when the address is
+	// nil.
+	sockaddr(family int) (syscall.Sockaddr, error)
+}
+
+// socket returns a network file descriptor that is ready for
+// asynchronous I/O using the network poller.
+func socket(net string, family, sotype, proto int, ipv6only bool, laddr, raddr sockaddr, deadline time.Time) (fd *netFD, err error) {
+	s, err := sysSocket(family, sotype, proto)
+	if err != nil {
+		return nil, err
+	}
+	if err = setDefaultSockopts(s, family, sotype, ipv6only); err != nil {
+		closesocket(s)
+		return nil, err
+	}
+	if fd, err = newFD(s, family, sotype, net); err != nil {
+		closesocket(s)
+		return nil, err
+	}
+
+	// This function makes a network file descriptor for the
+	// following applications:
+	//
+	// - An endpoint holder that opens a passive stream
+	//   connenction, known as a stream listener
+	//
+	// - An endpoint holder that opens a destination-unspecific
+	//   datagram connection, known as a datagram listener
+	//
+	// - An endpoint holder that opens an active stream or a
+	//   destination-specific datagram connection, known as a
+	//   dialer
+	//
+	// - An endpoint holder that opens the other connection, such
+	//   as talking to the protocol stack inside the kernel
+	//
+	// For stream and datagram listeners, they will only require
+	// named sockets, so we can assume that it's just a request
+	// from stream or datagram listeners when laddr is not nil but
+	// raddr is nil. Otherwise we assume it's just for dialers or
+	// the other connection holders.
+
+	if laddr != nil && raddr == nil {
+		switch sotype {
+		case syscall.SOCK_STREAM, syscall.SOCK_SEQPACKET:
+			if err := fd.listenStream(laddr, listenerBacklog); err != nil {
+				fd.Close()
+				return nil, err
+			}
+			return fd, nil
+		case syscall.SOCK_DGRAM:
+			if err := fd.listenDatagram(laddr); err != nil {
+				fd.Close()
+				return nil, err
+			}
+			return fd, nil
+		}
+	}
+	if err := fd.dial(laddr, raddr, deadline); err != nil {
+		fd.Close()
+		return nil, err
+	}
+	return fd, nil
+}
+
+func (fd *netFD) addrFunc() func(syscall.Sockaddr) Addr {
+	switch fd.family {
+	case syscall.AF_INET, syscall.AF_INET6:
+		switch fd.sotype {
+		case syscall.SOCK_STREAM:
+			return sockaddrToTCP
+		case syscall.SOCK_DGRAM:
+			return sockaddrToUDP
+		case syscall.SOCK_RAW:
+			return sockaddrToIP
+		}
+	case syscall.AF_UNIX:
+		switch fd.sotype {
+		case syscall.SOCK_STREAM:
+			return sockaddrToUnix
+		case syscall.SOCK_DGRAM:
+			return sockaddrToUnixgram
+		case syscall.SOCK_SEQPACKET:
+			return sockaddrToUnixpacket
+		}
+	}
+	return func(syscall.Sockaddr) Addr { return nil }
+}
+
+func (fd *netFD) dial(laddr, raddr sockaddr, deadline time.Time) error {
+	var err error
+	var lsa syscall.Sockaddr
+	if laddr != nil {
+		if lsa, err = laddr.sockaddr(fd.family); err != nil {
+			return err
+		} else if lsa != nil {
+			if err := syscall.Bind(fd.sysfd, lsa); err != nil {
+				return os.NewSyscallError("bind", err)
+			}
+		}
+	}
+	var rsa syscall.Sockaddr
+	if raddr != nil {
+		if rsa, err = raddr.sockaddr(fd.family); err != nil {
+			return err
+		}
+		if err := fd.connect(lsa, rsa, deadline); err != nil {
+			return err
+		}
+		fd.isConnected = true
+	} else {
+		if err := fd.init(); err != nil {
+			return err
+		}
+	}
+	lsa, _ = syscall.Getsockname(fd.sysfd)
+	if rsa, _ = syscall.Getpeername(fd.sysfd); rsa != nil {
+		fd.setAddr(fd.addrFunc()(lsa), fd.addrFunc()(rsa))
+	} else {
+		fd.setAddr(fd.addrFunc()(lsa), raddr)
+	}
+	return nil
+}
+
+func (fd *netFD) listenStream(laddr sockaddr, backlog int) error {
+	if err := setDefaultListenerSockopts(fd.sysfd); err != nil {
+		return err
+	}
+	if lsa, err := laddr.sockaddr(fd.family); err != nil {
+		return err
+	} else if lsa != nil {
+		if err := syscall.Bind(fd.sysfd, lsa); err != nil {
+			return os.NewSyscallError("bind", err)
+		}
+	}
+	if err := syscall.Listen(fd.sysfd, backlog); err != nil {
+		return os.NewSyscallError("listen", err)
+	}
+	if err := fd.init(); err != nil {
+		return err
+	}
+	lsa, _ := syscall.Getsockname(fd.sysfd)
+	fd.setAddr(fd.addrFunc()(lsa), nil)
+	return nil
+}
+
+func (fd *netFD) listenDatagram(laddr sockaddr) error {
+	switch addr := laddr.(type) {
+	case *UDPAddr:
+		// We provide a socket that listens to a wildcard
+		// address with reusable UDP port when the given laddr
+		// is an appropriate UDP multicast address prefix.
+		// This makes it possible for a single UDP listener to
+		// join multiple different group addresses, for
+		// multiple UDP listeners that listen on the same UDP
+		// port to join the same group address.
+		if addr.IP != nil && addr.IP.IsMulticast() {
+			if err := setDefaultMulticastSockopts(fd.sysfd); err != nil {
+				return err
+			}
+			addr := *addr
+			switch fd.family {
+			case syscall.AF_INET:
+				addr.IP = IPv4zero
+			case syscall.AF_INET6:
+				addr.IP = IPv6unspecified
+			}
+			laddr = &addr
+		}
+	}
+	if lsa, err := laddr.sockaddr(fd.family); err != nil {
+		return err
+	} else if lsa != nil {
+		if err := syscall.Bind(fd.sysfd, lsa); err != nil {
+			return os.NewSyscallError("bind", err)
+		}
+	}
+	if err := fd.init(); err != nil {
+		return err
+	}
+	lsa, _ := syscall.Getsockname(fd.sysfd)
+	fd.setAddr(fd.addrFunc()(lsa), nil)
+	return nil
+}
diff --git a/src/net/sock_stub.go b/src/net/sock_stub.go
new file mode 100644
index 0000000..ed6b089
--- /dev/null
+++ b/src/net/sock_stub.go
@@ -0,0 +1,15 @@
+// Copyright 2009 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build nacl solaris
+
+package net
+
+import "syscall"
+
+func maxListenerBacklog() int {
+	// TODO: Implement this
+	// NOTE: Never return a number bigger than 1<<16 - 1. See issue 5030.
+	return syscall.SOMAXCONN
+}
diff --git a/src/pkg/net/sock_windows.go b/src/net/sock_windows.go
similarity index 100%
rename from src/pkg/net/sock_windows.go
rename to src/net/sock_windows.go
diff --git a/src/net/sockopt_bsd.go b/src/net/sockopt_bsd.go
new file mode 100644
index 0000000..00e4dbf
--- /dev/null
+++ b/src/net/sockopt_bsd.go
@@ -0,0 +1,54 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin dragonfly freebsd netbsd openbsd
+
+package net
+
+import (
+	"os"
+	"runtime"
+	"syscall"
+)
+
+func setDefaultSockopts(s, family, sotype int, ipv6only bool) error {
+	if runtime.GOOS == "dragonfly" && sotype != syscall.SOCK_RAW {
+		// On DragonFly BSD, we adjust the ephemeral port
+		// range because unlike other BSD systems its default
+		// port range doesn't conform to IANA recommendation
+		// as described in RFC 6056 and is pretty narrow.
+		switch family {
+		case syscall.AF_INET:
+			syscall.SetsockoptInt(s, syscall.IPPROTO_IP, syscall.IP_PORTRANGE, syscall.IP_PORTRANGE_HIGH)
+		case syscall.AF_INET6:
+			syscall.SetsockoptInt(s, syscall.IPPROTO_IPV6, syscall.IPV6_PORTRANGE, syscall.IPV6_PORTRANGE_HIGH)
+		}
+	}
+	if family == syscall.AF_INET6 && sotype != syscall.SOCK_RAW {
+		// Allow both IP versions even if the OS default
+		// is otherwise.  Note that some operating systems
+		// never admit this option.
+		syscall.SetsockoptInt(s, syscall.IPPROTO_IPV6, syscall.IPV6_V6ONLY, boolint(ipv6only))
+	}
+	// Allow broadcast.
+	return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_BROADCAST, 1))
+}
+
+func setDefaultListenerSockopts(s int) error {
+	// Allow reuse of recently-used addresses.
+	return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1))
+}
+
+func setDefaultMulticastSockopts(s int) error {
+	// Allow multicast UDP and raw IP datagram sockets to listen
+	// concurrently across multiple listeners.
+	if err := syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1); err != nil {
+		return os.NewSyscallError("setsockopt", err)
+	}
+	// Allow reuse of recently-used ports.
+	// This option is supported only in descendants of 4.4BSD,
+	// to make an effective multicast application that requires
+	// quick draw possible.
+	return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_REUSEPORT, 1))
+}
diff --git a/src/pkg/net/sockopt_linux.go b/src/net/sockopt_linux.go
similarity index 100%
rename from src/pkg/net/sockopt_linux.go
rename to src/net/sockopt_linux.go
diff --git a/src/pkg/net/sockopt_plan9.go b/src/net/sockopt_plan9.go
similarity index 100%
rename from src/pkg/net/sockopt_plan9.go
rename to src/net/sockopt_plan9.go
diff --git a/src/net/sockopt_posix.go b/src/net/sockopt_posix.go
new file mode 100644
index 0000000..1654d1b
--- /dev/null
+++ b/src/net/sockopt_posix.go
@@ -0,0 +1,141 @@
+// Copyright 2009 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin dragonfly freebsd linux netbsd openbsd solaris windows
+
+package net
+
+import (
+	"os"
+	"syscall"
+)
+
+// Boolean to int.
+func boolint(b bool) int {
+	if b {
+		return 1
+	}
+	return 0
+}
+
+func ipv4AddrToInterface(ip IP) (*Interface, error) {
+	ift, err := Interfaces()
+	if err != nil {
+		return nil, err
+	}
+	for _, ifi := range ift {
+		ifat, err := ifi.Addrs()
+		if err != nil {
+			return nil, err
+		}
+		for _, ifa := range ifat {
+			switch v := ifa.(type) {
+			case *IPAddr:
+				if ip.Equal(v.IP) {
+					return &ifi, nil
+				}
+			case *IPNet:
+				if ip.Equal(v.IP) {
+					return &ifi, nil
+				}
+			}
+		}
+	}
+	if ip.Equal(IPv4zero) {
+		return nil, nil
+	}
+	return nil, errNoSuchInterface
+}
+
+func interfaceToIPv4Addr(ifi *Interface) (IP, error) {
+	if ifi == nil {
+		return IPv4zero, nil
+	}
+	ifat, err := ifi.Addrs()
+	if err != nil {
+		return nil, err
+	}
+	for _, ifa := range ifat {
+		switch v := ifa.(type) {
+		case *IPAddr:
+			if v.IP.To4() != nil {
+				return v.IP, nil
+			}
+		case *IPNet:
+			if v.IP.To4() != nil {
+				return v.IP, nil
+			}
+		}
+	}
+	return nil, errNoSuchInterface
+}
+
+func setIPv4MreqToInterface(mreq *syscall.IPMreq, ifi *Interface) error {
+	if ifi == nil {
+		return nil
+	}
+	ifat, err := ifi.Addrs()
+	if err != nil {
+		return err
+	}
+	for _, ifa := range ifat {
+		switch v := ifa.(type) {
+		case *IPAddr:
+			if a := v.IP.To4(); a != nil {
+				copy(mreq.Interface[:], a)
+				goto done
+			}
+		case *IPNet:
+			if a := v.IP.To4(); a != nil {
+				copy(mreq.Interface[:], a)
+				goto done
+			}
+		}
+	}
+done:
+	if bytesEqual(mreq.Multiaddr[:], IPv4zero.To4()) {
+		return errNoSuchMulticastInterface
+	}
+	return nil
+}
+
+func setReadBuffer(fd *netFD, bytes int) error {
+	if err := fd.incref(); err != nil {
+		return err
+	}
+	defer fd.decref()
+	return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_RCVBUF, bytes))
+}
+
+func setWriteBuffer(fd *netFD, bytes int) error {
+	if err := fd.incref(); err != nil {
+		return err
+	}
+	defer fd.decref()
+	return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_SNDBUF, bytes))
+}
+
+func setKeepAlive(fd *netFD, keepalive bool) error {
+	if err := fd.incref(); err != nil {
+		return err
+	}
+	defer fd.decref()
+	return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_KEEPALIVE, boolint(keepalive)))
+}
+
+func setLinger(fd *netFD, sec int) error {
+	var l syscall.Linger
+	if sec >= 0 {
+		l.Onoff = 1
+		l.Linger = int32(sec)
+	} else {
+		l.Onoff = 0
+		l.Linger = 0
+	}
+	if err := fd.incref(); err != nil {
+		return err
+	}
+	defer fd.decref()
+	return os.NewSyscallError("setsockopt", syscall.SetsockoptLinger(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_LINGER, &l))
+}
diff --git a/src/pkg/net/sockopt_solaris.go b/src/net/sockopt_solaris.go
similarity index 100%
rename from src/pkg/net/sockopt_solaris.go
rename to src/net/sockopt_solaris.go
diff --git a/src/net/sockopt_stub.go b/src/net/sockopt_stub.go
new file mode 100644
index 0000000..de5ee0b
--- /dev/null
+++ b/src/net/sockopt_stub.go
@@ -0,0 +1,37 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build nacl
+
+package net
+
+import "syscall"
+
+func setDefaultSockopts(s, family, sotype int, ipv6only bool) error {
+	return nil
+}
+
+func setDefaultListenerSockopts(s int) error {
+	return nil
+}
+
+func setDefaultMulticastSockopts(s int) error {
+	return nil
+}
+
+func setReadBuffer(fd *netFD, bytes int) error {
+	return syscall.ENOPROTOOPT
+}
+
+func setWriteBuffer(fd *netFD, bytes int) error {
+	return syscall.ENOPROTOOPT
+}
+
+func setKeepAlive(fd *netFD, keepalive bool) error {
+	return syscall.ENOPROTOOPT
+}
+
+func setLinger(fd *netFD, sec int) error {
+	return syscall.ENOPROTOOPT
+}
diff --git a/src/pkg/net/sockopt_windows.go b/src/net/sockopt_windows.go
similarity index 100%
rename from src/pkg/net/sockopt_windows.go
rename to src/net/sockopt_windows.go
diff --git a/src/net/sockoptip_bsd.go b/src/net/sockoptip_bsd.go
new file mode 100644
index 0000000..2199e48
--- /dev/null
+++ b/src/net/sockoptip_bsd.go
@@ -0,0 +1,34 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin dragonfly freebsd netbsd openbsd
+
+package net
+
+import (
+	"os"
+	"syscall"
+)
+
+func setIPv4MulticastInterface(fd *netFD, ifi *Interface) error {
+	ip, err := interfaceToIPv4Addr(ifi)
+	if err != nil {
+		return os.NewSyscallError("setsockopt", err)
+	}
+	var a [4]byte
+	copy(a[:], ip.To4())
+	if err := fd.incref(); err != nil {
+		return err
+	}
+	defer fd.decref()
+	return os.NewSyscallError("setsockopt", syscall.SetsockoptInet4Addr(fd.sysfd, syscall.IPPROTO_IP, syscall.IP_MULTICAST_IF, a))
+}
+
+func setIPv4MulticastLoopback(fd *netFD, v bool) error {
+	if err := fd.incref(); err != nil {
+		return err
+	}
+	defer fd.decref()
+	return os.NewSyscallError("setsockopt", syscall.SetsockoptByte(fd.sysfd, syscall.IPPROTO_IP, syscall.IP_MULTICAST_LOOP, byte(boolint(v))))
+}
diff --git a/src/pkg/net/sockoptip_linux.go b/src/net/sockoptip_linux.go
similarity index 100%
rename from src/pkg/net/sockoptip_linux.go
rename to src/net/sockoptip_linux.go
diff --git a/src/net/sockoptip_posix.go b/src/net/sockoptip_posix.go
new file mode 100644
index 0000000..c2579be
--- /dev/null
+++ b/src/net/sockoptip_posix.go
@@ -0,0 +1,57 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin dragonfly freebsd linux netbsd openbsd windows
+
+package net
+
+import (
+	"os"
+	"syscall"
+)
+
+func joinIPv4Group(fd *netFD, ifi *Interface, ip IP) error {
+	mreq := &syscall.IPMreq{Multiaddr: [4]byte{ip[0], ip[1], ip[2], ip[3]}}
+	if err := setIPv4MreqToInterface(mreq, ifi); err != nil {
+		return err
+	}
+	if err := fd.incref(); err != nil {
+		return err
+	}
+	defer fd.decref()
+	return os.NewSyscallError("setsockopt", syscall.SetsockoptIPMreq(fd.sysfd, syscall.IPPROTO_IP, syscall.IP_ADD_MEMBERSHIP, mreq))
+}
+
+func setIPv6MulticastInterface(fd *netFD, ifi *Interface) error {
+	var v int
+	if ifi != nil {
+		v = ifi.Index
+	}
+	if err := fd.incref(); err != nil {
+		return err
+	}
+	defer fd.decref()
+	return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd.sysfd, syscall.IPPROTO_IPV6, syscall.IPV6_MULTICAST_IF, v))
+}
+
+func setIPv6MulticastLoopback(fd *netFD, v bool) error {
+	if err := fd.incref(); err != nil {
+		return err
+	}
+	defer fd.decref()
+	return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd.sysfd, syscall.IPPROTO_IPV6, syscall.IPV6_MULTICAST_LOOP, boolint(v)))
+}
+
+func joinIPv6Group(fd *netFD, ifi *Interface, ip IP) error {
+	mreq := &syscall.IPv6Mreq{}
+	copy(mreq.Multiaddr[:], ip)
+	if ifi != nil {
+		mreq.Interface = uint32(ifi.Index)
+	}
+	if err := fd.incref(); err != nil {
+		return err
+	}
+	defer fd.decref()
+	return os.NewSyscallError("setsockopt", syscall.SetsockoptIPv6Mreq(fd.sysfd, syscall.IPPROTO_IPV6, syscall.IPV6_JOIN_GROUP, mreq))
+}
diff --git a/src/net/sockoptip_stub.go b/src/net/sockoptip_stub.go
new file mode 100644
index 0000000..32ec5dd
--- /dev/null
+++ b/src/net/sockoptip_stub.go
@@ -0,0 +1,39 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build nacl solaris
+
+package net
+
+import "syscall"
+
+func setIPv4MulticastInterface(fd *netFD, ifi *Interface) error {
+	// See golang.org/issue/7399.
+	return syscall.ENOPROTOOPT
+}
+
+func setIPv4MulticastLoopback(fd *netFD, v bool) error {
+	// See golang.org/issue/7399.
+	return syscall.ENOPROTOOPT
+}
+
+func joinIPv4Group(fd *netFD, ifi *Interface, ip IP) error {
+	// See golang.org/issue/7399.
+	return syscall.ENOPROTOOPT
+}
+
+func setIPv6MulticastInterface(fd *netFD, ifi *Interface) error {
+	// See golang.org/issue/7399.
+	return syscall.ENOPROTOOPT
+}
+
+func setIPv6MulticastLoopback(fd *netFD, v bool) error {
+	// See golang.org/issue/7399.
+	return syscall.ENOPROTOOPT
+}
+
+func joinIPv6Group(fd *netFD, ifi *Interface, ip IP) error {
+	// See golang.org/issue/7399.
+	return syscall.ENOPROTOOPT
+}
diff --git a/src/pkg/net/sockoptip_windows.go b/src/net/sockoptip_windows.go
similarity index 100%
rename from src/pkg/net/sockoptip_windows.go
rename to src/net/sockoptip_windows.go
diff --git a/src/pkg/net/sys_cloexec.go b/src/net/sys_cloexec.go
similarity index 100%
rename from src/pkg/net/sys_cloexec.go
rename to src/net/sys_cloexec.go
diff --git a/src/pkg/net/tcp_test.go b/src/net/tcp_test.go
similarity index 100%
rename from src/pkg/net/tcp_test.go
rename to src/net/tcp_test.go
diff --git a/src/pkg/net/tcpsock.go b/src/net/tcpsock.go
similarity index 100%
rename from src/pkg/net/tcpsock.go
rename to src/net/tcpsock.go
diff --git a/src/pkg/net/tcpsock_plan9.go b/src/net/tcpsock_plan9.go
similarity index 100%
rename from src/pkg/net/tcpsock_plan9.go
rename to src/net/tcpsock_plan9.go
diff --git a/src/net/tcpsock_posix.go b/src/net/tcpsock_posix.go
new file mode 100644
index 0000000..dd78aef
--- /dev/null
+++ b/src/net/tcpsock_posix.go
@@ -0,0 +1,299 @@
+// Copyright 2009 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris windows
+
+package net
+
+import (
+	"io"
+	"os"
+	"syscall"
+	"time"
+)
+
+// BUG(rsc): On OpenBSD, listening on the "tcp" network does not listen for
+// both IPv4 and IPv6 connections. This is due to the fact that IPv4 traffic
+// will not be routed to an IPv6 socket - two separate sockets are required
+// if both AFs are to be supported. See inet6(4) on OpenBSD for details.
+
+func sockaddrToTCP(sa syscall.Sockaddr) Addr {
+	switch sa := sa.(type) {
+	case *syscall.SockaddrInet4:
+		return &TCPAddr{IP: sa.Addr[0:], Port: sa.Port}
+	case *syscall.SockaddrInet6:
+		return &TCPAddr{IP: sa.Addr[0:], Port: sa.Port, Zone: zoneToString(int(sa.ZoneId))}
+	}
+	return nil
+}
+
+func (a *TCPAddr) family() int {
+	if a == nil || len(a.IP) <= IPv4len {
+		return syscall.AF_INET
+	}
+	if a.IP.To4() != nil {
+		return syscall.AF_INET
+	}
+	return syscall.AF_INET6
+}
+
+func (a *TCPAddr) isWildcard() bool {
+	if a == nil || a.IP == nil {
+		return true
+	}
+	return a.IP.IsUnspecified()
+}
+
+func (a *TCPAddr) sockaddr(family int) (syscall.Sockaddr, error) {
+	if a == nil {
+		return nil, nil
+	}
+	return ipToSockaddr(family, a.IP, a.Port, a.Zone)
+}
+
+// TCPConn is an implementation of the Conn interface for TCP network
+// connections.
+type TCPConn struct {
+	conn
+}
+
+func newTCPConn(fd *netFD) *TCPConn {
+	c := &TCPConn{conn{fd}}
+	c.SetNoDelay(true)
+	return c
+}
+
+// ReadFrom implements the io.ReaderFrom ReadFrom method.
+func (c *TCPConn) ReadFrom(r io.Reader) (int64, error) {
+	if n, err, handled := sendFile(c.fd, r); handled {
+		return n, err
+	}
+	return genericReadFrom(c, r)
+}
+
+// CloseRead shuts down the reading side of the TCP connection.
+// Most callers should just use Close.
+func (c *TCPConn) CloseRead() error {
+	if !c.ok() {
+		return syscall.EINVAL
+	}
+	return c.fd.closeRead()
+}
+
+// CloseWrite shuts down the writing side of the TCP connection.
+// Most callers should just use Close.
+func (c *TCPConn) CloseWrite() error {
+	if !c.ok() {
+		return syscall.EINVAL
+	}
+	return c.fd.closeWrite()
+}
+
+// SetLinger sets the behavior of Close on a connection which still
+// has data waiting to be sent or to be acknowledged.
+//
+// If sec < 0 (the default), the operating system finishes sending the
+// data in the background.
+//
+// If sec == 0, the operating system discards any unsent or
+// unacknowledged data.
+//
+// If sec > 0, the data is sent in the background as with sec < 0. On
+// some operating systems after sec seconds have elapsed any remaining
+// unsent data may be discarded.
+func (c *TCPConn) SetLinger(sec int) error {
+	if !c.ok() {
+		return syscall.EINVAL
+	}
+	return setLinger(c.fd, sec)
+}
+
+// SetKeepAlive sets whether the operating system should send
+// keepalive messages on the connection.
+func (c *TCPConn) SetKeepAlive(keepalive bool) error {
+	if !c.ok() {
+		return syscall.EINVAL
+	}
+	return setKeepAlive(c.fd, keepalive)
+}
+
+// SetKeepAlivePeriod sets period between keep alives.
+func (c *TCPConn) SetKeepAlivePeriod(d time.Duration) error {
+	if !c.ok() {
+		return syscall.EINVAL
+	}
+	return setKeepAlivePeriod(c.fd, d)
+}
+
+// SetNoDelay controls whether the operating system should delay
+// packet transmission in hopes of sending fewer packets (Nagle's
+// algorithm).  The default is true (no delay), meaning that data is
+// sent as soon as possible after a Write.
+func (c *TCPConn) SetNoDelay(noDelay bool) error {
+	if !c.ok() {
+		return syscall.EINVAL
+	}
+	return setNoDelay(c.fd, noDelay)
+}
+
+// DialTCP connects to the remote address raddr on the network net,
+// which must be "tcp", "tcp4", or "tcp6".  If laddr is not nil, it is
+// used as the local address for the connection.
+func DialTCP(net string, laddr, raddr *TCPAddr) (*TCPConn, error) {
+	switch net {
+	case "tcp", "tcp4", "tcp6":
+	default:
+		return nil, &OpError{Op: "dial", Net: net, Addr: raddr, Err: UnknownNetworkError(net)}
+	}
+	if raddr == nil {
+		return nil, &OpError{Op: "dial", Net: net, Addr: nil, Err: errMissingAddress}
+	}
+	return dialTCP(net, laddr, raddr, noDeadline)
+}
+
+func dialTCP(net string, laddr, raddr *TCPAddr, deadline time.Time) (*TCPConn, error) {
+	fd, err := internetSocket(net, laddr, raddr, deadline, syscall.SOCK_STREAM, 0, "dial")
+
+	// TCP has a rarely used mechanism called a 'simultaneous connection' in
+	// which Dial("tcp", addr1, addr2) run on the machine at addr1 can
+	// connect to a simultaneous Dial("tcp", addr2, addr1) run on the machine
+	// at addr2, without either machine executing Listen.  If laddr == nil,
+	// it means we want the kernel to pick an appropriate originating local
+	// address.  Some Linux kernels cycle blindly through a fixed range of
+	// local ports, regardless of destination port.  If a kernel happens to
+	// pick local port 50001 as the source for a Dial("tcp", "", "localhost:50001"),
+	// then the Dial will succeed, having simultaneously connected to itself.
+	// This can only happen when we are letting the kernel pick a port (laddr == nil)
+	// and when there is no listener for the destination address.
+	// It's hard to argue this is anything other than a kernel bug.  If we
+	// see this happen, rather than expose the buggy effect to users, we
+	// close the fd and try again.  If it happens twice more, we relent and
+	// use the result.  See also:
+	//	http://golang.org/issue/2690
+	//	http://stackoverflow.com/questions/4949858/
+	//
+	// The opposite can also happen: if we ask the kernel to pick an appropriate
+	// originating local address, sometimes it picks one that is already in use.
+	// So if the error is EADDRNOTAVAIL, we have to try again too, just for
+	// a different reason.
+	//
+	// The kernel socket code is no doubt enjoying watching us squirm.
+	for i := 0; i < 2 && (laddr == nil || laddr.Port == 0) && (selfConnect(fd, err) || spuriousENOTAVAIL(err)); i++ {
+		if err == nil {
+			fd.Close()
+		}
+		fd, err = internetSocket(net, laddr, raddr, deadline, syscall.SOCK_STREAM, 0, "dial")
+	}
+
+	if err != nil {
+		return nil, &OpError{Op: "dial", Net: net, Addr: raddr, Err: err}
+	}
+	return newTCPConn(fd), nil
+}
+
+func selfConnect(fd *netFD, err error) bool {
+	// If the connect failed, we clearly didn't connect to ourselves.
+	if err != nil {
+		return false
+	}
+
+	// The socket constructor can return an fd with raddr nil under certain
+	// unknown conditions. The errors in the calls there to Getpeername
+	// are discarded, but we can't catch the problem there because those
+	// calls are sometimes legally erroneous with a "socket not connected".
+	// Since this code (selfConnect) is already trying to work around
+	// a problem, we make sure if this happens we recognize trouble and
+	// ask the DialTCP routine to try again.
+	// TODO: try to understand what's really going on.
+	if fd.laddr == nil || fd.raddr == nil {
+		return true
+	}
+	l := fd.laddr.(*TCPAddr)
+	r := fd.raddr.(*TCPAddr)
+	return l.Port == r.Port && l.IP.Equal(r.IP)
+}
+
+func spuriousENOTAVAIL(err error) bool {
+	e, ok := err.(*OpError)
+	return ok && e.Err == syscall.EADDRNOTAVAIL
+}
+
+// TCPListener is a TCP network listener.  Clients should typically
+// use variables of type Listener instead of assuming TCP.
+type TCPListener struct {
+	fd *netFD
+}
+
+// AcceptTCP accepts the next incoming call and returns the new
+// connection.
+func (l *TCPListener) AcceptTCP() (*TCPConn, error) {
+	if l == nil || l.fd == nil {
+		return nil, syscall.EINVAL
+	}
+	fd, err := l.fd.accept()
+	if err != nil {
+		return nil, err
+	}
+	return newTCPConn(fd), nil
+}
+
+// Accept implements the Accept method in the Listener interface; it
+// waits for the next call and returns a generic Conn.
+func (l *TCPListener) Accept() (Conn, error) {
+	c, err := l.AcceptTCP()
+	if err != nil {
+		return nil, err
+	}
+	return c, nil
+}
+
+// Close stops listening on the TCP address.
+// Already Accepted connections are not closed.
+func (l *TCPListener) Close() error {
+	if l == nil || l.fd == nil {
+		return syscall.EINVAL
+	}
+	return l.fd.Close()
+}
+
+// Addr returns the listener's network address, a *TCPAddr.
+func (l *TCPListener) Addr() Addr { return l.fd.laddr }
+
+// SetDeadline sets the deadline associated with the listener.
+// A zero time value disables the deadline.
+func (l *TCPListener) SetDeadline(t time.Time) error {
+	if l == nil || l.fd == nil {
+		return syscall.EINVAL
+	}
+	return l.fd.setDeadline(t)
+}
+
+// File returns a copy of the underlying os.File, set to blocking
+// mode.  It is the caller's responsibility to close f when finished.
+// Closing l does not affect f, and closing f does not affect l.
+//
+// The returned os.File's file descriptor is different from the
+// connection's.  Attempting to change properties of the original
+// using this duplicate may or may not have the desired effect.
+func (l *TCPListener) File() (f *os.File, err error) { return l.fd.dup() }
+
+// ListenTCP announces on the TCP address laddr and returns a TCP
+// listener.  Net must be "tcp", "tcp4", or "tcp6".  If laddr has a
+// port of 0, ListenTCP will choose an available port.  The caller can
+// use the Addr method of TCPListener to retrieve the chosen address.
+func ListenTCP(net string, laddr *TCPAddr) (*TCPListener, error) {
+	switch net {
+	case "tcp", "tcp4", "tcp6":
+	default:
+		return nil, &OpError{Op: "listen", Net: net, Addr: laddr, Err: UnknownNetworkError(net)}
+	}
+	if laddr == nil {
+		laddr = &TCPAddr{}
+	}
+	fd, err := internetSocket(net, laddr, nil, noDeadline, syscall.SOCK_STREAM, 0, "listen")
+	if err != nil {
+		return nil, &OpError{Op: "listen", Net: net, Addr: laddr, Err: err}
+	}
+	return &TCPListener{fd}, nil
+}
diff --git a/src/net/tcpsockopt_darwin.go b/src/net/tcpsockopt_darwin.go
new file mode 100644
index 0000000..1f16090
--- /dev/null
+++ b/src/net/tcpsockopt_darwin.go
@@ -0,0 +1,29 @@
+// Copyright 2009 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package net
+
+import (
+	"os"
+	"syscall"
+	"time"
+)
+
+const sysTCP_KEEPINTVL = 0x101
+
+func setKeepAlivePeriod(fd *netFD, d time.Duration) error {
+	if err := fd.incref(); err != nil {
+		return err
+	}
+	defer fd.decref()
+	// The kernel expects seconds so round to next highest second.
+	d += (time.Second - time.Nanosecond)
+	secs := int(d.Seconds())
+	switch err := syscall.SetsockoptInt(fd.sysfd, syscall.IPPROTO_TCP, sysTCP_KEEPINTVL, secs); err {
+	case nil, syscall.ENOPROTOOPT: // OS X 10.7 and earlier don't support this option
+	default:
+		return os.NewSyscallError("setsockopt", err)
+	}
+	return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd.sysfd, syscall.IPPROTO_TCP, syscall.TCP_KEEPALIVE, secs))
+}
diff --git a/src/net/tcpsockopt_dragonfly.go b/src/net/tcpsockopt_dragonfly.go
new file mode 100644
index 0000000..0aa2132
--- /dev/null
+++ b/src/net/tcpsockopt_dragonfly.go
@@ -0,0 +1,26 @@
+// Copyright 2009 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package net
+
+import (
+	"os"
+	"syscall"
+	"time"
+)
+
+func setKeepAlivePeriod(fd *netFD, d time.Duration) error {
+	if err := fd.incref(); err != nil {
+		return err
+	}
+	defer fd.decref()
+	// The kernel expects milliseconds so round to next highest
+	// millisecond.
+	d += (time.Millisecond - time.Nanosecond)
+	msecs := int(d / time.Millisecond)
+	if err := syscall.SetsockoptInt(fd.sysfd, syscall.IPPROTO_TCP, syscall.TCP_KEEPINTVL, msecs); err != nil {
+		return os.NewSyscallError("setsockopt", err)
+	}
+	return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd.sysfd, syscall.IPPROTO_TCP, syscall.TCP_KEEPIDLE, msecs))
+}
diff --git a/src/net/tcpsockopt_openbsd.go b/src/net/tcpsockopt_openbsd.go
new file mode 100644
index 0000000..041e178
--- /dev/null
+++ b/src/net/tcpsockopt_openbsd.go
@@ -0,0 +1,16 @@
+// Copyright 2009 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package net
+
+import (
+	"syscall"
+	"time"
+)
+
+func setKeepAlivePeriod(fd *netFD, d time.Duration) error {
+	// OpenBSD has no user-settable per-socket TCP keepalive
+	// options.
+	return syscall.ENOPROTOOPT
+}
diff --git a/src/pkg/net/tcpsockopt_plan9.go b/src/net/tcpsockopt_plan9.go
similarity index 100%
rename from src/pkg/net/tcpsockopt_plan9.go
rename to src/net/tcpsockopt_plan9.go
diff --git a/src/net/tcpsockopt_posix.go b/src/net/tcpsockopt_posix.go
new file mode 100644
index 0000000..0abf3f9
--- /dev/null
+++ b/src/net/tcpsockopt_posix.go
@@ -0,0 +1,20 @@
+// Copyright 2009 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin dragonfly freebsd linux netbsd openbsd solaris windows
+
+package net
+
+import (
+	"os"
+	"syscall"
+)
+
+func setNoDelay(fd *netFD, noDelay bool) error {
+	if err := fd.incref(); err != nil {
+		return err
+	}
+	defer fd.decref()
+	return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd.sysfd, syscall.IPPROTO_TCP, syscall.TCP_NODELAY, boolint(noDelay)))
+}
diff --git a/src/net/tcpsockopt_stub.go b/src/net/tcpsockopt_stub.go
new file mode 100644
index 0000000..b413a76
--- /dev/null
+++ b/src/net/tcpsockopt_stub.go
@@ -0,0 +1,20 @@
+// Copyright 2009 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build nacl
+
+package net
+
+import (
+	"syscall"
+	"time"
+)
+
+func setNoDelay(fd *netFD, noDelay bool) error {
+	return syscall.ENOPROTOOPT
+}
+
+func setKeepAlivePeriod(fd *netFD, d time.Duration) error {
+	return syscall.ENOPROTOOPT
+}
diff --git a/src/net/tcpsockopt_unix.go b/src/net/tcpsockopt_unix.go
new file mode 100644
index 0000000..c9f604c
--- /dev/null
+++ b/src/net/tcpsockopt_unix.go
@@ -0,0 +1,27 @@
+// Copyright 2009 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build freebsd linux netbsd solaris
+
+package net
+
+import (
+	"os"
+	"syscall"
+	"time"
+)
+
+func setKeepAlivePeriod(fd *netFD, d time.Duration) error {
+	if err := fd.incref(); err != nil {
+		return err
+	}
+	defer fd.decref()
+	// The kernel expects seconds so round to next highest second.
+	d += (time.Second - time.Nanosecond)
+	secs := int(d.Seconds())
+	if err := syscall.SetsockoptInt(fd.sysfd, syscall.IPPROTO_TCP, syscall.TCP_KEEPINTVL, secs); err != nil {
+		return os.NewSyscallError("setsockopt", err)
+	}
+	return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd.sysfd, syscall.IPPROTO_TCP, syscall.TCP_KEEPIDLE, secs))
+}
diff --git a/src/net/tcpsockopt_windows.go b/src/net/tcpsockopt_windows.go
new file mode 100644
index 0000000..091f523
--- /dev/null
+++ b/src/net/tcpsockopt_windows.go
@@ -0,0 +1,32 @@
+// Copyright 2009 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package net
+
+import (
+	"os"
+	"syscall"
+	"time"
+	"unsafe"
+)
+
+func setKeepAlivePeriod(fd *netFD, d time.Duration) error {
+	if err := fd.incref(); err != nil {
+		return err
+	}
+	defer fd.decref()
+	// The kernel expects milliseconds so round to next highest
+	// millisecond.
+	d += (time.Millisecond - time.Nanosecond)
+	msecs := uint32(d / time.Millisecond)
+	ka := syscall.TCPKeepalive{
+		OnOff:    1,
+		Time:     msecs,
+		Interval: msecs,
+	}
+	ret := uint32(0)
+	size := uint32(unsafe.Sizeof(ka))
+	err := syscall.WSAIoctl(fd.sysfd, syscall.SIO_KEEPALIVE_VALS, (*byte)(unsafe.Pointer(&ka)), size, nil, 0, &ret, nil, 0)
+	return os.NewSyscallError("WSAIoctl", err)
+}
diff --git a/src/net/testdata/domain-resolv.conf b/src/net/testdata/domain-resolv.conf
new file mode 100644
index 0000000..ff26918
--- /dev/null
+++ b/src/net/testdata/domain-resolv.conf
@@ -0,0 +1,5 @@
+# /etc/resolv.conf
+
+search test invalid
+domain localdomain
+nameserver 8.8.8.8
diff --git a/src/net/testdata/empty-resolv.conf b/src/net/testdata/empty-resolv.conf
new file mode 100644
index 0000000..c4b2b57
--- /dev/null
+++ b/src/net/testdata/empty-resolv.conf
@@ -0,0 +1 @@
+# /etc/resolv.conf
diff --git a/src/pkg/net/testdata/hosts b/src/net/testdata/hosts
similarity index 100%
rename from src/pkg/net/testdata/hosts
rename to src/net/testdata/hosts
diff --git a/src/pkg/net/testdata/hosts_singleline b/src/net/testdata/hosts_singleline
similarity index 100%
rename from src/pkg/net/testdata/hosts_singleline
rename to src/net/testdata/hosts_singleline
diff --git a/src/pkg/net/testdata/igmp b/src/net/testdata/igmp
similarity index 100%
rename from src/pkg/net/testdata/igmp
rename to src/net/testdata/igmp
diff --git a/src/pkg/net/testdata/igmp6 b/src/net/testdata/igmp6
similarity index 100%
rename from src/pkg/net/testdata/igmp6
rename to src/net/testdata/igmp6
diff --git a/src/net/testdata/resolv.conf b/src/net/testdata/resolv.conf
new file mode 100644
index 0000000..04e87ee
--- /dev/null
+++ b/src/net/testdata/resolv.conf
@@ -0,0 +1,8 @@
+# /etc/resolv.conf
+
+domain localdomain
+nameserver 8.8.8.8
+nameserver 2001:4860:4860::8888
+nameserver fe80::1%lo0
+options ndots:5 timeout:10 attempts:3 rotate
+options attempts 3
diff --git a/src/net/testdata/search-resolv.conf b/src/net/testdata/search-resolv.conf
new file mode 100644
index 0000000..1c846bf
--- /dev/null
+++ b/src/net/testdata/search-resolv.conf
@@ -0,0 +1,5 @@
+# /etc/resolv.conf
+
+domain localdomain
+search test invalid
+nameserver 8.8.8.8
diff --git a/src/pkg/net/textproto/header.go b/src/net/textproto/header.go
similarity index 100%
rename from src/pkg/net/textproto/header.go
rename to src/net/textproto/header.go
diff --git a/src/pkg/net/textproto/pipeline.go b/src/net/textproto/pipeline.go
similarity index 100%
rename from src/pkg/net/textproto/pipeline.go
rename to src/net/textproto/pipeline.go
diff --git a/src/pkg/net/textproto/reader.go b/src/net/textproto/reader.go
similarity index 100%
rename from src/pkg/net/textproto/reader.go
rename to src/net/textproto/reader.go
diff --git a/src/pkg/net/textproto/reader_test.go b/src/net/textproto/reader_test.go
similarity index 100%
rename from src/pkg/net/textproto/reader_test.go
rename to src/net/textproto/reader_test.go
diff --git a/src/pkg/net/textproto/textproto.go b/src/net/textproto/textproto.go
similarity index 100%
rename from src/pkg/net/textproto/textproto.go
rename to src/net/textproto/textproto.go
diff --git a/src/pkg/net/textproto/writer.go b/src/net/textproto/writer.go
similarity index 100%
rename from src/pkg/net/textproto/writer.go
rename to src/net/textproto/writer.go
diff --git a/src/pkg/net/textproto/writer_test.go b/src/net/textproto/writer_test.go
similarity index 100%
rename from src/pkg/net/textproto/writer_test.go
rename to src/net/textproto/writer_test.go
diff --git a/src/pkg/net/timeout_test.go b/src/net/timeout_test.go
similarity index 100%
rename from src/pkg/net/timeout_test.go
rename to src/net/timeout_test.go
diff --git a/src/net/udp_test.go b/src/net/udp_test.go
new file mode 100644
index 0000000..125bbca
--- /dev/null
+++ b/src/net/udp_test.go
@@ -0,0 +1,298 @@
+// Copyright 2012 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package net
+
+import (
+	"reflect"
+	"runtime"
+	"strings"
+	"testing"
+	"time"
+)
+
+func TestResolveUDPAddr(t *testing.T) {
+	for _, tt := range resolveTCPAddrTests {
+		net := strings.Replace(tt.net, "tcp", "udp", -1)
+		addr, err := ResolveUDPAddr(net, tt.litAddrOrName)
+		if err != tt.err {
+			t.Fatalf("ResolveUDPAddr(%q, %q) failed: %v", net, tt.litAddrOrName, err)
+		}
+		if !reflect.DeepEqual(addr, (*UDPAddr)(tt.addr)) {
+			t.Fatalf("ResolveUDPAddr(%q, %q) = %#v, want %#v", net, tt.litAddrOrName, addr, tt.addr)
+		}
+		if err == nil {
+			str := addr.String()
+			addr1, err := ResolveUDPAddr(net, str)
+			if err != nil {
+				t.Fatalf("ResolveUDPAddr(%q, %q) [from %q]: %v", net, str, tt.litAddrOrName, err)
+			}
+			if !reflect.DeepEqual(addr1, addr) {
+				t.Fatalf("ResolveUDPAddr(%q, %q) [from %q] = %#v, want %#v", net, str, tt.litAddrOrName, addr1, addr)
+			}
+		}
+	}
+}
+
+func TestReadFromUDP(t *testing.T) {
+	switch runtime.GOOS {
+	case "nacl", "plan9":
+		t.Skipf("skipping test on %q, see issue 8916", runtime.GOOS)
+	}
+
+	ra, err := ResolveUDPAddr("udp", "127.0.0.1:7")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	la, err := ResolveUDPAddr("udp", "127.0.0.1:0")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	c, err := ListenUDP("udp", la)
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer c.Close()
+
+	_, err = c.WriteToUDP([]byte("a"), ra)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	err = c.SetDeadline(time.Now().Add(100 * time.Millisecond))
+	if err != nil {
+		t.Fatal(err)
+	}
+	b := make([]byte, 1)
+	_, _, err = c.ReadFromUDP(b)
+	if err == nil {
+		t.Fatal("ReadFromUDP should fail")
+	} else if !isTimeout(err) {
+		t.Fatal(err)
+	}
+}
+
+func TestWriteToUDP(t *testing.T) {
+	switch runtime.GOOS {
+	case "plan9":
+		t.Skipf("skipping test on %q", runtime.GOOS)
+	}
+
+	l, err := ListenPacket("udp", "127.0.0.1:0")
+	if err != nil {
+		t.Fatalf("Listen failed: %v", err)
+	}
+	defer l.Close()
+
+	testWriteToConn(t, l.LocalAddr().String())
+	testWriteToPacketConn(t, l.LocalAddr().String())
+}
+
+func testWriteToConn(t *testing.T, raddr string) {
+	c, err := Dial("udp", raddr)
+	if err != nil {
+		t.Fatalf("Dial failed: %v", err)
+	}
+	defer c.Close()
+
+	ra, err := ResolveUDPAddr("udp", raddr)
+	if err != nil {
+		t.Fatalf("ResolveUDPAddr failed: %v", err)
+	}
+
+	_, err = c.(*UDPConn).WriteToUDP([]byte("Connection-oriented mode socket"), ra)
+	if err == nil {
+		t.Fatal("WriteToUDP should fail")
+	}
+	if err != nil && err.(*OpError).Err != ErrWriteToConnected {
+		t.Fatalf("WriteToUDP should fail as ErrWriteToConnected: %v", err)
+	}
+
+	_, err = c.(*UDPConn).WriteTo([]byte("Connection-oriented mode socket"), ra)
+	if err == nil {
+		t.Fatal("WriteTo should fail")
+	}
+	if err != nil && err.(*OpError).Err != ErrWriteToConnected {
+		t.Fatalf("WriteTo should fail as ErrWriteToConnected: %v", err)
+	}
+
+	_, err = c.Write([]byte("Connection-oriented mode socket"))
+	if err != nil {
+		t.Fatalf("Write failed: %v", err)
+	}
+}
+
+func testWriteToPacketConn(t *testing.T, raddr string) {
+	c, err := ListenPacket("udp", "127.0.0.1:0")
+	if err != nil {
+		t.Fatalf("ListenPacket failed: %v", err)
+	}
+	defer c.Close()
+
+	ra, err := ResolveUDPAddr("udp", raddr)
+	if err != nil {
+		t.Fatalf("ResolveUDPAddr failed: %v", err)
+	}
+
+	_, err = c.(*UDPConn).WriteToUDP([]byte("Connection-less mode socket"), ra)
+	if err != nil {
+		t.Fatalf("WriteToUDP failed: %v", err)
+	}
+
+	_, err = c.WriteTo([]byte("Connection-less mode socket"), ra)
+	if err != nil {
+		t.Fatalf("WriteTo failed: %v", err)
+	}
+
+	_, err = c.(*UDPConn).Write([]byte("Connection-less mode socket"))
+	if err == nil {
+		t.Fatal("Write should fail")
+	}
+}
+
+var udpConnLocalNameTests = []struct {
+	net   string
+	laddr *UDPAddr
+}{
+	{"udp4", &UDPAddr{IP: IPv4(127, 0, 0, 1)}},
+	{"udp4", &UDPAddr{}},
+	{"udp4", nil},
+}
+
+func TestUDPConnLocalName(t *testing.T) {
+	if testing.Short() || !*testExternal {
+		t.Skip("skipping test to avoid external network")
+	}
+
+	for _, tt := range udpConnLocalNameTests {
+		c, err := ListenUDP(tt.net, tt.laddr)
+		if err != nil {
+			t.Fatalf("ListenUDP failed: %v", err)
+		}
+		defer c.Close()
+		la := c.LocalAddr()
+		if a, ok := la.(*UDPAddr); !ok || a.Port == 0 {
+			t.Fatalf("got %v; expected a proper address with non-zero port number", la)
+		}
+	}
+}
+
+func TestUDPConnLocalAndRemoteNames(t *testing.T) {
+	for _, laddr := range []string{"", "127.0.0.1:0"} {
+		c1, err := ListenPacket("udp", "127.0.0.1:0")
+		if err != nil {
+			t.Fatalf("ListenUDP failed: %v", err)
+		}
+		defer c1.Close()
+
+		var la *UDPAddr
+		if laddr != "" {
+			var err error
+			if la, err = ResolveUDPAddr("udp", laddr); err != nil {
+				t.Fatalf("ResolveUDPAddr failed: %v", err)
+			}
+		}
+		c2, err := DialUDP("udp", la, c1.LocalAddr().(*UDPAddr))
+		if err != nil {
+			t.Fatalf("DialUDP failed: %v", err)
+		}
+		defer c2.Close()
+
+		var connAddrs = [4]struct {
+			got Addr
+			ok  bool
+		}{
+			{c1.LocalAddr(), true},
+			{c1.(*UDPConn).RemoteAddr(), false},
+			{c2.LocalAddr(), true},
+			{c2.RemoteAddr(), true},
+		}
+		for _, ca := range connAddrs {
+			if a, ok := ca.got.(*UDPAddr); ok != ca.ok || ok && a.Port == 0 {
+				t.Fatalf("got %v; expected a proper address with non-zero port number", ca.got)
+			}
+		}
+	}
+}
+
+func TestIPv6LinkLocalUnicastUDP(t *testing.T) {
+	if testing.Short() || !*testExternal {
+		t.Skip("skipping test to avoid external network")
+	}
+	if !supportsIPv6 {
+		t.Skip("ipv6 is not supported")
+	}
+	ifi := loopbackInterface()
+	if ifi == nil {
+		t.Skip("loopback interface not found")
+	}
+	laddr := ipv6LinkLocalUnicastAddr(ifi)
+	if laddr == "" {
+		t.Skip("ipv6 unicast address on loopback not found")
+	}
+
+	type test struct {
+		net, addr  string
+		nameLookup bool
+	}
+	var tests = []test{
+		{"udp", "[" + laddr + "%" + ifi.Name + "]:0", false},
+		{"udp6", "[" + laddr + "%" + ifi.Name + "]:0", false},
+	}
+	// The first udp test fails on DragonFly - see issue 7473.
+	if runtime.GOOS == "dragonfly" {
+		tests = tests[1:]
+	}
+	switch runtime.GOOS {
+	case "darwin", "dragonfly", "freebsd", "openbsd", "netbsd":
+		tests = append(tests, []test{
+			{"udp", "[localhost%" + ifi.Name + "]:0", true},
+			{"udp6", "[localhost%" + ifi.Name + "]:0", true},
+		}...)
+	case "linux":
+		tests = append(tests, []test{
+			{"udp", "[ip6-localhost%" + ifi.Name + "]:0", true},
+			{"udp6", "[ip6-localhost%" + ifi.Name + "]:0", true},
+		}...)
+	}
+	for _, tt := range tests {
+		c1, err := ListenPacket(tt.net, tt.addr)
+		if err != nil {
+			// It might return "LookupHost returned no
+			// suitable address" error on some platforms.
+			t.Logf("ListenPacket failed: %v", err)
+			continue
+		}
+		defer c1.Close()
+		if la, ok := c1.LocalAddr().(*UDPAddr); !ok || !tt.nameLookup && la.Zone == "" {
+			t.Fatalf("got %v; expected a proper address with zone identifier", la)
+		}
+
+		c2, err := Dial(tt.net, c1.LocalAddr().String())
+		if err != nil {
+			t.Fatalf("Dial failed: %v", err)
+		}
+		defer c2.Close()
+		if la, ok := c2.LocalAddr().(*UDPAddr); !ok || !tt.nameLookup && la.Zone == "" {
+			t.Fatalf("got %v; expected a proper address with zone identifier", la)
+		}
+		if ra, ok := c2.RemoteAddr().(*UDPAddr); !ok || !tt.nameLookup && ra.Zone == "" {
+			t.Fatalf("got %v; expected a proper address with zone identifier", ra)
+		}
+
+		if _, err := c2.Write([]byte("UDP OVER IPV6 LINKLOCAL TEST")); err != nil {
+			t.Fatalf("Conn.Write failed: %v", err)
+		}
+		b := make([]byte, 32)
+		if _, from, err := c1.ReadFrom(b); err != nil {
+			t.Fatalf("PacketConn.ReadFrom failed: %v", err)
+		} else {
+			if ra, ok := from.(*UDPAddr); !ok || !tt.nameLookup && ra.Zone == "" {
+				t.Fatalf("got %v; expected a proper address with zone identifier", ra)
+			}
+		}
+	}
+}
diff --git a/src/pkg/net/udpsock.go b/src/net/udpsock.go
similarity index 100%
rename from src/pkg/net/udpsock.go
rename to src/net/udpsock.go
diff --git a/src/pkg/net/udpsock_plan9.go b/src/net/udpsock_plan9.go
similarity index 100%
rename from src/pkg/net/udpsock_plan9.go
rename to src/net/udpsock_plan9.go
diff --git a/src/net/udpsock_posix.go b/src/net/udpsock_posix.go
new file mode 100644
index 0000000..a053336
--- /dev/null
+++ b/src/net/udpsock_posix.go
@@ -0,0 +1,268 @@
+// Copyright 2009 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris windows
+
+package net
+
+import (
+	"syscall"
+	"time"
+)
+
+func sockaddrToUDP(sa syscall.Sockaddr) Addr {
+	switch sa := sa.(type) {
+	case *syscall.SockaddrInet4:
+		return &UDPAddr{IP: sa.Addr[0:], Port: sa.Port}
+	case *syscall.SockaddrInet6:
+		return &UDPAddr{IP: sa.Addr[0:], Port: sa.Port, Zone: zoneToString(int(sa.ZoneId))}
+	}
+	return nil
+}
+
+func (a *UDPAddr) family() int {
+	if a == nil || len(a.IP) <= IPv4len {
+		return syscall.AF_INET
+	}
+	if a.IP.To4() != nil {
+		return syscall.AF_INET
+	}
+	return syscall.AF_INET6
+}
+
+func (a *UDPAddr) isWildcard() bool {
+	if a == nil || a.IP == nil {
+		return true
+	}
+	return a.IP.IsUnspecified()
+}
+
+func (a *UDPAddr) sockaddr(family int) (syscall.Sockaddr, error) {
+	if a == nil {
+		return nil, nil
+	}
+	return ipToSockaddr(family, a.IP, a.Port, a.Zone)
+}
+
+// UDPConn is the implementation of the Conn and PacketConn interfaces
+// for UDP network connections.
+type UDPConn struct {
+	conn
+}
+
+func newUDPConn(fd *netFD) *UDPConn { return &UDPConn{conn{fd}} }
+
+// ReadFromUDP reads a UDP packet from c, copying the payload into b.
+// It returns the number of bytes copied into b and the return address
+// that was on the packet.
+//
+// ReadFromUDP can be made to time out and return an error with
+// Timeout() == true after a fixed time limit; see SetDeadline and
+// SetReadDeadline.
+func (c *UDPConn) ReadFromUDP(b []byte) (n int, addr *UDPAddr, err error) {
+	if !c.ok() {
+		return 0, nil, syscall.EINVAL
+	}
+	n, sa, err := c.fd.readFrom(b)
+	switch sa := sa.(type) {
+	case *syscall.SockaddrInet4:
+		addr = &UDPAddr{IP: sa.Addr[0:], Port: sa.Port}
+	case *syscall.SockaddrInet6:
+		addr = &UDPAddr{IP: sa.Addr[0:], Port: sa.Port, Zone: zoneToString(int(sa.ZoneId))}
+	}
+	return
+}
+
+// ReadFrom implements the PacketConn ReadFrom method.
+func (c *UDPConn) ReadFrom(b []byte) (int, Addr, error) {
+	if !c.ok() {
+		return 0, nil, syscall.EINVAL
+	}
+	n, addr, err := c.ReadFromUDP(b)
+	return n, addr.toAddr(), err
+}
+
+// ReadMsgUDP reads a packet from c, copying the payload into b and
+// the associated out-of-band data into oob.  It returns the number
+// of bytes copied into b, the number of bytes copied into oob, the
+// flags that were set on the packet and the source address of the
+// packet.
+func (c *UDPConn) ReadMsgUDP(b, oob []byte) (n, oobn, flags int, addr *UDPAddr, err error) {
+	if !c.ok() {
+		return 0, 0, 0, nil, syscall.EINVAL
+	}
+	var sa syscall.Sockaddr
+	n, oobn, flags, sa, err = c.fd.readMsg(b, oob)
+	switch sa := sa.(type) {
+	case *syscall.SockaddrInet4:
+		addr = &UDPAddr{IP: sa.Addr[0:], Port: sa.Port}
+	case *syscall.SockaddrInet6:
+		addr = &UDPAddr{IP: sa.Addr[0:], Port: sa.Port, Zone: zoneToString(int(sa.ZoneId))}
+	}
+	return
+}
+
+// WriteToUDP writes a UDP packet to addr via c, copying the payload
+// from b.
+//
+// WriteToUDP can be made to time out and return an error with
+// Timeout() == true after a fixed time limit; see SetDeadline and
+// SetWriteDeadline.  On packet-oriented connections, write timeouts
+// are rare.
+func (c *UDPConn) WriteToUDP(b []byte, addr *UDPAddr) (int, error) {
+	if !c.ok() {
+		return 0, syscall.EINVAL
+	}
+	if c.fd.isConnected {
+		return 0, &OpError{"write", c.fd.net, addr, ErrWriteToConnected}
+	}
+	if addr == nil {
+		return 0, &OpError{Op: "write", Net: c.fd.net, Addr: nil, Err: errMissingAddress}
+	}
+	sa, err := addr.sockaddr(c.fd.family)
+	if err != nil {
+		return 0, &OpError{"write", c.fd.net, addr, err}
+	}
+	return c.fd.writeTo(b, sa)
+}
+
+// WriteTo implements the PacketConn WriteTo method.
+func (c *UDPConn) WriteTo(b []byte, addr Addr) (int, error) {
+	if !c.ok() {
+		return 0, syscall.EINVAL
+	}
+	a, ok := addr.(*UDPAddr)
+	if !ok {
+		return 0, &OpError{"write", c.fd.net, addr, syscall.EINVAL}
+	}
+	return c.WriteToUDP(b, a)
+}
+
+// WriteMsgUDP writes a packet to addr via c, copying the payload from
+// b and the associated out-of-band data from oob.  It returns the
+// number of payload and out-of-band bytes written.
+func (c *UDPConn) WriteMsgUDP(b, oob []byte, addr *UDPAddr) (n, oobn int, err error) {
+	if !c.ok() {
+		return 0, 0, syscall.EINVAL
+	}
+	if c.fd.isConnected {
+		return 0, 0, &OpError{"write", c.fd.net, addr, ErrWriteToConnected}
+	}
+	if addr == nil {
+		return 0, 0, &OpError{Op: "write", Net: c.fd.net, Addr: nil, Err: errMissingAddress}
+	}
+	sa, err := addr.sockaddr(c.fd.family)
+	if err != nil {
+		return 0, 0, &OpError{"write", c.fd.net, addr, err}
+	}
+	return c.fd.writeMsg(b, oob, sa)
+}
+
+// DialUDP connects to the remote address raddr on the network net,
+// which must be "udp", "udp4", or "udp6".  If laddr is not nil, it is
+// used as the local address for the connection.
+func DialUDP(net string, laddr, raddr *UDPAddr) (*UDPConn, error) {
+	switch net {
+	case "udp", "udp4", "udp6":
+	default:
+		return nil, &OpError{Op: "dial", Net: net, Addr: raddr, Err: UnknownNetworkError(net)}
+	}
+	if raddr == nil {
+		return nil, &OpError{Op: "dial", Net: net, Addr: nil, Err: errMissingAddress}
+	}
+	return dialUDP(net, laddr, raddr, noDeadline)
+}
+
+func dialUDP(net string, laddr, raddr *UDPAddr, deadline time.Time) (*UDPConn, error) {
+	fd, err := internetSocket(net, laddr, raddr, deadline, syscall.SOCK_DGRAM, 0, "dial")
+	if err != nil {
+		return nil, &OpError{Op: "dial", Net: net, Addr: raddr, Err: err}
+	}
+	return newUDPConn(fd), nil
+}
+
+// ListenUDP listens for incoming UDP packets addressed to the local
+// address laddr.  Net must be "udp", "udp4", or "udp6".  If laddr has
+// a port of 0, ListenUDP will choose an available port.
+// The LocalAddr method of the returned UDPConn can be used to
+// discover the port.  The returned connection's ReadFrom and WriteTo
+// methods can be used to receive and send UDP packets with per-packet
+// addressing.
+func ListenUDP(net string, laddr *UDPAddr) (*UDPConn, error) {
+	switch net {
+	case "udp", "udp4", "udp6":
+	default:
+		return nil, &OpError{Op: "listen", Net: net, Addr: laddr, Err: UnknownNetworkError(net)}
+	}
+	if laddr == nil {
+		laddr = &UDPAddr{}
+	}
+	fd, err := internetSocket(net, laddr, nil, noDeadline, syscall.SOCK_DGRAM, 0, "listen")
+	if err != nil {
+		return nil, &OpError{Op: "listen", Net: net, Addr: laddr, Err: err}
+	}
+	return newUDPConn(fd), nil
+}
+
+// ListenMulticastUDP listens for incoming multicast UDP packets
+// addressed to the group address gaddr on ifi, which specifies the
+// interface to join.  ListenMulticastUDP uses default multicast
+// interface if ifi is nil.
+func ListenMulticastUDP(net string, ifi *Interface, gaddr *UDPAddr) (*UDPConn, error) {
+	switch net {
+	case "udp", "udp4", "udp6":
+	default:
+		return nil, &OpError{Op: "listen", Net: net, Addr: gaddr, Err: UnknownNetworkError(net)}
+	}
+	if gaddr == nil || gaddr.IP == nil {
+		return nil, &OpError{Op: "listen", Net: net, Addr: nil, Err: errMissingAddress}
+	}
+	fd, err := internetSocket(net, gaddr, nil, noDeadline, syscall.SOCK_DGRAM, 0, "listen")
+	if err != nil {
+		return nil, &OpError{Op: "listen", Net: net, Addr: gaddr, Err: err}
+	}
+	c := newUDPConn(fd)
+	if ip4 := gaddr.IP.To4(); ip4 != nil {
+		if err := listenIPv4MulticastUDP(c, ifi, ip4); err != nil {
+			c.Close()
+			return nil, &OpError{Op: "listen", Net: net, Addr: &IPAddr{IP: ip4}, Err: err}
+		}
+	} else {
+		if err := listenIPv6MulticastUDP(c, ifi, gaddr.IP); err != nil {
+			c.Close()
+			return nil, &OpError{Op: "listen", Net: net, Addr: &IPAddr{IP: gaddr.IP}, Err: err}
+		}
+	}
+	return c, nil
+}
+
+func listenIPv4MulticastUDP(c *UDPConn, ifi *Interface, ip IP) error {
+	if ifi != nil {
+		if err := setIPv4MulticastInterface(c.fd, ifi); err != nil {
+			return err
+		}
+	}
+	if err := setIPv4MulticastLoopback(c.fd, false); err != nil {
+		return err
+	}
+	if err := joinIPv4Group(c.fd, ifi, ip); err != nil {
+		return err
+	}
+	return nil
+}
+
+func listenIPv6MulticastUDP(c *UDPConn, ifi *Interface, ip IP) error {
+	if ifi != nil {
+		if err := setIPv6MulticastInterface(c.fd, ifi); err != nil {
+			return err
+		}
+	}
+	if err := setIPv6MulticastLoopback(c.fd, false); err != nil {
+		return err
+	}
+	if err := joinIPv6Group(c.fd, ifi, ip); err != nil {
+		return err
+	}
+	return nil
+}
diff --git a/src/net/unicast_posix_test.go b/src/net/unicast_posix_test.go
new file mode 100644
index 0000000..ab7ef40
--- /dev/null
+++ b/src/net/unicast_posix_test.go
@@ -0,0 +1,469 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !plan9
+
+package net
+
+import (
+	"runtime"
+	"syscall"
+	"testing"
+)
+
+var listenerTests = []struct {
+	net      string
+	laddr    string
+	ipv6     bool // test with underlying AF_INET6 socket
+	wildcard bool // test with wildcard address
+}{
+	{net: "tcp", laddr: "", wildcard: true},
+	{net: "tcp", laddr: "0.0.0.0", wildcard: true},
+	{net: "tcp", laddr: "[::ffff:0.0.0.0]", wildcard: true},
+	{net: "tcp", laddr: "[::]", ipv6: true, wildcard: true},
+
+	{net: "tcp", laddr: "127.0.0.1"},
+	{net: "tcp", laddr: "[::ffff:127.0.0.1]"},
+	{net: "tcp", laddr: "[::1]", ipv6: true},
+
+	{net: "tcp4", laddr: "", wildcard: true},
+	{net: "tcp4", laddr: "0.0.0.0", wildcard: true},
+	{net: "tcp4", laddr: "[::ffff:0.0.0.0]", wildcard: true},
+
+	{net: "tcp4", laddr: "127.0.0.1"},
+	{net: "tcp4", laddr: "[::ffff:127.0.0.1]"},
+
+	{net: "tcp6", laddr: "", ipv6: true, wildcard: true},
+	{net: "tcp6", laddr: "[::]", ipv6: true, wildcard: true},
+
+	{net: "tcp6", laddr: "[::1]", ipv6: true},
+}
+
+// TestTCPListener tests both single and double listen to a test
+// listener with same address family, same listening address and
+// same port.
+func TestTCPListener(t *testing.T) {
+	switch runtime.GOOS {
+	case "plan9":
+		t.Skipf("skipping test on %q", runtime.GOOS)
+	}
+
+	for _, tt := range listenerTests {
+		if tt.wildcard && (testing.Short() || !*testExternal) {
+			continue
+		}
+		if tt.ipv6 && !supportsIPv6 {
+			continue
+		}
+		l1, port := usableListenPort(t, tt.net, tt.laddr)
+		checkFirstListener(t, tt.net, tt.laddr+":"+port, l1)
+		l2, err := Listen(tt.net, tt.laddr+":"+port)
+		checkSecondListener(t, tt.net, tt.laddr+":"+port, err, l2)
+		l1.Close()
+	}
+}
+
+// TestUDPListener tests both single and double listen to a test
+// listener with same address family, same listening address and
+// same port.
+func TestUDPListener(t *testing.T) {
+	switch runtime.GOOS {
+	case "plan9":
+		t.Skipf("skipping test on %q", runtime.GOOS)
+	}
+
+	toudpnet := func(net string) string {
+		switch net {
+		case "tcp":
+			return "udp"
+		case "tcp4":
+			return "udp4"
+		case "tcp6":
+			return "udp6"
+		}
+		return "<nil>"
+	}
+
+	for _, tt := range listenerTests {
+		if tt.wildcard && (testing.Short() || !*testExternal) {
+			continue
+		}
+		if tt.ipv6 && !supportsIPv6 {
+			continue
+		}
+		tt.net = toudpnet(tt.net)
+		l1, port := usableListenPacketPort(t, tt.net, tt.laddr)
+		checkFirstListener(t, tt.net, tt.laddr+":"+port, l1)
+		l2, err := ListenPacket(tt.net, tt.laddr+":"+port)
+		checkSecondListener(t, tt.net, tt.laddr+":"+port, err, l2)
+		l1.Close()
+	}
+}
+
+var dualStackListenerTests = []struct {
+	net1     string // first listener
+	laddr1   string
+	net2     string // second listener
+	laddr2   string
+	wildcard bool  // test with wildcard address
+	xerr     error // expected error value, nil or other
+}{
+	// Test cases and expected results for the attemping 2nd listen on the same port
+	// 1st listen                2nd listen                 darwin  freebsd  linux  openbsd
+	// ------------------------------------------------------------------------------------
+	// "tcp"  ""                 "tcp"  ""                    -        -       -       -
+	// "tcp"  ""                 "tcp"  "0.0.0.0"             -        -       -       -
+	// "tcp"  "0.0.0.0"          "tcp"  ""                    -        -       -       -
+	// ------------------------------------------------------------------------------------
+	// "tcp"  ""                 "tcp"  "[::]"                -        -       -       ok
+	// "tcp"  "[::]"             "tcp"  ""                    -        -       -       ok
+	// "tcp"  "0.0.0.0"          "tcp"  "[::]"                -        -       -       ok
+	// "tcp"  "[::]"             "tcp"  "0.0.0.0"             -        -       -       ok
+	// "tcp"  "[::ffff:0.0.0.0]" "tcp"  "[::]"                -        -       -       ok
+	// "tcp"  "[::]"             "tcp"  "[::ffff:0.0.0.0]"    -        -       -       ok
+	// ------------------------------------------------------------------------------------
+	// "tcp4" ""                 "tcp6" ""                    ok       ok      ok      ok
+	// "tcp6" ""                 "tcp4" ""                    ok       ok      ok      ok
+	// "tcp4" "0.0.0.0"          "tcp6" "[::]"                ok       ok      ok      ok
+	// "tcp6" "[::]"             "tcp4" "0.0.0.0"             ok       ok      ok      ok
+	// ------------------------------------------------------------------------------------
+	// "tcp"  "127.0.0.1"        "tcp"  "[::1]"               ok       ok      ok      ok
+	// "tcp"  "[::1]"            "tcp"  "127.0.0.1"           ok       ok      ok      ok
+	// "tcp4" "127.0.0.1"        "tcp6" "[::1]"               ok       ok      ok      ok
+	// "tcp6" "[::1]"            "tcp4" "127.0.0.1"           ok       ok      ok      ok
+	//
+	// Platform default configurations:
+	// darwin, kernel version 11.3.0
+	//	net.inet6.ip6.v6only=0 (overridable by sysctl or IPV6_V6ONLY option)
+	// freebsd, kernel version 8.2
+	//	net.inet6.ip6.v6only=1 (overridable by sysctl or IPV6_V6ONLY option)
+	// linux, kernel version 3.0.0
+	//	net.ipv6.bindv6only=0 (overridable by sysctl or IPV6_V6ONLY option)
+	// openbsd, kernel version 5.0
+	//	net.inet6.ip6.v6only=1 (overriding is prohibited)
+
+	{net1: "tcp", laddr1: "", net2: "tcp", laddr2: "", wildcard: true, xerr: syscall.EADDRINUSE},
+	{net1: "tcp", laddr1: "", net2: "tcp", laddr2: "0.0.0.0", wildcard: true, xerr: syscall.EADDRINUSE},
+	{net1: "tcp", laddr1: "0.0.0.0", net2: "tcp", laddr2: "", wildcard: true, xerr: syscall.EADDRINUSE},
+
+	{net1: "tcp", laddr1: "", net2: "tcp", laddr2: "[::]", wildcard: true, xerr: syscall.EADDRINUSE},
+	{net1: "tcp", laddr1: "[::]", net2: "tcp", laddr2: "", wildcard: true, xerr: syscall.EADDRINUSE},
+	{net1: "tcp", laddr1: "0.0.0.0", net2: "tcp", laddr2: "[::]", wildcard: true, xerr: syscall.EADDRINUSE},
+	{net1: "tcp", laddr1: "[::]", net2: "tcp", laddr2: "0.0.0.0", wildcard: true, xerr: syscall.EADDRINUSE},
+	{net1: "tcp", laddr1: "[::ffff:0.0.0.0]", net2: "tcp", laddr2: "[::]", wildcard: true, xerr: syscall.EADDRINUSE},
+	{net1: "tcp", laddr1: "[::]", net2: "tcp", laddr2: "[::ffff:0.0.0.0]", wildcard: true, xerr: syscall.EADDRINUSE},
+
+	{net1: "tcp4", laddr1: "", net2: "tcp6", laddr2: "", wildcard: true},
+	{net1: "tcp6", laddr1: "", net2: "tcp4", laddr2: "", wildcard: true},
+	{net1: "tcp4", laddr1: "0.0.0.0", net2: "tcp6", laddr2: "[::]", wildcard: true},
+	{net1: "tcp6", laddr1: "[::]", net2: "tcp4", laddr2: "0.0.0.0", wildcard: true},
+
+	{net1: "tcp", laddr1: "127.0.0.1", net2: "tcp", laddr2: "[::1]"},
+	{net1: "tcp", laddr1: "[::1]", net2: "tcp", laddr2: "127.0.0.1"},
+	{net1: "tcp4", laddr1: "127.0.0.1", net2: "tcp6", laddr2: "[::1]"},
+	{net1: "tcp6", laddr1: "[::1]", net2: "tcp4", laddr2: "127.0.0.1"},
+}
+
+// TestDualStackTCPListener tests both single and double listen
+// to a test listener with various address families, different
+// listening address and same port.
+func TestDualStackTCPListener(t *testing.T) {
+	if testing.Short() {
+		t.Skip("skipping in -short mode, see issue 5001")
+	}
+	switch runtime.GOOS {
+	case "plan9":
+		t.Skipf("skipping test on %q", runtime.GOOS)
+	}
+	if !supportsIPv6 {
+		t.Skip("ipv6 is not supported")
+	}
+
+	for _, tt := range dualStackListenerTests {
+		if tt.wildcard && !*testExternal {
+			continue
+		}
+		switch runtime.GOOS {
+		case "openbsd":
+			if tt.wildcard && differentWildcardAddr(tt.laddr1, tt.laddr2) {
+				tt.xerr = nil
+			}
+		}
+		l1, port := usableListenPort(t, tt.net1, tt.laddr1)
+		laddr := tt.laddr1 + ":" + port
+		checkFirstListener(t, tt.net1, laddr, l1)
+		laddr = tt.laddr2 + ":" + port
+		l2, err := Listen(tt.net2, laddr)
+		checkDualStackSecondListener(t, tt.net2, laddr, tt.xerr, err, l2)
+		l1.Close()
+	}
+}
+
+// TestDualStackUDPListener tests both single and double listen
+// to a test listener with various address families, differnet
+// listening address and same port.
+func TestDualStackUDPListener(t *testing.T) {
+	if testing.Short() {
+		t.Skip("skipping in -short mode, see issue 5001")
+	}
+	switch runtime.GOOS {
+	case "plan9":
+		t.Skipf("skipping test on %q", runtime.GOOS)
+	}
+	if !supportsIPv6 {
+		t.Skip("ipv6 is not supported")
+	}
+
+	toudpnet := func(net string) string {
+		switch net {
+		case "tcp":
+			return "udp"
+		case "tcp4":
+			return "udp4"
+		case "tcp6":
+			return "udp6"
+		}
+		return "<nil>"
+	}
+
+	for _, tt := range dualStackListenerTests {
+		if tt.wildcard && (testing.Short() || !*testExternal) {
+			continue
+		}
+		tt.net1 = toudpnet(tt.net1)
+		tt.net2 = toudpnet(tt.net2)
+		switch runtime.GOOS {
+		case "openbsd":
+			if tt.wildcard && differentWildcardAddr(tt.laddr1, tt.laddr2) {
+				tt.xerr = nil
+			}
+		}
+		l1, port := usableListenPacketPort(t, tt.net1, tt.laddr1)
+		laddr := tt.laddr1 + ":" + port
+		checkFirstListener(t, tt.net1, laddr, l1)
+		laddr = tt.laddr2 + ":" + port
+		l2, err := ListenPacket(tt.net2, laddr)
+		checkDualStackSecondListener(t, tt.net2, laddr, tt.xerr, err, l2)
+		l1.Close()
+	}
+}
+
+func usableListenPort(t *testing.T, net, laddr string) (l Listener, port string) {
+	var nladdr string
+	var err error
+	switch net {
+	default:
+		panic("usableListenPort net=" + net)
+	case "tcp", "tcp4", "tcp6":
+		l, err = Listen(net, laddr+":0")
+		if err != nil {
+			t.Fatalf("Probe Listen(%q, %q) failed: %v", net, laddr, err)
+		}
+		nladdr = l.(*TCPListener).Addr().String()
+	}
+	_, port, err = SplitHostPort(nladdr)
+	if err != nil {
+		t.Fatalf("SplitHostPort failed: %v", err)
+	}
+	return l, port
+}
+
+func usableListenPacketPort(t *testing.T, net, laddr string) (l PacketConn, port string) {
+	var nladdr string
+	var err error
+	switch net {
+	default:
+		panic("usableListenPacketPort net=" + net)
+	case "udp", "udp4", "udp6":
+		l, err = ListenPacket(net, laddr+":0")
+		if err != nil {
+			t.Fatalf("Probe ListenPacket(%q, %q) failed: %v", net, laddr, err)
+		}
+		nladdr = l.(*UDPConn).LocalAddr().String()
+	}
+	_, port, err = SplitHostPort(nladdr)
+	if err != nil {
+		t.Fatalf("SplitHostPort failed: %v", err)
+	}
+	return l, port
+}
+
+func differentWildcardAddr(i, j string) bool {
+	if (i == "" || i == "0.0.0.0" || i == "::ffff:0.0.0.0") && (j == "" || j == "0.0.0.0" || j == "::ffff:0.0.0.0") {
+		return false
+	}
+	if i == "[::]" && j == "[::]" {
+		return false
+	}
+	return true
+}
+
+func checkFirstListener(t *testing.T, net, laddr string, l interface{}) {
+	switch net {
+	case "tcp":
+		fd := l.(*TCPListener).fd
+		checkDualStackAddrFamily(t, net, laddr, fd)
+	case "tcp4":
+		fd := l.(*TCPListener).fd
+		if fd.family != syscall.AF_INET {
+			t.Fatalf("First Listen(%q, %q) returns address family %v, expected %v", net, laddr, fd.family, syscall.AF_INET)
+		}
+	case "tcp6":
+		fd := l.(*TCPListener).fd
+		if fd.family != syscall.AF_INET6 {
+			t.Fatalf("First Listen(%q, %q) returns address family %v, expected %v", net, laddr, fd.family, syscall.AF_INET6)
+		}
+	case "udp":
+		fd := l.(*UDPConn).fd
+		checkDualStackAddrFamily(t, net, laddr, fd)
+	case "udp4":
+		fd := l.(*UDPConn).fd
+		if fd.family != syscall.AF_INET {
+			t.Fatalf("First ListenPacket(%q, %q) returns address family %v, expected %v", net, laddr, fd.family, syscall.AF_INET)
+		}
+	case "udp6":
+		fd := l.(*UDPConn).fd
+		if fd.family != syscall.AF_INET6 {
+			t.Fatalf("First ListenPacket(%q, %q) returns address family %v, expected %v", net, laddr, fd.family, syscall.AF_INET6)
+		}
+	default:
+		t.Fatalf("Unexpected network: %q", net)
+	}
+}
+
+func checkSecondListener(t *testing.T, net, laddr string, err error, l interface{}) {
+	switch net {
+	case "tcp", "tcp4", "tcp6":
+		if err == nil {
+			l.(*TCPListener).Close()
+			t.Fatalf("Second Listen(%q, %q) should fail", net, laddr)
+		}
+	case "udp", "udp4", "udp6":
+		if err == nil {
+			l.(*UDPConn).Close()
+			t.Fatalf("Second ListenPacket(%q, %q) should fail", net, laddr)
+		}
+	default:
+		t.Fatalf("Unexpected network: %q", net)
+	}
+}
+
+func checkDualStackSecondListener(t *testing.T, net, laddr string, xerr, err error, l interface{}) {
+	switch net {
+	case "tcp", "tcp4", "tcp6":
+		if xerr == nil && err != nil || xerr != nil && err == nil {
+			t.Fatalf("Second Listen(%q, %q) returns %v, expected %v", net, laddr, err, xerr)
+		}
+		if err == nil {
+			l.(*TCPListener).Close()
+		}
+	case "udp", "udp4", "udp6":
+		if xerr == nil && err != nil || xerr != nil && err == nil {
+			t.Fatalf("Second ListenPacket(%q, %q) returns %v, expected %v", net, laddr, err, xerr)
+		}
+		if err == nil {
+			l.(*UDPConn).Close()
+		}
+	default:
+		t.Fatalf("Unexpected network: %q", net)
+	}
+}
+
+func checkDualStackAddrFamily(t *testing.T, net, laddr string, fd *netFD) {
+	switch a := fd.laddr.(type) {
+	case *TCPAddr:
+		// If a node under test supports both IPv6 capability
+		// and IPv6 IPv4-mapping capability, we can assume
+		// that the node listens on a wildcard address with an
+		// AF_INET6 socket.
+		if supportsIPv4map && fd.laddr.(*TCPAddr).isWildcard() {
+			if fd.family != syscall.AF_INET6 {
+				t.Fatalf("Listen(%q, %q) returns address family %v, expected %v", net, laddr, fd.family, syscall.AF_INET6)
+			}
+		} else {
+			if fd.family != a.family() {
+				t.Fatalf("Listen(%q, %q) returns address family %v, expected %v", net, laddr, fd.family, a.family())
+			}
+		}
+	case *UDPAddr:
+		// If a node under test supports both IPv6 capability
+		// and IPv6 IPv4-mapping capability, we can assume
+		// that the node listens on a wildcard address with an
+		// AF_INET6 socket.
+		if supportsIPv4map && fd.laddr.(*UDPAddr).isWildcard() {
+			if fd.family != syscall.AF_INET6 {
+				t.Fatalf("ListenPacket(%q, %q) returns address family %v, expected %v", net, laddr, fd.family, syscall.AF_INET6)
+			}
+		} else {
+			if fd.family != a.family() {
+				t.Fatalf("ListenPacket(%q, %q) returns address family %v, expected %v", net, laddr, fd.family, a.family())
+			}
+		}
+	default:
+		t.Fatalf("Unexpected protocol address type: %T", a)
+	}
+}
+
+var prohibitionaryDialArgTests = []struct {
+	net  string
+	addr string
+}{
+	{"tcp6", "127.0.0.1"},
+	{"tcp6", "[::ffff:127.0.0.1]"},
+}
+
+func TestProhibitionaryDialArgs(t *testing.T) {
+	switch runtime.GOOS {
+	case "plan9":
+		t.Skipf("skipping test on %q", runtime.GOOS)
+	}
+	// This test requires both IPv6 and IPv6 IPv4-mapping functionality.
+	if !supportsIPv4map || testing.Short() || !*testExternal {
+		return
+	}
+
+	l, port := usableListenPort(t, "tcp", "[::]")
+	defer l.Close()
+
+	for _, tt := range prohibitionaryDialArgTests {
+		c, err := Dial(tt.net, tt.addr+":"+port)
+		if err == nil {
+			c.Close()
+			t.Fatalf("Dial(%q, %q) should fail", tt.net, tt.addr)
+		}
+	}
+}
+
+func TestWildWildcardListener(t *testing.T) {
+	switch runtime.GOOS {
+	case "plan9":
+		t.Skipf("skipping test on %q", runtime.GOOS)
+	}
+
+	if testing.Short() || !*testExternal {
+		t.Skip("skipping test to avoid external network")
+	}
+
+	defer func() {
+		if p := recover(); p != nil {
+			t.Fatalf("Listen, ListenPacket or protocol-specific Listen panicked: %v", p)
+		}
+	}()
+
+	if ln, err := Listen("tcp", ""); err == nil {
+		ln.Close()
+	}
+	if ln, err := ListenPacket("udp", ""); err == nil {
+		ln.Close()
+	}
+	if ln, err := ListenTCP("tcp", nil); err == nil {
+		ln.Close()
+	}
+	if ln, err := ListenUDP("udp", nil); err == nil {
+		ln.Close()
+	}
+	if ln, err := ListenIP("ip:icmp", nil); err == nil {
+		ln.Close()
+	}
+}
diff --git a/src/net/unix_test.go b/src/net/unix_test.go
new file mode 100644
index 0000000..1cdff39
--- /dev/null
+++ b/src/net/unix_test.go
@@ -0,0 +1,333 @@
+// Copyright 2013 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !nacl,!plan9,!windows
+
+package net
+
+import (
+	"bytes"
+	"os"
+	"reflect"
+	"runtime"
+	"syscall"
+	"testing"
+	"time"
+)
+
+func TestReadUnixgramWithUnnamedSocket(t *testing.T) {
+	addr := testUnixAddr()
+	la, err := ResolveUnixAddr("unixgram", addr)
+	if err != nil {
+		t.Fatalf("ResolveUnixAddr failed: %v", err)
+	}
+	c, err := ListenUnixgram("unixgram", la)
+	if err != nil {
+		t.Fatalf("ListenUnixgram failed: %v", err)
+	}
+	defer func() {
+		c.Close()
+		os.Remove(addr)
+	}()
+
+	off := make(chan bool)
+	data := [5]byte{1, 2, 3, 4, 5}
+	go func() {
+		defer func() { off <- true }()
+		s, err := syscall.Socket(syscall.AF_UNIX, syscall.SOCK_DGRAM, 0)
+		if err != nil {
+			t.Errorf("syscall.Socket failed: %v", err)
+			return
+		}
+		defer syscall.Close(s)
+		rsa := &syscall.SockaddrUnix{Name: addr}
+		if err := syscall.Sendto(s, data[:], 0, rsa); err != nil {
+			t.Errorf("syscall.Sendto failed: %v", err)
+			return
+		}
+	}()
+
+	<-off
+	b := make([]byte, 64)
+	c.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
+	n, from, err := c.ReadFrom(b)
+	if err != nil {
+		t.Fatalf("UnixConn.ReadFrom failed: %v", err)
+	}
+	if from != nil {
+		t.Fatalf("neighbor address is %v", from)
+	}
+	if !bytes.Equal(b[:n], data[:]) {
+		t.Fatalf("got %v, want %v", b[:n], data[:])
+	}
+}
+
+func TestReadUnixgramWithZeroBytesBuffer(t *testing.T) {
+	// issue 4352: Recvfrom failed with "address family not
+	// supported by protocol family" if zero-length buffer provided
+
+	addr := testUnixAddr()
+	la, err := ResolveUnixAddr("unixgram", addr)
+	if err != nil {
+		t.Fatalf("ResolveUnixAddr failed: %v", err)
+	}
+	c, err := ListenUnixgram("unixgram", la)
+	if err != nil {
+		t.Fatalf("ListenUnixgram failed: %v", err)
+	}
+	defer func() {
+		c.Close()
+		os.Remove(addr)
+	}()
+
+	off := make(chan bool)
+	go func() {
+		defer func() { off <- true }()
+		c, err := DialUnix("unixgram", nil, la)
+		if err != nil {
+			t.Errorf("DialUnix failed: %v", err)
+			return
+		}
+		defer c.Close()
+		if _, err := c.Write([]byte{1, 2, 3, 4, 5}); err != nil {
+			t.Errorf("UnixConn.Write failed: %v", err)
+			return
+		}
+	}()
+
+	<-off
+	c.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
+	_, from, err := c.ReadFrom(nil)
+	if err != nil {
+		t.Fatalf("UnixConn.ReadFrom failed: %v", err)
+	}
+	if from != nil {
+		t.Fatalf("neighbor address is %v", from)
+	}
+}
+
+func TestUnixgramAutobind(t *testing.T) {
+	if runtime.GOOS != "linux" {
+		t.Skip("skipping: autobind is linux only")
+	}
+
+	laddr := &UnixAddr{Name: "", Net: "unixgram"}
+	c1, err := ListenUnixgram("unixgram", laddr)
+	if err != nil {
+		t.Fatalf("ListenUnixgram failed: %v", err)
+	}
+	defer c1.Close()
+
+	// retrieve the autobind address
+	autoAddr := c1.LocalAddr().(*UnixAddr)
+	if len(autoAddr.Name) <= 1 {
+		t.Fatalf("invalid autobind address: %v", autoAddr)
+	}
+	if autoAddr.Name[0] != '@' {
+		t.Fatalf("invalid autobind address: %v", autoAddr)
+	}
+
+	c2, err := DialUnix("unixgram", nil, autoAddr)
+	if err != nil {
+		t.Fatalf("DialUnix failed: %v", err)
+	}
+	defer c2.Close()
+
+	if !reflect.DeepEqual(c1.LocalAddr(), c2.RemoteAddr()) {
+		t.Fatalf("expected autobind address %v, got %v", c1.LocalAddr(), c2.RemoteAddr())
+	}
+}
+
+func TestUnixAutobindClose(t *testing.T) {
+	if runtime.GOOS != "linux" {
+		t.Skip("skipping: autobind is linux only")
+	}
+	laddr := &UnixAddr{Name: "", Net: "unix"}
+	ln, err := ListenUnix("unix", laddr)
+	if err != nil {
+		t.Fatalf("ListenUnix failed: %v", err)
+	}
+	ln.Close()
+}
+
+func TestUnixgramWrite(t *testing.T) {
+	addr := testUnixAddr()
+	laddr, err := ResolveUnixAddr("unixgram", addr)
+	if err != nil {
+		t.Fatalf("ResolveUnixAddr failed: %v", err)
+	}
+	c, err := ListenPacket("unixgram", addr)
+	if err != nil {
+		t.Fatalf("ListenPacket failed: %v", err)
+	}
+	defer os.Remove(addr)
+	defer c.Close()
+
+	testUnixgramWriteConn(t, laddr)
+	testUnixgramWritePacketConn(t, laddr)
+}
+
+func testUnixgramWriteConn(t *testing.T, raddr *UnixAddr) {
+	c, err := Dial("unixgram", raddr.String())
+	if err != nil {
+		t.Fatalf("Dial failed: %v", err)
+	}
+	defer c.Close()
+
+	if _, err := c.(*UnixConn).WriteToUnix([]byte("Connection-oriented mode socket"), raddr); err == nil {
+		t.Fatal("WriteToUnix should fail")
+	} else if err.(*OpError).Err != ErrWriteToConnected {
+		t.Fatalf("WriteToUnix should fail as ErrWriteToConnected: %v", err)
+	}
+	if _, err = c.(*UnixConn).WriteTo([]byte("Connection-oriented mode socket"), raddr); err == nil {
+		t.Fatal("WriteTo should fail")
+	} else if err.(*OpError).Err != ErrWriteToConnected {
+		t.Fatalf("WriteTo should fail as ErrWriteToConnected: %v", err)
+	}
+	if _, _, err = c.(*UnixConn).WriteMsgUnix([]byte("Connection-oriented mode socket"), nil, raddr); err == nil {
+		t.Fatal("WriteTo should fail")
+	} else if err.(*OpError).Err != ErrWriteToConnected {
+		t.Fatalf("WriteMsgUnix should fail as ErrWriteToConnected: %v", err)
+	}
+	if _, err := c.Write([]byte("Connection-oriented mode socket")); err != nil {
+		t.Fatalf("Write failed: %v", err)
+	}
+}
+
+func testUnixgramWritePacketConn(t *testing.T, raddr *UnixAddr) {
+	addr := testUnixAddr()
+	c, err := ListenPacket("unixgram", addr)
+	if err != nil {
+		t.Fatalf("ListenPacket failed: %v", err)
+	}
+	defer os.Remove(addr)
+	defer c.Close()
+
+	if _, err := c.(*UnixConn).WriteToUnix([]byte("Connectionless mode socket"), raddr); err != nil {
+		t.Fatalf("WriteToUnix failed: %v", err)
+	}
+	if _, err := c.WriteTo([]byte("Connectionless mode socket"), raddr); err != nil {
+		t.Fatalf("WriteTo failed: %v", err)
+	}
+	if _, _, err := c.(*UnixConn).WriteMsgUnix([]byte("Connectionless mode socket"), nil, raddr); err != nil {
+		t.Fatalf("WriteMsgUnix failed: %v", err)
+	}
+	if _, err := c.(*UnixConn).Write([]byte("Connectionless mode socket")); err == nil {
+		t.Fatal("Write should fail")
+	}
+}
+
+func TestUnixConnLocalAndRemoteNames(t *testing.T) {
+	for _, laddr := range []string{"", testUnixAddr()} {
+		laddr := laddr
+		taddr := testUnixAddr()
+		ta, err := ResolveUnixAddr("unix", taddr)
+		if err != nil {
+			t.Fatalf("ResolveUnixAddr failed: %v", err)
+		}
+		ln, err := ListenUnix("unix", ta)
+		if err != nil {
+			t.Fatalf("ListenUnix failed: %v", err)
+		}
+		defer func() {
+			ln.Close()
+			os.Remove(taddr)
+		}()
+
+		done := make(chan int)
+		go transponder(t, ln, done)
+
+		la, err := ResolveUnixAddr("unix", laddr)
+		if err != nil {
+			t.Fatalf("ResolveUnixAddr failed: %v", err)
+		}
+		c, err := DialUnix("unix", la, ta)
+		if err != nil {
+			t.Fatalf("DialUnix failed: %v", err)
+		}
+		defer func() {
+			c.Close()
+			if la != nil {
+				defer os.Remove(laddr)
+			}
+		}()
+		if _, err := c.Write([]byte("UNIXCONN LOCAL AND REMOTE NAME TEST")); err != nil {
+			t.Fatalf("UnixConn.Write failed: %v", err)
+		}
+
+		switch runtime.GOOS {
+		case "android", "linux":
+			if laddr == "" {
+				laddr = "@" // autobind feature
+			}
+		}
+		var connAddrs = [3]struct{ got, want Addr }{
+			{ln.Addr(), ta},
+			{c.LocalAddr(), &UnixAddr{Name: laddr, Net: "unix"}},
+			{c.RemoteAddr(), ta},
+		}
+		for _, ca := range connAddrs {
+			if !reflect.DeepEqual(ca.got, ca.want) {
+				t.Fatalf("got %#v, expected %#v", ca.got, ca.want)
+			}
+		}
+
+		<-done
+	}
+}
+
+func TestUnixgramConnLocalAndRemoteNames(t *testing.T) {
+	for _, laddr := range []string{"", testUnixAddr()} {
+		laddr := laddr
+		taddr := testUnixAddr()
+		ta, err := ResolveUnixAddr("unixgram", taddr)
+		if err != nil {
+			t.Fatalf("ResolveUnixAddr failed: %v", err)
+		}
+		c1, err := ListenUnixgram("unixgram", ta)
+		if err != nil {
+			t.Fatalf("ListenUnixgram failed: %v", err)
+		}
+		defer func() {
+			c1.Close()
+			os.Remove(taddr)
+		}()
+
+		var la *UnixAddr
+		if laddr != "" {
+			if la, err = ResolveUnixAddr("unixgram", laddr); err != nil {
+				t.Fatalf("ResolveUnixAddr failed: %v", err)
+			}
+		}
+		c2, err := DialUnix("unixgram", la, ta)
+		if err != nil {
+			t.Fatalf("DialUnix failed: %v", err)
+		}
+		defer func() {
+			c2.Close()
+			if la != nil {
+				defer os.Remove(laddr)
+			}
+		}()
+
+		switch runtime.GOOS {
+		case "android", "linux":
+			if laddr == "" {
+				laddr = "@" // autobind feature
+			}
+		}
+
+		var connAddrs = [4]struct{ got, want Addr }{
+			{c1.LocalAddr(), ta},
+			{c1.RemoteAddr(), nil},
+			{c2.LocalAddr(), &UnixAddr{Name: laddr, Net: "unixgram"}},
+			{c2.RemoteAddr(), ta},
+		}
+		for _, ca := range connAddrs {
+			if !reflect.DeepEqual(ca.got, ca.want) {
+				t.Fatalf("got %#v, expected %#v", ca.got, ca.want)
+			}
+		}
+	}
+}
diff --git a/src/pkg/net/unixsock.go b/src/net/unixsock.go
similarity index 100%
rename from src/pkg/net/unixsock.go
rename to src/net/unixsock.go
diff --git a/src/pkg/net/unixsock_plan9.go b/src/net/unixsock_plan9.go
similarity index 100%
rename from src/pkg/net/unixsock_plan9.go
rename to src/net/unixsock_plan9.go
diff --git a/src/net/unixsock_posix.go b/src/net/unixsock_posix.go
new file mode 100644
index 0000000..3c2e78b
--- /dev/null
+++ b/src/net/unixsock_posix.go
@@ -0,0 +1,362 @@
+// Copyright 2009 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris windows
+
+package net
+
+import (
+	"errors"
+	"os"
+	"syscall"
+	"time"
+)
+
+func unixSocket(net string, laddr, raddr sockaddr, mode string, deadline time.Time) (*netFD, error) {
+	var sotype int
+	switch net {
+	case "unix":
+		sotype = syscall.SOCK_STREAM
+	case "unixgram":
+		sotype = syscall.SOCK_DGRAM
+	case "unixpacket":
+		sotype = syscall.SOCK_SEQPACKET
+	default:
+		return nil, UnknownNetworkError(net)
+	}
+
+	switch mode {
+	case "dial":
+		if laddr != nil && laddr.isWildcard() {
+			laddr = nil
+		}
+		if raddr != nil && raddr.isWildcard() {
+			raddr = nil
+		}
+		if raddr == nil && (sotype != syscall.SOCK_DGRAM || laddr == nil) {
+			return nil, errMissingAddress
+		}
+	case "listen":
+	default:
+		return nil, errors.New("unknown mode: " + mode)
+	}
+
+	fd, err := socket(net, syscall.AF_UNIX, sotype, 0, false, laddr, raddr, deadline)
+	if err != nil {
+		return nil, err
+	}
+	return fd, nil
+}
+
+func sockaddrToUnix(sa syscall.Sockaddr) Addr {
+	if s, ok := sa.(*syscall.SockaddrUnix); ok {
+		return &UnixAddr{Name: s.Name, Net: "unix"}
+	}
+	return nil
+}
+
+func sockaddrToUnixgram(sa syscall.Sockaddr) Addr {
+	if s, ok := sa.(*syscall.SockaddrUnix); ok {
+		return &UnixAddr{Name: s.Name, Net: "unixgram"}
+	}
+	return nil
+}
+
+func sockaddrToUnixpacket(sa syscall.Sockaddr) Addr {
+	if s, ok := sa.(*syscall.SockaddrUnix); ok {
+		return &UnixAddr{Name: s.Name, Net: "unixpacket"}
+	}
+	return nil
+}
+
+func sotypeToNet(sotype int) string {
+	switch sotype {
+	case syscall.SOCK_STREAM:
+		return "unix"
+	case syscall.SOCK_DGRAM:
+		return "unixgram"
+	case syscall.SOCK_SEQPACKET:
+		return "unixpacket"
+	default:
+		panic("sotypeToNet unknown socket type")
+	}
+}
+
+func (a *UnixAddr) family() int {
+	return syscall.AF_UNIX
+}
+
+func (a *UnixAddr) isWildcard() bool {
+	return a == nil || a.Name == ""
+}
+
+func (a *UnixAddr) sockaddr(family int) (syscall.Sockaddr, error) {
+	if a == nil {
+		return nil, nil
+	}
+	return &syscall.SockaddrUnix{Name: a.Name}, nil
+}
+
+// UnixConn is an implementation of the Conn interface for connections
+// to Unix domain sockets.
+type UnixConn struct {
+	conn
+}
+
+func newUnixConn(fd *netFD) *UnixConn { return &UnixConn{conn{fd}} }
+
+// ReadFromUnix reads a packet from c, copying the payload into b.  It
+// returns the number of bytes copied into b and the source address of
+// the packet.
+//
+// ReadFromUnix can be made to time out and return an error with
+// Timeout() == true after a fixed time limit; see SetDeadline and
+// SetReadDeadline.
+func (c *UnixConn) ReadFromUnix(b []byte) (n int, addr *UnixAddr, err error) {
+	if !c.ok() {
+		return 0, nil, syscall.EINVAL
+	}
+	n, sa, err := c.fd.readFrom(b)
+	switch sa := sa.(type) {
+	case *syscall.SockaddrUnix:
+		if sa.Name != "" {
+			addr = &UnixAddr{Name: sa.Name, Net: sotypeToNet(c.fd.sotype)}
+		}
+	}
+	return
+}
+
+// ReadFrom implements the PacketConn ReadFrom method.
+func (c *UnixConn) ReadFrom(b []byte) (int, Addr, error) {
+	if !c.ok() {
+		return 0, nil, syscall.EINVAL
+	}
+	n, addr, err := c.ReadFromUnix(b)
+	return n, addr.toAddr(), err
+}
+
+// ReadMsgUnix reads a packet from c, copying the payload into b and
+// the associated out-of-band data into oob.  It returns the number of
+// bytes copied into b, the number of bytes copied into oob, the flags
+// that were set on the packet, and the source address of the packet.
+func (c *UnixConn) ReadMsgUnix(b, oob []byte) (n, oobn, flags int, addr *UnixAddr, err error) {
+	if !c.ok() {
+		return 0, 0, 0, nil, syscall.EINVAL
+	}
+	n, oobn, flags, sa, err := c.fd.readMsg(b, oob)
+	switch sa := sa.(type) {
+	case *syscall.SockaddrUnix:
+		if sa.Name != "" {
+			addr = &UnixAddr{Name: sa.Name, Net: sotypeToNet(c.fd.sotype)}
+		}
+	}
+	return
+}
+
+// WriteToUnix writes a packet to addr via c, copying the payload from b.
+//
+// WriteToUnix can be made to time out and return an error with
+// Timeout() == true after a fixed time limit; see SetDeadline and
+// SetWriteDeadline.  On packet-oriented connections, write timeouts
+// are rare.
+func (c *UnixConn) WriteToUnix(b []byte, addr *UnixAddr) (n int, err error) {
+	if !c.ok() {
+		return 0, syscall.EINVAL
+	}
+	if c.fd.isConnected {
+		return 0, &OpError{Op: "write", Net: c.fd.net, Addr: addr, Err: ErrWriteToConnected}
+	}
+	if addr == nil {
+		return 0, &OpError{Op: "write", Net: c.fd.net, Addr: nil, Err: errMissingAddress}
+	}
+	if addr.Net != sotypeToNet(c.fd.sotype) {
+		return 0, syscall.EAFNOSUPPORT
+	}
+	sa := &syscall.SockaddrUnix{Name: addr.Name}
+	return c.fd.writeTo(b, sa)
+}
+
+// WriteTo implements the PacketConn WriteTo method.
+func (c *UnixConn) WriteTo(b []byte, addr Addr) (n int, err error) {
+	if !c.ok() {
+		return 0, syscall.EINVAL
+	}
+	a, ok := addr.(*UnixAddr)
+	if !ok {
+		return 0, &OpError{"write", c.fd.net, addr, syscall.EINVAL}
+	}
+	return c.WriteToUnix(b, a)
+}
+
+// WriteMsgUnix writes a packet to addr via c, copying the payload
+// from b and the associated out-of-band data from oob.  It returns
+// the number of payload and out-of-band bytes written.
+func (c *UnixConn) WriteMsgUnix(b, oob []byte, addr *UnixAddr) (n, oobn int, err error) {
+	if !c.ok() {
+		return 0, 0, syscall.EINVAL
+	}
+	if c.fd.sotype == syscall.SOCK_DGRAM && c.fd.isConnected {
+		return 0, 0, &OpError{Op: "write", Net: c.fd.net, Addr: addr, Err: ErrWriteToConnected}
+	}
+	if addr != nil {
+		if addr.Net != sotypeToNet(c.fd.sotype) {
+			return 0, 0, syscall.EAFNOSUPPORT
+		}
+		sa := &syscall.SockaddrUnix{Name: addr.Name}
+		return c.fd.writeMsg(b, oob, sa)
+	}
+	return c.fd.writeMsg(b, oob, nil)
+}
+
+// CloseRead shuts down the reading side of the Unix domain connection.
+// Most callers should just use Close.
+func (c *UnixConn) CloseRead() error {
+	if !c.ok() {
+		return syscall.EINVAL
+	}
+	return c.fd.closeRead()
+}
+
+// CloseWrite shuts down the writing side of the Unix domain connection.
+// Most callers should just use Close.
+func (c *UnixConn) CloseWrite() error {
+	if !c.ok() {
+		return syscall.EINVAL
+	}
+	return c.fd.closeWrite()
+}
+
+// DialUnix connects to the remote address raddr on the network net,
+// which must be "unix", "unixgram" or "unixpacket".  If laddr is not
+// nil, it is used as the local address for the connection.
+func DialUnix(net string, laddr, raddr *UnixAddr) (*UnixConn, error) {
+	switch net {
+	case "unix", "unixgram", "unixpacket":
+	default:
+		return nil, &OpError{Op: "dial", Net: net, Addr: raddr, Err: UnknownNetworkError(net)}
+	}
+	return dialUnix(net, laddr, raddr, noDeadline)
+}
+
+func dialUnix(net string, laddr, raddr *UnixAddr, deadline time.Time) (*UnixConn, error) {
+	fd, err := unixSocket(net, laddr, raddr, "dial", deadline)
+	if err != nil {
+		return nil, &OpError{Op: "dial", Net: net, Addr: raddr, Err: err}
+	}
+	return newUnixConn(fd), nil
+}
+
+// UnixListener is a Unix domain socket listener.  Clients should
+// typically use variables of type Listener instead of assuming Unix
+// domain sockets.
+type UnixListener struct {
+	fd   *netFD
+	path string
+}
+
+// ListenUnix announces on the Unix domain socket laddr and returns a
+// Unix listener.  The network net must be "unix" or "unixpacket".
+func ListenUnix(net string, laddr *UnixAddr) (*UnixListener, error) {
+	switch net {
+	case "unix", "unixpacket":
+	default:
+		return nil, &OpError{Op: "listen", Net: net, Addr: laddr, Err: UnknownNetworkError(net)}
+	}
+	if laddr == nil {
+		return nil, &OpError{Op: "listen", Net: net, Addr: nil, Err: errMissingAddress}
+	}
+	fd, err := unixSocket(net, laddr, nil, "listen", noDeadline)
+	if err != nil {
+		return nil, &OpError{Op: "listen", Net: net, Addr: laddr, Err: err}
+	}
+	return &UnixListener{fd, fd.laddr.String()}, nil
+}
+
+// AcceptUnix accepts the next incoming call and returns the new
+// connection.
+func (l *UnixListener) AcceptUnix() (*UnixConn, error) {
+	if l == nil || l.fd == nil {
+		return nil, syscall.EINVAL
+	}
+	fd, err := l.fd.accept()
+	if err != nil {
+		return nil, err
+	}
+	c := newUnixConn(fd)
+	return c, nil
+}
+
+// Accept implements the Accept method in the Listener interface; it
+// waits for the next call and returns a generic Conn.
+func (l *UnixListener) Accept() (c Conn, err error) {
+	c1, err := l.AcceptUnix()
+	if err != nil {
+		return nil, err
+	}
+	return c1, nil
+}
+
+// Close stops listening on the Unix address.  Already accepted
+// connections are not closed.
+func (l *UnixListener) Close() error {
+	if l == nil || l.fd == nil {
+		return syscall.EINVAL
+	}
+
+	// The operating system doesn't clean up
+	// the file that announcing created, so
+	// we have to clean it up ourselves.
+	// There's a race here--we can't know for
+	// sure whether someone else has come along
+	// and replaced our socket name already--
+	// but this sequence (remove then close)
+	// is at least compatible with the auto-remove
+	// sequence in ListenUnix.  It's only non-Go
+	// programs that can mess us up.
+	if l.path[0] != '@' {
+		syscall.Unlink(l.path)
+	}
+	return l.fd.Close()
+}
+
+// Addr returns the listener's network address.
+func (l *UnixListener) Addr() Addr { return l.fd.laddr }
+
+// SetDeadline sets the deadline associated with the listener.
+// A zero time value disables the deadline.
+func (l *UnixListener) SetDeadline(t time.Time) (err error) {
+	if l == nil || l.fd == nil {
+		return syscall.EINVAL
+	}
+	return l.fd.setDeadline(t)
+}
+
+// File returns a copy of the underlying os.File, set to blocking
+// mode.  It is the caller's responsibility to close f when finished.
+// Closing l does not affect f, and closing f does not affect l.
+//
+// The returned os.File's file descriptor is different from the
+// connection's.  Attempting to change properties of the original
+// using this duplicate may or may not have the desired effect.
+func (l *UnixListener) File() (f *os.File, err error) { return l.fd.dup() }
+
+// ListenUnixgram listens for incoming Unix datagram packets addressed
+// to the local address laddr.  The network net must be "unixgram".
+// The returned connection's ReadFrom and WriteTo methods can be used
+// to receive and send packets with per-packet addressing.
+func ListenUnixgram(net string, laddr *UnixAddr) (*UnixConn, error) {
+	switch net {
+	case "unixgram":
+	default:
+		return nil, &OpError{Op: "listen", Net: net, Addr: laddr, Err: UnknownNetworkError(net)}
+	}
+	if laddr == nil {
+		return nil, &OpError{Op: "listen", Net: net, Addr: nil, Err: errMissingAddress}
+	}
+	fd, err := unixSocket(net, laddr, nil, "listen", noDeadline)
+	if err != nil {
+		return nil, &OpError{Op: "listen", Net: net, Addr: laddr, Err: err}
+	}
+	return newUnixConn(fd), nil
+}
diff --git a/src/net/url/example_test.go b/src/net/url/example_test.go
new file mode 100644
index 0000000..e55c1aa
--- /dev/null
+++ b/src/net/url/example_test.go
@@ -0,0 +1,71 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package url_test
+
+import (
+	"fmt"
+	"log"
+	"net/http"
+	"net/http/httputil"
+	"net/url"
+	"strings"
+)
+
+func ExampleValues() {
+	v := url.Values{}
+	v.Set("name", "Ava")
+	v.Add("friend", "Jess")
+	v.Add("friend", "Sarah")
+	v.Add("friend", "Zoe")
+	// v.Encode() == "name=Ava&friend=Jess&friend=Sarah&friend=Zoe"
+	fmt.Println(v.Get("name"))
+	fmt.Println(v.Get("friend"))
+	fmt.Println(v["friend"])
+	// Output:
+	// Ava
+	// Jess
+	// [Jess Sarah Zoe]
+}
+
+func ExampleURL() {
+	u, err := url.Parse("http://bing.com/search?q=dotnet")
+	if err != nil {
+		log.Fatal(err)
+	}
+	u.Scheme = "https"
+	u.Host = "google.com"
+	q := u.Query()
+	q.Set("q", "golang")
+	u.RawQuery = q.Encode()
+	fmt.Println(u)
+	// Output: https://google.com/search?q=golang
+}
+
+func ExampleURL_opaque() {
+	// Sending a literal '%' in an HTTP request's Path
+	req := &http.Request{
+		Method: "GET",
+		Host:   "example.com", // takes precendence over URL.Host
+		URL: &url.URL{
+			Host:   "ignored",
+			Scheme: "https",
+			Opaque: "/%2f/",
+		},
+		Header: http.Header{
+			"User-Agent": {"godoc-example/0.1"},
+		},
+	}
+	out, err := httputil.DumpRequestOut(req, true)
+	if err != nil {
+		log.Fatal(err)
+	}
+	fmt.Println(strings.Replace(string(out), "\r", "", -1))
+	// Output:
+	// GET /%2f/ HTTP/1.1
+	// Host: example.com
+	// User-Agent: godoc-example/0.1
+	// Accept-Encoding: gzip
+	//
+}
diff --git a/src/net/url/url.go b/src/net/url/url.go
new file mode 100644
index 0000000..f167408
--- /dev/null
+++ b/src/net/url/url.go
@@ -0,0 +1,719 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package url parses URLs and implements query escaping.
+// See RFC 3986.
+package url
+
+import (
+	"bytes"
+	"errors"
+	"sort"
+	"strconv"
+	"strings"
+)
+
+// Error reports an error and the operation and URL that caused it.
+type Error struct {
+	Op  string
+	URL string
+	Err error
+}
+
+func (e *Error) Error() string { return e.Op + " " + e.URL + ": " + e.Err.Error() }
+
+func ishex(c byte) bool {
+	switch {
+	case '0' <= c && c <= '9':
+		return true
+	case 'a' <= c && c <= 'f':
+		return true
+	case 'A' <= c && c <= 'F':
+		return true
+	}
+	return false
+}
+
+func unhex(c byte) byte {
+	switch {
+	case '0' <= c && c <= '9':
+		return c - '0'
+	case 'a' <= c && c <= 'f':
+		return c - 'a' + 10
+	case 'A' <= c && c <= 'F':
+		return c - 'A' + 10
+	}
+	return 0
+}
+
+type encoding int
+
+const (
+	encodePath encoding = 1 + iota
+	encodeUserPassword
+	encodeQueryComponent
+	encodeFragment
+)
+
+type EscapeError string
+
+func (e EscapeError) Error() string {
+	return "invalid URL escape " + strconv.Quote(string(e))
+}
+
+// Return true if the specified character should be escaped when
+// appearing in a URL string, according to RFC 3986.
+func shouldEscape(c byte, mode encoding) bool {
+	// §2.3 Unreserved characters (alphanum)
+	if 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || '0' <= c && c <= '9' {
+		return false
+	}
+
+	switch c {
+	case '-', '_', '.', '~': // §2.3 Unreserved characters (mark)
+		return false
+
+	case '$', '&', '+', ',', '/', ':', ';', '=', '?', '@': // §2.2 Reserved characters (reserved)
+		// Different sections of the URL allow a few of
+		// the reserved characters to appear unescaped.
+		switch mode {
+		case encodePath: // §3.3
+			// The RFC allows : @ & = + $ but saves / ; , for assigning
+			// meaning to individual path segments. This package
+			// only manipulates the path as a whole, so we allow those
+			// last two as well. That leaves only ? to escape.
+			return c == '?'
+
+		case encodeUserPassword: // §3.2.1
+			// The RFC allows ';', ':', '&', '=', '+', '$', and ',' in
+			// userinfo, so we must escape only '@', '/', and '?'.
+			// The parsing of userinfo treats ':' as special so we must escape
+			// that too.
+			return c == '@' || c == '/' || c == '?' || c == ':'
+
+		case encodeQueryComponent: // §3.4
+			// The RFC reserves (so we must escape) everything.
+			return true
+
+		case encodeFragment: // §4.1
+			// The RFC text is silent but the grammar allows
+			// everything, so escape nothing.
+			return false
+		}
+	}
+
+	// Everything else must be escaped.
+	return true
+}
+
+// QueryUnescape does the inverse transformation of QueryEscape, converting
+// %AB into the byte 0xAB and '+' into ' ' (space). It returns an error if
+// any % is not followed by two hexadecimal digits.
+func QueryUnescape(s string) (string, error) {
+	return unescape(s, encodeQueryComponent)
+}
+
+// unescape unescapes a string; the mode specifies
+// which section of the URL string is being unescaped.
+func unescape(s string, mode encoding) (string, error) {
+	// Count %, check that they're well-formed.
+	n := 0
+	hasPlus := false
+	for i := 0; i < len(s); {
+		switch s[i] {
+		case '%':
+			n++
+			if i+2 >= len(s) || !ishex(s[i+1]) || !ishex(s[i+2]) {
+				s = s[i:]
+				if len(s) > 3 {
+					s = s[0:3]
+				}
+				return "", EscapeError(s)
+			}
+			i += 3
+		case '+':
+			hasPlus = mode == encodeQueryComponent
+			i++
+		default:
+			i++
+		}
+	}
+
+	if n == 0 && !hasPlus {
+		return s, nil
+	}
+
+	t := make([]byte, len(s)-2*n)
+	j := 0
+	for i := 0; i < len(s); {
+		switch s[i] {
+		case '%':
+			t[j] = unhex(s[i+1])<<4 | unhex(s[i+2])
+			j++
+			i += 3
+		case '+':
+			if mode == encodeQueryComponent {
+				t[j] = ' '
+			} else {
+				t[j] = '+'
+			}
+			j++
+			i++
+		default:
+			t[j] = s[i]
+			j++
+			i++
+		}
+	}
+	return string(t), nil
+}
+
+// QueryEscape escapes the string so it can be safely placed
+// inside a URL query.
+func QueryEscape(s string) string {
+	return escape(s, encodeQueryComponent)
+}
+
+func escape(s string, mode encoding) string {
+	spaceCount, hexCount := 0, 0
+	for i := 0; i < len(s); i++ {
+		c := s[i]
+		if shouldEscape(c, mode) {
+			if c == ' ' && mode == encodeQueryComponent {
+				spaceCount++
+			} else {
+				hexCount++
+			}
+		}
+	}
+
+	if spaceCount == 0 && hexCount == 0 {
+		return s
+	}
+
+	t := make([]byte, len(s)+2*hexCount)
+	j := 0
+	for i := 0; i < len(s); i++ {
+		switch c := s[i]; {
+		case c == ' ' && mode == encodeQueryComponent:
+			t[j] = '+'
+			j++
+		case shouldEscape(c, mode):
+			t[j] = '%'
+			t[j+1] = "0123456789ABCDEF"[c>>4]
+			t[j+2] = "0123456789ABCDEF"[c&15]
+			j += 3
+		default:
+			t[j] = s[i]
+			j++
+		}
+	}
+	return string(t)
+}
+
+// A URL represents a parsed URL (technically, a URI reference).
+// The general form represented is:
+//
+//	scheme://[userinfo@]host/path[?query][#fragment]
+//
+// URLs that do not start with a slash after the scheme are interpreted as:
+//
+//	scheme:opaque[?query][#fragment]
+//
+// Note that the Path field is stored in decoded form: /%47%6f%2f becomes /Go/.
+// A consequence is that it is impossible to tell which slashes in the Path were
+// slashes in the raw URL and which were %2f. This distinction is rarely important,
+// but when it is a client must use other routines to parse the raw URL or construct
+// the parsed URL. For example, an HTTP server can consult req.RequestURI, and
+// an HTTP client can use URL{Host: "example.com", Opaque: "//example.com/Go%2f"}
+// instead of URL{Host: "example.com", Path: "/Go/"}.
+type URL struct {
+	Scheme   string
+	Opaque   string    // encoded opaque data
+	User     *Userinfo // username and password information
+	Host     string    // host or host:port
+	Path     string
+	RawQuery string // encoded query values, without '?'
+	Fragment string // fragment for references, without '#'
+}
+
+// User returns a Userinfo containing the provided username
+// and no password set.
+func User(username string) *Userinfo {
+	return &Userinfo{username, "", false}
+}
+
+// UserPassword returns a Userinfo containing the provided username
+// and password.
+// This functionality should only be used with legacy web sites.
+// RFC 2396 warns that interpreting Userinfo this way
+// ``is NOT RECOMMENDED, because the passing of authentication
+// information in clear text (such as URI) has proven to be a
+// security risk in almost every case where it has been used.''
+func UserPassword(username, password string) *Userinfo {
+	return &Userinfo{username, password, true}
+}
+
+// The Userinfo type is an immutable encapsulation of username and
+// password details for a URL. An existing Userinfo value is guaranteed
+// to have a username set (potentially empty, as allowed by RFC 2396),
+// and optionally a password.
+type Userinfo struct {
+	username    string
+	password    string
+	passwordSet bool
+}
+
+// Username returns the username.
+func (u *Userinfo) Username() string {
+	return u.username
+}
+
+// Password returns the password in case it is set, and whether it is set.
+func (u *Userinfo) Password() (string, bool) {
+	if u.passwordSet {
+		return u.password, true
+	}
+	return "", false
+}
+
+// String returns the encoded userinfo information in the standard form
+// of "username[:password]".
+func (u *Userinfo) String() string {
+	s := escape(u.username, encodeUserPassword)
+	if u.passwordSet {
+		s += ":" + escape(u.password, encodeUserPassword)
+	}
+	return s
+}
+
+// Maybe rawurl is of the form scheme:path.
+// (Scheme must be [a-zA-Z][a-zA-Z0-9+-.]*)
+// If so, return scheme, path; else return "", rawurl.
+func getscheme(rawurl string) (scheme, path string, err error) {
+	for i := 0; i < len(rawurl); i++ {
+		c := rawurl[i]
+		switch {
+		case 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z':
+		// do nothing
+		case '0' <= c && c <= '9' || c == '+' || c == '-' || c == '.':
+			if i == 0 {
+				return "", rawurl, nil
+			}
+		case c == ':':
+			if i == 0 {
+				return "", "", errors.New("missing protocol scheme")
+			}
+			return rawurl[0:i], rawurl[i+1:], nil
+		default:
+			// we have encountered an invalid character,
+			// so there is no valid scheme
+			return "", rawurl, nil
+		}
+	}
+	return "", rawurl, nil
+}
+
+// Maybe s is of the form t c u.
+// If so, return t, c u (or t, u if cutc == true).
+// If not, return s, "".
+func split(s string, c string, cutc bool) (string, string) {
+	i := strings.Index(s, c)
+	if i < 0 {
+		return s, ""
+	}
+	if cutc {
+		return s[0:i], s[i+len(c):]
+	}
+	return s[0:i], s[i:]
+}
+
+// Parse parses rawurl into a URL structure.
+// The rawurl may be relative or absolute.
+func Parse(rawurl string) (url *URL, err error) {
+	// Cut off #frag
+	u, frag := split(rawurl, "#", true)
+	if url, err = parse(u, false); err != nil {
+		return nil, err
+	}
+	if frag == "" {
+		return url, nil
+	}
+	if url.Fragment, err = unescape(frag, encodeFragment); err != nil {
+		return nil, &Error{"parse", rawurl, err}
+	}
+	return url, nil
+}
+
+// ParseRequestURI parses rawurl into a URL structure.  It assumes that
+// rawurl was received in an HTTP request, so the rawurl is interpreted
+// only as an absolute URI or an absolute path.
+// The string rawurl is assumed not to have a #fragment suffix.
+// (Web browsers strip #fragment before sending the URL to a web server.)
+func ParseRequestURI(rawurl string) (url *URL, err error) {
+	return parse(rawurl, true)
+}
+
+// parse parses a URL from a string in one of two contexts.  If
+// viaRequest is true, the URL is assumed to have arrived via an HTTP request,
+// in which case only absolute URLs or path-absolute relative URLs are allowed.
+// If viaRequest is false, all forms of relative URLs are allowed.
+func parse(rawurl string, viaRequest bool) (url *URL, err error) {
+	var rest string
+
+	if rawurl == "" && viaRequest {
+		err = errors.New("empty url")
+		goto Error
+	}
+	url = new(URL)
+
+	if rawurl == "*" {
+		url.Path = "*"
+		return
+	}
+
+	// Split off possible leading "http:", "mailto:", etc.
+	// Cannot contain escaped characters.
+	if url.Scheme, rest, err = getscheme(rawurl); err != nil {
+		goto Error
+	}
+	url.Scheme = strings.ToLower(url.Scheme)
+
+	rest, url.RawQuery = split(rest, "?", true)
+
+	if !strings.HasPrefix(rest, "/") {
+		if url.Scheme != "" {
+			// We consider rootless paths per RFC 3986 as opaque.
+			url.Opaque = rest
+			return url, nil
+		}
+		if viaRequest {
+			err = errors.New("invalid URI for request")
+			goto Error
+		}
+	}
+
+	if (url.Scheme != "" || !viaRequest && !strings.HasPrefix(rest, "///")) && strings.HasPrefix(rest, "//") {
+		var authority string
+		authority, rest = split(rest[2:], "/", false)
+		url.User, url.Host, err = parseAuthority(authority)
+		if err != nil {
+			goto Error
+		}
+		if strings.Contains(url.Host, "%") {
+			err = errors.New("hexadecimal escape in host")
+			goto Error
+		}
+	}
+	if url.Path, err = unescape(rest, encodePath); err != nil {
+		goto Error
+	}
+	return url, nil
+
+Error:
+	return nil, &Error{"parse", rawurl, err}
+}
+
+func parseAuthority(authority string) (user *Userinfo, host string, err error) {
+	i := strings.LastIndex(authority, "@")
+	if i < 0 {
+		host = authority
+		return
+	}
+	userinfo, host := authority[:i], authority[i+1:]
+	if strings.Index(userinfo, ":") < 0 {
+		if userinfo, err = unescape(userinfo, encodeUserPassword); err != nil {
+			return
+		}
+		user = User(userinfo)
+	} else {
+		username, password := split(userinfo, ":", true)
+		if username, err = unescape(username, encodeUserPassword); err != nil {
+			return
+		}
+		if password, err = unescape(password, encodeUserPassword); err != nil {
+			return
+		}
+		user = UserPassword(username, password)
+	}
+	return
+}
+
+// String reassembles the URL into a valid URL string.
+// The general form of the result is one of:
+//
+//	scheme:opaque
+//	scheme://userinfo@host/path?query#fragment
+//
+// If u.Opaque is non-empty, String uses the first form;
+// otherwise it uses the second form.
+//
+// In the second form, the following rules apply:
+//	- if u.Scheme is empty, scheme: is omitted.
+//	- if u.User is nil, userinfo@ is omitted.
+//	- if u.Host is empty, host/ is omitted.
+//	- if u.Scheme and u.Host are empty and u.User is nil,
+//	   the entire scheme://userinfo@host/ is omitted.
+//	- if u.Host is non-empty and u.Path begins with a /,
+//	   the form host/path does not add its own /.
+//	- if u.RawQuery is empty, ?query is omitted.
+//	- if u.Fragment is empty, #fragment is omitted.
+func (u *URL) String() string {
+	var buf bytes.Buffer
+	if u.Scheme != "" {
+		buf.WriteString(u.Scheme)
+		buf.WriteByte(':')
+	}
+	if u.Opaque != "" {
+		buf.WriteString(u.Opaque)
+	} else {
+		if u.Scheme != "" || u.Host != "" || u.User != nil {
+			buf.WriteString("//")
+			if ui := u.User; ui != nil {
+				buf.WriteString(ui.String())
+				buf.WriteByte('@')
+			}
+			if h := u.Host; h != "" {
+				buf.WriteString(h)
+			}
+		}
+		if u.Path != "" && u.Path[0] != '/' && u.Host != "" {
+			buf.WriteByte('/')
+		}
+		buf.WriteString(escape(u.Path, encodePath))
+	}
+	if u.RawQuery != "" {
+		buf.WriteByte('?')
+		buf.WriteString(u.RawQuery)
+	}
+	if u.Fragment != "" {
+		buf.WriteByte('#')
+		buf.WriteString(escape(u.Fragment, encodeFragment))
+	}
+	return buf.String()
+}
+
+// Values maps a string key to a list of values.
+// It is typically used for query parameters and form values.
+// Unlike in the http.Header map, the keys in a Values map
+// are case-sensitive.
+type Values map[string][]string
+
+// Get gets the first value associated with the given key.
+// If there are no values associated with the key, Get returns
+// the empty string. To access multiple values, use the map
+// directly.
+func (v Values) Get(key string) string {
+	if v == nil {
+		return ""
+	}
+	vs, ok := v[key]
+	if !ok || len(vs) == 0 {
+		return ""
+	}
+	return vs[0]
+}
+
+// Set sets the key to value. It replaces any existing
+// values.
+func (v Values) Set(key, value string) {
+	v[key] = []string{value}
+}
+
+// Add adds the value to key. It appends to any existing
+// values associated with key.
+func (v Values) Add(key, value string) {
+	v[key] = append(v[key], value)
+}
+
+// Del deletes the values associated with key.
+func (v Values) Del(key string) {
+	delete(v, key)
+}
+
+// ParseQuery parses the URL-encoded query string and returns
+// a map listing the values specified for each key.
+// ParseQuery always returns a non-nil map containing all the
+// valid query parameters found; err describes the first decoding error
+// encountered, if any.
+func ParseQuery(query string) (m Values, err error) {
+	m = make(Values)
+	err = parseQuery(m, query)
+	return
+}
+
+func parseQuery(m Values, query string) (err error) {
+	for query != "" {
+		key := query
+		if i := strings.IndexAny(key, "&;"); i >= 0 {
+			key, query = key[:i], key[i+1:]
+		} else {
+			query = ""
+		}
+		if key == "" {
+			continue
+		}
+		value := ""
+		if i := strings.Index(key, "="); i >= 0 {
+			key, value = key[:i], key[i+1:]
+		}
+		key, err1 := QueryUnescape(key)
+		if err1 != nil {
+			if err == nil {
+				err = err1
+			}
+			continue
+		}
+		value, err1 = QueryUnescape(value)
+		if err1 != nil {
+			if err == nil {
+				err = err1
+			}
+			continue
+		}
+		m[key] = append(m[key], value)
+	}
+	return err
+}
+
+// Encode encodes the values into ``URL encoded'' form
+// ("bar=baz&foo=quux") sorted by key.
+func (v Values) Encode() string {
+	if v == nil {
+		return ""
+	}
+	var buf bytes.Buffer
+	keys := make([]string, 0, len(v))
+	for k := range v {
+		keys = append(keys, k)
+	}
+	sort.Strings(keys)
+	for _, k := range keys {
+		vs := v[k]
+		prefix := QueryEscape(k) + "="
+		for _, v := range vs {
+			if buf.Len() > 0 {
+				buf.WriteByte('&')
+			}
+			buf.WriteString(prefix)
+			buf.WriteString(QueryEscape(v))
+		}
+	}
+	return buf.String()
+}
+
+// resolvePath applies special path segments from refs and applies
+// them to base, per RFC 3986.
+func resolvePath(base, ref string) string {
+	var full string
+	if ref == "" {
+		full = base
+	} else if ref[0] != '/' {
+		i := strings.LastIndex(base, "/")
+		full = base[:i+1] + ref
+	} else {
+		full = ref
+	}
+	if full == "" {
+		return ""
+	}
+	var dst []string
+	src := strings.Split(full, "/")
+	for _, elem := range src {
+		switch elem {
+		case ".":
+			// drop
+		case "..":
+			if len(dst) > 0 {
+				dst = dst[:len(dst)-1]
+			}
+		default:
+			dst = append(dst, elem)
+		}
+	}
+	if last := src[len(src)-1]; last == "." || last == ".." {
+		// Add final slash to the joined path.
+		dst = append(dst, "")
+	}
+	return "/" + strings.TrimLeft(strings.Join(dst, "/"), "/")
+}
+
+// IsAbs returns true if the URL is absolute.
+func (u *URL) IsAbs() bool {
+	return u.Scheme != ""
+}
+
+// Parse parses a URL in the context of the receiver.  The provided URL
+// may be relative or absolute.  Parse returns nil, err on parse
+// failure, otherwise its return value is the same as ResolveReference.
+func (u *URL) Parse(ref string) (*URL, error) {
+	refurl, err := Parse(ref)
+	if err != nil {
+		return nil, err
+	}
+	return u.ResolveReference(refurl), nil
+}
+
+// ResolveReference resolves a URI reference to an absolute URI from
+// an absolute base URI, per RFC 3986 Section 5.2.  The URI reference
+// may be relative or absolute.  ResolveReference always returns a new
+// URL instance, even if the returned URL is identical to either the
+// base or reference. If ref is an absolute URL, then ResolveReference
+// ignores base and returns a copy of ref.
+func (u *URL) ResolveReference(ref *URL) *URL {
+	url := *ref
+	if ref.Scheme == "" {
+		url.Scheme = u.Scheme
+	}
+	if ref.Scheme != "" || ref.Host != "" || ref.User != nil {
+		// The "absoluteURI" or "net_path" cases.
+		url.Path = resolvePath(ref.Path, "")
+		return &url
+	}
+	if ref.Opaque != "" {
+		url.User = nil
+		url.Host = ""
+		url.Path = ""
+		return &url
+	}
+	if ref.Path == "" {
+		if ref.RawQuery == "" {
+			url.RawQuery = u.RawQuery
+			if ref.Fragment == "" {
+				url.Fragment = u.Fragment
+			}
+		}
+	}
+	// The "abs_path" or "rel_path" cases.
+	url.Host = u.Host
+	url.User = u.User
+	url.Path = resolvePath(u.Path, ref.Path)
+	return &url
+}
+
+// Query parses RawQuery and returns the corresponding values.
+func (u *URL) Query() Values {
+	v, _ := ParseQuery(u.RawQuery)
+	return v
+}
+
+// RequestURI returns the encoded path?query or opaque?query
+// string that would be used in an HTTP request for u.
+func (u *URL) RequestURI() string {
+	result := u.Opaque
+	if result == "" {
+		result = escape(u.Path, encodePath)
+		if result == "" {
+			result = "/"
+		}
+	} else {
+		if strings.HasPrefix(result, "//") {
+			result = u.Scheme + ":" + result
+		}
+	}
+	if u.RawQuery != "" {
+		result += "?" + u.RawQuery
+	}
+	return result
+}
diff --git a/src/net/url/url_test.go b/src/net/url/url_test.go
new file mode 100644
index 0000000..d8b19d8
--- /dev/null
+++ b/src/net/url/url_test.go
@@ -0,0 +1,961 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package url
+
+import (
+	"fmt"
+	"reflect"
+	"strings"
+	"testing"
+)
+
+type URLTest struct {
+	in        string
+	out       *URL
+	roundtrip string // expected result of reserializing the URL; empty means same as "in".
+}
+
+var urltests = []URLTest{
+	// no path
+	{
+		"http://www.google.com",
+		&URL{
+			Scheme: "http",
+			Host:   "www.google.com",
+		},
+		"",
+	},
+	// path
+	{
+		"http://www.google.com/",
+		&URL{
+			Scheme: "http",
+			Host:   "www.google.com",
+			Path:   "/",
+		},
+		"",
+	},
+	// path with hex escaping
+	{
+		"http://www.google.com/file%20one%26two",
+		&URL{
+			Scheme: "http",
+			Host:   "www.google.com",
+			Path:   "/file one&two",
+		},
+		"http://www.google.com/file%20one&two",
+	},
+	// user
+	{
+		"ftp://webmaster@www.google.com/",
+		&URL{
+			Scheme: "ftp",
+			User:   User("webmaster"),
+			Host:   "www.google.com",
+			Path:   "/",
+		},
+		"",
+	},
+	// escape sequence in username
+	{
+		"ftp://john%20doe@www.google.com/",
+		&URL{
+			Scheme: "ftp",
+			User:   User("john doe"),
+			Host:   "www.google.com",
+			Path:   "/",
+		},
+		"ftp://john%20doe@www.google.com/",
+	},
+	// query
+	{
+		"http://www.google.com/?q=go+language",
+		&URL{
+			Scheme:   "http",
+			Host:     "www.google.com",
+			Path:     "/",
+			RawQuery: "q=go+language",
+		},
+		"",
+	},
+	// query with hex escaping: NOT parsed
+	{
+		"http://www.google.com/?q=go%20language",
+		&URL{
+			Scheme:   "http",
+			Host:     "www.google.com",
+			Path:     "/",
+			RawQuery: "q=go%20language",
+		},
+		"",
+	},
+	// %20 outside query
+	{
+		"http://www.google.com/a%20b?q=c+d",
+		&URL{
+			Scheme:   "http",
+			Host:     "www.google.com",
+			Path:     "/a b",
+			RawQuery: "q=c+d",
+		},
+		"",
+	},
+	// path without leading /, so no parsing
+	{
+		"http:www.google.com/?q=go+language",
+		&URL{
+			Scheme:   "http",
+			Opaque:   "www.google.com/",
+			RawQuery: "q=go+language",
+		},
+		"http:www.google.com/?q=go+language",
+	},
+	// path without leading /, so no parsing
+	{
+		"http:%2f%2fwww.google.com/?q=go+language",
+		&URL{
+			Scheme:   "http",
+			Opaque:   "%2f%2fwww.google.com/",
+			RawQuery: "q=go+language",
+		},
+		"http:%2f%2fwww.google.com/?q=go+language",
+	},
+	// non-authority with path
+	{
+		"mailto:/webmaster at golang.org",
+		&URL{
+			Scheme: "mailto",
+			Path:   "/webmaster at golang.org",
+		},
+		"mailto:///webmaster@golang.org", // unfortunate compromise
+	},
+	// non-authority
+	{
+		"mailto:webmaster at golang.org",
+		&URL{
+			Scheme: "mailto",
+			Opaque: "webmaster at golang.org",
+		},
+		"",
+	},
+	// unescaped :// in query should not create a scheme
+	{
+		"/foo?query=http://bad",
+		&URL{
+			Path:     "/foo",
+			RawQuery: "query=http://bad",
+		},
+		"",
+	},
+	// leading // without scheme should create an authority
+	{
+		"//foo",
+		&URL{
+			Host: "foo",
+		},
+		"",
+	},
+	// leading // without scheme, with userinfo, path, and query
+	{
+		"//user at foo/path?a=b",
+		&URL{
+			User:     User("user"),
+			Host:     "foo",
+			Path:     "/path",
+			RawQuery: "a=b",
+		},
+		"",
+	},
+	// Three leading slashes isn't an authority, but doesn't return an error.
+	// (We can't return an error, as this code is also used via
+	// ServeHTTP -> ReadRequest -> Parse, which is arguably a
+	// different URL parsing context, but currently shares the
+	// same codepath)
+	{
+		"///threeslashes",
+		&URL{
+			Path: "///threeslashes",
+		},
+		"",
+	},
+	{
+		"http://user:password@google.com",
+		&URL{
+			Scheme: "http",
+			User:   UserPassword("user", "password"),
+			Host:   "google.com",
+		},
+		"http://user:password@google.com",
+	},
+	// unescaped @ in username should not confuse host
+	{
+		"http://j@ne:password@google.com",
+		&URL{
+			Scheme: "http",
+			User:   UserPassword("j at ne", "password"),
+			Host:   "google.com",
+		},
+		"http://j%40ne:password@google.com",
+	},
+	// unescaped @ in password should not confuse host
+	{
+		"http://jane:p@ssword@google.com",
+		&URL{
+			Scheme: "http",
+			User:   UserPassword("jane", "p at ssword"),
+			Host:   "google.com",
+		},
+		"http://jane:p%40ssword@google.com",
+	},
+	{
+		"http://j@ne:password@google.com/p@th?q=@go",
+		&URL{
+			Scheme:   "http",
+			User:     UserPassword("j at ne", "password"),
+			Host:     "google.com",
+			Path:     "/p at th",
+			RawQuery: "q=@go",
+		},
+		"http://j%40ne:password@google.com/p@th?q=@go",
+	},
+	{
+		"http://www.google.com/?q=go+language#foo",
+		&URL{
+			Scheme:   "http",
+			Host:     "www.google.com",
+			Path:     "/",
+			RawQuery: "q=go+language",
+			Fragment: "foo",
+		},
+		"",
+	},
+	{
+		"http://www.google.com/?q=go+language#foo%26bar",
+		&URL{
+			Scheme:   "http",
+			Host:     "www.google.com",
+			Path:     "/",
+			RawQuery: "q=go+language",
+			Fragment: "foo&bar",
+		},
+		"http://www.google.com/?q=go+language#foo&bar",
+	},
+	{
+		"file:///home/adg/rabbits",
+		&URL{
+			Scheme: "file",
+			Host:   "",
+			Path:   "/home/adg/rabbits",
+		},
+		"file:///home/adg/rabbits",
+	},
+	// "Windows" paths are no exception to the rule.
+	// See golang.org/issue/6027, especially comment #9.
+	{
+		"file:///C:/FooBar/Baz.txt",
+		&URL{
+			Scheme: "file",
+			Host:   "",
+			Path:   "/C:/FooBar/Baz.txt",
+		},
+		"file:///C:/FooBar/Baz.txt",
+	},
+	// case-insensitive scheme
+	{
+		"MaIlTo:webmaster at golang.org",
+		&URL{
+			Scheme: "mailto",
+			Opaque: "webmaster at golang.org",
+		},
+		"mailto:webmaster at golang.org",
+	},
+	// Relative path
+	{
+		"a/b/c",
+		&URL{
+			Path: "a/b/c",
+		},
+		"a/b/c",
+	},
+	// escaped '?' in username and password
+	{
+		"http://%3Fam:pa%3Fsword@google.com",
+		&URL{
+			Scheme: "http",
+			User:   UserPassword("?am", "pa?sword"),
+			Host:   "google.com",
+		},
+		"",
+	},
+}
+
+// more useful string for debugging than fmt's struct printer
+func ufmt(u *URL) string {
+	var user, pass interface{}
+	if u.User != nil {
+		user = u.User.Username()
+		if p, ok := u.User.Password(); ok {
+			pass = p
+		}
+	}
+	return fmt.Sprintf("opaque=%q, scheme=%q, user=%#v, pass=%#v, host=%q, path=%q, rawq=%q, frag=%q",
+		u.Opaque, u.Scheme, user, pass, u.Host, u.Path, u.RawQuery, u.Fragment)
+}
+
+func DoTest(t *testing.T, parse func(string) (*URL, error), name string, tests []URLTest) {
+	for _, tt := range tests {
+		u, err := parse(tt.in)
+		if err != nil {
+			t.Errorf("%s(%q) returned error %s", name, tt.in, err)
+			continue
+		}
+		if !reflect.DeepEqual(u, tt.out) {
+			t.Errorf("%s(%q):\n\thave %v\n\twant %v\n",
+				name, tt.in, ufmt(u), ufmt(tt.out))
+		}
+	}
+}
+
+func BenchmarkString(b *testing.B) {
+	b.StopTimer()
+	b.ReportAllocs()
+	for _, tt := range urltests {
+		u, err := Parse(tt.in)
+		if err != nil {
+			b.Errorf("Parse(%q) returned error %s", tt.in, err)
+			continue
+		}
+		if tt.roundtrip == "" {
+			continue
+		}
+		b.StartTimer()
+		var g string
+		for i := 0; i < b.N; i++ {
+			g = u.String()
+		}
+		b.StopTimer()
+		if w := tt.roundtrip; g != w {
+			b.Errorf("Parse(%q).String() == %q, want %q", tt.in, g, w)
+		}
+	}
+}
+
+func TestParse(t *testing.T) {
+	DoTest(t, Parse, "Parse", urltests)
+}
+
+const pathThatLooksSchemeRelative = "//not.a.user at not.a.host/just/a/path"
+
+var parseRequestURLTests = []struct {
+	url           string
+	expectedValid bool
+}{
+	{"http://foo.com", true},
+	{"http://foo.com/", true},
+	{"http://foo.com/path", true},
+	{"/", true},
+	{pathThatLooksSchemeRelative, true},
+	{"//not.a.user@%66%6f%6f.com/just/a/path/also", true},
+	{"foo.html", false},
+	{"../dir/", false},
+	{"*", true},
+}
+
+func TestParseRequestURI(t *testing.T) {
+	for _, test := range parseRequestURLTests {
+		_, err := ParseRequestURI(test.url)
+		valid := err == nil
+		if valid != test.expectedValid {
+			t.Errorf("Expected valid=%v for %q; got %v", test.expectedValid, test.url, valid)
+		}
+	}
+
+	url, err := ParseRequestURI(pathThatLooksSchemeRelative)
+	if err != nil {
+		t.Fatalf("Unexpected error %v", err)
+	}
+	if url.Path != pathThatLooksSchemeRelative {
+		t.Errorf("Expected path %q; got %q", pathThatLooksSchemeRelative, url.Path)
+	}
+}
+
+func DoTestString(t *testing.T, parse func(string) (*URL, error), name string, tests []URLTest) {
+	for _, tt := range tests {
+		u, err := parse(tt.in)
+		if err != nil {
+			t.Errorf("%s(%q) returned error %s", name, tt.in, err)
+			continue
+		}
+		expected := tt.in
+		if len(tt.roundtrip) > 0 {
+			expected = tt.roundtrip
+		}
+		s := u.String()
+		if s != expected {
+			t.Errorf("%s(%q).String() == %q (expected %q)", name, tt.in, s, expected)
+		}
+	}
+}
+
+func TestURLString(t *testing.T) {
+	DoTestString(t, Parse, "Parse", urltests)
+
+	// no leading slash on path should prepend
+	// slash on String() call
+	noslash := URLTest{
+		"http://www.google.com/search",
+		&URL{
+			Scheme: "http",
+			Host:   "www.google.com",
+			Path:   "search",
+		},
+		"",
+	}
+	s := noslash.out.String()
+	if s != noslash.in {
+		t.Errorf("Expected %s; go %s", noslash.in, s)
+	}
+}
+
+type EscapeTest struct {
+	in  string
+	out string
+	err error
+}
+
+var unescapeTests = []EscapeTest{
+	{
+		"",
+		"",
+		nil,
+	},
+	{
+		"abc",
+		"abc",
+		nil,
+	},
+	{
+		"1%41",
+		"1A",
+		nil,
+	},
+	{
+		"1%41%42%43",
+		"1ABC",
+		nil,
+	},
+	{
+		"%4a",
+		"J",
+		nil,
+	},
+	{
+		"%6F",
+		"o",
+		nil,
+	},
+	{
+		"%", // not enough characters after %
+		"",
+		EscapeError("%"),
+	},
+	{
+		"%a", // not enough characters after %
+		"",
+		EscapeError("%a"),
+	},
+	{
+		"%1", // not enough characters after %
+		"",
+		EscapeError("%1"),
+	},
+	{
+		"123%45%6", // not enough characters after %
+		"",
+		EscapeError("%6"),
+	},
+	{
+		"%zzzzz", // invalid hex digits
+		"",
+		EscapeError("%zz"),
+	},
+}
+
+func TestUnescape(t *testing.T) {
+	for _, tt := range unescapeTests {
+		actual, err := QueryUnescape(tt.in)
+		if actual != tt.out || (err != nil) != (tt.err != nil) {
+			t.Errorf("QueryUnescape(%q) = %q, %s; want %q, %s", tt.in, actual, err, tt.out, tt.err)
+		}
+	}
+}
+
+var escapeTests = []EscapeTest{
+	{
+		"",
+		"",
+		nil,
+	},
+	{
+		"abc",
+		"abc",
+		nil,
+	},
+	{
+		"one two",
+		"one+two",
+		nil,
+	},
+	{
+		"10%",
+		"10%25",
+		nil,
+	},
+	{
+		" ?&=#+%!<>#\"{}|\\^[]`☺\t:/@$'()*,;",
+		"+%3F%26%3D%23%2B%25%21%3C%3E%23%22%7B%7D%7C%5C%5E%5B%5D%60%E2%98%BA%09%3A%2F%40%24%27%28%29%2A%2C%3B",
+		nil,
+	},
+}
+
+func TestEscape(t *testing.T) {
+	for _, tt := range escapeTests {
+		actual := QueryEscape(tt.in)
+		if tt.out != actual {
+			t.Errorf("QueryEscape(%q) = %q, want %q", tt.in, actual, tt.out)
+		}
+
+		// for bonus points, verify that escape:unescape is an identity.
+		roundtrip, err := QueryUnescape(actual)
+		if roundtrip != tt.in || err != nil {
+			t.Errorf("QueryUnescape(%q) = %q, %s; want %q, %s", actual, roundtrip, err, tt.in, "[no error]")
+		}
+	}
+}
+
+//var userinfoTests = []UserinfoTest{
+//	{"user", "password", "user:password"},
+//	{"foo:bar", "~!@#$%^&*()_+{}|[]\\-=`:;'\"<>?,./",
+//		"foo%3Abar:~!%40%23$%25%5E&*()_+%7B%7D%7C%5B%5D%5C-=%60%3A;'%22%3C%3E?,.%2F"},
+//}
+
+type EncodeQueryTest struct {
+	m        Values
+	expected string
+}
+
+var encodeQueryTests = []EncodeQueryTest{
+	{nil, ""},
+	{Values{"q": {"puppies"}, "oe": {"utf8"}}, "oe=utf8&q=puppies"},
+	{Values{"q": {"dogs", "&", "7"}}, "q=dogs&q=%26&q=7"},
+	{Values{
+		"a": {"a1", "a2", "a3"},
+		"b": {"b1", "b2", "b3"},
+		"c": {"c1", "c2", "c3"},
+	}, "a=a1&a=a2&a=a3&b=b1&b=b2&b=b3&c=c1&c=c2&c=c3"},
+}
+
+func TestEncodeQuery(t *testing.T) {
+	for _, tt := range encodeQueryTests {
+		if q := tt.m.Encode(); q != tt.expected {
+			t.Errorf(`EncodeQuery(%+v) = %q, want %q`, tt.m, q, tt.expected)
+		}
+	}
+}
+
+var resolvePathTests = []struct {
+	base, ref, expected string
+}{
+	{"a/b", ".", "/a/"},
+	{"a/b", "c", "/a/c"},
+	{"a/b", "..", "/"},
+	{"a/", "..", "/"},
+	{"a/", "../..", "/"},
+	{"a/b/c", "..", "/a/"},
+	{"a/b/c", "../d", "/a/d"},
+	{"a/b/c", ".././d", "/a/d"},
+	{"a/b", "./..", "/"},
+	{"a/./b", ".", "/a/"},
+	{"a/../", ".", "/"},
+	{"a/.././b", "c", "/c"},
+}
+
+func TestResolvePath(t *testing.T) {
+	for _, test := range resolvePathTests {
+		got := resolvePath(test.base, test.ref)
+		if got != test.expected {
+			t.Errorf("For %q + %q got %q; expected %q", test.base, test.ref, got, test.expected)
+		}
+	}
+}
+
+var resolveReferenceTests = []struct {
+	base, rel, expected string
+}{
+	// Absolute URL references
+	{"http://foo.com?a=b", "https://bar.com/", "https://bar.com/"},
+	{"http://foo.com/", "https://bar.com/?a=b", "https://bar.com/?a=b"},
+	{"http://foo.com/bar", "mailto:foo at example.com", "mailto:foo at example.com"},
+
+	// Path-absolute references
+	{"http://foo.com/bar", "/baz", "http://foo.com/baz"},
+	{"http://foo.com/bar?a=b#f", "/baz", "http://foo.com/baz"},
+	{"http://foo.com/bar?a=b", "/baz?c=d", "http://foo.com/baz?c=d"},
+
+	// Scheme-relative
+	{"https://foo.com/bar?a=b", "//bar.com/quux", "https://bar.com/quux"},
+
+	// Path-relative references:
+
+	// ... current directory
+	{"http://foo.com", ".", "http://foo.com/"},
+	{"http://foo.com/bar", ".", "http://foo.com/"},
+	{"http://foo.com/bar/", ".", "http://foo.com/bar/"},
+
+	// ... going down
+	{"http://foo.com", "bar", "http://foo.com/bar"},
+	{"http://foo.com/", "bar", "http://foo.com/bar"},
+	{"http://foo.com/bar/baz", "quux", "http://foo.com/bar/quux"},
+
+	// ... going up
+	{"http://foo.com/bar/baz", "../quux", "http://foo.com/quux"},
+	{"http://foo.com/bar/baz", "../../../../../quux", "http://foo.com/quux"},
+	{"http://foo.com/bar", "..", "http://foo.com/"},
+	{"http://foo.com/bar/baz", "./..", "http://foo.com/"},
+	// ".." in the middle (issue 3560)
+	{"http://foo.com/bar/baz", "quux/dotdot/../tail", "http://foo.com/bar/quux/tail"},
+	{"http://foo.com/bar/baz", "quux/./dotdot/../tail", "http://foo.com/bar/quux/tail"},
+	{"http://foo.com/bar/baz", "quux/./dotdot/.././tail", "http://foo.com/bar/quux/tail"},
+	{"http://foo.com/bar/baz", "quux/./dotdot/./../tail", "http://foo.com/bar/quux/tail"},
+	{"http://foo.com/bar/baz", "quux/./dotdot/dotdot/././../../tail", "http://foo.com/bar/quux/tail"},
+	{"http://foo.com/bar/baz", "quux/./dotdot/dotdot/./.././../tail", "http://foo.com/bar/quux/tail"},
+	{"http://foo.com/bar/baz", "quux/./dotdot/dotdot/dotdot/./../../.././././tail", "http://foo.com/bar/quux/tail"},
+	{"http://foo.com/bar/baz", "quux/./dotdot/../dotdot/../dot/./tail/..", "http://foo.com/bar/quux/dot/"},
+
+	// Remove any dot-segments prior to forming the target URI.
+	// http://tools.ietf.org/html/rfc3986#section-5.2.4
+	{"http://foo.com/dot/./dotdot/../foo/bar", "../baz", "http://foo.com/dot/baz"},
+
+	// Triple dot isn't special
+	{"http://foo.com/bar", "...", "http://foo.com/..."},
+
+	// Fragment
+	{"http://foo.com/bar", ".#frag", "http://foo.com/#frag"},
+
+	// RFC 3986: Normal Examples
+	// http://tools.ietf.org/html/rfc3986#section-5.4.1
+	{"http://a/b/c/d;p?q", "g:h", "g:h"},
+	{"http://a/b/c/d;p?q", "g", "http://a/b/c/g"},
+	{"http://a/b/c/d;p?q", "./g", "http://a/b/c/g"},
+	{"http://a/b/c/d;p?q", "g/", "http://a/b/c/g/"},
+	{"http://a/b/c/d;p?q", "/g", "http://a/g"},
+	{"http://a/b/c/d;p?q", "//g", "http://g"},
+	{"http://a/b/c/d;p?q", "?y", "http://a/b/c/d;p?y"},
+	{"http://a/b/c/d;p?q", "g?y", "http://a/b/c/g?y"},
+	{"http://a/b/c/d;p?q", "#s", "http://a/b/c/d;p?q#s"},
+	{"http://a/b/c/d;p?q", "g#s", "http://a/b/c/g#s"},
+	{"http://a/b/c/d;p?q", "g?y#s", "http://a/b/c/g?y#s"},
+	{"http://a/b/c/d;p?q", ";x", "http://a/b/c/;x"},
+	{"http://a/b/c/d;p?q", "g;x", "http://a/b/c/g;x"},
+	{"http://a/b/c/d;p?q", "g;x?y#s", "http://a/b/c/g;x?y#s"},
+	{"http://a/b/c/d;p?q", "", "http://a/b/c/d;p?q"},
+	{"http://a/b/c/d;p?q", ".", "http://a/b/c/"},
+	{"http://a/b/c/d;p?q", "./", "http://a/b/c/"},
+	{"http://a/b/c/d;p?q", "..", "http://a/b/"},
+	{"http://a/b/c/d;p?q", "../", "http://a/b/"},
+	{"http://a/b/c/d;p?q", "../g", "http://a/b/g"},
+	{"http://a/b/c/d;p?q", "../..", "http://a/"},
+	{"http://a/b/c/d;p?q", "../../", "http://a/"},
+	{"http://a/b/c/d;p?q", "../../g", "http://a/g"},
+
+	// RFC 3986: Abnormal Examples
+	// http://tools.ietf.org/html/rfc3986#section-5.4.2
+	{"http://a/b/c/d;p?q", "../../../g", "http://a/g"},
+	{"http://a/b/c/d;p?q", "../../../../g", "http://a/g"},
+	{"http://a/b/c/d;p?q", "/./g", "http://a/g"},
+	{"http://a/b/c/d;p?q", "/../g", "http://a/g"},
+	{"http://a/b/c/d;p?q", "g.", "http://a/b/c/g."},
+	{"http://a/b/c/d;p?q", ".g", "http://a/b/c/.g"},
+	{"http://a/b/c/d;p?q", "g..", "http://a/b/c/g.."},
+	{"http://a/b/c/d;p?q", "..g", "http://a/b/c/..g"},
+	{"http://a/b/c/d;p?q", "./../g", "http://a/b/g"},
+	{"http://a/b/c/d;p?q", "./g/.", "http://a/b/c/g/"},
+	{"http://a/b/c/d;p?q", "g/./h", "http://a/b/c/g/h"},
+	{"http://a/b/c/d;p?q", "g/../h", "http://a/b/c/h"},
+	{"http://a/b/c/d;p?q", "g;x=1/./y", "http://a/b/c/g;x=1/y"},
+	{"http://a/b/c/d;p?q", "g;x=1/../y", "http://a/b/c/y"},
+	{"http://a/b/c/d;p?q", "g?y/./x", "http://a/b/c/g?y/./x"},
+	{"http://a/b/c/d;p?q", "g?y/../x", "http://a/b/c/g?y/../x"},
+	{"http://a/b/c/d;p?q", "g#s/./x", "http://a/b/c/g#s/./x"},
+	{"http://a/b/c/d;p?q", "g#s/../x", "http://a/b/c/g#s/../x"},
+
+	// Extras.
+	{"https://a/b/c/d;p?q", "//g?q", "https://g?q"},
+	{"https://a/b/c/d;p?q", "//g#s", "https://g#s"},
+	{"https://a/b/c/d;p?q", "//g/d/e/f?y#s", "https://g/d/e/f?y#s"},
+	{"https://a/b/c/d;p#s", "?y", "https://a/b/c/d;p?y"},
+	{"https://a/b/c/d;p?q#s", "?y", "https://a/b/c/d;p?y"},
+}
+
+func TestResolveReference(t *testing.T) {
+	mustParse := func(url string) *URL {
+		u, err := Parse(url)
+		if err != nil {
+			t.Fatalf("Expected URL to parse: %q, got error: %v", url, err)
+		}
+		return u
+	}
+	opaque := &URL{Scheme: "scheme", Opaque: "opaque"}
+	for _, test := range resolveReferenceTests {
+		base := mustParse(test.base)
+		rel := mustParse(test.rel)
+		url := base.ResolveReference(rel)
+		if url.String() != test.expected {
+			t.Errorf("URL(%q).ResolveReference(%q) == %q, got %q", test.base, test.rel, test.expected, url.String())
+		}
+		// Ensure that new instances are returned.
+		if base == url {
+			t.Errorf("Expected URL.ResolveReference to return new URL instance.")
+		}
+		// Test the convenience wrapper too.
+		url, err := base.Parse(test.rel)
+		if err != nil {
+			t.Errorf("URL(%q).Parse(%q) failed: %v", test.base, test.rel, err)
+		} else if url.String() != test.expected {
+			t.Errorf("URL(%q).Parse(%q) == %q, got %q", test.base, test.rel, test.expected, url.String())
+		} else if base == url {
+			// Ensure that new instances are returned for the wrapper too.
+			t.Errorf("Expected URL.Parse to return new URL instance.")
+		}
+		// Ensure Opaque resets the URL.
+		url = base.ResolveReference(opaque)
+		if *url != *opaque {
+			t.Errorf("ResolveReference failed to resolve opaque URL: want %#v, got %#v", url, opaque)
+		}
+		// Test the convenience wrapper with an opaque URL too.
+		url, err = base.Parse("scheme:opaque")
+		if err != nil {
+			t.Errorf(`URL(%q).Parse("scheme:opaque") failed: %v`, test.base, err)
+		} else if *url != *opaque {
+			t.Errorf("Parse failed to resolve opaque URL: want %#v, got %#v", url, opaque)
+		} else if base == url {
+			// Ensure that new instances are returned, again.
+			t.Errorf("Expected URL.Parse to return new URL instance.")
+		}
+	}
+}
+
+func TestQueryValues(t *testing.T) {
+	u, _ := Parse("http://x.com?foo=bar&bar=1&bar=2")
+	v := u.Query()
+	if len(v) != 2 {
+		t.Errorf("got %d keys in Query values, want 2", len(v))
+	}
+	if g, e := v.Get("foo"), "bar"; g != e {
+		t.Errorf("Get(foo) = %q, want %q", g, e)
+	}
+	// Case sensitive:
+	if g, e := v.Get("Foo"), ""; g != e {
+		t.Errorf("Get(Foo) = %q, want %q", g, e)
+	}
+	if g, e := v.Get("bar"), "1"; g != e {
+		t.Errorf("Get(bar) = %q, want %q", g, e)
+	}
+	if g, e := v.Get("baz"), ""; g != e {
+		t.Errorf("Get(baz) = %q, want %q", g, e)
+	}
+	v.Del("bar")
+	if g, e := v.Get("bar"), ""; g != e {
+		t.Errorf("second Get(bar) = %q, want %q", g, e)
+	}
+}
+
+type parseTest struct {
+	query string
+	out   Values
+}
+
+var parseTests = []parseTest{
+	{
+		query: "a=1&b=2",
+		out:   Values{"a": []string{"1"}, "b": []string{"2"}},
+	},
+	{
+		query: "a=1&a=2&a=banana",
+		out:   Values{"a": []string{"1", "2", "banana"}},
+	},
+	{
+		query: "ascii=%3Ckey%3A+0x90%3E",
+		out:   Values{"ascii": []string{"<key: 0x90>"}},
+	},
+	{
+		query: "a=1;b=2",
+		out:   Values{"a": []string{"1"}, "b": []string{"2"}},
+	},
+	{
+		query: "a=1&a=2;a=banana",
+		out:   Values{"a": []string{"1", "2", "banana"}},
+	},
+}
+
+func TestParseQuery(t *testing.T) {
+	for i, test := range parseTests {
+		form, err := ParseQuery(test.query)
+		if err != nil {
+			t.Errorf("test %d: Unexpected error: %v", i, err)
+			continue
+		}
+		if len(form) != len(test.out) {
+			t.Errorf("test %d: len(form) = %d, want %d", i, len(form), len(test.out))
+		}
+		for k, evs := range test.out {
+			vs, ok := form[k]
+			if !ok {
+				t.Errorf("test %d: Missing key %q", i, k)
+				continue
+			}
+			if len(vs) != len(evs) {
+				t.Errorf("test %d: len(form[%q]) = %d, want %d", i, k, len(vs), len(evs))
+				continue
+			}
+			for j, ev := range evs {
+				if v := vs[j]; v != ev {
+					t.Errorf("test %d: form[%q][%d] = %q, want %q", i, k, j, v, ev)
+				}
+			}
+		}
+	}
+}
+
+type RequestURITest struct {
+	url *URL
+	out string
+}
+
+var requritests = []RequestURITest{
+	{
+		&URL{
+			Scheme: "http",
+			Host:   "example.com",
+			Path:   "",
+		},
+		"/",
+	},
+	{
+		&URL{
+			Scheme: "http",
+			Host:   "example.com",
+			Path:   "/a b",
+		},
+		"/a%20b",
+	},
+	// golang.org/issue/4860 variant 1
+	{
+		&URL{
+			Scheme: "http",
+			Host:   "example.com",
+			Opaque: "/%2F/%2F/",
+		},
+		"/%2F/%2F/",
+	},
+	// golang.org/issue/4860 variant 2
+	{
+		&URL{
+			Scheme: "http",
+			Host:   "example.com",
+			Opaque: "//other.example.com/%2F/%2F/",
+		},
+		"http://other.example.com/%2F/%2F/",
+	},
+	{
+		&URL{
+			Scheme:   "http",
+			Host:     "example.com",
+			Path:     "/a b",
+			RawQuery: "q=go+language",
+		},
+		"/a%20b?q=go+language",
+	},
+	{
+		&URL{
+			Scheme: "myschema",
+			Opaque: "opaque",
+		},
+		"opaque",
+	},
+	{
+		&URL{
+			Scheme:   "myschema",
+			Opaque:   "opaque",
+			RawQuery: "q=go+language",
+		},
+		"opaque?q=go+language",
+	},
+}
+
+func TestRequestURI(t *testing.T) {
+	for _, tt := range requritests {
+		s := tt.url.RequestURI()
+		if s != tt.out {
+			t.Errorf("%#v.RequestURI() == %q (expected %q)", tt.url, s, tt.out)
+		}
+	}
+}
+
+func TestParseFailure(t *testing.T) {
+	// Test that the first parse error is returned.
+	const url = "%gh&%ij"
+	_, err := ParseQuery(url)
+	errStr := fmt.Sprint(err)
+	if !strings.Contains(errStr, "%gh") {
+		t.Errorf(`ParseQuery(%q) returned error %q, want something containing %q"`, url, errStr, "%gh")
+	}
+}
+
+type shouldEscapeTest struct {
+	in     byte
+	mode   encoding
+	escape bool
+}
+
+var shouldEscapeTests = []shouldEscapeTest{
+	// Unreserved characters (§2.3)
+	{'a', encodePath, false},
+	{'a', encodeUserPassword, false},
+	{'a', encodeQueryComponent, false},
+	{'a', encodeFragment, false},
+	{'z', encodePath, false},
+	{'A', encodePath, false},
+	{'Z', encodePath, false},
+	{'0', encodePath, false},
+	{'9', encodePath, false},
+	{'-', encodePath, false},
+	{'-', encodeUserPassword, false},
+	{'-', encodeQueryComponent, false},
+	{'-', encodeFragment, false},
+	{'.', encodePath, false},
+	{'_', encodePath, false},
+	{'~', encodePath, false},
+
+	// User information (§3.2.1)
+	{':', encodeUserPassword, true},
+	{'/', encodeUserPassword, true},
+	{'?', encodeUserPassword, true},
+	{'@', encodeUserPassword, true},
+	{'$', encodeUserPassword, false},
+	{'&', encodeUserPassword, false},
+	{'+', encodeUserPassword, false},
+	{',', encodeUserPassword, false},
+	{';', encodeUserPassword, false},
+	{'=', encodeUserPassword, false},
+}
+
+func TestShouldEscape(t *testing.T) {
+	for _, tt := range shouldEscapeTests {
+		if shouldEscape(tt.in, tt.mode) != tt.escape {
+			t.Errorf("shouldEscape(%q, %v) returned %v; expected %v", tt.in, tt.mode, !tt.escape, tt.escape)
+		}
+	}
+}
diff --git a/src/net/z_last_test.go b/src/net/z_last_test.go
new file mode 100644
index 0000000..716c103
--- /dev/null
+++ b/src/net/z_last_test.go
@@ -0,0 +1,99 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package net
+
+import (
+	"flag"
+	"fmt"
+	"testing"
+	"time"
+)
+
+var testDNSFlood = flag.Bool("dnsflood", false, "whether to test dns query flooding")
+
+func TestDNSThreadLimit(t *testing.T) {
+	if !*testDNSFlood {
+		t.Skip("test disabled; use -dnsflood to enable")
+	}
+
+	const N = 10000
+	c := make(chan int, N)
+	for i := 0; i < N; i++ {
+		go func(i int) {
+			LookupIP(fmt.Sprintf("%d.net-test.golang.org", i))
+			c <- 1
+		}(i)
+	}
+	// Don't bother waiting for the stragglers; stop at 0.9 N.
+	for i := 0; i < N*9/10; i++ {
+		if i%100 == 0 {
+			//println("TestDNSThreadLimit:", i)
+		}
+		<-c
+	}
+
+	// If we're still here, it worked.
+}
+
+func TestLookupIPDeadline(t *testing.T) {
+	if !*testDNSFlood {
+		t.Skip("test disabled; use -dnsflood to enable")
+	}
+
+	const N = 5000
+	const timeout = 3 * time.Second
+	c := make(chan error, 2*N)
+	for i := 0; i < N; i++ {
+		name := fmt.Sprintf("%d.net-test.golang.org", i)
+		go func() {
+			_, err := lookupIPDeadline(name, time.Now().Add(timeout/2))
+			c <- err
+		}()
+		go func() {
+			_, err := lookupIPDeadline(name, time.Now().Add(timeout))
+			c <- err
+		}()
+	}
+	qstats := struct {
+		succeeded, failed         int
+		timeout, temporary, other int
+		unknown                   int
+	}{}
+	deadline := time.After(timeout + time.Second)
+	for i := 0; i < 2*N; i++ {
+		select {
+		case <-deadline:
+			t.Fatal("deadline exceeded")
+		case err := <-c:
+			switch err := err.(type) {
+			case nil:
+				qstats.succeeded++
+			case Error:
+				qstats.failed++
+				if err.Timeout() {
+					qstats.timeout++
+				}
+				if err.Temporary() {
+					qstats.temporary++
+				}
+				if !err.Timeout() && !err.Temporary() {
+					qstats.other++
+				}
+			default:
+				qstats.failed++
+				qstats.unknown++
+			}
+		}
+	}
+
+	// A high volume of DNS queries for sub-domain of golang.org
+	// would be coordinated by authoritative or recursive server,
+	// or stub resolver which implements query-response rate
+	// limitation, so we can expect some query successes and more
+	// failures including timeout, temporary and other here.
+	// As a rule, unknown must not be shown but it might possibly
+	// happen due to issue 4856 for now.
+	t.Logf("%v succeeded, %v failed (%v timeout, %v temporary, %v other, %v unknown)", qstats.succeeded, qstats.failed, qstats.timeout, qstats.temporary, qstats.other, qstats.unknown)
+}
diff --git a/src/pkg/os/dir_plan9.go b/src/os/dir_plan9.go
similarity index 100%
rename from src/pkg/os/dir_plan9.go
rename to src/os/dir_plan9.go
diff --git a/src/os/dir_unix.go b/src/os/dir_unix.go
new file mode 100644
index 0000000..589db85
--- /dev/null
+++ b/src/os/dir_unix.go
@@ -0,0 +1,58 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris
+
+package os
+
+import (
+	"io"
+	"syscall"
+)
+
+const (
+	blockSize = 4096
+)
+
+func (f *File) readdirnames(n int) (names []string, err error) {
+	// If this file has no dirinfo, create one.
+	if f.dirinfo == nil {
+		f.dirinfo = new(dirInfo)
+		// The buffer must be at least a block long.
+		f.dirinfo.buf = make([]byte, blockSize)
+	}
+	d := f.dirinfo
+
+	size := n
+	if size <= 0 {
+		size = 100
+		n = -1
+	}
+
+	names = make([]string, 0, size) // Empty with room to grow.
+	for n != 0 {
+		// Refill the buffer if necessary
+		if d.bufp >= d.nbuf {
+			d.bufp = 0
+			var errno error
+			d.nbuf, errno = fixCount(syscall.ReadDirent(f.fd, d.buf))
+			if errno != nil {
+				return names, NewSyscallError("readdirent", errno)
+			}
+			if d.nbuf <= 0 {
+				break // EOF
+			}
+		}
+
+		// Drain the buffer
+		var nb, nc int
+		nb, nc, names = syscall.ParseDirent(d.buf[d.bufp:d.nbuf], n, names)
+		d.bufp += nb
+		n -= nc
+	}
+	if n >= 0 && len(names) == 0 {
+		return names, io.EOF
+	}
+	return names, nil
+}
diff --git a/src/pkg/os/dir_windows.go b/src/os/dir_windows.go
similarity index 100%
rename from src/pkg/os/dir_windows.go
rename to src/os/dir_windows.go
diff --git a/src/pkg/os/doc.go b/src/os/doc.go
similarity index 100%
rename from src/pkg/os/doc.go
rename to src/os/doc.go
diff --git a/src/os/env.go b/src/os/env.go
new file mode 100644
index 0000000..d0494a4
--- /dev/null
+++ b/src/os/env.go
@@ -0,0 +1,108 @@
+// Copyright 2010 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// General environment variables.
+
+package os
+
+import "syscall"
+
+// Expand replaces ${var} or $var in the string based on the mapping function.
+// For example, os.ExpandEnv(s) is equivalent to os.Expand(s, os.Getenv).
+func Expand(s string, mapping func(string) string) string {
+	buf := make([]byte, 0, 2*len(s))
+	// ${} is all ASCII, so bytes are fine for this operation.
+	i := 0
+	for j := 0; j < len(s); j++ {
+		if s[j] == '$' && j+1 < len(s) {
+			buf = append(buf, s[i:j]...)
+			name, w := getShellName(s[j+1:])
+			buf = append(buf, mapping(name)...)
+			j += w
+			i = j + 1
+		}
+	}
+	return string(buf) + s[i:]
+}
+
+// ExpandEnv replaces ${var} or $var in the string according to the values
+// of the current environment variables.  References to undefined
+// variables are replaced by the empty string.
+func ExpandEnv(s string) string {
+	return Expand(s, Getenv)
+}
+
+// isSpellSpecialVar reports whether the character identifies a special
+// shell variable such as $*.
+func isShellSpecialVar(c uint8) bool {
+	switch c {
+	case '*', '#', '$', '@', '!', '?', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
+		return true
+	}
+	return false
+}
+
+// isAlphaNum reports whether the byte is an ASCII letter, number, or underscore
+func isAlphaNum(c uint8) bool {
+	return c == '_' || '0' <= c && c <= '9' || 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z'
+}
+
+// getName returns the name that begins the string and the number of bytes
+// consumed to extract it.  If the name is enclosed in {}, it's part of a ${}
+// expansion and two more bytes are needed than the length of the name.
+func getShellName(s string) (string, int) {
+	switch {
+	case s[0] == '{':
+		if len(s) > 2 && isShellSpecialVar(s[1]) && s[2] == '}' {
+			return s[1:2], 3
+		}
+		// Scan to closing brace
+		for i := 1; i < len(s); i++ {
+			if s[i] == '}' {
+				return s[1:i], i + 1
+			}
+		}
+		return "", 1 // Bad syntax; just eat the brace.
+	case isShellSpecialVar(s[0]):
+		return s[0:1], 1
+	}
+	// Scan alphanumerics.
+	var i int
+	for i = 0; i < len(s) && isAlphaNum(s[i]); i++ {
+	}
+	return s[:i], i
+}
+
+// Getenv retrieves the value of the environment variable named by the key.
+// It returns the value, which will be empty if the variable is not present.
+func Getenv(key string) string {
+	v, _ := syscall.Getenv(key)
+	return v
+}
+
+// Setenv sets the value of the environment variable named by the key.
+// It returns an error, if any.
+func Setenv(key, value string) error {
+	err := syscall.Setenv(key, value)
+	if err != nil {
+		return NewSyscallError("setenv", err)
+	}
+	return nil
+}
+
+// Unsetenv unsets a single environment variable.
+func Unsetenv(key string) error {
+	return syscall.Unsetenv(key)
+}
+
+// Clearenv deletes all environment variables.
+func Clearenv() {
+	syscall.Clearenv()
+}
+
+// Environ returns a copy of strings representing the environment,
+// in the form "key=value".
+func Environ() []string {
+	return syscall.Environ()
+}
diff --git a/src/os/env_test.go b/src/os/env_test.go
new file mode 100644
index 0000000..e618067
--- /dev/null
+++ b/src/os/env_test.go
@@ -0,0 +1,96 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package os_test
+
+import (
+	. "os"
+	"reflect"
+	"strings"
+	"testing"
+)
+
+// testGetenv gives us a controlled set of variables for testing Expand.
+func testGetenv(s string) string {
+	switch s {
+	case "*":
+		return "all the args"
+	case "#":
+		return "NARGS"
+	case "$":
+		return "PID"
+	case "1":
+		return "ARGUMENT1"
+	case "HOME":
+		return "/usr/gopher"
+	case "H":
+		return "(Value of H)"
+	case "home_1":
+		return "/usr/foo"
+	case "_":
+		return "underscore"
+	}
+	return ""
+}
+
+var expandTests = []struct {
+	in, out string
+}{
+	{"", ""},
+	{"$*", "all the args"},
+	{"$$", "PID"},
+	{"${*}", "all the args"},
+	{"$1", "ARGUMENT1"},
+	{"${1}", "ARGUMENT1"},
+	{"now is the time", "now is the time"},
+	{"$HOME", "/usr/gopher"},
+	{"$home_1", "/usr/foo"},
+	{"${HOME}", "/usr/gopher"},
+	{"${H}OME", "(Value of H)OME"},
+	{"A$$$#$1$H$home_1*B", "APIDNARGSARGUMENT1(Value of H)/usr/foo*B"},
+}
+
+func TestExpand(t *testing.T) {
+	for _, test := range expandTests {
+		result := Expand(test.in, testGetenv)
+		if result != test.out {
+			t.Errorf("Expand(%q)=%q; expected %q", test.in, result, test.out)
+		}
+	}
+}
+
+func TestConsistentEnviron(t *testing.T) {
+	e0 := Environ()
+	for i := 0; i < 10; i++ {
+		e1 := Environ()
+		if !reflect.DeepEqual(e0, e1) {
+			t.Fatalf("environment changed")
+		}
+	}
+}
+
+func TestUnsetenv(t *testing.T) {
+	const testKey = "GO_TEST_UNSETENV"
+	set := func() bool {
+		prefix := testKey + "="
+		for _, key := range Environ() {
+			if strings.HasPrefix(key, prefix) {
+				return true
+			}
+		}
+		return false
+	}
+	if err := Setenv(testKey, "1"); err != nil {
+		t.Fatalf("Setenv: %v", err)
+	}
+	if !set() {
+		t.Error("Setenv didn't set TestUnsetenv")
+	}
+	if err := Unsetenv(testKey); err != nil {
+		t.Fatalf("Unsetenv: %v", err)
+	}
+	if set() {
+		t.Fatal("Unsetenv didn't clear TestUnsetenv")
+	}
+}
diff --git a/src/pkg/os/env_unix_test.go b/src/os/env_unix_test.go
similarity index 100%
rename from src/pkg/os/env_unix_test.go
rename to src/os/env_unix_test.go
diff --git a/src/pkg/os/error.go b/src/os/error.go
similarity index 100%
rename from src/pkg/os/error.go
rename to src/os/error.go
diff --git a/src/os/error_plan9.go b/src/os/error_plan9.go
new file mode 100644
index 0000000..001cdfc
--- /dev/null
+++ b/src/os/error_plan9.go
@@ -0,0 +1,54 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package os
+
+func isExist(err error) bool {
+	switch pe := err.(type) {
+	case nil:
+		return false
+	case *PathError:
+		err = pe.Err
+	case *LinkError:
+		err = pe.Err
+	}
+	return contains(err.Error(), " exists")
+}
+
+func isNotExist(err error) bool {
+	switch pe := err.(type) {
+	case nil:
+		return false
+	case *PathError:
+		err = pe.Err
+	case *LinkError:
+		err = pe.Err
+	}
+	return contains(err.Error(), "does not exist") || contains(err.Error(), "not found") ||
+		contains(err.Error(), "has been removed") || contains(err.Error(), "no parent")
+}
+
+func isPermission(err error) bool {
+	switch pe := err.(type) {
+	case nil:
+		return false
+	case *PathError:
+		err = pe.Err
+	case *LinkError:
+		err = pe.Err
+	}
+	return contains(err.Error(), "permission denied")
+}
+
+// contains is a local version of strings.Contains. It knows len(sep) > 1.
+func contains(s, sep string) bool {
+	n := len(sep)
+	c := sep[0]
+	for i := 0; i+n <= len(s); i++ {
+		if s[i] == c && s[i:i+n] == sep {
+			return true
+		}
+	}
+	return false
+}
diff --git a/src/pkg/os/error_test.go b/src/os/error_test.go
similarity index 100%
rename from src/pkg/os/error_test.go
rename to src/os/error_test.go
diff --git a/src/pkg/os/error_unix.go b/src/os/error_unix.go
similarity index 100%
rename from src/pkg/os/error_unix.go
rename to src/os/error_unix.go
diff --git a/src/pkg/os/error_windows.go b/src/os/error_windows.go
similarity index 100%
rename from src/pkg/os/error_windows.go
rename to src/os/error_windows.go
diff --git a/src/pkg/os/error_windows_test.go b/src/os/error_windows_test.go
similarity index 100%
rename from src/pkg/os/error_windows_test.go
rename to src/os/error_windows_test.go
diff --git a/src/pkg/os/exec.go b/src/os/exec.go
similarity index 100%
rename from src/pkg/os/exec.go
rename to src/os/exec.go
diff --git a/src/pkg/os/exec/example_test.go b/src/os/exec/example_test.go
similarity index 100%
rename from src/pkg/os/exec/example_test.go
rename to src/os/exec/example_test.go
diff --git a/src/os/exec/exec.go b/src/os/exec/exec.go
new file mode 100644
index 0000000..72b4905
--- /dev/null
+++ b/src/os/exec/exec.go
@@ -0,0 +1,500 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package exec runs external commands. It wraps os.StartProcess to make it
+// easier to remap stdin and stdout, connect I/O with pipes, and do other
+// adjustments.
+package exec
+
+import (
+	"bytes"
+	"errors"
+	"io"
+	"os"
+	"path/filepath"
+	"runtime"
+	"strconv"
+	"strings"
+	"sync"
+	"syscall"
+)
+
+// Error records the name of a binary that failed to be executed
+// and the reason it failed.
+type Error struct {
+	Name string
+	Err  error
+}
+
+func (e *Error) Error() string {
+	return "exec: " + strconv.Quote(e.Name) + ": " + e.Err.Error()
+}
+
+// Cmd represents an external command being prepared or run.
+type Cmd struct {
+	// Path is the path of the command to run.
+	//
+	// This is the only field that must be set to a non-zero
+	// value. If Path is relative, it is evaluated relative
+	// to Dir.
+	Path string
+
+	// Args holds command line arguments, including the command as Args[0].
+	// If the Args field is empty or nil, Run uses {Path}.
+	//
+	// In typical use, both Path and Args are set by calling Command.
+	Args []string
+
+	// Env specifies the environment of the process.
+	// If Env is nil, Run uses the current process's environment.
+	Env []string
+
+	// Dir specifies the working directory of the command.
+	// If Dir is the empty string, Run runs the command in the
+	// calling process's current directory.
+	Dir string
+
+	// Stdin specifies the process's standard input.
+	// If Stdin is nil, the process reads from the null device (os.DevNull).
+	// If Stdin is an *os.File, the process's standard input is connected
+	// directly to that file.
+	// Otherwise, during the execution of the command a separate
+	// goroutine reads from Stdin and delivers that data to the command
+	// over a pipe. In this case, Wait does not complete until the goroutine
+	// stops copying, either because it has reached the end of Stdin
+	// (EOF or a read error) or because writing to the pipe returned an error.
+	Stdin io.Reader
+
+	// Stdout and Stderr specify the process's standard output and error.
+	//
+	// If either is nil, Run connects the corresponding file descriptor
+	// to the null device (os.DevNull).
+	//
+	// If Stdout and Stderr are the same writer, at most one
+	// goroutine at a time will call Write.
+	Stdout io.Writer
+	Stderr io.Writer
+
+	// ExtraFiles specifies additional open files to be inherited by the
+	// new process. It does not include standard input, standard output, or
+	// standard error. If non-nil, entry i becomes file descriptor 3+i.
+	//
+	// BUG: on OS X 10.6, child processes may sometimes inherit unwanted fds.
+	// http://golang.org/issue/2603
+	ExtraFiles []*os.File
+
+	// SysProcAttr holds optional, operating system-specific attributes.
+	// Run passes it to os.StartProcess as the os.ProcAttr's Sys field.
+	SysProcAttr *syscall.SysProcAttr
+
+	// Process is the underlying process, once started.
+	Process *os.Process
+
+	// ProcessState contains information about an exited process,
+	// available after a call to Wait or Run.
+	ProcessState *os.ProcessState
+
+	lookPathErr     error // LookPath error, if any.
+	finished        bool  // when Wait was called
+	childFiles      []*os.File
+	closeAfterStart []io.Closer
+	closeAfterWait  []io.Closer
+	goroutine       []func() error
+	errch           chan error // one send per goroutine
+}
+
+// Command returns the Cmd struct to execute the named program with
+// the given arguments.
+//
+// It sets only the Path and Args in the returned structure.
+//
+// If name contains no path separators, Command uses LookPath to
+// resolve the path to a complete name if possible. Otherwise it uses
+// name directly.
+//
+// The returned Cmd's Args field is constructed from the command name
+// followed by the elements of arg, so arg should not include the
+// command name itself. For example, Command("echo", "hello")
+func Command(name string, arg ...string) *Cmd {
+	cmd := &Cmd{
+		Path: name,
+		Args: append([]string{name}, arg...),
+	}
+	if filepath.Base(name) == name {
+		if lp, err := LookPath(name); err != nil {
+			cmd.lookPathErr = err
+		} else {
+			cmd.Path = lp
+		}
+	}
+	return cmd
+}
+
+// interfaceEqual protects against panics from doing equality tests on
+// two interfaces with non-comparable underlying types.
+func interfaceEqual(a, b interface{}) bool {
+	defer func() {
+		recover()
+	}()
+	return a == b
+}
+
+func (c *Cmd) envv() []string {
+	if c.Env != nil {
+		return c.Env
+	}
+	return os.Environ()
+}
+
+func (c *Cmd) argv() []string {
+	if len(c.Args) > 0 {
+		return c.Args
+	}
+	return []string{c.Path}
+}
+
+func (c *Cmd) stdin() (f *os.File, err error) {
+	if c.Stdin == nil {
+		f, err = os.Open(os.DevNull)
+		if err != nil {
+			return
+		}
+		c.closeAfterStart = append(c.closeAfterStart, f)
+		return
+	}
+
+	if f, ok := c.Stdin.(*os.File); ok {
+		return f, nil
+	}
+
+	pr, pw, err := os.Pipe()
+	if err != nil {
+		return
+	}
+
+	c.closeAfterStart = append(c.closeAfterStart, pr)
+	c.closeAfterWait = append(c.closeAfterWait, pw)
+	c.goroutine = append(c.goroutine, func() error {
+		_, err := io.Copy(pw, c.Stdin)
+		if err1 := pw.Close(); err == nil {
+			err = err1
+		}
+		return err
+	})
+	return pr, nil
+}
+
+func (c *Cmd) stdout() (f *os.File, err error) {
+	return c.writerDescriptor(c.Stdout)
+}
+
+func (c *Cmd) stderr() (f *os.File, err error) {
+	if c.Stderr != nil && interfaceEqual(c.Stderr, c.Stdout) {
+		return c.childFiles[1], nil
+	}
+	return c.writerDescriptor(c.Stderr)
+}
+
+func (c *Cmd) writerDescriptor(w io.Writer) (f *os.File, err error) {
+	if w == nil {
+		f, err = os.OpenFile(os.DevNull, os.O_WRONLY, 0)
+		if err != nil {
+			return
+		}
+		c.closeAfterStart = append(c.closeAfterStart, f)
+		return
+	}
+
+	if f, ok := w.(*os.File); ok {
+		return f, nil
+	}
+
+	pr, pw, err := os.Pipe()
+	if err != nil {
+		return
+	}
+
+	c.closeAfterStart = append(c.closeAfterStart, pw)
+	c.closeAfterWait = append(c.closeAfterWait, pr)
+	c.goroutine = append(c.goroutine, func() error {
+		_, err := io.Copy(w, pr)
+		return err
+	})
+	return pw, nil
+}
+
+func (c *Cmd) closeDescriptors(closers []io.Closer) {
+	for _, fd := range closers {
+		fd.Close()
+	}
+}
+
+// Run starts the specified command and waits for it to complete.
+//
+// The returned error is nil if the command runs, has no problems
+// copying stdin, stdout, and stderr, and exits with a zero exit
+// status.
+//
+// If the command fails to run or doesn't complete successfully, the
+// error is of type *ExitError. Other error types may be
+// returned for I/O problems.
+func (c *Cmd) Run() error {
+	if err := c.Start(); err != nil {
+		return err
+	}
+	return c.Wait()
+}
+
+// lookExtensions finds windows executable by its dir and path.
+// It uses LookPath to try appropriate extensions.
+// lookExtensions does not search PATH, instead it converts `prog` into `.\prog`.
+func lookExtensions(path, dir string) (string, error) {
+	if filepath.Base(path) == path {
+		path = filepath.Join(".", path)
+	}
+	if dir == "" {
+		return LookPath(path)
+	}
+	if filepath.VolumeName(path) != "" {
+		return LookPath(path)
+	}
+	if len(path) > 1 && os.IsPathSeparator(path[0]) {
+		return LookPath(path)
+	}
+	dirandpath := filepath.Join(dir, path)
+	// We assume that LookPath will only add file extension.
+	lp, err := LookPath(dirandpath)
+	if err != nil {
+		return "", err
+	}
+	ext := strings.TrimPrefix(lp, dirandpath)
+	return path + ext, nil
+}
+
+// Start starts the specified command but does not wait for it to complete.
+//
+// The Wait method will return the exit code and release associated resources
+// once the command exits.
+func (c *Cmd) Start() error {
+	if c.lookPathErr != nil {
+		c.closeDescriptors(c.closeAfterStart)
+		c.closeDescriptors(c.closeAfterWait)
+		return c.lookPathErr
+	}
+	if runtime.GOOS == "windows" {
+		lp, err := lookExtensions(c.Path, c.Dir)
+		if err != nil {
+			c.closeDescriptors(c.closeAfterStart)
+			c.closeDescriptors(c.closeAfterWait)
+			return err
+		}
+		c.Path = lp
+	}
+	if c.Process != nil {
+		return errors.New("exec: already started")
+	}
+
+	type F func(*Cmd) (*os.File, error)
+	for _, setupFd := range []F{(*Cmd).stdin, (*Cmd).stdout, (*Cmd).stderr} {
+		fd, err := setupFd(c)
+		if err != nil {
+			c.closeDescriptors(c.closeAfterStart)
+			c.closeDescriptors(c.closeAfterWait)
+			return err
+		}
+		c.childFiles = append(c.childFiles, fd)
+	}
+	c.childFiles = append(c.childFiles, c.ExtraFiles...)
+
+	var err error
+	c.Process, err = os.StartProcess(c.Path, c.argv(), &os.ProcAttr{
+		Dir:   c.Dir,
+		Files: c.childFiles,
+		Env:   c.envv(),
+		Sys:   c.SysProcAttr,
+	})
+	if err != nil {
+		c.closeDescriptors(c.closeAfterStart)
+		c.closeDescriptors(c.closeAfterWait)
+		return err
+	}
+
+	c.closeDescriptors(c.closeAfterStart)
+
+	c.errch = make(chan error, len(c.goroutine))
+	for _, fn := range c.goroutine {
+		go func(fn func() error) {
+			c.errch <- fn()
+		}(fn)
+	}
+
+	return nil
+}
+
+// An ExitError reports an unsuccessful exit by a command.
+type ExitError struct {
+	*os.ProcessState
+}
+
+func (e *ExitError) Error() string {
+	return e.ProcessState.String()
+}
+
+// Wait waits for the command to exit.
+// It must have been started by Start.
+//
+// The returned error is nil if the command runs, has no problems
+// copying stdin, stdout, and stderr, and exits with a zero exit
+// status.
+//
+// If the command fails to run or doesn't complete successfully, the
+// error is of type *ExitError. Other error types may be
+// returned for I/O problems.
+//
+// Wait releases any resources associated with the Cmd.
+func (c *Cmd) Wait() error {
+	if c.Process == nil {
+		return errors.New("exec: not started")
+	}
+	if c.finished {
+		return errors.New("exec: Wait was already called")
+	}
+	c.finished = true
+	state, err := c.Process.Wait()
+	c.ProcessState = state
+
+	var copyError error
+	for range c.goroutine {
+		if err := <-c.errch; err != nil && copyError == nil {
+			copyError = err
+		}
+	}
+
+	c.closeDescriptors(c.closeAfterWait)
+
+	if err != nil {
+		return err
+	} else if !state.Success() {
+		return &ExitError{state}
+	}
+
+	return copyError
+}
+
+// Output runs the command and returns its standard output.
+func (c *Cmd) Output() ([]byte, error) {
+	if c.Stdout != nil {
+		return nil, errors.New("exec: Stdout already set")
+	}
+	var b bytes.Buffer
+	c.Stdout = &b
+	err := c.Run()
+	return b.Bytes(), err
+}
+
+// CombinedOutput runs the command and returns its combined standard
+// output and standard error.
+func (c *Cmd) CombinedOutput() ([]byte, error) {
+	if c.Stdout != nil {
+		return nil, errors.New("exec: Stdout already set")
+	}
+	if c.Stderr != nil {
+		return nil, errors.New("exec: Stderr already set")
+	}
+	var b bytes.Buffer
+	c.Stdout = &b
+	c.Stderr = &b
+	err := c.Run()
+	return b.Bytes(), err
+}
+
+// StdinPipe returns a pipe that will be connected to the command's
+// standard input when the command starts.
+// The pipe will be closed automatically after Wait sees the command exit.
+// A caller need only call Close to force the pipe to close sooner.
+// For example, if the command being run will not exit until standard input
+// is closed, the caller must close the pipe.
+func (c *Cmd) StdinPipe() (io.WriteCloser, error) {
+	if c.Stdin != nil {
+		return nil, errors.New("exec: Stdin already set")
+	}
+	if c.Process != nil {
+		return nil, errors.New("exec: StdinPipe after process started")
+	}
+	pr, pw, err := os.Pipe()
+	if err != nil {
+		return nil, err
+	}
+	c.Stdin = pr
+	c.closeAfterStart = append(c.closeAfterStart, pr)
+	wc := &closeOnce{File: pw}
+	c.closeAfterWait = append(c.closeAfterWait, wc)
+	return wc, nil
+}
+
+type closeOnce struct {
+	*os.File
+
+	once sync.Once
+	err  error
+}
+
+func (c *closeOnce) Close() error {
+	c.once.Do(c.close)
+	return c.err
+}
+
+func (c *closeOnce) close() {
+	c.err = c.File.Close()
+}
+
+// StdoutPipe returns a pipe that will be connected to the command's
+// standard output when the command starts.
+//
+// Wait will close the pipe after seeing the command exit, so most callers
+// need not close the pipe themselves; however, an implication is that
+// it is incorrect to call Wait before all reads from the pipe have completed.
+// For the same reason, it is incorrect to call Run when using StdoutPipe.
+// See the example for idiomatic usage.
+func (c *Cmd) StdoutPipe() (io.ReadCloser, error) {
+	if c.Stdout != nil {
+		return nil, errors.New("exec: Stdout already set")
+	}
+	if c.Process != nil {
+		return nil, errors.New("exec: StdoutPipe after process started")
+	}
+	pr, pw, err := os.Pipe()
+	if err != nil {
+		return nil, err
+	}
+	c.Stdout = pw
+	c.closeAfterStart = append(c.closeAfterStart, pw)
+	c.closeAfterWait = append(c.closeAfterWait, pr)
+	return pr, nil
+}
+
+// StderrPipe returns a pipe that will be connected to the command's
+// standard error when the command starts.
+//
+// Wait will close the pipe after seeing the command exit, so most callers
+// need not close the pipe themselves; however, an implication is that
+// it is incorrect to call Wait before all reads from the pipe have completed.
+// For the same reason, it is incorrect to use Run when using StderrPipe.
+// See the StdoutPipe example for idiomatic usage.
+func (c *Cmd) StderrPipe() (io.ReadCloser, error) {
+	if c.Stderr != nil {
+		return nil, errors.New("exec: Stderr already set")
+	}
+	if c.Process != nil {
+		return nil, errors.New("exec: StderrPipe after process started")
+	}
+	pr, pw, err := os.Pipe()
+	if err != nil {
+		return nil, err
+	}
+	c.Stderr = pw
+	c.closeAfterStart = append(c.closeAfterStart, pw)
+	c.closeAfterWait = append(c.closeAfterWait, pr)
+	return pr, nil
+}
diff --git a/src/os/exec/exec_test.go b/src/os/exec/exec_test.go
new file mode 100644
index 0000000..197d3e8
--- /dev/null
+++ b/src/os/exec/exec_test.go
@@ -0,0 +1,719 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Use an external test to avoid os/exec -> net/http -> crypto/x509 -> os/exec
+// circular dependency on non-cgo darwin.
+
+package exec_test
+
+import (
+	"bufio"
+	"bytes"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"log"
+	"net"
+	"net/http"
+	"net/http/httptest"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"runtime"
+	"strconv"
+	"strings"
+	"testing"
+	"time"
+)
+
+func helperCommand(t *testing.T, s ...string) *exec.Cmd {
+	if runtime.GOOS == "nacl" {
+		t.Skip("skipping on nacl")
+	}
+	cs := []string{"-test.run=TestHelperProcess", "--"}
+	cs = append(cs, s...)
+	cmd := exec.Command(os.Args[0], cs...)
+	cmd.Env = []string{"GO_WANT_HELPER_PROCESS=1"}
+	return cmd
+}
+
+func TestEcho(t *testing.T) {
+	bs, err := helperCommand(t, "echo", "foo bar", "baz").Output()
+	if err != nil {
+		t.Errorf("echo: %v", err)
+	}
+	if g, e := string(bs), "foo bar baz\n"; g != e {
+		t.Errorf("echo: want %q, got %q", e, g)
+	}
+}
+
+func TestCommandRelativeName(t *testing.T) {
+	// Run our own binary as a relative path
+	// (e.g. "_test/exec.test") our parent directory.
+	base := filepath.Base(os.Args[0]) // "exec.test"
+	dir := filepath.Dir(os.Args[0])   // "/tmp/go-buildNNNN/os/exec/_test"
+	if dir == "." {
+		t.Skip("skipping; running test at root somehow")
+	}
+	parentDir := filepath.Dir(dir) // "/tmp/go-buildNNNN/os/exec"
+	dirBase := filepath.Base(dir)  // "_test"
+	if dirBase == "." {
+		t.Skipf("skipping; unexpected shallow dir of %q", dir)
+	}
+
+	cmd := exec.Command(filepath.Join(dirBase, base), "-test.run=TestHelperProcess", "--", "echo", "foo")
+	cmd.Dir = parentDir
+	cmd.Env = []string{"GO_WANT_HELPER_PROCESS=1"}
+
+	out, err := cmd.Output()
+	if err != nil {
+		t.Errorf("echo: %v", err)
+	}
+	if g, e := string(out), "foo\n"; g != e {
+		t.Errorf("echo: want %q, got %q", e, g)
+	}
+}
+
+func TestCatStdin(t *testing.T) {
+	// Cat, testing stdin and stdout.
+	input := "Input string\nLine 2"
+	p := helperCommand(t, "cat")
+	p.Stdin = strings.NewReader(input)
+	bs, err := p.Output()
+	if err != nil {
+		t.Errorf("cat: %v", err)
+	}
+	s := string(bs)
+	if s != input {
+		t.Errorf("cat: want %q, got %q", input, s)
+	}
+}
+
+func TestCatGoodAndBadFile(t *testing.T) {
+	// Testing combined output and error values.
+	bs, err := helperCommand(t, "cat", "/bogus/file.foo", "exec_test.go").CombinedOutput()
+	if _, ok := err.(*exec.ExitError); !ok {
+		t.Errorf("expected *exec.ExitError from cat combined; got %T: %v", err, err)
+	}
+	s := string(bs)
+	sp := strings.SplitN(s, "\n", 2)
+	if len(sp) != 2 {
+		t.Fatalf("expected two lines from cat; got %q", s)
+	}
+	errLine, body := sp[0], sp[1]
+	if !strings.HasPrefix(errLine, "Error: open /bogus/file.foo") {
+		t.Errorf("expected stderr to complain about file; got %q", errLine)
+	}
+	if !strings.Contains(body, "func TestHelperProcess(t *testing.T)") {
+		t.Errorf("expected test code; got %q (len %d)", body, len(body))
+	}
+}
+
+func TestNoExistBinary(t *testing.T) {
+	// Can't run a non-existent binary
+	err := exec.Command("/no-exist-binary").Run()
+	if err == nil {
+		t.Error("expected error from /no-exist-binary")
+	}
+}
+
+func TestExitStatus(t *testing.T) {
+	// Test that exit values are returned correctly
+	cmd := helperCommand(t, "exit", "42")
+	err := cmd.Run()
+	want := "exit status 42"
+	switch runtime.GOOS {
+	case "plan9":
+		want = fmt.Sprintf("exit status: '%s %d: 42'", filepath.Base(cmd.Path), cmd.ProcessState.Pid())
+	}
+	if werr, ok := err.(*exec.ExitError); ok {
+		if s := werr.Error(); s != want {
+			t.Errorf("from exit 42 got exit %q, want %q", s, want)
+		}
+	} else {
+		t.Fatalf("expected *exec.ExitError from exit 42; got %T: %v", err, err)
+	}
+}
+
+func TestPipes(t *testing.T) {
+	check := func(what string, err error) {
+		if err != nil {
+			t.Fatalf("%s: %v", what, err)
+		}
+	}
+	// Cat, testing stdin and stdout.
+	c := helperCommand(t, "pipetest")
+	stdin, err := c.StdinPipe()
+	check("StdinPipe", err)
+	stdout, err := c.StdoutPipe()
+	check("StdoutPipe", err)
+	stderr, err := c.StderrPipe()
+	check("StderrPipe", err)
+
+	outbr := bufio.NewReader(stdout)
+	errbr := bufio.NewReader(stderr)
+	line := func(what string, br *bufio.Reader) string {
+		line, _, err := br.ReadLine()
+		if err != nil {
+			t.Fatalf("%s: %v", what, err)
+		}
+		return string(line)
+	}
+
+	err = c.Start()
+	check("Start", err)
+
+	_, err = stdin.Write([]byte("O:I am output\n"))
+	check("first stdin Write", err)
+	if g, e := line("first output line", outbr), "O:I am output"; g != e {
+		t.Errorf("got %q, want %q", g, e)
+	}
+
+	_, err = stdin.Write([]byte("E:I am error\n"))
+	check("second stdin Write", err)
+	if g, e := line("first error line", errbr), "E:I am error"; g != e {
+		t.Errorf("got %q, want %q", g, e)
+	}
+
+	_, err = stdin.Write([]byte("O:I am output2\n"))
+	check("third stdin Write 3", err)
+	if g, e := line("second output line", outbr), "O:I am output2"; g != e {
+		t.Errorf("got %q, want %q", g, e)
+	}
+
+	stdin.Close()
+	err = c.Wait()
+	check("Wait", err)
+}
+
+const stdinCloseTestString = "Some test string."
+
+// Issue 6270.
+func TestStdinClose(t *testing.T) {
+	check := func(what string, err error) {
+		if err != nil {
+			t.Fatalf("%s: %v", what, err)
+		}
+	}
+	cmd := helperCommand(t, "stdinClose")
+	stdin, err := cmd.StdinPipe()
+	check("StdinPipe", err)
+	// Check that we can access methods of the underlying os.File.`
+	if _, ok := stdin.(interface {
+		Fd() uintptr
+	}); !ok {
+		t.Error("can't access methods of underlying *os.File")
+	}
+	check("Start", cmd.Start())
+	go func() {
+		_, err := io.Copy(stdin, strings.NewReader(stdinCloseTestString))
+		check("Copy", err)
+		// Before the fix, this next line would race with cmd.Wait.
+		check("Close", stdin.Close())
+	}()
+	check("Wait", cmd.Wait())
+}
+
+// Issue 5071
+func TestPipeLookPathLeak(t *testing.T) {
+	fd0, lsof0 := numOpenFDS(t)
+	for i := 0; i < 4; i++ {
+		cmd := exec.Command("something-that-does-not-exist-binary")
+		cmd.StdoutPipe()
+		cmd.StderrPipe()
+		cmd.StdinPipe()
+		if err := cmd.Run(); err == nil {
+			t.Fatal("unexpected success")
+		}
+	}
+	for triesLeft := 3; triesLeft >= 0; triesLeft-- {
+		open, lsof := numOpenFDS(t)
+		fdGrowth := open - fd0
+		if fdGrowth > 2 {
+			if triesLeft > 0 {
+				// Work around what appears to be a race with Linux's
+				// proc filesystem (as used by lsof). It seems to only
+				// be eventually consistent. Give it awhile to settle.
+				// See golang.org/issue/7808
+				time.Sleep(100 * time.Millisecond)
+				continue
+			}
+			t.Errorf("leaked %d fds; want ~0; have:\n%s\noriginally:\n%s", fdGrowth, lsof, lsof0)
+		}
+		break
+	}
+}
+
+func numOpenFDS(t *testing.T) (n int, lsof []byte) {
+	lsof, err := exec.Command("lsof", "-b", "-n", "-p", strconv.Itoa(os.Getpid())).Output()
+	if err != nil {
+		t.Skip("skipping test; error finding or running lsof")
+	}
+	return bytes.Count(lsof, []byte("\n")), lsof
+}
+
+var testedAlreadyLeaked = false
+
+// basefds returns the number of expected file descriptors
+// to be present in a process at start.
+func basefds() uintptr {
+	return os.Stderr.Fd() + 1
+}
+
+func closeUnexpectedFds(t *testing.T, m string) {
+	for fd := basefds(); fd <= 101; fd++ {
+		err := os.NewFile(fd, "").Close()
+		if err == nil {
+			t.Logf("%s: Something already leaked - closed fd %d", m, fd)
+		}
+	}
+}
+
+func TestExtraFilesFDShuffle(t *testing.T) {
+	t.Skip("flaky test; see http://golang.org/issue/5780")
+	switch runtime.GOOS {
+	case "darwin":
+		// TODO(cnicolaou): http://golang.org/issue/2603
+		// leads to leaked file descriptors in this test when it's
+		// run from a builder.
+		closeUnexpectedFds(t, "TestExtraFilesFDShuffle")
+	case "netbsd":
+		// http://golang.org/issue/3955
+		closeUnexpectedFds(t, "TestExtraFilesFDShuffle")
+	case "windows":
+		t.Skip("no operating system support; skipping")
+	}
+
+	// syscall.StartProcess maps all the FDs passed to it in
+	// ProcAttr.Files (the concatenation of stdin,stdout,stderr and
+	// ExtraFiles) into consecutive FDs in the child, that is:
+	// Files{11, 12, 6, 7, 9, 3} should result in the file
+	// represented by FD 11 in the parent being made available as 0
+	// in the child, 12 as 1, etc.
+	//
+	// We want to test that FDs in the child do not get overwritten
+	// by one another as this shuffle occurs. The original implementation
+	// was buggy in that in some data dependent cases it would ovewrite
+	// stderr in the child with one of the ExtraFile members.
+	// Testing for this case is difficult because it relies on using
+	// the same FD values as that case. In particular, an FD of 3
+	// must be at an index of 4 or higher in ProcAttr.Files and
+	// the FD of the write end of the Stderr pipe (as obtained by
+	// StderrPipe()) must be the same as the size of ProcAttr.Files;
+	// therefore we test that the read end of this pipe (which is what
+	// is returned to the parent by StderrPipe() being one less than
+	// the size of ProcAttr.Files, i.e. 3+len(cmd.ExtraFiles).
+	//
+	// Moving this test case around within the overall tests may
+	// affect the FDs obtained and hence the checks to catch these cases.
+	npipes := 2
+	c := helperCommand(t, "extraFilesAndPipes", strconv.Itoa(npipes+1))
+	rd, wr, _ := os.Pipe()
+	defer rd.Close()
+	if rd.Fd() != 3 {
+		t.Errorf("bad test value for test pipe: fd %d", rd.Fd())
+	}
+	stderr, _ := c.StderrPipe()
+	wr.WriteString("_LAST")
+	wr.Close()
+
+	pipes := make([]struct {
+		r, w *os.File
+	}, npipes)
+	data := []string{"a", "b"}
+
+	for i := 0; i < npipes; i++ {
+		r, w, err := os.Pipe()
+		if err != nil {
+			t.Fatalf("unexpected error creating pipe: %s", err)
+		}
+		pipes[i].r = r
+		pipes[i].w = w
+		w.WriteString(data[i])
+		c.ExtraFiles = append(c.ExtraFiles, pipes[i].r)
+		defer func() {
+			r.Close()
+			w.Close()
+		}()
+	}
+	// Put fd 3 at the end.
+	c.ExtraFiles = append(c.ExtraFiles, rd)
+
+	stderrFd := int(stderr.(*os.File).Fd())
+	if stderrFd != ((len(c.ExtraFiles) + 3) - 1) {
+		t.Errorf("bad test value for stderr pipe")
+	}
+
+	expected := "child: " + strings.Join(data, "") + "_LAST"
+
+	err := c.Start()
+	if err != nil {
+		t.Fatalf("Run: %v", err)
+	}
+	ch := make(chan string, 1)
+	go func(ch chan string) {
+		buf := make([]byte, 512)
+		n, err := stderr.Read(buf)
+		if err != nil {
+			t.Fatalf("Read: %s", err)
+			ch <- err.Error()
+		} else {
+			ch <- string(buf[:n])
+		}
+		close(ch)
+	}(ch)
+	select {
+	case m := <-ch:
+		if m != expected {
+			t.Errorf("Read: '%s' not '%s'", m, expected)
+		}
+	case <-time.After(5 * time.Second):
+		t.Errorf("Read timedout")
+	}
+	c.Wait()
+}
+
+func TestExtraFiles(t *testing.T) {
+	switch runtime.GOOS {
+	case "nacl", "windows":
+		t.Skipf("skipping test on %q", runtime.GOOS)
+	}
+
+	// Ensure that file descriptors have not already been leaked into
+	// our environment.
+	if !testedAlreadyLeaked {
+		testedAlreadyLeaked = true
+		closeUnexpectedFds(t, "TestExtraFiles")
+	}
+
+	// Force network usage, to verify the epoll (or whatever) fd
+	// doesn't leak to the child,
+	ln, err := net.Listen("tcp", "127.0.0.1:0")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer ln.Close()
+
+	// Make sure duplicated fds don't leak to the child.
+	f, err := ln.(*net.TCPListener).File()
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer f.Close()
+	ln2, err := net.FileListener(f)
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer ln2.Close()
+
+	// Force TLS root certs to be loaded (which might involve
+	// cgo), to make sure none of that potential C code leaks fds.
+	ts := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {}))
+	// quiet expected TLS handshake error "remote error: bad certificate"
+	ts.Config.ErrorLog = log.New(ioutil.Discard, "", 0)
+	ts.StartTLS()
+	defer ts.Close()
+	_, err = http.Get(ts.URL)
+	if err == nil {
+		t.Errorf("success trying to fetch %s; want an error", ts.URL)
+	}
+
+	tf, err := ioutil.TempFile("", "")
+	if err != nil {
+		t.Fatalf("TempFile: %v", err)
+	}
+	defer os.Remove(tf.Name())
+	defer tf.Close()
+
+	const text = "Hello, fd 3!"
+	_, err = tf.Write([]byte(text))
+	if err != nil {
+		t.Fatalf("Write: %v", err)
+	}
+	_, err = tf.Seek(0, os.SEEK_SET)
+	if err != nil {
+		t.Fatalf("Seek: %v", err)
+	}
+
+	c := helperCommand(t, "read3")
+	var stdout, stderr bytes.Buffer
+	c.Stdout = &stdout
+	c.Stderr = &stderr
+	c.ExtraFiles = []*os.File{tf}
+	err = c.Run()
+	if err != nil {
+		t.Fatalf("Run: %v; stdout %q, stderr %q", err, stdout.Bytes(), stderr.Bytes())
+	}
+	if stdout.String() != text {
+		t.Errorf("got stdout %q, stderr %q; want %q on stdout", stdout.String(), stderr.String(), text)
+	}
+}
+
+func TestExtraFilesRace(t *testing.T) {
+	if runtime.GOOS == "windows" {
+		t.Skip("no operating system support; skipping")
+	}
+	listen := func() net.Listener {
+		ln, err := net.Listen("tcp", "127.0.0.1:0")
+		if err != nil {
+			t.Fatal(err)
+		}
+		return ln
+	}
+	listenerFile := func(ln net.Listener) *os.File {
+		f, err := ln.(*net.TCPListener).File()
+		if err != nil {
+			t.Fatal(err)
+		}
+		return f
+	}
+	runCommand := func(c *exec.Cmd, out chan<- string) {
+		bout, err := c.CombinedOutput()
+		if err != nil {
+			out <- "ERROR:" + err.Error()
+		} else {
+			out <- string(bout)
+		}
+	}
+
+	for i := 0; i < 10; i++ {
+		la := listen()
+		ca := helperCommand(t, "describefiles")
+		ca.ExtraFiles = []*os.File{listenerFile(la)}
+		lb := listen()
+		cb := helperCommand(t, "describefiles")
+		cb.ExtraFiles = []*os.File{listenerFile(lb)}
+		ares := make(chan string)
+		bres := make(chan string)
+		go runCommand(ca, ares)
+		go runCommand(cb, bres)
+		if got, want := <-ares, fmt.Sprintf("fd3: listener %s\n", la.Addr()); got != want {
+			t.Errorf("iteration %d, process A got:\n%s\nwant:\n%s\n", i, got, want)
+		}
+		if got, want := <-bres, fmt.Sprintf("fd3: listener %s\n", lb.Addr()); got != want {
+			t.Errorf("iteration %d, process B got:\n%s\nwant:\n%s\n", i, got, want)
+		}
+		la.Close()
+		lb.Close()
+		for _, f := range ca.ExtraFiles {
+			f.Close()
+		}
+		for _, f := range cb.ExtraFiles {
+			f.Close()
+		}
+
+	}
+}
+
+// TestHelperProcess isn't a real test. It's used as a helper process
+// for TestParameterRun.
+func TestHelperProcess(*testing.T) {
+	if os.Getenv("GO_WANT_HELPER_PROCESS") != "1" {
+		return
+	}
+	defer os.Exit(0)
+
+	// Determine which command to use to display open files.
+	ofcmd := "lsof"
+	switch runtime.GOOS {
+	case "dragonfly", "freebsd", "netbsd", "openbsd":
+		ofcmd = "fstat"
+	case "plan9":
+		ofcmd = "/bin/cat"
+	}
+
+	args := os.Args
+	for len(args) > 0 {
+		if args[0] == "--" {
+			args = args[1:]
+			break
+		}
+		args = args[1:]
+	}
+	if len(args) == 0 {
+		fmt.Fprintf(os.Stderr, "No command\n")
+		os.Exit(2)
+	}
+
+	cmd, args := args[0], args[1:]
+	switch cmd {
+	case "echo":
+		iargs := []interface{}{}
+		for _, s := range args {
+			iargs = append(iargs, s)
+		}
+		fmt.Println(iargs...)
+	case "cat":
+		if len(args) == 0 {
+			io.Copy(os.Stdout, os.Stdin)
+			return
+		}
+		exit := 0
+		for _, fn := range args {
+			f, err := os.Open(fn)
+			if err != nil {
+				fmt.Fprintf(os.Stderr, "Error: %v\n", err)
+				exit = 2
+			} else {
+				defer f.Close()
+				io.Copy(os.Stdout, f)
+			}
+		}
+		os.Exit(exit)
+	case "pipetest":
+		bufr := bufio.NewReader(os.Stdin)
+		for {
+			line, _, err := bufr.ReadLine()
+			if err == io.EOF {
+				break
+			} else if err != nil {
+				os.Exit(1)
+			}
+			if bytes.HasPrefix(line, []byte("O:")) {
+				os.Stdout.Write(line)
+				os.Stdout.Write([]byte{'\n'})
+			} else if bytes.HasPrefix(line, []byte("E:")) {
+				os.Stderr.Write(line)
+				os.Stderr.Write([]byte{'\n'})
+			} else {
+				os.Exit(1)
+			}
+		}
+	case "stdinClose":
+		b, err := ioutil.ReadAll(os.Stdin)
+		if err != nil {
+			fmt.Fprintf(os.Stderr, "Error: %v\n", err)
+			os.Exit(1)
+		}
+		if s := string(b); s != stdinCloseTestString {
+			fmt.Fprintf(os.Stderr, "Error: Read %q, want %q", s, stdinCloseTestString)
+			os.Exit(1)
+		}
+		os.Exit(0)
+	case "read3": // read fd 3
+		fd3 := os.NewFile(3, "fd3")
+		bs, err := ioutil.ReadAll(fd3)
+		if err != nil {
+			fmt.Printf("ReadAll from fd 3: %v", err)
+			os.Exit(1)
+		}
+		switch runtime.GOOS {
+		case "dragonfly":
+			// TODO(jsing): Determine why DragonFly is leaking
+			// file descriptors...
+		case "darwin":
+			// TODO(bradfitz): broken? Sometimes.
+			// http://golang.org/issue/2603
+			// Skip this additional part of the test for now.
+		case "netbsd":
+			// TODO(jsing): This currently fails on NetBSD due to
+			// the cloned file descriptors that result from opening
+			// /dev/urandom.
+			// http://golang.org/issue/3955
+		case "plan9":
+			// TODO(0intro): Determine why Plan 9 is leaking
+			// file descriptors.
+			// http://golang.org/issue/7118
+		case "solaris":
+			// TODO(aram): This fails on Solaris because libc opens
+			// its own files, as it sees fit. Darwin does the same,
+			// see: http://golang.org/issue/2603
+		default:
+			// Now verify that there are no other open fds.
+			var files []*os.File
+			for wantfd := basefds() + 1; wantfd <= 100; wantfd++ {
+				f, err := os.Open(os.Args[0])
+				if err != nil {
+					fmt.Printf("error opening file with expected fd %d: %v", wantfd, err)
+					os.Exit(1)
+				}
+				if got := f.Fd(); got != wantfd {
+					fmt.Printf("leaked parent file. fd = %d; want %d\n", got, wantfd)
+					var args []string
+					switch runtime.GOOS {
+					case "plan9":
+						args = []string{fmt.Sprintf("/proc/%d/fd", os.Getpid())}
+					default:
+						args = []string{"-p", fmt.Sprint(os.Getpid())}
+					}
+					out, _ := exec.Command(ofcmd, args...).CombinedOutput()
+					fmt.Print(string(out))
+					os.Exit(1)
+				}
+				files = append(files, f)
+			}
+			for _, f := range files {
+				f.Close()
+			}
+		}
+		// Referring to fd3 here ensures that it is not
+		// garbage collected, and therefore closed, while
+		// executing the wantfd loop above.  It doesn't matter
+		// what we do with fd3 as long as we refer to it;
+		// closing it is the easy choice.
+		fd3.Close()
+		os.Stdout.Write(bs)
+	case "exit":
+		n, _ := strconv.Atoi(args[0])
+		os.Exit(n)
+	case "describefiles":
+		f := os.NewFile(3, fmt.Sprintf("fd3"))
+		ln, err := net.FileListener(f)
+		if err == nil {
+			fmt.Printf("fd3: listener %s\n", ln.Addr())
+			ln.Close()
+		}
+		os.Exit(0)
+	case "extraFilesAndPipes":
+		n, _ := strconv.Atoi(args[0])
+		pipes := make([]*os.File, n)
+		for i := 0; i < n; i++ {
+			pipes[i] = os.NewFile(uintptr(3+i), strconv.Itoa(i))
+		}
+		response := ""
+		for i, r := range pipes {
+			ch := make(chan string, 1)
+			go func(c chan string) {
+				buf := make([]byte, 10)
+				n, err := r.Read(buf)
+				if err != nil {
+					fmt.Fprintf(os.Stderr, "Child: read error: %v on pipe %d\n", err, i)
+					os.Exit(1)
+				}
+				c <- string(buf[:n])
+				close(c)
+			}(ch)
+			select {
+			case m := <-ch:
+				response = response + m
+			case <-time.After(5 * time.Second):
+				fmt.Fprintf(os.Stderr, "Child: Timeout reading from pipe: %d\n", i)
+				os.Exit(1)
+			}
+		}
+		fmt.Fprintf(os.Stderr, "child: %s", response)
+		os.Exit(0)
+	case "exec":
+		cmd := exec.Command(args[1])
+		cmd.Dir = args[0]
+		output, err := cmd.CombinedOutput()
+		if err != nil {
+			fmt.Fprintf(os.Stderr, "Child: %s %s", err, string(output))
+			os.Exit(1)
+		}
+		fmt.Printf("%s", string(output))
+		os.Exit(0)
+	case "lookpath":
+		p, err := exec.LookPath(args[0])
+		if err != nil {
+			fmt.Fprintf(os.Stderr, "LookPath failed: %v\n", err)
+			os.Exit(1)
+		}
+		fmt.Print(p)
+		os.Exit(0)
+	default:
+		fmt.Fprintf(os.Stderr, "Unknown command %q\n", cmd)
+		os.Exit(2)
+	}
+}
diff --git a/src/pkg/os/exec/lp_plan9.go b/src/os/exec/lp_plan9.go
similarity index 100%
rename from src/pkg/os/exec/lp_plan9.go
rename to src/os/exec/lp_plan9.go
diff --git a/src/pkg/os/exec/lp_test.go b/src/os/exec/lp_test.go
similarity index 100%
rename from src/pkg/os/exec/lp_test.go
rename to src/os/exec/lp_test.go
diff --git a/src/pkg/os/exec/lp_unix.go b/src/os/exec/lp_unix.go
similarity index 100%
rename from src/pkg/os/exec/lp_unix.go
rename to src/os/exec/lp_unix.go
diff --git a/src/pkg/os/exec/lp_unix_test.go b/src/os/exec/lp_unix_test.go
similarity index 100%
rename from src/pkg/os/exec/lp_unix_test.go
rename to src/os/exec/lp_unix_test.go
diff --git a/src/pkg/os/exec/lp_windows.go b/src/os/exec/lp_windows.go
similarity index 100%
rename from src/pkg/os/exec/lp_windows.go
rename to src/os/exec/lp_windows.go
diff --git a/src/pkg/os/exec/lp_windows_test.go b/src/os/exec/lp_windows_test.go
similarity index 100%
rename from src/pkg/os/exec/lp_windows_test.go
rename to src/os/exec/lp_windows_test.go
diff --git a/src/pkg/os/exec_plan9.go b/src/os/exec_plan9.go
similarity index 100%
rename from src/pkg/os/exec_plan9.go
rename to src/os/exec_plan9.go
diff --git a/src/pkg/os/exec_posix.go b/src/os/exec_posix.go
similarity index 100%
rename from src/pkg/os/exec_posix.go
rename to src/os/exec_posix.go
diff --git a/src/os/exec_unix.go b/src/os/exec_unix.go
new file mode 100644
index 0000000..ed97f85
--- /dev/null
+++ b/src/os/exec_unix.go
@@ -0,0 +1,81 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris
+
+package os
+
+import (
+	"errors"
+	"runtime"
+	"syscall"
+	"time"
+)
+
+func (p *Process) wait() (ps *ProcessState, err error) {
+	if p.Pid == -1 {
+		return nil, syscall.EINVAL
+	}
+	var status syscall.WaitStatus
+	var rusage syscall.Rusage
+	pid1, e := syscall.Wait4(p.Pid, &status, 0, &rusage)
+	if e != nil {
+		return nil, NewSyscallError("wait", e)
+	}
+	if pid1 != 0 {
+		p.setDone()
+	}
+	ps = &ProcessState{
+		pid:    pid1,
+		status: status,
+		rusage: &rusage,
+	}
+	return ps, nil
+}
+
+var errFinished = errors.New("os: process already finished")
+
+func (p *Process) signal(sig Signal) error {
+	if p.Pid == -1 {
+		return errors.New("os: process already released")
+	}
+	if p.Pid == 0 {
+		return errors.New("os: process not initialized")
+	}
+	if p.done() {
+		return errFinished
+	}
+	s, ok := sig.(syscall.Signal)
+	if !ok {
+		return errors.New("os: unsupported signal type")
+	}
+	if e := syscall.Kill(p.Pid, s); e != nil {
+		if e == syscall.ESRCH {
+			return errFinished
+		}
+		return e
+	}
+	return nil
+}
+
+func (p *Process) release() error {
+	// NOOP for unix.
+	p.Pid = -1
+	// no need for a finalizer anymore
+	runtime.SetFinalizer(p, nil)
+	return nil
+}
+
+func findProcess(pid int) (p *Process, err error) {
+	// NOOP for unix.
+	return newProcess(pid, 0), nil
+}
+
+func (p *ProcessState) userTime() time.Duration {
+	return time.Duration(p.rusage.Utime.Nano()) * time.Nanosecond
+}
+
+func (p *ProcessState) systemTime() time.Duration {
+	return time.Duration(p.rusage.Stime.Nano()) * time.Nanosecond
+}
diff --git a/src/os/exec_windows.go b/src/os/exec_windows.go
new file mode 100644
index 0000000..393393b
--- /dev/null
+++ b/src/os/exec_windows.go
@@ -0,0 +1,118 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package os
+
+import (
+	"errors"
+	"runtime"
+	"syscall"
+	"time"
+	"unsafe"
+)
+
+func (p *Process) wait() (ps *ProcessState, err error) {
+	s, e := syscall.WaitForSingleObject(syscall.Handle(p.handle), syscall.INFINITE)
+	switch s {
+	case syscall.WAIT_OBJECT_0:
+		break
+	case syscall.WAIT_FAILED:
+		return nil, NewSyscallError("WaitForSingleObject", e)
+	default:
+		return nil, errors.New("os: unexpected result from WaitForSingleObject")
+	}
+	var ec uint32
+	e = syscall.GetExitCodeProcess(syscall.Handle(p.handle), &ec)
+	if e != nil {
+		return nil, NewSyscallError("GetExitCodeProcess", e)
+	}
+	var u syscall.Rusage
+	e = syscall.GetProcessTimes(syscall.Handle(p.handle), &u.CreationTime, &u.ExitTime, &u.KernelTime, &u.UserTime)
+	if e != nil {
+		return nil, NewSyscallError("GetProcessTimes", e)
+	}
+	p.setDone()
+	// NOTE(brainman): It seems that sometimes process is not dead
+	// when WaitForSingleObject returns. But we do not know any
+	// other way to wait for it. Sleeping for a while seems to do
+	// the trick sometimes. So we will sleep and smell the roses.
+	defer time.Sleep(5 * time.Millisecond)
+	defer p.Release()
+	return &ProcessState{p.Pid, syscall.WaitStatus{ExitCode: ec}, &u}, nil
+}
+
+func terminateProcess(pid, exitcode int) error {
+	h, e := syscall.OpenProcess(syscall.PROCESS_TERMINATE, false, uint32(pid))
+	if e != nil {
+		return NewSyscallError("OpenProcess", e)
+	}
+	defer syscall.CloseHandle(h)
+	e = syscall.TerminateProcess(h, uint32(exitcode))
+	return NewSyscallError("TerminateProcess", e)
+}
+
+func (p *Process) signal(sig Signal) error {
+	if p.handle == uintptr(syscall.InvalidHandle) {
+		return syscall.EINVAL
+	}
+	if p.done() {
+		return errors.New("os: process already finished")
+	}
+	if sig == Kill {
+		return terminateProcess(p.Pid, 1)
+	}
+	// TODO(rsc): Handle Interrupt too?
+	return syscall.Errno(syscall.EWINDOWS)
+}
+
+func (p *Process) release() error {
+	if p.handle == uintptr(syscall.InvalidHandle) {
+		return syscall.EINVAL
+	}
+	e := syscall.CloseHandle(syscall.Handle(p.handle))
+	if e != nil {
+		return NewSyscallError("CloseHandle", e)
+	}
+	p.handle = uintptr(syscall.InvalidHandle)
+	// no need for a finalizer anymore
+	runtime.SetFinalizer(p, nil)
+	return nil
+}
+
+func findProcess(pid int) (p *Process, err error) {
+	const da = syscall.STANDARD_RIGHTS_READ |
+		syscall.PROCESS_QUERY_INFORMATION | syscall.SYNCHRONIZE
+	h, e := syscall.OpenProcess(da, false, uint32(pid))
+	if e != nil {
+		return nil, NewSyscallError("OpenProcess", e)
+	}
+	return newProcess(pid, uintptr(h)), nil
+}
+
+func init() {
+	var argc int32
+	cmd := syscall.GetCommandLine()
+	argv, e := syscall.CommandLineToArgv(cmd, &argc)
+	if e != nil {
+		return
+	}
+	defer syscall.LocalFree(syscall.Handle(uintptr(unsafe.Pointer(argv))))
+	Args = make([]string, argc)
+	for i, v := range (*argv)[:argc] {
+		Args[i] = string(syscall.UTF16ToString((*v)[:]))
+	}
+}
+
+func ftToDuration(ft *syscall.Filetime) time.Duration {
+	n := int64(ft.HighDateTime)<<32 + int64(ft.LowDateTime) // in 100-nanosecond intervals
+	return time.Duration(n*100) * time.Nanosecond
+}
+
+func (p *ProcessState) userTime() time.Duration {
+	return ftToDuration(&p.rusage.UserTime)
+}
+
+func (p *ProcessState) systemTime() time.Duration {
+	return ftToDuration(&p.rusage.KernelTime)
+}
diff --git a/src/pkg/os/export_test.go b/src/os/export_test.go
similarity index 100%
rename from src/pkg/os/export_test.go
rename to src/os/export_test.go
diff --git a/src/os/file.go b/src/os/file.go
new file mode 100644
index 0000000..e12428c
--- /dev/null
+++ b/src/os/file.go
@@ -0,0 +1,266 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package os provides a platform-independent interface to operating system
+// functionality. The design is Unix-like, although the error handling is
+// Go-like; failing calls return values of type error rather than error numbers.
+// Often, more information is available within the error. For example,
+// if a call that takes a file name fails, such as Open or Stat, the error
+// will include the failing file name when printed and will be of type
+// *PathError, which may be unpacked for more information.
+//
+// The os interface is intended to be uniform across all operating systems.
+// Features not generally available appear in the system-specific package syscall.
+//
+// Here is a simple example, opening a file and reading some of it.
+//
+//	file, err := os.Open("file.go") // For read access.
+//	if err != nil {
+//		log.Fatal(err)
+//	}
+//
+// If the open fails, the error string will be self-explanatory, like
+//
+//	open file.go: no such file or directory
+//
+// The file's data can then be read into a slice of bytes. Read and
+// Write take their byte counts from the length of the argument slice.
+//
+//	data := make([]byte, 100)
+//	count, err := file.Read(data)
+//	if err != nil {
+//		log.Fatal(err)
+//	}
+//	fmt.Printf("read %d bytes: %q\n", count, data[:count])
+//
+package os
+
+import (
+	"io"
+	"syscall"
+)
+
+// Name returns the name of the file as presented to Open.
+func (f *File) Name() string { return f.name }
+
+// Stdin, Stdout, and Stderr are open Files pointing to the standard input,
+// standard output, and standard error file descriptors.
+var (
+	Stdin  = NewFile(uintptr(syscall.Stdin), "/dev/stdin")
+	Stdout = NewFile(uintptr(syscall.Stdout), "/dev/stdout")
+	Stderr = NewFile(uintptr(syscall.Stderr), "/dev/stderr")
+)
+
+// Flags to Open wrapping those of the underlying system. Not all flags
+// may be implemented on a given system.
+const (
+	O_RDONLY int = syscall.O_RDONLY // open the file read-only.
+	O_WRONLY int = syscall.O_WRONLY // open the file write-only.
+	O_RDWR   int = syscall.O_RDWR   // open the file read-write.
+	O_APPEND int = syscall.O_APPEND // append data to the file when writing.
+	O_CREATE int = syscall.O_CREAT  // create a new file if none exists.
+	O_EXCL   int = syscall.O_EXCL   // used with O_CREATE, file must not exist
+	O_SYNC   int = syscall.O_SYNC   // open for synchronous I/O.
+	O_TRUNC  int = syscall.O_TRUNC  // if possible, truncate file when opened.
+)
+
+// Seek whence values.
+const (
+	SEEK_SET int = 0 // seek relative to the origin of the file
+	SEEK_CUR int = 1 // seek relative to the current offset
+	SEEK_END int = 2 // seek relative to the end
+)
+
+// LinkError records an error during a link or symlink or rename
+// system call and the paths that caused it.
+type LinkError struct {
+	Op  string
+	Old string
+	New string
+	Err error
+}
+
+func (e *LinkError) Error() string {
+	return e.Op + " " + e.Old + " " + e.New + ": " + e.Err.Error()
+}
+
+// Read reads up to len(b) bytes from the File.
+// It returns the number of bytes read and an error, if any.
+// EOF is signaled by a zero count with err set to io.EOF.
+func (f *File) Read(b []byte) (n int, err error) {
+	if f == nil {
+		return 0, ErrInvalid
+	}
+	n, e := f.read(b)
+	if n < 0 {
+		n = 0
+	}
+	if n == 0 && len(b) > 0 && e == nil {
+		return 0, io.EOF
+	}
+	if e != nil {
+		err = &PathError{"read", f.name, e}
+	}
+	return n, err
+}
+
+// ReadAt reads len(b) bytes from the File starting at byte offset off.
+// It returns the number of bytes read and the error, if any.
+// ReadAt always returns a non-nil error when n < len(b).
+// At end of file, that error is io.EOF.
+func (f *File) ReadAt(b []byte, off int64) (n int, err error) {
+	if f == nil {
+		return 0, ErrInvalid
+	}
+	for len(b) > 0 {
+		m, e := f.pread(b, off)
+		if m == 0 && e == nil {
+			return n, io.EOF
+		}
+		if e != nil {
+			err = &PathError{"read", f.name, e}
+			break
+		}
+		n += m
+		b = b[m:]
+		off += int64(m)
+	}
+	return
+}
+
+// Write writes len(b) bytes to the File.
+// It returns the number of bytes written and an error, if any.
+// Write returns a non-nil error when n != len(b).
+func (f *File) Write(b []byte) (n int, err error) {
+	if f == nil {
+		return 0, ErrInvalid
+	}
+	n, e := f.write(b)
+	if n < 0 {
+		n = 0
+	}
+	if n != len(b) {
+		err = io.ErrShortWrite
+	}
+
+	epipecheck(f, e)
+
+	if e != nil {
+		err = &PathError{"write", f.name, e}
+	}
+	return n, err
+}
+
+// WriteAt writes len(b) bytes to the File starting at byte offset off.
+// It returns the number of bytes written and an error, if any.
+// WriteAt returns a non-nil error when n != len(b).
+func (f *File) WriteAt(b []byte, off int64) (n int, err error) {
+	if f == nil {
+		return 0, ErrInvalid
+	}
+	for len(b) > 0 {
+		m, e := f.pwrite(b, off)
+		if e != nil {
+			err = &PathError{"write", f.name, e}
+			break
+		}
+		n += m
+		b = b[m:]
+		off += int64(m)
+	}
+	return
+}
+
+// Seek sets the offset for the next Read or Write on file to offset, interpreted
+// according to whence: 0 means relative to the origin of the file, 1 means
+// relative to the current offset, and 2 means relative to the end.
+// It returns the new offset and an error, if any.
+func (f *File) Seek(offset int64, whence int) (ret int64, err error) {
+	if f == nil {
+		return 0, ErrInvalid
+	}
+	r, e := f.seek(offset, whence)
+	if e == nil && f.dirinfo != nil && r != 0 {
+		e = syscall.EISDIR
+	}
+	if e != nil {
+		return 0, &PathError{"seek", f.name, e}
+	}
+	return r, nil
+}
+
+// WriteString is like Write, but writes the contents of string s rather than
+// a slice of bytes.
+func (f *File) WriteString(s string) (ret int, err error) {
+	if f == nil {
+		return 0, ErrInvalid
+	}
+	return f.Write([]byte(s))
+}
+
+// Mkdir creates a new directory with the specified name and permission bits.
+// If there is an error, it will be of type *PathError.
+func Mkdir(name string, perm FileMode) error {
+	e := syscall.Mkdir(name, syscallMode(perm))
+	if e != nil {
+		return &PathError{"mkdir", name, e}
+	}
+	return nil
+}
+
+// Chdir changes the current working directory to the named directory.
+// If there is an error, it will be of type *PathError.
+func Chdir(dir string) error {
+	if e := syscall.Chdir(dir); e != nil {
+		return &PathError{"chdir", dir, e}
+	}
+	return nil
+}
+
+// Chdir changes the current working directory to the file,
+// which must be a directory.
+// If there is an error, it will be of type *PathError.
+func (f *File) Chdir() error {
+	if f == nil {
+		return ErrInvalid
+	}
+	if e := syscall.Fchdir(f.fd); e != nil {
+		return &PathError{"chdir", f.name, e}
+	}
+	return nil
+}
+
+// Open opens the named file for reading.  If successful, methods on
+// the returned file can be used for reading; the associated file
+// descriptor has mode O_RDONLY.
+// If there is an error, it will be of type *PathError.
+func Open(name string) (file *File, err error) {
+	return OpenFile(name, O_RDONLY, 0)
+}
+
+// Create creates the named file mode 0666 (before umask), truncating
+// it if it already exists.  If successful, methods on the returned
+// File can be used for I/O; the associated file descriptor has mode
+// O_RDWR.
+// If there is an error, it will be of type *PathError.
+func Create(name string) (file *File, err error) {
+	return OpenFile(name, O_RDWR|O_CREATE|O_TRUNC, 0666)
+}
+
+// lstat is overridden in tests.
+var lstat = Lstat
+
+// Rename renames (moves) a file. OS-specific restrictions might apply.
+func Rename(oldpath, newpath string) error {
+	return rename(oldpath, newpath)
+}
+
+// Many functions in package syscall return a count of -1 instead of 0.
+// Using fixCount(call()) instead of call() corrects the count.
+func fixCount(n int, err error) (int, error) {
+	if n < 0 {
+		n = 0
+	}
+	return n, err
+}
diff --git a/src/os/file_plan9.go b/src/os/file_plan9.go
new file mode 100644
index 0000000..132594e
--- /dev/null
+++ b/src/os/file_plan9.go
@@ -0,0 +1,469 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package os
+
+import (
+	"runtime"
+	"syscall"
+	"time"
+)
+
+// File represents an open file descriptor.
+type File struct {
+	*file
+}
+
+// file is the real representation of *File.
+// The extra level of indirection ensures that no clients of os
+// can overwrite this data, which could cause the finalizer
+// to close the wrong file descriptor.
+type file struct {
+	fd      int
+	name    string
+	dirinfo *dirInfo // nil unless directory being read
+}
+
+// Fd returns the integer Plan 9 file descriptor referencing the open file.
+// The file descriptor is valid only until f.Close is called or f is garbage collected.
+func (f *File) Fd() uintptr {
+	if f == nil {
+		return ^(uintptr(0))
+	}
+	return uintptr(f.fd)
+}
+
+// NewFile returns a new File with the given file descriptor and name.
+func NewFile(fd uintptr, name string) *File {
+	fdi := int(fd)
+	if fdi < 0 {
+		return nil
+	}
+	f := &File{&file{fd: fdi, name: name}}
+	runtime.SetFinalizer(f.file, (*file).close)
+	return f
+}
+
+// Auxiliary information if the File describes a directory
+type dirInfo struct {
+	buf  [syscall.STATMAX]byte // buffer for directory I/O
+	nbuf int                   // length of buf; return value from Read
+	bufp int                   // location of next record in buf.
+}
+
+func epipecheck(file *File, e error) {
+}
+
+// DevNull is the name of the operating system's ``null device.''
+// On Unix-like systems, it is "/dev/null"; on Windows, "NUL".
+const DevNull = "/dev/null"
+
+// syscallMode returns the syscall-specific mode bits from Go's portable mode bits.
+func syscallMode(i FileMode) (o uint32) {
+	o |= uint32(i.Perm())
+	if i&ModeAppend != 0 {
+		o |= syscall.DMAPPEND
+	}
+	if i&ModeExclusive != 0 {
+		o |= syscall.DMEXCL
+	}
+	if i&ModeTemporary != 0 {
+		o |= syscall.DMTMP
+	}
+	return
+}
+
+// OpenFile is the generalized open call; most users will use Open
+// or Create instead.  It opens the named file with specified flag
+// (O_RDONLY etc.) and perm, (0666 etc.) if applicable.  If successful,
+// methods on the returned File can be used for I/O.
+// If there is an error, it will be of type *PathError.
+func OpenFile(name string, flag int, perm FileMode) (file *File, err error) {
+	var (
+		fd     int
+		e      error
+		create bool
+		excl   bool
+		trunc  bool
+		append bool
+	)
+
+	if flag&O_CREATE == O_CREATE {
+		flag = flag & ^O_CREATE
+		create = true
+	}
+	if flag&O_EXCL == O_EXCL {
+		excl = true
+	}
+	if flag&O_TRUNC == O_TRUNC {
+		trunc = true
+	}
+	// O_APPEND is emulated on Plan 9
+	if flag&O_APPEND == O_APPEND {
+		flag = flag &^ O_APPEND
+		append = true
+	}
+
+	if (create && trunc) || excl {
+		fd, e = syscall.Create(name, flag, syscallMode(perm))
+	} else {
+		fd, e = syscall.Open(name, flag)
+		if e != nil && create {
+			var e1 error
+			fd, e1 = syscall.Create(name, flag, syscallMode(perm))
+			if e1 == nil {
+				e = nil
+			}
+		}
+	}
+
+	if e != nil {
+		return nil, &PathError{"open", name, e}
+	}
+
+	if append {
+		if _, e = syscall.Seek(fd, 0, SEEK_END); e != nil {
+			return nil, &PathError{"seek", name, e}
+		}
+	}
+
+	return NewFile(uintptr(fd), name), nil
+}
+
+// Close closes the File, rendering it unusable for I/O.
+// It returns an error, if any.
+func (f *File) Close() error {
+	if f == nil {
+		return ErrInvalid
+	}
+	return f.file.close()
+}
+
+func (file *file) close() error {
+	if file == nil || file.fd < 0 {
+		return ErrInvalid
+	}
+	var err error
+	syscall.ForkLock.RLock()
+	if e := syscall.Close(file.fd); e != nil {
+		err = &PathError{"close", file.name, e}
+	}
+	syscall.ForkLock.RUnlock()
+	file.fd = -1 // so it can't be closed again
+
+	// no need for a finalizer anymore
+	runtime.SetFinalizer(file, nil)
+	return err
+}
+
+// Stat returns the FileInfo structure describing file.
+// If there is an error, it will be of type *PathError.
+func (f *File) Stat() (fi FileInfo, err error) {
+	if f == nil {
+		return nil, ErrInvalid
+	}
+	d, err := dirstat(f)
+	if err != nil {
+		return nil, err
+	}
+	return fileInfoFromStat(d), nil
+}
+
+// Truncate changes the size of the file.
+// It does not change the I/O offset.
+// If there is an error, it will be of type *PathError.
+func (f *File) Truncate(size int64) error {
+	if f == nil {
+		return ErrInvalid
+	}
+
+	var d syscall.Dir
+	d.Null()
+	d.Length = size
+
+	var buf [syscall.STATFIXLEN]byte
+	n, err := d.Marshal(buf[:])
+	if err != nil {
+		return &PathError{"truncate", f.name, err}
+	}
+	if err = syscall.Fwstat(f.fd, buf[:n]); err != nil {
+		return &PathError{"truncate", f.name, err}
+	}
+	return nil
+}
+
+const chmodMask = uint32(syscall.DMAPPEND | syscall.DMEXCL | syscall.DMTMP | ModePerm)
+
+// Chmod changes the mode of the file to mode.
+// If there is an error, it will be of type *PathError.
+func (f *File) Chmod(mode FileMode) error {
+	if f == nil {
+		return ErrInvalid
+	}
+	var d syscall.Dir
+
+	odir, e := dirstat(f)
+	if e != nil {
+		return &PathError{"chmod", f.name, e}
+	}
+	d.Null()
+	d.Mode = odir.Mode&^chmodMask | syscallMode(mode)&chmodMask
+
+	var buf [syscall.STATFIXLEN]byte
+	n, err := d.Marshal(buf[:])
+	if err != nil {
+		return &PathError{"chmod", f.name, err}
+	}
+	if err = syscall.Fwstat(f.fd, buf[:n]); err != nil {
+		return &PathError{"chmod", f.name, err}
+	}
+	return nil
+}
+
+// Sync commits the current contents of the file to stable storage.
+// Typically, this means flushing the file system's in-memory copy
+// of recently written data to disk.
+func (f *File) Sync() (err error) {
+	if f == nil {
+		return ErrInvalid
+	}
+	var d syscall.Dir
+	d.Null()
+
+	var buf [syscall.STATFIXLEN]byte
+	n, err := d.Marshal(buf[:])
+	if err != nil {
+		return NewSyscallError("fsync", err)
+	}
+	if err = syscall.Fwstat(f.fd, buf[:n]); err != nil {
+		return NewSyscallError("fsync", err)
+	}
+	return nil
+}
+
+// read reads up to len(b) bytes from the File.
+// It returns the number of bytes read and an error, if any.
+func (f *File) read(b []byte) (n int, err error) {
+	return fixCount(syscall.Read(f.fd, b))
+}
+
+// pread reads len(b) bytes from the File starting at byte offset off.
+// It returns the number of bytes read and the error, if any.
+// EOF is signaled by a zero count with err set to nil.
+func (f *File) pread(b []byte, off int64) (n int, err error) {
+	return fixCount(syscall.Pread(f.fd, b, off))
+}
+
+// write writes len(b) bytes to the File.
+// It returns the number of bytes written and an error, if any.
+// Since Plan 9 preserves message boundaries, never allow
+// a zero-byte write.
+func (f *File) write(b []byte) (n int, err error) {
+	if len(b) == 0 {
+		return 0, nil
+	}
+	return fixCount(syscall.Write(f.fd, b))
+}
+
+// pwrite writes len(b) bytes to the File starting at byte offset off.
+// It returns the number of bytes written and an error, if any.
+// Since Plan 9 preserves message boundaries, never allow
+// a zero-byte write.
+func (f *File) pwrite(b []byte, off int64) (n int, err error) {
+	if len(b) == 0 {
+		return 0, nil
+	}
+	return fixCount(syscall.Pwrite(f.fd, b, off))
+}
+
+// seek sets the offset for the next Read or Write on file to offset, interpreted
+// according to whence: 0 means relative to the origin of the file, 1 means
+// relative to the current offset, and 2 means relative to the end.
+// It returns the new offset and an error, if any.
+func (f *File) seek(offset int64, whence int) (ret int64, err error) {
+	return syscall.Seek(f.fd, offset, whence)
+}
+
+// Truncate changes the size of the named file.
+// If the file is a symbolic link, it changes the size of the link's target.
+// If there is an error, it will be of type *PathError.
+func Truncate(name string, size int64) error {
+	var d syscall.Dir
+
+	d.Null()
+	d.Length = size
+
+	var buf [syscall.STATFIXLEN]byte
+	n, err := d.Marshal(buf[:])
+	if err != nil {
+		return &PathError{"truncate", name, err}
+	}
+	if err = syscall.Wstat(name, buf[:n]); err != nil {
+		return &PathError{"truncate", name, err}
+	}
+	return nil
+}
+
+// Remove removes the named file or directory.
+// If there is an error, it will be of type *PathError.
+func Remove(name string) error {
+	if e := syscall.Remove(name); e != nil {
+		return &PathError{"remove", name, e}
+	}
+	return nil
+}
+
+// HasPrefix from the strings package.
+func hasPrefix(s, prefix string) bool {
+	return len(s) >= len(prefix) && s[0:len(prefix)] == prefix
+}
+
+// Variant of LastIndex from the strings package.
+func lastIndex(s string, sep byte) int {
+	for i := len(s) - 1; i >= 0; i-- {
+		if s[i] == sep {
+			return i
+		}
+	}
+	return -1
+}
+
+func rename(oldname, newname string) error {
+	dirname := oldname[:lastIndex(oldname, '/')+1]
+	if hasPrefix(newname, dirname) {
+		newname = newname[len(dirname):]
+	} else {
+		return &LinkError{"rename", oldname, newname, ErrInvalid}
+	}
+
+	// If newname still contains slashes after removing the oldname
+	// prefix, the rename is cross-directory and must be rejected.
+	// This case is caught by d.Marshal below.
+
+	var d syscall.Dir
+
+	d.Null()
+	d.Name = newname
+
+	buf := make([]byte, syscall.STATFIXLEN+len(d.Name))
+	n, err := d.Marshal(buf[:])
+	if err != nil {
+		return &LinkError{"rename", oldname, newname, err}
+	}
+	if err = syscall.Wstat(oldname, buf[:n]); err != nil {
+		return &LinkError{"rename", oldname, newname, err}
+	}
+	return nil
+}
+
+// Chmod changes the mode of the named file to mode.
+// If the file is a symbolic link, it changes the mode of the link's target.
+// If there is an error, it will be of type *PathError.
+func Chmod(name string, mode FileMode) error {
+	var d syscall.Dir
+
+	odir, e := dirstat(name)
+	if e != nil {
+		return &PathError{"chmod", name, e}
+	}
+	d.Null()
+	d.Mode = odir.Mode&^chmodMask | syscallMode(mode)&chmodMask
+
+	var buf [syscall.STATFIXLEN]byte
+	n, err := d.Marshal(buf[:])
+	if err != nil {
+		return &PathError{"chmod", name, err}
+	}
+	if err = syscall.Wstat(name, buf[:n]); err != nil {
+		return &PathError{"chmod", name, err}
+	}
+	return nil
+}
+
+// Chtimes changes the access and modification times of the named
+// file, similar to the Unix utime() or utimes() functions.
+//
+// The underlying filesystem may truncate or round the values to a
+// less precise time unit.
+// If there is an error, it will be of type *PathError.
+func Chtimes(name string, atime time.Time, mtime time.Time) error {
+	var d syscall.Dir
+
+	d.Null()
+	d.Atime = uint32(atime.Unix())
+	d.Mtime = uint32(mtime.Unix())
+
+	var buf [syscall.STATFIXLEN]byte
+	n, err := d.Marshal(buf[:])
+	if err != nil {
+		return &PathError{"chtimes", name, err}
+	}
+	if err = syscall.Wstat(name, buf[:n]); err != nil {
+		return &PathError{"chtimes", name, err}
+	}
+	return nil
+}
+
+// Pipe returns a connected pair of Files; reads from r return bytes
+// written to w. It returns the files and an error, if any.
+func Pipe() (r *File, w *File, err error) {
+	var p [2]int
+
+	syscall.ForkLock.RLock()
+	if e := syscall.Pipe(p[0:]); e != nil {
+		syscall.ForkLock.RUnlock()
+		return nil, nil, NewSyscallError("pipe", e)
+	}
+	syscall.ForkLock.RUnlock()
+
+	return NewFile(uintptr(p[0]), "|0"), NewFile(uintptr(p[1]), "|1"), nil
+}
+
+// not supported on Plan 9
+
+// Link creates newname as a hard link to the oldname file.
+// If there is an error, it will be of type *LinkError.
+func Link(oldname, newname string) error {
+	return &LinkError{"link", oldname, newname, syscall.EPLAN9}
+}
+
+// Symlink creates newname as a symbolic link to oldname.
+// If there is an error, it will be of type *LinkError.
+func Symlink(oldname, newname string) error {
+	return &LinkError{"symlink", oldname, newname, syscall.EPLAN9}
+}
+
+// Readlink returns the destination of the named symbolic link.
+// If there is an error, it will be of type *PathError.
+func Readlink(name string) (string, error) {
+	return "", &PathError{"readlink", name, syscall.EPLAN9}
+}
+
+// Chown changes the numeric uid and gid of the named file.
+// If the file is a symbolic link, it changes the uid and gid of the link's target.
+// If there is an error, it will be of type *PathError.
+func Chown(name string, uid, gid int) error {
+	return &PathError{"chown", name, syscall.EPLAN9}
+}
+
+// Lchown changes the numeric uid and gid of the named file.
+// If the file is a symbolic link, it changes the uid and gid of the link itself.
+// If there is an error, it will be of type *PathError.
+func Lchown(name string, uid, gid int) error {
+	return &PathError{"lchown", name, syscall.EPLAN9}
+}
+
+// Chown changes the numeric uid and gid of the named file.
+// If there is an error, it will be of type *PathError.
+func (f *File) Chown(uid, gid int) error {
+	if f == nil {
+		return ErrInvalid
+	}
+	return &PathError{"chown", f.name, syscall.EPLAN9}
+}
+
+// TempDir returns the default directory to use for temporary files.
+func TempDir() string {
+	return "/tmp"
+}
diff --git a/src/os/file_posix.go b/src/os/file_posix.go
new file mode 100644
index 0000000..fbb3b5e
--- /dev/null
+++ b/src/os/file_posix.go
@@ -0,0 +1,149 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris windows
+
+package os
+
+import (
+	"syscall"
+	"time"
+)
+
+func sigpipe() // implemented in package runtime
+
+// Readlink returns the destination of the named symbolic link.
+// If there is an error, it will be of type *PathError.
+func Readlink(name string) (string, error) {
+	for len := 128; ; len *= 2 {
+		b := make([]byte, len)
+		n, e := fixCount(syscall.Readlink(name, b))
+		if e != nil {
+			return "", &PathError{"readlink", name, e}
+		}
+		if n < len {
+			return string(b[0:n]), nil
+		}
+	}
+}
+
+func rename(oldname, newname string) error {
+	e := syscall.Rename(oldname, newname)
+	if e != nil {
+		return &LinkError{"rename", oldname, newname, e}
+	}
+	return nil
+}
+
+// syscallMode returns the syscall-specific mode bits from Go's portable mode bits.
+func syscallMode(i FileMode) (o uint32) {
+	o |= uint32(i.Perm())
+	if i&ModeSetuid != 0 {
+		o |= syscall.S_ISUID
+	}
+	if i&ModeSetgid != 0 {
+		o |= syscall.S_ISGID
+	}
+	if i&ModeSticky != 0 {
+		o |= syscall.S_ISVTX
+	}
+	// No mapping for Go's ModeTemporary (plan9 only).
+	return
+}
+
+// Chmod changes the mode of the named file to mode.
+// If the file is a symbolic link, it changes the mode of the link's target.
+// If there is an error, it will be of type *PathError.
+func Chmod(name string, mode FileMode) error {
+	if e := syscall.Chmod(name, syscallMode(mode)); e != nil {
+		return &PathError{"chmod", name, e}
+	}
+	return nil
+}
+
+// Chmod changes the mode of the file to mode.
+// If there is an error, it will be of type *PathError.
+func (f *File) Chmod(mode FileMode) error {
+	if f == nil {
+		return ErrInvalid
+	}
+	if e := syscall.Fchmod(f.fd, syscallMode(mode)); e != nil {
+		return &PathError{"chmod", f.name, e}
+	}
+	return nil
+}
+
+// Chown changes the numeric uid and gid of the named file.
+// If the file is a symbolic link, it changes the uid and gid of the link's target.
+// If there is an error, it will be of type *PathError.
+func Chown(name string, uid, gid int) error {
+	if e := syscall.Chown(name, uid, gid); e != nil {
+		return &PathError{"chown", name, e}
+	}
+	return nil
+}
+
+// Lchown changes the numeric uid and gid of the named file.
+// If the file is a symbolic link, it changes the uid and gid of the link itself.
+// If there is an error, it will be of type *PathError.
+func Lchown(name string, uid, gid int) error {
+	if e := syscall.Lchown(name, uid, gid); e != nil {
+		return &PathError{"lchown", name, e}
+	}
+	return nil
+}
+
+// Chown changes the numeric uid and gid of the named file.
+// If there is an error, it will be of type *PathError.
+func (f *File) Chown(uid, gid int) error {
+	if f == nil {
+		return ErrInvalid
+	}
+	if e := syscall.Fchown(f.fd, uid, gid); e != nil {
+		return &PathError{"chown", f.name, e}
+	}
+	return nil
+}
+
+// Truncate changes the size of the file.
+// It does not change the I/O offset.
+// If there is an error, it will be of type *PathError.
+func (f *File) Truncate(size int64) error {
+	if f == nil {
+		return ErrInvalid
+	}
+	if e := syscall.Ftruncate(f.fd, size); e != nil {
+		return &PathError{"truncate", f.name, e}
+	}
+	return nil
+}
+
+// Sync commits the current contents of the file to stable storage.
+// Typically, this means flushing the file system's in-memory copy
+// of recently written data to disk.
+func (f *File) Sync() (err error) {
+	if f == nil {
+		return ErrInvalid
+	}
+	if e := syscall.Fsync(f.fd); e != nil {
+		return NewSyscallError("fsync", e)
+	}
+	return nil
+}
+
+// Chtimes changes the access and modification times of the named
+// file, similar to the Unix utime() or utimes() functions.
+//
+// The underlying filesystem may truncate or round the values to a
+// less precise time unit.
+// If there is an error, it will be of type *PathError.
+func Chtimes(name string, atime time.Time, mtime time.Time) error {
+	var utimes [2]syscall.Timespec
+	utimes[0] = syscall.NsecToTimespec(atime.UnixNano())
+	utimes[1] = syscall.NsecToTimespec(mtime.UnixNano())
+	if e := syscall.UtimesNano(name, utimes[0:]); e != nil {
+		return &PathError{"chtimes", name, e}
+	}
+	return nil
+}
diff --git a/src/os/file_unix.go b/src/os/file_unix.go
new file mode 100644
index 0000000..ff4fc7d
--- /dev/null
+++ b/src/os/file_unix.go
@@ -0,0 +1,339 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris
+
+package os
+
+import (
+	"runtime"
+	"sync/atomic"
+	"syscall"
+)
+
+// File represents an open file descriptor.
+type File struct {
+	*file
+}
+
+// file is the real representation of *File.
+// The extra level of indirection ensures that no clients of os
+// can overwrite this data, which could cause the finalizer
+// to close the wrong file descriptor.
+type file struct {
+	fd      int
+	name    string
+	dirinfo *dirInfo // nil unless directory being read
+	nepipe  int32    // number of consecutive EPIPE in Write
+}
+
+// Fd returns the integer Unix file descriptor referencing the open file.
+// The file descriptor is valid only until f.Close is called or f is garbage collected.
+func (f *File) Fd() uintptr {
+	if f == nil {
+		return ^(uintptr(0))
+	}
+	return uintptr(f.fd)
+}
+
+// NewFile returns a new File with the given file descriptor and name.
+func NewFile(fd uintptr, name string) *File {
+	fdi := int(fd)
+	if fdi < 0 {
+		return nil
+	}
+	f := &File{&file{fd: fdi, name: name}}
+	runtime.SetFinalizer(f.file, (*file).close)
+	return f
+}
+
+// Auxiliary information if the File describes a directory
+type dirInfo struct {
+	buf  []byte // buffer for directory I/O
+	nbuf int    // length of buf; return value from Getdirentries
+	bufp int    // location of next record in buf.
+}
+
+func epipecheck(file *File, e error) {
+	if e == syscall.EPIPE {
+		if atomic.AddInt32(&file.nepipe, 1) >= 10 {
+			sigpipe()
+		}
+	} else {
+		atomic.StoreInt32(&file.nepipe, 0)
+	}
+}
+
+// DevNull is the name of the operating system's ``null device.''
+// On Unix-like systems, it is "/dev/null"; on Windows, "NUL".
+const DevNull = "/dev/null"
+
+// OpenFile is the generalized open call; most users will use Open
+// or Create instead.  It opens the named file with specified flag
+// (O_RDONLY etc.) and perm, (0666 etc.) if applicable.  If successful,
+// methods on the returned File can be used for I/O.
+// If there is an error, it will be of type *PathError.
+func OpenFile(name string, flag int, perm FileMode) (file *File, err error) {
+	r, e := syscall.Open(name, flag|syscall.O_CLOEXEC, syscallMode(perm))
+	if e != nil {
+		return nil, &PathError{"open", name, e}
+	}
+
+	// There's a race here with fork/exec, which we are
+	// content to live with.  See ../syscall/exec_unix.go.
+	if !supportsCloseOnExec {
+		syscall.CloseOnExec(r)
+	}
+
+	return NewFile(uintptr(r), name), nil
+}
+
+// Close closes the File, rendering it unusable for I/O.
+// It returns an error, if any.
+func (f *File) Close() error {
+	if f == nil {
+		return ErrInvalid
+	}
+	return f.file.close()
+}
+
+func (file *file) close() error {
+	if file == nil || file.fd < 0 {
+		return syscall.EINVAL
+	}
+	var err error
+	if e := syscall.Close(file.fd); e != nil {
+		err = &PathError{"close", file.name, e}
+	}
+	file.fd = -1 // so it can't be closed again
+
+	// no need for a finalizer anymore
+	runtime.SetFinalizer(file, nil)
+	return err
+}
+
+// Stat returns the FileInfo structure describing file.
+// If there is an error, it will be of type *PathError.
+func (f *File) Stat() (fi FileInfo, err error) {
+	if f == nil {
+		return nil, ErrInvalid
+	}
+	var stat syscall.Stat_t
+	err = syscall.Fstat(f.fd, &stat)
+	if err != nil {
+		return nil, &PathError{"stat", f.name, err}
+	}
+	return fileInfoFromStat(&stat, f.name), nil
+}
+
+// Stat returns a FileInfo describing the named file.
+// If there is an error, it will be of type *PathError.
+func Stat(name string) (fi FileInfo, err error) {
+	var stat syscall.Stat_t
+	err = syscall.Stat(name, &stat)
+	if err != nil {
+		return nil, &PathError{"stat", name, err}
+	}
+	return fileInfoFromStat(&stat, name), nil
+}
+
+// Lstat returns a FileInfo describing the named file.
+// If the file is a symbolic link, the returned FileInfo
+// describes the symbolic link.  Lstat makes no attempt to follow the link.
+// If there is an error, it will be of type *PathError.
+func Lstat(name string) (fi FileInfo, err error) {
+	var stat syscall.Stat_t
+	err = syscall.Lstat(name, &stat)
+	if err != nil {
+		return nil, &PathError{"lstat", name, err}
+	}
+	return fileInfoFromStat(&stat, name), nil
+}
+
+func (f *File) readdir(n int) (fi []FileInfo, err error) {
+	dirname := f.name
+	if dirname == "" {
+		dirname = "."
+	}
+	names, err := f.Readdirnames(n)
+	fi = make([]FileInfo, 0, len(names))
+	for _, filename := range names {
+		fip, lerr := lstat(dirname + "/" + filename)
+		if IsNotExist(lerr) {
+			// File disappeared between readdir + stat.
+			// Just treat it as if it didn't exist.
+			continue
+		}
+		if lerr != nil {
+			return fi, lerr
+		}
+		fi = append(fi, fip)
+	}
+	return fi, err
+}
+
+// Darwin and FreeBSD can't read or write 2GB+ at a time,
+// even on 64-bit systems. See golang.org/issue/7812.
+// Use 1GB instead of, say, 2GB-1, to keep subsequent
+// reads aligned.
+const (
+	needsMaxRW = runtime.GOOS == "darwin" || runtime.GOOS == "freebsd"
+	maxRW      = 1 << 30
+)
+
+// read reads up to len(b) bytes from the File.
+// It returns the number of bytes read and an error, if any.
+func (f *File) read(b []byte) (n int, err error) {
+	if needsMaxRW && len(b) > maxRW {
+		b = b[:maxRW]
+	}
+	return fixCount(syscall.Read(f.fd, b))
+}
+
+// pread reads len(b) bytes from the File starting at byte offset off.
+// It returns the number of bytes read and the error, if any.
+// EOF is signaled by a zero count with err set to nil.
+func (f *File) pread(b []byte, off int64) (n int, err error) {
+	if needsMaxRW && len(b) > maxRW {
+		b = b[:maxRW]
+	}
+	return fixCount(syscall.Pread(f.fd, b, off))
+}
+
+// write writes len(b) bytes to the File.
+// It returns the number of bytes written and an error, if any.
+func (f *File) write(b []byte) (n int, err error) {
+	for {
+		bcap := b
+		if needsMaxRW && len(bcap) > maxRW {
+			bcap = bcap[:maxRW]
+		}
+		m, err := fixCount(syscall.Write(f.fd, bcap))
+		n += m
+
+		// If the syscall wrote some data but not all (short write)
+		// or it returned EINTR, then assume it stopped early for
+		// reasons that are uninteresting to the caller, and try again.
+		if 0 < m && m < len(bcap) || err == syscall.EINTR {
+			b = b[m:]
+			continue
+		}
+
+		if needsMaxRW && len(bcap) != len(b) && err == nil {
+			b = b[m:]
+			continue
+		}
+
+		return n, err
+	}
+}
+
+// pwrite writes len(b) bytes to the File starting at byte offset off.
+// It returns the number of bytes written and an error, if any.
+func (f *File) pwrite(b []byte, off int64) (n int, err error) {
+	if needsMaxRW && len(b) > maxRW {
+		b = b[:maxRW]
+	}
+	return fixCount(syscall.Pwrite(f.fd, b, off))
+}
+
+// seek sets the offset for the next Read or Write on file to offset, interpreted
+// according to whence: 0 means relative to the origin of the file, 1 means
+// relative to the current offset, and 2 means relative to the end.
+// It returns the new offset and an error, if any.
+func (f *File) seek(offset int64, whence int) (ret int64, err error) {
+	return syscall.Seek(f.fd, offset, whence)
+}
+
+// Truncate changes the size of the named file.
+// If the file is a symbolic link, it changes the size of the link's target.
+// If there is an error, it will be of type *PathError.
+func Truncate(name string, size int64) error {
+	if e := syscall.Truncate(name, size); e != nil {
+		return &PathError{"truncate", name, e}
+	}
+	return nil
+}
+
+// Remove removes the named file or directory.
+// If there is an error, it will be of type *PathError.
+func Remove(name string) error {
+	// System call interface forces us to know
+	// whether name is a file or directory.
+	// Try both: it is cheaper on average than
+	// doing a Stat plus the right one.
+	e := syscall.Unlink(name)
+	if e == nil {
+		return nil
+	}
+	e1 := syscall.Rmdir(name)
+	if e1 == nil {
+		return nil
+	}
+
+	// Both failed: figure out which error to return.
+	// OS X and Linux differ on whether unlink(dir)
+	// returns EISDIR, so can't use that.  However,
+	// both agree that rmdir(file) returns ENOTDIR,
+	// so we can use that to decide which error is real.
+	// Rmdir might also return ENOTDIR if given a bad
+	// file path, like /etc/passwd/foo, but in that case,
+	// both errors will be ENOTDIR, so it's okay to
+	// use the error from unlink.
+	if e1 != syscall.ENOTDIR {
+		e = e1
+	}
+	return &PathError{"remove", name, e}
+}
+
+// basename removes trailing slashes and the leading directory name from path name
+func basename(name string) string {
+	i := len(name) - 1
+	// Remove trailing slashes
+	for ; i > 0 && name[i] == '/'; i-- {
+		name = name[:i]
+	}
+	// Remove leading directory name
+	for i--; i >= 0; i-- {
+		if name[i] == '/' {
+			name = name[i+1:]
+			break
+		}
+	}
+
+	return name
+}
+
+// TempDir returns the default directory to use for temporary files.
+func TempDir() string {
+	dir := Getenv("TMPDIR")
+	if dir == "" {
+		if runtime.GOOS == "android" {
+			dir = "/data/local/tmp"
+		} else {
+			dir = "/tmp"
+		}
+	}
+	return dir
+}
+
+// Link creates newname as a hard link to the oldname file.
+// If there is an error, it will be of type *LinkError.
+func Link(oldname, newname string) error {
+	e := syscall.Link(oldname, newname)
+	if e != nil {
+		return &LinkError{"link", oldname, newname, e}
+	}
+	return nil
+}
+
+// Symlink creates newname as a symbolic link to oldname.
+// If there is an error, it will be of type *LinkError.
+func Symlink(oldname, newname string) error {
+	e := syscall.Symlink(oldname, newname)
+	if e != nil {
+		return &LinkError{"symlink", oldname, newname, e}
+	}
+	return nil
+}
diff --git a/src/os/file_windows.go b/src/os/file_windows.go
new file mode 100644
index 0000000..2a90a50
--- /dev/null
+++ b/src/os/file_windows.go
@@ -0,0 +1,596 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package os
+
+import (
+	"io"
+	"runtime"
+	"sync"
+	"syscall"
+	"unicode/utf16"
+	"unicode/utf8"
+	"unsafe"
+)
+
+// File represents an open file descriptor.
+type File struct {
+	*file
+}
+
+// file is the real representation of *File.
+// The extra level of indirection ensures that no clients of os
+// can overwrite this data, which could cause the finalizer
+// to close the wrong file descriptor.
+type file struct {
+	fd      syscall.Handle
+	name    string
+	dirinfo *dirInfo   // nil unless directory being read
+	l       sync.Mutex // used to implement windows pread/pwrite
+
+	// only for console io
+	isConsole bool
+	lastbits  []byte // first few bytes of the last incomplete rune in last write
+	readbuf   []rune // input console buffer
+}
+
+// Fd returns the Windows handle referencing the open file.
+// The handle is valid only until f.Close is called or f is garbage collected.
+func (file *File) Fd() uintptr {
+	if file == nil {
+		return uintptr(syscall.InvalidHandle)
+	}
+	return uintptr(file.fd)
+}
+
+// newFile returns a new File with the given file handle and name.
+// Unlike NewFile, it does not check that h is syscall.InvalidHandle.
+func newFile(h syscall.Handle, name string) *File {
+	f := &File{&file{fd: h, name: name}}
+	var m uint32
+	if syscall.GetConsoleMode(f.fd, &m) == nil {
+		f.isConsole = true
+	}
+	runtime.SetFinalizer(f.file, (*file).close)
+	return f
+}
+
+// NewFile returns a new File with the given file descriptor and name.
+func NewFile(fd uintptr, name string) *File {
+	h := syscall.Handle(fd)
+	if h == syscall.InvalidHandle {
+		return nil
+	}
+	return newFile(h, name)
+}
+
+// Auxiliary information if the File describes a directory
+type dirInfo struct {
+	data     syscall.Win32finddata
+	needdata bool
+	path     string
+	isempty  bool // set if FindFirstFile returns ERROR_FILE_NOT_FOUND
+}
+
+func epipecheck(file *File, e error) {
+}
+
+const DevNull = "NUL"
+
+func (f *file) isdir() bool { return f != nil && f.dirinfo != nil }
+
+func openFile(name string, flag int, perm FileMode) (file *File, err error) {
+	r, e := syscall.Open(name, flag|syscall.O_CLOEXEC, syscallMode(perm))
+	if e != nil {
+		return nil, e
+	}
+	return NewFile(uintptr(r), name), nil
+}
+
+func openDir(name string) (file *File, err error) {
+	maskp, e := syscall.UTF16PtrFromString(name + `\*`)
+	if e != nil {
+		return nil, e
+	}
+	d := new(dirInfo)
+	r, e := syscall.FindFirstFile(maskp, &d.data)
+	if e != nil {
+		// FindFirstFile returns ERROR_FILE_NOT_FOUND when
+		// no matching files can be found. Then, if directory
+		// exists, we should proceed.
+		if e != syscall.ERROR_FILE_NOT_FOUND {
+			return nil, e
+		}
+		var fa syscall.Win32FileAttributeData
+		namep, e := syscall.UTF16PtrFromString(name)
+		if e != nil {
+			return nil, e
+		}
+		e = syscall.GetFileAttributesEx(namep, syscall.GetFileExInfoStandard, (*byte)(unsafe.Pointer(&fa)))
+		if e != nil {
+			return nil, e
+		}
+		if fa.FileAttributes&syscall.FILE_ATTRIBUTE_DIRECTORY == 0 {
+			return nil, e
+		}
+		d.isempty = true
+	}
+	d.path = name
+	if !isAbs(d.path) {
+		d.path, e = syscall.FullPath(d.path)
+		if e != nil {
+			return nil, e
+		}
+	}
+	f := newFile(r, name)
+	f.dirinfo = d
+	return f, nil
+}
+
+// OpenFile is the generalized open call; most users will use Open
+// or Create instead.  It opens the named file with specified flag
+// (O_RDONLY etc.) and perm, (0666 etc.) if applicable.  If successful,
+// methods on the returned File can be used for I/O.
+// If there is an error, it will be of type *PathError.
+func OpenFile(name string, flag int, perm FileMode) (file *File, err error) {
+	if name == "" {
+		return nil, &PathError{"open", name, syscall.ENOENT}
+	}
+	r, errf := openFile(name, flag, perm)
+	if errf == nil {
+		return r, nil
+	}
+	r, errd := openDir(name)
+	if errd == nil {
+		if flag&O_WRONLY != 0 || flag&O_RDWR != 0 {
+			r.Close()
+			return nil, &PathError{"open", name, syscall.EISDIR}
+		}
+		return r, nil
+	}
+	return nil, &PathError{"open", name, errf}
+}
+
+// Close closes the File, rendering it unusable for I/O.
+// It returns an error, if any.
+func (file *File) Close() error {
+	if file == nil {
+		return ErrInvalid
+	}
+	return file.file.close()
+}
+
+func (file *file) close() error {
+	if file == nil {
+		return syscall.EINVAL
+	}
+	if file.isdir() && file.dirinfo.isempty {
+		// "special" empty directories
+		return nil
+	}
+	if file.fd == syscall.InvalidHandle {
+		return syscall.EINVAL
+	}
+	var e error
+	if file.isdir() {
+		e = syscall.FindClose(syscall.Handle(file.fd))
+	} else {
+		e = syscall.CloseHandle(syscall.Handle(file.fd))
+	}
+	var err error
+	if e != nil {
+		err = &PathError{"close", file.name, e}
+	}
+	file.fd = syscall.InvalidHandle // so it can't be closed again
+
+	// no need for a finalizer anymore
+	runtime.SetFinalizer(file, nil)
+	return err
+}
+
+func (file *File) readdir(n int) (fi []FileInfo, err error) {
+	if file == nil {
+		return nil, syscall.EINVAL
+	}
+	if !file.isdir() {
+		return nil, &PathError{"Readdir", file.name, syscall.ENOTDIR}
+	}
+	if !file.dirinfo.isempty && file.fd == syscall.InvalidHandle {
+		return nil, syscall.EINVAL
+	}
+	wantAll := n <= 0
+	size := n
+	if wantAll {
+		n = -1
+		size = 100
+	}
+	fi = make([]FileInfo, 0, size) // Empty with room to grow.
+	d := &file.dirinfo.data
+	for n != 0 && !file.dirinfo.isempty {
+		if file.dirinfo.needdata {
+			e := syscall.FindNextFile(syscall.Handle(file.fd), d)
+			if e != nil {
+				if e == syscall.ERROR_NO_MORE_FILES {
+					break
+				} else {
+					err = &PathError{"FindNextFile", file.name, e}
+					if !wantAll {
+						fi = nil
+					}
+					return
+				}
+			}
+		}
+		file.dirinfo.needdata = true
+		name := string(syscall.UTF16ToString(d.FileName[0:]))
+		if name == "." || name == ".." { // Useless names
+			continue
+		}
+		f := &fileStat{
+			name: name,
+			sys: syscall.Win32FileAttributeData{
+				FileAttributes: d.FileAttributes,
+				CreationTime:   d.CreationTime,
+				LastAccessTime: d.LastAccessTime,
+				LastWriteTime:  d.LastWriteTime,
+				FileSizeHigh:   d.FileSizeHigh,
+				FileSizeLow:    d.FileSizeLow,
+			},
+			path: file.dirinfo.path + `\` + name,
+		}
+		n--
+		fi = append(fi, f)
+	}
+	if !wantAll && len(fi) == 0 {
+		return fi, io.EOF
+	}
+	return fi, nil
+}
+
+// readConsole reads utf16 characters from console File,
+// encodes them into utf8 and stores them in buffer b.
+// It returns the number of utf8 bytes read and an error, if any.
+func (f *File) readConsole(b []byte) (n int, err error) {
+	if len(b) == 0 {
+		return 0, nil
+	}
+	if len(f.readbuf) == 0 {
+		// syscall.ReadConsole seems to fail, if given large buffer.
+		// So limit the buffer to 16000 characters.
+		numBytes := len(b)
+		if numBytes > 16000 {
+			numBytes = 16000
+		}
+		// get more input data from os
+		wchars := make([]uint16, numBytes)
+		var p *uint16
+		if len(b) > 0 {
+			p = &wchars[0]
+		}
+		var nw uint32
+		err := syscall.ReadConsole(f.fd, p, uint32(len(wchars)), &nw, nil)
+		if err != nil {
+			return 0, err
+		}
+		f.readbuf = utf16.Decode(wchars[:nw])
+	}
+	for i, r := range f.readbuf {
+		if utf8.RuneLen(r) > len(b) {
+			f.readbuf = f.readbuf[i:]
+			return n, nil
+		}
+		nr := utf8.EncodeRune(b, r)
+		b = b[nr:]
+		n += nr
+	}
+	f.readbuf = nil
+	return n, nil
+}
+
+// read reads up to len(b) bytes from the File.
+// It returns the number of bytes read and an error, if any.
+func (f *File) read(b []byte) (n int, err error) {
+	f.l.Lock()
+	defer f.l.Unlock()
+	if f.isConsole {
+		return f.readConsole(b)
+	}
+	return fixCount(syscall.Read(f.fd, b))
+}
+
+// pread reads len(b) bytes from the File starting at byte offset off.
+// It returns the number of bytes read and the error, if any.
+// EOF is signaled by a zero count with err set to 0.
+func (f *File) pread(b []byte, off int64) (n int, err error) {
+	f.l.Lock()
+	defer f.l.Unlock()
+	curoffset, e := syscall.Seek(f.fd, 0, 1)
+	if e != nil {
+		return 0, e
+	}
+	defer syscall.Seek(f.fd, curoffset, 0)
+	o := syscall.Overlapped{
+		OffsetHigh: uint32(off >> 32),
+		Offset:     uint32(off),
+	}
+	var done uint32
+	e = syscall.ReadFile(syscall.Handle(f.fd), b, &done, &o)
+	if e != nil {
+		if e == syscall.ERROR_HANDLE_EOF {
+			// end of file
+			return 0, nil
+		}
+		return 0, e
+	}
+	return int(done), nil
+}
+
+// writeConsole writes len(b) bytes to the console File.
+// It returns the number of bytes written and an error, if any.
+func (f *File) writeConsole(b []byte) (n int, err error) {
+	n = len(b)
+	runes := make([]rune, 0, 256)
+	if len(f.lastbits) > 0 {
+		b = append(f.lastbits, b...)
+		f.lastbits = nil
+
+	}
+	for len(b) >= utf8.UTFMax || utf8.FullRune(b) {
+		r, l := utf8.DecodeRune(b)
+		runes = append(runes, r)
+		b = b[l:]
+	}
+	if len(b) > 0 {
+		f.lastbits = make([]byte, len(b))
+		copy(f.lastbits, b)
+	}
+	// syscall.WriteConsole seems to fail, if given large buffer.
+	// So limit the buffer to 16000 characters. This number was
+	// discovered by experimenting with syscall.WriteConsole.
+	const maxWrite = 16000
+	for len(runes) > 0 {
+		m := len(runes)
+		if m > maxWrite {
+			m = maxWrite
+		}
+		chunk := runes[:m]
+		runes = runes[m:]
+		uint16s := utf16.Encode(chunk)
+		for len(uint16s) > 0 {
+			var written uint32
+			err = syscall.WriteConsole(f.fd, &uint16s[0], uint32(len(uint16s)), &written, nil)
+			if err != nil {
+				return 0, nil
+			}
+			uint16s = uint16s[written:]
+		}
+	}
+	return n, nil
+}
+
+// write writes len(b) bytes to the File.
+// It returns the number of bytes written and an error, if any.
+func (f *File) write(b []byte) (n int, err error) {
+	f.l.Lock()
+	defer f.l.Unlock()
+	if f.isConsole {
+		return f.writeConsole(b)
+	}
+	return fixCount(syscall.Write(f.fd, b))
+}
+
+// pwrite writes len(b) bytes to the File starting at byte offset off.
+// It returns the number of bytes written and an error, if any.
+func (f *File) pwrite(b []byte, off int64) (n int, err error) {
+	f.l.Lock()
+	defer f.l.Unlock()
+	curoffset, e := syscall.Seek(f.fd, 0, 1)
+	if e != nil {
+		return 0, e
+	}
+	defer syscall.Seek(f.fd, curoffset, 0)
+	o := syscall.Overlapped{
+		OffsetHigh: uint32(off >> 32),
+		Offset:     uint32(off),
+	}
+	var done uint32
+	e = syscall.WriteFile(syscall.Handle(f.fd), b, &done, &o)
+	if e != nil {
+		return 0, e
+	}
+	return int(done), nil
+}
+
+// seek sets the offset for the next Read or Write on file to offset, interpreted
+// according to whence: 0 means relative to the origin of the file, 1 means
+// relative to the current offset, and 2 means relative to the end.
+// It returns the new offset and an error, if any.
+func (f *File) seek(offset int64, whence int) (ret int64, err error) {
+	f.l.Lock()
+	defer f.l.Unlock()
+	return syscall.Seek(f.fd, offset, whence)
+}
+
+// Truncate changes the size of the named file.
+// If the file is a symbolic link, it changes the size of the link's target.
+func Truncate(name string, size int64) error {
+	f, e := OpenFile(name, O_WRONLY|O_CREATE, 0666)
+	if e != nil {
+		return e
+	}
+	defer f.Close()
+	e1 := f.Truncate(size)
+	if e1 != nil {
+		return e1
+	}
+	return nil
+}
+
+// Remove removes the named file or directory.
+// If there is an error, it will be of type *PathError.
+func Remove(name string) error {
+	p, e := syscall.UTF16PtrFromString(name)
+	if e != nil {
+		return &PathError{"remove", name, e}
+	}
+
+	// Go file interface forces us to know whether
+	// name is a file or directory. Try both.
+	e = syscall.DeleteFile(p)
+	if e == nil {
+		return nil
+	}
+	e1 := syscall.RemoveDirectory(p)
+	if e1 == nil {
+		return nil
+	}
+
+	// Both failed: figure out which error to return.
+	if e1 != e {
+		a, e2 := syscall.GetFileAttributes(p)
+		if e2 != nil {
+			e = e2
+		} else {
+			if a&syscall.FILE_ATTRIBUTE_DIRECTORY != 0 {
+				e = e1
+			}
+		}
+	}
+	return &PathError{"remove", name, e}
+}
+
+// Pipe returns a connected pair of Files; reads from r return bytes written to w.
+// It returns the files and an error, if any.
+func Pipe() (r *File, w *File, err error) {
+	var p [2]syscall.Handle
+
+	// See ../syscall/exec.go for description of lock.
+	syscall.ForkLock.RLock()
+	e := syscall.Pipe(p[0:])
+	if e != nil {
+		syscall.ForkLock.RUnlock()
+		return nil, nil, NewSyscallError("pipe", e)
+	}
+	syscall.CloseOnExec(p[0])
+	syscall.CloseOnExec(p[1])
+	syscall.ForkLock.RUnlock()
+
+	return NewFile(uintptr(p[0]), "|0"), NewFile(uintptr(p[1]), "|1"), nil
+}
+
+// TempDir returns the default directory to use for temporary files.
+func TempDir() string {
+	const pathSep = '\\'
+	dirw := make([]uint16, syscall.MAX_PATH)
+	n, _ := syscall.GetTempPath(uint32(len(dirw)), &dirw[0])
+	if n > uint32(len(dirw)) {
+		dirw = make([]uint16, n)
+		n, _ = syscall.GetTempPath(uint32(len(dirw)), &dirw[0])
+		if n > uint32(len(dirw)) {
+			n = 0
+		}
+	}
+	if n > 0 && dirw[n-1] == pathSep {
+		n--
+	}
+	return string(utf16.Decode(dirw[0:n]))
+}
+
+// Link creates newname as a hard link to the oldname file.
+// If there is an error, it will be of type *LinkError.
+func Link(oldname, newname string) error {
+	n, err := syscall.UTF16PtrFromString(newname)
+	if err != nil {
+		return &LinkError{"link", oldname, newname, err}
+	}
+	o, err := syscall.UTF16PtrFromString(oldname)
+	if err != nil {
+		return &LinkError{"link", oldname, newname, err}
+	}
+
+	e := syscall.CreateHardLink(n, o, 0)
+	if e != nil {
+		return &LinkError{"link", oldname, newname, err}
+	}
+	return nil
+}
+
+// Symlink creates newname as a symbolic link to oldname.
+// If there is an error, it will be of type *LinkError.
+func Symlink(oldname, newname string) error {
+	// CreateSymbolicLink is not supported before Windows Vista
+	if syscall.LoadCreateSymbolicLink() != nil {
+		return &LinkError{"symlink", oldname, newname, syscall.EWINDOWS}
+	}
+
+	// '/' does not work in link's content
+	oldname = fromSlash(oldname)
+
+	// need the exact location of the oldname when its relative to determine if its a directory
+	destpath := oldname
+	if !isAbs(oldname) {
+		destpath = dirname(newname) + `\` + oldname
+	}
+
+	fi, err := Lstat(destpath)
+	isdir := err == nil && fi.IsDir()
+
+	n, err := syscall.UTF16PtrFromString(newname)
+	if err != nil {
+		return &LinkError{"symlink", oldname, newname, err}
+	}
+	o, err := syscall.UTF16PtrFromString(oldname)
+	if err != nil {
+		return &LinkError{"symlink", oldname, newname, err}
+	}
+
+	var flags uint32
+	if isdir {
+		flags |= syscall.SYMBOLIC_LINK_FLAG_DIRECTORY
+	}
+	err = syscall.CreateSymbolicLink(n, o, flags)
+	if err != nil {
+		return &LinkError{"symlink", oldname, newname, err}
+	}
+	return nil
+}
+
+func fromSlash(path string) string {
+	// Replace each '/' with '\\' if present
+	var pathbuf []byte
+	var lastSlash int
+	for i, b := range path {
+		if b == '/' {
+			if pathbuf == nil {
+				pathbuf = make([]byte, len(path))
+			}
+			copy(pathbuf[lastSlash:], path[lastSlash:i])
+			pathbuf[i] = '\\'
+			lastSlash = i + 1
+		}
+	}
+	if pathbuf == nil {
+		return path
+	}
+
+	copy(pathbuf[lastSlash:], path[lastSlash:])
+	return string(pathbuf)
+}
+
+func dirname(path string) string {
+	vol := volumeName(path)
+	i := len(path) - 1
+	for i >= len(vol) && !IsPathSeparator(path[i]) {
+		i--
+	}
+	dir := path[len(vol) : i+1]
+	last := len(dir) - 1
+	if last > 0 && IsPathSeparator(dir[last]) {
+		dir = dir[:last]
+	}
+	if dir == "" {
+		dir = "."
+	}
+	return vol + dir
+}
diff --git a/src/os/getwd.go b/src/os/getwd.go
new file mode 100644
index 0000000..d5da53b
--- /dev/null
+++ b/src/os/getwd.go
@@ -0,0 +1,123 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package os
+
+import (
+	"runtime"
+	"sync"
+	"syscall"
+)
+
+var getwdCache struct {
+	sync.Mutex
+	dir string
+}
+
+// useSyscallwd determines whether to use the return value of
+// syscall.Getwd based on its error.
+var useSyscallwd = func(error) bool { return true }
+
+// Getwd returns a rooted path name corresponding to the
+// current directory.  If the current directory can be
+// reached via multiple paths (due to symbolic links),
+// Getwd may return any one of them.
+func Getwd() (dir string, err error) {
+	if runtime.GOOS == "windows" {
+		return syscall.Getwd()
+	}
+
+	// Clumsy but widespread kludge:
+	// if $PWD is set and matches ".", use it.
+	dot, err := Stat(".")
+	if err != nil {
+		return "", err
+	}
+	dir = Getenv("PWD")
+	if len(dir) > 0 && dir[0] == '/' {
+		d, err := Stat(dir)
+		if err == nil && SameFile(dot, d) {
+			return dir, nil
+		}
+	}
+
+	// If the operating system provides a Getwd call, use it.
+	// Otherwise, we're trying to find our way back to ".".
+	if syscall.ImplementsGetwd {
+		s, e := syscall.Getwd()
+		if useSyscallwd(e) {
+			return s, NewSyscallError("getwd", e)
+		}
+	}
+
+	// Apply same kludge but to cached dir instead of $PWD.
+	getwdCache.Lock()
+	dir = getwdCache.dir
+	getwdCache.Unlock()
+	if len(dir) > 0 {
+		d, err := Stat(dir)
+		if err == nil && SameFile(dot, d) {
+			return dir, nil
+		}
+	}
+
+	// Root is a special case because it has no parent
+	// and ends in a slash.
+	root, err := Stat("/")
+	if err != nil {
+		// Can't stat root - no hope.
+		return "", err
+	}
+	if SameFile(root, dot) {
+		return "/", nil
+	}
+
+	// General algorithm: find name in parent
+	// and then find name of parent.  Each iteration
+	// adds /name to the beginning of dir.
+	dir = ""
+	for parent := ".."; ; parent = "../" + parent {
+		if len(parent) >= 1024 { // Sanity check
+			return "", syscall.ENAMETOOLONG
+		}
+		fd, err := Open(parent)
+		if err != nil {
+			return "", err
+		}
+
+		for {
+			names, err := fd.Readdirnames(100)
+			if err != nil {
+				fd.Close()
+				return "", err
+			}
+			for _, name := range names {
+				d, _ := Lstat(parent + "/" + name)
+				if SameFile(d, dot) {
+					dir = "/" + name + dir
+					goto Found
+				}
+			}
+		}
+
+	Found:
+		pd, err := fd.Stat()
+		if err != nil {
+			return "", err
+		}
+		fd.Close()
+		if SameFile(pd, root) {
+			break
+		}
+		// Set up for next round.
+		dot = pd
+	}
+
+	// Save answer as hint to avoid the expensive path next time.
+	getwdCache.Lock()
+	getwdCache.dir = dir
+	getwdCache.Unlock()
+
+	return dir, nil
+}
diff --git a/src/pkg/os/getwd_darwin.go b/src/os/getwd_darwin.go
similarity index 100%
rename from src/pkg/os/getwd_darwin.go
rename to src/os/getwd_darwin.go
diff --git a/src/os/os_test.go b/src/os/os_test.go
new file mode 100644
index 0000000..a30a2b0
--- /dev/null
+++ b/src/os/os_test.go
@@ -0,0 +1,1484 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package os_test
+
+import (
+	"bytes"
+	"errors"
+	"flag"
+	"fmt"
+	"io"
+	"io/ioutil"
+	. "os"
+	osexec "os/exec"
+	"path/filepath"
+	"reflect"
+	"runtime"
+	"sort"
+	"strings"
+	"sync"
+	"syscall"
+	"testing"
+	"text/template"
+	"time"
+)
+
+var supportsSymlinks = true
+
+var dot = []string{
+	"dir_unix.go",
+	"env.go",
+	"error.go",
+	"file.go",
+	"os_test.go",
+	"types.go",
+	"stat_darwin.go",
+	"stat_linux.go",
+}
+
+type sysDir struct {
+	name  string
+	files []string
+}
+
+var sysdir = func() (sd *sysDir) {
+	switch runtime.GOOS {
+	case "android":
+		sd = &sysDir{
+			"/system/etc",
+			[]string{
+				"audio_policy.conf",
+				"system_fonts.xml",
+			},
+		}
+	case "windows":
+		sd = &sysDir{
+			Getenv("SystemRoot") + "\\system32\\drivers\\etc",
+			[]string{
+				"networks",
+				"protocol",
+				"services",
+			},
+		}
+	case "plan9":
+		sd = &sysDir{
+			"/lib/ndb",
+			[]string{
+				"common",
+				"local",
+			},
+		}
+	default:
+		sd = &sysDir{
+			"/etc",
+			[]string{
+				"group",
+				"hosts",
+				"passwd",
+			},
+		}
+	}
+	return
+}()
+
+func size(name string, t *testing.T) int64 {
+	file, err := Open(name)
+	if err != nil {
+		t.Fatal("open failed:", err)
+	}
+	defer file.Close()
+	var buf [100]byte
+	len := 0
+	for {
+		n, e := file.Read(buf[0:])
+		len += n
+		if e == io.EOF {
+			break
+		}
+		if e != nil {
+			t.Fatal("read failed:", err)
+		}
+	}
+	return int64(len)
+}
+
+func equal(name1, name2 string) (r bool) {
+	switch runtime.GOOS {
+	case "windows":
+		r = strings.ToLower(name1) == strings.ToLower(name2)
+	default:
+		r = name1 == name2
+	}
+	return
+}
+
+func newFile(testName string, t *testing.T) (f *File) {
+	// Use a local file system, not NFS.
+	// On Unix, override $TMPDIR in case the user
+	// has it set to an NFS-mounted directory.
+	dir := ""
+	if runtime.GOOS != "android" && runtime.GOOS != "windows" {
+		dir = "/tmp"
+	}
+	f, err := ioutil.TempFile(dir, "_Go_"+testName)
+	if err != nil {
+		t.Fatalf("TempFile %s: %s", testName, err)
+	}
+	return
+}
+
+func newDir(testName string, t *testing.T) (name string) {
+	// Use a local file system, not NFS.
+	// On Unix, override $TMPDIR in case the user
+	// has it set to an NFS-mounted directory.
+	dir := ""
+	if runtime.GOOS != "android" && runtime.GOOS != "windows" {
+		dir = "/tmp"
+	}
+	name, err := ioutil.TempDir(dir, "_Go_"+testName)
+	if err != nil {
+		t.Fatalf("TempDir %s: %s", testName, err)
+	}
+	return
+}
+
+var sfdir = sysdir.name
+var sfname = sysdir.files[0]
+
+func TestStat(t *testing.T) {
+	path := sfdir + "/" + sfname
+	dir, err := Stat(path)
+	if err != nil {
+		t.Fatal("stat failed:", err)
+	}
+	if !equal(sfname, dir.Name()) {
+		t.Error("name should be ", sfname, "; is", dir.Name())
+	}
+	filesize := size(path, t)
+	if dir.Size() != filesize {
+		t.Error("size should be", filesize, "; is", dir.Size())
+	}
+}
+
+func TestFstat(t *testing.T) {
+	path := sfdir + "/" + sfname
+	file, err1 := Open(path)
+	if err1 != nil {
+		t.Fatal("open failed:", err1)
+	}
+	defer file.Close()
+	dir, err2 := file.Stat()
+	if err2 != nil {
+		t.Fatal("fstat failed:", err2)
+	}
+	if !equal(sfname, dir.Name()) {
+		t.Error("name should be ", sfname, "; is", dir.Name())
+	}
+	filesize := size(path, t)
+	if dir.Size() != filesize {
+		t.Error("size should be", filesize, "; is", dir.Size())
+	}
+}
+
+func TestLstat(t *testing.T) {
+	path := sfdir + "/" + sfname
+	dir, err := Lstat(path)
+	if err != nil {
+		t.Fatal("lstat failed:", err)
+	}
+	if !equal(sfname, dir.Name()) {
+		t.Error("name should be ", sfname, "; is", dir.Name())
+	}
+	filesize := size(path, t)
+	if dir.Size() != filesize {
+		t.Error("size should be", filesize, "; is", dir.Size())
+	}
+}
+
+// Read with length 0 should not return EOF.
+func TestRead0(t *testing.T) {
+	path := sfdir + "/" + sfname
+	f, err := Open(path)
+	if err != nil {
+		t.Fatal("open failed:", err)
+	}
+	defer f.Close()
+
+	b := make([]byte, 0)
+	n, err := f.Read(b)
+	if n != 0 || err != nil {
+		t.Errorf("Read(0) = %d, %v, want 0, nil", n, err)
+	}
+	b = make([]byte, 100)
+	n, err = f.Read(b)
+	if n <= 0 || err != nil {
+		t.Errorf("Read(100) = %d, %v, want >0, nil", n, err)
+	}
+}
+
+func testReaddirnames(dir string, contents []string, t *testing.T) {
+	file, err := Open(dir)
+	if err != nil {
+		t.Fatalf("open %q failed: %v", dir, err)
+	}
+	defer file.Close()
+	s, err2 := file.Readdirnames(-1)
+	if err2 != nil {
+		t.Fatalf("readdirnames %q failed: %v", dir, err2)
+	}
+	for _, m := range contents {
+		found := false
+		for _, n := range s {
+			if n == "." || n == ".." {
+				t.Errorf("got %s in directory", n)
+			}
+			if equal(m, n) {
+				if found {
+					t.Error("present twice:", m)
+				}
+				found = true
+			}
+		}
+		if !found {
+			t.Error("could not find", m)
+		}
+	}
+}
+
+func testReaddir(dir string, contents []string, t *testing.T) {
+	file, err := Open(dir)
+	if err != nil {
+		t.Fatalf("open %q failed: %v", dir, err)
+	}
+	defer file.Close()
+	s, err2 := file.Readdir(-1)
+	if err2 != nil {
+		t.Fatalf("readdir %q failed: %v", dir, err2)
+	}
+	for _, m := range contents {
+		found := false
+		for _, n := range s {
+			if equal(m, n.Name()) {
+				if found {
+					t.Error("present twice:", m)
+				}
+				found = true
+			}
+		}
+		if !found {
+			t.Error("could not find", m)
+		}
+	}
+}
+
+func TestReaddirnames(t *testing.T) {
+	testReaddirnames(".", dot, t)
+	testReaddirnames(sysdir.name, sysdir.files, t)
+}
+
+func TestReaddir(t *testing.T) {
+	testReaddir(".", dot, t)
+	testReaddir(sysdir.name, sysdir.files, t)
+}
+
+// Read the directory one entry at a time.
+func smallReaddirnames(file *File, length int, t *testing.T) []string {
+	names := make([]string, length)
+	count := 0
+	for {
+		d, err := file.Readdirnames(1)
+		if err == io.EOF {
+			break
+		}
+		if err != nil {
+			t.Fatalf("readdirnames %q failed: %v", file.Name(), err)
+		}
+		if len(d) == 0 {
+			t.Fatalf("readdirnames %q returned empty slice and no error", file.Name())
+		}
+		names[count] = d[0]
+		count++
+	}
+	return names[0:count]
+}
+
+// Check that reading a directory one entry at a time gives the same result
+// as reading it all at once.
+func TestReaddirnamesOneAtATime(t *testing.T) {
+	// big directory that doesn't change often.
+	dir := "/usr/bin"
+	switch runtime.GOOS {
+	case "android":
+		dir = "/system/bin"
+	case "plan9":
+		dir = "/bin"
+	case "windows":
+		dir = Getenv("SystemRoot") + "\\system32"
+	}
+	file, err := Open(dir)
+	if err != nil {
+		t.Fatalf("open %q failed: %v", dir, err)
+	}
+	defer file.Close()
+	all, err1 := file.Readdirnames(-1)
+	if err1 != nil {
+		t.Fatalf("readdirnames %q failed: %v", dir, err1)
+	}
+	file1, err2 := Open(dir)
+	if err2 != nil {
+		t.Fatalf("open %q failed: %v", dir, err2)
+	}
+	defer file1.Close()
+	small := smallReaddirnames(file1, len(all)+100, t) // +100 in case we screw up
+	if len(small) < len(all) {
+		t.Fatalf("len(small) is %d, less than %d", len(small), len(all))
+	}
+	for i, n := range all {
+		if small[i] != n {
+			t.Errorf("small read %q mismatch: %v", small[i], n)
+		}
+	}
+}
+
+func TestReaddirNValues(t *testing.T) {
+	if testing.Short() {
+		t.Skip("test.short; skipping")
+	}
+	dir, err := ioutil.TempDir("", "")
+	if err != nil {
+		t.Fatalf("TempDir: %v", err)
+	}
+	defer RemoveAll(dir)
+	for i := 1; i <= 105; i++ {
+		f, err := Create(filepath.Join(dir, fmt.Sprintf("%d", i)))
+		if err != nil {
+			t.Fatalf("Create: %v", err)
+		}
+		f.Write([]byte(strings.Repeat("X", i)))
+		f.Close()
+	}
+
+	var d *File
+	openDir := func() {
+		var err error
+		d, err = Open(dir)
+		if err != nil {
+			t.Fatalf("Open directory: %v", err)
+		}
+	}
+
+	readDirExpect := func(n, want int, wantErr error) {
+		fi, err := d.Readdir(n)
+		if err != wantErr {
+			t.Fatalf("Readdir of %d got error %v, want %v", n, err, wantErr)
+		}
+		if g, e := len(fi), want; g != e {
+			t.Errorf("Readdir of %d got %d files, want %d", n, g, e)
+		}
+	}
+
+	readDirNamesExpect := func(n, want int, wantErr error) {
+		fi, err := d.Readdirnames(n)
+		if err != wantErr {
+			t.Fatalf("Readdirnames of %d got error %v, want %v", n, err, wantErr)
+		}
+		if g, e := len(fi), want; g != e {
+			t.Errorf("Readdirnames of %d got %d files, want %d", n, g, e)
+		}
+	}
+
+	for _, fn := range []func(int, int, error){readDirExpect, readDirNamesExpect} {
+		// Test the slurp case
+		openDir()
+		fn(0, 105, nil)
+		fn(0, 0, nil)
+		d.Close()
+
+		// Slurp with -1 instead
+		openDir()
+		fn(-1, 105, nil)
+		fn(-2, 0, nil)
+		fn(0, 0, nil)
+		d.Close()
+
+		// Test the bounded case
+		openDir()
+		fn(1, 1, nil)
+		fn(2, 2, nil)
+		fn(105, 102, nil) // and tests buffer >100 case
+		fn(3, 0, io.EOF)
+		d.Close()
+	}
+}
+
+func touch(t *testing.T, name string) {
+	f, err := Create(name)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if err := f.Close(); err != nil {
+		t.Fatal(err)
+	}
+}
+
+func TestReaddirStatFailures(t *testing.T) {
+	switch runtime.GOOS {
+	case "windows", "plan9":
+		// Windows and Plan 9 already do this correctly,
+		// but are structured with different syscalls such
+		// that they don't use Lstat, so the hook below for
+		// testing it wouldn't work.
+		t.Skipf("skipping test on %v", runtime.GOOS)
+	}
+	dir, err := ioutil.TempDir("", "")
+	if err != nil {
+		t.Fatalf("TempDir: %v", err)
+	}
+	defer RemoveAll(dir)
+	touch(t, filepath.Join(dir, "good1"))
+	touch(t, filepath.Join(dir, "x")) // will disappear or have an error
+	touch(t, filepath.Join(dir, "good2"))
+	defer func() {
+		*LstatP = Lstat
+	}()
+	var xerr error // error to return for x
+	*LstatP = func(path string) (FileInfo, error) {
+		if xerr != nil && strings.HasSuffix(path, "x") {
+			return nil, xerr
+		}
+		return Lstat(path)
+	}
+	readDir := func() ([]FileInfo, error) {
+		d, err := Open(dir)
+		if err != nil {
+			t.Fatal(err)
+		}
+		defer d.Close()
+		return d.Readdir(-1)
+	}
+	mustReadDir := func(testName string) []FileInfo {
+		fis, err := readDir()
+		if err != nil {
+			t.Fatalf("%s: Readdir: %v", testName, err)
+		}
+		return fis
+	}
+	names := func(fis []FileInfo) []string {
+		s := make([]string, len(fis))
+		for i, fi := range fis {
+			s[i] = fi.Name()
+		}
+		sort.Strings(s)
+		return s
+	}
+
+	if got, want := names(mustReadDir("inital readdir")),
+		[]string{"good1", "good2", "x"}; !reflect.DeepEqual(got, want) {
+		t.Errorf("initial readdir got %q; want %q", got, want)
+	}
+
+	xerr = ErrNotExist
+	if got, want := names(mustReadDir("with x disappearing")),
+		[]string{"good1", "good2"}; !reflect.DeepEqual(got, want) {
+		t.Errorf("with x disappearing, got %q; want %q", got, want)
+	}
+
+	xerr = errors.New("some real error")
+	if _, err := readDir(); err != xerr {
+		t.Errorf("with a non-ErrNotExist error, got error %v; want %v", err, xerr)
+	}
+}
+
+func TestHardLink(t *testing.T) {
+	// Hardlinks are not supported under windows or Plan 9.
+	if runtime.GOOS == "plan9" {
+		return
+	}
+	from, to := "hardlinktestfrom", "hardlinktestto"
+	Remove(from) // Just in case.
+	file, err := Create(to)
+	if err != nil {
+		t.Fatalf("open %q failed: %v", to, err)
+	}
+	defer Remove(to)
+	if err = file.Close(); err != nil {
+		t.Errorf("close %q failed: %v", to, err)
+	}
+	err = Link(to, from)
+	if err != nil {
+		t.Fatalf("link %q, %q failed: %v", to, from, err)
+	}
+	defer Remove(from)
+	tostat, err := Stat(to)
+	if err != nil {
+		t.Fatalf("stat %q failed: %v", to, err)
+	}
+	fromstat, err := Stat(from)
+	if err != nil {
+		t.Fatalf("stat %q failed: %v", from, err)
+	}
+	if !SameFile(tostat, fromstat) {
+		t.Errorf("link %q, %q did not create hard link", to, from)
+	}
+}
+
+func TestSymlink(t *testing.T) {
+	switch runtime.GOOS {
+	case "android", "nacl", "plan9":
+		t.Skipf("skipping on %s", runtime.GOOS)
+	case "windows":
+		if !supportsSymlinks {
+			t.Skipf("skipping on %s", runtime.GOOS)
+		}
+	}
+	from, to := "symlinktestfrom", "symlinktestto"
+	Remove(from) // Just in case.
+	file, err := Create(to)
+	if err != nil {
+		t.Fatalf("open %q failed: %v", to, err)
+	}
+	defer Remove(to)
+	if err = file.Close(); err != nil {
+		t.Errorf("close %q failed: %v", to, err)
+	}
+	err = Symlink(to, from)
+	if err != nil {
+		t.Fatalf("symlink %q, %q failed: %v", to, from, err)
+	}
+	defer Remove(from)
+	tostat, err := Lstat(to)
+	if err != nil {
+		t.Fatalf("stat %q failed: %v", to, err)
+	}
+	if tostat.Mode()&ModeSymlink != 0 {
+		t.Fatalf("stat %q claims to have found a symlink", to)
+	}
+	fromstat, err := Stat(from)
+	if err != nil {
+		t.Fatalf("stat %q failed: %v", from, err)
+	}
+	if !SameFile(tostat, fromstat) {
+		t.Errorf("symlink %q, %q did not create symlink", to, from)
+	}
+	fromstat, err = Lstat(from)
+	if err != nil {
+		t.Fatalf("lstat %q failed: %v", from, err)
+	}
+	if fromstat.Mode()&ModeSymlink == 0 {
+		t.Fatalf("symlink %q, %q did not create symlink", to, from)
+	}
+	fromstat, err = Stat(from)
+	if err != nil {
+		t.Fatalf("stat %q failed: %v", from, err)
+	}
+	if fromstat.Mode()&ModeSymlink != 0 {
+		t.Fatalf("stat %q did not follow symlink", from)
+	}
+	s, err := Readlink(from)
+	if err != nil {
+		t.Fatalf("readlink %q failed: %v", from, err)
+	}
+	if s != to {
+		t.Fatalf("after symlink %q != %q", s, to)
+	}
+	file, err = Open(from)
+	if err != nil {
+		t.Fatalf("open %q failed: %v", from, err)
+	}
+	file.Close()
+}
+
+func TestLongSymlink(t *testing.T) {
+	switch runtime.GOOS {
+	case "plan9", "nacl":
+		t.Skipf("skipping on %s", runtime.GOOS)
+	case "windows":
+		if !supportsSymlinks {
+			t.Skipf("skipping on %s", runtime.GOOS)
+		}
+	}
+	s := "0123456789abcdef"
+	// Long, but not too long: a common limit is 255.
+	s = s + s + s + s + s + s + s + s + s + s + s + s + s + s + s
+	from := "longsymlinktestfrom"
+	Remove(from) // Just in case.
+	err := Symlink(s, from)
+	if err != nil {
+		t.Fatalf("symlink %q, %q failed: %v", s, from, err)
+	}
+	defer Remove(from)
+	r, err := Readlink(from)
+	if err != nil {
+		t.Fatalf("readlink %q failed: %v", from, err)
+	}
+	if r != s {
+		t.Fatalf("after symlink %q != %q", r, s)
+	}
+}
+
+func TestRename(t *testing.T) {
+	from, to := "renamefrom", "renameto"
+	Remove(to) // Just in case.
+	file, err := Create(from)
+	if err != nil {
+		t.Fatalf("open %q failed: %v", to, err)
+	}
+	if err = file.Close(); err != nil {
+		t.Errorf("close %q failed: %v", to, err)
+	}
+	err = Rename(from, to)
+	if err != nil {
+		t.Fatalf("rename %q, %q failed: %v", to, from, err)
+	}
+	defer Remove(to)
+	_, err = Stat(to)
+	if err != nil {
+		t.Errorf("stat %q failed: %v", to, err)
+	}
+}
+
+func exec(t *testing.T, dir, cmd string, args []string, expect string) {
+	r, w, err := Pipe()
+	if err != nil {
+		t.Fatalf("Pipe: %v", err)
+	}
+	defer r.Close()
+	attr := &ProcAttr{Dir: dir, Files: []*File{nil, w, Stderr}}
+	p, err := StartProcess(cmd, args, attr)
+	if err != nil {
+		t.Fatalf("StartProcess: %v", err)
+	}
+	w.Close()
+
+	var b bytes.Buffer
+	io.Copy(&b, r)
+	output := b.String()
+
+	fi1, _ := Stat(strings.TrimSpace(output))
+	fi2, _ := Stat(expect)
+	if !SameFile(fi1, fi2) {
+		t.Errorf("exec %q returned %q wanted %q",
+			strings.Join(append([]string{cmd}, args...), " "), output, expect)
+	}
+	p.Wait()
+}
+
+func TestStartProcess(t *testing.T) {
+	switch runtime.GOOS {
+	case "android", "nacl":
+		t.Skipf("skipping on %s", runtime.GOOS)
+	}
+
+	var dir, cmd string
+	var args []string
+	if runtime.GOOS == "windows" {
+		cmd = Getenv("COMSPEC")
+		dir = Getenv("SystemRoot")
+		args = []string{"/c", "cd"}
+	} else {
+		cmd = "/bin/pwd"
+		dir = "/"
+		args = []string{}
+	}
+	cmddir, cmdbase := filepath.Split(cmd)
+	args = append([]string{cmdbase}, args...)
+	// Test absolute executable path.
+	exec(t, dir, cmd, args, dir)
+	// Test relative executable path.
+	exec(t, cmddir, cmdbase, args, cmddir)
+}
+
+func checkMode(t *testing.T, path string, mode FileMode) {
+	dir, err := Stat(path)
+	if err != nil {
+		t.Fatalf("Stat %q (looking for mode %#o): %s", path, mode, err)
+	}
+	if dir.Mode()&0777 != mode {
+		t.Errorf("Stat %q: mode %#o want %#o", path, dir.Mode(), mode)
+	}
+}
+
+func TestChmod(t *testing.T) {
+	// Chmod is not supported under windows.
+	if runtime.GOOS == "windows" {
+		return
+	}
+	f := newFile("TestChmod", t)
+	defer Remove(f.Name())
+	defer f.Close()
+
+	if err := Chmod(f.Name(), 0456); err != nil {
+		t.Fatalf("chmod %s 0456: %s", f.Name(), err)
+	}
+	checkMode(t, f.Name(), 0456)
+
+	if err := f.Chmod(0123); err != nil {
+		t.Fatalf("chmod %s 0123: %s", f.Name(), err)
+	}
+	checkMode(t, f.Name(), 0123)
+}
+
+func checkSize(t *testing.T, f *File, size int64) {
+	dir, err := f.Stat()
+	if err != nil {
+		t.Fatalf("Stat %q (looking for size %d): %s", f.Name(), size, err)
+	}
+	if dir.Size() != size {
+		t.Errorf("Stat %q: size %d want %d", f.Name(), dir.Size(), size)
+	}
+}
+
+func TestFTruncate(t *testing.T) {
+	f := newFile("TestFTruncate", t)
+	defer Remove(f.Name())
+	defer f.Close()
+
+	checkSize(t, f, 0)
+	f.Write([]byte("hello, world\n"))
+	checkSize(t, f, 13)
+	f.Truncate(10)
+	checkSize(t, f, 10)
+	f.Truncate(1024)
+	checkSize(t, f, 1024)
+	f.Truncate(0)
+	checkSize(t, f, 0)
+	_, err := f.Write([]byte("surprise!"))
+	if err == nil {
+		checkSize(t, f, 13+9) // wrote at offset past where hello, world was.
+	}
+}
+
+func TestTruncate(t *testing.T) {
+	f := newFile("TestTruncate", t)
+	defer Remove(f.Name())
+	defer f.Close()
+
+	checkSize(t, f, 0)
+	f.Write([]byte("hello, world\n"))
+	checkSize(t, f, 13)
+	Truncate(f.Name(), 10)
+	checkSize(t, f, 10)
+	Truncate(f.Name(), 1024)
+	checkSize(t, f, 1024)
+	Truncate(f.Name(), 0)
+	checkSize(t, f, 0)
+	_, err := f.Write([]byte("surprise!"))
+	if err == nil {
+		checkSize(t, f, 13+9) // wrote at offset past where hello, world was.
+	}
+}
+
+// Use TempDir (via newFile) to make sure we're on a local file system,
+// so that timings are not distorted by latency and caching.
+// On NFS, timings can be off due to caching of meta-data on
+// NFS servers (Issue 848).
+func TestChtimes(t *testing.T) {
+	f := newFile("TestChtimes", t)
+	defer Remove(f.Name())
+
+	f.Write([]byte("hello, world\n"))
+	f.Close()
+
+	testChtimes(t, f.Name())
+}
+
+// Use TempDir (via newDir) to make sure we're on a local file system,
+// so that timings are not distorted by latency and caching.
+// On NFS, timings can be off due to caching of meta-data on
+// NFS servers (Issue 848).
+func TestChtimesDir(t *testing.T) {
+	name := newDir("TestChtimes", t)
+	defer RemoveAll(name)
+
+	testChtimes(t, name)
+}
+
+func testChtimes(t *testing.T, name string) {
+	st, err := Stat(name)
+	if err != nil {
+		t.Fatalf("Stat %s: %s", name, err)
+	}
+	preStat := st
+
+	// Move access and modification time back a second
+	at := Atime(preStat)
+	mt := preStat.ModTime()
+	err = Chtimes(name, at.Add(-time.Second), mt.Add(-time.Second))
+	if err != nil {
+		t.Fatalf("Chtimes %s: %s", name, err)
+	}
+
+	st, err = Stat(name)
+	if err != nil {
+		t.Fatalf("second Stat %s: %s", name, err)
+	}
+	postStat := st
+
+	/* Plan 9, NaCl:
+		Mtime is the time of the last change of content.  Similarly, atime is set whenever the
+	    contents are accessed; also, it is set whenever mtime is set.
+	*/
+	pat := Atime(postStat)
+	pmt := postStat.ModTime()
+	if !pat.Before(at) && runtime.GOOS != "plan9" && runtime.GOOS != "nacl" {
+		t.Errorf("AccessTime didn't go backwards; was=%d, after=%d", at, pat)
+	}
+
+	if !pmt.Before(mt) {
+		t.Errorf("ModTime didn't go backwards; was=%d, after=%d", mt, pmt)
+	}
+}
+
+func TestChdirAndGetwd(t *testing.T) {
+	// TODO(brainman): file.Chdir() is not implemented on windows.
+	if runtime.GOOS == "windows" {
+		return
+	}
+	fd, err := Open(".")
+	if err != nil {
+		t.Fatalf("Open .: %s", err)
+	}
+	// These are chosen carefully not to be symlinks on a Mac
+	// (unlike, say, /var, /etc), except /tmp, which we handle below.
+	dirs := []string{"/", "/usr/bin", "/tmp"}
+	// /usr/bin does not usually exist on Plan 9 or Android.
+	switch runtime.GOOS {
+	case "android":
+		dirs = []string{"/", "/system/bin"}
+	case "plan9":
+		dirs = []string{"/", "/usr"}
+	}
+	oldwd := Getenv("PWD")
+	for mode := 0; mode < 2; mode++ {
+		for _, d := range dirs {
+			if mode == 0 {
+				err = Chdir(d)
+			} else {
+				fd1, err := Open(d)
+				if err != nil {
+					t.Errorf("Open %s: %s", d, err)
+					continue
+				}
+				err = fd1.Chdir()
+				fd1.Close()
+			}
+			if d == "/tmp" {
+				Setenv("PWD", "/tmp")
+			}
+			pwd, err1 := Getwd()
+			Setenv("PWD", oldwd)
+			err2 := fd.Chdir()
+			if err2 != nil {
+				// We changed the current directory and cannot go back.
+				// Don't let the tests continue; they'll scribble
+				// all over some other directory.
+				fmt.Fprintf(Stderr, "fchdir back to dot failed: %s\n", err2)
+				Exit(1)
+			}
+			if err != nil {
+				fd.Close()
+				t.Fatalf("Chdir %s: %s", d, err)
+			}
+			if err1 != nil {
+				fd.Close()
+				t.Fatalf("Getwd in %s: %s", d, err1)
+			}
+			if pwd != d {
+				fd.Close()
+				t.Fatalf("Getwd returned %q want %q", pwd, d)
+			}
+		}
+	}
+	fd.Close()
+}
+
+func TestSeek(t *testing.T) {
+	f := newFile("TestSeek", t)
+	defer Remove(f.Name())
+	defer f.Close()
+
+	const data = "hello, world\n"
+	io.WriteString(f, data)
+
+	type test struct {
+		in     int64
+		whence int
+		out    int64
+	}
+	var tests = []test{
+		{0, 1, int64(len(data))},
+		{0, 0, 0},
+		{5, 0, 5},
+		{0, 2, int64(len(data))},
+		{0, 0, 0},
+		{-1, 2, int64(len(data)) - 1},
+		{1 << 33, 0, 1 << 33},
+		{1 << 33, 2, 1<<33 + int64(len(data))},
+	}
+	for i, tt := range tests {
+		off, err := f.Seek(tt.in, tt.whence)
+		if off != tt.out || err != nil {
+			if e, ok := err.(*PathError); ok && e.Err == syscall.EINVAL && tt.out > 1<<32 {
+				// Reiserfs rejects the big seeks.
+				// http://code.google.com/p/go/issues/detail?id=91
+				break
+			}
+			t.Errorf("#%d: Seek(%v, %v) = %v, %v want %v, nil", i, tt.in, tt.whence, off, err, tt.out)
+		}
+	}
+}
+
+type openErrorTest struct {
+	path  string
+	mode  int
+	error error
+}
+
+var openErrorTests = []openErrorTest{
+	{
+		sfdir + "/no-such-file",
+		O_RDONLY,
+		syscall.ENOENT,
+	},
+	{
+		sfdir,
+		O_WRONLY,
+		syscall.EISDIR,
+	},
+	{
+		sfdir + "/" + sfname + "/no-such-file",
+		O_WRONLY,
+		syscall.ENOTDIR,
+	},
+}
+
+func TestOpenError(t *testing.T) {
+	for _, tt := range openErrorTests {
+		f, err := OpenFile(tt.path, tt.mode, 0)
+		if err == nil {
+			t.Errorf("Open(%q, %d) succeeded", tt.path, tt.mode)
+			f.Close()
+			continue
+		}
+		perr, ok := err.(*PathError)
+		if !ok {
+			t.Errorf("Open(%q, %d) returns error of %T type; want *PathError", tt.path, tt.mode, err)
+		}
+		if perr.Err != tt.error {
+			if runtime.GOOS == "plan9" {
+				syscallErrStr := perr.Err.Error()
+				expectedErrStr := strings.Replace(tt.error.Error(), "file ", "", 1)
+				if !strings.HasSuffix(syscallErrStr, expectedErrStr) {
+					// Some Plan 9 file servers incorrectly return
+					// EACCES rather than EISDIR when a directory is
+					// opened for write.
+					if tt.error == syscall.EISDIR && strings.HasSuffix(syscallErrStr, syscall.EACCES.Error()) {
+						continue
+					}
+					t.Errorf("Open(%q, %d) = _, %q; want suffix %q", tt.path, tt.mode, syscallErrStr, expectedErrStr)
+				}
+				continue
+			}
+			if runtime.GOOS == "dragonfly" {
+				// DragonFly incorrectly returns EACCES rather
+				// EISDIR when a directory is opened for write.
+				if tt.error == syscall.EISDIR && perr.Err == syscall.EACCES {
+					continue
+				}
+			}
+			t.Errorf("Open(%q, %d) = _, %q; want %q", tt.path, tt.mode, perr.Err.Error(), tt.error.Error())
+		}
+	}
+}
+
+func TestOpenNoName(t *testing.T) {
+	f, err := Open("")
+	if err == nil {
+		t.Fatal(`Open("") succeeded`)
+		f.Close()
+	}
+}
+
+func run(t *testing.T, cmd []string) string {
+	// Run /bin/hostname and collect output.
+	r, w, err := Pipe()
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer r.Close()
+	p, err := StartProcess("/bin/hostname", []string{"hostname"}, &ProcAttr{Files: []*File{nil, w, Stderr}})
+	if err != nil {
+		t.Fatal(err)
+	}
+	w.Close()
+
+	var b bytes.Buffer
+	io.Copy(&b, r)
+	_, err = p.Wait()
+	if err != nil {
+		t.Fatalf("run hostname Wait: %v", err)
+	}
+	err = p.Kill()
+	if err == nil {
+		t.Errorf("expected an error from Kill running 'hostname'")
+	}
+	output := b.String()
+	if n := len(output); n > 0 && output[n-1] == '\n' {
+		output = output[0 : n-1]
+	}
+	if output == "" {
+		t.Fatalf("%v produced no output", cmd)
+	}
+
+	return output
+}
+
+func TestHostname(t *testing.T) {
+	// There is no other way to fetch hostname on windows, but via winapi.
+	// On Plan 9 it can be taken from #c/sysname as Hostname() does.
+	switch runtime.GOOS {
+	case "android", "nacl", "plan9", "windows":
+		t.Skipf("skipping on %s", runtime.GOOS)
+	}
+
+	// Check internal Hostname() against the output of /bin/hostname.
+	// Allow that the internal Hostname returns a Fully Qualified Domain Name
+	// and the /bin/hostname only returns the first component
+	hostname, err := Hostname()
+	if err != nil {
+		t.Fatalf("%v", err)
+	}
+	want := run(t, []string{"/bin/hostname"})
+	if hostname != want {
+		i := strings.Index(hostname, ".")
+		if i < 0 || hostname[0:i] != want {
+			t.Errorf("Hostname() = %q, want %q", hostname, want)
+		}
+	}
+}
+
+func TestReadAt(t *testing.T) {
+	f := newFile("TestReadAt", t)
+	defer Remove(f.Name())
+	defer f.Close()
+
+	const data = "hello, world\n"
+	io.WriteString(f, data)
+
+	b := make([]byte, 5)
+	n, err := f.ReadAt(b, 7)
+	if err != nil || n != len(b) {
+		t.Fatalf("ReadAt 7: %d, %v", n, err)
+	}
+	if string(b) != "world" {
+		t.Fatalf("ReadAt 7: have %q want %q", string(b), "world")
+	}
+}
+
+func TestWriteAt(t *testing.T) {
+	f := newFile("TestWriteAt", t)
+	defer Remove(f.Name())
+	defer f.Close()
+
+	const data = "hello, world\n"
+	io.WriteString(f, data)
+
+	n, err := f.WriteAt([]byte("WORLD"), 7)
+	if err != nil || n != 5 {
+		t.Fatalf("WriteAt 7: %d, %v", n, err)
+	}
+
+	b, err := ioutil.ReadFile(f.Name())
+	if err != nil {
+		t.Fatalf("ReadFile %s: %v", f.Name(), err)
+	}
+	if string(b) != "hello, WORLD\n" {
+		t.Fatalf("after write: have %q want %q", string(b), "hello, WORLD\n")
+	}
+}
+
+func writeFile(t *testing.T, fname string, flag int, text string) string {
+	f, err := OpenFile(fname, flag, 0666)
+	if err != nil {
+		t.Fatalf("Open: %v", err)
+	}
+	n, err := io.WriteString(f, text)
+	if err != nil {
+		t.Fatalf("WriteString: %d, %v", n, err)
+	}
+	f.Close()
+	data, err := ioutil.ReadFile(fname)
+	if err != nil {
+		t.Fatalf("ReadFile: %v", err)
+	}
+	return string(data)
+}
+
+func TestAppend(t *testing.T) {
+	const f = "append.txt"
+	defer Remove(f)
+	s := writeFile(t, f, O_CREATE|O_TRUNC|O_RDWR, "new")
+	if s != "new" {
+		t.Fatalf("writeFile: have %q want %q", s, "new")
+	}
+	s = writeFile(t, f, O_APPEND|O_RDWR, "|append")
+	if s != "new|append" {
+		t.Fatalf("writeFile: have %q want %q", s, "new|append")
+	}
+	s = writeFile(t, f, O_CREATE|O_APPEND|O_RDWR, "|append")
+	if s != "new|append|append" {
+		t.Fatalf("writeFile: have %q want %q", s, "new|append|append")
+	}
+	err := Remove(f)
+	if err != nil {
+		t.Fatalf("Remove: %v", err)
+	}
+	s = writeFile(t, f, O_CREATE|O_APPEND|O_RDWR, "new&append")
+	if s != "new&append" {
+		t.Fatalf("writeFile: after append have %q want %q", s, "new&append")
+	}
+	s = writeFile(t, f, O_CREATE|O_RDWR, "old")
+	if s != "old&append" {
+		t.Fatalf("writeFile: after create have %q want %q", s, "old&append")
+	}
+	s = writeFile(t, f, O_CREATE|O_TRUNC|O_RDWR, "new")
+	if s != "new" {
+		t.Fatalf("writeFile: after truncate have %q want %q", s, "new")
+	}
+}
+
+func TestStatDirWithTrailingSlash(t *testing.T) {
+	// Create new temporary directory and arrange to clean it up.
+	path, err := ioutil.TempDir("", "/_TestStatDirWithSlash_")
+	if err != nil {
+		t.Fatalf("TempDir: %s", err)
+	}
+	defer RemoveAll(path)
+
+	// Stat of path should succeed.
+	_, err = Stat(path)
+	if err != nil {
+		t.Fatalf("stat %s failed: %s", path, err)
+	}
+
+	// Stat of path+"/" should succeed too.
+	path += "/"
+	_, err = Stat(path)
+	if err != nil {
+		t.Fatalf("stat %s failed: %s", path, err)
+	}
+}
+
+func TestNilProcessStateString(t *testing.T) {
+	var ps *ProcessState
+	s := ps.String()
+	if s != "<nil>" {
+		t.Errorf("(*ProcessState)(nil).String() = %q, want %q", s, "<nil>")
+	}
+}
+
+func TestSameFile(t *testing.T) {
+	fa, err := Create("a")
+	if err != nil {
+		t.Fatalf("Create(a): %v", err)
+	}
+	defer Remove(fa.Name())
+	fa.Close()
+	fb, err := Create("b")
+	if err != nil {
+		t.Fatalf("Create(b): %v", err)
+	}
+	defer Remove(fb.Name())
+	fb.Close()
+
+	ia1, err := Stat("a")
+	if err != nil {
+		t.Fatalf("Stat(a): %v", err)
+	}
+	ia2, err := Stat("a")
+	if err != nil {
+		t.Fatalf("Stat(a): %v", err)
+	}
+	if !SameFile(ia1, ia2) {
+		t.Errorf("files should be same")
+	}
+
+	ib, err := Stat("b")
+	if err != nil {
+		t.Fatalf("Stat(b): %v", err)
+	}
+	if SameFile(ia1, ib) {
+		t.Errorf("files should be different")
+	}
+}
+
+func TestDevNullFile(t *testing.T) {
+	f, err := Open(DevNull)
+	if err != nil {
+		t.Fatalf("Open(%s): %v", DevNull, err)
+	}
+	defer f.Close()
+	fi, err := f.Stat()
+	if err != nil {
+		t.Fatalf("Stat(%s): %v", DevNull, err)
+	}
+	name := filepath.Base(DevNull)
+	if fi.Name() != name {
+		t.Fatalf("wrong file name have %v want %v", fi.Name(), name)
+	}
+	if fi.Size() != 0 {
+		t.Fatalf("wrong file size have %d want 0", fi.Size())
+	}
+}
+
+var testLargeWrite = flag.Bool("large_write", false, "run TestLargeWriteToConsole test that floods console with output")
+
+func TestLargeWriteToConsole(t *testing.T) {
+	if !*testLargeWrite {
+		t.Skip("skipping console-flooding test; enable with -large_write")
+	}
+	b := make([]byte, 32000)
+	for i := range b {
+		b[i] = '.'
+	}
+	b[len(b)-1] = '\n'
+	n, err := Stdout.Write(b)
+	if err != nil {
+		t.Fatalf("Write to os.Stdout failed: %v", err)
+	}
+	if n != len(b) {
+		t.Errorf("Write to os.Stdout should return %d; got %d", len(b), n)
+	}
+	n, err = Stderr.Write(b)
+	if err != nil {
+		t.Fatalf("Write to os.Stderr failed: %v", err)
+	}
+	if n != len(b) {
+		t.Errorf("Write to os.Stderr should return %d; got %d", len(b), n)
+	}
+}
+
+func TestStatDirModeExec(t *testing.T) {
+	const mode = 0111
+
+	path, err := ioutil.TempDir("", "go-build")
+	if err != nil {
+		t.Fatalf("Failed to create temp directory: %v", err)
+	}
+	defer RemoveAll(path)
+
+	if err := Chmod(path, 0777); err != nil {
+		t.Fatalf("Chmod %q 0777: %v", path, err)
+	}
+
+	dir, err := Stat(path)
+	if err != nil {
+		t.Fatalf("Stat %q (looking for mode %#o): %s", path, mode, err)
+	}
+	if dir.Mode()&mode != mode {
+		t.Errorf("Stat %q: mode %#o want %#o", path, dir.Mode()&mode, mode)
+	}
+}
+
+func TestReadAtEOF(t *testing.T) {
+	f := newFile("TestReadAtEOF", t)
+	defer Remove(f.Name())
+	defer f.Close()
+
+	_, err := f.ReadAt(make([]byte, 10), 0)
+	switch err {
+	case io.EOF:
+		// all good
+	case nil:
+		t.Fatalf("ReadAt succeeded")
+	default:
+		t.Fatalf("ReadAt failed: %s", err)
+	}
+}
+
+func testKillProcess(t *testing.T, processKiller func(p *Process)) {
+	switch runtime.GOOS {
+	case "android", "nacl":
+		t.Skipf("skipping on %s", runtime.GOOS)
+	}
+
+	dir, err := ioutil.TempDir("", "go-build")
+	if err != nil {
+		t.Fatalf("Failed to create temp directory: %v", err)
+	}
+	defer RemoveAll(dir)
+
+	src := filepath.Join(dir, "main.go")
+	f, err := Create(src)
+	if err != nil {
+		t.Fatalf("Failed to create %v: %v", src, err)
+	}
+	st := template.Must(template.New("source").Parse(`
+package main
+import "time"
+func main() {
+	time.Sleep(time.Second)
+}
+`))
+	err = st.Execute(f, nil)
+	if err != nil {
+		f.Close()
+		t.Fatalf("Failed to execute template: %v", err)
+	}
+	f.Close()
+
+	exe := filepath.Join(dir, "main.exe")
+	output, err := osexec.Command("go", "build", "-o", exe, src).CombinedOutput()
+	if err != nil {
+		t.Fatalf("Failed to build exe %v: %v %v", exe, err, string(output))
+	}
+
+	cmd := osexec.Command(exe)
+	err = cmd.Start()
+	if err != nil {
+		t.Fatalf("Failed to start test process: %v", err)
+	}
+	go func() {
+		time.Sleep(100 * time.Millisecond)
+		processKiller(cmd.Process)
+	}()
+	err = cmd.Wait()
+	if err == nil {
+		t.Errorf("Test process succeeded, but expected to fail")
+	}
+}
+
+func TestKillStartProcess(t *testing.T) {
+	testKillProcess(t, func(p *Process) {
+		err := p.Kill()
+		if err != nil {
+			t.Fatalf("Failed to kill test process: %v", err)
+		}
+	})
+}
+
+func TestGetppid(t *testing.T) {
+	switch runtime.GOOS {
+	case "nacl":
+		t.Skip("skipping on nacl")
+	case "plan9":
+		// TODO: golang.org/issue/8206
+		t.Skipf("skipping test on plan9; see issue 8206")
+	}
+
+	if Getenv("GO_WANT_HELPER_PROCESS") == "1" {
+		fmt.Print(Getppid())
+		Exit(0)
+	}
+
+	cmd := osexec.Command(Args[0], "-test.run=TestGetppid")
+	cmd.Env = append(Environ(), "GO_WANT_HELPER_PROCESS=1")
+
+	// verify that Getppid() from the forked process reports our process id
+	output, err := cmd.CombinedOutput()
+	if err != nil {
+		t.Fatalf("Failed to spawn child process: %v %q", err, string(output))
+	}
+
+	childPpid := string(output)
+	ourPid := fmt.Sprintf("%d", Getpid())
+	if childPpid != ourPid {
+		t.Fatalf("Child process reports parent process id '%v', expected '%v'", childPpid, ourPid)
+	}
+}
+
+func TestKillFindProcess(t *testing.T) {
+	testKillProcess(t, func(p *Process) {
+		p2, err := FindProcess(p.Pid)
+		if err != nil {
+			t.Fatalf("Failed to find test process: %v", err)
+		}
+		err = p2.Kill()
+		if err != nil {
+			t.Fatalf("Failed to kill test process: %v", err)
+		}
+	})
+}
+
+var nilFileMethodTests = []struct {
+	name string
+	f    func(*File) error
+}{
+	{"Chdir", func(f *File) error { return f.Chdir() }},
+	{"Close", func(f *File) error { return f.Close() }},
+	{"Chmod", func(f *File) error { return f.Chmod(0) }},
+	{"Chown", func(f *File) error { return f.Chown(0, 0) }},
+	{"Read", func(f *File) error { _, err := f.Read(make([]byte, 0)); return err }},
+	{"ReadAt", func(f *File) error { _, err := f.ReadAt(make([]byte, 0), 0); return err }},
+	{"Readdir", func(f *File) error { _, err := f.Readdir(1); return err }},
+	{"Readdirnames", func(f *File) error { _, err := f.Readdirnames(1); return err }},
+	{"Seek", func(f *File) error { _, err := f.Seek(0, 0); return err }},
+	{"Stat", func(f *File) error { _, err := f.Stat(); return err }},
+	{"Sync", func(f *File) error { return f.Sync() }},
+	{"Truncate", func(f *File) error { return f.Truncate(0) }},
+	{"Write", func(f *File) error { _, err := f.Write(make([]byte, 0)); return err }},
+	{"WriteAt", func(f *File) error { _, err := f.WriteAt(make([]byte, 0), 0); return err }},
+	{"WriteString", func(f *File) error { _, err := f.WriteString(""); return err }},
+}
+
+// Test that all File methods give ErrInvalid if the receiver is nil.
+func TestNilFileMethods(t *testing.T) {
+	for _, tt := range nilFileMethodTests {
+		var file *File
+		got := tt.f(file)
+		if got != ErrInvalid {
+			t.Errorf("%v should fail when f is nil; got %v", tt.name, got)
+		}
+	}
+}
+
+func mkdirTree(t *testing.T, root string, level, max int) {
+	if level >= max {
+		return
+	}
+	level++
+	for i := 'a'; i < 'c'; i++ {
+		dir := filepath.Join(root, string(i))
+		if err := Mkdir(dir, 0700); err != nil {
+			t.Fatal(err)
+		}
+		mkdirTree(t, dir, level, max)
+	}
+}
+
+// Test that simultaneous RemoveAll do not report an error.
+// As long as it gets removed, we should be happy.
+func TestRemoveAllRace(t *testing.T) {
+	if runtime.GOOS == "windows" {
+		// Windows has very strict rules about things like
+		// removing directories while someone else has
+		// them open. The racing doesn't work out nicely
+		// like it does on Unix.
+		t.Skip("skipping on windows")
+	}
+
+	n := runtime.GOMAXPROCS(16)
+	defer runtime.GOMAXPROCS(n)
+	root, err := ioutil.TempDir("", "issue")
+	if err != nil {
+		t.Fatal(err)
+	}
+	mkdirTree(t, root, 1, 6)
+	hold := make(chan struct{})
+	var wg sync.WaitGroup
+	for i := 0; i < 4; i++ {
+		wg.Add(1)
+		go func() {
+			defer wg.Done()
+			<-hold
+			err := RemoveAll(root)
+			if err != nil {
+				t.Errorf("unexpected error: %T, %q", err, err)
+			}
+		}()
+	}
+	close(hold) // let workers race to remove root
+	wg.Wait()
+}
diff --git a/src/pkg/os/os_unix_test.go b/src/os/os_unix_test.go
similarity index 100%
rename from src/pkg/os/os_unix_test.go
rename to src/os/os_unix_test.go
diff --git a/src/os/os_windows_test.go b/src/os/os_windows_test.go
new file mode 100644
index 0000000..fd96713
--- /dev/null
+++ b/src/os/os_windows_test.go
@@ -0,0 +1,81 @@
+package os_test
+
+import (
+	"io/ioutil"
+	"os"
+	"path/filepath"
+	"syscall"
+	"testing"
+)
+
+func init() {
+	tmpdir, err := ioutil.TempDir("", "symtest")
+	if err != nil {
+		panic("failed to create temp directory: " + err.Error())
+	}
+	defer os.RemoveAll(tmpdir)
+
+	err = os.Symlink("target", filepath.Join(tmpdir, "symlink"))
+	if err == nil {
+		return
+	}
+
+	err = err.(*os.LinkError).Err
+	switch err {
+	case syscall.EWINDOWS, syscall.ERROR_PRIVILEGE_NOT_HELD:
+		supportsSymlinks = false
+	}
+}
+
+func TestSameWindowsFile(t *testing.T) {
+	temp, err := ioutil.TempDir("", "TestSameWindowsFile")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.RemoveAll(temp)
+
+	wd, err := os.Getwd()
+	if err != nil {
+		t.Fatal(err)
+	}
+	err = os.Chdir(temp)
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.Chdir(wd)
+
+	f, err := os.Create("a")
+	if err != nil {
+		t.Fatal(err)
+	}
+	f.Close()
+
+	ia1, err := os.Stat("a")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	path, err := filepath.Abs("a")
+	if err != nil {
+		t.Fatal(err)
+	}
+	ia2, err := os.Stat(path)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if !os.SameFile(ia1, ia2) {
+		t.Errorf("files should be same")
+	}
+
+	p := filepath.VolumeName(path) + filepath.Base(path)
+	if err != nil {
+		t.Fatal(err)
+	}
+	ia3, err := os.Stat(p)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if !os.SameFile(ia1, ia3) {
+		t.Errorf("files should be same")
+	}
+}
diff --git a/src/os/path.go b/src/os/path.go
new file mode 100644
index 0000000..84a3be3
--- /dev/null
+++ b/src/os/path.go
@@ -0,0 +1,131 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package os
+
+import (
+	"io"
+	"syscall"
+)
+
+// MkdirAll creates a directory named path,
+// along with any necessary parents, and returns nil,
+// or else returns an error.
+// The permission bits perm are used for all
+// directories that MkdirAll creates.
+// If path is already a directory, MkdirAll does nothing
+// and returns nil.
+func MkdirAll(path string, perm FileMode) error {
+	// Fast path: if we can tell whether path is a directory or file, stop with success or error.
+	dir, err := Stat(path)
+	if err == nil {
+		if dir.IsDir() {
+			return nil
+		}
+		return &PathError{"mkdir", path, syscall.ENOTDIR}
+	}
+
+	// Slow path: make sure parent exists and then call Mkdir for path.
+	i := len(path)
+	for i > 0 && IsPathSeparator(path[i-1]) { // Skip trailing path separator.
+		i--
+	}
+
+	j := i
+	for j > 0 && !IsPathSeparator(path[j-1]) { // Scan backward over element.
+		j--
+	}
+
+	if j > 1 {
+		// Create parent
+		err = MkdirAll(path[0:j-1], perm)
+		if err != nil {
+			return err
+		}
+	}
+
+	// Parent now exists; invoke Mkdir and use its result.
+	err = Mkdir(path, perm)
+	if err != nil {
+		// Handle arguments like "foo/." by
+		// double-checking that directory doesn't exist.
+		dir, err1 := Lstat(path)
+		if err1 == nil && dir.IsDir() {
+			return nil
+		}
+		return err
+	}
+	return nil
+}
+
+// RemoveAll removes path and any children it contains.
+// It removes everything it can but returns the first error
+// it encounters.  If the path does not exist, RemoveAll
+// returns nil (no error).
+func RemoveAll(path string) error {
+	// Simple case: if Remove works, we're done.
+	err := Remove(path)
+	if err == nil || IsNotExist(err) {
+		return nil
+	}
+
+	// Otherwise, is this a directory we need to recurse into?
+	dir, serr := Lstat(path)
+	if serr != nil {
+		if serr, ok := serr.(*PathError); ok && (IsNotExist(serr.Err) || serr.Err == syscall.ENOTDIR) {
+			return nil
+		}
+		return serr
+	}
+	if !dir.IsDir() {
+		// Not a directory; return the error from Remove.
+		return err
+	}
+
+	// Directory.
+	fd, err := Open(path)
+	if err != nil {
+		if IsNotExist(err) {
+			// Race. It was deleted between the Lstat and Open.
+			// Return nil per RemoveAll's docs.
+			return nil
+		}
+		return err
+	}
+
+	// Remove contents & return first error.
+	err = nil
+	for {
+		names, err1 := fd.Readdirnames(100)
+		for _, name := range names {
+			err1 := RemoveAll(path + string(PathSeparator) + name)
+			if err == nil {
+				err = err1
+			}
+		}
+		if err1 == io.EOF {
+			break
+		}
+		// If Readdirnames returned an error, use it.
+		if err == nil {
+			err = err1
+		}
+		if len(names) == 0 {
+			break
+		}
+	}
+
+	// Close directory, because windows won't remove opened directory.
+	fd.Close()
+
+	// Remove directory.
+	err1 := Remove(path)
+	if err1 == nil || IsNotExist(err1) {
+		return nil
+	}
+	if err == nil {
+		err = err1
+	}
+	return err
+}
diff --git a/src/pkg/os/path_plan9.go b/src/os/path_plan9.go
similarity index 100%
rename from src/pkg/os/path_plan9.go
rename to src/os/path_plan9.go
diff --git a/src/os/path_test.go b/src/os/path_test.go
new file mode 100644
index 0000000..6f24a43
--- /dev/null
+++ b/src/os/path_test.go
@@ -0,0 +1,220 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package os_test
+
+import (
+	"io/ioutil"
+	. "os"
+	"path/filepath"
+	"runtime"
+	"syscall"
+	"testing"
+)
+
+func TestMkdirAll(t *testing.T) {
+	tmpDir := TempDir()
+	path := tmpDir + "/_TestMkdirAll_/dir/./dir2"
+	err := MkdirAll(path, 0777)
+	if err != nil {
+		t.Fatalf("MkdirAll %q: %s", path, err)
+	}
+	defer RemoveAll(tmpDir + "/_TestMkdirAll_")
+
+	// Already exists, should succeed.
+	err = MkdirAll(path, 0777)
+	if err != nil {
+		t.Fatalf("MkdirAll %q (second time): %s", path, err)
+	}
+
+	// Make file.
+	fpath := path + "/file"
+	f, err := Create(fpath)
+	if err != nil {
+		t.Fatalf("create %q: %s", fpath, err)
+	}
+	defer f.Close()
+
+	// Can't make directory named after file.
+	err = MkdirAll(fpath, 0777)
+	if err == nil {
+		t.Fatalf("MkdirAll %q: no error", fpath)
+	}
+	perr, ok := err.(*PathError)
+	if !ok {
+		t.Fatalf("MkdirAll %q returned %T, not *PathError", fpath, err)
+	}
+	if filepath.Clean(perr.Path) != filepath.Clean(fpath) {
+		t.Fatalf("MkdirAll %q returned wrong error path: %q not %q", fpath, filepath.Clean(perr.Path), filepath.Clean(fpath))
+	}
+
+	// Can't make subdirectory of file.
+	ffpath := fpath + "/subdir"
+	err = MkdirAll(ffpath, 0777)
+	if err == nil {
+		t.Fatalf("MkdirAll %q: no error", ffpath)
+	}
+	perr, ok = err.(*PathError)
+	if !ok {
+		t.Fatalf("MkdirAll %q returned %T, not *PathError", ffpath, err)
+	}
+	if filepath.Clean(perr.Path) != filepath.Clean(fpath) {
+		t.Fatalf("MkdirAll %q returned wrong error path: %q not %q", ffpath, filepath.Clean(perr.Path), filepath.Clean(fpath))
+	}
+
+	if runtime.GOOS == "windows" {
+		path := tmpDir + `\_TestMkdirAll_\dir\.\dir2\`
+		err := MkdirAll(path, 0777)
+		if err != nil {
+			t.Fatalf("MkdirAll %q: %s", path, err)
+		}
+	}
+}
+
+func TestRemoveAll(t *testing.T) {
+	tmpDir := TempDir()
+	// Work directory.
+	path := tmpDir + "/_TestRemoveAll_"
+	fpath := path + "/file"
+	dpath := path + "/dir"
+
+	// Make directory with 1 file and remove.
+	if err := MkdirAll(path, 0777); err != nil {
+		t.Fatalf("MkdirAll %q: %s", path, err)
+	}
+	fd, err := Create(fpath)
+	if err != nil {
+		t.Fatalf("create %q: %s", fpath, err)
+	}
+	fd.Close()
+	if err = RemoveAll(path); err != nil {
+		t.Fatalf("RemoveAll %q (first): %s", path, err)
+	}
+	if _, err = Lstat(path); err == nil {
+		t.Fatalf("Lstat %q succeeded after RemoveAll (first)", path)
+	}
+
+	// Make directory with file and subdirectory and remove.
+	if err = MkdirAll(dpath, 0777); err != nil {
+		t.Fatalf("MkdirAll %q: %s", dpath, err)
+	}
+	fd, err = Create(fpath)
+	if err != nil {
+		t.Fatalf("create %q: %s", fpath, err)
+	}
+	fd.Close()
+	fd, err = Create(dpath + "/file")
+	if err != nil {
+		t.Fatalf("create %q: %s", fpath, err)
+	}
+	fd.Close()
+	if err = RemoveAll(path); err != nil {
+		t.Fatalf("RemoveAll %q (second): %s", path, err)
+	}
+	if _, err := Lstat(path); err == nil {
+		t.Fatalf("Lstat %q succeeded after RemoveAll (second)", path)
+	}
+
+	// Determine if we should run the following test.
+	testit := true
+	if runtime.GOOS == "windows" {
+		// Chmod is not supported under windows.
+		testit = false
+	} else {
+		// Test fails as root.
+		testit = Getuid() != 0
+	}
+	if testit {
+		// Make directory with file and subdirectory and trigger error.
+		if err = MkdirAll(dpath, 0777); err != nil {
+			t.Fatalf("MkdirAll %q: %s", dpath, err)
+		}
+
+		for _, s := range []string{fpath, dpath + "/file1", path + "/zzz"} {
+			fd, err = Create(s)
+			if err != nil {
+				t.Fatalf("create %q: %s", s, err)
+			}
+			fd.Close()
+		}
+		if err = Chmod(dpath, 0); err != nil {
+			t.Fatalf("Chmod %q 0: %s", dpath, err)
+		}
+
+		// No error checking here: either RemoveAll
+		// will or won't be able to remove dpath;
+		// either way we want to see if it removes fpath
+		// and path/zzz.  Reasons why RemoveAll might
+		// succeed in removing dpath as well include:
+		//	* running as root
+		//	* running on a file system without permissions (FAT)
+		RemoveAll(path)
+		Chmod(dpath, 0777)
+
+		for _, s := range []string{fpath, path + "/zzz"} {
+			if _, err = Lstat(s); err == nil {
+				t.Fatalf("Lstat %q succeeded after partial RemoveAll", s)
+			}
+		}
+	}
+	if err = RemoveAll(path); err != nil {
+		t.Fatalf("RemoveAll %q after partial RemoveAll: %s", path, err)
+	}
+	if _, err = Lstat(path); err == nil {
+		t.Fatalf("Lstat %q succeeded after RemoveAll (final)", path)
+	}
+}
+
+func TestMkdirAllWithSymlink(t *testing.T) {
+	switch runtime.GOOS {
+	case "nacl", "plan9":
+		t.Skipf("skipping on %s", runtime.GOOS)
+	case "windows":
+		if !supportsSymlinks {
+			t.Skipf("skipping on %s", runtime.GOOS)
+		}
+	}
+
+	tmpDir, err := ioutil.TempDir("", "TestMkdirAllWithSymlink-")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer RemoveAll(tmpDir)
+
+	dir := tmpDir + "/dir"
+	err = Mkdir(dir, 0755)
+	if err != nil {
+		t.Fatalf("Mkdir %s: %s", dir, err)
+	}
+
+	link := tmpDir + "/link"
+	err = Symlink("dir", link)
+	if err != nil {
+		t.Fatalf("Symlink %s: %s", link, err)
+	}
+
+	path := link + "/foo"
+	err = MkdirAll(path, 0755)
+	if err != nil {
+		t.Errorf("MkdirAll %q: %s", path, err)
+	}
+}
+
+func TestMkdirAllAtSlash(t *testing.T) {
+	switch runtime.GOOS {
+	case "android", "plan9", "windows":
+		t.Skipf("skipping on %s", runtime.GOOS)
+	}
+	RemoveAll("/_go_os_test")
+	err := MkdirAll("/_go_os_test/dir", 0777)
+	if err != nil {
+		pathErr, ok := err.(*PathError)
+		// common for users not to be able to write to /
+		if ok && pathErr.Err == syscall.EACCES {
+			return
+		}
+		t.Fatalf(`MkdirAll "/_go_os_test/dir": %v`, err)
+	}
+	RemoveAll("/_go_os_test")
+}
diff --git a/src/pkg/os/path_unix.go b/src/os/path_unix.go
similarity index 100%
rename from src/pkg/os/path_unix.go
rename to src/os/path_unix.go
diff --git a/src/pkg/os/path_windows.go b/src/os/path_windows.go
similarity index 100%
rename from src/pkg/os/path_windows.go
rename to src/os/path_windows.go
diff --git a/src/pkg/os/pipe_bsd.go b/src/os/pipe_bsd.go
similarity index 100%
rename from src/pkg/os/pipe_bsd.go
rename to src/os/pipe_bsd.go
diff --git a/src/pkg/os/pipe_linux.go b/src/os/pipe_linux.go
similarity index 100%
rename from src/pkg/os/pipe_linux.go
rename to src/os/pipe_linux.go
diff --git a/src/os/proc.go b/src/os/proc.go
new file mode 100644
index 0000000..774f099
--- /dev/null
+++ b/src/os/proc.go
@@ -0,0 +1,49 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Process etc.
+
+package os
+
+import (
+	"runtime"
+	"syscall"
+)
+
+// Args hold the command-line arguments, starting with the program name.
+var Args []string
+
+func init() {
+	if runtime.GOOS == "windows" {
+		// Initialized in exec_windows.go.
+		return
+	}
+	Args = runtime_args()
+}
+
+func runtime_args() []string // in package runtime
+
+// Getuid returns the numeric user id of the caller.
+func Getuid() int { return syscall.Getuid() }
+
+// Geteuid returns the numeric effective user id of the caller.
+func Geteuid() int { return syscall.Geteuid() }
+
+// Getgid returns the numeric group id of the caller.
+func Getgid() int { return syscall.Getgid() }
+
+// Getegid returns the numeric effective group id of the caller.
+func Getegid() int { return syscall.Getegid() }
+
+// Getgroups returns a list of the numeric ids of groups that the caller belongs to.
+func Getgroups() ([]int, error) {
+	gids, e := syscall.Getgroups()
+	return gids, NewSyscallError("getgroups", e)
+}
+
+// Exit causes the current program to exit with the given status code.
+// Conventionally, code zero indicates success, non-zero an error.
+// The program terminates immediately; deferred functions are
+// not run.
+func Exit(code int) { syscall.Exit(code) }
diff --git a/src/pkg/os/signal/example_test.go b/src/os/signal/example_test.go
similarity index 100%
rename from src/pkg/os/signal/example_test.go
rename to src/os/signal/example_test.go
diff --git a/src/os/signal/sig.s b/src/os/signal/sig.s
new file mode 100644
index 0000000..d54c284
--- /dev/null
+++ b/src/os/signal/sig.s
@@ -0,0 +1,23 @@
+// Copyright 2012 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Assembly to get into package runtime without using exported symbols.
+
+// +build amd64 amd64p32 arm 386
+
+#include "textflag.h"
+
+#ifdef GOARCH_arm
+#define JMP B
+#endif
+
+TEXT ·signal_disable(SB),NOSPLIT,$0
+	JMP runtime·signal_disable(SB)
+
+TEXT ·signal_enable(SB),NOSPLIT,$0
+	JMP runtime·signal_enable(SB)
+
+TEXT ·signal_recv(SB),NOSPLIT,$0
+	JMP runtime·signal_recv(SB)
+
diff --git a/src/pkg/os/signal/signal.go b/src/os/signal/signal.go
similarity index 100%
rename from src/pkg/os/signal/signal.go
rename to src/os/signal/signal.go
diff --git a/src/pkg/os/signal/signal_stub.go b/src/os/signal/signal_stub.go
similarity index 100%
rename from src/pkg/os/signal/signal_stub.go
rename to src/os/signal/signal_stub.go
diff --git a/src/os/signal/signal_test.go b/src/os/signal/signal_test.go
new file mode 100644
index 0000000..22337a7
--- /dev/null
+++ b/src/os/signal/signal_test.go
@@ -0,0 +1,208 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin dragonfly freebsd linux netbsd openbsd solaris
+
+package signal
+
+import (
+	"flag"
+	"io/ioutil"
+	"os"
+	"os/exec"
+	"runtime"
+	"strconv"
+	"syscall"
+	"testing"
+	"time"
+)
+
+func waitSig(t *testing.T, c <-chan os.Signal, sig os.Signal) {
+	select {
+	case s := <-c:
+		if s != sig {
+			t.Fatalf("signal was %v, want %v", s, sig)
+		}
+	case <-time.After(1 * time.Second):
+		t.Fatalf("timeout waiting for %v", sig)
+	}
+}
+
+// Test that basic signal handling works.
+func TestSignal(t *testing.T) {
+	// Ask for SIGHUP
+	c := make(chan os.Signal, 1)
+	Notify(c, syscall.SIGHUP)
+	defer Stop(c)
+
+	// Send this process a SIGHUP
+	t.Logf("sighup...")
+	syscall.Kill(syscall.Getpid(), syscall.SIGHUP)
+	waitSig(t, c, syscall.SIGHUP)
+
+	// Ask for everything we can get.
+	c1 := make(chan os.Signal, 1)
+	Notify(c1)
+
+	// Send this process a SIGWINCH
+	t.Logf("sigwinch...")
+	syscall.Kill(syscall.Getpid(), syscall.SIGWINCH)
+	waitSig(t, c1, syscall.SIGWINCH)
+
+	// Send two more SIGHUPs, to make sure that
+	// they get delivered on c1 and that not reading
+	// from c does not block everything.
+	t.Logf("sighup...")
+	syscall.Kill(syscall.Getpid(), syscall.SIGHUP)
+	waitSig(t, c1, syscall.SIGHUP)
+	t.Logf("sighup...")
+	syscall.Kill(syscall.Getpid(), syscall.SIGHUP)
+	waitSig(t, c1, syscall.SIGHUP)
+
+	// The first SIGHUP should be waiting for us on c.
+	waitSig(t, c, syscall.SIGHUP)
+}
+
+func TestStress(t *testing.T) {
+	dur := 3 * time.Second
+	if testing.Short() {
+		dur = 100 * time.Millisecond
+	}
+	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4))
+	done := make(chan bool)
+	finished := make(chan bool)
+	go func() {
+		sig := make(chan os.Signal, 1)
+		Notify(sig, syscall.SIGUSR1)
+		defer Stop(sig)
+	Loop:
+		for {
+			select {
+			case <-sig:
+			case <-done:
+				break Loop
+			}
+		}
+		finished <- true
+	}()
+	go func() {
+	Loop:
+		for {
+			select {
+			case <-done:
+				break Loop
+			default:
+				syscall.Kill(syscall.Getpid(), syscall.SIGUSR1)
+				runtime.Gosched()
+			}
+		}
+		finished <- true
+	}()
+	time.Sleep(dur)
+	close(done)
+	<-finished
+	<-finished
+	// When run with 'go test -cpu=1,2,4' SIGUSR1 from this test can slip
+	// into subsequent TestSignal() causing failure.
+	// Sleep for a while to reduce the possibility of the failure.
+	time.Sleep(10 * time.Millisecond)
+}
+
+var sendUncaughtSighup = flag.Int("send_uncaught_sighup", 0, "send uncaught SIGHUP during TestStop")
+
+// Test that Stop cancels the channel's registrations.
+func TestStop(t *testing.T) {
+	sigs := []syscall.Signal{
+		syscall.SIGWINCH,
+		syscall.SIGHUP,
+	}
+
+	for _, sig := range sigs {
+		// Send the signal.
+		// If it's SIGWINCH, we should not see it.
+		// If it's SIGHUP, maybe we'll die. Let the flag tell us what to do.
+		if sig != syscall.SIGHUP || *sendUncaughtSighup == 1 {
+			syscall.Kill(syscall.Getpid(), sig)
+		}
+		time.Sleep(100 * time.Millisecond)
+
+		// Ask for signal
+		c := make(chan os.Signal, 1)
+		Notify(c, sig)
+		defer Stop(c)
+
+		// Send this process that signal
+		syscall.Kill(syscall.Getpid(), sig)
+		waitSig(t, c, sig)
+
+		Stop(c)
+		select {
+		case s := <-c:
+			t.Fatalf("unexpected signal %v", s)
+		case <-time.After(100 * time.Millisecond):
+			// nothing to read - good
+		}
+
+		// Send the signal.
+		// If it's SIGWINCH, we should not see it.
+		// If it's SIGHUP, maybe we'll die. Let the flag tell us what to do.
+		if sig != syscall.SIGHUP || *sendUncaughtSighup == 2 {
+			syscall.Kill(syscall.Getpid(), sig)
+		}
+
+		select {
+		case s := <-c:
+			t.Fatalf("unexpected signal %v", s)
+		case <-time.After(100 * time.Millisecond):
+			// nothing to read - good
+		}
+	}
+}
+
+// Test that when run under nohup, an uncaught SIGHUP does not kill the program,
+// but a
+func TestNohup(t *testing.T) {
+	// Ugly: ask for SIGHUP so that child will not have no-hup set
+	// even if test is running under nohup environment.
+	// We have no intention of reading from c.
+	c := make(chan os.Signal, 1)
+	Notify(c, syscall.SIGHUP)
+
+	// When run without nohup, the test should crash on an uncaught SIGHUP.
+	// When run under nohup, the test should ignore uncaught SIGHUPs,
+	// because the runtime is not supposed to be listening for them.
+	// Either way, TestStop should still be able to catch them when it wants them
+	// and then when it stops wanting them, the original behavior should resume.
+	//
+	// send_uncaught_sighup=1 sends the SIGHUP before starting to listen for SIGHUPs.
+	// send_uncaught_sighup=2 sends the SIGHUP after no longer listening for SIGHUPs.
+	//
+	// Both should fail without nohup and succeed with nohup.
+
+	for i := 1; i <= 2; i++ {
+		out, err := exec.Command(os.Args[0], "-test.run=TestStop", "-send_uncaught_sighup="+strconv.Itoa(i)).CombinedOutput()
+		if err == nil {
+			t.Fatalf("ran test with -send_uncaught_sighup=%d and it succeeded: expected failure.\nOutput:\n%s", i, out)
+		}
+	}
+
+	Stop(c)
+
+	// Again, this time with nohup, assuming we can find it.
+	_, err := os.Stat("/usr/bin/nohup")
+	if err != nil {
+		t.Skip("cannot find nohup; skipping second half of test")
+	}
+
+	for i := 1; i <= 2; i++ {
+		os.Remove("nohup.out")
+		out, err := exec.Command("/usr/bin/nohup", os.Args[0], "-test.run=TestStop", "-send_uncaught_sighup="+strconv.Itoa(i)).CombinedOutput()
+
+		data, _ := ioutil.ReadFile("nohup.out")
+		os.Remove("nohup.out")
+		if err != nil {
+			t.Fatalf("ran test with -send_uncaught_sighup=%d under nohup and it failed: expected success.\nError: %v\nOutput:\n%s%s", i, err, out, data)
+		}
+	}
+}
diff --git a/src/pkg/os/signal/signal_unix.go b/src/os/signal/signal_unix.go
similarity index 100%
rename from src/pkg/os/signal/signal_unix.go
rename to src/os/signal/signal_unix.go
diff --git a/src/pkg/os/signal/signal_windows_test.go b/src/os/signal/signal_windows_test.go
similarity index 100%
rename from src/pkg/os/signal/signal_windows_test.go
rename to src/os/signal/signal_windows_test.go
diff --git a/src/pkg/os/stat_darwin.go b/src/os/stat_darwin.go
similarity index 100%
rename from src/pkg/os/stat_darwin.go
rename to src/os/stat_darwin.go
diff --git a/src/pkg/os/stat_dragonfly.go b/src/os/stat_dragonfly.go
similarity index 100%
rename from src/pkg/os/stat_dragonfly.go
rename to src/os/stat_dragonfly.go
diff --git a/src/pkg/os/stat_freebsd.go b/src/os/stat_freebsd.go
similarity index 100%
rename from src/pkg/os/stat_freebsd.go
rename to src/os/stat_freebsd.go
diff --git a/src/pkg/os/stat_linux.go b/src/os/stat_linux.go
similarity index 100%
rename from src/pkg/os/stat_linux.go
rename to src/os/stat_linux.go
diff --git a/src/pkg/os/stat_nacl.go b/src/os/stat_nacl.go
similarity index 100%
rename from src/pkg/os/stat_nacl.go
rename to src/os/stat_nacl.go
diff --git a/src/pkg/os/stat_netbsd.go b/src/os/stat_netbsd.go
similarity index 100%
rename from src/pkg/os/stat_netbsd.go
rename to src/os/stat_netbsd.go
diff --git a/src/pkg/os/stat_openbsd.go b/src/os/stat_openbsd.go
similarity index 100%
rename from src/pkg/os/stat_openbsd.go
rename to src/os/stat_openbsd.go
diff --git a/src/pkg/os/stat_plan9.go b/src/os/stat_plan9.go
similarity index 100%
rename from src/pkg/os/stat_plan9.go
rename to src/os/stat_plan9.go
diff --git a/src/pkg/os/stat_solaris.go b/src/os/stat_solaris.go
similarity index 100%
rename from src/pkg/os/stat_solaris.go
rename to src/os/stat_solaris.go
diff --git a/src/os/stat_windows.go b/src/os/stat_windows.go
new file mode 100644
index 0000000..f396c1d
--- /dev/null
+++ b/src/os/stat_windows.go
@@ -0,0 +1,170 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package os
+
+import (
+	"syscall"
+	"unsafe"
+)
+
+// Stat returns the FileInfo structure describing file.
+// If there is an error, it will be of type *PathError.
+func (file *File) Stat() (fi FileInfo, err error) {
+	if file == nil {
+		return nil, ErrInvalid
+	}
+	if file == nil || file.fd < 0 {
+		return nil, syscall.EINVAL
+	}
+	if file.isdir() {
+		// I don't know any better way to do that for directory
+		return Stat(file.name)
+	}
+	if file.name == DevNull {
+		return &devNullStat, nil
+	}
+	var d syscall.ByHandleFileInformation
+	e := syscall.GetFileInformationByHandle(syscall.Handle(file.fd), &d)
+	if e != nil {
+		return nil, &PathError{"GetFileInformationByHandle", file.name, e}
+	}
+	return &fileStat{
+		name: basename(file.name),
+		sys: syscall.Win32FileAttributeData{
+			FileAttributes: d.FileAttributes,
+			CreationTime:   d.CreationTime,
+			LastAccessTime: d.LastAccessTime,
+			LastWriteTime:  d.LastWriteTime,
+			FileSizeHigh:   d.FileSizeHigh,
+			FileSizeLow:    d.FileSizeLow,
+		},
+		vol:   d.VolumeSerialNumber,
+		idxhi: d.FileIndexHigh,
+		idxlo: d.FileIndexLow,
+	}, nil
+}
+
+// Stat returns a FileInfo structure describing the named file.
+// If there is an error, it will be of type *PathError.
+func Stat(name string) (fi FileInfo, err error) {
+	for {
+		fi, err = Lstat(name)
+		if err != nil {
+			return
+		}
+		if fi.Mode()&ModeSymlink == 0 {
+			return
+		}
+		name, err = Readlink(name)
+		if err != nil {
+			return
+		}
+	}
+	return fi, err
+}
+
+// Lstat returns the FileInfo structure describing the named file.
+// If the file is a symbolic link, the returned FileInfo
+// describes the symbolic link.  Lstat makes no attempt to follow the link.
+// If there is an error, it will be of type *PathError.
+func Lstat(name string) (fi FileInfo, err error) {
+	if len(name) == 0 {
+		return nil, &PathError{"Lstat", name, syscall.Errno(syscall.ERROR_PATH_NOT_FOUND)}
+	}
+	if name == DevNull {
+		return &devNullStat, nil
+	}
+	fs := &fileStat{name: basename(name)}
+	namep, e := syscall.UTF16PtrFromString(name)
+	if e != nil {
+		return nil, &PathError{"Lstat", name, e}
+	}
+	e = syscall.GetFileAttributesEx(namep, syscall.GetFileExInfoStandard, (*byte)(unsafe.Pointer(&fs.sys)))
+	if e != nil {
+		return nil, &PathError{"GetFileAttributesEx", name, e}
+	}
+	fs.path = name
+	if !isAbs(fs.path) {
+		fs.path, e = syscall.FullPath(fs.path)
+		if e != nil {
+			return nil, e
+		}
+	}
+	return fs, nil
+}
+
+// basename removes trailing slashes and the leading
+// directory name and drive letter from path name.
+func basename(name string) string {
+	// Remove drive letter
+	if len(name) == 2 && name[1] == ':' {
+		name = "."
+	} else if len(name) > 2 && name[1] == ':' {
+		name = name[2:]
+	}
+	i := len(name) - 1
+	// Remove trailing slashes
+	for ; i > 0 && (name[i] == '/' || name[i] == '\\'); i-- {
+		name = name[:i]
+	}
+	// Remove leading directory name
+	for i--; i >= 0; i-- {
+		if name[i] == '/' || name[i] == '\\' {
+			name = name[i+1:]
+			break
+		}
+	}
+	return name
+}
+
+func isAbs(path string) (b bool) {
+	v := volumeName(path)
+	if v == "" {
+		return false
+	}
+	path = path[len(v):]
+	if path == "" {
+		return false
+	}
+	return IsPathSeparator(path[0])
+}
+
+func volumeName(path string) (v string) {
+	if len(path) < 2 {
+		return ""
+	}
+	// with drive letter
+	c := path[0]
+	if path[1] == ':' &&
+		('0' <= c && c <= '9' || 'a' <= c && c <= 'z' ||
+			'A' <= c && c <= 'Z') {
+		return path[:2]
+	}
+	// is it UNC
+	if l := len(path); l >= 5 && IsPathSeparator(path[0]) && IsPathSeparator(path[1]) &&
+		!IsPathSeparator(path[2]) && path[2] != '.' {
+		// first, leading `\\` and next shouldn't be `\`. its server name.
+		for n := 3; n < l-1; n++ {
+			// second, next '\' shouldn't be repeated.
+			if IsPathSeparator(path[n]) {
+				n++
+				// third, following something characters. its share name.
+				if !IsPathSeparator(path[n]) {
+					if path[n] == '.' {
+						break
+					}
+					for ; n < l; n++ {
+						if IsPathSeparator(path[n]) {
+							break
+						}
+					}
+					return path[:n]
+				}
+				break
+			}
+		}
+	}
+	return ""
+}
diff --git a/src/pkg/os/str.go b/src/os/str.go
similarity index 100%
rename from src/pkg/os/str.go
rename to src/os/str.go
diff --git a/src/pkg/os/sys_bsd.go b/src/os/sys_bsd.go
similarity index 100%
rename from src/pkg/os/sys_bsd.go
rename to src/os/sys_bsd.go
diff --git a/src/pkg/os/sys_darwin.go b/src/os/sys_darwin.go
similarity index 100%
rename from src/pkg/os/sys_darwin.go
rename to src/os/sys_darwin.go
diff --git a/src/pkg/os/sys_freebsd.go b/src/os/sys_freebsd.go
similarity index 100%
rename from src/pkg/os/sys_freebsd.go
rename to src/os/sys_freebsd.go
diff --git a/src/pkg/os/sys_linux.go b/src/os/sys_linux.go
similarity index 100%
rename from src/pkg/os/sys_linux.go
rename to src/os/sys_linux.go
diff --git a/src/pkg/os/sys_nacl.go b/src/os/sys_nacl.go
similarity index 100%
rename from src/pkg/os/sys_nacl.go
rename to src/os/sys_nacl.go
diff --git a/src/pkg/os/sys_plan9.go b/src/os/sys_plan9.go
similarity index 100%
rename from src/pkg/os/sys_plan9.go
rename to src/os/sys_plan9.go
diff --git a/src/pkg/os/sys_solaris.go b/src/os/sys_solaris.go
similarity index 100%
rename from src/pkg/os/sys_solaris.go
rename to src/os/sys_solaris.go
diff --git a/src/pkg/os/sys_unix.go b/src/os/sys_unix.go
similarity index 100%
rename from src/pkg/os/sys_unix.go
rename to src/os/sys_unix.go
diff --git a/src/pkg/os/sys_windows.go b/src/os/sys_windows.go
similarity index 100%
rename from src/pkg/os/sys_windows.go
rename to src/os/sys_windows.go
diff --git a/src/pkg/os/types.go b/src/os/types.go
similarity index 100%
rename from src/pkg/os/types.go
rename to src/os/types.go
diff --git a/src/pkg/os/types_notwin.go b/src/os/types_notwin.go
similarity index 100%
rename from src/pkg/os/types_notwin.go
rename to src/os/types_notwin.go
diff --git a/src/os/types_windows.go b/src/os/types_windows.go
new file mode 100644
index 0000000..7b2e546
--- /dev/null
+++ b/src/os/types_windows.go
@@ -0,0 +1,107 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package os
+
+import (
+	"sync"
+	"syscall"
+	"time"
+)
+
+// A fileStat is the implementation of FileInfo returned by Stat and Lstat.
+type fileStat struct {
+	name string
+	sys  syscall.Win32FileAttributeData
+
+	// used to implement SameFile
+	sync.Mutex
+	path  string
+	vol   uint32
+	idxhi uint32
+	idxlo uint32
+}
+
+func (fs *fileStat) Size() int64 {
+	return int64(fs.sys.FileSizeHigh)<<32 + int64(fs.sys.FileSizeLow)
+}
+
+func (fs *fileStat) Mode() (m FileMode) {
+	if fs == &devNullStat {
+		return ModeDevice | ModeCharDevice | 0666
+	}
+	if fs.sys.FileAttributes&syscall.FILE_ATTRIBUTE_DIRECTORY != 0 {
+		m |= ModeDir | 0111
+	}
+	if fs.sys.FileAttributes&syscall.FILE_ATTRIBUTE_READONLY != 0 {
+		m |= 0444
+	} else {
+		m |= 0666
+	}
+	if fs.sys.FileAttributes&syscall.FILE_ATTRIBUTE_REPARSE_POINT != 0 {
+		m |= ModeSymlink
+	}
+	return m
+}
+
+func (fs *fileStat) ModTime() time.Time {
+	return time.Unix(0, fs.sys.LastWriteTime.Nanoseconds())
+}
+
+// Sys returns syscall.Win32FileAttributeData for file fs.
+func (fs *fileStat) Sys() interface{} { return &fs.sys }
+
+func (fs *fileStat) loadFileId() error {
+	fs.Lock()
+	defer fs.Unlock()
+	if fs.path == "" {
+		// already done
+		return nil
+	}
+	pathp, err := syscall.UTF16PtrFromString(fs.path)
+	if err != nil {
+		return err
+	}
+	h, err := syscall.CreateFile(pathp, 0, 0, nil, syscall.OPEN_EXISTING, syscall.FILE_FLAG_BACKUP_SEMANTICS, 0)
+	if err != nil {
+		return err
+	}
+	defer syscall.CloseHandle(h)
+	var i syscall.ByHandleFileInformation
+	err = syscall.GetFileInformationByHandle(syscall.Handle(h), &i)
+	if err != nil {
+		return err
+	}
+	fs.path = ""
+	fs.vol = i.VolumeSerialNumber
+	fs.idxhi = i.FileIndexHigh
+	fs.idxlo = i.FileIndexLow
+	return nil
+}
+
+// devNullStat is fileStat structure describing DevNull file ("NUL").
+var devNullStat = fileStat{
+	name: DevNull,
+	// hopefully this will work for SameFile
+	vol:   0,
+	idxhi: 0,
+	idxlo: 0,
+}
+
+func sameFile(fs1, fs2 *fileStat) bool {
+	e := fs1.loadFileId()
+	if e != nil {
+		return false
+	}
+	e = fs2.loadFileId()
+	if e != nil {
+		return false
+	}
+	return fs1.vol == fs2.vol && fs1.idxhi == fs2.idxhi && fs1.idxlo == fs2.idxlo
+}
+
+// For testing.
+func atime(fi FileInfo) time.Time {
+	return time.Unix(0, fi.Sys().(*syscall.Win32FileAttributeData).LastAccessTime.Nanoseconds())
+}
diff --git a/src/pkg/os/user/lookup.go b/src/os/user/lookup.go
similarity index 100%
rename from src/pkg/os/user/lookup.go
rename to src/os/user/lookup.go
diff --git a/src/pkg/os/user/lookup_plan9.go b/src/os/user/lookup_plan9.go
similarity index 100%
rename from src/pkg/os/user/lookup_plan9.go
rename to src/os/user/lookup_plan9.go
diff --git a/src/os/user/lookup_stubs.go b/src/os/user/lookup_stubs.go
new file mode 100644
index 0000000..4fb0e3c
--- /dev/null
+++ b/src/os/user/lookup_stubs.go
@@ -0,0 +1,28 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !cgo,!windows,!plan9 android
+
+package user
+
+import (
+	"fmt"
+	"runtime"
+)
+
+func init() {
+	implemented = false
+}
+
+func current() (*User, error) {
+	return nil, fmt.Errorf("user: Current not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
+}
+
+func lookup(username string) (*User, error) {
+	return nil, fmt.Errorf("user: Lookup not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
+}
+
+func lookupId(uid string) (*User, error) {
+	return nil, fmt.Errorf("user: LookupId not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
+}
diff --git a/src/os/user/lookup_unix.go b/src/os/user/lookup_unix.go
new file mode 100644
index 0000000..0871473
--- /dev/null
+++ b/src/os/user/lookup_unix.go
@@ -0,0 +1,112 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin dragonfly freebsd !android,linux netbsd openbsd solaris
+// +build cgo
+
+package user
+
+import (
+	"fmt"
+	"runtime"
+	"strconv"
+	"strings"
+	"syscall"
+	"unsafe"
+)
+
+/*
+#include <unistd.h>
+#include <sys/types.h>
+#include <pwd.h>
+#include <stdlib.h>
+
+static int mygetpwuid_r(int uid, struct passwd *pwd,
+	char *buf, size_t buflen, struct passwd **result) {
+ return getpwuid_r(uid, pwd, buf, buflen, result);
+}
+*/
+import "C"
+
+func current() (*User, error) {
+	return lookupUnix(syscall.Getuid(), "", false)
+}
+
+func lookup(username string) (*User, error) {
+	return lookupUnix(-1, username, true)
+}
+
+func lookupId(uid string) (*User, error) {
+	i, e := strconv.Atoi(uid)
+	if e != nil {
+		return nil, e
+	}
+	return lookupUnix(i, "", false)
+}
+
+func lookupUnix(uid int, username string, lookupByName bool) (*User, error) {
+	var pwd C.struct_passwd
+	var result *C.struct_passwd
+
+	var bufSize C.long
+	if runtime.GOOS == "dragonfly" || runtime.GOOS == "freebsd" {
+		// DragonFly and FreeBSD do not have _SC_GETPW_R_SIZE_MAX
+		// and just return -1.  So just use the same
+		// size that Linux returns.
+		bufSize = 1024
+	} else {
+		bufSize = C.sysconf(C._SC_GETPW_R_SIZE_MAX)
+		if bufSize <= 0 || bufSize > 1<<20 {
+			return nil, fmt.Errorf("user: unreasonable _SC_GETPW_R_SIZE_MAX of %d", bufSize)
+		}
+	}
+	buf := C.malloc(C.size_t(bufSize))
+	defer C.free(buf)
+	var rv C.int
+	if lookupByName {
+		nameC := C.CString(username)
+		defer C.free(unsafe.Pointer(nameC))
+		rv = C.getpwnam_r(nameC,
+			&pwd,
+			(*C.char)(buf),
+			C.size_t(bufSize),
+			&result)
+		if rv != 0 {
+			return nil, fmt.Errorf("user: lookup username %s: %s", username, syscall.Errno(rv))
+		}
+		if result == nil {
+			return nil, UnknownUserError(username)
+		}
+	} else {
+		// mygetpwuid_r is a wrapper around getpwuid_r to
+		// to avoid using uid_t because C.uid_t(uid) for
+		// unknown reasons doesn't work on linux.
+		rv = C.mygetpwuid_r(C.int(uid),
+			&pwd,
+			(*C.char)(buf),
+			C.size_t(bufSize),
+			&result)
+		if rv != 0 {
+			return nil, fmt.Errorf("user: lookup userid %d: %s", uid, syscall.Errno(rv))
+		}
+		if result == nil {
+			return nil, UnknownUserIdError(uid)
+		}
+	}
+	u := &User{
+		Uid:      strconv.Itoa(int(pwd.pw_uid)),
+		Gid:      strconv.Itoa(int(pwd.pw_gid)),
+		Username: C.GoString(pwd.pw_name),
+		Name:     C.GoString(pwd.pw_gecos),
+		HomeDir:  C.GoString(pwd.pw_dir),
+	}
+	// The pw_gecos field isn't quite standardized.  Some docs
+	// say: "It is expected to be a comma separated list of
+	// personal data where the first item is the full name of the
+	// user."
+	if i := strings.Index(u.Name, ","); i >= 0 {
+		u.Name = u.Name[:i]
+	}
+	return u, nil
+}
diff --git a/src/pkg/os/user/lookup_windows.go b/src/os/user/lookup_windows.go
similarity index 100%
rename from src/pkg/os/user/lookup_windows.go
rename to src/os/user/lookup_windows.go
diff --git a/src/pkg/os/user/user.go b/src/os/user/user.go
similarity index 100%
rename from src/pkg/os/user/user.go
rename to src/os/user/user.go
diff --git a/src/pkg/os/user/user_test.go b/src/os/user/user_test.go
similarity index 100%
rename from src/pkg/os/user/user_test.go
rename to src/os/user/user_test.go
diff --git a/src/pkg/path/example_test.go b/src/path/example_test.go
similarity index 100%
rename from src/pkg/path/example_test.go
rename to src/path/example_test.go
diff --git a/src/pkg/path/filepath/example_unix_test.go b/src/path/filepath/example_unix_test.go
similarity index 100%
rename from src/pkg/path/filepath/example_unix_test.go
rename to src/path/filepath/example_unix_test.go
diff --git a/src/pkg/path/filepath/export_test.go b/src/path/filepath/export_test.go
similarity index 100%
rename from src/pkg/path/filepath/export_test.go
rename to src/path/filepath/export_test.go
diff --git a/src/path/filepath/match.go b/src/path/filepath/match.go
new file mode 100644
index 0000000..ecc07aa
--- /dev/null
+++ b/src/path/filepath/match.go
@@ -0,0 +1,309 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package filepath
+
+import (
+	"errors"
+	"os"
+	"runtime"
+	"sort"
+	"strings"
+	"unicode/utf8"
+)
+
+// ErrBadPattern indicates a globbing pattern was malformed.
+var ErrBadPattern = errors.New("syntax error in pattern")
+
+// Match returns true if name matches the shell file name pattern.
+// The pattern syntax is:
+//
+//	pattern:
+//		{ term }
+//	term:
+//		'*'         matches any sequence of non-Separator characters
+//		'?'         matches any single non-Separator character
+//		'[' [ '^' ] { character-range } ']'
+//		            character class (must be non-empty)
+//		c           matches character c (c != '*', '?', '\\', '[')
+//		'\\' c      matches character c
+//
+//	character-range:
+//		c           matches character c (c != '\\', '-', ']')
+//		'\\' c      matches character c
+//		lo '-' hi   matches character c for lo <= c <= hi
+//
+// Match requires pattern to match all of name, not just a substring.
+// The only possible returned error is ErrBadPattern, when pattern
+// is malformed.
+//
+// On Windows, escaping is disabled. Instead, '\\' is treated as
+// path separator.
+//
+func Match(pattern, name string) (matched bool, err error) {
+Pattern:
+	for len(pattern) > 0 {
+		var star bool
+		var chunk string
+		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
+		}
+		// Look for match at current position.
+		t, ok, err := matchChunk(chunk, name)
+		// if we're the last chunk, make sure we've exhausted the name
+		// otherwise we'll give a false result even if we could still match
+		// using the star
+		if ok && (len(t) == 0 || len(pattern) > 0) {
+			name = t
+			continue
+		}
+		if err != nil {
+			return false, err
+		}
+		if star {
+			// Look for match skipping i+1 bytes.
+			// Cannot skip /.
+			for i := 0; i < len(name) && name[i] != Separator; i++ {
+				t, ok, err := matchChunk(chunk, name[i+1:])
+				if ok {
+					// if we're the last chunk, make sure we exhausted the name
+					if len(pattern) == 0 && len(t) > 0 {
+						continue
+					}
+					name = t
+					continue Pattern
+				}
+				if err != nil {
+					return false, err
+				}
+			}
+		}
+		return false, nil
+	}
+	return len(name) == 0, nil
+}
+
+// scanChunk gets the next segment of pattern, which is a non-star string
+// possibly preceded by a star.
+func scanChunk(pattern string) (star bool, chunk, rest string) {
+	for len(pattern) > 0 && pattern[0] == '*' {
+		pattern = pattern[1:]
+		star = true
+	}
+	inrange := false
+	var i int
+Scan:
+	for i = 0; i < len(pattern); i++ {
+		switch pattern[i] {
+		case '\\':
+			if runtime.GOOS != "windows" {
+				// error check handled in matchChunk: bad pattern.
+				if i+1 < len(pattern) {
+					i++
+				}
+			}
+		case '[':
+			inrange = true
+		case ']':
+			inrange = false
+		case '*':
+			if !inrange {
+				break Scan
+			}
+		}
+	}
+	return star, pattern[0:i], pattern[i:]
+}
+
+// matchChunk checks whether chunk matches the beginning of s.
+// If so, it returns the remainder of s (after the match).
+// Chunk is all single-character operators: literals, char classes, and ?.
+func matchChunk(chunk, s string) (rest string, ok bool, err error) {
+	for len(chunk) > 0 {
+		if len(s) == 0 {
+			return
+		}
+		switch chunk[0] {
+		case '[':
+			// character class
+			r, n := utf8.DecodeRuneInString(s)
+			s = s[n:]
+			chunk = chunk[1:]
+			// We can't end right after '[', we're expecting at least
+			// a closing bracket and possibly a caret.
+			if len(chunk) == 0 {
+				err = ErrBadPattern
+				return
+			}
+			// possibly negated
+			negated := chunk[0] == '^'
+			if negated {
+				chunk = chunk[1:]
+			}
+			// parse all ranges
+			match := false
+			nrange := 0
+			for {
+				if len(chunk) > 0 && chunk[0] == ']' && nrange > 0 {
+					chunk = chunk[1:]
+					break
+				}
+				var lo, hi rune
+				if lo, chunk, err = getEsc(chunk); err != nil {
+					return
+				}
+				hi = lo
+				if chunk[0] == '-' {
+					if hi, chunk, err = getEsc(chunk[1:]); err != nil {
+						return
+					}
+				}
+				if lo <= r && r <= hi {
+					match = true
+				}
+				nrange++
+			}
+			if match == negated {
+				return
+			}
+
+		case '?':
+			if s[0] == Separator {
+				return
+			}
+			_, n := utf8.DecodeRuneInString(s)
+			s = s[n:]
+			chunk = chunk[1:]
+
+		case '\\':
+			if runtime.GOOS != "windows" {
+				chunk = chunk[1:]
+				if len(chunk) == 0 {
+					err = ErrBadPattern
+					return
+				}
+			}
+			fallthrough
+
+		default:
+			if chunk[0] != s[0] {
+				return
+			}
+			s = s[1:]
+			chunk = chunk[1:]
+		}
+	}
+	return s, true, nil
+}
+
+// getEsc gets a possibly-escaped character from chunk, for a character class.
+func getEsc(chunk string) (r rune, nchunk string, err error) {
+	if len(chunk) == 0 || chunk[0] == '-' || chunk[0] == ']' {
+		err = ErrBadPattern
+		return
+	}
+	if chunk[0] == '\\' && runtime.GOOS != "windows" {
+		chunk = chunk[1:]
+		if len(chunk) == 0 {
+			err = ErrBadPattern
+			return
+		}
+	}
+	r, n := utf8.DecodeRuneInString(chunk)
+	if r == utf8.RuneError && n == 1 {
+		err = ErrBadPattern
+	}
+	nchunk = chunk[n:]
+	if len(nchunk) == 0 {
+		err = ErrBadPattern
+	}
+	return
+}
+
+// Glob returns the names of all files matching pattern or nil
+// if there is no matching file. The syntax of patterns is the same
+// as in Match. The pattern may describe hierarchical names such as
+// /usr/*/bin/ed (assuming the Separator is '/').
+//
+// Glob ignores file system errors such as I/O errors reading directories.
+// The only possible returned error is ErrBadPattern, when pattern
+// is malformed.
+func Glob(pattern string) (matches []string, err error) {
+	if !hasMeta(pattern) {
+		if _, err = os.Lstat(pattern); err != nil {
+			return nil, nil
+		}
+		return []string{pattern}, nil
+	}
+
+	dir, file := Split(pattern)
+	switch dir {
+	case "":
+		dir = "."
+	case string(Separator):
+		// nothing
+	default:
+		dir = dir[0 : len(dir)-1] // chop off trailing separator
+	}
+
+	if !hasMeta(dir) {
+		return glob(dir, file, nil)
+	}
+
+	var m []string
+	m, err = Glob(dir)
+	if err != nil {
+		return
+	}
+	for _, d := range m {
+		matches, err = glob(d, file, matches)
+		if err != nil {
+			return
+		}
+	}
+	return
+}
+
+// glob searches for files matching pattern in the directory dir
+// and appends them to matches. If the directory cannot be
+// opened, it returns the existing matches. New matches are
+// added in lexicographical order.
+func glob(dir, pattern string, matches []string) (m []string, e error) {
+	m = matches
+	fi, err := os.Stat(dir)
+	if err != nil {
+		return
+	}
+	if !fi.IsDir() {
+		return
+	}
+	d, err := os.Open(dir)
+	if err != nil {
+		return
+	}
+	defer d.Close()
+
+	names, _ := d.Readdirnames(-1)
+	sort.Strings(names)
+
+	for _, n := range names {
+		matched, err := Match(pattern, n)
+		if err != nil {
+			return m, err
+		}
+		if matched {
+			m = append(m, Join(dir, n))
+		}
+	}
+	return
+}
+
+// hasMeta returns true if path contains any of the magic characters
+// recognized by Match.
+func hasMeta(path string) bool {
+	// TODO(niemeyer): Should other magic characters be added here?
+	return strings.IndexAny(path, "*?[") >= 0
+}
diff --git a/src/path/filepath/match_test.go b/src/path/filepath/match_test.go
new file mode 100644
index 0000000..20ec5aa
--- /dev/null
+++ b/src/path/filepath/match_test.go
@@ -0,0 +1,211 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package filepath_test
+
+import (
+	"io/ioutil"
+	"os"
+	. "path/filepath"
+	"runtime"
+	"strings"
+	"testing"
+)
+
+type MatchTest struct {
+	pattern, s string
+	match      bool
+	err        error
+}
+
+var matchTests = []MatchTest{
+	{"abc", "abc", true, nil},
+	{"*", "abc", true, nil},
+	{"*c", "abc", true, nil},
+	{"a*", "a", true, nil},
+	{"a*", "abc", true, nil},
+	{"a*", "ab/c", false, nil},
+	{"a*/b", "abc/b", true, nil},
+	{"a*/b", "a/c/b", false, nil},
+	{"a*b*c*d*e*/f", "axbxcxdxe/f", true, nil},
+	{"a*b*c*d*e*/f", "axbxcxdxexxx/f", true, nil},
+	{"a*b*c*d*e*/f", "axbxcxdxe/xxx/f", false, nil},
+	{"a*b*c*d*e*/f", "axbxcxdxexxx/fff", false, nil},
+	{"a*b?c*x", "abxbbxdbxebxczzx", true, nil},
+	{"a*b?c*x", "abxbbxdbxebxczzy", false, nil},
+	{"ab[c]", "abc", true, nil},
+	{"ab[b-d]", "abc", true, nil},
+	{"ab[e-g]", "abc", false, nil},
+	{"ab[^c]", "abc", false, nil},
+	{"ab[^b-d]", "abc", false, nil},
+	{"ab[^e-g]", "abc", true, nil},
+	{"a\\*b", "a*b", true, nil},
+	{"a\\*b", "ab", false, nil},
+	{"a?b", "a☺b", true, nil},
+	{"a[^a]b", "a☺b", true, nil},
+	{"a???b", "a☺b", false, nil},
+	{"a[^a][^a][^a]b", "a☺b", false, nil},
+	{"[a-ζ]*", "α", true, nil},
+	{"*[a-ζ]", "A", false, nil},
+	{"a?b", "a/b", false, nil},
+	{"a*b", "a/b", false, nil},
+	{"[\\]a]", "]", true, nil},
+	{"[\\-]", "-", true, nil},
+	{"[x\\-]", "x", true, nil},
+	{"[x\\-]", "-", true, nil},
+	{"[x\\-]", "z", false, nil},
+	{"[\\-x]", "x", true, nil},
+	{"[\\-x]", "-", true, nil},
+	{"[\\-x]", "a", false, nil},
+	{"[]a]", "]", false, ErrBadPattern},
+	{"[-]", "-", false, ErrBadPattern},
+	{"[x-]", "x", false, ErrBadPattern},
+	{"[x-]", "-", false, ErrBadPattern},
+	{"[x-]", "z", false, ErrBadPattern},
+	{"[-x]", "x", false, ErrBadPattern},
+	{"[-x]", "-", false, ErrBadPattern},
+	{"[-x]", "a", false, ErrBadPattern},
+	{"\\", "a", false, ErrBadPattern},
+	{"[a-b-c]", "a", false, ErrBadPattern},
+	{"[", "a", false, ErrBadPattern},
+	{"[^", "a", false, ErrBadPattern},
+	{"[^bc", "a", false, ErrBadPattern},
+	{"a[", "a", false, nil},
+	{"a[", "ab", false, ErrBadPattern},
+	{"*x", "xxx", true, nil},
+}
+
+func errp(e error) string {
+	if e == nil {
+		return "<nil>"
+	}
+	return e.Error()
+}
+
+func TestMatch(t *testing.T) {
+	for _, tt := range matchTests {
+		pattern := tt.pattern
+		s := tt.s
+		if runtime.GOOS == "windows" {
+			if strings.Index(pattern, "\\") >= 0 {
+				// no escape allowed on windows.
+				continue
+			}
+			pattern = Clean(pattern)
+			s = Clean(s)
+		}
+		ok, err := Match(pattern, s)
+		if ok != tt.match || err != tt.err {
+			t.Errorf("Match(%#q, %#q) = %v, %q want %v, %q", pattern, s, ok, errp(err), tt.match, errp(tt.err))
+		}
+	}
+}
+
+// contains returns true if vector contains the string s.
+func contains(vector []string, s string) bool {
+	for _, elem := range vector {
+		if elem == s {
+			return true
+		}
+	}
+	return false
+}
+
+var globTests = []struct {
+	pattern, result string
+}{
+	{"match.go", "match.go"},
+	{"mat?h.go", "match.go"},
+	{"*", "match.go"},
+	{"../*/match.go", "../filepath/match.go"},
+}
+
+func TestGlob(t *testing.T) {
+	for _, tt := range globTests {
+		pattern := tt.pattern
+		result := tt.result
+		if runtime.GOOS == "windows" {
+			pattern = Clean(pattern)
+			result = Clean(result)
+		}
+		matches, err := Glob(pattern)
+		if err != nil {
+			t.Errorf("Glob error for %q: %s", pattern, err)
+			continue
+		}
+		if !contains(matches, result) {
+			t.Errorf("Glob(%#q) = %#v want %v", pattern, matches, result)
+		}
+	}
+	for _, pattern := range []string{"no_match", "../*/no_match"} {
+		matches, err := Glob(pattern)
+		if err != nil {
+			t.Errorf("Glob error for %q: %s", pattern, err)
+			continue
+		}
+		if len(matches) != 0 {
+			t.Errorf("Glob(%#q) = %#v want []", pattern, matches)
+		}
+	}
+}
+
+func TestGlobError(t *testing.T) {
+	_, err := Glob("[7]")
+	if err != nil {
+		t.Error("expected error for bad pattern; got none")
+	}
+}
+
+var globSymlinkTests = []struct {
+	path, dest string
+	brokenLink bool
+}{
+	{"test1", "link1", false},
+	{"test2", "link2", true},
+}
+
+func TestGlobSymlink(t *testing.T) {
+	switch runtime.GOOS {
+	case "nacl", "plan9":
+		t.Skipf("skipping on %s", runtime.GOOS)
+	case "windows":
+		if !supportsSymlinks {
+			t.Skipf("skipping on %s", runtime.GOOS)
+		}
+
+	}
+
+	tmpDir, err := ioutil.TempDir("", "globsymlink")
+	if err != nil {
+		t.Fatal("creating temp dir:", err)
+	}
+	defer os.RemoveAll(tmpDir)
+
+	for _, tt := range globSymlinkTests {
+		path := Join(tmpDir, tt.path)
+		dest := Join(tmpDir, tt.dest)
+		f, err := os.Create(path)
+		if err != nil {
+			t.Fatal(err)
+		}
+		if err := f.Close(); err != nil {
+			t.Fatal(err)
+		}
+		err = os.Symlink(path, dest)
+		if err != nil {
+			t.Fatal(err)
+		}
+		if tt.brokenLink {
+			// Break the symlink.
+			os.Remove(path)
+		}
+		matches, err := Glob(dest)
+		if err != nil {
+			t.Errorf("GlobSymlink error for %q: %s", dest, err)
+		}
+		if !contains(matches, dest) {
+			t.Errorf("Glob(%#q) = %#v want %v", dest, matches, dest)
+		}
+	}
+}
diff --git a/src/path/filepath/path.go b/src/path/filepath/path.go
new file mode 100644
index 0000000..d37fc9d
--- /dev/null
+++ b/src/path/filepath/path.go
@@ -0,0 +1,464 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package filepath implements utility routines for manipulating filename paths
+// in a way compatible with the target operating system-defined file paths.
+package filepath
+
+import (
+	"errors"
+	"os"
+	"sort"
+	"strings"
+)
+
+// A lazybuf is a lazily constructed path buffer.
+// It supports append, reading previously appended bytes,
+// and retrieving the final string. It does not allocate a buffer
+// to hold the output until that output diverges from s.
+type lazybuf struct {
+	path       string
+	buf        []byte
+	w          int
+	volAndPath string
+	volLen     int
+}
+
+func (b *lazybuf) index(i int) byte {
+	if b.buf != nil {
+		return b.buf[i]
+	}
+	return b.path[i]
+}
+
+func (b *lazybuf) append(c byte) {
+	if b.buf == nil {
+		if b.w < len(b.path) && b.path[b.w] == c {
+			b.w++
+			return
+		}
+		b.buf = make([]byte, len(b.path))
+		copy(b.buf, b.path[:b.w])
+	}
+	b.buf[b.w] = c
+	b.w++
+}
+
+func (b *lazybuf) string() string {
+	if b.buf == nil {
+		return b.volAndPath[:b.volLen+b.w]
+	}
+	return b.volAndPath[:b.volLen] + string(b.buf[:b.w])
+}
+
+const (
+	Separator     = os.PathSeparator
+	ListSeparator = os.PathListSeparator
+)
+
+// Clean returns the shortest path name equivalent to path
+// by purely lexical processing.  It applies the following rules
+// iteratively until no further processing can be done:
+//
+//	1. Replace multiple Separator elements with a single one.
+//	2. Eliminate each . path name element (the current directory).
+//	3. Eliminate each inner .. path name element (the parent directory)
+//	   along with the non-.. element that precedes it.
+//	4. Eliminate .. elements that begin a rooted path:
+//	   that is, replace "/.." by "/" at the beginning of a path,
+//	   assuming Separator is '/'.
+//
+// The returned path ends in a slash only if it represents a root directory,
+// such as "/" on Unix or `C:\` on Windows.
+//
+// If the result of this process is an empty string, Clean
+// returns the string ".".
+//
+// See also Rob Pike, ``Lexical File Names in Plan 9 or
+// Getting Dot-Dot Right,''
+// http://plan9.bell-labs.com/sys/doc/lexnames.html
+func Clean(path string) string {
+	originalPath := path
+	volLen := volumeNameLen(path)
+	path = path[volLen:]
+	if path == "" {
+		if volLen > 1 && originalPath[1] != ':' {
+			// should be UNC
+			return FromSlash(originalPath)
+		}
+		return originalPath + "."
+	}
+	rooted := os.IsPathSeparator(path[0])
+
+	// Invariants:
+	//	reading from path; r is index of next byte to process.
+	//	writing to buf; w is index of next byte to write.
+	//	dotdot is index in buf where .. must stop, either because
+	//		it is the leading slash or it is a leading ../../.. prefix.
+	n := len(path)
+	out := lazybuf{path: path, volAndPath: originalPath, volLen: volLen}
+	r, dotdot := 0, 0
+	if rooted {
+		out.append(Separator)
+		r, dotdot = 1, 1
+	}
+
+	for r < n {
+		switch {
+		case os.IsPathSeparator(path[r]):
+			// empty path element
+			r++
+		case path[r] == '.' && (r+1 == n || os.IsPathSeparator(path[r+1])):
+			// . element
+			r++
+		case path[r] == '.' && path[r+1] == '.' && (r+2 == n || os.IsPathSeparator(path[r+2])):
+			// .. element: remove to last separator
+			r += 2
+			switch {
+			case out.w > dotdot:
+				// can backtrack
+				out.w--
+				for out.w > dotdot && !os.IsPathSeparator(out.index(out.w)) {
+					out.w--
+				}
+			case !rooted:
+				// cannot backtrack, but not rooted, so append .. element.
+				if out.w > 0 {
+					out.append(Separator)
+				}
+				out.append('.')
+				out.append('.')
+				dotdot = out.w
+			}
+		default:
+			// real path element.
+			// add slash if needed
+			if rooted && out.w != 1 || !rooted && out.w != 0 {
+				out.append(Separator)
+			}
+			// copy element
+			for ; r < n && !os.IsPathSeparator(path[r]); r++ {
+				out.append(path[r])
+			}
+		}
+	}
+
+	// Turn empty string into "."
+	if out.w == 0 {
+		out.append('.')
+	}
+
+	return FromSlash(out.string())
+}
+
+// ToSlash returns the result of replacing each separator character
+// in path with a slash ('/') character. Multiple separators are
+// replaced by multiple slashes.
+func ToSlash(path string) string {
+	if Separator == '/' {
+		return path
+	}
+	return strings.Replace(path, string(Separator), "/", -1)
+}
+
+// FromSlash returns the result of replacing each slash ('/') character
+// in path with a separator character. Multiple slashes are replaced
+// by multiple separators.
+func FromSlash(path string) string {
+	if Separator == '/' {
+		return path
+	}
+	return strings.Replace(path, "/", string(Separator), -1)
+}
+
+// SplitList splits a list of paths joined by the OS-specific ListSeparator,
+// usually found in PATH or GOPATH environment variables.
+// Unlike strings.Split, SplitList returns an empty slice when passed an empty string.
+func SplitList(path string) []string {
+	return splitList(path)
+}
+
+// Split splits path immediately following the final Separator,
+// separating it into a directory and file name component.
+// If there is no Separator in path, Split returns an empty dir
+// and file set to path.
+// The returned values have the property that path = dir+file.
+func Split(path string) (dir, file string) {
+	vol := VolumeName(path)
+	i := len(path) - 1
+	for i >= len(vol) && !os.IsPathSeparator(path[i]) {
+		i--
+	}
+	return path[:i+1], path[i+1:]
+}
+
+// Join joins any number of path elements into a single path, adding
+// a Separator if necessary. The result is Cleaned, in particular
+// all empty strings are ignored.
+func Join(elem ...string) string {
+	for i, e := range elem {
+		if e != "" {
+			return Clean(strings.Join(elem[i:], string(Separator)))
+		}
+	}
+	return ""
+}
+
+// Ext returns the file name extension used by path.
+// The extension is the suffix beginning at the final dot
+// in the final element of path; it is empty if there is
+// no dot.
+func Ext(path string) string {
+	for i := len(path) - 1; i >= 0 && !os.IsPathSeparator(path[i]); i-- {
+		if path[i] == '.' {
+			return path[i:]
+		}
+	}
+	return ""
+}
+
+// EvalSymlinks returns the path name after the evaluation of any symbolic
+// links.
+// If path is relative the result will be relative to the current directory,
+// unless one of the components is an absolute symbolic link.
+func EvalSymlinks(path string) (string, error) {
+	return evalSymlinks(path)
+}
+
+// Abs returns an absolute representation of path.
+// If the path is not absolute it will be joined with the current
+// working directory to turn it into an absolute path.  The absolute
+// path name for a given file is not guaranteed to be unique.
+func Abs(path string) (string, error) {
+	return abs(path)
+}
+
+func unixAbs(path string) (string, error) {
+	if IsAbs(path) {
+		return Clean(path), nil
+	}
+	wd, err := os.Getwd()
+	if err != nil {
+		return "", err
+	}
+	return Join(wd, path), nil
+}
+
+// Rel returns a relative path that is lexically equivalent to targpath when
+// joined to basepath with an intervening separator. That is,
+// Join(basepath, Rel(basepath, targpath)) is equivalent to targpath itself.
+// On success, the returned path will always be relative to basepath,
+// even if basepath and targpath share no elements.
+// An error is returned if targpath can't be made relative to basepath or if
+// knowing the current working directory would be necessary to compute it.
+func Rel(basepath, targpath string) (string, error) {
+	baseVol := VolumeName(basepath)
+	targVol := VolumeName(targpath)
+	base := Clean(basepath)
+	targ := Clean(targpath)
+	if targ == base {
+		return ".", nil
+	}
+	base = base[len(baseVol):]
+	targ = targ[len(targVol):]
+	if base == "." {
+		base = ""
+	}
+	// Can't use IsAbs - `\a` and `a` are both relative in Windows.
+	baseSlashed := len(base) > 0 && base[0] == Separator
+	targSlashed := len(targ) > 0 && targ[0] == Separator
+	if baseSlashed != targSlashed || baseVol != targVol {
+		return "", errors.New("Rel: can't make " + targ + " relative to " + base)
+	}
+	// Position base[b0:bi] and targ[t0:ti] at the first differing elements.
+	bl := len(base)
+	tl := len(targ)
+	var b0, bi, t0, ti int
+	for {
+		for bi < bl && base[bi] != Separator {
+			bi++
+		}
+		for ti < tl && targ[ti] != Separator {
+			ti++
+		}
+		if targ[t0:ti] != base[b0:bi] {
+			break
+		}
+		if bi < bl {
+			bi++
+		}
+		if ti < tl {
+			ti++
+		}
+		b0 = bi
+		t0 = ti
+	}
+	if base[b0:bi] == ".." {
+		return "", errors.New("Rel: can't make " + targ + " relative to " + base)
+	}
+	if b0 != bl {
+		// Base elements left. Must go up before going down.
+		seps := strings.Count(base[b0:bl], string(Separator))
+		size := 2 + seps*3
+		if tl != t0 {
+			size += 1 + tl - t0
+		}
+		buf := make([]byte, size)
+		n := copy(buf, "..")
+		for i := 0; i < seps; i++ {
+			buf[n] = Separator
+			copy(buf[n+1:], "..")
+			n += 3
+		}
+		if t0 != tl {
+			buf[n] = Separator
+			copy(buf[n+1:], targ[t0:])
+		}
+		return string(buf), nil
+	}
+	return targ[t0:], nil
+}
+
+// SkipDir is used as a return value from WalkFuncs to indicate that
+// the directory named in the call is to be skipped. It is not returned
+// as an error by any function.
+var SkipDir = errors.New("skip this directory")
+
+// WalkFunc is the type of the function called for each file or directory
+// visited by Walk. The path argument contains the argument to Walk as a
+// prefix; that is, if Walk is called with "dir", which is a directory
+// containing the file "a", the walk function will be called with argument
+// "dir/a". The info argument is the os.FileInfo for the named path.
+//
+// If there was a problem walking to the file or directory named by path, the
+// incoming error will describe the problem and the function can decide how
+// to handle that error (and Walk will not descend into that directory). If
+// an error is returned, processing stops. The sole exception is that if path
+// is a directory and the function returns the special value SkipDir, the
+// contents of the directory are skipped and processing continues as usual on
+// the next file.
+type WalkFunc func(path string, info os.FileInfo, err error) error
+
+var lstat = os.Lstat // for testing
+
+// walk recursively descends path, calling w.
+func walk(path string, info os.FileInfo, walkFn WalkFunc) error {
+	err := walkFn(path, info, nil)
+	if err != nil {
+		if info.IsDir() && err == SkipDir {
+			return nil
+		}
+		return err
+	}
+
+	if !info.IsDir() {
+		return nil
+	}
+
+	names, err := readDirNames(path)
+	if err != nil {
+		return walkFn(path, info, err)
+	}
+
+	for _, name := range names {
+		filename := Join(path, name)
+		fileInfo, err := lstat(filename)
+		if err != nil {
+			if err := walkFn(filename, fileInfo, err); err != nil && err != SkipDir {
+				return err
+			}
+		} else {
+			err = walk(filename, fileInfo, walkFn)
+			if err != nil {
+				if !fileInfo.IsDir() || err != SkipDir {
+					return err
+				}
+			}
+		}
+	}
+	return nil
+}
+
+// Walk walks the file tree rooted at root, calling walkFn for each file or
+// directory in the tree, including root. All errors that arise visiting files
+// and directories are filtered by walkFn. The files are walked in lexical
+// order, which makes the output deterministic but means that for very
+// large directories Walk can be inefficient.
+// Walk does not follow symbolic links.
+func Walk(root string, walkFn WalkFunc) error {
+	info, err := os.Lstat(root)
+	if err != nil {
+		return walkFn(root, nil, err)
+	}
+	return walk(root, info, walkFn)
+}
+
+// readDirNames reads the directory named by dirname and returns
+// a sorted list of directory entries.
+func readDirNames(dirname string) ([]string, error) {
+	f, err := os.Open(dirname)
+	if err != nil {
+		return nil, err
+	}
+	names, err := f.Readdirnames(-1)
+	f.Close()
+	if err != nil {
+		return nil, err
+	}
+	sort.Strings(names)
+	return names, nil
+}
+
+// Base returns the last element of path.
+// Trailing path separators are removed before extracting the last element.
+// If the path is empty, Base returns ".".
+// If the path consists entirely of separators, Base returns a single separator.
+func Base(path string) string {
+	if path == "" {
+		return "."
+	}
+	// Strip trailing slashes.
+	for len(path) > 0 && os.IsPathSeparator(path[len(path)-1]) {
+		path = path[0 : len(path)-1]
+	}
+	// Throw away volume name
+	path = path[len(VolumeName(path)):]
+	// Find the last element
+	i := len(path) - 1
+	for i >= 0 && !os.IsPathSeparator(path[i]) {
+		i--
+	}
+	if i >= 0 {
+		path = path[i+1:]
+	}
+	// If empty now, it had only slashes.
+	if path == "" {
+		return string(Separator)
+	}
+	return path
+}
+
+// Dir returns all but the last element of path, typically the path's directory.
+// After dropping the final element, the path is Cleaned and trailing
+// slashes are removed.
+// If the path is empty, Dir returns ".".
+// If the path consists entirely of separators, Dir returns a single separator.
+// The returned path does not end in a separator unless it is the root directory.
+func Dir(path string) string {
+	vol := VolumeName(path)
+	i := len(path) - 1
+	for i >= len(vol) && !os.IsPathSeparator(path[i]) {
+		i--
+	}
+	dir := Clean(path[len(vol) : i+1])
+	return vol + dir
+}
+
+// VolumeName returns leading volume name.
+// Given "C:\foo\bar" it returns "C:" under windows.
+// Given "\\host\share\foo" it returns "\\host\share".
+// On other platforms it returns "".
+func VolumeName(path string) (v string) {
+	return path[:volumeNameLen(path)]
+}
diff --git a/src/path/filepath/path_plan9.go b/src/path/filepath/path_plan9.go
new file mode 100644
index 0000000..ee8912d
--- /dev/null
+++ b/src/path/filepath/path_plan9.go
@@ -0,0 +1,34 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package filepath
+
+import "strings"
+
+// IsAbs returns true if the path is absolute.
+func IsAbs(path string) bool {
+	return strings.HasPrefix(path, "/") || strings.HasPrefix(path, "#")
+}
+
+// volumeNameLen returns length of the leading volume name on Windows.
+// It returns 0 elsewhere.
+func volumeNameLen(path string) int {
+	return 0
+}
+
+// HasPrefix exists for historical compatibility and should not be used.
+func HasPrefix(p, prefix string) bool {
+	return strings.HasPrefix(p, prefix)
+}
+
+func splitList(path string) []string {
+	if path == "" {
+		return []string{}
+	}
+	return strings.Split(path, string(ListSeparator))
+}
+
+func abs(path string) (string, error) {
+	return unixAbs(path)
+}
diff --git a/src/path/filepath/path_test.go b/src/path/filepath/path_test.go
new file mode 100644
index 0000000..399284b
--- /dev/null
+++ b/src/path/filepath/path_test.go
@@ -0,0 +1,1028 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package filepath_test
+
+import (
+	"errors"
+	"io/ioutil"
+	"os"
+	"path/filepath"
+	"reflect"
+	"runtime"
+	"strings"
+	"testing"
+)
+
+var supportsSymlinks = true
+
+type PathTest struct {
+	path, result string
+}
+
+var cleantests = []PathTest{
+	// Already clean
+	{"abc", "abc"},
+	{"abc/def", "abc/def"},
+	{"a/b/c", "a/b/c"},
+	{".", "."},
+	{"..", ".."},
+	{"../..", "../.."},
+	{"../../abc", "../../abc"},
+	{"/abc", "/abc"},
+	{"/", "/"},
+
+	// Empty is current dir
+	{"", "."},
+
+	// Remove trailing slash
+	{"abc/", "abc"},
+	{"abc/def/", "abc/def"},
+	{"a/b/c/", "a/b/c"},
+	{"./", "."},
+	{"../", ".."},
+	{"../../", "../.."},
+	{"/abc/", "/abc"},
+
+	// Remove doubled slash
+	{"abc//def//ghi", "abc/def/ghi"},
+	{"//abc", "/abc"},
+	{"///abc", "/abc"},
+	{"//abc//", "/abc"},
+	{"abc//", "abc"},
+
+	// Remove . elements
+	{"abc/./def", "abc/def"},
+	{"/./abc/def", "/abc/def"},
+	{"abc/.", "abc"},
+
+	// Remove .. elements
+	{"abc/def/ghi/../jkl", "abc/def/jkl"},
+	{"abc/def/../ghi/../jkl", "abc/jkl"},
+	{"abc/def/..", "abc"},
+	{"abc/def/../..", "."},
+	{"/abc/def/../..", "/"},
+	{"abc/def/../../..", ".."},
+	{"/abc/def/../../..", "/"},
+	{"abc/def/../../../ghi/jkl/../../../mno", "../../mno"},
+	{"/../abc", "/abc"},
+
+	// Combinations
+	{"abc/./../def", "def"},
+	{"abc//./../def", "def"},
+	{"abc/../../././../def", "../../def"},
+}
+
+var wincleantests = []PathTest{
+	{`c:`, `c:.`},
+	{`c:\`, `c:\`},
+	{`c:\abc`, `c:\abc`},
+	{`c:abc\..\..\.\.\..\def`, `c:..\..\def`},
+	{`c:\abc\def\..\..`, `c:\`},
+	{`c:\..\abc`, `c:\abc`},
+	{`c:..\abc`, `c:..\abc`},
+	{`\`, `\`},
+	{`/`, `\`},
+	{`\\i\..\c$`, `\c$`},
+	{`\\i\..\i\c$`, `\i\c$`},
+	{`\\i\..\I\c$`, `\I\c$`},
+	{`\\host\share\foo\..\bar`, `\\host\share\bar`},
+	{`//host/share/foo/../baz`, `\\host\share\baz`},
+	{`\\a\b\..\c`, `\\a\b\c`},
+	{`\\a\b`, `\\a\b`},
+}
+
+func TestClean(t *testing.T) {
+	tests := cleantests
+	if runtime.GOOS == "windows" {
+		for i := range tests {
+			tests[i].result = filepath.FromSlash(tests[i].result)
+		}
+		tests = append(tests, wincleantests...)
+	}
+	for _, test := range tests {
+		if s := filepath.Clean(test.path); s != test.result {
+			t.Errorf("Clean(%q) = %q, want %q", test.path, s, test.result)
+		}
+		if s := filepath.Clean(test.result); s != test.result {
+			t.Errorf("Clean(%q) = %q, want %q", test.result, s, test.result)
+		}
+	}
+
+	if testing.Short() {
+		t.Skip("skipping malloc count in short mode")
+	}
+	if runtime.GOMAXPROCS(0) > 1 {
+		t.Log("skipping AllocsPerRun checks; GOMAXPROCS>1")
+		return
+	}
+
+	for _, test := range tests {
+		allocs := testing.AllocsPerRun(100, func() { filepath.Clean(test.result) })
+		if allocs > 0 {
+			t.Errorf("Clean(%q): %v allocs, want zero", test.result, allocs)
+		}
+	}
+}
+
+const sep = filepath.Separator
+
+var slashtests = []PathTest{
+	{"", ""},
+	{"/", string(sep)},
+	{"/a/b", string([]byte{sep, 'a', sep, 'b'})},
+	{"a//b", string([]byte{'a', sep, sep, 'b'})},
+}
+
+func TestFromAndToSlash(t *testing.T) {
+	for _, test := range slashtests {
+		if s := filepath.FromSlash(test.path); s != test.result {
+			t.Errorf("FromSlash(%q) = %q, want %q", test.path, s, test.result)
+		}
+		if s := filepath.ToSlash(test.result); s != test.path {
+			t.Errorf("ToSlash(%q) = %q, want %q", test.result, s, test.path)
+		}
+	}
+}
+
+type SplitListTest struct {
+	list   string
+	result []string
+}
+
+const lsep = filepath.ListSeparator
+
+var splitlisttests = []SplitListTest{
+	{"", []string{}},
+	{string([]byte{'a', lsep, 'b'}), []string{"a", "b"}},
+	{string([]byte{lsep, 'a', lsep, 'b'}), []string{"", "a", "b"}},
+}
+
+var winsplitlisttests = []SplitListTest{
+	// quoted
+	{`"a"`, []string{`a`}},
+
+	// semicolon
+	{`";"`, []string{`;`}},
+	{`"a;b"`, []string{`a;b`}},
+	{`";";`, []string{`;`, ``}},
+	{`;";"`, []string{``, `;`}},
+
+	// partially quoted
+	{`a";"b`, []string{`a;b`}},
+	{`a; ""b`, []string{`a`, ` b`}},
+	{`"a;b`, []string{`a;b`}},
+	{`""a;b`, []string{`a`, `b`}},
+	{`"""a;b`, []string{`a;b`}},
+	{`""""a;b`, []string{`a`, `b`}},
+	{`a";b`, []string{`a;b`}},
+	{`a;b";c`, []string{`a`, `b;c`}},
+	{`"a";b";c`, []string{`a`, `b;c`}},
+}
+
+func TestSplitList(t *testing.T) {
+	tests := splitlisttests
+	if runtime.GOOS == "windows" {
+		tests = append(tests, winsplitlisttests...)
+	}
+	for _, test := range tests {
+		if l := filepath.SplitList(test.list); !reflect.DeepEqual(l, test.result) {
+			t.Errorf("SplitList(%#q) = %#q, want %#q", test.list, l, test.result)
+		}
+	}
+}
+
+type SplitTest struct {
+	path, dir, file string
+}
+
+var unixsplittests = []SplitTest{
+	{"a/b", "a/", "b"},
+	{"a/b/", "a/b/", ""},
+	{"a/", "a/", ""},
+	{"a", "", "a"},
+	{"/", "/", ""},
+}
+
+var winsplittests = []SplitTest{
+	{`c:`, `c:`, ``},
+	{`c:/`, `c:/`, ``},
+	{`c:/foo`, `c:/`, `foo`},
+	{`c:/foo/bar`, `c:/foo/`, `bar`},
+	{`//host/share`, `//host/share`, ``},
+	{`//host/share/`, `//host/share/`, ``},
+	{`//host/share/foo`, `//host/share/`, `foo`},
+	{`\\host\share`, `\\host\share`, ``},
+	{`\\host\share\`, `\\host\share\`, ``},
+	{`\\host\share\foo`, `\\host\share\`, `foo`},
+}
+
+func TestSplit(t *testing.T) {
+	var splittests []SplitTest
+	splittests = unixsplittests
+	if runtime.GOOS == "windows" {
+		splittests = append(splittests, winsplittests...)
+	}
+	for _, test := range splittests {
+		if d, f := filepath.Split(test.path); d != test.dir || f != test.file {
+			t.Errorf("Split(%q) = %q, %q, want %q, %q", test.path, d, f, test.dir, test.file)
+		}
+	}
+}
+
+type JoinTest struct {
+	elem []string
+	path string
+}
+
+var jointests = []JoinTest{
+	// zero parameters
+	{[]string{}, ""},
+
+	// one parameter
+	{[]string{""}, ""},
+	{[]string{"a"}, "a"},
+
+	// two parameters
+	{[]string{"a", "b"}, "a/b"},
+	{[]string{"a", ""}, "a"},
+	{[]string{"", "b"}, "b"},
+	{[]string{"/", "a"}, "/a"},
+	{[]string{"/", ""}, "/"},
+	{[]string{"a/", "b"}, "a/b"},
+	{[]string{"a/", ""}, "a"},
+	{[]string{"", ""}, ""},
+}
+
+var winjointests = []JoinTest{
+	{[]string{`directory`, `file`}, `directory\file`},
+	{[]string{`C:\Windows\`, `System32`}, `C:\Windows\System32`},
+	{[]string{`C:\Windows\`, ``}, `C:\Windows`},
+	{[]string{`C:\`, `Windows`}, `C:\Windows`},
+	{[]string{`C:`, `Windows`}, `C:\Windows`},
+	{[]string{`\\host\share`, `foo`}, `\\host\share\foo`},
+	{[]string{`//host/share`, `foo/bar`}, `\\host\share\foo\bar`},
+}
+
+// join takes a []string and passes it to Join.
+func join(elem []string, args ...string) string {
+	args = elem
+	return filepath.Join(args...)
+}
+
+func TestJoin(t *testing.T) {
+	if runtime.GOOS == "windows" {
+		jointests = append(jointests, winjointests...)
+	}
+	for _, test := range jointests {
+		if p := join(test.elem); p != filepath.FromSlash(test.path) {
+			t.Errorf("join(%q) = %q, want %q", test.elem, p, test.path)
+		}
+	}
+}
+
+type ExtTest struct {
+	path, ext string
+}
+
+var exttests = []ExtTest{
+	{"path.go", ".go"},
+	{"path.pb.go", ".go"},
+	{"a.dir/b", ""},
+	{"a.dir/b.go", ".go"},
+	{"a.dir/", ""},
+}
+
+func TestExt(t *testing.T) {
+	for _, test := range exttests {
+		if x := filepath.Ext(test.path); x != test.ext {
+			t.Errorf("Ext(%q) = %q, want %q", test.path, x, test.ext)
+		}
+	}
+}
+
+type Node struct {
+	name    string
+	entries []*Node // nil if the entry is a file
+	mark    int
+}
+
+var tree = &Node{
+	"testdata",
+	[]*Node{
+		{"a", nil, 0},
+		{"b", []*Node{}, 0},
+		{"c", nil, 0},
+		{
+			"d",
+			[]*Node{
+				{"x", nil, 0},
+				{"y", []*Node{}, 0},
+				{
+					"z",
+					[]*Node{
+						{"u", nil, 0},
+						{"v", nil, 0},
+					},
+					0,
+				},
+			},
+			0,
+		},
+	},
+	0,
+}
+
+func walkTree(n *Node, path string, f func(path string, n *Node)) {
+	f(path, n)
+	for _, e := range n.entries {
+		walkTree(e, filepath.Join(path, e.name), f)
+	}
+}
+
+func makeTree(t *testing.T) {
+	walkTree(tree, tree.name, func(path string, n *Node) {
+		if n.entries == nil {
+			fd, err := os.Create(path)
+			if err != nil {
+				t.Errorf("makeTree: %v", err)
+				return
+			}
+			fd.Close()
+		} else {
+			os.Mkdir(path, 0770)
+		}
+	})
+}
+
+func markTree(n *Node) { walkTree(n, "", func(path string, n *Node) { n.mark++ }) }
+
+func checkMarks(t *testing.T, report bool) {
+	walkTree(tree, tree.name, func(path string, n *Node) {
+		if n.mark != 1 && report {
+			t.Errorf("node %s mark = %d; expected 1", path, n.mark)
+		}
+		n.mark = 0
+	})
+}
+
+// Assumes that each node name is unique. Good enough for a test.
+// If clear is true, any incoming error is cleared before return. The errors
+// are always accumulated, though.
+func mark(path string, info os.FileInfo, err error, errors *[]error, clear bool) error {
+	if err != nil {
+		*errors = append(*errors, err)
+		if clear {
+			return nil
+		}
+		return err
+	}
+	name := info.Name()
+	walkTree(tree, tree.name, func(path string, n *Node) {
+		if n.name == name {
+			n.mark++
+		}
+	})
+	return nil
+}
+
+func TestWalk(t *testing.T) {
+	makeTree(t)
+	errors := make([]error, 0, 10)
+	clear := true
+	markFn := func(path string, info os.FileInfo, err error) error {
+		return mark(path, info, err, &errors, clear)
+	}
+	// Expect no errors.
+	err := filepath.Walk(tree.name, markFn)
+	if err != nil {
+		t.Fatalf("no error expected, found: %s", err)
+	}
+	if len(errors) != 0 {
+		t.Fatalf("unexpected errors: %s", errors)
+	}
+	checkMarks(t, true)
+	errors = errors[0:0]
+
+	// Test permission errors.  Only possible if we're not root
+	// and only on some file systems (AFS, FAT).  To avoid errors during
+	// all.bash on those file systems, skip during go test -short.
+	if os.Getuid() > 0 && !testing.Short() {
+		// introduce 2 errors: chmod top-level directories to 0
+		os.Chmod(filepath.Join(tree.name, tree.entries[1].name), 0)
+		os.Chmod(filepath.Join(tree.name, tree.entries[3].name), 0)
+
+		// 3) capture errors, expect two.
+		// mark respective subtrees manually
+		markTree(tree.entries[1])
+		markTree(tree.entries[3])
+		// correct double-marking of directory itself
+		tree.entries[1].mark--
+		tree.entries[3].mark--
+		err := filepath.Walk(tree.name, markFn)
+		if err != nil {
+			t.Fatalf("expected no error return from Walk, got %s", err)
+		}
+		if len(errors) != 2 {
+			t.Errorf("expected 2 errors, got %d: %s", len(errors), errors)
+		}
+		// the inaccessible subtrees were marked manually
+		checkMarks(t, true)
+		errors = errors[0:0]
+
+		// 4) capture errors, stop after first error.
+		// mark respective subtrees manually
+		markTree(tree.entries[1])
+		markTree(tree.entries[3])
+		// correct double-marking of directory itself
+		tree.entries[1].mark--
+		tree.entries[3].mark--
+		clear = false // error will stop processing
+		err = filepath.Walk(tree.name, markFn)
+		if err == nil {
+			t.Fatalf("expected error return from Walk")
+		}
+		if len(errors) != 1 {
+			t.Errorf("expected 1 error, got %d: %s", len(errors), errors)
+		}
+		// the inaccessible subtrees were marked manually
+		checkMarks(t, false)
+		errors = errors[0:0]
+
+		// restore permissions
+		os.Chmod(filepath.Join(tree.name, tree.entries[1].name), 0770)
+		os.Chmod(filepath.Join(tree.name, tree.entries[3].name), 0770)
+	}
+
+	// cleanup
+	if err := os.RemoveAll(tree.name); err != nil {
+		t.Errorf("removeTree: %v", err)
+	}
+}
+
+func touch(t *testing.T, name string) {
+	f, err := os.Create(name)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if err := f.Close(); err != nil {
+		t.Fatal(err)
+	}
+}
+
+func TestWalkFileError(t *testing.T) {
+	td, err := ioutil.TempDir("", "walktest")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.RemoveAll(td)
+
+	touch(t, filepath.Join(td, "foo"))
+	touch(t, filepath.Join(td, "bar"))
+	dir := filepath.Join(td, "dir")
+	if err := os.MkdirAll(filepath.Join(td, "dir"), 0755); err != nil {
+		t.Fatal(err)
+	}
+	touch(t, filepath.Join(dir, "baz"))
+	touch(t, filepath.Join(dir, "stat-error"))
+	defer func() {
+		*filepath.LstatP = os.Lstat
+	}()
+	statErr := errors.New("some stat error")
+	*filepath.LstatP = func(path string) (os.FileInfo, error) {
+		if strings.HasSuffix(path, "stat-error") {
+			return nil, statErr
+		}
+		return os.Lstat(path)
+	}
+	got := map[string]error{}
+	err = filepath.Walk(td, func(path string, fi os.FileInfo, err error) error {
+		rel, _ := filepath.Rel(td, path)
+		got[filepath.ToSlash(rel)] = err
+		return nil
+	})
+	if err != nil {
+		t.Errorf("Walk error: %v", err)
+	}
+	want := map[string]error{
+		".":              nil,
+		"foo":            nil,
+		"bar":            nil,
+		"dir":            nil,
+		"dir/baz":        nil,
+		"dir/stat-error": statErr,
+	}
+	if !reflect.DeepEqual(got, want) {
+		t.Errorf("Walked %#v; want %#v", got, want)
+	}
+}
+
+var basetests = []PathTest{
+	{"", "."},
+	{".", "."},
+	{"/.", "."},
+	{"/", "/"},
+	{"////", "/"},
+	{"x/", "x"},
+	{"abc", "abc"},
+	{"abc/def", "def"},
+	{"a/b/.x", ".x"},
+	{"a/b/c.", "c."},
+	{"a/b/c.x", "c.x"},
+}
+
+var winbasetests = []PathTest{
+	{`c:\`, `\`},
+	{`c:.`, `.`},
+	{`c:\a\b`, `b`},
+	{`c:a\b`, `b`},
+	{`c:a\b\c`, `c`},
+	{`\\host\share\`, `\`},
+	{`\\host\share\a`, `a`},
+	{`\\host\share\a\b`, `b`},
+}
+
+func TestBase(t *testing.T) {
+	tests := basetests
+	if runtime.GOOS == "windows" {
+		// make unix tests work on windows
+		for i := range tests {
+			tests[i].result = filepath.Clean(tests[i].result)
+		}
+		// add windows specific tests
+		tests = append(tests, winbasetests...)
+	}
+	for _, test := range tests {
+		if s := filepath.Base(test.path); s != test.result {
+			t.Errorf("Base(%q) = %q, want %q", test.path, s, test.result)
+		}
+	}
+}
+
+var dirtests = []PathTest{
+	{"", "."},
+	{".", "."},
+	{"/.", "/"},
+	{"/", "/"},
+	{"////", "/"},
+	{"/foo", "/"},
+	{"x/", "x"},
+	{"abc", "."},
+	{"abc/def", "abc"},
+	{"a/b/.x", "a/b"},
+	{"a/b/c.", "a/b"},
+	{"a/b/c.x", "a/b"},
+}
+
+var windirtests = []PathTest{
+	{`c:\`, `c:\`},
+	{`c:.`, `c:.`},
+	{`c:\a\b`, `c:\a`},
+	{`c:a\b`, `c:a`},
+	{`c:a\b\c`, `c:a\b`},
+	{`\\host\share\`, `\\host\share\`},
+	{`\\host\share\a`, `\\host\share\`},
+	{`\\host\share\a\b`, `\\host\share\a`},
+}
+
+func TestDir(t *testing.T) {
+	tests := dirtests
+	if runtime.GOOS == "windows" {
+		// make unix tests work on windows
+		for i := range tests {
+			tests[i].result = filepath.Clean(tests[i].result)
+		}
+		// add windows specific tests
+		tests = append(tests, windirtests...)
+	}
+	for _, test := range tests {
+		if s := filepath.Dir(test.path); s != test.result {
+			t.Errorf("Dir(%q) = %q, want %q", test.path, s, test.result)
+		}
+	}
+}
+
+type IsAbsTest struct {
+	path  string
+	isAbs bool
+}
+
+var isabstests = []IsAbsTest{
+	{"", false},
+	{"/", true},
+	{"/usr/bin/gcc", true},
+	{"..", false},
+	{"/a/../bb", true},
+	{".", false},
+	{"./", false},
+	{"lala", false},
+}
+
+var winisabstests = []IsAbsTest{
+	{`C:\`, true},
+	{`c\`, false},
+	{`c::`, false},
+	{`c:`, false},
+	{`/`, false},
+	{`\`, false},
+	{`\Windows`, false},
+	{`c:a\b`, false},
+	{`c:\a\b`, true},
+	{`c:/a/b`, true},
+	{`\\host\share\foo`, true},
+	{`//host/share/foo/bar`, true},
+}
+
+func TestIsAbs(t *testing.T) {
+	var tests []IsAbsTest
+	if runtime.GOOS == "windows" {
+		tests = append(tests, winisabstests...)
+		// All non-windows tests should fail, because they have no volume letter.
+		for _, test := range isabstests {
+			tests = append(tests, IsAbsTest{test.path, false})
+		}
+		// All non-windows test should work as intended if prefixed with volume letter.
+		for _, test := range isabstests {
+			tests = append(tests, IsAbsTest{"c:" + test.path, test.isAbs})
+		}
+	} else {
+		tests = isabstests
+	}
+
+	for _, test := range tests {
+		if r := filepath.IsAbs(test.path); r != test.isAbs {
+			t.Errorf("IsAbs(%q) = %v, want %v", test.path, r, test.isAbs)
+		}
+	}
+}
+
+type EvalSymlinksTest struct {
+	// If dest is empty, the path is created; otherwise the dest is symlinked to the path.
+	path, dest string
+}
+
+var EvalSymlinksTestDirs = []EvalSymlinksTest{
+	{"test", ""},
+	{"test/dir", ""},
+	{"test/dir/link3", "../../"},
+	{"test/link1", "../test"},
+	{"test/link2", "dir"},
+	{"test/linkabs", "/"},
+}
+
+var EvalSymlinksTests = []EvalSymlinksTest{
+	{"test", "test"},
+	{"test/dir", "test/dir"},
+	{"test/dir/../..", "."},
+	{"test/link1", "test"},
+	{"test/link2", "test/dir"},
+	{"test/link1/dir", "test/dir"},
+	{"test/link2/..", "test"},
+	{"test/dir/link3", "."},
+	{"test/link2/link3/test", "test"},
+	{"test/linkabs", "/"},
+}
+
+var EvalSymlinksAbsWindowsTests = []EvalSymlinksTest{
+	{`c:\`, `c:\`},
+}
+
+// simpleJoin builds a file name from the directory and path.
+// It does not use Join because we don't want ".." to be evaluated.
+func simpleJoin(dir, path string) string {
+	return dir + string(filepath.Separator) + path
+}
+
+func TestEvalSymlinks(t *testing.T) {
+	switch runtime.GOOS {
+	case "nacl", "plan9":
+		t.Skipf("skipping on %s", runtime.GOOS)
+	}
+
+	tmpDir, err := ioutil.TempDir("", "evalsymlink")
+	if err != nil {
+		t.Fatal("creating temp dir:", err)
+	}
+	defer os.RemoveAll(tmpDir)
+
+	// /tmp may itself be a symlink! Avoid the confusion, although
+	// it means trusting the thing we're testing.
+	tmpDir, err = filepath.EvalSymlinks(tmpDir)
+	if err != nil {
+		t.Fatal("eval symlink for tmp dir:", err)
+	}
+
+	// Create the symlink farm using relative paths.
+	for _, d := range EvalSymlinksTestDirs {
+		var err error
+		path := simpleJoin(tmpDir, d.path)
+		if d.dest == "" {
+			err = os.Mkdir(path, 0755)
+		} else {
+			if supportsSymlinks {
+				err = os.Symlink(d.dest, path)
+			}
+		}
+		if err != nil {
+			t.Fatal(err)
+		}
+	}
+
+	var tests []EvalSymlinksTest
+	if supportsSymlinks {
+		tests = EvalSymlinksTests
+	} else {
+		for _, d := range EvalSymlinksTests {
+			if d.path == d.dest {
+				// will test only real files and directories
+				tests = append(tests, d)
+				// test "canonical" names
+				d2 := EvalSymlinksTest{
+					path: strings.ToUpper(d.path),
+					dest: d.dest,
+				}
+				tests = append(tests, d2)
+			}
+		}
+	}
+
+	// Evaluate the symlink farm.
+	for _, d := range tests {
+		path := simpleJoin(tmpDir, d.path)
+		dest := simpleJoin(tmpDir, d.dest)
+		if filepath.IsAbs(d.dest) || os.IsPathSeparator(d.dest[0]) {
+			dest = d.dest
+		}
+		if p, err := filepath.EvalSymlinks(path); err != nil {
+			t.Errorf("EvalSymlinks(%q) error: %v", d.path, err)
+		} else if filepath.Clean(p) != filepath.Clean(dest) {
+			t.Errorf("Clean(%q)=%q, want %q", path, p, dest)
+		}
+	}
+}
+
+// Test directories relative to temporary directory.
+// The tests are run in absTestDirs[0].
+var absTestDirs = []string{
+	"a",
+	"a/b",
+	"a/b/c",
+}
+
+// Test paths relative to temporary directory. $ expands to the directory.
+// The tests are run in absTestDirs[0].
+// We create absTestDirs first.
+var absTests = []string{
+	".",
+	"b",
+	"../a",
+	"../a/b",
+	"../a/b/./c/../../.././a",
+	"$",
+	"$/.",
+	"$/a/../a/b",
+	"$/a/b/c/../../.././a",
+}
+
+func TestAbs(t *testing.T) {
+	root, err := ioutil.TempDir("", "TestAbs")
+	if err != nil {
+		t.Fatal("TempDir failed: ", err)
+	}
+	defer os.RemoveAll(root)
+
+	wd, err := os.Getwd()
+	if err != nil {
+		t.Fatal("getwd failed: ", err)
+	}
+	err = os.Chdir(root)
+	if err != nil {
+		t.Fatal("chdir failed: ", err)
+	}
+	defer os.Chdir(wd)
+
+	for _, dir := range absTestDirs {
+		err = os.Mkdir(dir, 0777)
+		if err != nil {
+			t.Fatal("Mkdir failed: ", err)
+		}
+	}
+
+	if runtime.GOOS == "windows" {
+		vol := filepath.VolumeName(root)
+		var extra []string
+		for _, path := range absTests {
+			if strings.Index(path, "$") != -1 {
+				continue
+			}
+			path = vol + path
+			extra = append(extra, path)
+		}
+		absTests = append(absTests, extra...)
+	}
+
+	err = os.Chdir(absTestDirs[0])
+	if err != nil {
+		t.Fatal("chdir failed: ", err)
+	}
+
+	for _, path := range absTests {
+		path = strings.Replace(path, "$", root, -1)
+		info, err := os.Stat(path)
+		if err != nil {
+			t.Errorf("%s: %s", path, err)
+			continue
+		}
+
+		abspath, err := filepath.Abs(path)
+		if err != nil {
+			t.Errorf("Abs(%q) error: %v", path, err)
+			continue
+		}
+		absinfo, err := os.Stat(abspath)
+		if err != nil || !os.SameFile(absinfo, info) {
+			t.Errorf("Abs(%q)=%q, not the same file", path, abspath)
+		}
+		if !filepath.IsAbs(abspath) {
+			t.Errorf("Abs(%q)=%q, not an absolute path", path, abspath)
+		}
+		if filepath.IsAbs(path) && abspath != filepath.Clean(path) {
+			t.Errorf("Abs(%q)=%q, isn't clean", path, abspath)
+		}
+	}
+}
+
+type RelTests struct {
+	root, path, want string
+}
+
+var reltests = []RelTests{
+	{"a/b", "a/b", "."},
+	{"a/b/.", "a/b", "."},
+	{"a/b", "a/b/.", "."},
+	{"./a/b", "a/b", "."},
+	{"a/b", "./a/b", "."},
+	{"ab/cd", "ab/cde", "../cde"},
+	{"ab/cd", "ab/c", "../c"},
+	{"a/b", "a/b/c/d", "c/d"},
+	{"a/b", "a/b/../c", "../c"},
+	{"a/b/../c", "a/b", "../b"},
+	{"a/b/c", "a/c/d", "../../c/d"},
+	{"a/b", "c/d", "../../c/d"},
+	{"a/b/c/d", "a/b", "../.."},
+	{"a/b/c/d", "a/b/", "../.."},
+	{"a/b/c/d/", "a/b", "../.."},
+	{"a/b/c/d/", "a/b/", "../.."},
+	{"../../a/b", "../../a/b/c/d", "c/d"},
+	{"/a/b", "/a/b", "."},
+	{"/a/b/.", "/a/b", "."},
+	{"/a/b", "/a/b/.", "."},
+	{"/ab/cd", "/ab/cde", "../cde"},
+	{"/ab/cd", "/ab/c", "../c"},
+	{"/a/b", "/a/b/c/d", "c/d"},
+	{"/a/b", "/a/b/../c", "../c"},
+	{"/a/b/../c", "/a/b", "../b"},
+	{"/a/b/c", "/a/c/d", "../../c/d"},
+	{"/a/b", "/c/d", "../../c/d"},
+	{"/a/b/c/d", "/a/b", "../.."},
+	{"/a/b/c/d", "/a/b/", "../.."},
+	{"/a/b/c/d/", "/a/b", "../.."},
+	{"/a/b/c/d/", "/a/b/", "../.."},
+	{"/../../a/b", "/../../a/b/c/d", "c/d"},
+	{".", "a/b", "a/b"},
+	{".", "..", ".."},
+
+	// can't do purely lexically
+	{"..", ".", "err"},
+	{"..", "a", "err"},
+	{"../..", "..", "err"},
+	{"a", "/a", "err"},
+	{"/a", "a", "err"},
+}
+
+var winreltests = []RelTests{
+	{`C:a\b\c`, `C:a/b/d`, `..\d`},
+	{`C:\`, `D:\`, `err`},
+	{`C:`, `D:`, `err`},
+}
+
+func TestRel(t *testing.T) {
+	tests := append([]RelTests{}, reltests...)
+	if runtime.GOOS == "windows" {
+		for i := range tests {
+			tests[i].want = filepath.FromSlash(tests[i].want)
+		}
+		tests = append(tests, winreltests...)
+	}
+	for _, test := range tests {
+		got, err := filepath.Rel(test.root, test.path)
+		if test.want == "err" {
+			if err == nil {
+				t.Errorf("Rel(%q, %q)=%q, want error", test.root, test.path, got)
+			}
+			continue
+		}
+		if err != nil {
+			t.Errorf("Rel(%q, %q): want %q, got error: %s", test.root, test.path, test.want, err)
+		}
+		if got != test.want {
+			t.Errorf("Rel(%q, %q)=%q, want %q", test.root, test.path, got, test.want)
+		}
+	}
+}
+
+type VolumeNameTest struct {
+	path string
+	vol  string
+}
+
+var volumenametests = []VolumeNameTest{
+	{`c:/foo/bar`, `c:`},
+	{`c:`, `c:`},
+	{`2:`, ``},
+	{``, ``},
+	{`\\\host`, ``},
+	{`\\\host\`, ``},
+	{`\\\host\share`, ``},
+	{`\\\host\\share`, ``},
+	{`\\host`, ``},
+	{`//host`, ``},
+	{`\\host\`, ``},
+	{`//host/`, ``},
+	{`\\host\share`, `\\host\share`},
+	{`//host/share`, `//host/share`},
+	{`\\host\share\`, `\\host\share`},
+	{`//host/share/`, `//host/share`},
+	{`\\host\share\foo`, `\\host\share`},
+	{`//host/share/foo`, `//host/share`},
+	{`\\host\share\\foo\\\bar\\\\baz`, `\\host\share`},
+	{`//host/share//foo///bar////baz`, `//host/share`},
+	{`\\host\share\foo\..\bar`, `\\host\share`},
+	{`//host/share/foo/../bar`, `//host/share`},
+}
+
+func TestVolumeName(t *testing.T) {
+	if runtime.GOOS != "windows" {
+		return
+	}
+	for _, v := range volumenametests {
+		if vol := filepath.VolumeName(v.path); vol != v.vol {
+			t.Errorf("VolumeName(%q)=%q, want %q", v.path, vol, v.vol)
+		}
+	}
+}
+
+func TestDriveLetterInEvalSymlinks(t *testing.T) {
+	if runtime.GOOS != "windows" {
+		return
+	}
+	wd, _ := os.Getwd()
+	if len(wd) < 3 {
+		t.Errorf("Current directory path %q is too short", wd)
+	}
+	lp := strings.ToLower(wd)
+	up := strings.ToUpper(wd)
+	flp, err := filepath.EvalSymlinks(lp)
+	if err != nil {
+		t.Fatalf("EvalSymlinks(%q) failed: %q", lp, err)
+	}
+	fup, err := filepath.EvalSymlinks(up)
+	if err != nil {
+		t.Fatalf("EvalSymlinks(%q) failed: %q", up, err)
+	}
+	if flp != fup {
+		t.Errorf("Results of EvalSymlinks do not match: %q and %q", flp, fup)
+	}
+}
+
+func TestBug3486(t *testing.T) { // http://code.google.com/p/go/issues/detail?id=3486
+	root, err := filepath.EvalSymlinks(runtime.GOROOT() + "/test")
+	if err != nil {
+		t.Fatal(err)
+	}
+	bugs := filepath.Join(root, "bugs")
+	ken := filepath.Join(root, "ken")
+	seenBugs := false
+	seenKen := false
+	filepath.Walk(root, func(pth string, info os.FileInfo, err error) error {
+		if err != nil {
+			t.Fatal(err)
+		}
+
+		switch pth {
+		case bugs:
+			seenBugs = true
+			return filepath.SkipDir
+		case ken:
+			if !seenBugs {
+				t.Fatal("filepath.Walk out of order - ken before bugs")
+			}
+			seenKen = true
+		}
+		return nil
+	})
+	if !seenKen {
+		t.Fatalf("%q not seen", ken)
+	}
+}
diff --git a/src/path/filepath/path_unix.go b/src/path/filepath/path_unix.go
new file mode 100644
index 0000000..4e7d0d1
--- /dev/null
+++ b/src/path/filepath/path_unix.go
@@ -0,0 +1,36 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris
+
+package filepath
+
+import "strings"
+
+// IsAbs returns true if the path is absolute.
+func IsAbs(path string) bool {
+	return strings.HasPrefix(path, "/")
+}
+
+// volumeNameLen returns length of the leading volume name on Windows.
+// It returns 0 elsewhere.
+func volumeNameLen(path string) int {
+	return 0
+}
+
+// HasPrefix exists for historical compatibility and should not be used.
+func HasPrefix(p, prefix string) bool {
+	return strings.HasPrefix(p, prefix)
+}
+
+func splitList(path string) []string {
+	if path == "" {
+		return []string{}
+	}
+	return strings.Split(path, string(ListSeparator))
+}
+
+func abs(path string) (string, error) {
+	return unixAbs(path)
+}
diff --git a/src/path/filepath/path_windows.go b/src/path/filepath/path_windows.go
new file mode 100644
index 0000000..ec50f6b
--- /dev/null
+++ b/src/path/filepath/path_windows.go
@@ -0,0 +1,110 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package filepath
+
+import (
+	"strings"
+	"syscall"
+)
+
+func isSlash(c uint8) bool {
+	return c == '\\' || c == '/'
+}
+
+// IsAbs returns true if the path is absolute.
+func IsAbs(path string) (b bool) {
+	l := volumeNameLen(path)
+	if l == 0 {
+		return false
+	}
+	path = path[l:]
+	if path == "" {
+		return false
+	}
+	return isSlash(path[0])
+}
+
+// volumeNameLen returns length of the leading volume name on Windows.
+// It returns 0 elsewhere.
+func volumeNameLen(path string) int {
+	if len(path) < 2 {
+		return 0
+	}
+	// with drive letter
+	c := path[0]
+	if path[1] == ':' && ('a' <= c && c <= 'z' || 'A' <= c && c <= 'Z') {
+		return 2
+	}
+	// is it UNC
+	if l := len(path); l >= 5 && isSlash(path[0]) && isSlash(path[1]) &&
+		!isSlash(path[2]) && path[2] != '.' {
+		// first, leading `\\` and next shouldn't be `\`. its server name.
+		for n := 3; n < l-1; n++ {
+			// second, next '\' shouldn't be repeated.
+			if isSlash(path[n]) {
+				n++
+				// third, following something characters. its share name.
+				if !isSlash(path[n]) {
+					if path[n] == '.' {
+						break
+					}
+					for ; n < l; n++ {
+						if isSlash(path[n]) {
+							break
+						}
+					}
+					return n
+				}
+				break
+			}
+		}
+	}
+	return 0
+}
+
+// HasPrefix exists for historical compatibility and should not be used.
+func HasPrefix(p, prefix string) bool {
+	if strings.HasPrefix(p, prefix) {
+		return true
+	}
+	return strings.HasPrefix(strings.ToLower(p), strings.ToLower(prefix))
+}
+
+func splitList(path string) []string {
+	// The same implementation is used in LookPath in os/exec;
+	// consider changing os/exec when changing this.
+
+	if path == "" {
+		return []string{}
+	}
+
+	// Split path, respecting but preserving quotes.
+	list := []string{}
+	start := 0
+	quo := false
+	for i := 0; i < len(path); i++ {
+		switch c := path[i]; {
+		case c == '"':
+			quo = !quo
+		case c == ListSeparator && !quo:
+			list = append(list, path[start:i])
+			start = i + 1
+		}
+	}
+	list = append(list, path[start:])
+
+	// Remove quotes.
+	for i, s := range list {
+		if strings.Contains(s, `"`) {
+			list[i] = strings.Replace(s, `"`, ``, -1)
+		}
+	}
+
+	return list
+}
+
+func abs(path string) (string, error) {
+	return syscall.FullPath(path)
+}
diff --git a/src/path/filepath/path_windows_test.go b/src/path/filepath/path_windows_test.go
new file mode 100644
index 0000000..100cf30
--- /dev/null
+++ b/src/path/filepath/path_windows_test.go
@@ -0,0 +1,113 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package filepath_test
+
+import (
+	"io/ioutil"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"reflect"
+	"syscall"
+	"testing"
+)
+
+func init() {
+	tmpdir, err := ioutil.TempDir("", "symtest")
+	if err != nil {
+		panic("failed to create temp directory: " + err.Error())
+	}
+	defer os.RemoveAll(tmpdir)
+
+	err = os.Symlink("target", filepath.Join(tmpdir, "symlink"))
+	if err == nil {
+		return
+	}
+
+	err = err.(*os.LinkError).Err
+	switch err {
+	case syscall.EWINDOWS, syscall.ERROR_PRIVILEGE_NOT_HELD:
+		supportsSymlinks = false
+	}
+}
+
+func TestWinSplitListTestsAreValid(t *testing.T) {
+	comspec := os.Getenv("ComSpec")
+	if comspec == "" {
+		t.Fatal("%ComSpec% must be set")
+	}
+
+	for ti, tt := range winsplitlisttests {
+		testWinSplitListTestIsValid(t, ti, tt, comspec)
+	}
+}
+
+func testWinSplitListTestIsValid(t *testing.T, ti int, tt SplitListTest,
+	comspec string) {
+
+	const (
+		cmdfile             = `printdir.cmd`
+		perm    os.FileMode = 0700
+	)
+
+	tmp, err := ioutil.TempDir("", "testWinSplitListTestIsValid")
+	if err != nil {
+		t.Fatalf("TempDir failed: %v", err)
+	}
+	defer os.RemoveAll(tmp)
+
+	for i, d := range tt.result {
+		if d == "" {
+			continue
+		}
+		if cd := filepath.Clean(d); filepath.VolumeName(cd) != "" ||
+			cd[0] == '\\' || cd == ".." || (len(cd) >= 3 && cd[0:3] == `..\`) {
+			t.Errorf("%d,%d: %#q refers outside working directory", ti, i, d)
+			return
+		}
+		dd := filepath.Join(tmp, d)
+		if _, err := os.Stat(dd); err == nil {
+			t.Errorf("%d,%d: %#q already exists", ti, i, d)
+			return
+		}
+		if err = os.MkdirAll(dd, perm); err != nil {
+			t.Errorf("%d,%d: MkdirAll(%#q) failed: %v", ti, i, dd, err)
+			return
+		}
+		fn, data := filepath.Join(dd, cmdfile), []byte("@echo "+d+"\r\n")
+		if err = ioutil.WriteFile(fn, data, perm); err != nil {
+			t.Errorf("%d,%d: WriteFile(%#q) failed: %v", ti, i, fn, err)
+			return
+		}
+	}
+
+	for i, d := range tt.result {
+		if d == "" {
+			continue
+		}
+		exp := []byte(d + "\r\n")
+		cmd := &exec.Cmd{
+			Path: comspec,
+			Args: []string{`/c`, cmdfile},
+			Env:  []string{`Path=` + tt.list},
+			Dir:  tmp,
+		}
+		out, err := cmd.CombinedOutput()
+		switch {
+		case err != nil:
+			t.Errorf("%d,%d: execution error %v\n%q", ti, i, err, out)
+			return
+		case !reflect.DeepEqual(out, exp):
+			t.Errorf("%d,%d: expected %#q, got %#q", ti, i, exp, out)
+			return
+		default:
+			// unshadow cmdfile in next directory
+			err = os.Remove(filepath.Join(tmp, d, cmdfile))
+			if err != nil {
+				t.Fatalf("Remove test command failed: %v", err)
+			}
+		}
+	}
+}
diff --git a/src/path/filepath/symlink.go b/src/path/filepath/symlink.go
new file mode 100644
index 0000000..df0a9e0
--- /dev/null
+++ b/src/path/filepath/symlink.go
@@ -0,0 +1,72 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package filepath
+
+import (
+	"bytes"
+	"errors"
+	"os"
+)
+
+const utf8RuneSelf = 0x80
+
+func walkSymlinks(path string) (string, error) {
+	const maxIter = 255
+	originalPath := path
+	// consume path by taking each frontmost path element,
+	// expanding it if it's a symlink, and appending it to b
+	var b bytes.Buffer
+	for n := 0; path != ""; n++ {
+		if n > maxIter {
+			return "", errors.New("EvalSymlinks: too many links in " + originalPath)
+		}
+
+		// find next path component, p
+		var i = -1
+		for j, c := range path {
+			if c < utf8RuneSelf && os.IsPathSeparator(uint8(c)) {
+				i = j
+				break
+			}
+		}
+		var p string
+		if i == -1 {
+			p, path = path, ""
+		} else {
+			p, path = path[:i], path[i+1:]
+		}
+
+		if p == "" {
+			if b.Len() == 0 {
+				// must be absolute path
+				b.WriteRune(Separator)
+			}
+			continue
+		}
+
+		fi, err := os.Lstat(b.String() + p)
+		if err != nil {
+			return "", err
+		}
+		if fi.Mode()&os.ModeSymlink == 0 {
+			b.WriteString(p)
+			if path != "" || (b.Len() == 2 && len(p) == 2 && p[1] == ':') {
+				b.WriteRune(Separator)
+			}
+			continue
+		}
+
+		// it's a symlink, put it at the front of path
+		dest, err := os.Readlink(b.String() + p)
+		if err != nil {
+			return "", err
+		}
+		if IsAbs(dest) || os.IsPathSeparator(dest[0]) {
+			b.Reset()
+		}
+		path = dest + string(Separator) + path
+	}
+	return Clean(b.String()), nil
+}
diff --git a/src/path/filepath/symlink_unix.go b/src/path/filepath/symlink_unix.go
new file mode 100644
index 0000000..d20e63a
--- /dev/null
+++ b/src/path/filepath/symlink_unix.go
@@ -0,0 +1,7 @@
+// +build !windows
+
+package filepath
+
+func evalSymlinks(path string) (string, error) {
+	return walkSymlinks(path)
+}
diff --git a/src/path/filepath/symlink_windows.go b/src/path/filepath/symlink_windows.go
new file mode 100644
index 0000000..327c2c8
--- /dev/null
+++ b/src/path/filepath/symlink_windows.go
@@ -0,0 +1,74 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package filepath
+
+import (
+	"syscall"
+)
+
+func toShort(path string) (string, error) {
+	p, err := syscall.UTF16FromString(path)
+	if err != nil {
+		return "", err
+	}
+	b := p // GetShortPathName says we can reuse buffer
+	n, err := syscall.GetShortPathName(&p[0], &b[0], uint32(len(b)))
+	if err != nil {
+		return "", err
+	}
+	if n > uint32(len(b)) {
+		b = make([]uint16, n)
+		n, err = syscall.GetShortPathName(&p[0], &b[0], uint32(len(b)))
+		if err != nil {
+			return "", err
+		}
+	}
+	return syscall.UTF16ToString(b), nil
+}
+
+func toLong(path string) (string, error) {
+	p, err := syscall.UTF16FromString(path)
+	if err != nil {
+		return "", err
+	}
+	b := p // GetLongPathName says we can reuse buffer
+	n, err := syscall.GetLongPathName(&p[0], &b[0], uint32(len(b)))
+	if err != nil {
+		return "", err
+	}
+	if n > uint32(len(b)) {
+		b = make([]uint16, n)
+		n, err = syscall.GetLongPathName(&p[0], &b[0], uint32(len(b)))
+		if err != nil {
+			return "", err
+		}
+	}
+	b = b[:n]
+	return syscall.UTF16ToString(b), nil
+}
+
+func evalSymlinks(path string) (string, error) {
+	path, err := walkSymlinks(path)
+	if err != nil {
+		return "", err
+	}
+
+	p, err := toShort(path)
+	if err != nil {
+		return "", err
+	}
+	p, err = toLong(p)
+	if err != nil {
+		return "", err
+	}
+	// syscall.GetLongPathName does not change the case of the drive letter,
+	// but the result of EvalSymlinks must be unique, so we have
+	// EvalSymlinks(`c:\a`) == EvalSymlinks(`C:\a`).
+	// Make drive letter upper case.
+	if len(p) >= 2 && p[1] == ':' && 'a' <= p[0] && p[0] <= 'z' {
+		p = string(p[0]+'A'-'a') + p[1:]
+	}
+	return Clean(p), nil
+}
diff --git a/src/pkg/path/match.go b/src/path/match.go
similarity index 100%
rename from src/pkg/path/match.go
rename to src/path/match.go
diff --git a/src/pkg/path/match_test.go b/src/path/match_test.go
similarity index 100%
rename from src/pkg/path/match_test.go
rename to src/path/match_test.go
diff --git a/src/path/path.go b/src/path/path.go
new file mode 100644
index 0000000..98a6d52
--- /dev/null
+++ b/src/path/path.go
@@ -0,0 +1,210 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package path implements utility routines for manipulating slash-separated
+// paths.
+package path
+
+import (
+	"strings"
+)
+
+// A lazybuf is a lazily constructed path buffer.
+// It supports append, reading previously appended bytes,
+// and retrieving the final string. It does not allocate a buffer
+// to hold the output until that output diverges from s.
+type lazybuf struct {
+	s   string
+	buf []byte
+	w   int
+}
+
+func (b *lazybuf) index(i int) byte {
+	if b.buf != nil {
+		return b.buf[i]
+	}
+	return b.s[i]
+}
+
+func (b *lazybuf) append(c byte) {
+	if b.buf == nil {
+		if b.w < len(b.s) && b.s[b.w] == c {
+			b.w++
+			return
+		}
+		b.buf = make([]byte, len(b.s))
+		copy(b.buf, b.s[:b.w])
+	}
+	b.buf[b.w] = c
+	b.w++
+}
+
+func (b *lazybuf) string() string {
+	if b.buf == nil {
+		return b.s[:b.w]
+	}
+	return string(b.buf[:b.w])
+}
+
+// Clean returns the shortest path name equivalent to path
+// by purely lexical processing.  It applies the following rules
+// iteratively until no further processing can be done:
+//
+//	1. Replace multiple slashes with a single slash.
+//	2. Eliminate each . path name element (the current directory).
+//	3. Eliminate each inner .. path name element (the parent directory)
+//	   along with the non-.. element that precedes it.
+//	4. Eliminate .. elements that begin a rooted path:
+//	   that is, replace "/.." by "/" at the beginning of a path.
+//
+// The returned path ends in a slash only if it is the root "/".
+//
+// If the result of this process is an empty string, Clean
+// returns the string ".".
+//
+// See also Rob Pike, ``Lexical File Names in Plan 9 or
+// Getting Dot-Dot Right,''
+// http://plan9.bell-labs.com/sys/doc/lexnames.html
+func Clean(path string) string {
+	if path == "" {
+		return "."
+	}
+
+	rooted := path[0] == '/'
+	n := len(path)
+
+	// Invariants:
+	//	reading from path; r is index of next byte to process.
+	//	writing to buf; w is index of next byte to write.
+	//	dotdot is index in buf where .. must stop, either because
+	//		it is the leading slash or it is a leading ../../.. prefix.
+	out := lazybuf{s: path}
+	r, dotdot := 0, 0
+	if rooted {
+		out.append('/')
+		r, dotdot = 1, 1
+	}
+
+	for r < n {
+		switch {
+		case path[r] == '/':
+			// empty path element
+			r++
+		case path[r] == '.' && (r+1 == n || path[r+1] == '/'):
+			// . element
+			r++
+		case path[r] == '.' && path[r+1] == '.' && (r+2 == n || path[r+2] == '/'):
+			// .. element: remove to last /
+			r += 2
+			switch {
+			case out.w > dotdot:
+				// can backtrack
+				out.w--
+				for out.w > dotdot && out.index(out.w) != '/' {
+					out.w--
+				}
+			case !rooted:
+				// cannot backtrack, but not rooted, so append .. element.
+				if out.w > 0 {
+					out.append('/')
+				}
+				out.append('.')
+				out.append('.')
+				dotdot = out.w
+			}
+		default:
+			// real path element.
+			// add slash if needed
+			if rooted && out.w != 1 || !rooted && out.w != 0 {
+				out.append('/')
+			}
+			// copy element
+			for ; r < n && path[r] != '/'; r++ {
+				out.append(path[r])
+			}
+		}
+	}
+
+	// Turn empty string into "."
+	if out.w == 0 {
+		return "."
+	}
+
+	return out.string()
+}
+
+// Split splits path immediately following the final slash.
+// separating it into a directory and file name component.
+// If there is no slash path, Split returns an empty dir and
+// file set to path.
+// The returned values have the property that path = dir+file.
+func Split(path string) (dir, file string) {
+	i := strings.LastIndex(path, "/")
+	return path[:i+1], path[i+1:]
+}
+
+// Join joins any number of path elements into a single path, adding a
+// separating slash if necessary. The result is Cleaned; in particular,
+// all empty strings are ignored.
+func Join(elem ...string) string {
+	for i, e := range elem {
+		if e != "" {
+			return Clean(strings.Join(elem[i:], "/"))
+		}
+	}
+	return ""
+}
+
+// Ext returns the file name extension used by path.
+// The extension is the suffix beginning at the final dot
+// in the final slash-separated element of path;
+// it is empty if there is no dot.
+func Ext(path string) string {
+	for i := len(path) - 1; i >= 0 && path[i] != '/'; i-- {
+		if path[i] == '.' {
+			return path[i:]
+		}
+	}
+	return ""
+}
+
+// Base returns the last element of path.
+// Trailing slashes are removed before extracting the last element.
+// If the path is empty, Base returns ".".
+// If the path consists entirely of slashes, Base returns "/".
+func Base(path string) string {
+	if path == "" {
+		return "."
+	}
+	// Strip trailing slashes.
+	for len(path) > 0 && path[len(path)-1] == '/' {
+		path = path[0 : len(path)-1]
+	}
+	// Find the last element
+	if i := strings.LastIndex(path, "/"); i >= 0 {
+		path = path[i+1:]
+	}
+	// If empty now, it had only slashes.
+	if path == "" {
+		return "/"
+	}
+	return path
+}
+
+// IsAbs returns true if the path is absolute.
+func IsAbs(path string) bool {
+	return len(path) > 0 && path[0] == '/'
+}
+
+// Dir returns all but the last element of path, typically the path's directory.
+// After dropping the final element using Split, the path is Cleaned and trailing
+// slashes are removed.
+// If the path is empty, Dir returns ".".
+// If the path consists entirely of slashes followed by non-slash bytes, Dir
+// returns a single slash. In any other case, the returned path does not end in a
+// slash.
+func Dir(path string) string {
+	dir, _ := Split(path)
+	return Clean(dir)
+}
diff --git a/src/pkg/path/path_test.go b/src/path/path_test.go
similarity index 100%
rename from src/pkg/path/path_test.go
rename to src/path/path_test.go
diff --git a/src/pkg/archive/tar/reader.go b/src/pkg/archive/tar/reader.go
deleted file mode 100644
index 920a9b0..0000000
--- a/src/pkg/archive/tar/reader.go
+++ /dev/null
@@ -1,817 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package tar
-
-// TODO(dsymonds):
-//   - pax extensions
-
-import (
-	"bytes"
-	"errors"
-	"io"
-	"io/ioutil"
-	"os"
-	"strconv"
-	"strings"
-	"time"
-)
-
-var (
-	ErrHeader = errors.New("archive/tar: invalid tar header")
-)
-
-const maxNanoSecondIntSize = 9
-
-// A Reader provides sequential access to the contents of a tar archive.
-// A tar archive consists of a sequence of files.
-// The Next method advances to the next file in the archive (including the first),
-// and then it can be treated as an io.Reader to access the file's data.
-type Reader struct {
-	r    io.Reader
-	err  error
-	pad  int64          // amount of padding (ignored) after current file entry
-	curr numBytesReader // reader for current file entry
-}
-
-// A numBytesReader is an io.Reader with a numBytes method, returning the number
-// of bytes remaining in the underlying encoded data.
-type numBytesReader interface {
-	io.Reader
-	numBytes() int64
-}
-
-// A regFileReader is a numBytesReader for reading file data from a tar archive.
-type regFileReader struct {
-	r  io.Reader // underlying reader
-	nb int64     // number of unread bytes for current file entry
-}
-
-// A sparseFileReader is a numBytesReader for reading sparse file data from a tar archive.
-type sparseFileReader struct {
-	rfr *regFileReader // reads the sparse-encoded file data
-	sp  []sparseEntry  // the sparse map for the file
-	pos int64          // keeps track of file position
-	tot int64          // total size of the file
-}
-
-// Keywords for GNU sparse files in a PAX extended header
-const (
-	paxGNUSparseNumBlocks = "GNU.sparse.numblocks"
-	paxGNUSparseOffset    = "GNU.sparse.offset"
-	paxGNUSparseNumBytes  = "GNU.sparse.numbytes"
-	paxGNUSparseMap       = "GNU.sparse.map"
-	paxGNUSparseName      = "GNU.sparse.name"
-	paxGNUSparseMajor     = "GNU.sparse.major"
-	paxGNUSparseMinor     = "GNU.sparse.minor"
-	paxGNUSparseSize      = "GNU.sparse.size"
-	paxGNUSparseRealSize  = "GNU.sparse.realsize"
-)
-
-// Keywords for old GNU sparse headers
-const (
-	oldGNUSparseMainHeaderOffset               = 386
-	oldGNUSparseMainHeaderIsExtendedOffset     = 482
-	oldGNUSparseMainHeaderNumEntries           = 4
-	oldGNUSparseExtendedHeaderIsExtendedOffset = 504
-	oldGNUSparseExtendedHeaderNumEntries       = 21
-	oldGNUSparseOffsetSize                     = 12
-	oldGNUSparseNumBytesSize                   = 12
-)
-
-// NewReader creates a new Reader reading from r.
-func NewReader(r io.Reader) *Reader { return &Reader{r: r} }
-
-// Next advances to the next entry in the tar archive.
-func (tr *Reader) Next() (*Header, error) {
-	var hdr *Header
-	if tr.err == nil {
-		tr.skipUnread()
-	}
-	if tr.err != nil {
-		return hdr, tr.err
-	}
-	hdr = tr.readHeader()
-	if hdr == nil {
-		return hdr, tr.err
-	}
-	// Check for PAX/GNU header.
-	switch hdr.Typeflag {
-	case TypeXHeader:
-		//  PAX extended header
-		headers, err := parsePAX(tr)
-		if err != nil {
-			return nil, err
-		}
-		// We actually read the whole file,
-		// but this skips alignment padding
-		tr.skipUnread()
-		hdr = tr.readHeader()
-		mergePAX(hdr, headers)
-
-		// Check for a PAX format sparse file
-		sp, err := tr.checkForGNUSparsePAXHeaders(hdr, headers)
-		if err != nil {
-			tr.err = err
-			return nil, err
-		}
-		if sp != nil {
-			// Current file is a PAX format GNU sparse file.
-			// Set the current file reader to a sparse file reader.
-			tr.curr = &sparseFileReader{rfr: tr.curr.(*regFileReader), sp: sp, tot: hdr.Size}
-		}
-		return hdr, nil
-	case TypeGNULongName:
-		// We have a GNU long name header. Its contents are the real file name.
-		realname, err := ioutil.ReadAll(tr)
-		if err != nil {
-			return nil, err
-		}
-		hdr, err := tr.Next()
-		hdr.Name = cString(realname)
-		return hdr, err
-	case TypeGNULongLink:
-		// We have a GNU long link header.
-		realname, err := ioutil.ReadAll(tr)
-		if err != nil {
-			return nil, err
-		}
-		hdr, err := tr.Next()
-		hdr.Linkname = cString(realname)
-		return hdr, err
-	}
-	return hdr, tr.err
-}
-
-// checkForGNUSparsePAXHeaders checks the PAX headers for GNU sparse headers. If they are found, then
-// this function reads the sparse map and returns it. Unknown sparse formats are ignored, causing the file to
-// be treated as a regular file.
-func (tr *Reader) checkForGNUSparsePAXHeaders(hdr *Header, headers map[string]string) ([]sparseEntry, error) {
-	var sparseFormat string
-
-	// Check for sparse format indicators
-	major, majorOk := headers[paxGNUSparseMajor]
-	minor, minorOk := headers[paxGNUSparseMinor]
-	sparseName, sparseNameOk := headers[paxGNUSparseName]
-	_, sparseMapOk := headers[paxGNUSparseMap]
-	sparseSize, sparseSizeOk := headers[paxGNUSparseSize]
-	sparseRealSize, sparseRealSizeOk := headers[paxGNUSparseRealSize]
-
-	// Identify which, if any, sparse format applies from which PAX headers are set
-	if majorOk && minorOk {
-		sparseFormat = major + "." + minor
-	} else if sparseNameOk && sparseMapOk {
-		sparseFormat = "0.1"
-	} else if sparseSizeOk {
-		sparseFormat = "0.0"
-	} else {
-		// Not a PAX format GNU sparse file.
-		return nil, nil
-	}
-
-	// Check for unknown sparse format
-	if sparseFormat != "0.0" && sparseFormat != "0.1" && sparseFormat != "1.0" {
-		return nil, nil
-	}
-
-	// Update hdr from GNU sparse PAX headers
-	if sparseNameOk {
-		hdr.Name = sparseName
-	}
-	if sparseSizeOk {
-		realSize, err := strconv.ParseInt(sparseSize, 10, 0)
-		if err != nil {
-			return nil, ErrHeader
-		}
-		hdr.Size = realSize
-	} else if sparseRealSizeOk {
-		realSize, err := strconv.ParseInt(sparseRealSize, 10, 0)
-		if err != nil {
-			return nil, ErrHeader
-		}
-		hdr.Size = realSize
-	}
-
-	// Set up the sparse map, according to the particular sparse format in use
-	var sp []sparseEntry
-	var err error
-	switch sparseFormat {
-	case "0.0", "0.1":
-		sp, err = readGNUSparseMap0x1(headers)
-	case "1.0":
-		sp, err = readGNUSparseMap1x0(tr.curr)
-	}
-	return sp, err
-}
-
-// mergePAX merges well known headers according to PAX standard.
-// In general headers with the same name as those found
-// in the header struct overwrite those found in the header
-// struct with higher precision or longer values. Esp. useful
-// for name and linkname fields.
-func mergePAX(hdr *Header, headers map[string]string) error {
-	for k, v := range headers {
-		switch k {
-		case paxPath:
-			hdr.Name = v
-		case paxLinkpath:
-			hdr.Linkname = v
-		case paxGname:
-			hdr.Gname = v
-		case paxUname:
-			hdr.Uname = v
-		case paxUid:
-			uid, err := strconv.ParseInt(v, 10, 0)
-			if err != nil {
-				return err
-			}
-			hdr.Uid = int(uid)
-		case paxGid:
-			gid, err := strconv.ParseInt(v, 10, 0)
-			if err != nil {
-				return err
-			}
-			hdr.Gid = int(gid)
-		case paxAtime:
-			t, err := parsePAXTime(v)
-			if err != nil {
-				return err
-			}
-			hdr.AccessTime = t
-		case paxMtime:
-			t, err := parsePAXTime(v)
-			if err != nil {
-				return err
-			}
-			hdr.ModTime = t
-		case paxCtime:
-			t, err := parsePAXTime(v)
-			if err != nil {
-				return err
-			}
-			hdr.ChangeTime = t
-		case paxSize:
-			size, err := strconv.ParseInt(v, 10, 0)
-			if err != nil {
-				return err
-			}
-			hdr.Size = int64(size)
-		default:
-			if strings.HasPrefix(k, paxXattr) {
-				if hdr.Xattrs == nil {
-					hdr.Xattrs = make(map[string]string)
-				}
-				hdr.Xattrs[k[len(paxXattr):]] = v
-			}
-		}
-	}
-	return nil
-}
-
-// parsePAXTime takes a string of the form %d.%d as described in
-// the PAX specification.
-func parsePAXTime(t string) (time.Time, error) {
-	buf := []byte(t)
-	pos := bytes.IndexByte(buf, '.')
-	var seconds, nanoseconds int64
-	var err error
-	if pos == -1 {
-		seconds, err = strconv.ParseInt(t, 10, 0)
-		if err != nil {
-			return time.Time{}, err
-		}
-	} else {
-		seconds, err = strconv.ParseInt(string(buf[:pos]), 10, 0)
-		if err != nil {
-			return time.Time{}, err
-		}
-		nano_buf := string(buf[pos+1:])
-		// Pad as needed before converting to a decimal.
-		// For example .030 -> .030000000 -> 30000000 nanoseconds
-		if len(nano_buf) < maxNanoSecondIntSize {
-			// Right pad
-			nano_buf += strings.Repeat("0", maxNanoSecondIntSize-len(nano_buf))
-		} else if len(nano_buf) > maxNanoSecondIntSize {
-			// Right truncate
-			nano_buf = nano_buf[:maxNanoSecondIntSize]
-		}
-		nanoseconds, err = strconv.ParseInt(string(nano_buf), 10, 0)
-		if err != nil {
-			return time.Time{}, err
-		}
-	}
-	ts := time.Unix(seconds, nanoseconds)
-	return ts, nil
-}
-
-// parsePAX parses PAX headers.
-// If an extended header (type 'x') is invalid, ErrHeader is returned
-func parsePAX(r io.Reader) (map[string]string, error) {
-	buf, err := ioutil.ReadAll(r)
-	if err != nil {
-		return nil, err
-	}
-
-	// For GNU PAX sparse format 0.0 support.
-	// This function transforms the sparse format 0.0 headers into sparse format 0.1 headers.
-	var sparseMap bytes.Buffer
-
-	headers := make(map[string]string)
-	// Each record is constructed as
-	//     "%d %s=%s\n", length, keyword, value
-	for len(buf) > 0 {
-		// or the header was empty to start with.
-		var sp int
-		// The size field ends at the first space.
-		sp = bytes.IndexByte(buf, ' ')
-		if sp == -1 {
-			return nil, ErrHeader
-		}
-		// Parse the first token as a decimal integer.
-		n, err := strconv.ParseInt(string(buf[:sp]), 10, 0)
-		if err != nil {
-			return nil, ErrHeader
-		}
-		// Extract everything between the decimal and the n -1 on the
-		// beginning to eat the ' ', -1 on the end to skip the newline.
-		var record []byte
-		record, buf = buf[sp+1:n-1], buf[n:]
-		// The first equals is guaranteed to mark the end of the key.
-		// Everything else is value.
-		eq := bytes.IndexByte(record, '=')
-		if eq == -1 {
-			return nil, ErrHeader
-		}
-		key, value := record[:eq], record[eq+1:]
-
-		keyStr := string(key)
-		if keyStr == paxGNUSparseOffset || keyStr == paxGNUSparseNumBytes {
-			// GNU sparse format 0.0 special key. Write to sparseMap instead of using the headers map.
-			sparseMap.Write(value)
-			sparseMap.Write([]byte{','})
-		} else {
-			// Normal key. Set the value in the headers map.
-			headers[keyStr] = string(value)
-		}
-	}
-	if sparseMap.Len() != 0 {
-		// Add sparse info to headers, chopping off the extra comma
-		sparseMap.Truncate(sparseMap.Len() - 1)
-		headers[paxGNUSparseMap] = sparseMap.String()
-	}
-	return headers, nil
-}
-
-// cString parses bytes as a NUL-terminated C-style string.
-// If a NUL byte is not found then the whole slice is returned as a string.
-func cString(b []byte) string {
-	n := 0
-	for n < len(b) && b[n] != 0 {
-		n++
-	}
-	return string(b[0:n])
-}
-
-func (tr *Reader) octal(b []byte) int64 {
-	// Check for binary format first.
-	if len(b) > 0 && b[0]&0x80 != 0 {
-		var x int64
-		for i, c := range b {
-			if i == 0 {
-				c &= 0x7f // ignore signal bit in first byte
-			}
-			x = x<<8 | int64(c)
-		}
-		return x
-	}
-
-	// Because unused fields are filled with NULs, we need
-	// to skip leading NULs. Fields may also be padded with
-	// spaces or NULs.
-	// So we remove leading and trailing NULs and spaces to
-	// be sure.
-	b = bytes.Trim(b, " \x00")
-
-	if len(b) == 0 {
-		return 0
-	}
-	x, err := strconv.ParseUint(cString(b), 8, 64)
-	if err != nil {
-		tr.err = err
-	}
-	return int64(x)
-}
-
-// skipUnread skips any unread bytes in the existing file entry, as well as any alignment padding.
-func (tr *Reader) skipUnread() {
-	nr := tr.numBytes() + tr.pad // number of bytes to skip
-	tr.curr, tr.pad = nil, 0
-	if sr, ok := tr.r.(io.Seeker); ok {
-		if _, err := sr.Seek(nr, os.SEEK_CUR); err == nil {
-			return
-		}
-	}
-	_, tr.err = io.CopyN(ioutil.Discard, tr.r, nr)
-}
-
-func (tr *Reader) verifyChecksum(header []byte) bool {
-	if tr.err != nil {
-		return false
-	}
-
-	given := tr.octal(header[148:156])
-	unsigned, signed := checksum(header)
-	return given == unsigned || given == signed
-}
-
-func (tr *Reader) readHeader() *Header {
-	header := make([]byte, blockSize)
-	if _, tr.err = io.ReadFull(tr.r, header); tr.err != nil {
-		return nil
-	}
-
-	// Two blocks of zero bytes marks the end of the archive.
-	if bytes.Equal(header, zeroBlock[0:blockSize]) {
-		if _, tr.err = io.ReadFull(tr.r, header); tr.err != nil {
-			return nil
-		}
-		if bytes.Equal(header, zeroBlock[0:blockSize]) {
-			tr.err = io.EOF
-		} else {
-			tr.err = ErrHeader // zero block and then non-zero block
-		}
-		return nil
-	}
-
-	if !tr.verifyChecksum(header) {
-		tr.err = ErrHeader
-		return nil
-	}
-
-	// Unpack
-	hdr := new(Header)
-	s := slicer(header)
-
-	hdr.Name = cString(s.next(100))
-	hdr.Mode = tr.octal(s.next(8))
-	hdr.Uid = int(tr.octal(s.next(8)))
-	hdr.Gid = int(tr.octal(s.next(8)))
-	hdr.Size = tr.octal(s.next(12))
-	hdr.ModTime = time.Unix(tr.octal(s.next(12)), 0)
-	s.next(8) // chksum
-	hdr.Typeflag = s.next(1)[0]
-	hdr.Linkname = cString(s.next(100))
-
-	// The remainder of the header depends on the value of magic.
-	// The original (v7) version of tar had no explicit magic field,
-	// so its magic bytes, like the rest of the block, are NULs.
-	magic := string(s.next(8)) // contains version field as well.
-	var format string
-	switch {
-	case magic[:6] == "ustar\x00": // POSIX tar (1003.1-1988)
-		if string(header[508:512]) == "tar\x00" {
-			format = "star"
-		} else {
-			format = "posix"
-		}
-	case magic == "ustar  \x00": // old GNU tar
-		format = "gnu"
-	}
-
-	switch format {
-	case "posix", "gnu", "star":
-		hdr.Uname = cString(s.next(32))
-		hdr.Gname = cString(s.next(32))
-		devmajor := s.next(8)
-		devminor := s.next(8)
-		if hdr.Typeflag == TypeChar || hdr.Typeflag == TypeBlock {
-			hdr.Devmajor = tr.octal(devmajor)
-			hdr.Devminor = tr.octal(devminor)
-		}
-		var prefix string
-		switch format {
-		case "posix", "gnu":
-			prefix = cString(s.next(155))
-		case "star":
-			prefix = cString(s.next(131))
-			hdr.AccessTime = time.Unix(tr.octal(s.next(12)), 0)
-			hdr.ChangeTime = time.Unix(tr.octal(s.next(12)), 0)
-		}
-		if len(prefix) > 0 {
-			hdr.Name = prefix + "/" + hdr.Name
-		}
-	}
-
-	if tr.err != nil {
-		tr.err = ErrHeader
-		return nil
-	}
-
-	// Maximum value of hdr.Size is 64 GB (12 octal digits),
-	// so there's no risk of int64 overflowing.
-	nb := int64(hdr.Size)
-	tr.pad = -nb & (blockSize - 1) // blockSize is a power of two
-
-	// Set the current file reader.
-	tr.curr = &regFileReader{r: tr.r, nb: nb}
-
-	// Check for old GNU sparse format entry.
-	if hdr.Typeflag == TypeGNUSparse {
-		// Get the real size of the file.
-		hdr.Size = tr.octal(header[483:495])
-
-		// Read the sparse map.
-		sp := tr.readOldGNUSparseMap(header)
-		if tr.err != nil {
-			return nil
-		}
-		// Current file is a GNU sparse file. Update the current file reader.
-		tr.curr = &sparseFileReader{rfr: tr.curr.(*regFileReader), sp: sp, tot: hdr.Size}
-	}
-
-	return hdr
-}
-
-// A sparseEntry holds a single entry in a sparse file's sparse map.
-// A sparse entry indicates the offset and size in a sparse file of a
-// block of data.
-type sparseEntry struct {
-	offset   int64
-	numBytes int64
-}
-
-// readOldGNUSparseMap reads the sparse map as stored in the old GNU sparse format.
-// The sparse map is stored in the tar header if it's small enough. If it's larger than four entries,
-// then one or more extension headers are used to store the rest of the sparse map.
-func (tr *Reader) readOldGNUSparseMap(header []byte) []sparseEntry {
-	isExtended := header[oldGNUSparseMainHeaderIsExtendedOffset] != 0
-	spCap := oldGNUSparseMainHeaderNumEntries
-	if isExtended {
-		spCap += oldGNUSparseExtendedHeaderNumEntries
-	}
-	sp := make([]sparseEntry, 0, spCap)
-	s := slicer(header[oldGNUSparseMainHeaderOffset:])
-
-	// Read the four entries from the main tar header
-	for i := 0; i < oldGNUSparseMainHeaderNumEntries; i++ {
-		offset := tr.octal(s.next(oldGNUSparseOffsetSize))
-		numBytes := tr.octal(s.next(oldGNUSparseNumBytesSize))
-		if tr.err != nil {
-			tr.err = ErrHeader
-			return nil
-		}
-		if offset == 0 && numBytes == 0 {
-			break
-		}
-		sp = append(sp, sparseEntry{offset: offset, numBytes: numBytes})
-	}
-
-	for isExtended {
-		// There are more entries. Read an extension header and parse its entries.
-		sparseHeader := make([]byte, blockSize)
-		if _, tr.err = io.ReadFull(tr.r, sparseHeader); tr.err != nil {
-			return nil
-		}
-		isExtended = sparseHeader[oldGNUSparseExtendedHeaderIsExtendedOffset] != 0
-		s = slicer(sparseHeader)
-		for i := 0; i < oldGNUSparseExtendedHeaderNumEntries; i++ {
-			offset := tr.octal(s.next(oldGNUSparseOffsetSize))
-			numBytes := tr.octal(s.next(oldGNUSparseNumBytesSize))
-			if tr.err != nil {
-				tr.err = ErrHeader
-				return nil
-			}
-			if offset == 0 && numBytes == 0 {
-				break
-			}
-			sp = append(sp, sparseEntry{offset: offset, numBytes: numBytes})
-		}
-	}
-	return sp
-}
-
-// readGNUSparseMap1x0 reads the sparse map as stored in GNU's PAX sparse format version 1.0.
-// The sparse map is stored just before the file data and padded out to the nearest block boundary.
-func readGNUSparseMap1x0(r io.Reader) ([]sparseEntry, error) {
-	buf := make([]byte, 2*blockSize)
-	sparseHeader := buf[:blockSize]
-
-	// readDecimal is a helper function to read a decimal integer from the sparse map
-	// while making sure to read from the file in blocks of size blockSize
-	readDecimal := func() (int64, error) {
-		// Look for newline
-		nl := bytes.IndexByte(sparseHeader, '\n')
-		if nl == -1 {
-			if len(sparseHeader) >= blockSize {
-				// This is an error
-				return 0, ErrHeader
-			}
-			oldLen := len(sparseHeader)
-			newLen := oldLen + blockSize
-			if cap(sparseHeader) < newLen {
-				// There's more header, but we need to make room for the next block
-				copy(buf, sparseHeader)
-				sparseHeader = buf[:newLen]
-			} else {
-				// There's more header, and we can just reslice
-				sparseHeader = sparseHeader[:newLen]
-			}
-
-			// Now that sparseHeader is large enough, read next block
-			if _, err := io.ReadFull(r, sparseHeader[oldLen:newLen]); err != nil {
-				return 0, err
-			}
-
-			// Look for a newline in the new data
-			nl = bytes.IndexByte(sparseHeader[oldLen:newLen], '\n')
-			if nl == -1 {
-				// This is an error
-				return 0, ErrHeader
-			}
-			nl += oldLen // We want the position from the beginning
-		}
-		// Now that we've found a newline, read a number
-		n, err := strconv.ParseInt(string(sparseHeader[:nl]), 10, 0)
-		if err != nil {
-			return 0, ErrHeader
-		}
-
-		// Update sparseHeader to consume this number
-		sparseHeader = sparseHeader[nl+1:]
-		return n, nil
-	}
-
-	// Read the first block
-	if _, err := io.ReadFull(r, sparseHeader); err != nil {
-		return nil, err
-	}
-
-	// The first line contains the number of entries
-	numEntries, err := readDecimal()
-	if err != nil {
-		return nil, err
-	}
-
-	// Read all the entries
-	sp := make([]sparseEntry, 0, numEntries)
-	for i := int64(0); i < numEntries; i++ {
-		// Read the offset
-		offset, err := readDecimal()
-		if err != nil {
-			return nil, err
-		}
-		// Read numBytes
-		numBytes, err := readDecimal()
-		if err != nil {
-			return nil, err
-		}
-
-		sp = append(sp, sparseEntry{offset: offset, numBytes: numBytes})
-	}
-
-	return sp, nil
-}
-
-// readGNUSparseMap0x1 reads the sparse map as stored in GNU's PAX sparse format version 0.1.
-// The sparse map is stored in the PAX headers.
-func readGNUSparseMap0x1(headers map[string]string) ([]sparseEntry, error) {
-	// Get number of entries
-	numEntriesStr, ok := headers[paxGNUSparseNumBlocks]
-	if !ok {
-		return nil, ErrHeader
-	}
-	numEntries, err := strconv.ParseInt(numEntriesStr, 10, 0)
-	if err != nil {
-		return nil, ErrHeader
-	}
-
-	sparseMap := strings.Split(headers[paxGNUSparseMap], ",")
-
-	// There should be two numbers in sparseMap for each entry
-	if int64(len(sparseMap)) != 2*numEntries {
-		return nil, ErrHeader
-	}
-
-	// Loop through the entries in the sparse map
-	sp := make([]sparseEntry, 0, numEntries)
-	for i := int64(0); i < numEntries; i++ {
-		offset, err := strconv.ParseInt(sparseMap[2*i], 10, 0)
-		if err != nil {
-			return nil, ErrHeader
-		}
-		numBytes, err := strconv.ParseInt(sparseMap[2*i+1], 10, 0)
-		if err != nil {
-			return nil, ErrHeader
-		}
-		sp = append(sp, sparseEntry{offset: offset, numBytes: numBytes})
-	}
-
-	return sp, nil
-}
-
-// numBytes returns the number of bytes left to read in the current file's entry
-// in the tar archive, or 0 if there is no current file.
-func (tr *Reader) numBytes() int64 {
-	if tr.curr == nil {
-		// No current file, so no bytes
-		return 0
-	}
-	return tr.curr.numBytes()
-}
-
-// Read reads from the current entry in the tar archive.
-// It returns 0, io.EOF when it reaches the end of that entry,
-// until Next is called to advance to the next entry.
-func (tr *Reader) Read(b []byte) (n int, err error) {
-	if tr.curr == nil {
-		return 0, io.EOF
-	}
-	n, err = tr.curr.Read(b)
-	if err != nil && err != io.EOF {
-		tr.err = err
-	}
-	return
-}
-
-func (rfr *regFileReader) Read(b []byte) (n int, err error) {
-	if rfr.nb == 0 {
-		// file consumed
-		return 0, io.EOF
-	}
-	if int64(len(b)) > rfr.nb {
-		b = b[0:rfr.nb]
-	}
-	n, err = rfr.r.Read(b)
-	rfr.nb -= int64(n)
-
-	if err == io.EOF && rfr.nb > 0 {
-		err = io.ErrUnexpectedEOF
-	}
-	return
-}
-
-// numBytes returns the number of bytes left to read in the file's data in the tar archive.
-func (rfr *regFileReader) numBytes() int64 {
-	return rfr.nb
-}
-
-// readHole reads a sparse file hole ending at offset toOffset
-func (sfr *sparseFileReader) readHole(b []byte, toOffset int64) int {
-	n64 := toOffset - sfr.pos
-	if n64 > int64(len(b)) {
-		n64 = int64(len(b))
-	}
-	n := int(n64)
-	for i := 0; i < n; i++ {
-		b[i] = 0
-	}
-	sfr.pos += n64
-	return n
-}
-
-// Read reads the sparse file data in expanded form.
-func (sfr *sparseFileReader) Read(b []byte) (n int, err error) {
-	if len(sfr.sp) == 0 {
-		// No more data fragments to read from.
-		if sfr.pos < sfr.tot {
-			// We're in the last hole
-			n = sfr.readHole(b, sfr.tot)
-			return
-		}
-		// Otherwise, we're at the end of the file
-		return 0, io.EOF
-	}
-	if sfr.pos < sfr.sp[0].offset {
-		// We're in a hole
-		n = sfr.readHole(b, sfr.sp[0].offset)
-		return
-	}
-
-	// We're not in a hole, so we'll read from the next data fragment
-	posInFragment := sfr.pos - sfr.sp[0].offset
-	bytesLeft := sfr.sp[0].numBytes - posInFragment
-	if int64(len(b)) > bytesLeft {
-		b = b[0:bytesLeft]
-	}
-
-	n, err = sfr.rfr.Read(b)
-	sfr.pos += int64(n)
-
-	if int64(n) == bytesLeft {
-		// We're done with this fragment
-		sfr.sp = sfr.sp[1:]
-	}
-
-	if err == io.EOF && sfr.pos < sfr.tot {
-		// We reached the end of the last fragment's data, but there's a final hole
-		err = nil
-	}
-	return
-}
-
-// numBytes returns the number of bytes left to read in the sparse file's
-// sparse-encoded data in the tar archive.
-func (sfr *sparseFileReader) numBytes() int64 {
-	return sfr.rfr.nb
-}
diff --git a/src/pkg/archive/tar/writer.go b/src/pkg/archive/tar/writer.go
deleted file mode 100644
index 6eff6f6..0000000
--- a/src/pkg/archive/tar/writer.go
+++ /dev/null
@@ -1,383 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package tar
-
-// TODO(dsymonds):
-// - catch more errors (no first header, etc.)
-
-import (
-	"bytes"
-	"errors"
-	"fmt"
-	"io"
-	"os"
-	"path"
-	"strconv"
-	"strings"
-	"time"
-)
-
-var (
-	ErrWriteTooLong    = errors.New("archive/tar: write too long")
-	ErrFieldTooLong    = errors.New("archive/tar: header field too long")
-	ErrWriteAfterClose = errors.New("archive/tar: write after close")
-	errNameTooLong     = errors.New("archive/tar: name too long")
-	errInvalidHeader   = errors.New("archive/tar: header field too long or contains invalid values")
-)
-
-// A Writer provides sequential writing of a tar archive in POSIX.1 format.
-// A tar archive consists of a sequence of files.
-// Call WriteHeader to begin a new file, and then call Write to supply that file's data,
-// writing at most hdr.Size bytes in total.
-type Writer struct {
-	w          io.Writer
-	err        error
-	nb         int64 // number of unwritten bytes for current file entry
-	pad        int64 // amount of padding to write after current file entry
-	closed     bool
-	usedBinary bool // whether the binary numeric field extension was used
-	preferPax  bool // use pax header instead of binary numeric header
-}
-
-// NewWriter creates a new Writer writing to w.
-func NewWriter(w io.Writer) *Writer { return &Writer{w: w} }
-
-// Flush finishes writing the current file (optional).
-func (tw *Writer) Flush() error {
-	if tw.nb > 0 {
-		tw.err = fmt.Errorf("archive/tar: missed writing %d bytes", tw.nb)
-		return tw.err
-	}
-
-	n := tw.nb + tw.pad
-	for n > 0 && tw.err == nil {
-		nr := n
-		if nr > blockSize {
-			nr = blockSize
-		}
-		var nw int
-		nw, tw.err = tw.w.Write(zeroBlock[0:nr])
-		n -= int64(nw)
-	}
-	tw.nb = 0
-	tw.pad = 0
-	return tw.err
-}
-
-// Write s into b, terminating it with a NUL if there is room.
-// If the value is too long for the field and allowPax is true add a paxheader record instead
-func (tw *Writer) cString(b []byte, s string, allowPax bool, paxKeyword string, paxHeaders map[string]string) {
-	needsPaxHeader := allowPax && len(s) > len(b) || !isASCII(s)
-	if needsPaxHeader {
-		paxHeaders[paxKeyword] = s
-		return
-	}
-	if len(s) > len(b) {
-		if tw.err == nil {
-			tw.err = ErrFieldTooLong
-		}
-		return
-	}
-	ascii := toASCII(s)
-	copy(b, ascii)
-	if len(ascii) < len(b) {
-		b[len(ascii)] = 0
-	}
-}
-
-// Encode x as an octal ASCII string and write it into b with leading zeros.
-func (tw *Writer) octal(b []byte, x int64) {
-	s := strconv.FormatInt(x, 8)
-	// leading zeros, but leave room for a NUL.
-	for len(s)+1 < len(b) {
-		s = "0" + s
-	}
-	tw.cString(b, s, false, paxNone, nil)
-}
-
-// Write x into b, either as octal or as binary (GNUtar/star extension).
-// If the value is too long for the field and writingPax is enabled both for the field and the add a paxheader record instead
-func (tw *Writer) numeric(b []byte, x int64, allowPax bool, paxKeyword string, paxHeaders map[string]string) {
-	// Try octal first.
-	s := strconv.FormatInt(x, 8)
-	if len(s) < len(b) {
-		tw.octal(b, x)
-		return
-	}
-
-	// If it is too long for octal, and pax is preferred, use a pax header
-	if allowPax && tw.preferPax {
-		tw.octal(b, 0)
-		s := strconv.FormatInt(x, 10)
-		paxHeaders[paxKeyword] = s
-		return
-	}
-
-	// Too big: use binary (big-endian).
-	tw.usedBinary = true
-	for i := len(b) - 1; x > 0 && i >= 0; i-- {
-		b[i] = byte(x)
-		x >>= 8
-	}
-	b[0] |= 0x80 // highest bit indicates binary format
-}
-
-var (
-	minTime = time.Unix(0, 0)
-	// There is room for 11 octal digits (33 bits) of mtime.
-	maxTime = minTime.Add((1<<33 - 1) * time.Second)
-)
-
-// WriteHeader writes hdr and prepares to accept the file's contents.
-// WriteHeader calls Flush if it is not the first header.
-// Calling after a Close will return ErrWriteAfterClose.
-func (tw *Writer) WriteHeader(hdr *Header) error {
-	return tw.writeHeader(hdr, true)
-}
-
-// WriteHeader writes hdr and prepares to accept the file's contents.
-// WriteHeader calls Flush if it is not the first header.
-// Calling after a Close will return ErrWriteAfterClose.
-// As this method is called internally by writePax header to allow it to
-// suppress writing the pax header.
-func (tw *Writer) writeHeader(hdr *Header, allowPax bool) error {
-	if tw.closed {
-		return ErrWriteAfterClose
-	}
-	if tw.err == nil {
-		tw.Flush()
-	}
-	if tw.err != nil {
-		return tw.err
-	}
-
-	// a map to hold pax header records, if any are needed
-	paxHeaders := make(map[string]string)
-
-	// TODO(shanemhansen): we might want to use PAX headers for
-	// subsecond time resolution, but for now let's just capture
-	// too long fields or non ascii characters
-
-	header := make([]byte, blockSize)
-	s := slicer(header)
-
-	// keep a reference to the filename to allow to overwrite it later if we detect that we can use ustar longnames instead of pax
-	pathHeaderBytes := s.next(fileNameSize)
-
-	tw.cString(pathHeaderBytes, hdr.Name, true, paxPath, paxHeaders)
-
-	// Handle out of range ModTime carefully.
-	var modTime int64
-	if !hdr.ModTime.Before(minTime) && !hdr.ModTime.After(maxTime) {
-		modTime = hdr.ModTime.Unix()
-	}
-
-	tw.octal(s.next(8), hdr.Mode)                                   // 100:108
-	tw.numeric(s.next(8), int64(hdr.Uid), true, paxUid, paxHeaders) // 108:116
-	tw.numeric(s.next(8), int64(hdr.Gid), true, paxGid, paxHeaders) // 116:124
-	tw.numeric(s.next(12), hdr.Size, true, paxSize, paxHeaders)     // 124:136
-	tw.numeric(s.next(12), modTime, false, paxNone, nil)            // 136:148 --- consider using pax for finer granularity
-	s.next(8)                                                       // chksum (148:156)
-	s.next(1)[0] = hdr.Typeflag                                     // 156:157
-
-	tw.cString(s.next(100), hdr.Linkname, true, paxLinkpath, paxHeaders)
-
-	copy(s.next(8), []byte("ustar\x0000"))                        // 257:265
-	tw.cString(s.next(32), hdr.Uname, true, paxUname, paxHeaders) // 265:297
-	tw.cString(s.next(32), hdr.Gname, true, paxGname, paxHeaders) // 297:329
-	tw.numeric(s.next(8), hdr.Devmajor, false, paxNone, nil)      // 329:337
-	tw.numeric(s.next(8), hdr.Devminor, false, paxNone, nil)      // 337:345
-
-	// keep a reference to the prefix to allow to overwrite it later if we detect that we can use ustar longnames instead of pax
-	prefixHeaderBytes := s.next(155)
-	tw.cString(prefixHeaderBytes, "", false, paxNone, nil) // 345:500  prefix
-
-	// Use the GNU magic instead of POSIX magic if we used any GNU extensions.
-	if tw.usedBinary {
-		copy(header[257:265], []byte("ustar  \x00"))
-	}
-
-	_, paxPathUsed := paxHeaders[paxPath]
-	// try to use a ustar header when only the name is too long
-	if !tw.preferPax && len(paxHeaders) == 1 && paxPathUsed {
-		suffix := hdr.Name
-		prefix := ""
-		if len(hdr.Name) > fileNameSize && isASCII(hdr.Name) {
-			var err error
-			prefix, suffix, err = tw.splitUSTARLongName(hdr.Name)
-			if err == nil {
-				// ok we can use a ustar long name instead of pax, now correct the fields
-
-				// remove the path field from the pax header. this will suppress the pax header
-				delete(paxHeaders, paxPath)
-
-				// update the path fields
-				tw.cString(pathHeaderBytes, suffix, false, paxNone, nil)
-				tw.cString(prefixHeaderBytes, prefix, false, paxNone, nil)
-
-				// Use the ustar magic if we used ustar long names.
-				if len(prefix) > 0 && !tw.usedBinary {
-					copy(header[257:265], []byte("ustar\x00"))
-				}
-			}
-		}
-	}
-
-	// The chksum field is terminated by a NUL and a space.
-	// This is different from the other octal fields.
-	chksum, _ := checksum(header)
-	tw.octal(header[148:155], chksum)
-	header[155] = ' '
-
-	if tw.err != nil {
-		// problem with header; probably integer too big for a field.
-		return tw.err
-	}
-
-	if allowPax {
-		for k, v := range hdr.Xattrs {
-			paxHeaders[paxXattr+k] = v
-		}
-	}
-
-	if len(paxHeaders) > 0 {
-		if !allowPax {
-			return errInvalidHeader
-		}
-		if err := tw.writePAXHeader(hdr, paxHeaders); err != nil {
-			return err
-		}
-	}
-	tw.nb = int64(hdr.Size)
-	tw.pad = (blockSize - (tw.nb % blockSize)) % blockSize
-
-	_, tw.err = tw.w.Write(header)
-	return tw.err
-}
-
-// writeUSTARLongName splits a USTAR long name hdr.Name.
-// name must be < 256 characters. errNameTooLong is returned
-// if hdr.Name can't be split. The splitting heuristic
-// is compatible with gnu tar.
-func (tw *Writer) splitUSTARLongName(name string) (prefix, suffix string, err error) {
-	length := len(name)
-	if length > fileNamePrefixSize+1 {
-		length = fileNamePrefixSize + 1
-	} else if name[length-1] == '/' {
-		length--
-	}
-	i := strings.LastIndex(name[:length], "/")
-	// nlen contains the resulting length in the name field.
-	// plen contains the resulting length in the prefix field.
-	nlen := len(name) - i - 1
-	plen := i
-	if i <= 0 || nlen > fileNameSize || nlen == 0 || plen > fileNamePrefixSize {
-		err = errNameTooLong
-		return
-	}
-	prefix, suffix = name[:i], name[i+1:]
-	return
-}
-
-// writePaxHeader writes an extended pax header to the
-// archive.
-func (tw *Writer) writePAXHeader(hdr *Header, paxHeaders map[string]string) error {
-	// Prepare extended header
-	ext := new(Header)
-	ext.Typeflag = TypeXHeader
-	// Setting ModTime is required for reader parsing to
-	// succeed, and seems harmless enough.
-	ext.ModTime = hdr.ModTime
-	// The spec asks that we namespace our pseudo files
-	// with the current pid.
-	pid := os.Getpid()
-	dir, file := path.Split(hdr.Name)
-	fullName := path.Join(dir,
-		fmt.Sprintf("PaxHeaders.%d", pid), file)
-
-	ascii := toASCII(fullName)
-	if len(ascii) > 100 {
-		ascii = ascii[:100]
-	}
-	ext.Name = ascii
-	// Construct the body
-	var buf bytes.Buffer
-
-	for k, v := range paxHeaders {
-		fmt.Fprint(&buf, paxHeader(k+"="+v))
-	}
-
-	ext.Size = int64(len(buf.Bytes()))
-	if err := tw.writeHeader(ext, false); err != nil {
-		return err
-	}
-	if _, err := tw.Write(buf.Bytes()); err != nil {
-		return err
-	}
-	if err := tw.Flush(); err != nil {
-		return err
-	}
-	return nil
-}
-
-// paxHeader formats a single pax record, prefixing it with the appropriate length
-func paxHeader(msg string) string {
-	const padding = 2 // Extra padding for space and newline
-	size := len(msg) + padding
-	size += len(strconv.Itoa(size))
-	record := fmt.Sprintf("%d %s\n", size, msg)
-	if len(record) != size {
-		// Final adjustment if adding size increased
-		// the number of digits in size
-		size = len(record)
-		record = fmt.Sprintf("%d %s\n", size, msg)
-	}
-	return record
-}
-
-// Write writes to the current entry in the tar archive.
-// Write returns the error ErrWriteTooLong if more than
-// hdr.Size bytes are written after WriteHeader.
-func (tw *Writer) Write(b []byte) (n int, err error) {
-	if tw.closed {
-		err = ErrWriteTooLong
-		return
-	}
-	overwrite := false
-	if int64(len(b)) > tw.nb {
-		b = b[0:tw.nb]
-		overwrite = true
-	}
-	n, err = tw.w.Write(b)
-	tw.nb -= int64(n)
-	if err == nil && overwrite {
-		err = ErrWriteTooLong
-		return
-	}
-	tw.err = err
-	return
-}
-
-// Close closes the tar archive, flushing any unwritten
-// data to the underlying writer.
-func (tw *Writer) Close() error {
-	if tw.err != nil || tw.closed {
-		return tw.err
-	}
-	tw.Flush()
-	tw.closed = true
-	if tw.err != nil {
-		return tw.err
-	}
-
-	// trailer: two zero blocks
-	for i := 0; i < 2; i++ {
-		_, tw.err = tw.w.Write(zeroBlock)
-		if tw.err != nil {
-			break
-		}
-	}
-	return tw.err
-}
diff --git a/src/pkg/archive/tar/writer_test.go b/src/pkg/archive/tar/writer_test.go
deleted file mode 100644
index 512fab1..0000000
--- a/src/pkg/archive/tar/writer_test.go
+++ /dev/null
@@ -1,456 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package tar
-
-import (
-	"bytes"
-	"fmt"
-	"io"
-	"io/ioutil"
-	"os"
-	"reflect"
-	"strings"
-	"testing"
-	"testing/iotest"
-	"time"
-)
-
-type writerTestEntry struct {
-	header   *Header
-	contents string
-}
-
-type writerTest struct {
-	file    string // filename of expected output
-	entries []*writerTestEntry
-}
-
-var writerTests = []*writerTest{
-	// The writer test file was produced with this command:
-	// tar (GNU tar) 1.26
-	//   ln -s small.txt link.txt
-	//   tar -b 1 --format=ustar -c -f writer.tar small.txt small2.txt link.txt
-	{
-		file: "testdata/writer.tar",
-		entries: []*writerTestEntry{
-			{
-				header: &Header{
-					Name:     "small.txt",
-					Mode:     0640,
-					Uid:      73025,
-					Gid:      5000,
-					Size:     5,
-					ModTime:  time.Unix(1246508266, 0),
-					Typeflag: '0',
-					Uname:    "dsymonds",
-					Gname:    "eng",
-				},
-				contents: "Kilts",
-			},
-			{
-				header: &Header{
-					Name:     "small2.txt",
-					Mode:     0640,
-					Uid:      73025,
-					Gid:      5000,
-					Size:     11,
-					ModTime:  time.Unix(1245217492, 0),
-					Typeflag: '0',
-					Uname:    "dsymonds",
-					Gname:    "eng",
-				},
-				contents: "Google.com\n",
-			},
-			{
-				header: &Header{
-					Name:     "link.txt",
-					Mode:     0777,
-					Uid:      1000,
-					Gid:      1000,
-					Size:     0,
-					ModTime:  time.Unix(1314603082, 0),
-					Typeflag: '2',
-					Linkname: "small.txt",
-					Uname:    "strings",
-					Gname:    "strings",
-				},
-				// no contents
-			},
-		},
-	},
-	// The truncated test file was produced using these commands:
-	//   dd if=/dev/zero bs=1048576 count=16384 > /tmp/16gig.txt
-	//   tar -b 1 -c -f- /tmp/16gig.txt | dd bs=512 count=8 > writer-big.tar
-	{
-		file: "testdata/writer-big.tar",
-		entries: []*writerTestEntry{
-			{
-				header: &Header{
-					Name:     "tmp/16gig.txt",
-					Mode:     0640,
-					Uid:      73025,
-					Gid:      5000,
-					Size:     16 << 30,
-					ModTime:  time.Unix(1254699560, 0),
-					Typeflag: '0',
-					Uname:    "dsymonds",
-					Gname:    "eng",
-				},
-				// fake contents
-				contents: strings.Repeat("\x00", 4<<10),
-			},
-		},
-	},
-	// The truncated test file was produced using these commands:
-	//   dd if=/dev/zero bs=1048576 count=16384 > (longname/)*15 /16gig.txt
-	//   tar -b 1 -c -f- (longname/)*15 /16gig.txt | dd bs=512 count=8 > writer-big-long.tar
-	{
-		file: "testdata/writer-big-long.tar",
-		entries: []*writerTestEntry{
-			{
-				header: &Header{
-					Name:     strings.Repeat("longname/", 15) + "16gig.txt",
-					Mode:     0644,
-					Uid:      1000,
-					Gid:      1000,
-					Size:     16 << 30,
-					ModTime:  time.Unix(1399583047, 0),
-					Typeflag: '0',
-					Uname:    "guillaume",
-					Gname:    "guillaume",
-				},
-				// fake contents
-				contents: strings.Repeat("\x00", 4<<10),
-			},
-		},
-	},
-	// This file was produced using gnu tar 1.17
-	// gnutar  -b 4 --format=ustar (longname/)*15 + file.txt
-	{
-		file: "testdata/ustar.tar",
-		entries: []*writerTestEntry{
-			{
-				header: &Header{
-					Name:     strings.Repeat("longname/", 15) + "file.txt",
-					Mode:     0644,
-					Uid:      0765,
-					Gid:      024,
-					Size:     06,
-					ModTime:  time.Unix(1360135598, 0),
-					Typeflag: '0',
-					Uname:    "shane",
-					Gname:    "staff",
-				},
-				contents: "hello\n",
-			},
-		},
-	},
-}
-
-// Render byte array in a two-character hexadecimal string, spaced for easy visual inspection.
-func bytestr(offset int, b []byte) string {
-	const rowLen = 32
-	s := fmt.Sprintf("%04x ", offset)
-	for _, ch := range b {
-		switch {
-		case '0' <= ch && ch <= '9', 'A' <= ch && ch <= 'Z', 'a' <= ch && ch <= 'z':
-			s += fmt.Sprintf("  %c", ch)
-		default:
-			s += fmt.Sprintf(" %02x", ch)
-		}
-	}
-	return s
-}
-
-// Render a pseudo-diff between two blocks of bytes.
-func bytediff(a []byte, b []byte) string {
-	const rowLen = 32
-	s := fmt.Sprintf("(%d bytes vs. %d bytes)\n", len(a), len(b))
-	for offset := 0; len(a)+len(b) > 0; offset += rowLen {
-		na, nb := rowLen, rowLen
-		if na > len(a) {
-			na = len(a)
-		}
-		if nb > len(b) {
-			nb = len(b)
-		}
-		sa := bytestr(offset, a[0:na])
-		sb := bytestr(offset, b[0:nb])
-		if sa != sb {
-			s += fmt.Sprintf("-%v\n+%v\n", sa, sb)
-		}
-		a = a[na:]
-		b = b[nb:]
-	}
-	return s
-}
-
-func TestWriter(t *testing.T) {
-testLoop:
-	for i, test := range writerTests {
-		expected, err := ioutil.ReadFile(test.file)
-		if err != nil {
-			t.Errorf("test %d: Unexpected error: %v", i, err)
-			continue
-		}
-
-		buf := new(bytes.Buffer)
-		tw := NewWriter(iotest.TruncateWriter(buf, 4<<10)) // only catch the first 4 KB
-		big := false
-		for j, entry := range test.entries {
-			big = big || entry.header.Size > 1<<10
-			if err := tw.WriteHeader(entry.header); err != nil {
-				t.Errorf("test %d, entry %d: Failed writing header: %v", i, j, err)
-				continue testLoop
-			}
-			if _, err := io.WriteString(tw, entry.contents); err != nil {
-				t.Errorf("test %d, entry %d: Failed writing contents: %v", i, j, err)
-				continue testLoop
-			}
-		}
-		// Only interested in Close failures for the small tests.
-		if err := tw.Close(); err != nil && !big {
-			t.Errorf("test %d: Failed closing archive: %v", i, err)
-			continue testLoop
-		}
-
-		actual := buf.Bytes()
-		if !bytes.Equal(expected, actual) {
-			t.Errorf("test %d: Incorrect result: (-=expected, +=actual)\n%v",
-				i, bytediff(expected, actual))
-		}
-		if testing.Short() { // The second test is expensive.
-			break
-		}
-	}
-}
-
-func TestPax(t *testing.T) {
-	// Create an archive with a large name
-	fileinfo, err := os.Stat("testdata/small.txt")
-	if err != nil {
-		t.Fatal(err)
-	}
-	hdr, err := FileInfoHeader(fileinfo, "")
-	if err != nil {
-		t.Fatalf("os.Stat: %v", err)
-	}
-	// Force a PAX long name to be written
-	longName := strings.Repeat("ab", 100)
-	contents := strings.Repeat(" ", int(hdr.Size))
-	hdr.Name = longName
-	var buf bytes.Buffer
-	writer := NewWriter(&buf)
-	if err := writer.WriteHeader(hdr); err != nil {
-		t.Fatal(err)
-	}
-	if _, err = writer.Write([]byte(contents)); err != nil {
-		t.Fatal(err)
-	}
-	if err := writer.Close(); err != nil {
-		t.Fatal(err)
-	}
-	// Simple test to make sure PAX extensions are in effect
-	if !bytes.Contains(buf.Bytes(), []byte("PaxHeaders.")) {
-		t.Fatal("Expected at least one PAX header to be written.")
-	}
-	// Test that we can get a long name back out of the archive.
-	reader := NewReader(&buf)
-	hdr, err = reader.Next()
-	if err != nil {
-		t.Fatal(err)
-	}
-	if hdr.Name != longName {
-		t.Fatal("Couldn't recover long file name")
-	}
-}
-
-func TestPaxSymlink(t *testing.T) {
-	// Create an archive with a large linkname
-	fileinfo, err := os.Stat("testdata/small.txt")
-	if err != nil {
-		t.Fatal(err)
-	}
-	hdr, err := FileInfoHeader(fileinfo, "")
-	hdr.Typeflag = TypeSymlink
-	if err != nil {
-		t.Fatalf("os.Stat:1 %v", err)
-	}
-	// Force a PAX long linkname to be written
-	longLinkname := strings.Repeat("1234567890/1234567890", 10)
-	hdr.Linkname = longLinkname
-
-	hdr.Size = 0
-	var buf bytes.Buffer
-	writer := NewWriter(&buf)
-	if err := writer.WriteHeader(hdr); err != nil {
-		t.Fatal(err)
-	}
-	if err := writer.Close(); err != nil {
-		t.Fatal(err)
-	}
-	// Simple test to make sure PAX extensions are in effect
-	if !bytes.Contains(buf.Bytes(), []byte("PaxHeaders.")) {
-		t.Fatal("Expected at least one PAX header to be written.")
-	}
-	// Test that we can get a long name back out of the archive.
-	reader := NewReader(&buf)
-	hdr, err = reader.Next()
-	if err != nil {
-		t.Fatal(err)
-	}
-	if hdr.Linkname != longLinkname {
-		t.Fatal("Couldn't recover long link name")
-	}
-}
-
-func TestPaxNonAscii(t *testing.T) {
-	// Create an archive with non ascii. These should trigger a pax header
-	// because pax headers have a defined utf-8 encoding.
-	fileinfo, err := os.Stat("testdata/small.txt")
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	hdr, err := FileInfoHeader(fileinfo, "")
-	if err != nil {
-		t.Fatalf("os.Stat:1 %v", err)
-	}
-
-	// some sample data
-	chineseFilename := "文件名"
-	chineseGroupname := "組"
-	chineseUsername := "用戶名"
-
-	hdr.Name = chineseFilename
-	hdr.Gname = chineseGroupname
-	hdr.Uname = chineseUsername
-
-	contents := strings.Repeat(" ", int(hdr.Size))
-
-	var buf bytes.Buffer
-	writer := NewWriter(&buf)
-	if err := writer.WriteHeader(hdr); err != nil {
-		t.Fatal(err)
-	}
-	if _, err = writer.Write([]byte(contents)); err != nil {
-		t.Fatal(err)
-	}
-	if err := writer.Close(); err != nil {
-		t.Fatal(err)
-	}
-	// Simple test to make sure PAX extensions are in effect
-	if !bytes.Contains(buf.Bytes(), []byte("PaxHeaders.")) {
-		t.Fatal("Expected at least one PAX header to be written.")
-	}
-	// Test that we can get a long name back out of the archive.
-	reader := NewReader(&buf)
-	hdr, err = reader.Next()
-	if err != nil {
-		t.Fatal(err)
-	}
-	if hdr.Name != chineseFilename {
-		t.Fatal("Couldn't recover unicode name")
-	}
-	if hdr.Gname != chineseGroupname {
-		t.Fatal("Couldn't recover unicode group")
-	}
-	if hdr.Uname != chineseUsername {
-		t.Fatal("Couldn't recover unicode user")
-	}
-}
-
-func TestPaxXattrs(t *testing.T) {
-	xattrs := map[string]string{
-		"user.key": "value",
-	}
-
-	// Create an archive with an xattr
-	fileinfo, err := os.Stat("testdata/small.txt")
-	if err != nil {
-		t.Fatal(err)
-	}
-	hdr, err := FileInfoHeader(fileinfo, "")
-	if err != nil {
-		t.Fatalf("os.Stat: %v", err)
-	}
-	contents := "Kilts"
-	hdr.Xattrs = xattrs
-	var buf bytes.Buffer
-	writer := NewWriter(&buf)
-	if err := writer.WriteHeader(hdr); err != nil {
-		t.Fatal(err)
-	}
-	if _, err = writer.Write([]byte(contents)); err != nil {
-		t.Fatal(err)
-	}
-	if err := writer.Close(); err != nil {
-		t.Fatal(err)
-	}
-	// Test that we can get the xattrs back out of the archive.
-	reader := NewReader(&buf)
-	hdr, err = reader.Next()
-	if err != nil {
-		t.Fatal(err)
-	}
-	if !reflect.DeepEqual(hdr.Xattrs, xattrs) {
-		t.Fatalf("xattrs did not survive round trip: got %+v, want %+v",
-			hdr.Xattrs, xattrs)
-	}
-}
-
-func TestPAXHeader(t *testing.T) {
-	medName := strings.Repeat("CD", 50)
-	longName := strings.Repeat("AB", 100)
-	paxTests := [][2]string{
-		{paxPath + "=/etc/hosts", "19 path=/etc/hosts\n"},
-		{"a=b", "6 a=b\n"},          // Single digit length
-		{"a=names", "11 a=names\n"}, // Test case involving carries
-		{paxPath + "=" + longName, fmt.Sprintf("210 path=%s\n", longName)},
-		{paxPath + "=" + medName, fmt.Sprintf("110 path=%s\n", medName)}}
-
-	for _, test := range paxTests {
-		key, expected := test[0], test[1]
-		if result := paxHeader(key); result != expected {
-			t.Fatalf("paxHeader: got %s, expected %s", result, expected)
-		}
-	}
-}
-
-func TestUSTARLongName(t *testing.T) {
-	// Create an archive with a path that failed to split with USTAR extension in previous versions.
-	fileinfo, err := os.Stat("testdata/small.txt")
-	if err != nil {
-		t.Fatal(err)
-	}
-	hdr, err := FileInfoHeader(fileinfo, "")
-	hdr.Typeflag = TypeDir
-	if err != nil {
-		t.Fatalf("os.Stat:1 %v", err)
-	}
-	// Force a PAX long name to be written. The name was taken from a practical example
-	// that fails and replaced ever char through numbers to anonymize the sample.
-	longName := "/0000_0000000/00000-000000000/0000_0000000/00000-0000000000000/0000_0000000/00000-0000000-00000000/0000_0000000/00000000/0000_0000000/000/0000_0000000/00000000v00/0000_0000000/000000/0000_0000000/0000000/0000_0000000/00000y-00/0000/0000/00000000/0x000000/"
-	hdr.Name = longName
-
-	hdr.Size = 0
-	var buf bytes.Buffer
-	writer := NewWriter(&buf)
-	if err := writer.WriteHeader(hdr); err != nil {
-		t.Fatal(err)
-	}
-	if err := writer.Close(); err != nil {
-		t.Fatal(err)
-	}
-	// Test that we can get a long name back out of the archive.
-	reader := NewReader(&buf)
-	hdr, err = reader.Next()
-	if err != nil {
-		t.Fatal(err)
-	}
-	if hdr.Name != longName {
-		t.Fatal("Couldn't recover long name")
-	}
-}
diff --git a/src/pkg/archive/zip/reader.go b/src/pkg/archive/zip/reader.go
deleted file mode 100644
index 80ee030..0000000
--- a/src/pkg/archive/zip/reader.go
+++ /dev/null
@@ -1,448 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package zip
-
-import (
-	"bufio"
-	"encoding/binary"
-	"errors"
-	"hash"
-	"hash/crc32"
-	"io"
-	"os"
-)
-
-var (
-	ErrFormat    = errors.New("zip: not a valid zip file")
-	ErrAlgorithm = errors.New("zip: unsupported compression algorithm")
-	ErrChecksum  = errors.New("zip: checksum error")
-)
-
-type Reader struct {
-	r       io.ReaderAt
-	File    []*File
-	Comment string
-}
-
-type ReadCloser struct {
-	f *os.File
-	Reader
-}
-
-type File struct {
-	FileHeader
-	zipr         io.ReaderAt
-	zipsize      int64
-	headerOffset int64
-}
-
-func (f *File) hasDataDescriptor() bool {
-	return f.Flags&0x8 != 0
-}
-
-// OpenReader will open the Zip file specified by name and return a ReadCloser.
-func OpenReader(name string) (*ReadCloser, error) {
-	f, err := os.Open(name)
-	if err != nil {
-		return nil, err
-	}
-	fi, err := f.Stat()
-	if err != nil {
-		f.Close()
-		return nil, err
-	}
-	r := new(ReadCloser)
-	if err := r.init(f, fi.Size()); err != nil {
-		f.Close()
-		return nil, err
-	}
-	r.f = f
-	return r, nil
-}
-
-// NewReader returns a new Reader reading from r, which is assumed to
-// have the given size in bytes.
-func NewReader(r io.ReaderAt, size int64) (*Reader, error) {
-	zr := new(Reader)
-	if err := zr.init(r, size); err != nil {
-		return nil, err
-	}
-	return zr, nil
-}
-
-func (z *Reader) init(r io.ReaderAt, size int64) error {
-	end, err := readDirectoryEnd(r, size)
-	if err != nil {
-		return err
-	}
-	z.r = r
-	z.File = make([]*File, 0, end.directoryRecords)
-	z.Comment = end.comment
-	rs := io.NewSectionReader(r, 0, size)
-	if _, err = rs.Seek(int64(end.directoryOffset), os.SEEK_SET); err != nil {
-		return err
-	}
-	buf := bufio.NewReader(rs)
-
-	// The count of files inside a zip is truncated to fit in a uint16.
-	// Gloss over this by reading headers until we encounter
-	// a bad one, and then only report a ErrFormat or UnexpectedEOF if
-	// the file count modulo 65536 is incorrect.
-	for {
-		f := &File{zipr: r, zipsize: size}
-		err = readDirectoryHeader(f, buf)
-		if err == ErrFormat || err == io.ErrUnexpectedEOF {
-			break
-		}
-		if err != nil {
-			return err
-		}
-		z.File = append(z.File, f)
-	}
-	if uint16(len(z.File)) != uint16(end.directoryRecords) { // only compare 16 bits here
-		// Return the readDirectoryHeader error if we read
-		// the wrong number of directory entries.
-		return err
-	}
-	return nil
-}
-
-// Close closes the Zip file, rendering it unusable for I/O.
-func (rc *ReadCloser) Close() error {
-	return rc.f.Close()
-}
-
-// DataOffset returns the offset of the file's possibly-compressed
-// data, relative to the beginning of the zip file.
-//
-// Most callers should instead use Open, which transparently
-// decompresses data and verifies checksums.
-func (f *File) DataOffset() (offset int64, err error) {
-	bodyOffset, err := f.findBodyOffset()
-	if err != nil {
-		return
-	}
-	return f.headerOffset + bodyOffset, nil
-}
-
-// Open returns a ReadCloser that provides access to the File's contents.
-// Multiple files may be read concurrently.
-func (f *File) Open() (rc io.ReadCloser, err error) {
-	bodyOffset, err := f.findBodyOffset()
-	if err != nil {
-		return
-	}
-	size := int64(f.CompressedSize64)
-	r := io.NewSectionReader(f.zipr, f.headerOffset+bodyOffset, size)
-	dcomp := decompressor(f.Method)
-	if dcomp == nil {
-		err = ErrAlgorithm
-		return
-	}
-	rc = dcomp(r)
-	var desr io.Reader
-	if f.hasDataDescriptor() {
-		desr = io.NewSectionReader(f.zipr, f.headerOffset+bodyOffset+size, dataDescriptorLen)
-	}
-	rc = &checksumReader{rc, crc32.NewIEEE(), f, desr, nil}
-	return
-}
-
-type checksumReader struct {
-	rc   io.ReadCloser
-	hash hash.Hash32
-	f    *File
-	desr io.Reader // if non-nil, where to read the data descriptor
-	err  error     // sticky error
-}
-
-func (r *checksumReader) Read(b []byte) (n int, err error) {
-	if r.err != nil {
-		return 0, r.err
-	}
-	n, err = r.rc.Read(b)
-	r.hash.Write(b[:n])
-	if err == nil {
-		return
-	}
-	if err == io.EOF {
-		if r.desr != nil {
-			if err1 := readDataDescriptor(r.desr, r.f); err1 != nil {
-				err = err1
-			} else if r.hash.Sum32() != r.f.CRC32 {
-				err = ErrChecksum
-			}
-		} else {
-			// If there's not a data descriptor, we still compare
-			// the CRC32 of what we've read against the file header
-			// or TOC's CRC32, if it seems like it was set.
-			if r.f.CRC32 != 0 && r.hash.Sum32() != r.f.CRC32 {
-				err = ErrChecksum
-			}
-		}
-	}
-	r.err = err
-	return
-}
-
-func (r *checksumReader) Close() error { return r.rc.Close() }
-
-// findBodyOffset does the minimum work to verify the file has a header
-// and returns the file body offset.
-func (f *File) findBodyOffset() (int64, error) {
-	var buf [fileHeaderLen]byte
-	if _, err := f.zipr.ReadAt(buf[:], f.headerOffset); err != nil {
-		return 0, err
-	}
-	b := readBuf(buf[:])
-	if sig := b.uint32(); sig != fileHeaderSignature {
-		return 0, ErrFormat
-	}
-	b = b[22:] // skip over most of the header
-	filenameLen := int(b.uint16())
-	extraLen := int(b.uint16())
-	return int64(fileHeaderLen + filenameLen + extraLen), nil
-}
-
-// readDirectoryHeader attempts to read a directory header from r.
-// It returns io.ErrUnexpectedEOF if it cannot read a complete header,
-// and ErrFormat if it doesn't find a valid header signature.
-func readDirectoryHeader(f *File, r io.Reader) error {
-	var buf [directoryHeaderLen]byte
-	if _, err := io.ReadFull(r, buf[:]); err != nil {
-		return err
-	}
-	b := readBuf(buf[:])
-	if sig := b.uint32(); sig != directoryHeaderSignature {
-		return ErrFormat
-	}
-	f.CreatorVersion = b.uint16()
-	f.ReaderVersion = b.uint16()
-	f.Flags = b.uint16()
-	f.Method = b.uint16()
-	f.ModifiedTime = b.uint16()
-	f.ModifiedDate = b.uint16()
-	f.CRC32 = b.uint32()
-	f.CompressedSize = b.uint32()
-	f.UncompressedSize = b.uint32()
-	f.CompressedSize64 = uint64(f.CompressedSize)
-	f.UncompressedSize64 = uint64(f.UncompressedSize)
-	filenameLen := int(b.uint16())
-	extraLen := int(b.uint16())
-	commentLen := int(b.uint16())
-	b = b[4:] // skipped start disk number and internal attributes (2x uint16)
-	f.ExternalAttrs = b.uint32()
-	f.headerOffset = int64(b.uint32())
-	d := make([]byte, filenameLen+extraLen+commentLen)
-	if _, err := io.ReadFull(r, d); err != nil {
-		return err
-	}
-	f.Name = string(d[:filenameLen])
-	f.Extra = d[filenameLen : filenameLen+extraLen]
-	f.Comment = string(d[filenameLen+extraLen:])
-
-	if len(f.Extra) > 0 {
-		b := readBuf(f.Extra)
-		for len(b) >= 4 { // need at least tag and size
-			tag := b.uint16()
-			size := b.uint16()
-			if int(size) > len(b) {
-				return ErrFormat
-			}
-			if tag == zip64ExtraId {
-				// update directory values from the zip64 extra block
-				eb := readBuf(b[:size])
-				if len(eb) >= 8 {
-					f.UncompressedSize64 = eb.uint64()
-				}
-				if len(eb) >= 8 {
-					f.CompressedSize64 = eb.uint64()
-				}
-				if len(eb) >= 8 {
-					f.headerOffset = int64(eb.uint64())
-				}
-			}
-			b = b[size:]
-		}
-		// Should have consumed the whole header.
-		if len(b) != 0 {
-			return ErrFormat
-		}
-	}
-	return nil
-}
-
-func readDataDescriptor(r io.Reader, f *File) error {
-	var buf [dataDescriptorLen]byte
-
-	// The spec says: "Although not originally assigned a
-	// signature, the value 0x08074b50 has commonly been adopted
-	// as a signature value for the data descriptor record.
-	// Implementers should be aware that ZIP files may be
-	// encountered with or without this signature marking data
-	// descriptors and should account for either case when reading
-	// ZIP files to ensure compatibility."
-	//
-	// dataDescriptorLen includes the size of the signature but
-	// first read just those 4 bytes to see if it exists.
-	if _, err := io.ReadFull(r, buf[:4]); err != nil {
-		return err
-	}
-	off := 0
-	maybeSig := readBuf(buf[:4])
-	if maybeSig.uint32() != dataDescriptorSignature {
-		// No data descriptor signature. Keep these four
-		// bytes.
-		off += 4
-	}
-	if _, err := io.ReadFull(r, buf[off:12]); err != nil {
-		return err
-	}
-	b := readBuf(buf[:12])
-	if b.uint32() != f.CRC32 {
-		return ErrChecksum
-	}
-
-	// The two sizes that follow here can be either 32 bits or 64 bits
-	// but the spec is not very clear on this and different
-	// interpretations has been made causing incompatibilities. We
-	// already have the sizes from the central directory so we can
-	// just ignore these.
-
-	return nil
-}
-
-func readDirectoryEnd(r io.ReaderAt, size int64) (dir *directoryEnd, err error) {
-	// look for directoryEndSignature in the last 1k, then in the last 65k
-	var buf []byte
-	var directoryEndOffset int64
-	for i, bLen := range []int64{1024, 65 * 1024} {
-		if bLen > size {
-			bLen = size
-		}
-		buf = make([]byte, int(bLen))
-		if _, err := r.ReadAt(buf, size-bLen); err != nil && err != io.EOF {
-			return nil, err
-		}
-		if p := findSignatureInBlock(buf); p >= 0 {
-			buf = buf[p:]
-			directoryEndOffset = size - bLen + int64(p)
-			break
-		}
-		if i == 1 || bLen == size {
-			return nil, ErrFormat
-		}
-	}
-
-	// read header into struct
-	b := readBuf(buf[4:]) // skip signature
-	d := &directoryEnd{
-		diskNbr:            uint32(b.uint16()),
-		dirDiskNbr:         uint32(b.uint16()),
-		dirRecordsThisDisk: uint64(b.uint16()),
-		directoryRecords:   uint64(b.uint16()),
-		directorySize:      uint64(b.uint32()),
-		directoryOffset:    uint64(b.uint32()),
-		commentLen:         b.uint16(),
-	}
-	l := int(d.commentLen)
-	if l > len(b) {
-		return nil, errors.New("zip: invalid comment length")
-	}
-	d.comment = string(b[:l])
-
-	p, err := findDirectory64End(r, directoryEndOffset)
-	if err == nil && p >= 0 {
-		err = readDirectory64End(r, p, d)
-	}
-	if err != nil {
-		return nil, err
-	}
-
-	// Make sure directoryOffset points to somewhere in our file.
-	if o := int64(d.directoryOffset); o < 0 || o >= size {
-		return nil, ErrFormat
-	}
-	return d, nil
-}
-
-// findDirectory64End tries to read the zip64 locator just before the
-// directory end and returns the offset of the zip64 directory end if
-// found.
-func findDirectory64End(r io.ReaderAt, directoryEndOffset int64) (int64, error) {
-	locOffset := directoryEndOffset - directory64LocLen
-	if locOffset < 0 {
-		return -1, nil // no need to look for a header outside the file
-	}
-	buf := make([]byte, directory64LocLen)
-	if _, err := r.ReadAt(buf, locOffset); err != nil {
-		return -1, err
-	}
-	b := readBuf(buf)
-	if sig := b.uint32(); sig != directory64LocSignature {
-		return -1, nil
-	}
-	b = b[4:]       // skip number of the disk with the start of the zip64 end of central directory
-	p := b.uint64() // relative offset of the zip64 end of central directory record
-	return int64(p), nil
-}
-
-// readDirectory64End reads the zip64 directory end and updates the
-// directory end with the zip64 directory end values.
-func readDirectory64End(r io.ReaderAt, offset int64, d *directoryEnd) (err error) {
-	buf := make([]byte, directory64EndLen)
-	if _, err := r.ReadAt(buf, offset); err != nil {
-		return err
-	}
-
-	b := readBuf(buf)
-	if sig := b.uint32(); sig != directory64EndSignature {
-		return ErrFormat
-	}
-
-	b = b[12:]                        // skip dir size, version and version needed (uint64 + 2x uint16)
-	d.diskNbr = b.uint32()            // number of this disk
-	d.dirDiskNbr = b.uint32()         // number of the disk with the start of the central directory
-	d.dirRecordsThisDisk = b.uint64() // total number of entries in the central directory on this disk
-	d.directoryRecords = b.uint64()   // total number of entries in the central directory
-	d.directorySize = b.uint64()      // size of the central directory
-	d.directoryOffset = b.uint64()    // offset of start of central directory with respect to the starting disk number
-
-	return nil
-}
-
-func findSignatureInBlock(b []byte) int {
-	for i := len(b) - directoryEndLen; i >= 0; i-- {
-		// defined from directoryEndSignature in struct.go
-		if b[i] == 'P' && b[i+1] == 'K' && b[i+2] == 0x05 && b[i+3] == 0x06 {
-			// n is length of comment
-			n := int(b[i+directoryEndLen-2]) | int(b[i+directoryEndLen-1])<<8
-			if n+directoryEndLen+i <= len(b) {
-				return i
-			}
-		}
-	}
-	return -1
-}
-
-type readBuf []byte
-
-func (b *readBuf) uint16() uint16 {
-	v := binary.LittleEndian.Uint16(*b)
-	*b = (*b)[2:]
-	return v
-}
-
-func (b *readBuf) uint32() uint32 {
-	v := binary.LittleEndian.Uint32(*b)
-	*b = (*b)[4:]
-	return v
-}
-
-func (b *readBuf) uint64() uint64 {
-	v := binary.LittleEndian.Uint64(*b)
-	*b = (*b)[8:]
-	return v
-}
diff --git a/src/pkg/archive/zip/reader_test.go b/src/pkg/archive/zip/reader_test.go
deleted file mode 100644
index 5652f3a..0000000
--- a/src/pkg/archive/zip/reader_test.go
+++ /dev/null
@@ -1,510 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package zip
-
-import (
-	"bytes"
-	"encoding/binary"
-	"encoding/hex"
-	"io"
-	"io/ioutil"
-	"os"
-	"path/filepath"
-	"regexp"
-	"testing"
-	"time"
-)
-
-type ZipTest struct {
-	Name    string
-	Source  func() (r io.ReaderAt, size int64) // if non-nil, used instead of testdata/<Name> file
-	Comment string
-	File    []ZipTestFile
-	Error   error // the error that Opening this file should return
-}
-
-type ZipTestFile struct {
-	Name       string
-	Content    []byte // if blank, will attempt to compare against File
-	ContentErr error
-	File       string // name of file to compare to (relative to testdata/)
-	Mtime      string // modified time in format "mm-dd-yy hh:mm:ss"
-	Mode       os.FileMode
-}
-
-// Caution: The Mtime values found for the test files should correspond to
-//          the values listed with unzip -l <zipfile>. However, the values
-//          listed by unzip appear to be off by some hours. When creating
-//          fresh test files and testing them, this issue is not present.
-//          The test files were created in Sydney, so there might be a time
-//          zone issue. The time zone information does have to be encoded
-//          somewhere, because otherwise unzip -l could not provide a different
-//          time from what the archive/zip package provides, but there appears
-//          to be no documentation about this.
-
-var tests = []ZipTest{
-	{
-		Name:    "test.zip",
-		Comment: "This is a zipfile comment.",
-		File: []ZipTestFile{
-			{
-				Name:    "test.txt",
-				Content: []byte("This is a test text file.\n"),
-				Mtime:   "09-05-10 12:12:02",
-				Mode:    0644,
-			},
-			{
-				Name:  "gophercolor16x16.png",
-				File:  "gophercolor16x16.png",
-				Mtime: "09-05-10 15:52:58",
-				Mode:  0644,
-			},
-		},
-	},
-	{
-		Name:    "test-trailing-junk.zip",
-		Comment: "This is a zipfile comment.",
-		File: []ZipTestFile{
-			{
-				Name:    "test.txt",
-				Content: []byte("This is a test text file.\n"),
-				Mtime:   "09-05-10 12:12:02",
-				Mode:    0644,
-			},
-			{
-				Name:  "gophercolor16x16.png",
-				File:  "gophercolor16x16.png",
-				Mtime: "09-05-10 15:52:58",
-				Mode:  0644,
-			},
-		},
-	},
-	{
-		Name:   "r.zip",
-		Source: returnRecursiveZip,
-		File: []ZipTestFile{
-			{
-				Name:    "r/r.zip",
-				Content: rZipBytes(),
-				Mtime:   "03-04-10 00:24:16",
-				Mode:    0666,
-			},
-		},
-	},
-	{
-		Name: "symlink.zip",
-		File: []ZipTestFile{
-			{
-				Name:    "symlink",
-				Content: []byte("../target"),
-				Mode:    0777 | os.ModeSymlink,
-			},
-		},
-	},
-	{
-		Name: "readme.zip",
-	},
-	{
-		Name:  "readme.notzip",
-		Error: ErrFormat,
-	},
-	{
-		Name: "dd.zip",
-		File: []ZipTestFile{
-			{
-				Name:    "filename",
-				Content: []byte("This is a test textfile.\n"),
-				Mtime:   "02-02-11 13:06:20",
-				Mode:    0666,
-			},
-		},
-	},
-	{
-		// created in windows XP file manager.
-		Name: "winxp.zip",
-		File: crossPlatform,
-	},
-	{
-		// created by Zip 3.0 under Linux
-		Name: "unix.zip",
-		File: crossPlatform,
-	},
-	{
-		// created by Go, before we wrote the "optional" data
-		// descriptor signatures (which are required by OS X)
-		Name: "go-no-datadesc-sig.zip",
-		File: []ZipTestFile{
-			{
-				Name:    "foo.txt",
-				Content: []byte("foo\n"),
-				Mtime:   "03-08-12 16:59:10",
-				Mode:    0644,
-			},
-			{
-				Name:    "bar.txt",
-				Content: []byte("bar\n"),
-				Mtime:   "03-08-12 16:59:12",
-				Mode:    0644,
-			},
-		},
-	},
-	{
-		// created by Go, after we wrote the "optional" data
-		// descriptor signatures (which are required by OS X)
-		Name: "go-with-datadesc-sig.zip",
-		File: []ZipTestFile{
-			{
-				Name:    "foo.txt",
-				Content: []byte("foo\n"),
-				Mode:    0666,
-			},
-			{
-				Name:    "bar.txt",
-				Content: []byte("bar\n"),
-				Mode:    0666,
-			},
-		},
-	},
-	{
-		Name:   "Bad-CRC32-in-data-descriptor",
-		Source: returnCorruptCRC32Zip,
-		File: []ZipTestFile{
-			{
-				Name:       "foo.txt",
-				Content:    []byte("foo\n"),
-				Mode:       0666,
-				ContentErr: ErrChecksum,
-			},
-			{
-				Name:    "bar.txt",
-				Content: []byte("bar\n"),
-				Mode:    0666,
-			},
-		},
-	},
-	// Tests that we verify (and accept valid) crc32s on files
-	// with crc32s in their file header (not in data descriptors)
-	{
-		Name: "crc32-not-streamed.zip",
-		File: []ZipTestFile{
-			{
-				Name:    "foo.txt",
-				Content: []byte("foo\n"),
-				Mtime:   "03-08-12 16:59:10",
-				Mode:    0644,
-			},
-			{
-				Name:    "bar.txt",
-				Content: []byte("bar\n"),
-				Mtime:   "03-08-12 16:59:12",
-				Mode:    0644,
-			},
-		},
-	},
-	// Tests that we verify (and reject invalid) crc32s on files
-	// with crc32s in their file header (not in data descriptors)
-	{
-		Name:   "crc32-not-streamed.zip",
-		Source: returnCorruptNotStreamedZip,
-		File: []ZipTestFile{
-			{
-				Name:       "foo.txt",
-				Content:    []byte("foo\n"),
-				Mtime:      "03-08-12 16:59:10",
-				Mode:       0644,
-				ContentErr: ErrChecksum,
-			},
-			{
-				Name:    "bar.txt",
-				Content: []byte("bar\n"),
-				Mtime:   "03-08-12 16:59:12",
-				Mode:    0644,
-			},
-		},
-	},
-	{
-		Name: "zip64.zip",
-		File: []ZipTestFile{
-			{
-				Name:    "README",
-				Content: []byte("This small file is in ZIP64 format.\n"),
-				Mtime:   "08-10-12 14:33:32",
-				Mode:    0644,
-			},
-		},
-	},
-	// Another zip64 file with different Extras fields. (golang.org/issue/7069)
-	{
-		Name: "zip64-2.zip",
-		File: []ZipTestFile{
-			{
-				Name:    "README",
-				Content: []byte("This small file is in ZIP64 format.\n"),
-				Mtime:   "08-10-12 14:33:32",
-				Mode:    0644,
-			},
-		},
-	},
-}
-
-var crossPlatform = []ZipTestFile{
-	{
-		Name:    "hello",
-		Content: []byte("world \r\n"),
-		Mode:    0666,
-	},
-	{
-		Name:    "dir/bar",
-		Content: []byte("foo \r\n"),
-		Mode:    0666,
-	},
-	{
-		Name:    "dir/empty/",
-		Content: []byte{},
-		Mode:    os.ModeDir | 0777,
-	},
-	{
-		Name:    "readonly",
-		Content: []byte("important \r\n"),
-		Mode:    0444,
-	},
-}
-
-func TestReader(t *testing.T) {
-	for _, zt := range tests {
-		readTestZip(t, zt)
-	}
-}
-
-func readTestZip(t *testing.T, zt ZipTest) {
-	var z *Reader
-	var err error
-	if zt.Source != nil {
-		rat, size := zt.Source()
-		z, err = NewReader(rat, size)
-	} else {
-		var rc *ReadCloser
-		rc, err = OpenReader(filepath.Join("testdata", zt.Name))
-		if err == nil {
-			defer rc.Close()
-			z = &rc.Reader
-		}
-	}
-	if err != zt.Error {
-		t.Errorf("%s: error=%v, want %v", zt.Name, err, zt.Error)
-		return
-	}
-
-	// bail if file is not zip
-	if err == ErrFormat {
-		return
-	}
-
-	// bail here if no Files expected to be tested
-	// (there may actually be files in the zip, but we don't care)
-	if zt.File == nil {
-		return
-	}
-
-	if z.Comment != zt.Comment {
-		t.Errorf("%s: comment=%q, want %q", zt.Name, z.Comment, zt.Comment)
-	}
-	if len(z.File) != len(zt.File) {
-		t.Fatalf("%s: file count=%d, want %d", zt.Name, len(z.File), len(zt.File))
-	}
-
-	// test read of each file
-	for i, ft := range zt.File {
-		readTestFile(t, zt, ft, z.File[i])
-	}
-
-	// test simultaneous reads
-	n := 0
-	done := make(chan bool)
-	for i := 0; i < 5; i++ {
-		for j, ft := range zt.File {
-			go func(j int, ft ZipTestFile) {
-				readTestFile(t, zt, ft, z.File[j])
-				done <- true
-			}(j, ft)
-			n++
-		}
-	}
-	for ; n > 0; n-- {
-		<-done
-	}
-}
-
-func readTestFile(t *testing.T, zt ZipTest, ft ZipTestFile, f *File) {
-	if f.Name != ft.Name {
-		t.Errorf("%s: name=%q, want %q", zt.Name, f.Name, ft.Name)
-	}
-
-	if ft.Mtime != "" {
-		mtime, err := time.Parse("01-02-06 15:04:05", ft.Mtime)
-		if err != nil {
-			t.Error(err)
-			return
-		}
-		if ft := f.ModTime(); !ft.Equal(mtime) {
-			t.Errorf("%s: %s: mtime=%s, want %s", zt.Name, f.Name, ft, mtime)
-		}
-	}
-
-	testFileMode(t, zt.Name, f, ft.Mode)
-
-	var b bytes.Buffer
-	r, err := f.Open()
-	if err != nil {
-		t.Errorf("%s: %v", zt.Name, err)
-		return
-	}
-
-	_, err = io.Copy(&b, r)
-	if err != ft.ContentErr {
-		t.Errorf("%s: copying contents: %v (want %v)", zt.Name, err, ft.ContentErr)
-	}
-	if err != nil {
-		return
-	}
-	r.Close()
-
-	size := uint64(f.UncompressedSize)
-	if size == uint32max {
-		size = f.UncompressedSize64
-	}
-	if g := uint64(b.Len()); g != size {
-		t.Errorf("%v: read %v bytes but f.UncompressedSize == %v", f.Name, g, size)
-	}
-
-	var c []byte
-	if ft.Content != nil {
-		c = ft.Content
-	} else if c, err = ioutil.ReadFile("testdata/" + ft.File); err != nil {
-		t.Error(err)
-		return
-	}
-
-	if b.Len() != len(c) {
-		t.Errorf("%s: len=%d, want %d", f.Name, b.Len(), len(c))
-		return
-	}
-
-	for i, b := range b.Bytes() {
-		if b != c[i] {
-			t.Errorf("%s: content[%d]=%q want %q", f.Name, i, b, c[i])
-			return
-		}
-	}
-}
-
-func testFileMode(t *testing.T, zipName string, f *File, want os.FileMode) {
-	mode := f.Mode()
-	if want == 0 {
-		t.Errorf("%s: %s mode: got %v, want none", zipName, f.Name, mode)
-	} else if mode != want {
-		t.Errorf("%s: %s mode: want %v, got %v", zipName, f.Name, want, mode)
-	}
-}
-
-func TestInvalidFiles(t *testing.T) {
-	const size = 1024 * 70 // 70kb
-	b := make([]byte, size)
-
-	// zeroes
-	_, err := NewReader(bytes.NewReader(b), size)
-	if err != ErrFormat {
-		t.Errorf("zeroes: error=%v, want %v", err, ErrFormat)
-	}
-
-	// repeated directoryEndSignatures
-	sig := make([]byte, 4)
-	binary.LittleEndian.PutUint32(sig, directoryEndSignature)
-	for i := 0; i < size-4; i += 4 {
-		copy(b[i:i+4], sig)
-	}
-	_, err = NewReader(bytes.NewReader(b), size)
-	if err != ErrFormat {
-		t.Errorf("sigs: error=%v, want %v", err, ErrFormat)
-	}
-}
-
-func messWith(fileName string, corrupter func(b []byte)) (r io.ReaderAt, size int64) {
-	data, err := ioutil.ReadFile(filepath.Join("testdata", fileName))
-	if err != nil {
-		panic("Error reading " + fileName + ": " + err.Error())
-	}
-	corrupter(data)
-	return bytes.NewReader(data), int64(len(data))
-}
-
-func returnCorruptCRC32Zip() (r io.ReaderAt, size int64) {
-	return messWith("go-with-datadesc-sig.zip", func(b []byte) {
-		// Corrupt one of the CRC32s in the data descriptor:
-		b[0x2d]++
-	})
-}
-
-func returnCorruptNotStreamedZip() (r io.ReaderAt, size int64) {
-	return messWith("crc32-not-streamed.zip", func(b []byte) {
-		// Corrupt foo.txt's final crc32 byte, in both
-		// the file header and TOC. (0x7e -> 0x7f)
-		b[0x11]++
-		b[0x9d]++
-
-		// TODO(bradfitz): add a new test that only corrupts
-		// one of these values, and verify that that's also an
-		// error. Currently, the reader code doesn't verify the
-		// fileheader and TOC's crc32 match if they're both
-		// non-zero and only the second line above, the TOC,
-		// is what matters.
-	})
-}
-
-// rZipBytes returns the bytes of a recursive zip file, without
-// putting it on disk and triggering certain virus scanners.
-func rZipBytes() []byte {
-	s := `
-0000000 50 4b 03 04 14 00 00 00 08 00 08 03 64 3c f9 f4
-0000010 89 64 48 01 00 00 b8 01 00 00 07 00 00 00 72 2f
-0000020 72 2e 7a 69 70 00 25 00 da ff 50 4b 03 04 14 00
-0000030 00 00 08 00 08 03 64 3c f9 f4 89 64 48 01 00 00
-0000040 b8 01 00 00 07 00 00 00 72 2f 72 2e 7a 69 70 00
-0000050 2f 00 d0 ff 00 25 00 da ff 50 4b 03 04 14 00 00
-0000060 00 08 00 08 03 64 3c f9 f4 89 64 48 01 00 00 b8
-0000070 01 00 00 07 00 00 00 72 2f 72 2e 7a 69 70 00 2f
-0000080 00 d0 ff c2 54 8e 57 39 00 05 00 fa ff c2 54 8e
-0000090 57 39 00 05 00 fa ff 00 05 00 fa ff 00 14 00 eb
-00000a0 ff c2 54 8e 57 39 00 05 00 fa ff 00 05 00 fa ff
-00000b0 00 14 00 eb ff 42 88 21 c4 00 00 14 00 eb ff 42
-00000c0 88 21 c4 00 00 14 00 eb ff 42 88 21 c4 00 00 14
-00000d0 00 eb ff 42 88 21 c4 00 00 14 00 eb ff 42 88 21
-00000e0 c4 00 00 00 00 ff ff 00 00 00 ff ff 00 34 00 cb
-00000f0 ff 42 88 21 c4 00 00 00 00 ff ff 00 00 00 ff ff
-0000100 00 34 00 cb ff 42 e8 21 5e 0f 00 00 00 ff ff 0a
-0000110 f0 66 64 12 61 c0 15 dc e8 a0 48 bf 48 af 2a b3
-0000120 20 c0 9b 95 0d c4 67 04 42 53 06 06 06 40 00 06
-0000130 00 f9 ff 6d 01 00 00 00 00 42 e8 21 5e 0f 00 00
-0000140 00 ff ff 0a f0 66 64 12 61 c0 15 dc e8 a0 48 bf
-0000150 48 af 2a b3 20 c0 9b 95 0d c4 67 04 42 53 06 06
-0000160 06 40 00 06 00 f9 ff 6d 01 00 00 00 00 50 4b 01
-0000170 02 14 00 14 00 00 00 08 00 08 03 64 3c f9 f4 89
-0000180 64 48 01 00 00 b8 01 00 00 07 00 00 00 00 00 00
-0000190 00 00 00 00 00 00 00 00 00 00 00 72 2f 72 2e 7a
-00001a0 69 70 50 4b 05 06 00 00 00 00 01 00 01 00 35 00
-00001b0 00 00 6d 01 00 00 00 00`
-	s = regexp.MustCompile(`[0-9a-f]{7}`).ReplaceAllString(s, "")
-	s = regexp.MustCompile(`\s+`).ReplaceAllString(s, "")
-	b, err := hex.DecodeString(s)
-	if err != nil {
-		panic(err)
-	}
-	return b
-}
-
-func returnRecursiveZip() (r io.ReaderAt, size int64) {
-	b := rZipBytes()
-	return bytes.NewReader(b), int64(len(b))
-}
diff --git a/src/pkg/archive/zip/writer.go b/src/pkg/archive/zip/writer.go
deleted file mode 100644
index 6c9800a..0000000
--- a/src/pkg/archive/zip/writer.go
+++ /dev/null
@@ -1,351 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package zip
-
-import (
-	"bufio"
-	"encoding/binary"
-	"errors"
-	"hash"
-	"hash/crc32"
-	"io"
-)
-
-// TODO(adg): support zip file comments
-// TODO(adg): support specifying deflate level
-
-// Writer implements a zip file writer.
-type Writer struct {
-	cw     *countWriter
-	dir    []*header
-	last   *fileWriter
-	closed bool
-}
-
-type header struct {
-	*FileHeader
-	offset uint64
-}
-
-// NewWriter returns a new Writer writing a zip file to w.
-func NewWriter(w io.Writer) *Writer {
-	return &Writer{cw: &countWriter{w: bufio.NewWriter(w)}}
-}
-
-// Close finishes writing the zip file by writing the central directory.
-// It does not (and can not) close the underlying writer.
-func (w *Writer) Close() error {
-	if w.last != nil && !w.last.closed {
-		if err := w.last.close(); err != nil {
-			return err
-		}
-		w.last = nil
-	}
-	if w.closed {
-		return errors.New("zip: writer closed twice")
-	}
-	w.closed = true
-
-	// write central directory
-	start := w.cw.count
-	for _, h := range w.dir {
-		var buf [directoryHeaderLen]byte
-		b := writeBuf(buf[:])
-		b.uint32(uint32(directoryHeaderSignature))
-		b.uint16(h.CreatorVersion)
-		b.uint16(h.ReaderVersion)
-		b.uint16(h.Flags)
-		b.uint16(h.Method)
-		b.uint16(h.ModifiedTime)
-		b.uint16(h.ModifiedDate)
-		b.uint32(h.CRC32)
-		if h.isZip64() || h.offset > uint32max {
-			// the file needs a zip64 header. store maxint in both
-			// 32 bit size fields (and offset later) to signal that the
-			// zip64 extra header should be used.
-			b.uint32(uint32max) // compressed size
-			b.uint32(uint32max) // uncompressed size
-
-			// append a zip64 extra block to Extra
-			var buf [28]byte // 2x uint16 + 3x uint64
-			eb := writeBuf(buf[:])
-			eb.uint16(zip64ExtraId)
-			eb.uint16(24) // size = 3x uint64
-			eb.uint64(h.UncompressedSize64)
-			eb.uint64(h.CompressedSize64)
-			eb.uint64(h.offset)
-			h.Extra = append(h.Extra, buf[:]...)
-		} else {
-			b.uint32(h.CompressedSize)
-			b.uint32(h.UncompressedSize)
-		}
-		b.uint16(uint16(len(h.Name)))
-		b.uint16(uint16(len(h.Extra)))
-		b.uint16(uint16(len(h.Comment)))
-		b = b[4:] // skip disk number start and internal file attr (2x uint16)
-		b.uint32(h.ExternalAttrs)
-		if h.offset > uint32max {
-			b.uint32(uint32max)
-		} else {
-			b.uint32(uint32(h.offset))
-		}
-		if _, err := w.cw.Write(buf[:]); err != nil {
-			return err
-		}
-		if _, err := io.WriteString(w.cw, h.Name); err != nil {
-			return err
-		}
-		if _, err := w.cw.Write(h.Extra); err != nil {
-			return err
-		}
-		if _, err := io.WriteString(w.cw, h.Comment); err != nil {
-			return err
-		}
-	}
-	end := w.cw.count
-
-	records := uint64(len(w.dir))
-	size := uint64(end - start)
-	offset := uint64(start)
-
-	if records > uint16max || size > uint32max || offset > uint32max {
-		var buf [directory64EndLen + directory64LocLen]byte
-		b := writeBuf(buf[:])
-
-		// zip64 end of central directory record
-		b.uint32(directory64EndSignature)
-		b.uint64(directory64EndLen)
-		b.uint16(zipVersion45) // version made by
-		b.uint16(zipVersion45) // version needed to extract
-		b.uint32(0)            // number of this disk
-		b.uint32(0)            // number of the disk with the start of the central directory
-		b.uint64(records)      // total number of entries in the central directory on this disk
-		b.uint64(records)      // total number of entries in the central directory
-		b.uint64(size)         // size of the central directory
-		b.uint64(offset)       // offset of start of central directory with respect to the starting disk number
-
-		// zip64 end of central directory locator
-		b.uint32(directory64LocSignature)
-		b.uint32(0)           // number of the disk with the start of the zip64 end of central directory
-		b.uint64(uint64(end)) // relative offset of the zip64 end of central directory record
-		b.uint32(1)           // total number of disks
-
-		if _, err := w.cw.Write(buf[:]); err != nil {
-			return err
-		}
-
-		// store max values in the regular end record to signal that
-		// that the zip64 values should be used instead
-		records = uint16max
-		size = uint32max
-		offset = uint32max
-	}
-
-	// write end record
-	var buf [directoryEndLen]byte
-	b := writeBuf(buf[:])
-	b.uint32(uint32(directoryEndSignature))
-	b = b[4:]                 // skip over disk number and first disk number (2x uint16)
-	b.uint16(uint16(records)) // number of entries this disk
-	b.uint16(uint16(records)) // number of entries total
-	b.uint32(uint32(size))    // size of directory
-	b.uint32(uint32(offset))  // start of directory
-	// skipped size of comment (always zero)
-	if _, err := w.cw.Write(buf[:]); err != nil {
-		return err
-	}
-
-	return w.cw.w.(*bufio.Writer).Flush()
-}
-
-// Create adds a file to the zip file using the provided name.
-// It returns a Writer to which the file contents should be written.
-// The name must be a relative path: it must not start with a drive
-// letter (e.g. C:) or leading slash, and only forward slashes are
-// allowed.
-// The file's contents must be written to the io.Writer before the next
-// call to Create, CreateHeader, or Close.
-func (w *Writer) Create(name string) (io.Writer, error) {
-	header := &FileHeader{
-		Name:   name,
-		Method: Deflate,
-	}
-	return w.CreateHeader(header)
-}
-
-// CreateHeader adds a file to the zip file using the provided FileHeader
-// for the file metadata.
-// It returns a Writer to which the file contents should be written.
-// The file's contents must be written to the io.Writer before the next
-// call to Create, CreateHeader, or Close.
-func (w *Writer) CreateHeader(fh *FileHeader) (io.Writer, error) {
-	if w.last != nil && !w.last.closed {
-		if err := w.last.close(); err != nil {
-			return nil, err
-		}
-	}
-
-	fh.Flags |= 0x8 // we will write a data descriptor
-
-	fh.CreatorVersion = fh.CreatorVersion&0xff00 | zipVersion20 // preserve compatibility byte
-	fh.ReaderVersion = zipVersion20
-
-	fw := &fileWriter{
-		zipw:      w.cw,
-		compCount: &countWriter{w: w.cw},
-		crc32:     crc32.NewIEEE(),
-	}
-	comp := compressor(fh.Method)
-	if comp == nil {
-		return nil, ErrAlgorithm
-	}
-	var err error
-	fw.comp, err = comp(fw.compCount)
-	if err != nil {
-		return nil, err
-	}
-	fw.rawCount = &countWriter{w: fw.comp}
-
-	h := &header{
-		FileHeader: fh,
-		offset:     uint64(w.cw.count),
-	}
-	w.dir = append(w.dir, h)
-	fw.header = h
-
-	if err := writeHeader(w.cw, fh); err != nil {
-		return nil, err
-	}
-
-	w.last = fw
-	return fw, nil
-}
-
-func writeHeader(w io.Writer, h *FileHeader) error {
-	var buf [fileHeaderLen]byte
-	b := writeBuf(buf[:])
-	b.uint32(uint32(fileHeaderSignature))
-	b.uint16(h.ReaderVersion)
-	b.uint16(h.Flags)
-	b.uint16(h.Method)
-	b.uint16(h.ModifiedTime)
-	b.uint16(h.ModifiedDate)
-	b.uint32(0) // since we are writing a data descriptor crc32,
-	b.uint32(0) // compressed size,
-	b.uint32(0) // and uncompressed size should be zero
-	b.uint16(uint16(len(h.Name)))
-	b.uint16(uint16(len(h.Extra)))
-	if _, err := w.Write(buf[:]); err != nil {
-		return err
-	}
-	if _, err := io.WriteString(w, h.Name); err != nil {
-		return err
-	}
-	_, err := w.Write(h.Extra)
-	return err
-}
-
-type fileWriter struct {
-	*header
-	zipw      io.Writer
-	rawCount  *countWriter
-	comp      io.WriteCloser
-	compCount *countWriter
-	crc32     hash.Hash32
-	closed    bool
-}
-
-func (w *fileWriter) Write(p []byte) (int, error) {
-	if w.closed {
-		return 0, errors.New("zip: write to closed file")
-	}
-	w.crc32.Write(p)
-	return w.rawCount.Write(p)
-}
-
-func (w *fileWriter) close() error {
-	if w.closed {
-		return errors.New("zip: file closed twice")
-	}
-	w.closed = true
-	if err := w.comp.Close(); err != nil {
-		return err
-	}
-
-	// update FileHeader
-	fh := w.header.FileHeader
-	fh.CRC32 = w.crc32.Sum32()
-	fh.CompressedSize64 = uint64(w.compCount.count)
-	fh.UncompressedSize64 = uint64(w.rawCount.count)
-
-	if fh.isZip64() {
-		fh.CompressedSize = uint32max
-		fh.UncompressedSize = uint32max
-		fh.ReaderVersion = zipVersion45 // requires 4.5 - File uses ZIP64 format extensions
-	} else {
-		fh.CompressedSize = uint32(fh.CompressedSize64)
-		fh.UncompressedSize = uint32(fh.UncompressedSize64)
-	}
-
-	// Write data descriptor. This is more complicated than one would
-	// think, see e.g. comments in zipfile.c:putextended() and
-	// http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7073588.
-	// The approach here is to write 8 byte sizes if needed without
-	// adding a zip64 extra in the local header (too late anyway).
-	var buf []byte
-	if fh.isZip64() {
-		buf = make([]byte, dataDescriptor64Len)
-	} else {
-		buf = make([]byte, dataDescriptorLen)
-	}
-	b := writeBuf(buf)
-	b.uint32(dataDescriptorSignature) // de-facto standard, required by OS X
-	b.uint32(fh.CRC32)
-	if fh.isZip64() {
-		b.uint64(fh.CompressedSize64)
-		b.uint64(fh.UncompressedSize64)
-	} else {
-		b.uint32(fh.CompressedSize)
-		b.uint32(fh.UncompressedSize)
-	}
-	_, err := w.zipw.Write(buf)
-	return err
-}
-
-type countWriter struct {
-	w     io.Writer
-	count int64
-}
-
-func (w *countWriter) Write(p []byte) (int, error) {
-	n, err := w.w.Write(p)
-	w.count += int64(n)
-	return n, err
-}
-
-type nopCloser struct {
-	io.Writer
-}
-
-func (w nopCloser) Close() error {
-	return nil
-}
-
-type writeBuf []byte
-
-func (b *writeBuf) uint16(v uint16) {
-	binary.LittleEndian.PutUint16(*b, v)
-	*b = (*b)[2:]
-}
-
-func (b *writeBuf) uint32(v uint32) {
-	binary.LittleEndian.PutUint32(*b, v)
-	*b = (*b)[4:]
-}
-
-func (b *writeBuf) uint64(v uint64) {
-	binary.LittleEndian.PutUint64(*b, v)
-	*b = (*b)[8:]
-}
diff --git a/src/pkg/archive/zip/writer_test.go b/src/pkg/archive/zip/writer_test.go
deleted file mode 100644
index 4bfa870..0000000
--- a/src/pkg/archive/zip/writer_test.go
+++ /dev/null
@@ -1,145 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package zip
-
-import (
-	"bytes"
-	"io/ioutil"
-	"math/rand"
-	"os"
-	"testing"
-)
-
-// TODO(adg): a more sophisticated test suite
-
-type WriteTest struct {
-	Name   string
-	Data   []byte
-	Method uint16
-	Mode   os.FileMode
-}
-
-var writeTests = []WriteTest{
-	{
-		Name:   "foo",
-		Data:   []byte("Rabbits, guinea pigs, gophers, marsupial rats, and quolls."),
-		Method: Store,
-		Mode:   0666,
-	},
-	{
-		Name:   "bar",
-		Data:   nil, // large data set in the test
-		Method: Deflate,
-		Mode:   0644,
-	},
-	{
-		Name:   "setuid",
-		Data:   []byte("setuid file"),
-		Method: Deflate,
-		Mode:   0755 | os.ModeSetuid,
-	},
-	{
-		Name:   "setgid",
-		Data:   []byte("setgid file"),
-		Method: Deflate,
-		Mode:   0755 | os.ModeSetgid,
-	},
-	{
-		Name:   "symlink",
-		Data:   []byte("../link/target"),
-		Method: Deflate,
-		Mode:   0755 | os.ModeSymlink,
-	},
-}
-
-func TestWriter(t *testing.T) {
-	largeData := make([]byte, 1<<17)
-	for i := range largeData {
-		largeData[i] = byte(rand.Int())
-	}
-	writeTests[1].Data = largeData
-	defer func() {
-		writeTests[1].Data = nil
-	}()
-
-	// write a zip file
-	buf := new(bytes.Buffer)
-	w := NewWriter(buf)
-
-	for _, wt := range writeTests {
-		testCreate(t, w, &wt)
-	}
-
-	if err := w.Close(); err != nil {
-		t.Fatal(err)
-	}
-
-	// read it back
-	r, err := NewReader(bytes.NewReader(buf.Bytes()), int64(buf.Len()))
-	if err != nil {
-		t.Fatal(err)
-	}
-	for i, wt := range writeTests {
-		testReadFile(t, r.File[i], &wt)
-	}
-}
-
-func testCreate(t *testing.T, w *Writer, wt *WriteTest) {
-	header := &FileHeader{
-		Name:   wt.Name,
-		Method: wt.Method,
-	}
-	if wt.Mode != 0 {
-		header.SetMode(wt.Mode)
-	}
-	f, err := w.CreateHeader(header)
-	if err != nil {
-		t.Fatal(err)
-	}
-	_, err = f.Write(wt.Data)
-	if err != nil {
-		t.Fatal(err)
-	}
-}
-
-func testReadFile(t *testing.T, f *File, wt *WriteTest) {
-	if f.Name != wt.Name {
-		t.Fatalf("File name: got %q, want %q", f.Name, wt.Name)
-	}
-	testFileMode(t, wt.Name, f, wt.Mode)
-	rc, err := f.Open()
-	if err != nil {
-		t.Fatal("opening:", err)
-	}
-	b, err := ioutil.ReadAll(rc)
-	if err != nil {
-		t.Fatal("reading:", err)
-	}
-	err = rc.Close()
-	if err != nil {
-		t.Fatal("closing:", err)
-	}
-	if !bytes.Equal(b, wt.Data) {
-		t.Errorf("File contents %q, want %q", b, wt.Data)
-	}
-}
-
-func BenchmarkCompressedZipGarbage(b *testing.B) {
-	b.ReportAllocs()
-	var buf bytes.Buffer
-	bigBuf := bytes.Repeat([]byte("a"), 1<<20)
-	for i := 0; i < b.N; i++ {
-		buf.Reset()
-		zw := NewWriter(&buf)
-		for j := 0; j < 3; j++ {
-			w, _ := zw.CreateHeader(&FileHeader{
-				Name:   "foo",
-				Method: Deflate,
-			})
-			w.Write(bigBuf)
-		}
-		zw.Close()
-	}
-}
diff --git a/src/pkg/bufio/bufio.go b/src/pkg/bufio/bufio.go
deleted file mode 100644
index 61ef261..0000000
--- a/src/pkg/bufio/bufio.go
+++ /dev/null
@@ -1,698 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package bufio implements buffered I/O.  It wraps an io.Reader or io.Writer
-// object, creating another object (Reader or Writer) that also implements
-// the interface but provides buffering and some help for textual I/O.
-package bufio
-
-import (
-	"bytes"
-	"errors"
-	"io"
-	"unicode/utf8"
-)
-
-const (
-	defaultBufSize = 4096
-)
-
-var (
-	ErrInvalidUnreadByte = errors.New("bufio: invalid use of UnreadByte")
-	ErrInvalidUnreadRune = errors.New("bufio: invalid use of UnreadRune")
-	ErrBufferFull        = errors.New("bufio: buffer full")
-	ErrNegativeCount     = errors.New("bufio: negative count")
-)
-
-// Buffered input.
-
-// Reader implements buffering for an io.Reader object.
-type Reader struct {
-	buf          []byte
-	rd           io.Reader
-	r, w         int
-	err          error
-	lastByte     int
-	lastRuneSize int
-}
-
-const minReadBufferSize = 16
-const maxConsecutiveEmptyReads = 100
-
-// NewReaderSize returns a new Reader whose buffer has at least the specified
-// size. If the argument io.Reader is already a Reader with large enough
-// size, it returns the underlying Reader.
-func NewReaderSize(rd io.Reader, size int) *Reader {
-	// Is it already a Reader?
-	b, ok := rd.(*Reader)
-	if ok && len(b.buf) >= size {
-		return b
-	}
-	if size < minReadBufferSize {
-		size = minReadBufferSize
-	}
-	r := new(Reader)
-	r.reset(make([]byte, size), rd)
-	return r
-}
-
-// NewReader returns a new Reader whose buffer has the default size.
-func NewReader(rd io.Reader) *Reader {
-	return NewReaderSize(rd, defaultBufSize)
-}
-
-// Reset discards any buffered data, resets all state, and switches
-// the buffered reader to read from r.
-func (b *Reader) Reset(r io.Reader) {
-	b.reset(b.buf, r)
-}
-
-func (b *Reader) reset(buf []byte, r io.Reader) {
-	*b = Reader{
-		buf:          buf,
-		rd:           r,
-		lastByte:     -1,
-		lastRuneSize: -1,
-	}
-}
-
-var errNegativeRead = errors.New("bufio: reader returned negative count from Read")
-
-// fill reads a new chunk into the buffer.
-func (b *Reader) fill() {
-	// Slide existing data to beginning.
-	if b.r > 0 {
-		copy(b.buf, b.buf[b.r:b.w])
-		b.w -= b.r
-		b.r = 0
-	}
-
-	if b.w >= len(b.buf) {
-		panic("bufio: tried to fill full buffer")
-	}
-
-	// Read new data: try a limited number of times.
-	for i := maxConsecutiveEmptyReads; i > 0; i-- {
-		n, err := b.rd.Read(b.buf[b.w:])
-		if n < 0 {
-			panic(errNegativeRead)
-		}
-		b.w += n
-		if err != nil {
-			b.err = err
-			return
-		}
-		if n > 0 {
-			return
-		}
-	}
-	b.err = io.ErrNoProgress
-}
-
-func (b *Reader) readErr() error {
-	err := b.err
-	b.err = nil
-	return err
-}
-
-// Peek returns the next n bytes without advancing the reader. The bytes stop
-// being valid at the next read call. If Peek returns fewer than n bytes, it
-// also returns an error explaining why the read is short. The error is
-// ErrBufferFull if n is larger than b's buffer size.
-func (b *Reader) Peek(n int) ([]byte, error) {
-	if n < 0 {
-		return nil, ErrNegativeCount
-	}
-	if n > len(b.buf) {
-		return nil, ErrBufferFull
-	}
-	// 0 <= n <= len(b.buf)
-	for b.w-b.r < n && b.err == nil {
-		b.fill() // b.w-b.r < len(b.buf) => buffer is not full
-	}
-	m := b.w - b.r
-	if m > n {
-		m = n
-	}
-	var err error
-	if m < n {
-		err = b.readErr()
-		if err == nil {
-			err = ErrBufferFull
-		}
-	}
-	return b.buf[b.r : b.r+m], err
-}
-
-// Read reads data into p.
-// It returns the number of bytes read into p.
-// It calls Read at most once on the underlying Reader,
-// hence n may be less than len(p).
-// At EOF, the count will be zero and err will be io.EOF.
-func (b *Reader) Read(p []byte) (n int, err error) {
-	n = len(p)
-	if n == 0 {
-		return 0, b.readErr()
-	}
-	if b.r == b.w {
-		if b.err != nil {
-			return 0, b.readErr()
-		}
-		if len(p) >= len(b.buf) {
-			// Large read, empty buffer.
-			// Read directly into p to avoid copy.
-			n, b.err = b.rd.Read(p)
-			if n < 0 {
-				panic(errNegativeRead)
-			}
-			if n > 0 {
-				b.lastByte = int(p[n-1])
-				b.lastRuneSize = -1
-			}
-			return n, b.readErr()
-		}
-		b.fill() // buffer is empty
-		if b.w == b.r {
-			return 0, b.readErr()
-		}
-	}
-
-	if n > b.w-b.r {
-		n = b.w - b.r
-	}
-	copy(p[0:n], b.buf[b.r:])
-	b.r += n
-	b.lastByte = int(b.buf[b.r-1])
-	b.lastRuneSize = -1
-	return n, nil
-}
-
-// ReadByte reads and returns a single byte.
-// If no byte is available, returns an error.
-func (b *Reader) ReadByte() (c byte, err error) {
-	b.lastRuneSize = -1
-	for b.r == b.w {
-		if b.err != nil {
-			return 0, b.readErr()
-		}
-		b.fill() // buffer is empty
-	}
-	c = b.buf[b.r]
-	b.r++
-	b.lastByte = int(c)
-	return c, nil
-}
-
-// UnreadByte unreads the last byte.  Only the most recently read byte can be unread.
-func (b *Reader) UnreadByte() error {
-	if b.lastByte < 0 || b.r == 0 && b.w > 0 {
-		return ErrInvalidUnreadByte
-	}
-	// b.r > 0 || b.w == 0
-	if b.r > 0 {
-		b.r--
-	} else {
-		// b.r == 0 && b.w == 0
-		b.w = 1
-	}
-	b.buf[b.r] = byte(b.lastByte)
-	b.lastByte = -1
-	b.lastRuneSize = -1
-	return nil
-}
-
-// ReadRune reads a single UTF-8 encoded Unicode character and returns the
-// rune and its size in bytes. If the encoded rune is invalid, it consumes one byte
-// and returns unicode.ReplacementChar (U+FFFD) with a size of 1.
-func (b *Reader) ReadRune() (r rune, size int, err error) {
-	for b.r+utf8.UTFMax > b.w && !utf8.FullRune(b.buf[b.r:b.w]) && b.err == nil && b.w-b.r < len(b.buf) {
-		b.fill() // b.w-b.r < len(buf) => buffer is not full
-	}
-	b.lastRuneSize = -1
-	if b.r == b.w {
-		return 0, 0, b.readErr()
-	}
-	r, size = rune(b.buf[b.r]), 1
-	if r >= 0x80 {
-		r, size = utf8.DecodeRune(b.buf[b.r:b.w])
-	}
-	b.r += size
-	b.lastByte = int(b.buf[b.r-1])
-	b.lastRuneSize = size
-	return r, size, nil
-}
-
-// UnreadRune unreads the last rune.  If the most recent read operation on
-// the buffer was not a ReadRune, UnreadRune returns an error.  (In this
-// regard it is stricter than UnreadByte, which will unread the last byte
-// from any read operation.)
-func (b *Reader) UnreadRune() error {
-	if b.lastRuneSize < 0 || b.r < b.lastRuneSize {
-		return ErrInvalidUnreadRune
-	}
-	b.r -= b.lastRuneSize
-	b.lastByte = -1
-	b.lastRuneSize = -1
-	return nil
-}
-
-// Buffered returns the number of bytes that can be read from the current buffer.
-func (b *Reader) Buffered() int { return b.w - b.r }
-
-// ReadSlice reads until the first occurrence of delim in the input,
-// returning a slice pointing at the bytes in the buffer.
-// The bytes stop being valid at the next read.
-// If ReadSlice encounters an error before finding a delimiter,
-// it returns all the data in the buffer and the error itself (often io.EOF).
-// ReadSlice fails with error ErrBufferFull if the buffer fills without a delim.
-// Because the data returned from ReadSlice will be overwritten
-// by the next I/O operation, most clients should use
-// ReadBytes or ReadString instead.
-// ReadSlice returns err != nil if and only if line does not end in delim.
-func (b *Reader) ReadSlice(delim byte) (line []byte, err error) {
-	for {
-		// Search buffer.
-		if i := bytes.IndexByte(b.buf[b.r:b.w], delim); i >= 0 {
-			line = b.buf[b.r : b.r+i+1]
-			b.r += i + 1
-			break
-		}
-
-		// Pending error?
-		if b.err != nil {
-			line = b.buf[b.r:b.w]
-			b.r = b.w
-			err = b.readErr()
-			break
-		}
-
-		// Buffer full?
-		if n := b.Buffered(); n >= len(b.buf) {
-			b.r = b.w
-			line = b.buf
-			err = ErrBufferFull
-			break
-		}
-
-		b.fill() // buffer is not full
-	}
-
-	// Handle last byte, if any.
-	if i := len(line) - 1; i >= 0 {
-		b.lastByte = int(line[i])
-	}
-
-	return
-}
-
-// ReadLine is a low-level line-reading primitive. Most callers should use
-// ReadBytes('\n') or ReadString('\n') instead or use a Scanner.
-//
-// ReadLine tries to return a single line, not including the end-of-line bytes.
-// If the line was too long for the buffer then isPrefix is set and the
-// beginning of the line is returned. The rest of the line will be returned
-// from future calls. isPrefix will be false when returning the last fragment
-// of the line. The returned buffer is only valid until the next call to
-// ReadLine. ReadLine either returns a non-nil line or it returns an error,
-// never both.
-//
-// The text returned from ReadLine does not include the line end ("\r\n" or "\n").
-// No indication or error is given if the input ends without a final line end.
-// Calling UnreadByte after ReadLine will always unread the last byte read
-// (possibly a character belonging to the line end) even if that byte is not
-// part of the line returned by ReadLine.
-func (b *Reader) ReadLine() (line []byte, isPrefix bool, err error) {
-	line, err = b.ReadSlice('\n')
-	if err == ErrBufferFull {
-		// Handle the case where "\r\n" straddles the buffer.
-		if len(line) > 0 && line[len(line)-1] == '\r' {
-			// Put the '\r' back on buf and drop it from line.
-			// Let the next call to ReadLine check for "\r\n".
-			if b.r == 0 {
-				// should be unreachable
-				panic("bufio: tried to rewind past start of buffer")
-			}
-			b.r--
-			line = line[:len(line)-1]
-		}
-		return line, true, nil
-	}
-
-	if len(line) == 0 {
-		if err != nil {
-			line = nil
-		}
-		return
-	}
-	err = nil
-
-	if line[len(line)-1] == '\n' {
-		drop := 1
-		if len(line) > 1 && line[len(line)-2] == '\r' {
-			drop = 2
-		}
-		line = line[:len(line)-drop]
-	}
-	return
-}
-
-// ReadBytes reads until the first occurrence of delim in the input,
-// returning a slice containing the data up to and including the delimiter.
-// If ReadBytes encounters an error before finding a delimiter,
-// it returns the data read before the error and the error itself (often io.EOF).
-// ReadBytes returns err != nil if and only if the returned data does not end in
-// delim.
-// For simple uses, a Scanner may be more convenient.
-func (b *Reader) ReadBytes(delim byte) (line []byte, err error) {
-	// Use ReadSlice to look for array,
-	// accumulating full buffers.
-	var frag []byte
-	var full [][]byte
-	err = nil
-
-	for {
-		var e error
-		frag, e = b.ReadSlice(delim)
-		if e == nil { // got final fragment
-			break
-		}
-		if e != ErrBufferFull { // unexpected error
-			err = e
-			break
-		}
-
-		// Make a copy of the buffer.
-		buf := make([]byte, len(frag))
-		copy(buf, frag)
-		full = append(full, buf)
-	}
-
-	// Allocate new buffer to hold the full pieces and the fragment.
-	n := 0
-	for i := range full {
-		n += len(full[i])
-	}
-	n += len(frag)
-
-	// Copy full pieces and fragment in.
-	buf := make([]byte, n)
-	n = 0
-	for i := range full {
-		n += copy(buf[n:], full[i])
-	}
-	copy(buf[n:], frag)
-	return buf, err
-}
-
-// ReadString reads until the first occurrence of delim in the input,
-// returning a string containing the data up to and including the delimiter.
-// If ReadString encounters an error before finding a delimiter,
-// it returns the data read before the error and the error itself (often io.EOF).
-// ReadString returns err != nil if and only if the returned data does not end in
-// delim.
-// For simple uses, a Scanner may be more convenient.
-func (b *Reader) ReadString(delim byte) (line string, err error) {
-	bytes, err := b.ReadBytes(delim)
-	line = string(bytes)
-	return line, err
-}
-
-// WriteTo implements io.WriterTo.
-func (b *Reader) WriteTo(w io.Writer) (n int64, err error) {
-	n, err = b.writeBuf(w)
-	if err != nil {
-		return
-	}
-
-	if r, ok := b.rd.(io.WriterTo); ok {
-		m, err := r.WriteTo(w)
-		n += m
-		return n, err
-	}
-
-	if w, ok := w.(io.ReaderFrom); ok {
-		m, err := w.ReadFrom(b.rd)
-		n += m
-		return n, err
-	}
-
-	if b.w-b.r < len(b.buf) {
-		b.fill() // buffer not full
-	}
-
-	for b.r < b.w {
-		// b.r < b.w => buffer is not empty
-		m, err := b.writeBuf(w)
-		n += m
-		if err != nil {
-			return n, err
-		}
-		b.fill() // buffer is empty
-	}
-
-	if b.err == io.EOF {
-		b.err = nil
-	}
-
-	return n, b.readErr()
-}
-
-// writeBuf writes the Reader's buffer to the writer.
-func (b *Reader) writeBuf(w io.Writer) (int64, error) {
-	n, err := w.Write(b.buf[b.r:b.w])
-	if n < b.r-b.w {
-		panic(errors.New("bufio: writer did not write all data"))
-	}
-	b.r += n
-	return int64(n), err
-}
-
-// buffered output
-
-// Writer implements buffering for an io.Writer object.
-// If an error occurs writing to a Writer, no more data will be
-// accepted and all subsequent writes will return the error.
-// After all data has been written, the client should call the
-// Flush method to guarantee all data has been forwarded to
-// the underlying io.Writer.
-type Writer struct {
-	err error
-	buf []byte
-	n   int
-	wr  io.Writer
-}
-
-// NewWriterSize returns a new Writer whose buffer has at least the specified
-// size. If the argument io.Writer is already a Writer with large enough
-// size, it returns the underlying Writer.
-func NewWriterSize(w io.Writer, size int) *Writer {
-	// Is it already a Writer?
-	b, ok := w.(*Writer)
-	if ok && len(b.buf) >= size {
-		return b
-	}
-	if size <= 0 {
-		size = defaultBufSize
-	}
-	return &Writer{
-		buf: make([]byte, size),
-		wr:  w,
-	}
-}
-
-// NewWriter returns a new Writer whose buffer has the default size.
-func NewWriter(w io.Writer) *Writer {
-	return NewWriterSize(w, defaultBufSize)
-}
-
-// Reset discards any unflushed buffered data, clears any error, and
-// resets b to write its output to w.
-func (b *Writer) Reset(w io.Writer) {
-	b.err = nil
-	b.n = 0
-	b.wr = w
-}
-
-// Flush writes any buffered data to the underlying io.Writer.
-func (b *Writer) Flush() error {
-	err := b.flush()
-	return err
-}
-
-func (b *Writer) flush() error {
-	if b.err != nil {
-		return b.err
-	}
-	if b.n == 0 {
-		return nil
-	}
-	n, err := b.wr.Write(b.buf[0:b.n])
-	if n < b.n && err == nil {
-		err = io.ErrShortWrite
-	}
-	if err != nil {
-		if n > 0 && n < b.n {
-			copy(b.buf[0:b.n-n], b.buf[n:b.n])
-		}
-		b.n -= n
-		b.err = err
-		return err
-	}
-	b.n = 0
-	return nil
-}
-
-// Available returns how many bytes are unused in the buffer.
-func (b *Writer) Available() int { return len(b.buf) - b.n }
-
-// Buffered returns the number of bytes that have been written into the current buffer.
-func (b *Writer) Buffered() int { return b.n }
-
-// Write writes the contents of p into the buffer.
-// It returns the number of bytes written.
-// If nn < len(p), it also returns an error explaining
-// why the write is short.
-func (b *Writer) Write(p []byte) (nn int, err error) {
-	for len(p) > b.Available() && b.err == nil {
-		var n int
-		if b.Buffered() == 0 {
-			// Large write, empty buffer.
-			// Write directly from p to avoid copy.
-			n, b.err = b.wr.Write(p)
-		} else {
-			n = copy(b.buf[b.n:], p)
-			b.n += n
-			b.flush()
-		}
-		nn += n
-		p = p[n:]
-	}
-	if b.err != nil {
-		return nn, b.err
-	}
-	n := copy(b.buf[b.n:], p)
-	b.n += n
-	nn += n
-	return nn, nil
-}
-
-// WriteByte writes a single byte.
-func (b *Writer) WriteByte(c byte) error {
-	if b.err != nil {
-		return b.err
-	}
-	if b.Available() <= 0 && b.flush() != nil {
-		return b.err
-	}
-	b.buf[b.n] = c
-	b.n++
-	return nil
-}
-
-// WriteRune writes a single Unicode code point, returning
-// the number of bytes written and any error.
-func (b *Writer) WriteRune(r rune) (size int, err error) {
-	if r < utf8.RuneSelf {
-		err = b.WriteByte(byte(r))
-		if err != nil {
-			return 0, err
-		}
-		return 1, nil
-	}
-	if b.err != nil {
-		return 0, b.err
-	}
-	n := b.Available()
-	if n < utf8.UTFMax {
-		if b.flush(); b.err != nil {
-			return 0, b.err
-		}
-		n = b.Available()
-		if n < utf8.UTFMax {
-			// Can only happen if buffer is silly small.
-			return b.WriteString(string(r))
-		}
-	}
-	size = utf8.EncodeRune(b.buf[b.n:], r)
-	b.n += size
-	return size, nil
-}
-
-// WriteString writes a string.
-// It returns the number of bytes written.
-// If the count is less than len(s), it also returns an error explaining
-// why the write is short.
-func (b *Writer) WriteString(s string) (int, error) {
-	nn := 0
-	for len(s) > b.Available() && b.err == nil {
-		n := copy(b.buf[b.n:], s)
-		b.n += n
-		nn += n
-		s = s[n:]
-		b.flush()
-	}
-	if b.err != nil {
-		return nn, b.err
-	}
-	n := copy(b.buf[b.n:], s)
-	b.n += n
-	nn += n
-	return nn, nil
-}
-
-// ReadFrom implements io.ReaderFrom.
-func (b *Writer) ReadFrom(r io.Reader) (n int64, err error) {
-	if b.Buffered() == 0 {
-		if w, ok := b.wr.(io.ReaderFrom); ok {
-			return w.ReadFrom(r)
-		}
-	}
-	var m int
-	for {
-		if b.Available() == 0 {
-			if err1 := b.flush(); err1 != nil {
-				return n, err1
-			}
-		}
-		nr := 0
-		for nr < maxConsecutiveEmptyReads {
-			m, err = r.Read(b.buf[b.n:])
-			if m != 0 || err != nil {
-				break
-			}
-			nr++
-		}
-		if nr == maxConsecutiveEmptyReads {
-			return n, io.ErrNoProgress
-		}
-		b.n += m
-		n += int64(m)
-		if err != nil {
-			break
-		}
-	}
-	if err == io.EOF {
-		// If we filled the buffer exactly, flush pre-emptively.
-		if b.Available() == 0 {
-			err = b.flush()
-		} else {
-			err = nil
-		}
-	}
-	return n, err
-}
-
-// buffered input and output
-
-// ReadWriter stores pointers to a Reader and a Writer.
-// It implements io.ReadWriter.
-type ReadWriter struct {
-	*Reader
-	*Writer
-}
-
-// NewReadWriter allocates a new ReadWriter that dispatches to r and w.
-func NewReadWriter(r *Reader, w *Writer) *ReadWriter {
-	return &ReadWriter{r, w}
-}
diff --git a/src/pkg/bufio/bufio_test.go b/src/pkg/bufio/bufio_test.go
deleted file mode 100644
index 76d3c8e..0000000
--- a/src/pkg/bufio/bufio_test.go
+++ /dev/null
@@ -1,1417 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package bufio_test
-
-import (
-	. "bufio"
-	"bytes"
-	"errors"
-	"fmt"
-	"io"
-	"io/ioutil"
-	"strings"
-	"testing"
-	"testing/iotest"
-	"time"
-	"unicode/utf8"
-)
-
-// Reads from a reader and rot13s the result.
-type rot13Reader struct {
-	r io.Reader
-}
-
-func newRot13Reader(r io.Reader) *rot13Reader {
-	r13 := new(rot13Reader)
-	r13.r = r
-	return r13
-}
-
-func (r13 *rot13Reader) Read(p []byte) (int, error) {
-	n, err := r13.r.Read(p)
-	if err != nil {
-		return n, err
-	}
-	for i := 0; i < n; i++ {
-		c := p[i] | 0x20 // lowercase byte
-		if 'a' <= c && c <= 'm' {
-			p[i] += 13
-		} else if 'n' <= c && c <= 'z' {
-			p[i] -= 13
-		}
-	}
-	return n, nil
-}
-
-// Call ReadByte to accumulate the text of a file
-func readBytes(buf *Reader) string {
-	var b [1000]byte
-	nb := 0
-	for {
-		c, err := buf.ReadByte()
-		if err == io.EOF {
-			break
-		}
-		if err == nil {
-			b[nb] = c
-			nb++
-		} else if err != iotest.ErrTimeout {
-			panic("Data: " + err.Error())
-		}
-	}
-	return string(b[0:nb])
-}
-
-func TestReaderSimple(t *testing.T) {
-	data := "hello world"
-	b := NewReader(strings.NewReader(data))
-	if s := readBytes(b); s != "hello world" {
-		t.Errorf("simple hello world test failed: got %q", s)
-	}
-
-	b = NewReader(newRot13Reader(strings.NewReader(data)))
-	if s := readBytes(b); s != "uryyb jbeyq" {
-		t.Errorf("rot13 hello world test failed: got %q", s)
-	}
-}
-
-type readMaker struct {
-	name string
-	fn   func(io.Reader) io.Reader
-}
-
-var readMakers = []readMaker{
-	{"full", func(r io.Reader) io.Reader { return r }},
-	{"byte", iotest.OneByteReader},
-	{"half", iotest.HalfReader},
-	{"data+err", iotest.DataErrReader},
-	{"timeout", iotest.TimeoutReader},
-}
-
-// Call ReadString (which ends up calling everything else)
-// to accumulate the text of a file.
-func readLines(b *Reader) string {
-	s := ""
-	for {
-		s1, err := b.ReadString('\n')
-		if err == io.EOF {
-			break
-		}
-		if err != nil && err != iotest.ErrTimeout {
-			panic("GetLines: " + err.Error())
-		}
-		s += s1
-	}
-	return s
-}
-
-// Call Read to accumulate the text of a file
-func reads(buf *Reader, m int) string {
-	var b [1000]byte
-	nb := 0
-	for {
-		n, err := buf.Read(b[nb : nb+m])
-		nb += n
-		if err == io.EOF {
-			break
-		}
-	}
-	return string(b[0:nb])
-}
-
-type bufReader struct {
-	name string
-	fn   func(*Reader) string
-}
-
-var bufreaders = []bufReader{
-	{"1", func(b *Reader) string { return reads(b, 1) }},
-	{"2", func(b *Reader) string { return reads(b, 2) }},
-	{"3", func(b *Reader) string { return reads(b, 3) }},
-	{"4", func(b *Reader) string { return reads(b, 4) }},
-	{"5", func(b *Reader) string { return reads(b, 5) }},
-	{"7", func(b *Reader) string { return reads(b, 7) }},
-	{"bytes", readBytes},
-	{"lines", readLines},
-}
-
-const minReadBufferSize = 16
-
-var bufsizes = []int{
-	0, minReadBufferSize, 23, 32, 46, 64, 93, 128, 1024, 4096,
-}
-
-func TestReader(t *testing.T) {
-	var texts [31]string
-	str := ""
-	all := ""
-	for i := 0; i < len(texts)-1; i++ {
-		texts[i] = str + "\n"
-		all += texts[i]
-		str += string(i%26 + 'a')
-	}
-	texts[len(texts)-1] = all
-
-	for h := 0; h < len(texts); h++ {
-		text := texts[h]
-		for i := 0; i < len(readMakers); i++ {
-			for j := 0; j < len(bufreaders); j++ {
-				for k := 0; k < len(bufsizes); k++ {
-					readmaker := readMakers[i]
-					bufreader := bufreaders[j]
-					bufsize := bufsizes[k]
-					read := readmaker.fn(strings.NewReader(text))
-					buf := NewReaderSize(read, bufsize)
-					s := bufreader.fn(buf)
-					if s != text {
-						t.Errorf("reader=%s fn=%s bufsize=%d want=%q got=%q",
-							readmaker.name, bufreader.name, bufsize, text, s)
-					}
-				}
-			}
-		}
-	}
-}
-
-type zeroReader struct{}
-
-func (zeroReader) Read(p []byte) (int, error) {
-	return 0, nil
-}
-
-func TestZeroReader(t *testing.T) {
-	var z zeroReader
-	r := NewReader(z)
-
-	c := make(chan error)
-	go func() {
-		_, err := r.ReadByte()
-		c <- err
-	}()
-
-	select {
-	case err := <-c:
-		if err == nil {
-			t.Error("error expected")
-		} else if err != io.ErrNoProgress {
-			t.Error("unexpected error:", err)
-		}
-	case <-time.After(time.Second):
-		t.Error("test timed out (endless loop in ReadByte?)")
-	}
-}
-
-// A StringReader delivers its data one string segment at a time via Read.
-type StringReader struct {
-	data []string
-	step int
-}
-
-func (r *StringReader) Read(p []byte) (n int, err error) {
-	if r.step < len(r.data) {
-		s := r.data[r.step]
-		n = copy(p, s)
-		r.step++
-	} else {
-		err = io.EOF
-	}
-	return
-}
-
-func readRuneSegments(t *testing.T, segments []string) {
-	got := ""
-	want := strings.Join(segments, "")
-	r := NewReader(&StringReader{data: segments})
-	for {
-		r, _, err := r.ReadRune()
-		if err != nil {
-			if err != io.EOF {
-				return
-			}
-			break
-		}
-		got += string(r)
-	}
-	if got != want {
-		t.Errorf("segments=%v got=%s want=%s", segments, got, want)
-	}
-}
-
-var segmentList = [][]string{
-	{},
-	{""},
-	{"日", "本語"},
-	{"\u65e5", "\u672c", "\u8a9e"},
-	{"\U000065e5", "\U0000672c", "\U00008a9e"},
-	{"\xe6", "\x97\xa5\xe6", "\x9c\xac\xe8\xaa\x9e"},
-	{"Hello", ", ", "World", "!"},
-	{"Hello", ", ", "", "World", "!"},
-}
-
-func TestReadRune(t *testing.T) {
-	for _, s := range segmentList {
-		readRuneSegments(t, s)
-	}
-}
-
-func TestUnreadRune(t *testing.T) {
-	segments := []string{"Hello, world:", "日本語"}
-	r := NewReader(&StringReader{data: segments})
-	got := ""
-	want := strings.Join(segments, "")
-	// Normal execution.
-	for {
-		r1, _, err := r.ReadRune()
-		if err != nil {
-			if err != io.EOF {
-				t.Error("unexpected error on ReadRune:", err)
-			}
-			break
-		}
-		got += string(r1)
-		// Put it back and read it again.
-		if err = r.UnreadRune(); err != nil {
-			t.Fatal("unexpected error on UnreadRune:", err)
-		}
-		r2, _, err := r.ReadRune()
-		if err != nil {
-			t.Fatal("unexpected error reading after unreading:", err)
-		}
-		if r1 != r2 {
-			t.Fatalf("incorrect rune after unread: got %c, want %c", r1, r2)
-		}
-	}
-	if got != want {
-		t.Errorf("got %q, want %q", got, want)
-	}
-}
-
-func TestUnreadByte(t *testing.T) {
-	segments := []string{"Hello, ", "world"}
-	r := NewReader(&StringReader{data: segments})
-	got := ""
-	want := strings.Join(segments, "")
-	// Normal execution.
-	for {
-		b1, err := r.ReadByte()
-		if err != nil {
-			if err != io.EOF {
-				t.Error("unexpected error on ReadByte:", err)
-			}
-			break
-		}
-		got += string(b1)
-		// Put it back and read it again.
-		if err = r.UnreadByte(); err != nil {
-			t.Fatal("unexpected error on UnreadByte:", err)
-		}
-		b2, err := r.ReadByte()
-		if err != nil {
-			t.Fatal("unexpected error reading after unreading:", err)
-		}
-		if b1 != b2 {
-			t.Fatalf("incorrect byte after unread: got %q, want %q", b1, b2)
-		}
-	}
-	if got != want {
-		t.Errorf("got %q, want %q", got, want)
-	}
-}
-
-func TestUnreadByteMultiple(t *testing.T) {
-	segments := []string{"Hello, ", "world"}
-	data := strings.Join(segments, "")
-	for n := 0; n <= len(data); n++ {
-		r := NewReader(&StringReader{data: segments})
-		// Read n bytes.
-		for i := 0; i < n; i++ {
-			b, err := r.ReadByte()
-			if err != nil {
-				t.Fatalf("n = %d: unexpected error on ReadByte: %v", n, err)
-			}
-			if b != data[i] {
-				t.Fatalf("n = %d: incorrect byte returned from ReadByte: got %q, want %q", n, b, data[i])
-			}
-		}
-		// Unread one byte if there is one.
-		if n > 0 {
-			if err := r.UnreadByte(); err != nil {
-				t.Errorf("n = %d: unexpected error on UnreadByte: %v", n, err)
-			}
-		}
-		// Test that we cannot unread any further.
-		if err := r.UnreadByte(); err == nil {
-			t.Errorf("n = %d: expected error on UnreadByte", n)
-		}
-	}
-}
-
-func TestUnreadByteOthers(t *testing.T) {
-	// A list of readers to use in conjunction with UnreadByte.
-	var readers = []func(*Reader, byte) ([]byte, error){
-		(*Reader).ReadBytes,
-		(*Reader).ReadSlice,
-		func(r *Reader, delim byte) ([]byte, error) {
-			data, err := r.ReadString(delim)
-			return []byte(data), err
-		},
-		// ReadLine doesn't fit the data/pattern easily
-		// so we leave it out. It should be covered via
-		// the ReadSlice test since ReadLine simply calls
-		// ReadSlice, and it's that function that handles
-		// the last byte.
-	}
-
-	// Try all readers with UnreadByte.
-	for rno, read := range readers {
-		// Some input data that is longer than the minimum reader buffer size.
-		const n = 10
-		var buf bytes.Buffer
-		for i := 0; i < n; i++ {
-			buf.WriteString("abcdefg")
-		}
-
-		r := NewReaderSize(&buf, minReadBufferSize)
-		readTo := func(delim byte, want string) {
-			data, err := read(r, delim)
-			if err != nil {
-				t.Fatalf("#%d: unexpected error reading to %c: %v", rno, delim, err)
-			}
-			if got := string(data); got != want {
-				t.Fatalf("#%d: got %q, want %q", rno, got, want)
-			}
-		}
-
-		// Read the data with occasional UnreadByte calls.
-		for i := 0; i < n; i++ {
-			readTo('d', "abcd")
-			for j := 0; j < 3; j++ {
-				if err := r.UnreadByte(); err != nil {
-					t.Fatalf("#%d: unexpected error on UnreadByte: %v", rno, err)
-				}
-				readTo('d', "d")
-			}
-			readTo('g', "efg")
-		}
-
-		// All data should have been read.
-		_, err := r.ReadByte()
-		if err != io.EOF {
-			t.Errorf("#%d: got error %v; want EOF", rno, err)
-		}
-	}
-}
-
-// Test that UnreadRune fails if the preceding operation was not a ReadRune.
-func TestUnreadRuneError(t *testing.T) {
-	buf := make([]byte, 3) // All runes in this test are 3 bytes long
-	r := NewReader(&StringReader{data: []string{"日本語日本語日本語"}})
-	if r.UnreadRune() == nil {
-		t.Error("expected error on UnreadRune from fresh buffer")
-	}
-	_, _, err := r.ReadRune()
-	if err != nil {
-		t.Error("unexpected error on ReadRune (1):", err)
-	}
-	if err = r.UnreadRune(); err != nil {
-		t.Error("unexpected error on UnreadRune (1):", err)
-	}
-	if r.UnreadRune() == nil {
-		t.Error("expected error after UnreadRune (1)")
-	}
-	// Test error after Read.
-	_, _, err = r.ReadRune() // reset state
-	if err != nil {
-		t.Error("unexpected error on ReadRune (2):", err)
-	}
-	_, err = r.Read(buf)
-	if err != nil {
-		t.Error("unexpected error on Read (2):", err)
-	}
-	if r.UnreadRune() == nil {
-		t.Error("expected error after Read (2)")
-	}
-	// Test error after ReadByte.
-	_, _, err = r.ReadRune() // reset state
-	if err != nil {
-		t.Error("unexpected error on ReadRune (2):", err)
-	}
-	for _ = range buf {
-		_, err = r.ReadByte()
-		if err != nil {
-			t.Error("unexpected error on ReadByte (2):", err)
-		}
-	}
-	if r.UnreadRune() == nil {
-		t.Error("expected error after ReadByte")
-	}
-	// Test error after UnreadByte.
-	_, _, err = r.ReadRune() // reset state
-	if err != nil {
-		t.Error("unexpected error on ReadRune (3):", err)
-	}
-	_, err = r.ReadByte()
-	if err != nil {
-		t.Error("unexpected error on ReadByte (3):", err)
-	}
-	err = r.UnreadByte()
-	if err != nil {
-		t.Error("unexpected error on UnreadByte (3):", err)
-	}
-	if r.UnreadRune() == nil {
-		t.Error("expected error after UnreadByte (3)")
-	}
-}
-
-func TestUnreadRuneAtEOF(t *testing.T) {
-	// UnreadRune/ReadRune should error at EOF (was a bug; used to panic)
-	r := NewReader(strings.NewReader("x"))
-	r.ReadRune()
-	r.ReadRune()
-	r.UnreadRune()
-	_, _, err := r.ReadRune()
-	if err == nil {
-		t.Error("expected error at EOF")
-	} else if err != io.EOF {
-		t.Error("expected EOF; got", err)
-	}
-}
-
-func TestReadWriteRune(t *testing.T) {
-	const NRune = 1000
-	byteBuf := new(bytes.Buffer)
-	w := NewWriter(byteBuf)
-	// Write the runes out using WriteRune
-	buf := make([]byte, utf8.UTFMax)
-	for r := rune(0); r < NRune; r++ {
-		size := utf8.EncodeRune(buf, r)
-		nbytes, err := w.WriteRune(r)
-		if err != nil {
-			t.Fatalf("WriteRune(0x%x) error: %s", r, err)
-		}
-		if nbytes != size {
-			t.Fatalf("WriteRune(0x%x) expected %d, got %d", r, size, nbytes)
-		}
-	}
-	w.Flush()
-
-	r := NewReader(byteBuf)
-	// Read them back with ReadRune
-	for r1 := rune(0); r1 < NRune; r1++ {
-		size := utf8.EncodeRune(buf, r1)
-		nr, nbytes, err := r.ReadRune()
-		if nr != r1 || nbytes != size || err != nil {
-			t.Fatalf("ReadRune(0x%x) got 0x%x,%d not 0x%x,%d (err=%s)", r1, nr, nbytes, r1, size, err)
-		}
-	}
-}
-
-func TestWriter(t *testing.T) {
-	var data [8192]byte
-
-	for i := 0; i < len(data); i++ {
-		data[i] = byte(' ' + i%('~'-' '))
-	}
-	w := new(bytes.Buffer)
-	for i := 0; i < len(bufsizes); i++ {
-		for j := 0; j < len(bufsizes); j++ {
-			nwrite := bufsizes[i]
-			bs := bufsizes[j]
-
-			// Write nwrite bytes using buffer size bs.
-			// Check that the right amount makes it out
-			// and that the data is correct.
-
-			w.Reset()
-			buf := NewWriterSize(w, bs)
-			context := fmt.Sprintf("nwrite=%d bufsize=%d", nwrite, bs)
-			n, e1 := buf.Write(data[0:nwrite])
-			if e1 != nil || n != nwrite {
-				t.Errorf("%s: buf.Write %d = %d, %v", context, nwrite, n, e1)
-				continue
-			}
-			if e := buf.Flush(); e != nil {
-				t.Errorf("%s: buf.Flush = %v", context, e)
-			}
-
-			written := w.Bytes()
-			if len(written) != nwrite {
-				t.Errorf("%s: %d bytes written", context, len(written))
-			}
-			for l := 0; l < len(written); l++ {
-				if written[i] != data[i] {
-					t.Errorf("wrong bytes written")
-					t.Errorf("want=%q", data[0:len(written)])
-					t.Errorf("have=%q", written)
-				}
-			}
-		}
-	}
-}
-
-// Check that write errors are returned properly.
-
-type errorWriterTest struct {
-	n, m   int
-	err    error
-	expect error
-}
-
-func (w errorWriterTest) Write(p []byte) (int, error) {
-	return len(p) * w.n / w.m, w.err
-}
-
-var errorWriterTests = []errorWriterTest{
-	{0, 1, nil, io.ErrShortWrite},
-	{1, 2, nil, io.ErrShortWrite},
-	{1, 1, nil, nil},
-	{0, 1, io.ErrClosedPipe, io.ErrClosedPipe},
-	{1, 2, io.ErrClosedPipe, io.ErrClosedPipe},
-	{1, 1, io.ErrClosedPipe, io.ErrClosedPipe},
-}
-
-func TestWriteErrors(t *testing.T) {
-	for _, w := range errorWriterTests {
-		buf := NewWriter(w)
-		_, e := buf.Write([]byte("hello world"))
-		if e != nil {
-			t.Errorf("Write hello to %v: %v", w, e)
-			continue
-		}
-		// Two flushes, to verify the error is sticky.
-		for i := 0; i < 2; i++ {
-			e = buf.Flush()
-			if e != w.expect {
-				t.Errorf("Flush %d/2 %v: got %v, wanted %v", i+1, w, e, w.expect)
-			}
-		}
-	}
-}
-
-func TestNewReaderSizeIdempotent(t *testing.T) {
-	const BufSize = 1000
-	b := NewReaderSize(strings.NewReader("hello world"), BufSize)
-	// Does it recognize itself?
-	b1 := NewReaderSize(b, BufSize)
-	if b1 != b {
-		t.Error("NewReaderSize did not detect underlying Reader")
-	}
-	// Does it wrap if existing buffer is too small?
-	b2 := NewReaderSize(b, 2*BufSize)
-	if b2 == b {
-		t.Error("NewReaderSize did not enlarge buffer")
-	}
-}
-
-func TestNewWriterSizeIdempotent(t *testing.T) {
-	const BufSize = 1000
-	b := NewWriterSize(new(bytes.Buffer), BufSize)
-	// Does it recognize itself?
-	b1 := NewWriterSize(b, BufSize)
-	if b1 != b {
-		t.Error("NewWriterSize did not detect underlying Writer")
-	}
-	// Does it wrap if existing buffer is too small?
-	b2 := NewWriterSize(b, 2*BufSize)
-	if b2 == b {
-		t.Error("NewWriterSize did not enlarge buffer")
-	}
-}
-
-func TestWriteString(t *testing.T) {
-	const BufSize = 8
-	buf := new(bytes.Buffer)
-	b := NewWriterSize(buf, BufSize)
-	b.WriteString("0")                         // easy
-	b.WriteString("123456")                    // still easy
-	b.WriteString("7890")                      // easy after flush
-	b.WriteString("abcdefghijklmnopqrstuvwxy") // hard
-	b.WriteString("z")
-	if err := b.Flush(); err != nil {
-		t.Error("WriteString", err)
-	}
-	s := "01234567890abcdefghijklmnopqrstuvwxyz"
-	if string(buf.Bytes()) != s {
-		t.Errorf("WriteString wants %q gets %q", s, string(buf.Bytes()))
-	}
-}
-
-func TestBufferFull(t *testing.T) {
-	const longString = "And now, hello, world! It is the time for all good men to come to the aid of their party"
-	buf := NewReaderSize(strings.NewReader(longString), minReadBufferSize)
-	line, err := buf.ReadSlice('!')
-	if string(line) != "And now, hello, " || err != ErrBufferFull {
-		t.Errorf("first ReadSlice(,) = %q, %v", line, err)
-	}
-	line, err = buf.ReadSlice('!')
-	if string(line) != "world!" || err != nil {
-		t.Errorf("second ReadSlice(,) = %q, %v", line, err)
-	}
-}
-
-func TestPeek(t *testing.T) {
-	p := make([]byte, 10)
-	// string is 16 (minReadBufferSize) long.
-	buf := NewReaderSize(strings.NewReader("abcdefghijklmnop"), minReadBufferSize)
-	if s, err := buf.Peek(1); string(s) != "a" || err != nil {
-		t.Fatalf("want %q got %q, err=%v", "a", string(s), err)
-	}
-	if s, err := buf.Peek(4); string(s) != "abcd" || err != nil {
-		t.Fatalf("want %q got %q, err=%v", "abcd", string(s), err)
-	}
-	if _, err := buf.Peek(-1); err != ErrNegativeCount {
-		t.Fatalf("want ErrNegativeCount got %v", err)
-	}
-	if _, err := buf.Peek(32); err != ErrBufferFull {
-		t.Fatalf("want ErrBufFull got %v", err)
-	}
-	if _, err := buf.Read(p[0:3]); string(p[0:3]) != "abc" || err != nil {
-		t.Fatalf("want %q got %q, err=%v", "abc", string(p[0:3]), err)
-	}
-	if s, err := buf.Peek(1); string(s) != "d" || err != nil {
-		t.Fatalf("want %q got %q, err=%v", "d", string(s), err)
-	}
-	if s, err := buf.Peek(2); string(s) != "de" || err != nil {
-		t.Fatalf("want %q got %q, err=%v", "de", string(s), err)
-	}
-	if _, err := buf.Read(p[0:3]); string(p[0:3]) != "def" || err != nil {
-		t.Fatalf("want %q got %q, err=%v", "def", string(p[0:3]), err)
-	}
-	if s, err := buf.Peek(4); string(s) != "ghij" || err != nil {
-		t.Fatalf("want %q got %q, err=%v", "ghij", string(s), err)
-	}
-	if _, err := buf.Read(p[0:]); string(p[0:]) != "ghijklmnop" || err != nil {
-		t.Fatalf("want %q got %q, err=%v", "ghijklmnop", string(p[0:minReadBufferSize]), err)
-	}
-	if s, err := buf.Peek(0); string(s) != "" || err != nil {
-		t.Fatalf("want %q got %q, err=%v", "", string(s), err)
-	}
-	if _, err := buf.Peek(1); err != io.EOF {
-		t.Fatalf("want EOF got %v", err)
-	}
-
-	// Test for issue 3022, not exposing a reader's error on a successful Peek.
-	buf = NewReaderSize(dataAndEOFReader("abcd"), 32)
-	if s, err := buf.Peek(2); string(s) != "ab" || err != nil {
-		t.Errorf(`Peek(2) on "abcd", EOF = %q, %v; want "ab", nil`, string(s), err)
-	}
-	if s, err := buf.Peek(4); string(s) != "abcd" || err != nil {
-		t.Errorf(`Peek(4) on "abcd", EOF = %q, %v; want "abcd", nil`, string(s), err)
-	}
-	if n, err := buf.Read(p[0:5]); string(p[0:n]) != "abcd" || err != nil {
-		t.Fatalf("Read after peek = %q, %v; want abcd, EOF", p[0:n], err)
-	}
-	if n, err := buf.Read(p[0:1]); string(p[0:n]) != "" || err != io.EOF {
-		t.Fatalf(`second Read after peek = %q, %v; want "", EOF`, p[0:n], err)
-	}
-}
-
-type dataAndEOFReader string
-
-func (r dataAndEOFReader) Read(p []byte) (int, error) {
-	return copy(p, r), io.EOF
-}
-
-func TestPeekThenUnreadRune(t *testing.T) {
-	// This sequence used to cause a crash.
-	r := NewReader(strings.NewReader("x"))
-	r.ReadRune()
-	r.Peek(1)
-	r.UnreadRune()
-	r.ReadRune() // Used to panic here
-}
-
-var testOutput = []byte("0123456789abcdefghijklmnopqrstuvwxy")
-var testInput = []byte("012\n345\n678\n9ab\ncde\nfgh\nijk\nlmn\nopq\nrst\nuvw\nxy")
-var testInputrn = []byte("012\r\n345\r\n678\r\n9ab\r\ncde\r\nfgh\r\nijk\r\nlmn\r\nopq\r\nrst\r\nuvw\r\nxy\r\n\n\r\n")
-
-// TestReader wraps a []byte and returns reads of a specific length.
-type testReader struct {
-	data   []byte
-	stride int
-}
-
-func (t *testReader) Read(buf []byte) (n int, err error) {
-	n = t.stride
-	if n > len(t.data) {
-		n = len(t.data)
-	}
-	if n > len(buf) {
-		n = len(buf)
-	}
-	copy(buf, t.data)
-	t.data = t.data[n:]
-	if len(t.data) == 0 {
-		err = io.EOF
-	}
-	return
-}
-
-func testReadLine(t *testing.T, input []byte) {
-	//for stride := 1; stride < len(input); stride++ {
-	for stride := 1; stride < 2; stride++ {
-		done := 0
-		reader := testReader{input, stride}
-		l := NewReaderSize(&reader, len(input)+1)
-		for {
-			line, isPrefix, err := l.ReadLine()
-			if len(line) > 0 && err != nil {
-				t.Errorf("ReadLine returned both data and error: %s", err)
-			}
-			if isPrefix {
-				t.Errorf("ReadLine returned prefix")
-			}
-			if err != nil {
-				if err != io.EOF {
-					t.Fatalf("Got unknown error: %s", err)
-				}
-				break
-			}
-			if want := testOutput[done : done+len(line)]; !bytes.Equal(want, line) {
-				t.Errorf("Bad line at stride %d: want: %x got: %x", stride, want, line)
-			}
-			done += len(line)
-		}
-		if done != len(testOutput) {
-			t.Errorf("ReadLine didn't return everything: got: %d, want: %d (stride: %d)", done, len(testOutput), stride)
-		}
-	}
-}
-
-func TestReadLine(t *testing.T) {
-	testReadLine(t, testInput)
-	testReadLine(t, testInputrn)
-}
-
-func TestLineTooLong(t *testing.T) {
-	data := make([]byte, 0)
-	for i := 0; i < minReadBufferSize*5/2; i++ {
-		data = append(data, '0'+byte(i%10))
-	}
-	buf := bytes.NewReader(data)
-	l := NewReaderSize(buf, minReadBufferSize)
-	line, isPrefix, err := l.ReadLine()
-	if !isPrefix || !bytes.Equal(line, data[:minReadBufferSize]) || err != nil {
-		t.Errorf("bad result for first line: got %q want %q %v", line, data[:minReadBufferSize], err)
-	}
-	data = data[len(line):]
-	line, isPrefix, err = l.ReadLine()
-	if !isPrefix || !bytes.Equal(line, data[:minReadBufferSize]) || err != nil {
-		t.Errorf("bad result for second line: got %q want %q %v", line, data[:minReadBufferSize], err)
-	}
-	data = data[len(line):]
-	line, isPrefix, err = l.ReadLine()
-	if isPrefix || !bytes.Equal(line, data[:minReadBufferSize/2]) || err != nil {
-		t.Errorf("bad result for third line: got %q want %q %v", line, data[:minReadBufferSize/2], err)
-	}
-	line, isPrefix, err = l.ReadLine()
-	if isPrefix || err == nil {
-		t.Errorf("expected no more lines: %x %s", line, err)
-	}
-}
-
-func TestReadAfterLines(t *testing.T) {
-	line1 := "this is line1"
-	restData := "this is line2\nthis is line 3\n"
-	inbuf := bytes.NewReader([]byte(line1 + "\n" + restData))
-	outbuf := new(bytes.Buffer)
-	maxLineLength := len(line1) + len(restData)/2
-	l := NewReaderSize(inbuf, maxLineLength)
-	line, isPrefix, err := l.ReadLine()
-	if isPrefix || err != nil || string(line) != line1 {
-		t.Errorf("bad result for first line: isPrefix=%v err=%v line=%q", isPrefix, err, string(line))
-	}
-	n, err := io.Copy(outbuf, l)
-	if int(n) != len(restData) || err != nil {
-		t.Errorf("bad result for Read: n=%d err=%v", n, err)
-	}
-	if outbuf.String() != restData {
-		t.Errorf("bad result for Read: got %q; expected %q", outbuf.String(), restData)
-	}
-}
-
-func TestReadEmptyBuffer(t *testing.T) {
-	l := NewReaderSize(new(bytes.Buffer), minReadBufferSize)
-	line, isPrefix, err := l.ReadLine()
-	if err != io.EOF {
-		t.Errorf("expected EOF from ReadLine, got '%s' %t %s", line, isPrefix, err)
-	}
-}
-
-func TestLinesAfterRead(t *testing.T) {
-	l := NewReaderSize(bytes.NewReader([]byte("foo")), minReadBufferSize)
-	_, err := ioutil.ReadAll(l)
-	if err != nil {
-		t.Error(err)
-		return
-	}
-
-	line, isPrefix, err := l.ReadLine()
-	if err != io.EOF {
-		t.Errorf("expected EOF from ReadLine, got '%s' %t %s", line, isPrefix, err)
-	}
-}
-
-func TestReadLineNonNilLineOrError(t *testing.T) {
-	r := NewReader(strings.NewReader("line 1\n"))
-	for i := 0; i < 2; i++ {
-		l, _, err := r.ReadLine()
-		if l != nil && err != nil {
-			t.Fatalf("on line %d/2; ReadLine=%#v, %v; want non-nil line or Error, but not both",
-				i+1, l, err)
-		}
-	}
-}
-
-type readLineResult struct {
-	line     []byte
-	isPrefix bool
-	err      error
-}
-
-var readLineNewlinesTests = []struct {
-	input  string
-	expect []readLineResult
-}{
-	{"012345678901234\r\n012345678901234\r\n", []readLineResult{
-		{[]byte("012345678901234"), true, nil},
-		{nil, false, nil},
-		{[]byte("012345678901234"), true, nil},
-		{nil, false, nil},
-		{nil, false, io.EOF},
-	}},
-	{"0123456789012345\r012345678901234\r", []readLineResult{
-		{[]byte("0123456789012345"), true, nil},
-		{[]byte("\r012345678901234"), true, nil},
-		{[]byte("\r"), false, nil},
-		{nil, false, io.EOF},
-	}},
-}
-
-func TestReadLineNewlines(t *testing.T) {
-	for _, e := range readLineNewlinesTests {
-		testReadLineNewlines(t, e.input, e.expect)
-	}
-}
-
-func testReadLineNewlines(t *testing.T, input string, expect []readLineResult) {
-	b := NewReaderSize(strings.NewReader(input), minReadBufferSize)
-	for i, e := range expect {
-		line, isPrefix, err := b.ReadLine()
-		if !bytes.Equal(line, e.line) {
-			t.Errorf("%q call %d, line == %q, want %q", input, i, line, e.line)
-			return
-		}
-		if isPrefix != e.isPrefix {
-			t.Errorf("%q call %d, isPrefix == %v, want %v", input, i, isPrefix, e.isPrefix)
-			return
-		}
-		if err != e.err {
-			t.Errorf("%q call %d, err == %v, want %v", input, i, err, e.err)
-			return
-		}
-	}
-}
-
-func createTestInput(n int) []byte {
-	input := make([]byte, n)
-	for i := range input {
-		// 101 and 251 are arbitrary prime numbers.
-		// The idea is to create an input sequence
-		// which doesn't repeat too frequently.
-		input[i] = byte(i % 251)
-		if i%101 == 0 {
-			input[i] ^= byte(i / 101)
-		}
-	}
-	return input
-}
-
-func TestReaderWriteTo(t *testing.T) {
-	input := createTestInput(8192)
-	r := NewReader(onlyReader{bytes.NewReader(input)})
-	w := new(bytes.Buffer)
-	if n, err := r.WriteTo(w); err != nil || n != int64(len(input)) {
-		t.Fatalf("r.WriteTo(w) = %d, %v, want %d, nil", n, err, len(input))
-	}
-
-	for i, val := range w.Bytes() {
-		if val != input[i] {
-			t.Errorf("after write: out[%d] = %#x, want %#x", i, val, input[i])
-		}
-	}
-}
-
-type errorWriterToTest struct {
-	rn, wn     int
-	rerr, werr error
-	expected   error
-}
-
-func (r errorWriterToTest) Read(p []byte) (int, error) {
-	return len(p) * r.rn, r.rerr
-}
-
-func (w errorWriterToTest) Write(p []byte) (int, error) {
-	return len(p) * w.wn, w.werr
-}
-
-var errorWriterToTests = []errorWriterToTest{
-	{1, 0, nil, io.ErrClosedPipe, io.ErrClosedPipe},
-	{0, 1, io.ErrClosedPipe, nil, io.ErrClosedPipe},
-	{0, 0, io.ErrUnexpectedEOF, io.ErrClosedPipe, io.ErrClosedPipe},
-	{0, 1, io.EOF, nil, nil},
-}
-
-func TestReaderWriteToErrors(t *testing.T) {
-	for i, rw := range errorWriterToTests {
-		r := NewReader(rw)
-		if _, err := r.WriteTo(rw); err != rw.expected {
-			t.Errorf("r.WriteTo(errorWriterToTests[%d]) = _, %v, want _,%v", i, err, rw.expected)
-		}
-	}
-}
-
-func TestWriterReadFrom(t *testing.T) {
-	ws := []func(io.Writer) io.Writer{
-		func(w io.Writer) io.Writer { return onlyWriter{w} },
-		func(w io.Writer) io.Writer { return w },
-	}
-
-	rs := []func(io.Reader) io.Reader{
-		iotest.DataErrReader,
-		func(r io.Reader) io.Reader { return r },
-	}
-
-	for ri, rfunc := range rs {
-		for wi, wfunc := range ws {
-			input := createTestInput(8192)
-			b := new(bytes.Buffer)
-			w := NewWriter(wfunc(b))
-			r := rfunc(bytes.NewReader(input))
-			if n, err := w.ReadFrom(r); err != nil || n != int64(len(input)) {
-				t.Errorf("ws[%d],rs[%d]: w.ReadFrom(r) = %d, %v, want %d, nil", wi, ri, n, err, len(input))
-				continue
-			}
-			if err := w.Flush(); err != nil {
-				t.Errorf("Flush returned %v", err)
-				continue
-			}
-			if got, want := b.String(), string(input); got != want {
-				t.Errorf("ws[%d], rs[%d]:\ngot  %q\nwant %q\n", wi, ri, got, want)
-			}
-		}
-	}
-}
-
-type errorReaderFromTest struct {
-	rn, wn     int
-	rerr, werr error
-	expected   error
-}
-
-func (r errorReaderFromTest) Read(p []byte) (int, error) {
-	return len(p) * r.rn, r.rerr
-}
-
-func (w errorReaderFromTest) Write(p []byte) (int, error) {
-	return len(p) * w.wn, w.werr
-}
-
-var errorReaderFromTests = []errorReaderFromTest{
-	{0, 1, io.EOF, nil, nil},
-	{1, 1, io.EOF, nil, nil},
-	{0, 1, io.ErrClosedPipe, nil, io.ErrClosedPipe},
-	{0, 0, io.ErrClosedPipe, io.ErrShortWrite, io.ErrClosedPipe},
-	{1, 0, nil, io.ErrShortWrite, io.ErrShortWrite},
-}
-
-func TestWriterReadFromErrors(t *testing.T) {
-	for i, rw := range errorReaderFromTests {
-		w := NewWriter(rw)
-		if _, err := w.ReadFrom(rw); err != rw.expected {
-			t.Errorf("w.ReadFrom(errorReaderFromTests[%d]) = _, %v, want _,%v", i, err, rw.expected)
-		}
-	}
-}
-
-// TestWriterReadFromCounts tests that using io.Copy to copy into a
-// bufio.Writer does not prematurely flush the buffer. For example, when
-// buffering writes to a network socket, excessive network writes should be
-// avoided.
-func TestWriterReadFromCounts(t *testing.T) {
-	var w0 writeCountingDiscard
-	b0 := NewWriterSize(&w0, 1234)
-	b0.WriteString(strings.Repeat("x", 1000))
-	if w0 != 0 {
-		t.Fatalf("write 1000 'x's: got %d writes, want 0", w0)
-	}
-	b0.WriteString(strings.Repeat("x", 200))
-	if w0 != 0 {
-		t.Fatalf("write 1200 'x's: got %d writes, want 0", w0)
-	}
-	io.Copy(b0, onlyReader{strings.NewReader(strings.Repeat("x", 30))})
-	if w0 != 0 {
-		t.Fatalf("write 1230 'x's: got %d writes, want 0", w0)
-	}
-	io.Copy(b0, onlyReader{strings.NewReader(strings.Repeat("x", 9))})
-	if w0 != 1 {
-		t.Fatalf("write 1239 'x's: got %d writes, want 1", w0)
-	}
-
-	var w1 writeCountingDiscard
-	b1 := NewWriterSize(&w1, 1234)
-	b1.WriteString(strings.Repeat("x", 1200))
-	b1.Flush()
-	if w1 != 1 {
-		t.Fatalf("flush 1200 'x's: got %d writes, want 1", w1)
-	}
-	b1.WriteString(strings.Repeat("x", 89))
-	if w1 != 1 {
-		t.Fatalf("write 1200 + 89 'x's: got %d writes, want 1", w1)
-	}
-	io.Copy(b1, onlyReader{strings.NewReader(strings.Repeat("x", 700))})
-	if w1 != 1 {
-		t.Fatalf("write 1200 + 789 'x's: got %d writes, want 1", w1)
-	}
-	io.Copy(b1, onlyReader{strings.NewReader(strings.Repeat("x", 600))})
-	if w1 != 2 {
-		t.Fatalf("write 1200 + 1389 'x's: got %d writes, want 2", w1)
-	}
-	b1.Flush()
-	if w1 != 3 {
-		t.Fatalf("flush 1200 + 1389 'x's: got %d writes, want 3", w1)
-	}
-}
-
-// A writeCountingDiscard is like ioutil.Discard and counts the number of times
-// Write is called on it.
-type writeCountingDiscard int
-
-func (w *writeCountingDiscard) Write(p []byte) (int, error) {
-	*w++
-	return len(p), nil
-}
-
-type negativeReader int
-
-func (r *negativeReader) Read([]byte) (int, error) { return -1, nil }
-
-func TestNegativeRead(t *testing.T) {
-	// should panic with a description pointing at the reader, not at itself.
-	// (should NOT panic with slice index error, for example.)
-	b := NewReader(new(negativeReader))
-	defer func() {
-		switch err := recover().(type) {
-		case nil:
-			t.Fatal("read did not panic")
-		case error:
-			if !strings.Contains(err.Error(), "reader returned negative count from Read") {
-				t.Fatalf("wrong panic: %v", err)
-			}
-		default:
-			t.Fatalf("unexpected panic value: %T(%v)", err, err)
-		}
-	}()
-	b.Read(make([]byte, 100))
-}
-
-var errFake = errors.New("fake error")
-
-type errorThenGoodReader struct {
-	didErr bool
-	nread  int
-}
-
-func (r *errorThenGoodReader) Read(p []byte) (int, error) {
-	r.nread++
-	if !r.didErr {
-		r.didErr = true
-		return 0, errFake
-	}
-	return len(p), nil
-}
-
-func TestReaderClearError(t *testing.T) {
-	r := &errorThenGoodReader{}
-	b := NewReader(r)
-	buf := make([]byte, 1)
-	if _, err := b.Read(nil); err != nil {
-		t.Fatalf("1st nil Read = %v; want nil", err)
-	}
-	if _, err := b.Read(buf); err != errFake {
-		t.Fatalf("1st Read = %v; want errFake", err)
-	}
-	if _, err := b.Read(nil); err != nil {
-		t.Fatalf("2nd nil Read = %v; want nil", err)
-	}
-	if _, err := b.Read(buf); err != nil {
-		t.Fatalf("3rd Read with buffer = %v; want nil", err)
-	}
-	if r.nread != 2 {
-		t.Errorf("num reads = %d; want 2", r.nread)
-	}
-}
-
-// Test for golang.org/issue/5947
-func TestWriterReadFromWhileFull(t *testing.T) {
-	buf := new(bytes.Buffer)
-	w := NewWriterSize(buf, 10)
-
-	// Fill buffer exactly.
-	n, err := w.Write([]byte("0123456789"))
-	if n != 10 || err != nil {
-		t.Fatalf("Write returned (%v, %v), want (10, nil)", n, err)
-	}
-
-	// Use ReadFrom to read in some data.
-	n2, err := w.ReadFrom(strings.NewReader("abcdef"))
-	if n2 != 6 || err != nil {
-		t.Fatalf("ReadFrom returned (%v, %v), want (6, nil)", n2, err)
-	}
-}
-
-type emptyThenNonEmptyReader struct {
-	r io.Reader
-	n int
-}
-
-func (r *emptyThenNonEmptyReader) Read(p []byte) (int, error) {
-	if r.n <= 0 {
-		return r.r.Read(p)
-	}
-	r.n--
-	return 0, nil
-}
-
-// Test for golang.org/issue/7611
-func TestWriterReadFromUntilEOF(t *testing.T) {
-	buf := new(bytes.Buffer)
-	w := NewWriterSize(buf, 5)
-
-	// Partially fill buffer
-	n, err := w.Write([]byte("0123"))
-	if n != 4 || err != nil {
-		t.Fatalf("Write returned (%v, %v), want (4, nil)", n, err)
-	}
-
-	// Use ReadFrom to read in some data.
-	r := &emptyThenNonEmptyReader{r: strings.NewReader("abcd"), n: 3}
-	n2, err := w.ReadFrom(r)
-	if n2 != 4 || err != nil {
-		t.Fatalf("ReadFrom returned (%v, %v), want (4, nil)", n2, err)
-	}
-	w.Flush()
-	if got, want := string(buf.Bytes()), "0123abcd"; got != want {
-		t.Fatalf("buf.Bytes() returned %q, want %q", got, want)
-	}
-}
-
-func TestWriterReadFromErrNoProgress(t *testing.T) {
-	buf := new(bytes.Buffer)
-	w := NewWriterSize(buf, 5)
-
-	// Partially fill buffer
-	n, err := w.Write([]byte("0123"))
-	if n != 4 || err != nil {
-		t.Fatalf("Write returned (%v, %v), want (4, nil)", n, err)
-	}
-
-	// Use ReadFrom to read in some data.
-	r := &emptyThenNonEmptyReader{r: strings.NewReader("abcd"), n: 100}
-	n2, err := w.ReadFrom(r)
-	if n2 != 0 || err != io.ErrNoProgress {
-		t.Fatalf("buf.Bytes() returned (%v, %v), want (0, io.ErrNoProgress)", n2, err)
-	}
-}
-
-func TestReaderReset(t *testing.T) {
-	r := NewReader(strings.NewReader("foo foo"))
-	buf := make([]byte, 3)
-	r.Read(buf)
-	if string(buf) != "foo" {
-		t.Errorf("buf = %q; want foo", buf)
-	}
-	r.Reset(strings.NewReader("bar bar"))
-	all, err := ioutil.ReadAll(r)
-	if err != nil {
-		t.Fatal(err)
-	}
-	if string(all) != "bar bar" {
-		t.Errorf("ReadAll = %q; want bar bar", all)
-	}
-}
-
-func TestWriterReset(t *testing.T) {
-	var buf1, buf2 bytes.Buffer
-	w := NewWriter(&buf1)
-	w.WriteString("foo")
-	w.Reset(&buf2) // and not flushed
-	w.WriteString("bar")
-	w.Flush()
-	if buf1.String() != "" {
-		t.Errorf("buf1 = %q; want empty", buf1.String())
-	}
-	if buf2.String() != "bar" {
-		t.Errorf("buf2 = %q; want bar", buf2.String())
-	}
-}
-
-// An onlyReader only implements io.Reader, no matter what other methods the underlying implementation may have.
-type onlyReader struct {
-	io.Reader
-}
-
-// An onlyWriter only implements io.Writer, no matter what other methods the underlying implementation may have.
-type onlyWriter struct {
-	io.Writer
-}
-
-func BenchmarkReaderCopyOptimal(b *testing.B) {
-	// Optimal case is where the underlying reader implements io.WriterTo
-	srcBuf := bytes.NewBuffer(make([]byte, 8192))
-	src := NewReader(srcBuf)
-	dstBuf := new(bytes.Buffer)
-	dst := onlyWriter{dstBuf}
-	for i := 0; i < b.N; i++ {
-		srcBuf.Reset()
-		src.Reset(srcBuf)
-		dstBuf.Reset()
-		io.Copy(dst, src)
-	}
-}
-
-func BenchmarkReaderCopyUnoptimal(b *testing.B) {
-	// Unoptimal case is where the underlying reader doesn't implement io.WriterTo
-	srcBuf := bytes.NewBuffer(make([]byte, 8192))
-	src := NewReader(onlyReader{srcBuf})
-	dstBuf := new(bytes.Buffer)
-	dst := onlyWriter{dstBuf}
-	for i := 0; i < b.N; i++ {
-		srcBuf.Reset()
-		src.Reset(onlyReader{srcBuf})
-		dstBuf.Reset()
-		io.Copy(dst, src)
-	}
-}
-
-func BenchmarkReaderCopyNoWriteTo(b *testing.B) {
-	srcBuf := bytes.NewBuffer(make([]byte, 8192))
-	srcReader := NewReader(srcBuf)
-	src := onlyReader{srcReader}
-	dstBuf := new(bytes.Buffer)
-	dst := onlyWriter{dstBuf}
-	for i := 0; i < b.N; i++ {
-		srcBuf.Reset()
-		srcReader.Reset(srcBuf)
-		dstBuf.Reset()
-		io.Copy(dst, src)
-	}
-}
-
-func BenchmarkReaderWriteToOptimal(b *testing.B) {
-	const bufSize = 16 << 10
-	buf := make([]byte, bufSize)
-	r := bytes.NewReader(buf)
-	srcReader := NewReaderSize(onlyReader{r}, 1<<10)
-	if _, ok := ioutil.Discard.(io.ReaderFrom); !ok {
-		b.Fatal("ioutil.Discard doesn't support ReaderFrom")
-	}
-	for i := 0; i < b.N; i++ {
-		r.Seek(0, 0)
-		srcReader.Reset(onlyReader{r})
-		n, err := srcReader.WriteTo(ioutil.Discard)
-		if err != nil {
-			b.Fatal(err)
-		}
-		if n != bufSize {
-			b.Fatalf("n = %d; want %d", n, bufSize)
-		}
-	}
-}
-
-func BenchmarkWriterCopyOptimal(b *testing.B) {
-	// Optimal case is where the underlying writer implements io.ReaderFrom
-	srcBuf := bytes.NewBuffer(make([]byte, 8192))
-	src := onlyReader{srcBuf}
-	dstBuf := new(bytes.Buffer)
-	dst := NewWriter(dstBuf)
-	for i := 0; i < b.N; i++ {
-		srcBuf.Reset()
-		dstBuf.Reset()
-		dst.Reset(dstBuf)
-		io.Copy(dst, src)
-	}
-}
-
-func BenchmarkWriterCopyUnoptimal(b *testing.B) {
-	srcBuf := bytes.NewBuffer(make([]byte, 8192))
-	src := onlyReader{srcBuf}
-	dstBuf := new(bytes.Buffer)
-	dst := NewWriter(onlyWriter{dstBuf})
-	for i := 0; i < b.N; i++ {
-		srcBuf.Reset()
-		dstBuf.Reset()
-		dst.Reset(onlyWriter{dstBuf})
-		io.Copy(dst, src)
-	}
-}
-
-func BenchmarkWriterCopyNoReadFrom(b *testing.B) {
-	srcBuf := bytes.NewBuffer(make([]byte, 8192))
-	src := onlyReader{srcBuf}
-	dstBuf := new(bytes.Buffer)
-	dstWriter := NewWriter(dstBuf)
-	dst := onlyWriter{dstWriter}
-	for i := 0; i < b.N; i++ {
-		srcBuf.Reset()
-		dstBuf.Reset()
-		dstWriter.Reset(dstBuf)
-		io.Copy(dst, src)
-	}
-}
-
-func BenchmarkReaderEmpty(b *testing.B) {
-	b.ReportAllocs()
-	str := strings.Repeat("x", 16<<10)
-	for i := 0; i < b.N; i++ {
-		br := NewReader(strings.NewReader(str))
-		n, err := io.Copy(ioutil.Discard, br)
-		if err != nil {
-			b.Fatal(err)
-		}
-		if n != int64(len(str)) {
-			b.Fatal("wrong length")
-		}
-	}
-}
-
-func BenchmarkWriterEmpty(b *testing.B) {
-	b.ReportAllocs()
-	str := strings.Repeat("x", 1<<10)
-	bs := []byte(str)
-	for i := 0; i < b.N; i++ {
-		bw := NewWriter(ioutil.Discard)
-		bw.Flush()
-		bw.WriteByte('a')
-		bw.Flush()
-		bw.WriteRune('B')
-		bw.Flush()
-		bw.Write(bs)
-		bw.Flush()
-		bw.WriteString(str)
-		bw.Flush()
-	}
-}
-
-func BenchmarkWriterFlush(b *testing.B) {
-	b.ReportAllocs()
-	bw := NewWriter(ioutil.Discard)
-	str := strings.Repeat("x", 50)
-	for i := 0; i < b.N; i++ {
-		bw.WriteString(str)
-		bw.Flush()
-	}
-}
diff --git a/src/pkg/bufio/scan.go b/src/pkg/bufio/scan.go
deleted file mode 100644
index 715ce07..0000000
--- a/src/pkg/bufio/scan.go
+++ /dev/null
@@ -1,346 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package bufio
-
-import (
-	"bytes"
-	"errors"
-	"io"
-	"unicode/utf8"
-)
-
-// Scanner provides a convenient interface for reading data such as
-// a file of newline-delimited lines of text. Successive calls to
-// the Scan method will step through the 'tokens' of a file, skipping
-// the bytes between the tokens. The specification of a token is
-// defined by a split function of type SplitFunc; the default split
-// function breaks the input into lines with line termination stripped. Split
-// functions are defined in this package for scanning a file into
-// lines, bytes, UTF-8-encoded runes, and space-delimited words. The
-// client may instead provide a custom split function.
-//
-// Scanning stops unrecoverably at EOF, the first I/O error, or a token too
-// large to fit in the buffer. When a scan stops, the reader may have
-// advanced arbitrarily far past the last token. Programs that need more
-// control over error handling or large tokens, or must run sequential scans
-// on a reader, should use bufio.Reader instead.
-//
-type Scanner struct {
-	r            io.Reader // The reader provided by the client.
-	split        SplitFunc // The function to split the tokens.
-	maxTokenSize int       // Maximum size of a token; modified by tests.
-	token        []byte    // Last token returned by split.
-	buf          []byte    // Buffer used as argument to split.
-	start        int       // First non-processed byte in buf.
-	end          int       // End of data in buf.
-	err          error     // Sticky error.
-}
-
-// SplitFunc is the signature of the split function used to tokenize the
-// input. The arguments are an initial substring of the remaining unprocessed
-// data and a flag, atEOF, that reports whether the Reader has no more data
-// to give. The return values are the number of bytes to advance the input
-// and the next token to return to the user, plus an error, if any. If the
-// data does not yet hold a complete token, for instance if it has no newline
-// while scanning lines, SplitFunc can return (0, nil, nil) to signal the
-// Scanner to read more data into the slice and try again with a longer slice
-// starting at the same point in the input.
-//
-// If the returned error is non-nil, scanning stops and the error
-// is returned to the client.
-//
-// The function is never called with an empty data slice unless atEOF
-// is true. If atEOF is true, however, data may be non-empty and,
-// as always, holds unprocessed text.
-type SplitFunc func(data []byte, atEOF bool) (advance int, token []byte, err error)
-
-// Errors returned by Scanner.
-var (
-	ErrTooLong         = errors.New("bufio.Scanner: token too long")
-	ErrNegativeAdvance = errors.New("bufio.Scanner: SplitFunc returns negative advance count")
-	ErrAdvanceTooFar   = errors.New("bufio.Scanner: SplitFunc returns advance count beyond input")
-)
-
-const (
-	// Maximum size used to buffer a token. The actual maximum token size
-	// may be smaller as the buffer may need to include, for instance, a newline.
-	MaxScanTokenSize = 64 * 1024
-)
-
-// NewScanner returns a new Scanner to read from r.
-// The split function defaults to ScanLines.
-func NewScanner(r io.Reader) *Scanner {
-	return &Scanner{
-		r:            r,
-		split:        ScanLines,
-		maxTokenSize: MaxScanTokenSize,
-		buf:          make([]byte, 4096), // Plausible starting size; needn't be large.
-	}
-}
-
-// Err returns the first non-EOF error that was encountered by the Scanner.
-func (s *Scanner) Err() error {
-	if s.err == io.EOF {
-		return nil
-	}
-	return s.err
-}
-
-// Bytes returns the most recent token generated by a call to Scan.
-// The underlying array may point to data that will be overwritten
-// by a subsequent call to Scan. It does no allocation.
-func (s *Scanner) Bytes() []byte {
-	return s.token
-}
-
-// Text returns the most recent token generated by a call to Scan
-// as a newly allocated string holding its bytes.
-func (s *Scanner) Text() string {
-	return string(s.token)
-}
-
-// Scan advances the Scanner to the next token, which will then be
-// available through the Bytes or Text method. It returns false when the
-// scan stops, either by reaching the end of the input or an error.
-// After Scan returns false, the Err method will return any error that
-// occurred during scanning, except that if it was io.EOF, Err
-// will return nil.
-func (s *Scanner) Scan() bool {
-	// Loop until we have a token.
-	for {
-		// See if we can get a token with what we already have.
-		if s.end > s.start {
-			advance, token, err := s.split(s.buf[s.start:s.end], s.err != nil)
-			if err != nil {
-				s.setErr(err)
-				return false
-			}
-			if !s.advance(advance) {
-				return false
-			}
-			s.token = token
-			if token != nil {
-				return true
-			}
-		}
-		// We cannot generate a token with what we are holding.
-		// If we've already hit EOF or an I/O error, we are done.
-		if s.err != nil {
-			// Shut it down.
-			s.start = 0
-			s.end = 0
-			return false
-		}
-		// Must read more data.
-		// First, shift data to beginning of buffer if there's lots of empty space
-		// or space is needed.
-		if s.start > 0 && (s.end == len(s.buf) || s.start > len(s.buf)/2) {
-			copy(s.buf, s.buf[s.start:s.end])
-			s.end -= s.start
-			s.start = 0
-		}
-		// Is the buffer full? If so, resize.
-		if s.end == len(s.buf) {
-			if len(s.buf) >= s.maxTokenSize {
-				s.setErr(ErrTooLong)
-				return false
-			}
-			newSize := len(s.buf) * 2
-			if newSize > s.maxTokenSize {
-				newSize = s.maxTokenSize
-			}
-			newBuf := make([]byte, newSize)
-			copy(newBuf, s.buf[s.start:s.end])
-			s.buf = newBuf
-			s.end -= s.start
-			s.start = 0
-			continue
-		}
-		// Finally we can read some input. Make sure we don't get stuck with
-		// a misbehaving Reader. Officially we don't need to do this, but let's
-		// be extra careful: Scanner is for safe, simple jobs.
-		for loop := 0; ; {
-			n, err := s.r.Read(s.buf[s.end:len(s.buf)])
-			s.end += n
-			if err != nil {
-				s.setErr(err)
-				break
-			}
-			if n > 0 {
-				break
-			}
-			loop++
-			if loop > maxConsecutiveEmptyReads {
-				s.setErr(io.ErrNoProgress)
-				break
-			}
-		}
-	}
-}
-
-// advance consumes n bytes of the buffer. It reports whether the advance was legal.
-func (s *Scanner) advance(n int) bool {
-	if n < 0 {
-		s.setErr(ErrNegativeAdvance)
-		return false
-	}
-	if n > s.end-s.start {
-		s.setErr(ErrAdvanceTooFar)
-		return false
-	}
-	s.start += n
-	return true
-}
-
-// setErr records the first error encountered.
-func (s *Scanner) setErr(err error) {
-	if s.err == nil || s.err == io.EOF {
-		s.err = err
-	}
-}
-
-// Split sets the split function for the Scanner. If called, it must be
-// called before Scan. The default split function is ScanLines.
-func (s *Scanner) Split(split SplitFunc) {
-	s.split = split
-}
-
-// Split functions
-
-// ScanBytes is a split function for a Scanner that returns each byte as a token.
-func ScanBytes(data []byte, atEOF bool) (advance int, token []byte, err error) {
-	if atEOF && len(data) == 0 {
-		return 0, nil, nil
-	}
-	return 1, data[0:1], nil
-}
-
-var errorRune = []byte(string(utf8.RuneError))
-
-// ScanRunes is a split function for a Scanner that returns each
-// UTF-8-encoded rune as a token. The sequence of runes returned is
-// equivalent to that from a range loop over the input as a string, which
-// means that erroneous UTF-8 encodings translate to U+FFFD = "\xef\xbf\xbd".
-// Because of the Scan interface, this makes it impossible for the client to
-// distinguish correctly encoded replacement runes from encoding errors.
-func ScanRunes(data []byte, atEOF bool) (advance int, token []byte, err error) {
-	if atEOF && len(data) == 0 {
-		return 0, nil, nil
-	}
-
-	// Fast path 1: ASCII.
-	if data[0] < utf8.RuneSelf {
-		return 1, data[0:1], nil
-	}
-
-	// Fast path 2: Correct UTF-8 decode without error.
-	_, width := utf8.DecodeRune(data)
-	if width > 1 {
-		// It's a valid encoding. Width cannot be one for a correctly encoded
-		// non-ASCII rune.
-		return width, data[0:width], nil
-	}
-
-	// We know it's an error: we have width==1 and implicitly r==utf8.RuneError.
-	// Is the error because there wasn't a full rune to be decoded?
-	// FullRune distinguishes correctly between erroneous and incomplete encodings.
-	if !atEOF && !utf8.FullRune(data) {
-		// Incomplete; get more bytes.
-		return 0, nil, nil
-	}
-
-	// We have a real UTF-8 encoding error. Return a properly encoded error rune
-	// but advance only one byte. This matches the behavior of a range loop over
-	// an incorrectly encoded string.
-	return 1, errorRune, nil
-}
-
-// dropCR drops a terminal \r from the data.
-func dropCR(data []byte) []byte {
-	if len(data) > 0 && data[len(data)-1] == '\r' {
-		return data[0 : len(data)-1]
-	}
-	return data
-}
-
-// ScanLines is a split function for a Scanner that returns each line of
-// text, stripped of any trailing end-of-line marker. The returned line may
-// be empty. The end-of-line marker is one optional carriage return followed
-// by one mandatory newline. In regular expression notation, it is `\r?\n`.
-// The last non-empty line of input will be returned even if it has no
-// newline.
-func ScanLines(data []byte, atEOF bool) (advance int, token []byte, err error) {
-	if atEOF && len(data) == 0 {
-		return 0, nil, nil
-	}
-	if i := bytes.IndexByte(data, '\n'); i >= 0 {
-		// We have a full newline-terminated line.
-		return i + 1, dropCR(data[0:i]), nil
-	}
-	// If we're at EOF, we have a final, non-terminated line. Return it.
-	if atEOF {
-		return len(data), dropCR(data), nil
-	}
-	// Request more data.
-	return 0, nil, nil
-}
-
-// isSpace reports whether the character is a Unicode white space character.
-// We avoid dependency on the unicode package, but check validity of the implementation
-// in the tests.
-func isSpace(r rune) bool {
-	if r <= '\u00FF' {
-		// Obvious ASCII ones: \t through \r plus space. Plus two Latin-1 oddballs.
-		switch r {
-		case ' ', '\t', '\n', '\v', '\f', '\r':
-			return true
-		case '\u0085', '\u00A0':
-			return true
-		}
-		return false
-	}
-	// High-valued ones.
-	if '\u2000' <= r && r <= '\u200a' {
-		return true
-	}
-	switch r {
-	case '\u1680', '\u2028', '\u2029', '\u202f', '\u205f', '\u3000':
-		return true
-	}
-	return false
-}
-
-// ScanWords is a split function for a Scanner that returns each
-// space-separated word of text, with surrounding spaces deleted. It will
-// never return an empty string. The definition of space is set by
-// unicode.IsSpace.
-func ScanWords(data []byte, atEOF bool) (advance int, token []byte, err error) {
-	// Skip leading spaces.
-	start := 0
-	for width := 0; start < len(data); start += width {
-		var r rune
-		r, width = utf8.DecodeRune(data[start:])
-		if !isSpace(r) {
-			break
-		}
-	}
-	if atEOF && len(data) == 0 {
-		return 0, nil, nil
-	}
-	// Scan until space, marking end of word.
-	for width, i := 0, start; i < len(data); i += width {
-		var r rune
-		r, width = utf8.DecodeRune(data[i:])
-		if isSpace(r) {
-			return i + width, data[start:i], nil
-		}
-	}
-	// If we're at EOF, we have a final, non-empty, non-terminated word. Return it.
-	if atEOF && len(data) > start {
-		return len(data), data[start:], nil
-	}
-	// Request more data.
-	return 0, nil, nil
-}
diff --git a/src/pkg/bufio/scan_test.go b/src/pkg/bufio/scan_test.go
deleted file mode 100644
index 0db7cad..0000000
--- a/src/pkg/bufio/scan_test.go
+++ /dev/null
@@ -1,406 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package bufio_test
-
-import (
-	. "bufio"
-	"bytes"
-	"errors"
-	"io"
-	"strings"
-	"testing"
-	"unicode"
-	"unicode/utf8"
-)
-
-// Test white space table matches the Unicode definition.
-func TestSpace(t *testing.T) {
-	for r := rune(0); r <= utf8.MaxRune; r++ {
-		if IsSpace(r) != unicode.IsSpace(r) {
-			t.Fatalf("white space property disagrees: %#U should be %t", r, unicode.IsSpace(r))
-		}
-	}
-}
-
-var scanTests = []string{
-	"",
-	"a",
-	"¼",
-	"☹",
-	"\x81",   // UTF-8 error
-	"\uFFFD", // correctly encoded RuneError
-	"abcdefgh",
-	"abc def\n\t\tgh    ",
-	"abc¼☹\x81\uFFFD日本語\x82abc",
-}
-
-func TestScanByte(t *testing.T) {
-	for n, test := range scanTests {
-		buf := strings.NewReader(test)
-		s := NewScanner(buf)
-		s.Split(ScanBytes)
-		var i int
-		for i = 0; s.Scan(); i++ {
-			if b := s.Bytes(); len(b) != 1 || b[0] != test[i] {
-				t.Errorf("#%d: %d: expected %q got %q", n, i, test, b)
-			}
-		}
-		if i != len(test) {
-			t.Errorf("#%d: termination expected at %d; got %d", n, len(test), i)
-		}
-		err := s.Err()
-		if err != nil {
-			t.Errorf("#%d: %v", n, err)
-		}
-	}
-}
-
-// Test that the rune splitter returns same sequence of runes (not bytes) as for range string.
-func TestScanRune(t *testing.T) {
-	for n, test := range scanTests {
-		buf := strings.NewReader(test)
-		s := NewScanner(buf)
-		s.Split(ScanRunes)
-		var i, runeCount int
-		var expect rune
-		// Use a string range loop to validate the sequence of runes.
-		for i, expect = range string(test) {
-			if !s.Scan() {
-				break
-			}
-			runeCount++
-			got, _ := utf8.DecodeRune(s.Bytes())
-			if got != expect {
-				t.Errorf("#%d: %d: expected %q got %q", n, i, expect, got)
-			}
-		}
-		if s.Scan() {
-			t.Errorf("#%d: scan ran too long, got %q", n, s.Text())
-		}
-		testRuneCount := utf8.RuneCountInString(test)
-		if runeCount != testRuneCount {
-			t.Errorf("#%d: termination expected at %d; got %d", n, testRuneCount, runeCount)
-		}
-		err := s.Err()
-		if err != nil {
-			t.Errorf("#%d: %v", n, err)
-		}
-	}
-}
-
-var wordScanTests = []string{
-	"",
-	" ",
-	"\n",
-	"a",
-	" a ",
-	"abc def",
-	" abc def ",
-	" abc\tdef\nghi\rjkl\fmno\vpqr\u0085stu\u00a0\n",
-}
-
-// Test that the word splitter returns the same data as strings.Fields.
-func TestScanWords(t *testing.T) {
-	for n, test := range wordScanTests {
-		buf := strings.NewReader(test)
-		s := NewScanner(buf)
-		s.Split(ScanWords)
-		words := strings.Fields(test)
-		var wordCount int
-		for wordCount = 0; wordCount < len(words); wordCount++ {
-			if !s.Scan() {
-				break
-			}
-			got := s.Text()
-			if got != words[wordCount] {
-				t.Errorf("#%d: %d: expected %q got %q", n, wordCount, words[wordCount], got)
-			}
-		}
-		if s.Scan() {
-			t.Errorf("#%d: scan ran too long, got %q", n, s.Text())
-		}
-		if wordCount != len(words) {
-			t.Errorf("#%d: termination expected at %d; got %d", n, len(words), wordCount)
-		}
-		err := s.Err()
-		if err != nil {
-			t.Errorf("#%d: %v", n, err)
-		}
-	}
-}
-
-// slowReader is a reader that returns only a few bytes at a time, to test the incremental
-// reads in Scanner.Scan.
-type slowReader struct {
-	max int
-	buf io.Reader
-}
-
-func (sr *slowReader) Read(p []byte) (n int, err error) {
-	if len(p) > sr.max {
-		p = p[0:sr.max]
-	}
-	return sr.buf.Read(p)
-}
-
-// genLine writes to buf a predictable but non-trivial line of text of length
-// n, including the terminal newline and an occasional carriage return.
-// If addNewline is false, the \r and \n are not emitted.
-func genLine(buf *bytes.Buffer, lineNum, n int, addNewline bool) {
-	buf.Reset()
-	doCR := lineNum%5 == 0
-	if doCR {
-		n--
-	}
-	for i := 0; i < n-1; i++ { // Stop early for \n.
-		c := 'a' + byte(lineNum+i)
-		if c == '\n' || c == '\r' { // Don't confuse us.
-			c = 'N'
-		}
-		buf.WriteByte(c)
-	}
-	if addNewline {
-		if doCR {
-			buf.WriteByte('\r')
-		}
-		buf.WriteByte('\n')
-	}
-	return
-}
-
-// Test the line splitter, including some carriage returns but no long lines.
-func TestScanLongLines(t *testing.T) {
-	const smallMaxTokenSize = 256 // Much smaller for more efficient testing.
-	// Build a buffer of lots of line lengths up to but not exceeding smallMaxTokenSize.
-	tmp := new(bytes.Buffer)
-	buf := new(bytes.Buffer)
-	lineNum := 0
-	j := 0
-	for i := 0; i < 2*smallMaxTokenSize; i++ {
-		genLine(tmp, lineNum, j, true)
-		if j < smallMaxTokenSize {
-			j++
-		} else {
-			j--
-		}
-		buf.Write(tmp.Bytes())
-		lineNum++
-	}
-	s := NewScanner(&slowReader{1, buf})
-	s.Split(ScanLines)
-	s.MaxTokenSize(smallMaxTokenSize)
-	j = 0
-	for lineNum := 0; s.Scan(); lineNum++ {
-		genLine(tmp, lineNum, j, false)
-		if j < smallMaxTokenSize {
-			j++
-		} else {
-			j--
-		}
-		line := tmp.String() // We use the string-valued token here, for variety.
-		if s.Text() != line {
-			t.Errorf("%d: bad line: %d %d\n%.100q\n%.100q\n", lineNum, len(s.Bytes()), len(line), s.Text(), line)
-		}
-	}
-	err := s.Err()
-	if err != nil {
-		t.Fatal(err)
-	}
-}
-
-// Test that the line splitter errors out on a long line.
-func TestScanLineTooLong(t *testing.T) {
-	const smallMaxTokenSize = 256 // Much smaller for more efficient testing.
-	// Build a buffer of lots of line lengths up to but not exceeding smallMaxTokenSize.
-	tmp := new(bytes.Buffer)
-	buf := new(bytes.Buffer)
-	lineNum := 0
-	j := 0
-	for i := 0; i < 2*smallMaxTokenSize; i++ {
-		genLine(tmp, lineNum, j, true)
-		j++
-		buf.Write(tmp.Bytes())
-		lineNum++
-	}
-	s := NewScanner(&slowReader{3, buf})
-	s.Split(ScanLines)
-	s.MaxTokenSize(smallMaxTokenSize)
-	j = 0
-	for lineNum := 0; s.Scan(); lineNum++ {
-		genLine(tmp, lineNum, j, false)
-		if j < smallMaxTokenSize {
-			j++
-		} else {
-			j--
-		}
-		line := tmp.Bytes()
-		if !bytes.Equal(s.Bytes(), line) {
-			t.Errorf("%d: bad line: %d %d\n%.100q\n%.100q\n", lineNum, len(s.Bytes()), len(line), s.Bytes(), line)
-		}
-	}
-	err := s.Err()
-	if err != ErrTooLong {
-		t.Fatalf("expected ErrTooLong; got %s", err)
-	}
-}
-
-// Test that the line splitter handles a final line without a newline.
-func testNoNewline(text string, lines []string, t *testing.T) {
-	buf := strings.NewReader(text)
-	s := NewScanner(&slowReader{7, buf})
-	s.Split(ScanLines)
-	for lineNum := 0; s.Scan(); lineNum++ {
-		line := lines[lineNum]
-		if s.Text() != line {
-			t.Errorf("%d: bad line: %d %d\n%.100q\n%.100q\n", lineNum, len(s.Bytes()), len(line), s.Bytes(), line)
-		}
-	}
-	err := s.Err()
-	if err != nil {
-		t.Fatal(err)
-	}
-}
-
-var noNewlineLines = []string{
-	"abcdefghijklmn\nopqrstuvwxyz",
-}
-
-// Test that the line splitter handles a final line without a newline.
-func TestScanLineNoNewline(t *testing.T) {
-	const text = "abcdefghijklmn\nopqrstuvwxyz"
-	lines := []string{
-		"abcdefghijklmn",
-		"opqrstuvwxyz",
-	}
-	testNoNewline(text, lines, t)
-}
-
-// Test that the line splitter handles a final line with a carriage return but no newline.
-func TestScanLineReturnButNoNewline(t *testing.T) {
-	const text = "abcdefghijklmn\nopqrstuvwxyz\r"
-	lines := []string{
-		"abcdefghijklmn",
-		"opqrstuvwxyz",
-	}
-	testNoNewline(text, lines, t)
-}
-
-// Test that the line splitter handles a final empty line.
-func TestScanLineEmptyFinalLine(t *testing.T) {
-	const text = "abcdefghijklmn\nopqrstuvwxyz\n\n"
-	lines := []string{
-		"abcdefghijklmn",
-		"opqrstuvwxyz",
-		"",
-	}
-	testNoNewline(text, lines, t)
-}
-
-// Test that the line splitter handles a final empty line with a carriage return but no newline.
-func TestScanLineEmptyFinalLineWithCR(t *testing.T) {
-	const text = "abcdefghijklmn\nopqrstuvwxyz\n\r"
-	lines := []string{
-		"abcdefghijklmn",
-		"opqrstuvwxyz",
-		"",
-	}
-	testNoNewline(text, lines, t)
-}
-
-var testError = errors.New("testError")
-
-// Test the correct error is returned when the split function errors out.
-func TestSplitError(t *testing.T) {
-	// Create a split function that delivers a little data, then a predictable error.
-	numSplits := 0
-	const okCount = 7
-	errorSplit := func(data []byte, atEOF bool) (advance int, token []byte, err error) {
-		if atEOF {
-			panic("didn't get enough data")
-		}
-		if numSplits >= okCount {
-			return 0, nil, testError
-		}
-		numSplits++
-		return 1, data[0:1], nil
-	}
-	// Read the data.
-	const text = "abcdefghijklmnopqrstuvwxyz"
-	buf := strings.NewReader(text)
-	s := NewScanner(&slowReader{1, buf})
-	s.Split(errorSplit)
-	var i int
-	for i = 0; s.Scan(); i++ {
-		if len(s.Bytes()) != 1 || text[i] != s.Bytes()[0] {
-			t.Errorf("#%d: expected %q got %q", i, text[i], s.Bytes()[0])
-		}
-	}
-	// Check correct termination location and error.
-	if i != okCount {
-		t.Errorf("unexpected termination; expected %d tokens got %d", okCount, i)
-	}
-	err := s.Err()
-	if err != testError {
-		t.Fatalf("expected %q got %v", testError, err)
-	}
-}
-
-// Test that an EOF is overridden by a user-generated scan error.
-func TestErrAtEOF(t *testing.T) {
-	s := NewScanner(strings.NewReader("1 2 33"))
-	// This spitter will fail on last entry, after s.err==EOF.
-	split := func(data []byte, atEOF bool) (advance int, token []byte, err error) {
-		advance, token, err = ScanWords(data, atEOF)
-		if len(token) > 1 {
-			if s.ErrOrEOF() != io.EOF {
-				t.Fatal("not testing EOF")
-			}
-			err = testError
-		}
-		return
-	}
-	s.Split(split)
-	for s.Scan() {
-	}
-	if s.Err() != testError {
-		t.Fatal("wrong error:", s.Err())
-	}
-}
-
-// Test for issue 5268.
-type alwaysError struct{}
-
-func (alwaysError) Read(p []byte) (int, error) {
-	return 0, io.ErrUnexpectedEOF
-}
-
-func TestNonEOFWithEmptyRead(t *testing.T) {
-	scanner := NewScanner(alwaysError{})
-	for scanner.Scan() {
-		t.Fatal("read should fail")
-	}
-	err := scanner.Err()
-	if err != io.ErrUnexpectedEOF {
-		t.Errorf("unexpected error: %v", err)
-	}
-}
-
-// Test that Scan finishes if we have endless empty reads.
-type endlessZeros struct{}
-
-func (endlessZeros) Read(p []byte) (int, error) {
-	return 0, nil
-}
-
-func TestBadReader(t *testing.T) {
-	scanner := NewScanner(endlessZeros{})
-	for scanner.Scan() {
-		t.Fatal("read should fail")
-	}
-	err := scanner.Err()
-	if err != io.ErrNoProgress {
-		t.Errorf("unexpected error: %v", err)
-	}
-}
diff --git a/src/pkg/bytes/bytes.go b/src/pkg/bytes/bytes.go
deleted file mode 100644
index 0c53e4c..0000000
--- a/src/pkg/bytes/bytes.go
+++ /dev/null
@@ -1,697 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package bytes implements functions for the manipulation of byte slices.
-// It is analogous to the facilities of the strings package.
-package bytes
-
-import (
-	"unicode"
-	"unicode/utf8"
-)
-
-func equalPortable(a, b []byte) bool {
-	if len(a) != len(b) {
-		return false
-	}
-	for i, c := range a {
-		if c != b[i] {
-			return false
-		}
-	}
-	return true
-}
-
-// explode splits s into a slice of UTF-8 sequences, one per Unicode character (still slices of bytes),
-// up to a maximum of n byte slices. Invalid UTF-8 sequences are chopped into individual bytes.
-func explode(s []byte, n int) [][]byte {
-	if n <= 0 {
-		n = len(s)
-	}
-	a := make([][]byte, n)
-	var size int
-	na := 0
-	for len(s) > 0 {
-		if na+1 >= n {
-			a[na] = s
-			na++
-			break
-		}
-		_, size = utf8.DecodeRune(s)
-		a[na] = s[0:size]
-		s = s[size:]
-		na++
-	}
-	return a[0:na]
-}
-
-// Count counts the number of non-overlapping instances of sep in s.
-func Count(s, sep []byte) int {
-	n := len(sep)
-	if n == 0 {
-		return utf8.RuneCount(s) + 1
-	}
-	if n > len(s) {
-		return 0
-	}
-	count := 0
-	c := sep[0]
-	i := 0
-	t := s[:len(s)-n+1]
-	for i < len(t) {
-		if t[i] != c {
-			o := IndexByte(t[i:], c)
-			if o < 0 {
-				break
-			}
-			i += o
-		}
-		if n == 1 || Equal(s[i:i+n], sep) {
-			count++
-			i += n
-			continue
-		}
-		i++
-	}
-	return count
-}
-
-// Contains reports whether subslice is within b.
-func Contains(b, subslice []byte) bool {
-	return Index(b, subslice) != -1
-}
-
-// Index returns the index of the first instance of sep in s, or -1 if sep is not present in s.
-func Index(s, sep []byte) int {
-	n := len(sep)
-	if n == 0 {
-		return 0
-	}
-	if n > len(s) {
-		return -1
-	}
-	c := sep[0]
-	if n == 1 {
-		return IndexByte(s, c)
-	}
-	i := 0
-	t := s[:len(s)-n+1]
-	for i < len(t) {
-		if t[i] != c {
-			o := IndexByte(t[i:], c)
-			if o < 0 {
-				break
-			}
-			i += o
-		}
-		if Equal(s[i:i+n], sep) {
-			return i
-		}
-		i++
-	}
-	return -1
-}
-
-func indexBytePortable(s []byte, c byte) int {
-	for i, b := range s {
-		if b == c {
-			return i
-		}
-	}
-	return -1
-}
-
-// LastIndex returns the index of the last instance of sep in s, or -1 if sep is not present in s.
-func LastIndex(s, sep []byte) int {
-	n := len(sep)
-	if n == 0 {
-		return len(s)
-	}
-	c := sep[0]
-	for i := len(s) - n; i >= 0; i-- {
-		if s[i] == c && (n == 1 || Equal(s[i:i+n], sep)) {
-			return i
-		}
-	}
-	return -1
-}
-
-// IndexRune interprets s as a sequence of UTF-8-encoded Unicode code points.
-// It returns the byte index of the first occurrence in s of the given rune.
-// It returns -1 if rune is not present in s.
-func IndexRune(s []byte, r rune) int {
-	for i := 0; i < len(s); {
-		r1, size := utf8.DecodeRune(s[i:])
-		if r == r1 {
-			return i
-		}
-		i += size
-	}
-	return -1
-}
-
-// IndexAny interprets s as a sequence of UTF-8-encoded Unicode code points.
-// It returns the byte index of the first occurrence in s of any of the Unicode
-// code points in chars.  It returns -1 if chars is empty or if there is no code
-// point in common.
-func IndexAny(s []byte, chars string) int {
-	if len(chars) > 0 {
-		var r rune
-		var width int
-		for i := 0; i < len(s); i += width {
-			r = rune(s[i])
-			if r < utf8.RuneSelf {
-				width = 1
-			} else {
-				r, width = utf8.DecodeRune(s[i:])
-			}
-			for _, ch := range chars {
-				if r == ch {
-					return i
-				}
-			}
-		}
-	}
-	return -1
-}
-
-// LastIndexAny interprets s as a sequence of UTF-8-encoded Unicode code
-// points.  It returns the byte index of the last occurrence in s of any of
-// the Unicode code points in chars.  It returns -1 if chars is empty or if
-// there is no code point in common.
-func LastIndexAny(s []byte, chars string) int {
-	if len(chars) > 0 {
-		for i := len(s); i > 0; {
-			r, size := utf8.DecodeLastRune(s[0:i])
-			i -= size
-			for _, ch := range chars {
-				if r == ch {
-					return i
-				}
-			}
-		}
-	}
-	return -1
-}
-
-// Generic split: splits after each instance of sep,
-// including sepSave bytes of sep in the subslices.
-func genSplit(s, sep []byte, sepSave, n int) [][]byte {
-	if n == 0 {
-		return nil
-	}
-	if len(sep) == 0 {
-		return explode(s, n)
-	}
-	if n < 0 {
-		n = Count(s, sep) + 1
-	}
-	c := sep[0]
-	start := 0
-	a := make([][]byte, n)
-	na := 0
-	for i := 0; i+len(sep) <= len(s) && na+1 < n; i++ {
-		if s[i] == c && (len(sep) == 1 || Equal(s[i:i+len(sep)], sep)) {
-			a[na] = s[start : i+sepSave]
-			na++
-			start = i + len(sep)
-			i += len(sep) - 1
-		}
-	}
-	a[na] = s[start:]
-	return a[0 : na+1]
-}
-
-// SplitN slices s into subslices separated by sep and returns a slice of
-// the subslices between those separators.
-// If sep is empty, SplitN splits after each UTF-8 sequence.
-// The count determines the number of subslices to return:
-//   n > 0: at most n subslices; the last subslice will be the unsplit remainder.
-//   n == 0: the result is nil (zero subslices)
-//   n < 0: all subslices
-func SplitN(s, sep []byte, n int) [][]byte { return genSplit(s, sep, 0, n) }
-
-// SplitAfterN slices s into subslices after each instance of sep and
-// returns a slice of those subslices.
-// If sep is empty, SplitAfterN splits after each UTF-8 sequence.
-// The count determines the number of subslices to return:
-//   n > 0: at most n subslices; the last subslice will be the unsplit remainder.
-//   n == 0: the result is nil (zero subslices)
-//   n < 0: all subslices
-func SplitAfterN(s, sep []byte, n int) [][]byte {
-	return genSplit(s, sep, len(sep), n)
-}
-
-// Split slices s into all subslices separated by sep and returns a slice of
-// the subslices between those separators.
-// If sep is empty, Split splits after each UTF-8 sequence.
-// It is equivalent to SplitN with a count of -1.
-func Split(s, sep []byte) [][]byte { return genSplit(s, sep, 0, -1) }
-
-// SplitAfter slices s into all subslices after each instance of sep and
-// returns a slice of those subslices.
-// If sep is empty, SplitAfter splits after each UTF-8 sequence.
-// It is equivalent to SplitAfterN with a count of -1.
-func SplitAfter(s, sep []byte) [][]byte {
-	return genSplit(s, sep, len(sep), -1)
-}
-
-// Fields splits the slice s around each instance of one or more consecutive white space
-// characters, returning a slice of subslices of s or an empty list if s contains only white space.
-func Fields(s []byte) [][]byte {
-	return FieldsFunc(s, unicode.IsSpace)
-}
-
-// FieldsFunc interprets s as a sequence of UTF-8-encoded Unicode code points.
-// It splits the slice s at each run of code points c satisfying f(c) and
-// returns a slice of subslices of s.  If all code points in s satisfy f(c), or
-// len(s) == 0, an empty slice is returned.
-func FieldsFunc(s []byte, f func(rune) bool) [][]byte {
-	n := 0
-	inField := false
-	for i := 0; i < len(s); {
-		r, size := utf8.DecodeRune(s[i:])
-		wasInField := inField
-		inField = !f(r)
-		if inField && !wasInField {
-			n++
-		}
-		i += size
-	}
-
-	a := make([][]byte, n)
-	na := 0
-	fieldStart := -1
-	for i := 0; i <= len(s) && na < n; {
-		r, size := utf8.DecodeRune(s[i:])
-		if fieldStart < 0 && size > 0 && !f(r) {
-			fieldStart = i
-			i += size
-			continue
-		}
-		if fieldStart >= 0 && (size == 0 || f(r)) {
-			a[na] = s[fieldStart:i]
-			na++
-			fieldStart = -1
-		}
-		if size == 0 {
-			break
-		}
-		i += size
-	}
-	return a[0:na]
-}
-
-// Join concatenates the elements of s to create a new byte slice. The separator
-// sep is placed between elements in the resulting slice.
-func Join(s [][]byte, sep []byte) []byte {
-	if len(s) == 0 {
-		return []byte{}
-	}
-	if len(s) == 1 {
-		// Just return a copy.
-		return append([]byte(nil), s[0]...)
-	}
-	n := len(sep) * (len(s) - 1)
-	for _, v := range s {
-		n += len(v)
-	}
-
-	b := make([]byte, n)
-	bp := copy(b, s[0])
-	for _, v := range s[1:] {
-		bp += copy(b[bp:], sep)
-		bp += copy(b[bp:], v)
-	}
-	return b
-}
-
-// HasPrefix tests whether the byte slice s begins with prefix.
-func HasPrefix(s, prefix []byte) bool {
-	return len(s) >= len(prefix) && Equal(s[0:len(prefix)], prefix)
-}
-
-// HasSuffix tests whether the byte slice s ends with suffix.
-func HasSuffix(s, suffix []byte) bool {
-	return len(s) >= len(suffix) && Equal(s[len(s)-len(suffix):], suffix)
-}
-
-// Map returns a copy of the byte slice s with all its characters modified
-// according to the mapping function. If mapping returns a negative value, the character is
-// dropped from the string with no replacement.  The characters in s and the
-// output are interpreted as UTF-8-encoded Unicode code points.
-func Map(mapping func(r rune) rune, s []byte) []byte {
-	// In the worst case, the slice can grow when mapped, making
-	// things unpleasant.  But it's so rare we barge in assuming it's
-	// fine.  It could also shrink but that falls out naturally.
-	maxbytes := len(s) // length of b
-	nbytes := 0        // number of bytes encoded in b
-	b := make([]byte, maxbytes)
-	for i := 0; i < len(s); {
-		wid := 1
-		r := rune(s[i])
-		if r >= utf8.RuneSelf {
-			r, wid = utf8.DecodeRune(s[i:])
-		}
-		r = mapping(r)
-		if r >= 0 {
-			rl := utf8.RuneLen(r)
-			if rl < 0 {
-				rl = len(string(utf8.RuneError))
-			}
-			if nbytes+rl > maxbytes {
-				// Grow the buffer.
-				maxbytes = maxbytes*2 + utf8.UTFMax
-				nb := make([]byte, maxbytes)
-				copy(nb, b[0:nbytes])
-				b = nb
-			}
-			nbytes += utf8.EncodeRune(b[nbytes:maxbytes], r)
-		}
-		i += wid
-	}
-	return b[0:nbytes]
-}
-
-// Repeat returns a new byte slice consisting of count copies of b.
-func Repeat(b []byte, count int) []byte {
-	nb := make([]byte, len(b)*count)
-	bp := 0
-	for i := 0; i < count; i++ {
-		bp += copy(nb[bp:], b)
-	}
-	return nb
-}
-
-// ToUpper returns a copy of the byte slice s with all Unicode letters mapped to their upper case.
-func ToUpper(s []byte) []byte { return Map(unicode.ToUpper, s) }
-
-// ToLower returns a copy of the byte slice s with all Unicode letters mapped to their lower case.
-func ToLower(s []byte) []byte { return Map(unicode.ToLower, s) }
-
-// ToTitle returns a copy of the byte slice s with all Unicode letters mapped to their title case.
-func ToTitle(s []byte) []byte { return Map(unicode.ToTitle, s) }
-
-// ToUpperSpecial returns a copy of the byte slice s with all Unicode letters mapped to their
-// upper case, giving priority to the special casing rules.
-func ToUpperSpecial(_case unicode.SpecialCase, s []byte) []byte {
-	return Map(func(r rune) rune { return _case.ToUpper(r) }, s)
-}
-
-// ToLowerSpecial returns a copy of the byte slice s with all Unicode letters mapped to their
-// lower case, giving priority to the special casing rules.
-func ToLowerSpecial(_case unicode.SpecialCase, s []byte) []byte {
-	return Map(func(r rune) rune { return _case.ToLower(r) }, s)
-}
-
-// ToTitleSpecial returns a copy of the byte slice s with all Unicode letters mapped to their
-// title case, giving priority to the special casing rules.
-func ToTitleSpecial(_case unicode.SpecialCase, s []byte) []byte {
-	return Map(func(r rune) rune { return _case.ToTitle(r) }, s)
-}
-
-// isSeparator reports whether the rune could mark a word boundary.
-// TODO: update when package unicode captures more of the properties.
-func isSeparator(r rune) bool {
-	// ASCII alphanumerics and underscore are not separators
-	if r <= 0x7F {
-		switch {
-		case '0' <= r && r <= '9':
-			return false
-		case 'a' <= r && r <= 'z':
-			return false
-		case 'A' <= r && r <= 'Z':
-			return false
-		case r == '_':
-			return false
-		}
-		return true
-	}
-	// Letters and digits are not separators
-	if unicode.IsLetter(r) || unicode.IsDigit(r) {
-		return false
-	}
-	// Otherwise, all we can do for now is treat spaces as separators.
-	return unicode.IsSpace(r)
-}
-
-// Title returns a copy of s with all Unicode letters that begin words
-// mapped to their title case.
-//
-// BUG: The rule Title uses for word boundaries does not handle Unicode punctuation properly.
-func Title(s []byte) []byte {
-	// Use a closure here to remember state.
-	// Hackish but effective. Depends on Map scanning in order and calling
-	// the closure once per rune.
-	prev := ' '
-	return Map(
-		func(r rune) rune {
-			if isSeparator(prev) {
-				prev = r
-				return unicode.ToTitle(r)
-			}
-			prev = r
-			return r
-		},
-		s)
-}
-
-// TrimLeftFunc returns a subslice of s by slicing off all leading UTF-8-encoded
-// Unicode code points c that satisfy f(c).
-func TrimLeftFunc(s []byte, f func(r rune) bool) []byte {
-	i := indexFunc(s, f, false)
-	if i == -1 {
-		return nil
-	}
-	return s[i:]
-}
-
-// TrimRightFunc returns a subslice of s by slicing off all trailing UTF-8
-// encoded Unicode code points c that satisfy f(c).
-func TrimRightFunc(s []byte, f func(r rune) bool) []byte {
-	i := lastIndexFunc(s, f, false)
-	if i >= 0 && s[i] >= utf8.RuneSelf {
-		_, wid := utf8.DecodeRune(s[i:])
-		i += wid
-	} else {
-		i++
-	}
-	return s[0:i]
-}
-
-// TrimFunc returns a subslice of s by slicing off all leading and trailing
-// UTF-8-encoded Unicode code points c that satisfy f(c).
-func TrimFunc(s []byte, f func(r rune) bool) []byte {
-	return TrimRightFunc(TrimLeftFunc(s, f), f)
-}
-
-// TrimPrefix returns s without the provided leading prefix string.
-// If s doesn't start with prefix, s is returned unchanged.
-func TrimPrefix(s, prefix []byte) []byte {
-	if HasPrefix(s, prefix) {
-		return s[len(prefix):]
-	}
-	return s
-}
-
-// TrimSuffix returns s without the provided trailing suffix string.
-// If s doesn't end with suffix, s is returned unchanged.
-func TrimSuffix(s, suffix []byte) []byte {
-	if HasSuffix(s, suffix) {
-		return s[:len(s)-len(suffix)]
-	}
-	return s
-}
-
-// IndexFunc interprets s as a sequence of UTF-8-encoded Unicode code points.
-// It returns the byte index in s of the first Unicode
-// code point satisfying f(c), or -1 if none do.
-func IndexFunc(s []byte, f func(r rune) bool) int {
-	return indexFunc(s, f, true)
-}
-
-// LastIndexFunc interprets s as a sequence of UTF-8-encoded Unicode code points.
-// It returns the byte index in s of the last Unicode
-// code point satisfying f(c), or -1 if none do.
-func LastIndexFunc(s []byte, f func(r rune) bool) int {
-	return lastIndexFunc(s, f, true)
-}
-
-// indexFunc is the same as IndexFunc except that if
-// truth==false, the sense of the predicate function is
-// inverted.
-func indexFunc(s []byte, f func(r rune) bool, truth bool) int {
-	start := 0
-	for start < len(s) {
-		wid := 1
-		r := rune(s[start])
-		if r >= utf8.RuneSelf {
-			r, wid = utf8.DecodeRune(s[start:])
-		}
-		if f(r) == truth {
-			return start
-		}
-		start += wid
-	}
-	return -1
-}
-
-// lastIndexFunc is the same as LastIndexFunc except that if
-// truth==false, the sense of the predicate function is
-// inverted.
-func lastIndexFunc(s []byte, f func(r rune) bool, truth bool) int {
-	for i := len(s); i > 0; {
-		r, size := rune(s[i-1]), 1
-		if r >= utf8.RuneSelf {
-			r, size = utf8.DecodeLastRune(s[0:i])
-		}
-		i -= size
-		if f(r) == truth {
-			return i
-		}
-	}
-	return -1
-}
-
-func makeCutsetFunc(cutset string) func(r rune) bool {
-	return func(r rune) bool {
-		for _, c := range cutset {
-			if c == r {
-				return true
-			}
-		}
-		return false
-	}
-}
-
-// Trim returns a subslice of s by slicing off all leading and
-// trailing UTF-8-encoded Unicode code points contained in cutset.
-func Trim(s []byte, cutset string) []byte {
-	return TrimFunc(s, makeCutsetFunc(cutset))
-}
-
-// TrimLeft returns a subslice of s by slicing off all leading
-// UTF-8-encoded Unicode code points contained in cutset.
-func TrimLeft(s []byte, cutset string) []byte {
-	return TrimLeftFunc(s, makeCutsetFunc(cutset))
-}
-
-// TrimRight returns a subslice of s by slicing off all trailing
-// UTF-8-encoded Unicode code points that are contained in cutset.
-func TrimRight(s []byte, cutset string) []byte {
-	return TrimRightFunc(s, makeCutsetFunc(cutset))
-}
-
-// TrimSpace returns a subslice of s by slicing off all leading and
-// trailing white space, as defined by Unicode.
-func TrimSpace(s []byte) []byte {
-	return TrimFunc(s, unicode.IsSpace)
-}
-
-// Runes returns a slice of runes (Unicode code points) equivalent to s.
-func Runes(s []byte) []rune {
-	t := make([]rune, utf8.RuneCount(s))
-	i := 0
-	for len(s) > 0 {
-		r, l := utf8.DecodeRune(s)
-		t[i] = r
-		i++
-		s = s[l:]
-	}
-	return t
-}
-
-// Replace returns a copy of the slice s with the first n
-// non-overlapping instances of old replaced by new.
-// If n < 0, there is no limit on the number of replacements.
-func Replace(s, old, new []byte, n int) []byte {
-	m := 0
-	if n != 0 {
-		// Compute number of replacements.
-		m = Count(s, old)
-	}
-	if m == 0 {
-		// Just return a copy.
-		return append([]byte(nil), s...)
-	}
-	if n < 0 || m < n {
-		n = m
-	}
-
-	// Apply replacements to buffer.
-	t := make([]byte, len(s)+n*(len(new)-len(old)))
-	w := 0
-	start := 0
-	for i := 0; i < n; i++ {
-		j := start
-		if len(old) == 0 {
-			if i > 0 {
-				_, wid := utf8.DecodeRune(s[start:])
-				j += wid
-			}
-		} else {
-			j += Index(s[start:], old)
-		}
-		w += copy(t[w:], s[start:j])
-		w += copy(t[w:], new)
-		start = j + len(old)
-	}
-	w += copy(t[w:], s[start:])
-	return t[0:w]
-}
-
-// EqualFold reports whether s and t, interpreted as UTF-8 strings,
-// are equal under Unicode case-folding.
-func EqualFold(s, t []byte) bool {
-	for len(s) != 0 && len(t) != 0 {
-		// Extract first rune from each.
-		var sr, tr rune
-		if s[0] < utf8.RuneSelf {
-			sr, s = rune(s[0]), s[1:]
-		} else {
-			r, size := utf8.DecodeRune(s)
-			sr, s = r, s[size:]
-		}
-		if t[0] < utf8.RuneSelf {
-			tr, t = rune(t[0]), t[1:]
-		} else {
-			r, size := utf8.DecodeRune(t)
-			tr, t = r, t[size:]
-		}
-
-		// If they match, keep going; if not, return false.
-
-		// Easy case.
-		if tr == sr {
-			continue
-		}
-
-		// Make sr < tr to simplify what follows.
-		if tr < sr {
-			tr, sr = sr, tr
-		}
-		// Fast check for ASCII.
-		if tr < utf8.RuneSelf && 'A' <= sr && sr <= 'Z' {
-			// ASCII, and sr is upper case.  tr must be lower case.
-			if tr == sr+'a'-'A' {
-				continue
-			}
-			return false
-		}
-
-		// General case.  SimpleFold(x) returns the next equivalent rune > x
-		// or wraps around to smaller values.
-		r := unicode.SimpleFold(sr)
-		for r != sr && r < tr {
-			r = unicode.SimpleFold(r)
-		}
-		if r == tr {
-			continue
-		}
-		return false
-	}
-
-	// One string is empty.  Are both?
-	return len(s) == len(t)
-}
diff --git a/src/pkg/bytes/bytes.s b/src/pkg/bytes/bytes.s
deleted file mode 100644
index 55103ba..0000000
--- a/src/pkg/bytes/bytes.s
+++ /dev/null
@@ -1,5 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// This file is here just to make the go tool happy.
diff --git a/src/pkg/bytes/bytes_test.go b/src/pkg/bytes/bytes_test.go
deleted file mode 100644
index 394dd7a..0000000
--- a/src/pkg/bytes/bytes_test.go
+++ /dev/null
@@ -1,1234 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package bytes_test
-
-import (
-	. "bytes"
-	"math/rand"
-	"reflect"
-	"testing"
-	"unicode"
-	"unicode/utf8"
-)
-
-func eq(a, b []string) bool {
-	if len(a) != len(b) {
-		return false
-	}
-	for i := 0; i < len(a); i++ {
-		if a[i] != b[i] {
-			return false
-		}
-	}
-	return true
-}
-
-func sliceOfString(s [][]byte) []string {
-	result := make([]string, len(s))
-	for i, v := range s {
-		result[i] = string(v)
-	}
-	return result
-}
-
-// For ease of reading, the test cases use strings that are converted to byte
-// slices before invoking the functions.
-
-var abcd = "abcd"
-var faces = "☺☻☹"
-var commas = "1,2,3,4"
-var dots = "1....2....3....4"
-
-type BinOpTest struct {
-	a string
-	b string
-	i int
-}
-
-var equalTests = []struct {
-	a, b []byte
-	i    int
-}{
-	{[]byte(""), []byte(""), 0},
-	{[]byte("a"), []byte(""), 1},
-	{[]byte(""), []byte("a"), -1},
-	{[]byte("abc"), []byte("abc"), 0},
-	{[]byte("ab"), []byte("abc"), -1},
-	{[]byte("abc"), []byte("ab"), 1},
-	{[]byte("x"), []byte("ab"), 1},
-	{[]byte("ab"), []byte("x"), -1},
-	{[]byte("x"), []byte("a"), 1},
-	{[]byte("b"), []byte("x"), -1},
-	// test runtime·memeq's chunked implementation
-	{[]byte("abcdefgh"), []byte("abcdefgh"), 0},
-	{[]byte("abcdefghi"), []byte("abcdefghi"), 0},
-	{[]byte("abcdefghi"), []byte("abcdefghj"), -1},
-	// nil tests
-	{nil, nil, 0},
-	{[]byte(""), nil, 0},
-	{nil, []byte(""), 0},
-	{[]byte("a"), nil, 1},
-	{nil, []byte("a"), -1},
-}
-
-func TestEqual(t *testing.T) {
-	for _, tt := range compareTests {
-		eql := Equal(tt.a, tt.b)
-		if eql != (tt.i == 0) {
-			t.Errorf(`Equal(%q, %q) = %v`, tt.a, tt.b, eql)
-		}
-		eql = EqualPortable(tt.a, tt.b)
-		if eql != (tt.i == 0) {
-			t.Errorf(`EqualPortable(%q, %q) = %v`, tt.a, tt.b, eql)
-		}
-	}
-}
-
-func TestEqualExhaustive(t *testing.T) {
-	var size = 128
-	if testing.Short() {
-		size = 32
-	}
-	a := make([]byte, size)
-	b := make([]byte, size)
-	b_init := make([]byte, size)
-	// randomish but deterministic data
-	for i := 0; i < size; i++ {
-		a[i] = byte(17 * i)
-		b_init[i] = byte(23*i + 100)
-	}
-
-	for len := 0; len <= size; len++ {
-		for x := 0; x <= size-len; x++ {
-			for y := 0; y <= size-len; y++ {
-				copy(b, b_init)
-				copy(b[y:y+len], a[x:x+len])
-				if !Equal(a[x:x+len], b[y:y+len]) || !Equal(b[y:y+len], a[x:x+len]) {
-					t.Errorf("Equal(%d, %d, %d) = false", len, x, y)
-				}
-			}
-		}
-	}
-}
-
-// make sure Equal returns false for minimally different strings.  The data
-// is all zeros except for a single one in one location.
-func TestNotEqual(t *testing.T) {
-	var size = 128
-	if testing.Short() {
-		size = 32
-	}
-	a := make([]byte, size)
-	b := make([]byte, size)
-
-	for len := 0; len <= size; len++ {
-		for x := 0; x <= size-len; x++ {
-			for y := 0; y <= size-len; y++ {
-				for diffpos := x; diffpos < x+len; diffpos++ {
-					a[diffpos] = 1
-					if Equal(a[x:x+len], b[y:y+len]) || Equal(b[y:y+len], a[x:x+len]) {
-						t.Errorf("NotEqual(%d, %d, %d, %d) = true", len, x, y, diffpos)
-					}
-					a[diffpos] = 0
-				}
-			}
-		}
-	}
-}
-
-var indexTests = []BinOpTest{
-	{"", "", 0},
-	{"", "a", -1},
-	{"", "foo", -1},
-	{"fo", "foo", -1},
-	{"foo", "baz", -1},
-	{"foo", "foo", 0},
-	{"oofofoofooo", "f", 2},
-	{"oofofoofooo", "foo", 4},
-	{"barfoobarfoo", "foo", 3},
-	{"foo", "", 0},
-	{"foo", "o", 1},
-	{"abcABCabc", "A", 3},
-	// cases with one byte strings - test IndexByte and special case in Index()
-	{"", "a", -1},
-	{"x", "a", -1},
-	{"x", "x", 0},
-	{"abc", "a", 0},
-	{"abc", "b", 1},
-	{"abc", "c", 2},
-	{"abc", "x", -1},
-	{"barfoobarfooyyyzzzyyyzzzyyyzzzyyyxxxzzzyyy", "x", 33},
-	{"foofyfoobarfoobar", "y", 4},
-	{"oooooooooooooooooooooo", "r", -1},
-}
-
-var lastIndexTests = []BinOpTest{
-	{"", "", 0},
-	{"", "a", -1},
-	{"", "foo", -1},
-	{"fo", "foo", -1},
-	{"foo", "foo", 0},
-	{"foo", "f", 0},
-	{"oofofoofooo", "f", 7},
-	{"oofofoofooo", "foo", 7},
-	{"barfoobarfoo", "foo", 9},
-	{"foo", "", 3},
-	{"foo", "o", 2},
-	{"abcABCabc", "A", 3},
-	{"abcABCabc", "a", 6},
-}
-
-var indexAnyTests = []BinOpTest{
-	{"", "", -1},
-	{"", "a", -1},
-	{"", "abc", -1},
-	{"a", "", -1},
-	{"a", "a", 0},
-	{"aaa", "a", 0},
-	{"abc", "xyz", -1},
-	{"abc", "xcz", 2},
-	{"ab☺c", "x☺yz", 2},
-	{"aRegExp*", ".(|)*+?^$[]", 7},
-	{dots + dots + dots, " ", -1},
-}
-
-var lastIndexAnyTests = []BinOpTest{
-	{"", "", -1},
-	{"", "a", -1},
-	{"", "abc", -1},
-	{"a", "", -1},
-	{"a", "a", 0},
-	{"aaa", "a", 2},
-	{"abc", "xyz", -1},
-	{"abc", "ab", 1},
-	{"a☺b☻c☹d", "uvw☻xyz", 2 + len("☺")},
-	{"a.RegExp*", ".(|)*+?^$[]", 8},
-	{dots + dots + dots, " ", -1},
-}
-
-var indexRuneTests = []BinOpTest{
-	{"", "a", -1},
-	{"", "☺", -1},
-	{"foo", "☹", -1},
-	{"foo", "o", 1},
-	{"foo☺bar", "☺", 3},
-	{"foo☺☻☹bar", "☹", 9},
-}
-
-// Execute f on each test case.  funcName should be the name of f; it's used
-// in failure reports.
-func runIndexTests(t *testing.T, f func(s, sep []byte) int, funcName string, testCases []BinOpTest) {
-	for _, test := range testCases {
-		a := []byte(test.a)
-		b := []byte(test.b)
-		actual := f(a, b)
-		if actual != test.i {
-			t.Errorf("%s(%q,%q) = %v; want %v", funcName, a, b, actual, test.i)
-		}
-	}
-}
-
-func runIndexAnyTests(t *testing.T, f func(s []byte, chars string) int, funcName string, testCases []BinOpTest) {
-	for _, test := range testCases {
-		a := []byte(test.a)
-		actual := f(a, test.b)
-		if actual != test.i {
-			t.Errorf("%s(%q,%q) = %v; want %v", funcName, a, test.b, actual, test.i)
-		}
-	}
-}
-
-func TestIndex(t *testing.T)     { runIndexTests(t, Index, "Index", indexTests) }
-func TestLastIndex(t *testing.T) { runIndexTests(t, LastIndex, "LastIndex", lastIndexTests) }
-func TestIndexAny(t *testing.T)  { runIndexAnyTests(t, IndexAny, "IndexAny", indexAnyTests) }
-func TestLastIndexAny(t *testing.T) {
-	runIndexAnyTests(t, LastIndexAny, "LastIndexAny", lastIndexAnyTests)
-}
-
-func TestIndexByte(t *testing.T) {
-	for _, tt := range indexTests {
-		if len(tt.b) != 1 {
-			continue
-		}
-		a := []byte(tt.a)
-		b := tt.b[0]
-		pos := IndexByte(a, b)
-		if pos != tt.i {
-			t.Errorf(`IndexByte(%q, '%c') = %v`, tt.a, b, pos)
-		}
-		posp := IndexBytePortable(a, b)
-		if posp != tt.i {
-			t.Errorf(`indexBytePortable(%q, '%c') = %v`, tt.a, b, posp)
-		}
-	}
-}
-
-// test a larger buffer with different sizes and alignments
-func TestIndexByteBig(t *testing.T) {
-	var n = 1024
-	if testing.Short() {
-		n = 128
-	}
-	b := make([]byte, n)
-	for i := 0; i < n; i++ {
-		// different start alignments
-		b1 := b[i:]
-		for j := 0; j < len(b1); j++ {
-			b1[j] = 'x'
-			pos := IndexByte(b1, 'x')
-			if pos != j {
-				t.Errorf("IndexByte(%q, 'x') = %v", b1, pos)
-			}
-			b1[j] = 0
-			pos = IndexByte(b1, 'x')
-			if pos != -1 {
-				t.Errorf("IndexByte(%q, 'x') = %v", b1, pos)
-			}
-		}
-		// different end alignments
-		b1 = b[:i]
-		for j := 0; j < len(b1); j++ {
-			b1[j] = 'x'
-			pos := IndexByte(b1, 'x')
-			if pos != j {
-				t.Errorf("IndexByte(%q, 'x') = %v", b1, pos)
-			}
-			b1[j] = 0
-			pos = IndexByte(b1, 'x')
-			if pos != -1 {
-				t.Errorf("IndexByte(%q, 'x') = %v", b1, pos)
-			}
-		}
-		// different start and end alignments
-		b1 = b[i/2 : n-(i+1)/2]
-		for j := 0; j < len(b1); j++ {
-			b1[j] = 'x'
-			pos := IndexByte(b1, 'x')
-			if pos != j {
-				t.Errorf("IndexByte(%q, 'x') = %v", b1, pos)
-			}
-			b1[j] = 0
-			pos = IndexByte(b1, 'x')
-			if pos != -1 {
-				t.Errorf("IndexByte(%q, 'x') = %v", b1, pos)
-			}
-		}
-	}
-}
-
-func TestIndexRune(t *testing.T) {
-	for _, tt := range indexRuneTests {
-		a := []byte(tt.a)
-		r, _ := utf8.DecodeRuneInString(tt.b)
-		pos := IndexRune(a, r)
-		if pos != tt.i {
-			t.Errorf(`IndexRune(%q, '%c') = %v`, tt.a, r, pos)
-		}
-	}
-}
-
-var bmbuf []byte
-
-func BenchmarkIndexByte32(b *testing.B)          { bmIndexByte(b, IndexByte, 32) }
-func BenchmarkIndexByte4K(b *testing.B)          { bmIndexByte(b, IndexByte, 4<<10) }
-func BenchmarkIndexByte4M(b *testing.B)          { bmIndexByte(b, IndexByte, 4<<20) }
-func BenchmarkIndexByte64M(b *testing.B)         { bmIndexByte(b, IndexByte, 64<<20) }
-func BenchmarkIndexBytePortable32(b *testing.B)  { bmIndexByte(b, IndexBytePortable, 32) }
-func BenchmarkIndexBytePortable4K(b *testing.B)  { bmIndexByte(b, IndexBytePortable, 4<<10) }
-func BenchmarkIndexBytePortable4M(b *testing.B)  { bmIndexByte(b, IndexBytePortable, 4<<20) }
-func BenchmarkIndexBytePortable64M(b *testing.B) { bmIndexByte(b, IndexBytePortable, 64<<20) }
-
-func bmIndexByte(b *testing.B, index func([]byte, byte) int, n int) {
-	if len(bmbuf) < n {
-		bmbuf = make([]byte, n)
-	}
-	b.SetBytes(int64(n))
-	buf := bmbuf[0:n]
-	buf[n-1] = 'x'
-	for i := 0; i < b.N; i++ {
-		j := index(buf, 'x')
-		if j != n-1 {
-			b.Fatal("bad index", j)
-		}
-	}
-	buf[n-1] = '\x00'
-}
-
-func BenchmarkEqual0(b *testing.B) {
-	var buf [4]byte
-	buf1 := buf[0:0]
-	buf2 := buf[1:1]
-	for i := 0; i < b.N; i++ {
-		eq := Equal(buf1, buf2)
-		if !eq {
-			b.Fatal("bad equal")
-		}
-	}
-}
-
-func BenchmarkEqual1(b *testing.B)           { bmEqual(b, Equal, 1) }
-func BenchmarkEqual6(b *testing.B)           { bmEqual(b, Equal, 6) }
-func BenchmarkEqual9(b *testing.B)           { bmEqual(b, Equal, 9) }
-func BenchmarkEqual15(b *testing.B)          { bmEqual(b, Equal, 15) }
-func BenchmarkEqual16(b *testing.B)          { bmEqual(b, Equal, 16) }
-func BenchmarkEqual20(b *testing.B)          { bmEqual(b, Equal, 20) }
-func BenchmarkEqual32(b *testing.B)          { bmEqual(b, Equal, 32) }
-func BenchmarkEqual4K(b *testing.B)          { bmEqual(b, Equal, 4<<10) }
-func BenchmarkEqual4M(b *testing.B)          { bmEqual(b, Equal, 4<<20) }
-func BenchmarkEqual64M(b *testing.B)         { bmEqual(b, Equal, 64<<20) }
-func BenchmarkEqualPort1(b *testing.B)       { bmEqual(b, EqualPortable, 1) }
-func BenchmarkEqualPort6(b *testing.B)       { bmEqual(b, EqualPortable, 6) }
-func BenchmarkEqualPort32(b *testing.B)      { bmEqual(b, EqualPortable, 32) }
-func BenchmarkEqualPort4K(b *testing.B)      { bmEqual(b, EqualPortable, 4<<10) }
-func BenchmarkEqualPortable4M(b *testing.B)  { bmEqual(b, EqualPortable, 4<<20) }
-func BenchmarkEqualPortable64M(b *testing.B) { bmEqual(b, EqualPortable, 64<<20) }
-
-func bmEqual(b *testing.B, equal func([]byte, []byte) bool, n int) {
-	if len(bmbuf) < 2*n {
-		bmbuf = make([]byte, 2*n)
-	}
-	b.SetBytes(int64(n))
-	buf1 := bmbuf[0:n]
-	buf2 := bmbuf[n : 2*n]
-	buf1[n-1] = 'x'
-	buf2[n-1] = 'x'
-	for i := 0; i < b.N; i++ {
-		eq := equal(buf1, buf2)
-		if !eq {
-			b.Fatal("bad equal")
-		}
-	}
-	buf1[n-1] = '\x00'
-	buf2[n-1] = '\x00'
-}
-
-func BenchmarkIndex32(b *testing.B)  { bmIndex(b, Index, 32) }
-func BenchmarkIndex4K(b *testing.B)  { bmIndex(b, Index, 4<<10) }
-func BenchmarkIndex4M(b *testing.B)  { bmIndex(b, Index, 4<<20) }
-func BenchmarkIndex64M(b *testing.B) { bmIndex(b, Index, 64<<20) }
-
-func bmIndex(b *testing.B, index func([]byte, []byte) int, n int) {
-	if len(bmbuf) < n {
-		bmbuf = make([]byte, n)
-	}
-	b.SetBytes(int64(n))
-	buf := bmbuf[0:n]
-	buf[n-1] = 'x'
-	for i := 0; i < b.N; i++ {
-		j := index(buf, buf[n-7:])
-		if j != n-7 {
-			b.Fatal("bad index", j)
-		}
-	}
-	buf[n-1] = '\x00'
-}
-
-func BenchmarkIndexEasy32(b *testing.B)  { bmIndexEasy(b, Index, 32) }
-func BenchmarkIndexEasy4K(b *testing.B)  { bmIndexEasy(b, Index, 4<<10) }
-func BenchmarkIndexEasy4M(b *testing.B)  { bmIndexEasy(b, Index, 4<<20) }
-func BenchmarkIndexEasy64M(b *testing.B) { bmIndexEasy(b, Index, 64<<20) }
-
-func bmIndexEasy(b *testing.B, index func([]byte, []byte) int, n int) {
-	if len(bmbuf) < n {
-		bmbuf = make([]byte, n)
-	}
-	b.SetBytes(int64(n))
-	buf := bmbuf[0:n]
-	buf[n-1] = 'x'
-	buf[n-7] = 'x'
-	for i := 0; i < b.N; i++ {
-		j := index(buf, buf[n-7:])
-		if j != n-7 {
-			b.Fatal("bad index", j)
-		}
-	}
-	buf[n-1] = '\x00'
-	buf[n-7] = '\x00'
-}
-
-func BenchmarkCount32(b *testing.B)  { bmCount(b, Count, 32) }
-func BenchmarkCount4K(b *testing.B)  { bmCount(b, Count, 4<<10) }
-func BenchmarkCount4M(b *testing.B)  { bmCount(b, Count, 4<<20) }
-func BenchmarkCount64M(b *testing.B) { bmCount(b, Count, 64<<20) }
-
-func bmCount(b *testing.B, count func([]byte, []byte) int, n int) {
-	if len(bmbuf) < n {
-		bmbuf = make([]byte, n)
-	}
-	b.SetBytes(int64(n))
-	buf := bmbuf[0:n]
-	buf[n-1] = 'x'
-	for i := 0; i < b.N; i++ {
-		j := count(buf, buf[n-7:])
-		if j != 1 {
-			b.Fatal("bad count", j)
-		}
-	}
-	buf[n-1] = '\x00'
-}
-
-func BenchmarkCountEasy32(b *testing.B)  { bmCountEasy(b, Count, 32) }
-func BenchmarkCountEasy4K(b *testing.B)  { bmCountEasy(b, Count, 4<<10) }
-func BenchmarkCountEasy4M(b *testing.B)  { bmCountEasy(b, Count, 4<<20) }
-func BenchmarkCountEasy64M(b *testing.B) { bmCountEasy(b, Count, 64<<20) }
-
-func bmCountEasy(b *testing.B, count func([]byte, []byte) int, n int) {
-	if len(bmbuf) < n {
-		bmbuf = make([]byte, n)
-	}
-	b.SetBytes(int64(n))
-	buf := bmbuf[0:n]
-	buf[n-1] = 'x'
-	buf[n-7] = 'x'
-	for i := 0; i < b.N; i++ {
-		j := count(buf, buf[n-7:])
-		if j != 1 {
-			b.Fatal("bad count", j)
-		}
-	}
-	buf[n-1] = '\x00'
-	buf[n-7] = '\x00'
-}
-
-type ExplodeTest struct {
-	s string
-	n int
-	a []string
-}
-
-var explodetests = []ExplodeTest{
-	{"", -1, []string{}},
-	{abcd, -1, []string{"a", "b", "c", "d"}},
-	{faces, -1, []string{"☺", "☻", "☹"}},
-	{abcd, 2, []string{"a", "bcd"}},
-}
-
-func TestExplode(t *testing.T) {
-	for _, tt := range explodetests {
-		a := SplitN([]byte(tt.s), nil, tt.n)
-		result := sliceOfString(a)
-		if !eq(result, tt.a) {
-			t.Errorf(`Explode("%s", %d) = %v; want %v`, tt.s, tt.n, result, tt.a)
-			continue
-		}
-		s := Join(a, []byte{})
-		if string(s) != tt.s {
-			t.Errorf(`Join(Explode("%s", %d), "") = "%s"`, tt.s, tt.n, s)
-		}
-	}
-}
-
-type SplitTest struct {
-	s   string
-	sep string
-	n   int
-	a   []string
-}
-
-var splittests = []SplitTest{
-	{abcd, "a", 0, nil},
-	{abcd, "a", -1, []string{"", "bcd"}},
-	{abcd, "z", -1, []string{"abcd"}},
-	{abcd, "", -1, []string{"a", "b", "c", "d"}},
-	{commas, ",", -1, []string{"1", "2", "3", "4"}},
-	{dots, "...", -1, []string{"1", ".2", ".3", ".4"}},
-	{faces, "☹", -1, []string{"☺☻", ""}},
-	{faces, "~", -1, []string{faces}},
-	{faces, "", -1, []string{"☺", "☻", "☹"}},
-	{"1 2 3 4", " ", 3, []string{"1", "2", "3 4"}},
-	{"1 2", " ", 3, []string{"1", "2"}},
-	{"123", "", 2, []string{"1", "23"}},
-	{"123", "", 17, []string{"1", "2", "3"}},
-}
-
-func TestSplit(t *testing.T) {
-	for _, tt := range splittests {
-		a := SplitN([]byte(tt.s), []byte(tt.sep), tt.n)
-		result := sliceOfString(a)
-		if !eq(result, tt.a) {
-			t.Errorf(`Split(%q, %q, %d) = %v; want %v`, tt.s, tt.sep, tt.n, result, tt.a)
-			continue
-		}
-		if tt.n == 0 {
-			continue
-		}
-		s := Join(a, []byte(tt.sep))
-		if string(s) != tt.s {
-			t.Errorf(`Join(Split(%q, %q, %d), %q) = %q`, tt.s, tt.sep, tt.n, tt.sep, s)
-		}
-		if tt.n < 0 {
-			b := Split([]byte(tt.s), []byte(tt.sep))
-			if !reflect.DeepEqual(a, b) {
-				t.Errorf("Split disagrees withSplitN(%q, %q, %d) = %v; want %v", tt.s, tt.sep, tt.n, b, a)
-			}
-		}
-		if len(a) > 0 {
-			in, out := a[0], s
-			if cap(in) == cap(out) && &in[:1][0] == &out[:1][0] {
-				t.Errorf("Join(%#v, %q) didn't copy", a, tt.sep)
-			}
-		}
-	}
-}
-
-var splitaftertests = []SplitTest{
-	{abcd, "a", -1, []string{"a", "bcd"}},
-	{abcd, "z", -1, []string{"abcd"}},
-	{abcd, "", -1, []string{"a", "b", "c", "d"}},
-	{commas, ",", -1, []string{"1,", "2,", "3,", "4"}},
-	{dots, "...", -1, []string{"1...", ".2...", ".3...", ".4"}},
-	{faces, "☹", -1, []string{"☺☻☹", ""}},
-	{faces, "~", -1, []string{faces}},
-	{faces, "", -1, []string{"☺", "☻", "☹"}},
-	{"1 2 3 4", " ", 3, []string{"1 ", "2 ", "3 4"}},
-	{"1 2 3", " ", 3, []string{"1 ", "2 ", "3"}},
-	{"1 2", " ", 3, []string{"1 ", "2"}},
-	{"123", "", 2, []string{"1", "23"}},
-	{"123", "", 17, []string{"1", "2", "3"}},
-}
-
-func TestSplitAfter(t *testing.T) {
-	for _, tt := range splitaftertests {
-		a := SplitAfterN([]byte(tt.s), []byte(tt.sep), tt.n)
-		result := sliceOfString(a)
-		if !eq(result, tt.a) {
-			t.Errorf(`Split(%q, %q, %d) = %v; want %v`, tt.s, tt.sep, tt.n, result, tt.a)
-			continue
-		}
-		s := Join(a, nil)
-		if string(s) != tt.s {
-			t.Errorf(`Join(Split(%q, %q, %d), %q) = %q`, tt.s, tt.sep, tt.n, tt.sep, s)
-		}
-		if tt.n < 0 {
-			b := SplitAfter([]byte(tt.s), []byte(tt.sep))
-			if !reflect.DeepEqual(a, b) {
-				t.Errorf("SplitAfter disagrees withSplitAfterN(%q, %q, %d) = %v; want %v", tt.s, tt.sep, tt.n, b, a)
-			}
-		}
-	}
-}
-
-type FieldsTest struct {
-	s string
-	a []string
-}
-
-var fieldstests = []FieldsTest{
-	{"", []string{}},
-	{" ", []string{}},
-	{" \t ", []string{}},
-	{"  abc  ", []string{"abc"}},
-	{"1 2 3 4", []string{"1", "2", "3", "4"}},
-	{"1  2  3  4", []string{"1", "2", "3", "4"}},
-	{"1\t\t2\t\t3\t4", []string{"1", "2", "3", "4"}},
-	{"1\u20002\u20013\u20024", []string{"1", "2", "3", "4"}},
-	{"\u2000\u2001\u2002", []string{}},
-	{"\n™\t™\n", []string{"™", "™"}},
-	{faces, []string{faces}},
-}
-
-func TestFields(t *testing.T) {
-	for _, tt := range fieldstests {
-		a := Fields([]byte(tt.s))
-		result := sliceOfString(a)
-		if !eq(result, tt.a) {
-			t.Errorf("Fields(%q) = %v; want %v", tt.s, a, tt.a)
-			continue
-		}
-	}
-}
-
-func TestFieldsFunc(t *testing.T) {
-	for _, tt := range fieldstests {
-		a := FieldsFunc([]byte(tt.s), unicode.IsSpace)
-		result := sliceOfString(a)
-		if !eq(result, tt.a) {
-			t.Errorf("FieldsFunc(%q, unicode.IsSpace) = %v; want %v", tt.s, a, tt.a)
-			continue
-		}
-	}
-	pred := func(c rune) bool { return c == 'X' }
-	var fieldsFuncTests = []FieldsTest{
-		{"", []string{}},
-		{"XX", []string{}},
-		{"XXhiXXX", []string{"hi"}},
-		{"aXXbXXXcX", []string{"a", "b", "c"}},
-	}
-	for _, tt := range fieldsFuncTests {
-		a := FieldsFunc([]byte(tt.s), pred)
-		result := sliceOfString(a)
-		if !eq(result, tt.a) {
-			t.Errorf("FieldsFunc(%q) = %v, want %v", tt.s, a, tt.a)
-		}
-	}
-}
-
-// Test case for any function which accepts and returns a byte slice.
-// For ease of creation, we write the byte slices as strings.
-type StringTest struct {
-	in, out string
-}
-
-var upperTests = []StringTest{
-	{"", ""},
-	{"abc", "ABC"},
-	{"AbC123", "ABC123"},
-	{"azAZ09_", "AZAZ09_"},
-	{"\u0250\u0250\u0250\u0250\u0250", "\u2C6F\u2C6F\u2C6F\u2C6F\u2C6F"}, // grows one byte per char
-}
-
-var lowerTests = []StringTest{
-	{"", ""},
-	{"abc", "abc"},
-	{"AbC123", "abc123"},
-	{"azAZ09_", "azaz09_"},
-	{"\u2C6D\u2C6D\u2C6D\u2C6D\u2C6D", "\u0251\u0251\u0251\u0251\u0251"}, // shrinks one byte per char
-}
-
-const space = "\t\v\r\f\n\u0085\u00a0\u2000\u3000"
-
-var trimSpaceTests = []StringTest{
-	{"", ""},
-	{"abc", "abc"},
-	{space + "abc" + space, "abc"},
-	{" ", ""},
-	{" \t\r\n \t\t\r\r\n\n ", ""},
-	{" \t\r\n x\t\t\r\r\n\n ", "x"},
-	{" \u2000\t\r\n x\t\t\r\r\ny\n \u3000", "x\t\t\r\r\ny"},
-	{"1 \t\r\n2", "1 \t\r\n2"},
-	{" x\x80", "x\x80"},
-	{" x\xc0", "x\xc0"},
-	{"x \xc0\xc0 ", "x \xc0\xc0"},
-	{"x \xc0", "x \xc0"},
-	{"x \xc0 ", "x \xc0"},
-	{"x \xc0\xc0 ", "x \xc0\xc0"},
-	{"x ☺\xc0\xc0 ", "x ☺\xc0\xc0"},
-	{"x ☺ ", "x ☺"},
-}
-
-// Execute f on each test case.  funcName should be the name of f; it's used
-// in failure reports.
-func runStringTests(t *testing.T, f func([]byte) []byte, funcName string, testCases []StringTest) {
-	for _, tc := range testCases {
-		actual := string(f([]byte(tc.in)))
-		if actual != tc.out {
-			t.Errorf("%s(%q) = %q; want %q", funcName, tc.in, actual, tc.out)
-		}
-	}
-}
-
-func tenRunes(r rune) string {
-	runes := make([]rune, 10)
-	for i := range runes {
-		runes[i] = r
-	}
-	return string(runes)
-}
-
-// User-defined self-inverse mapping function
-func rot13(r rune) rune {
-	const step = 13
-	if r >= 'a' && r <= 'z' {
-		return ((r - 'a' + step) % 26) + 'a'
-	}
-	if r >= 'A' && r <= 'Z' {
-		return ((r - 'A' + step) % 26) + 'A'
-	}
-	return r
-}
-
-func TestMap(t *testing.T) {
-	// Run a couple of awful growth/shrinkage tests
-	a := tenRunes('a')
-
-	// 1.  Grow.  This triggers two reallocations in Map.
-	maxRune := func(r rune) rune { return unicode.MaxRune }
-	m := Map(maxRune, []byte(a))
-	expect := tenRunes(unicode.MaxRune)
-	if string(m) != expect {
-		t.Errorf("growing: expected %q got %q", expect, m)
-	}
-
-	// 2. Shrink
-	minRune := func(r rune) rune { return 'a' }
-	m = Map(minRune, []byte(tenRunes(unicode.MaxRune)))
-	expect = a
-	if string(m) != expect {
-		t.Errorf("shrinking: expected %q got %q", expect, m)
-	}
-
-	// 3. Rot13
-	m = Map(rot13, []byte("a to zed"))
-	expect = "n gb mrq"
-	if string(m) != expect {
-		t.Errorf("rot13: expected %q got %q", expect, m)
-	}
-
-	// 4. Rot13^2
-	m = Map(rot13, Map(rot13, []byte("a to zed")))
-	expect = "a to zed"
-	if string(m) != expect {
-		t.Errorf("rot13: expected %q got %q", expect, m)
-	}
-
-	// 5. Drop
-	dropNotLatin := func(r rune) rune {
-		if unicode.Is(unicode.Latin, r) {
-			return r
-		}
-		return -1
-	}
-	m = Map(dropNotLatin, []byte("Hello, 세계"))
-	expect = "Hello"
-	if string(m) != expect {
-		t.Errorf("drop: expected %q got %q", expect, m)
-	}
-
-	// 6. Invalid rune
-	invalidRune := func(r rune) rune {
-		return utf8.MaxRune + 1
-	}
-	m = Map(invalidRune, []byte("x"))
-	expect = "\uFFFD"
-	if string(m) != expect {
-		t.Errorf("invalidRune: expected %q got %q", expect, m)
-	}
-}
-
-func TestToUpper(t *testing.T) { runStringTests(t, ToUpper, "ToUpper", upperTests) }
-
-func TestToLower(t *testing.T) { runStringTests(t, ToLower, "ToLower", lowerTests) }
-
-func TestTrimSpace(t *testing.T) { runStringTests(t, TrimSpace, "TrimSpace", trimSpaceTests) }
-
-type RepeatTest struct {
-	in, out string
-	count   int
-}
-
-var RepeatTests = []RepeatTest{
-	{"", "", 0},
-	{"", "", 1},
-	{"", "", 2},
-	{"-", "", 0},
-	{"-", "-", 1},
-	{"-", "----------", 10},
-	{"abc ", "abc abc abc ", 3},
-}
-
-func TestRepeat(t *testing.T) {
-	for _, tt := range RepeatTests {
-		tin := []byte(tt.in)
-		tout := []byte(tt.out)
-		a := Repeat(tin, tt.count)
-		if !Equal(a, tout) {
-			t.Errorf("Repeat(%q, %d) = %q; want %q", tin, tt.count, a, tout)
-			continue
-		}
-	}
-}
-
-func runesEqual(a, b []rune) bool {
-	if len(a) != len(b) {
-		return false
-	}
-	for i, r := range a {
-		if r != b[i] {
-			return false
-		}
-	}
-	return true
-}
-
-type RunesTest struct {
-	in    string
-	out   []rune
-	lossy bool
-}
-
-var RunesTests = []RunesTest{
-	{"", []rune{}, false},
-	{" ", []rune{32}, false},
-	{"ABC", []rune{65, 66, 67}, false},
-	{"abc", []rune{97, 98, 99}, false},
-	{"\u65e5\u672c\u8a9e", []rune{26085, 26412, 35486}, false},
-	{"ab\x80c", []rune{97, 98, 0xFFFD, 99}, true},
-	{"ab\xc0c", []rune{97, 98, 0xFFFD, 99}, true},
-}
-
-func TestRunes(t *testing.T) {
-	for _, tt := range RunesTests {
-		tin := []byte(tt.in)
-		a := Runes(tin)
-		if !runesEqual(a, tt.out) {
-			t.Errorf("Runes(%q) = %v; want %v", tin, a, tt.out)
-			continue
-		}
-		if !tt.lossy {
-			// can only test reassembly if we didn't lose information
-			s := string(a)
-			if s != tt.in {
-				t.Errorf("string(Runes(%q)) = %x; want %x", tin, s, tin)
-			}
-		}
-	}
-}
-
-type TrimTest struct {
-	f            string
-	in, arg, out string
-}
-
-var trimTests = []TrimTest{
-	{"Trim", "abba", "a", "bb"},
-	{"Trim", "abba", "ab", ""},
-	{"TrimLeft", "abba", "ab", ""},
-	{"TrimRight", "abba", "ab", ""},
-	{"TrimLeft", "abba", "a", "bba"},
-	{"TrimRight", "abba", "a", "abb"},
-	{"Trim", "<tag>", "<>", "tag"},
-	{"Trim", "* listitem", " *", "listitem"},
-	{"Trim", `"quote"`, `"`, "quote"},
-	{"Trim", "\u2C6F\u2C6F\u0250\u0250\u2C6F\u2C6F", "\u2C6F", "\u0250\u0250"},
-	//empty string tests
-	{"Trim", "abba", "", "abba"},
-	{"Trim", "", "123", ""},
-	{"Trim", "", "", ""},
-	{"TrimLeft", "abba", "", "abba"},
-	{"TrimLeft", "", "123", ""},
-	{"TrimLeft", "", "", ""},
-	{"TrimRight", "abba", "", "abba"},
-	{"TrimRight", "", "123", ""},
-	{"TrimRight", "", "", ""},
-	{"TrimRight", "☺\xc0", "☺", "☺\xc0"},
-	{"TrimPrefix", "aabb", "a", "abb"},
-	{"TrimPrefix", "aabb", "b", "aabb"},
-	{"TrimSuffix", "aabb", "a", "aabb"},
-	{"TrimSuffix", "aabb", "b", "aab"},
-}
-
-func TestTrim(t *testing.T) {
-	for _, tc := range trimTests {
-		name := tc.f
-		var f func([]byte, string) []byte
-		var fb func([]byte, []byte) []byte
-		switch name {
-		case "Trim":
-			f = Trim
-		case "TrimLeft":
-			f = TrimLeft
-		case "TrimRight":
-			f = TrimRight
-		case "TrimPrefix":
-			fb = TrimPrefix
-		case "TrimSuffix":
-			fb = TrimSuffix
-		default:
-			t.Errorf("Undefined trim function %s", name)
-		}
-		var actual string
-		if f != nil {
-			actual = string(f([]byte(tc.in), tc.arg))
-		} else {
-			actual = string(fb([]byte(tc.in), []byte(tc.arg)))
-		}
-		if actual != tc.out {
-			t.Errorf("%s(%q, %q) = %q; want %q", name, tc.in, tc.arg, actual, tc.out)
-		}
-	}
-}
-
-type predicate struct {
-	f    func(r rune) bool
-	name string
-}
-
-var isSpace = predicate{unicode.IsSpace, "IsSpace"}
-var isDigit = predicate{unicode.IsDigit, "IsDigit"}
-var isUpper = predicate{unicode.IsUpper, "IsUpper"}
-var isValidRune = predicate{
-	func(r rune) bool {
-		return r != utf8.RuneError
-	},
-	"IsValidRune",
-}
-
-type TrimFuncTest struct {
-	f       predicate
-	in, out string
-}
-
-func not(p predicate) predicate {
-	return predicate{
-		func(r rune) bool {
-			return !p.f(r)
-		},
-		"not " + p.name,
-	}
-}
-
-var trimFuncTests = []TrimFuncTest{
-	{isSpace, space + " hello " + space, "hello"},
-	{isDigit, "\u0e50\u0e5212hello34\u0e50\u0e51", "hello"},
-	{isUpper, "\u2C6F\u2C6F\u2C6F\u2C6FABCDhelloEF\u2C6F\u2C6FGH\u2C6F\u2C6F", "hello"},
-	{not(isSpace), "hello" + space + "hello", space},
-	{not(isDigit), "hello\u0e50\u0e521234\u0e50\u0e51helo", "\u0e50\u0e521234\u0e50\u0e51"},
-	{isValidRune, "ab\xc0a\xc0cd", "\xc0a\xc0"},
-	{not(isValidRune), "\xc0a\xc0", "a"},
-}
-
-func TestTrimFunc(t *testing.T) {
-	for _, tc := range trimFuncTests {
-		actual := string(TrimFunc([]byte(tc.in), tc.f.f))
-		if actual != tc.out {
-			t.Errorf("TrimFunc(%q, %q) = %q; want %q", tc.in, tc.f.name, actual, tc.out)
-		}
-	}
-}
-
-type IndexFuncTest struct {
-	in          string
-	f           predicate
-	first, last int
-}
-
-var indexFuncTests = []IndexFuncTest{
-	{"", isValidRune, -1, -1},
-	{"abc", isDigit, -1, -1},
-	{"0123", isDigit, 0, 3},
-	{"a1b", isDigit, 1, 1},
-	{space, isSpace, 0, len(space) - 3}, // last rune in space is 3 bytes
-	{"\u0e50\u0e5212hello34\u0e50\u0e51", isDigit, 0, 18},
-	{"\u2C6F\u2C6F\u2C6F\u2C6FABCDhelloEF\u2C6F\u2C6FGH\u2C6F\u2C6F", isUpper, 0, 34},
-	{"12\u0e50\u0e52hello34\u0e50\u0e51", not(isDigit), 8, 12},
-
-	// tests of invalid UTF-8
-	{"\x801", isDigit, 1, 1},
-	{"\x80abc", isDigit, -1, -1},
-	{"\xc0a\xc0", isValidRune, 1, 1},
-	{"\xc0a\xc0", not(isValidRune), 0, 2},
-	{"\xc0☺\xc0", not(isValidRune), 0, 4},
-	{"\xc0☺\xc0\xc0", not(isValidRune), 0, 5},
-	{"ab\xc0a\xc0cd", not(isValidRune), 2, 4},
-	{"a\xe0\x80cd", not(isValidRune), 1, 2},
-}
-
-func TestIndexFunc(t *testing.T) {
-	for _, tc := range indexFuncTests {
-		first := IndexFunc([]byte(tc.in), tc.f.f)
-		if first != tc.first {
-			t.Errorf("IndexFunc(%q, %s) = %d; want %d", tc.in, tc.f.name, first, tc.first)
-		}
-		last := LastIndexFunc([]byte(tc.in), tc.f.f)
-		if last != tc.last {
-			t.Errorf("LastIndexFunc(%q, %s) = %d; want %d", tc.in, tc.f.name, last, tc.last)
-		}
-	}
-}
-
-type ReplaceTest struct {
-	in       string
-	old, new string
-	n        int
-	out      string
-}
-
-var ReplaceTests = []ReplaceTest{
-	{"hello", "l", "L", 0, "hello"},
-	{"hello", "l", "L", -1, "heLLo"},
-	{"hello", "x", "X", -1, "hello"},
-	{"", "x", "X", -1, ""},
-	{"radar", "r", "<r>", -1, "<r>ada<r>"},
-	{"", "", "<>", -1, "<>"},
-	{"banana", "a", "<>", -1, "b<>n<>n<>"},
-	{"banana", "a", "<>", 1, "b<>nana"},
-	{"banana", "a", "<>", 1000, "b<>n<>n<>"},
-	{"banana", "an", "<>", -1, "b<><>a"},
-	{"banana", "ana", "<>", -1, "b<>na"},
-	{"banana", "", "<>", -1, "<>b<>a<>n<>a<>n<>a<>"},
-	{"banana", "", "<>", 10, "<>b<>a<>n<>a<>n<>a<>"},
-	{"banana", "", "<>", 6, "<>b<>a<>n<>a<>n<>a"},
-	{"banana", "", "<>", 5, "<>b<>a<>n<>a<>na"},
-	{"banana", "", "<>", 1, "<>banana"},
-	{"banana", "a", "a", -1, "banana"},
-	{"banana", "a", "a", 1, "banana"},
-	{"☺☻☹", "", "<>", -1, "<>☺<>☻<>☹<>"},
-}
-
-func TestReplace(t *testing.T) {
-	for _, tt := range ReplaceTests {
-		in := append([]byte(tt.in), "<spare>"...)
-		in = in[:len(tt.in)]
-		out := Replace(in, []byte(tt.old), []byte(tt.new), tt.n)
-		if s := string(out); s != tt.out {
-			t.Errorf("Replace(%q, %q, %q, %d) = %q, want %q", tt.in, tt.old, tt.new, tt.n, s, tt.out)
-		}
-		if cap(in) == cap(out) && &in[:1][0] == &out[:1][0] {
-			t.Errorf("Replace(%q, %q, %q, %d) didn't copy", tt.in, tt.old, tt.new, tt.n)
-		}
-	}
-}
-
-type TitleTest struct {
-	in, out string
-}
-
-var TitleTests = []TitleTest{
-	{"", ""},
-	{"a", "A"},
-	{" aaa aaa aaa ", " Aaa Aaa Aaa "},
-	{" Aaa Aaa Aaa ", " Aaa Aaa Aaa "},
-	{"123a456", "123a456"},
-	{"double-blind", "Double-Blind"},
-	{"ÿøû", "Ÿøû"},
-	{"with_underscore", "With_underscore"},
-	{"unicode \xe2\x80\xa8 line separator", "Unicode \xe2\x80\xa8 Line Separator"},
-}
-
-func TestTitle(t *testing.T) {
-	for _, tt := range TitleTests {
-		if s := string(Title([]byte(tt.in))); s != tt.out {
-			t.Errorf("Title(%q) = %q, want %q", tt.in, s, tt.out)
-		}
-	}
-}
-
-var ToTitleTests = []TitleTest{
-	{"", ""},
-	{"a", "A"},
-	{" aaa aaa aaa ", " AAA AAA AAA "},
-	{" Aaa Aaa Aaa ", " AAA AAA AAA "},
-	{"123a456", "123A456"},
-	{"double-blind", "DOUBLE-BLIND"},
-	{"ÿøû", "ŸØÛ"},
-}
-
-func TestToTitle(t *testing.T) {
-	for _, tt := range ToTitleTests {
-		if s := string(ToTitle([]byte(tt.in))); s != tt.out {
-			t.Errorf("ToTitle(%q) = %q, want %q", tt.in, s, tt.out)
-		}
-	}
-}
-
-var EqualFoldTests = []struct {
-	s, t string
-	out  bool
-}{
-	{"abc", "abc", true},
-	{"ABcd", "ABcd", true},
-	{"123abc", "123ABC", true},
-	{"αβδ", "ΑΒΔ", true},
-	{"abc", "xyz", false},
-	{"abc", "XYZ", false},
-	{"abcdefghijk", "abcdefghijX", false},
-	{"abcdefghijk", "abcdefghij\u212A", true},
-	{"abcdefghijK", "abcdefghij\u212A", true},
-	{"abcdefghijkz", "abcdefghij\u212Ay", false},
-	{"abcdefghijKz", "abcdefghij\u212Ay", false},
-}
-
-func TestEqualFold(t *testing.T) {
-	for _, tt := range EqualFoldTests {
-		if out := EqualFold([]byte(tt.s), []byte(tt.t)); out != tt.out {
-			t.Errorf("EqualFold(%#q, %#q) = %v, want %v", tt.s, tt.t, out, tt.out)
-		}
-		if out := EqualFold([]byte(tt.t), []byte(tt.s)); out != tt.out {
-			t.Errorf("EqualFold(%#q, %#q) = %v, want %v", tt.t, tt.s, out, tt.out)
-		}
-	}
-}
-
-func TestBufferGrowNegative(t *testing.T) {
-	defer func() {
-		if err := recover(); err == nil {
-			t.Fatal("Grow(-1) should have panicked")
-		}
-	}()
-	var b Buffer
-	b.Grow(-1)
-}
-
-func TestBufferTruncateNegative(t *testing.T) {
-	defer func() {
-		if err := recover(); err == nil {
-			t.Fatal("Truncate(-1) should have panicked")
-		}
-	}()
-	var b Buffer
-	b.Truncate(-1)
-}
-
-func TestBufferTruncateOutOfRange(t *testing.T) {
-	defer func() {
-		if err := recover(); err == nil {
-			t.Fatal("Truncate(20) should have panicked")
-		}
-	}()
-	var b Buffer
-	b.Write(make([]byte, 10))
-	b.Truncate(20)
-}
-
-var containsTests = []struct {
-	b, subslice []byte
-	want        bool
-}{
-	{[]byte("hello"), []byte("hel"), true},
-	{[]byte("日本語"), []byte("日本"), true},
-	{[]byte("hello"), []byte("Hello, world"), false},
-	{[]byte("東京"), []byte("京東"), false},
-}
-
-func TestContains(t *testing.T) {
-	for _, tt := range containsTests {
-		if got := Contains(tt.b, tt.subslice); got != tt.want {
-			t.Errorf("Contains(%q, %q) = %v, want %v", tt.b, tt.subslice, got, tt.want)
-		}
-	}
-}
-
-var makeFieldsInput = func() []byte {
-	x := make([]byte, 1<<20)
-	// Input is ~10% space, ~10% 2-byte UTF-8, rest ASCII non-space.
-	for i := range x {
-		switch rand.Intn(10) {
-		case 0:
-			x[i] = ' '
-		case 1:
-			if i > 0 && x[i-1] == 'x' {
-				copy(x[i-1:], "χ")
-				break
-			}
-			fallthrough
-		default:
-			x[i] = 'x'
-		}
-	}
-	return x
-}
-
-var fieldsInput = makeFieldsInput()
-
-func BenchmarkFields(b *testing.B) {
-	b.SetBytes(int64(len(fieldsInput)))
-	for i := 0; i < b.N; i++ {
-		Fields(fieldsInput)
-	}
-}
-
-func BenchmarkFieldsFunc(b *testing.B) {
-	b.SetBytes(int64(len(fieldsInput)))
-	for i := 0; i < b.N; i++ {
-		FieldsFunc(fieldsInput, unicode.IsSpace)
-	}
-}
-
-func BenchmarkTrimSpace(b *testing.B) {
-	s := []byte("  Some text.  \n")
-	for i := 0; i < b.N; i++ {
-		TrimSpace(s)
-	}
-}
diff --git a/src/pkg/compress/bzip2/bzip2.go b/src/pkg/compress/bzip2/bzip2.go
deleted file mode 100644
index 82e30c7..0000000
--- a/src/pkg/compress/bzip2/bzip2.go
+++ /dev/null
@@ -1,484 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package bzip2 implements bzip2 decompression.
-package bzip2
-
-import "io"
-
-// There's no RFC for bzip2. I used the Wikipedia page for reference and a lot
-// of guessing: http://en.wikipedia.org/wiki/Bzip2
-// The source code to pyflate was useful for debugging:
-// http://www.paul.sladen.org/projects/pyflate
-
-// A StructuralError is returned when the bzip2 data is found to be
-// syntactically invalid.
-type StructuralError string
-
-func (s StructuralError) Error() string {
-	return "bzip2 data invalid: " + string(s)
-}
-
-// A reader decompresses bzip2 compressed data.
-type reader struct {
-	br           bitReader
-	fileCRC      uint32
-	blockCRC     uint32
-	wantBlockCRC uint32
-	setupDone    bool // true if we have parsed the bzip2 header.
-	blockSize    int  // blockSize in bytes, i.e. 900 * 1024.
-	eof          bool
-	buf          []byte    // stores Burrows-Wheeler transformed data.
-	c            [256]uint // the `C' array for the inverse BWT.
-	tt           []uint32  // mirrors the `tt' array in the bzip2 source and contains the P array in the upper 24 bits.
-	tPos         uint32    // Index of the next output byte in tt.
-
-	preRLE      []uint32 // contains the RLE data still to be processed.
-	preRLEUsed  int      // number of entries of preRLE used.
-	lastByte    int      // the last byte value seen.
-	byteRepeats uint     // the number of repeats of lastByte seen.
-	repeats     uint     // the number of copies of lastByte to output.
-}
-
-// NewReader returns an io.Reader which decompresses bzip2 data from r.
-func NewReader(r io.Reader) io.Reader {
-	bz2 := new(reader)
-	bz2.br = newBitReader(r)
-	return bz2
-}
-
-const bzip2FileMagic = 0x425a // "BZ"
-const bzip2BlockMagic = 0x314159265359
-const bzip2FinalMagic = 0x177245385090
-
-// setup parses the bzip2 header.
-func (bz2 *reader) setup(needMagic bool) error {
-	br := &bz2.br
-
-	if needMagic {
-		magic := br.ReadBits(16)
-		if magic != bzip2FileMagic {
-			return StructuralError("bad magic value")
-		}
-	}
-
-	t := br.ReadBits(8)
-	if t != 'h' {
-		return StructuralError("non-Huffman entropy encoding")
-	}
-
-	level := br.ReadBits(8)
-	if level < '1' || level > '9' {
-		return StructuralError("invalid compression level")
-	}
-
-	bz2.fileCRC = 0
-	bz2.blockSize = 100 * 1024 * (int(level) - '0')
-	if bz2.blockSize > len(bz2.tt) {
-		bz2.tt = make([]uint32, bz2.blockSize)
-	}
-	return nil
-}
-
-func (bz2 *reader) Read(buf []byte) (n int, err error) {
-	if bz2.eof {
-		return 0, io.EOF
-	}
-
-	if !bz2.setupDone {
-		err = bz2.setup(true)
-		brErr := bz2.br.Err()
-		if brErr != nil {
-			err = brErr
-		}
-		if err != nil {
-			return 0, err
-		}
-		bz2.setupDone = true
-	}
-
-	n, err = bz2.read(buf)
-	brErr := bz2.br.Err()
-	if brErr != nil {
-		err = brErr
-	}
-	return
-}
-
-func (bz2 *reader) readFromBlock(buf []byte) int {
-	// bzip2 is a block based compressor, except that it has a run-length
-	// preprocessing step. The block based nature means that we can
-	// preallocate fixed-size buffers and reuse them. However, the RLE
-	// preprocessing would require allocating huge buffers to store the
-	// maximum expansion. Thus we process blocks all at once, except for
-	// the RLE which we decompress as required.
-	n := 0
-	for (bz2.repeats > 0 || bz2.preRLEUsed < len(bz2.preRLE)) && n < len(buf) {
-		// We have RLE data pending.
-
-		// The run-length encoding works like this:
-		// Any sequence of four equal bytes is followed by a length
-		// byte which contains the number of repeats of that byte to
-		// include. (The number of repeats can be zero.) Because we are
-		// decompressing on-demand our state is kept in the reader
-		// object.
-
-		if bz2.repeats > 0 {
-			buf[n] = byte(bz2.lastByte)
-			n++
-			bz2.repeats--
-			if bz2.repeats == 0 {
-				bz2.lastByte = -1
-			}
-			continue
-		}
-
-		bz2.tPos = bz2.preRLE[bz2.tPos]
-		b := byte(bz2.tPos)
-		bz2.tPos >>= 8
-		bz2.preRLEUsed++
-
-		if bz2.byteRepeats == 3 {
-			bz2.repeats = uint(b)
-			bz2.byteRepeats = 0
-			continue
-		}
-
-		if bz2.lastByte == int(b) {
-			bz2.byteRepeats++
-		} else {
-			bz2.byteRepeats = 0
-		}
-		bz2.lastByte = int(b)
-
-		buf[n] = b
-		n++
-	}
-
-	return n
-}
-
-func (bz2 *reader) read(buf []byte) (int, error) {
-	for {
-		n := bz2.readFromBlock(buf)
-		if n > 0 {
-			bz2.blockCRC = updateCRC(bz2.blockCRC, buf[:n])
-			return n, nil
-		}
-
-		// End of block. Check CRC.
-		if bz2.blockCRC != bz2.wantBlockCRC {
-			bz2.br.err = StructuralError("block checksum mismatch")
-			return 0, bz2.br.err
-		}
-
-		// Find next block.
-		br := &bz2.br
-		switch br.ReadBits64(48) {
-		default:
-			return 0, StructuralError("bad magic value found")
-
-		case bzip2BlockMagic:
-			// Start of block.
-			err := bz2.readBlock()
-			if err != nil {
-				return 0, err
-			}
-
-		case bzip2FinalMagic:
-			// Check end-of-file CRC.
-			wantFileCRC := uint32(br.ReadBits64(32))
-			if br.err != nil {
-				return 0, br.err
-			}
-			if bz2.fileCRC != wantFileCRC {
-				br.err = StructuralError("file checksum mismatch")
-				return 0, br.err
-			}
-
-			// Skip ahead to byte boundary.
-			// Is there a file concatenated to this one?
-			// It would start with BZ.
-			if br.bits%8 != 0 {
-				br.ReadBits(br.bits % 8)
-			}
-			b, err := br.r.ReadByte()
-			if err == io.EOF {
-				br.err = io.EOF
-				bz2.eof = true
-				return 0, io.EOF
-			}
-			if err != nil {
-				br.err = err
-				return 0, err
-			}
-			z, err := br.r.ReadByte()
-			if err != nil {
-				if err == io.EOF {
-					err = io.ErrUnexpectedEOF
-				}
-				br.err = err
-				return 0, err
-			}
-			if b != 'B' || z != 'Z' {
-				return 0, StructuralError("bad magic value in continuation file")
-			}
-			if err := bz2.setup(false); err != nil {
-				return 0, err
-			}
-		}
-	}
-}
-
-// readBlock reads a bzip2 block. The magic number should already have been consumed.
-func (bz2 *reader) readBlock() (err error) {
-	br := &bz2.br
-	bz2.wantBlockCRC = uint32(br.ReadBits64(32)) // skip checksum. TODO: check it if we can figure out what it is.
-	bz2.blockCRC = 0
-	bz2.fileCRC = (bz2.fileCRC<<1 | bz2.fileCRC>>31) ^ bz2.wantBlockCRC
-	randomized := br.ReadBits(1)
-	if randomized != 0 {
-		return StructuralError("deprecated randomized files")
-	}
-	origPtr := uint(br.ReadBits(24))
-
-	// If not every byte value is used in the block (i.e., it's text) then
-	// the symbol set is reduced. The symbols used are stored as a
-	// two-level, 16x16 bitmap.
-	symbolRangeUsedBitmap := br.ReadBits(16)
-	symbolPresent := make([]bool, 256)
-	numSymbols := 0
-	for symRange := uint(0); symRange < 16; symRange++ {
-		if symbolRangeUsedBitmap&(1<<(15-symRange)) != 0 {
-			bits := br.ReadBits(16)
-			for symbol := uint(0); symbol < 16; symbol++ {
-				if bits&(1<<(15-symbol)) != 0 {
-					symbolPresent[16*symRange+symbol] = true
-					numSymbols++
-				}
-			}
-		}
-	}
-
-	// A block uses between two and six different Huffman trees.
-	numHuffmanTrees := br.ReadBits(3)
-	if numHuffmanTrees < 2 || numHuffmanTrees > 6 {
-		return StructuralError("invalid number of Huffman trees")
-	}
-
-	// The Huffman tree can switch every 50 symbols so there's a list of
-	// tree indexes telling us which tree to use for each 50 symbol block.
-	numSelectors := br.ReadBits(15)
-	treeIndexes := make([]uint8, numSelectors)
-
-	// The tree indexes are move-to-front transformed and stored as unary
-	// numbers.
-	mtfTreeDecoder := newMTFDecoderWithRange(numHuffmanTrees)
-	for i := range treeIndexes {
-		c := 0
-		for {
-			inc := br.ReadBits(1)
-			if inc == 0 {
-				break
-			}
-			c++
-		}
-		if c >= numHuffmanTrees {
-			return StructuralError("tree index too large")
-		}
-		treeIndexes[i] = uint8(mtfTreeDecoder.Decode(c))
-	}
-
-	// The list of symbols for the move-to-front transform is taken from
-	// the previously decoded symbol bitmap.
-	symbols := make([]byte, numSymbols)
-	nextSymbol := 0
-	for i := 0; i < 256; i++ {
-		if symbolPresent[i] {
-			symbols[nextSymbol] = byte(i)
-			nextSymbol++
-		}
-	}
-	mtf := newMTFDecoder(symbols)
-
-	numSymbols += 2 // to account for RUNA and RUNB symbols
-	huffmanTrees := make([]huffmanTree, numHuffmanTrees)
-
-	// Now we decode the arrays of code-lengths for each tree.
-	lengths := make([]uint8, numSymbols)
-	for i := 0; i < numHuffmanTrees; i++ {
-		// The code lengths are delta encoded from a 5-bit base value.
-		length := br.ReadBits(5)
-		for j := 0; j < numSymbols; j++ {
-			for {
-				if !br.ReadBit() {
-					break
-				}
-				if br.ReadBit() {
-					length--
-				} else {
-					length++
-				}
-			}
-			if length < 0 || length > 20 {
-				return StructuralError("Huffman length out of range")
-			}
-			lengths[j] = uint8(length)
-		}
-		huffmanTrees[i], err = newHuffmanTree(lengths)
-		if err != nil {
-			return err
-		}
-	}
-
-	selectorIndex := 1 // the next tree index to use
-	currentHuffmanTree := huffmanTrees[treeIndexes[0]]
-	bufIndex := 0 // indexes bz2.buf, the output buffer.
-	// The output of the move-to-front transform is run-length encoded and
-	// we merge the decoding into the Huffman parsing loop. These two
-	// variables accumulate the repeat count. See the Wikipedia page for
-	// details.
-	repeat := 0
-	repeat_power := 0
-
-	// The `C' array (used by the inverse BWT) needs to be zero initialized.
-	for i := range bz2.c {
-		bz2.c[i] = 0
-	}
-
-	decoded := 0 // counts the number of symbols decoded by the current tree.
-	for {
-		if decoded == 50 {
-			currentHuffmanTree = huffmanTrees[treeIndexes[selectorIndex]]
-			selectorIndex++
-			decoded = 0
-		}
-
-		v := currentHuffmanTree.Decode(br)
-		decoded++
-
-		if v < 2 {
-			// This is either the RUNA or RUNB symbol.
-			if repeat == 0 {
-				repeat_power = 1
-			}
-			repeat += repeat_power << v
-			repeat_power <<= 1
-
-			// This limit of 2 million comes from the bzip2 source
-			// code. It prevents repeat from overflowing.
-			if repeat > 2*1024*1024 {
-				return StructuralError("repeat count too large")
-			}
-			continue
-		}
-
-		if repeat > 0 {
-			// We have decoded a complete run-length so we need to
-			// replicate the last output symbol.
-			if repeat > bz2.blockSize-bufIndex {
-				return StructuralError("repeats past end of block")
-			}
-			for i := 0; i < repeat; i++ {
-				b := byte(mtf.First())
-				bz2.tt[bufIndex] = uint32(b)
-				bz2.c[b]++
-				bufIndex++
-			}
-			repeat = 0
-		}
-
-		if int(v) == numSymbols-1 {
-			// This is the EOF symbol. Because it's always at the
-			// end of the move-to-front list, and never gets moved
-			// to the front, it has this unique value.
-			break
-		}
-
-		// Since two metasymbols (RUNA and RUNB) have values 0 and 1,
-		// one would expect |v-2| to be passed to the MTF decoder.
-		// However, the front of the MTF list is never referenced as 0,
-		// it's always referenced with a run-length of 1. Thus 0
-		// doesn't need to be encoded and we have |v-1| in the next
-		// line.
-		b := byte(mtf.Decode(int(v - 1)))
-		if bufIndex >= bz2.blockSize {
-			return StructuralError("data exceeds block size")
-		}
-		bz2.tt[bufIndex] = uint32(b)
-		bz2.c[b]++
-		bufIndex++
-	}
-
-	if origPtr >= uint(bufIndex) {
-		return StructuralError("origPtr out of bounds")
-	}
-
-	// We have completed the entropy decoding. Now we can perform the
-	// inverse BWT and setup the RLE buffer.
-	bz2.preRLE = bz2.tt[:bufIndex]
-	bz2.preRLEUsed = 0
-	bz2.tPos = inverseBWT(bz2.preRLE, origPtr, bz2.c[:])
-	bz2.lastByte = -1
-	bz2.byteRepeats = 0
-	bz2.repeats = 0
-
-	return nil
-}
-
-// inverseBWT implements the inverse Burrows-Wheeler transform as described in
-// http://www.hpl.hp.com/techreports/Compaq-DEC/SRC-RR-124.pdf, section 4.2.
-// In that document, origPtr is called `I' and c is the `C' array after the
-// first pass over the data. It's an argument here because we merge the first
-// pass with the Huffman decoding.
-//
-// This also implements the `single array' method from the bzip2 source code
-// which leaves the output, still shuffled, in the bottom 8 bits of tt with the
-// index of the next byte in the top 24-bits. The index of the first byte is
-// returned.
-func inverseBWT(tt []uint32, origPtr uint, c []uint) uint32 {
-	sum := uint(0)
-	for i := 0; i < 256; i++ {
-		sum += c[i]
-		c[i] = sum - c[i]
-	}
-
-	for i := range tt {
-		b := tt[i] & 0xff
-		tt[c[b]] |= uint32(i) << 8
-		c[b]++
-	}
-
-	return tt[origPtr] >> 8
-}
-
-// This is a standard CRC32 like in hash/crc32 except that all the shifts are reversed,
-// causing the bits in the input to be processed in the reverse of the usual order.
-
-var crctab [256]uint32
-
-func init() {
-	const poly = 0x04C11DB7
-	for i := range crctab {
-		crc := uint32(i) << 24
-		for j := 0; j < 8; j++ {
-			if crc&0x80000000 != 0 {
-				crc = (crc << 1) ^ poly
-			} else {
-				crc <<= 1
-			}
-		}
-		crctab[i] = crc
-	}
-}
-
-// updateCRC updates the crc value to incorporate the data in b.
-// The initial value is 0.
-func updateCRC(val uint32, b []byte) uint32 {
-	crc := ^val
-	for _, v := range b {
-		crc = crctab[byte(crc>>24)^v] ^ (crc << 8)
-	}
-	return ^crc
-}
diff --git a/src/pkg/compress/bzip2/bzip2_test.go b/src/pkg/compress/bzip2/bzip2_test.go
deleted file mode 100644
index 727249d..0000000
--- a/src/pkg/compress/bzip2/bzip2_test.go
+++ /dev/null
@@ -1,363 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package bzip2
-
-import (
-	"bytes"
-	"encoding/base64"
-	"encoding/hex"
-	"io"
-	"io/ioutil"
-	"testing"
-)
-
-func TestBitReader(t *testing.T) {
-	buf := bytes.NewReader([]byte{0xaa})
-	br := newBitReader(buf)
-	if n := br.ReadBits(1); n != 1 {
-		t.Errorf("read 1 wrong")
-	}
-	if n := br.ReadBits(1); n != 0 {
-		t.Errorf("read 2 wrong")
-	}
-	if n := br.ReadBits(1); n != 1 {
-		t.Errorf("read 3 wrong")
-	}
-	if n := br.ReadBits(1); n != 0 {
-		t.Errorf("read 4 wrong")
-	}
-}
-
-func TestBitReaderLarge(t *testing.T) {
-	buf := bytes.NewReader([]byte{0x12, 0x34, 0x56, 0x78})
-	br := newBitReader(buf)
-	if n := br.ReadBits(32); n != 0x12345678 {
-		t.Errorf("got: %x want: %x", n, 0x12345678)
-	}
-}
-
-func readerFromHex(s string) io.Reader {
-	data, err := hex.DecodeString(s)
-	if err != nil {
-		panic("readerFromHex: bad input")
-	}
-	return bytes.NewReader(data)
-}
-
-func decompressHex(s string) (out []byte, err error) {
-	r := NewReader(readerFromHex(s))
-	return ioutil.ReadAll(r)
-}
-
-func TestHelloWorldBZ2(t *testing.T) {
-	out, err := decompressHex(helloWorldBZ2Hex)
-	if err != nil {
-		t.Errorf("error from Read: %s", err)
-		return
-	}
-
-	if !bytes.Equal(helloWorld, out) {
-		t.Errorf("got %x, want %x", out, helloWorld)
-	}
-}
-
-func TestConcat(t *testing.T) {
-	out, err := decompressHex(helloWorldBZ2Hex + helloWorldBZ2Hex)
-	if err != nil {
-		t.Errorf("error from Read: %s", err)
-		return
-	}
-
-	hello2 := bytes.Repeat(helloWorld, 2)
-	if !bytes.Equal(hello2, out) {
-		t.Errorf("got %x, want %x", out, hello2)
-	}
-}
-
-func testZeros(t *testing.T, inHex string, n int) {
-	out, err := decompressHex(inHex)
-	if err != nil {
-		t.Errorf("error from Read: %s", err)
-		return
-	}
-
-	expected := make([]byte, n)
-
-	if !bytes.Equal(expected, out) {
-		allZeros := true
-		for _, b := range out {
-			if b != 0 {
-				allZeros = false
-				break
-			}
-		}
-		t.Errorf("incorrect result, got %d bytes (allZeros: %t)", len(out), allZeros)
-	}
-}
-
-func Test32Zeros(t *testing.T) {
-	testZeros(t, thirtyTwoZerosBZ2Hex, 32)
-}
-
-func Test1MBZeros(t *testing.T) {
-	testZeros(t, oneMBZerosBZ2Hex, 1024*1024)
-}
-
-func testRandomData(t *testing.T, compressedHex, uncompressedHex string) {
-	out, err := decompressHex(compressedHex)
-	if err != nil {
-		t.Errorf("error from Read: %s", err)
-		return
-	}
-
-	expected, _ := hex.DecodeString(uncompressedHex)
-
-	if !bytes.Equal(out, expected) {
-		t.Errorf("incorrect result\ngot:  %x\nwant: %x", out, expected)
-	}
-}
-
-func TestRandomData1(t *testing.T) {
-	testRandomData(t, randBZ2Hex, randHex)
-}
-
-func TestRandomData2(t *testing.T) {
-	// This test involves several repeated bytes in the output, but they
-	// should trigger RLE decoding.
-	testRandomData(t, rand2BZ2Hex, rand2Hex)
-}
-
-func TestRandomData3(t *testing.T) {
-	// This test uses the full range of symbols.
-	testRandomData(t, rand3BZ2Hex, rand3Hex)
-}
-
-func Test1MBSawtooth(t *testing.T) {
-	out, err := decompressHex(oneMBSawtoothBZ2Hex)
-	if err != nil {
-		t.Errorf("error from Read: %s", err)
-		return
-	}
-
-	expected := make([]byte, 1024*1024)
-
-	for i := range expected {
-		expected[i] = byte(i)
-	}
-
-	if !bytes.Equal(out, expected) {
-		t.Error("incorrect result")
-	}
-}
-
-const helloWorldBZ2Hex = "425a68393141592653594eece83600000251800010400006449080200031064c4101a7a9a580bb9431f8bb9229c28482776741b0"
-
-var helloWorld = []byte("hello world\n")
-
-const thirtyTwoZerosBZ2Hex = "425a6839314159265359b5aa5098000000600040000004200021008283177245385090b5aa5098"
-const oneMBZerosBZ2Hex = "425a683931415926535938571ce50008084000c0040008200030cc0529a60806c4201e2ee48a70a12070ae39ca"
-
-const randBZ2Hex = "425a6839314159265359905d990d0001957fffffffffffafffffffffffffffffbfff6fffdfffffffffffffffffffffffffffffc002b6dd75676ed5b77720098320d11a64626981323d4da47a83131a13d09e8040f534cd4f4d27a464d193008cd09804601347a980026350c9886234d36864193d1351b44c136919e90340d26127a4cd264c32023009898981310c0344c340027a8303427a99a04c00003534c230d034f5006468d268cf54d36a3009a69a62626261311b40026013d34201a6934c9a604c98ca6c8460989fa9346234d30d3469a2604fd4131a7aa6d0046043d4c62098479269e89e835190d0 [...]
-const randHex = "c95138082bdf2b9bfa5b1072b23f729735d42c785eeb94320fb14c265b9c2ca421d01a3db986df1ac2acde5a0e6bf955d6f95e61261540905928e195f1a66644cc7f37281744fff4dc6df35566a494c41a8167151950eb74f5fc45f85ad0e5ed28b49adfe218aa7ec1707e8e1d55825f61f72beda3b4c006b8c9188d7336a5d875329b1b58c27cc4e89ecbae02c7712400c39dd131d2c6de82e2863da51d472bdfb21ecce62cc9cf769ed28aedc7583d755da45a0d90874bda269dd53283a9bdfd05f95fc8e9a304bb338ea1a2111894678c18134f17d31a15d9bfc1237894650f3e715e2548639ecbddb845cfe [...]
-
-const oneMBSawtoothBZ2Hex = "425a683931415926535971931ea00006ddffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe007de00000000000000024c00130001300000000000000000000000000000000000000000000000000000000126000980009800000000000000000000000000000000000000000000000000000000930004c0004c000000000000000000000000000000000000000000000000000000004980026000260000000000000000000000000000000000000000000000000000000009aaaaa000000000000000000000000000000000000000000000000000000000000 [...]
-
-const rand2BZ2Hex = "425a6839314159265359d992d0f60000137dfe84020310091c1e280e100e042801099210094806c0110002e70806402000546034000034000000f2830000032000d3403264049270eb7a9280d308ca06ad28f6981bee1bf8160727c7364510d73a1e123083421b63f031f63993a0f40051fbf177245385090d992d0f60"
-const rand2Hex = "92d5652616ac444a4a04af1a8a3964aca0450d43d6cf233bd03233f4ba92f8719e6c2a2bd4f5f88db07ecd0da3a33b263483db9b2c158786ad6363be35d17335ba"
-
-const rand3BZ2Hex = "425a68393141592653593be669d00000327ffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffc002b3b2b1b6e2bae400004c00132300004c0d268c004c08c0130026001a008683234c0684c34008c230261a04c0260064d07a8d00034000d27a1268c9931a8d327a3427a41faa69ea0da264c1a34219326869b51b49a6469a3268c689fa53269a62794687a9a68f5189994c9e487a8f534fd49a3d34043629e8c93d04da4f4648d30d4f44d3234c4d3023d0840680984d309934c234d3131a000640984f536a6132601300130130c8d00d04d1841ea7a8d31a02609b40023 [...]
-const rand3Hex = "1744b384d68c042371244e13500d4bfb98c6244e3d71a5b700224420b59c593553f33bd786e3d0ce31626f511bc985f59d1a88aa38ba8ad6218d306abee60dd9172540232b95be1af146c69e72e5fde667a090dc3f93bdc5c5af0ab80acdbaa7a505f628c59dc0247b31a439cacf5010a94376d71521df08c178b02fb96fdb1809144ea38c68536187c53201fea8631fb0a880b4451ccdca7cc61f6aafca21cc7449d920599db61789ac3b1e164b3390124f95022aeea39ccca3ec1053f4fa10de2978e2861ea58e477085c2220021a0927aa94c5d0006b5055abba340e4f9eba22e969978dfd18e278a8b89d8 [...]
-
-const (
-	digits = iota
-	twain
-)
-
-var testfiles = []string{
-	// Digits is the digits of the irrational number e. Its decimal representation
-	// does not repeat, but there are only 10 possible digits, so it should be
-	// reasonably compressible.
-	digits: "testdata/e.txt.bz2",
-	// Twain is Project Gutenberg's edition of Mark Twain's classic English novel.
-	twain: "testdata/Mark.Twain-Tom.Sawyer.txt.bz2",
-}
-
-func benchmarkDecode(b *testing.B, testfile int) {
-	compressed, err := ioutil.ReadFile(testfiles[testfile])
-	if err != nil {
-		b.Fatal(err)
-	}
-	b.SetBytes(int64(len(compressed)))
-	for i := 0; i < b.N; i++ {
-		r := bytes.NewReader(compressed)
-		io.Copy(ioutil.Discard, NewReader(r))
-	}
-}
-
-func BenchmarkDecodeDigits(b *testing.B) { benchmarkDecode(b, digits) }
-func BenchmarkDecodeTwain(b *testing.B)  { benchmarkDecode(b, twain) }
-
-func TestBufferOverrun(t *testing.T) {
-	// Tests https://code.google.com/p/go/issues/detail?id=5747.
-	buffer := bytes.NewReader([]byte(bufferOverrunBase64))
-	decoder := base64.NewDecoder(base64.StdEncoding, buffer)
-	decompressor := NewReader(decoder)
-	// This shouldn't panic.
-	ioutil.ReadAll(decompressor)
-}
-
-var bufferOverrunBase64 string = `
-QlpoNTFBWSZTWTzyiGcACMP/////////////////////////////////3/7f3///
-////4N/fCZODak2Xo44GIHZgkGzDRbFAuwAAKoFV7T6AO6qwA6APb6s2rOoAkAAD
-oACUoDtndh0iQAPkAAAAaPWihQoCgr5t97Obju21ChQB0NBm3RbA7apXrRoBooAA
-AhA+IAHWl2Us3O7t9yieb3udvd76+4+fd33nd3HO1bVvfcGRne6+3vfPvfc++995
-w7k973eJhasLVec970tzDNXdX28LoPXZ3H3K9z0s5ufWAfes49d5594c3dUYtI+2
-+h1dvtpRa+uvrVEAG9bl893RVEN7cWvroSqWjPMGgAQi7Gq8TJSgKKdjKFBIB9Ae
-LqWxleu715eXe7ml9e5098Z6G1vr7t1QZ6ot76YzPd3j7333t2ql2Chm7XrA9ICQ
-VF77z3rVBWqkSXtlfb099hyezAr6USbGpICTSCFAaqHrKo+tUnm32rpE4Ue+t2mj
-bKUeipEqwc93EdhhTwmQpOhhesC9iqDSPNTWYNSnUtBdm1nsA0nqqNd7OWwDXtFL
-ONmmA6Ubke26I9UblvWIPR5VOWOnctai443URunnDy77uVC59OfRvezlDu33Z7Ly
-3NNuuHW63088xu3t3NHZhkZbG7tXRlj00qOtbaXTJUUdspTbABR9R6EUwQAEAAAA
-EMEwRpoAAAABMmhoAAjBNNAaCMhponpoGpgJpk9TEyp6niGKZkAaAEfqMQ09U80p
-+pMGSCKngIAAAAgAAg0AAJhGgABGCEaaTyTKeNI1PE0wkj01GajMSNPSZGnqbU9T
-anlPUNAHqGQ0DQAMg9TamgAAYRU/IAAICAmjQJgjQBMEwp5DTSaaYmhTeqfplPID
-U1T9TynoU82pT1NPU/VP0j1NHqRpk9TTR7SnqaNNGmmQAaAD1Aeo0PSAAAAaaBiK
-eBAQBGgIABGQA0AmBNNBoaAgaJmpglPEyYap6npiTT0agGjJjUaaDTQAAAAAAM1A
-9QAaAAAADU8iEAQAEyAJk0NNNJgIZTJ5E00YSemiaZNGm1MpGNJ+lPU9qm9U2RDM
-oY0EzJB6h6nqDID1NMBDDRpo1AGNAjCMmhkMgaYSJIgAAAQyAAEyBoATECCNhTT0
-U/IZAmCM1DSTxkzUE8p6NDaGiZGJqntTFHvUyU9qPQp7Kn5GgKNPU9QAGg9QAAA3
-wz0Pk/g/m/m9P9H4vxv2+dH3gCS8nhbbbbbYxtgNsBsG0m2MbG0NNtsbYNsaY0wb
-bBibGmm22mxptNpsaGNDTY02JsG0MY0xg2MaYNNDbGwG0L5vsK/F9DO+EAA447Kq
-p7Wdf6Y+5c20T7DfHyMXIzRKrZexw72uiQI+y55vOe52xpqbCLC2uR20JdER7Zvr
-7ufuKb6zhiBxLuj0eA27v8RpMLucw9Ohwcizi2wrpt+yU1FdpM7ZYPcwS3XTef+A
-Wzjxwhdrgw3aH1LeC1eZW900x8V9Nv4hTPXp4l067P/4ANVZFF/imOe/d5bdueam
-/DFFokQWnFaU+ZqLBCM+d0PialJQWnLqRQZk/KhfbbYc2pCUTgffcSYbrCM1N+8l
-HU6gSz+h2GJXs+tbrNviL83M97X0vcTn/F82P8wen8/3/h3sHY+sf9CSej9ThYTV
-3lQ+FUHpfpGD4kv7dYMV995dpDX/y3xR8FoXx1bjUxBTNxuutwQ/h/Eedn9wpn6w
-E3+ND8YhN1HSriIxRE/6uFyMv6/oC6Elarw3aHMMqHJkGiiz6tejmvnYLQa+Qm6G
-deZ7jXTZV6NlpocgDnRdimS06bTYSkvPAL/xoWNLkX6N6VljU0dfKSBmm2uZE/xu
-sutQ1EdP7GdjhglIq4xlOFUFEQpmX+xx7R8y6c0GSAaqusOjNZwxZRudOvmXm1tZ
-T+YnbeB2ir9eiHNrtJNSLD/J/WDyuQpwBUtLKo0krccY/wIILP7f86teb9Z/9oyz
-OX05qEWbObfhpRw+9+rCvp/35ML8KX3aHaI0n+tudbFRsV5FLW+Oa8ruLN4peyVL
-DWjTHrXNthq/s7zAJYMeFJZkZt5mT9rfpH+5g3nc+piOSZ+J5nHtOnKI7Ff8Xl+j
-0t76XTNucCHQ6whav1OHdF53TY5wuv5OzvrdnxoId8fTyUvERr0ERINu/8XxZZ5f
-B5/kTZ8bBO0wv54Jp+ED/GQI8lZHzIQCP3vfQhwnCTj9TvITic7P4mYLDbH3fyzR
-i+6EajCcpXLWSGf+ZXkOrWspDWDhXtEKas0v3UqWksqgY1rTj45krX4KihN+daXs
-pZl5WPlta5p06CX6Xm2SfzqkMw12/3ix1bpnnZ+kFeBNX7A+E9zzG6OZaN78GOpl
-9Ht/eZn9PqWdav852zr0zqkDK2H5IjdvNah+b1YVGdQGzwR4Nw+f13yEKnV+y66W
-djfq7zWp7m5w+hzfv+Ly8O7oet5Vvd8/wQvO7qzOZ2vjf9X8Tj8PnMb/nc/nKqRR
-+ml4UEhOOwfCeJEEI109CMYSh91iAJqPjMyH6KjrPD7W25llZVcREYNCTg6htbQt
-M38wYoquCWP6tdKYlVIv14xTNUeUf4El/FunCf6csZkmv+9tfWx7t59wuKIa3saU
-tZs9M+3HFOZtz3OLg/Unoaj9BYazYqA78xBU9tZzrtmF/rQL9CGJt90o/oYnSfcS
-SL3haaw351LXWQ1XOsv1SmH3v6ymuxEpPPnEDmBELaTYsvvMIWJsmPZFFww++Kd7
-s/Jo0JFeUU7uNtI+gVosAIpVVuWfI/9tOIycz7I5Z7zjV+NR2OuZbYtW5F08KX4o
-2k/xuJIchcNFPtxPfw9dkDgscRbMckyFMrzuZ3IvrcGzk0J6iI5ytrv37bGpAXMz
-WK9mMMPebepNevmLjjo/QWoM968Sjv7ldlPS5AinHcXwsFv6dmmh8lJt7UOJWoKu
-lMD1cB2ksIGpMdv8iuqR42Rn/kn+17BhhUZcwDBaUXVdX6bKW7fxlUYbq+mlqIcf
-a9v8HF87M9ANbi9bq9onf9TD7nQ6Xf6vZci8TBPX+/GI0He6j31fTVQYW+NsQxvO
-J8xrx+e58CCLQNjxeIyPt+F+qk/QMiXw+LyxGVkV/XcGQT9X03jSDP6beJ5QG1JW
-9Q3qLv/YixWI7gPV9Mrhf2oRYTc/9KLFRhkE3SjKOTKuSSBKQ24fI+hEznamH71D
-66Hwez8/0et7AtTv9zvamv2OD5He6fMV4k+ePl6+qPfO5CdHtK+eCDZL5+4f5yrl
-gTcRFiq8fXbc5IaI5fbbc1KMM/2T0Mr7+Hwaco6FtXm0fmhCgTZRqY4pKiEIfmaz
-QwHNOOCrtMJ2VwsyMumt7xsOolGnizRev6lILH43qPcczQM7Gc5zRin80YvFt1Qm
-h/57Z0auR2h0fuX50MBO4XQ+26y5l6v4j902R66c0j3z2KHstKQ04J/h6LbuNQE4
-D6cu/lyfK69DxxX8wb8XaQkMUcJdo1LzqUGDAb3Kfn/A3P/JYc99MO9qv67+SxWb
-wYTyqKdWTd+1KbR/Rcn0Io5zI/QquX7FA1bxfMytjQ/X+l0fh0Pf+Hx97meH4fQL
-7/T8/sdTm9Tn8nELvedyhydLlPPTScINdXyLIq9wgIJr4fWPbp9ZhFh/56fdSgOG
-HDXg+gkXsN2Rddr4HQ5P3u+RhLzmSjhzoqY5EsPC4QvRlX9JXjB84rPV5USR66qa
-/kjw4156GJnzoXtydKJE53t6PHfZWO+3ujsfI6iAdshc7OFzGXiZB9PtItKodhYq
-nABkTKdcpu4+TOpf9h5piX5slsaBjkeTnj/Ba02ilboQfcDVigxrYn/iTH5ySWUW
-/lHtg78s5UZM8sErwhNe3N3w+6ZOMnU+5i86/xFNtqZfDdXTGy1H3PzGbdtZXYT+
-Ixx2vpwBYzbPVYHxKosM5rPiVmcTllI9nuoSfeh9ib4foFWauOpvdmhBDqpTpKTX
-u8EO2l2Z195G2RIV7TlKSxGWjR5sl/nALu1uzBeLd9zpSujzMTd1uTX9Qk/Q1S+r
-vaW6bm8qqPO4jb6Wx6XIkm321nrIF6Ae25d1+Dpv/P5G4NoLd2j6/EtENC3FeR5z
-oo7bA+tI8yEQRhiF0z1FlJXLD5ZbhNNWQm/j/IbzRfh8JtOFZU7ruShLvHXysW9S
-9V909tr9jn8/E/Hb5N/1NVNHnZu2HIUvJvHJiHd2ucmeI9PWUMnppmE65GQ5E9xV
-ZRlGEH0X85EvmHyEupkMrCC0oMv9RCq+/H8gcfpe00Hs/S+regT5p58cyYomh93v
-qvuw/A06BE/wzJESuYbN9pqYpoXqXFemW1NksHEJ2w+PYMJ27WJyD5FpaXB85VaW
-qMOhDfO8E3QdH8ybyKt/UgI8/tDGpFbyOlaVdIv1FXJhoLp8soAA4Djg6/KZ066N
-ZFYuS8WdjpSZGP4/Lw+1yaXlzNznc/k2uHe2uXP3uFuPcHx+Dm44utxldoO1uBPy
-+jzOs14+MIgOjOHMVNqAbMd8fUedLlhJMCfMtm4uz01enLNKcMrtLlPIR37Yukh1
-YEMXYpm7eU4XU+j+Jj3pDyaXtXs+p1fWfTN/cy9/Oxs4umUXQ4uHh1kObtayDJ56
-/QMxiHobjHNKuKfMxsrYEwN+QVIyVjAwMDYuMjQ1AAA9IwJniiBLRkZDAAAXt0Ja
-aDQxQVkmU1lZtwytAACLf///////////////////+//////v//////////bv78//
-/+AXO133uwO2xB2UxIvbKXrCqCoURUBL2ytFI82AFdcOwMhVTHtk5rD3szEVNYD4
-aIQINCaMRoTaSn7SbSMJiYmEwieTEp+psqbMCp+VNPaFNpqbBNR7UmanlPUeKfqm
-j1PU0/VPU08o9Q9EeKHlPJtKbYqeTCYhN6U9T1NH6mp+lPyoGNTI/Knkyg1MggAg
-CaMEyQnqZoaaRtRtJpppppoDaTR6hpphGh6mmgHpMQBpkGTTEAAaAAAA00AZDag0
-ADIBkGgABqemiRNTI0k8aU0PRGRoAZlP0UAAAGgAAAyAADQaAAAaAAAAAAAAAAAA
-AaAAAAM0kgRBJ5MlPFP1Gj0jTTTUaekxNAbUGjTQMgaZANNAAAAaAADTQAAAAAAA
-ANAA0AAANADQ0QAAAAAAAAAaGgAAAAAAABoA0AAA0AAAAAAAAAAAAANAAAAAkSEI
-aTRpomp5DUxNNDTJPTKaep6T09Kemmo2JG0aTQ9ENogaaGhkABo0NHqaBoDTI0DC
-Gj0gNAMhoDQ9QMQNAGQAaDDwyMPIMlbG1vhRBTFo6JksSupgpAjPbY0ec02IGXjb
-eS+FBsh01+O4ZOaD+srUZCFaT4DRjVDLx7uKIsFtESIDUg1ZkhyCSYov05C00MtR
-BdNNa/AYPGOQZWcs+VegXOPrkushFbZ3mBoRD6WamClkpBaHZrUhUl02bIfRXX4w
-b3/9cW9nHDVxh2qFBxqgRKfmq7/Jc/tdJk05nVrGbckGVy2PnIy30CDhpWmqrSot
-K2bOnX0NbP1iy2cd0Na0ZmbRstm4MzMzbbMySTd35F7f+zPP8DC+NJLYcakkkkRd
-NZlupJt3OMFoDAD2g+N3FAMCydhIpoRHRQAdFI5nNg4ugEXHCYxkMyGCwtaJmial
-y0IMlpSYYM/weXNJAhFqS0GNmvaPEtYGjbvaucMdklOTmBX1vfVAkTYB1uXCSK64
-UNIixOqRKLuRCFtqIQtgwqaFrCkIYbbewErWABa+VGADWsJXJjfx5SJViLuwiGXq
-Ru6vCuwmU5CJiJz3UiBpmLv0r2wskxUhY4tzPVGQ9RMXJl65eLSNwZVwaSyGZ9Cm
-A3jztQUUpFeUryBTskW95iVwRMFrhBCwZBAFJBZvhMEMNoDJJlUoIhQkAkjbExp2
-YZio+ZYeAZUwmH1qUbdQixmxf0+61+aVgJ1hwxsO1yG3hFx4pfjc09ITVht0pG8u
-FtVFhPa1KE0gTRUSVXywkITucqk0Waz5Fs6qJpVHYdNrbYRFxnFsQGY1qmsTLjK6
-4QX5Rddo6krM/Bx9CqIAKq4CzVQYHrmIAd2EBhYmwVYwLvhzKIUrc2EirnGIvyuD
-O4YZDSwsVTA0BpVvUOjDErkCraBoSutcKwUSSLGhVvNYHLz3klgZD++wWsa/swLw
-gvNDY2De+sncOv8X2lq4HD95ZdwPuTIMXCwSbg4RrIqv+L0y6F17pqDecyQYPEj3
-iN/0BBeWZlJAyBMi5U3Q1zAlsK8IlDhaXGmvZrgISq5CfNjmUgxDeMggOKqxu4sI
-OrilS49Lkl1J3u3GjXTuH+rX+4ccyFAQnizCpPClcY77F59j63S6fr5vr+y99tuO
-7Ox7Wg/ljwhdyaK4xMmXczeJbx7x07htJNtC4xcQfAtvzeznLrN6MN/ILIBOI65I
-qIA2D5fHHj1XN4aN6TvOjWDaSbSWqxCSCvXUpzkNJAkWXAuTwF8k5uSJvQj/rVo0
-hAhEMEIYkCRGx9AX+byIuXWlLMbbVeliHNUL5AQYmNwLFu4SkmGD+UWtBMyVHQOQ
-ss0ggoVKSKOBUgnVS6ljt7WE1qXqJJ4QA1pEwYNLEaguEE1LtPNoVr5WzjbSbWPk
-V9OW3y9IneUDLoIV5pAkEFTEFGFVjeTFxtpzBBfGgycBxVCdz8eESBIzsamRchAa
-TQunQH8DHnpfod9QuAuRvc7JBlKUCYmCjMvynLcxIFohxCaYrDvGw4QbXZB7oWQ7
-hpoGlz23ayDfB8NrRRzdilsEQyQniu9ASLQg7RrGZnoTr1ai12IbCEUCGdFq03P5
-nBnRFAGmisQGcyykV9gKtcVMWLhCuVmXg86dndn7slUpRNSSEAU20oaWIm1maFTu
-E0DT4gTbg0nuhjtz3kNOz+i7sBm0bkXjxQWuLqlZEmp60ZTyRZJDUqKSEKg6hqcy
-ERxdU22CSNOO10RYUUiDVpKhPNdKTOIE1thp02sBNoNTFSht8WJtaBQ09qN3jd5r
-dOLX4IA5fevRyCCzDgRXfV4wzik4KROjmxmTMglBySlIMEzcXehnDXCRiZSlvwA2
-0YsIOROcm4UrIRFxJHctJH7OdN5u1aHVHb5UaLHpv48NgmFRE56KTSoaWunqm2st
-S0mrAdOiqcR12PWVbdVRJKcQ0DQuhwlAPcRtpxN3D4kbXJjToSYJIFw406G2CSaK
-jQMIJPZGlQmgyFhoCSzeGS1VSq5SKKQQxs5RqKUcVUNY57YUETb4mXzV84SPngKi
-nsce0mXByZq5BKUA9puHZWLNwQIYuDaJUNgG+E01E3pDYVNLKYQ0hsVesgV5gZY0
-htDsRdGtm0+iGnkN6+Ea9YJtUZNAkx2GgSoix12nTW0avTUfxR3oYcpvZ7IdtABE
-UhBcjG4qZtDZsS1JQHys243vhLaDTSvvTeBiJA2tmokqECTBcSOCAGkAxMKlVAva
-4IsLRaBBqhxDbcGtgdw03mFcLUaFuhtKuuEIEkUleJQwby/zwu9uvvZK4xTV+ECM
-a8lmzxKmqkBggYK1+xPdbmJclm6tSZhE/OSJtCEjs+unJIQkT9hCWgBJqGMS07Eh
-AJNmBiuVEVdTyjkIJkavuZmx2sJF13htgEZUCC23lZFOE6gWbM9WyYNJTM8yCQrb
-0Sx3OQvBML5cRATAQkSQkAJOAhoxpQkNi4ZiEVDbdtJAME0RXNDXGHA3M3Q0mm1o
-IEwbWpaM1DQCSMbGRCAu3iRIQiT6RlBpT1n3tfwvUXz3gIVlx3mEximY/kZW1kNG
-sgEJIrBisaEoGYPJ+1CQUYFBw+eGEHJQBpNHjErXUJY2iWHQ30hXwFBuMSxQ2lB5
-bg+/LX3euG6HsHUB1lFvBvaiaBrITVwkCTa1d0s9CHZCiDZjbWReKyrpPE2oSa7o
-LPrR4BJvys9ttjUpzETSSMxh8vsr9dXTwKBtK+1xCTGDQmNIaE29HmHdS5GSxpya
-MismcAUSEgSxHBrKtgsZzduG7vHZn16l3kFkVITtENIzS2JsiBwFTDlhgexsjBHv
-5HXOYxHBzoSDCcPZ0ctvkY9aS5XpoQuFYkGJgCsqjJZeUMNUEpDSbKcnUc1PifIA
-CbR2UoXawBlspkEBr9HBfvUi/MUakZVOf1WKYrqSaIXce62JOyhJLq3qJBloTA0F
-VbILEtM+heFmNRCFt70GJrExVJri0ArYbCRbADSGDBpBXxxb/6fo+s3C7uaL7RjM
-LV2IQBNrAJrKFeJwTsPnxbAsemirUx2lk1kaxschzdK4TQNJN5wQnolIFg401OZ4
-2na11LnT3lR+1k1TMJhiAjXMk0F1ooHnYlt9LKfJ3ZIOmeY+2l9bUQHWFNGyEyfj
-EAcu3kpGLq0Ez7XOS+EpAASRQTAYMATfVQibHLTT30zG732+pNe9za1JNt8sNJYn
-RjWuJ6jL5ILV0rcd9vT7X9fObvcXitpvJ2XBJE+PhX2HaTkyWeF9pwnlQNrTe9hV
-tzhA+ihZrDrHNmLcQjZbnv/IMubqq8egxY80t5n6vZ6U5TR6U9uZJvai1xtqAyCR
-NWkW52m00rDTEuO6BA4q2RHDWwbETF55rRsWLIgNW9qJCyMHPbTM/dMBmWMQSMxz
-4M2pRzt47SICxA327UqSCEERqMFybmYi3nUxePtLgHYplqRiw4ynMbXd/kiQ0LE0
-PKJSSCXA42ymziCpAxNWflzpzQdJZusahRFr6t6m+4p273/Taj7k+hZyNgBAgXAY
-8F7pTts6orLb8IA6o4TOwkwQYmKvKu9VwMrE7+GUhVIAgY9a8DyQMiDBkEAwh7S1
-KgCBfao8DK1CwSS8Z3WjL5MEgt93z2koUQCD/YxMBppiCMp7SDVSmkkIHptfGpeh
-t+M13Ccv1tavIASFiaQl6rBz3K4N3DSGwNkCibrvEAC0fQirOWnc4NVbcLKpFG1l
-NQXF/eqdT79wq1Mvlap3QSCLhcD2D3fCkKVWid4aSjtp9FOX1Uaf7P9eT93zd9Sv
-mj2yNLRUGzyI/0oONNSzmmkvJ5Cq2X2CdldIWMGZO57RJ8oyATAWTQmRmNkfh0Sx
-uuR/J9oUsomVy1AEntc0dlPivkqBkBqrxU3j5PnWkaI3ZRGc0gg9spCQEISh4xEU
-pMhVrnmDQLfLP8Ouqpx917MAw7hkjQk6BJFTAbXDsz3LSHIxo/gB8qrA1vbvdZZh
-LtR0frJdfdppX8nAQX/TAxOQ8+H6yw8a9i7/zJEfSYIhop59N/fhcWW2F14cj2Xc
-fyHaZ04lTO4uPnly91jwuFPaREuZVp8AxImIhlkxkAN61tWdWG7tEbaCgszh6VIz
-ThFnHo2Vi8SQXPrXCN7J9Tc9ZYiAYqoThV/u6SYsea5aZL8deOvKBQCgZZuIxX1z
-4EnfcqG176vY4VqMBIC4pMJz0WcHJYqN+j7BiwGoMBwExrIdTB7q4XIFLotcIpS0
-1MqyVsesvoQq7WObmGQXdMliMirSLcDuSx8Qy+4pIBgGDIyMp1qbonnGdcHYvU8S
-O0A8s/iua5oFdNZTWvbVI4FUH9sKcLiB3/fIAF+sB4n8q6L+UCfmbPcAo/crQ6b3
-HqhDBMY9J0q/jdz9GNYZ/1fbXdkUqAQKFePhtzJDRBZba27+LPQNMCcrHMq06F1T
-4QmLmkHt7LxB2pAczUO+T2O9bHEw/HWw+dYf2MoRDUw=
-`
diff --git a/src/pkg/compress/bzip2/move_to_front.go b/src/pkg/compress/bzip2/move_to_front.go
deleted file mode 100644
index b7e75a7..0000000
--- a/src/pkg/compress/bzip2/move_to_front.go
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package bzip2
-
-// moveToFrontDecoder implements a move-to-front list. Such a list is an
-// efficient way to transform a string with repeating elements into one with
-// many small valued numbers, which is suitable for entropy encoding. It works
-// by starting with an initial list of symbols and references symbols by their
-// index into that list. When a symbol is referenced, it's moved to the front
-// of the list. Thus, a repeated symbol ends up being encoded with many zeros,
-// as the symbol will be at the front of the list after the first access.
-type moveToFrontDecoder struct {
-	// Rather than actually keep the list in memory, the symbols are stored
-	// as a circular, double linked list with the symbol indexed by head
-	// at the front of the list.
-	symbols [256]byte
-	next    [256]uint8
-	prev    [256]uint8
-	head    uint8
-	len     int
-}
-
-// newMTFDecoder creates a move-to-front decoder with an explicit initial list
-// of symbols.
-func newMTFDecoder(symbols []byte) *moveToFrontDecoder {
-	if len(symbols) > 256 {
-		panic("too many symbols")
-	}
-
-	m := new(moveToFrontDecoder)
-	copy(m.symbols[:], symbols)
-	m.len = len(symbols)
-	m.threadLinkedList()
-	return m
-}
-
-// newMTFDecoderWithRange creates a move-to-front decoder with an initial
-// symbol list of 0...n-1.
-func newMTFDecoderWithRange(n int) *moveToFrontDecoder {
-	if n > 256 {
-		panic("newMTFDecoderWithRange: cannot have > 256 symbols")
-	}
-
-	m := new(moveToFrontDecoder)
-	for i := 0; i < n; i++ {
-		m.symbols[byte(i)] = byte(i)
-	}
-	m.len = n
-	m.threadLinkedList()
-	return m
-}
-
-// threadLinkedList creates the initial linked-list pointers.
-func (m *moveToFrontDecoder) threadLinkedList() {
-	if m.len == 0 {
-		return
-	}
-
-	m.prev[0] = uint8(m.len - 1)
-
-	for i := byte(0); int(i) < m.len-1; i++ {
-		m.next[i] = uint8(i + 1)
-		m.prev[i+1] = uint8(i)
-	}
-
-	m.next[m.len-1] = 0
-}
-
-func (m *moveToFrontDecoder) Decode(n int) (b byte) {
-	// Most of the time, n will be zero so it's worth dealing with this
-	// simple case.
-	if n == 0 {
-		return m.symbols[m.head]
-	}
-
-	i := m.head
-	for j := 0; j < n; j++ {
-		i = m.next[i]
-	}
-	b = m.symbols[i]
-
-	m.next[m.prev[i]] = m.next[i]
-	m.prev[m.next[i]] = m.prev[i]
-	m.next[i] = m.head
-	m.prev[i] = m.prev[m.head]
-	m.next[m.prev[m.head]] = i
-	m.prev[m.head] = i
-	m.head = i
-
-	return
-}
-
-// First returns the symbol at the front of the list.
-func (m *moveToFrontDecoder) First() byte {
-	return m.symbols[m.head]
-}
diff --git a/src/pkg/compress/flate/fixedhuff.go b/src/pkg/compress/flate/fixedhuff.go
deleted file mode 100644
index 9be3d53..0000000
--- a/src/pkg/compress/flate/fixedhuff.go
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package flate
-
-// autogenerated by gen.go, DO NOT EDIT
-
-var fixedHuffmanDecoder = huffmanDecoder{
-	7,
-	[huffmanNumChunks]uint32{
-		0x1007, 0x0508, 0x0108, 0x1188, 0x1107, 0x0708, 0x0308, 0x0c09,
-		0x1087, 0x0608, 0x0208, 0x0a09, 0x0008, 0x0808, 0x0408, 0x0e09,
-		0x1047, 0x0588, 0x0188, 0x0909, 0x1147, 0x0788, 0x0388, 0x0d09,
-		0x10c7, 0x0688, 0x0288, 0x0b09, 0x0088, 0x0888, 0x0488, 0x0f09,
-		0x1027, 0x0548, 0x0148, 0x11c8, 0x1127, 0x0748, 0x0348, 0x0c89,
-		0x10a7, 0x0648, 0x0248, 0x0a89, 0x0048, 0x0848, 0x0448, 0x0e89,
-		0x1067, 0x05c8, 0x01c8, 0x0989, 0x1167, 0x07c8, 0x03c8, 0x0d89,
-		0x10e7, 0x06c8, 0x02c8, 0x0b89, 0x00c8, 0x08c8, 0x04c8, 0x0f89,
-		0x1017, 0x0528, 0x0128, 0x11a8, 0x1117, 0x0728, 0x0328, 0x0c49,
-		0x1097, 0x0628, 0x0228, 0x0a49, 0x0028, 0x0828, 0x0428, 0x0e49,
-		0x1057, 0x05a8, 0x01a8, 0x0949, 0x1157, 0x07a8, 0x03a8, 0x0d49,
-		0x10d7, 0x06a8, 0x02a8, 0x0b49, 0x00a8, 0x08a8, 0x04a8, 0x0f49,
-		0x1037, 0x0568, 0x0168, 0x11e8, 0x1137, 0x0768, 0x0368, 0x0cc9,
-		0x10b7, 0x0668, 0x0268, 0x0ac9, 0x0068, 0x0868, 0x0468, 0x0ec9,
-		0x1077, 0x05e8, 0x01e8, 0x09c9, 0x1177, 0x07e8, 0x03e8, 0x0dc9,
-		0x10f7, 0x06e8, 0x02e8, 0x0bc9, 0x00e8, 0x08e8, 0x04e8, 0x0fc9,
-		0x1007, 0x0518, 0x0118, 0x1198, 0x1107, 0x0718, 0x0318, 0x0c29,
-		0x1087, 0x0618, 0x0218, 0x0a29, 0x0018, 0x0818, 0x0418, 0x0e29,
-		0x1047, 0x0598, 0x0198, 0x0929, 0x1147, 0x0798, 0x0398, 0x0d29,
-		0x10c7, 0x0698, 0x0298, 0x0b29, 0x0098, 0x0898, 0x0498, 0x0f29,
-		0x1027, 0x0558, 0x0158, 0x11d8, 0x1127, 0x0758, 0x0358, 0x0ca9,
-		0x10a7, 0x0658, 0x0258, 0x0aa9, 0x0058, 0x0858, 0x0458, 0x0ea9,
-		0x1067, 0x05d8, 0x01d8, 0x09a9, 0x1167, 0x07d8, 0x03d8, 0x0da9,
-		0x10e7, 0x06d8, 0x02d8, 0x0ba9, 0x00d8, 0x08d8, 0x04d8, 0x0fa9,
-		0x1017, 0x0538, 0x0138, 0x11b8, 0x1117, 0x0738, 0x0338, 0x0c69,
-		0x1097, 0x0638, 0x0238, 0x0a69, 0x0038, 0x0838, 0x0438, 0x0e69,
-		0x1057, 0x05b8, 0x01b8, 0x0969, 0x1157, 0x07b8, 0x03b8, 0x0d69,
-		0x10d7, 0x06b8, 0x02b8, 0x0b69, 0x00b8, 0x08b8, 0x04b8, 0x0f69,
-		0x1037, 0x0578, 0x0178, 0x11f8, 0x1137, 0x0778, 0x0378, 0x0ce9,
-		0x10b7, 0x0678, 0x0278, 0x0ae9, 0x0078, 0x0878, 0x0478, 0x0ee9,
-		0x1077, 0x05f8, 0x01f8, 0x09e9, 0x1177, 0x07f8, 0x03f8, 0x0de9,
-		0x10f7, 0x06f8, 0x02f8, 0x0be9, 0x00f8, 0x08f8, 0x04f8, 0x0fe9,
-		0x1007, 0x0508, 0x0108, 0x1188, 0x1107, 0x0708, 0x0308, 0x0c19,
-		0x1087, 0x0608, 0x0208, 0x0a19, 0x0008, 0x0808, 0x0408, 0x0e19,
-		0x1047, 0x0588, 0x0188, 0x0919, 0x1147, 0x0788, 0x0388, 0x0d19,
-		0x10c7, 0x0688, 0x0288, 0x0b19, 0x0088, 0x0888, 0x0488, 0x0f19,
-		0x1027, 0x0548, 0x0148, 0x11c8, 0x1127, 0x0748, 0x0348, 0x0c99,
-		0x10a7, 0x0648, 0x0248, 0x0a99, 0x0048, 0x0848, 0x0448, 0x0e99,
-		0x1067, 0x05c8, 0x01c8, 0x0999, 0x1167, 0x07c8, 0x03c8, 0x0d99,
-		0x10e7, 0x06c8, 0x02c8, 0x0b99, 0x00c8, 0x08c8, 0x04c8, 0x0f99,
-		0x1017, 0x0528, 0x0128, 0x11a8, 0x1117, 0x0728, 0x0328, 0x0c59,
-		0x1097, 0x0628, 0x0228, 0x0a59, 0x0028, 0x0828, 0x0428, 0x0e59,
-		0x1057, 0x05a8, 0x01a8, 0x0959, 0x1157, 0x07a8, 0x03a8, 0x0d59,
-		0x10d7, 0x06a8, 0x02a8, 0x0b59, 0x00a8, 0x08a8, 0x04a8, 0x0f59,
-		0x1037, 0x0568, 0x0168, 0x11e8, 0x1137, 0x0768, 0x0368, 0x0cd9,
-		0x10b7, 0x0668, 0x0268, 0x0ad9, 0x0068, 0x0868, 0x0468, 0x0ed9,
-		0x1077, 0x05e8, 0x01e8, 0x09d9, 0x1177, 0x07e8, 0x03e8, 0x0dd9,
-		0x10f7, 0x06e8, 0x02e8, 0x0bd9, 0x00e8, 0x08e8, 0x04e8, 0x0fd9,
-		0x1007, 0x0518, 0x0118, 0x1198, 0x1107, 0x0718, 0x0318, 0x0c39,
-		0x1087, 0x0618, 0x0218, 0x0a39, 0x0018, 0x0818, 0x0418, 0x0e39,
-		0x1047, 0x0598, 0x0198, 0x0939, 0x1147, 0x0798, 0x0398, 0x0d39,
-		0x10c7, 0x0698, 0x0298, 0x0b39, 0x0098, 0x0898, 0x0498, 0x0f39,
-		0x1027, 0x0558, 0x0158, 0x11d8, 0x1127, 0x0758, 0x0358, 0x0cb9,
-		0x10a7, 0x0658, 0x0258, 0x0ab9, 0x0058, 0x0858, 0x0458, 0x0eb9,
-		0x1067, 0x05d8, 0x01d8, 0x09b9, 0x1167, 0x07d8, 0x03d8, 0x0db9,
-		0x10e7, 0x06d8, 0x02d8, 0x0bb9, 0x00d8, 0x08d8, 0x04d8, 0x0fb9,
-		0x1017, 0x0538, 0x0138, 0x11b8, 0x1117, 0x0738, 0x0338, 0x0c79,
-		0x1097, 0x0638, 0x0238, 0x0a79, 0x0038, 0x0838, 0x0438, 0x0e79,
-		0x1057, 0x05b8, 0x01b8, 0x0979, 0x1157, 0x07b8, 0x03b8, 0x0d79,
-		0x10d7, 0x06b8, 0x02b8, 0x0b79, 0x00b8, 0x08b8, 0x04b8, 0x0f79,
-		0x1037, 0x0578, 0x0178, 0x11f8, 0x1137, 0x0778, 0x0378, 0x0cf9,
-		0x10b7, 0x0678, 0x0278, 0x0af9, 0x0078, 0x0878, 0x0478, 0x0ef9,
-		0x1077, 0x05f8, 0x01f8, 0x09f9, 0x1177, 0x07f8, 0x03f8, 0x0df9,
-		0x10f7, 0x06f8, 0x02f8, 0x0bf9, 0x00f8, 0x08f8, 0x04f8, 0x0ff9,
-	},
-	nil, 0,
-}
diff --git a/src/pkg/compress/flate/gen.go b/src/pkg/compress/flate/gen.go
deleted file mode 100644
index 1427557..0000000
--- a/src/pkg/compress/flate/gen.go
+++ /dev/null
@@ -1,165 +0,0 @@
-// Copyright 2012 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build ignore
-
-// This program generates fixedhuff.go
-// Invoke as
-//
-//      go run gen.go |gofmt >fixedhuff.go
-
-package main
-
-import (
-	"fmt"
-)
-
-const maxCodeLen = 16
-
-// Note: the definition of the huffmanDecoder struct is copied from
-// inflate.go, as it is private to the implementation.
-
-// chunk & 15 is number of bits
-// chunk >> 4 is value, including table link
-
-const (
-	huffmanChunkBits  = 9
-	huffmanNumChunks  = 1 << huffmanChunkBits
-	huffmanCountMask  = 15
-	huffmanValueShift = 4
-)
-
-type huffmanDecoder struct {
-	min      int                      // the minimum code length
-	chunks   [huffmanNumChunks]uint32 // chunks as described above
-	links    [][]uint32               // overflow links
-	linkMask uint32                   // mask the width of the link table
-}
-
-// Initialize Huffman decoding tables from array of code lengths.
-func (h *huffmanDecoder) init(bits []int) bool {
-	// Count number of codes of each length,
-	// compute min and max length.
-	var count [maxCodeLen]int
-	var min, max int
-	for _, n := range bits {
-		if n == 0 {
-			continue
-		}
-		if min == 0 || n < min {
-			min = n
-		}
-		if n > max {
-			max = n
-		}
-		count[n]++
-	}
-	if max == 0 {
-		return false
-	}
-
-	h.min = min
-	var linkBits uint
-	var numLinks int
-	if max > huffmanChunkBits {
-		linkBits = uint(max) - huffmanChunkBits
-		numLinks = 1 << linkBits
-		h.linkMask = uint32(numLinks - 1)
-	}
-	code := 0
-	var nextcode [maxCodeLen]int
-	for i := min; i <= max; i++ {
-		if i == huffmanChunkBits+1 {
-			// create link tables
-			link := code >> 1
-			h.links = make([][]uint32, huffmanNumChunks-link)
-			for j := uint(link); j < huffmanNumChunks; j++ {
-				reverse := int(reverseByte[j>>8]) | int(reverseByte[j&0xff])<<8
-				reverse >>= uint(16 - huffmanChunkBits)
-				off := j - uint(link)
-				h.chunks[reverse] = uint32(off<<huffmanValueShift + uint(i))
-				h.links[off] = make([]uint32, 1<<linkBits)
-			}
-		}
-		n := count[i]
-		nextcode[i] = code
-		code += n
-		code <<= 1
-	}
-
-	for i, n := range bits {
-		if n == 0 {
-			continue
-		}
-		code := nextcode[n]
-		nextcode[n]++
-		chunk := uint32(i<<huffmanValueShift | n)
-		reverse := int(reverseByte[code>>8]) | int(reverseByte[code&0xff])<<8
-		reverse >>= uint(16 - n)
-		if n <= huffmanChunkBits {
-			for off := reverse; off < huffmanNumChunks; off += 1 << uint(n) {
-				h.chunks[off] = chunk
-			}
-		} else {
-			linktab := h.links[h.chunks[reverse&(huffmanNumChunks-1)]>>huffmanValueShift]
-			reverse >>= huffmanChunkBits
-			for off := reverse; off < numLinks; off += 1 << uint(n-huffmanChunkBits) {
-				linktab[off] = chunk
-			}
-		}
-	}
-	return true
-}
-
-func main() {
-	var h huffmanDecoder
-	var bits [288]int
-	initReverseByte()
-	for i := 0; i < 144; i++ {
-		bits[i] = 8
-	}
-	for i := 144; i < 256; i++ {
-		bits[i] = 9
-	}
-	for i := 256; i < 280; i++ {
-		bits[i] = 7
-	}
-	for i := 280; i < 288; i++ {
-		bits[i] = 8
-	}
-	h.init(bits[:])
-	fmt.Println("package flate")
-	fmt.Println()
-	fmt.Println("// autogenerated by gen.go, DO NOT EDIT")
-	fmt.Println()
-	fmt.Println("var fixedHuffmanDecoder = huffmanDecoder{")
-	fmt.Printf("\t%d,\n", h.min)
-	fmt.Println("\t[huffmanNumChunks]uint32{")
-	for i := 0; i < huffmanNumChunks; i++ {
-		if i&7 == 0 {
-			fmt.Printf("\t\t")
-		} else {
-			fmt.Printf(" ")
-		}
-		fmt.Printf("0x%04x,", h.chunks[i])
-		if i&7 == 7 {
-			fmt.Println()
-		}
-	}
-	fmt.Println("\t},")
-	fmt.Println("\tnil, 0,")
-	fmt.Println("}")
-}
-
-var reverseByte [256]byte
-
-func initReverseByte() {
-	for x := 0; x < 256; x++ {
-		var result byte
-		for i := uint(0); i < 8; i++ {
-			result |= byte(((x >> i) & 1) << (7 - i))
-		}
-		reverseByte[x] = result
-	}
-}
diff --git a/src/pkg/compress/flate/inflate.go b/src/pkg/compress/flate/inflate.go
deleted file mode 100644
index ce4923e..0000000
--- a/src/pkg/compress/flate/inflate.go
+++ /dev/null
@@ -1,708 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package flate implements the DEFLATE compressed data format, described in
-// RFC 1951.  The gzip and zlib packages implement access to DEFLATE-based file
-// formats.
-package flate
-
-import (
-	"bufio"
-	"io"
-	"strconv"
-)
-
-const (
-	maxCodeLen = 16    // max length of Huffman code
-	maxHist    = 32768 // max history required
-	// The next three numbers come from the RFC, section 3.2.7.
-	maxLit   = 286
-	maxDist  = 32
-	numCodes = 19 // number of codes in Huffman meta-code
-)
-
-// A CorruptInputError reports the presence of corrupt input at a given offset.
-type CorruptInputError int64
-
-func (e CorruptInputError) Error() string {
-	return "flate: corrupt input before offset " + strconv.FormatInt(int64(e), 10)
-}
-
-// An InternalError reports an error in the flate code itself.
-type InternalError string
-
-func (e InternalError) Error() string { return "flate: internal error: " + string(e) }
-
-// A ReadError reports an error encountered while reading input.
-type ReadError struct {
-	Offset int64 // byte offset where error occurred
-	Err    error // error returned by underlying Read
-}
-
-func (e *ReadError) Error() string {
-	return "flate: read error at offset " + strconv.FormatInt(e.Offset, 10) + ": " + e.Err.Error()
-}
-
-// A WriteError reports an error encountered while writing output.
-type WriteError struct {
-	Offset int64 // byte offset where error occurred
-	Err    error // error returned by underlying Write
-}
-
-func (e *WriteError) Error() string {
-	return "flate: write error at offset " + strconv.FormatInt(e.Offset, 10) + ": " + e.Err.Error()
-}
-
-// Note that much of the implementation of huffmanDecoder is also copied
-// into gen.go (in package main) for the purpose of precomputing the
-// fixed huffman tables so they can be included statically.
-
-// The data structure for decoding Huffman tables is based on that of
-// zlib. There is a lookup table of a fixed bit width (huffmanChunkBits),
-// For codes smaller than the table width, there are multiple entries
-// (each combination of trailing bits has the same value). For codes
-// larger than the table width, the table contains a link to an overflow
-// table. The width of each entry in the link table is the maximum code
-// size minus the chunk width.
-
-// Note that you can do a lookup in the table even without all bits
-// filled. Since the extra bits are zero, and the DEFLATE Huffman codes
-// have the property that shorter codes come before longer ones, the
-// bit length estimate in the result is a lower bound on the actual
-// number of bits.
-
-// chunk & 15 is number of bits
-// chunk >> 4 is value, including table link
-
-const (
-	huffmanChunkBits  = 9
-	huffmanNumChunks  = 1 << huffmanChunkBits
-	huffmanCountMask  = 15
-	huffmanValueShift = 4
-)
-
-type huffmanDecoder struct {
-	min      int                      // the minimum code length
-	chunks   [huffmanNumChunks]uint32 // chunks as described above
-	links    [][]uint32               // overflow links
-	linkMask uint32                   // mask the width of the link table
-}
-
-// Initialize Huffman decoding tables from array of code lengths.
-func (h *huffmanDecoder) init(bits []int) bool {
-	if h.min != 0 {
-		*h = huffmanDecoder{}
-	}
-
-	// Count number of codes of each length,
-	// compute min and max length.
-	var count [maxCodeLen]int
-	var min, max int
-	for _, n := range bits {
-		if n == 0 {
-			continue
-		}
-		if min == 0 || n < min {
-			min = n
-		}
-		if n > max {
-			max = n
-		}
-		count[n]++
-	}
-	if max == 0 {
-		return false
-	}
-
-	h.min = min
-	var linkBits uint
-	var numLinks int
-	if max > huffmanChunkBits {
-		linkBits = uint(max) - huffmanChunkBits
-		numLinks = 1 << linkBits
-		h.linkMask = uint32(numLinks - 1)
-	}
-	code := 0
-	var nextcode [maxCodeLen]int
-	for i := min; i <= max; i++ {
-		if i == huffmanChunkBits+1 {
-			// create link tables
-			link := code >> 1
-			if huffmanNumChunks < link {
-				return false
-			}
-			h.links = make([][]uint32, huffmanNumChunks-link)
-			for j := uint(link); j < huffmanNumChunks; j++ {
-				reverse := int(reverseByte[j>>8]) | int(reverseByte[j&0xff])<<8
-				reverse >>= uint(16 - huffmanChunkBits)
-				off := j - uint(link)
-				h.chunks[reverse] = uint32(off<<huffmanValueShift + uint(i))
-				h.links[off] = make([]uint32, 1<<linkBits)
-			}
-		}
-		n := count[i]
-		nextcode[i] = code
-		code += n
-		code <<= 1
-	}
-
-	for i, n := range bits {
-		if n == 0 {
-			continue
-		}
-		code := nextcode[n]
-		nextcode[n]++
-		chunk := uint32(i<<huffmanValueShift | n)
-		reverse := int(reverseByte[code>>8]) | int(reverseByte[code&0xff])<<8
-		reverse >>= uint(16 - n)
-		if n <= huffmanChunkBits {
-			for off := reverse; off < huffmanNumChunks; off += 1 << uint(n) {
-				h.chunks[off] = chunk
-			}
-		} else {
-			value := h.chunks[reverse&(huffmanNumChunks-1)] >> huffmanValueShift
-			if value >= uint32(len(h.links)) {
-				return false
-			}
-			linktab := h.links[value]
-			reverse >>= huffmanChunkBits
-			for off := reverse; off < numLinks; off += 1 << uint(n-huffmanChunkBits) {
-				linktab[off] = chunk
-			}
-		}
-	}
-	return true
-}
-
-// The actual read interface needed by NewReader.
-// If the passed in io.Reader does not also have ReadByte,
-// the NewReader will introduce its own buffering.
-type Reader interface {
-	io.Reader
-	io.ByteReader
-}
-
-// Decompress state.
-type decompressor struct {
-	// Input source.
-	r       Reader
-	roffset int64
-	woffset int64
-
-	// Input bits, in top of b.
-	b  uint32
-	nb uint
-
-	// Huffman decoders for literal/length, distance.
-	h1, h2 huffmanDecoder
-
-	// Length arrays used to define Huffman codes.
-	bits     *[maxLit + maxDist]int
-	codebits *[numCodes]int
-
-	// Output history, buffer.
-	hist  *[maxHist]byte
-	hp    int  // current output position in buffer
-	hw    int  // have written hist[0:hw] already
-	hfull bool // buffer has filled at least once
-
-	// Temporary buffer (avoids repeated allocation).
-	buf [4]byte
-
-	// Next step in the decompression,
-	// and decompression state.
-	step     func(*decompressor)
-	final    bool
-	err      error
-	toRead   []byte
-	hl, hd   *huffmanDecoder
-	copyLen  int
-	copyDist int
-}
-
-func (f *decompressor) nextBlock() {
-	if f.final {
-		if f.hw != f.hp {
-			f.flush((*decompressor).nextBlock)
-			return
-		}
-		f.err = io.EOF
-		return
-	}
-	for f.nb < 1+2 {
-		if f.err = f.moreBits(); f.err != nil {
-			return
-		}
-	}
-	f.final = f.b&1 == 1
-	f.b >>= 1
-	typ := f.b & 3
-	f.b >>= 2
-	f.nb -= 1 + 2
-	switch typ {
-	case 0:
-		f.dataBlock()
-	case 1:
-		// compressed, fixed Huffman tables
-		f.hl = &fixedHuffmanDecoder
-		f.hd = nil
-		f.huffmanBlock()
-	case 2:
-		// compressed, dynamic Huffman tables
-		if f.err = f.readHuffman(); f.err != nil {
-			break
-		}
-		f.hl = &f.h1
-		f.hd = &f.h2
-		f.huffmanBlock()
-	default:
-		// 3 is reserved.
-		f.err = CorruptInputError(f.roffset)
-	}
-}
-
-func (f *decompressor) Read(b []byte) (int, error) {
-	for {
-		if len(f.toRead) > 0 {
-			n := copy(b, f.toRead)
-			f.toRead = f.toRead[n:]
-			return n, nil
-		}
-		if f.err != nil {
-			return 0, f.err
-		}
-		f.step(f)
-	}
-}
-
-func (f *decompressor) Close() error {
-	if f.err == io.EOF {
-		return nil
-	}
-	return f.err
-}
-
-// RFC 1951 section 3.2.7.
-// Compression with dynamic Huffman codes
-
-var codeOrder = [...]int{16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}
-
-func (f *decompressor) readHuffman() error {
-	// HLIT[5], HDIST[5], HCLEN[4].
-	for f.nb < 5+5+4 {
-		if err := f.moreBits(); err != nil {
-			return err
-		}
-	}
-	nlit := int(f.b&0x1F) + 257
-	if nlit > maxLit {
-		return CorruptInputError(f.roffset)
-	}
-	f.b >>= 5
-	ndist := int(f.b&0x1F) + 1
-	// maxDist is 32, so ndist is always valid.
-	f.b >>= 5
-	nclen := int(f.b&0xF) + 4
-	// numCodes is 19, so nclen is always valid.
-	f.b >>= 4
-	f.nb -= 5 + 5 + 4
-
-	// (HCLEN+4)*3 bits: code lengths in the magic codeOrder order.
-	for i := 0; i < nclen; i++ {
-		for f.nb < 3 {
-			if err := f.moreBits(); err != nil {
-				return err
-			}
-		}
-		f.codebits[codeOrder[i]] = int(f.b & 0x7)
-		f.b >>= 3
-		f.nb -= 3
-	}
-	for i := nclen; i < len(codeOrder); i++ {
-		f.codebits[codeOrder[i]] = 0
-	}
-	if !f.h1.init(f.codebits[0:]) {
-		return CorruptInputError(f.roffset)
-	}
-
-	// HLIT + 257 code lengths, HDIST + 1 code lengths,
-	// using the code length Huffman code.
-	for i, n := 0, nlit+ndist; i < n; {
-		x, err := f.huffSym(&f.h1)
-		if err != nil {
-			return err
-		}
-		if x < 16 {
-			// Actual length.
-			f.bits[i] = x
-			i++
-			continue
-		}
-		// Repeat previous length or zero.
-		var rep int
-		var nb uint
-		var b int
-		switch x {
-		default:
-			return InternalError("unexpected length code")
-		case 16:
-			rep = 3
-			nb = 2
-			if i == 0 {
-				return CorruptInputError(f.roffset)
-			}
-			b = f.bits[i-1]
-		case 17:
-			rep = 3
-			nb = 3
-			b = 0
-		case 18:
-			rep = 11
-			nb = 7
-			b = 0
-		}
-		for f.nb < nb {
-			if err := f.moreBits(); err != nil {
-				return err
-			}
-		}
-		rep += int(f.b & uint32(1<<nb-1))
-		f.b >>= nb
-		f.nb -= nb
-		if i+rep > n {
-			return CorruptInputError(f.roffset)
-		}
-		for j := 0; j < rep; j++ {
-			f.bits[i] = b
-			i++
-		}
-	}
-
-	if !f.h1.init(f.bits[0:nlit]) || !f.h2.init(f.bits[nlit:nlit+ndist]) {
-		return CorruptInputError(f.roffset)
-	}
-
-	return nil
-}
-
-// Decode a single Huffman block from f.
-// hl and hd are the Huffman states for the lit/length values
-// and the distance values, respectively.  If hd == nil, using the
-// fixed distance encoding associated with fixed Huffman blocks.
-func (f *decompressor) huffmanBlock() {
-	for {
-		v, err := f.huffSym(f.hl)
-		if err != nil {
-			f.err = err
-			return
-		}
-		var n uint // number of bits extra
-		var length int
-		switch {
-		case v < 256:
-			f.hist[f.hp] = byte(v)
-			f.hp++
-			if f.hp == len(f.hist) {
-				// After the flush, continue this loop.
-				f.flush((*decompressor).huffmanBlock)
-				return
-			}
-			continue
-		case v == 256:
-			// Done with huffman block; read next block.
-			f.step = (*decompressor).nextBlock
-			return
-		// otherwise, reference to older data
-		case v < 265:
-			length = v - (257 - 3)
-			n = 0
-		case v < 269:
-			length = v*2 - (265*2 - 11)
-			n = 1
-		case v < 273:
-			length = v*4 - (269*4 - 19)
-			n = 2
-		case v < 277:
-			length = v*8 - (273*8 - 35)
-			n = 3
-		case v < 281:
-			length = v*16 - (277*16 - 67)
-			n = 4
-		case v < 285:
-			length = v*32 - (281*32 - 131)
-			n = 5
-		default:
-			length = 258
-			n = 0
-		}
-		if n > 0 {
-			for f.nb < n {
-				if err = f.moreBits(); err != nil {
-					f.err = err
-					return
-				}
-			}
-			length += int(f.b & uint32(1<<n-1))
-			f.b >>= n
-			f.nb -= n
-		}
-
-		var dist int
-		if f.hd == nil {
-			for f.nb < 5 {
-				if err = f.moreBits(); err != nil {
-					f.err = err
-					return
-				}
-			}
-			dist = int(reverseByte[(f.b&0x1F)<<3])
-			f.b >>= 5
-			f.nb -= 5
-		} else {
-			if dist, err = f.huffSym(f.hd); err != nil {
-				f.err = err
-				return
-			}
-		}
-
-		switch {
-		case dist < 4:
-			dist++
-		case dist >= 30:
-			f.err = CorruptInputError(f.roffset)
-			return
-		default:
-			nb := uint(dist-2) >> 1
-			// have 1 bit in bottom of dist, need nb more.
-			extra := (dist & 1) << nb
-			for f.nb < nb {
-				if err = f.moreBits(); err != nil {
-					f.err = err
-					return
-				}
-			}
-			extra |= int(f.b & uint32(1<<nb-1))
-			f.b >>= nb
-			f.nb -= nb
-			dist = 1<<(nb+1) + 1 + extra
-		}
-
-		// Copy history[-dist:-dist+length] into output.
-		if dist > len(f.hist) {
-			f.err = InternalError("bad history distance")
-			return
-		}
-
-		// No check on length; encoding can be prescient.
-		if !f.hfull && dist > f.hp {
-			f.err = CorruptInputError(f.roffset)
-			return
-		}
-
-		f.copyLen, f.copyDist = length, dist
-		if f.copyHist() {
-			return
-		}
-	}
-}
-
-// copyHist copies f.copyLen bytes from f.hist (f.copyDist bytes ago) to itself.
-// It reports whether the f.hist buffer is full.
-func (f *decompressor) copyHist() bool {
-	p := f.hp - f.copyDist
-	if p < 0 {
-		p += len(f.hist)
-	}
-	for f.copyLen > 0 {
-		n := f.copyLen
-		if x := len(f.hist) - f.hp; n > x {
-			n = x
-		}
-		if x := len(f.hist) - p; n > x {
-			n = x
-		}
-		forwardCopy(f.hist[:], f.hp, p, n)
-		p += n
-		f.hp += n
-		f.copyLen -= n
-		if f.hp == len(f.hist) {
-			// After flush continue copying out of history.
-			f.flush((*decompressor).copyHuff)
-			return true
-		}
-		if p == len(f.hist) {
-			p = 0
-		}
-	}
-	return false
-}
-
-func (f *decompressor) copyHuff() {
-	if f.copyHist() {
-		return
-	}
-	f.huffmanBlock()
-}
-
-// Copy a single uncompressed data block from input to output.
-func (f *decompressor) dataBlock() {
-	// Uncompressed.
-	// Discard current half-byte.
-	f.nb = 0
-	f.b = 0
-
-	// Length then ones-complement of length.
-	nr, err := io.ReadFull(f.r, f.buf[0:4])
-	f.roffset += int64(nr)
-	if err != nil {
-		f.err = &ReadError{f.roffset, err}
-		return
-	}
-	n := int(f.buf[0]) | int(f.buf[1])<<8
-	nn := int(f.buf[2]) | int(f.buf[3])<<8
-	if uint16(nn) != uint16(^n) {
-		f.err = CorruptInputError(f.roffset)
-		return
-	}
-
-	if n == 0 {
-		// 0-length block means sync
-		f.flush((*decompressor).nextBlock)
-		return
-	}
-
-	f.copyLen = n
-	f.copyData()
-}
-
-// copyData copies f.copyLen bytes from the underlying reader into f.hist.
-// It pauses for reads when f.hist is full.
-func (f *decompressor) copyData() {
-	n := f.copyLen
-	for n > 0 {
-		m := len(f.hist) - f.hp
-		if m > n {
-			m = n
-		}
-		m, err := io.ReadFull(f.r, f.hist[f.hp:f.hp+m])
-		f.roffset += int64(m)
-		if err != nil {
-			f.err = &ReadError{f.roffset, err}
-			return
-		}
-		n -= m
-		f.hp += m
-		if f.hp == len(f.hist) {
-			f.copyLen = n
-			f.flush((*decompressor).copyData)
-			return
-		}
-	}
-	f.step = (*decompressor).nextBlock
-}
-
-func (f *decompressor) setDict(dict []byte) {
-	if len(dict) > len(f.hist) {
-		// Will only remember the tail.
-		dict = dict[len(dict)-len(f.hist):]
-	}
-
-	f.hp = copy(f.hist[:], dict)
-	if f.hp == len(f.hist) {
-		f.hp = 0
-		f.hfull = true
-	}
-	f.hw = f.hp
-}
-
-func (f *decompressor) moreBits() error {
-	c, err := f.r.ReadByte()
-	if err != nil {
-		if err == io.EOF {
-			err = io.ErrUnexpectedEOF
-		}
-		return err
-	}
-	f.roffset++
-	f.b |= uint32(c) << f.nb
-	f.nb += 8
-	return nil
-}
-
-// Read the next Huffman-encoded symbol from f according to h.
-func (f *decompressor) huffSym(h *huffmanDecoder) (int, error) {
-	n := uint(h.min)
-	for {
-		for f.nb < n {
-			if err := f.moreBits(); err != nil {
-				return 0, err
-			}
-		}
-		chunk := h.chunks[f.b&(huffmanNumChunks-1)]
-		n = uint(chunk & huffmanCountMask)
-		if n > huffmanChunkBits {
-			chunk = h.links[chunk>>huffmanValueShift][(f.b>>huffmanChunkBits)&h.linkMask]
-			n = uint(chunk & huffmanCountMask)
-			if n == 0 {
-				f.err = CorruptInputError(f.roffset)
-				return 0, f.err
-			}
-		}
-		if n <= f.nb {
-			f.b >>= n
-			f.nb -= n
-			return int(chunk >> huffmanValueShift), nil
-		}
-	}
-}
-
-// Flush any buffered output to the underlying writer.
-func (f *decompressor) flush(step func(*decompressor)) {
-	f.toRead = f.hist[f.hw:f.hp]
-	f.woffset += int64(f.hp - f.hw)
-	f.hw = f.hp
-	if f.hp == len(f.hist) {
-		f.hp = 0
-		f.hw = 0
-		f.hfull = true
-	}
-	f.step = step
-}
-
-func makeReader(r io.Reader) Reader {
-	if rr, ok := r.(Reader); ok {
-		return rr
-	}
-	return bufio.NewReader(r)
-}
-
-// NewReader returns a new ReadCloser that can be used
-// to read the uncompressed version of r.  It is the caller's
-// responsibility to call Close on the ReadCloser when
-// finished reading.
-func NewReader(r io.Reader) io.ReadCloser {
-	var f decompressor
-	f.bits = new([maxLit + maxDist]int)
-	f.codebits = new([numCodes]int)
-	f.r = makeReader(r)
-	f.hist = new([maxHist]byte)
-	f.step = (*decompressor).nextBlock
-	return &f
-}
-
-// NewReaderDict is like NewReader but initializes the reader
-// with a preset dictionary.  The returned Reader behaves as if
-// the uncompressed data stream started with the given dictionary,
-// which has already been read.  NewReaderDict is typically used
-// to read data compressed by NewWriterDict.
-func NewReaderDict(r io.Reader, dict []byte) io.ReadCloser {
-	var f decompressor
-	f.r = makeReader(r)
-	f.hist = new([maxHist]byte)
-	f.bits = new([maxLit + maxDist]int)
-	f.codebits = new([numCodes]int)
-	f.step = (*decompressor).nextBlock
-	f.setDict(dict)
-	return &f
-}
diff --git a/src/pkg/compress/gzip/gunzip.go b/src/pkg/compress/gzip/gunzip.go
deleted file mode 100644
index 4f398b1..0000000
--- a/src/pkg/compress/gzip/gunzip.go
+++ /dev/null
@@ -1,255 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package gzip implements reading and writing of gzip format compressed files,
-// as specified in RFC 1952.
-package gzip
-
-import (
-	"bufio"
-	"compress/flate"
-	"errors"
-	"hash"
-	"hash/crc32"
-	"io"
-	"time"
-)
-
-const (
-	gzipID1     = 0x1f
-	gzipID2     = 0x8b
-	gzipDeflate = 8
-	flagText    = 1 << 0
-	flagHdrCrc  = 1 << 1
-	flagExtra   = 1 << 2
-	flagName    = 1 << 3
-	flagComment = 1 << 4
-)
-
-func makeReader(r io.Reader) flate.Reader {
-	if rr, ok := r.(flate.Reader); ok {
-		return rr
-	}
-	return bufio.NewReader(r)
-}
-
-var (
-	// ErrChecksum is returned when reading GZIP data that has an invalid checksum.
-	ErrChecksum = errors.New("gzip: invalid checksum")
-	// ErrHeader is returned when reading GZIP data that has an invalid header.
-	ErrHeader = errors.New("gzip: invalid header")
-)
-
-// The gzip file stores a header giving metadata about the compressed file.
-// That header is exposed as the fields of the Writer and Reader structs.
-type Header struct {
-	Comment string    // comment
-	Extra   []byte    // "extra data"
-	ModTime time.Time // modification time
-	Name    string    // file name
-	OS      byte      // operating system type
-}
-
-// A Reader is an io.Reader that can be read to retrieve
-// uncompressed data from a gzip-format compressed file.
-//
-// In general, a gzip file can be a concatenation of gzip files,
-// each with its own header.  Reads from the Reader
-// return the concatenation of the uncompressed data of each.
-// Only the first header is recorded in the Reader fields.
-//
-// Gzip files store a length and checksum of the uncompressed data.
-// The Reader will return a ErrChecksum when Read
-// reaches the end of the uncompressed data if it does not
-// have the expected length or checksum.  Clients should treat data
-// returned by Read as tentative until they receive the io.EOF
-// marking the end of the data.
-type Reader struct {
-	Header
-	r            flate.Reader
-	decompressor io.ReadCloser
-	digest       hash.Hash32
-	size         uint32
-	flg          byte
-	buf          [512]byte
-	err          error
-}
-
-// NewReader creates a new Reader reading the given reader.
-// The implementation buffers input and may read more data than necessary from r.
-// It is the caller's responsibility to call Close on the Reader when done.
-func NewReader(r io.Reader) (*Reader, error) {
-	z := new(Reader)
-	z.r = makeReader(r)
-	z.digest = crc32.NewIEEE()
-	if err := z.readHeader(true); err != nil {
-		return nil, err
-	}
-	return z, nil
-}
-
-// Reset discards the Reader z's state and makes it equivalent to the
-// result of its original state from NewReader, but reading from r instead.
-// This permits reusing a Reader rather than allocating a new one.
-func (z *Reader) Reset(r io.Reader) error {
-	z.r = makeReader(r)
-	if z.digest == nil {
-		z.digest = crc32.NewIEEE()
-	} else {
-		z.digest.Reset()
-	}
-	z.size = 0
-	z.err = nil
-	return z.readHeader(true)
-}
-
-// GZIP (RFC 1952) is little-endian, unlike ZLIB (RFC 1950).
-func get4(p []byte) uint32 {
-	return uint32(p[0]) | uint32(p[1])<<8 | uint32(p[2])<<16 | uint32(p[3])<<24
-}
-
-func (z *Reader) readString() (string, error) {
-	var err error
-	needconv := false
-	for i := 0; ; i++ {
-		if i >= len(z.buf) {
-			return "", ErrHeader
-		}
-		z.buf[i], err = z.r.ReadByte()
-		if err != nil {
-			return "", err
-		}
-		if z.buf[i] > 0x7f {
-			needconv = true
-		}
-		if z.buf[i] == 0 {
-			// GZIP (RFC 1952) specifies that strings are NUL-terminated ISO 8859-1 (Latin-1).
-			if needconv {
-				s := make([]rune, 0, i)
-				for _, v := range z.buf[0:i] {
-					s = append(s, rune(v))
-				}
-				return string(s), nil
-			}
-			return string(z.buf[0:i]), nil
-		}
-	}
-}
-
-func (z *Reader) read2() (uint32, error) {
-	_, err := io.ReadFull(z.r, z.buf[0:2])
-	if err != nil {
-		return 0, err
-	}
-	return uint32(z.buf[0]) | uint32(z.buf[1])<<8, nil
-}
-
-func (z *Reader) readHeader(save bool) error {
-	_, err := io.ReadFull(z.r, z.buf[0:10])
-	if err != nil {
-		return err
-	}
-	if z.buf[0] != gzipID1 || z.buf[1] != gzipID2 || z.buf[2] != gzipDeflate {
-		return ErrHeader
-	}
-	z.flg = z.buf[3]
-	if save {
-		z.ModTime = time.Unix(int64(get4(z.buf[4:8])), 0)
-		// z.buf[8] is xfl, ignored
-		z.OS = z.buf[9]
-	}
-	z.digest.Reset()
-	z.digest.Write(z.buf[0:10])
-
-	if z.flg&flagExtra != 0 {
-		n, err := z.read2()
-		if err != nil {
-			return err
-		}
-		data := make([]byte, n)
-		if _, err = io.ReadFull(z.r, data); err != nil {
-			return err
-		}
-		if save {
-			z.Extra = data
-		}
-	}
-
-	var s string
-	if z.flg&flagName != 0 {
-		if s, err = z.readString(); err != nil {
-			return err
-		}
-		if save {
-			z.Name = s
-		}
-	}
-
-	if z.flg&flagComment != 0 {
-		if s, err = z.readString(); err != nil {
-			return err
-		}
-		if save {
-			z.Comment = s
-		}
-	}
-
-	if z.flg&flagHdrCrc != 0 {
-		n, err := z.read2()
-		if err != nil {
-			return err
-		}
-		sum := z.digest.Sum32() & 0xFFFF
-		if n != sum {
-			return ErrHeader
-		}
-	}
-
-	z.digest.Reset()
-	z.decompressor = flate.NewReader(z.r)
-	return nil
-}
-
-func (z *Reader) Read(p []byte) (n int, err error) {
-	if z.err != nil {
-		return 0, z.err
-	}
-	if len(p) == 0 {
-		return 0, nil
-	}
-
-	n, err = z.decompressor.Read(p)
-	z.digest.Write(p[0:n])
-	z.size += uint32(n)
-	if n != 0 || err != io.EOF {
-		z.err = err
-		return
-	}
-
-	// Finished file; check checksum + size.
-	if _, err := io.ReadFull(z.r, z.buf[0:8]); err != nil {
-		z.err = err
-		return 0, err
-	}
-	crc32, isize := get4(z.buf[0:4]), get4(z.buf[4:8])
-	sum := z.digest.Sum32()
-	if sum != crc32 || isize != z.size {
-		z.err = ErrChecksum
-		return 0, z.err
-	}
-
-	// File is ok; is there another?
-	if err = z.readHeader(false); err != nil {
-		z.err = err
-		return
-	}
-
-	// Yes.  Reset and read from it.
-	z.digest.Reset()
-	z.size = 0
-	return z.Read(p)
-}
-
-// Close closes the Reader. It does not close the underlying io.Reader.
-func (z *Reader) Close() error { return z.decompressor.Close() }
diff --git a/src/pkg/compress/gzip/gunzip_test.go b/src/pkg/compress/gzip/gunzip_test.go
deleted file mode 100644
index 2471038..0000000
--- a/src/pkg/compress/gzip/gunzip_test.go
+++ /dev/null
@@ -1,369 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package gzip
-
-import (
-	"bytes"
-	"io"
-	"io/ioutil"
-	"os"
-	"testing"
-	"time"
-)
-
-type gunzipTest struct {
-	name string
-	desc string
-	raw  string
-	gzip []byte
-	err  error
-}
-
-var gunzipTests = []gunzipTest{
-	{ // has 1 empty fixed-huffman block
-		"empty.txt",
-		"empty.txt",
-		"",
-		[]byte{
-			0x1f, 0x8b, 0x08, 0x08, 0xf7, 0x5e, 0x14, 0x4a,
-			0x00, 0x03, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e,
-			0x74, 0x78, 0x74, 0x00, 0x03, 0x00, 0x00, 0x00,
-			0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-		},
-		nil,
-	},
-	{ // has 1 non-empty fixed huffman block
-		"hello.txt",
-		"hello.txt",
-		"hello world\n",
-		[]byte{
-			0x1f, 0x8b, 0x08, 0x08, 0xc8, 0x58, 0x13, 0x4a,
-			0x00, 0x03, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x2e,
-			0x74, 0x78, 0x74, 0x00, 0xcb, 0x48, 0xcd, 0xc9,
-			0xc9, 0x57, 0x28, 0xcf, 0x2f, 0xca, 0x49, 0xe1,
-			0x02, 0x00, 0x2d, 0x3b, 0x08, 0xaf, 0x0c, 0x00,
-			0x00, 0x00,
-		},
-		nil,
-	},
-	{ // concatenation
-		"hello.txt",
-		"hello.txt x2",
-		"hello world\n" +
-			"hello world\n",
-		[]byte{
-			0x1f, 0x8b, 0x08, 0x08, 0xc8, 0x58, 0x13, 0x4a,
-			0x00, 0x03, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x2e,
-			0x74, 0x78, 0x74, 0x00, 0xcb, 0x48, 0xcd, 0xc9,
-			0xc9, 0x57, 0x28, 0xcf, 0x2f, 0xca, 0x49, 0xe1,
-			0x02, 0x00, 0x2d, 0x3b, 0x08, 0xaf, 0x0c, 0x00,
-			0x00, 0x00,
-			0x1f, 0x8b, 0x08, 0x08, 0xc8, 0x58, 0x13, 0x4a,
-			0x00, 0x03, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x2e,
-			0x74, 0x78, 0x74, 0x00, 0xcb, 0x48, 0xcd, 0xc9,
-			0xc9, 0x57, 0x28, 0xcf, 0x2f, 0xca, 0x49, 0xe1,
-			0x02, 0x00, 0x2d, 0x3b, 0x08, 0xaf, 0x0c, 0x00,
-			0x00, 0x00,
-		},
-		nil,
-	},
-	{ // has a fixed huffman block with some length-distance pairs
-		"shesells.txt",
-		"shesells.txt",
-		"she sells seashells by the seashore\n",
-		[]byte{
-			0x1f, 0x8b, 0x08, 0x08, 0x72, 0x66, 0x8b, 0x4a,
-			0x00, 0x03, 0x73, 0x68, 0x65, 0x73, 0x65, 0x6c,
-			0x6c, 0x73, 0x2e, 0x74, 0x78, 0x74, 0x00, 0x2b,
-			0xce, 0x48, 0x55, 0x28, 0x4e, 0xcd, 0xc9, 0x29,
-			0x06, 0x92, 0x89, 0xc5, 0x19, 0x60, 0x56, 0x52,
-			0xa5, 0x42, 0x09, 0x58, 0x18, 0x28, 0x90, 0x5f,
-			0x94, 0xca, 0x05, 0x00, 0x76, 0xb0, 0x3b, 0xeb,
-			0x24, 0x00, 0x00, 0x00,
-		},
-		nil,
-	},
-	{ // has dynamic huffman blocks
-		"gettysburg",
-		"gettysburg",
-		"  Four score and seven years ago our fathers brought forth on\n" +
-			"this continent, a new nation, conceived in Liberty, and dedicated\n" +
-			"to the proposition that all men are created equal.\n" +
-			"  Now we are engaged in a great Civil War, testing whether that\n" +
-			"nation, or any nation so conceived and so dedicated, can long\n" +
-			"endure.\n" +
-			"  We are met on a great battle-field of that war.\n" +
-			"  We have come to dedicate a portion of that field, as a final\n" +
-			"resting place for those who here gave their lives that that\n" +
-			"nation might live.  It is altogether fitting and proper that\n" +
-			"we should do this.\n" +
-			"  But, in a larger sense, we can not dedicate — we can not\n" +
-			"consecrate — we can not hallow — this ground.\n" +
-			"  The brave men, living and dead, who struggled here, have\n" +
-			"consecrated it, far above our poor power to add or detract.\n" +
-			"The world will little note, nor long remember what we say here,\n" +
-			"but it can never forget what they did here.\n" +
-			"  It is for us the living, rather, to be dedicated here to the\n" +
-			"unfinished work which they who fought here have thus far so\n" +
-			"nobly advanced.  It is rather for us to be here dedicated to\n" +
-			"the great task remaining before us — that from these honored\n" +
-			"dead we take increased devotion to that cause for which they\n" +
-			"gave the last full measure of devotion —\n" +
-			"  that we here highly resolve that these dead shall not have\n" +
-			"died in vain — that this nation, under God, shall have a new\n" +
-			"birth of freedom — and that government of the people, by the\n" +
-			"people, for the people, shall not perish from this earth.\n" +
-			"\n" +
-			"Abraham Lincoln, November 19, 1863, Gettysburg, Pennsylvania\n",
-		[]byte{
-			0x1f, 0x8b, 0x08, 0x08, 0xd1, 0x12, 0x2b, 0x4a,
-			0x00, 0x03, 0x67, 0x65, 0x74, 0x74, 0x79, 0x73,
-			0x62, 0x75, 0x72, 0x67, 0x00, 0x65, 0x54, 0xcd,
-			0x6e, 0xd4, 0x30, 0x10, 0xbe, 0xfb, 0x29, 0xe6,
-			0x01, 0x42, 0xa5, 0x0a, 0x09, 0xc1, 0x11, 0x90,
-			0x40, 0x48, 0xa8, 0xe2, 0x80, 0xd4, 0xf3, 0x24,
-			0x9e, 0x24, 0x56, 0xbd, 0x9e, 0xc5, 0x76, 0x76,
-			0x95, 0x1b, 0x0f, 0xc1, 0x13, 0xf2, 0x24, 0x7c,
-			0x63, 0x77, 0x9b, 0x4a, 0x5c, 0xaa, 0x6e, 0x6c,
-			0xcf, 0x7c, 0x7f, 0x33, 0x44, 0x5f, 0x74, 0xcb,
-			0x54, 0x26, 0xcd, 0x42, 0x9c, 0x3c, 0x15, 0xb9,
-			0x48, 0xa2, 0x5d, 0x38, 0x17, 0xe2, 0x45, 0xc9,
-			0x4e, 0x67, 0xae, 0xab, 0xe0, 0xf7, 0x98, 0x75,
-			0x5b, 0xd6, 0x4a, 0xb3, 0xe6, 0xba, 0x92, 0x26,
-			0x57, 0xd7, 0x50, 0x68, 0xd2, 0x54, 0x43, 0x92,
-			0x54, 0x07, 0x62, 0x4a, 0x72, 0xa5, 0xc4, 0x35,
-			0x68, 0x1a, 0xec, 0x60, 0x92, 0x70, 0x11, 0x4f,
-			0x21, 0xd1, 0xf7, 0x30, 0x4a, 0xae, 0xfb, 0xd0,
-			0x9a, 0x78, 0xf1, 0x61, 0xe2, 0x2a, 0xde, 0x55,
-			0x25, 0xd4, 0xa6, 0x73, 0xd6, 0xb3, 0x96, 0x60,
-			0xef, 0xf0, 0x9b, 0x2b, 0x71, 0x8c, 0x74, 0x02,
-			0x10, 0x06, 0xac, 0x29, 0x8b, 0xdd, 0x25, 0xf9,
-			0xb5, 0x71, 0xbc, 0x73, 0x44, 0x0f, 0x7a, 0xa5,
-			0xab, 0xb4, 0x33, 0x49, 0x0b, 0x2f, 0xbd, 0x03,
-			0xd3, 0x62, 0x17, 0xe9, 0x73, 0xb8, 0x84, 0x48,
-			0x8f, 0x9c, 0x07, 0xaa, 0x52, 0x00, 0x6d, 0xa1,
-			0xeb, 0x2a, 0xc6, 0xa0, 0x95, 0x76, 0x37, 0x78,
-			0x9a, 0x81, 0x65, 0x7f, 0x46, 0x4b, 0x45, 0x5f,
-			0xe1, 0x6d, 0x42, 0xe8, 0x01, 0x13, 0x5c, 0x38,
-			0x51, 0xd4, 0xb4, 0x38, 0x49, 0x7e, 0xcb, 0x62,
-			0x28, 0x1e, 0x3b, 0x82, 0x93, 0x54, 0x48, 0xf1,
-			0xd2, 0x7d, 0xe4, 0x5a, 0xa3, 0xbc, 0x99, 0x83,
-			0x44, 0x4f, 0x3a, 0x77, 0x36, 0x57, 0xce, 0xcf,
-			0x2f, 0x56, 0xbe, 0x80, 0x90, 0x9e, 0x84, 0xea,
-			0x51, 0x1f, 0x8f, 0xcf, 0x90, 0xd4, 0x60, 0xdc,
-			0x5e, 0xb4, 0xf7, 0x10, 0x0b, 0x26, 0xe0, 0xff,
-			0xc4, 0xd1, 0xe5, 0x67, 0x2e, 0xe7, 0xc8, 0x93,
-			0x98, 0x05, 0xb8, 0xa8, 0x45, 0xc0, 0x4d, 0x09,
-			0xdc, 0x84, 0x16, 0x2b, 0x0d, 0x9a, 0x21, 0x53,
-			0x04, 0x8b, 0xd2, 0x0b, 0xbd, 0xa2, 0x4c, 0xa7,
-			0x60, 0xee, 0xd9, 0xe1, 0x1d, 0xd1, 0xb7, 0x4a,
-			0x30, 0x8f, 0x63, 0xd5, 0xa5, 0x8b, 0x33, 0x87,
-			0xda, 0x1a, 0x18, 0x79, 0xf3, 0xe3, 0xa6, 0x17,
-			0x94, 0x2e, 0xab, 0x6e, 0xa0, 0xe3, 0xcd, 0xac,
-			0x50, 0x8c, 0xca, 0xa7, 0x0d, 0x76, 0x37, 0xd1,
-			0x23, 0xe7, 0x05, 0x57, 0x8b, 0xa4, 0x22, 0x83,
-			0xd9, 0x62, 0x52, 0x25, 0xad, 0x07, 0xbb, 0xbf,
-			0xbf, 0xff, 0xbc, 0xfa, 0xee, 0x20, 0x73, 0x91,
-			0x29, 0xff, 0x7f, 0x02, 0x71, 0x62, 0x84, 0xb5,
-			0xf6, 0xb5, 0x25, 0x6b, 0x41, 0xde, 0x92, 0xb7,
-			0x76, 0x3f, 0x91, 0x91, 0x31, 0x1b, 0x41, 0x84,
-			0x62, 0x30, 0x0a, 0x37, 0xa4, 0x5e, 0x18, 0x3a,
-			0x99, 0x08, 0xa5, 0xe6, 0x6d, 0x59, 0x22, 0xec,
-			0x33, 0x39, 0x86, 0x26, 0xf5, 0xab, 0x66, 0xc8,
-			0x08, 0x20, 0xcf, 0x0c, 0xd7, 0x47, 0x45, 0x21,
-			0x0b, 0xf6, 0x59, 0xd5, 0xfe, 0x5c, 0x8d, 0xaa,
-			0x12, 0x7b, 0x6f, 0xa1, 0xf0, 0x52, 0x33, 0x4f,
-			0xf5, 0xce, 0x59, 0xd3, 0xab, 0x66, 0x10, 0xbf,
-			0x06, 0xc4, 0x31, 0x06, 0x73, 0xd6, 0x80, 0xa2,
-			0x78, 0xc2, 0x45, 0xcb, 0x03, 0x65, 0x39, 0xc9,
-			0x09, 0xd1, 0x06, 0x04, 0x33, 0x1a, 0x5a, 0xf1,
-			0xde, 0x01, 0xb8, 0x71, 0x83, 0xc4, 0xb5, 0xb3,
-			0xc3, 0x54, 0x65, 0x33, 0x0d, 0x5a, 0xf7, 0x9b,
-			0x90, 0x7c, 0x27, 0x1f, 0x3a, 0x58, 0xa3, 0xd8,
-			0xfd, 0x30, 0x5f, 0xb7, 0xd2, 0x66, 0xa2, 0x93,
-			0x1c, 0x28, 0xb7, 0xe9, 0x1b, 0x0c, 0xe1, 0x28,
-			0x47, 0x26, 0xbb, 0xe9, 0x7d, 0x7e, 0xdc, 0x96,
-			0x10, 0x92, 0x50, 0x56, 0x7c, 0x06, 0xe2, 0x27,
-			0xb4, 0x08, 0xd3, 0xda, 0x7b, 0x98, 0x34, 0x73,
-			0x9f, 0xdb, 0xf6, 0x62, 0xed, 0x31, 0x41, 0x13,
-			0xd3, 0xa2, 0xa8, 0x4b, 0x3a, 0xc6, 0x1d, 0xe4,
-			0x2f, 0x8c, 0xf8, 0xfb, 0x97, 0x64, 0xf4, 0xb6,
-			0x2f, 0x80, 0x5a, 0xf3, 0x56, 0xe0, 0x40, 0x50,
-			0xd5, 0x19, 0xd0, 0x1e, 0xfc, 0xca, 0xe5, 0xc9,
-			0xd4, 0x60, 0x00, 0x81, 0x2e, 0xa3, 0xcc, 0xb6,
-			0x52, 0xf0, 0xb4, 0xdb, 0x69, 0x99, 0xce, 0x7a,
-			0x32, 0x4c, 0x08, 0xed, 0xaa, 0x10, 0x10, 0xe3,
-			0x6f, 0xee, 0x99, 0x68, 0x95, 0x9f, 0x04, 0x71,
-			0xb2, 0x49, 0x2f, 0x62, 0xa6, 0x5e, 0xb4, 0xef,
-			0x02, 0xed, 0x4f, 0x27, 0xde, 0x4a, 0x0f, 0xfd,
-			0xc1, 0xcc, 0xdd, 0x02, 0x8f, 0x08, 0x16, 0x54,
-			0xdf, 0xda, 0xca, 0xe0, 0x82, 0xf1, 0xb4, 0x31,
-			0x7a, 0xa9, 0x81, 0xfe, 0x90, 0xb7, 0x3e, 0xdb,
-			0xd3, 0x35, 0xc0, 0x20, 0x80, 0x33, 0x46, 0x4a,
-			0x63, 0xab, 0xd1, 0x0d, 0x29, 0xd2, 0xe2, 0x84,
-			0xb8, 0xdb, 0xfa, 0xe9, 0x89, 0x44, 0x86, 0x7c,
-			0xe8, 0x0b, 0xe6, 0x02, 0x6a, 0x07, 0x9b, 0x96,
-			0xd0, 0xdb, 0x2e, 0x41, 0x4c, 0xa1, 0xd5, 0x57,
-			0x45, 0x14, 0xfb, 0xe3, 0xa6, 0x72, 0x5b, 0x87,
-			0x6e, 0x0c, 0x6d, 0x5b, 0xce, 0xe0, 0x2f, 0xe2,
-			0x21, 0x81, 0x95, 0xb0, 0xe8, 0xb6, 0x32, 0x0b,
-			0xb2, 0x98, 0x13, 0x52, 0x5d, 0xfb, 0xec, 0x63,
-			0x17, 0x8a, 0x9e, 0x23, 0x22, 0x36, 0xee, 0xcd,
-			0xda, 0xdb, 0xcf, 0x3e, 0xf1, 0xc7, 0xf1, 0x01,
-			0x12, 0x93, 0x0a, 0xeb, 0x6f, 0xf2, 0x02, 0x15,
-			0x96, 0x77, 0x5d, 0xef, 0x9c, 0xfb, 0x88, 0x91,
-			0x59, 0xf9, 0x84, 0xdd, 0x9b, 0x26, 0x8d, 0x80,
-			0xf9, 0x80, 0x66, 0x2d, 0xac, 0xf7, 0x1f, 0x06,
-			0xba, 0x7f, 0xff, 0xee, 0xed, 0x40, 0x5f, 0xa5,
-			0xd6, 0xbd, 0x8c, 0x5b, 0x46, 0xd2, 0x7e, 0x48,
-			0x4a, 0x65, 0x8f, 0x08, 0x42, 0x60, 0xf7, 0x0f,
-			0xb9, 0x16, 0x0b, 0x0c, 0x1a, 0x06, 0x00, 0x00,
-		},
-		nil,
-	},
-	{ // has 1 non-empty fixed huffman block then garbage
-		"hello.txt",
-		"hello.txt + garbage",
-		"hello world\n",
-		[]byte{
-			0x1f, 0x8b, 0x08, 0x08, 0xc8, 0x58, 0x13, 0x4a,
-			0x00, 0x03, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x2e,
-			0x74, 0x78, 0x74, 0x00, 0xcb, 0x48, 0xcd, 0xc9,
-			0xc9, 0x57, 0x28, 0xcf, 0x2f, 0xca, 0x49, 0xe1,
-			0x02, 0x00, 0x2d, 0x3b, 0x08, 0xaf, 0x0c, 0x00,
-			0x00, 0x00, 'g', 'a', 'r', 'b', 'a', 'g', 'e', '!', '!', '!',
-		},
-		ErrHeader,
-	},
-	{ // has 1 non-empty fixed huffman block not enough header
-		"hello.txt",
-		"hello.txt + garbage",
-		"hello world\n",
-		[]byte{
-			0x1f, 0x8b, 0x08, 0x08, 0xc8, 0x58, 0x13, 0x4a,
-			0x00, 0x03, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x2e,
-			0x74, 0x78, 0x74, 0x00, 0xcb, 0x48, 0xcd, 0xc9,
-			0xc9, 0x57, 0x28, 0xcf, 0x2f, 0xca, 0x49, 0xe1,
-			0x02, 0x00, 0x2d, 0x3b, 0x08, 0xaf, 0x0c, 0x00,
-			0x00, 0x00, gzipID1,
-		},
-		io.ErrUnexpectedEOF,
-	},
-	{ // has 1 non-empty fixed huffman block but corrupt checksum
-		"hello.txt",
-		"hello.txt + corrupt checksum",
-		"hello world\n",
-		[]byte{
-			0x1f, 0x8b, 0x08, 0x08, 0xc8, 0x58, 0x13, 0x4a,
-			0x00, 0x03, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x2e,
-			0x74, 0x78, 0x74, 0x00, 0xcb, 0x48, 0xcd, 0xc9,
-			0xc9, 0x57, 0x28, 0xcf, 0x2f, 0xca, 0x49, 0xe1,
-			0x02, 0x00, 0xff, 0xff, 0xff, 0xff, 0x0c, 0x00,
-			0x00, 0x00,
-		},
-		ErrChecksum,
-	},
-	{ // has 1 non-empty fixed huffman block but corrupt size
-		"hello.txt",
-		"hello.txt + corrupt size",
-		"hello world\n",
-		[]byte{
-			0x1f, 0x8b, 0x08, 0x08, 0xc8, 0x58, 0x13, 0x4a,
-			0x00, 0x03, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x2e,
-			0x74, 0x78, 0x74, 0x00, 0xcb, 0x48, 0xcd, 0xc9,
-			0xc9, 0x57, 0x28, 0xcf, 0x2f, 0xca, 0x49, 0xe1,
-			0x02, 0x00, 0x2d, 0x3b, 0x08, 0xaf, 0xff, 0x00,
-			0x00, 0x00,
-		},
-		ErrChecksum,
-	},
-}
-
-func TestDecompressor(t *testing.T) {
-	b := new(bytes.Buffer)
-	for _, tt := range gunzipTests {
-		in := bytes.NewReader(tt.gzip)
-		gzip, err := NewReader(in)
-		if err != nil {
-			t.Errorf("%s: NewReader: %s", tt.name, err)
-			continue
-		}
-		defer gzip.Close()
-		if tt.name != gzip.Name {
-			t.Errorf("%s: got name %s", tt.name, gzip.Name)
-		}
-		b.Reset()
-		n, err := io.Copy(b, gzip)
-		if err != tt.err {
-			t.Errorf("%s: io.Copy: %v want %v", tt.name, err, tt.err)
-		}
-		s := b.String()
-		if s != tt.raw {
-			t.Errorf("%s: got %d-byte %q want %d-byte %q", tt.name, n, s, len(tt.raw), tt.raw)
-		}
-
-		// Test Reader Reset.
-		in = bytes.NewReader(tt.gzip)
-		err = gzip.Reset(in)
-		if err != nil {
-			t.Errorf("%s: Reset: %s", tt.name, err)
-			continue
-		}
-		if tt.name != gzip.Name {
-			t.Errorf("%s: got name %s", tt.name, gzip.Name)
-		}
-		b.Reset()
-		n, err = io.Copy(b, gzip)
-		if err != tt.err {
-			t.Errorf("%s: io.Copy: %v want %v", tt.name, err, tt.err)
-		}
-		s = b.String()
-		if s != tt.raw {
-			t.Errorf("%s: got %d-byte %q want %d-byte %q", tt.name, n, s, len(tt.raw), tt.raw)
-		}
-	}
-}
-
-func TestIssue6550(t *testing.T) {
-	f, err := os.Open("testdata/issue6550.gz")
-	if err != nil {
-		t.Fatal(err)
-	}
-	gzip, err := NewReader(f)
-	if err != nil {
-		t.Fatalf("NewReader(testdata/issue6550.gz): %v", err)
-	}
-	defer gzip.Close()
-	done := make(chan bool, 1)
-	go func() {
-		_, err := io.Copy(ioutil.Discard, gzip)
-		if err == nil {
-			t.Errorf("Copy succeeded")
-		} else {
-			t.Logf("Copy failed (correctly): %v", err)
-		}
-		done <- true
-	}()
-	select {
-	case <-time.After(1 * time.Second):
-		t.Errorf("Copy hung")
-	case <-done:
-		// ok
-	}
-}
-
-func TestInitialReset(t *testing.T) {
-	var r Reader
-	if err := r.Reset(bytes.NewReader(gunzipTests[1].gzip)); err != nil {
-		t.Error(err)
-	}
-	var buf bytes.Buffer
-	if _, err := io.Copy(&buf, &r); err != nil {
-		t.Error(err)
-	}
-	if s := buf.String(); s != gunzipTests[1].raw {
-		t.Errorf("got %q want %q", s, gunzipTests[1].raw)
-	}
-}
diff --git a/src/pkg/compress/lzw/reader.go b/src/pkg/compress/lzw/reader.go
deleted file mode 100644
index ef59699..0000000
--- a/src/pkg/compress/lzw/reader.go
+++ /dev/null
@@ -1,253 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package lzw implements the Lempel-Ziv-Welch compressed data format,
-// described in T. A. Welch, ``A Technique for High-Performance Data
-// Compression'', Computer, 17(6) (June 1984), pp 8-19.
-//
-// In particular, it implements LZW as used by the GIF, TIFF and PDF file
-// formats, which means variable-width codes up to 12 bits and the first
-// two non-literal codes are a clear code and an EOF code.
-package lzw
-
-// TODO(nigeltao): check that TIFF and PDF use LZW in the same way as GIF,
-// modulo LSB/MSB packing order.
-
-import (
-	"bufio"
-	"errors"
-	"fmt"
-	"io"
-)
-
-// Order specifies the bit ordering in an LZW data stream.
-type Order int
-
-const (
-	// LSB means Least Significant Bits first, as used in the GIF file format.
-	LSB Order = iota
-	// MSB means Most Significant Bits first, as used in the TIFF and PDF
-	// file formats.
-	MSB
-)
-
-const (
-	maxWidth           = 12
-	decoderInvalidCode = 0xffff
-	flushBuffer        = 1 << maxWidth
-)
-
-// decoder is the state from which the readXxx method converts a byte
-// stream into a code stream.
-type decoder struct {
-	r        io.ByteReader
-	bits     uint32
-	nBits    uint
-	width    uint
-	read     func(*decoder) (uint16, error) // readLSB or readMSB
-	litWidth int                            // width in bits of literal codes
-	err      error
-
-	// The first 1<<litWidth codes are literal codes.
-	// The next two codes mean clear and EOF.
-	// Other valid codes are in the range [lo, hi] where lo := clear + 2,
-	// with the upper bound incrementing on each code seen.
-	// overflow is the code at which hi overflows the code width.
-	// last is the most recently seen code, or decoderInvalidCode.
-	clear, eof, hi, overflow, last uint16
-
-	// Each code c in [lo, hi] expands to two or more bytes. For c != hi:
-	//   suffix[c] is the last of these bytes.
-	//   prefix[c] is the code for all but the last byte.
-	//   This code can either be a literal code or another code in [lo, c).
-	// The c == hi case is a special case.
-	suffix [1 << maxWidth]uint8
-	prefix [1 << maxWidth]uint16
-
-	// output is the temporary output buffer.
-	// Literal codes are accumulated from the start of the buffer.
-	// Non-literal codes decode to a sequence of suffixes that are first
-	// written right-to-left from the end of the buffer before being copied
-	// to the start of the buffer.
-	// It is flushed when it contains >= 1<<maxWidth bytes,
-	// so that there is always room to decode an entire code.
-	output [2 * 1 << maxWidth]byte
-	o      int    // write index into output
-	toRead []byte // bytes to return from Read
-}
-
-// readLSB returns the next code for "Least Significant Bits first" data.
-func (d *decoder) readLSB() (uint16, error) {
-	for d.nBits < d.width {
-		x, err := d.r.ReadByte()
-		if err != nil {
-			return 0, err
-		}
-		d.bits |= uint32(x) << d.nBits
-		d.nBits += 8
-	}
-	code := uint16(d.bits & (1<<d.width - 1))
-	d.bits >>= d.width
-	d.nBits -= d.width
-	return code, nil
-}
-
-// readMSB returns the next code for "Most Significant Bits first" data.
-func (d *decoder) readMSB() (uint16, error) {
-	for d.nBits < d.width {
-		x, err := d.r.ReadByte()
-		if err != nil {
-			return 0, err
-		}
-		d.bits |= uint32(x) << (24 - d.nBits)
-		d.nBits += 8
-	}
-	code := uint16(d.bits >> (32 - d.width))
-	d.bits <<= d.width
-	d.nBits -= d.width
-	return code, nil
-}
-
-func (d *decoder) Read(b []byte) (int, error) {
-	for {
-		if len(d.toRead) > 0 {
-			n := copy(b, d.toRead)
-			d.toRead = d.toRead[n:]
-			return n, nil
-		}
-		if d.err != nil {
-			return 0, d.err
-		}
-		d.decode()
-	}
-}
-
-// decode decompresses bytes from r and leaves them in d.toRead.
-// read specifies how to decode bytes into codes.
-// litWidth is the width in bits of literal codes.
-func (d *decoder) decode() {
-	// Loop over the code stream, converting codes into decompressed bytes.
-	for {
-		code, err := d.read(d)
-		if err != nil {
-			if err == io.EOF {
-				err = io.ErrUnexpectedEOF
-			}
-			d.err = err
-			return
-		}
-		switch {
-		case code < d.clear:
-			// We have a literal code.
-			d.output[d.o] = uint8(code)
-			d.o++
-			if d.last != decoderInvalidCode {
-				// Save what the hi code expands to.
-				d.suffix[d.hi] = uint8(code)
-				d.prefix[d.hi] = d.last
-			}
-		case code == d.clear:
-			d.width = 1 + uint(d.litWidth)
-			d.hi = d.eof
-			d.overflow = 1 << d.width
-			d.last = decoderInvalidCode
-			continue
-		case code == d.eof:
-			d.flush()
-			d.err = io.EOF
-			return
-		case code <= d.hi:
-			c, i := code, len(d.output)-1
-			if code == d.hi {
-				// code == hi is a special case which expands to the last expansion
-				// followed by the head of the last expansion. To find the head, we walk
-				// the prefix chain until we find a literal code.
-				c = d.last
-				for c >= d.clear {
-					c = d.prefix[c]
-				}
-				d.output[i] = uint8(c)
-				i--
-				c = d.last
-			}
-			// Copy the suffix chain into output and then write that to w.
-			for c >= d.clear {
-				d.output[i] = d.suffix[c]
-				i--
-				c = d.prefix[c]
-			}
-			d.output[i] = uint8(c)
-			d.o += copy(d.output[d.o:], d.output[i:])
-			if d.last != decoderInvalidCode {
-				// Save what the hi code expands to.
-				d.suffix[d.hi] = uint8(c)
-				d.prefix[d.hi] = d.last
-			}
-		default:
-			d.err = errors.New("lzw: invalid code")
-			return
-		}
-		d.last, d.hi = code, d.hi+1
-		if d.hi >= d.overflow {
-			if d.width == maxWidth {
-				d.last = decoderInvalidCode
-			} else {
-				d.width++
-				d.overflow <<= 1
-			}
-		}
-		if d.o >= flushBuffer {
-			d.flush()
-			return
-		}
-	}
-}
-
-func (d *decoder) flush() {
-	d.toRead = d.output[:d.o]
-	d.o = 0
-}
-
-var errClosed = errors.New("compress/lzw: reader/writer is closed")
-
-func (d *decoder) Close() error {
-	d.err = errClosed // in case any Reads come along
-	return nil
-}
-
-// NewReader creates a new io.ReadCloser.
-// Reads from the returned io.ReadCloser read and decompress data from r.
-// It is the caller's responsibility to call Close on the ReadCloser when
-// finished reading.
-// The number of bits to use for literal codes, litWidth, must be in the
-// range [2,8] and is typically 8.
-func NewReader(r io.Reader, order Order, litWidth int) io.ReadCloser {
-	d := new(decoder)
-	switch order {
-	case LSB:
-		d.read = (*decoder).readLSB
-	case MSB:
-		d.read = (*decoder).readMSB
-	default:
-		d.err = errors.New("lzw: unknown order")
-		return d
-	}
-	if litWidth < 2 || 8 < litWidth {
-		d.err = fmt.Errorf("lzw: litWidth %d out of range", litWidth)
-		return d
-	}
-	if br, ok := r.(io.ByteReader); ok {
-		d.r = br
-	} else {
-		d.r = bufio.NewReader(r)
-	}
-	d.litWidth = litWidth
-	d.width = 1 + uint(litWidth)
-	d.clear = uint16(1) << uint(litWidth)
-	d.eof, d.hi = d.clear+1, d.clear+1
-	d.overflow = uint16(1) << d.width
-	d.last = decoderInvalidCode
-
-	return d
-}
diff --git a/src/pkg/compress/zlib/reader.go b/src/pkg/compress/zlib/reader.go
deleted file mode 100644
index 9e1aafd..0000000
--- a/src/pkg/compress/zlib/reader.go
+++ /dev/null
@@ -1,132 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-/*
-Package zlib implements reading and writing of zlib format compressed data,
-as specified in RFC 1950.
-
-The implementation provides filters that uncompress during reading
-and compress during writing.  For example, to write compressed data
-to a buffer:
-
-	var b bytes.Buffer
-	w := zlib.NewWriter(&b)
-	w.Write([]byte("hello, world\n"))
-	w.Close()
-
-and to read that data back:
-
-	r, err := zlib.NewReader(&b)
-	io.Copy(os.Stdout, r)
-	r.Close()
-*/
-package zlib
-
-import (
-	"bufio"
-	"compress/flate"
-	"errors"
-	"hash"
-	"hash/adler32"
-	"io"
-)
-
-const zlibDeflate = 8
-
-var (
-	// ErrChecksum is returned when reading ZLIB data that has an invalid checksum.
-	ErrChecksum = errors.New("zlib: invalid checksum")
-	// ErrDictionary is returned when reading ZLIB data that has an invalid dictionary.
-	ErrDictionary = errors.New("zlib: invalid dictionary")
-	// ErrHeader is returned when reading ZLIB data that has an invalid header.
-	ErrHeader = errors.New("zlib: invalid header")
-)
-
-type reader struct {
-	r            flate.Reader
-	decompressor io.ReadCloser
-	digest       hash.Hash32
-	err          error
-	scratch      [4]byte
-}
-
-// NewReader creates a new io.ReadCloser.
-// Reads from the returned io.ReadCloser read and decompress data from r.
-// The implementation buffers input and may read more data than necessary from r.
-// It is the caller's responsibility to call Close on the ReadCloser when done.
-func NewReader(r io.Reader) (io.ReadCloser, error) {
-	return NewReaderDict(r, nil)
-}
-
-// NewReaderDict is like NewReader but uses a preset dictionary.
-// NewReaderDict ignores the dictionary if the compressed data does not refer to it.
-func NewReaderDict(r io.Reader, dict []byte) (io.ReadCloser, error) {
-	z := new(reader)
-	if fr, ok := r.(flate.Reader); ok {
-		z.r = fr
-	} else {
-		z.r = bufio.NewReader(r)
-	}
-	_, err := io.ReadFull(z.r, z.scratch[0:2])
-	if err != nil {
-		return nil, err
-	}
-	h := uint(z.scratch[0])<<8 | uint(z.scratch[1])
-	if (z.scratch[0]&0x0f != zlibDeflate) || (h%31 != 0) {
-		return nil, ErrHeader
-	}
-	if z.scratch[1]&0x20 != 0 {
-		_, err = io.ReadFull(z.r, z.scratch[0:4])
-		if err != nil {
-			return nil, err
-		}
-		checksum := uint32(z.scratch[0])<<24 | uint32(z.scratch[1])<<16 | uint32(z.scratch[2])<<8 | uint32(z.scratch[3])
-		if checksum != adler32.Checksum(dict) {
-			return nil, ErrDictionary
-		}
-		z.decompressor = flate.NewReaderDict(z.r, dict)
-	} else {
-		z.decompressor = flate.NewReader(z.r)
-	}
-	z.digest = adler32.New()
-	return z, nil
-}
-
-func (z *reader) Read(p []byte) (n int, err error) {
-	if z.err != nil {
-		return 0, z.err
-	}
-	if len(p) == 0 {
-		return 0, nil
-	}
-
-	n, err = z.decompressor.Read(p)
-	z.digest.Write(p[0:n])
-	if n != 0 || err != io.EOF {
-		z.err = err
-		return
-	}
-
-	// Finished file; check checksum.
-	if _, err := io.ReadFull(z.r, z.scratch[0:4]); err != nil {
-		z.err = err
-		return 0, err
-	}
-	// ZLIB (RFC 1950) is big-endian, unlike GZIP (RFC 1952).
-	checksum := uint32(z.scratch[0])<<24 | uint32(z.scratch[1])<<16 | uint32(z.scratch[2])<<8 | uint32(z.scratch[3])
-	if checksum != z.digest.Sum32() {
-		z.err = ErrChecksum
-		return 0, z.err
-	}
-	return
-}
-
-// Calling Close does not close the wrapped io.Reader originally passed to NewReader.
-func (z *reader) Close() error {
-	if z.err != nil {
-		return z.err
-	}
-	z.err = z.decompressor.Close()
-	return z.err
-}
diff --git a/src/pkg/crypto/aes/asm_amd64.s b/src/pkg/crypto/aes/asm_amd64.s
deleted file mode 100644
index 5c22881..0000000
--- a/src/pkg/crypto/aes/asm_amd64.s
+++ /dev/null
@@ -1,289 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../../cmd/ld/textflag.h"
-
-// func hasAsm() bool
-// returns whether AES-NI is supported
-TEXT ·hasAsm(SB),NOSPLIT,$0
-	XORQ AX, AX
-	INCL AX
-	CPUID
-	SHRQ $25, CX
-	ANDQ $1, CX
-	MOVB CX, ret+0(FP)
-	RET
-
-// func encryptBlockAsm(nr int, xk *uint32, dst, src *byte)
-TEXT ·encryptBlockAsm(SB),NOSPLIT,$0
-	MOVQ nr+0(FP), CX
-	MOVQ xk+8(FP), AX
-	MOVQ dst+16(FP), DX
-	MOVQ src+24(FP), BX
-	MOVUPS 0(AX), X1
-	MOVUPS 0(BX), X0
-	ADDQ $16, AX
-	PXOR X1, X0
-	SUBQ $12, CX
-	JE Lenc196
-	JB Lenc128
-Lenc256:
-	MOVUPS 0(AX), X1
-	AESENC X1, X0
-	MOVUPS 16(AX), X1
-	AESENC X1, X0
-	ADDQ $32, AX
-Lenc196:
-	MOVUPS 0(AX), X1
-	AESENC X1, X0
-	MOVUPS 16(AX), X1
-	AESENC X1, X0
-	ADDQ $32, AX
-Lenc128:
-	MOVUPS 0(AX), X1
-	AESENC X1, X0
-	MOVUPS 16(AX), X1
-	AESENC X1, X0
-	MOVUPS 32(AX), X1
-	AESENC X1, X0
-	MOVUPS 48(AX), X1
-	AESENC X1, X0
-	MOVUPS 64(AX), X1
-	AESENC X1, X0
-	MOVUPS 80(AX), X1
-	AESENC X1, X0
-	MOVUPS 96(AX), X1
-	AESENC X1, X0
-	MOVUPS 112(AX), X1
-	AESENC X1, X0
-	MOVUPS 128(AX), X1
-	AESENC X1, X0
-	MOVUPS 144(AX), X1
-	AESENCLAST X1, X0
-	MOVUPS X0, 0(DX)
-	RET
-
-// func decryptBlockAsm(nr int, xk *uint32, dst, src *byte)
-TEXT ·decryptBlockAsm(SB),NOSPLIT,$0
-	MOVQ nr+0(FP), CX
-	MOVQ xk+8(FP), AX
-	MOVQ dst+16(FP), DX
-	MOVQ src+24(FP), BX
-	MOVUPS 0(AX), X1
-	MOVUPS 0(BX), X0
-	ADDQ $16, AX
-	PXOR X1, X0
-	SUBQ $12, CX
-	JE Ldec196
-	JB Ldec128
-Ldec256:
-	MOVUPS 0(AX), X1
-	AESDEC X1, X0
-	MOVUPS 16(AX), X1
-	AESDEC X1, X0
-	ADDQ $32, AX
-Ldec196:
-	MOVUPS 0(AX), X1
-	AESDEC X1, X0
-	MOVUPS 16(AX), X1
-	AESDEC X1, X0
-	ADDQ $32, AX
-Ldec128:
-	MOVUPS 0(AX), X1
-	AESDEC X1, X0
-	MOVUPS 16(AX), X1
-	AESDEC X1, X0
-	MOVUPS 32(AX), X1
-	AESDEC X1, X0
-	MOVUPS 48(AX), X1
-	AESDEC X1, X0
-	MOVUPS 64(AX), X1
-	AESDEC X1, X0
-	MOVUPS 80(AX), X1
-	AESDEC X1, X0
-	MOVUPS 96(AX), X1
-	AESDEC X1, X0
-	MOVUPS 112(AX), X1
-	AESDEC X1, X0
-	MOVUPS 128(AX), X1
-	AESDEC X1, X0
-	MOVUPS 144(AX), X1
-	AESDECLAST X1, X0
-	MOVUPS X0, 0(DX)
-	RET
-
-// func expandKeyAsm(nr int, key *byte, enc, dec *uint32) {
-// Note that round keys are stored in uint128 format, not uint32
-TEXT ·expandKeyAsm(SB),NOSPLIT,$0
-	MOVQ nr+0(FP), CX
-	MOVQ key+8(FP), AX
-	MOVQ enc+16(FP), BX
-	MOVQ dec+24(FP), DX
-	MOVUPS (AX), X0
-	// enc
-	MOVUPS X0, (BX)
-	ADDQ $16, BX
-	PXOR X4, X4 // _expand_key_* expect X4 to be zero
-	CMPL CX, $12
-	JE Lexp_enc196
-	JB Lexp_enc128
-Lexp_enc256:
-	MOVUPS 16(AX), X2
-	MOVUPS X2, (BX)
-	ADDQ $16, BX
-	AESKEYGENASSIST $0x01, X2, X1
-	CALL _expand_key_256a<>(SB)
-	AESKEYGENASSIST $0x01, X0, X1
-	CALL _expand_key_256b<>(SB)
-	AESKEYGENASSIST $0x02, X2, X1
-	CALL _expand_key_256a<>(SB)
-	AESKEYGENASSIST $0x02, X0, X1
-	CALL _expand_key_256b<>(SB)
-	AESKEYGENASSIST $0x04, X2, X1
-	CALL _expand_key_256a<>(SB)
-	AESKEYGENASSIST $0x04, X0, X1
-	CALL _expand_key_256b<>(SB)
-	AESKEYGENASSIST $0x08, X2, X1
-	CALL _expand_key_256a<>(SB)
-	AESKEYGENASSIST $0x08, X0, X1
-	CALL _expand_key_256b<>(SB)
-	AESKEYGENASSIST $0x10, X2, X1
-	CALL _expand_key_256a<>(SB)
-	AESKEYGENASSIST $0x10, X0, X1
-	CALL _expand_key_256b<>(SB)
-	AESKEYGENASSIST $0x20, X2, X1
-	CALL _expand_key_256a<>(SB)
-	AESKEYGENASSIST $0x20, X0, X1
-	CALL _expand_key_256b<>(SB)
-	AESKEYGENASSIST $0x40, X2, X1
-	CALL _expand_key_256a<>(SB)
-	JMP Lexp_dec
-Lexp_enc196:
-	MOVQ 16(AX), X2
-	AESKEYGENASSIST $0x01, X2, X1
-	CALL _expand_key_192a<>(SB)
-	AESKEYGENASSIST $0x02, X2, X1
-	CALL _expand_key_192b<>(SB)
-	AESKEYGENASSIST $0x04, X2, X1
-	CALL _expand_key_192a<>(SB)
-	AESKEYGENASSIST $0x08, X2, X1
-	CALL _expand_key_192b<>(SB)
-	AESKEYGENASSIST $0x10, X2, X1
-	CALL _expand_key_192a<>(SB)
-	AESKEYGENASSIST $0x20, X2, X1
-	CALL _expand_key_192b<>(SB)
-	AESKEYGENASSIST $0x40, X2, X1
-	CALL _expand_key_192a<>(SB)
-	AESKEYGENASSIST $0x80, X2, X1
-	CALL _expand_key_192b<>(SB)
-	JMP Lexp_dec
-Lexp_enc128:
-	AESKEYGENASSIST $0x01, X0, X1
-	CALL _expand_key_128<>(SB)
-	AESKEYGENASSIST $0x02, X0, X1
-	CALL _expand_key_128<>(SB)
-	AESKEYGENASSIST $0x04, X0, X1
-	CALL _expand_key_128<>(SB)
-	AESKEYGENASSIST $0x08, X0, X1
-	CALL _expand_key_128<>(SB)
-	AESKEYGENASSIST $0x10, X0, X1
-	CALL _expand_key_128<>(SB)
-	AESKEYGENASSIST $0x20, X0, X1
-	CALL _expand_key_128<>(SB)
-	AESKEYGENASSIST $0x40, X0, X1
-	CALL _expand_key_128<>(SB)
-	AESKEYGENASSIST $0x80, X0, X1
-	CALL _expand_key_128<>(SB)
-	AESKEYGENASSIST $0x1b, X0, X1
-	CALL _expand_key_128<>(SB)
-	AESKEYGENASSIST $0x36, X0, X1
-	CALL _expand_key_128<>(SB)
-Lexp_dec:
-	// dec
-	SUBQ $16, BX
-	MOVUPS (BX), X1
-	MOVUPS X1, (DX)
-	DECQ CX
-Lexp_dec_loop:
-	MOVUPS -16(BX), X1
-	AESIMC X1, X0
-	MOVUPS X0, 16(DX)
-	SUBQ $16, BX
-	ADDQ $16, DX
-	DECQ CX
-	JNZ Lexp_dec_loop
-	MOVUPS -16(BX), X0
-	MOVUPS X0, 16(DX)
-	RET
-
-#define PSHUFD_X0_X0_ BYTE $0x66; BYTE $0x0f; BYTE $0x70; BYTE $0xc0
-#define PSHUFD_X1_X1_ BYTE $0x66; BYTE $0x0f; BYTE $0x70; BYTE $0xc9
-TEXT _expand_key_128<>(SB),NOSPLIT,$0
-	PSHUFD $0xff, X1, X1
-	SHUFPS $0x10, X0, X4
-	PXOR X4, X0
-	SHUFPS $0x8c, X0, X4
-	PXOR X4, X0
-	PXOR X1, X0
-	MOVUPS X0, (BX)
-	ADDQ $16, BX
-	RET
-
-#define PSLLDQ_X5_ BYTE $0x66; BYTE $0x0f; BYTE $0x73; BYTE $0xfd
-#define PSHUFD_X0_X3_ BYTE $0x66; BYTE $0x0f; BYTE $0x70; BYTE $0xd8
-TEXT _expand_key_192a<>(SB),NOSPLIT,$0
-	PSHUFD $0x55, X1, X1
-	SHUFPS $0x10, X0, X4
-	PXOR X4, X0
-	SHUFPS $0x8c, X0, X4
-	PXOR X4, X0
-	PXOR X1, X0
-
-	MOVAPS X2, X5
-	MOVAPS X2, X6
-	PSLLDQ_X5_; BYTE $0x4
-	PSHUFD $0xff, X0, X3
-	PXOR X3, X2
-	PXOR X5, X2
-
-	MOVAPS X0, X1
-	SHUFPS $0x44, X0, X6
-	MOVUPS X6, (BX)
-	SHUFPS $0x4e, X2, X1
-	MOVUPS X1, 16(BX)
-	ADDQ $32, BX
-	RET
-
-TEXT _expand_key_192b<>(SB),NOSPLIT,$0
-	PSHUFD $0x55, X1, X1
-	SHUFPS $0x10, X0, X4
-	PXOR X4, X0
-	SHUFPS $0x8c, X0, X4
-	PXOR X4, X0
-	PXOR X1, X0
-
-	MOVAPS X2, X5
-	PSLLDQ_X5_; BYTE $0x4
-	PSHUFD $0xff, X0, X3
-	PXOR X3, X2
-	PXOR X5, X2
-
-	MOVUPS X0, (BX)
-	ADDQ $16, BX
-	RET
-
-TEXT _expand_key_256a<>(SB),NOSPLIT,$0
-	JMP _expand_key_128<>(SB)
-
-TEXT _expand_key_256b<>(SB),NOSPLIT,$0
-	PSHUFD $0xaa, X1, X1
-	SHUFPS $0x10, X2, X4
-	PXOR X4, X2
-	SHUFPS $0x8c, X2, X4
-	PXOR X4, X2
-	PXOR X1, X2
-
-	MOVUPS X2, (BX)
-	ADDQ $16, BX
-	RET
diff --git a/src/pkg/crypto/cipher/cfb_test.go b/src/pkg/crypto/cipher/cfb_test.go
deleted file mode 100644
index ec708ab..0000000
--- a/src/pkg/crypto/cipher/cfb_test.go
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package cipher_test
-
-import (
-	"bytes"
-	"crypto/aes"
-	"crypto/cipher"
-	"crypto/rand"
-	"testing"
-)
-
-func TestCFB(t *testing.T) {
-	block, err := aes.NewCipher(commonKey128)
-	if err != nil {
-		t.Error(err)
-		return
-	}
-
-	plaintext := []byte("this is the plaintext. this is the plaintext.")
-	iv := make([]byte, block.BlockSize())
-	rand.Reader.Read(iv)
-	cfb := cipher.NewCFBEncrypter(block, iv)
-	ciphertext := make([]byte, len(plaintext))
-	copy(ciphertext, plaintext)
-	cfb.XORKeyStream(ciphertext, ciphertext)
-
-	cfbdec := cipher.NewCFBDecrypter(block, iv)
-	plaintextCopy := make([]byte, len(plaintext))
-	copy(plaintextCopy, ciphertext)
-	cfbdec.XORKeyStream(plaintextCopy, plaintextCopy)
-
-	if !bytes.Equal(plaintextCopy, plaintext) {
-		t.Errorf("got: %x, want: %x", plaintextCopy, plaintext)
-	}
-}
diff --git a/src/pkg/crypto/cipher/example_test.go b/src/pkg/crypto/cipher/example_test.go
deleted file mode 100644
index 373f679..0000000
--- a/src/pkg/crypto/cipher/example_test.go
+++ /dev/null
@@ -1,283 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package cipher_test
-
-import (
-	"crypto/aes"
-	"crypto/cipher"
-	"crypto/rand"
-	"encoding/hex"
-	"fmt"
-	"io"
-	"os"
-)
-
-func ExampleNewCBCDecrypter() {
-	key := []byte("example key 1234")
-	ciphertext, _ := hex.DecodeString("f363f3ccdcb12bb883abf484ba77d9cd7d32b5baecb3d4b1b3e0e4beffdb3ded")
-
-	block, err := aes.NewCipher(key)
-	if err != nil {
-		panic(err)
-	}
-
-	// The IV needs to be unique, but not secure. Therefore it's common to
-	// include it at the beginning of the ciphertext.
-	if len(ciphertext) < aes.BlockSize {
-		panic("ciphertext too short")
-	}
-	iv := ciphertext[:aes.BlockSize]
-	ciphertext = ciphertext[aes.BlockSize:]
-
-	// CBC mode always works in whole blocks.
-	if len(ciphertext)%aes.BlockSize != 0 {
-		panic("ciphertext is not a multiple of the block size")
-	}
-
-	mode := cipher.NewCBCDecrypter(block, iv)
-
-	// CryptBlocks can work in-place if the two arguments are the same.
-	mode.CryptBlocks(ciphertext, ciphertext)
-
-	// If the original plaintext lengths are not a multiple of the block
-	// size, padding would have to be added when encrypting, which would be
-	// removed at this point. For an example, see
-	// https://tools.ietf.org/html/rfc5246#section-6.2.3.2. However, it's
-	// critical to note that ciphertexts must be authenticated (i.e. by
-	// using crypto/hmac) before being decrypted in order to avoid creating
-	// a padding oracle.
-
-	fmt.Printf("%s\n", ciphertext)
-	// Output: exampleplaintext
-}
-
-func ExampleNewCBCEncrypter() {
-	key := []byte("example key 1234")
-	plaintext := []byte("exampleplaintext")
-
-	// CBC mode works on blocks so plaintexts may need to be padded to the
-	// next whole block. For an example of such padding, see
-	// https://tools.ietf.org/html/rfc5246#section-6.2.3.2. Here we'll
-	// assume that the plaintext is already of the correct length.
-	if len(plaintext)%aes.BlockSize != 0 {
-		panic("plaintext is not a multiple of the block size")
-	}
-
-	block, err := aes.NewCipher(key)
-	if err != nil {
-		panic(err)
-	}
-
-	// The IV needs to be unique, but not secure. Therefore it's common to
-	// include it at the beginning of the ciphertext.
-	ciphertext := make([]byte, aes.BlockSize+len(plaintext))
-	iv := ciphertext[:aes.BlockSize]
-	if _, err := io.ReadFull(rand.Reader, iv); err != nil {
-		panic(err)
-	}
-
-	mode := cipher.NewCBCEncrypter(block, iv)
-	mode.CryptBlocks(ciphertext[aes.BlockSize:], plaintext)
-
-	// It's important to remember that ciphertexts must be authenticated
-	// (i.e. by using crypto/hmac) as well as being encrypted in order to
-	// be secure.
-
-	fmt.Printf("%x\n", ciphertext)
-}
-
-func ExampleNewCFBDecrypter() {
-	key := []byte("example key 1234")
-	ciphertext, _ := hex.DecodeString("22277966616d9bc47177bd02603d08c9a67d5380d0fe8cf3b44438dff7b9")
-
-	block, err := aes.NewCipher(key)
-	if err != nil {
-		panic(err)
-	}
-
-	// The IV needs to be unique, but not secure. Therefore it's common to
-	// include it at the beginning of the ciphertext.
-	if len(ciphertext) < aes.BlockSize {
-		panic("ciphertext too short")
-	}
-	iv := ciphertext[:aes.BlockSize]
-	ciphertext = ciphertext[aes.BlockSize:]
-
-	stream := cipher.NewCFBDecrypter(block, iv)
-
-	// XORKeyStream can work in-place if the two arguments are the same.
-	stream.XORKeyStream(ciphertext, ciphertext)
-	fmt.Printf("%s", ciphertext)
-	// Output: some plaintext
-}
-
-func ExampleNewCFBEncrypter() {
-	key := []byte("example key 1234")
-	plaintext := []byte("some plaintext")
-
-	block, err := aes.NewCipher(key)
-	if err != nil {
-		panic(err)
-	}
-
-	// The IV needs to be unique, but not secure. Therefore it's common to
-	// include it at the beginning of the ciphertext.
-	ciphertext := make([]byte, aes.BlockSize+len(plaintext))
-	iv := ciphertext[:aes.BlockSize]
-	if _, err := io.ReadFull(rand.Reader, iv); err != nil {
-		panic(err)
-	}
-
-	stream := cipher.NewCFBEncrypter(block, iv)
-	stream.XORKeyStream(ciphertext[aes.BlockSize:], plaintext)
-
-	// It's important to remember that ciphertexts must be authenticated
-	// (i.e. by using crypto/hmac) as well as being encrypted in order to
-	// be secure.
-}
-
-func ExampleNewCTR() {
-	key := []byte("example key 1234")
-	plaintext := []byte("some plaintext")
-
-	block, err := aes.NewCipher(key)
-	if err != nil {
-		panic(err)
-	}
-
-	// The IV needs to be unique, but not secure. Therefore it's common to
-	// include it at the beginning of the ciphertext.
-	ciphertext := make([]byte, aes.BlockSize+len(plaintext))
-	iv := ciphertext[:aes.BlockSize]
-	if _, err := io.ReadFull(rand.Reader, iv); err != nil {
-		panic(err)
-	}
-
-	stream := cipher.NewCTR(block, iv)
-	stream.XORKeyStream(ciphertext[aes.BlockSize:], plaintext)
-
-	// It's important to remember that ciphertexts must be authenticated
-	// (i.e. by using crypto/hmac) as well as being encrypted in order to
-	// be secure.
-
-	// CTR mode is the same for both encryption and decryption, so we can
-	// also decrypt that ciphertext with NewCTR.
-
-	plaintext2 := make([]byte, len(plaintext))
-	stream = cipher.NewCTR(block, iv)
-	stream.XORKeyStream(plaintext2, ciphertext[aes.BlockSize:])
-
-	fmt.Printf("%s\n", plaintext2)
-	// Output: some plaintext
-}
-
-func ExampleNewOFB() {
-	key := []byte("example key 1234")
-	plaintext := []byte("some plaintext")
-
-	block, err := aes.NewCipher(key)
-	if err != nil {
-		panic(err)
-	}
-
-	// The IV needs to be unique, but not secure. Therefore it's common to
-	// include it at the beginning of the ciphertext.
-	ciphertext := make([]byte, aes.BlockSize+len(plaintext))
-	iv := ciphertext[:aes.BlockSize]
-	if _, err := io.ReadFull(rand.Reader, iv); err != nil {
-		panic(err)
-	}
-
-	stream := cipher.NewOFB(block, iv)
-	stream.XORKeyStream(ciphertext[aes.BlockSize:], plaintext)
-
-	// It's important to remember that ciphertexts must be authenticated
-	// (i.e. by using crypto/hmac) as well as being encrypted in order to
-	// be secure.
-
-	// OFB mode is the same for both encryption and decryption, so we can
-	// also decrypt that ciphertext with NewOFB.
-
-	plaintext2 := make([]byte, len(plaintext))
-	stream = cipher.NewOFB(block, iv)
-	stream.XORKeyStream(plaintext2, ciphertext[aes.BlockSize:])
-
-	fmt.Printf("%s\n", plaintext2)
-	// Output: some plaintext
-}
-
-func ExampleStreamReader() {
-	key := []byte("example key 1234")
-
-	inFile, err := os.Open("encrypted-file")
-	if err != nil {
-		panic(err)
-	}
-	defer inFile.Close()
-
-	block, err := aes.NewCipher(key)
-	if err != nil {
-		panic(err)
-	}
-
-	// If the key is unique for each ciphertext, then it's ok to use a zero
-	// IV.
-	var iv [aes.BlockSize]byte
-	stream := cipher.NewOFB(block, iv[:])
-
-	outFile, err := os.OpenFile("decrypted-file", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
-	if err != nil {
-		panic(err)
-	}
-	defer outFile.Close()
-
-	reader := &cipher.StreamReader{S: stream, R: inFile}
-	// Copy the input file to the output file, decrypting as we go.
-	if _, err := io.Copy(outFile, reader); err != nil {
-		panic(err)
-	}
-
-	// Note that this example is simplistic in that it omits any
-	// authentication of the encrypted data. It you were actually to use
-	// StreamReader in this manner, an attacker could flip arbitrary bits in
-	// the output.
-}
-
-func ExampleStreamWriter() {
-	key := []byte("example key 1234")
-
-	inFile, err := os.Open("plaintext-file")
-	if err != nil {
-		panic(err)
-	}
-	defer inFile.Close()
-
-	block, err := aes.NewCipher(key)
-	if err != nil {
-		panic(err)
-	}
-
-	// If the key is unique for each ciphertext, then it's ok to use a zero
-	// IV.
-	var iv [aes.BlockSize]byte
-	stream := cipher.NewOFB(block, iv[:])
-
-	outFile, err := os.OpenFile("encrypted-file", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
-	if err != nil {
-		panic(err)
-	}
-	defer outFile.Close()
-
-	writer := &cipher.StreamWriter{S: stream, W: outFile}
-	// Copy the input file to the output file, encrypting as we go.
-	if _, err := io.Copy(writer, inFile); err != nil {
-		panic(err)
-	}
-
-	// Note that this example is simplistic in that it omits any
-	// authentication of the encrypted data. It you were actually to use
-	// StreamReader in this manner, an attacker could flip arbitrary bits in
-	// the decrypted result.
-}
diff --git a/src/pkg/crypto/crypto.go b/src/pkg/crypto/crypto.go
deleted file mode 100644
index 4b03628..0000000
--- a/src/pkg/crypto/crypto.go
+++ /dev/null
@@ -1,85 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package crypto collects common cryptographic constants.
-package crypto
-
-import (
-	"hash"
-	"strconv"
-)
-
-// Hash identifies a cryptographic hash function that is implemented in another
-// package.
-type Hash uint
-
-const (
-	MD4       Hash = 1 + iota // import code.google.com/p/go.crypto/md4
-	MD5                       // import crypto/md5
-	SHA1                      // import crypto/sha1
-	SHA224                    // import crypto/sha256
-	SHA256                    // import crypto/sha256
-	SHA384                    // import crypto/sha512
-	SHA512                    // import crypto/sha512
-	MD5SHA1                   // no implementation; MD5+SHA1 used for TLS RSA
-	RIPEMD160                 // import code.google.com/p/go.crypto/ripemd160
-	maxHash
-)
-
-var digestSizes = []uint8{
-	MD4:       16,
-	MD5:       16,
-	SHA1:      20,
-	SHA224:    28,
-	SHA256:    32,
-	SHA384:    48,
-	SHA512:    64,
-	MD5SHA1:   36,
-	RIPEMD160: 20,
-}
-
-// Size returns the length, in bytes, of a digest resulting from the given hash
-// function. It doesn't require that the hash function in question be linked
-// into the program.
-func (h Hash) Size() int {
-	if h > 0 && h < maxHash {
-		return int(digestSizes[h])
-	}
-	panic("crypto: Size of unknown hash function")
-}
-
-var hashes = make([]func() hash.Hash, maxHash)
-
-// New returns a new hash.Hash calculating the given hash function. New panics
-// if the hash function is not linked into the binary.
-func (h Hash) New() hash.Hash {
-	if h > 0 && h < maxHash {
-		f := hashes[h]
-		if f != nil {
-			return f()
-		}
-	}
-	panic("crypto: requested hash function #" + strconv.Itoa(int(h)) + " is unavailable")
-}
-
-// Available reports whether the given hash function is linked into the binary.
-func (h Hash) Available() bool {
-	return h < maxHash && hashes[h] != nil
-}
-
-// RegisterHash registers a function that returns a new instance of the given
-// hash function. This is intended to be called from the init function in
-// packages that implement hash functions.
-func RegisterHash(h Hash, f func() hash.Hash) {
-	if h >= maxHash {
-		panic("crypto: RegisterHash of unknown hash function")
-	}
-	hashes[h] = f
-}
-
-// PublicKey represents a public key using an unspecified algorithm.
-type PublicKey interface{}
-
-// PrivateKey represents a private key using an unspecified algorithm.
-type PrivateKey interface{}
diff --git a/src/pkg/crypto/ecdsa/ecdsa.go b/src/pkg/crypto/ecdsa/ecdsa.go
deleted file mode 100644
index 1bec743..0000000
--- a/src/pkg/crypto/ecdsa/ecdsa.go
+++ /dev/null
@@ -1,165 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package ecdsa implements the Elliptic Curve Digital Signature Algorithm, as
-// defined in FIPS 186-3.
-package ecdsa
-
-// References:
-//   [NSA]: Suite B implementer's guide to FIPS 186-3,
-//     http://www.nsa.gov/ia/_files/ecdsa.pdf
-//   [SECG]: SECG, SEC1
-//     http://www.secg.org/download/aid-780/sec1-v2.pdf
-
-import (
-	"crypto/elliptic"
-	"io"
-	"math/big"
-)
-
-// PublicKey represents an ECDSA public key.
-type PublicKey struct {
-	elliptic.Curve
-	X, Y *big.Int
-}
-
-// PrivateKey represents a ECDSA private key.
-type PrivateKey struct {
-	PublicKey
-	D *big.Int
-}
-
-var one = new(big.Int).SetInt64(1)
-
-// randFieldElement returns a random element of the field underlying the given
-// curve using the procedure given in [NSA] A.2.1.
-func randFieldElement(c elliptic.Curve, rand io.Reader) (k *big.Int, err error) {
-	params := c.Params()
-	b := make([]byte, params.BitSize/8+8)
-	_, err = io.ReadFull(rand, b)
-	if err != nil {
-		return
-	}
-
-	k = new(big.Int).SetBytes(b)
-	n := new(big.Int).Sub(params.N, one)
-	k.Mod(k, n)
-	k.Add(k, one)
-	return
-}
-
-// GenerateKey generates a public and private key pair.
-func GenerateKey(c elliptic.Curve, rand io.Reader) (priv *PrivateKey, err error) {
-	k, err := randFieldElement(c, rand)
-	if err != nil {
-		return
-	}
-
-	priv = new(PrivateKey)
-	priv.PublicKey.Curve = c
-	priv.D = k
-	priv.PublicKey.X, priv.PublicKey.Y = c.ScalarBaseMult(k.Bytes())
-	return
-}
-
-// hashToInt converts a hash value to an integer. There is some disagreement
-// about how this is done. [NSA] suggests that this is done in the obvious
-// manner, but [SECG] truncates the hash to the bit-length of the curve order
-// first. We follow [SECG] because that's what OpenSSL does. Additionally,
-// OpenSSL right shifts excess bits from the number if the hash is too large
-// and we mirror that too.
-func hashToInt(hash []byte, c elliptic.Curve) *big.Int {
-	orderBits := c.Params().N.BitLen()
-	orderBytes := (orderBits + 7) / 8
-	if len(hash) > orderBytes {
-		hash = hash[:orderBytes]
-	}
-
-	ret := new(big.Int).SetBytes(hash)
-	excess := len(hash)*8 - orderBits
-	if excess > 0 {
-		ret.Rsh(ret, uint(excess))
-	}
-	return ret
-}
-
-// fermatInverse calculates the inverse of k in GF(P) using Fermat's method.
-// This has better constant-time properties than Euclid's method (implemented
-// in math/big.Int.ModInverse) although math/big itself isn't strictly
-// constant-time so it's not perfect.
-func fermatInverse(k, N *big.Int) *big.Int {
-	two := big.NewInt(2)
-	nMinus2 := new(big.Int).Sub(N, two)
-	return new(big.Int).Exp(k, nMinus2, N)
-}
-
-// Sign signs an arbitrary length hash (which should be the result of hashing a
-// larger message) using the private key, priv. It returns the signature as a
-// pair of integers. The security of the private key depends on the entropy of
-// rand.
-func Sign(rand io.Reader, priv *PrivateKey, hash []byte) (r, s *big.Int, err error) {
-	// See [NSA] 3.4.1
-	c := priv.PublicKey.Curve
-	N := c.Params().N
-
-	var k, kInv *big.Int
-	for {
-		for {
-			k, err = randFieldElement(c, rand)
-			if err != nil {
-				r = nil
-				return
-			}
-
-			kInv = fermatInverse(k, N)
-			r, _ = priv.Curve.ScalarBaseMult(k.Bytes())
-			r.Mod(r, N)
-			if r.Sign() != 0 {
-				break
-			}
-		}
-
-		e := hashToInt(hash, c)
-		s = new(big.Int).Mul(priv.D, r)
-		s.Add(s, e)
-		s.Mul(s, kInv)
-		s.Mod(s, N)
-		if s.Sign() != 0 {
-			break
-		}
-	}
-
-	return
-}
-
-// Verify verifies the signature in r, s of hash using the public key, pub. Its
-// return value records whether the signature is valid.
-func Verify(pub *PublicKey, hash []byte, r, s *big.Int) bool {
-	// See [NSA] 3.4.2
-	c := pub.Curve
-	N := c.Params().N
-
-	if r.Sign() == 0 || s.Sign() == 0 {
-		return false
-	}
-	if r.Cmp(N) >= 0 || s.Cmp(N) >= 0 {
-		return false
-	}
-	e := hashToInt(hash, c)
-	w := new(big.Int).ModInverse(s, N)
-
-	u1 := e.Mul(e, w)
-	u1.Mod(u1, N)
-	u2 := w.Mul(r, w)
-	u2.Mod(u2, N)
-
-	x1, y1 := c.ScalarBaseMult(u1.Bytes())
-	x2, y2 := c.ScalarMult(pub.X, pub.Y, u2.Bytes())
-	x, y := c.Add(x1, y1, x2, y2)
-	if x.Sign() == 0 && y.Sign() == 0 {
-		return false
-	}
-	x.Mod(x, N)
-	return x.Cmp(r) == 0
-}
diff --git a/src/pkg/crypto/md5/gen.go b/src/pkg/crypto/md5/gen.go
deleted file mode 100644
index 75295e4..0000000
--- a/src/pkg/crypto/md5/gen.go
+++ /dev/null
@@ -1,316 +0,0 @@
-// Copyright 2012 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build ignore
-
-// This program generates md5block.go
-// Invoke as
-//
-//	go run gen.go [-full] |gofmt >md5block.go
-//
-// The -full flag causes the generated code to do a full
-// (16x) unrolling instead of a 4x unrolling.
-
-package main
-
-import (
-	"flag"
-	"log"
-	"os"
-	"strings"
-	"text/template"
-)
-
-func main() {
-	flag.Parse()
-
-	t := template.Must(template.New("main").Funcs(funcs).Parse(program))
-	if err := t.Execute(os.Stdout, data); err != nil {
-		log.Fatal(err)
-	}
-}
-
-type Data struct {
-	a, b, c, d string
-	Shift1     []int
-	Shift2     []int
-	Shift3     []int
-	Shift4     []int
-	Table1     []uint32
-	Table2     []uint32
-	Table3     []uint32
-	Table4     []uint32
-	Full       bool
-}
-
-var funcs = template.FuncMap{
-	"dup":     dup,
-	"relabel": relabel,
-	"rotate":  rotate,
-}
-
-func dup(count int, x []int) []int {
-	var out []int
-	for i := 0; i < count; i++ {
-		out = append(out, x...)
-	}
-	return out
-}
-
-func relabel(s string) string {
-	return strings.NewReplacer("a", data.a, "b", data.b, "c", data.c, "d", data.d).Replace(s)
-}
-
-func rotate() string {
-	data.a, data.b, data.c, data.d = data.d, data.a, data.b, data.c
-	return "" // no output
-}
-
-func init() {
-	flag.BoolVar(&data.Full, "full", false, "complete unrolling")
-}
-
-var data = Data{
-	a:      "a",
-	b:      "b",
-	c:      "c",
-	d:      "d",
-	Shift1: []int{7, 12, 17, 22},
-	Shift2: []int{5, 9, 14, 20},
-	Shift3: []int{4, 11, 16, 23},
-	Shift4: []int{6, 10, 15, 21},
-
-	// table[i] = int((1<<32) * abs(sin(i+1 radians))).
-	Table1: []uint32{
-		// round 1
-		0xd76aa478,
-		0xe8c7b756,
-		0x242070db,
-		0xc1bdceee,
-		0xf57c0faf,
-		0x4787c62a,
-		0xa8304613,
-		0xfd469501,
-		0x698098d8,
-		0x8b44f7af,
-		0xffff5bb1,
-		0x895cd7be,
-		0x6b901122,
-		0xfd987193,
-		0xa679438e,
-		0x49b40821,
-	},
-	Table2: []uint32{
-		// round 2
-		0xf61e2562,
-		0xc040b340,
-		0x265e5a51,
-		0xe9b6c7aa,
-		0xd62f105d,
-		0x2441453,
-		0xd8a1e681,
-		0xe7d3fbc8,
-		0x21e1cde6,
-		0xc33707d6,
-		0xf4d50d87,
-		0x455a14ed,
-		0xa9e3e905,
-		0xfcefa3f8,
-		0x676f02d9,
-		0x8d2a4c8a,
-	},
-	Table3: []uint32{
-		// round3
-		0xfffa3942,
-		0x8771f681,
-		0x6d9d6122,
-		0xfde5380c,
-		0xa4beea44,
-		0x4bdecfa9,
-		0xf6bb4b60,
-		0xbebfbc70,
-		0x289b7ec6,
-		0xeaa127fa,
-		0xd4ef3085,
-		0x4881d05,
-		0xd9d4d039,
-		0xe6db99e5,
-		0x1fa27cf8,
-		0xc4ac5665,
-	},
-	Table4: []uint32{
-		// round 4
-		0xf4292244,
-		0x432aff97,
-		0xab9423a7,
-		0xfc93a039,
-		0x655b59c3,
-		0x8f0ccc92,
-		0xffeff47d,
-		0x85845dd1,
-		0x6fa87e4f,
-		0xfe2ce6e0,
-		0xa3014314,
-		0x4e0811a1,
-		0xf7537e82,
-		0xbd3af235,
-		0x2ad7d2bb,
-		0xeb86d391,
-	},
-}
-
-var program = `// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// DO NOT EDIT.
-// Generate with: go run gen.go{{if .Full}} -full{{end}} | gofmt >md5block.go
-
-package md5
-
-import (
-	"unsafe"
-	"runtime"
-)
-
-{{if not .Full}}
-	var t1 = [...]uint32{
-	{{range .Table1}}{{printf "\t%#x,\n" .}}{{end}}
-	}
-	
-	var t2 = [...]uint32{
-	{{range .Table2}}{{printf "\t%#x,\n" .}}{{end}}
-	}
-	
-	var t3 = [...]uint32{
-	{{range .Table3}}{{printf "\t%#x,\n" .}}{{end}}
-	}
-	
-	var t4 = [...]uint32{
-	{{range .Table4}}{{printf "\t%#x,\n" .}}{{end}}
-	}
-{{end}}
-
-const x86 = runtime.GOARCH == "amd64" || runtime.GOARCH == "386"
-
-var littleEndian bool
-
-func init() {
-	x := uint32(0x04030201)
-	y := [4]byte{0x1, 0x2, 0x3, 0x4}
-	littleEndian = *(*[4]byte)(unsafe.Pointer(&x)) == y
-}
-
-func blockGeneric(dig *digest, p []byte) {
-	a := dig.s[0]
-	b := dig.s[1]
-	c := dig.s[2]
-	d := dig.s[3]
-	var X *[16]uint32
-	var xbuf [16]uint32
-	for len(p) >= chunk {
-		aa, bb, cc, dd := a, b, c, d
-
-		// This is a constant condition - it is not evaluated on each iteration.
-		if x86 {
-			// MD5 was designed so that x86 processors can just iterate
-			// over the block data directly as uint32s, and we generate
-			// less code and run 1.3x faster if we take advantage of that.
-			// My apologies.
-			X = (*[16]uint32)(unsafe.Pointer(&p[0]))
-		} else if littleEndian && uintptr(unsafe.Pointer(&p[0]))&(unsafe.Alignof(uint32(0))-1) == 0 {
-			X = (*[16]uint32)(unsafe.Pointer(&p[0]))
-		} else {
-			X = &xbuf
-			j := 0
-			for i := 0; i < 16; i++ {
-				X[i&15] = uint32(p[j]) | uint32(p[j+1])<<8 | uint32(p[j+2])<<16 | uint32(p[j+3])<<24
-				j += 4
-			}
-		}
-
-		{{if .Full}}
-			// Round 1.
-			{{range $i, $s := dup 4 .Shift1}}
-				{{index $.Table1 $i | printf "a += (((c^d)&b)^d) + X[%d] + %d" $i | relabel}}
-				{{printf "a = a<<%d | a>>(32-%d) + b" $s $s | relabel}}
-				{{rotate}}
-			{{end}}
-	
-			// Round 2.
-			{{range $i, $s := dup 4 .Shift2}}
-				{{index $.Table2 $i | printf "a += (((b^c)&d)^c) + X[(1+5*%d)&15] + %d" $i | relabel}}
-				{{printf "a = a<<%d | a>>(32-%d) + b" $s $s | relabel}}
-				{{rotate}}
-			{{end}}
-	
-			// Round 3.
-			{{range $i, $s := dup 4 .Shift3}}
-				{{index $.Table3 $i | printf "a += (b^c^d) + X[(5+3*%d)&15] + %d" $i | relabel}}
-				{{printf "a = a<<%d | a>>(32-%d) + b" $s $s | relabel}}
-				{{rotate}}
-			{{end}}
-	
-			// Round 4.
-			{{range $i, $s := dup 4 .Shift4}}
-				{{index $.Table4 $i | printf "a += (c^(b|^d)) + X[(7*%d)&15] + %d" $i | relabel}}
-				{{printf "a = a<<%d | a>>(32-%d) + b" $s $s | relabel}}
-				{{rotate}}
-			{{end}}
-		{{else}}
-			// Round 1.
-			for i := uint(0); i < 16; {
-				{{range $s := .Shift1}}
-					{{printf "a += (((c^d)&b)^d) + X[i&15] + t1[i&15]" | relabel}}
-					{{printf "a = a<<%d | a>>(32-%d) + b" $s $s | relabel}}
-					i++
-					{{rotate}}
-				{{end}}
-			}
-	
-			// Round 2.
-			for i := uint(0); i < 16; {
-				{{range $s := .Shift2}}
-					{{printf "a += (((b^c)&d)^c) + X[(1+5*i)&15] + t2[i&15]" | relabel}}
-					{{printf "a = a<<%d | a>>(32-%d) + b" $s $s | relabel}}
-					i++
-					{{rotate}}
-				{{end}}
-			}
-	
-			// Round 3.
-			for i := uint(0); i < 16; {
-				{{range $s := .Shift3}}
-					{{printf "a += (b^c^d) + X[(5+3*i)&15] + t3[i&15]" | relabel}}
-					{{printf "a = a<<%d | a>>(32-%d) + b" $s $s | relabel}}
-					i++
-					{{rotate}}
-				{{end}}
-			}
-	
-			// Round 4.
-			for i := uint(0); i < 16; {
-				{{range $s := .Shift4}}
-					{{printf "a += (c^(b|^d)) + X[(7*i)&15] + t4[i&15]" | relabel}}
-					{{printf "a = a<<%d | a>>(32-%d) + b" $s $s | relabel}}
-					i++
-					{{rotate}}
-				{{end}}
-			}
-		{{end}}
-
-		a += aa
-		b += bb
-		c += cc
-		d += dd
-
-		p = p[chunk:]
-	}
-
-	dig.s[0] = a
-	dig.s[1] = b
-	dig.s[2] = c
-	dig.s[3] = d
-}
-`
diff --git a/src/pkg/crypto/md5/md5.go b/src/pkg/crypto/md5/md5.go
deleted file mode 100644
index 1a1f35f..0000000
--- a/src/pkg/crypto/md5/md5.go
+++ /dev/null
@@ -1,134 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package md5 implements the MD5 hash algorithm as defined in RFC 1321.
-package md5
-
-import (
-	"crypto"
-	"hash"
-)
-
-func init() {
-	crypto.RegisterHash(crypto.MD5, New)
-}
-
-// The size of an MD5 checksum in bytes.
-const Size = 16
-
-// The blocksize of MD5 in bytes.
-const BlockSize = 64
-
-const (
-	chunk = 64
-	init0 = 0x67452301
-	init1 = 0xEFCDAB89
-	init2 = 0x98BADCFE
-	init3 = 0x10325476
-)
-
-// digest represents the partial evaluation of a checksum.
-type digest struct {
-	s   [4]uint32
-	x   [chunk]byte
-	nx  int
-	len uint64
-}
-
-func (d *digest) Reset() {
-	d.s[0] = init0
-	d.s[1] = init1
-	d.s[2] = init2
-	d.s[3] = init3
-	d.nx = 0
-	d.len = 0
-}
-
-// New returns a new hash.Hash computing the MD5 checksum.
-func New() hash.Hash {
-	d := new(digest)
-	d.Reset()
-	return d
-}
-
-func (d *digest) Size() int { return Size }
-
-func (d *digest) BlockSize() int { return BlockSize }
-
-func (d *digest) Write(p []byte) (nn int, err error) {
-	nn = len(p)
-	d.len += uint64(nn)
-	if d.nx > 0 {
-		n := len(p)
-		if n > chunk-d.nx {
-			n = chunk - d.nx
-		}
-		for i := 0; i < n; i++ {
-			d.x[d.nx+i] = p[i]
-		}
-		d.nx += n
-		if d.nx == chunk {
-			block(d, d.x[0:chunk])
-			d.nx = 0
-		}
-		p = p[n:]
-	}
-	if len(p) >= chunk {
-		n := len(p) &^ (chunk - 1)
-		block(d, p[:n])
-		p = p[n:]
-	}
-	if len(p) > 0 {
-		d.nx = copy(d.x[:], p)
-	}
-	return
-}
-
-func (d0 *digest) Sum(in []byte) []byte {
-	// Make a copy of d0 so that caller can keep writing and summing.
-	d := *d0
-	hash := d.checkSum()
-	return append(in, hash[:]...)
-}
-
-func (d *digest) checkSum() [Size]byte {
-	// Padding.  Add a 1 bit and 0 bits until 56 bytes mod 64.
-	len := d.len
-	var tmp [64]byte
-	tmp[0] = 0x80
-	if len%64 < 56 {
-		d.Write(tmp[0 : 56-len%64])
-	} else {
-		d.Write(tmp[0 : 64+56-len%64])
-	}
-
-	// Length in bits.
-	len <<= 3
-	for i := uint(0); i < 8; i++ {
-		tmp[i] = byte(len >> (8 * i))
-	}
-	d.Write(tmp[0:8])
-
-	if d.nx != 0 {
-		panic("d.nx != 0")
-	}
-
-	var digest [Size]byte
-	for i, s := range d.s {
-		digest[i*4] = byte(s)
-		digest[i*4+1] = byte(s >> 8)
-		digest[i*4+2] = byte(s >> 16)
-		digest[i*4+3] = byte(s >> 24)
-	}
-
-	return digest
-}
-
-// Sum returns the MD5 checksum of the data.
-func Sum(data []byte) [Size]byte {
-	var d digest
-	d.Reset()
-	d.Write(data)
-	return d.checkSum()
-}
diff --git a/src/pkg/crypto/md5/md5block.go b/src/pkg/crypto/md5/md5block.go
deleted file mode 100644
index e2a1767..0000000
--- a/src/pkg/crypto/md5/md5block.go
+++ /dev/null
@@ -1,265 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// DO NOT EDIT.
-// Generate with: go run gen.go -full | gofmt >md5block.go
-
-package md5
-
-import (
-	"runtime"
-	"unsafe"
-)
-
-const x86 = runtime.GOARCH == "amd64" || runtime.GOARCH == "386"
-
-var littleEndian bool
-
-func init() {
-	x := uint32(0x04030201)
-	y := [4]byte{0x1, 0x2, 0x3, 0x4}
-	littleEndian = *(*[4]byte)(unsafe.Pointer(&x)) == y
-}
-
-func blockGeneric(dig *digest, p []byte) {
-	a := dig.s[0]
-	b := dig.s[1]
-	c := dig.s[2]
-	d := dig.s[3]
-	var X *[16]uint32
-	var xbuf [16]uint32
-	for len(p) >= chunk {
-		aa, bb, cc, dd := a, b, c, d
-
-		// This is a constant condition - it is not evaluated on each iteration.
-		if x86 {
-			// MD5 was designed so that x86 processors can just iterate
-			// over the block data directly as uint32s, and we generate
-			// less code and run 1.3x faster if we take advantage of that.
-			// My apologies.
-			X = (*[16]uint32)(unsafe.Pointer(&p[0]))
-		} else if littleEndian && uintptr(unsafe.Pointer(&p[0]))&(unsafe.Alignof(uint32(0))-1) == 0 {
-			X = (*[16]uint32)(unsafe.Pointer(&p[0]))
-		} else {
-			X = &xbuf
-			j := 0
-			for i := 0; i < 16; i++ {
-				X[i&15] = uint32(p[j]) | uint32(p[j+1])<<8 | uint32(p[j+2])<<16 | uint32(p[j+3])<<24
-				j += 4
-			}
-		}
-
-		// Round 1.
-
-		a += (((c ^ d) & b) ^ d) + X[0] + 3614090360
-		a = a<<7 | a>>(32-7) + b
-
-		d += (((b ^ c) & a) ^ c) + X[1] + 3905402710
-		d = d<<12 | d>>(32-12) + a
-
-		c += (((a ^ b) & d) ^ b) + X[2] + 606105819
-		c = c<<17 | c>>(32-17) + d
-
-		b += (((d ^ a) & c) ^ a) + X[3] + 3250441966
-		b = b<<22 | b>>(32-22) + c
-
-		a += (((c ^ d) & b) ^ d) + X[4] + 4118548399
-		a = a<<7 | a>>(32-7) + b
-
-		d += (((b ^ c) & a) ^ c) + X[5] + 1200080426
-		d = d<<12 | d>>(32-12) + a
-
-		c += (((a ^ b) & d) ^ b) + X[6] + 2821735955
-		c = c<<17 | c>>(32-17) + d
-
-		b += (((d ^ a) & c) ^ a) + X[7] + 4249261313
-		b = b<<22 | b>>(32-22) + c
-
-		a += (((c ^ d) & b) ^ d) + X[8] + 1770035416
-		a = a<<7 | a>>(32-7) + b
-
-		d += (((b ^ c) & a) ^ c) + X[9] + 2336552879
-		d = d<<12 | d>>(32-12) + a
-
-		c += (((a ^ b) & d) ^ b) + X[10] + 4294925233
-		c = c<<17 | c>>(32-17) + d
-
-		b += (((d ^ a) & c) ^ a) + X[11] + 2304563134
-		b = b<<22 | b>>(32-22) + c
-
-		a += (((c ^ d) & b) ^ d) + X[12] + 1804603682
-		a = a<<7 | a>>(32-7) + b
-
-		d += (((b ^ c) & a) ^ c) + X[13] + 4254626195
-		d = d<<12 | d>>(32-12) + a
-
-		c += (((a ^ b) & d) ^ b) + X[14] + 2792965006
-		c = c<<17 | c>>(32-17) + d
-
-		b += (((d ^ a) & c) ^ a) + X[15] + 1236535329
-		b = b<<22 | b>>(32-22) + c
-
-		// Round 2.
-
-		a += (((b ^ c) & d) ^ c) + X[(1+5*0)&15] + 4129170786
-		a = a<<5 | a>>(32-5) + b
-
-		d += (((a ^ b) & c) ^ b) + X[(1+5*1)&15] + 3225465664
-		d = d<<9 | d>>(32-9) + a
-
-		c += (((d ^ a) & b) ^ a) + X[(1+5*2)&15] + 643717713
-		c = c<<14 | c>>(32-14) + d
-
-		b += (((c ^ d) & a) ^ d) + X[(1+5*3)&15] + 3921069994
-		b = b<<20 | b>>(32-20) + c
-
-		a += (((b ^ c) & d) ^ c) + X[(1+5*4)&15] + 3593408605
-		a = a<<5 | a>>(32-5) + b
-
-		d += (((a ^ b) & c) ^ b) + X[(1+5*5)&15] + 38016083
-		d = d<<9 | d>>(32-9) + a
-
-		c += (((d ^ a) & b) ^ a) + X[(1+5*6)&15] + 3634488961
-		c = c<<14 | c>>(32-14) + d
-
-		b += (((c ^ d) & a) ^ d) + X[(1+5*7)&15] + 3889429448
-		b = b<<20 | b>>(32-20) + c
-
-		a += (((b ^ c) & d) ^ c) + X[(1+5*8)&15] + 568446438
-		a = a<<5 | a>>(32-5) + b
-
-		d += (((a ^ b) & c) ^ b) + X[(1+5*9)&15] + 3275163606
-		d = d<<9 | d>>(32-9) + a
-
-		c += (((d ^ a) & b) ^ a) + X[(1+5*10)&15] + 4107603335
-		c = c<<14 | c>>(32-14) + d
-
-		b += (((c ^ d) & a) ^ d) + X[(1+5*11)&15] + 1163531501
-		b = b<<20 | b>>(32-20) + c
-
-		a += (((b ^ c) & d) ^ c) + X[(1+5*12)&15] + 2850285829
-		a = a<<5 | a>>(32-5) + b
-
-		d += (((a ^ b) & c) ^ b) + X[(1+5*13)&15] + 4243563512
-		d = d<<9 | d>>(32-9) + a
-
-		c += (((d ^ a) & b) ^ a) + X[(1+5*14)&15] + 1735328473
-		c = c<<14 | c>>(32-14) + d
-
-		b += (((c ^ d) & a) ^ d) + X[(1+5*15)&15] + 2368359562
-		b = b<<20 | b>>(32-20) + c
-
-		// Round 3.
-
-		a += (b ^ c ^ d) + X[(5+3*0)&15] + 4294588738
-		a = a<<4 | a>>(32-4) + b
-
-		d += (a ^ b ^ c) + X[(5+3*1)&15] + 2272392833
-		d = d<<11 | d>>(32-11) + a
-
-		c += (d ^ a ^ b) + X[(5+3*2)&15] + 1839030562
-		c = c<<16 | c>>(32-16) + d
-
-		b += (c ^ d ^ a) + X[(5+3*3)&15] + 4259657740
-		b = b<<23 | b>>(32-23) + c
-
-		a += (b ^ c ^ d) + X[(5+3*4)&15] + 2763975236
-		a = a<<4 | a>>(32-4) + b
-
-		d += (a ^ b ^ c) + X[(5+3*5)&15] + 1272893353
-		d = d<<11 | d>>(32-11) + a
-
-		c += (d ^ a ^ b) + X[(5+3*6)&15] + 4139469664
-		c = c<<16 | c>>(32-16) + d
-
-		b += (c ^ d ^ a) + X[(5+3*7)&15] + 3200236656
-		b = b<<23 | b>>(32-23) + c
-
-		a += (b ^ c ^ d) + X[(5+3*8)&15] + 681279174
-		a = a<<4 | a>>(32-4) + b
-
-		d += (a ^ b ^ c) + X[(5+3*9)&15] + 3936430074
-		d = d<<11 | d>>(32-11) + a
-
-		c += (d ^ a ^ b) + X[(5+3*10)&15] + 3572445317
-		c = c<<16 | c>>(32-16) + d
-
-		b += (c ^ d ^ a) + X[(5+3*11)&15] + 76029189
-		b = b<<23 | b>>(32-23) + c
-
-		a += (b ^ c ^ d) + X[(5+3*12)&15] + 3654602809
-		a = a<<4 | a>>(32-4) + b
-
-		d += (a ^ b ^ c) + X[(5+3*13)&15] + 3873151461
-		d = d<<11 | d>>(32-11) + a
-
-		c += (d ^ a ^ b) + X[(5+3*14)&15] + 530742520
-		c = c<<16 | c>>(32-16) + d
-
-		b += (c ^ d ^ a) + X[(5+3*15)&15] + 3299628645
-		b = b<<23 | b>>(32-23) + c
-
-		// Round 4.
-
-		a += (c ^ (b | ^d)) + X[(7*0)&15] + 4096336452
-		a = a<<6 | a>>(32-6) + b
-
-		d += (b ^ (a | ^c)) + X[(7*1)&15] + 1126891415
-		d = d<<10 | d>>(32-10) + a
-
-		c += (a ^ (d | ^b)) + X[(7*2)&15] + 2878612391
-		c = c<<15 | c>>(32-15) + d
-
-		b += (d ^ (c | ^a)) + X[(7*3)&15] + 4237533241
-		b = b<<21 | b>>(32-21) + c
-
-		a += (c ^ (b | ^d)) + X[(7*4)&15] + 1700485571
-		a = a<<6 | a>>(32-6) + b
-
-		d += (b ^ (a | ^c)) + X[(7*5)&15] + 2399980690
-		d = d<<10 | d>>(32-10) + a
-
-		c += (a ^ (d | ^b)) + X[(7*6)&15] + 4293915773
-		c = c<<15 | c>>(32-15) + d
-
-		b += (d ^ (c | ^a)) + X[(7*7)&15] + 2240044497
-		b = b<<21 | b>>(32-21) + c
-
-		a += (c ^ (b | ^d)) + X[(7*8)&15] + 1873313359
-		a = a<<6 | a>>(32-6) + b
-
-		d += (b ^ (a | ^c)) + X[(7*9)&15] + 4264355552
-		d = d<<10 | d>>(32-10) + a
-
-		c += (a ^ (d | ^b)) + X[(7*10)&15] + 2734768916
-		c = c<<15 | c>>(32-15) + d
-
-		b += (d ^ (c | ^a)) + X[(7*11)&15] + 1309151649
-		b = b<<21 | b>>(32-21) + c
-
-		a += (c ^ (b | ^d)) + X[(7*12)&15] + 4149444226
-		a = a<<6 | a>>(32-6) + b
-
-		d += (b ^ (a | ^c)) + X[(7*13)&15] + 3174756917
-		d = d<<10 | d>>(32-10) + a
-
-		c += (a ^ (d | ^b)) + X[(7*14)&15] + 718787259
-		c = c<<15 | c>>(32-15) + d
-
-		b += (d ^ (c | ^a)) + X[(7*15)&15] + 3951481745
-		b = b<<21 | b>>(32-21) + c
-
-		a += aa
-		b += bb
-		c += cc
-		d += dd
-
-		p = p[chunk:]
-	}
-
-	dig.s[0] = a
-	dig.s[1] = b
-	dig.s[2] = c
-	dig.s[3] = d
-}
diff --git a/src/pkg/crypto/md5/md5block_386.s b/src/pkg/crypto/md5/md5block_386.s
deleted file mode 100644
index e5c27ac..0000000
--- a/src/pkg/crypto/md5/md5block_386.s
+++ /dev/null
@@ -1,182 +0,0 @@
-// Original source:
-//	http://www.zorinaq.com/papers/md5-amd64.html
-//	http://www.zorinaq.com/papers/md5-amd64.tar.bz2
-//
-// Translated from Perl generating GNU assembly into
-// #defines generating 8a assembly, and adjusted for 386,
-// by the Go Authors.
-
-#include "../../../cmd/ld/textflag.h"
-
-// MD5 optimized for AMD64.
-//
-// Author: Marc Bevand <bevand_m (at) epita.fr>
-// Licence: I hereby disclaim the copyright on this code and place it
-// in the public domain.
-
-#define ROUND1(a, b, c, d, index, const, shift) \
-	XORL	c, BP; \
-	LEAL	const(a)(DI*1), a; \
-	ANDL	b, BP; \
-	XORL d, BP; \
-	MOVL (index*4)(SI), DI; \
-	ADDL BP, a; \
-	ROLL $shift, a; \
-	MOVL c, BP; \
-	ADDL b, a
-
-#define ROUND2(a, b, c, d, index, const, shift) \
-	LEAL	const(a)(DI*1),a; \
-	MOVL	d,		DI; \
-	ANDL	b,		DI; \
-	MOVL	d,		BP; \
-	NOTL	BP; \
-	ANDL	c,		BP; \
-	ORL	DI,		BP; \
-	MOVL	(index*4)(SI),DI; \
-	ADDL	BP,		a; \
-	ROLL	$shift,	a; \
-	ADDL	b,		a
-
-#define ROUND3(a, b, c, d, index, const, shift) \
-	LEAL	const(a)(DI*1),a; \
-	MOVL	(index*4)(SI),DI; \
-	XORL	d,		BP; \
-	XORL	b,		BP; \
-	ADDL	BP,		a; \
-	ROLL	$shift,		a; \
-	MOVL	b,		BP; \
-	ADDL	b,		a
-
-#define ROUND4(a, b, c, d, index, const, shift) \
-	LEAL	const(a)(DI*1),a; \
-	ORL	b,		BP; \
-	XORL	c,		BP; \
-	ADDL	BP,		a; \
-	MOVL	(index*4)(SI),DI; \
-	MOVL	$0xffffffff,	BP; \
-	ROLL	$shift,		a; \
-	XORL	c,		BP; \
-	ADDL	b,		a
-
-TEXT	·block(SB),NOSPLIT,$24-16
-	MOVL	dig+0(FP),	BP
-	MOVL	p+4(FP),	SI
-	MOVL	p_len+8(FP), DX
-	SHRL	$6,		DX
-	SHLL	$6,		DX
-
-	LEAL	(SI)(DX*1),	DI
-	MOVL	(0*4)(BP),	AX
-	MOVL	(1*4)(BP),	BX
-	MOVL	(2*4)(BP),	CX
-	MOVL	(3*4)(BP),	DX
-
-	CMPL	SI,		DI
-	JEQ	end
-
-	MOVL	DI,		16(SP)
-
-loop:
-	MOVL	AX,		0(SP)
-	MOVL	BX,		4(SP)
-	MOVL	CX,		8(SP)
-	MOVL	DX,		12(SP)
-
-	MOVL	(0*4)(SI),	DI
-	MOVL	DX,		BP
-
-	ROUND1(AX,BX,CX,DX, 1,0xd76aa478, 7);
-	ROUND1(DX,AX,BX,CX, 2,0xe8c7b756,12);
-	ROUND1(CX,DX,AX,BX, 3,0x242070db,17);
-	ROUND1(BX,CX,DX,AX, 4,0xc1bdceee,22);
-	ROUND1(AX,BX,CX,DX, 5,0xf57c0faf, 7);
-	ROUND1(DX,AX,BX,CX, 6,0x4787c62a,12);
-	ROUND1(CX,DX,AX,BX, 7,0xa8304613,17);
-	ROUND1(BX,CX,DX,AX, 8,0xfd469501,22);
-	ROUND1(AX,BX,CX,DX, 9,0x698098d8, 7);
-	ROUND1(DX,AX,BX,CX,10,0x8b44f7af,12);
-	ROUND1(CX,DX,AX,BX,11,0xffff5bb1,17);
-	ROUND1(BX,CX,DX,AX,12,0x895cd7be,22);
-	ROUND1(AX,BX,CX,DX,13,0x6b901122, 7);
-	ROUND1(DX,AX,BX,CX,14,0xfd987193,12);
-	ROUND1(CX,DX,AX,BX,15,0xa679438e,17);
-	ROUND1(BX,CX,DX,AX, 0,0x49b40821,22);
-
-	MOVL	(1*4)(SI),	DI
-	MOVL	DX,		BP
-
-	ROUND2(AX,BX,CX,DX, 6,0xf61e2562, 5);
-	ROUND2(DX,AX,BX,CX,11,0xc040b340, 9);
-	ROUND2(CX,DX,AX,BX, 0,0x265e5a51,14);
-	ROUND2(BX,CX,DX,AX, 5,0xe9b6c7aa,20);
-	ROUND2(AX,BX,CX,DX,10,0xd62f105d, 5);
-	ROUND2(DX,AX,BX,CX,15, 0x2441453, 9);
-	ROUND2(CX,DX,AX,BX, 4,0xd8a1e681,14);
-	ROUND2(BX,CX,DX,AX, 9,0xe7d3fbc8,20);
-	ROUND2(AX,BX,CX,DX,14,0x21e1cde6, 5);
-	ROUND2(DX,AX,BX,CX, 3,0xc33707d6, 9);
-	ROUND2(CX,DX,AX,BX, 8,0xf4d50d87,14);
-	ROUND2(BX,CX,DX,AX,13,0x455a14ed,20);
-	ROUND2(AX,BX,CX,DX, 2,0xa9e3e905, 5);
-	ROUND2(DX,AX,BX,CX, 7,0xfcefa3f8, 9);
-	ROUND2(CX,DX,AX,BX,12,0x676f02d9,14);
-	ROUND2(BX,CX,DX,AX, 0,0x8d2a4c8a,20);
- 
-	MOVL	(5*4)(SI),	DI
-	MOVL	CX,		BP
-
-	ROUND3(AX,BX,CX,DX, 8,0xfffa3942, 4);
-	ROUND3(DX,AX,BX,CX,11,0x8771f681,11);
-	ROUND3(CX,DX,AX,BX,14,0x6d9d6122,16);
-	ROUND3(BX,CX,DX,AX, 1,0xfde5380c,23);
-	ROUND3(AX,BX,CX,DX, 4,0xa4beea44, 4);
-	ROUND3(DX,AX,BX,CX, 7,0x4bdecfa9,11);
-	ROUND3(CX,DX,AX,BX,10,0xf6bb4b60,16);
-	ROUND3(BX,CX,DX,AX,13,0xbebfbc70,23);
-	ROUND3(AX,BX,CX,DX, 0,0x289b7ec6, 4);
-	ROUND3(DX,AX,BX,CX, 3,0xeaa127fa,11);
-	ROUND3(CX,DX,AX,BX, 6,0xd4ef3085,16);
-	ROUND3(BX,CX,DX,AX, 9, 0x4881d05,23);
-	ROUND3(AX,BX,CX,DX,12,0xd9d4d039, 4);
-	ROUND3(DX,AX,BX,CX,15,0xe6db99e5,11);
-	ROUND3(CX,DX,AX,BX, 2,0x1fa27cf8,16);
-	ROUND3(BX,CX,DX,AX, 0,0xc4ac5665,23);
-
-	MOVL	(0*4)(SI),	DI
-	MOVL	$0xffffffff,	BP
-	XORL	DX,		BP
-
-	ROUND4(AX,BX,CX,DX, 7,0xf4292244, 6);
-	ROUND4(DX,AX,BX,CX,14,0x432aff97,10);
-	ROUND4(CX,DX,AX,BX, 5,0xab9423a7,15);
-	ROUND4(BX,CX,DX,AX,12,0xfc93a039,21);
-	ROUND4(AX,BX,CX,DX, 3,0x655b59c3, 6);
-	ROUND4(DX,AX,BX,CX,10,0x8f0ccc92,10);
-	ROUND4(CX,DX,AX,BX, 1,0xffeff47d,15);
-	ROUND4(BX,CX,DX,AX, 8,0x85845dd1,21);
-	ROUND4(AX,BX,CX,DX,15,0x6fa87e4f, 6);
-	ROUND4(DX,AX,BX,CX, 6,0xfe2ce6e0,10);
-	ROUND4(CX,DX,AX,BX,13,0xa3014314,15);
-	ROUND4(BX,CX,DX,AX, 4,0x4e0811a1,21);
-	ROUND4(AX,BX,CX,DX,11,0xf7537e82, 6);
-	ROUND4(DX,AX,BX,CX, 2,0xbd3af235,10);
-	ROUND4(CX,DX,AX,BX, 9,0x2ad7d2bb,15);
-	ROUND4(BX,CX,DX,AX, 0,0xeb86d391,21);
-
-	ADDL	0(SP),	AX
-	ADDL	4(SP),	BX
-	ADDL	8(SP),	CX
-	ADDL	12(SP),	DX
-
-	ADDL	$64,		SI
-	CMPL	SI,		16(SP)
-	JB	loop
-
-end:
-	MOVL	dig+0(FP),	BP
-	MOVL	AX,		(0*4)(BP)
-	MOVL	BX,		(1*4)(BP)
-	MOVL	CX,		(2*4)(BP)
-	MOVL	DX,		(3*4)(BP)
-	RET
diff --git a/src/pkg/crypto/md5/md5block_amd64.s b/src/pkg/crypto/md5/md5block_amd64.s
deleted file mode 100644
index 178e49c..0000000
--- a/src/pkg/crypto/md5/md5block_amd64.s
+++ /dev/null
@@ -1,179 +0,0 @@
-// Original source:
-//	http://www.zorinaq.com/papers/md5-amd64.html
-//	http://www.zorinaq.com/papers/md5-amd64.tar.bz2
-//
-// Translated from Perl generating GNU assembly into
-// #defines generating 6a assembly by the Go Authors.
-
-#include "../../../cmd/ld/textflag.h"
-
-// MD5 optimized for AMD64.
-//
-// Author: Marc Bevand <bevand_m (at) epita.fr>
-// Licence: I hereby disclaim the copyright on this code and place it
-// in the public domain.
-
-TEXT	·block(SB),NOSPLIT,$0-32
-	MOVQ	dig+0(FP),	BP
-	MOVQ	p+8(FP),	SI
-	MOVQ	p_len+16(FP), DX
-	SHRQ	$6,		DX
-	SHLQ	$6,		DX
-
-	LEAQ	(SI)(DX*1),	DI
-	MOVL	(0*4)(BP),	AX
-	MOVL	(1*4)(BP),	BX
-	MOVL	(2*4)(BP),	CX
-	MOVL	(3*4)(BP),	DX
-
-	CMPQ	SI,		DI
-	JEQ	end
-
-loop:
-	MOVL	AX,		R12
-	MOVL	BX,		R13
-	MOVL	CX,		R14
-	MOVL	DX,		R15
-
-	MOVL	(0*4)(SI),	R8
-	MOVL	DX,		R9
-
-#define ROUND1(a, b, c, d, index, const, shift) \
-	XORL	c, R9; \
-	LEAL	const(a)(R8*1), a; \
-	ANDL	b, R9; \
-	XORL d, R9; \
-	MOVL (index*4)(SI), R8; \
-	ADDL R9, a; \
-	ROLL $shift, a; \
-	MOVL c, R9; \
-	ADDL b, a
-
-	ROUND1(AX,BX,CX,DX, 1,0xd76aa478, 7);
-	ROUND1(DX,AX,BX,CX, 2,0xe8c7b756,12);
-	ROUND1(CX,DX,AX,BX, 3,0x242070db,17);
-	ROUND1(BX,CX,DX,AX, 4,0xc1bdceee,22);
-	ROUND1(AX,BX,CX,DX, 5,0xf57c0faf, 7);
-	ROUND1(DX,AX,BX,CX, 6,0x4787c62a,12);
-	ROUND1(CX,DX,AX,BX, 7,0xa8304613,17);
-	ROUND1(BX,CX,DX,AX, 8,0xfd469501,22);
-	ROUND1(AX,BX,CX,DX, 9,0x698098d8, 7);
-	ROUND1(DX,AX,BX,CX,10,0x8b44f7af,12);
-	ROUND1(CX,DX,AX,BX,11,0xffff5bb1,17);
-	ROUND1(BX,CX,DX,AX,12,0x895cd7be,22);
-	ROUND1(AX,BX,CX,DX,13,0x6b901122, 7);
-	ROUND1(DX,AX,BX,CX,14,0xfd987193,12);
-	ROUND1(CX,DX,AX,BX,15,0xa679438e,17);
-	ROUND1(BX,CX,DX,AX, 0,0x49b40821,22);
-
-	MOVL	(1*4)(SI),	R8
-	MOVL	DX,		R9
-	MOVL	DX,		R10
-
-#define ROUND2(a, b, c, d, index, const, shift) \
-	NOTL	R9; \
-	LEAL	const(a)(R8*1),a; \
-	ANDL	b,		R10; \
-	ANDL	c,		R9; \
-	MOVL	(index*4)(SI),R8; \
-	ORL	R9,		R10; \
-	MOVL	c,		R9; \
-	ADDL	R10,		a; \
-	MOVL	c,		R10; \
-	ROLL	$shift,	a; \
-	ADDL	b,		a
-
-	ROUND2(AX,BX,CX,DX, 6,0xf61e2562, 5);
-	ROUND2(DX,AX,BX,CX,11,0xc040b340, 9);
-	ROUND2(CX,DX,AX,BX, 0,0x265e5a51,14);
-	ROUND2(BX,CX,DX,AX, 5,0xe9b6c7aa,20);
-	ROUND2(AX,BX,CX,DX,10,0xd62f105d, 5);
-	ROUND2(DX,AX,BX,CX,15, 0x2441453, 9);
-	ROUND2(CX,DX,AX,BX, 4,0xd8a1e681,14);
-	ROUND2(BX,CX,DX,AX, 9,0xe7d3fbc8,20);
-	ROUND2(AX,BX,CX,DX,14,0x21e1cde6, 5);
-	ROUND2(DX,AX,BX,CX, 3,0xc33707d6, 9);
-	ROUND2(CX,DX,AX,BX, 8,0xf4d50d87,14);
-	ROUND2(BX,CX,DX,AX,13,0x455a14ed,20);
-	ROUND2(AX,BX,CX,DX, 2,0xa9e3e905, 5);
-	ROUND2(DX,AX,BX,CX, 7,0xfcefa3f8, 9);
-	ROUND2(CX,DX,AX,BX,12,0x676f02d9,14);
-	ROUND2(BX,CX,DX,AX, 0,0x8d2a4c8a,20);
- 
-	MOVL	(5*4)(SI),	R8
-	MOVL	CX,		R9
-
-#define ROUND3(a, b, c, d, index, const, shift) \
-	LEAL	const(a)(R8*1),a; \
-	MOVL	(index*4)(SI),R8; \
-	XORL	d,		R9; \
-	XORL	b,		R9; \
-	ADDL	R9,		a; \
-	ROLL	$shift,		a; \
-	MOVL	b,		R9; \
-	ADDL	b,		a
-
-	ROUND3(AX,BX,CX,DX, 8,0xfffa3942, 4);
-	ROUND3(DX,AX,BX,CX,11,0x8771f681,11);
-	ROUND3(CX,DX,AX,BX,14,0x6d9d6122,16);
-	ROUND3(BX,CX,DX,AX, 1,0xfde5380c,23);
-	ROUND3(AX,BX,CX,DX, 4,0xa4beea44, 4);
-	ROUND3(DX,AX,BX,CX, 7,0x4bdecfa9,11);
-	ROUND3(CX,DX,AX,BX,10,0xf6bb4b60,16);
-	ROUND3(BX,CX,DX,AX,13,0xbebfbc70,23);
-	ROUND3(AX,BX,CX,DX, 0,0x289b7ec6, 4);
-	ROUND3(DX,AX,BX,CX, 3,0xeaa127fa,11);
-	ROUND3(CX,DX,AX,BX, 6,0xd4ef3085,16);
-	ROUND3(BX,CX,DX,AX, 9, 0x4881d05,23);
-	ROUND3(AX,BX,CX,DX,12,0xd9d4d039, 4);
-	ROUND3(DX,AX,BX,CX,15,0xe6db99e5,11);
-	ROUND3(CX,DX,AX,BX, 2,0x1fa27cf8,16);
-	ROUND3(BX,CX,DX,AX, 0,0xc4ac5665,23);
-
-	MOVL	(0*4)(SI),	R8
-	MOVL	$0xffffffff,	R9
-	XORL	DX,		R9
-
-#define ROUND4(a, b, c, d, index, const, shift) \
-	LEAL	const(a)(R8*1),a; \
-	ORL	b,		R9; \
-	XORL	c,		R9; \
-	ADDL	R9,		a; \
-	MOVL	(index*4)(SI),R8; \
-	MOVL	$0xffffffff,	R9; \
-	ROLL	$shift,		a; \
-	XORL	c,		R9; \
-	ADDL	b,		a
-	
-	ROUND4(AX,BX,CX,DX, 7,0xf4292244, 6);
-	ROUND4(DX,AX,BX,CX,14,0x432aff97,10);
-	ROUND4(CX,DX,AX,BX, 5,0xab9423a7,15);
-	ROUND4(BX,CX,DX,AX,12,0xfc93a039,21);
-	ROUND4(AX,BX,CX,DX, 3,0x655b59c3, 6);
-	ROUND4(DX,AX,BX,CX,10,0x8f0ccc92,10);
-	ROUND4(CX,DX,AX,BX, 1,0xffeff47d,15);
-	ROUND4(BX,CX,DX,AX, 8,0x85845dd1,21);
-	ROUND4(AX,BX,CX,DX,15,0x6fa87e4f, 6);
-	ROUND4(DX,AX,BX,CX, 6,0xfe2ce6e0,10);
-	ROUND4(CX,DX,AX,BX,13,0xa3014314,15);
-	ROUND4(BX,CX,DX,AX, 4,0x4e0811a1,21);
-	ROUND4(AX,BX,CX,DX,11,0xf7537e82, 6);
-	ROUND4(DX,AX,BX,CX, 2,0xbd3af235,10);
-	ROUND4(CX,DX,AX,BX, 9,0x2ad7d2bb,15);
-	ROUND4(BX,CX,DX,AX, 0,0xeb86d391,21);
-
-	ADDL	R12,	AX
-	ADDL	R13,	BX
-	ADDL	R14,	CX
-	ADDL	R15,	DX
-
-	ADDQ	$64,		SI
-	CMPQ	SI,		DI
-	JB	loop
-
-end:
-	MOVL	AX,		(0*4)(BP)
-	MOVL	BX,		(1*4)(BP)
-	MOVL	CX,		(2*4)(BP)
-	MOVL	DX,		(3*4)(BP)
-	RET
diff --git a/src/pkg/crypto/md5/md5block_amd64p32.s b/src/pkg/crypto/md5/md5block_amd64p32.s
deleted file mode 100644
index a78a3f6..0000000
--- a/src/pkg/crypto/md5/md5block_amd64p32.s
+++ /dev/null
@@ -1,184 +0,0 @@
-// Original source:
-//	http://www.zorinaq.com/papers/md5-amd64.html
-//	http://www.zorinaq.com/papers/md5-amd64.tar.bz2
-//
-// Translated from Perl generating GNU assembly into
-// #defines generating 6a assembly by the Go Authors.
-//
-// Restrictions to make code safe for Native Client:
-// replace BP with R11, reloaded before use at return.
-// replace R15 with R11.
-
-#include "../../../cmd/ld/textflag.h"
-
-// MD5 optimized for AMD64.
-//
-// Author: Marc Bevand <bevand_m (at) epita.fr>
-// Licence: I hereby disclaim the copyright on this code and place it
-// in the public domain.
-
-TEXT	·block(SB),NOSPLIT,$0-32
-	MOVL	dig+0(FP),	R11
-	MOVL	p+4(FP),	SI
-	MOVL	p_len+8(FP), DX
-	SHRQ	$6,		DX
-	SHLQ	$6,		DX
-
-	LEAQ	(SI)(DX*1),	DI
-	MOVL	(0*4)(R11),	AX
-	MOVL	(1*4)(R11),	BX
-	MOVL	(2*4)(R11),	CX
-	MOVL	(3*4)(R11),	DX
-
-	CMPQ	SI,		DI
-	JEQ	end
-
-loop:
-	MOVL	AX,		R12
-	MOVL	BX,		R13
-	MOVL	CX,		R14
-	MOVL	DX,		R11
-
-	MOVL	(0*4)(SI),	R8
-	MOVL	DX,		R9
-
-#define ROUND1(a, b, c, d, index, const, shift) \
-	XORL	c, R9; \
-	LEAL	const(a)(R8*1), a; \
-	ANDL	b, R9; \
-	XORL d, R9; \
-	MOVL (index*4)(SI), R8; \
-	ADDL R9, a; \
-	ROLL $shift, a; \
-	MOVL c, R9; \
-	ADDL b, a
-
-	ROUND1(AX,BX,CX,DX, 1,0xd76aa478, 7);
-	ROUND1(DX,AX,BX,CX, 2,0xe8c7b756,12);
-	ROUND1(CX,DX,AX,BX, 3,0x242070db,17);
-	ROUND1(BX,CX,DX,AX, 4,0xc1bdceee,22);
-	ROUND1(AX,BX,CX,DX, 5,0xf57c0faf, 7);
-	ROUND1(DX,AX,BX,CX, 6,0x4787c62a,12);
-	ROUND1(CX,DX,AX,BX, 7,0xa8304613,17);
-	ROUND1(BX,CX,DX,AX, 8,0xfd469501,22);
-	ROUND1(AX,BX,CX,DX, 9,0x698098d8, 7);
-	ROUND1(DX,AX,BX,CX,10,0x8b44f7af,12);
-	ROUND1(CX,DX,AX,BX,11,0xffff5bb1,17);
-	ROUND1(BX,CX,DX,AX,12,0x895cd7be,22);
-	ROUND1(AX,BX,CX,DX,13,0x6b901122, 7);
-	ROUND1(DX,AX,BX,CX,14,0xfd987193,12);
-	ROUND1(CX,DX,AX,BX,15,0xa679438e,17);
-	ROUND1(BX,CX,DX,AX, 0,0x49b40821,22);
-
-	MOVL	(1*4)(SI),	R8
-	MOVL	DX,		R9
-	MOVL	DX,		R10
-
-#define ROUND2(a, b, c, d, index, const, shift) \
-	NOTL	R9; \
-	LEAL	const(a)(R8*1),a; \
-	ANDL	b,		R10; \
-	ANDL	c,		R9; \
-	MOVL	(index*4)(SI),R8; \
-	ORL	R9,		R10; \
-	MOVL	c,		R9; \
-	ADDL	R10,		a; \
-	MOVL	c,		R10; \
-	ROLL	$shift,	a; \
-	ADDL	b,		a
-
-	ROUND2(AX,BX,CX,DX, 6,0xf61e2562, 5);
-	ROUND2(DX,AX,BX,CX,11,0xc040b340, 9);
-	ROUND2(CX,DX,AX,BX, 0,0x265e5a51,14);
-	ROUND2(BX,CX,DX,AX, 5,0xe9b6c7aa,20);
-	ROUND2(AX,BX,CX,DX,10,0xd62f105d, 5);
-	ROUND2(DX,AX,BX,CX,15, 0x2441453, 9);
-	ROUND2(CX,DX,AX,BX, 4,0xd8a1e681,14);
-	ROUND2(BX,CX,DX,AX, 9,0xe7d3fbc8,20);
-	ROUND2(AX,BX,CX,DX,14,0x21e1cde6, 5);
-	ROUND2(DX,AX,BX,CX, 3,0xc33707d6, 9);
-	ROUND2(CX,DX,AX,BX, 8,0xf4d50d87,14);
-	ROUND2(BX,CX,DX,AX,13,0x455a14ed,20);
-	ROUND2(AX,BX,CX,DX, 2,0xa9e3e905, 5);
-	ROUND2(DX,AX,BX,CX, 7,0xfcefa3f8, 9);
-	ROUND2(CX,DX,AX,BX,12,0x676f02d9,14);
-	ROUND2(BX,CX,DX,AX, 0,0x8d2a4c8a,20);
- 
-	MOVL	(5*4)(SI),	R8
-	MOVL	CX,		R9
-
-#define ROUND3(a, b, c, d, index, const, shift) \
-	LEAL	const(a)(R8*1),a; \
-	MOVL	(index*4)(SI),R8; \
-	XORL	d,		R9; \
-	XORL	b,		R9; \
-	ADDL	R9,		a; \
-	ROLL	$shift,		a; \
-	MOVL	b,		R9; \
-	ADDL	b,		a
-
-	ROUND3(AX,BX,CX,DX, 8,0xfffa3942, 4);
-	ROUND3(DX,AX,BX,CX,11,0x8771f681,11);
-	ROUND3(CX,DX,AX,BX,14,0x6d9d6122,16);
-	ROUND3(BX,CX,DX,AX, 1,0xfde5380c,23);
-	ROUND3(AX,BX,CX,DX, 4,0xa4beea44, 4);
-	ROUND3(DX,AX,BX,CX, 7,0x4bdecfa9,11);
-	ROUND3(CX,DX,AX,BX,10,0xf6bb4b60,16);
-	ROUND3(BX,CX,DX,AX,13,0xbebfbc70,23);
-	ROUND3(AX,BX,CX,DX, 0,0x289b7ec6, 4);
-	ROUND3(DX,AX,BX,CX, 3,0xeaa127fa,11);
-	ROUND3(CX,DX,AX,BX, 6,0xd4ef3085,16);
-	ROUND3(BX,CX,DX,AX, 9, 0x4881d05,23);
-	ROUND3(AX,BX,CX,DX,12,0xd9d4d039, 4);
-	ROUND3(DX,AX,BX,CX,15,0xe6db99e5,11);
-	ROUND3(CX,DX,AX,BX, 2,0x1fa27cf8,16);
-	ROUND3(BX,CX,DX,AX, 0,0xc4ac5665,23);
-
-	MOVL	(0*4)(SI),	R8
-	MOVL	$0xffffffff,	R9
-	XORL	DX,		R9
-
-#define ROUND4(a, b, c, d, index, const, shift) \
-	LEAL	const(a)(R8*1),a; \
-	ORL	b,		R9; \
-	XORL	c,		R9; \
-	ADDL	R9,		a; \
-	MOVL	(index*4)(SI),R8; \
-	MOVL	$0xffffffff,	R9; \
-	ROLL	$shift,		a; \
-	XORL	c,		R9; \
-	ADDL	b,		a
-	
-	ROUND4(AX,BX,CX,DX, 7,0xf4292244, 6);
-	ROUND4(DX,AX,BX,CX,14,0x432aff97,10);
-	ROUND4(CX,DX,AX,BX, 5,0xab9423a7,15);
-	ROUND4(BX,CX,DX,AX,12,0xfc93a039,21);
-	ROUND4(AX,BX,CX,DX, 3,0x655b59c3, 6);
-	ROUND4(DX,AX,BX,CX,10,0x8f0ccc92,10);
-	ROUND4(CX,DX,AX,BX, 1,0xffeff47d,15);
-	ROUND4(BX,CX,DX,AX, 8,0x85845dd1,21);
-	ROUND4(AX,BX,CX,DX,15,0x6fa87e4f, 6);
-	ROUND4(DX,AX,BX,CX, 6,0xfe2ce6e0,10);
-	ROUND4(CX,DX,AX,BX,13,0xa3014314,15);
-	ROUND4(BX,CX,DX,AX, 4,0x4e0811a1,21);
-	ROUND4(AX,BX,CX,DX,11,0xf7537e82, 6);
-	ROUND4(DX,AX,BX,CX, 2,0xbd3af235,10);
-	ROUND4(CX,DX,AX,BX, 9,0x2ad7d2bb,15);
-	ROUND4(BX,CX,DX,AX, 0,0xeb86d391,21);
-
-	ADDL	R12,	AX
-	ADDL	R13,	BX
-	ADDL	R14,	CX
-	ADDL	R11,	DX
-
-	ADDQ	$64,		SI
-	CMPQ	SI,		DI
-	JB	loop
-
-end:
-	MOVL	dig+0(FP),	R11
-	MOVL	AX,		(0*4)(R11)
-	MOVL	BX,		(1*4)(R11)
-	MOVL	CX,		(2*4)(R11)
-	MOVL	DX,		(3*4)(R11)
-	RET
diff --git a/src/pkg/crypto/md5/md5block_arm.s b/src/pkg/crypto/md5/md5block_arm.s
deleted file mode 100644
index e644bfc..0000000
--- a/src/pkg/crypto/md5/md5block_arm.s
+++ /dev/null
@@ -1,299 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-//
-// ARM version of md5block.go
-
-#include "../../../cmd/ld/textflag.h"
-
-// Register definitions
-table = 0	// Pointer to MD5 constants table
-data = 1	// Pointer to data to hash
-a = 2		// MD5 accumulator
-b = 3		// MD5 accumulator
-c = 4		// MD5 accumulator
-d = 5		// MD5 accumulator
-c0 = 6		// MD5 constant
-c1 = 7		// MD5 constant
-c2 = 8		// MD5 constant
-// r9, r10 are forbidden
-// r11 is OK provided you check the assembler that no synthetic instructions use it
-c3 = 11		// MD5 constant
-t0 = 12		// temporary
-t1 = 14		// temporary
-
-// func block(dig *digest, p []byte)
-// 0(FP) is *digest
-// 4(FP) is p.array (struct Slice)
-// 8(FP) is p.len
-//12(FP) is p.cap
-//
-// Stack frame
-p_end = -4	// -4(SP) pointer to the end of data
-p_data = -8	// -8(SP) current data pointer
-buf = -8-4*16	//-72(SP) 16 words temporary buffer
-		// 3 words at 4..12(R13) for called routine parameters
-
-TEXT	·block(SB), NOSPLIT, $84-16
-	MOVW	p+4(FP), R(data)	// pointer to the data
-	MOVW	p_len+8(FP), R(t0)	// number of bytes
-	ADD	R(data), R(t0)
-	MOVW	R(t0), p_end(SP)	// pointer to end of data
-
-loop:
-	MOVW	R(data), p_data(SP)	// Save R(data)
-	AND.S	$3, R(data), R(t0)	// TST $3, R(data) not working see issue 5921
-	BEQ	aligned			// aligned detected - skip copy
-
-	// Copy the unaligned source data into the aligned temporary buffer
-	// memove(to=4(R13), from=8(R13), n=12(R13)) - Corrupts all registers
-	MOVW	$buf(SP), R(table)	// to
-	MOVW	$64, R(c0)		// n
-	MOVM.IB	[R(table),R(data),R(c0)], (R13)
-	BL	runtime·memmove(SB)
-
-	// Point to the local aligned copy of the data
-	MOVW	$buf(SP), R(data)
-
-aligned:
-	// Point to the table of constants
-	// A PC relative add would be cheaper than this
-	MOVW	$·table(SB), R(table)
-
-	// Load up initial MD5 accumulator
-	MOVW	dig+0(FP), R(c0)
-	MOVM.IA (R(c0)), [R(a),R(b),R(c),R(d)]
-
-// a += (((c^d)&b)^d) + X[index] + const
-// a = a<<shift | a>>(32-shift) + b
-#define ROUND1(a, b, c, d, index, shift, const) \
-	EOR	R(c), R(d), R(t0)		; \
-	AND	R(b), R(t0)			; \
-	EOR	R(d), R(t0)			; \
-	MOVW	(index<<2)(R(data)), R(t1)	; \
-	ADD	R(t1), R(t0)			; \
-	ADD	R(const), R(t0)			; \
-	ADD	R(t0), R(a)			; \
-	ADD	R(a)@>(32-shift), R(b), R(a)	;
-
-	MOVM.IA.W (R(table)), [R(c0),R(c1),R(c2),R(c3)]
-	ROUND1(a, b, c, d,  0,	7, c0)
-	ROUND1(d, a, b, c,  1, 12, c1)
-	ROUND1(c, d, a, b,  2, 17, c2)
-	ROUND1(b, c, d, a,  3, 22, c3)
-
-	MOVM.IA.W (R(table)), [R(c0),R(c1),R(c2),R(c3)]
-	ROUND1(a, b, c, d,  4,	7, c0)
-	ROUND1(d, a, b, c,  5, 12, c1)
-	ROUND1(c, d, a, b,  6, 17, c2)
-	ROUND1(b, c, d, a,  7, 22, c3)
-
-	MOVM.IA.W (R(table)), [R(c0),R(c1),R(c2),R(c3)]
-	ROUND1(a, b, c, d,  8,	7, c0)
-	ROUND1(d, a, b, c,  9, 12, c1)
-	ROUND1(c, d, a, b, 10, 17, c2)
-	ROUND1(b, c, d, a, 11, 22, c3)
-
-	MOVM.IA.W (R(table)), [R(c0),R(c1),R(c2),R(c3)]
-	ROUND1(a, b, c, d, 12,	7, c0)
-	ROUND1(d, a, b, c, 13, 12, c1)
-	ROUND1(c, d, a, b, 14, 17, c2)
-	ROUND1(b, c, d, a, 15, 22, c3)
-
-// a += (((b^c)&d)^c) + X[index] + const
-// a = a<<shift | a>>(32-shift) + b
-#define ROUND2(a, b, c, d, index, shift, const) \
-	EOR	R(b), R(c), R(t0)		; \
-	AND	R(d), R(t0)			; \
-	EOR	R(c), R(t0)			; \
-	MOVW	(index<<2)(R(data)), R(t1)	; \
-	ADD	R(t1), R(t0)			; \
-	ADD	R(const), R(t0)			; \
-	ADD	R(t0), R(a)			; \
-	ADD	R(a)@>(32-shift), R(b), R(a)	;
-
-	MOVM.IA.W (R(table)), [R(c0),R(c1),R(c2),R(c3)]
-	ROUND2(a, b, c, d,  1,	5, c0)
-	ROUND2(d, a, b, c,  6,	9, c1)
-	ROUND2(c, d, a, b, 11, 14, c2)
-	ROUND2(b, c, d, a,  0, 20, c3)
-
-	MOVM.IA.W (R(table)), [R(c0),R(c1),R(c2),R(c3)]
-	ROUND2(a, b, c, d,  5,	5, c0)
-	ROUND2(d, a, b, c, 10,	9, c1)
-	ROUND2(c, d, a, b, 15, 14, c2)
-	ROUND2(b, c, d, a,  4, 20, c3)
-
-	MOVM.IA.W (R(table)), [R(c0),R(c1),R(c2),R(c3)]
-	ROUND2(a, b, c, d,  9,	5, c0)
-	ROUND2(d, a, b, c, 14,	9, c1)
-	ROUND2(c, d, a, b,  3, 14, c2)
-	ROUND2(b, c, d, a,  8, 20, c3)
-
-	MOVM.IA.W (R(table)), [R(c0),R(c1),R(c2),R(c3)]
-	ROUND2(a, b, c, d, 13,	5, c0)
-	ROUND2(d, a, b, c,  2,	9, c1)
-	ROUND2(c, d, a, b,  7, 14, c2)
-	ROUND2(b, c, d, a, 12, 20, c3)
-
-// a += (b^c^d) + X[index] + const
-// a = a<<shift | a>>(32-shift) + b
-#define ROUND3(a, b, c, d, index, shift, const) \
-	EOR	R(b), R(c), R(t0)		; \
-	EOR	R(d), R(t0)			; \
-	MOVW	(index<<2)(R(data)), R(t1)	; \
-	ADD	R(t1), R(t0)			; \
-	ADD	R(const), R(t0)			; \
-	ADD	R(t0), R(a)			; \
-	ADD	R(a)@>(32-shift), R(b), R(a)	;
-
-	MOVM.IA.W (R(table)), [R(c0),R(c1),R(c2),R(c3)]
-	ROUND3(a, b, c, d,  5,	4, c0)
-	ROUND3(d, a, b, c,  8, 11, c1)
-	ROUND3(c, d, a, b, 11, 16, c2)
-	ROUND3(b, c, d, a, 14, 23, c3)
-
-	MOVM.IA.W (R(table)), [R(c0),R(c1),R(c2),R(c3)]
-	ROUND3(a, b, c, d,  1,	4, c0)
-	ROUND3(d, a, b, c,  4, 11, c1)
-	ROUND3(c, d, a, b,  7, 16, c2)
-	ROUND3(b, c, d, a, 10, 23, c3)
-
-	MOVM.IA.W (R(table)), [R(c0),R(c1),R(c2),R(c3)]
-	ROUND3(a, b, c, d, 13,	4, c0)
-	ROUND3(d, a, b, c,  0, 11, c1)
-	ROUND3(c, d, a, b,  3, 16, c2)
-	ROUND3(b, c, d, a,  6, 23, c3)
-
-	MOVM.IA.W (R(table)), [R(c0),R(c1),R(c2),R(c3)]
-	ROUND3(a, b, c, d,  9,	4, c0)
-	ROUND3(d, a, b, c, 12, 11, c1)
-	ROUND3(c, d, a, b, 15, 16, c2)
-	ROUND3(b, c, d, a,  2, 23, c3)
-
-// a += (c^(b|^d)) + X[index] + const
-// a = a<<shift | a>>(32-shift) + b
-#define ROUND4(a, b, c, d, index, shift, const) \
-	MVN	R(d), R(t0)			; \
-	ORR	R(b), R(t0)			; \
-	EOR	R(c), R(t0)			; \
-	MOVW	(index<<2)(R(data)), R(t1)	; \
-	ADD	R(t1), R(t0)			; \
-	ADD	R(const), R(t0)			; \
-	ADD	R(t0), R(a)			; \
-	ADD	R(a)@>(32-shift), R(b), R(a)	;
-
-	MOVM.IA.W (R(table)), [R(c0),R(c1),R(c2),R(c3)]
-	ROUND4(a, b, c, d,  0,	6, c0)
-	ROUND4(d, a, b, c,  7, 10, c1)
-	ROUND4(c, d, a, b, 14, 15, c2)
-	ROUND4(b, c, d, a,  5, 21, c3)
-
-	MOVM.IA.W (R(table)), [R(c0),R(c1),R(c2),R(c3)]
-	ROUND4(a, b, c, d, 12,	6, c0)
-	ROUND4(d, a, b, c,  3, 10, c1)
-	ROUND4(c, d, a, b, 10, 15, c2)
-	ROUND4(b, c, d, a,  1, 21, c3)
-
-	MOVM.IA.W (R(table)), [R(c0),R(c1),R(c2),R(c3)]
-	ROUND4(a, b, c, d,  8,	6, c0)
-	ROUND4(d, a, b, c, 15, 10, c1)
-	ROUND4(c, d, a, b,  6, 15, c2)
-	ROUND4(b, c, d, a, 13, 21, c3)
-
-	MOVM.IA.W (R(table)), [R(c0),R(c1),R(c2),R(c3)]
-	ROUND4(a, b, c, d,  4,	6, c0)
-	ROUND4(d, a, b, c, 11, 10, c1)
-	ROUND4(c, d, a, b,  2, 15, c2)
-	ROUND4(b, c, d, a,  9, 21, c3)
-
-	MOVW	dig+0(FP), R(t0)
-	MOVM.IA (R(t0)), [R(c0),R(c1),R(c2),R(c3)]
-
-	ADD	R(c0), R(a)
-	ADD	R(c1), R(b)
-	ADD	R(c2), R(c)
-	ADD	R(c3), R(d)
-
-	MOVM.IA [R(a),R(b),R(c),R(d)], (R(t0))
-
-	MOVW	p_data(SP), R(data)
-	MOVW	p_end(SP), R(t0)
-	ADD	$64, R(data)
-	CMP	R(t0), R(data)
-	BLO	loop
-
-	RET
-
-// MD5 constants table
-
-	// Round 1
-	DATA	·table+0x00(SB)/4, $0xd76aa478
-	DATA	·table+0x04(SB)/4, $0xe8c7b756
-	DATA	·table+0x08(SB)/4, $0x242070db
-	DATA	·table+0x0c(SB)/4, $0xc1bdceee
-	DATA	·table+0x10(SB)/4, $0xf57c0faf
-	DATA	·table+0x14(SB)/4, $0x4787c62a
-	DATA	·table+0x18(SB)/4, $0xa8304613
-	DATA	·table+0x1c(SB)/4, $0xfd469501
-	DATA	·table+0x20(SB)/4, $0x698098d8
-	DATA	·table+0x24(SB)/4, $0x8b44f7af
-	DATA	·table+0x28(SB)/4, $0xffff5bb1
-	DATA	·table+0x2c(SB)/4, $0x895cd7be
-	DATA	·table+0x30(SB)/4, $0x6b901122
-	DATA	·table+0x34(SB)/4, $0xfd987193
-	DATA	·table+0x38(SB)/4, $0xa679438e
-	DATA	·table+0x3c(SB)/4, $0x49b40821
-	// Round 2
-	DATA	·table+0x40(SB)/4, $0xf61e2562
-	DATA	·table+0x44(SB)/4, $0xc040b340
-	DATA	·table+0x48(SB)/4, $0x265e5a51
-	DATA	·table+0x4c(SB)/4, $0xe9b6c7aa
-	DATA	·table+0x50(SB)/4, $0xd62f105d
-	DATA	·table+0x54(SB)/4, $0x02441453
-	DATA	·table+0x58(SB)/4, $0xd8a1e681
-	DATA	·table+0x5c(SB)/4, $0xe7d3fbc8
-	DATA	·table+0x60(SB)/4, $0x21e1cde6
-	DATA	·table+0x64(SB)/4, $0xc33707d6
-	DATA	·table+0x68(SB)/4, $0xf4d50d87
-	DATA	·table+0x6c(SB)/4, $0x455a14ed
-	DATA	·table+0x70(SB)/4, $0xa9e3e905
-	DATA	·table+0x74(SB)/4, $0xfcefa3f8
-	DATA	·table+0x78(SB)/4, $0x676f02d9
-	DATA	·table+0x7c(SB)/4, $0x8d2a4c8a
-	// Round 3
-	DATA	·table+0x80(SB)/4, $0xfffa3942
-	DATA	·table+0x84(SB)/4, $0x8771f681
-	DATA	·table+0x88(SB)/4, $0x6d9d6122
-	DATA	·table+0x8c(SB)/4, $0xfde5380c
-	DATA	·table+0x90(SB)/4, $0xa4beea44
-	DATA	·table+0x94(SB)/4, $0x4bdecfa9
-	DATA	·table+0x98(SB)/4, $0xf6bb4b60
-	DATA	·table+0x9c(SB)/4, $0xbebfbc70
-	DATA	·table+0xa0(SB)/4, $0x289b7ec6
-	DATA	·table+0xa4(SB)/4, $0xeaa127fa
-	DATA	·table+0xa8(SB)/4, $0xd4ef3085
-	DATA	·table+0xac(SB)/4, $0x04881d05
-	DATA	·table+0xb0(SB)/4, $0xd9d4d039
-	DATA	·table+0xb4(SB)/4, $0xe6db99e5
-	DATA	·table+0xb8(SB)/4, $0x1fa27cf8
-	DATA	·table+0xbc(SB)/4, $0xc4ac5665
-	// Round 4
-	DATA	·table+0xc0(SB)/4, $0xf4292244
-	DATA	·table+0xc4(SB)/4, $0x432aff97
-	DATA	·table+0xc8(SB)/4, $0xab9423a7
-	DATA	·table+0xcc(SB)/4, $0xfc93a039
-	DATA	·table+0xd0(SB)/4, $0x655b59c3
-	DATA	·table+0xd4(SB)/4, $0x8f0ccc92
-	DATA	·table+0xd8(SB)/4, $0xffeff47d
-	DATA	·table+0xdc(SB)/4, $0x85845dd1
-	DATA	·table+0xe0(SB)/4, $0x6fa87e4f
-	DATA	·table+0xe4(SB)/4, $0xfe2ce6e0
-	DATA	·table+0xe8(SB)/4, $0xa3014314
-	DATA	·table+0xec(SB)/4, $0x4e0811a1
-	DATA	·table+0xf0(SB)/4, $0xf7537e82
-	DATA	·table+0xf4(SB)/4, $0xbd3af235
-	DATA	·table+0xf8(SB)/4, $0x2ad7d2bb
-	DATA	·table+0xfc(SB)/4, $0xeb86d391
-	// Global definition
-	GLOBL	·table(SB),8,$256
diff --git a/src/pkg/crypto/rand/rand_unix.go b/src/pkg/crypto/rand/rand_unix.go
deleted file mode 100644
index 1e741fd..0000000
--- a/src/pkg/crypto/rand/rand_unix.go
+++ /dev/null
@@ -1,138 +0,0 @@
-// Copyright 2010 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build darwin dragonfly freebsd linux nacl netbsd openbsd plan9 solaris
-
-// Unix cryptographically secure pseudorandom number
-// generator.
-
-package rand
-
-import (
-	"bufio"
-	"crypto/aes"
-	"crypto/cipher"
-	"io"
-	"os"
-	"runtime"
-	"sync"
-	"time"
-)
-
-// Easy implementation: read from /dev/urandom.
-// This is sufficient on Linux, OS X, and FreeBSD.
-
-func init() {
-	if runtime.GOOS == "plan9" {
-		Reader = newReader(nil)
-	} else {
-		Reader = &devReader{name: "/dev/urandom"}
-	}
-}
-
-// A devReader satisfies reads by reading the file named name.
-type devReader struct {
-	name string
-	f    io.Reader
-	mu   sync.Mutex
-}
-
-func (r *devReader) Read(b []byte) (n int, err error) {
-	r.mu.Lock()
-	defer r.mu.Unlock()
-	if r.f == nil {
-		f, err := os.Open(r.name)
-		if f == nil {
-			return 0, err
-		}
-		if runtime.GOOS == "plan9" {
-			r.f = f
-		} else {
-			r.f = bufio.NewReader(f)
-		}
-	}
-	return r.f.Read(b)
-}
-
-// Alternate pseudo-random implementation for use on
-// systems without a reliable /dev/urandom.
-
-// newReader returns a new pseudorandom generator that
-// seeds itself by reading from entropy.  If entropy == nil,
-// the generator seeds itself by reading from the system's
-// random number generator, typically /dev/random.
-// The Read method on the returned reader always returns
-// the full amount asked for, or else it returns an error.
-//
-// The generator uses the X9.31 algorithm with AES-128,
-// reseeding after every 1 MB of generated data.
-func newReader(entropy io.Reader) io.Reader {
-	if entropy == nil {
-		entropy = &devReader{name: "/dev/random"}
-	}
-	return &reader{entropy: entropy}
-}
-
-type reader struct {
-	mu                   sync.Mutex
-	budget               int // number of bytes that can be generated
-	cipher               cipher.Block
-	entropy              io.Reader
-	time, seed, dst, key [aes.BlockSize]byte
-}
-
-func (r *reader) Read(b []byte) (n int, err error) {
-	r.mu.Lock()
-	defer r.mu.Unlock()
-	n = len(b)
-
-	for len(b) > 0 {
-		if r.budget == 0 {
-			_, err := io.ReadFull(r.entropy, r.seed[0:])
-			if err != nil {
-				return n - len(b), err
-			}
-			_, err = io.ReadFull(r.entropy, r.key[0:])
-			if err != nil {
-				return n - len(b), err
-			}
-			r.cipher, err = aes.NewCipher(r.key[0:])
-			if err != nil {
-				return n - len(b), err
-			}
-			r.budget = 1 << 20 // reseed after generating 1MB
-		}
-		r.budget -= aes.BlockSize
-
-		// ANSI X9.31 (== X9.17) algorithm, but using AES in place of 3DES.
-		//
-		// single block:
-		// t = encrypt(time)
-		// dst = encrypt(t^seed)
-		// seed = encrypt(t^dst)
-		ns := time.Now().UnixNano()
-		r.time[0] = byte(ns >> 56)
-		r.time[1] = byte(ns >> 48)
-		r.time[2] = byte(ns >> 40)
-		r.time[3] = byte(ns >> 32)
-		r.time[4] = byte(ns >> 24)
-		r.time[5] = byte(ns >> 16)
-		r.time[6] = byte(ns >> 8)
-		r.time[7] = byte(ns)
-		r.cipher.Encrypt(r.time[0:], r.time[0:])
-		for i := 0; i < aes.BlockSize; i++ {
-			r.dst[i] = r.time[i] ^ r.seed[i]
-		}
-		r.cipher.Encrypt(r.dst[0:], r.dst[0:])
-		for i := 0; i < aes.BlockSize; i++ {
-			r.seed[i] = r.time[i] ^ r.dst[i]
-		}
-		r.cipher.Encrypt(r.seed[0:], r.seed[0:])
-
-		m := copy(b, r.dst[0:])
-		b = b[m:]
-	}
-
-	return n, nil
-}
diff --git a/src/pkg/crypto/rc4/rc4_386.s b/src/pkg/crypto/rc4/rc4_386.s
deleted file mode 100644
index b04fc1f..0000000
--- a/src/pkg/crypto/rc4/rc4_386.s
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../../cmd/ld/textflag.h"
-
-// func xorKeyStream(dst, src *byte, n int, state *[256]byte, i, j *uint8)
-TEXT ·xorKeyStream(SB),NOSPLIT,$0
-	MOVL dst+0(FP), DI
-	MOVL src+4(FP), SI
-	MOVL state+12(FP), BP
-
-	MOVL i+16(FP), AX
-	MOVBLZX (AX), AX
-	MOVL j+20(FP), BX
-	MOVBLZX (BX), BX
-	CMPL n+8(FP), $0
-	JEQ done
-
-loop:
-	// i += 1
-	INCB AX
-
-	// j += c.s[i]
-	MOVBLZX (BP)(AX*4), DX
-	ADDB DX, BX
-	MOVBLZX BX, BX
-
-	// c.s[i], c.s[j] = c.s[j], c.s[i]
-	MOVBLZX (BP)(BX*4), CX
-	MOVB CX, (BP)(AX*4)
-	MOVB DX, (BP)(BX*4)
-
-	// *dst = *src ^ c.s[c.s[i]+c.s[j]]
-	ADDB DX, CX
-	MOVBLZX CX, CX
-	MOVB (BP)(CX*4), CX
-	XORB (SI), CX
-	MOVBLZX CX, CX
-	MOVB CX, (DI)
-
-	INCL SI
-	INCL DI
-	DECL n+8(FP)
-	JNE loop
-
-done:
-	MOVL i+16(FP), CX
-	MOVB AX, (CX)
-	MOVL j+20(FP), CX
-	MOVB BX, (CX)
-
-	RET
diff --git a/src/pkg/crypto/rc4/rc4_amd64.s b/src/pkg/crypto/rc4/rc4_amd64.s
deleted file mode 100644
index e3234b6..0000000
--- a/src/pkg/crypto/rc4/rc4_amd64.s
+++ /dev/null
@@ -1,179 +0,0 @@
-// Original source:
-//	http://www.zorinaq.com/papers/rc4-amd64.html
-//	http://www.zorinaq.com/papers/rc4-amd64.tar.bz2
-
-#include "../../../cmd/ld/textflag.h"
-
-// Local modifications:
-//
-// Transliterated from GNU to 6a assembly syntax by the Go authors.
-// The comments and spacing are from the original.
-//
-// The new EXTEND macros avoid a bad stall on some systems after 8-bit math.
-//
-// The original code accumulated 64 bits of key stream in an integer
-// register and then XOR'ed the key stream into the data 8 bytes at a time.
-// Modified to accumulate 128 bits of key stream into an XMM register
-// and then XOR the key stream into the data 16 bytes at a time.
-// Approximately doubles throughput.
-
-// NOTE: Changing EXTEND to a no-op makes the code run 1.2x faster on Core i5
-// but makes the code run 2.0x slower on Xeon.
-#define EXTEND(r) MOVBLZX r, r
-
-/*
-** RC4 implementation optimized for AMD64.
-**
-** Author: Marc Bevand <bevand_m (at) epita.fr>
-** Licence: I hereby disclaim the copyright on this code and place it
-** in the public domain.
-**
-** The code has been designed to be easily integrated into openssl:
-** the exported RC4() function can replace the actual implementations
-** openssl already contains. Please note that when linking with openssl,
-** it requires that sizeof(RC4_INT) == 8. So openssl must be compiled
-** with -DRC4_INT='unsigned long'.
-**
-** The throughput achieved by this code is about 320 MBytes/sec, on
-** a 1.8 GHz AMD Opteron (rev C0) processor.
-*/
-
-TEXT ·xorKeyStream(SB),NOSPLIT,$0
-	MOVQ	n+16(FP),	BX		// rbx = ARG(len)
-	MOVQ	src+8(FP),	SI		// in = ARG(in)
-	MOVQ	dst+0(FP),	DI		// out = ARG(out)
-	MOVQ	state+24(FP),	BP		// d = ARG(data)
-	MOVQ	i+32(FP),	AX
-	MOVBQZX	0(AX),		CX		// x = *xp
-	MOVQ	j+40(FP),	AX
-	MOVBQZX	0(AX),		DX		// y = *yp
-
-	LEAQ	(SI)(BX*1),	R9		// limit = in+len
-
-l1:	CMPQ	SI,		R9		// cmp in with in+len
-	JGE	finished			// jump if (in >= in+len)
-
-	INCB	CX
-	EXTEND(CX)
-	TESTL	$15,		CX
-	JZ	wordloop
-
-	MOVBLZX	(BP)(CX*4),	AX
-
-	ADDB	AX,		DX		// y += tx
-	EXTEND(DX)
-	MOVBLZX	(BP)(DX*4),	BX		// ty = d[y]
-	MOVB	BX,		(BP)(CX*4)	// d[x] = ty
-	ADDB	AX,		BX		// val = ty+tx
-	EXTEND(BX)
-	MOVB	AX,		(BP)(DX*4)	// d[y] = tx
-	MOVBLZX	(BP)(BX*4),	R8		// val = d[val]
-	XORB	(SI),		R8		// xor 1 byte
-	MOVB	R8,		(DI)
-	INCQ	SI				// in++
-	INCQ	DI				// out++
-	JMP l1
-
-wordloop:
-	SUBQ	$16,		R9
-	CMPQ	SI,		R9
-	JGT	end
-
-start:
-	ADDQ	$16,		SI		// increment in
-	ADDQ	$16,		DI		// increment out
-
-	// Each KEYROUND generates one byte of key and
-	// inserts it into an XMM register at the given 16-bit index.
-	// The key state array is uint32 words only using the bottom
-	// byte of each word, so the 16-bit OR only copies 8 useful bits.
-	// We accumulate alternating bytes into X0 and X1, and then at
-	// the end we OR X1<<8 into X0 to produce the actual key.
-	//
-	// At the beginning of the loop, CX%16 == 0, so the 16 loads
-	// at state[CX], state[CX+1], ..., state[CX+15] can precompute
-	// (state+CX) as R12 and then become R12[0], R12[1], ... R12[15],
-	// without fear of the byte computation CX+15 wrapping around.
-	//
-	// The first round needs R12[0], the second needs R12[1], and so on.
-	// We can avoid memory stalls by starting the load for round n+1
-	// before the end of round n, using the LOAD macro.
-	LEAQ	(BP)(CX*4),	R12
-
-#define KEYROUND(xmm, load, off, r1, r2, index) \
-	MOVBLZX	(BP)(DX*4),	R8; \
-	MOVB	r1,		(BP)(DX*4); \
-	load((off+1), r2); \
-	MOVB	R8,		(off*4)(R12); \
-	ADDB	r1,		R8; \
-	EXTEND(R8); \
-	PINSRW	$index, (BP)(R8*4), xmm
-
-#define LOAD(off, reg) \
-	MOVBLZX	(off*4)(R12),	reg; \
-	ADDB	reg,		DX; \
-	EXTEND(DX)
-
-#define SKIP(off, reg)
-
-	LOAD(0, AX)
-	KEYROUND(X0, LOAD, 0, AX, BX, 0)
-	KEYROUND(X1, LOAD, 1, BX, AX, 0)
-	KEYROUND(X0, LOAD, 2, AX, BX, 1)
-	KEYROUND(X1, LOAD, 3, BX, AX, 1)
-	KEYROUND(X0, LOAD, 4, AX, BX, 2)
-	KEYROUND(X1, LOAD, 5, BX, AX, 2)
-	KEYROUND(X0, LOAD, 6, AX, BX, 3)
-	KEYROUND(X1, LOAD, 7, BX, AX, 3)
-	KEYROUND(X0, LOAD, 8, AX, BX, 4)
-	KEYROUND(X1, LOAD, 9, BX, AX, 4)
-	KEYROUND(X0, LOAD, 10, AX, BX, 5)
-	KEYROUND(X1, LOAD, 11, BX, AX, 5)
-	KEYROUND(X0, LOAD, 12, AX, BX, 6)
-	KEYROUND(X1, LOAD, 13, BX, AX, 6)
-	KEYROUND(X0, LOAD, 14, AX, BX, 7)
-	KEYROUND(X1, SKIP, 15, BX, AX, 7)
-	
-	ADDB	$16,		CX
-
-	PSLLQ	$8,		X1
-	PXOR	X1,		X0
-	MOVOU	-16(SI),	X2
-	PXOR	X0,		X2
-	MOVOU	X2,		-16(DI)
-
-	CMPQ	SI,		R9		// cmp in with in+len-16
-	JLE	start				// jump if (in <= in+len-16)
-
-end:
-	DECB	CX
-	ADDQ	$16,		R9		// tmp = in+len
-
-	// handle the last bytes, one by one
-l2:	CMPQ	SI,		R9		// cmp in with in+len
-	JGE	finished			// jump if (in >= in+len)
-
-	INCB	CX
-	EXTEND(CX)
-	MOVBLZX	(BP)(CX*4),	AX
-
-	ADDB	AX,		DX		// y += tx
-	EXTEND(DX)
-	MOVBLZX	(BP)(DX*4),	BX		// ty = d[y]
-	MOVB	BX,		(BP)(CX*4)	// d[x] = ty
-	ADDB	AX,		BX		// val = ty+tx
-	EXTEND(BX)
-	MOVB	AX,		(BP)(DX*4)	// d[y] = tx
-	MOVBLZX	(BP)(BX*4),	R8		// val = d[val]
-	XORB	(SI),		R8		// xor 1 byte
-	MOVB	R8,		(DI)
-	INCQ	SI				// in++
-	INCQ	DI				// out++
-	JMP l2
-
-finished:
-	MOVQ	j+40(FP),	BX
-	MOVB	DX, 0(BX)
-	MOVQ	i+32(FP),	AX
-	MOVB	CX, 0(AX)
-	RET
diff --git a/src/pkg/crypto/rc4/rc4_amd64p32.s b/src/pkg/crypto/rc4/rc4_amd64p32.s
deleted file mode 100644
index 27d8495..0000000
--- a/src/pkg/crypto/rc4/rc4_amd64p32.s
+++ /dev/null
@@ -1,192 +0,0 @@
-// Original source:
-//	http://www.zorinaq.com/papers/rc4-amd64.html
-//	http://www.zorinaq.com/papers/rc4-amd64.tar.bz2
-
-#include "../../../cmd/ld/textflag.h"
-
-// Local modifications:
-//
-// Transliterated from GNU to 6a assembly syntax by the Go authors.
-// The comments and spacing are from the original.
-//
-// The new EXTEND macros avoid a bad stall on some systems after 8-bit math.
-//
-// The original code accumulated 64 bits of key stream in an integer
-// register and then XOR'ed the key stream into the data 8 bytes at a time.
-// Modified to accumulate 128 bits of key stream into an XMM register
-// and then XOR the key stream into the data 16 bytes at a time.
-// Approximately doubles throughput.
-//
-// Converted to amd64p32.
-//
-// To make safe for Native Client, avoid use of BP, R15,
-// and two-register addressing modes.
-
-// NOTE: Changing EXTEND to a no-op makes the code run 1.2x faster on Core i5
-// but makes the code run 2.0x slower on Xeon.
-#define EXTEND(r) MOVBLZX r, r
-
-/*
-** RC4 implementation optimized for AMD64.
-**
-** Author: Marc Bevand <bevand_m (at) epita.fr>
-** Licence: I hereby disclaim the copyright on this code and place it
-** in the public domain.
-**
-** The code has been designed to be easily integrated into openssl:
-** the exported RC4() function can replace the actual implementations
-** openssl already contains. Please note that when linking with openssl,
-** it requires that sizeof(RC4_INT) == 8. So openssl must be compiled
-** with -DRC4_INT='unsigned long'.
-**
-** The throughput achieved by this code is about 320 MBytes/sec, on
-** a 1.8 GHz AMD Opteron (rev C0) processor.
-*/
-
-TEXT ·xorKeyStream(SB),NOSPLIT,$0
-	MOVL	n+8(FP),	BX		// rbx = ARG(len)
-	MOVL	src+4(FP),	SI		// in = ARG(in)
-	MOVL	dst+0(FP),	DI		// out = ARG(out)
-	MOVL	state+12(FP),	R10		// d = ARG(data)
-	MOVL	i+16(FP),	AX
-	MOVBQZX	0(AX),		CX		// x = *xp
-	MOVL	j+20(FP),	AX
-	MOVBQZX	0(AX),		DX		// y = *yp
-
-	LEAQ	(SI)(BX*1),	R9		// limit = in+len
-
-l1:	CMPQ	SI,		R9		// cmp in with in+len
-	JGE	finished			// jump if (in >= in+len)
-
-	INCB	CX
-	EXTEND(CX)
-	TESTL	$15,		CX
-	JZ	wordloop
-	LEAL	(R10)(CX*4), R12
-
-	MOVBLZX	(R12),	AX
-
-	ADDB	AX,		DX		// y += tx
-	EXTEND(DX)
-	LEAL (R10)(DX*4), R11
-	MOVBLZX	(R11),	BX		// ty = d[y]
-	MOVB	BX,		(R12)	// d[x] = ty
-	ADDB	AX,		BX		// val = ty+tx
-	EXTEND(BX)
-	LEAL (R10)(BX*4), R13
-	MOVB	AX,		(R11)	// d[y] = tx
-	MOVBLZX	(R13),	R8		// val = d[val]
-	XORB	(SI),		R8		// xor 1 byte
-	MOVB	R8,		(DI)
-	INCQ	SI				// in++
-	INCQ	DI				// out++
-	JMP l1
-
-wordloop:
-	SUBQ	$16,		R9
-	CMPQ	SI,		R9
-	JGT	end
-
-start:
-	ADDQ	$16,		SI		// increment in
-	ADDQ	$16,		DI		// increment out
-
-	// Each KEYROUND generates one byte of key and
-	// inserts it into an XMM register at the given 16-bit index.
-	// The key state array is uint32 words only using the bottom
-	// byte of each word, so the 16-bit OR only copies 8 useful bits.
-	// We accumulate alternating bytes into X0 and X1, and then at
-	// the end we OR X1<<8 into X0 to produce the actual key.
-	//
-	// At the beginning of the loop, CX%16 == 0, so the 16 loads
-	// at state[CX], state[CX+1], ..., state[CX+15] can precompute
-	// (state+CX) as R12 and then become R12[0], R12[1], ... R12[15],
-	// without fear of the byte computation CX+15 wrapping around.
-	//
-	// The first round needs R12[0], the second needs R12[1], and so on.
-	// We can avoid memory stalls by starting the load for round n+1
-	// before the end of round n, using the LOAD macro.
-	LEAQ	(R10)(CX*4),	R12
-
-#define KEYROUND(xmm, load, off, r1, r2, index) \
-	LEAL (R10)(DX*4), R11; \
-	MOVBLZX	(R11),	R8; \
-	MOVB	r1,		(R11); \
-	load((off+1), r2); \
-	MOVB	R8,		(off*4)(R12); \
-	ADDB	r1,		R8; \
-	EXTEND(R8); \
-	LEAL (R10)(R8*4), R14; \
-	PINSRW	$index, (R14), xmm
-
-#define LOAD(off, reg) \
-	MOVBLZX	(off*4)(R12),	reg; \
-	ADDB	reg,		DX; \
-	EXTEND(DX)
-
-#define SKIP(off, reg)
-
-	LOAD(0, AX)
-	KEYROUND(X0, LOAD, 0, AX, BX, 0)
-	KEYROUND(X1, LOAD, 1, BX, AX, 0)
-	KEYROUND(X0, LOAD, 2, AX, BX, 1)
-	KEYROUND(X1, LOAD, 3, BX, AX, 1)
-	KEYROUND(X0, LOAD, 4, AX, BX, 2)
-	KEYROUND(X1, LOAD, 5, BX, AX, 2)
-	KEYROUND(X0, LOAD, 6, AX, BX, 3)
-	KEYROUND(X1, LOAD, 7, BX, AX, 3)
-	KEYROUND(X0, LOAD, 8, AX, BX, 4)
-	KEYROUND(X1, LOAD, 9, BX, AX, 4)
-	KEYROUND(X0, LOAD, 10, AX, BX, 5)
-	KEYROUND(X1, LOAD, 11, BX, AX, 5)
-	KEYROUND(X0, LOAD, 12, AX, BX, 6)
-	KEYROUND(X1, LOAD, 13, BX, AX, 6)
-	KEYROUND(X0, LOAD, 14, AX, BX, 7)
-	KEYROUND(X1, SKIP, 15, BX, AX, 7)
-	
-	ADDB	$16,		CX
-
-	PSLLQ	$8,		X1
-	PXOR	X1,		X0
-	MOVOU	-16(SI),	X2
-	PXOR	X0,		X2
-	MOVOU	X2,		-16(DI)
-
-	CMPQ	SI,		R9		// cmp in with in+len-16
-	JLE	start				// jump if (in <= in+len-16)
-
-end:
-	DECB	CX
-	ADDQ	$16,		R9		// tmp = in+len
-
-	// handle the last bytes, one by one
-l2:	CMPQ	SI,		R9		// cmp in with in+len
-	JGE	finished			// jump if (in >= in+len)
-
-	INCB	CX
-	EXTEND(CX)
-	LEAL (R10)(CX*4), R12
-	MOVBLZX	(R12),	AX
-
-	ADDB	AX,		DX		// y += tx
-	EXTEND(DX)
-	LEAL (R10)(DX*4), R11
-	MOVBLZX	(R11),	BX		// ty = d[y]
-	MOVB	BX,		(R12)	// d[x] = ty
-	ADDB	AX,		BX		// val = ty+tx
-	EXTEND(BX)
-	LEAL (R10)(BX*4), R13
-	MOVB	AX,		(R11)	// d[y] = tx
-	MOVBLZX	(R13),	R8		// val = d[val]
-	XORB	(SI),		R8		// xor 1 byte
-	MOVB	R8,		(DI)
-	INCQ	SI				// in++
-	INCQ	DI				// out++
-	JMP l2
-
-finished:
-	MOVL	j+20(FP),	BX
-	MOVB	DX, 0(BX)
-	MOVL	i+16(FP),	AX
-	MOVB	CX, 0(AX)
-	RET
diff --git a/src/pkg/crypto/rc4/rc4_arm.s b/src/pkg/crypto/rc4/rc4_arm.s
deleted file mode 100644
index 3aad729..0000000
--- a/src/pkg/crypto/rc4/rc4_arm.s
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../../cmd/ld/textflag.h"
-
-// Registers
-dst = 0
-src = 1
-n = 2
-state = 3
-pi = 4
-pj = 5
-i = 6
-j = 7
-k = 8
-t = 11
-t2 = 12
-
-// func xorKeyStream(dst, src *byte, n int, state *[256]byte, i, j *uint8)
-TEXT ·xorKeyStream(SB),NOSPLIT,$0
-	MOVW 0(FP), R(dst)
-	MOVW 4(FP), R(src)
-	MOVW 8(FP), R(n)
-	MOVW 12(FP), R(state)
-	MOVW 16(FP), R(pi)
-	MOVW 20(FP), R(pj)
-	MOVBU (R(pi)), R(i)
-	MOVBU (R(pj)), R(j)
-	MOVW $0, R(k)
-
-loop:
-	// i += 1; j += state[i]
-	ADD $1, R(i)
-	AND $0xff, R(i)
-	MOVBU R(i)<<2(R(state)), R(t)
-	ADD R(t), R(j)
-	AND $0xff, R(j)
-
-	// swap state[i] <-> state[j]
-	MOVBU R(j)<<2(R(state)), R(t2)
-	MOVB R(t2), R(i)<<2(R(state))
-	MOVB R(t), R(j)<<2(R(state))
-
-	// dst[k] = src[k] ^ state[state[i] + state[j]]
-	ADD R(t2), R(t)
-	AND $0xff, R(t)
-	MOVBU R(t)<<2(R(state)), R(t)
-	MOVBU R(k)<<0(R(src)), R(t2)
-	EOR R(t), R(t2)
-	MOVB R(t2), R(k)<<0(R(dst))
-
-	ADD $1, R(k)
-	CMP R(k), R(n)
-	BNE loop
-
-done:
-	MOVB R(i), (R(pi))
-	MOVB R(j), (R(pj))
-	RET
diff --git a/src/pkg/crypto/rc4/rc4_asm.go b/src/pkg/crypto/rc4/rc4_asm.go
deleted file mode 100644
index fc71b9a..0000000
--- a/src/pkg/crypto/rc4/rc4_asm.go
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build amd64 amd64p32 arm 386
-
-package rc4
-
-func xorKeyStream(dst, src *byte, n int, state *[256]uint32, i, j *uint8)
-
-// XORKeyStream sets dst to the result of XORing src with the key stream.
-// Dst and src may be the same slice but otherwise should not overlap.
-func (c *Cipher) XORKeyStream(dst, src []byte) {
-	if len(src) == 0 {
-		return
-	}
-	xorKeyStream(&dst[0], &src[0], len(src), &c.s, &c.i, &c.j)
-}
diff --git a/src/pkg/crypto/rc4/rc4_ref.go b/src/pkg/crypto/rc4/rc4_ref.go
deleted file mode 100644
index 1ecce1a..0000000
--- a/src/pkg/crypto/rc4/rc4_ref.go
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build !amd64,!amd64p32,!arm,!386
-
-package rc4
-
-// XORKeyStream sets dst to the result of XORing src with the key stream.
-// Dst and src may be the same slice but otherwise should not overlap.
-func (c *Cipher) XORKeyStream(dst, src []byte) {
-	c.xorKeyStreamGeneric(dst, src)
-}
diff --git a/src/pkg/crypto/rsa/pss.go b/src/pkg/crypto/rsa/pss.go
deleted file mode 100644
index 18eafbc..0000000
--- a/src/pkg/crypto/rsa/pss.go
+++ /dev/null
@@ -1,282 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package rsa
-
-// This file implements the PSS signature scheme [1].
-//
-// [1] http://www.rsa.com/rsalabs/pkcs/files/h11300-wp-pkcs-1v2-2-rsa-cryptography-standard.pdf
-
-import (
-	"bytes"
-	"crypto"
-	"errors"
-	"hash"
-	"io"
-	"math/big"
-)
-
-func emsaPSSEncode(mHash []byte, emBits int, salt []byte, hash hash.Hash) ([]byte, error) {
-	// See [1], section 9.1.1
-	hLen := hash.Size()
-	sLen := len(salt)
-	emLen := (emBits + 7) / 8
-
-	// 1.  If the length of M is greater than the input limitation for the
-	//     hash function (2^61 - 1 octets for SHA-1), output "message too
-	//     long" and stop.
-	//
-	// 2.  Let mHash = Hash(M), an octet string of length hLen.
-
-	if len(mHash) != hLen {
-		return nil, errors.New("crypto/rsa: input must be hashed message")
-	}
-
-	// 3.  If emLen < hLen + sLen + 2, output "encoding error" and stop.
-
-	if emLen < hLen+sLen+2 {
-		return nil, errors.New("crypto/rsa: encoding error")
-	}
-
-	em := make([]byte, emLen)
-	db := em[:emLen-sLen-hLen-2+1+sLen]
-	h := em[emLen-sLen-hLen-2+1+sLen : emLen-1]
-
-	// 4.  Generate a random octet string salt of length sLen; if sLen = 0,
-	//     then salt is the empty string.
-	//
-	// 5.  Let
-	//       M' = (0x)00 00 00 00 00 00 00 00 || mHash || salt;
-	//
-	//     M' is an octet string of length 8 + hLen + sLen with eight
-	//     initial zero octets.
-	//
-	// 6.  Let H = Hash(M'), an octet string of length hLen.
-
-	var prefix [8]byte
-
-	hash.Write(prefix[:])
-	hash.Write(mHash)
-	hash.Write(salt)
-
-	h = hash.Sum(h[:0])
-	hash.Reset()
-
-	// 7.  Generate an octet string PS consisting of emLen - sLen - hLen - 2
-	//     zero octets.  The length of PS may be 0.
-	//
-	// 8.  Let DB = PS || 0x01 || salt; DB is an octet string of length
-	//     emLen - hLen - 1.
-
-	db[emLen-sLen-hLen-2] = 0x01
-	copy(db[emLen-sLen-hLen-1:], salt)
-
-	// 9.  Let dbMask = MGF(H, emLen - hLen - 1).
-	//
-	// 10. Let maskedDB = DB \xor dbMask.
-
-	mgf1XOR(db, hash, h)
-
-	// 11. Set the leftmost 8 * emLen - emBits bits of the leftmost octet in
-	//     maskedDB to zero.
-
-	db[0] &= (0xFF >> uint(8*emLen-emBits))
-
-	// 12. Let EM = maskedDB || H || 0xbc.
-	em[emLen-1] = 0xBC
-
-	// 13. Output EM.
-	return em, nil
-}
-
-func emsaPSSVerify(mHash, em []byte, emBits, sLen int, hash hash.Hash) error {
-	// 1.  If the length of M is greater than the input limitation for the
-	//     hash function (2^61 - 1 octets for SHA-1), output "inconsistent"
-	//     and stop.
-	//
-	// 2.  Let mHash = Hash(M), an octet string of length hLen.
-	hLen := hash.Size()
-	if hLen != len(mHash) {
-		return ErrVerification
-	}
-
-	// 3.  If emLen < hLen + sLen + 2, output "inconsistent" and stop.
-	emLen := (emBits + 7) / 8
-	if emLen < hLen+sLen+2 {
-		return ErrVerification
-	}
-
-	// 4.  If the rightmost octet of EM does not have hexadecimal value
-	//     0xbc, output "inconsistent" and stop.
-	if em[len(em)-1] != 0xBC {
-		return ErrVerification
-	}
-
-	// 5.  Let maskedDB be the leftmost emLen - hLen - 1 octets of EM, and
-	//     let H be the next hLen octets.
-	db := em[:emLen-hLen-1]
-	h := em[emLen-hLen-1 : len(em)-1]
-
-	// 6.  If the leftmost 8 * emLen - emBits bits of the leftmost octet in
-	//     maskedDB are not all equal to zero, output "inconsistent" and
-	//     stop.
-	if em[0]&(0xFF<<uint(8-(8*emLen-emBits))) != 0 {
-		return ErrVerification
-	}
-
-	// 7.  Let dbMask = MGF(H, emLen - hLen - 1).
-	//
-	// 8.  Let DB = maskedDB \xor dbMask.
-	mgf1XOR(db, hash, h)
-
-	// 9.  Set the leftmost 8 * emLen - emBits bits of the leftmost octet in DB
-	//     to zero.
-	db[0] &= (0xFF >> uint(8*emLen-emBits))
-
-	if sLen == PSSSaltLengthAuto {
-	FindSaltLength:
-		for sLen = emLen - (hLen + 2); sLen >= 0; sLen-- {
-			switch db[emLen-hLen-sLen-2] {
-			case 1:
-				break FindSaltLength
-			case 0:
-				continue
-			default:
-				return ErrVerification
-			}
-		}
-		if sLen < 0 {
-			return ErrVerification
-		}
-	} else {
-		// 10. If the emLen - hLen - sLen - 2 leftmost octets of DB are not zero
-		//     or if the octet at position emLen - hLen - sLen - 1 (the leftmost
-		//     position is "position 1") does not have hexadecimal value 0x01,
-		//     output "inconsistent" and stop.
-		for _, e := range db[:emLen-hLen-sLen-2] {
-			if e != 0x00 {
-				return ErrVerification
-			}
-		}
-		if db[emLen-hLen-sLen-2] != 0x01 {
-			return ErrVerification
-		}
-	}
-
-	// 11.  Let salt be the last sLen octets of DB.
-	salt := db[len(db)-sLen:]
-
-	// 12.  Let
-	//          M' = (0x)00 00 00 00 00 00 00 00 || mHash || salt ;
-	//     M' is an octet string of length 8 + hLen + sLen with eight
-	//     initial zero octets.
-	//
-	// 13. Let H' = Hash(M'), an octet string of length hLen.
-	var prefix [8]byte
-	hash.Write(prefix[:])
-	hash.Write(mHash)
-	hash.Write(salt)
-
-	h0 := hash.Sum(nil)
-
-	// 14. If H = H', output "consistent." Otherwise, output "inconsistent."
-	if !bytes.Equal(h0, h) {
-		return ErrVerification
-	}
-	return nil
-}
-
-// signPSSWithSalt calculates the signature of hashed using PSS [1] with specified salt.
-// Note that hashed must be the result of hashing the input message using the
-// given hash function. salt is a random sequence of bytes whose length will be
-// later used to verify the signature.
-func signPSSWithSalt(rand io.Reader, priv *PrivateKey, hash crypto.Hash, hashed, salt []byte) (s []byte, err error) {
-	nBits := priv.N.BitLen()
-	em, err := emsaPSSEncode(hashed, nBits-1, salt, hash.New())
-	if err != nil {
-		return
-	}
-	m := new(big.Int).SetBytes(em)
-	c, err := decrypt(rand, priv, m)
-	if err != nil {
-		return
-	}
-	s = make([]byte, (nBits+7)/8)
-	copyWithLeftPad(s, c.Bytes())
-	return
-}
-
-const (
-	// PSSSaltLengthAuto causes the salt in a PSS signature to be as large
-	// as possible when signing, and to be auto-detected when verifying.
-	PSSSaltLengthAuto = 0
-	// PSSSaltLengthEqualsHash causes the salt length to equal the length
-	// of the hash used in the signature.
-	PSSSaltLengthEqualsHash = -1
-)
-
-// PSSOptions contains options for creating and verifying PSS signatures.
-type PSSOptions struct {
-	// SaltLength controls the length of the salt used in the PSS
-	// signature. It can either be a number of bytes, or one of the special
-	// PSSSaltLength constants.
-	SaltLength int
-}
-
-func (opts *PSSOptions) saltLength() int {
-	if opts == nil {
-		return PSSSaltLengthAuto
-	}
-	return opts.SaltLength
-}
-
-// SignPSS calculates the signature of hashed using RSASSA-PSS [1].
-// Note that hashed must be the result of hashing the input message using the
-// given hash function. The opts argument may be nil, in which case sensible
-// defaults are used.
-func SignPSS(rand io.Reader, priv *PrivateKey, hash crypto.Hash, hashed []byte, opts *PSSOptions) (s []byte, err error) {
-	saltLength := opts.saltLength()
-	switch saltLength {
-	case PSSSaltLengthAuto:
-		saltLength = (priv.N.BitLen()+7)/8 - 2 - hash.Size()
-	case PSSSaltLengthEqualsHash:
-		saltLength = hash.Size()
-	}
-
-	salt := make([]byte, saltLength)
-	if _, err = io.ReadFull(rand, salt); err != nil {
-		return
-	}
-	return signPSSWithSalt(rand, priv, hash, hashed, salt)
-}
-
-// VerifyPSS verifies a PSS signature.
-// hashed is the result of hashing the input message using the given hash
-// function and sig is the signature. A valid signature is indicated by
-// returning a nil error. The opts argument may be nil, in which case sensible
-// defaults are used.
-func VerifyPSS(pub *PublicKey, hash crypto.Hash, hashed []byte, sig []byte, opts *PSSOptions) error {
-	return verifyPSS(pub, hash, hashed, sig, opts.saltLength())
-}
-
-// verifyPSS verifies a PSS signature with the given salt length.
-func verifyPSS(pub *PublicKey, hash crypto.Hash, hashed []byte, sig []byte, saltLen int) error {
-	nBits := pub.N.BitLen()
-	if len(sig) != (nBits+7)/8 {
-		return ErrVerification
-	}
-	s := new(big.Int).SetBytes(sig)
-	m := encrypt(new(big.Int), pub, s)
-	emBits := nBits - 1
-	emLen := (emBits + 7) / 8
-	if emLen < len(m.Bytes()) {
-		return ErrVerification
-	}
-	em := make([]byte, emLen)
-	copyWithLeftPad(em, m.Bytes())
-	if saltLen == PSSSaltLengthEqualsHash {
-		saltLen = hash.Size()
-	}
-	return emsaPSSVerify(hashed, em, emBits, saltLen, hash.New())
-}
diff --git a/src/pkg/crypto/rsa/rsa.go b/src/pkg/crypto/rsa/rsa.go
deleted file mode 100644
index bce6ba4..0000000
--- a/src/pkg/crypto/rsa/rsa.go
+++ /dev/null
@@ -1,538 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package rsa implements RSA encryption as specified in PKCS#1.
-package rsa
-
-import (
-	"crypto/rand"
-	"crypto/subtle"
-	"errors"
-	"hash"
-	"io"
-	"math/big"
-)
-
-var bigZero = big.NewInt(0)
-var bigOne = big.NewInt(1)
-
-// A PublicKey represents the public part of an RSA key.
-type PublicKey struct {
-	N *big.Int // modulus
-	E int      // public exponent
-}
-
-var (
-	errPublicModulus       = errors.New("crypto/rsa: missing public modulus")
-	errPublicExponentSmall = errors.New("crypto/rsa: public exponent too small")
-	errPublicExponentLarge = errors.New("crypto/rsa: public exponent too large")
-)
-
-// checkPub sanity checks the public key before we use it.
-// We require pub.E to fit into a 32-bit integer so that we
-// do not have different behavior depending on whether
-// int is 32 or 64 bits. See also
-// http://www.imperialviolet.org/2012/03/16/rsae.html.
-func checkPub(pub *PublicKey) error {
-	if pub.N == nil {
-		return errPublicModulus
-	}
-	if pub.E < 2 {
-		return errPublicExponentSmall
-	}
-	if pub.E > 1<<31-1 {
-		return errPublicExponentLarge
-	}
-	return nil
-}
-
-// A PrivateKey represents an RSA key
-type PrivateKey struct {
-	PublicKey            // public part.
-	D         *big.Int   // private exponent
-	Primes    []*big.Int // prime factors of N, has >= 2 elements.
-
-	// Precomputed contains precomputed values that speed up private
-	// operations, if available.
-	Precomputed PrecomputedValues
-}
-
-type PrecomputedValues struct {
-	Dp, Dq *big.Int // D mod (P-1) (or mod Q-1)
-	Qinv   *big.Int // Q^-1 mod P
-
-	// CRTValues is used for the 3rd and subsequent primes. Due to a
-	// historical accident, the CRT for the first two primes is handled
-	// differently in PKCS#1 and interoperability is sufficiently
-	// important that we mirror this.
-	CRTValues []CRTValue
-}
-
-// CRTValue contains the precomputed chinese remainder theorem values.
-type CRTValue struct {
-	Exp   *big.Int // D mod (prime-1).
-	Coeff *big.Int // R·Coeff ≡ 1 mod Prime.
-	R     *big.Int // product of primes prior to this (inc p and q).
-}
-
-// Validate performs basic sanity checks on the key.
-// It returns nil if the key is valid, or else an error describing a problem.
-func (priv *PrivateKey) Validate() error {
-	if err := checkPub(&priv.PublicKey); err != nil {
-		return err
-	}
-
-	// Check that the prime factors are actually prime. Note that this is
-	// just a sanity check. Since the random witnesses chosen by
-	// ProbablyPrime are deterministic, given the candidate number, it's
-	// easy for an attack to generate composites that pass this test.
-	for _, prime := range priv.Primes {
-		if !prime.ProbablyPrime(20) {
-			return errors.New("crypto/rsa: prime factor is composite")
-		}
-	}
-
-	// Check that Πprimes == n.
-	modulus := new(big.Int).Set(bigOne)
-	for _, prime := range priv.Primes {
-		modulus.Mul(modulus, prime)
-	}
-	if modulus.Cmp(priv.N) != 0 {
-		return errors.New("crypto/rsa: invalid modulus")
-	}
-
-	// Check that de ≡ 1 mod p-1, for each prime.
-	// This implies that e is coprime to each p-1 as e has a multiplicative
-	// inverse. Therefore e is coprime to lcm(p-1,q-1,r-1,...) =
-	// exponent(ℤ/nℤ). It also implies that a^de ≡ a mod p as a^(p-1) ≡ 1
-	// mod p. Thus a^de ≡ a mod n for all a coprime to n, as required.
-	congruence := new(big.Int)
-	de := new(big.Int).SetInt64(int64(priv.E))
-	de.Mul(de, priv.D)
-	for _, prime := range priv.Primes {
-		pminus1 := new(big.Int).Sub(prime, bigOne)
-		congruence.Mod(de, pminus1)
-		if congruence.Cmp(bigOne) != 0 {
-			return errors.New("crypto/rsa: invalid exponents")
-		}
-	}
-	return nil
-}
-
-// GenerateKey generates an RSA keypair of the given bit size using the
-// random source random (for example, crypto/rand.Reader).
-func GenerateKey(random io.Reader, bits int) (priv *PrivateKey, err error) {
-	return GenerateMultiPrimeKey(random, 2, bits)
-}
-
-// GenerateMultiPrimeKey generates a multi-prime RSA keypair of the given bit
-// size and the given random source, as suggested in [1]. Although the public
-// keys are compatible (actually, indistinguishable) from the 2-prime case,
-// the private keys are not. Thus it may not be possible to export multi-prime
-// private keys in certain formats or to subsequently import them into other
-// code.
-//
-// Table 1 in [2] suggests maximum numbers of primes for a given size.
-//
-// [1] US patent 4405829 (1972, expired)
-// [2] http://www.cacr.math.uwaterloo.ca/techreports/2006/cacr2006-16.pdf
-func GenerateMultiPrimeKey(random io.Reader, nprimes int, bits int) (priv *PrivateKey, err error) {
-	priv = new(PrivateKey)
-	priv.E = 65537
-
-	if nprimes < 2 {
-		return nil, errors.New("crypto/rsa: GenerateMultiPrimeKey: nprimes must be >= 2")
-	}
-
-	primes := make([]*big.Int, nprimes)
-
-NextSetOfPrimes:
-	for {
-		todo := bits
-		// crypto/rand should set the top two bits in each prime.
-		// Thus each prime has the form
-		//   p_i = 2^bitlen(p_i) × 0.11... (in base 2).
-		// And the product is:
-		//   P = 2^todo × α
-		// where α is the product of nprimes numbers of the form 0.11...
-		//
-		// If α < 1/2 (which can happen for nprimes > 2), we need to
-		// shift todo to compensate for lost bits: the mean value of 0.11...
-		// is 7/8, so todo + shift - nprimes * log2(7/8) ~= bits - 1/2
-		// will give good results.
-		if nprimes >= 7 {
-			todo += (nprimes - 2) / 5
-		}
-		for i := 0; i < nprimes; i++ {
-			primes[i], err = rand.Prime(random, todo/(nprimes-i))
-			if err != nil {
-				return nil, err
-			}
-			todo -= primes[i].BitLen()
-		}
-
-		// Make sure that primes is pairwise unequal.
-		for i, prime := range primes {
-			for j := 0; j < i; j++ {
-				if prime.Cmp(primes[j]) == 0 {
-					continue NextSetOfPrimes
-				}
-			}
-		}
-
-		n := new(big.Int).Set(bigOne)
-		totient := new(big.Int).Set(bigOne)
-		pminus1 := new(big.Int)
-		for _, prime := range primes {
-			n.Mul(n, prime)
-			pminus1.Sub(prime, bigOne)
-			totient.Mul(totient, pminus1)
-		}
-		if n.BitLen() != bits {
-			// This should never happen for nprimes == 2 because
-			// crypto/rand should set the top two bits in each prime.
-			// For nprimes > 2 we hope it does not happen often.
-			continue NextSetOfPrimes
-		}
-
-		g := new(big.Int)
-		priv.D = new(big.Int)
-		y := new(big.Int)
-		e := big.NewInt(int64(priv.E))
-		g.GCD(priv.D, y, e, totient)
-
-		if g.Cmp(bigOne) == 0 {
-			if priv.D.Sign() < 0 {
-				priv.D.Add(priv.D, totient)
-			}
-			priv.Primes = primes
-			priv.N = n
-
-			break
-		}
-	}
-
-	priv.Precompute()
-	return
-}
-
-// incCounter increments a four byte, big-endian counter.
-func incCounter(c *[4]byte) {
-	if c[3]++; c[3] != 0 {
-		return
-	}
-	if c[2]++; c[2] != 0 {
-		return
-	}
-	if c[1]++; c[1] != 0 {
-		return
-	}
-	c[0]++
-}
-
-// mgf1XOR XORs the bytes in out with a mask generated using the MGF1 function
-// specified in PKCS#1 v2.1.
-func mgf1XOR(out []byte, hash hash.Hash, seed []byte) {
-	var counter [4]byte
-	var digest []byte
-
-	done := 0
-	for done < len(out) {
-		hash.Write(seed)
-		hash.Write(counter[0:4])
-		digest = hash.Sum(digest[:0])
-		hash.Reset()
-
-		for i := 0; i < len(digest) && done < len(out); i++ {
-			out[done] ^= digest[i]
-			done++
-		}
-		incCounter(&counter)
-	}
-}
-
-// ErrMessageTooLong is returned when attempting to encrypt a message which is
-// too large for the size of the public key.
-var ErrMessageTooLong = errors.New("crypto/rsa: message too long for RSA public key size")
-
-func encrypt(c *big.Int, pub *PublicKey, m *big.Int) *big.Int {
-	e := big.NewInt(int64(pub.E))
-	c.Exp(m, e, pub.N)
-	return c
-}
-
-// EncryptOAEP encrypts the given message with RSA-OAEP.
-// The message must be no longer than the length of the public modulus less
-// twice the hash length plus 2.
-func EncryptOAEP(hash hash.Hash, random io.Reader, pub *PublicKey, msg []byte, label []byte) (out []byte, err error) {
-	if err := checkPub(pub); err != nil {
-		return nil, err
-	}
-	hash.Reset()
-	k := (pub.N.BitLen() + 7) / 8
-	if len(msg) > k-2*hash.Size()-2 {
-		err = ErrMessageTooLong
-		return
-	}
-
-	hash.Write(label)
-	lHash := hash.Sum(nil)
-	hash.Reset()
-
-	em := make([]byte, k)
-	seed := em[1 : 1+hash.Size()]
-	db := em[1+hash.Size():]
-
-	copy(db[0:hash.Size()], lHash)
-	db[len(db)-len(msg)-1] = 1
-	copy(db[len(db)-len(msg):], msg)
-
-	_, err = io.ReadFull(random, seed)
-	if err != nil {
-		return
-	}
-
-	mgf1XOR(db, hash, seed)
-	mgf1XOR(seed, hash, db)
-
-	m := new(big.Int)
-	m.SetBytes(em)
-	c := encrypt(new(big.Int), pub, m)
-	out = c.Bytes()
-
-	if len(out) < k {
-		// If the output is too small, we need to left-pad with zeros.
-		t := make([]byte, k)
-		copy(t[k-len(out):], out)
-		out = t
-	}
-
-	return
-}
-
-// ErrDecryption represents a failure to decrypt a message.
-// It is deliberately vague to avoid adaptive attacks.
-var ErrDecryption = errors.New("crypto/rsa: decryption error")
-
-// ErrVerification represents a failure to verify a signature.
-// It is deliberately vague to avoid adaptive attacks.
-var ErrVerification = errors.New("crypto/rsa: verification error")
-
-// modInverse returns ia, the inverse of a in the multiplicative group of prime
-// order n. It requires that a be a member of the group (i.e. less than n).
-func modInverse(a, n *big.Int) (ia *big.Int, ok bool) {
-	g := new(big.Int)
-	x := new(big.Int)
-	y := new(big.Int)
-	g.GCD(x, y, a, n)
-	if g.Cmp(bigOne) != 0 {
-		// In this case, a and n aren't coprime and we cannot calculate
-		// the inverse. This happens because the values of n are nearly
-		// prime (being the product of two primes) rather than truly
-		// prime.
-		return
-	}
-
-	if x.Cmp(bigOne) < 0 {
-		// 0 is not the multiplicative inverse of any element so, if x
-		// < 1, then x is negative.
-		x.Add(x, n)
-	}
-
-	return x, true
-}
-
-// Precompute performs some calculations that speed up private key operations
-// in the future.
-func (priv *PrivateKey) Precompute() {
-	if priv.Precomputed.Dp != nil {
-		return
-	}
-
-	priv.Precomputed.Dp = new(big.Int).Sub(priv.Primes[0], bigOne)
-	priv.Precomputed.Dp.Mod(priv.D, priv.Precomputed.Dp)
-
-	priv.Precomputed.Dq = new(big.Int).Sub(priv.Primes[1], bigOne)
-	priv.Precomputed.Dq.Mod(priv.D, priv.Precomputed.Dq)
-
-	priv.Precomputed.Qinv = new(big.Int).ModInverse(priv.Primes[1], priv.Primes[0])
-
-	r := new(big.Int).Mul(priv.Primes[0], priv.Primes[1])
-	priv.Precomputed.CRTValues = make([]CRTValue, len(priv.Primes)-2)
-	for i := 2; i < len(priv.Primes); i++ {
-		prime := priv.Primes[i]
-		values := &priv.Precomputed.CRTValues[i-2]
-
-		values.Exp = new(big.Int).Sub(prime, bigOne)
-		values.Exp.Mod(priv.D, values.Exp)
-
-		values.R = new(big.Int).Set(r)
-		values.Coeff = new(big.Int).ModInverse(r, prime)
-
-		r.Mul(r, prime)
-	}
-}
-
-// decrypt performs an RSA decryption, resulting in a plaintext integer. If a
-// random source is given, RSA blinding is used.
-func decrypt(random io.Reader, priv *PrivateKey, c *big.Int) (m *big.Int, err error) {
-	// TODO(agl): can we get away with reusing blinds?
-	if c.Cmp(priv.N) > 0 {
-		err = ErrDecryption
-		return
-	}
-
-	var ir *big.Int
-	if random != nil {
-		// Blinding enabled. Blinding involves multiplying c by r^e.
-		// Then the decryption operation performs (m^e * r^e)^d mod n
-		// which equals mr mod n. The factor of r can then be removed
-		// by multiplying by the multiplicative inverse of r.
-
-		var r *big.Int
-
-		for {
-			r, err = rand.Int(random, priv.N)
-			if err != nil {
-				return
-			}
-			if r.Cmp(bigZero) == 0 {
-				r = bigOne
-			}
-			var ok bool
-			ir, ok = modInverse(r, priv.N)
-			if ok {
-				break
-			}
-		}
-		bigE := big.NewInt(int64(priv.E))
-		rpowe := new(big.Int).Exp(r, bigE, priv.N)
-		cCopy := new(big.Int).Set(c)
-		cCopy.Mul(cCopy, rpowe)
-		cCopy.Mod(cCopy, priv.N)
-		c = cCopy
-	}
-
-	if priv.Precomputed.Dp == nil {
-		m = new(big.Int).Exp(c, priv.D, priv.N)
-	} else {
-		// We have the precalculated values needed for the CRT.
-		m = new(big.Int).Exp(c, priv.Precomputed.Dp, priv.Primes[0])
-		m2 := new(big.Int).Exp(c, priv.Precomputed.Dq, priv.Primes[1])
-		m.Sub(m, m2)
-		if m.Sign() < 0 {
-			m.Add(m, priv.Primes[0])
-		}
-		m.Mul(m, priv.Precomputed.Qinv)
-		m.Mod(m, priv.Primes[0])
-		m.Mul(m, priv.Primes[1])
-		m.Add(m, m2)
-
-		for i, values := range priv.Precomputed.CRTValues {
-			prime := priv.Primes[2+i]
-			m2.Exp(c, values.Exp, prime)
-			m2.Sub(m2, m)
-			m2.Mul(m2, values.Coeff)
-			m2.Mod(m2, prime)
-			if m2.Sign() < 0 {
-				m2.Add(m2, prime)
-			}
-			m2.Mul(m2, values.R)
-			m.Add(m, m2)
-		}
-	}
-
-	if ir != nil {
-		// Unblind.
-		m.Mul(m, ir)
-		m.Mod(m, priv.N)
-	}
-
-	return
-}
-
-// DecryptOAEP decrypts ciphertext using RSA-OAEP.
-// If random != nil, DecryptOAEP uses RSA blinding to avoid timing side-channel attacks.
-func DecryptOAEP(hash hash.Hash, random io.Reader, priv *PrivateKey, ciphertext []byte, label []byte) (msg []byte, err error) {
-	if err := checkPub(&priv.PublicKey); err != nil {
-		return nil, err
-	}
-	k := (priv.N.BitLen() + 7) / 8
-	if len(ciphertext) > k ||
-		k < hash.Size()*2+2 {
-		err = ErrDecryption
-		return
-	}
-
-	c := new(big.Int).SetBytes(ciphertext)
-
-	m, err := decrypt(random, priv, c)
-	if err != nil {
-		return
-	}
-
-	hash.Write(label)
-	lHash := hash.Sum(nil)
-	hash.Reset()
-
-	// Converting the plaintext number to bytes will strip any
-	// leading zeros so we may have to left pad. We do this unconditionally
-	// to avoid leaking timing information. (Although we still probably
-	// leak the number of leading zeros. It's not clear that we can do
-	// anything about this.)
-	em := leftPad(m.Bytes(), k)
-
-	firstByteIsZero := subtle.ConstantTimeByteEq(em[0], 0)
-
-	seed := em[1 : hash.Size()+1]
-	db := em[hash.Size()+1:]
-
-	mgf1XOR(seed, hash, db)
-	mgf1XOR(db, hash, seed)
-
-	lHash2 := db[0:hash.Size()]
-
-	// We have to validate the plaintext in constant time in order to avoid
-	// attacks like: J. Manger. A Chosen Ciphertext Attack on RSA Optimal
-	// Asymmetric Encryption Padding (OAEP) as Standardized in PKCS #1
-	// v2.0. In J. Kilian, editor, Advances in Cryptology.
-	lHash2Good := subtle.ConstantTimeCompare(lHash, lHash2)
-
-	// The remainder of the plaintext must be zero or more 0x00, followed
-	// by 0x01, followed by the message.
-	//   lookingForIndex: 1 iff we are still looking for the 0x01
-	//   index: the offset of the first 0x01 byte
-	//   invalid: 1 iff we saw a non-zero byte before the 0x01.
-	var lookingForIndex, index, invalid int
-	lookingForIndex = 1
-	rest := db[hash.Size():]
-
-	for i := 0; i < len(rest); i++ {
-		equals0 := subtle.ConstantTimeByteEq(rest[i], 0)
-		equals1 := subtle.ConstantTimeByteEq(rest[i], 1)
-		index = subtle.ConstantTimeSelect(lookingForIndex&equals1, i, index)
-		lookingForIndex = subtle.ConstantTimeSelect(equals1, 0, lookingForIndex)
-		invalid = subtle.ConstantTimeSelect(lookingForIndex&^equals0, 1, invalid)
-	}
-
-	if firstByteIsZero&lHash2Good&^invalid&^lookingForIndex != 1 {
-		err = ErrDecryption
-		return
-	}
-
-	msg = rest[index+1:]
-	return
-}
-
-// leftPad returns a new slice of length size. The contents of input are right
-// aligned in the new slice.
-func leftPad(input []byte, size int) (out []byte) {
-	n := len(input)
-	if n > size {
-		n = size
-	}
-	out = make([]byte, size)
-	copy(out[len(out)-n:], input)
-	return
-}
diff --git a/src/pkg/crypto/sha1/sha1block_386.s b/src/pkg/crypto/sha1/sha1block_386.s
deleted file mode 100644
index 688851c..0000000
--- a/src/pkg/crypto/sha1/sha1block_386.s
+++ /dev/null
@@ -1,233 +0,0 @@
-// Copyright 2013 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../../cmd/ld/textflag.h"
-
-// SHA1 block routine. See sha1block.go for Go equivalent.
-//
-// There are 80 rounds of 4 types:
-//   - rounds 0-15 are type 1 and load data (ROUND1 macro).
-//   - rounds 16-19 are type 1 and do not load data (ROUND1x macro).
-//   - rounds 20-39 are type 2 and do not load data (ROUND2 macro).
-//   - rounds 40-59 are type 3 and do not load data (ROUND3 macro).
-//   - rounds 60-79 are type 4 and do not load data (ROUND4 macro).
-//
-// Each round loads or shuffles the data, then computes a per-round
-// function of b, c, d, and then mixes the result into and rotates the
-// five registers a, b, c, d, e holding the intermediate results.
-//
-// The register rotation is implemented by rotating the arguments to
-// the round macros instead of by explicit move instructions.
-
-// Like sha1block_amd64.s, but we keep the data and limit pointers on the stack.
-// To free up the word pointer (R10 on amd64, DI here), we add it to e during
-// LOAD/SHUFFLE instead of during MIX.
-//
-// The stack holds the intermediate word array - 16 uint32s - at 0(SP) up to 64(SP).
-// The saved a, b, c, d, e (R11 through R15 on amd64) are at 64(SP) up to 84(SP).
-// The saved limit pointer (DI on amd64) is at 84(SP).
-// The saved data pointer (SI on amd64) is at 88(SP).
-
-#define LOAD(index, e) \
-	MOVL	88(SP), SI; \
-	MOVL	(index*4)(SI), DI; \
-	BSWAPL	DI; \
-	MOVL	DI, (index*4)(SP); \
-	ADDL	DI, e
-
-#define SHUFFLE(index, e) \
-	MOVL	(((index)&0xf)*4)(SP), DI; \
-	XORL	(((index-3)&0xf)*4)(SP), DI; \
-	XORL	(((index-8)&0xf)*4)(SP), DI; \
-	XORL	(((index-14)&0xf)*4)(SP), DI; \
-	ROLL	$1, DI; \
-	MOVL	DI, (((index)&0xf)*4)(SP); \
-	ADDL	DI, e
-
-#define FUNC1(a, b, c, d, e) \
-	MOVL	d, DI; \
-	XORL	c, DI; \
-	ANDL	b, DI; \
-	XORL	d, DI
-
-#define FUNC2(a, b, c, d, e) \
-	MOVL	b, DI; \
-	XORL	c, DI; \
-	XORL	d, DI
-
-#define FUNC3(a, b, c, d, e) \
-	MOVL	b, SI; \
-	ORL	c, SI; \
-	ANDL	d, SI; \
-	MOVL	b, DI; \
-	ANDL	c, DI; \
-	ORL	SI, DI
-
-#define FUNC4 FUNC2
-
-#define MIX(a, b, c, d, e, const) \
-	ROLL	$30, b; \
-	ADDL	DI, e; \
-	MOVL	a, SI; \
-	ROLL	$5, SI; \
-	LEAL	const(e)(SI*1), e
-
-#define ROUND1(a, b, c, d, e, index) \
-	LOAD(index, e); \
-	FUNC1(a, b, c, d, e); \
-	MIX(a, b, c, d, e, 0x5A827999)
-
-#define ROUND1x(a, b, c, d, e, index) \
-	SHUFFLE(index, e); \
-	FUNC1(a, b, c, d, e); \
-	MIX(a, b, c, d, e, 0x5A827999)
-
-#define ROUND2(a, b, c, d, e, index) \
-	SHUFFLE(index, e); \
-	FUNC2(a, b, c, d, e); \
-	MIX(a, b, c, d, e, 0x6ED9EBA1)
-
-#define ROUND3(a, b, c, d, e, index) \
-	SHUFFLE(index, e); \
-	FUNC3(a, b, c, d, e); \
-	MIX(a, b, c, d, e, 0x8F1BBCDC)
-
-#define ROUND4(a, b, c, d, e, index) \
-	SHUFFLE(index, e); \
-	FUNC4(a, b, c, d, e); \
-	MIX(a, b, c, d, e, 0xCA62C1D6)
-
-// func block(dig *digest, p []byte)
-TEXT ·block(SB),NOSPLIT,$92-16
-	MOVL	dig+0(FP),	BP
-	MOVL	p+4(FP),	SI
-	MOVL	p_len+8(FP),	DX
-	SHRL	$6,		DX
-	SHLL	$6,		DX
-	
-	LEAL	(SI)(DX*1),	DI
-	MOVL	(0*4)(BP),	AX
-	MOVL	(1*4)(BP),	BX
-	MOVL	(2*4)(BP),	CX
-	MOVL	(3*4)(BP),	DX
-	MOVL	(4*4)(BP),	BP
-
-	CMPL	SI,		DI
-	JEQ	end
-
-	MOVL	DI,	84(SP)
-
-loop:
-	MOVL	SI,	88(SP)
-
-	MOVL	AX,	64(SP)
-	MOVL	BX,	68(SP)
-	MOVL	CX,	72(SP)
-	MOVL	DX,	76(SP)
-	MOVL	BP,	80(SP)
-
-	ROUND1(AX, BX, CX, DX, BP, 0)
-	ROUND1(BP, AX, BX, CX, DX, 1)
-	ROUND1(DX, BP, AX, BX, CX, 2)
-	ROUND1(CX, DX, BP, AX, BX, 3)
-	ROUND1(BX, CX, DX, BP, AX, 4)
-	ROUND1(AX, BX, CX, DX, BP, 5)
-	ROUND1(BP, AX, BX, CX, DX, 6)
-	ROUND1(DX, BP, AX, BX, CX, 7)
-	ROUND1(CX, DX, BP, AX, BX, 8)
-	ROUND1(BX, CX, DX, BP, AX, 9)
-	ROUND1(AX, BX, CX, DX, BP, 10)
-	ROUND1(BP, AX, BX, CX, DX, 11)
-	ROUND1(DX, BP, AX, BX, CX, 12)
-	ROUND1(CX, DX, BP, AX, BX, 13)
-	ROUND1(BX, CX, DX, BP, AX, 14)
-	ROUND1(AX, BX, CX, DX, BP, 15)
-
-	ROUND1x(BP, AX, BX, CX, DX, 16)
-	ROUND1x(DX, BP, AX, BX, CX, 17)
-	ROUND1x(CX, DX, BP, AX, BX, 18)
-	ROUND1x(BX, CX, DX, BP, AX, 19)
-	
-	ROUND2(AX, BX, CX, DX, BP, 20)
-	ROUND2(BP, AX, BX, CX, DX, 21)
-	ROUND2(DX, BP, AX, BX, CX, 22)
-	ROUND2(CX, DX, BP, AX, BX, 23)
-	ROUND2(BX, CX, DX, BP, AX, 24)
-	ROUND2(AX, BX, CX, DX, BP, 25)
-	ROUND2(BP, AX, BX, CX, DX, 26)
-	ROUND2(DX, BP, AX, BX, CX, 27)
-	ROUND2(CX, DX, BP, AX, BX, 28)
-	ROUND2(BX, CX, DX, BP, AX, 29)
-	ROUND2(AX, BX, CX, DX, BP, 30)
-	ROUND2(BP, AX, BX, CX, DX, 31)
-	ROUND2(DX, BP, AX, BX, CX, 32)
-	ROUND2(CX, DX, BP, AX, BX, 33)
-	ROUND2(BX, CX, DX, BP, AX, 34)
-	ROUND2(AX, BX, CX, DX, BP, 35)
-	ROUND2(BP, AX, BX, CX, DX, 36)
-	ROUND2(DX, BP, AX, BX, CX, 37)
-	ROUND2(CX, DX, BP, AX, BX, 38)
-	ROUND2(BX, CX, DX, BP, AX, 39)
-	
-	ROUND3(AX, BX, CX, DX, BP, 40)
-	ROUND3(BP, AX, BX, CX, DX, 41)
-	ROUND3(DX, BP, AX, BX, CX, 42)
-	ROUND3(CX, DX, BP, AX, BX, 43)
-	ROUND3(BX, CX, DX, BP, AX, 44)
-	ROUND3(AX, BX, CX, DX, BP, 45)
-	ROUND3(BP, AX, BX, CX, DX, 46)
-	ROUND3(DX, BP, AX, BX, CX, 47)
-	ROUND3(CX, DX, BP, AX, BX, 48)
-	ROUND3(BX, CX, DX, BP, AX, 49)
-	ROUND3(AX, BX, CX, DX, BP, 50)
-	ROUND3(BP, AX, BX, CX, DX, 51)
-	ROUND3(DX, BP, AX, BX, CX, 52)
-	ROUND3(CX, DX, BP, AX, BX, 53)
-	ROUND3(BX, CX, DX, BP, AX, 54)
-	ROUND3(AX, BX, CX, DX, BP, 55)
-	ROUND3(BP, AX, BX, CX, DX, 56)
-	ROUND3(DX, BP, AX, BX, CX, 57)
-	ROUND3(CX, DX, BP, AX, BX, 58)
-	ROUND3(BX, CX, DX, BP, AX, 59)
-	
-	ROUND4(AX, BX, CX, DX, BP, 60)
-	ROUND4(BP, AX, BX, CX, DX, 61)
-	ROUND4(DX, BP, AX, BX, CX, 62)
-	ROUND4(CX, DX, BP, AX, BX, 63)
-	ROUND4(BX, CX, DX, BP, AX, 64)
-	ROUND4(AX, BX, CX, DX, BP, 65)
-	ROUND4(BP, AX, BX, CX, DX, 66)
-	ROUND4(DX, BP, AX, BX, CX, 67)
-	ROUND4(CX, DX, BP, AX, BX, 68)
-	ROUND4(BX, CX, DX, BP, AX, 69)
-	ROUND4(AX, BX, CX, DX, BP, 70)
-	ROUND4(BP, AX, BX, CX, DX, 71)
-	ROUND4(DX, BP, AX, BX, CX, 72)
-	ROUND4(CX, DX, BP, AX, BX, 73)
-	ROUND4(BX, CX, DX, BP, AX, 74)
-	ROUND4(AX, BX, CX, DX, BP, 75)
-	ROUND4(BP, AX, BX, CX, DX, 76)
-	ROUND4(DX, BP, AX, BX, CX, 77)
-	ROUND4(CX, DX, BP, AX, BX, 78)
-	ROUND4(BX, CX, DX, BP, AX, 79)
-
-	ADDL	64(SP), AX
-	ADDL	68(SP), BX
-	ADDL	72(SP), CX
-	ADDL	76(SP), DX
-	ADDL	80(SP), BP
-
-	MOVL	88(SP), SI
-	ADDL	$64, SI
-	CMPL	SI, 84(SP)
-	JB	loop
-
-end:
-	MOVL	dig+0(FP), DI
-	MOVL	AX, (0*4)(DI)
-	MOVL	BX, (1*4)(DI)
-	MOVL	CX, (2*4)(DI)
-	MOVL	DX, (3*4)(DI)
-	MOVL	BP, (4*4)(DI)
-	RET
diff --git a/src/pkg/crypto/sha1/sha1block_amd64.s b/src/pkg/crypto/sha1/sha1block_amd64.s
deleted file mode 100644
index 8ffb9d5..0000000
--- a/src/pkg/crypto/sha1/sha1block_amd64.s
+++ /dev/null
@@ -1,216 +0,0 @@
-// Copyright 2013 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../../cmd/ld/textflag.h"
-
-// SHA1 block routine. See sha1block.go for Go equivalent.
-//
-// There are 80 rounds of 4 types:
-//   - rounds 0-15 are type 1 and load data (ROUND1 macro).
-//   - rounds 16-19 are type 1 and do not load data (ROUND1x macro).
-//   - rounds 20-39 are type 2 and do not load data (ROUND2 macro).
-//   - rounds 40-59 are type 3 and do not load data (ROUND3 macro).
-//   - rounds 60-79 are type 4 and do not load data (ROUND4 macro).
-//
-// Each round loads or shuffles the data, then computes a per-round
-// function of b, c, d, and then mixes the result into and rotates the
-// five registers a, b, c, d, e holding the intermediate results.
-//
-// The register rotation is implemented by rotating the arguments to
-// the round macros instead of by explicit move instructions.
-
-#define LOAD(index) \
-	MOVL	(index*4)(SI), R10; \
-	BSWAPL	R10; \
-	MOVL	R10, (index*4)(SP)
-
-#define SHUFFLE(index) \
-	MOVL	(((index)&0xf)*4)(SP), R10; \
-	XORL	(((index-3)&0xf)*4)(SP), R10; \
-	XORL	(((index-8)&0xf)*4)(SP), R10; \
-	XORL	(((index-14)&0xf)*4)(SP), R10; \
-	ROLL	$1, R10; \
-	MOVL	R10, (((index)&0xf)*4)(SP)
-
-#define FUNC1(a, b, c, d, e) \
-	MOVL	d, R9; \
-	XORL	c, R9; \
-	ANDL	b, R9; \
-	XORL	d, R9
-
-#define FUNC2(a, b, c, d, e) \
-	MOVL	b, R9; \
-	XORL	c, R9; \
-	XORL	d, R9
-
-#define FUNC3(a, b, c, d, e) \
-	MOVL	b, R8; \
-	ORL	c, R8; \
-	ANDL	d, R8; \
-	MOVL	b, R9; \
-	ANDL	c, R9; \
-	ORL	R8, R9
-	
-#define FUNC4 FUNC2
-
-#define MIX(a, b, c, d, e, const) \
-	ROLL	$30, b; \
-	ADDL	R9, e; \
-	MOVL	a, R8; \
-	ROLL	$5, R8; \
-	LEAL	const(e)(R10*1), e; \
-	ADDL	R8, e
-
-#define ROUND1(a, b, c, d, e, index) \
-	LOAD(index); \
-	FUNC1(a, b, c, d, e); \
-	MIX(a, b, c, d, e, 0x5A827999)
-
-#define ROUND1x(a, b, c, d, e, index) \
-	SHUFFLE(index); \
-	FUNC1(a, b, c, d, e); \
-	MIX(a, b, c, d, e, 0x5A827999)
-
-#define ROUND2(a, b, c, d, e, index) \
-	SHUFFLE(index); \
-	FUNC2(a, b, c, d, e); \
-	MIX(a, b, c, d, e, 0x6ED9EBA1)
-
-#define ROUND3(a, b, c, d, e, index) \
-	SHUFFLE(index); \
-	FUNC3(a, b, c, d, e); \
-	MIX(a, b, c, d, e, 0x8F1BBCDC)
-
-#define ROUND4(a, b, c, d, e, index) \
-	SHUFFLE(index); \
-	FUNC4(a, b, c, d, e); \
-	MIX(a, b, c, d, e, 0xCA62C1D6)
-
-TEXT ·block(SB),NOSPLIT,$64-32
-	MOVQ	dig+0(FP),	BP
-	MOVQ	p_base+8(FP),	SI
-	MOVQ	p_len+16(FP),	DX
-	SHRQ	$6,		DX
-	SHLQ	$6,		DX
-	
-	LEAQ	(SI)(DX*1),	DI
-	MOVL	(0*4)(BP),	AX
-	MOVL	(1*4)(BP),	BX
-	MOVL	(2*4)(BP),	CX
-	MOVL	(3*4)(BP),	DX
-	MOVL	(4*4)(BP),	BP
-
-	CMPQ	SI,		DI
-	JEQ	end
-
-loop:
-	MOVL	AX,	R11
-	MOVL	BX,	R12
-	MOVL	CX,	R13
-	MOVL	DX,	R14
-	MOVL	BP,	R15
-
-	ROUND1(AX, BX, CX, DX, BP, 0)
-	ROUND1(BP, AX, BX, CX, DX, 1)
-	ROUND1(DX, BP, AX, BX, CX, 2)
-	ROUND1(CX, DX, BP, AX, BX, 3)
-	ROUND1(BX, CX, DX, BP, AX, 4)
-	ROUND1(AX, BX, CX, DX, BP, 5)
-	ROUND1(BP, AX, BX, CX, DX, 6)
-	ROUND1(DX, BP, AX, BX, CX, 7)
-	ROUND1(CX, DX, BP, AX, BX, 8)
-	ROUND1(BX, CX, DX, BP, AX, 9)
-	ROUND1(AX, BX, CX, DX, BP, 10)
-	ROUND1(BP, AX, BX, CX, DX, 11)
-	ROUND1(DX, BP, AX, BX, CX, 12)
-	ROUND1(CX, DX, BP, AX, BX, 13)
-	ROUND1(BX, CX, DX, BP, AX, 14)
-	ROUND1(AX, BX, CX, DX, BP, 15)
-
-	ROUND1x(BP, AX, BX, CX, DX, 16)
-	ROUND1x(DX, BP, AX, BX, CX, 17)
-	ROUND1x(CX, DX, BP, AX, BX, 18)
-	ROUND1x(BX, CX, DX, BP, AX, 19)
-	
-	ROUND2(AX, BX, CX, DX, BP, 20)
-	ROUND2(BP, AX, BX, CX, DX, 21)
-	ROUND2(DX, BP, AX, BX, CX, 22)
-	ROUND2(CX, DX, BP, AX, BX, 23)
-	ROUND2(BX, CX, DX, BP, AX, 24)
-	ROUND2(AX, BX, CX, DX, BP, 25)
-	ROUND2(BP, AX, BX, CX, DX, 26)
-	ROUND2(DX, BP, AX, BX, CX, 27)
-	ROUND2(CX, DX, BP, AX, BX, 28)
-	ROUND2(BX, CX, DX, BP, AX, 29)
-	ROUND2(AX, BX, CX, DX, BP, 30)
-	ROUND2(BP, AX, BX, CX, DX, 31)
-	ROUND2(DX, BP, AX, BX, CX, 32)
-	ROUND2(CX, DX, BP, AX, BX, 33)
-	ROUND2(BX, CX, DX, BP, AX, 34)
-	ROUND2(AX, BX, CX, DX, BP, 35)
-	ROUND2(BP, AX, BX, CX, DX, 36)
-	ROUND2(DX, BP, AX, BX, CX, 37)
-	ROUND2(CX, DX, BP, AX, BX, 38)
-	ROUND2(BX, CX, DX, BP, AX, 39)
-	
-	ROUND3(AX, BX, CX, DX, BP, 40)
-	ROUND3(BP, AX, BX, CX, DX, 41)
-	ROUND3(DX, BP, AX, BX, CX, 42)
-	ROUND3(CX, DX, BP, AX, BX, 43)
-	ROUND3(BX, CX, DX, BP, AX, 44)
-	ROUND3(AX, BX, CX, DX, BP, 45)
-	ROUND3(BP, AX, BX, CX, DX, 46)
-	ROUND3(DX, BP, AX, BX, CX, 47)
-	ROUND3(CX, DX, BP, AX, BX, 48)
-	ROUND3(BX, CX, DX, BP, AX, 49)
-	ROUND3(AX, BX, CX, DX, BP, 50)
-	ROUND3(BP, AX, BX, CX, DX, 51)
-	ROUND3(DX, BP, AX, BX, CX, 52)
-	ROUND3(CX, DX, BP, AX, BX, 53)
-	ROUND3(BX, CX, DX, BP, AX, 54)
-	ROUND3(AX, BX, CX, DX, BP, 55)
-	ROUND3(BP, AX, BX, CX, DX, 56)
-	ROUND3(DX, BP, AX, BX, CX, 57)
-	ROUND3(CX, DX, BP, AX, BX, 58)
-	ROUND3(BX, CX, DX, BP, AX, 59)
-	
-	ROUND4(AX, BX, CX, DX, BP, 60)
-	ROUND4(BP, AX, BX, CX, DX, 61)
-	ROUND4(DX, BP, AX, BX, CX, 62)
-	ROUND4(CX, DX, BP, AX, BX, 63)
-	ROUND4(BX, CX, DX, BP, AX, 64)
-	ROUND4(AX, BX, CX, DX, BP, 65)
-	ROUND4(BP, AX, BX, CX, DX, 66)
-	ROUND4(DX, BP, AX, BX, CX, 67)
-	ROUND4(CX, DX, BP, AX, BX, 68)
-	ROUND4(BX, CX, DX, BP, AX, 69)
-	ROUND4(AX, BX, CX, DX, BP, 70)
-	ROUND4(BP, AX, BX, CX, DX, 71)
-	ROUND4(DX, BP, AX, BX, CX, 72)
-	ROUND4(CX, DX, BP, AX, BX, 73)
-	ROUND4(BX, CX, DX, BP, AX, 74)
-	ROUND4(AX, BX, CX, DX, BP, 75)
-	ROUND4(BP, AX, BX, CX, DX, 76)
-	ROUND4(DX, BP, AX, BX, CX, 77)
-	ROUND4(CX, DX, BP, AX, BX, 78)
-	ROUND4(BX, CX, DX, BP, AX, 79)
-
-	ADDL	R11, AX
-	ADDL	R12, BX
-	ADDL	R13, CX
-	ADDL	R14, DX
-	ADDL	R15, BP
-
-	ADDQ	$64, SI
-	CMPQ	SI, DI
-	JB	loop
-
-end:
-	MOVQ	dig+0(FP), DI
-	MOVL	AX, (0*4)(DI)
-	MOVL	BX, (1*4)(DI)
-	MOVL	CX, (2*4)(DI)
-	MOVL	DX, (3*4)(DI)
-	MOVL	BP, (4*4)(DI)
-	RET
diff --git a/src/pkg/crypto/sha1/sha1block_amd64p32.s b/src/pkg/crypto/sha1/sha1block_amd64p32.s
deleted file mode 100644
index 3c589d9..0000000
--- a/src/pkg/crypto/sha1/sha1block_amd64p32.s
+++ /dev/null
@@ -1,216 +0,0 @@
-// Copyright 2013 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../../cmd/ld/textflag.h"
-
-// SHA1 block routine. See sha1block.go for Go equivalent.
-//
-// There are 80 rounds of 4 types:
-//   - rounds 0-15 are type 1 and load data (ROUND1 macro).
-//   - rounds 16-19 are type 1 and do not load data (ROUND1x macro).
-//   - rounds 20-39 are type 2 and do not load data (ROUND2 macro).
-//   - rounds 40-59 are type 3 and do not load data (ROUND3 macro).
-//   - rounds 60-79 are type 4 and do not load data (ROUND4 macro).
-//
-// Each round loads or shuffles the data, then computes a per-round
-// function of b, c, d, and then mixes the result into and rotates the
-// five registers a, b, c, d, e holding the intermediate results.
-//
-// The register rotation is implemented by rotating the arguments to
-// the round macros instead of by explicit move instructions.
-//
-// amd64p32 version.
-// To ensure safety for Native Client, avoids use of BP and R15
-// as well as two-register addressing modes.
-
-#define LOAD(index) \
-	MOVL	(index*4)(SI), R10; \
-	BSWAPL	R10; \
-	MOVL	R10, (index*4)(SP)
-
-#define SHUFFLE(index) \
-	MOVL	(((index)&0xf)*4)(SP), R10; \
-	XORL	(((index-3)&0xf)*4)(SP), R10; \
-	XORL	(((index-8)&0xf)*4)(SP), R10; \
-	XORL	(((index-14)&0xf)*4)(SP), R10; \
-	ROLL	$1, R10; \
-	MOVL	R10, (((index)&0xf)*4)(SP)
-
-#define FUNC1(a, b, c, d, e) \
-	MOVL	d, R9; \
-	XORL	c, R9; \
-	ANDL	b, R9; \
-	XORL	d, R9
-
-#define FUNC2(a, b, c, d, e) \
-	MOVL	b, R9; \
-	XORL	c, R9; \
-	XORL	d, R9
-
-#define FUNC3(a, b, c, d, e) \
-	MOVL	b, R8; \
-	ORL	c, R8; \
-	ANDL	d, R8; \
-	MOVL	b, R9; \
-	ANDL	c, R9; \
-	ORL	R8, R9
-	
-#define FUNC4 FUNC2
-
-#define MIX(a, b, c, d, e, const) \
-	ROLL	$30, b; \
-	ADDL	R9, e; \
-	MOVL	a, R8; \
-	ROLL	$5, R8; \
-	LEAL	const(e)(R10*1), e; \
-	ADDL	R8, e
-
-#define ROUND1(a, b, c, d, e, index) \
-	LOAD(index); \
-	FUNC1(a, b, c, d, e); \
-	MIX(a, b, c, d, e, 0x5A827999)
-
-#define ROUND1x(a, b, c, d, e, index) \
-	SHUFFLE(index); \
-	FUNC1(a, b, c, d, e); \
-	MIX(a, b, c, d, e, 0x5A827999)
-
-#define ROUND2(a, b, c, d, e, index) \
-	SHUFFLE(index); \
-	FUNC2(a, b, c, d, e); \
-	MIX(a, b, c, d, e, 0x6ED9EBA1)
-
-#define ROUND3(a, b, c, d, e, index) \
-	SHUFFLE(index); \
-	FUNC3(a, b, c, d, e); \
-	MIX(a, b, c, d, e, 0x8F1BBCDC)
-
-#define ROUND4(a, b, c, d, e, index) \
-	SHUFFLE(index); \
-	FUNC4(a, b, c, d, e); \
-	MIX(a, b, c, d, e, 0xCA62C1D6)
-
-TEXT ·block(SB),NOSPLIT,$64-32
-	MOVL	dig+0(FP),	R14
-	MOVL	p_base+4(FP),	SI
-	MOVL	p_len+8(FP),	DX
-	SHRQ	$6,		DX
-	SHLQ	$6,		DX
-	
-	LEAQ	(SI)(DX*1),	DI
-	MOVL	(0*4)(R14),	AX
-	MOVL	(1*4)(R14),	BX
-	MOVL	(2*4)(R14),	CX
-	MOVL	(3*4)(R14),	DX
-	MOVL	(4*4)(R14),	R13
-
-	CMPQ	SI,		DI
-	JEQ	end
-
-loop:
-#define BP R13 /* keep diff from sha1block_amd64.s small */
-	ROUND1(AX, BX, CX, DX, BP, 0)
-	ROUND1(BP, AX, BX, CX, DX, 1)
-	ROUND1(DX, BP, AX, BX, CX, 2)
-	ROUND1(CX, DX, BP, AX, BX, 3)
-	ROUND1(BX, CX, DX, BP, AX, 4)
-	ROUND1(AX, BX, CX, DX, BP, 5)
-	ROUND1(BP, AX, BX, CX, DX, 6)
-	ROUND1(DX, BP, AX, BX, CX, 7)
-	ROUND1(CX, DX, BP, AX, BX, 8)
-	ROUND1(BX, CX, DX, BP, AX, 9)
-	ROUND1(AX, BX, CX, DX, BP, 10)
-	ROUND1(BP, AX, BX, CX, DX, 11)
-	ROUND1(DX, BP, AX, BX, CX, 12)
-	ROUND1(CX, DX, BP, AX, BX, 13)
-	ROUND1(BX, CX, DX, BP, AX, 14)
-	ROUND1(AX, BX, CX, DX, BP, 15)
-
-	ROUND1x(BP, AX, BX, CX, DX, 16)
-	ROUND1x(DX, BP, AX, BX, CX, 17)
-	ROUND1x(CX, DX, BP, AX, BX, 18)
-	ROUND1x(BX, CX, DX, BP, AX, 19)
-	
-	ROUND2(AX, BX, CX, DX, BP, 20)
-	ROUND2(BP, AX, BX, CX, DX, 21)
-	ROUND2(DX, BP, AX, BX, CX, 22)
-	ROUND2(CX, DX, BP, AX, BX, 23)
-	ROUND2(BX, CX, DX, BP, AX, 24)
-	ROUND2(AX, BX, CX, DX, BP, 25)
-	ROUND2(BP, AX, BX, CX, DX, 26)
-	ROUND2(DX, BP, AX, BX, CX, 27)
-	ROUND2(CX, DX, BP, AX, BX, 28)
-	ROUND2(BX, CX, DX, BP, AX, 29)
-	ROUND2(AX, BX, CX, DX, BP, 30)
-	ROUND2(BP, AX, BX, CX, DX, 31)
-	ROUND2(DX, BP, AX, BX, CX, 32)
-	ROUND2(CX, DX, BP, AX, BX, 33)
-	ROUND2(BX, CX, DX, BP, AX, 34)
-	ROUND2(AX, BX, CX, DX, BP, 35)
-	ROUND2(BP, AX, BX, CX, DX, 36)
-	ROUND2(DX, BP, AX, BX, CX, 37)
-	ROUND2(CX, DX, BP, AX, BX, 38)
-	ROUND2(BX, CX, DX, BP, AX, 39)
-	
-	ROUND3(AX, BX, CX, DX, BP, 40)
-	ROUND3(BP, AX, BX, CX, DX, 41)
-	ROUND3(DX, BP, AX, BX, CX, 42)
-	ROUND3(CX, DX, BP, AX, BX, 43)
-	ROUND3(BX, CX, DX, BP, AX, 44)
-	ROUND3(AX, BX, CX, DX, BP, 45)
-	ROUND3(BP, AX, BX, CX, DX, 46)
-	ROUND3(DX, BP, AX, BX, CX, 47)
-	ROUND3(CX, DX, BP, AX, BX, 48)
-	ROUND3(BX, CX, DX, BP, AX, 49)
-	ROUND3(AX, BX, CX, DX, BP, 50)
-	ROUND3(BP, AX, BX, CX, DX, 51)
-	ROUND3(DX, BP, AX, BX, CX, 52)
-	ROUND3(CX, DX, BP, AX, BX, 53)
-	ROUND3(BX, CX, DX, BP, AX, 54)
-	ROUND3(AX, BX, CX, DX, BP, 55)
-	ROUND3(BP, AX, BX, CX, DX, 56)
-	ROUND3(DX, BP, AX, BX, CX, 57)
-	ROUND3(CX, DX, BP, AX, BX, 58)
-	ROUND3(BX, CX, DX, BP, AX, 59)
-	
-	ROUND4(AX, BX, CX, DX, BP, 60)
-	ROUND4(BP, AX, BX, CX, DX, 61)
-	ROUND4(DX, BP, AX, BX, CX, 62)
-	ROUND4(CX, DX, BP, AX, BX, 63)
-	ROUND4(BX, CX, DX, BP, AX, 64)
-	ROUND4(AX, BX, CX, DX, BP, 65)
-	ROUND4(BP, AX, BX, CX, DX, 66)
-	ROUND4(DX, BP, AX, BX, CX, 67)
-	ROUND4(CX, DX, BP, AX, BX, 68)
-	ROUND4(BX, CX, DX, BP, AX, 69)
-	ROUND4(AX, BX, CX, DX, BP, 70)
-	ROUND4(BP, AX, BX, CX, DX, 71)
-	ROUND4(DX, BP, AX, BX, CX, 72)
-	ROUND4(CX, DX, BP, AX, BX, 73)
-	ROUND4(BX, CX, DX, BP, AX, 74)
-	ROUND4(AX, BX, CX, DX, BP, 75)
-	ROUND4(BP, AX, BX, CX, DX, 76)
-	ROUND4(DX, BP, AX, BX, CX, 77)
-	ROUND4(CX, DX, BP, AX, BX, 78)
-	ROUND4(BX, CX, DX, BP, AX, 79)
-#undef BP
-
-	ADDL	(0*4)(R14), AX
-	ADDL	(1*4)(R14), BX
-	ADDL	(2*4)(R14), CX
-	ADDL	(3*4)(R14), DX
-	ADDL	(4*4)(R14), R13
-
-	MOVL	AX, (0*4)(R14)
-	MOVL	BX, (1*4)(R14)
-	MOVL	CX, (2*4)(R14)
-	MOVL	DX, (3*4)(R14)
-	MOVL	R13, (4*4)(R14)
-
-	ADDQ	$64, SI
-	CMPQ	SI, DI
-	JB	loop
-
-end:
-	RET
diff --git a/src/pkg/crypto/sha1/sha1block_arm.s b/src/pkg/crypto/sha1/sha1block_arm.s
deleted file mode 100644
index 5917e8b..0000000
--- a/src/pkg/crypto/sha1/sha1block_arm.s
+++ /dev/null
@@ -1,217 +0,0 @@
-// Copyright 2014 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-//
-// ARM version of md5block.go
-
-#include "../../../cmd/ld/textflag.h"
-
-// SHA1 block routine. See sha1block.go for Go equivalent.
-//
-// There are 80 rounds of 4 types:
-//   - rounds 0-15 are type 1 and load data (ROUND1 macro).
-//   - rounds 16-19 are type 1 and do not load data (ROUND1x macro).
-//   - rounds 20-39 are type 2 and do not load data (ROUND2 macro).
-//   - rounds 40-59 are type 3 and do not load data (ROUND3 macro).
-//   - rounds 60-79 are type 4 and do not load data (ROUND4 macro).
-//
-// Each round loads or shuffles the data, then computes a per-round
-// function of b, c, d, and then mixes the result into and rotates the
-// five registers a, b, c, d, e holding the intermediate results.
-//
-// The register rotation is implemented by rotating the arguments to
-// the round macros instead of by explicit move instructions.
-
-// Register definitions
-data = 0	// Pointer to incoming data
-const = 1	// Current constant for SHA round
-a = 2		// SHA1 accumulator
-b = 3		// SHA1 accumulator
-c = 4		// SHA1 accumulator
-d = 5		// SHA1 accumulator
-e = 6		// SHA1 accumulator
-t0 = 7		// Temporary
-t1 = 8		// Temporary
-// r9, r10 are forbidden
-// r11 is OK provided you check the assembler that no synthetic instructions use it
-t2 = 11		// Temporary
-ctr = 12	// loop counter
-w = 14		// point to w buffer
-
-// func block(dig *digest, p []byte)
-// 0(FP) is *digest
-// 4(FP) is p.array (struct Slice)
-// 8(FP) is p.len
-//12(FP) is p.cap
-//
-// Stack frame
-p_end = -4		// -4(SP) pointer to the end of data
-p_data = p_end - 4	// -8(SP) current data pointer
-w_buf = p_data - 4*80	// -328(SP) 80 words temporary buffer w uint32[80]
-saved = w_buf - 4*5	// -348(SP) saved sha1 registers a,b,c,d,e - these must be last
-// Total size +4 for saved LR is 352
-
-	// w[i] = p[j]<<24 | p[j+1]<<16 | p[j+2]<<8 | p[j+3]
-	// e += w[i]
-#define LOAD(e) \
-	MOVBU	2(R(data)), R(t0) ; \
-	MOVBU	3(R(data)), R(t1) ; \
-	MOVBU	1(R(data)), R(t2) ; \
-	ORR	R(t0)<<8, R(t1), R(t0)	    ; \
-	MOVBU.P	4(R(data)), R(t1) ; \
-	ORR	R(t2)<<16, R(t0), R(t0)	    ; \
-	ORR	R(t1)<<24, R(t0), R(t0)	    ; \
-	MOVW.P	R(t0), 4(R(w))		    ; \
-	ADD	R(t0), R(e), R(e)
-	
-	// tmp := w[(i-3)&0xf] ^ w[(i-8)&0xf] ^ w[(i-14)&0xf] ^ w[(i)&0xf]
-	// w[i&0xf] = tmp<<1 | tmp>>(32-1)
-	// e += w[i&0xf] 
-#define SHUFFLE(e) \
-	MOVW	(-16*4)(R(w)), R(t0) ; \
-	MOVW	(-14*4)(R(w)), R(t1) ; \
-	MOVW	(-8*4)(R(w)), R(t2)  ; \
-	EOR	R(t0), R(t1), R(t0)  ; \
-	MOVW	(-3*4)(R(w)), R(t1)  ; \
-	EOR	R(t2), R(t0), R(t0)  ; \
-	EOR	R(t0), R(t1), R(t0)  ; \
-	MOVW	R(t0)@>(32-1), R(t0)  ; \
-	MOVW.P	R(t0), 4(R(w))	  ; \
-	ADD	R(t0), R(e), R(e)
-
-	// t1 = (b & c) | ((~b) & d)
-#define FUNC1(a, b, c, d, e) \
-	MVN	R(b), R(t1)	   ; \
-	AND	R(b), R(c), R(t0)  ; \
-	AND	R(d), R(t1), R(t1) ; \
-	ORR	R(t0), R(t1), R(t1)
-
-	// t1 = b ^ c ^ d
-#define FUNC2(a, b, c, d, e) \
-	EOR	R(b), R(c), R(t1) ; \
-	EOR	R(d), R(t1), R(t1)
-
-	// t1 = (b & c) | (b & d) | (c & d) =
-	// t1 = (b & c) | ((b | c) & d)
-#define FUNC3(a, b, c, d, e) \
-	ORR	R(b), R(c), R(t0)  ; \
-	AND	R(b), R(c), R(t1)  ; \
-	AND	R(d), R(t0), R(t0) ; \
-	ORR	R(t0), R(t1), R(t1)
-
-#define FUNC4 FUNC2
-
-	// a5 := a<<5 | a>>(32-5)
-	// b = b<<30 | b>>(32-30)
-	// e = a5 + t1 + e + const
-#define MIX(a, b, c, d, e) \
-	ADD	R(t1), R(e), R(e)	 ; \
-	MOVW	R(b)@>(32-30), R(b)	 ; \
-	ADD	R(a)@>(32-5), R(e), R(e) ; \
-	ADD	R(const), R(e), R(e)
-
-#define ROUND1(a, b, c, d, e) \
-	LOAD(e)		; \
-	FUNC1(a, b, c, d, e)	; \
-	MIX(a, b, c, d, e)
-
-#define ROUND1x(a, b, c, d, e) \
-	SHUFFLE(e)	; \
-	FUNC1(a, b, c, d, e)	; \
-	MIX(a, b, c, d, e)
-
-#define ROUND2(a, b, c, d, e) \
-	SHUFFLE(e)	; \
-	FUNC2(a, b, c, d, e)	; \
-	MIX(a, b, c, d, e)
-
-#define ROUND3(a, b, c, d, e) \
-	SHUFFLE(e)	; \
-	FUNC3(a, b, c, d, e)	; \
-	MIX(a, b, c, d, e)
-
-#define ROUND4(a, b, c, d, e) \
-	SHUFFLE(e)	; \
-	FUNC4(a, b, c, d, e)	; \
-	MIX(a, b, c, d, e)
-
-
-// func block(dig *digest, p []byte)
-TEXT	·block(SB), 0, $352-16
-	MOVW	p+4(FP), R(data)	// pointer to the data
-	MOVW	p_len+8(FP), R(t0)	// number of bytes
-	ADD	R(data), R(t0)
-	MOVW	R(t0), p_end(SP)	// pointer to end of data
-
-	// Load up initial SHA1 accumulator
-	MOVW	dig+0(FP), R(t0)
-	MOVM.IA (R(t0)), [R(a),R(b),R(c),R(d),R(e)]
-
-loop:
-	// Save registers at SP+4 onwards
-	MOVM.IB [R(a),R(b),R(c),R(d),R(e)], (R13)
-
-	MOVW	$w_buf(SP), R(w)
-	MOVW	$0x5A827999, R(const)
-	MOVW	$3, R(ctr)
-loop1:	ROUND1(a, b, c, d, e)
-	ROUND1(e, a, b, c, d)
-	ROUND1(d, e, a, b, c)
-	ROUND1(c, d, e, a, b)
-	ROUND1(b, c, d, e, a)
-	SUB.S	$1, R(ctr)
-	BNE	loop1
-
-	ROUND1(a, b, c, d, e)
-	ROUND1x(e, a, b, c, d)
-	ROUND1x(d, e, a, b, c)
-	ROUND1x(c, d, e, a, b)
-	ROUND1x(b, c, d, e, a)
-	
-	MOVW	$0x6ED9EBA1, R(const)
-	MOVW	$4, R(ctr)
-loop2:	ROUND2(a, b, c, d, e)
-	ROUND2(e, a, b, c, d)
-	ROUND2(d, e, a, b, c)
-	ROUND2(c, d, e, a, b)
-	ROUND2(b, c, d, e, a)
-	SUB.S	$1, R(ctr)
-	BNE	loop2
-	
-	MOVW	$0x8F1BBCDC, R(const)
-	MOVW	$4, R(ctr)
-loop3:	ROUND3(a, b, c, d, e)
-	ROUND3(e, a, b, c, d)
-	ROUND3(d, e, a, b, c)
-	ROUND3(c, d, e, a, b)
-	ROUND3(b, c, d, e, a)
-	SUB.S	$1, R(ctr)
-	BNE	loop3
-	
-	MOVW	$0xCA62C1D6, R(const)
-	MOVW	$4, R(ctr)
-loop4:	ROUND4(a, b, c, d, e)
-	ROUND4(e, a, b, c, d)
-	ROUND4(d, e, a, b, c)
-	ROUND4(c, d, e, a, b)
-	ROUND4(b, c, d, e, a)
-	SUB.S	$1, R(ctr)
-	BNE	loop4
-
-	// Accumulate - restoring registers from SP+4
-	MOVM.IB (R13), [R(t0),R(t1),R(t2),R(ctr),R(w)]
-	ADD	R(t0), R(a)
-	ADD	R(t1), R(b)
-	ADD	R(t2), R(c)
-	ADD	R(ctr), R(d)
-	ADD	R(w), R(e)
-
-	MOVW	p_end(SP), R(t0)
-	CMP	R(t0), R(data)
-	BLO	loop
-
-	// Save final SHA1 accumulator
-	MOVW	dig+0(FP), R(t0)
-	MOVM.IA [R(a),R(b),R(c),R(d),R(e)], (R(t0))
-
-	RET
diff --git a/src/pkg/crypto/sha256/sha256block_amd64.s b/src/pkg/crypto/sha256/sha256block_amd64.s
deleted file mode 100644
index 95aebbe..0000000
--- a/src/pkg/crypto/sha256/sha256block_amd64.s
+++ /dev/null
@@ -1,256 +0,0 @@
-// Copyright 2013 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../../cmd/ld/textflag.h"
-
-// SHA256 block routine. See sha256block.go for Go equivalent.
-//
-// The algorithm is detailed in FIPS 180-4:
-//
-//  http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf
-//
-// Wt = Mt; for 0 <= t <= 15
-// Wt = SIGMA1(Wt-2) + SIGMA0(Wt-15) + Wt-16; for 16 <= t <= 63
-//
-// a = H0
-// b = H1
-// c = H2
-// d = H3
-// e = H4
-// f = H5
-// g = H6
-// h = H7
-//
-// for t = 0 to 63 {
-//    T1 = h + BIGSIGMA1(e) + Ch(e,f,g) + Kt + Wt
-//    T2 = BIGSIGMA0(a) + Maj(a,b,c)
-//    h = g
-//    g = f
-//    f = e
-//    e = d + T1
-//    d = c
-//    c = b
-//    b = a
-//    a = T1 + T2
-// }
-//
-// H0 = a + H0
-// H1 = b + H1
-// H2 = c + H2
-// H3 = d + H3
-// H4 = e + H4
-// H5 = f + H5
-// H6 = g + H6
-// H7 = h + H7
-
-// Wt = Mt; for 0 <= t <= 15
-#define MSGSCHEDULE0(index) \
-	MOVL	(index*4)(SI), AX; \
-	BSWAPL	AX; \
-	MOVL	AX, (index*4)(BP)
-
-// Wt = SIGMA1(Wt-2) + Wt-7 + SIGMA0(Wt-15) + Wt-16; for 16 <= t <= 63
-//   SIGMA0(x) = ROTR(7,x) XOR ROTR(18,x) XOR SHR(3,x)
-//   SIGMA1(x) = ROTR(17,x) XOR ROTR(19,x) XOR SHR(10,x)
-#define MSGSCHEDULE1(index) \
-	MOVL	((index-2)*4)(BP), AX; \
-	MOVL	AX, CX; \
-	RORL	$17, AX; \
-	MOVL	CX, DX; \
-	RORL	$19, CX; \
-	SHRL	$10, DX; \
-	MOVL	((index-15)*4)(BP), BX; \
-	XORL	CX, AX; \
-	MOVL	BX, CX; \
-	XORL	DX, AX; \
-	RORL	$7, BX; \
-	MOVL	CX, DX; \
-	SHRL	$3, DX; \
-	RORL	$18, CX; \
-	ADDL	((index-7)*4)(BP), AX; \
-	XORL	CX, BX; \
-	XORL	DX, BX; \
-	ADDL	((index-16)*4)(BP), BX; \
-	ADDL	BX, AX; \
-	MOVL	AX, ((index)*4)(BP)
-
-// Calculate T1 in AX - uses AX, CX and DX registers.
-// h is also used as an accumulator. Wt is passed in AX.
-//   T1 = h + BIGSIGMA1(e) + Ch(e, f, g) + Kt + Wt
-//     BIGSIGMA1(x) = ROTR(6,x) XOR ROTR(11,x) XOR ROTR(25,x)
-//     Ch(x, y, z) = (x AND y) XOR (NOT x AND z)
-#define SHA256T1(const, e, f, g, h) \
-	ADDL	AX, h; \
-	MOVL	e, AX; \
-	ADDL	$const, h; \
-	MOVL	e, CX; \
-	RORL	$6, AX; \
-	MOVL	e, DX; \
-	RORL	$11, CX; \
-	XORL	CX, AX; \
-	MOVL	e, CX; \
-	RORL	$25, DX; \
-	ANDL	f, CX; \
-	XORL	AX, DX; \
-	MOVL	e, AX; \
-	NOTL	AX; \
-	ADDL	DX, h; \
-	ANDL	g, AX; \
-	XORL	CX, AX; \
-	ADDL	h, AX
-
-// Calculate T2 in BX - uses BX, CX, DX and DI registers.
-//   T2 = BIGSIGMA0(a) + Maj(a, b, c)
-//     BIGSIGMA0(x) = ROTR(2,x) XOR ROTR(13,x) XOR ROTR(22,x)
-//     Maj(x, y, z) = (x AND y) XOR (x AND z) XOR (y AND z)
-#define SHA256T2(a, b, c) \
-	MOVL	a, DI; \
-	MOVL	c, BX; \
-	RORL	$2, DI; \
-	MOVL	a, DX; \
-	ANDL	b, BX; \
-	RORL	$13, DX; \
-	MOVL	a, CX; \
-	ANDL	c, CX; \
-	XORL	DX, DI; \
-	XORL	CX, BX; \
-	MOVL	a, DX; \
-	MOVL	b, CX; \
-	RORL	$22, DX; \
-	ANDL	a, CX; \
-	XORL	CX, BX; \
-	XORL	DX, DI; \
-	ADDL	DI, BX
-
-// Calculate T1 and T2, then e = d + T1 and a = T1 + T2.
-// The values for e and a are stored in d and h, ready for rotation.
-#define SHA256ROUND(index, const, a, b, c, d, e, f, g, h) \
-	SHA256T1(const, e, f, g, h); \
-	SHA256T2(a, b, c); \
-	MOVL	BX, h; \
-	ADDL	AX, d; \
-	ADDL	AX, h
-
-#define SHA256ROUND0(index, const, a, b, c, d, e, f, g, h) \
-	MSGSCHEDULE0(index); \
-	SHA256ROUND(index, const, a, b, c, d, e, f, g, h)
-
-#define SHA256ROUND1(index, const, a, b, c, d, e, f, g, h) \
-	MSGSCHEDULE1(index); \
-	SHA256ROUND(index, const, a, b, c, d, e, f, g, h)
-
-TEXT ·block(SB),0,$264-32
-	MOVQ	p_base+8(FP), SI
-	MOVQ	p_len+16(FP), DX
-	SHRQ	$6, DX
-	SHLQ	$6, DX
-
-	LEAQ	(SI)(DX*1), DI
-	MOVQ	DI, 256(SP)
-	CMPQ	SI, DI
-	JEQ	end
-
-	MOVQ	dig+0(FP), BP
-	MOVL	(0*4)(BP), R8		// a = H0
-	MOVL	(1*4)(BP), R9		// b = H1
-	MOVL	(2*4)(BP), R10		// c = H2
-	MOVL	(3*4)(BP), R11		// d = H3
-	MOVL	(4*4)(BP), R12		// e = H4
-	MOVL	(5*4)(BP), R13		// f = H5
-	MOVL	(6*4)(BP), R14		// g = H6
-	MOVL	(7*4)(BP), R15		// h = H7
-
-loop:
-	MOVQ	SP, BP			// message schedule
-
-	SHA256ROUND0(0, 0x428a2f98, R8, R9, R10, R11, R12, R13, R14, R15)
-	SHA256ROUND0(1, 0x71374491, R15, R8, R9, R10, R11, R12, R13, R14)
-	SHA256ROUND0(2, 0xb5c0fbcf, R14, R15, R8, R9, R10, R11, R12, R13)
-	SHA256ROUND0(3, 0xe9b5dba5, R13, R14, R15, R8, R9, R10, R11, R12)
-	SHA256ROUND0(4, 0x3956c25b, R12, R13, R14, R15, R8, R9, R10, R11)
-	SHA256ROUND0(5, 0x59f111f1, R11, R12, R13, R14, R15, R8, R9, R10)
-	SHA256ROUND0(6, 0x923f82a4, R10, R11, R12, R13, R14, R15, R8, R9)
-	SHA256ROUND0(7, 0xab1c5ed5, R9, R10, R11, R12, R13, R14, R15, R8)
-	SHA256ROUND0(8, 0xd807aa98, R8, R9, R10, R11, R12, R13, R14, R15)
-	SHA256ROUND0(9, 0x12835b01, R15, R8, R9, R10, R11, R12, R13, R14)
-	SHA256ROUND0(10, 0x243185be, R14, R15, R8, R9, R10, R11, R12, R13)
-	SHA256ROUND0(11, 0x550c7dc3, R13, R14, R15, R8, R9, R10, R11, R12)
-	SHA256ROUND0(12, 0x72be5d74, R12, R13, R14, R15, R8, R9, R10, R11)
-	SHA256ROUND0(13, 0x80deb1fe, R11, R12, R13, R14, R15, R8, R9, R10)
-	SHA256ROUND0(14, 0x9bdc06a7, R10, R11, R12, R13, R14, R15, R8, R9)
-	SHA256ROUND0(15, 0xc19bf174, R9, R10, R11, R12, R13, R14, R15, R8)
-
-	SHA256ROUND1(16, 0xe49b69c1, R8, R9, R10, R11, R12, R13, R14, R15)
-	SHA256ROUND1(17, 0xefbe4786, R15, R8, R9, R10, R11, R12, R13, R14)
-	SHA256ROUND1(18, 0x0fc19dc6, R14, R15, R8, R9, R10, R11, R12, R13)
-	SHA256ROUND1(19, 0x240ca1cc, R13, R14, R15, R8, R9, R10, R11, R12)
-	SHA256ROUND1(20, 0x2de92c6f, R12, R13, R14, R15, R8, R9, R10, R11)
-	SHA256ROUND1(21, 0x4a7484aa, R11, R12, R13, R14, R15, R8, R9, R10)
-	SHA256ROUND1(22, 0x5cb0a9dc, R10, R11, R12, R13, R14, R15, R8, R9)
-	SHA256ROUND1(23, 0x76f988da, R9, R10, R11, R12, R13, R14, R15, R8)
-	SHA256ROUND1(24, 0x983e5152, R8, R9, R10, R11, R12, R13, R14, R15)
-	SHA256ROUND1(25, 0xa831c66d, R15, R8, R9, R10, R11, R12, R13, R14)
-	SHA256ROUND1(26, 0xb00327c8, R14, R15, R8, R9, R10, R11, R12, R13)
-	SHA256ROUND1(27, 0xbf597fc7, R13, R14, R15, R8, R9, R10, R11, R12)
-	SHA256ROUND1(28, 0xc6e00bf3, R12, R13, R14, R15, R8, R9, R10, R11)
-	SHA256ROUND1(29, 0xd5a79147, R11, R12, R13, R14, R15, R8, R9, R10)
-	SHA256ROUND1(30, 0x06ca6351, R10, R11, R12, R13, R14, R15, R8, R9)
-	SHA256ROUND1(31, 0x14292967, R9, R10, R11, R12, R13, R14, R15, R8)
-	SHA256ROUND1(32, 0x27b70a85, R8, R9, R10, R11, R12, R13, R14, R15)
-	SHA256ROUND1(33, 0x2e1b2138, R15, R8, R9, R10, R11, R12, R13, R14)
-	SHA256ROUND1(34, 0x4d2c6dfc, R14, R15, R8, R9, R10, R11, R12, R13)
-	SHA256ROUND1(35, 0x53380d13, R13, R14, R15, R8, R9, R10, R11, R12)
-	SHA256ROUND1(36, 0x650a7354, R12, R13, R14, R15, R8, R9, R10, R11)
-	SHA256ROUND1(37, 0x766a0abb, R11, R12, R13, R14, R15, R8, R9, R10)
-	SHA256ROUND1(38, 0x81c2c92e, R10, R11, R12, R13, R14, R15, R8, R9)
-	SHA256ROUND1(39, 0x92722c85, R9, R10, R11, R12, R13, R14, R15, R8)
-	SHA256ROUND1(40, 0xa2bfe8a1, R8, R9, R10, R11, R12, R13, R14, R15)
-	SHA256ROUND1(41, 0xa81a664b, R15, R8, R9, R10, R11, R12, R13, R14)
-	SHA256ROUND1(42, 0xc24b8b70, R14, R15, R8, R9, R10, R11, R12, R13)
-	SHA256ROUND1(43, 0xc76c51a3, R13, R14, R15, R8, R9, R10, R11, R12)
-	SHA256ROUND1(44, 0xd192e819, R12, R13, R14, R15, R8, R9, R10, R11)
-	SHA256ROUND1(45, 0xd6990624, R11, R12, R13, R14, R15, R8, R9, R10)
-	SHA256ROUND1(46, 0xf40e3585, R10, R11, R12, R13, R14, R15, R8, R9)
-	SHA256ROUND1(47, 0x106aa070, R9, R10, R11, R12, R13, R14, R15, R8)
-	SHA256ROUND1(48, 0x19a4c116, R8, R9, R10, R11, R12, R13, R14, R15)
-	SHA256ROUND1(49, 0x1e376c08, R15, R8, R9, R10, R11, R12, R13, R14)
-	SHA256ROUND1(50, 0x2748774c, R14, R15, R8, R9, R10, R11, R12, R13)
-	SHA256ROUND1(51, 0x34b0bcb5, R13, R14, R15, R8, R9, R10, R11, R12)
-	SHA256ROUND1(52, 0x391c0cb3, R12, R13, R14, R15, R8, R9, R10, R11)
-	SHA256ROUND1(53, 0x4ed8aa4a, R11, R12, R13, R14, R15, R8, R9, R10)
-	SHA256ROUND1(54, 0x5b9cca4f, R10, R11, R12, R13, R14, R15, R8, R9)
-	SHA256ROUND1(55, 0x682e6ff3, R9, R10, R11, R12, R13, R14, R15, R8)
-	SHA256ROUND1(56, 0x748f82ee, R8, R9, R10, R11, R12, R13, R14, R15)
-	SHA256ROUND1(57, 0x78a5636f, R15, R8, R9, R10, R11, R12, R13, R14)
-	SHA256ROUND1(58, 0x84c87814, R14, R15, R8, R9, R10, R11, R12, R13)
-	SHA256ROUND1(59, 0x8cc70208, R13, R14, R15, R8, R9, R10, R11, R12)
-	SHA256ROUND1(60, 0x90befffa, R12, R13, R14, R15, R8, R9, R10, R11)
-	SHA256ROUND1(61, 0xa4506ceb, R11, R12, R13, R14, R15, R8, R9, R10)
-	SHA256ROUND1(62, 0xbef9a3f7, R10, R11, R12, R13, R14, R15, R8, R9)
-	SHA256ROUND1(63, 0xc67178f2, R9, R10, R11, R12, R13, R14, R15, R8)
-
-	MOVQ	dig+0(FP), BP
-	ADDL	(0*4)(BP), R8	// H0 = a + H0
-	MOVL	R8, (0*4)(BP)
-	ADDL	(1*4)(BP), R9	// H1 = b + H1
-	MOVL	R9, (1*4)(BP)
-	ADDL	(2*4)(BP), R10	// H2 = c + H2
-	MOVL	R10, (2*4)(BP)
-	ADDL	(3*4)(BP), R11	// H3 = d + H3
-	MOVL	R11, (3*4)(BP)
-	ADDL	(4*4)(BP), R12	// H4 = e + H4
-	MOVL	R12, (4*4)(BP)
-	ADDL	(5*4)(BP), R13	// H5 = f + H5
-	MOVL	R13, (5*4)(BP)
-	ADDL	(6*4)(BP), R14	// H6 = g + H6
-	MOVL	R14, (6*4)(BP)
-	ADDL	(7*4)(BP), R15	// H7 = h + H7
-	MOVL	R15, (7*4)(BP)
-
-	ADDQ	$64, SI
-	CMPQ	SI, 256(SP)
-	JB	loop
-
-end:
-	RET
diff --git a/src/pkg/crypto/sha512/sha512block_amd64.s b/src/pkg/crypto/sha512/sha512block_amd64.s
deleted file mode 100644
index 344d8d2..0000000
--- a/src/pkg/crypto/sha512/sha512block_amd64.s
+++ /dev/null
@@ -1,273 +0,0 @@
-// Copyright 2013 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../../cmd/ld/textflag.h"
-
-// SHA512 block routine. See sha512block.go for Go equivalent.
-//
-// The algorithm is detailed in FIPS 180-4:
-//
-//  http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf
-//
-// Wt = Mt; for 0 <= t <= 15
-// Wt = SIGMA1(Wt-2) + SIGMA0(Wt-15) + Wt-16; for 16 <= t <= 79
-//
-// a = H0
-// b = H1
-// c = H2
-// d = H3
-// e = H4
-// f = H5
-// g = H6
-// h = H7
-//
-// for t = 0 to 79 {
-//    T1 = h + BIGSIGMA1(e) + Ch(e,f,g) + Kt + Wt
-//    T2 = BIGSIGMA0(a) + Maj(a,b,c)
-//    h = g
-//    g = f
-//    f = e
-//    e = d + T1
-//    d = c
-//    c = b
-//    b = a
-//    a = T1 + T2
-// }
-//
-// H0 = a + H0
-// H1 = b + H1
-// H2 = c + H2
-// H3 = d + H3
-// H4 = e + H4
-// H5 = f + H5
-// H6 = g + H6
-// H7 = h + H7
-
-// Wt = Mt; for 0 <= t <= 15
-#define MSGSCHEDULE0(index) \
-	MOVQ	(index*8)(SI), AX; \
-	BSWAPQ	AX; \
-	MOVQ	AX, (index*8)(BP)
-
-// Wt = SIGMA1(Wt-2) + Wt-7 + SIGMA0(Wt-15) + Wt-16; for 16 <= t <= 79
-//   SIGMA0(x) = ROTR(1,x) XOR ROTR(8,x) XOR SHR(7,x)
-//   SIGMA1(x) = ROTR(19,x) XOR ROTR(61,x) XOR SHR(6,x)
-#define MSGSCHEDULE1(index) \
-	MOVQ	((index-2)*8)(BP), AX; \
-	MOVQ	AX, CX; \
-	RORQ	$19, AX; \
-	MOVQ	CX, DX; \
-	RORQ	$61, CX; \
-	SHRQ	$6, DX; \
-	MOVQ	((index-15)*8)(BP), BX; \
-	XORQ	CX, AX; \
-	MOVQ	BX, CX; \
-	XORQ	DX, AX; \
-	RORQ	$1, BX; \
-	MOVQ	CX, DX; \
-	SHRQ	$7, DX; \
-	RORQ	$8, CX; \
-	ADDQ	((index-7)*8)(BP), AX; \
-	XORQ	CX, BX; \
-	XORQ	DX, BX; \
-	ADDQ	((index-16)*8)(BP), BX; \
-	ADDQ	BX, AX; \
-	MOVQ	AX, ((index)*8)(BP)
-
-// Calculate T1 in AX - uses AX, CX and DX registers.
-// h is also used as an accumulator. Wt is passed in AX.
-//   T1 = h + BIGSIGMA1(e) + Ch(e, f, g) + Kt + Wt
-//     BIGSIGMA1(x) = ROTR(14,x) XOR ROTR(18,x) XOR ROTR(41,x)
-//     Ch(x, y, z) = (x AND y) XOR (NOT x AND z)
-#define SHA512T1(const, e, f, g, h) \
-	MOVQ	$const, DX; \
-	ADDQ	AX, h; \
-	MOVQ	e, AX; \
-	ADDQ	DX, h; \
-	MOVQ	e, CX; \
-	RORQ	$14, AX; \
-	MOVQ	e, DX; \
-	RORQ	$18, CX; \
-	XORQ	CX, AX; \
-	MOVQ	e, CX; \
-	RORQ	$41, DX; \
-	ANDQ	f, CX; \
-	XORQ	AX, DX; \
-	MOVQ	e, AX; \
-	NOTQ	AX; \
-	ADDQ	DX, h; \
-	ANDQ	g, AX; \
-	XORQ	CX, AX; \
-	ADDQ	h, AX
-
-// Calculate T2 in BX - uses BX, CX, DX and DI registers.
-//   T2 = BIGSIGMA0(a) + Maj(a, b, c)
-//     BIGSIGMA0(x) = ROTR(28,x) XOR ROTR(34,x) XOR ROTR(39,x)
-//     Maj(x, y, z) = (x AND y) XOR (x AND z) XOR (y AND z)
-#define SHA512T2(a, b, c) \
-	MOVQ	a, DI; \
-	MOVQ	c, BX; \
-	RORQ	$28, DI; \
-	MOVQ	a, DX; \
-	ANDQ	b, BX; \
-	RORQ	$34, DX; \
-	MOVQ	a, CX; \
-	ANDQ	c, CX; \
-	XORQ	DX, DI; \
-	XORQ	CX, BX; \
-	MOVQ	a, DX; \
-	MOVQ	b, CX; \
-	RORQ	$39, DX; \
-	ANDQ	a, CX; \
-	XORQ	CX, BX; \
-	XORQ	DX, DI; \
-	ADDQ	DI, BX
-
-// Calculate T1 and T2, then e = d + T1 and a = T1 + T2.
-// The values for e and a are stored in d and h, ready for rotation.
-#define SHA512ROUND(index, const, a, b, c, d, e, f, g, h) \
-	SHA512T1(const, e, f, g, h); \
-	SHA512T2(a, b, c); \
-	MOVQ	BX, h; \
-	ADDQ	AX, d; \
-	ADDQ	AX, h
-
-#define SHA512ROUND0(index, const, a, b, c, d, e, f, g, h) \
-	MSGSCHEDULE0(index); \
-	SHA512ROUND(index, const, a, b, c, d, e, f, g, h)
-
-#define SHA512ROUND1(index, const, a, b, c, d, e, f, g, h) \
-	MSGSCHEDULE1(index); \
-	SHA512ROUND(index, const, a, b, c, d, e, f, g, h)
-
-TEXT ·block(SB),0,$648-32
-	MOVQ	p_base+8(FP), SI
-	MOVQ	p_len+16(FP), DX
-	SHRQ	$7, DX
-	SHLQ	$7, DX
-
-	LEAQ	(SI)(DX*1), DI
-	MOVQ	DI, 640(SP)
-	CMPQ	SI, DI
-	JEQ	end
-
-	MOVQ	dig+0(FP), BP
-	MOVQ	(0*8)(BP), R8		// a = H0
-	MOVQ	(1*8)(BP), R9		// b = H1
-	MOVQ	(2*8)(BP), R10		// c = H2
-	MOVQ	(3*8)(BP), R11		// d = H3
-	MOVQ	(4*8)(BP), R12		// e = H4
-	MOVQ	(5*8)(BP), R13		// f = H5
-	MOVQ	(6*8)(BP), R14		// g = H6
-	MOVQ	(7*8)(BP), R15		// h = H7
-
-loop:
-	MOVQ	SP, BP			// message schedule
-
-	SHA512ROUND0(0, 0x428a2f98d728ae22, R8, R9, R10, R11, R12, R13, R14, R15)
-	SHA512ROUND0(1, 0x7137449123ef65cd, R15, R8, R9, R10, R11, R12, R13, R14)
-	SHA512ROUND0(2, 0xb5c0fbcfec4d3b2f, R14, R15, R8, R9, R10, R11, R12, R13)
-	SHA512ROUND0(3, 0xe9b5dba58189dbbc, R13, R14, R15, R8, R9, R10, R11, R12)
-	SHA512ROUND0(4, 0x3956c25bf348b538, R12, R13, R14, R15, R8, R9, R10, R11)
-	SHA512ROUND0(5, 0x59f111f1b605d019, R11, R12, R13, R14, R15, R8, R9, R10)
-	SHA512ROUND0(6, 0x923f82a4af194f9b, R10, R11, R12, R13, R14, R15, R8, R9)
-	SHA512ROUND0(7, 0xab1c5ed5da6d8118, R9, R10, R11, R12, R13, R14, R15, R8)
-	SHA512ROUND0(8, 0xd807aa98a3030242, R8, R9, R10, R11, R12, R13, R14, R15)
-	SHA512ROUND0(9, 0x12835b0145706fbe, R15, R8, R9, R10, R11, R12, R13, R14)
-	SHA512ROUND0(10, 0x243185be4ee4b28c, R14, R15, R8, R9, R10, R11, R12, R13)
-	SHA512ROUND0(11, 0x550c7dc3d5ffb4e2, R13, R14, R15, R8, R9, R10, R11, R12)
-	SHA512ROUND0(12, 0x72be5d74f27b896f, R12, R13, R14, R15, R8, R9, R10, R11)
-	SHA512ROUND0(13, 0x80deb1fe3b1696b1, R11, R12, R13, R14, R15, R8, R9, R10)
-	SHA512ROUND0(14, 0x9bdc06a725c71235, R10, R11, R12, R13, R14, R15, R8, R9)
-	SHA512ROUND0(15, 0xc19bf174cf692694, R9, R10, R11, R12, R13, R14, R15, R8)
-
-	SHA512ROUND1(16, 0xe49b69c19ef14ad2, R8, R9, R10, R11, R12, R13, R14, R15)
-	SHA512ROUND1(17, 0xefbe4786384f25e3, R15, R8, R9, R10, R11, R12, R13, R14)
-	SHA512ROUND1(18, 0x0fc19dc68b8cd5b5, R14, R15, R8, R9, R10, R11, R12, R13)
-	SHA512ROUND1(19, 0x240ca1cc77ac9c65, R13, R14, R15, R8, R9, R10, R11, R12)
-	SHA512ROUND1(20, 0x2de92c6f592b0275, R12, R13, R14, R15, R8, R9, R10, R11)
-	SHA512ROUND1(21, 0x4a7484aa6ea6e483, R11, R12, R13, R14, R15, R8, R9, R10)
-	SHA512ROUND1(22, 0x5cb0a9dcbd41fbd4, R10, R11, R12, R13, R14, R15, R8, R9)
-	SHA512ROUND1(23, 0x76f988da831153b5, R9, R10, R11, R12, R13, R14, R15, R8)
-	SHA512ROUND1(24, 0x983e5152ee66dfab, R8, R9, R10, R11, R12, R13, R14, R15)
-	SHA512ROUND1(25, 0xa831c66d2db43210, R15, R8, R9, R10, R11, R12, R13, R14)
-	SHA512ROUND1(26, 0xb00327c898fb213f, R14, R15, R8, R9, R10, R11, R12, R13)
-	SHA512ROUND1(27, 0xbf597fc7beef0ee4, R13, R14, R15, R8, R9, R10, R11, R12)
-	SHA512ROUND1(28, 0xc6e00bf33da88fc2, R12, R13, R14, R15, R8, R9, R10, R11)
-	SHA512ROUND1(29, 0xd5a79147930aa725, R11, R12, R13, R14, R15, R8, R9, R10)
-	SHA512ROUND1(30, 0x06ca6351e003826f, R10, R11, R12, R13, R14, R15, R8, R9)
-	SHA512ROUND1(31, 0x142929670a0e6e70, R9, R10, R11, R12, R13, R14, R15, R8)
-	SHA512ROUND1(32, 0x27b70a8546d22ffc, R8, R9, R10, R11, R12, R13, R14, R15)
-	SHA512ROUND1(33, 0x2e1b21385c26c926, R15, R8, R9, R10, R11, R12, R13, R14)
-	SHA512ROUND1(34, 0x4d2c6dfc5ac42aed, R14, R15, R8, R9, R10, R11, R12, R13)
-	SHA512ROUND1(35, 0x53380d139d95b3df, R13, R14, R15, R8, R9, R10, R11, R12)
-	SHA512ROUND1(36, 0x650a73548baf63de, R12, R13, R14, R15, R8, R9, R10, R11)
-	SHA512ROUND1(37, 0x766a0abb3c77b2a8, R11, R12, R13, R14, R15, R8, R9, R10)
-	SHA512ROUND1(38, 0x81c2c92e47edaee6, R10, R11, R12, R13, R14, R15, R8, R9)
-	SHA512ROUND1(39, 0x92722c851482353b, R9, R10, R11, R12, R13, R14, R15, R8)
-	SHA512ROUND1(40, 0xa2bfe8a14cf10364, R8, R9, R10, R11, R12, R13, R14, R15)
-	SHA512ROUND1(41, 0xa81a664bbc423001, R15, R8, R9, R10, R11, R12, R13, R14)
-	SHA512ROUND1(42, 0xc24b8b70d0f89791, R14, R15, R8, R9, R10, R11, R12, R13)
-	SHA512ROUND1(43, 0xc76c51a30654be30, R13, R14, R15, R8, R9, R10, R11, R12)
-	SHA512ROUND1(44, 0xd192e819d6ef5218, R12, R13, R14, R15, R8, R9, R10, R11)
-	SHA512ROUND1(45, 0xd69906245565a910, R11, R12, R13, R14, R15, R8, R9, R10)
-	SHA512ROUND1(46, 0xf40e35855771202a, R10, R11, R12, R13, R14, R15, R8, R9)
-	SHA512ROUND1(47, 0x106aa07032bbd1b8, R9, R10, R11, R12, R13, R14, R15, R8)
-	SHA512ROUND1(48, 0x19a4c116b8d2d0c8, R8, R9, R10, R11, R12, R13, R14, R15)
-	SHA512ROUND1(49, 0x1e376c085141ab53, R15, R8, R9, R10, R11, R12, R13, R14)
-	SHA512ROUND1(50, 0x2748774cdf8eeb99, R14, R15, R8, R9, R10, R11, R12, R13)
-	SHA512ROUND1(51, 0x34b0bcb5e19b48a8, R13, R14, R15, R8, R9, R10, R11, R12)
-	SHA512ROUND1(52, 0x391c0cb3c5c95a63, R12, R13, R14, R15, R8, R9, R10, R11)
-	SHA512ROUND1(53, 0x4ed8aa4ae3418acb, R11, R12, R13, R14, R15, R8, R9, R10)
-	SHA512ROUND1(54, 0x5b9cca4f7763e373, R10, R11, R12, R13, R14, R15, R8, R9)
-	SHA512ROUND1(55, 0x682e6ff3d6b2b8a3, R9, R10, R11, R12, R13, R14, R15, R8)
-	SHA512ROUND1(56, 0x748f82ee5defb2fc, R8, R9, R10, R11, R12, R13, R14, R15)
-	SHA512ROUND1(57, 0x78a5636f43172f60, R15, R8, R9, R10, R11, R12, R13, R14)
-	SHA512ROUND1(58, 0x84c87814a1f0ab72, R14, R15, R8, R9, R10, R11, R12, R13)
-	SHA512ROUND1(59, 0x8cc702081a6439ec, R13, R14, R15, R8, R9, R10, R11, R12)
-	SHA512ROUND1(60, 0x90befffa23631e28, R12, R13, R14, R15, R8, R9, R10, R11)
-	SHA512ROUND1(61, 0xa4506cebde82bde9, R11, R12, R13, R14, R15, R8, R9, R10)
-	SHA512ROUND1(62, 0xbef9a3f7b2c67915, R10, R11, R12, R13, R14, R15, R8, R9)
-	SHA512ROUND1(63, 0xc67178f2e372532b, R9, R10, R11, R12, R13, R14, R15, R8)
-	SHA512ROUND1(64, 0xca273eceea26619c, R8, R9, R10, R11, R12, R13, R14, R15)
-	SHA512ROUND1(65, 0xd186b8c721c0c207, R15, R8, R9, R10, R11, R12, R13, R14)
-	SHA512ROUND1(66, 0xeada7dd6cde0eb1e, R14, R15, R8, R9, R10, R11, R12, R13)
-	SHA512ROUND1(67, 0xf57d4f7fee6ed178, R13, R14, R15, R8, R9, R10, R11, R12)
-	SHA512ROUND1(68, 0x06f067aa72176fba, R12, R13, R14, R15, R8, R9, R10, R11)
-	SHA512ROUND1(69, 0x0a637dc5a2c898a6, R11, R12, R13, R14, R15, R8, R9, R10)
-	SHA512ROUND1(70, 0x113f9804bef90dae, R10, R11, R12, R13, R14, R15, R8, R9)
-	SHA512ROUND1(71, 0x1b710b35131c471b, R9, R10, R11, R12, R13, R14, R15, R8)
-	SHA512ROUND1(72, 0x28db77f523047d84, R8, R9, R10, R11, R12, R13, R14, R15)
-	SHA512ROUND1(73, 0x32caab7b40c72493, R15, R8, R9, R10, R11, R12, R13, R14)
-	SHA512ROUND1(74, 0x3c9ebe0a15c9bebc, R14, R15, R8, R9, R10, R11, R12, R13)
-	SHA512ROUND1(75, 0x431d67c49c100d4c, R13, R14, R15, R8, R9, R10, R11, R12)
-	SHA512ROUND1(76, 0x4cc5d4becb3e42b6, R12, R13, R14, R15, R8, R9, R10, R11)
-	SHA512ROUND1(77, 0x597f299cfc657e2a, R11, R12, R13, R14, R15, R8, R9, R10)
-	SHA512ROUND1(78, 0x5fcb6fab3ad6faec, R10, R11, R12, R13, R14, R15, R8, R9)
-	SHA512ROUND1(79, 0x6c44198c4a475817, R9, R10, R11, R12, R13, R14, R15, R8)
-
-	MOVQ	dig+0(FP), BP
-	ADDQ	(0*8)(BP), R8	// H0 = a + H0
-	MOVQ	R8, (0*8)(BP)
-	ADDQ	(1*8)(BP), R9	// H1 = b + H1
-	MOVQ	R9, (1*8)(BP)
-	ADDQ	(2*8)(BP), R10	// H2 = c + H2
-	MOVQ	R10, (2*8)(BP)
-	ADDQ	(3*8)(BP), R11	// H3 = d + H3
-	MOVQ	R11, (3*8)(BP)
-	ADDQ	(4*8)(BP), R12	// H4 = e + H4
-	MOVQ	R12, (4*8)(BP)
-	ADDQ	(5*8)(BP), R13	// H5 = f + H5
-	MOVQ	R13, (5*8)(BP)
-	ADDQ	(6*8)(BP), R14	// H6 = g + H6
-	MOVQ	R14, (6*8)(BP)
-	ADDQ	(7*8)(BP), R15	// H7 = h + H7
-	MOVQ	R15, (7*8)(BP)
-
-	ADDQ	$128, SI
-	CMPQ	SI, 640(SP)
-	JB	loop
-
-end:
-	RET
diff --git a/src/pkg/crypto/subtle/constant_time.go b/src/pkg/crypto/subtle/constant_time.go
deleted file mode 100644
index 9c4b14a..0000000
--- a/src/pkg/crypto/subtle/constant_time.go
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package subtle implements functions that are often useful in cryptographic
-// code but require careful thought to use correctly.
-package subtle
-
-// ConstantTimeCompare returns 1 iff the two equal length slices, x
-// and y, have equal contents. The time taken is a function of the length of
-// the slices and is independent of the contents.
-func ConstantTimeCompare(x, y []byte) int {
-	if len(x) != len(y) {
-		panic("subtle: slices have different lengths")
-	}
-
-	var v byte
-
-	for i := 0; i < len(x); i++ {
-		v |= x[i] ^ y[i]
-	}
-
-	return ConstantTimeByteEq(v, 0)
-}
-
-// ConstantTimeSelect returns x if v is 1 and y if v is 0.
-// Its behavior is undefined if v takes any other value.
-func ConstantTimeSelect(v, x, y int) int { return ^(v-1)&x | (v-1)&y }
-
-// ConstantTimeByteEq returns 1 if x == y and 0 otherwise.
-func ConstantTimeByteEq(x, y uint8) int {
-	z := ^(x ^ y)
-	z &= z >> 4
-	z &= z >> 2
-	z &= z >> 1
-
-	return int(z)
-}
-
-// ConstantTimeEq returns 1 if x == y and 0 otherwise.
-func ConstantTimeEq(x, y int32) int {
-	z := ^(x ^ y)
-	z &= z >> 16
-	z &= z >> 8
-	z &= z >> 4
-	z &= z >> 2
-	z &= z >> 1
-
-	return int(z & 1)
-}
-
-// ConstantTimeCopy copies the contents of y into x (a slice of equal length)
-// if v == 1. If v == 0, x is left unchanged. Its behavior is undefined if v
-// takes any other value.
-func ConstantTimeCopy(v int, x, y []byte) {
-	if len(x) != len(y) {
-		panic("subtle: slices have different lengths")
-	}
-
-	xmask := byte(v - 1)
-	ymask := byte(^(v - 1))
-	for i := 0; i < len(x); i++ {
-		x[i] = x[i]&xmask | y[i]&ymask
-	}
-	return
-}
-
-// ConstantTimeLessOrEq returns 1 if x <= y and 0 otherwise.
-// Its behavior is undefined if x or y are negative or > 2**31 - 1.
-func ConstantTimeLessOrEq(x, y int) int {
-	x32 := int32(x)
-	y32 := int32(y)
-	return int(((x32 - y32 - 1) >> 31) & 1)
-}
diff --git a/src/pkg/crypto/subtle/constant_time_test.go b/src/pkg/crypto/subtle/constant_time_test.go
deleted file mode 100644
index d8e321e..0000000
--- a/src/pkg/crypto/subtle/constant_time_test.go
+++ /dev/null
@@ -1,125 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package subtle
-
-import (
-	"testing"
-	"testing/quick"
-)
-
-type TestConstantTimeCompareStruct struct {
-	a, b []byte
-	out  int
-}
-
-var testConstantTimeCompareData = []TestConstantTimeCompareStruct{
-	{[]byte{}, []byte{}, 1},
-	{[]byte{0x11}, []byte{0x11}, 1},
-	{[]byte{0x12}, []byte{0x11}, 0},
-}
-
-func TestConstantTimeCompare(t *testing.T) {
-	for i, test := range testConstantTimeCompareData {
-		if r := ConstantTimeCompare(test.a, test.b); r != test.out {
-			t.Errorf("#%d bad result (got %x, want %x)", i, r, test.out)
-		}
-	}
-}
-
-type TestConstantTimeByteEqStruct struct {
-	a, b uint8
-	out  int
-}
-
-var testConstandTimeByteEqData = []TestConstantTimeByteEqStruct{
-	{0, 0, 1},
-	{0, 1, 0},
-	{1, 0, 0},
-	{0xff, 0xff, 1},
-	{0xff, 0xfe, 0},
-}
-
-func byteEq(a, b uint8) int {
-	if a == b {
-		return 1
-	}
-	return 0
-}
-
-func TestConstantTimeByteEq(t *testing.T) {
-	for i, test := range testConstandTimeByteEqData {
-		if r := ConstantTimeByteEq(test.a, test.b); r != test.out {
-			t.Errorf("#%d bad result (got %x, want %x)", i, r, test.out)
-		}
-	}
-	err := quick.CheckEqual(ConstantTimeByteEq, byteEq, nil)
-	if err != nil {
-		t.Error(err)
-	}
-}
-
-func eq(a, b int32) int {
-	if a == b {
-		return 1
-	}
-	return 0
-}
-
-func TestConstantTimeEq(t *testing.T) {
-	err := quick.CheckEqual(ConstantTimeEq, eq, nil)
-	if err != nil {
-		t.Error(err)
-	}
-}
-
-func makeCopy(v int, x, y []byte) []byte {
-	if len(x) > len(y) {
-		x = x[0:len(y)]
-	} else {
-		y = y[0:len(x)]
-	}
-	if v == 1 {
-		copy(x, y)
-	}
-	return x
-}
-
-func constantTimeCopyWrapper(v int, x, y []byte) []byte {
-	if len(x) > len(y) {
-		x = x[0:len(y)]
-	} else {
-		y = y[0:len(x)]
-	}
-	v &= 1
-	ConstantTimeCopy(v, x, y)
-	return x
-}
-
-func TestConstantTimeCopy(t *testing.T) {
-	err := quick.CheckEqual(constantTimeCopyWrapper, makeCopy, nil)
-	if err != nil {
-		t.Error(err)
-	}
-}
-
-var lessOrEqTests = []struct {
-	x, y, result int
-}{
-	{0, 0, 1},
-	{1, 0, 0},
-	{0, 1, 1},
-	{10, 20, 1},
-	{20, 10, 0},
-	{10, 10, 1},
-}
-
-func TestConstantTimeLessOrEq(t *testing.T) {
-	for i, test := range lessOrEqTests {
-		result := ConstantTimeLessOrEq(test.x, test.y)
-		if result != test.result {
-			t.Errorf("#%d: %d <= %d gave %d, expected %d", i, test.x, test.y, result, test.result)
-		}
-	}
-}
diff --git a/src/pkg/crypto/tls/alert.go b/src/pkg/crypto/tls/alert.go
deleted file mode 100644
index 0856311..0000000
--- a/src/pkg/crypto/tls/alert.go
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package tls
-
-import "strconv"
-
-type alert uint8
-
-const (
-	// alert level
-	alertLevelWarning = 1
-	alertLevelError   = 2
-)
-
-const (
-	alertCloseNotify            alert = 0
-	alertUnexpectedMessage      alert = 10
-	alertBadRecordMAC           alert = 20
-	alertDecryptionFailed       alert = 21
-	alertRecordOverflow         alert = 22
-	alertDecompressionFailure   alert = 30
-	alertHandshakeFailure       alert = 40
-	alertBadCertificate         alert = 42
-	alertUnsupportedCertificate alert = 43
-	alertCertificateRevoked     alert = 44
-	alertCertificateExpired     alert = 45
-	alertCertificateUnknown     alert = 46
-	alertIllegalParameter       alert = 47
-	alertUnknownCA              alert = 48
-	alertAccessDenied           alert = 49
-	alertDecodeError            alert = 50
-	alertDecryptError           alert = 51
-	alertProtocolVersion        alert = 70
-	alertInsufficientSecurity   alert = 71
-	alertInternalError          alert = 80
-	alertUserCanceled           alert = 90
-	alertNoRenegotiation        alert = 100
-)
-
-var alertText = map[alert]string{
-	alertCloseNotify:            "close notify",
-	alertUnexpectedMessage:      "unexpected message",
-	alertBadRecordMAC:           "bad record MAC",
-	alertDecryptionFailed:       "decryption failed",
-	alertRecordOverflow:         "record overflow",
-	alertDecompressionFailure:   "decompression failure",
-	alertHandshakeFailure:       "handshake failure",
-	alertBadCertificate:         "bad certificate",
-	alertUnsupportedCertificate: "unsupported certificate",
-	alertCertificateRevoked:     "revoked certificate",
-	alertCertificateExpired:     "expired certificate",
-	alertCertificateUnknown:     "unknown certificate",
-	alertIllegalParameter:       "illegal parameter",
-	alertUnknownCA:              "unknown certificate authority",
-	alertAccessDenied:           "access denied",
-	alertDecodeError:            "error decoding message",
-	alertDecryptError:           "error decrypting message",
-	alertProtocolVersion:        "protocol version not supported",
-	alertInsufficientSecurity:   "insufficient security level",
-	alertInternalError:          "internal error",
-	alertUserCanceled:           "user canceled",
-	alertNoRenegotiation:        "no renegotiation",
-}
-
-func (e alert) String() string {
-	s, ok := alertText[e]
-	if ok {
-		return s
-	}
-	return "alert(" + strconv.Itoa(int(e)) + ")"
-}
-
-func (e alert) Error() string {
-	return e.String()
-}
diff --git a/src/pkg/crypto/tls/cipher_suites.go b/src/pkg/crypto/tls/cipher_suites.go
deleted file mode 100644
index 39a5145..0000000
--- a/src/pkg/crypto/tls/cipher_suites.go
+++ /dev/null
@@ -1,270 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package tls
-
-import (
-	"crypto/aes"
-	"crypto/cipher"
-	"crypto/des"
-	"crypto/hmac"
-	"crypto/rc4"
-	"crypto/sha1"
-	"crypto/x509"
-	"hash"
-)
-
-// a keyAgreement implements the client and server side of a TLS key agreement
-// protocol by generating and processing key exchange messages.
-type keyAgreement interface {
-	// On the server side, the first two methods are called in order.
-
-	// In the case that the key agreement protocol doesn't use a
-	// ServerKeyExchange message, generateServerKeyExchange can return nil,
-	// nil.
-	generateServerKeyExchange(*Config, *Certificate, *clientHelloMsg, *serverHelloMsg) (*serverKeyExchangeMsg, error)
-	processClientKeyExchange(*Config, *Certificate, *clientKeyExchangeMsg, uint16) ([]byte, error)
-
-	// On the client side, the next two methods are called in order.
-
-	// This method may not be called if the server doesn't send a
-	// ServerKeyExchange message.
-	processServerKeyExchange(*Config, *clientHelloMsg, *serverHelloMsg, *x509.Certificate, *serverKeyExchangeMsg) error
-	generateClientKeyExchange(*Config, *clientHelloMsg, *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error)
-}
-
-const (
-	// suiteECDH indicates that the cipher suite involves elliptic curve
-	// Diffie-Hellman. This means that it should only be selected when the
-	// client indicates that it supports ECC with a curve and point format
-	// that we're happy with.
-	suiteECDHE = 1 << iota
-	// suiteECDSA indicates that the cipher suite involves an ECDSA
-	// signature and therefore may only be selected when the server's
-	// certificate is ECDSA. If this is not set then the cipher suite is
-	// RSA based.
-	suiteECDSA
-	// suiteTLS12 indicates that the cipher suite should only be advertised
-	// and accepted when using TLS 1.2.
-	suiteTLS12
-)
-
-// A cipherSuite is a specific combination of key agreement, cipher and MAC
-// function. All cipher suites currently assume RSA key agreement.
-type cipherSuite struct {
-	id uint16
-	// the lengths, in bytes, of the key material needed for each component.
-	keyLen int
-	macLen int
-	ivLen  int
-	ka     func(version uint16) keyAgreement
-	// flags is a bitmask of the suite* values, above.
-	flags  int
-	cipher func(key, iv []byte, isRead bool) interface{}
-	mac    func(version uint16, macKey []byte) macFunction
-	aead   func(key, fixedNonce []byte) cipher.AEAD
-}
-
-var cipherSuites = []*cipherSuite{
-	// Ciphersuite order is chosen so that ECDHE comes before plain RSA
-	// and RC4 comes before AES (because of the Lucky13 attack).
-	{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, ecdheRSAKA, suiteECDHE | suiteTLS12, nil, nil, aeadAESGCM},
-	{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, ecdheECDSAKA, suiteECDHE | suiteECDSA | suiteTLS12, nil, nil, aeadAESGCM},
-	{TLS_ECDHE_RSA_WITH_RC4_128_SHA, 16, 20, 0, ecdheRSAKA, suiteECDHE, cipherRC4, macSHA1, nil},
-	{TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, 16, 20, 0, ecdheECDSAKA, suiteECDHE | suiteECDSA, cipherRC4, macSHA1, nil},
-	{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdheRSAKA, suiteECDHE, cipherAES, macSHA1, nil},
-	{TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdheECDSAKA, suiteECDHE | suiteECDSA, cipherAES, macSHA1, nil},
-	{TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdheRSAKA, suiteECDHE, cipherAES, macSHA1, nil},
-	{TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdheECDSAKA, suiteECDHE | suiteECDSA, cipherAES, macSHA1, nil},
-	{TLS_RSA_WITH_RC4_128_SHA, 16, 20, 0, rsaKA, 0, cipherRC4, macSHA1, nil},
-	{TLS_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, rsaKA, 0, cipherAES, macSHA1, nil},
-	{TLS_RSA_WITH_AES_256_CBC_SHA, 32, 20, 16, rsaKA, 0, cipherAES, macSHA1, nil},
-	{TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, ecdheRSAKA, suiteECDHE, cipher3DES, macSHA1, nil},
-	{TLS_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, rsaKA, 0, cipher3DES, macSHA1, nil},
-}
-
-func cipherRC4(key, iv []byte, isRead bool) interface{} {
-	cipher, _ := rc4.NewCipher(key)
-	return cipher
-}
-
-func cipher3DES(key, iv []byte, isRead bool) interface{} {
-	block, _ := des.NewTripleDESCipher(key)
-	if isRead {
-		return cipher.NewCBCDecrypter(block, iv)
-	}
-	return cipher.NewCBCEncrypter(block, iv)
-}
-
-func cipherAES(key, iv []byte, isRead bool) interface{} {
-	block, _ := aes.NewCipher(key)
-	if isRead {
-		return cipher.NewCBCDecrypter(block, iv)
-	}
-	return cipher.NewCBCEncrypter(block, iv)
-}
-
-// macSHA1 returns a macFunction for the given protocol version.
-func macSHA1(version uint16, key []byte) macFunction {
-	if version == VersionSSL30 {
-		mac := ssl30MAC{
-			h:   sha1.New(),
-			key: make([]byte, len(key)),
-		}
-		copy(mac.key, key)
-		return mac
-	}
-	return tls10MAC{hmac.New(sha1.New, key)}
-}
-
-type macFunction interface {
-	Size() int
-	MAC(digestBuf, seq, header, data []byte) []byte
-}
-
-// fixedNonceAEAD wraps an AEAD and prefixes a fixed portion of the nonce to
-// each call.
-type fixedNonceAEAD struct {
-	// sealNonce and openNonce are buffers where the larger nonce will be
-	// constructed. Since a seal and open operation may be running
-	// concurrently, there is a separate buffer for each.
-	sealNonce, openNonce []byte
-	aead                 cipher.AEAD
-}
-
-func (f *fixedNonceAEAD) NonceSize() int { return 8 }
-func (f *fixedNonceAEAD) Overhead() int  { return f.aead.Overhead() }
-
-func (f *fixedNonceAEAD) Seal(out, nonce, plaintext, additionalData []byte) []byte {
-	copy(f.sealNonce[len(f.sealNonce)-8:], nonce)
-	return f.aead.Seal(out, f.sealNonce, plaintext, additionalData)
-}
-
-func (f *fixedNonceAEAD) Open(out, nonce, plaintext, additionalData []byte) ([]byte, error) {
-	copy(f.openNonce[len(f.openNonce)-8:], nonce)
-	return f.aead.Open(out, f.openNonce, plaintext, additionalData)
-}
-
-func aeadAESGCM(key, fixedNonce []byte) cipher.AEAD {
-	aes, err := aes.NewCipher(key)
-	if err != nil {
-		panic(err)
-	}
-	aead, err := cipher.NewGCM(aes)
-	if err != nil {
-		panic(err)
-	}
-
-	nonce1, nonce2 := make([]byte, 12), make([]byte, 12)
-	copy(nonce1, fixedNonce)
-	copy(nonce2, fixedNonce)
-
-	return &fixedNonceAEAD{nonce1, nonce2, aead}
-}
-
-// ssl30MAC implements the SSLv3 MAC function, as defined in
-// www.mozilla.org/projects/security/pki/nss/ssl/draft302.txt section 5.2.3.1
-type ssl30MAC struct {
-	h   hash.Hash
-	key []byte
-}
-
-func (s ssl30MAC) Size() int {
-	return s.h.Size()
-}
-
-var ssl30Pad1 = [48]byte{0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36}
-
-var ssl30Pad2 = [48]byte{0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c}
-
-func (s ssl30MAC) MAC(digestBuf, seq, header, data []byte) []byte {
-	padLength := 48
-	if s.h.Size() == 20 {
-		padLength = 40
-	}
-
-	s.h.Reset()
-	s.h.Write(s.key)
-	s.h.Write(ssl30Pad1[:padLength])
-	s.h.Write(seq)
-	s.h.Write(header[:1])
-	s.h.Write(header[3:5])
-	s.h.Write(data)
-	digestBuf = s.h.Sum(digestBuf[:0])
-
-	s.h.Reset()
-	s.h.Write(s.key)
-	s.h.Write(ssl30Pad2[:padLength])
-	s.h.Write(digestBuf)
-	return s.h.Sum(digestBuf[:0])
-}
-
-// tls10MAC implements the TLS 1.0 MAC function. RFC 2246, section 6.2.3.
-type tls10MAC struct {
-	h hash.Hash
-}
-
-func (s tls10MAC) Size() int {
-	return s.h.Size()
-}
-
-func (s tls10MAC) MAC(digestBuf, seq, header, data []byte) []byte {
-	s.h.Reset()
-	s.h.Write(seq)
-	s.h.Write(header)
-	s.h.Write(data)
-	return s.h.Sum(digestBuf[:0])
-}
-
-func rsaKA(version uint16) keyAgreement {
-	return rsaKeyAgreement{}
-}
-
-func ecdheECDSAKA(version uint16) keyAgreement {
-	return &ecdheKeyAgreement{
-		sigType: signatureECDSA,
-		version: version,
-	}
-}
-
-func ecdheRSAKA(version uint16) keyAgreement {
-	return &ecdheKeyAgreement{
-		sigType: signatureRSA,
-		version: version,
-	}
-}
-
-// mutualCipherSuite returns a cipherSuite given a list of supported
-// ciphersuites and the id requested by the peer.
-func mutualCipherSuite(have []uint16, want uint16) *cipherSuite {
-	for _, id := range have {
-		if id == want {
-			for _, suite := range cipherSuites {
-				if suite.id == want {
-					return suite
-				}
-			}
-			return nil
-		}
-	}
-	return nil
-}
-
-// A list of the possible cipher suite ids. Taken from
-// http://www.iana.org/assignments/tls-parameters/tls-parameters.xml
-const (
-	TLS_RSA_WITH_RC4_128_SHA                uint16 = 0x0005
-	TLS_RSA_WITH_3DES_EDE_CBC_SHA           uint16 = 0x000a
-	TLS_RSA_WITH_AES_128_CBC_SHA            uint16 = 0x002f
-	TLS_RSA_WITH_AES_256_CBC_SHA            uint16 = 0x0035
-	TLS_ECDHE_ECDSA_WITH_RC4_128_SHA        uint16 = 0xc007
-	TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA    uint16 = 0xc009
-	TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA    uint16 = 0xc00a
-	TLS_ECDHE_RSA_WITH_RC4_128_SHA          uint16 = 0xc011
-	TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA     uint16 = 0xc012
-	TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA      uint16 = 0xc013
-	TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA      uint16 = 0xc014
-	TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256   uint16 = 0xc02f
-	TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 uint16 = 0xc02b
-)
diff --git a/src/pkg/crypto/tls/common.go b/src/pkg/crypto/tls/common.go
deleted file mode 100644
index fca98bd..0000000
--- a/src/pkg/crypto/tls/common.go
+++ /dev/null
@@ -1,568 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package tls
-
-import (
-	"container/list"
-	"crypto"
-	"crypto/rand"
-	"crypto/x509"
-	"fmt"
-	"io"
-	"math/big"
-	"strings"
-	"sync"
-	"time"
-)
-
-const (
-	VersionSSL30 = 0x0300
-	VersionTLS10 = 0x0301
-	VersionTLS11 = 0x0302
-	VersionTLS12 = 0x0303
-)
-
-const (
-	maxPlaintext    = 16384        // maximum plaintext payload length
-	maxCiphertext   = 16384 + 2048 // maximum ciphertext payload length
-	recordHeaderLen = 5            // record header length
-	maxHandshake    = 65536        // maximum handshake we support (protocol max is 16 MB)
-
-	minVersion = VersionSSL30
-	maxVersion = VersionTLS12
-)
-
-// TLS record types.
-type recordType uint8
-
-const (
-	recordTypeChangeCipherSpec recordType = 20
-	recordTypeAlert            recordType = 21
-	recordTypeHandshake        recordType = 22
-	recordTypeApplicationData  recordType = 23
-)
-
-// TLS handshake message types.
-const (
-	typeClientHello        uint8 = 1
-	typeServerHello        uint8 = 2
-	typeNewSessionTicket   uint8 = 4
-	typeCertificate        uint8 = 11
-	typeServerKeyExchange  uint8 = 12
-	typeCertificateRequest uint8 = 13
-	typeServerHelloDone    uint8 = 14
-	typeCertificateVerify  uint8 = 15
-	typeClientKeyExchange  uint8 = 16
-	typeFinished           uint8 = 20
-	typeCertificateStatus  uint8 = 22
-	typeNextProtocol       uint8 = 67 // Not IANA assigned
-)
-
-// TLS compression types.
-const (
-	compressionNone uint8 = 0
-)
-
-// TLS extension numbers
-const (
-	extensionServerName          uint16 = 0
-	extensionStatusRequest       uint16 = 5
-	extensionSupportedCurves     uint16 = 10
-	extensionSupportedPoints     uint16 = 11
-	extensionSignatureAlgorithms uint16 = 13
-	extensionSessionTicket       uint16 = 35
-	extensionNextProtoNeg        uint16 = 13172 // not IANA assigned
-	extensionRenegotiationInfo   uint16 = 0xff01
-)
-
-// TLS signaling cipher suite values
-const (
-	scsvRenegotiation uint16 = 0x00ff
-)
-
-// CurveID is the type of a TLS identifier for an elliptic curve. See
-// http://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-8
-type CurveID uint16
-
-const (
-	CurveP256 CurveID = 23
-	CurveP384 CurveID = 24
-	CurveP521 CurveID = 25
-)
-
-// TLS Elliptic Curve Point Formats
-// http://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-9
-const (
-	pointFormatUncompressed uint8 = 0
-)
-
-// TLS CertificateStatusType (RFC 3546)
-const (
-	statusTypeOCSP uint8 = 1
-)
-
-// Certificate types (for certificateRequestMsg)
-const (
-	certTypeRSASign    = 1 // A certificate containing an RSA key
-	certTypeDSSSign    = 2 // A certificate containing a DSA key
-	certTypeRSAFixedDH = 3 // A certificate containing a static DH key
-	certTypeDSSFixedDH = 4 // A certificate containing a static DH key
-
-	// See RFC4492 sections 3 and 5.5.
-	certTypeECDSASign      = 64 // A certificate containing an ECDSA-capable public key, signed with ECDSA.
-	certTypeRSAFixedECDH   = 65 // A certificate containing an ECDH-capable public key, signed with RSA.
-	certTypeECDSAFixedECDH = 66 // A certificate containing an ECDH-capable public key, signed with ECDSA.
-
-	// Rest of these are reserved by the TLS spec
-)
-
-// Hash functions for TLS 1.2 (See RFC 5246, section A.4.1)
-const (
-	hashSHA1   uint8 = 2
-	hashSHA256 uint8 = 4
-)
-
-// Signature algorithms for TLS 1.2 (See RFC 5246, section A.4.1)
-const (
-	signatureRSA   uint8 = 1
-	signatureECDSA uint8 = 3
-)
-
-// signatureAndHash mirrors the TLS 1.2, SignatureAndHashAlgorithm struct. See
-// RFC 5246, section A.4.1.
-type signatureAndHash struct {
-	hash, signature uint8
-}
-
-// supportedSKXSignatureAlgorithms contains the signature and hash algorithms
-// that the code advertises as supported in a TLS 1.2 ClientHello.
-var supportedSKXSignatureAlgorithms = []signatureAndHash{
-	{hashSHA256, signatureRSA},
-	{hashSHA256, signatureECDSA},
-	{hashSHA1, signatureRSA},
-	{hashSHA1, signatureECDSA},
-}
-
-// supportedClientCertSignatureAlgorithms contains the signature and hash
-// algorithms that the code advertises as supported in a TLS 1.2
-// CertificateRequest.
-var supportedClientCertSignatureAlgorithms = []signatureAndHash{
-	{hashSHA256, signatureRSA},
-	{hashSHA256, signatureECDSA},
-}
-
-// ConnectionState records basic TLS details about the connection.
-type ConnectionState struct {
-	Version                    uint16                // TLS version used by the connection (e.g. VersionTLS12)
-	HandshakeComplete          bool                  // TLS handshake is complete
-	DidResume                  bool                  // connection resumes a previous TLS connection
-	CipherSuite                uint16                // cipher suite in use (TLS_RSA_WITH_RC4_128_SHA, ...)
-	NegotiatedProtocol         string                // negotiated next protocol (from Config.NextProtos)
-	NegotiatedProtocolIsMutual bool                  // negotiated protocol was advertised by server
-	ServerName                 string                // server name requested by client, if any (server side only)
-	PeerCertificates           []*x509.Certificate   // certificate chain presented by remote peer
-	VerifiedChains             [][]*x509.Certificate // verified chains built from PeerCertificates
-}
-
-// ClientAuthType declares the policy the server will follow for
-// TLS Client Authentication.
-type ClientAuthType int
-
-const (
-	NoClientCert ClientAuthType = iota
-	RequestClientCert
-	RequireAnyClientCert
-	VerifyClientCertIfGiven
-	RequireAndVerifyClientCert
-)
-
-// ClientSessionState contains the state needed by clients to resume TLS
-// sessions.
-type ClientSessionState struct {
-	sessionTicket      []uint8             // Encrypted ticket used for session resumption with server
-	vers               uint16              // SSL/TLS version negotiated for the session
-	cipherSuite        uint16              // Ciphersuite negotiated for the session
-	masterSecret       []byte              // MasterSecret generated by client on a full handshake
-	serverCertificates []*x509.Certificate // Certificate chain presented by the server
-}
-
-// ClientSessionCache is a cache of ClientSessionState objects that can be used
-// by a client to resume a TLS session with a given server. ClientSessionCache
-// implementations should expect to be called concurrently from different
-// goroutines.
-type ClientSessionCache interface {
-	// Get searches for a ClientSessionState associated with the given key.
-	// On return, ok is true if one was found.
-	Get(sessionKey string) (session *ClientSessionState, ok bool)
-
-	// Put adds the ClientSessionState to the cache with the given key.
-	Put(sessionKey string, cs *ClientSessionState)
-}
-
-// A Config structure is used to configure a TLS client or server.
-// After one has been passed to a TLS function it must not be
-// modified. A Config may be reused; the tls package will also not
-// modify it.
-type Config struct {
-	// Rand provides the source of entropy for nonces and RSA blinding.
-	// If Rand is nil, TLS uses the cryptographic random reader in package
-	// crypto/rand.
-	// The Reader must be safe for use by multiple goroutines.
-	Rand io.Reader
-
-	// Time returns the current time as the number of seconds since the epoch.
-	// If Time is nil, TLS uses time.Now.
-	Time func() time.Time
-
-	// Certificates contains one or more certificate chains
-	// to present to the other side of the connection.
-	// Server configurations must include at least one certificate.
-	Certificates []Certificate
-
-	// NameToCertificate maps from a certificate name to an element of
-	// Certificates. Note that a certificate name can be of the form
-	// '*.example.com' and so doesn't have to be a domain name as such.
-	// See Config.BuildNameToCertificate
-	// The nil value causes the first element of Certificates to be used
-	// for all connections.
-	NameToCertificate map[string]*Certificate
-
-	// RootCAs defines the set of root certificate authorities
-	// that clients use when verifying server certificates.
-	// If RootCAs is nil, TLS uses the host's root CA set.
-	RootCAs *x509.CertPool
-
-	// NextProtos is a list of supported, application level protocols.
-	NextProtos []string
-
-	// ServerName is used to verify the hostname on the returned
-	// certificates unless InsecureSkipVerify is given. It is also included
-	// in the client's handshake to support virtual hosting.
-	ServerName string
-
-	// ClientAuth determines the server's policy for
-	// TLS Client Authentication. The default is NoClientCert.
-	ClientAuth ClientAuthType
-
-	// ClientCAs defines the set of root certificate authorities
-	// that servers use if required to verify a client certificate
-	// by the policy in ClientAuth.
-	ClientCAs *x509.CertPool
-
-	// InsecureSkipVerify controls whether a client verifies the
-	// server's certificate chain and host name.
-	// If InsecureSkipVerify is true, TLS accepts any certificate
-	// presented by the server and any host name in that certificate.
-	// In this mode, TLS is susceptible to man-in-the-middle attacks.
-	// This should be used only for testing.
-	InsecureSkipVerify bool
-
-	// CipherSuites is a list of supported cipher suites. If CipherSuites
-	// is nil, TLS uses a list of suites supported by the implementation.
-	CipherSuites []uint16
-
-	// PreferServerCipherSuites controls whether the server selects the
-	// client's most preferred ciphersuite, or the server's most preferred
-	// ciphersuite. If true then the server's preference, as expressed in
-	// the order of elements in CipherSuites, is used.
-	PreferServerCipherSuites bool
-
-	// SessionTicketsDisabled may be set to true to disable session ticket
-	// (resumption) support.
-	SessionTicketsDisabled bool
-
-	// SessionTicketKey is used by TLS servers to provide session
-	// resumption. See RFC 5077. If zero, it will be filled with
-	// random data before the first server handshake.
-	//
-	// If multiple servers are terminating connections for the same host
-	// they should all have the same SessionTicketKey. If the
-	// SessionTicketKey leaks, previously recorded and future TLS
-	// connections using that key are compromised.
-	SessionTicketKey [32]byte
-
-	// SessionCache is a cache of ClientSessionState entries for TLS session
-	// resumption.
-	ClientSessionCache ClientSessionCache
-
-	// MinVersion contains the minimum SSL/TLS version that is acceptable.
-	// If zero, then SSLv3 is taken as the minimum.
-	MinVersion uint16
-
-	// MaxVersion contains the maximum SSL/TLS version that is acceptable.
-	// If zero, then the maximum version supported by this package is used,
-	// which is currently TLS 1.2.
-	MaxVersion uint16
-
-	// CurvePreferences contains the elliptic curves that will be used in
-	// an ECDHE handshake, in preference order. If empty, the default will
-	// be used.
-	CurvePreferences []CurveID
-
-	serverInitOnce sync.Once // guards calling (*Config).serverInit
-}
-
-func (c *Config) serverInit() {
-	if c.SessionTicketsDisabled {
-		return
-	}
-
-	// If the key has already been set then we have nothing to do.
-	for _, b := range c.SessionTicketKey {
-		if b != 0 {
-			return
-		}
-	}
-
-	if _, err := io.ReadFull(c.rand(), c.SessionTicketKey[:]); err != nil {
-		c.SessionTicketsDisabled = true
-	}
-}
-
-func (c *Config) rand() io.Reader {
-	r := c.Rand
-	if r == nil {
-		return rand.Reader
-	}
-	return r
-}
-
-func (c *Config) time() time.Time {
-	t := c.Time
-	if t == nil {
-		t = time.Now
-	}
-	return t()
-}
-
-func (c *Config) cipherSuites() []uint16 {
-	s := c.CipherSuites
-	if s == nil {
-		s = defaultCipherSuites()
-	}
-	return s
-}
-
-func (c *Config) minVersion() uint16 {
-	if c == nil || c.MinVersion == 0 {
-		return minVersion
-	}
-	return c.MinVersion
-}
-
-func (c *Config) maxVersion() uint16 {
-	if c == nil || c.MaxVersion == 0 {
-		return maxVersion
-	}
-	return c.MaxVersion
-}
-
-var defaultCurvePreferences = []CurveID{CurveP256, CurveP384, CurveP521}
-
-func (c *Config) curvePreferences() []CurveID {
-	if c == nil || len(c.CurvePreferences) == 0 {
-		return defaultCurvePreferences
-	}
-	return c.CurvePreferences
-}
-
-// mutualVersion returns the protocol version to use given the advertised
-// version of the peer.
-func (c *Config) mutualVersion(vers uint16) (uint16, bool) {
-	minVersion := c.minVersion()
-	maxVersion := c.maxVersion()
-
-	if vers < minVersion {
-		return 0, false
-	}
-	if vers > maxVersion {
-		vers = maxVersion
-	}
-	return vers, true
-}
-
-// getCertificateForName returns the best certificate for the given name,
-// defaulting to the first element of c.Certificates if there are no good
-// options.
-func (c *Config) getCertificateForName(name string) *Certificate {
-	if len(c.Certificates) == 1 || c.NameToCertificate == nil {
-		// There's only one choice, so no point doing any work.
-		return &c.Certificates[0]
-	}
-
-	name = strings.ToLower(name)
-	for len(name) > 0 && name[len(name)-1] == '.' {
-		name = name[:len(name)-1]
-	}
-
-	if cert, ok := c.NameToCertificate[name]; ok {
-		return cert
-	}
-
-	// try replacing labels in the name with wildcards until we get a
-	// match.
-	labels := strings.Split(name, ".")
-	for i := range labels {
-		labels[i] = "*"
-		candidate := strings.Join(labels, ".")
-		if cert, ok := c.NameToCertificate[candidate]; ok {
-			return cert
-		}
-	}
-
-	// If nothing matches, return the first certificate.
-	return &c.Certificates[0]
-}
-
-// BuildNameToCertificate parses c.Certificates and builds c.NameToCertificate
-// from the CommonName and SubjectAlternateName fields of each of the leaf
-// certificates.
-func (c *Config) BuildNameToCertificate() {
-	c.NameToCertificate = make(map[string]*Certificate)
-	for i := range c.Certificates {
-		cert := &c.Certificates[i]
-		x509Cert, err := x509.ParseCertificate(cert.Certificate[0])
-		if err != nil {
-			continue
-		}
-		if len(x509Cert.Subject.CommonName) > 0 {
-			c.NameToCertificate[x509Cert.Subject.CommonName] = cert
-		}
-		for _, san := range x509Cert.DNSNames {
-			c.NameToCertificate[san] = cert
-		}
-	}
-}
-
-// A Certificate is a chain of one or more certificates, leaf first.
-type Certificate struct {
-	Certificate [][]byte
-	PrivateKey  crypto.PrivateKey // supported types: *rsa.PrivateKey, *ecdsa.PrivateKey
-	// OCSPStaple contains an optional OCSP response which will be served
-	// to clients that request it.
-	OCSPStaple []byte
-	// Leaf is the parsed form of the leaf certificate, which may be
-	// initialized using x509.ParseCertificate to reduce per-handshake
-	// processing for TLS clients doing client authentication. If nil, the
-	// leaf certificate will be parsed as needed.
-	Leaf *x509.Certificate
-}
-
-// A TLS record.
-type record struct {
-	contentType  recordType
-	major, minor uint8
-	payload      []byte
-}
-
-type handshakeMessage interface {
-	marshal() []byte
-	unmarshal([]byte) bool
-}
-
-// lruSessionCache is a ClientSessionCache implementation that uses an LRU
-// caching strategy.
-type lruSessionCache struct {
-	sync.Mutex
-
-	m        map[string]*list.Element
-	q        *list.List
-	capacity int
-}
-
-type lruSessionCacheEntry struct {
-	sessionKey string
-	state      *ClientSessionState
-}
-
-// NewLRUClientSessionCache returns a ClientSessionCache with the given
-// capacity that uses an LRU strategy. If capacity is < 1, a default capacity
-// is used instead.
-func NewLRUClientSessionCache(capacity int) ClientSessionCache {
-	const defaultSessionCacheCapacity = 64
-
-	if capacity < 1 {
-		capacity = defaultSessionCacheCapacity
-	}
-	return &lruSessionCache{
-		m:        make(map[string]*list.Element),
-		q:        list.New(),
-		capacity: capacity,
-	}
-}
-
-// Put adds the provided (sessionKey, cs) pair to the cache.
-func (c *lruSessionCache) Put(sessionKey string, cs *ClientSessionState) {
-	c.Lock()
-	defer c.Unlock()
-
-	if elem, ok := c.m[sessionKey]; ok {
-		entry := elem.Value.(*lruSessionCacheEntry)
-		entry.state = cs
-		c.q.MoveToFront(elem)
-		return
-	}
-
-	if c.q.Len() < c.capacity {
-		entry := &lruSessionCacheEntry{sessionKey, cs}
-		c.m[sessionKey] = c.q.PushFront(entry)
-		return
-	}
-
-	elem := c.q.Back()
-	entry := elem.Value.(*lruSessionCacheEntry)
-	delete(c.m, entry.sessionKey)
-	entry.sessionKey = sessionKey
-	entry.state = cs
-	c.q.MoveToFront(elem)
-	c.m[sessionKey] = elem
-}
-
-// Get returns the ClientSessionState value associated with a given key. It
-// returns (nil, false) if no value is found.
-func (c *lruSessionCache) Get(sessionKey string) (*ClientSessionState, bool) {
-	c.Lock()
-	defer c.Unlock()
-
-	if elem, ok := c.m[sessionKey]; ok {
-		c.q.MoveToFront(elem)
-		return elem.Value.(*lruSessionCacheEntry).state, true
-	}
-	return nil, false
-}
-
-// TODO(jsing): Make these available to both crypto/x509 and crypto/tls.
-type dsaSignature struct {
-	R, S *big.Int
-}
-
-type ecdsaSignature dsaSignature
-
-var emptyConfig Config
-
-func defaultConfig() *Config {
-	return &emptyConfig
-}
-
-var (
-	once                   sync.Once
-	varDefaultCipherSuites []uint16
-)
-
-func defaultCipherSuites() []uint16 {
-	once.Do(initDefaultCipherSuites)
-	return varDefaultCipherSuites
-}
-
-func initDefaultCipherSuites() {
-	varDefaultCipherSuites = make([]uint16, len(cipherSuites))
-	for i, suite := range cipherSuites {
-		varDefaultCipherSuites[i] = suite.id
-	}
-}
-
-func unexpectedMessageError(wanted, got interface{}) error {
-	return fmt.Errorf("tls: received unexpected handshake message of type %T when waiting for %T", got, wanted)
-}
diff --git a/src/pkg/crypto/tls/conn.go b/src/pkg/crypto/tls/conn.go
deleted file mode 100644
index 8f7d2c1..0000000
--- a/src/pkg/crypto/tls/conn.go
+++ /dev/null
@@ -1,1024 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// TLS low level connection and record layer
-
-package tls
-
-import (
-	"bytes"
-	"crypto/cipher"
-	"crypto/subtle"
-	"crypto/x509"
-	"errors"
-	"fmt"
-	"io"
-	"net"
-	"sync"
-	"time"
-)
-
-// A Conn represents a secured connection.
-// It implements the net.Conn interface.
-type Conn struct {
-	// constant
-	conn     net.Conn
-	isClient bool
-
-	// constant after handshake; protected by handshakeMutex
-	handshakeMutex    sync.Mutex // handshakeMutex < in.Mutex, out.Mutex, errMutex
-	handshakeErr      error      // error resulting from handshake
-	vers              uint16     // TLS version
-	haveVers          bool       // version has been negotiated
-	config            *Config    // configuration passed to constructor
-	handshakeComplete bool
-	didResume         bool // whether this connection was a session resumption
-	cipherSuite       uint16
-	ocspResponse      []byte // stapled OCSP response
-	peerCertificates  []*x509.Certificate
-	// verifiedChains contains the certificate chains that we built, as
-	// opposed to the ones presented by the server.
-	verifiedChains [][]*x509.Certificate
-	// serverName contains the server name indicated by the client, if any.
-	serverName string
-
-	clientProtocol         string
-	clientProtocolFallback bool
-
-	// input/output
-	in, out  halfConn     // in.Mutex < out.Mutex
-	rawInput *block       // raw input, right off the wire
-	input    *block       // application data waiting to be read
-	hand     bytes.Buffer // handshake data waiting to be read
-
-	tmp [16]byte
-}
-
-// Access to net.Conn methods.
-// Cannot just embed net.Conn because that would
-// export the struct field too.
-
-// LocalAddr returns the local network address.
-func (c *Conn) LocalAddr() net.Addr {
-	return c.conn.LocalAddr()
-}
-
-// RemoteAddr returns the remote network address.
-func (c *Conn) RemoteAddr() net.Addr {
-	return c.conn.RemoteAddr()
-}
-
-// SetDeadline sets the read and write deadlines associated with the connection.
-// A zero value for t means Read and Write will not time out.
-// After a Write has timed out, the TLS state is corrupt and all future writes will return the same error.
-func (c *Conn) SetDeadline(t time.Time) error {
-	return c.conn.SetDeadline(t)
-}
-
-// SetReadDeadline sets the read deadline on the underlying connection.
-// A zero value for t means Read will not time out.
-func (c *Conn) SetReadDeadline(t time.Time) error {
-	return c.conn.SetReadDeadline(t)
-}
-
-// SetWriteDeadline sets the write deadline on the underlying connection.
-// A zero value for t means Write will not time out.
-// After a Write has timed out, the TLS state is corrupt and all future writes will return the same error.
-func (c *Conn) SetWriteDeadline(t time.Time) error {
-	return c.conn.SetWriteDeadline(t)
-}
-
-// A halfConn represents one direction of the record layer
-// connection, either sending or receiving.
-type halfConn struct {
-	sync.Mutex
-
-	err     error       // first permanent error
-	version uint16      // protocol version
-	cipher  interface{} // cipher algorithm
-	mac     macFunction
-	seq     [8]byte // 64-bit sequence number
-	bfree   *block  // list of free blocks
-
-	nextCipher interface{} // next encryption state
-	nextMac    macFunction // next MAC algorithm
-
-	// used to save allocating a new buffer for each MAC.
-	inDigestBuf, outDigestBuf []byte
-}
-
-func (hc *halfConn) setErrorLocked(err error) error {
-	hc.err = err
-	return err
-}
-
-func (hc *halfConn) error() error {
-	hc.Lock()
-	err := hc.err
-	hc.Unlock()
-	return err
-}
-
-// prepareCipherSpec sets the encryption and MAC states
-// that a subsequent changeCipherSpec will use.
-func (hc *halfConn) prepareCipherSpec(version uint16, cipher interface{}, mac macFunction) {
-	hc.version = version
-	hc.nextCipher = cipher
-	hc.nextMac = mac
-}
-
-// changeCipherSpec changes the encryption and MAC states
-// to the ones previously passed to prepareCipherSpec.
-func (hc *halfConn) changeCipherSpec() error {
-	if hc.nextCipher == nil {
-		return alertInternalError
-	}
-	hc.cipher = hc.nextCipher
-	hc.mac = hc.nextMac
-	hc.nextCipher = nil
-	hc.nextMac = nil
-	for i := range hc.seq {
-		hc.seq[i] = 0
-	}
-	return nil
-}
-
-// incSeq increments the sequence number.
-func (hc *halfConn) incSeq() {
-	for i := 7; i >= 0; i-- {
-		hc.seq[i]++
-		if hc.seq[i] != 0 {
-			return
-		}
-	}
-
-	// Not allowed to let sequence number wrap.
-	// Instead, must renegotiate before it does.
-	// Not likely enough to bother.
-	panic("TLS: sequence number wraparound")
-}
-
-// resetSeq resets the sequence number to zero.
-func (hc *halfConn) resetSeq() {
-	for i := range hc.seq {
-		hc.seq[i] = 0
-	}
-}
-
-// removePadding returns an unpadded slice, in constant time, which is a prefix
-// of the input. It also returns a byte which is equal to 255 if the padding
-// was valid and 0 otherwise. See RFC 2246, section 6.2.3.2
-func removePadding(payload []byte) ([]byte, byte) {
-	if len(payload) < 1 {
-		return payload, 0
-	}
-
-	paddingLen := payload[len(payload)-1]
-	t := uint(len(payload)-1) - uint(paddingLen)
-	// if len(payload) >= (paddingLen - 1) then the MSB of t is zero
-	good := byte(int32(^t) >> 31)
-
-	toCheck := 255 // the maximum possible padding length
-	// The length of the padded data is public, so we can use an if here
-	if toCheck+1 > len(payload) {
-		toCheck = len(payload) - 1
-	}
-
-	for i := 0; i < toCheck; i++ {
-		t := uint(paddingLen) - uint(i)
-		// if i <= paddingLen then the MSB of t is zero
-		mask := byte(int32(^t) >> 31)
-		b := payload[len(payload)-1-i]
-		good &^= mask&paddingLen ^ mask&b
-	}
-
-	// We AND together the bits of good and replicate the result across
-	// all the bits.
-	good &= good << 4
-	good &= good << 2
-	good &= good << 1
-	good = uint8(int8(good) >> 7)
-
-	toRemove := good&paddingLen + 1
-	return payload[:len(payload)-int(toRemove)], good
-}
-
-// removePaddingSSL30 is a replacement for removePadding in the case that the
-// protocol version is SSLv3. In this version, the contents of the padding
-// are random and cannot be checked.
-func removePaddingSSL30(payload []byte) ([]byte, byte) {
-	if len(payload) < 1 {
-		return payload, 0
-	}
-
-	paddingLen := int(payload[len(payload)-1]) + 1
-	if paddingLen > len(payload) {
-		return payload, 0
-	}
-
-	return payload[:len(payload)-paddingLen], 255
-}
-
-func roundUp(a, b int) int {
-	return a + (b-a%b)%b
-}
-
-// cbcMode is an interface for block ciphers using cipher block chaining.
-type cbcMode interface {
-	cipher.BlockMode
-	SetIV([]byte)
-}
-
-// decrypt checks and strips the mac and decrypts the data in b. Returns a
-// success boolean, the number of bytes to skip from the start of the record in
-// order to get the application payload, and an optional alert value.
-func (hc *halfConn) decrypt(b *block) (ok bool, prefixLen int, alertValue alert) {
-	// pull out payload
-	payload := b.data[recordHeaderLen:]
-
-	macSize := 0
-	if hc.mac != nil {
-		macSize = hc.mac.Size()
-	}
-
-	paddingGood := byte(255)
-	explicitIVLen := 0
-
-	// decrypt
-	if hc.cipher != nil {
-		switch c := hc.cipher.(type) {
-		case cipher.Stream:
-			c.XORKeyStream(payload, payload)
-		case cipher.AEAD:
-			explicitIVLen = 8
-			if len(payload) < explicitIVLen {
-				return false, 0, alertBadRecordMAC
-			}
-			nonce := payload[:8]
-			payload = payload[8:]
-
-			var additionalData [13]byte
-			copy(additionalData[:], hc.seq[:])
-			copy(additionalData[8:], b.data[:3])
-			n := len(payload) - c.Overhead()
-			additionalData[11] = byte(n >> 8)
-			additionalData[12] = byte(n)
-			var err error
-			payload, err = c.Open(payload[:0], nonce, payload, additionalData[:])
-			if err != nil {
-				return false, 0, alertBadRecordMAC
-			}
-			b.resize(recordHeaderLen + explicitIVLen + len(payload))
-		case cbcMode:
-			blockSize := c.BlockSize()
-			if hc.version >= VersionTLS11 {
-				explicitIVLen = blockSize
-			}
-
-			if len(payload)%blockSize != 0 || len(payload) < roundUp(explicitIVLen+macSize+1, blockSize) {
-				return false, 0, alertBadRecordMAC
-			}
-
-			if explicitIVLen > 0 {
-				c.SetIV(payload[:explicitIVLen])
-				payload = payload[explicitIVLen:]
-			}
-			c.CryptBlocks(payload, payload)
-			if hc.version == VersionSSL30 {
-				payload, paddingGood = removePaddingSSL30(payload)
-			} else {
-				payload, paddingGood = removePadding(payload)
-			}
-			b.resize(recordHeaderLen + explicitIVLen + len(payload))
-
-			// note that we still have a timing side-channel in the
-			// MAC check, below. An attacker can align the record
-			// so that a correct padding will cause one less hash
-			// block to be calculated. Then they can iteratively
-			// decrypt a record by breaking each byte. See
-			// "Password Interception in a SSL/TLS Channel", Brice
-			// Canvel et al.
-			//
-			// However, our behavior matches OpenSSL, so we leak
-			// only as much as they do.
-		default:
-			panic("unknown cipher type")
-		}
-	}
-
-	// check, strip mac
-	if hc.mac != nil {
-		if len(payload) < macSize {
-			return false, 0, alertBadRecordMAC
-		}
-
-		// strip mac off payload, b.data
-		n := len(payload) - macSize
-		b.data[3] = byte(n >> 8)
-		b.data[4] = byte(n)
-		b.resize(recordHeaderLen + explicitIVLen + n)
-		remoteMAC := payload[n:]
-		localMAC := hc.mac.MAC(hc.inDigestBuf, hc.seq[0:], b.data[:recordHeaderLen], payload[:n])
-
-		if subtle.ConstantTimeCompare(localMAC, remoteMAC) != 1 || paddingGood != 255 {
-			return false, 0, alertBadRecordMAC
-		}
-		hc.inDigestBuf = localMAC
-	}
-	hc.incSeq()
-
-	return true, recordHeaderLen + explicitIVLen, 0
-}
-
-// padToBlockSize calculates the needed padding block, if any, for a payload.
-// On exit, prefix aliases payload and extends to the end of the last full
-// block of payload. finalBlock is a fresh slice which contains the contents of
-// any suffix of payload as well as the needed padding to make finalBlock a
-// full block.
-func padToBlockSize(payload []byte, blockSize int) (prefix, finalBlock []byte) {
-	overrun := len(payload) % blockSize
-	paddingLen := blockSize - overrun
-	prefix = payload[:len(payload)-overrun]
-	finalBlock = make([]byte, blockSize)
-	copy(finalBlock, payload[len(payload)-overrun:])
-	for i := overrun; i < blockSize; i++ {
-		finalBlock[i] = byte(paddingLen - 1)
-	}
-	return
-}
-
-// encrypt encrypts and macs the data in b.
-func (hc *halfConn) encrypt(b *block, explicitIVLen int) (bool, alert) {
-	// mac
-	if hc.mac != nil {
-		mac := hc.mac.MAC(hc.outDigestBuf, hc.seq[0:], b.data[:recordHeaderLen], b.data[recordHeaderLen+explicitIVLen:])
-
-		n := len(b.data)
-		b.resize(n + len(mac))
-		copy(b.data[n:], mac)
-		hc.outDigestBuf = mac
-	}
-
-	payload := b.data[recordHeaderLen:]
-
-	// encrypt
-	if hc.cipher != nil {
-		switch c := hc.cipher.(type) {
-		case cipher.Stream:
-			c.XORKeyStream(payload, payload)
-		case cipher.AEAD:
-			payloadLen := len(b.data) - recordHeaderLen - explicitIVLen
-			b.resize(len(b.data) + c.Overhead())
-			nonce := b.data[recordHeaderLen : recordHeaderLen+explicitIVLen]
-			payload := b.data[recordHeaderLen+explicitIVLen:]
-			payload = payload[:payloadLen]
-
-			var additionalData [13]byte
-			copy(additionalData[:], hc.seq[:])
-			copy(additionalData[8:], b.data[:3])
-			additionalData[11] = byte(payloadLen >> 8)
-			additionalData[12] = byte(payloadLen)
-
-			c.Seal(payload[:0], nonce, payload, additionalData[:])
-		case cbcMode:
-			blockSize := c.BlockSize()
-			if explicitIVLen > 0 {
-				c.SetIV(payload[:explicitIVLen])
-				payload = payload[explicitIVLen:]
-			}
-			prefix, finalBlock := padToBlockSize(payload, blockSize)
-			b.resize(recordHeaderLen + explicitIVLen + len(prefix) + len(finalBlock))
-			c.CryptBlocks(b.data[recordHeaderLen+explicitIVLen:], prefix)
-			c.CryptBlocks(b.data[recordHeaderLen+explicitIVLen+len(prefix):], finalBlock)
-		default:
-			panic("unknown cipher type")
-		}
-	}
-
-	// update length to include MAC and any block padding needed.
-	n := len(b.data) - recordHeaderLen
-	b.data[3] = byte(n >> 8)
-	b.data[4] = byte(n)
-	hc.incSeq()
-
-	return true, 0
-}
-
-// A block is a simple data buffer.
-type block struct {
-	data []byte
-	off  int // index for Read
-	link *block
-}
-
-// resize resizes block to be n bytes, growing if necessary.
-func (b *block) resize(n int) {
-	if n > cap(b.data) {
-		b.reserve(n)
-	}
-	b.data = b.data[0:n]
-}
-
-// reserve makes sure that block contains a capacity of at least n bytes.
-func (b *block) reserve(n int) {
-	if cap(b.data) >= n {
-		return
-	}
-	m := cap(b.data)
-	if m == 0 {
-		m = 1024
-	}
-	for m < n {
-		m *= 2
-	}
-	data := make([]byte, len(b.data), m)
-	copy(data, b.data)
-	b.data = data
-}
-
-// readFromUntil reads from r into b until b contains at least n bytes
-// or else returns an error.
-func (b *block) readFromUntil(r io.Reader, n int) error {
-	// quick case
-	if len(b.data) >= n {
-		return nil
-	}
-
-	// read until have enough.
-	b.reserve(n)
-	for {
-		m, err := r.Read(b.data[len(b.data):cap(b.data)])
-		b.data = b.data[0 : len(b.data)+m]
-		if len(b.data) >= n {
-			// TODO(bradfitz,agl): slightly suspicious
-			// that we're throwing away r.Read's err here.
-			break
-		}
-		if err != nil {
-			return err
-		}
-	}
-	return nil
-}
-
-func (b *block) Read(p []byte) (n int, err error) {
-	n = copy(p, b.data[b.off:])
-	b.off += n
-	return
-}
-
-// newBlock allocates a new block, from hc's free list if possible.
-func (hc *halfConn) newBlock() *block {
-	b := hc.bfree
-	if b == nil {
-		return new(block)
-	}
-	hc.bfree = b.link
-	b.link = nil
-	b.resize(0)
-	return b
-}
-
-// freeBlock returns a block to hc's free list.
-// The protocol is such that each side only has a block or two on
-// its free list at a time, so there's no need to worry about
-// trimming the list, etc.
-func (hc *halfConn) freeBlock(b *block) {
-	b.link = hc.bfree
-	hc.bfree = b
-}
-
-// splitBlock splits a block after the first n bytes,
-// returning a block with those n bytes and a
-// block with the remainder.  the latter may be nil.
-func (hc *halfConn) splitBlock(b *block, n int) (*block, *block) {
-	if len(b.data) <= n {
-		return b, nil
-	}
-	bb := hc.newBlock()
-	bb.resize(len(b.data) - n)
-	copy(bb.data, b.data[n:])
-	b.data = b.data[0:n]
-	return b, bb
-}
-
-// readRecord reads the next TLS record from the connection
-// and updates the record layer state.
-// c.in.Mutex <= L; c.input == nil.
-func (c *Conn) readRecord(want recordType) error {
-	// Caller must be in sync with connection:
-	// handshake data if handshake not yet completed,
-	// else application data.  (We don't support renegotiation.)
-	switch want {
-	default:
-		c.sendAlert(alertInternalError)
-		return c.in.setErrorLocked(errors.New("tls: unknown record type requested"))
-	case recordTypeHandshake, recordTypeChangeCipherSpec:
-		if c.handshakeComplete {
-			c.sendAlert(alertInternalError)
-			return c.in.setErrorLocked(errors.New("tls: handshake or ChangeCipherSpec requested after handshake complete"))
-		}
-	case recordTypeApplicationData:
-		if !c.handshakeComplete {
-			c.sendAlert(alertInternalError)
-			return c.in.setErrorLocked(errors.New("tls: application data record requested before handshake complete"))
-		}
-	}
-
-Again:
-	if c.rawInput == nil {
-		c.rawInput = c.in.newBlock()
-	}
-	b := c.rawInput
-
-	// Read header, payload.
-	if err := b.readFromUntil(c.conn, recordHeaderLen); err != nil {
-		// RFC suggests that EOF without an alertCloseNotify is
-		// an error, but popular web sites seem to do this,
-		// so we can't make it an error.
-		// if err == io.EOF {
-		// 	err = io.ErrUnexpectedEOF
-		// }
-		if e, ok := err.(net.Error); !ok || !e.Temporary() {
-			c.in.setErrorLocked(err)
-		}
-		return err
-	}
-	typ := recordType(b.data[0])
-
-	// No valid TLS record has a type of 0x80, however SSLv2 handshakes
-	// start with a uint16 length where the MSB is set and the first record
-	// is always < 256 bytes long. Therefore typ == 0x80 strongly suggests
-	// an SSLv2 client.
-	if want == recordTypeHandshake && typ == 0x80 {
-		c.sendAlert(alertProtocolVersion)
-		return c.in.setErrorLocked(errors.New("tls: unsupported SSLv2 handshake received"))
-	}
-
-	vers := uint16(b.data[1])<<8 | uint16(b.data[2])
-	n := int(b.data[3])<<8 | int(b.data[4])
-	if c.haveVers && vers != c.vers {
-		c.sendAlert(alertProtocolVersion)
-		return c.in.setErrorLocked(fmt.Errorf("tls: received record with version %x when expecting version %x", vers, c.vers))
-	}
-	if n > maxCiphertext {
-		c.sendAlert(alertRecordOverflow)
-		return c.in.setErrorLocked(fmt.Errorf("tls: oversized record received with length %d", n))
-	}
-	if !c.haveVers {
-		// First message, be extra suspicious:
-		// this might not be a TLS client.
-		// Bail out before reading a full 'body', if possible.
-		// The current max version is 3.1.
-		// If the version is >= 16.0, it's probably not real.
-		// Similarly, a clientHello message encodes in
-		// well under a kilobyte.  If the length is >= 12 kB,
-		// it's probably not real.
-		if (typ != recordTypeAlert && typ != want) || vers >= 0x1000 || n >= 0x3000 {
-			c.sendAlert(alertUnexpectedMessage)
-			return c.in.setErrorLocked(fmt.Errorf("tls: first record does not look like a TLS handshake"))
-		}
-	}
-	if err := b.readFromUntil(c.conn, recordHeaderLen+n); err != nil {
-		if err == io.EOF {
-			err = io.ErrUnexpectedEOF
-		}
-		if e, ok := err.(net.Error); !ok || !e.Temporary() {
-			c.in.setErrorLocked(err)
-		}
-		return err
-	}
-
-	// Process message.
-	b, c.rawInput = c.in.splitBlock(b, recordHeaderLen+n)
-	ok, off, err := c.in.decrypt(b)
-	if !ok {
-		c.in.setErrorLocked(c.sendAlert(err))
-	}
-	b.off = off
-	data := b.data[b.off:]
-	if len(data) > maxPlaintext {
-		err := c.sendAlert(alertRecordOverflow)
-		c.in.freeBlock(b)
-		return c.in.setErrorLocked(err)
-	}
-
-	switch typ {
-	default:
-		c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
-
-	case recordTypeAlert:
-		if len(data) != 2 {
-			c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
-			break
-		}
-		if alert(data[1]) == alertCloseNotify {
-			c.in.setErrorLocked(io.EOF)
-			break
-		}
-		switch data[0] {
-		case alertLevelWarning:
-			// drop on the floor
-			c.in.freeBlock(b)
-			goto Again
-		case alertLevelError:
-			c.in.setErrorLocked(&net.OpError{Op: "remote error", Err: alert(data[1])})
-		default:
-			c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
-		}
-
-	case recordTypeChangeCipherSpec:
-		if typ != want || len(data) != 1 || data[0] != 1 {
-			c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
-			break
-		}
-		err := c.in.changeCipherSpec()
-		if err != nil {
-			c.in.setErrorLocked(c.sendAlert(err.(alert)))
-		}
-
-	case recordTypeApplicationData:
-		if typ != want {
-			c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
-			break
-		}
-		c.input = b
-		b = nil
-
-	case recordTypeHandshake:
-		// TODO(rsc): Should at least pick off connection close.
-		if typ != want {
-			return c.in.setErrorLocked(c.sendAlert(alertNoRenegotiation))
-		}
-		c.hand.Write(data)
-	}
-
-	if b != nil {
-		c.in.freeBlock(b)
-	}
-	return c.in.err
-}
-
-// sendAlert sends a TLS alert message.
-// c.out.Mutex <= L.
-func (c *Conn) sendAlertLocked(err alert) error {
-	switch err {
-	case alertNoRenegotiation, alertCloseNotify:
-		c.tmp[0] = alertLevelWarning
-	default:
-		c.tmp[0] = alertLevelError
-	}
-	c.tmp[1] = byte(err)
-	c.writeRecord(recordTypeAlert, c.tmp[0:2])
-	// closeNotify is a special case in that it isn't an error:
-	if err != alertCloseNotify {
-		return c.out.setErrorLocked(&net.OpError{Op: "local error", Err: err})
-	}
-	return nil
-}
-
-// sendAlert sends a TLS alert message.
-// L < c.out.Mutex.
-func (c *Conn) sendAlert(err alert) error {
-	c.out.Lock()
-	defer c.out.Unlock()
-	return c.sendAlertLocked(err)
-}
-
-// writeRecord writes a TLS record with the given type and payload
-// to the connection and updates the record layer state.
-// c.out.Mutex <= L.
-func (c *Conn) writeRecord(typ recordType, data []byte) (n int, err error) {
-	b := c.out.newBlock()
-	for len(data) > 0 {
-		m := len(data)
-		if m > maxPlaintext {
-			m = maxPlaintext
-		}
-		explicitIVLen := 0
-		explicitIVIsSeq := false
-
-		var cbc cbcMode
-		if c.out.version >= VersionTLS11 {
-			var ok bool
-			if cbc, ok = c.out.cipher.(cbcMode); ok {
-				explicitIVLen = cbc.BlockSize()
-			}
-		}
-		if explicitIVLen == 0 {
-			if _, ok := c.out.cipher.(cipher.AEAD); ok {
-				explicitIVLen = 8
-				// The AES-GCM construction in TLS has an
-				// explicit nonce so that the nonce can be
-				// random. However, the nonce is only 8 bytes
-				// which is too small for a secure, random
-				// nonce. Therefore we use the sequence number
-				// as the nonce.
-				explicitIVIsSeq = true
-			}
-		}
-		b.resize(recordHeaderLen + explicitIVLen + m)
-		b.data[0] = byte(typ)
-		vers := c.vers
-		if vers == 0 {
-			// Some TLS servers fail if the record version is
-			// greater than TLS 1.0 for the initial ClientHello.
-			vers = VersionTLS10
-		}
-		b.data[1] = byte(vers >> 8)
-		b.data[2] = byte(vers)
-		b.data[3] = byte(m >> 8)
-		b.data[4] = byte(m)
-		if explicitIVLen > 0 {
-			explicitIV := b.data[recordHeaderLen : recordHeaderLen+explicitIVLen]
-			if explicitIVIsSeq {
-				copy(explicitIV, c.out.seq[:])
-			} else {
-				if _, err = io.ReadFull(c.config.rand(), explicitIV); err != nil {
-					break
-				}
-			}
-		}
-		copy(b.data[recordHeaderLen+explicitIVLen:], data)
-		c.out.encrypt(b, explicitIVLen)
-		_, err = c.conn.Write(b.data)
-		if err != nil {
-			break
-		}
-		n += m
-		data = data[m:]
-	}
-	c.out.freeBlock(b)
-
-	if typ == recordTypeChangeCipherSpec {
-		err = c.out.changeCipherSpec()
-		if err != nil {
-			// Cannot call sendAlert directly,
-			// because we already hold c.out.Mutex.
-			c.tmp[0] = alertLevelError
-			c.tmp[1] = byte(err.(alert))
-			c.writeRecord(recordTypeAlert, c.tmp[0:2])
-			return n, c.out.setErrorLocked(&net.OpError{Op: "local error", Err: err})
-		}
-	}
-	return
-}
-
-// readHandshake reads the next handshake message from
-// the record layer.
-// c.in.Mutex < L; c.out.Mutex < L.
-func (c *Conn) readHandshake() (interface{}, error) {
-	for c.hand.Len() < 4 {
-		if err := c.in.err; err != nil {
-			return nil, err
-		}
-		if err := c.readRecord(recordTypeHandshake); err != nil {
-			return nil, err
-		}
-	}
-
-	data := c.hand.Bytes()
-	n := int(data[1])<<16 | int(data[2])<<8 | int(data[3])
-	if n > maxHandshake {
-		return nil, c.in.setErrorLocked(c.sendAlert(alertInternalError))
-	}
-	for c.hand.Len() < 4+n {
-		if err := c.in.err; err != nil {
-			return nil, err
-		}
-		if err := c.readRecord(recordTypeHandshake); err != nil {
-			return nil, err
-		}
-	}
-	data = c.hand.Next(4 + n)
-	var m handshakeMessage
-	switch data[0] {
-	case typeClientHello:
-		m = new(clientHelloMsg)
-	case typeServerHello:
-		m = new(serverHelloMsg)
-	case typeNewSessionTicket:
-		m = new(newSessionTicketMsg)
-	case typeCertificate:
-		m = new(certificateMsg)
-	case typeCertificateRequest:
-		m = &certificateRequestMsg{
-			hasSignatureAndHash: c.vers >= VersionTLS12,
-		}
-	case typeCertificateStatus:
-		m = new(certificateStatusMsg)
-	case typeServerKeyExchange:
-		m = new(serverKeyExchangeMsg)
-	case typeServerHelloDone:
-		m = new(serverHelloDoneMsg)
-	case typeClientKeyExchange:
-		m = new(clientKeyExchangeMsg)
-	case typeCertificateVerify:
-		m = &certificateVerifyMsg{
-			hasSignatureAndHash: c.vers >= VersionTLS12,
-		}
-	case typeNextProtocol:
-		m = new(nextProtoMsg)
-	case typeFinished:
-		m = new(finishedMsg)
-	default:
-		return nil, c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
-	}
-
-	// The handshake message unmarshallers
-	// expect to be able to keep references to data,
-	// so pass in a fresh copy that won't be overwritten.
-	data = append([]byte(nil), data...)
-
-	if !m.unmarshal(data) {
-		return nil, c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
-	}
-	return m, nil
-}
-
-// Write writes data to the connection.
-func (c *Conn) Write(b []byte) (int, error) {
-	if err := c.Handshake(); err != nil {
-		return 0, err
-	}
-
-	c.out.Lock()
-	defer c.out.Unlock()
-
-	if err := c.out.err; err != nil {
-		return 0, err
-	}
-
-	if !c.handshakeComplete {
-		return 0, alertInternalError
-	}
-
-	// SSL 3.0 and TLS 1.0 are susceptible to a chosen-plaintext
-	// attack when using block mode ciphers due to predictable IVs.
-	// This can be prevented by splitting each Application Data
-	// record into two records, effectively randomizing the IV.
-	//
-	// http://www.openssl.org/~bodo/tls-cbc.txt
-	// https://bugzilla.mozilla.org/show_bug.cgi?id=665814
-	// http://www.imperialviolet.org/2012/01/15/beastfollowup.html
-
-	var m int
-	if len(b) > 1 && c.vers <= VersionTLS10 {
-		if _, ok := c.out.cipher.(cipher.BlockMode); ok {
-			n, err := c.writeRecord(recordTypeApplicationData, b[:1])
-			if err != nil {
-				return n, c.out.setErrorLocked(err)
-			}
-			m, b = 1, b[1:]
-		}
-	}
-
-	n, err := c.writeRecord(recordTypeApplicationData, b)
-	return n + m, c.out.setErrorLocked(err)
-}
-
-// Read can be made to time out and return a net.Error with Timeout() == true
-// after a fixed time limit; see SetDeadline and SetReadDeadline.
-func (c *Conn) Read(b []byte) (n int, err error) {
-	if err = c.Handshake(); err != nil {
-		return
-	}
-	if len(b) == 0 {
-		// Put this after Handshake, in case people were calling
-		// Read(nil) for the side effect of the Handshake.
-		return
-	}
-
-	c.in.Lock()
-	defer c.in.Unlock()
-
-	// Some OpenSSL servers send empty records in order to randomize the
-	// CBC IV. So this loop ignores a limited number of empty records.
-	const maxConsecutiveEmptyRecords = 100
-	for emptyRecordCount := 0; emptyRecordCount <= maxConsecutiveEmptyRecords; emptyRecordCount++ {
-		for c.input == nil && c.in.err == nil {
-			if err := c.readRecord(recordTypeApplicationData); err != nil {
-				// Soft error, like EAGAIN
-				return 0, err
-			}
-		}
-		if err := c.in.err; err != nil {
-			return 0, err
-		}
-
-		n, err = c.input.Read(b)
-		if c.input.off >= len(c.input.data) {
-			c.in.freeBlock(c.input)
-			c.input = nil
-		}
-
-		// If a close-notify alert is waiting, read it so that
-		// we can return (n, EOF) instead of (n, nil), to signal
-		// to the HTTP response reading goroutine that the
-		// connection is now closed. This eliminates a race
-		// where the HTTP response reading goroutine would
-		// otherwise not observe the EOF until its next read,
-		// by which time a client goroutine might have already
-		// tried to reuse the HTTP connection for a new
-		// request.
-		// See https://codereview.appspot.com/76400046
-		// and http://golang.org/issue/3514
-		if ri := c.rawInput; ri != nil &&
-			n != 0 && err == nil &&
-			c.input == nil && len(ri.data) > 0 && recordType(ri.data[0]) == recordTypeAlert {
-			if recErr := c.readRecord(recordTypeApplicationData); recErr != nil {
-				err = recErr // will be io.EOF on closeNotify
-			}
-		}
-
-		if n != 0 || err != nil {
-			return n, err
-		}
-	}
-
-	return 0, io.ErrNoProgress
-}
-
-// Close closes the connection.
-func (c *Conn) Close() error {
-	var alertErr error
-
-	c.handshakeMutex.Lock()
-	defer c.handshakeMutex.Unlock()
-	if c.handshakeComplete {
-		alertErr = c.sendAlert(alertCloseNotify)
-	}
-
-	if err := c.conn.Close(); err != nil {
-		return err
-	}
-	return alertErr
-}
-
-// Handshake runs the client or server handshake
-// protocol if it has not yet been run.
-// Most uses of this package need not call Handshake
-// explicitly: the first Read or Write will call it automatically.
-func (c *Conn) Handshake() error {
-	c.handshakeMutex.Lock()
-	defer c.handshakeMutex.Unlock()
-	if err := c.handshakeErr; err != nil {
-		return err
-	}
-	if c.handshakeComplete {
-		return nil
-	}
-
-	if c.isClient {
-		c.handshakeErr = c.clientHandshake()
-	} else {
-		c.handshakeErr = c.serverHandshake()
-	}
-	return c.handshakeErr
-}
-
-// ConnectionState returns basic TLS details about the connection.
-func (c *Conn) ConnectionState() ConnectionState {
-	c.handshakeMutex.Lock()
-	defer c.handshakeMutex.Unlock()
-
-	var state ConnectionState
-	state.HandshakeComplete = c.handshakeComplete
-	if c.handshakeComplete {
-		state.Version = c.vers
-		state.NegotiatedProtocol = c.clientProtocol
-		state.DidResume = c.didResume
-		state.NegotiatedProtocolIsMutual = !c.clientProtocolFallback
-		state.CipherSuite = c.cipherSuite
-		state.PeerCertificates = c.peerCertificates
-		state.VerifiedChains = c.verifiedChains
-		state.ServerName = c.serverName
-	}
-
-	return state
-}
-
-// OCSPResponse returns the stapled OCSP response from the TLS server, if
-// any. (Only valid for client connections.)
-func (c *Conn) OCSPResponse() []byte {
-	c.handshakeMutex.Lock()
-	defer c.handshakeMutex.Unlock()
-
-	return c.ocspResponse
-}
-
-// VerifyHostname checks that the peer certificate chain is valid for
-// connecting to host.  If so, it returns nil; if not, it returns an error
-// describing the problem.
-func (c *Conn) VerifyHostname(host string) error {
-	c.handshakeMutex.Lock()
-	defer c.handshakeMutex.Unlock()
-	if !c.isClient {
-		return errors.New("tls: VerifyHostname called on TLS server connection")
-	}
-	if !c.handshakeComplete {
-		return errors.New("tls: handshake has not yet been performed")
-	}
-	return c.peerCertificates[0].VerifyHostname(host)
-}
diff --git a/src/pkg/crypto/tls/conn_test.go b/src/pkg/crypto/tls/conn_test.go
deleted file mode 100644
index 5c55514..0000000
--- a/src/pkg/crypto/tls/conn_test.go
+++ /dev/null
@@ -1,106 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package tls
-
-import (
-	"testing"
-)
-
-func TestRoundUp(t *testing.T) {
-	if roundUp(0, 16) != 0 ||
-		roundUp(1, 16) != 16 ||
-		roundUp(15, 16) != 16 ||
-		roundUp(16, 16) != 16 ||
-		roundUp(17, 16) != 32 {
-		t.Error("roundUp broken")
-	}
-}
-
-var paddingTests = []struct {
-	in          []byte
-	good        bool
-	expectedLen int
-}{
-	{[]byte{1, 2, 3, 4, 0}, true, 4},
-	{[]byte{1, 2, 3, 4, 0, 1}, false, 0},
-	{[]byte{1, 2, 3, 4, 99, 99}, false, 0},
-	{[]byte{1, 2, 3, 4, 1, 1}, true, 4},
-	{[]byte{1, 2, 3, 2, 2, 2}, true, 3},
-	{[]byte{1, 2, 3, 3, 3, 3}, true, 2},
-	{[]byte{1, 2, 3, 4, 3, 3}, false, 0},
-	{[]byte{1, 4, 4, 4, 4, 4}, true, 1},
-	{[]byte{5, 5, 5, 5, 5, 5}, true, 0},
-	{[]byte{6, 6, 6, 6, 6, 6}, false, 0},
-}
-
-func TestRemovePadding(t *testing.T) {
-	for i, test := range paddingTests {
-		payload, good := removePadding(test.in)
-		expectedGood := byte(255)
-		if !test.good {
-			expectedGood = 0
-		}
-		if good != expectedGood {
-			t.Errorf("#%d: wrong validity, want:%d got:%d", i, expectedGood, good)
-		}
-		if good == 255 && len(payload) != test.expectedLen {
-			t.Errorf("#%d: got %d, want %d", i, len(payload), test.expectedLen)
-		}
-	}
-}
-
-var certExampleCom = `308201403081eda003020102020101300b06092a864886f70d010105301e311c301a060355040a131354657374696e67204365727469666963617465301e170d3131313030313138353835325a170d3132303933303138353835325a301e311c301a060355040a131354657374696e67204365727469666963617465305a300b06092a864886f70d010101034b003048024100bced6e32368599eeddf18796bfd03958a154f87e5b084f96e85136a56b886733592f493f0fc68b0d6b3551781cb95e13c5de458b28d6fb60d20a9129313261410203010001a31a301830160603551d11040f300d820b6578 [...]
-
-var certWildcardExampleCom = `308201423081efa003020102020101300b06092a864886f70d010105301e311c301a060355040a131354657374696e67204365727469666963617465301e170d3131313030313139303034365a170d3132303933303139303034365a301e311c301a060355040a131354657374696e67204365727469666963617465305a300b06092a864886f70d010101034b003048024100bced6e32368599eeddf18796bfd03958a154f87e5b084f96e85136a56b886733592f493f0fc68b0d6b3551781cb95e13c5de458b28d6fb60d20a9129313261410203010001a31c301a30180603551d110411300f [...]
-
-var certFooExampleCom = `308201443081f1a003020102020101300b06092a864886f70d010105301e311c301a060355040a131354657374696e67204365727469666963617465301e170d3131313030313139303131345a170d3132303933303139303131345a301e311c301a060355040a131354657374696e67204365727469666963617465305a300b06092a864886f70d010101034b003048024100bced6e32368599eeddf18796bfd03958a154f87e5b084f96e85136a56b886733592f493f0fc68b0d6b3551781cb95e13c5de458b28d6fb60d20a9129313261410203010001a31e301c301a0603551d1104133011820f6 [...]
-
-var certDoubleWildcardExampleCom = `308201443081f1a003020102020101300b06092a864886f70d010105301e311c301a060355040a131354657374696e67204365727469666963617465301e170d3131313030313139303134315a170d3132303933303139303134315a301e311c301a060355040a131354657374696e67204365727469666963617465305a300b06092a864886f70d010101034b003048024100bced6e32368599eeddf18796bfd03958a154f87e5b084f96e85136a56b886733592f493f0fc68b0d6b3551781cb95e13c5de458b28d6fb60d20a9129313261410203010001a31e301c301a0603551d1104 [...]
-
-func TestCertificateSelection(t *testing.T) {
-	config := Config{
-		Certificates: []Certificate{
-			{
-				Certificate: [][]byte{fromHex(certExampleCom)},
-			},
-			{
-				Certificate: [][]byte{fromHex(certWildcardExampleCom)},
-			},
-			{
-				Certificate: [][]byte{fromHex(certFooExampleCom)},
-			},
-			{
-				Certificate: [][]byte{fromHex(certDoubleWildcardExampleCom)},
-			},
-		},
-	}
-
-	config.BuildNameToCertificate()
-
-	pointerToIndex := func(c *Certificate) int {
-		for i := range config.Certificates {
-			if c == &config.Certificates[i] {
-				return i
-			}
-		}
-		return -1
-	}
-
-	if n := pointerToIndex(config.getCertificateForName("example.com")); n != 0 {
-		t.Errorf("example.com returned certificate %d, not 0", n)
-	}
-	if n := pointerToIndex(config.getCertificateForName("bar.example.com")); n != 1 {
-		t.Errorf("bar.example.com returned certificate %d, not 1", n)
-	}
-	if n := pointerToIndex(config.getCertificateForName("foo.example.com")); n != 2 {
-		t.Errorf("foo.example.com returned certificate %d, not 2", n)
-	}
-	if n := pointerToIndex(config.getCertificateForName("foo.bar.example.com")); n != 3 {
-		t.Errorf("foo.bar.example.com returned certificate %d, not 3", n)
-	}
-	if n := pointerToIndex(config.getCertificateForName("foo.bar.baz.example.com")); n != 0 {
-		t.Errorf("foo.bar.baz.example.com returned certificate %d, not 0", n)
-	}
-}
diff --git a/src/pkg/crypto/tls/generate_cert.go b/src/pkg/crypto/tls/generate_cert.go
deleted file mode 100644
index 5c6d839..0000000
--- a/src/pkg/crypto/tls/generate_cert.go
+++ /dev/null
@@ -1,115 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build ignore
-
-// Generate a self-signed X.509 certificate for a TLS server. Outputs to
-// 'cert.pem' and 'key.pem' and will overwrite existing files.
-
-package main
-
-import (
-	"crypto/rand"
-	"crypto/rsa"
-	"crypto/x509"
-	"crypto/x509/pkix"
-	"encoding/pem"
-	"flag"
-	"fmt"
-	"log"
-	"math/big"
-	"net"
-	"os"
-	"strings"
-	"time"
-)
-
-var (
-	host      = flag.String("host", "", "Comma-separated hostnames and IPs to generate a certificate for")
-	validFrom = flag.String("start-date", "", "Creation date formatted as Jan 1 15:04:05 2011")
-	validFor  = flag.Duration("duration", 365*24*time.Hour, "Duration that certificate is valid for")
-	isCA      = flag.Bool("ca", false, "whether this cert should be its own Certificate Authority")
-	rsaBits   = flag.Int("rsa-bits", 2048, "Size of RSA key to generate")
-)
-
-func main() {
-	flag.Parse()
-
-	if len(*host) == 0 {
-		log.Fatalf("Missing required --host parameter")
-	}
-
-	priv, err := rsa.GenerateKey(rand.Reader, *rsaBits)
-	if err != nil {
-		log.Fatalf("failed to generate private key: %s", err)
-	}
-
-	var notBefore time.Time
-	if len(*validFrom) == 0 {
-		notBefore = time.Now()
-	} else {
-		notBefore, err = time.Parse("Jan 2 15:04:05 2006", *validFrom)
-		if err != nil {
-			fmt.Fprintf(os.Stderr, "Failed to parse creation date: %s\n", err)
-			os.Exit(1)
-		}
-	}
-
-	notAfter := notBefore.Add(*validFor)
-
-	serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
-	serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
-	if err != nil {
-		log.Fatalf("failed to generate serial number: %s", err)
-	}
-
-	template := x509.Certificate{
-		SerialNumber: serialNumber,
-		Subject: pkix.Name{
-			Organization: []string{"Acme Co"},
-		},
-		NotBefore: notBefore,
-		NotAfter:  notAfter,
-
-		KeyUsage:              x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
-		ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
-		BasicConstraintsValid: true,
-	}
-
-	hosts := strings.Split(*host, ",")
-	for _, h := range hosts {
-		if ip := net.ParseIP(h); ip != nil {
-			template.IPAddresses = append(template.IPAddresses, ip)
-		} else {
-			template.DNSNames = append(template.DNSNames, h)
-		}
-	}
-
-	if *isCA {
-		template.IsCA = true
-		template.KeyUsage |= x509.KeyUsageCertSign
-	}
-
-	derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv)
-	if err != nil {
-		log.Fatalf("Failed to create certificate: %s", err)
-	}
-
-	certOut, err := os.Create("cert.pem")
-	if err != nil {
-		log.Fatalf("failed to open cert.pem for writing: %s", err)
-	}
-	pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes})
-	certOut.Close()
-	log.Print("written cert.pem\n")
-
-	keyOut, err := os.OpenFile("key.pem", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
-	if err != nil {
-		log.Print("failed to open key.pem for writing:", err)
-		return
-	}
-	pem.Encode(keyOut, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)})
-	keyOut.Close()
-	log.Print("written key.pem\n")
-}
diff --git a/src/pkg/crypto/tls/handshake_client.go b/src/pkg/crypto/tls/handshake_client.go
deleted file mode 100644
index a320fde..0000000
--- a/src/pkg/crypto/tls/handshake_client.go
+++ /dev/null
@@ -1,601 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package tls
-
-import (
-	"bytes"
-	"crypto/ecdsa"
-	"crypto/rsa"
-	"crypto/subtle"
-	"crypto/x509"
-	"encoding/asn1"
-	"errors"
-	"fmt"
-	"io"
-	"net"
-	"strconv"
-)
-
-type clientHandshakeState struct {
-	c            *Conn
-	serverHello  *serverHelloMsg
-	hello        *clientHelloMsg
-	suite        *cipherSuite
-	finishedHash finishedHash
-	masterSecret []byte
-	session      *ClientSessionState
-}
-
-func (c *Conn) clientHandshake() error {
-	if c.config == nil {
-		c.config = defaultConfig()
-	}
-
-	if len(c.config.ServerName) == 0 && !c.config.InsecureSkipVerify {
-		return errors.New("tls: either ServerName or InsecureSkipVerify must be specified in the tls.Config")
-	}
-
-	hello := &clientHelloMsg{
-		vers:                c.config.maxVersion(),
-		compressionMethods:  []uint8{compressionNone},
-		random:              make([]byte, 32),
-		ocspStapling:        true,
-		serverName:          c.config.ServerName,
-		supportedCurves:     c.config.curvePreferences(),
-		supportedPoints:     []uint8{pointFormatUncompressed},
-		nextProtoNeg:        len(c.config.NextProtos) > 0,
-		secureRenegotiation: true,
-	}
-
-	possibleCipherSuites := c.config.cipherSuites()
-	hello.cipherSuites = make([]uint16, 0, len(possibleCipherSuites))
-
-NextCipherSuite:
-	for _, suiteId := range possibleCipherSuites {
-		for _, suite := range cipherSuites {
-			if suite.id != suiteId {
-				continue
-			}
-			// Don't advertise TLS 1.2-only cipher suites unless
-			// we're attempting TLS 1.2.
-			if hello.vers < VersionTLS12 && suite.flags&suiteTLS12 != 0 {
-				continue
-			}
-			hello.cipherSuites = append(hello.cipherSuites, suiteId)
-			continue NextCipherSuite
-		}
-	}
-
-	_, err := io.ReadFull(c.config.rand(), hello.random)
-	if err != nil {
-		c.sendAlert(alertInternalError)
-		return errors.New("tls: short read from Rand: " + err.Error())
-	}
-
-	if hello.vers >= VersionTLS12 {
-		hello.signatureAndHashes = supportedSKXSignatureAlgorithms
-	}
-
-	var session *ClientSessionState
-	var cacheKey string
-	sessionCache := c.config.ClientSessionCache
-	if c.config.SessionTicketsDisabled {
-		sessionCache = nil
-	}
-
-	if sessionCache != nil {
-		hello.ticketSupported = true
-
-		// Try to resume a previously negotiated TLS session, if
-		// available.
-		cacheKey = clientSessionCacheKey(c.conn.RemoteAddr(), c.config)
-		candidateSession, ok := sessionCache.Get(cacheKey)
-		if ok {
-			// Check that the ciphersuite/version used for the
-			// previous session are still valid.
-			cipherSuiteOk := false
-			for _, id := range hello.cipherSuites {
-				if id == candidateSession.cipherSuite {
-					cipherSuiteOk = true
-					break
-				}
-			}
-
-			versOk := candidateSession.vers >= c.config.minVersion() &&
-				candidateSession.vers <= c.config.maxVersion()
-			if versOk && cipherSuiteOk {
-				session = candidateSession
-			}
-		}
-	}
-
-	if session != nil {
-		hello.sessionTicket = session.sessionTicket
-		// A random session ID is used to detect when the
-		// server accepted the ticket and is resuming a session
-		// (see RFC 5077).
-		hello.sessionId = make([]byte, 16)
-		if _, err := io.ReadFull(c.config.rand(), hello.sessionId); err != nil {
-			c.sendAlert(alertInternalError)
-			return errors.New("tls: short read from Rand: " + err.Error())
-		}
-	}
-
-	c.writeRecord(recordTypeHandshake, hello.marshal())
-
-	msg, err := c.readHandshake()
-	if err != nil {
-		return err
-	}
-	serverHello, ok := msg.(*serverHelloMsg)
-	if !ok {
-		c.sendAlert(alertUnexpectedMessage)
-		return unexpectedMessageError(serverHello, msg)
-	}
-
-	vers, ok := c.config.mutualVersion(serverHello.vers)
-	if !ok || vers < VersionTLS10 {
-		// TLS 1.0 is the minimum version supported as a client.
-		c.sendAlert(alertProtocolVersion)
-		return fmt.Errorf("tls: server selected unsupported protocol version %x", serverHello.vers)
-	}
-	c.vers = vers
-	c.haveVers = true
-
-	suite := mutualCipherSuite(c.config.cipherSuites(), serverHello.cipherSuite)
-	if suite == nil {
-		c.sendAlert(alertHandshakeFailure)
-		return fmt.Errorf("tls: server selected an unsupported cipher suite")
-	}
-
-	hs := &clientHandshakeState{
-		c:            c,
-		serverHello:  serverHello,
-		hello:        hello,
-		suite:        suite,
-		finishedHash: newFinishedHash(c.vers),
-		session:      session,
-	}
-
-	hs.finishedHash.Write(hs.hello.marshal())
-	hs.finishedHash.Write(hs.serverHello.marshal())
-
-	isResume, err := hs.processServerHello()
-	if err != nil {
-		return err
-	}
-
-	if isResume {
-		if err := hs.establishKeys(); err != nil {
-			return err
-		}
-		if err := hs.readSessionTicket(); err != nil {
-			return err
-		}
-		if err := hs.readFinished(); err != nil {
-			return err
-		}
-		if err := hs.sendFinished(); err != nil {
-			return err
-		}
-	} else {
-		if err := hs.doFullHandshake(); err != nil {
-			return err
-		}
-		if err := hs.establishKeys(); err != nil {
-			return err
-		}
-		if err := hs.sendFinished(); err != nil {
-			return err
-		}
-		if err := hs.readSessionTicket(); err != nil {
-			return err
-		}
-		if err := hs.readFinished(); err != nil {
-			return err
-		}
-	}
-
-	if sessionCache != nil && hs.session != nil && session != hs.session {
-		sessionCache.Put(cacheKey, hs.session)
-	}
-
-	c.didResume = isResume
-	c.handshakeComplete = true
-	c.cipherSuite = suite.id
-	return nil
-}
-
-func (hs *clientHandshakeState) doFullHandshake() error {
-	c := hs.c
-
-	msg, err := c.readHandshake()
-	if err != nil {
-		return err
-	}
-	certMsg, ok := msg.(*certificateMsg)
-	if !ok || len(certMsg.certificates) == 0 {
-		c.sendAlert(alertUnexpectedMessage)
-		return unexpectedMessageError(certMsg, msg)
-	}
-	hs.finishedHash.Write(certMsg.marshal())
-
-	certs := make([]*x509.Certificate, len(certMsg.certificates))
-	for i, asn1Data := range certMsg.certificates {
-		cert, err := x509.ParseCertificate(asn1Data)
-		if err != nil {
-			c.sendAlert(alertBadCertificate)
-			return errors.New("tls: failed to parse certificate from server: " + err.Error())
-		}
-		certs[i] = cert
-	}
-
-	if !c.config.InsecureSkipVerify {
-		opts := x509.VerifyOptions{
-			Roots:         c.config.RootCAs,
-			CurrentTime:   c.config.time(),
-			DNSName:       c.config.ServerName,
-			Intermediates: x509.NewCertPool(),
-		}
-
-		for i, cert := range certs {
-			if i == 0 {
-				continue
-			}
-			opts.Intermediates.AddCert(cert)
-		}
-		c.verifiedChains, err = certs[0].Verify(opts)
-		if err != nil {
-			c.sendAlert(alertBadCertificate)
-			return err
-		}
-	}
-
-	switch certs[0].PublicKey.(type) {
-	case *rsa.PublicKey, *ecdsa.PublicKey:
-		break
-	default:
-		c.sendAlert(alertUnsupportedCertificate)
-		return fmt.Errorf("tls: server's certificate contains an unsupported type of public key: %T", certs[0].PublicKey)
-	}
-
-	c.peerCertificates = certs
-
-	if hs.serverHello.ocspStapling {
-		msg, err = c.readHandshake()
-		if err != nil {
-			return err
-		}
-		cs, ok := msg.(*certificateStatusMsg)
-		if !ok {
-			c.sendAlert(alertUnexpectedMessage)
-			return unexpectedMessageError(cs, msg)
-		}
-		hs.finishedHash.Write(cs.marshal())
-
-		if cs.statusType == statusTypeOCSP {
-			c.ocspResponse = cs.response
-		}
-	}
-
-	msg, err = c.readHandshake()
-	if err != nil {
-		return err
-	}
-
-	keyAgreement := hs.suite.ka(c.vers)
-
-	skx, ok := msg.(*serverKeyExchangeMsg)
-	if ok {
-		hs.finishedHash.Write(skx.marshal())
-		err = keyAgreement.processServerKeyExchange(c.config, hs.hello, hs.serverHello, certs[0], skx)
-		if err != nil {
-			c.sendAlert(alertUnexpectedMessage)
-			return err
-		}
-
-		msg, err = c.readHandshake()
-		if err != nil {
-			return err
-		}
-	}
-
-	var chainToSend *Certificate
-	var certRequested bool
-	certReq, ok := msg.(*certificateRequestMsg)
-	if ok {
-		certRequested = true
-
-		// RFC 4346 on the certificateAuthorities field:
-		// A list of the distinguished names of acceptable certificate
-		// authorities. These distinguished names may specify a desired
-		// distinguished name for a root CA or for a subordinate CA;
-		// thus, this message can be used to describe both known roots
-		// and a desired authorization space. If the
-		// certificate_authorities list is empty then the client MAY
-		// send any certificate of the appropriate
-		// ClientCertificateType, unless there is some external
-		// arrangement to the contrary.
-
-		hs.finishedHash.Write(certReq.marshal())
-
-		var rsaAvail, ecdsaAvail bool
-		for _, certType := range certReq.certificateTypes {
-			switch certType {
-			case certTypeRSASign:
-				rsaAvail = true
-			case certTypeECDSASign:
-				ecdsaAvail = true
-			}
-		}
-
-		// We need to search our list of client certs for one
-		// where SignatureAlgorithm is RSA and the Issuer is in
-		// certReq.certificateAuthorities
-	findCert:
-		for i, chain := range c.config.Certificates {
-			if !rsaAvail && !ecdsaAvail {
-				continue
-			}
-
-			for j, cert := range chain.Certificate {
-				x509Cert := chain.Leaf
-				// parse the certificate if this isn't the leaf
-				// node, or if chain.Leaf was nil
-				if j != 0 || x509Cert == nil {
-					if x509Cert, err = x509.ParseCertificate(cert); err != nil {
-						c.sendAlert(alertInternalError)
-						return errors.New("tls: failed to parse client certificate #" + strconv.Itoa(i) + ": " + err.Error())
-					}
-				}
-
-				switch {
-				case rsaAvail && x509Cert.PublicKeyAlgorithm == x509.RSA:
-				case ecdsaAvail && x509Cert.PublicKeyAlgorithm == x509.ECDSA:
-				default:
-					continue findCert
-				}
-
-				if len(certReq.certificateAuthorities) == 0 {
-					// they gave us an empty list, so just take the
-					// first RSA cert from c.config.Certificates
-					chainToSend = &chain
-					break findCert
-				}
-
-				for _, ca := range certReq.certificateAuthorities {
-					if bytes.Equal(x509Cert.RawIssuer, ca) {
-						chainToSend = &chain
-						break findCert
-					}
-				}
-			}
-		}
-
-		msg, err = c.readHandshake()
-		if err != nil {
-			return err
-		}
-	}
-
-	shd, ok := msg.(*serverHelloDoneMsg)
-	if !ok {
-		c.sendAlert(alertUnexpectedMessage)
-		return unexpectedMessageError(shd, msg)
-	}
-	hs.finishedHash.Write(shd.marshal())
-
-	// If the server requested a certificate then we have to send a
-	// Certificate message, even if it's empty because we don't have a
-	// certificate to send.
-	if certRequested {
-		certMsg = new(certificateMsg)
-		if chainToSend != nil {
-			certMsg.certificates = chainToSend.Certificate
-		}
-		hs.finishedHash.Write(certMsg.marshal())
-		c.writeRecord(recordTypeHandshake, certMsg.marshal())
-	}
-
-	preMasterSecret, ckx, err := keyAgreement.generateClientKeyExchange(c.config, hs.hello, certs[0])
-	if err != nil {
-		c.sendAlert(alertInternalError)
-		return err
-	}
-	if ckx != nil {
-		hs.finishedHash.Write(ckx.marshal())
-		c.writeRecord(recordTypeHandshake, ckx.marshal())
-	}
-
-	if chainToSend != nil {
-		var signed []byte
-		certVerify := &certificateVerifyMsg{
-			hasSignatureAndHash: c.vers >= VersionTLS12,
-		}
-
-		switch key := c.config.Certificates[0].PrivateKey.(type) {
-		case *ecdsa.PrivateKey:
-			digest, _, hashId := hs.finishedHash.hashForClientCertificate(signatureECDSA)
-			r, s, err := ecdsa.Sign(c.config.rand(), key, digest)
-			if err == nil {
-				signed, err = asn1.Marshal(ecdsaSignature{r, s})
-			}
-			certVerify.signatureAndHash.signature = signatureECDSA
-			certVerify.signatureAndHash.hash = hashId
-		case *rsa.PrivateKey:
-			digest, hashFunc, hashId := hs.finishedHash.hashForClientCertificate(signatureRSA)
-			signed, err = rsa.SignPKCS1v15(c.config.rand(), key, hashFunc, digest)
-			certVerify.signatureAndHash.signature = signatureRSA
-			certVerify.signatureAndHash.hash = hashId
-		default:
-			err = errors.New("unknown private key type")
-		}
-		if err != nil {
-			c.sendAlert(alertInternalError)
-			return errors.New("tls: failed to sign handshake with client certificate: " + err.Error())
-		}
-		certVerify.signature = signed
-
-		hs.finishedHash.Write(certVerify.marshal())
-		c.writeRecord(recordTypeHandshake, certVerify.marshal())
-	}
-
-	hs.masterSecret = masterFromPreMasterSecret(c.vers, preMasterSecret, hs.hello.random, hs.serverHello.random)
-	return nil
-}
-
-func (hs *clientHandshakeState) establishKeys() error {
-	c := hs.c
-
-	clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV :=
-		keysFromMasterSecret(c.vers, hs.masterSecret, hs.hello.random, hs.serverHello.random, hs.suite.macLen, hs.suite.keyLen, hs.suite.ivLen)
-	var clientCipher, serverCipher interface{}
-	var clientHash, serverHash macFunction
-	if hs.suite.cipher != nil {
-		clientCipher = hs.suite.cipher(clientKey, clientIV, false /* not for reading */)
-		clientHash = hs.suite.mac(c.vers, clientMAC)
-		serverCipher = hs.suite.cipher(serverKey, serverIV, true /* for reading */)
-		serverHash = hs.suite.mac(c.vers, serverMAC)
-	} else {
-		clientCipher = hs.suite.aead(clientKey, clientIV)
-		serverCipher = hs.suite.aead(serverKey, serverIV)
-	}
-
-	c.in.prepareCipherSpec(c.vers, serverCipher, serverHash)
-	c.out.prepareCipherSpec(c.vers, clientCipher, clientHash)
-	return nil
-}
-
-func (hs *clientHandshakeState) serverResumedSession() bool {
-	// If the server responded with the same sessionId then it means the
-	// sessionTicket is being used to resume a TLS session.
-	return hs.session != nil && hs.hello.sessionId != nil &&
-		bytes.Equal(hs.serverHello.sessionId, hs.hello.sessionId)
-}
-
-func (hs *clientHandshakeState) processServerHello() (bool, error) {
-	c := hs.c
-
-	if hs.serverHello.compressionMethod != compressionNone {
-		c.sendAlert(alertUnexpectedMessage)
-		return false, errors.New("tls: server selected unsupported compression format")
-	}
-
-	if !hs.hello.nextProtoNeg && hs.serverHello.nextProtoNeg {
-		c.sendAlert(alertHandshakeFailure)
-		return false, errors.New("server advertised unrequested NPN extension")
-	}
-
-	if hs.serverResumedSession() {
-		// Restore masterSecret and peerCerts from previous state
-		hs.masterSecret = hs.session.masterSecret
-		c.peerCertificates = hs.session.serverCertificates
-		return true, nil
-	}
-	return false, nil
-}
-
-func (hs *clientHandshakeState) readFinished() error {
-	c := hs.c
-
-	c.readRecord(recordTypeChangeCipherSpec)
-	if err := c.in.error(); err != nil {
-		return err
-	}
-
-	msg, err := c.readHandshake()
-	if err != nil {
-		return err
-	}
-	serverFinished, ok := msg.(*finishedMsg)
-	if !ok {
-		c.sendAlert(alertUnexpectedMessage)
-		return unexpectedMessageError(serverFinished, msg)
-	}
-
-	verify := hs.finishedHash.serverSum(hs.masterSecret)
-	if len(verify) != len(serverFinished.verifyData) ||
-		subtle.ConstantTimeCompare(verify, serverFinished.verifyData) != 1 {
-		c.sendAlert(alertHandshakeFailure)
-		return errors.New("tls: server's Finished message was incorrect")
-	}
-	hs.finishedHash.Write(serverFinished.marshal())
-	return nil
-}
-
-func (hs *clientHandshakeState) readSessionTicket() error {
-	if !hs.serverHello.ticketSupported {
-		return nil
-	}
-
-	c := hs.c
-	msg, err := c.readHandshake()
-	if err != nil {
-		return err
-	}
-	sessionTicketMsg, ok := msg.(*newSessionTicketMsg)
-	if !ok {
-		c.sendAlert(alertUnexpectedMessage)
-		return unexpectedMessageError(sessionTicketMsg, msg)
-	}
-	hs.finishedHash.Write(sessionTicketMsg.marshal())
-
-	hs.session = &ClientSessionState{
-		sessionTicket:      sessionTicketMsg.ticket,
-		vers:               c.vers,
-		cipherSuite:        hs.suite.id,
-		masterSecret:       hs.masterSecret,
-		serverCertificates: c.peerCertificates,
-	}
-
-	return nil
-}
-
-func (hs *clientHandshakeState) sendFinished() error {
-	c := hs.c
-
-	c.writeRecord(recordTypeChangeCipherSpec, []byte{1})
-	if hs.serverHello.nextProtoNeg {
-		nextProto := new(nextProtoMsg)
-		proto, fallback := mutualProtocol(c.config.NextProtos, hs.serverHello.nextProtos)
-		nextProto.proto = proto
-		c.clientProtocol = proto
-		c.clientProtocolFallback = fallback
-
-		hs.finishedHash.Write(nextProto.marshal())
-		c.writeRecord(recordTypeHandshake, nextProto.marshal())
-	}
-
-	finished := new(finishedMsg)
-	finished.verifyData = hs.finishedHash.clientSum(hs.masterSecret)
-	hs.finishedHash.Write(finished.marshal())
-	c.writeRecord(recordTypeHandshake, finished.marshal())
-	return nil
-}
-
-// clientSessionCacheKey returns a key used to cache sessionTickets that could
-// be used to resume previously negotiated TLS sessions with a server.
-func clientSessionCacheKey(serverAddr net.Addr, config *Config) string {
-	if len(config.ServerName) > 0 {
-		return config.ServerName
-	}
-	return serverAddr.String()
-}
-
-// mutualProtocol finds the mutual Next Protocol Negotiation protocol given the
-// set of client and server supported protocols. The set of client supported
-// protocols must not be empty. It returns the resulting protocol and flag
-// indicating if the fallback case was reached.
-func mutualProtocol(clientProtos, serverProtos []string) (string, bool) {
-	for _, s := range serverProtos {
-		for _, c := range clientProtos {
-			if s == c {
-				return s, false
-			}
-		}
-	}
-
-	return clientProtos[0], true
-}
diff --git a/src/pkg/crypto/tls/handshake_client_test.go b/src/pkg/crypto/tls/handshake_client_test.go
deleted file mode 100644
index 0d73c8e..0000000
--- a/src/pkg/crypto/tls/handshake_client_test.go
+++ /dev/null
@@ -1,439 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package tls
-
-import (
-	"bytes"
-	"crypto/ecdsa"
-	"crypto/rsa"
-	"crypto/x509"
-	"encoding/pem"
-	"fmt"
-	"io"
-	"net"
-	"os"
-	"os/exec"
-	"path/filepath"
-	"strconv"
-	"testing"
-	"time"
-)
-
-// Note: see comment in handshake_test.go for details of how the reference
-// tests work.
-
-// blockingSource is an io.Reader that blocks a Read call until it's closed.
-type blockingSource chan bool
-
-func (b blockingSource) Read([]byte) (n int, err error) {
-	<-b
-	return 0, io.EOF
-}
-
-// clientTest represents a test of the TLS client handshake against a reference
-// implementation.
-type clientTest struct {
-	// name is a freeform string identifying the test and the file in which
-	// the expected results will be stored.
-	name string
-	// command, if not empty, contains a series of arguments for the
-	// command to run for the reference server.
-	command []string
-	// config, if not nil, contains a custom Config to use for this test.
-	config *Config
-	// cert, if not empty, contains a DER-encoded certificate for the
-	// reference server.
-	cert []byte
-	// key, if not nil, contains either a *rsa.PrivateKey or
-	// *ecdsa.PrivateKey which is the private key for the reference server.
-	key interface{}
-}
-
-var defaultServerCommand = []string{"openssl", "s_server"}
-
-// connFromCommand starts the reference server process, connects to it and
-// returns a recordingConn for the connection. The stdin return value is a
-// blockingSource for the stdin of the child process. It must be closed before
-// Waiting for child.
-func (test *clientTest) connFromCommand() (conn *recordingConn, child *exec.Cmd, stdin blockingSource, err error) {
-	cert := testRSACertificate
-	if len(test.cert) > 0 {
-		cert = test.cert
-	}
-	certPath := tempFile(string(cert))
-	defer os.Remove(certPath)
-
-	var key interface{} = testRSAPrivateKey
-	if test.key != nil {
-		key = test.key
-	}
-	var pemType string
-	var derBytes []byte
-	switch key := key.(type) {
-	case *rsa.PrivateKey:
-		pemType = "RSA"
-		derBytes = x509.MarshalPKCS1PrivateKey(key)
-	case *ecdsa.PrivateKey:
-		pemType = "EC"
-		var err error
-		derBytes, err = x509.MarshalECPrivateKey(key)
-		if err != nil {
-			panic(err)
-		}
-	default:
-		panic("unknown key type")
-	}
-
-	var pemOut bytes.Buffer
-	pem.Encode(&pemOut, &pem.Block{Type: pemType + " PRIVATE KEY", Bytes: derBytes})
-
-	keyPath := tempFile(string(pemOut.Bytes()))
-	defer os.Remove(keyPath)
-
-	var command []string
-	if len(test.command) > 0 {
-		command = append(command, test.command...)
-	} else {
-		command = append(command, defaultServerCommand...)
-	}
-	command = append(command, "-cert", certPath, "-certform", "DER", "-key", keyPath)
-	// serverPort contains the port that OpenSSL will listen on. OpenSSL
-	// can't take "0" as an argument here so we have to pick a number and
-	// hope that it's not in use on the machine. Since this only occurs
-	// when -update is given and thus when there's a human watching the
-	// test, this isn't too bad.
-	const serverPort = 24323
-	command = append(command, "-accept", strconv.Itoa(serverPort))
-
-	cmd := exec.Command(command[0], command[1:]...)
-	stdin = blockingSource(make(chan bool))
-	cmd.Stdin = stdin
-	var out bytes.Buffer
-	cmd.Stdout = &out
-	cmd.Stderr = &out
-	if err := cmd.Start(); err != nil {
-		return nil, nil, nil, err
-	}
-
-	// OpenSSL does print an "ACCEPT" banner, but it does so *before*
-	// opening the listening socket, so we can't use that to wait until it
-	// has started listening. Thus we are forced to poll until we get a
-	// connection.
-	var tcpConn net.Conn
-	for i := uint(0); i < 5; i++ {
-		var err error
-		tcpConn, err = net.DialTCP("tcp", nil, &net.TCPAddr{
-			IP:   net.IPv4(127, 0, 0, 1),
-			Port: serverPort,
-		})
-		if err == nil {
-			break
-		}
-		time.Sleep((1 << i) * 5 * time.Millisecond)
-	}
-	if tcpConn == nil {
-		close(stdin)
-		out.WriteTo(os.Stdout)
-		cmd.Process.Kill()
-		return nil, nil, nil, cmd.Wait()
-	}
-
-	record := &recordingConn{
-		Conn: tcpConn,
-	}
-
-	return record, cmd, stdin, nil
-}
-
-func (test *clientTest) dataPath() string {
-	return filepath.Join("testdata", "Client-"+test.name)
-}
-
-func (test *clientTest) loadData() (flows [][]byte, err error) {
-	in, err := os.Open(test.dataPath())
-	if err != nil {
-		return nil, err
-	}
-	defer in.Close()
-	return parseTestData(in)
-}
-
-func (test *clientTest) run(t *testing.T, write bool) {
-	var clientConn, serverConn net.Conn
-	var recordingConn *recordingConn
-	var childProcess *exec.Cmd
-	var stdin blockingSource
-
-	if write {
-		var err error
-		recordingConn, childProcess, stdin, err = test.connFromCommand()
-		if err != nil {
-			t.Fatalf("Failed to start subcommand: %s", err)
-		}
-		clientConn = recordingConn
-	} else {
-		clientConn, serverConn = net.Pipe()
-	}
-
-	config := test.config
-	if config == nil {
-		config = testConfig
-	}
-	client := Client(clientConn, config)
-
-	doneChan := make(chan bool)
-	go func() {
-		if _, err := client.Write([]byte("hello\n")); err != nil {
-			t.Logf("Client.Write failed: %s", err)
-		}
-		client.Close()
-		clientConn.Close()
-		doneChan <- true
-	}()
-
-	if !write {
-		flows, err := test.loadData()
-		if err != nil {
-			t.Fatalf("%s: failed to load data from %s", test.name, test.dataPath())
-		}
-		for i, b := range flows {
-			if i%2 == 1 {
-				serverConn.Write(b)
-				continue
-			}
-			bb := make([]byte, len(b))
-			_, err := io.ReadFull(serverConn, bb)
-			if err != nil {
-				t.Fatalf("%s #%d: %s", test.name, i, err)
-			}
-			if !bytes.Equal(b, bb) {
-				t.Fatalf("%s #%d: mismatch on read: got:%x want:%x", test.name, i, bb, b)
-			}
-		}
-		serverConn.Close()
-	}
-
-	<-doneChan
-
-	if write {
-		path := test.dataPath()
-		out, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
-		if err != nil {
-			t.Fatalf("Failed to create output file: %s", err)
-		}
-		defer out.Close()
-		recordingConn.Close()
-		close(stdin)
-		childProcess.Process.Kill()
-		childProcess.Wait()
-		if len(recordingConn.flows) < 3 {
-			childProcess.Stdout.(*bytes.Buffer).WriteTo(os.Stdout)
-			t.Fatalf("Client connection didn't work")
-		}
-		recordingConn.WriteTo(out)
-		fmt.Printf("Wrote %s\n", path)
-	}
-}
-
-func runClientTestForVersion(t *testing.T, template *clientTest, prefix, option string) {
-	test := *template
-	test.name = prefix + test.name
-	if len(test.command) == 0 {
-		test.command = defaultClientCommand
-	}
-	test.command = append([]string(nil), test.command...)
-	test.command = append(test.command, option)
-	test.run(t, *update)
-}
-
-func runClientTestTLS10(t *testing.T, template *clientTest) {
-	runClientTestForVersion(t, template, "TLSv10-", "-tls1")
-}
-
-func runClientTestTLS11(t *testing.T, template *clientTest) {
-	runClientTestForVersion(t, template, "TLSv11-", "-tls1_1")
-}
-
-func runClientTestTLS12(t *testing.T, template *clientTest) {
-	runClientTestForVersion(t, template, "TLSv12-", "-tls1_2")
-}
-
-func TestHandshakeClientRSARC4(t *testing.T) {
-	test := &clientTest{
-		name:    "RSA-RC4",
-		command: []string{"openssl", "s_server", "-cipher", "RC4-SHA"},
-	}
-	runClientTestTLS10(t, test)
-	runClientTestTLS11(t, test)
-	runClientTestTLS12(t, test)
-}
-
-func TestHandshakeClientECDHERSAAES(t *testing.T) {
-	test := &clientTest{
-		name:    "ECDHE-RSA-AES",
-		command: []string{"openssl", "s_server", "-cipher", "ECDHE-RSA-AES128-SHA"},
-	}
-	runClientTestTLS10(t, test)
-	runClientTestTLS11(t, test)
-	runClientTestTLS12(t, test)
-}
-
-func TestHandshakeClientECDHEECDSAAES(t *testing.T) {
-	test := &clientTest{
-		name:    "ECDHE-ECDSA-AES",
-		command: []string{"openssl", "s_server", "-cipher", "ECDHE-ECDSA-AES128-SHA"},
-		cert:    testECDSACertificate,
-		key:     testECDSAPrivateKey,
-	}
-	runClientTestTLS10(t, test)
-	runClientTestTLS11(t, test)
-	runClientTestTLS12(t, test)
-}
-
-func TestHandshakeClientECDHEECDSAAESGCM(t *testing.T) {
-	test := &clientTest{
-		name:    "ECDHE-ECDSA-AES-GCM",
-		command: []string{"openssl", "s_server", "-cipher", "ECDHE-ECDSA-AES128-GCM-SHA256"},
-		cert:    testECDSACertificate,
-		key:     testECDSAPrivateKey,
-	}
-	runClientTestTLS12(t, test)
-}
-
-func TestHandshakeClientCertRSA(t *testing.T) {
-	config := *testConfig
-	cert, _ := X509KeyPair([]byte(clientCertificatePEM), []byte(clientKeyPEM))
-	config.Certificates = []Certificate{cert}
-
-	test := &clientTest{
-		name:    "ClientCert-RSA-RSA",
-		command: []string{"openssl", "s_server", "-cipher", "RC4-SHA", "-verify", "1"},
-		config:  &config,
-	}
-
-	runClientTestTLS10(t, test)
-	runClientTestTLS12(t, test)
-
-	test = &clientTest{
-		name:    "ClientCert-RSA-ECDSA",
-		command: []string{"openssl", "s_server", "-cipher", "ECDHE-ECDSA-AES128-SHA", "-verify", "1"},
-		config:  &config,
-		cert:    testECDSACertificate,
-		key:     testECDSAPrivateKey,
-	}
-
-	runClientTestTLS10(t, test)
-	runClientTestTLS12(t, test)
-}
-
-func TestHandshakeClientCertECDSA(t *testing.T) {
-	config := *testConfig
-	cert, _ := X509KeyPair([]byte(clientECDSACertificatePEM), []byte(clientECDSAKeyPEM))
-	config.Certificates = []Certificate{cert}
-
-	test := &clientTest{
-		name:    "ClientCert-ECDSA-RSA",
-		command: []string{"openssl", "s_server", "-cipher", "RC4-SHA", "-verify", "1"},
-		config:  &config,
-	}
-
-	runClientTestTLS10(t, test)
-	runClientTestTLS12(t, test)
-
-	test = &clientTest{
-		name:    "ClientCert-ECDSA-ECDSA",
-		command: []string{"openssl", "s_server", "-cipher", "ECDHE-ECDSA-AES128-SHA", "-verify", "1"},
-		config:  &config,
-		cert:    testECDSACertificate,
-		key:     testECDSAPrivateKey,
-	}
-
-	runClientTestTLS10(t, test)
-	runClientTestTLS12(t, test)
-}
-
-func TestClientResumption(t *testing.T) {
-	serverConfig := &Config{
-		CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA},
-		Certificates: testConfig.Certificates,
-	}
-	clientConfig := &Config{
-		CipherSuites:       []uint16{TLS_RSA_WITH_RC4_128_SHA},
-		InsecureSkipVerify: true,
-		ClientSessionCache: NewLRUClientSessionCache(32),
-	}
-
-	testResumeState := func(test string, didResume bool) {
-		hs, err := testHandshake(clientConfig, serverConfig)
-		if err != nil {
-			t.Fatalf("%s: handshake failed: %s", test, err)
-		}
-		if hs.DidResume != didResume {
-			t.Fatalf("%s resumed: %v, expected: %v", test, hs.DidResume, didResume)
-		}
-	}
-
-	testResumeState("Handshake", false)
-	testResumeState("Resume", true)
-
-	if _, err := io.ReadFull(serverConfig.rand(), serverConfig.SessionTicketKey[:]); err != nil {
-		t.Fatalf("Failed to invalidate SessionTicketKey")
-	}
-	testResumeState("InvalidSessionTicketKey", false)
-	testResumeState("ResumeAfterInvalidSessionTicketKey", true)
-
-	clientConfig.CipherSuites = []uint16{TLS_ECDHE_RSA_WITH_RC4_128_SHA}
-	testResumeState("DifferentCipherSuite", false)
-	testResumeState("DifferentCipherSuiteRecovers", true)
-
-	clientConfig.ClientSessionCache = nil
-	testResumeState("WithoutSessionCache", false)
-}
-
-func TestLRUClientSessionCache(t *testing.T) {
-	// Initialize cache of capacity 4.
-	cache := NewLRUClientSessionCache(4)
-	cs := make([]ClientSessionState, 6)
-	keys := []string{"0", "1", "2", "3", "4", "5", "6"}
-
-	// Add 4 entries to the cache and look them up.
-	for i := 0; i < 4; i++ {
-		cache.Put(keys[i], &cs[i])
-	}
-	for i := 0; i < 4; i++ {
-		if s, ok := cache.Get(keys[i]); !ok || s != &cs[i] {
-			t.Fatalf("session cache failed lookup for added key: %s", keys[i])
-		}
-	}
-
-	// Add 2 more entries to the cache. First 2 should be evicted.
-	for i := 4; i < 6; i++ {
-		cache.Put(keys[i], &cs[i])
-	}
-	for i := 0; i < 2; i++ {
-		if s, ok := cache.Get(keys[i]); ok || s != nil {
-			t.Fatalf("session cache should have evicted key: %s", keys[i])
-		}
-	}
-
-	// Touch entry 2. LRU should evict 3 next.
-	cache.Get(keys[2])
-	cache.Put(keys[0], &cs[0])
-	if s, ok := cache.Get(keys[3]); ok || s != nil {
-		t.Fatalf("session cache should have evicted key 3")
-	}
-
-	// Update entry 0 in place.
-	cache.Put(keys[0], &cs[3])
-	if s, ok := cache.Get(keys[0]); !ok || s != &cs[3] {
-		t.Fatalf("session cache failed update for key 0")
-	}
-
-	// Adding a nil entry is valid.
-	cache.Put(keys[0], nil)
-	if s, ok := cache.Get(keys[0]); !ok || s != nil {
-		t.Fatalf("failed to add nil entry to cache")
-	}
-}
diff --git a/src/pkg/crypto/tls/handshake_messages.go b/src/pkg/crypto/tls/handshake_messages.go
deleted file mode 100644
index 7bcaa5e..0000000
--- a/src/pkg/crypto/tls/handshake_messages.go
+++ /dev/null
@@ -1,1344 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package tls
-
-import "bytes"
-
-type clientHelloMsg struct {
-	raw                 []byte
-	vers                uint16
-	random              []byte
-	sessionId           []byte
-	cipherSuites        []uint16
-	compressionMethods  []uint8
-	nextProtoNeg        bool
-	serverName          string
-	ocspStapling        bool
-	supportedCurves     []CurveID
-	supportedPoints     []uint8
-	ticketSupported     bool
-	sessionTicket       []uint8
-	signatureAndHashes  []signatureAndHash
-	secureRenegotiation bool
-}
-
-func (m *clientHelloMsg) equal(i interface{}) bool {
-	m1, ok := i.(*clientHelloMsg)
-	if !ok {
-		return false
-	}
-
-	return bytes.Equal(m.raw, m1.raw) &&
-		m.vers == m1.vers &&
-		bytes.Equal(m.random, m1.random) &&
-		bytes.Equal(m.sessionId, m1.sessionId) &&
-		eqUint16s(m.cipherSuites, m1.cipherSuites) &&
-		bytes.Equal(m.compressionMethods, m1.compressionMethods) &&
-		m.nextProtoNeg == m1.nextProtoNeg &&
-		m.serverName == m1.serverName &&
-		m.ocspStapling == m1.ocspStapling &&
-		eqCurveIDs(m.supportedCurves, m1.supportedCurves) &&
-		bytes.Equal(m.supportedPoints, m1.supportedPoints) &&
-		m.ticketSupported == m1.ticketSupported &&
-		bytes.Equal(m.sessionTicket, m1.sessionTicket) &&
-		eqSignatureAndHashes(m.signatureAndHashes, m1.signatureAndHashes) &&
-		m.secureRenegotiation == m1.secureRenegotiation
-}
-
-func (m *clientHelloMsg) marshal() []byte {
-	if m.raw != nil {
-		return m.raw
-	}
-
-	length := 2 + 32 + 1 + len(m.sessionId) + 2 + len(m.cipherSuites)*2 + 1 + len(m.compressionMethods)
-	numExtensions := 0
-	extensionsLength := 0
-	if m.nextProtoNeg {
-		numExtensions++
-	}
-	if m.ocspStapling {
-		extensionsLength += 1 + 2 + 2
-		numExtensions++
-	}
-	if len(m.serverName) > 0 {
-		extensionsLength += 5 + len(m.serverName)
-		numExtensions++
-	}
-	if len(m.supportedCurves) > 0 {
-		extensionsLength += 2 + 2*len(m.supportedCurves)
-		numExtensions++
-	}
-	if len(m.supportedPoints) > 0 {
-		extensionsLength += 1 + len(m.supportedPoints)
-		numExtensions++
-	}
-	if m.ticketSupported {
-		extensionsLength += len(m.sessionTicket)
-		numExtensions++
-	}
-	if len(m.signatureAndHashes) > 0 {
-		extensionsLength += 2 + 2*len(m.signatureAndHashes)
-		numExtensions++
-	}
-	if m.secureRenegotiation {
-		extensionsLength += 1
-		numExtensions++
-	}
-	if numExtensions > 0 {
-		extensionsLength += 4 * numExtensions
-		length += 2 + extensionsLength
-	}
-
-	x := make([]byte, 4+length)
-	x[0] = typeClientHello
-	x[1] = uint8(length >> 16)
-	x[2] = uint8(length >> 8)
-	x[3] = uint8(length)
-	x[4] = uint8(m.vers >> 8)
-	x[5] = uint8(m.vers)
-	copy(x[6:38], m.random)
-	x[38] = uint8(len(m.sessionId))
-	copy(x[39:39+len(m.sessionId)], m.sessionId)
-	y := x[39+len(m.sessionId):]
-	y[0] = uint8(len(m.cipherSuites) >> 7)
-	y[1] = uint8(len(m.cipherSuites) << 1)
-	for i, suite := range m.cipherSuites {
-		y[2+i*2] = uint8(suite >> 8)
-		y[3+i*2] = uint8(suite)
-	}
-	z := y[2+len(m.cipherSuites)*2:]
-	z[0] = uint8(len(m.compressionMethods))
-	copy(z[1:], m.compressionMethods)
-
-	z = z[1+len(m.compressionMethods):]
-	if numExtensions > 0 {
-		z[0] = byte(extensionsLength >> 8)
-		z[1] = byte(extensionsLength)
-		z = z[2:]
-	}
-	if m.nextProtoNeg {
-		z[0] = byte(extensionNextProtoNeg >> 8)
-		z[1] = byte(extensionNextProtoNeg & 0xff)
-		// The length is always 0
-		z = z[4:]
-	}
-	if len(m.serverName) > 0 {
-		z[0] = byte(extensionServerName >> 8)
-		z[1] = byte(extensionServerName & 0xff)
-		l := len(m.serverName) + 5
-		z[2] = byte(l >> 8)
-		z[3] = byte(l)
-		z = z[4:]
-
-		// RFC 3546, section 3.1
-		//
-		// struct {
-		//     NameType name_type;
-		//     select (name_type) {
-		//         case host_name: HostName;
-		//     } name;
-		// } ServerName;
-		//
-		// enum {
-		//     host_name(0), (255)
-		// } NameType;
-		//
-		// opaque HostName<1..2^16-1>;
-		//
-		// struct {
-		//     ServerName server_name_list<1..2^16-1>
-		// } ServerNameList;
-
-		z[0] = byte((len(m.serverName) + 3) >> 8)
-		z[1] = byte(len(m.serverName) + 3)
-		z[3] = byte(len(m.serverName) >> 8)
-		z[4] = byte(len(m.serverName))
-		copy(z[5:], []byte(m.serverName))
-		z = z[l:]
-	}
-	if m.ocspStapling {
-		// RFC 4366, section 3.6
-		z[0] = byte(extensionStatusRequest >> 8)
-		z[1] = byte(extensionStatusRequest)
-		z[2] = 0
-		z[3] = 5
-		z[4] = 1 // OCSP type
-		// Two zero valued uint16s for the two lengths.
-		z = z[9:]
-	}
-	if len(m.supportedCurves) > 0 {
-		// http://tools.ietf.org/html/rfc4492#section-5.5.1
-		z[0] = byte(extensionSupportedCurves >> 8)
-		z[1] = byte(extensionSupportedCurves)
-		l := 2 + 2*len(m.supportedCurves)
-		z[2] = byte(l >> 8)
-		z[3] = byte(l)
-		l -= 2
-		z[4] = byte(l >> 8)
-		z[5] = byte(l)
-		z = z[6:]
-		for _, curve := range m.supportedCurves {
-			z[0] = byte(curve >> 8)
-			z[1] = byte(curve)
-			z = z[2:]
-		}
-	}
-	if len(m.supportedPoints) > 0 {
-		// http://tools.ietf.org/html/rfc4492#section-5.5.2
-		z[0] = byte(extensionSupportedPoints >> 8)
-		z[1] = byte(extensionSupportedPoints)
-		l := 1 + len(m.supportedPoints)
-		z[2] = byte(l >> 8)
-		z[3] = byte(l)
-		l--
-		z[4] = byte(l)
-		z = z[5:]
-		for _, pointFormat := range m.supportedPoints {
-			z[0] = byte(pointFormat)
-			z = z[1:]
-		}
-	}
-	if m.ticketSupported {
-		// http://tools.ietf.org/html/rfc5077#section-3.2
-		z[0] = byte(extensionSessionTicket >> 8)
-		z[1] = byte(extensionSessionTicket)
-		l := len(m.sessionTicket)
-		z[2] = byte(l >> 8)
-		z[3] = byte(l)
-		z = z[4:]
-		copy(z, m.sessionTicket)
-		z = z[len(m.sessionTicket):]
-	}
-	if len(m.signatureAndHashes) > 0 {
-		// https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
-		z[0] = byte(extensionSignatureAlgorithms >> 8)
-		z[1] = byte(extensionSignatureAlgorithms)
-		l := 2 + 2*len(m.signatureAndHashes)
-		z[2] = byte(l >> 8)
-		z[3] = byte(l)
-		z = z[4:]
-
-		l -= 2
-		z[0] = byte(l >> 8)
-		z[1] = byte(l)
-		z = z[2:]
-		for _, sigAndHash := range m.signatureAndHashes {
-			z[0] = sigAndHash.hash
-			z[1] = sigAndHash.signature
-			z = z[2:]
-		}
-	}
-	if m.secureRenegotiation {
-		z[0] = byte(extensionRenegotiationInfo >> 8)
-		z[1] = byte(extensionRenegotiationInfo & 0xff)
-		z[2] = 0
-		z[3] = 1
-		z = z[5:]
-	}
-
-	m.raw = x
-
-	return x
-}
-
-func (m *clientHelloMsg) unmarshal(data []byte) bool {
-	if len(data) < 42 {
-		return false
-	}
-	m.raw = data
-	m.vers = uint16(data[4])<<8 | uint16(data[5])
-	m.random = data[6:38]
-	sessionIdLen := int(data[38])
-	if sessionIdLen > 32 || len(data) < 39+sessionIdLen {
-		return false
-	}
-	m.sessionId = data[39 : 39+sessionIdLen]
-	data = data[39+sessionIdLen:]
-	if len(data) < 2 {
-		return false
-	}
-	// cipherSuiteLen is the number of bytes of cipher suite numbers. Since
-	// they are uint16s, the number must be even.
-	cipherSuiteLen := int(data[0])<<8 | int(data[1])
-	if cipherSuiteLen%2 == 1 || len(data) < 2+cipherSuiteLen {
-		return false
-	}
-	numCipherSuites := cipherSuiteLen / 2
-	m.cipherSuites = make([]uint16, numCipherSuites)
-	for i := 0; i < numCipherSuites; i++ {
-		m.cipherSuites[i] = uint16(data[2+2*i])<<8 | uint16(data[3+2*i])
-		if m.cipherSuites[i] == scsvRenegotiation {
-			m.secureRenegotiation = true
-		}
-	}
-	data = data[2+cipherSuiteLen:]
-	if len(data) < 1 {
-		return false
-	}
-	compressionMethodsLen := int(data[0])
-	if len(data) < 1+compressionMethodsLen {
-		return false
-	}
-	m.compressionMethods = data[1 : 1+compressionMethodsLen]
-
-	data = data[1+compressionMethodsLen:]
-
-	m.nextProtoNeg = false
-	m.serverName = ""
-	m.ocspStapling = false
-	m.ticketSupported = false
-	m.sessionTicket = nil
-	m.signatureAndHashes = nil
-
-	if len(data) == 0 {
-		// ClientHello is optionally followed by extension data
-		return true
-	}
-	if len(data) < 2 {
-		return false
-	}
-
-	extensionsLength := int(data[0])<<8 | int(data[1])
-	data = data[2:]
-	if extensionsLength != len(data) {
-		return false
-	}
-
-	for len(data) != 0 {
-		if len(data) < 4 {
-			return false
-		}
-		extension := uint16(data[0])<<8 | uint16(data[1])
-		length := int(data[2])<<8 | int(data[3])
-		data = data[4:]
-		if len(data) < length {
-			return false
-		}
-
-		switch extension {
-		case extensionServerName:
-			if length < 2 {
-				return false
-			}
-			numNames := int(data[0])<<8 | int(data[1])
-			d := data[2:]
-			for i := 0; i < numNames; i++ {
-				if len(d) < 3 {
-					return false
-				}
-				nameType := d[0]
-				nameLen := int(d[1])<<8 | int(d[2])
-				d = d[3:]
-				if len(d) < nameLen {
-					return false
-				}
-				if nameType == 0 {
-					m.serverName = string(d[0:nameLen])
-					break
-				}
-				d = d[nameLen:]
-			}
-		case extensionNextProtoNeg:
-			if length > 0 {
-				return false
-			}
-			m.nextProtoNeg = true
-		case extensionStatusRequest:
-			m.ocspStapling = length > 0 && data[0] == statusTypeOCSP
-		case extensionSupportedCurves:
-			// http://tools.ietf.org/html/rfc4492#section-5.5.1
-			if length < 2 {
-				return false
-			}
-			l := int(data[0])<<8 | int(data[1])
-			if l%2 == 1 || length != l+2 {
-				return false
-			}
-			numCurves := l / 2
-			m.supportedCurves = make([]CurveID, numCurves)
-			d := data[2:]
-			for i := 0; i < numCurves; i++ {
-				m.supportedCurves[i] = CurveID(d[0])<<8 | CurveID(d[1])
-				d = d[2:]
-			}
-		case extensionSupportedPoints:
-			// http://tools.ietf.org/html/rfc4492#section-5.5.2
-			if length < 1 {
-				return false
-			}
-			l := int(data[0])
-			if length != l+1 {
-				return false
-			}
-			m.supportedPoints = make([]uint8, l)
-			copy(m.supportedPoints, data[1:])
-		case extensionSessionTicket:
-			// http://tools.ietf.org/html/rfc5077#section-3.2
-			m.ticketSupported = true
-			m.sessionTicket = data[:length]
-		case extensionSignatureAlgorithms:
-			// https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
-			if length < 2 || length&1 != 0 {
-				return false
-			}
-			l := int(data[0])<<8 | int(data[1])
-			if l != length-2 {
-				return false
-			}
-			n := l / 2
-			d := data[2:]
-			m.signatureAndHashes = make([]signatureAndHash, n)
-			for i := range m.signatureAndHashes {
-				m.signatureAndHashes[i].hash = d[0]
-				m.signatureAndHashes[i].signature = d[1]
-				d = d[2:]
-			}
-		case extensionRenegotiationInfo + 1:
-			if length != 1 || data[0] != 0 {
-				return false
-			}
-			m.secureRenegotiation = true
-		}
-		data = data[length:]
-	}
-
-	return true
-}
-
-type serverHelloMsg struct {
-	raw                 []byte
-	vers                uint16
-	random              []byte
-	sessionId           []byte
-	cipherSuite         uint16
-	compressionMethod   uint8
-	nextProtoNeg        bool
-	nextProtos          []string
-	ocspStapling        bool
-	ticketSupported     bool
-	secureRenegotiation bool
-}
-
-func (m *serverHelloMsg) equal(i interface{}) bool {
-	m1, ok := i.(*serverHelloMsg)
-	if !ok {
-		return false
-	}
-
-	return bytes.Equal(m.raw, m1.raw) &&
-		m.vers == m1.vers &&
-		bytes.Equal(m.random, m1.random) &&
-		bytes.Equal(m.sessionId, m1.sessionId) &&
-		m.cipherSuite == m1.cipherSuite &&
-		m.compressionMethod == m1.compressionMethod &&
-		m.nextProtoNeg == m1.nextProtoNeg &&
-		eqStrings(m.nextProtos, m1.nextProtos) &&
-		m.ocspStapling == m1.ocspStapling &&
-		m.ticketSupported == m1.ticketSupported &&
-		m.secureRenegotiation == m1.secureRenegotiation
-}
-
-func (m *serverHelloMsg) marshal() []byte {
-	if m.raw != nil {
-		return m.raw
-	}
-
-	length := 38 + len(m.sessionId)
-	numExtensions := 0
-	extensionsLength := 0
-
-	nextProtoLen := 0
-	if m.nextProtoNeg {
-		numExtensions++
-		for _, v := range m.nextProtos {
-			nextProtoLen += len(v)
-		}
-		nextProtoLen += len(m.nextProtos)
-		extensionsLength += nextProtoLen
-	}
-	if m.ocspStapling {
-		numExtensions++
-	}
-	if m.ticketSupported {
-		numExtensions++
-	}
-	if m.secureRenegotiation {
-		extensionsLength += 1
-		numExtensions++
-	}
-	if numExtensions > 0 {
-		extensionsLength += 4 * numExtensions
-		length += 2 + extensionsLength
-	}
-
-	x := make([]byte, 4+length)
-	x[0] = typeServerHello
-	x[1] = uint8(length >> 16)
-	x[2] = uint8(length >> 8)
-	x[3] = uint8(length)
-	x[4] = uint8(m.vers >> 8)
-	x[5] = uint8(m.vers)
-	copy(x[6:38], m.random)
-	x[38] = uint8(len(m.sessionId))
-	copy(x[39:39+len(m.sessionId)], m.sessionId)
-	z := x[39+len(m.sessionId):]
-	z[0] = uint8(m.cipherSuite >> 8)
-	z[1] = uint8(m.cipherSuite)
-	z[2] = uint8(m.compressionMethod)
-
-	z = z[3:]
-	if numExtensions > 0 {
-		z[0] = byte(extensionsLength >> 8)
-		z[1] = byte(extensionsLength)
-		z = z[2:]
-	}
-	if m.nextProtoNeg {
-		z[0] = byte(extensionNextProtoNeg >> 8)
-		z[1] = byte(extensionNextProtoNeg & 0xff)
-		z[2] = byte(nextProtoLen >> 8)
-		z[3] = byte(nextProtoLen)
-		z = z[4:]
-
-		for _, v := range m.nextProtos {
-			l := len(v)
-			if l > 255 {
-				l = 255
-			}
-			z[0] = byte(l)
-			copy(z[1:], []byte(v[0:l]))
-			z = z[1+l:]
-		}
-	}
-	if m.ocspStapling {
-		z[0] = byte(extensionStatusRequest >> 8)
-		z[1] = byte(extensionStatusRequest)
-		z = z[4:]
-	}
-	if m.ticketSupported {
-		z[0] = byte(extensionSessionTicket >> 8)
-		z[1] = byte(extensionSessionTicket)
-		z = z[4:]
-	}
-	if m.secureRenegotiation {
-		z[0] = byte(extensionRenegotiationInfo >> 8)
-		z[1] = byte(extensionRenegotiationInfo & 0xff)
-		z[2] = 0
-		z[3] = 1
-		z = z[5:]
-	}
-
-	m.raw = x
-
-	return x
-}
-
-func (m *serverHelloMsg) unmarshal(data []byte) bool {
-	if len(data) < 42 {
-		return false
-	}
-	m.raw = data
-	m.vers = uint16(data[4])<<8 | uint16(data[5])
-	m.random = data[6:38]
-	sessionIdLen := int(data[38])
-	if sessionIdLen > 32 || len(data) < 39+sessionIdLen {
-		return false
-	}
-	m.sessionId = data[39 : 39+sessionIdLen]
-	data = data[39+sessionIdLen:]
-	if len(data) < 3 {
-		return false
-	}
-	m.cipherSuite = uint16(data[0])<<8 | uint16(data[1])
-	m.compressionMethod = data[2]
-	data = data[3:]
-
-	m.nextProtoNeg = false
-	m.nextProtos = nil
-	m.ocspStapling = false
-	m.ticketSupported = false
-
-	if len(data) == 0 {
-		// ServerHello is optionally followed by extension data
-		return true
-	}
-	if len(data) < 2 {
-		return false
-	}
-
-	extensionsLength := int(data[0])<<8 | int(data[1])
-	data = data[2:]
-	if len(data) != extensionsLength {
-		return false
-	}
-
-	for len(data) != 0 {
-		if len(data) < 4 {
-			return false
-		}
-		extension := uint16(data[0])<<8 | uint16(data[1])
-		length := int(data[2])<<8 | int(data[3])
-		data = data[4:]
-		if len(data) < length {
-			return false
-		}
-
-		switch extension {
-		case extensionNextProtoNeg:
-			m.nextProtoNeg = true
-			d := data[:length]
-			for len(d) > 0 {
-				l := int(d[0])
-				d = d[1:]
-				if l == 0 || l > len(d) {
-					return false
-				}
-				m.nextProtos = append(m.nextProtos, string(d[:l]))
-				d = d[l:]
-			}
-		case extensionStatusRequest:
-			if length > 0 {
-				return false
-			}
-			m.ocspStapling = true
-		case extensionSessionTicket:
-			if length > 0 {
-				return false
-			}
-			m.ticketSupported = true
-		case extensionRenegotiationInfo:
-			if length != 1 || data[0] != 0 {
-				return false
-			}
-			m.secureRenegotiation = true
-		}
-		data = data[length:]
-	}
-
-	return true
-}
-
-type certificateMsg struct {
-	raw          []byte
-	certificates [][]byte
-}
-
-func (m *certificateMsg) equal(i interface{}) bool {
-	m1, ok := i.(*certificateMsg)
-	if !ok {
-		return false
-	}
-
-	return bytes.Equal(m.raw, m1.raw) &&
-		eqByteSlices(m.certificates, m1.certificates)
-}
-
-func (m *certificateMsg) marshal() (x []byte) {
-	if m.raw != nil {
-		return m.raw
-	}
-
-	var i int
-	for _, slice := range m.certificates {
-		i += len(slice)
-	}
-
-	length := 3 + 3*len(m.certificates) + i
-	x = make([]byte, 4+length)
-	x[0] = typeCertificate
-	x[1] = uint8(length >> 16)
-	x[2] = uint8(length >> 8)
-	x[3] = uint8(length)
-
-	certificateOctets := length - 3
-	x[4] = uint8(certificateOctets >> 16)
-	x[5] = uint8(certificateOctets >> 8)
-	x[6] = uint8(certificateOctets)
-
-	y := x[7:]
-	for _, slice := range m.certificates {
-		y[0] = uint8(len(slice) >> 16)
-		y[1] = uint8(len(slice) >> 8)
-		y[2] = uint8(len(slice))
-		copy(y[3:], slice)
-		y = y[3+len(slice):]
-	}
-
-	m.raw = x
-	return
-}
-
-func (m *certificateMsg) unmarshal(data []byte) bool {
-	if len(data) < 7 {
-		return false
-	}
-
-	m.raw = data
-	certsLen := uint32(data[4])<<16 | uint32(data[5])<<8 | uint32(data[6])
-	if uint32(len(data)) != certsLen+7 {
-		return false
-	}
-
-	numCerts := 0
-	d := data[7:]
-	for certsLen > 0 {
-		if len(d) < 4 {
-			return false
-		}
-		certLen := uint32(d[0])<<16 | uint32(d[1])<<8 | uint32(d[2])
-		if uint32(len(d)) < 3+certLen {
-			return false
-		}
-		d = d[3+certLen:]
-		certsLen -= 3 + certLen
-		numCerts++
-	}
-
-	m.certificates = make([][]byte, numCerts)
-	d = data[7:]
-	for i := 0; i < numCerts; i++ {
-		certLen := uint32(d[0])<<16 | uint32(d[1])<<8 | uint32(d[2])
-		m.certificates[i] = d[3 : 3+certLen]
-		d = d[3+certLen:]
-	}
-
-	return true
-}
-
-type serverKeyExchangeMsg struct {
-	raw []byte
-	key []byte
-}
-
-func (m *serverKeyExchangeMsg) equal(i interface{}) bool {
-	m1, ok := i.(*serverKeyExchangeMsg)
-	if !ok {
-		return false
-	}
-
-	return bytes.Equal(m.raw, m1.raw) &&
-		bytes.Equal(m.key, m1.key)
-}
-
-func (m *serverKeyExchangeMsg) marshal() []byte {
-	if m.raw != nil {
-		return m.raw
-	}
-	length := len(m.key)
-	x := make([]byte, length+4)
-	x[0] = typeServerKeyExchange
-	x[1] = uint8(length >> 16)
-	x[2] = uint8(length >> 8)
-	x[3] = uint8(length)
-	copy(x[4:], m.key)
-
-	m.raw = x
-	return x
-}
-
-func (m *serverKeyExchangeMsg) unmarshal(data []byte) bool {
-	m.raw = data
-	if len(data) < 4 {
-		return false
-	}
-	m.key = data[4:]
-	return true
-}
-
-type certificateStatusMsg struct {
-	raw        []byte
-	statusType uint8
-	response   []byte
-}
-
-func (m *certificateStatusMsg) equal(i interface{}) bool {
-	m1, ok := i.(*certificateStatusMsg)
-	if !ok {
-		return false
-	}
-
-	return bytes.Equal(m.raw, m1.raw) &&
-		m.statusType == m1.statusType &&
-		bytes.Equal(m.response, m1.response)
-}
-
-func (m *certificateStatusMsg) marshal() []byte {
-	if m.raw != nil {
-		return m.raw
-	}
-
-	var x []byte
-	if m.statusType == statusTypeOCSP {
-		x = make([]byte, 4+4+len(m.response))
-		x[0] = typeCertificateStatus
-		l := len(m.response) + 4
-		x[1] = byte(l >> 16)
-		x[2] = byte(l >> 8)
-		x[3] = byte(l)
-		x[4] = statusTypeOCSP
-
-		l -= 4
-		x[5] = byte(l >> 16)
-		x[6] = byte(l >> 8)
-		x[7] = byte(l)
-		copy(x[8:], m.response)
-	} else {
-		x = []byte{typeCertificateStatus, 0, 0, 1, m.statusType}
-	}
-
-	m.raw = x
-	return x
-}
-
-func (m *certificateStatusMsg) unmarshal(data []byte) bool {
-	m.raw = data
-	if len(data) < 5 {
-		return false
-	}
-	m.statusType = data[4]
-
-	m.response = nil
-	if m.statusType == statusTypeOCSP {
-		if len(data) < 8 {
-			return false
-		}
-		respLen := uint32(data[5])<<16 | uint32(data[6])<<8 | uint32(data[7])
-		if uint32(len(data)) != 4+4+respLen {
-			return false
-		}
-		m.response = data[8:]
-	}
-	return true
-}
-
-type serverHelloDoneMsg struct{}
-
-func (m *serverHelloDoneMsg) equal(i interface{}) bool {
-	_, ok := i.(*serverHelloDoneMsg)
-	return ok
-}
-
-func (m *serverHelloDoneMsg) marshal() []byte {
-	x := make([]byte, 4)
-	x[0] = typeServerHelloDone
-	return x
-}
-
-func (m *serverHelloDoneMsg) unmarshal(data []byte) bool {
-	return len(data) == 4
-}
-
-type clientKeyExchangeMsg struct {
-	raw        []byte
-	ciphertext []byte
-}
-
-func (m *clientKeyExchangeMsg) equal(i interface{}) bool {
-	m1, ok := i.(*clientKeyExchangeMsg)
-	if !ok {
-		return false
-	}
-
-	return bytes.Equal(m.raw, m1.raw) &&
-		bytes.Equal(m.ciphertext, m1.ciphertext)
-}
-
-func (m *clientKeyExchangeMsg) marshal() []byte {
-	if m.raw != nil {
-		return m.raw
-	}
-	length := len(m.ciphertext)
-	x := make([]byte, length+4)
-	x[0] = typeClientKeyExchange
-	x[1] = uint8(length >> 16)
-	x[2] = uint8(length >> 8)
-	x[3] = uint8(length)
-	copy(x[4:], m.ciphertext)
-
-	m.raw = x
-	return x
-}
-
-func (m *clientKeyExchangeMsg) unmarshal(data []byte) bool {
-	m.raw = data
-	if len(data) < 4 {
-		return false
-	}
-	l := int(data[1])<<16 | int(data[2])<<8 | int(data[3])
-	if l != len(data)-4 {
-		return false
-	}
-	m.ciphertext = data[4:]
-	return true
-}
-
-type finishedMsg struct {
-	raw        []byte
-	verifyData []byte
-}
-
-func (m *finishedMsg) equal(i interface{}) bool {
-	m1, ok := i.(*finishedMsg)
-	if !ok {
-		return false
-	}
-
-	return bytes.Equal(m.raw, m1.raw) &&
-		bytes.Equal(m.verifyData, m1.verifyData)
-}
-
-func (m *finishedMsg) marshal() (x []byte) {
-	if m.raw != nil {
-		return m.raw
-	}
-
-	x = make([]byte, 4+len(m.verifyData))
-	x[0] = typeFinished
-	x[3] = byte(len(m.verifyData))
-	copy(x[4:], m.verifyData)
-	m.raw = x
-	return
-}
-
-func (m *finishedMsg) unmarshal(data []byte) bool {
-	m.raw = data
-	if len(data) < 4 {
-		return false
-	}
-	m.verifyData = data[4:]
-	return true
-}
-
-type nextProtoMsg struct {
-	raw   []byte
-	proto string
-}
-
-func (m *nextProtoMsg) equal(i interface{}) bool {
-	m1, ok := i.(*nextProtoMsg)
-	if !ok {
-		return false
-	}
-
-	return bytes.Equal(m.raw, m1.raw) &&
-		m.proto == m1.proto
-}
-
-func (m *nextProtoMsg) marshal() []byte {
-	if m.raw != nil {
-		return m.raw
-	}
-	l := len(m.proto)
-	if l > 255 {
-		l = 255
-	}
-
-	padding := 32 - (l+2)%32
-	length := l + padding + 2
-	x := make([]byte, length+4)
-	x[0] = typeNextProtocol
-	x[1] = uint8(length >> 16)
-	x[2] = uint8(length >> 8)
-	x[3] = uint8(length)
-
-	y := x[4:]
-	y[0] = byte(l)
-	copy(y[1:], []byte(m.proto[0:l]))
-	y = y[1+l:]
-	y[0] = byte(padding)
-
-	m.raw = x
-
-	return x
-}
-
-func (m *nextProtoMsg) unmarshal(data []byte) bool {
-	m.raw = data
-
-	if len(data) < 5 {
-		return false
-	}
-	data = data[4:]
-	protoLen := int(data[0])
-	data = data[1:]
-	if len(data) < protoLen {
-		return false
-	}
-	m.proto = string(data[0:protoLen])
-	data = data[protoLen:]
-
-	if len(data) < 1 {
-		return false
-	}
-	paddingLen := int(data[0])
-	data = data[1:]
-	if len(data) != paddingLen {
-		return false
-	}
-
-	return true
-}
-
-type certificateRequestMsg struct {
-	raw []byte
-	// hasSignatureAndHash indicates whether this message includes a list
-	// of signature and hash functions. This change was introduced with TLS
-	// 1.2.
-	hasSignatureAndHash bool
-
-	certificateTypes       []byte
-	signatureAndHashes     []signatureAndHash
-	certificateAuthorities [][]byte
-}
-
-func (m *certificateRequestMsg) equal(i interface{}) bool {
-	m1, ok := i.(*certificateRequestMsg)
-	if !ok {
-		return false
-	}
-
-	return bytes.Equal(m.raw, m1.raw) &&
-		bytes.Equal(m.certificateTypes, m1.certificateTypes) &&
-		eqByteSlices(m.certificateAuthorities, m1.certificateAuthorities) &&
-		eqSignatureAndHashes(m.signatureAndHashes, m1.signatureAndHashes)
-}
-
-func (m *certificateRequestMsg) marshal() (x []byte) {
-	if m.raw != nil {
-		return m.raw
-	}
-
-	// See http://tools.ietf.org/html/rfc4346#section-7.4.4
-	length := 1 + len(m.certificateTypes) + 2
-	casLength := 0
-	for _, ca := range m.certificateAuthorities {
-		casLength += 2 + len(ca)
-	}
-	length += casLength
-
-	if m.hasSignatureAndHash {
-		length += 2 + 2*len(m.signatureAndHashes)
-	}
-
-	x = make([]byte, 4+length)
-	x[0] = typeCertificateRequest
-	x[1] = uint8(length >> 16)
-	x[2] = uint8(length >> 8)
-	x[3] = uint8(length)
-
-	x[4] = uint8(len(m.certificateTypes))
-
-	copy(x[5:], m.certificateTypes)
-	y := x[5+len(m.certificateTypes):]
-
-	if m.hasSignatureAndHash {
-		n := len(m.signatureAndHashes) * 2
-		y[0] = uint8(n >> 8)
-		y[1] = uint8(n)
-		y = y[2:]
-		for _, sigAndHash := range m.signatureAndHashes {
-			y[0] = sigAndHash.hash
-			y[1] = sigAndHash.signature
-			y = y[2:]
-		}
-	}
-
-	y[0] = uint8(casLength >> 8)
-	y[1] = uint8(casLength)
-	y = y[2:]
-	for _, ca := range m.certificateAuthorities {
-		y[0] = uint8(len(ca) >> 8)
-		y[1] = uint8(len(ca))
-		y = y[2:]
-		copy(y, ca)
-		y = y[len(ca):]
-	}
-
-	m.raw = x
-	return
-}
-
-func (m *certificateRequestMsg) unmarshal(data []byte) bool {
-	m.raw = data
-
-	if len(data) < 5 {
-		return false
-	}
-
-	length := uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
-	if uint32(len(data))-4 != length {
-		return false
-	}
-
-	numCertTypes := int(data[4])
-	data = data[5:]
-	if numCertTypes == 0 || len(data) <= numCertTypes {
-		return false
-	}
-
-	m.certificateTypes = make([]byte, numCertTypes)
-	if copy(m.certificateTypes, data) != numCertTypes {
-		return false
-	}
-
-	data = data[numCertTypes:]
-
-	if m.hasSignatureAndHash {
-		if len(data) < 2 {
-			return false
-		}
-		sigAndHashLen := uint16(data[0])<<8 | uint16(data[1])
-		data = data[2:]
-		if sigAndHashLen&1 != 0 {
-			return false
-		}
-		if len(data) < int(sigAndHashLen) {
-			return false
-		}
-		numSigAndHash := sigAndHashLen / 2
-		m.signatureAndHashes = make([]signatureAndHash, numSigAndHash)
-		for i := range m.signatureAndHashes {
-			m.signatureAndHashes[i].hash = data[0]
-			m.signatureAndHashes[i].signature = data[1]
-			data = data[2:]
-		}
-	}
-
-	if len(data) < 2 {
-		return false
-	}
-	casLength := uint16(data[0])<<8 | uint16(data[1])
-	data = data[2:]
-	if len(data) < int(casLength) {
-		return false
-	}
-	cas := make([]byte, casLength)
-	copy(cas, data)
-	data = data[casLength:]
-
-	m.certificateAuthorities = nil
-	for len(cas) > 0 {
-		if len(cas) < 2 {
-			return false
-		}
-		caLen := uint16(cas[0])<<8 | uint16(cas[1])
-		cas = cas[2:]
-
-		if len(cas) < int(caLen) {
-			return false
-		}
-
-		m.certificateAuthorities = append(m.certificateAuthorities, cas[:caLen])
-		cas = cas[caLen:]
-	}
-	if len(data) > 0 {
-		return false
-	}
-
-	return true
-}
-
-type certificateVerifyMsg struct {
-	raw                 []byte
-	hasSignatureAndHash bool
-	signatureAndHash    signatureAndHash
-	signature           []byte
-}
-
-func (m *certificateVerifyMsg) equal(i interface{}) bool {
-	m1, ok := i.(*certificateVerifyMsg)
-	if !ok {
-		return false
-	}
-
-	return bytes.Equal(m.raw, m1.raw) &&
-		m.hasSignatureAndHash == m1.hasSignatureAndHash &&
-		m.signatureAndHash.hash == m1.signatureAndHash.hash &&
-		m.signatureAndHash.signature == m1.signatureAndHash.signature &&
-		bytes.Equal(m.signature, m1.signature)
-}
-
-func (m *certificateVerifyMsg) marshal() (x []byte) {
-	if m.raw != nil {
-		return m.raw
-	}
-
-	// See http://tools.ietf.org/html/rfc4346#section-7.4.8
-	siglength := len(m.signature)
-	length := 2 + siglength
-	if m.hasSignatureAndHash {
-		length += 2
-	}
-	x = make([]byte, 4+length)
-	x[0] = typeCertificateVerify
-	x[1] = uint8(length >> 16)
-	x[2] = uint8(length >> 8)
-	x[3] = uint8(length)
-	y := x[4:]
-	if m.hasSignatureAndHash {
-		y[0] = m.signatureAndHash.hash
-		y[1] = m.signatureAndHash.signature
-		y = y[2:]
-	}
-	y[0] = uint8(siglength >> 8)
-	y[1] = uint8(siglength)
-	copy(y[2:], m.signature)
-
-	m.raw = x
-
-	return
-}
-
-func (m *certificateVerifyMsg) unmarshal(data []byte) bool {
-	m.raw = data
-
-	if len(data) < 6 {
-		return false
-	}
-
-	length := uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
-	if uint32(len(data))-4 != length {
-		return false
-	}
-
-	data = data[4:]
-	if m.hasSignatureAndHash {
-		m.signatureAndHash.hash = data[0]
-		m.signatureAndHash.signature = data[1]
-		data = data[2:]
-	}
-
-	if len(data) < 2 {
-		return false
-	}
-	siglength := int(data[0])<<8 + int(data[1])
-	data = data[2:]
-	if len(data) != siglength {
-		return false
-	}
-
-	m.signature = data
-
-	return true
-}
-
-type newSessionTicketMsg struct {
-	raw    []byte
-	ticket []byte
-}
-
-func (m *newSessionTicketMsg) equal(i interface{}) bool {
-	m1, ok := i.(*newSessionTicketMsg)
-	if !ok {
-		return false
-	}
-
-	return bytes.Equal(m.raw, m1.raw) &&
-		bytes.Equal(m.ticket, m1.ticket)
-}
-
-func (m *newSessionTicketMsg) marshal() (x []byte) {
-	if m.raw != nil {
-		return m.raw
-	}
-
-	// See http://tools.ietf.org/html/rfc5077#section-3.3
-	ticketLen := len(m.ticket)
-	length := 2 + 4 + ticketLen
-	x = make([]byte, 4+length)
-	x[0] = typeNewSessionTicket
-	x[1] = uint8(length >> 16)
-	x[2] = uint8(length >> 8)
-	x[3] = uint8(length)
-	x[8] = uint8(ticketLen >> 8)
-	x[9] = uint8(ticketLen)
-	copy(x[10:], m.ticket)
-
-	m.raw = x
-
-	return
-}
-
-func (m *newSessionTicketMsg) unmarshal(data []byte) bool {
-	m.raw = data
-
-	if len(data) < 10 {
-		return false
-	}
-
-	length := uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
-	if uint32(len(data))-4 != length {
-		return false
-	}
-
-	ticketLen := int(data[8])<<8 + int(data[9])
-	if len(data)-10 != ticketLen {
-		return false
-	}
-
-	m.ticket = data[10:]
-
-	return true
-}
-
-func eqUint16s(x, y []uint16) bool {
-	if len(x) != len(y) {
-		return false
-	}
-	for i, v := range x {
-		if y[i] != v {
-			return false
-		}
-	}
-	return true
-}
-
-func eqCurveIDs(x, y []CurveID) bool {
-	if len(x) != len(y) {
-		return false
-	}
-	for i, v := range x {
-		if y[i] != v {
-			return false
-		}
-	}
-	return true
-}
-
-func eqStrings(x, y []string) bool {
-	if len(x) != len(y) {
-		return false
-	}
-	for i, v := range x {
-		if y[i] != v {
-			return false
-		}
-	}
-	return true
-}
-
-func eqByteSlices(x, y [][]byte) bool {
-	if len(x) != len(y) {
-		return false
-	}
-	for i, v := range x {
-		if !bytes.Equal(v, y[i]) {
-			return false
-		}
-	}
-	return true
-}
-
-func eqSignatureAndHashes(x, y []signatureAndHash) bool {
-	if len(x) != len(y) {
-		return false
-	}
-	for i, v := range x {
-		v2 := y[i]
-		if v.hash != v2.hash || v.signature != v2.signature {
-			return false
-		}
-	}
-	return true
-}
diff --git a/src/pkg/crypto/tls/handshake_messages_test.go b/src/pkg/crypto/tls/handshake_messages_test.go
deleted file mode 100644
index f46aabd..0000000
--- a/src/pkg/crypto/tls/handshake_messages_test.go
+++ /dev/null
@@ -1,246 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package tls
-
-import (
-	"math/rand"
-	"reflect"
-	"testing"
-	"testing/quick"
-)
-
-var tests = []interface{}{
-	&clientHelloMsg{},
-	&serverHelloMsg{},
-	&finishedMsg{},
-
-	&certificateMsg{},
-	&certificateRequestMsg{},
-	&certificateVerifyMsg{},
-	&certificateStatusMsg{},
-	&clientKeyExchangeMsg{},
-	&nextProtoMsg{},
-	&newSessionTicketMsg{},
-	&sessionState{},
-}
-
-type testMessage interface {
-	marshal() []byte
-	unmarshal([]byte) bool
-	equal(interface{}) bool
-}
-
-func TestMarshalUnmarshal(t *testing.T) {
-	rand := rand.New(rand.NewSource(0))
-
-	for i, iface := range tests {
-		ty := reflect.ValueOf(iface).Type()
-
-		n := 100
-		if testing.Short() {
-			n = 5
-		}
-		for j := 0; j < n; j++ {
-			v, ok := quick.Value(ty, rand)
-			if !ok {
-				t.Errorf("#%d: failed to create value", i)
-				break
-			}
-
-			m1 := v.Interface().(testMessage)
-			marshaled := m1.marshal()
-			m2 := iface.(testMessage)
-			if !m2.unmarshal(marshaled) {
-				t.Errorf("#%d failed to unmarshal %#v %x", i, m1, marshaled)
-				break
-			}
-			m2.marshal() // to fill any marshal cache in the message
-
-			if !m1.equal(m2) {
-				t.Errorf("#%d got:%#v want:%#v %x", i, m2, m1, marshaled)
-				break
-			}
-
-			if i >= 3 {
-				// The first three message types (ClientHello,
-				// ServerHello and Finished) are allowed to
-				// have parsable prefixes because the extension
-				// data is optional and the length of the
-				// Finished varies across versions.
-				for j := 0; j < len(marshaled); j++ {
-					if m2.unmarshal(marshaled[0:j]) {
-						t.Errorf("#%d unmarshaled a prefix of length %d of %#v", i, j, m1)
-						break
-					}
-				}
-			}
-		}
-	}
-}
-
-func TestFuzz(t *testing.T) {
-	rand := rand.New(rand.NewSource(0))
-	for _, iface := range tests {
-		m := iface.(testMessage)
-
-		for j := 0; j < 1000; j++ {
-			len := rand.Intn(100)
-			bytes := randomBytes(len, rand)
-			// This just looks for crashes due to bounds errors etc.
-			m.unmarshal(bytes)
-		}
-	}
-}
-
-func randomBytes(n int, rand *rand.Rand) []byte {
-	r := make([]byte, n)
-	for i := 0; i < n; i++ {
-		r[i] = byte(rand.Int31())
-	}
-	return r
-}
-
-func randomString(n int, rand *rand.Rand) string {
-	b := randomBytes(n, rand)
-	return string(b)
-}
-
-func (*clientHelloMsg) Generate(rand *rand.Rand, size int) reflect.Value {
-	m := &clientHelloMsg{}
-	m.vers = uint16(rand.Intn(65536))
-	m.random = randomBytes(32, rand)
-	m.sessionId = randomBytes(rand.Intn(32), rand)
-	m.cipherSuites = make([]uint16, rand.Intn(63)+1)
-	for i := 0; i < len(m.cipherSuites); i++ {
-		m.cipherSuites[i] = uint16(rand.Int31())
-	}
-	m.compressionMethods = randomBytes(rand.Intn(63)+1, rand)
-	if rand.Intn(10) > 5 {
-		m.nextProtoNeg = true
-	}
-	if rand.Intn(10) > 5 {
-		m.serverName = randomString(rand.Intn(255), rand)
-	}
-	m.ocspStapling = rand.Intn(10) > 5
-	m.supportedPoints = randomBytes(rand.Intn(5)+1, rand)
-	m.supportedCurves = make([]CurveID, rand.Intn(5)+1)
-	for i := range m.supportedCurves {
-		m.supportedCurves[i] = CurveID(rand.Intn(30000))
-	}
-	if rand.Intn(10) > 5 {
-		m.ticketSupported = true
-		if rand.Intn(10) > 5 {
-			m.sessionTicket = randomBytes(rand.Intn(300), rand)
-		}
-	}
-	if rand.Intn(10) > 5 {
-		m.signatureAndHashes = supportedSKXSignatureAlgorithms
-	}
-
-	return reflect.ValueOf(m)
-}
-
-func (*serverHelloMsg) Generate(rand *rand.Rand, size int) reflect.Value {
-	m := &serverHelloMsg{}
-	m.vers = uint16(rand.Intn(65536))
-	m.random = randomBytes(32, rand)
-	m.sessionId = randomBytes(rand.Intn(32), rand)
-	m.cipherSuite = uint16(rand.Int31())
-	m.compressionMethod = uint8(rand.Intn(256))
-
-	if rand.Intn(10) > 5 {
-		m.nextProtoNeg = true
-
-		n := rand.Intn(10)
-		m.nextProtos = make([]string, n)
-		for i := 0; i < n; i++ {
-			m.nextProtos[i] = randomString(20, rand)
-		}
-	}
-
-	if rand.Intn(10) > 5 {
-		m.ocspStapling = true
-	}
-	if rand.Intn(10) > 5 {
-		m.ticketSupported = true
-	}
-
-	return reflect.ValueOf(m)
-}
-
-func (*certificateMsg) Generate(rand *rand.Rand, size int) reflect.Value {
-	m := &certificateMsg{}
-	numCerts := rand.Intn(20)
-	m.certificates = make([][]byte, numCerts)
-	for i := 0; i < numCerts; i++ {
-		m.certificates[i] = randomBytes(rand.Intn(10)+1, rand)
-	}
-	return reflect.ValueOf(m)
-}
-
-func (*certificateRequestMsg) Generate(rand *rand.Rand, size int) reflect.Value {
-	m := &certificateRequestMsg{}
-	m.certificateTypes = randomBytes(rand.Intn(5)+1, rand)
-	numCAs := rand.Intn(100)
-	m.certificateAuthorities = make([][]byte, numCAs)
-	for i := 0; i < numCAs; i++ {
-		m.certificateAuthorities[i] = randomBytes(rand.Intn(15)+1, rand)
-	}
-	return reflect.ValueOf(m)
-}
-
-func (*certificateVerifyMsg) Generate(rand *rand.Rand, size int) reflect.Value {
-	m := &certificateVerifyMsg{}
-	m.signature = randomBytes(rand.Intn(15)+1, rand)
-	return reflect.ValueOf(m)
-}
-
-func (*certificateStatusMsg) Generate(rand *rand.Rand, size int) reflect.Value {
-	m := &certificateStatusMsg{}
-	if rand.Intn(10) > 5 {
-		m.statusType = statusTypeOCSP
-		m.response = randomBytes(rand.Intn(10)+1, rand)
-	} else {
-		m.statusType = 42
-	}
-	return reflect.ValueOf(m)
-}
-
-func (*clientKeyExchangeMsg) Generate(rand *rand.Rand, size int) reflect.Value {
-	m := &clientKeyExchangeMsg{}
-	m.ciphertext = randomBytes(rand.Intn(1000)+1, rand)
-	return reflect.ValueOf(m)
-}
-
-func (*finishedMsg) Generate(rand *rand.Rand, size int) reflect.Value {
-	m := &finishedMsg{}
-	m.verifyData = randomBytes(12, rand)
-	return reflect.ValueOf(m)
-}
-
-func (*nextProtoMsg) Generate(rand *rand.Rand, size int) reflect.Value {
-	m := &nextProtoMsg{}
-	m.proto = randomString(rand.Intn(255), rand)
-	return reflect.ValueOf(m)
-}
-
-func (*newSessionTicketMsg) Generate(rand *rand.Rand, size int) reflect.Value {
-	m := &newSessionTicketMsg{}
-	m.ticket = randomBytes(rand.Intn(4), rand)
-	return reflect.ValueOf(m)
-}
-
-func (*sessionState) Generate(rand *rand.Rand, size int) reflect.Value {
-	s := &sessionState{}
-	s.vers = uint16(rand.Intn(10000))
-	s.cipherSuite = uint16(rand.Intn(10000))
-	s.masterSecret = randomBytes(rand.Intn(100), rand)
-	numCerts := rand.Intn(20)
-	s.certificates = make([][]byte, numCerts)
-	for i := 0; i < numCerts; i++ {
-		s.certificates[i] = randomBytes(rand.Intn(10)+1, rand)
-	}
-	return reflect.ValueOf(s)
-}
diff --git a/src/pkg/crypto/tls/handshake_server.go b/src/pkg/crypto/tls/handshake_server.go
deleted file mode 100644
index dff6fd9..0000000
--- a/src/pkg/crypto/tls/handshake_server.go
+++ /dev/null
@@ -1,654 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package tls
-
-import (
-	"crypto"
-	"crypto/ecdsa"
-	"crypto/rsa"
-	"crypto/subtle"
-	"crypto/x509"
-	"encoding/asn1"
-	"errors"
-	"fmt"
-	"io"
-)
-
-// serverHandshakeState contains details of a server handshake in progress.
-// It's discarded once the handshake has completed.
-type serverHandshakeState struct {
-	c               *Conn
-	clientHello     *clientHelloMsg
-	hello           *serverHelloMsg
-	suite           *cipherSuite
-	ellipticOk      bool
-	ecdsaOk         bool
-	sessionState    *sessionState
-	finishedHash    finishedHash
-	masterSecret    []byte
-	certsFromClient [][]byte
-	cert            *Certificate
-}
-
-// serverHandshake performs a TLS handshake as a server.
-func (c *Conn) serverHandshake() error {
-	config := c.config
-
-	// If this is the first server handshake, we generate a random key to
-	// encrypt the tickets with.
-	config.serverInitOnce.Do(config.serverInit)
-
-	hs := serverHandshakeState{
-		c: c,
-	}
-	isResume, err := hs.readClientHello()
-	if err != nil {
-		return err
-	}
-
-	// For an overview of TLS handshaking, see https://tools.ietf.org/html/rfc5246#section-7.3
-	if isResume {
-		// The client has included a session ticket and so we do an abbreviated handshake.
-		if err := hs.doResumeHandshake(); err != nil {
-			return err
-		}
-		if err := hs.establishKeys(); err != nil {
-			return err
-		}
-		if err := hs.sendFinished(); err != nil {
-			return err
-		}
-		if err := hs.readFinished(); err != nil {
-			return err
-		}
-		c.didResume = true
-	} else {
-		// The client didn't include a session ticket, or it wasn't
-		// valid so we do a full handshake.
-		if err := hs.doFullHandshake(); err != nil {
-			return err
-		}
-		if err := hs.establishKeys(); err != nil {
-			return err
-		}
-		if err := hs.readFinished(); err != nil {
-			return err
-		}
-		if err := hs.sendSessionTicket(); err != nil {
-			return err
-		}
-		if err := hs.sendFinished(); err != nil {
-			return err
-		}
-	}
-	c.handshakeComplete = true
-
-	return nil
-}
-
-// readClientHello reads a ClientHello message from the client and decides
-// whether we will perform session resumption.
-func (hs *serverHandshakeState) readClientHello() (isResume bool, err error) {
-	config := hs.c.config
-	c := hs.c
-
-	msg, err := c.readHandshake()
-	if err != nil {
-		return false, err
-	}
-	var ok bool
-	hs.clientHello, ok = msg.(*clientHelloMsg)
-	if !ok {
-		c.sendAlert(alertUnexpectedMessage)
-		return false, unexpectedMessageError(hs.clientHello, msg)
-	}
-	c.vers, ok = config.mutualVersion(hs.clientHello.vers)
-	if !ok {
-		c.sendAlert(alertProtocolVersion)
-		return false, fmt.Errorf("tls: client offered an unsupported, maximum protocol version of %x", hs.clientHello.vers)
-	}
-	c.haveVers = true
-
-	hs.finishedHash = newFinishedHash(c.vers)
-	hs.finishedHash.Write(hs.clientHello.marshal())
-
-	hs.hello = new(serverHelloMsg)
-
-	supportedCurve := false
-	preferredCurves := config.curvePreferences()
-Curves:
-	for _, curve := range hs.clientHello.supportedCurves {
-		for _, supported := range preferredCurves {
-			if supported == curve {
-				supportedCurve = true
-				break Curves
-			}
-		}
-	}
-
-	supportedPointFormat := false
-	for _, pointFormat := range hs.clientHello.supportedPoints {
-		if pointFormat == pointFormatUncompressed {
-			supportedPointFormat = true
-			break
-		}
-	}
-	hs.ellipticOk = supportedCurve && supportedPointFormat
-
-	foundCompression := false
-	// We only support null compression, so check that the client offered it.
-	for _, compression := range hs.clientHello.compressionMethods {
-		if compression == compressionNone {
-			foundCompression = true
-			break
-		}
-	}
-
-	if !foundCompression {
-		c.sendAlert(alertHandshakeFailure)
-		return false, errors.New("tls: client does not support uncompressed connections")
-	}
-
-	hs.hello.vers = c.vers
-	hs.hello.random = make([]byte, 32)
-	_, err = io.ReadFull(config.rand(), hs.hello.random)
-	if err != nil {
-		c.sendAlert(alertInternalError)
-		return false, err
-	}
-	hs.hello.secureRenegotiation = hs.clientHello.secureRenegotiation
-	hs.hello.compressionMethod = compressionNone
-	if len(hs.clientHello.serverName) > 0 {
-		c.serverName = hs.clientHello.serverName
-	}
-	// Although sending an empty NPN extension is reasonable, Firefox has
-	// had a bug around this. Best to send nothing at all if
-	// config.NextProtos is empty. See
-	// https://code.google.com/p/go/issues/detail?id=5445.
-	if hs.clientHello.nextProtoNeg && len(config.NextProtos) > 0 {
-		hs.hello.nextProtoNeg = true
-		hs.hello.nextProtos = config.NextProtos
-	}
-
-	if len(config.Certificates) == 0 {
-		c.sendAlert(alertInternalError)
-		return false, errors.New("tls: no certificates configured")
-	}
-	hs.cert = &config.Certificates[0]
-	if len(hs.clientHello.serverName) > 0 {
-		hs.cert = config.getCertificateForName(hs.clientHello.serverName)
-	}
-
-	_, hs.ecdsaOk = hs.cert.PrivateKey.(*ecdsa.PrivateKey)
-
-	if hs.checkForResumption() {
-		return true, nil
-	}
-
-	var preferenceList, supportedList []uint16
-	if c.config.PreferServerCipherSuites {
-		preferenceList = c.config.cipherSuites()
-		supportedList = hs.clientHello.cipherSuites
-	} else {
-		preferenceList = hs.clientHello.cipherSuites
-		supportedList = c.config.cipherSuites()
-	}
-
-	for _, id := range preferenceList {
-		if hs.suite = c.tryCipherSuite(id, supportedList, c.vers, hs.ellipticOk, hs.ecdsaOk); hs.suite != nil {
-			break
-		}
-	}
-
-	if hs.suite == nil {
-		c.sendAlert(alertHandshakeFailure)
-		return false, errors.New("tls: no cipher suite supported by both client and server")
-	}
-
-	return false, nil
-}
-
-// checkForResumption returns true if we should perform resumption on this connection.
-func (hs *serverHandshakeState) checkForResumption() bool {
-	c := hs.c
-
-	if c.config.SessionTicketsDisabled {
-		return false
-	}
-
-	var ok bool
-	if hs.sessionState, ok = c.decryptTicket(hs.clientHello.sessionTicket); !ok {
-		return false
-	}
-
-	if hs.sessionState.vers > hs.clientHello.vers {
-		return false
-	}
-	if vers, ok := c.config.mutualVersion(hs.sessionState.vers); !ok || vers != hs.sessionState.vers {
-		return false
-	}
-
-	cipherSuiteOk := false
-	// Check that the client is still offering the ciphersuite in the session.
-	for _, id := range hs.clientHello.cipherSuites {
-		if id == hs.sessionState.cipherSuite {
-			cipherSuiteOk = true
-			break
-		}
-	}
-	if !cipherSuiteOk {
-		return false
-	}
-
-	// Check that we also support the ciphersuite from the session.
-	hs.suite = c.tryCipherSuite(hs.sessionState.cipherSuite, c.config.cipherSuites(), hs.sessionState.vers, hs.ellipticOk, hs.ecdsaOk)
-	if hs.suite == nil {
-		return false
-	}
-
-	sessionHasClientCerts := len(hs.sessionState.certificates) != 0
-	needClientCerts := c.config.ClientAuth == RequireAnyClientCert || c.config.ClientAuth == RequireAndVerifyClientCert
-	if needClientCerts && !sessionHasClientCerts {
-		return false
-	}
-	if sessionHasClientCerts && c.config.ClientAuth == NoClientCert {
-		return false
-	}
-
-	return true
-}
-
-func (hs *serverHandshakeState) doResumeHandshake() error {
-	c := hs.c
-
-	hs.hello.cipherSuite = hs.suite.id
-	// We echo the client's session ID in the ServerHello to let it know
-	// that we're doing a resumption.
-	hs.hello.sessionId = hs.clientHello.sessionId
-	hs.finishedHash.Write(hs.hello.marshal())
-	c.writeRecord(recordTypeHandshake, hs.hello.marshal())
-
-	if len(hs.sessionState.certificates) > 0 {
-		if _, err := hs.processCertsFromClient(hs.sessionState.certificates); err != nil {
-			return err
-		}
-	}
-
-	hs.masterSecret = hs.sessionState.masterSecret
-
-	return nil
-}
-
-func (hs *serverHandshakeState) doFullHandshake() error {
-	config := hs.c.config
-	c := hs.c
-
-	if hs.clientHello.ocspStapling && len(hs.cert.OCSPStaple) > 0 {
-		hs.hello.ocspStapling = true
-	}
-
-	hs.hello.ticketSupported = hs.clientHello.ticketSupported && !config.SessionTicketsDisabled
-	hs.hello.cipherSuite = hs.suite.id
-	hs.finishedHash.Write(hs.hello.marshal())
-	c.writeRecord(recordTypeHandshake, hs.hello.marshal())
-
-	certMsg := new(certificateMsg)
-	certMsg.certificates = hs.cert.Certificate
-	hs.finishedHash.Write(certMsg.marshal())
-	c.writeRecord(recordTypeHandshake, certMsg.marshal())
-
-	if hs.hello.ocspStapling {
-		certStatus := new(certificateStatusMsg)
-		certStatus.statusType = statusTypeOCSP
-		certStatus.response = hs.cert.OCSPStaple
-		hs.finishedHash.Write(certStatus.marshal())
-		c.writeRecord(recordTypeHandshake, certStatus.marshal())
-	}
-
-	keyAgreement := hs.suite.ka(c.vers)
-	skx, err := keyAgreement.generateServerKeyExchange(config, hs.cert, hs.clientHello, hs.hello)
-	if err != nil {
-		c.sendAlert(alertHandshakeFailure)
-		return err
-	}
-	if skx != nil {
-		hs.finishedHash.Write(skx.marshal())
-		c.writeRecord(recordTypeHandshake, skx.marshal())
-	}
-
-	if config.ClientAuth >= RequestClientCert {
-		// Request a client certificate
-		certReq := new(certificateRequestMsg)
-		certReq.certificateTypes = []byte{
-			byte(certTypeRSASign),
-			byte(certTypeECDSASign),
-		}
-		if c.vers >= VersionTLS12 {
-			certReq.hasSignatureAndHash = true
-			certReq.signatureAndHashes = supportedClientCertSignatureAlgorithms
-		}
-
-		// An empty list of certificateAuthorities signals to
-		// the client that it may send any certificate in response
-		// to our request. When we know the CAs we trust, then
-		// we can send them down, so that the client can choose
-		// an appropriate certificate to give to us.
-		if config.ClientCAs != nil {
-			certReq.certificateAuthorities = config.ClientCAs.Subjects()
-		}
-		hs.finishedHash.Write(certReq.marshal())
-		c.writeRecord(recordTypeHandshake, certReq.marshal())
-	}
-
-	helloDone := new(serverHelloDoneMsg)
-	hs.finishedHash.Write(helloDone.marshal())
-	c.writeRecord(recordTypeHandshake, helloDone.marshal())
-
-	var pub crypto.PublicKey // public key for client auth, if any
-
-	msg, err := c.readHandshake()
-	if err != nil {
-		return err
-	}
-
-	var ok bool
-	// If we requested a client certificate, then the client must send a
-	// certificate message, even if it's empty.
-	if config.ClientAuth >= RequestClientCert {
-		if certMsg, ok = msg.(*certificateMsg); !ok {
-			c.sendAlert(alertUnexpectedMessage)
-			return unexpectedMessageError(certMsg, msg)
-		}
-		hs.finishedHash.Write(certMsg.marshal())
-
-		if len(certMsg.certificates) == 0 {
-			// The client didn't actually send a certificate
-			switch config.ClientAuth {
-			case RequireAnyClientCert, RequireAndVerifyClientCert:
-				c.sendAlert(alertBadCertificate)
-				return errors.New("tls: client didn't provide a certificate")
-			}
-		}
-
-		pub, err = hs.processCertsFromClient(certMsg.certificates)
-		if err != nil {
-			return err
-		}
-
-		msg, err = c.readHandshake()
-		if err != nil {
-			return err
-		}
-	}
-
-	// Get client key exchange
-	ckx, ok := msg.(*clientKeyExchangeMsg)
-	if !ok {
-		c.sendAlert(alertUnexpectedMessage)
-		return unexpectedMessageError(ckx, msg)
-	}
-	hs.finishedHash.Write(ckx.marshal())
-
-	// If we received a client cert in response to our certificate request message,
-	// the client will send us a certificateVerifyMsg immediately after the
-	// clientKeyExchangeMsg.  This message is a digest of all preceding
-	// handshake-layer messages that is signed using the private key corresponding
-	// to the client's certificate. This allows us to verify that the client is in
-	// possession of the private key of the certificate.
-	if len(c.peerCertificates) > 0 {
-		msg, err = c.readHandshake()
-		if err != nil {
-			return err
-		}
-		certVerify, ok := msg.(*certificateVerifyMsg)
-		if !ok {
-			c.sendAlert(alertUnexpectedMessage)
-			return unexpectedMessageError(certVerify, msg)
-		}
-
-		switch key := pub.(type) {
-		case *ecdsa.PublicKey:
-			ecdsaSig := new(ecdsaSignature)
-			if _, err = asn1.Unmarshal(certVerify.signature, ecdsaSig); err != nil {
-				break
-			}
-			if ecdsaSig.R.Sign() <= 0 || ecdsaSig.S.Sign() <= 0 {
-				err = errors.New("ECDSA signature contained zero or negative values")
-				break
-			}
-			digest, _, _ := hs.finishedHash.hashForClientCertificate(signatureECDSA)
-			if !ecdsa.Verify(key, digest, ecdsaSig.R, ecdsaSig.S) {
-				err = errors.New("ECDSA verification failure")
-				break
-			}
-		case *rsa.PublicKey:
-			digest, hashFunc, _ := hs.finishedHash.hashForClientCertificate(signatureRSA)
-			err = rsa.VerifyPKCS1v15(key, hashFunc, digest, certVerify.signature)
-		}
-		if err != nil {
-			c.sendAlert(alertBadCertificate)
-			return errors.New("could not validate signature of connection nonces: " + err.Error())
-		}
-
-		hs.finishedHash.Write(certVerify.marshal())
-	}
-
-	preMasterSecret, err := keyAgreement.processClientKeyExchange(config, hs.cert, ckx, c.vers)
-	if err != nil {
-		c.sendAlert(alertHandshakeFailure)
-		return err
-	}
-	hs.masterSecret = masterFromPreMasterSecret(c.vers, preMasterSecret, hs.clientHello.random, hs.hello.random)
-
-	return nil
-}
-
-func (hs *serverHandshakeState) establishKeys() error {
-	c := hs.c
-
-	clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV :=
-		keysFromMasterSecret(c.vers, hs.masterSecret, hs.clientHello.random, hs.hello.random, hs.suite.macLen, hs.suite.keyLen, hs.suite.ivLen)
-
-	var clientCipher, serverCipher interface{}
-	var clientHash, serverHash macFunction
-
-	if hs.suite.aead == nil {
-		clientCipher = hs.suite.cipher(clientKey, clientIV, true /* for reading */)
-		clientHash = hs.suite.mac(c.vers, clientMAC)
-		serverCipher = hs.suite.cipher(serverKey, serverIV, false /* not for reading */)
-		serverHash = hs.suite.mac(c.vers, serverMAC)
-	} else {
-		clientCipher = hs.suite.aead(clientKey, clientIV)
-		serverCipher = hs.suite.aead(serverKey, serverIV)
-	}
-
-	c.in.prepareCipherSpec(c.vers, clientCipher, clientHash)
-	c.out.prepareCipherSpec(c.vers, serverCipher, serverHash)
-
-	return nil
-}
-
-func (hs *serverHandshakeState) readFinished() error {
-	c := hs.c
-
-	c.readRecord(recordTypeChangeCipherSpec)
-	if err := c.in.error(); err != nil {
-		return err
-	}
-
-	if hs.hello.nextProtoNeg {
-		msg, err := c.readHandshake()
-		if err != nil {
-			return err
-		}
-		nextProto, ok := msg.(*nextProtoMsg)
-		if !ok {
-			c.sendAlert(alertUnexpectedMessage)
-			return unexpectedMessageError(nextProto, msg)
-		}
-		hs.finishedHash.Write(nextProto.marshal())
-		c.clientProtocol = nextProto.proto
-	}
-
-	msg, err := c.readHandshake()
-	if err != nil {
-		return err
-	}
-	clientFinished, ok := msg.(*finishedMsg)
-	if !ok {
-		c.sendAlert(alertUnexpectedMessage)
-		return unexpectedMessageError(clientFinished, msg)
-	}
-
-	verify := hs.finishedHash.clientSum(hs.masterSecret)
-	if len(verify) != len(clientFinished.verifyData) ||
-		subtle.ConstantTimeCompare(verify, clientFinished.verifyData) != 1 {
-		c.sendAlert(alertHandshakeFailure)
-		return errors.New("tls: client's Finished message is incorrect")
-	}
-
-	hs.finishedHash.Write(clientFinished.marshal())
-	return nil
-}
-
-func (hs *serverHandshakeState) sendSessionTicket() error {
-	if !hs.hello.ticketSupported {
-		return nil
-	}
-
-	c := hs.c
-	m := new(newSessionTicketMsg)
-
-	var err error
-	state := sessionState{
-		vers:         c.vers,
-		cipherSuite:  hs.suite.id,
-		masterSecret: hs.masterSecret,
-		certificates: hs.certsFromClient,
-	}
-	m.ticket, err = c.encryptTicket(&state)
-	if err != nil {
-		return err
-	}
-
-	hs.finishedHash.Write(m.marshal())
-	c.writeRecord(recordTypeHandshake, m.marshal())
-
-	return nil
-}
-
-func (hs *serverHandshakeState) sendFinished() error {
-	c := hs.c
-
-	c.writeRecord(recordTypeChangeCipherSpec, []byte{1})
-
-	finished := new(finishedMsg)
-	finished.verifyData = hs.finishedHash.serverSum(hs.masterSecret)
-	hs.finishedHash.Write(finished.marshal())
-	c.writeRecord(recordTypeHandshake, finished.marshal())
-
-	c.cipherSuite = hs.suite.id
-
-	return nil
-}
-
-// processCertsFromClient takes a chain of client certificates either from a
-// Certificates message or from a sessionState and verifies them. It returns
-// the public key of the leaf certificate.
-func (hs *serverHandshakeState) processCertsFromClient(certificates [][]byte) (crypto.PublicKey, error) {
-	c := hs.c
-
-	hs.certsFromClient = certificates
-	certs := make([]*x509.Certificate, len(certificates))
-	var err error
-	for i, asn1Data := range certificates {
-		if certs[i], err = x509.ParseCertificate(asn1Data); err != nil {
-			c.sendAlert(alertBadCertificate)
-			return nil, errors.New("tls: failed to parse client certificate: " + err.Error())
-		}
-	}
-
-	if c.config.ClientAuth >= VerifyClientCertIfGiven && len(certs) > 0 {
-		opts := x509.VerifyOptions{
-			Roots:         c.config.ClientCAs,
-			CurrentTime:   c.config.time(),
-			Intermediates: x509.NewCertPool(),
-			KeyUsages:     []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
-		}
-
-		for _, cert := range certs[1:] {
-			opts.Intermediates.AddCert(cert)
-		}
-
-		chains, err := certs[0].Verify(opts)
-		if err != nil {
-			c.sendAlert(alertBadCertificate)
-			return nil, errors.New("tls: failed to verify client's certificate: " + err.Error())
-		}
-
-		ok := false
-		for _, ku := range certs[0].ExtKeyUsage {
-			if ku == x509.ExtKeyUsageClientAuth {
-				ok = true
-				break
-			}
-		}
-		if !ok {
-			c.sendAlert(alertHandshakeFailure)
-			return nil, errors.New("tls: client's certificate's extended key usage doesn't permit it to be used for client authentication")
-		}
-
-		c.verifiedChains = chains
-	}
-
-	if len(certs) > 0 {
-		var pub crypto.PublicKey
-		switch key := certs[0].PublicKey.(type) {
-		case *ecdsa.PublicKey, *rsa.PublicKey:
-			pub = key
-		default:
-			c.sendAlert(alertUnsupportedCertificate)
-			return nil, fmt.Errorf("tls: client's certificate contains an unsupported public key of type %T", certs[0].PublicKey)
-		}
-		c.peerCertificates = certs
-		return pub, nil
-	}
-
-	return nil, nil
-}
-
-// tryCipherSuite returns a cipherSuite with the given id if that cipher suite
-// is acceptable to use.
-func (c *Conn) tryCipherSuite(id uint16, supportedCipherSuites []uint16, version uint16, ellipticOk, ecdsaOk bool) *cipherSuite {
-	for _, supported := range supportedCipherSuites {
-		if id == supported {
-			var candidate *cipherSuite
-
-			for _, s := range cipherSuites {
-				if s.id == id {
-					candidate = s
-					break
-				}
-			}
-			if candidate == nil {
-				continue
-			}
-			// Don't select a ciphersuite which we can't
-			// support for this client.
-			if (candidate.flags&suiteECDHE != 0) && !ellipticOk {
-				continue
-			}
-			if (candidate.flags&suiteECDSA != 0) != ecdsaOk {
-				continue
-			}
-			if version < VersionTLS12 && candidate.flags&suiteTLS12 != 0 {
-				continue
-			}
-			return candidate
-		}
-	}
-
-	return nil
-}
diff --git a/src/pkg/crypto/tls/handshake_server_test.go b/src/pkg/crypto/tls/handshake_server_test.go
deleted file mode 100644
index 3444d5c..0000000
--- a/src/pkg/crypto/tls/handshake_server_test.go
+++ /dev/null
@@ -1,726 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package tls
-
-import (
-	"bytes"
-	"crypto/ecdsa"
-	"crypto/elliptic"
-	"crypto/rsa"
-	"crypto/x509"
-	"encoding/hex"
-	"encoding/pem"
-	"errors"
-	"fmt"
-	"io"
-	"math/big"
-	"net"
-	"os"
-	"os/exec"
-	"path/filepath"
-	"strings"
-	"testing"
-	"time"
-)
-
-// zeroSource is an io.Reader that returns an unlimited number of zero bytes.
-type zeroSource struct{}
-
-func (zeroSource) Read(b []byte) (n int, err error) {
-	for i := range b {
-		b[i] = 0
-	}
-
-	return len(b), nil
-}
-
-var testConfig *Config
-
-func init() {
-	testConfig = &Config{
-		Time:               func() time.Time { return time.Unix(0, 0) },
-		Rand:               zeroSource{},
-		Certificates:       make([]Certificate, 2),
-		InsecureSkipVerify: true,
-		MinVersion:         VersionSSL30,
-		MaxVersion:         VersionTLS12,
-	}
-	testConfig.Certificates[0].Certificate = [][]byte{testRSACertificate}
-	testConfig.Certificates[0].PrivateKey = testRSAPrivateKey
-	testConfig.Certificates[1].Certificate = [][]byte{testSNICertificate}
-	testConfig.Certificates[1].PrivateKey = testRSAPrivateKey
-	testConfig.BuildNameToCertificate()
-}
-
-func testClientHelloFailure(t *testing.T, m handshakeMessage, expectedSubStr string) {
-	// Create in-memory network connection,
-	// send message to server.  Should return
-	// expected error.
-	c, s := net.Pipe()
-	go func() {
-		cli := Client(c, testConfig)
-		if ch, ok := m.(*clientHelloMsg); ok {
-			cli.vers = ch.vers
-		}
-		cli.writeRecord(recordTypeHandshake, m.marshal())
-		c.Close()
-	}()
-	err := Server(s, testConfig).Handshake()
-	s.Close()
-	if err == nil || !strings.Contains(err.Error(), expectedSubStr) {
-		t.Errorf("Got error: %s; expected to match substring '%s'", err, expectedSubStr)
-	}
-}
-
-func TestSimpleError(t *testing.T) {
-	testClientHelloFailure(t, &serverHelloDoneMsg{}, "unexpected handshake message")
-}
-
-var badProtocolVersions = []uint16{0x0000, 0x0005, 0x0100, 0x0105, 0x0200, 0x0205}
-
-func TestRejectBadProtocolVersion(t *testing.T) {
-	for _, v := range badProtocolVersions {
-		testClientHelloFailure(t, &clientHelloMsg{vers: v}, "unsupported, maximum protocol version")
-	}
-}
-
-func TestNoSuiteOverlap(t *testing.T) {
-	clientHello := &clientHelloMsg{
-		vers:               0x0301,
-		cipherSuites:       []uint16{0xff00},
-		compressionMethods: []uint8{0},
-	}
-	testClientHelloFailure(t, clientHello, "no cipher suite supported by both client and server")
-}
-
-func TestNoCompressionOverlap(t *testing.T) {
-	clientHello := &clientHelloMsg{
-		vers:               0x0301,
-		cipherSuites:       []uint16{TLS_RSA_WITH_RC4_128_SHA},
-		compressionMethods: []uint8{0xff},
-	}
-	testClientHelloFailure(t, clientHello, "client does not support uncompressed connections")
-}
-
-func TestTLS12OnlyCipherSuites(t *testing.T) {
-	// Test that a Server doesn't select a TLS 1.2-only cipher suite when
-	// the client negotiates TLS 1.1.
-	var zeros [32]byte
-
-	clientHello := &clientHelloMsg{
-		vers:   VersionTLS11,
-		random: zeros[:],
-		cipherSuites: []uint16{
-			// The Server, by default, will use the client's
-			// preference order. So the GCM cipher suite
-			// will be selected unless it's excluded because
-			// of the version in this ClientHello.
-			TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
-			TLS_RSA_WITH_RC4_128_SHA,
-		},
-		compressionMethods: []uint8{compressionNone},
-		supportedCurves:    []CurveID{CurveP256, CurveP384, CurveP521},
-		supportedPoints:    []uint8{pointFormatUncompressed},
-	}
-
-	c, s := net.Pipe()
-	var reply interface{}
-	var clientErr error
-	go func() {
-		cli := Client(c, testConfig)
-		cli.vers = clientHello.vers
-		cli.writeRecord(recordTypeHandshake, clientHello.marshal())
-		reply, clientErr = cli.readHandshake()
-		c.Close()
-	}()
-	config := *testConfig
-	config.CipherSuites = clientHello.cipherSuites
-	Server(s, &config).Handshake()
-	s.Close()
-	if clientErr != nil {
-		t.Fatal(clientErr)
-	}
-	serverHello, ok := reply.(*serverHelloMsg)
-	if !ok {
-		t.Fatalf("didn't get ServerHello message in reply. Got %v\n", reply)
-	}
-	if s := serverHello.cipherSuite; s != TLS_RSA_WITH_RC4_128_SHA {
-		t.Fatalf("bad cipher suite from server: %x", s)
-	}
-}
-
-func TestAlertForwarding(t *testing.T) {
-	c, s := net.Pipe()
-	go func() {
-		Client(c, testConfig).sendAlert(alertUnknownCA)
-		c.Close()
-	}()
-
-	err := Server(s, testConfig).Handshake()
-	s.Close()
-	if e, ok := err.(*net.OpError); !ok || e.Err != error(alertUnknownCA) {
-		t.Errorf("Got error: %s; expected: %s", err, error(alertUnknownCA))
-	}
-}
-
-func TestClose(t *testing.T) {
-	c, s := net.Pipe()
-	go c.Close()
-
-	err := Server(s, testConfig).Handshake()
-	s.Close()
-	if err != io.EOF {
-		t.Errorf("Got error: %s; expected: %s", err, io.EOF)
-	}
-}
-
-func testHandshake(clientConfig, serverConfig *Config) (state ConnectionState, err error) {
-	c, s := net.Pipe()
-	done := make(chan bool)
-	go func() {
-		cli := Client(c, clientConfig)
-		cli.Handshake()
-		c.Close()
-		done <- true
-	}()
-	server := Server(s, serverConfig)
-	err = server.Handshake()
-	if err == nil {
-		state = server.ConnectionState()
-	}
-	s.Close()
-	<-done
-	return
-}
-
-func TestVersion(t *testing.T) {
-	serverConfig := &Config{
-		Certificates: testConfig.Certificates,
-		MaxVersion:   VersionTLS11,
-	}
-	clientConfig := &Config{
-		InsecureSkipVerify: true,
-	}
-	state, err := testHandshake(clientConfig, serverConfig)
-	if err != nil {
-		t.Fatalf("handshake failed: %s", err)
-	}
-	if state.Version != VersionTLS11 {
-		t.Fatalf("Incorrect version %x, should be %x", state.Version, VersionTLS11)
-	}
-}
-
-func TestCipherSuitePreference(t *testing.T) {
-	serverConfig := &Config{
-		CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA},
-		Certificates: testConfig.Certificates,
-		MaxVersion:   VersionTLS11,
-	}
-	clientConfig := &Config{
-		CipherSuites:       []uint16{TLS_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_RC4_128_SHA},
-		InsecureSkipVerify: true,
-	}
-	state, err := testHandshake(clientConfig, serverConfig)
-	if err != nil {
-		t.Fatalf("handshake failed: %s", err)
-	}
-	if state.CipherSuite != TLS_RSA_WITH_AES_128_CBC_SHA {
-		// By default the server should use the client's preference.
-		t.Fatalf("Client's preference was not used, got %x", state.CipherSuite)
-	}
-
-	serverConfig.PreferServerCipherSuites = true
-	state, err = testHandshake(clientConfig, serverConfig)
-	if err != nil {
-		t.Fatalf("handshake failed: %s", err)
-	}
-	if state.CipherSuite != TLS_RSA_WITH_RC4_128_SHA {
-		t.Fatalf("Server's preference was not used, got %x", state.CipherSuite)
-	}
-}
-
-// Note: see comment in handshake_test.go for details of how the reference
-// tests work.
-
-// serverTest represents a test of the TLS server handshake against a reference
-// implementation.
-type serverTest struct {
-	// name is a freeform string identifying the test and the file in which
-	// the expected results will be stored.
-	name string
-	// command, if not empty, contains a series of arguments for the
-	// command to run for the reference server.
-	command []string
-	// expectedPeerCerts contains a list of PEM blocks of expected
-	// certificates from the client.
-	expectedPeerCerts []string
-	// config, if not nil, contains a custom Config to use for this test.
-	config *Config
-}
-
-var defaultClientCommand = []string{"openssl", "s_client", "-no_ticket"}
-
-// connFromCommand starts opens a listening socket and starts the reference
-// client to connect to it. It returns a recordingConn that wraps the resulting
-// connection.
-func (test *serverTest) connFromCommand() (conn *recordingConn, child *exec.Cmd, err error) {
-	l, err := net.ListenTCP("tcp", &net.TCPAddr{
-		IP:   net.IPv4(127, 0, 0, 1),
-		Port: 0,
-	})
-	if err != nil {
-		return nil, nil, err
-	}
-	defer l.Close()
-
-	port := l.Addr().(*net.TCPAddr).Port
-
-	var command []string
-	command = append(command, test.command...)
-	if len(command) == 0 {
-		command = defaultClientCommand
-	}
-	command = append(command, "-connect")
-	command = append(command, fmt.Sprintf("127.0.0.1:%d", port))
-	cmd := exec.Command(command[0], command[1:]...)
-	cmd.Stdin = nil
-	var output bytes.Buffer
-	cmd.Stdout = &output
-	cmd.Stderr = &output
-	if err := cmd.Start(); err != nil {
-		return nil, nil, err
-	}
-
-	connChan := make(chan interface{})
-	go func() {
-		tcpConn, err := l.Accept()
-		if err != nil {
-			connChan <- err
-		}
-		connChan <- tcpConn
-	}()
-
-	var tcpConn net.Conn
-	select {
-	case connOrError := <-connChan:
-		if err, ok := connOrError.(error); ok {
-			return nil, nil, err
-		}
-		tcpConn = connOrError.(net.Conn)
-	case <-time.After(2 * time.Second):
-		output.WriteTo(os.Stdout)
-		return nil, nil, errors.New("timed out waiting for connection from child process")
-	}
-
-	record := &recordingConn{
-		Conn: tcpConn,
-	}
-
-	return record, cmd, nil
-}
-
-func (test *serverTest) dataPath() string {
-	return filepath.Join("testdata", "Server-"+test.name)
-}
-
-func (test *serverTest) loadData() (flows [][]byte, err error) {
-	in, err := os.Open(test.dataPath())
-	if err != nil {
-		return nil, err
-	}
-	defer in.Close()
-	return parseTestData(in)
-}
-
-func (test *serverTest) run(t *testing.T, write bool) {
-	var clientConn, serverConn net.Conn
-	var recordingConn *recordingConn
-	var childProcess *exec.Cmd
-
-	if write {
-		var err error
-		recordingConn, childProcess, err = test.connFromCommand()
-		if err != nil {
-			t.Fatalf("Failed to start subcommand: %s", err)
-		}
-		serverConn = recordingConn
-	} else {
-		clientConn, serverConn = net.Pipe()
-	}
-	config := test.config
-	if config == nil {
-		config = testConfig
-	}
-	server := Server(serverConn, config)
-	peerCertsChan := make(chan []*x509.Certificate, 1)
-	go func() {
-		if _, err := server.Write([]byte("hello, world\n")); err != nil {
-			t.Logf("Error from Server.Write: %s", err)
-		}
-		server.Close()
-		serverConn.Close()
-		peerCertsChan <- server.ConnectionState().PeerCertificates
-	}()
-
-	if !write {
-		flows, err := test.loadData()
-		if err != nil {
-			t.Fatalf("%s: failed to load data from %s", test.name, test.dataPath())
-		}
-		for i, b := range flows {
-			if i%2 == 0 {
-				clientConn.Write(b)
-				continue
-			}
-			bb := make([]byte, len(b))
-			n, err := io.ReadFull(clientConn, bb)
-			if err != nil {
-				t.Fatalf("%s #%d: %s\nRead %d, wanted %d, got %x, wanted %x\n", test.name, i+1, err, n, len(bb), bb[:n], b)
-			}
-			if !bytes.Equal(b, bb) {
-				t.Fatalf("%s #%d: mismatch on read: got:%x want:%x", test.name, i+1, bb, b)
-			}
-		}
-		clientConn.Close()
-	}
-
-	peerCerts := <-peerCertsChan
-	if len(peerCerts) == len(test.expectedPeerCerts) {
-		for i, peerCert := range peerCerts {
-			block, _ := pem.Decode([]byte(test.expectedPeerCerts[i]))
-			if !bytes.Equal(block.Bytes, peerCert.Raw) {
-				t.Fatalf("%s: mismatch on peer cert %d", test.name, i+1)
-			}
-		}
-	} else {
-		t.Fatalf("%s: mismatch on peer list length: %d (wanted) != %d (got)", test.name, len(test.expectedPeerCerts), len(peerCerts))
-	}
-
-	if write {
-		path := test.dataPath()
-		out, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
-		if err != nil {
-			t.Fatalf("Failed to create output file: %s", err)
-		}
-		defer out.Close()
-		recordingConn.Close()
-		if len(recordingConn.flows) < 3 {
-			childProcess.Stdout.(*bytes.Buffer).WriteTo(os.Stdout)
-			t.Fatalf("Handshake failed")
-		}
-		recordingConn.WriteTo(out)
-		fmt.Printf("Wrote %s\n", path)
-		childProcess.Wait()
-	}
-}
-
-func runServerTestForVersion(t *testing.T, template *serverTest, prefix, option string) {
-	test := *template
-	test.name = prefix + test.name
-	if len(test.command) == 0 {
-		test.command = defaultClientCommand
-	}
-	test.command = append([]string(nil), test.command...)
-	test.command = append(test.command, option)
-	test.run(t, *update)
-}
-
-func runServerTestSSLv3(t *testing.T, template *serverTest) {
-	runServerTestForVersion(t, template, "SSLv3-", "-ssl3")
-}
-
-func runServerTestTLS10(t *testing.T, template *serverTest) {
-	runServerTestForVersion(t, template, "TLSv10-", "-tls1")
-}
-
-func runServerTestTLS11(t *testing.T, template *serverTest) {
-	runServerTestForVersion(t, template, "TLSv11-", "-tls1_1")
-}
-
-func runServerTestTLS12(t *testing.T, template *serverTest) {
-	runServerTestForVersion(t, template, "TLSv12-", "-tls1_2")
-}
-
-func TestHandshakeServerRSARC4(t *testing.T) {
-	test := &serverTest{
-		name:    "RSA-RC4",
-		command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "RC4-SHA"},
-	}
-	runServerTestSSLv3(t, test)
-	runServerTestTLS10(t, test)
-	runServerTestTLS11(t, test)
-	runServerTestTLS12(t, test)
-}
-
-func TestHandshakeServerRSA3DES(t *testing.T) {
-	test := &serverTest{
-		name:    "RSA-3DES",
-		command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "DES-CBC3-SHA"},
-	}
-	runServerTestSSLv3(t, test)
-	runServerTestTLS10(t, test)
-	runServerTestTLS12(t, test)
-}
-
-func TestHandshakeServerRSAAES(t *testing.T) {
-	test := &serverTest{
-		name:    "RSA-AES",
-		command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "AES128-SHA"},
-	}
-	runServerTestSSLv3(t, test)
-	runServerTestTLS10(t, test)
-	runServerTestTLS12(t, test)
-}
-
-func TestHandshakeServerAESGCM(t *testing.T) {
-	test := &serverTest{
-		name:    "RSA-AES-GCM",
-		command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "ECDHE-RSA-AES128-GCM-SHA256"},
-	}
-	runServerTestTLS12(t, test)
-}
-
-func TestHandshakeServerECDHEECDSAAES(t *testing.T) {
-	config := *testConfig
-	config.Certificates = make([]Certificate, 1)
-	config.Certificates[0].Certificate = [][]byte{testECDSACertificate}
-	config.Certificates[0].PrivateKey = testECDSAPrivateKey
-	config.BuildNameToCertificate()
-
-	test := &serverTest{
-		name:    "ECDHE-ECDSA-AES",
-		command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "ECDHE-ECDSA-AES256-SHA"},
-		config:  &config,
-	}
-	runServerTestTLS10(t, test)
-	runServerTestTLS12(t, test)
-}
-
-// TestHandshakeServerSNI involves a client sending an SNI extension of
-// "snitest.com", which happens to match the CN of testSNICertificate. The test
-// verifies that the server correctly selects that certificate.
-func TestHandshakeServerSNI(t *testing.T) {
-	test := &serverTest{
-		name:    "SNI",
-		command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "AES128-SHA", "-servername", "snitest.com"},
-	}
-	runServerTestTLS12(t, test)
-}
-
-// TestCipherSuiteCertPreferance ensures that we select an RSA ciphersuite with
-// an RSA certificate and an ECDSA ciphersuite with an ECDSA certificate.
-func TestCipherSuiteCertPreferenceECDSA(t *testing.T) {
-	config := *testConfig
-	config.CipherSuites = []uint16{TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA}
-	config.PreferServerCipherSuites = true
-
-	test := &serverTest{
-		name:   "CipherSuiteCertPreferenceRSA",
-		config: &config,
-	}
-	runServerTestTLS12(t, test)
-
-	config = *testConfig
-	config.CipherSuites = []uint16{TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA}
-	config.Certificates = []Certificate{
-		Certificate{
-			Certificate: [][]byte{testECDSACertificate},
-			PrivateKey:  testECDSAPrivateKey,
-		},
-	}
-	config.BuildNameToCertificate()
-	config.PreferServerCipherSuites = true
-
-	test = &serverTest{
-		name:   "CipherSuiteCertPreferenceECDSA",
-		config: &config,
-	}
-	runServerTestTLS12(t, test)
-}
-
-func TestResumption(t *testing.T) {
-	sessionFilePath := tempFile("")
-	defer os.Remove(sessionFilePath)
-
-	test := &serverTest{
-		name:    "IssueTicket",
-		command: []string{"openssl", "s_client", "-cipher", "RC4-SHA", "-sess_out", sessionFilePath},
-	}
-	runServerTestTLS12(t, test)
-
-	test = &serverTest{
-		name:    "Resume",
-		command: []string{"openssl", "s_client", "-cipher", "RC4-SHA", "-sess_in", sessionFilePath},
-	}
-	runServerTestTLS12(t, test)
-}
-
-func TestResumptionDisabled(t *testing.T) {
-	sessionFilePath := tempFile("")
-	defer os.Remove(sessionFilePath)
-
-	config := *testConfig
-
-	test := &serverTest{
-		name:    "IssueTicketPreDisable",
-		command: []string{"openssl", "s_client", "-cipher", "RC4-SHA", "-sess_out", sessionFilePath},
-		config:  &config,
-	}
-	runServerTestTLS12(t, test)
-
-	config.SessionTicketsDisabled = true
-
-	test = &serverTest{
-		name:    "ResumeDisabled",
-		command: []string{"openssl", "s_client", "-cipher", "RC4-SHA", "-sess_in", sessionFilePath},
-		config:  &config,
-	}
-	runServerTestTLS12(t, test)
-
-	// One needs to manually confirm that the handshake in the golden data
-	// file for ResumeDisabled does not include a resumption handshake.
-}
-
-// cert.pem and key.pem were generated with generate_cert.go
-// Thus, they have no ExtKeyUsage fields and trigger an error
-// when verification is turned on.
-
-const clientCertificatePEM = `
------BEGIN CERTIFICATE-----
-MIIB7TCCAVigAwIBAgIBADALBgkqhkiG9w0BAQUwJjEQMA4GA1UEChMHQWNtZSBD
-bzESMBAGA1UEAxMJMTI3LjAuMC4xMB4XDTExMTIwODA3NTUxMloXDTEyMTIwNzA4
-MDAxMlowJjEQMA4GA1UEChMHQWNtZSBDbzESMBAGA1UEAxMJMTI3LjAuMC4xMIGc
-MAsGCSqGSIb3DQEBAQOBjAAwgYgCgYBO0Hsx44Jk2VnAwoekXh6LczPHY1PfZpIG
-hPZk1Y/kNqcdK+izIDZFI7Xjla7t4PUgnI2V339aEu+H5Fto5OkOdOwEin/ekyfE
-ARl6vfLcPRSr0FTKIQzQTW6HLlzF0rtNS0/Otiz3fojsfNcCkXSmHgwa2uNKWi7e
-E5xMQIhZkwIDAQABozIwMDAOBgNVHQ8BAf8EBAMCAKAwDQYDVR0OBAYEBAECAwQw
-DwYDVR0jBAgwBoAEAQIDBDALBgkqhkiG9w0BAQUDgYEANh+zegx1yW43RmEr1b3A
-p0vMRpqBWHyFeSnIyMZn3TJWRSt1tukkqVCavh9a+hoV2cxVlXIWg7nCto/9iIw4
-hB2rXZIxE0/9gzvGnfERYraL7KtnvshksBFQRlgXa5kc0x38BvEO5ZaoDPl4ILdE
-GFGNEH5PlGffo05wc46QkYU=
------END CERTIFICATE-----`
-
-const clientKeyPEM = `
------BEGIN RSA PRIVATE KEY-----
-MIICWgIBAAKBgE7QezHjgmTZWcDCh6ReHotzM8djU99mkgaE9mTVj+Q2px0r6LMg
-NkUjteOVru3g9SCcjZXff1oS74fkW2jk6Q507ASKf96TJ8QBGXq98tw9FKvQVMoh
-DNBNbocuXMXSu01LT862LPd+iOx81wKRdKYeDBra40paLt4TnExAiFmTAgMBAAEC
-gYBxvXd8yNteFTns8A/2yomEMC4yeosJJSpp1CsN3BJ7g8/qTnrVPxBy+RU+qr63
-t2WquaOu/cr5P8iEsa6lk20tf8pjKLNXeX0b1RTzK8rJLbS7nGzP3tvOhL096VtQ
-dAo4ROEaro0TzYpHmpciSvxVIeEIAAdFDObDJPKqcJAxyQJBAJizfYgK8Gzx9fsx
-hxp+VteCbVPg2euASH5Yv3K5LukRdKoSzHE2grUVQgN/LafC0eZibRanxHegYSr7
-7qaswKUCQQCEIWor/X4XTMdVj3Oj+vpiw75y/S9gh682+myZL+d/02IEkwnB098P
-RkKVpenBHyrGg0oeN5La7URILWKj7CPXAkBKo6F+d+phNjwIFoN1Xb/RA32w/D1I
-saG9sF+UEhRt9AxUfW/U/tIQ9V0ZHHcSg1XaCM5Nvp934brdKdvTOKnJAkBD5h/3
-Rybatlvg/fzBEaJFyq09zhngkxlZOUtBVTqzl17RVvY2orgH02U4HbCHy4phxOn7
-qTdQRYlHRftgnWK1AkANibn9PRYJ7mJyJ9Dyj2QeNcSkSTzrt0tPvUMf4+meJymN
-1Ntu5+S1DLLzfxlaljWG6ylW6DNxujCyuXIV2rvA
------END RSA PRIVATE KEY-----`
-
-const clientECDSACertificatePEM = `
------BEGIN CERTIFICATE-----
-MIIB/DCCAV4CCQCaMIRsJjXZFzAJBgcqhkjOPQQBMEUxCzAJBgNVBAYTAkFVMRMw
-EQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0
-eSBMdGQwHhcNMTIxMTE0MTMyNTUzWhcNMjIxMTEyMTMyNTUzWjBBMQswCQYDVQQG
-EwJBVTEMMAoGA1UECBMDTlNXMRAwDgYDVQQHEwdQeXJtb250MRIwEAYDVQQDEwlK
-b2VsIFNpbmcwgZswEAYHKoZIzj0CAQYFK4EEACMDgYYABACVjJF1FMBexFe01MNv
-ja5oHt1vzobhfm6ySD6B5U7ixohLZNz1MLvT/2XMW/TdtWo+PtAd3kfDdq0Z9kUs
-jLzYHQFMH3CQRnZIi4+DzEpcj0B22uCJ7B0rxE4wdihBsmKo+1vx+U56jb0JuK7q
-ixgnTy5w/hOWusPTQBbNZU6sER7m8TAJBgcqhkjOPQQBA4GMADCBiAJCAOAUxGBg
-C3JosDJdYUoCdFzCgbkWqD8pyDbHgf9stlvZcPE4O1BIKJTLCRpS8V3ujfK58PDa
-2RU6+b0DeoeiIzXsAkIBo9SKeDUcSpoj0gq+KxAxnZxfvuiRs9oa9V2jI/Umi0Vw
-jWVim34BmT0Y9hCaOGGbLlfk+syxis7iI6CH8OFnUes=
------END CERTIFICATE-----`
-
-const clientECDSAKeyPEM = `
------BEGIN EC PARAMETERS-----
-BgUrgQQAIw==
------END EC PARAMETERS-----
------BEGIN EC PRIVATE KEY-----
-MIHcAgEBBEIBkJN9X4IqZIguiEVKMqeBUP5xtRsEv4HJEtOpOGLELwO53SD78Ew8
-k+wLWoqizS3NpQyMtrU8JFdWfj+C57UNkOugBwYFK4EEACOhgYkDgYYABACVjJF1
-FMBexFe01MNvja5oHt1vzobhfm6ySD6B5U7ixohLZNz1MLvT/2XMW/TdtWo+PtAd
-3kfDdq0Z9kUsjLzYHQFMH3CQRnZIi4+DzEpcj0B22uCJ7B0rxE4wdihBsmKo+1vx
-+U56jb0JuK7qixgnTy5w/hOWusPTQBbNZU6sER7m8Q==
------END EC PRIVATE KEY-----`
-
-func TestClientAuth(t *testing.T) {
-	var certPath, keyPath, ecdsaCertPath, ecdsaKeyPath string
-
-	if *update {
-		certPath = tempFile(clientCertificatePEM)
-		defer os.Remove(certPath)
-		keyPath = tempFile(clientKeyPEM)
-		defer os.Remove(keyPath)
-		ecdsaCertPath = tempFile(clientECDSACertificatePEM)
-		defer os.Remove(ecdsaCertPath)
-		ecdsaKeyPath = tempFile(clientECDSAKeyPEM)
-		defer os.Remove(ecdsaKeyPath)
-	}
-
-	config := *testConfig
-	config.ClientAuth = RequestClientCert
-
-	test := &serverTest{
-		name:    "ClientAuthRequestedNotGiven",
-		command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "RC4-SHA"},
-		config:  &config,
-	}
-	runServerTestTLS12(t, test)
-
-	test = &serverTest{
-		name:              "ClientAuthRequestedAndGiven",
-		command:           []string{"openssl", "s_client", "-no_ticket", "-cipher", "RC4-SHA", "-cert", certPath, "-key", keyPath},
-		config:            &config,
-		expectedPeerCerts: []string{clientCertificatePEM},
-	}
-	runServerTestTLS12(t, test)
-
-	test = &serverTest{
-		name:              "ClientAuthRequestedAndECDSAGiven",
-		command:           []string{"openssl", "s_client", "-no_ticket", "-cipher", "RC4-SHA", "-cert", ecdsaCertPath, "-key", ecdsaKeyPath},
-		config:            &config,
-		expectedPeerCerts: []string{clientECDSACertificatePEM},
-	}
-	runServerTestTLS12(t, test)
-}
-
-func bigFromString(s string) *big.Int {
-	ret := new(big.Int)
-	ret.SetString(s, 10)
-	return ret
-}
-
-func fromHex(s string) []byte {
-	b, _ := hex.DecodeString(s)
-	return b
-}
-
-var testRSACertificate = fromHex("308202b030820219a00302010202090085b0bba48a7fb8ca300d06092a864886f70d01010505003045310b3009060355040613024155311330110603550408130a536f6d652d53746174653121301f060355040a1318496e7465726e6574205769646769747320507479204c7464301e170d3130303432343039303933385a170d3131303432343039303933385a3045310b3009060355040613024155311330110603550408130a536f6d652d53746174653121301f060355040a1318496e7465726e6574205769646769747320507479204c746430819f300d06092a864886f70d010101 [...]
-
-var testECDSACertificate = fromHex("3082020030820162020900b8bf2d47a0d2ebf4300906072a8648ce3d04013045310b3009060355040613024155311330110603550408130a536f6d652d53746174653121301f060355040a1318496e7465726e6574205769646769747320507479204c7464301e170d3132313132323135303633325a170d3232313132303135303633325a3045310b3009060355040613024155311330110603550408130a536f6d652d53746174653121301f060355040a1318496e7465726e6574205769646769747320507479204c746430819b301006072a8648ce3d020106052b81040023038186 [...]
-
-var testSNICertificate = fromHex("308201f23082015da003020102020100300b06092a864886f70d01010530283110300e060355040a130741636d6520436f311430120603550403130b736e69746573742e636f6d301e170d3132303431313137343033355a170d3133303431313137343533355a30283110300e060355040a130741636d6520436f311430120603550403130b736e69746573742e636f6d30819d300b06092a864886f70d01010103818d0030818902818100bb79d6f517b5e5bf4610d0dc69bee62b07435ad0032d8a7a4385b71452e7a5654c2c78b8238cb5b482e5de1f953b7e62a52ca533d6fe125c7a [...]
-
-var testRSAPrivateKey = &rsa.PrivateKey{
-	PublicKey: rsa.PublicKey{
-		N: bigFromString("131650079503776001033793877885499001334664249354723305978524647182322416328664556247316495448366990052837680518067798333412266673813370895702118944398081598789828837447552603077848001020611640547221687072142537202428102790818451901395596882588063427854225330436740647715202971973145151161964464812406232198521"),
-		E: 65537,
-	},
-	D: bigFromString("29354450337804273969007277378287027274721892607543397931919078829901848876371746653677097639302788129485893852488285045793268732234230875671682624082413996177431586734171663258657462237320300610850244186316880055243099640544518318093544057213190320837094958164973959123058337475052510833916491060913053867729"),
-	Primes: []*big.Int{
-		bigFromString("11969277782311800166562047708379380720136961987713178380670422671426759650127150688426177829077494755200794297055316163155755835813760102405344560929062149"),
-		bigFromString("10998999429884441391899182616418192492905073053684657075974935218461686523870125521822756579792315215543092255516093840728890783887287417039645833477273829"),
-	},
-}
-
-var testECDSAPrivateKey = &ecdsa.PrivateKey{
-	PublicKey: ecdsa.PublicKey{
-		Curve: elliptic.P521(),
-		X:     bigFromString("2636411247892461147287360222306590634450676461695221912739908880441342231985950069527906976759812296359387337367668045707086543273113073382714101597903639351"),
-		Y:     bigFromString("3204695818431246682253994090650952614555094516658732116404513121125038617915183037601737180082382202488628239201196033284060130040574800684774115478859677243"),
-	},
-	D: bigFromString("5477294338614160138026852784385529180817726002953041720191098180813046231640184669647735805135001309477695746518160084669446643325196003346204701381388769751"),
-}
diff --git a/src/pkg/crypto/tls/key_agreement.go b/src/pkg/crypto/tls/key_agreement.go
deleted file mode 100644
index f38b701..0000000
--- a/src/pkg/crypto/tls/key_agreement.go
+++ /dev/null
@@ -1,407 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package tls
-
-import (
-	"crypto"
-	"crypto/ecdsa"
-	"crypto/elliptic"
-	"crypto/md5"
-	"crypto/rsa"
-	"crypto/sha1"
-	"crypto/sha256"
-	"crypto/x509"
-	"encoding/asn1"
-	"errors"
-	"io"
-	"math/big"
-)
-
-var errClientKeyExchange = errors.New("tls: invalid ClientKeyExchange message")
-var errServerKeyExchange = errors.New("tls: invalid ServerKeyExchange message")
-
-// rsaKeyAgreement implements the standard TLS key agreement where the client
-// encrypts the pre-master secret to the server's public key.
-type rsaKeyAgreement struct{}
-
-func (ka rsaKeyAgreement) generateServerKeyExchange(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) {
-	return nil, nil
-}
-
-func (ka rsaKeyAgreement) processClientKeyExchange(config *Config, cert *Certificate, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) {
-	preMasterSecret := make([]byte, 48)
-	_, err := io.ReadFull(config.rand(), preMasterSecret[2:])
-	if err != nil {
-		return nil, err
-	}
-
-	if len(ckx.ciphertext) < 2 {
-		return nil, errClientKeyExchange
-	}
-
-	ciphertext := ckx.ciphertext
-	if version != VersionSSL30 {
-		ciphertextLen := int(ckx.ciphertext[0])<<8 | int(ckx.ciphertext[1])
-		if ciphertextLen != len(ckx.ciphertext)-2 {
-			return nil, errClientKeyExchange
-		}
-		ciphertext = ckx.ciphertext[2:]
-	}
-
-	err = rsa.DecryptPKCS1v15SessionKey(config.rand(), cert.PrivateKey.(*rsa.PrivateKey), ciphertext, preMasterSecret)
-	if err != nil {
-		return nil, err
-	}
-	// We don't check the version number in the premaster secret.  For one,
-	// by checking it, we would leak information about the validity of the
-	// encrypted pre-master secret. Secondly, it provides only a small
-	// benefit against a downgrade attack and some implementations send the
-	// wrong version anyway. See the discussion at the end of section
-	// 7.4.7.1 of RFC 4346.
-	return preMasterSecret, nil
-}
-
-func (ka rsaKeyAgreement) processServerKeyExchange(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, cert *x509.Certificate, skx *serverKeyExchangeMsg) error {
-	return errors.New("tls: unexpected ServerKeyExchange")
-}
-
-func (ka rsaKeyAgreement) generateClientKeyExchange(config *Config, clientHello *clientHelloMsg, cert *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) {
-	preMasterSecret := make([]byte, 48)
-	preMasterSecret[0] = byte(clientHello.vers >> 8)
-	preMasterSecret[1] = byte(clientHello.vers)
-	_, err := io.ReadFull(config.rand(), preMasterSecret[2:])
-	if err != nil {
-		return nil, nil, err
-	}
-
-	encrypted, err := rsa.EncryptPKCS1v15(config.rand(), cert.PublicKey.(*rsa.PublicKey), preMasterSecret)
-	if err != nil {
-		return nil, nil, err
-	}
-	ckx := new(clientKeyExchangeMsg)
-	ckx.ciphertext = make([]byte, len(encrypted)+2)
-	ckx.ciphertext[0] = byte(len(encrypted) >> 8)
-	ckx.ciphertext[1] = byte(len(encrypted))
-	copy(ckx.ciphertext[2:], encrypted)
-	return preMasterSecret, ckx, nil
-}
-
-// sha1Hash calculates a SHA1 hash over the given byte slices.
-func sha1Hash(slices [][]byte) []byte {
-	hsha1 := sha1.New()
-	for _, slice := range slices {
-		hsha1.Write(slice)
-	}
-	return hsha1.Sum(nil)
-}
-
-// md5SHA1Hash implements TLS 1.0's hybrid hash function which consists of the
-// concatenation of an MD5 and SHA1 hash.
-func md5SHA1Hash(slices [][]byte) []byte {
-	md5sha1 := make([]byte, md5.Size+sha1.Size)
-	hmd5 := md5.New()
-	for _, slice := range slices {
-		hmd5.Write(slice)
-	}
-	copy(md5sha1, hmd5.Sum(nil))
-	copy(md5sha1[md5.Size:], sha1Hash(slices))
-	return md5sha1
-}
-
-// sha256Hash implements TLS 1.2's hash function.
-func sha256Hash(slices [][]byte) []byte {
-	h := sha256.New()
-	for _, slice := range slices {
-		h.Write(slice)
-	}
-	return h.Sum(nil)
-}
-
-// hashForServerKeyExchange hashes the given slices and returns their digest
-// and the identifier of the hash function used. The hashFunc argument is only
-// used for >= TLS 1.2 and precisely identifies the hash function to use.
-func hashForServerKeyExchange(sigType, hashFunc uint8, version uint16, slices ...[]byte) ([]byte, crypto.Hash, error) {
-	if version >= VersionTLS12 {
-		switch hashFunc {
-		case hashSHA256:
-			return sha256Hash(slices), crypto.SHA256, nil
-		case hashSHA1:
-			return sha1Hash(slices), crypto.SHA1, nil
-		default:
-			return nil, crypto.Hash(0), errors.New("tls: unknown hash function used by peer")
-		}
-	}
-	if sigType == signatureECDSA {
-		return sha1Hash(slices), crypto.SHA1, nil
-	}
-	return md5SHA1Hash(slices), crypto.MD5SHA1, nil
-}
-
-// pickTLS12HashForSignature returns a TLS 1.2 hash identifier for signing a
-// ServerKeyExchange given the signature type being used and the client's
-// advertised list of supported signature and hash combinations.
-func pickTLS12HashForSignature(sigType uint8, clientSignatureAndHashes []signatureAndHash) (uint8, error) {
-	if len(clientSignatureAndHashes) == 0 {
-		// If the client didn't specify any signature_algorithms
-		// extension then we can assume that it supports SHA1. See
-		// http://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
-		return hashSHA1, nil
-	}
-
-	for _, sigAndHash := range clientSignatureAndHashes {
-		if sigAndHash.signature != sigType {
-			continue
-		}
-		switch sigAndHash.hash {
-		case hashSHA1, hashSHA256:
-			return sigAndHash.hash, nil
-		}
-	}
-
-	return 0, errors.New("tls: client doesn't support any common hash functions")
-}
-
-func curveForCurveID(id CurveID) (elliptic.Curve, bool) {
-	switch id {
-	case CurveP256:
-		return elliptic.P256(), true
-	case CurveP384:
-		return elliptic.P384(), true
-	case CurveP521:
-		return elliptic.P521(), true
-	default:
-		return nil, false
-	}
-
-}
-
-// ecdheRSAKeyAgreement implements a TLS key agreement where the server
-// generates a ephemeral EC public/private key pair and signs it. The
-// pre-master secret is then calculated using ECDH. The signature may
-// either be ECDSA or RSA.
-type ecdheKeyAgreement struct {
-	version    uint16
-	sigType    uint8
-	privateKey []byte
-	curve      elliptic.Curve
-	x, y       *big.Int
-}
-
-func (ka *ecdheKeyAgreement) generateServerKeyExchange(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) {
-	var curveid CurveID
-	preferredCurves := config.curvePreferences()
-
-NextCandidate:
-	for _, candidate := range preferredCurves {
-		for _, c := range clientHello.supportedCurves {
-			if candidate == c {
-				curveid = c
-				break NextCandidate
-			}
-		}
-	}
-
-	if curveid == 0 {
-		return nil, errors.New("tls: no supported elliptic curves offered")
-	}
-
-	var ok bool
-	if ka.curve, ok = curveForCurveID(curveid); !ok {
-		return nil, errors.New("tls: preferredCurves includes unsupported curve")
-	}
-
-	var x, y *big.Int
-	var err error
-	ka.privateKey, x, y, err = elliptic.GenerateKey(ka.curve, config.rand())
-	if err != nil {
-		return nil, err
-	}
-	ecdhePublic := elliptic.Marshal(ka.curve, x, y)
-
-	// http://tools.ietf.org/html/rfc4492#section-5.4
-	serverECDHParams := make([]byte, 1+2+1+len(ecdhePublic))
-	serverECDHParams[0] = 3 // named curve
-	serverECDHParams[1] = byte(curveid >> 8)
-	serverECDHParams[2] = byte(curveid)
-	serverECDHParams[3] = byte(len(ecdhePublic))
-	copy(serverECDHParams[4:], ecdhePublic)
-
-	var tls12HashId uint8
-	if ka.version >= VersionTLS12 {
-		if tls12HashId, err = pickTLS12HashForSignature(ka.sigType, clientHello.signatureAndHashes); err != nil {
-			return nil, err
-		}
-	}
-
-	digest, hashFunc, err := hashForServerKeyExchange(ka.sigType, tls12HashId, ka.version, clientHello.random, hello.random, serverECDHParams)
-	if err != nil {
-		return nil, err
-	}
-	var sig []byte
-	switch ka.sigType {
-	case signatureECDSA:
-		privKey, ok := cert.PrivateKey.(*ecdsa.PrivateKey)
-		if !ok {
-			return nil, errors.New("ECDHE ECDSA requires an ECDSA server private key")
-		}
-		r, s, err := ecdsa.Sign(config.rand(), privKey, digest)
-		if err != nil {
-			return nil, errors.New("failed to sign ECDHE parameters: " + err.Error())
-		}
-		sig, err = asn1.Marshal(ecdsaSignature{r, s})
-	case signatureRSA:
-		privKey, ok := cert.PrivateKey.(*rsa.PrivateKey)
-		if !ok {
-			return nil, errors.New("ECDHE RSA requires a RSA server private key")
-		}
-		sig, err = rsa.SignPKCS1v15(config.rand(), privKey, hashFunc, digest)
-		if err != nil {
-			return nil, errors.New("failed to sign ECDHE parameters: " + err.Error())
-		}
-	default:
-		return nil, errors.New("unknown ECDHE signature algorithm")
-	}
-
-	skx := new(serverKeyExchangeMsg)
-	sigAndHashLen := 0
-	if ka.version >= VersionTLS12 {
-		sigAndHashLen = 2
-	}
-	skx.key = make([]byte, len(serverECDHParams)+sigAndHashLen+2+len(sig))
-	copy(skx.key, serverECDHParams)
-	k := skx.key[len(serverECDHParams):]
-	if ka.version >= VersionTLS12 {
-		k[0] = tls12HashId
-		k[1] = ka.sigType
-		k = k[2:]
-	}
-	k[0] = byte(len(sig) >> 8)
-	k[1] = byte(len(sig))
-	copy(k[2:], sig)
-
-	return skx, nil
-}
-
-func (ka *ecdheKeyAgreement) processClientKeyExchange(config *Config, cert *Certificate, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) {
-	if len(ckx.ciphertext) == 0 || int(ckx.ciphertext[0]) != len(ckx.ciphertext)-1 {
-		return nil, errClientKeyExchange
-	}
-	x, y := elliptic.Unmarshal(ka.curve, ckx.ciphertext[1:])
-	if x == nil {
-		return nil, errClientKeyExchange
-	}
-	x, _ = ka.curve.ScalarMult(x, y, ka.privateKey)
-	preMasterSecret := make([]byte, (ka.curve.Params().BitSize+7)>>3)
-	xBytes := x.Bytes()
-	copy(preMasterSecret[len(preMasterSecret)-len(xBytes):], xBytes)
-
-	return preMasterSecret, nil
-}
-
-func (ka *ecdheKeyAgreement) processServerKeyExchange(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, cert *x509.Certificate, skx *serverKeyExchangeMsg) error {
-	if len(skx.key) < 4 {
-		return errServerKeyExchange
-	}
-	if skx.key[0] != 3 { // named curve
-		return errors.New("tls: server selected unsupported curve")
-	}
-	curveid := CurveID(skx.key[1])<<8 | CurveID(skx.key[2])
-
-	var ok bool
-	if ka.curve, ok = curveForCurveID(curveid); !ok {
-		return errors.New("tls: server selected unsupported curve")
-	}
-
-	publicLen := int(skx.key[3])
-	if publicLen+4 > len(skx.key) {
-		return errServerKeyExchange
-	}
-	ka.x, ka.y = elliptic.Unmarshal(ka.curve, skx.key[4:4+publicLen])
-	if ka.x == nil {
-		return errServerKeyExchange
-	}
-	serverECDHParams := skx.key[:4+publicLen]
-
-	sig := skx.key[4+publicLen:]
-	if len(sig) < 2 {
-		return errServerKeyExchange
-	}
-
-	var tls12HashId uint8
-	if ka.version >= VersionTLS12 {
-		// handle SignatureAndHashAlgorithm
-		var sigAndHash []uint8
-		sigAndHash, sig = sig[:2], sig[2:]
-		if sigAndHash[1] != ka.sigType {
-			return errServerKeyExchange
-		}
-		tls12HashId = sigAndHash[0]
-		if len(sig) < 2 {
-			return errServerKeyExchange
-		}
-	}
-	sigLen := int(sig[0])<<8 | int(sig[1])
-	if sigLen+2 != len(sig) {
-		return errServerKeyExchange
-	}
-	sig = sig[2:]
-
-	digest, hashFunc, err := hashForServerKeyExchange(ka.sigType, tls12HashId, ka.version, clientHello.random, serverHello.random, serverECDHParams)
-	if err != nil {
-		return err
-	}
-	switch ka.sigType {
-	case signatureECDSA:
-		pubKey, ok := cert.PublicKey.(*ecdsa.PublicKey)
-		if !ok {
-			return errors.New("ECDHE ECDSA requires a ECDSA server public key")
-		}
-		ecdsaSig := new(ecdsaSignature)
-		if _, err := asn1.Unmarshal(sig, ecdsaSig); err != nil {
-			return err
-		}
-		if ecdsaSig.R.Sign() <= 0 || ecdsaSig.S.Sign() <= 0 {
-			return errors.New("ECDSA signature contained zero or negative values")
-		}
-		if !ecdsa.Verify(pubKey, digest, ecdsaSig.R, ecdsaSig.S) {
-			return errors.New("ECDSA verification failure")
-		}
-	case signatureRSA:
-		pubKey, ok := cert.PublicKey.(*rsa.PublicKey)
-		if !ok {
-			return errors.New("ECDHE RSA requires a RSA server public key")
-		}
-		if err := rsa.VerifyPKCS1v15(pubKey, hashFunc, digest, sig); err != nil {
-			return err
-		}
-	default:
-		return errors.New("unknown ECDHE signature algorithm")
-	}
-
-	return nil
-}
-
-func (ka *ecdheKeyAgreement) generateClientKeyExchange(config *Config, clientHello *clientHelloMsg, cert *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) {
-	if ka.curve == nil {
-		return nil, nil, errors.New("missing ServerKeyExchange message")
-	}
-	priv, mx, my, err := elliptic.GenerateKey(ka.curve, config.rand())
-	if err != nil {
-		return nil, nil, err
-	}
-	x, _ := ka.curve.ScalarMult(ka.x, ka.y, priv)
-	preMasterSecret := make([]byte, (ka.curve.Params().BitSize+7)>>3)
-	xBytes := x.Bytes()
-	copy(preMasterSecret[len(preMasterSecret)-len(xBytes):], xBytes)
-
-	serialized := elliptic.Marshal(ka.curve, mx, my)
-
-	ckx := new(clientKeyExchangeMsg)
-	ckx.ciphertext = make([]byte, 1+len(serialized))
-	ckx.ciphertext[0] = byte(len(serialized))
-	copy(ckx.ciphertext[1:], serialized)
-
-	return preMasterSecret, ckx, nil
-}
diff --git a/src/pkg/crypto/tls/tls_test.go b/src/pkg/crypto/tls/tls_test.go
deleted file mode 100644
index f8c94ff..0000000
--- a/src/pkg/crypto/tls/tls_test.go
+++ /dev/null
@@ -1,237 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package tls
-
-import (
-	"fmt"
-	"io"
-	"net"
-	"strings"
-	"testing"
-	"time"
-)
-
-var rsaCertPEM = `-----BEGIN CERTIFICATE-----
-MIIB0zCCAX2gAwIBAgIJAI/M7BYjwB+uMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV
-BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
-aWRnaXRzIFB0eSBMdGQwHhcNMTIwOTEyMjE1MjAyWhcNMTUwOTEyMjE1MjAyWjBF
-MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50
-ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANLJ
-hPHhITqQbPklG3ibCVxwGMRfp/v4XqhfdQHdcVfHap6NQ5Wok/4xIA+ui35/MmNa
-rtNuC+BdZ1tMuVCPFZcCAwEAAaNQME4wHQYDVR0OBBYEFJvKs8RfJaXTH08W+SGv
-zQyKn0H8MB8GA1UdIwQYMBaAFJvKs8RfJaXTH08W+SGvzQyKn0H8MAwGA1UdEwQF
-MAMBAf8wDQYJKoZIhvcNAQEFBQADQQBJlffJHybjDGxRMqaRmDhX0+6v02TUKZsW
-r5QuVbpQhH6u+0UgcW0jp9QwpxoPTLTWGXEWBBBurxFwiCBhkQ+V
------END CERTIFICATE-----
-`
-
-var rsaKeyPEM = `-----BEGIN RSA PRIVATE KEY-----
-MIIBOwIBAAJBANLJhPHhITqQbPklG3ibCVxwGMRfp/v4XqhfdQHdcVfHap6NQ5Wo
-k/4xIA+ui35/MmNartNuC+BdZ1tMuVCPFZcCAwEAAQJAEJ2N+zsR0Xn8/Q6twa4G
-6OB1M1WO+k+ztnX/1SvNeWu8D6GImtupLTYgjZcHufykj09jiHmjHx8u8ZZB/o1N
-MQIhAPW+eyZo7ay3lMz1V01WVjNKK9QSn1MJlb06h/LuYv9FAiEA25WPedKgVyCW
-SmUwbPw8fnTcpqDWE3yTO3vKcebqMSsCIBF3UmVue8YU3jybC3NxuXq3wNm34R8T
-xVLHwDXh/6NJAiEAl2oHGGLz64BuAfjKrqwz7qMYr9HCLIe/YsoWq/olzScCIQDi
-D2lWusoe2/nEqfDVVWGWlyJ7yOmqaVm/iNUN9B2N2g==
------END RSA PRIVATE KEY-----
-`
-
-// keyPEM is the same as rsaKeyPEM, but declares itself as just
-// "PRIVATE KEY", not "RSA PRIVATE KEY".  http://golang.org/issue/4477
-var keyPEM = `-----BEGIN PRIVATE KEY-----
-MIIBOwIBAAJBANLJhPHhITqQbPklG3ibCVxwGMRfp/v4XqhfdQHdcVfHap6NQ5Wo
-k/4xIA+ui35/MmNartNuC+BdZ1tMuVCPFZcCAwEAAQJAEJ2N+zsR0Xn8/Q6twa4G
-6OB1M1WO+k+ztnX/1SvNeWu8D6GImtupLTYgjZcHufykj09jiHmjHx8u8ZZB/o1N
-MQIhAPW+eyZo7ay3lMz1V01WVjNKK9QSn1MJlb06h/LuYv9FAiEA25WPedKgVyCW
-SmUwbPw8fnTcpqDWE3yTO3vKcebqMSsCIBF3UmVue8YU3jybC3NxuXq3wNm34R8T
-xVLHwDXh/6NJAiEAl2oHGGLz64BuAfjKrqwz7qMYr9HCLIe/YsoWq/olzScCIQDi
-D2lWusoe2/nEqfDVVWGWlyJ7yOmqaVm/iNUN9B2N2g==
------END PRIVATE KEY-----
-`
-
-var ecdsaCertPEM = `-----BEGIN CERTIFICATE-----
-MIIB/jCCAWICCQDscdUxw16XFDAJBgcqhkjOPQQBMEUxCzAJBgNVBAYTAkFVMRMw
-EQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0
-eSBMdGQwHhcNMTIxMTE0MTI0MDQ4WhcNMTUxMTE0MTI0MDQ4WjBFMQswCQYDVQQG
-EwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lk
-Z2l0cyBQdHkgTHRkMIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQBY9+my9OoeSUR
-lDQdV/x8LsOuLilthhiS1Tz4aGDHIPwC1mlvnf7fg5lecYpMCrLLhauAc1UJXcgl
-01xoLuzgtAEAgv2P/jgytzRSpUYvgLBt1UA0leLYBy6mQQbrNEuqT3INapKIcUv8
-XxYP0xMEUksLPq6Ca+CRSqTtrd/23uTnapkwCQYHKoZIzj0EAQOBigAwgYYCQXJo
-A7Sl2nLVf+4Iu/tAX/IF4MavARKC4PPHK3zfuGfPR3oCCcsAoz3kAzOeijvd0iXb
-H5jBImIxPL4WxQNiBTexAkF8D1EtpYuWdlVQ80/h/f4pBcGiXPqX5h2PQSQY7hP1
-+jwM1FGS4fREIOvlBYr/SzzQRtwrvrzGYxDEDbsC0ZGRnA==
------END CERTIFICATE-----
-`
-
-var ecdsaKeyPEM = `-----BEGIN EC PARAMETERS-----
-BgUrgQQAIw==
------END EC PARAMETERS-----
------BEGIN EC PRIVATE KEY-----
-MIHcAgEBBEIBrsoKp0oqcv6/JovJJDoDVSGWdirrkgCWxrprGlzB9o0X8fV675X0
-NwuBenXFfeZvVcwluO7/Q9wkYoPd/t3jGImgBwYFK4EEACOhgYkDgYYABAFj36bL
-06h5JRGUNB1X/Hwuw64uKW2GGJLVPPhoYMcg/ALWaW+d/t+DmV5xikwKssuFq4Bz
-VQldyCXTXGgu7OC0AQCC/Y/+ODK3NFKlRi+AsG3VQDSV4tgHLqZBBus0S6pPcg1q
-kohxS/xfFg/TEwRSSws+roJr4JFKpO2t3/be5OdqmQ==
------END EC PRIVATE KEY-----
-`
-
-var keyPairTests = []struct {
-	algo string
-	cert string
-	key  string
-}{
-	{"ECDSA", ecdsaCertPEM, ecdsaKeyPEM},
-	{"RSA", rsaCertPEM, rsaKeyPEM},
-	{"RSA-untyped", rsaCertPEM, keyPEM}, // golang.org/issue/4477
-}
-
-func TestX509KeyPair(t *testing.T) {
-	var pem []byte
-	for _, test := range keyPairTests {
-		pem = []byte(test.cert + test.key)
-		if _, err := X509KeyPair(pem, pem); err != nil {
-			t.Errorf("Failed to load %s cert followed by %s key: %s", test.algo, test.algo, err)
-		}
-		pem = []byte(test.key + test.cert)
-		if _, err := X509KeyPair(pem, pem); err != nil {
-			t.Errorf("Failed to load %s key followed by %s cert: %s", test.algo, test.algo, err)
-		}
-	}
-}
-
-func TestX509MixedKeyPair(t *testing.T) {
-	if _, err := X509KeyPair([]byte(rsaCertPEM), []byte(ecdsaKeyPEM)); err == nil {
-		t.Error("Load of RSA certificate succeeded with ECDSA private key")
-	}
-	if _, err := X509KeyPair([]byte(ecdsaCertPEM), []byte(rsaKeyPEM)); err == nil {
-		t.Error("Load of ECDSA certificate succeeded with RSA private key")
-	}
-}
-
-func newLocalListener(t *testing.T) net.Listener {
-	ln, err := net.Listen("tcp", "127.0.0.1:0")
-	if err != nil {
-		ln, err = net.Listen("tcp6", "[::1]:0")
-	}
-	if err != nil {
-		t.Fatal(err)
-	}
-	return ln
-}
-
-func TestDialTimeout(t *testing.T) {
-	if testing.Short() {
-		t.Skip("skipping in short mode")
-	}
-	listener := newLocalListener(t)
-
-	addr := listener.Addr().String()
-	defer listener.Close()
-
-	complete := make(chan bool)
-	defer close(complete)
-
-	go func() {
-		conn, err := listener.Accept()
-		if err != nil {
-			t.Error(err)
-			return
-		}
-		<-complete
-		conn.Close()
-	}()
-
-	dialer := &net.Dialer{
-		Timeout: 10 * time.Millisecond,
-	}
-
-	var err error
-	if _, err = DialWithDialer(dialer, "tcp", addr, nil); err == nil {
-		t.Fatal("DialWithTimeout completed successfully")
-	}
-
-	if !strings.Contains(err.Error(), "timed out") {
-		t.Errorf("resulting error not a timeout: %s", err)
-	}
-}
-
-// tests that Conn.Read returns (non-zero, io.EOF) instead of
-// (non-zero, nil) when a Close (alertCloseNotify) is sitting right
-// behind the application data in the buffer.
-func TestConnReadNonzeroAndEOF(t *testing.T) {
-	// This test is racy: it assumes that after a write to a
-	// localhost TCP connection, the peer TCP connection can
-	// immediately read it.  Because it's racy, we skip this test
-	// in short mode, and then retry it several times with an
-	// increasing sleep in between our final write (via srv.Close
-	// below) and the following read.
-	if testing.Short() {
-		t.Skip("skipping in short mode")
-	}
-	var err error
-	for delay := time.Millisecond; delay <= 64*time.Millisecond; delay *= 2 {
-		if err = testConnReadNonzeroAndEOF(t, delay); err == nil {
-			return
-		}
-	}
-	t.Error(err)
-}
-
-func testConnReadNonzeroAndEOF(t *testing.T, delay time.Duration) error {
-	ln := newLocalListener(t)
-	defer ln.Close()
-
-	srvCh := make(chan *Conn, 1)
-	var serr error
-	go func() {
-		sconn, err := ln.Accept()
-		if err != nil {
-			serr = err
-			srvCh <- nil
-			return
-		}
-		serverConfig := *testConfig
-		srv := Server(sconn, &serverConfig)
-		if err := srv.Handshake(); err != nil {
-			serr = fmt.Errorf("handshake: %v", err)
-			srvCh <- nil
-			return
-		}
-		srvCh <- srv
-	}()
-
-	clientConfig := *testConfig
-	conn, err := Dial("tcp", ln.Addr().String(), &clientConfig)
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer conn.Close()
-
-	srv := <-srvCh
-	if srv == nil {
-		return serr
-	}
-
-	buf := make([]byte, 6)
-
-	srv.Write([]byte("foobar"))
-	n, err := conn.Read(buf)
-	if n != 6 || err != nil || string(buf) != "foobar" {
-		return fmt.Errorf("Read = %d, %v, data %q; want 6, nil, foobar", n, err, buf)
-	}
-
-	srv.Write([]byte("abcdef"))
-	srv.Close()
-	time.Sleep(delay)
-	n, err = conn.Read(buf)
-	if n != 6 || string(buf) != "abcdef" {
-		return fmt.Errorf("Read = %d, buf= %q; want 6, abcdef", n, buf)
-	}
-	if err != io.EOF {
-		return fmt.Errorf("Second Read error = %v; want io.EOF", err)
-	}
-	return nil
-}
diff --git a/src/pkg/crypto/x509/pem_decrypt_test.go b/src/pkg/crypto/x509/pem_decrypt_test.go
deleted file mode 100644
index 59ba6f9..0000000
--- a/src/pkg/crypto/x509/pem_decrypt_test.go
+++ /dev/null
@@ -1,223 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package x509
-
-import (
-	"bytes"
-	"crypto/rand"
-	"encoding/base64"
-	"encoding/pem"
-	"testing"
-)
-
-func TestDecrypt(t *testing.T) {
-	for i, data := range testData {
-		t.Logf("test %d. %s", i, data.kind)
-		block, rest := pem.Decode(data.pemData)
-		if len(rest) > 0 {
-			t.Error("extra data")
-		}
-		der, err := DecryptPEMBlock(block, data.password)
-		if err != nil {
-			t.Error("decrypt failed: ", err)
-			continue
-		}
-		if _, err := ParsePKCS1PrivateKey(der); err != nil {
-			t.Error("invalid private key: ", err)
-		}
-		plainDER, err := base64.StdEncoding.DecodeString(data.plainDER)
-		if err != nil {
-			t.Fatal("cannot decode test DER data: ", err)
-		}
-		if !bytes.Equal(der, plainDER) {
-			t.Error("data mismatch")
-		}
-	}
-}
-
-func TestEncrypt(t *testing.T) {
-	for i, data := range testData {
-		t.Logf("test %d. %s", i, data.kind)
-		plainDER, err := base64.StdEncoding.DecodeString(data.plainDER)
-		if err != nil {
-			t.Fatal("cannot decode test DER data: ", err)
-		}
-		password := []byte("kremvax1")
-		block, err := EncryptPEMBlock(rand.Reader, "RSA PRIVATE KEY", plainDER, password, data.kind)
-		if err != nil {
-			t.Error("encrypt: ", err)
-			continue
-		}
-		if !IsEncryptedPEMBlock(block) {
-			t.Error("PEM block does not appear to be encrypted")
-		}
-		if block.Type != "RSA PRIVATE KEY" {
-			t.Errorf("unexpected block type; got %q want %q", block.Type, "RSA PRIVATE KEY")
-		}
-		if block.Headers["Proc-Type"] != "4,ENCRYPTED" {
-			t.Errorf("block does not have correct Proc-Type header")
-		}
-		der, err := DecryptPEMBlock(block, password)
-		if err != nil {
-			t.Error("decrypt: ", err)
-			continue
-		}
-		if !bytes.Equal(der, plainDER) {
-			t.Errorf("data mismatch")
-		}
-	}
-}
-
-var testData = []struct {
-	kind     PEMCipher
-	password []byte
-	pemData  []byte
-	plainDER string
-}{
-	{
-		kind:     PEMCipherDES,
-		password: []byte("asdf"),
-		pemData: []byte(`
------BEGIN RSA PRIVATE KEY-----
-Proc-Type: 4,ENCRYPTED
-DEK-Info: DES-CBC,34F09A4FC8DE22B5
-
-WXxy8kbZdiZvANtKvhmPBLV7eVFj2A5z6oAxvI9KGyhG0ZK0skfnt00C24vfU7m5
-ICXeoqP67lzJ18xCzQfHjDaBNs53DSDT+Iz4e8QUep1xQ30+8QKX2NA2coee3nwc
-6oM1cuvhNUDemBH2i3dKgMVkfaga0zQiiOq6HJyGSncCMSruQ7F9iWEfRbFcxFCx
-qtHb1kirfGKEtgWTF+ynyco6+2gMXNu70L7nJcnxnV/RLFkHt7AUU1yrclxz7eZz
-XOH9VfTjb52q/I8Suozq9coVQwg4tXfIoYUdT//O+mB7zJb9HI9Ps77b9TxDE6Gm
-4C9brwZ3zg2vqXcwwV6QRZMtyll9rOpxkbw6NPlpfBqkc3xS51bbxivbO/Nve4KD
-r12ymjFNF4stXCfJnNqKoZ50BHmEEUDu5Wb0fpVn82XrGw7CYc4iug==
------END RSA PRIVATE KEY-----`),
-		plainDER: `
-MIIBPAIBAAJBAPASZe+tCPU6p80AjHhDkVsLYa51D35e/YGa8QcZyooeZM8EHozo
-KD0fNiKI+53bHdy07N+81VQ8/ejPcRoXPlsCAwEAAQJBAMTxIuSq27VpR+zZ7WJf
-c6fvv1OBvpMZ0/d1pxL/KnOAgq2rD5hDtk9b0LGhTPgQAmrrMTKuSeGoIuYE+gKQ
-QvkCIQD+GC1m+/do+QRurr0uo46Kx1LzLeSCrjBk34wiOp2+dwIhAPHfTLRXS2fv
-7rljm0bYa4+eDZpz+E8RcXEgzhhvcQQ9AiAI5eHZJGOyml3MXnQjiPi55WcDOw0w
-glcRgT6QCEtz2wIhANSyqaFtosIkHKqrDUGfz/bb5tqMYTAnBruVPaf/WEOBAiEA
-9xORWeRG1tRpso4+dYy4KdDkuLPIO01KY6neYGm3BCM=`,
-	},
-	{
-		kind:     PEMCipher3DES,
-		password: []byte("asdf"),
-		pemData: []byte(`
------BEGIN RSA PRIVATE KEY-----
-Proc-Type: 4,ENCRYPTED
-DEK-Info: DES-EDE3-CBC,C1F4A6A03682C2C7
-
-0JqVdBEH6iqM7drTkj+e2W/bE3LqakaiWhb9WUVonFkhyu8ca/QzebY3b5gCvAZQ
-YwBvDcT/GHospKqPx+cxDHJNsUASDZws6bz8ZXWJGwZGExKzr0+Qx5fgXn44Ms3x
-8g1ENFuTXtxo+KoNK0zuAMAqp66Llcds3Fjl4XR18QaD0CrVNAfOdgATWZm5GJxk
-Fgx5f84nT+/ovvreG+xeOzWgvtKo0UUZVrhGOgfKLpa57adumcJ6SkUuBtEFpZFB
-ldw5w7WC7d13x2LsRkwo8ZrDKgIV+Y9GNvhuCCkTzNP0V3gNeJpd201HZHR+9n3w
-3z0VjR/MGqsfcy1ziEWMNOO53At3zlG6zP05aHMnMcZoVXadEK6L1gz++inSSDCq
-gI0UJP4e3JVB7AkgYymYAwiYALAkoEIuanxoc50njJk=
------END RSA PRIVATE KEY-----`),
-		plainDER: `
-MIIBOwIBAAJBANOCXKdoNS/iP/MAbl9cf1/SF3P+Ns7ZeNL27CfmDh0O6Zduaax5
-NBiumd2PmjkaCu7lQ5JOibHfWn+xJsc3kw0CAwEAAQJANX/W8d1Q/sCqzkuAn4xl
-B5a7qfJWaLHndu1QRLNTRJPn0Ee7OKJ4H0QKOhQM6vpjRrz+P2u9thn6wUxoPsef
-QQIhAP/jCkfejFcy4v15beqKzwz08/tslVjF+Yq41eJGejmxAiEA05pMoqfkyjcx
-fyvGhpoOyoCp71vSGUfR2I9CR65oKh0CIC1Msjs66LlfJtQctRq6bCEtFCxEcsP+
-eEjYo/Sk6WphAiEAxpgWPMJeU/shFT28gS+tmhjPZLpEoT1qkVlC14u0b3ECIQDX
-tZZZxCtPAm7shftEib0VU77Lk8MsXJcx2C4voRsjEw==`,
-	},
-	{
-		kind:     PEMCipherAES128,
-		password: []byte("asdf"),
-		pemData: []byte(`
------BEGIN RSA PRIVATE KEY-----
-Proc-Type: 4,ENCRYPTED
-DEK-Info: AES-128-CBC,D4492E793FC835CC038A728ED174F78A
-
-EyfQSzXSjv6BaNH+NHdXRlkHdimpF9izWlugVJAPApgXrq5YldPe2aGIOFXyJ+QE
-ZIG20DYqaPzJRjTEbPNZ6Es0S2JJ5yCpKxwJuDkgJZKtF39Q2i36JeGbSZQIuWJE
-GZbBpf1jDH/pr0iGonuAdl2PCCZUiy+8eLsD2tyviHUkFLOB+ykYoJ5t8ngZ/B6D
-33U43LLb7+9zD4y3Q9OVHqBFGyHcxCY9+9Qh4ZnFp7DTf6RY5TNEvE3s4g6aDpBs
-3NbvRVvYTgs8K9EPk4K+5R+P2kD8J8KvEIGxVa1vz8QoCJ/jr7Ka2rvNgPCex5/E
-080LzLHPCrXKdlr/f50yhNWq08ZxMWQFkui+FDHPDUaEELKAXV8/5PDxw80Rtybo
-AVYoCVIbZXZCuCO81op8UcOgEpTtyU5Lgh3Mw5scQL0=
------END RSA PRIVATE KEY-----`),
-		plainDER: `
-MIIBOgIBAAJBAMBlj5FxYtqbcy8wY89d/S7n0+r5MzD9F63BA/Lpl78vQKtdJ5dT
-cDGh/rBt1ufRrNp0WihcmZi7Mpl/3jHjiWECAwEAAQJABNOHYnKhtDIqFYj1OAJ3
-k3GlU0OlERmIOoeY/cL2V4lgwllPBEs7r134AY4wMmZSBUj8UR/O4SNO668ElKPE
-cQIhAOuqY7/115x5KCdGDMWi+jNaMxIvI4ETGwV40ykGzqlzAiEA0P9oEC3m9tHB
-kbpjSTxaNkrXxDgdEOZz8X0uOUUwHNsCIAwzcSCiGLyYJTULUmP1ESERfW1mlV78
-XzzESaJpIM/zAiBQkSTcl9VhcJreQqvjn5BnPZLP4ZHS4gPwJAGdsj5J4QIhAOVR
-B3WlRNTXR2WsJ5JdByezg9xzdXzULqmga0OE339a`,
-	},
-	{
-		kind:     PEMCipherAES192,
-		password: []byte("asdf"),
-		pemData: []byte(`
------BEGIN RSA PRIVATE KEY-----
-Proc-Type: 4,ENCRYPTED
-DEK-Info: AES-192-CBC,E2C9FB02BCA23ADE1829F8D8BC5F5369
-
-cqVslvHqDDM6qwU6YjezCRifXmKsrgEev7ng6Qs7UmDJOpHDgJQZI9fwMFUhIyn5
-FbCu1SHkLMW52Ld3CuEqMnzWMlhPrW8tFvUOrMWPYSisv7nNq88HobZEJcUNL2MM
-Y15XmHW6IJwPqhKyLHpWXyOCVEh4ODND2nV15PCoi18oTa475baxSk7+1qH7GuIs
-Rb7tshNTMqHbCpyo9Rn3UxeFIf9efdl8YLiMoIqc7J8E5e9VlbeQSdLMQOgDAQJG
-ReUtTw8exmKsY4gsSjhkg5uiw7/ZB1Ihto0qnfQJgjGc680qGkT1d6JfvOfeYAk6
-xn5RqS/h8rYAYm64KnepfC9vIujo4NqpaREDmaLdX5MJPQ+SlytITQvgUsUq3q/t
-Ss85xjQEZH3hzwjQqdJvmA4hYP6SUjxYpBM+02xZ1Xw=
------END RSA PRIVATE KEY-----`),
-		plainDER: `
-MIIBOwIBAAJBAMGcRrZiNNmtF20zyS6MQ7pdGx17aFDl+lTl+qnLuJRUCMUG05xs
-OmxmL/O1Qlf+bnqR8Bgg65SfKg21SYuLhiMCAwEAAQJBAL94uuHyO4wux2VC+qpj
-IzPykjdU7XRcDHbbvksf4xokSeUFjjD3PB0Qa83M94y89ZfdILIqS9x5EgSB4/lX
-qNkCIQD6cCIqLfzq/lYbZbQgAAjpBXeQVYsbvVtJrPrXJAlVVQIhAMXpDKMeFPMn
-J0g2rbx1gngx0qOa5r5iMU5w/noN4W2XAiBjf+WzCG5yFvazD+dOx3TC0A8+4x3P
-uZ3pWbaXf5PNuQIgAcdXarvhelH2w2piY1g3BPeFqhzBSCK/yLGxR82KIh8CIQDD
-+qGKsd09NhQ/G27y/DARzOYtml1NvdmCQAgsDIIOLA==`,
-	},
-	{
-		kind:     PEMCipherAES256,
-		password: []byte("asdf"),
-		pemData: []byte(`
------BEGIN RSA PRIVATE KEY-----
-Proc-Type: 4,ENCRYPTED
-DEK-Info: AES-256-CBC,8E7ED5CD731902CE938957A886A5FFBD
-
-4Mxr+KIzRVwoOP0wwq6caSkvW0iS+GE2h2Ov/u+n9ZTMwL83PRnmjfjzBgfRZLVf
-JFPXxUK26kMNpIdssNnqGOds+DhB+oSrsNKoxgxSl5OBoYv9eJTVYm7qOyAFIsjr
-DRKAcjYCmzfesr7PVTowwy0RtHmYwyXMGDlAzzZrEvaiySFFmMyKKvtoavwaFoc7
-Pz3RZScwIuubzTGJ1x8EzdffYOsdCa9Mtgpp3L136+23dOd6L/qK2EG2fzrJSHs/
-2XugkleBFSMKzEp9mxXKRfa++uidQvMZTFLDK9w5YjrRvMBo/l2BoZIsq0jAIE1N
-sv5Z/KwlX+3MDEpPQpUwGPlGGdLnjI3UZ+cjgqBcoMiNc6HfgbBgYJSU6aDSHuCk
-clCwByxWkBNgJ2GrkwNrF26v+bGJJJNR4SKouY1jQf0=
------END RSA PRIVATE KEY-----`),
-		plainDER: `
-MIIBOgIBAAJBAKy3GFkstoCHIEeUU/qO8207m8WSrjksR+p9B4tf1w5k+2O1V/GY
-AQ5WFCApItcOkQe/I0yZZJk/PmCqMzSxrc8CAwEAAQJAOCAz0F7AW9oNelVQSP8F
-Sfzx7O1yom+qWyAQQJF/gFR11gpf9xpVnnyu1WxIRnDUh1LZwUsjwlDYb7MB74id
-oQIhANPcOiLwOPT4sIUpRM5HG6BF1BI7L77VpyGVk8xNP7X/AiEA0LMHZtk4I+lJ
-nClgYp4Yh2JZ1Znbu7IoQMCEJCjwKDECIGd8Dzm5tViTkUW6Hs3Tlf73nNs65duF
-aRnSglss8I3pAiEAonEnKruawgD8RavDFR+fUgmQiPz4FnGGeVgfwpGG1JECIBYq
-PXHYtPqxQIbD2pScR5qum7iGUh11lEUPkmt+2uqS`,
-	},
-	{
-		// generated with:
-		// openssl genrsa -aes128 -passout pass:asdf -out server.orig.key 128
-		kind:     PEMCipherAES128,
-		password: []byte("asdf"),
-		pemData: []byte(`
------BEGIN RSA PRIVATE KEY-----
-Proc-Type: 4,ENCRYPTED
-DEK-Info: AES-128-CBC,74611ABC2571AF11B1BF9B69E62C89E7
-
-6ei/MlytjE0FFgZOGQ+jrwomKfpl8kdefeE0NSt/DMRrw8OacHAzBNi3pPEa0eX3
-eND9l7C9meCirWovjj9QWVHrXyugFuDIqgdhQ8iHTgCfF3lrmcttVrbIfMDw+smD
-hTP8O1mS/MHl92NE0nhv0w==
------END RSA PRIVATE KEY-----`),
-		plainDER: `
-MGMCAQACEQC6ssxmYuauuHGOCDAI54RdAgMBAAECEQCWIn6Yv2O+kBcDF7STctKB
-AgkA8SEfu/2i3g0CCQDGNlXbBHX7kQIIK3Ww5o0cYbECCQDCimPb0dYGsQIIeQ7A
-jryIst8=`,
-	},
-}
diff --git a/src/pkg/crypto/x509/pkix/pkix.go b/src/pkg/crypto/x509/pkix/pkix.go
deleted file mode 100644
index 58c1e54..0000000
--- a/src/pkg/crypto/x509/pkix/pkix.go
+++ /dev/null
@@ -1,178 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package pkix contains shared, low level structures used for ASN.1 parsing
-// and serialization of X.509 certificates, CRL and OCSP.
-package pkix
-
-import (
-	"encoding/asn1"
-	"math/big"
-	"time"
-)
-
-// AlgorithmIdentifier represents the ASN.1 structure of the same name. See RFC
-// 5280, section 4.1.1.2.
-type AlgorithmIdentifier struct {
-	Algorithm  asn1.ObjectIdentifier
-	Parameters asn1.RawValue `asn1:"optional"`
-}
-
-type RDNSequence []RelativeDistinguishedNameSET
-
-type RelativeDistinguishedNameSET []AttributeTypeAndValue
-
-// AttributeTypeAndValue mirrors the ASN.1 structure of the same name in
-// http://tools.ietf.org/html/rfc5280#section-4.1.2.4
-type AttributeTypeAndValue struct {
-	Type  asn1.ObjectIdentifier
-	Value interface{}
-}
-
-// AttributeTypeAndValueSET represents a set of ASN.1 sequences of
-// AttributeTypeAndValue sequences from RFC 2986 (PKCS #10).
-type AttributeTypeAndValueSET struct {
-	Type  asn1.ObjectIdentifier
-	Value [][]AttributeTypeAndValue `asn1:"set"`
-}
-
-// Extension represents the ASN.1 structure of the same name. See RFC
-// 5280, section 4.2.
-type Extension struct {
-	Id       asn1.ObjectIdentifier
-	Critical bool `asn1:"optional"`
-	Value    []byte
-}
-
-// Name represents an X.509 distinguished name. This only includes the common
-// elements of a DN.  Additional elements in the name are ignored.
-type Name struct {
-	Country, Organization, OrganizationalUnit []string
-	Locality, Province                        []string
-	StreetAddress, PostalCode                 []string
-	SerialNumber, CommonName                  string
-
-	Names []AttributeTypeAndValue
-}
-
-func (n *Name) FillFromRDNSequence(rdns *RDNSequence) {
-	for _, rdn := range *rdns {
-		if len(rdn) == 0 {
-			continue
-		}
-		atv := rdn[0]
-		n.Names = append(n.Names, atv)
-		value, ok := atv.Value.(string)
-		if !ok {
-			continue
-		}
-
-		t := atv.Type
-		if len(t) == 4 && t[0] == 2 && t[1] == 5 && t[2] == 4 {
-			switch t[3] {
-			case 3:
-				n.CommonName = value
-			case 5:
-				n.SerialNumber = value
-			case 6:
-				n.Country = append(n.Country, value)
-			case 7:
-				n.Locality = append(n.Locality, value)
-			case 8:
-				n.Province = append(n.Province, value)
-			case 9:
-				n.StreetAddress = append(n.StreetAddress, value)
-			case 10:
-				n.Organization = append(n.Organization, value)
-			case 11:
-				n.OrganizationalUnit = append(n.OrganizationalUnit, value)
-			case 17:
-				n.PostalCode = append(n.PostalCode, value)
-			}
-		}
-	}
-}
-
-var (
-	oidCountry            = []int{2, 5, 4, 6}
-	oidOrganization       = []int{2, 5, 4, 10}
-	oidOrganizationalUnit = []int{2, 5, 4, 11}
-	oidCommonName         = []int{2, 5, 4, 3}
-	oidSerialNumber       = []int{2, 5, 4, 5}
-	oidLocality           = []int{2, 5, 4, 7}
-	oidProvince           = []int{2, 5, 4, 8}
-	oidStreetAddress      = []int{2, 5, 4, 9}
-	oidPostalCode         = []int{2, 5, 4, 17}
-)
-
-// appendRDNs appends a relativeDistinguishedNameSET to the given RDNSequence
-// and returns the new value. The relativeDistinguishedNameSET contains an
-// attributeTypeAndValue for each of the given values. See RFC 5280, A.1, and
-// search for AttributeTypeAndValue.
-func appendRDNs(in RDNSequence, values []string, oid asn1.ObjectIdentifier) RDNSequence {
-	if len(values) == 0 {
-		return in
-	}
-
-	s := make([]AttributeTypeAndValue, len(values))
-	for i, value := range values {
-		s[i].Type = oid
-		s[i].Value = value
-	}
-
-	return append(in, s)
-}
-
-func (n Name) ToRDNSequence() (ret RDNSequence) {
-	ret = appendRDNs(ret, n.Country, oidCountry)
-	ret = appendRDNs(ret, n.Organization, oidOrganization)
-	ret = appendRDNs(ret, n.OrganizationalUnit, oidOrganizationalUnit)
-	ret = appendRDNs(ret, n.Locality, oidLocality)
-	ret = appendRDNs(ret, n.Province, oidProvince)
-	ret = appendRDNs(ret, n.StreetAddress, oidStreetAddress)
-	ret = appendRDNs(ret, n.PostalCode, oidPostalCode)
-	if len(n.CommonName) > 0 {
-		ret = appendRDNs(ret, []string{n.CommonName}, oidCommonName)
-	}
-	if len(n.SerialNumber) > 0 {
-		ret = appendRDNs(ret, []string{n.SerialNumber}, oidSerialNumber)
-	}
-
-	return ret
-}
-
-// CertificateList represents the ASN.1 structure of the same name. See RFC
-// 5280, section 5.1. Use Certificate.CheckCRLSignature to verify the
-// signature.
-type CertificateList struct {
-	TBSCertList        TBSCertificateList
-	SignatureAlgorithm AlgorithmIdentifier
-	SignatureValue     asn1.BitString
-}
-
-// HasExpired reports whether now is past the expiry time of certList.
-func (certList *CertificateList) HasExpired(now time.Time) bool {
-	return now.After(certList.TBSCertList.NextUpdate)
-}
-
-// TBSCertificateList represents the ASN.1 structure of the same name. See RFC
-// 5280, section 5.1.
-type TBSCertificateList struct {
-	Raw                 asn1.RawContent
-	Version             int `asn1:"optional,default:2"`
-	Signature           AlgorithmIdentifier
-	Issuer              RDNSequence
-	ThisUpdate          time.Time
-	NextUpdate          time.Time
-	RevokedCertificates []RevokedCertificate `asn1:"optional"`
-	Extensions          []Extension          `asn1:"tag:0,optional,explicit"`
-}
-
-// RevokedCertificate represents the ASN.1 structure of the same name. See RFC
-// 5280, section 5.1.
-type RevokedCertificate struct {
-	SerialNumber   *big.Int
-	RevocationTime time.Time
-	Extensions     []Extension `asn1:"optional"`
-}
diff --git a/src/pkg/crypto/x509/root_unix.go b/src/pkg/crypto/x509/root_unix.go
deleted file mode 100644
index 11ad3c4..0000000
--- a/src/pkg/crypto/x509/root_unix.go
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build dragonfly freebsd linux nacl netbsd openbsd solaris
-
-package x509
-
-import "io/ioutil"
-
-// Possible certificate files; stop after finding one.
-var certFiles = []string{
-	"/etc/ssl/certs/ca-certificates.crt",     // Debian/Ubuntu/Gentoo etc.
-	"/etc/pki/tls/certs/ca-bundle.crt",       // Fedora/RHEL
-	"/etc/ssl/ca-bundle.pem",                 // OpenSUSE
-	"/etc/ssl/cert.pem",                      // OpenBSD
-	"/usr/local/share/certs/ca-root-nss.crt", // FreeBSD/DragonFly
-}
-
-func (c *Certificate) systemVerify(opts *VerifyOptions) (chains [][]*Certificate, err error) {
-	return nil, nil
-}
-
-func initSystemRoots() {
-	roots := NewCertPool()
-	for _, file := range certFiles {
-		data, err := ioutil.ReadFile(file)
-		if err == nil {
-			roots.AppendCertsFromPEM(data)
-			systemRoots = roots
-			return
-		}
-	}
-
-	// All of the files failed to load. systemRoots will be nil which will
-	// trigger a specific error at verification time.
-}
diff --git a/src/pkg/crypto/x509/verify.go b/src/pkg/crypto/x509/verify.go
deleted file mode 100644
index 5fd8e37..0000000
--- a/src/pkg/crypto/x509/verify.go
+++ /dev/null
@@ -1,474 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package x509
-
-import (
-	"fmt"
-	"net"
-	"runtime"
-	"strings"
-	"time"
-	"unicode/utf8"
-)
-
-type InvalidReason int
-
-const (
-	// NotAuthorizedToSign results when a certificate is signed by another
-	// which isn't marked as a CA certificate.
-	NotAuthorizedToSign InvalidReason = iota
-	// Expired results when a certificate has expired, based on the time
-	// given in the VerifyOptions.
-	Expired
-	// CANotAuthorizedForThisName results when an intermediate or root
-	// certificate has a name constraint which doesn't include the name
-	// being checked.
-	CANotAuthorizedForThisName
-	// TooManyIntermediates results when a path length constraint is
-	// violated.
-	TooManyIntermediates
-	// IncompatibleUsage results when the certificate's key usage indicates
-	// that it may only be used for a different purpose.
-	IncompatibleUsage
-)
-
-// CertificateInvalidError results when an odd error occurs. Users of this
-// library probably want to handle all these errors uniformly.
-type CertificateInvalidError struct {
-	Cert   *Certificate
-	Reason InvalidReason
-}
-
-func (e CertificateInvalidError) Error() string {
-	switch e.Reason {
-	case NotAuthorizedToSign:
-		return "x509: certificate is not authorized to sign other certificates"
-	case Expired:
-		return "x509: certificate has expired or is not yet valid"
-	case CANotAuthorizedForThisName:
-		return "x509: a root or intermediate certificate is not authorized to sign in this domain"
-	case TooManyIntermediates:
-		return "x509: too many intermediates for path length constraint"
-	case IncompatibleUsage:
-		return "x509: certificate specifies an incompatible key usage"
-	}
-	return "x509: unknown error"
-}
-
-// HostnameError results when the set of authorized names doesn't match the
-// requested name.
-type HostnameError struct {
-	Certificate *Certificate
-	Host        string
-}
-
-func (h HostnameError) Error() string {
-	c := h.Certificate
-
-	var valid string
-	if ip := net.ParseIP(h.Host); ip != nil {
-		// Trying to validate an IP
-		if len(c.IPAddresses) == 0 {
-			return "x509: cannot validate certificate for " + h.Host + " because it doesn't contain any IP SANs"
-		}
-		for _, san := range c.IPAddresses {
-			if len(valid) > 0 {
-				valid += ", "
-			}
-			valid += san.String()
-		}
-	} else {
-		if len(c.DNSNames) > 0 {
-			valid = strings.Join(c.DNSNames, ", ")
-		} else {
-			valid = c.Subject.CommonName
-		}
-	}
-	return "x509: certificate is valid for " + valid + ", not " + h.Host
-}
-
-// UnknownAuthorityError results when the certificate issuer is unknown
-type UnknownAuthorityError struct {
-	cert *Certificate
-	// hintErr contains an error that may be helpful in determining why an
-	// authority wasn't found.
-	hintErr error
-	// hintCert contains a possible authority certificate that was rejected
-	// because of the error in hintErr.
-	hintCert *Certificate
-}
-
-func (e UnknownAuthorityError) Error() string {
-	s := "x509: certificate signed by unknown authority"
-	if e.hintErr != nil {
-		certName := e.hintCert.Subject.CommonName
-		if len(certName) == 0 {
-			if len(e.hintCert.Subject.Organization) > 0 {
-				certName = e.hintCert.Subject.Organization[0]
-			}
-			certName = "serial:" + e.hintCert.SerialNumber.String()
-		}
-		s += fmt.Sprintf(" (possibly because of %q while trying to verify candidate authority certificate %q)", e.hintErr, certName)
-	}
-	return s
-}
-
-// SystemRootsError results when we fail to load the system root certificates.
-type SystemRootsError struct {
-}
-
-func (e SystemRootsError) Error() string {
-	return "x509: failed to load system roots and no roots provided"
-}
-
-// VerifyOptions contains parameters for Certificate.Verify. It's a structure
-// because other PKIX verification APIs have ended up needing many options.
-type VerifyOptions struct {
-	DNSName       string
-	Intermediates *CertPool
-	Roots         *CertPool // if nil, the system roots are used
-	CurrentTime   time.Time // if zero, the current time is used
-	// KeyUsage specifies which Extended Key Usage values are acceptable.
-	// An empty list means ExtKeyUsageServerAuth. Key usage is considered a
-	// constraint down the chain which mirrors Windows CryptoAPI behaviour,
-	// but not the spec. To accept any key usage, include ExtKeyUsageAny.
-	KeyUsages []ExtKeyUsage
-}
-
-const (
-	leafCertificate = iota
-	intermediateCertificate
-	rootCertificate
-)
-
-// isValid performs validity checks on the c.
-func (c *Certificate) isValid(certType int, currentChain []*Certificate, opts *VerifyOptions) error {
-	now := opts.CurrentTime
-	if now.IsZero() {
-		now = time.Now()
-	}
-	if now.Before(c.NotBefore) || now.After(c.NotAfter) {
-		return CertificateInvalidError{c, Expired}
-	}
-
-	if len(c.PermittedDNSDomains) > 0 {
-		ok := false
-		for _, domain := range c.PermittedDNSDomains {
-			if opts.DNSName == domain ||
-				(strings.HasSuffix(opts.DNSName, domain) &&
-					len(opts.DNSName) >= 1+len(domain) &&
-					opts.DNSName[len(opts.DNSName)-len(domain)-1] == '.') {
-				ok = true
-				break
-			}
-		}
-
-		if !ok {
-			return CertificateInvalidError{c, CANotAuthorizedForThisName}
-		}
-	}
-
-	// KeyUsage status flags are ignored. From Engineering Security, Peter
-	// Gutmann: A European government CA marked its signing certificates as
-	// being valid for encryption only, but no-one noticed. Another
-	// European CA marked its signature keys as not being valid for
-	// signatures. A different CA marked its own trusted root certificate
-	// as being invalid for certificate signing.  Another national CA
-	// distributed a certificate to be used to encrypt data for the
-	// country’s tax authority that was marked as only being usable for
-	// digital signatures but not for encryption. Yet another CA reversed
-	// the order of the bit flags in the keyUsage due to confusion over
-	// encoding endianness, essentially setting a random keyUsage in
-	// certificates that it issued. Another CA created a self-invalidating
-	// certificate by adding a certificate policy statement stipulating
-	// that the certificate had to be used strictly as specified in the
-	// keyUsage, and a keyUsage containing a flag indicating that the RSA
-	// encryption key could only be used for Diffie-Hellman key agreement.
-
-	if certType == intermediateCertificate && (!c.BasicConstraintsValid || !c.IsCA) {
-		return CertificateInvalidError{c, NotAuthorizedToSign}
-	}
-
-	if c.BasicConstraintsValid && c.MaxPathLen >= 0 {
-		numIntermediates := len(currentChain) - 1
-		if numIntermediates > c.MaxPathLen {
-			return CertificateInvalidError{c, TooManyIntermediates}
-		}
-	}
-
-	return nil
-}
-
-// Verify attempts to verify c by building one or more chains from c to a
-// certificate in opts.Roots, using certificates in opts.Intermediates if
-// needed. If successful, it returns one or more chains where the first
-// element of the chain is c and the last element is from opts.Roots.
-//
-// WARNING: this doesn't do any revocation checking.
-func (c *Certificate) Verify(opts VerifyOptions) (chains [][]*Certificate, err error) {
-	// Use Windows's own verification and chain building.
-	if opts.Roots == nil && runtime.GOOS == "windows" {
-		return c.systemVerify(&opts)
-	}
-
-	if opts.Roots == nil {
-		opts.Roots = systemRootsPool()
-		if opts.Roots == nil {
-			return nil, SystemRootsError{}
-		}
-	}
-
-	err = c.isValid(leafCertificate, nil, &opts)
-	if err != nil {
-		return
-	}
-
-	if len(opts.DNSName) > 0 {
-		err = c.VerifyHostname(opts.DNSName)
-		if err != nil {
-			return
-		}
-	}
-
-	candidateChains, err := c.buildChains(make(map[int][][]*Certificate), []*Certificate{c}, &opts)
-	if err != nil {
-		return
-	}
-
-	keyUsages := opts.KeyUsages
-	if len(keyUsages) == 0 {
-		keyUsages = []ExtKeyUsage{ExtKeyUsageServerAuth}
-	}
-
-	// If any key usage is acceptable then we're done.
-	for _, usage := range keyUsages {
-		if usage == ExtKeyUsageAny {
-			chains = candidateChains
-			return
-		}
-	}
-
-	for _, candidate := range candidateChains {
-		if checkChainForKeyUsage(candidate, keyUsages) {
-			chains = append(chains, candidate)
-		}
-	}
-
-	if len(chains) == 0 {
-		err = CertificateInvalidError{c, IncompatibleUsage}
-	}
-
-	return
-}
-
-func appendToFreshChain(chain []*Certificate, cert *Certificate) []*Certificate {
-	n := make([]*Certificate, len(chain)+1)
-	copy(n, chain)
-	n[len(chain)] = cert
-	return n
-}
-
-func (c *Certificate) buildChains(cache map[int][][]*Certificate, currentChain []*Certificate, opts *VerifyOptions) (chains [][]*Certificate, err error) {
-	possibleRoots, failedRoot, rootErr := opts.Roots.findVerifiedParents(c)
-	for _, rootNum := range possibleRoots {
-		root := opts.Roots.certs[rootNum]
-		err = root.isValid(rootCertificate, currentChain, opts)
-		if err != nil {
-			continue
-		}
-		chains = append(chains, appendToFreshChain(currentChain, root))
-	}
-
-	possibleIntermediates, failedIntermediate, intermediateErr := opts.Intermediates.findVerifiedParents(c)
-nextIntermediate:
-	for _, intermediateNum := range possibleIntermediates {
-		intermediate := opts.Intermediates.certs[intermediateNum]
-		for _, cert := range currentChain {
-			if cert == intermediate {
-				continue nextIntermediate
-			}
-		}
-		err = intermediate.isValid(intermediateCertificate, currentChain, opts)
-		if err != nil {
-			continue
-		}
-		var childChains [][]*Certificate
-		childChains, ok := cache[intermediateNum]
-		if !ok {
-			childChains, err = intermediate.buildChains(cache, appendToFreshChain(currentChain, intermediate), opts)
-			cache[intermediateNum] = childChains
-		}
-		chains = append(chains, childChains...)
-	}
-
-	if len(chains) > 0 {
-		err = nil
-	}
-
-	if len(chains) == 0 && err == nil {
-		hintErr := rootErr
-		hintCert := failedRoot
-		if hintErr == nil {
-			hintErr = intermediateErr
-			hintCert = failedIntermediate
-		}
-		err = UnknownAuthorityError{c, hintErr, hintCert}
-	}
-
-	return
-}
-
-func matchHostnames(pattern, host string) bool {
-	if len(pattern) == 0 || len(host) == 0 {
-		return false
-	}
-
-	patternParts := strings.Split(pattern, ".")
-	hostParts := strings.Split(host, ".")
-
-	if len(patternParts) != len(hostParts) {
-		return false
-	}
-
-	for i, patternPart := range patternParts {
-		if patternPart == "*" {
-			continue
-		}
-		if patternPart != hostParts[i] {
-			return false
-		}
-	}
-
-	return true
-}
-
-// toLowerCaseASCII returns a lower-case version of in. See RFC 6125 6.4.1. We use
-// an explicitly ASCII function to avoid any sharp corners resulting from
-// performing Unicode operations on DNS labels.
-func toLowerCaseASCII(in string) string {
-	// If the string is already lower-case then there's nothing to do.
-	isAlreadyLowerCase := true
-	for _, c := range in {
-		if c == utf8.RuneError {
-			// If we get a UTF-8 error then there might be
-			// upper-case ASCII bytes in the invalid sequence.
-			isAlreadyLowerCase = false
-			break
-		}
-		if 'A' <= c && c <= 'Z' {
-			isAlreadyLowerCase = false
-			break
-		}
-	}
-
-	if isAlreadyLowerCase {
-		return in
-	}
-
-	out := []byte(in)
-	for i, c := range out {
-		if 'A' <= c && c <= 'Z' {
-			out[i] += 'a' - 'A'
-		}
-	}
-	return string(out)
-}
-
-// VerifyHostname returns nil if c is a valid certificate for the named host.
-// Otherwise it returns an error describing the mismatch.
-func (c *Certificate) VerifyHostname(h string) error {
-	// IP addresses may be written in [ ].
-	candidateIP := h
-	if len(h) >= 3 && h[0] == '[' && h[len(h)-1] == ']' {
-		candidateIP = h[1 : len(h)-1]
-	}
-	if ip := net.ParseIP(candidateIP); ip != nil {
-		// We only match IP addresses against IP SANs.
-		// https://tools.ietf.org/html/rfc6125#appendix-B.2
-		for _, candidate := range c.IPAddresses {
-			if ip.Equal(candidate) {
-				return nil
-			}
-		}
-		return HostnameError{c, candidateIP}
-	}
-
-	lowered := toLowerCaseASCII(h)
-
-	if len(c.DNSNames) > 0 {
-		for _, match := range c.DNSNames {
-			if matchHostnames(toLowerCaseASCII(match), lowered) {
-				return nil
-			}
-		}
-		// If Subject Alt Name is given, we ignore the common name.
-	} else if matchHostnames(toLowerCaseASCII(c.Subject.CommonName), lowered) {
-		return nil
-	}
-
-	return HostnameError{c, h}
-}
-
-func checkChainForKeyUsage(chain []*Certificate, keyUsages []ExtKeyUsage) bool {
-	usages := make([]ExtKeyUsage, len(keyUsages))
-	copy(usages, keyUsages)
-
-	if len(chain) == 0 {
-		return false
-	}
-
-	usagesRemaining := len(usages)
-
-	// We walk down the list and cross out any usages that aren't supported
-	// by each certificate. If we cross out all the usages, then the chain
-	// is unacceptable.
-
-NextCert:
-	for i := len(chain) - 1; i >= 0; i-- {
-		cert := chain[i]
-		if len(cert.ExtKeyUsage) == 0 && len(cert.UnknownExtKeyUsage) == 0 {
-			// The certificate doesn't have any extended key usage specified.
-			continue
-		}
-
-		for _, usage := range cert.ExtKeyUsage {
-			if usage == ExtKeyUsageAny {
-				// The certificate is explicitly good for any usage.
-				continue NextCert
-			}
-		}
-
-		const invalidUsage ExtKeyUsage = -1
-
-	NextRequestedUsage:
-		for i, requestedUsage := range usages {
-			if requestedUsage == invalidUsage {
-				continue
-			}
-
-			for _, usage := range cert.ExtKeyUsage {
-				if requestedUsage == usage {
-					continue NextRequestedUsage
-				} else if requestedUsage == ExtKeyUsageServerAuth &&
-					(usage == ExtKeyUsageNetscapeServerGatedCrypto ||
-						usage == ExtKeyUsageMicrosoftServerGatedCrypto) {
-					// In order to support COMODO
-					// certificate chains, we have to
-					// accept Netscape or Microsoft SGC
-					// usages as equal to ServerAuth.
-					continue NextRequestedUsage
-				}
-			}
-
-			usages[i] = invalidUsage
-			usagesRemaining--
-			if usagesRemaining == 0 {
-				return false
-			}
-		}
-	}
-
-	return true
-}
diff --git a/src/pkg/crypto/x509/x509.go b/src/pkg/crypto/x509/x509.go
deleted file mode 100644
index c347fb3..0000000
--- a/src/pkg/crypto/x509/x509.go
+++ /dev/null
@@ -1,1903 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package x509 parses X.509-encoded keys and certificates.
-package x509
-
-import (
-	"bytes"
-	"crypto"
-	"crypto/dsa"
-	"crypto/ecdsa"
-	"crypto/elliptic"
-	"crypto/rsa"
-	"crypto/sha1"
-	_ "crypto/sha256"
-	_ "crypto/sha512"
-	"crypto/x509/pkix"
-	"encoding/asn1"
-	"encoding/pem"
-	"errors"
-	"io"
-	"math/big"
-	"net"
-	"strconv"
-	"time"
-)
-
-// pkixPublicKey reflects a PKIX public key structure. See SubjectPublicKeyInfo
-// in RFC 3280.
-type pkixPublicKey struct {
-	Algo      pkix.AlgorithmIdentifier
-	BitString asn1.BitString
-}
-
-// ParsePKIXPublicKey parses a DER encoded public key. These values are
-// typically found in PEM blocks with "BEGIN PUBLIC KEY".
-func ParsePKIXPublicKey(derBytes []byte) (pub interface{}, err error) {
-	var pki publicKeyInfo
-	if _, err = asn1.Unmarshal(derBytes, &pki); err != nil {
-		return
-	}
-	algo := getPublicKeyAlgorithmFromOID(pki.Algorithm.Algorithm)
-	if algo == UnknownPublicKeyAlgorithm {
-		return nil, errors.New("x509: unknown public key algorithm")
-	}
-	return parsePublicKey(algo, &pki)
-}
-
-func marshalPublicKey(pub interface{}) (publicKeyBytes []byte, publicKeyAlgorithm pkix.AlgorithmIdentifier, err error) {
-	switch pub := pub.(type) {
-	case *rsa.PublicKey:
-		publicKeyBytes, err = asn1.Marshal(rsaPublicKey{
-			N: pub.N,
-			E: pub.E,
-		})
-		publicKeyAlgorithm.Algorithm = oidPublicKeyRSA
-		// This is a NULL parameters value which is technically
-		// superfluous, but most other code includes it and, by
-		// doing this, we match their public key hashes.
-		publicKeyAlgorithm.Parameters = asn1.RawValue{
-			Tag: 5,
-		}
-	case *ecdsa.PublicKey:
-		publicKeyBytes = elliptic.Marshal(pub.Curve, pub.X, pub.Y)
-		oid, ok := oidFromNamedCurve(pub.Curve)
-		if !ok {
-			return nil, pkix.AlgorithmIdentifier{}, errors.New("x509: unsupported elliptic curve")
-		}
-		publicKeyAlgorithm.Algorithm = oidPublicKeyECDSA
-		var paramBytes []byte
-		paramBytes, err = asn1.Marshal(oid)
-		if err != nil {
-			return
-		}
-		publicKeyAlgorithm.Parameters.FullBytes = paramBytes
-	default:
-		return nil, pkix.AlgorithmIdentifier{}, errors.New("x509: only RSA and ECDSA public keys supported")
-	}
-
-	return publicKeyBytes, publicKeyAlgorithm, nil
-}
-
-// MarshalPKIXPublicKey serialises a public key to DER-encoded PKIX format.
-func MarshalPKIXPublicKey(pub interface{}) ([]byte, error) {
-	var publicKeyBytes []byte
-	var publicKeyAlgorithm pkix.AlgorithmIdentifier
-	var err error
-
-	if publicKeyBytes, publicKeyAlgorithm, err = marshalPublicKey(pub); err != nil {
-		return nil, err
-	}
-
-	pkix := pkixPublicKey{
-		Algo: publicKeyAlgorithm,
-		BitString: asn1.BitString{
-			Bytes:     publicKeyBytes,
-			BitLength: 8 * len(publicKeyBytes),
-		},
-	}
-
-	ret, _ := asn1.Marshal(pkix)
-	return ret, nil
-}
-
-// These structures reflect the ASN.1 structure of X.509 certificates.:
-
-type certificate struct {
-	Raw                asn1.RawContent
-	TBSCertificate     tbsCertificate
-	SignatureAlgorithm pkix.AlgorithmIdentifier
-	SignatureValue     asn1.BitString
-}
-
-type tbsCertificate struct {
-	Raw                asn1.RawContent
-	Version            int `asn1:"optional,explicit,default:1,tag:0"`
-	SerialNumber       *big.Int
-	SignatureAlgorithm pkix.AlgorithmIdentifier
-	Issuer             asn1.RawValue
-	Validity           validity
-	Subject            asn1.RawValue
-	PublicKey          publicKeyInfo
-	UniqueId           asn1.BitString   `asn1:"optional,tag:1"`
-	SubjectUniqueId    asn1.BitString   `asn1:"optional,tag:2"`
-	Extensions         []pkix.Extension `asn1:"optional,explicit,tag:3"`
-}
-
-type dsaAlgorithmParameters struct {
-	P, Q, G *big.Int
-}
-
-type dsaSignature struct {
-	R, S *big.Int
-}
-
-type ecdsaSignature dsaSignature
-
-type validity struct {
-	NotBefore, NotAfter time.Time
-}
-
-type publicKeyInfo struct {
-	Raw       asn1.RawContent
-	Algorithm pkix.AlgorithmIdentifier
-	PublicKey asn1.BitString
-}
-
-// RFC 5280,  4.2.1.1
-type authKeyId struct {
-	Id []byte `asn1:"optional,tag:0"`
-}
-
-type SignatureAlgorithm int
-
-const (
-	UnknownSignatureAlgorithm SignatureAlgorithm = iota
-	MD2WithRSA
-	MD5WithRSA
-	SHA1WithRSA
-	SHA256WithRSA
-	SHA384WithRSA
-	SHA512WithRSA
-	DSAWithSHA1
-	DSAWithSHA256
-	ECDSAWithSHA1
-	ECDSAWithSHA256
-	ECDSAWithSHA384
-	ECDSAWithSHA512
-)
-
-type PublicKeyAlgorithm int
-
-const (
-	UnknownPublicKeyAlgorithm PublicKeyAlgorithm = iota
-	RSA
-	DSA
-	ECDSA
-)
-
-// OIDs for signature algorithms
-//
-// pkcs-1 OBJECT IDENTIFIER ::= {
-//    iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 1 }
-//
-//
-// RFC 3279 2.2.1 RSA Signature Algorithms
-//
-// md2WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 2 }
-//
-// md5WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 4 }
-//
-// sha-1WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 5 }
-//
-// dsaWithSha1 OBJECT IDENTIFIER ::= {
-//    iso(1) member-body(2) us(840) x9-57(10040) x9cm(4) 3 }
-//
-// RFC 3279 2.2.3 ECDSA Signature Algorithm
-//
-// ecdsa-with-SHA1 OBJECT IDENTIFIER ::= {
-// 	  iso(1) member-body(2) us(840) ansi-x962(10045)
-//    signatures(4) ecdsa-with-SHA1(1)}
-//
-//
-// RFC 4055 5 PKCS #1 Version 1.5
-//
-// sha256WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 11 }
-//
-// sha384WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 12 }
-//
-// sha512WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 13 }
-//
-//
-// RFC 5758 3.1 DSA Signature Algorithms
-//
-// dsaWithSha256 OBJECT IDENTIFIER ::= {
-//    joint-iso-ccitt(2) country(16) us(840) organization(1) gov(101)
-//    csor(3) algorithms(4) id-dsa-with-sha2(3) 2}
-//
-// RFC 5758 3.2 ECDSA Signature Algorithm
-//
-// ecdsa-with-SHA256 OBJECT IDENTIFIER ::= { iso(1) member-body(2)
-//    us(840) ansi-X9-62(10045) signatures(4) ecdsa-with-SHA2(3) 2 }
-//
-// ecdsa-with-SHA384 OBJECT IDENTIFIER ::= { iso(1) member-body(2)
-//    us(840) ansi-X9-62(10045) signatures(4) ecdsa-with-SHA2(3) 3 }
-//
-// ecdsa-with-SHA512 OBJECT IDENTIFIER ::= { iso(1) member-body(2)
-//    us(840) ansi-X9-62(10045) signatures(4) ecdsa-with-SHA2(3) 4 }
-
-var (
-	oidSignatureMD2WithRSA      = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 2}
-	oidSignatureMD5WithRSA      = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 4}
-	oidSignatureSHA1WithRSA     = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 5}
-	oidSignatureSHA256WithRSA   = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 11}
-	oidSignatureSHA384WithRSA   = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 12}
-	oidSignatureSHA512WithRSA   = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 13}
-	oidSignatureDSAWithSHA1     = asn1.ObjectIdentifier{1, 2, 840, 10040, 4, 3}
-	oidSignatureDSAWithSHA256   = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 4, 3, 2}
-	oidSignatureECDSAWithSHA1   = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 1}
-	oidSignatureECDSAWithSHA256 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 2}
-	oidSignatureECDSAWithSHA384 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 3}
-	oidSignatureECDSAWithSHA512 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 4}
-)
-
-var signatureAlgorithmDetails = []struct {
-	algo       SignatureAlgorithm
-	oid        asn1.ObjectIdentifier
-	pubKeyAlgo PublicKeyAlgorithm
-	hash       crypto.Hash
-}{
-	{MD2WithRSA, oidSignatureMD2WithRSA, RSA, crypto.Hash(0) /* no value for MD2 */},
-	{MD5WithRSA, oidSignatureMD5WithRSA, RSA, crypto.MD5},
-	{SHA1WithRSA, oidSignatureSHA1WithRSA, RSA, crypto.SHA1},
-	{SHA256WithRSA, oidSignatureSHA256WithRSA, RSA, crypto.SHA256},
-	{SHA384WithRSA, oidSignatureSHA384WithRSA, RSA, crypto.SHA384},
-	{SHA512WithRSA, oidSignatureSHA512WithRSA, RSA, crypto.SHA512},
-	{DSAWithSHA1, oidSignatureDSAWithSHA1, DSA, crypto.SHA1},
-	{DSAWithSHA256, oidSignatureDSAWithSHA256, DSA, crypto.SHA256},
-	{ECDSAWithSHA1, oidSignatureECDSAWithSHA1, ECDSA, crypto.SHA1},
-	{ECDSAWithSHA256, oidSignatureECDSAWithSHA256, ECDSA, crypto.SHA256},
-	{ECDSAWithSHA384, oidSignatureECDSAWithSHA384, ECDSA, crypto.SHA384},
-	{ECDSAWithSHA512, oidSignatureECDSAWithSHA512, ECDSA, crypto.SHA512},
-}
-
-func getSignatureAlgorithmFromOID(oid asn1.ObjectIdentifier) SignatureAlgorithm {
-	for _, details := range signatureAlgorithmDetails {
-		if oid.Equal(details.oid) {
-			return details.algo
-		}
-	}
-	return UnknownSignatureAlgorithm
-}
-
-// RFC 3279, 2.3 Public Key Algorithms
-//
-// pkcs-1 OBJECT IDENTIFIER ::== { iso(1) member-body(2) us(840)
-//    rsadsi(113549) pkcs(1) 1 }
-//
-// rsaEncryption OBJECT IDENTIFIER ::== { pkcs1-1 1 }
-//
-// id-dsa OBJECT IDENTIFIER ::== { iso(1) member-body(2) us(840)
-//    x9-57(10040) x9cm(4) 1 }
-//
-// RFC 5480, 2.1.1 Unrestricted Algorithm Identifier and Parameters
-//
-// id-ecPublicKey OBJECT IDENTIFIER ::= {
-//       iso(1) member-body(2) us(840) ansi-X9-62(10045) keyType(2) 1 }
-var (
-	oidPublicKeyRSA   = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 1}
-	oidPublicKeyDSA   = asn1.ObjectIdentifier{1, 2, 840, 10040, 4, 1}
-	oidPublicKeyECDSA = asn1.ObjectIdentifier{1, 2, 840, 10045, 2, 1}
-)
-
-func getPublicKeyAlgorithmFromOID(oid asn1.ObjectIdentifier) PublicKeyAlgorithm {
-	switch {
-	case oid.Equal(oidPublicKeyRSA):
-		return RSA
-	case oid.Equal(oidPublicKeyDSA):
-		return DSA
-	case oid.Equal(oidPublicKeyECDSA):
-		return ECDSA
-	}
-	return UnknownPublicKeyAlgorithm
-}
-
-// RFC 5480, 2.1.1.1. Named Curve
-//
-// secp224r1 OBJECT IDENTIFIER ::= {
-//   iso(1) identified-organization(3) certicom(132) curve(0) 33 }
-//
-// secp256r1 OBJECT IDENTIFIER ::= {
-//   iso(1) member-body(2) us(840) ansi-X9-62(10045) curves(3)
-//   prime(1) 7 }
-//
-// secp384r1 OBJECT IDENTIFIER ::= {
-//   iso(1) identified-organization(3) certicom(132) curve(0) 34 }
-//
-// secp521r1 OBJECT IDENTIFIER ::= {
-//   iso(1) identified-organization(3) certicom(132) curve(0) 35 }
-//
-// NB: secp256r1 is equivalent to prime256v1
-var (
-	oidNamedCurveP224 = asn1.ObjectIdentifier{1, 3, 132, 0, 33}
-	oidNamedCurveP256 = asn1.ObjectIdentifier{1, 2, 840, 10045, 3, 1, 7}
-	oidNamedCurveP384 = asn1.ObjectIdentifier{1, 3, 132, 0, 34}
-	oidNamedCurveP521 = asn1.ObjectIdentifier{1, 3, 132, 0, 35}
-)
-
-func namedCurveFromOID(oid asn1.ObjectIdentifier) elliptic.Curve {
-	switch {
-	case oid.Equal(oidNamedCurveP224):
-		return elliptic.P224()
-	case oid.Equal(oidNamedCurveP256):
-		return elliptic.P256()
-	case oid.Equal(oidNamedCurveP384):
-		return elliptic.P384()
-	case oid.Equal(oidNamedCurveP521):
-		return elliptic.P521()
-	}
-	return nil
-}
-
-func oidFromNamedCurve(curve elliptic.Curve) (asn1.ObjectIdentifier, bool) {
-	switch curve {
-	case elliptic.P224():
-		return oidNamedCurveP224, true
-	case elliptic.P256():
-		return oidNamedCurveP256, true
-	case elliptic.P384():
-		return oidNamedCurveP384, true
-	case elliptic.P521():
-		return oidNamedCurveP521, true
-	}
-
-	return nil, false
-}
-
-// KeyUsage represents the set of actions that are valid for a given key. It's
-// a bitmap of the KeyUsage* constants.
-type KeyUsage int
-
-const (
-	KeyUsageDigitalSignature KeyUsage = 1 << iota
-	KeyUsageContentCommitment
-	KeyUsageKeyEncipherment
-	KeyUsageDataEncipherment
-	KeyUsageKeyAgreement
-	KeyUsageCertSign
-	KeyUsageCRLSign
-	KeyUsageEncipherOnly
-	KeyUsageDecipherOnly
-)
-
-// RFC 5280, 4.2.1.12  Extended Key Usage
-//
-// anyExtendedKeyUsage OBJECT IDENTIFIER ::= { id-ce-extKeyUsage 0 }
-//
-// id-kp OBJECT IDENTIFIER ::= { id-pkix 3 }
-//
-// id-kp-serverAuth             OBJECT IDENTIFIER ::= { id-kp 1 }
-// id-kp-clientAuth             OBJECT IDENTIFIER ::= { id-kp 2 }
-// id-kp-codeSigning            OBJECT IDENTIFIER ::= { id-kp 3 }
-// id-kp-emailProtection        OBJECT IDENTIFIER ::= { id-kp 4 }
-// id-kp-timeStamping           OBJECT IDENTIFIER ::= { id-kp 8 }
-// id-kp-OCSPSigning            OBJECT IDENTIFIER ::= { id-kp 9 }
-var (
-	oidExtKeyUsageAny                        = asn1.ObjectIdentifier{2, 5, 29, 37, 0}
-	oidExtKeyUsageServerAuth                 = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 1}
-	oidExtKeyUsageClientAuth                 = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 2}
-	oidExtKeyUsageCodeSigning                = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 3}
-	oidExtKeyUsageEmailProtection            = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 4}
-	oidExtKeyUsageIPSECEndSystem             = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 5}
-	oidExtKeyUsageIPSECTunnel                = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 6}
-	oidExtKeyUsageIPSECUser                  = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 7}
-	oidExtKeyUsageTimeStamping               = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 8}
-	oidExtKeyUsageOCSPSigning                = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 9}
-	oidExtKeyUsageMicrosoftServerGatedCrypto = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 10, 3, 3}
-	oidExtKeyUsageNetscapeServerGatedCrypto  = asn1.ObjectIdentifier{2, 16, 840, 1, 113730, 4, 1}
-)
-
-// ExtKeyUsage represents an extended set of actions that are valid for a given key.
-// Each of the ExtKeyUsage* constants define a unique action.
-type ExtKeyUsage int
-
-const (
-	ExtKeyUsageAny ExtKeyUsage = iota
-	ExtKeyUsageServerAuth
-	ExtKeyUsageClientAuth
-	ExtKeyUsageCodeSigning
-	ExtKeyUsageEmailProtection
-	ExtKeyUsageIPSECEndSystem
-	ExtKeyUsageIPSECTunnel
-	ExtKeyUsageIPSECUser
-	ExtKeyUsageTimeStamping
-	ExtKeyUsageOCSPSigning
-	ExtKeyUsageMicrosoftServerGatedCrypto
-	ExtKeyUsageNetscapeServerGatedCrypto
-)
-
-// extKeyUsageOIDs contains the mapping between an ExtKeyUsage and its OID.
-var extKeyUsageOIDs = []struct {
-	extKeyUsage ExtKeyUsage
-	oid         asn1.ObjectIdentifier
-}{
-	{ExtKeyUsageAny, oidExtKeyUsageAny},
-	{ExtKeyUsageServerAuth, oidExtKeyUsageServerAuth},
-	{ExtKeyUsageClientAuth, oidExtKeyUsageClientAuth},
-	{ExtKeyUsageCodeSigning, oidExtKeyUsageCodeSigning},
-	{ExtKeyUsageEmailProtection, oidExtKeyUsageEmailProtection},
-	{ExtKeyUsageIPSECEndSystem, oidExtKeyUsageIPSECEndSystem},
-	{ExtKeyUsageIPSECTunnel, oidExtKeyUsageIPSECTunnel},
-	{ExtKeyUsageIPSECUser, oidExtKeyUsageIPSECUser},
-	{ExtKeyUsageTimeStamping, oidExtKeyUsageTimeStamping},
-	{ExtKeyUsageOCSPSigning, oidExtKeyUsageOCSPSigning},
-	{ExtKeyUsageMicrosoftServerGatedCrypto, oidExtKeyUsageMicrosoftServerGatedCrypto},
-	{ExtKeyUsageNetscapeServerGatedCrypto, oidExtKeyUsageNetscapeServerGatedCrypto},
-}
-
-func extKeyUsageFromOID(oid asn1.ObjectIdentifier) (eku ExtKeyUsage, ok bool) {
-	for _, pair := range extKeyUsageOIDs {
-		if oid.Equal(pair.oid) {
-			return pair.extKeyUsage, true
-		}
-	}
-	return
-}
-
-func oidFromExtKeyUsage(eku ExtKeyUsage) (oid asn1.ObjectIdentifier, ok bool) {
-	for _, pair := range extKeyUsageOIDs {
-		if eku == pair.extKeyUsage {
-			return pair.oid, true
-		}
-	}
-	return
-}
-
-// A Certificate represents an X.509 certificate.
-type Certificate struct {
-	Raw                     []byte // Complete ASN.1 DER content (certificate, signature algorithm and signature).
-	RawTBSCertificate       []byte // Certificate part of raw ASN.1 DER content.
-	RawSubjectPublicKeyInfo []byte // DER encoded SubjectPublicKeyInfo.
-	RawSubject              []byte // DER encoded Subject
-	RawIssuer               []byte // DER encoded Issuer
-
-	Signature          []byte
-	SignatureAlgorithm SignatureAlgorithm
-
-	PublicKeyAlgorithm PublicKeyAlgorithm
-	PublicKey          interface{}
-
-	Version             int
-	SerialNumber        *big.Int
-	Issuer              pkix.Name
-	Subject             pkix.Name
-	NotBefore, NotAfter time.Time // Validity bounds.
-	KeyUsage            KeyUsage
-
-	// Extensions contains raw X.509 extensions. When parsing certificates,
-	// this can be used to extract non-critical extensions that are not
-	// parsed by this package. When marshaling certificates, the Extensions
-	// field is ignored, see ExtraExtensions.
-	Extensions []pkix.Extension
-
-	// ExtraExtensions contains extensions to be copied, raw, into any
-	// marshaled certificates. Values override any extensions that would
-	// otherwise be produced based on the other fields. The ExtraExtensions
-	// field is not populated when parsing certificates, see Extensions.
-	ExtraExtensions []pkix.Extension
-
-	ExtKeyUsage        []ExtKeyUsage           // Sequence of extended key usages.
-	UnknownExtKeyUsage []asn1.ObjectIdentifier // Encountered extended key usages unknown to this package.
-
-	BasicConstraintsValid bool // if true then the next two fields are valid.
-	IsCA                  bool
-	MaxPathLen            int
-
-	SubjectKeyId   []byte
-	AuthorityKeyId []byte
-
-	// RFC 5280, 4.2.2.1 (Authority Information Access)
-	OCSPServer            []string
-	IssuingCertificateURL []string
-
-	// Subject Alternate Name values
-	DNSNames       []string
-	EmailAddresses []string
-	IPAddresses    []net.IP
-
-	// Name constraints
-	PermittedDNSDomainsCritical bool // if true then the name constraints are marked critical.
-	PermittedDNSDomains         []string
-
-	// CRL Distribution Points
-	CRLDistributionPoints []string
-
-	PolicyIdentifiers []asn1.ObjectIdentifier
-}
-
-// ErrUnsupportedAlgorithm results from attempting to perform an operation that
-// involves algorithms that are not currently implemented.
-var ErrUnsupportedAlgorithm = errors.New("x509: cannot verify signature: algorithm unimplemented")
-
-// ConstraintViolationError results when a requested usage is not permitted by
-// a certificate. For example: checking a signature when the public key isn't a
-// certificate signing key.
-type ConstraintViolationError struct{}
-
-func (ConstraintViolationError) Error() string {
-	return "x509: invalid signature: parent certificate cannot sign this kind of certificate"
-}
-
-func (c *Certificate) Equal(other *Certificate) bool {
-	return bytes.Equal(c.Raw, other.Raw)
-}
-
-// Entrust have a broken root certificate (CN=Entrust.net Certification
-// Authority (2048)) which isn't marked as a CA certificate and is thus invalid
-// according to PKIX.
-// We recognise this certificate by its SubjectPublicKeyInfo and exempt it
-// from the Basic Constraints requirement.
-// See http://www.entrust.net/knowledge-base/technote.cfm?tn=7869
-//
-// TODO(agl): remove this hack once their reissued root is sufficiently
-// widespread.
-var entrustBrokenSPKI = []byte{
-	0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09,
-	0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
-	0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00,
-	0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01,
-	0x00, 0x97, 0xa3, 0x2d, 0x3c, 0x9e, 0xde, 0x05,
-	0xda, 0x13, 0xc2, 0x11, 0x8d, 0x9d, 0x8e, 0xe3,
-	0x7f, 0xc7, 0x4b, 0x7e, 0x5a, 0x9f, 0xb3, 0xff,
-	0x62, 0xab, 0x73, 0xc8, 0x28, 0x6b, 0xba, 0x10,
-	0x64, 0x82, 0x87, 0x13, 0xcd, 0x57, 0x18, 0xff,
-	0x28, 0xce, 0xc0, 0xe6, 0x0e, 0x06, 0x91, 0x50,
-	0x29, 0x83, 0xd1, 0xf2, 0xc3, 0x2a, 0xdb, 0xd8,
-	0xdb, 0x4e, 0x04, 0xcc, 0x00, 0xeb, 0x8b, 0xb6,
-	0x96, 0xdc, 0xbc, 0xaa, 0xfa, 0x52, 0x77, 0x04,
-	0xc1, 0xdb, 0x19, 0xe4, 0xae, 0x9c, 0xfd, 0x3c,
-	0x8b, 0x03, 0xef, 0x4d, 0xbc, 0x1a, 0x03, 0x65,
-	0xf9, 0xc1, 0xb1, 0x3f, 0x72, 0x86, 0xf2, 0x38,
-	0xaa, 0x19, 0xae, 0x10, 0x88, 0x78, 0x28, 0xda,
-	0x75, 0xc3, 0x3d, 0x02, 0x82, 0x02, 0x9c, 0xb9,
-	0xc1, 0x65, 0x77, 0x76, 0x24, 0x4c, 0x98, 0xf7,
-	0x6d, 0x31, 0x38, 0xfb, 0xdb, 0xfe, 0xdb, 0x37,
-	0x02, 0x76, 0xa1, 0x18, 0x97, 0xa6, 0xcc, 0xde,
-	0x20, 0x09, 0x49, 0x36, 0x24, 0x69, 0x42, 0xf6,
-	0xe4, 0x37, 0x62, 0xf1, 0x59, 0x6d, 0xa9, 0x3c,
-	0xed, 0x34, 0x9c, 0xa3, 0x8e, 0xdb, 0xdc, 0x3a,
-	0xd7, 0xf7, 0x0a, 0x6f, 0xef, 0x2e, 0xd8, 0xd5,
-	0x93, 0x5a, 0x7a, 0xed, 0x08, 0x49, 0x68, 0xe2,
-	0x41, 0xe3, 0x5a, 0x90, 0xc1, 0x86, 0x55, 0xfc,
-	0x51, 0x43, 0x9d, 0xe0, 0xb2, 0xc4, 0x67, 0xb4,
-	0xcb, 0x32, 0x31, 0x25, 0xf0, 0x54, 0x9f, 0x4b,
-	0xd1, 0x6f, 0xdb, 0xd4, 0xdd, 0xfc, 0xaf, 0x5e,
-	0x6c, 0x78, 0x90, 0x95, 0xde, 0xca, 0x3a, 0x48,
-	0xb9, 0x79, 0x3c, 0x9b, 0x19, 0xd6, 0x75, 0x05,
-	0xa0, 0xf9, 0x88, 0xd7, 0xc1, 0xe8, 0xa5, 0x09,
-	0xe4, 0x1a, 0x15, 0xdc, 0x87, 0x23, 0xaa, 0xb2,
-	0x75, 0x8c, 0x63, 0x25, 0x87, 0xd8, 0xf8, 0x3d,
-	0xa6, 0xc2, 0xcc, 0x66, 0xff, 0xa5, 0x66, 0x68,
-	0x55, 0x02, 0x03, 0x01, 0x00, 0x01,
-}
-
-// CheckSignatureFrom verifies that the signature on c is a valid signature
-// from parent.
-func (c *Certificate) CheckSignatureFrom(parent *Certificate) (err error) {
-	// RFC 5280, 4.2.1.9:
-	// "If the basic constraints extension is not present in a version 3
-	// certificate, or the extension is present but the cA boolean is not
-	// asserted, then the certified public key MUST NOT be used to verify
-	// certificate signatures."
-	// (except for Entrust, see comment above entrustBrokenSPKI)
-	if (parent.Version == 3 && !parent.BasicConstraintsValid ||
-		parent.BasicConstraintsValid && !parent.IsCA) &&
-		!bytes.Equal(c.RawSubjectPublicKeyInfo, entrustBrokenSPKI) {
-		return ConstraintViolationError{}
-	}
-
-	if parent.KeyUsage != 0 && parent.KeyUsage&KeyUsageCertSign == 0 {
-		return ConstraintViolationError{}
-	}
-
-	if parent.PublicKeyAlgorithm == UnknownPublicKeyAlgorithm {
-		return ErrUnsupportedAlgorithm
-	}
-
-	// TODO(agl): don't ignore the path length constraint.
-
-	return parent.CheckSignature(c.SignatureAlgorithm, c.RawTBSCertificate, c.Signature)
-}
-
-// CheckSignature verifies that signature is a valid signature over signed from
-// c's public key.
-func (c *Certificate) CheckSignature(algo SignatureAlgorithm, signed, signature []byte) (err error) {
-	var hashType crypto.Hash
-
-	switch algo {
-	case SHA1WithRSA, DSAWithSHA1, ECDSAWithSHA1:
-		hashType = crypto.SHA1
-	case SHA256WithRSA, DSAWithSHA256, ECDSAWithSHA256:
-		hashType = crypto.SHA256
-	case SHA384WithRSA, ECDSAWithSHA384:
-		hashType = crypto.SHA384
-	case SHA512WithRSA, ECDSAWithSHA512:
-		hashType = crypto.SHA512
-	default:
-		return ErrUnsupportedAlgorithm
-	}
-
-	if !hashType.Available() {
-		return ErrUnsupportedAlgorithm
-	}
-	h := hashType.New()
-
-	h.Write(signed)
-	digest := h.Sum(nil)
-
-	switch pub := c.PublicKey.(type) {
-	case *rsa.PublicKey:
-		return rsa.VerifyPKCS1v15(pub, hashType, digest, signature)
-	case *dsa.PublicKey:
-		dsaSig := new(dsaSignature)
-		if _, err := asn1.Unmarshal(signature, dsaSig); err != nil {
-			return err
-		}
-		if dsaSig.R.Sign() <= 0 || dsaSig.S.Sign() <= 0 {
-			return errors.New("x509: DSA signature contained zero or negative values")
-		}
-		if !dsa.Verify(pub, digest, dsaSig.R, dsaSig.S) {
-			return errors.New("x509: DSA verification failure")
-		}
-		return
-	case *ecdsa.PublicKey:
-		ecdsaSig := new(ecdsaSignature)
-		if _, err := asn1.Unmarshal(signature, ecdsaSig); err != nil {
-			return err
-		}
-		if ecdsaSig.R.Sign() <= 0 || ecdsaSig.S.Sign() <= 0 {
-			return errors.New("x509: ECDSA signature contained zero or negative values")
-		}
-		if !ecdsa.Verify(pub, digest, ecdsaSig.R, ecdsaSig.S) {
-			return errors.New("x509: ECDSA verification failure")
-		}
-		return
-	}
-	return ErrUnsupportedAlgorithm
-}
-
-// CheckCRLSignature checks that the signature in crl is from c.
-func (c *Certificate) CheckCRLSignature(crl *pkix.CertificateList) (err error) {
-	algo := getSignatureAlgorithmFromOID(crl.SignatureAlgorithm.Algorithm)
-	return c.CheckSignature(algo, crl.TBSCertList.Raw, crl.SignatureValue.RightAlign())
-}
-
-type UnhandledCriticalExtension struct{}
-
-func (h UnhandledCriticalExtension) Error() string {
-	return "x509: unhandled critical extension"
-}
-
-type basicConstraints struct {
-	IsCA       bool `asn1:"optional"`
-	MaxPathLen int  `asn1:"optional,default:-1"`
-}
-
-// RFC 5280 4.2.1.4
-type policyInformation struct {
-	Policy asn1.ObjectIdentifier
-	// policyQualifiers omitted
-}
-
-// RFC 5280, 4.2.1.10
-type nameConstraints struct {
-	Permitted []generalSubtree `asn1:"optional,tag:0"`
-	Excluded  []generalSubtree `asn1:"optional,tag:1"`
-}
-
-type generalSubtree struct {
-	Name string `asn1:"tag:2,optional,ia5"`
-}
-
-// RFC 5280, 4.2.2.1
-type authorityInfoAccess struct {
-	Method   asn1.ObjectIdentifier
-	Location asn1.RawValue
-}
-
-// RFC 5280, 4.2.1.14
-type distributionPoint struct {
-	DistributionPoint distributionPointName `asn1:"optional,tag:0"`
-	Reason            asn1.BitString        `asn1:"optional,tag:1"`
-	CRLIssuer         asn1.RawValue         `asn1:"optional,tag:2"`
-}
-
-type distributionPointName struct {
-	FullName     asn1.RawValue    `asn1:"optional,tag:0"`
-	RelativeName pkix.RDNSequence `asn1:"optional,tag:1"`
-}
-
-func parsePublicKey(algo PublicKeyAlgorithm, keyData *publicKeyInfo) (interface{}, error) {
-	asn1Data := keyData.PublicKey.RightAlign()
-	switch algo {
-	case RSA:
-		p := new(rsaPublicKey)
-		_, err := asn1.Unmarshal(asn1Data, p)
-		if err != nil {
-			return nil, err
-		}
-
-		if p.N.Sign() <= 0 {
-			return nil, errors.New("x509: RSA modulus is not a positive number")
-		}
-		if p.E <= 0 {
-			return nil, errors.New("x509: RSA public exponent is not a positive number")
-		}
-
-		pub := &rsa.PublicKey{
-			E: p.E,
-			N: p.N,
-		}
-		return pub, nil
-	case DSA:
-		var p *big.Int
-		_, err := asn1.Unmarshal(asn1Data, &p)
-		if err != nil {
-			return nil, err
-		}
-		paramsData := keyData.Algorithm.Parameters.FullBytes
-		params := new(dsaAlgorithmParameters)
-		_, err = asn1.Unmarshal(paramsData, params)
-		if err != nil {
-			return nil, err
-		}
-		if p.Sign() <= 0 || params.P.Sign() <= 0 || params.Q.Sign() <= 0 || params.G.Sign() <= 0 {
-			return nil, errors.New("x509: zero or negative DSA parameter")
-		}
-		pub := &dsa.PublicKey{
-			Parameters: dsa.Parameters{
-				P: params.P,
-				Q: params.Q,
-				G: params.G,
-			},
-			Y: p,
-		}
-		return pub, nil
-	case ECDSA:
-		paramsData := keyData.Algorithm.Parameters.FullBytes
-		namedCurveOID := new(asn1.ObjectIdentifier)
-		_, err := asn1.Unmarshal(paramsData, namedCurveOID)
-		if err != nil {
-			return nil, err
-		}
-		namedCurve := namedCurveFromOID(*namedCurveOID)
-		if namedCurve == nil {
-			return nil, errors.New("x509: unsupported elliptic curve")
-		}
-		x, y := elliptic.Unmarshal(namedCurve, asn1Data)
-		if x == nil {
-			return nil, errors.New("x509: failed to unmarshal elliptic curve point")
-		}
-		pub := &ecdsa.PublicKey{
-			Curve: namedCurve,
-			X:     x,
-			Y:     y,
-		}
-		return pub, nil
-	default:
-		return nil, nil
-	}
-}
-
-func parseSANExtension(value []byte) (dnsNames, emailAddresses []string, ipAddresses []net.IP, err error) {
-	// RFC 5280, 4.2.1.6
-
-	// SubjectAltName ::= GeneralNames
-	//
-	// GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
-	//
-	// GeneralName ::= CHOICE {
-	//      otherName                       [0]     OtherName,
-	//      rfc822Name                      [1]     IA5String,
-	//      dNSName                         [2]     IA5String,
-	//      x400Address                     [3]     ORAddress,
-	//      directoryName                   [4]     Name,
-	//      ediPartyName                    [5]     EDIPartyName,
-	//      uniformResourceIdentifier       [6]     IA5String,
-	//      iPAddress                       [7]     OCTET STRING,
-	//      registeredID                    [8]     OBJECT IDENTIFIER }
-	var seq asn1.RawValue
-	if _, err = asn1.Unmarshal(value, &seq); err != nil {
-		return
-	}
-	if !seq.IsCompound || seq.Tag != 16 || seq.Class != 0 {
-		err = asn1.StructuralError{Msg: "bad SAN sequence"}
-		return
-	}
-
-	rest := seq.Bytes
-	for len(rest) > 0 {
-		var v asn1.RawValue
-		rest, err = asn1.Unmarshal(rest, &v)
-		if err != nil {
-			return
-		}
-		switch v.Tag {
-		case 1:
-			emailAddresses = append(emailAddresses, string(v.Bytes))
-		case 2:
-			dnsNames = append(dnsNames, string(v.Bytes))
-		case 7:
-			switch len(v.Bytes) {
-			case net.IPv4len, net.IPv6len:
-				ipAddresses = append(ipAddresses, v.Bytes)
-			default:
-				err = errors.New("x509: certificate contained IP address of length " + strconv.Itoa(len(v.Bytes)))
-				return
-			}
-		}
-	}
-
-	return
-}
-
-func parseCertificate(in *certificate) (*Certificate, error) {
-	out := new(Certificate)
-	out.Raw = in.Raw
-	out.RawTBSCertificate = in.TBSCertificate.Raw
-	out.RawSubjectPublicKeyInfo = in.TBSCertificate.PublicKey.Raw
-	out.RawSubject = in.TBSCertificate.Subject.FullBytes
-	out.RawIssuer = in.TBSCertificate.Issuer.FullBytes
-
-	out.Signature = in.SignatureValue.RightAlign()
-	out.SignatureAlgorithm =
-		getSignatureAlgorithmFromOID(in.TBSCertificate.SignatureAlgorithm.Algorithm)
-
-	out.PublicKeyAlgorithm =
-		getPublicKeyAlgorithmFromOID(in.TBSCertificate.PublicKey.Algorithm.Algorithm)
-	var err error
-	out.PublicKey, err = parsePublicKey(out.PublicKeyAlgorithm, &in.TBSCertificate.PublicKey)
-	if err != nil {
-		return nil, err
-	}
-
-	if in.TBSCertificate.SerialNumber.Sign() < 0 {
-		return nil, errors.New("x509: negative serial number")
-	}
-
-	out.Version = in.TBSCertificate.Version + 1
-	out.SerialNumber = in.TBSCertificate.SerialNumber
-
-	var issuer, subject pkix.RDNSequence
-	if _, err := asn1.Unmarshal(in.TBSCertificate.Subject.FullBytes, &subject); err != nil {
-		return nil, err
-	}
-	if _, err := asn1.Unmarshal(in.TBSCertificate.Issuer.FullBytes, &issuer); err != nil {
-		return nil, err
-	}
-
-	out.Issuer.FillFromRDNSequence(&issuer)
-	out.Subject.FillFromRDNSequence(&subject)
-
-	out.NotBefore = in.TBSCertificate.Validity.NotBefore
-	out.NotAfter = in.TBSCertificate.Validity.NotAfter
-
-	for _, e := range in.TBSCertificate.Extensions {
-		out.Extensions = append(out.Extensions, e)
-
-		if len(e.Id) == 4 && e.Id[0] == 2 && e.Id[1] == 5 && e.Id[2] == 29 {
-			switch e.Id[3] {
-			case 15:
-				// RFC 5280, 4.2.1.3
-				var usageBits asn1.BitString
-				_, err := asn1.Unmarshal(e.Value, &usageBits)
-
-				if err == nil {
-					var usage int
-					for i := 0; i < 9; i++ {
-						if usageBits.At(i) != 0 {
-							usage |= 1 << uint(i)
-						}
-					}
-					out.KeyUsage = KeyUsage(usage)
-					continue
-				}
-			case 19:
-				// RFC 5280, 4.2.1.9
-				var constraints basicConstraints
-				_, err := asn1.Unmarshal(e.Value, &constraints)
-
-				if err == nil {
-					out.BasicConstraintsValid = true
-					out.IsCA = constraints.IsCA
-					out.MaxPathLen = constraints.MaxPathLen
-					continue
-				}
-			case 17:
-				out.DNSNames, out.EmailAddresses, out.IPAddresses, err = parseSANExtension(e.Value)
-				if err != nil {
-					return nil, err
-				}
-
-				if len(out.DNSNames) > 0 || len(out.EmailAddresses) > 0 || len(out.IPAddresses) > 0 {
-					continue
-				}
-				// If we didn't parse any of the names then we
-				// fall through to the critical check below.
-
-			case 30:
-				// RFC 5280, 4.2.1.10
-
-				// NameConstraints ::= SEQUENCE {
-				//      permittedSubtrees       [0]     GeneralSubtrees OPTIONAL,
-				//      excludedSubtrees        [1]     GeneralSubtrees OPTIONAL }
-				//
-				// GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree
-				//
-				// GeneralSubtree ::= SEQUENCE {
-				//      base                    GeneralName,
-				//      minimum         [0]     BaseDistance DEFAULT 0,
-				//      maximum         [1]     BaseDistance OPTIONAL }
-				//
-				// BaseDistance ::= INTEGER (0..MAX)
-
-				var constraints nameConstraints
-				_, err := asn1.Unmarshal(e.Value, &constraints)
-				if err != nil {
-					return nil, err
-				}
-
-				if len(constraints.Excluded) > 0 && e.Critical {
-					return out, UnhandledCriticalExtension{}
-				}
-
-				for _, subtree := range constraints.Permitted {
-					if len(subtree.Name) == 0 {
-						if e.Critical {
-							return out, UnhandledCriticalExtension{}
-						}
-						continue
-					}
-					out.PermittedDNSDomains = append(out.PermittedDNSDomains, subtree.Name)
-				}
-				continue
-
-			case 31:
-				// RFC 5280, 4.2.1.14
-
-				// CRLDistributionPoints ::= SEQUENCE SIZE (1..MAX) OF DistributionPoint
-				//
-				// DistributionPoint ::= SEQUENCE {
-				//     distributionPoint       [0]     DistributionPointName OPTIONAL,
-				//     reasons                 [1]     ReasonFlags OPTIONAL,
-				//     cRLIssuer               [2]     GeneralNames OPTIONAL }
-				//
-				// DistributionPointName ::= CHOICE {
-				//     fullName                [0]     GeneralNames,
-				//     nameRelativeToCRLIssuer [1]     RelativeDistinguishedName }
-
-				var cdp []distributionPoint
-				_, err := asn1.Unmarshal(e.Value, &cdp)
-				if err != nil {
-					return nil, err
-				}
-
-				for _, dp := range cdp {
-					var n asn1.RawValue
-					_, err = asn1.Unmarshal(dp.DistributionPoint.FullName.Bytes, &n)
-					if err != nil {
-						return nil, err
-					}
-
-					if n.Tag == 6 {
-						out.CRLDistributionPoints = append(out.CRLDistributionPoints, string(n.Bytes))
-					}
-				}
-				continue
-
-			case 35:
-				// RFC 5280, 4.2.1.1
-				var a authKeyId
-				_, err = asn1.Unmarshal(e.Value, &a)
-				if err != nil {
-					return nil, err
-				}
-				out.AuthorityKeyId = a.Id
-				continue
-
-			case 37:
-				// RFC 5280, 4.2.1.12.  Extended Key Usage
-
-				// id-ce-extKeyUsage OBJECT IDENTIFIER ::= { id-ce 37 }
-				//
-				// ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
-				//
-				// KeyPurposeId ::= OBJECT IDENTIFIER
-
-				var keyUsage []asn1.ObjectIdentifier
-				_, err = asn1.Unmarshal(e.Value, &keyUsage)
-				if err != nil {
-					return nil, err
-				}
-
-				for _, u := range keyUsage {
-					if extKeyUsage, ok := extKeyUsageFromOID(u); ok {
-						out.ExtKeyUsage = append(out.ExtKeyUsage, extKeyUsage)
-					} else {
-						out.UnknownExtKeyUsage = append(out.UnknownExtKeyUsage, u)
-					}
-				}
-
-				continue
-
-			case 14:
-				// RFC 5280, 4.2.1.2
-				var keyid []byte
-				_, err = asn1.Unmarshal(e.Value, &keyid)
-				if err != nil {
-					return nil, err
-				}
-				out.SubjectKeyId = keyid
-				continue
-
-			case 32:
-				// RFC 5280 4.2.1.4: Certificate Policies
-				var policies []policyInformation
-				if _, err = asn1.Unmarshal(e.Value, &policies); err != nil {
-					return nil, err
-				}
-				out.PolicyIdentifiers = make([]asn1.ObjectIdentifier, len(policies))
-				for i, policy := range policies {
-					out.PolicyIdentifiers[i] = policy.Policy
-				}
-			}
-		} else if e.Id.Equal(oidExtensionAuthorityInfoAccess) {
-			// RFC 5280 4.2.2.1: Authority Information Access
-			var aia []authorityInfoAccess
-			if _, err = asn1.Unmarshal(e.Value, &aia); err != nil {
-				return nil, err
-			}
-
-			for _, v := range aia {
-				// GeneralName: uniformResourceIdentifier [6] IA5String
-				if v.Location.Tag != 6 {
-					continue
-				}
-				if v.Method.Equal(oidAuthorityInfoAccessOcsp) {
-					out.OCSPServer = append(out.OCSPServer, string(v.Location.Bytes))
-				} else if v.Method.Equal(oidAuthorityInfoAccessIssuers) {
-					out.IssuingCertificateURL = append(out.IssuingCertificateURL, string(v.Location.Bytes))
-				}
-			}
-		}
-
-		if e.Critical {
-			return out, UnhandledCriticalExtension{}
-		}
-	}
-
-	return out, nil
-}
-
-// ParseCertificate parses a single certificate from the given ASN.1 DER data.
-func ParseCertificate(asn1Data []byte) (*Certificate, error) {
-	var cert certificate
-	rest, err := asn1.Unmarshal(asn1Data, &cert)
-	if err != nil {
-		return nil, err
-	}
-	if len(rest) > 0 {
-		return nil, asn1.SyntaxError{Msg: "trailing data"}
-	}
-
-	return parseCertificate(&cert)
-}
-
-// ParseCertificates parses one or more certificates from the given ASN.1 DER
-// data. The certificates must be concatenated with no intermediate padding.
-func ParseCertificates(asn1Data []byte) ([]*Certificate, error) {
-	var v []*certificate
-
-	for len(asn1Data) > 0 {
-		cert := new(certificate)
-		var err error
-		asn1Data, err = asn1.Unmarshal(asn1Data, cert)
-		if err != nil {
-			return nil, err
-		}
-		v = append(v, cert)
-	}
-
-	ret := make([]*Certificate, len(v))
-	for i, ci := range v {
-		cert, err := parseCertificate(ci)
-		if err != nil {
-			return nil, err
-		}
-		ret[i] = cert
-	}
-
-	return ret, nil
-}
-
-func reverseBitsInAByte(in byte) byte {
-	b1 := in>>4 | in<<4
-	b2 := b1>>2&0x33 | b1<<2&0xcc
-	b3 := b2>>1&0x55 | b2<<1&0xaa
-	return b3
-}
-
-var (
-	oidExtensionSubjectKeyId          = []int{2, 5, 29, 14}
-	oidExtensionKeyUsage              = []int{2, 5, 29, 15}
-	oidExtensionExtendedKeyUsage      = []int{2, 5, 29, 37}
-	oidExtensionAuthorityKeyId        = []int{2, 5, 29, 35}
-	oidExtensionBasicConstraints      = []int{2, 5, 29, 19}
-	oidExtensionSubjectAltName        = []int{2, 5, 29, 17}
-	oidExtensionCertificatePolicies   = []int{2, 5, 29, 32}
-	oidExtensionNameConstraints       = []int{2, 5, 29, 30}
-	oidExtensionCRLDistributionPoints = []int{2, 5, 29, 31}
-	oidExtensionAuthorityInfoAccess   = []int{1, 3, 6, 1, 5, 5, 7, 1, 1}
-)
-
-var (
-	oidAuthorityInfoAccessOcsp    = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 48, 1}
-	oidAuthorityInfoAccessIssuers = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 48, 2}
-)
-
-// oidNotInExtensions returns whether an extension with the given oid exists in
-// extensions.
-func oidInExtensions(oid asn1.ObjectIdentifier, extensions []pkix.Extension) bool {
-	for _, e := range extensions {
-		if e.Id.Equal(oid) {
-			return true
-		}
-	}
-	return false
-}
-
-// marshalSANs marshals a list of addresses into a the contents of an X.509
-// SubjectAlternativeName extension.
-func marshalSANs(dnsNames, emailAddresses []string, ipAddresses []net.IP) (derBytes []byte, err error) {
-	var rawValues []asn1.RawValue
-	for _, name := range dnsNames {
-		rawValues = append(rawValues, asn1.RawValue{Tag: 2, Class: 2, Bytes: []byte(name)})
-	}
-	for _, email := range emailAddresses {
-		rawValues = append(rawValues, asn1.RawValue{Tag: 1, Class: 2, Bytes: []byte(email)})
-	}
-	for _, rawIP := range ipAddresses {
-		// If possible, we always want to encode IPv4 addresses in 4 bytes.
-		ip := rawIP.To4()
-		if ip == nil {
-			ip = rawIP
-		}
-		rawValues = append(rawValues, asn1.RawValue{Tag: 7, Class: 2, Bytes: ip})
-	}
-	return asn1.Marshal(rawValues)
-}
-
-func buildExtensions(template *Certificate) (ret []pkix.Extension, err error) {
-	ret = make([]pkix.Extension, 10 /* maximum number of elements. */)
-	n := 0
-
-	if template.KeyUsage != 0 &&
-		!oidInExtensions(oidExtensionKeyUsage, template.ExtraExtensions) {
-		ret[n].Id = oidExtensionKeyUsage
-		ret[n].Critical = true
-
-		var a [2]byte
-		a[0] = reverseBitsInAByte(byte(template.KeyUsage))
-		a[1] = reverseBitsInAByte(byte(template.KeyUsage >> 8))
-
-		l := 1
-		if a[1] != 0 {
-			l = 2
-		}
-
-		ret[n].Value, err = asn1.Marshal(asn1.BitString{Bytes: a[0:l], BitLength: l * 8})
-		if err != nil {
-			return
-		}
-		n++
-	}
-
-	if (len(template.ExtKeyUsage) > 0 || len(template.UnknownExtKeyUsage) > 0) &&
-		!oidInExtensions(oidExtensionExtendedKeyUsage, template.ExtraExtensions) {
-		ret[n].Id = oidExtensionExtendedKeyUsage
-
-		var oids []asn1.ObjectIdentifier
-		for _, u := range template.ExtKeyUsage {
-			if oid, ok := oidFromExtKeyUsage(u); ok {
-				oids = append(oids, oid)
-			} else {
-				panic("internal error")
-			}
-		}
-
-		oids = append(oids, template.UnknownExtKeyUsage...)
-
-		ret[n].Value, err = asn1.Marshal(oids)
-		if err != nil {
-			return
-		}
-		n++
-	}
-
-	if template.BasicConstraintsValid && !oidInExtensions(oidExtensionBasicConstraints, template.ExtraExtensions) {
-		ret[n].Id = oidExtensionBasicConstraints
-		ret[n].Value, err = asn1.Marshal(basicConstraints{template.IsCA, template.MaxPathLen})
-		ret[n].Critical = true
-		if err != nil {
-			return
-		}
-		n++
-	}
-
-	if len(template.SubjectKeyId) > 0 && !oidInExtensions(oidExtensionSubjectKeyId, template.ExtraExtensions) {
-		ret[n].Id = oidExtensionSubjectKeyId
-		ret[n].Value, err = asn1.Marshal(template.SubjectKeyId)
-		if err != nil {
-			return
-		}
-		n++
-	}
-
-	if len(template.AuthorityKeyId) > 0 && !oidInExtensions(oidExtensionAuthorityKeyId, template.ExtraExtensions) {
-		ret[n].Id = oidExtensionAuthorityKeyId
-		ret[n].Value, err = asn1.Marshal(authKeyId{template.AuthorityKeyId})
-		if err != nil {
-			return
-		}
-		n++
-	}
-
-	if (len(template.OCSPServer) > 0 || len(template.IssuingCertificateURL) > 0) &&
-		!oidInExtensions(oidExtensionAuthorityInfoAccess, template.ExtraExtensions) {
-		ret[n].Id = oidExtensionAuthorityInfoAccess
-		var aiaValues []authorityInfoAccess
-		for _, name := range template.OCSPServer {
-			aiaValues = append(aiaValues, authorityInfoAccess{
-				Method:   oidAuthorityInfoAccessOcsp,
-				Location: asn1.RawValue{Tag: 6, Class: 2, Bytes: []byte(name)},
-			})
-		}
-		for _, name := range template.IssuingCertificateURL {
-			aiaValues = append(aiaValues, authorityInfoAccess{
-				Method:   oidAuthorityInfoAccessIssuers,
-				Location: asn1.RawValue{Tag: 6, Class: 2, Bytes: []byte(name)},
-			})
-		}
-		ret[n].Value, err = asn1.Marshal(aiaValues)
-		if err != nil {
-			return
-		}
-		n++
-	}
-
-	if (len(template.DNSNames) > 0 || len(template.EmailAddresses) > 0 || len(template.IPAddresses) > 0) &&
-		!oidInExtensions(oidExtensionSubjectAltName, template.ExtraExtensions) {
-		ret[n].Id = oidExtensionSubjectAltName
-		ret[n].Value, err = marshalSANs(template.DNSNames, template.EmailAddresses, template.IPAddresses)
-		if err != nil {
-			return
-		}
-		n++
-	}
-
-	if len(template.PolicyIdentifiers) > 0 &&
-		!oidInExtensions(oidExtensionCertificatePolicies, template.ExtraExtensions) {
-		ret[n].Id = oidExtensionCertificatePolicies
-		policies := make([]policyInformation, len(template.PolicyIdentifiers))
-		for i, policy := range template.PolicyIdentifiers {
-			policies[i].Policy = policy
-		}
-		ret[n].Value, err = asn1.Marshal(policies)
-		if err != nil {
-			return
-		}
-		n++
-	}
-
-	if len(template.PermittedDNSDomains) > 0 &&
-		!oidInExtensions(oidExtensionNameConstraints, template.ExtraExtensions) {
-		ret[n].Id = oidExtensionNameConstraints
-		ret[n].Critical = template.PermittedDNSDomainsCritical
-
-		var out nameConstraints
-		out.Permitted = make([]generalSubtree, len(template.PermittedDNSDomains))
-		for i, permitted := range template.PermittedDNSDomains {
-			out.Permitted[i] = generalSubtree{Name: permitted}
-		}
-		ret[n].Value, err = asn1.Marshal(out)
-		if err != nil {
-			return
-		}
-		n++
-	}
-
-	if len(template.CRLDistributionPoints) > 0 &&
-		!oidInExtensions(oidExtensionCRLDistributionPoints, template.ExtraExtensions) {
-		ret[n].Id = oidExtensionCRLDistributionPoints
-
-		var crlDp []distributionPoint
-		for _, name := range template.CRLDistributionPoints {
-			rawFullName, _ := asn1.Marshal(asn1.RawValue{Tag: 6, Class: 2, Bytes: []byte(name)})
-
-			dp := distributionPoint{
-				DistributionPoint: distributionPointName{
-					FullName: asn1.RawValue{Tag: 0, Class: 2, Bytes: rawFullName},
-				},
-			}
-			crlDp = append(crlDp, dp)
-		}
-
-		ret[n].Value, err = asn1.Marshal(crlDp)
-		if err != nil {
-			return
-		}
-		n++
-	}
-
-	// Adding another extension here? Remember to update the maximum number
-	// of elements in the make() at the top of the function.
-
-	return append(ret[:n], template.ExtraExtensions...), nil
-}
-
-func subjectBytes(cert *Certificate) ([]byte, error) {
-	if len(cert.RawSubject) > 0 {
-		return cert.RawSubject, nil
-	}
-
-	return asn1.Marshal(cert.Subject.ToRDNSequence())
-}
-
-// signingParamsForPrivateKey returns the parameters to use for signing with
-// priv. If requestedSigAlgo is not zero then it overrides the default
-// signature algorithm.
-func signingParamsForPrivateKey(priv interface{}, requestedSigAlgo SignatureAlgorithm) (hashFunc crypto.Hash, sigAlgo pkix.AlgorithmIdentifier, err error) {
-	var pubType PublicKeyAlgorithm
-
-	switch priv := priv.(type) {
-	case *rsa.PrivateKey:
-		pubType = RSA
-		sigAlgo.Algorithm = oidSignatureSHA256WithRSA
-		hashFunc = crypto.SHA256
-
-	case *ecdsa.PrivateKey:
-		pubType = ECDSA
-
-		switch priv.Curve {
-		case elliptic.P224(), elliptic.P256():
-			hashFunc = crypto.SHA256
-			sigAlgo.Algorithm = oidSignatureECDSAWithSHA256
-		case elliptic.P384():
-			hashFunc = crypto.SHA384
-			sigAlgo.Algorithm = oidSignatureECDSAWithSHA384
-		case elliptic.P521():
-			hashFunc = crypto.SHA512
-			sigAlgo.Algorithm = oidSignatureECDSAWithSHA512
-		default:
-			err = errors.New("x509: unknown elliptic curve")
-		}
-
-	default:
-		err = errors.New("x509: only RSA and ECDSA private keys supported")
-	}
-
-	if err != nil {
-		return
-	}
-
-	if requestedSigAlgo == 0 {
-		return
-	}
-
-	found := false
-	for _, details := range signatureAlgorithmDetails {
-		if details.algo == requestedSigAlgo {
-			if details.pubKeyAlgo != pubType {
-				err = errors.New("x509: requested SignatureAlgorithm does not match private key type")
-				return
-			}
-			sigAlgo.Algorithm, hashFunc = details.oid, details.hash
-			if hashFunc == 0 {
-				err = errors.New("x509: cannot sign with hash function requested")
-				return
-			}
-			found = true
-			break
-		}
-	}
-
-	if !found {
-		err = errors.New("x509: unknown SignatureAlgorithm")
-	}
-
-	return
-}
-
-// CreateCertificate creates a new certificate based on a template. The
-// following members of template are used: SerialNumber, Subject, NotBefore,
-// NotAfter, KeyUsage, ExtKeyUsage, UnknownExtKeyUsage, BasicConstraintsValid,
-// IsCA, MaxPathLen, SubjectKeyId, DNSNames, PermittedDNSDomainsCritical,
-// PermittedDNSDomains, SignatureAlgorithm.
-//
-// The certificate is signed by parent. If parent is equal to template then the
-// certificate is self-signed. The parameter pub is the public key of the
-// signee and priv is the private key of the signer.
-//
-// The returned slice is the certificate in DER encoding.
-//
-// The only supported key types are RSA and ECDSA (*rsa.PublicKey or
-// *ecdsa.PublicKey for pub, *rsa.PrivateKey or *ecdsa.PrivateKey for priv).
-func CreateCertificate(rand io.Reader, template, parent *Certificate, pub interface{}, priv interface{}) (cert []byte, err error) {
-	hashFunc, signatureAlgorithm, err := signingParamsForPrivateKey(priv, template.SignatureAlgorithm)
-	if err != nil {
-		return nil, err
-	}
-
-	publicKeyBytes, publicKeyAlgorithm, err := marshalPublicKey(pub)
-	if err != nil {
-		return nil, err
-	}
-
-	if err != nil {
-		return
-	}
-
-	if len(parent.SubjectKeyId) > 0 {
-		template.AuthorityKeyId = parent.SubjectKeyId
-	}
-
-	extensions, err := buildExtensions(template)
-	if err != nil {
-		return
-	}
-
-	asn1Issuer, err := subjectBytes(parent)
-	if err != nil {
-		return
-	}
-
-	asn1Subject, err := subjectBytes(template)
-	if err != nil {
-		return
-	}
-
-	encodedPublicKey := asn1.BitString{BitLength: len(publicKeyBytes) * 8, Bytes: publicKeyBytes}
-	c := tbsCertificate{
-		Version:            2,
-		SerialNumber:       template.SerialNumber,
-		SignatureAlgorithm: signatureAlgorithm,
-		Issuer:             asn1.RawValue{FullBytes: asn1Issuer},
-		Validity:           validity{template.NotBefore.UTC(), template.NotAfter.UTC()},
-		Subject:            asn1.RawValue{FullBytes: asn1Subject},
-		PublicKey:          publicKeyInfo{nil, publicKeyAlgorithm, encodedPublicKey},
-		Extensions:         extensions,
-	}
-
-	tbsCertContents, err := asn1.Marshal(c)
-	if err != nil {
-		return
-	}
-
-	c.Raw = tbsCertContents
-
-	h := hashFunc.New()
-	h.Write(tbsCertContents)
-	digest := h.Sum(nil)
-
-	var signature []byte
-
-	switch priv := priv.(type) {
-	case *rsa.PrivateKey:
-		signature, err = rsa.SignPKCS1v15(rand, priv, hashFunc, digest)
-	case *ecdsa.PrivateKey:
-		var r, s *big.Int
-		if r, s, err = ecdsa.Sign(rand, priv, digest); err == nil {
-			signature, err = asn1.Marshal(ecdsaSignature{r, s})
-		}
-	default:
-		panic("internal error")
-	}
-
-	if err != nil {
-		return
-	}
-
-	cert, err = asn1.Marshal(certificate{
-		nil,
-		c,
-		signatureAlgorithm,
-		asn1.BitString{Bytes: signature, BitLength: len(signature) * 8},
-	})
-	return
-}
-
-// pemCRLPrefix is the magic string that indicates that we have a PEM encoded
-// CRL.
-var pemCRLPrefix = []byte("-----BEGIN X509 CRL")
-
-// pemType is the type of a PEM encoded CRL.
-var pemType = "X509 CRL"
-
-// ParseCRL parses a CRL from the given bytes. It's often the case that PEM
-// encoded CRLs will appear where they should be DER encoded, so this function
-// will transparently handle PEM encoding as long as there isn't any leading
-// garbage.
-func ParseCRL(crlBytes []byte) (certList *pkix.CertificateList, err error) {
-	if bytes.HasPrefix(crlBytes, pemCRLPrefix) {
-		block, _ := pem.Decode(crlBytes)
-		if block != nil && block.Type == pemType {
-			crlBytes = block.Bytes
-		}
-	}
-	return ParseDERCRL(crlBytes)
-}
-
-// ParseDERCRL parses a DER encoded CRL from the given bytes.
-func ParseDERCRL(derBytes []byte) (certList *pkix.CertificateList, err error) {
-	certList = new(pkix.CertificateList)
-	_, err = asn1.Unmarshal(derBytes, certList)
-	if err != nil {
-		certList = nil
-	}
-	return
-}
-
-// CreateCRL returns a DER encoded CRL, signed by this Certificate, that
-// contains the given list of revoked certificates.
-//
-// The only supported key type is RSA (*rsa.PrivateKey for priv).
-func (c *Certificate) CreateCRL(rand io.Reader, priv interface{}, revokedCerts []pkix.RevokedCertificate, now, expiry time.Time) (crlBytes []byte, err error) {
-	rsaPriv, ok := priv.(*rsa.PrivateKey)
-	if !ok {
-		return nil, errors.New("x509: non-RSA private keys not supported")
-	}
-	tbsCertList := pkix.TBSCertificateList{
-		Version: 2,
-		Signature: pkix.AlgorithmIdentifier{
-			Algorithm: oidSignatureSHA1WithRSA,
-		},
-		Issuer:              c.Subject.ToRDNSequence(),
-		ThisUpdate:          now.UTC(),
-		NextUpdate:          expiry.UTC(),
-		RevokedCertificates: revokedCerts,
-	}
-
-	tbsCertListContents, err := asn1.Marshal(tbsCertList)
-	if err != nil {
-		return
-	}
-
-	h := sha1.New()
-	h.Write(tbsCertListContents)
-	digest := h.Sum(nil)
-
-	signature, err := rsa.SignPKCS1v15(rand, rsaPriv, crypto.SHA1, digest)
-	if err != nil {
-		return
-	}
-
-	return asn1.Marshal(pkix.CertificateList{
-		TBSCertList: tbsCertList,
-		SignatureAlgorithm: pkix.AlgorithmIdentifier{
-			Algorithm: oidSignatureSHA1WithRSA,
-		},
-		SignatureValue: asn1.BitString{Bytes: signature, BitLength: len(signature) * 8},
-	})
-}
-
-// CertificateRequest represents a PKCS #10, certificate signature request.
-type CertificateRequest struct {
-	Raw                      []byte // Complete ASN.1 DER content (CSR, signature algorithm and signature).
-	RawTBSCertificateRequest []byte // Certificate request info part of raw ASN.1 DER content.
-	RawSubjectPublicKeyInfo  []byte // DER encoded SubjectPublicKeyInfo.
-	RawSubject               []byte // DER encoded Subject.
-
-	Version            int
-	Signature          []byte
-	SignatureAlgorithm SignatureAlgorithm
-
-	PublicKeyAlgorithm PublicKeyAlgorithm
-	PublicKey          interface{}
-
-	Subject pkix.Name
-
-	// Attributes is a collection of attributes providing
-	// additional information about the subject of the certificate.
-	// See RFC 2986 section 4.1.
-	Attributes []pkix.AttributeTypeAndValueSET
-
-	// Extensions contains raw X.509 extensions. When parsing CSRs, this
-	// can be used to extract extensions that are not parsed by this
-	// package.
-	Extensions []pkix.Extension
-
-	// ExtraExtensions contains extensions to be copied, raw, into any
-	// marshaled CSR. Values override any extensions that would otherwise
-	// be produced based on the other fields but are overridden by any
-	// extensions specified in Attributes.
-	//
-	// The ExtraExtensions field is not populated when parsing CSRs, see
-	// Extensions.
-	ExtraExtensions []pkix.Extension
-
-	// Subject Alternate Name values.
-	DNSNames       []string
-	EmailAddresses []string
-	IPAddresses    []net.IP
-}
-
-// These structures reflect the ASN.1 structure of X.509 certificate
-// signature requests (see RFC 2986):
-
-type tbsCertificateRequest struct {
-	Raw        asn1.RawContent
-	Version    int
-	Subject    asn1.RawValue
-	PublicKey  publicKeyInfo
-	Attributes []pkix.AttributeTypeAndValueSET `asn1:"tag:0"`
-}
-
-type certificateRequest struct {
-	Raw                asn1.RawContent
-	TBSCSR             tbsCertificateRequest
-	SignatureAlgorithm pkix.AlgorithmIdentifier
-	SignatureValue     asn1.BitString
-}
-
-// oidExtensionRequest is a PKCS#9 OBJECT IDENTIFIER that indicates requested
-// extensions in a CSR.
-var oidExtensionRequest = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 14}
-
-// CreateCertificateRequest creates a new certificate based on a template. The
-// following members of template are used: Subject, Attributes,
-// SignatureAlgorithm, Extension, DNSNames, EmailAddresses, and IPAddresses.
-// The private key is the private key of the signer.
-//
-// The returned slice is the certificate request in DER encoding.
-//
-// The only supported key types are RSA (*rsa.PrivateKey) and ECDSA
-// (*ecdsa.PrivateKey).
-func CreateCertificateRequest(rand io.Reader, template *CertificateRequest, priv interface{}) (csr []byte, err error) {
-	hashFunc, sigAlgo, err := signingParamsForPrivateKey(priv, template.SignatureAlgorithm)
-	if err != nil {
-		return nil, err
-	}
-
-	var publicKeyBytes []byte
-	var publicKeyAlgorithm pkix.AlgorithmIdentifier
-
-	switch priv := priv.(type) {
-	case *rsa.PrivateKey:
-		publicKeyBytes, publicKeyAlgorithm, err = marshalPublicKey(&priv.PublicKey)
-	case *ecdsa.PrivateKey:
-		publicKeyBytes, publicKeyAlgorithm, err = marshalPublicKey(&priv.PublicKey)
-	default:
-		panic("internal error")
-	}
-
-	if err != nil {
-		return nil, err
-	}
-
-	var extensions []pkix.Extension
-
-	if (len(template.DNSNames) > 0 || len(template.EmailAddresses) > 0 || len(template.IPAddresses) > 0) &&
-		!oidInExtensions(oidExtensionSubjectAltName, template.ExtraExtensions) {
-		sanBytes, err := marshalSANs(template.DNSNames, template.EmailAddresses, template.IPAddresses)
-		if err != nil {
-			return nil, err
-		}
-
-		extensions = append(extensions, pkix.Extension{
-			Id:    oidExtensionSubjectAltName,
-			Value: sanBytes,
-		})
-	}
-
-	extensions = append(extensions, template.ExtraExtensions...)
-
-	var attributes []pkix.AttributeTypeAndValueSET
-	attributes = append(attributes, template.Attributes...)
-
-	if len(extensions) > 0 {
-		// specifiedExtensions contains all the extensions that we
-		// found specified via template.Attributes.
-		specifiedExtensions := make(map[string]bool)
-
-		for _, atvSet := range template.Attributes {
-			if !atvSet.Type.Equal(oidExtensionRequest) {
-				continue
-			}
-
-			for _, atvs := range atvSet.Value {
-				for _, atv := range atvs {
-					specifiedExtensions[atv.Type.String()] = true
-				}
-			}
-		}
-
-		atvs := make([]pkix.AttributeTypeAndValue, 0, len(extensions))
-		for _, e := range extensions {
-			if specifiedExtensions[e.Id.String()] {
-				// Attributes already contained a value for
-				// this extension and it takes priority.
-				continue
-			}
-
-			atvs = append(atvs, pkix.AttributeTypeAndValue{
-				// There is no place for the critical flag in a CSR.
-				Type:  e.Id,
-				Value: e.Value,
-			})
-		}
-
-		// Append the extensions to an existing attribute if possible.
-		appended := false
-		for _, atvSet := range attributes {
-			if !atvSet.Type.Equal(oidExtensionRequest) || len(atvSet.Value) == 0 {
-				continue
-			}
-
-			atvSet.Value[0] = append(atvSet.Value[0], atvs...)
-			appended = true
-			break
-		}
-
-		// Otherwise, add a new attribute for the extensions.
-		if !appended {
-			attributes = append(attributes, pkix.AttributeTypeAndValueSET{
-				Type: oidExtensionRequest,
-				Value: [][]pkix.AttributeTypeAndValue{
-					atvs,
-				},
-			})
-		}
-	}
-
-	asn1Subject := template.RawSubject
-	if len(asn1Subject) == 0 {
-		asn1Subject, err = asn1.Marshal(template.Subject.ToRDNSequence())
-		if err != nil {
-			return
-		}
-	}
-
-	tbsCSR := tbsCertificateRequest{
-		Version: 0, // PKCS #10, RFC 2986
-		Subject: asn1.RawValue{FullBytes: asn1Subject},
-		PublicKey: publicKeyInfo{
-			Algorithm: publicKeyAlgorithm,
-			PublicKey: asn1.BitString{
-				Bytes:     publicKeyBytes,
-				BitLength: len(publicKeyBytes) * 8,
-			},
-		},
-		Attributes: attributes,
-	}
-
-	tbsCSRContents, err := asn1.Marshal(tbsCSR)
-	if err != nil {
-		return
-	}
-	tbsCSR.Raw = tbsCSRContents
-
-	h := hashFunc.New()
-	h.Write(tbsCSRContents)
-	digest := h.Sum(nil)
-
-	var signature []byte
-	switch priv := priv.(type) {
-	case *rsa.PrivateKey:
-		signature, err = rsa.SignPKCS1v15(rand, priv, hashFunc, digest)
-	case *ecdsa.PrivateKey:
-		var r, s *big.Int
-		if r, s, err = ecdsa.Sign(rand, priv, digest); err == nil {
-			signature, err = asn1.Marshal(ecdsaSignature{r, s})
-		}
-	default:
-		panic("internal error")
-	}
-
-	if err != nil {
-		return
-	}
-
-	return asn1.Marshal(certificateRequest{
-		TBSCSR:             tbsCSR,
-		SignatureAlgorithm: sigAlgo,
-		SignatureValue: asn1.BitString{
-			Bytes:     signature,
-			BitLength: len(signature) * 8,
-		},
-	})
-}
-
-// ParseCertificateRequest parses a single certificate request from the
-// given ASN.1 DER data.
-func ParseCertificateRequest(asn1Data []byte) (*CertificateRequest, error) {
-	var csr certificateRequest
-
-	rest, err := asn1.Unmarshal(asn1Data, &csr)
-	if err != nil {
-		return nil, err
-	} else if len(rest) != 0 {
-		return nil, asn1.SyntaxError{Msg: "trailing data"}
-	}
-
-	return parseCertificateRequest(&csr)
-}
-
-func parseCertificateRequest(in *certificateRequest) (*CertificateRequest, error) {
-	out := &CertificateRequest{
-		Raw: in.Raw,
-		RawTBSCertificateRequest: in.TBSCSR.Raw,
-		RawSubjectPublicKeyInfo:  in.TBSCSR.PublicKey.Raw,
-		RawSubject:               in.TBSCSR.Subject.FullBytes,
-
-		Signature:          in.SignatureValue.RightAlign(),
-		SignatureAlgorithm: getSignatureAlgorithmFromOID(in.SignatureAlgorithm.Algorithm),
-
-		PublicKeyAlgorithm: getPublicKeyAlgorithmFromOID(in.TBSCSR.PublicKey.Algorithm.Algorithm),
-
-		Version:    in.TBSCSR.Version,
-		Attributes: in.TBSCSR.Attributes,
-	}
-
-	var err error
-	out.PublicKey, err = parsePublicKey(out.PublicKeyAlgorithm, &in.TBSCSR.PublicKey)
-	if err != nil {
-		return nil, err
-	}
-
-	var subject pkix.RDNSequence
-	if _, err := asn1.Unmarshal(in.TBSCSR.Subject.FullBytes, &subject); err != nil {
-		return nil, err
-	}
-
-	out.Subject.FillFromRDNSequence(&subject)
-
-	var extensions []pkix.AttributeTypeAndValue
-
-	for _, atvSet := range in.TBSCSR.Attributes {
-		if !atvSet.Type.Equal(oidExtensionRequest) {
-			continue
-		}
-
-		for _, atvs := range atvSet.Value {
-			extensions = append(extensions, atvs...)
-		}
-	}
-
-	out.Extensions = make([]pkix.Extension, 0, len(extensions))
-
-	for _, e := range extensions {
-		value, ok := e.Value.([]byte)
-		if !ok {
-			return nil, errors.New("x509: extension attribute contained non-OCTET STRING data")
-		}
-
-		out.Extensions = append(out.Extensions, pkix.Extension{
-			Id:    e.Type,
-			Value: value,
-		})
-
-		if len(e.Type) == 4 && e.Type[0] == 2 && e.Type[1] == 5 && e.Type[2] == 29 {
-			switch e.Type[3] {
-			case 17:
-				out.DNSNames, out.EmailAddresses, out.IPAddresses, err = parseSANExtension(value)
-				if err != nil {
-					return nil, err
-				}
-			}
-		}
-	}
-
-	return out, nil
-}
diff --git a/src/pkg/crypto/x509/x509_test.go b/src/pkg/crypto/x509/x509_test.go
deleted file mode 100644
index 2fd54c7..0000000
--- a/src/pkg/crypto/x509/x509_test.go
+++ /dev/null
@@ -1,952 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package x509
-
-import (
-	"bytes"
-	"crypto/dsa"
-	"crypto/ecdsa"
-	"crypto/elliptic"
-	"crypto/rand"
-	"crypto/rsa"
-	_ "crypto/sha256"
-	_ "crypto/sha512"
-	"crypto/x509/pkix"
-	"encoding/asn1"
-	"encoding/base64"
-	"encoding/hex"
-	"encoding/pem"
-	"math/big"
-	"net"
-	"os/exec"
-	"reflect"
-	"runtime"
-	"testing"
-	"time"
-)
-
-func TestParsePKCS1PrivateKey(t *testing.T) {
-	block, _ := pem.Decode([]byte(pemPrivateKey))
-	priv, err := ParsePKCS1PrivateKey(block.Bytes)
-	if err != nil {
-		t.Errorf("Failed to parse private key: %s", err)
-		return
-	}
-	if priv.PublicKey.N.Cmp(rsaPrivateKey.PublicKey.N) != 0 ||
-		priv.PublicKey.E != rsaPrivateKey.PublicKey.E ||
-		priv.D.Cmp(rsaPrivateKey.D) != 0 ||
-		priv.Primes[0].Cmp(rsaPrivateKey.Primes[0]) != 0 ||
-		priv.Primes[1].Cmp(rsaPrivateKey.Primes[1]) != 0 {
-		t.Errorf("got:%+v want:%+v", priv, rsaPrivateKey)
-	}
-}
-
-func TestParsePKIXPublicKey(t *testing.T) {
-	block, _ := pem.Decode([]byte(pemPublicKey))
-	pub, err := ParsePKIXPublicKey(block.Bytes)
-	if err != nil {
-		t.Errorf("Failed to parse RSA public key: %s", err)
-		return
-	}
-	rsaPub, ok := pub.(*rsa.PublicKey)
-	if !ok {
-		t.Errorf("Value returned from ParsePKIXPublicKey was not an RSA public key")
-		return
-	}
-
-	pubBytes2, err := MarshalPKIXPublicKey(rsaPub)
-	if err != nil {
-		t.Errorf("Failed to marshal RSA public key for the second time: %s", err)
-		return
-	}
-	if !bytes.Equal(pubBytes2, block.Bytes) {
-		t.Errorf("Reserialization of public key didn't match. got %x, want %x", pubBytes2, block.Bytes)
-	}
-}
-
-var pemPublicKey = `-----BEGIN PUBLIC KEY-----
-MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3VoPN9PKUjKFLMwOge6+
-wnDi8sbETGIx2FKXGgqtAKpzmem53kRGEQg8WeqRmp12wgp74TGpkEXsGae7RS1k
-enJCnma4fii+noGH7R0qKgHvPrI2Bwa9hzsH8tHxpyM3qrXslOmD45EH9SxIDUBJ
-FehNdaPbLP1gFyahKMsdfxFJLUvbUycuZSJ2ZnIgeVxwm4qbSvZInL9Iu4FzuPtg
-fINKcbbovy1qq4KvPIrXzhbY3PWDc6btxCf3SE0JdE1MCPThntB62/bLMSQ7xdDR
-FF53oIpvxe/SCOymfWq/LW849Ytv3Xwod0+wzAP8STXG4HSELS4UedPYeHJJJYcZ
-+QIDAQAB
------END PUBLIC KEY-----
-`
-
-var pemPrivateKey = `-----BEGIN RSA PRIVATE KEY-----
-MIIBOgIBAAJBALKZD0nEffqM1ACuak0bijtqE2QrI/KLADv7l3kK3ppMyCuLKoF0
-fd7Ai2KW5ToIwzFofvJcS/STa6HA5gQenRUCAwEAAQJBAIq9amn00aS0h/CrjXqu
-/ThglAXJmZhOMPVn4eiu7/ROixi9sex436MaVeMqSNf7Ex9a8fRNfWss7Sqd9eWu
-RTUCIQDasvGASLqmjeffBNLTXV2A5g4t+kLVCpsEIZAycV5GswIhANEPLmax0ME/
-EO+ZJ79TJKN5yiGBRsv5yvx5UiHxajEXAiAhAol5N4EUyq6I9w1rYdhPMGpLfk7A
-IU2snfRJ6Nq2CQIgFrPsWRCkV+gOYcajD17rEqmuLrdIRexpg8N1DOSXoJ8CIGlS
-tAboUGBxTDq3ZroNism3DaMIbKPyYrAqhKov1h5V
------END RSA PRIVATE KEY-----
-`
-
-func bigFromString(s string) *big.Int {
-	ret := new(big.Int)
-	ret.SetString(s, 10)
-	return ret
-}
-
-func fromBase10(base10 string) *big.Int {
-	i := new(big.Int)
-	i.SetString(base10, 10)
-	return i
-}
-
-func bigFromHexString(s string) *big.Int {
-	ret := new(big.Int)
-	ret.SetString(s, 16)
-	return ret
-}
-
-var rsaPrivateKey = &rsa.PrivateKey{
-	PublicKey: rsa.PublicKey{
-		N: bigFromString("9353930466774385905609975137998169297361893554149986716853295022578535724979677252958524466350471210367835187480748268864277464700638583474144061408845077"),
-		E: 65537,
-	},
-	D: bigFromString("7266398431328116344057699379749222532279343923819063639497049039389899328538543087657733766554155839834519529439851673014800261285757759040931985506583861"),
-	Primes: []*big.Int{
-		bigFromString("98920366548084643601728869055592650835572950932266967461790948584315647051443"),
-		bigFromString("94560208308847015747498523884063394671606671904944666360068158221458669711639"),
-	},
-}
-
-func TestMarshalRSAPrivateKey(t *testing.T) {
-	priv := &rsa.PrivateKey{
-		PublicKey: rsa.PublicKey{
-			N: fromBase10("163463789223821934005382697499360491063202653175117663575997325752773828440517910965693338085989218523515777627185298180728491911224194106120335924014037649250961367599344976877654539058841495051754260530374204866970724486090227536836837180577955668114019388333679546429514334733370663119788211805264396414969732960370000525461085078052692794147890354611580731567721518924522511061735072404889936086508819296291634650994768496431656827090474620105813087195770539057874962969 [...]
-			E: 3,
-		},
-		D: fromBase10("1089758594825479560035884649995736607088017687834117757173315505018492189603452739771288920573261456823438517514568654538189946074827960707468906160093584328339742450662299845851030260392276633678361736868609004276571829091409933444915482937517995836999340772494618624324956892823708621575925990986174864212407187487986129938987423048992827162125929489414284042840719693244447408885774612310497861709885861944567553258778702322885238314955747007780271870542027573973795895379 [...]
-		Primes: []*big.Int{
-			fromBase10("1025363189502892836833747188838978207017355117492483312747347695538428729137306368764177201532277413433182799108299960196606011786562992097313508180436744488171474690412562218914213688661311117337381958560443"),
-			fromBase10("3467903426626310123395340254094941045497208049900750380025518552334536945536837294961497712862519984786362199788654739924501424784631315081391467293694361474867825728031147665777546570788493758372218019373"),
-			fromBase10("4597024781409332673052708605078359346966325141767460991205742124888960305710298765592730135879076084498363772408626791576005136245060321874472727132746643162385746062759369754202494417496879741537284589047"),
-		},
-	}
-
-	derBytes := MarshalPKCS1PrivateKey(priv)
-
-	priv2, err := ParsePKCS1PrivateKey(derBytes)
-	if err != nil {
-		t.Errorf("error parsing serialized key: %s", err)
-		return
-	}
-	if priv.PublicKey.N.Cmp(priv2.PublicKey.N) != 0 ||
-		priv.PublicKey.E != priv2.PublicKey.E ||
-		priv.D.Cmp(priv2.D) != 0 ||
-		len(priv2.Primes) != 3 ||
-		priv.Primes[0].Cmp(priv2.Primes[0]) != 0 ||
-		priv.Primes[1].Cmp(priv2.Primes[1]) != 0 ||
-		priv.Primes[2].Cmp(priv2.Primes[2]) != 0 {
-		t.Errorf("got:%+v want:%+v", priv, priv2)
-	}
-}
-
-type matchHostnamesTest struct {
-	pattern, host string
-	ok            bool
-}
-
-var matchHostnamesTests = []matchHostnamesTest{
-	{"a.b.c", "a.b.c", true},
-	{"a.b.c", "b.b.c", false},
-	{"", "b.b.c", false},
-	{"a.b.c", "", false},
-	{"example.com", "example.com", true},
-	{"example.com", "www.example.com", false},
-	{"*.example.com", "www.example.com", true},
-	{"*.example.com", "xyz.www.example.com", false},
-	{"*.*.example.com", "xyz.www.example.com", true},
-	{"*.www.*.com", "xyz.www.example.com", true},
-}
-
-func TestMatchHostnames(t *testing.T) {
-	for i, test := range matchHostnamesTests {
-		r := matchHostnames(test.pattern, test.host)
-		if r != test.ok {
-			t.Errorf("#%d mismatch got: %t want: %t", i, r, test.ok)
-		}
-	}
-}
-
-func TestMatchIP(t *testing.T) {
-	// Check that pattern matching is working.
-	c := &Certificate{
-		DNSNames: []string{"*.foo.bar.baz"},
-		Subject: pkix.Name{
-			CommonName: "*.foo.bar.baz",
-		},
-	}
-	err := c.VerifyHostname("quux.foo.bar.baz")
-	if err != nil {
-		t.Fatalf("VerifyHostname(quux.foo.bar.baz): %v", err)
-	}
-
-	// But check that if we change it to be matching against an IP address,
-	// it is rejected.
-	c = &Certificate{
-		DNSNames: []string{"*.2.3.4"},
-		Subject: pkix.Name{
-			CommonName: "*.2.3.4",
-		},
-	}
-	err = c.VerifyHostname("1.2.3.4")
-	if err == nil {
-		t.Fatalf("VerifyHostname(1.2.3.4) should have failed, did not")
-	}
-
-	c = &Certificate{
-		IPAddresses: []net.IP{net.ParseIP("127.0.0.1"), net.ParseIP("::1")},
-	}
-	err = c.VerifyHostname("127.0.0.1")
-	if err != nil {
-		t.Fatalf("VerifyHostname(127.0.0.1): %v", err)
-	}
-	err = c.VerifyHostname("::1")
-	if err != nil {
-		t.Fatalf("VerifyHostname(::1): %v", err)
-	}
-	err = c.VerifyHostname("[::1]")
-	if err != nil {
-		t.Fatalf("VerifyHostname([::1]): %v", err)
-	}
-}
-
-func TestCertificateParse(t *testing.T) {
-	s, _ := hex.DecodeString(certBytes)
-	certs, err := ParseCertificates(s)
-	if err != nil {
-		t.Error(err)
-	}
-	if len(certs) != 2 {
-		t.Errorf("Wrong number of certs: got %d want 2", len(certs))
-		return
-	}
-
-	err = certs[0].CheckSignatureFrom(certs[1])
-	if err != nil {
-		t.Error(err)
-	}
-
-	if err := certs[0].VerifyHostname("mail.google.com"); err != nil {
-		t.Error(err)
-	}
-
-	const expectedExtensions = 4
-	if n := len(certs[0].Extensions); n != expectedExtensions {
-		t.Errorf("want %d extensions, got %d", expectedExtensions, n)
-	}
-}
-
-var certBytes = "308203223082028ba00302010202106edf0d9499fd4533dd1297fc42a93be1300d06092a864886" +
-	"f70d0101050500304c310b3009060355040613025a4131253023060355040a131c546861777465" +
-	"20436f6e73756c74696e67202850747929204c74642e311630140603550403130d546861777465" +
-	"20534743204341301e170d3039303332353136343932395a170d3130303332353136343932395a" +
-	"3069310b3009060355040613025553311330110603550408130a43616c69666f726e6961311630" +
-	"140603550407130d4d6f756e7461696e205669657731133011060355040a130a476f6f676c6520" +
-	"496e63311830160603550403130f6d61696c2e676f6f676c652e636f6d30819f300d06092a8648" +
-	"86f70d010101050003818d0030818902818100c5d6f892fccaf5614b064149e80a2c9581a218ef" +
-	"41ec35bd7a58125ae76f9ea54ddc893abbeb029f6b73616bf0ffd868791fba7af9c4aebf3706ba" +
-	"3eeaeed27435b4ddcfb157c05f351d66aa87fee0de072d66d773affbd36ab78bef090e0cc861a9" +
-	"03ac90dd98b51c9c41566c017f0beec3bff391051ffba0f5cc6850ad2a590203010001a381e730" +
-	"81e430280603551d250421301f06082b0601050507030106082b06010505070302060960864801" +
-	"86f842040130360603551d1f042f302d302ba029a0278625687474703a2f2f63726c2e74686177" +
-	"74652e636f6d2f54686177746553474343412e63726c307206082b060105050701010466306430" +
-	"2206082b060105050730018616687474703a2f2f6f6373702e7468617774652e636f6d303e0608" +
-	"2b060105050730028632687474703a2f2f7777772e7468617774652e636f6d2f7265706f736974" +
-	"6f72792f5468617774655f5347435f43412e637274300c0603551d130101ff04023000300d0609" +
-	"2a864886f70d01010505000381810062f1f3050ebc105e497c7aedf87e24d2f4a986bb3b837bd1" +
-	"9b91ebcad98b065992f6bd2b49b7d6d3cb2e427a99d606c7b1d46352527fac39e6a8b6726de5bf" +
-	"70212a52cba07634a5e332011bd1868e78eb5e3c93cf03072276786f207494feaa0ed9d53b2110" +
-	"a76571f90209cdae884385c882587030ee15f33d761e2e45a6bc308203233082028ca003020102" +
-	"020430000002300d06092a864886f70d0101050500305f310b3009060355040613025553311730" +
-	"15060355040a130e566572695369676e2c20496e632e31373035060355040b132e436c61737320" +
-	"33205075626c6963205072696d6172792043657274696669636174696f6e20417574686f726974" +
-	"79301e170d3034303531333030303030305a170d3134303531323233353935395a304c310b3009" +
-	"060355040613025a4131253023060355040a131c54686177746520436f6e73756c74696e672028" +
-	"50747929204c74642e311630140603550403130d5468617774652053474320434130819f300d06" +
-	"092a864886f70d010101050003818d0030818902818100d4d367d08d157faecd31fe7d1d91a13f" +
-	"0b713cacccc864fb63fc324b0794bd6f80ba2fe10493c033fc093323e90b742b71c403c6d2cde2" +
-	"2ff50963cdff48a500bfe0e7f388b72d32de9836e60aad007bc4644a3b847503f270927d0e62f5" +
-	"21ab693684317590f8bfc76c881b06957cc9e5a8de75a12c7a68dfd5ca1c875860190203010001" +
-	"a381fe3081fb30120603551d130101ff040830060101ff020100300b0603551d0f040403020106" +
-	"301106096086480186f842010104040302010630280603551d110421301fa41d301b3119301706" +
-	"035504031310507269766174654c6162656c332d313530310603551d1f042a30283026a024a022" +
-	"8620687474703a2f2f63726c2e766572697369676e2e636f6d2f706361332e63726c303206082b" +
-	"0601050507010104263024302206082b060105050730018616687474703a2f2f6f6373702e7468" +
-	"617774652e636f6d30340603551d25042d302b06082b0601050507030106082b06010505070302" +
-	"06096086480186f8420401060a6086480186f845010801300d06092a864886f70d010105050003" +
-	"81810055ac63eadea1ddd2905f9f0bce76be13518f93d9052bc81b774bad6950a1eededcfddb07" +
-	"e9e83994dcab72792f06bfab8170c4a8edea5334edef1e53d906c7562bd15cf4d18a8eb42bb137" +
-	"9048084225c53e8acb7feb6f04d16dc574a2f7a27c7b603c77cd0ece48027f012fb69b37e02a2a" +
-	"36dcd585d6ace53f546f961e05af"
-
-func TestCreateSelfSignedCertificate(t *testing.T) {
-	random := rand.Reader
-
-	block, _ := pem.Decode([]byte(pemPrivateKey))
-	rsaPriv, err := ParsePKCS1PrivateKey(block.Bytes)
-	if err != nil {
-		t.Fatalf("Failed to parse private key: %s", err)
-	}
-
-	ecdsaPriv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
-	if err != nil {
-		t.Fatalf("Failed to generate ECDSA key: %s", err)
-	}
-
-	tests := []struct {
-		name      string
-		pub, priv interface{}
-		checkSig  bool
-		sigAlgo   SignatureAlgorithm
-	}{
-		{"RSA/RSA", &rsaPriv.PublicKey, rsaPriv, true, SHA1WithRSA},
-		{"RSA/ECDSA", &rsaPriv.PublicKey, ecdsaPriv, false, ECDSAWithSHA384},
-		{"ECDSA/RSA", &ecdsaPriv.PublicKey, rsaPriv, false, SHA256WithRSA},
-		{"ECDSA/ECDSA", &ecdsaPriv.PublicKey, ecdsaPriv, true, ECDSAWithSHA1},
-	}
-
-	testExtKeyUsage := []ExtKeyUsage{ExtKeyUsageClientAuth, ExtKeyUsageServerAuth}
-	testUnknownExtKeyUsage := []asn1.ObjectIdentifier{[]int{1, 2, 3}, []int{2, 59, 1}}
-	extraExtensionData := []byte("extra extension")
-
-	for _, test := range tests {
-		commonName := "test.example.com"
-		template := Certificate{
-			SerialNumber: big.NewInt(1),
-			Subject: pkix.Name{
-				CommonName:   commonName,
-				Organization: []string{"Σ Acme Co"},
-			},
-			NotBefore: time.Unix(1000, 0),
-			NotAfter:  time.Unix(100000, 0),
-
-			SignatureAlgorithm: test.sigAlgo,
-
-			SubjectKeyId: []byte{1, 2, 3, 4},
-			KeyUsage:     KeyUsageCertSign,
-
-			ExtKeyUsage:        testExtKeyUsage,
-			UnknownExtKeyUsage: testUnknownExtKeyUsage,
-
-			BasicConstraintsValid: true,
-			IsCA: true,
-
-			OCSPServer:            []string{"http://ocsp.example.com"},
-			IssuingCertificateURL: []string{"http://crt.example.com/ca1.crt"},
-
-			DNSNames:       []string{"test.example.com"},
-			EmailAddresses: []string{"gopher at golang.org"},
-			IPAddresses:    []net.IP{net.IPv4(127, 0, 0, 1).To4(), net.ParseIP("2001:4860:0:2001::68")},
-
-			PolicyIdentifiers:   []asn1.ObjectIdentifier{[]int{1, 2, 3}},
-			PermittedDNSDomains: []string{".example.com", "example.com"},
-
-			CRLDistributionPoints: []string{"http://crl1.example.com/ca1.crl", "http://crl2.example.com/ca1.crl"},
-
-			ExtraExtensions: []pkix.Extension{
-				{
-					Id:    []int{1, 2, 3, 4},
-					Value: extraExtensionData,
-				},
-				// This extension should override the SubjectKeyId, above.
-				{
-					Id:       oidExtensionSubjectKeyId,
-					Critical: false,
-					Value:    []byte{0x04, 0x04, 4, 3, 2, 1},
-				},
-			},
-		}
-
-		derBytes, err := CreateCertificate(random, &template, &template, test.pub, test.priv)
-		if err != nil {
-			t.Errorf("%s: failed to create certificate: %s", test.name, err)
-			continue
-		}
-
-		cert, err := ParseCertificate(derBytes)
-		if err != nil {
-			t.Errorf("%s: failed to parse certificate: %s", test.name, err)
-			continue
-		}
-
-		if len(cert.PolicyIdentifiers) != 1 || !cert.PolicyIdentifiers[0].Equal(template.PolicyIdentifiers[0]) {
-			t.Errorf("%s: failed to parse policy identifiers: got:%#v want:%#v", test.name, cert.PolicyIdentifiers, template.PolicyIdentifiers)
-		}
-
-		if len(cert.PermittedDNSDomains) != 2 || cert.PermittedDNSDomains[0] != ".example.com" || cert.PermittedDNSDomains[1] != "example.com" {
-			t.Errorf("%s: failed to parse name constraints: %#v", test.name, cert.PermittedDNSDomains)
-		}
-
-		if cert.Subject.CommonName != commonName {
-			t.Errorf("%s: subject wasn't correctly copied from the template. Got %s, want %s", test.name, cert.Subject.CommonName, commonName)
-		}
-
-		if cert.Issuer.CommonName != commonName {
-			t.Errorf("%s: issuer wasn't correctly copied from the template. Got %s, want %s", test.name, cert.Issuer.CommonName, commonName)
-		}
-
-		if cert.SignatureAlgorithm != test.sigAlgo {
-			t.Errorf("%s: SignatureAlgorithm wasn't copied from template. Got %v, want %v", test.name, cert.SignatureAlgorithm, test.sigAlgo)
-		}
-
-		if !reflect.DeepEqual(cert.ExtKeyUsage, testExtKeyUsage) {
-			t.Errorf("%s: extkeyusage wasn't correctly copied from the template. Got %v, want %v", test.name, cert.ExtKeyUsage, testExtKeyUsage)
-		}
-
-		if !reflect.DeepEqual(cert.UnknownExtKeyUsage, testUnknownExtKeyUsage) {
-			t.Errorf("%s: unknown extkeyusage wasn't correctly copied from the template. Got %v, want %v", test.name, cert.UnknownExtKeyUsage, testUnknownExtKeyUsage)
-		}
-
-		if !reflect.DeepEqual(cert.OCSPServer, template.OCSPServer) {
-			t.Errorf("%s: OCSP servers differ from template. Got %v, want %v", test.name, cert.OCSPServer, template.OCSPServer)
-		}
-
-		if !reflect.DeepEqual(cert.IssuingCertificateURL, template.IssuingCertificateURL) {
-			t.Errorf("%s: Issuing certificate URLs differ from template. Got %v, want %v", test.name, cert.IssuingCertificateURL, template.IssuingCertificateURL)
-		}
-
-		if !reflect.DeepEqual(cert.DNSNames, template.DNSNames) {
-			t.Errorf("%s: SAN DNS names differ from template. Got %v, want %v", test.name, cert.DNSNames, template.DNSNames)
-		}
-
-		if !reflect.DeepEqual(cert.EmailAddresses, template.EmailAddresses) {
-			t.Errorf("%s: SAN emails differ from template. Got %v, want %v", test.name, cert.EmailAddresses, template.EmailAddresses)
-		}
-
-		if !reflect.DeepEqual(cert.IPAddresses, template.IPAddresses) {
-			t.Errorf("%s: SAN IPs differ from template. Got %v, want %v", test.name, cert.IPAddresses, template.IPAddresses)
-		}
-
-		if !reflect.DeepEqual(cert.CRLDistributionPoints, template.CRLDistributionPoints) {
-			t.Errorf("%s: CRL distribution points differ from template. Got %v, want %v", test.name, cert.CRLDistributionPoints, template.CRLDistributionPoints)
-		}
-
-		if !bytes.Equal(cert.SubjectKeyId, []byte{4, 3, 2, 1}) {
-			t.Errorf("%s: ExtraExtensions didn't override SubjectKeyId", test.name)
-		}
-
-		if bytes.Index(derBytes, extraExtensionData) == -1 {
-			t.Errorf("%s: didn't find extra extension in DER output", test.name)
-		}
-
-		if test.checkSig {
-			err = cert.CheckSignatureFrom(cert)
-			if err != nil {
-				t.Errorf("%s: signature verification failed: %s", test.name, err)
-			}
-		}
-	}
-}
-
-// Self-signed certificate using ECDSA with SHA1 & secp256r1
-var ecdsaSHA1CertPem = `
------BEGIN CERTIFICATE-----
-MIICDjCCAbUCCQDF6SfN0nsnrjAJBgcqhkjOPQQBMIGPMQswCQYDVQQGEwJVUzET
-MBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEVMBMG
-A1UECgwMR29vZ2xlLCBJbmMuMRcwFQYDVQQDDA53d3cuZ29vZ2xlLmNvbTEjMCEG
-CSqGSIb3DQEJARYUZ29sYW5nLWRldkBnbWFpbC5jb20wHhcNMTIwNTIwMjAyMDUw
-WhcNMjIwNTE4MjAyMDUwWjCBjzELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlm
-b3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxFTATBgNVBAoMDEdvb2dsZSwg
-SW5jLjEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20xIzAhBgkqhkiG9w0BCQEWFGdv
-bGFuZy1kZXZAZ21haWwuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE/Wgn
-WQDo5+bz71T0327ERgd5SDDXFbXLpzIZDXTkjpe8QTEbsF+ezsQfrekrpDPC4Cd3
-P9LY0tG+aI8IyVKdUjAJBgcqhkjOPQQBA0gAMEUCIGlsqMcRqWVIWTD6wXwe6Jk2
-DKxL46r/FLgJYnzBEH99AiEA3fBouObsvV1R3oVkb4BQYnD4/4LeId6lAT43YvyV
-a/A=
------END CERTIFICATE-----
-`
-
-// Self-signed certificate using ECDSA with SHA256 & secp256r1
-var ecdsaSHA256p256CertPem = `
------BEGIN CERTIFICATE-----
-MIICDzCCAbYCCQDlsuMWvgQzhTAKBggqhkjOPQQDAjCBjzELMAkGA1UEBhMCVVMx
-EzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxFTAT
-BgNVBAoMDEdvb2dsZSwgSW5jLjEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20xIzAh
-BgkqhkiG9w0BCQEWFGdvbGFuZy1kZXZAZ21haWwuY29tMB4XDTEyMDUyMTAwMTkx
-NloXDTIyMDUxOTAwMTkxNlowgY8xCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxp
-Zm9ybmlhMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MRUwEwYDVQQKDAxHb29nbGUs
-IEluYy4xFzAVBgNVBAMMDnd3dy5nb29nbGUuY29tMSMwIQYJKoZIhvcNAQkBFhRn
-b2xhbmctZGV2QGdtYWlsLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABPMt
-2ErhxAty5EJRu9yM+MTy+hUXm3pdW1ensAv382KoGExSXAFWP7pjJnNtHO+XSwVm
-YNtqjcAGFKpweoN//kQwCgYIKoZIzj0EAwIDRwAwRAIgIYSaUA/IB81gjbIw/hUV
-70twxJr5EcgOo0hLp3Jm+EYCIFDO3NNcgmURbJ1kfoS3N/0O+irUtoPw38YoNkqJ
-h5wi
------END CERTIFICATE-----
-`
-
-// Self-signed certificate using ECDSA with SHA256 & secp384r1
-var ecdsaSHA256p384CertPem = `
------BEGIN CERTIFICATE-----
-MIICSjCCAdECCQDje/no7mXkVzAKBggqhkjOPQQDAjCBjjELMAkGA1UEBhMCVVMx
-EzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxFDAS
-BgNVBAoMC0dvb2dsZSwgSW5jMRcwFQYDVQQDDA53d3cuZ29vZ2xlLmNvbTEjMCEG
-CSqGSIb3DQEJARYUZ29sYW5nLWRldkBnbWFpbC5jb20wHhcNMTIwNTIxMDYxMDM0
-WhcNMjIwNTE5MDYxMDM0WjCBjjELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlm
-b3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxFDASBgNVBAoMC0dvb2dsZSwg
-SW5jMRcwFQYDVQQDDA53d3cuZ29vZ2xlLmNvbTEjMCEGCSqGSIb3DQEJARYUZ29s
-YW5nLWRldkBnbWFpbC5jb20wdjAQBgcqhkjOPQIBBgUrgQQAIgNiAARRuzRNIKRK
-jIktEmXanNmrTR/q/FaHXLhWRZ6nHWe26Fw7Rsrbk+VjGy4vfWtNn7xSFKrOu5ze
-qxKnmE0h5E480MNgrUiRkaGO2GMJJVmxx20aqkXOk59U8yGA4CghE6MwCgYIKoZI
-zj0EAwIDZwAwZAIwBZEN8gvmRmfeP/9C1PRLzODIY4JqWub2PLRT4mv9GU+yw3Gr
-PU9A3CHMdEcdw/MEAjBBO1lId8KOCh9UZunsSMfqXiVurpzmhWd6VYZ/32G+M+Mh
-3yILeYQzllt/g0rKVRk=
------END CERTIFICATE-----
-`
-
-// Self-signed certificate using ECDSA with SHA384 & secp521r1
-var ecdsaSHA384p521CertPem = `
------BEGIN CERTIFICATE-----
-MIICljCCAfcCCQDhp1AFD/ahKjAKBggqhkjOPQQDAzCBjjELMAkGA1UEBhMCVVMx
-EzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxFDAS
-BgNVBAoMC0dvb2dsZSwgSW5jMRcwFQYDVQQDDA53d3cuZ29vZ2xlLmNvbTEjMCEG
-CSqGSIb3DQEJARYUZ29sYW5nLWRldkBnbWFpbC5jb20wHhcNMTIwNTIxMTUwNDI5
-WhcNMjIwNTE5MTUwNDI5WjCBjjELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlm
-b3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxFDASBgNVBAoMC0dvb2dsZSwg
-SW5jMRcwFQYDVQQDDA53d3cuZ29vZ2xlLmNvbTEjMCEGCSqGSIb3DQEJARYUZ29s
-YW5nLWRldkBnbWFpbC5jb20wgZswEAYHKoZIzj0CAQYFK4EEACMDgYYABACqx9Rv
-IssRs1LWYcNN+WffwlHw4Tv3y8/LIAA9MF1ZScIonU9nRMxt4a2uGJVCPDw6JHpz
-PaYc0E9puLoE9AfKpwFr59Jkot7dBg55SKPEFkddoip/rvmN7NPAWjMBirOwjOkm
-8FPthvPhGPqsu9AvgVuHu3PosWiHGNrhh379pva8MzAKBggqhkjOPQQDAwOBjAAw
-gYgCQgEHNmswkUdPpHqrVxp9PvLVl+xxPuHBkT+75z9JizyxtqykHQo9Uh6SWCYH
-BF9KLolo01wMt8DjoYP5Fb3j5MH7xwJCAbWZzTOp4l4DPkIvAh4LeC4VWbwPPyqh
-kBg71w/iEcSY3wUKgHGcJJrObZw7wys91I5kENljqw/Samdr3ka+jBJa
------END CERTIFICATE-----
-`
-
-var ecdsaTests = []struct {
-	sigAlgo SignatureAlgorithm
-	pemCert string
-}{
-	{ECDSAWithSHA1, ecdsaSHA1CertPem},
-	{ECDSAWithSHA256, ecdsaSHA256p256CertPem},
-	{ECDSAWithSHA256, ecdsaSHA256p384CertPem},
-	{ECDSAWithSHA384, ecdsaSHA384p521CertPem},
-}
-
-func TestECDSA(t *testing.T) {
-	for i, test := range ecdsaTests {
-		pemBlock, _ := pem.Decode([]byte(test.pemCert))
-		cert, err := ParseCertificate(pemBlock.Bytes)
-		if err != nil {
-			t.Errorf("%d: failed to parse certificate: %s", i, err)
-			continue
-		}
-		if sa := cert.SignatureAlgorithm; sa != test.sigAlgo {
-			t.Errorf("%d: signature algorithm is %v, want %v", i, sa, test.sigAlgo)
-		}
-		if parsedKey, ok := cert.PublicKey.(*ecdsa.PublicKey); !ok {
-			t.Errorf("%d: wanted an ECDSA public key but found: %#v", i, parsedKey)
-		}
-		if pka := cert.PublicKeyAlgorithm; pka != ECDSA {
-			t.Errorf("%d: public key algorithm is %v, want ECDSA", i, pka)
-		}
-		if err = cert.CheckSignatureFrom(cert); err != nil {
-			t.Errorf("%d: certificate verification failed: %s", i, err)
-		}
-	}
-}
-
-// Self-signed certificate using DSA with SHA1
-var dsaCertPem = `-----BEGIN CERTIFICATE-----
-MIIEDTCCA82gAwIBAgIJALHPghaoxeDhMAkGByqGSM44BAMweTELMAkGA1UEBhMC
-VVMxCzAJBgNVBAgTAk5DMQ8wDQYDVQQHEwZOZXd0b24xFDASBgNVBAoTC0dvb2ds
-ZSwgSW5jMRIwEAYDVQQDEwlKb24gQWxsaWUxIjAgBgkqhkiG9w0BCQEWE2pvbmFs
-bGllQGdvb2dsZS5jb20wHhcNMTEwNTE0MDMwMTQ1WhcNMTEwNjEzMDMwMTQ1WjB5
-MQswCQYDVQQGEwJVUzELMAkGA1UECBMCTkMxDzANBgNVBAcTBk5ld3RvbjEUMBIG
-A1UEChMLR29vZ2xlLCBJbmMxEjAQBgNVBAMTCUpvbiBBbGxpZTEiMCAGCSqGSIb3
-DQEJARYTam9uYWxsaWVAZ29vZ2xlLmNvbTCCAbcwggEsBgcqhkjOOAQBMIIBHwKB
-gQC8hLUnQ7FpFYu4WXTj6DKvXvz8QrJkNJCVMTpKAT7uBpobk32S5RrPKXocd4gN
-8lyGB9ggS03EVlEwXvSmO0DH2MQtke2jl9j1HLydClMf4sbx5V6TV9IFw505U1iW
-jL7awRMgxge+FsudtJK254FjMFo03ZnOQ8ZJJ9E6AEDrlwIVAJpnBn9moyP11Ox5
-Asc/5dnjb6dPAoGBAJFHd4KVv1iTVCvEG6gGiYop5DJh28hUQcN9kul+2A0yPUSC
-X93oN00P8Vh3eYgSaCWZsha7zDG53MrVJ0Zf6v/X/CoZNhLldeNOepivTRAzn+Rz
-kKUYy5l1sxYLHQKF0UGNCXfFKZT0PCmgU+PWhYNBBMn6/cIh44vp85ideo5CA4GE
-AAKBgFmifCafzeRaohYKXJgMGSEaggCVCRq5xdyDCat+wbOkjC4mfG01/um3G8u5
-LxasjlWRKTR/tcAL7t0QuokVyQaYdVypZXNaMtx1db7YBuHjj3aP+8JOQRI9xz8c
-bp5NDJ5pISiFOv4p3GZfqZPcqckDt78AtkQrmnal2txhhjF6o4HeMIHbMB0GA1Ud
-DgQWBBQVyyr7hO11ZFFpWX50298Sa3V+rzCBqwYDVR0jBIGjMIGggBQVyyr7hO11
-ZFFpWX50298Sa3V+r6F9pHsweTELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAk5DMQ8w
-DQYDVQQHEwZOZXd0b24xFDASBgNVBAoTC0dvb2dsZSwgSW5jMRIwEAYDVQQDEwlK
-b24gQWxsaWUxIjAgBgkqhkiG9w0BCQEWE2pvbmFsbGllQGdvb2dsZS5jb22CCQCx
-z4IWqMXg4TAMBgNVHRMEBTADAQH/MAkGByqGSM44BAMDLwAwLAIUPtn/5j8Q1jJI
-7ggOIsgrhgUdjGQCFCsmDq1H11q9+9Wp9IMeGrTSKHIM
------END CERTIFICATE-----
-`
-
-func TestParseCertificateWithDsaPublicKey(t *testing.T) {
-	expectedKey := &dsa.PublicKey{
-		Parameters: dsa.Parameters{
-			P: bigFromHexString("00BC84B52743B169158BB85974E3E832AF5EFCFC42B264349095313A4A013EEE069A1B937D92E51ACF297A1C77880DF25C8607D8204B4DC45651305EF4A63B40C7D8C42D91EDA397D8F51CBC9D0A531FE2C6F1E55E9357D205C39D395358968CBEDAC11320C607BE16CB9DB492B6E78163305A34DD99CE43C64927D13A0040EB97"),
-			Q: bigFromHexString("009A67067F66A323F5D4EC7902C73FE5D9E36FA74F"),
-			G: bigFromHexString("009147778295BF5893542BC41BA806898A29E43261DBC85441C37D92E97ED80D323D44825FDDE8374D0FF15877798812682599B216BBCC31B9DCCAD527465FEAFFD7FC2A193612E575E34E7A98AF4D10339FE47390A518CB9975B3160B1D0285D1418D0977C52994F43C29A053E3D685834104C9FAFDC221E38BE9F3989D7A8E42"),
-		},
-		Y: bigFromHexString("59A27C269FCDE45AA2160A5C980C19211A820095091AB9C5DC8309AB7EC1B3A48C2E267C6D35FEE9B71BCBB92F16AC8E559129347FB5C00BEEDD10BA8915C90698755CA965735A32DC7575BED806E1E38F768FFBC24E41123DC73F1C6E9E4D0C9E692128853AFE29DC665FA993DCA9C903B7BF00B6442B9A76A5DADC6186317A"),
-	}
-	pemBlock, _ := pem.Decode([]byte(dsaCertPem))
-	cert, err := ParseCertificate(pemBlock.Bytes)
-	if err != nil {
-		t.Fatalf("Failed to parse certificate: %s", err)
-	}
-	if cert.PublicKeyAlgorithm != DSA {
-		t.Errorf("Parsed key algorithm was not DSA")
-	}
-	parsedKey, ok := cert.PublicKey.(*dsa.PublicKey)
-	if !ok {
-		t.Fatalf("Parsed key was not a DSA key: %s", err)
-	}
-	if expectedKey.Y.Cmp(parsedKey.Y) != 0 ||
-		expectedKey.P.Cmp(parsedKey.P) != 0 ||
-		expectedKey.Q.Cmp(parsedKey.Q) != 0 ||
-		expectedKey.G.Cmp(parsedKey.G) != 0 {
-		t.Fatal("Parsed key differs from expected key")
-	}
-}
-
-func TestParseCertificateWithDSASignatureAlgorithm(t *testing.T) {
-	pemBlock, _ := pem.Decode([]byte(dsaCertPem))
-	cert, err := ParseCertificate(pemBlock.Bytes)
-	if err != nil {
-		t.Fatalf("Failed to parse certificate: %s", err)
-	}
-	if cert.SignatureAlgorithm != DSAWithSHA1 {
-		t.Errorf("Parsed signature algorithm was not DSAWithSHA1")
-	}
-}
-
-func TestVerifyCertificateWithDSASignature(t *testing.T) {
-	pemBlock, _ := pem.Decode([]byte(dsaCertPem))
-	cert, err := ParseCertificate(pemBlock.Bytes)
-	if err != nil {
-		t.Fatalf("Failed to parse certificate: %s", err)
-	}
-	// test cert is self-signed
-	if err = cert.CheckSignatureFrom(cert); err != nil {
-		t.Fatalf("DSA Certificate verification failed: %s", err)
-	}
-}
-
-const pemCertificate = `-----BEGIN CERTIFICATE-----
-MIIB5DCCAZCgAwIBAgIBATALBgkqhkiG9w0BAQUwLTEQMA4GA1UEChMHQWNtZSBDbzEZMBcGA1UE
-AxMQdGVzdC5leGFtcGxlLmNvbTAeFw03MDAxMDEwMDE2NDBaFw03MDAxMDIwMzQ2NDBaMC0xEDAO
-BgNVBAoTB0FjbWUgQ28xGTAXBgNVBAMTEHRlc3QuZXhhbXBsZS5jb20wWjALBgkqhkiG9w0BAQED
-SwAwSAJBALKZD0nEffqM1ACuak0bijtqE2QrI/KLADv7l3kK3ppMyCuLKoF0fd7Ai2KW5ToIwzFo
-fvJcS/STa6HA5gQenRUCAwEAAaOBnjCBmzAOBgNVHQ8BAf8EBAMCAAQwDwYDVR0TAQH/BAUwAwEB
-/zANBgNVHQ4EBgQEAQIDBDAPBgNVHSMECDAGgAQBAgMEMBsGA1UdEQQUMBKCEHRlc3QuZXhhbXBs
-ZS5jb20wDwYDVR0gBAgwBjAEBgIqAzAqBgNVHR4EIzAhoB8wDoIMLmV4YW1wbGUuY29tMA2CC2V4
-YW1wbGUuY29tMAsGCSqGSIb3DQEBBQNBAHKZKoS1wEQOGhgklx4+/yFYQlnqwKXvar/ZecQvJwui
-0seMQnwBhwdBkHfVIU2Fu5VUMRyxlf0ZNaDXcpU581k=
------END CERTIFICATE-----`
-
-func TestCRLCreation(t *testing.T) {
-	block, _ := pem.Decode([]byte(pemPrivateKey))
-	priv, _ := ParsePKCS1PrivateKey(block.Bytes)
-	block, _ = pem.Decode([]byte(pemCertificate))
-	cert, _ := ParseCertificate(block.Bytes)
-
-	now := time.Unix(1000, 0)
-	expiry := time.Unix(10000, 0)
-
-	revokedCerts := []pkix.RevokedCertificate{
-		{
-			SerialNumber:   big.NewInt(1),
-			RevocationTime: now,
-		},
-		{
-			SerialNumber:   big.NewInt(42),
-			RevocationTime: now,
-		},
-	}
-
-	crlBytes, err := cert.CreateCRL(rand.Reader, priv, revokedCerts, now, expiry)
-	if err != nil {
-		t.Errorf("error creating CRL: %s", err)
-	}
-
-	_, err = ParseDERCRL(crlBytes)
-	if err != nil {
-		t.Errorf("error reparsing CRL: %s", err)
-	}
-}
-
-func fromBase64(in string) []byte {
-	out := make([]byte, base64.StdEncoding.DecodedLen(len(in)))
-	n, err := base64.StdEncoding.Decode(out, []byte(in))
-	if err != nil {
-		panic("failed to base64 decode")
-	}
-	return out[:n]
-}
-
-func TestParseDERCRL(t *testing.T) {
-	derBytes := fromBase64(derCRLBase64)
-	certList, err := ParseDERCRL(derBytes)
-	if err != nil {
-		t.Errorf("error parsing: %s", err)
-		return
-	}
-	numCerts := len(certList.TBSCertList.RevokedCertificates)
-	expected := 88
-	if numCerts != expected {
-		t.Errorf("bad number of revoked certificates. got: %d want: %d", numCerts, expected)
-	}
-
-	if certList.HasExpired(time.Unix(1302517272, 0)) {
-		t.Errorf("CRL has expired (but shouldn't have)")
-	}
-
-	// Can't check the signature here without a package cycle.
-}
-
-func TestParsePEMCRL(t *testing.T) {
-	pemBytes := fromBase64(pemCRLBase64)
-	certList, err := ParseCRL(pemBytes)
-	if err != nil {
-		t.Errorf("error parsing: %s", err)
-		return
-	}
-	numCerts := len(certList.TBSCertList.RevokedCertificates)
-	expected := 2
-	if numCerts != expected {
-		t.Errorf("bad number of revoked certificates. got: %d want: %d", numCerts, expected)
-	}
-
-	if certList.HasExpired(time.Unix(1302517272, 0)) {
-		t.Errorf("CRL has expired (but shouldn't have)")
-	}
-
-	// Can't check the signature here without a package cycle.
-}
-
-func TestImports(t *testing.T) {
-	if runtime.GOOS == "nacl" {
-		t.Skip("skipping on nacl")
-	}
-
-	if err := exec.Command("go", "run", "x509_test_import.go").Run(); err != nil {
-		t.Errorf("failed to run x509_test_import.go: %s", err)
-	}
-}
-
-const derCRLBase64 = "MIINqzCCDJMCAQEwDQYJKoZIhvcNAQEFBQAwVjEZMBcGA1UEAxMQUEtJIEZJTk1FQ0NBTklDQTEVMBMGA1UEChMMRklOTUVDQ0FOSUNBMRUwEwYDVQQLEwxGSU5NRUNDQU5JQ0ExCzAJBgNVBAYTAklUFw0xMTA1MDQxNjU3NDJaFw0xMTA1MDQyMDU3NDJaMIIMBzAhAg4Ze1od49Lt1qIXBydAzhcNMDkwNzE2MDg0MzIyWjAAMCECDl0HSL9bcZ1Ci/UHJ0DPFw0wOTA3MTYwODQzMTNaMAAwIQIOESB9tVAmX3cY7QcnQNAXDTA5MDcxNjA4NDUyMlowADAhAg4S1tGAQ3mHt8uVBydA1RcNMDkwODA0MTUyNTIyWjAAMCECDlQ249Y7vtC25ScHJ0DWFw0wOTA4MDQxNTI1MzdaMAAwIQIOISMop3NkA4PfYwcnQNkXDTA5MDgwNDExMD [...]
-
-const pemCRLBase64 = "LS0tLS1CRUdJTiBYNTA5IENSTC0tLS0tDQpNSUlCOWpDQ0FWOENBUUV3RFFZSktvWklodmNOQVFFRkJRQXdiREVhTUJnR0ExVUVDaE1SVWxOQklGTmxZM1Z5DQphWFI1SUVsdVl5NHhIakFjQmdOVkJBTVRGVkpUUVNCUWRXSnNhV01nVW05dmRDQkRRU0IyTVRFdU1Dd0dDU3FHDQpTSWIzRFFFSkFSWWZjbk5oYTJWdmJuSnZiM1J6YVdkdVFISnpZWE5sWTNWeWFYUjVMbU52YlJjTk1URXdNakl6DQpNVGt5T0RNd1doY05NVEV3T0RJeU1Ua3lPRE13V2pDQmpEQktBaEVBckRxb2g5RkhKSFhUN09QZ3V1bjQrQmNODQpNRGt4TVRBeU1UUXlOekE1V2pBbU1Bb0dBMVVkRlFRRENnRUpNQmdHQTFVZEdBUVJHQTh5TURBNU1URXdNak [...]
-
-func TestCreateCertificateRequest(t *testing.T) {
-	random := rand.Reader
-
-	block, _ := pem.Decode([]byte(pemPrivateKey))
-	rsaPriv, err := ParsePKCS1PrivateKey(block.Bytes)
-	if err != nil {
-		t.Fatalf("Failed to parse private key: %s", err)
-	}
-
-	ecdsa256Priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
-	if err != nil {
-		t.Fatalf("Failed to generate ECDSA key: %s", err)
-	}
-
-	ecdsa384Priv, err := ecdsa.GenerateKey(elliptic.P384(), rand.Reader)
-	if err != nil {
-		t.Fatalf("Failed to generate ECDSA key: %s", err)
-	}
-
-	ecdsa521Priv, err := ecdsa.GenerateKey(elliptic.P521(), rand.Reader)
-	if err != nil {
-		t.Fatalf("Failed to generate ECDSA key: %s", err)
-	}
-
-	tests := []struct {
-		name    string
-		priv    interface{}
-		sigAlgo SignatureAlgorithm
-	}{
-		{"RSA", rsaPriv, SHA1WithRSA},
-		{"ECDSA-256", ecdsa256Priv, ECDSAWithSHA1},
-		{"ECDSA-384", ecdsa384Priv, ECDSAWithSHA1},
-		{"ECDSA-521", ecdsa521Priv, ECDSAWithSHA1},
-	}
-
-	for _, test := range tests {
-		template := CertificateRequest{
-			Subject: pkix.Name{
-				CommonName:   "test.example.com",
-				Organization: []string{"Σ Acme Co"},
-			},
-			SignatureAlgorithm: test.sigAlgo,
-			DNSNames:           []string{"test.example.com"},
-			EmailAddresses:     []string{"gopher at golang.org"},
-			IPAddresses:        []net.IP{net.IPv4(127, 0, 0, 1).To4(), net.ParseIP("2001:4860:0:2001::68")},
-		}
-
-		derBytes, err := CreateCertificateRequest(random, &template, test.priv)
-		if err != nil {
-			t.Errorf("%s: failed to create certificate request: %s", test.name, err)
-			continue
-		}
-
-		out, err := ParseCertificateRequest(derBytes)
-		if err != nil {
-			t.Errorf("%s: failed to create certificate request: %s", test.name, err)
-			continue
-		}
-
-		if out.Subject.CommonName != template.Subject.CommonName {
-			t.Errorf("%s: output subject common name and template subject common name don't match", test.name)
-		} else if len(out.Subject.Organization) != len(template.Subject.Organization) {
-			t.Errorf("%s: output subject organisation and template subject organisation don't match", test.name)
-		} else if len(out.DNSNames) != len(template.DNSNames) {
-			t.Errorf("%s: output DNS names and template DNS names don't match", test.name)
-		} else if len(out.EmailAddresses) != len(template.EmailAddresses) {
-			t.Errorf("%s: output email addresses and template email addresses don't match", test.name)
-		} else if len(out.IPAddresses) != len(template.IPAddresses) {
-			t.Errorf("%s: output IP addresses and template IP addresses names don't match", test.name)
-		}
-	}
-}
-
-func marshalAndParseCSR(t *testing.T, template *CertificateRequest) *CertificateRequest {
-	block, _ := pem.Decode([]byte(pemPrivateKey))
-	rsaPriv, err := ParsePKCS1PrivateKey(block.Bytes)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	derBytes, err := CreateCertificateRequest(rand.Reader, template, rsaPriv)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	csr, err := ParseCertificateRequest(derBytes)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	return csr
-}
-
-func TestCertificateRequestOverrides(t *testing.T) {
-	sanContents, err := marshalSANs([]string{"foo.example.com"}, nil, nil)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	template := CertificateRequest{
-		Subject: pkix.Name{
-			CommonName:   "test.example.com",
-			Organization: []string{"Σ Acme Co"},
-		},
-		DNSNames: []string{"test.example.com"},
-
-		// An explicit extension should override the DNSNames from the
-		// template.
-		ExtraExtensions: []pkix.Extension{
-			pkix.Extension{
-				Id:    oidExtensionSubjectAltName,
-				Value: sanContents,
-			},
-		},
-	}
-
-	csr := marshalAndParseCSR(t, &template)
-
-	if len(csr.DNSNames) != 1 || csr.DNSNames[0] != "foo.example.com" {
-		t.Errorf("Extension did not override template. Got %v\n", csr.DNSNames)
-	}
-
-	// If there is already an attribute with X.509 extensions then the
-	// extra extensions should be added to it rather than creating a CSR
-	// with two extension attributes.
-
-	template.Attributes = []pkix.AttributeTypeAndValueSET{
-		pkix.AttributeTypeAndValueSET{
-			Type: oidExtensionRequest,
-			Value: [][]pkix.AttributeTypeAndValue{
-				[]pkix.AttributeTypeAndValue{
-					pkix.AttributeTypeAndValue{
-						Type:  oidExtensionAuthorityInfoAccess,
-						Value: []byte("foo"),
-					},
-				},
-			},
-		},
-	}
-
-	csr = marshalAndParseCSR(t, &template)
-	if l := len(csr.Attributes); l != 1 {
-		t.Errorf("incorrect number of attributes: %d\n", l)
-	}
-
-	if !csr.Attributes[0].Type.Equal(oidExtensionRequest) ||
-		len(csr.Attributes[0].Value) != 1 ||
-		len(csr.Attributes[0].Value[0]) != 2 {
-		t.Errorf("bad attributes: %#v\n", csr.Attributes)
-	}
-
-	sanContents2, err := marshalSANs([]string{"foo2.example.com"}, nil, nil)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	// Extensions in Attributes should override those in ExtraExtensions.
-	template.Attributes[0].Value[0] = append(template.Attributes[0].Value[0], pkix.AttributeTypeAndValue{
-		Type:  oidExtensionSubjectAltName,
-		Value: sanContents2,
-	})
-
-	csr = marshalAndParseCSR(t, &template)
-
-	if len(csr.DNSNames) != 1 || csr.DNSNames[0] != "foo2.example.com" {
-		t.Errorf("Attributes did not override ExtraExtensions. Got %v\n", csr.DNSNames)
-	}
-}
-
-func TestParseCertificateRequest(t *testing.T) {
-	csrBytes := fromBase64(csrBase64)
-	csr, err := ParseCertificateRequest(csrBytes)
-	if err != nil {
-		t.Fatalf("failed to parse CSR: %s", err)
-	}
-
-	if len(csr.EmailAddresses) != 1 || csr.EmailAddresses[0] != "gopher at golang.org" {
-		t.Errorf("incorrect email addresses found: %v", csr.EmailAddresses)
-	}
-
-	if len(csr.DNSNames) != 1 || csr.DNSNames[0] != "test.example.com" {
-		t.Errorf("incorrect DNS names found: %v", csr.DNSNames)
-	}
-
-	if len(csr.Subject.Country) != 1 || csr.Subject.Country[0] != "AU" {
-		t.Errorf("incorrect Subject name: %v", csr.Subject)
-	}
-
-	found := false
-	for _, e := range csr.Extensions {
-		if e.Id.Equal(oidExtensionBasicConstraints) {
-			found = true
-			break
-		}
-	}
-	if !found {
-		t.Errorf("basic constraints extension not found in CSR")
-	}
-}
-
-// This CSR was generated with OpenSSL:
-//  openssl req -out CSR.csr -new -newkey rsa:2048 -nodes -keyout privateKey.key -config openssl.cnf
-//
-// The openssl.cnf needs to include this section:
-//   [ v3_req ]
-//   basicConstraints = CA:FALSE
-//   keyUsage = nonRepudiation, digitalSignature, keyEncipherment
-//   subjectAltName = email:gopher at golang.org,DNS:test.example.com
-const csrBase64 = "MIIC4zCCAcsCAQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOY+MVedRg2JEnyeLcSzcsMv2VcsTfkB5+Etd6hihAh6MrGezNyASMMKuQN6YhCX1icQDiQtGsDLTtheNnSXK06tAhHjAP/hGlszRJp+5+rP2M58fDBAkUBEhskbCUWwpY14jFtVuGNJ8vF8h8IeczdolvQhX9lVai9G0EUXJMliMKdjA899H0mRs9PzHyidyrXFNiZlQXfD8Kg7gETn2Ny965iyI6ujAIYSCvam6TnxRHYH2MBKyVGvsYGbPYUQJCsgdgyajEg6ekihvQY3SzO1HSAlZAd7d1QYO4VeWJ2mY6Wu3Jpmh+AmG19S9CcHq [...]
diff --git a/src/pkg/database/sql/convert_test.go b/src/pkg/database/sql/convert_test.go
deleted file mode 100644
index 6e24830..0000000
--- a/src/pkg/database/sql/convert_test.go
+++ /dev/null
@@ -1,337 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package sql
-
-import (
-	"database/sql/driver"
-	"fmt"
-	"reflect"
-	"runtime"
-	"testing"
-	"time"
-)
-
-var someTime = time.Unix(123, 0)
-var answer int64 = 42
-
-type conversionTest struct {
-	s, d interface{} // source and destination
-
-	// following are used if they're non-zero
-	wantint   int64
-	wantuint  uint64
-	wantstr   string
-	wantbytes []byte
-	wantraw   RawBytes
-	wantf32   float32
-	wantf64   float64
-	wanttime  time.Time
-	wantbool  bool // used if d is of type *bool
-	wanterr   string
-	wantiface interface{}
-	wantptr   *int64 // if non-nil, *d's pointed value must be equal to *wantptr
-	wantnil   bool   // if true, *d must be *int64(nil)
-}
-
-// Target variables for scanning into.
-var (
-	scanstr    string
-	scanbytes  []byte
-	scanraw    RawBytes
-	scanint    int
-	scanint8   int8
-	scanint16  int16
-	scanint32  int32
-	scanuint8  uint8
-	scanuint16 uint16
-	scanbool   bool
-	scanf32    float32
-	scanf64    float64
-	scantime   time.Time
-	scanptr    *int64
-	scaniface  interface{}
-)
-
-var conversionTests = []conversionTest{
-	// Exact conversions (destination pointer type matches source type)
-	{s: "foo", d: &scanstr, wantstr: "foo"},
-	{s: 123, d: &scanint, wantint: 123},
-	{s: someTime, d: &scantime, wanttime: someTime},
-
-	// To strings
-	{s: "string", d: &scanstr, wantstr: "string"},
-	{s: []byte("byteslice"), d: &scanstr, wantstr: "byteslice"},
-	{s: 123, d: &scanstr, wantstr: "123"},
-	{s: int8(123), d: &scanstr, wantstr: "123"},
-	{s: int64(123), d: &scanstr, wantstr: "123"},
-	{s: uint8(123), d: &scanstr, wantstr: "123"},
-	{s: uint16(123), d: &scanstr, wantstr: "123"},
-	{s: uint32(123), d: &scanstr, wantstr: "123"},
-	{s: uint64(123), d: &scanstr, wantstr: "123"},
-	{s: 1.5, d: &scanstr, wantstr: "1.5"},
-
-	// To []byte
-	{s: nil, d: &scanbytes, wantbytes: nil},
-	{s: "string", d: &scanbytes, wantbytes: []byte("string")},
-	{s: []byte("byteslice"), d: &scanbytes, wantbytes: []byte("byteslice")},
-	{s: 123, d: &scanbytes, wantbytes: []byte("123")},
-	{s: int8(123), d: &scanbytes, wantbytes: []byte("123")},
-	{s: int64(123), d: &scanbytes, wantbytes: []byte("123")},
-	{s: uint8(123), d: &scanbytes, wantbytes: []byte("123")},
-	{s: uint16(123), d: &scanbytes, wantbytes: []byte("123")},
-	{s: uint32(123), d: &scanbytes, wantbytes: []byte("123")},
-	{s: uint64(123), d: &scanbytes, wantbytes: []byte("123")},
-	{s: 1.5, d: &scanbytes, wantbytes: []byte("1.5")},
-
-	// To RawBytes
-	{s: nil, d: &scanraw, wantraw: nil},
-	{s: []byte("byteslice"), d: &scanraw, wantraw: RawBytes("byteslice")},
-	{s: 123, d: &scanraw, wantraw: RawBytes("123")},
-	{s: int8(123), d: &scanraw, wantraw: RawBytes("123")},
-	{s: int64(123), d: &scanraw, wantraw: RawBytes("123")},
-	{s: uint8(123), d: &scanraw, wantraw: RawBytes("123")},
-	{s: uint16(123), d: &scanraw, wantraw: RawBytes("123")},
-	{s: uint32(123), d: &scanraw, wantraw: RawBytes("123")},
-	{s: uint64(123), d: &scanraw, wantraw: RawBytes("123")},
-	{s: 1.5, d: &scanraw, wantraw: RawBytes("1.5")},
-
-	// Strings to integers
-	{s: "255", d: &scanuint8, wantuint: 255},
-	{s: "256", d: &scanuint8, wanterr: `converting string "256" to a uint8: strconv.ParseUint: parsing "256": value out of range`},
-	{s: "256", d: &scanuint16, wantuint: 256},
-	{s: "-1", d: &scanint, wantint: -1},
-	{s: "foo", d: &scanint, wanterr: `converting string "foo" to a int: strconv.ParseInt: parsing "foo": invalid syntax`},
-
-	// True bools
-	{s: true, d: &scanbool, wantbool: true},
-	{s: "True", d: &scanbool, wantbool: true},
-	{s: "TRUE", d: &scanbool, wantbool: true},
-	{s: "1", d: &scanbool, wantbool: true},
-	{s: 1, d: &scanbool, wantbool: true},
-	{s: int64(1), d: &scanbool, wantbool: true},
-	{s: uint16(1), d: &scanbool, wantbool: true},
-
-	// False bools
-	{s: false, d: &scanbool, wantbool: false},
-	{s: "false", d: &scanbool, wantbool: false},
-	{s: "FALSE", d: &scanbool, wantbool: false},
-	{s: "0", d: &scanbool, wantbool: false},
-	{s: 0, d: &scanbool, wantbool: false},
-	{s: int64(0), d: &scanbool, wantbool: false},
-	{s: uint16(0), d: &scanbool, wantbool: false},
-
-	// Not bools
-	{s: "yup", d: &scanbool, wanterr: `sql/driver: couldn't convert "yup" into type bool`},
-	{s: 2, d: &scanbool, wanterr: `sql/driver: couldn't convert 2 into type bool`},
-
-	// Floats
-	{s: float64(1.5), d: &scanf64, wantf64: float64(1.5)},
-	{s: int64(1), d: &scanf64, wantf64: float64(1)},
-	{s: float64(1.5), d: &scanf32, wantf32: float32(1.5)},
-	{s: "1.5", d: &scanf32, wantf32: float32(1.5)},
-	{s: "1.5", d: &scanf64, wantf64: float64(1.5)},
-
-	// Pointers
-	{s: interface{}(nil), d: &scanptr, wantnil: true},
-	{s: int64(42), d: &scanptr, wantptr: &answer},
-
-	// To interface{}
-	{s: float64(1.5), d: &scaniface, wantiface: float64(1.5)},
-	{s: int64(1), d: &scaniface, wantiface: int64(1)},
-	{s: "str", d: &scaniface, wantiface: "str"},
-	{s: []byte("byteslice"), d: &scaniface, wantiface: []byte("byteslice")},
-	{s: true, d: &scaniface, wantiface: true},
-	{s: nil, d: &scaniface},
-	{s: []byte(nil), d: &scaniface, wantiface: []byte(nil)},
-}
-
-func intPtrValue(intptr interface{}) interface{} {
-	return reflect.Indirect(reflect.Indirect(reflect.ValueOf(intptr))).Int()
-}
-
-func intValue(intptr interface{}) int64 {
-	return reflect.Indirect(reflect.ValueOf(intptr)).Int()
-}
-
-func uintValue(intptr interface{}) uint64 {
-	return reflect.Indirect(reflect.ValueOf(intptr)).Uint()
-}
-
-func float64Value(ptr interface{}) float64 {
-	return *(ptr.(*float64))
-}
-
-func float32Value(ptr interface{}) float32 {
-	return *(ptr.(*float32))
-}
-
-func timeValue(ptr interface{}) time.Time {
-	return *(ptr.(*time.Time))
-}
-
-func TestConversions(t *testing.T) {
-	for n, ct := range conversionTests {
-		err := convertAssign(ct.d, ct.s)
-		errstr := ""
-		if err != nil {
-			errstr = err.Error()
-		}
-		errf := func(format string, args ...interface{}) {
-			base := fmt.Sprintf("convertAssign #%d: for %v (%T) -> %T, ", n, ct.s, ct.s, ct.d)
-			t.Errorf(base+format, args...)
-		}
-		if errstr != ct.wanterr {
-			errf("got error %q, want error %q", errstr, ct.wanterr)
-		}
-		if ct.wantstr != "" && ct.wantstr != scanstr {
-			errf("want string %q, got %q", ct.wantstr, scanstr)
-		}
-		if ct.wantint != 0 && ct.wantint != intValue(ct.d) {
-			errf("want int %d, got %d", ct.wantint, intValue(ct.d))
-		}
-		if ct.wantuint != 0 && ct.wantuint != uintValue(ct.d) {
-			errf("want uint %d, got %d", ct.wantuint, uintValue(ct.d))
-		}
-		if ct.wantf32 != 0 && ct.wantf32 != float32Value(ct.d) {
-			errf("want float32 %v, got %v", ct.wantf32, float32Value(ct.d))
-		}
-		if ct.wantf64 != 0 && ct.wantf64 != float64Value(ct.d) {
-			errf("want float32 %v, got %v", ct.wantf64, float64Value(ct.d))
-		}
-		if bp, boolTest := ct.d.(*bool); boolTest && *bp != ct.wantbool && ct.wanterr == "" {
-			errf("want bool %v, got %v", ct.wantbool, *bp)
-		}
-		if !ct.wanttime.IsZero() && !ct.wanttime.Equal(timeValue(ct.d)) {
-			errf("want time %v, got %v", ct.wanttime, timeValue(ct.d))
-		}
-		if ct.wantnil && *ct.d.(**int64) != nil {
-			errf("want nil, got %v", intPtrValue(ct.d))
-		}
-		if ct.wantptr != nil {
-			if *ct.d.(**int64) == nil {
-				errf("want pointer to %v, got nil", *ct.wantptr)
-			} else if *ct.wantptr != intPtrValue(ct.d) {
-				errf("want pointer to %v, got %v", *ct.wantptr, intPtrValue(ct.d))
-			}
-		}
-		if ifptr, ok := ct.d.(*interface{}); ok {
-			if !reflect.DeepEqual(ct.wantiface, scaniface) {
-				errf("want interface %#v, got %#v", ct.wantiface, scaniface)
-				continue
-			}
-			if srcBytes, ok := ct.s.([]byte); ok {
-				dstBytes := (*ifptr).([]byte)
-				if len(srcBytes) > 0 && &dstBytes[0] == &srcBytes[0] {
-					errf("copy into interface{} didn't copy []byte data")
-				}
-			}
-		}
-	}
-}
-
-func TestNullString(t *testing.T) {
-	var ns NullString
-	convertAssign(&ns, []byte("foo"))
-	if !ns.Valid {
-		t.Errorf("expecting not null")
-	}
-	if ns.String != "foo" {
-		t.Errorf("expecting foo; got %q", ns.String)
-	}
-	convertAssign(&ns, nil)
-	if ns.Valid {
-		t.Errorf("expecting null on nil")
-	}
-	if ns.String != "" {
-		t.Errorf("expecting blank on nil; got %q", ns.String)
-	}
-}
-
-type valueConverterTest struct {
-	c       driver.ValueConverter
-	in, out interface{}
-	err     string
-}
-
-var valueConverterTests = []valueConverterTest{
-	{driver.DefaultParameterConverter, NullString{"hi", true}, "hi", ""},
-	{driver.DefaultParameterConverter, NullString{"", false}, nil, ""},
-}
-
-func TestValueConverters(t *testing.T) {
-	for i, tt := range valueConverterTests {
-		out, err := tt.c.ConvertValue(tt.in)
-		goterr := ""
-		if err != nil {
-			goterr = err.Error()
-		}
-		if goterr != tt.err {
-			t.Errorf("test %d: %T(%T(%v)) error = %q; want error = %q",
-				i, tt.c, tt.in, tt.in, goterr, tt.err)
-		}
-		if tt.err != "" {
-			continue
-		}
-		if !reflect.DeepEqual(out, tt.out) {
-			t.Errorf("test %d: %T(%T(%v)) = %v (%T); want %v (%T)",
-				i, tt.c, tt.in, tt.in, out, out, tt.out, tt.out)
-		}
-	}
-}
-
-// Tests that assigning to RawBytes doesn't allocate (and also works).
-func TestRawBytesAllocs(t *testing.T) {
-	buf := make(RawBytes, 10)
-	test := func(name string, in interface{}, want string) {
-		if err := convertAssign(&buf, in); err != nil {
-			t.Fatalf("%s: convertAssign = %v", name, err)
-		}
-		match := len(buf) == len(want)
-		if match {
-			for i, b := range buf {
-				if want[i] != b {
-					match = false
-					break
-				}
-			}
-		}
-		if !match {
-			t.Fatalf("%s: got %q (len %d); want %q (len %d)", name, buf, len(buf), want, len(want))
-		}
-	}
-	n := testing.AllocsPerRun(100, func() {
-		test("uint64", uint64(12345678), "12345678")
-		test("uint32", uint32(1234), "1234")
-		test("uint16", uint16(12), "12")
-		test("uint8", uint8(1), "1")
-		test("uint", uint(123), "123")
-		test("int", int(123), "123")
-		test("int8", int8(1), "1")
-		test("int16", int16(12), "12")
-		test("int32", int32(1234), "1234")
-		test("int64", int64(12345678), "12345678")
-		test("float32", float32(1.5), "1.5")
-		test("float64", float64(64), "64")
-		test("bool", false, "false")
-	})
-
-	// The numbers below are only valid for 64-bit interface word sizes,
-	// and gc. With 32-bit words there are more convT2E allocs, and
-	// with gccgo, only pointers currently go in interface data.
-	// So only care on amd64 gc for now.
-	measureAllocs := runtime.GOARCH == "amd64" && runtime.Compiler == "gc"
-
-	if n > 0.5 && measureAllocs {
-		t.Fatalf("allocs = %v; want 0", n)
-	}
-
-	// This one involves a convT2E allocation, string -> interface{}
-	n = testing.AllocsPerRun(100, func() {
-		test("string", "foo", "foo")
-	})
-	if n > 1.5 && measureAllocs {
-		t.Fatalf("allocs = %v; want max 1", n)
-	}
-}
diff --git a/src/pkg/database/sql/fakedb_test.go b/src/pkg/database/sql/fakedb_test.go
deleted file mode 100644
index c7db0dd..0000000
--- a/src/pkg/database/sql/fakedb_test.go
+++ /dev/null
@@ -1,805 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package sql
-
-import (
-	"database/sql/driver"
-	"errors"
-	"fmt"
-	"io"
-	"log"
-	"strconv"
-	"strings"
-	"sync"
-	"testing"
-	"time"
-)
-
-var _ = log.Printf
-
-// fakeDriver is a fake database that implements Go's driver.Driver
-// interface, just for testing.
-//
-// It speaks a query language that's semantically similar to but
-// syntactically different and simpler than SQL.  The syntax is as
-// follows:
-//
-//   WIPE
-//   CREATE|<tablename>|<col>=<type>,<col>=<type>,...
-//     where types are: "string", [u]int{8,16,32,64}, "bool"
-//   INSERT|<tablename>|col=val,col2=val2,col3=?
-//   SELECT|<tablename>|projectcol1,projectcol2|filtercol=?,filtercol2=?
-//
-// When opening a fakeDriver's database, it starts empty with no
-// tables.  All tables and data are stored in memory only.
-type fakeDriver struct {
-	mu         sync.Mutex // guards 3 following fields
-	openCount  int        // conn opens
-	closeCount int        // conn closes
-	waitCh     chan struct{}
-	waitingCh  chan struct{}
-	dbs        map[string]*fakeDB
-}
-
-type fakeDB struct {
-	name string
-
-	mu      sync.Mutex
-	free    []*fakeConn
-	tables  map[string]*table
-	badConn bool
-}
-
-type table struct {
-	mu      sync.Mutex
-	colname []string
-	coltype []string
-	rows    []*row
-}
-
-func (t *table) columnIndex(name string) int {
-	for n, nname := range t.colname {
-		if name == nname {
-			return n
-		}
-	}
-	return -1
-}
-
-type row struct {
-	cols []interface{} // must be same size as its table colname + coltype
-}
-
-func (r *row) clone() *row {
-	nrow := &row{cols: make([]interface{}, len(r.cols))}
-	copy(nrow.cols, r.cols)
-	return nrow
-}
-
-type fakeConn struct {
-	db *fakeDB // where to return ourselves to
-
-	currTx *fakeTx
-
-	// Stats for tests:
-	mu          sync.Mutex
-	stmtsMade   int
-	stmtsClosed int
-	numPrepare  int
-	bad         bool
-}
-
-func (c *fakeConn) incrStat(v *int) {
-	c.mu.Lock()
-	*v++
-	c.mu.Unlock()
-}
-
-type fakeTx struct {
-	c *fakeConn
-}
-
-type fakeStmt struct {
-	c *fakeConn
-	q string // just for debugging
-
-	cmd   string
-	table string
-
-	closed bool
-
-	colName      []string      // used by CREATE, INSERT, SELECT (selected columns)
-	colType      []string      // used by CREATE
-	colValue     []interface{} // used by INSERT (mix of strings and "?" for bound params)
-	placeholders int           // used by INSERT/SELECT: number of ? params
-
-	whereCol []string // used by SELECT (all placeholders)
-
-	placeholderConverter []driver.ValueConverter // used by INSERT
-}
-
-var fdriver driver.Driver = &fakeDriver{}
-
-func init() {
-	Register("test", fdriver)
-}
-
-// Supports dsn forms:
-//    <dbname>
-//    <dbname>;<opts>  (only currently supported option is `badConn`,
-//                      which causes driver.ErrBadConn to be returned on
-//                      every other conn.Begin())
-func (d *fakeDriver) Open(dsn string) (driver.Conn, error) {
-	parts := strings.Split(dsn, ";")
-	if len(parts) < 1 {
-		return nil, errors.New("fakedb: no database name")
-	}
-	name := parts[0]
-
-	db := d.getDB(name)
-
-	d.mu.Lock()
-	d.openCount++
-	d.mu.Unlock()
-	conn := &fakeConn{db: db}
-
-	if len(parts) >= 2 && parts[1] == "badConn" {
-		conn.bad = true
-	}
-	if d.waitCh != nil {
-		d.waitingCh <- struct{}{}
-		<-d.waitCh
-		d.waitCh = nil
-		d.waitingCh = nil
-	}
-	return conn, nil
-}
-
-func (d *fakeDriver) getDB(name string) *fakeDB {
-	d.mu.Lock()
-	defer d.mu.Unlock()
-	if d.dbs == nil {
-		d.dbs = make(map[string]*fakeDB)
-	}
-	db, ok := d.dbs[name]
-	if !ok {
-		db = &fakeDB{name: name}
-		d.dbs[name] = db
-	}
-	return db
-}
-
-func (db *fakeDB) wipe() {
-	db.mu.Lock()
-	defer db.mu.Unlock()
-	db.tables = nil
-}
-
-func (db *fakeDB) createTable(name string, columnNames, columnTypes []string) error {
-	db.mu.Lock()
-	defer db.mu.Unlock()
-	if db.tables == nil {
-		db.tables = make(map[string]*table)
-	}
-	if _, exist := db.tables[name]; exist {
-		return fmt.Errorf("table %q already exists", name)
-	}
-	if len(columnNames) != len(columnTypes) {
-		return fmt.Errorf("create table of %q len(names) != len(types): %d vs %d",
-			name, len(columnNames), len(columnTypes))
-	}
-	db.tables[name] = &table{colname: columnNames, coltype: columnTypes}
-	return nil
-}
-
-// must be called with db.mu lock held
-func (db *fakeDB) table(table string) (*table, bool) {
-	if db.tables == nil {
-		return nil, false
-	}
-	t, ok := db.tables[table]
-	return t, ok
-}
-
-func (db *fakeDB) columnType(table, column string) (typ string, ok bool) {
-	db.mu.Lock()
-	defer db.mu.Unlock()
-	t, ok := db.table(table)
-	if !ok {
-		return
-	}
-	for n, cname := range t.colname {
-		if cname == column {
-			return t.coltype[n], true
-		}
-	}
-	return "", false
-}
-
-func (c *fakeConn) isBad() bool {
-	// if not simulating bad conn, do nothing
-	if !c.bad {
-		return false
-	}
-	// alternate between bad conn and not bad conn
-	c.db.badConn = !c.db.badConn
-	return c.db.badConn
-}
-
-func (c *fakeConn) Begin() (driver.Tx, error) {
-	if c.isBad() {
-		return nil, driver.ErrBadConn
-	}
-	if c.currTx != nil {
-		return nil, errors.New("already in a transaction")
-	}
-	c.currTx = &fakeTx{c: c}
-	return c.currTx, nil
-}
-
-var hookPostCloseConn struct {
-	sync.Mutex
-	fn func(*fakeConn, error)
-}
-
-func setHookpostCloseConn(fn func(*fakeConn, error)) {
-	hookPostCloseConn.Lock()
-	defer hookPostCloseConn.Unlock()
-	hookPostCloseConn.fn = fn
-}
-
-var testStrictClose *testing.T
-
-// setStrictFakeConnClose sets the t to Errorf on when fakeConn.Close
-// fails to close. If nil, the check is disabled.
-func setStrictFakeConnClose(t *testing.T) {
-	testStrictClose = t
-}
-
-func (c *fakeConn) Close() (err error) {
-	drv := fdriver.(*fakeDriver)
-	defer func() {
-		if err != nil && testStrictClose != nil {
-			testStrictClose.Errorf("failed to close a test fakeConn: %v", err)
-		}
-		hookPostCloseConn.Lock()
-		fn := hookPostCloseConn.fn
-		hookPostCloseConn.Unlock()
-		if fn != nil {
-			fn(c, err)
-		}
-		if err == nil {
-			drv.mu.Lock()
-			drv.closeCount++
-			drv.mu.Unlock()
-		}
-	}()
-	if c.currTx != nil {
-		return errors.New("can't close fakeConn; in a Transaction")
-	}
-	if c.db == nil {
-		return errors.New("can't close fakeConn; already closed")
-	}
-	if c.stmtsMade > c.stmtsClosed {
-		return errors.New("can't close; dangling statement(s)")
-	}
-	c.db = nil
-	return nil
-}
-
-func checkSubsetTypes(args []driver.Value) error {
-	for n, arg := range args {
-		switch arg.(type) {
-		case int64, float64, bool, nil, []byte, string, time.Time:
-		default:
-			return fmt.Errorf("fakedb_test: invalid argument #%d: %v, type %T", n+1, arg, arg)
-		}
-	}
-	return nil
-}
-
-func (c *fakeConn) Exec(query string, args []driver.Value) (driver.Result, error) {
-	// This is an optional interface, but it's implemented here
-	// just to check that all the args are of the proper types.
-	// ErrSkip is returned so the caller acts as if we didn't
-	// implement this at all.
-	err := checkSubsetTypes(args)
-	if err != nil {
-		return nil, err
-	}
-	return nil, driver.ErrSkip
-}
-
-func (c *fakeConn) Query(query string, args []driver.Value) (driver.Rows, error) {
-	// This is an optional interface, but it's implemented here
-	// just to check that all the args are of the proper types.
-	// ErrSkip is returned so the caller acts as if we didn't
-	// implement this at all.
-	err := checkSubsetTypes(args)
-	if err != nil {
-		return nil, err
-	}
-	return nil, driver.ErrSkip
-}
-
-func errf(msg string, args ...interface{}) error {
-	return errors.New("fakedb: " + fmt.Sprintf(msg, args...))
-}
-
-// parts are table|selectCol1,selectCol2|whereCol=?,whereCol2=?
-// (note that where columns must always contain ? marks,
-//  just a limitation for fakedb)
-func (c *fakeConn) prepareSelect(stmt *fakeStmt, parts []string) (driver.Stmt, error) {
-	if len(parts) != 3 {
-		stmt.Close()
-		return nil, errf("invalid SELECT syntax with %d parts; want 3", len(parts))
-	}
-	stmt.table = parts[0]
-	stmt.colName = strings.Split(parts[1], ",")
-	for n, colspec := range strings.Split(parts[2], ",") {
-		if colspec == "" {
-			continue
-		}
-		nameVal := strings.Split(colspec, "=")
-		if len(nameVal) != 2 {
-			stmt.Close()
-			return nil, errf("SELECT on table %q has invalid column spec of %q (index %d)", stmt.table, colspec, n)
-		}
-		column, value := nameVal[0], nameVal[1]
-		_, ok := c.db.columnType(stmt.table, column)
-		if !ok {
-			stmt.Close()
-			return nil, errf("SELECT on table %q references non-existent column %q", stmt.table, column)
-		}
-		if value != "?" {
-			stmt.Close()
-			return nil, errf("SELECT on table %q has pre-bound value for where column %q; need a question mark",
-				stmt.table, column)
-		}
-		stmt.whereCol = append(stmt.whereCol, column)
-		stmt.placeholders++
-	}
-	return stmt, nil
-}
-
-// parts are table|col=type,col2=type2
-func (c *fakeConn) prepareCreate(stmt *fakeStmt, parts []string) (driver.Stmt, error) {
-	if len(parts) != 2 {
-		stmt.Close()
-		return nil, errf("invalid CREATE syntax with %d parts; want 2", len(parts))
-	}
-	stmt.table = parts[0]
-	for n, colspec := range strings.Split(parts[1], ",") {
-		nameType := strings.Split(colspec, "=")
-		if len(nameType) != 2 {
-			stmt.Close()
-			return nil, errf("CREATE table %q has invalid column spec of %q (index %d)", stmt.table, colspec, n)
-		}
-		stmt.colName = append(stmt.colName, nameType[0])
-		stmt.colType = append(stmt.colType, nameType[1])
-	}
-	return stmt, nil
-}
-
-// parts are table|col=?,col2=val
-func (c *fakeConn) prepareInsert(stmt *fakeStmt, parts []string) (driver.Stmt, error) {
-	if len(parts) != 2 {
-		stmt.Close()
-		return nil, errf("invalid INSERT syntax with %d parts; want 2", len(parts))
-	}
-	stmt.table = parts[0]
-	for n, colspec := range strings.Split(parts[1], ",") {
-		nameVal := strings.Split(colspec, "=")
-		if len(nameVal) != 2 {
-			stmt.Close()
-			return nil, errf("INSERT table %q has invalid column spec of %q (index %d)", stmt.table, colspec, n)
-		}
-		column, value := nameVal[0], nameVal[1]
-		ctype, ok := c.db.columnType(stmt.table, column)
-		if !ok {
-			stmt.Close()
-			return nil, errf("INSERT table %q references non-existent column %q", stmt.table, column)
-		}
-		stmt.colName = append(stmt.colName, column)
-
-		if value != "?" {
-			var subsetVal interface{}
-			// Convert to driver subset type
-			switch ctype {
-			case "string":
-				subsetVal = []byte(value)
-			case "blob":
-				subsetVal = []byte(value)
-			case "int32":
-				i, err := strconv.Atoi(value)
-				if err != nil {
-					stmt.Close()
-					return nil, errf("invalid conversion to int32 from %q", value)
-				}
-				subsetVal = int64(i) // int64 is a subset type, but not int32
-			default:
-				stmt.Close()
-				return nil, errf("unsupported conversion for pre-bound parameter %q to type %q", value, ctype)
-			}
-			stmt.colValue = append(stmt.colValue, subsetVal)
-		} else {
-			stmt.placeholders++
-			stmt.placeholderConverter = append(stmt.placeholderConverter, converterForType(ctype))
-			stmt.colValue = append(stmt.colValue, "?")
-		}
-	}
-	return stmt, nil
-}
-
-// hook to simulate broken connections
-var hookPrepareBadConn func() bool
-
-func (c *fakeConn) Prepare(query string) (driver.Stmt, error) {
-	c.numPrepare++
-	if c.db == nil {
-		panic("nil c.db; conn = " + fmt.Sprintf("%#v", c))
-	}
-
-	if hookPrepareBadConn != nil && hookPrepareBadConn() {
-		return nil, driver.ErrBadConn
-	}
-
-	parts := strings.Split(query, "|")
-	if len(parts) < 1 {
-		return nil, errf("empty query")
-	}
-	cmd := parts[0]
-	parts = parts[1:]
-	stmt := &fakeStmt{q: query, c: c, cmd: cmd}
-	c.incrStat(&c.stmtsMade)
-	switch cmd {
-	case "WIPE":
-		// Nothing
-	case "SELECT":
-		return c.prepareSelect(stmt, parts)
-	case "CREATE":
-		return c.prepareCreate(stmt, parts)
-	case "INSERT":
-		return c.prepareInsert(stmt, parts)
-	case "NOSERT":
-		// Do all the prep-work like for an INSERT but don't actually insert the row.
-		// Used for some of the concurrent tests.
-		return c.prepareInsert(stmt, parts)
-	default:
-		stmt.Close()
-		return nil, errf("unsupported command type %q", cmd)
-	}
-	return stmt, nil
-}
-
-func (s *fakeStmt) ColumnConverter(idx int) driver.ValueConverter {
-	if len(s.placeholderConverter) == 0 {
-		return driver.DefaultParameterConverter
-	}
-	return s.placeholderConverter[idx]
-}
-
-func (s *fakeStmt) Close() error {
-	if s.c == nil {
-		panic("nil conn in fakeStmt.Close")
-	}
-	if s.c.db == nil {
-		panic("in fakeStmt.Close, conn's db is nil (already closed)")
-	}
-	if !s.closed {
-		s.c.incrStat(&s.c.stmtsClosed)
-		s.closed = true
-	}
-	return nil
-}
-
-var errClosed = errors.New("fakedb: statement has been closed")
-
-// hook to simulate broken connections
-var hookExecBadConn func() bool
-
-func (s *fakeStmt) Exec(args []driver.Value) (driver.Result, error) {
-	if s.closed {
-		return nil, errClosed
-	}
-
-	if hookExecBadConn != nil && hookExecBadConn() {
-		return nil, driver.ErrBadConn
-	}
-
-	err := checkSubsetTypes(args)
-	if err != nil {
-		return nil, err
-	}
-
-	db := s.c.db
-	switch s.cmd {
-	case "WIPE":
-		db.wipe()
-		return driver.ResultNoRows, nil
-	case "CREATE":
-		if err := db.createTable(s.table, s.colName, s.colType); err != nil {
-			return nil, err
-		}
-		return driver.ResultNoRows, nil
-	case "INSERT":
-		return s.execInsert(args, true)
-	case "NOSERT":
-		// Do all the prep-work like for an INSERT but don't actually insert the row.
-		// Used for some of the concurrent tests.
-		return s.execInsert(args, false)
-	}
-	fmt.Printf("EXEC statement, cmd=%q: %#v\n", s.cmd, s)
-	return nil, fmt.Errorf("unimplemented statement Exec command type of %q", s.cmd)
-}
-
-// When doInsert is true, add the row to the table.
-// When doInsert is false do prep-work and error checking, but don't
-// actually add the row to the table.
-func (s *fakeStmt) execInsert(args []driver.Value, doInsert bool) (driver.Result, error) {
-	db := s.c.db
-	if len(args) != s.placeholders {
-		panic("error in pkg db; should only get here if size is correct")
-	}
-	db.mu.Lock()
-	t, ok := db.table(s.table)
-	db.mu.Unlock()
-	if !ok {
-		return nil, fmt.Errorf("fakedb: table %q doesn't exist", s.table)
-	}
-
-	t.mu.Lock()
-	defer t.mu.Unlock()
-
-	var cols []interface{}
-	if doInsert {
-		cols = make([]interface{}, len(t.colname))
-	}
-	argPos := 0
-	for n, colname := range s.colName {
-		colidx := t.columnIndex(colname)
-		if colidx == -1 {
-			return nil, fmt.Errorf("fakedb: column %q doesn't exist or dropped since prepared statement was created", colname)
-		}
-		var val interface{}
-		if strvalue, ok := s.colValue[n].(string); ok && strvalue == "?" {
-			val = args[argPos]
-			argPos++
-		} else {
-			val = s.colValue[n]
-		}
-		if doInsert {
-			cols[colidx] = val
-		}
-	}
-
-	if doInsert {
-		t.rows = append(t.rows, &row{cols: cols})
-	}
-	return driver.RowsAffected(1), nil
-}
-
-// hook to simulate broken connections
-var hookQueryBadConn func() bool
-
-func (s *fakeStmt) Query(args []driver.Value) (driver.Rows, error) {
-	if s.closed {
-		return nil, errClosed
-	}
-
-	if hookQueryBadConn != nil && hookQueryBadConn() {
-		return nil, driver.ErrBadConn
-	}
-
-	err := checkSubsetTypes(args)
-	if err != nil {
-		return nil, err
-	}
-
-	db := s.c.db
-	if len(args) != s.placeholders {
-		panic("error in pkg db; should only get here if size is correct")
-	}
-
-	db.mu.Lock()
-	t, ok := db.table(s.table)
-	db.mu.Unlock()
-	if !ok {
-		return nil, fmt.Errorf("fakedb: table %q doesn't exist", s.table)
-	}
-
-	if s.table == "magicquery" {
-		if len(s.whereCol) == 2 && s.whereCol[0] == "op" && s.whereCol[1] == "millis" {
-			if args[0] == "sleep" {
-				time.Sleep(time.Duration(args[1].(int64)) * time.Millisecond)
-			}
-		}
-	}
-
-	t.mu.Lock()
-	defer t.mu.Unlock()
-
-	colIdx := make(map[string]int) // select column name -> column index in table
-	for _, name := range s.colName {
-		idx := t.columnIndex(name)
-		if idx == -1 {
-			return nil, fmt.Errorf("fakedb: unknown column name %q", name)
-		}
-		colIdx[name] = idx
-	}
-
-	mrows := []*row{}
-rows:
-	for _, trow := range t.rows {
-		// Process the where clause, skipping non-match rows. This is lazy
-		// and just uses fmt.Sprintf("%v") to test equality.  Good enough
-		// for test code.
-		for widx, wcol := range s.whereCol {
-			idx := t.columnIndex(wcol)
-			if idx == -1 {
-				return nil, fmt.Errorf("db: invalid where clause column %q", wcol)
-			}
-			tcol := trow.cols[idx]
-			if bs, ok := tcol.([]byte); ok {
-				// lazy hack to avoid sprintf %v on a []byte
-				tcol = string(bs)
-			}
-			if fmt.Sprintf("%v", tcol) != fmt.Sprintf("%v", args[widx]) {
-				continue rows
-			}
-		}
-		mrow := &row{cols: make([]interface{}, len(s.colName))}
-		for seli, name := range s.colName {
-			mrow.cols[seli] = trow.cols[colIdx[name]]
-		}
-		mrows = append(mrows, mrow)
-	}
-
-	cursor := &rowsCursor{
-		pos:    -1,
-		rows:   mrows,
-		cols:   s.colName,
-		errPos: -1,
-	}
-	return cursor, nil
-}
-
-func (s *fakeStmt) NumInput() int {
-	return s.placeholders
-}
-
-func (tx *fakeTx) Commit() error {
-	tx.c.currTx = nil
-	return nil
-}
-
-func (tx *fakeTx) Rollback() error {
-	tx.c.currTx = nil
-	return nil
-}
-
-type rowsCursor struct {
-	cols   []string
-	pos    int
-	rows   []*row
-	closed bool
-
-	// errPos and err are for making Next return early with error.
-	errPos int
-	err    error
-
-	// a clone of slices to give out to clients, indexed by the
-	// the original slice's first byte address.  we clone them
-	// just so we're able to corrupt them on close.
-	bytesClone map[*byte][]byte
-}
-
-func (rc *rowsCursor) Close() error {
-	if !rc.closed {
-		for _, bs := range rc.bytesClone {
-			bs[0] = 255 // first byte corrupted
-		}
-	}
-	rc.closed = true
-	return nil
-}
-
-func (rc *rowsCursor) Columns() []string {
-	return rc.cols
-}
-
-var rowsCursorNextHook func(dest []driver.Value) error
-
-func (rc *rowsCursor) Next(dest []driver.Value) error {
-	if rowsCursorNextHook != nil {
-		return rowsCursorNextHook(dest)
-	}
-
-	if rc.closed {
-		return errors.New("fakedb: cursor is closed")
-	}
-	rc.pos++
-	if rc.pos == rc.errPos {
-		return rc.err
-	}
-	if rc.pos >= len(rc.rows) {
-		return io.EOF // per interface spec
-	}
-	for i, v := range rc.rows[rc.pos].cols {
-		// TODO(bradfitz): convert to subset types? naah, I
-		// think the subset types should only be input to
-		// driver, but the sql package should be able to handle
-		// a wider range of types coming out of drivers. all
-		// for ease of drivers, and to prevent drivers from
-		// messing up conversions or doing them differently.
-		dest[i] = v
-
-		if bs, ok := v.([]byte); ok {
-			if rc.bytesClone == nil {
-				rc.bytesClone = make(map[*byte][]byte)
-			}
-			clone, ok := rc.bytesClone[&bs[0]]
-			if !ok {
-				clone = make([]byte, len(bs))
-				copy(clone, bs)
-				rc.bytesClone[&bs[0]] = clone
-			}
-			dest[i] = clone
-		}
-	}
-	return nil
-}
-
-// fakeDriverString is like driver.String, but indirects pointers like
-// DefaultValueConverter.
-//
-// This could be surprising behavior to retroactively apply to
-// driver.String now that Go1 is out, but this is convenient for
-// our TestPointerParamsAndScans.
-//
-type fakeDriverString struct{}
-
-func (fakeDriverString) ConvertValue(v interface{}) (driver.Value, error) {
-	switch c := v.(type) {
-	case string, []byte:
-		return v, nil
-	case *string:
-		if c == nil {
-			return nil, nil
-		}
-		return *c, nil
-	}
-	return fmt.Sprintf("%v", v), nil
-}
-
-func converterForType(typ string) driver.ValueConverter {
-	switch typ {
-	case "bool":
-		return driver.Bool
-	case "nullbool":
-		return driver.Null{Converter: driver.Bool}
-	case "int32":
-		return driver.Int32
-	case "string":
-		return driver.NotNull{Converter: fakeDriverString{}}
-	case "nullstring":
-		return driver.Null{Converter: fakeDriverString{}}
-	case "int64":
-		// TODO(coopernurse): add type-specific converter
-		return driver.NotNull{Converter: driver.DefaultParameterConverter}
-	case "nullint64":
-		// TODO(coopernurse): add type-specific converter
-		return driver.Null{Converter: driver.DefaultParameterConverter}
-	case "float64":
-		// TODO(coopernurse): add type-specific converter
-		return driver.NotNull{Converter: driver.DefaultParameterConverter}
-	case "nullfloat64":
-		// TODO(coopernurse): add type-specific converter
-		return driver.Null{Converter: driver.DefaultParameterConverter}
-	case "datetime":
-		return driver.DefaultParameterConverter
-	}
-	panic("invalid fakedb column type of " + typ)
-}
diff --git a/src/pkg/database/sql/sql.go b/src/pkg/database/sql/sql.go
deleted file mode 100644
index 765b80c..0000000
--- a/src/pkg/database/sql/sql.go
+++ /dev/null
@@ -1,1720 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package sql provides a generic interface around SQL (or SQL-like)
-// databases.
-//
-// The sql package must be used in conjunction with a database driver.
-// See http://golang.org/s/sqldrivers for a list of drivers.
-//
-// For more usage examples, see the wiki page at
-// http://golang.org/s/sqlwiki.
-package sql
-
-import (
-	"container/list"
-	"database/sql/driver"
-	"errors"
-	"fmt"
-	"io"
-	"runtime"
-	"sync"
-)
-
-var drivers = make(map[string]driver.Driver)
-
-// Register makes a database driver available by the provided name.
-// If Register is called twice with the same name or if driver is nil,
-// it panics.
-func Register(name string, driver driver.Driver) {
-	if driver == nil {
-		panic("sql: Register driver is nil")
-	}
-	if _, dup := drivers[name]; dup {
-		panic("sql: Register called twice for driver " + name)
-	}
-	drivers[name] = driver
-}
-
-// RawBytes is a byte slice that holds a reference to memory owned by
-// the database itself. After a Scan into a RawBytes, the slice is only
-// valid until the next call to Next, Scan, or Close.
-type RawBytes []byte
-
-// NullString represents a string that may be null.
-// NullString implements the Scanner interface so
-// it can be used as a scan destination:
-//
-//  var s NullString
-//  err := db.QueryRow("SELECT name FROM foo WHERE id=?", id).Scan(&s)
-//  ...
-//  if s.Valid {
-//     // use s.String
-//  } else {
-//     // NULL value
-//  }
-//
-type NullString struct {
-	String string
-	Valid  bool // Valid is true if String is not NULL
-}
-
-// Scan implements the Scanner interface.
-func (ns *NullString) Scan(value interface{}) error {
-	if value == nil {
-		ns.String, ns.Valid = "", false
-		return nil
-	}
-	ns.Valid = true
-	return convertAssign(&ns.String, value)
-}
-
-// Value implements the driver Valuer interface.
-func (ns NullString) Value() (driver.Value, error) {
-	if !ns.Valid {
-		return nil, nil
-	}
-	return ns.String, nil
-}
-
-// NullInt64 represents an int64 that may be null.
-// NullInt64 implements the Scanner interface so
-// it can be used as a scan destination, similar to NullString.
-type NullInt64 struct {
-	Int64 int64
-	Valid bool // Valid is true if Int64 is not NULL
-}
-
-// Scan implements the Scanner interface.
-func (n *NullInt64) Scan(value interface{}) error {
-	if value == nil {
-		n.Int64, n.Valid = 0, false
-		return nil
-	}
-	n.Valid = true
-	return convertAssign(&n.Int64, value)
-}
-
-// Value implements the driver Valuer interface.
-func (n NullInt64) Value() (driver.Value, error) {
-	if !n.Valid {
-		return nil, nil
-	}
-	return n.Int64, nil
-}
-
-// NullFloat64 represents a float64 that may be null.
-// NullFloat64 implements the Scanner interface so
-// it can be used as a scan destination, similar to NullString.
-type NullFloat64 struct {
-	Float64 float64
-	Valid   bool // Valid is true if Float64 is not NULL
-}
-
-// Scan implements the Scanner interface.
-func (n *NullFloat64) Scan(value interface{}) error {
-	if value == nil {
-		n.Float64, n.Valid = 0, false
-		return nil
-	}
-	n.Valid = true
-	return convertAssign(&n.Float64, value)
-}
-
-// Value implements the driver Valuer interface.
-func (n NullFloat64) Value() (driver.Value, error) {
-	if !n.Valid {
-		return nil, nil
-	}
-	return n.Float64, nil
-}
-
-// NullBool represents a bool that may be null.
-// NullBool implements the Scanner interface so
-// it can be used as a scan destination, similar to NullString.
-type NullBool struct {
-	Bool  bool
-	Valid bool // Valid is true if Bool is not NULL
-}
-
-// Scan implements the Scanner interface.
-func (n *NullBool) Scan(value interface{}) error {
-	if value == nil {
-		n.Bool, n.Valid = false, false
-		return nil
-	}
-	n.Valid = true
-	return convertAssign(&n.Bool, value)
-}
-
-// Value implements the driver Valuer interface.
-func (n NullBool) Value() (driver.Value, error) {
-	if !n.Valid {
-		return nil, nil
-	}
-	return n.Bool, nil
-}
-
-// Scanner is an interface used by Scan.
-type Scanner interface {
-	// Scan assigns a value from a database driver.
-	//
-	// The src value will be of one of the following restricted
-	// set of types:
-	//
-	//    int64
-	//    float64
-	//    bool
-	//    []byte
-	//    string
-	//    time.Time
-	//    nil - for NULL values
-	//
-	// An error should be returned if the value can not be stored
-	// without loss of information.
-	Scan(src interface{}) error
-}
-
-// ErrNoRows is returned by Scan when QueryRow doesn't return a
-// row. In such a case, QueryRow returns a placeholder *Row value that
-// defers this error until a Scan.
-var ErrNoRows = errors.New("sql: no rows in result set")
-
-// DB is a database handle representing a pool of zero or more
-// underlying connections. It's safe for concurrent use by multiple
-// goroutines.
-//
-// The sql package creates and frees connections automatically; it
-// also maintains a free pool of idle connections. If the database has
-// a concept of per-connection state, such state can only be reliably
-// observed within a transaction. Once DB.Begin is called, the
-// returned Tx is bound to a single connection. Once Commit or
-// Rollback is called on the transaction, that transaction's
-// connection is returned to DB's idle connection pool. The pool size
-// can be controlled with SetMaxIdleConns.
-type DB struct {
-	driver driver.Driver
-	dsn    string
-
-	mu           sync.Mutex // protects following fields
-	freeConn     *list.List // of *driverConn
-	connRequests *list.List // of connRequest
-	numOpen      int
-	pendingOpens int
-	// Used to signal the need for new connections
-	// a goroutine running connectionOpener() reads on this chan and
-	// maybeOpenNewConnections sends on the chan (one send per needed connection)
-	// It is closed during db.Close(). The close tells the connectionOpener
-	// goroutine to exit.
-	openerCh chan struct{}
-	closed   bool
-	dep      map[finalCloser]depSet
-	lastPut  map[*driverConn]string // stacktrace of last conn's put; debug only
-	maxIdle  int                    // zero means defaultMaxIdleConns; negative means 0
-	maxOpen  int                    // <= 0 means unlimited
-}
-
-// driverConn wraps a driver.Conn with a mutex, to
-// be held during all calls into the Conn. (including any calls onto
-// interfaces returned via that Conn, such as calls on Tx, Stmt,
-// Result, Rows)
-type driverConn struct {
-	db *DB
-
-	sync.Mutex  // guards following
-	ci          driver.Conn
-	closed      bool
-	finalClosed bool // ci.Close has been called
-	openStmt    map[driver.Stmt]bool
-
-	// guarded by db.mu
-	inUse      bool
-	onPut      []func() // code (with db.mu held) run when conn is next returned
-	dbmuClosed bool     // same as closed, but guarded by db.mu, for connIfFree
-	// This is the Element returned by db.freeConn.PushFront(conn).
-	// It's used by connIfFree to remove the conn from the freeConn list.
-	listElem *list.Element
-}
-
-func (dc *driverConn) releaseConn(err error) {
-	dc.db.putConn(dc, err)
-}
-
-func (dc *driverConn) removeOpenStmt(si driver.Stmt) {
-	dc.Lock()
-	defer dc.Unlock()
-	delete(dc.openStmt, si)
-}
-
-func (dc *driverConn) prepareLocked(query string) (driver.Stmt, error) {
-	si, err := dc.ci.Prepare(query)
-	if err == nil {
-		// Track each driverConn's open statements, so we can close them
-		// before closing the conn.
-		//
-		// TODO(bradfitz): let drivers opt out of caring about
-		// stmt closes if the conn is about to close anyway? For now
-		// do the safe thing, in case stmts need to be closed.
-		//
-		// TODO(bradfitz): after Go 1.2, closing driver.Stmts
-		// should be moved to driverStmt, using unique
-		// *driverStmts everywhere (including from
-		// *Stmt.connStmt, instead of returning a
-		// driver.Stmt), using driverStmt as a pointer
-		// everywhere, and making it a finalCloser.
-		if dc.openStmt == nil {
-			dc.openStmt = make(map[driver.Stmt]bool)
-		}
-		dc.openStmt[si] = true
-	}
-	return si, err
-}
-
-// the dc.db's Mutex is held.
-func (dc *driverConn) closeDBLocked() func() error {
-	dc.Lock()
-	defer dc.Unlock()
-	if dc.closed {
-		return func() error { return errors.New("sql: duplicate driverConn close") }
-	}
-	dc.closed = true
-	return dc.db.removeDepLocked(dc, dc)
-}
-
-func (dc *driverConn) Close() error {
-	dc.Lock()
-	if dc.closed {
-		dc.Unlock()
-		return errors.New("sql: duplicate driverConn close")
-	}
-	dc.closed = true
-	dc.Unlock() // not defer; removeDep finalClose calls may need to lock
-
-	// And now updates that require holding dc.mu.Lock.
-	dc.db.mu.Lock()
-	dc.dbmuClosed = true
-	fn := dc.db.removeDepLocked(dc, dc)
-	dc.db.mu.Unlock()
-	return fn()
-}
-
-func (dc *driverConn) finalClose() error {
-	dc.Lock()
-
-	for si := range dc.openStmt {
-		si.Close()
-	}
-	dc.openStmt = nil
-
-	err := dc.ci.Close()
-	dc.ci = nil
-	dc.finalClosed = true
-	dc.Unlock()
-
-	dc.db.mu.Lock()
-	dc.db.numOpen--
-	dc.db.maybeOpenNewConnections()
-	dc.db.mu.Unlock()
-
-	return err
-}
-
-// driverStmt associates a driver.Stmt with the
-// *driverConn from which it came, so the driverConn's lock can be
-// held during calls.
-type driverStmt struct {
-	sync.Locker // the *driverConn
-	si          driver.Stmt
-}
-
-func (ds *driverStmt) Close() error {
-	ds.Lock()
-	defer ds.Unlock()
-	return ds.si.Close()
-}
-
-// depSet is a finalCloser's outstanding dependencies
-type depSet map[interface{}]bool // set of true bools
-
-// The finalCloser interface is used by (*DB).addDep and related
-// dependency reference counting.
-type finalCloser interface {
-	// finalClose is called when the reference count of an object
-	// goes to zero. (*DB).mu is not held while calling it.
-	finalClose() error
-}
-
-// addDep notes that x now depends on dep, and x's finalClose won't be
-// called until all of x's dependencies are removed with removeDep.
-func (db *DB) addDep(x finalCloser, dep interface{}) {
-	//println(fmt.Sprintf("addDep(%T %p, %T %p)", x, x, dep, dep))
-	db.mu.Lock()
-	defer db.mu.Unlock()
-	db.addDepLocked(x, dep)
-}
-
-func (db *DB) addDepLocked(x finalCloser, dep interface{}) {
-	if db.dep == nil {
-		db.dep = make(map[finalCloser]depSet)
-	}
-	xdep := db.dep[x]
-	if xdep == nil {
-		xdep = make(depSet)
-		db.dep[x] = xdep
-	}
-	xdep[dep] = true
-}
-
-// removeDep notes that x no longer depends on dep.
-// If x still has dependencies, nil is returned.
-// If x no longer has any dependencies, its finalClose method will be
-// called and its error value will be returned.
-func (db *DB) removeDep(x finalCloser, dep interface{}) error {
-	db.mu.Lock()
-	fn := db.removeDepLocked(x, dep)
-	db.mu.Unlock()
-	return fn()
-}
-
-func (db *DB) removeDepLocked(x finalCloser, dep interface{}) func() error {
-	//println(fmt.Sprintf("removeDep(%T %p, %T %p)", x, x, dep, dep))
-
-	xdep, ok := db.dep[x]
-	if !ok {
-		panic(fmt.Sprintf("unpaired removeDep: no deps for %T", x))
-	}
-
-	l0 := len(xdep)
-	delete(xdep, dep)
-
-	switch len(xdep) {
-	case l0:
-		// Nothing removed. Shouldn't happen.
-		panic(fmt.Sprintf("unpaired removeDep: no %T dep on %T", dep, x))
-	case 0:
-		// No more dependencies.
-		delete(db.dep, x)
-		return x.finalClose
-	default:
-		// Dependencies remain.
-		return func() error { return nil }
-	}
-}
-
-// This is the size of the connectionOpener request chan (dn.openerCh).
-// This value should be larger than the maximum typical value
-// used for db.maxOpen. If maxOpen is significantly larger than
-// connectionRequestQueueSize then it is possible for ALL calls into the *DB
-// to block until the connectionOpener can satisfy the backlog of requests.
-var connectionRequestQueueSize = 1000000
-
-// Open opens a database specified by its database driver name and a
-// driver-specific data source name, usually consisting of at least a
-// database name and connection information.
-//
-// Most users will open a database via a driver-specific connection
-// helper function that returns a *DB. No database drivers are included
-// in the Go standard library. See http://golang.org/s/sqldrivers for
-// a list of third-party drivers.
-//
-// Open may just validate its arguments without creating a connection
-// to the database. To verify that the data source name is valid, call
-// Ping.
-//
-// The returned DB is safe for concurrent use by multiple goroutines
-// and maintains its own pool of idle connections. Thus, the Open
-// function should be called just once. It is rarely necessary to
-// close a DB.
-func Open(driverName, dataSourceName string) (*DB, error) {
-	driveri, ok := drivers[driverName]
-	if !ok {
-		return nil, fmt.Errorf("sql: unknown driver %q (forgotten import?)", driverName)
-	}
-	db := &DB{
-		driver:   driveri,
-		dsn:      dataSourceName,
-		openerCh: make(chan struct{}, connectionRequestQueueSize),
-		lastPut:  make(map[*driverConn]string),
-	}
-	db.freeConn = list.New()
-	db.connRequests = list.New()
-	go db.connectionOpener()
-	return db, nil
-}
-
-// Ping verifies a connection to the database is still alive,
-// establishing a connection if necessary.
-func (db *DB) Ping() error {
-	// TODO(bradfitz): give drivers an optional hook to implement
-	// this in a more efficient or more reliable way, if they
-	// have one.
-	dc, err := db.conn()
-	if err != nil {
-		return err
-	}
-	db.putConn(dc, nil)
-	return nil
-}
-
-// Close closes the database, releasing any open resources.
-//
-// It is rare to Close a DB, as the DB handle is meant to be
-// long-lived and shared between many goroutines.
-func (db *DB) Close() error {
-	db.mu.Lock()
-	if db.closed { // Make DB.Close idempotent
-		db.mu.Unlock()
-		return nil
-	}
-	close(db.openerCh)
-	var err error
-	fns := make([]func() error, 0, db.freeConn.Len())
-	for db.freeConn.Front() != nil {
-		dc := db.freeConn.Front().Value.(*driverConn)
-		dc.listElem = nil
-		fns = append(fns, dc.closeDBLocked())
-		db.freeConn.Remove(db.freeConn.Front())
-	}
-	db.closed = true
-	for db.connRequests.Front() != nil {
-		req := db.connRequests.Front().Value.(connRequest)
-		db.connRequests.Remove(db.connRequests.Front())
-		close(req)
-	}
-	db.mu.Unlock()
-	for _, fn := range fns {
-		err1 := fn()
-		if err1 != nil {
-			err = err1
-		}
-	}
-	return err
-}
-
-const defaultMaxIdleConns = 2
-
-func (db *DB) maxIdleConnsLocked() int {
-	n := db.maxIdle
-	switch {
-	case n == 0:
-		// TODO(bradfitz): ask driver, if supported, for its default preference
-		return defaultMaxIdleConns
-	case n < 0:
-		return 0
-	default:
-		return n
-	}
-}
-
-// SetMaxIdleConns sets the maximum number of connections in the idle
-// connection pool.
-//
-// If MaxOpenConns is greater than 0 but less than the new MaxIdleConns
-// then the new MaxIdleConns will be reduced to match the MaxOpenConns limit
-//
-// If n <= 0, no idle connections are retained.
-func (db *DB) SetMaxIdleConns(n int) {
-	db.mu.Lock()
-	if n > 0 {
-		db.maxIdle = n
-	} else {
-		// No idle connections.
-		db.maxIdle = -1
-	}
-	// Make sure maxIdle doesn't exceed maxOpen
-	if db.maxOpen > 0 && db.maxIdleConnsLocked() > db.maxOpen {
-		db.maxIdle = db.maxOpen
-	}
-	var closing []*driverConn
-	for db.freeConn.Len() > db.maxIdleConnsLocked() {
-		dc := db.freeConn.Back().Value.(*driverConn)
-		dc.listElem = nil
-		db.freeConn.Remove(db.freeConn.Back())
-		closing = append(closing, dc)
-	}
-	db.mu.Unlock()
-	for _, c := range closing {
-		c.Close()
-	}
-}
-
-// SetMaxOpenConns sets the maximum number of open connections to the database.
-//
-// If MaxIdleConns is greater than 0 and the new MaxOpenConns is less than
-// MaxIdleConns, then MaxIdleConns will be reduced to match the new
-// MaxOpenConns limit
-//
-// If n <= 0, then there is no limit on the number of open connections.
-// The default is 0 (unlimited).
-func (db *DB) SetMaxOpenConns(n int) {
-	db.mu.Lock()
-	db.maxOpen = n
-	if n < 0 {
-		db.maxOpen = 0
-	}
-	syncMaxIdle := db.maxOpen > 0 && db.maxIdleConnsLocked() > db.maxOpen
-	db.mu.Unlock()
-	if syncMaxIdle {
-		db.SetMaxIdleConns(n)
-	}
-}
-
-// Assumes db.mu is locked.
-// If there are connRequests and the connection limit hasn't been reached,
-// then tell the connectionOpener to open new connections.
-func (db *DB) maybeOpenNewConnections() {
-	numRequests := db.connRequests.Len() - db.pendingOpens
-	if db.maxOpen > 0 {
-		numCanOpen := db.maxOpen - (db.numOpen + db.pendingOpens)
-		if numRequests > numCanOpen {
-			numRequests = numCanOpen
-		}
-	}
-	for numRequests > 0 {
-		db.pendingOpens++
-		numRequests--
-		db.openerCh <- struct{}{}
-	}
-}
-
-// Runs in a separate goroutine, opens new connections when requested.
-func (db *DB) connectionOpener() {
-	for _ = range db.openerCh {
-		db.openNewConnection()
-	}
-}
-
-// Open one new connection
-func (db *DB) openNewConnection() {
-	ci, err := db.driver.Open(db.dsn)
-	db.mu.Lock()
-	defer db.mu.Unlock()
-	if db.closed {
-		if err == nil {
-			ci.Close()
-		}
-		return
-	}
-	db.pendingOpens--
-	if err != nil {
-		db.putConnDBLocked(nil, err)
-		return
-	}
-	dc := &driverConn{
-		db: db,
-		ci: ci,
-	}
-	if db.putConnDBLocked(dc, err) {
-		db.addDepLocked(dc, dc)
-		db.numOpen++
-	} else {
-		ci.Close()
-	}
-}
-
-// connRequest represents one request for a new connection
-// When there are no idle connections available, DB.conn will create
-// a new connRequest and put it on the db.connRequests list.
-type connRequest chan<- interface{} // takes either a *driverConn or an error
-
-var errDBClosed = errors.New("sql: database is closed")
-
-// conn returns a newly-opened or cached *driverConn
-func (db *DB) conn() (*driverConn, error) {
-	db.mu.Lock()
-	if db.closed {
-		db.mu.Unlock()
-		return nil, errDBClosed
-	}
-
-	// If db.maxOpen > 0 and the number of open connections is over the limit
-	// and there are no free connection, make a request and wait.
-	if db.maxOpen > 0 && db.numOpen >= db.maxOpen && db.freeConn.Len() == 0 {
-		// Make the connRequest channel. It's buffered so that the
-		// connectionOpener doesn't block while waiting for the req to be read.
-		ch := make(chan interface{}, 1)
-		req := connRequest(ch)
-		db.connRequests.PushBack(req)
-		db.maybeOpenNewConnections()
-		db.mu.Unlock()
-		ret, ok := <-ch
-		if !ok {
-			return nil, errDBClosed
-		}
-		switch ret.(type) {
-		case *driverConn:
-			return ret.(*driverConn), nil
-		case error:
-			return nil, ret.(error)
-		default:
-			panic("sql: Unexpected type passed through connRequest.ch")
-		}
-	}
-
-	if f := db.freeConn.Front(); f != nil {
-		conn := f.Value.(*driverConn)
-		conn.listElem = nil
-		db.freeConn.Remove(f)
-		conn.inUse = true
-		db.mu.Unlock()
-		return conn, nil
-	}
-
-	db.numOpen++ // optimistically
-	db.mu.Unlock()
-	ci, err := db.driver.Open(db.dsn)
-	if err != nil {
-		db.mu.Lock()
-		db.numOpen-- // correct for earlier optimism
-		db.mu.Unlock()
-		return nil, err
-	}
-	db.mu.Lock()
-	dc := &driverConn{
-		db: db,
-		ci: ci,
-	}
-	db.addDepLocked(dc, dc)
-	dc.inUse = true
-	db.mu.Unlock()
-	return dc, nil
-}
-
-var (
-	errConnClosed = errors.New("database/sql: internal sentinel error: conn is closed")
-	errConnBusy   = errors.New("database/sql: internal sentinel error: conn is busy")
-)
-
-// connIfFree returns (wanted, nil) if wanted is still a valid conn and
-// isn't in use.
-//
-// The error is errConnClosed if the connection if the requested connection
-// is invalid because it's been closed.
-//
-// The error is errConnBusy if the connection is in use.
-func (db *DB) connIfFree(wanted *driverConn) (*driverConn, error) {
-	db.mu.Lock()
-	defer db.mu.Unlock()
-	if wanted.dbmuClosed {
-		return nil, errConnClosed
-	}
-	if wanted.inUse {
-		return nil, errConnBusy
-	}
-	if wanted.listElem != nil {
-		db.freeConn.Remove(wanted.listElem)
-		wanted.listElem = nil
-		wanted.inUse = true
-		return wanted, nil
-	}
-	// TODO(bradfitz): shouldn't get here. After Go 1.1, change this to:
-	// panic("connIfFree call requested a non-closed, non-busy, non-free conn")
-	// Which passes all the tests, but I'm too paranoid to include this
-	// late in Go 1.1.
-	// Instead, treat it like a busy connection:
-	return nil, errConnBusy
-}
-
-// putConnHook is a hook for testing.
-var putConnHook func(*DB, *driverConn)
-
-// noteUnusedDriverStatement notes that si is no longer used and should
-// be closed whenever possible (when c is next not in use), unless c is
-// already closed.
-func (db *DB) noteUnusedDriverStatement(c *driverConn, si driver.Stmt) {
-	db.mu.Lock()
-	defer db.mu.Unlock()
-	if c.inUse {
-		c.onPut = append(c.onPut, func() {
-			si.Close()
-		})
-	} else {
-		c.Lock()
-		defer c.Unlock()
-		if !c.finalClosed {
-			si.Close()
-		}
-	}
-}
-
-// debugGetPut determines whether getConn & putConn calls' stack traces
-// are returned for more verbose crashes.
-const debugGetPut = false
-
-// putConn adds a connection to the db's free pool.
-// err is optionally the last error that occurred on this connection.
-func (db *DB) putConn(dc *driverConn, err error) {
-	db.mu.Lock()
-	if !dc.inUse {
-		if debugGetPut {
-			fmt.Printf("putConn(%v) DUPLICATE was: %s\n\nPREVIOUS was: %s", dc, stack(), db.lastPut[dc])
-		}
-		panic("sql: connection returned that was never out")
-	}
-	if debugGetPut {
-		db.lastPut[dc] = stack()
-	}
-	dc.inUse = false
-
-	for _, fn := range dc.onPut {
-		fn()
-	}
-	dc.onPut = nil
-
-	if err == driver.ErrBadConn {
-		// Don't reuse bad connections.
-		// Since the conn is considered bad and is being discarded, treat it
-		// as closed. Don't decrement the open count here, finalClose will
-		// take care of that.
-		db.maybeOpenNewConnections()
-		db.mu.Unlock()
-		dc.Close()
-		return
-	}
-	if putConnHook != nil {
-		putConnHook(db, dc)
-	}
-	added := db.putConnDBLocked(dc, nil)
-	db.mu.Unlock()
-
-	if !added {
-		dc.Close()
-	}
-}
-
-// Satisfy a connRequest or put the driverConn in the idle pool and return true
-// or return false.
-// putConnDBLocked will satisfy a connRequest if there is one, or it will
-// return the *driverConn to the freeConn list if err == nil and the idle
-// connection limit will not be exceeded.
-// If err != nil, the value of dc is ignored.
-// If err == nil, then dc must not equal nil.
-// If a connRequest was fulfilled or the *driverConn was placed in the
-// freeConn list, then true is returned, otherwise false is returned.
-func (db *DB) putConnDBLocked(dc *driverConn, err error) bool {
-	if db.connRequests.Len() > 0 {
-		req := db.connRequests.Front().Value.(connRequest)
-		db.connRequests.Remove(db.connRequests.Front())
-		if err != nil {
-			req <- err
-		} else {
-			dc.inUse = true
-			req <- dc
-		}
-		return true
-	} else if err == nil && !db.closed && db.maxIdleConnsLocked() > db.freeConn.Len() {
-		dc.listElem = db.freeConn.PushFront(dc)
-		return true
-	}
-	return false
-}
-
-// maxBadConnRetries is the number of maximum retries if the driver returns
-// driver.ErrBadConn to signal a broken connection.
-const maxBadConnRetries = 10
-
-// Prepare creates a prepared statement for later queries or executions.
-// Multiple queries or executions may be run concurrently from the
-// returned statement.
-func (db *DB) Prepare(query string) (*Stmt, error) {
-	var stmt *Stmt
-	var err error
-	for i := 0; i < maxBadConnRetries; i++ {
-		stmt, err = db.prepare(query)
-		if err != driver.ErrBadConn {
-			break
-		}
-	}
-	return stmt, err
-}
-
-func (db *DB) prepare(query string) (*Stmt, error) {
-	// TODO: check if db.driver supports an optional
-	// driver.Preparer interface and call that instead, if so,
-	// otherwise we make a prepared statement that's bound
-	// to a connection, and to execute this prepared statement
-	// we either need to use this connection (if it's free), else
-	// get a new connection + re-prepare + execute on that one.
-	dc, err := db.conn()
-	if err != nil {
-		return nil, err
-	}
-	dc.Lock()
-	si, err := dc.prepareLocked(query)
-	dc.Unlock()
-	if err != nil {
-		db.putConn(dc, err)
-		return nil, err
-	}
-	stmt := &Stmt{
-		db:    db,
-		query: query,
-		css:   []connStmt{{dc, si}},
-	}
-	db.addDep(stmt, stmt)
-	db.putConn(dc, nil)
-	return stmt, nil
-}
-
-// Exec executes a query without returning any rows.
-// The args are for any placeholder parameters in the query.
-func (db *DB) Exec(query string, args ...interface{}) (Result, error) {
-	var res Result
-	var err error
-	for i := 0; i < maxBadConnRetries; i++ {
-		res, err = db.exec(query, args)
-		if err != driver.ErrBadConn {
-			break
-		}
-	}
-	return res, err
-}
-
-func (db *DB) exec(query string, args []interface{}) (res Result, err error) {
-	dc, err := db.conn()
-	if err != nil {
-		return nil, err
-	}
-	defer func() {
-		db.putConn(dc, err)
-	}()
-
-	if execer, ok := dc.ci.(driver.Execer); ok {
-		dargs, err := driverArgs(nil, args)
-		if err != nil {
-			return nil, err
-		}
-		dc.Lock()
-		resi, err := execer.Exec(query, dargs)
-		dc.Unlock()
-		if err != driver.ErrSkip {
-			if err != nil {
-				return nil, err
-			}
-			return driverResult{dc, resi}, nil
-		}
-	}
-
-	dc.Lock()
-	si, err := dc.ci.Prepare(query)
-	dc.Unlock()
-	if err != nil {
-		return nil, err
-	}
-	defer withLock(dc, func() { si.Close() })
-	return resultFromStatement(driverStmt{dc, si}, args...)
-}
-
-// Query executes a query that returns rows, typically a SELECT.
-// The args are for any placeholder parameters in the query.
-func (db *DB) Query(query string, args ...interface{}) (*Rows, error) {
-	var rows *Rows
-	var err error
-	for i := 0; i < maxBadConnRetries; i++ {
-		rows, err = db.query(query, args)
-		if err != driver.ErrBadConn {
-			break
-		}
-	}
-	return rows, err
-}
-
-func (db *DB) query(query string, args []interface{}) (*Rows, error) {
-	ci, err := db.conn()
-	if err != nil {
-		return nil, err
-	}
-
-	return db.queryConn(ci, ci.releaseConn, query, args)
-}
-
-// queryConn executes a query on the given connection.
-// The connection gets released by the releaseConn function.
-func (db *DB) queryConn(dc *driverConn, releaseConn func(error), query string, args []interface{}) (*Rows, error) {
-	if queryer, ok := dc.ci.(driver.Queryer); ok {
-		dargs, err := driverArgs(nil, args)
-		if err != nil {
-			releaseConn(err)
-			return nil, err
-		}
-		dc.Lock()
-		rowsi, err := queryer.Query(query, dargs)
-		dc.Unlock()
-		if err != driver.ErrSkip {
-			if err != nil {
-				releaseConn(err)
-				return nil, err
-			}
-			// Note: ownership of dc passes to the *Rows, to be freed
-			// with releaseConn.
-			rows := &Rows{
-				dc:          dc,
-				releaseConn: releaseConn,
-				rowsi:       rowsi,
-			}
-			return rows, nil
-		}
-	}
-
-	dc.Lock()
-	si, err := dc.ci.Prepare(query)
-	dc.Unlock()
-	if err != nil {
-		releaseConn(err)
-		return nil, err
-	}
-
-	ds := driverStmt{dc, si}
-	rowsi, err := rowsiFromStatement(ds, args...)
-	if err != nil {
-		dc.Lock()
-		si.Close()
-		dc.Unlock()
-		releaseConn(err)
-		return nil, err
-	}
-
-	// Note: ownership of ci passes to the *Rows, to be freed
-	// with releaseConn.
-	rows := &Rows{
-		dc:          dc,
-		releaseConn: releaseConn,
-		rowsi:       rowsi,
-		closeStmt:   si,
-	}
-	return rows, nil
-}
-
-// QueryRow executes a query that is expected to return at most one row.
-// QueryRow always return a non-nil value. Errors are deferred until
-// Row's Scan method is called.
-func (db *DB) QueryRow(query string, args ...interface{}) *Row {
-	rows, err := db.Query(query, args...)
-	return &Row{rows: rows, err: err}
-}
-
-// Begin starts a transaction. The isolation level is dependent on
-// the driver.
-func (db *DB) Begin() (*Tx, error) {
-	var tx *Tx
-	var err error
-	for i := 0; i < maxBadConnRetries; i++ {
-		tx, err = db.begin()
-		if err != driver.ErrBadConn {
-			break
-		}
-	}
-	return tx, err
-}
-
-func (db *DB) begin() (tx *Tx, err error) {
-	dc, err := db.conn()
-	if err != nil {
-		return nil, err
-	}
-	dc.Lock()
-	txi, err := dc.ci.Begin()
-	dc.Unlock()
-	if err != nil {
-		db.putConn(dc, err)
-		return nil, err
-	}
-	return &Tx{
-		db:  db,
-		dc:  dc,
-		txi: txi,
-	}, nil
-}
-
-// Driver returns the database's underlying driver.
-func (db *DB) Driver() driver.Driver {
-	return db.driver
-}
-
-// Tx is an in-progress database transaction.
-//
-// A transaction must end with a call to Commit or Rollback.
-//
-// After a call to Commit or Rollback, all operations on the
-// transaction fail with ErrTxDone.
-type Tx struct {
-	db *DB
-
-	// dc is owned exclusively until Commit or Rollback, at which point
-	// it's returned with putConn.
-	dc  *driverConn
-	txi driver.Tx
-
-	// done transitions from false to true exactly once, on Commit
-	// or Rollback. once done, all operations fail with
-	// ErrTxDone.
-	done bool
-}
-
-var ErrTxDone = errors.New("sql: Transaction has already been committed or rolled back")
-
-func (tx *Tx) close() {
-	if tx.done {
-		panic("double close") // internal error
-	}
-	tx.done = true
-	tx.db.putConn(tx.dc, nil)
-	tx.dc = nil
-	tx.txi = nil
-}
-
-func (tx *Tx) grabConn() (*driverConn, error) {
-	if tx.done {
-		return nil, ErrTxDone
-	}
-	return tx.dc, nil
-}
-
-// Commit commits the transaction.
-func (tx *Tx) Commit() error {
-	if tx.done {
-		return ErrTxDone
-	}
-	defer tx.close()
-	tx.dc.Lock()
-	defer tx.dc.Unlock()
-	return tx.txi.Commit()
-}
-
-// Rollback aborts the transaction.
-func (tx *Tx) Rollback() error {
-	if tx.done {
-		return ErrTxDone
-	}
-	defer tx.close()
-	tx.dc.Lock()
-	defer tx.dc.Unlock()
-	return tx.txi.Rollback()
-}
-
-// Prepare creates a prepared statement for use within a transaction.
-//
-// The returned statement operates within the transaction and can no longer
-// be used once the transaction has been committed or rolled back.
-//
-// To use an existing prepared statement on this transaction, see Tx.Stmt.
-func (tx *Tx) Prepare(query string) (*Stmt, error) {
-	// TODO(bradfitz): We could be more efficient here and either
-	// provide a method to take an existing Stmt (created on
-	// perhaps a different Conn), and re-create it on this Conn if
-	// necessary. Or, better: keep a map in DB of query string to
-	// Stmts, and have Stmt.Execute do the right thing and
-	// re-prepare if the Conn in use doesn't have that prepared
-	// statement.  But we'll want to avoid caching the statement
-	// in the case where we only call conn.Prepare implicitly
-	// (such as in db.Exec or tx.Exec), but the caller package
-	// can't be holding a reference to the returned statement.
-	// Perhaps just looking at the reference count (by noting
-	// Stmt.Close) would be enough. We might also want a finalizer
-	// on Stmt to drop the reference count.
-	dc, err := tx.grabConn()
-	if err != nil {
-		return nil, err
-	}
-
-	dc.Lock()
-	si, err := dc.ci.Prepare(query)
-	dc.Unlock()
-	if err != nil {
-		return nil, err
-	}
-
-	stmt := &Stmt{
-		db: tx.db,
-		tx: tx,
-		txsi: &driverStmt{
-			Locker: dc,
-			si:     si,
-		},
-		query: query,
-	}
-	return stmt, nil
-}
-
-// Stmt returns a transaction-specific prepared statement from
-// an existing statement.
-//
-// Example:
-//  updateMoney, err := db.Prepare("UPDATE balance SET money=money+? WHERE id=?")
-//  ...
-//  tx, err := db.Begin()
-//  ...
-//  res, err := tx.Stmt(updateMoney).Exec(123.45, 98293203)
-func (tx *Tx) Stmt(stmt *Stmt) *Stmt {
-	// TODO(bradfitz): optimize this. Currently this re-prepares
-	// each time.  This is fine for now to illustrate the API but
-	// we should really cache already-prepared statements
-	// per-Conn. See also the big comment in Tx.Prepare.
-
-	if tx.db != stmt.db {
-		return &Stmt{stickyErr: errors.New("sql: Tx.Stmt: statement from different database used")}
-	}
-	dc, err := tx.grabConn()
-	if err != nil {
-		return &Stmt{stickyErr: err}
-	}
-	dc.Lock()
-	si, err := dc.ci.Prepare(stmt.query)
-	dc.Unlock()
-	return &Stmt{
-		db: tx.db,
-		tx: tx,
-		txsi: &driverStmt{
-			Locker: dc,
-			si:     si,
-		},
-		query:     stmt.query,
-		stickyErr: err,
-	}
-}
-
-// Exec executes a query that doesn't return rows.
-// For example: an INSERT and UPDATE.
-func (tx *Tx) Exec(query string, args ...interface{}) (Result, error) {
-	dc, err := tx.grabConn()
-	if err != nil {
-		return nil, err
-	}
-
-	if execer, ok := dc.ci.(driver.Execer); ok {
-		dargs, err := driverArgs(nil, args)
-		if err != nil {
-			return nil, err
-		}
-		dc.Lock()
-		resi, err := execer.Exec(query, dargs)
-		dc.Unlock()
-		if err == nil {
-			return driverResult{dc, resi}, nil
-		}
-		if err != driver.ErrSkip {
-			return nil, err
-		}
-	}
-
-	dc.Lock()
-	si, err := dc.ci.Prepare(query)
-	dc.Unlock()
-	if err != nil {
-		return nil, err
-	}
-	defer withLock(dc, func() { si.Close() })
-
-	return resultFromStatement(driverStmt{dc, si}, args...)
-}
-
-// Query executes a query that returns rows, typically a SELECT.
-func (tx *Tx) Query(query string, args ...interface{}) (*Rows, error) {
-	dc, err := tx.grabConn()
-	if err != nil {
-		return nil, err
-	}
-	releaseConn := func(error) {}
-	return tx.db.queryConn(dc, releaseConn, query, args)
-}
-
-// QueryRow executes a query that is expected to return at most one row.
-// QueryRow always return a non-nil value. Errors are deferred until
-// Row's Scan method is called.
-func (tx *Tx) QueryRow(query string, args ...interface{}) *Row {
-	rows, err := tx.Query(query, args...)
-	return &Row{rows: rows, err: err}
-}
-
-// connStmt is a prepared statement on a particular connection.
-type connStmt struct {
-	dc *driverConn
-	si driver.Stmt
-}
-
-// Stmt is a prepared statement. Stmt is safe for concurrent use by multiple goroutines.
-type Stmt struct {
-	// Immutable:
-	db        *DB    // where we came from
-	query     string // that created the Stmt
-	stickyErr error  // if non-nil, this error is returned for all operations
-
-	closemu sync.RWMutex // held exclusively during close, for read otherwise.
-
-	// If in a transaction, else both nil:
-	tx   *Tx
-	txsi *driverStmt
-
-	mu     sync.Mutex // protects the rest of the fields
-	closed bool
-
-	// css is a list of underlying driver statement interfaces
-	// that are valid on particular connections.  This is only
-	// used if tx == nil and one is found that has idle
-	// connections.  If tx != nil, txsi is always used.
-	css []connStmt
-}
-
-// Exec executes a prepared statement with the given arguments and
-// returns a Result summarizing the effect of the statement.
-func (s *Stmt) Exec(args ...interface{}) (Result, error) {
-	s.closemu.RLock()
-	defer s.closemu.RUnlock()
-
-	var res Result
-	for i := 0; i < maxBadConnRetries; i++ {
-		dc, releaseConn, si, err := s.connStmt()
-		if err != nil {
-			if err == driver.ErrBadConn {
-				continue
-			}
-			return nil, err
-		}
-
-		res, err = resultFromStatement(driverStmt{dc, si}, args...)
-		releaseConn(err)
-		if err != driver.ErrBadConn {
-			return res, err
-		}
-	}
-	return nil, driver.ErrBadConn
-}
-
-func resultFromStatement(ds driverStmt, args ...interface{}) (Result, error) {
-	ds.Lock()
-	want := ds.si.NumInput()
-	ds.Unlock()
-
-	// -1 means the driver doesn't know how to count the number of
-	// placeholders, so we won't sanity check input here and instead let the
-	// driver deal with errors.
-	if want != -1 && len(args) != want {
-		return nil, fmt.Errorf("sql: expected %d arguments, got %d", want, len(args))
-	}
-
-	dargs, err := driverArgs(&ds, args)
-	if err != nil {
-		return nil, err
-	}
-
-	ds.Lock()
-	resi, err := ds.si.Exec(dargs)
-	ds.Unlock()
-	if err != nil {
-		return nil, err
-	}
-	return driverResult{ds.Locker, resi}, nil
-}
-
-// connStmt returns a free driver connection on which to execute the
-// statement, a function to call to release the connection, and a
-// statement bound to that connection.
-func (s *Stmt) connStmt() (ci *driverConn, releaseConn func(error), si driver.Stmt, err error) {
-	if err = s.stickyErr; err != nil {
-		return
-	}
-	s.mu.Lock()
-	if s.closed {
-		s.mu.Unlock()
-		err = errors.New("sql: statement is closed")
-		return
-	}
-
-	// In a transaction, we always use the connection that the
-	// transaction was created on.
-	if s.tx != nil {
-		s.mu.Unlock()
-		ci, err = s.tx.grabConn() // blocks, waiting for the connection.
-		if err != nil {
-			return
-		}
-		releaseConn = func(error) {}
-		return ci, releaseConn, s.txsi.si, nil
-	}
-
-	var cs connStmt
-	match := false
-	for i := 0; i < len(s.css); i++ {
-		v := s.css[i]
-		_, err := s.db.connIfFree(v.dc)
-		if err == nil {
-			match = true
-			cs = v
-			break
-		}
-		if err == errConnClosed {
-			// Lazily remove dead conn from our freelist.
-			s.css[i] = s.css[len(s.css)-1]
-			s.css = s.css[:len(s.css)-1]
-			i--
-		}
-
-	}
-	s.mu.Unlock()
-
-	// Make a new conn if all are busy.
-	// TODO(bradfitz): or wait for one? make configurable later?
-	if !match {
-		dc, err := s.db.conn()
-		if err != nil {
-			return nil, nil, nil, err
-		}
-		dc.Lock()
-		si, err := dc.prepareLocked(s.query)
-		dc.Unlock()
-		if err != nil {
-			s.db.putConn(dc, err)
-			return nil, nil, nil, err
-		}
-		s.mu.Lock()
-		cs = connStmt{dc, si}
-		s.css = append(s.css, cs)
-		s.mu.Unlock()
-	}
-
-	conn := cs.dc
-	return conn, conn.releaseConn, cs.si, nil
-}
-
-// Query executes a prepared query statement with the given arguments
-// and returns the query results as a *Rows.
-func (s *Stmt) Query(args ...interface{}) (*Rows, error) {
-	s.closemu.RLock()
-	defer s.closemu.RUnlock()
-
-	var rowsi driver.Rows
-	for i := 0; i < maxBadConnRetries; i++ {
-		dc, releaseConn, si, err := s.connStmt()
-		if err != nil {
-			if err == driver.ErrBadConn {
-				continue
-			}
-			return nil, err
-		}
-
-		rowsi, err = rowsiFromStatement(driverStmt{dc, si}, args...)
-		if err == nil {
-			// Note: ownership of ci passes to the *Rows, to be freed
-			// with releaseConn.
-			rows := &Rows{
-				dc:    dc,
-				rowsi: rowsi,
-				// releaseConn set below
-			}
-			s.db.addDep(s, rows)
-			rows.releaseConn = func(err error) {
-				releaseConn(err)
-				s.db.removeDep(s, rows)
-			}
-			return rows, nil
-		}
-
-		releaseConn(err)
-		if err != driver.ErrBadConn {
-			return nil, err
-		}
-	}
-	return nil, driver.ErrBadConn
-}
-
-func rowsiFromStatement(ds driverStmt, args ...interface{}) (driver.Rows, error) {
-	ds.Lock()
-	want := ds.si.NumInput()
-	ds.Unlock()
-
-	// -1 means the driver doesn't know how to count the number of
-	// placeholders, so we won't sanity check input here and instead let the
-	// driver deal with errors.
-	if want != -1 && len(args) != want {
-		return nil, fmt.Errorf("sql: statement expects %d inputs; got %d", want, len(args))
-	}
-
-	dargs, err := driverArgs(&ds, args)
-	if err != nil {
-		return nil, err
-	}
-
-	ds.Lock()
-	rowsi, err := ds.si.Query(dargs)
-	ds.Unlock()
-	if err != nil {
-		return nil, err
-	}
-	return rowsi, nil
-}
-
-// QueryRow executes a prepared query statement with the given arguments.
-// If an error occurs during the execution of the statement, that error will
-// be returned by a call to Scan on the returned *Row, which is always non-nil.
-// If the query selects no rows, the *Row's Scan will return ErrNoRows.
-// Otherwise, the *Row's Scan scans the first selected row and discards
-// the rest.
-//
-// Example usage:
-//
-//  var name string
-//  err := nameByUseridStmt.QueryRow(id).Scan(&name)
-func (s *Stmt) QueryRow(args ...interface{}) *Row {
-	rows, err := s.Query(args...)
-	if err != nil {
-		return &Row{err: err}
-	}
-	return &Row{rows: rows}
-}
-
-// Close closes the statement.
-func (s *Stmt) Close() error {
-	s.closemu.Lock()
-	defer s.closemu.Unlock()
-
-	if s.stickyErr != nil {
-		return s.stickyErr
-	}
-	s.mu.Lock()
-	if s.closed {
-		s.mu.Unlock()
-		return nil
-	}
-	s.closed = true
-
-	if s.tx != nil {
-		s.txsi.Close()
-		s.mu.Unlock()
-		return nil
-	}
-	s.mu.Unlock()
-
-	return s.db.removeDep(s, s)
-}
-
-func (s *Stmt) finalClose() error {
-	s.mu.Lock()
-	defer s.mu.Unlock()
-	if s.css != nil {
-		for _, v := range s.css {
-			s.db.noteUnusedDriverStatement(v.dc, v.si)
-			v.dc.removeOpenStmt(v.si)
-		}
-		s.css = nil
-	}
-	return nil
-}
-
-// Rows is the result of a query. Its cursor starts before the first row
-// of the result set. Use Next to advance through the rows:
-//
-//     rows, err := db.Query("SELECT ...")
-//     ...
-//     defer rows.Close()
-//     for rows.Next() {
-//         var id int
-//         var name string
-//         err = rows.Scan(&id, &name)
-//         ...
-//     }
-//     err = rows.Err() // get any error encountered during iteration
-//     ...
-type Rows struct {
-	dc          *driverConn // owned; must call releaseConn when closed to release
-	releaseConn func(error)
-	rowsi       driver.Rows
-
-	closed    bool
-	lastcols  []driver.Value
-	lasterr   error       // non-nil only if closed is true
-	closeStmt driver.Stmt // if non-nil, statement to Close on close
-}
-
-// Next prepares the next result row for reading with the Scan method.  It
-// returns true on success, or false if there is no next result row or an error
-// happened while preparing it.  Err should be consulted to distinguish between
-// the two cases.
-//
-// Every call to Scan, even the first one, must be preceded by a call to Next.
-func (rs *Rows) Next() bool {
-	if rs.closed {
-		return false
-	}
-	if rs.lastcols == nil {
-		rs.lastcols = make([]driver.Value, len(rs.rowsi.Columns()))
-	}
-	rs.lasterr = rs.rowsi.Next(rs.lastcols)
-	if rs.lasterr != nil {
-		rs.Close()
-		return false
-	}
-	return true
-}
-
-// Err returns the error, if any, that was encountered during iteration.
-// Err may be called after an explicit or implicit Close.
-func (rs *Rows) Err() error {
-	if rs.lasterr == io.EOF {
-		return nil
-	}
-	return rs.lasterr
-}
-
-// Columns returns the column names.
-// Columns returns an error if the rows are closed, or if the rows
-// are from QueryRow and there was a deferred error.
-func (rs *Rows) Columns() ([]string, error) {
-	if rs.closed {
-		return nil, errors.New("sql: Rows are closed")
-	}
-	if rs.rowsi == nil {
-		return nil, errors.New("sql: no Rows available")
-	}
-	return rs.rowsi.Columns(), nil
-}
-
-// Scan copies the columns in the current row into the values pointed
-// at by dest.
-//
-// If an argument has type *[]byte, Scan saves in that argument a copy
-// of the corresponding data. The copy is owned by the caller and can
-// be modified and held indefinitely. The copy can be avoided by using
-// an argument of type *RawBytes instead; see the documentation for
-// RawBytes for restrictions on its use.
-//
-// If an argument has type *interface{}, Scan copies the value
-// provided by the underlying driver without conversion. If the value
-// is of type []byte, a copy is made and the caller owns the result.
-func (rs *Rows) Scan(dest ...interface{}) error {
-	if rs.closed {
-		return errors.New("sql: Rows are closed")
-	}
-	if rs.lastcols == nil {
-		return errors.New("sql: Scan called without calling Next")
-	}
-	if len(dest) != len(rs.lastcols) {
-		return fmt.Errorf("sql: expected %d destination arguments in Scan, not %d", len(rs.lastcols), len(dest))
-	}
-	for i, sv := range rs.lastcols {
-		err := convertAssign(dest[i], sv)
-		if err != nil {
-			return fmt.Errorf("sql: Scan error on column index %d: %v", i, err)
-		}
-	}
-	return nil
-}
-
-var rowsCloseHook func(*Rows, *error)
-
-// Close closes the Rows, preventing further enumeration. If Next returns
-// false, the Rows are closed automatically and it will suffice to check the
-// result of Err. Close is idempotent and does not affect the result of Err.
-func (rs *Rows) Close() error {
-	if rs.closed {
-		return nil
-	}
-	rs.closed = true
-	err := rs.rowsi.Close()
-	if fn := rowsCloseHook; fn != nil {
-		fn(rs, &err)
-	}
-	if rs.closeStmt != nil {
-		rs.closeStmt.Close()
-	}
-	rs.releaseConn(err)
-	return err
-}
-
-// Row is the result of calling QueryRow to select a single row.
-type Row struct {
-	// One of these two will be non-nil:
-	err  error // deferred error for easy chaining
-	rows *Rows
-}
-
-// Scan copies the columns from the matched row into the values
-// pointed at by dest.  If more than one row matches the query,
-// Scan uses the first row and discards the rest.  If no row matches
-// the query, Scan returns ErrNoRows.
-func (r *Row) Scan(dest ...interface{}) error {
-	if r.err != nil {
-		return r.err
-	}
-
-	// TODO(bradfitz): for now we need to defensively clone all
-	// []byte that the driver returned (not permitting
-	// *RawBytes in Rows.Scan), since we're about to close
-	// the Rows in our defer, when we return from this function.
-	// the contract with the driver.Next(...) interface is that it
-	// can return slices into read-only temporary memory that's
-	// only valid until the next Scan/Close.  But the TODO is that
-	// for a lot of drivers, this copy will be unnecessary.  We
-	// should provide an optional interface for drivers to
-	// implement to say, "don't worry, the []bytes that I return
-	// from Next will not be modified again." (for instance, if
-	// they were obtained from the network anyway) But for now we
-	// don't care.
-	defer r.rows.Close()
-	for _, dp := range dest {
-		if _, ok := dp.(*RawBytes); ok {
-			return errors.New("sql: RawBytes isn't allowed on Row.Scan")
-		}
-	}
-
-	if !r.rows.Next() {
-		if err := r.rows.Err(); err != nil {
-			return err
-		}
-		return ErrNoRows
-	}
-	err := r.rows.Scan(dest...)
-	if err != nil {
-		return err
-	}
-	// Make sure the query can be processed to completion with no errors.
-	if err := r.rows.Close(); err != nil {
-		return err
-	}
-
-	return nil
-}
-
-// A Result summarizes an executed SQL command.
-type Result interface {
-	// LastInsertId returns the integer generated by the database
-	// in response to a command. Typically this will be from an
-	// "auto increment" column when inserting a new row. Not all
-	// databases support this feature, and the syntax of such
-	// statements varies.
-	LastInsertId() (int64, error)
-
-	// RowsAffected returns the number of rows affected by an
-	// update, insert, or delete. Not every database or database
-	// driver may support this.
-	RowsAffected() (int64, error)
-}
-
-type driverResult struct {
-	sync.Locker // the *driverConn
-	resi        driver.Result
-}
-
-func (dr driverResult) LastInsertId() (int64, error) {
-	dr.Lock()
-	defer dr.Unlock()
-	return dr.resi.LastInsertId()
-}
-
-func (dr driverResult) RowsAffected() (int64, error) {
-	dr.Lock()
-	defer dr.Unlock()
-	return dr.resi.RowsAffected()
-}
-
-func stack() string {
-	var buf [2 << 10]byte
-	return string(buf[:runtime.Stack(buf[:], false)])
-}
-
-// withLock runs while holding lk.
-func withLock(lk sync.Locker, fn func()) {
-	lk.Lock()
-	fn()
-	lk.Unlock()
-}
diff --git a/src/pkg/database/sql/sql_test.go b/src/pkg/database/sql/sql_test.go
deleted file mode 100644
index 7971f14..0000000
--- a/src/pkg/database/sql/sql_test.go
+++ /dev/null
@@ -1,1949 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package sql
-
-import (
-	"database/sql/driver"
-	"errors"
-	"fmt"
-	"math/rand"
-	"reflect"
-	"runtime"
-	"strings"
-	"sync"
-	"testing"
-	"time"
-)
-
-func init() {
-	type dbConn struct {
-		db *DB
-		c  *driverConn
-	}
-	freedFrom := make(map[dbConn]string)
-	putConnHook = func(db *DB, c *driverConn) {
-		if c.listElem != nil {
-			// print before panic, as panic may get lost due to conflicting panic
-			// (all goroutines asleep) elsewhere, since we might not unlock
-			// the mutex in freeConn here.
-			println("double free of conn. conflicts are:\nA) " + freedFrom[dbConn{db, c}] + "\n\nand\nB) " + stack())
-			panic("double free of conn.")
-		}
-		freedFrom[dbConn{db, c}] = stack()
-	}
-}
-
-const fakeDBName = "foo"
-
-var chrisBirthday = time.Unix(123456789, 0)
-
-func newTestDB(t testing.TB, name string) *DB {
-	db, err := Open("test", fakeDBName)
-	if err != nil {
-		t.Fatalf("Open: %v", err)
-	}
-	if _, err := db.Exec("WIPE"); err != nil {
-		t.Fatalf("exec wipe: %v", err)
-	}
-	if name == "people" {
-		exec(t, db, "CREATE|people|name=string,age=int32,photo=blob,dead=bool,bdate=datetime")
-		exec(t, db, "INSERT|people|name=Alice,age=?,photo=APHOTO", 1)
-		exec(t, db, "INSERT|people|name=Bob,age=?,photo=BPHOTO", 2)
-		exec(t, db, "INSERT|people|name=Chris,age=?,photo=CPHOTO,bdate=?", 3, chrisBirthday)
-	}
-	if name == "magicquery" {
-		// Magic table name and column, known by fakedb_test.go.
-		exec(t, db, "CREATE|magicquery|op=string,millis=int32")
-		exec(t, db, "INSERT|magicquery|op=sleep,millis=10")
-	}
-	return db
-}
-
-func exec(t testing.TB, db *DB, query string, args ...interface{}) {
-	_, err := db.Exec(query, args...)
-	if err != nil {
-		t.Fatalf("Exec of %q: %v", query, err)
-	}
-}
-
-func closeDB(t testing.TB, db *DB) {
-	if e := recover(); e != nil {
-		fmt.Printf("Panic: %v\n", e)
-		panic(e)
-	}
-	defer setHookpostCloseConn(nil)
-	setHookpostCloseConn(func(_ *fakeConn, err error) {
-		if err != nil {
-			t.Errorf("Error closing fakeConn: %v", err)
-		}
-	})
-	for node, i := db.freeConn.Front(), 0; node != nil; node, i = node.Next(), i+1 {
-		dc := node.Value.(*driverConn)
-		if n := len(dc.openStmt); n > 0 {
-			// Just a sanity check. This is legal in
-			// general, but if we make the tests clean up
-			// their statements first, then we can safely
-			// verify this is always zero here, and any
-			// other value is a leak.
-			t.Errorf("while closing db, freeConn %d/%d had %d open stmts; want 0", i, db.freeConn.Len(), n)
-		}
-	}
-	err := db.Close()
-	if err != nil {
-		t.Fatalf("error closing DB: %v", err)
-	}
-	db.mu.Lock()
-	count := db.numOpen
-	db.mu.Unlock()
-	if count != 0 {
-		t.Fatalf("%d connections still open after closing DB", db.numOpen)
-	}
-}
-
-// numPrepares assumes that db has exactly 1 idle conn and returns
-// its count of calls to Prepare
-func numPrepares(t *testing.T, db *DB) int {
-	if n := db.freeConn.Len(); n != 1 {
-		t.Fatalf("free conns = %d; want 1", n)
-	}
-	return (db.freeConn.Front().Value.(*driverConn)).ci.(*fakeConn).numPrepare
-}
-
-func (db *DB) numDeps() int {
-	db.mu.Lock()
-	defer db.mu.Unlock()
-	return len(db.dep)
-}
-
-// Dependencies are closed via a goroutine, so this polls waiting for
-// numDeps to fall to want, waiting up to d.
-func (db *DB) numDepsPollUntil(want int, d time.Duration) int {
-	deadline := time.Now().Add(d)
-	for {
-		n := db.numDeps()
-		if n <= want || time.Now().After(deadline) {
-			return n
-		}
-		time.Sleep(50 * time.Millisecond)
-	}
-}
-
-func (db *DB) numFreeConns() int {
-	db.mu.Lock()
-	defer db.mu.Unlock()
-	return db.freeConn.Len()
-}
-
-func (db *DB) dumpDeps(t *testing.T) {
-	for fc := range db.dep {
-		db.dumpDep(t, 0, fc, map[finalCloser]bool{})
-	}
-}
-
-func (db *DB) dumpDep(t *testing.T, depth int, dep finalCloser, seen map[finalCloser]bool) {
-	seen[dep] = true
-	indent := strings.Repeat("  ", depth)
-	ds := db.dep[dep]
-	for k := range ds {
-		t.Logf("%s%T (%p) waiting for -> %T (%p)", indent, dep, dep, k, k)
-		if fc, ok := k.(finalCloser); ok {
-			if !seen[fc] {
-				db.dumpDep(t, depth+1, fc, seen)
-			}
-		}
-	}
-}
-
-func TestQuery(t *testing.T) {
-	db := newTestDB(t, "people")
-	defer closeDB(t, db)
-	prepares0 := numPrepares(t, db)
-	rows, err := db.Query("SELECT|people|age,name|")
-	if err != nil {
-		t.Fatalf("Query: %v", err)
-	}
-	type row struct {
-		age  int
-		name string
-	}
-	got := []row{}
-	for rows.Next() {
-		var r row
-		err = rows.Scan(&r.age, &r.name)
-		if err != nil {
-			t.Fatalf("Scan: %v", err)
-		}
-		got = append(got, r)
-	}
-	err = rows.Err()
-	if err != nil {
-		t.Fatalf("Err: %v", err)
-	}
-	want := []row{
-		{age: 1, name: "Alice"},
-		{age: 2, name: "Bob"},
-		{age: 3, name: "Chris"},
-	}
-	if !reflect.DeepEqual(got, want) {
-		t.Errorf("mismatch.\n got: %#v\nwant: %#v", got, want)
-	}
-
-	// And verify that the final rows.Next() call, which hit EOF,
-	// also closed the rows connection.
-	if n := db.numFreeConns(); n != 1 {
-		t.Fatalf("free conns after query hitting EOF = %d; want 1", n)
-	}
-	if prepares := numPrepares(t, db) - prepares0; prepares != 1 {
-		t.Errorf("executed %d Prepare statements; want 1", prepares)
-	}
-}
-
-func TestByteOwnership(t *testing.T) {
-	db := newTestDB(t, "people")
-	defer closeDB(t, db)
-	rows, err := db.Query("SELECT|people|name,photo|")
-	if err != nil {
-		t.Fatalf("Query: %v", err)
-	}
-	type row struct {
-		name  []byte
-		photo RawBytes
-	}
-	got := []row{}
-	for rows.Next() {
-		var r row
-		err = rows.Scan(&r.name, &r.photo)
-		if err != nil {
-			t.Fatalf("Scan: %v", err)
-		}
-		got = append(got, r)
-	}
-	corruptMemory := []byte("\xffPHOTO")
-	want := []row{
-		{name: []byte("Alice"), photo: corruptMemory},
-		{name: []byte("Bob"), photo: corruptMemory},
-		{name: []byte("Chris"), photo: corruptMemory},
-	}
-	if !reflect.DeepEqual(got, want) {
-		t.Errorf("mismatch.\n got: %#v\nwant: %#v", got, want)
-	}
-
-	var photo RawBytes
-	err = db.QueryRow("SELECT|people|photo|name=?", "Alice").Scan(&photo)
-	if err == nil {
-		t.Error("want error scanning into RawBytes from QueryRow")
-	}
-}
-
-func TestRowsColumns(t *testing.T) {
-	db := newTestDB(t, "people")
-	defer closeDB(t, db)
-	rows, err := db.Query("SELECT|people|age,name|")
-	if err != nil {
-		t.Fatalf("Query: %v", err)
-	}
-	cols, err := rows.Columns()
-	if err != nil {
-		t.Fatalf("Columns: %v", err)
-	}
-	want := []string{"age", "name"}
-	if !reflect.DeepEqual(cols, want) {
-		t.Errorf("got %#v; want %#v", cols, want)
-	}
-	if err := rows.Close(); err != nil {
-		t.Errorf("error closing rows: %s", err)
-	}
-}
-
-func TestQueryRow(t *testing.T) {
-	db := newTestDB(t, "people")
-	defer closeDB(t, db)
-	var name string
-	var age int
-	var birthday time.Time
-
-	err := db.QueryRow("SELECT|people|age,name|age=?", 3).Scan(&age)
-	if err == nil || !strings.Contains(err.Error(), "expected 2 destination arguments") {
-		t.Errorf("expected error from wrong number of arguments; actually got: %v", err)
-	}
-
-	err = db.QueryRow("SELECT|people|bdate|age=?", 3).Scan(&birthday)
-	if err != nil || !birthday.Equal(chrisBirthday) {
-		t.Errorf("chris birthday = %v, err = %v; want %v", birthday, err, chrisBirthday)
-	}
-
-	err = db.QueryRow("SELECT|people|age,name|age=?", 2).Scan(&age, &name)
-	if err != nil {
-		t.Fatalf("age QueryRow+Scan: %v", err)
-	}
-	if name != "Bob" {
-		t.Errorf("expected name Bob, got %q", name)
-	}
-	if age != 2 {
-		t.Errorf("expected age 2, got %d", age)
-	}
-
-	err = db.QueryRow("SELECT|people|age,name|name=?", "Alice").Scan(&age, &name)
-	if err != nil {
-		t.Fatalf("name QueryRow+Scan: %v", err)
-	}
-	if name != "Alice" {
-		t.Errorf("expected name Alice, got %q", name)
-	}
-	if age != 1 {
-		t.Errorf("expected age 1, got %d", age)
-	}
-
-	var photo []byte
-	err = db.QueryRow("SELECT|people|photo|name=?", "Alice").Scan(&photo)
-	if err != nil {
-		t.Fatalf("photo QueryRow+Scan: %v", err)
-	}
-	want := []byte("APHOTO")
-	if !reflect.DeepEqual(photo, want) {
-		t.Errorf("photo = %q; want %q", photo, want)
-	}
-}
-
-func TestStatementErrorAfterClose(t *testing.T) {
-	db := newTestDB(t, "people")
-	defer closeDB(t, db)
-	stmt, err := db.Prepare("SELECT|people|age|name=?")
-	if err != nil {
-		t.Fatalf("Prepare: %v", err)
-	}
-	err = stmt.Close()
-	if err != nil {
-		t.Fatalf("Close: %v", err)
-	}
-	var name string
-	err = stmt.QueryRow("foo").Scan(&name)
-	if err == nil {
-		t.Errorf("expected error from QueryRow.Scan after Stmt.Close")
-	}
-}
-
-func TestStatementQueryRow(t *testing.T) {
-	db := newTestDB(t, "people")
-	defer closeDB(t, db)
-	stmt, err := db.Prepare("SELECT|people|age|name=?")
-	if err != nil {
-		t.Fatalf("Prepare: %v", err)
-	}
-	defer stmt.Close()
-	var age int
-	for n, tt := range []struct {
-		name string
-		want int
-	}{
-		{"Alice", 1},
-		{"Bob", 2},
-		{"Chris", 3},
-	} {
-		if err := stmt.QueryRow(tt.name).Scan(&age); err != nil {
-			t.Errorf("%d: on %q, QueryRow/Scan: %v", n, tt.name, err)
-		} else if age != tt.want {
-			t.Errorf("%d: age=%d, want %d", n, age, tt.want)
-		}
-	}
-}
-
-// golang.org/issue/3734
-func TestStatementQueryRowConcurrent(t *testing.T) {
-	db := newTestDB(t, "people")
-	defer closeDB(t, db)
-	stmt, err := db.Prepare("SELECT|people|age|name=?")
-	if err != nil {
-		t.Fatalf("Prepare: %v", err)
-	}
-	defer stmt.Close()
-
-	const n = 10
-	ch := make(chan error, n)
-	for i := 0; i < n; i++ {
-		go func() {
-			var age int
-			err := stmt.QueryRow("Alice").Scan(&age)
-			if err == nil && age != 1 {
-				err = fmt.Errorf("unexpected age %d", age)
-			}
-			ch <- err
-		}()
-	}
-	for i := 0; i < n; i++ {
-		if err := <-ch; err != nil {
-			t.Error(err)
-		}
-	}
-}
-
-// just a test of fakedb itself
-func TestBogusPreboundParameters(t *testing.T) {
-	db := newTestDB(t, "foo")
-	defer closeDB(t, db)
-	exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool")
-	_, err := db.Prepare("INSERT|t1|name=?,age=bogusconversion")
-	if err == nil {
-		t.Fatalf("expected error")
-	}
-	if err.Error() != `fakedb: invalid conversion to int32 from "bogusconversion"` {
-		t.Errorf("unexpected error: %v", err)
-	}
-}
-
-func TestExec(t *testing.T) {
-	db := newTestDB(t, "foo")
-	defer closeDB(t, db)
-	exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool")
-	stmt, err := db.Prepare("INSERT|t1|name=?,age=?")
-	if err != nil {
-		t.Errorf("Stmt, err = %v, %v", stmt, err)
-	}
-	defer stmt.Close()
-
-	type execTest struct {
-		args    []interface{}
-		wantErr string
-	}
-	execTests := []execTest{
-		// Okay:
-		{[]interface{}{"Brad", 31}, ""},
-		{[]interface{}{"Brad", int64(31)}, ""},
-		{[]interface{}{"Bob", "32"}, ""},
-		{[]interface{}{7, 9}, ""},
-
-		// Invalid conversions:
-		{[]interface{}{"Brad", int64(0xFFFFFFFF)}, "sql: converting argument #1's type: sql/driver: value 4294967295 overflows int32"},
-		{[]interface{}{"Brad", "strconv fail"}, "sql: converting argument #1's type: sql/driver: value \"strconv fail\" can't be converted to int32"},
-
-		// Wrong number of args:
-		{[]interface{}{}, "sql: expected 2 arguments, got 0"},
-		{[]interface{}{1, 2, 3}, "sql: expected 2 arguments, got 3"},
-	}
-	for n, et := range execTests {
-		_, err := stmt.Exec(et.args...)
-		errStr := ""
-		if err != nil {
-			errStr = err.Error()
-		}
-		if errStr != et.wantErr {
-			t.Errorf("stmt.Execute #%d: for %v, got error %q, want error %q",
-				n, et.args, errStr, et.wantErr)
-		}
-	}
-}
-
-func TestTxStmt(t *testing.T) {
-	db := newTestDB(t, "")
-	defer closeDB(t, db)
-	exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool")
-	stmt, err := db.Prepare("INSERT|t1|name=?,age=?")
-	if err != nil {
-		t.Fatalf("Stmt, err = %v, %v", stmt, err)
-	}
-	defer stmt.Close()
-	tx, err := db.Begin()
-	if err != nil {
-		t.Fatalf("Begin = %v", err)
-	}
-	txs := tx.Stmt(stmt)
-	defer txs.Close()
-	_, err = txs.Exec("Bobby", 7)
-	if err != nil {
-		t.Fatalf("Exec = %v", err)
-	}
-	err = tx.Commit()
-	if err != nil {
-		t.Fatalf("Commit = %v", err)
-	}
-}
-
-// Issue: http://golang.org/issue/2784
-// This test didn't fail before because we got lucky with the fakedb driver.
-// It was failing, and now not, in github.com/bradfitz/go-sql-test
-func TestTxQuery(t *testing.T) {
-	db := newTestDB(t, "")
-	defer closeDB(t, db)
-	exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool")
-	exec(t, db, "INSERT|t1|name=Alice")
-
-	tx, err := db.Begin()
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer tx.Rollback()
-
-	r, err := tx.Query("SELECT|t1|name|")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer r.Close()
-
-	if !r.Next() {
-		if r.Err() != nil {
-			t.Fatal(r.Err())
-		}
-		t.Fatal("expected one row")
-	}
-
-	var x string
-	err = r.Scan(&x)
-	if err != nil {
-		t.Fatal(err)
-	}
-}
-
-func TestTxQueryInvalid(t *testing.T) {
-	db := newTestDB(t, "")
-	defer closeDB(t, db)
-
-	tx, err := db.Begin()
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer tx.Rollback()
-
-	_, err = tx.Query("SELECT|t1|name|")
-	if err == nil {
-		t.Fatal("Error expected")
-	}
-}
-
-// Tests fix for issue 4433, that retries in Begin happen when
-// conn.Begin() returns ErrBadConn
-func TestTxErrBadConn(t *testing.T) {
-	db, err := Open("test", fakeDBName+";badConn")
-	if err != nil {
-		t.Fatalf("Open: %v", err)
-	}
-	if _, err := db.Exec("WIPE"); err != nil {
-		t.Fatalf("exec wipe: %v", err)
-	}
-	defer closeDB(t, db)
-	exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool")
-	stmt, err := db.Prepare("INSERT|t1|name=?,age=?")
-	if err != nil {
-		t.Fatalf("Stmt, err = %v, %v", stmt, err)
-	}
-	defer stmt.Close()
-	tx, err := db.Begin()
-	if err != nil {
-		t.Fatalf("Begin = %v", err)
-	}
-	txs := tx.Stmt(stmt)
-	defer txs.Close()
-	_, err = txs.Exec("Bobby", 7)
-	if err != nil {
-		t.Fatalf("Exec = %v", err)
-	}
-	err = tx.Commit()
-	if err != nil {
-		t.Fatalf("Commit = %v", err)
-	}
-}
-
-// Tests fix for issue 2542, that we release a lock when querying on
-// a closed connection.
-func TestIssue2542Deadlock(t *testing.T) {
-	db := newTestDB(t, "people")
-	closeDB(t, db)
-	for i := 0; i < 2; i++ {
-		_, err := db.Query("SELECT|people|age,name|")
-		if err == nil {
-			t.Fatalf("expected error")
-		}
-	}
-}
-
-// From golang.org/issue/3865
-func TestCloseStmtBeforeRows(t *testing.T) {
-	db := newTestDB(t, "people")
-	defer closeDB(t, db)
-
-	s, err := db.Prepare("SELECT|people|name|")
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	r, err := s.Query()
-	if err != nil {
-		s.Close()
-		t.Fatal(err)
-	}
-
-	err = s.Close()
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	r.Close()
-}
-
-// Tests fix for issue 2788, that we bind nil to a []byte if the
-// value in the column is sql null
-func TestNullByteSlice(t *testing.T) {
-	db := newTestDB(t, "")
-	defer closeDB(t, db)
-	exec(t, db, "CREATE|t|id=int32,name=nullstring")
-	exec(t, db, "INSERT|t|id=10,name=?", nil)
-
-	var name []byte
-
-	err := db.QueryRow("SELECT|t|name|id=?", 10).Scan(&name)
-	if err != nil {
-		t.Fatal(err)
-	}
-	if name != nil {
-		t.Fatalf("name []byte should be nil for null column value, got: %#v", name)
-	}
-
-	exec(t, db, "INSERT|t|id=11,name=?", "bob")
-	err = db.QueryRow("SELECT|t|name|id=?", 11).Scan(&name)
-	if err != nil {
-		t.Fatal(err)
-	}
-	if string(name) != "bob" {
-		t.Fatalf("name []byte should be bob, got: %q", string(name))
-	}
-}
-
-func TestPointerParamsAndScans(t *testing.T) {
-	db := newTestDB(t, "")
-	defer closeDB(t, db)
-	exec(t, db, "CREATE|t|id=int32,name=nullstring")
-
-	bob := "bob"
-	var name *string
-
-	name = &bob
-	exec(t, db, "INSERT|t|id=10,name=?", name)
-	name = nil
-	exec(t, db, "INSERT|t|id=20,name=?", name)
-
-	err := db.QueryRow("SELECT|t|name|id=?", 10).Scan(&name)
-	if err != nil {
-		t.Fatalf("querying id 10: %v", err)
-	}
-	if name == nil {
-		t.Errorf("id 10's name = nil; want bob")
-	} else if *name != "bob" {
-		t.Errorf("id 10's name = %q; want bob", *name)
-	}
-
-	err = db.QueryRow("SELECT|t|name|id=?", 20).Scan(&name)
-	if err != nil {
-		t.Fatalf("querying id 20: %v", err)
-	}
-	if name != nil {
-		t.Errorf("id 20 = %q; want nil", *name)
-	}
-}
-
-func TestQueryRowClosingStmt(t *testing.T) {
-	db := newTestDB(t, "people")
-	defer closeDB(t, db)
-	var name string
-	var age int
-	err := db.QueryRow("SELECT|people|age,name|age=?", 3).Scan(&age, &name)
-	if err != nil {
-		t.Fatal(err)
-	}
-	if db.freeConn.Len() != 1 {
-		t.Fatalf("expected 1 free conn")
-	}
-	fakeConn := (db.freeConn.Front().Value.(*driverConn)).ci.(*fakeConn)
-	if made, closed := fakeConn.stmtsMade, fakeConn.stmtsClosed; made != closed {
-		t.Errorf("statement close mismatch: made %d, closed %d", made, closed)
-	}
-}
-
-// Test issue 6651
-func TestIssue6651(t *testing.T) {
-	db := newTestDB(t, "people")
-	defer closeDB(t, db)
-
-	var v string
-
-	want := "error in rows.Next"
-	rowsCursorNextHook = func(dest []driver.Value) error {
-		return fmt.Errorf(want)
-	}
-	defer func() { rowsCursorNextHook = nil }()
-	err := db.QueryRow("SELECT|people|name|").Scan(&v)
-	if err == nil || err.Error() != want {
-		t.Errorf("error = %q; want %q", err, want)
-	}
-	rowsCursorNextHook = nil
-
-	want = "error in rows.Close"
-	rowsCloseHook = func(rows *Rows, err *error) {
-		*err = fmt.Errorf(want)
-	}
-	defer func() { rowsCloseHook = nil }()
-	err = db.QueryRow("SELECT|people|name|").Scan(&v)
-	if err == nil || err.Error() != want {
-		t.Errorf("error = %q; want %q", err, want)
-	}
-}
-
-type nullTestRow struct {
-	nullParam    interface{}
-	notNullParam interface{}
-	scanNullVal  interface{}
-}
-
-type nullTestSpec struct {
-	nullType    string
-	notNullType string
-	rows        [6]nullTestRow
-}
-
-func TestNullStringParam(t *testing.T) {
-	spec := nullTestSpec{"nullstring", "string", [6]nullTestRow{
-		{NullString{"aqua", true}, "", NullString{"aqua", true}},
-		{NullString{"brown", false}, "", NullString{"", false}},
-		{"chartreuse", "", NullString{"chartreuse", true}},
-		{NullString{"darkred", true}, "", NullString{"darkred", true}},
-		{NullString{"eel", false}, "", NullString{"", false}},
-		{"foo", NullString{"black", false}, nil},
-	}}
-	nullTestRun(t, spec)
-}
-
-func TestNullInt64Param(t *testing.T) {
-	spec := nullTestSpec{"nullint64", "int64", [6]nullTestRow{
-		{NullInt64{31, true}, 1, NullInt64{31, true}},
-		{NullInt64{-22, false}, 1, NullInt64{0, false}},
-		{22, 1, NullInt64{22, true}},
-		{NullInt64{33, true}, 1, NullInt64{33, true}},
-		{NullInt64{222, false}, 1, NullInt64{0, false}},
-		{0, NullInt64{31, false}, nil},
-	}}
-	nullTestRun(t, spec)
-}
-
-func TestNullFloat64Param(t *testing.T) {
-	spec := nullTestSpec{"nullfloat64", "float64", [6]nullTestRow{
-		{NullFloat64{31.2, true}, 1, NullFloat64{31.2, true}},
-		{NullFloat64{13.1, false}, 1, NullFloat64{0, false}},
-		{-22.9, 1, NullFloat64{-22.9, true}},
-		{NullFloat64{33.81, true}, 1, NullFloat64{33.81, true}},
-		{NullFloat64{222, false}, 1, NullFloat64{0, false}},
-		{10, NullFloat64{31.2, false}, nil},
-	}}
-	nullTestRun(t, spec)
-}
-
-func TestNullBoolParam(t *testing.T) {
-	spec := nullTestSpec{"nullbool", "bool", [6]nullTestRow{
-		{NullBool{false, true}, true, NullBool{false, true}},
-		{NullBool{true, false}, false, NullBool{false, false}},
-		{true, true, NullBool{true, true}},
-		{NullBool{true, true}, false, NullBool{true, true}},
-		{NullBool{true, false}, true, NullBool{false, false}},
-		{true, NullBool{true, false}, nil},
-	}}
-	nullTestRun(t, spec)
-}
-
-func nullTestRun(t *testing.T, spec nullTestSpec) {
-	db := newTestDB(t, "")
-	defer closeDB(t, db)
-	exec(t, db, fmt.Sprintf("CREATE|t|id=int32,name=string,nullf=%s,notnullf=%s", spec.nullType, spec.notNullType))
-
-	// Inserts with db.Exec:
-	exec(t, db, "INSERT|t|id=?,name=?,nullf=?,notnullf=?", 1, "alice", spec.rows[0].nullParam, spec.rows[0].notNullParam)
-	exec(t, db, "INSERT|t|id=?,name=?,nullf=?,notnullf=?", 2, "bob", spec.rows[1].nullParam, spec.rows[1].notNullParam)
-
-	// Inserts with a prepared statement:
-	stmt, err := db.Prepare("INSERT|t|id=?,name=?,nullf=?,notnullf=?")
-	if err != nil {
-		t.Fatalf("prepare: %v", err)
-	}
-	defer stmt.Close()
-	if _, err := stmt.Exec(3, "chris", spec.rows[2].nullParam, spec.rows[2].notNullParam); err != nil {
-		t.Errorf("exec insert chris: %v", err)
-	}
-	if _, err := stmt.Exec(4, "dave", spec.rows[3].nullParam, spec.rows[3].notNullParam); err != nil {
-		t.Errorf("exec insert dave: %v", err)
-	}
-	if _, err := stmt.Exec(5, "eleanor", spec.rows[4].nullParam, spec.rows[4].notNullParam); err != nil {
-		t.Errorf("exec insert eleanor: %v", err)
-	}
-
-	// Can't put null val into non-null col
-	if _, err := stmt.Exec(6, "bob", spec.rows[5].nullParam, spec.rows[5].notNullParam); err == nil {
-		t.Errorf("expected error inserting nil val with prepared statement Exec")
-	}
-
-	_, err = db.Exec("INSERT|t|id=?,name=?,nullf=?", 999, nil, nil)
-	if err == nil {
-		// TODO: this test fails, but it's just because
-		// fakeConn implements the optional Execer interface,
-		// so arguably this is the correct behavior.  But
-		// maybe I should flesh out the fakeConn.Exec
-		// implementation so this properly fails.
-		// t.Errorf("expected error inserting nil name with Exec")
-	}
-
-	paramtype := reflect.TypeOf(spec.rows[0].nullParam)
-	bindVal := reflect.New(paramtype).Interface()
-
-	for i := 0; i < 5; i++ {
-		id := i + 1
-		if err := db.QueryRow("SELECT|t|nullf|id=?", id).Scan(bindVal); err != nil {
-			t.Errorf("id=%d Scan: %v", id, err)
-		}
-		bindValDeref := reflect.ValueOf(bindVal).Elem().Interface()
-		if !reflect.DeepEqual(bindValDeref, spec.rows[i].scanNullVal) {
-			t.Errorf("id=%d got %#v, want %#v", id, bindValDeref, spec.rows[i].scanNullVal)
-		}
-	}
-}
-
-// golang.org/issue/4859
-func TestQueryRowNilScanDest(t *testing.T) {
-	db := newTestDB(t, "people")
-	defer closeDB(t, db)
-	var name *string // nil pointer
-	err := db.QueryRow("SELECT|people|name|").Scan(name)
-	want := "sql: Scan error on column index 0: destination pointer is nil"
-	if err == nil || err.Error() != want {
-		t.Errorf("error = %q; want %q", err.Error(), want)
-	}
-}
-
-func TestIssue4902(t *testing.T) {
-	db := newTestDB(t, "people")
-	defer closeDB(t, db)
-
-	driver := db.driver.(*fakeDriver)
-	opens0 := driver.openCount
-
-	var stmt *Stmt
-	var err error
-	for i := 0; i < 10; i++ {
-		stmt, err = db.Prepare("SELECT|people|name|")
-		if err != nil {
-			t.Fatal(err)
-		}
-		err = stmt.Close()
-		if err != nil {
-			t.Fatal(err)
-		}
-	}
-
-	opens := driver.openCount - opens0
-	if opens > 1 {
-		t.Errorf("opens = %d; want <= 1", opens)
-		t.Logf("db = %#v", db)
-		t.Logf("driver = %#v", driver)
-		t.Logf("stmt = %#v", stmt)
-	}
-}
-
-// Issue 3857
-// This used to deadlock.
-func TestSimultaneousQueries(t *testing.T) {
-	db := newTestDB(t, "people")
-	defer closeDB(t, db)
-
-	tx, err := db.Begin()
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer tx.Rollback()
-
-	r1, err := tx.Query("SELECT|people|name|")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer r1.Close()
-
-	r2, err := tx.Query("SELECT|people|name|")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer r2.Close()
-}
-
-func TestMaxIdleConns(t *testing.T) {
-	db := newTestDB(t, "people")
-	defer closeDB(t, db)
-
-	tx, err := db.Begin()
-	if err != nil {
-		t.Fatal(err)
-	}
-	tx.Commit()
-	if got := db.freeConn.Len(); got != 1 {
-		t.Errorf("freeConns = %d; want 1", got)
-	}
-
-	db.SetMaxIdleConns(0)
-
-	if got := db.freeConn.Len(); got != 0 {
-		t.Errorf("freeConns after set to zero = %d; want 0", got)
-	}
-
-	tx, err = db.Begin()
-	if err != nil {
-		t.Fatal(err)
-	}
-	tx.Commit()
-	if got := db.freeConn.Len(); got != 0 {
-		t.Errorf("freeConns = %d; want 0", got)
-	}
-}
-
-func TestMaxOpenConns(t *testing.T) {
-	if testing.Short() {
-		t.Skip("skipping in short mode")
-	}
-	defer setHookpostCloseConn(nil)
-	setHookpostCloseConn(func(_ *fakeConn, err error) {
-		if err != nil {
-			t.Errorf("Error closing fakeConn: %v", err)
-		}
-	})
-
-	db := newTestDB(t, "magicquery")
-	defer closeDB(t, db)
-
-	driver := db.driver.(*fakeDriver)
-
-	// Force the number of open connections to 0 so we can get an accurate
-	// count for the test
-	db.SetMaxIdleConns(0)
-
-	if g, w := db.numFreeConns(), 0; g != w {
-		t.Errorf("free conns = %d; want %d", g, w)
-	}
-
-	if n := db.numDepsPollUntil(0, time.Second); n > 0 {
-		t.Errorf("number of dependencies = %d; expected 0", n)
-		db.dumpDeps(t)
-	}
-
-	driver.mu.Lock()
-	opens0 := driver.openCount
-	closes0 := driver.closeCount
-	driver.mu.Unlock()
-
-	db.SetMaxIdleConns(10)
-	db.SetMaxOpenConns(10)
-
-	stmt, err := db.Prepare("SELECT|magicquery|op|op=?,millis=?")
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	// Start 50 parallel slow queries.
-	const (
-		nquery      = 50
-		sleepMillis = 25
-		nbatch      = 2
-	)
-	var wg sync.WaitGroup
-	for batch := 0; batch < nbatch; batch++ {
-		for i := 0; i < nquery; i++ {
-			wg.Add(1)
-			go func() {
-				defer wg.Done()
-				var op string
-				if err := stmt.QueryRow("sleep", sleepMillis).Scan(&op); err != nil && err != ErrNoRows {
-					t.Error(err)
-				}
-			}()
-		}
-		// Sleep for twice the expected length of time for the
-		// batch of 50 queries above to finish before starting
-		// the next round.
-		time.Sleep(2 * sleepMillis * time.Millisecond)
-	}
-	wg.Wait()
-
-	if g, w := db.numFreeConns(), 10; g != w {
-		t.Errorf("free conns = %d; want %d", g, w)
-	}
-
-	if n := db.numDepsPollUntil(20, time.Second); n > 20 {
-		t.Errorf("number of dependencies = %d; expected <= 20", n)
-		db.dumpDeps(t)
-	}
-
-	driver.mu.Lock()
-	opens := driver.openCount - opens0
-	closes := driver.closeCount - closes0
-	driver.mu.Unlock()
-
-	if opens > 10 {
-		t.Logf("open calls = %d", opens)
-		t.Logf("close calls = %d", closes)
-		t.Errorf("db connections opened = %d; want <= 10", opens)
-		db.dumpDeps(t)
-	}
-
-	if err := stmt.Close(); err != nil {
-		t.Fatal(err)
-	}
-
-	if g, w := db.numFreeConns(), 10; g != w {
-		t.Errorf("free conns = %d; want %d", g, w)
-	}
-
-	if n := db.numDepsPollUntil(10, time.Second); n > 10 {
-		t.Errorf("number of dependencies = %d; expected <= 10", n)
-		db.dumpDeps(t)
-	}
-
-	db.SetMaxOpenConns(5)
-
-	if g, w := db.numFreeConns(), 5; g != w {
-		t.Errorf("free conns = %d; want %d", g, w)
-	}
-
-	if n := db.numDepsPollUntil(5, time.Second); n > 5 {
-		t.Errorf("number of dependencies = %d; expected 0", n)
-		db.dumpDeps(t)
-	}
-
-	db.SetMaxOpenConns(0)
-
-	if g, w := db.numFreeConns(), 5; g != w {
-		t.Errorf("free conns = %d; want %d", g, w)
-	}
-
-	if n := db.numDepsPollUntil(5, time.Second); n > 5 {
-		t.Errorf("number of dependencies = %d; expected 0", n)
-		db.dumpDeps(t)
-	}
-
-	db.SetMaxIdleConns(0)
-
-	if g, w := db.numFreeConns(), 0; g != w {
-		t.Errorf("free conns = %d; want %d", g, w)
-	}
-
-	if n := db.numDepsPollUntil(0, time.Second); n > 0 {
-		t.Errorf("number of dependencies = %d; expected 0", n)
-		db.dumpDeps(t)
-	}
-}
-
-func TestSingleOpenConn(t *testing.T) {
-	db := newTestDB(t, "people")
-	defer closeDB(t, db)
-
-	db.SetMaxOpenConns(1)
-
-	rows, err := db.Query("SELECT|people|name|")
-	if err != nil {
-		t.Fatal(err)
-	}
-	if err = rows.Close(); err != nil {
-		t.Fatal(err)
-	}
-	// shouldn't deadlock
-	rows, err = db.Query("SELECT|people|name|")
-	if err != nil {
-		t.Fatal(err)
-	}
-	if err = rows.Close(); err != nil {
-		t.Fatal(err)
-	}
-}
-
-// golang.org/issue/5323
-func TestStmtCloseDeps(t *testing.T) {
-	if testing.Short() {
-		t.Skip("skipping in short mode")
-	}
-	defer setHookpostCloseConn(nil)
-	setHookpostCloseConn(func(_ *fakeConn, err error) {
-		if err != nil {
-			t.Errorf("Error closing fakeConn: %v", err)
-		}
-	})
-
-	db := newTestDB(t, "magicquery")
-	defer closeDB(t, db)
-
-	driver := db.driver.(*fakeDriver)
-
-	driver.mu.Lock()
-	opens0 := driver.openCount
-	closes0 := driver.closeCount
-	driver.mu.Unlock()
-	openDelta0 := opens0 - closes0
-
-	stmt, err := db.Prepare("SELECT|magicquery|op|op=?,millis=?")
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	// Start 50 parallel slow queries.
-	const (
-		nquery      = 50
-		sleepMillis = 25
-		nbatch      = 2
-	)
-	var wg sync.WaitGroup
-	for batch := 0; batch < nbatch; batch++ {
-		for i := 0; i < nquery; i++ {
-			wg.Add(1)
-			go func() {
-				defer wg.Done()
-				var op string
-				if err := stmt.QueryRow("sleep", sleepMillis).Scan(&op); err != nil && err != ErrNoRows {
-					t.Error(err)
-				}
-			}()
-		}
-		// Sleep for twice the expected length of time for the
-		// batch of 50 queries above to finish before starting
-		// the next round.
-		time.Sleep(2 * sleepMillis * time.Millisecond)
-	}
-	wg.Wait()
-
-	if g, w := db.numFreeConns(), 2; g != w {
-		t.Errorf("free conns = %d; want %d", g, w)
-	}
-
-	if n := db.numDepsPollUntil(4, time.Second); n > 4 {
-		t.Errorf("number of dependencies = %d; expected <= 4", n)
-		db.dumpDeps(t)
-	}
-
-	driver.mu.Lock()
-	opens := driver.openCount - opens0
-	closes := driver.closeCount - closes0
-	openDelta := (driver.openCount - driver.closeCount) - openDelta0
-	driver.mu.Unlock()
-
-	if openDelta > 2 {
-		t.Logf("open calls = %d", opens)
-		t.Logf("close calls = %d", closes)
-		t.Logf("open delta = %d", openDelta)
-		t.Errorf("db connections opened = %d; want <= 2", openDelta)
-		db.dumpDeps(t)
-	}
-
-	if len(stmt.css) > nquery {
-		t.Errorf("len(stmt.css) = %d; want <= %d", len(stmt.css), nquery)
-	}
-
-	if err := stmt.Close(); err != nil {
-		t.Fatal(err)
-	}
-
-	if g, w := db.numFreeConns(), 2; g != w {
-		t.Errorf("free conns = %d; want %d", g, w)
-	}
-
-	if n := db.numDepsPollUntil(2, time.Second); n > 2 {
-		t.Errorf("number of dependencies = %d; expected <= 2", n)
-		db.dumpDeps(t)
-	}
-
-	db.SetMaxIdleConns(0)
-
-	if g, w := db.numFreeConns(), 0; g != w {
-		t.Errorf("free conns = %d; want %d", g, w)
-	}
-
-	if n := db.numDepsPollUntil(0, time.Second); n > 0 {
-		t.Errorf("number of dependencies = %d; expected 0", n)
-		db.dumpDeps(t)
-	}
-}
-
-// golang.org/issue/5046
-func TestCloseConnBeforeStmts(t *testing.T) {
-	db := newTestDB(t, "people")
-	defer closeDB(t, db)
-
-	defer setHookpostCloseConn(nil)
-	setHookpostCloseConn(func(_ *fakeConn, err error) {
-		if err != nil {
-			t.Errorf("Error closing fakeConn: %v; from %s", err, stack())
-			db.dumpDeps(t)
-			t.Errorf("DB = %#v", db)
-		}
-	})
-
-	stmt, err := db.Prepare("SELECT|people|name|")
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	if db.freeConn.Len() != 1 {
-		t.Fatalf("expected 1 freeConn; got %d", db.freeConn.Len())
-	}
-	dc := db.freeConn.Front().Value.(*driverConn)
-	if dc.closed {
-		t.Errorf("conn shouldn't be closed")
-	}
-
-	if n := len(dc.openStmt); n != 1 {
-		t.Errorf("driverConn num openStmt = %d; want 1", n)
-	}
-	err = db.Close()
-	if err != nil {
-		t.Errorf("db Close = %v", err)
-	}
-	if !dc.closed {
-		t.Errorf("after db.Close, driverConn should be closed")
-	}
-	if n := len(dc.openStmt); n != 0 {
-		t.Errorf("driverConn num openStmt = %d; want 0", n)
-	}
-
-	err = stmt.Close()
-	if err != nil {
-		t.Errorf("Stmt close = %v", err)
-	}
-
-	if !dc.closed {
-		t.Errorf("conn should be closed")
-	}
-	if dc.ci != nil {
-		t.Errorf("after Stmt Close, driverConn's Conn interface should be nil")
-	}
-}
-
-// golang.org/issue/5283: don't release the Rows' connection in Close
-// before calling Stmt.Close.
-func TestRowsCloseOrder(t *testing.T) {
-	db := newTestDB(t, "people")
-	defer closeDB(t, db)
-
-	db.SetMaxIdleConns(0)
-	setStrictFakeConnClose(t)
-	defer setStrictFakeConnClose(nil)
-
-	rows, err := db.Query("SELECT|people|age,name|")
-	if err != nil {
-		t.Fatal(err)
-	}
-	err = rows.Close()
-	if err != nil {
-		t.Fatal(err)
-	}
-}
-
-func TestRowsImplicitClose(t *testing.T) {
-	db := newTestDB(t, "people")
-	defer closeDB(t, db)
-
-	rows, err := db.Query("SELECT|people|age,name|")
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	want, fail := 2, errors.New("fail")
-	r := rows.rowsi.(*rowsCursor)
-	r.errPos, r.err = want, fail
-
-	got := 0
-	for rows.Next() {
-		got++
-	}
-	if got != want {
-		t.Errorf("got %d rows, want %d", got, want)
-	}
-	if err := rows.Err(); err != fail {
-		t.Errorf("got error %v, want %v", err, fail)
-	}
-	if !r.closed {
-		t.Errorf("r.closed is false, want true")
-	}
-}
-
-func TestStmtCloseOrder(t *testing.T) {
-	db := newTestDB(t, "people")
-	defer closeDB(t, db)
-
-	db.SetMaxIdleConns(0)
-	setStrictFakeConnClose(t)
-	defer setStrictFakeConnClose(nil)
-
-	_, err := db.Query("SELECT|non_existent|name|")
-	if err == nil {
-		t.Fatal("Quering non-existent table should fail")
-	}
-}
-
-// golang.org/issue/5781
-func TestErrBadConnReconnect(t *testing.T) {
-	db := newTestDB(t, "foo")
-	defer closeDB(t, db)
-	exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool")
-
-	simulateBadConn := func(name string, hook *func() bool, op func() error) {
-		broken, retried := false, false
-		numOpen := db.numOpen
-
-		// simulate a broken connection on the first try
-		*hook = func() bool {
-			if !broken {
-				broken = true
-				return true
-			}
-			retried = true
-			return false
-		}
-
-		if err := op(); err != nil {
-			t.Errorf(name+": %v", err)
-			return
-		}
-
-		if !broken || !retried {
-			t.Error(name + ": Failed to simulate broken connection")
-		}
-		*hook = nil
-
-		if numOpen != db.numOpen {
-			t.Errorf(name+": leaked %d connection(s)!", db.numOpen-numOpen)
-			numOpen = db.numOpen
-		}
-	}
-
-	// db.Exec
-	dbExec := func() error {
-		_, err := db.Exec("INSERT|t1|name=?,age=?,dead=?", "Gordon", 3, true)
-		return err
-	}
-	simulateBadConn("db.Exec prepare", &hookPrepareBadConn, dbExec)
-	simulateBadConn("db.Exec exec", &hookExecBadConn, dbExec)
-
-	// db.Query
-	dbQuery := func() error {
-		rows, err := db.Query("SELECT|t1|age,name|")
-		if err == nil {
-			err = rows.Close()
-		}
-		return err
-	}
-	simulateBadConn("db.Query prepare", &hookPrepareBadConn, dbQuery)
-	simulateBadConn("db.Query query", &hookQueryBadConn, dbQuery)
-
-	// db.Prepare
-	simulateBadConn("db.Prepare", &hookPrepareBadConn, func() error {
-		stmt, err := db.Prepare("INSERT|t1|name=?,age=?,dead=?")
-		if err != nil {
-			return err
-		}
-		stmt.Close()
-		return nil
-	})
-
-	// stmt.Exec
-	stmt1, err := db.Prepare("INSERT|t1|name=?,age=?,dead=?")
-	if err != nil {
-		t.Fatalf("prepare: %v", err)
-	}
-	defer stmt1.Close()
-	// make sure we must prepare the stmt first
-	for _, cs := range stmt1.css {
-		cs.dc.inUse = true
-	}
-
-	stmtExec := func() error {
-		_, err := stmt1.Exec("Gopher", 3, false)
-		return err
-	}
-	simulateBadConn("stmt.Exec prepare", &hookPrepareBadConn, stmtExec)
-	simulateBadConn("stmt.Exec exec", &hookExecBadConn, stmtExec)
-
-	// stmt.Query
-	stmt2, err := db.Prepare("SELECT|t1|age,name|")
-	if err != nil {
-		t.Fatalf("prepare: %v", err)
-	}
-	defer stmt2.Close()
-	// make sure we must prepare the stmt first
-	for _, cs := range stmt2.css {
-		cs.dc.inUse = true
-	}
-
-	stmtQuery := func() error {
-		rows, err := stmt2.Query()
-		if err == nil {
-			err = rows.Close()
-		}
-		return err
-	}
-	simulateBadConn("stmt.Query prepare", &hookPrepareBadConn, stmtQuery)
-	simulateBadConn("stmt.Query exec", &hookQueryBadConn, stmtQuery)
-}
-
-type concurrentTest interface {
-	init(t testing.TB, db *DB)
-	finish(t testing.TB)
-	test(t testing.TB) error
-}
-
-type concurrentDBQueryTest struct {
-	db *DB
-}
-
-func (c *concurrentDBQueryTest) init(t testing.TB, db *DB) {
-	c.db = db
-}
-
-func (c *concurrentDBQueryTest) finish(t testing.TB) {
-	c.db = nil
-}
-
-func (c *concurrentDBQueryTest) test(t testing.TB) error {
-	rows, err := c.db.Query("SELECT|people|name|")
-	if err != nil {
-		t.Error(err)
-		return err
-	}
-	var name string
-	for rows.Next() {
-		rows.Scan(&name)
-	}
-	rows.Close()
-	return nil
-}
-
-type concurrentDBExecTest struct {
-	db *DB
-}
-
-func (c *concurrentDBExecTest) init(t testing.TB, db *DB) {
-	c.db = db
-}
-
-func (c *concurrentDBExecTest) finish(t testing.TB) {
-	c.db = nil
-}
-
-func (c *concurrentDBExecTest) test(t testing.TB) error {
-	_, err := c.db.Exec("NOSERT|people|name=Chris,age=?,photo=CPHOTO,bdate=?", 3, chrisBirthday)
-	if err != nil {
-		t.Error(err)
-		return err
-	}
-	return nil
-}
-
-type concurrentStmtQueryTest struct {
-	db   *DB
-	stmt *Stmt
-}
-
-func (c *concurrentStmtQueryTest) init(t testing.TB, db *DB) {
-	c.db = db
-	var err error
-	c.stmt, err = db.Prepare("SELECT|people|name|")
-	if err != nil {
-		t.Fatal(err)
-	}
-}
-
-func (c *concurrentStmtQueryTest) finish(t testing.TB) {
-	if c.stmt != nil {
-		c.stmt.Close()
-		c.stmt = nil
-	}
-	c.db = nil
-}
-
-func (c *concurrentStmtQueryTest) test(t testing.TB) error {
-	rows, err := c.stmt.Query()
-	if err != nil {
-		t.Errorf("error on query:  %v", err)
-		return err
-	}
-
-	var name string
-	for rows.Next() {
-		rows.Scan(&name)
-	}
-	rows.Close()
-	return nil
-}
-
-type concurrentStmtExecTest struct {
-	db   *DB
-	stmt *Stmt
-}
-
-func (c *concurrentStmtExecTest) init(t testing.TB, db *DB) {
-	c.db = db
-	var err error
-	c.stmt, err = db.Prepare("NOSERT|people|name=Chris,age=?,photo=CPHOTO,bdate=?")
-	if err != nil {
-		t.Fatal(err)
-	}
-}
-
-func (c *concurrentStmtExecTest) finish(t testing.TB) {
-	if c.stmt != nil {
-		c.stmt.Close()
-		c.stmt = nil
-	}
-	c.db = nil
-}
-
-func (c *concurrentStmtExecTest) test(t testing.TB) error {
-	_, err := c.stmt.Exec(3, chrisBirthday)
-	if err != nil {
-		t.Errorf("error on exec:  %v", err)
-		return err
-	}
-	return nil
-}
-
-type concurrentTxQueryTest struct {
-	db *DB
-	tx *Tx
-}
-
-func (c *concurrentTxQueryTest) init(t testing.TB, db *DB) {
-	c.db = db
-	var err error
-	c.tx, err = c.db.Begin()
-	if err != nil {
-		t.Fatal(err)
-	}
-}
-
-func (c *concurrentTxQueryTest) finish(t testing.TB) {
-	if c.tx != nil {
-		c.tx.Rollback()
-		c.tx = nil
-	}
-	c.db = nil
-}
-
-func (c *concurrentTxQueryTest) test(t testing.TB) error {
-	rows, err := c.db.Query("SELECT|people|name|")
-	if err != nil {
-		t.Error(err)
-		return err
-	}
-	var name string
-	for rows.Next() {
-		rows.Scan(&name)
-	}
-	rows.Close()
-	return nil
-}
-
-type concurrentTxExecTest struct {
-	db *DB
-	tx *Tx
-}
-
-func (c *concurrentTxExecTest) init(t testing.TB, db *DB) {
-	c.db = db
-	var err error
-	c.tx, err = c.db.Begin()
-	if err != nil {
-		t.Fatal(err)
-	}
-}
-
-func (c *concurrentTxExecTest) finish(t testing.TB) {
-	if c.tx != nil {
-		c.tx.Rollback()
-		c.tx = nil
-	}
-	c.db = nil
-}
-
-func (c *concurrentTxExecTest) test(t testing.TB) error {
-	_, err := c.tx.Exec("NOSERT|people|name=Chris,age=?,photo=CPHOTO,bdate=?", 3, chrisBirthday)
-	if err != nil {
-		t.Error(err)
-		return err
-	}
-	return nil
-}
-
-type concurrentTxStmtQueryTest struct {
-	db   *DB
-	tx   *Tx
-	stmt *Stmt
-}
-
-func (c *concurrentTxStmtQueryTest) init(t testing.TB, db *DB) {
-	c.db = db
-	var err error
-	c.tx, err = c.db.Begin()
-	if err != nil {
-		t.Fatal(err)
-	}
-	c.stmt, err = c.tx.Prepare("SELECT|people|name|")
-	if err != nil {
-		t.Fatal(err)
-	}
-}
-
-func (c *concurrentTxStmtQueryTest) finish(t testing.TB) {
-	if c.stmt != nil {
-		c.stmt.Close()
-		c.stmt = nil
-	}
-	if c.tx != nil {
-		c.tx.Rollback()
-		c.tx = nil
-	}
-	c.db = nil
-}
-
-func (c *concurrentTxStmtQueryTest) test(t testing.TB) error {
-	rows, err := c.stmt.Query()
-	if err != nil {
-		t.Errorf("error on query:  %v", err)
-		return err
-	}
-
-	var name string
-	for rows.Next() {
-		rows.Scan(&name)
-	}
-	rows.Close()
-	return nil
-}
-
-type concurrentTxStmtExecTest struct {
-	db   *DB
-	tx   *Tx
-	stmt *Stmt
-}
-
-func (c *concurrentTxStmtExecTest) init(t testing.TB, db *DB) {
-	c.db = db
-	var err error
-	c.tx, err = c.db.Begin()
-	if err != nil {
-		t.Fatal(err)
-	}
-	c.stmt, err = c.tx.Prepare("NOSERT|people|name=Chris,age=?,photo=CPHOTO,bdate=?")
-	if err != nil {
-		t.Fatal(err)
-	}
-}
-
-func (c *concurrentTxStmtExecTest) finish(t testing.TB) {
-	if c.stmt != nil {
-		c.stmt.Close()
-		c.stmt = nil
-	}
-	if c.tx != nil {
-		c.tx.Rollback()
-		c.tx = nil
-	}
-	c.db = nil
-}
-
-func (c *concurrentTxStmtExecTest) test(t testing.TB) error {
-	_, err := c.stmt.Exec(3, chrisBirthday)
-	if err != nil {
-		t.Errorf("error on exec:  %v", err)
-		return err
-	}
-	return nil
-}
-
-type concurrentRandomTest struct {
-	tests []concurrentTest
-}
-
-func (c *concurrentRandomTest) init(t testing.TB, db *DB) {
-	c.tests = []concurrentTest{
-		new(concurrentDBQueryTest),
-		new(concurrentDBExecTest),
-		new(concurrentStmtQueryTest),
-		new(concurrentStmtExecTest),
-		new(concurrentTxQueryTest),
-		new(concurrentTxExecTest),
-		new(concurrentTxStmtQueryTest),
-		new(concurrentTxStmtExecTest),
-	}
-	for _, ct := range c.tests {
-		ct.init(t, db)
-	}
-}
-
-func (c *concurrentRandomTest) finish(t testing.TB) {
-	for _, ct := range c.tests {
-		ct.finish(t)
-	}
-}
-
-func (c *concurrentRandomTest) test(t testing.TB) error {
-	ct := c.tests[rand.Intn(len(c.tests))]
-	return ct.test(t)
-}
-
-func doConcurrentTest(t testing.TB, ct concurrentTest) {
-	maxProcs, numReqs := 1, 500
-	if testing.Short() {
-		maxProcs, numReqs = 4, 50
-	}
-	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(maxProcs))
-
-	db := newTestDB(t, "people")
-	defer closeDB(t, db)
-
-	ct.init(t, db)
-	defer ct.finish(t)
-
-	var wg sync.WaitGroup
-	wg.Add(numReqs)
-
-	reqs := make(chan bool)
-	defer close(reqs)
-
-	for i := 0; i < maxProcs*2; i++ {
-		go func() {
-			for _ = range reqs {
-				err := ct.test(t)
-				if err != nil {
-					wg.Done()
-					continue
-				}
-				wg.Done()
-			}
-		}()
-	}
-
-	for i := 0; i < numReqs; i++ {
-		reqs <- true
-	}
-
-	wg.Wait()
-}
-
-func manyConcurrentQueries(t testing.TB) {
-	maxProcs, numReqs := 16, 500
-	if testing.Short() {
-		maxProcs, numReqs = 4, 50
-	}
-	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(maxProcs))
-
-	db := newTestDB(t, "people")
-	defer closeDB(t, db)
-
-	stmt, err := db.Prepare("SELECT|people|name|")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer stmt.Close()
-
-	var wg sync.WaitGroup
-	wg.Add(numReqs)
-
-	reqs := make(chan bool)
-	defer close(reqs)
-
-	for i := 0; i < maxProcs*2; i++ {
-		go func() {
-			for _ = range reqs {
-				rows, err := stmt.Query()
-				if err != nil {
-					t.Errorf("error on query:  %v", err)
-					wg.Done()
-					continue
-				}
-
-				var name string
-				for rows.Next() {
-					rows.Scan(&name)
-				}
-				rows.Close()
-
-				wg.Done()
-			}
-		}()
-	}
-
-	for i := 0; i < numReqs; i++ {
-		reqs <- true
-	}
-
-	wg.Wait()
-}
-
-func TestIssue6081(t *testing.T) {
-	db := newTestDB(t, "people")
-	defer closeDB(t, db)
-
-	drv := db.driver.(*fakeDriver)
-	drv.mu.Lock()
-	opens0 := drv.openCount
-	closes0 := drv.closeCount
-	drv.mu.Unlock()
-
-	stmt, err := db.Prepare("SELECT|people|name|")
-	if err != nil {
-		t.Fatal(err)
-	}
-	rowsCloseHook = func(rows *Rows, err *error) {
-		*err = driver.ErrBadConn
-	}
-	defer func() { rowsCloseHook = nil }()
-	for i := 0; i < 10; i++ {
-		rows, err := stmt.Query()
-		if err != nil {
-			t.Fatal(err)
-		}
-		rows.Close()
-	}
-	if n := len(stmt.css); n > 1 {
-		t.Errorf("len(css slice) = %d; want <= 1", n)
-	}
-	stmt.Close()
-	if n := len(stmt.css); n != 0 {
-		t.Errorf("len(css slice) after Close = %d; want 0", n)
-	}
-
-	drv.mu.Lock()
-	opens := drv.openCount - opens0
-	closes := drv.closeCount - closes0
-	drv.mu.Unlock()
-	if opens < 9 {
-		t.Errorf("opens = %d; want >= 9", opens)
-	}
-	if closes < 9 {
-		t.Errorf("closes = %d; want >= 9", closes)
-	}
-}
-
-func TestConcurrency(t *testing.T) {
-	doConcurrentTest(t, new(concurrentDBQueryTest))
-	doConcurrentTest(t, new(concurrentDBExecTest))
-	doConcurrentTest(t, new(concurrentStmtQueryTest))
-	doConcurrentTest(t, new(concurrentStmtExecTest))
-	doConcurrentTest(t, new(concurrentTxQueryTest))
-	doConcurrentTest(t, new(concurrentTxExecTest))
-	doConcurrentTest(t, new(concurrentTxStmtQueryTest))
-	doConcurrentTest(t, new(concurrentTxStmtExecTest))
-	doConcurrentTest(t, new(concurrentRandomTest))
-}
-
-func TestConnectionLeak(t *testing.T) {
-	db := newTestDB(t, "people")
-	defer closeDB(t, db)
-	// Start by opening defaultMaxIdleConns
-	rows := make([]*Rows, defaultMaxIdleConns)
-	// We need to SetMaxOpenConns > MaxIdleConns, so the DB can open
-	// a new connection and we can fill the idle queue with the released
-	// connections.
-	db.SetMaxOpenConns(len(rows) + 1)
-	for ii := range rows {
-		r, err := db.Query("SELECT|people|name|")
-		if err != nil {
-			t.Fatal(err)
-		}
-		r.Next()
-		if err := r.Err(); err != nil {
-			t.Fatal(err)
-		}
-		rows[ii] = r
-	}
-	// Now we have defaultMaxIdleConns busy connections. Open
-	// a new one, but wait until the busy connections are released
-	// before returning control to DB.
-	drv := db.driver.(*fakeDriver)
-	drv.waitCh = make(chan struct{}, 1)
-	drv.waitingCh = make(chan struct{}, 1)
-	var wg sync.WaitGroup
-	wg.Add(1)
-	go func() {
-		r, err := db.Query("SELECT|people|name|")
-		if err != nil {
-			t.Fatal(err)
-		}
-		r.Close()
-		wg.Done()
-	}()
-	// Wait until the goroutine we've just created has started waiting.
-	<-drv.waitingCh
-	// Now close the busy connections. This provides a connection for
-	// the blocked goroutine and then fills up the idle queue.
-	for _, v := range rows {
-		v.Close()
-	}
-	// At this point we give the new connection to DB. This connection is
-	// now useless, since the idle queue is full and there are no pending
-	// requests. DB should deal with this situation without leaking the
-	// connection.
-	drv.waitCh <- struct{}{}
-	wg.Wait()
-}
-
-func BenchmarkConcurrentDBExec(b *testing.B) {
-	b.ReportAllocs()
-	ct := new(concurrentDBExecTest)
-	for i := 0; i < b.N; i++ {
-		doConcurrentTest(b, ct)
-	}
-}
-
-func BenchmarkConcurrentStmtQuery(b *testing.B) {
-	b.ReportAllocs()
-	ct := new(concurrentStmtQueryTest)
-	for i := 0; i < b.N; i++ {
-		doConcurrentTest(b, ct)
-	}
-}
-
-func BenchmarkConcurrentStmtExec(b *testing.B) {
-	b.ReportAllocs()
-	ct := new(concurrentStmtExecTest)
-	for i := 0; i < b.N; i++ {
-		doConcurrentTest(b, ct)
-	}
-}
-
-func BenchmarkConcurrentTxQuery(b *testing.B) {
-	b.ReportAllocs()
-	ct := new(concurrentTxQueryTest)
-	for i := 0; i < b.N; i++ {
-		doConcurrentTest(b, ct)
-	}
-}
-
-func BenchmarkConcurrentTxExec(b *testing.B) {
-	b.ReportAllocs()
-	ct := new(concurrentTxExecTest)
-	for i := 0; i < b.N; i++ {
-		doConcurrentTest(b, ct)
-	}
-}
-
-func BenchmarkConcurrentTxStmtQuery(b *testing.B) {
-	b.ReportAllocs()
-	ct := new(concurrentTxStmtQueryTest)
-	for i := 0; i < b.N; i++ {
-		doConcurrentTest(b, ct)
-	}
-}
-
-func BenchmarkConcurrentTxStmtExec(b *testing.B) {
-	b.ReportAllocs()
-	ct := new(concurrentTxStmtExecTest)
-	for i := 0; i < b.N; i++ {
-		doConcurrentTest(b, ct)
-	}
-}
-
-func BenchmarkConcurrentRandom(b *testing.B) {
-	b.ReportAllocs()
-	ct := new(concurrentRandomTest)
-	for i := 0; i < b.N; i++ {
-		doConcurrentTest(b, ct)
-	}
-}
diff --git a/src/pkg/debug/dwarf/type.go b/src/pkg/debug/dwarf/type.go
deleted file mode 100644
index 68866d0..0000000
--- a/src/pkg/debug/dwarf/type.go
+++ /dev/null
@@ -1,659 +0,0 @@
-// Copyright 2009 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// DWARF type information structures.
-// The format is heavily biased toward C, but for simplicity
-// the String methods use a pseudo-Go syntax.
-
-package dwarf
-
-import "strconv"
-
-// A Type conventionally represents a pointer to any of the
-// specific Type structures (CharType, StructType, etc.).
-type Type interface {
-	Common() *CommonType
-	String() string
-	Size() int64
-}
-
-// A CommonType holds fields common to multiple types.
-// If a field is not known or not applicable for a given type,
-// the zero value is used.
-type CommonType struct {
-	ByteSize int64  // size of value of this type, in bytes
-	Name     string // name that can be used to refer to type
-}
-
-func (c *CommonType) Common() *CommonType { return c }
-
-func (c *CommonType) Size() int64 { return c.ByteSize }
-
-// Basic types
-
-// A BasicType holds fields common to all basic types.
-type BasicType struct {
-	CommonType
-	BitSize   int64
-	BitOffset int64
-}
-
-func (b *BasicType) Basic() *BasicType { return b }
-
-func (t *BasicType) String() string {
-	if t.Name != "" {
-		return t.Name
-	}
-	return "?"
-}
-
-// A CharType represents a signed character type.
-type CharType struct {
-	BasicType
-}
-
-// A UcharType represents an unsigned character type.
-type UcharType struct {
-	BasicType
-}
-
-// An IntType represents a signed integer type.
-type IntType struct {
-	BasicType
-}
-
-// A UintType represents an unsigned integer type.
-type UintType struct {
-	BasicType
-}
-
-// A FloatType represents a floating point type.
-type FloatType struct {
-	BasicType
-}
-
-// A ComplexType represents a complex floating point type.
-type ComplexType struct {
-	BasicType
-}
-
-// A BoolType represents a boolean type.
-type BoolType struct {
-	BasicType
-}
-
-// An AddrType represents a machine address type.
-type AddrType struct {
-	BasicType
-}
-
-// qualifiers
-
-// A QualType represents a type that has the C/C++ "const", "restrict", or "volatile" qualifier.
-type QualType struct {
-	CommonType
-	Qual string
-	Type Type
-}
-
-func (t *QualType) String() string { return t.Qual + " " + t.Type.String() }
-
-func (t *QualType) Size() int64 { return t.Type.Size() }
-
-// An ArrayType represents a fixed size array type.
-type ArrayType struct {
-	CommonType
-	Type          Type
-	StrideBitSize int64 // if > 0, number of bits to hold each element
-	Count         int64 // if == -1, an incomplete array, like char x[].
-}
-
-func (t *ArrayType) String() string {
-	return "[" + strconv.FormatInt(t.Count, 10) + "]" + t.Type.String()
-}
-
-func (t *ArrayType) Size() int64 { return t.Count * t.Type.Size() }
-
-// A VoidType represents the C void type.
-type VoidType struct {
-	CommonType
-}
-
-func (t *VoidType) String() string { return "void" }
-
-// A PtrType represents a pointer type.
-type PtrType struct {
-	CommonType
-	Type Type
-}
-
-func (t *PtrType) String() string { return "*" + t.Type.String() }
-
-// A StructType represents a struct, union, or C++ class type.
-type StructType struct {
-	CommonType
-	StructName string
-	Kind       string // "struct", "union", or "class".
-	Field      []*StructField
-	Incomplete bool // if true, struct, union, class is declared but not defined
-}
-
-// A StructField represents a field in a struct, union, or C++ class type.
-type StructField struct {
-	Name       string
-	Type       Type
-	ByteOffset int64
-	ByteSize   int64
-	BitOffset  int64 // within the ByteSize bytes at ByteOffset
-	BitSize    int64 // zero if not a bit field
-}
-
-func (t *StructType) String() string {
-	if t.StructName != "" {
-		return t.Kind + " " + t.StructName
-	}
-	return t.Defn()
-}
-
-func (t *StructType) Defn() string {
-	s := t.Kind
-	if t.StructName != "" {
-		s += " " + t.StructName
-	}
-	if t.Incomplete {
-		s += " /*incomplete*/"
-		return s
-	}
-	s += " {"
-	for i, f := range t.Field {
-		if i > 0 {
-			s += "; "
-		}
-		s += f.Name + " " + f.Type.String()
-		s += "@" + strconv.FormatInt(f.ByteOffset, 10)
-		if f.BitSize > 0 {
-			s += " : " + strconv.FormatInt(f.BitSize, 10)
-			s += "@" + strconv.FormatInt(f.BitOffset, 10)
-		}
-	}
-	s += "}"
-	return s
-}
-
-// An EnumType represents an enumerated type.
-// The only indication of its native integer type is its ByteSize
-// (inside CommonType).
-type EnumType struct {
-	CommonType
-	EnumName string
-	Val      []*EnumValue
-}
-
-// An EnumValue represents a single enumeration value.
-type EnumValue struct {
-	Name string
-	Val  int64
-}
-
-func (t *EnumType) String() string {
-	s := "enum"
-	if t.EnumName != "" {
-		s += " " + t.EnumName
-	}
-	s += " {"
-	for i, v := range t.Val {
-		if i > 0 {
-			s += "; "
-		}
-		s += v.Name + "=" + strconv.FormatInt(v.Val, 10)
-	}
-	s += "}"
-	return s
-}
-
-// A FuncType represents a function type.
-type FuncType struct {
-	CommonType
-	ReturnType Type
-	ParamType  []Type
-}
-
-func (t *FuncType) String() string {
-	s := "func("
-	for i, t := range t.ParamType {
-		if i > 0 {
-			s += ", "
-		}
-		s += t.String()
-	}
-	s += ")"
-	if t.ReturnType != nil {
-		s += " " + t.ReturnType.String()
-	}
-	return s
-}
-
-// A DotDotDotType represents the variadic ... function parameter.
-type DotDotDotType struct {
-	CommonType
-}
-
-func (t *DotDotDotType) String() string { return "..." }
-
-// A TypedefType represents a named type.
-type TypedefType struct {
-	CommonType
-	Type Type
-}
-
-func (t *TypedefType) String() string { return t.Name }
-
-func (t *TypedefType) Size() int64 { return t.Type.Size() }
-
-// typeReader is used to read from either the info section or the
-// types section.
-type typeReader interface {
-	Seek(Offset)
-	Next() (*Entry, error)
-	clone() typeReader
-	offset() Offset
-}
-
-// Type reads the type at off in the DWARF ``info'' section.
-func (d *Data) Type(off Offset) (Type, error) {
-	return d.readType("info", d.Reader(), off, d.typeCache)
-}
-
-// readType reads a type from r at off of name using and updating a
-// type cache.
-func (d *Data) readType(name string, r typeReader, off Offset, typeCache map[Offset]Type) (Type, error) {
-	if t, ok := typeCache[off]; ok {
-		return t, nil
-	}
-	r.Seek(off)
-	e, err := r.Next()
-	if err != nil {
-		return nil, err
-	}
-	if e == nil || e.Offset != off {
-		return nil, DecodeError{name, off, "no type at offset"}
-	}
-
-	// Parse type from Entry.
-	// Must always set typeCache[off] before calling
-	// d.Type recursively, to handle circular types correctly.
-	var typ Type
-
-	nextDepth := 0
-
-	// Get next child; set err if error happens.
-	next := func() *Entry {
-		if !e.Children {
-			return nil
-		}
-		// Only return direct children.
-		// Skip over composite entries that happen to be nested
-		// inside this one. Most DWARF generators wouldn't generate
-		// such a thing, but clang does.
-		// See golang.org/issue/6472.
-		for {
-			kid, err1 := r.Next()
-			if err1 != nil {
-				err = err1
-				return nil
-			}
-			if kid == nil {
-				err = DecodeError{name, r.offset(), "unexpected end of DWARF entries"}
-				return nil
-			}
-			if kid.Tag == 0 {
-				if nextDepth > 0 {
-					nextDepth--
-					continue
-				}
-				return nil
-			}
-			if kid.Children {
-				nextDepth++
-			}
-			if nextDepth > 0 {
-				continue
-			}
-			return kid
-		}
-	}
-
-	// Get Type referred to by Entry's AttrType field.
-	// Set err if error happens.  Not having a type is an error.
-	typeOf := func(e *Entry) Type {
-		tval := e.Val(AttrType)
-		var t Type
-		switch toff := tval.(type) {
-		case Offset:
-			if t, err = d.readType(name, r.clone(), toff, typeCache); err != nil {
-				return nil
-			}
-		case uint64:
-			if t, err = d.sigToType(toff); err != nil {
-				return nil
-			}
-		default:
-			// It appears that no Type means "void".
-			return new(VoidType)
-		}
-		return t
-	}
-
-	switch e.Tag {
-	case TagArrayType:
-		// Multi-dimensional array.  (DWARF v2 §5.4)
-		// Attributes:
-		//	AttrType:subtype [required]
-		//	AttrStrideSize: size in bits of each element of the array
-		//	AttrByteSize: size of entire array
-		// Children:
-		//	TagSubrangeType or TagEnumerationType giving one dimension.
-		//	dimensions are in left to right order.
-		t := new(ArrayType)
-		typ = t
-		typeCache[off] = t
-		if t.Type = typeOf(e); err != nil {
-			goto Error
-		}
-		t.StrideBitSize, _ = e.Val(AttrStrideSize).(int64)
-
-		// Accumulate dimensions,
-		ndim := 0
-		for kid := next(); kid != nil; kid = next() {
-			// TODO(rsc): Can also be TagEnumerationType
-			// but haven't seen that in the wild yet.
-			switch kid.Tag {
-			case TagSubrangeType:
-				max, ok := kid.Val(AttrUpperBound).(int64)
-				if !ok {
-					max = -2 // Count == -1, as in x[].
-				}
-				if ndim == 0 {
-					t.Count = max + 1
-				} else {
-					// Multidimensional array.
-					// Create new array type underneath this one.
-					t.Type = &ArrayType{Type: t.Type, Count: max + 1}
-				}
-				ndim++
-			case TagEnumerationType:
-				err = DecodeError{name, kid.Offset, "cannot handle enumeration type as array bound"}
-				goto Error
-			}
-		}
-		if ndim == 0 {
-			// LLVM generates this for x[].
-			t.Count = -1
-		}
-
-	case TagBaseType:
-		// Basic type.  (DWARF v2 §5.1)
-		// Attributes:
-		//	AttrName: name of base type in programming language of the compilation unit [required]
-		//	AttrEncoding: encoding value for type (encFloat etc) [required]
-		//	AttrByteSize: size of type in bytes [required]
-		//	AttrBitOffset: for sub-byte types, size in bits
-		//	AttrBitSize: for sub-byte types, bit offset of high order bit in the AttrByteSize bytes
-		name, _ := e.Val(AttrName).(string)
-		enc, ok := e.Val(AttrEncoding).(int64)
-		if !ok {
-			err = DecodeError{name, e.Offset, "missing encoding attribute for " + name}
-			goto Error
-		}
-		switch enc {
-		default:
-			err = DecodeError{name, e.Offset, "unrecognized encoding attribute value"}
-			goto Error
-
-		case encAddress:
-			typ = new(AddrType)
-		case encBoolean:
-			typ = new(BoolType)
-		case encComplexFloat:
-			typ = new(ComplexType)
-		case encFloat:
-			typ = new(FloatType)
-		case encSigned:
-			typ = new(IntType)
-		case encUnsigned:
-			typ = new(UintType)
-		case encSignedChar:
-			typ = new(CharType)
-		case encUnsignedChar:
-			typ = new(UcharType)
-		}
-		typeCache[off] = typ
-		t := typ.(interface {
-			Basic() *BasicType
-		}).Basic()
-		t.Name = name
-		t.BitSize, _ = e.Val(AttrBitSize).(int64)
-		t.BitOffset, _ = e.Val(AttrBitOffset).(int64)
-
-	case TagClassType, TagStructType, TagUnionType:
-		// Structure, union, or class type.  (DWARF v2 §5.5)
-		// Attributes:
-		//	AttrName: name of struct, union, or class
-		//	AttrByteSize: byte size [required]
-		//	AttrDeclaration: if true, struct/union/class is incomplete
-		// Children:
-		//	TagMember to describe one member.
-		//		AttrName: name of member [required]
-		//		AttrType: type of member [required]
-		//		AttrByteSize: size in bytes
-		//		AttrBitOffset: bit offset within bytes for bit fields
-		//		AttrBitSize: bit size for bit fields
-		//		AttrDataMemberLoc: location within struct [required for struct, class]
-		// There is much more to handle C++, all ignored for now.
-		t := new(StructType)
-		typ = t
-		typeCache[off] = t
-		switch e.Tag {
-		case TagClassType:
-			t.Kind = "class"
-		case TagStructType:
-			t.Kind = "struct"
-		case TagUnionType:
-			t.Kind = "union"
-		}
-		t.StructName, _ = e.Val(AttrName).(string)
-		t.Incomplete = e.Val(AttrDeclaration) != nil
-		t.Field = make([]*StructField, 0, 8)
-		var lastFieldType Type
-		var lastFieldBitOffset int64
-		for kid := next(); kid != nil; kid = next() {
-			if kid.Tag == TagMember {
-				f := new(StructField)
-				if f.Type = typeOf(kid); err != nil {
-					goto Error
-				}
-				switch loc := kid.Val(AttrDataMemberLoc).(type) {
-				case []byte:
-					// TODO: Should have original compilation
-					// unit here, not unknownFormat.
-					b := makeBuf(d, unknownFormat{}, "location", 0, loc)
-					if b.uint8() != opPlusUconst {
-						err = DecodeError{name, kid.Offset, "unexpected opcode"}
-						goto Error
-					}
-					f.ByteOffset = int64(b.uint())
-					if b.err != nil {
-						err = b.err
-						goto Error
-					}
-				case int64:
-					f.ByteOffset = loc
-				}
-
-				haveBitOffset := false
-				f.Name, _ = kid.Val(AttrName).(string)
-				f.ByteSize, _ = kid.Val(AttrByteSize).(int64)
-				f.BitOffset, haveBitOffset = kid.Val(AttrBitOffset).(int64)
-				f.BitSize, _ = kid.Val(AttrBitSize).(int64)
-				t.Field = append(t.Field, f)
-
-				bito := f.BitOffset
-				if !haveBitOffset {
-					bito = f.ByteOffset * 8
-				}
-				if bito == lastFieldBitOffset && t.Kind != "union" {
-					// Last field was zero width.  Fix array length.
-					// (DWARF writes out 0-length arrays as if they were 1-length arrays.)
-					zeroArray(lastFieldType)
-				}
-				lastFieldType = f.Type
-				lastFieldBitOffset = bito
-			}
-		}
-		if t.Kind != "union" {
-			b, ok := e.Val(AttrByteSize).(int64)
-			if ok && b*8 == lastFieldBitOffset {
-				// Final field must be zero width.  Fix array length.
-				zeroArray(lastFieldType)
-			}
-		}
-
-	case TagConstType, TagVolatileType, TagRestrictType:
-		// Type modifier (DWARF v2 §5.2)
-		// Attributes:
-		//	AttrType: subtype
-		t := new(QualType)
-		typ = t
-		typeCache[off] = t
-		if t.Type = typeOf(e); err != nil {
-			goto Error
-		}
-		switch e.Tag {
-		case TagConstType:
-			t.Qual = "const"
-		case TagRestrictType:
-			t.Qual = "restrict"
-		case TagVolatileType:
-			t.Qual = "volatile"
-		}
-
-	case TagEnumerationType:
-		// Enumeration type (DWARF v2 §5.6)
-		// Attributes:
-		//	AttrName: enum name if any
-		//	AttrByteSize: bytes required to represent largest value
-		// Children:
-		//	TagEnumerator:
-		//		AttrName: name of constant
-		//		AttrConstValue: value of constant
-		t := new(EnumType)
-		typ = t
-		typeCache[off] = t
-		t.EnumName, _ = e.Val(AttrName).(string)
-		t.Val = make([]*EnumValue, 0, 8)
-		for kid := next(); kid != nil; kid = next() {
-			if kid.Tag == TagEnumerator {
-				f := new(EnumValue)
-				f.Name, _ = kid.Val(AttrName).(string)
-				f.Val, _ = kid.Val(AttrConstValue).(int64)
-				n := len(t.Val)
-				if n >= cap(t.Val) {
-					val := make([]*EnumValue, n, n*2)
-					copy(val, t.Val)
-					t.Val = val
-				}
-				t.Val = t.Val[0 : n+1]
-				t.Val[n] = f
-			}
-		}
-
-	case TagPointerType:
-		// Type modifier (DWARF v2 §5.2)
-		// Attributes:
-		//	AttrType: subtype [not required!  void* has no AttrType]
-		//	AttrAddrClass: address class [ignored]
-		t := new(PtrType)
-		typ = t
-		typeCache[off] = t
-		if e.Val(AttrType) == nil {
-			t.Type = &VoidType{}
-			break
-		}
-		t.Type = typeOf(e)
-
-	case TagSubroutineType:
-		// Subroutine type.  (DWARF v2 §5.7)
-		// Attributes:
-		//	AttrType: type of return value if any
-		//	AttrName: possible name of type [ignored]
-		//	AttrPrototyped: whether used ANSI C prototype [ignored]
-		// Children:
-		//	TagFormalParameter: typed parameter
-		//		AttrType: type of parameter
-		//	TagUnspecifiedParameter: final ...
-		t := new(FuncType)
-		typ = t
-		typeCache[off] = t
-		if t.ReturnType = typeOf(e); err != nil {
-			goto Error
-		}
-		t.ParamType = make([]Type, 0, 8)
-		for kid := next(); kid != nil; kid = next() {
-			var tkid Type
-			switch kid.Tag {
-			default:
-				continue
-			case TagFormalParameter:
-				if tkid = typeOf(kid); err != nil {
-					goto Error
-				}
-			case TagUnspecifiedParameters:
-				tkid = &DotDotDotType{}
-			}
-			t.ParamType = append(t.ParamType, tkid)
-		}
-
-	case TagTypedef:
-		// Typedef (DWARF v2 §5.3)
-		// Attributes:
-		//	AttrName: name [required]
-		//	AttrType: type definition [required]
-		t := new(TypedefType)
-		typ = t
-		typeCache[off] = t
-		t.Name, _ = e.Val(AttrName).(string)
-		t.Type = typeOf(e)
-	}
-
-	if err != nil {
-		goto Error
-	}
-
-	{
-		b, ok := e.Val(AttrByteSize).(int64)
-		if !ok {
-			b = -1
-		}
-		typ.Common().ByteSize = b
-	}
-	return typ, nil
-
-Error:
-	// If the parse fails, take the type out of the cache
-	// so that the next call with this offset doesn't hit
-	// the cache and return success.
-	delete(typeCache, off)
-	return nil, err
-}
-
-func zeroArray(t Type) {
-	for {
-		at, ok := t.(*ArrayType)
-		if !ok {
-			break
-		}
-		at.Count = 0
-		t = at.Type
-	}
-}
diff --git a/src/pkg/debug/elf/elf.go b/src/pkg/debug/elf/elf.go
deleted file mode 100644
index d622dae..0000000
--- a/src/pkg/debug/elf/elf.go
+++ /dev/null
@@ -1,1521 +0,0 @@
-/*
- * ELF constants and data structures
- *
- * Derived from:
- * $FreeBSD: src/sys/sys/elf32.h,v 1.8.14.1 2005/12/30 22:13:58 marcel Exp $
- * $FreeBSD: src/sys/sys/elf64.h,v 1.10.14.1 2005/12/30 22:13:58 marcel Exp $
- * $FreeBSD: src/sys/sys/elf_common.h,v 1.15.8.1 2005/12/30 22:13:58 marcel Exp $
- * $FreeBSD: src/sys/alpha/include/elf.h,v 1.14 2003/09/25 01:10:22 peter Exp $
- * $FreeBSD: src/sys/amd64/include/elf.h,v 1.18 2004/08/03 08:21:48 dfr Exp $
- * $FreeBSD: src/sys/arm/include/elf.h,v 1.5.2.1 2006/06/30 21:42:52 cognet Exp $
- * $FreeBSD: src/sys/i386/include/elf.h,v 1.16 2004/08/02 19:12:17 dfr Exp $
- * $FreeBSD: src/sys/powerpc/include/elf.h,v 1.7 2004/11/02 09:47:01 ssouhlal Exp $
- * $FreeBSD: src/sys/sparc64/include/elf.h,v 1.12 2003/09/25 01:10:26 peter Exp $
- *
- * Copyright (c) 1996-1998 John D. Polstra.  All rights reserved.
- * Copyright (c) 2001 David E. O'Brien
- * Portions Copyright 2009 The Go Authors.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-package elf
-
-import "strconv"
-
-/*
- * Constants
- */
-
-// Indexes into the Header.Ident array.
-const (
-	EI_CLASS      = 4  /* Class of machine. */
-	EI_DATA       = 5  /* Data format. */
-	EI_VERSION    = 6  /* ELF format version. */
-	EI_OSABI      = 7  /* Operating system / ABI identification */
-	EI_ABIVERSION = 8  /* ABI version */
-	EI_PAD        = 9  /* Start of padding (per SVR4 ABI). */
-	EI_NIDENT     = 16 /* Size of e_ident array. */
-)
-
-// Initial magic number for ELF files.
-const ELFMAG = "\177ELF"
-
-// Version is found in Header.Ident[EI_VERSION] and Header.Version.
-type Version byte
-
-const (
-	EV_NONE    Version = 0
-	EV_CURRENT Version = 1
-)
-
-var versionStrings = []intName{
-	{0, "EV_NONE"},
-	{1, "EV_CURRENT"},
-}
-
-func (i Version) String() string   { return stringName(uint32(i), versionStrings, false) }
-func (i Version) GoString() string { return stringName(uint32(i), versionStrings, true) }
-
-// Class is found in Header.Ident[EI_CLASS] and Header.Class.
-type Class byte
-
-const (
-	ELFCLASSNONE Class = 0 /* Unknown class. */
-	ELFCLASS32   Class = 1 /* 32-bit architecture. */
-	ELFCLASS64   Class = 2 /* 64-bit architecture. */
-)
-
-var classStrings = []intName{
-	{0, "ELFCLASSNONE"},
-	{1, "ELFCLASS32"},
-	{2, "ELFCLASS64"},
-}
-
-func (i Class) String() string   { return stringName(uint32(i), classStrings, false) }
-func (i Class) GoString() string { return stringName(uint32(i), classStrings, true) }
-
-// Data is found in Header.Ident[EI_DATA] and Header.Data.
-type Data byte
-
-const (
-	ELFDATANONE Data = 0 /* Unknown data format. */
-	ELFDATA2LSB Data = 1 /* 2's complement little-endian. */
-	ELFDATA2MSB Data = 2 /* 2's complement big-endian. */
-)
-
-var dataStrings = []intName{
-	{0, "ELFDATANONE"},
-	{1, "ELFDATA2LSB"},
-	{2, "ELFDATA2MSB"},
-}
-
-func (i Data) String() string   { return stringName(uint32(i), dataStrings, false) }
-func (i Data) GoString() string { return stringName(uint32(i), dataStrings, true) }
-
-// OSABI is found in Header.Ident[EI_OSABI] and Header.OSABI.
-type OSABI byte
-
-const (
-	ELFOSABI_NONE       OSABI = 0   /* UNIX System V ABI */
-	ELFOSABI_HPUX       OSABI = 1   /* HP-UX operating system */
-	ELFOSABI_NETBSD     OSABI = 2   /* NetBSD */
-	ELFOSABI_LINUX      OSABI = 3   /* GNU/Linux */
-	ELFOSABI_HURD       OSABI = 4   /* GNU/Hurd */
-	ELFOSABI_86OPEN     OSABI = 5   /* 86Open common IA32 ABI */
-	ELFOSABI_SOLARIS    OSABI = 6   /* Solaris */
-	ELFOSABI_AIX        OSABI = 7   /* AIX */
-	ELFOSABI_IRIX       OSABI = 8   /* IRIX */
-	ELFOSABI_FREEBSD    OSABI = 9   /* FreeBSD */
-	ELFOSABI_TRU64      OSABI = 10  /* TRU64 UNIX */
-	ELFOSABI_MODESTO    OSABI = 11  /* Novell Modesto */
-	ELFOSABI_OPENBSD    OSABI = 12  /* OpenBSD */
-	ELFOSABI_OPENVMS    OSABI = 13  /* Open VMS */
-	ELFOSABI_NSK        OSABI = 14  /* HP Non-Stop Kernel */
-	ELFOSABI_ARM        OSABI = 97  /* ARM */
-	ELFOSABI_STANDALONE OSABI = 255 /* Standalone (embedded) application */
-)
-
-var osabiStrings = []intName{
-	{0, "ELFOSABI_NONE"},
-	{1, "ELFOSABI_HPUX"},
-	{2, "ELFOSABI_NETBSD"},
-	{3, "ELFOSABI_LINUX"},
-	{4, "ELFOSABI_HURD"},
-	{5, "ELFOSABI_86OPEN"},
-	{6, "ELFOSABI_SOLARIS"},
-	{7, "ELFOSABI_AIX"},
-	{8, "ELFOSABI_IRIX"},
-	{9, "ELFOSABI_FREEBSD"},
-	{10, "ELFOSABI_TRU64"},
-	{11, "ELFOSABI_MODESTO"},
-	{12, "ELFOSABI_OPENBSD"},
-	{13, "ELFOSABI_OPENVMS"},
-	{14, "ELFOSABI_NSK"},
-	{97, "ELFOSABI_ARM"},
-	{255, "ELFOSABI_STANDALONE"},
-}
-
-func (i OSABI) String() string   { return stringName(uint32(i), osabiStrings, false) }
-func (i OSABI) GoString() string { return stringName(uint32(i), osabiStrings, true) }
-
-// Type is found in Header.Type.
-type Type uint16
-
-const (
-	ET_NONE   Type = 0      /* Unknown type. */
-	ET_REL    Type = 1      /* Relocatable. */
-	ET_EXEC   Type = 2      /* Executable. */
-	ET_DYN    Type = 3      /* Shared object. */
-	ET_CORE   Type = 4      /* Core file. */
-	ET_LOOS   Type = 0xfe00 /* First operating system specific. */
-	ET_HIOS   Type = 0xfeff /* Last operating system-specific. */
-	ET_LOPROC Type = 0xff00 /* First processor-specific. */
-	ET_HIPROC Type = 0xffff /* Last processor-specific. */
-)
-
-var typeStrings = []intName{
-	{0, "ET_NONE"},
-	{1, "ET_REL"},
-	{2, "ET_EXEC"},
-	{3, "ET_DYN"},
-	{4, "ET_CORE"},
-	{0xfe00, "ET_LOOS"},
-	{0xfeff, "ET_HIOS"},
-	{0xff00, "ET_LOPROC"},
-	{0xffff, "ET_HIPROC"},
-}
-
-func (i Type) String() string   { return stringName(uint32(i), typeStrings, false) }
-func (i Type) GoString() string { return stringName(uint32(i), typeStrings, true) }
-
-// Machine is found in Header.Machine.
-type Machine uint16
-
-const (
-	EM_NONE        Machine = 0  /* Unknown machine. */
-	EM_M32         Machine = 1  /* AT&T WE32100. */
-	EM_SPARC       Machine = 2  /* Sun SPARC. */
-	EM_386         Machine = 3  /* Intel i386. */
-	EM_68K         Machine = 4  /* Motorola 68000. */
-	EM_88K         Machine = 5  /* Motorola 88000. */
-	EM_860         Machine = 7  /* Intel i860. */
-	EM_MIPS        Machine = 8  /* MIPS R3000 Big-Endian only. */
-	EM_S370        Machine = 9  /* IBM System/370. */
-	EM_MIPS_RS3_LE Machine = 10 /* MIPS R3000 Little-Endian. */
-	EM_PARISC      Machine = 15 /* HP PA-RISC. */
-	EM_VPP500      Machine = 17 /* Fujitsu VPP500. */
-	EM_SPARC32PLUS Machine = 18 /* SPARC v8plus. */
-	EM_960         Machine = 19 /* Intel 80960. */
-	EM_PPC         Machine = 20 /* PowerPC 32-bit. */
-	EM_PPC64       Machine = 21 /* PowerPC 64-bit. */
-	EM_S390        Machine = 22 /* IBM System/390. */
-	EM_V800        Machine = 36 /* NEC V800. */
-	EM_FR20        Machine = 37 /* Fujitsu FR20. */
-	EM_RH32        Machine = 38 /* TRW RH-32. */
-	EM_RCE         Machine = 39 /* Motorola RCE. */
-	EM_ARM         Machine = 40 /* ARM. */
-	EM_SH          Machine = 42 /* Hitachi SH. */
-	EM_SPARCV9     Machine = 43 /* SPARC v9 64-bit. */
-	EM_TRICORE     Machine = 44 /* Siemens TriCore embedded processor. */
-	EM_ARC         Machine = 45 /* Argonaut RISC Core. */
-	EM_H8_300      Machine = 46 /* Hitachi H8/300. */
-	EM_H8_300H     Machine = 47 /* Hitachi H8/300H. */
-	EM_H8S         Machine = 48 /* Hitachi H8S. */
-	EM_H8_500      Machine = 49 /* Hitachi H8/500. */
-	EM_IA_64       Machine = 50 /* Intel IA-64 Processor. */
-	EM_MIPS_X      Machine = 51 /* Stanford MIPS-X. */
-	EM_COLDFIRE    Machine = 52 /* Motorola ColdFire. */
-	EM_68HC12      Machine = 53 /* Motorola M68HC12. */
-	EM_MMA         Machine = 54 /* Fujitsu MMA. */
-	EM_PCP         Machine = 55 /* Siemens PCP. */
-	EM_NCPU        Machine = 56 /* Sony nCPU. */
-	EM_NDR1        Machine = 57 /* Denso NDR1 microprocessor. */
-	EM_STARCORE    Machine = 58 /* Motorola Star*Core processor. */
-	EM_ME16        Machine = 59 /* Toyota ME16 processor. */
-	EM_ST100       Machine = 60 /* STMicroelectronics ST100 processor. */
-	EM_TINYJ       Machine = 61 /* Advanced Logic Corp. TinyJ processor. */
-	EM_X86_64      Machine = 62 /* Advanced Micro Devices x86-64 */
-
-	/* Non-standard or deprecated. */
-	EM_486         Machine = 6      /* Intel i486. */
-	EM_MIPS_RS4_BE Machine = 10     /* MIPS R4000 Big-Endian */
-	EM_ALPHA_STD   Machine = 41     /* Digital Alpha (standard value). */
-	EM_ALPHA       Machine = 0x9026 /* Alpha (written in the absence of an ABI) */
-)
-
-var machineStrings = []intName{
-	{0, "EM_NONE"},
-	{1, "EM_M32"},
-	{2, "EM_SPARC"},
-	{3, "EM_386"},
-	{4, "EM_68K"},
-	{5, "EM_88K"},
-	{7, "EM_860"},
-	{8, "EM_MIPS"},
-	{9, "EM_S370"},
-	{10, "EM_MIPS_RS3_LE"},
-	{15, "EM_PARISC"},
-	{17, "EM_VPP500"},
-	{18, "EM_SPARC32PLUS"},
-	{19, "EM_960"},
-	{20, "EM_PPC"},
-	{21, "EM_PPC64"},
-	{22, "EM_S390"},
-	{36, "EM_V800"},
-	{37, "EM_FR20"},
-	{38, "EM_RH32"},
-	{39, "EM_RCE"},
-	{40, "EM_ARM"},
-	{42, "EM_SH"},
-	{43, "EM_SPARCV9"},
-	{44, "EM_TRICORE"},
-	{45, "EM_ARC"},
-	{46, "EM_H8_300"},
-	{47, "EM_H8_300H"},
-	{48, "EM_H8S"},
-	{49, "EM_H8_500"},
-	{50, "EM_IA_64"},
-	{51, "EM_MIPS_X"},
-	{52, "EM_COLDFIRE"},
-	{53, "EM_68HC12"},
-	{54, "EM_MMA"},
-	{55, "EM_PCP"},
-	{56, "EM_NCPU"},
-	{57, "EM_NDR1"},
-	{58, "EM_STARCORE"},
-	{59, "EM_ME16"},
-	{60, "EM_ST100"},
-	{61, "EM_TINYJ"},
-	{62, "EM_X86_64"},
-
-	/* Non-standard or deprecated. */
-	{6, "EM_486"},
-	{10, "EM_MIPS_RS4_BE"},
-	{41, "EM_ALPHA_STD"},
-	{0x9026, "EM_ALPHA"},
-}
-
-func (i Machine) String() string   { return stringName(uint32(i), machineStrings, false) }
-func (i Machine) GoString() string { return stringName(uint32(i), machineStrings, true) }
-
-// Special section indices.
-type SectionIndex int
-
-const (
-	SHN_UNDEF     SectionIndex = 0      /* Undefined, missing, irrelevant. */
-	SHN_LORESERVE SectionIndex = 0xff00 /* First of reserved range. */
-	SHN_LOPROC    SectionIndex = 0xff00 /* First processor-specific. */
-	SHN_HIPROC    SectionIndex = 0xff1f /* Last processor-specific. */
-	SHN_LOOS      SectionIndex = 0xff20 /* First operating system-specific. */
-	SHN_HIOS      SectionIndex = 0xff3f /* Last operating system-specific. */
-	SHN_ABS       SectionIndex = 0xfff1 /* Absolute values. */
-	SHN_COMMON    SectionIndex = 0xfff2 /* Common data. */
-	SHN_XINDEX    SectionIndex = 0xffff /* Escape -- index stored elsewhere. */
-	SHN_HIRESERVE SectionIndex = 0xffff /* Last of reserved range. */
-)
-
-var shnStrings = []intName{
-	{0, "SHN_UNDEF"},
-	{0xff00, "SHN_LOPROC"},
-	{0xff20, "SHN_LOOS"},
-	{0xfff1, "SHN_ABS"},
-	{0xfff2, "SHN_COMMON"},
-	{0xffff, "SHN_XINDEX"},
-}
-
-func (i SectionIndex) String() string   { return stringName(uint32(i), shnStrings, false) }
-func (i SectionIndex) GoString() string { return stringName(uint32(i), shnStrings, true) }
-
-// Section type.
-type SectionType uint32
-
-const (
-	SHT_NULL           SectionType = 0          /* inactive */
-	SHT_PROGBITS       SectionType = 1          /* program defined information */
-	SHT_SYMTAB         SectionType = 2          /* symbol table section */
-	SHT_STRTAB         SectionType = 3          /* string table section */
-	SHT_RELA           SectionType = 4          /* relocation section with addends */
-	SHT_HASH           SectionType = 5          /* symbol hash table section */
-	SHT_DYNAMIC        SectionType = 6          /* dynamic section */
-	SHT_NOTE           SectionType = 7          /* note section */
-	SHT_NOBITS         SectionType = 8          /* no space section */
-	SHT_REL            SectionType = 9          /* relocation section - no addends */
-	SHT_SHLIB          SectionType = 10         /* reserved - purpose unknown */
-	SHT_DYNSYM         SectionType = 11         /* dynamic symbol table section */
-	SHT_INIT_ARRAY     SectionType = 14         /* Initialization function pointers. */
-	SHT_FINI_ARRAY     SectionType = 15         /* Termination function pointers. */
-	SHT_PREINIT_ARRAY  SectionType = 16         /* Pre-initialization function ptrs. */
-	SHT_GROUP          SectionType = 17         /* Section group. */
-	SHT_SYMTAB_SHNDX   SectionType = 18         /* Section indexes (see SHN_XINDEX). */
-	SHT_LOOS           SectionType = 0x60000000 /* First of OS specific semantics */
-	SHT_GNU_ATTRIBUTES SectionType = 0x6ffffff5 /* GNU object attributes */
-	SHT_GNU_HASH       SectionType = 0x6ffffff6 /* GNU hash table */
-	SHT_GNU_LIBLIST    SectionType = 0x6ffffff7 /* GNU prelink library list */
-	SHT_GNU_VERDEF     SectionType = 0x6ffffffd /* GNU version definition section */
-	SHT_GNU_VERNEED    SectionType = 0x6ffffffe /* GNU version needs section */
-	SHT_GNU_VERSYM     SectionType = 0x6fffffff /* GNU version symbol table */
-	SHT_HIOS           SectionType = 0x6fffffff /* Last of OS specific semantics */
-	SHT_LOPROC         SectionType = 0x70000000 /* reserved range for processor */
-	SHT_HIPROC         SectionType = 0x7fffffff /* specific section header types */
-	SHT_LOUSER         SectionType = 0x80000000 /* reserved range for application */
-	SHT_HIUSER         SectionType = 0xffffffff /* specific indexes */
-)
-
-var shtStrings = []intName{
-	{0, "SHT_NULL"},
-	{1, "SHT_PROGBITS"},
-	{2, "SHT_SYMTAB"},
-	{3, "SHT_STRTAB"},
-	{4, "SHT_RELA"},
-	{5, "SHT_HASH"},
-	{6, "SHT_DYNAMIC"},
-	{7, "SHT_NOTE"},
-	{8, "SHT_NOBITS"},
-	{9, "SHT_REL"},
-	{10, "SHT_SHLIB"},
-	{11, "SHT_DYNSYM"},
-	{14, "SHT_INIT_ARRAY"},
-	{15, "SHT_FINI_ARRAY"},
-	{16, "SHT_PREINIT_ARRAY"},
-	{17, "SHT_GROUP"},
-	{18, "SHT_SYMTAB_SHNDX"},
-	{0x60000000, "SHT_LOOS"},
-	{0x6ffffff5, "SHT_GNU_ATTRIBUTES"},
-	{0x6ffffff6, "SHT_GNU_HASH"},
-	{0x6ffffff7, "SHT_GNU_LIBLIST"},
-	{0x6ffffffd, "SHT_GNU_VERDEF"},
-	{0x6ffffffe, "SHT_GNU_VERNEED"},
-	{0x6fffffff, "SHT_GNU_VERSYM"},
-	{0x70000000, "SHT_LOPROC"},
-	{0x7fffffff, "SHT_HIPROC"},
-	{0x80000000, "SHT_LOUSER"},
-	{0xffffffff, "SHT_HIUSER"},
-}
-
-func (i SectionType) String() string   { return stringName(uint32(i), shtStrings, false) }
-func (i SectionType) GoString() string { return stringName(uint32(i), shtStrings, true) }
-
-// Section flags.
-type SectionFlag uint32
-
-const (
-	SHF_WRITE            SectionFlag = 0x1        /* Section contains writable data. */
-	SHF_ALLOC            SectionFlag = 0x2        /* Section occupies memory. */
-	SHF_EXECINSTR        SectionFlag = 0x4        /* Section contains instructions. */
-	SHF_MERGE            SectionFlag = 0x10       /* Section may be merged. */
-	SHF_STRINGS          SectionFlag = 0x20       /* Section contains strings. */
-	SHF_INFO_LINK        SectionFlag = 0x40       /* sh_info holds section index. */
-	SHF_LINK_ORDER       SectionFlag = 0x80       /* Special ordering requirements. */
-	SHF_OS_NONCONFORMING SectionFlag = 0x100      /* OS-specific processing required. */
-	SHF_GROUP            SectionFlag = 0x200      /* Member of section group. */
-	SHF_TLS              SectionFlag = 0x400      /* Section contains TLS data. */
-	SHF_MASKOS           SectionFlag = 0x0ff00000 /* OS-specific semantics. */
-	SHF_MASKPROC         SectionFlag = 0xf0000000 /* Processor-specific semantics. */
-)
-
-var shfStrings = []intName{
-	{0x1, "SHF_WRITE"},
-	{0x2, "SHF_ALLOC"},
-	{0x4, "SHF_EXECINSTR"},
-	{0x10, "SHF_MERGE"},
-	{0x20, "SHF_STRINGS"},
-	{0x40, "SHF_INFO_LINK"},
-	{0x80, "SHF_LINK_ORDER"},
-	{0x100, "SHF_OS_NONCONFORMING"},
-	{0x200, "SHF_GROUP"},
-	{0x400, "SHF_TLS"},
-}
-
-func (i SectionFlag) String() string   { return flagName(uint32(i), shfStrings, false) }
-func (i SectionFlag) GoString() string { return flagName(uint32(i), shfStrings, true) }
-
-// Prog.Type
-type ProgType int
-
-const (
-	PT_NULL    ProgType = 0          /* Unused entry. */
-	PT_LOAD    ProgType = 1          /* Loadable segment. */
-	PT_DYNAMIC ProgType = 2          /* Dynamic linking information segment. */
-	PT_INTERP  ProgType = 3          /* Pathname of interpreter. */
-	PT_NOTE    ProgType = 4          /* Auxiliary information. */
-	PT_SHLIB   ProgType = 5          /* Reserved (not used). */
-	PT_PHDR    ProgType = 6          /* Location of program header itself. */
-	PT_TLS     ProgType = 7          /* Thread local storage segment */
-	PT_LOOS    ProgType = 0x60000000 /* First OS-specific. */
-	PT_HIOS    ProgType = 0x6fffffff /* Last OS-specific. */
-	PT_LOPROC  ProgType = 0x70000000 /* First processor-specific type. */
-	PT_HIPROC  ProgType = 0x7fffffff /* Last processor-specific type. */
-)
-
-var ptStrings = []intName{
-	{0, "PT_NULL"},
-	{1, "PT_LOAD"},
-	{2, "PT_DYNAMIC"},
-	{3, "PT_INTERP"},
-	{4, "PT_NOTE"},
-	{5, "PT_SHLIB"},
-	{6, "PT_PHDR"},
-	{7, "PT_TLS"},
-	{0x60000000, "PT_LOOS"},
-	{0x6fffffff, "PT_HIOS"},
-	{0x70000000, "PT_LOPROC"},
-	{0x7fffffff, "PT_HIPROC"},
-}
-
-func (i ProgType) String() string   { return stringName(uint32(i), ptStrings, false) }
-func (i ProgType) GoString() string { return stringName(uint32(i), ptStrings, true) }
-
-// Prog.Flag
-type ProgFlag uint32
-
-const (
-	PF_X        ProgFlag = 0x1        /* Executable. */
-	PF_W        ProgFlag = 0x2        /* Writable. */
-	PF_R        ProgFlag = 0x4        /* Readable. */
-	PF_MASKOS   ProgFlag = 0x0ff00000 /* Operating system-specific. */
-	PF_MASKPROC ProgFlag = 0xf0000000 /* Processor-specific. */
-)
-
-var pfStrings = []intName{
-	{0x1, "PF_X"},
-	{0x2, "PF_W"},
-	{0x4, "PF_R"},
-}
-
-func (i ProgFlag) String() string   { return flagName(uint32(i), pfStrings, false) }
-func (i ProgFlag) GoString() string { return flagName(uint32(i), pfStrings, true) }
-
-// Dyn.Tag
-type DynTag int
-
-const (
-	DT_NULL         DynTag = 0  /* Terminating entry. */
-	DT_NEEDED       DynTag = 1  /* String table offset of a needed shared library. */
-	DT_PLTRELSZ     DynTag = 2  /* Total size in bytes of PLT relocations. */
-	DT_PLTGOT       DynTag = 3  /* Processor-dependent address. */
-	DT_HASH         DynTag = 4  /* Address of symbol hash table. */
-	DT_STRTAB       DynTag = 5  /* Address of string table. */
-	DT_SYMTAB       DynTag = 6  /* Address of symbol table. */
-	DT_RELA         DynTag = 7  /* Address of ElfNN_Rela relocations. */
-	DT_RELASZ       DynTag = 8  /* Total size of ElfNN_Rela relocations. */
-	DT_RELAENT      DynTag = 9  /* Size of each ElfNN_Rela relocation entry. */
-	DT_STRSZ        DynTag = 10 /* Size of string table. */
-	DT_SYMENT       DynTag = 11 /* Size of each symbol table entry. */
-	DT_INIT         DynTag = 12 /* Address of initialization function. */
-	DT_FINI         DynTag = 13 /* Address of finalization function. */
-	DT_SONAME       DynTag = 14 /* String table offset of shared object name. */
-	DT_RPATH        DynTag = 15 /* String table offset of library path. [sup] */
-	DT_SYMBOLIC     DynTag = 16 /* Indicates "symbolic" linking. [sup] */
-	DT_REL          DynTag = 17 /* Address of ElfNN_Rel relocations. */
-	DT_RELSZ        DynTag = 18 /* Total size of ElfNN_Rel relocations. */
-	DT_RELENT       DynTag = 19 /* Size of each ElfNN_Rel relocation. */
-	DT_PLTREL       DynTag = 20 /* Type of relocation used for PLT. */
-	DT_DEBUG        DynTag = 21 /* Reserved (not used). */
-	DT_TEXTREL      DynTag = 22 /* Indicates there may be relocations in non-writable segments. [sup] */
-	DT_JMPREL       DynTag = 23 /* Address of PLT relocations. */
-	DT_BIND_NOW     DynTag = 24 /* [sup] */
-	DT_INIT_ARRAY   DynTag = 25 /* Address of the array of pointers to initialization functions */
-	DT_FINI_ARRAY   DynTag = 26 /* Address of the array of pointers to termination functions */
-	DT_INIT_ARRAYSZ DynTag = 27 /* Size in bytes of the array of initialization functions. */
-	DT_FINI_ARRAYSZ DynTag = 28 /* Size in bytes of the array of termination functions. */
-	DT_RUNPATH      DynTag = 29 /* String table offset of a null-terminated library search path string. */
-	DT_FLAGS        DynTag = 30 /* Object specific flag values. */
-	DT_ENCODING     DynTag = 32 /* Values greater than or equal to DT_ENCODING
-	   and less than DT_LOOS follow the rules for
-	   the interpretation of the d_un union
-	   as follows: even == 'd_ptr', even == 'd_val'
-	   or none */
-	DT_PREINIT_ARRAY   DynTag = 32         /* Address of the array of pointers to pre-initialization functions. */
-	DT_PREINIT_ARRAYSZ DynTag = 33         /* Size in bytes of the array of pre-initialization functions. */
-	DT_LOOS            DynTag = 0x6000000d /* First OS-specific */
-	DT_HIOS            DynTag = 0x6ffff000 /* Last OS-specific */
-	DT_VERSYM          DynTag = 0x6ffffff0
-	DT_VERNEED         DynTag = 0x6ffffffe
-	DT_VERNEEDNUM      DynTag = 0x6fffffff
-	DT_LOPROC          DynTag = 0x70000000 /* First processor-specific type. */
-	DT_HIPROC          DynTag = 0x7fffffff /* Last processor-specific type. */
-)
-
-var dtStrings = []intName{
-	{0, "DT_NULL"},
-	{1, "DT_NEEDED"},
-	{2, "DT_PLTRELSZ"},
-	{3, "DT_PLTGOT"},
-	{4, "DT_HASH"},
-	{5, "DT_STRTAB"},
-	{6, "DT_SYMTAB"},
-	{7, "DT_RELA"},
-	{8, "DT_RELASZ"},
-	{9, "DT_RELAENT"},
-	{10, "DT_STRSZ"},
-	{11, "DT_SYMENT"},
-	{12, "DT_INIT"},
-	{13, "DT_FINI"},
-	{14, "DT_SONAME"},
-	{15, "DT_RPATH"},
-	{16, "DT_SYMBOLIC"},
-	{17, "DT_REL"},
-	{18, "DT_RELSZ"},
-	{19, "DT_RELENT"},
-	{20, "DT_PLTREL"},
-	{21, "DT_DEBUG"},
-	{22, "DT_TEXTREL"},
-	{23, "DT_JMPREL"},
-	{24, "DT_BIND_NOW"},
-	{25, "DT_INIT_ARRAY"},
-	{26, "DT_FINI_ARRAY"},
-	{27, "DT_INIT_ARRAYSZ"},
-	{28, "DT_FINI_ARRAYSZ"},
-	{29, "DT_RUNPATH"},
-	{30, "DT_FLAGS"},
-	{32, "DT_ENCODING"},
-	{32, "DT_PREINIT_ARRAY"},
-	{33, "DT_PREINIT_ARRAYSZ"},
-	{0x6000000d, "DT_LOOS"},
-	{0x6ffff000, "DT_HIOS"},
-	{0x6ffffff0, "DT_VERSYM"},
-	{0x6ffffffe, "DT_VERNEED"},
-	{0x6fffffff, "DT_VERNEEDNUM"},
-	{0x70000000, "DT_LOPROC"},
-	{0x7fffffff, "DT_HIPROC"},
-}
-
-func (i DynTag) String() string   { return stringName(uint32(i), dtStrings, false) }
-func (i DynTag) GoString() string { return stringName(uint32(i), dtStrings, true) }
-
-// DT_FLAGS values.
-type DynFlag int
-
-const (
-	DF_ORIGIN DynFlag = 0x0001 /* Indicates that the object being loaded may
-	   make reference to the
-	   $ORIGIN substitution string */
-	DF_SYMBOLIC DynFlag = 0x0002 /* Indicates "symbolic" linking. */
-	DF_TEXTREL  DynFlag = 0x0004 /* Indicates there may be relocations in non-writable segments. */
-	DF_BIND_NOW DynFlag = 0x0008 /* Indicates that the dynamic linker should
-	   process all relocations for the object
-	   containing this entry before transferring
-	   control to the program. */
-	DF_STATIC_TLS DynFlag = 0x0010 /* Indicates that the shared object or
-	   executable contains code using a static
-	   thread-local storage scheme. */
-)
-
-var dflagStrings = []intName{
-	{0x0001, "DF_ORIGIN"},
-	{0x0002, "DF_SYMBOLIC"},
-	{0x0004, "DF_TEXTREL"},
-	{0x0008, "DF_BIND_NOW"},
-	{0x0010, "DF_STATIC_TLS"},
-}
-
-func (i DynFlag) String() string   { return flagName(uint32(i), dflagStrings, false) }
-func (i DynFlag) GoString() string { return flagName(uint32(i), dflagStrings, true) }
-
-// NType values; used in core files.
-type NType int
-
-const (
-	NT_PRSTATUS NType = 1 /* Process status. */
-	NT_FPREGSET NType = 2 /* Floating point registers. */
-	NT_PRPSINFO NType = 3 /* Process state info. */
-)
-
-var ntypeStrings = []intName{
-	{1, "NT_PRSTATUS"},
-	{2, "NT_FPREGSET"},
-	{3, "NT_PRPSINFO"},
-}
-
-func (i NType) String() string   { return stringName(uint32(i), ntypeStrings, false) }
-func (i NType) GoString() string { return stringName(uint32(i), ntypeStrings, true) }
-
-/* Symbol Binding - ELFNN_ST_BIND - st_info */
-type SymBind int
-
-const (
-	STB_LOCAL  SymBind = 0  /* Local symbol */
-	STB_GLOBAL SymBind = 1  /* Global symbol */
-	STB_WEAK   SymBind = 2  /* like global - lower precedence */
-	STB_LOOS   SymBind = 10 /* Reserved range for operating system */
-	STB_HIOS   SymBind = 12 /*   specific semantics. */
-	STB_LOPROC SymBind = 13 /* reserved range for processor */
-	STB_HIPROC SymBind = 15 /*   specific semantics. */
-)
-
-var stbStrings = []intName{
-	{0, "STB_LOCAL"},
-	{1, "STB_GLOBAL"},
-	{2, "STB_WEAK"},
-	{10, "STB_LOOS"},
-	{12, "STB_HIOS"},
-	{13, "STB_LOPROC"},
-	{15, "STB_HIPROC"},
-}
-
-func (i SymBind) String() string   { return stringName(uint32(i), stbStrings, false) }
-func (i SymBind) GoString() string { return stringName(uint32(i), stbStrings, true) }
-
-/* Symbol type - ELFNN_ST_TYPE - st_info */
-type SymType int
-
-const (
-	STT_NOTYPE  SymType = 0  /* Unspecified type. */
-	STT_OBJECT  SymType = 1  /* Data object. */
-	STT_FUNC    SymType = 2  /* Function. */
-	STT_SECTION SymType = 3  /* Section. */
-	STT_FILE    SymType = 4  /* Source file. */
-	STT_COMMON  SymType = 5  /* Uninitialized common block. */
-	STT_TLS     SymType = 6  /* TLS object. */
-	STT_LOOS    SymType = 10 /* Reserved range for operating system */
-	STT_HIOS    SymType = 12 /*   specific semantics. */
-	STT_LOPROC  SymType = 13 /* reserved range for processor */
-	STT_HIPROC  SymType = 15 /*   specific semantics. */
-)
-
-var sttStrings = []intName{
-	{0, "STT_NOTYPE"},
-	{1, "STT_OBJECT"},
-	{2, "STT_FUNC"},
-	{3, "STT_SECTION"},
-	{4, "STT_FILE"},
-	{5, "STT_COMMON"},
-	{6, "STT_TLS"},
-	{10, "STT_LOOS"},
-	{12, "STT_HIOS"},
-	{13, "STT_LOPROC"},
-	{15, "STT_HIPROC"},
-}
-
-func (i SymType) String() string   { return stringName(uint32(i), sttStrings, false) }
-func (i SymType) GoString() string { return stringName(uint32(i), sttStrings, true) }
-
-/* Symbol visibility - ELFNN_ST_VISIBILITY - st_other */
-type SymVis int
-
-const (
-	STV_DEFAULT   SymVis = 0x0 /* Default visibility (see binding). */
-	STV_INTERNAL  SymVis = 0x1 /* Special meaning in relocatable objects. */
-	STV_HIDDEN    SymVis = 0x2 /* Not visible. */
-	STV_PROTECTED SymVis = 0x3 /* Visible but not preemptible. */
-)
-
-var stvStrings = []intName{
-	{0x0, "STV_DEFAULT"},
-	{0x1, "STV_INTERNAL"},
-	{0x2, "STV_HIDDEN"},
-	{0x3, "STV_PROTECTED"},
-}
-
-func (i SymVis) String() string   { return stringName(uint32(i), stvStrings, false) }
-func (i SymVis) GoString() string { return stringName(uint32(i), stvStrings, true) }
-
-/*
- * Relocation types.
- */
-
-// Relocation types for x86-64.
-type R_X86_64 int
-
-const (
-	R_X86_64_NONE     R_X86_64 = 0  /* No relocation. */
-	R_X86_64_64       R_X86_64 = 1  /* Add 64 bit symbol value. */
-	R_X86_64_PC32     R_X86_64 = 2  /* PC-relative 32 bit signed sym value. */
-	R_X86_64_GOT32    R_X86_64 = 3  /* PC-relative 32 bit GOT offset. */
-	R_X86_64_PLT32    R_X86_64 = 4  /* PC-relative 32 bit PLT offset. */
-	R_X86_64_COPY     R_X86_64 = 5  /* Copy data from shared object. */
-	R_X86_64_GLOB_DAT R_X86_64 = 6  /* Set GOT entry to data address. */
-	R_X86_64_JMP_SLOT R_X86_64 = 7  /* Set GOT entry to code address. */
-	R_X86_64_RELATIVE R_X86_64 = 8  /* Add load address of shared object. */
-	R_X86_64_GOTPCREL R_X86_64 = 9  /* Add 32 bit signed pcrel offset to GOT. */
-	R_X86_64_32       R_X86_64 = 10 /* Add 32 bit zero extended symbol value */
-	R_X86_64_32S      R_X86_64 = 11 /* Add 32 bit sign extended symbol value */
-	R_X86_64_16       R_X86_64 = 12 /* Add 16 bit zero extended symbol value */
-	R_X86_64_PC16     R_X86_64 = 13 /* Add 16 bit signed extended pc relative symbol value */
-	R_X86_64_8        R_X86_64 = 14 /* Add 8 bit zero extended symbol value */
-	R_X86_64_PC8      R_X86_64 = 15 /* Add 8 bit signed extended pc relative symbol value */
-	R_X86_64_DTPMOD64 R_X86_64 = 16 /* ID of module containing symbol */
-	R_X86_64_DTPOFF64 R_X86_64 = 17 /* Offset in TLS block */
-	R_X86_64_TPOFF64  R_X86_64 = 18 /* Offset in static TLS block */
-	R_X86_64_TLSGD    R_X86_64 = 19 /* PC relative offset to GD GOT entry */
-	R_X86_64_TLSLD    R_X86_64 = 20 /* PC relative offset to LD GOT entry */
-	R_X86_64_DTPOFF32 R_X86_64 = 21 /* Offset in TLS block */
-	R_X86_64_GOTTPOFF R_X86_64 = 22 /* PC relative offset to IE GOT entry */
-	R_X86_64_TPOFF32  R_X86_64 = 23 /* Offset in static TLS block */
-)
-
-var rx86_64Strings = []intName{
-	{0, "R_X86_64_NONE"},
-	{1, "R_X86_64_64"},
-	{2, "R_X86_64_PC32"},
-	{3, "R_X86_64_GOT32"},
-	{4, "R_X86_64_PLT32"},
-	{5, "R_X86_64_COPY"},
-	{6, "R_X86_64_GLOB_DAT"},
-	{7, "R_X86_64_JMP_SLOT"},
-	{8, "R_X86_64_RELATIVE"},
-	{9, "R_X86_64_GOTPCREL"},
-	{10, "R_X86_64_32"},
-	{11, "R_X86_64_32S"},
-	{12, "R_X86_64_16"},
-	{13, "R_X86_64_PC16"},
-	{14, "R_X86_64_8"},
-	{15, "R_X86_64_PC8"},
-	{16, "R_X86_64_DTPMOD64"},
-	{17, "R_X86_64_DTPOFF64"},
-	{18, "R_X86_64_TPOFF64"},
-	{19, "R_X86_64_TLSGD"},
-	{20, "R_X86_64_TLSLD"},
-	{21, "R_X86_64_DTPOFF32"},
-	{22, "R_X86_64_GOTTPOFF"},
-	{23, "R_X86_64_TPOFF32"},
-}
-
-func (i R_X86_64) String() string   { return stringName(uint32(i), rx86_64Strings, false) }
-func (i R_X86_64) GoString() string { return stringName(uint32(i), rx86_64Strings, true) }
-
-// Relocation types for Alpha.
-type R_ALPHA int
-
-const (
-	R_ALPHA_NONE           R_ALPHA = 0  /* No reloc */
-	R_ALPHA_REFLONG        R_ALPHA = 1  /* Direct 32 bit */
-	R_ALPHA_REFQUAD        R_ALPHA = 2  /* Direct 64 bit */
-	R_ALPHA_GPREL32        R_ALPHA = 3  /* GP relative 32 bit */
-	R_ALPHA_LITERAL        R_ALPHA = 4  /* GP relative 16 bit w/optimization */
-	R_ALPHA_LITUSE         R_ALPHA = 5  /* Optimization hint for LITERAL */
-	R_ALPHA_GPDISP         R_ALPHA = 6  /* Add displacement to GP */
-	R_ALPHA_BRADDR         R_ALPHA = 7  /* PC+4 relative 23 bit shifted */
-	R_ALPHA_HINT           R_ALPHA = 8  /* PC+4 relative 16 bit shifted */
-	R_ALPHA_SREL16         R_ALPHA = 9  /* PC relative 16 bit */
-	R_ALPHA_SREL32         R_ALPHA = 10 /* PC relative 32 bit */
-	R_ALPHA_SREL64         R_ALPHA = 11 /* PC relative 64 bit */
-	R_ALPHA_OP_PUSH        R_ALPHA = 12 /* OP stack push */
-	R_ALPHA_OP_STORE       R_ALPHA = 13 /* OP stack pop and store */
-	R_ALPHA_OP_PSUB        R_ALPHA = 14 /* OP stack subtract */
-	R_ALPHA_OP_PRSHIFT     R_ALPHA = 15 /* OP stack right shift */
-	R_ALPHA_GPVALUE        R_ALPHA = 16
-	R_ALPHA_GPRELHIGH      R_ALPHA = 17
-	R_ALPHA_GPRELLOW       R_ALPHA = 18
-	R_ALPHA_IMMED_GP_16    R_ALPHA = 19
-	R_ALPHA_IMMED_GP_HI32  R_ALPHA = 20
-	R_ALPHA_IMMED_SCN_HI32 R_ALPHA = 21
-	R_ALPHA_IMMED_BR_HI32  R_ALPHA = 22
-	R_ALPHA_IMMED_LO32     R_ALPHA = 23
-	R_ALPHA_COPY           R_ALPHA = 24 /* Copy symbol at runtime */
-	R_ALPHA_GLOB_DAT       R_ALPHA = 25 /* Create GOT entry */
-	R_ALPHA_JMP_SLOT       R_ALPHA = 26 /* Create PLT entry */
-	R_ALPHA_RELATIVE       R_ALPHA = 27 /* Adjust by program base */
-)
-
-var ralphaStrings = []intName{
-	{0, "R_ALPHA_NONE"},
-	{1, "R_ALPHA_REFLONG"},
-	{2, "R_ALPHA_REFQUAD"},
-	{3, "R_ALPHA_GPREL32"},
-	{4, "R_ALPHA_LITERAL"},
-	{5, "R_ALPHA_LITUSE"},
-	{6, "R_ALPHA_GPDISP"},
-	{7, "R_ALPHA_BRADDR"},
-	{8, "R_ALPHA_HINT"},
-	{9, "R_ALPHA_SREL16"},
-	{10, "R_ALPHA_SREL32"},
-	{11, "R_ALPHA_SREL64"},
-	{12, "R_ALPHA_OP_PUSH"},
-	{13, "R_ALPHA_OP_STORE"},
-	{14, "R_ALPHA_OP_PSUB"},
-	{15, "R_ALPHA_OP_PRSHIFT"},
-	{16, "R_ALPHA_GPVALUE"},
-	{17, "R_ALPHA_GPRELHIGH"},
-	{18, "R_ALPHA_GPRELLOW"},
-	{19, "R_ALPHA_IMMED_GP_16"},
-	{20, "R_ALPHA_IMMED_GP_HI32"},
-	{21, "R_ALPHA_IMMED_SCN_HI32"},
-	{22, "R_ALPHA_IMMED_BR_HI32"},
-	{23, "R_ALPHA_IMMED_LO32"},
-	{24, "R_ALPHA_COPY"},
-	{25, "R_ALPHA_GLOB_DAT"},
-	{26, "R_ALPHA_JMP_SLOT"},
-	{27, "R_ALPHA_RELATIVE"},
-}
-
-func (i R_ALPHA) String() string   { return stringName(uint32(i), ralphaStrings, false) }
-func (i R_ALPHA) GoString() string { return stringName(uint32(i), ralphaStrings, true) }
-
-// Relocation types for ARM.
-type R_ARM int
-
-const (
-	R_ARM_NONE          R_ARM = 0 /* No relocation. */
-	R_ARM_PC24          R_ARM = 1
-	R_ARM_ABS32         R_ARM = 2
-	R_ARM_REL32         R_ARM = 3
-	R_ARM_PC13          R_ARM = 4
-	R_ARM_ABS16         R_ARM = 5
-	R_ARM_ABS12         R_ARM = 6
-	R_ARM_THM_ABS5      R_ARM = 7
-	R_ARM_ABS8          R_ARM = 8
-	R_ARM_SBREL32       R_ARM = 9
-	R_ARM_THM_PC22      R_ARM = 10
-	R_ARM_THM_PC8       R_ARM = 11
-	R_ARM_AMP_VCALL9    R_ARM = 12
-	R_ARM_SWI24         R_ARM = 13
-	R_ARM_THM_SWI8      R_ARM = 14
-	R_ARM_XPC25         R_ARM = 15
-	R_ARM_THM_XPC22     R_ARM = 16
-	R_ARM_COPY          R_ARM = 20 /* Copy data from shared object. */
-	R_ARM_GLOB_DAT      R_ARM = 21 /* Set GOT entry to data address. */
-	R_ARM_JUMP_SLOT     R_ARM = 22 /* Set GOT entry to code address. */
-	R_ARM_RELATIVE      R_ARM = 23 /* Add load address of shared object. */
-	R_ARM_GOTOFF        R_ARM = 24 /* Add GOT-relative symbol address. */
-	R_ARM_GOTPC         R_ARM = 25 /* Add PC-relative GOT table address. */
-	R_ARM_GOT32         R_ARM = 26 /* Add PC-relative GOT offset. */
-	R_ARM_PLT32         R_ARM = 27 /* Add PC-relative PLT offset. */
-	R_ARM_GNU_VTENTRY   R_ARM = 100
-	R_ARM_GNU_VTINHERIT R_ARM = 101
-	R_ARM_RSBREL32      R_ARM = 250
-	R_ARM_THM_RPC22     R_ARM = 251
-	R_ARM_RREL32        R_ARM = 252
-	R_ARM_RABS32        R_ARM = 253
-	R_ARM_RPC24         R_ARM = 254
-	R_ARM_RBASE         R_ARM = 255
-)
-
-var rarmStrings = []intName{
-	{0, "R_ARM_NONE"},
-	{1, "R_ARM_PC24"},
-	{2, "R_ARM_ABS32"},
-	{3, "R_ARM_REL32"},
-	{4, "R_ARM_PC13"},
-	{5, "R_ARM_ABS16"},
-	{6, "R_ARM_ABS12"},
-	{7, "R_ARM_THM_ABS5"},
-	{8, "R_ARM_ABS8"},
-	{9, "R_ARM_SBREL32"},
-	{10, "R_ARM_THM_PC22"},
-	{11, "R_ARM_THM_PC8"},
-	{12, "R_ARM_AMP_VCALL9"},
-	{13, "R_ARM_SWI24"},
-	{14, "R_ARM_THM_SWI8"},
-	{15, "R_ARM_XPC25"},
-	{16, "R_ARM_THM_XPC22"},
-	{20, "R_ARM_COPY"},
-	{21, "R_ARM_GLOB_DAT"},
-	{22, "R_ARM_JUMP_SLOT"},
-	{23, "R_ARM_RELATIVE"},
-	{24, "R_ARM_GOTOFF"},
-	{25, "R_ARM_GOTPC"},
-	{26, "R_ARM_GOT32"},
-	{27, "R_ARM_PLT32"},
-	{100, "R_ARM_GNU_VTENTRY"},
-	{101, "R_ARM_GNU_VTINHERIT"},
-	{250, "R_ARM_RSBREL32"},
-	{251, "R_ARM_THM_RPC22"},
-	{252, "R_ARM_RREL32"},
-	{253, "R_ARM_RABS32"},
-	{254, "R_ARM_RPC24"},
-	{255, "R_ARM_RBASE"},
-}
-
-func (i R_ARM) String() string   { return stringName(uint32(i), rarmStrings, false) }
-func (i R_ARM) GoString() string { return stringName(uint32(i), rarmStrings, true) }
-
-// Relocation types for 386.
-type R_386 int
-
-const (
-	R_386_NONE         R_386 = 0  /* No relocation. */
-	R_386_32           R_386 = 1  /* Add symbol value. */
-	R_386_PC32         R_386 = 2  /* Add PC-relative symbol value. */
-	R_386_GOT32        R_386 = 3  /* Add PC-relative GOT offset. */
-	R_386_PLT32        R_386 = 4  /* Add PC-relative PLT offset. */
-	R_386_COPY         R_386 = 5  /* Copy data from shared object. */
-	R_386_GLOB_DAT     R_386 = 6  /* Set GOT entry to data address. */
-	R_386_JMP_SLOT     R_386 = 7  /* Set GOT entry to code address. */
-	R_386_RELATIVE     R_386 = 8  /* Add load address of shared object. */
-	R_386_GOTOFF       R_386 = 9  /* Add GOT-relative symbol address. */
-	R_386_GOTPC        R_386 = 10 /* Add PC-relative GOT table address. */
-	R_386_TLS_TPOFF    R_386 = 14 /* Negative offset in static TLS block */
-	R_386_TLS_IE       R_386 = 15 /* Absolute address of GOT for -ve static TLS */
-	R_386_TLS_GOTIE    R_386 = 16 /* GOT entry for negative static TLS block */
-	R_386_TLS_LE       R_386 = 17 /* Negative offset relative to static TLS */
-	R_386_TLS_GD       R_386 = 18 /* 32 bit offset to GOT (index,off) pair */
-	R_386_TLS_LDM      R_386 = 19 /* 32 bit offset to GOT (index,zero) pair */
-	R_386_TLS_GD_32    R_386 = 24 /* 32 bit offset to GOT (index,off) pair */
-	R_386_TLS_GD_PUSH  R_386 = 25 /* pushl instruction for Sun ABI GD sequence */
-	R_386_TLS_GD_CALL  R_386 = 26 /* call instruction for Sun ABI GD sequence */
-	R_386_TLS_GD_POP   R_386 = 27 /* popl instruction for Sun ABI GD sequence */
-	R_386_TLS_LDM_32   R_386 = 28 /* 32 bit offset to GOT (index,zero) pair */
-	R_386_TLS_LDM_PUSH R_386 = 29 /* pushl instruction for Sun ABI LD sequence */
-	R_386_TLS_LDM_CALL R_386 = 30 /* call instruction for Sun ABI LD sequence */
-	R_386_TLS_LDM_POP  R_386 = 31 /* popl instruction for Sun ABI LD sequence */
-	R_386_TLS_LDO_32   R_386 = 32 /* 32 bit offset from start of TLS block */
-	R_386_TLS_IE_32    R_386 = 33 /* 32 bit offset to GOT static TLS offset entry */
-	R_386_TLS_LE_32    R_386 = 34 /* 32 bit offset within static TLS block */
-	R_386_TLS_DTPMOD32 R_386 = 35 /* GOT entry containing TLS index */
-	R_386_TLS_DTPOFF32 R_386 = 36 /* GOT entry containing TLS offset */
-	R_386_TLS_TPOFF32  R_386 = 37 /* GOT entry of -ve static TLS offset */
-)
-
-var r386Strings = []intName{
-	{0, "R_386_NONE"},
-	{1, "R_386_32"},
-	{2, "R_386_PC32"},
-	{3, "R_386_GOT32"},
-	{4, "R_386_PLT32"},
-	{5, "R_386_COPY"},
-	{6, "R_386_GLOB_DAT"},
-	{7, "R_386_JMP_SLOT"},
-	{8, "R_386_RELATIVE"},
-	{9, "R_386_GOTOFF"},
-	{10, "R_386_GOTPC"},
-	{14, "R_386_TLS_TPOFF"},
-	{15, "R_386_TLS_IE"},
-	{16, "R_386_TLS_GOTIE"},
-	{17, "R_386_TLS_LE"},
-	{18, "R_386_TLS_GD"},
-	{19, "R_386_TLS_LDM"},
-	{24, "R_386_TLS_GD_32"},
-	{25, "R_386_TLS_GD_PUSH"},
-	{26, "R_386_TLS_GD_CALL"},
-	{27, "R_386_TLS_GD_POP"},
-	{28, "R_386_TLS_LDM_32"},
-	{29, "R_386_TLS_LDM_PUSH"},
-	{30, "R_386_TLS_LDM_CALL"},
-	{31, "R_386_TLS_LDM_POP"},
-	{32, "R_386_TLS_LDO_32"},
-	{33, "R_386_TLS_IE_32"},
-	{34, "R_386_TLS_LE_32"},
-	{35, "R_386_TLS_DTPMOD32"},
-	{36, "R_386_TLS_DTPOFF32"},
-	{37, "R_386_TLS_TPOFF32"},
-}
-
-func (i R_386) String() string   { return stringName(uint32(i), r386Strings, false) }
-func (i R_386) GoString() string { return stringName(uint32(i), r386Strings, true) }
-
-// Relocation types for PowerPC.
-type R_PPC int
-
-const (
-	R_PPC_NONE            R_PPC = 0 /* No relocation. */
-	R_PPC_ADDR32          R_PPC = 1
-	R_PPC_ADDR24          R_PPC = 2
-	R_PPC_ADDR16          R_PPC = 3
-	R_PPC_ADDR16_LO       R_PPC = 4
-	R_PPC_ADDR16_HI       R_PPC = 5
-	R_PPC_ADDR16_HA       R_PPC = 6
-	R_PPC_ADDR14          R_PPC = 7
-	R_PPC_ADDR14_BRTAKEN  R_PPC = 8
-	R_PPC_ADDR14_BRNTAKEN R_PPC = 9
-	R_PPC_REL24           R_PPC = 10
-	R_PPC_REL14           R_PPC = 11
-	R_PPC_REL14_BRTAKEN   R_PPC = 12
-	R_PPC_REL14_BRNTAKEN  R_PPC = 13
-	R_PPC_GOT16           R_PPC = 14
-	R_PPC_GOT16_LO        R_PPC = 15
-	R_PPC_GOT16_HI        R_PPC = 16
-	R_PPC_GOT16_HA        R_PPC = 17
-	R_PPC_PLTREL24        R_PPC = 18
-	R_PPC_COPY            R_PPC = 19
-	R_PPC_GLOB_DAT        R_PPC = 20
-	R_PPC_JMP_SLOT        R_PPC = 21
-	R_PPC_RELATIVE        R_PPC = 22
-	R_PPC_LOCAL24PC       R_PPC = 23
-	R_PPC_UADDR32         R_PPC = 24
-	R_PPC_UADDR16         R_PPC = 25
-	R_PPC_REL32           R_PPC = 26
-	R_PPC_PLT32           R_PPC = 27
-	R_PPC_PLTREL32        R_PPC = 28
-	R_PPC_PLT16_LO        R_PPC = 29
-	R_PPC_PLT16_HI        R_PPC = 30
-	R_PPC_PLT16_HA        R_PPC = 31
-	R_PPC_SDAREL16        R_PPC = 32
-	R_PPC_SECTOFF         R_PPC = 33
-	R_PPC_SECTOFF_LO      R_PPC = 34
-	R_PPC_SECTOFF_HI      R_PPC = 35
-	R_PPC_SECTOFF_HA      R_PPC = 36
-	R_PPC_TLS             R_PPC = 67
-	R_PPC_DTPMOD32        R_PPC = 68
-	R_PPC_TPREL16         R_PPC = 69
-	R_PPC_TPREL16_LO      R_PPC = 70
-	R_PPC_TPREL16_HI      R_PPC = 71
-	R_PPC_TPREL16_HA      R_PPC = 72
-	R_PPC_TPREL32         R_PPC = 73
-	R_PPC_DTPREL16        R_PPC = 74
-	R_PPC_DTPREL16_LO     R_PPC = 75
-	R_PPC_DTPREL16_HI     R_PPC = 76
-	R_PPC_DTPREL16_HA     R_PPC = 77
-	R_PPC_DTPREL32        R_PPC = 78
-	R_PPC_GOT_TLSGD16     R_PPC = 79
-	R_PPC_GOT_TLSGD16_LO  R_PPC = 80
-	R_PPC_GOT_TLSGD16_HI  R_PPC = 81
-	R_PPC_GOT_TLSGD16_HA  R_PPC = 82
-	R_PPC_GOT_TLSLD16     R_PPC = 83
-	R_PPC_GOT_TLSLD16_LO  R_PPC = 84
-	R_PPC_GOT_TLSLD16_HI  R_PPC = 85
-	R_PPC_GOT_TLSLD16_HA  R_PPC = 86
-	R_PPC_GOT_TPREL16     R_PPC = 87
-	R_PPC_GOT_TPREL16_LO  R_PPC = 88
-	R_PPC_GOT_TPREL16_HI  R_PPC = 89
-	R_PPC_GOT_TPREL16_HA  R_PPC = 90
-	R_PPC_EMB_NADDR32     R_PPC = 101
-	R_PPC_EMB_NADDR16     R_PPC = 102
-	R_PPC_EMB_NADDR16_LO  R_PPC = 103
-	R_PPC_EMB_NADDR16_HI  R_PPC = 104
-	R_PPC_EMB_NADDR16_HA  R_PPC = 105
-	R_PPC_EMB_SDAI16      R_PPC = 106
-	R_PPC_EMB_SDA2I16     R_PPC = 107
-	R_PPC_EMB_SDA2REL     R_PPC = 108
-	R_PPC_EMB_SDA21       R_PPC = 109
-	R_PPC_EMB_MRKREF      R_PPC = 110
-	R_PPC_EMB_RELSEC16    R_PPC = 111
-	R_PPC_EMB_RELST_LO    R_PPC = 112
-	R_PPC_EMB_RELST_HI    R_PPC = 113
-	R_PPC_EMB_RELST_HA    R_PPC = 114
-	R_PPC_EMB_BIT_FLD     R_PPC = 115
-	R_PPC_EMB_RELSDA      R_PPC = 116
-)
-
-var rppcStrings = []intName{
-	{0, "R_PPC_NONE"},
-	{1, "R_PPC_ADDR32"},
-	{2, "R_PPC_ADDR24"},
-	{3, "R_PPC_ADDR16"},
-	{4, "R_PPC_ADDR16_LO"},
-	{5, "R_PPC_ADDR16_HI"},
-	{6, "R_PPC_ADDR16_HA"},
-	{7, "R_PPC_ADDR14"},
-	{8, "R_PPC_ADDR14_BRTAKEN"},
-	{9, "R_PPC_ADDR14_BRNTAKEN"},
-	{10, "R_PPC_REL24"},
-	{11, "R_PPC_REL14"},
-	{12, "R_PPC_REL14_BRTAKEN"},
-	{13, "R_PPC_REL14_BRNTAKEN"},
-	{14, "R_PPC_GOT16"},
-	{15, "R_PPC_GOT16_LO"},
-	{16, "R_PPC_GOT16_HI"},
-	{17, "R_PPC_GOT16_HA"},
-	{18, "R_PPC_PLTREL24"},
-	{19, "R_PPC_COPY"},
-	{20, "R_PPC_GLOB_DAT"},
-	{21, "R_PPC_JMP_SLOT"},
-	{22, "R_PPC_RELATIVE"},
-	{23, "R_PPC_LOCAL24PC"},
-	{24, "R_PPC_UADDR32"},
-	{25, "R_PPC_UADDR16"},
-	{26, "R_PPC_REL32"},
-	{27, "R_PPC_PLT32"},
-	{28, "R_PPC_PLTREL32"},
-	{29, "R_PPC_PLT16_LO"},
-	{30, "R_PPC_PLT16_HI"},
-	{31, "R_PPC_PLT16_HA"},
-	{32, "R_PPC_SDAREL16"},
-	{33, "R_PPC_SECTOFF"},
-	{34, "R_PPC_SECTOFF_LO"},
-	{35, "R_PPC_SECTOFF_HI"},
-	{36, "R_PPC_SECTOFF_HA"},
-
-	{67, "R_PPC_TLS"},
-	{68, "R_PPC_DTPMOD32"},
-	{69, "R_PPC_TPREL16"},
-	{70, "R_PPC_TPREL16_LO"},
-	{71, "R_PPC_TPREL16_HI"},
-	{72, "R_PPC_TPREL16_HA"},
-	{73, "R_PPC_TPREL32"},
-	{74, "R_PPC_DTPREL16"},
-	{75, "R_PPC_DTPREL16_LO"},
-	{76, "R_PPC_DTPREL16_HI"},
-	{77, "R_PPC_DTPREL16_HA"},
-	{78, "R_PPC_DTPREL32"},
-	{79, "R_PPC_GOT_TLSGD16"},
-	{80, "R_PPC_GOT_TLSGD16_LO"},
-	{81, "R_PPC_GOT_TLSGD16_HI"},
-	{82, "R_PPC_GOT_TLSGD16_HA"},
-	{83, "R_PPC_GOT_TLSLD16"},
-	{84, "R_PPC_GOT_TLSLD16_LO"},
-	{85, "R_PPC_GOT_TLSLD16_HI"},
-	{86, "R_PPC_GOT_TLSLD16_HA"},
-	{87, "R_PPC_GOT_TPREL16"},
-	{88, "R_PPC_GOT_TPREL16_LO"},
-	{89, "R_PPC_GOT_TPREL16_HI"},
-	{90, "R_PPC_GOT_TPREL16_HA"},
-
-	{101, "R_PPC_EMB_NADDR32"},
-	{102, "R_PPC_EMB_NADDR16"},
-	{103, "R_PPC_EMB_NADDR16_LO"},
-	{104, "R_PPC_EMB_NADDR16_HI"},
-	{105, "R_PPC_EMB_NADDR16_HA"},
-	{106, "R_PPC_EMB_SDAI16"},
-	{107, "R_PPC_EMB_SDA2I16"},
-	{108, "R_PPC_EMB_SDA2REL"},
-	{109, "R_PPC_EMB_SDA21"},
-	{110, "R_PPC_EMB_MRKREF"},
-	{111, "R_PPC_EMB_RELSEC16"},
-	{112, "R_PPC_EMB_RELST_LO"},
-	{113, "R_PPC_EMB_RELST_HI"},
-	{114, "R_PPC_EMB_RELST_HA"},
-	{115, "R_PPC_EMB_BIT_FLD"},
-	{116, "R_PPC_EMB_RELSDA"},
-}
-
-func (i R_PPC) String() string   { return stringName(uint32(i), rppcStrings, false) }
-func (i R_PPC) GoString() string { return stringName(uint32(i), rppcStrings, true) }
-
-// Relocation types for SPARC.
-type R_SPARC int
-
-const (
-	R_SPARC_NONE     R_SPARC = 0
-	R_SPARC_8        R_SPARC = 1
-	R_SPARC_16       R_SPARC = 2
-	R_SPARC_32       R_SPARC = 3
-	R_SPARC_DISP8    R_SPARC = 4
-	R_SPARC_DISP16   R_SPARC = 5
-	R_SPARC_DISP32   R_SPARC = 6
-	R_SPARC_WDISP30  R_SPARC = 7
-	R_SPARC_WDISP22  R_SPARC = 8
-	R_SPARC_HI22     R_SPARC = 9
-	R_SPARC_22       R_SPARC = 10
-	R_SPARC_13       R_SPARC = 11
-	R_SPARC_LO10     R_SPARC = 12
-	R_SPARC_GOT10    R_SPARC = 13
-	R_SPARC_GOT13    R_SPARC = 14
-	R_SPARC_GOT22    R_SPARC = 15
-	R_SPARC_PC10     R_SPARC = 16
-	R_SPARC_PC22     R_SPARC = 17
-	R_SPARC_WPLT30   R_SPARC = 18
-	R_SPARC_COPY     R_SPARC = 19
-	R_SPARC_GLOB_DAT R_SPARC = 20
-	R_SPARC_JMP_SLOT R_SPARC = 21
-	R_SPARC_RELATIVE R_SPARC = 22
-	R_SPARC_UA32     R_SPARC = 23
-	R_SPARC_PLT32    R_SPARC = 24
-	R_SPARC_HIPLT22  R_SPARC = 25
-	R_SPARC_LOPLT10  R_SPARC = 26
-	R_SPARC_PCPLT32  R_SPARC = 27
-	R_SPARC_PCPLT22  R_SPARC = 28
-	R_SPARC_PCPLT10  R_SPARC = 29
-	R_SPARC_10       R_SPARC = 30
-	R_SPARC_11       R_SPARC = 31
-	R_SPARC_64       R_SPARC = 32
-	R_SPARC_OLO10    R_SPARC = 33
-	R_SPARC_HH22     R_SPARC = 34
-	R_SPARC_HM10     R_SPARC = 35
-	R_SPARC_LM22     R_SPARC = 36
-	R_SPARC_PC_HH22  R_SPARC = 37
-	R_SPARC_PC_HM10  R_SPARC = 38
-	R_SPARC_PC_LM22  R_SPARC = 39
-	R_SPARC_WDISP16  R_SPARC = 40
-	R_SPARC_WDISP19  R_SPARC = 41
-	R_SPARC_GLOB_JMP R_SPARC = 42
-	R_SPARC_7        R_SPARC = 43
-	R_SPARC_5        R_SPARC = 44
-	R_SPARC_6        R_SPARC = 45
-	R_SPARC_DISP64   R_SPARC = 46
-	R_SPARC_PLT64    R_SPARC = 47
-	R_SPARC_HIX22    R_SPARC = 48
-	R_SPARC_LOX10    R_SPARC = 49
-	R_SPARC_H44      R_SPARC = 50
-	R_SPARC_M44      R_SPARC = 51
-	R_SPARC_L44      R_SPARC = 52
-	R_SPARC_REGISTER R_SPARC = 53
-	R_SPARC_UA64     R_SPARC = 54
-	R_SPARC_UA16     R_SPARC = 55
-)
-
-var rsparcStrings = []intName{
-	{0, "R_SPARC_NONE"},
-	{1, "R_SPARC_8"},
-	{2, "R_SPARC_16"},
-	{3, "R_SPARC_32"},
-	{4, "R_SPARC_DISP8"},
-	{5, "R_SPARC_DISP16"},
-	{6, "R_SPARC_DISP32"},
-	{7, "R_SPARC_WDISP30"},
-	{8, "R_SPARC_WDISP22"},
-	{9, "R_SPARC_HI22"},
-	{10, "R_SPARC_22"},
-	{11, "R_SPARC_13"},
-	{12, "R_SPARC_LO10"},
-	{13, "R_SPARC_GOT10"},
-	{14, "R_SPARC_GOT13"},
-	{15, "R_SPARC_GOT22"},
-	{16, "R_SPARC_PC10"},
-	{17, "R_SPARC_PC22"},
-	{18, "R_SPARC_WPLT30"},
-	{19, "R_SPARC_COPY"},
-	{20, "R_SPARC_GLOB_DAT"},
-	{21, "R_SPARC_JMP_SLOT"},
-	{22, "R_SPARC_RELATIVE"},
-	{23, "R_SPARC_UA32"},
-	{24, "R_SPARC_PLT32"},
-	{25, "R_SPARC_HIPLT22"},
-	{26, "R_SPARC_LOPLT10"},
-	{27, "R_SPARC_PCPLT32"},
-	{28, "R_SPARC_PCPLT22"},
-	{29, "R_SPARC_PCPLT10"},
-	{30, "R_SPARC_10"},
-	{31, "R_SPARC_11"},
-	{32, "R_SPARC_64"},
-	{33, "R_SPARC_OLO10"},
-	{34, "R_SPARC_HH22"},
-	{35, "R_SPARC_HM10"},
-	{36, "R_SPARC_LM22"},
-	{37, "R_SPARC_PC_HH22"},
-	{38, "R_SPARC_PC_HM10"},
-	{39, "R_SPARC_PC_LM22"},
-	{40, "R_SPARC_WDISP16"},
-	{41, "R_SPARC_WDISP19"},
-	{42, "R_SPARC_GLOB_JMP"},
-	{43, "R_SPARC_7"},
-	{44, "R_SPARC_5"},
-	{45, "R_SPARC_6"},
-	{46, "R_SPARC_DISP64"},
-	{47, "R_SPARC_PLT64"},
-	{48, "R_SPARC_HIX22"},
-	{49, "R_SPARC_LOX10"},
-	{50, "R_SPARC_H44"},
-	{51, "R_SPARC_M44"},
-	{52, "R_SPARC_L44"},
-	{53, "R_SPARC_REGISTER"},
-	{54, "R_SPARC_UA64"},
-	{55, "R_SPARC_UA16"},
-}
-
-func (i R_SPARC) String() string   { return stringName(uint32(i), rsparcStrings, false) }
-func (i R_SPARC) GoString() string { return stringName(uint32(i), rsparcStrings, true) }
-
-// Magic number for the elf trampoline, chosen wisely to be an immediate value.
-const ARM_MAGIC_TRAMP_NUMBER = 0x5c000003
-
-// ELF32 File header.
-type Header32 struct {
-	Ident     [EI_NIDENT]byte /* File identification. */
-	Type      uint16          /* File type. */
-	Machine   uint16          /* Machine architecture. */
-	Version   uint32          /* ELF format version. */
-	Entry     uint32          /* Entry point. */
-	Phoff     uint32          /* Program header file offset. */
-	Shoff     uint32          /* Section header file offset. */
-	Flags     uint32          /* Architecture-specific flags. */
-	Ehsize    uint16          /* Size of ELF header in bytes. */
-	Phentsize uint16          /* Size of program header entry. */
-	Phnum     uint16          /* Number of program header entries. */
-	Shentsize uint16          /* Size of section header entry. */
-	Shnum     uint16          /* Number of section header entries. */
-	Shstrndx  uint16          /* Section name strings section. */
-}
-
-// ELF32 Section header.
-type Section32 struct {
-	Name      uint32 /* Section name (index into the section header string table). */
-	Type      uint32 /* Section type. */
-	Flags     uint32 /* Section flags. */
-	Addr      uint32 /* Address in memory image. */
-	Off       uint32 /* Offset in file. */
-	Size      uint32 /* Size in bytes. */
-	Link      uint32 /* Index of a related section. */
-	Info      uint32 /* Depends on section type. */
-	Addralign uint32 /* Alignment in bytes. */
-	Entsize   uint32 /* Size of each entry in section. */
-}
-
-// ELF32 Program header.
-type Prog32 struct {
-	Type   uint32 /* Entry type. */
-	Off    uint32 /* File offset of contents. */
-	Vaddr  uint32 /* Virtual address in memory image. */
-	Paddr  uint32 /* Physical address (not used). */
-	Filesz uint32 /* Size of contents in file. */
-	Memsz  uint32 /* Size of contents in memory. */
-	Flags  uint32 /* Access permission flags. */
-	Align  uint32 /* Alignment in memory and file. */
-}
-
-// ELF32 Dynamic structure.  The ".dynamic" section contains an array of them.
-type Dyn32 struct {
-	Tag int32  /* Entry type. */
-	Val uint32 /* Integer/Address value. */
-}
-
-/*
- * Relocation entries.
- */
-
-// ELF32 Relocations that don't need an addend field.
-type Rel32 struct {
-	Off  uint32 /* Location to be relocated. */
-	Info uint32 /* Relocation type and symbol index. */
-}
-
-// ELF32 Relocations that need an addend field.
-type Rela32 struct {
-	Off    uint32 /* Location to be relocated. */
-	Info   uint32 /* Relocation type and symbol index. */
-	Addend int32  /* Addend. */
-}
-
-func R_SYM32(info uint32) uint32      { return uint32(info >> 8) }
-func R_TYPE32(info uint32) uint32     { return uint32(info & 0xff) }
-func R_INFO32(sym, typ uint32) uint32 { return sym<<8 | typ }
-
-// ELF32 Symbol.
-type Sym32 struct {
-	Name  uint32
-	Value uint32
-	Size  uint32
-	Info  uint8
-	Other uint8
-	Shndx uint16
-}
-
-const Sym32Size = 16
-
-func ST_BIND(info uint8) SymBind { return SymBind(info >> 4) }
-func ST_TYPE(info uint8) SymType { return SymType(info & 0xF) }
-func ST_INFO(bind SymBind, typ SymType) uint8 {
-	return uint8(bind)<<4 | uint8(typ)&0xf
-}
-func ST_VISIBILITY(other uint8) SymVis { return SymVis(other & 3) }
-
-/*
- * ELF64
- */
-
-// ELF64 file header.
-type Header64 struct {
-	Ident     [EI_NIDENT]byte /* File identification. */
-	Type      uint16          /* File type. */
-	Machine   uint16          /* Machine architecture. */
-	Version   uint32          /* ELF format version. */
-	Entry     uint64          /* Entry point. */
-	Phoff     uint64          /* Program header file offset. */
-	Shoff     uint64          /* Section header file offset. */
-	Flags     uint32          /* Architecture-specific flags. */
-	Ehsize    uint16          /* Size of ELF header in bytes. */
-	Phentsize uint16          /* Size of program header entry. */
-	Phnum     uint16          /* Number of program header entries. */
-	Shentsize uint16          /* Size of section header entry. */
-	Shnum     uint16          /* Number of section header entries. */
-	Shstrndx  uint16          /* Section name strings section. */
-}
-
-// ELF64 Section header.
-type Section64 struct {
-	Name      uint32 /* Section name (index into the section header string table). */
-	Type      uint32 /* Section type. */
-	Flags     uint64 /* Section flags. */
-	Addr      uint64 /* Address in memory image. */
-	Off       uint64 /* Offset in file. */
-	Size      uint64 /* Size in bytes. */
-	Link      uint32 /* Index of a related section. */
-	Info      uint32 /* Depends on section type. */
-	Addralign uint64 /* Alignment in bytes. */
-	Entsize   uint64 /* Size of each entry in section. */
-}
-
-// ELF64 Program header.
-type Prog64 struct {
-	Type   uint32 /* Entry type. */
-	Flags  uint32 /* Access permission flags. */
-	Off    uint64 /* File offset of contents. */
-	Vaddr  uint64 /* Virtual address in memory image. */
-	Paddr  uint64 /* Physical address (not used). */
-	Filesz uint64 /* Size of contents in file. */
-	Memsz  uint64 /* Size of contents in memory. */
-	Align  uint64 /* Alignment in memory and file. */
-}
-
-// ELF64 Dynamic structure.  The ".dynamic" section contains an array of them.
-type Dyn64 struct {
-	Tag int64  /* Entry type. */
-	Val uint64 /* Integer/address value */
-}
-
-/*
- * Relocation entries.
- */
-
-/* ELF64 relocations that don't need an addend field. */
-type Rel64 struct {
-	Off  uint64 /* Location to be relocated. */
-	Info uint64 /* Relocation type and symbol index. */
-}
-
-/* ELF64 relocations that need an addend field. */
-type Rela64 struct {
-	Off    uint64 /* Location to be relocated. */
-	Info   uint64 /* Relocation type and symbol index. */
-	Addend int64  /* Addend. */
-}
-
-func R_SYM64(info uint64) uint32    { return uint32(info >> 32) }
-func R_TYPE64(info uint64) uint32   { return uint32(info) }
-func R_INFO(sym, typ uint32) uint64 { return uint64(sym)<<32 | uint64(typ) }
-
-// ELF64 symbol table entries.
-type Sym64 struct {
-	Name  uint32 /* String table index of name. */
-	Info  uint8  /* Type and binding information. */
-	Other uint8  /* Reserved (not used). */
-	Shndx uint16 /* Section index of symbol. */
-	Value uint64 /* Symbol value. */
-	Size  uint64 /* Size of associated object. */
-}
-
-const Sym64Size = 24
-
-type intName struct {
-	i uint32
-	s string
-}
-
-func stringName(i uint32, names []intName, goSyntax bool) string {
-	for _, n := range names {
-		if n.i == i {
-			if goSyntax {
-				return "elf." + n.s
-			}
-			return n.s
-		}
-	}
-
-	// second pass - look for smaller to add with.
-	// assume sorted already
-	for j := len(names) - 1; j >= 0; j-- {
-		n := names[j]
-		if n.i < i {
-			s := n.s
-			if goSyntax {
-				s = "elf." + s
-			}
-			return s + "+" + strconv.FormatUint(uint64(i-n.i), 10)
-		}
-	}
-
-	return strconv.FormatUint(uint64(i), 10)
-}
-
-func flagName(i uint32, names []intName, goSyntax bool) string {
-	s := ""
-	for _, n := range names {
-		if n.i&i == n.i {
-			if len(s) > 0 {
-				s += "+"
-			}
-			if goSyntax {
-				s += "elf."
-			}
-			s += n.s
-			i -= n.i
-		}
-	}
-	if len(s) == 0 {
-		return "0x" + strconv.FormatUint(uint64(i), 16)
-	}
-	if i != 0 {
-		s += "+0x" + strconv.FormatUint(uint64(i), 16)
-	}
-	return s
-}
diff --git a/src/pkg/debug/elf/file.go b/src/pkg/debug/elf/file.go
deleted file mode 100644
index 423932f..0000000
--- a/src/pkg/debug/elf/file.go
+++ /dev/null
@@ -1,881 +0,0 @@
-// Copyright 2009 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package elf implements access to ELF object files.
-package elf
-
-import (
-	"bytes"
-	"debug/dwarf"
-	"encoding/binary"
-	"errors"
-	"fmt"
-	"io"
-	"os"
-)
-
-// TODO: error reporting detail
-
-/*
- * Internal ELF representation
- */
-
-// A FileHeader represents an ELF file header.
-type FileHeader struct {
-	Class      Class
-	Data       Data
-	Version    Version
-	OSABI      OSABI
-	ABIVersion uint8
-	ByteOrder  binary.ByteOrder
-	Type       Type
-	Machine    Machine
-	Entry      uint64
-}
-
-// A File represents an open ELF file.
-type File struct {
-	FileHeader
-	Sections  []*Section
-	Progs     []*Prog
-	closer    io.Closer
-	gnuNeed   []verneed
-	gnuVersym []byte
-}
-
-// A SectionHeader represents a single ELF section header.
-type SectionHeader struct {
-	Name      string
-	Type      SectionType
-	Flags     SectionFlag
-	Addr      uint64
-	Offset    uint64
-	Size      uint64
-	Link      uint32
-	Info      uint32
-	Addralign uint64
-	Entsize   uint64
-}
-
-// A Section represents a single section in an ELF file.
-type Section struct {
-	SectionHeader
-
-	// Embed ReaderAt for ReadAt method.
-	// Do not embed SectionReader directly
-	// to avoid having Read and Seek.
-	// If a client wants Read and Seek it must use
-	// Open() to avoid fighting over the seek offset
-	// with other clients.
-	io.ReaderAt
-	sr *io.SectionReader
-}
-
-// Data reads and returns the contents of the ELF section.
-func (s *Section) Data() ([]byte, error) {
-	dat := make([]byte, s.sr.Size())
-	n, err := s.sr.ReadAt(dat, 0)
-	if n == len(dat) {
-		err = nil
-	}
-	return dat[0:n], err
-}
-
-// stringTable reads and returns the string table given by the
-// specified link value.
-func (f *File) stringTable(link uint32) ([]byte, error) {
-	if link <= 0 || link >= uint32(len(f.Sections)) {
-		return nil, errors.New("section has invalid string table link")
-	}
-	return f.Sections[link].Data()
-}
-
-// Open returns a new ReadSeeker reading the ELF section.
-func (s *Section) Open() io.ReadSeeker { return io.NewSectionReader(s.sr, 0, 1<<63-1) }
-
-// A ProgHeader represents a single ELF program header.
-type ProgHeader struct {
-	Type   ProgType
-	Flags  ProgFlag
-	Off    uint64
-	Vaddr  uint64
-	Paddr  uint64
-	Filesz uint64
-	Memsz  uint64
-	Align  uint64
-}
-
-// A Prog represents a single ELF program header in an ELF binary.
-type Prog struct {
-	ProgHeader
-
-	// Embed ReaderAt for ReadAt method.
-	// Do not embed SectionReader directly
-	// to avoid having Read and Seek.
-	// If a client wants Read and Seek it must use
-	// Open() to avoid fighting over the seek offset
-	// with other clients.
-	io.ReaderAt
-	sr *io.SectionReader
-}
-
-// Open returns a new ReadSeeker reading the ELF program body.
-func (p *Prog) Open() io.ReadSeeker { return io.NewSectionReader(p.sr, 0, 1<<63-1) }
-
-// A Symbol represents an entry in an ELF symbol table section.
-type Symbol struct {
-	Name        string
-	Info, Other byte
-	Section     SectionIndex
-	Value, Size uint64
-}
-
-/*
- * ELF reader
- */
-
-type FormatError struct {
-	off int64
-	msg string
-	val interface{}
-}
-
-func (e *FormatError) Error() string {
-	msg := e.msg
-	if e.val != nil {
-		msg += fmt.Sprintf(" '%v' ", e.val)
-	}
-	msg += fmt.Sprintf("in record at byte %#x", e.off)
-	return msg
-}
-
-// Open opens the named file using os.Open and prepares it for use as an ELF binary.
-func Open(name string) (*File, error) {
-	f, err := os.Open(name)
-	if err != nil {
-		return nil, err
-	}
-	ff, err := NewFile(f)
-	if err != nil {
-		f.Close()
-		return nil, err
-	}
-	ff.closer = f
-	return ff, nil
-}
-
-// Close closes the File.
-// If the File was created using NewFile directly instead of Open,
-// Close has no effect.
-func (f *File) Close() error {
-	var err error
-	if f.closer != nil {
-		err = f.closer.Close()
-		f.closer = nil
-	}
-	return err
-}
-
-// SectionByType returns the first section in f with the
-// given type, or nil if there is no such section.
-func (f *File) SectionByType(typ SectionType) *Section {
-	for _, s := range f.Sections {
-		if s.Type == typ {
-			return s
-		}
-	}
-	return nil
-}
-
-// NewFile creates a new File for accessing an ELF binary in an underlying reader.
-// The ELF binary is expected to start at position 0 in the ReaderAt.
-func NewFile(r io.ReaderAt) (*File, error) {
-	sr := io.NewSectionReader(r, 0, 1<<63-1)
-	// Read and decode ELF identifier
-	var ident [16]uint8
-	if _, err := r.ReadAt(ident[0:], 0); err != nil {
-		return nil, err
-	}
-	if ident[0] != '\x7f' || ident[1] != 'E' || ident[2] != 'L' || ident[3] != 'F' {
-		return nil, &FormatError{0, "bad magic number", ident[0:4]}
-	}
-
-	f := new(File)
-	f.Class = Class(ident[EI_CLASS])
-	switch f.Class {
-	case ELFCLASS32:
-	case ELFCLASS64:
-		// ok
-	default:
-		return nil, &FormatError{0, "unknown ELF class", f.Class}
-	}
-
-	f.Data = Data(ident[EI_DATA])
-	switch f.Data {
-	case ELFDATA2LSB:
-		f.ByteOrder = binary.LittleEndian
-	case ELFDATA2MSB:
-		f.ByteOrder = binary.BigEndian
-	default:
-		return nil, &FormatError{0, "unknown ELF data encoding", f.Data}
-	}
-
-	f.Version = Version(ident[EI_VERSION])
-	if f.Version != EV_CURRENT {
-		return nil, &FormatError{0, "unknown ELF version", f.Version}
-	}
-
-	f.OSABI = OSABI(ident[EI_OSABI])
-	f.ABIVersion = ident[EI_ABIVERSION]
-
-	// Read ELF file header
-	var phoff int64
-	var phentsize, phnum int
-	var shoff int64
-	var shentsize, shnum, shstrndx int
-	shstrndx = -1
-	switch f.Class {
-	case ELFCLASS32:
-		hdr := new(Header32)
-		sr.Seek(0, os.SEEK_SET)
-		if err := binary.Read(sr, f.ByteOrder, hdr); err != nil {
-			return nil, err
-		}
-		f.Type = Type(hdr.Type)
-		f.Machine = Machine(hdr.Machine)
-		f.Entry = uint64(hdr.Entry)
-		if v := Version(hdr.Version); v != f.Version {
-			return nil, &FormatError{0, "mismatched ELF version", v}
-		}
-		phoff = int64(hdr.Phoff)
-		phentsize = int(hdr.Phentsize)
-		phnum = int(hdr.Phnum)
-		shoff = int64(hdr.Shoff)
-		shentsize = int(hdr.Shentsize)
-		shnum = int(hdr.Shnum)
-		shstrndx = int(hdr.Shstrndx)
-	case ELFCLASS64:
-		hdr := new(Header64)
-		sr.Seek(0, os.SEEK_SET)
-		if err := binary.Read(sr, f.ByteOrder, hdr); err != nil {
-			return nil, err
-		}
-		f.Type = Type(hdr.Type)
-		f.Machine = Machine(hdr.Machine)
-		f.Entry = uint64(hdr.Entry)
-		if v := Version(hdr.Version); v != f.Version {
-			return nil, &FormatError{0, "mismatched ELF version", v}
-		}
-		phoff = int64(hdr.Phoff)
-		phentsize = int(hdr.Phentsize)
-		phnum = int(hdr.Phnum)
-		shoff = int64(hdr.Shoff)
-		shentsize = int(hdr.Shentsize)
-		shnum = int(hdr.Shnum)
-		shstrndx = int(hdr.Shstrndx)
-	}
-
-	if shnum > 0 && shoff > 0 && (shstrndx < 0 || shstrndx >= shnum) {
-		return nil, &FormatError{0, "invalid ELF shstrndx", shstrndx}
-	}
-
-	// Read program headers
-	f.Progs = make([]*Prog, phnum)
-	for i := 0; i < phnum; i++ {
-		off := phoff + int64(i)*int64(phentsize)
-		sr.Seek(off, os.SEEK_SET)
-		p := new(Prog)
-		switch f.Class {
-		case ELFCLASS32:
-			ph := new(Prog32)
-			if err := binary.Read(sr, f.ByteOrder, ph); err != nil {
-				return nil, err
-			}
-			p.ProgHeader = ProgHeader{
-				Type:   ProgType(ph.Type),
-				Flags:  ProgFlag(ph.Flags),
-				Off:    uint64(ph.Off),
-				Vaddr:  uint64(ph.Vaddr),
-				Paddr:  uint64(ph.Paddr),
-				Filesz: uint64(ph.Filesz),
-				Memsz:  uint64(ph.Memsz),
-				Align:  uint64(ph.Align),
-			}
-		case ELFCLASS64:
-			ph := new(Prog64)
-			if err := binary.Read(sr, f.ByteOrder, ph); err != nil {
-				return nil, err
-			}
-			p.ProgHeader = ProgHeader{
-				Type:   ProgType(ph.Type),
-				Flags:  ProgFlag(ph.Flags),
-				Off:    uint64(ph.Off),
-				Vaddr:  uint64(ph.Vaddr),
-				Paddr:  uint64(ph.Paddr),
-				Filesz: uint64(ph.Filesz),
-				Memsz:  uint64(ph.Memsz),
-				Align:  uint64(ph.Align),
-			}
-		}
-		p.sr = io.NewSectionReader(r, int64(p.Off), int64(p.Filesz))
-		p.ReaderAt = p.sr
-		f.Progs[i] = p
-	}
-
-	// Read section headers
-	f.Sections = make([]*Section, shnum)
-	names := make([]uint32, shnum)
-	for i := 0; i < shnum; i++ {
-		off := shoff + int64(i)*int64(shentsize)
-		sr.Seek(off, os.SEEK_SET)
-		s := new(Section)
-		switch f.Class {
-		case ELFCLASS32:
-			sh := new(Section32)
-			if err := binary.Read(sr, f.ByteOrder, sh); err != nil {
-				return nil, err
-			}
-			names[i] = sh.Name
-			s.SectionHeader = SectionHeader{
-				Type:      SectionType(sh.Type),
-				Flags:     SectionFlag(sh.Flags),
-				Addr:      uint64(sh.Addr),
-				Offset:    uint64(sh.Off),
-				Size:      uint64(sh.Size),
-				Link:      uint32(sh.Link),
-				Info:      uint32(sh.Info),
-				Addralign: uint64(sh.Addralign),
-				Entsize:   uint64(sh.Entsize),
-			}
-		case ELFCLASS64:
-			sh := new(Section64)
-			if err := binary.Read(sr, f.ByteOrder, sh); err != nil {
-				return nil, err
-			}
-			names[i] = sh.Name
-			s.SectionHeader = SectionHeader{
-				Type:      SectionType(sh.Type),
-				Flags:     SectionFlag(sh.Flags),
-				Offset:    uint64(sh.Off),
-				Size:      uint64(sh.Size),
-				Addr:      uint64(sh.Addr),
-				Link:      uint32(sh.Link),
-				Info:      uint32(sh.Info),
-				Addralign: uint64(sh.Addralign),
-				Entsize:   uint64(sh.Entsize),
-			}
-		}
-		s.sr = io.NewSectionReader(r, int64(s.Offset), int64(s.Size))
-		s.ReaderAt = s.sr
-		f.Sections[i] = s
-	}
-
-	if len(f.Sections) == 0 {
-		return f, nil
-	}
-
-	// Load section header string table.
-	shstrtab, err := f.Sections[shstrndx].Data()
-	if err != nil {
-		return nil, err
-	}
-	for i, s := range f.Sections {
-		var ok bool
-		s.Name, ok = getString(shstrtab, int(names[i]))
-		if !ok {
-			return nil, &FormatError{shoff + int64(i*shentsize), "bad section name index", names[i]}
-		}
-	}
-
-	return f, nil
-}
-
-// getSymbols returns a slice of Symbols from parsing the symbol table
-// with the given type, along with the associated string table.
-func (f *File) getSymbols(typ SectionType) ([]Symbol, []byte, error) {
-	switch f.Class {
-	case ELFCLASS64:
-		return f.getSymbols64(typ)
-
-	case ELFCLASS32:
-		return f.getSymbols32(typ)
-	}
-
-	return nil, nil, errors.New("not implemented")
-}
-
-func (f *File) getSymbols32(typ SectionType) ([]Symbol, []byte, error) {
-	symtabSection := f.SectionByType(typ)
-	if symtabSection == nil {
-		return nil, nil, errors.New("no symbol section")
-	}
-
-	data, err := symtabSection.Data()
-	if err != nil {
-		return nil, nil, errors.New("cannot load symbol section")
-	}
-	symtab := bytes.NewReader(data)
-	if symtab.Len()%Sym32Size != 0 {
-		return nil, nil, errors.New("length of symbol section is not a multiple of SymSize")
-	}
-
-	strdata, err := f.stringTable(symtabSection.Link)
-	if err != nil {
-		return nil, nil, errors.New("cannot load string table section")
-	}
-
-	// The first entry is all zeros.
-	var skip [Sym32Size]byte
-	symtab.Read(skip[:])
-
-	symbols := make([]Symbol, symtab.Len()/Sym32Size)
-
-	i := 0
-	var sym Sym32
-	for symtab.Len() > 0 {
-		binary.Read(symtab, f.ByteOrder, &sym)
-		str, _ := getString(strdata, int(sym.Name))
-		symbols[i].Name = str
-		symbols[i].Info = sym.Info
-		symbols[i].Other = sym.Other
-		symbols[i].Section = SectionIndex(sym.Shndx)
-		symbols[i].Value = uint64(sym.Value)
-		symbols[i].Size = uint64(sym.Size)
-		i++
-	}
-
-	return symbols, strdata, nil
-}
-
-func (f *File) getSymbols64(typ SectionType) ([]Symbol, []byte, error) {
-	symtabSection := f.SectionByType(typ)
-	if symtabSection == nil {
-		return nil, nil, errors.New("no symbol section")
-	}
-
-	data, err := symtabSection.Data()
-	if err != nil {
-		return nil, nil, errors.New("cannot load symbol section")
-	}
-	symtab := bytes.NewReader(data)
-	if symtab.Len()%Sym64Size != 0 {
-		return nil, nil, errors.New("length of symbol section is not a multiple of Sym64Size")
-	}
-
-	strdata, err := f.stringTable(symtabSection.Link)
-	if err != nil {
-		return nil, nil, errors.New("cannot load string table section")
-	}
-
-	// The first entry is all zeros.
-	var skip [Sym64Size]byte
-	symtab.Read(skip[:])
-
-	symbols := make([]Symbol, symtab.Len()/Sym64Size)
-
-	i := 0
-	var sym Sym64
-	for symtab.Len() > 0 {
-		binary.Read(symtab, f.ByteOrder, &sym)
-		str, _ := getString(strdata, int(sym.Name))
-		symbols[i].Name = str
-		symbols[i].Info = sym.Info
-		symbols[i].Other = sym.Other
-		symbols[i].Section = SectionIndex(sym.Shndx)
-		symbols[i].Value = sym.Value
-		symbols[i].Size = sym.Size
-		i++
-	}
-
-	return symbols, strdata, nil
-}
-
-// getString extracts a string from an ELF string table.
-func getString(section []byte, start int) (string, bool) {
-	if start < 0 || start >= len(section) {
-		return "", false
-	}
-
-	for end := start; end < len(section); end++ {
-		if section[end] == 0 {
-			return string(section[start:end]), true
-		}
-	}
-	return "", false
-}
-
-// Section returns a section with the given name, or nil if no such
-// section exists.
-func (f *File) Section(name string) *Section {
-	for _, s := range f.Sections {
-		if s.Name == name {
-			return s
-		}
-	}
-	return nil
-}
-
-// applyRelocations applies relocations to dst. rels is a relocations section
-// in RELA format.
-func (f *File) applyRelocations(dst []byte, rels []byte) error {
-	if f.Class == ELFCLASS64 && f.Machine == EM_X86_64 {
-		return f.applyRelocationsAMD64(dst, rels)
-	}
-	if f.Class == ELFCLASS32 && f.Machine == EM_386 {
-		return f.applyRelocations386(dst, rels)
-	}
-
-	return errors.New("not implemented")
-}
-
-func (f *File) applyRelocationsAMD64(dst []byte, rels []byte) error {
-	// 24 is the size of Rela64.
-	if len(rels)%24 != 0 {
-		return errors.New("length of relocation section is not a multiple of 24")
-	}
-
-	symbols, _, err := f.getSymbols(SHT_SYMTAB)
-	if err != nil {
-		return err
-	}
-
-	b := bytes.NewReader(rels)
-	var rela Rela64
-
-	for b.Len() > 0 {
-		binary.Read(b, f.ByteOrder, &rela)
-		symNo := rela.Info >> 32
-		t := R_X86_64(rela.Info & 0xffff)
-
-		if symNo == 0 || symNo > uint64(len(symbols)) {
-			continue
-		}
-		sym := &symbols[symNo-1]
-		if SymType(sym.Info&0xf) != STT_SECTION {
-			// We don't handle non-section relocations for now.
-			continue
-		}
-
-		switch t {
-		case R_X86_64_64:
-			if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 {
-				continue
-			}
-			f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], uint64(rela.Addend))
-		case R_X86_64_32:
-			if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 {
-				continue
-			}
-			f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], uint32(rela.Addend))
-		}
-	}
-
-	return nil
-}
-
-func (f *File) applyRelocations386(dst []byte, rels []byte) error {
-	// 8 is the size of Rel32.
-	if len(rels)%8 != 0 {
-		return errors.New("length of relocation section is not a multiple of 8")
-	}
-
-	symbols, _, err := f.getSymbols(SHT_SYMTAB)
-	if err != nil {
-		return err
-	}
-
-	b := bytes.NewReader(rels)
-	var rel Rel32
-
-	for b.Len() > 0 {
-		binary.Read(b, f.ByteOrder, &rel)
-		symNo := rel.Info >> 8
-		t := R_386(rel.Info & 0xff)
-
-		if symNo == 0 || symNo > uint32(len(symbols)) {
-			continue
-		}
-		sym := &symbols[symNo-1]
-
-		if t == R_386_32 {
-			if rel.Off+4 >= uint32(len(dst)) {
-				continue
-			}
-			val := f.ByteOrder.Uint32(dst[rel.Off : rel.Off+4])
-			val += uint32(sym.Value)
-			f.ByteOrder.PutUint32(dst[rel.Off:rel.Off+4], val)
-		}
-	}
-
-	return nil
-}
-
-func (f *File) DWARF() (*dwarf.Data, error) {
-	// There are many other DWARF sections, but these
-	// are the required ones, and the debug/dwarf package
-	// does not use the others, so don't bother loading them.
-	var names = [...]string{"abbrev", "info", "str"}
-	var dat [len(names)][]byte
-	for i, name := range names {
-		name = ".debug_" + name
-		s := f.Section(name)
-		if s == nil {
-			continue
-		}
-		b, err := s.Data()
-		if err != nil && uint64(len(b)) < s.Size {
-			return nil, err
-		}
-		dat[i] = b
-	}
-
-	// If there's a relocation table for .debug_info, we have to process it
-	// now otherwise the data in .debug_info is invalid for x86-64 objects.
-	rela := f.Section(".rela.debug_info")
-	if rela != nil && rela.Type == SHT_RELA && f.Machine == EM_X86_64 {
-		data, err := rela.Data()
-		if err != nil {
-			return nil, err
-		}
-		err = f.applyRelocations(dat[1], data)
-		if err != nil {
-			return nil, err
-		}
-	}
-
-	// When using clang we need to process relocations even for 386.
-	rel := f.Section(".rel.debug_info")
-	if rel != nil && rel.Type == SHT_REL && f.Machine == EM_386 {
-		data, err := rel.Data()
-		if err != nil {
-			return nil, err
-		}
-		err = f.applyRelocations(dat[1], data)
-		if err != nil {
-			return nil, err
-		}
-	}
-
-	abbrev, info, str := dat[0], dat[1], dat[2]
-	d, err := dwarf.New(abbrev, nil, nil, info, nil, nil, nil, str)
-	if err != nil {
-		return nil, err
-	}
-
-	// Look for DWARF4 .debug_types sections.
-	for i, s := range f.Sections {
-		if s.Name == ".debug_types" {
-			b, err := s.Data()
-			if err != nil && uint64(len(b)) < s.Size {
-				return nil, err
-			}
-
-			for _, r := range f.Sections {
-				if r.Type != SHT_RELA && r.Type != SHT_REL {
-					continue
-				}
-				if int(r.Info) != i {
-					continue
-				}
-				rd, err := r.Data()
-				if err != nil {
-					return nil, err
-				}
-				err = f.applyRelocations(b, rd)
-				if err != nil {
-					return nil, err
-				}
-			}
-
-			err = d.AddTypes(fmt.Sprintf("types-%d", i), b)
-			if err != nil {
-				return nil, err
-			}
-		}
-	}
-
-	return d, nil
-}
-
-// Symbols returns the symbol table for f.
-//
-// For compatibility with Go 1.0, Symbols omits the null symbol at index 0.
-// After retrieving the symbols as symtab, an externally supplied index x
-// corresponds to symtab[x-1], not symtab[x].
-func (f *File) Symbols() ([]Symbol, error) {
-	sym, _, err := f.getSymbols(SHT_SYMTAB)
-	return sym, err
-}
-
-type ImportedSymbol struct {
-	Name    string
-	Version string
-	Library string
-}
-
-// ImportedSymbols returns the names of all symbols
-// referred to by the binary f that are expected to be
-// satisfied by other libraries at dynamic load time.
-// It does not return weak symbols.
-func (f *File) ImportedSymbols() ([]ImportedSymbol, error) {
-	sym, str, err := f.getSymbols(SHT_DYNSYM)
-	if err != nil {
-		return nil, err
-	}
-	f.gnuVersionInit(str)
-	var all []ImportedSymbol
-	for i, s := range sym {
-		if ST_BIND(s.Info) == STB_GLOBAL && s.Section == SHN_UNDEF {
-			all = append(all, ImportedSymbol{Name: s.Name})
-			f.gnuVersion(i, &all[len(all)-1])
-		}
-	}
-	return all, nil
-}
-
-type verneed struct {
-	File string
-	Name string
-}
-
-// gnuVersionInit parses the GNU version tables
-// for use by calls to gnuVersion.
-func (f *File) gnuVersionInit(str []byte) {
-	// Accumulate verneed information.
-	vn := f.SectionByType(SHT_GNU_VERNEED)
-	if vn == nil {
-		return
-	}
-	d, _ := vn.Data()
-
-	var need []verneed
-	i := 0
-	for {
-		if i+16 > len(d) {
-			break
-		}
-		vers := f.ByteOrder.Uint16(d[i : i+2])
-		if vers != 1 {
-			break
-		}
-		cnt := f.ByteOrder.Uint16(d[i+2 : i+4])
-		fileoff := f.ByteOrder.Uint32(d[i+4 : i+8])
-		aux := f.ByteOrder.Uint32(d[i+8 : i+12])
-		next := f.ByteOrder.Uint32(d[i+12 : i+16])
-		file, _ := getString(str, int(fileoff))
-
-		var name string
-		j := i + int(aux)
-		for c := 0; c < int(cnt); c++ {
-			if j+16 > len(d) {
-				break
-			}
-			// hash := f.ByteOrder.Uint32(d[j:j+4])
-			// flags := f.ByteOrder.Uint16(d[j+4:j+6])
-			other := f.ByteOrder.Uint16(d[j+6 : j+8])
-			nameoff := f.ByteOrder.Uint32(d[j+8 : j+12])
-			next := f.ByteOrder.Uint32(d[j+12 : j+16])
-			name, _ = getString(str, int(nameoff))
-			ndx := int(other)
-			if ndx >= len(need) {
-				a := make([]verneed, 2*(ndx+1))
-				copy(a, need)
-				need = a
-			}
-
-			need[ndx] = verneed{file, name}
-			if next == 0 {
-				break
-			}
-			j += int(next)
-		}
-
-		if next == 0 {
-			break
-		}
-		i += int(next)
-	}
-
-	// Versym parallels symbol table, indexing into verneed.
-	vs := f.SectionByType(SHT_GNU_VERSYM)
-	if vs == nil {
-		return
-	}
-	d, _ = vs.Data()
-
-	f.gnuNeed = need
-	f.gnuVersym = d
-}
-
-// gnuVersion adds Library and Version information to sym,
-// which came from offset i of the symbol table.
-func (f *File) gnuVersion(i int, sym *ImportedSymbol) {
-	// Each entry is two bytes.
-	i = (i + 1) * 2
-	if i >= len(f.gnuVersym) {
-		return
-	}
-	j := int(f.ByteOrder.Uint16(f.gnuVersym[i:]))
-	if j < 2 || j >= len(f.gnuNeed) {
-		return
-	}
-	n := &f.gnuNeed[j]
-	sym.Library = n.File
-	sym.Version = n.Name
-}
-
-// ImportedLibraries returns the names of all libraries
-// referred to by the binary f that are expected to be
-// linked with the binary at dynamic link time.
-func (f *File) ImportedLibraries() ([]string, error) {
-	return f.DynString(DT_NEEDED)
-}
-
-// DynString returns the strings listed for the given tag in the file's dynamic
-// section.
-//
-// The tag must be one that takes string values: DT_NEEDED, DT_SONAME, DT_RPATH, or
-// DT_RUNPATH.
-func (f *File) DynString(tag DynTag) ([]string, error) {
-	switch tag {
-	case DT_NEEDED, DT_SONAME, DT_RPATH, DT_RUNPATH:
-	default:
-		return nil, fmt.Errorf("non-string-valued tag %v", tag)
-	}
-	ds := f.SectionByType(SHT_DYNAMIC)
-	if ds == nil {
-		// not dynamic, so no libraries
-		return nil, nil
-	}
-	d, err := ds.Data()
-	if err != nil {
-		return nil, err
-	}
-	str, err := f.stringTable(ds.Link)
-	if err != nil {
-		return nil, err
-	}
-	var all []string
-	for len(d) > 0 {
-		var t DynTag
-		var v uint64
-		switch f.Class {
-		case ELFCLASS32:
-			t = DynTag(f.ByteOrder.Uint32(d[0:4]))
-			v = uint64(f.ByteOrder.Uint32(d[4:8]))
-			d = d[8:]
-		case ELFCLASS64:
-			t = DynTag(f.ByteOrder.Uint64(d[0:8]))
-			v = f.ByteOrder.Uint64(d[8:16])
-			d = d[16:]
-		}
-		if t == tag {
-			s, ok := getString(str, int(v))
-			if ok {
-				all = append(all, s)
-			}
-		}
-	}
-	return all, nil
-}
diff --git a/src/pkg/debug/elf/file_test.go b/src/pkg/debug/elf/file_test.go
deleted file mode 100644
index 7f88a54..0000000
--- a/src/pkg/debug/elf/file_test.go
+++ /dev/null
@@ -1,339 +0,0 @@
-// Copyright 2009 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package elf
-
-import (
-	"bytes"
-	"compress/gzip"
-	"debug/dwarf"
-	"encoding/binary"
-	"io"
-	"net"
-	"os"
-	"path"
-	"reflect"
-	"runtime"
-	"testing"
-)
-
-type fileTest struct {
-	file     string
-	hdr      FileHeader
-	sections []SectionHeader
-	progs    []ProgHeader
-	needed   []string
-}
-
-var fileTests = []fileTest{
-	{
-		"testdata/gcc-386-freebsd-exec",
-		FileHeader{ELFCLASS32, ELFDATA2LSB, EV_CURRENT, ELFOSABI_FREEBSD, 0, binary.LittleEndian, ET_EXEC, EM_386, 0x80483cc},
-		[]SectionHeader{
-			{"", SHT_NULL, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
-			{".interp", SHT_PROGBITS, SHF_ALLOC, 0x80480d4, 0xd4, 0x15, 0x0, 0x0, 0x1, 0x0},
-			{".hash", SHT_HASH, SHF_ALLOC, 0x80480ec, 0xec, 0x90, 0x3, 0x0, 0x4, 0x4},
-			{".dynsym", SHT_DYNSYM, SHF_ALLOC, 0x804817c, 0x17c, 0x110, 0x4, 0x1, 0x4, 0x10},
-			{".dynstr", SHT_STRTAB, SHF_ALLOC, 0x804828c, 0x28c, 0xbb, 0x0, 0x0, 0x1, 0x0},
-			{".rel.plt", SHT_REL, SHF_ALLOC, 0x8048348, 0x348, 0x20, 0x3, 0x7, 0x4, 0x8},
-			{".init", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x8048368, 0x368, 0x11, 0x0, 0x0, 0x4, 0x0},
-			{".plt", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x804837c, 0x37c, 0x50, 0x0, 0x0, 0x4, 0x4},
-			{".text", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x80483cc, 0x3cc, 0x180, 0x0, 0x0, 0x4, 0x0},
-			{".fini", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x804854c, 0x54c, 0xc, 0x0, 0x0, 0x4, 0x0},
-			{".rodata", SHT_PROGBITS, SHF_ALLOC, 0x8048558, 0x558, 0xa3, 0x0, 0x0, 0x1, 0x0},
-			{".data", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x80495fc, 0x5fc, 0xc, 0x0, 0x0, 0x4, 0x0},
-			{".eh_frame", SHT_PROGBITS, SHF_ALLOC, 0x8049608, 0x608, 0x4, 0x0, 0x0, 0x4, 0x0},
-			{".dynamic", SHT_DYNAMIC, SHF_WRITE + SHF_ALLOC, 0x804960c, 0x60c, 0x98, 0x4, 0x0, 0x4, 0x8},
-			{".ctors", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x80496a4, 0x6a4, 0x8, 0x0, 0x0, 0x4, 0x0},
-			{".dtors", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x80496ac, 0x6ac, 0x8, 0x0, 0x0, 0x4, 0x0},
-			{".jcr", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x80496b4, 0x6b4, 0x4, 0x0, 0x0, 0x4, 0x0},
-			{".got", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x80496b8, 0x6b8, 0x1c, 0x0, 0x0, 0x4, 0x4},
-			{".bss", SHT_NOBITS, SHF_WRITE + SHF_ALLOC, 0x80496d4, 0x6d4, 0x20, 0x0, 0x0, 0x4, 0x0},
-			{".comment", SHT_PROGBITS, 0x0, 0x0, 0x6d4, 0x12d, 0x0, 0x0, 0x1, 0x0},
-			{".debug_aranges", SHT_PROGBITS, 0x0, 0x0, 0x801, 0x20, 0x0, 0x0, 0x1, 0x0},
-			{".debug_pubnames", SHT_PROGBITS, 0x0, 0x0, 0x821, 0x1b, 0x0, 0x0, 0x1, 0x0},
-			{".debug_info", SHT_PROGBITS, 0x0, 0x0, 0x83c, 0x11d, 0x0, 0x0, 0x1, 0x0},
-			{".debug_abbrev", SHT_PROGBITS, 0x0, 0x0, 0x959, 0x41, 0x0, 0x0, 0x1, 0x0},
-			{".debug_line", SHT_PROGBITS, 0x0, 0x0, 0x99a, 0x35, 0x0, 0x0, 0x1, 0x0},
-			{".debug_frame", SHT_PROGBITS, 0x0, 0x0, 0x9d0, 0x30, 0x0, 0x0, 0x4, 0x0},
-			{".debug_str", SHT_PROGBITS, 0x0, 0x0, 0xa00, 0xd, 0x0, 0x0, 0x1, 0x0},
-			{".shstrtab", SHT_STRTAB, 0x0, 0x0, 0xa0d, 0xf8, 0x0, 0x0, 0x1, 0x0},
-			{".symtab", SHT_SYMTAB, 0x0, 0x0, 0xfb8, 0x4b0, 0x1d, 0x38, 0x4, 0x10},
-			{".strtab", SHT_STRTAB, 0x0, 0x0, 0x1468, 0x206, 0x0, 0x0, 0x1, 0x0},
-		},
-		[]ProgHeader{
-			{PT_PHDR, PF_R + PF_X, 0x34, 0x8048034, 0x8048034, 0xa0, 0xa0, 0x4},
-			{PT_INTERP, PF_R, 0xd4, 0x80480d4, 0x80480d4, 0x15, 0x15, 0x1},
-			{PT_LOAD, PF_R + PF_X, 0x0, 0x8048000, 0x8048000, 0x5fb, 0x5fb, 0x1000},
-			{PT_LOAD, PF_R + PF_W, 0x5fc, 0x80495fc, 0x80495fc, 0xd8, 0xf8, 0x1000},
-			{PT_DYNAMIC, PF_R + PF_W, 0x60c, 0x804960c, 0x804960c, 0x98, 0x98, 0x4},
-		},
-		[]string{"libc.so.6"},
-	},
-	{
-		"testdata/gcc-amd64-linux-exec",
-		FileHeader{ELFCLASS64, ELFDATA2LSB, EV_CURRENT, ELFOSABI_NONE, 0, binary.LittleEndian, ET_EXEC, EM_X86_64, 0x4003e0},
-		[]SectionHeader{
-			{"", SHT_NULL, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
-			{".interp", SHT_PROGBITS, SHF_ALLOC, 0x400200, 0x200, 0x1c, 0x0, 0x0, 0x1, 0x0},
-			{".note.ABI-tag", SHT_NOTE, SHF_ALLOC, 0x40021c, 0x21c, 0x20, 0x0, 0x0, 0x4, 0x0},
-			{".hash", SHT_HASH, SHF_ALLOC, 0x400240, 0x240, 0x24, 0x5, 0x0, 0x8, 0x4},
-			{".gnu.hash", SHT_LOOS + 268435446, SHF_ALLOC, 0x400268, 0x268, 0x1c, 0x5, 0x0, 0x8, 0x0},
-			{".dynsym", SHT_DYNSYM, SHF_ALLOC, 0x400288, 0x288, 0x60, 0x6, 0x1, 0x8, 0x18},
-			{".dynstr", SHT_STRTAB, SHF_ALLOC, 0x4002e8, 0x2e8, 0x3d, 0x0, 0x0, 0x1, 0x0},
-			{".gnu.version", SHT_HIOS, SHF_ALLOC, 0x400326, 0x326, 0x8, 0x5, 0x0, 0x2, 0x2},
-			{".gnu.version_r", SHT_LOOS + 268435454, SHF_ALLOC, 0x400330, 0x330, 0x20, 0x6, 0x1, 0x8, 0x0},
-			{".rela.dyn", SHT_RELA, SHF_ALLOC, 0x400350, 0x350, 0x18, 0x5, 0x0, 0x8, 0x18},
-			{".rela.plt", SHT_RELA, SHF_ALLOC, 0x400368, 0x368, 0x30, 0x5, 0xc, 0x8, 0x18},
-			{".init", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x400398, 0x398, 0x18, 0x0, 0x0, 0x4, 0x0},
-			{".plt", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x4003b0, 0x3b0, 0x30, 0x0, 0x0, 0x4, 0x10},
-			{".text", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x4003e0, 0x3e0, 0x1b4, 0x0, 0x0, 0x10, 0x0},
-			{".fini", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR, 0x400594, 0x594, 0xe, 0x0, 0x0, 0x4, 0x0},
-			{".rodata", SHT_PROGBITS, SHF_ALLOC, 0x4005a4, 0x5a4, 0x11, 0x0, 0x0, 0x4, 0x0},
-			{".eh_frame_hdr", SHT_PROGBITS, SHF_ALLOC, 0x4005b8, 0x5b8, 0x24, 0x0, 0x0, 0x4, 0x0},
-			{".eh_frame", SHT_PROGBITS, SHF_ALLOC, 0x4005e0, 0x5e0, 0xa4, 0x0, 0x0, 0x8, 0x0},
-			{".ctors", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x600688, 0x688, 0x10, 0x0, 0x0, 0x8, 0x0},
-			{".dtors", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x600698, 0x698, 0x10, 0x0, 0x0, 0x8, 0x0},
-			{".jcr", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x6006a8, 0x6a8, 0x8, 0x0, 0x0, 0x8, 0x0},
-			{".dynamic", SHT_DYNAMIC, SHF_WRITE + SHF_ALLOC, 0x6006b0, 0x6b0, 0x1a0, 0x6, 0x0, 0x8, 0x10},
-			{".got", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x600850, 0x850, 0x8, 0x0, 0x0, 0x8, 0x8},
-			{".got.plt", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x600858, 0x858, 0x28, 0x0, 0x0, 0x8, 0x8},
-			{".data", SHT_PROGBITS, SHF_WRITE + SHF_ALLOC, 0x600880, 0x880, 0x18, 0x0, 0x0, 0x8, 0x0},
-			{".bss", SHT_NOBITS, SHF_WRITE + SHF_ALLOC, 0x600898, 0x898, 0x8, 0x0, 0x0, 0x4, 0x0},
-			{".comment", SHT_PROGBITS, 0x0, 0x0, 0x898, 0x126, 0x0, 0x0, 0x1, 0x0},
-			{".debug_aranges", SHT_PROGBITS, 0x0, 0x0, 0x9c0, 0x90, 0x0, 0x0, 0x10, 0x0},
-			{".debug_pubnames", SHT_PROGBITS, 0x0, 0x0, 0xa50, 0x25, 0x0, 0x0, 0x1, 0x0},
-			{".debug_info", SHT_PROGBITS, 0x0, 0x0, 0xa75, 0x1a7, 0x0, 0x0, 0x1, 0x0},
-			{".debug_abbrev", SHT_PROGBITS, 0x0, 0x0, 0xc1c, 0x6f, 0x0, 0x0, 0x1, 0x0},
-			{".debug_line", SHT_PROGBITS, 0x0, 0x0, 0xc8b, 0x13f, 0x0, 0x0, 0x1, 0x0},
-			{".debug_str", SHT_PROGBITS, SHF_MERGE + SHF_STRINGS, 0x0, 0xdca, 0xb1, 0x0, 0x0, 0x1, 0x1},
-			{".debug_ranges", SHT_PROGBITS, 0x0, 0x0, 0xe80, 0x90, 0x0, 0x0, 0x10, 0x0},
-			{".shstrtab", SHT_STRTAB, 0x0, 0x0, 0xf10, 0x149, 0x0, 0x0, 0x1, 0x0},
-			{".symtab", SHT_SYMTAB, 0x0, 0x0, 0x19a0, 0x6f0, 0x24, 0x39, 0x8, 0x18},
-			{".strtab", SHT_STRTAB, 0x0, 0x0, 0x2090, 0x1fc, 0x0, 0x0, 0x1, 0x0},
-		},
-		[]ProgHeader{
-			{PT_PHDR, PF_R + PF_X, 0x40, 0x400040, 0x400040, 0x1c0, 0x1c0, 0x8},
-			{PT_INTERP, PF_R, 0x200, 0x400200, 0x400200, 0x1c, 0x1c, 1},
-			{PT_LOAD, PF_R + PF_X, 0x0, 0x400000, 0x400000, 0x684, 0x684, 0x200000},
-			{PT_LOAD, PF_R + PF_W, 0x688, 0x600688, 0x600688, 0x210, 0x218, 0x200000},
-			{PT_DYNAMIC, PF_R + PF_W, 0x6b0, 0x6006b0, 0x6006b0, 0x1a0, 0x1a0, 0x8},
-			{PT_NOTE, PF_R, 0x21c, 0x40021c, 0x40021c, 0x20, 0x20, 0x4},
-			{PT_LOOS + 0x474E550, PF_R, 0x5b8, 0x4005b8, 0x4005b8, 0x24, 0x24, 0x4},
-			{PT_LOOS + 0x474E551, PF_R + PF_W, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8},
-		},
-		[]string{"libc.so.6"},
-	},
-	{
-		"testdata/hello-world-core.gz",
-		FileHeader{ELFCLASS64, ELFDATA2LSB, EV_CURRENT, ELFOSABI_NONE, 0x0, binary.LittleEndian, ET_CORE, EM_X86_64, 0x0},
-		[]SectionHeader{},
-		[]ProgHeader{
-			{Type: PT_NOTE, Flags: 0x0, Off: 0x3f8, Vaddr: 0x0, Paddr: 0x0, Filesz: 0x8ac, Memsz: 0x0, Align: 0x0},
-			{Type: PT_LOAD, Flags: PF_X + PF_R, Off: 0x1000, Vaddr: 0x400000, Paddr: 0x0, Filesz: 0x0, Memsz: 0x1000, Align: 0x1000},
-			{Type: PT_LOAD, Flags: PF_R, Off: 0x1000, Vaddr: 0x401000, Paddr: 0x0, Filesz: 0x1000, Memsz: 0x1000, Align: 0x1000},
-			{Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0x2000, Vaddr: 0x402000, Paddr: 0x0, Filesz: 0x1000, Memsz: 0x1000, Align: 0x1000},
-			{Type: PT_LOAD, Flags: PF_X + PF_R, Off: 0x3000, Vaddr: 0x7f54078b8000, Paddr: 0x0, Filesz: 0x0, Memsz: 0x1b5000, Align: 0x1000},
-			{Type: PT_LOAD, Flags: 0x0, Off: 0x3000, Vaddr: 0x7f5407a6d000, Paddr: 0x0, Filesz: 0x0, Memsz: 0x1ff000, Align: 0x1000},
-			{Type: PT_LOAD, Flags: PF_R, Off: 0x3000, Vaddr: 0x7f5407c6c000, Paddr: 0x0, Filesz: 0x4000, Memsz: 0x4000, Align: 0x1000},
-			{Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0x7000, Vaddr: 0x7f5407c70000, Paddr: 0x0, Filesz: 0x2000, Memsz: 0x2000, Align: 0x1000},
-			{Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0x9000, Vaddr: 0x7f5407c72000, Paddr: 0x0, Filesz: 0x5000, Memsz: 0x5000, Align: 0x1000},
-			{Type: PT_LOAD, Flags: PF_X + PF_R, Off: 0xe000, Vaddr: 0x7f5407c77000, Paddr: 0x0, Filesz: 0x0, Memsz: 0x22000, Align: 0x1000},
-			{Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0xe000, Vaddr: 0x7f5407e81000, Paddr: 0x0, Filesz: 0x3000, Memsz: 0x3000, Align: 0x1000},
-			{Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0x11000, Vaddr: 0x7f5407e96000, Paddr: 0x0, Filesz: 0x3000, Memsz: 0x3000, Align: 0x1000},
-			{Type: PT_LOAD, Flags: PF_R, Off: 0x14000, Vaddr: 0x7f5407e99000, Paddr: 0x0, Filesz: 0x1000, Memsz: 0x1000, Align: 0x1000},
-			{Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0x15000, Vaddr: 0x7f5407e9a000, Paddr: 0x0, Filesz: 0x2000, Memsz: 0x2000, Align: 0x1000},
-			{Type: PT_LOAD, Flags: PF_W + PF_R, Off: 0x17000, Vaddr: 0x7fff79972000, Paddr: 0x0, Filesz: 0x23000, Memsz: 0x23000, Align: 0x1000},
-			{Type: PT_LOAD, Flags: PF_X + PF_R, Off: 0x3a000, Vaddr: 0x7fff799f8000, Paddr: 0x0, Filesz: 0x1000, Memsz: 0x1000, Align: 0x1000},
-			{Type: PT_LOAD, Flags: PF_X + PF_R, Off: 0x3b000, Vaddr: 0xffffffffff600000, Paddr: 0x0, Filesz: 0x1000, Memsz: 0x1000, Align: 0x1000},
-		},
-		nil,
-	},
-}
-
-func TestOpen(t *testing.T) {
-	for i := range fileTests {
-		tt := &fileTests[i]
-
-		var f *File
-		var err error
-		if path.Ext(tt.file) == ".gz" {
-			var r io.ReaderAt
-			if r, err = decompress(tt.file); err == nil {
-				f, err = NewFile(r)
-			}
-		} else {
-			f, err = Open(tt.file)
-		}
-		defer f.Close()
-		if err != nil {
-			t.Errorf("cannot open file %s: %v", tt.file, err)
-			continue
-		}
-		if !reflect.DeepEqual(f.FileHeader, tt.hdr) {
-			t.Errorf("open %s:\n\thave %#v\n\twant %#v\n", tt.file, f.FileHeader, tt.hdr)
-			continue
-		}
-		for i, s := range f.Sections {
-			if i >= len(tt.sections) {
-				break
-			}
-			sh := &tt.sections[i]
-			if !reflect.DeepEqual(&s.SectionHeader, sh) {
-				t.Errorf("open %s, section %d:\n\thave %#v\n\twant %#v\n", tt.file, i, &s.SectionHeader, sh)
-			}
-		}
-		for i, p := range f.Progs {
-			if i >= len(tt.progs) {
-				break
-			}
-			ph := &tt.progs[i]
-			if !reflect.DeepEqual(&p.ProgHeader, ph) {
-				t.Errorf("open %s, program %d:\n\thave %#v\n\twant %#v\n", tt.file, i, &p.ProgHeader, ph)
-			}
-		}
-		tn := len(tt.sections)
-		fn := len(f.Sections)
-		if tn != fn {
-			t.Errorf("open %s: len(Sections) = %d, want %d", tt.file, fn, tn)
-		}
-		tn = len(tt.progs)
-		fn = len(f.Progs)
-		if tn != fn {
-			t.Errorf("open %s: len(Progs) = %d, want %d", tt.file, fn, tn)
-		}
-		tl := tt.needed
-		fl, err := f.ImportedLibraries()
-		if err != nil {
-			t.Error(err)
-		}
-		if !reflect.DeepEqual(tl, fl) {
-			t.Errorf("open %s: DT_NEEDED = %v, want %v", tt.file, tl, fl)
-		}
-	}
-}
-
-// elf.NewFile requires io.ReaderAt, which compress/gzip cannot
-// provide. Decompress the file to a bytes.Reader.
-func decompress(gz string) (io.ReaderAt, error) {
-	in, err := os.Open(gz)
-	if err != nil {
-		return nil, err
-	}
-	defer in.Close()
-	r, err := gzip.NewReader(in)
-	if err != nil {
-		return nil, err
-	}
-	var out bytes.Buffer
-	_, err = io.Copy(&out, r)
-	return bytes.NewReader(out.Bytes()), err
-}
-
-type relocationTestEntry struct {
-	entryNumber int
-	entry       *dwarf.Entry
-}
-
-type relocationTest struct {
-	file    string
-	entries []relocationTestEntry
-}
-
-var relocationTests = []relocationTest{
-	{
-		"testdata/go-relocation-test-gcc441-x86-64.obj",
-		[]relocationTestEntry{
-			{0, &dwarf.Entry{Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{{Attr: dwarf.AttrProducer, Val: "GNU C 4.4.1"}, {Attr: dwarf.AttrLanguage, Val: int64(1)}, {Attr: dwarf.AttrName, Val: "go-relocation-test.c"}, {Attr: dwarf.AttrCompDir, Val: "/tmp"}, {Attr: dwarf.AttrLowpc, Val: uint64(0x0)}, {Attr: dwarf.AttrHighpc, Val: uint64(0x6)}, {Attr: dwarf.AttrStmtList, Val: int64(0)}}}},
-		},
-	},
-	{
-		"testdata/go-relocation-test-gcc441-x86.obj",
-		[]relocationTestEntry{
-			{0, &dwarf.Entry{Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{{Attr: dwarf.AttrProducer, Val: "GNU C 4.4.1"}, {Attr: dwarf.AttrLanguage, Val: int64(1)}, {Attr: dwarf.AttrName, Val: "t.c"}, {Attr: dwarf.AttrCompDir, Val: "/tmp"}, {Attr: dwarf.AttrLowpc, Val: uint64(0x0)}, {Attr: dwarf.AttrHighpc, Val: uint64(0x5)}, {Attr: dwarf.AttrStmtList, Val: int64(0)}}}},
-		},
-	},
-	{
-		"testdata/go-relocation-test-gcc424-x86-64.obj",
-		[]relocationTestEntry{
-			{0, &dwarf.Entry{Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{{Attr: dwarf.AttrProducer, Val: "GNU C 4.2.4 (Ubuntu 4.2.4-1ubuntu4)"}, {Attr: dwarf.AttrLanguage, Val: int64(1)}, {Attr: dwarf.AttrName, Val: "go-relocation-test-gcc424.c"}, {Attr: dwarf.AttrCompDir, Val: "/tmp"}, {Attr: dwarf.AttrLowpc, Val: uint64(0x0)}, {Attr: dwarf.AttrHighpc, Val: uint64(0x6)}, {Attr: dwarf.AttrStmtList, Val: int64(0)}}}},
-		},
-	},
-	{
-		"testdata/go-relocation-test-clang-x86.obj",
-		[]relocationTestEntry{
-			{0, &dwarf.Entry{Offset: 0xb, Tag: dwarf.TagCompileUnit, Children: true, Field: []dwarf.Field{{Attr: dwarf.AttrProducer, Val: "clang version google3-trunk (trunk r209387)"}, {Attr: dwarf.AttrLanguage, Val: int64(12)}, {Attr: dwarf.AttrName, Val: "go-relocation-test-clang.c"}, {Attr: dwarf.AttrStmtList, Val: int64(0)}, {Attr: dwarf.AttrCompDir, Val: "/tmp"}}}},
-		},
-	},
-	{
-		"testdata/gcc-amd64-openbsd-debug-with-rela.obj",
-		[]relocationTestEntry{
-			{203, &dwarf.Entry{Offset: 0xc62, Tag: dwarf.TagMember, Children: false, Field: []dwarf.Field{{Attr: dwarf.AttrName, Val: "it_interval"}, {Attr: dwarf.AttrDeclFile, Val: int64(7)}, {Attr: dwarf.AttrDeclLine, Val: int64(236)}, {Attr: dwarf.AttrType, Val: dwarf.Offset(0xb7f)}, {Attr: dwarf.AttrDataMemberLoc, Val: []byte{0x23, 0x0}}}}},
-			{204, &dwarf.Entry{Offset: 0xc70, Tag: dwarf.TagMember, Children: false, Field: []dwarf.Field{{Attr: dwarf.AttrName, Val: "it_value"}, {Attr: dwarf.AttrDeclFile, Val: int64(7)}, {Attr: dwarf.AttrDeclLine, Val: int64(237)}, {Attr: dwarf.AttrType, Val: dwarf.Offset(0xb7f)}, {Attr: dwarf.AttrDataMemberLoc, Val: []byte{0x23, 0x10}}}}},
-		},
-	},
-}
-
-func TestDWARFRelocations(t *testing.T) {
-	for i, test := range relocationTests {
-		f, err := Open(test.file)
-		if err != nil {
-			t.Error(err)
-			continue
-		}
-		dwarf, err := f.DWARF()
-		if err != nil {
-			t.Error(err)
-			continue
-		}
-		for _, testEntry := range test.entries {
-			reader := dwarf.Reader()
-			for j := 0; j < testEntry.entryNumber; j++ {
-				entry, err := reader.Next()
-				if entry == nil || err != nil {
-					t.Errorf("Failed to skip to entry %d: %v", testEntry.entryNumber, err)
-					continue
-				}
-			}
-			entry, err := reader.Next()
-			if err != nil {
-				t.Error(err)
-				continue
-			}
-			if !reflect.DeepEqual(testEntry.entry, entry) {
-				t.Errorf("#%d/%d: mismatch: got:%#v want:%#v", i, testEntry.entryNumber, entry, testEntry.entry)
-				continue
-			}
-		}
-	}
-}
-
-func TestNoSectionOverlaps(t *testing.T) {
-	// Ensure 6l outputs sections without overlaps.
-	if runtime.GOOS != "linux" && runtime.GOOS != "freebsd" {
-		return // not ELF
-	}
-	_ = net.ResolveIPAddr // force dynamic linkage
-	f, err := Open(os.Args[0])
-	if err != nil {
-		t.Error(err)
-		return
-	}
-	for i, si := range f.Sections {
-		sih := si.SectionHeader
-		if sih.Type == SHT_NOBITS {
-			continue
-		}
-		for j, sj := range f.Sections {
-			sjh := sj.SectionHeader
-			if i == j || sjh.Type == SHT_NOBITS || sih.Offset == sjh.Offset && sih.Size == 0 {
-				continue
-			}
-			if sih.Offset >= sjh.Offset && sih.Offset < sjh.Offset+sjh.Size {
-				t.Errorf("ld produced ELF with section %s within %s: 0x%x <= 0x%x..0x%x < 0x%x",
-					sih.Name, sjh.Name, sjh.Offset, sih.Offset, sih.Offset+sih.Size, sjh.Offset+sjh.Size)
-			}
-		}
-	}
-}
diff --git a/src/pkg/debug/gosym/symtab.go b/src/pkg/debug/gosym/symtab.go
deleted file mode 100644
index 3864e3c..0000000
--- a/src/pkg/debug/gosym/symtab.go
+++ /dev/null
@@ -1,710 +0,0 @@
-// Copyright 2009 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package gosym implements access to the Go symbol
-// and line number tables embedded in Go binaries generated
-// by the gc compilers.
-package gosym
-
-// The table format is a variant of the format used in Plan 9's a.out
-// format, documented at http://plan9.bell-labs.com/magic/man2html/6/a.out.
-// The best reference for the differences between the Plan 9 format
-// and the Go format is the runtime source, specifically ../../runtime/symtab.c.
-
-import (
-	"bytes"
-	"encoding/binary"
-	"fmt"
-	"strconv"
-	"strings"
-)
-
-/*
- * Symbols
- */
-
-// A Sym represents a single symbol table entry.
-type Sym struct {
-	Value  uint64
-	Type   byte
-	Name   string
-	GoType uint64
-	// If this symbol if a function symbol, the corresponding Func
-	Func *Func
-}
-
-// Static reports whether this symbol is static (not visible outside its file).
-func (s *Sym) Static() bool { return s.Type >= 'a' }
-
-// PackageName returns the package part of the symbol name,
-// or the empty string if there is none.
-func (s *Sym) PackageName() string {
-	if i := strings.Index(s.Name, "."); i != -1 {
-		return s.Name[0:i]
-	}
-	return ""
-}
-
-// ReceiverName returns the receiver type name of this symbol,
-// or the empty string if there is none.
-func (s *Sym) ReceiverName() string {
-	l := strings.Index(s.Name, ".")
-	r := strings.LastIndex(s.Name, ".")
-	if l == -1 || r == -1 || l == r {
-		return ""
-	}
-	return s.Name[l+1 : r]
-}
-
-// BaseName returns the symbol name without the package or receiver name.
-func (s *Sym) BaseName() string {
-	if i := strings.LastIndex(s.Name, "."); i != -1 {
-		return s.Name[i+1:]
-	}
-	return s.Name
-}
-
-// A Func collects information about a single function.
-type Func struct {
-	Entry uint64
-	*Sym
-	End       uint64
-	Params    []*Sym
-	Locals    []*Sym
-	FrameSize int
-	LineTable *LineTable
-	Obj       *Obj
-}
-
-// An Obj represents a collection of functions in a symbol table.
-//
-// The exact method of division of a binary into separate Objs is an internal detail
-// of the symbol table format.
-//
-// In early versions of Go each source file became a different Obj.
-//
-// In Go 1 and Go 1.1, each package produced one Obj for all Go sources
-// and one Obj per C source file.
-//
-// In Go 1.2, there is a single Obj for the entire program.
-type Obj struct {
-	// Funcs is a list of functions in the Obj.
-	Funcs []Func
-
-	// In Go 1.1 and earlier, Paths is a list of symbols corresponding
-	// to the source file names that produced the Obj.
-	// In Go 1.2, Paths is nil.
-	// Use the keys of Table.Files to obtain a list of source files.
-	Paths []Sym // meta
-}
-
-/*
- * Symbol tables
- */
-
-// Table represents a Go symbol table.  It stores all of the
-// symbols decoded from the program and provides methods to translate
-// between symbols, names, and addresses.
-type Table struct {
-	Syms  []Sym
-	Funcs []Func
-	Files map[string]*Obj // nil for Go 1.2 and later binaries
-	Objs  []Obj           // nil for Go 1.2 and later binaries
-
-	go12line *LineTable // Go 1.2 line number table
-}
-
-type sym struct {
-	value  uint64
-	gotype uint64
-	typ    byte
-	name   []byte
-}
-
-var (
-	littleEndianSymtab    = []byte{0xFD, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00}
-	bigEndianSymtab       = []byte{0xFF, 0xFF, 0xFF, 0xFD, 0x00, 0x00, 0x00}
-	oldLittleEndianSymtab = []byte{0xFE, 0xFF, 0xFF, 0xFF, 0x00, 0x00}
-)
-
-func walksymtab(data []byte, fn func(sym) error) error {
-	if len(data) == 0 { // missing symtab is okay
-		return nil
-	}
-	var order binary.ByteOrder = binary.BigEndian
-	newTable := false
-	switch {
-	case bytes.HasPrefix(data, oldLittleEndianSymtab):
-		// Same as Go 1.0, but little endian.
-		// Format was used during interim development between Go 1.0 and Go 1.1.
-		// Should not be widespread, but easy to support.
-		data = data[6:]
-		order = binary.LittleEndian
-	case bytes.HasPrefix(data, bigEndianSymtab):
-		newTable = true
-	case bytes.HasPrefix(data, littleEndianSymtab):
-		newTable = true
-		order = binary.LittleEndian
-	}
-	var ptrsz int
-	if newTable {
-		if len(data) < 8 {
-			return &DecodingError{len(data), "unexpected EOF", nil}
-		}
-		ptrsz = int(data[7])
-		if ptrsz != 4 && ptrsz != 8 {
-			return &DecodingError{7, "invalid pointer size", ptrsz}
-		}
-		data = data[8:]
-	}
-	var s sym
-	p := data
-	for len(p) >= 4 {
-		var typ byte
-		if newTable {
-			// Symbol type, value, Go type.
-			typ = p[0] & 0x3F
-			wideValue := p[0]&0x40 != 0
-			goType := p[0]&0x80 != 0
-			if typ < 26 {
-				typ += 'A'
-			} else {
-				typ += 'a' - 26
-			}
-			s.typ = typ
-			p = p[1:]
-			if wideValue {
-				if len(p) < ptrsz {
-					return &DecodingError{len(data), "unexpected EOF", nil}
-				}
-				// fixed-width value
-				if ptrsz == 8 {
-					s.value = order.Uint64(p[0:8])
-					p = p[8:]
-				} else {
-					s.value = uint64(order.Uint32(p[0:4]))
-					p = p[4:]
-				}
-			} else {
-				// varint value
-				s.value = 0
-				shift := uint(0)
-				for len(p) > 0 && p[0]&0x80 != 0 {
-					s.value |= uint64(p[0]&0x7F) << shift
-					shift += 7
-					p = p[1:]
-				}
-				if len(p) == 0 {
-					return &DecodingError{len(data), "unexpected EOF", nil}
-				}
-				s.value |= uint64(p[0]) << shift
-				p = p[1:]
-			}
-			if goType {
-				if len(p) < ptrsz {
-					return &DecodingError{len(data), "unexpected EOF", nil}
-				}
-				// fixed-width go type
-				if ptrsz == 8 {
-					s.gotype = order.Uint64(p[0:8])
-					p = p[8:]
-				} else {
-					s.gotype = uint64(order.Uint32(p[0:4]))
-					p = p[4:]
-				}
-			}
-		} else {
-			// Value, symbol type.
-			s.value = uint64(order.Uint32(p[0:4]))
-			if len(p) < 5 {
-				return &DecodingError{len(data), "unexpected EOF", nil}
-			}
-			typ = p[4]
-			if typ&0x80 == 0 {
-				return &DecodingError{len(data) - len(p) + 4, "bad symbol type", typ}
-			}
-			typ &^= 0x80
-			s.typ = typ
-			p = p[5:]
-		}
-
-		// Name.
-		var i int
-		var nnul int
-		for i = 0; i < len(p); i++ {
-			if p[i] == 0 {
-				nnul = 1
-				break
-			}
-		}
-		switch typ {
-		case 'z', 'Z':
-			p = p[i+nnul:]
-			for i = 0; i+2 <= len(p); i += 2 {
-				if p[i] == 0 && p[i+1] == 0 {
-					nnul = 2
-					break
-				}
-			}
-		}
-		if len(p) < i+nnul {
-			return &DecodingError{len(data), "unexpected EOF", nil}
-		}
-		s.name = p[0:i]
-		i += nnul
-		p = p[i:]
-
-		if !newTable {
-			if len(p) < 4 {
-				return &DecodingError{len(data), "unexpected EOF", nil}
-			}
-			// Go type.
-			s.gotype = uint64(order.Uint32(p[:4]))
-			p = p[4:]
-		}
-		fn(s)
-	}
-	return nil
-}
-
-// NewTable decodes the Go symbol table in data,
-// returning an in-memory representation.
-func NewTable(symtab []byte, pcln *LineTable) (*Table, error) {
-	var n int
-	err := walksymtab(symtab, func(s sym) error {
-		n++
-		return nil
-	})
-	if err != nil {
-		return nil, err
-	}
-
-	var t Table
-	if pcln.isGo12() {
-		t.go12line = pcln
-	}
-	fname := make(map[uint16]string)
-	t.Syms = make([]Sym, 0, n)
-	nf := 0
-	nz := 0
-	lasttyp := uint8(0)
-	err = walksymtab(symtab, func(s sym) error {
-		n := len(t.Syms)
-		t.Syms = t.Syms[0 : n+1]
-		ts := &t.Syms[n]
-		ts.Type = s.typ
-		ts.Value = uint64(s.value)
-		ts.GoType = uint64(s.gotype)
-		switch s.typ {
-		default:
-			// rewrite name to use . instead of · (c2 b7)
-			w := 0
-			b := s.name
-			for i := 0; i < len(b); i++ {
-				if b[i] == 0xc2 && i+1 < len(b) && b[i+1] == 0xb7 {
-					i++
-					b[i] = '.'
-				}
-				b[w] = b[i]
-				w++
-			}
-			ts.Name = string(s.name[0:w])
-		case 'z', 'Z':
-			if lasttyp != 'z' && lasttyp != 'Z' {
-				nz++
-			}
-			for i := 0; i < len(s.name); i += 2 {
-				eltIdx := binary.BigEndian.Uint16(s.name[i : i+2])
-				elt, ok := fname[eltIdx]
-				if !ok {
-					return &DecodingError{-1, "bad filename code", eltIdx}
-				}
-				if n := len(ts.Name); n > 0 && ts.Name[n-1] != '/' {
-					ts.Name += "/"
-				}
-				ts.Name += elt
-			}
-		}
-		switch s.typ {
-		case 'T', 't', 'L', 'l':
-			nf++
-		case 'f':
-			fname[uint16(s.value)] = ts.Name
-		}
-		lasttyp = s.typ
-		return nil
-	})
-	if err != nil {
-		return nil, err
-	}
-
-	t.Funcs = make([]Func, 0, nf)
-	t.Files = make(map[string]*Obj)
-
-	var obj *Obj
-	if t.go12line != nil {
-		// Put all functions into one Obj.
-		t.Objs = make([]Obj, 1)
-		obj = &t.Objs[0]
-		t.go12line.go12MapFiles(t.Files, obj)
-	} else {
-		t.Objs = make([]Obj, 0, nz)
-	}
-
-	// Count text symbols and attach frame sizes, parameters, and
-	// locals to them.  Also, find object file boundaries.
-	lastf := 0
-	for i := 0; i < len(t.Syms); i++ {
-		sym := &t.Syms[i]
-		switch sym.Type {
-		case 'Z', 'z': // path symbol
-			if t.go12line != nil {
-				// Go 1.2 binaries have the file information elsewhere. Ignore.
-				break
-			}
-			// Finish the current object
-			if obj != nil {
-				obj.Funcs = t.Funcs[lastf:]
-			}
-			lastf = len(t.Funcs)
-
-			// Start new object
-			n := len(t.Objs)
-			t.Objs = t.Objs[0 : n+1]
-			obj = &t.Objs[n]
-
-			// Count & copy path symbols
-			var end int
-			for end = i + 1; end < len(t.Syms); end++ {
-				if c := t.Syms[end].Type; c != 'Z' && c != 'z' {
-					break
-				}
-			}
-			obj.Paths = t.Syms[i:end]
-			i = end - 1 // loop will i++
-
-			// Record file names
-			depth := 0
-			for j := range obj.Paths {
-				s := &obj.Paths[j]
-				if s.Name == "" {
-					depth--
-				} else {
-					if depth == 0 {
-						t.Files[s.Name] = obj
-					}
-					depth++
-				}
-			}
-
-		case 'T', 't', 'L', 'l': // text symbol
-			if n := len(t.Funcs); n > 0 {
-				t.Funcs[n-1].End = sym.Value
-			}
-			if sym.Name == "etext" {
-				continue
-			}
-
-			// Count parameter and local (auto) syms
-			var np, na int
-			var end int
-		countloop:
-			for end = i + 1; end < len(t.Syms); end++ {
-				switch t.Syms[end].Type {
-				case 'T', 't', 'L', 'l', 'Z', 'z':
-					break countloop
-				case 'p':
-					np++
-				case 'a':
-					na++
-				}
-			}
-
-			// Fill in the function symbol
-			n := len(t.Funcs)
-			t.Funcs = t.Funcs[0 : n+1]
-			fn := &t.Funcs[n]
-			sym.Func = fn
-			fn.Params = make([]*Sym, 0, np)
-			fn.Locals = make([]*Sym, 0, na)
-			fn.Sym = sym
-			fn.Entry = sym.Value
-			fn.Obj = obj
-			if t.go12line != nil {
-				// All functions share the same line table.
-				// It knows how to narrow down to a specific
-				// function quickly.
-				fn.LineTable = t.go12line
-			} else if pcln != nil {
-				fn.LineTable = pcln.slice(fn.Entry)
-				pcln = fn.LineTable
-			}
-			for j := i; j < end; j++ {
-				s := &t.Syms[j]
-				switch s.Type {
-				case 'm':
-					fn.FrameSize = int(s.Value)
-				case 'p':
-					n := len(fn.Params)
-					fn.Params = fn.Params[0 : n+1]
-					fn.Params[n] = s
-				case 'a':
-					n := len(fn.Locals)
-					fn.Locals = fn.Locals[0 : n+1]
-					fn.Locals[n] = s
-				}
-			}
-			i = end - 1 // loop will i++
-		}
-	}
-
-	if t.go12line != nil && nf == 0 {
-		t.Funcs = t.go12line.go12Funcs()
-	}
-	if obj != nil {
-		obj.Funcs = t.Funcs[lastf:]
-	}
-	return &t, nil
-}
-
-// PCToFunc returns the function containing the program counter pc,
-// or nil if there is no such function.
-func (t *Table) PCToFunc(pc uint64) *Func {
-	funcs := t.Funcs
-	for len(funcs) > 0 {
-		m := len(funcs) / 2
-		fn := &funcs[m]
-		switch {
-		case pc < fn.Entry:
-			funcs = funcs[0:m]
-		case fn.Entry <= pc && pc < fn.End:
-			return fn
-		default:
-			funcs = funcs[m+1:]
-		}
-	}
-	return nil
-}
-
-// PCToLine looks up line number information for a program counter.
-// If there is no information, it returns fn == nil.
-func (t *Table) PCToLine(pc uint64) (file string, line int, fn *Func) {
-	if fn = t.PCToFunc(pc); fn == nil {
-		return
-	}
-	if t.go12line != nil {
-		file = t.go12line.go12PCToFile(pc)
-		line = t.go12line.go12PCToLine(pc)
-	} else {
-		file, line = fn.Obj.lineFromAline(fn.LineTable.PCToLine(pc))
-	}
-	return
-}
-
-// LineToPC looks up the first program counter on the given line in
-// the named file.  It returns UnknownPathError or UnknownLineError if
-// there is an error looking up this line.
-func (t *Table) LineToPC(file string, line int) (pc uint64, fn *Func, err error) {
-	obj, ok := t.Files[file]
-	if !ok {
-		return 0, nil, UnknownFileError(file)
-	}
-
-	if t.go12line != nil {
-		pc := t.go12line.go12LineToPC(file, line)
-		if pc == 0 {
-			return 0, nil, &UnknownLineError{file, line}
-		}
-		return pc, t.PCToFunc(pc), nil
-	}
-
-	abs, err := obj.alineFromLine(file, line)
-	if err != nil {
-		return
-	}
-	for i := range obj.Funcs {
-		f := &obj.Funcs[i]
-		pc := f.LineTable.LineToPC(abs, f.End)
-		if pc != 0 {
-			return pc, f, nil
-		}
-	}
-	return 0, nil, &UnknownLineError{file, line}
-}
-
-// LookupSym returns the text, data, or bss symbol with the given name,
-// or nil if no such symbol is found.
-func (t *Table) LookupSym(name string) *Sym {
-	// TODO(austin) Maybe make a map
-	for i := range t.Syms {
-		s := &t.Syms[i]
-		switch s.Type {
-		case 'T', 't', 'L', 'l', 'D', 'd', 'B', 'b':
-			if s.Name == name {
-				return s
-			}
-		}
-	}
-	return nil
-}
-
-// LookupFunc returns the text, data, or bss symbol with the given name,
-// or nil if no such symbol is found.
-func (t *Table) LookupFunc(name string) *Func {
-	for i := range t.Funcs {
-		f := &t.Funcs[i]
-		if f.Sym.Name == name {
-			return f
-		}
-	}
-	return nil
-}
-
-// SymByAddr returns the text, data, or bss symbol starting at the given address.
-func (t *Table) SymByAddr(addr uint64) *Sym {
-	for i := range t.Syms {
-		s := &t.Syms[i]
-		switch s.Type {
-		case 'T', 't', 'L', 'l', 'D', 'd', 'B', 'b':
-			if s.Value == addr {
-				return s
-			}
-		}
-	}
-	return nil
-}
-
-/*
- * Object files
- */
-
-// This is legacy code for Go 1.1 and earlier, which used the
-// Plan 9 format for pc-line tables. This code was never quite
-// correct. It's probably very close, and it's usually correct, but
-// we never quite found all the corner cases.
-//
-// Go 1.2 and later use a simpler format, documented at golang.org/s/go12symtab.
-
-func (o *Obj) lineFromAline(aline int) (string, int) {
-	type stackEnt struct {
-		path   string
-		start  int
-		offset int
-		prev   *stackEnt
-	}
-
-	noPath := &stackEnt{"", 0, 0, nil}
-	tos := noPath
-
-pathloop:
-	for _, s := range o.Paths {
-		val := int(s.Value)
-		switch {
-		case val > aline:
-			break pathloop
-
-		case val == 1:
-			// Start a new stack
-			tos = &stackEnt{s.Name, val, 0, noPath}
-
-		case s.Name == "":
-			// Pop
-			if tos == noPath {
-				return "<malformed symbol table>", 0
-			}
-			tos.prev.offset += val - tos.start
-			tos = tos.prev
-
-		default:
-			// Push
-			tos = &stackEnt{s.Name, val, 0, tos}
-		}
-	}
-
-	if tos == noPath {
-		return "", 0
-	}
-	return tos.path, aline - tos.start - tos.offset + 1
-}
-
-func (o *Obj) alineFromLine(path string, line int) (int, error) {
-	if line < 1 {
-		return 0, &UnknownLineError{path, line}
-	}
-
-	for i, s := range o.Paths {
-		// Find this path
-		if s.Name != path {
-			continue
-		}
-
-		// Find this line at this stack level
-		depth := 0
-		var incstart int
-		line += int(s.Value)
-	pathloop:
-		for _, s := range o.Paths[i:] {
-			val := int(s.Value)
-			switch {
-			case depth == 1 && val >= line:
-				return line - 1, nil
-
-			case s.Name == "":
-				depth--
-				if depth == 0 {
-					break pathloop
-				} else if depth == 1 {
-					line += val - incstart
-				}
-
-			default:
-				if depth == 1 {
-					incstart = val
-				}
-				depth++
-			}
-		}
-		return 0, &UnknownLineError{path, line}
-	}
-	return 0, UnknownFileError(path)
-}
-
-/*
- * Errors
- */
-
-// UnknownFileError represents a failure to find the specific file in
-// the symbol table.
-type UnknownFileError string
-
-func (e UnknownFileError) Error() string { return "unknown file: " + string(e) }
-
-// UnknownLineError represents a failure to map a line to a program
-// counter, either because the line is beyond the bounds of the file
-// or because there is no code on the given line.
-type UnknownLineError struct {
-	File string
-	Line int
-}
-
-func (e *UnknownLineError) Error() string {
-	return "no code at " + e.File + ":" + strconv.Itoa(e.Line)
-}
-
-// DecodingError represents an error during the decoding of
-// the symbol table.
-type DecodingError struct {
-	off int
-	msg string
-	val interface{}
-}
-
-func (e *DecodingError) Error() string {
-	msg := e.msg
-	if e.val != nil {
-		msg += fmt.Sprintf(" '%v'", e.val)
-	}
-	msg += fmt.Sprintf(" at byte %#x", e.off)
-	return msg
-}
diff --git a/src/pkg/debug/pe/file.go b/src/pkg/debug/pe/file.go
deleted file mode 100644
index ce6f140..0000000
--- a/src/pkg/debug/pe/file.go
+++ /dev/null
@@ -1,390 +0,0 @@
-// Copyright 2009 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package pe implements access to PE (Microsoft Windows Portable Executable) files.
-package pe
-
-import (
-	"debug/dwarf"
-	"encoding/binary"
-	"errors"
-	"fmt"
-	"io"
-	"os"
-	"strconv"
-	"unsafe"
-)
-
-// A File represents an open PE file.
-type File struct {
-	FileHeader
-	OptionalHeader interface{} // of type *OptionalHeader32 or *OptionalHeader64
-	Sections       []*Section
-	Symbols        []*Symbol
-
-	closer io.Closer
-}
-
-type SectionHeader struct {
-	Name                 string
-	VirtualSize          uint32
-	VirtualAddress       uint32
-	Size                 uint32
-	Offset               uint32
-	PointerToRelocations uint32
-	PointerToLineNumbers uint32
-	NumberOfRelocations  uint16
-	NumberOfLineNumbers  uint16
-	Characteristics      uint32
-}
-
-type Section struct {
-	SectionHeader
-
-	// Embed ReaderAt for ReadAt method.
-	// Do not embed SectionReader directly
-	// to avoid having Read and Seek.
-	// If a client wants Read and Seek it must use
-	// Open() to avoid fighting over the seek offset
-	// with other clients.
-	io.ReaderAt
-	sr *io.SectionReader
-}
-
-type Symbol struct {
-	Name          string
-	Value         uint32
-	SectionNumber int16
-	Type          uint16
-	StorageClass  uint8
-}
-
-type ImportDirectory struct {
-	OriginalFirstThunk uint32
-	TimeDateStamp      uint32
-	ForwarderChain     uint32
-	Name               uint32
-	FirstThunk         uint32
-
-	dll string
-}
-
-// Data reads and returns the contents of the PE section.
-func (s *Section) Data() ([]byte, error) {
-	dat := make([]byte, s.sr.Size())
-	n, err := s.sr.ReadAt(dat, 0)
-	if n == len(dat) {
-		err = nil
-	}
-	return dat[0:n], err
-}
-
-// Open returns a new ReadSeeker reading the PE section.
-func (s *Section) Open() io.ReadSeeker { return io.NewSectionReader(s.sr, 0, 1<<63-1) }
-
-type FormatError struct {
-	off int64
-	msg string
-	val interface{}
-}
-
-func (e *FormatError) Error() string {
-	msg := e.msg
-	if e.val != nil {
-		msg += fmt.Sprintf(" '%v'", e.val)
-	}
-	msg += fmt.Sprintf(" in record at byte %#x", e.off)
-	return msg
-}
-
-// Open opens the named file using os.Open and prepares it for use as a PE binary.
-func Open(name string) (*File, error) {
-	f, err := os.Open(name)
-	if err != nil {
-		return nil, err
-	}
-	ff, err := NewFile(f)
-	if err != nil {
-		f.Close()
-		return nil, err
-	}
-	ff.closer = f
-	return ff, nil
-}
-
-// Close closes the File.
-// If the File was created using NewFile directly instead of Open,
-// Close has no effect.
-func (f *File) Close() error {
-	var err error
-	if f.closer != nil {
-		err = f.closer.Close()
-		f.closer = nil
-	}
-	return err
-}
-
-// NewFile creates a new File for accessing a PE binary in an underlying reader.
-func NewFile(r io.ReaderAt) (*File, error) {
-	f := new(File)
-	sr := io.NewSectionReader(r, 0, 1<<63-1)
-
-	var dosheader [96]byte
-	if _, err := r.ReadAt(dosheader[0:], 0); err != nil {
-		return nil, err
-	}
-	var base int64
-	if dosheader[0] == 'M' && dosheader[1] == 'Z' {
-		signoff := int64(binary.LittleEndian.Uint32(dosheader[0x3c:]))
-		var sign [4]byte
-		r.ReadAt(sign[:], signoff)
-		if !(sign[0] == 'P' && sign[1] == 'E' && sign[2] == 0 && sign[3] == 0) {
-			return nil, errors.New("Invalid PE File Format.")
-		}
-		base = signoff + 4
-	} else {
-		base = int64(0)
-	}
-	sr.Seek(base, os.SEEK_SET)
-	if err := binary.Read(sr, binary.LittleEndian, &f.FileHeader); err != nil {
-		return nil, err
-	}
-	if f.FileHeader.Machine != IMAGE_FILE_MACHINE_UNKNOWN && f.FileHeader.Machine != IMAGE_FILE_MACHINE_AMD64 && f.FileHeader.Machine != IMAGE_FILE_MACHINE_I386 {
-		return nil, errors.New("Invalid PE File Format.")
-	}
-
-	var ss []byte
-	if f.FileHeader.NumberOfSymbols > 0 {
-		// Get COFF string table, which is located at the end of the COFF symbol table.
-		sr.Seek(int64(f.FileHeader.PointerToSymbolTable+COFFSymbolSize*f.FileHeader.NumberOfSymbols), os.SEEK_SET)
-		var l uint32
-		if err := binary.Read(sr, binary.LittleEndian, &l); err != nil {
-			return nil, err
-		}
-		ss = make([]byte, l)
-		if _, err := r.ReadAt(ss, int64(f.FileHeader.PointerToSymbolTable+COFFSymbolSize*f.FileHeader.NumberOfSymbols)); err != nil {
-			return nil, err
-		}
-
-		// Process COFF symbol table.
-		sr.Seek(int64(f.FileHeader.PointerToSymbolTable), os.SEEK_SET)
-		aux := uint8(0)
-		for i := 0; i < int(f.FileHeader.NumberOfSymbols); i++ {
-			cs := new(COFFSymbol)
-			if err := binary.Read(sr, binary.LittleEndian, cs); err != nil {
-				return nil, err
-			}
-			if aux > 0 {
-				aux--
-				continue
-			}
-			var name string
-			if cs.Name[0] == 0 && cs.Name[1] == 0 && cs.Name[2] == 0 && cs.Name[3] == 0 {
-				si := int(binary.LittleEndian.Uint32(cs.Name[4:]))
-				name, _ = getString(ss, si)
-			} else {
-				name = cstring(cs.Name[:])
-			}
-			aux = cs.NumberOfAuxSymbols
-			s := &Symbol{
-				Name:          name,
-				Value:         cs.Value,
-				SectionNumber: cs.SectionNumber,
-				Type:          cs.Type,
-				StorageClass:  cs.StorageClass,
-			}
-			f.Symbols = append(f.Symbols, s)
-		}
-	}
-
-	// Read optional header.
-	sr.Seek(base, os.SEEK_SET)
-	if err := binary.Read(sr, binary.LittleEndian, &f.FileHeader); err != nil {
-		return nil, err
-	}
-	var oh32 OptionalHeader32
-	var oh64 OptionalHeader64
-	switch uintptr(f.FileHeader.SizeOfOptionalHeader) {
-	case unsafe.Sizeof(oh32):
-		if err := binary.Read(sr, binary.LittleEndian, &oh32); err != nil {
-			return nil, err
-		}
-		if oh32.Magic != 0x10b { // PE32
-			return nil, fmt.Errorf("pe32 optional header has unexpected Magic of 0x%x", oh32.Magic)
-		}
-		f.OptionalHeader = &oh32
-	case unsafe.Sizeof(oh64):
-		if err := binary.Read(sr, binary.LittleEndian, &oh64); err != nil {
-			return nil, err
-		}
-		if oh64.Magic != 0x20b { // PE32+
-			return nil, fmt.Errorf("pe32+ optional header has unexpected Magic of 0x%x", oh64.Magic)
-		}
-		f.OptionalHeader = &oh64
-	}
-
-	// Process sections.
-	f.Sections = make([]*Section, f.FileHeader.NumberOfSections)
-	for i := 0; i < int(f.FileHeader.NumberOfSections); i++ {
-		sh := new(SectionHeader32)
-		if err := binary.Read(sr, binary.LittleEndian, sh); err != nil {
-			return nil, err
-		}
-		var name string
-		if sh.Name[0] == '\x2F' {
-			si, _ := strconv.Atoi(cstring(sh.Name[1:]))
-			name, _ = getString(ss, si)
-		} else {
-			name = cstring(sh.Name[0:])
-		}
-		s := new(Section)
-		s.SectionHeader = SectionHeader{
-			Name:                 name,
-			VirtualSize:          sh.VirtualSize,
-			VirtualAddress:       sh.VirtualAddress,
-			Size:                 sh.SizeOfRawData,
-			Offset:               sh.PointerToRawData,
-			PointerToRelocations: sh.PointerToRelocations,
-			PointerToLineNumbers: sh.PointerToLineNumbers,
-			NumberOfRelocations:  sh.NumberOfRelocations,
-			NumberOfLineNumbers:  sh.NumberOfLineNumbers,
-			Characteristics:      sh.Characteristics,
-		}
-		s.sr = io.NewSectionReader(r, int64(s.SectionHeader.Offset), int64(s.SectionHeader.Size))
-		s.ReaderAt = s.sr
-		f.Sections[i] = s
-	}
-	return f, nil
-}
-
-func cstring(b []byte) string {
-	var i int
-	for i = 0; i < len(b) && b[i] != 0; i++ {
-	}
-	return string(b[0:i])
-}
-
-// getString extracts a string from symbol string table.
-func getString(section []byte, start int) (string, bool) {
-	if start < 0 || start >= len(section) {
-		return "", false
-	}
-
-	for end := start; end < len(section); end++ {
-		if section[end] == 0 {
-			return string(section[start:end]), true
-		}
-	}
-	return "", false
-}
-
-// Section returns the first section with the given name, or nil if no such
-// section exists.
-func (f *File) Section(name string) *Section {
-	for _, s := range f.Sections {
-		if s.Name == name {
-			return s
-		}
-	}
-	return nil
-}
-
-func (f *File) DWARF() (*dwarf.Data, error) {
-	// There are many other DWARF sections, but these
-	// are the required ones, and the debug/dwarf package
-	// does not use the others, so don't bother loading them.
-	var names = [...]string{"abbrev", "info", "str"}
-	var dat [len(names)][]byte
-	for i, name := range names {
-		name = ".debug_" + name
-		s := f.Section(name)
-		if s == nil {
-			continue
-		}
-		b, err := s.Data()
-		if err != nil && uint32(len(b)) < s.Size {
-			return nil, err
-		}
-		dat[i] = b
-	}
-
-	abbrev, info, str := dat[0], dat[1], dat[2]
-	return dwarf.New(abbrev, nil, nil, info, nil, nil, nil, str)
-}
-
-// ImportedSymbols returns the names of all symbols
-// referred to by the binary f that are expected to be
-// satisfied by other libraries at dynamic load time.
-// It does not return weak symbols.
-func (f *File) ImportedSymbols() ([]string, error) {
-	pe64 := f.Machine == IMAGE_FILE_MACHINE_AMD64
-	ds := f.Section(".idata")
-	if ds == nil {
-		// not dynamic, so no libraries
-		return nil, nil
-	}
-	d, err := ds.Data()
-	if err != nil {
-		return nil, err
-	}
-	var ida []ImportDirectory
-	for len(d) > 0 {
-		var dt ImportDirectory
-		dt.OriginalFirstThunk = binary.LittleEndian.Uint32(d[0:4])
-		dt.Name = binary.LittleEndian.Uint32(d[12:16])
-		dt.FirstThunk = binary.LittleEndian.Uint32(d[16:20])
-		d = d[20:]
-		if dt.OriginalFirstThunk == 0 {
-			break
-		}
-		ida = append(ida, dt)
-	}
-	names, _ := ds.Data()
-	var all []string
-	for _, dt := range ida {
-		dt.dll, _ = getString(names, int(dt.Name-ds.VirtualAddress))
-		d, _ = ds.Data()
-		// seek to OriginalFirstThunk
-		d = d[dt.OriginalFirstThunk-ds.VirtualAddress:]
-		for len(d) > 0 {
-			if pe64 { // 64bit
-				va := binary.LittleEndian.Uint64(d[0:8])
-				d = d[8:]
-				if va == 0 {
-					break
-				}
-				if va&0x8000000000000000 > 0 { // is Ordinal
-					// TODO add dynimport ordinal support.
-				} else {
-					fn, _ := getString(names, int(uint32(va)-ds.VirtualAddress+2))
-					all = append(all, fn+":"+dt.dll)
-				}
-			} else { // 32bit
-				va := binary.LittleEndian.Uint32(d[0:4])
-				d = d[4:]
-				if va == 0 {
-					break
-				}
-				if va&0x80000000 > 0 { // is Ordinal
-					// TODO add dynimport ordinal support.
-					//ord := va&0x0000FFFF
-				} else {
-					fn, _ := getString(names, int(va-ds.VirtualAddress+2))
-					all = append(all, fn+":"+dt.dll)
-				}
-			}
-		}
-	}
-
-	return all, nil
-}
-
-// ImportedLibraries returns the names of all libraries
-// referred to by the binary f that are expected to be
-// linked with the binary at dynamic link time.
-func (f *File) ImportedLibraries() ([]string, error) {
-	// TODO
-	// cgo -dynimport don't use this for windows PE, so just return.
-	return nil, nil
-}
diff --git a/src/pkg/debug/pe/file_test.go b/src/pkg/debug/pe/file_test.go
deleted file mode 100644
index ddbb271..0000000
--- a/src/pkg/debug/pe/file_test.go
+++ /dev/null
@@ -1,236 +0,0 @@
-// Copyright 2009 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package pe
-
-import (
-	"reflect"
-	"testing"
-)
-
-type fileTest struct {
-	file     string
-	hdr      FileHeader
-	opthdr   interface{}
-	sections []*SectionHeader
-	symbols  []*Symbol
-}
-
-var fileTests = []fileTest{
-	{
-		"testdata/gcc-386-mingw-obj",
-		FileHeader{0x014c, 0x000c, 0x0, 0x64a, 0x1e, 0x0, 0x104},
-		nil,
-		[]*SectionHeader{
-			{".text", 0, 0, 36, 500, 1440, 0, 3, 0, 0x60300020},
-			{".data", 0, 0, 0, 0, 0, 0, 0, 0, 3224371264},
-			{".bss", 0, 0, 0, 0, 0, 0, 0, 0, 3224371328},
-			{".debug_abbrev", 0, 0, 137, 536, 0, 0, 0, 0, 0x42100000},
-			{".debug_info", 0, 0, 418, 673, 1470, 0, 7, 0, 1108344832},
-			{".debug_line", 0, 0, 128, 1091, 1540, 0, 1, 0, 1108344832},
-			{".rdata", 0, 0, 16, 1219, 0, 0, 0, 0, 1076887616},
-			{".debug_frame", 0, 0, 52, 1235, 1550, 0, 2, 0, 1110441984},
-			{".debug_loc", 0, 0, 56, 1287, 0, 0, 0, 0, 1108344832},
-			{".debug_pubnames", 0, 0, 27, 1343, 1570, 0, 1, 0, 1108344832},
-			{".debug_pubtypes", 0, 0, 38, 1370, 1580, 0, 1, 0, 1108344832},
-			{".debug_aranges", 0, 0, 32, 1408, 1590, 0, 2, 0, 1108344832},
-		},
-		[]*Symbol{
-			{".file", 0x0, -2, 0x0, 0x67},
-			{"_main", 0x0, 1, 0x20, 0x2},
-			{".text", 0x0, 1, 0x0, 0x3},
-			{".data", 0x0, 2, 0x0, 0x3},
-			{".bss", 0x0, 3, 0x0, 0x3},
-			{".debug_abbrev", 0x0, 4, 0x0, 0x3},
-			{".debug_info", 0x0, 5, 0x0, 0x3},
-			{".debug_line", 0x0, 6, 0x0, 0x3},
-			{".rdata", 0x0, 7, 0x0, 0x3},
-			{".debug_frame", 0x0, 8, 0x0, 0x3},
-			{".debug_loc", 0x0, 9, 0x0, 0x3},
-			{".debug_pubnames", 0x0, 10, 0x0, 0x3},
-			{".debug_pubtypes", 0x0, 11, 0x0, 0x3},
-			{".debug_aranges", 0x0, 12, 0x0, 0x3},
-			{"___main", 0x0, 0, 0x20, 0x2},
-			{"_puts", 0x0, 0, 0x20, 0x2},
-		},
-	},
-	{
-		"testdata/gcc-386-mingw-exec",
-		FileHeader{0x014c, 0x000f, 0x4c6a1b60, 0x3c00, 0x282, 0xe0, 0x107},
-		&OptionalHeader32{
-			0x10b, 0x2, 0x38, 0xe00, 0x1a00, 0x200, 0x1160, 0x1000, 0x2000, 0x400000, 0x1000, 0x200, 0x4, 0x0, 0x1, 0x0, 0x4, 0x0, 0x0, 0x10000, 0x400, 0x14abb, 0x3, 0x0, 0x200000, 0x1000, 0x100000, 0x1000, 0x0, 0x10,
-			[16]DataDirectory{
-				{0x0, 0x0},
-				{0x5000, 0x3c8},
-				{0x0, 0x0},
-				{0x0, 0x0},
-				{0x0, 0x0},
-				{0x0, 0x0},
-				{0x0, 0x0},
-				{0x0, 0x0},
-				{0x0, 0x0},
-				{0x7000, 0x18},
-				{0x0, 0x0},
-				{0x0, 0x0},
-				{0x0, 0x0},
-				{0x0, 0x0},
-				{0x0, 0x0},
-				{0x0, 0x0},
-			},
-		},
-		[]*SectionHeader{
-			{".text", 0xcd8, 0x1000, 0xe00, 0x400, 0x0, 0x0, 0x0, 0x0, 0x60500060},
-			{".data", 0x10, 0x2000, 0x200, 0x1200, 0x0, 0x0, 0x0, 0x0, 0xc0300040},
-			{".rdata", 0x120, 0x3000, 0x200, 0x1400, 0x0, 0x0, 0x0, 0x0, 0x40300040},
-			{".bss", 0xdc, 0x4000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0400080},
-			{".idata", 0x3c8, 0x5000, 0x400, 0x1600, 0x0, 0x0, 0x0, 0x0, 0xc0300040},
-			{".CRT", 0x18, 0x6000, 0x200, 0x1a00, 0x0, 0x0, 0x0, 0x0, 0xc0300040},
-			{".tls", 0x20, 0x7000, 0x200, 0x1c00, 0x0, 0x0, 0x0, 0x0, 0xc0300040},
-			{".debug_aranges", 0x20, 0x8000, 0x200, 0x1e00, 0x0, 0x0, 0x0, 0x0, 0x42100000},
-			{".debug_pubnames", 0x51, 0x9000, 0x200, 0x2000, 0x0, 0x0, 0x0, 0x0, 0x42100000},
-			{".debug_pubtypes", 0x91, 0xa000, 0x200, 0x2200, 0x0, 0x0, 0x0, 0x0, 0x42100000},
-			{".debug_info", 0xe22, 0xb000, 0x1000, 0x2400, 0x0, 0x0, 0x0, 0x0, 0x42100000},
-			{".debug_abbrev", 0x157, 0xc000, 0x200, 0x3400, 0x0, 0x0, 0x0, 0x0, 0x42100000},
-			{".debug_line", 0x144, 0xd000, 0x200, 0x3600, 0x0, 0x0, 0x0, 0x0, 0x42100000},
-			{".debug_frame", 0x34, 0xe000, 0x200, 0x3800, 0x0, 0x0, 0x0, 0x0, 0x42300000},
-			{".debug_loc", 0x38, 0xf000, 0x200, 0x3a00, 0x0, 0x0, 0x0, 0x0, 0x42100000},
-		},
-		[]*Symbol{},
-	},
-	{
-		"testdata/gcc-amd64-mingw-obj",
-		FileHeader{0x8664, 0x6, 0x0, 0x198, 0x12, 0x0, 0x4},
-		nil,
-		[]*SectionHeader{
-			{".text", 0x0, 0x0, 0x30, 0x104, 0x15c, 0x0, 0x3, 0x0, 0x60500020},
-			{".data", 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0500040},
-			{".bss", 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0500080},
-			{".rdata", 0x0, 0x0, 0x10, 0x134, 0x0, 0x0, 0x0, 0x0, 0x40500040},
-			{".xdata", 0x0, 0x0, 0xc, 0x144, 0x0, 0x0, 0x0, 0x0, 0x40300040},
-			{".pdata", 0x0, 0x0, 0xc, 0x150, 0x17a, 0x0, 0x3, 0x0, 0x40300040},
-		},
-		[]*Symbol{
-			{".file", 0x0, -2, 0x0, 0x67},
-			{"main", 0x0, 1, 0x20, 0x2},
-			{".text", 0x0, 1, 0x0, 0x3},
-			{".data", 0x0, 2, 0x0, 0x3},
-			{".bss", 0x0, 3, 0x0, 0x3},
-			{".rdata", 0x0, 4, 0x0, 0x3},
-			{".xdata", 0x0, 5, 0x0, 0x3},
-			{".pdata", 0x0, 6, 0x0, 0x3},
-			{"__main", 0x0, 0, 0x20, 0x2},
-			{"puts", 0x0, 0, 0x20, 0x2},
-		},
-	},
-	{
-		"testdata/gcc-amd64-mingw-exec",
-		FileHeader{0x8664, 0x9, 0x53472993, 0x0, 0x0, 0xf0, 0x22f},
-		&OptionalHeader64{
-			0x20b, 0x2, 0x16, 0x6a00, 0x2400, 0x1600, 0x14e0, 0x1000, 0x400000, 0x1000, 0x200, 0x4, 0x0, 0x0, 0x0, 0x5, 0x2, 0x0, 0x11000, 0x400, 0x1841e, 0x3, 0x0, 0x200000, 0x1000, 0x100000, 0x1000, 0x0, 0x10,
-			[16]DataDirectory{
-				{0x0, 0x0},
-				{0xe000, 0x990},
-				{0x0, 0x0},
-				{0xa000, 0x498},
-				{0x0, 0x0},
-				{0x0, 0x0},
-				{0x0, 0x0},
-				{0x0, 0x0},
-				{0x0, 0x0},
-				{0x10000, 0x28},
-				{0x0, 0x0},
-				{0x0, 0x0},
-				{0xe254, 0x218},
-				{0x0, 0x0},
-				{0x0, 0x0},
-				{0x0, 0x0},
-			},
-		},
-		[]*SectionHeader{
-			{".text", 0x6860, 0x1000, 0x6a00, 0x400, 0x0, 0x0, 0x0, 0x0, 0x60500020},
-			{".data", 0xe0, 0x8000, 0x200, 0x6e00, 0x0, 0x0, 0x0, 0x0, 0xc0500040},
-			{".rdata", 0x6b0, 0x9000, 0x800, 0x7000, 0x0, 0x0, 0x0, 0x0, 0x40600040},
-			{".pdata", 0x498, 0xa000, 0x600, 0x7800, 0x0, 0x0, 0x0, 0x0, 0x40300040},
-			{".xdata", 0x488, 0xb000, 0x600, 0x7e00, 0x0, 0x0, 0x0, 0x0, 0x40300040},
-			{".bss", 0x1410, 0xc000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0600080},
-			{".idata", 0x990, 0xe000, 0xa00, 0x8400, 0x0, 0x0, 0x0, 0x0, 0xc0300040},
-			{".CRT", 0x68, 0xf000, 0x200, 0x8e00, 0x0, 0x0, 0x0, 0x0, 0xc0400040},
-			{".tls", 0x48, 0x10000, 0x200, 0x9000, 0x0, 0x0, 0x0, 0x0, 0xc0600040},
-		},
-		[]*Symbol{},
-	},
-}
-
-func isOptHdrEq(a, b interface{}) bool {
-	switch va := a.(type) {
-	case *OptionalHeader32:
-		vb, ok := b.(*OptionalHeader32)
-		if !ok {
-			return false
-		}
-		return *vb == *va
-	case *OptionalHeader64:
-		vb, ok := b.(*OptionalHeader64)
-		if !ok {
-			return false
-		}
-		return *vb == *va
-	case nil:
-		return b == nil
-	}
-	return false
-}
-
-func TestOpen(t *testing.T) {
-	for i := range fileTests {
-		tt := &fileTests[i]
-
-		f, err := Open(tt.file)
-		if err != nil {
-			t.Error(err)
-			continue
-		}
-		if !reflect.DeepEqual(f.FileHeader, tt.hdr) {
-			t.Errorf("open %s:\n\thave %#v\n\twant %#v\n", tt.file, f.FileHeader, tt.hdr)
-			continue
-		}
-		if !isOptHdrEq(tt.opthdr, f.OptionalHeader) {
-			t.Errorf("open %s:\n\thave %#v\n\twant %#v\n", tt.file, f.OptionalHeader, tt.opthdr)
-			continue
-		}
-
-		for i, sh := range f.Sections {
-			if i >= len(tt.sections) {
-				break
-			}
-			have := &sh.SectionHeader
-			want := tt.sections[i]
-			if !reflect.DeepEqual(have, want) {
-				t.Errorf("open %s, section %d:\n\thave %#v\n\twant %#v\n", tt.file, i, have, want)
-			}
-		}
-		tn := len(tt.sections)
-		fn := len(f.Sections)
-		if tn != fn {
-			t.Errorf("open %s: len(Sections) = %d, want %d", tt.file, fn, tn)
-		}
-		for i, have := range f.Symbols {
-			if i >= len(tt.symbols) {
-				break
-			}
-			want := tt.symbols[i]
-			if !reflect.DeepEqual(have, want) {
-				t.Errorf("open %s, symbol %d:\n\thave %#v\n\twant %#v\n", tt.file, i, have, want)
-			}
-		}
-	}
-}
-
-func TestOpenFailure(t *testing.T) {
-	filename := "file.go"    // not a PE file
-	_, err := Open(filename) // don't crash
-	if err == nil {
-		t.Errorf("open %s: succeeded unexpectedly", filename)
-	}
-}
diff --git a/src/pkg/debug/pe/testdata/gcc-amd64-mingw-exec b/src/pkg/debug/pe/testdata/gcc-amd64-mingw-exec
deleted file mode 100644
index 78d4e5f..0000000
Binary files a/src/pkg/debug/pe/testdata/gcc-amd64-mingw-exec and /dev/null differ
diff --git a/src/pkg/debug/plan9obj/file.go b/src/pkg/debug/plan9obj/file.go
deleted file mode 100644
index 60a5857..0000000
--- a/src/pkg/debug/plan9obj/file.go
+++ /dev/null
@@ -1,325 +0,0 @@
-// Copyright 2014 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package plan9obj implements access to Plan 9 a.out object files.
-package plan9obj
-
-import (
-	"encoding/binary"
-	"errors"
-	"fmt"
-	"io"
-	"os"
-)
-
-// A FileHeader represents a Plan 9 a.out file header.
-type FileHeader struct {
-	Magic   uint32
-	Bss     uint32
-	Entry   uint64
-	PtrSize int
-}
-
-// A File represents an open Plan 9 a.out file.
-type File struct {
-	FileHeader
-	Sections []*Section
-	closer   io.Closer
-}
-
-// A SectionHeader represents a single Plan 9 a.out section header.
-// This structure doesn't exist on-disk, but eases navigation
-// through the object file.
-type SectionHeader struct {
-	Name   string
-	Size   uint32
-	Offset uint32
-}
-
-// A Section represents a single section in a Plan 9 a.out file.
-type Section struct {
-	SectionHeader
-
-	// Embed ReaderAt for ReadAt method.
-	// Do not embed SectionReader directly
-	// to avoid having Read and Seek.
-	// If a client wants Read and Seek it must use
-	// Open() to avoid fighting over the seek offset
-	// with other clients.
-	io.ReaderAt
-	sr *io.SectionReader
-}
-
-// Data reads and returns the contents of the Plan 9 a.out section.
-func (s *Section) Data() ([]byte, error) {
-	dat := make([]byte, s.sr.Size())
-	n, err := s.sr.ReadAt(dat, 0)
-	if n == len(dat) {
-		err = nil
-	}
-	return dat[0:n], err
-}
-
-// Open returns a new ReadSeeker reading the Plan 9 a.out section.
-func (s *Section) Open() io.ReadSeeker { return io.NewSectionReader(s.sr, 0, 1<<63-1) }
-
-// A Symbol represents an entry in a Plan 9 a.out symbol table section.
-type Sym struct {
-	Value uint64
-	Type  rune
-	Name  string
-}
-
-/*
- * Plan 9 a.out reader
- */
-
-// formatError is returned by some operations if the data does
-// not have the correct format for an object file.
-type formatError struct {
-	off int
-	msg string
-	val interface{}
-}
-
-func (e *formatError) Error() string {
-	msg := e.msg
-	if e.val != nil {
-		msg += fmt.Sprintf(" '%v'", e.val)
-	}
-	msg += fmt.Sprintf(" in record at byte %#x", e.off)
-	return msg
-}
-
-// Open opens the named file using os.Open and prepares it for use as a Plan 9 a.out binary.
-func Open(name string) (*File, error) {
-	f, err := os.Open(name)
-	if err != nil {
-		return nil, err
-	}
-	ff, err := NewFile(f)
-	if err != nil {
-		f.Close()
-		return nil, err
-	}
-	ff.closer = f
-	return ff, nil
-}
-
-// Close closes the File.
-// If the File was created using NewFile directly instead of Open,
-// Close has no effect.
-func (f *File) Close() error {
-	var err error
-	if f.closer != nil {
-		err = f.closer.Close()
-		f.closer = nil
-	}
-	return err
-}
-
-func parseMagic(magic []byte) (uint32, error) {
-	m := binary.BigEndian.Uint32(magic)
-	switch m {
-	case Magic386, MagicAMD64, MagicARM:
-		return m, nil
-	}
-	return 0, &formatError{0, "bad magic number", magic}
-}
-
-// NewFile creates a new File for accessing a Plan 9 binary in an underlying reader.
-// The Plan 9 binary is expected to start at position 0 in the ReaderAt.
-func NewFile(r io.ReaderAt) (*File, error) {
-	sr := io.NewSectionReader(r, 0, 1<<63-1)
-	// Read and decode Plan 9 magic
-	var magic [4]byte
-	if _, err := r.ReadAt(magic[:], 0); err != nil {
-		return nil, err
-	}
-	_, err := parseMagic(magic[:])
-	if err != nil {
-		return nil, err
-	}
-
-	ph := new(prog)
-	if err := binary.Read(sr, binary.BigEndian, ph); err != nil {
-		return nil, err
-	}
-
-	f := &File{FileHeader: FileHeader{
-		Magic:   ph.Magic,
-		Bss:     ph.Bss,
-		Entry:   uint64(ph.Entry),
-		PtrSize: 4,
-	}}
-
-	hdrSize := 4 * 8
-
-	if ph.Magic&Magic64 != 0 {
-		if err := binary.Read(sr, binary.BigEndian, &f.Entry); err != nil {
-			return nil, err
-		}
-		f.PtrSize = 8
-		hdrSize += 8
-	}
-
-	var sects = []struct {
-		name string
-		size uint32
-	}{
-		{"text", ph.Text},
-		{"data", ph.Data},
-		{"syms", ph.Syms},
-		{"spsz", ph.Spsz},
-		{"pcsz", ph.Pcsz},
-	}
-
-	f.Sections = make([]*Section, 5)
-
-	off := uint32(hdrSize)
-
-	for i, sect := range sects {
-		s := new(Section)
-		s.SectionHeader = SectionHeader{
-			Name:   sect.name,
-			Size:   sect.size,
-			Offset: off,
-		}
-		off += sect.size
-		s.sr = io.NewSectionReader(r, int64(s.Offset), int64(s.Size))
-		s.ReaderAt = s.sr
-		f.Sections[i] = s
-	}
-
-	return f, nil
-}
-
-func walksymtab(data []byte, ptrsz int, fn func(sym) error) error {
-	var order binary.ByteOrder = binary.BigEndian
-	var s sym
-	p := data
-	for len(p) >= 4 {
-		// Symbol type, value.
-		if len(p) < ptrsz {
-			return &formatError{len(data), "unexpected EOF", nil}
-		}
-		// fixed-width value
-		if ptrsz == 8 {
-			s.value = order.Uint64(p[0:8])
-			p = p[8:]
-		} else {
-			s.value = uint64(order.Uint32(p[0:4]))
-			p = p[4:]
-		}
-
-		var typ byte
-		typ = p[0] & 0x7F
-		s.typ = typ
-		p = p[1:]
-
-		// Name.
-		var i int
-		var nnul int
-		for i = 0; i < len(p); i++ {
-			if p[i] == 0 {
-				nnul = 1
-				break
-			}
-		}
-		switch typ {
-		case 'z', 'Z':
-			p = p[i+nnul:]
-			for i = 0; i+2 <= len(p); i += 2 {
-				if p[i] == 0 && p[i+1] == 0 {
-					nnul = 2
-					break
-				}
-			}
-		}
-		if len(p) < i+nnul {
-			return &formatError{len(data), "unexpected EOF", nil}
-		}
-		s.name = p[0:i]
-		i += nnul
-		p = p[i:]
-
-		fn(s)
-	}
-	return nil
-}
-
-// NewTable decodes the Go symbol table in data,
-// returning an in-memory representation.
-func newTable(symtab []byte, ptrsz int) ([]Sym, error) {
-	var n int
-	err := walksymtab(symtab, ptrsz, func(s sym) error {
-		n++
-		return nil
-	})
-	if err != nil {
-		return nil, err
-	}
-
-	fname := make(map[uint16]string)
-	syms := make([]Sym, 0, n)
-	err = walksymtab(symtab, ptrsz, func(s sym) error {
-		n := len(syms)
-		syms = syms[0 : n+1]
-		ts := &syms[n]
-		ts.Type = rune(s.typ)
-		ts.Value = s.value
-		switch s.typ {
-		default:
-			ts.Name = string(s.name[:])
-		case 'z', 'Z':
-			for i := 0; i < len(s.name); i += 2 {
-				eltIdx := binary.BigEndian.Uint16(s.name[i : i+2])
-				elt, ok := fname[eltIdx]
-				if !ok {
-					return &formatError{-1, "bad filename code", eltIdx}
-				}
-				if n := len(ts.Name); n > 0 && ts.Name[n-1] != '/' {
-					ts.Name += "/"
-				}
-				ts.Name += elt
-			}
-		}
-		switch s.typ {
-		case 'f':
-			fname[uint16(s.value)] = ts.Name
-		}
-		return nil
-	})
-	if err != nil {
-		return nil, err
-	}
-
-	return syms, nil
-}
-
-// Symbols returns the symbol table for f.
-func (f *File) Symbols() ([]Sym, error) {
-	symtabSection := f.Section("syms")
-	if symtabSection == nil {
-		return nil, errors.New("no symbol section")
-	}
-
-	symtab, err := symtabSection.Data()
-	if err != nil {
-		return nil, errors.New("cannot load symbol section")
-	}
-
-	return newTable(symtab, f.PtrSize)
-}
-
-// Section returns a section with the given name, or nil if no such
-// section exists.
-func (f *File) Section(name string) *Section {
-	for _, s := range f.Sections {
-		if s.Name == name {
-			return s
-		}
-	}
-	return nil
-}
diff --git a/src/pkg/debug/plan9obj/file_test.go b/src/pkg/debug/plan9obj/file_test.go
deleted file mode 100644
index 96186d8..0000000
--- a/src/pkg/debug/plan9obj/file_test.go
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright 2014 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package plan9obj
-
-import (
-	"reflect"
-	"testing"
-)
-
-type fileTest struct {
-	file     string
-	hdr      FileHeader
-	sections []*SectionHeader
-}
-
-var fileTests = []fileTest{
-	{
-		"testdata/386-plan9-exec",
-		FileHeader{Magic386, 0x324, 0x14, 4},
-		[]*SectionHeader{
-			{"text", 0x4c5f, 0x20},
-			{"data", 0x94c, 0x4c7f},
-			{"syms", 0x2c2b, 0x55cb},
-			{"spsz", 0x0, 0x81f6},
-			{"pcsz", 0xf7a, 0x81f6},
-		},
-	},
-	{
-		"testdata/amd64-plan9-exec",
-		FileHeader{MagicAMD64, 0x618, 0x13, 8},
-		[]*SectionHeader{
-			{"text", 0x4213, 0x28},
-			{"data", 0xa80, 0x423b},
-			{"syms", 0x2c8c, 0x4cbb},
-			{"spsz", 0x0, 0x7947},
-			{"pcsz", 0xca0, 0x7947},
-		},
-	},
-}
-
-func TestOpen(t *testing.T) {
-	for i := range fileTests {
-		tt := &fileTests[i]
-
-		f, err := Open(tt.file)
-		if err != nil {
-			t.Error(err)
-			continue
-		}
-		if !reflect.DeepEqual(f.FileHeader, tt.hdr) {
-			t.Errorf("open %s:\n\thave %#v\n\twant %#v\n", tt.file, f.FileHeader, tt.hdr)
-			continue
-		}
-
-		for i, sh := range f.Sections {
-			if i >= len(tt.sections) {
-				break
-			}
-			have := &sh.SectionHeader
-			want := tt.sections[i]
-			if !reflect.DeepEqual(have, want) {
-				t.Errorf("open %s, section %d:\n\thave %#v\n\twant %#v\n", tt.file, i, have, want)
-			}
-		}
-		tn := len(tt.sections)
-		fn := len(f.Sections)
-		if tn != fn {
-			t.Errorf("open %s: len(Sections) = %d, want %d", tt.file, fn, tn)
-		}
-	}
-}
-
-func TestOpenFailure(t *testing.T) {
-	filename := "file.go"    // not a Plan 9 a.out file
-	_, err := Open(filename) // don't crash
-	if err == nil {
-		t.Errorf("open %s: succeeded unexpectedly", filename)
-	}
-}
diff --git a/src/pkg/encoding/ascii85/ascii85.go b/src/pkg/encoding/ascii85/ascii85.go
deleted file mode 100644
index 60da304..0000000
--- a/src/pkg/encoding/ascii85/ascii85.go
+++ /dev/null
@@ -1,311 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package ascii85 implements the ascii85 data encoding
-// as used in the btoa tool and Adobe's PostScript and PDF document formats.
-package ascii85
-
-import (
-	"io"
-	"strconv"
-)
-
-/*
- * Encoder
- */
-
-// Encode encodes src into at most MaxEncodedLen(len(src))
-// bytes of dst, returning the actual number of bytes written.
-//
-// The encoding handles 4-byte chunks, using a special encoding
-// for the last fragment, so Encode is not appropriate for use on
-// individual blocks of a large data stream.  Use NewEncoder() instead.
-//
-// Often, ascii85-encoded data is wrapped in <~ and ~> symbols.
-// Encode does not add these.
-func Encode(dst, src []byte) int {
-	if len(src) == 0 {
-		return 0
-	}
-
-	n := 0
-	for len(src) > 0 {
-		dst[0] = 0
-		dst[1] = 0
-		dst[2] = 0
-		dst[3] = 0
-		dst[4] = 0
-
-		// Unpack 4 bytes into uint32 to repack into base 85 5-byte.
-		var v uint32
-		switch len(src) {
-		default:
-			v |= uint32(src[3])
-			fallthrough
-		case 3:
-			v |= uint32(src[2]) << 8
-			fallthrough
-		case 2:
-			v |= uint32(src[1]) << 16
-			fallthrough
-		case 1:
-			v |= uint32(src[0]) << 24
-		}
-
-		// Special case: zero (!!!!!) shortens to z.
-		if v == 0 && len(src) >= 4 {
-			dst[0] = 'z'
-			dst = dst[1:]
-			src = src[4:]
-			n++
-			continue
-		}
-
-		// Otherwise, 5 base 85 digits starting at !.
-		for i := 4; i >= 0; i-- {
-			dst[i] = '!' + byte(v%85)
-			v /= 85
-		}
-
-		// If src was short, discard the low destination bytes.
-		m := 5
-		if len(src) < 4 {
-			m -= 4 - len(src)
-			src = nil
-		} else {
-			src = src[4:]
-		}
-		dst = dst[m:]
-		n += m
-	}
-	return n
-}
-
-// MaxEncodedLen returns the maximum length of an encoding of n source bytes.
-func MaxEncodedLen(n int) int { return (n + 3) / 4 * 5 }
-
-// NewEncoder returns a new ascii85 stream encoder.  Data written to
-// the returned writer will be encoded and then written to w.
-// Ascii85 encodings operate in 32-bit blocks; when finished
-// writing, the caller must Close the returned encoder to flush any
-// trailing partial block.
-func NewEncoder(w io.Writer) io.WriteCloser { return &encoder{w: w} }
-
-type encoder struct {
-	err  error
-	w    io.Writer
-	buf  [4]byte    // buffered data waiting to be encoded
-	nbuf int        // number of bytes in buf
-	out  [1024]byte // output buffer
-}
-
-func (e *encoder) Write(p []byte) (n int, err error) {
-	if e.err != nil {
-		return 0, e.err
-	}
-
-	// Leading fringe.
-	if e.nbuf > 0 {
-		var i int
-		for i = 0; i < len(p) && e.nbuf < 4; i++ {
-			e.buf[e.nbuf] = p[i]
-			e.nbuf++
-		}
-		n += i
-		p = p[i:]
-		if e.nbuf < 4 {
-			return
-		}
-		nout := Encode(e.out[0:], e.buf[0:])
-		if _, e.err = e.w.Write(e.out[0:nout]); e.err != nil {
-			return n, e.err
-		}
-		e.nbuf = 0
-	}
-
-	// Large interior chunks.
-	for len(p) >= 4 {
-		nn := len(e.out) / 5 * 4
-		if nn > len(p) {
-			nn = len(p)
-		}
-		nn -= nn % 4
-		if nn > 0 {
-			nout := Encode(e.out[0:], p[0:nn])
-			if _, e.err = e.w.Write(e.out[0:nout]); e.err != nil {
-				return n, e.err
-			}
-		}
-		n += nn
-		p = p[nn:]
-	}
-
-	// Trailing fringe.
-	for i := 0; i < len(p); i++ {
-		e.buf[i] = p[i]
-	}
-	e.nbuf = len(p)
-	n += len(p)
-	return
-}
-
-// Close flushes any pending output from the encoder.
-// It is an error to call Write after calling Close.
-func (e *encoder) Close() error {
-	// If there's anything left in the buffer, flush it out
-	if e.err == nil && e.nbuf > 0 {
-		nout := Encode(e.out[0:], e.buf[0:e.nbuf])
-		e.nbuf = 0
-		_, e.err = e.w.Write(e.out[0:nout])
-	}
-	return e.err
-}
-
-/*
- * Decoder
- */
-
-type CorruptInputError int64
-
-func (e CorruptInputError) Error() string {
-	return "illegal ascii85 data at input byte " + strconv.FormatInt(int64(e), 10)
-}
-
-// Decode decodes src into dst, returning both the number
-// of bytes written to dst and the number consumed from src.
-// If src contains invalid ascii85 data, Decode will return the
-// number of bytes successfully written and a CorruptInputError.
-// Decode ignores space and control characters in src.
-// Often, ascii85-encoded data is wrapped in <~ and ~> symbols.
-// Decode expects these to have been stripped by the caller.
-//
-// If flush is true, Decode assumes that src represents the
-// end of the input stream and processes it completely rather
-// than wait for the completion of another 32-bit block.
-//
-// NewDecoder wraps an io.Reader interface around Decode.
-//
-func Decode(dst, src []byte, flush bool) (ndst, nsrc int, err error) {
-	var v uint32
-	var nb int
-	for i, b := range src {
-		if len(dst)-ndst < 4 {
-			return
-		}
-		switch {
-		case b <= ' ':
-			continue
-		case b == 'z' && nb == 0:
-			nb = 5
-			v = 0
-		case '!' <= b && b <= 'u':
-			v = v*85 + uint32(b-'!')
-			nb++
-		default:
-			return 0, 0, CorruptInputError(i)
-		}
-		if nb == 5 {
-			nsrc = i + 1
-			dst[ndst] = byte(v >> 24)
-			dst[ndst+1] = byte(v >> 16)
-			dst[ndst+2] = byte(v >> 8)
-			dst[ndst+3] = byte(v)
-			ndst += 4
-			nb = 0
-			v = 0
-		}
-	}
-	if flush {
-		nsrc = len(src)
-		if nb > 0 {
-			// The number of output bytes in the last fragment
-			// is the number of leftover input bytes - 1:
-			// the extra byte provides enough bits to cover
-			// the inefficiency of the encoding for the block.
-			if nb == 1 {
-				return 0, 0, CorruptInputError(len(src))
-			}
-			for i := nb; i < 5; i++ {
-				// The short encoding truncated the output value.
-				// We have to assume the worst case values (digit 84)
-				// in order to ensure that the top bits are correct.
-				v = v*85 + 84
-			}
-			for i := 0; i < nb-1; i++ {
-				dst[ndst] = byte(v >> 24)
-				v <<= 8
-				ndst++
-			}
-		}
-	}
-	return
-}
-
-// NewDecoder constructs a new ascii85 stream decoder.
-func NewDecoder(r io.Reader) io.Reader { return &decoder{r: r} }
-
-type decoder struct {
-	err     error
-	readErr error
-	r       io.Reader
-	end     bool       // saw end of message
-	buf     [1024]byte // leftover input
-	nbuf    int
-	out     []byte // leftover decoded output
-	outbuf  [1024]byte
-}
-
-func (d *decoder) Read(p []byte) (n int, err error) {
-	if len(p) == 0 {
-		return 0, nil
-	}
-	if d.err != nil {
-		return 0, d.err
-	}
-
-	for {
-		// Copy leftover output from last decode.
-		if len(d.out) > 0 {
-			n = copy(p, d.out)
-			d.out = d.out[n:]
-			return
-		}
-
-		// Decode leftover input from last read.
-		var nn, nsrc, ndst int
-		if d.nbuf > 0 {
-			ndst, nsrc, d.err = Decode(d.outbuf[0:], d.buf[0:d.nbuf], d.readErr != nil)
-			if ndst > 0 {
-				d.out = d.outbuf[0:ndst]
-				d.nbuf = copy(d.buf[0:], d.buf[nsrc:d.nbuf])
-				continue // copy out and return
-			}
-			if ndst == 0 && d.err == nil {
-				// Special case: input buffer is mostly filled with non-data bytes.
-				// Filter out such bytes to make room for more input.
-				off := 0
-				for i := 0; i < d.nbuf; i++ {
-					if d.buf[i] > ' ' {
-						d.buf[off] = d.buf[i]
-						off++
-					}
-				}
-				d.nbuf = off
-			}
-		}
-
-		// Out of input, out of decoded output.  Check errors.
-		if d.err != nil {
-			return 0, d.err
-		}
-		if d.readErr != nil {
-			d.err = d.readErr
-			return 0, d.err
-		}
-
-		// Read more data.
-		nn, d.readErr = d.r.Read(d.buf[d.nbuf:])
-		d.nbuf += nn
-	}
-}
diff --git a/src/pkg/encoding/asn1/asn1.go b/src/pkg/encoding/asn1/asn1.go
deleted file mode 100644
index ec7f91c..0000000
--- a/src/pkg/encoding/asn1/asn1.go
+++ /dev/null
@@ -1,908 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package asn1 implements parsing of DER-encoded ASN.1 data structures,
-// as defined in ITU-T Rec X.690.
-//
-// See also ``A Layman's Guide to a Subset of ASN.1, BER, and DER,''
-// http://luca.ntop.org/Teaching/Appunti/asn1.html.
-package asn1
-
-// ASN.1 is a syntax for specifying abstract objects and BER, DER, PER, XER etc
-// are different encoding formats for those objects. Here, we'll be dealing
-// with DER, the Distinguished Encoding Rules. DER is used in X.509 because
-// it's fast to parse and, unlike BER, has a unique encoding for every object.
-// When calculating hashes over objects, it's important that the resulting
-// bytes be the same at both ends and DER removes this margin of error.
-//
-// ASN.1 is very complex and this package doesn't attempt to implement
-// everything by any means.
-
-import (
-	"fmt"
-	"math/big"
-	"reflect"
-	"strconv"
-	"time"
-)
-
-// A StructuralError suggests that the ASN.1 data is valid, but the Go type
-// which is receiving it doesn't match.
-type StructuralError struct {
-	Msg string
-}
-
-func (e StructuralError) Error() string { return "asn1: structure error: " + e.Msg }
-
-// A SyntaxError suggests that the ASN.1 data is invalid.
-type SyntaxError struct {
-	Msg string
-}
-
-func (e SyntaxError) Error() string { return "asn1: syntax error: " + e.Msg }
-
-// We start by dealing with each of the primitive types in turn.
-
-// BOOLEAN
-
-func parseBool(bytes []byte) (ret bool, err error) {
-	if len(bytes) != 1 {
-		err = SyntaxError{"invalid boolean"}
-		return
-	}
-
-	// DER demands that "If the encoding represents the boolean value TRUE,
-	// its single contents octet shall have all eight bits set to one."
-	// Thus only 0 and 255 are valid encoded values.
-	switch bytes[0] {
-	case 0:
-		ret = false
-	case 0xff:
-		ret = true
-	default:
-		err = SyntaxError{"invalid boolean"}
-	}
-
-	return
-}
-
-// INTEGER
-
-// parseInt64 treats the given bytes as a big-endian, signed integer and
-// returns the result.
-func parseInt64(bytes []byte) (ret int64, err error) {
-	if len(bytes) > 8 {
-		// We'll overflow an int64 in this case.
-		err = StructuralError{"integer too large"}
-		return
-	}
-	for bytesRead := 0; bytesRead < len(bytes); bytesRead++ {
-		ret <<= 8
-		ret |= int64(bytes[bytesRead])
-	}
-
-	// Shift up and down in order to sign extend the result.
-	ret <<= 64 - uint8(len(bytes))*8
-	ret >>= 64 - uint8(len(bytes))*8
-	return
-}
-
-// parseInt treats the given bytes as a big-endian, signed integer and returns
-// the result.
-func parseInt32(bytes []byte) (int32, error) {
-	ret64, err := parseInt64(bytes)
-	if err != nil {
-		return 0, err
-	}
-	if ret64 != int64(int32(ret64)) {
-		return 0, StructuralError{"integer too large"}
-	}
-	return int32(ret64), nil
-}
-
-var bigOne = big.NewInt(1)
-
-// parseBigInt treats the given bytes as a big-endian, signed integer and returns
-// the result.
-func parseBigInt(bytes []byte) *big.Int {
-	ret := new(big.Int)
-	if len(bytes) > 0 && bytes[0]&0x80 == 0x80 {
-		// This is a negative number.
-		notBytes := make([]byte, len(bytes))
-		for i := range notBytes {
-			notBytes[i] = ^bytes[i]
-		}
-		ret.SetBytes(notBytes)
-		ret.Add(ret, bigOne)
-		ret.Neg(ret)
-		return ret
-	}
-	ret.SetBytes(bytes)
-	return ret
-}
-
-// BIT STRING
-
-// BitString is the structure to use when you want an ASN.1 BIT STRING type. A
-// bit string is padded up to the nearest byte in memory and the number of
-// valid bits is recorded. Padding bits will be zero.
-type BitString struct {
-	Bytes     []byte // bits packed into bytes.
-	BitLength int    // length in bits.
-}
-
-// At returns the bit at the given index. If the index is out of range it
-// returns false.
-func (b BitString) At(i int) int {
-	if i < 0 || i >= b.BitLength {
-		return 0
-	}
-	x := i / 8
-	y := 7 - uint(i%8)
-	return int(b.Bytes[x]>>y) & 1
-}
-
-// RightAlign returns a slice where the padding bits are at the beginning. The
-// slice may share memory with the BitString.
-func (b BitString) RightAlign() []byte {
-	shift := uint(8 - (b.BitLength % 8))
-	if shift == 8 || len(b.Bytes) == 0 {
-		return b.Bytes
-	}
-
-	a := make([]byte, len(b.Bytes))
-	a[0] = b.Bytes[0] >> shift
-	for i := 1; i < len(b.Bytes); i++ {
-		a[i] = b.Bytes[i-1] << (8 - shift)
-		a[i] |= b.Bytes[i] >> shift
-	}
-
-	return a
-}
-
-// parseBitString parses an ASN.1 bit string from the given byte slice and returns it.
-func parseBitString(bytes []byte) (ret BitString, err error) {
-	if len(bytes) == 0 {
-		err = SyntaxError{"zero length BIT STRING"}
-		return
-	}
-	paddingBits := int(bytes[0])
-	if paddingBits > 7 ||
-		len(bytes) == 1 && paddingBits > 0 ||
-		bytes[len(bytes)-1]&((1<<bytes[0])-1) != 0 {
-		err = SyntaxError{"invalid padding bits in BIT STRING"}
-		return
-	}
-	ret.BitLength = (len(bytes)-1)*8 - paddingBits
-	ret.Bytes = bytes[1:]
-	return
-}
-
-// OBJECT IDENTIFIER
-
-// An ObjectIdentifier represents an ASN.1 OBJECT IDENTIFIER.
-type ObjectIdentifier []int
-
-// Equal reports whether oi and other represent the same identifier.
-func (oi ObjectIdentifier) Equal(other ObjectIdentifier) bool {
-	if len(oi) != len(other) {
-		return false
-	}
-	for i := 0; i < len(oi); i++ {
-		if oi[i] != other[i] {
-			return false
-		}
-	}
-
-	return true
-}
-
-func (oi ObjectIdentifier) String() string {
-	var s string
-
-	for i, v := range oi {
-		if i > 0 {
-			s += "."
-		}
-		s += strconv.Itoa(v)
-	}
-
-	return s
-}
-
-// parseObjectIdentifier parses an OBJECT IDENTIFIER from the given bytes and
-// returns it. An object identifier is a sequence of variable length integers
-// that are assigned in a hierarchy.
-func parseObjectIdentifier(bytes []byte) (s []int, err error) {
-	if len(bytes) == 0 {
-		err = SyntaxError{"zero length OBJECT IDENTIFIER"}
-		return
-	}
-
-	// In the worst case, we get two elements from the first byte (which is
-	// encoded differently) and then every varint is a single byte long.
-	s = make([]int, len(bytes)+1)
-
-	// The first varint is 40*value1 + value2:
-	// According to this packing, value1 can take the values 0, 1 and 2 only.
-	// When value1 = 0 or value1 = 1, then value2 is <= 39. When value1 = 2,
-	// then there are no restrictions on value2.
-	v, offset, err := parseBase128Int(bytes, 0)
-	if err != nil {
-		return
-	}
-	if v < 80 {
-		s[0] = v / 40
-		s[1] = v % 40
-	} else {
-		s[0] = 2
-		s[1] = v - 80
-	}
-
-	i := 2
-	for ; offset < len(bytes); i++ {
-		v, offset, err = parseBase128Int(bytes, offset)
-		if err != nil {
-			return
-		}
-		s[i] = v
-	}
-	s = s[0:i]
-	return
-}
-
-// ENUMERATED
-
-// An Enumerated is represented as a plain int.
-type Enumerated int
-
-// FLAG
-
-// A Flag accepts any data and is set to true if present.
-type Flag bool
-
-// parseBase128Int parses a base-128 encoded int from the given offset in the
-// given byte slice. It returns the value and the new offset.
-func parseBase128Int(bytes []byte, initOffset int) (ret, offset int, err error) {
-	offset = initOffset
-	for shifted := 0; offset < len(bytes); shifted++ {
-		if shifted > 4 {
-			err = StructuralError{"base 128 integer too large"}
-			return
-		}
-		ret <<= 7
-		b := bytes[offset]
-		ret |= int(b & 0x7f)
-		offset++
-		if b&0x80 == 0 {
-			return
-		}
-	}
-	err = SyntaxError{"truncated base 128 integer"}
-	return
-}
-
-// UTCTime
-
-func parseUTCTime(bytes []byte) (ret time.Time, err error) {
-	s := string(bytes)
-	ret, err = time.Parse("0601021504Z0700", s)
-	if err != nil {
-		ret, err = time.Parse("060102150405Z0700", s)
-	}
-	if err == nil && ret.Year() >= 2050 {
-		// UTCTime only encodes times prior to 2050. See https://tools.ietf.org/html/rfc5280#section-4.1.2.5.1
-		ret = ret.AddDate(-100, 0, 0)
-	}
-
-	return
-}
-
-// parseGeneralizedTime parses the GeneralizedTime from the given byte slice
-// and returns the resulting time.
-func parseGeneralizedTime(bytes []byte) (ret time.Time, err error) {
-	return time.Parse("20060102150405Z0700", string(bytes))
-}
-
-// PrintableString
-
-// parsePrintableString parses a ASN.1 PrintableString from the given byte
-// array and returns it.
-func parsePrintableString(bytes []byte) (ret string, err error) {
-	for _, b := range bytes {
-		if !isPrintable(b) {
-			err = SyntaxError{"PrintableString contains invalid character"}
-			return
-		}
-	}
-	ret = string(bytes)
-	return
-}
-
-// isPrintable returns true iff the given b is in the ASN.1 PrintableString set.
-func isPrintable(b byte) bool {
-	return 'a' <= b && b <= 'z' ||
-		'A' <= b && b <= 'Z' ||
-		'0' <= b && b <= '9' ||
-		'\'' <= b && b <= ')' ||
-		'+' <= b && b <= '/' ||
-		b == ' ' ||
-		b == ':' ||
-		b == '=' ||
-		b == '?' ||
-		// This is technically not allowed in a PrintableString.
-		// However, x509 certificates with wildcard strings don't
-		// always use the correct string type so we permit it.
-		b == '*'
-}
-
-// IA5String
-
-// parseIA5String parses a ASN.1 IA5String (ASCII string) from the given
-// byte slice and returns it.
-func parseIA5String(bytes []byte) (ret string, err error) {
-	for _, b := range bytes {
-		if b >= 0x80 {
-			err = SyntaxError{"IA5String contains invalid character"}
-			return
-		}
-	}
-	ret = string(bytes)
-	return
-}
-
-// T61String
-
-// parseT61String parses a ASN.1 T61String (8-bit clean string) from the given
-// byte slice and returns it.
-func parseT61String(bytes []byte) (ret string, err error) {
-	return string(bytes), nil
-}
-
-// UTF8String
-
-// parseUTF8String parses a ASN.1 UTF8String (raw UTF-8) from the given byte
-// array and returns it.
-func parseUTF8String(bytes []byte) (ret string, err error) {
-	return string(bytes), nil
-}
-
-// A RawValue represents an undecoded ASN.1 object.
-type RawValue struct {
-	Class, Tag int
-	IsCompound bool
-	Bytes      []byte
-	FullBytes  []byte // includes the tag and length
-}
-
-// RawContent is used to signal that the undecoded, DER data needs to be
-// preserved for a struct. To use it, the first field of the struct must have
-// this type. It's an error for any of the other fields to have this type.
-type RawContent []byte
-
-// Tagging
-
-// parseTagAndLength parses an ASN.1 tag and length pair from the given offset
-// into a byte slice. It returns the parsed data and the new offset. SET and
-// SET OF (tag 17) are mapped to SEQUENCE and SEQUENCE OF (tag 16) since we
-// don't distinguish between ordered and unordered objects in this code.
-func parseTagAndLength(bytes []byte, initOffset int) (ret tagAndLength, offset int, err error) {
-	offset = initOffset
-	b := bytes[offset]
-	offset++
-	ret.class = int(b >> 6)
-	ret.isCompound = b&0x20 == 0x20
-	ret.tag = int(b & 0x1f)
-
-	// If the bottom five bits are set, then the tag number is actually base 128
-	// encoded afterwards
-	if ret.tag == 0x1f {
-		ret.tag, offset, err = parseBase128Int(bytes, offset)
-		if err != nil {
-			return
-		}
-	}
-	if offset >= len(bytes) {
-		err = SyntaxError{"truncated tag or length"}
-		return
-	}
-	b = bytes[offset]
-	offset++
-	if b&0x80 == 0 {
-		// The length is encoded in the bottom 7 bits.
-		ret.length = int(b & 0x7f)
-	} else {
-		// Bottom 7 bits give the number of length bytes to follow.
-		numBytes := int(b & 0x7f)
-		if numBytes == 0 {
-			err = SyntaxError{"indefinite length found (not DER)"}
-			return
-		}
-		ret.length = 0
-		for i := 0; i < numBytes; i++ {
-			if offset >= len(bytes) {
-				err = SyntaxError{"truncated tag or length"}
-				return
-			}
-			b = bytes[offset]
-			offset++
-			if ret.length >= 1<<23 {
-				// We can't shift ret.length up without
-				// overflowing.
-				err = StructuralError{"length too large"}
-				return
-			}
-			ret.length <<= 8
-			ret.length |= int(b)
-			if ret.length == 0 {
-				// DER requires that lengths be minimal.
-				err = StructuralError{"superfluous leading zeros in length"}
-				return
-			}
-		}
-	}
-
-	return
-}
-
-// parseSequenceOf is used for SEQUENCE OF and SET OF values. It tries to parse
-// a number of ASN.1 values from the given byte slice and returns them as a
-// slice of Go values of the given type.
-func parseSequenceOf(bytes []byte, sliceType reflect.Type, elemType reflect.Type) (ret reflect.Value, err error) {
-	expectedTag, compoundType, ok := getUniversalType(elemType)
-	if !ok {
-		err = StructuralError{"unknown Go type for slice"}
-		return
-	}
-
-	// First we iterate over the input and count the number of elements,
-	// checking that the types are correct in each case.
-	numElements := 0
-	for offset := 0; offset < len(bytes); {
-		var t tagAndLength
-		t, offset, err = parseTagAndLength(bytes, offset)
-		if err != nil {
-			return
-		}
-		switch t.tag {
-		case tagIA5String, tagGeneralString, tagT61String, tagUTF8String:
-			// We pretend that various other string types are
-			// PRINTABLE STRINGs so that a sequence of them can be
-			// parsed into a []string.
-			t.tag = tagPrintableString
-		case tagGeneralizedTime, tagUTCTime:
-			// Likewise, both time types are treated the same.
-			t.tag = tagUTCTime
-		}
-
-		if t.class != classUniversal || t.isCompound != compoundType || t.tag != expectedTag {
-			err = StructuralError{"sequence tag mismatch"}
-			return
-		}
-		if invalidLength(offset, t.length, len(bytes)) {
-			err = SyntaxError{"truncated sequence"}
-			return
-		}
-		offset += t.length
-		numElements++
-	}
-	ret = reflect.MakeSlice(sliceType, numElements, numElements)
-	params := fieldParameters{}
-	offset := 0
-	for i := 0; i < numElements; i++ {
-		offset, err = parseField(ret.Index(i), bytes, offset, params)
-		if err != nil {
-			return
-		}
-	}
-	return
-}
-
-var (
-	bitStringType        = reflect.TypeOf(BitString{})
-	objectIdentifierType = reflect.TypeOf(ObjectIdentifier{})
-	enumeratedType       = reflect.TypeOf(Enumerated(0))
-	flagType             = reflect.TypeOf(Flag(false))
-	timeType             = reflect.TypeOf(time.Time{})
-	rawValueType         = reflect.TypeOf(RawValue{})
-	rawContentsType      = reflect.TypeOf(RawContent(nil))
-	bigIntType           = reflect.TypeOf(new(big.Int))
-)
-
-// invalidLength returns true iff offset + length > sliceLength, or if the
-// addition would overflow.
-func invalidLength(offset, length, sliceLength int) bool {
-	return offset+length < offset || offset+length > sliceLength
-}
-
-// parseField is the main parsing function. Given a byte slice and an offset
-// into the array, it will try to parse a suitable ASN.1 value out and store it
-// in the given Value.
-func parseField(v reflect.Value, bytes []byte, initOffset int, params fieldParameters) (offset int, err error) {
-	offset = initOffset
-	fieldType := v.Type()
-
-	// If we have run out of data, it may be that there are optional elements at the end.
-	if offset == len(bytes) {
-		if !setDefaultValue(v, params) {
-			err = SyntaxError{"sequence truncated"}
-		}
-		return
-	}
-
-	// Deal with raw values.
-	if fieldType == rawValueType {
-		var t tagAndLength
-		t, offset, err = parseTagAndLength(bytes, offset)
-		if err != nil {
-			return
-		}
-		if invalidLength(offset, t.length, len(bytes)) {
-			err = SyntaxError{"data truncated"}
-			return
-		}
-		result := RawValue{t.class, t.tag, t.isCompound, bytes[offset : offset+t.length], bytes[initOffset : offset+t.length]}
-		offset += t.length
-		v.Set(reflect.ValueOf(result))
-		return
-	}
-
-	// Deal with the ANY type.
-	if ifaceType := fieldType; ifaceType.Kind() == reflect.Interface && ifaceType.NumMethod() == 0 {
-		var t tagAndLength
-		t, offset, err = parseTagAndLength(bytes, offset)
-		if err != nil {
-			return
-		}
-		if invalidLength(offset, t.length, len(bytes)) {
-			err = SyntaxError{"data truncated"}
-			return
-		}
-		var result interface{}
-		if !t.isCompound && t.class == classUniversal {
-			innerBytes := bytes[offset : offset+t.length]
-			switch t.tag {
-			case tagPrintableString:
-				result, err = parsePrintableString(innerBytes)
-			case tagIA5String:
-				result, err = parseIA5String(innerBytes)
-			case tagT61String:
-				result, err = parseT61String(innerBytes)
-			case tagUTF8String:
-				result, err = parseUTF8String(innerBytes)
-			case tagInteger:
-				result, err = parseInt64(innerBytes)
-			case tagBitString:
-				result, err = parseBitString(innerBytes)
-			case tagOID:
-				result, err = parseObjectIdentifier(innerBytes)
-			case tagUTCTime:
-				result, err = parseUTCTime(innerBytes)
-			case tagOctetString:
-				result = innerBytes
-			default:
-				// If we don't know how to handle the type, we just leave Value as nil.
-			}
-		}
-		offset += t.length
-		if err != nil {
-			return
-		}
-		if result != nil {
-			v.Set(reflect.ValueOf(result))
-		}
-		return
-	}
-	universalTag, compoundType, ok1 := getUniversalType(fieldType)
-	if !ok1 {
-		err = StructuralError{fmt.Sprintf("unknown Go type: %v", fieldType)}
-		return
-	}
-
-	t, offset, err := parseTagAndLength(bytes, offset)
-	if err != nil {
-		return
-	}
-	if params.explicit {
-		expectedClass := classContextSpecific
-		if params.application {
-			expectedClass = classApplication
-		}
-		if t.class == expectedClass && t.tag == *params.tag && (t.length == 0 || t.isCompound) {
-			if t.length > 0 {
-				t, offset, err = parseTagAndLength(bytes, offset)
-				if err != nil {
-					return
-				}
-			} else {
-				if fieldType != flagType {
-					err = StructuralError{"zero length explicit tag was not an asn1.Flag"}
-					return
-				}
-				v.SetBool(true)
-				return
-			}
-		} else {
-			// The tags didn't match, it might be an optional element.
-			ok := setDefaultValue(v, params)
-			if ok {
-				offset = initOffset
-			} else {
-				err = StructuralError{"explicitly tagged member didn't match"}
-			}
-			return
-		}
-	}
-
-	// Special case for strings: all the ASN.1 string types map to the Go
-	// type string. getUniversalType returns the tag for PrintableString
-	// when it sees a string, so if we see a different string type on the
-	// wire, we change the universal type to match.
-	if universalTag == tagPrintableString {
-		switch t.tag {
-		case tagIA5String, tagGeneralString, tagT61String, tagUTF8String:
-			universalTag = t.tag
-		}
-	}
-
-	// Special case for time: UTCTime and GeneralizedTime both map to the
-	// Go type time.Time.
-	if universalTag == tagUTCTime && t.tag == tagGeneralizedTime {
-		universalTag = tagGeneralizedTime
-	}
-
-	if params.set {
-		universalTag = tagSet
-	}
-
-	expectedClass := classUniversal
-	expectedTag := universalTag
-
-	if !params.explicit && params.tag != nil {
-		expectedClass = classContextSpecific
-		expectedTag = *params.tag
-	}
-
-	if !params.explicit && params.application && params.tag != nil {
-		expectedClass = classApplication
-		expectedTag = *params.tag
-	}
-
-	// We have unwrapped any explicit tagging at this point.
-	if t.class != expectedClass || t.tag != expectedTag || t.isCompound != compoundType {
-		// Tags don't match. Again, it could be an optional element.
-		ok := setDefaultValue(v, params)
-		if ok {
-			offset = initOffset
-		} else {
-			err = StructuralError{fmt.Sprintf("tags don't match (%d vs %+v) %+v %s @%d", expectedTag, t, params, fieldType.Name(), offset)}
-		}
-		return
-	}
-	if invalidLength(offset, t.length, len(bytes)) {
-		err = SyntaxError{"data truncated"}
-		return
-	}
-	innerBytes := bytes[offset : offset+t.length]
-	offset += t.length
-
-	// We deal with the structures defined in this package first.
-	switch fieldType {
-	case objectIdentifierType:
-		newSlice, err1 := parseObjectIdentifier(innerBytes)
-		v.Set(reflect.MakeSlice(v.Type(), len(newSlice), len(newSlice)))
-		if err1 == nil {
-			reflect.Copy(v, reflect.ValueOf(newSlice))
-		}
-		err = err1
-		return
-	case bitStringType:
-		bs, err1 := parseBitString(innerBytes)
-		if err1 == nil {
-			v.Set(reflect.ValueOf(bs))
-		}
-		err = err1
-		return
-	case timeType:
-		var time time.Time
-		var err1 error
-		if universalTag == tagUTCTime {
-			time, err1 = parseUTCTime(innerBytes)
-		} else {
-			time, err1 = parseGeneralizedTime(innerBytes)
-		}
-		if err1 == nil {
-			v.Set(reflect.ValueOf(time))
-		}
-		err = err1
-		return
-	case enumeratedType:
-		parsedInt, err1 := parseInt32(innerBytes)
-		if err1 == nil {
-			v.SetInt(int64(parsedInt))
-		}
-		err = err1
-		return
-	case flagType:
-		v.SetBool(true)
-		return
-	case bigIntType:
-		parsedInt := parseBigInt(innerBytes)
-		v.Set(reflect.ValueOf(parsedInt))
-		return
-	}
-	switch val := v; val.Kind() {
-	case reflect.Bool:
-		parsedBool, err1 := parseBool(innerBytes)
-		if err1 == nil {
-			val.SetBool(parsedBool)
-		}
-		err = err1
-		return
-	case reflect.Int, reflect.Int32, reflect.Int64:
-		if val.Type().Size() == 4 {
-			parsedInt, err1 := parseInt32(innerBytes)
-			if err1 == nil {
-				val.SetInt(int64(parsedInt))
-			}
-			err = err1
-		} else {
-			parsedInt, err1 := parseInt64(innerBytes)
-			if err1 == nil {
-				val.SetInt(parsedInt)
-			}
-			err = err1
-		}
-		return
-	// TODO(dfc) Add support for the remaining integer types
-	case reflect.Struct:
-		structType := fieldType
-
-		if structType.NumField() > 0 &&
-			structType.Field(0).Type == rawContentsType {
-			bytes := bytes[initOffset:offset]
-			val.Field(0).Set(reflect.ValueOf(RawContent(bytes)))
-		}
-
-		innerOffset := 0
-		for i := 0; i < structType.NumField(); i++ {
-			field := structType.Field(i)
-			if i == 0 && field.Type == rawContentsType {
-				continue
-			}
-			innerOffset, err = parseField(val.Field(i), innerBytes, innerOffset, parseFieldParameters(field.Tag.Get("asn1")))
-			if err != nil {
-				return
-			}
-		}
-		// We allow extra bytes at the end of the SEQUENCE because
-		// adding elements to the end has been used in X.509 as the
-		// version numbers have increased.
-		return
-	case reflect.Slice:
-		sliceType := fieldType
-		if sliceType.Elem().Kind() == reflect.Uint8 {
-			val.Set(reflect.MakeSlice(sliceType, len(innerBytes), len(innerBytes)))
-			reflect.Copy(val, reflect.ValueOf(innerBytes))
-			return
-		}
-		newSlice, err1 := parseSequenceOf(innerBytes, sliceType, sliceType.Elem())
-		if err1 == nil {
-			val.Set(newSlice)
-		}
-		err = err1
-		return
-	case reflect.String:
-		var v string
-		switch universalTag {
-		case tagPrintableString:
-			v, err = parsePrintableString(innerBytes)
-		case tagIA5String:
-			v, err = parseIA5String(innerBytes)
-		case tagT61String:
-			v, err = parseT61String(innerBytes)
-		case tagUTF8String:
-			v, err = parseUTF8String(innerBytes)
-		case tagGeneralString:
-			// GeneralString is specified in ISO-2022/ECMA-35,
-			// A brief review suggests that it includes structures
-			// that allow the encoding to change midstring and
-			// such. We give up and pass it as an 8-bit string.
-			v, err = parseT61String(innerBytes)
-		default:
-			err = SyntaxError{fmt.Sprintf("internal error: unknown string type %d", universalTag)}
-		}
-		if err == nil {
-			val.SetString(v)
-		}
-		return
-	}
-	err = StructuralError{"unsupported: " + v.Type().String()}
-	return
-}
-
-// setDefaultValue is used to install a default value, from a tag string, into
-// a Value. It is successful is the field was optional, even if a default value
-// wasn't provided or it failed to install it into the Value.
-func setDefaultValue(v reflect.Value, params fieldParameters) (ok bool) {
-	if !params.optional {
-		return
-	}
-	ok = true
-	if params.defaultValue == nil {
-		return
-	}
-	switch val := v; val.Kind() {
-	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-		val.SetInt(*params.defaultValue)
-	}
-	return
-}
-
-// Unmarshal parses the DER-encoded ASN.1 data structure b
-// and uses the reflect package to fill in an arbitrary value pointed at by val.
-// Because Unmarshal uses the reflect package, the structs
-// being written to must use upper case field names.
-//
-// An ASN.1 INTEGER can be written to an int, int32, int64,
-// or *big.Int (from the math/big package).
-// If the encoded value does not fit in the Go type,
-// Unmarshal returns a parse error.
-//
-// An ASN.1 BIT STRING can be written to a BitString.
-//
-// An ASN.1 OCTET STRING can be written to a []byte.
-//
-// An ASN.1 OBJECT IDENTIFIER can be written to an
-// ObjectIdentifier.
-//
-// An ASN.1 ENUMERATED can be written to an Enumerated.
-//
-// An ASN.1 UTCTIME or GENERALIZEDTIME can be written to a time.Time.
-//
-// An ASN.1 PrintableString or IA5String can be written to a string.
-//
-// Any of the above ASN.1 values can be written to an interface{}.
-// The value stored in the interface has the corresponding Go type.
-// For integers, that type is int64.
-//
-// An ASN.1 SEQUENCE OF x or SET OF x can be written
-// to a slice if an x can be written to the slice's element type.
-//
-// An ASN.1 SEQUENCE or SET can be written to a struct
-// if each of the elements in the sequence can be
-// written to the corresponding element in the struct.
-//
-// The following tags on struct fields have special meaning to Unmarshal:
-//
-//	application	specifies that a APPLICATION tag is used
-//	default:x	sets the default value for optional integer fields
-//	explicit	specifies that an additional, explicit tag wraps the implicit one
-//	optional	marks the field as ASN.1 OPTIONAL
-//	set		causes a SET, rather than a SEQUENCE type to be expected
-//	tag:x		specifies the ASN.1 tag number; implies ASN.1 CONTEXT SPECIFIC
-//
-// If the type of the first field of a structure is RawContent then the raw
-// ASN1 contents of the struct will be stored in it.
-//
-// If the type name of a slice element ends with "SET" then it's treated as if
-// the "set" tag was set on it. This can be used with nested slices where a
-// struct tag cannot be given.
-//
-// Other ASN.1 types are not supported; if it encounters them,
-// Unmarshal returns a parse error.
-func Unmarshal(b []byte, val interface{}) (rest []byte, err error) {
-	return UnmarshalWithParams(b, val, "")
-}
-
-// UnmarshalWithParams allows field parameters to be specified for the
-// top-level element. The form of the params is the same as the field tags.
-func UnmarshalWithParams(b []byte, val interface{}, params string) (rest []byte, err error) {
-	v := reflect.ValueOf(val).Elem()
-	offset, err := parseField(v, b, 0, parseFieldParameters(params))
-	if err != nil {
-		return nil, err
-	}
-	return b[offset:], nil
-}
diff --git a/src/pkg/encoding/asn1/asn1_test.go b/src/pkg/encoding/asn1/asn1_test.go
deleted file mode 100644
index b553f78..0000000
--- a/src/pkg/encoding/asn1/asn1_test.go
+++ /dev/null
@@ -1,814 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package asn1
-
-import (
-	"bytes"
-	"fmt"
-	"math/big"
-	"reflect"
-	"testing"
-	"time"
-)
-
-type boolTest struct {
-	in  []byte
-	ok  bool
-	out bool
-}
-
-var boolTestData = []boolTest{
-	{[]byte{0x00}, true, false},
-	{[]byte{0xff}, true, true},
-	{[]byte{0x00, 0x00}, false, false},
-	{[]byte{0xff, 0xff}, false, false},
-	{[]byte{0x01}, false, false},
-}
-
-func TestParseBool(t *testing.T) {
-	for i, test := range boolTestData {
-		ret, err := parseBool(test.in)
-		if (err == nil) != test.ok {
-			t.Errorf("#%d: Incorrect error result (did fail? %v, expected: %v)", i, err == nil, test.ok)
-		}
-		if test.ok && ret != test.out {
-			t.Errorf("#%d: Bad result: %v (expected %v)", i, ret, test.out)
-		}
-	}
-}
-
-type int64Test struct {
-	in  []byte
-	ok  bool
-	out int64
-}
-
-var int64TestData = []int64Test{
-	{[]byte{0x00}, true, 0},
-	{[]byte{0x7f}, true, 127},
-	{[]byte{0x00, 0x80}, true, 128},
-	{[]byte{0x01, 0x00}, true, 256},
-	{[]byte{0x80}, true, -128},
-	{[]byte{0xff, 0x7f}, true, -129},
-	{[]byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, true, -1},
-	{[]byte{0xff}, true, -1},
-	{[]byte{0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, true, -9223372036854775808},
-	{[]byte{0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, false, 0},
-}
-
-func TestParseInt64(t *testing.T) {
-	for i, test := range int64TestData {
-		ret, err := parseInt64(test.in)
-		if (err == nil) != test.ok {
-			t.Errorf("#%d: Incorrect error result (did fail? %v, expected: %v)", i, err == nil, test.ok)
-		}
-		if test.ok && ret != test.out {
-			t.Errorf("#%d: Bad result: %v (expected %v)", i, ret, test.out)
-		}
-	}
-}
-
-type int32Test struct {
-	in  []byte
-	ok  bool
-	out int32
-}
-
-var int32TestData = []int32Test{
-	{[]byte{0x00}, true, 0},
-	{[]byte{0x7f}, true, 127},
-	{[]byte{0x00, 0x80}, true, 128},
-	{[]byte{0x01, 0x00}, true, 256},
-	{[]byte{0x80}, true, -128},
-	{[]byte{0xff, 0x7f}, true, -129},
-	{[]byte{0xff, 0xff, 0xff, 0xff}, true, -1},
-	{[]byte{0xff}, true, -1},
-	{[]byte{0x80, 0x00, 0x00, 0x00}, true, -2147483648},
-	{[]byte{0x80, 0x00, 0x00, 0x00, 0x00}, false, 0},
-}
-
-func TestParseInt32(t *testing.T) {
-	for i, test := range int32TestData {
-		ret, err := parseInt32(test.in)
-		if (err == nil) != test.ok {
-			t.Errorf("#%d: Incorrect error result (did fail? %v, expected: %v)", i, err == nil, test.ok)
-		}
-		if test.ok && int32(ret) != test.out {
-			t.Errorf("#%d: Bad result: %v (expected %v)", i, ret, test.out)
-		}
-	}
-}
-
-var bigIntTests = []struct {
-	in     []byte
-	base10 string
-}{
-	{[]byte{0xff}, "-1"},
-	{[]byte{0x00}, "0"},
-	{[]byte{0x01}, "1"},
-	{[]byte{0x00, 0xff}, "255"},
-	{[]byte{0xff, 0x00}, "-256"},
-	{[]byte{0x01, 0x00}, "256"},
-}
-
-func TestParseBigInt(t *testing.T) {
-	for i, test := range bigIntTests {
-		ret := parseBigInt(test.in)
-		if ret.String() != test.base10 {
-			t.Errorf("#%d: bad result from %x, got %s want %s", i, test.in, ret.String(), test.base10)
-		}
-		fw := newForkableWriter()
-		marshalBigInt(fw, ret)
-		result := fw.Bytes()
-		if !bytes.Equal(result, test.in) {
-			t.Errorf("#%d: got %x from marshaling %s, want %x", i, result, ret, test.in)
-		}
-	}
-}
-
-type bitStringTest struct {
-	in        []byte
-	ok        bool
-	out       []byte
-	bitLength int
-}
-
-var bitStringTestData = []bitStringTest{
-	{[]byte{}, false, []byte{}, 0},
-	{[]byte{0x00}, true, []byte{}, 0},
-	{[]byte{0x07, 0x00}, true, []byte{0x00}, 1},
-	{[]byte{0x07, 0x01}, false, []byte{}, 0},
-	{[]byte{0x07, 0x40}, false, []byte{}, 0},
-	{[]byte{0x08, 0x00}, false, []byte{}, 0},
-}
-
-func TestBitString(t *testing.T) {
-	for i, test := range bitStringTestData {
-		ret, err := parseBitString(test.in)
-		if (err == nil) != test.ok {
-			t.Errorf("#%d: Incorrect error result (did fail? %v, expected: %v)", i, err == nil, test.ok)
-		}
-		if err == nil {
-			if test.bitLength != ret.BitLength || !bytes.Equal(ret.Bytes, test.out) {
-				t.Errorf("#%d: Bad result: %v (expected %v %v)", i, ret, test.out, test.bitLength)
-			}
-		}
-	}
-}
-
-func TestBitStringAt(t *testing.T) {
-	bs := BitString{[]byte{0x82, 0x40}, 16}
-	if bs.At(0) != 1 {
-		t.Error("#1: Failed")
-	}
-	if bs.At(1) != 0 {
-		t.Error("#2: Failed")
-	}
-	if bs.At(6) != 1 {
-		t.Error("#3: Failed")
-	}
-	if bs.At(9) != 1 {
-		t.Error("#4: Failed")
-	}
-	if bs.At(-1) != 0 {
-		t.Error("#5: Failed")
-	}
-	if bs.At(17) != 0 {
-		t.Error("#6: Failed")
-	}
-}
-
-type bitStringRightAlignTest struct {
-	in    []byte
-	inlen int
-	out   []byte
-}
-
-var bitStringRightAlignTests = []bitStringRightAlignTest{
-	{[]byte{0x80}, 1, []byte{0x01}},
-	{[]byte{0x80, 0x80}, 9, []byte{0x01, 0x01}},
-	{[]byte{}, 0, []byte{}},
-	{[]byte{0xce}, 8, []byte{0xce}},
-	{[]byte{0xce, 0x47}, 16, []byte{0xce, 0x47}},
-	{[]byte{0x34, 0x50}, 12, []byte{0x03, 0x45}},
-}
-
-func TestBitStringRightAlign(t *testing.T) {
-	for i, test := range bitStringRightAlignTests {
-		bs := BitString{test.in, test.inlen}
-		out := bs.RightAlign()
-		if !bytes.Equal(out, test.out) {
-			t.Errorf("#%d got: %x want: %x", i, out, test.out)
-		}
-	}
-}
-
-type objectIdentifierTest struct {
-	in  []byte
-	ok  bool
-	out []int
-}
-
-var objectIdentifierTestData = []objectIdentifierTest{
-	{[]byte{}, false, []int{}},
-	{[]byte{85}, true, []int{2, 5}},
-	{[]byte{85, 0x02}, true, []int{2, 5, 2}},
-	{[]byte{85, 0x02, 0xc0, 0x00}, true, []int{2, 5, 2, 0x2000}},
-	{[]byte{0x81, 0x34, 0x03}, true, []int{2, 100, 3}},
-	{[]byte{85, 0x02, 0xc0, 0x80, 0x80, 0x80, 0x80}, false, []int{}},
-}
-
-func TestObjectIdentifier(t *testing.T) {
-	for i, test := range objectIdentifierTestData {
-		ret, err := parseObjectIdentifier(test.in)
-		if (err == nil) != test.ok {
-			t.Errorf("#%d: Incorrect error result (did fail? %v, expected: %v)", i, err == nil, test.ok)
-		}
-		if err == nil {
-			if !reflect.DeepEqual(test.out, ret) {
-				t.Errorf("#%d: Bad result: %v (expected %v)", i, ret, test.out)
-			}
-		}
-	}
-
-	if s := ObjectIdentifier([]int{1, 2, 3, 4}).String(); s != "1.2.3.4" {
-		t.Errorf("bad ObjectIdentifier.String(). Got %s, want 1.2.3.4", s)
-	}
-}
-
-type timeTest struct {
-	in  string
-	ok  bool
-	out time.Time
-}
-
-var utcTestData = []timeTest{
-	{"910506164540-0700", true, time.Date(1991, 05, 06, 16, 45, 40, 0, time.FixedZone("", -7*60*60))},
-	{"910506164540+0730", true, time.Date(1991, 05, 06, 16, 45, 40, 0, time.FixedZone("", 7*60*60+30*60))},
-	{"910506234540Z", true, time.Date(1991, 05, 06, 23, 45, 40, 0, time.UTC)},
-	{"9105062345Z", true, time.Date(1991, 05, 06, 23, 45, 0, 0, time.UTC)},
-	{"5105062345Z", true, time.Date(1951, 05, 06, 23, 45, 0, 0, time.UTC)},
-	{"a10506234540Z", false, time.Time{}},
-	{"91a506234540Z", false, time.Time{}},
-	{"9105a6234540Z", false, time.Time{}},
-	{"910506a34540Z", false, time.Time{}},
-	{"910506334a40Z", false, time.Time{}},
-	{"91050633444aZ", false, time.Time{}},
-	{"910506334461Z", false, time.Time{}},
-	{"910506334400Za", false, time.Time{}},
-}
-
-func TestUTCTime(t *testing.T) {
-	for i, test := range utcTestData {
-		ret, err := parseUTCTime([]byte(test.in))
-		if err != nil {
-			if test.ok {
-				t.Errorf("#%d: parseUTCTime(%q) = error %v", i, test.in, err)
-			}
-			continue
-		}
-		if !test.ok {
-			t.Errorf("#%d: parseUTCTime(%q) succeeded, should have failed", i, test.in)
-			continue
-		}
-		const format = "Jan _2 15:04:05 -0700 2006" // ignore zone name, just offset
-		have := ret.Format(format)
-		want := test.out.Format(format)
-		if have != want {
-			t.Errorf("#%d: parseUTCTime(%q) = %s, want %s", i, test.in, have, want)
-		}
-	}
-}
-
-var generalizedTimeTestData = []timeTest{
-	{"20100102030405Z", true, time.Date(2010, 01, 02, 03, 04, 05, 0, time.UTC)},
-	{"20100102030405", false, time.Time{}},
-	{"20100102030405+0607", true, time.Date(2010, 01, 02, 03, 04, 05, 0, time.FixedZone("", 6*60*60+7*60))},
-	{"20100102030405-0607", true, time.Date(2010, 01, 02, 03, 04, 05, 0, time.FixedZone("", -6*60*60-7*60))},
-}
-
-func TestGeneralizedTime(t *testing.T) {
-	for i, test := range generalizedTimeTestData {
-		ret, err := parseGeneralizedTime([]byte(test.in))
-		if (err == nil) != test.ok {
-			t.Errorf("#%d: Incorrect error result (did fail? %v, expected: %v)", i, err == nil, test.ok)
-		}
-		if err == nil {
-			if !reflect.DeepEqual(test.out, ret) {
-				t.Errorf("#%d: Bad result: %v (expected %v)", i, ret, test.out)
-			}
-		}
-	}
-}
-
-type tagAndLengthTest struct {
-	in  []byte
-	ok  bool
-	out tagAndLength
-}
-
-var tagAndLengthData = []tagAndLengthTest{
-	{[]byte{0x80, 0x01}, true, tagAndLength{2, 0, 1, false}},
-	{[]byte{0xa0, 0x01}, true, tagAndLength{2, 0, 1, true}},
-	{[]byte{0x02, 0x00}, true, tagAndLength{0, 2, 0, false}},
-	{[]byte{0xfe, 0x00}, true, tagAndLength{3, 30, 0, true}},
-	{[]byte{0x1f, 0x01, 0x00}, true, tagAndLength{0, 1, 0, false}},
-	{[]byte{0x1f, 0x81, 0x00, 0x00}, true, tagAndLength{0, 128, 0, false}},
-	{[]byte{0x1f, 0x81, 0x80, 0x01, 0x00}, true, tagAndLength{0, 0x4001, 0, false}},
-	{[]byte{0x00, 0x81, 0x01}, true, tagAndLength{0, 0, 1, false}},
-	{[]byte{0x00, 0x82, 0x01, 0x00}, true, tagAndLength{0, 0, 256, false}},
-	{[]byte{0x00, 0x83, 0x01, 0x00}, false, tagAndLength{}},
-	{[]byte{0x1f, 0x85}, false, tagAndLength{}},
-	{[]byte{0x30, 0x80}, false, tagAndLength{}},
-	// Superfluous zeros in the length should be an error.
-	{[]byte{0xa0, 0x82, 0x00, 0x01}, false, tagAndLength{}},
-	// Lengths up to the maximum size of an int should work.
-	{[]byte{0xa0, 0x84, 0x7f, 0xff, 0xff, 0xff}, true, tagAndLength{2, 0, 0x7fffffff, true}},
-	// Lengths that would overflow an int should be rejected.
-	{[]byte{0xa0, 0x84, 0x80, 0x00, 0x00, 0x00}, false, tagAndLength{}},
-}
-
-func TestParseTagAndLength(t *testing.T) {
-	for i, test := range tagAndLengthData {
-		tagAndLength, _, err := parseTagAndLength(test.in, 0)
-		if (err == nil) != test.ok {
-			t.Errorf("#%d: Incorrect error result (did pass? %v, expected: %v)", i, err == nil, test.ok)
-		}
-		if err == nil && !reflect.DeepEqual(test.out, tagAndLength) {
-			t.Errorf("#%d: Bad result: %v (expected %v)", i, tagAndLength, test.out)
-		}
-	}
-}
-
-type parseFieldParametersTest struct {
-	in  string
-	out fieldParameters
-}
-
-func newInt(n int) *int { return &n }
-
-func newInt64(n int64) *int64 { return &n }
-
-func newString(s string) *string { return &s }
-
-func newBool(b bool) *bool { return &b }
-
-var parseFieldParametersTestData []parseFieldParametersTest = []parseFieldParametersTest{
-	{"", fieldParameters{}},
-	{"ia5", fieldParameters{stringType: tagIA5String}},
-	{"printable", fieldParameters{stringType: tagPrintableString}},
-	{"optional", fieldParameters{optional: true}},
-	{"explicit", fieldParameters{explicit: true, tag: new(int)}},
-	{"application", fieldParameters{application: true, tag: new(int)}},
-	{"optional,explicit", fieldParameters{optional: true, explicit: true, tag: new(int)}},
-	{"default:42", fieldParameters{defaultValue: newInt64(42)}},
-	{"tag:17", fieldParameters{tag: newInt(17)}},
-	{"optional,explicit,default:42,tag:17", fieldParameters{optional: true, explicit: true, defaultValue: newInt64(42), tag: newInt(17)}},
-	{"optional,explicit,default:42,tag:17,rubbish1", fieldParameters{true, true, false, newInt64(42), newInt(17), 0, false, false}},
-	{"set", fieldParameters{set: true}},
-}
-
-func TestParseFieldParameters(t *testing.T) {
-	for i, test := range parseFieldParametersTestData {
-		f := parseFieldParameters(test.in)
-		if !reflect.DeepEqual(f, test.out) {
-			t.Errorf("#%d: Bad result: %v (expected %v)", i, f, test.out)
-		}
-	}
-}
-
-type TestObjectIdentifierStruct struct {
-	OID ObjectIdentifier
-}
-
-type TestContextSpecificTags struct {
-	A int `asn1:"tag:1"`
-}
-
-type TestContextSpecificTags2 struct {
-	A int `asn1:"explicit,tag:1"`
-	B int
-}
-
-type TestElementsAfterString struct {
-	S    string
-	A, B int
-}
-
-type TestBigInt struct {
-	X *big.Int
-}
-
-type TestSet struct {
-	Ints []int `asn1:"set"`
-}
-
-var unmarshalTestData = []struct {
-	in  []byte
-	out interface{}
-}{
-	{[]byte{0x02, 0x01, 0x42}, newInt(0x42)},
-	{[]byte{0x30, 0x08, 0x06, 0x06, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d}, &TestObjectIdentifierStruct{[]int{1, 2, 840, 113549}}},
-	{[]byte{0x03, 0x04, 0x06, 0x6e, 0x5d, 0xc0}, &BitString{[]byte{110, 93, 192}, 18}},
-	{[]byte{0x30, 0x09, 0x02, 0x01, 0x01, 0x02, 0x01, 0x02, 0x02, 0x01, 0x03}, &[]int{1, 2, 3}},
-	{[]byte{0x02, 0x01, 0x10}, newInt(16)},
-	{[]byte{0x13, 0x04, 't', 'e', 's', 't'}, newString("test")},
-	{[]byte{0x16, 0x04, 't', 'e', 's', 't'}, newString("test")},
-	{[]byte{0x16, 0x04, 't', 'e', 's', 't'}, &RawValue{0, 22, false, []byte("test"), []byte("\x16\x04test")}},
-	{[]byte{0x04, 0x04, 1, 2, 3, 4}, &RawValue{0, 4, false, []byte{1, 2, 3, 4}, []byte{4, 4, 1, 2, 3, 4}}},
-	{[]byte{0x30, 0x03, 0x81, 0x01, 0x01}, &TestContextSpecificTags{1}},
-	{[]byte{0x30, 0x08, 0xa1, 0x03, 0x02, 0x01, 0x01, 0x02, 0x01, 0x02}, &TestContextSpecificTags2{1, 2}},
-	{[]byte{0x01, 0x01, 0x00}, newBool(false)},
-	{[]byte{0x01, 0x01, 0xff}, newBool(true)},
-	{[]byte{0x30, 0x0b, 0x13, 0x03, 0x66, 0x6f, 0x6f, 0x02, 0x01, 0x22, 0x02, 0x01, 0x33}, &TestElementsAfterString{"foo", 0x22, 0x33}},
-	{[]byte{0x30, 0x05, 0x02, 0x03, 0x12, 0x34, 0x56}, &TestBigInt{big.NewInt(0x123456)}},
-	{[]byte{0x30, 0x0b, 0x31, 0x09, 0x02, 0x01, 0x01, 0x02, 0x01, 0x02, 0x02, 0x01, 0x03}, &TestSet{Ints: []int{1, 2, 3}}},
-}
-
-func TestUnmarshal(t *testing.T) {
-	for i, test := range unmarshalTestData {
-		pv := reflect.New(reflect.TypeOf(test.out).Elem())
-		val := pv.Interface()
-		_, err := Unmarshal(test.in, val)
-		if err != nil {
-			t.Errorf("Unmarshal failed at index %d %v", i, err)
-		}
-		if !reflect.DeepEqual(val, test.out) {
-			t.Errorf("#%d:\nhave %#v\nwant %#v", i, val, test.out)
-		}
-	}
-}
-
-type Certificate struct {
-	TBSCertificate     TBSCertificate
-	SignatureAlgorithm AlgorithmIdentifier
-	SignatureValue     BitString
-}
-
-type TBSCertificate struct {
-	Version            int `asn1:"optional,explicit,default:0,tag:0"`
-	SerialNumber       RawValue
-	SignatureAlgorithm AlgorithmIdentifier
-	Issuer             RDNSequence
-	Validity           Validity
-	Subject            RDNSequence
-	PublicKey          PublicKeyInfo
-}
-
-type AlgorithmIdentifier struct {
-	Algorithm ObjectIdentifier
-}
-
-type RDNSequence []RelativeDistinguishedNameSET
-
-type RelativeDistinguishedNameSET []AttributeTypeAndValue
-
-type AttributeTypeAndValue struct {
-	Type  ObjectIdentifier
-	Value interface{}
-}
-
-type Validity struct {
-	NotBefore, NotAfter time.Time
-}
-
-type PublicKeyInfo struct {
-	Algorithm AlgorithmIdentifier
-	PublicKey BitString
-}
-
-func TestCertificate(t *testing.T) {
-	// This is a minimal, self-signed certificate that should parse correctly.
-	var cert Certificate
-	if _, err := Unmarshal(derEncodedSelfSignedCertBytes, &cert); err != nil {
-		t.Errorf("Unmarshal failed: %v", err)
-	}
-	if !reflect.DeepEqual(cert, derEncodedSelfSignedCert) {
-		t.Errorf("Bad result:\ngot: %+v\nwant: %+v", cert, derEncodedSelfSignedCert)
-	}
-}
-
-func TestCertificateWithNUL(t *testing.T) {
-	// This is the paypal NUL-hack certificate. It should fail to parse because
-	// NUL isn't a permitted character in a PrintableString.
-
-	var cert Certificate
-	if _, err := Unmarshal(derEncodedPaypalNULCertBytes, &cert); err == nil {
-		t.Error("Unmarshal succeeded, should not have")
-	}
-}
-
-type rawStructTest struct {
-	Raw RawContent
-	A   int
-}
-
-func TestRawStructs(t *testing.T) {
-	var s rawStructTest
-	input := []byte{0x30, 0x03, 0x02, 0x01, 0x50}
-
-	rest, err := Unmarshal(input, &s)
-	if len(rest) != 0 {
-		t.Errorf("incomplete parse: %x", rest)
-		return
-	}
-	if err != nil {
-		t.Error(err)
-		return
-	}
-	if s.A != 0x50 {
-		t.Errorf("bad value for A: got %d want %d", s.A, 0x50)
-	}
-	if !bytes.Equal([]byte(s.Raw), input) {
-		t.Errorf("bad value for Raw: got %x want %x", s.Raw, input)
-	}
-}
-
-type oiEqualTest struct {
-	first  ObjectIdentifier
-	second ObjectIdentifier
-	same   bool
-}
-
-var oiEqualTests = []oiEqualTest{
-	{
-		ObjectIdentifier{1, 2, 3},
-		ObjectIdentifier{1, 2, 3},
-		true,
-	},
-	{
-		ObjectIdentifier{1},
-		ObjectIdentifier{1, 2, 3},
-		false,
-	},
-	{
-		ObjectIdentifier{1, 2, 3},
-		ObjectIdentifier{10, 11, 12},
-		false,
-	},
-}
-
-func TestObjectIdentifierEqual(t *testing.T) {
-	for _, o := range oiEqualTests {
-		if s := o.first.Equal(o.second); s != o.same {
-			t.Errorf("ObjectIdentifier.Equal: got: %t want: %t", s, o.same)
-		}
-	}
-}
-
-var derEncodedSelfSignedCert = Certificate{
-	TBSCertificate: TBSCertificate{
-		Version:            0,
-		SerialNumber:       RawValue{Class: 0, Tag: 2, IsCompound: false, Bytes: []uint8{0x0, 0x8c, 0xc3, 0x37, 0x92, 0x10, 0xec, 0x2c, 0x98}, FullBytes: []byte{2, 9, 0x0, 0x8c, 0xc3, 0x37, 0x92, 0x10, 0xec, 0x2c, 0x98}},
-		SignatureAlgorithm: AlgorithmIdentifier{Algorithm: ObjectIdentifier{1, 2, 840, 113549, 1, 1, 5}},
-		Issuer: RDNSequence{
-			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 6}, Value: "XX"}},
-			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 8}, Value: "Some-State"}},
-			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 7}, Value: "City"}},
-			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 10}, Value: "Internet Widgits Pty Ltd"}},
-			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 3}, Value: "false.example.com"}},
-			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{1, 2, 840, 113549, 1, 9, 1}, Value: "false at example.com"}},
-		},
-		Validity: Validity{
-			NotBefore: time.Date(2009, 10, 8, 00, 25, 53, 0, time.UTC),
-			NotAfter:  time.Date(2010, 10, 8, 00, 25, 53, 0, time.UTC),
-		},
-		Subject: RDNSequence{
-			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 6}, Value: "XX"}},
-			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 8}, Value: "Some-State"}},
-			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 7}, Value: "City"}},
-			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 10}, Value: "Internet Widgits Pty Ltd"}},
-			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 3}, Value: "false.example.com"}},
-			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{1, 2, 840, 113549, 1, 9, 1}, Value: "false at example.com"}},
-		},
-		PublicKey: PublicKeyInfo{
-			Algorithm: AlgorithmIdentifier{Algorithm: ObjectIdentifier{1, 2, 840, 113549, 1, 1, 1}},
-			PublicKey: BitString{
-				Bytes: []uint8{
-					0x30, 0x48, 0x2, 0x41, 0x0, 0xcd, 0xb7,
-					0x63, 0x9c, 0x32, 0x78, 0xf0, 0x6, 0xaa, 0x27, 0x7f, 0x6e, 0xaf, 0x42,
-					0x90, 0x2b, 0x59, 0x2d, 0x8c, 0xbc, 0xbe, 0x38, 0xa1, 0xc9, 0x2b, 0xa4,
-					0x69, 0x5a, 0x33, 0x1b, 0x1d, 0xea, 0xde, 0xad, 0xd8, 0xe9, 0xa5, 0xc2,
-					0x7e, 0x8c, 0x4c, 0x2f, 0xd0, 0xa8, 0x88, 0x96, 0x57, 0x72, 0x2a, 0x4f,
-					0x2a, 0xf7, 0x58, 0x9c, 0xf2, 0xc7, 0x70, 0x45, 0xdc, 0x8f, 0xde, 0xec,
-					0x35, 0x7d, 0x2, 0x3, 0x1, 0x0, 0x1,
-				},
-				BitLength: 592,
-			},
-		},
-	},
-	SignatureAlgorithm: AlgorithmIdentifier{Algorithm: ObjectIdentifier{1, 2, 840, 113549, 1, 1, 5}},
-	SignatureValue: BitString{
-		Bytes: []uint8{
-			0xa6, 0x7b, 0x6, 0xec, 0x5e, 0xce,
-			0x92, 0x77, 0x2c, 0xa4, 0x13, 0xcb, 0xa3, 0xca, 0x12, 0x56, 0x8f, 0xdc, 0x6c,
-			0x7b, 0x45, 0x11, 0xcd, 0x40, 0xa7, 0xf6, 0x59, 0x98, 0x4, 0x2, 0xdf, 0x2b,
-			0x99, 0x8b, 0xb9, 0xa4, 0xa8, 0xcb, 0xeb, 0x34, 0xc0, 0xf0, 0xa7, 0x8c, 0xf8,
-			0xd9, 0x1e, 0xde, 0x14, 0xa5, 0xed, 0x76, 0xbf, 0x11, 0x6f, 0xe3, 0x60, 0xaa,
-			0xfa, 0x88, 0x21, 0x49, 0x4, 0x35,
-		},
-		BitLength: 512,
-	},
-}
-
-var derEncodedSelfSignedCertBytes = []byte{
-	0x30, 0x82, 0x02, 0x18, 0x30,
-	0x82, 0x01, 0xc2, 0x02, 0x09, 0x00, 0x8c, 0xc3, 0x37, 0x92, 0x10, 0xec, 0x2c,
-	0x98, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
-	0x05, 0x05, 0x00, 0x30, 0x81, 0x92, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
-	0x04, 0x06, 0x13, 0x02, 0x58, 0x58, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55,
-	0x04, 0x08, 0x13, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74,
-	0x65, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x04, 0x43,
-	0x69, 0x74, 0x79, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
-	0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64,
-	0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, 0x31,
-	0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x66, 0x61, 0x6c,
-	0x73, 0x65, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f,
-	0x6d, 0x31, 0x20, 0x30, 0x1e, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
-	0x01, 0x09, 0x01, 0x16, 0x11, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x40, 0x65, 0x78,
-	0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d,
-	0x30, 0x39, 0x31, 0x30, 0x30, 0x38, 0x30, 0x30, 0x32, 0x35, 0x35, 0x33, 0x5a,
-	0x17, 0x0d, 0x31, 0x30, 0x31, 0x30, 0x30, 0x38, 0x30, 0x30, 0x32, 0x35, 0x35,
-	0x33, 0x5a, 0x30, 0x81, 0x92, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
-	0x06, 0x13, 0x02, 0x58, 0x58, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04,
-	0x08, 0x13, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65,
-	0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x04, 0x43, 0x69,
-	0x74, 0x79, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x18,
-	0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67,
-	0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, 0x31, 0x1a,
-	0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x66, 0x61, 0x6c, 0x73,
-	0x65, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d,
-	0x31, 0x20, 0x30, 0x1e, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
-	0x09, 0x01, 0x16, 0x11, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x40, 0x65, 0x78, 0x61,
-	0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x5c, 0x30, 0x0d, 0x06,
-	0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03,
-	0x4b, 0x00, 0x30, 0x48, 0x02, 0x41, 0x00, 0xcd, 0xb7, 0x63, 0x9c, 0x32, 0x78,
-	0xf0, 0x06, 0xaa, 0x27, 0x7f, 0x6e, 0xaf, 0x42, 0x90, 0x2b, 0x59, 0x2d, 0x8c,
-	0xbc, 0xbe, 0x38, 0xa1, 0xc9, 0x2b, 0xa4, 0x69, 0x5a, 0x33, 0x1b, 0x1d, 0xea,
-	0xde, 0xad, 0xd8, 0xe9, 0xa5, 0xc2, 0x7e, 0x8c, 0x4c, 0x2f, 0xd0, 0xa8, 0x88,
-	0x96, 0x57, 0x72, 0x2a, 0x4f, 0x2a, 0xf7, 0x58, 0x9c, 0xf2, 0xc7, 0x70, 0x45,
-	0xdc, 0x8f, 0xde, 0xec, 0x35, 0x7d, 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x0d,
-	0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00,
-	0x03, 0x41, 0x00, 0xa6, 0x7b, 0x06, 0xec, 0x5e, 0xce, 0x92, 0x77, 0x2c, 0xa4,
-	0x13, 0xcb, 0xa3, 0xca, 0x12, 0x56, 0x8f, 0xdc, 0x6c, 0x7b, 0x45, 0x11, 0xcd,
-	0x40, 0xa7, 0xf6, 0x59, 0x98, 0x04, 0x02, 0xdf, 0x2b, 0x99, 0x8b, 0xb9, 0xa4,
-	0xa8, 0xcb, 0xeb, 0x34, 0xc0, 0xf0, 0xa7, 0x8c, 0xf8, 0xd9, 0x1e, 0xde, 0x14,
-	0xa5, 0xed, 0x76, 0xbf, 0x11, 0x6f, 0xe3, 0x60, 0xaa, 0xfa, 0x88, 0x21, 0x49,
-	0x04, 0x35,
-}
-
-var derEncodedPaypalNULCertBytes = []byte{
-	0x30, 0x82, 0x06, 0x44, 0x30,
-	0x82, 0x05, 0xad, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x03, 0x00, 0xf0, 0x9b,
-	0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05,
-	0x05, 0x00, 0x30, 0x82, 0x01, 0x12, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
-	0x04, 0x06, 0x13, 0x02, 0x45, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55,
-	0x04, 0x08, 0x13, 0x09, 0x42, 0x61, 0x72, 0x63, 0x65, 0x6c, 0x6f, 0x6e, 0x61,
-	0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x09, 0x42, 0x61,
-	0x72, 0x63, 0x65, 0x6c, 0x6f, 0x6e, 0x61, 0x31, 0x29, 0x30, 0x27, 0x06, 0x03,
-	0x55, 0x04, 0x0a, 0x13, 0x20, 0x49, 0x50, 0x53, 0x20, 0x43, 0x65, 0x72, 0x74,
-	0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74,
-	0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x73, 0x2e, 0x6c, 0x2e, 0x31, 0x2e,
-	0x30, 0x2c, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x14, 0x25, 0x67, 0x65, 0x6e, 0x65,
-	0x72, 0x61, 0x6c, 0x40, 0x69, 0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d,
-	0x20, 0x43, 0x2e, 0x49, 0x2e, 0x46, 0x2e, 0x20, 0x20, 0x42, 0x2d, 0x42, 0x36,
-	0x32, 0x32, 0x31, 0x30, 0x36, 0x39, 0x35, 0x31, 0x2e, 0x30, 0x2c, 0x06, 0x03,
-	0x55, 0x04, 0x0b, 0x13, 0x25, 0x69, 0x70, 0x73, 0x43, 0x41, 0x20, 0x43, 0x4c,
-	0x41, 0x53, 0x45, 0x41, 0x31, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
-	0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72,
-	0x69, 0x74, 0x79, 0x31, 0x2e, 0x30, 0x2c, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
-	0x25, 0x69, 0x70, 0x73, 0x43, 0x41, 0x20, 0x43, 0x4c, 0x41, 0x53, 0x45, 0x41,
-	0x31, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69,
-	0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31,
-	0x20, 0x30, 0x1e, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09,
-	0x01, 0x16, 0x11, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x40, 0x69, 0x70,
-	0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x39,
-	0x30, 0x32, 0x32, 0x34, 0x32, 0x33, 0x30, 0x34, 0x31, 0x37, 0x5a, 0x17, 0x0d,
-	0x31, 0x31, 0x30, 0x32, 0x32, 0x34, 0x32, 0x33, 0x30, 0x34, 0x31, 0x37, 0x5a,
-	0x30, 0x81, 0x94, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
-	0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13,
-	0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x16,
-	0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0d, 0x53, 0x61, 0x6e, 0x20,
-	0x46, 0x72, 0x61, 0x6e, 0x63, 0x69, 0x73, 0x63, 0x6f, 0x31, 0x11, 0x30, 0x0f,
-	0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x08, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69,
-	0x74, 0x79, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x0b,
-	0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x55, 0x6e, 0x69, 0x74, 0x31, 0x2f,
-	0x30, 0x2d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x26, 0x77, 0x77, 0x77, 0x2e,
-	0x70, 0x61, 0x79, 0x70, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x73, 0x73,
-	0x6c, 0x2e, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x63, 0x6f, 0x6e, 0x6e, 0x65,
-	0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x63, 0x63, 0x30, 0x81, 0x9f, 0x30, 0x0d,
-	0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00,
-	0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xd2, 0x69,
-	0xfa, 0x6f, 0x3a, 0x00, 0xb4, 0x21, 0x1b, 0xc8, 0xb1, 0x02, 0xd7, 0x3f, 0x19,
-	0xb2, 0xc4, 0x6d, 0xb4, 0x54, 0xf8, 0x8b, 0x8a, 0xcc, 0xdb, 0x72, 0xc2, 0x9e,
-	0x3c, 0x60, 0xb9, 0xc6, 0x91, 0x3d, 0x82, 0xb7, 0x7d, 0x99, 0xff, 0xd1, 0x29,
-	0x84, 0xc1, 0x73, 0x53, 0x9c, 0x82, 0xdd, 0xfc, 0x24, 0x8c, 0x77, 0xd5, 0x41,
-	0xf3, 0xe8, 0x1e, 0x42, 0xa1, 0xad, 0x2d, 0x9e, 0xff, 0x5b, 0x10, 0x26, 0xce,
-	0x9d, 0x57, 0x17, 0x73, 0x16, 0x23, 0x38, 0xc8, 0xd6, 0xf1, 0xba, 0xa3, 0x96,
-	0x5b, 0x16, 0x67, 0x4a, 0x4f, 0x73, 0x97, 0x3a, 0x4d, 0x14, 0xa4, 0xf4, 0xe2,
-	0x3f, 0x8b, 0x05, 0x83, 0x42, 0xd1, 0xd0, 0xdc, 0x2f, 0x7a, 0xe5, 0xb6, 0x10,
-	0xb2, 0x11, 0xc0, 0xdc, 0x21, 0x2a, 0x90, 0xff, 0xae, 0x97, 0x71, 0x5a, 0x49,
-	0x81, 0xac, 0x40, 0xf3, 0x3b, 0xb8, 0x59, 0xb2, 0x4f, 0x02, 0x03, 0x01, 0x00,
-	0x01, 0xa3, 0x82, 0x03, 0x21, 0x30, 0x82, 0x03, 0x1d, 0x30, 0x09, 0x06, 0x03,
-	0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x11, 0x06, 0x09, 0x60, 0x86,
-	0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x01, 0x04, 0x04, 0x03, 0x02, 0x06, 0x40,
-	0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x03, 0xf8,
-	0x30, 0x13, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x0c, 0x30, 0x0a, 0x06, 0x08,
-	0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x30, 0x1d, 0x06, 0x03, 0x55,
-	0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x61, 0x8f, 0x61, 0x34, 0x43, 0x55, 0x14,
-	0x7f, 0x27, 0x09, 0xce, 0x4c, 0x8b, 0xea, 0x9b, 0x7b, 0x19, 0x25, 0xbc, 0x6e,
-	0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14,
-	0x0e, 0x07, 0x60, 0xd4, 0x39, 0xc9, 0x1b, 0x5b, 0x5d, 0x90, 0x7b, 0x23, 0xc8,
-	0xd2, 0x34, 0x9d, 0x4a, 0x9a, 0x46, 0x39, 0x30, 0x09, 0x06, 0x03, 0x55, 0x1d,
-	0x11, 0x04, 0x02, 0x30, 0x00, 0x30, 0x1c, 0x06, 0x03, 0x55, 0x1d, 0x12, 0x04,
-	0x15, 0x30, 0x13, 0x81, 0x11, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x40,
-	0x69, 0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x72, 0x06, 0x09,
-	0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x0d, 0x04, 0x65, 0x16, 0x63,
-	0x4f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20,
-	0x49, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x4e,
-	0x4f, 0x54, 0x20, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x41, 0x54, 0x45, 0x44, 0x2e,
-	0x20, 0x43, 0x4c, 0x41, 0x53, 0x45, 0x41, 0x31, 0x20, 0x53, 0x65, 0x72, 0x76,
-	0x65, 0x72, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74,
-	0x65, 0x20, 0x69, 0x73, 0x73, 0x75, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x68,
-	0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x70,
-	0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x30, 0x2f, 0x06, 0x09, 0x60,
-	0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x02, 0x04, 0x22, 0x16, 0x20, 0x68,
-	0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x70,
-	0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61,
-	0x32, 0x30, 0x30, 0x32, 0x2f, 0x30, 0x43, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
-	0x86, 0xf8, 0x42, 0x01, 0x04, 0x04, 0x36, 0x16, 0x34, 0x68, 0x74, 0x74, 0x70,
-	0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x70, 0x73, 0x63, 0x61,
-	0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61, 0x32, 0x30, 0x30,
-	0x32, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61, 0x32, 0x30, 0x30, 0x32, 0x43, 0x4c,
-	0x41, 0x53, 0x45, 0x41, 0x31, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x46, 0x06, 0x09,
-	0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x03, 0x04, 0x39, 0x16, 0x37,
-	0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69,
-	0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x70, 0x73, 0x63,
-	0x61, 0x32, 0x30, 0x30, 0x32, 0x2f, 0x72, 0x65, 0x76, 0x6f, 0x63, 0x61, 0x74,
-	0x69, 0x6f, 0x6e, 0x43, 0x4c, 0x41, 0x53, 0x45, 0x41, 0x31, 0x2e, 0x68, 0x74,
-	0x6d, 0x6c, 0x3f, 0x30, 0x43, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8,
-	0x42, 0x01, 0x07, 0x04, 0x36, 0x16, 0x34, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a,
-	0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x70, 0x73, 0x63, 0x61, 0x2e, 0x63,
-	0x6f, 0x6d, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61, 0x32, 0x30, 0x30, 0x32, 0x2f,
-	0x72, 0x65, 0x6e, 0x65, 0x77, 0x61, 0x6c, 0x43, 0x4c, 0x41, 0x53, 0x45, 0x41,
-	0x31, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x3f, 0x30, 0x41, 0x06, 0x09, 0x60, 0x86,
-	0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x08, 0x04, 0x34, 0x16, 0x32, 0x68, 0x74,
-	0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x70, 0x73,
-	0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61, 0x32,
-	0x30, 0x30, 0x32, 0x2f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x43, 0x4c, 0x41,
-	0x53, 0x45, 0x41, 0x31, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x30, 0x81, 0x83, 0x06,
-	0x03, 0x55, 0x1d, 0x1f, 0x04, 0x7c, 0x30, 0x7a, 0x30, 0x39, 0xa0, 0x37, 0xa0,
-	0x35, 0x86, 0x33, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77,
-	0x2e, 0x69, 0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x70,
-	0x73, 0x63, 0x61, 0x32, 0x30, 0x30, 0x32, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61,
-	0x32, 0x30, 0x30, 0x32, 0x43, 0x4c, 0x41, 0x53, 0x45, 0x41, 0x31, 0x2e, 0x63,
-	0x72, 0x6c, 0x30, 0x3d, 0xa0, 0x3b, 0xa0, 0x39, 0x86, 0x37, 0x68, 0x74, 0x74,
-	0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x62, 0x61, 0x63, 0x6b, 0x2e, 0x69,
-	0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x70, 0x73, 0x63,
-	0x61, 0x32, 0x30, 0x30, 0x32, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61, 0x32, 0x30,
-	0x30, 0x32, 0x43, 0x4c, 0x41, 0x53, 0x45, 0x41, 0x31, 0x2e, 0x63, 0x72, 0x6c,
-	0x30, 0x32, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04,
-	0x26, 0x30, 0x24, 0x30, 0x22, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
-	0x30, 0x01, 0x86, 0x16, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63,
-	0x73, 0x70, 0x2e, 0x69, 0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
-	0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05,
-	0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x68, 0xee, 0x79, 0x97, 0x97, 0xdd, 0x3b,
-	0xef, 0x16, 0x6a, 0x06, 0xf2, 0x14, 0x9a, 0x6e, 0xcd, 0x9e, 0x12, 0xf7, 0xaa,
-	0x83, 0x10, 0xbd, 0xd1, 0x7c, 0x98, 0xfa, 0xc7, 0xae, 0xd4, 0x0e, 0x2c, 0x9e,
-	0x38, 0x05, 0x9d, 0x52, 0x60, 0xa9, 0x99, 0x0a, 0x81, 0xb4, 0x98, 0x90, 0x1d,
-	0xae, 0xbb, 0x4a, 0xd7, 0xb9, 0xdc, 0x88, 0x9e, 0x37, 0x78, 0x41, 0x5b, 0xf7,
-	0x82, 0xa5, 0xf2, 0xba, 0x41, 0x25, 0x5a, 0x90, 0x1a, 0x1e, 0x45, 0x38, 0xa1,
-	0x52, 0x58, 0x75, 0x94, 0x26, 0x44, 0xfb, 0x20, 0x07, 0xba, 0x44, 0xcc, 0xe5,
-	0x4a, 0x2d, 0x72, 0x3f, 0x98, 0x47, 0xf6, 0x26, 0xdc, 0x05, 0x46, 0x05, 0x07,
-	0x63, 0x21, 0xab, 0x46, 0x9b, 0x9c, 0x78, 0xd5, 0x54, 0x5b, 0x3d, 0x0c, 0x1e,
-	0xc8, 0x64, 0x8c, 0xb5, 0x50, 0x23, 0x82, 0x6f, 0xdb, 0xb8, 0x22, 0x1c, 0x43,
-	0x96, 0x07, 0xa8, 0xbb,
-}
-
-var stringSliceTestData = [][]string{
-	{"foo", "bar"},
-	{"foo", "\\bar"},
-	{"foo", "\"bar\""},
-	{"foo", "åäö"},
-}
-
-func TestStringSlice(t *testing.T) {
-	for _, test := range stringSliceTestData {
-		bs, err := Marshal(test)
-		if err != nil {
-			t.Error(err)
-		}
-
-		var res []string
-		_, err = Unmarshal(bs, &res)
-		if err != nil {
-			t.Error(err)
-		}
-
-		if fmt.Sprintf("%v", res) != fmt.Sprintf("%v", test) {
-			t.Errorf("incorrect marshal/unmarshal; %v != %v", res, test)
-		}
-	}
-}
diff --git a/src/pkg/encoding/asn1/marshal.go b/src/pkg/encoding/asn1/marshal.go
deleted file mode 100644
index e26fe59..0000000
--- a/src/pkg/encoding/asn1/marshal.go
+++ /dev/null
@@ -1,632 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package asn1
-
-import (
-	"bytes"
-	"errors"
-	"fmt"
-	"io"
-	"math/big"
-	"reflect"
-	"time"
-	"unicode/utf8"
-)
-
-// A forkableWriter is an in-memory buffer that can be
-// 'forked' to create new forkableWriters that bracket the
-// original.  After
-//    pre, post := w.fork();
-// the overall sequence of bytes represented is logically w+pre+post.
-type forkableWriter struct {
-	*bytes.Buffer
-	pre, post *forkableWriter
-}
-
-func newForkableWriter() *forkableWriter {
-	return &forkableWriter{new(bytes.Buffer), nil, nil}
-}
-
-func (f *forkableWriter) fork() (pre, post *forkableWriter) {
-	if f.pre != nil || f.post != nil {
-		panic("have already forked")
-	}
-	f.pre = newForkableWriter()
-	f.post = newForkableWriter()
-	return f.pre, f.post
-}
-
-func (f *forkableWriter) Len() (l int) {
-	l += f.Buffer.Len()
-	if f.pre != nil {
-		l += f.pre.Len()
-	}
-	if f.post != nil {
-		l += f.post.Len()
-	}
-	return
-}
-
-func (f *forkableWriter) writeTo(out io.Writer) (n int, err error) {
-	n, err = out.Write(f.Bytes())
-	if err != nil {
-		return
-	}
-
-	var nn int
-
-	if f.pre != nil {
-		nn, err = f.pre.writeTo(out)
-		n += nn
-		if err != nil {
-			return
-		}
-	}
-
-	if f.post != nil {
-		nn, err = f.post.writeTo(out)
-		n += nn
-	}
-	return
-}
-
-func marshalBase128Int(out *forkableWriter, n int64) (err error) {
-	if n == 0 {
-		err = out.WriteByte(0)
-		return
-	}
-
-	l := 0
-	for i := n; i > 0; i >>= 7 {
-		l++
-	}
-
-	for i := l - 1; i >= 0; i-- {
-		o := byte(n >> uint(i*7))
-		o &= 0x7f
-		if i != 0 {
-			o |= 0x80
-		}
-		err = out.WriteByte(o)
-		if err != nil {
-			return
-		}
-	}
-
-	return nil
-}
-
-func marshalInt64(out *forkableWriter, i int64) (err error) {
-	n := int64Length(i)
-
-	for ; n > 0; n-- {
-		err = out.WriteByte(byte(i >> uint((n-1)*8)))
-		if err != nil {
-			return
-		}
-	}
-
-	return nil
-}
-
-func int64Length(i int64) (numBytes int) {
-	numBytes = 1
-
-	for i > 127 {
-		numBytes++
-		i >>= 8
-	}
-
-	for i < -128 {
-		numBytes++
-		i >>= 8
-	}
-
-	return
-}
-
-func marshalBigInt(out *forkableWriter, n *big.Int) (err error) {
-	if n.Sign() < 0 {
-		// A negative number has to be converted to two's-complement
-		// form. So we'll subtract 1 and invert. If the
-		// most-significant-bit isn't set then we'll need to pad the
-		// beginning with 0xff in order to keep the number negative.
-		nMinus1 := new(big.Int).Neg(n)
-		nMinus1.Sub(nMinus1, bigOne)
-		bytes := nMinus1.Bytes()
-		for i := range bytes {
-			bytes[i] ^= 0xff
-		}
-		if len(bytes) == 0 || bytes[0]&0x80 == 0 {
-			err = out.WriteByte(0xff)
-			if err != nil {
-				return
-			}
-		}
-		_, err = out.Write(bytes)
-	} else if n.Sign() == 0 {
-		// Zero is written as a single 0 zero rather than no bytes.
-		err = out.WriteByte(0x00)
-	} else {
-		bytes := n.Bytes()
-		if len(bytes) > 0 && bytes[0]&0x80 != 0 {
-			// We'll have to pad this with 0x00 in order to stop it
-			// looking like a negative number.
-			err = out.WriteByte(0)
-			if err != nil {
-				return
-			}
-		}
-		_, err = out.Write(bytes)
-	}
-	return
-}
-
-func marshalLength(out *forkableWriter, i int) (err error) {
-	n := lengthLength(i)
-
-	for ; n > 0; n-- {
-		err = out.WriteByte(byte(i >> uint((n-1)*8)))
-		if err != nil {
-			return
-		}
-	}
-
-	return nil
-}
-
-func lengthLength(i int) (numBytes int) {
-	numBytes = 1
-	for i > 255 {
-		numBytes++
-		i >>= 8
-	}
-	return
-}
-
-func marshalTagAndLength(out *forkableWriter, t tagAndLength) (err error) {
-	b := uint8(t.class) << 6
-	if t.isCompound {
-		b |= 0x20
-	}
-	if t.tag >= 31 {
-		b |= 0x1f
-		err = out.WriteByte(b)
-		if err != nil {
-			return
-		}
-		err = marshalBase128Int(out, int64(t.tag))
-		if err != nil {
-			return
-		}
-	} else {
-		b |= uint8(t.tag)
-		err = out.WriteByte(b)
-		if err != nil {
-			return
-		}
-	}
-
-	if t.length >= 128 {
-		l := lengthLength(t.length)
-		err = out.WriteByte(0x80 | byte(l))
-		if err != nil {
-			return
-		}
-		err = marshalLength(out, t.length)
-		if err != nil {
-			return
-		}
-	} else {
-		err = out.WriteByte(byte(t.length))
-		if err != nil {
-			return
-		}
-	}
-
-	return nil
-}
-
-func marshalBitString(out *forkableWriter, b BitString) (err error) {
-	paddingBits := byte((8 - b.BitLength%8) % 8)
-	err = out.WriteByte(paddingBits)
-	if err != nil {
-		return
-	}
-	_, err = out.Write(b.Bytes)
-	return
-}
-
-func marshalObjectIdentifier(out *forkableWriter, oid []int) (err error) {
-	if len(oid) < 2 || oid[0] > 2 || (oid[0] < 2 && oid[1] >= 40) {
-		return StructuralError{"invalid object identifier"}
-	}
-
-	err = marshalBase128Int(out, int64(oid[0]*40+oid[1]))
-	if err != nil {
-		return
-	}
-	for i := 2; i < len(oid); i++ {
-		err = marshalBase128Int(out, int64(oid[i]))
-		if err != nil {
-			return
-		}
-	}
-
-	return
-}
-
-func marshalPrintableString(out *forkableWriter, s string) (err error) {
-	b := []byte(s)
-	for _, c := range b {
-		if !isPrintable(c) {
-			return StructuralError{"PrintableString contains invalid character"}
-		}
-	}
-
-	_, err = out.Write(b)
-	return
-}
-
-func marshalIA5String(out *forkableWriter, s string) (err error) {
-	b := []byte(s)
-	for _, c := range b {
-		if c > 127 {
-			return StructuralError{"IA5String contains invalid character"}
-		}
-	}
-
-	_, err = out.Write(b)
-	return
-}
-
-func marshalUTF8String(out *forkableWriter, s string) (err error) {
-	_, err = out.Write([]byte(s))
-	return
-}
-
-func marshalTwoDigits(out *forkableWriter, v int) (err error) {
-	err = out.WriteByte(byte('0' + (v/10)%10))
-	if err != nil {
-		return
-	}
-	return out.WriteByte(byte('0' + v%10))
-}
-
-func marshalFourDigits(out *forkableWriter, v int) (err error) {
-	var bytes [4]byte
-	for i := range bytes {
-		bytes[3-i] = '0' + byte(v%10)
-		v /= 10
-	}
-	_, err = out.Write(bytes[:])
-	return
-}
-
-func outsideUTCRange(t time.Time) bool {
-	year := t.Year()
-	return year < 1950 || year >= 2050
-}
-
-func marshalUTCTime(out *forkableWriter, t time.Time) (err error) {
-	year := t.Year()
-
-	switch {
-	case 1950 <= year && year < 2000:
-		err = marshalTwoDigits(out, int(year-1900))
-	case 2000 <= year && year < 2050:
-		err = marshalTwoDigits(out, int(year-2000))
-	default:
-		return StructuralError{"cannot represent time as UTCTime"}
-	}
-	if err != nil {
-		return
-	}
-
-	return marshalTimeCommon(out, t)
-}
-
-func marshalGeneralizedTime(out *forkableWriter, t time.Time) (err error) {
-	year := t.Year()
-	if year < 0 || year > 9999 {
-		return StructuralError{"cannot represent time as GeneralizedTime"}
-	}
-	if err = marshalFourDigits(out, year); err != nil {
-		return
-	}
-
-	return marshalTimeCommon(out, t)
-}
-
-func marshalTimeCommon(out *forkableWriter, t time.Time) (err error) {
-	_, month, day := t.Date()
-
-	err = marshalTwoDigits(out, int(month))
-	if err != nil {
-		return
-	}
-
-	err = marshalTwoDigits(out, day)
-	if err != nil {
-		return
-	}
-
-	hour, min, sec := t.Clock()
-
-	err = marshalTwoDigits(out, hour)
-	if err != nil {
-		return
-	}
-
-	err = marshalTwoDigits(out, min)
-	if err != nil {
-		return
-	}
-
-	err = marshalTwoDigits(out, sec)
-	if err != nil {
-		return
-	}
-
-	_, offset := t.Zone()
-
-	switch {
-	case offset/60 == 0:
-		err = out.WriteByte('Z')
-		return
-	case offset > 0:
-		err = out.WriteByte('+')
-	case offset < 0:
-		err = out.WriteByte('-')
-	}
-
-	if err != nil {
-		return
-	}
-
-	offsetMinutes := offset / 60
-	if offsetMinutes < 0 {
-		offsetMinutes = -offsetMinutes
-	}
-
-	err = marshalTwoDigits(out, offsetMinutes/60)
-	if err != nil {
-		return
-	}
-
-	err = marshalTwoDigits(out, offsetMinutes%60)
-	return
-}
-
-func stripTagAndLength(in []byte) []byte {
-	_, offset, err := parseTagAndLength(in, 0)
-	if err != nil {
-		return in
-	}
-	return in[offset:]
-}
-
-func marshalBody(out *forkableWriter, value reflect.Value, params fieldParameters) (err error) {
-	switch value.Type() {
-	case timeType:
-		t := value.Interface().(time.Time)
-		if outsideUTCRange(t) {
-			return marshalGeneralizedTime(out, t)
-		} else {
-			return marshalUTCTime(out, t)
-		}
-	case bitStringType:
-		return marshalBitString(out, value.Interface().(BitString))
-	case objectIdentifierType:
-		return marshalObjectIdentifier(out, value.Interface().(ObjectIdentifier))
-	case bigIntType:
-		return marshalBigInt(out, value.Interface().(*big.Int))
-	}
-
-	switch v := value; v.Kind() {
-	case reflect.Bool:
-		if v.Bool() {
-			return out.WriteByte(255)
-		} else {
-			return out.WriteByte(0)
-		}
-	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-		return marshalInt64(out, int64(v.Int()))
-	case reflect.Struct:
-		t := v.Type()
-
-		startingField := 0
-
-		// If the first element of the structure is a non-empty
-		// RawContents, then we don't bother serializing the rest.
-		if t.NumField() > 0 && t.Field(0).Type == rawContentsType {
-			s := v.Field(0)
-			if s.Len() > 0 {
-				bytes := make([]byte, s.Len())
-				for i := 0; i < s.Len(); i++ {
-					bytes[i] = uint8(s.Index(i).Uint())
-				}
-				/* The RawContents will contain the tag and
-				 * length fields but we'll also be writing
-				 * those ourselves, so we strip them out of
-				 * bytes */
-				_, err = out.Write(stripTagAndLength(bytes))
-				return
-			} else {
-				startingField = 1
-			}
-		}
-
-		for i := startingField; i < t.NumField(); i++ {
-			var pre *forkableWriter
-			pre, out = out.fork()
-			err = marshalField(pre, v.Field(i), parseFieldParameters(t.Field(i).Tag.Get("asn1")))
-			if err != nil {
-				return
-			}
-		}
-		return
-	case reflect.Slice:
-		sliceType := v.Type()
-		if sliceType.Elem().Kind() == reflect.Uint8 {
-			bytes := make([]byte, v.Len())
-			for i := 0; i < v.Len(); i++ {
-				bytes[i] = uint8(v.Index(i).Uint())
-			}
-			_, err = out.Write(bytes)
-			return
-		}
-
-		var fp fieldParameters
-		for i := 0; i < v.Len(); i++ {
-			var pre *forkableWriter
-			pre, out = out.fork()
-			err = marshalField(pre, v.Index(i), fp)
-			if err != nil {
-				return
-			}
-		}
-		return
-	case reflect.String:
-		switch params.stringType {
-		case tagIA5String:
-			return marshalIA5String(out, v.String())
-		case tagPrintableString:
-			return marshalPrintableString(out, v.String())
-		default:
-			return marshalUTF8String(out, v.String())
-		}
-	}
-
-	return StructuralError{"unknown Go type"}
-}
-
-func marshalField(out *forkableWriter, v reflect.Value, params fieldParameters) (err error) {
-	// If the field is an interface{} then recurse into it.
-	if v.Kind() == reflect.Interface && v.Type().NumMethod() == 0 {
-		return marshalField(out, v.Elem(), params)
-	}
-
-	if v.Kind() == reflect.Slice && v.Len() == 0 && params.omitEmpty {
-		return
-	}
-
-	if params.optional && reflect.DeepEqual(v.Interface(), reflect.Zero(v.Type()).Interface()) {
-		return
-	}
-
-	if v.Type() == rawValueType {
-		rv := v.Interface().(RawValue)
-		if len(rv.FullBytes) != 0 {
-			_, err = out.Write(rv.FullBytes)
-		} else {
-			err = marshalTagAndLength(out, tagAndLength{rv.Class, rv.Tag, len(rv.Bytes), rv.IsCompound})
-			if err != nil {
-				return
-			}
-			_, err = out.Write(rv.Bytes)
-		}
-		return
-	}
-
-	tag, isCompound, ok := getUniversalType(v.Type())
-	if !ok {
-		err = StructuralError{fmt.Sprintf("unknown Go type: %v", v.Type())}
-		return
-	}
-	class := classUniversal
-
-	if params.stringType != 0 && tag != tagPrintableString {
-		return StructuralError{"explicit string type given to non-string member"}
-	}
-
-	switch tag {
-	case tagPrintableString:
-		if params.stringType == 0 {
-			// This is a string without an explicit string type. We'll use
-			// a PrintableString if the character set in the string is
-			// sufficiently limited, otherwise we'll use a UTF8String.
-			for _, r := range v.String() {
-				if r >= utf8.RuneSelf || !isPrintable(byte(r)) {
-					if !utf8.ValidString(v.String()) {
-						return errors.New("asn1: string not valid UTF-8")
-					}
-					tag = tagUTF8String
-					break
-				}
-			}
-		} else {
-			tag = params.stringType
-		}
-	case tagUTCTime:
-		if outsideUTCRange(v.Interface().(time.Time)) {
-			tag = tagGeneralizedTime
-		}
-	}
-
-	if params.set {
-		if tag != tagSequence {
-			return StructuralError{"non sequence tagged as set"}
-		}
-		tag = tagSet
-	}
-
-	tags, body := out.fork()
-
-	err = marshalBody(body, v, params)
-	if err != nil {
-		return
-	}
-
-	bodyLen := body.Len()
-
-	var explicitTag *forkableWriter
-	if params.explicit {
-		explicitTag, tags = tags.fork()
-	}
-
-	if !params.explicit && params.tag != nil {
-		// implicit tag.
-		tag = *params.tag
-		class = classContextSpecific
-	}
-
-	err = marshalTagAndLength(tags, tagAndLength{class, tag, bodyLen, isCompound})
-	if err != nil {
-		return
-	}
-
-	if params.explicit {
-		err = marshalTagAndLength(explicitTag, tagAndLength{
-			class:      classContextSpecific,
-			tag:        *params.tag,
-			length:     bodyLen + tags.Len(),
-			isCompound: true,
-		})
-	}
-
-	return nil
-}
-
-// Marshal returns the ASN.1 encoding of val.
-//
-// In addition to the struct tags recognised by Unmarshal, the following can be
-// used:
-//
-//	ia5:		causes strings to be marshaled as ASN.1, IA5 strings
-//	omitempty:	causes empty slices to be skipped
-//	printable:	causes strings to be marshaled as ASN.1, PrintableString strings.
-//	utf8:		causes strings to be marshaled as ASN.1, UTF8 strings
-func Marshal(val interface{}) ([]byte, error) {
-	var out bytes.Buffer
-	v := reflect.ValueOf(val)
-	f := newForkableWriter()
-	err := marshalField(f, v, fieldParameters{})
-	if err != nil {
-		return nil, err
-	}
-	_, err = f.writeTo(&out)
-	return out.Bytes(), nil
-}
diff --git a/src/pkg/encoding/asn1/marshal_test.go b/src/pkg/encoding/asn1/marshal_test.go
deleted file mode 100644
index a15acbe..0000000
--- a/src/pkg/encoding/asn1/marshal_test.go
+++ /dev/null
@@ -1,157 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package asn1
-
-import (
-	"bytes"
-	"encoding/hex"
-	"math/big"
-	"testing"
-	"time"
-)
-
-type intStruct struct {
-	A int
-}
-
-type twoIntStruct struct {
-	A int
-	B int
-}
-
-type bigIntStruct struct {
-	A *big.Int
-}
-
-type nestedStruct struct {
-	A intStruct
-}
-
-type rawContentsStruct struct {
-	Raw RawContent
-	A   int
-}
-
-type implicitTagTest struct {
-	A int `asn1:"implicit,tag:5"`
-}
-
-type explicitTagTest struct {
-	A int `asn1:"explicit,tag:5"`
-}
-
-type ia5StringTest struct {
-	A string `asn1:"ia5"`
-}
-
-type printableStringTest struct {
-	A string `asn1:"printable"`
-}
-
-type optionalRawValueTest struct {
-	A RawValue `asn1:"optional"`
-}
-
-type omitEmptyTest struct {
-	A []string `asn1:"omitempty"`
-}
-
-type testSET []int
-
-var PST = time.FixedZone("PST", -8*60*60)
-
-type marshalTest struct {
-	in  interface{}
-	out string // hex encoded
-}
-
-func farFuture() time.Time {
-	t, err := time.Parse(time.RFC3339, "2100-04-05T12:01:01Z")
-	if err != nil {
-		panic(err)
-	}
-	return t
-}
-
-var marshalTests = []marshalTest{
-	{10, "02010a"},
-	{127, "02017f"},
-	{128, "02020080"},
-	{-128, "020180"},
-	{-129, "0202ff7f"},
-	{intStruct{64}, "3003020140"},
-	{bigIntStruct{big.NewInt(0x123456)}, "30050203123456"},
-	{twoIntStruct{64, 65}, "3006020140020141"},
-	{nestedStruct{intStruct{127}}, "3005300302017f"},
-	{[]byte{1, 2, 3}, "0403010203"},
-	{implicitTagTest{64}, "3003850140"},
-	{explicitTagTest{64}, "3005a503020140"},
-	{time.Unix(0, 0).UTC(), "170d3730303130313030303030305a"},
-	{time.Unix(1258325776, 0).UTC(), "170d3039313131353232353631365a"},
-	{time.Unix(1258325776, 0).In(PST), "17113039313131353134353631362d30383030"},
-	{farFuture(), "180f32313030303430353132303130315a"},
-	{BitString{[]byte{0x80}, 1}, "03020780"},
-	{BitString{[]byte{0x81, 0xf0}, 12}, "03030481f0"},
-	{ObjectIdentifier([]int{1, 2, 3, 4}), "06032a0304"},
-	{ObjectIdentifier([]int{1, 2, 840, 133549, 1, 1, 5}), "06092a864888932d010105"},
-	{ObjectIdentifier([]int{2, 100, 3}), "0603813403"},
-	{"test", "130474657374"},
-	{
-		"" +
-			"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +
-			"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +
-			"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +
-			"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", // This is 127 times 'x'
-		"137f" +
-			"7878787878787878787878787878787878787878787878787878787878787878" +
-			"7878787878787878787878787878787878787878787878787878787878787878" +
-			"7878787878787878787878787878787878787878787878787878787878787878" +
-			"78787878787878787878787878787878787878787878787878787878787878",
-	},
-	{
-		"" +
-			"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +
-			"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +
-			"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +
-			"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", // This is 128 times 'x'
-		"138180" +
-			"7878787878787878787878787878787878787878787878787878787878787878" +
-			"7878787878787878787878787878787878787878787878787878787878787878" +
-			"7878787878787878787878787878787878787878787878787878787878787878" +
-			"7878787878787878787878787878787878787878787878787878787878787878",
-	},
-	{ia5StringTest{"test"}, "3006160474657374"},
-	{optionalRawValueTest{}, "3000"},
-	{printableStringTest{"test"}, "3006130474657374"},
-	{printableStringTest{"test*"}, "30071305746573742a"},
-	{rawContentsStruct{nil, 64}, "3003020140"},
-	{rawContentsStruct{[]byte{0x30, 3, 1, 2, 3}, 64}, "3003010203"},
-	{RawValue{Tag: 1, Class: 2, IsCompound: false, Bytes: []byte{1, 2, 3}}, "8103010203"},
-	{testSET([]int{10}), "310302010a"},
-	{omitEmptyTest{[]string{}}, "3000"},
-	{omitEmptyTest{[]string{"1"}}, "30053003130131"},
-	{"Σ", "0c02cea3"},
-}
-
-func TestMarshal(t *testing.T) {
-	for i, test := range marshalTests {
-		data, err := Marshal(test.in)
-		if err != nil {
-			t.Errorf("#%d failed: %s", i, err)
-		}
-		out, _ := hex.DecodeString(test.out)
-		if !bytes.Equal(out, data) {
-			t.Errorf("#%d got: %x want %x\n\t%q\n\t%q", i, data, out, data, out)
-
-		}
-	}
-}
-
-func TestInvalidUTF8(t *testing.T) {
-	_, err := Marshal(string([]byte{0xff, 0xff}))
-	if err == nil {
-		t.Errorf("invalid UTF8 string was accepted")
-	}
-}
diff --git a/src/pkg/encoding/base32/base32.go b/src/pkg/encoding/base32/base32.go
deleted file mode 100644
index d770de3..0000000
--- a/src/pkg/encoding/base32/base32.go
+++ /dev/null
@@ -1,428 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package base32 implements base32 encoding as specified by RFC 4648.
-package base32
-
-import (
-	"bytes"
-	"io"
-	"strconv"
-	"strings"
-)
-
-/*
- * Encodings
- */
-
-// An Encoding is a radix 32 encoding/decoding scheme, defined by a
-// 32-character alphabet.  The most common is the "base32" encoding
-// introduced for SASL GSSAPI and standardized in RFC 4648.
-// The alternate "base32hex" encoding is used in DNSSEC.
-type Encoding struct {
-	encode    string
-	decodeMap [256]byte
-}
-
-const encodeStd = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"
-const encodeHex = "0123456789ABCDEFGHIJKLMNOPQRSTUV"
-
-// NewEncoding returns a new Encoding defined by the given alphabet,
-// which must be a 32-byte string.
-func NewEncoding(encoder string) *Encoding {
-	e := new(Encoding)
-	e.encode = encoder
-	for i := 0; i < len(e.decodeMap); i++ {
-		e.decodeMap[i] = 0xFF
-	}
-	for i := 0; i < len(encoder); i++ {
-		e.decodeMap[encoder[i]] = byte(i)
-	}
-	return e
-}
-
-// StdEncoding is the standard base32 encoding, as defined in
-// RFC 4648.
-var StdEncoding = NewEncoding(encodeStd)
-
-// HexEncoding is the ``Extended Hex Alphabet'' defined in RFC 4648.
-// It is typically used in DNS.
-var HexEncoding = NewEncoding(encodeHex)
-
-var removeNewlinesMapper = func(r rune) rune {
-	if r == '\r' || r == '\n' {
-		return -1
-	}
-	return r
-}
-
-/*
- * Encoder
- */
-
-// Encode encodes src using the encoding enc, writing
-// EncodedLen(len(src)) bytes to dst.
-//
-// The encoding pads the output to a multiple of 8 bytes,
-// so Encode is not appropriate for use on individual blocks
-// of a large data stream.  Use NewEncoder() instead.
-func (enc *Encoding) Encode(dst, src []byte) {
-	if len(src) == 0 {
-		return
-	}
-
-	for len(src) > 0 {
-		dst[0] = 0
-		dst[1] = 0
-		dst[2] = 0
-		dst[3] = 0
-		dst[4] = 0
-		dst[5] = 0
-		dst[6] = 0
-		dst[7] = 0
-
-		// Unpack 8x 5-bit source blocks into a 5 byte
-		// destination quantum
-		switch len(src) {
-		default:
-			dst[7] |= src[4] & 0x1F
-			dst[6] |= src[4] >> 5
-			fallthrough
-		case 4:
-			dst[6] |= (src[3] << 3) & 0x1F
-			dst[5] |= (src[3] >> 2) & 0x1F
-			dst[4] |= src[3] >> 7
-			fallthrough
-		case 3:
-			dst[4] |= (src[2] << 1) & 0x1F
-			dst[3] |= (src[2] >> 4) & 0x1F
-			fallthrough
-		case 2:
-			dst[3] |= (src[1] << 4) & 0x1F
-			dst[2] |= (src[1] >> 1) & 0x1F
-			dst[1] |= (src[1] >> 6) & 0x1F
-			fallthrough
-		case 1:
-			dst[1] |= (src[0] << 2) & 0x1F
-			dst[0] |= src[0] >> 3
-		}
-
-		// Encode 5-bit blocks using the base32 alphabet
-		for j := 0; j < 8; j++ {
-			dst[j] = enc.encode[dst[j]]
-		}
-
-		// Pad the final quantum
-		if len(src) < 5 {
-			dst[7] = '='
-			if len(src) < 4 {
-				dst[6] = '='
-				dst[5] = '='
-				if len(src) < 3 {
-					dst[4] = '='
-					if len(src) < 2 {
-						dst[3] = '='
-						dst[2] = '='
-					}
-				}
-			}
-			break
-		}
-		src = src[5:]
-		dst = dst[8:]
-	}
-}
-
-// EncodeToString returns the base32 encoding of src.
-func (enc *Encoding) EncodeToString(src []byte) string {
-	buf := make([]byte, enc.EncodedLen(len(src)))
-	enc.Encode(buf, src)
-	return string(buf)
-}
-
-type encoder struct {
-	err  error
-	enc  *Encoding
-	w    io.Writer
-	buf  [5]byte    // buffered data waiting to be encoded
-	nbuf int        // number of bytes in buf
-	out  [1024]byte // output buffer
-}
-
-func (e *encoder) Write(p []byte) (n int, err error) {
-	if e.err != nil {
-		return 0, e.err
-	}
-
-	// Leading fringe.
-	if e.nbuf > 0 {
-		var i int
-		for i = 0; i < len(p) && e.nbuf < 5; i++ {
-			e.buf[e.nbuf] = p[i]
-			e.nbuf++
-		}
-		n += i
-		p = p[i:]
-		if e.nbuf < 5 {
-			return
-		}
-		e.enc.Encode(e.out[0:], e.buf[0:])
-		if _, e.err = e.w.Write(e.out[0:8]); e.err != nil {
-			return n, e.err
-		}
-		e.nbuf = 0
-	}
-
-	// Large interior chunks.
-	for len(p) >= 5 {
-		nn := len(e.out) / 8 * 5
-		if nn > len(p) {
-			nn = len(p)
-			nn -= nn % 5
-		}
-		e.enc.Encode(e.out[0:], p[0:nn])
-		if _, e.err = e.w.Write(e.out[0 : nn/5*8]); e.err != nil {
-			return n, e.err
-		}
-		n += nn
-		p = p[nn:]
-	}
-
-	// Trailing fringe.
-	for i := 0; i < len(p); i++ {
-		e.buf[i] = p[i]
-	}
-	e.nbuf = len(p)
-	n += len(p)
-	return
-}
-
-// Close flushes any pending output from the encoder.
-// It is an error to call Write after calling Close.
-func (e *encoder) Close() error {
-	// If there's anything left in the buffer, flush it out
-	if e.err == nil && e.nbuf > 0 {
-		e.enc.Encode(e.out[0:], e.buf[0:e.nbuf])
-		e.nbuf = 0
-		_, e.err = e.w.Write(e.out[0:8])
-	}
-	return e.err
-}
-
-// NewEncoder returns a new base32 stream encoder.  Data written to
-// the returned writer will be encoded using enc and then written to w.
-// Base32 encodings operate in 5-byte blocks; when finished
-// writing, the caller must Close the returned encoder to flush any
-// partially written blocks.
-func NewEncoder(enc *Encoding, w io.Writer) io.WriteCloser {
-	return &encoder{enc: enc, w: w}
-}
-
-// EncodedLen returns the length in bytes of the base32 encoding
-// of an input buffer of length n.
-func (enc *Encoding) EncodedLen(n int) int { return (n + 4) / 5 * 8 }
-
-/*
- * Decoder
- */
-
-type CorruptInputError int64
-
-func (e CorruptInputError) Error() string {
-	return "illegal base32 data at input byte " + strconv.FormatInt(int64(e), 10)
-}
-
-// decode is like Decode but returns an additional 'end' value, which
-// indicates if end-of-message padding was encountered and thus any
-// additional data is an error. This method assumes that src has been
-// stripped of all supported whitespace ('\r' and '\n').
-func (enc *Encoding) decode(dst, src []byte) (n int, end bool, err error) {
-	olen := len(src)
-	for len(src) > 0 && !end {
-		// Decode quantum using the base32 alphabet
-		var dbuf [8]byte
-		dlen := 8
-
-		for j := 0; j < 8; {
-			if len(src) == 0 {
-				return n, false, CorruptInputError(olen - len(src) - j)
-			}
-			in := src[0]
-			src = src[1:]
-			if in == '=' && j >= 2 && len(src) < 8 {
-				// We've reached the end and there's padding
-				if len(src)+j < 8-1 {
-					// not enough padding
-					return n, false, CorruptInputError(olen)
-				}
-				for k := 0; k < 8-1-j; k++ {
-					if len(src) > k && src[k] != '=' {
-						// incorrect padding
-						return n, false, CorruptInputError(olen - len(src) + k - 1)
-					}
-				}
-				dlen, end = j, true
-				// 7, 5 and 2 are not valid padding lengths, and so 1, 3 and 6 are not
-				// valid dlen values. See RFC 4648 Section 6 "Base 32 Encoding" listing
-				// the five valid padding lengths, and Section 9 "Illustrations and
-				// Examples" for an illustration for how the 1st, 3rd and 6th base32
-				// src bytes do not yield enough information to decode a dst byte.
-				if dlen == 1 || dlen == 3 || dlen == 6 {
-					return n, false, CorruptInputError(olen - len(src) - 1)
-				}
-				break
-			}
-			dbuf[j] = enc.decodeMap[in]
-			if dbuf[j] == 0xFF {
-				return n, false, CorruptInputError(olen - len(src) - 1)
-			}
-			j++
-		}
-
-		// Pack 8x 5-bit source blocks into 5 byte destination
-		// quantum
-		switch dlen {
-		case 8:
-			dst[4] = dbuf[6]<<5 | dbuf[7]
-			fallthrough
-		case 7:
-			dst[3] = dbuf[4]<<7 | dbuf[5]<<2 | dbuf[6]>>3
-			fallthrough
-		case 5:
-			dst[2] = dbuf[3]<<4 | dbuf[4]>>1
-			fallthrough
-		case 4:
-			dst[1] = dbuf[1]<<6 | dbuf[2]<<1 | dbuf[3]>>4
-			fallthrough
-		case 2:
-			dst[0] = dbuf[0]<<3 | dbuf[1]>>2
-		}
-		dst = dst[5:]
-		switch dlen {
-		case 2:
-			n += 1
-		case 4:
-			n += 2
-		case 5:
-			n += 3
-		case 7:
-			n += 4
-		case 8:
-			n += 5
-		}
-	}
-	return n, end, nil
-}
-
-// Decode decodes src using the encoding enc.  It writes at most
-// DecodedLen(len(src)) bytes to dst and returns the number of bytes
-// written.  If src contains invalid base32 data, it will return the
-// number of bytes successfully written and CorruptInputError.
-// New line characters (\r and \n) are ignored.
-func (enc *Encoding) Decode(dst, src []byte) (n int, err error) {
-	src = bytes.Map(removeNewlinesMapper, src)
-	n, _, err = enc.decode(dst, src)
-	return
-}
-
-// DecodeString returns the bytes represented by the base32 string s.
-func (enc *Encoding) DecodeString(s string) ([]byte, error) {
-	s = strings.Map(removeNewlinesMapper, s)
-	dbuf := make([]byte, enc.DecodedLen(len(s)))
-	n, err := enc.Decode(dbuf, []byte(s))
-	return dbuf[:n], err
-}
-
-type decoder struct {
-	err    error
-	enc    *Encoding
-	r      io.Reader
-	end    bool       // saw end of message
-	buf    [1024]byte // leftover input
-	nbuf   int
-	out    []byte // leftover decoded output
-	outbuf [1024 / 8 * 5]byte
-}
-
-func (d *decoder) Read(p []byte) (n int, err error) {
-	if d.err != nil {
-		return 0, d.err
-	}
-
-	// Use leftover decoded output from last read.
-	if len(d.out) > 0 {
-		n = copy(p, d.out)
-		d.out = d.out[n:]
-		return n, nil
-	}
-
-	// Read a chunk.
-	nn := len(p) / 5 * 8
-	if nn < 8 {
-		nn = 8
-	}
-	if nn > len(d.buf) {
-		nn = len(d.buf)
-	}
-	nn, d.err = io.ReadAtLeast(d.r, d.buf[d.nbuf:nn], 8-d.nbuf)
-	d.nbuf += nn
-	if d.nbuf < 8 {
-		return 0, d.err
-	}
-
-	// Decode chunk into p, or d.out and then p if p is too small.
-	nr := d.nbuf / 8 * 8
-	nw := d.nbuf / 8 * 5
-	if nw > len(p) {
-		nw, d.end, d.err = d.enc.decode(d.outbuf[0:], d.buf[0:nr])
-		d.out = d.outbuf[0:nw]
-		n = copy(p, d.out)
-		d.out = d.out[n:]
-	} else {
-		n, d.end, d.err = d.enc.decode(p, d.buf[0:nr])
-	}
-	d.nbuf -= nr
-	for i := 0; i < d.nbuf; i++ {
-		d.buf[i] = d.buf[i+nr]
-	}
-
-	if d.err == nil {
-		d.err = err
-	}
-	return n, d.err
-}
-
-type newlineFilteringReader struct {
-	wrapped io.Reader
-}
-
-func (r *newlineFilteringReader) Read(p []byte) (int, error) {
-	n, err := r.wrapped.Read(p)
-	for n > 0 {
-		offset := 0
-		for i, b := range p[0:n] {
-			if b != '\r' && b != '\n' {
-				if i != offset {
-					p[offset] = b
-				}
-				offset++
-			}
-		}
-		if offset > 0 {
-			return offset, err
-		}
-		// Previous buffer entirely whitespace, read again
-		n, err = r.wrapped.Read(p)
-	}
-	return n, err
-}
-
-// NewDecoder constructs a new base32 stream decoder.
-func NewDecoder(enc *Encoding, r io.Reader) io.Reader {
-	return &decoder{enc: enc, r: &newlineFilteringReader{r}}
-}
-
-// DecodedLen returns the maximum length in bytes of the decoded data
-// corresponding to n bytes of base32-encoded data.
-func (enc *Encoding) DecodedLen(n int) int { return n / 8 * 5 }
diff --git a/src/pkg/encoding/base32/base32_test.go b/src/pkg/encoding/base32/base32_test.go
deleted file mode 100644
index f56b996..0000000
--- a/src/pkg/encoding/base32/base32_test.go
+++ /dev/null
@@ -1,286 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package base32
-
-import (
-	"bytes"
-	"io"
-	"io/ioutil"
-	"strings"
-	"testing"
-)
-
-type testpair struct {
-	decoded, encoded string
-}
-
-var pairs = []testpair{
-	// RFC 4648 examples
-	{"", ""},
-	{"f", "MY======"},
-	{"fo", "MZXQ===="},
-	{"foo", "MZXW6==="},
-	{"foob", "MZXW6YQ="},
-	{"fooba", "MZXW6YTB"},
-	{"foobar", "MZXW6YTBOI======"},
-
-	// Wikipedia examples, converted to base32
-	{"sure.", "ON2XEZJO"},
-	{"sure", "ON2XEZI="},
-	{"sur", "ON2XE==="},
-	{"su", "ON2Q===="},
-	{"leasure.", "NRSWC43VOJSS4==="},
-	{"easure.", "MVQXG5LSMUXA===="},
-	{"asure.", "MFZXK4TFFY======"},
-	{"sure.", "ON2XEZJO"},
-}
-
-var bigtest = testpair{
-	"Twas brillig, and the slithy toves",
-	"KR3WC4ZAMJZGS3DMNFTSYIDBNZSCA5DIMUQHG3DJORUHSIDUN53GK4Y=",
-}
-
-func testEqual(t *testing.T, msg string, args ...interface{}) bool {
-	if args[len(args)-2] != args[len(args)-1] {
-		t.Errorf(msg, args...)
-		return false
-	}
-	return true
-}
-
-func TestEncode(t *testing.T) {
-	for _, p := range pairs {
-		got := StdEncoding.EncodeToString([]byte(p.decoded))
-		testEqual(t, "Encode(%q) = %q, want %q", p.decoded, got, p.encoded)
-	}
-}
-
-func TestEncoder(t *testing.T) {
-	for _, p := range pairs {
-		bb := &bytes.Buffer{}
-		encoder := NewEncoder(StdEncoding, bb)
-		encoder.Write([]byte(p.decoded))
-		encoder.Close()
-		testEqual(t, "Encode(%q) = %q, want %q", p.decoded, bb.String(), p.encoded)
-	}
-}
-
-func TestEncoderBuffering(t *testing.T) {
-	input := []byte(bigtest.decoded)
-	for bs := 1; bs <= 12; bs++ {
-		bb := &bytes.Buffer{}
-		encoder := NewEncoder(StdEncoding, bb)
-		for pos := 0; pos < len(input); pos += bs {
-			end := pos + bs
-			if end > len(input) {
-				end = len(input)
-			}
-			n, err := encoder.Write(input[pos:end])
-			testEqual(t, "Write(%q) gave error %v, want %v", input[pos:end], err, error(nil))
-			testEqual(t, "Write(%q) gave length %v, want %v", input[pos:end], n, end-pos)
-		}
-		err := encoder.Close()
-		testEqual(t, "Close gave error %v, want %v", err, error(nil))
-		testEqual(t, "Encoding/%d of %q = %q, want %q", bs, bigtest.decoded, bb.String(), bigtest.encoded)
-	}
-}
-
-func TestDecode(t *testing.T) {
-	for _, p := range pairs {
-		dbuf := make([]byte, StdEncoding.DecodedLen(len(p.encoded)))
-		count, end, err := StdEncoding.decode(dbuf, []byte(p.encoded))
-		testEqual(t, "Decode(%q) = error %v, want %v", p.encoded, err, error(nil))
-		testEqual(t, "Decode(%q) = length %v, want %v", p.encoded, count, len(p.decoded))
-		if len(p.encoded) > 0 {
-			testEqual(t, "Decode(%q) = end %v, want %v", p.encoded, end, (p.encoded[len(p.encoded)-1] == '='))
-		}
-		testEqual(t, "Decode(%q) = %q, want %q", p.encoded,
-			string(dbuf[0:count]),
-			p.decoded)
-
-		dbuf, err = StdEncoding.DecodeString(p.encoded)
-		testEqual(t, "DecodeString(%q) = error %v, want %v", p.encoded, err, error(nil))
-		testEqual(t, "DecodeString(%q) = %q, want %q", p.encoded, string(dbuf), p.decoded)
-	}
-}
-
-func TestDecoder(t *testing.T) {
-	for _, p := range pairs {
-		decoder := NewDecoder(StdEncoding, strings.NewReader(p.encoded))
-		dbuf := make([]byte, StdEncoding.DecodedLen(len(p.encoded)))
-		count, err := decoder.Read(dbuf)
-		if err != nil && err != io.EOF {
-			t.Fatal("Read failed", err)
-		}
-		testEqual(t, "Read from %q = length %v, want %v", p.encoded, count, len(p.decoded))
-		testEqual(t, "Decoding of %q = %q, want %q", p.encoded, string(dbuf[0:count]), p.decoded)
-		if err != io.EOF {
-			count, err = decoder.Read(dbuf)
-		}
-		testEqual(t, "Read from %q = %v, want %v", p.encoded, err, io.EOF)
-	}
-}
-
-func TestDecoderBuffering(t *testing.T) {
-	for bs := 1; bs <= 12; bs++ {
-		decoder := NewDecoder(StdEncoding, strings.NewReader(bigtest.encoded))
-		buf := make([]byte, len(bigtest.decoded)+12)
-		var total int
-		for total = 0; total < len(bigtest.decoded); {
-			n, err := decoder.Read(buf[total : total+bs])
-			testEqual(t, "Read from %q at pos %d = %d, %v, want _, %v", bigtest.encoded, total, n, err, error(nil))
-			total += n
-		}
-		testEqual(t, "Decoding/%d of %q = %q, want %q", bs, bigtest.encoded, string(buf[0:total]), bigtest.decoded)
-	}
-}
-
-func TestDecodeCorrupt(t *testing.T) {
-	testCases := []struct {
-		input  string
-		offset int // -1 means no corruption.
-	}{
-		{"", -1},
-		{"!!!!", 0},
-		{"x===", 0},
-		{"AA=A====", 2},
-		{"AAA=AAAA", 3},
-		{"MMMMMMMMM", 8},
-		{"MMMMMM", 0},
-		{"A=", 1},
-		{"AA=", 3},
-		{"AA==", 4},
-		{"AA===", 5},
-		{"AAAA=", 5},
-		{"AAAA==", 6},
-		{"AAAAA=", 6},
-		{"AAAAA==", 7},
-		{"A=======", 1},
-		{"AA======", -1},
-		{"AAA=====", 3},
-		{"AAAA====", -1},
-		{"AAAAA===", -1},
-		{"AAAAAA==", 6},
-		{"AAAAAAA=", -1},
-		{"AAAAAAAA", -1},
-	}
-	for _, tc := range testCases {
-		dbuf := make([]byte, StdEncoding.DecodedLen(len(tc.input)))
-		_, err := StdEncoding.Decode(dbuf, []byte(tc.input))
-		if tc.offset == -1 {
-			if err != nil {
-				t.Error("Decoder wrongly detected coruption in", tc.input)
-			}
-			continue
-		}
-		switch err := err.(type) {
-		case CorruptInputError:
-			testEqual(t, "Corruption in %q at offset %v, want %v", tc.input, int(err), tc.offset)
-		default:
-			t.Error("Decoder failed to detect corruption in", tc)
-		}
-	}
-}
-
-func TestBig(t *testing.T) {
-	n := 3*1000 + 1
-	raw := make([]byte, n)
-	const alpha = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
-	for i := 0; i < n; i++ {
-		raw[i] = alpha[i%len(alpha)]
-	}
-	encoded := new(bytes.Buffer)
-	w := NewEncoder(StdEncoding, encoded)
-	nn, err := w.Write(raw)
-	if nn != n || err != nil {
-		t.Fatalf("Encoder.Write(raw) = %d, %v want %d, nil", nn, err, n)
-	}
-	err = w.Close()
-	if err != nil {
-		t.Fatalf("Encoder.Close() = %v want nil", err)
-	}
-	decoded, err := ioutil.ReadAll(NewDecoder(StdEncoding, encoded))
-	if err != nil {
-		t.Fatalf("ioutil.ReadAll(NewDecoder(...)): %v", err)
-	}
-
-	if !bytes.Equal(raw, decoded) {
-		var i int
-		for i = 0; i < len(decoded) && i < len(raw); i++ {
-			if decoded[i] != raw[i] {
-				break
-			}
-		}
-		t.Errorf("Decode(Encode(%d-byte string)) failed at offset %d", n, i)
-	}
-}
-
-func testStringEncoding(t *testing.T, expected string, examples []string) {
-	for _, e := range examples {
-		buf, err := StdEncoding.DecodeString(e)
-		if err != nil {
-			t.Errorf("Decode(%q) failed: %v", e, err)
-			continue
-		}
-		if s := string(buf); s != expected {
-			t.Errorf("Decode(%q) = %q, want %q", e, s, expected)
-		}
-	}
-}
-
-func TestNewLineCharacters(t *testing.T) {
-	// Each of these should decode to the string "sure", without errors.
-	examples := []string{
-		"ON2XEZI=",
-		"ON2XEZI=\r",
-		"ON2XEZI=\n",
-		"ON2XEZI=\r\n",
-		"ON2XEZ\r\nI=",
-		"ON2X\rEZ\nI=",
-		"ON2X\nEZ\rI=",
-		"ON2XEZ\nI=",
-		"ON2XEZI\n=",
-	}
-	testStringEncoding(t, "sure", examples)
-
-	// Each of these should decode to the string "foobar", without errors.
-	examples = []string{
-		"MZXW6YTBOI======",
-		"MZXW6YTBOI=\r\n=====",
-	}
-	testStringEncoding(t, "foobar", examples)
-}
-
-func TestDecoderIssue4779(t *testing.T) {
-	encoded := `JRXXEZLNEBUXA43VNUQGI33MN5ZCA43JOQQGC3LFOQWCAY3PNZZWKY3UMV2HK4
-RAMFSGS4DJONUWG2LOM4QGK3DJOQWCA43FMQQGI3YKMVUXK43NN5SCA5DFNVYG64RANFXGG2LENFSH
-K3TUEB2XIIDMMFRG64TFEBSXIIDEN5WG64TFEBWWCZ3OMEQGC3DJOF2WCLRAKV2CAZLONFWQUYLEEB
-WWS3TJNUQHMZLONFQW2LBAOF2WS4ZANZXXG5DSOVSCAZLYMVZGG2LUMF2GS33OEB2WY3DBNVRW6IDM
-MFRG64TJOMQG42LTNEQHK5AKMFWGS4LVNFYCAZLYEBSWCIDDN5WW233EN4QGG33OONSXC5LBOQXCAR
-DVNFZSAYLVORSSA2LSOVZGKIDEN5WG64RANFXAU4TFOBZGK2DFNZSGK4TJOQQGS3RAOZXWY5LQORQX
-IZJAOZSWY2LUEBSXG43FEBRWS3DMOVWSAZDPNRXXEZJAMV2SAZTVM5UWC5BANZ2WY3DBBJYGC4TJMF
-2HK4ROEBCXQY3FOB2GK5LSEBZWS3TUEBXWGY3BMVRWC5BAMN2XA2LEMF2GC5BANZXW4IDQOJXWSZDF
-NZ2CYIDTOVXHIIDJNYFGG5LMOBQSA4LVNEQG6ZTGNFRWSYJAMRSXGZLSOVXHIIDNN5WGY2LUEBQW42
-LNEBUWIIDFON2CA3DBMJXXE5LNFY==
-====`
-	encodedShort := strings.Replace(encoded, "\n", "", -1)
-
-	dec := NewDecoder(StdEncoding, strings.NewReader(encoded))
-	res1, err := ioutil.ReadAll(dec)
-	if err != nil {
-		t.Errorf("ReadAll failed: %v", err)
-	}
-
-	dec = NewDecoder(StdEncoding, strings.NewReader(encodedShort))
-	var res2 []byte
-	res2, err = ioutil.ReadAll(dec)
-	if err != nil {
-		t.Errorf("ReadAll failed: %v", err)
-	}
-
-	if !bytes.Equal(res1, res2) {
-		t.Error("Decoded results not equal")
-	}
-}
diff --git a/src/pkg/encoding/base64/base64.go b/src/pkg/encoding/base64/base64.go
deleted file mode 100644
index e38c26d..0000000
--- a/src/pkg/encoding/base64/base64.go
+++ /dev/null
@@ -1,393 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package base64 implements base64 encoding as specified by RFC 4648.
-package base64
-
-import (
-	"bytes"
-	"io"
-	"strconv"
-	"strings"
-)
-
-/*
- * Encodings
- */
-
-// An Encoding is a radix 64 encoding/decoding scheme, defined by a
-// 64-character alphabet.  The most common encoding is the "base64"
-// encoding defined in RFC 4648 and used in MIME (RFC 2045) and PEM
-// (RFC 1421).  RFC 4648 also defines an alternate encoding, which is
-// the standard encoding with - and _ substituted for + and /.
-type Encoding struct {
-	encode    string
-	decodeMap [256]byte
-}
-
-const encodeStd = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
-const encodeURL = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"
-
-// NewEncoding returns a new Encoding defined by the given alphabet,
-// which must be a 64-byte string.
-func NewEncoding(encoder string) *Encoding {
-	e := new(Encoding)
-	e.encode = encoder
-	for i := 0; i < len(e.decodeMap); i++ {
-		e.decodeMap[i] = 0xFF
-	}
-	for i := 0; i < len(encoder); i++ {
-		e.decodeMap[encoder[i]] = byte(i)
-	}
-	return e
-}
-
-// StdEncoding is the standard base64 encoding, as defined in
-// RFC 4648.
-var StdEncoding = NewEncoding(encodeStd)
-
-// URLEncoding is the alternate base64 encoding defined in RFC 4648.
-// It is typically used in URLs and file names.
-var URLEncoding = NewEncoding(encodeURL)
-
-var removeNewlinesMapper = func(r rune) rune {
-	if r == '\r' || r == '\n' {
-		return -1
-	}
-	return r
-}
-
-/*
- * Encoder
- */
-
-// Encode encodes src using the encoding enc, writing
-// EncodedLen(len(src)) bytes to dst.
-//
-// The encoding pads the output to a multiple of 4 bytes,
-// so Encode is not appropriate for use on individual blocks
-// of a large data stream.  Use NewEncoder() instead.
-func (enc *Encoding) Encode(dst, src []byte) {
-	if len(src) == 0 {
-		return
-	}
-
-	for len(src) > 0 {
-		dst[0] = 0
-		dst[1] = 0
-		dst[2] = 0
-		dst[3] = 0
-
-		// Unpack 4x 6-bit source blocks into a 4 byte
-		// destination quantum
-		switch len(src) {
-		default:
-			dst[3] |= src[2] & 0x3F
-			dst[2] |= src[2] >> 6
-			fallthrough
-		case 2:
-			dst[2] |= (src[1] << 2) & 0x3F
-			dst[1] |= src[1] >> 4
-			fallthrough
-		case 1:
-			dst[1] |= (src[0] << 4) & 0x3F
-			dst[0] |= src[0] >> 2
-		}
-
-		// Encode 6-bit blocks using the base64 alphabet
-		for j := 0; j < 4; j++ {
-			dst[j] = enc.encode[dst[j]]
-		}
-
-		// Pad the final quantum
-		if len(src) < 3 {
-			dst[3] = '='
-			if len(src) < 2 {
-				dst[2] = '='
-			}
-			break
-		}
-
-		src = src[3:]
-		dst = dst[4:]
-	}
-}
-
-// EncodeToString returns the base64 encoding of src.
-func (enc *Encoding) EncodeToString(src []byte) string {
-	buf := make([]byte, enc.EncodedLen(len(src)))
-	enc.Encode(buf, src)
-	return string(buf)
-}
-
-type encoder struct {
-	err  error
-	enc  *Encoding
-	w    io.Writer
-	buf  [3]byte    // buffered data waiting to be encoded
-	nbuf int        // number of bytes in buf
-	out  [1024]byte // output buffer
-}
-
-func (e *encoder) Write(p []byte) (n int, err error) {
-	if e.err != nil {
-		return 0, e.err
-	}
-
-	// Leading fringe.
-	if e.nbuf > 0 {
-		var i int
-		for i = 0; i < len(p) && e.nbuf < 3; i++ {
-			e.buf[e.nbuf] = p[i]
-			e.nbuf++
-		}
-		n += i
-		p = p[i:]
-		if e.nbuf < 3 {
-			return
-		}
-		e.enc.Encode(e.out[0:], e.buf[0:])
-		if _, e.err = e.w.Write(e.out[0:4]); e.err != nil {
-			return n, e.err
-		}
-		e.nbuf = 0
-	}
-
-	// Large interior chunks.
-	for len(p) >= 3 {
-		nn := len(e.out) / 4 * 3
-		if nn > len(p) {
-			nn = len(p)
-			nn -= nn % 3
-		}
-		e.enc.Encode(e.out[0:], p[0:nn])
-		if _, e.err = e.w.Write(e.out[0 : nn/3*4]); e.err != nil {
-			return n, e.err
-		}
-		n += nn
-		p = p[nn:]
-	}
-
-	// Trailing fringe.
-	for i := 0; i < len(p); i++ {
-		e.buf[i] = p[i]
-	}
-	e.nbuf = len(p)
-	n += len(p)
-	return
-}
-
-// Close flushes any pending output from the encoder.
-// It is an error to call Write after calling Close.
-func (e *encoder) Close() error {
-	// If there's anything left in the buffer, flush it out
-	if e.err == nil && e.nbuf > 0 {
-		e.enc.Encode(e.out[0:], e.buf[0:e.nbuf])
-		e.nbuf = 0
-		_, e.err = e.w.Write(e.out[0:4])
-	}
-	return e.err
-}
-
-// NewEncoder returns a new base64 stream encoder.  Data written to
-// the returned writer will be encoded using enc and then written to w.
-// Base64 encodings operate in 4-byte blocks; when finished
-// writing, the caller must Close the returned encoder to flush any
-// partially written blocks.
-func NewEncoder(enc *Encoding, w io.Writer) io.WriteCloser {
-	return &encoder{enc: enc, w: w}
-}
-
-// EncodedLen returns the length in bytes of the base64 encoding
-// of an input buffer of length n.
-func (enc *Encoding) EncodedLen(n int) int { return (n + 2) / 3 * 4 }
-
-/*
- * Decoder
- */
-
-type CorruptInputError int64
-
-func (e CorruptInputError) Error() string {
-	return "illegal base64 data at input byte " + strconv.FormatInt(int64(e), 10)
-}
-
-// decode is like Decode but returns an additional 'end' value, which
-// indicates if end-of-message padding was encountered and thus any
-// additional data is an error. This method assumes that src has been
-// stripped of all supported whitespace ('\r' and '\n').
-func (enc *Encoding) decode(dst, src []byte) (n int, end bool, err error) {
-	olen := len(src)
-	for len(src) > 0 && !end {
-		// Decode quantum using the base64 alphabet
-		var dbuf [4]byte
-		dlen := 4
-
-		for j := range dbuf {
-			if len(src) == 0 {
-				return n, false, CorruptInputError(olen - len(src) - j)
-			}
-			in := src[0]
-			src = src[1:]
-			if in == '=' {
-				// We've reached the end and there's padding
-				switch j {
-				case 0, 1:
-					// incorrect padding
-					return n, false, CorruptInputError(olen - len(src) - 1)
-				case 2:
-					// "==" is expected, the first "=" is already consumed.
-					if len(src) == 0 {
-						// not enough padding
-						return n, false, CorruptInputError(olen)
-					}
-					if src[0] != '=' {
-						// incorrect padding
-						return n, false, CorruptInputError(olen - len(src) - 1)
-					}
-					src = src[1:]
-				}
-				if len(src) > 0 {
-					// trailing garbage
-					err = CorruptInputError(olen - len(src))
-				}
-				dlen, end = j, true
-				break
-			}
-			dbuf[j] = enc.decodeMap[in]
-			if dbuf[j] == 0xFF {
-				return n, false, CorruptInputError(olen - len(src) - 1)
-			}
-		}
-
-		// Pack 4x 6-bit source blocks into 3 byte destination
-		// quantum
-		switch dlen {
-		case 4:
-			dst[2] = dbuf[2]<<6 | dbuf[3]
-			fallthrough
-		case 3:
-			dst[1] = dbuf[1]<<4 | dbuf[2]>>2
-			fallthrough
-		case 2:
-			dst[0] = dbuf[0]<<2 | dbuf[1]>>4
-		}
-		dst = dst[3:]
-		n += dlen - 1
-	}
-
-	return n, end, err
-}
-
-// Decode decodes src using the encoding enc.  It writes at most
-// DecodedLen(len(src)) bytes to dst and returns the number of bytes
-// written.  If src contains invalid base64 data, it will return the
-// number of bytes successfully written and CorruptInputError.
-// New line characters (\r and \n) are ignored.
-func (enc *Encoding) Decode(dst, src []byte) (n int, err error) {
-	src = bytes.Map(removeNewlinesMapper, src)
-	n, _, err = enc.decode(dst, src)
-	return
-}
-
-// DecodeString returns the bytes represented by the base64 string s.
-func (enc *Encoding) DecodeString(s string) ([]byte, error) {
-	s = strings.Map(removeNewlinesMapper, s)
-	dbuf := make([]byte, enc.DecodedLen(len(s)))
-	n, err := enc.Decode(dbuf, []byte(s))
-	return dbuf[:n], err
-}
-
-type decoder struct {
-	err    error
-	enc    *Encoding
-	r      io.Reader
-	end    bool       // saw end of message
-	buf    [1024]byte // leftover input
-	nbuf   int
-	out    []byte // leftover decoded output
-	outbuf [1024 / 4 * 3]byte
-}
-
-func (d *decoder) Read(p []byte) (n int, err error) {
-	if d.err != nil {
-		return 0, d.err
-	}
-
-	// Use leftover decoded output from last read.
-	if len(d.out) > 0 {
-		n = copy(p, d.out)
-		d.out = d.out[n:]
-		return n, nil
-	}
-
-	// Read a chunk.
-	nn := len(p) / 3 * 4
-	if nn < 4 {
-		nn = 4
-	}
-	if nn > len(d.buf) {
-		nn = len(d.buf)
-	}
-	nn, d.err = io.ReadAtLeast(d.r, d.buf[d.nbuf:nn], 4-d.nbuf)
-	d.nbuf += nn
-	if d.err != nil || d.nbuf < 4 {
-		return 0, d.err
-	}
-
-	// Decode chunk into p, or d.out and then p if p is too small.
-	nr := d.nbuf / 4 * 4
-	nw := d.nbuf / 4 * 3
-	if nw > len(p) {
-		nw, d.end, d.err = d.enc.decode(d.outbuf[0:], d.buf[0:nr])
-		d.out = d.outbuf[0:nw]
-		n = copy(p, d.out)
-		d.out = d.out[n:]
-	} else {
-		n, d.end, d.err = d.enc.decode(p, d.buf[0:nr])
-	}
-	d.nbuf -= nr
-	for i := 0; i < d.nbuf; i++ {
-		d.buf[i] = d.buf[i+nr]
-	}
-
-	if d.err == nil {
-		d.err = err
-	}
-	return n, d.err
-}
-
-type newlineFilteringReader struct {
-	wrapped io.Reader
-}
-
-func (r *newlineFilteringReader) Read(p []byte) (int, error) {
-	n, err := r.wrapped.Read(p)
-	for n > 0 {
-		offset := 0
-		for i, b := range p[0:n] {
-			if b != '\r' && b != '\n' {
-				if i != offset {
-					p[offset] = b
-				}
-				offset++
-			}
-		}
-		if offset > 0 {
-			return offset, err
-		}
-		// Previous buffer entirely whitespace, read again
-		n, err = r.wrapped.Read(p)
-	}
-	return n, err
-}
-
-// NewDecoder constructs a new base64 stream decoder.
-func NewDecoder(enc *Encoding, r io.Reader) io.Reader {
-	return &decoder{enc: enc, r: &newlineFilteringReader{r}}
-}
-
-// DecodedLen returns the maximum length in bytes of the decoded data
-// corresponding to n bytes of base64-encoded data.
-func (enc *Encoding) DecodedLen(n int) int { return n / 4 * 3 }
diff --git a/src/pkg/encoding/base64/base64_test.go b/src/pkg/encoding/base64/base64_test.go
deleted file mode 100644
index a075194..0000000
--- a/src/pkg/encoding/base64/base64_test.go
+++ /dev/null
@@ -1,344 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package base64
-
-import (
-	"bytes"
-	"errors"
-	"io"
-	"io/ioutil"
-	"reflect"
-	"strings"
-	"testing"
-	"time"
-)
-
-type testpair struct {
-	decoded, encoded string
-}
-
-var pairs = []testpair{
-	// RFC 3548 examples
-	{"\x14\xfb\x9c\x03\xd9\x7e", "FPucA9l+"},
-	{"\x14\xfb\x9c\x03\xd9", "FPucA9k="},
-	{"\x14\xfb\x9c\x03", "FPucAw=="},
-
-	// RFC 4648 examples
-	{"", ""},
-	{"f", "Zg=="},
-	{"fo", "Zm8="},
-	{"foo", "Zm9v"},
-	{"foob", "Zm9vYg=="},
-	{"fooba", "Zm9vYmE="},
-	{"foobar", "Zm9vYmFy"},
-
-	// Wikipedia examples
-	{"sure.", "c3VyZS4="},
-	{"sure", "c3VyZQ=="},
-	{"sur", "c3Vy"},
-	{"su", "c3U="},
-	{"leasure.", "bGVhc3VyZS4="},
-	{"easure.", "ZWFzdXJlLg=="},
-	{"asure.", "YXN1cmUu"},
-	{"sure.", "c3VyZS4="},
-}
-
-var bigtest = testpair{
-	"Twas brillig, and the slithy toves",
-	"VHdhcyBicmlsbGlnLCBhbmQgdGhlIHNsaXRoeSB0b3Zlcw==",
-}
-
-func testEqual(t *testing.T, msg string, args ...interface{}) bool {
-	if args[len(args)-2] != args[len(args)-1] {
-		t.Errorf(msg, args...)
-		return false
-	}
-	return true
-}
-
-func TestEncode(t *testing.T) {
-	for _, p := range pairs {
-		got := StdEncoding.EncodeToString([]byte(p.decoded))
-		testEqual(t, "Encode(%q) = %q, want %q", p.decoded, got, p.encoded)
-	}
-}
-
-func TestEncoder(t *testing.T) {
-	for _, p := range pairs {
-		bb := &bytes.Buffer{}
-		encoder := NewEncoder(StdEncoding, bb)
-		encoder.Write([]byte(p.decoded))
-		encoder.Close()
-		testEqual(t, "Encode(%q) = %q, want %q", p.decoded, bb.String(), p.encoded)
-	}
-}
-
-func TestEncoderBuffering(t *testing.T) {
-	input := []byte(bigtest.decoded)
-	for bs := 1; bs <= 12; bs++ {
-		bb := &bytes.Buffer{}
-		encoder := NewEncoder(StdEncoding, bb)
-		for pos := 0; pos < len(input); pos += bs {
-			end := pos + bs
-			if end > len(input) {
-				end = len(input)
-			}
-			n, err := encoder.Write(input[pos:end])
-			testEqual(t, "Write(%q) gave error %v, want %v", input[pos:end], err, error(nil))
-			testEqual(t, "Write(%q) gave length %v, want %v", input[pos:end], n, end-pos)
-		}
-		err := encoder.Close()
-		testEqual(t, "Close gave error %v, want %v", err, error(nil))
-		testEqual(t, "Encoding/%d of %q = %q, want %q", bs, bigtest.decoded, bb.String(), bigtest.encoded)
-	}
-}
-
-func TestDecode(t *testing.T) {
-	for _, p := range pairs {
-		dbuf := make([]byte, StdEncoding.DecodedLen(len(p.encoded)))
-		count, end, err := StdEncoding.decode(dbuf, []byte(p.encoded))
-		testEqual(t, "Decode(%q) = error %v, want %v", p.encoded, err, error(nil))
-		testEqual(t, "Decode(%q) = length %v, want %v", p.encoded, count, len(p.decoded))
-		if len(p.encoded) > 0 {
-			testEqual(t, "Decode(%q) = end %v, want %v", p.encoded, end, (p.encoded[len(p.encoded)-1] == '='))
-		}
-		testEqual(t, "Decode(%q) = %q, want %q", p.encoded, string(dbuf[0:count]), p.decoded)
-
-		dbuf, err = StdEncoding.DecodeString(p.encoded)
-		testEqual(t, "DecodeString(%q) = error %v, want %v", p.encoded, err, error(nil))
-		testEqual(t, "DecodeString(%q) = %q, want %q", string(dbuf), p.decoded)
-	}
-}
-
-func TestDecoder(t *testing.T) {
-	for _, p := range pairs {
-		decoder := NewDecoder(StdEncoding, strings.NewReader(p.encoded))
-		dbuf := make([]byte, StdEncoding.DecodedLen(len(p.encoded)))
-		count, err := decoder.Read(dbuf)
-		if err != nil && err != io.EOF {
-			t.Fatal("Read failed", err)
-		}
-		testEqual(t, "Read from %q = length %v, want %v", p.encoded, count, len(p.decoded))
-		testEqual(t, "Decoding of %q = %q, want %q", p.encoded, string(dbuf[0:count]), p.decoded)
-		if err != io.EOF {
-			count, err = decoder.Read(dbuf)
-		}
-		testEqual(t, "Read from %q = %v, want %v", p.encoded, err, io.EOF)
-	}
-}
-
-func TestDecoderBuffering(t *testing.T) {
-	for bs := 1; bs <= 12; bs++ {
-		decoder := NewDecoder(StdEncoding, strings.NewReader(bigtest.encoded))
-		buf := make([]byte, len(bigtest.decoded)+12)
-		var total int
-		for total = 0; total < len(bigtest.decoded); {
-			n, err := decoder.Read(buf[total : total+bs])
-			testEqual(t, "Read from %q at pos %d = %d, %v, want _, %v", bigtest.encoded, total, n, err, error(nil))
-			total += n
-		}
-		testEqual(t, "Decoding/%d of %q = %q, want %q", bs, bigtest.encoded, string(buf[0:total]), bigtest.decoded)
-	}
-}
-
-func TestDecodeCorrupt(t *testing.T) {
-	testCases := []struct {
-		input  string
-		offset int // -1 means no corruption.
-	}{
-		{"", -1},
-		{"!!!!", 0},
-		{"====", 0},
-		{"x===", 1},
-		{"=AAA", 0},
-		{"A=AA", 1},
-		{"AA=A", 2},
-		{"AA==A", 4},
-		{"AAA=AAAA", 4},
-		{"AAAAA", 4},
-		{"AAAAAA", 4},
-		{"A=", 1},
-		{"A==", 1},
-		{"AA=", 3},
-		{"AA==", -1},
-		{"AAA=", -1},
-		{"AAAA", -1},
-		{"AAAAAA=", 7},
-		{"YWJjZA=====", 8},
-	}
-	for _, tc := range testCases {
-		dbuf := make([]byte, StdEncoding.DecodedLen(len(tc.input)))
-		_, err := StdEncoding.Decode(dbuf, []byte(tc.input))
-		if tc.offset == -1 {
-			if err != nil {
-				t.Error("Decoder wrongly detected coruption in", tc.input)
-			}
-			continue
-		}
-		switch err := err.(type) {
-		case CorruptInputError:
-			testEqual(t, "Corruption in %q at offset %v, want %v", tc.input, int(err), tc.offset)
-		default:
-			t.Error("Decoder failed to detect corruption in", tc)
-		}
-	}
-}
-
-func TestBig(t *testing.T) {
-	n := 3*1000 + 1
-	raw := make([]byte, n)
-	const alpha = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
-	for i := 0; i < n; i++ {
-		raw[i] = alpha[i%len(alpha)]
-	}
-	encoded := new(bytes.Buffer)
-	w := NewEncoder(StdEncoding, encoded)
-	nn, err := w.Write(raw)
-	if nn != n || err != nil {
-		t.Fatalf("Encoder.Write(raw) = %d, %v want %d, nil", nn, err, n)
-	}
-	err = w.Close()
-	if err != nil {
-		t.Fatalf("Encoder.Close() = %v want nil", err)
-	}
-	decoded, err := ioutil.ReadAll(NewDecoder(StdEncoding, encoded))
-	if err != nil {
-		t.Fatalf("ioutil.ReadAll(NewDecoder(...)): %v", err)
-	}
-
-	if !bytes.Equal(raw, decoded) {
-		var i int
-		for i = 0; i < len(decoded) && i < len(raw); i++ {
-			if decoded[i] != raw[i] {
-				break
-			}
-		}
-		t.Errorf("Decode(Encode(%d-byte string)) failed at offset %d", n, i)
-	}
-}
-
-func TestNewLineCharacters(t *testing.T) {
-	// Each of these should decode to the string "sure", without errors.
-	const expected = "sure"
-	examples := []string{
-		"c3VyZQ==",
-		"c3VyZQ==\r",
-		"c3VyZQ==\n",
-		"c3VyZQ==\r\n",
-		"c3VyZ\r\nQ==",
-		"c3V\ryZ\nQ==",
-		"c3V\nyZ\rQ==",
-		"c3VyZ\nQ==",
-		"c3VyZQ\n==",
-		"c3VyZQ=\n=",
-		"c3VyZQ=\r\n\r\n=",
-	}
-	for _, e := range examples {
-		buf, err := StdEncoding.DecodeString(e)
-		if err != nil {
-			t.Errorf("Decode(%q) failed: %v", e, err)
-			continue
-		}
-		if s := string(buf); s != expected {
-			t.Errorf("Decode(%q) = %q, want %q", e, s, expected)
-		}
-	}
-}
-
-type nextRead struct {
-	n   int   // bytes to return
-	err error // error to return
-}
-
-// faultInjectReader returns data from source, rate-limited
-// and with the errors as written to nextc.
-type faultInjectReader struct {
-	source string
-	nextc  <-chan nextRead
-}
-
-func (r *faultInjectReader) Read(p []byte) (int, error) {
-	nr := <-r.nextc
-	if len(p) > nr.n {
-		p = p[:nr.n]
-	}
-	n := copy(p, r.source)
-	r.source = r.source[n:]
-	return n, nr.err
-}
-
-// tests that we don't ignore errors from our underlying reader
-func TestDecoderIssue3577(t *testing.T) {
-	next := make(chan nextRead, 10)
-	wantErr := errors.New("my error")
-	next <- nextRead{5, nil}
-	next <- nextRead{10, wantErr}
-	next <- nextRead{0, wantErr}
-	d := NewDecoder(StdEncoding, &faultInjectReader{
-		source: "VHdhcyBicmlsbGlnLCBhbmQgdGhlIHNsaXRoeSB0b3Zlcw==", // twas brillig...
-		nextc:  next,
-	})
-	errc := make(chan error)
-	go func() {
-		_, err := ioutil.ReadAll(d)
-		errc <- err
-	}()
-	select {
-	case err := <-errc:
-		if err != wantErr {
-			t.Errorf("got error %v; want %v", err, wantErr)
-		}
-	case <-time.After(5 * time.Second):
-		t.Errorf("timeout; Decoder blocked without returning an error")
-	}
-}
-
-func TestDecoderIssue4779(t *testing.T) {
-	encoded := `CP/EAT8AAAEF
-AQEBAQEBAAAAAAAAAAMAAQIEBQYHCAkKCwEAAQUBAQEBAQEAAAAAAAAAAQACAwQFBgcICQoLEAAB
-BAEDAgQCBQcGCAUDDDMBAAIRAwQhEjEFQVFhEyJxgTIGFJGhsUIjJBVSwWIzNHKC0UMHJZJT8OHx
-Y3M1FqKygyZEk1RkRcKjdDYX0lXiZfKzhMPTdePzRieUpIW0lcTU5PSltcXV5fVWZnaGlqa2xtbm
-9jdHV2d3h5ent8fX5/cRAAICAQIEBAMEBQYHBwYFNQEAAhEDITESBEFRYXEiEwUygZEUobFCI8FS
-0fAzJGLhcoKSQ1MVY3M08SUGFqKygwcmNcLSRJNUoxdkRVU2dGXi8rOEw9N14/NGlKSFtJXE1OT0
-pbXF1eX1VmZ2hpamtsbW5vYnN0dXZ3eHl6e3x//aAAwDAQACEQMRAD8A9VSSSSUpJJJJSkkkJ+Tj
-1kiy1jCJJDnAcCTykpKkuQ6p/jN6FgmxlNduXawwAzaGH+V6jn/R/wCt71zdn+N/qL3kVYFNYB4N
-ji6PDVjWpKp9TSXnvTf8bFNjg3qOEa2n6VlLpj/rT/pf567DpX1i6L1hs9Py67X8mqdtg/rUWbbf
-+gkp0kkkklKSSSSUpJJJJT//0PVUkkklKVLq3WMDpGI7KzrNjADtYNXvI/Mqr/Pd/q9W3vaxjnvM
-NaCXE9gNSvGPrf8AWS3qmba5jjsJhoB0DAf0NDf6sevf+/lf8Hj0JJATfWT6/dV6oXU1uOLQeKKn
-EQP+Hubtfe/+R7Mf/g7f5xcocp++Z11JMCJPgFBxOg7/AOuqDx8I/ikpkXkmSdU8mJIJA/O8EMAy
-j+mSARB/17pKVXYWHXjsj7yIex0PadzXMO1zT5KHoNA3HT8ietoGhgjsfA+CSnvvqh/jJtqsrwOv
-2b6NGNzXfTYexzJ+nU7/ALkf4P8Awv6P9KvTQQ4AgyDqCF85Pho3CTB7eHwXoH+LT65uZbX9X+o2
-bqbPb06551Y4
-`
-	encodedShort := strings.Replace(encoded, "\n", "", -1)
-
-	dec := NewDecoder(StdEncoding, strings.NewReader(encoded))
-	res1, err := ioutil.ReadAll(dec)
-	if err != nil {
-		t.Errorf("ReadAll failed: %v", err)
-	}
-
-	dec = NewDecoder(StdEncoding, strings.NewReader(encodedShort))
-	var res2 []byte
-	res2, err = ioutil.ReadAll(dec)
-	if err != nil {
-		t.Errorf("ReadAll failed: %v", err)
-	}
-
-	if !bytes.Equal(res1, res2) {
-		t.Error("Decoded results not equal")
-	}
-}
-
-func TestDecoderIssue7733(t *testing.T) {
-	s, err := StdEncoding.DecodeString("YWJjZA=====")
-	want := CorruptInputError(8)
-	if !reflect.DeepEqual(want, err) {
-		t.Errorf("Error = %v; want CorruptInputError(8)", err)
-	}
-	if string(s) != "abcd" {
-		t.Errorf("DecodeString = %q; want abcd", s)
-	}
-}
diff --git a/src/pkg/encoding/binary/binary.go b/src/pkg/encoding/binary/binary.go
deleted file mode 100644
index a569487..0000000
--- a/src/pkg/encoding/binary/binary.go
+++ /dev/null
@@ -1,639 +0,0 @@
-// Copyright 2009 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package binary implements simple translation between numbers and byte
-// sequences and encoding and decoding of varints.
-//
-// Numbers are translated by reading and writing fixed-size values.
-// A fixed-size value is either a fixed-size arithmetic
-// type (int8, uint8, int16, float32, complex64, ...)
-// or an array or struct containing only fixed-size values.
-//
-// Varints are a method of encoding integers using one or more bytes;
-// numbers with smaller absolute value take a smaller number of bytes.
-// For a specification, see http://code.google.com/apis/protocolbuffers/docs/encoding.html.
-//
-// This package favors simplicity over efficiency. Clients that require
-// high-performance serialization, especially for large data structures,
-// should look at more advanced solutions such as the encoding/gob
-// package or protocol buffers.
-package binary
-
-import (
-	"errors"
-	"io"
-	"math"
-	"reflect"
-)
-
-// A ByteOrder specifies how to convert byte sequences into
-// 16-, 32-, or 64-bit unsigned integers.
-type ByteOrder interface {
-	Uint16([]byte) uint16
-	Uint32([]byte) uint32
-	Uint64([]byte) uint64
-	PutUint16([]byte, uint16)
-	PutUint32([]byte, uint32)
-	PutUint64([]byte, uint64)
-	String() string
-}
-
-// LittleEndian is the little-endian implementation of ByteOrder.
-var LittleEndian littleEndian
-
-// BigEndian is the big-endian implementation of ByteOrder.
-var BigEndian bigEndian
-
-type littleEndian struct{}
-
-func (littleEndian) Uint16(b []byte) uint16 { return uint16(b[0]) | uint16(b[1])<<8 }
-
-func (littleEndian) PutUint16(b []byte, v uint16) {
-	b[0] = byte(v)
-	b[1] = byte(v >> 8)
-}
-
-func (littleEndian) Uint32(b []byte) uint32 {
-	return uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24
-}
-
-func (littleEndian) PutUint32(b []byte, v uint32) {
-	b[0] = byte(v)
-	b[1] = byte(v >> 8)
-	b[2] = byte(v >> 16)
-	b[3] = byte(v >> 24)
-}
-
-func (littleEndian) Uint64(b []byte) uint64 {
-	return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 |
-		uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56
-}
-
-func (littleEndian) PutUint64(b []byte, v uint64) {
-	b[0] = byte(v)
-	b[1] = byte(v >> 8)
-	b[2] = byte(v >> 16)
-	b[3] = byte(v >> 24)
-	b[4] = byte(v >> 32)
-	b[5] = byte(v >> 40)
-	b[6] = byte(v >> 48)
-	b[7] = byte(v >> 56)
-}
-
-func (littleEndian) String() string { return "LittleEndian" }
-
-func (littleEndian) GoString() string { return "binary.LittleEndian" }
-
-type bigEndian struct{}
-
-func (bigEndian) Uint16(b []byte) uint16 { return uint16(b[1]) | uint16(b[0])<<8 }
-
-func (bigEndian) PutUint16(b []byte, v uint16) {
-	b[0] = byte(v >> 8)
-	b[1] = byte(v)
-}
-
-func (bigEndian) Uint32(b []byte) uint32 {
-	return uint32(b[3]) | uint32(b[2])<<8 | uint32(b[1])<<16 | uint32(b[0])<<24
-}
-
-func (bigEndian) PutUint32(b []byte, v uint32) {
-	b[0] = byte(v >> 24)
-	b[1] = byte(v >> 16)
-	b[2] = byte(v >> 8)
-	b[3] = byte(v)
-}
-
-func (bigEndian) Uint64(b []byte) uint64 {
-	return uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 |
-		uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56
-}
-
-func (bigEndian) PutUint64(b []byte, v uint64) {
-	b[0] = byte(v >> 56)
-	b[1] = byte(v >> 48)
-	b[2] = byte(v >> 40)
-	b[3] = byte(v >> 32)
-	b[4] = byte(v >> 24)
-	b[5] = byte(v >> 16)
-	b[6] = byte(v >> 8)
-	b[7] = byte(v)
-}
-
-func (bigEndian) String() string { return "BigEndian" }
-
-func (bigEndian) GoString() string { return "binary.BigEndian" }
-
-// Read reads structured binary data from r into data.
-// Data must be a pointer to a fixed-size value or a slice
-// of fixed-size values.
-// Bytes read from r are decoded using the specified byte order
-// and written to successive fields of the data.
-// When reading into structs, the field data for fields with
-// blank (_) field names is skipped; i.e., blank field names
-// may be used for padding.
-// When reading into a struct, all non-blank fields must be exported.
-func Read(r io.Reader, order ByteOrder, data interface{}) error {
-	// Fast path for basic types and slices.
-	if n := intDataSize(data); n != 0 {
-		var b [8]byte
-		var bs []byte
-		if n > len(b) {
-			bs = make([]byte, n)
-		} else {
-			bs = b[:n]
-		}
-		if _, err := io.ReadFull(r, bs); err != nil {
-			return err
-		}
-		switch data := data.(type) {
-		case *int8:
-			*data = int8(b[0])
-		case *uint8:
-			*data = b[0]
-		case *int16:
-			*data = int16(order.Uint16(bs))
-		case *uint16:
-			*data = order.Uint16(bs)
-		case *int32:
-			*data = int32(order.Uint32(bs))
-		case *uint32:
-			*data = order.Uint32(bs)
-		case *int64:
-			*data = int64(order.Uint64(bs))
-		case *uint64:
-			*data = order.Uint64(bs)
-		case []int8:
-			for i, x := range bs { // Easier to loop over the input for 8-bit values.
-				data[i] = int8(x)
-			}
-		case []uint8:
-			copy(data, bs)
-		case []int16:
-			for i := range data {
-				data[i] = int16(order.Uint16(bs[2*i:]))
-			}
-		case []uint16:
-			for i := range data {
-				data[i] = order.Uint16(bs[2*i:])
-			}
-		case []int32:
-			for i := range data {
-				data[i] = int32(order.Uint32(bs[4*i:]))
-			}
-		case []uint32:
-			for i := range data {
-				data[i] = order.Uint32(bs[4*i:])
-			}
-		case []int64:
-			for i := range data {
-				data[i] = int64(order.Uint64(bs[8*i:]))
-			}
-		case []uint64:
-			for i := range data {
-				data[i] = order.Uint64(bs[8*i:])
-			}
-		}
-		return nil
-	}
-
-	// Fallback to reflect-based decoding.
-	var v reflect.Value
-	switch d := reflect.ValueOf(data); d.Kind() {
-	case reflect.Ptr:
-		v = d.Elem()
-	case reflect.Slice:
-		v = d
-	default:
-		return errors.New("binary.Read: invalid type " + d.Type().String())
-	}
-	size, err := dataSize(v)
-	if err != nil {
-		return errors.New("binary.Read: " + err.Error())
-	}
-	d := &decoder{order: order, buf: make([]byte, size)}
-	if _, err := io.ReadFull(r, d.buf); err != nil {
-		return err
-	}
-	d.value(v)
-	return nil
-}
-
-// Write writes the binary representation of data into w.
-// Data must be a fixed-size value or a slice of fixed-size
-// values, or a pointer to such data.
-// Bytes written to w are encoded using the specified byte order
-// and read from successive fields of the data.
-// When writing structs, zero values are written for fields
-// with blank (_) field names.
-func Write(w io.Writer, order ByteOrder, data interface{}) error {
-	// Fast path for basic types and slices.
-	if n := intDataSize(data); n != 0 {
-		var b [8]byte
-		var bs []byte
-		if n > len(b) {
-			bs = make([]byte, n)
-		} else {
-			bs = b[:n]
-		}
-		switch v := data.(type) {
-		case *int8:
-			bs = b[:1]
-			b[0] = byte(*v)
-		case int8:
-			bs = b[:1]
-			b[0] = byte(v)
-		case []int8:
-			for i, x := range v {
-				bs[i] = byte(x)
-			}
-		case *uint8:
-			bs = b[:1]
-			b[0] = *v
-		case uint8:
-			bs = b[:1]
-			b[0] = byte(v)
-		case []uint8:
-			bs = v
-		case *int16:
-			bs = b[:2]
-			order.PutUint16(bs, uint16(*v))
-		case int16:
-			bs = b[:2]
-			order.PutUint16(bs, uint16(v))
-		case []int16:
-			for i, x := range v {
-				order.PutUint16(bs[2*i:], uint16(x))
-			}
-		case *uint16:
-			bs = b[:2]
-			order.PutUint16(bs, *v)
-		case uint16:
-			bs = b[:2]
-			order.PutUint16(bs, v)
-		case []uint16:
-			for i, x := range v {
-				order.PutUint16(bs[2*i:], x)
-			}
-		case *int32:
-			bs = b[:4]
-			order.PutUint32(bs, uint32(*v))
-		case int32:
-			bs = b[:4]
-			order.PutUint32(bs, uint32(v))
-		case []int32:
-			for i, x := range v {
-				order.PutUint32(bs[4*i:], uint32(x))
-			}
-		case *uint32:
-			bs = b[:4]
-			order.PutUint32(bs, *v)
-		case uint32:
-			bs = b[:4]
-			order.PutUint32(bs, v)
-		case []uint32:
-			for i, x := range v {
-				order.PutUint32(bs[4*i:], x)
-			}
-		case *int64:
-			bs = b[:8]
-			order.PutUint64(bs, uint64(*v))
-		case int64:
-			bs = b[:8]
-			order.PutUint64(bs, uint64(v))
-		case []int64:
-			for i, x := range v {
-				order.PutUint64(bs[8*i:], uint64(x))
-			}
-		case *uint64:
-			bs = b[:8]
-			order.PutUint64(bs, *v)
-		case uint64:
-			bs = b[:8]
-			order.PutUint64(bs, v)
-		case []uint64:
-			for i, x := range v {
-				order.PutUint64(bs[8*i:], x)
-			}
-		}
-		_, err := w.Write(bs)
-		return err
-	}
-
-	// Fallback to reflect-based encoding.
-	v := reflect.Indirect(reflect.ValueOf(data))
-	size, err := dataSize(v)
-	if err != nil {
-		return errors.New("binary.Write: " + err.Error())
-	}
-	buf := make([]byte, size)
-	e := &encoder{order: order, buf: buf}
-	e.value(v)
-	_, err = w.Write(buf)
-	return err
-}
-
-// Size returns how many bytes Write would generate to encode the value v, which
-// must be a fixed-size value or a slice of fixed-size values, or a pointer to such data.
-func Size(v interface{}) int {
-	n, err := dataSize(reflect.Indirect(reflect.ValueOf(v)))
-	if err != nil {
-		return -1
-	}
-	return n
-}
-
-// dataSize returns the number of bytes the actual data represented by v occupies in memory.
-// For compound structures, it sums the sizes of the elements. Thus, for instance, for a slice
-// it returns the length of the slice times the element size and does not count the memory
-// occupied by the header.
-func dataSize(v reflect.Value) (int, error) {
-	if v.Kind() == reflect.Slice {
-		elem, err := sizeof(v.Type().Elem())
-		if err != nil {
-			return 0, err
-		}
-		return v.Len() * elem, nil
-	}
-	return sizeof(v.Type())
-}
-
-func sizeof(t reflect.Type) (int, error) {
-	switch t.Kind() {
-	case reflect.Array:
-		n, err := sizeof(t.Elem())
-		if err != nil {
-			return 0, err
-		}
-		return t.Len() * n, nil
-
-	case reflect.Struct:
-		sum := 0
-		for i, n := 0, t.NumField(); i < n; i++ {
-			s, err := sizeof(t.Field(i).Type)
-			if err != nil {
-				return 0, err
-			}
-			sum += s
-		}
-		return sum, nil
-
-	case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
-		reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
-		reflect.Float32, reflect.Float64, reflect.Complex64, reflect.Complex128:
-		return int(t.Size()), nil
-	}
-	return 0, errors.New("invalid type " + t.String())
-}
-
-type coder struct {
-	order ByteOrder
-	buf   []byte
-}
-
-type decoder coder
-type encoder coder
-
-func (d *decoder) uint8() uint8 {
-	x := d.buf[0]
-	d.buf = d.buf[1:]
-	return x
-}
-
-func (e *encoder) uint8(x uint8) {
-	e.buf[0] = x
-	e.buf = e.buf[1:]
-}
-
-func (d *decoder) uint16() uint16 {
-	x := d.order.Uint16(d.buf[0:2])
-	d.buf = d.buf[2:]
-	return x
-}
-
-func (e *encoder) uint16(x uint16) {
-	e.order.PutUint16(e.buf[0:2], x)
-	e.buf = e.buf[2:]
-}
-
-func (d *decoder) uint32() uint32 {
-	x := d.order.Uint32(d.buf[0:4])
-	d.buf = d.buf[4:]
-	return x
-}
-
-func (e *encoder) uint32(x uint32) {
-	e.order.PutUint32(e.buf[0:4], x)
-	e.buf = e.buf[4:]
-}
-
-func (d *decoder) uint64() uint64 {
-	x := d.order.Uint64(d.buf[0:8])
-	d.buf = d.buf[8:]
-	return x
-}
-
-func (e *encoder) uint64(x uint64) {
-	e.order.PutUint64(e.buf[0:8], x)
-	e.buf = e.buf[8:]
-}
-
-func (d *decoder) int8() int8 { return int8(d.uint8()) }
-
-func (e *encoder) int8(x int8) { e.uint8(uint8(x)) }
-
-func (d *decoder) int16() int16 { return int16(d.uint16()) }
-
-func (e *encoder) int16(x int16) { e.uint16(uint16(x)) }
-
-func (d *decoder) int32() int32 { return int32(d.uint32()) }
-
-func (e *encoder) int32(x int32) { e.uint32(uint32(x)) }
-
-func (d *decoder) int64() int64 { return int64(d.uint64()) }
-
-func (e *encoder) int64(x int64) { e.uint64(uint64(x)) }
-
-func (d *decoder) value(v reflect.Value) {
-	switch v.Kind() {
-	case reflect.Array:
-		l := v.Len()
-		for i := 0; i < l; i++ {
-			d.value(v.Index(i))
-		}
-
-	case reflect.Struct:
-		t := v.Type()
-		l := v.NumField()
-		for i := 0; i < l; i++ {
-			// Note: Calling v.CanSet() below is an optimization.
-			// It would be sufficient to check the field name,
-			// but creating the StructField info for each field is
-			// costly (run "go test -bench=ReadStruct" and compare
-			// results when making changes to this code).
-			if v := v.Field(i); v.CanSet() || t.Field(i).Name != "_" {
-				d.value(v)
-			} else {
-				d.skip(v)
-			}
-		}
-
-	case reflect.Slice:
-		l := v.Len()
-		for i := 0; i < l; i++ {
-			d.value(v.Index(i))
-		}
-
-	case reflect.Int8:
-		v.SetInt(int64(d.int8()))
-	case reflect.Int16:
-		v.SetInt(int64(d.int16()))
-	case reflect.Int32:
-		v.SetInt(int64(d.int32()))
-	case reflect.Int64:
-		v.SetInt(d.int64())
-
-	case reflect.Uint8:
-		v.SetUint(uint64(d.uint8()))
-	case reflect.Uint16:
-		v.SetUint(uint64(d.uint16()))
-	case reflect.Uint32:
-		v.SetUint(uint64(d.uint32()))
-	case reflect.Uint64:
-		v.SetUint(d.uint64())
-
-	case reflect.Float32:
-		v.SetFloat(float64(math.Float32frombits(d.uint32())))
-	case reflect.Float64:
-		v.SetFloat(math.Float64frombits(d.uint64()))
-
-	case reflect.Complex64:
-		v.SetComplex(complex(
-			float64(math.Float32frombits(d.uint32())),
-			float64(math.Float32frombits(d.uint32())),
-		))
-	case reflect.Complex128:
-		v.SetComplex(complex(
-			math.Float64frombits(d.uint64()),
-			math.Float64frombits(d.uint64()),
-		))
-	}
-}
-
-func (e *encoder) value(v reflect.Value) {
-	switch v.Kind() {
-	case reflect.Array:
-		l := v.Len()
-		for i := 0; i < l; i++ {
-			e.value(v.Index(i))
-		}
-
-	case reflect.Struct:
-		t := v.Type()
-		l := v.NumField()
-		for i := 0; i < l; i++ {
-			// see comment for corresponding code in decoder.value()
-			if v := v.Field(i); v.CanSet() || t.Field(i).Name != "_" {
-				e.value(v)
-			} else {
-				e.skip(v)
-			}
-		}
-
-	case reflect.Slice:
-		l := v.Len()
-		for i := 0; i < l; i++ {
-			e.value(v.Index(i))
-		}
-
-	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-		switch v.Type().Kind() {
-		case reflect.Int8:
-			e.int8(int8(v.Int()))
-		case reflect.Int16:
-			e.int16(int16(v.Int()))
-		case reflect.Int32:
-			e.int32(int32(v.Int()))
-		case reflect.Int64:
-			e.int64(v.Int())
-		}
-
-	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
-		switch v.Type().Kind() {
-		case reflect.Uint8:
-			e.uint8(uint8(v.Uint()))
-		case reflect.Uint16:
-			e.uint16(uint16(v.Uint()))
-		case reflect.Uint32:
-			e.uint32(uint32(v.Uint()))
-		case reflect.Uint64:
-			e.uint64(v.Uint())
-		}
-
-	case reflect.Float32, reflect.Float64:
-		switch v.Type().Kind() {
-		case reflect.Float32:
-			e.uint32(math.Float32bits(float32(v.Float())))
-		case reflect.Float64:
-			e.uint64(math.Float64bits(v.Float()))
-		}
-
-	case reflect.Complex64, reflect.Complex128:
-		switch v.Type().Kind() {
-		case reflect.Complex64:
-			x := v.Complex()
-			e.uint32(math.Float32bits(float32(real(x))))
-			e.uint32(math.Float32bits(float32(imag(x))))
-		case reflect.Complex128:
-			x := v.Complex()
-			e.uint64(math.Float64bits(real(x)))
-			e.uint64(math.Float64bits(imag(x)))
-		}
-	}
-}
-
-func (d *decoder) skip(v reflect.Value) {
-	n, _ := dataSize(v)
-	d.buf = d.buf[n:]
-}
-
-func (e *encoder) skip(v reflect.Value) {
-	n, _ := dataSize(v)
-	for i := range e.buf[0:n] {
-		e.buf[i] = 0
-	}
-	e.buf = e.buf[n:]
-}
-
-// intDataSize returns the size of the data required to represent the data when encoded.
-// It returns zero if the type cannot be implemented by the fast path in Read or Write.
-func intDataSize(data interface{}) int {
-	switch data := data.(type) {
-	case int8, *int8, *uint8:
-		return 1
-	case []int8:
-		return len(data)
-	case []uint8:
-		return len(data)
-	case int16, *int16, *uint16:
-		return 2
-	case []int16:
-		return 2 * len(data)
-	case []uint16:
-		return 2 * len(data)
-	case int32, *int32, *uint32:
-		return 4
-	case []int32:
-		return 4 * len(data)
-	case []uint32:
-		return 4 * len(data)
-	case int64, *int64, *uint64:
-		return 8
-	case []int64:
-		return 8 * len(data)
-	case []uint64:
-		return 8 * len(data)
-	}
-	return 0
-}
diff --git a/src/pkg/encoding/binary/binary_test.go b/src/pkg/encoding/binary/binary_test.go
deleted file mode 100644
index c80c903..0000000
--- a/src/pkg/encoding/binary/binary_test.go
+++ /dev/null
@@ -1,397 +0,0 @@
-// Copyright 2009 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package binary
-
-import (
-	"bytes"
-	"io"
-	"math"
-	"reflect"
-	"strings"
-	"testing"
-)
-
-type Struct struct {
-	Int8       int8
-	Int16      int16
-	Int32      int32
-	Int64      int64
-	Uint8      uint8
-	Uint16     uint16
-	Uint32     uint32
-	Uint64     uint64
-	Float32    float32
-	Float64    float64
-	Complex64  complex64
-	Complex128 complex128
-	Array      [4]uint8
-}
-
-type T struct {
-	Int     int
-	Uint    uint
-	Uintptr uintptr
-	Array   [4]int
-}
-
-var s = Struct{
-	0x01,
-	0x0203,
-	0x04050607,
-	0x08090a0b0c0d0e0f,
-	0x10,
-	0x1112,
-	0x13141516,
-	0x1718191a1b1c1d1e,
-
-	math.Float32frombits(0x1f202122),
-	math.Float64frombits(0x232425262728292a),
-	complex(
-		math.Float32frombits(0x2b2c2d2e),
-		math.Float32frombits(0x2f303132),
-	),
-	complex(
-		math.Float64frombits(0x333435363738393a),
-		math.Float64frombits(0x3b3c3d3e3f404142),
-	),
-
-	[4]uint8{0x43, 0x44, 0x45, 0x46},
-}
-
-var big = []byte{
-	1,
-	2, 3,
-	4, 5, 6, 7,
-	8, 9, 10, 11, 12, 13, 14, 15,
-	16,
-	17, 18,
-	19, 20, 21, 22,
-	23, 24, 25, 26, 27, 28, 29, 30,
-
-	31, 32, 33, 34,
-	35, 36, 37, 38, 39, 40, 41, 42,
-	43, 44, 45, 46, 47, 48, 49, 50,
-	51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66,
-
-	67, 68, 69, 70,
-}
-
-var little = []byte{
-	1,
-	3, 2,
-	7, 6, 5, 4,
-	15, 14, 13, 12, 11, 10, 9, 8,
-	16,
-	18, 17,
-	22, 21, 20, 19,
-	30, 29, 28, 27, 26, 25, 24, 23,
-
-	34, 33, 32, 31,
-	42, 41, 40, 39, 38, 37, 36, 35,
-	46, 45, 44, 43, 50, 49, 48, 47,
-	58, 57, 56, 55, 54, 53, 52, 51, 66, 65, 64, 63, 62, 61, 60, 59,
-
-	67, 68, 69, 70,
-}
-
-var src = []byte{1, 2, 3, 4, 5, 6, 7, 8}
-var res = []int32{0x01020304, 0x05060708}
-
-func checkResult(t *testing.T, dir string, order ByteOrder, err error, have, want interface{}) {
-	if err != nil {
-		t.Errorf("%v %v: %v", dir, order, err)
-		return
-	}
-	if !reflect.DeepEqual(have, want) {
-		t.Errorf("%v %v:\n\thave %+v\n\twant %+v", dir, order, have, want)
-	}
-}
-
-func testRead(t *testing.T, order ByteOrder, b []byte, s1 interface{}) {
-	var s2 Struct
-	err := Read(bytes.NewReader(b), order, &s2)
-	checkResult(t, "Read", order, err, s2, s1)
-}
-
-func testWrite(t *testing.T, order ByteOrder, b []byte, s1 interface{}) {
-	buf := new(bytes.Buffer)
-	err := Write(buf, order, s1)
-	checkResult(t, "Write", order, err, buf.Bytes(), b)
-}
-
-func TestLittleEndianRead(t *testing.T)     { testRead(t, LittleEndian, little, s) }
-func TestLittleEndianWrite(t *testing.T)    { testWrite(t, LittleEndian, little, s) }
-func TestLittleEndianPtrWrite(t *testing.T) { testWrite(t, LittleEndian, little, &s) }
-
-func TestBigEndianRead(t *testing.T)     { testRead(t, BigEndian, big, s) }
-func TestBigEndianWrite(t *testing.T)    { testWrite(t, BigEndian, big, s) }
-func TestBigEndianPtrWrite(t *testing.T) { testWrite(t, BigEndian, big, &s) }
-
-func TestReadSlice(t *testing.T) {
-	slice := make([]int32, 2)
-	err := Read(bytes.NewReader(src), BigEndian, slice)
-	checkResult(t, "ReadSlice", BigEndian, err, slice, res)
-}
-
-func TestWriteSlice(t *testing.T) {
-	buf := new(bytes.Buffer)
-	err := Write(buf, BigEndian, res)
-	checkResult(t, "WriteSlice", BigEndian, err, buf.Bytes(), src)
-}
-
-// Addresses of arrays are easier to manipulate with reflection than are slices.
-var intArrays = []interface{}{
-	&[100]int8{},
-	&[100]int16{},
-	&[100]int32{},
-	&[100]int64{},
-	&[100]uint8{},
-	&[100]uint16{},
-	&[100]uint32{},
-	&[100]uint64{},
-}
-
-func TestSliceRoundTrip(t *testing.T) {
-	buf := new(bytes.Buffer)
-	for _, array := range intArrays {
-		src := reflect.ValueOf(array).Elem()
-		unsigned := false
-		switch src.Index(0).Kind() {
-		case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
-			unsigned = true
-		}
-		for i := 0; i < src.Len(); i++ {
-			if unsigned {
-				src.Index(i).SetUint(uint64(i * 0x07654321))
-			} else {
-				src.Index(i).SetInt(int64(i * 0x07654321))
-			}
-		}
-		buf.Reset()
-		srcSlice := src.Slice(0, src.Len())
-		err := Write(buf, BigEndian, srcSlice.Interface())
-		if err != nil {
-			t.Fatal(err)
-		}
-		dst := reflect.New(src.Type()).Elem()
-		dstSlice := dst.Slice(0, dst.Len())
-		err = Read(buf, BigEndian, dstSlice.Interface())
-		if err != nil {
-			t.Fatal(err)
-		}
-		if !reflect.DeepEqual(src.Interface(), dst.Interface()) {
-			t.Fatal(src)
-		}
-	}
-}
-
-func TestWriteT(t *testing.T) {
-	buf := new(bytes.Buffer)
-	ts := T{}
-	if err := Write(buf, BigEndian, ts); err == nil {
-		t.Errorf("WriteT: have err == nil, want non-nil")
-	}
-
-	tv := reflect.Indirect(reflect.ValueOf(ts))
-	for i, n := 0, tv.NumField(); i < n; i++ {
-		typ := tv.Field(i).Type().String()
-		if typ == "[4]int" {
-			typ = "int" // the problem is int, not the [4]
-		}
-		if err := Write(buf, BigEndian, tv.Field(i).Interface()); err == nil {
-			t.Errorf("WriteT.%v: have err == nil, want non-nil", tv.Field(i).Type())
-		} else if !strings.Contains(err.Error(), typ) {
-			t.Errorf("WriteT: have err == %q, want it to mention %s", err, typ)
-		}
-	}
-}
-
-type BlankFields struct {
-	A uint32
-	_ int32
-	B float64
-	_ [4]int16
-	C byte
-	_ [7]byte
-	_ struct {
-		f [8]float32
-	}
-}
-
-type BlankFieldsProbe struct {
-	A  uint32
-	P0 int32
-	B  float64
-	P1 [4]int16
-	C  byte
-	P2 [7]byte
-	P3 struct {
-		F [8]float32
-	}
-}
-
-func TestBlankFields(t *testing.T) {
-	buf := new(bytes.Buffer)
-	b1 := BlankFields{A: 1234567890, B: 2.718281828, C: 42}
-	if err := Write(buf, LittleEndian, &b1); err != nil {
-		t.Error(err)
-	}
-
-	// zero values must have been written for blank fields
-	var p BlankFieldsProbe
-	if err := Read(buf, LittleEndian, &p); err != nil {
-		t.Error(err)
-	}
-
-	// quick test: only check first value of slices
-	if p.P0 != 0 || p.P1[0] != 0 || p.P2[0] != 0 || p.P3.F[0] != 0 {
-		t.Errorf("non-zero values for originally blank fields: %#v", p)
-	}
-
-	// write p and see if we can probe only some fields
-	if err := Write(buf, LittleEndian, &p); err != nil {
-		t.Error(err)
-	}
-
-	// read should ignore blank fields in b2
-	var b2 BlankFields
-	if err := Read(buf, LittleEndian, &b2); err != nil {
-		t.Error(err)
-	}
-	if b1.A != b2.A || b1.B != b2.B || b1.C != b2.C {
-		t.Errorf("%#v != %#v", b1, b2)
-	}
-}
-
-// An attempt to read into a struct with an unexported field will
-// panic.  This is probably not the best choice, but at this point
-// anything else would be an API change.
-
-type Unexported struct {
-	a int32
-}
-
-func TestUnexportedRead(t *testing.T) {
-	var buf bytes.Buffer
-	u1 := Unexported{a: 1}
-	if err := Write(&buf, LittleEndian, &u1); err != nil {
-		t.Fatal(err)
-	}
-
-	defer func() {
-		if recover() == nil {
-			t.Fatal("did not panic")
-		}
-	}()
-	var u2 Unexported
-	Read(&buf, LittleEndian, &u2)
-}
-
-type byteSliceReader struct {
-	remain []byte
-}
-
-func (br *byteSliceReader) Read(p []byte) (int, error) {
-	n := copy(p, br.remain)
-	br.remain = br.remain[n:]
-	return n, nil
-}
-
-func BenchmarkReadSlice1000Int32s(b *testing.B) {
-	bsr := &byteSliceReader{}
-	slice := make([]int32, 1000)
-	buf := make([]byte, len(slice)*4)
-	b.SetBytes(int64(len(buf)))
-	b.ResetTimer()
-	for i := 0; i < b.N; i++ {
-		bsr.remain = buf
-		Read(bsr, BigEndian, slice)
-	}
-}
-
-func BenchmarkReadStruct(b *testing.B) {
-	bsr := &byteSliceReader{}
-	var buf bytes.Buffer
-	Write(&buf, BigEndian, &s)
-	n, _ := dataSize(reflect.ValueOf(s))
-	b.SetBytes(int64(n))
-	t := s
-	b.ResetTimer()
-	for i := 0; i < b.N; i++ {
-		bsr.remain = buf.Bytes()
-		Read(bsr, BigEndian, &t)
-	}
-	b.StopTimer()
-	if !reflect.DeepEqual(s, t) {
-		b.Fatal("no match")
-	}
-}
-
-func BenchmarkReadInts(b *testing.B) {
-	var ls Struct
-	bsr := &byteSliceReader{}
-	var r io.Reader = bsr
-	b.SetBytes(2 * (1 + 2 + 4 + 8))
-	b.ResetTimer()
-	for i := 0; i < b.N; i++ {
-		bsr.remain = big
-		Read(r, BigEndian, &ls.Int8)
-		Read(r, BigEndian, &ls.Int16)
-		Read(r, BigEndian, &ls.Int32)
-		Read(r, BigEndian, &ls.Int64)
-		Read(r, BigEndian, &ls.Uint8)
-		Read(r, BigEndian, &ls.Uint16)
-		Read(r, BigEndian, &ls.Uint32)
-		Read(r, BigEndian, &ls.Uint64)
-	}
-
-	want := s
-	want.Float32 = 0
-	want.Float64 = 0
-	want.Complex64 = 0
-	want.Complex128 = 0
-	for i := range want.Array {
-		want.Array[i] = 0
-	}
-	b.StopTimer()
-	if !reflect.DeepEqual(ls, want) {
-		panic("no match")
-	}
-}
-
-func BenchmarkWriteInts(b *testing.B) {
-	buf := new(bytes.Buffer)
-	var w io.Writer = buf
-	b.SetBytes(2 * (1 + 2 + 4 + 8))
-	b.ResetTimer()
-	for i := 0; i < b.N; i++ {
-		buf.Reset()
-		Write(w, BigEndian, s.Int8)
-		Write(w, BigEndian, s.Int16)
-		Write(w, BigEndian, s.Int32)
-		Write(w, BigEndian, s.Int64)
-		Write(w, BigEndian, s.Uint8)
-		Write(w, BigEndian, s.Uint16)
-		Write(w, BigEndian, s.Uint32)
-		Write(w, BigEndian, s.Uint64)
-	}
-	b.StopTimer()
-	if !bytes.Equal(buf.Bytes(), big[:30]) {
-		b.Fatalf("first half doesn't match: %x %x", buf.Bytes(), big[:30])
-	}
-}
-
-func BenchmarkWriteSlice1000Int32s(b *testing.B) {
-	slice := make([]int32, 1000)
-	buf := new(bytes.Buffer)
-	var w io.Writer = buf
-	b.SetBytes(4 * 1000)
-	b.ResetTimer()
-	for i := 0; i < b.N; i++ {
-		buf.Reset()
-		Write(w, BigEndian, slice)
-	}
-	b.StopTimer()
-}
diff --git a/src/pkg/encoding/csv/writer.go b/src/pkg/encoding/csv/writer.go
deleted file mode 100644
index 1faecb6..0000000
--- a/src/pkg/encoding/csv/writer.go
+++ /dev/null
@@ -1,127 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package csv
-
-import (
-	"bufio"
-	"io"
-	"strings"
-	"unicode"
-	"unicode/utf8"
-)
-
-// A Writer writes records to a CSV encoded file.
-//
-// As returned by NewWriter, a Writer writes records terminated by a
-// newline and uses ',' as the field delimiter.  The exported fields can be
-// changed to customize the details before the first call to Write or WriteAll.
-//
-// Comma is the field delimiter.
-//
-// If UseCRLF is true, the Writer ends each record with \r\n instead of \n.
-type Writer struct {
-	Comma   rune // Field delimiter (set to ',' by NewWriter)
-	UseCRLF bool // True to use \r\n as the line terminator
-	w       *bufio.Writer
-}
-
-// NewWriter returns a new Writer that writes to w.
-func NewWriter(w io.Writer) *Writer {
-	return &Writer{
-		Comma: ',',
-		w:     bufio.NewWriter(w),
-	}
-}
-
-// Writer writes a single CSV record to w along with any necessary quoting.
-// A record is a slice of strings with each string being one field.
-func (w *Writer) Write(record []string) (err error) {
-	for n, field := range record {
-		if n > 0 {
-			if _, err = w.w.WriteRune(w.Comma); err != nil {
-				return
-			}
-		}
-
-		// If we don't have to have a quoted field then just
-		// write out the field and continue to the next field.
-		if !w.fieldNeedsQuotes(field) {
-			if _, err = w.w.WriteString(field); err != nil {
-				return
-			}
-			continue
-		}
-		if err = w.w.WriteByte('"'); err != nil {
-			return
-		}
-
-		for _, r1 := range field {
-			switch r1 {
-			case '"':
-				_, err = w.w.WriteString(`""`)
-			case '\r':
-				if !w.UseCRLF {
-					err = w.w.WriteByte('\r')
-				}
-			case '\n':
-				if w.UseCRLF {
-					_, err = w.w.WriteString("\r\n")
-				} else {
-					err = w.w.WriteByte('\n')
-				}
-			default:
-				_, err = w.w.WriteRune(r1)
-			}
-			if err != nil {
-				return
-			}
-		}
-
-		if err = w.w.WriteByte('"'); err != nil {
-			return
-		}
-	}
-	if w.UseCRLF {
-		_, err = w.w.WriteString("\r\n")
-	} else {
-		err = w.w.WriteByte('\n')
-	}
-	return
-}
-
-// Flush writes any buffered data to the underlying io.Writer.
-// To check if an error occurred during the Flush, call Error.
-func (w *Writer) Flush() {
-	w.w.Flush()
-}
-
-// Error reports any error that has occurred during a previous Write or Flush.
-func (w *Writer) Error() error {
-	_, err := w.w.Write(nil)
-	return err
-}
-
-// WriteAll writes multiple CSV records to w using Write and then calls Flush.
-func (w *Writer) WriteAll(records [][]string) (err error) {
-	for _, record := range records {
-		err = w.Write(record)
-		if err != nil {
-			return err
-		}
-	}
-	return w.w.Flush()
-}
-
-// fieldNeedsQuotes returns true if our field must be enclosed in quotes.
-// Empty fields, files with a Comma, fields with a quote or newline, and
-// fields which start with a space must be enclosed in quotes.
-func (w *Writer) fieldNeedsQuotes(field string) bool {
-	if len(field) == 0 || strings.IndexRune(field, w.Comma) >= 0 || strings.IndexAny(field, "\"\r\n") >= 0 {
-		return true
-	}
-
-	r1, _ := utf8.DecodeRuneInString(field)
-	return unicode.IsSpace(r1)
-}
diff --git a/src/pkg/encoding/csv/writer_test.go b/src/pkg/encoding/csv/writer_test.go
deleted file mode 100644
index 22b740c..0000000
--- a/src/pkg/encoding/csv/writer_test.go
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package csv
-
-import (
-	"bytes"
-	"errors"
-	"testing"
-)
-
-var writeTests = []struct {
-	Input   [][]string
-	Output  string
-	UseCRLF bool
-}{
-	{Input: [][]string{{"abc"}}, Output: "abc\n"},
-	{Input: [][]string{{"abc"}}, Output: "abc\r\n", UseCRLF: true},
-	{Input: [][]string{{`"abc"`}}, Output: `"""abc"""` + "\n"},
-	{Input: [][]string{{`a"b`}}, Output: `"a""b"` + "\n"},
-	{Input: [][]string{{`"a"b"`}}, Output: `"""a""b"""` + "\n"},
-	{Input: [][]string{{" abc"}}, Output: `" abc"` + "\n"},
-	{Input: [][]string{{"abc,def"}}, Output: `"abc,def"` + "\n"},
-	{Input: [][]string{{"abc", "def"}}, Output: "abc,def\n"},
-	{Input: [][]string{{"abc"}, {"def"}}, Output: "abc\ndef\n"},
-	{Input: [][]string{{"abc\ndef"}}, Output: "\"abc\ndef\"\n"},
-	{Input: [][]string{{"abc\ndef"}}, Output: "\"abc\r\ndef\"\r\n", UseCRLF: true},
-	{Input: [][]string{{"abc\rdef"}}, Output: "\"abcdef\"\r\n", UseCRLF: true},
-	{Input: [][]string{{"abc\rdef"}}, Output: "\"abc\rdef\"\n", UseCRLF: false},
-}
-
-func TestWrite(t *testing.T) {
-	for n, tt := range writeTests {
-		b := &bytes.Buffer{}
-		f := NewWriter(b)
-		f.UseCRLF = tt.UseCRLF
-		err := f.WriteAll(tt.Input)
-		if err != nil {
-			t.Errorf("Unexpected error: %s\n", err)
-		}
-		out := b.String()
-		if out != tt.Output {
-			t.Errorf("#%d: out=%q want %q", n, out, tt.Output)
-		}
-	}
-}
-
-type errorWriter struct{}
-
-func (e errorWriter) Write(b []byte) (int, error) {
-	return 0, errors.New("Test")
-}
-
-func TestError(t *testing.T) {
-	b := &bytes.Buffer{}
-	f := NewWriter(b)
-	f.Write([]string{"abc"})
-	f.Flush()
-	err := f.Error()
-
-	if err != nil {
-		t.Errorf("Unexpected error: %s\n", err)
-	}
-
-	f = NewWriter(errorWriter{})
-	f.Write([]string{"abc"})
-	f.Flush()
-	err = f.Error()
-
-	if err == nil {
-		t.Error("Error should not be nil")
-	}
-}
diff --git a/src/pkg/encoding/gob/codec_test.go b/src/pkg/encoding/gob/codec_test.go
deleted file mode 100644
index fa57f37..0000000
--- a/src/pkg/encoding/gob/codec_test.go
+++ /dev/null
@@ -1,1506 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package gob
-
-import (
-	"bytes"
-	"errors"
-	"flag"
-	"math"
-	"math/rand"
-	"reflect"
-	"strings"
-	"testing"
-	"time"
-	"unsafe"
-)
-
-var doFuzzTests = flag.Bool("gob.fuzz", false, "run the fuzz tests, which are large and very slow")
-
-// Guarantee encoding format by comparing some encodings to hand-written values
-type EncodeT struct {
-	x uint64
-	b []byte
-}
-
-var encodeT = []EncodeT{
-	{0x00, []byte{0x00}},
-	{0x0F, []byte{0x0F}},
-	{0xFF, []byte{0xFF, 0xFF}},
-	{0xFFFF, []byte{0xFE, 0xFF, 0xFF}},
-	{0xFFFFFF, []byte{0xFD, 0xFF, 0xFF, 0xFF}},
-	{0xFFFFFFFF, []byte{0xFC, 0xFF, 0xFF, 0xFF, 0xFF}},
-	{0xFFFFFFFFFF, []byte{0xFB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}},
-	{0xFFFFFFFFFFFF, []byte{0xFA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}},
-	{0xFFFFFFFFFFFFFF, []byte{0xF9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}},
-	{0xFFFFFFFFFFFFFFFF, []byte{0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}},
-	{0x1111, []byte{0xFE, 0x11, 0x11}},
-	{0x1111111111111111, []byte{0xF8, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}},
-	{0x8888888888888888, []byte{0xF8, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88}},
-	{1 << 63, []byte{0xF8, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
-}
-
-// testError is meant to be used as a deferred function to turn a panic(gobError) into a
-// plain test.Error call.
-func testError(t *testing.T) {
-	if e := recover(); e != nil {
-		t.Error(e.(gobError).err) // Will re-panic if not one of our errors, such as a runtime error.
-	}
-	return
-}
-
-// Test basic encode/decode routines for unsigned integers
-func TestUintCodec(t *testing.T) {
-	defer testError(t)
-	b := new(bytes.Buffer)
-	encState := newEncoderState(b)
-	for _, tt := range encodeT {
-		b.Reset()
-		encState.encodeUint(tt.x)
-		if !bytes.Equal(tt.b, b.Bytes()) {
-			t.Errorf("encodeUint: %#x encode: expected % x got % x", tt.x, tt.b, b.Bytes())
-		}
-	}
-	decState := newDecodeState(b)
-	for u := uint64(0); ; u = (u + 1) * 7 {
-		b.Reset()
-		encState.encodeUint(u)
-		v := decState.decodeUint()
-		if u != v {
-			t.Errorf("Encode/Decode: sent %#x received %#x", u, v)
-		}
-		if u&(1<<63) != 0 {
-			break
-		}
-	}
-}
-
-func verifyInt(i int64, t *testing.T) {
-	defer testError(t)
-	var b = new(bytes.Buffer)
-	encState := newEncoderState(b)
-	encState.encodeInt(i)
-	decState := newDecodeState(b)
-	decState.buf = make([]byte, 8)
-	j := decState.decodeInt()
-	if i != j {
-		t.Errorf("Encode/Decode: sent %#x received %#x", uint64(i), uint64(j))
-	}
-}
-
-// Test basic encode/decode routines for signed integers
-func TestIntCodec(t *testing.T) {
-	for u := uint64(0); ; u = (u + 1) * 7 {
-		// Do positive and negative values
-		i := int64(u)
-		verifyInt(i, t)
-		verifyInt(-i, t)
-		verifyInt(^i, t)
-		if u&(1<<63) != 0 {
-			break
-		}
-	}
-	verifyInt(-1<<63, t) // a tricky case
-}
-
-// The result of encoding a true boolean with field number 7
-var boolResult = []byte{0x07, 0x01}
-
-// The result of encoding a number 17 with field number 7
-var signedResult = []byte{0x07, 2 * 17}
-var unsignedResult = []byte{0x07, 17}
-var floatResult = []byte{0x07, 0xFE, 0x31, 0x40}
-
-// The result of encoding a number 17+19i with field number 7
-var complexResult = []byte{0x07, 0xFE, 0x31, 0x40, 0xFE, 0x33, 0x40}
-
-// The result of encoding "hello" with field number 7
-var bytesResult = []byte{0x07, 0x05, 'h', 'e', 'l', 'l', 'o'}
-
-func newDecodeState(buf *bytes.Buffer) *decoderState {
-	d := new(decoderState)
-	d.b = buf
-	d.buf = make([]byte, uint64Size)
-	return d
-}
-
-func newEncoderState(b *bytes.Buffer) *encoderState {
-	b.Reset()
-	state := &encoderState{enc: nil, b: b}
-	state.fieldnum = -1
-	return state
-}
-
-// Test instruction execution for encoding.
-// Do not run the machine yet; instead do individual instructions crafted by hand.
-func TestScalarEncInstructions(t *testing.T) {
-	var b = new(bytes.Buffer)
-
-	// bool
-	{
-		data := struct{ a bool }{true}
-		instr := &encInstr{encBool, 6, 0, 0}
-		state := newEncoderState(b)
-		instr.op(instr, state, unsafe.Pointer(&data))
-		if !bytes.Equal(boolResult, b.Bytes()) {
-			t.Errorf("bool enc instructions: expected % x got % x", boolResult, b.Bytes())
-		}
-	}
-
-	// int
-	{
-		b.Reset()
-		data := struct{ a int }{17}
-		instr := &encInstr{encInt, 6, 0, 0}
-		state := newEncoderState(b)
-		instr.op(instr, state, unsafe.Pointer(&data))
-		if !bytes.Equal(signedResult, b.Bytes()) {
-			t.Errorf("int enc instructions: expected % x got % x", signedResult, b.Bytes())
-		}
-	}
-
-	// uint
-	{
-		b.Reset()
-		data := struct{ a uint }{17}
-		instr := &encInstr{encUint, 6, 0, 0}
-		state := newEncoderState(b)
-		instr.op(instr, state, unsafe.Pointer(&data))
-		if !bytes.Equal(unsignedResult, b.Bytes()) {
-			t.Errorf("uint enc instructions: expected % x got % x", unsignedResult, b.Bytes())
-		}
-	}
-
-	// int8
-	{
-		b.Reset()
-		data := struct{ a int8 }{17}
-		instr := &encInstr{encInt8, 6, 0, 0}
-		state := newEncoderState(b)
-		instr.op(instr, state, unsafe.Pointer(&data))
-		if !bytes.Equal(signedResult, b.Bytes()) {
-			t.Errorf("int8 enc instructions: expected % x got % x", signedResult, b.Bytes())
-		}
-	}
-
-	// uint8
-	{
-		b.Reset()
-		data := struct{ a uint8 }{17}
-		instr := &encInstr{encUint8, 6, 0, 0}
-		state := newEncoderState(b)
-		instr.op(instr, state, unsafe.Pointer(&data))
-		if !bytes.Equal(unsignedResult, b.Bytes()) {
-			t.Errorf("uint8 enc instructions: expected % x got % x", unsignedResult, b.Bytes())
-		}
-	}
-
-	// int16
-	{
-		b.Reset()
-		data := struct{ a int16 }{17}
-		instr := &encInstr{encInt16, 6, 0, 0}
-		state := newEncoderState(b)
-		instr.op(instr, state, unsafe.Pointer(&data))
-		if !bytes.Equal(signedResult, b.Bytes()) {
-			t.Errorf("int16 enc instructions: expected % x got % x", signedResult, b.Bytes())
-		}
-	}
-
-	// uint16
-	{
-		b.Reset()
-		data := struct{ a uint16 }{17}
-		instr := &encInstr{encUint16, 6, 0, 0}
-		state := newEncoderState(b)
-		instr.op(instr, state, unsafe.Pointer(&data))
-		if !bytes.Equal(unsignedResult, b.Bytes()) {
-			t.Errorf("uint16 enc instructions: expected % x got % x", unsignedResult, b.Bytes())
-		}
-	}
-
-	// int32
-	{
-		b.Reset()
-		data := struct{ a int32 }{17}
-		instr := &encInstr{encInt32, 6, 0, 0}
-		state := newEncoderState(b)
-		instr.op(instr, state, unsafe.Pointer(&data))
-		if !bytes.Equal(signedResult, b.Bytes()) {
-			t.Errorf("int32 enc instructions: expected % x got % x", signedResult, b.Bytes())
-		}
-	}
-
-	// uint32
-	{
-		b.Reset()
-		data := struct{ a uint32 }{17}
-		instr := &encInstr{encUint32, 6, 0, 0}
-		state := newEncoderState(b)
-		instr.op(instr, state, unsafe.Pointer(&data))
-		if !bytes.Equal(unsignedResult, b.Bytes()) {
-			t.Errorf("uint32 enc instructions: expected % x got % x", unsignedResult, b.Bytes())
-		}
-	}
-
-	// int64
-	{
-		b.Reset()
-		data := struct{ a int64 }{17}
-		instr := &encInstr{encInt64, 6, 0, 0}
-		state := newEncoderState(b)
-		instr.op(instr, state, unsafe.Pointer(&data))
-		if !bytes.Equal(signedResult, b.Bytes()) {
-			t.Errorf("int64 enc instructions: expected % x got % x", signedResult, b.Bytes())
-		}
-	}
-
-	// uint64
-	{
-		b.Reset()
-		data := struct{ a uint64 }{17}
-		instr := &encInstr{encUint64, 6, 0, 0}
-		state := newEncoderState(b)
-		instr.op(instr, state, unsafe.Pointer(&data))
-		if !bytes.Equal(unsignedResult, b.Bytes()) {
-			t.Errorf("uint64 enc instructions: expected % x got % x", unsignedResult, b.Bytes())
-		}
-	}
-
-	// float32
-	{
-		b.Reset()
-		data := struct{ a float32 }{17}
-		instr := &encInstr{encFloat32, 6, 0, 0}
-		state := newEncoderState(b)
-		instr.op(instr, state, unsafe.Pointer(&data))
-		if !bytes.Equal(floatResult, b.Bytes()) {
-			t.Errorf("float32 enc instructions: expected % x got % x", floatResult, b.Bytes())
-		}
-	}
-
-	// float64
-	{
-		b.Reset()
-		data := struct{ a float64 }{17}
-		instr := &encInstr{encFloat64, 6, 0, 0}
-		state := newEncoderState(b)
-		instr.op(instr, state, unsafe.Pointer(&data))
-		if !bytes.Equal(floatResult, b.Bytes()) {
-			t.Errorf("float64 enc instructions: expected % x got % x", floatResult, b.Bytes())
-		}
-	}
-
-	// bytes == []uint8
-	{
-		b.Reset()
-		data := struct{ a []byte }{[]byte("hello")}
-		instr := &encInstr{encUint8Array, 6, 0, 0}
-		state := newEncoderState(b)
-		instr.op(instr, state, unsafe.Pointer(&data))
-		if !bytes.Equal(bytesResult, b.Bytes()) {
-			t.Errorf("bytes enc instructions: expected % x got % x", bytesResult, b.Bytes())
-		}
-	}
-
-	// string
-	{
-		b.Reset()
-		data := struct{ a string }{"hello"}
-		instr := &encInstr{encString, 6, 0, 0}
-		state := newEncoderState(b)
-		instr.op(instr, state, unsafe.Pointer(&data))
-		if !bytes.Equal(bytesResult, b.Bytes()) {
-			t.Errorf("string enc instructions: expected % x got % x", bytesResult, b.Bytes())
-		}
-	}
-}
-
-func execDec(typ string, instr *decInstr, state *decoderState, t *testing.T, p unsafe.Pointer) {
-	defer testError(t)
-	v := int(state.decodeUint())
-	if v+state.fieldnum != 6 {
-		t.Fatalf("decoding field number %d, got %d", 6, v+state.fieldnum)
-	}
-	instr.op(instr, state, decIndirect(p, instr.indir))
-	state.fieldnum = 6
-}
-
-func newDecodeStateFromData(data []byte) *decoderState {
-	b := bytes.NewBuffer(data)
-	state := newDecodeState(b)
-	state.fieldnum = -1
-	return state
-}
-
-// Test instruction execution for decoding.
-// Do not run the machine yet; instead do individual instructions crafted by hand.
-func TestScalarDecInstructions(t *testing.T) {
-	ovfl := errors.New("overflow")
-
-	// bool
-	{
-		var data struct {
-			a bool
-		}
-		instr := &decInstr{decBool, 6, 0, 0, ovfl}
-		state := newDecodeStateFromData(boolResult)
-		execDec("bool", instr, state, t, unsafe.Pointer(&data))
-		if data.a != true {
-			t.Errorf("bool a = %v not true", data.a)
-		}
-	}
-	// int
-	{
-		var data struct {
-			a int
-		}
-		instr := &decInstr{decOpTable[reflect.Int], 6, 0, 0, ovfl}
-		state := newDecodeStateFromData(signedResult)
-		execDec("int", instr, state, t, unsafe.Pointer(&data))
-		if data.a != 17 {
-			t.Errorf("int a = %v not 17", data.a)
-		}
-	}
-
-	// uint
-	{
-		var data struct {
-			a uint
-		}
-		instr := &decInstr{decOpTable[reflect.Uint], 6, 0, 0, ovfl}
-		state := newDecodeStateFromData(unsignedResult)
-		execDec("uint", instr, state, t, unsafe.Pointer(&data))
-		if data.a != 17 {
-			t.Errorf("uint a = %v not 17", data.a)
-		}
-	}
-
-	// int8
-	{
-		var data struct {
-			a int8
-		}
-		instr := &decInstr{decInt8, 6, 0, 0, ovfl}
-		state := newDecodeStateFromData(signedResult)
-		execDec("int8", instr, state, t, unsafe.Pointer(&data))
-		if data.a != 17 {
-			t.Errorf("int8 a = %v not 17", data.a)
-		}
-	}
-
-	// uint8
-	{
-		var data struct {
-			a uint8
-		}
-		instr := &decInstr{decUint8, 6, 0, 0, ovfl}
-		state := newDecodeStateFromData(unsignedResult)
-		execDec("uint8", instr, state, t, unsafe.Pointer(&data))
-		if data.a != 17 {
-			t.Errorf("uint8 a = %v not 17", data.a)
-		}
-	}
-
-	// int16
-	{
-		var data struct {
-			a int16
-		}
-		instr := &decInstr{decInt16, 6, 0, 0, ovfl}
-		state := newDecodeStateFromData(signedResult)
-		execDec("int16", instr, state, t, unsafe.Pointer(&data))
-		if data.a != 17 {
-			t.Errorf("int16 a = %v not 17", data.a)
-		}
-	}
-
-	// uint16
-	{
-		var data struct {
-			a uint16
-		}
-		instr := &decInstr{decUint16, 6, 0, 0, ovfl}
-		state := newDecodeStateFromData(unsignedResult)
-		execDec("uint16", instr, state, t, unsafe.Pointer(&data))
-		if data.a != 17 {
-			t.Errorf("uint16 a = %v not 17", data.a)
-		}
-	}
-
-	// int32
-	{
-		var data struct {
-			a int32
-		}
-		instr := &decInstr{decInt32, 6, 0, 0, ovfl}
-		state := newDecodeStateFromData(signedResult)
-		execDec("int32", instr, state, t, unsafe.Pointer(&data))
-		if data.a != 17 {
-			t.Errorf("int32 a = %v not 17", data.a)
-		}
-	}
-
-	// uint32
-	{
-		var data struct {
-			a uint32
-		}
-		instr := &decInstr{decUint32, 6, 0, 0, ovfl}
-		state := newDecodeStateFromData(unsignedResult)
-		execDec("uint32", instr, state, t, unsafe.Pointer(&data))
-		if data.a != 17 {
-			t.Errorf("uint32 a = %v not 17", data.a)
-		}
-	}
-
-	// uintptr
-	{
-		var data struct {
-			a uintptr
-		}
-		instr := &decInstr{decOpTable[reflect.Uintptr], 6, 0, 0, ovfl}
-		state := newDecodeStateFromData(unsignedResult)
-		execDec("uintptr", instr, state, t, unsafe.Pointer(&data))
-		if data.a != 17 {
-			t.Errorf("uintptr a = %v not 17", data.a)
-		}
-	}
-
-	// int64
-	{
-		var data struct {
-			a int64
-		}
-		instr := &decInstr{decInt64, 6, 0, 0, ovfl}
-		state := newDecodeStateFromData(signedResult)
-		execDec("int64", instr, state, t, unsafe.Pointer(&data))
-		if data.a != 17 {
-			t.Errorf("int64 a = %v not 17", data.a)
-		}
-	}
-
-	// uint64
-	{
-		var data struct {
-			a uint64
-		}
-		instr := &decInstr{decUint64, 6, 0, 0, ovfl}
-		state := newDecodeStateFromData(unsignedResult)
-		execDec("uint64", instr, state, t, unsafe.Pointer(&data))
-		if data.a != 17 {
-			t.Errorf("uint64 a = %v not 17", data.a)
-		}
-	}
-
-	// float32
-	{
-		var data struct {
-			a float32
-		}
-		instr := &decInstr{decFloat32, 6, 0, 0, ovfl}
-		state := newDecodeStateFromData(floatResult)
-		execDec("float32", instr, state, t, unsafe.Pointer(&data))
-		if data.a != 17 {
-			t.Errorf("float32 a = %v not 17", data.a)
-		}
-	}
-
-	// float64
-	{
-		var data struct {
-			a float64
-		}
-		instr := &decInstr{decFloat64, 6, 0, 0, ovfl}
-		state := newDecodeStateFromData(floatResult)
-		execDec("float64", instr, state, t, unsafe.Pointer(&data))
-		if data.a != 17 {
-			t.Errorf("float64 a = %v not 17", data.a)
-		}
-	}
-
-	// complex64
-	{
-		var data struct {
-			a complex64
-		}
-		instr := &decInstr{decOpTable[reflect.Complex64], 6, 0, 0, ovfl}
-		state := newDecodeStateFromData(complexResult)
-		execDec("complex", instr, state, t, unsafe.Pointer(&data))
-		if data.a != 17+19i {
-			t.Errorf("complex a = %v not 17+19i", data.a)
-		}
-	}
-
-	// complex128
-	{
-		var data struct {
-			a complex128
-		}
-		instr := &decInstr{decOpTable[reflect.Complex128], 6, 0, 0, ovfl}
-		state := newDecodeStateFromData(complexResult)
-		execDec("complex", instr, state, t, unsafe.Pointer(&data))
-		if data.a != 17+19i {
-			t.Errorf("complex a = %v not 17+19i", data.a)
-		}
-	}
-
-	// bytes == []uint8
-	{
-		var data struct {
-			a []byte
-		}
-		instr := &decInstr{decUint8Slice, 6, 0, 0, ovfl}
-		state := newDecodeStateFromData(bytesResult)
-		execDec("bytes", instr, state, t, unsafe.Pointer(&data))
-		if string(data.a) != "hello" {
-			t.Errorf(`bytes a = %q not "hello"`, string(data.a))
-		}
-	}
-
-	// string
-	{
-		var data struct {
-			a string
-		}
-		instr := &decInstr{decString, 6, 0, 0, ovfl}
-		state := newDecodeStateFromData(bytesResult)
-		execDec("bytes", instr, state, t, unsafe.Pointer(&data))
-		if data.a != "hello" {
-			t.Errorf(`bytes a = %q not "hello"`, data.a)
-		}
-	}
-}
-
-func TestEndToEnd(t *testing.T) {
-	type T2 struct {
-		T string
-	}
-	s1 := "string1"
-	s2 := "string2"
-	type T1 struct {
-		A, B, C  int
-		M        map[string]*float64
-		EmptyMap map[string]int // to check that we receive a non-nil map.
-		N        *[3]float64
-		Strs     *[2]string
-		Int64s   *[]int64
-		RI       complex64
-		S        string
-		Y        []byte
-		T        *T2
-	}
-	pi := 3.14159
-	e := 2.71828
-	t1 := &T1{
-		A:        17,
-		B:        18,
-		C:        -5,
-		M:        map[string]*float64{"pi": &pi, "e": &e},
-		EmptyMap: make(map[string]int),
-		N:        &[3]float64{1.5, 2.5, 3.5},
-		Strs:     &[2]string{s1, s2},
-		Int64s:   &[]int64{77, 89, 123412342134},
-		RI:       17 - 23i,
-		S:        "Now is the time",
-		Y:        []byte("hello, sailor"),
-		T:        &T2{"this is T2"},
-	}
-	b := new(bytes.Buffer)
-	err := NewEncoder(b).Encode(t1)
-	if err != nil {
-		t.Error("encode:", err)
-	}
-	var _t1 T1
-	err = NewDecoder(b).Decode(&_t1)
-	if err != nil {
-		t.Fatal("decode:", err)
-	}
-	if !reflect.DeepEqual(t1, &_t1) {
-		t.Errorf("encode expected %v got %v", *t1, _t1)
-	}
-	// Be absolutely sure the received map is non-nil.
-	if t1.EmptyMap == nil {
-		t.Errorf("nil map sent")
-	}
-	if _t1.EmptyMap == nil {
-		t.Errorf("nil map received")
-	}
-}
-
-func TestOverflow(t *testing.T) {
-	type inputT struct {
-		Maxi int64
-		Mini int64
-		Maxu uint64
-		Maxf float64
-		Minf float64
-		Maxc complex128
-		Minc complex128
-	}
-	var it inputT
-	var err error
-	b := new(bytes.Buffer)
-	enc := NewEncoder(b)
-	dec := NewDecoder(b)
-
-	// int8
-	b.Reset()
-	it = inputT{
-		Maxi: math.MaxInt8 + 1,
-	}
-	type outi8 struct {
-		Maxi int8
-		Mini int8
-	}
-	var o1 outi8
-	enc.Encode(it)
-	err = dec.Decode(&o1)
-	if err == nil || err.Error() != `value for "Maxi" out of range` {
-		t.Error("wrong overflow error for int8:", err)
-	}
-	it = inputT{
-		Mini: math.MinInt8 - 1,
-	}
-	b.Reset()
-	enc.Encode(it)
-	err = dec.Decode(&o1)
-	if err == nil || err.Error() != `value for "Mini" out of range` {
-		t.Error("wrong underflow error for int8:", err)
-	}
-
-	// int16
-	b.Reset()
-	it = inputT{
-		Maxi: math.MaxInt16 + 1,
-	}
-	type outi16 struct {
-		Maxi int16
-		Mini int16
-	}
-	var o2 outi16
-	enc.Encode(it)
-	err = dec.Decode(&o2)
-	if err == nil || err.Error() != `value for "Maxi" out of range` {
-		t.Error("wrong overflow error for int16:", err)
-	}
-	it = inputT{
-		Mini: math.MinInt16 - 1,
-	}
-	b.Reset()
-	enc.Encode(it)
-	err = dec.Decode(&o2)
-	if err == nil || err.Error() != `value for "Mini" out of range` {
-		t.Error("wrong underflow error for int16:", err)
-	}
-
-	// int32
-	b.Reset()
-	it = inputT{
-		Maxi: math.MaxInt32 + 1,
-	}
-	type outi32 struct {
-		Maxi int32
-		Mini int32
-	}
-	var o3 outi32
-	enc.Encode(it)
-	err = dec.Decode(&o3)
-	if err == nil || err.Error() != `value for "Maxi" out of range` {
-		t.Error("wrong overflow error for int32:", err)
-	}
-	it = inputT{
-		Mini: math.MinInt32 - 1,
-	}
-	b.Reset()
-	enc.Encode(it)
-	err = dec.Decode(&o3)
-	if err == nil || err.Error() != `value for "Mini" out of range` {
-		t.Error("wrong underflow error for int32:", err)
-	}
-
-	// uint8
-	b.Reset()
-	it = inputT{
-		Maxu: math.MaxUint8 + 1,
-	}
-	type outu8 struct {
-		Maxu uint8
-	}
-	var o4 outu8
-	enc.Encode(it)
-	err = dec.Decode(&o4)
-	if err == nil || err.Error() != `value for "Maxu" out of range` {
-		t.Error("wrong overflow error for uint8:", err)
-	}
-
-	// uint16
-	b.Reset()
-	it = inputT{
-		Maxu: math.MaxUint16 + 1,
-	}
-	type outu16 struct {
-		Maxu uint16
-	}
-	var o5 outu16
-	enc.Encode(it)
-	err = dec.Decode(&o5)
-	if err == nil || err.Error() != `value for "Maxu" out of range` {
-		t.Error("wrong overflow error for uint16:", err)
-	}
-
-	// uint32
-	b.Reset()
-	it = inputT{
-		Maxu: math.MaxUint32 + 1,
-	}
-	type outu32 struct {
-		Maxu uint32
-	}
-	var o6 outu32
-	enc.Encode(it)
-	err = dec.Decode(&o6)
-	if err == nil || err.Error() != `value for "Maxu" out of range` {
-		t.Error("wrong overflow error for uint32:", err)
-	}
-
-	// float32
-	b.Reset()
-	it = inputT{
-		Maxf: math.MaxFloat32 * 2,
-	}
-	type outf32 struct {
-		Maxf float32
-		Minf float32
-	}
-	var o7 outf32
-	enc.Encode(it)
-	err = dec.Decode(&o7)
-	if err == nil || err.Error() != `value for "Maxf" out of range` {
-		t.Error("wrong overflow error for float32:", err)
-	}
-
-	// complex64
-	b.Reset()
-	it = inputT{
-		Maxc: complex(math.MaxFloat32*2, math.MaxFloat32*2),
-	}
-	type outc64 struct {
-		Maxc complex64
-		Minc complex64
-	}
-	var o8 outc64
-	enc.Encode(it)
-	err = dec.Decode(&o8)
-	if err == nil || err.Error() != `value for "Maxc" out of range` {
-		t.Error("wrong overflow error for complex64:", err)
-	}
-}
-
-func TestNesting(t *testing.T) {
-	type RT struct {
-		A    string
-		Next *RT
-	}
-	rt := new(RT)
-	rt.A = "level1"
-	rt.Next = new(RT)
-	rt.Next.A = "level2"
-	b := new(bytes.Buffer)
-	NewEncoder(b).Encode(rt)
-	var drt RT
-	dec := NewDecoder(b)
-	err := dec.Decode(&drt)
-	if err != nil {
-		t.Fatal("decoder error:", err)
-	}
-	if drt.A != rt.A {
-		t.Errorf("nesting: encode expected %v got %v", *rt, drt)
-	}
-	if drt.Next == nil {
-		t.Errorf("nesting: recursion failed")
-	}
-	if drt.Next.A != rt.Next.A {
-		t.Errorf("nesting: encode expected %v got %v", *rt.Next, *drt.Next)
-	}
-}
-
-// These three structures have the same data with different indirections
-type T0 struct {
-	A int
-	B int
-	C int
-	D int
-}
-type T1 struct {
-	A int
-	B *int
-	C **int
-	D ***int
-}
-type T2 struct {
-	A ***int
-	B **int
-	C *int
-	D int
-}
-
-func TestAutoIndirection(t *testing.T) {
-	// First transfer t1 into t0
-	var t1 T1
-	t1.A = 17
-	t1.B = new(int)
-	*t1.B = 177
-	t1.C = new(*int)
-	*t1.C = new(int)
-	**t1.C = 1777
-	t1.D = new(**int)
-	*t1.D = new(*int)
-	**t1.D = new(int)
-	***t1.D = 17777
-	b := new(bytes.Buffer)
-	enc := NewEncoder(b)
-	enc.Encode(t1)
-	dec := NewDecoder(b)
-	var t0 T0
-	dec.Decode(&t0)
-	if t0.A != 17 || t0.B != 177 || t0.C != 1777 || t0.D != 17777 {
-		t.Errorf("t1->t0: expected {17 177 1777 17777}; got %v", t0)
-	}
-
-	// Now transfer t2 into t0
-	var t2 T2
-	t2.D = 17777
-	t2.C = new(int)
-	*t2.C = 1777
-	t2.B = new(*int)
-	*t2.B = new(int)
-	**t2.B = 177
-	t2.A = new(**int)
-	*t2.A = new(*int)
-	**t2.A = new(int)
-	***t2.A = 17
-	b.Reset()
-	enc.Encode(t2)
-	t0 = T0{}
-	dec.Decode(&t0)
-	if t0.A != 17 || t0.B != 177 || t0.C != 1777 || t0.D != 17777 {
-		t.Errorf("t2->t0 expected {17 177 1777 17777}; got %v", t0)
-	}
-
-	// Now transfer t0 into t1
-	t0 = T0{17, 177, 1777, 17777}
-	b.Reset()
-	enc.Encode(t0)
-	t1 = T1{}
-	dec.Decode(&t1)
-	if t1.A != 17 || *t1.B != 177 || **t1.C != 1777 || ***t1.D != 17777 {
-		t.Errorf("t0->t1 expected {17 177 1777 17777}; got {%d %d %d %d}", t1.A, *t1.B, **t1.C, ***t1.D)
-	}
-
-	// Now transfer t0 into t2
-	b.Reset()
-	enc.Encode(t0)
-	t2 = T2{}
-	dec.Decode(&t2)
-	if ***t2.A != 17 || **t2.B != 177 || *t2.C != 1777 || t2.D != 17777 {
-		t.Errorf("t0->t2 expected {17 177 1777 17777}; got {%d %d %d %d}", ***t2.A, **t2.B, *t2.C, t2.D)
-	}
-
-	// Now do t2 again but without pre-allocated pointers.
-	b.Reset()
-	enc.Encode(t0)
-	***t2.A = 0
-	**t2.B = 0
-	*t2.C = 0
-	t2.D = 0
-	dec.Decode(&t2)
-	if ***t2.A != 17 || **t2.B != 177 || *t2.C != 1777 || t2.D != 17777 {
-		t.Errorf("t0->t2 expected {17 177 1777 17777}; got {%d %d %d %d}", ***t2.A, **t2.B, *t2.C, t2.D)
-	}
-}
-
-type RT0 struct {
-	A int
-	B string
-	C float64
-}
-type RT1 struct {
-	C      float64
-	B      string
-	A      int
-	NotSet string
-}
-
-func TestReorderedFields(t *testing.T) {
-	var rt0 RT0
-	rt0.A = 17
-	rt0.B = "hello"
-	rt0.C = 3.14159
-	b := new(bytes.Buffer)
-	NewEncoder(b).Encode(rt0)
-	dec := NewDecoder(b)
-	var rt1 RT1
-	// Wire type is RT0, local type is RT1.
-	err := dec.Decode(&rt1)
-	if err != nil {
-		t.Fatal("decode error:", err)
-	}
-	if rt0.A != rt1.A || rt0.B != rt1.B || rt0.C != rt1.C {
-		t.Errorf("rt1->rt0: expected %v; got %v", rt0, rt1)
-	}
-}
-
-// Like an RT0 but with fields we'll ignore on the decode side.
-type IT0 struct {
-	A        int64
-	B        string
-	Ignore_d []int
-	Ignore_e [3]float64
-	Ignore_f bool
-	Ignore_g string
-	Ignore_h []byte
-	Ignore_i *RT1
-	Ignore_m map[string]int
-	C        float64
-}
-
-func TestIgnoredFields(t *testing.T) {
-	var it0 IT0
-	it0.A = 17
-	it0.B = "hello"
-	it0.C = 3.14159
-	it0.Ignore_d = []int{1, 2, 3}
-	it0.Ignore_e[0] = 1.0
-	it0.Ignore_e[1] = 2.0
-	it0.Ignore_e[2] = 3.0
-	it0.Ignore_f = true
-	it0.Ignore_g = "pay no attention"
-	it0.Ignore_h = []byte("to the curtain")
-	it0.Ignore_i = &RT1{3.1, "hi", 7, "hello"}
-	it0.Ignore_m = map[string]int{"one": 1, "two": 2}
-
-	b := new(bytes.Buffer)
-	NewEncoder(b).Encode(it0)
-	dec := NewDecoder(b)
-	var rt1 RT1
-	// Wire type is IT0, local type is RT1.
-	err := dec.Decode(&rt1)
-	if err != nil {
-		t.Error("error: ", err)
-	}
-	if int(it0.A) != rt1.A || it0.B != rt1.B || it0.C != rt1.C {
-		t.Errorf("rt0->rt1: expected %v; got %v", it0, rt1)
-	}
-}
-
-func TestBadRecursiveType(t *testing.T) {
-	type Rec ***Rec
-	var rec Rec
-	b := new(bytes.Buffer)
-	err := NewEncoder(b).Encode(&rec)
-	if err == nil {
-		t.Error("expected error; got none")
-	} else if strings.Index(err.Error(), "recursive") < 0 {
-		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.
-}
-
-type Indirect struct {
-	A ***[3]int
-	S ***[]int
-	M ****map[string]int
-}
-
-type Direct struct {
-	A [3]int
-	S []int
-	M map[string]int
-}
-
-func TestIndirectSliceMapArray(t *testing.T) {
-	// Marshal indirect, unmarshal to direct.
-	i := new(Indirect)
-	i.A = new(**[3]int)
-	*i.A = new(*[3]int)
-	**i.A = new([3]int)
-	***i.A = [3]int{1, 2, 3}
-	i.S = new(**[]int)
-	*i.S = new(*[]int)
-	**i.S = new([]int)
-	***i.S = []int{4, 5, 6}
-	i.M = new(***map[string]int)
-	*i.M = new(**map[string]int)
-	**i.M = new(*map[string]int)
-	***i.M = new(map[string]int)
-	****i.M = map[string]int{"one": 1, "two": 2, "three": 3}
-	b := new(bytes.Buffer)
-	NewEncoder(b).Encode(i)
-	dec := NewDecoder(b)
-	var d Direct
-	err := dec.Decode(&d)
-	if err != nil {
-		t.Error("error: ", err)
-	}
-	if len(d.A) != 3 || d.A[0] != 1 || d.A[1] != 2 || d.A[2] != 3 {
-		t.Errorf("indirect to direct: d.A is %v not %v", d.A, ***i.A)
-	}
-	if len(d.S) != 3 || d.S[0] != 4 || d.S[1] != 5 || d.S[2] != 6 {
-		t.Errorf("indirect to direct: d.S is %v not %v", d.S, ***i.S)
-	}
-	if len(d.M) != 3 || d.M["one"] != 1 || d.M["two"] != 2 || d.M["three"] != 3 {
-		t.Errorf("indirect to direct: d.M is %v not %v", d.M, ***i.M)
-	}
-	// Marshal direct, unmarshal to indirect.
-	d.A = [3]int{11, 22, 33}
-	d.S = []int{44, 55, 66}
-	d.M = map[string]int{"four": 4, "five": 5, "six": 6}
-	i = new(Indirect)
-	b.Reset()
-	NewEncoder(b).Encode(d)
-	dec = NewDecoder(b)
-	err = dec.Decode(&i)
-	if err != nil {
-		t.Fatal("error: ", err)
-	}
-	if len(***i.A) != 3 || (***i.A)[0] != 11 || (***i.A)[1] != 22 || (***i.A)[2] != 33 {
-		t.Errorf("direct to indirect: ***i.A is %v not %v", ***i.A, d.A)
-	}
-	if len(***i.S) != 3 || (***i.S)[0] != 44 || (***i.S)[1] != 55 || (***i.S)[2] != 66 {
-		t.Errorf("direct to indirect: ***i.S is %v not %v", ***i.S, ***i.S)
-	}
-	if len(****i.M) != 3 || (****i.M)["four"] != 4 || (****i.M)["five"] != 5 || (****i.M)["six"] != 6 {
-		t.Errorf("direct to indirect: ****i.M is %v not %v", ****i.M, d.M)
-	}
-}
-
-// An interface with several implementations
-type Squarer interface {
-	Square() int
-}
-
-type Int int
-
-func (i Int) Square() int {
-	return int(i * i)
-}
-
-type Float float64
-
-func (f Float) Square() int {
-	return int(f * f)
-}
-
-type Vector []int
-
-func (v Vector) Square() int {
-	sum := 0
-	for _, x := range v {
-		sum += x * x
-	}
-	return sum
-}
-
-type Point struct {
-	X, Y int
-}
-
-func (p Point) Square() int {
-	return p.X*p.X + p.Y*p.Y
-}
-
-// A struct with interfaces in it.
-type InterfaceItem struct {
-	I             int
-	Sq1, Sq2, Sq3 Squarer
-	F             float64
-	Sq            []Squarer
-}
-
-// The same struct without interfaces
-type NoInterfaceItem struct {
-	I int
-	F float64
-}
-
-func TestInterface(t *testing.T) {
-	iVal := Int(3)
-	fVal := Float(5)
-	// Sending a Vector will require that the receiver define a type in the middle of
-	// receiving the value for item2.
-	vVal := Vector{1, 2, 3}
-	b := new(bytes.Buffer)
-	item1 := &InterfaceItem{1, iVal, fVal, vVal, 11.5, []Squarer{iVal, fVal, nil, vVal}}
-	// Register the types.
-	Register(Int(0))
-	Register(Float(0))
-	Register(Vector{})
-	err := NewEncoder(b).Encode(item1)
-	if err != nil {
-		t.Error("expected no encode error; got", err)
-	}
-
-	item2 := InterfaceItem{}
-	err = NewDecoder(b).Decode(&item2)
-	if err != nil {
-		t.Fatal("decode:", err)
-	}
-	if item2.I != item1.I {
-		t.Error("normal int did not decode correctly")
-	}
-	if item2.Sq1 == nil || item2.Sq1.Square() != iVal.Square() {
-		t.Error("Int did not decode correctly")
-	}
-	if item2.Sq2 == nil || item2.Sq2.Square() != fVal.Square() {
-		t.Error("Float did not decode correctly")
-	}
-	if item2.Sq3 == nil || item2.Sq3.Square() != vVal.Square() {
-		t.Error("Vector did not decode correctly")
-	}
-	if item2.F != item1.F {
-		t.Error("normal float did not decode correctly")
-	}
-	// Now check that we received a slice of Squarers correctly, including a nil element
-	if len(item1.Sq) != len(item2.Sq) {
-		t.Fatalf("[]Squarer length wrong: got %d; expected %d", len(item2.Sq), len(item1.Sq))
-	}
-	for i, v1 := range item1.Sq {
-		v2 := item2.Sq[i]
-		if v1 == nil || v2 == nil {
-			if v1 != nil || v2 != nil {
-				t.Errorf("item %d inconsistent nils", i)
-			}
-		} else if v1.Square() != v2.Square() {
-			t.Errorf("item %d inconsistent values: %v %v", i, v1, v2)
-		}
-	}
-}
-
-// A struct with all basic types, stored in interfaces.
-type BasicInterfaceItem struct {
-	Int, Int8, Int16, Int32, Int64      interface{}
-	Uint, Uint8, Uint16, Uint32, Uint64 interface{}
-	Float32, Float64                    interface{}
-	Complex64, Complex128               interface{}
-	Bool                                interface{}
-	String                              interface{}
-	Bytes                               interface{}
-}
-
-func TestInterfaceBasic(t *testing.T) {
-	b := new(bytes.Buffer)
-	item1 := &BasicInterfaceItem{
-		int(1), int8(1), int16(1), int32(1), int64(1),
-		uint(1), uint8(1), uint16(1), uint32(1), uint64(1),
-		float32(1), 1.0,
-		complex64(1i), complex128(1i),
-		true,
-		"hello",
-		[]byte("sailor"),
-	}
-	err := NewEncoder(b).Encode(item1)
-	if err != nil {
-		t.Error("expected no encode error; got", err)
-	}
-
-	item2 := &BasicInterfaceItem{}
-	err = NewDecoder(b).Decode(&item2)
-	if err != nil {
-		t.Fatal("decode:", err)
-	}
-	if !reflect.DeepEqual(item1, item2) {
-		t.Errorf("encode expected %v got %v", item1, item2)
-	}
-	// Hand check a couple for correct types.
-	if v, ok := item2.Bool.(bool); !ok || !v {
-		t.Error("boolean should be true")
-	}
-	if v, ok := item2.String.(string); !ok || v != item1.String.(string) {
-		t.Errorf("string should be %v is %v", item1.String, v)
-	}
-}
-
-type String string
-
-type PtrInterfaceItem struct {
-	Str1 interface{} // basic
-	Str2 interface{} // derived
-}
-
-// We'll send pointers; should receive values.
-// Also check that we can register T but send *T.
-func TestInterfacePointer(t *testing.T) {
-	b := new(bytes.Buffer)
-	str1 := "howdy"
-	str2 := String("kiddo")
-	item1 := &PtrInterfaceItem{
-		&str1,
-		&str2,
-	}
-	// Register the type.
-	Register(str2)
-	err := NewEncoder(b).Encode(item1)
-	if err != nil {
-		t.Error("expected no encode error; got", err)
-	}
-
-	item2 := &PtrInterfaceItem{}
-	err = NewDecoder(b).Decode(&item2)
-	if err != nil {
-		t.Fatal("decode:", err)
-	}
-	// Hand test for correct types and values.
-	if v, ok := item2.Str1.(string); !ok || v != str1 {
-		t.Errorf("basic string failed: %q should be %q", v, str1)
-	}
-	if v, ok := item2.Str2.(String); !ok || v != str2 {
-		t.Errorf("derived type String failed: %q should be %q", v, str2)
-	}
-}
-
-func TestIgnoreInterface(t *testing.T) {
-	iVal := Int(3)
-	fVal := Float(5)
-	// Sending a Point will require that the receiver define a type in the middle of
-	// receiving the value for item2.
-	pVal := Point{2, 3}
-	b := new(bytes.Buffer)
-	item1 := &InterfaceItem{1, iVal, fVal, pVal, 11.5, nil}
-	// Register the types.
-	Register(Int(0))
-	Register(Float(0))
-	Register(Point{})
-	err := NewEncoder(b).Encode(item1)
-	if err != nil {
-		t.Error("expected no encode error; got", err)
-	}
-
-	item2 := NoInterfaceItem{}
-	err = NewDecoder(b).Decode(&item2)
-	if err != nil {
-		t.Fatal("decode:", err)
-	}
-	if item2.I != item1.I {
-		t.Error("normal int did not decode correctly")
-	}
-	if item2.F != item2.F {
-		t.Error("normal float did not decode correctly")
-	}
-}
-
-type U struct {
-	A int
-	B string
-	c float64
-	D uint
-}
-
-func TestUnexportedFields(t *testing.T) {
-	var u0 U
-	u0.A = 17
-	u0.B = "hello"
-	u0.c = 3.14159
-	u0.D = 23
-	b := new(bytes.Buffer)
-	NewEncoder(b).Encode(u0)
-	dec := NewDecoder(b)
-	var u1 U
-	u1.c = 1234.
-	err := dec.Decode(&u1)
-	if err != nil {
-		t.Fatal("decode error:", err)
-	}
-	if u0.A != u0.A || u0.B != u1.B || u0.D != u1.D {
-		t.Errorf("u1->u0: expected %v; got %v", u0, u1)
-	}
-	if u1.c != 1234. {
-		t.Error("u1.c modified")
-	}
-}
-
-var singletons = []interface{}{
-	true,
-	7,
-	3.2,
-	"hello",
-	[3]int{11, 22, 33},
-	[]float32{0.5, 0.25, 0.125},
-	map[string]int{"one": 1, "two": 2},
-}
-
-func TestDebugSingleton(t *testing.T) {
-	if debugFunc == nil {
-		return
-	}
-	b := new(bytes.Buffer)
-	// Accumulate a number of values and print them out all at once.
-	for _, x := range singletons {
-		err := NewEncoder(b).Encode(x)
-		if err != nil {
-			t.Fatal("encode:", err)
-		}
-	}
-	debugFunc(b)
-}
-
-// A type that won't be defined in the gob until we send it in an interface value.
-type OnTheFly struct {
-	A int
-}
-
-type DT struct {
-	//	X OnTheFly
-	A     int
-	B     string
-	C     float64
-	I     interface{}
-	J     interface{}
-	I_nil interface{}
-	M     map[string]int
-	T     [3]int
-	S     []string
-}
-
-func newDT() DT {
-	var dt DT
-	dt.A = 17
-	dt.B = "hello"
-	dt.C = 3.14159
-	dt.I = 271828
-	dt.J = OnTheFly{3}
-	dt.I_nil = nil
-	dt.M = map[string]int{"one": 1, "two": 2}
-	dt.T = [3]int{11, 22, 33}
-	dt.S = []string{"hi", "joe"}
-	return dt
-}
-
-func TestDebugStruct(t *testing.T) {
-	if debugFunc == nil {
-		return
-	}
-	Register(OnTheFly{})
-	dt := newDT()
-	b := new(bytes.Buffer)
-	err := NewEncoder(b).Encode(dt)
-	if err != nil {
-		t.Fatal("encode:", err)
-	}
-	debugBuffer := bytes.NewBuffer(b.Bytes())
-	dt2 := &DT{}
-	err = NewDecoder(b).Decode(&dt2)
-	if err != nil {
-		t.Error("decode:", err)
-	}
-	debugFunc(debugBuffer)
-}
-
-func encFuzzDec(rng *rand.Rand, in interface{}) error {
-	buf := new(bytes.Buffer)
-	enc := NewEncoder(buf)
-	if err := enc.Encode(&in); err != nil {
-		return err
-	}
-
-	b := buf.Bytes()
-	for i, bi := range b {
-		if rng.Intn(10) < 3 {
-			b[i] = bi + uint8(rng.Intn(256))
-		}
-	}
-
-	dec := NewDecoder(buf)
-	var e interface{}
-	if err := dec.Decode(&e); err != nil {
-		return err
-	}
-	return nil
-}
-
-// This does some "fuzz testing" by attempting to decode a sequence of random bytes.
-func TestFuzz(t *testing.T) {
-	if !*doFuzzTests {
-		t.Logf("disabled; run with -gob.fuzz to enable")
-		return
-	}
-
-	// all possible inputs
-	input := []interface{}{
-		new(int),
-		new(float32),
-		new(float64),
-		new(complex128),
-		&ByteStruct{255},
-		&ArrayStruct{},
-		&StringStruct{"hello"},
-		&GobTest1{0, &StringStruct{"hello"}},
-	}
-	testFuzz(t, time.Now().UnixNano(), 100, input...)
-}
-
-func TestFuzzRegressions(t *testing.T) {
-	if !*doFuzzTests {
-		t.Logf("disabled; run with -gob.fuzz to enable")
-		return
-	}
-
-	// An instance triggering a type name of length ~102 GB.
-	testFuzz(t, 1328492090837718000, 100, new(float32))
-	// An instance triggering a type name of 1.6 GB.
-	// Note: can take several minutes to run.
-	testFuzz(t, 1330522872628565000, 100, new(int))
-}
-
-func testFuzz(t *testing.T, seed int64, n int, input ...interface{}) {
-	for _, e := range input {
-		t.Logf("seed=%d n=%d e=%T", seed, n, e)
-		rng := rand.New(rand.NewSource(seed))
-		for i := 0; i < n; i++ {
-			encFuzzDec(rng, e)
-		}
-	}
-}
-
-// TestFuzzOneByte tries to decode corrupted input sequences
-// and checks that no panic occurs.
-func TestFuzzOneByte(t *testing.T) {
-	buf := new(bytes.Buffer)
-	Register(OnTheFly{})
-	dt := newDT()
-	if err := NewEncoder(buf).Encode(dt); err != nil {
-		t.Fatal(err)
-	}
-	s := buf.String()
-
-	indices := make([]int, 0, len(s))
-	for i := 0; i < len(s); i++ {
-		switch i {
-		case 14, 167, 231, 265: // a slice length, corruptions are not handled yet.
-			continue
-		}
-		indices = append(indices, i)
-	}
-	if testing.Short() {
-		indices = []int{1, 111, 178} // known fixed panics
-	}
-	for _, i := range indices {
-		for j := 0; j < 256; j += 3 {
-			b := []byte(s)
-			b[i] ^= byte(j)
-			var e DT
-			func() {
-				defer func() {
-					if p := recover(); p != nil {
-						t.Errorf("crash for b[%d] ^= 0x%x", i, j)
-						panic(p)
-					}
-				}()
-				err := NewDecoder(bytes.NewReader(b)).Decode(&e)
-				_ = err
-			}()
-		}
-	}
-}
diff --git a/src/pkg/encoding/gob/debug.go b/src/pkg/encoding/gob/debug.go
deleted file mode 100644
index 6117eb0..0000000
--- a/src/pkg/encoding/gob/debug.go
+++ /dev/null
@@ -1,705 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Delete the next line to include in the gob package.
-// +build ignore
-
-package gob
-
-// This file is not normally included in the gob package.  Used only for debugging the package itself.
-// Except for reading uints, it is an implementation of a reader that is independent of
-// the one implemented by Decoder.
-// To enable the Debug function, delete the +build ignore line above and do
-//	go install
-
-import (
-	"bytes"
-	"fmt"
-	"io"
-	"os"
-	"strings"
-	"sync"
-)
-
-var dumpBytes = false // If true, print the remaining bytes in the input buffer at each item.
-
-// Init installs the debugging facility. If this file is not compiled in the
-// package, the tests in codec_test.go are no-ops.
-func init() {
-	debugFunc = Debug
-}
-
-var (
-	blanks = bytes.Repeat([]byte{' '}, 3*10)
-	empty  = []byte(": <empty>\n")
-	tabs   = strings.Repeat("\t", 100)
-)
-
-// tab indents itself when printed.
-type tab int
-
-func (t tab) String() string {
-	n := int(t)
-	if n > len(tabs) {
-		n = len(tabs)
-	}
-	return tabs[0:n]
-}
-
-func (t tab) print() {
-	fmt.Fprint(os.Stderr, t)
-}
-
-// A peekReader wraps an io.Reader, allowing one to peek ahead to see
-// what's coming without stealing the data from the client of the Reader.
-type peekReader struct {
-	r    io.Reader
-	data []byte // read-ahead data
-}
-
-// newPeekReader returns a peekReader that wraps r.
-func newPeekReader(r io.Reader) *peekReader {
-	return &peekReader{r: r}
-}
-
-// Read is the usual method. It will first take data that has been read ahead.
-func (p *peekReader) Read(b []byte) (n int, err error) {
-	if len(p.data) == 0 {
-		return p.r.Read(b)
-	}
-	// Satisfy what's possible from the read-ahead data.
-	n = copy(b, p.data)
-	// Move data down to beginning of slice, to avoid endless growth
-	copy(p.data, p.data[n:])
-	p.data = p.data[:len(p.data)-n]
-	return
-}
-
-// peek returns as many bytes as possible from the unread
-// portion of the stream, up to the length of b.
-func (p *peekReader) peek(b []byte) (n int, err error) {
-	if len(p.data) > 0 {
-		n = copy(b, p.data)
-		if n == len(b) {
-			return
-		}
-		b = b[n:]
-	}
-	if len(b) == 0 {
-		return
-	}
-	m, e := io.ReadFull(p.r, b)
-	if m > 0 {
-		p.data = append(p.data, b[:m]...)
-	}
-	n += m
-	if e == io.ErrUnexpectedEOF {
-		// That means m > 0 but we reached EOF. If we got data
-		// we won't complain about not being able to peek enough.
-		if n > 0 {
-			e = nil
-		} else {
-			e = io.EOF
-		}
-	}
-	return n, e
-}
-
-type debugger struct {
-	mutex          sync.Mutex
-	remain         int  // the number of bytes known to remain in the input
-	remainingKnown bool // the value of 'remain' is valid
-	r              *peekReader
-	wireType       map[typeId]*wireType
-	tmp            []byte // scratch space for decoding uints.
-}
-
-// dump prints the next nBytes of the input.
-// It arranges to print the output aligned from call to
-// call, to make it easy to see what has been consumed.
-func (deb *debugger) dump(format string, args ...interface{}) {
-	if !dumpBytes {
-		return
-	}
-	fmt.Fprintf(os.Stderr, format+" ", args...)
-	if !deb.remainingKnown {
-		return
-	}
-	if deb.remain < 0 {
-		fmt.Fprintf(os.Stderr, "remaining byte count is negative! %d\n", deb.remain)
-		return
-	}
-	data := make([]byte, deb.remain)
-	n, _ := deb.r.peek(data)
-	if n == 0 {
-		os.Stderr.Write(empty)
-		return
-	}
-	b := new(bytes.Buffer)
-	fmt.Fprintf(b, "[%d]{\n", deb.remain)
-	// Blanks until first byte
-	lineLength := 0
-	if n := len(data); n%10 != 0 {
-		lineLength = 10 - n%10
-		fmt.Fprintf(b, "\t%s", blanks[:lineLength*3])
-	}
-	// 10 bytes per line
-	for len(data) > 0 {
-		if lineLength == 0 {
-			fmt.Fprint(b, "\t")
-		}
-		m := 10 - lineLength
-		lineLength = 0
-		if m > len(data) {
-			m = len(data)
-		}
-		fmt.Fprintf(b, "% x\n", data[:m])
-		data = data[m:]
-	}
-	fmt.Fprint(b, "}\n")
-	os.Stderr.Write(b.Bytes())
-}
-
-// Debug prints a human-readable representation of the gob data read from r.
-// It is a no-op unless debugging was enabled when the package was built.
-func Debug(r io.Reader) {
-	err := debug(r)
-	if err != nil {
-		fmt.Fprintf(os.Stderr, "gob debug: %s\n", err)
-	}
-}
-
-// debug implements Debug, but catches panics and returns
-// them as errors to be printed by Debug.
-func debug(r io.Reader) (err error) {
-	defer catchError(&err)
-	fmt.Fprintln(os.Stderr, "Start of debugging")
-	deb := &debugger{
-		r:        newPeekReader(r),
-		wireType: make(map[typeId]*wireType),
-		tmp:      make([]byte, 16),
-	}
-	if b, ok := r.(*bytes.Buffer); ok {
-		deb.remain = b.Len()
-		deb.remainingKnown = true
-	}
-	deb.gobStream()
-	return
-}
-
-// note that we've consumed some bytes
-func (deb *debugger) consumed(n int) {
-	if deb.remainingKnown {
-		deb.remain -= n
-	}
-}
-
-// int64 decodes and returns the next integer, which must be present.
-// Don't call this if you could be at EOF.
-func (deb *debugger) int64() int64 {
-	return toInt(deb.uint64())
-}
-
-// uint64 returns and decodes the next unsigned integer, which must be present.
-// Don't call this if you could be at EOF.
-// TODO: handle errors better.
-func (deb *debugger) uint64() uint64 {
-	n, w, err := decodeUintReader(deb.r, deb.tmp)
-	if err != nil {
-		errorf("debug: read error: %s", err)
-	}
-	deb.consumed(w)
-	return n
-}
-
-// GobStream:
-//	DelimitedMessage* (until EOF)
-func (deb *debugger) gobStream() {
-	// Make sure we're single-threaded through here.
-	deb.mutex.Lock()
-	defer deb.mutex.Unlock()
-
-	for deb.delimitedMessage(0) {
-	}
-}
-
-// DelimitedMessage:
-//	uint(lengthOfMessage) Message
-func (deb *debugger) delimitedMessage(indent tab) bool {
-	for {
-		n := deb.loadBlock(true)
-		if n < 0 {
-			return false
-		}
-		deb.dump("Delimited message of length %d", n)
-		deb.message(indent)
-	}
-	return true
-}
-
-// loadBlock preps us to read a message
-// of the length specified next in the input. It returns
-// the length of the block. The argument tells whether
-// an EOF is acceptable now.  If it is and one is found,
-// the return value is negative.
-func (deb *debugger) loadBlock(eofOK bool) int {
-	n64, w, err := decodeUintReader(deb.r, deb.tmp) // deb.uint64 will error at EOF
-	if err != nil {
-		if eofOK && err == io.EOF {
-			return -1
-		}
-		errorf("debug: unexpected error: %s", err)
-	}
-	deb.consumed(w)
-	n := int(n64)
-	if n < 0 {
-		errorf("huge value for message length: %d", n64)
-	}
-	return int(n)
-}
-
-// Message:
-//	TypeSequence TypedValue
-// TypeSequence
-//	(TypeDefinition DelimitedTypeDefinition*)?
-// DelimitedTypeDefinition:
-//	uint(lengthOfTypeDefinition) TypeDefinition
-// TypedValue:
-//	int(typeId) Value
-func (deb *debugger) message(indent tab) bool {
-	for {
-		// Convert the uint64 to a signed integer typeId
-		uid := deb.int64()
-		id := typeId(uid)
-		deb.dump("type id=%d", id)
-		if id < 0 {
-			deb.typeDefinition(indent, -id)
-			n := deb.loadBlock(false)
-			deb.dump("Message of length %d", n)
-			continue
-		} else {
-			deb.value(indent, id)
-			break
-		}
-	}
-	return true
-}
-
-// Helper methods to make it easy to scan a type descriptor.
-
-// common returns the CommonType at the input point.
-func (deb *debugger) common() CommonType {
-	fieldNum := -1
-	name := ""
-	id := typeId(0)
-	for {
-		delta := deb.delta(-1)
-		if delta == 0 {
-			break
-		}
-		fieldNum += delta
-		switch fieldNum {
-		case 0:
-			name = deb.string()
-		case 1:
-			// Id typeId
-			id = deb.typeId()
-		default:
-			errorf("corrupted CommonType")
-		}
-	}
-	return CommonType{name, id}
-}
-
-// uint returns the unsigned int at the input point, as a uint (not uint64).
-func (deb *debugger) uint() uint {
-	return uint(deb.uint64())
-}
-
-// int returns the signed int at the input point, as an int (not int64).
-func (deb *debugger) int() int {
-	return int(deb.int64())
-}
-
-// typeId returns the type id at the input point.
-func (deb *debugger) typeId() typeId {
-	return typeId(deb.int64())
-}
-
-// string returns the string at the input point.
-func (deb *debugger) string() string {
-	x := int(deb.uint64())
-	b := make([]byte, x)
-	nb, _ := deb.r.Read(b)
-	if nb != x {
-		errorf("corrupted type")
-	}
-	deb.consumed(nb)
-	return string(b)
-}
-
-// delta returns the field delta at the input point.  The expect argument,
-// if non-negative, identifies what the value should be.
-func (deb *debugger) delta(expect int) int {
-	delta := int(deb.uint64())
-	if delta < 0 || (expect >= 0 && delta != expect) {
-		errorf("decode: corrupted type: delta %d expected %d", delta, expect)
-	}
-	return delta
-}
-
-// TypeDefinition:
-//	[int(-typeId) (already read)] encodingOfWireType
-func (deb *debugger) typeDefinition(indent tab, id typeId) {
-	deb.dump("type definition for id %d", id)
-	// Encoding is of a wireType. Decode the structure as usual
-	fieldNum := -1
-	wire := new(wireType)
-	// A wireType defines a single field.
-	delta := deb.delta(-1)
-	fieldNum += delta
-	switch fieldNum {
-	case 0: // array type, one field of {{Common}, elem, length}
-		// Field number 0 is CommonType
-		deb.delta(1)
-		com := deb.common()
-		// Field number 1 is type Id of elem
-		deb.delta(1)
-		id := deb.typeId()
-		// Field number 3 is length
-		deb.delta(1)
-		length := deb.int()
-		wire.ArrayT = &arrayType{com, id, length}
-
-	case 1: // slice type, one field of {{Common}, elem}
-		// Field number 0 is CommonType
-		deb.delta(1)
-		com := deb.common()
-		// Field number 1 is type Id of elem
-		deb.delta(1)
-		id := deb.typeId()
-		wire.SliceT = &sliceType{com, id}
-
-	case 2: // struct type, one field of {{Common}, []fieldType}
-		// Field number 0 is CommonType
-		deb.delta(1)
-		com := deb.common()
-		// Field number 1 is slice of FieldType
-		deb.delta(1)
-		numField := int(deb.uint())
-		field := make([]*fieldType, numField)
-		for i := 0; i < numField; i++ {
-			field[i] = new(fieldType)
-			deb.delta(1) // field 0 of fieldType: name
-			field[i].Name = deb.string()
-			deb.delta(1) // field 1 of fieldType: id
-			field[i].Id = deb.typeId()
-			deb.delta(0) // end of fieldType
-		}
-		wire.StructT = &structType{com, field}
-
-	case 3: // map type, one field of {{Common}, key, elem}
-		// Field number 0 is CommonType
-		deb.delta(1)
-		com := deb.common()
-		// Field number 1 is type Id of key
-		deb.delta(1)
-		keyId := deb.typeId()
-		// Field number 2 is type Id of elem
-		deb.delta(1)
-		elemId := deb.typeId()
-		wire.MapT = &mapType{com, keyId, elemId}
-	case 4: // GobEncoder type, one field of {{Common}}
-		// Field number 0 is CommonType
-		deb.delta(1)
-		com := deb.common()
-		wire.GobEncoderT = &gobEncoderType{com}
-	case 5: // BinaryMarshaler type, one field of {{Common}}
-		// Field number 0 is CommonType
-		deb.delta(1)
-		com := deb.common()
-		wire.BinaryMarshalerT = &gobEncoderType{com}
-	case 6: // TextMarshaler type, one field of {{Common}}
-		// Field number 0 is CommonType
-		deb.delta(1)
-		com := deb.common()
-		wire.TextMarshalerT = &gobEncoderType{com}
-	default:
-		errorf("bad field in type %d", fieldNum)
-	}
-	deb.printWireType(indent, wire)
-	deb.delta(0) // end inner type (arrayType, etc.)
-	deb.delta(0) // end wireType
-	// Remember we've seen this type.
-	deb.wireType[id] = wire
-}
-
-// Value:
-//	SingletonValue | StructValue
-func (deb *debugger) value(indent tab, id typeId) {
-	wire, ok := deb.wireType[id]
-	if ok && wire.StructT != nil {
-		deb.structValue(indent, id)
-	} else {
-		deb.singletonValue(indent, id)
-	}
-}
-
-// SingletonValue:
-//	uint(0) FieldValue
-func (deb *debugger) singletonValue(indent tab, id typeId) {
-	deb.dump("Singleton value")
-	// is it a builtin type?
-	wire := deb.wireType[id]
-	_, ok := builtinIdToType[id]
-	if !ok && wire == nil {
-		errorf("type id %d not defined", id)
-	}
-	m := deb.uint64()
-	if m != 0 {
-		errorf("expected zero; got %d", m)
-	}
-	deb.fieldValue(indent, id)
-}
-
-// InterfaceValue:
-//	NilInterfaceValue | NonNilInterfaceValue
-func (deb *debugger) interfaceValue(indent tab) {
-	deb.dump("Start of interface value")
-	if nameLen := deb.uint64(); nameLen == 0 {
-		deb.nilInterfaceValue(indent)
-	} else {
-		deb.nonNilInterfaceValue(indent, int(nameLen))
-	}
-}
-
-// NilInterfaceValue:
-//	uint(0) [already read]
-func (deb *debugger) nilInterfaceValue(indent tab) int {
-	fmt.Fprintf(os.Stderr, "%snil interface\n", indent)
-	return 0
-}
-
-// NonNilInterfaceValue:
-//	ConcreteTypeName TypeSequence InterfaceContents
-// ConcreteTypeName:
-//	uint(lengthOfName) [already read=n] name
-// InterfaceContents:
-//	int(concreteTypeId) DelimitedValue
-// DelimitedValue:
-//	uint(length) Value
-func (deb *debugger) nonNilInterfaceValue(indent tab, nameLen int) {
-	// ConcreteTypeName
-	b := make([]byte, nameLen)
-	deb.r.Read(b) // TODO: CHECK THESE READS!!
-	deb.consumed(nameLen)
-	name := string(b)
-
-	for {
-		id := deb.typeId()
-		if id < 0 {
-			deb.typeDefinition(indent, -id)
-			n := deb.loadBlock(false)
-			deb.dump("Nested message of length %d", n)
-		} else {
-			// DelimitedValue
-			x := deb.uint64() // in case we want to ignore the value; we don't.
-			fmt.Fprintf(os.Stderr, "%sinterface value, type %q id=%d; valueLength %d\n", indent, name, id, x)
-			deb.value(indent, id)
-			break
-		}
-	}
-}
-
-// printCommonType prints a common type; used by printWireType.
-func (deb *debugger) printCommonType(indent tab, kind string, common *CommonType) {
-	indent.print()
-	fmt.Fprintf(os.Stderr, "%s %q id=%d\n", kind, common.Name, common.Id)
-}
-
-// printWireType prints the contents of a wireType.
-func (deb *debugger) printWireType(indent tab, wire *wireType) {
-	fmt.Fprintf(os.Stderr, "%stype definition {\n", indent)
-	indent++
-	switch {
-	case wire.ArrayT != nil:
-		deb.printCommonType(indent, "array", &wire.ArrayT.CommonType)
-		fmt.Fprintf(os.Stderr, "%slen %d\n", indent+1, wire.ArrayT.Len)
-		fmt.Fprintf(os.Stderr, "%selemid %d\n", indent+1, wire.ArrayT.Elem)
-	case wire.MapT != nil:
-		deb.printCommonType(indent, "map", &wire.MapT.CommonType)
-		fmt.Fprintf(os.Stderr, "%skey id=%d\n", indent+1, wire.MapT.Key)
-		fmt.Fprintf(os.Stderr, "%selem id=%d\n", indent+1, wire.MapT.Elem)
-	case wire.SliceT != nil:
-		deb.printCommonType(indent, "slice", &wire.SliceT.CommonType)
-		fmt.Fprintf(os.Stderr, "%selem id=%d\n", indent+1, wire.SliceT.Elem)
-	case wire.StructT != nil:
-		deb.printCommonType(indent, "struct", &wire.StructT.CommonType)
-		for i, field := range wire.StructT.Field {
-			fmt.Fprintf(os.Stderr, "%sfield %d:\t%s\tid=%d\n", indent+1, i, field.Name, field.Id)
-		}
-	case wire.GobEncoderT != nil:
-		deb.printCommonType(indent, "GobEncoder", &wire.GobEncoderT.CommonType)
-	}
-	indent--
-	fmt.Fprintf(os.Stderr, "%s}\n", indent)
-}
-
-// fieldValue prints a value of any type, such as a struct field.
-// FieldValue:
-//	builtinValue | ArrayValue | MapValue | SliceValue | StructValue | InterfaceValue
-func (deb *debugger) fieldValue(indent tab, id typeId) {
-	_, ok := builtinIdToType[id]
-	if ok {
-		if id == tInterface {
-			deb.interfaceValue(indent)
-		} else {
-			deb.printBuiltin(indent, id)
-		}
-		return
-	}
-	wire, ok := deb.wireType[id]
-	if !ok {
-		errorf("type id %d not defined", id)
-	}
-	switch {
-	case wire.ArrayT != nil:
-		deb.arrayValue(indent, wire)
-	case wire.MapT != nil:
-		deb.mapValue(indent, wire)
-	case wire.SliceT != nil:
-		deb.sliceValue(indent, wire)
-	case wire.StructT != nil:
-		deb.structValue(indent, id)
-	case wire.GobEncoderT != nil:
-		deb.gobEncoderValue(indent, id)
-	default:
-		panic("bad wire type for field")
-	}
-}
-
-// printBuiltin prints a value not of a fundamental type, that is,
-// one whose type is known to gobs at bootstrap time.
-func (deb *debugger) printBuiltin(indent tab, id typeId) {
-	switch id {
-	case tBool:
-		x := deb.int64()
-		if x == 0 {
-			fmt.Fprintf(os.Stderr, "%sfalse\n", indent)
-		} else {
-			fmt.Fprintf(os.Stderr, "%strue\n", indent)
-		}
-	case tInt:
-		x := deb.int64()
-		fmt.Fprintf(os.Stderr, "%s%d\n", indent, x)
-	case tUint:
-		x := deb.int64()
-		fmt.Fprintf(os.Stderr, "%s%d\n", indent, x)
-	case tFloat:
-		x := deb.uint64()
-		fmt.Fprintf(os.Stderr, "%s%g\n", indent, floatFromBits(x))
-	case tComplex:
-		r := deb.uint64()
-		i := deb.uint64()
-		fmt.Fprintf(os.Stderr, "%s%g+%gi\n", indent, floatFromBits(r), floatFromBits(i))
-	case tBytes:
-		x := int(deb.uint64())
-		b := make([]byte, x)
-		deb.r.Read(b)
-		deb.consumed(x)
-		fmt.Fprintf(os.Stderr, "%s{% x}=%q\n", indent, b, b)
-	case tString:
-		x := int(deb.uint64())
-		b := make([]byte, x)
-		deb.r.Read(b)
-		deb.consumed(x)
-		fmt.Fprintf(os.Stderr, "%s%q\n", indent, b)
-	default:
-		panic("unknown builtin")
-	}
-}
-
-// ArrayValue:
-//	uint(n) FieldValue*n
-func (deb *debugger) arrayValue(indent tab, wire *wireType) {
-	elemId := wire.ArrayT.Elem
-	u := deb.uint64()
-	length := int(u)
-	for i := 0; i < length; i++ {
-		deb.fieldValue(indent, elemId)
-	}
-	if length != wire.ArrayT.Len {
-		fmt.Fprintf(os.Stderr, "%s(wrong length for array: %d should be %d)\n", indent, length, wire.ArrayT.Len)
-	}
-}
-
-// MapValue:
-//	uint(n) (FieldValue FieldValue)*n  [n (key, value) pairs]
-func (deb *debugger) mapValue(indent tab, wire *wireType) {
-	keyId := wire.MapT.Key
-	elemId := wire.MapT.Elem
-	u := deb.uint64()
-	length := int(u)
-	for i := 0; i < length; i++ {
-		deb.fieldValue(indent+1, keyId)
-		deb.fieldValue(indent+1, elemId)
-	}
-}
-
-// SliceValue:
-//	uint(n) (n FieldValue)
-func (deb *debugger) sliceValue(indent tab, wire *wireType) {
-	elemId := wire.SliceT.Elem
-	u := deb.uint64()
-	length := int(u)
-	deb.dump("Start of slice of length %d", length)
-
-	for i := 0; i < length; i++ {
-		deb.fieldValue(indent, elemId)
-	}
-}
-
-// StructValue:
-//	(uint(fieldDelta) FieldValue)*
-func (deb *debugger) structValue(indent tab, id typeId) {
-	deb.dump("Start of struct value of %q id=%d\n<<\n", id.name(), id)
-	fmt.Fprintf(os.Stderr, "%s%s struct {\n", indent, id.name())
-	wire, ok := deb.wireType[id]
-	if !ok {
-		errorf("type id %d not defined", id)
-	}
-	strct := wire.StructT
-	fieldNum := -1
-	indent++
-	for {
-		delta := deb.uint64()
-		if delta == 0 { // struct terminator is zero delta fieldnum
-			break
-		}
-		fieldNum += int(delta)
-		if fieldNum < 0 || fieldNum >= len(strct.Field) {
-			deb.dump("field number out of range: prevField=%d delta=%d", fieldNum-int(delta), delta)
-			break
-		}
-		fmt.Fprintf(os.Stderr, "%sfield %d:\t%s\n", indent, fieldNum, wire.StructT.Field[fieldNum].Name)
-		deb.fieldValue(indent+1, strct.Field[fieldNum].Id)
-	}
-	indent--
-	fmt.Fprintf(os.Stderr, "%s} // end %s struct\n", indent, id.name())
-	deb.dump(">> End of struct value of type %d %q", id, id.name())
-}
-
-// GobEncoderValue:
-//	uint(n) byte*n
-func (deb *debugger) gobEncoderValue(indent tab, id typeId) {
-	len := deb.uint64()
-	deb.dump("GobEncoder value of %q id=%d, length %d\n", id.name(), id, len)
-	fmt.Fprintf(os.Stderr, "%s%s (implements GobEncoder)\n", indent, id.name())
-	data := make([]byte, len)
-	_, err := deb.r.Read(data)
-	if err != nil {
-		errorf("gobEncoder data read: %s", err)
-	}
-	fmt.Fprintf(os.Stderr, "%s[% .2x]\n", indent+1, data)
-}
diff --git a/src/pkg/encoding/gob/decode.go b/src/pkg/encoding/gob/decode.go
deleted file mode 100644
index d851314..0000000
--- a/src/pkg/encoding/gob/decode.go
+++ /dev/null
@@ -1,1317 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package gob
-
-// TODO(rsc): When garbage collector changes, revisit
-// the allocations in this file that use unsafe.Pointer.
-
-import (
-	"bytes"
-	"encoding"
-	"errors"
-	"io"
-	"math"
-	"reflect"
-	"unsafe"
-)
-
-var (
-	errBadUint = errors.New("gob: encoded unsigned integer out of range")
-	errBadType = errors.New("gob: unknown type id or corrupted data")
-	errRange   = errors.New("gob: bad data: field numbers out of bounds")
-)
-
-// decoderState is the execution state of an instance of the decoder. A new state
-// is created for nested objects.
-type decoderState struct {
-	dec *Decoder
-	// The buffer is stored with an extra indirection because it may be replaced
-	// if we load a type during decode (when reading an interface value).
-	b        *bytes.Buffer
-	fieldnum int // the last field number read.
-	buf      []byte
-	next     *decoderState // for free list
-}
-
-// We pass the bytes.Buffer separately for easier testing of the infrastructure
-// without requiring a full Decoder.
-func (dec *Decoder) newDecoderState(buf *bytes.Buffer) *decoderState {
-	d := dec.freeList
-	if d == nil {
-		d = new(decoderState)
-		d.dec = dec
-		d.buf = make([]byte, uint64Size)
-	} else {
-		dec.freeList = d.next
-	}
-	d.b = buf
-	return d
-}
-
-func (dec *Decoder) freeDecoderState(d *decoderState) {
-	d.next = dec.freeList
-	dec.freeList = d
-}
-
-func overflow(name string) error {
-	return errors.New(`value for "` + name + `" out of range`)
-}
-
-// decodeUintReader reads an encoded unsigned integer from an io.Reader.
-// Used only by the Decoder to read the message length.
-func decodeUintReader(r io.Reader, buf []byte) (x uint64, width int, err error) {
-	width = 1
-	n, err := io.ReadFull(r, buf[0:width])
-	if n == 0 {
-		return
-	}
-	b := buf[0]
-	if b <= 0x7f {
-		return uint64(b), width, nil
-	}
-	n = -int(int8(b))
-	if n > uint64Size {
-		err = errBadUint
-		return
-	}
-	width, err = io.ReadFull(r, buf[0:n])
-	if err != nil {
-		if err == io.EOF {
-			err = io.ErrUnexpectedEOF
-		}
-		return
-	}
-	// Could check that the high byte is zero but it's not worth it.
-	for _, b := range buf[0:width] {
-		x = x<<8 | uint64(b)
-	}
-	width++ // +1 for length byte
-	return
-}
-
-// decodeUint reads an encoded unsigned integer from state.r.
-// Does not check for overflow.
-func (state *decoderState) decodeUint() (x uint64) {
-	b, err := state.b.ReadByte()
-	if err != nil {
-		error_(err)
-	}
-	if b <= 0x7f {
-		return uint64(b)
-	}
-	n := -int(int8(b))
-	if n > uint64Size {
-		error_(errBadUint)
-	}
-	width, err := state.b.Read(state.buf[0:n])
-	if err != nil {
-		error_(err)
-	}
-	// Don't need to check error; it's safe to loop regardless.
-	// Could check that the high byte is zero but it's not worth it.
-	for _, b := range state.buf[0:width] {
-		x = x<<8 | uint64(b)
-	}
-	return x
-}
-
-// decodeInt reads an encoded signed integer from state.r.
-// Does not check for overflow.
-func (state *decoderState) decodeInt() int64 {
-	x := state.decodeUint()
-	if x&1 != 0 {
-		return ^int64(x >> 1)
-	}
-	return int64(x >> 1)
-}
-
-// decOp is the signature of a decoding operator for a given type.
-type decOp func(i *decInstr, state *decoderState, p unsafe.Pointer)
-
-// The 'instructions' of the decoding machine
-type decInstr struct {
-	op     decOp
-	field  int     // field number of the wire type
-	indir  int     // how many pointer indirections to reach the value in the struct
-	offset uintptr // offset in the structure of the field to encode
-	ovfl   error   // error message for overflow/underflow (for arrays, of the elements)
-}
-
-// Since the encoder writes no zeros, if we arrive at a decoder we have
-// a value to extract and store.  The field number has already been read
-// (it's how we knew to call this decoder).
-// Each decoder is responsible for handling any indirections associated
-// with the data structure.  If any pointer so reached is nil, allocation must
-// be done.
-
-// Walk the pointer hierarchy, allocating if we find a nil.  Stop one before the end.
-func decIndirect(p unsafe.Pointer, indir int) unsafe.Pointer {
-	for ; indir > 1; indir-- {
-		if *(*unsafe.Pointer)(p) == nil {
-			// Allocation required
-			*(*unsafe.Pointer)(p) = unsafe.Pointer(new(unsafe.Pointer))
-		}
-		p = *(*unsafe.Pointer)(p)
-	}
-	return p
-}
-
-// ignoreUint discards a uint value with no destination.
-func ignoreUint(i *decInstr, state *decoderState, p unsafe.Pointer) {
-	state.decodeUint()
-}
-
-// ignoreTwoUints discards a uint value with no destination. It's used to skip
-// complex values.
-func ignoreTwoUints(i *decInstr, state *decoderState, p unsafe.Pointer) {
-	state.decodeUint()
-	state.decodeUint()
-}
-
-// decBool decodes a uint and stores it as a boolean through p.
-func decBool(i *decInstr, state *decoderState, p unsafe.Pointer) {
-	if i.indir > 0 {
-		if *(*unsafe.Pointer)(p) == nil {
-			*(*unsafe.Pointer)(p) = unsafe.Pointer(new(bool))
-		}
-		p = *(*unsafe.Pointer)(p)
-	}
-	*(*bool)(p) = state.decodeUint() != 0
-}
-
-// decInt8 decodes an integer and stores it as an int8 through p.
-func decInt8(i *decInstr, state *decoderState, p unsafe.Pointer) {
-	if i.indir > 0 {
-		if *(*unsafe.Pointer)(p) == nil {
-			*(*unsafe.Pointer)(p) = unsafe.Pointer(new(int8))
-		}
-		p = *(*unsafe.Pointer)(p)
-	}
-	v := state.decodeInt()
-	if v < math.MinInt8 || math.MaxInt8 < v {
-		error_(i.ovfl)
-	} else {
-		*(*int8)(p) = int8(v)
-	}
-}
-
-// decUint8 decodes an unsigned integer and stores it as a uint8 through p.
-func decUint8(i *decInstr, state *decoderState, p unsafe.Pointer) {
-	if i.indir > 0 {
-		if *(*unsafe.Pointer)(p) == nil {
-			*(*unsafe.Pointer)(p) = unsafe.Pointer(new(uint8))
-		}
-		p = *(*unsafe.Pointer)(p)
-	}
-	v := state.decodeUint()
-	if math.MaxUint8 < v {
-		error_(i.ovfl)
-	} else {
-		*(*uint8)(p) = uint8(v)
-	}
-}
-
-// decInt16 decodes an integer and stores it as an int16 through p.
-func decInt16(i *decInstr, state *decoderState, p unsafe.Pointer) {
-	if i.indir > 0 {
-		if *(*unsafe.Pointer)(p) == nil {
-			*(*unsafe.Pointer)(p) = unsafe.Pointer(new(int16))
-		}
-		p = *(*unsafe.Pointer)(p)
-	}
-	v := state.decodeInt()
-	if v < math.MinInt16 || math.MaxInt16 < v {
-		error_(i.ovfl)
-	} else {
-		*(*int16)(p) = int16(v)
-	}
-}
-
-// decUint16 decodes an unsigned integer and stores it as a uint16 through p.
-func decUint16(i *decInstr, state *decoderState, p unsafe.Pointer) {
-	if i.indir > 0 {
-		if *(*unsafe.Pointer)(p) == nil {
-			*(*unsafe.Pointer)(p) = unsafe.Pointer(new(uint16))
-		}
-		p = *(*unsafe.Pointer)(p)
-	}
-	v := state.decodeUint()
-	if math.MaxUint16 < v {
-		error_(i.ovfl)
-	} else {
-		*(*uint16)(p) = uint16(v)
-	}
-}
-
-// decInt32 decodes an integer and stores it as an int32 through p.
-func decInt32(i *decInstr, state *decoderState, p unsafe.Pointer) {
-	if i.indir > 0 {
-		if *(*unsafe.Pointer)(p) == nil {
-			*(*unsafe.Pointer)(p) = unsafe.Pointer(new(int32))
-		}
-		p = *(*unsafe.Pointer)(p)
-	}
-	v := state.decodeInt()
-	if v < math.MinInt32 || math.MaxInt32 < v {
-		error_(i.ovfl)
-	} else {
-		*(*int32)(p) = int32(v)
-	}
-}
-
-// decUint32 decodes an unsigned integer and stores it as a uint32 through p.
-func decUint32(i *decInstr, state *decoderState, p unsafe.Pointer) {
-	if i.indir > 0 {
-		if *(*unsafe.Pointer)(p) == nil {
-			*(*unsafe.Pointer)(p) = unsafe.Pointer(new(uint32))
-		}
-		p = *(*unsafe.Pointer)(p)
-	}
-	v := state.decodeUint()
-	if math.MaxUint32 < v {
-		error_(i.ovfl)
-	} else {
-		*(*uint32)(p) = uint32(v)
-	}
-}
-
-// decInt64 decodes an integer and stores it as an int64 through p.
-func decInt64(i *decInstr, state *decoderState, p unsafe.Pointer) {
-	if i.indir > 0 {
-		if *(*unsafe.Pointer)(p) == nil {
-			*(*unsafe.Pointer)(p) = unsafe.Pointer(new(int64))
-		}
-		p = *(*unsafe.Pointer)(p)
-	}
-	*(*int64)(p) = int64(state.decodeInt())
-}
-
-// decUint64 decodes an unsigned integer and stores it as a uint64 through p.
-func decUint64(i *decInstr, state *decoderState, p unsafe.Pointer) {
-	if i.indir > 0 {
-		if *(*unsafe.Pointer)(p) == nil {
-			*(*unsafe.Pointer)(p) = unsafe.Pointer(new(uint64))
-		}
-		p = *(*unsafe.Pointer)(p)
-	}
-	*(*uint64)(p) = uint64(state.decodeUint())
-}
-
-// Floating-point numbers are transmitted as uint64s holding the bits
-// of the underlying representation.  They are sent byte-reversed, with
-// the exponent end coming out first, so integer floating point numbers
-// (for example) transmit more compactly.  This routine does the
-// unswizzling.
-func floatFromBits(u uint64) float64 {
-	var v uint64
-	for i := 0; i < 8; i++ {
-		v <<= 8
-		v |= u & 0xFF
-		u >>= 8
-	}
-	return math.Float64frombits(v)
-}
-
-// storeFloat32 decodes an unsigned integer, treats it as a 32-bit floating-point
-// number, and stores it through p. It's a helper function for float32 and complex64.
-func storeFloat32(i *decInstr, state *decoderState, p unsafe.Pointer) {
-	v := floatFromBits(state.decodeUint())
-	av := v
-	if av < 0 {
-		av = -av
-	}
-	// +Inf is OK in both 32- and 64-bit floats.  Underflow is always OK.
-	if math.MaxFloat32 < av && av <= math.MaxFloat64 {
-		error_(i.ovfl)
-	} else {
-		*(*float32)(p) = float32(v)
-	}
-}
-
-// decFloat32 decodes an unsigned integer, treats it as a 32-bit floating-point
-// number, and stores it through p.
-func decFloat32(i *decInstr, state *decoderState, p unsafe.Pointer) {
-	if i.indir > 0 {
-		if *(*unsafe.Pointer)(p) == nil {
-			*(*unsafe.Pointer)(p) = unsafe.Pointer(new(float32))
-		}
-		p = *(*unsafe.Pointer)(p)
-	}
-	storeFloat32(i, state, p)
-}
-
-// decFloat64 decodes an unsigned integer, treats it as a 64-bit floating-point
-// number, and stores it through p.
-func decFloat64(i *decInstr, state *decoderState, p unsafe.Pointer) {
-	if i.indir > 0 {
-		if *(*unsafe.Pointer)(p) == nil {
-			*(*unsafe.Pointer)(p) = unsafe.Pointer(new(float64))
-		}
-		p = *(*unsafe.Pointer)(p)
-	}
-	*(*float64)(p) = floatFromBits(uint64(state.decodeUint()))
-}
-
-// decComplex64 decodes a pair of unsigned integers, treats them as a
-// pair of floating point numbers, and stores them as a complex64 through p.
-// The real part comes first.
-func decComplex64(i *decInstr, state *decoderState, p unsafe.Pointer) {
-	if i.indir > 0 {
-		if *(*unsafe.Pointer)(p) == nil {
-			*(*unsafe.Pointer)(p) = unsafe.Pointer(new(complex64))
-		}
-		p = *(*unsafe.Pointer)(p)
-	}
-	storeFloat32(i, state, p)
-	storeFloat32(i, state, unsafe.Pointer(uintptr(p)+unsafe.Sizeof(float32(0))))
-}
-
-// decComplex128 decodes a pair of unsigned integers, treats them as a
-// pair of floating point numbers, and stores them as a complex128 through p.
-// The real part comes first.
-func decComplex128(i *decInstr, state *decoderState, p unsafe.Pointer) {
-	if i.indir > 0 {
-		if *(*unsafe.Pointer)(p) == nil {
-			*(*unsafe.Pointer)(p) = unsafe.Pointer(new(complex128))
-		}
-		p = *(*unsafe.Pointer)(p)
-	}
-	real := floatFromBits(uint64(state.decodeUint()))
-	imag := floatFromBits(uint64(state.decodeUint()))
-	*(*complex128)(p) = complex(real, imag)
-}
-
-// decUint8Slice decodes a byte slice and stores through p a slice header
-// describing the data.
-// uint8 slices are encoded as an unsigned count followed by the raw bytes.
-func decUint8Slice(i *decInstr, state *decoderState, p unsafe.Pointer) {
-	if i.indir > 0 {
-		if *(*unsafe.Pointer)(p) == nil {
-			*(*unsafe.Pointer)(p) = unsafe.Pointer(new([]uint8))
-		}
-		p = *(*unsafe.Pointer)(p)
-	}
-	n := state.decodeUint()
-	if n > uint64(state.b.Len()) {
-		errorf("length of []byte exceeds input size (%d bytes)", n)
-	}
-	slice := (*[]uint8)(p)
-	if uint64(cap(*slice)) < n {
-		*slice = make([]uint8, n)
-	} else {
-		*slice = (*slice)[0:n]
-	}
-	if _, err := state.b.Read(*slice); err != nil {
-		errorf("error decoding []byte: %s", err)
-	}
-}
-
-// decString decodes byte array and stores through p a string header
-// describing the data.
-// Strings are encoded as an unsigned count followed by the raw bytes.
-func decString(i *decInstr, state *decoderState, p unsafe.Pointer) {
-	if i.indir > 0 {
-		if *(*unsafe.Pointer)(p) == nil {
-			*(*unsafe.Pointer)(p) = unsafe.Pointer(new(string))
-		}
-		p = *(*unsafe.Pointer)(p)
-	}
-	n := state.decodeUint()
-	if n > uint64(state.b.Len()) {
-		errorf("string length exceeds input size (%d bytes)", n)
-	}
-	b := make([]byte, n)
-	state.b.Read(b)
-	// It would be a shame to do the obvious thing here,
-	//	*(*string)(p) = string(b)
-	// because we've already allocated the storage and this would
-	// allocate again and copy.  So we do this ugly hack, which is even
-	// even more unsafe than it looks as it depends the memory
-	// representation of a string matching the beginning of the memory
-	// representation of a byte slice (a byte slice is longer).
-	*(*string)(p) = *(*string)(unsafe.Pointer(&b))
-}
-
-// ignoreUint8Array skips over the data for a byte slice value with no destination.
-func ignoreUint8Array(i *decInstr, state *decoderState, p unsafe.Pointer) {
-	b := make([]byte, state.decodeUint())
-	state.b.Read(b)
-}
-
-// Execution engine
-
-// The encoder engine is an array of instructions indexed by field number of the incoming
-// decoder.  It is executed with random access according to field number.
-type decEngine struct {
-	instr    []decInstr
-	numInstr int // the number of active instructions
-}
-
-// allocate makes sure storage is available for an object of underlying type rtyp
-// that is indir levels of indirection through p.
-func allocate(rtyp reflect.Type, p unsafe.Pointer, indir int) unsafe.Pointer {
-	if indir == 0 {
-		return p
-	}
-	up := p
-	if indir > 1 {
-		up = decIndirect(up, indir)
-	}
-	if *(*unsafe.Pointer)(up) == nil {
-		// Allocate object.
-		*(*unsafe.Pointer)(up) = unsafe.Pointer(reflect.New(rtyp).Pointer())
-	}
-	return *(*unsafe.Pointer)(up)
-}
-
-// decodeSingle decodes a top-level value that is not a struct and stores it through p.
-// Such values are preceded by a zero, making them have the memory layout of a
-// struct field (although with an illegal field number).
-func (dec *Decoder) decodeSingle(engine *decEngine, ut *userTypeInfo, basep unsafe.Pointer) {
-	state := dec.newDecoderState(&dec.buf)
-	state.fieldnum = singletonField
-	delta := int(state.decodeUint())
-	if delta != 0 {
-		errorf("decode: corrupted data: non-zero delta for singleton")
-	}
-	instr := &engine.instr[singletonField]
-	if instr.indir != ut.indir {
-		errorf("internal error: inconsistent indirection instr %d ut %d", instr.indir, ut.indir)
-	}
-	ptr := basep // offset will be zero
-	if instr.indir > 1 {
-		ptr = decIndirect(ptr, instr.indir)
-	}
-	instr.op(instr, state, ptr)
-	dec.freeDecoderState(state)
-}
-
-// decodeStruct decodes a top-level struct and stores it through p.
-// Indir is for the value, not the type.  At the time of the call it may
-// differ from ut.indir, which was computed when the engine was built.
-// This state cannot arise for decodeSingle, which is called directly
-// from the user's value, not from the innards of an engine.
-func (dec *Decoder) decodeStruct(engine *decEngine, ut *userTypeInfo, p unsafe.Pointer, indir int) {
-	p = allocate(ut.base, p, indir)
-	state := dec.newDecoderState(&dec.buf)
-	state.fieldnum = -1
-	basep := p
-	for state.b.Len() > 0 {
-		delta := int(state.decodeUint())
-		if delta < 0 {
-			errorf("decode: corrupted data: negative delta")
-		}
-		if delta == 0 { // struct terminator is zero delta fieldnum
-			break
-		}
-		fieldnum := state.fieldnum + delta
-		if fieldnum >= len(engine.instr) {
-			error_(errRange)
-			break
-		}
-		instr := &engine.instr[fieldnum]
-		p := unsafe.Pointer(uintptr(basep) + instr.offset)
-		if instr.indir > 1 {
-			p = decIndirect(p, instr.indir)
-		}
-		instr.op(instr, state, p)
-		state.fieldnum = fieldnum
-	}
-	dec.freeDecoderState(state)
-}
-
-// ignoreStruct discards the data for a struct with no destination.
-func (dec *Decoder) ignoreStruct(engine *decEngine) {
-	state := dec.newDecoderState(&dec.buf)
-	state.fieldnum = -1
-	for state.b.Len() > 0 {
-		delta := int(state.decodeUint())
-		if delta < 0 {
-			errorf("ignore decode: corrupted data: negative delta")
-		}
-		if delta == 0 { // struct terminator is zero delta fieldnum
-			break
-		}
-		fieldnum := state.fieldnum + delta
-		if fieldnum >= len(engine.instr) {
-			error_(errRange)
-		}
-		instr := &engine.instr[fieldnum]
-		instr.op(instr, state, unsafe.Pointer(nil))
-		state.fieldnum = fieldnum
-	}
-	dec.freeDecoderState(state)
-}
-
-// ignoreSingle discards the data for a top-level non-struct value with no
-// destination. It's used when calling Decode with a nil value.
-func (dec *Decoder) ignoreSingle(engine *decEngine) {
-	state := dec.newDecoderState(&dec.buf)
-	state.fieldnum = singletonField
-	delta := int(state.decodeUint())
-	if delta != 0 {
-		errorf("decode: corrupted data: non-zero delta for singleton")
-	}
-	instr := &engine.instr[singletonField]
-	instr.op(instr, state, unsafe.Pointer(nil))
-	dec.freeDecoderState(state)
-}
-
-// decodeArrayHelper does the work for decoding arrays and slices.
-func (dec *Decoder) decodeArrayHelper(state *decoderState, p unsafe.Pointer, elemOp decOp, elemWid uintptr, length, elemIndir int, ovfl error) {
-	instr := &decInstr{elemOp, 0, elemIndir, 0, ovfl}
-	for i := 0; i < length; i++ {
-		if state.b.Len() == 0 {
-			errorf("decoding array or slice: length exceeds input size (%d elements)", length)
-		}
-		up := p
-		if elemIndir > 1 {
-			up = decIndirect(up, elemIndir)
-		}
-		elemOp(instr, state, up)
-		p = unsafe.Pointer(uintptr(p) + elemWid)
-	}
-}
-
-// decodeArray decodes an array and stores it through p, that is, p points to the zeroth element.
-// The length is an unsigned integer preceding the elements.  Even though the length is redundant
-// (it's part of the type), it's a useful check and is included in the encoding.
-func (dec *Decoder) decodeArray(atyp reflect.Type, state *decoderState, p unsafe.Pointer, elemOp decOp, elemWid uintptr, length, indir, elemIndir int, ovfl error) {
-	if indir > 0 {
-		p = allocate(atyp, p, 1) // All but the last level has been allocated by dec.Indirect
-	}
-	if n := state.decodeUint(); n != uint64(length) {
-		errorf("length mismatch in decodeArray")
-	}
-	dec.decodeArrayHelper(state, p, elemOp, elemWid, length, elemIndir, ovfl)
-}
-
-// decodeIntoValue is a helper for map decoding.  Since maps are decoded using reflection,
-// unlike the other items we can't use a pointer directly.
-func decodeIntoValue(state *decoderState, op decOp, indir int, v reflect.Value, ovfl error) reflect.Value {
-	instr := &decInstr{op, 0, indir, 0, ovfl}
-	up := unsafeAddr(v)
-	if indir > 1 {
-		up = decIndirect(up, indir)
-	}
-	op(instr, state, up)
-	return v
-}
-
-// decodeMap decodes a map and stores its header through p.
-// Maps are encoded as a length followed by key:value pairs.
-// Because the internals of maps are not visible to us, we must
-// use reflection rather than pointer magic.
-func (dec *Decoder) decodeMap(mtyp reflect.Type, state *decoderState, p unsafe.Pointer, keyOp, elemOp decOp, indir, keyIndir, elemIndir int, ovfl error) {
-	if indir > 0 {
-		p = allocate(mtyp, p, 1) // All but the last level has been allocated by dec.Indirect
-	}
-	up := unsafe.Pointer(p)
-	if *(*unsafe.Pointer)(up) == nil { // maps are represented as a pointer in the runtime
-		// Allocate map.
-		*(*unsafe.Pointer)(up) = unsafe.Pointer(reflect.MakeMap(mtyp).Pointer())
-	}
-	// Maps cannot be accessed by moving addresses around the way
-	// that slices etc. can.  We must recover a full reflection value for
-	// the iteration.
-	v := reflect.NewAt(mtyp, unsafe.Pointer(p)).Elem()
-	n := int(state.decodeUint())
-	for i := 0; i < n; i++ {
-		key := decodeIntoValue(state, keyOp, keyIndir, allocValue(mtyp.Key()), ovfl)
-		elem := decodeIntoValue(state, elemOp, elemIndir, allocValue(mtyp.Elem()), ovfl)
-		v.SetMapIndex(key, elem)
-	}
-}
-
-// ignoreArrayHelper does the work for discarding arrays and slices.
-func (dec *Decoder) ignoreArrayHelper(state *decoderState, elemOp decOp, length int) {
-	instr := &decInstr{elemOp, 0, 0, 0, errors.New("no error")}
-	for i := 0; i < length; i++ {
-		elemOp(instr, state, nil)
-	}
-}
-
-// ignoreArray discards the data for an array value with no destination.
-func (dec *Decoder) ignoreArray(state *decoderState, elemOp decOp, length int) {
-	if n := state.decodeUint(); n != uint64(length) {
-		errorf("length mismatch in ignoreArray")
-	}
-	dec.ignoreArrayHelper(state, elemOp, length)
-}
-
-// ignoreMap discards the data for a map value with no destination.
-func (dec *Decoder) ignoreMap(state *decoderState, keyOp, elemOp decOp) {
-	n := int(state.decodeUint())
-	keyInstr := &decInstr{keyOp, 0, 0, 0, errors.New("no error")}
-	elemInstr := &decInstr{elemOp, 0, 0, 0, errors.New("no error")}
-	for i := 0; i < n; i++ {
-		keyOp(keyInstr, state, nil)
-		elemOp(elemInstr, state, nil)
-	}
-}
-
-// decodeSlice decodes a slice and stores the slice header through p.
-// Slices are encoded as an unsigned length followed by the elements.
-func (dec *Decoder) decodeSlice(atyp reflect.Type, state *decoderState, p unsafe.Pointer, elemOp decOp, elemWid uintptr, indir, elemIndir int, ovfl error) {
-	nr := state.decodeUint()
-	n := int(nr)
-	if indir > 0 {
-		if *(*unsafe.Pointer)(p) == nil {
-			// Allocate the slice header.
-			*(*unsafe.Pointer)(p) = unsafe.Pointer(new([]unsafe.Pointer))
-		}
-		p = *(*unsafe.Pointer)(p)
-	}
-	// Allocate storage for the slice elements, that is, the underlying array,
-	// if the existing slice does not have the capacity.
-	// Always write a header at p.
-	hdrp := (*reflect.SliceHeader)(p)
-	if hdrp.Cap < n {
-		hdrp.Data = reflect.MakeSlice(atyp, n, n).Pointer()
-		hdrp.Cap = n
-	}
-	hdrp.Len = n
-	dec.decodeArrayHelper(state, unsafe.Pointer(hdrp.Data), elemOp, elemWid, n, elemIndir, ovfl)
-}
-
-// ignoreSlice skips over the data for a slice value with no destination.
-func (dec *Decoder) ignoreSlice(state *decoderState, elemOp decOp) {
-	dec.ignoreArrayHelper(state, elemOp, int(state.decodeUint()))
-}
-
-// setInterfaceValue sets an interface value to a concrete value,
-// but first it checks that the assignment will succeed.
-func setInterfaceValue(ivalue reflect.Value, value reflect.Value) {
-	if !value.Type().AssignableTo(ivalue.Type()) {
-		errorf("%s is not assignable to type %s", value.Type(), ivalue.Type())
-	}
-	ivalue.Set(value)
-}
-
-// decodeInterface decodes an interface value and stores it through p.
-// Interfaces are encoded as the name of a concrete type followed by a value.
-// If the name is empty, the value is nil and no value is sent.
-func (dec *Decoder) decodeInterface(ityp reflect.Type, state *decoderState, p unsafe.Pointer, indir int) {
-	// Create a writable interface reflect.Value.  We need one even for the nil case.
-	ivalue := allocValue(ityp)
-	// Read the name of the concrete type.
-	nr := state.decodeUint()
-	if nr < 0 || nr > 1<<31 { // zero is permissible for anonymous types
-		errorf("invalid type name length %d", nr)
-	}
-	if nr > uint64(state.b.Len()) {
-		errorf("invalid type name length %d: exceeds input size", nr)
-	}
-	b := make([]byte, nr)
-	state.b.Read(b)
-	name := string(b)
-	if name == "" {
-		// Copy the representation of the nil interface value to the target.
-		// This is horribly unsafe and special.
-		if indir > 0 {
-			p = allocate(ityp, p, 1) // All but the last level has been allocated by dec.Indirect
-		}
-		*(*[2]uintptr)(unsafe.Pointer(p)) = ivalue.InterfaceData()
-		return
-	}
-	if len(name) > 1024 {
-		errorf("name too long (%d bytes): %.20q...", len(name), name)
-	}
-	// The concrete type must be registered.
-	registerLock.RLock()
-	typ, ok := nameToConcreteType[name]
-	registerLock.RUnlock()
-	if !ok {
-		errorf("name not registered for interface: %q", name)
-	}
-	// Read the type id of the concrete value.
-	concreteId := dec.decodeTypeSequence(true)
-	if concreteId < 0 {
-		error_(dec.err)
-	}
-	// Byte count of value is next; we don't care what it is (it's there
-	// in case we want to ignore the value by skipping it completely).
-	state.decodeUint()
-	// Read the concrete value.
-	value := allocValue(typ)
-	dec.decodeValue(concreteId, value)
-	if dec.err != nil {
-		error_(dec.err)
-	}
-	// Allocate the destination interface value.
-	if indir > 0 {
-		p = allocate(ityp, p, 1) // All but the last level has been allocated by dec.Indirect
-	}
-	// Assign the concrete value to the interface.
-	// Tread carefully; it might not satisfy the interface.
-	setInterfaceValue(ivalue, value)
-	// Copy the representation of the interface value to the target.
-	// This is horribly unsafe and special.
-	*(*[2]uintptr)(unsafe.Pointer(p)) = ivalue.InterfaceData()
-}
-
-// ignoreInterface discards the data for an interface value with no destination.
-func (dec *Decoder) ignoreInterface(state *decoderState) {
-	// Read the name of the concrete type.
-	b := make([]byte, state.decodeUint())
-	_, err := state.b.Read(b)
-	if err != nil {
-		error_(err)
-	}
-	id := dec.decodeTypeSequence(true)
-	if id < 0 {
-		error_(dec.err)
-	}
-	// At this point, the decoder buffer contains a delimited value. Just toss it.
-	state.b.Next(int(state.decodeUint()))
-}
-
-// decodeGobDecoder decodes something implementing the GobDecoder interface.
-// The data is encoded as a byte slice.
-func (dec *Decoder) decodeGobDecoder(ut *userTypeInfo, state *decoderState, v reflect.Value) {
-	// Read the bytes for the value.
-	b := make([]byte, state.decodeUint())
-	_, err := state.b.Read(b)
-	if err != nil {
-		error_(err)
-	}
-	// We know it's one of these.
-	switch ut.externalDec {
-	case xGob:
-		err = v.Interface().(GobDecoder).GobDecode(b)
-	case xBinary:
-		err = v.Interface().(encoding.BinaryUnmarshaler).UnmarshalBinary(b)
-	case xText:
-		err = v.Interface().(encoding.TextUnmarshaler).UnmarshalText(b)
-	}
-	if err != nil {
-		error_(err)
-	}
-}
-
-// ignoreGobDecoder discards the data for a GobDecoder value with no destination.
-func (dec *Decoder) ignoreGobDecoder(state *decoderState) {
-	// Read the bytes for the value.
-	b := make([]byte, state.decodeUint())
-	_, err := state.b.Read(b)
-	if err != nil {
-		error_(err)
-	}
-}
-
-// Index by Go types.
-var decOpTable = [...]decOp{
-	reflect.Bool:       decBool,
-	reflect.Int8:       decInt8,
-	reflect.Int16:      decInt16,
-	reflect.Int32:      decInt32,
-	reflect.Int64:      decInt64,
-	reflect.Uint8:      decUint8,
-	reflect.Uint16:     decUint16,
-	reflect.Uint32:     decUint32,
-	reflect.Uint64:     decUint64,
-	reflect.Float32:    decFloat32,
-	reflect.Float64:    decFloat64,
-	reflect.Complex64:  decComplex64,
-	reflect.Complex128: decComplex128,
-	reflect.String:     decString,
-}
-
-// Indexed by gob types.  tComplex will be added during type.init().
-var decIgnoreOpMap = map[typeId]decOp{
-	tBool:    ignoreUint,
-	tInt:     ignoreUint,
-	tUint:    ignoreUint,
-	tFloat:   ignoreUint,
-	tBytes:   ignoreUint8Array,
-	tString:  ignoreUint8Array,
-	tComplex: ignoreTwoUints,
-}
-
-// decOpFor returns the decoding op for the base type under rt and
-// the indirection count to reach it.
-func (dec *Decoder) decOpFor(wireId typeId, rt reflect.Type, name string, inProgress map[reflect.Type]*decOp) (*decOp, int) {
-	ut := userType(rt)
-	// If the type implements GobEncoder, we handle it without further processing.
-	if ut.externalDec != 0 {
-		return dec.gobDecodeOpFor(ut)
-	}
-
-	// If this type is already in progress, it's a recursive type (e.g. map[string]*T).
-	// Return the pointer to the op we're already building.
-	if opPtr := inProgress[rt]; opPtr != nil {
-		return opPtr, ut.indir
-	}
-	typ := ut.base
-	indir := ut.indir
-	var op decOp
-	k := typ.Kind()
-	if int(k) < len(decOpTable) {
-		op = decOpTable[k]
-	}
-	if op == nil {
-		inProgress[rt] = &op
-		// Special cases
-		switch t := typ; t.Kind() {
-		case reflect.Array:
-			name = "element of " + name
-			elemId := dec.wireType[wireId].ArrayT.Elem
-			elemOp, elemIndir := dec.decOpFor(elemId, t.Elem(), name, inProgress)
-			ovfl := overflow(name)
-			op = func(i *decInstr, state *decoderState, p unsafe.Pointer) {
-				state.dec.decodeArray(t, state, p, *elemOp, t.Elem().Size(), t.Len(), i.indir, elemIndir, ovfl)
-			}
-
-		case reflect.Map:
-			keyId := dec.wireType[wireId].MapT.Key
-			elemId := dec.wireType[wireId].MapT.Elem
-			keyOp, keyIndir := dec.decOpFor(keyId, t.Key(), "key of "+name, inProgress)
-			elemOp, elemIndir := dec.decOpFor(elemId, t.Elem(), "element of "+name, inProgress)
-			ovfl := overflow(name)
-			op = func(i *decInstr, state *decoderState, p unsafe.Pointer) {
-				state.dec.decodeMap(t, state, p, *keyOp, *elemOp, i.indir, keyIndir, elemIndir, ovfl)
-			}
-
-		case reflect.Slice:
-			name = "element of " + name
-			if t.Elem().Kind() == reflect.Uint8 {
-				op = decUint8Slice
-				break
-			}
-			var elemId typeId
-			if tt, ok := builtinIdToType[wireId]; ok {
-				elemId = tt.(*sliceType).Elem
-			} else {
-				elemId = dec.wireType[wireId].SliceT.Elem
-			}
-			elemOp, elemIndir := dec.decOpFor(elemId, t.Elem(), name, inProgress)
-			ovfl := overflow(name)
-			op = func(i *decInstr, state *decoderState, p unsafe.Pointer) {
-				state.dec.decodeSlice(t, state, p, *elemOp, t.Elem().Size(), i.indir, elemIndir, ovfl)
-			}
-
-		case reflect.Struct:
-			// Generate a closure that calls out to the engine for the nested type.
-			enginePtr, err := dec.getDecEnginePtr(wireId, userType(typ))
-			if err != nil {
-				error_(err)
-			}
-			op = func(i *decInstr, state *decoderState, p unsafe.Pointer) {
-				// indirect through enginePtr to delay evaluation for recursive structs.
-				dec.decodeStruct(*enginePtr, userType(typ), p, i.indir)
-			}
-		case reflect.Interface:
-			op = func(i *decInstr, state *decoderState, p unsafe.Pointer) {
-				state.dec.decodeInterface(t, state, p, i.indir)
-			}
-		}
-	}
-	if op == nil {
-		errorf("decode can't handle type %s", rt)
-	}
-	return &op, indir
-}
-
-// decIgnoreOpFor returns the decoding op for a field that has no destination.
-func (dec *Decoder) decIgnoreOpFor(wireId typeId) decOp {
-	op, ok := decIgnoreOpMap[wireId]
-	if !ok {
-		if wireId == tInterface {
-			// Special case because it's a method: the ignored item might
-			// define types and we need to record their state in the decoder.
-			op = func(i *decInstr, state *decoderState, p unsafe.Pointer) {
-				state.dec.ignoreInterface(state)
-			}
-			return op
-		}
-		// Special cases
-		wire := dec.wireType[wireId]
-		switch {
-		case wire == nil:
-			errorf("bad data: undefined type %s", wireId.string())
-		case wire.ArrayT != nil:
-			elemId := wire.ArrayT.Elem
-			elemOp := dec.decIgnoreOpFor(elemId)
-			op = func(i *decInstr, state *decoderState, p unsafe.Pointer) {
-				state.dec.ignoreArray(state, elemOp, wire.ArrayT.Len)
-			}
-
-		case wire.MapT != nil:
-			keyId := dec.wireType[wireId].MapT.Key
-			elemId := dec.wireType[wireId].MapT.Elem
-			keyOp := dec.decIgnoreOpFor(keyId)
-			elemOp := dec.decIgnoreOpFor(elemId)
-			op = func(i *decInstr, state *decoderState, p unsafe.Pointer) {
-				state.dec.ignoreMap(state, keyOp, elemOp)
-			}
-
-		case wire.SliceT != nil:
-			elemId := wire.SliceT.Elem
-			elemOp := dec.decIgnoreOpFor(elemId)
-			op = func(i *decInstr, state *decoderState, p unsafe.Pointer) {
-				state.dec.ignoreSlice(state, elemOp)
-			}
-
-		case wire.StructT != nil:
-			// Generate a closure that calls out to the engine for the nested type.
-			enginePtr, err := dec.getIgnoreEnginePtr(wireId)
-			if err != nil {
-				error_(err)
-			}
-			op = func(i *decInstr, state *decoderState, p unsafe.Pointer) {
-				// indirect through enginePtr to delay evaluation for recursive structs
-				state.dec.ignoreStruct(*enginePtr)
-			}
-
-		case wire.GobEncoderT != nil, wire.BinaryMarshalerT != nil, wire.TextMarshalerT != nil:
-			op = func(i *decInstr, state *decoderState, p unsafe.Pointer) {
-				state.dec.ignoreGobDecoder(state)
-			}
-		}
-	}
-	if op == nil {
-		errorf("bad data: ignore can't handle type %s", wireId.string())
-	}
-	return op
-}
-
-// gobDecodeOpFor returns the op for a type that is known to implement
-// GobDecoder.
-func (dec *Decoder) gobDecodeOpFor(ut *userTypeInfo) (*decOp, int) {
-	rcvrType := ut.user
-	if ut.decIndir == -1 {
-		rcvrType = reflect.PtrTo(rcvrType)
-	} else if ut.decIndir > 0 {
-		for i := int8(0); i < ut.decIndir; i++ {
-			rcvrType = rcvrType.Elem()
-		}
-	}
-	var op decOp
-	op = func(i *decInstr, state *decoderState, p unsafe.Pointer) {
-		// Caller has gotten us to within one indirection of our value.
-		if i.indir > 0 {
-			if *(*unsafe.Pointer)(p) == nil {
-				*(*unsafe.Pointer)(p) = unsafe.Pointer(reflect.New(ut.base).Pointer())
-			}
-		}
-		// Now p is a pointer to the base type.  Do we need to climb out to
-		// get to the receiver type?
-		var v reflect.Value
-		if ut.decIndir == -1 {
-			v = reflect.NewAt(rcvrType, unsafe.Pointer(&p)).Elem()
-		} else {
-			v = reflect.NewAt(rcvrType, p).Elem()
-		}
-		state.dec.decodeGobDecoder(ut, state, v)
-	}
-	return &op, int(ut.indir)
-
-}
-
-// compatibleType asks: Are these two gob Types compatible?
-// Answers the question for basic types, arrays, maps and slices, plus
-// GobEncoder/Decoder pairs.
-// Structs are considered ok; fields will be checked later.
-func (dec *Decoder) compatibleType(fr reflect.Type, fw typeId, inProgress map[reflect.Type]typeId) bool {
-	if rhs, ok := inProgress[fr]; ok {
-		return rhs == fw
-	}
-	inProgress[fr] = fw
-	ut := userType(fr)
-	wire, ok := dec.wireType[fw]
-	// If wire was encoded with an encoding method, fr must have that method.
-	// And if not, it must not.
-	// At most one of the booleans in ut is set.
-	// We could possibly relax this constraint in the future in order to
-	// choose the decoding method using the data in the wireType.
-	// The parentheses look odd but are correct.
-	if (ut.externalDec == xGob) != (ok && wire.GobEncoderT != nil) ||
-		(ut.externalDec == xBinary) != (ok && wire.BinaryMarshalerT != nil) ||
-		(ut.externalDec == xText) != (ok && wire.TextMarshalerT != nil) {
-		return false
-	}
-	if ut.externalDec != 0 { // This test trumps all others.
-		return true
-	}
-	switch t := ut.base; t.Kind() {
-	default:
-		// chan, etc: cannot handle.
-		return false
-	case reflect.Bool:
-		return fw == tBool
-	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-		return fw == tInt
-	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
-		return fw == tUint
-	case reflect.Float32, reflect.Float64:
-		return fw == tFloat
-	case reflect.Complex64, reflect.Complex128:
-		return fw == tComplex
-	case reflect.String:
-		return fw == tString
-	case reflect.Interface:
-		return fw == tInterface
-	case reflect.Array:
-		if !ok || wire.ArrayT == nil {
-			return false
-		}
-		array := wire.ArrayT
-		return t.Len() == array.Len && dec.compatibleType(t.Elem(), array.Elem, inProgress)
-	case reflect.Map:
-		if !ok || wire.MapT == nil {
-			return false
-		}
-		MapType := wire.MapT
-		return dec.compatibleType(t.Key(), MapType.Key, inProgress) && dec.compatibleType(t.Elem(), MapType.Elem, inProgress)
-	case reflect.Slice:
-		// Is it an array of bytes?
-		if t.Elem().Kind() == reflect.Uint8 {
-			return fw == tBytes
-		}
-		// Extract and compare element types.
-		var sw *sliceType
-		if tt, ok := builtinIdToType[fw]; ok {
-			sw, _ = tt.(*sliceType)
-		} else if wire != nil {
-			sw = wire.SliceT
-		}
-		elem := userType(t.Elem()).base
-		return sw != nil && dec.compatibleType(elem, sw.Elem, inProgress)
-	case reflect.Struct:
-		return true
-	}
-}
-
-// typeString returns a human-readable description of the type identified by remoteId.
-func (dec *Decoder) typeString(remoteId typeId) string {
-	if t := idToType[remoteId]; t != nil {
-		// globally known type.
-		return t.string()
-	}
-	return dec.wireType[remoteId].string()
-}
-
-// compileSingle compiles the decoder engine for a non-struct top-level value, including
-// GobDecoders.
-func (dec *Decoder) compileSingle(remoteId typeId, ut *userTypeInfo) (engine *decEngine, err error) {
-	rt := ut.user
-	engine = new(decEngine)
-	engine.instr = make([]decInstr, 1) // one item
-	name := rt.String()                // best we can do
-	if !dec.compatibleType(rt, remoteId, make(map[reflect.Type]typeId)) {
-		remoteType := dec.typeString(remoteId)
-		// Common confusing case: local interface type, remote concrete type.
-		if ut.base.Kind() == reflect.Interface && remoteId != tInterface {
-			return nil, errors.New("gob: local interface type " + name + " can only be decoded from remote interface type; received concrete type " + remoteType)
-		}
-		return nil, errors.New("gob: decoding into local type " + name + ", received remote type " + remoteType)
-	}
-	op, indir := dec.decOpFor(remoteId, rt, name, make(map[reflect.Type]*decOp))
-	ovfl := errors.New(`value for "` + name + `" out of range`)
-	engine.instr[singletonField] = decInstr{*op, singletonField, indir, 0, ovfl}
-	engine.numInstr = 1
-	return
-}
-
-// compileIgnoreSingle compiles the decoder engine for a non-struct top-level value that will be discarded.
-func (dec *Decoder) compileIgnoreSingle(remoteId typeId) (engine *decEngine, err error) {
-	engine = new(decEngine)
-	engine.instr = make([]decInstr, 1) // one item
-	op := dec.decIgnoreOpFor(remoteId)
-	ovfl := overflow(dec.typeString(remoteId))
-	engine.instr[0] = decInstr{op, 0, 0, 0, ovfl}
-	engine.numInstr = 1
-	return
-}
-
-// compileDec compiles the decoder engine for a value.  If the value is not a struct,
-// it calls out to compileSingle.
-func (dec *Decoder) compileDec(remoteId typeId, ut *userTypeInfo) (engine *decEngine, err error) {
-	rt := ut.base
-	srt := rt
-	if srt.Kind() != reflect.Struct || ut.externalDec != 0 {
-		return dec.compileSingle(remoteId, ut)
-	}
-	var wireStruct *structType
-	// Builtin types can come from global pool; the rest must be defined by the decoder.
-	// Also we know we're decoding a struct now, so the client must have sent one.
-	if t, ok := builtinIdToType[remoteId]; ok {
-		wireStruct, _ = t.(*structType)
-	} else {
-		wire := dec.wireType[remoteId]
-		if wire == nil {
-			error_(errBadType)
-		}
-		wireStruct = wire.StructT
-	}
-	if wireStruct == nil {
-		errorf("type mismatch in decoder: want struct type %s; got non-struct", rt)
-	}
-	engine = new(decEngine)
-	engine.instr = make([]decInstr, len(wireStruct.Field))
-	seen := make(map[reflect.Type]*decOp)
-	// Loop over the fields of the wire type.
-	for fieldnum := 0; fieldnum < len(wireStruct.Field); fieldnum++ {
-		wireField := wireStruct.Field[fieldnum]
-		if wireField.Name == "" {
-			errorf("empty name for remote field of type %s", wireStruct.Name)
-		}
-		ovfl := overflow(wireField.Name)
-		// Find the field of the local type with the same name.
-		localField, present := srt.FieldByName(wireField.Name)
-		// TODO(r): anonymous names
-		if !present || !isExported(wireField.Name) {
-			op := dec.decIgnoreOpFor(wireField.Id)
-			engine.instr[fieldnum] = decInstr{op, fieldnum, 0, 0, ovfl}
-			continue
-		}
-		if !dec.compatibleType(localField.Type, wireField.Id, make(map[reflect.Type]typeId)) {
-			errorf("wrong type (%s) for received field %s.%s", localField.Type, wireStruct.Name, wireField.Name)
-		}
-		op, indir := dec.decOpFor(wireField.Id, localField.Type, localField.Name, seen)
-		engine.instr[fieldnum] = decInstr{*op, fieldnum, indir, uintptr(localField.Offset), ovfl}
-		engine.numInstr++
-	}
-	return
-}
-
-// getDecEnginePtr returns the engine for the specified type.
-func (dec *Decoder) getDecEnginePtr(remoteId typeId, ut *userTypeInfo) (enginePtr **decEngine, err error) {
-	rt := ut.user
-	decoderMap, ok := dec.decoderCache[rt]
-	if !ok {
-		decoderMap = make(map[typeId]**decEngine)
-		dec.decoderCache[rt] = decoderMap
-	}
-	if enginePtr, ok = decoderMap[remoteId]; !ok {
-		// To handle recursive types, mark this engine as underway before compiling.
-		enginePtr = new(*decEngine)
-		decoderMap[remoteId] = enginePtr
-		*enginePtr, err = dec.compileDec(remoteId, ut)
-		if err != nil {
-			delete(decoderMap, remoteId)
-		}
-	}
-	return
-}
-
-// emptyStruct is the type we compile into when ignoring a struct value.
-type emptyStruct struct{}
-
-var emptyStructType = reflect.TypeOf(emptyStruct{})
-
-// getDecEnginePtr returns the engine for the specified type when the value is to be discarded.
-func (dec *Decoder) getIgnoreEnginePtr(wireId typeId) (enginePtr **decEngine, err error) {
-	var ok bool
-	if enginePtr, ok = dec.ignorerCache[wireId]; !ok {
-		// To handle recursive types, mark this engine as underway before compiling.
-		enginePtr = new(*decEngine)
-		dec.ignorerCache[wireId] = enginePtr
-		wire := dec.wireType[wireId]
-		if wire != nil && wire.StructT != nil {
-			*enginePtr, err = dec.compileDec(wireId, userType(emptyStructType))
-		} else {
-			*enginePtr, err = dec.compileIgnoreSingle(wireId)
-		}
-		if err != nil {
-			delete(dec.ignorerCache, wireId)
-		}
-	}
-	return
-}
-
-// decodeValue decodes the data stream representing a value and stores it in val.
-func (dec *Decoder) decodeValue(wireId typeId, val reflect.Value) {
-	defer catchError(&dec.err)
-	// If the value is nil, it means we should just ignore this item.
-	if !val.IsValid() {
-		dec.decodeIgnoredValue(wireId)
-		return
-	}
-	// Dereference down to the underlying type.
-	ut := userType(val.Type())
-	base := ut.base
-	var enginePtr **decEngine
-	enginePtr, dec.err = dec.getDecEnginePtr(wireId, ut)
-	if dec.err != nil {
-		return
-	}
-	engine := *enginePtr
-	if st := base; st.Kind() == reflect.Struct && ut.externalDec == 0 {
-		if engine.numInstr == 0 && st.NumField() > 0 &&
-			dec.wireType[wireId] != nil && len(dec.wireType[wireId].StructT.Field) > 0 {
-			name := base.Name()
-			errorf("type mismatch: no fields matched compiling decoder for %s", name)
-		}
-		dec.decodeStruct(engine, ut, unsafeAddr(val), ut.indir)
-	} else {
-		dec.decodeSingle(engine, ut, unsafeAddr(val))
-	}
-}
-
-// decodeIgnoredValue decodes the data stream representing a value of the specified type and discards it.
-func (dec *Decoder) decodeIgnoredValue(wireId typeId) {
-	var enginePtr **decEngine
-	enginePtr, dec.err = dec.getIgnoreEnginePtr(wireId)
-	if dec.err != nil {
-		return
-	}
-	wire := dec.wireType[wireId]
-	if wire != nil && wire.StructT != nil {
-		dec.ignoreStruct(*enginePtr)
-	} else {
-		dec.ignoreSingle(*enginePtr)
-	}
-}
-
-func init() {
-	var iop, uop decOp
-	switch reflect.TypeOf(int(0)).Bits() {
-	case 32:
-		iop = decInt32
-		uop = decUint32
-	case 64:
-		iop = decInt64
-		uop = decUint64
-	default:
-		panic("gob: unknown size of int/uint")
-	}
-	decOpTable[reflect.Int] = iop
-	decOpTable[reflect.Uint] = uop
-
-	// Finally uintptr
-	switch reflect.TypeOf(uintptr(0)).Bits() {
-	case 32:
-		uop = decUint32
-	case 64:
-		uop = decUint64
-	default:
-		panic("gob: unknown size of uintptr")
-	}
-	decOpTable[reflect.Uintptr] = uop
-}
-
-// Gob assumes it can call UnsafeAddr on any Value
-// in order to get a pointer it can copy data from.
-// Values that have just been created and do not point
-// into existing structs or slices cannot be addressed,
-// so simulate it by returning a pointer to a copy.
-// Each call allocates once.
-func unsafeAddr(v reflect.Value) unsafe.Pointer {
-	if v.CanAddr() {
-		return unsafe.Pointer(v.UnsafeAddr())
-	}
-	x := reflect.New(v.Type()).Elem()
-	x.Set(v)
-	return unsafe.Pointer(x.UnsafeAddr())
-}
-
-// Gob depends on being able to take the address
-// of zeroed Values it creates, so use this wrapper instead
-// of the standard reflect.Zero.
-// Each call allocates once.
-func allocValue(t reflect.Type) reflect.Value {
-	return reflect.New(t).Elem()
-}
diff --git a/src/pkg/encoding/gob/decoder.go b/src/pkg/encoding/gob/decoder.go
deleted file mode 100644
index 3a769ec..0000000
--- a/src/pkg/encoding/gob/decoder.go
+++ /dev/null
@@ -1,237 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package gob
-
-import (
-	"bufio"
-	"bytes"
-	"errors"
-	"io"
-	"reflect"
-	"sync"
-)
-
-// A Decoder manages the receipt of type and data information read from the
-// remote side of a connection.
-type Decoder struct {
-	mutex        sync.Mutex                              // each item must be received atomically
-	r            io.Reader                               // source of the data
-	buf          bytes.Buffer                            // buffer for more efficient i/o from r
-	wireType     map[typeId]*wireType                    // map from remote ID to local description
-	decoderCache map[reflect.Type]map[typeId]**decEngine // cache of compiled engines
-	ignorerCache map[typeId]**decEngine                  // ditto for ignored objects
-	freeList     *decoderState                           // list of free decoderStates; avoids reallocation
-	countBuf     []byte                                  // used for decoding integers while parsing messages
-	tmp          []byte                                  // temporary storage for i/o; saves reallocating
-	err          error
-}
-
-// NewDecoder returns a new decoder that reads from the io.Reader.
-// If r does not also implement io.ByteReader, it will be wrapped in a
-// bufio.Reader.
-func NewDecoder(r io.Reader) *Decoder {
-	dec := new(Decoder)
-	// We use the ability to read bytes as a plausible surrogate for buffering.
-	if _, ok := r.(io.ByteReader); !ok {
-		r = bufio.NewReader(r)
-	}
-	dec.r = r
-	dec.wireType = make(map[typeId]*wireType)
-	dec.decoderCache = make(map[reflect.Type]map[typeId]**decEngine)
-	dec.ignorerCache = make(map[typeId]**decEngine)
-	dec.countBuf = make([]byte, 9) // counts may be uint64s (unlikely!), require 9 bytes
-
-	return dec
-}
-
-// recvType loads the definition of a type.
-func (dec *Decoder) recvType(id typeId) {
-	// Have we already seen this type?  That's an error
-	if id < firstUserId || dec.wireType[id] != nil {
-		dec.err = errors.New("gob: duplicate type received")
-		return
-	}
-
-	// Type:
-	wire := new(wireType)
-	dec.decodeValue(tWireType, reflect.ValueOf(wire))
-	if dec.err != nil {
-		return
-	}
-	// Remember we've seen this type.
-	dec.wireType[id] = wire
-}
-
-var errBadCount = errors.New("invalid message length")
-
-// recvMessage reads the next count-delimited item from the input. It is the converse
-// of Encoder.writeMessage. It returns false on EOF or other error reading the message.
-func (dec *Decoder) recvMessage() bool {
-	// Read a count.
-	nbytes, _, err := decodeUintReader(dec.r, dec.countBuf)
-	if err != nil {
-		dec.err = err
-		return false
-	}
-	// Upper limit of 1GB, allowing room to grow a little without overflow.
-	// TODO: We might want more control over this limit.
-	if nbytes >= 1<<30 {
-		dec.err = errBadCount
-		return false
-	}
-	dec.readMessage(int(nbytes))
-	return dec.err == nil
-}
-
-// readMessage reads the next nbytes bytes from the input.
-func (dec *Decoder) readMessage(nbytes int) {
-	// Allocate the dec.tmp buffer, up to 10KB.
-	const maxBuf = 10 * 1024
-	nTmp := nbytes
-	if nTmp > maxBuf {
-		nTmp = maxBuf
-	}
-	if cap(dec.tmp) < nTmp {
-		nAlloc := nTmp + 100 // A little extra for growth.
-		if nAlloc > maxBuf {
-			nAlloc = maxBuf
-		}
-		dec.tmp = make([]byte, nAlloc)
-	}
-	dec.tmp = dec.tmp[:nTmp]
-
-	// Read the data
-	dec.buf.Grow(nbytes)
-	for nbytes > 0 {
-		if nbytes < nTmp {
-			dec.tmp = dec.tmp[:nbytes]
-		}
-		var nRead int
-		nRead, dec.err = io.ReadFull(dec.r, dec.tmp)
-		if dec.err != nil {
-			if dec.err == io.EOF {
-				dec.err = io.ErrUnexpectedEOF
-			}
-			return
-		}
-		dec.buf.Write(dec.tmp)
-		nbytes -= nRead
-	}
-}
-
-// toInt turns an encoded uint64 into an int, according to the marshaling rules.
-func toInt(x uint64) int64 {
-	i := int64(x >> 1)
-	if x&1 != 0 {
-		i = ^i
-	}
-	return i
-}
-
-func (dec *Decoder) nextInt() int64 {
-	n, _, err := decodeUintReader(&dec.buf, dec.countBuf)
-	if err != nil {
-		dec.err = err
-	}
-	return toInt(n)
-}
-
-func (dec *Decoder) nextUint() uint64 {
-	n, _, err := decodeUintReader(&dec.buf, dec.countBuf)
-	if err != nil {
-		dec.err = err
-	}
-	return n
-}
-
-// decodeTypeSequence parses:
-// TypeSequence
-//	(TypeDefinition DelimitedTypeDefinition*)?
-// and returns the type id of the next value.  It returns -1 at
-// EOF.  Upon return, the remainder of dec.buf is the value to be
-// decoded.  If this is an interface value, it can be ignored by
-// resetting that buffer.
-func (dec *Decoder) decodeTypeSequence(isInterface bool) typeId {
-	for dec.err == nil {
-		if dec.buf.Len() == 0 {
-			if !dec.recvMessage() {
-				break
-			}
-		}
-		// Receive a type id.
-		id := typeId(dec.nextInt())
-		if id >= 0 {
-			// Value follows.
-			return id
-		}
-		// Type definition for (-id) follows.
-		dec.recvType(-id)
-		// When decoding an interface, after a type there may be a
-		// DelimitedValue still in the buffer.  Skip its count.
-		// (Alternatively, the buffer is empty and the byte count
-		// will be absorbed by recvMessage.)
-		if dec.buf.Len() > 0 {
-			if !isInterface {
-				dec.err = errors.New("extra data in buffer")
-				break
-			}
-			dec.nextUint()
-		}
-	}
-	return -1
-}
-
-// Decode reads the next value from the input stream and stores
-// it in the data represented by the empty interface value.
-// If e is nil, the value will be discarded. Otherwise,
-// the value underlying e must be a pointer to the
-// correct type for the next data item received.
-// If the input is at EOF, Decode returns io.EOF and
-// does not modify e.
-func (dec *Decoder) Decode(e interface{}) error {
-	if e == nil {
-		return dec.DecodeValue(reflect.Value{})
-	}
-	value := reflect.ValueOf(e)
-	// If e represents a value as opposed to a pointer, the answer won't
-	// get back to the caller.  Make sure it's a pointer.
-	if value.Type().Kind() != reflect.Ptr {
-		dec.err = errors.New("gob: attempt to decode into a non-pointer")
-		return dec.err
-	}
-	return dec.DecodeValue(value)
-}
-
-// DecodeValue reads the next value from the input stream.
-// If v is the zero reflect.Value (v.Kind() == Invalid), DecodeValue discards the value.
-// Otherwise, it stores the value into v.  In that case, v must represent
-// a non-nil pointer to data or be an assignable reflect.Value (v.CanSet())
-// If the input is at EOF, DecodeValue returns io.EOF and
-// does not modify e.
-func (dec *Decoder) DecodeValue(v reflect.Value) error {
-	if v.IsValid() {
-		if v.Kind() == reflect.Ptr && !v.IsNil() {
-			// That's okay, we'll store through the pointer.
-		} else if !v.CanSet() {
-			return errors.New("gob: DecodeValue of unassignable value")
-		}
-	}
-	// Make sure we're single-threaded through here.
-	dec.mutex.Lock()
-	defer dec.mutex.Unlock()
-
-	dec.buf.Reset() // In case data lingers from previous invocation.
-	dec.err = nil
-	id := dec.decodeTypeSequence(false)
-	if dec.err == nil {
-		dec.decodeValue(id, v)
-	}
-	return dec.err
-}
-
-// If debug.go is compiled into the program , debugFunc prints a human-readable
-// representation of the gob data read from r by calling that file's Debug function.
-// Otherwise it is nil.
-var debugFunc func(io.Reader)
diff --git a/src/pkg/encoding/gob/encode.go b/src/pkg/encoding/gob/encode.go
deleted file mode 100644
index 7831c02..0000000
--- a/src/pkg/encoding/gob/encode.go
+++ /dev/null
@@ -1,760 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package gob
-
-import (
-	"bytes"
-	"encoding"
-	"math"
-	"reflect"
-	"unsafe"
-)
-
-const uint64Size = int(unsafe.Sizeof(uint64(0)))
-
-// encoderState is the global execution state of an instance of the encoder.
-// Field numbers are delta encoded and always increase. The field
-// number is initialized to -1 so 0 comes out as delta(1). A delta of
-// 0 terminates the structure.
-type encoderState struct {
-	enc      *Encoder
-	b        *bytes.Buffer
-	sendZero bool                 // encoding an array element or map key/value pair; send zero values
-	fieldnum int                  // the last field number written.
-	buf      [1 + uint64Size]byte // buffer used by the encoder; here to avoid allocation.
-	next     *encoderState        // for free list
-}
-
-func (enc *Encoder) newEncoderState(b *bytes.Buffer) *encoderState {
-	e := enc.freeList
-	if e == nil {
-		e = new(encoderState)
-		e.enc = enc
-	} else {
-		enc.freeList = e.next
-	}
-	e.sendZero = false
-	e.fieldnum = 0
-	e.b = b
-	return e
-}
-
-func (enc *Encoder) freeEncoderState(e *encoderState) {
-	e.next = enc.freeList
-	enc.freeList = e
-}
-
-// Unsigned integers have a two-state encoding.  If the number is less
-// than 128 (0 through 0x7F), its value is written directly.
-// Otherwise the value is written in big-endian byte order preceded
-// by the byte length, negated.
-
-// encodeUint writes an encoded unsigned integer to state.b.
-func (state *encoderState) encodeUint(x uint64) {
-	if x <= 0x7F {
-		err := state.b.WriteByte(uint8(x))
-		if err != nil {
-			error_(err)
-		}
-		return
-	}
-	i := uint64Size
-	for x > 0 {
-		state.buf[i] = uint8(x)
-		x >>= 8
-		i--
-	}
-	state.buf[i] = uint8(i - uint64Size) // = loop count, negated
-	_, err := state.b.Write(state.buf[i : uint64Size+1])
-	if err != nil {
-		error_(err)
-	}
-}
-
-// encodeInt writes an encoded signed integer to state.w.
-// The low bit of the encoding says whether to bit complement the (other bits of the)
-// uint to recover the int.
-func (state *encoderState) encodeInt(i int64) {
-	var x uint64
-	if i < 0 {
-		x = uint64(^i<<1) | 1
-	} else {
-		x = uint64(i << 1)
-	}
-	state.encodeUint(uint64(x))
-}
-
-// encOp is the signature of an encoding operator for a given type.
-type encOp func(i *encInstr, state *encoderState, p unsafe.Pointer)
-
-// The 'instructions' of the encoding machine
-type encInstr struct {
-	op     encOp
-	field  int     // field number
-	indir  int     // how many pointer indirections to reach the value in the struct
-	offset uintptr // offset in the structure of the field to encode
-}
-
-// update emits a field number and updates the state to record its value for delta encoding.
-// If the instruction pointer is nil, it does nothing
-func (state *encoderState) update(instr *encInstr) {
-	if instr != nil {
-		state.encodeUint(uint64(instr.field - state.fieldnum))
-		state.fieldnum = instr.field
-	}
-}
-
-// Each encoder for a composite is responsible for handling any
-// indirections associated with the elements of the data structure.
-// If any pointer so reached is nil, no bytes are written.  If the
-// data item is zero, no bytes are written.  Single values - ints,
-// strings etc. - are indirected before calling their encoders.
-// Otherwise, the output (for a scalar) is the field number, as an
-// encoded integer, followed by the field data in its appropriate
-// format.
-
-// encIndirect dereferences p indir times and returns the result.
-func encIndirect(p unsafe.Pointer, indir int) unsafe.Pointer {
-	for ; indir > 0; indir-- {
-		p = *(*unsafe.Pointer)(p)
-		if p == nil {
-			return unsafe.Pointer(nil)
-		}
-	}
-	return p
-}
-
-// encBool encodes the bool with address p as an unsigned 0 or 1.
-func encBool(i *encInstr, state *encoderState, p unsafe.Pointer) {
-	b := *(*bool)(p)
-	if b || state.sendZero {
-		state.update(i)
-		if b {
-			state.encodeUint(1)
-		} else {
-			state.encodeUint(0)
-		}
-	}
-}
-
-// encInt encodes the int with address p.
-func encInt(i *encInstr, state *encoderState, p unsafe.Pointer) {
-	v := int64(*(*int)(p))
-	if v != 0 || state.sendZero {
-		state.update(i)
-		state.encodeInt(v)
-	}
-}
-
-// encUint encodes the uint with address p.
-func encUint(i *encInstr, state *encoderState, p unsafe.Pointer) {
-	v := uint64(*(*uint)(p))
-	if v != 0 || state.sendZero {
-		state.update(i)
-		state.encodeUint(v)
-	}
-}
-
-// encInt8 encodes the int8 with address p.
-func encInt8(i *encInstr, state *encoderState, p unsafe.Pointer) {
-	v := int64(*(*int8)(p))
-	if v != 0 || state.sendZero {
-		state.update(i)
-		state.encodeInt(v)
-	}
-}
-
-// encUint8 encodes the uint8 with address p.
-func encUint8(i *encInstr, state *encoderState, p unsafe.Pointer) {
-	v := uint64(*(*uint8)(p))
-	if v != 0 || state.sendZero {
-		state.update(i)
-		state.encodeUint(v)
-	}
-}
-
-// encInt16 encodes the int16 with address p.
-func encInt16(i *encInstr, state *encoderState, p unsafe.Pointer) {
-	v := int64(*(*int16)(p))
-	if v != 0 || state.sendZero {
-		state.update(i)
-		state.encodeInt(v)
-	}
-}
-
-// encUint16 encodes the uint16 with address p.
-func encUint16(i *encInstr, state *encoderState, p unsafe.Pointer) {
-	v := uint64(*(*uint16)(p))
-	if v != 0 || state.sendZero {
-		state.update(i)
-		state.encodeUint(v)
-	}
-}
-
-// encInt32 encodes the int32 with address p.
-func encInt32(i *encInstr, state *encoderState, p unsafe.Pointer) {
-	v := int64(*(*int32)(p))
-	if v != 0 || state.sendZero {
-		state.update(i)
-		state.encodeInt(v)
-	}
-}
-
-// encUint encodes the uint32 with address p.
-func encUint32(i *encInstr, state *encoderState, p unsafe.Pointer) {
-	v := uint64(*(*uint32)(p))
-	if v != 0 || state.sendZero {
-		state.update(i)
-		state.encodeUint(v)
-	}
-}
-
-// encInt64 encodes the int64 with address p.
-func encInt64(i *encInstr, state *encoderState, p unsafe.Pointer) {
-	v := *(*int64)(p)
-	if v != 0 || state.sendZero {
-		state.update(i)
-		state.encodeInt(v)
-	}
-}
-
-// encInt64 encodes the uint64 with address p.
-func encUint64(i *encInstr, state *encoderState, p unsafe.Pointer) {
-	v := *(*uint64)(p)
-	if v != 0 || state.sendZero {
-		state.update(i)
-		state.encodeUint(v)
-	}
-}
-
-// encUintptr encodes the uintptr with address p.
-func encUintptr(i *encInstr, state *encoderState, p unsafe.Pointer) {
-	v := uint64(*(*uintptr)(p))
-	if v != 0 || state.sendZero {
-		state.update(i)
-		state.encodeUint(v)
-	}
-}
-
-// floatBits returns a uint64 holding the bits of a floating-point number.
-// Floating-point numbers are transmitted as uint64s holding the bits
-// of the underlying representation.  They are sent byte-reversed, with
-// the exponent end coming out first, so integer floating point numbers
-// (for example) transmit more compactly.  This routine does the
-// swizzling.
-func floatBits(f float64) uint64 {
-	u := math.Float64bits(f)
-	var v uint64
-	for i := 0; i < 8; i++ {
-		v <<= 8
-		v |= u & 0xFF
-		u >>= 8
-	}
-	return v
-}
-
-// encFloat32 encodes the float32 with address p.
-func encFloat32(i *encInstr, state *encoderState, p unsafe.Pointer) {
-	f := *(*float32)(p)
-	if f != 0 || state.sendZero {
-		v := floatBits(float64(f))
-		state.update(i)
-		state.encodeUint(v)
-	}
-}
-
-// encFloat64 encodes the float64 with address p.
-func encFloat64(i *encInstr, state *encoderState, p unsafe.Pointer) {
-	f := *(*float64)(p)
-	if f != 0 || state.sendZero {
-		state.update(i)
-		v := floatBits(f)
-		state.encodeUint(v)
-	}
-}
-
-// encComplex64 encodes the complex64 with address p.
-// Complex numbers are just a pair of floating-point numbers, real part first.
-func encComplex64(i *encInstr, state *encoderState, p unsafe.Pointer) {
-	c := *(*complex64)(p)
-	if c != 0+0i || state.sendZero {
-		rpart := floatBits(float64(real(c)))
-		ipart := floatBits(float64(imag(c)))
-		state.update(i)
-		state.encodeUint(rpart)
-		state.encodeUint(ipart)
-	}
-}
-
-// encComplex128 encodes the complex128 with address p.
-func encComplex128(i *encInstr, state *encoderState, p unsafe.Pointer) {
-	c := *(*complex128)(p)
-	if c != 0+0i || state.sendZero {
-		rpart := floatBits(real(c))
-		ipart := floatBits(imag(c))
-		state.update(i)
-		state.encodeUint(rpart)
-		state.encodeUint(ipart)
-	}
-}
-
-// encUint8Array encodes the byte slice whose header has address p.
-// Byte arrays are encoded as an unsigned count followed by the raw bytes.
-func encUint8Array(i *encInstr, state *encoderState, p unsafe.Pointer) {
-	b := *(*[]byte)(p)
-	if len(b) > 0 || state.sendZero {
-		state.update(i)
-		state.encodeUint(uint64(len(b)))
-		state.b.Write(b)
-	}
-}
-
-// encString encodes the string whose header has address p.
-// Strings are encoded as an unsigned count followed by the raw bytes.
-func encString(i *encInstr, state *encoderState, p unsafe.Pointer) {
-	s := *(*string)(p)
-	if len(s) > 0 || state.sendZero {
-		state.update(i)
-		state.encodeUint(uint64(len(s)))
-		state.b.WriteString(s)
-	}
-}
-
-// encStructTerminator encodes the end of an encoded struct
-// as delta field number of 0.
-func encStructTerminator(i *encInstr, state *encoderState, p unsafe.Pointer) {
-	state.encodeUint(0)
-}
-
-// Execution engine
-
-// encEngine an array of instructions indexed by field number of the encoding
-// data, typically a struct.  It is executed top to bottom, walking the struct.
-type encEngine struct {
-	instr []encInstr
-}
-
-const singletonField = 0
-
-// encodeSingle encodes a single top-level non-struct value.
-func (enc *Encoder) encodeSingle(b *bytes.Buffer, engine *encEngine, basep unsafe.Pointer) {
-	state := enc.newEncoderState(b)
-	state.fieldnum = singletonField
-	// There is no surrounding struct to frame the transmission, so we must
-	// generate data even if the item is zero.  To do this, set sendZero.
-	state.sendZero = true
-	instr := &engine.instr[singletonField]
-	p := basep // offset will be zero
-	if instr.indir > 0 {
-		if p = encIndirect(p, instr.indir); p == nil {
-			return
-		}
-	}
-	instr.op(instr, state, p)
-	enc.freeEncoderState(state)
-}
-
-// encodeStruct encodes a single struct value.
-func (enc *Encoder) encodeStruct(b *bytes.Buffer, engine *encEngine, basep unsafe.Pointer) {
-	state := enc.newEncoderState(b)
-	state.fieldnum = -1
-	for i := 0; i < len(engine.instr); i++ {
-		instr := &engine.instr[i]
-		p := unsafe.Pointer(uintptr(basep) + instr.offset)
-		if instr.indir > 0 {
-			if p = encIndirect(p, instr.indir); p == nil {
-				continue
-			}
-		}
-		instr.op(instr, state, p)
-	}
-	enc.freeEncoderState(state)
-}
-
-// encodeArray encodes the array whose 0th element is at p.
-func (enc *Encoder) encodeArray(b *bytes.Buffer, p unsafe.Pointer, op encOp, elemWid uintptr, elemIndir int, length int) {
-	state := enc.newEncoderState(b)
-	state.fieldnum = -1
-	state.sendZero = true
-	state.encodeUint(uint64(length))
-	for i := 0; i < length; i++ {
-		elemp := p
-		if elemIndir > 0 {
-			up := encIndirect(elemp, elemIndir)
-			if up == nil {
-				errorf("encodeArray: nil element")
-			}
-			elemp = up
-		}
-		op(nil, state, elemp)
-		p = unsafe.Pointer(uintptr(p) + elemWid)
-	}
-	enc.freeEncoderState(state)
-}
-
-// encodeReflectValue is a helper for maps. It encodes the value v.
-func encodeReflectValue(state *encoderState, v reflect.Value, op encOp, indir int) {
-	for i := 0; i < indir && v.IsValid(); i++ {
-		v = reflect.Indirect(v)
-	}
-	if !v.IsValid() {
-		errorf("encodeReflectValue: nil element")
-	}
-	op(nil, state, unsafeAddr(v))
-}
-
-// encodeMap encodes a map as unsigned count followed by key:value pairs.
-// Because map internals are not exposed, we must use reflection rather than
-// addresses.
-func (enc *Encoder) encodeMap(b *bytes.Buffer, mv reflect.Value, keyOp, elemOp encOp, keyIndir, elemIndir int) {
-	state := enc.newEncoderState(b)
-	state.fieldnum = -1
-	state.sendZero = true
-	keys := mv.MapKeys()
-	state.encodeUint(uint64(len(keys)))
-	for _, key := range keys {
-		encodeReflectValue(state, key, keyOp, keyIndir)
-		encodeReflectValue(state, mv.MapIndex(key), elemOp, elemIndir)
-	}
-	enc.freeEncoderState(state)
-}
-
-// encodeInterface encodes the interface value iv.
-// To send an interface, we send a string identifying the concrete type, followed
-// by the type identifier (which might require defining that type right now), followed
-// by the concrete value.  A nil value gets sent as the empty string for the name,
-// followed by no value.
-func (enc *Encoder) encodeInterface(b *bytes.Buffer, iv reflect.Value) {
-	// Gobs can encode nil interface values but not typed interface
-	// values holding nil pointers, since nil pointers point to no value.
-	elem := iv.Elem()
-	if elem.Kind() == reflect.Ptr && elem.IsNil() {
-		errorf("gob: cannot encode nil pointer of type %s inside interface", iv.Elem().Type())
-	}
-	state := enc.newEncoderState(b)
-	state.fieldnum = -1
-	state.sendZero = true
-	if iv.IsNil() {
-		state.encodeUint(0)
-		return
-	}
-
-	ut := userType(iv.Elem().Type())
-	registerLock.RLock()
-	name, ok := concreteTypeToName[ut.base]
-	registerLock.RUnlock()
-	if !ok {
-		errorf("type not registered for interface: %s", ut.base)
-	}
-	// Send the name.
-	state.encodeUint(uint64(len(name)))
-	_, err := state.b.WriteString(name)
-	if err != nil {
-		error_(err)
-	}
-	// Define the type id if necessary.
-	enc.sendTypeDescriptor(enc.writer(), state, ut)
-	// Send the type id.
-	enc.sendTypeId(state, ut)
-	// Encode the value into a new buffer.  Any nested type definitions
-	// should be written to b, before the encoded value.
-	enc.pushWriter(b)
-	data := new(bytes.Buffer)
-	data.Write(spaceForLength)
-	enc.encode(data, elem, ut)
-	if enc.err != nil {
-		error_(enc.err)
-	}
-	enc.popWriter()
-	enc.writeMessage(b, data)
-	if enc.err != nil {
-		error_(err)
-	}
-	enc.freeEncoderState(state)
-}
-
-// isZero reports whether the value is the zero of its type.
-func isZero(val reflect.Value) bool {
-	switch val.Kind() {
-	case reflect.Array:
-		for i := 0; i < val.Len(); i++ {
-			if !isZero(val.Index(i)) {
-				return false
-			}
-		}
-		return true
-	case reflect.Map, reflect.Slice, reflect.String:
-		return val.Len() == 0
-	case reflect.Bool:
-		return !val.Bool()
-	case reflect.Complex64, reflect.Complex128:
-		return val.Complex() == 0
-	case reflect.Chan, reflect.Func, reflect.Interface, reflect.Ptr:
-		return val.IsNil()
-	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-		return val.Int() == 0
-	case reflect.Float32, reflect.Float64:
-		return val.Float() == 0
-	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
-		return val.Uint() == 0
-	case reflect.Struct:
-		for i := 0; i < val.NumField(); i++ {
-			if !isZero(val.Field(i)) {
-				return false
-			}
-		}
-		return true
-	}
-	panic("unknown type in isZero " + val.Type().String())
-}
-
-// encGobEncoder encodes a value that implements the GobEncoder interface.
-// The data is sent as a byte array.
-func (enc *Encoder) encodeGobEncoder(b *bytes.Buffer, ut *userTypeInfo, v reflect.Value) {
-	// TODO: should we catch panics from the called method?
-
-	var data []byte
-	var err error
-	// We know it's one of these.
-	switch ut.externalEnc {
-	case xGob:
-		data, err = v.Interface().(GobEncoder).GobEncode()
-	case xBinary:
-		data, err = v.Interface().(encoding.BinaryMarshaler).MarshalBinary()
-	case xText:
-		data, err = v.Interface().(encoding.TextMarshaler).MarshalText()
-	}
-	if err != nil {
-		error_(err)
-	}
-	state := enc.newEncoderState(b)
-	state.fieldnum = -1
-	state.encodeUint(uint64(len(data)))
-	state.b.Write(data)
-	enc.freeEncoderState(state)
-}
-
-var encOpTable = [...]encOp{
-	reflect.Bool:       encBool,
-	reflect.Int:        encInt,
-	reflect.Int8:       encInt8,
-	reflect.Int16:      encInt16,
-	reflect.Int32:      encInt32,
-	reflect.Int64:      encInt64,
-	reflect.Uint:       encUint,
-	reflect.Uint8:      encUint8,
-	reflect.Uint16:     encUint16,
-	reflect.Uint32:     encUint32,
-	reflect.Uint64:     encUint64,
-	reflect.Uintptr:    encUintptr,
-	reflect.Float32:    encFloat32,
-	reflect.Float64:    encFloat64,
-	reflect.Complex64:  encComplex64,
-	reflect.Complex128: encComplex128,
-	reflect.String:     encString,
-}
-
-// encOpFor returns (a pointer to) the encoding op for the base type under rt and
-// the indirection count to reach it.
-func (enc *Encoder) encOpFor(rt reflect.Type, inProgress map[reflect.Type]*encOp) (*encOp, int) {
-	ut := userType(rt)
-	// If the type implements GobEncoder, we handle it without further processing.
-	if ut.externalEnc != 0 {
-		return enc.gobEncodeOpFor(ut)
-	}
-	// If this type is already in progress, it's a recursive type (e.g. map[string]*T).
-	// Return the pointer to the op we're already building.
-	if opPtr := inProgress[rt]; opPtr != nil {
-		return opPtr, ut.indir
-	}
-	typ := ut.base
-	indir := ut.indir
-	k := typ.Kind()
-	var op encOp
-	if int(k) < len(encOpTable) {
-		op = encOpTable[k]
-	}
-	if op == nil {
-		inProgress[rt] = &op
-		// Special cases
-		switch t := typ; t.Kind() {
-		case reflect.Slice:
-			if t.Elem().Kind() == reflect.Uint8 {
-				op = encUint8Array
-				break
-			}
-			// Slices have a header; we decode it to find the underlying array.
-			elemOp, elemIndir := enc.encOpFor(t.Elem(), inProgress)
-			op = func(i *encInstr, state *encoderState, p unsafe.Pointer) {
-				slice := (*reflect.SliceHeader)(p)
-				if !state.sendZero && slice.Len == 0 {
-					return
-				}
-				state.update(i)
-				state.enc.encodeArray(state.b, unsafe.Pointer(slice.Data), *elemOp, t.Elem().Size(), elemIndir, int(slice.Len))
-			}
-		case reflect.Array:
-			// True arrays have size in the type.
-			elemOp, elemIndir := enc.encOpFor(t.Elem(), inProgress)
-			op = func(i *encInstr, state *encoderState, p unsafe.Pointer) {
-				state.update(i)
-				state.enc.encodeArray(state.b, p, *elemOp, t.Elem().Size(), elemIndir, t.Len())
-			}
-		case reflect.Map:
-			keyOp, keyIndir := enc.encOpFor(t.Key(), inProgress)
-			elemOp, elemIndir := enc.encOpFor(t.Elem(), inProgress)
-			op = func(i *encInstr, state *encoderState, p unsafe.Pointer) {
-				// Maps cannot be accessed by moving addresses around the way
-				// that slices etc. can.  We must recover a full reflection value for
-				// the iteration.
-				v := reflect.NewAt(t, unsafe.Pointer(p)).Elem()
-				mv := reflect.Indirect(v)
-				// We send zero-length (but non-nil) maps because the
-				// receiver might want to use the map.  (Maps don't use append.)
-				if !state.sendZero && mv.IsNil() {
-					return
-				}
-				state.update(i)
-				state.enc.encodeMap(state.b, mv, *keyOp, *elemOp, keyIndir, elemIndir)
-			}
-		case reflect.Struct:
-			// Generate a closure that calls out to the engine for the nested type.
-			enc.getEncEngine(userType(typ))
-			info := mustGetTypeInfo(typ)
-			op = func(i *encInstr, state *encoderState, p unsafe.Pointer) {
-				state.update(i)
-				// indirect through info to delay evaluation for recursive structs
-				state.enc.encodeStruct(state.b, info.encoder, p)
-			}
-		case reflect.Interface:
-			op = func(i *encInstr, state *encoderState, p unsafe.Pointer) {
-				// Interfaces transmit the name and contents of the concrete
-				// value they contain.
-				v := reflect.NewAt(t, unsafe.Pointer(p)).Elem()
-				iv := reflect.Indirect(v)
-				if !state.sendZero && (!iv.IsValid() || iv.IsNil()) {
-					return
-				}
-				state.update(i)
-				state.enc.encodeInterface(state.b, iv)
-			}
-		}
-	}
-	if op == nil {
-		errorf("can't happen: encode type %s", rt)
-	}
-	return &op, indir
-}
-
-// gobEncodeOpFor returns the op for a type that is known to implement
-// GobEncoder.
-func (enc *Encoder) gobEncodeOpFor(ut *userTypeInfo) (*encOp, int) {
-	rt := ut.user
-	if ut.encIndir == -1 {
-		rt = reflect.PtrTo(rt)
-	} else if ut.encIndir > 0 {
-		for i := int8(0); i < ut.encIndir; i++ {
-			rt = rt.Elem()
-		}
-	}
-	var op encOp
-	op = func(i *encInstr, state *encoderState, p unsafe.Pointer) {
-		var v reflect.Value
-		if ut.encIndir == -1 {
-			// Need to climb up one level to turn value into pointer.
-			v = reflect.NewAt(rt, unsafe.Pointer(&p)).Elem()
-		} else {
-			v = reflect.NewAt(rt, p).Elem()
-		}
-		if !state.sendZero && isZero(v) {
-			return
-		}
-		state.update(i)
-		state.enc.encodeGobEncoder(state.b, ut, v)
-	}
-	return &op, int(ut.encIndir) // encIndir: op will get called with p == address of receiver.
-}
-
-// compileEnc returns the engine to compile the type.
-func (enc *Encoder) compileEnc(ut *userTypeInfo) *encEngine {
-	srt := ut.base
-	engine := new(encEngine)
-	seen := make(map[reflect.Type]*encOp)
-	rt := ut.base
-	if ut.externalEnc != 0 {
-		rt = ut.user
-	}
-	if ut.externalEnc == 0 && srt.Kind() == reflect.Struct {
-		for fieldNum, wireFieldNum := 0, 0; fieldNum < srt.NumField(); fieldNum++ {
-			f := srt.Field(fieldNum)
-			if !isSent(&f) {
-				continue
-			}
-			op, indir := enc.encOpFor(f.Type, seen)
-			engine.instr = append(engine.instr, encInstr{*op, wireFieldNum, indir, uintptr(f.Offset)})
-			wireFieldNum++
-		}
-		if srt.NumField() > 0 && len(engine.instr) == 0 {
-			errorf("type %s has no exported fields", rt)
-		}
-		engine.instr = append(engine.instr, encInstr{encStructTerminator, 0, 0, 0})
-	} else {
-		engine.instr = make([]encInstr, 1)
-		op, indir := enc.encOpFor(rt, seen)
-		engine.instr[0] = encInstr{*op, singletonField, indir, 0} // offset is zero
-	}
-	return engine
-}
-
-// getEncEngine returns the engine to compile the type.
-// typeLock must be held (or we're in initialization and guaranteed single-threaded).
-func (enc *Encoder) getEncEngine(ut *userTypeInfo) *encEngine {
-	info, err1 := getTypeInfo(ut)
-	if err1 != nil {
-		error_(err1)
-	}
-	if info.encoder == nil {
-		// Assign the encEngine now, so recursive types work correctly. But...
-		info.encoder = new(encEngine)
-		// ... if we fail to complete building the engine, don't cache the half-built machine.
-		// Doing this here means we won't cache a type that is itself OK but
-		// that contains a nested type that won't compile. The result is consistent
-		// error behavior when Encode is called multiple times on the top-level type.
-		ok := false
-		defer func() {
-			if !ok {
-				info.encoder = nil
-			}
-		}()
-		info.encoder = enc.compileEnc(ut)
-		ok = true
-	}
-	return info.encoder
-}
-
-// lockAndGetEncEngine is a function that locks and compiles.
-// This lets us hold the lock only while compiling, not when encoding.
-func (enc *Encoder) lockAndGetEncEngine(ut *userTypeInfo) *encEngine {
-	typeLock.Lock()
-	defer typeLock.Unlock()
-	return enc.getEncEngine(ut)
-}
-
-func (enc *Encoder) encode(b *bytes.Buffer, value reflect.Value, ut *userTypeInfo) {
-	defer catchError(&enc.err)
-	engine := enc.lockAndGetEncEngine(ut)
-	indir := ut.indir
-	if ut.externalEnc != 0 {
-		indir = int(ut.encIndir)
-	}
-	for i := 0; i < indir; i++ {
-		value = reflect.Indirect(value)
-	}
-	if ut.externalEnc == 0 && value.Type().Kind() == reflect.Struct {
-		enc.encodeStruct(b, engine, unsafeAddr(value))
-	} else {
-		enc.encodeSingle(b, engine, unsafeAddr(value))
-	}
-}
diff --git a/src/pkg/encoding/gob/encoder.go b/src/pkg/encoding/gob/encoder.go
deleted file mode 100644
index a3301c3..0000000
--- a/src/pkg/encoding/gob/encoder.go
+++ /dev/null
@@ -1,253 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package gob
-
-import (
-	"bytes"
-	"io"
-	"reflect"
-	"sync"
-)
-
-// An Encoder manages the transmission of type and data information to the
-// other side of a connection.
-type Encoder struct {
-	mutex      sync.Mutex              // each item must be sent atomically
-	w          []io.Writer             // where to send the data
-	sent       map[reflect.Type]typeId // which types we've already sent
-	countState *encoderState           // stage for writing counts
-	freeList   *encoderState           // list of free encoderStates; avoids reallocation
-	byteBuf    bytes.Buffer            // buffer for top-level encoderState
-	err        error
-}
-
-// Before we encode a message, we reserve space at the head of the
-// buffer in which to encode its length. This means we can use the
-// buffer to assemble the message without another allocation.
-const maxLength = 9 // Maximum size of an encoded length.
-var spaceForLength = make([]byte, maxLength)
-
-// NewEncoder returns a new encoder that will transmit on the io.Writer.
-func NewEncoder(w io.Writer) *Encoder {
-	enc := new(Encoder)
-	enc.w = []io.Writer{w}
-	enc.sent = make(map[reflect.Type]typeId)
-	enc.countState = enc.newEncoderState(new(bytes.Buffer))
-	return enc
-}
-
-// writer() returns the innermost writer the encoder is using
-func (enc *Encoder) writer() io.Writer {
-	return enc.w[len(enc.w)-1]
-}
-
-// pushWriter adds a writer to the encoder.
-func (enc *Encoder) pushWriter(w io.Writer) {
-	enc.w = append(enc.w, w)
-}
-
-// popWriter pops the innermost writer.
-func (enc *Encoder) popWriter() {
-	enc.w = enc.w[0 : len(enc.w)-1]
-}
-
-func (enc *Encoder) setError(err error) {
-	if enc.err == nil { // remember the first.
-		enc.err = err
-	}
-}
-
-// writeMessage sends the data item preceded by a unsigned count of its length.
-func (enc *Encoder) writeMessage(w io.Writer, b *bytes.Buffer) {
-	// Space has been reserved for the length at the head of the message.
-	// This is a little dirty: we grab the slice from the bytes.Buffer and massage
-	// it by hand.
-	message := b.Bytes()
-	messageLen := len(message) - maxLength
-	// Encode the length.
-	enc.countState.b.Reset()
-	enc.countState.encodeUint(uint64(messageLen))
-	// Copy the length to be a prefix of the message.
-	offset := maxLength - enc.countState.b.Len()
-	copy(message[offset:], enc.countState.b.Bytes())
-	// Write the data.
-	_, err := w.Write(message[offset:])
-	// Drain the buffer and restore the space at the front for the count of the next message.
-	b.Reset()
-	b.Write(spaceForLength)
-	if err != nil {
-		enc.setError(err)
-	}
-}
-
-// sendActualType sends the requested type, without further investigation, unless
-// it's been sent before.
-func (enc *Encoder) sendActualType(w io.Writer, state *encoderState, ut *userTypeInfo, actual reflect.Type) (sent bool) {
-	if _, alreadySent := enc.sent[actual]; alreadySent {
-		return false
-	}
-	typeLock.Lock()
-	info, err := getTypeInfo(ut)
-	typeLock.Unlock()
-	if err != nil {
-		enc.setError(err)
-		return
-	}
-	// Send the pair (-id, type)
-	// Id:
-	state.encodeInt(-int64(info.id))
-	// Type:
-	enc.encode(state.b, reflect.ValueOf(info.wire), wireTypeUserInfo)
-	enc.writeMessage(w, state.b)
-	if enc.err != nil {
-		return
-	}
-
-	// Remember we've sent this type, both what the user gave us and the base type.
-	enc.sent[ut.base] = info.id
-	if ut.user != ut.base {
-		enc.sent[ut.user] = info.id
-	}
-	// Now send the inner types
-	switch st := actual; st.Kind() {
-	case reflect.Struct:
-		for i := 0; i < st.NumField(); i++ {
-			if isExported(st.Field(i).Name) {
-				enc.sendType(w, state, st.Field(i).Type)
-			}
-		}
-	case reflect.Array, reflect.Slice:
-		enc.sendType(w, state, st.Elem())
-	case reflect.Map:
-		enc.sendType(w, state, st.Key())
-		enc.sendType(w, state, st.Elem())
-	}
-	return true
-}
-
-// sendType sends the type info to the other side, if necessary.
-func (enc *Encoder) sendType(w io.Writer, state *encoderState, origt reflect.Type) (sent bool) {
-	ut := userType(origt)
-	if ut.externalEnc != 0 {
-		// The rules are different: regardless of the underlying type's representation,
-		// we need to tell the other side that the base type is a GobEncoder.
-		return enc.sendActualType(w, state, ut, ut.base)
-	}
-
-	// It's a concrete value, so drill down to the base type.
-	switch rt := ut.base; rt.Kind() {
-	default:
-		// Basic types and interfaces do not need to be described.
-		return
-	case reflect.Slice:
-		// If it's []uint8, don't send; it's considered basic.
-		if rt.Elem().Kind() == reflect.Uint8 {
-			return
-		}
-		// Otherwise we do send.
-		break
-	case reflect.Array:
-		// arrays must be sent so we know their lengths and element types.
-		break
-	case reflect.Map:
-		// maps must be sent so we know their lengths and key/value types.
-		break
-	case reflect.Struct:
-		// structs must be sent so we know their fields.
-		break
-	case reflect.Chan, reflect.Func:
-		// If we get here, it's a field of a struct; ignore it.
-		return
-	}
-
-	return enc.sendActualType(w, state, ut, ut.base)
-}
-
-// Encode transmits the data item represented by the empty interface value,
-// guaranteeing that all necessary type information has been transmitted first.
-func (enc *Encoder) Encode(e interface{}) error {
-	return enc.EncodeValue(reflect.ValueOf(e))
-}
-
-// sendTypeDescriptor makes sure the remote side knows about this type.
-// It will send a descriptor if this is the first time the type has been
-// sent.
-func (enc *Encoder) sendTypeDescriptor(w io.Writer, state *encoderState, ut *userTypeInfo) {
-	// Make sure the type is known to the other side.
-	// First, have we already sent this type?
-	rt := ut.base
-	if ut.externalEnc != 0 {
-		rt = ut.user
-	}
-	if _, alreadySent := enc.sent[rt]; !alreadySent {
-		// No, so send it.
-		sent := enc.sendType(w, state, rt)
-		if enc.err != nil {
-			return
-		}
-		// If the type info has still not been transmitted, it means we have
-		// a singleton basic type (int, []byte etc.) at top level.  We don't
-		// need to send the type info but we do need to update enc.sent.
-		if !sent {
-			typeLock.Lock()
-			info, err := getTypeInfo(ut)
-			typeLock.Unlock()
-			if err != nil {
-				enc.setError(err)
-				return
-			}
-			enc.sent[rt] = info.id
-		}
-	}
-}
-
-// sendTypeId sends the id, which must have already been defined.
-func (enc *Encoder) sendTypeId(state *encoderState, ut *userTypeInfo) {
-	// Identify the type of this top-level value.
-	state.encodeInt(int64(enc.sent[ut.base]))
-}
-
-// EncodeValue transmits the data item represented by the reflection value,
-// guaranteeing that all necessary type information has been transmitted first.
-func (enc *Encoder) EncodeValue(value reflect.Value) error {
-	// Gobs contain values. They cannot represent nil pointers, which
-	// have no value to encode.
-	if value.Kind() == reflect.Ptr && value.IsNil() {
-		panic("gob: cannot encode nil pointer of type " + value.Type().String())
-	}
-
-	// Make sure we're single-threaded through here, so multiple
-	// goroutines can share an encoder.
-	enc.mutex.Lock()
-	defer enc.mutex.Unlock()
-
-	// Remove any nested writers remaining due to previous errors.
-	enc.w = enc.w[0:1]
-
-	ut, err := validUserType(value.Type())
-	if err != nil {
-		return err
-	}
-
-	enc.err = nil
-	enc.byteBuf.Reset()
-	enc.byteBuf.Write(spaceForLength)
-	state := enc.newEncoderState(&enc.byteBuf)
-
-	enc.sendTypeDescriptor(enc.writer(), state, ut)
-	enc.sendTypeId(state, ut)
-	if enc.err != nil {
-		return enc.err
-	}
-
-	// Encode the object.
-	enc.encode(state.b, value, ut)
-	if enc.err == nil {
-		enc.writeMessage(enc.writer(), state.b)
-	}
-
-	enc.freeEncoderState(state)
-	return enc.err
-}
diff --git a/src/pkg/encoding/gob/encoder_test.go b/src/pkg/encoding/gob/encoder_test.go
deleted file mode 100644
index 6445ce1..0000000
--- a/src/pkg/encoding/gob/encoder_test.go
+++ /dev/null
@@ -1,862 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package gob
-
-import (
-	"bytes"
-	"fmt"
-	"io"
-	"reflect"
-	"strings"
-	"testing"
-)
-
-type ET2 struct {
-	X string
-}
-
-type ET1 struct {
-	A    int
-	Et2  *ET2
-	Next *ET1
-}
-
-// Like ET1 but with a different name for a field
-type ET3 struct {
-	A             int
-	Et2           *ET2
-	DifferentNext *ET1
-}
-
-// Like ET1 but with a different type for a field
-type ET4 struct {
-	A    int
-	Et2  float64
-	Next int
-}
-
-func TestEncoderDecoder(t *testing.T) {
-	b := new(bytes.Buffer)
-	enc := NewEncoder(b)
-	et1 := new(ET1)
-	et1.A = 7
-	et1.Et2 = new(ET2)
-	err := enc.Encode(et1)
-	if err != nil {
-		t.Error("encoder fail:", err)
-	}
-	dec := NewDecoder(b)
-	newEt1 := new(ET1)
-	err = dec.Decode(newEt1)
-	if err != nil {
-		t.Fatal("error decoding ET1:", err)
-	}
-
-	if !reflect.DeepEqual(et1, newEt1) {
-		t.Fatalf("invalid data for et1: expected %+v; got %+v", *et1, *newEt1)
-	}
-	if b.Len() != 0 {
-		t.Error("not at eof;", b.Len(), "bytes left")
-	}
-
-	enc.Encode(et1)
-	newEt1 = new(ET1)
-	err = dec.Decode(newEt1)
-	if err != nil {
-		t.Fatal("round 2: error decoding ET1:", err)
-	}
-	if !reflect.DeepEqual(et1, newEt1) {
-		t.Fatalf("round 2: invalid data for et1: expected %+v; got %+v", *et1, *newEt1)
-	}
-	if b.Len() != 0 {
-		t.Error("round 2: not at eof;", b.Len(), "bytes left")
-	}
-
-	// Now test with a running encoder/decoder pair that we recognize a type mismatch.
-	err = enc.Encode(et1)
-	if err != nil {
-		t.Error("round 3: encoder fail:", err)
-	}
-	newEt2 := new(ET2)
-	err = dec.Decode(newEt2)
-	if err == nil {
-		t.Fatal("round 3: expected `bad type' error decoding ET2")
-	}
-}
-
-// Run one value through the encoder/decoder, but use the wrong type.
-// Input is always an ET1; we compare it to whatever is under 'e'.
-func badTypeCheck(e interface{}, shouldFail bool, msg string, t *testing.T) {
-	b := new(bytes.Buffer)
-	enc := NewEncoder(b)
-	et1 := new(ET1)
-	et1.A = 7
-	et1.Et2 = new(ET2)
-	err := enc.Encode(et1)
-	if err != nil {
-		t.Error("encoder fail:", err)
-	}
-	dec := NewDecoder(b)
-	err = dec.Decode(e)
-	if shouldFail && err == nil {
-		t.Error("expected error for", msg)
-	}
-	if !shouldFail && err != nil {
-		t.Error("unexpected error for", msg, err)
-	}
-}
-
-// Test that we recognize a bad type the first time.
-func TestWrongTypeDecoder(t *testing.T) {
-	badTypeCheck(new(ET2), true, "no fields in common", t)
-	badTypeCheck(new(ET3), false, "different name of field", t)
-	badTypeCheck(new(ET4), true, "different type of field", t)
-}
-
-func corruptDataCheck(s string, err error, t *testing.T) {
-	b := bytes.NewBufferString(s)
-	dec := NewDecoder(b)
-	err1 := dec.Decode(new(ET2))
-	if err1 != err {
-		t.Errorf("from %q expected error %s; got %s", s, err, err1)
-	}
-}
-
-// Check that we survive bad data.
-func TestBadData(t *testing.T) {
-	corruptDataCheck("", io.EOF, t)
-	corruptDataCheck("\x7Fhi", io.ErrUnexpectedEOF, t)
-	corruptDataCheck("\x03now is the time for all good men", errBadType, t)
-	// issue 6323.
-	corruptDataCheck("\x04\x24foo", errRange, t)
-}
-
-// Types not supported at top level by the Encoder.
-var unsupportedValues = []interface{}{
-	make(chan int),
-	func(a int) bool { return true },
-}
-
-func TestUnsupported(t *testing.T) {
-	var b bytes.Buffer
-	enc := NewEncoder(&b)
-	for _, v := range unsupportedValues {
-		err := enc.Encode(v)
-		if err == nil {
-			t.Errorf("expected error for %T; got none", v)
-		}
-	}
-}
-
-func encAndDec(in, out interface{}) error {
-	b := new(bytes.Buffer)
-	enc := NewEncoder(b)
-	err := enc.Encode(in)
-	if err != nil {
-		return err
-	}
-	dec := NewDecoder(b)
-	err = dec.Decode(out)
-	if err != nil {
-		return err
-	}
-	return nil
-}
-
-func TestTypeToPtrType(t *testing.T) {
-	// Encode a T, decode a *T
-	type Type0 struct {
-		A int
-	}
-	t0 := Type0{7}
-	t0p := new(Type0)
-	if err := encAndDec(t0, t0p); err != nil {
-		t.Error(err)
-	}
-}
-
-func TestPtrTypeToType(t *testing.T) {
-	// Encode a *T, decode a T
-	type Type1 struct {
-		A uint
-	}
-	t1p := &Type1{17}
-	var t1 Type1
-	if err := encAndDec(t1, t1p); err != nil {
-		t.Error(err)
-	}
-}
-
-func TestTypeToPtrPtrPtrPtrType(t *testing.T) {
-	type Type2 struct {
-		A ****float64
-	}
-	t2 := Type2{}
-	t2.A = new(***float64)
-	*t2.A = new(**float64)
-	**t2.A = new(*float64)
-	***t2.A = new(float64)
-	****t2.A = 27.4
-	t2pppp := new(***Type2)
-	if err := encAndDec(t2, t2pppp); err != nil {
-		t.Fatal(err)
-	}
-	if ****(****t2pppp).A != ****t2.A {
-		t.Errorf("wrong value after decode: %g not %g", ****(****t2pppp).A, ****t2.A)
-	}
-}
-
-func TestSlice(t *testing.T) {
-	type Type3 struct {
-		A []string
-	}
-	t3p := &Type3{[]string{"hello", "world"}}
-	var t3 Type3
-	if err := encAndDec(t3, t3p); err != nil {
-		t.Error(err)
-	}
-}
-
-func TestValueError(t *testing.T) {
-	// Encode a *T, decode a T
-	type Type4 struct {
-		A int
-	}
-	t4p := &Type4{3}
-	var t4 Type4 // note: not a pointer.
-	if err := encAndDec(t4p, t4); err == nil || strings.Index(err.Error(), "pointer") < 0 {
-		t.Error("expected error about pointer; got", err)
-	}
-}
-
-func TestArray(t *testing.T) {
-	type Type5 struct {
-		A [3]string
-		B [3]byte
-	}
-	type Type6 struct {
-		A [2]string // can't hold t5.a
-	}
-	t5 := Type5{[3]string{"hello", ",", "world"}, [3]byte{1, 2, 3}}
-	var t5p Type5
-	if err := encAndDec(t5, &t5p); err != nil {
-		t.Error(err)
-	}
-	var t6 Type6
-	if err := encAndDec(t5, &t6); err == nil {
-		t.Error("should fail with mismatched array sizes")
-	}
-}
-
-func TestRecursiveMapType(t *testing.T) {
-	type recursiveMap map[string]recursiveMap
-	r1 := recursiveMap{"A": recursiveMap{"B": nil, "C": nil}, "D": nil}
-	r2 := make(recursiveMap)
-	if err := encAndDec(r1, &r2); err != nil {
-		t.Error(err)
-	}
-}
-
-func TestRecursiveSliceType(t *testing.T) {
-	type recursiveSlice []recursiveSlice
-	r1 := recursiveSlice{0: recursiveSlice{0: nil}, 1: nil}
-	r2 := make(recursiveSlice, 0)
-	if err := encAndDec(r1, &r2); err != nil {
-		t.Error(err)
-	}
-}
-
-// Regression test for bug: must send zero values inside arrays
-func TestDefaultsInArray(t *testing.T) {
-	type Type7 struct {
-		B []bool
-		I []int
-		S []string
-		F []float64
-	}
-	t7 := Type7{
-		[]bool{false, false, true},
-		[]int{0, 0, 1},
-		[]string{"hi", "", "there"},
-		[]float64{0, 0, 1},
-	}
-	var t7p Type7
-	if err := encAndDec(t7, &t7p); err != nil {
-		t.Error(err)
-	}
-}
-
-var testInt int
-var testFloat32 float32
-var testString string
-var testSlice []string
-var testMap map[string]int
-var testArray [7]int
-
-type SingleTest struct {
-	in  interface{}
-	out interface{}
-	err string
-}
-
-var singleTests = []SingleTest{
-	{17, &testInt, ""},
-	{float32(17.5), &testFloat32, ""},
-	{"bike shed", &testString, ""},
-	{[]string{"bike", "shed", "paint", "color"}, &testSlice, ""},
-	{map[string]int{"seven": 7, "twelve": 12}, &testMap, ""},
-	{[7]int{4, 55, 0, 0, 0, 0, 0}, &testArray, ""}, // case that once triggered a bug
-	{[7]int{4, 55, 1, 44, 22, 66, 1234}, &testArray, ""},
-
-	// Decode errors
-	{172, &testFloat32, "type"},
-}
-
-func TestSingletons(t *testing.T) {
-	b := new(bytes.Buffer)
-	enc := NewEncoder(b)
-	dec := NewDecoder(b)
-	for _, test := range singleTests {
-		b.Reset()
-		err := enc.Encode(test.in)
-		if err != nil {
-			t.Errorf("error encoding %v: %s", test.in, err)
-			continue
-		}
-		err = dec.Decode(test.out)
-		switch {
-		case err != nil && test.err == "":
-			t.Errorf("error decoding %v: %s", test.in, err)
-			continue
-		case err == nil && test.err != "":
-			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 {
-				t.Errorf("wrong error decoding %v: wanted %s, got %v", test.in, test.err, err)
-			}
-			continue
-		}
-		// Get rid of the pointer in the rhs
-		val := reflect.ValueOf(test.out).Elem().Interface()
-		if !reflect.DeepEqual(test.in, val) {
-			t.Errorf("decoding singleton: expected %v got %v", test.in, val)
-		}
-	}
-}
-
-func TestStructNonStruct(t *testing.T) {
-	type Struct struct {
-		A string
-	}
-	type NonStruct string
-	s := Struct{"hello"}
-	var sp Struct
-	if err := encAndDec(s, &sp); err != nil {
-		t.Error(err)
-	}
-	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 {
-		t.Error("for struct/non-struct expected type error; got", err)
-	}
-	// Now try the other way
-	var nsp NonStruct
-	if err := encAndDec(ns, &nsp); err != nil {
-		t.Error(err)
-	}
-	if err := encAndDec(ns, &s); err == nil {
-		t.Error("should get error for non-struct/struct")
-	} else if strings.Index(err.Error(), "type") < 0 {
-		t.Error("for non-struct/struct expected type error; got", err)
-	}
-}
-
-type interfaceIndirectTestI interface {
-	F() bool
-}
-
-type interfaceIndirectTestT struct{}
-
-func (this *interfaceIndirectTestT) F() bool {
-	return true
-}
-
-// A version of a bug reported on golang-nuts.  Also tests top-level
-// slice of interfaces.  The issue was registering *T caused T to be
-// stored as the concrete type.
-func TestInterfaceIndirect(t *testing.T) {
-	Register(&interfaceIndirectTestT{})
-	b := new(bytes.Buffer)
-	w := []interfaceIndirectTestI{&interfaceIndirectTestT{}}
-	err := NewEncoder(b).Encode(w)
-	if err != nil {
-		t.Fatal("encode error:", err)
-	}
-
-	var r []interfaceIndirectTestI
-	err = NewDecoder(b).Decode(&r)
-	if err != nil {
-		t.Fatal("decode error:", err)
-	}
-}
-
-// Now follow various tests that decode into things that can't represent the
-// encoded value, all of which should be legal.
-
-// Also, when the ignored object contains an interface value, it may define
-// types. Make sure that skipping the value still defines the types by using
-// the encoder/decoder pair to send a value afterwards.  If an interface
-// is sent, its type in the test is always NewType0, so this checks that the
-// encoder and decoder don't skew with respect to type definitions.
-
-type Struct0 struct {
-	I interface{}
-}
-
-type NewType0 struct {
-	S string
-}
-
-type ignoreTest struct {
-	in, out interface{}
-}
-
-var ignoreTests = []ignoreTest{
-	// Decode normal struct into an empty struct
-	{&struct{ A int }{23}, &struct{}{}},
-	// Decode normal struct into a nil.
-	{&struct{ A int }{23}, nil},
-	// Decode singleton string into a nil.
-	{"hello, world", nil},
-	// Decode singleton slice into a nil.
-	{[]int{1, 2, 3, 4}, nil},
-	// Decode struct containing an interface into a nil.
-	{&Struct0{&NewType0{"value0"}}, nil},
-	// Decode singleton slice of interfaces into a nil.
-	{[]interface{}{"hi", &NewType0{"value1"}, 23}, nil},
-}
-
-func TestDecodeIntoNothing(t *testing.T) {
-	Register(new(NewType0))
-	for i, test := range ignoreTests {
-		b := new(bytes.Buffer)
-		enc := NewEncoder(b)
-		err := enc.Encode(test.in)
-		if err != nil {
-			t.Errorf("%d: encode error %s:", i, err)
-			continue
-		}
-		dec := NewDecoder(b)
-		err = dec.Decode(test.out)
-		if err != nil {
-			t.Errorf("%d: decode error: %s", i, err)
-			continue
-		}
-		// Now see if the encoder and decoder are in a consistent state.
-		str := fmt.Sprintf("Value %d", i)
-		err = enc.Encode(&NewType0{str})
-		if err != nil {
-			t.Fatalf("%d: NewType0 encode error: %s", i, err)
-		}
-		ns := new(NewType0)
-		err = dec.Decode(ns)
-		if err != nil {
-			t.Fatalf("%d: NewType0 decode error: %s", i, err)
-		}
-		if ns.S != str {
-			t.Fatalf("%d: expected %q got %q", i, str, ns.S)
-		}
-	}
-}
-
-// Another bug from golang-nuts, involving nested interfaces.
-type Bug0Outer struct {
-	Bug0Field interface{}
-}
-
-type Bug0Inner struct {
-	A int
-}
-
-func TestNestedInterfaces(t *testing.T) {
-	var buf bytes.Buffer
-	e := NewEncoder(&buf)
-	d := NewDecoder(&buf)
-	Register(new(Bug0Outer))
-	Register(new(Bug0Inner))
-	f := &Bug0Outer{&Bug0Outer{&Bug0Inner{7}}}
-	var v interface{} = f
-	err := e.Encode(&v)
-	if err != nil {
-		t.Fatal("Encode:", err)
-	}
-	err = d.Decode(&v)
-	if err != nil {
-		t.Fatal("Decode:", err)
-	}
-	// Make sure it decoded correctly.
-	outer1, ok := v.(*Bug0Outer)
-	if !ok {
-		t.Fatalf("v not Bug0Outer: %T", v)
-	}
-	outer2, ok := outer1.Bug0Field.(*Bug0Outer)
-	if !ok {
-		t.Fatalf("v.Bug0Field not Bug0Outer: %T", outer1.Bug0Field)
-	}
-	inner, ok := outer2.Bug0Field.(*Bug0Inner)
-	if !ok {
-		t.Fatalf("v.Bug0Field.Bug0Field not Bug0Inner: %T", outer2.Bug0Field)
-	}
-	if inner.A != 7 {
-		t.Fatalf("final value %d; expected %d", inner.A, 7)
-	}
-}
-
-// The bugs keep coming. We forgot to send map subtypes before the map.
-
-type Bug1Elem struct {
-	Name string
-	Id   int
-}
-
-type Bug1StructMap map[string]Bug1Elem
-
-func bug1EncDec(in Bug1StructMap, out *Bug1StructMap) error {
-	return nil
-}
-
-func TestMapBug1(t *testing.T) {
-	in := make(Bug1StructMap)
-	in["val1"] = Bug1Elem{"elem1", 1}
-	in["val2"] = Bug1Elem{"elem2", 2}
-
-	b := new(bytes.Buffer)
-	enc := NewEncoder(b)
-	err := enc.Encode(in)
-	if err != nil {
-		t.Fatal("encode:", err)
-	}
-	dec := NewDecoder(b)
-	out := make(Bug1StructMap)
-	err = dec.Decode(&out)
-	if err != nil {
-		t.Fatal("decode:", err)
-	}
-	if !reflect.DeepEqual(in, out) {
-		t.Errorf("mismatch: %v %v", in, out)
-	}
-}
-
-func TestGobMapInterfaceEncode(t *testing.T) {
-	m := map[string]interface{}{
-		"up": uintptr(0),
-		"i0": []int{-1},
-		"i1": []int8{-1},
-		"i2": []int16{-1},
-		"i3": []int32{-1},
-		"i4": []int64{-1},
-		"u0": []uint{1},
-		"u1": []uint8{1},
-		"u2": []uint16{1},
-		"u3": []uint32{1},
-		"u4": []uint64{1},
-		"f0": []float32{1},
-		"f1": []float64{1},
-		"c0": []complex64{complex(2, -2)},
-		"c1": []complex128{complex(2, float64(-2))},
-		"us": []uintptr{0},
-		"bo": []bool{false},
-		"st": []string{"s"},
-	}
-	enc := NewEncoder(new(bytes.Buffer))
-	err := enc.Encode(m)
-	if err != nil {
-		t.Errorf("encode map: %s", err)
-	}
-}
-
-func TestSliceReusesMemory(t *testing.T) {
-	buf := new(bytes.Buffer)
-	// Bytes
-	{
-		x := []byte("abcd")
-		enc := NewEncoder(buf)
-		err := enc.Encode(x)
-		if err != nil {
-			t.Errorf("bytes: encode: %s", err)
-		}
-		// Decode into y, which is big enough.
-		y := []byte("ABCDE")
-		addr := &y[0]
-		dec := NewDecoder(buf)
-		err = dec.Decode(&y)
-		if err != nil {
-			t.Fatal("bytes: decode:", err)
-		}
-		if !bytes.Equal(x, y) {
-			t.Errorf("bytes: expected %q got %q\n", x, y)
-		}
-		if addr != &y[0] {
-			t.Errorf("bytes: unnecessary reallocation")
-		}
-	}
-	// general slice
-	{
-		x := []rune("abcd")
-		enc := NewEncoder(buf)
-		err := enc.Encode(x)
-		if err != nil {
-			t.Errorf("ints: encode: %s", err)
-		}
-		// Decode into y, which is big enough.
-		y := []rune("ABCDE")
-		addr := &y[0]
-		dec := NewDecoder(buf)
-		err = dec.Decode(&y)
-		if err != nil {
-			t.Fatal("ints: decode:", err)
-		}
-		if !reflect.DeepEqual(x, y) {
-			t.Errorf("ints: expected %q got %q\n", x, y)
-		}
-		if addr != &y[0] {
-			t.Errorf("ints: unnecessary reallocation")
-		}
-	}
-}
-
-// Used to crash: negative count in recvMessage.
-func TestBadCount(t *testing.T) {
-	b := []byte{0xfb, 0xa5, 0x82, 0x2f, 0xca, 0x1}
-	if err := NewDecoder(bytes.NewReader(b)).Decode(nil); err == nil {
-		t.Error("expected error from bad count")
-	} else if err.Error() != errBadCount.Error() {
-		t.Error("expected bad count error; got", err)
-	}
-}
-
-// Verify that sequential Decoders built on a single input will
-// succeed if the input implements ReadByte and there is no
-// type information in the stream.
-func TestSequentialDecoder(t *testing.T) {
-	b := new(bytes.Buffer)
-	enc := NewEncoder(b)
-	const count = 10
-	for i := 0; i < count; i++ {
-		s := fmt.Sprintf("%d", i)
-		if err := enc.Encode(s); err != nil {
-			t.Error("encoder fail:", err)
-		}
-	}
-	for i := 0; i < count; i++ {
-		dec := NewDecoder(b)
-		var s string
-		if err := dec.Decode(&s); err != nil {
-			t.Fatal("decoder fail:", err)
-		}
-		if s != fmt.Sprintf("%d", i) {
-			t.Fatalf("decode expected %d got %s", i, s)
-		}
-	}
-}
-
-// Should be able to have unrepresentable fields (chan, func, *chan etc.); we just ignore them.
-type Bug2 struct {
-	A   int
-	C   chan int
-	CP  *chan int
-	F   func()
-	FPP **func()
-}
-
-func TestChanFuncIgnored(t *testing.T) {
-	c := make(chan int)
-	f := func() {}
-	fp := &f
-	b0 := Bug2{23, c, &c, f, &fp}
-	var buf bytes.Buffer
-	enc := NewEncoder(&buf)
-	if err := enc.Encode(b0); err != nil {
-		t.Fatal("error encoding:", err)
-	}
-	var b1 Bug2
-	err := NewDecoder(&buf).Decode(&b1)
-	if err != nil {
-		t.Fatal("decode:", err)
-	}
-	if b1.A != b0.A {
-		t.Fatalf("got %d want %d", b1.A, b0.A)
-	}
-	if b1.C != nil || b1.CP != nil || b1.F != nil || b1.FPP != nil {
-		t.Fatal("unexpected value for chan or func")
-	}
-}
-
-func TestSliceIncompatibility(t *testing.T) {
-	var in = []byte{1, 2, 3}
-	var out []int
-	if err := encAndDec(in, &out); err == nil {
-		t.Error("expected compatibility error")
-	}
-}
-
-// Mutually recursive slices of structs caused problems.
-type Bug3 struct {
-	Num      int
-	Children []*Bug3
-}
-
-func TestGobPtrSlices(t *testing.T) {
-	in := []*Bug3{
-		{1, nil},
-		{2, nil},
-	}
-	b := new(bytes.Buffer)
-	err := NewEncoder(b).Encode(&in)
-	if err != nil {
-		t.Fatal("encode:", err)
-	}
-
-	var out []*Bug3
-	err = NewDecoder(b).Decode(&out)
-	if err != nil {
-		t.Fatal("decode:", err)
-	}
-	if !reflect.DeepEqual(in, out) {
-		t.Fatalf("got %v; wanted %v", out, in)
-	}
-}
-
-// getDecEnginePtr cached engine for ut.base instead of ut.user so we passed
-// a *map and then tried to reuse its engine to decode the inner map.
-func TestPtrToMapOfMap(t *testing.T) {
-	Register(make(map[string]interface{}))
-	subdata := make(map[string]interface{})
-	subdata["bar"] = "baz"
-	data := make(map[string]interface{})
-	data["foo"] = subdata
-
-	b := new(bytes.Buffer)
-	err := NewEncoder(b).Encode(data)
-	if err != nil {
-		t.Fatal("encode:", err)
-	}
-	var newData map[string]interface{}
-	err = NewDecoder(b).Decode(&newData)
-	if err != nil {
-		t.Fatal("decode:", err)
-	}
-	if !reflect.DeepEqual(data, newData) {
-		t.Fatalf("expected %v got %v", data, newData)
-	}
-}
-
-// A top-level nil pointer generates a panic with a helpful string-valued message.
-func TestTopLevelNilPointer(t *testing.T) {
-	errMsg := topLevelNilPanic(t)
-	if errMsg == "" {
-		t.Fatal("top-level nil pointer did not panic")
-	}
-	if !strings.Contains(errMsg, "nil pointer") {
-		t.Fatal("expected nil pointer error, got:", errMsg)
-	}
-}
-
-func topLevelNilPanic(t *testing.T) (panicErr string) {
-	defer func() {
-		e := recover()
-		if err, ok := e.(string); ok {
-			panicErr = err
-		}
-	}()
-	var ip *int
-	buf := new(bytes.Buffer)
-	if err := NewEncoder(buf).Encode(ip); err != nil {
-		t.Fatal("error in encode:", err)
-	}
-	return
-}
-
-func TestNilPointerInsideInterface(t *testing.T) {
-	var ip *int
-	si := struct {
-		I interface{}
-	}{
-		I: ip,
-	}
-	buf := new(bytes.Buffer)
-	err := NewEncoder(buf).Encode(si)
-	if err == nil {
-		t.Fatal("expected error, got none")
-	}
-	errMsg := err.Error()
-	if !strings.Contains(errMsg, "nil pointer") || !strings.Contains(errMsg, "interface") {
-		t.Fatal("expected error about nil pointer and interface, got:", errMsg)
-	}
-}
-
-type Bug4Public struct {
-	Name   string
-	Secret Bug4Secret
-}
-
-type Bug4Secret struct {
-	a int // error: no exported fields.
-}
-
-// Test that a failed compilation doesn't leave around an executable encoder.
-// Issue 3273.
-func TestMutipleEncodingsOfBadType(t *testing.T) {
-	x := Bug4Public{
-		Name:   "name",
-		Secret: Bug4Secret{1},
-	}
-	buf := new(bytes.Buffer)
-	enc := NewEncoder(buf)
-	err := enc.Encode(x)
-	if err == nil {
-		t.Fatal("first encoding: expected error")
-	}
-	buf.Reset()
-	enc = NewEncoder(buf)
-	err = enc.Encode(x)
-	if err == nil {
-		t.Fatal("second encoding: expected error")
-	}
-	if !strings.Contains(err.Error(), "no exported fields") {
-		t.Errorf("expected error about no exported fields; got %v", err)
-	}
-}
-
-// There was an error check comparing the length of the input with the
-// length of the slice being decoded. It was wrong because the next
-// thing in the input might be a type definition, which would lead to
-// an incorrect length check.  This test reproduces the corner case.
-
-type Z struct {
-}
-
-func Test29ElementSlice(t *testing.T) {
-	Register(Z{})
-	src := make([]interface{}, 100) // Size needs to be bigger than size of type definition.
-	for i := range src {
-		src[i] = Z{}
-	}
-	buf := new(bytes.Buffer)
-	err := NewEncoder(buf).Encode(src)
-	if err != nil {
-		t.Fatalf("encode: %v", err)
-		return
-	}
-
-	var dst []interface{}
-	err = NewDecoder(buf).Decode(&dst)
-	if err != nil {
-		t.Errorf("decode: %v", err)
-		return
-	}
-}
diff --git a/src/pkg/encoding/gob/gobencdec_test.go b/src/pkg/encoding/gob/gobencdec_test.go
deleted file mode 100644
index 157b772..0000000
--- a/src/pkg/encoding/gob/gobencdec_test.go
+++ /dev/null
@@ -1,797 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// This file contains tests of the GobEncoder/GobDecoder support.
-
-package gob
-
-import (
-	"bytes"
-	"errors"
-	"fmt"
-	"io"
-	"net"
-	"strings"
-	"testing"
-	"time"
-)
-
-// Types that implement the GobEncoder/Decoder interfaces.
-
-type ByteStruct struct {
-	a byte // not an exported field
-}
-
-type StringStruct struct {
-	s string // not an exported field
-}
-
-type ArrayStruct struct {
-	a [8192]byte // not an exported field
-}
-
-type Gobber int
-
-type ValueGobber string // encodes with a value, decodes with a pointer.
-
-type BinaryGobber int
-
-type BinaryValueGobber string
-
-type TextGobber int
-
-type TextValueGobber string
-
-// The relevant methods
-
-func (g *ByteStruct) GobEncode() ([]byte, error) {
-	b := make([]byte, 3)
-	b[0] = g.a
-	b[1] = g.a + 1
-	b[2] = g.a + 2
-	return b, nil
-}
-
-func (g *ByteStruct) GobDecode(data []byte) error {
-	if g == nil {
-		return errors.New("NIL RECEIVER")
-	}
-	// Expect N sequential-valued bytes.
-	if len(data) == 0 {
-		return io.EOF
-	}
-	g.a = data[0]
-	for i, c := range data {
-		if c != g.a+byte(i) {
-			return errors.New("invalid data sequence")
-		}
-	}
-	return nil
-}
-
-func (g *StringStruct) GobEncode() ([]byte, error) {
-	return []byte(g.s), nil
-}
-
-func (g *StringStruct) GobDecode(data []byte) error {
-	// Expect N sequential-valued bytes.
-	if len(data) == 0 {
-		return io.EOF
-	}
-	a := data[0]
-	for i, c := range data {
-		if c != a+byte(i) {
-			return errors.New("invalid data sequence")
-		}
-	}
-	g.s = string(data)
-	return nil
-}
-
-func (a *ArrayStruct) GobEncode() ([]byte, error) {
-	return a.a[:], nil
-}
-
-func (a *ArrayStruct) GobDecode(data []byte) error {
-	if len(data) != len(a.a) {
-		return errors.New("wrong length in array decode")
-	}
-	copy(a.a[:], data)
-	return nil
-}
-
-func (g *Gobber) GobEncode() ([]byte, error) {
-	return []byte(fmt.Sprintf("VALUE=%d", *g)), nil
-}
-
-func (g *Gobber) GobDecode(data []byte) error {
-	_, err := fmt.Sscanf(string(data), "VALUE=%d", (*int)(g))
-	return err
-}
-
-func (g *BinaryGobber) MarshalBinary() ([]byte, error) {
-	return []byte(fmt.Sprintf("VALUE=%d", *g)), nil
-}
-
-func (g *BinaryGobber) UnmarshalBinary(data []byte) error {
-	_, err := fmt.Sscanf(string(data), "VALUE=%d", (*int)(g))
-	return err
-}
-
-func (g *TextGobber) MarshalText() ([]byte, error) {
-	return []byte(fmt.Sprintf("VALUE=%d", *g)), nil
-}
-
-func (g *TextGobber) UnmarshalText(data []byte) error {
-	_, err := fmt.Sscanf(string(data), "VALUE=%d", (*int)(g))
-	return err
-}
-
-func (v ValueGobber) GobEncode() ([]byte, error) {
-	return []byte(fmt.Sprintf("VALUE=%s", v)), nil
-}
-
-func (v *ValueGobber) GobDecode(data []byte) error {
-	_, err := fmt.Sscanf(string(data), "VALUE=%s", (*string)(v))
-	return err
-}
-
-func (v BinaryValueGobber) MarshalBinary() ([]byte, error) {
-	return []byte(fmt.Sprintf("VALUE=%s", v)), nil
-}
-
-func (v *BinaryValueGobber) UnmarshalBinary(data []byte) error {
-	_, err := fmt.Sscanf(string(data), "VALUE=%s", (*string)(v))
-	return err
-}
-
-func (v TextValueGobber) MarshalText() ([]byte, error) {
-	return []byte(fmt.Sprintf("VALUE=%s", v)), nil
-}
-
-func (v *TextValueGobber) UnmarshalText(data []byte) error {
-	_, err := fmt.Sscanf(string(data), "VALUE=%s", (*string)(v))
-	return err
-}
-
-// Structs that include GobEncodable fields.
-
-type GobTest0 struct {
-	X int // guarantee we have  something in common with GobTest*
-	G *ByteStruct
-}
-
-type GobTest1 struct {
-	X int // guarantee we have  something in common with GobTest*
-	G *StringStruct
-}
-
-type GobTest2 struct {
-	X int    // guarantee we have  something in common with GobTest*
-	G string // not a GobEncoder - should give us errors
-}
-
-type GobTest3 struct {
-	X int // guarantee we have  something in common with GobTest*
-	G *Gobber
-	B *BinaryGobber
-	T *TextGobber
-}
-
-type GobTest4 struct {
-	X  int // guarantee we have  something in common with GobTest*
-	V  ValueGobber
-	BV BinaryValueGobber
-	TV TextValueGobber
-}
-
-type GobTest5 struct {
-	X  int // guarantee we have  something in common with GobTest*
-	V  *ValueGobber
-	BV *BinaryValueGobber
-	TV *TextValueGobber
-}
-
-type GobTest6 struct {
-	X  int // guarantee we have  something in common with GobTest*
-	V  ValueGobber
-	W  *ValueGobber
-	BV BinaryValueGobber
-	BW *BinaryValueGobber
-	TV TextValueGobber
-	TW *TextValueGobber
-}
-
-type GobTest7 struct {
-	X  int // guarantee we have  something in common with GobTest*
-	V  *ValueGobber
-	W  ValueGobber
-	BV *BinaryValueGobber
-	BW BinaryValueGobber
-	TV *TextValueGobber
-	TW TextValueGobber
-}
-
-type GobTestIgnoreEncoder struct {
-	X int // guarantee we have  something in common with GobTest*
-}
-
-type GobTestValueEncDec struct {
-	X int          // guarantee we have  something in common with GobTest*
-	G StringStruct // not a pointer.
-}
-
-type GobTestIndirectEncDec struct {
-	X int             // guarantee we have  something in common with GobTest*
-	G ***StringStruct // indirections to the receiver.
-}
-
-type GobTestArrayEncDec struct {
-	X int         // guarantee we have  something in common with GobTest*
-	A ArrayStruct // not a pointer.
-}
-
-type GobTestIndirectArrayEncDec struct {
-	X int            // guarantee we have  something in common with GobTest*
-	A ***ArrayStruct // indirections to a large receiver.
-}
-
-func TestGobEncoderField(t *testing.T) {
-	b := new(bytes.Buffer)
-	// First a field that's a structure.
-	enc := NewEncoder(b)
-	err := enc.Encode(GobTest0{17, &ByteStruct{'A'}})
-	if err != nil {
-		t.Fatal("encode error:", err)
-	}
-	dec := NewDecoder(b)
-	x := new(GobTest0)
-	err = dec.Decode(x)
-	if err != nil {
-		t.Fatal("decode error:", err)
-	}
-	if x.G.a != 'A' {
-		t.Errorf("expected 'A' got %c", x.G.a)
-	}
-	// Now a field that's not a structure.
-	b.Reset()
-	gobber := Gobber(23)
-	bgobber := BinaryGobber(24)
-	tgobber := TextGobber(25)
-	err = enc.Encode(GobTest3{17, &gobber, &bgobber, &tgobber})
-	if err != nil {
-		t.Fatal("encode error:", err)
-	}
-	y := new(GobTest3)
-	err = dec.Decode(y)
-	if err != nil {
-		t.Fatal("decode error:", err)
-	}
-	if *y.G != 23 || *y.B != 24 || *y.T != 25 {
-		t.Errorf("expected '23 got %d", *y.G)
-	}
-}
-
-// Even though the field is a value, we can still take its address
-// and should be able to call the methods.
-func TestGobEncoderValueField(t *testing.T) {
-	b := new(bytes.Buffer)
-	// First a field that's a structure.
-	enc := NewEncoder(b)
-	err := enc.Encode(GobTestValueEncDec{17, StringStruct{"HIJKL"}})
-	if err != nil {
-		t.Fatal("encode error:", err)
-	}
-	dec := NewDecoder(b)
-	x := new(GobTestValueEncDec)
-	err = dec.Decode(x)
-	if err != nil {
-		t.Fatal("decode error:", err)
-	}
-	if x.G.s != "HIJKL" {
-		t.Errorf("expected `HIJKL` got %s", x.G.s)
-	}
-}
-
-// GobEncode/Decode should work even if the value is
-// more indirect than the receiver.
-func TestGobEncoderIndirectField(t *testing.T) {
-	b := new(bytes.Buffer)
-	// First a field that's a structure.
-	enc := NewEncoder(b)
-	s := &StringStruct{"HIJKL"}
-	sp := &s
-	err := enc.Encode(GobTestIndirectEncDec{17, &sp})
-	if err != nil {
-		t.Fatal("encode error:", err)
-	}
-	dec := NewDecoder(b)
-	x := new(GobTestIndirectEncDec)
-	err = dec.Decode(x)
-	if err != nil {
-		t.Fatal("decode error:", err)
-	}
-	if (***x.G).s != "HIJKL" {
-		t.Errorf("expected `HIJKL` got %s", (***x.G).s)
-	}
-}
-
-// Test with a large field with methods.
-func TestGobEncoderArrayField(t *testing.T) {
-	b := new(bytes.Buffer)
-	enc := NewEncoder(b)
-	var a GobTestArrayEncDec
-	a.X = 17
-	for i := range a.A.a {
-		a.A.a[i] = byte(i)
-	}
-	err := enc.Encode(a)
-	if err != nil {
-		t.Fatal("encode error:", err)
-	}
-	dec := NewDecoder(b)
-	x := new(GobTestArrayEncDec)
-	err = dec.Decode(x)
-	if err != nil {
-		t.Fatal("decode error:", err)
-	}
-	for i, v := range x.A.a {
-		if v != byte(i) {
-			t.Errorf("expected %x got %x", byte(i), v)
-			break
-		}
-	}
-}
-
-// Test an indirection to a large field with methods.
-func TestGobEncoderIndirectArrayField(t *testing.T) {
-	b := new(bytes.Buffer)
-	enc := NewEncoder(b)
-	var a GobTestIndirectArrayEncDec
-	a.X = 17
-	var array ArrayStruct
-	ap := &array
-	app := &ap
-	a.A = &app
-	for i := range array.a {
-		array.a[i] = byte(i)
-	}
-	err := enc.Encode(a)
-	if err != nil {
-		t.Fatal("encode error:", err)
-	}
-	dec := NewDecoder(b)
-	x := new(GobTestIndirectArrayEncDec)
-	err = dec.Decode(x)
-	if err != nil {
-		t.Fatal("decode error:", err)
-	}
-	for i, v := range (***x.A).a {
-		if v != byte(i) {
-			t.Errorf("expected %x got %x", byte(i), v)
-			break
-		}
-	}
-}
-
-// As long as the fields have the same name and implement the
-// interface, we can cross-connect them.  Not sure it's useful
-// and may even be bad but it works and it's hard to prevent
-// without exposing the contents of the object, which would
-// defeat the purpose.
-func TestGobEncoderFieldsOfDifferentType(t *testing.T) {
-	// first, string in field to byte in field
-	b := new(bytes.Buffer)
-	enc := NewEncoder(b)
-	err := enc.Encode(GobTest1{17, &StringStruct{"ABC"}})
-	if err != nil {
-		t.Fatal("encode error:", err)
-	}
-	dec := NewDecoder(b)
-	x := new(GobTest0)
-	err = dec.Decode(x)
-	if err != nil {
-		t.Fatal("decode error:", err)
-	}
-	if x.G.a != 'A' {
-		t.Errorf("expected 'A' got %c", x.G.a)
-	}
-	// now the other direction, byte in field to string in field
-	b.Reset()
-	err = enc.Encode(GobTest0{17, &ByteStruct{'X'}})
-	if err != nil {
-		t.Fatal("encode error:", err)
-	}
-	y := new(GobTest1)
-	err = dec.Decode(y)
-	if err != nil {
-		t.Fatal("decode error:", err)
-	}
-	if y.G.s != "XYZ" {
-		t.Fatalf("expected `XYZ` got %q", y.G.s)
-	}
-}
-
-// Test that we can encode a value and decode into a pointer.
-func TestGobEncoderValueEncoder(t *testing.T) {
-	// first, string in field to byte in field
-	b := new(bytes.Buffer)
-	enc := NewEncoder(b)
-	err := enc.Encode(GobTest4{17, ValueGobber("hello"), BinaryValueGobber("Καλημέρα"), TextValueGobber("こんにちは")})
-	if err != nil {
-		t.Fatal("encode error:", err)
-	}
-	dec := NewDecoder(b)
-	x := new(GobTest5)
-	err = dec.Decode(x)
-	if err != nil {
-		t.Fatal("decode error:", err)
-	}
-	if *x.V != "hello" || *x.BV != "Καλημέρα" || *x.TV != "こんにちは" {
-		t.Errorf("expected `hello` got %s", *x.V)
-	}
-}
-
-// Test that we can use a value then a pointer type of a GobEncoder
-// in the same encoded value.  Bug 4647.
-func TestGobEncoderValueThenPointer(t *testing.T) {
-	v := ValueGobber("forty-two")
-	w := ValueGobber("six-by-nine")
-	bv := BinaryValueGobber("1nanocentury")
-	bw := BinaryValueGobber("πseconds")
-	tv := TextValueGobber("gravitationalacceleration")
-	tw := TextValueGobber("π²ft/s²")
-
-	// this was a bug: encoding a GobEncoder by value before a GobEncoder
-	// pointer would cause duplicate type definitions to be sent.
-
-	b := new(bytes.Buffer)
-	enc := NewEncoder(b)
-	if err := enc.Encode(GobTest6{42, v, &w, bv, &bw, tv, &tw}); err != nil {
-		t.Fatal("encode error:", err)
-	}
-	dec := NewDecoder(b)
-	x := new(GobTest6)
-	if err := dec.Decode(x); err != nil {
-		t.Fatal("decode error:", err)
-	}
-
-	if got, want := x.V, v; got != want {
-		t.Errorf("v = %q, want %q", got, want)
-	}
-	if got, want := x.W, w; got == nil {
-		t.Errorf("w = nil, want %q", want)
-	} else if *got != want {
-		t.Errorf("w = %q, want %q", *got, want)
-	}
-
-	if got, want := x.BV, bv; got != want {
-		t.Errorf("bv = %q, want %q", got, want)
-	}
-	if got, want := x.BW, bw; got == nil {
-		t.Errorf("bw = nil, want %q", want)
-	} else if *got != want {
-		t.Errorf("bw = %q, want %q", *got, want)
-	}
-
-	if got, want := x.TV, tv; got != want {
-		t.Errorf("tv = %q, want %q", got, want)
-	}
-	if got, want := x.TW, tw; got == nil {
-		t.Errorf("tw = nil, want %q", want)
-	} else if *got != want {
-		t.Errorf("tw = %q, want %q", *got, want)
-	}
-}
-
-// Test that we can use a pointer then a value type of a GobEncoder
-// in the same encoded value.
-func TestGobEncoderPointerThenValue(t *testing.T) {
-	v := ValueGobber("forty-two")
-	w := ValueGobber("six-by-nine")
-	bv := BinaryValueGobber("1nanocentury")
-	bw := BinaryValueGobber("πseconds")
-	tv := TextValueGobber("gravitationalacceleration")
-	tw := TextValueGobber("π²ft/s²")
-
-	b := new(bytes.Buffer)
-	enc := NewEncoder(b)
-	if err := enc.Encode(GobTest7{42, &v, w, &bv, bw, &tv, tw}); err != nil {
-		t.Fatal("encode error:", err)
-	}
-	dec := NewDecoder(b)
-	x := new(GobTest7)
-	if err := dec.Decode(x); err != nil {
-		t.Fatal("decode error:", err)
-	}
-
-	if got, want := x.V, v; got == nil {
-		t.Errorf("v = nil, want %q", want)
-	} else if *got != want {
-		t.Errorf("v = %q, want %q", *got, want)
-	}
-	if got, want := x.W, w; got != want {
-		t.Errorf("w = %q, want %q", got, want)
-	}
-
-	if got, want := x.BV, bv; got == nil {
-		t.Errorf("bv = nil, want %q", want)
-	} else if *got != want {
-		t.Errorf("bv = %q, want %q", *got, want)
-	}
-	if got, want := x.BW, bw; got != want {
-		t.Errorf("bw = %q, want %q", got, want)
-	}
-
-	if got, want := x.TV, tv; got == nil {
-		t.Errorf("tv = nil, want %q", want)
-	} else if *got != want {
-		t.Errorf("tv = %q, want %q", *got, want)
-	}
-	if got, want := x.TW, tw; got != want {
-		t.Errorf("tw = %q, want %q", got, want)
-	}
-}
-
-func TestGobEncoderFieldTypeError(t *testing.T) {
-	// GobEncoder to non-decoder: error
-	b := new(bytes.Buffer)
-	enc := NewEncoder(b)
-	err := enc.Encode(GobTest1{17, &StringStruct{"ABC"}})
-	if err != nil {
-		t.Fatal("encode error:", err)
-	}
-	dec := NewDecoder(b)
-	x := &GobTest2{}
-	err = dec.Decode(x)
-	if err == nil {
-		t.Fatal("expected decode error for mismatched fields (encoder to non-decoder)")
-	}
-	if strings.Index(err.Error(), "type") < 0 {
-		t.Fatal("expected type error; got", err)
-	}
-	// Non-encoder to GobDecoder: error
-	b.Reset()
-	err = enc.Encode(GobTest2{17, "ABC"})
-	if err != nil {
-		t.Fatal("encode error:", err)
-	}
-	y := &GobTest1{}
-	err = dec.Decode(y)
-	if err == nil {
-		t.Fatal("expected decode error for mismatched fields (non-encoder to decoder)")
-	}
-	if strings.Index(err.Error(), "type") < 0 {
-		t.Fatal("expected type error; got", err)
-	}
-}
-
-// Even though ByteStruct is a struct, it's treated as a singleton at the top level.
-func TestGobEncoderStructSingleton(t *testing.T) {
-	b := new(bytes.Buffer)
-	enc := NewEncoder(b)
-	err := enc.Encode(&ByteStruct{'A'})
-	if err != nil {
-		t.Fatal("encode error:", err)
-	}
-	dec := NewDecoder(b)
-	x := new(ByteStruct)
-	err = dec.Decode(x)
-	if err != nil {
-		t.Fatal("decode error:", err)
-	}
-	if x.a != 'A' {
-		t.Errorf("expected 'A' got %c", x.a)
-	}
-}
-
-func TestGobEncoderNonStructSingleton(t *testing.T) {
-	b := new(bytes.Buffer)
-	enc := NewEncoder(b)
-	err := enc.Encode(Gobber(1234))
-	if err != nil {
-		t.Fatal("encode error:", err)
-	}
-	dec := NewDecoder(b)
-	var x Gobber
-	err = dec.Decode(&x)
-	if err != nil {
-		t.Fatal("decode error:", err)
-	}
-	if x != 1234 {
-		t.Errorf("expected 1234 got %d", x)
-	}
-}
-
-func TestGobEncoderIgnoreStructField(t *testing.T) {
-	b := new(bytes.Buffer)
-	// First a field that's a structure.
-	enc := NewEncoder(b)
-	err := enc.Encode(GobTest0{17, &ByteStruct{'A'}})
-	if err != nil {
-		t.Fatal("encode error:", err)
-	}
-	dec := NewDecoder(b)
-	x := new(GobTestIgnoreEncoder)
-	err = dec.Decode(x)
-	if err != nil {
-		t.Fatal("decode error:", err)
-	}
-	if x.X != 17 {
-		t.Errorf("expected 17 got %c", x.X)
-	}
-}
-
-func TestGobEncoderIgnoreNonStructField(t *testing.T) {
-	b := new(bytes.Buffer)
-	// First a field that's a structure.
-	enc := NewEncoder(b)
-	gobber := Gobber(23)
-	bgobber := BinaryGobber(24)
-	tgobber := TextGobber(25)
-	err := enc.Encode(GobTest3{17, &gobber, &bgobber, &tgobber})
-	if err != nil {
-		t.Fatal("encode error:", err)
-	}
-	dec := NewDecoder(b)
-	x := new(GobTestIgnoreEncoder)
-	err = dec.Decode(x)
-	if err != nil {
-		t.Fatal("decode error:", err)
-	}
-	if x.X != 17 {
-		t.Errorf("expected 17 got %c", x.X)
-	}
-}
-
-func TestGobEncoderIgnoreNilEncoder(t *testing.T) {
-	b := new(bytes.Buffer)
-	// First a field that's a structure.
-	enc := NewEncoder(b)
-	err := enc.Encode(GobTest0{X: 18}) // G is nil
-	if err != nil {
-		t.Fatal("encode error:", err)
-	}
-	dec := NewDecoder(b)
-	x := new(GobTest0)
-	err = dec.Decode(x)
-	if err != nil {
-		t.Fatal("decode error:", err)
-	}
-	if x.X != 18 {
-		t.Errorf("expected x.X = 18, got %v", x.X)
-	}
-	if x.G != nil {
-		t.Errorf("expected x.G = nil, got %v", x.G)
-	}
-}
-
-type gobDecoderBug0 struct {
-	foo, bar string
-}
-
-func (br *gobDecoderBug0) String() string {
-	return br.foo + "-" + br.bar
-}
-
-func (br *gobDecoderBug0) GobEncode() ([]byte, error) {
-	return []byte(br.String()), nil
-}
-
-func (br *gobDecoderBug0) GobDecode(b []byte) error {
-	br.foo = "foo"
-	br.bar = "bar"
-	return nil
-}
-
-// This was a bug: the receiver has a different indirection level
-// than the variable.
-func TestGobEncoderExtraIndirect(t *testing.T) {
-	gdb := &gobDecoderBug0{"foo", "bar"}
-	buf := new(bytes.Buffer)
-	e := NewEncoder(buf)
-	if err := e.Encode(gdb); err != nil {
-		t.Fatalf("encode: %v", err)
-	}
-	d := NewDecoder(buf)
-	var got *gobDecoderBug0
-	if err := d.Decode(&got); err != nil {
-		t.Fatalf("decode: %v", err)
-	}
-	if got.foo != gdb.foo || got.bar != gdb.bar {
-		t.Errorf("got = %q, want %q", got, gdb)
-	}
-}
-
-// Another bug: this caused a crash with the new Go1 Time type.
-// We throw in a gob-encoding array, to test another case of isZero,
-// and a struct containing an nil interface, to test a third.
-type isZeroBug struct {
-	T time.Time
-	S string
-	I int
-	A isZeroBugArray
-	F isZeroBugInterface
-}
-
-type isZeroBugArray [2]uint8
-
-// Receiver is value, not pointer, to test isZero of array.
-func (a isZeroBugArray) GobEncode() (b []byte, e error) {
-	b = append(b, a[:]...)
-	return b, nil
-}
-
-func (a *isZeroBugArray) GobDecode(data []byte) error {
-	if len(data) != len(a) {
-		return io.EOF
-	}
-	a[0] = data[0]
-	a[1] = data[1]
-	return nil
-}
-
-type isZeroBugInterface struct {
-	I interface{}
-}
-
-func (i isZeroBugInterface) GobEncode() (b []byte, e error) {
-	return []byte{}, nil
-}
-
-func (i *isZeroBugInterface) GobDecode(data []byte) error {
-	return nil
-}
-
-func TestGobEncodeIsZero(t *testing.T) {
-	x := isZeroBug{time.Now(), "hello", -55, isZeroBugArray{1, 2}, isZeroBugInterface{}}
-	b := new(bytes.Buffer)
-	enc := NewEncoder(b)
-	err := enc.Encode(x)
-	if err != nil {
-		t.Fatal("encode:", err)
-	}
-	var y isZeroBug
-	dec := NewDecoder(b)
-	err = dec.Decode(&y)
-	if err != nil {
-		t.Fatal("decode:", err)
-	}
-	if x != y {
-		t.Fatalf("%v != %v", x, y)
-	}
-}
-
-func TestGobEncodePtrError(t *testing.T) {
-	var err error
-	b := new(bytes.Buffer)
-	enc := NewEncoder(b)
-	err = enc.Encode(&err)
-	if err != nil {
-		t.Fatal("encode:", err)
-	}
-	dec := NewDecoder(b)
-	err2 := fmt.Errorf("foo")
-	err = dec.Decode(&err2)
-	if err != nil {
-		t.Fatal("decode:", err)
-	}
-	if err2 != nil {
-		t.Fatalf("expected nil, got %v", err2)
-	}
-}
-
-func TestNetIP(t *testing.T) {
-	// Encoding of net.IP{1,2,3,4} in Go 1.1.
-	enc := []byte{0x07, 0x0a, 0x00, 0x04, 0x01, 0x02, 0x03, 0x04}
-
-	var ip net.IP
-	err := NewDecoder(bytes.NewReader(enc)).Decode(&ip)
-	if err != nil {
-		t.Fatalf("decode: %v", err)
-	}
-	if ip.String() != "1.2.3.4" {
-		t.Errorf("decoded to %v, want 1.2.3.4", ip.String())
-	}
-}
diff --git a/src/pkg/encoding/gob/timing_test.go b/src/pkg/encoding/gob/timing_test.go
deleted file mode 100644
index 9fbb0ac..0000000
--- a/src/pkg/encoding/gob/timing_test.go
+++ /dev/null
@@ -1,109 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package gob
-
-import (
-	"bytes"
-	"io"
-	"os"
-	"runtime"
-	"testing"
-)
-
-type Bench struct {
-	A int
-	B float64
-	C string
-	D []byte
-}
-
-func benchmarkEndToEnd(r io.Reader, w io.Writer, b *testing.B) {
-	b.StopTimer()
-	enc := NewEncoder(w)
-	dec := NewDecoder(r)
-	bench := &Bench{7, 3.2, "now is the time", []byte("for all good men")}
-	b.StartTimer()
-	for i := 0; i < b.N; i++ {
-		if enc.Encode(bench) != nil {
-			panic("encode error")
-		}
-		if dec.Decode(bench) != nil {
-			panic("decode error")
-		}
-	}
-}
-
-func BenchmarkEndToEndPipe(b *testing.B) {
-	r, w, err := os.Pipe()
-	if err != nil {
-		b.Fatal("can't get pipe:", err)
-	}
-	benchmarkEndToEnd(r, w, b)
-}
-
-func BenchmarkEndToEndByteBuffer(b *testing.B) {
-	var buf bytes.Buffer
-	benchmarkEndToEnd(&buf, &buf, b)
-}
-
-func TestCountEncodeMallocs(t *testing.T) {
-	if testing.Short() {
-		t.Skip("skipping malloc count in short mode")
-	}
-	if runtime.GOMAXPROCS(0) > 1 {
-		t.Skip("skipping; GOMAXPROCS>1")
-	}
-
-	const N = 1000
-
-	var buf bytes.Buffer
-	enc := NewEncoder(&buf)
-	bench := &Bench{7, 3.2, "now is the time", []byte("for all good men")}
-
-	allocs := testing.AllocsPerRun(N, func() {
-		err := enc.Encode(bench)
-		if err != nil {
-			t.Fatal("encode:", err)
-		}
-	})
-	if allocs != 0 {
-		t.Fatalf("mallocs per encode of type Bench: %v; wanted 0\n", allocs)
-	}
-}
-
-func TestCountDecodeMallocs(t *testing.T) {
-	if testing.Short() {
-		t.Skip("skipping malloc count in short mode")
-	}
-	if runtime.GOMAXPROCS(0) > 1 {
-		t.Skip("skipping; GOMAXPROCS>1")
-	}
-
-	const N = 1000
-
-	var buf bytes.Buffer
-	enc := NewEncoder(&buf)
-	bench := &Bench{7, 3.2, "now is the time", []byte("for all good men")}
-
-	// Fill the buffer with enough to decode
-	testing.AllocsPerRun(N, func() {
-		err := enc.Encode(bench)
-		if err != nil {
-			t.Fatal("encode:", err)
-		}
-	})
-
-	dec := NewDecoder(&buf)
-	allocs := testing.AllocsPerRun(N, func() {
-		*bench = Bench{}
-		err := dec.Decode(&bench)
-		if err != nil {
-			t.Fatal("decode:", err)
-		}
-	})
-	if allocs != 3 {
-		t.Fatalf("mallocs per decode of type Bench: %v; wanted 3\n", allocs)
-	}
-}
diff --git a/src/pkg/encoding/gob/type.go b/src/pkg/encoding/gob/type.go
deleted file mode 100644
index cad1452..0000000
--- a/src/pkg/encoding/gob/type.go
+++ /dev/null
@@ -1,893 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package gob
-
-import (
-	"encoding"
-	"errors"
-	"fmt"
-	"os"
-	"reflect"
-	"sync"
-	"unicode"
-	"unicode/utf8"
-)
-
-// userTypeInfo stores the information associated with a type the user has handed
-// to the package.  It's computed once and stored in a map keyed by reflection
-// type.
-type userTypeInfo struct {
-	user        reflect.Type // the type the user handed us
-	base        reflect.Type // the base type after all indirections
-	indir       int          // number of indirections to reach the base type
-	externalEnc int          // xGob, xBinary, or xText
-	externalDec int          // xGob, xBinary or xText
-	encIndir    int8         // number of indirections to reach the receiver type; may be negative
-	decIndir    int8         // number of indirections to reach the receiver type; may be negative
-}
-
-// externalEncoding bits
-const (
-	xGob    = 1 + iota // GobEncoder or GobDecoder
-	xBinary            // encoding.BinaryMarshaler or encoding.BinaryUnmarshaler
-	xText              // encoding.TextMarshaler or encoding.TextUnmarshaler
-)
-
-var (
-	// Protected by an RWMutex because we read it a lot and write
-	// it only when we see a new type, typically when compiling.
-	userTypeLock  sync.RWMutex
-	userTypeCache = make(map[reflect.Type]*userTypeInfo)
-)
-
-// validType returns, and saves, the information associated with user-provided type rt.
-// If the user type is not valid, err will be non-nil.  To be used when the error handler
-// is not set up.
-func validUserType(rt reflect.Type) (ut *userTypeInfo, err error) {
-	userTypeLock.RLock()
-	ut = userTypeCache[rt]
-	userTypeLock.RUnlock()
-	if ut != nil {
-		return
-	}
-	// Now set the value under the write lock.
-	userTypeLock.Lock()
-	defer userTypeLock.Unlock()
-	if ut = userTypeCache[rt]; ut != nil {
-		// Lost the race; not a problem.
-		return
-	}
-	ut = new(userTypeInfo)
-	ut.base = rt
-	ut.user = rt
-	// A type that is just a cycle of pointers (such as type T *T) cannot
-	// be represented in gobs, which need some concrete data.  We use a
-	// cycle detection algorithm from Knuth, Vol 2, Section 3.1, Ex 6,
-	// pp 539-540.  As we step through indirections, run another type at
-	// half speed. If they meet up, there's a cycle.
-	slowpoke := ut.base // walks half as fast as ut.base
-	for {
-		pt := ut.base
-		if pt.Kind() != reflect.Ptr {
-			break
-		}
-		ut.base = pt.Elem()
-		if ut.base == slowpoke { // ut.base lapped slowpoke
-			// recursive pointer type.
-			return nil, errors.New("can't represent recursive pointer type " + ut.base.String())
-		}
-		if ut.indir%2 == 0 {
-			slowpoke = slowpoke.Elem()
-		}
-		ut.indir++
-	}
-
-	if ok, indir := implementsInterface(ut.user, gobEncoderInterfaceType); ok {
-		ut.externalEnc, ut.encIndir = xGob, indir
-	} else if ok, indir := implementsInterface(ut.user, binaryMarshalerInterfaceType); ok {
-		ut.externalEnc, ut.encIndir = xBinary, indir
-	}
-
-	// NOTE(rsc): Would like to allow MarshalText here, but results in incompatibility
-	// with older encodings for net.IP. See golang.org/issue/6760.
-	// } else if ok, indir := implementsInterface(ut.user, textMarshalerInterfaceType); ok {
-	// 	ut.externalEnc, ut.encIndir = xText, indir
-	// }
-
-	if ok, indir := implementsInterface(ut.user, gobDecoderInterfaceType); ok {
-		ut.externalDec, ut.decIndir = xGob, indir
-	} else if ok, indir := implementsInterface(ut.user, binaryUnmarshalerInterfaceType); ok {
-		ut.externalDec, ut.decIndir = xBinary, indir
-	}
-
-	// See note above.
-	// } else if ok, indir := implementsInterface(ut.user, textUnmarshalerInterfaceType); ok {
-	// 	ut.externalDec, ut.decIndir = xText, indir
-	// }
-
-	userTypeCache[rt] = ut
-	return
-}
-
-var (
-	gobEncoderInterfaceType        = reflect.TypeOf((*GobEncoder)(nil)).Elem()
-	gobDecoderInterfaceType        = reflect.TypeOf((*GobDecoder)(nil)).Elem()
-	binaryMarshalerInterfaceType   = reflect.TypeOf((*encoding.BinaryMarshaler)(nil)).Elem()
-	binaryUnmarshalerInterfaceType = reflect.TypeOf((*encoding.BinaryUnmarshaler)(nil)).Elem()
-	textMarshalerInterfaceType     = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem()
-	textUnmarshalerInterfaceType   = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem()
-)
-
-// implementsInterface reports whether the type implements the
-// gobEncoder/gobDecoder interface.
-// It also returns the number of indirections required to get to the
-// implementation.
-func implementsInterface(typ, gobEncDecType reflect.Type) (success bool, indir int8) {
-	if typ == nil {
-		return
-	}
-	rt := typ
-	// The type might be a pointer and we need to keep
-	// dereferencing to the base type until we find an implementation.
-	for {
-		if rt.Implements(gobEncDecType) {
-			return true, indir
-		}
-		if p := rt; p.Kind() == reflect.Ptr {
-			indir++
-			if indir > 100 { // insane number of indirections
-				return false, 0
-			}
-			rt = p.Elem()
-			continue
-		}
-		break
-	}
-	// No luck yet, but if this is a base type (non-pointer), the pointer might satisfy.
-	if typ.Kind() != reflect.Ptr {
-		// Not a pointer, but does the pointer work?
-		if reflect.PtrTo(typ).Implements(gobEncDecType) {
-			return true, -1
-		}
-	}
-	return false, 0
-}
-
-// userType returns, and saves, the information associated with user-provided type rt.
-// If the user type is not valid, it calls error.
-func userType(rt reflect.Type) *userTypeInfo {
-	ut, err := validUserType(rt)
-	if err != nil {
-		error_(err)
-	}
-	return ut
-}
-
-// A typeId represents a gob Type as an integer that can be passed on the wire.
-// Internally, typeIds are used as keys to a map to recover the underlying type info.
-type typeId int32
-
-var nextId typeId       // incremented for each new type we build
-var typeLock sync.Mutex // set while building a type
-const firstUserId = 64  // lowest id number granted to user
-
-type gobType interface {
-	id() typeId
-	setId(id typeId)
-	name() string
-	string() string // not public; only for debugging
-	safeString(seen map[typeId]bool) string
-}
-
-var types = make(map[reflect.Type]gobType)
-var idToType = make(map[typeId]gobType)
-var builtinIdToType map[typeId]gobType // set in init() after builtins are established
-
-func setTypeId(typ gobType) {
-	// When building recursive types, someone may get there before us.
-	if typ.id() != 0 {
-		return
-	}
-	nextId++
-	typ.setId(nextId)
-	idToType[nextId] = typ
-}
-
-func (t typeId) gobType() gobType {
-	if t == 0 {
-		return nil
-	}
-	return idToType[t]
-}
-
-// string returns the string representation of the type associated with the typeId.
-func (t typeId) string() string {
-	if t.gobType() == nil {
-		return "<nil>"
-	}
-	return t.gobType().string()
-}
-
-// Name returns the name of the type associated with the typeId.
-func (t typeId) name() string {
-	if t.gobType() == nil {
-		return "<nil>"
-	}
-	return t.gobType().name()
-}
-
-// CommonType holds elements of all types.
-// It is a historical artifact, kept for binary compatibility and exported
-// only for the benefit of the package's encoding of type descriptors. It is
-// not intended for direct use by clients.
-type CommonType struct {
-	Name string
-	Id   typeId
-}
-
-func (t *CommonType) id() typeId { return t.Id }
-
-func (t *CommonType) setId(id typeId) { t.Id = id }
-
-func (t *CommonType) string() string { return t.Name }
-
-func (t *CommonType) safeString(seen map[typeId]bool) string {
-	return t.Name
-}
-
-func (t *CommonType) name() string { return t.Name }
-
-// Create and check predefined types
-// The string for tBytes is "bytes" not "[]byte" to signify its specialness.
-
-var (
-	// Primordial types, needed during initialization.
-	// Always passed as pointers so the interface{} type
-	// goes through without losing its interfaceness.
-	tBool      = bootstrapType("bool", (*bool)(nil), 1)
-	tInt       = bootstrapType("int", (*int)(nil), 2)
-	tUint      = bootstrapType("uint", (*uint)(nil), 3)
-	tFloat     = bootstrapType("float", (*float64)(nil), 4)
-	tBytes     = bootstrapType("bytes", (*[]byte)(nil), 5)
-	tString    = bootstrapType("string", (*string)(nil), 6)
-	tComplex   = bootstrapType("complex", (*complex128)(nil), 7)
-	tInterface = bootstrapType("interface", (*interface{})(nil), 8)
-	// Reserve some Ids for compatible expansion
-	tReserved7 = bootstrapType("_reserved1", (*struct{ r7 int })(nil), 9)
-	tReserved6 = bootstrapType("_reserved1", (*struct{ r6 int })(nil), 10)
-	tReserved5 = bootstrapType("_reserved1", (*struct{ r5 int })(nil), 11)
-	tReserved4 = bootstrapType("_reserved1", (*struct{ r4 int })(nil), 12)
-	tReserved3 = bootstrapType("_reserved1", (*struct{ r3 int })(nil), 13)
-	tReserved2 = bootstrapType("_reserved1", (*struct{ r2 int })(nil), 14)
-	tReserved1 = bootstrapType("_reserved1", (*struct{ r1 int })(nil), 15)
-)
-
-// Predefined because it's needed by the Decoder
-var tWireType = mustGetTypeInfo(reflect.TypeOf(wireType{})).id
-var wireTypeUserInfo *userTypeInfo // userTypeInfo of (*wireType)
-
-func init() {
-	// Some magic numbers to make sure there are no surprises.
-	checkId(16, tWireType)
-	checkId(17, mustGetTypeInfo(reflect.TypeOf(arrayType{})).id)
-	checkId(18, mustGetTypeInfo(reflect.TypeOf(CommonType{})).id)
-	checkId(19, mustGetTypeInfo(reflect.TypeOf(sliceType{})).id)
-	checkId(20, mustGetTypeInfo(reflect.TypeOf(structType{})).id)
-	checkId(21, mustGetTypeInfo(reflect.TypeOf(fieldType{})).id)
-	checkId(23, mustGetTypeInfo(reflect.TypeOf(mapType{})).id)
-
-	builtinIdToType = make(map[typeId]gobType)
-	for k, v := range idToType {
-		builtinIdToType[k] = v
-	}
-
-	// Move the id space upwards to allow for growth in the predefined world
-	// without breaking existing files.
-	if nextId > firstUserId {
-		panic(fmt.Sprintln("nextId too large:", nextId))
-	}
-	nextId = firstUserId
-	registerBasics()
-	wireTypeUserInfo = userType(reflect.TypeOf((*wireType)(nil)))
-}
-
-// Array type
-type arrayType struct {
-	CommonType
-	Elem typeId
-	Len  int
-}
-
-func newArrayType(name string) *arrayType {
-	a := &arrayType{CommonType{Name: name}, 0, 0}
-	return a
-}
-
-func (a *arrayType) init(elem gobType, len int) {
-	// Set our type id before evaluating the element's, in case it's our own.
-	setTypeId(a)
-	a.Elem = elem.id()
-	a.Len = len
-}
-
-func (a *arrayType) safeString(seen map[typeId]bool) string {
-	if seen[a.Id] {
-		return a.Name
-	}
-	seen[a.Id] = true
-	return fmt.Sprintf("[%d]%s", a.Len, a.Elem.gobType().safeString(seen))
-}
-
-func (a *arrayType) string() string { return a.safeString(make(map[typeId]bool)) }
-
-// GobEncoder type (something that implements the GobEncoder interface)
-type gobEncoderType struct {
-	CommonType
-}
-
-func newGobEncoderType(name string) *gobEncoderType {
-	g := &gobEncoderType{CommonType{Name: name}}
-	setTypeId(g)
-	return g
-}
-
-func (g *gobEncoderType) safeString(seen map[typeId]bool) string {
-	return g.Name
-}
-
-func (g *gobEncoderType) string() string { return g.Name }
-
-// Map type
-type mapType struct {
-	CommonType
-	Key  typeId
-	Elem typeId
-}
-
-func newMapType(name string) *mapType {
-	m := &mapType{CommonType{Name: name}, 0, 0}
-	return m
-}
-
-func (m *mapType) init(key, elem gobType) {
-	// Set our type id before evaluating the element's, in case it's our own.
-	setTypeId(m)
-	m.Key = key.id()
-	m.Elem = elem.id()
-}
-
-func (m *mapType) safeString(seen map[typeId]bool) string {
-	if seen[m.Id] {
-		return m.Name
-	}
-	seen[m.Id] = true
-	key := m.Key.gobType().safeString(seen)
-	elem := m.Elem.gobType().safeString(seen)
-	return fmt.Sprintf("map[%s]%s", key, elem)
-}
-
-func (m *mapType) string() string { return m.safeString(make(map[typeId]bool)) }
-
-// Slice type
-type sliceType struct {
-	CommonType
-	Elem typeId
-}
-
-func newSliceType(name string) *sliceType {
-	s := &sliceType{CommonType{Name: name}, 0}
-	return s
-}
-
-func (s *sliceType) init(elem gobType) {
-	// Set our type id before evaluating the element's, in case it's our own.
-	setTypeId(s)
-	// See the comments about ids in newTypeObject. Only slices and
-	// structs have mutual recursion.
-	if elem.id() == 0 {
-		setTypeId(elem)
-	}
-	s.Elem = elem.id()
-}
-
-func (s *sliceType) safeString(seen map[typeId]bool) string {
-	if seen[s.Id] {
-		return s.Name
-	}
-	seen[s.Id] = true
-	return fmt.Sprintf("[]%s", s.Elem.gobType().safeString(seen))
-}
-
-func (s *sliceType) string() string { return s.safeString(make(map[typeId]bool)) }
-
-// Struct type
-type fieldType struct {
-	Name string
-	Id   typeId
-}
-
-type structType struct {
-	CommonType
-	Field []*fieldType
-}
-
-func (s *structType) safeString(seen map[typeId]bool) string {
-	if s == nil {
-		return "<nil>"
-	}
-	if _, ok := seen[s.Id]; ok {
-		return s.Name
-	}
-	seen[s.Id] = true
-	str := s.Name + " = struct { "
-	for _, f := range s.Field {
-		str += fmt.Sprintf("%s %s; ", f.Name, f.Id.gobType().safeString(seen))
-	}
-	str += "}"
-	return str
-}
-
-func (s *structType) string() string { return s.safeString(make(map[typeId]bool)) }
-
-func newStructType(name string) *structType {
-	s := &structType{CommonType{Name: name}, nil}
-	// For historical reasons we set the id here rather than init.
-	// See the comment in newTypeObject for details.
-	setTypeId(s)
-	return s
-}
-
-// newTypeObject allocates a gobType for the reflection type rt.
-// Unless ut represents a GobEncoder, rt should be the base type
-// of ut.
-// This is only called from the encoding side. The decoding side
-// works through typeIds and userTypeInfos alone.
-func newTypeObject(name string, ut *userTypeInfo, rt reflect.Type) (gobType, error) {
-	// Does this type implement GobEncoder?
-	if ut.externalEnc != 0 {
-		return newGobEncoderType(name), nil
-	}
-	var err error
-	var type0, type1 gobType
-	defer func() {
-		if err != nil {
-			delete(types, rt)
-		}
-	}()
-	// Install the top-level type before the subtypes (e.g. struct before
-	// fields) so recursive types can be constructed safely.
-	switch t := rt; t.Kind() {
-	// All basic types are easy: they are predefined.
-	case reflect.Bool:
-		return tBool.gobType(), nil
-
-	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-		return tInt.gobType(), nil
-
-	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
-		return tUint.gobType(), nil
-
-	case reflect.Float32, reflect.Float64:
-		return tFloat.gobType(), nil
-
-	case reflect.Complex64, reflect.Complex128:
-		return tComplex.gobType(), nil
-
-	case reflect.String:
-		return tString.gobType(), nil
-
-	case reflect.Interface:
-		return tInterface.gobType(), nil
-
-	case reflect.Array:
-		at := newArrayType(name)
-		types[rt] = at
-		type0, err = getBaseType("", t.Elem())
-		if err != nil {
-			return nil, err
-		}
-		// Historical aside:
-		// For arrays, maps, and slices, we set the type id after the elements
-		// are constructed. This is to retain the order of type id allocation after
-		// a fix made to handle recursive types, which changed the order in
-		// which types are built.  Delaying the setting in this way preserves
-		// type ids while allowing recursive types to be described. Structs,
-		// done below, were already handling recursion correctly so they
-		// assign the top-level id before those of the field.
-		at.init(type0, t.Len())
-		return at, nil
-
-	case reflect.Map:
-		mt := newMapType(name)
-		types[rt] = mt
-		type0, err = getBaseType("", t.Key())
-		if err != nil {
-			return nil, err
-		}
-		type1, err = getBaseType("", t.Elem())
-		if err != nil {
-			return nil, err
-		}
-		mt.init(type0, type1)
-		return mt, nil
-
-	case reflect.Slice:
-		// []byte == []uint8 is a special case
-		if t.Elem().Kind() == reflect.Uint8 {
-			return tBytes.gobType(), nil
-		}
-		st := newSliceType(name)
-		types[rt] = st
-		type0, err = getBaseType(t.Elem().Name(), t.Elem())
-		if err != nil {
-			return nil, err
-		}
-		st.init(type0)
-		return st, nil
-
-	case reflect.Struct:
-		st := newStructType(name)
-		types[rt] = st
-		idToType[st.id()] = st
-		for i := 0; i < t.NumField(); i++ {
-			f := t.Field(i)
-			if !isSent(&f) {
-				continue
-			}
-			typ := userType(f.Type).base
-			tname := typ.Name()
-			if tname == "" {
-				t := userType(f.Type).base
-				tname = t.String()
-			}
-			gt, err := getBaseType(tname, f.Type)
-			if err != nil {
-				return nil, err
-			}
-			// Some mutually recursive types can cause us to be here while
-			// still defining the element. Fix the element type id here.
-			// We could do this more neatly by setting the id at the start of
-			// building every type, but that would break binary compatibility.
-			if gt.id() == 0 {
-				setTypeId(gt)
-			}
-			st.Field = append(st.Field, &fieldType{f.Name, gt.id()})
-		}
-		return st, nil
-
-	default:
-		return nil, errors.New("gob NewTypeObject can't handle type: " + rt.String())
-	}
-}
-
-// isExported reports whether this is an exported - upper case - name.
-func isExported(name string) bool {
-	rune, _ := utf8.DecodeRuneInString(name)
-	return unicode.IsUpper(rune)
-}
-
-// isSent reports whether this struct field is to be transmitted.
-// It will be transmitted only if it is exported and not a chan or func field
-// or pointer to chan or func.
-func isSent(field *reflect.StructField) bool {
-	if !isExported(field.Name) {
-		return false
-	}
-	// If the field is a chan or func or pointer thereto, don't send it.
-	// That is, treat it like an unexported field.
-	typ := field.Type
-	for typ.Kind() == reflect.Ptr {
-		typ = typ.Elem()
-	}
-	if typ.Kind() == reflect.Chan || typ.Kind() == reflect.Func {
-		return false
-	}
-	return true
-}
-
-// getBaseType returns the Gob type describing the given reflect.Type's base type.
-// typeLock must be held.
-func getBaseType(name string, rt reflect.Type) (gobType, error) {
-	ut := userType(rt)
-	return getType(name, ut, ut.base)
-}
-
-// getType returns the Gob type describing the given reflect.Type.
-// Should be called only when handling GobEncoders/Decoders,
-// which may be pointers.  All other types are handled through the
-// base type, never a pointer.
-// typeLock must be held.
-func getType(name string, ut *userTypeInfo, rt reflect.Type) (gobType, error) {
-	typ, present := types[rt]
-	if present {
-		return typ, nil
-	}
-	typ, err := newTypeObject(name, ut, rt)
-	if err == nil {
-		types[rt] = typ
-	}
-	return typ, err
-}
-
-func checkId(want, got typeId) {
-	if want != got {
-		fmt.Fprintf(os.Stderr, "checkId: %d should be %d\n", int(got), int(want))
-		panic("bootstrap type wrong id: " + got.name() + " " + got.string() + " not " + want.string())
-	}
-}
-
-// used for building the basic types; called only from init().  the incoming
-// interface always refers to a pointer.
-func bootstrapType(name string, e interface{}, expect typeId) typeId {
-	rt := reflect.TypeOf(e).Elem()
-	_, present := types[rt]
-	if present {
-		panic("bootstrap type already present: " + name + ", " + rt.String())
-	}
-	typ := &CommonType{Name: name}
-	types[rt] = typ
-	setTypeId(typ)
-	checkId(expect, nextId)
-	userType(rt) // might as well cache it now
-	return nextId
-}
-
-// Representation of the information we send and receive about this type.
-// Each value we send is preceded by its type definition: an encoded int.
-// However, the very first time we send the value, we first send the pair
-// (-id, wireType).
-// For bootstrapping purposes, we assume that the recipient knows how
-// to decode a wireType; it is exactly the wireType struct here, interpreted
-// using the gob rules for sending a structure, except that we assume the
-// ids for wireType and structType etc. are known.  The relevant pieces
-// are built in encode.go's init() function.
-// To maintain binary compatibility, if you extend this type, always put
-// the new fields last.
-type wireType struct {
-	ArrayT           *arrayType
-	SliceT           *sliceType
-	StructT          *structType
-	MapT             *mapType
-	GobEncoderT      *gobEncoderType
-	BinaryMarshalerT *gobEncoderType
-	TextMarshalerT   *gobEncoderType
-}
-
-func (w *wireType) string() string {
-	const unknown = "unknown type"
-	if w == nil {
-		return unknown
-	}
-	switch {
-	case w.ArrayT != nil:
-		return w.ArrayT.Name
-	case w.SliceT != nil:
-		return w.SliceT.Name
-	case w.StructT != nil:
-		return w.StructT.Name
-	case w.MapT != nil:
-		return w.MapT.Name
-	case w.GobEncoderT != nil:
-		return w.GobEncoderT.Name
-	case w.BinaryMarshalerT != nil:
-		return w.BinaryMarshalerT.Name
-	case w.TextMarshalerT != nil:
-		return w.TextMarshalerT.Name
-	}
-	return unknown
-}
-
-type typeInfo struct {
-	id      typeId
-	encoder *encEngine
-	wire    *wireType
-}
-
-var typeInfoMap = make(map[reflect.Type]*typeInfo) // protected by typeLock
-
-// typeLock must be held.
-func getTypeInfo(ut *userTypeInfo) (*typeInfo, error) {
-	rt := ut.base
-	if ut.externalEnc != 0 {
-		// We want the user type, not the base type.
-		rt = ut.user
-	}
-	info, ok := typeInfoMap[rt]
-	if ok {
-		return info, nil
-	}
-	info = new(typeInfo)
-	gt, err := getBaseType(rt.Name(), rt)
-	if err != nil {
-		return nil, err
-	}
-	info.id = gt.id()
-
-	if ut.externalEnc != 0 {
-		userType, err := getType(rt.Name(), ut, rt)
-		if err != nil {
-			return nil, err
-		}
-		gt := userType.id().gobType().(*gobEncoderType)
-		switch ut.externalEnc {
-		case xGob:
-			info.wire = &wireType{GobEncoderT: gt}
-		case xBinary:
-			info.wire = &wireType{BinaryMarshalerT: gt}
-		case xText:
-			info.wire = &wireType{TextMarshalerT: gt}
-		}
-		typeInfoMap[ut.user] = info
-		return info, nil
-	}
-
-	t := info.id.gobType()
-	switch typ := rt; typ.Kind() {
-	case reflect.Array:
-		info.wire = &wireType{ArrayT: t.(*arrayType)}
-	case reflect.Map:
-		info.wire = &wireType{MapT: t.(*mapType)}
-	case reflect.Slice:
-		// []byte == []uint8 is a special case handled separately
-		if typ.Elem().Kind() != reflect.Uint8 {
-			info.wire = &wireType{SliceT: t.(*sliceType)}
-		}
-	case reflect.Struct:
-		info.wire = &wireType{StructT: t.(*structType)}
-	}
-	typeInfoMap[rt] = info
-	return info, nil
-}
-
-// Called only when a panic is acceptable and unexpected.
-func mustGetTypeInfo(rt reflect.Type) *typeInfo {
-	t, err := getTypeInfo(userType(rt))
-	if err != nil {
-		panic("getTypeInfo: " + err.Error())
-	}
-	return t
-}
-
-// GobEncoder is the interface describing data that provides its own
-// representation for encoding values for transmission to a GobDecoder.
-// A type that implements GobEncoder and GobDecoder has complete
-// control over the representation of its data and may therefore
-// contain things such as private fields, channels, and functions,
-// which are not usually transmissible in gob streams.
-//
-// Note: Since gobs can be stored permanently, It is good design
-// to guarantee the encoding used by a GobEncoder is stable as the
-// software evolves.  For instance, it might make sense for GobEncode
-// to include a version number in the encoding.
-type GobEncoder interface {
-	// GobEncode returns a byte slice representing the encoding of the
-	// receiver for transmission to a GobDecoder, usually of the same
-	// concrete type.
-	GobEncode() ([]byte, error)
-}
-
-// GobDecoder is the interface describing data that provides its own
-// routine for decoding transmitted values sent by a GobEncoder.
-type GobDecoder interface {
-	// GobDecode overwrites the receiver, which must be a pointer,
-	// with the value represented by the byte slice, which was written
-	// by GobEncode, usually for the same concrete type.
-	GobDecode([]byte) error
-}
-
-var (
-	registerLock       sync.RWMutex
-	nameToConcreteType = make(map[string]reflect.Type)
-	concreteTypeToName = make(map[reflect.Type]string)
-)
-
-// RegisterName is like Register but uses the provided name rather than the
-// type's default.
-func RegisterName(name string, value interface{}) {
-	if name == "" {
-		// reserved for nil
-		panic("attempt to register empty name")
-	}
-	registerLock.Lock()
-	defer registerLock.Unlock()
-	ut := userType(reflect.TypeOf(value))
-	// Check for incompatible duplicates. The name must refer to the
-	// same user type, and vice versa.
-	if t, ok := nameToConcreteType[name]; ok && t != ut.user {
-		panic(fmt.Sprintf("gob: registering duplicate types for %q: %s != %s", name, t, ut.user))
-	}
-	if n, ok := concreteTypeToName[ut.base]; ok && n != name {
-		panic(fmt.Sprintf("gob: registering duplicate names for %s: %q != %q", ut.user, n, name))
-	}
-	// Store the name and type provided by the user....
-	nameToConcreteType[name] = reflect.TypeOf(value)
-	// but the flattened type in the type table, since that's what decode needs.
-	concreteTypeToName[ut.base] = name
-}
-
-// Register records a type, identified by a value for that type, under its
-// internal type name.  That name will identify the concrete type of a value
-// sent or received as an interface variable.  Only types that will be
-// transferred as implementations of interface values need to be registered.
-// Expecting to be used only during initialization, it panics if the mapping
-// between types and names is not a bijection.
-func Register(value interface{}) {
-	// Default to printed representation for unnamed types
-	rt := reflect.TypeOf(value)
-	name := rt.String()
-
-	// But for named types (or pointers to them), qualify with import path (but see inner comment).
-	// Dereference one pointer looking for a named type.
-	star := ""
-	if rt.Name() == "" {
-		if pt := rt; pt.Kind() == reflect.Ptr {
-			star = "*"
-			// NOTE: The following line should be rt = pt.Elem() to implement
-			// what the comment above claims, but fixing it would break compatibility
-			// with existing gobs.
-			//
-			// Given package p imported as "full/p" with these definitions:
-			//     package p
-			//     type T1 struct { ... }
-			// this table shows the intended and actual strings used by gob to
-			// name the types:
-			//
-			// Type      Correct string     Actual string
-			//
-			// T1        full/p.T1          full/p.T1
-			// *T1       *full/p.T1         *p.T1
-			//
-			// The missing full path cannot be fixed without breaking existing gob decoders.
-			rt = pt
-		}
-	}
-	if rt.Name() != "" {
-		if rt.PkgPath() == "" {
-			name = star + rt.Name()
-		} else {
-			name = star + rt.PkgPath() + "." + rt.Name()
-		}
-	}
-
-	RegisterName(name, value)
-}
-
-func registerBasics() {
-	Register(int(0))
-	Register(int8(0))
-	Register(int16(0))
-	Register(int32(0))
-	Register(int64(0))
-	Register(uint(0))
-	Register(uint8(0))
-	Register(uint16(0))
-	Register(uint32(0))
-	Register(uint64(0))
-	Register(float32(0))
-	Register(float64(0))
-	Register(complex64(0i))
-	Register(complex128(0i))
-	Register(uintptr(0))
-	Register(false)
-	Register("")
-	Register([]byte(nil))
-	Register([]int(nil))
-	Register([]int8(nil))
-	Register([]int16(nil))
-	Register([]int32(nil))
-	Register([]int64(nil))
-	Register([]uint(nil))
-	Register([]uint8(nil))
-	Register([]uint16(nil))
-	Register([]uint32(nil))
-	Register([]uint64(nil))
-	Register([]float32(nil))
-	Register([]float64(nil))
-	Register([]complex64(nil))
-	Register([]complex128(nil))
-	Register([]uintptr(nil))
-	Register([]bool(nil))
-	Register([]string(nil))
-}
diff --git a/src/pkg/encoding/json/decode.go b/src/pkg/encoding/json/decode.go
deleted file mode 100644
index af1c908..0000000
--- a/src/pkg/encoding/json/decode.go
+++ /dev/null
@@ -1,1050 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Represents JSON data structure using native Go types: booleans, floats,
-// strings, arrays, and maps.
-
-package json
-
-import (
-	"bytes"
-	"encoding"
-	"encoding/base64"
-	"errors"
-	"fmt"
-	"reflect"
-	"runtime"
-	"strconv"
-	"unicode"
-	"unicode/utf16"
-	"unicode/utf8"
-)
-
-// Unmarshal parses the JSON-encoded data and stores the result
-// in the value pointed to by v.
-//
-// Unmarshal uses the inverse of the encodings that
-// Marshal uses, allocating maps, slices, and pointers as necessary,
-// with the following additional rules:
-//
-// To unmarshal JSON into a pointer, Unmarshal first handles the case of
-// the JSON being the JSON literal null.  In that case, Unmarshal sets
-// the pointer to nil.  Otherwise, Unmarshal unmarshals the JSON into
-// the value pointed at by the pointer.  If the pointer is nil, Unmarshal
-// allocates a new value for it to point to.
-//
-// To unmarshal JSON into a struct, Unmarshal matches incoming object
-// keys to the keys used by Marshal (either the struct field name or its tag),
-// preferring an exact match but also accepting a case-insensitive match.
-//
-// To unmarshal JSON into an interface value,
-// Unmarshal stores one of these in the interface value:
-//
-//	bool, for JSON booleans
-//	float64, for JSON numbers
-//	string, for JSON strings
-//	[]interface{}, for JSON arrays
-//	map[string]interface{}, for JSON objects
-//	nil for JSON null
-//
-// If a JSON value is not appropriate for a given target type,
-// or if a JSON number overflows the target type, Unmarshal
-// skips that field and completes the unmarshalling as best it can.
-// If no more serious errors are encountered, Unmarshal returns
-// an UnmarshalTypeError describing the earliest such error.
-//
-// The JSON null value unmarshals into an interface, map, pointer, or slice
-// by setting that Go value to nil. Because null is often used in JSON to mean
-// ``not present,'' unmarshaling a JSON null into any other Go type has no effect
-// on the value and produces no error.
-//
-// When unmarshaling quoted strings, invalid UTF-8 or
-// invalid UTF-16 surrogate pairs are not treated as an error.
-// Instead, they are replaced by the Unicode replacement
-// character U+FFFD.
-//
-func Unmarshal(data []byte, v interface{}) error {
-	// Check for well-formedness.
-	// Avoids filling out half a data structure
-	// before discovering a JSON syntax error.
-	var d decodeState
-	err := checkValid(data, &d.scan)
-	if err != nil {
-		return err
-	}
-
-	d.init(data)
-	return d.unmarshal(v)
-}
-
-// Unmarshaler is the interface implemented by objects
-// that can unmarshal a JSON description of themselves.
-// The input can be assumed to be a valid encoding of
-// a JSON value. UnmarshalJSON must copy the JSON data
-// if it wishes to retain the data after returning.
-type Unmarshaler interface {
-	UnmarshalJSON([]byte) error
-}
-
-// An UnmarshalTypeError describes a JSON value that was
-// not appropriate for a value of a specific Go type.
-type UnmarshalTypeError struct {
-	Value string       // description of JSON value - "bool", "array", "number -5"
-	Type  reflect.Type // type of Go value it could not be assigned to
-}
-
-func (e *UnmarshalTypeError) Error() string {
-	return "json: cannot unmarshal " + e.Value + " into Go value of type " + e.Type.String()
-}
-
-// An UnmarshalFieldError describes a JSON object key that
-// led to an unexported (and therefore unwritable) struct field.
-// (No longer used; kept for compatibility.)
-type UnmarshalFieldError struct {
-	Key   string
-	Type  reflect.Type
-	Field reflect.StructField
-}
-
-func (e *UnmarshalFieldError) Error() string {
-	return "json: cannot unmarshal object key " + strconv.Quote(e.Key) + " into unexported field " + e.Field.Name + " of type " + e.Type.String()
-}
-
-// An InvalidUnmarshalError describes an invalid argument passed to Unmarshal.
-// (The argument to Unmarshal must be a non-nil pointer.)
-type InvalidUnmarshalError struct {
-	Type reflect.Type
-}
-
-func (e *InvalidUnmarshalError) Error() string {
-	if e.Type == nil {
-		return "json: Unmarshal(nil)"
-	}
-
-	if e.Type.Kind() != reflect.Ptr {
-		return "json: Unmarshal(non-pointer " + e.Type.String() + ")"
-	}
-	return "json: Unmarshal(nil " + e.Type.String() + ")"
-}
-
-func (d *decodeState) unmarshal(v interface{}) (err error) {
-	defer func() {
-		if r := recover(); r != nil {
-			if _, ok := r.(runtime.Error); ok {
-				panic(r)
-			}
-			err = r.(error)
-		}
-	}()
-
-	rv := reflect.ValueOf(v)
-	if rv.Kind() != reflect.Ptr || rv.IsNil() {
-		return &InvalidUnmarshalError{reflect.TypeOf(v)}
-	}
-
-	d.scan.reset()
-	// We decode rv not rv.Elem because the Unmarshaler interface
-	// test must be applied at the top level of the value.
-	d.value(rv)
-	return d.savedError
-}
-
-// A Number represents a JSON number literal.
-type Number string
-
-// String returns the literal text of the number.
-func (n Number) String() string { return string(n) }
-
-// Float64 returns the number as a float64.
-func (n Number) Float64() (float64, error) {
-	return strconv.ParseFloat(string(n), 64)
-}
-
-// Int64 returns the number as an int64.
-func (n Number) Int64() (int64, error) {
-	return strconv.ParseInt(string(n), 10, 64)
-}
-
-// decodeState represents the state while decoding a JSON value.
-type decodeState struct {
-	data       []byte
-	off        int // read offset in data
-	scan       scanner
-	nextscan   scanner // for calls to nextValue
-	savedError error
-	tempstr    string // scratch space to avoid some allocations
-	useNumber  bool
-}
-
-// errPhase is used for errors that should not happen unless
-// there is a bug in the JSON decoder or something is editing
-// the data slice while the decoder executes.
-var errPhase = errors.New("JSON decoder out of sync - data changing underfoot?")
-
-func (d *decodeState) init(data []byte) *decodeState {
-	d.data = data
-	d.off = 0
-	d.savedError = nil
-	return d
-}
-
-// error aborts the decoding by panicking with err.
-func (d *decodeState) error(err error) {
-	panic(err)
-}
-
-// saveError saves the first err it is called with,
-// for reporting at the end of the unmarshal.
-func (d *decodeState) saveError(err error) {
-	if d.savedError == nil {
-		d.savedError = err
-	}
-}
-
-// next cuts off and returns the next full JSON value in d.data[d.off:].
-// The next value is known to be an object or array, not a literal.
-func (d *decodeState) next() []byte {
-	c := d.data[d.off]
-	item, rest, err := nextValue(d.data[d.off:], &d.nextscan)
-	if err != nil {
-		d.error(err)
-	}
-	d.off = len(d.data) - len(rest)
-
-	// Our scanner has seen the opening brace/bracket
-	// and thinks we're still in the middle of the object.
-	// invent a closing brace/bracket to get it out.
-	if c == '{' {
-		d.scan.step(&d.scan, '}')
-	} else {
-		d.scan.step(&d.scan, ']')
-	}
-
-	return item
-}
-
-// scanWhile processes bytes in d.data[d.off:] until it
-// receives a scan code not equal to op.
-// It updates d.off and returns the new scan code.
-func (d *decodeState) scanWhile(op int) int {
-	var newOp int
-	for {
-		if d.off >= len(d.data) {
-			newOp = d.scan.eof()
-			d.off = len(d.data) + 1 // mark processed EOF with len+1
-		} else {
-			c := int(d.data[d.off])
-			d.off++
-			newOp = d.scan.step(&d.scan, c)
-		}
-		if newOp != op {
-			break
-		}
-	}
-	return newOp
-}
-
-// value decodes a JSON value from d.data[d.off:] into the value.
-// it updates d.off to point past the decoded value.
-func (d *decodeState) value(v reflect.Value) {
-	if !v.IsValid() {
-		_, rest, err := nextValue(d.data[d.off:], &d.nextscan)
-		if err != nil {
-			d.error(err)
-		}
-		d.off = len(d.data) - len(rest)
-
-		// d.scan thinks we're still at the beginning of the item.
-		// Feed in an empty string - the shortest, simplest value -
-		// so that it knows we got to the end of the value.
-		if d.scan.redo {
-			// rewind.
-			d.scan.redo = false
-			d.scan.step = stateBeginValue
-		}
-		d.scan.step(&d.scan, '"')
-		d.scan.step(&d.scan, '"')
-
-		n := len(d.scan.parseState)
-		if n > 0 && d.scan.parseState[n-1] == parseObjectKey {
-			// d.scan thinks we just read an object key; finish the object
-			d.scan.step(&d.scan, ':')
-			d.scan.step(&d.scan, '"')
-			d.scan.step(&d.scan, '"')
-			d.scan.step(&d.scan, '}')
-		}
-
-		return
-	}
-
-	switch op := d.scanWhile(scanSkipSpace); op {
-	default:
-		d.error(errPhase)
-
-	case scanBeginArray:
-		d.array(v)
-
-	case scanBeginObject:
-		d.object(v)
-
-	case scanBeginLiteral:
-		d.literal(v)
-	}
-}
-
-// indirect walks down v allocating pointers as needed,
-// until it gets to a non-pointer.
-// if it encounters an Unmarshaler, indirect stops and returns that.
-// if decodingNull is true, indirect stops at the last pointer so it can be set to nil.
-func (d *decodeState) indirect(v reflect.Value, decodingNull bool) (Unmarshaler, encoding.TextUnmarshaler, reflect.Value) {
-	// If v is a named type and is addressable,
-	// start with its address, so that if the type has pointer methods,
-	// we find them.
-	if v.Kind() != reflect.Ptr && v.Type().Name() != "" && v.CanAddr() {
-		v = v.Addr()
-	}
-	for {
-		// Load value from interface, but only if the result will be
-		// usefully addressable.
-		if v.Kind() == reflect.Interface && !v.IsNil() {
-			e := v.Elem()
-			if e.Kind() == reflect.Ptr && !e.IsNil() && (!decodingNull || e.Elem().Kind() == reflect.Ptr) {
-				v = e
-				continue
-			}
-		}
-
-		if v.Kind() != reflect.Ptr {
-			break
-		}
-
-		if v.Elem().Kind() != reflect.Ptr && decodingNull && v.CanSet() {
-			break
-		}
-		if v.IsNil() {
-			v.Set(reflect.New(v.Type().Elem()))
-		}
-		if v.Type().NumMethod() > 0 {
-			if u, ok := v.Interface().(Unmarshaler); ok {
-				return u, nil, reflect.Value{}
-			}
-			if u, ok := v.Interface().(encoding.TextUnmarshaler); ok {
-				return nil, u, reflect.Value{}
-			}
-		}
-		v = v.Elem()
-	}
-	return nil, nil, v
-}
-
-// array consumes an array from d.data[d.off-1:], decoding into the value v.
-// the first byte of the array ('[') has been read already.
-func (d *decodeState) array(v reflect.Value) {
-	// Check for unmarshaler.
-	u, ut, pv := d.indirect(v, false)
-	if u != nil {
-		d.off--
-		err := u.UnmarshalJSON(d.next())
-		if err != nil {
-			d.error(err)
-		}
-		return
-	}
-	if ut != nil {
-		d.saveError(&UnmarshalTypeError{"array", v.Type()})
-		d.off--
-		d.next()
-		return
-	}
-
-	v = pv
-
-	// Check type of target.
-	switch v.Kind() {
-	case reflect.Interface:
-		if v.NumMethod() == 0 {
-			// Decoding into nil interface?  Switch to non-reflect code.
-			v.Set(reflect.ValueOf(d.arrayInterface()))
-			return
-		}
-		// Otherwise it's invalid.
-		fallthrough
-	default:
-		d.saveError(&UnmarshalTypeError{"array", v.Type()})
-		d.off--
-		d.next()
-		return
-	case reflect.Array:
-	case reflect.Slice:
-		break
-	}
-
-	i := 0
-	for {
-		// Look ahead for ] - can only happen on first iteration.
-		op := d.scanWhile(scanSkipSpace)
-		if op == scanEndArray {
-			break
-		}
-
-		// Back up so d.value can have the byte we just read.
-		d.off--
-		d.scan.undo(op)
-
-		// Get element of array, growing if necessary.
-		if v.Kind() == reflect.Slice {
-			// Grow slice if necessary
-			if i >= v.Cap() {
-				newcap := v.Cap() + v.Cap()/2
-				if newcap < 4 {
-					newcap = 4
-				}
-				newv := reflect.MakeSlice(v.Type(), v.Len(), newcap)
-				reflect.Copy(newv, v)
-				v.Set(newv)
-			}
-			if i >= v.Len() {
-				v.SetLen(i + 1)
-			}
-		}
-
-		if i < v.Len() {
-			// Decode into element.
-			d.value(v.Index(i))
-		} else {
-			// Ran out of fixed array: skip.
-			d.value(reflect.Value{})
-		}
-		i++
-
-		// Next token must be , or ].
-		op = d.scanWhile(scanSkipSpace)
-		if op == scanEndArray {
-			break
-		}
-		if op != scanArrayValue {
-			d.error(errPhase)
-		}
-	}
-
-	if i < v.Len() {
-		if v.Kind() == reflect.Array {
-			// Array.  Zero the rest.
-			z := reflect.Zero(v.Type().Elem())
-			for ; i < v.Len(); i++ {
-				v.Index(i).Set(z)
-			}
-		} else {
-			v.SetLen(i)
-		}
-	}
-	if i == 0 && v.Kind() == reflect.Slice {
-		v.Set(reflect.MakeSlice(v.Type(), 0, 0))
-	}
-}
-
-// object consumes an object from d.data[d.off-1:], decoding into the value v.
-// the first byte of the object ('{') has been read already.
-func (d *decodeState) object(v reflect.Value) {
-	// Check for unmarshaler.
-	u, ut, pv := d.indirect(v, false)
-	if u != nil {
-		d.off--
-		err := u.UnmarshalJSON(d.next())
-		if err != nil {
-			d.error(err)
-		}
-		return
-	}
-	if ut != nil {
-		d.saveError(&UnmarshalTypeError{"object", v.Type()})
-		d.off--
-		d.next() // skip over { } in input
-		return
-	}
-	v = pv
-
-	// Decoding into nil interface?  Switch to non-reflect code.
-	if v.Kind() == reflect.Interface && v.NumMethod() == 0 {
-		v.Set(reflect.ValueOf(d.objectInterface()))
-		return
-	}
-
-	// Check type of target: struct or map[string]T
-	switch v.Kind() {
-	case reflect.Map:
-		// map must have string kind
-		t := v.Type()
-		if t.Key().Kind() != reflect.String {
-			d.saveError(&UnmarshalTypeError{"object", v.Type()})
-			break
-		}
-		if v.IsNil() {
-			v.Set(reflect.MakeMap(t))
-		}
-	case reflect.Struct:
-
-	default:
-		d.saveError(&UnmarshalTypeError{"object", v.Type()})
-		d.off--
-		d.next() // skip over { } in input
-		return
-	}
-
-	var mapElem reflect.Value
-
-	for {
-		// Read opening " of string key or closing }.
-		op := d.scanWhile(scanSkipSpace)
-		if op == scanEndObject {
-			// closing } - can only happen on first iteration.
-			break
-		}
-		if op != scanBeginLiteral {
-			d.error(errPhase)
-		}
-
-		// Read key.
-		start := d.off - 1
-		op = d.scanWhile(scanContinue)
-		item := d.data[start : d.off-1]
-		key, ok := unquoteBytes(item)
-		if !ok {
-			d.error(errPhase)
-		}
-
-		// Figure out field corresponding to key.
-		var subv reflect.Value
-		destring := false // whether the value is wrapped in a string to be decoded first
-
-		if v.Kind() == reflect.Map {
-			elemType := v.Type().Elem()
-			if !mapElem.IsValid() {
-				mapElem = reflect.New(elemType).Elem()
-			} else {
-				mapElem.Set(reflect.Zero(elemType))
-			}
-			subv = mapElem
-		} else {
-			var f *field
-			fields := cachedTypeFields(v.Type())
-			for i := range fields {
-				ff := &fields[i]
-				if bytes.Equal(ff.nameBytes, key) {
-					f = ff
-					break
-				}
-				if f == nil && ff.equalFold(ff.nameBytes, key) {
-					f = ff
-				}
-			}
-			if f != nil {
-				subv = v
-				destring = f.quoted
-				for _, i := range f.index {
-					if subv.Kind() == reflect.Ptr {
-						if subv.IsNil() {
-							subv.Set(reflect.New(subv.Type().Elem()))
-						}
-						subv = subv.Elem()
-					}
-					subv = subv.Field(i)
-				}
-			}
-		}
-
-		// Read : before value.
-		if op == scanSkipSpace {
-			op = d.scanWhile(scanSkipSpace)
-		}
-		if op != scanObjectKey {
-			d.error(errPhase)
-		}
-
-		// Read value.
-		if destring {
-			d.value(reflect.ValueOf(&d.tempstr))
-			d.literalStore([]byte(d.tempstr), subv, true)
-			d.tempstr = "" // Zero scratch space for successive values.
-		} else {
-			d.value(subv)
-		}
-
-		// Write value back to map;
-		// if using struct, subv points into struct already.
-		if v.Kind() == reflect.Map {
-			kv := reflect.ValueOf(key).Convert(v.Type().Key())
-			v.SetMapIndex(kv, subv)
-		}
-
-		// Next token must be , or }.
-		op = d.scanWhile(scanSkipSpace)
-		if op == scanEndObject {
-			break
-		}
-		if op != scanObjectValue {
-			d.error(errPhase)
-		}
-	}
-}
-
-// literal consumes a literal from d.data[d.off-1:], decoding into the value v.
-// The first byte of the literal has been read already
-// (that's how the caller knows it's a literal).
-func (d *decodeState) literal(v reflect.Value) {
-	// All bytes inside literal return scanContinue op code.
-	start := d.off - 1
-	op := d.scanWhile(scanContinue)
-
-	// Scan read one byte too far; back up.
-	d.off--
-	d.scan.undo(op)
-
-	d.literalStore(d.data[start:d.off], v, false)
-}
-
-// convertNumber converts the number literal s to a float64 or a Number
-// depending on the setting of d.useNumber.
-func (d *decodeState) convertNumber(s string) (interface{}, error) {
-	if d.useNumber {
-		return Number(s), nil
-	}
-	f, err := strconv.ParseFloat(s, 64)
-	if err != nil {
-		return nil, &UnmarshalTypeError{"number " + s, reflect.TypeOf(0.0)}
-	}
-	return f, nil
-}
-
-var numberType = reflect.TypeOf(Number(""))
-
-// literalStore decodes a literal stored in item into v.
-//
-// fromQuoted indicates whether this literal came from unwrapping a
-// string from the ",string" struct tag option. this is used only to
-// produce more helpful error messages.
-func (d *decodeState) literalStore(item []byte, v reflect.Value, fromQuoted bool) {
-	// Check for unmarshaler.
-	if len(item) == 0 {
-		//Empty string given
-		d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type()))
-		return
-	}
-	wantptr := item[0] == 'n' // null
-	u, ut, pv := d.indirect(v, wantptr)
-	if u != nil {
-		err := u.UnmarshalJSON(item)
-		if err != nil {
-			d.error(err)
-		}
-		return
-	}
-	if ut != nil {
-		if item[0] != '"' {
-			if fromQuoted {
-				d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type()))
-			} else {
-				d.saveError(&UnmarshalTypeError{"string", v.Type()})
-			}
-		}
-		s, ok := unquoteBytes(item)
-		if !ok {
-			if fromQuoted {
-				d.error(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type()))
-			} else {
-				d.error(errPhase)
-			}
-		}
-		err := ut.UnmarshalText(s)
-		if err != nil {
-			d.error(err)
-		}
-		return
-	}
-
-	v = pv
-
-	switch c := item[0]; c {
-	case 'n': // null
-		switch v.Kind() {
-		case reflect.Interface, reflect.Ptr, reflect.Map, reflect.Slice:
-			v.Set(reflect.Zero(v.Type()))
-			// otherwise, ignore null for primitives/string
-		}
-	case 't', 'f': // true, false
-		value := c == 't'
-		switch v.Kind() {
-		default:
-			if fromQuoted {
-				d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type()))
-			} else {
-				d.saveError(&UnmarshalTypeError{"bool", v.Type()})
-			}
-		case reflect.Bool:
-			v.SetBool(value)
-		case reflect.Interface:
-			if v.NumMethod() == 0 {
-				v.Set(reflect.ValueOf(value))
-			} else {
-				d.saveError(&UnmarshalTypeError{"bool", v.Type()})
-			}
-		}
-
-	case '"': // string
-		s, ok := unquoteBytes(item)
-		if !ok {
-			if fromQuoted {
-				d.error(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type()))
-			} else {
-				d.error(errPhase)
-			}
-		}
-		switch v.Kind() {
-		default:
-			d.saveError(&UnmarshalTypeError{"string", v.Type()})
-		case reflect.Slice:
-			if v.Type() != byteSliceType {
-				d.saveError(&UnmarshalTypeError{"string", v.Type()})
-				break
-			}
-			b := make([]byte, base64.StdEncoding.DecodedLen(len(s)))
-			n, err := base64.StdEncoding.Decode(b, s)
-			if err != nil {
-				d.saveError(err)
-				break
-			}
-			v.Set(reflect.ValueOf(b[0:n]))
-		case reflect.String:
-			v.SetString(string(s))
-		case reflect.Interface:
-			if v.NumMethod() == 0 {
-				v.Set(reflect.ValueOf(string(s)))
-			} else {
-				d.saveError(&UnmarshalTypeError{"string", v.Type()})
-			}
-		}
-
-	default: // number
-		if c != '-' && (c < '0' || c > '9') {
-			if fromQuoted {
-				d.error(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type()))
-			} else {
-				d.error(errPhase)
-			}
-		}
-		s := string(item)
-		switch v.Kind() {
-		default:
-			if v.Kind() == reflect.String && v.Type() == numberType {
-				v.SetString(s)
-				break
-			}
-			if fromQuoted {
-				d.error(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type()))
-			} else {
-				d.error(&UnmarshalTypeError{"number", v.Type()})
-			}
-		case reflect.Interface:
-			n, err := d.convertNumber(s)
-			if err != nil {
-				d.saveError(err)
-				break
-			}
-			if v.NumMethod() != 0 {
-				d.saveError(&UnmarshalTypeError{"number", v.Type()})
-				break
-			}
-			v.Set(reflect.ValueOf(n))
-
-		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-			n, err := strconv.ParseInt(s, 10, 64)
-			if err != nil || v.OverflowInt(n) {
-				d.saveError(&UnmarshalTypeError{"number " + s, v.Type()})
-				break
-			}
-			v.SetInt(n)
-
-		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
-			n, err := strconv.ParseUint(s, 10, 64)
-			if err != nil || v.OverflowUint(n) {
-				d.saveError(&UnmarshalTypeError{"number " + s, v.Type()})
-				break
-			}
-			v.SetUint(n)
-
-		case reflect.Float32, reflect.Float64:
-			n, err := strconv.ParseFloat(s, v.Type().Bits())
-			if err != nil || v.OverflowFloat(n) {
-				d.saveError(&UnmarshalTypeError{"number " + s, v.Type()})
-				break
-			}
-			v.SetFloat(n)
-		}
-	}
-}
-
-// The xxxInterface routines build up a value to be stored
-// in an empty interface.  They are not strictly necessary,
-// but they avoid the weight of reflection in this common case.
-
-// valueInterface is like value but returns interface{}
-func (d *decodeState) valueInterface() interface{} {
-	switch d.scanWhile(scanSkipSpace) {
-	default:
-		d.error(errPhase)
-		panic("unreachable")
-	case scanBeginArray:
-		return d.arrayInterface()
-	case scanBeginObject:
-		return d.objectInterface()
-	case scanBeginLiteral:
-		return d.literalInterface()
-	}
-}
-
-// arrayInterface is like array but returns []interface{}.
-func (d *decodeState) arrayInterface() []interface{} {
-	var v = make([]interface{}, 0)
-	for {
-		// Look ahead for ] - can only happen on first iteration.
-		op := d.scanWhile(scanSkipSpace)
-		if op == scanEndArray {
-			break
-		}
-
-		// Back up so d.value can have the byte we just read.
-		d.off--
-		d.scan.undo(op)
-
-		v = append(v, d.valueInterface())
-
-		// Next token must be , or ].
-		op = d.scanWhile(scanSkipSpace)
-		if op == scanEndArray {
-			break
-		}
-		if op != scanArrayValue {
-			d.error(errPhase)
-		}
-	}
-	return v
-}
-
-// objectInterface is like object but returns map[string]interface{}.
-func (d *decodeState) objectInterface() map[string]interface{} {
-	m := make(map[string]interface{})
-	for {
-		// Read opening " of string key or closing }.
-		op := d.scanWhile(scanSkipSpace)
-		if op == scanEndObject {
-			// closing } - can only happen on first iteration.
-			break
-		}
-		if op != scanBeginLiteral {
-			d.error(errPhase)
-		}
-
-		// Read string key.
-		start := d.off - 1
-		op = d.scanWhile(scanContinue)
-		item := d.data[start : d.off-1]
-		key, ok := unquote(item)
-		if !ok {
-			d.error(errPhase)
-		}
-
-		// Read : before value.
-		if op == scanSkipSpace {
-			op = d.scanWhile(scanSkipSpace)
-		}
-		if op != scanObjectKey {
-			d.error(errPhase)
-		}
-
-		// Read value.
-		m[key] = d.valueInterface()
-
-		// Next token must be , or }.
-		op = d.scanWhile(scanSkipSpace)
-		if op == scanEndObject {
-			break
-		}
-		if op != scanObjectValue {
-			d.error(errPhase)
-		}
-	}
-	return m
-}
-
-// literalInterface is like literal but returns an interface value.
-func (d *decodeState) literalInterface() interface{} {
-	// All bytes inside literal return scanContinue op code.
-	start := d.off - 1
-	op := d.scanWhile(scanContinue)
-
-	// Scan read one byte too far; back up.
-	d.off--
-	d.scan.undo(op)
-	item := d.data[start:d.off]
-
-	switch c := item[0]; c {
-	case 'n': // null
-		return nil
-
-	case 't', 'f': // true, false
-		return c == 't'
-
-	case '"': // string
-		s, ok := unquote(item)
-		if !ok {
-			d.error(errPhase)
-		}
-		return s
-
-	default: // number
-		if c != '-' && (c < '0' || c > '9') {
-			d.error(errPhase)
-		}
-		n, err := d.convertNumber(string(item))
-		if err != nil {
-			d.saveError(err)
-		}
-		return n
-	}
-}
-
-// getu4 decodes \uXXXX from the beginning of s, returning the hex value,
-// or it returns -1.
-func getu4(s []byte) rune {
-	if len(s) < 6 || s[0] != '\\' || s[1] != 'u' {
-		return -1
-	}
-	r, err := strconv.ParseUint(string(s[2:6]), 16, 64)
-	if err != nil {
-		return -1
-	}
-	return rune(r)
-}
-
-// unquote converts a quoted JSON string literal s into an actual string t.
-// The rules are different than for Go, so cannot use strconv.Unquote.
-func unquote(s []byte) (t string, ok bool) {
-	s, ok = unquoteBytes(s)
-	t = string(s)
-	return
-}
-
-func unquoteBytes(s []byte) (t []byte, ok bool) {
-	if len(s) < 2 || s[0] != '"' || s[len(s)-1] != '"' {
-		return
-	}
-	s = s[1 : len(s)-1]
-
-	// Check for unusual characters. If there are none,
-	// then no unquoting is needed, so return a slice of the
-	// original bytes.
-	r := 0
-	for r < len(s) {
-		c := s[r]
-		if c == '\\' || c == '"' || c < ' ' {
-			break
-		}
-		if c < utf8.RuneSelf {
-			r++
-			continue
-		}
-		rr, size := utf8.DecodeRune(s[r:])
-		if rr == utf8.RuneError && size == 1 {
-			break
-		}
-		r += size
-	}
-	if r == len(s) {
-		return s, true
-	}
-
-	b := make([]byte, len(s)+2*utf8.UTFMax)
-	w := copy(b, s[0:r])
-	for r < len(s) {
-		// Out of room?  Can only happen if s is full of
-		// malformed UTF-8 and we're replacing each
-		// byte with RuneError.
-		if w >= len(b)-2*utf8.UTFMax {
-			nb := make([]byte, (len(b)+utf8.UTFMax)*2)
-			copy(nb, b[0:w])
-			b = nb
-		}
-		switch c := s[r]; {
-		case c == '\\':
-			r++
-			if r >= len(s) {
-				return
-			}
-			switch s[r] {
-			default:
-				return
-			case '"', '\\', '/', '\'':
-				b[w] = s[r]
-				r++
-				w++
-			case 'b':
-				b[w] = '\b'
-				r++
-				w++
-			case 'f':
-				b[w] = '\f'
-				r++
-				w++
-			case 'n':
-				b[w] = '\n'
-				r++
-				w++
-			case 'r':
-				b[w] = '\r'
-				r++
-				w++
-			case 't':
-				b[w] = '\t'
-				r++
-				w++
-			case 'u':
-				r--
-				rr := getu4(s[r:])
-				if rr < 0 {
-					return
-				}
-				r += 6
-				if utf16.IsSurrogate(rr) {
-					rr1 := getu4(s[r:])
-					if dec := utf16.DecodeRune(rr, rr1); dec != unicode.ReplacementChar {
-						// A valid pair; consume.
-						r += 6
-						w += utf8.EncodeRune(b[w:], dec)
-						break
-					}
-					// Invalid surrogate; fall back to replacement rune.
-					rr = unicode.ReplacementChar
-				}
-				w += utf8.EncodeRune(b[w:], rr)
-			}
-
-		// Quote, control characters are invalid.
-		case c == '"', c < ' ':
-			return
-
-		// ASCII
-		case c < utf8.RuneSelf:
-			b[w] = c
-			r++
-			w++
-
-		// Coerce to well-formed UTF-8.
-		default:
-			rr, size := utf8.DecodeRune(s[r:])
-			r += size
-			w += utf8.EncodeRune(b[w:], rr)
-		}
-	}
-	return b[0:w], true
-}
diff --git a/src/pkg/encoding/json/decode_test.go b/src/pkg/encoding/json/decode_test.go
deleted file mode 100644
index 238a87f..0000000
--- a/src/pkg/encoding/json/decode_test.go
+++ /dev/null
@@ -1,1356 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package json
-
-import (
-	"bytes"
-	"encoding"
-	"fmt"
-	"image"
-	"reflect"
-	"strings"
-	"testing"
-	"time"
-)
-
-type T struct {
-	X string
-	Y int
-	Z int `json:"-"`
-}
-
-type U struct {
-	Alphabet string `json:"alpha"`
-}
-
-type V struct {
-	F1 interface{}
-	F2 int32
-	F3 Number
-}
-
-// ifaceNumAsFloat64/ifaceNumAsNumber are used to test unmarshaling with and
-// without UseNumber
-var ifaceNumAsFloat64 = map[string]interface{}{
-	"k1": float64(1),
-	"k2": "s",
-	"k3": []interface{}{float64(1), float64(2.0), float64(3e-3)},
-	"k4": map[string]interface{}{"kk1": "s", "kk2": float64(2)},
-}
-
-var ifaceNumAsNumber = map[string]interface{}{
-	"k1": Number("1"),
-	"k2": "s",
-	"k3": []interface{}{Number("1"), Number("2.0"), Number("3e-3")},
-	"k4": map[string]interface{}{"kk1": "s", "kk2": Number("2")},
-}
-
-type tx struct {
-	x int
-}
-
-// A type that can unmarshal itself.
-
-type unmarshaler struct {
-	T bool
-}
-
-func (u *unmarshaler) UnmarshalJSON(b []byte) error {
-	*u = unmarshaler{true} // All we need to see that UnmarshalJSON is called.
-	return nil
-}
-
-type ustruct struct {
-	M unmarshaler
-}
-
-type unmarshalerText struct {
-	T bool
-}
-
-// needed for re-marshaling tests
-func (u *unmarshalerText) MarshalText() ([]byte, error) {
-	return []byte(""), nil
-}
-
-func (u *unmarshalerText) UnmarshalText(b []byte) error {
-	*u = unmarshalerText{true} // All we need to see that UnmarshalText is called.
-	return nil
-}
-
-var _ encoding.TextUnmarshaler = (*unmarshalerText)(nil)
-
-type ustructText struct {
-	M unmarshalerText
-}
-
-var (
-	um0, um1 unmarshaler // target2 of unmarshaling
-	ump      = &um1
-	umtrue   = unmarshaler{true}
-	umslice  = []unmarshaler{{true}}
-	umslicep = new([]unmarshaler)
-	umstruct = ustruct{unmarshaler{true}}
-
-	um0T, um1T unmarshalerText // target2 of unmarshaling
-	umpT       = &um1T
-	umtrueT    = unmarshalerText{true}
-	umsliceT   = []unmarshalerText{{true}}
-	umslicepT  = new([]unmarshalerText)
-	umstructT  = ustructText{unmarshalerText{true}}
-)
-
-// Test data structures for anonymous fields.
-
-type Point struct {
-	Z int
-}
-
-type Top struct {
-	Level0 int
-	Embed0
-	*Embed0a
-	*Embed0b `json:"e,omitempty"` // treated as named
-	Embed0c  `json:"-"`           // ignored
-	Loop
-	Embed0p // has Point with X, Y, used
-	Embed0q // has Point with Z, used
-}
-
-type Embed0 struct {
-	Level1a int // overridden by Embed0a's Level1a with json tag
-	Level1b int // used because Embed0a's Level1b is renamed
-	Level1c int // used because Embed0a's Level1c is ignored
-	Level1d int // annihilated by Embed0a's Level1d
-	Level1e int `json:"x"` // annihilated by Embed0a.Level1e
-}
-
-type Embed0a struct {
-	Level1a int `json:"Level1a,omitempty"`
-	Level1b int `json:"LEVEL1B,omitempty"`
-	Level1c int `json:"-"`
-	Level1d int // annihilated by Embed0's Level1d
-	Level1f int `json:"x"` // annihilated by Embed0's Level1e
-}
-
-type Embed0b Embed0
-
-type Embed0c Embed0
-
-type Embed0p struct {
-	image.Point
-}
-
-type Embed0q struct {
-	Point
-}
-
-type Loop struct {
-	Loop1 int `json:",omitempty"`
-	Loop2 int `json:",omitempty"`
-	*Loop
-}
-
-// From reflect test:
-// The X in S6 and S7 annihilate, but they also block the X in S8.S9.
-type S5 struct {
-	S6
-	S7
-	S8
-}
-
-type S6 struct {
-	X int
-}
-
-type S7 S6
-
-type S8 struct {
-	S9
-}
-
-type S9 struct {
-	X int
-	Y int
-}
-
-// From reflect test:
-// The X in S11.S6 and S12.S6 annihilate, but they also block the X in S13.S8.S9.
-type S10 struct {
-	S11
-	S12
-	S13
-}
-
-type S11 struct {
-	S6
-}
-
-type S12 struct {
-	S6
-}
-
-type S13 struct {
-	S8
-}
-
-type unmarshalTest struct {
-	in        string
-	ptr       interface{}
-	out       interface{}
-	err       error
-	useNumber bool
-}
-
-type Ambig struct {
-	// Given "hello", the first match should win.
-	First  int `json:"HELLO"`
-	Second int `json:"Hello"`
-}
-
-type XYZ struct {
-	X interface{}
-	Y interface{}
-	Z interface{}
-}
-
-var unmarshalTests = []unmarshalTest{
-	// basic types
-	{in: `true`, ptr: new(bool), out: true},
-	{in: `1`, ptr: new(int), out: 1},
-	{in: `1.2`, ptr: new(float64), out: 1.2},
-	{in: `-5`, ptr: new(int16), out: int16(-5)},
-	{in: `2`, ptr: new(Number), out: Number("2"), useNumber: true},
-	{in: `2`, ptr: new(Number), out: Number("2")},
-	{in: `2`, ptr: new(interface{}), out: float64(2.0)},
-	{in: `2`, ptr: new(interface{}), out: Number("2"), useNumber: true},
-	{in: `"a\u1234"`, ptr: new(string), out: "a\u1234"},
-	{in: `"http:\/\/"`, ptr: new(string), out: "http://"},
-	{in: `"g-clef: \uD834\uDD1E"`, ptr: new(string), out: "g-clef: \U0001D11E"},
-	{in: `"invalid: \uD834x\uDD1E"`, ptr: new(string), out: "invalid: \uFFFDx\uFFFD"},
-	{in: "null", ptr: new(interface{}), out: nil},
-	{in: `{"X": [1,2,3], "Y": 4}`, ptr: new(T), out: T{Y: 4}, err: &UnmarshalTypeError{"array", reflect.TypeOf("")}},
-	{in: `{"x": 1}`, ptr: new(tx), out: tx{}},
-	{in: `{"F1":1,"F2":2,"F3":3}`, ptr: new(V), out: V{F1: float64(1), F2: int32(2), F3: Number("3")}},
-	{in: `{"F1":1,"F2":2,"F3":3}`, ptr: new(V), out: V{F1: Number("1"), F2: int32(2), F3: Number("3")}, useNumber: true},
-	{in: `{"k1":1,"k2":"s","k3":[1,2.0,3e-3],"k4":{"kk1":"s","kk2":2}}`, ptr: new(interface{}), out: ifaceNumAsFloat64},
-	{in: `{"k1":1,"k2":"s","k3":[1,2.0,3e-3],"k4":{"kk1":"s","kk2":2}}`, ptr: new(interface{}), out: ifaceNumAsNumber, useNumber: true},
-
-	// raw values with whitespace
-	{in: "\n true ", ptr: new(bool), out: true},
-	{in: "\t 1 ", ptr: new(int), out: 1},
-	{in: "\r 1.2 ", ptr: new(float64), out: 1.2},
-	{in: "\t -5 \n", ptr: new(int16), out: int16(-5)},
-	{in: "\t \"a\\u1234\" \n", ptr: new(string), out: "a\u1234"},
-
-	// Z has a "-" tag.
-	{in: `{"Y": 1, "Z": 2}`, ptr: new(T), out: T{Y: 1}},
-
-	{in: `{"alpha": "abc", "alphabet": "xyz"}`, ptr: new(U), out: U{Alphabet: "abc"}},
-	{in: `{"alpha": "abc"}`, ptr: new(U), out: U{Alphabet: "abc"}},
-	{in: `{"alphabet": "xyz"}`, ptr: new(U), out: U{}},
-
-	// syntax errors
-	{in: `{"X": "foo", "Y"}`, err: &SyntaxError{"invalid character '}' after object key", 17}},
-	{in: `[1, 2, 3+]`, err: &SyntaxError{"invalid character '+' after array element", 9}},
-	{in: `{"X":12x}`, err: &SyntaxError{"invalid character 'x' after object key:value pair", 8}, useNumber: true},
-
-	// raw value errors
-	{in: "\x01 42", err: &SyntaxError{"invalid character '\\x01' looking for beginning of value", 1}},
-	{in: " 42 \x01", err: &SyntaxError{"invalid character '\\x01' after top-level value", 5}},
-	{in: "\x01 true", err: &SyntaxError{"invalid character '\\x01' looking for beginning of value", 1}},
-	{in: " false \x01", err: &SyntaxError{"invalid character '\\x01' after top-level value", 8}},
-	{in: "\x01 1.2", err: &SyntaxError{"invalid character '\\x01' looking for beginning of value", 1}},
-	{in: " 3.4 \x01", err: &SyntaxError{"invalid character '\\x01' after top-level value", 6}},
-	{in: "\x01 \"string\"", err: &SyntaxError{"invalid character '\\x01' looking for beginning of value", 1}},
-	{in: " \"string\" \x01", err: &SyntaxError{"invalid character '\\x01' after top-level value", 11}},
-
-	// array tests
-	{in: `[1, 2, 3]`, ptr: new([3]int), out: [3]int{1, 2, 3}},
-	{in: `[1, 2, 3]`, ptr: new([1]int), out: [1]int{1}},
-	{in: `[1, 2, 3]`, ptr: new([5]int), out: [5]int{1, 2, 3, 0, 0}},
-
-	// empty array to interface test
-	{in: `[]`, ptr: new([]interface{}), out: []interface{}{}},
-	{in: `null`, ptr: new([]interface{}), out: []interface{}(nil)},
-	{in: `{"T":[]}`, ptr: new(map[string]interface{}), out: map[string]interface{}{"T": []interface{}{}}},
-	{in: `{"T":null}`, ptr: new(map[string]interface{}), out: map[string]interface{}{"T": interface{}(nil)}},
-
-	// composite tests
-	{in: allValueIndent, ptr: new(All), out: allValue},
-	{in: allValueCompact, ptr: new(All), out: allValue},
-	{in: allValueIndent, ptr: new(*All), out: &allValue},
-	{in: allValueCompact, ptr: new(*All), out: &allValue},
-	{in: pallValueIndent, ptr: new(All), out: pallValue},
-	{in: pallValueCompact, ptr: new(All), out: pallValue},
-	{in: pallValueIndent, ptr: new(*All), out: &pallValue},
-	{in: pallValueCompact, ptr: new(*All), out: &pallValue},
-
-	// unmarshal interface test
-	{in: `{"T":false}`, ptr: &um0, out: umtrue}, // use "false" so test will fail if custom unmarshaler is not called
-	{in: `{"T":false}`, ptr: &ump, out: &umtrue},
-	{in: `[{"T":false}]`, ptr: &umslice, out: umslice},
-	{in: `[{"T":false}]`, ptr: &umslicep, out: &umslice},
-	{in: `{"M":{"T":false}}`, ptr: &umstruct, out: umstruct},
-
-	// UnmarshalText interface test
-	{in: `"X"`, ptr: &um0T, out: umtrueT}, // use "false" so test will fail if custom unmarshaler is not called
-	{in: `"X"`, ptr: &umpT, out: &umtrueT},
-	{in: `["X"]`, ptr: &umsliceT, out: umsliceT},
-	{in: `["X"]`, ptr: &umslicepT, out: &umsliceT},
-	{in: `{"M":"X"}`, ptr: &umstructT, out: umstructT},
-
-	{
-		in: `{
-			"Level0": 1,
-			"Level1b": 2,
-			"Level1c": 3,
-			"x": 4,
-			"Level1a": 5,
-			"LEVEL1B": 6,
-			"e": {
-				"Level1a": 8,
-				"Level1b": 9,
-				"Level1c": 10,
-				"Level1d": 11,
-				"x": 12
-			},
-			"Loop1": 13,
-			"Loop2": 14,
-			"X": 15,
-			"Y": 16,
-			"Z": 17
-		}`,
-		ptr: new(Top),
-		out: Top{
-			Level0: 1,
-			Embed0: Embed0{
-				Level1b: 2,
-				Level1c: 3,
-			},
-			Embed0a: &Embed0a{
-				Level1a: 5,
-				Level1b: 6,
-			},
-			Embed0b: &Embed0b{
-				Level1a: 8,
-				Level1b: 9,
-				Level1c: 10,
-				Level1d: 11,
-				Level1e: 12,
-			},
-			Loop: Loop{
-				Loop1: 13,
-				Loop2: 14,
-			},
-			Embed0p: Embed0p{
-				Point: image.Point{X: 15, Y: 16},
-			},
-			Embed0q: Embed0q{
-				Point: Point{Z: 17},
-			},
-		},
-	},
-	{
-		in:  `{"hello": 1}`,
-		ptr: new(Ambig),
-		out: Ambig{First: 1},
-	},
-
-	{
-		in:  `{"X": 1,"Y":2}`,
-		ptr: new(S5),
-		out: S5{S8: S8{S9: S9{Y: 2}}},
-	},
-	{
-		in:  `{"X": 1,"Y":2}`,
-		ptr: new(S10),
-		out: S10{S13: S13{S8: S8{S9: S9{Y: 2}}}},
-	},
-
-	// invalid UTF-8 is coerced to valid UTF-8.
-	{
-		in:  "\"hello\xffworld\"",
-		ptr: new(string),
-		out: "hello\ufffdworld",
-	},
-	{
-		in:  "\"hello\xc2\xc2world\"",
-		ptr: new(string),
-		out: "hello\ufffd\ufffdworld",
-	},
-	{
-		in:  "\"hello\xc2\xffworld\"",
-		ptr: new(string),
-		out: "hello\ufffd\ufffdworld",
-	},
-	{
-		in:  "\"hello\\ud800world\"",
-		ptr: new(string),
-		out: "hello\ufffdworld",
-	},
-	{
-		in:  "\"hello\\ud800\\ud800world\"",
-		ptr: new(string),
-		out: "hello\ufffd\ufffdworld",
-	},
-	{
-		in:  "\"hello\\ud800\\ud800world\"",
-		ptr: new(string),
-		out: "hello\ufffd\ufffdworld",
-	},
-	{
-		in:  "\"hello\xed\xa0\x80\xed\xb0\x80world\"",
-		ptr: new(string),
-		out: "hello\ufffd\ufffd\ufffd\ufffd\ufffd\ufffdworld",
-	},
-}
-
-func TestMarshal(t *testing.T) {
-	b, err := Marshal(allValue)
-	if err != nil {
-		t.Fatalf("Marshal allValue: %v", err)
-	}
-	if string(b) != allValueCompact {
-		t.Errorf("Marshal allValueCompact")
-		diff(t, b, []byte(allValueCompact))
-		return
-	}
-
-	b, err = Marshal(pallValue)
-	if err != nil {
-		t.Fatalf("Marshal pallValue: %v", err)
-	}
-	if string(b) != pallValueCompact {
-		t.Errorf("Marshal pallValueCompact")
-		diff(t, b, []byte(pallValueCompact))
-		return
-	}
-}
-
-var badUTF8 = []struct {
-	in, out string
-}{
-	{"hello\xffworld", `"hello\ufffdworld"`},
-	{"", `""`},
-	{"\xff", `"\ufffd"`},
-	{"\xff\xff", `"\ufffd\ufffd"`},
-	{"a\xffb", `"a\ufffdb"`},
-	{"\xe6\x97\xa5\xe6\x9c\xac\xff\xaa\x9e", `"日本\ufffd\ufffd\ufffd"`},
-}
-
-func TestMarshalBadUTF8(t *testing.T) {
-	for _, tt := range badUTF8 {
-		b, err := Marshal(tt.in)
-		if string(b) != tt.out || err != nil {
-			t.Errorf("Marshal(%q) = %#q, %v, want %#q, nil", tt.in, b, err, tt.out)
-		}
-	}
-}
-
-func TestMarshalNumberZeroVal(t *testing.T) {
-	var n Number
-	out, err := Marshal(n)
-	if err != nil {
-		t.Fatal(err)
-	}
-	outStr := string(out)
-	if outStr != "0" {
-		t.Fatalf("Invalid zero val for Number: %q", outStr)
-	}
-}
-
-func TestMarshalEmbeds(t *testing.T) {
-	top := &Top{
-		Level0: 1,
-		Embed0: Embed0{
-			Level1b: 2,
-			Level1c: 3,
-		},
-		Embed0a: &Embed0a{
-			Level1a: 5,
-			Level1b: 6,
-		},
-		Embed0b: &Embed0b{
-			Level1a: 8,
-			Level1b: 9,
-			Level1c: 10,
-			Level1d: 11,
-			Level1e: 12,
-		},
-		Loop: Loop{
-			Loop1: 13,
-			Loop2: 14,
-		},
-		Embed0p: Embed0p{
-			Point: image.Point{X: 15, Y: 16},
-		},
-		Embed0q: Embed0q{
-			Point: Point{Z: 17},
-		},
-	}
-	b, err := Marshal(top)
-	if err != nil {
-		t.Fatal(err)
-	}
-	want := "{\"Level0\":1,\"Level1b\":2,\"Level1c\":3,\"Level1a\":5,\"LEVEL1B\":6,\"e\":{\"Level1a\":8,\"Level1b\":9,\"Level1c\":10,\"Level1d\":11,\"x\":12},\"Loop1\":13,\"Loop2\":14,\"X\":15,\"Y\":16,\"Z\":17}"
-	if string(b) != want {
-		t.Errorf("Wrong marshal result.\n got: %q\nwant: %q", b, want)
-	}
-}
-
-func TestUnmarshal(t *testing.T) {
-	for i, tt := range unmarshalTests {
-		var scan scanner
-		in := []byte(tt.in)
-		if err := checkValid(in, &scan); err != nil {
-			if !reflect.DeepEqual(err, tt.err) {
-				t.Errorf("#%d: checkValid: %#v", i, err)
-				continue
-			}
-		}
-		if tt.ptr == nil {
-			continue
-		}
-		// v = new(right-type)
-		v := reflect.New(reflect.TypeOf(tt.ptr).Elem())
-		dec := NewDecoder(bytes.NewReader(in))
-		if tt.useNumber {
-			dec.UseNumber()
-		}
-		if err := dec.Decode(v.Interface()); !reflect.DeepEqual(err, tt.err) {
-			t.Errorf("#%d: %v want %v", i, err, tt.err)
-			continue
-		}
-		if !reflect.DeepEqual(v.Elem().Interface(), tt.out) {
-			t.Errorf("#%d: mismatch\nhave: %#+v\nwant: %#+v", i, v.Elem().Interface(), tt.out)
-			data, _ := Marshal(v.Elem().Interface())
-			println(string(data))
-			data, _ = Marshal(tt.out)
-			println(string(data))
-			continue
-		}
-
-		// Check round trip.
-		if tt.err == nil {
-			enc, err := Marshal(v.Interface())
-			if err != nil {
-				t.Errorf("#%d: error re-marshaling: %v", i, err)
-				continue
-			}
-			vv := reflect.New(reflect.TypeOf(tt.ptr).Elem())
-			dec = NewDecoder(bytes.NewReader(enc))
-			if tt.useNumber {
-				dec.UseNumber()
-			}
-			if err := dec.Decode(vv.Interface()); err != nil {
-				t.Errorf("#%d: error re-unmarshaling %#q: %v", i, enc, err)
-				continue
-			}
-			if !reflect.DeepEqual(v.Elem().Interface(), vv.Elem().Interface()) {
-				t.Errorf("#%d: mismatch\nhave: %#+v\nwant: %#+v", i, v.Elem().Interface(), vv.Elem().Interface())
-				t.Errorf("     In: %q", strings.Map(noSpace, string(in)))
-				t.Errorf("Marshal: %q", strings.Map(noSpace, string(enc)))
-				continue
-			}
-		}
-	}
-}
-
-func TestUnmarshalMarshal(t *testing.T) {
-	initBig()
-	var v interface{}
-	if err := Unmarshal(jsonBig, &v); err != nil {
-		t.Fatalf("Unmarshal: %v", err)
-	}
-	b, err := Marshal(v)
-	if err != nil {
-		t.Fatalf("Marshal: %v", err)
-	}
-	if !bytes.Equal(jsonBig, b) {
-		t.Errorf("Marshal jsonBig")
-		diff(t, b, jsonBig)
-		return
-	}
-}
-
-var numberTests = []struct {
-	in       string
-	i        int64
-	intErr   string
-	f        float64
-	floatErr string
-}{
-	{in: "-1.23e1", intErr: "strconv.ParseInt: parsing \"-1.23e1\": invalid syntax", f: -1.23e1},
-	{in: "-12", i: -12, f: -12.0},
-	{in: "1e1000", intErr: "strconv.ParseInt: parsing \"1e1000\": invalid syntax", floatErr: "strconv.ParseFloat: parsing \"1e1000\": value out of range"},
-}
-
-// Independent of Decode, basic coverage of the accessors in Number
-func TestNumberAccessors(t *testing.T) {
-	for _, tt := range numberTests {
-		n := Number(tt.in)
-		if s := n.String(); s != tt.in {
-			t.Errorf("Number(%q).String() is %q", tt.in, s)
-		}
-		if i, err := n.Int64(); err == nil && tt.intErr == "" && i != tt.i {
-			t.Errorf("Number(%q).Int64() is %d", tt.in, i)
-		} else if (err == nil && tt.intErr != "") || (err != nil && err.Error() != tt.intErr) {
-			t.Errorf("Number(%q).Int64() wanted error %q but got: %v", tt.in, tt.intErr, err)
-		}
-		if f, err := n.Float64(); err == nil && tt.floatErr == "" && f != tt.f {
-			t.Errorf("Number(%q).Float64() is %g", tt.in, f)
-		} else if (err == nil && tt.floatErr != "") || (err != nil && err.Error() != tt.floatErr) {
-			t.Errorf("Number(%q).Float64() wanted error %q but got: %v", tt.in, tt.floatErr, err)
-		}
-	}
-}
-
-func TestLargeByteSlice(t *testing.T) {
-	s0 := make([]byte, 2000)
-	for i := range s0 {
-		s0[i] = byte(i)
-	}
-	b, err := Marshal(s0)
-	if err != nil {
-		t.Fatalf("Marshal: %v", err)
-	}
-	var s1 []byte
-	if err := Unmarshal(b, &s1); err != nil {
-		t.Fatalf("Unmarshal: %v", err)
-	}
-	if !bytes.Equal(s0, s1) {
-		t.Errorf("Marshal large byte slice")
-		diff(t, s0, s1)
-	}
-}
-
-type Xint struct {
-	X int
-}
-
-func TestUnmarshalInterface(t *testing.T) {
-	var xint Xint
-	var i interface{} = &xint
-	if err := Unmarshal([]byte(`{"X":1}`), &i); err != nil {
-		t.Fatalf("Unmarshal: %v", err)
-	}
-	if xint.X != 1 {
-		t.Fatalf("Did not write to xint")
-	}
-}
-
-func TestUnmarshalPtrPtr(t *testing.T) {
-	var xint Xint
-	pxint := &xint
-	if err := Unmarshal([]byte(`{"X":1}`), &pxint); err != nil {
-		t.Fatalf("Unmarshal: %v", err)
-	}
-	if xint.X != 1 {
-		t.Fatalf("Did not write to xint")
-	}
-}
-
-func TestEscape(t *testing.T) {
-	const input = `"foobar"<html>` + " [\u2028 \u2029]"
-	const expected = `"\"foobar\"\u003chtml\u003e [\u2028 \u2029]"`
-	b, err := Marshal(input)
-	if err != nil {
-		t.Fatalf("Marshal error: %v", err)
-	}
-	if s := string(b); s != expected {
-		t.Errorf("Encoding of [%s]:\n got [%s]\nwant [%s]", input, s, expected)
-	}
-}
-
-// WrongString is a struct that's misusing the ,string modifier.
-type WrongString struct {
-	Message string `json:"result,string"`
-}
-
-type wrongStringTest struct {
-	in, err string
-}
-
-var wrongStringTests = []wrongStringTest{
-	{`{"result":"x"}`, `json: invalid use of ,string struct tag, trying to unmarshal "x" into string`},
-	{`{"result":"foo"}`, `json: invalid use of ,string struct tag, trying to unmarshal "foo" into string`},
-	{`{"result":"123"}`, `json: invalid use of ,string struct tag, trying to unmarshal "123" into string`},
-}
-
-// If people misuse the ,string modifier, the error message should be
-// helpful, telling the user that they're doing it wrong.
-func TestErrorMessageFromMisusedString(t *testing.T) {
-	for n, tt := range wrongStringTests {
-		r := strings.NewReader(tt.in)
-		var s WrongString
-		err := NewDecoder(r).Decode(&s)
-		got := fmt.Sprintf("%v", err)
-		if got != tt.err {
-			t.Errorf("%d. got err = %q, want %q", n, got, tt.err)
-		}
-	}
-}
-
-func noSpace(c rune) rune {
-	if isSpace(c) {
-		return -1
-	}
-	return c
-}
-
-type All struct {
-	Bool    bool
-	Int     int
-	Int8    int8
-	Int16   int16
-	Int32   int32
-	Int64   int64
-	Uint    uint
-	Uint8   uint8
-	Uint16  uint16
-	Uint32  uint32
-	Uint64  uint64
-	Uintptr uintptr
-	Float32 float32
-	Float64 float64
-
-	Foo  string `json:"bar"`
-	Foo2 string `json:"bar2,dummyopt"`
-
-	IntStr int64 `json:",string"`
-
-	PBool    *bool
-	PInt     *int
-	PInt8    *int8
-	PInt16   *int16
-	PInt32   *int32
-	PInt64   *int64
-	PUint    *uint
-	PUint8   *uint8
-	PUint16  *uint16
-	PUint32  *uint32
-	PUint64  *uint64
-	PUintptr *uintptr
-	PFloat32 *float32
-	PFloat64 *float64
-
-	String  string
-	PString *string
-
-	Map   map[string]Small
-	MapP  map[string]*Small
-	PMap  *map[string]Small
-	PMapP *map[string]*Small
-
-	EmptyMap map[string]Small
-	NilMap   map[string]Small
-
-	Slice   []Small
-	SliceP  []*Small
-	PSlice  *[]Small
-	PSliceP *[]*Small
-
-	EmptySlice []Small
-	NilSlice   []Small
-
-	StringSlice []string
-	ByteSlice   []byte
-
-	Small   Small
-	PSmall  *Small
-	PPSmall **Small
-
-	Interface  interface{}
-	PInterface *interface{}
-
-	unexported int
-}
-
-type Small struct {
-	Tag string
-}
-
-var allValue = All{
-	Bool:    true,
-	Int:     2,
-	Int8:    3,
-	Int16:   4,
-	Int32:   5,
-	Int64:   6,
-	Uint:    7,
-	Uint8:   8,
-	Uint16:  9,
-	Uint32:  10,
-	Uint64:  11,
-	Uintptr: 12,
-	Float32: 14.1,
-	Float64: 15.1,
-	Foo:     "foo",
-	Foo2:    "foo2",
-	IntStr:  42,
-	String:  "16",
-	Map: map[string]Small{
-		"17": {Tag: "tag17"},
-		"18": {Tag: "tag18"},
-	},
-	MapP: map[string]*Small{
-		"19": {Tag: "tag19"},
-		"20": nil,
-	},
-	EmptyMap:    map[string]Small{},
-	Slice:       []Small{{Tag: "tag20"}, {Tag: "tag21"}},
-	SliceP:      []*Small{{Tag: "tag22"}, nil, {Tag: "tag23"}},
-	EmptySlice:  []Small{},
-	StringSlice: []string{"str24", "str25", "str26"},
-	ByteSlice:   []byte{27, 28, 29},
-	Small:       Small{Tag: "tag30"},
-	PSmall:      &Small{Tag: "tag31"},
-	Interface:   5.2,
-}
-
-var pallValue = All{
-	PBool:      &allValue.Bool,
-	PInt:       &allValue.Int,
-	PInt8:      &allValue.Int8,
-	PInt16:     &allValue.Int16,
-	PInt32:     &allValue.Int32,
-	PInt64:     &allValue.Int64,
-	PUint:      &allValue.Uint,
-	PUint8:     &allValue.Uint8,
-	PUint16:    &allValue.Uint16,
-	PUint32:    &allValue.Uint32,
-	PUint64:    &allValue.Uint64,
-	PUintptr:   &allValue.Uintptr,
-	PFloat32:   &allValue.Float32,
-	PFloat64:   &allValue.Float64,
-	PString:    &allValue.String,
-	PMap:       &allValue.Map,
-	PMapP:      &allValue.MapP,
-	PSlice:     &allValue.Slice,
-	PSliceP:    &allValue.SliceP,
-	PPSmall:    &allValue.PSmall,
-	PInterface: &allValue.Interface,
-}
-
-var allValueIndent = `{
-	"Bool": true,
-	"Int": 2,
-	"Int8": 3,
-	"Int16": 4,
-	"Int32": 5,
-	"Int64": 6,
-	"Uint": 7,
-	"Uint8": 8,
-	"Uint16": 9,
-	"Uint32": 10,
-	"Uint64": 11,
-	"Uintptr": 12,
-	"Float32": 14.1,
-	"Float64": 15.1,
-	"bar": "foo",
-	"bar2": "foo2",
-	"IntStr": "42",
-	"PBool": null,
-	"PInt": null,
-	"PInt8": null,
-	"PInt16": null,
-	"PInt32": null,
-	"PInt64": null,
-	"PUint": null,
-	"PUint8": null,
-	"PUint16": null,
-	"PUint32": null,
-	"PUint64": null,
-	"PUintptr": null,
-	"PFloat32": null,
-	"PFloat64": null,
-	"String": "16",
-	"PString": null,
-	"Map": {
-		"17": {
-			"Tag": "tag17"
-		},
-		"18": {
-			"Tag": "tag18"
-		}
-	},
-	"MapP": {
-		"19": {
-			"Tag": "tag19"
-		},
-		"20": null
-	},
-	"PMap": null,
-	"PMapP": null,
-	"EmptyMap": {},
-	"NilMap": null,
-	"Slice": [
-		{
-			"Tag": "tag20"
-		},
-		{
-			"Tag": "tag21"
-		}
-	],
-	"SliceP": [
-		{
-			"Tag": "tag22"
-		},
-		null,
-		{
-			"Tag": "tag23"
-		}
-	],
-	"PSlice": null,
-	"PSliceP": null,
-	"EmptySlice": [],
-	"NilSlice": null,
-	"StringSlice": [
-		"str24",
-		"str25",
-		"str26"
-	],
-	"ByteSlice": "Gxwd",
-	"Small": {
-		"Tag": "tag30"
-	},
-	"PSmall": {
-		"Tag": "tag31"
-	},
-	"PPSmall": null,
-	"Interface": 5.2,
-	"PInterface": null
-}`
-
-var allValueCompact = strings.Map(noSpace, allValueIndent)
-
-var pallValueIndent = `{
-	"Bool": false,
-	"Int": 0,
-	"Int8": 0,
-	"Int16": 0,
-	"Int32": 0,
-	"Int64": 0,
-	"Uint": 0,
-	"Uint8": 0,
-	"Uint16": 0,
-	"Uint32": 0,
-	"Uint64": 0,
-	"Uintptr": 0,
-	"Float32": 0,
-	"Float64": 0,
-	"bar": "",
-	"bar2": "",
-        "IntStr": "0",
-	"PBool": true,
-	"PInt": 2,
-	"PInt8": 3,
-	"PInt16": 4,
-	"PInt32": 5,
-	"PInt64": 6,
-	"PUint": 7,
-	"PUint8": 8,
-	"PUint16": 9,
-	"PUint32": 10,
-	"PUint64": 11,
-	"PUintptr": 12,
-	"PFloat32": 14.1,
-	"PFloat64": 15.1,
-	"String": "",
-	"PString": "16",
-	"Map": null,
-	"MapP": null,
-	"PMap": {
-		"17": {
-			"Tag": "tag17"
-		},
-		"18": {
-			"Tag": "tag18"
-		}
-	},
-	"PMapP": {
-		"19": {
-			"Tag": "tag19"
-		},
-		"20": null
-	},
-	"EmptyMap": null,
-	"NilMap": null,
-	"Slice": null,
-	"SliceP": null,
-	"PSlice": [
-		{
-			"Tag": "tag20"
-		},
-		{
-			"Tag": "tag21"
-		}
-	],
-	"PSliceP": [
-		{
-			"Tag": "tag22"
-		},
-		null,
-		{
-			"Tag": "tag23"
-		}
-	],
-	"EmptySlice": null,
-	"NilSlice": null,
-	"StringSlice": null,
-	"ByteSlice": null,
-	"Small": {
-		"Tag": ""
-	},
-	"PSmall": null,
-	"PPSmall": {
-		"Tag": "tag31"
-	},
-	"Interface": null,
-	"PInterface": 5.2
-}`
-
-var pallValueCompact = strings.Map(noSpace, pallValueIndent)
-
-func TestRefUnmarshal(t *testing.T) {
-	type S struct {
-		// Ref is defined in encode_test.go.
-		R0 Ref
-		R1 *Ref
-		R2 RefText
-		R3 *RefText
-	}
-	want := S{
-		R0: 12,
-		R1: new(Ref),
-		R2: 13,
-		R3: new(RefText),
-	}
-	*want.R1 = 12
-	*want.R3 = 13
-
-	var got S
-	if err := Unmarshal([]byte(`{"R0":"ref","R1":"ref","R2":"ref","R3":"ref"}`), &got); err != nil {
-		t.Fatalf("Unmarshal: %v", err)
-	}
-	if !reflect.DeepEqual(got, want) {
-		t.Errorf("got %+v, want %+v", got, want)
-	}
-}
-
-// Test that the empty string doesn't panic decoding when ,string is specified
-// Issue 3450
-func TestEmptyString(t *testing.T) {
-	type T2 struct {
-		Number1 int `json:",string"`
-		Number2 int `json:",string"`
-	}
-	data := `{"Number1":"1", "Number2":""}`
-	dec := NewDecoder(strings.NewReader(data))
-	var t2 T2
-	err := dec.Decode(&t2)
-	if err == nil {
-		t.Fatal("Decode: did not return error")
-	}
-	if t2.Number1 != 1 {
-		t.Fatal("Decode: did not set Number1")
-	}
-}
-
-// Test that the returned error is non-nil when trying to unmarshal null string into int, for successive ,string option
-// Issue 7046
-func TestNullString(t *testing.T) {
-	type T struct {
-		A int `json:",string"`
-		B int `json:",string"`
-	}
-	data := []byte(`{"A": "1", "B": null}`)
-	var s T
-	err := Unmarshal(data, &s)
-	if err == nil {
-		t.Fatalf("expected error; got %v", s)
-	}
-}
-
-func intp(x int) *int {
-	p := new(int)
-	*p = x
-	return p
-}
-
-func intpp(x *int) **int {
-	pp := new(*int)
-	*pp = x
-	return pp
-}
-
-var interfaceSetTests = []struct {
-	pre  interface{}
-	json string
-	post interface{}
-}{
-	{"foo", `"bar"`, "bar"},
-	{"foo", `2`, 2.0},
-	{"foo", `true`, true},
-	{"foo", `null`, nil},
-
-	{nil, `null`, nil},
-	{new(int), `null`, nil},
-	{(*int)(nil), `null`, nil},
-	{new(*int), `null`, new(*int)},
-	{(**int)(nil), `null`, nil},
-	{intp(1), `null`, nil},
-	{intpp(nil), `null`, intpp(nil)},
-	{intpp(intp(1)), `null`, intpp(nil)},
-}
-
-func TestInterfaceSet(t *testing.T) {
-	for _, tt := range interfaceSetTests {
-		b := struct{ X interface{} }{tt.pre}
-		blob := `{"X":` + tt.json + `}`
-		if err := Unmarshal([]byte(blob), &b); err != nil {
-			t.Errorf("Unmarshal %#q: %v", blob, err)
-			continue
-		}
-		if !reflect.DeepEqual(b.X, tt.post) {
-			t.Errorf("Unmarshal %#q into %#v: X=%#v, want %#v", blob, tt.pre, b.X, tt.post)
-		}
-	}
-}
-
-// JSON null values should be ignored for primitives and string values instead of resulting in an error.
-// Issue 2540
-func TestUnmarshalNulls(t *testing.T) {
-	jsonData := []byte(`{
-		"Bool"    : null,
-		"Int"     : null,
-		"Int8"    : null,
-		"Int16"   : null,
-		"Int32"   : null,
-		"Int64"   : null,
-		"Uint"    : null,
-		"Uint8"   : null,
-		"Uint16"  : null,
-		"Uint32"  : null,
-		"Uint64"  : null,
-		"Float32" : null,
-		"Float64" : null,
-		"String"  : null}`)
-
-	nulls := All{
-		Bool:    true,
-		Int:     2,
-		Int8:    3,
-		Int16:   4,
-		Int32:   5,
-		Int64:   6,
-		Uint:    7,
-		Uint8:   8,
-		Uint16:  9,
-		Uint32:  10,
-		Uint64:  11,
-		Float32: 12.1,
-		Float64: 13.1,
-		String:  "14"}
-
-	err := Unmarshal(jsonData, &nulls)
-	if err != nil {
-		t.Errorf("Unmarshal of null values failed: %v", err)
-	}
-	if !nulls.Bool || nulls.Int != 2 || nulls.Int8 != 3 || nulls.Int16 != 4 || nulls.Int32 != 5 || nulls.Int64 != 6 ||
-		nulls.Uint != 7 || nulls.Uint8 != 8 || nulls.Uint16 != 9 || nulls.Uint32 != 10 || nulls.Uint64 != 11 ||
-		nulls.Float32 != 12.1 || nulls.Float64 != 13.1 || nulls.String != "14" {
-
-		t.Errorf("Unmarshal of null values affected primitives")
-	}
-}
-
-func TestStringKind(t *testing.T) {
-	type stringKind string
-
-	var m1, m2 map[stringKind]int
-	m1 = map[stringKind]int{
-		"foo": 42,
-	}
-
-	data, err := Marshal(m1)
-	if err != nil {
-		t.Errorf("Unexpected error marshalling: %v", err)
-	}
-
-	err = Unmarshal(data, &m2)
-	if err != nil {
-		t.Errorf("Unexpected error unmarshalling: %v", err)
-	}
-
-	if !reflect.DeepEqual(m1, m2) {
-		t.Error("Items should be equal after encoding and then decoding")
-	}
-
-}
-
-var decodeTypeErrorTests = []struct {
-	dest interface{}
-	src  string
-}{
-	{new(string), `{"user": "name"}`}, // issue 4628.
-	{new(error), `{}`},                // issue 4222
-	{new(error), `[]`},
-	{new(error), `""`},
-	{new(error), `123`},
-	{new(error), `true`},
-}
-
-func TestUnmarshalTypeError(t *testing.T) {
-	for _, item := range decodeTypeErrorTests {
-		err := Unmarshal([]byte(item.src), item.dest)
-		if _, ok := err.(*UnmarshalTypeError); !ok {
-			t.Errorf("expected type error for Unmarshal(%q, type %T): got %T",
-				item.src, item.dest, err)
-		}
-	}
-}
-
-var unmarshalSyntaxTests = []string{
-	"tru",
-	"fals",
-	"nul",
-	"123e",
-	`"hello`,
-	`[1,2,3`,
-	`{"key":1`,
-	`{"key":1,`,
-}
-
-func TestUnmarshalSyntax(t *testing.T) {
-	var x interface{}
-	for _, src := range unmarshalSyntaxTests {
-		err := Unmarshal([]byte(src), &x)
-		if _, ok := err.(*SyntaxError); !ok {
-			t.Errorf("expected syntax error for Unmarshal(%q): got %T", src, err)
-		}
-	}
-}
-
-// Test handling of unexported fields that should be ignored.
-// Issue 4660
-type unexportedFields struct {
-	Name string
-	m    map[string]interface{} `json:"-"`
-	m2   map[string]interface{} `json:"abcd"`
-}
-
-func TestUnmarshalUnexported(t *testing.T) {
-	input := `{"Name": "Bob", "m": {"x": 123}, "m2": {"y": 456}, "abcd": {"z": 789}}`
-	want := &unexportedFields{Name: "Bob"}
-
-	out := &unexportedFields{}
-	err := Unmarshal([]byte(input), out)
-	if err != nil {
-		t.Errorf("got error %v, expected nil", err)
-	}
-	if !reflect.DeepEqual(out, want) {
-		t.Errorf("got %q, want %q", out, want)
-	}
-}
-
-// Time3339 is a time.Time which encodes to and from JSON
-// as an RFC 3339 time in UTC.
-type Time3339 time.Time
-
-func (t *Time3339) UnmarshalJSON(b []byte) error {
-	if len(b) < 2 || b[0] != '"' || b[len(b)-1] != '"' {
-		return fmt.Errorf("types: failed to unmarshal non-string value %q as an RFC 3339 time", b)
-	}
-	tm, err := time.Parse(time.RFC3339, string(b[1:len(b)-1]))
-	if err != nil {
-		return err
-	}
-	*t = Time3339(tm)
-	return nil
-}
-
-func TestUnmarshalJSONLiteralError(t *testing.T) {
-	var t3 Time3339
-	err := Unmarshal([]byte(`"0000-00-00T00:00:00Z"`), &t3)
-	if err == nil {
-		t.Fatalf("expected error; got time %v", time.Time(t3))
-	}
-	if !strings.Contains(err.Error(), "range") {
-		t.Errorf("got err = %v; want out of range error", err)
-	}
-}
-
-// Test that extra object elements in an array do not result in a
-// "data changing underfoot" error.
-// Issue 3717
-func TestSkipArrayObjects(t *testing.T) {
-	json := `[{}]`
-	var dest [0]interface{}
-
-	err := Unmarshal([]byte(json), &dest)
-	if err != nil {
-		t.Errorf("got error %q, want nil", err)
-	}
-}
-
-// Test semantics of pre-filled struct fields and pre-filled map fields.
-// Issue 4900.
-func TestPrefilled(t *testing.T) {
-	ptrToMap := func(m map[string]interface{}) *map[string]interface{} { return &m }
-
-	// Values here change, cannot reuse table across runs.
-	var prefillTests = []struct {
-		in  string
-		ptr interface{}
-		out interface{}
-	}{
-		{
-			in:  `{"X": 1, "Y": 2}`,
-			ptr: &XYZ{X: float32(3), Y: int16(4), Z: 1.5},
-			out: &XYZ{X: float64(1), Y: float64(2), Z: 1.5},
-		},
-		{
-			in:  `{"X": 1, "Y": 2}`,
-			ptr: ptrToMap(map[string]interface{}{"X": float32(3), "Y": int16(4), "Z": 1.5}),
-			out: ptrToMap(map[string]interface{}{"X": float64(1), "Y": float64(2), "Z": 1.5}),
-		},
-	}
-
-	for _, tt := range prefillTests {
-		ptrstr := fmt.Sprintf("%v", tt.ptr)
-		err := Unmarshal([]byte(tt.in), tt.ptr) // tt.ptr edited here
-		if err != nil {
-			t.Errorf("Unmarshal: %v", err)
-		}
-		if !reflect.DeepEqual(tt.ptr, tt.out) {
-			t.Errorf("Unmarshal(%#q, %s): have %v, want %v", tt.in, ptrstr, tt.ptr, tt.out)
-		}
-	}
-}
-
-var invalidUnmarshalTests = []struct {
-	v    interface{}
-	want string
-}{
-	{nil, "json: Unmarshal(nil)"},
-	{struct{}{}, "json: Unmarshal(non-pointer struct {})"},
-	{(*int)(nil), "json: Unmarshal(nil *int)"},
-}
-
-func TestInvalidUnmarshal(t *testing.T) {
-	buf := []byte(`{"a":"1"}`)
-	for _, tt := range invalidUnmarshalTests {
-		err := Unmarshal(buf, tt.v)
-		if err == nil {
-			t.Errorf("Unmarshal expecting error, got nil")
-			continue
-		}
-		if got := err.Error(); got != tt.want {
-			t.Errorf("Unmarshal = %q; want %q", got, tt.want)
-		}
-	}
-}
diff --git a/src/pkg/encoding/json/encode.go b/src/pkg/encoding/json/encode.go
deleted file mode 100644
index 741ddd8..0000000
--- a/src/pkg/encoding/json/encode.go
+++ /dev/null
@@ -1,1175 +0,0 @@
-// Copyright 2010 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package json implements encoding and decoding of JSON objects as defined in
-// RFC 4627. The mapping between JSON objects and Go values is described
-// in the documentation for the Marshal and Unmarshal functions.
-//
-// See "JSON and Go" for an introduction to this package:
-// http://golang.org/doc/articles/json_and_go.html
-package json
-
-import (
-	"bytes"
-	"encoding"
-	"encoding/base64"
-	"math"
-	"reflect"
-	"runtime"
-	"sort"
-	"strconv"
-	"strings"
-	"sync"
-	"unicode"
-	"unicode/utf8"
-)
-
-// Marshal returns the JSON encoding of v.
-//
-// Marshal traverses the value v recursively.
-// If an encountered value implements the Marshaler interface
-// and is not a nil pointer, Marshal calls its MarshalJSON method
-// to produce JSON.  The nil pointer exception is not strictly necessary
-// but mimics a similar, necessary exception in the behavior of
-// UnmarshalJSON.
-//
-// Otherwise, Marshal uses the following type-dependent default encodings:
-//
-// Boolean values encode as JSON booleans.
-//
-// Floating point, integer, and Number values encode as JSON numbers.
-//
-// String values encode as JSON strings. InvalidUTF8Error will be returned
-// if an invalid UTF-8 sequence is encountered.
-// The angle brackets "<" and ">" are escaped to "\u003c" and "\u003e"
-// to keep some browsers from misinterpreting JSON output as HTML.
-// Ampersand "&" is also escaped to "\u0026" for the same reason.
-//
-// Array and slice values encode as JSON arrays, except that
-// []byte encodes as a base64-encoded string, and a nil slice
-// encodes as the null JSON object.
-//
-// Struct values encode as JSON objects. Each exported struct field
-// becomes a member of the object unless
-//   - the field's tag is "-", or
-//   - the field is empty and its tag specifies the "omitempty" option.
-// The empty values are false, 0, any
-// nil pointer or interface value, and any array, slice, map, or string of
-// length zero. The object's default key string is the struct field name
-// but can be specified in the struct field's tag value. The "json" key in
-// the struct field's tag value is the key name, followed by an optional comma
-// and options. Examples:
-//
-//   // Field is ignored by this package.
-//   Field int `json:"-"`
-//
-//   // Field appears in JSON as key "myName".
-//   Field int `json:"myName"`
-//
-//   // Field appears in JSON as key "myName" and
-//   // the field is omitted from the object if its value is empty,
-//   // as defined above.
-//   Field int `json:"myName,omitempty"`
-//
-//   // Field appears in JSON as key "Field" (the default), but
-//   // the field is skipped if empty.
-//   // Note the leading comma.
-//   Field int `json:",omitempty"`
-//
-// The "string" option signals that a field is stored as JSON inside a
-// JSON-encoded string. It applies only to fields of string, floating point,
-// or integer types. This extra level of encoding is sometimes used when
-// communicating with JavaScript programs:
-//
-//    Int64String int64 `json:",string"`
-//
-// The key name will be used if it's a non-empty string consisting of
-// only Unicode letters, digits, dollar signs, percent signs, hyphens,
-// underscores and slashes.
-//
-// Anonymous struct fields are usually marshaled as if their inner exported fields
-// were fields in the outer struct, subject to the usual Go visibility rules amended
-// as described in the next paragraph.
-// An anonymous struct field with a name given in its JSON tag is treated as
-// having that name, rather than being anonymous.
-//
-// The Go visibility rules for struct fields are amended for JSON when
-// deciding which field to marshal or unmarshal. If there are
-// multiple fields at the same level, and that level is the least
-// nested (and would therefore be the nesting level selected by the
-// usual Go rules), the following extra rules apply:
-//
-// 1) Of those fields, if any are JSON-tagged, only tagged fields are considered,
-// even if there are multiple untagged fields that would otherwise conflict.
-// 2) If there is exactly one field (tagged or not according to the first rule), that is selected.
-// 3) Otherwise there are multiple fields, and all are ignored; no error occurs.
-//
-// Handling of anonymous struct fields is new in Go 1.1.
-// Prior to Go 1.1, anonymous struct fields were ignored. To force ignoring of
-// an anonymous struct field in both current and earlier versions, give the field
-// a JSON tag of "-".
-//
-// Map values encode as JSON objects.
-// The map's key type must be string; the object keys are used directly
-// as map keys.
-//
-// Pointer values encode as the value pointed to.
-// A nil pointer encodes as the null JSON object.
-//
-// Interface values encode as the value contained in the interface.
-// A nil interface value encodes as the null JSON object.
-//
-// Channel, complex, and function values cannot be encoded in JSON.
-// Attempting to encode such a value causes Marshal to return
-// an UnsupportedTypeError.
-//
-// JSON cannot represent cyclic data structures and Marshal does not
-// handle them.  Passing cyclic structures to Marshal will result in
-// an infinite recursion.
-//
-func Marshal(v interface{}) ([]byte, error) {
-	e := &encodeState{}
-	err := e.marshal(v)
-	if err != nil {
-		return nil, err
-	}
-	return e.Bytes(), nil
-}
-
-// MarshalIndent is like Marshal but applies Indent to format the output.
-func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) {
-	b, err := Marshal(v)
-	if err != nil {
-		return nil, err
-	}
-	var buf bytes.Buffer
-	err = Indent(&buf, b, prefix, indent)
-	if err != nil {
-		return nil, err
-	}
-	return buf.Bytes(), nil
-}
-
-// HTMLEscape appends to dst the JSON-encoded src with <, >, &, U+2028 and U+2029
-// characters inside string literals changed to \u003c, \u003e, \u0026, \u2028, \u2029
-// so that the JSON will be safe to embed inside HTML <script> tags.
-// For historical reasons, web browsers don't honor standard HTML
-// escaping within <script> tags, so an alternative JSON encoding must
-// be used.
-func HTMLEscape(dst *bytes.Buffer, src []byte) {
-	// The characters can only appear in string literals,
-	// so just scan the string one byte at a time.
-	start := 0
-	for i, c := range src {
-		if c == '<' || c == '>' || c == '&' {
-			if start < i {
-				dst.Write(src[start:i])
-			}
-			dst.WriteString(`\u00`)
-			dst.WriteByte(hex[c>>4])
-			dst.WriteByte(hex[c&0xF])
-			start = i + 1
-		}
-		// Convert U+2028 and U+2029 (E2 80 A8 and E2 80 A9).
-		if c == 0xE2 && i+2 < len(src) && src[i+1] == 0x80 && src[i+2]&^1 == 0xA8 {
-			if start < i {
-				dst.Write(src[start:i])
-			}
-			dst.WriteString(`\u202`)
-			dst.WriteByte(hex[src[i+2]&0xF])
-			start = i + 3
-		}
-	}
-	if start < len(src) {
-		dst.Write(src[start:])
-	}
-}
-
-// Marshaler is the interface implemented by objects that
-// can marshal themselves into valid JSON.
-type Marshaler interface {
-	MarshalJSON() ([]byte, error)
-}
-
-// An UnsupportedTypeError is returned by Marshal when attempting
-// to encode an unsupported value type.
-type UnsupportedTypeError struct {
-	Type reflect.Type
-}
-
-func (e *UnsupportedTypeError) Error() string {
-	return "json: unsupported type: " + e.Type.String()
-}
-
-type UnsupportedValueError struct {
-	Value reflect.Value
-	Str   string
-}
-
-func (e *UnsupportedValueError) Error() string {
-	return "json: unsupported value: " + e.Str
-}
-
-// Before Go 1.2, an InvalidUTF8Error was returned by Marshal when
-// attempting to encode a string value with invalid UTF-8 sequences.
-// As of Go 1.2, Marshal instead coerces the string to valid UTF-8 by
-// replacing invalid bytes with the Unicode replacement rune U+FFFD.
-// This error is no longer generated but is kept for backwards compatibility
-// with programs that might mention it.
-type InvalidUTF8Error struct {
-	S string // the whole string value that caused the error
-}
-
-func (e *InvalidUTF8Error) Error() string {
-	return "json: invalid UTF-8 in string: " + strconv.Quote(e.S)
-}
-
-type MarshalerError struct {
-	Type reflect.Type
-	Err  error
-}
-
-func (e *MarshalerError) Error() string {
-	return "json: error calling MarshalJSON for type " + e.Type.String() + ": " + e.Err.Error()
-}
-
-var hex = "0123456789abcdef"
-
-// An encodeState encodes JSON into a bytes.Buffer.
-type encodeState struct {
-	bytes.Buffer // accumulated output
-	scratch      [64]byte
-}
-
-var encodeStatePool sync.Pool
-
-func newEncodeState() *encodeState {
-	if v := encodeStatePool.Get(); v != nil {
-		e := v.(*encodeState)
-		e.Reset()
-		return e
-	}
-	return new(encodeState)
-}
-
-func (e *encodeState) marshal(v interface{}) (err error) {
-	defer func() {
-		if r := recover(); r != nil {
-			if _, ok := r.(runtime.Error); ok {
-				panic(r)
-			}
-			if s, ok := r.(string); ok {
-				panic(s)
-			}
-			err = r.(error)
-		}
-	}()
-	e.reflectValue(reflect.ValueOf(v))
-	return nil
-}
-
-func (e *encodeState) error(err error) {
-	panic(err)
-}
-
-var byteSliceType = reflect.TypeOf([]byte(nil))
-
-func isEmptyValue(v reflect.Value) bool {
-	switch v.Kind() {
-	case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
-		return v.Len() == 0
-	case reflect.Bool:
-		return !v.Bool()
-	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-		return v.Int() == 0
-	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
-		return v.Uint() == 0
-	case reflect.Float32, reflect.Float64:
-		return v.Float() == 0
-	case reflect.Interface, reflect.Ptr:
-		return v.IsNil()
-	}
-	return false
-}
-
-func (e *encodeState) reflectValue(v reflect.Value) {
-	valueEncoder(v)(e, v, false)
-}
-
-type encoderFunc func(e *encodeState, v reflect.Value, quoted bool)
-
-var encoderCache struct {
-	sync.RWMutex
-	m map[reflect.Type]encoderFunc
-}
-
-func valueEncoder(v reflect.Value) encoderFunc {
-	if !v.IsValid() {
-		return invalidValueEncoder
-	}
-	return typeEncoder(v.Type())
-}
-
-func typeEncoder(t reflect.Type) encoderFunc {
-	encoderCache.RLock()
-	f := encoderCache.m[t]
-	encoderCache.RUnlock()
-	if f != nil {
-		return f
-	}
-
-	// To deal with recursive types, populate the map with an
-	// indirect func before we build it. This type waits on the
-	// real func (f) to be ready and then calls it.  This indirect
-	// func is only used for recursive types.
-	encoderCache.Lock()
-	if encoderCache.m == nil {
-		encoderCache.m = make(map[reflect.Type]encoderFunc)
-	}
-	var wg sync.WaitGroup
-	wg.Add(1)
-	encoderCache.m[t] = func(e *encodeState, v reflect.Value, quoted bool) {
-		wg.Wait()
-		f(e, v, quoted)
-	}
-	encoderCache.Unlock()
-
-	// Compute fields without lock.
-	// Might duplicate effort but won't hold other computations back.
-	f = newTypeEncoder(t, true)
-	wg.Done()
-	encoderCache.Lock()
-	encoderCache.m[t] = f
-	encoderCache.Unlock()
-	return f
-}
-
-var (
-	marshalerType     = reflect.TypeOf(new(Marshaler)).Elem()
-	textMarshalerType = reflect.TypeOf(new(encoding.TextMarshaler)).Elem()
-)
-
-// newTypeEncoder constructs an encoderFunc for a type.
-// The returned encoder only checks CanAddr when allowAddr is true.
-func newTypeEncoder(t reflect.Type, allowAddr bool) encoderFunc {
-	if t.Implements(marshalerType) {
-		return marshalerEncoder
-	}
-	if t.Kind() != reflect.Ptr && allowAddr {
-		if reflect.PtrTo(t).Implements(marshalerType) {
-			return newCondAddrEncoder(addrMarshalerEncoder, newTypeEncoder(t, false))
-		}
-	}
-
-	if t.Implements(textMarshalerType) {
-		return textMarshalerEncoder
-	}
-	if t.Kind() != reflect.Ptr && allowAddr {
-		if reflect.PtrTo(t).Implements(textMarshalerType) {
-			return newCondAddrEncoder(addrTextMarshalerEncoder, newTypeEncoder(t, false))
-		}
-	}
-
-	switch t.Kind() {
-	case reflect.Bool:
-		return boolEncoder
-	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-		return intEncoder
-	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
-		return uintEncoder
-	case reflect.Float32:
-		return float32Encoder
-	case reflect.Float64:
-		return float64Encoder
-	case reflect.String:
-		return stringEncoder
-	case reflect.Interface:
-		return interfaceEncoder
-	case reflect.Struct:
-		return newStructEncoder(t)
-	case reflect.Map:
-		return newMapEncoder(t)
-	case reflect.Slice:
-		return newSliceEncoder(t)
-	case reflect.Array:
-		return newArrayEncoder(t)
-	case reflect.Ptr:
-		return newPtrEncoder(t)
-	default:
-		return unsupportedTypeEncoder
-	}
-}
-
-func invalidValueEncoder(e *encodeState, v reflect.Value, quoted bool) {
-	e.WriteString("null")
-}
-
-func marshalerEncoder(e *encodeState, v reflect.Value, quoted bool) {
-	if v.Kind() == reflect.Ptr && v.IsNil() {
-		e.WriteString("null")
-		return
-	}
-	m := v.Interface().(Marshaler)
-	b, err := m.MarshalJSON()
-	if err == nil {
-		// copy JSON into buffer, checking validity.
-		err = compact(&e.Buffer, b, true)
-	}
-	if err != nil {
-		e.error(&MarshalerError{v.Type(), err})
-	}
-}
-
-func addrMarshalerEncoder(e *encodeState, v reflect.Value, quoted bool) {
-	va := v.Addr()
-	if va.IsNil() {
-		e.WriteString("null")
-		return
-	}
-	m := va.Interface().(Marshaler)
-	b, err := m.MarshalJSON()
-	if err == nil {
-		// copy JSON into buffer, checking validity.
-		err = compact(&e.Buffer, b, true)
-	}
-	if err != nil {
-		e.error(&MarshalerError{v.Type(), err})
-	}
-}
-
-func textMarshalerEncoder(e *encodeState, v reflect.Value, quoted bool) {
-	if v.Kind() == reflect.Ptr && v.IsNil() {
-		e.WriteString("null")
-		return
-	}
-	m := v.Interface().(encoding.TextMarshaler)
-	b, err := m.MarshalText()
-	if err == nil {
-		_, err = e.stringBytes(b)
-	}
-	if err != nil {
-		e.error(&MarshalerError{v.Type(), err})
-	}
-}
-
-func addrTextMarshalerEncoder(e *encodeState, v reflect.Value, quoted bool) {
-	va := v.Addr()
-	if va.IsNil() {
-		e.WriteString("null")
-		return
-	}
-	m := va.Interface().(encoding.TextMarshaler)
-	b, err := m.MarshalText()
-	if err == nil {
-		_, err = e.stringBytes(b)
-	}
-	if err != nil {
-		e.error(&MarshalerError{v.Type(), err})
-	}
-}
-
-func boolEncoder(e *encodeState, v reflect.Value, quoted bool) {
-	if quoted {
-		e.WriteByte('"')
-	}
-	if v.Bool() {
-		e.WriteString("true")
-	} else {
-		e.WriteString("false")
-	}
-	if quoted {
-		e.WriteByte('"')
-	}
-}
-
-func intEncoder(e *encodeState, v reflect.Value, quoted bool) {
-	b := strconv.AppendInt(e.scratch[:0], v.Int(), 10)
-	if quoted {
-		e.WriteByte('"')
-	}
-	e.Write(b)
-	if quoted {
-		e.WriteByte('"')
-	}
-}
-
-func uintEncoder(e *encodeState, v reflect.Value, quoted bool) {
-	b := strconv.AppendUint(e.scratch[:0], v.Uint(), 10)
-	if quoted {
-		e.WriteByte('"')
-	}
-	e.Write(b)
-	if quoted {
-		e.WriteByte('"')
-	}
-}
-
-type floatEncoder int // number of bits
-
-func (bits floatEncoder) encode(e *encodeState, v reflect.Value, quoted bool) {
-	f := v.Float()
-	if math.IsInf(f, 0) || math.IsNaN(f) {
-		e.error(&UnsupportedValueError{v, strconv.FormatFloat(f, 'g', -1, int(bits))})
-	}
-	b := strconv.AppendFloat(e.scratch[:0], f, 'g', -1, int(bits))
-	if quoted {
-		e.WriteByte('"')
-	}
-	e.Write(b)
-	if quoted {
-		e.WriteByte('"')
-	}
-}
-
-var (
-	float32Encoder = (floatEncoder(32)).encode
-	float64Encoder = (floatEncoder(64)).encode
-)
-
-func stringEncoder(e *encodeState, v reflect.Value, quoted bool) {
-	if v.Type() == numberType {
-		numStr := v.String()
-		if numStr == "" {
-			numStr = "0" // Number's zero-val
-		}
-		e.WriteString(numStr)
-		return
-	}
-	if quoted {
-		sb, err := Marshal(v.String())
-		if err != nil {
-			e.error(err)
-		}
-		e.string(string(sb))
-	} else {
-		e.string(v.String())
-	}
-}
-
-func interfaceEncoder(e *encodeState, v reflect.Value, quoted bool) {
-	if v.IsNil() {
-		e.WriteString("null")
-		return
-	}
-	e.reflectValue(v.Elem())
-}
-
-func unsupportedTypeEncoder(e *encodeState, v reflect.Value, quoted bool) {
-	e.error(&UnsupportedTypeError{v.Type()})
-}
-
-type structEncoder struct {
-	fields    []field
-	fieldEncs []encoderFunc
-}
-
-func (se *structEncoder) encode(e *encodeState, v reflect.Value, quoted bool) {
-	e.WriteByte('{')
-	first := true
-	for i, f := range se.fields {
-		fv := fieldByIndex(v, f.index)
-		if !fv.IsValid() || f.omitEmpty && isEmptyValue(fv) {
-			continue
-		}
-		if first {
-			first = false
-		} else {
-			e.WriteByte(',')
-		}
-		e.string(f.name)
-		e.WriteByte(':')
-		se.fieldEncs[i](e, fv, f.quoted)
-	}
-	e.WriteByte('}')
-}
-
-func newStructEncoder(t reflect.Type) encoderFunc {
-	fields := cachedTypeFields(t)
-	se := &structEncoder{
-		fields:    fields,
-		fieldEncs: make([]encoderFunc, len(fields)),
-	}
-	for i, f := range fields {
-		se.fieldEncs[i] = typeEncoder(typeByIndex(t, f.index))
-	}
-	return se.encode
-}
-
-type mapEncoder struct {
-	elemEnc encoderFunc
-}
-
-func (me *mapEncoder) encode(e *encodeState, v reflect.Value, _ bool) {
-	if v.IsNil() {
-		e.WriteString("null")
-		return
-	}
-	e.WriteByte('{')
-	var sv stringValues = v.MapKeys()
-	sort.Sort(sv)
-	for i, k := range sv {
-		if i > 0 {
-			e.WriteByte(',')
-		}
-		e.string(k.String())
-		e.WriteByte(':')
-		me.elemEnc(e, v.MapIndex(k), false)
-	}
-	e.WriteByte('}')
-}
-
-func newMapEncoder(t reflect.Type) encoderFunc {
-	if t.Key().Kind() != reflect.String {
-		return unsupportedTypeEncoder
-	}
-	me := &mapEncoder{typeEncoder(t.Elem())}
-	return me.encode
-}
-
-func encodeByteSlice(e *encodeState, v reflect.Value, _ bool) {
-	if v.IsNil() {
-		e.WriteString("null")
-		return
-	}
-	s := v.Bytes()
-	e.WriteByte('"')
-	if len(s) < 1024 {
-		// for small buffers, using Encode directly is much faster.
-		dst := make([]byte, base64.StdEncoding.EncodedLen(len(s)))
-		base64.StdEncoding.Encode(dst, s)
-		e.Write(dst)
-	} else {
-		// for large buffers, avoid unnecessary extra temporary
-		// buffer space.
-		enc := base64.NewEncoder(base64.StdEncoding, e)
-		enc.Write(s)
-		enc.Close()
-	}
-	e.WriteByte('"')
-}
-
-// sliceEncoder just wraps an arrayEncoder, checking to make sure the value isn't nil.
-type sliceEncoder struct {
-	arrayEnc encoderFunc
-}
-
-func (se *sliceEncoder) encode(e *encodeState, v reflect.Value, _ bool) {
-	if v.IsNil() {
-		e.WriteString("null")
-		return
-	}
-	se.arrayEnc(e, v, false)
-}
-
-func newSliceEncoder(t reflect.Type) encoderFunc {
-	// Byte slices get special treatment; arrays don't.
-	if t.Elem().Kind() == reflect.Uint8 {
-		return encodeByteSlice
-	}
-	enc := &sliceEncoder{newArrayEncoder(t)}
-	return enc.encode
-}
-
-type arrayEncoder struct {
-	elemEnc encoderFunc
-}
-
-func (ae *arrayEncoder) encode(e *encodeState, v reflect.Value, _ bool) {
-	e.WriteByte('[')
-	n := v.Len()
-	for i := 0; i < n; i++ {
-		if i > 0 {
-			e.WriteByte(',')
-		}
-		ae.elemEnc(e, v.Index(i), false)
-	}
-	e.WriteByte(']')
-}
-
-func newArrayEncoder(t reflect.Type) encoderFunc {
-	enc := &arrayEncoder{typeEncoder(t.Elem())}
-	return enc.encode
-}
-
-type ptrEncoder struct {
-	elemEnc encoderFunc
-}
-
-func (pe *ptrEncoder) encode(e *encodeState, v reflect.Value, _ bool) {
-	if v.IsNil() {
-		e.WriteString("null")
-		return
-	}
-	pe.elemEnc(e, v.Elem(), false)
-}
-
-func newPtrEncoder(t reflect.Type) encoderFunc {
-	enc := &ptrEncoder{typeEncoder(t.Elem())}
-	return enc.encode
-}
-
-type condAddrEncoder struct {
-	canAddrEnc, elseEnc encoderFunc
-}
-
-func (ce *condAddrEncoder) encode(e *encodeState, v reflect.Value, quoted bool) {
-	if v.CanAddr() {
-		ce.canAddrEnc(e, v, quoted)
-	} else {
-		ce.elseEnc(e, v, quoted)
-	}
-}
-
-// newCondAddrEncoder returns an encoder that checks whether its value
-// CanAddr and delegates to canAddrEnc if so, else to elseEnc.
-func newCondAddrEncoder(canAddrEnc, elseEnc encoderFunc) encoderFunc {
-	enc := &condAddrEncoder{canAddrEnc: canAddrEnc, elseEnc: elseEnc}
-	return enc.encode
-}
-
-func isValidTag(s string) bool {
-	if s == "" {
-		return false
-	}
-	for _, c := range s {
-		switch {
-		case strings.ContainsRune("!#$%&()*+-./:<=>?@[]^_{|}~ ", c):
-			// Backslash and quote chars are reserved, but
-			// otherwise any punctuation chars are allowed
-			// in a tag name.
-		default:
-			if !unicode.IsLetter(c) && !unicode.IsDigit(c) {
-				return false
-			}
-		}
-	}
-	return true
-}
-
-func fieldByIndex(v reflect.Value, index []int) reflect.Value {
-	for _, i := range index {
-		if v.Kind() == reflect.Ptr {
-			if v.IsNil() {
-				return reflect.Value{}
-			}
-			v = v.Elem()
-		}
-		v = v.Field(i)
-	}
-	return v
-}
-
-func typeByIndex(t reflect.Type, index []int) reflect.Type {
-	for _, i := range index {
-		if t.Kind() == reflect.Ptr {
-			t = t.Elem()
-		}
-		t = t.Field(i).Type
-	}
-	return t
-}
-
-// stringValues is a slice of reflect.Value holding *reflect.StringValue.
-// It implements the methods to sort by string.
-type stringValues []reflect.Value
-
-func (sv stringValues) Len() int           { return len(sv) }
-func (sv stringValues) Swap(i, j int)      { sv[i], sv[j] = sv[j], sv[i] }
-func (sv stringValues) Less(i, j int) bool { return sv.get(i) < sv.get(j) }
-func (sv stringValues) get(i int) string   { return sv[i].String() }
-
-// NOTE: keep in sync with stringBytes below.
-func (e *encodeState) string(s string) (int, error) {
-	len0 := e.Len()
-	e.WriteByte('"')
-	start := 0
-	for i := 0; i < len(s); {
-		if b := s[i]; b < utf8.RuneSelf {
-			if 0x20 <= b && b != '\\' && b != '"' && b != '<' && b != '>' && b != '&' {
-				i++
-				continue
-			}
-			if start < i {
-				e.WriteString(s[start:i])
-			}
-			switch b {
-			case '\\', '"':
-				e.WriteByte('\\')
-				e.WriteByte(b)
-			case '\n':
-				e.WriteByte('\\')
-				e.WriteByte('n')
-			case '\r':
-				e.WriteByte('\\')
-				e.WriteByte('r')
-			default:
-				// This encodes bytes < 0x20 except for \n and \r,
-				// as well as <, > and &. The latter are escaped because they
-				// can lead to security holes when user-controlled strings
-				// are rendered into JSON and served to some browsers.
-				e.WriteString(`\u00`)
-				e.WriteByte(hex[b>>4])
-				e.WriteByte(hex[b&0xF])
-			}
-			i++
-			start = i
-			continue
-		}
-		c, size := utf8.DecodeRuneInString(s[i:])
-		if c == utf8.RuneError && size == 1 {
-			if start < i {
-				e.WriteString(s[start:i])
-			}
-			e.WriteString(`\ufffd`)
-			i += size
-			start = i
-			continue
-		}
-		// U+2028 is LINE SEPARATOR.
-		// U+2029 is PARAGRAPH SEPARATOR.
-		// They are both technically valid characters in JSON strings,
-		// but don't work in JSONP, which has to be evaluated as JavaScript,
-		// and can lead to security holes there. It is valid JSON to
-		// escape them, so we do so unconditionally.
-		// See http://timelessrepo.com/json-isnt-a-javascript-subset for discussion.
-		if c == '\u2028' || c == '\u2029' {
-			if start < i {
-				e.WriteString(s[start:i])
-			}
-			e.WriteString(`\u202`)
-			e.WriteByte(hex[c&0xF])
-			i += size
-			start = i
-			continue
-		}
-		i += size
-	}
-	if start < len(s) {
-		e.WriteString(s[start:])
-	}
-	e.WriteByte('"')
-	return e.Len() - len0, nil
-}
-
-// NOTE: keep in sync with string above.
-func (e *encodeState) stringBytes(s []byte) (int, error) {
-	len0 := e.Len()
-	e.WriteByte('"')
-	start := 0
-	for i := 0; i < len(s); {
-		if b := s[i]; b < utf8.RuneSelf {
-			if 0x20 <= b && b != '\\' && b != '"' && b != '<' && b != '>' && b != '&' {
-				i++
-				continue
-			}
-			if start < i {
-				e.Write(s[start:i])
-			}
-			switch b {
-			case '\\', '"':
-				e.WriteByte('\\')
-				e.WriteByte(b)
-			case '\n':
-				e.WriteByte('\\')
-				e.WriteByte('n')
-			case '\r':
-				e.WriteByte('\\')
-				e.WriteByte('r')
-			default:
-				// This encodes bytes < 0x20 except for \n and \r,
-				// as well as < and >. The latter are escaped because they
-				// can lead to security holes when user-controlled strings
-				// are rendered into JSON and served to some browsers.
-				e.WriteString(`\u00`)
-				e.WriteByte(hex[b>>4])
-				e.WriteByte(hex[b&0xF])
-			}
-			i++
-			start = i
-			continue
-		}
-		c, size := utf8.DecodeRune(s[i:])
-		if c == utf8.RuneError && size == 1 {
-			if start < i {
-				e.Write(s[start:i])
-			}
-			e.WriteString(`\ufffd`)
-			i += size
-			start = i
-			continue
-		}
-		// U+2028 is LINE SEPARATOR.
-		// U+2029 is PARAGRAPH SEPARATOR.
-		// They are both technically valid characters in JSON strings,
-		// but don't work in JSONP, which has to be evaluated as JavaScript,
-		// and can lead to security holes there. It is valid JSON to
-		// escape them, so we do so unconditionally.
-		// See http://timelessrepo.com/json-isnt-a-javascript-subset for discussion.
-		if c == '\u2028' || c == '\u2029' {
-			if start < i {
-				e.Write(s[start:i])
-			}
-			e.WriteString(`\u202`)
-			e.WriteByte(hex[c&0xF])
-			i += size
-			start = i
-			continue
-		}
-		i += size
-	}
-	if start < len(s) {
-		e.Write(s[start:])
-	}
-	e.WriteByte('"')
-	return e.Len() - len0, nil
-}
-
-// A field represents a single field found in a struct.
-type field struct {
-	name      string
-	nameBytes []byte                 // []byte(name)
-	equalFold func(s, t []byte) bool // bytes.EqualFold or equivalent
-
-	tag       bool
-	index     []int
-	typ       reflect.Type
-	omitEmpty bool
-	quoted    bool
-}
-
-func fillField(f field) field {
-	f.nameBytes = []byte(f.name)
-	f.equalFold = foldFunc(f.nameBytes)
-	return f
-}
-
-// byName sorts field by name, breaking ties with depth,
-// then breaking ties with "name came from json tag", then
-// breaking ties with index sequence.
-type byName []field
-
-func (x byName) Len() int { return len(x) }
-
-func (x byName) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
-
-func (x byName) Less(i, j int) bool {
-	if x[i].name != x[j].name {
-		return x[i].name < x[j].name
-	}
-	if len(x[i].index) != len(x[j].index) {
-		return len(x[i].index) < len(x[j].index)
-	}
-	if x[i].tag != x[j].tag {
-		return x[i].tag
-	}
-	return byIndex(x).Less(i, j)
-}
-
-// byIndex sorts field by index sequence.
-type byIndex []field
-
-func (x byIndex) Len() int { return len(x) }
-
-func (x byIndex) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
-
-func (x byIndex) Less(i, j int) bool {
-	for k, xik := range x[i].index {
-		if k >= len(x[j].index) {
-			return false
-		}
-		if xik != x[j].index[k] {
-			return xik < x[j].index[k]
-		}
-	}
-	return len(x[i].index) < len(x[j].index)
-}
-
-// typeFields returns a list of fields that JSON should recognize for the given type.
-// The algorithm is breadth-first search over the set of structs to include - the top struct
-// and then any reachable anonymous structs.
-func typeFields(t reflect.Type) []field {
-	// Anonymous fields to explore at the current level and the next.
-	current := []field{}
-	next := []field{{typ: t}}
-
-	// Count of queued names for current level and the next.
-	count := map[reflect.Type]int{}
-	nextCount := map[reflect.Type]int{}
-
-	// Types already visited at an earlier level.
-	visited := map[reflect.Type]bool{}
-
-	// Fields found.
-	var fields []field
-
-	for len(next) > 0 {
-		current, next = next, current[:0]
-		count, nextCount = nextCount, map[reflect.Type]int{}
-
-		for _, f := range current {
-			if visited[f.typ] {
-				continue
-			}
-			visited[f.typ] = true
-
-			// Scan f.typ for fields to include.
-			for i := 0; i < f.typ.NumField(); i++ {
-				sf := f.typ.Field(i)
-				if sf.PkgPath != "" { // unexported
-					continue
-				}
-				tag := sf.Tag.Get("json")
-				if tag == "-" {
-					continue
-				}
-				name, opts := parseTag(tag)
-				if !isValidTag(name) {
-					name = ""
-				}
-				index := make([]int, len(f.index)+1)
-				copy(index, f.index)
-				index[len(f.index)] = i
-
-				ft := sf.Type
-				if ft.Name() == "" && ft.Kind() == reflect.Ptr {
-					// Follow pointer.
-					ft = ft.Elem()
-				}
-
-				// Record found field and index sequence.
-				if name != "" || !sf.Anonymous || ft.Kind() != reflect.Struct {
-					tagged := name != ""
-					if name == "" {
-						name = sf.Name
-					}
-					fields = append(fields, fillField(field{
-						name:      name,
-						tag:       tagged,
-						index:     index,
-						typ:       ft,
-						omitEmpty: opts.Contains("omitempty"),
-						quoted:    opts.Contains("string"),
-					}))
-					if count[f.typ] > 1 {
-						// If there were multiple instances, add a second,
-						// so that the annihilation code will see a duplicate.
-						// It only cares about the distinction between 1 or 2,
-						// so don't bother generating any more copies.
-						fields = append(fields, fields[len(fields)-1])
-					}
-					continue
-				}
-
-				// Record new anonymous struct to explore in next round.
-				nextCount[ft]++
-				if nextCount[ft] == 1 {
-					next = append(next, fillField(field{name: ft.Name(), index: index, typ: ft}))
-				}
-			}
-		}
-	}
-
-	sort.Sort(byName(fields))
-
-	// Delete all fields that are hidden by the Go rules for embedded fields,
-	// except that fields with JSON tags are promoted.
-
-	// The fields are sorted in primary order of name, secondary order
-	// of field index length. Loop over names; for each name, delete
-	// hidden fields by choosing the one dominant field that survives.
-	out := fields[:0]
-	for advance, i := 0, 0; i < len(fields); i += advance {
-		// One iteration per name.
-		// Find the sequence of fields with the name of this first field.
-		fi := fields[i]
-		name := fi.name
-		for advance = 1; i+advance < len(fields); advance++ {
-			fj := fields[i+advance]
-			if fj.name != name {
-				break
-			}
-		}
-		if advance == 1 { // Only one field with this name
-			out = append(out, fi)
-			continue
-		}
-		dominant, ok := dominantField(fields[i : i+advance])
-		if ok {
-			out = append(out, dominant)
-		}
-	}
-
-	fields = out
-	sort.Sort(byIndex(fields))
-
-	return fields
-}
-
-// dominantField looks through the fields, all of which are known to
-// have the same name, to find the single field that dominates the
-// others using Go's embedding rules, modified by the presence of
-// JSON tags. If there are multiple top-level fields, the boolean
-// will be false: This condition is an error in Go and we skip all
-// the fields.
-func dominantField(fields []field) (field, bool) {
-	// The fields are sorted in increasing index-length order. The winner
-	// must therefore be one with the shortest index length. Drop all
-	// longer entries, which is easy: just truncate the slice.
-	length := len(fields[0].index)
-	tagged := -1 // Index of first tagged field.
-	for i, f := range fields {
-		if len(f.index) > length {
-			fields = fields[:i]
-			break
-		}
-		if f.tag {
-			if tagged >= 0 {
-				// Multiple tagged fields at the same level: conflict.
-				// Return no field.
-				return field{}, false
-			}
-			tagged = i
-		}
-	}
-	if tagged >= 0 {
-		return fields[tagged], true
-	}
-	// All remaining fields have the same length. If there's more than one,
-	// we have a conflict (two fields named "X" at the same level) and we
-	// return no field.
-	if len(fields) > 1 {
-		return field{}, false
-	}
-	return fields[0], true
-}
-
-var fieldCache struct {
-	sync.RWMutex
-	m map[reflect.Type][]field
-}
-
-// cachedTypeFields is like typeFields but uses a cache to avoid repeated work.
-func cachedTypeFields(t reflect.Type) []field {
-	fieldCache.RLock()
-	f := fieldCache.m[t]
-	fieldCache.RUnlock()
-	if f != nil {
-		return f
-	}
-
-	// Compute fields without lock.
-	// Might duplicate effort but won't hold other computations back.
-	f = typeFields(t)
-	if f == nil {
-		f = []field{}
-	}
-
-	fieldCache.Lock()
-	if fieldCache.m == nil {
-		fieldCache.m = map[reflect.Type][]field{}
-	}
-	fieldCache.m[t] = f
-	fieldCache.Unlock()
-	return f
-}
diff --git a/src/pkg/encoding/json/encode_test.go b/src/pkg/encoding/json/encode_test.go
deleted file mode 100644
index 2e89a78..0000000
--- a/src/pkg/encoding/json/encode_test.go
+++ /dev/null
@@ -1,454 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package json
-
-import (
-	"bytes"
-	"math"
-	"reflect"
-	"testing"
-	"unicode"
-)
-
-type Optionals struct {
-	Sr string `json:"sr"`
-	So string `json:"so,omitempty"`
-	Sw string `json:"-"`
-
-	Ir int `json:"omitempty"` // actually named omitempty, not an option
-	Io int `json:"io,omitempty"`
-
-	Slr []string `json:"slr,random"`
-	Slo []string `json:"slo,omitempty"`
-
-	Mr map[string]interface{} `json:"mr"`
-	Mo map[string]interface{} `json:",omitempty"`
-
-	Fr float64 `json:"fr"`
-	Fo float64 `json:"fo,omitempty"`
-
-	Br bool `json:"br"`
-	Bo bool `json:"bo,omitempty"`
-
-	Ur uint `json:"ur"`
-	Uo uint `json:"uo,omitempty"`
-
-	Str struct{} `json:"str"`
-	Sto struct{} `json:"sto,omitempty"`
-}
-
-var optionalsExpected = `{
- "sr": "",
- "omitempty": 0,
- "slr": null,
- "mr": {},
- "fr": 0,
- "br": false,
- "ur": 0,
- "str": {},
- "sto": {}
-}`
-
-func TestOmitEmpty(t *testing.T) {
-	var o Optionals
-	o.Sw = "something"
-	o.Mr = map[string]interface{}{}
-	o.Mo = map[string]interface{}{}
-
-	got, err := MarshalIndent(&o, "", " ")
-	if err != nil {
-		t.Fatal(err)
-	}
-	if got := string(got); got != optionalsExpected {
-		t.Errorf(" got: %s\nwant: %s\n", got, optionalsExpected)
-	}
-}
-
-type StringTag struct {
-	BoolStr bool   `json:",string"`
-	IntStr  int64  `json:",string"`
-	StrStr  string `json:",string"`
-}
-
-var stringTagExpected = `{
- "BoolStr": "true",
- "IntStr": "42",
- "StrStr": "\"xzbit\""
-}`
-
-func TestStringTag(t *testing.T) {
-	var s StringTag
-	s.BoolStr = true
-	s.IntStr = 42
-	s.StrStr = "xzbit"
-	got, err := MarshalIndent(&s, "", " ")
-	if err != nil {
-		t.Fatal(err)
-	}
-	if got := string(got); got != stringTagExpected {
-		t.Fatalf(" got: %s\nwant: %s\n", got, stringTagExpected)
-	}
-
-	// Verify that it round-trips.
-	var s2 StringTag
-	err = NewDecoder(bytes.NewReader(got)).Decode(&s2)
-	if err != nil {
-		t.Fatalf("Decode: %v", err)
-	}
-	if !reflect.DeepEqual(s, s2) {
-		t.Fatalf("decode didn't match.\nsource: %#v\nEncoded as:\n%s\ndecode: %#v", s, string(got), s2)
-	}
-}
-
-// byte slices are special even if they're renamed types.
-type renamedByte byte
-type renamedByteSlice []byte
-type renamedRenamedByteSlice []renamedByte
-
-func TestEncodeRenamedByteSlice(t *testing.T) {
-	s := renamedByteSlice("abc")
-	result, err := Marshal(s)
-	if err != nil {
-		t.Fatal(err)
-	}
-	expect := `"YWJj"`
-	if string(result) != expect {
-		t.Errorf(" got %s want %s", result, expect)
-	}
-	r := renamedRenamedByteSlice("abc")
-	result, err = Marshal(r)
-	if err != nil {
-		t.Fatal(err)
-	}
-	if string(result) != expect {
-		t.Errorf(" got %s want %s", result, expect)
-	}
-}
-
-var unsupportedValues = []interface{}{
-	math.NaN(),
-	math.Inf(-1),
-	math.Inf(1),
-}
-
-func TestUnsupportedValues(t *testing.T) {
-	for _, v := range unsupportedValues {
-		if _, err := Marshal(v); err != nil {
-			if _, ok := err.(*UnsupportedValueError); !ok {
-				t.Errorf("for %v, got %T want UnsupportedValueError", v, err)
-			}
-		} else {
-			t.Errorf("for %v, expected error", v)
-		}
-	}
-}
-
-// Ref has Marshaler and Unmarshaler methods with pointer receiver.
-type Ref int
-
-func (*Ref) MarshalJSON() ([]byte, error) {
-	return []byte(`"ref"`), nil
-}
-
-func (r *Ref) UnmarshalJSON([]byte) error {
-	*r = 12
-	return nil
-}
-
-// Val has Marshaler methods with value receiver.
-type Val int
-
-func (Val) MarshalJSON() ([]byte, error) {
-	return []byte(`"val"`), nil
-}
-
-// RefText has Marshaler and Unmarshaler methods with pointer receiver.
-type RefText int
-
-func (*RefText) MarshalText() ([]byte, error) {
-	return []byte(`"ref"`), nil
-}
-
-func (r *RefText) UnmarshalText([]byte) error {
-	*r = 13
-	return nil
-}
-
-// ValText has Marshaler methods with value receiver.
-type ValText int
-
-func (ValText) MarshalText() ([]byte, error) {
-	return []byte(`"val"`), nil
-}
-
-func TestRefValMarshal(t *testing.T) {
-	var s = struct {
-		R0 Ref
-		R1 *Ref
-		R2 RefText
-		R3 *RefText
-		V0 Val
-		V1 *Val
-		V2 ValText
-		V3 *ValText
-	}{
-		R0: 12,
-		R1: new(Ref),
-		R2: 14,
-		R3: new(RefText),
-		V0: 13,
-		V1: new(Val),
-		V2: 15,
-		V3: new(ValText),
-	}
-	const want = `{"R0":"ref","R1":"ref","R2":"\"ref\"","R3":"\"ref\"","V0":"val","V1":"val","V2":"\"val\"","V3":"\"val\""}`
-	b, err := Marshal(&s)
-	if err != nil {
-		t.Fatalf("Marshal: %v", err)
-	}
-	if got := string(b); got != want {
-		t.Errorf("got %q, want %q", got, want)
-	}
-}
-
-// C implements Marshaler and returns unescaped JSON.
-type C int
-
-func (C) MarshalJSON() ([]byte, error) {
-	return []byte(`"<&>"`), nil
-}
-
-// CText implements Marshaler and returns unescaped text.
-type CText int
-
-func (CText) MarshalText() ([]byte, error) {
-	return []byte(`"<&>"`), nil
-}
-
-func TestMarshalerEscaping(t *testing.T) {
-	var c C
-	want := `"\u003c\u0026\u003e"`
-	b, err := Marshal(c)
-	if err != nil {
-		t.Fatalf("Marshal(c): %v", err)
-	}
-	if got := string(b); got != want {
-		t.Errorf("Marshal(c) = %#q, want %#q", got, want)
-	}
-
-	var ct CText
-	want = `"\"\u003c\u0026\u003e\""`
-	b, err = Marshal(ct)
-	if err != nil {
-		t.Fatalf("Marshal(ct): %v", err)
-	}
-	if got := string(b); got != want {
-		t.Errorf("Marshal(ct) = %#q, want %#q", got, want)
-	}
-}
-
-type IntType int
-
-type MyStruct struct {
-	IntType
-}
-
-func TestAnonymousNonstruct(t *testing.T) {
-	var i IntType = 11
-	a := MyStruct{i}
-	const want = `{"IntType":11}`
-
-	b, err := Marshal(a)
-	if err != nil {
-		t.Fatalf("Marshal: %v", err)
-	}
-	if got := string(b); got != want {
-		t.Errorf("got %q, want %q", got, want)
-	}
-}
-
-type BugA struct {
-	S string
-}
-
-type BugB struct {
-	BugA
-	S string
-}
-
-type BugC struct {
-	S string
-}
-
-// Legal Go: We never use the repeated embedded field (S).
-type BugX struct {
-	A int
-	BugA
-	BugB
-}
-
-// Issue 5245.
-func TestEmbeddedBug(t *testing.T) {
-	v := BugB{
-		BugA{"A"},
-		"B",
-	}
-	b, err := Marshal(v)
-	if err != nil {
-		t.Fatal("Marshal:", err)
-	}
-	want := `{"S":"B"}`
-	got := string(b)
-	if got != want {
-		t.Fatalf("Marshal: got %s want %s", got, want)
-	}
-	// Now check that the duplicate field, S, does not appear.
-	x := BugX{
-		A: 23,
-	}
-	b, err = Marshal(x)
-	if err != nil {
-		t.Fatal("Marshal:", err)
-	}
-	want = `{"A":23}`
-	got = string(b)
-	if got != want {
-		t.Fatalf("Marshal: got %s want %s", got, want)
-	}
-}
-
-type BugD struct { // Same as BugA after tagging.
-	XXX string `json:"S"`
-}
-
-// BugD's tagged S field should dominate BugA's.
-type BugY struct {
-	BugA
-	BugD
-}
-
-// Test that a field with a tag dominates untagged fields.
-func TestTaggedFieldDominates(t *testing.T) {
-	v := BugY{
-		BugA{"BugA"},
-		BugD{"BugD"},
-	}
-	b, err := Marshal(v)
-	if err != nil {
-		t.Fatal("Marshal:", err)
-	}
-	want := `{"S":"BugD"}`
-	got := string(b)
-	if got != want {
-		t.Fatalf("Marshal: got %s want %s", got, want)
-	}
-}
-
-// There are no tags here, so S should not appear.
-type BugZ struct {
-	BugA
-	BugC
-	BugY // Contains a tagged S field through BugD; should not dominate.
-}
-
-func TestDuplicatedFieldDisappears(t *testing.T) {
-	v := BugZ{
-		BugA{"BugA"},
-		BugC{"BugC"},
-		BugY{
-			BugA{"nested BugA"},
-			BugD{"nested BugD"},
-		},
-	}
-	b, err := Marshal(v)
-	if err != nil {
-		t.Fatal("Marshal:", err)
-	}
-	want := `{}`
-	got := string(b)
-	if got != want {
-		t.Fatalf("Marshal: got %s want %s", got, want)
-	}
-}
-
-func TestStringBytes(t *testing.T) {
-	// Test that encodeState.stringBytes and encodeState.string use the same encoding.
-	es := &encodeState{}
-	var r []rune
-	for i := '\u0000'; i <= unicode.MaxRune; i++ {
-		r = append(r, i)
-	}
-	s := string(r) + "\xff\xff\xffhello" // some invalid UTF-8 too
-	_, err := es.string(s)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	esBytes := &encodeState{}
-	_, err = esBytes.stringBytes([]byte(s))
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	enc := es.Buffer.String()
-	encBytes := esBytes.Buffer.String()
-	if enc != encBytes {
-		i := 0
-		for i < len(enc) && i < len(encBytes) && enc[i] == encBytes[i] {
-			i++
-		}
-		enc = enc[i:]
-		encBytes = encBytes[i:]
-		i = 0
-		for i < len(enc) && i < len(encBytes) && enc[len(enc)-i-1] == encBytes[len(encBytes)-i-1] {
-			i++
-		}
-		enc = enc[:len(enc)-i]
-		encBytes = encBytes[:len(encBytes)-i]
-
-		if len(enc) > 20 {
-			enc = enc[:20] + "..."
-		}
-		if len(encBytes) > 20 {
-			encBytes = encBytes[:20] + "..."
-		}
-
-		t.Errorf("encodings differ at %#q vs %#q", enc, encBytes)
-	}
-}
-
-func TestIssue6458(t *testing.T) {
-	type Foo struct {
-		M RawMessage
-	}
-	x := Foo{RawMessage(`"foo"`)}
-
-	b, err := Marshal(&x)
-	if err != nil {
-		t.Fatal(err)
-	}
-	if want := `{"M":"foo"}`; string(b) != want {
-		t.Errorf("Marshal(&x) = %#q; want %#q", b, want)
-	}
-
-	b, err = Marshal(x)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	if want := `{"M":"ImZvbyI="}`; string(b) != want {
-		t.Errorf("Marshal(x) = %#q; want %#q", b, want)
-	}
-}
-
-func TestHTMLEscape(t *testing.T) {
-	var b, want bytes.Buffer
-	m := `{"M":"<html>foo &` + "\xe2\x80\xa8 \xe2\x80\xa9" + `</html>"}`
-	want.Write([]byte(`{"M":"\u003chtml\u003efoo \u0026\u2028 \u2029\u003c/html\u003e"}`))
-	HTMLEscape(&b, []byte(m))
-	if !bytes.Equal(b.Bytes(), want.Bytes()) {
-		t.Errorf("HTMLEscape(&b, []byte(m)) = %s; want %s", b.Bytes(), want.Bytes())
-	}
-}
diff --git a/src/pkg/encoding/json/stream.go b/src/pkg/encoding/json/stream.go
deleted file mode 100644
index 1cb289f..0000000
--- a/src/pkg/encoding/json/stream.go
+++ /dev/null
@@ -1,201 +0,0 @@
-// Copyright 2010 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package json
-
-import (
-	"bytes"
-	"errors"
-	"io"
-)
-
-// A Decoder reads and decodes JSON objects from an input stream.
-type Decoder struct {
-	r    io.Reader
-	buf  []byte
-	d    decodeState
-	scan scanner
-	err  error
-}
-
-// NewDecoder returns a new decoder that reads from r.
-//
-// The decoder introduces its own buffering and may
-// read data from r beyond the JSON values requested.
-func NewDecoder(r io.Reader) *Decoder {
-	return &Decoder{r: r}
-}
-
-// UseNumber causes the Decoder to unmarshal a number into an interface{} as a
-// Number instead of as a float64.
-func (dec *Decoder) UseNumber() { dec.d.useNumber = true }
-
-// Decode reads the next JSON-encoded value from its
-// input and stores it in the value pointed to by v.
-//
-// See the documentation for Unmarshal for details about
-// the conversion of JSON into a Go value.
-func (dec *Decoder) Decode(v interface{}) error {
-	if dec.err != nil {
-		return dec.err
-	}
-
-	n, err := dec.readValue()
-	if err != nil {
-		return err
-	}
-
-	// Don't save err from unmarshal into dec.err:
-	// the connection is still usable since we read a complete JSON
-	// object from it before the error happened.
-	dec.d.init(dec.buf[0:n])
-	err = dec.d.unmarshal(v)
-
-	// Slide rest of data down.
-	rest := copy(dec.buf, dec.buf[n:])
-	dec.buf = dec.buf[0:rest]
-
-	return err
-}
-
-// Buffered returns a reader of the data remaining in the Decoder's
-// buffer. The reader is valid until the next call to Decode.
-func (dec *Decoder) Buffered() io.Reader {
-	return bytes.NewReader(dec.buf)
-}
-
-// readValue reads a JSON value into dec.buf.
-// It returns the length of the encoding.
-func (dec *Decoder) readValue() (int, error) {
-	dec.scan.reset()
-
-	scanp := 0
-	var err error
-Input:
-	for {
-		// Look in the buffer for a new value.
-		for i, c := range dec.buf[scanp:] {
-			dec.scan.bytes++
-			v := dec.scan.step(&dec.scan, int(c))
-			if v == scanEnd {
-				scanp += i
-				break Input
-			}
-			// scanEnd is delayed one byte.
-			// We might block trying to get that byte from src,
-			// so instead invent a space byte.
-			if (v == scanEndObject || v == scanEndArray) && dec.scan.step(&dec.scan, ' ') == scanEnd {
-				scanp += i + 1
-				break Input
-			}
-			if v == scanError {
-				dec.err = dec.scan.err
-				return 0, dec.scan.err
-			}
-		}
-		scanp = len(dec.buf)
-
-		// Did the last read have an error?
-		// Delayed until now to allow buffer scan.
-		if err != nil {
-			if err == io.EOF {
-				if dec.scan.step(&dec.scan, ' ') == scanEnd {
-					break Input
-				}
-				if nonSpace(dec.buf) {
-					err = io.ErrUnexpectedEOF
-				}
-			}
-			dec.err = err
-			return 0, err
-		}
-
-		// Make room to read more into the buffer.
-		const minRead = 512
-		if cap(dec.buf)-len(dec.buf) < minRead {
-			newBuf := make([]byte, len(dec.buf), 2*cap(dec.buf)+minRead)
-			copy(newBuf, dec.buf)
-			dec.buf = newBuf
-		}
-
-		// Read.  Delay error for next iteration (after scan).
-		var n int
-		n, err = dec.r.Read(dec.buf[len(dec.buf):cap(dec.buf)])
-		dec.buf = dec.buf[0 : len(dec.buf)+n]
-	}
-	return scanp, nil
-}
-
-func nonSpace(b []byte) bool {
-	for _, c := range b {
-		if !isSpace(rune(c)) {
-			return true
-		}
-	}
-	return false
-}
-
-// An Encoder writes JSON objects to an output stream.
-type Encoder struct {
-	w   io.Writer
-	e   encodeState
-	err error
-}
-
-// NewEncoder returns a new encoder that writes to w.
-func NewEncoder(w io.Writer) *Encoder {
-	return &Encoder{w: w}
-}
-
-// Encode writes the JSON encoding of v to the stream,
-// followed by a newline character.
-//
-// See the documentation for Marshal for details about the
-// conversion of Go values to JSON.
-func (enc *Encoder) Encode(v interface{}) error {
-	if enc.err != nil {
-		return enc.err
-	}
-	e := newEncodeState()
-	err := e.marshal(v)
-	if err != nil {
-		return err
-	}
-
-	// Terminate each value with a newline.
-	// This makes the output look a little nicer
-	// when debugging, and some kind of space
-	// is required if the encoded value was a number,
-	// so that the reader knows there aren't more
-	// digits coming.
-	e.WriteByte('\n')
-
-	if _, err = enc.w.Write(e.Bytes()); err != nil {
-		enc.err = err
-	}
-	encodeStatePool.Put(e)
-	return err
-}
-
-// RawMessage is a raw encoded JSON object.
-// It implements Marshaler and Unmarshaler and can
-// be used to delay JSON decoding or precompute a JSON encoding.
-type RawMessage []byte
-
-// MarshalJSON returns *m as the JSON encoding of m.
-func (m *RawMessage) MarshalJSON() ([]byte, error) {
-	return *m, nil
-}
-
-// UnmarshalJSON sets *m to a copy of data.
-func (m *RawMessage) UnmarshalJSON(data []byte) error {
-	if m == nil {
-		return errors.New("json.RawMessage: UnmarshalJSON on nil pointer")
-	}
-	*m = append((*m)[0:0], data...)
-	return nil
-}
-
-var _ Marshaler = (*RawMessage)(nil)
-var _ Unmarshaler = (*RawMessage)(nil)
diff --git a/src/pkg/encoding/xml/xml.go b/src/pkg/encoding/xml/xml.go
deleted file mode 100644
index b473cb8..0000000
--- a/src/pkg/encoding/xml/xml.go
+++ /dev/null
@@ -1,1935 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package xml implements a simple XML 1.0 parser that
-// understands XML name spaces.
-package xml
-
-// References:
-//    Annotated XML spec: http://www.xml.com/axml/testaxml.htm
-//    XML name spaces: http://www.w3.org/TR/REC-xml-names/
-
-// TODO(rsc):
-//	Test error handling.
-
-import (
-	"bufio"
-	"bytes"
-	"errors"
-	"fmt"
-	"io"
-	"strconv"
-	"strings"
-	"unicode"
-	"unicode/utf8"
-)
-
-// A SyntaxError represents a syntax error in the XML input stream.
-type SyntaxError struct {
-	Msg  string
-	Line int
-}
-
-func (e *SyntaxError) Error() string {
-	return "XML syntax error on line " + strconv.Itoa(e.Line) + ": " + e.Msg
-}
-
-// A Name represents an XML name (Local) annotated
-// with a name space identifier (Space).
-// In tokens returned by Decoder.Token, the Space identifier
-// is given as a canonical URL, not the short prefix used
-// in the document being parsed.
-type Name struct {
-	Space, Local string
-}
-
-// An Attr represents an attribute in an XML element (Name=Value).
-type Attr struct {
-	Name  Name
-	Value string
-}
-
-// A Token is an interface holding one of the token types:
-// StartElement, EndElement, CharData, Comment, ProcInst, or Directive.
-type Token interface{}
-
-// A StartElement represents an XML start element.
-type StartElement struct {
-	Name Name
-	Attr []Attr
-}
-
-func (e StartElement) Copy() StartElement {
-	attrs := make([]Attr, len(e.Attr))
-	copy(attrs, e.Attr)
-	e.Attr = attrs
-	return e
-}
-
-// End returns the corresponding XML end element.
-func (e StartElement) End() EndElement {
-	return EndElement{e.Name}
-}
-
-// An EndElement represents an XML end element.
-type EndElement struct {
-	Name Name
-}
-
-// A CharData represents XML character data (raw text),
-// in which XML escape sequences have been replaced by
-// the characters they represent.
-type CharData []byte
-
-func makeCopy(b []byte) []byte {
-	b1 := make([]byte, len(b))
-	copy(b1, b)
-	return b1
-}
-
-func (c CharData) Copy() CharData { return CharData(makeCopy(c)) }
-
-// A Comment represents an XML comment of the form <!--comment-->.
-// The bytes do not include the <!-- and --> comment markers.
-type Comment []byte
-
-func (c Comment) Copy() Comment { return Comment(makeCopy(c)) }
-
-// A ProcInst represents an XML processing instruction of the form <?target inst?>
-type ProcInst struct {
-	Target string
-	Inst   []byte
-}
-
-func (p ProcInst) Copy() ProcInst {
-	p.Inst = makeCopy(p.Inst)
-	return p
-}
-
-// A Directive represents an XML directive of the form <!text>.
-// The bytes do not include the <! and > markers.
-type Directive []byte
-
-func (d Directive) Copy() Directive { return Directive(makeCopy(d)) }
-
-// CopyToken returns a copy of a Token.
-func CopyToken(t Token) Token {
-	switch v := t.(type) {
-	case CharData:
-		return v.Copy()
-	case Comment:
-		return v.Copy()
-	case Directive:
-		return v.Copy()
-	case ProcInst:
-		return v.Copy()
-	case StartElement:
-		return v.Copy()
-	}
-	return t
-}
-
-// A Decoder represents an XML parser reading a particular input stream.
-// The parser assumes that its input is encoded in UTF-8.
-type Decoder struct {
-	// Strict defaults to true, enforcing the requirements
-	// of the XML specification.
-	// If set to false, the parser allows input containing common
-	// mistakes:
-	//	* If an element is missing an end tag, the parser invents
-	//	  end tags as necessary to keep the return values from Token
-	//	  properly balanced.
-	//	* In attribute values and character data, unknown or malformed
-	//	  character entities (sequences beginning with &) are left alone.
-	//
-	// Setting:
-	//
-	//	d.Strict = false;
-	//	d.AutoClose = HTMLAutoClose;
-	//	d.Entity = HTMLEntity
-	//
-	// creates a parser that can handle typical HTML.
-	//
-	// Strict mode does not enforce the requirements of the XML name spaces TR.
-	// In particular it does not reject name space tags using undefined prefixes.
-	// Such tags are recorded with the unknown prefix as the name space URL.
-	Strict bool
-
-	// When Strict == false, AutoClose indicates a set of elements to
-	// consider closed immediately after they are opened, regardless
-	// of whether an end element is present.
-	AutoClose []string
-
-	// Entity can be used to map non-standard entity names to string replacements.
-	// The parser behaves as if these standard mappings are present in the map,
-	// regardless of the actual map content:
-	//
-	//	"lt": "<",
-	//	"gt": ">",
-	//	"amp": "&",
-	//	"apos": "'",
-	//	"quot": `"`,
-	Entity map[string]string
-
-	// CharsetReader, if non-nil, defines a function to generate
-	// charset-conversion readers, converting from the provided
-	// non-UTF-8 charset into UTF-8. If CharsetReader is nil or
-	// returns an error, parsing stops with an error. One of the
-	// the CharsetReader's result values must be non-nil.
-	CharsetReader func(charset string, input io.Reader) (io.Reader, error)
-
-	// DefaultSpace sets the default name space used for unadorned tags,
-	// as if the entire XML stream were wrapped in an element containing
-	// the attribute xmlns="DefaultSpace".
-	DefaultSpace string
-
-	r              io.ByteReader
-	buf            bytes.Buffer
-	saved          *bytes.Buffer
-	stk            *stack
-	free           *stack
-	needClose      bool
-	toClose        Name
-	nextToken      Token
-	nextByte       int
-	ns             map[string]string
-	err            error
-	line           int
-	unmarshalDepth int
-}
-
-// NewDecoder creates a new XML parser reading from r.
-// If r does not implement io.ByteReader, NewDecoder will
-// do its own buffering.
-func NewDecoder(r io.Reader) *Decoder {
-	d := &Decoder{
-		ns:       make(map[string]string),
-		nextByte: -1,
-		line:     1,
-		Strict:   true,
-	}
-	d.switchToReader(r)
-	return d
-}
-
-// Token returns the next XML token in the input stream.
-// At the end of the input stream, Token returns nil, io.EOF.
-//
-// Slices of bytes in the returned token data refer to the
-// parser's internal buffer and remain valid only until the next
-// call to Token.  To acquire a copy of the bytes, call CopyToken
-// or the token's Copy method.
-//
-// Token expands self-closing elements such as <br/>
-// into separate start and end elements returned by successive calls.
-//
-// Token guarantees that the StartElement and EndElement
-// tokens it returns are properly nested and matched:
-// if Token encounters an unexpected end element,
-// it will return an error.
-//
-// Token implements XML name spaces as described by
-// http://www.w3.org/TR/REC-xml-names/.  Each of the
-// Name structures contained in the Token has the Space
-// set to the URL identifying its name space when known.
-// If Token encounters an unrecognized name space prefix,
-// it uses the prefix as the Space rather than report an error.
-func (d *Decoder) Token() (t Token, err error) {
-	if d.stk != nil && d.stk.kind == stkEOF {
-		err = io.EOF
-		return
-	}
-	if d.nextToken != nil {
-		t = d.nextToken
-		d.nextToken = nil
-	} else if t, err = d.rawToken(); err != nil {
-		return
-	}
-
-	if !d.Strict {
-		if t1, ok := d.autoClose(t); ok {
-			d.nextToken = t
-			t = t1
-		}
-	}
-	switch t1 := t.(type) {
-	case StartElement:
-		// In XML name spaces, the translations listed in the
-		// attributes apply to the element name and
-		// to the other attribute names, so process
-		// the translations first.
-		for _, a := range t1.Attr {
-			if a.Name.Space == "xmlns" {
-				v, ok := d.ns[a.Name.Local]
-				d.pushNs(a.Name.Local, v, ok)
-				d.ns[a.Name.Local] = a.Value
-			}
-			if a.Name.Space == "" && a.Name.Local == "xmlns" {
-				// Default space for untagged names
-				v, ok := d.ns[""]
-				d.pushNs("", v, ok)
-				d.ns[""] = a.Value
-			}
-		}
-
-		d.translate(&t1.Name, true)
-		for i := range t1.Attr {
-			d.translate(&t1.Attr[i].Name, false)
-		}
-		d.pushElement(t1.Name)
-		t = t1
-
-	case EndElement:
-		d.translate(&t1.Name, true)
-		if !d.popElement(&t1) {
-			return nil, d.err
-		}
-		t = t1
-	}
-	return
-}
-
-const xmlURL = "http://www.w3.org/XML/1998/namespace"
-
-// Apply name space translation to name n.
-// The default name space (for Space=="")
-// applies only to element names, not to attribute names.
-func (d *Decoder) translate(n *Name, isElementName bool) {
-	switch {
-	case n.Space == "xmlns":
-		return
-	case n.Space == "" && !isElementName:
-		return
-	case n.Space == "xml":
-		n.Space = xmlURL
-	case n.Space == "" && n.Local == "xmlns":
-		return
-	}
-	if v, ok := d.ns[n.Space]; ok {
-		n.Space = v
-	} else if n.Space == "" {
-		n.Space = d.DefaultSpace
-	}
-}
-
-func (d *Decoder) switchToReader(r io.Reader) {
-	// Get efficient byte at a time reader.
-	// Assume that if reader has its own
-	// ReadByte, it's efficient enough.
-	// Otherwise, use bufio.
-	if rb, ok := r.(io.ByteReader); ok {
-		d.r = rb
-	} else {
-		d.r = bufio.NewReader(r)
-	}
-}
-
-// Parsing state - stack holds old name space translations
-// and the current set of open elements.  The translations to pop when
-// ending a given tag are *below* it on the stack, which is
-// more work but forced on us by XML.
-type stack struct {
-	next *stack
-	kind int
-	name Name
-	ok   bool
-}
-
-const (
-	stkStart = iota
-	stkNs
-	stkEOF
-)
-
-func (d *Decoder) push(kind int) *stack {
-	s := d.free
-	if s != nil {
-		d.free = s.next
-	} else {
-		s = new(stack)
-	}
-	s.next = d.stk
-	s.kind = kind
-	d.stk = s
-	return s
-}
-
-func (d *Decoder) pop() *stack {
-	s := d.stk
-	if s != nil {
-		d.stk = s.next
-		s.next = d.free
-		d.free = s
-	}
-	return s
-}
-
-// Record that after the current element is finished
-// (that element is already pushed on the stack)
-// Token should return EOF until popEOF is called.
-func (d *Decoder) pushEOF() {
-	// Walk down stack to find Start.
-	// It might not be the top, because there might be stkNs
-	// entries above it.
-	start := d.stk
-	for start.kind != stkStart {
-		start = start.next
-	}
-	// The stkNs entries below a start are associated with that
-	// element too; skip over them.
-	for start.next != nil && start.next.kind == stkNs {
-		start = start.next
-	}
-	s := d.free
-	if s != nil {
-		d.free = s.next
-	} else {
-		s = new(stack)
-	}
-	s.kind = stkEOF
-	s.next = start.next
-	start.next = s
-}
-
-// Undo a pushEOF.
-// The element must have been finished, so the EOF should be at the top of the stack.
-func (d *Decoder) popEOF() bool {
-	if d.stk == nil || d.stk.kind != stkEOF {
-		return false
-	}
-	d.pop()
-	return true
-}
-
-// Record that we are starting an element with the given name.
-func (d *Decoder) pushElement(name Name) {
-	s := d.push(stkStart)
-	s.name = name
-}
-
-// Record that we are changing the value of ns[local].
-// The old value is url, ok.
-func (d *Decoder) pushNs(local string, url string, ok bool) {
-	s := d.push(stkNs)
-	s.name.Local = local
-	s.name.Space = url
-	s.ok = ok
-}
-
-// Creates a SyntaxError with the current line number.
-func (d *Decoder) syntaxError(msg string) error {
-	return &SyntaxError{Msg: msg, Line: d.line}
-}
-
-// Record that we are ending an element with the given name.
-// The name must match the record at the top of the stack,
-// which must be a pushElement record.
-// After popping the element, apply any undo records from
-// the stack to restore the name translations that existed
-// before we saw this element.
-func (d *Decoder) popElement(t *EndElement) bool {
-	s := d.pop()
-	name := t.Name
-	switch {
-	case s == nil || s.kind != stkStart:
-		d.err = d.syntaxError("unexpected end element </" + name.Local + ">")
-		return false
-	case s.name.Local != name.Local:
-		if !d.Strict {
-			d.needClose = true
-			d.toClose = t.Name
-			t.Name = s.name
-			return true
-		}
-		d.err = d.syntaxError("element <" + s.name.Local + "> closed by </" + name.Local + ">")
-		return false
-	case s.name.Space != name.Space:
-		d.err = d.syntaxError("element <" + s.name.Local + "> in space " + s.name.Space +
-			"closed by </" + name.Local + "> in space " + name.Space)
-		return false
-	}
-
-	// Pop stack until a Start or EOF is on the top, undoing the
-	// translations that were associated with the element we just closed.
-	for d.stk != nil && d.stk.kind != stkStart && d.stk.kind != stkEOF {
-		s := d.pop()
-		if s.ok {
-			d.ns[s.name.Local] = s.name.Space
-		} else {
-			delete(d.ns, s.name.Local)
-		}
-	}
-
-	return true
-}
-
-// If the top element on the stack is autoclosing and
-// t is not the end tag, invent the end tag.
-func (d *Decoder) autoClose(t Token) (Token, bool) {
-	if d.stk == nil || d.stk.kind != stkStart {
-		return nil, false
-	}
-	name := strings.ToLower(d.stk.name.Local)
-	for _, s := range d.AutoClose {
-		if strings.ToLower(s) == name {
-			// This one should be auto closed if t doesn't close it.
-			et, ok := t.(EndElement)
-			if !ok || et.Name.Local != name {
-				return EndElement{d.stk.name}, true
-			}
-			break
-		}
-	}
-	return nil, false
-}
-
-var errRawToken = errors.New("xml: cannot use RawToken from UnmarshalXML method")
-
-// RawToken is like Token but does not verify that
-// start and end elements match and does not translate
-// name space prefixes to their corresponding URLs.
-func (d *Decoder) RawToken() (Token, error) {
-	if d.unmarshalDepth > 0 {
-		return nil, errRawToken
-	}
-	return d.rawToken()
-}
-
-func (d *Decoder) rawToken() (Token, error) {
-	if d.err != nil {
-		return nil, d.err
-	}
-	if d.needClose {
-		// The last element we read was self-closing and
-		// we returned just the StartElement half.
-		// Return the EndElement half now.
-		d.needClose = false
-		return EndElement{d.toClose}, nil
-	}
-
-	b, ok := d.getc()
-	if !ok {
-		return nil, d.err
-	}
-
-	if b != '<' {
-		// Text section.
-		d.ungetc(b)
-		data := d.text(-1, false)
-		if data == nil {
-			return nil, d.err
-		}
-		return CharData(data), nil
-	}
-
-	if b, ok = d.mustgetc(); !ok {
-		return nil, d.err
-	}
-	switch b {
-	case '/':
-		// </: End element
-		var name Name
-		if name, ok = d.nsname(); !ok {
-			if d.err == nil {
-				d.err = d.syntaxError("expected element name after </")
-			}
-			return nil, d.err
-		}
-		d.space()
-		if b, ok = d.mustgetc(); !ok {
-			return nil, d.err
-		}
-		if b != '>' {
-			d.err = d.syntaxError("invalid characters between </" + name.Local + " and >")
-			return nil, d.err
-		}
-		return EndElement{name}, nil
-
-	case '?':
-		// <?: Processing instruction.
-		// TODO(rsc): Should parse the <?xml declaration to make sure the version is 1.0.
-		var target string
-		if target, ok = d.name(); !ok {
-			if d.err == nil {
-				d.err = d.syntaxError("expected target name after <?")
-			}
-			return nil, d.err
-		}
-		d.space()
-		d.buf.Reset()
-		var b0 byte
-		for {
-			if b, ok = d.mustgetc(); !ok {
-				return nil, d.err
-			}
-			d.buf.WriteByte(b)
-			if b0 == '?' && b == '>' {
-				break
-			}
-			b0 = b
-		}
-		data := d.buf.Bytes()
-		data = data[0 : len(data)-2] // chop ?>
-
-		if target == "xml" {
-			enc := procInstEncoding(string(data))
-			if enc != "" && enc != "utf-8" && enc != "UTF-8" {
-				if d.CharsetReader == nil {
-					d.err = fmt.Errorf("xml: encoding %q declared but Decoder.CharsetReader is nil", enc)
-					return nil, d.err
-				}
-				newr, err := d.CharsetReader(enc, d.r.(io.Reader))
-				if err != nil {
-					d.err = fmt.Errorf("xml: opening charset %q: %v", enc, err)
-					return nil, d.err
-				}
-				if newr == nil {
-					panic("CharsetReader returned a nil Reader for charset " + enc)
-				}
-				d.switchToReader(newr)
-			}
-		}
-		return ProcInst{target, data}, nil
-
-	case '!':
-		// <!: Maybe comment, maybe CDATA.
-		if b, ok = d.mustgetc(); !ok {
-			return nil, d.err
-		}
-		switch b {
-		case '-': // <!-
-			// Probably <!-- for a comment.
-			if b, ok = d.mustgetc(); !ok {
-				return nil, d.err
-			}
-			if b != '-' {
-				d.err = d.syntaxError("invalid sequence <!- not part of <!--")
-				return nil, d.err
-			}
-			// Look for terminator.
-			d.buf.Reset()
-			var b0, b1 byte
-			for {
-				if b, ok = d.mustgetc(); !ok {
-					return nil, d.err
-				}
-				d.buf.WriteByte(b)
-				if b0 == '-' && b1 == '-' && b == '>' {
-					break
-				}
-				b0, b1 = b1, b
-			}
-			data := d.buf.Bytes()
-			data = data[0 : len(data)-3] // chop -->
-			return Comment(data), nil
-
-		case '[': // <![
-			// Probably <![CDATA[.
-			for i := 0; i < 6; i++ {
-				if b, ok = d.mustgetc(); !ok {
-					return nil, d.err
-				}
-				if b != "CDATA["[i] {
-					d.err = d.syntaxError("invalid <![ sequence")
-					return nil, d.err
-				}
-			}
-			// Have <![CDATA[.  Read text until ]]>.
-			data := d.text(-1, true)
-			if data == nil {
-				return nil, d.err
-			}
-			return CharData(data), nil
-		}
-
-		// Probably a directive: <!DOCTYPE ...>, <!ENTITY ...>, etc.
-		// We don't care, but accumulate for caller. Quoted angle
-		// brackets do not count for nesting.
-		d.buf.Reset()
-		d.buf.WriteByte(b)
-		inquote := uint8(0)
-		depth := 0
-		for {
-			if b, ok = d.mustgetc(); !ok {
-				return nil, d.err
-			}
-			if inquote == 0 && b == '>' && depth == 0 {
-				break
-			}
-		HandleB:
-			d.buf.WriteByte(b)
-			switch {
-			case b == inquote:
-				inquote = 0
-
-			case inquote != 0:
-				// in quotes, no special action
-
-			case b == '\'' || b == '"':
-				inquote = b
-
-			case b == '>' && inquote == 0:
-				depth--
-
-			case b == '<' && inquote == 0:
-				// Look for <!-- to begin comment.
-				s := "!--"
-				for i := 0; i < len(s); i++ {
-					if b, ok = d.mustgetc(); !ok {
-						return nil, d.err
-					}
-					if b != s[i] {
-						for j := 0; j < i; j++ {
-							d.buf.WriteByte(s[j])
-						}
-						depth++
-						goto HandleB
-					}
-				}
-
-				// Remove < that was written above.
-				d.buf.Truncate(d.buf.Len() - 1)
-
-				// Look for terminator.
-				var b0, b1 byte
-				for {
-					if b, ok = d.mustgetc(); !ok {
-						return nil, d.err
-					}
-					if b0 == '-' && b1 == '-' && b == '>' {
-						break
-					}
-					b0, b1 = b1, b
-				}
-			}
-		}
-		return Directive(d.buf.Bytes()), nil
-	}
-
-	// Must be an open element like <a href="foo">
-	d.ungetc(b)
-
-	var (
-		name  Name
-		empty bool
-		attr  []Attr
-	)
-	if name, ok = d.nsname(); !ok {
-		if d.err == nil {
-			d.err = d.syntaxError("expected element name after <")
-		}
-		return nil, d.err
-	}
-
-	attr = make([]Attr, 0, 4)
-	for {
-		d.space()
-		if b, ok = d.mustgetc(); !ok {
-			return nil, d.err
-		}
-		if b == '/' {
-			empty = true
-			if b, ok = d.mustgetc(); !ok {
-				return nil, d.err
-			}
-			if b != '>' {
-				d.err = d.syntaxError("expected /> in element")
-				return nil, d.err
-			}
-			break
-		}
-		if b == '>' {
-			break
-		}
-		d.ungetc(b)
-
-		n := len(attr)
-		if n >= cap(attr) {
-			nattr := make([]Attr, n, 2*cap(attr))
-			copy(nattr, attr)
-			attr = nattr
-		}
-		attr = attr[0 : n+1]
-		a := &attr[n]
-		if a.Name, ok = d.nsname(); !ok {
-			if d.err == nil {
-				d.err = d.syntaxError("expected attribute name in element")
-			}
-			return nil, d.err
-		}
-		d.space()
-		if b, ok = d.mustgetc(); !ok {
-			return nil, d.err
-		}
-		if b != '=' {
-			if d.Strict {
-				d.err = d.syntaxError("attribute name without = in element")
-				return nil, d.err
-			} else {
-				d.ungetc(b)
-				a.Value = a.Name.Local
-			}
-		} else {
-			d.space()
-			data := d.attrval()
-			if data == nil {
-				return nil, d.err
-			}
-			a.Value = string(data)
-		}
-	}
-	if empty {
-		d.needClose = true
-		d.toClose = name
-	}
-	return StartElement{name, attr}, nil
-}
-
-func (d *Decoder) attrval() []byte {
-	b, ok := d.mustgetc()
-	if !ok {
-		return nil
-	}
-	// Handle quoted attribute values
-	if b == '"' || b == '\'' {
-		return d.text(int(b), false)
-	}
-	// Handle unquoted attribute values for strict parsers
-	if d.Strict {
-		d.err = d.syntaxError("unquoted or missing attribute value in element")
-		return nil
-	}
-	// Handle unquoted attribute values for unstrict parsers
-	d.ungetc(b)
-	d.buf.Reset()
-	for {
-		b, ok = d.mustgetc()
-		if !ok {
-			return nil
-		}
-		// http://www.w3.org/TR/REC-html40/intro/sgmltut.html#h-3.2.2
-		if 'a' <= b && b <= 'z' || 'A' <= b && b <= 'Z' ||
-			'0' <= b && b <= '9' || b == '_' || b == ':' || b == '-' {
-			d.buf.WriteByte(b)
-		} else {
-			d.ungetc(b)
-			break
-		}
-	}
-	return d.buf.Bytes()
-}
-
-// Skip spaces if any
-func (d *Decoder) space() {
-	for {
-		b, ok := d.getc()
-		if !ok {
-			return
-		}
-		switch b {
-		case ' ', '\r', '\n', '\t':
-		default:
-			d.ungetc(b)
-			return
-		}
-	}
-}
-
-// Read a single byte.
-// If there is no byte to read, return ok==false
-// and leave the error in d.err.
-// Maintain line number.
-func (d *Decoder) getc() (b byte, ok bool) {
-	if d.err != nil {
-		return 0, false
-	}
-	if d.nextByte >= 0 {
-		b = byte(d.nextByte)
-		d.nextByte = -1
-	} else {
-		b, d.err = d.r.ReadByte()
-		if d.err != nil {
-			return 0, false
-		}
-		if d.saved != nil {
-			d.saved.WriteByte(b)
-		}
-	}
-	if b == '\n' {
-		d.line++
-	}
-	return b, true
-}
-
-// Return saved offset.
-// If we did ungetc (nextByte >= 0), have to back up one.
-func (d *Decoder) savedOffset() int {
-	n := d.saved.Len()
-	if d.nextByte >= 0 {
-		n--
-	}
-	return n
-}
-
-// Must read a single byte.
-// If there is no byte to read,
-// set d.err to SyntaxError("unexpected EOF")
-// and return ok==false
-func (d *Decoder) mustgetc() (b byte, ok bool) {
-	if b, ok = d.getc(); !ok {
-		if d.err == io.EOF {
-			d.err = d.syntaxError("unexpected EOF")
-		}
-	}
-	return
-}
-
-// Unread a single byte.
-func (d *Decoder) ungetc(b byte) {
-	if b == '\n' {
-		d.line--
-	}
-	d.nextByte = int(b)
-}
-
-var entity = map[string]int{
-	"lt":   '<',
-	"gt":   '>',
-	"amp":  '&',
-	"apos": '\'',
-	"quot": '"',
-}
-
-// Read plain text section (XML calls it character data).
-// If quote >= 0, we are in a quoted string and need to find the matching quote.
-// If cdata == true, we are in a <![CDATA[ section and need to find ]]>.
-// On failure return nil and leave the error in d.err.
-func (d *Decoder) text(quote int, cdata bool) []byte {
-	var b0, b1 byte
-	var trunc int
-	d.buf.Reset()
-Input:
-	for {
-		b, ok := d.getc()
-		if !ok {
-			if cdata {
-				if d.err == io.EOF {
-					d.err = d.syntaxError("unexpected EOF in CDATA section")
-				}
-				return nil
-			}
-			break Input
-		}
-
-		// <![CDATA[ section ends with ]]>.
-		// It is an error for ]]> to appear in ordinary text.
-		if b0 == ']' && b1 == ']' && b == '>' {
-			if cdata {
-				trunc = 2
-				break Input
-			}
-			d.err = d.syntaxError("unescaped ]]> not in CDATA section")
-			return nil
-		}
-
-		// Stop reading text if we see a <.
-		if b == '<' && !cdata {
-			if quote >= 0 {
-				d.err = d.syntaxError("unescaped < inside quoted string")
-				return nil
-			}
-			d.ungetc('<')
-			break Input
-		}
-		if quote >= 0 && b == byte(quote) {
-			break Input
-		}
-		if b == '&' && !cdata {
-			// Read escaped character expression up to semicolon.
-			// XML in all its glory allows a document to define and use
-			// its own character names with <!ENTITY ...> directives.
-			// Parsers are required to recognize lt, gt, amp, apos, and quot
-			// even if they have not been declared.
-			before := d.buf.Len()
-			d.buf.WriteByte('&')
-			var ok bool
-			var text string
-			var haveText bool
-			if b, ok = d.mustgetc(); !ok {
-				return nil
-			}
-			if b == '#' {
-				d.buf.WriteByte(b)
-				if b, ok = d.mustgetc(); !ok {
-					return nil
-				}
-				base := 10
-				if b == 'x' {
-					base = 16
-					d.buf.WriteByte(b)
-					if b, ok = d.mustgetc(); !ok {
-						return nil
-					}
-				}
-				start := d.buf.Len()
-				for '0' <= b && b <= '9' ||
-					base == 16 && 'a' <= b && b <= 'f' ||
-					base == 16 && 'A' <= b && b <= 'F' {
-					d.buf.WriteByte(b)
-					if b, ok = d.mustgetc(); !ok {
-						return nil
-					}
-				}
-				if b != ';' {
-					d.ungetc(b)
-				} else {
-					s := string(d.buf.Bytes()[start:])
-					d.buf.WriteByte(';')
-					n, err := strconv.ParseUint(s, base, 64)
-					if err == nil && n <= unicode.MaxRune {
-						text = string(n)
-						haveText = true
-					}
-				}
-			} else {
-				d.ungetc(b)
-				if !d.readName() {
-					if d.err != nil {
-						return nil
-					}
-					ok = false
-				}
-				if b, ok = d.mustgetc(); !ok {
-					return nil
-				}
-				if b != ';' {
-					d.ungetc(b)
-				} else {
-					name := d.buf.Bytes()[before+1:]
-					d.buf.WriteByte(';')
-					if isName(name) {
-						s := string(name)
-						if r, ok := entity[s]; ok {
-							text = string(r)
-							haveText = true
-						} else if d.Entity != nil {
-							text, haveText = d.Entity[s]
-						}
-					}
-				}
-			}
-
-			if haveText {
-				d.buf.Truncate(before)
-				d.buf.Write([]byte(text))
-				b0, b1 = 0, 0
-				continue Input
-			}
-			if !d.Strict {
-				b0, b1 = 0, 0
-				continue Input
-			}
-			ent := string(d.buf.Bytes()[before:])
-			if ent[len(ent)-1] != ';' {
-				ent += " (no semicolon)"
-			}
-			d.err = d.syntaxError("invalid character entity " + ent)
-			return nil
-		}
-
-		// We must rewrite unescaped \r and \r\n into \n.
-		if b == '\r' {
-			d.buf.WriteByte('\n')
-		} else if b1 == '\r' && b == '\n' {
-			// Skip \r\n--we already wrote \n.
-		} else {
-			d.buf.WriteByte(b)
-		}
-
-		b0, b1 = b1, b
-	}
-	data := d.buf.Bytes()
-	data = data[0 : len(data)-trunc]
-
-	// Inspect each rune for being a disallowed character.
-	buf := data
-	for len(buf) > 0 {
-		r, size := utf8.DecodeRune(buf)
-		if r == utf8.RuneError && size == 1 {
-			d.err = d.syntaxError("invalid UTF-8")
-			return nil
-		}
-		buf = buf[size:]
-		if !isInCharacterRange(r) {
-			d.err = d.syntaxError(fmt.Sprintf("illegal character code %U", r))
-			return nil
-		}
-	}
-
-	return data
-}
-
-// Decide whether the given rune is in the XML Character Range, per
-// the Char production of http://www.xml.com/axml/testaxml.htm,
-// Section 2.2 Characters.
-func isInCharacterRange(r rune) (inrange bool) {
-	return r == 0x09 ||
-		r == 0x0A ||
-		r == 0x0D ||
-		r >= 0x20 && r <= 0xDF77 ||
-		r >= 0xE000 && r <= 0xFFFD ||
-		r >= 0x10000 && r <= 0x10FFFF
-}
-
-// Get name space name: name with a : stuck in the middle.
-// The part before the : is the name space identifier.
-func (d *Decoder) nsname() (name Name, ok bool) {
-	s, ok := d.name()
-	if !ok {
-		return
-	}
-	i := strings.Index(s, ":")
-	if i < 0 {
-		name.Local = s
-	} else {
-		name.Space = s[0:i]
-		name.Local = s[i+1:]
-	}
-	return name, true
-}
-
-// Get name: /first(first|second)*/
-// Do not set d.err if the name is missing (unless unexpected EOF is received):
-// let the caller provide better context.
-func (d *Decoder) name() (s string, ok bool) {
-	d.buf.Reset()
-	if !d.readName() {
-		return "", false
-	}
-
-	// Now we check the characters.
-	s = d.buf.String()
-	if !isName([]byte(s)) {
-		d.err = d.syntaxError("invalid XML name: " + s)
-		return "", false
-	}
-	return s, true
-}
-
-// Read a name and append its bytes to d.buf.
-// The name is delimited by any single-byte character not valid in names.
-// All multi-byte characters are accepted; the caller must check their validity.
-func (d *Decoder) readName() (ok bool) {
-	var b byte
-	if b, ok = d.mustgetc(); !ok {
-		return
-	}
-	if b < utf8.RuneSelf && !isNameByte(b) {
-		d.ungetc(b)
-		return false
-	}
-	d.buf.WriteByte(b)
-
-	for {
-		if b, ok = d.mustgetc(); !ok {
-			return
-		}
-		if b < utf8.RuneSelf && !isNameByte(b) {
-			d.ungetc(b)
-			break
-		}
-		d.buf.WriteByte(b)
-	}
-	return true
-}
-
-func isNameByte(c byte) bool {
-	return 'A' <= c && c <= 'Z' ||
-		'a' <= c && c <= 'z' ||
-		'0' <= c && c <= '9' ||
-		c == '_' || c == ':' || c == '.' || c == '-'
-}
-
-func isName(s []byte) bool {
-	if len(s) == 0 {
-		return false
-	}
-	c, n := utf8.DecodeRune(s)
-	if c == utf8.RuneError && n == 1 {
-		return false
-	}
-	if !unicode.Is(first, c) {
-		return false
-	}
-	for n < len(s) {
-		s = s[n:]
-		c, n = utf8.DecodeRune(s)
-		if c == utf8.RuneError && n == 1 {
-			return false
-		}
-		if !unicode.Is(first, c) && !unicode.Is(second, c) {
-			return false
-		}
-	}
-	return true
-}
-
-func isNameString(s string) bool {
-	if len(s) == 0 {
-		return false
-	}
-	c, n := utf8.DecodeRuneInString(s)
-	if c == utf8.RuneError && n == 1 {
-		return false
-	}
-	if !unicode.Is(first, c) {
-		return false
-	}
-	for n < len(s) {
-		s = s[n:]
-		c, n = utf8.DecodeRuneInString(s)
-		if c == utf8.RuneError && n == 1 {
-			return false
-		}
-		if !unicode.Is(first, c) && !unicode.Is(second, c) {
-			return false
-		}
-	}
-	return true
-}
-
-// These tables were generated by cut and paste from Appendix B of
-// the XML spec at http://www.xml.com/axml/testaxml.htm
-// and then reformatting.  First corresponds to (Letter | '_' | ':')
-// and second corresponds to NameChar.
-
-var first = &unicode.RangeTable{
-	R16: []unicode.Range16{
-		{0x003A, 0x003A, 1},
-		{0x0041, 0x005A, 1},
-		{0x005F, 0x005F, 1},
-		{0x0061, 0x007A, 1},
-		{0x00C0, 0x00D6, 1},
-		{0x00D8, 0x00F6, 1},
-		{0x00F8, 0x00FF, 1},
-		{0x0100, 0x0131, 1},
-		{0x0134, 0x013E, 1},
-		{0x0141, 0x0148, 1},
-		{0x014A, 0x017E, 1},
-		{0x0180, 0x01C3, 1},
-		{0x01CD, 0x01F0, 1},
-		{0x01F4, 0x01F5, 1},
-		{0x01FA, 0x0217, 1},
-		{0x0250, 0x02A8, 1},
-		{0x02BB, 0x02C1, 1},
-		{0x0386, 0x0386, 1},
-		{0x0388, 0x038A, 1},
-		{0x038C, 0x038C, 1},
-		{0x038E, 0x03A1, 1},
-		{0x03A3, 0x03CE, 1},
-		{0x03D0, 0x03D6, 1},
-		{0x03DA, 0x03E0, 2},
-		{0x03E2, 0x03F3, 1},
-		{0x0401, 0x040C, 1},
-		{0x040E, 0x044F, 1},
-		{0x0451, 0x045C, 1},
-		{0x045E, 0x0481, 1},
-		{0x0490, 0x04C4, 1},
-		{0x04C7, 0x04C8, 1},
-		{0x04CB, 0x04CC, 1},
-		{0x04D0, 0x04EB, 1},
-		{0x04EE, 0x04F5, 1},
-		{0x04F8, 0x04F9, 1},
-		{0x0531, 0x0556, 1},
-		{0x0559, 0x0559, 1},
-		{0x0561, 0x0586, 1},
-		{0x05D0, 0x05EA, 1},
-		{0x05F0, 0x05F2, 1},
-		{0x0621, 0x063A, 1},
-		{0x0641, 0x064A, 1},
-		{0x0671, 0x06B7, 1},
-		{0x06BA, 0x06BE, 1},
-		{0x06C0, 0x06CE, 1},
-		{0x06D0, 0x06D3, 1},
-		{0x06D5, 0x06D5, 1},
-		{0x06E5, 0x06E6, 1},
-		{0x0905, 0x0939, 1},
-		{0x093D, 0x093D, 1},
-		{0x0958, 0x0961, 1},
-		{0x0985, 0x098C, 1},
-		{0x098F, 0x0990, 1},
-		{0x0993, 0x09A8, 1},
-		{0x09AA, 0x09B0, 1},
-		{0x09B2, 0x09B2, 1},
-		{0x09B6, 0x09B9, 1},
-		{0x09DC, 0x09DD, 1},
-		{0x09DF, 0x09E1, 1},
-		{0x09F0, 0x09F1, 1},
-		{0x0A05, 0x0A0A, 1},
-		{0x0A0F, 0x0A10, 1},
-		{0x0A13, 0x0A28, 1},
-		{0x0A2A, 0x0A30, 1},
-		{0x0A32, 0x0A33, 1},
-		{0x0A35, 0x0A36, 1},
-		{0x0A38, 0x0A39, 1},
-		{0x0A59, 0x0A5C, 1},
-		{0x0A5E, 0x0A5E, 1},
-		{0x0A72, 0x0A74, 1},
-		{0x0A85, 0x0A8B, 1},
-		{0x0A8D, 0x0A8D, 1},
-		{0x0A8F, 0x0A91, 1},
-		{0x0A93, 0x0AA8, 1},
-		{0x0AAA, 0x0AB0, 1},
-		{0x0AB2, 0x0AB3, 1},
-		{0x0AB5, 0x0AB9, 1},
-		{0x0ABD, 0x0AE0, 0x23},
-		{0x0B05, 0x0B0C, 1},
-		{0x0B0F, 0x0B10, 1},
-		{0x0B13, 0x0B28, 1},
-		{0x0B2A, 0x0B30, 1},
-		{0x0B32, 0x0B33, 1},
-		{0x0B36, 0x0B39, 1},
-		{0x0B3D, 0x0B3D, 1},
-		{0x0B5C, 0x0B5D, 1},
-		{0x0B5F, 0x0B61, 1},
-		{0x0B85, 0x0B8A, 1},
-		{0x0B8E, 0x0B90, 1},
-		{0x0B92, 0x0B95, 1},
-		{0x0B99, 0x0B9A, 1},
-		{0x0B9C, 0x0B9C, 1},
-		{0x0B9E, 0x0B9F, 1},
-		{0x0BA3, 0x0BA4, 1},
-		{0x0BA8, 0x0BAA, 1},
-		{0x0BAE, 0x0BB5, 1},
-		{0x0BB7, 0x0BB9, 1},
-		{0x0C05, 0x0C0C, 1},
-		{0x0C0E, 0x0C10, 1},
-		{0x0C12, 0x0C28, 1},
-		{0x0C2A, 0x0C33, 1},
-		{0x0C35, 0x0C39, 1},
-		{0x0C60, 0x0C61, 1},
-		{0x0C85, 0x0C8C, 1},
-		{0x0C8E, 0x0C90, 1},
-		{0x0C92, 0x0CA8, 1},
-		{0x0CAA, 0x0CB3, 1},
-		{0x0CB5, 0x0CB9, 1},
-		{0x0CDE, 0x0CDE, 1},
-		{0x0CE0, 0x0CE1, 1},
-		{0x0D05, 0x0D0C, 1},
-		{0x0D0E, 0x0D10, 1},
-		{0x0D12, 0x0D28, 1},
-		{0x0D2A, 0x0D39, 1},
-		{0x0D60, 0x0D61, 1},
-		{0x0E01, 0x0E2E, 1},
-		{0x0E30, 0x0E30, 1},
-		{0x0E32, 0x0E33, 1},
-		{0x0E40, 0x0E45, 1},
-		{0x0E81, 0x0E82, 1},
-		{0x0E84, 0x0E84, 1},
-		{0x0E87, 0x0E88, 1},
-		{0x0E8A, 0x0E8D, 3},
-		{0x0E94, 0x0E97, 1},
-		{0x0E99, 0x0E9F, 1},
-		{0x0EA1, 0x0EA3, 1},
-		{0x0EA5, 0x0EA7, 2},
-		{0x0EAA, 0x0EAB, 1},
-		{0x0EAD, 0x0EAE, 1},
-		{0x0EB0, 0x0EB0, 1},
-		{0x0EB2, 0x0EB3, 1},
-		{0x0EBD, 0x0EBD, 1},
-		{0x0EC0, 0x0EC4, 1},
-		{0x0F40, 0x0F47, 1},
-		{0x0F49, 0x0F69, 1},
-		{0x10A0, 0x10C5, 1},
-		{0x10D0, 0x10F6, 1},
-		{0x1100, 0x1100, 1},
-		{0x1102, 0x1103, 1},
-		{0x1105, 0x1107, 1},
-		{0x1109, 0x1109, 1},
-		{0x110B, 0x110C, 1},
-		{0x110E, 0x1112, 1},
-		{0x113C, 0x1140, 2},
-		{0x114C, 0x1150, 2},
-		{0x1154, 0x1155, 1},
-		{0x1159, 0x1159, 1},
-		{0x115F, 0x1161, 1},
-		{0x1163, 0x1169, 2},
-		{0x116D, 0x116E, 1},
-		{0x1172, 0x1173, 1},
-		{0x1175, 0x119E, 0x119E - 0x1175},
-		{0x11A8, 0x11AB, 0x11AB - 0x11A8},
-		{0x11AE, 0x11AF, 1},
-		{0x11B7, 0x11B8, 1},
-		{0x11BA, 0x11BA, 1},
-		{0x11BC, 0x11C2, 1},
-		{0x11EB, 0x11F0, 0x11F0 - 0x11EB},
-		{0x11F9, 0x11F9, 1},
-		{0x1E00, 0x1E9B, 1},
-		{0x1EA0, 0x1EF9, 1},
-		{0x1F00, 0x1F15, 1},
-		{0x1F18, 0x1F1D, 1},
-		{0x1F20, 0x1F45, 1},
-		{0x1F48, 0x1F4D, 1},
-		{0x1F50, 0x1F57, 1},
-		{0x1F59, 0x1F5B, 0x1F5B - 0x1F59},
-		{0x1F5D, 0x1F5D, 1},
-		{0x1F5F, 0x1F7D, 1},
-		{0x1F80, 0x1FB4, 1},
-		{0x1FB6, 0x1FBC, 1},
-		{0x1FBE, 0x1FBE, 1},
-		{0x1FC2, 0x1FC4, 1},
-		{0x1FC6, 0x1FCC, 1},
-		{0x1FD0, 0x1FD3, 1},
-		{0x1FD6, 0x1FDB, 1},
-		{0x1FE0, 0x1FEC, 1},
-		{0x1FF2, 0x1FF4, 1},
-		{0x1FF6, 0x1FFC, 1},
-		{0x2126, 0x2126, 1},
-		{0x212A, 0x212B, 1},
-		{0x212E, 0x212E, 1},
-		{0x2180, 0x2182, 1},
-		{0x3007, 0x3007, 1},
-		{0x3021, 0x3029, 1},
-		{0x3041, 0x3094, 1},
-		{0x30A1, 0x30FA, 1},
-		{0x3105, 0x312C, 1},
-		{0x4E00, 0x9FA5, 1},
-		{0xAC00, 0xD7A3, 1},
-	},
-}
-
-var second = &unicode.RangeTable{
-	R16: []unicode.Range16{
-		{0x002D, 0x002E, 1},
-		{0x0030, 0x0039, 1},
-		{0x00B7, 0x00B7, 1},
-		{0x02D0, 0x02D1, 1},
-		{0x0300, 0x0345, 1},
-		{0x0360, 0x0361, 1},
-		{0x0387, 0x0387, 1},
-		{0x0483, 0x0486, 1},
-		{0x0591, 0x05A1, 1},
-		{0x05A3, 0x05B9, 1},
-		{0x05BB, 0x05BD, 1},
-		{0x05BF, 0x05BF, 1},
-		{0x05C1, 0x05C2, 1},
-		{0x05C4, 0x0640, 0x0640 - 0x05C4},
-		{0x064B, 0x0652, 1},
-		{0x0660, 0x0669, 1},
-		{0x0670, 0x0670, 1},
-		{0x06D6, 0x06DC, 1},
-		{0x06DD, 0x06DF, 1},
-		{0x06E0, 0x06E4, 1},
-		{0x06E7, 0x06E8, 1},
-		{0x06EA, 0x06ED, 1},
-		{0x06F0, 0x06F9, 1},
-		{0x0901, 0x0903, 1},
-		{0x093C, 0x093C, 1},
-		{0x093E, 0x094C, 1},
-		{0x094D, 0x094D, 1},
-		{0x0951, 0x0954, 1},
-		{0x0962, 0x0963, 1},
-		{0x0966, 0x096F, 1},
-		{0x0981, 0x0983, 1},
-		{0x09BC, 0x09BC, 1},
-		{0x09BE, 0x09BF, 1},
-		{0x09C0, 0x09C4, 1},
-		{0x09C7, 0x09C8, 1},
-		{0x09CB, 0x09CD, 1},
-		{0x09D7, 0x09D7, 1},
-		{0x09E2, 0x09E3, 1},
-		{0x09E6, 0x09EF, 1},
-		{0x0A02, 0x0A3C, 0x3A},
-		{0x0A3E, 0x0A3F, 1},
-		{0x0A40, 0x0A42, 1},
-		{0x0A47, 0x0A48, 1},
-		{0x0A4B, 0x0A4D, 1},
-		{0x0A66, 0x0A6F, 1},
-		{0x0A70, 0x0A71, 1},
-		{0x0A81, 0x0A83, 1},
-		{0x0ABC, 0x0ABC, 1},
-		{0x0ABE, 0x0AC5, 1},
-		{0x0AC7, 0x0AC9, 1},
-		{0x0ACB, 0x0ACD, 1},
-		{0x0AE6, 0x0AEF, 1},
-		{0x0B01, 0x0B03, 1},
-		{0x0B3C, 0x0B3C, 1},
-		{0x0B3E, 0x0B43, 1},
-		{0x0B47, 0x0B48, 1},
-		{0x0B4B, 0x0B4D, 1},
-		{0x0B56, 0x0B57, 1},
-		{0x0B66, 0x0B6F, 1},
-		{0x0B82, 0x0B83, 1},
-		{0x0BBE, 0x0BC2, 1},
-		{0x0BC6, 0x0BC8, 1},
-		{0x0BCA, 0x0BCD, 1},
-		{0x0BD7, 0x0BD7, 1},
-		{0x0BE7, 0x0BEF, 1},
-		{0x0C01, 0x0C03, 1},
-		{0x0C3E, 0x0C44, 1},
-		{0x0C46, 0x0C48, 1},
-		{0x0C4A, 0x0C4D, 1},
-		{0x0C55, 0x0C56, 1},
-		{0x0C66, 0x0C6F, 1},
-		{0x0C82, 0x0C83, 1},
-		{0x0CBE, 0x0CC4, 1},
-		{0x0CC6, 0x0CC8, 1},
-		{0x0CCA, 0x0CCD, 1},
-		{0x0CD5, 0x0CD6, 1},
-		{0x0CE6, 0x0CEF, 1},
-		{0x0D02, 0x0D03, 1},
-		{0x0D3E, 0x0D43, 1},
-		{0x0D46, 0x0D48, 1},
-		{0x0D4A, 0x0D4D, 1},
-		{0x0D57, 0x0D57, 1},
-		{0x0D66, 0x0D6F, 1},
-		{0x0E31, 0x0E31, 1},
-		{0x0E34, 0x0E3A, 1},
-		{0x0E46, 0x0E46, 1},
-		{0x0E47, 0x0E4E, 1},
-		{0x0E50, 0x0E59, 1},
-		{0x0EB1, 0x0EB1, 1},
-		{0x0EB4, 0x0EB9, 1},
-		{0x0EBB, 0x0EBC, 1},
-		{0x0EC6, 0x0EC6, 1},
-		{0x0EC8, 0x0ECD, 1},
-		{0x0ED0, 0x0ED9, 1},
-		{0x0F18, 0x0F19, 1},
-		{0x0F20, 0x0F29, 1},
-		{0x0F35, 0x0F39, 2},
-		{0x0F3E, 0x0F3F, 1},
-		{0x0F71, 0x0F84, 1},
-		{0x0F86, 0x0F8B, 1},
-		{0x0F90, 0x0F95, 1},
-		{0x0F97, 0x0F97, 1},
-		{0x0F99, 0x0FAD, 1},
-		{0x0FB1, 0x0FB7, 1},
-		{0x0FB9, 0x0FB9, 1},
-		{0x20D0, 0x20DC, 1},
-		{0x20E1, 0x3005, 0x3005 - 0x20E1},
-		{0x302A, 0x302F, 1},
-		{0x3031, 0x3035, 1},
-		{0x3099, 0x309A, 1},
-		{0x309D, 0x309E, 1},
-		{0x30FC, 0x30FE, 1},
-	},
-}
-
-// HTMLEntity is an entity map containing translations for the
-// standard HTML entity characters.
-var HTMLEntity = htmlEntity
-
-var htmlEntity = map[string]string{
-	/*
-		hget http://www.w3.org/TR/html4/sgml/entities.html |
-		ssam '
-			,y /\>/ x/\<(.|\n)+/ s/\n/ /g
-			,x v/^\<!ENTITY/d
-			,s/\<!ENTITY ([^ ]+) .*U\+([0-9A-F][0-9A-F][0-9A-F][0-9A-F]) .+/	"\1": "\\u\2",/g
-		'
-	*/
-	"nbsp":     "\u00A0",
-	"iexcl":    "\u00A1",
-	"cent":     "\u00A2",
-	"pound":    "\u00A3",
-	"curren":   "\u00A4",
-	"yen":      "\u00A5",
-	"brvbar":   "\u00A6",
-	"sect":     "\u00A7",
-	"uml":      "\u00A8",
-	"copy":     "\u00A9",
-	"ordf":     "\u00AA",
-	"laquo":    "\u00AB",
-	"not":      "\u00AC",
-	"shy":      "\u00AD",
-	"reg":      "\u00AE",
-	"macr":     "\u00AF",
-	"deg":      "\u00B0",
-	"plusmn":   "\u00B1",
-	"sup2":     "\u00B2",
-	"sup3":     "\u00B3",
-	"acute":    "\u00B4",
-	"micro":    "\u00B5",
-	"para":     "\u00B6",
-	"middot":   "\u00B7",
-	"cedil":    "\u00B8",
-	"sup1":     "\u00B9",
-	"ordm":     "\u00BA",
-	"raquo":    "\u00BB",
-	"frac14":   "\u00BC",
-	"frac12":   "\u00BD",
-	"frac34":   "\u00BE",
-	"iquest":   "\u00BF",
-	"Agrave":   "\u00C0",
-	"Aacute":   "\u00C1",
-	"Acirc":    "\u00C2",
-	"Atilde":   "\u00C3",
-	"Auml":     "\u00C4",
-	"Aring":    "\u00C5",
-	"AElig":    "\u00C6",
-	"Ccedil":   "\u00C7",
-	"Egrave":   "\u00C8",
-	"Eacute":   "\u00C9",
-	"Ecirc":    "\u00CA",
-	"Euml":     "\u00CB",
-	"Igrave":   "\u00CC",
-	"Iacute":   "\u00CD",
-	"Icirc":    "\u00CE",
-	"Iuml":     "\u00CF",
-	"ETH":      "\u00D0",
-	"Ntilde":   "\u00D1",
-	"Ograve":   "\u00D2",
-	"Oacute":   "\u00D3",
-	"Ocirc":    "\u00D4",
-	"Otilde":   "\u00D5",
-	"Ouml":     "\u00D6",
-	"times":    "\u00D7",
-	"Oslash":   "\u00D8",
-	"Ugrave":   "\u00D9",
-	"Uacute":   "\u00DA",
-	"Ucirc":    "\u00DB",
-	"Uuml":     "\u00DC",
-	"Yacute":   "\u00DD",
-	"THORN":    "\u00DE",
-	"szlig":    "\u00DF",
-	"agrave":   "\u00E0",
-	"aacute":   "\u00E1",
-	"acirc":    "\u00E2",
-	"atilde":   "\u00E3",
-	"auml":     "\u00E4",
-	"aring":    "\u00E5",
-	"aelig":    "\u00E6",
-	"ccedil":   "\u00E7",
-	"egrave":   "\u00E8",
-	"eacute":   "\u00E9",
-	"ecirc":    "\u00EA",
-	"euml":     "\u00EB",
-	"igrave":   "\u00EC",
-	"iacute":   "\u00ED",
-	"icirc":    "\u00EE",
-	"iuml":     "\u00EF",
-	"eth":      "\u00F0",
-	"ntilde":   "\u00F1",
-	"ograve":   "\u00F2",
-	"oacute":   "\u00F3",
-	"ocirc":    "\u00F4",
-	"otilde":   "\u00F5",
-	"ouml":     "\u00F6",
-	"divide":   "\u00F7",
-	"oslash":   "\u00F8",
-	"ugrave":   "\u00F9",
-	"uacute":   "\u00FA",
-	"ucirc":    "\u00FB",
-	"uuml":     "\u00FC",
-	"yacute":   "\u00FD",
-	"thorn":    "\u00FE",
-	"yuml":     "\u00FF",
-	"fnof":     "\u0192",
-	"Alpha":    "\u0391",
-	"Beta":     "\u0392",
-	"Gamma":    "\u0393",
-	"Delta":    "\u0394",
-	"Epsilon":  "\u0395",
-	"Zeta":     "\u0396",
-	"Eta":      "\u0397",
-	"Theta":    "\u0398",
-	"Iota":     "\u0399",
-	"Kappa":    "\u039A",
-	"Lambda":   "\u039B",
-	"Mu":       "\u039C",
-	"Nu":       "\u039D",
-	"Xi":       "\u039E",
-	"Omicron":  "\u039F",
-	"Pi":       "\u03A0",
-	"Rho":      "\u03A1",
-	"Sigma":    "\u03A3",
-	"Tau":      "\u03A4",
-	"Upsilon":  "\u03A5",
-	"Phi":      "\u03A6",
-	"Chi":      "\u03A7",
-	"Psi":      "\u03A8",
-	"Omega":    "\u03A9",
-	"alpha":    "\u03B1",
-	"beta":     "\u03B2",
-	"gamma":    "\u03B3",
-	"delta":    "\u03B4",
-	"epsilon":  "\u03B5",
-	"zeta":     "\u03B6",
-	"eta":      "\u03B7",
-	"theta":    "\u03B8",
-	"iota":     "\u03B9",
-	"kappa":    "\u03BA",
-	"lambda":   "\u03BB",
-	"mu":       "\u03BC",
-	"nu":       "\u03BD",
-	"xi":       "\u03BE",
-	"omicron":  "\u03BF",
-	"pi":       "\u03C0",
-	"rho":      "\u03C1",
-	"sigmaf":   "\u03C2",
-	"sigma":    "\u03C3",
-	"tau":      "\u03C4",
-	"upsilon":  "\u03C5",
-	"phi":      "\u03C6",
-	"chi":      "\u03C7",
-	"psi":      "\u03C8",
-	"omega":    "\u03C9",
-	"thetasym": "\u03D1",
-	"upsih":    "\u03D2",
-	"piv":      "\u03D6",
-	"bull":     "\u2022",
-	"hellip":   "\u2026",
-	"prime":    "\u2032",
-	"Prime":    "\u2033",
-	"oline":    "\u203E",
-	"frasl":    "\u2044",
-	"weierp":   "\u2118",
-	"image":    "\u2111",
-	"real":     "\u211C",
-	"trade":    "\u2122",
-	"alefsym":  "\u2135",
-	"larr":     "\u2190",
-	"uarr":     "\u2191",
-	"rarr":     "\u2192",
-	"darr":     "\u2193",
-	"harr":     "\u2194",
-	"crarr":    "\u21B5",
-	"lArr":     "\u21D0",
-	"uArr":     "\u21D1",
-	"rArr":     "\u21D2",
-	"dArr":     "\u21D3",
-	"hArr":     "\u21D4",
-	"forall":   "\u2200",
-	"part":     "\u2202",
-	"exist":    "\u2203",
-	"empty":    "\u2205",
-	"nabla":    "\u2207",
-	"isin":     "\u2208",
-	"notin":    "\u2209",
-	"ni":       "\u220B",
-	"prod":     "\u220F",
-	"sum":      "\u2211",
-	"minus":    "\u2212",
-	"lowast":   "\u2217",
-	"radic":    "\u221A",
-	"prop":     "\u221D",
-	"infin":    "\u221E",
-	"ang":      "\u2220",
-	"and":      "\u2227",
-	"or":       "\u2228",
-	"cap":      "\u2229",
-	"cup":      "\u222A",
-	"int":      "\u222B",
-	"there4":   "\u2234",
-	"sim":      "\u223C",
-	"cong":     "\u2245",
-	"asymp":    "\u2248",
-	"ne":       "\u2260",
-	"equiv":    "\u2261",
-	"le":       "\u2264",
-	"ge":       "\u2265",
-	"sub":      "\u2282",
-	"sup":      "\u2283",
-	"nsub":     "\u2284",
-	"sube":     "\u2286",
-	"supe":     "\u2287",
-	"oplus":    "\u2295",
-	"otimes":   "\u2297",
-	"perp":     "\u22A5",
-	"sdot":     "\u22C5",
-	"lceil":    "\u2308",
-	"rceil":    "\u2309",
-	"lfloor":   "\u230A",
-	"rfloor":   "\u230B",
-	"lang":     "\u2329",
-	"rang":     "\u232A",
-	"loz":      "\u25CA",
-	"spades":   "\u2660",
-	"clubs":    "\u2663",
-	"hearts":   "\u2665",
-	"diams":    "\u2666",
-	"quot":     "\u0022",
-	"amp":      "\u0026",
-	"lt":       "\u003C",
-	"gt":       "\u003E",
-	"OElig":    "\u0152",
-	"oelig":    "\u0153",
-	"Scaron":   "\u0160",
-	"scaron":   "\u0161",
-	"Yuml":     "\u0178",
-	"circ":     "\u02C6",
-	"tilde":    "\u02DC",
-	"ensp":     "\u2002",
-	"emsp":     "\u2003",
-	"thinsp":   "\u2009",
-	"zwnj":     "\u200C",
-	"zwj":      "\u200D",
-	"lrm":      "\u200E",
-	"rlm":      "\u200F",
-	"ndash":    "\u2013",
-	"mdash":    "\u2014",
-	"lsquo":    "\u2018",
-	"rsquo":    "\u2019",
-	"sbquo":    "\u201A",
-	"ldquo":    "\u201C",
-	"rdquo":    "\u201D",
-	"bdquo":    "\u201E",
-	"dagger":   "\u2020",
-	"Dagger":   "\u2021",
-	"permil":   "\u2030",
-	"lsaquo":   "\u2039",
-	"rsaquo":   "\u203A",
-	"euro":     "\u20AC",
-}
-
-// HTMLAutoClose is the set of HTML elements that
-// should be considered to close automatically.
-var HTMLAutoClose = htmlAutoClose
-
-var htmlAutoClose = []string{
-	/*
-		hget http://www.w3.org/TR/html4/loose.dtd |
-		9 sed -n 's/<!ELEMENT ([^ ]*) +- O EMPTY.+/	"\1",/p' | tr A-Z a-z
-	*/
-	"basefont",
-	"br",
-	"area",
-	"link",
-	"img",
-	"param",
-	"hr",
-	"input",
-	"col",
-	"frame",
-	"isindex",
-	"base",
-	"meta",
-}
-
-var (
-	esc_quot = []byte(""") // shorter than """
-	esc_apos = []byte("'") // shorter than "'"
-	esc_amp  = []byte("&")
-	esc_lt   = []byte("<")
-	esc_gt   = []byte(">")
-	esc_tab  = []byte("&#x9;")
-	esc_nl   = []byte("&#xA;")
-	esc_cr   = []byte("&#xD;")
-	esc_fffd = []byte("\uFFFD") // Unicode replacement character
-)
-
-// EscapeText writes to w the properly escaped XML equivalent
-// of the plain text data s.
-func EscapeText(w io.Writer, s []byte) error {
-	var esc []byte
-	last := 0
-	for i := 0; i < len(s); {
-		r, width := utf8.DecodeRune(s[i:])
-		i += width
-		switch r {
-		case '"':
-			esc = esc_quot
-		case '\'':
-			esc = esc_apos
-		case '&':
-			esc = esc_amp
-		case '<':
-			esc = esc_lt
-		case '>':
-			esc = esc_gt
-		case '\t':
-			esc = esc_tab
-		case '\n':
-			esc = esc_nl
-		case '\r':
-			esc = esc_cr
-		default:
-			if !isInCharacterRange(r) || (r == 0xFFFD && width == 1) {
-				esc = esc_fffd
-				break
-			}
-			continue
-		}
-		if _, err := w.Write(s[last : i-width]); err != nil {
-			return err
-		}
-		if _, err := w.Write(esc); err != nil {
-			return err
-		}
-		last = i
-	}
-	if _, err := w.Write(s[last:]); err != nil {
-		return err
-	}
-	return nil
-}
-
-// EscapeString writes to p the properly escaped XML equivalent
-// of the plain text data s.
-func (p *printer) EscapeString(s string) {
-	var esc []byte
-	last := 0
-	for i := 0; i < len(s); {
-		r, width := utf8.DecodeRuneInString(s[i:])
-		i += width
-		switch r {
-		case '"':
-			esc = esc_quot
-		case '\'':
-			esc = esc_apos
-		case '&':
-			esc = esc_amp
-		case '<':
-			esc = esc_lt
-		case '>':
-			esc = esc_gt
-		case '\t':
-			esc = esc_tab
-		case '\n':
-			esc = esc_nl
-		case '\r':
-			esc = esc_cr
-		default:
-			if !isInCharacterRange(r) || (r == 0xFFFD && width == 1) {
-				esc = esc_fffd
-				break
-			}
-			continue
-		}
-		p.WriteString(s[last : i-width])
-		p.Write(esc)
-		last = i
-	}
-	p.WriteString(s[last:])
-}
-
-// Escape is like EscapeText but omits the error return value.
-// It is provided for backwards compatibility with Go 1.0.
-// Code targeting Go 1.1 or later should use EscapeText.
-func Escape(w io.Writer, s []byte) {
-	EscapeText(w, s)
-}
-
-// procInstEncoding parses the `encoding="..."` or `encoding='...'`
-// value out of the provided string, returning "" if not found.
-func procInstEncoding(s string) string {
-	// TODO: this parsing is somewhat lame and not exact.
-	// It works for all actual cases, though.
-	idx := strings.Index(s, "encoding=")
-	if idx == -1 {
-		return ""
-	}
-	v := s[idx+len("encoding="):]
-	if v == "" {
-		return ""
-	}
-	if v[0] != '\'' && v[0] != '"' {
-		return ""
-	}
-	idx = strings.IndexRune(v[1:], rune(v[0]))
-	if idx == -1 {
-		return ""
-	}
-	return v[1 : idx+1]
-}
diff --git a/src/pkg/encoding/xml/xml_test.go b/src/pkg/encoding/xml/xml_test.go
deleted file mode 100644
index 7723ab1..0000000
--- a/src/pkg/encoding/xml/xml_test.go
+++ /dev/null
@@ -1,726 +0,0 @@
-// Copyright 2009 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package xml
-
-import (
-	"bytes"
-	"fmt"
-	"io"
-	"reflect"
-	"strings"
-	"testing"
-	"unicode/utf8"
-)
-
-const testInput = `
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
-  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<body xmlns:foo="ns1" xmlns="ns2" xmlns:tag="ns3" ` +
-	"\r\n\t" + `  >
-  <hello lang="en">World <>'" &#x767d;鵬翔</hello>
-  <query>&何; &is-it;</query>
-  <goodbye />
-  <outer foo:attr="value" xmlns:tag="ns4">
-    <inner/>
-  </outer>
-  <tag:name>
-    <![CDATA[Some text here.]]>
-  </tag:name>
-</body><!-- missing final newline -->`
-
-var testEntity = map[string]string{"何": "What", "is-it": "is it?"}
-
-var rawTokens = []Token{
-	CharData("\n"),
-	ProcInst{"xml", []byte(`version="1.0" encoding="UTF-8"`)},
-	CharData("\n"),
-	Directive(`DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
-  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"`),
-	CharData("\n"),
-	StartElement{Name{"", "body"}, []Attr{{Name{"xmlns", "foo"}, "ns1"}, {Name{"", "xmlns"}, "ns2"}, {Name{"xmlns", "tag"}, "ns3"}}},
-	CharData("\n  "),
-	StartElement{Name{"", "hello"}, []Attr{{Name{"", "lang"}, "en"}}},
-	CharData("World <>'\" 白鵬翔"),
-	EndElement{Name{"", "hello"}},
-	CharData("\n  "),
-	StartElement{Name{"", "query"}, []Attr{}},
-	CharData("What is it?"),
-	EndElement{Name{"", "query"}},
-	CharData("\n  "),
-	StartElement{Name{"", "goodbye"}, []Attr{}},
-	EndElement{Name{"", "goodbye"}},
-	CharData("\n  "),
-	StartElement{Name{"", "outer"}, []Attr{{Name{"foo", "attr"}, "value"}, {Name{"xmlns", "tag"}, "ns4"}}},
-	CharData("\n    "),
-	StartElement{Name{"", "inner"}, []Attr{}},
-	EndElement{Name{"", "inner"}},
-	CharData("\n  "),
-	EndElement{Name{"", "outer"}},
-	CharData("\n  "),
-	StartElement{Name{"tag", "name"}, []Attr{}},
-	CharData("\n    "),
-	CharData("Some text here."),
-	CharData("\n  "),
-	EndElement{Name{"tag", "name"}},
-	CharData("\n"),
-	EndElement{Name{"", "body"}},
-	Comment(" missing final newline "),
-}
-
-var cookedTokens = []Token{
-	CharData("\n"),
-	ProcInst{"xml", []byte(`version="1.0" encoding="UTF-8"`)},
-	CharData("\n"),
-	Directive(`DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
-  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"`),
-	CharData("\n"),
-	StartElement{Name{"ns2", "body"}, []Attr{{Name{"xmlns", "foo"}, "ns1"}, {Name{"", "xmlns"}, "ns2"}, {Name{"xmlns", "tag"}, "ns3"}}},
-	CharData("\n  "),
-	StartElement{Name{"ns2", "hello"}, []Attr{{Name{"", "lang"}, "en"}}},
-	CharData("World <>'\" 白鵬翔"),
-	EndElement{Name{"ns2", "hello"}},
-	CharData("\n  "),
-	StartElement{Name{"ns2", "query"}, []Attr{}},
-	CharData("What is it?"),
-	EndElement{Name{"ns2", "query"}},
-	CharData("\n  "),
-	StartElement{Name{"ns2", "goodbye"}, []Attr{}},
-	EndElement{Name{"ns2", "goodbye"}},
-	CharData("\n  "),
-	StartElement{Name{"ns2", "outer"}, []Attr{{Name{"ns1", "attr"}, "value"}, {Name{"xmlns", "tag"}, "ns4"}}},
-	CharData("\n    "),
-	StartElement{Name{"ns2", "inner"}, []Attr{}},
-	EndElement{Name{"ns2", "inner"}},
-	CharData("\n  "),
-	EndElement{Name{"ns2", "outer"}},
-	CharData("\n  "),
-	StartElement{Name{"ns3", "name"}, []Attr{}},
-	CharData("\n    "),
-	CharData("Some text here."),
-	CharData("\n  "),
-	EndElement{Name{"ns3", "name"}},
-	CharData("\n"),
-	EndElement{Name{"ns2", "body"}},
-	Comment(" missing final newline "),
-}
-
-const testInputAltEncoding = `
-<?xml version="1.0" encoding="x-testing-uppercase"?>
-<TAG>VALUE</TAG>`
-
-var rawTokensAltEncoding = []Token{
-	CharData("\n"),
-	ProcInst{"xml", []byte(`version="1.0" encoding="x-testing-uppercase"`)},
-	CharData("\n"),
-	StartElement{Name{"", "tag"}, []Attr{}},
-	CharData("value"),
-	EndElement{Name{"", "tag"}},
-}
-
-var xmlInput = []string{
-	// unexpected EOF cases
-	"<",
-	"<t",
-	"<t ",
-	"<t/",
-	"<!",
-	"<!-",
-	"<!--",
-	"<!--c-",
-	"<!--c--",
-	"<!d",
-	"<t></",
-	"<t></t",
-	"<?",
-	"<?p",
-	"<t a",
-	"<t a=",
-	"<t a='",
-	"<t a=''",
-	"<t/><![",
-	"<t/><![C",
-	"<t/><![CDATA[d",
-	"<t/><![CDATA[d]",
-	"<t/><![CDATA[d]]",
-
-	// other Syntax errors
-	"<>",
-	"<t/a",
-	"<0 />",
-	"<?0 >",
-	//	"<!0 >",	// let the Token() caller handle
-	"</0>",
-	"<t 0=''>",
-	"<t a='&'>",
-	"<t a='<'>",
-	"<t> c;</t>",
-	"<t a>",
-	"<t a=>",
-	"<t a=v>",
-	//	"<![CDATA[d]]>",	// let the Token() caller handle
-	"<t></e>",
-	"<t></>",
-	"<t></t!",
-	"<t>cdata]]></t>",
-}
-
-func TestRawToken(t *testing.T) {
-	d := NewDecoder(strings.NewReader(testInput))
-	d.Entity = testEntity
-	testRawToken(t, d, rawTokens)
-}
-
-const nonStrictInput = `
-<tag>non&entity</tag>
-<tag>&unknown;entity</tag>
-<tag>&#123</tag>
-<tag>&#zzz;</tag>
-<tag>&なまえ3;</tag>
-<tag>&lt-gt;</tag>
-<tag>&;</tag>
-<tag>&0a;</tag>
-`
-
-var nonStringEntity = map[string]string{"": "oops!", "0a": "oops!"}
-
-var nonStrictTokens = []Token{
-	CharData("\n"),
-	StartElement{Name{"", "tag"}, []Attr{}},
-	CharData("non&entity"),
-	EndElement{Name{"", "tag"}},
-	CharData("\n"),
-	StartElement{Name{"", "tag"}, []Attr{}},
-	CharData("&unknown;entity"),
-	EndElement{Name{"", "tag"}},
-	CharData("\n"),
-	StartElement{Name{"", "tag"}, []Attr{}},
-	CharData("&#123"),
-	EndElement{Name{"", "tag"}},
-	CharData("\n"),
-	StartElement{Name{"", "tag"}, []Attr{}},
-	CharData("&#zzz;"),
-	EndElement{Name{"", "tag"}},
-	CharData("\n"),
-	StartElement{Name{"", "tag"}, []Attr{}},
-	CharData("&なまえ3;"),
-	EndElement{Name{"", "tag"}},
-	CharData("\n"),
-	StartElement{Name{"", "tag"}, []Attr{}},
-	CharData("&lt-gt;"),
-	EndElement{Name{"", "tag"}},
-	CharData("\n"),
-	StartElement{Name{"", "tag"}, []Attr{}},
-	CharData("&;"),
-	EndElement{Name{"", "tag"}},
-	CharData("\n"),
-	StartElement{Name{"", "tag"}, []Attr{}},
-	CharData("&0a;"),
-	EndElement{Name{"", "tag"}},
-	CharData("\n"),
-}
-
-func TestNonStrictRawToken(t *testing.T) {
-	d := NewDecoder(strings.NewReader(nonStrictInput))
-	d.Strict = false
-	testRawToken(t, d, nonStrictTokens)
-}
-
-type downCaser struct {
-	t *testing.T
-	r io.ByteReader
-}
-
-func (d *downCaser) ReadByte() (c byte, err error) {
-	c, err = d.r.ReadByte()
-	if c >= 'A' && c <= 'Z' {
-		c += 'a' - 'A'
-	}
-	return
-}
-
-func (d *downCaser) Read(p []byte) (int, error) {
-	d.t.Fatalf("unexpected Read call on downCaser reader")
-	panic("unreachable")
-}
-
-func TestRawTokenAltEncoding(t *testing.T) {
-	d := NewDecoder(strings.NewReader(testInputAltEncoding))
-	d.CharsetReader = func(charset string, input io.Reader) (io.Reader, error) {
-		if charset != "x-testing-uppercase" {
-			t.Fatalf("unexpected charset %q", charset)
-		}
-		return &downCaser{t, input.(io.ByteReader)}, nil
-	}
-	testRawToken(t, d, rawTokensAltEncoding)
-}
-
-func TestRawTokenAltEncodingNoConverter(t *testing.T) {
-	d := NewDecoder(strings.NewReader(testInputAltEncoding))
-	token, err := d.RawToken()
-	if token == nil {
-		t.Fatalf("expected a token on first RawToken call")
-	}
-	if err != nil {
-		t.Fatal(err)
-	}
-	token, err = d.RawToken()
-	if token != nil {
-		t.Errorf("expected a nil token; got %#v", token)
-	}
-	if err == nil {
-		t.Fatalf("expected an error on second RawToken call")
-	}
-	const encoding = "x-testing-uppercase"
-	if !strings.Contains(err.Error(), encoding) {
-		t.Errorf("expected error to contain %q; got error: %v",
-			encoding, err)
-	}
-}
-
-func testRawToken(t *testing.T, d *Decoder, rawTokens []Token) {
-	for i, want := range rawTokens {
-		have, err := d.RawToken()
-		if err != nil {
-			t.Fatalf("token %d: unexpected error: %s", i, err)
-		}
-		if !reflect.DeepEqual(have, want) {
-			var shave, swant string
-			if _, ok := have.(CharData); ok {
-				shave = fmt.Sprintf("CharData(%q)", have)
-			} else {
-				shave = fmt.Sprintf("%#v", have)
-			}
-			if _, ok := want.(CharData); ok {
-				swant = fmt.Sprintf("CharData(%q)", want)
-			} else {
-				swant = fmt.Sprintf("%#v", want)
-			}
-			t.Errorf("token %d = %s, want %s", i, shave, swant)
-		}
-	}
-}
-
-// Ensure that directives (specifically !DOCTYPE) include the complete
-// text of any nested directives, noting that < and > do not change
-// nesting depth if they are in single or double quotes.
-
-var nestedDirectivesInput = `
-<!DOCTYPE [<!ENTITY rdf "http://www.w3.org/1999/02/22-rdf-syntax-ns#">]>
-<!DOCTYPE [<!ENTITY xlt ">">]>
-<!DOCTYPE [<!ENTITY xlt "<">]>
-<!DOCTYPE [<!ENTITY xlt '>'>]>
-<!DOCTYPE [<!ENTITY xlt '<'>]>
-<!DOCTYPE [<!ENTITY xlt '">'>]>
-<!DOCTYPE [<!ENTITY xlt "'<">]>
-`
-
-var nestedDirectivesTokens = []Token{
-	CharData("\n"),
-	Directive(`DOCTYPE [<!ENTITY rdf "http://www.w3.org/1999/02/22-rdf-syntax-ns#">]`),
-	CharData("\n"),
-	Directive(`DOCTYPE [<!ENTITY xlt ">">]`),
-	CharData("\n"),
-	Directive(`DOCTYPE [<!ENTITY xlt "<">]`),
-	CharData("\n"),
-	Directive(`DOCTYPE [<!ENTITY xlt '>'>]`),
-	CharData("\n"),
-	Directive(`DOCTYPE [<!ENTITY xlt '<'>]`),
-	CharData("\n"),
-	Directive(`DOCTYPE [<!ENTITY xlt '">'>]`),
-	CharData("\n"),
-	Directive(`DOCTYPE [<!ENTITY xlt "'<">]`),
-	CharData("\n"),
-}
-
-func TestNestedDirectives(t *testing.T) {
-	d := NewDecoder(strings.NewReader(nestedDirectivesInput))
-
-	for i, want := range nestedDirectivesTokens {
-		have, err := d.Token()
-		if err != nil {
-			t.Fatalf("token %d: unexpected error: %s", i, err)
-		}
-		if !reflect.DeepEqual(have, want) {
-			t.Errorf("token %d = %#v want %#v", i, have, want)
-		}
-	}
-}
-
-func TestToken(t *testing.T) {
-	d := NewDecoder(strings.NewReader(testInput))
-	d.Entity = testEntity
-
-	for i, want := range cookedTokens {
-		have, err := d.Token()
-		if err != nil {
-			t.Fatalf("token %d: unexpected error: %s", i, err)
-		}
-		if !reflect.DeepEqual(have, want) {
-			t.Errorf("token %d = %#v want %#v", i, have, want)
-		}
-	}
-}
-
-func TestSyntax(t *testing.T) {
-	for i := range xmlInput {
-		d := NewDecoder(strings.NewReader(xmlInput[i]))
-		var err error
-		for _, err = d.Token(); err == nil; _, err = d.Token() {
-		}
-		if _, ok := err.(*SyntaxError); !ok {
-			t.Fatalf(`xmlInput "%s": expected SyntaxError not received`, xmlInput[i])
-		}
-	}
-}
-
-type allScalars struct {
-	True1     bool
-	True2     bool
-	False1    bool
-	False2    bool
-	Int       int
-	Int8      int8
-	Int16     int16
-	Int32     int32
-	Int64     int64
-	Uint      int
-	Uint8     uint8
-	Uint16    uint16
-	Uint32    uint32
-	Uint64    uint64
-	Uintptr   uintptr
-	Float32   float32
-	Float64   float64
-	String    string
-	PtrString *string
-}
-
-var all = allScalars{
-	True1:     true,
-	True2:     true,
-	False1:    false,
-	False2:    false,
-	Int:       1,
-	Int8:      -2,
-	Int16:     3,
-	Int32:     -4,
-	Int64:     5,
-	Uint:      6,
-	Uint8:     7,
-	Uint16:    8,
-	Uint32:    9,
-	Uint64:    10,
-	Uintptr:   11,
-	Float32:   13.0,
-	Float64:   14.0,
-	String:    "15",
-	PtrString: &sixteen,
-}
-
-var sixteen = "16"
-
-const testScalarsInput = `<allscalars>
-	<True1>true</True1>
-	<True2>1</True2>
-	<False1>false</False1>
-	<False2>0</False2>
-	<Int>1</Int>
-	<Int8>-2</Int8>
-	<Int16>3</Int16>
-	<Int32>-4</Int32>
-	<Int64>5</Int64>
-	<Uint>6</Uint>
-	<Uint8>7</Uint8>
-	<Uint16>8</Uint16>
-	<Uint32>9</Uint32>
-	<Uint64>10</Uint64>
-	<Uintptr>11</Uintptr>
-	<Float>12.0</Float>
-	<Float32>13.0</Float32>
-	<Float64>14.0</Float64>
-	<String>15</String>
-	<PtrString>16</PtrString>
-</allscalars>`
-
-func TestAllScalars(t *testing.T) {
-	var a allScalars
-	err := Unmarshal([]byte(testScalarsInput), &a)
-
-	if err != nil {
-		t.Fatal(err)
-	}
-	if !reflect.DeepEqual(a, all) {
-		t.Errorf("have %+v want %+v", a, all)
-	}
-}
-
-type item struct {
-	Field_a string
-}
-
-func TestIssue569(t *testing.T) {
-	data := `<item><Field_a>abcd</Field_a></item>`
-	var i item
-	err := Unmarshal([]byte(data), &i)
-
-	if err != nil || i.Field_a != "abcd" {
-		t.Fatal("Expecting abcd")
-	}
-}
-
-func TestUnquotedAttrs(t *testing.T) {
-	data := "<tag attr=azAZ09:-_\t>"
-	d := NewDecoder(strings.NewReader(data))
-	d.Strict = false
-	token, err := d.Token()
-	if _, ok := err.(*SyntaxError); ok {
-		t.Errorf("Unexpected error: %v", err)
-	}
-	if token.(StartElement).Name.Local != "tag" {
-		t.Errorf("Unexpected tag name: %v", token.(StartElement).Name.Local)
-	}
-	attr := token.(StartElement).Attr[0]
-	if attr.Value != "azAZ09:-_" {
-		t.Errorf("Unexpected attribute value: %v", attr.Value)
-	}
-	if attr.Name.Local != "attr" {
-		t.Errorf("Unexpected attribute name: %v", attr.Name.Local)
-	}
-}
-
-func TestValuelessAttrs(t *testing.T) {
-	tests := [][3]string{
-		{"<p nowrap>", "p", "nowrap"},
-		{"<p nowrap >", "p", "nowrap"},
-		{"<input checked/>", "input", "checked"},
-		{"<input checked />", "input", "checked"},
-	}
-	for _, test := range tests {
-		d := NewDecoder(strings.NewReader(test[0]))
-		d.Strict = false
-		token, err := d.Token()
-		if _, ok := err.(*SyntaxError); ok {
-			t.Errorf("Unexpected error: %v", err)
-		}
-		if token.(StartElement).Name.Local != test[1] {
-			t.Errorf("Unexpected tag name: %v", token.(StartElement).Name.Local)
-		}
-		attr := token.(StartElement).Attr[0]
-		if attr.Value != test[2] {
-			t.Errorf("Unexpected attribute value: %v", attr.Value)
-		}
-		if attr.Name.Local != test[2] {
-			t.Errorf("Unexpected attribute name: %v", attr.Name.Local)
-		}
-	}
-}
-
-func TestCopyTokenCharData(t *testing.T) {
-	data := []byte("same data")
-	var tok1 Token = CharData(data)
-	tok2 := CopyToken(tok1)
-	if !reflect.DeepEqual(tok1, tok2) {
-		t.Error("CopyToken(CharData) != CharData")
-	}
-	data[1] = 'o'
-	if reflect.DeepEqual(tok1, tok2) {
-		t.Error("CopyToken(CharData) uses same buffer.")
-	}
-}
-
-func TestCopyTokenStartElement(t *testing.T) {
-	elt := StartElement{Name{"", "hello"}, []Attr{{Name{"", "lang"}, "en"}}}
-	var tok1 Token = elt
-	tok2 := CopyToken(tok1)
-	if tok1.(StartElement).Attr[0].Value != "en" {
-		t.Error("CopyToken overwrote Attr[0]")
-	}
-	if !reflect.DeepEqual(tok1, tok2) {
-		t.Error("CopyToken(StartElement) != StartElement")
-	}
-	tok1.(StartElement).Attr[0] = Attr{Name{"", "lang"}, "de"}
-	if reflect.DeepEqual(tok1, tok2) {
-		t.Error("CopyToken(CharData) uses same buffer.")
-	}
-}
-
-func TestSyntaxErrorLineNum(t *testing.T) {
-	testInput := "<P>Foo<P>\n\n<P>Bar</>\n"
-	d := NewDecoder(strings.NewReader(testInput))
-	var err error
-	for _, err = d.Token(); err == nil; _, err = d.Token() {
-	}
-	synerr, ok := err.(*SyntaxError)
-	if !ok {
-		t.Error("Expected SyntaxError.")
-	}
-	if synerr.Line != 3 {
-		t.Error("SyntaxError didn't have correct line number.")
-	}
-}
-
-func TestTrailingRawToken(t *testing.T) {
-	input := `<FOO></FOO>  `
-	d := NewDecoder(strings.NewReader(input))
-	var err error
-	for _, err = d.RawToken(); err == nil; _, err = d.RawToken() {
-	}
-	if err != io.EOF {
-		t.Fatalf("d.RawToken() = _, %v, want _, io.EOF", err)
-	}
-}
-
-func TestTrailingToken(t *testing.T) {
-	input := `<FOO></FOO>  `
-	d := NewDecoder(strings.NewReader(input))
-	var err error
-	for _, err = d.Token(); err == nil; _, err = d.Token() {
-	}
-	if err != io.EOF {
-		t.Fatalf("d.Token() = _, %v, want _, io.EOF", err)
-	}
-}
-
-func TestEntityInsideCDATA(t *testing.T) {
-	input := `<test><![CDATA[ &val=foo ]]></test>`
-	d := NewDecoder(strings.NewReader(input))
-	var err error
-	for _, err = d.Token(); err == nil; _, err = d.Token() {
-	}
-	if err != io.EOF {
-		t.Fatalf("d.Token() = _, %v, want _, io.EOF", err)
-	}
-}
-
-var characterTests = []struct {
-	in  string
-	err string
-}{
-	{"\x12<doc/>", "illegal character code U+0012"},
-	{"<?xml version=\"1.0\"?>\x0b<doc/>", "illegal character code U+000B"},
-	{"\xef\xbf\xbe<doc/>", "illegal character code U+FFFE"},
-	{"<?xml version=\"1.0\"?><doc>\r\n<hiya/>\x07<toots/></doc>", "illegal character code U+0007"},
-	{"<?xml version=\"1.0\"?><doc \x12='value'>what's up</doc>", "expected attribute name in element"},
-	{"<doc>&abc\x01;</doc>", "invalid character entity &abc (no semicolon)"},
-	{"<doc>&\x01;</doc>", "invalid character entity & (no semicolon)"},
-	{"<doc>&\xef\xbf\xbe;</doc>", "invalid character entity &\uFFFE;"},
-	{"<doc>&hello;</doc>", "invalid character entity &hello;"},
-}
-
-func TestDisallowedCharacters(t *testing.T) {
-
-	for i, tt := range characterTests {
-		d := NewDecoder(strings.NewReader(tt.in))
-		var err error
-
-		for err == nil {
-			_, err = d.Token()
-		}
-		synerr, ok := err.(*SyntaxError)
-		if !ok {
-			t.Fatalf("input %d d.Token() = _, %v, want _, *SyntaxError", i, err)
-		}
-		if synerr.Msg != tt.err {
-			t.Fatalf("input %d synerr.Msg wrong: want %q, got %q", i, tt.err, synerr.Msg)
-		}
-	}
-}
-
-type procInstEncodingTest struct {
-	expect, got string
-}
-
-var procInstTests = []struct {
-	input, expect string
-}{
-	{`version="1.0" encoding="utf-8"`, "utf-8"},
-	{`version="1.0" encoding='utf-8'`, "utf-8"},
-	{`version="1.0" encoding='utf-8' `, "utf-8"},
-	{`version="1.0" encoding=utf-8`, ""},
-	{`encoding="FOO" `, "FOO"},
-}
-
-func TestProcInstEncoding(t *testing.T) {
-	for _, test := range procInstTests {
-		got := procInstEncoding(test.input)
-		if got != test.expect {
-			t.Errorf("procInstEncoding(%q) = %q; want %q", test.input, got, test.expect)
-		}
-	}
-}
-
-// Ensure that directives with comments include the complete
-// text of any nested directives.
-
-var directivesWithCommentsInput = `
-<!DOCTYPE [<!-- a comment --><!ENTITY rdf "http://www.w3.org/1999/02/22-rdf-syntax-ns#">]>
-<!DOCTYPE [<!ENTITY go "Golang"><!-- a comment-->]>
-<!DOCTYPE <!-> <!> <!----> <!-->--> <!--->--> [<!ENTITY go "Golang"><!-- a comment-->]>
-`
-
-var directivesWithCommentsTokens = []Token{
-	CharData("\n"),
-	Directive(`DOCTYPE [<!ENTITY rdf "http://www.w3.org/1999/02/22-rdf-syntax-ns#">]`),
-	CharData("\n"),
-	Directive(`DOCTYPE [<!ENTITY go "Golang">]`),
-	CharData("\n"),
-	Directive(`DOCTYPE <!-> <!>    [<!ENTITY go "Golang">]`),
-	CharData("\n"),
-}
-
-func TestDirectivesWithComments(t *testing.T) {
-	d := NewDecoder(strings.NewReader(directivesWithCommentsInput))
-
-	for i, want := range directivesWithCommentsTokens {
-		have, err := d.Token()
-		if err != nil {
-			t.Fatalf("token %d: unexpected error: %s", i, err)
-		}
-		if !reflect.DeepEqual(have, want) {
-			t.Errorf("token %d = %#v want %#v", i, have, want)
-		}
-	}
-}
-
-// Writer whose Write method always returns an error.
-type errWriter struct{}
-
-func (errWriter) Write(p []byte) (n int, err error) { return 0, fmt.Errorf("unwritable") }
-
-func TestEscapeTextIOErrors(t *testing.T) {
-	expectErr := "unwritable"
-	err := EscapeText(errWriter{}, []byte{'A'})
-
-	if err == nil || err.Error() != expectErr {
-		t.Errorf("have %v, want %v", err, expectErr)
-	}
-}
-
-func TestEscapeTextInvalidChar(t *testing.T) {
-	input := []byte("A \x00 terminated string.")
-	expected := "A \uFFFD terminated string."
-
-	buff := new(bytes.Buffer)
-	if err := EscapeText(buff, input); err != nil {
-		t.Fatalf("have %v, want nil", err)
-	}
-	text := buff.String()
-
-	if text != expected {
-		t.Errorf("have %v, want %v", text, expected)
-	}
-}
-
-func TestIssue5880(t *testing.T) {
-	type T []byte
-	data, err := Marshal(T{192, 168, 0, 1})
-	if err != nil {
-		t.Errorf("Marshal error: %v", err)
-	}
-	if !utf8.Valid(data) {
-		t.Errorf("Marshal generated invalid UTF-8: %x", data)
-	}
-}
diff --git a/src/pkg/flag/flag.go b/src/pkg/flag/flag.go
deleted file mode 100644
index cd2a165..0000000
--- a/src/pkg/flag/flag.go
+++ /dev/null
@@ -1,849 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-/*
-	Package flag implements command-line flag parsing.
-
-	Usage:
-
-	Define flags using flag.String(), Bool(), Int(), etc.
-
-	This declares an integer flag, -flagname, stored in the pointer ip, with type *int.
-		import "flag"
-		var ip = flag.Int("flagname", 1234, "help message for flagname")
-	If you like, you can bind the flag to a variable using the Var() functions.
-		var flagvar int
-		func init() {
-			flag.IntVar(&flagvar, "flagname", 1234, "help message for flagname")
-		}
-	Or you can create custom flags that satisfy the Value interface (with
-	pointer receivers) and couple them to flag parsing by
-		flag.Var(&flagVal, "name", "help message for flagname")
-	For such flags, the default value is just the initial value of the variable.
-
-	After all flags are defined, call
-		flag.Parse()
-	to parse the command line into the defined flags.
-
-	Flags may then be used directly. If you're using the flags themselves,
-	they are all pointers; if you bind to variables, they're values.
-		fmt.Println("ip has value ", *ip)
-		fmt.Println("flagvar has value ", flagvar)
-
-	After parsing, the arguments after the flag are available as the
-	slice flag.Args() or individually as flag.Arg(i).
-	The arguments are indexed from 0 through flag.NArg()-1.
-
-	Command line flag syntax:
-		-flag
-		-flag=x
-		-flag x  // non-boolean flags only
-	One or two minus signs may be used; they are equivalent.
-	The last form is not permitted for boolean flags because the
-	meaning of the command
-		cmd -x *
-	will change if there is a file called 0, false, etc.  You must
-	use the -flag=false form to turn off a boolean flag.
-
-	Flag parsing stops just before the first non-flag argument
-	("-" is a non-flag argument) or after the terminator "--".
-
-	Integer flags accept 1234, 0664, 0x1234 and may be negative.
-	Boolean flags may be:
-		1, 0, t, f, T, F, true, false, TRUE, FALSE, True, False
-	Duration flags accept any input valid for time.ParseDuration.
-
-	The default set of command-line flags is controlled by
-	top-level functions.  The FlagSet type allows one to define
-	independent sets of flags, such as to implement subcommands
-	in a command-line interface. The methods of FlagSet are
-	analogous to the top-level functions for the command-line
-	flag set.
-*/
-package flag
-
-import (
-	"errors"
-	"fmt"
-	"io"
-	"os"
-	"sort"
-	"strconv"
-	"time"
-)
-
-// ErrHelp is the error returned if the flag -help is invoked but no such flag is defined.
-var ErrHelp = errors.New("flag: help requested")
-
-// -- bool Value
-type boolValue bool
-
-func newBoolValue(val bool, p *bool) *boolValue {
-	*p = val
-	return (*boolValue)(p)
-}
-
-func (b *boolValue) Set(s string) error {
-	v, err := strconv.ParseBool(s)
-	*b = boolValue(v)
-	return err
-}
-
-func (b *boolValue) Get() interface{} { return bool(*b) }
-
-func (b *boolValue) String() string { return fmt.Sprintf("%v", *b) }
-
-func (b *boolValue) IsBoolFlag() bool { return true }
-
-// optional interface to indicate boolean flags that can be
-// supplied without "=value" text
-type boolFlag interface {
-	Value
-	IsBoolFlag() bool
-}
-
-// -- int Value
-type intValue int
-
-func newIntValue(val int, p *int) *intValue {
-	*p = val
-	return (*intValue)(p)
-}
-
-func (i *intValue) Set(s string) error {
-	v, err := strconv.ParseInt(s, 0, 64)
-	*i = intValue(v)
-	return err
-}
-
-func (i *intValue) Get() interface{} { return int(*i) }
-
-func (i *intValue) String() string { return fmt.Sprintf("%v", *i) }
-
-// -- int64 Value
-type int64Value int64
-
-func newInt64Value(val int64, p *int64) *int64Value {
-	*p = val
-	return (*int64Value)(p)
-}
-
-func (i *int64Value) Set(s string) error {
-	v, err := strconv.ParseInt(s, 0, 64)
-	*i = int64Value(v)
-	return err
-}
-
-func (i *int64Value) Get() interface{} { return int64(*i) }
-
-func (i *int64Value) String() string { return fmt.Sprintf("%v", *i) }
-
-// -- uint Value
-type uintValue uint
-
-func newUintValue(val uint, p *uint) *uintValue {
-	*p = val
-	return (*uintValue)(p)
-}
-
-func (i *uintValue) Set(s string) error {
-	v, err := strconv.ParseUint(s, 0, 64)
-	*i = uintValue(v)
-	return err
-}
-
-func (i *uintValue) Get() interface{} { return uint(*i) }
-
-func (i *uintValue) String() string { return fmt.Sprintf("%v", *i) }
-
-// -- uint64 Value
-type uint64Value uint64
-
-func newUint64Value(val uint64, p *uint64) *uint64Value {
-	*p = val
-	return (*uint64Value)(p)
-}
-
-func (i *uint64Value) Set(s string) error {
-	v, err := strconv.ParseUint(s, 0, 64)
-	*i = uint64Value(v)
-	return err
-}
-
-func (i *uint64Value) Get() interface{} { return uint64(*i) }
-
-func (i *uint64Value) String() string { return fmt.Sprintf("%v", *i) }
-
-// -- string Value
-type stringValue string
-
-func newStringValue(val string, p *string) *stringValue {
-	*p = val
-	return (*stringValue)(p)
-}
-
-func (s *stringValue) Set(val string) error {
-	*s = stringValue(val)
-	return nil
-}
-
-func (s *stringValue) Get() interface{} { return string(*s) }
-
-func (s *stringValue) String() string { return fmt.Sprintf("%s", *s) }
-
-// -- float64 Value
-type float64Value float64
-
-func newFloat64Value(val float64, p *float64) *float64Value {
-	*p = val
-	return (*float64Value)(p)
-}
-
-func (f *float64Value) Set(s string) error {
-	v, err := strconv.ParseFloat(s, 64)
-	*f = float64Value(v)
-	return err
-}
-
-func (f *float64Value) Get() interface{} { return float64(*f) }
-
-func (f *float64Value) String() string { return fmt.Sprintf("%v", *f) }
-
-// -- time.Duration Value
-type durationValue time.Duration
-
-func newDurationValue(val time.Duration, p *time.Duration) *durationValue {
-	*p = val
-	return (*durationValue)(p)
-}
-
-func (d *durationValue) Set(s string) error {
-	v, err := time.ParseDuration(s)
-	*d = durationValue(v)
-	return err
-}
-
-func (d *durationValue) Get() interface{} { return time.Duration(*d) }
-
-func (d *durationValue) String() string { return (*time.Duration)(d).String() }
-
-// Value is the interface to the dynamic value stored in a flag.
-// (The default value is represented as a string.)
-//
-// If a Value has an IsBoolFlag() bool method returning true,
-// the command-line parser makes -name equivalent to -name=true
-// rather than using the next command-line argument.
-type Value interface {
-	String() string
-	Set(string) error
-}
-
-// Getter is an interface that allows the contents of a Value to be retrieved.
-// It wraps the Value interface, rather than being part of it, because it
-// appeared after Go 1 and its compatibility rules. All Value types provided
-// by this package satisfy the Getter interface.
-type Getter interface {
-	Value
-	Get() interface{}
-}
-
-// ErrorHandling defines how to handle flag parsing errors.
-type ErrorHandling int
-
-const (
-	ContinueOnError ErrorHandling = iota
-	ExitOnError
-	PanicOnError
-)
-
-// A FlagSet represents a set of defined flags.  The zero value of a FlagSet
-// has no name and has ContinueOnError error handling.
-type FlagSet struct {
-	// Usage is the function called when an error occurs while parsing flags.
-	// The field is a function (not a method) that may be changed to point to
-	// a custom error handler.
-	Usage func()
-
-	name          string
-	parsed        bool
-	actual        map[string]*Flag
-	formal        map[string]*Flag
-	args          []string // arguments after flags
-	errorHandling ErrorHandling
-	output        io.Writer // nil means stderr; use out() accessor
-}
-
-// A Flag represents the state of a flag.
-type Flag struct {
-	Name     string // name as it appears on command line
-	Usage    string // help message
-	Value    Value  // value as set
-	DefValue string // default value (as text); for usage message
-}
-
-// sortFlags returns the flags as a slice in lexicographical sorted order.
-func sortFlags(flags map[string]*Flag) []*Flag {
-	list := make(sort.StringSlice, len(flags))
-	i := 0
-	for _, f := range flags {
-		list[i] = f.Name
-		i++
-	}
-	list.Sort()
-	result := make([]*Flag, len(list))
-	for i, name := range list {
-		result[i] = flags[name]
-	}
-	return result
-}
-
-func (f *FlagSet) out() io.Writer {
-	if f.output == nil {
-		return os.Stderr
-	}
-	return f.output
-}
-
-// SetOutput sets the destination for usage and error messages.
-// If output is nil, os.Stderr is used.
-func (f *FlagSet) SetOutput(output io.Writer) {
-	f.output = output
-}
-
-// VisitAll visits the flags in lexicographical order, calling fn for each.
-// It visits all flags, even those not set.
-func (f *FlagSet) VisitAll(fn func(*Flag)) {
-	for _, flag := range sortFlags(f.formal) {
-		fn(flag)
-	}
-}
-
-// VisitAll visits the command-line flags in lexicographical order, calling
-// fn for each.  It visits all flags, even those not set.
-func VisitAll(fn func(*Flag)) {
-	CommandLine.VisitAll(fn)
-}
-
-// Visit visits the flags in lexicographical order, calling fn for each.
-// It visits only those flags that have been set.
-func (f *FlagSet) Visit(fn func(*Flag)) {
-	for _, flag := range sortFlags(f.actual) {
-		fn(flag)
-	}
-}
-
-// Visit visits the command-line flags in lexicographical order, calling fn
-// for each.  It visits only those flags that have been set.
-func Visit(fn func(*Flag)) {
-	CommandLine.Visit(fn)
-}
-
-// Lookup returns the Flag structure of the named flag, returning nil if none exists.
-func (f *FlagSet) Lookup(name string) *Flag {
-	return f.formal[name]
-}
-
-// Lookup returns the Flag structure of the named command-line flag,
-// returning nil if none exists.
-func Lookup(name string) *Flag {
-	return CommandLine.formal[name]
-}
-
-// Set sets the value of the named flag.
-func (f *FlagSet) Set(name, value string) error {
-	flag, ok := f.formal[name]
-	if !ok {
-		return fmt.Errorf("no such flag -%v", name)
-	}
-	err := flag.Value.Set(value)
-	if err != nil {
-		return err
-	}
-	if f.actual == nil {
-		f.actual = make(map[string]*Flag)
-	}
-	f.actual[name] = flag
-	return nil
-}
-
-// Set sets the value of the named command-line flag.
-func Set(name, value string) error {
-	return CommandLine.Set(name, value)
-}
-
-// PrintDefaults prints, to standard error unless configured
-// otherwise, the default values of all defined flags in the set.
-func (f *FlagSet) PrintDefaults() {
-	f.VisitAll(func(flag *Flag) {
-		format := "  -%s=%s: %s\n"
-		if _, ok := flag.Value.(*stringValue); ok {
-			// put quotes on the value
-			format = "  -%s=%q: %s\n"
-		}
-		fmt.Fprintf(f.out(), format, flag.Name, flag.DefValue, flag.Usage)
-	})
-}
-
-// PrintDefaults prints to standard error the default values of all defined command-line flags.
-func PrintDefaults() {
-	CommandLine.PrintDefaults()
-}
-
-// defaultUsage is the default function to print a usage message.
-func defaultUsage(f *FlagSet) {
-	if f.name == "" {
-		fmt.Fprintf(f.out(), "Usage:\n")
-	} else {
-		fmt.Fprintf(f.out(), "Usage of %s:\n", f.name)
-	}
-	f.PrintDefaults()
-}
-
-// NOTE: Usage is not just defaultUsage(CommandLine)
-// because it serves (via godoc flag Usage) as the example
-// for how to write your own usage function.
-
-// Usage prints to standard error a usage message documenting all defined command-line flags.
-// The function is a variable that may be changed to point to a custom function.
-var Usage = func() {
-	fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
-	PrintDefaults()
-}
-
-// NFlag returns the number of flags that have been set.
-func (f *FlagSet) NFlag() int { return len(f.actual) }
-
-// NFlag returns the number of command-line flags that have been set.
-func NFlag() int { return len(CommandLine.actual) }
-
-// Arg returns the i'th argument.  Arg(0) is the first remaining argument
-// after flags have been processed.
-func (f *FlagSet) Arg(i int) string {
-	if i < 0 || i >= len(f.args) {
-		return ""
-	}
-	return f.args[i]
-}
-
-// Arg returns the i'th command-line argument.  Arg(0) is the first remaining argument
-// after flags have been processed.
-func Arg(i int) string {
-	return CommandLine.Arg(i)
-}
-
-// NArg is the number of arguments remaining after flags have been processed.
-func (f *FlagSet) NArg() int { return len(f.args) }
-
-// NArg is the number of arguments remaining after flags have been processed.
-func NArg() int { return len(CommandLine.args) }
-
-// Args returns the non-flag arguments.
-func (f *FlagSet) Args() []string { return f.args }
-
-// Args returns the non-flag command-line arguments.
-func Args() []string { return CommandLine.args }
-
-// BoolVar defines a bool flag with specified name, default value, and usage string.
-// The argument p points to a bool variable in which to store the value of the flag.
-func (f *FlagSet) BoolVar(p *bool, name string, value bool, usage string) {
-	f.Var(newBoolValue(value, p), name, usage)
-}
-
-// BoolVar defines a bool flag with specified name, default value, and usage string.
-// The argument p points to a bool variable in which to store the value of the flag.
-func BoolVar(p *bool, name string, value bool, usage string) {
-	CommandLine.Var(newBoolValue(value, p), name, usage)
-}
-
-// Bool defines a bool flag with specified name, default value, and usage string.
-// The return value is the address of a bool variable that stores the value of the flag.
-func (f *FlagSet) Bool(name string, value bool, usage string) *bool {
-	p := new(bool)
-	f.BoolVar(p, name, value, usage)
-	return p
-}
-
-// Bool defines a bool flag with specified name, default value, and usage string.
-// The return value is the address of a bool variable that stores the value of the flag.
-func Bool(name string, value bool, usage string) *bool {
-	return CommandLine.Bool(name, value, usage)
-}
-
-// IntVar defines an int flag with specified name, default value, and usage string.
-// The argument p points to an int variable in which to store the value of the flag.
-func (f *FlagSet) IntVar(p *int, name string, value int, usage string) {
-	f.Var(newIntValue(value, p), name, usage)
-}
-
-// IntVar defines an int flag with specified name, default value, and usage string.
-// The argument p points to an int variable in which to store the value of the flag.
-func IntVar(p *int, name string, value int, usage string) {
-	CommandLine.Var(newIntValue(value, p), name, usage)
-}
-
-// Int defines an int flag with specified name, default value, and usage string.
-// The return value is the address of an int variable that stores the value of the flag.
-func (f *FlagSet) Int(name string, value int, usage string) *int {
-	p := new(int)
-	f.IntVar(p, name, value, usage)
-	return p
-}
-
-// Int defines an int flag with specified name, default value, and usage string.
-// The return value is the address of an int variable that stores the value of the flag.
-func Int(name string, value int, usage string) *int {
-	return CommandLine.Int(name, value, usage)
-}
-
-// Int64Var defines an int64 flag with specified name, default value, and usage string.
-// The argument p points to an int64 variable in which to store the value of the flag.
-func (f *FlagSet) Int64Var(p *int64, name string, value int64, usage string) {
-	f.Var(newInt64Value(value, p), name, usage)
-}
-
-// Int64Var defines an int64 flag with specified name, default value, and usage string.
-// The argument p points to an int64 variable in which to store the value of the flag.
-func Int64Var(p *int64, name string, value int64, usage string) {
-	CommandLine.Var(newInt64Value(value, p), name, usage)
-}
-
-// Int64 defines an int64 flag with specified name, default value, and usage string.
-// The return value is the address of an int64 variable that stores the value of the flag.
-func (f *FlagSet) Int64(name string, value int64, usage string) *int64 {
-	p := new(int64)
-	f.Int64Var(p, name, value, usage)
-	return p
-}
-
-// Int64 defines an int64 flag with specified name, default value, and usage string.
-// The return value is the address of an int64 variable that stores the value of the flag.
-func Int64(name string, value int64, usage string) *int64 {
-	return CommandLine.Int64(name, value, usage)
-}
-
-// UintVar defines a uint flag with specified name, default value, and usage string.
-// The argument p points to a uint variable in which to store the value of the flag.
-func (f *FlagSet) UintVar(p *uint, name string, value uint, usage string) {
-	f.Var(newUintValue(value, p), name, usage)
-}
-
-// UintVar defines a uint flag with specified name, default value, and usage string.
-// The argument p points to a uint  variable in which to store the value of the flag.
-func UintVar(p *uint, name string, value uint, usage string) {
-	CommandLine.Var(newUintValue(value, p), name, usage)
-}
-
-// Uint defines a uint flag with specified name, default value, and usage string.
-// The return value is the address of a uint  variable that stores the value of the flag.
-func (f *FlagSet) Uint(name string, value uint, usage string) *uint {
-	p := new(uint)
-	f.UintVar(p, name, value, usage)
-	return p
-}
-
-// Uint defines a uint flag with specified name, default value, and usage string.
-// The return value is the address of a uint  variable that stores the value of the flag.
-func Uint(name string, value uint, usage string) *uint {
-	return CommandLine.Uint(name, value, usage)
-}
-
-// Uint64Var defines a uint64 flag with specified name, default value, and usage string.
-// The argument p points to a uint64 variable in which to store the value of the flag.
-func (f *FlagSet) Uint64Var(p *uint64, name string, value uint64, usage string) {
-	f.Var(newUint64Value(value, p), name, usage)
-}
-
-// Uint64Var defines a uint64 flag with specified name, default value, and usage string.
-// The argument p points to a uint64 variable in which to store the value of the flag.
-func Uint64Var(p *uint64, name string, value uint64, usage string) {
-	CommandLine.Var(newUint64Value(value, p), name, usage)
-}
-
-// Uint64 defines a uint64 flag with specified name, default value, and usage string.
-// The return value is the address of a uint64 variable that stores the value of the flag.
-func (f *FlagSet) Uint64(name string, value uint64, usage string) *uint64 {
-	p := new(uint64)
-	f.Uint64Var(p, name, value, usage)
-	return p
-}
-
-// Uint64 defines a uint64 flag with specified name, default value, and usage string.
-// The return value is the address of a uint64 variable that stores the value of the flag.
-func Uint64(name string, value uint64, usage string) *uint64 {
-	return CommandLine.Uint64(name, value, usage)
-}
-
-// StringVar defines a string flag with specified name, default value, and usage string.
-// The argument p points to a string variable in which to store the value of the flag.
-func (f *FlagSet) StringVar(p *string, name string, value string, usage string) {
-	f.Var(newStringValue(value, p), name, usage)
-}
-
-// StringVar defines a string flag with specified name, default value, and usage string.
-// The argument p points to a string variable in which to store the value of the flag.
-func StringVar(p *string, name string, value string, usage string) {
-	CommandLine.Var(newStringValue(value, p), name, usage)
-}
-
-// String defines a string flag with specified name, default value, and usage string.
-// The return value is the address of a string variable that stores the value of the flag.
-func (f *FlagSet) String(name string, value string, usage string) *string {
-	p := new(string)
-	f.StringVar(p, name, value, usage)
-	return p
-}
-
-// String defines a string flag with specified name, default value, and usage string.
-// The return value is the address of a string variable that stores the value of the flag.
-func String(name string, value string, usage string) *string {
-	return CommandLine.String(name, value, usage)
-}
-
-// Float64Var defines a float64 flag with specified name, default value, and usage string.
-// The argument p points to a float64 variable in which to store the value of the flag.
-func (f *FlagSet) Float64Var(p *float64, name string, value float64, usage string) {
-	f.Var(newFloat64Value(value, p), name, usage)
-}
-
-// Float64Var defines a float64 flag with specified name, default value, and usage string.
-// The argument p points to a float64 variable in which to store the value of the flag.
-func Float64Var(p *float64, name string, value float64, usage string) {
-	CommandLine.Var(newFloat64Value(value, p), name, usage)
-}
-
-// Float64 defines a float64 flag with specified name, default value, and usage string.
-// The return value is the address of a float64 variable that stores the value of the flag.
-func (f *FlagSet) Float64(name string, value float64, usage string) *float64 {
-	p := new(float64)
-	f.Float64Var(p, name, value, usage)
-	return p
-}
-
-// Float64 defines a float64 flag with specified name, default value, and usage string.
-// The return value is the address of a float64 variable that stores the value of the flag.
-func Float64(name string, value float64, usage string) *float64 {
-	return CommandLine.Float64(name, value, usage)
-}
-
-// DurationVar defines a time.Duration flag with specified name, default value, and usage string.
-// The argument p points to a time.Duration variable in which to store the value of the flag.
-func (f *FlagSet) DurationVar(p *time.Duration, name string, value time.Duration, usage string) {
-	f.Var(newDurationValue(value, p), name, usage)
-}
-
-// DurationVar defines a time.Duration flag with specified name, default value, and usage string.
-// The argument p points to a time.Duration variable in which to store the value of the flag.
-func DurationVar(p *time.Duration, name string, value time.Duration, usage string) {
-	CommandLine.Var(newDurationValue(value, p), name, usage)
-}
-
-// Duration defines a time.Duration flag with specified name, default value, and usage string.
-// The return value is the address of a time.Duration variable that stores the value of the flag.
-func (f *FlagSet) Duration(name string, value time.Duration, usage string) *time.Duration {
-	p := new(time.Duration)
-	f.DurationVar(p, name, value, usage)
-	return p
-}
-
-// Duration defines a time.Duration flag with specified name, default value, and usage string.
-// The return value is the address of a time.Duration variable that stores the value of the flag.
-func Duration(name string, value time.Duration, usage string) *time.Duration {
-	return CommandLine.Duration(name, value, usage)
-}
-
-// Var defines a flag with the specified name and usage string. The type and
-// value of the flag are represented by the first argument, of type Value, which
-// typically holds a user-defined implementation of Value. For instance, the
-// caller could create a flag that turns a comma-separated string into a slice
-// of strings by giving the slice the methods of Value; in particular, Set would
-// decompose the comma-separated string into the slice.
-func (f *FlagSet) Var(value Value, name string, usage string) {
-	// Remember the default value as a string; it won't change.
-	flag := &Flag{name, usage, value, value.String()}
-	_, alreadythere := f.formal[name]
-	if alreadythere {
-		var msg string
-		if f.name == "" {
-			msg = fmt.Sprintf("flag redefined: %s", name)
-		} else {
-			msg = fmt.Sprintf("%s flag redefined: %s", f.name, name)
-		}
-		fmt.Fprintln(f.out(), msg)
-		panic(msg) // Happens only if flags are declared with identical names
-	}
-	if f.formal == nil {
-		f.formal = make(map[string]*Flag)
-	}
-	f.formal[name] = flag
-}
-
-// Var defines a flag with the specified name and usage string. The type and
-// value of the flag are represented by the first argument, of type Value, which
-// typically holds a user-defined implementation of Value. For instance, the
-// caller could create a flag that turns a comma-separated string into a slice
-// of strings by giving the slice the methods of Value; in particular, Set would
-// decompose the comma-separated string into the slice.
-func Var(value Value, name string, usage string) {
-	CommandLine.Var(value, name, usage)
-}
-
-// failf prints to standard error a formatted error and usage message and
-// returns the error.
-func (f *FlagSet) failf(format string, a ...interface{}) error {
-	err := fmt.Errorf(format, a...)
-	fmt.Fprintln(f.out(), err)
-	f.usage()
-	return err
-}
-
-// usage calls the Usage method for the flag set, or the usage function if
-// the flag set is CommandLine.
-func (f *FlagSet) usage() {
-	if f == CommandLine {
-		Usage()
-	} else if f.Usage == nil {
-		defaultUsage(f)
-	} else {
-		f.Usage()
-	}
-}
-
-// parseOne parses one flag. It reports whether a flag was seen.
-func (f *FlagSet) parseOne() (bool, error) {
-	if len(f.args) == 0 {
-		return false, nil
-	}
-	s := f.args[0]
-	if len(s) == 0 || s[0] != '-' || len(s) == 1 {
-		return false, nil
-	}
-	num_minuses := 1
-	if s[1] == '-' {
-		num_minuses++
-		if len(s) == 2 { // "--" terminates the flags
-			f.args = f.args[1:]
-			return false, nil
-		}
-	}
-	name := s[num_minuses:]
-	if len(name) == 0 || name[0] == '-' || name[0] == '=' {
-		return false, f.failf("bad flag syntax: %s", s)
-	}
-
-	// it's a flag. does it have an argument?
-	f.args = f.args[1:]
-	has_value := false
-	value := ""
-	for i := 1; i < len(name); i++ { // equals cannot be first
-		if name[i] == '=' {
-			value = name[i+1:]
-			has_value = true
-			name = name[0:i]
-			break
-		}
-	}
-	m := f.formal
-	flag, alreadythere := m[name] // BUG
-	if !alreadythere {
-		if name == "help" || name == "h" { // special case for nice help message.
-			f.usage()
-			return false, ErrHelp
-		}
-		return false, f.failf("flag provided but not defined: -%s", name)
-	}
-	if fv, ok := flag.Value.(boolFlag); ok && fv.IsBoolFlag() { // special case: doesn't need an arg
-		if has_value {
-			if err := fv.Set(value); err != nil {
-				return false, f.failf("invalid boolean value %q for -%s: %v", value, name, err)
-			}
-		} else {
-			fv.Set("true")
-		}
-	} else {
-		// It must have a value, which might be the next argument.
-		if !has_value && len(f.args) > 0 {
-			// value is the next arg
-			has_value = true
-			value, f.args = f.args[0], f.args[1:]
-		}
-		if !has_value {
-			return false, f.failf("flag needs an argument: -%s", name)
-		}
-		if err := flag.Value.Set(value); err != nil {
-			return false, f.failf("invalid value %q for flag -%s: %v", value, name, err)
-		}
-	}
-	if f.actual == nil {
-		f.actual = make(map[string]*Flag)
-	}
-	f.actual[name] = flag
-	return true, nil
-}
-
-// Parse parses flag definitions from the argument list, which should not
-// include the command name.  Must be called after all flags in the FlagSet
-// are defined and before flags are accessed by the program.
-// The return value will be ErrHelp if -help was set but not defined.
-func (f *FlagSet) Parse(arguments []string) error {
-	f.parsed = true
-	f.args = arguments
-	for {
-		seen, err := f.parseOne()
-		if seen {
-			continue
-		}
-		if err == nil {
-			break
-		}
-		switch f.errorHandling {
-		case ContinueOnError:
-			return err
-		case ExitOnError:
-			os.Exit(2)
-		case PanicOnError:
-			panic(err)
-		}
-	}
-	return nil
-}
-
-// Parsed reports whether f.Parse has been called.
-func (f *FlagSet) Parsed() bool {
-	return f.parsed
-}
-
-// Parse parses the command-line flags from os.Args[1:].  Must be called
-// after all flags are defined and before flags are accessed by the program.
-func Parse() {
-	// Ignore errors; CommandLine is set for ExitOnError.
-	CommandLine.Parse(os.Args[1:])
-}
-
-// Parsed returns true if the command-line flags have been parsed.
-func Parsed() bool {
-	return CommandLine.Parsed()
-}
-
-// CommandLine is the default set of command-line flags, parsed from os.Args.
-// The top-level functions such as BoolVar, Arg, and on are wrappers for the
-// methods of CommandLine.
-var CommandLine = NewFlagSet(os.Args[0], ExitOnError)
-
-// NewFlagSet returns a new, empty flag set with the specified name and
-// error handling property.
-func NewFlagSet(name string, errorHandling ErrorHandling) *FlagSet {
-	f := &FlagSet{
-		name:          name,
-		errorHandling: errorHandling,
-	}
-	return f
-}
-
-// Init sets the name and error handling property for a flag set.
-// By default, the zero FlagSet uses an empty name and the
-// ContinueOnError error handling policy.
-func (f *FlagSet) Init(name string, errorHandling ErrorHandling) {
-	f.name = name
-	f.errorHandling = errorHandling
-}
diff --git a/src/pkg/flag/flag_test.go b/src/pkg/flag/flag_test.go
deleted file mode 100644
index 2c03872..0000000
--- a/src/pkg/flag/flag_test.go
+++ /dev/null
@@ -1,369 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package flag_test
-
-import (
-	"bytes"
-	. "flag"
-	"fmt"
-	"os"
-	"sort"
-	"strings"
-	"testing"
-	"time"
-)
-
-func boolString(s string) string {
-	if s == "0" {
-		return "false"
-	}
-	return "true"
-}
-
-func TestEverything(t *testing.T) {
-	ResetForTesting(nil)
-	Bool("test_bool", false, "bool value")
-	Int("test_int", 0, "int value")
-	Int64("test_int64", 0, "int64 value")
-	Uint("test_uint", 0, "uint value")
-	Uint64("test_uint64", 0, "uint64 value")
-	String("test_string", "0", "string value")
-	Float64("test_float64", 0, "float64 value")
-	Duration("test_duration", 0, "time.Duration value")
-
-	m := make(map[string]*Flag)
-	desired := "0"
-	visitor := func(f *Flag) {
-		if len(f.Name) > 5 && f.Name[0:5] == "test_" {
-			m[f.Name] = f
-			ok := false
-			switch {
-			case f.Value.String() == desired:
-				ok = true
-			case f.Name == "test_bool" && f.Value.String() == boolString(desired):
-				ok = true
-			case f.Name == "test_duration" && f.Value.String() == desired+"s":
-				ok = true
-			}
-			if !ok {
-				t.Error("Visit: bad value", f.Value.String(), "for", f.Name)
-			}
-		}
-	}
-	VisitAll(visitor)
-	if len(m) != 8 {
-		t.Error("VisitAll misses some flags")
-		for k, v := range m {
-			t.Log(k, *v)
-		}
-	}
-	m = make(map[string]*Flag)
-	Visit(visitor)
-	if len(m) != 0 {
-		t.Errorf("Visit sees unset flags")
-		for k, v := range m {
-			t.Log(k, *v)
-		}
-	}
-	// Now set all flags
-	Set("test_bool", "true")
-	Set("test_int", "1")
-	Set("test_int64", "1")
-	Set("test_uint", "1")
-	Set("test_uint64", "1")
-	Set("test_string", "1")
-	Set("test_float64", "1")
-	Set("test_duration", "1s")
-	desired = "1"
-	Visit(visitor)
-	if len(m) != 8 {
-		t.Error("Visit fails after set")
-		for k, v := range m {
-			t.Log(k, *v)
-		}
-	}
-	// Now test they're visited in sort order.
-	var flagNames []string
-	Visit(func(f *Flag) { flagNames = append(flagNames, f.Name) })
-	if !sort.StringsAreSorted(flagNames) {
-		t.Errorf("flag names not sorted: %v", flagNames)
-	}
-}
-
-func TestGet(t *testing.T) {
-	ResetForTesting(nil)
-	Bool("test_bool", true, "bool value")
-	Int("test_int", 1, "int value")
-	Int64("test_int64", 2, "int64 value")
-	Uint("test_uint", 3, "uint value")
-	Uint64("test_uint64", 4, "uint64 value")
-	String("test_string", "5", "string value")
-	Float64("test_float64", 6, "float64 value")
-	Duration("test_duration", 7, "time.Duration value")
-
-	visitor := func(f *Flag) {
-		if len(f.Name) > 5 && f.Name[0:5] == "test_" {
-			g, ok := f.Value.(Getter)
-			if !ok {
-				t.Errorf("Visit: value does not satisfy Getter: %T", f.Value)
-				return
-			}
-			switch f.Name {
-			case "test_bool":
-				ok = g.Get() == true
-			case "test_int":
-				ok = g.Get() == int(1)
-			case "test_int64":
-				ok = g.Get() == int64(2)
-			case "test_uint":
-				ok = g.Get() == uint(3)
-			case "test_uint64":
-				ok = g.Get() == uint64(4)
-			case "test_string":
-				ok = g.Get() == "5"
-			case "test_float64":
-				ok = g.Get() == float64(6)
-			case "test_duration":
-				ok = g.Get() == time.Duration(7)
-			}
-			if !ok {
-				t.Errorf("Visit: bad value %T(%v) for %s", g.Get(), g.Get(), f.Name)
-			}
-		}
-	}
-	VisitAll(visitor)
-}
-
-func TestUsage(t *testing.T) {
-	called := false
-	ResetForTesting(func() { called = true })
-	if CommandLine.Parse([]string{"-x"}) == nil {
-		t.Error("parse did not fail for unknown flag")
-	}
-	if !called {
-		t.Error("did not call Usage for unknown flag")
-	}
-}
-
-func testParse(f *FlagSet, t *testing.T) {
-	if f.Parsed() {
-		t.Error("f.Parse() = true before Parse")
-	}
-	boolFlag := f.Bool("bool", false, "bool value")
-	bool2Flag := f.Bool("bool2", false, "bool2 value")
-	intFlag := f.Int("int", 0, "int value")
-	int64Flag := f.Int64("int64", 0, "int64 value")
-	uintFlag := f.Uint("uint", 0, "uint value")
-	uint64Flag := f.Uint64("uint64", 0, "uint64 value")
-	stringFlag := f.String("string", "0", "string value")
-	float64Flag := f.Float64("float64", 0, "float64 value")
-	durationFlag := f.Duration("duration", 5*time.Second, "time.Duration value")
-	extra := "one-extra-argument"
-	args := []string{
-		"-bool",
-		"-bool2=true",
-		"--int", "22",
-		"--int64", "0x23",
-		"-uint", "24",
-		"--uint64", "25",
-		"-string", "hello",
-		"-float64", "2718e28",
-		"-duration", "2m",
-		extra,
-	}
-	if err := f.Parse(args); err != nil {
-		t.Fatal(err)
-	}
-	if !f.Parsed() {
-		t.Error("f.Parse() = false after Parse")
-	}
-	if *boolFlag != true {
-		t.Error("bool flag should be true, is ", *boolFlag)
-	}
-	if *bool2Flag != true {
-		t.Error("bool2 flag should be true, is ", *bool2Flag)
-	}
-	if *intFlag != 22 {
-		t.Error("int flag should be 22, is ", *intFlag)
-	}
-	if *int64Flag != 0x23 {
-		t.Error("int64 flag should be 0x23, is ", *int64Flag)
-	}
-	if *uintFlag != 24 {
-		t.Error("uint flag should be 24, is ", *uintFlag)
-	}
-	if *uint64Flag != 25 {
-		t.Error("uint64 flag should be 25, is ", *uint64Flag)
-	}
-	if *stringFlag != "hello" {
-		t.Error("string flag should be `hello`, is ", *stringFlag)
-	}
-	if *float64Flag != 2718e28 {
-		t.Error("float64 flag should be 2718e28, is ", *float64Flag)
-	}
-	if *durationFlag != 2*time.Minute {
-		t.Error("duration flag should be 2m, is ", *durationFlag)
-	}
-	if len(f.Args()) != 1 {
-		t.Error("expected one argument, got", len(f.Args()))
-	} else if f.Args()[0] != extra {
-		t.Errorf("expected argument %q got %q", extra, f.Args()[0])
-	}
-}
-
-func TestParse(t *testing.T) {
-	ResetForTesting(func() { t.Error("bad parse") })
-	testParse(CommandLine, t)
-}
-
-func TestFlagSetParse(t *testing.T) {
-	testParse(NewFlagSet("test", ContinueOnError), t)
-}
-
-// Declare a user-defined flag type.
-type flagVar []string
-
-func (f *flagVar) String() string {
-	return fmt.Sprint([]string(*f))
-}
-
-func (f *flagVar) Set(value string) error {
-	*f = append(*f, value)
-	return nil
-}
-
-func TestUserDefined(t *testing.T) {
-	var flags FlagSet
-	flags.Init("test", ContinueOnError)
-	var v flagVar
-	flags.Var(&v, "v", "usage")
-	if err := flags.Parse([]string{"-v", "1", "-v", "2", "-v=3"}); err != nil {
-		t.Error(err)
-	}
-	if len(v) != 3 {
-		t.Fatal("expected 3 args; got ", len(v))
-	}
-	expect := "[1 2 3]"
-	if v.String() != expect {
-		t.Errorf("expected value %q got %q", expect, v.String())
-	}
-}
-
-// Declare a user-defined boolean flag type.
-type boolFlagVar struct {
-	count int
-}
-
-func (b *boolFlagVar) String() string {
-	return fmt.Sprintf("%d", b.count)
-}
-
-func (b *boolFlagVar) Set(value string) error {
-	if value == "true" {
-		b.count++
-	}
-	return nil
-}
-
-func (b *boolFlagVar) IsBoolFlag() bool {
-	return b.count < 4
-}
-
-func TestUserDefinedBool(t *testing.T) {
-	var flags FlagSet
-	flags.Init("test", ContinueOnError)
-	var b boolFlagVar
-	var err error
-	flags.Var(&b, "b", "usage")
-	if err = flags.Parse([]string{"-b", "-b", "-b", "-b=true", "-b=false", "-b", "barg", "-b"}); err != nil {
-		if b.count < 4 {
-			t.Error(err)
-		}
-	}
-
-	if b.count != 4 {
-		t.Errorf("want: %d; got: %d", 4, b.count)
-	}
-
-	if err == nil {
-		t.Error("expected error; got none")
-	}
-}
-
-func TestSetOutput(t *testing.T) {
-	var flags FlagSet
-	var buf bytes.Buffer
-	flags.SetOutput(&buf)
-	flags.Init("test", ContinueOnError)
-	flags.Parse([]string{"-unknown"})
-	if out := buf.String(); !strings.Contains(out, "-unknown") {
-		t.Logf("expected output mentioning unknown; got %q", out)
-	}
-}
-
-// This tests that one can reset the flags. This still works but not well, and is
-// superseded by FlagSet.
-func TestChangingArgs(t *testing.T) {
-	ResetForTesting(func() { t.Fatal("bad parse") })
-	oldArgs := os.Args
-	defer func() { os.Args = oldArgs }()
-	os.Args = []string{"cmd", "-before", "subcmd", "-after", "args"}
-	before := Bool("before", false, "")
-	if err := CommandLine.Parse(os.Args[1:]); err != nil {
-		t.Fatal(err)
-	}
-	cmd := Arg(0)
-	os.Args = Args()
-	after := Bool("after", false, "")
-	Parse()
-	args := Args()
-
-	if !*before || cmd != "subcmd" || !*after || len(args) != 1 || args[0] != "args" {
-		t.Fatalf("expected true subcmd true [args] got %v %v %v %v", *before, cmd, *after, args)
-	}
-}
-
-// Test that -help invokes the usage message and returns ErrHelp.
-func TestHelp(t *testing.T) {
-	var helpCalled = false
-	fs := NewFlagSet("help test", ContinueOnError)
-	fs.Usage = func() { helpCalled = true }
-	var flag bool
-	fs.BoolVar(&flag, "flag", false, "regular flag")
-	// Regular flag invocation should work
-	err := fs.Parse([]string{"-flag=true"})
-	if err != nil {
-		t.Fatal("expected no error; got ", err)
-	}
-	if !flag {
-		t.Error("flag was not set by -flag")
-	}
-	if helpCalled {
-		t.Error("help called for regular flag")
-		helpCalled = false // reset for next test
-	}
-	// Help flag should work as expected.
-	err = fs.Parse([]string{"-help"})
-	if err == nil {
-		t.Fatal("error expected")
-	}
-	if err != ErrHelp {
-		t.Fatal("expected ErrHelp; got ", err)
-	}
-	if !helpCalled {
-		t.Fatal("help was not called")
-	}
-	// If we define a help flag, that should override.
-	var help bool
-	fs.BoolVar(&help, "help", false, "help flag")
-	helpCalled = false
-	err = fs.Parse([]string{"-help"})
-	if err != nil {
-		t.Fatal("expected no error for defined -help; got ", err)
-	}
-	if helpCalled {
-		t.Fatal("help was called; should not have been for defined help flag")
-	}
-}
diff --git a/src/pkg/fmt/doc.go b/src/pkg/fmt/doc.go
deleted file mode 100644
index 02642d6..0000000
--- a/src/pkg/fmt/doc.go
+++ /dev/null
@@ -1,272 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-/*
-	Package fmt implements formatted I/O with functions analogous
-	to C's printf and scanf.  The format 'verbs' are derived from C's but
-	are simpler.
-
-
-	Printing
-
-	The verbs:
-
-	General:
-		%v	the value in a default format.
-			when printing structs, the plus flag (%+v) adds field names
-		%#v	a Go-syntax representation of the value
-		%T	a Go-syntax representation of the type of the value
-		%%	a literal percent sign; consumes no value
-
-	Boolean:
-		%t	the word true or false
-	Integer:
-		%b	base 2
-		%c	the character represented by the corresponding Unicode code point
-		%d	base 10
-		%o	base 8
-		%q	a single-quoted character literal safely escaped with Go syntax.
-		%x	base 16, with lower-case letters for a-f
-		%X	base 16, with upper-case letters for A-F
-		%U	Unicode format: U+1234; same as "U+%04X"
-	Floating-point and complex constituents:
-		%b	decimalless scientific notation with exponent a power of two,
-			in the manner of strconv.FormatFloat with the 'b' format,
-			e.g. -123456p-78
-		%e	scientific notation, e.g. -1234.456e+78
-		%E	scientific notation, e.g. -1234.456E+78
-		%f	decimal point but no exponent, e.g. 123.456
-		%F	synonym for %f
-		%g	whichever of %e or %f produces more compact output
-		%G	whichever of %E or %f produces more compact output
-	String and slice of bytes:
-		%s	the uninterpreted bytes of the string or slice
-		%q	a double-quoted string safely escaped with Go syntax
-		%x	base 16, lower-case, two characters per byte
-		%X	base 16, upper-case, two characters per byte
-	Pointer:
-		%p	base 16 notation, with leading 0x
-
-	There is no 'u' flag.  Integers are printed unsigned if they have unsigned type.
-	Similarly, there is no need to specify the size of the operand (int8, int64).
-
-	Width is specified by an optional decimal number immediately following the verb.
-	If absent, the width is whatever is necessary to represent the value.
-	Precision is specified after the (optional) width by a period followed by a
-	decimal number. If no period is present, a default precision is used.
-	A period with no following number specifies a precision of zero.
-	Examples:
-		%f:    default width, default precision
-		%9f    width 9, default precision
-		%.2f   default width, precision 2
-		%9.2f  width 9, precision 2
-		%9.f   width 9, precision 0
-
-	Width and precision are measured in units of Unicode code points.
-	(This differs from C's printf where the units are numbers
-	of bytes.) Either or both of the flags may be replaced with the
-	character '*', causing their values to be obtained from the next
-	operand, which must be of type int.
-
-	For most values, width is the minimum number of characters to output,
-	padding the formatted form with spaces if necessary.
-	For strings, precision is the maximum number of characters to output,
-	truncating if necessary.
-
-	For floating-point values, width sets the minimum width of the field and
-	precision sets the number of places after the decimal, if appropriate,
-	except that for %g/%G it sets the total number of digits. For example,
-	given 123.45 the format %6.2f prints 123.45 while %.4g prints 123.5.
-	The default precision for %e and %f is 6; for %g it is the smallest
-	number of digits necessary to identify the value uniquely.
-
-	For complex numbers, the width and precision apply to the two
-	components independently and the result is parenthesized, so %f applied
-	to 1.2+3.4i produces (1.200000+3.400000i).
-
-	Other flags:
-		+	always print a sign for numeric values;
-			guarantee ASCII-only output for %q (%+q)
-		-	pad with spaces on the right rather than the left (left-justify the field)
-		#	alternate format: add leading 0 for octal (%#o), 0x for hex (%#x);
-			0X for hex (%#X); suppress 0x for %p (%#p);
-			for %q, print a raw (backquoted) string if strconv.CanBackquote
-			returns true;
-			write e.g. U+0078 'x' if the character is printable for %U (%#U).
-		' '	(space) leave a space for elided sign in numbers (% d);
-			put spaces between bytes printing strings or slices in hex (% x, % X)
-		0	pad with leading zeros rather than spaces;
-			for numbers, this moves the padding after the sign
-
-	Flags are ignored by verbs that do not expect them.
-	For example there is no alternate decimal format, so %#d and %d
-	behave identically.
-
-	For each Printf-like function, there is also a Print function
-	that takes no format and is equivalent to saying %v for every
-	operand.  Another variant Println inserts blanks between
-	operands and appends a newline.
-
-	Regardless of the verb, if an operand is an interface value,
-	the internal concrete value is used, not the interface itself.
-	Thus:
-		var i interface{} = 23
-		fmt.Printf("%v\n", i)
-	will print 23.
-
-	Except when printed using the verbs %T and %p, special
-	formatting considerations apply for operands that implement
-	certain interfaces. In order of application:
-
-	1. If an operand implements the Formatter interface, it will
-	be invoked. Formatter provides fine control of formatting.
-
-	2. If the %v verb is used with the # flag (%#v) and the operand
-	implements the GoStringer interface, that will be invoked.
-
-	If the format (which is implicitly %v for Println etc.) is valid
-	for a string (%s %q %v %x %X), the following two rules apply:
-
-	3. If an operand implements the error interface, the Error method
-	will be invoked to convert the object to a string, which will then
-	be formatted as required by the verb (if any).
-
-	4. If an operand implements method String() string, that method
-	will be invoked to convert the object to a string, which will then
-	be formatted as required by the verb (if any).
-
-	For compound operands such as slices and structs, the format
-	applies to the elements of each operand, recursively, not to the
-	operand as a whole. Thus %q will quote each element of a slice
-	of strings, and %6.2f will control formatting for each element
-	of a floating-point array.
-
-	To avoid recursion in cases such as
-		type X string
-		func (x X) String() string { return Sprintf("<%s>", x) }
-	convert the value before recurring:
-		func (x X) String() string { return Sprintf("<%s>", string(x)) }
-
-	Explicit argument indexes:
-
-	In Printf, Sprintf, and Fprintf, the default behavior is for each
-	formatting verb to format successive arguments passed in the call.
-	However, the notation [n] immediately before the verb indicates that the
-	nth one-indexed argument is to be formatted instead. The same notation
-	before a '*' for a width or precision selects the argument index holding
-	the value. After processing a bracketed expression [n], arguments n+1,
-	n+2, etc. will be processed unless otherwise directed.
-
-	For example,
-		fmt.Sprintf("%[2]d %[1]d\n", 11, 22)
-	will yield "22, 11", while
-		fmt.Sprintf("%[3]*.[2]*[1]f", 12.0, 2, 6),
-	equivalent to
-		fmt.Sprintf("%6.2f", 12.0),
-	will yield " 12.00". Because an explicit index affects subsequent verbs,
-	this notation can be used to print the same values multiple times
-	by resetting the index for the first argument to be repeated:
-		fmt.Sprintf("%d %d %#[1]x %#x", 16, 17)
-	will yield "16 17 0x10 0x11".
-
-	Format errors:
-
-	If an invalid argument is given for a verb, such as providing
-	a string to %d, the generated string will contain a
-	description of the problem, as in these examples:
-
-		Wrong type or unknown verb: %!verb(type=value)
-			Printf("%d", hi):          %!d(string=hi)
-		Too many arguments: %!(EXTRA type=value)
-			Printf("hi", "guys"):      hi%!(EXTRA string=guys)
-		Too few arguments: %!verb(MISSING)
-			Printf("hi%d"):            hi %!d(MISSING)
-		Non-int for width or precision: %!(BADWIDTH) or %!(BADPREC)
-			Printf("%*s", 4.5, "hi"):  %!(BADWIDTH)hi
-			Printf("%.*s", 4.5, "hi"): %!(BADPREC)hi
-		Invalid or invalid use of argument index: %!(BADINDEX)
-			Printf("%*[2]d", 7):       %!d(BADINDEX)
-			Printf("%.[2]d", 7):       %!d(BADINDEX)
-
-	All errors begin with the string "%!" followed sometimes
-	by a single character (the verb) and end with a parenthesized
-	description.
-
-	If an Error or String method triggers a panic when called by a
-	print routine, the fmt package reformats the error message
-	from the panic, decorating it with an indication that it came
-	through the fmt package.  For example, if a String method
-	calls panic("bad"), the resulting formatted message will look
-	like
-		%!s(PANIC=bad)
-
-	The %!s just shows the print verb in use when the failure
-	occurred.
-
-	Scanning
-
-	An analogous set of functions scans formatted text to yield
-	values.  Scan, Scanf and Scanln read from os.Stdin; Fscan,
-	Fscanf and Fscanln read from a specified io.Reader; Sscan,
-	Sscanf and Sscanln read from an argument string.  Scanln,
-	Fscanln and Sscanln stop scanning at a newline and require that
-	the items be followed by one; Scanf, Fscanf and Sscanf require
-	newlines in the input to match newlines in the format; the other
-	routines treat newlines as spaces.
-
-	Scanf, Fscanf, and Sscanf parse the arguments according to a
-	format string, analogous to that of Printf.  For example, %x
-	will scan an integer as a hexadecimal number, and %v will scan
-	the default representation format for the value.
-
-	The formats behave analogously to those of Printf with the
-	following exceptions:
-
-		%p is not implemented
-		%T is not implemented
-		%e %E %f %F %g %G are all equivalent and scan any floating point or complex value
-		%s and %v on strings scan a space-delimited token
-		Flags # and + are not implemented.
-
-	The familiar base-setting prefixes 0 (octal) and 0x
-	(hexadecimal) are accepted when scanning integers without a
-	format or with the %v verb.
-
-	Width is interpreted in the input text (%5s means at most
-	five runes of input will be read to scan a string) but there
-	is no syntax for scanning with a precision (no %5.2f, just
-	%5f).
-
-	When scanning with a format, all non-empty runs of space
-	characters (except newline) are equivalent to a single
-	space in both the format and the input.  With that proviso,
-	text in the format string must match the input text; scanning
-	stops if it does not, with the return value of the function
-	indicating the number of arguments scanned.
-
-	In all the scanning functions, a carriage return followed
-	immediately by a newline is treated as a plain newline
-	(\r\n means the same as \n).
-
-	In all the scanning functions, if an operand implements method
-	Scan (that is, it implements the Scanner interface) that
-	method will be used to scan the text for that operand.  Also,
-	if the number of arguments scanned is less than the number of
-	arguments provided, an error is returned.
-
-	All arguments to be scanned must be either pointers to basic
-	types or implementations of the Scanner interface.
-
-	Note: Fscan etc. can read one character (rune) past the input
-	they return, which means that a loop calling a scan routine
-	may skip some of the input.  This is usually a problem only
-	when there is no space between input values.  If the reader
-	provided to Fscan implements ReadRune, that method will be used
-	to read characters.  If the reader also implements UnreadRune,
-	that method will be used to save the character and successive
-	calls will not lose data.  To attach ReadRune and UnreadRune
-	methods to a reader without that capability, use
-	bufio.NewReader.
-*/
-package fmt
diff --git a/src/pkg/fmt/fmt_test.go b/src/pkg/fmt/fmt_test.go
deleted file mode 100644
index 7e3d06b..0000000
--- a/src/pkg/fmt/fmt_test.go
+++ /dev/null
@@ -1,1147 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package fmt_test
-
-import (
-	"bytes"
-	. "fmt"
-	"io"
-	"math"
-	"runtime"
-	"strings"
-	"testing"
-	"time"
-	"unicode"
-)
-
-type (
-	renamedBool       bool
-	renamedInt        int
-	renamedInt8       int8
-	renamedInt16      int16
-	renamedInt32      int32
-	renamedInt64      int64
-	renamedUint       uint
-	renamedUint8      uint8
-	renamedUint16     uint16
-	renamedUint32     uint32
-	renamedUint64     uint64
-	renamedUintptr    uintptr
-	renamedString     string
-	renamedBytes      []byte
-	renamedFloat32    float32
-	renamedFloat64    float64
-	renamedComplex64  complex64
-	renamedComplex128 complex128
-)
-
-func TestFmtInterface(t *testing.T) {
-	var i1 interface{}
-	i1 = "abc"
-	s := Sprintf("%s", i1)
-	if s != "abc" {
-		t.Errorf(`Sprintf("%%s", empty("abc")) = %q want %q`, s, "abc")
-	}
-}
-
-const b32 uint32 = 1<<32 - 1
-const b64 uint64 = 1<<64 - 1
-
-var array = [5]int{1, 2, 3, 4, 5}
-var iarray = [4]interface{}{1, "hello", 2.5, nil}
-var slice = array[:]
-var islice = iarray[:]
-
-type A struct {
-	i int
-	j uint
-	s string
-	x []int
-}
-
-type I int
-
-func (i I) String() string { return Sprintf("<%d>", int(i)) }
-
-type B struct {
-	I I
-	j int
-}
-
-type C struct {
-	i int
-	B
-}
-
-type F int
-
-func (f F) Format(s State, c rune) {
-	Fprintf(s, "<%c=F(%d)>", c, int(f))
-}
-
-type G int
-
-func (g G) GoString() string {
-	return Sprintf("GoString(%d)", int(g))
-}
-
-type S struct {
-	F F // a struct field that Formats
-	G G // a struct field that GoStrings
-}
-
-type SI struct {
-	I interface{}
-}
-
-// P is a type with a String method with pointer receiver for testing %p.
-type P int
-
-var pValue P
-
-func (p *P) String() string {
-	return "String(p)"
-}
-
-var barray = [5]renamedUint8{1, 2, 3, 4, 5}
-var bslice = barray[:]
-
-var b byte
-
-var fmtTests = []struct {
-	fmt string
-	val interface{}
-	out string
-}{
-	{"%d", 12345, "12345"},
-	{"%v", 12345, "12345"},
-	{"%t", true, "true"},
-
-	// basic string
-	{"%s", "abc", "abc"},
-	{"%x", "abc", "616263"},
-	{"%x", "xyz", "78797a"},
-	{"%X", "xyz", "78797A"},
-	{"%q", "abc", `"abc"`},
-
-	// basic bytes
-	{"%s", []byte("abc"), "abc"},
-	{"%x", []byte("abc"), "616263"},
-	{"% x", []byte("abc\xff"), "61 62 63 ff"},
-	{"%#x", []byte("abc\xff"), "0x610x620x630xff"},
-	{"%#X", []byte("abc\xff"), "0X610X620X630XFF"},
-	{"%# x", []byte("abc\xff"), "0x61 0x62 0x63 0xff"},
-	{"%# X", []byte("abc\xff"), "0X61 0X62 0X63 0XFF"},
-	{"% X", []byte("abc\xff"), "61 62 63 FF"},
-	{"%x", []byte("xyz"), "78797a"},
-	{"%X", []byte("xyz"), "78797A"},
-	{"%q", []byte("abc"), `"abc"`},
-
-	// escaped strings
-	{"%#q", `abc`, "`abc`"},
-	{"%#q", `"`, "`\"`"},
-	{"1 %#q", `\n`, "1 `\\n`"},
-	{"2 %#q", "\n", `2 "\n"`},
-	{"%q", `"`, `"\""`},
-	{"%q", "\a\b\f\r\n\t\v", `"\a\b\f\r\n\t\v"`},
-	{"%q", "abc\xffdef", `"abc\xffdef"`},
-	{"%q", "\u263a", `"☺"`},
-	{"%+q", "\u263a", `"\u263a"`},
-	{"%q", "\U0010ffff", `"\U0010ffff"`},
-
-	// escaped characters
-	{"%q", 'x', `'x'`},
-	{"%q", 0, `'\x00'`},
-	{"%q", '\n', `'\n'`},
-	{"%q", '\u0e00', `'\u0e00'`},         // not a printable rune.
-	{"%q", '\U000c2345', `'\U000c2345'`}, // not a printable rune.
-	{"%q", int64(0x7FFFFFFF), `%!q(int64=2147483647)`},
-	{"%q", uint64(0xFFFFFFFF), `%!q(uint64=4294967295)`},
-	{"%q", '"', `'"'`},
-	{"%q", '\'', `'\''`},
-	{"%q", "\u263a", `"☺"`},
-	{"%+q", "\u263a", `"\u263a"`},
-
-	// width
-	{"%5s", "abc", "  abc"},
-	{"%2s", "\u263a", " ☺"},
-	{"%-5s", "abc", "abc  "},
-	{"%-8q", "abc", `"abc"   `},
-	{"%05s", "abc", "00abc"},
-	{"%08q", "abc", `000"abc"`},
-	{"%5s", "abcdefghijklmnopqrstuvwxyz", "abcdefghijklmnopqrstuvwxyz"},
-	{"%.5s", "abcdefghijklmnopqrstuvwxyz", "abcde"},
-	{"%.5s", "日本語日本語", "日本語日本"},
-	{"%.5s", []byte("日本語日本語"), "日本語日本"},
-	{"%.5q", "abcdefghijklmnopqrstuvwxyz", `"abcde"`},
-	{"%.3q", "日本語日本語", `"日本語"`},
-	{"%.3q", []byte("日本語日本語"), `"日本語"`},
-	{"%10.1q", "日本語日本語", `       "日"`},
-	{"%10v", nil, "     <nil>"},
-	{"%-10v", nil, "<nil>     "},
-
-	// integers
-	{"%d", 12345, "12345"},
-	{"%d", -12345, "-12345"},
-	{"%10d", 12345, "     12345"},
-	{"%10d", -12345, "    -12345"},
-	{"%+10d", 12345, "    +12345"},
-	{"%010d", 12345, "0000012345"},
-	{"%010d", -12345, "-000012345"},
-	{"%-10d", 12345, "12345     "},
-	{"%010.3d", 1, "       001"},
-	{"%010.3d", -1, "      -001"},
-	{"%+d", 12345, "+12345"},
-	{"%+d", -12345, "-12345"},
-	{"%+d", 0, "+0"},
-	{"% d", 0, " 0"},
-	{"% d", 12345, " 12345"},
-	{"%.0d", 0, ""},
-	{"%.d", 0, ""},
-
-	// unicode format
-	{"%U", 0x1, "U+0001"},
-	{"%U", uint(0x1), "U+0001"},
-	{"%.8U", 0x2, "U+00000002"},
-	{"%U", 0x1234, "U+1234"},
-	{"%U", 0x12345, "U+12345"},
-	{"%10.6U", 0xABC, "  U+000ABC"},
-	{"%-10.6U", 0xABC, "U+000ABC  "},
-	{"%U", '\n', `U+000A`},
-	{"%#U", '\n', `U+000A`},
-	{"%U", 'x', `U+0078`},
-	{"%#U", 'x', `U+0078 'x'`},
-	{"%U", '\u263a', `U+263A`},
-	{"%#U", '\u263a', `U+263A '☺'`},
-
-	// floats
-	{"%+.3e", 0.0, "+0.000e+00"},
-	{"%+.3e", 1.0, "+1.000e+00"},
-	{"%+.3f", -1.0, "-1.000"},
-	{"%+.3F", -1.0, "-1.000"},
-	{"%+.3F", float32(-1.0), "-1.000"},
-	{"%+07.2f", 1.0, "+001.00"},
-	{"%+07.2f", -1.0, "-001.00"},
-	{"%+10.2f", +1.0, "     +1.00"},
-	{"%+10.2f", -1.0, "     -1.00"},
-	{"% .3E", -1.0, "-1.000E+00"},
-	{"% .3e", 1.0, " 1.000e+00"},
-	{"%+.3g", 0.0, "+0"},
-	{"%+.3g", 1.0, "+1"},
-	{"%+.3g", -1.0, "-1"},
-	{"% .3g", -1.0, "-1"},
-	{"% .3g", 1.0, " 1"},
-	{"%b", float32(1.0), "8388608p-23"},
-	{"%b", 1.0, "4503599627370496p-52"},
-
-	// complex values
-	{"%+.3e", 0i, "(+0.000e+00+0.000e+00i)"},
-	{"%+.3f", 0i, "(+0.000+0.000i)"},
-	{"%+.3g", 0i, "(+0+0i)"},
-	{"%+.3e", 1 + 2i, "(+1.000e+00+2.000e+00i)"},
-	{"%+.3f", 1 + 2i, "(+1.000+2.000i)"},
-	{"%+.3g", 1 + 2i, "(+1+2i)"},
-	{"%.3e", 0i, "(0.000e+00+0.000e+00i)"},
-	{"%.3f", 0i, "(0.000+0.000i)"},
-	{"%.3F", 0i, "(0.000+0.000i)"},
-	{"%.3F", complex64(0i), "(0.000+0.000i)"},
-	{"%.3g", 0i, "(0+0i)"},
-	{"%.3e", 1 + 2i, "(1.000e+00+2.000e+00i)"},
-	{"%.3f", 1 + 2i, "(1.000+2.000i)"},
-	{"%.3g", 1 + 2i, "(1+2i)"},
-	{"%.3e", -1 - 2i, "(-1.000e+00-2.000e+00i)"},
-	{"%.3f", -1 - 2i, "(-1.000-2.000i)"},
-	{"%.3g", -1 - 2i, "(-1-2i)"},
-	{"% .3E", -1 - 2i, "(-1.000E+00-2.000E+00i)"},
-	{"%+.3g", complex64(1 + 2i), "(+1+2i)"},
-	{"%+.3g", complex128(1 + 2i), "(+1+2i)"},
-	{"%b", complex64(1 + 2i), "(8388608p-23+8388608p-22i)"},
-	{"%b", 1 + 2i, "(4503599627370496p-52+4503599627370496p-51i)"},
-
-	// erroneous formats
-	{"", 2, "%!(EXTRA int=2)"},
-	{"%d", "hello", "%!d(string=hello)"},
-
-	// old test/fmt_test.go
-	{"%d", 1234, "1234"},
-	{"%d", -1234, "-1234"},
-	{"%d", uint(1234), "1234"},
-	{"%d", uint32(b32), "4294967295"},
-	{"%d", uint64(b64), "18446744073709551615"},
-	{"%o", 01234, "1234"},
-	{"%#o", 01234, "01234"},
-	{"%o", uint32(b32), "37777777777"},
-	{"%o", uint64(b64), "1777777777777777777777"},
-	{"%x", 0x1234abcd, "1234abcd"},
-	{"%#x", 0x1234abcd, "0x1234abcd"},
-	{"%x", b32 - 0x1234567, "fedcba98"},
-	{"%X", 0x1234abcd, "1234ABCD"},
-	{"%X", b32 - 0x1234567, "FEDCBA98"},
-	{"%#X", 0, "0X0"},
-	{"%x", b64, "ffffffffffffffff"},
-	{"%b", 7, "111"},
-	{"%b", b64, "1111111111111111111111111111111111111111111111111111111111111111"},
-	{"%b", -6, "-110"},
-	{"%e", 1.0, "1.000000e+00"},
-	{"%e", 1234.5678e3, "1.234568e+06"},
-	{"%e", 1234.5678e-8, "1.234568e-05"},
-	{"%e", -7.0, "-7.000000e+00"},
-	{"%e", -1e-9, "-1.000000e-09"},
-	{"%f", 1234.5678e3, "1234567.800000"},
-	{"%f", 1234.5678e-8, "0.000012"},
-	{"%f", -7.0, "-7.000000"},
-	{"%f", -1e-9, "-0.000000"},
-	{"%g", 1234.5678e3, "1.2345678e+06"},
-	{"%g", float32(1234.5678e3), "1.2345678e+06"},
-	{"%g", 1234.5678e-8, "1.2345678e-05"},
-	{"%g", -7.0, "-7"},
-	{"%g", -1e-9, "-1e-09"},
-	{"%g", float32(-1e-9), "-1e-09"},
-	{"%E", 1.0, "1.000000E+00"},
-	{"%E", 1234.5678e3, "1.234568E+06"},
-	{"%E", 1234.5678e-8, "1.234568E-05"},
-	{"%E", -7.0, "-7.000000E+00"},
-	{"%E", -1e-9, "-1.000000E-09"},
-	{"%G", 1234.5678e3, "1.2345678E+06"},
-	{"%G", float32(1234.5678e3), "1.2345678E+06"},
-	{"%G", 1234.5678e-8, "1.2345678E-05"},
-	{"%G", -7.0, "-7"},
-	{"%G", -1e-9, "-1E-09"},
-	{"%G", float32(-1e-9), "-1E-09"},
-	{"%c", 'x', "x"},
-	{"%c", 0xe4, "ä"},
-	{"%c", 0x672c, "本"},
-	{"%c", '日', "日"},
-	{"%20.8d", 1234, "            00001234"},
-	{"%20.8d", -1234, "           -00001234"},
-	{"%20d", 1234, "                1234"},
-	{"%-20.8d", 1234, "00001234            "},
-	{"%-20.8d", -1234, "-00001234           "},
-	{"%-#20.8x", 0x1234abc, "0x01234abc          "},
-	{"%-#20.8X", 0x1234abc, "0X01234ABC          "},
-	{"%-#20.8o", 01234, "00001234            "},
-	{"%.20b", 7, "00000000000000000111"},
-	{"%20.5s", "qwertyuiop", "               qwert"},
-	{"%.5s", "qwertyuiop", "qwert"},
-	{"%-20.5s", "qwertyuiop", "qwert               "},
-	{"%20c", 'x', "                   x"},
-	{"%-20c", 'x', "x                   "},
-	{"%20.6e", 1.2345e3, "        1.234500e+03"},
-	{"%20.6e", 1.2345e-3, "        1.234500e-03"},
-	{"%20e", 1.2345e3, "        1.234500e+03"},
-	{"%20e", 1.2345e-3, "        1.234500e-03"},
-	{"%20.8e", 1.2345e3, "      1.23450000e+03"},
-	{"%20f", 1.23456789e3, "         1234.567890"},
-	{"%20f", 1.23456789e-3, "            0.001235"},
-	{"%20f", 12345678901.23456789, "  12345678901.234568"},
-	{"%-20f", 1.23456789e3, "1234.567890         "},
-	{"%20.8f", 1.23456789e3, "       1234.56789000"},
-	{"%20.8f", 1.23456789e-3, "          0.00123457"},
-	{"%g", 1.23456789e3, "1234.56789"},
-	{"%g", 1.23456789e-3, "0.00123456789"},
-	{"%g", 1.23456789e20, "1.23456789e+20"},
-	{"%20e", math.Inf(1), "                +Inf"},
-	{"%-20f", math.Inf(-1), "-Inf                "},
-	{"%20g", math.NaN(), "                 NaN"},
-
-	// arrays
-	{"%v", array, "[1 2 3 4 5]"},
-	{"%v", iarray, "[1 hello 2.5 <nil>]"},
-	{"%v", barray, "[1 2 3 4 5]"},
-	{"%v", &array, "&[1 2 3 4 5]"},
-	{"%v", &iarray, "&[1 hello 2.5 <nil>]"},
-	{"%v", &barray, "&[1 2 3 4 5]"},
-
-	// slices
-	{"%v", slice, "[1 2 3 4 5]"},
-	{"%v", islice, "[1 hello 2.5 <nil>]"},
-	{"%v", bslice, "[1 2 3 4 5]"},
-	{"%v", &slice, "&[1 2 3 4 5]"},
-	{"%v", &islice, "&[1 hello 2.5 <nil>]"},
-	{"%v", &bslice, "&[1 2 3 4 5]"},
-
-	// complexes with %v
-	{"%v", 1 + 2i, "(1+2i)"},
-	{"%v", complex64(1 + 2i), "(1+2i)"},
-	{"%v", complex128(1 + 2i), "(1+2i)"},
-
-	// structs
-	{"%v", A{1, 2, "a", []int{1, 2}}, `{1 2 a [1 2]}`},
-	{"%+v", A{1, 2, "a", []int{1, 2}}, `{i:1 j:2 s:a x:[1 2]}`},
-
-	// +v on structs with Stringable items
-	{"%+v", B{1, 2}, `{I:<1> j:2}`},
-	{"%+v", C{1, B{2, 3}}, `{i:1 B:{I:<2> j:3}}`},
-
-	// other formats on Stringable items
-	{"%s", I(23), `<23>`},
-	{"%q", I(23), `"<23>"`},
-	{"%x", I(23), `3c32333e`},
-	{"%#x", I(23), `0x3c0x320x330x3e`},
-	{"%# x", I(23), `0x3c 0x32 0x33 0x3e`},
-	{"%d", I(23), `23`}, // Stringer applies only to string formats.
-
-	// go syntax
-	{"%#v", A{1, 2, "a", []int{1, 2}}, `fmt_test.A{i:1, j:0x2, s:"a", x:[]int{1, 2}}`},
-	{"%#v", &b, "(*uint8)(0xPTR)"},
-	{"%#v", TestFmtInterface, "(func(*testing.T))(0xPTR)"},
-	{"%#v", make(chan int), "(chan int)(0xPTR)"},
-	{"%#v", uint64(1<<64 - 1), "0xffffffffffffffff"},
-	{"%#v", 1000000000, "1000000000"},
-	{"%#v", map[string]int{"a": 1}, `map[string]int{"a":1}`},
-	{"%#v", map[string]B{"a": {1, 2}}, `map[string]fmt_test.B{"a":fmt_test.B{I:1, j:2}}`},
-	{"%#v", []string{"a", "b"}, `[]string{"a", "b"}`},
-	{"%#v", SI{}, `fmt_test.SI{I:interface {}(nil)}`},
-	{"%#v", []int(nil), `[]int(nil)`},
-	{"%#v", []int{}, `[]int{}`},
-	{"%#v", array, `[5]int{1, 2, 3, 4, 5}`},
-	{"%#v", &array, `&[5]int{1, 2, 3, 4, 5}`},
-	{"%#v", iarray, `[4]interface {}{1, "hello", 2.5, interface {}(nil)}`},
-	{"%#v", &iarray, `&[4]interface {}{1, "hello", 2.5, interface {}(nil)}`},
-	{"%#v", map[int]byte(nil), `map[int]uint8(nil)`},
-	{"%#v", map[int]byte{}, `map[int]uint8{}`},
-	{"%#v", "foo", `"foo"`},
-	{"%#v", barray, `[5]fmt_test.renamedUint8{0x1, 0x2, 0x3, 0x4, 0x5}`},
-	{"%#v", bslice, `[]fmt_test.renamedUint8{0x1, 0x2, 0x3, 0x4, 0x5}`},
-	{"%#v", []byte(nil), "[]byte(nil)"},
-	{"%#v", []int32(nil), "[]int32(nil)"},
-
-	// slices with other formats
-	{"%#x", []int{1, 2, 15}, `[0x1 0x2 0xf]`},
-	{"%x", []int{1, 2, 15}, `[1 2 f]`},
-	{"%d", []int{1, 2, 15}, `[1 2 15]`},
-	{"%d", []byte{1, 2, 15}, `[1 2 15]`},
-	{"%q", []string{"a", "b"}, `["a" "b"]`},
-
-	// renamings
-	{"%v", renamedBool(true), "true"},
-	{"%d", renamedBool(true), "%!d(fmt_test.renamedBool=true)"},
-	{"%o", renamedInt(8), "10"},
-	{"%d", renamedInt8(-9), "-9"},
-	{"%v", renamedInt16(10), "10"},
-	{"%v", renamedInt32(-11), "-11"},
-	{"%X", renamedInt64(255), "FF"},
-	{"%v", renamedUint(13), "13"},
-	{"%o", renamedUint8(14), "16"},
-	{"%X", renamedUint16(15), "F"},
-	{"%d", renamedUint32(16), "16"},
-	{"%X", renamedUint64(17), "11"},
-	{"%o", renamedUintptr(18), "22"},
-	{"%x", renamedString("thing"), "7468696e67"},
-	{"%d", renamedBytes([]byte{1, 2, 15}), `[1 2 15]`},
-	{"%q", renamedBytes([]byte("hello")), `"hello"`},
-	{"%x", []renamedUint8{'a', 'b', 'c'}, "616263"},
-	{"%s", []renamedUint8{'h', 'e', 'l', 'l', 'o'}, "hello"},
-	{"%q", []renamedUint8{'h', 'e', 'l', 'l', 'o'}, `"hello"`},
-	{"%v", renamedFloat32(22), "22"},
-	{"%v", renamedFloat64(33), "33"},
-	{"%v", renamedComplex64(3 + 4i), "(3+4i)"},
-	{"%v", renamedComplex128(4 - 3i), "(4-3i)"},
-
-	// Formatter
-	{"%x", F(1), "<x=F(1)>"},
-	{"%x", G(2), "2"},
-	{"%+v", S{F(4), G(5)}, "{F:<v=F(4)> G:5}"},
-
-	// GoStringer
-	{"%#v", G(6), "GoString(6)"},
-	{"%#v", S{F(7), G(8)}, "fmt_test.S{F:<v=F(7)>, G:GoString(8)}"},
-
-	// %T
-	{"%T", (4 - 3i), "complex128"},
-	{"%T", renamedComplex128(4 - 3i), "fmt_test.renamedComplex128"},
-	{"%T", intVal, "int"},
-	{"%6T", &intVal, "  *int"},
-	{"%10T", nil, "     <nil>"},
-	{"%-10T", nil, "<nil>     "},
-
-	// %p
-	{"p0=%p", new(int), "p0=0xPTR"},
-	{"p1=%s", &pValue, "p1=String(p)"}, // String method...
-	{"p2=%p", &pValue, "p2=0xPTR"},     // ... not called with %p
-	{"p3=%p", (*int)(nil), "p3=0x0"},
-	{"p4=%#p", new(int), "p4=PTR"},
-
-	// %p on non-pointers
-	{"%p", make(chan int), "0xPTR"},
-	{"%p", make(map[int]int), "0xPTR"},
-	{"%p", make([]int, 1), "0xPTR"},
-	{"%p", 27, "%!p(int=27)"}, // not a pointer at all
-
-	// %q on pointers
-	{"%q", (*int)(nil), "%!q(*int=<nil>)"},
-	{"%q", new(int), "%!q(*int=0xPTR)"},
-
-	// %v on pointers formats 0 as <nil>
-	{"%v", (*int)(nil), "<nil>"},
-	{"%v", new(int), "0xPTR"},
-
-	// %d etc. pointers use specified base.
-	{"%d", new(int), "PTR_d"},
-	{"%o", new(int), "PTR_o"},
-	{"%x", new(int), "PTR_x"},
-
-	// %d on Stringer should give integer if possible
-	{"%s", time.Time{}.Month(), "January"},
-	{"%d", time.Time{}.Month(), "1"},
-
-	// erroneous things
-	{"%s %", "hello", "hello %!(NOVERB)"},
-	{"%s %.2", "hello", "hello %!(NOVERB)"},
-	{"%d", "hello", "%!d(string=hello)"},
-	{"no args", "hello", "no args%!(EXTRA string=hello)"},
-	{"%s", nil, "%!s(<nil>)"},
-	{"%T", nil, "<nil>"},
-	{"%-1", 100, "%!(NOVERB)%!(EXTRA int=100)"},
-
-	// The "<nil>" show up because maps are printed by
-	// first obtaining a list of keys and then looking up
-	// each key.  Since NaNs can be map keys but cannot
-	// be fetched directly, the lookup fails and returns a
-	// zero reflect.Value, which formats as <nil>.
-	// This test is just to check that it shows the two NaNs at all.
-	{"%v", map[float64]int{math.NaN(): 1, math.NaN(): 2}, "map[NaN:<nil> NaN:<nil>]"},
-
-	// Used to crash because nByte didn't allow for a sign.
-	{"%b", int64(-1 << 63), zeroFill("-1", 63, "")},
-
-	// Used to panic.
-	{"%0100d", 1, zeroFill("", 100, "1")},
-	{"%0100d", -1, zeroFill("-", 99, "1")},
-	{"%0.100f", 1.0, zeroFill("1.", 100, "")},
-	{"%0.100f", -1.0, zeroFill("-1.", 100, "")},
-
-	// Comparison of padding rules with C printf.
-	/*
-		C program:
-		#include <stdio.h>
-
-		char *format[] = {
-			"[%.2f]",
-			"[% .2f]",
-			"[%+.2f]",
-			"[%7.2f]",
-			"[% 7.2f]",
-			"[%+7.2f]",
-			"[%07.2f]",
-			"[% 07.2f]",
-			"[%+07.2f]",
-		};
-
-		int main(void) {
-			int i;
-			for(i = 0; i < 9; i++) {
-				printf("%s: ", format[i]);
-				printf(format[i], 1.0);
-				printf(" ");
-				printf(format[i], -1.0);
-				printf("\n");
-			}
-		}
-
-		Output:
-			[%.2f]: [1.00] [-1.00]
-			[% .2f]: [ 1.00] [-1.00]
-			[%+.2f]: [+1.00] [-1.00]
-			[%7.2f]: [   1.00] [  -1.00]
-			[% 7.2f]: [   1.00] [  -1.00]
-			[%+7.2f]: [  +1.00] [  -1.00]
-			[%07.2f]: [0001.00] [-001.00]
-			[% 07.2f]: [ 001.00] [-001.00]
-			[%+07.2f]: [+001.00] [-001.00]
-	*/
-	{"%.2f", 1.0, "1.00"},
-	{"%.2f", -1.0, "-1.00"},
-	{"% .2f", 1.0, " 1.00"},
-	{"% .2f", -1.0, "-1.00"},
-	{"%+.2f", 1.0, "+1.00"},
-	{"%+.2f", -1.0, "-1.00"},
-	{"%7.2f", 1.0, "   1.00"},
-	{"%7.2f", -1.0, "  -1.00"},
-	{"% 7.2f", 1.0, "   1.00"},
-	{"% 7.2f", -1.0, "  -1.00"},
-	{"%+7.2f", 1.0, "  +1.00"},
-	{"%+7.2f", -1.0, "  -1.00"},
-	{"%07.2f", 1.0, "0001.00"},
-	{"%07.2f", -1.0, "-001.00"},
-	{"% 07.2f", 1.0, " 001.00"},
-	{"% 07.2f", -1.0, "-001.00"},
-	{"%+07.2f", 1.0, "+001.00"},
-	{"%+07.2f", -1.0, "-001.00"},
-
-	// Complex numbers: exhaustively tested in TestComplexFormatting.
-	{"%7.2f", 1 + 2i, "(   1.00  +2.00i)"},
-	{"%+07.2f", -1 - 2i, "(-001.00-002.00i)"},
-	// Zero padding does not apply to infinities.
-	{"%020f", math.Inf(-1), "                -Inf"},
-	{"%020f", math.Inf(+1), "                +Inf"},
-	{"% 020f", math.Inf(-1), "                -Inf"},
-	{"% 020f", math.Inf(+1), "                 Inf"},
-	{"%+020f", math.Inf(-1), "                -Inf"},
-	{"%+020f", math.Inf(+1), "                +Inf"},
-	{"%20f", -1.0, "           -1.000000"},
-	// Make sure we can handle very large widths.
-	{"%0100f", -1.0, zeroFill("-", 99, "1.000000")},
-
-	// Complex fmt used to leave the plus flag set for future entries in the array
-	// causing +2+0i and +3+0i instead of 2+0i and 3+0i.
-	{"%v", []complex64{1, 2, 3}, "[(1+0i) (2+0i) (3+0i)]"},
-	{"%v", []complex128{1, 2, 3}, "[(1+0i) (2+0i) (3+0i)]"},
-
-	// Incomplete format specification caused crash.
-	{"%.", 3, "%!.(int=3)"},
-
-	// Used to panic with out-of-bounds for very large numeric representations.
-	// nByte is set to handle one bit per uint64 in %b format, with a negative number.
-	// See issue 6777.
-	{"%#064x", 1, zeroFill("0x", 64, "1")},
-	{"%#064x", -1, zeroFill("-0x", 63, "1")},
-	{"%#064b", 1, zeroFill("", 64, "1")},
-	{"%#064b", -1, zeroFill("-", 63, "1")},
-	{"%#064o", 1, zeroFill("", 64, "1")},
-	{"%#064o", -1, zeroFill("-", 63, "1")},
-	{"%#064d", 1, zeroFill("", 64, "1")},
-	{"%#064d", -1, zeroFill("-", 63, "1")},
-	// Test that we handle the crossover above the size of uint64
-	{"%#072x", 1, zeroFill("0x", 72, "1")},
-	{"%#072x", -1, zeroFill("-0x", 71, "1")},
-	{"%#072b", 1, zeroFill("", 72, "1")},
-	{"%#072b", -1, zeroFill("-", 71, "1")},
-	{"%#072o", 1, zeroFill("", 72, "1")},
-	{"%#072o", -1, zeroFill("-", 71, "1")},
-	{"%#072d", 1, zeroFill("", 72, "1")},
-	{"%#072d", -1, zeroFill("-", 71, "1")},
-
-	// Padding for complex numbers. Has been bad, then fixed, then bad again.
-	{"%+10.2f", +104.66 + 440.51i, "(   +104.66   +440.51i)"},
-	{"%+10.2f", -104.66 + 440.51i, "(   -104.66   +440.51i)"},
-	{"%+10.2f", +104.66 - 440.51i, "(   +104.66   -440.51i)"},
-	{"%+10.2f", -104.66 - 440.51i, "(   -104.66   -440.51i)"},
-	{"%+010.2f", +104.66 + 440.51i, "(+000104.66+000440.51i)"},
-	{"%+010.2f", -104.66 + 440.51i, "(-000104.66+000440.51i)"},
-	{"%+010.2f", +104.66 - 440.51i, "(+000104.66-000440.51i)"},
-	{"%+010.2f", -104.66 - 440.51i, "(-000104.66-000440.51i)"},
-}
-
-// zeroFill generates zero-filled strings of the specified width. The length
-// of the suffix (but not the prefix) is compensated for in the width calculation.
-func zeroFill(prefix string, width int, suffix string) string {
-	return prefix + strings.Repeat("0", width-len(suffix)) + suffix
-}
-
-func TestSprintf(t *testing.T) {
-	for _, tt := range fmtTests {
-		s := Sprintf(tt.fmt, tt.val)
-		if i := strings.Index(tt.out, "PTR"); i >= 0 {
-			pattern := "PTR"
-			chars := "0123456789abcdefABCDEF"
-			switch {
-			case strings.HasPrefix(tt.out[i:], "PTR_d"):
-				pattern = "PTR_d"
-				chars = chars[:10]
-			case strings.HasPrefix(tt.out[i:], "PTR_o"):
-				pattern = "PTR_o"
-				chars = chars[:8]
-			case strings.HasPrefix(tt.out[i:], "PTR_x"):
-				pattern = "PTR_x"
-			}
-			j := i
-			for ; j < len(s); j++ {
-				c := s[j]
-				if !strings.ContainsRune(chars, rune(c)) {
-					break
-				}
-			}
-			s = s[0:i] + pattern + s[j:]
-		}
-		if s != tt.out {
-			if _, ok := tt.val.(string); ok {
-				// Don't requote the already-quoted strings.
-				// It's too confusing to read the errors.
-				t.Errorf("Sprintf(%q, %q) = <%s> want <%s>", tt.fmt, tt.val, s, tt.out)
-			} else {
-				t.Errorf("Sprintf(%q, %v) = %q want %q", tt.fmt, tt.val, s, tt.out)
-			}
-		}
-	}
-}
-
-// TestComplexFormatting checks that a complex always formats to the same
-// thing as if done by hand with two singleton prints.
-func TestComplexFormatting(t *testing.T) {
-	var yesNo = []bool{true, false}
-	var signs = []float64{1, 0, -1}
-	for _, plus := range yesNo {
-		for _, zero := range yesNo {
-			for _, space := range yesNo {
-				for _, char := range "fFeEgG" {
-					realFmt := "%"
-					if zero {
-						realFmt += "0"
-					}
-					if space {
-						realFmt += " "
-					}
-					if plus {
-						realFmt += "+"
-					}
-					realFmt += "10.2"
-					realFmt += string(char)
-					// Imaginary part always has a sign, so force + and ignore space.
-					imagFmt := "%"
-					if zero {
-						imagFmt += "0"
-					}
-					imagFmt += "+"
-					imagFmt += "10.2"
-					imagFmt += string(char)
-					for _, realSign := range signs {
-						for _, imagSign := range signs {
-							one := Sprintf(realFmt, complex(realSign, imagSign))
-							two := Sprintf("("+realFmt+imagFmt+"i)", realSign, imagSign)
-							if one != two {
-								t.Error(f, one, two)
-							}
-						}
-					}
-				}
-			}
-		}
-	}
-}
-
-type SE []interface{} // slice of empty; notational compactness.
-
-var reorderTests = []struct {
-	fmt string
-	val SE
-	out string
-}{
-	{"%[1]d", SE{1}, "1"},
-	{"%[2]d", SE{2, 1}, "1"},
-	{"%[2]d %[1]d", SE{1, 2}, "2 1"},
-	{"%[2]*[1]d", SE{2, 5}, "    2"},
-	{"%6.2f", SE{12.0}, " 12.00"}, // Explicit version of next line.
-	{"%[3]*.[2]*[1]f", SE{12.0, 2, 6}, " 12.00"},
-	{"%[1]*.[2]*[3]f", SE{6, 2, 12.0}, " 12.00"},
-	{"%10f", SE{12.0}, " 12.000000"},
-	{"%[1]*[3]f", SE{10, 99, 12.0}, " 12.000000"},
-	{"%.6f", SE{12.0}, "12.000000"}, // Explicit version of next line.
-	{"%.[1]*[3]f", SE{6, 99, 12.0}, "12.000000"},
-	{"%6.f", SE{12.0}, "    12"}, //  // Explicit version of next line; empty precision means zero.
-	{"%[1]*.[3]f", SE{6, 3, 12.0}, "    12"},
-	// An actual use! Print the same arguments twice.
-	{"%d %d %d %#[1]o %#o %#o", SE{11, 12, 13}, "11 12 13 013 014 015"},
-
-	// Erroneous cases.
-	{"%[d", SE{2, 1}, "%!d(BADINDEX)"},
-	{"%]d", SE{2, 1}, "%!](int=2)d%!(EXTRA int=1)"},
-	{"%[]d", SE{2, 1}, "%!d(BADINDEX)"},
-	{"%[-3]d", SE{2, 1}, "%!d(BADINDEX)"},
-	{"%[99]d", SE{2, 1}, "%!d(BADINDEX)"},
-	{"%[3]", SE{2, 1}, "%!(NOVERB)"},
-	{"%[1].2d", SE{5, 6}, "%!d(BADINDEX)"},
-	{"%[1]2d", SE{2, 1}, "%!d(BADINDEX)"},
-	{"%3.[2]d", SE{7}, "%!d(BADINDEX)"},
-	{"%.[2]d", SE{7}, "%!d(BADINDEX)"},
-	{"%d %d %d %#[1]o %#o %#o %#o", SE{11, 12, 13}, "11 12 13 013 014 015 %!o(MISSING)"},
-	{"%[5]d %[2]d %d", SE{1, 2, 3}, "%!d(BADINDEX) 2 3"},
-	{"%d %[3]d %d", SE{1, 2}, "1 %!d(BADINDEX) 2"}, // Erroneous index does not affect sequence.
-}
-
-func TestReorder(t *testing.T) {
-	for _, tt := range reorderTests {
-		s := Sprintf(tt.fmt, tt.val...)
-		if s != tt.out {
-			t.Errorf("Sprintf(%q, %v) = <%s> want <%s>", tt.fmt, tt.val, s, tt.out)
-		} else {
-		}
-	}
-}
-
-func BenchmarkSprintfEmpty(b *testing.B) {
-	b.RunParallel(func(pb *testing.PB) {
-		for pb.Next() {
-			Sprintf("")
-		}
-	})
-}
-
-func BenchmarkSprintfString(b *testing.B) {
-	b.RunParallel(func(pb *testing.PB) {
-		for pb.Next() {
-			Sprintf("%s", "hello")
-		}
-	})
-}
-
-func BenchmarkSprintfInt(b *testing.B) {
-	b.RunParallel(func(pb *testing.PB) {
-		for pb.Next() {
-			Sprintf("%d", 5)
-		}
-	})
-}
-
-func BenchmarkSprintfIntInt(b *testing.B) {
-	b.RunParallel(func(pb *testing.PB) {
-		for pb.Next() {
-			Sprintf("%d %d", 5, 6)
-		}
-	})
-}
-
-func BenchmarkSprintfPrefixedInt(b *testing.B) {
-	b.RunParallel(func(pb *testing.PB) {
-		for pb.Next() {
-			Sprintf("This is some meaningless prefix text that needs to be scanned %d", 6)
-		}
-	})
-}
-
-func BenchmarkSprintfFloat(b *testing.B) {
-	b.RunParallel(func(pb *testing.PB) {
-		for pb.Next() {
-			Sprintf("%g", 5.23184)
-		}
-	})
-}
-
-func BenchmarkManyArgs(b *testing.B) {
-	b.RunParallel(func(pb *testing.PB) {
-		var buf bytes.Buffer
-		for pb.Next() {
-			buf.Reset()
-			Fprintf(&buf, "%2d/%2d/%2d %d:%d:%d %s %s\n", 3, 4, 5, 11, 12, 13, "hello", "world")
-		}
-	})
-}
-
-var mallocBuf bytes.Buffer
-
-var mallocTest = []struct {
-	count int
-	desc  string
-	fn    func()
-}{
-	{0, `Sprintf("")`, func() { Sprintf("") }},
-	{1, `Sprintf("xxx")`, func() { Sprintf("xxx") }},
-	{1, `Sprintf("%x")`, func() { Sprintf("%x", 7) }},
-	{2, `Sprintf("%s")`, func() { Sprintf("%s", "hello") }},
-	{1, `Sprintf("%x %x")`, func() { Sprintf("%x %x", 7, 112) }},
-	// For %g we use a float32, not float64, to guarantee passing the argument
-	// does not need to allocate memory to store the result in a pointer-sized word.
-	{2, `Sprintf("%g")`, func() { Sprintf("%g", float32(3.14159)) }},
-	{0, `Fprintf(buf, "%x %x %x")`, func() { mallocBuf.Reset(); Fprintf(&mallocBuf, "%x %x %x", 7, 8, 9) }},
-	{1, `Fprintf(buf, "%s")`, func() { mallocBuf.Reset(); Fprintf(&mallocBuf, "%s", "hello") }},
-}
-
-var _ bytes.Buffer
-
-func TestCountMallocs(t *testing.T) {
-	if testing.Short() {
-		t.Skip("skipping malloc count in short mode")
-	}
-	if runtime.GOMAXPROCS(0) > 1 {
-		t.Skip("skipping; GOMAXPROCS>1")
-	}
-	for _, mt := range mallocTest {
-		mallocs := testing.AllocsPerRun(100, mt.fn)
-		if got, max := mallocs, float64(mt.count); got > max {
-			t.Errorf("%s: got %v allocs, want <=%v", mt.desc, got, max)
-		}
-	}
-}
-
-type flagPrinter struct{}
-
-func (*flagPrinter) Format(f State, c rune) {
-	s := "%"
-	for i := 0; i < 128; i++ {
-		if f.Flag(i) {
-			s += string(i)
-		}
-	}
-	if w, ok := f.Width(); ok {
-		s += Sprintf("%d", w)
-	}
-	if p, ok := f.Precision(); ok {
-		s += Sprintf(".%d", p)
-	}
-	s += string(c)
-	io.WriteString(f, "["+s+"]")
-}
-
-var flagtests = []struct {
-	in  string
-	out string
-}{
-	{"%a", "[%a]"},
-	{"%-a", "[%-a]"},
-	{"%+a", "[%+a]"},
-	{"%#a", "[%#a]"},
-	{"% a", "[% a]"},
-	{"%0a", "[%0a]"},
-	{"%1.2a", "[%1.2a]"},
-	{"%-1.2a", "[%-1.2a]"},
-	{"%+1.2a", "[%+1.2a]"},
-	{"%-+1.2a", "[%+-1.2a]"},
-	{"%-+1.2abc", "[%+-1.2a]bc"},
-	{"%-1.2abc", "[%-1.2a]bc"},
-}
-
-func TestFlagParser(t *testing.T) {
-	var flagprinter flagPrinter
-	for _, tt := range flagtests {
-		s := Sprintf(tt.in, &flagprinter)
-		if s != tt.out {
-			t.Errorf("Sprintf(%q, &flagprinter) => %q, want %q", tt.in, s, tt.out)
-		}
-	}
-}
-
-func TestStructPrinter(t *testing.T) {
-	var s struct {
-		a string
-		b string
-		c int
-	}
-	s.a = "abc"
-	s.b = "def"
-	s.c = 123
-	var tests = []struct {
-		fmt string
-		out string
-	}{
-		{"%v", "{abc def 123}"},
-		{"%+v", "{a:abc b:def c:123}"},
-	}
-	for _, tt := range tests {
-		out := Sprintf(tt.fmt, s)
-		if out != tt.out {
-			t.Errorf("Sprintf(%q, &s) = %q, want %q", tt.fmt, out, tt.out)
-		}
-	}
-}
-
-// presentInMap checks map printing using substrings so we don't depend on the
-// print order.
-func presentInMap(s string, a []string, t *testing.T) {
-	for i := 0; i < len(a); i++ {
-		loc := strings.Index(s, a[i])
-		if loc < 0 {
-			t.Errorf("map print: expected to find %q in %q", a[i], s)
-		}
-		// make sure the match ends here
-		loc += len(a[i])
-		if loc >= len(s) || (s[loc] != ' ' && s[loc] != ']') {
-			t.Errorf("map print: %q not properly terminated in %q", a[i], s)
-		}
-	}
-}
-
-func TestMapPrinter(t *testing.T) {
-	m0 := make(map[int]string)
-	s := Sprint(m0)
-	if s != "map[]" {
-		t.Errorf("empty map printed as %q not %q", s, "map[]")
-	}
-	m1 := map[int]string{1: "one", 2: "two", 3: "three"}
-	a := []string{"1:one", "2:two", "3:three"}
-	presentInMap(Sprintf("%v", m1), a, t)
-	presentInMap(Sprint(m1), a, t)
-}
-
-func TestEmptyMap(t *testing.T) {
-	const emptyMapStr = "map[]"
-	var m map[string]int
-	s := Sprint(m)
-	if s != emptyMapStr {
-		t.Errorf("nil map printed as %q not %q", s, emptyMapStr)
-	}
-	m = make(map[string]int)
-	s = Sprint(m)
-	if s != emptyMapStr {
-		t.Errorf("empty map printed as %q not %q", s, emptyMapStr)
-	}
-}
-
-// TestBlank checks that Sprint (and hence Print, Fprint) puts spaces in the
-// right places, that is, between arg pairs in which neither is a string.
-func TestBlank(t *testing.T) {
-	got := Sprint("<", 1, ">:", 1, 2, 3, "!")
-	expect := "<1>:1 2 3!"
-	if got != expect {
-		t.Errorf("got %q expected %q", got, expect)
-	}
-}
-
-// TestBlankln checks that Sprintln (and hence Println, Fprintln) puts spaces in
-// the right places, that is, between all arg pairs.
-func TestBlankln(t *testing.T) {
-	got := Sprintln("<", 1, ">:", 1, 2, 3, "!")
-	expect := "< 1 >: 1 2 3 !\n"
-	if got != expect {
-		t.Errorf("got %q expected %q", got, expect)
-	}
-}
-
-// TestFormatterPrintln checks Formatter with Sprint, Sprintln, Sprintf.
-func TestFormatterPrintln(t *testing.T) {
-	f := F(1)
-	expect := "<v=F(1)>\n"
-	s := Sprint(f, "\n")
-	if s != expect {
-		t.Errorf("Sprint wrong with Formatter: expected %q got %q", expect, s)
-	}
-	s = Sprintln(f)
-	if s != expect {
-		t.Errorf("Sprintln wrong with Formatter: expected %q got %q", expect, s)
-	}
-	s = Sprintf("%v\n", f)
-	if s != expect {
-		t.Errorf("Sprintf wrong with Formatter: expected %q got %q", expect, s)
-	}
-}
-
-func args(a ...interface{}) []interface{} { return a }
-
-var startests = []struct {
-	fmt string
-	in  []interface{}
-	out string
-}{
-	{"%*d", args(4, 42), "  42"},
-	{"%.*d", args(4, 42), "0042"},
-	{"%*.*d", args(8, 4, 42), "    0042"},
-	{"%0*d", args(4, 42), "0042"},
-	{"%-*d", args(4, 42), "42  "},
-
-	// erroneous
-	{"%*d", args(nil, 42), "%!(BADWIDTH)42"},
-	{"%.*d", args(nil, 42), "%!(BADPREC)42"},
-	{"%*d", args(5, "foo"), "%!d(string=  foo)"},
-	{"%*% %d", args(20, 5), "% 5"},
-	{"%*", args(4), "%!(NOVERB)"},
-	{"%*d", args(int32(4), 42), "%!(BADWIDTH)42"},
-}
-
-func TestWidthAndPrecision(t *testing.T) {
-	for _, tt := range startests {
-		s := Sprintf(tt.fmt, tt.in...)
-		if s != tt.out {
-			t.Errorf("%q: got %q expected %q", tt.fmt, s, tt.out)
-		}
-	}
-}
-
-// Panic is a type that panics in String.
-type Panic struct {
-	message interface{}
-}
-
-// Value receiver.
-func (p Panic) GoString() string {
-	panic(p.message)
-}
-
-// Value receiver.
-func (p Panic) String() string {
-	panic(p.message)
-}
-
-// PanicF is a type that panics in Format.
-type PanicF struct {
-	message interface{}
-}
-
-// Value receiver.
-func (p PanicF) Format(f State, c rune) {
-	panic(p.message)
-}
-
-var panictests = []struct {
-	fmt string
-	in  interface{}
-	out string
-}{
-	// String
-	{"%s", (*Panic)(nil), "<nil>"}, // nil pointer special case
-	{"%s", Panic{io.ErrUnexpectedEOF}, "%!s(PANIC=unexpected EOF)"},
-	{"%s", Panic{3}, "%!s(PANIC=3)"},
-	// GoString
-	{"%#v", (*Panic)(nil), "<nil>"}, // nil pointer special case
-	{"%#v", Panic{io.ErrUnexpectedEOF}, "%!v(PANIC=unexpected EOF)"},
-	{"%#v", Panic{3}, "%!v(PANIC=3)"},
-	// Format
-	{"%s", (*PanicF)(nil), "<nil>"}, // nil pointer special case
-	{"%s", PanicF{io.ErrUnexpectedEOF}, "%!s(PANIC=unexpected EOF)"},
-	{"%s", PanicF{3}, "%!s(PANIC=3)"},
-}
-
-func TestPanics(t *testing.T) {
-	for _, tt := range panictests {
-		s := Sprintf(tt.fmt, tt.in)
-		if s != tt.out {
-			t.Errorf("%q: got %q expected %q", tt.fmt, s, tt.out)
-		}
-	}
-}
-
-// recurCount tests that erroneous String routine doesn't cause fatal recursion.
-var recurCount = 0
-
-type Recur struct {
-	i      int
-	failed *bool
-}
-
-func (r *Recur) String() string {
-	if recurCount++; recurCount > 10 {
-		*r.failed = true
-		return "FAIL"
-	}
-	// This will call badVerb. Before the fix, that would cause us to recur into
-	// this routine to print %!p(value). Now we don't call the user's method
-	// during an error.
-	return Sprintf("recur@%p value: %d", r, r.i)
-}
-
-func TestBadVerbRecursion(t *testing.T) {
-	failed := false
-	r := &Recur{3, &failed}
-	Sprintf("recur@%p value: %d\n", &r, r.i)
-	if failed {
-		t.Error("fail with pointer")
-	}
-	failed = false
-	r = &Recur{4, &failed}
-	Sprintf("recur@%p, value: %d\n", r, r.i)
-	if failed {
-		t.Error("fail with value")
-	}
-}
-
-func TestIsSpace(t *testing.T) {
-	// This tests the internal isSpace function.
-	// IsSpace = isSpace is defined in export_test.go.
-	for i := rune(0); i <= unicode.MaxRune; i++ {
-		if IsSpace(i) != unicode.IsSpace(i) {
-			t.Errorf("isSpace(%U) = %v, want %v", i, IsSpace(i), unicode.IsSpace(i))
-		}
-	}
-}
-
-func TestNilDoesNotBecomeTyped(t *testing.T) {
-	type A struct{}
-	type B struct{}
-	var a *A = nil
-	var b B = B{}
-	got := Sprintf("%s %s %s %s %s", nil, a, nil, b, nil)
-	const expect = "%!s(<nil>) %!s(*fmt_test.A=<nil>) %!s(<nil>) {} %!s(<nil>)"
-	if got != expect {
-		t.Errorf("expected:\n\t%q\ngot:\n\t%q", expect, got)
-	}
-}
diff --git a/src/pkg/fmt/format.go b/src/pkg/fmt/format.go
deleted file mode 100644
index a89c542..0000000
--- a/src/pkg/fmt/format.go
+++ /dev/null
@@ -1,492 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package fmt
-
-import (
-	"math"
-	"strconv"
-	"unicode/utf8"
-)
-
-const (
-	// %b of an int64, plus a sign.
-	// Hex can add 0x and we handle it specially.
-	nByte = 65
-
-	ldigits = "0123456789abcdef"
-	udigits = "0123456789ABCDEF"
-)
-
-const (
-	signed   = true
-	unsigned = false
-)
-
-var padZeroBytes = make([]byte, nByte)
-var padSpaceBytes = make([]byte, nByte)
-
-func init() {
-	for i := 0; i < nByte; i++ {
-		padZeroBytes[i] = '0'
-		padSpaceBytes[i] = ' '
-	}
-}
-
-// A fmt is the raw formatter used by Printf etc.
-// It prints into a buffer that must be set up separately.
-type fmt struct {
-	intbuf [nByte]byte
-	buf    *buffer
-	// width, precision
-	wid  int
-	prec int
-	// flags
-	widPresent  bool
-	precPresent bool
-	minus       bool
-	plus        bool
-	sharp       bool
-	space       bool
-	unicode     bool
-	uniQuote    bool // Use 'x'= prefix for %U if printable.
-	zero        bool
-}
-
-func (f *fmt) clearflags() {
-	f.wid = 0
-	f.widPresent = false
-	f.prec = 0
-	f.precPresent = false
-	f.minus = false
-	f.plus = false
-	f.sharp = false
-	f.space = false
-	f.unicode = false
-	f.uniQuote = false
-	f.zero = false
-}
-
-func (f *fmt) init(buf *buffer) {
-	f.buf = buf
-	f.clearflags()
-}
-
-// computePadding computes left and right padding widths (only one will be non-zero).
-func (f *fmt) computePadding(width int) (padding []byte, leftWidth, rightWidth int) {
-	left := !f.minus
-	w := f.wid
-	if w < 0 {
-		left = false
-		w = -w
-	}
-	w -= width
-	if w > 0 {
-		if left && f.zero {
-			return padZeroBytes, w, 0
-		}
-		if left {
-			return padSpaceBytes, w, 0
-		} else {
-			// can't be zero padding on the right
-			return padSpaceBytes, 0, w
-		}
-	}
-	return
-}
-
-// writePadding generates n bytes of padding.
-func (f *fmt) writePadding(n int, padding []byte) {
-	for n > 0 {
-		m := n
-		if m > nByte {
-			m = nByte
-		}
-		f.buf.Write(padding[0:m])
-		n -= m
-	}
-}
-
-// pad appends b to f.buf, padded on left (w > 0) or right (w < 0 or f.minus).
-func (f *fmt) pad(b []byte) {
-	if !f.widPresent || f.wid == 0 {
-		f.buf.Write(b)
-		return
-	}
-	padding, left, right := f.computePadding(len(b))
-	if left > 0 {
-		f.writePadding(left, padding)
-	}
-	f.buf.Write(b)
-	if right > 0 {
-		f.writePadding(right, padding)
-	}
-}
-
-// padString appends s to buf, padded on left (w > 0) or right (w < 0 or f.minus).
-func (f *fmt) padString(s string) {
-	if !f.widPresent || f.wid == 0 {
-		f.buf.WriteString(s)
-		return
-	}
-	padding, left, right := f.computePadding(utf8.RuneCountInString(s))
-	if left > 0 {
-		f.writePadding(left, padding)
-	}
-	f.buf.WriteString(s)
-	if right > 0 {
-		f.writePadding(right, padding)
-	}
-}
-
-var (
-	trueBytes  = []byte("true")
-	falseBytes = []byte("false")
-)
-
-// fmt_boolean formats a boolean.
-func (f *fmt) fmt_boolean(v bool) {
-	if v {
-		f.pad(trueBytes)
-	} else {
-		f.pad(falseBytes)
-	}
-}
-
-// integer; interprets prec but not wid.  Once formatted, result is sent to pad()
-// and then flags are cleared.
-func (f *fmt) integer(a int64, base uint64, signedness bool, digits string) {
-	// precision of 0 and value of 0 means "print nothing"
-	if f.precPresent && f.prec == 0 && a == 0 {
-		return
-	}
-
-	var buf []byte = f.intbuf[0:]
-	if f.widPresent {
-		width := f.wid
-		if base == 16 && f.sharp {
-			// Also adds "0x".
-			width += 2
-		}
-		if width > nByte {
-			// We're going to need a bigger boat.
-			buf = make([]byte, width)
-		}
-	}
-
-	negative := signedness == signed && a < 0
-	if negative {
-		a = -a
-	}
-
-	// two ways to ask for extra leading zero digits: %.3d or %03d.
-	// apparently the first cancels the second.
-	prec := 0
-	if f.precPresent {
-		prec = f.prec
-		f.zero = false
-	} else if f.zero && f.widPresent && !f.minus && f.wid > 0 {
-		prec = f.wid
-		if negative || f.plus || f.space {
-			prec-- // leave room for sign
-		}
-	}
-
-	// format a into buf, ending at buf[i].  (printing is easier right-to-left.)
-	// a is made into unsigned ua.  we could make things
-	// marginally faster by splitting the 32-bit case out into a separate
-	// block but it's not worth the duplication, so ua has 64 bits.
-	i := len(buf)
-	ua := uint64(a)
-	for ua >= base {
-		i--
-		buf[i] = digits[ua%base]
-		ua /= base
-	}
-	i--
-	buf[i] = digits[ua]
-	for i > 0 && prec > len(buf)-i {
-		i--
-		buf[i] = '0'
-	}
-
-	// Various prefixes: 0x, -, etc.
-	if f.sharp {
-		switch base {
-		case 8:
-			if buf[i] != '0' {
-				i--
-				buf[i] = '0'
-			}
-		case 16:
-			i--
-			buf[i] = 'x' + digits[10] - 'a'
-			i--
-			buf[i] = '0'
-		}
-	}
-	if f.unicode {
-		i--
-		buf[i] = '+'
-		i--
-		buf[i] = 'U'
-	}
-
-	if negative {
-		i--
-		buf[i] = '-'
-	} else if f.plus {
-		i--
-		buf[i] = '+'
-	} else if f.space {
-		i--
-		buf[i] = ' '
-	}
-
-	// If we want a quoted char for %#U, move the data up to make room.
-	if f.unicode && f.uniQuote && a >= 0 && a <= utf8.MaxRune && strconv.IsPrint(rune(a)) {
-		runeWidth := utf8.RuneLen(rune(a))
-		width := 1 + 1 + runeWidth + 1 // space, quote, rune, quote
-		copy(buf[i-width:], buf[i:])   // guaranteed to have enough room.
-		i -= width
-		// Now put " 'x'" at the end.
-		j := len(buf) - width
-		buf[j] = ' '
-		j++
-		buf[j] = '\''
-		j++
-		utf8.EncodeRune(buf[j:], rune(a))
-		j += runeWidth
-		buf[j] = '\''
-	}
-
-	f.pad(buf[i:])
-}
-
-// truncate truncates the string to the specified precision, if present.
-func (f *fmt) truncate(s string) string {
-	if f.precPresent && f.prec < utf8.RuneCountInString(s) {
-		n := f.prec
-		for i := range s {
-			if n == 0 {
-				s = s[:i]
-				break
-			}
-			n--
-		}
-	}
-	return s
-}
-
-// fmt_s formats a string.
-func (f *fmt) fmt_s(s string) {
-	s = f.truncate(s)
-	f.padString(s)
-}
-
-// fmt_sbx formats a string or byte slice as a hexadecimal encoding of its bytes.
-func (f *fmt) fmt_sbx(s string, b []byte, digits string) {
-	n := len(b)
-	if b == nil {
-		n = len(s)
-	}
-	x := digits[10] - 'a' + 'x'
-	// TODO: Avoid buffer by pre-padding.
-	var buf []byte
-	for i := 0; i < n; i++ {
-		if i > 0 && f.space {
-			buf = append(buf, ' ')
-		}
-		if f.sharp {
-			buf = append(buf, '0', x)
-		}
-		var c byte
-		if b == nil {
-			c = s[i]
-		} else {
-			c = b[i]
-		}
-		buf = append(buf, digits[c>>4], digits[c&0xF])
-	}
-	f.pad(buf)
-}
-
-// fmt_sx formats a string as a hexadecimal encoding of its bytes.
-func (f *fmt) fmt_sx(s, digits string) {
-	f.fmt_sbx(s, nil, digits)
-}
-
-// fmt_bx formats a byte slice as a hexadecimal encoding of its bytes.
-func (f *fmt) fmt_bx(b []byte, digits string) {
-	f.fmt_sbx("", b, digits)
-}
-
-// fmt_q formats a string as a double-quoted, escaped Go string constant.
-func (f *fmt) fmt_q(s string) {
-	s = f.truncate(s)
-	var quoted string
-	if f.sharp && strconv.CanBackquote(s) {
-		quoted = "`" + s + "`"
-	} else {
-		if f.plus {
-			quoted = strconv.QuoteToASCII(s)
-		} else {
-			quoted = strconv.Quote(s)
-		}
-	}
-	f.padString(quoted)
-}
-
-// fmt_qc formats the integer as a single-quoted, escaped Go character constant.
-// If the character is not valid Unicode, it will print '\ufffd'.
-func (f *fmt) fmt_qc(c int64) {
-	var quoted []byte
-	if f.plus {
-		quoted = strconv.AppendQuoteRuneToASCII(f.intbuf[0:0], rune(c))
-	} else {
-		quoted = strconv.AppendQuoteRune(f.intbuf[0:0], rune(c))
-	}
-	f.pad(quoted)
-}
-
-// floating-point
-
-func doPrec(f *fmt, def int) int {
-	if f.precPresent {
-		return f.prec
-	}
-	return def
-}
-
-// formatFloat formats a float64; it is an efficient equivalent to  f.pad(strconv.FormatFloat()...).
-func (f *fmt) formatFloat(v float64, verb byte, prec, n int) {
-	// Format number, reserving space for leading + sign if needed.
-	num := strconv.AppendFloat(f.intbuf[0:1], v, verb, prec, n)
-	if num[1] == '-' || num[1] == '+' {
-		num = num[1:]
-	} else {
-		num[0] = '+'
-	}
-	// Special handling for infinity, which doesn't look like a number so shouldn't be padded with zeros.
-	if math.IsInf(v, 0) {
-		if f.zero {
-			defer func() { f.zero = true }()
-			f.zero = false
-		}
-	}
-	// num is now a signed version of the number.
-	// If we're zero padding, want the sign before the leading zeros.
-	// Achieve this by writing the sign out and then padding the unsigned number.
-	if f.zero && f.widPresent && f.wid > len(num) {
-		if f.space && v >= 0 {
-			f.buf.WriteByte(' ') // This is what C does: even with zero, f.space means space.
-			f.wid--
-		} else if f.plus || v < 0 {
-			f.buf.WriteByte(num[0])
-			f.wid--
-		}
-		f.pad(num[1:])
-		return
-	}
-	// f.space says to replace a leading + with a space.
-	if f.space && num[0] == '+' {
-		num[0] = ' '
-		f.pad(num)
-		return
-	}
-	// Now we know the sign is attached directly to the number, if present at all.
-	// We want a sign if asked for, if it's negative, or if it's infinity (+Inf vs. -Inf).
-	if f.plus || num[0] == '-' || math.IsInf(v, 0) {
-		f.pad(num)
-		return
-	}
-	// No sign to show and the number is positive; just print the unsigned number.
-	f.pad(num[1:])
-}
-
-// fmt_e64 formats a float64 in the form -1.23e+12.
-func (f *fmt) fmt_e64(v float64) { f.formatFloat(v, 'e', doPrec(f, 6), 64) }
-
-// fmt_E64 formats a float64 in the form -1.23E+12.
-func (f *fmt) fmt_E64(v float64) { f.formatFloat(v, 'E', doPrec(f, 6), 64) }
-
-// fmt_f64 formats a float64 in the form -1.23.
-func (f *fmt) fmt_f64(v float64) { f.formatFloat(v, 'f', doPrec(f, 6), 64) }
-
-// fmt_g64 formats a float64 in the 'f' or 'e' form according to size.
-func (f *fmt) fmt_g64(v float64) { f.formatFloat(v, 'g', doPrec(f, -1), 64) }
-
-// fmt_G64 formats a float64 in the 'f' or 'E' form according to size.
-func (f *fmt) fmt_G64(v float64) { f.formatFloat(v, 'G', doPrec(f, -1), 64) }
-
-// fmt_fb64 formats a float64 in the form -123p3 (exponent is power of 2).
-func (f *fmt) fmt_fb64(v float64) { f.formatFloat(v, 'b', 0, 64) }
-
-// float32
-// cannot defer to float64 versions
-// because it will get rounding wrong in corner cases.
-
-// fmt_e32 formats a float32 in the form -1.23e+12.
-func (f *fmt) fmt_e32(v float32) { f.formatFloat(float64(v), 'e', doPrec(f, 6), 32) }
-
-// fmt_E32 formats a float32 in the form -1.23E+12.
-func (f *fmt) fmt_E32(v float32) { f.formatFloat(float64(v), 'E', doPrec(f, 6), 32) }
-
-// fmt_f32 formats a float32 in the form -1.23.
-func (f *fmt) fmt_f32(v float32) { f.formatFloat(float64(v), 'f', doPrec(f, 6), 32) }
-
-// fmt_g32 formats a float32 in the 'f' or 'e' form according to size.
-func (f *fmt) fmt_g32(v float32) { f.formatFloat(float64(v), 'g', doPrec(f, -1), 32) }
-
-// fmt_G32 formats a float32 in the 'f' or 'E' form according to size.
-func (f *fmt) fmt_G32(v float32) { f.formatFloat(float64(v), 'G', doPrec(f, -1), 32) }
-
-// fmt_fb32 formats a float32 in the form -123p3 (exponent is power of 2).
-func (f *fmt) fmt_fb32(v float32) { f.formatFloat(float64(v), 'b', 0, 32) }
-
-// fmt_c64 formats a complex64 according to the verb.
-func (f *fmt) fmt_c64(v complex64, verb rune) {
-	f.fmt_complex(float64(real(v)), float64(imag(v)), 32, verb)
-}
-
-// fmt_c128 formats a complex128 according to the verb.
-func (f *fmt) fmt_c128(v complex128, verb rune) {
-	f.fmt_complex(real(v), imag(v), 64, verb)
-}
-
-// fmt_complex formats a complex number as (r+ji).
-func (f *fmt) fmt_complex(r, j float64, size int, verb rune) {
-	f.buf.WriteByte('(')
-	oldPlus := f.plus
-	oldSpace := f.space
-	oldWid := f.wid
-	for i := 0; ; i++ {
-		switch verb {
-		case 'b':
-			f.formatFloat(r, 'b', 0, size)
-		case 'e':
-			f.formatFloat(r, 'e', doPrec(f, 6), size)
-		case 'E':
-			f.formatFloat(r, 'E', doPrec(f, 6), size)
-		case 'f', 'F':
-			f.formatFloat(r, 'f', doPrec(f, 6), size)
-		case 'g':
-			f.formatFloat(r, 'g', doPrec(f, -1), size)
-		case 'G':
-			f.formatFloat(r, 'G', doPrec(f, -1), size)
-		}
-		if i != 0 {
-			break
-		}
-		// Imaginary part always has a sign.
-		f.plus = true
-		f.space = false
-		f.wid = oldWid
-		r = j
-	}
-	f.space = oldSpace
-	f.plus = oldPlus
-	f.wid = oldWid
-	f.buf.Write(irparenBytes)
-}
diff --git a/src/pkg/fmt/print.go b/src/pkg/fmt/print.go
deleted file mode 100644
index 302661f..0000000
--- a/src/pkg/fmt/print.go
+++ /dev/null
@@ -1,1199 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package fmt
-
-import (
-	"errors"
-	"io"
-	"os"
-	"reflect"
-	"sync"
-	"unicode/utf8"
-)
-
-// Some constants in the form of bytes, to avoid string overhead.
-// Needlessly fastidious, I suppose.
-var (
-	commaSpaceBytes  = []byte(", ")
-	nilAngleBytes    = []byte("<nil>")
-	nilParenBytes    = []byte("(nil)")
-	nilBytes         = []byte("nil")
-	mapBytes         = []byte("map[")
-	percentBangBytes = []byte("%!")
-	missingBytes     = []byte("(MISSING)")
-	badIndexBytes    = []byte("(BADINDEX)")
-	panicBytes       = []byte("(PANIC=")
-	extraBytes       = []byte("%!(EXTRA ")
-	irparenBytes     = []byte("i)")
-	bytesBytes       = []byte("[]byte{")
-	badWidthBytes    = []byte("%!(BADWIDTH)")
-	badPrecBytes     = []byte("%!(BADPREC)")
-	noVerbBytes      = []byte("%!(NOVERB)")
-)
-
-// State represents the printer state passed to custom formatters.
-// It provides access to the io.Writer interface plus information about
-// the flags and options for the operand's format specifier.
-type State interface {
-	// Write is the function to call to emit formatted output to be printed.
-	Write(b []byte) (ret int, err error)
-	// Width returns the value of the width option and whether it has been set.
-	Width() (wid int, ok bool)
-	// Precision returns the value of the precision option and whether it has been set.
-	Precision() (prec int, ok bool)
-
-	// Flag reports whether the flag c, a character, has been set.
-	Flag(c int) bool
-}
-
-// Formatter is the interface implemented by values with a custom formatter.
-// The implementation of Format may call Sprint(f) or Fprint(f) etc.
-// to generate its output.
-type Formatter interface {
-	Format(f State, c rune)
-}
-
-// Stringer is implemented by any value that has a String method,
-// which defines the ``native'' format for that value.
-// The String method is used to print values passed as an operand
-// to any format that accepts a string or to an unformatted printer
-// such as Print.
-type Stringer interface {
-	String() string
-}
-
-// GoStringer is implemented by any value that has a GoString method,
-// which defines the Go syntax for that value.
-// The GoString method is used to print values passed as an operand
-// to a %#v format.
-type GoStringer interface {
-	GoString() string
-}
-
-// Use simple []byte instead of bytes.Buffer to avoid large dependency.
-type buffer []byte
-
-func (b *buffer) Write(p []byte) (n int, err error) {
-	*b = append(*b, p...)
-	return len(p), nil
-}
-
-func (b *buffer) WriteString(s string) (n int, err error) {
-	*b = append(*b, s...)
-	return len(s), nil
-}
-
-func (b *buffer) WriteByte(c byte) error {
-	*b = append(*b, c)
-	return nil
-}
-
-func (bp *buffer) WriteRune(r rune) error {
-	if r < utf8.RuneSelf {
-		*bp = append(*bp, byte(r))
-		return nil
-	}
-
-	b := *bp
-	n := len(b)
-	for n+utf8.UTFMax > cap(b) {
-		b = append(b, 0)
-	}
-	w := utf8.EncodeRune(b[n:n+utf8.UTFMax], r)
-	*bp = b[:n+w]
-	return nil
-}
-
-type pp struct {
-	n         int
-	panicking bool
-	erroring  bool // printing an error condition
-	buf       buffer
-	// arg holds the current item, as an interface{}.
-	arg interface{}
-	// value holds the current item, as a reflect.Value, and will be
-	// the zero Value if the item has not been reflected.
-	value reflect.Value
-	// reordered records whether the format string used argument reordering.
-	reordered bool
-	// goodArgNum records whether the most recent reordering directive was valid.
-	goodArgNum bool
-	runeBuf    [utf8.UTFMax]byte
-	fmt        fmt
-}
-
-var ppFree = sync.Pool{
-	New: func() interface{} { return new(pp) },
-}
-
-// newPrinter allocates a new pp struct or grab a cached one.
-func newPrinter() *pp {
-	p := ppFree.Get().(*pp)
-	p.panicking = false
-	p.erroring = false
-	p.fmt.init(&p.buf)
-	return p
-}
-
-// free saves used pp structs in ppFree; avoids an allocation per invocation.
-func (p *pp) free() {
-	// Don't hold on to pp structs with large buffers.
-	if cap(p.buf) > 1024 {
-		return
-	}
-	p.buf = p.buf[:0]
-	p.arg = nil
-	p.value = reflect.Value{}
-	ppFree.Put(p)
-}
-
-func (p *pp) Width() (wid int, ok bool) { return p.fmt.wid, p.fmt.widPresent }
-
-func (p *pp) Precision() (prec int, ok bool) { return p.fmt.prec, p.fmt.precPresent }
-
-func (p *pp) Flag(b int) bool {
-	switch b {
-	case '-':
-		return p.fmt.minus
-	case '+':
-		return p.fmt.plus
-	case '#':
-		return p.fmt.sharp
-	case ' ':
-		return p.fmt.space
-	case '0':
-		return p.fmt.zero
-	}
-	return false
-}
-
-func (p *pp) add(c rune) {
-	p.buf.WriteRune(c)
-}
-
-// Implement Write so we can call Fprintf on a pp (through State), for
-// recursive use in custom verbs.
-func (p *pp) Write(b []byte) (ret int, err error) {
-	return p.buf.Write(b)
-}
-
-// These routines end in 'f' and take a format string.
-
-// Fprintf formats according to a format specifier and writes to w.
-// It returns the number of bytes written and any write error encountered.
-func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) {
-	p := newPrinter()
-	p.doPrintf(format, a)
-	n, err = w.Write(p.buf)
-	p.free()
-	return
-}
-
-// Printf formats according to a format specifier and writes to standard output.
-// It returns the number of bytes written and any write error encountered.
-func Printf(format string, a ...interface{}) (n int, err error) {
-	return Fprintf(os.Stdout, format, a...)
-}
-
-// Sprintf formats according to a format specifier and returns the resulting string.
-func Sprintf(format string, a ...interface{}) string {
-	p := newPrinter()
-	p.doPrintf(format, a)
-	s := string(p.buf)
-	p.free()
-	return s
-}
-
-// Errorf formats according to a format specifier and returns the string
-// as a value that satisfies error.
-func Errorf(format string, a ...interface{}) error {
-	return errors.New(Sprintf(format, a...))
-}
-
-// These routines do not take a format string
-
-// Fprint formats using the default formats for its operands and writes to w.
-// Spaces are added between operands when neither is a string.
-// It returns the number of bytes written and any write error encountered.
-func Fprint(w io.Writer, a ...interface{}) (n int, err error) {
-	p := newPrinter()
-	p.doPrint(a, false, false)
-	n, err = w.Write(p.buf)
-	p.free()
-	return
-}
-
-// Print formats using the default formats for its operands and writes to standard output.
-// Spaces are added between operands when neither is a string.
-// It returns the number of bytes written and any write error encountered.
-func Print(a ...interface{}) (n int, err error) {
-	return Fprint(os.Stdout, a...)
-}
-
-// Sprint formats using the default formats for its operands and returns the resulting string.
-// Spaces are added between operands when neither is a string.
-func Sprint(a ...interface{}) string {
-	p := newPrinter()
-	p.doPrint(a, false, false)
-	s := string(p.buf)
-	p.free()
-	return s
-}
-
-// These routines end in 'ln', do not take a format string,
-// always add spaces between operands, and add a newline
-// after the last operand.
-
-// Fprintln formats using the default formats for its operands and writes to w.
-// Spaces are always added between operands and a newline is appended.
-// It returns the number of bytes written and any write error encountered.
-func Fprintln(w io.Writer, a ...interface{}) (n int, err error) {
-	p := newPrinter()
-	p.doPrint(a, true, true)
-	n, err = w.Write(p.buf)
-	p.free()
-	return
-}
-
-// Println formats using the default formats for its operands and writes to standard output.
-// Spaces are always added between operands and a newline is appended.
-// It returns the number of bytes written and any write error encountered.
-func Println(a ...interface{}) (n int, err error) {
-	return Fprintln(os.Stdout, a...)
-}
-
-// Sprintln formats using the default formats for its operands and returns the resulting string.
-// Spaces are always added between operands and a newline is appended.
-func Sprintln(a ...interface{}) string {
-	p := newPrinter()
-	p.doPrint(a, true, true)
-	s := string(p.buf)
-	p.free()
-	return s
-}
-
-// getField gets the i'th field of the struct value.
-// If the field is itself is an interface, return a value for
-// the thing inside the interface, not the interface itself.
-func getField(v reflect.Value, i int) reflect.Value {
-	val := v.Field(i)
-	if val.Kind() == reflect.Interface && !val.IsNil() {
-		val = val.Elem()
-	}
-	return val
-}
-
-// parsenum converts ASCII to integer.  num is 0 (and isnum is false) if no number present.
-func parsenum(s string, start, end int) (num int, isnum bool, newi int) {
-	if start >= end {
-		return 0, false, end
-	}
-	for newi = start; newi < end && '0' <= s[newi] && s[newi] <= '9'; newi++ {
-		num = num*10 + int(s[newi]-'0')
-		isnum = true
-	}
-	return
-}
-
-func (p *pp) unknownType(v interface{}) {
-	if v == nil {
-		p.buf.Write(nilAngleBytes)
-		return
-	}
-	p.buf.WriteByte('?')
-	p.buf.WriteString(reflect.TypeOf(v).String())
-	p.buf.WriteByte('?')
-}
-
-func (p *pp) badVerb(verb rune) {
-	p.erroring = true
-	p.add('%')
-	p.add('!')
-	p.add(verb)
-	p.add('(')
-	switch {
-	case p.arg != nil:
-		p.buf.WriteString(reflect.TypeOf(p.arg).String())
-		p.add('=')
-		p.printArg(p.arg, 'v', false, false, 0)
-	case p.value.IsValid():
-		p.buf.WriteString(p.value.Type().String())
-		p.add('=')
-		p.printValue(p.value, 'v', false, false, 0)
-	default:
-		p.buf.Write(nilAngleBytes)
-	}
-	p.add(')')
-	p.erroring = false
-}
-
-func (p *pp) fmtBool(v bool, verb rune) {
-	switch verb {
-	case 't', 'v':
-		p.fmt.fmt_boolean(v)
-	default:
-		p.badVerb(verb)
-	}
-}
-
-// fmtC formats a rune for the 'c' format.
-func (p *pp) fmtC(c int64) {
-	r := rune(c) // Check for overflow.
-	if int64(r) != c {
-		r = utf8.RuneError
-	}
-	w := utf8.EncodeRune(p.runeBuf[0:utf8.UTFMax], r)
-	p.fmt.pad(p.runeBuf[0:w])
-}
-
-func (p *pp) fmtInt64(v int64, verb rune) {
-	switch verb {
-	case 'b':
-		p.fmt.integer(v, 2, signed, ldigits)
-	case 'c':
-		p.fmtC(v)
-	case 'd', 'v':
-		p.fmt.integer(v, 10, signed, ldigits)
-	case 'o':
-		p.fmt.integer(v, 8, signed, ldigits)
-	case 'q':
-		if 0 <= v && v <= utf8.MaxRune {
-			p.fmt.fmt_qc(v)
-		} else {
-			p.badVerb(verb)
-		}
-	case 'x':
-		p.fmt.integer(v, 16, signed, ldigits)
-	case 'U':
-		p.fmtUnicode(v)
-	case 'X':
-		p.fmt.integer(v, 16, signed, udigits)
-	default:
-		p.badVerb(verb)
-	}
-}
-
-// fmt0x64 formats a uint64 in hexadecimal and prefixes it with 0x or
-// not, as requested, by temporarily setting the sharp flag.
-func (p *pp) fmt0x64(v uint64, leading0x bool) {
-	sharp := p.fmt.sharp
-	p.fmt.sharp = leading0x
-	p.fmt.integer(int64(v), 16, unsigned, ldigits)
-	p.fmt.sharp = sharp
-}
-
-// fmtUnicode formats a uint64 in U+1234 form by
-// temporarily turning on the unicode flag and tweaking the precision.
-func (p *pp) fmtUnicode(v int64) {
-	precPresent := p.fmt.precPresent
-	sharp := p.fmt.sharp
-	p.fmt.sharp = false
-	prec := p.fmt.prec
-	if !precPresent {
-		// If prec is already set, leave it alone; otherwise 4 is minimum.
-		p.fmt.prec = 4
-		p.fmt.precPresent = true
-	}
-	p.fmt.unicode = true // turn on U+
-	p.fmt.uniQuote = sharp
-	p.fmt.integer(int64(v), 16, unsigned, udigits)
-	p.fmt.unicode = false
-	p.fmt.uniQuote = false
-	p.fmt.prec = prec
-	p.fmt.precPresent = precPresent
-	p.fmt.sharp = sharp
-}
-
-func (p *pp) fmtUint64(v uint64, verb rune, goSyntax bool) {
-	switch verb {
-	case 'b':
-		p.fmt.integer(int64(v), 2, unsigned, ldigits)
-	case 'c':
-		p.fmtC(int64(v))
-	case 'd':
-		p.fmt.integer(int64(v), 10, unsigned, ldigits)
-	case 'v':
-		if goSyntax {
-			p.fmt0x64(v, true)
-		} else {
-			p.fmt.integer(int64(v), 10, unsigned, ldigits)
-		}
-	case 'o':
-		p.fmt.integer(int64(v), 8, unsigned, ldigits)
-	case 'q':
-		if 0 <= v && v <= utf8.MaxRune {
-			p.fmt.fmt_qc(int64(v))
-		} else {
-			p.badVerb(verb)
-		}
-	case 'x':
-		p.fmt.integer(int64(v), 16, unsigned, ldigits)
-	case 'X':
-		p.fmt.integer(int64(v), 16, unsigned, udigits)
-	case 'U':
-		p.fmtUnicode(int64(v))
-	default:
-		p.badVerb(verb)
-	}
-}
-
-func (p *pp) fmtFloat32(v float32, verb rune) {
-	switch verb {
-	case 'b':
-		p.fmt.fmt_fb32(v)
-	case 'e':
-		p.fmt.fmt_e32(v)
-	case 'E':
-		p.fmt.fmt_E32(v)
-	case 'f', 'F':
-		p.fmt.fmt_f32(v)
-	case 'g', 'v':
-		p.fmt.fmt_g32(v)
-	case 'G':
-		p.fmt.fmt_G32(v)
-	default:
-		p.badVerb(verb)
-	}
-}
-
-func (p *pp) fmtFloat64(v float64, verb rune) {
-	switch verb {
-	case 'b':
-		p.fmt.fmt_fb64(v)
-	case 'e':
-		p.fmt.fmt_e64(v)
-	case 'E':
-		p.fmt.fmt_E64(v)
-	case 'f', 'F':
-		p.fmt.fmt_f64(v)
-	case 'g', 'v':
-		p.fmt.fmt_g64(v)
-	case 'G':
-		p.fmt.fmt_G64(v)
-	default:
-		p.badVerb(verb)
-	}
-}
-
-func (p *pp) fmtComplex64(v complex64, verb rune) {
-	switch verb {
-	case 'b', 'e', 'E', 'f', 'F', 'g', 'G':
-		p.fmt.fmt_c64(v, verb)
-	case 'v':
-		p.fmt.fmt_c64(v, 'g')
-	default:
-		p.badVerb(verb)
-	}
-}
-
-func (p *pp) fmtComplex128(v complex128, verb rune) {
-	switch verb {
-	case 'b', 'e', 'E', 'f', 'F', 'g', 'G':
-		p.fmt.fmt_c128(v, verb)
-	case 'v':
-		p.fmt.fmt_c128(v, 'g')
-	default:
-		p.badVerb(verb)
-	}
-}
-
-func (p *pp) fmtString(v string, verb rune, goSyntax bool) {
-	switch verb {
-	case 'v':
-		if goSyntax {
-			p.fmt.fmt_q(v)
-		} else {
-			p.fmt.fmt_s(v)
-		}
-	case 's':
-		p.fmt.fmt_s(v)
-	case 'x':
-		p.fmt.fmt_sx(v, ldigits)
-	case 'X':
-		p.fmt.fmt_sx(v, udigits)
-	case 'q':
-		p.fmt.fmt_q(v)
-	default:
-		p.badVerb(verb)
-	}
-}
-
-func (p *pp) fmtBytes(v []byte, verb rune, goSyntax bool, typ reflect.Type, depth int) {
-	if verb == 'v' || verb == 'd' {
-		if goSyntax {
-			if v == nil {
-				if typ == nil {
-					p.buf.WriteString("[]byte(nil)")
-				} else {
-					p.buf.WriteString(typ.String())
-					p.buf.Write(nilParenBytes)
-				}
-				return
-			}
-			if typ == nil {
-				p.buf.Write(bytesBytes)
-			} else {
-				p.buf.WriteString(typ.String())
-				p.buf.WriteByte('{')
-			}
-		} else {
-			p.buf.WriteByte('[')
-		}
-		for i, c := range v {
-			if i > 0 {
-				if goSyntax {
-					p.buf.Write(commaSpaceBytes)
-				} else {
-					p.buf.WriteByte(' ')
-				}
-			}
-			p.printArg(c, 'v', p.fmt.plus, goSyntax, depth+1)
-		}
-		if goSyntax {
-			p.buf.WriteByte('}')
-		} else {
-			p.buf.WriteByte(']')
-		}
-		return
-	}
-	switch verb {
-	case 's':
-		p.fmt.fmt_s(string(v))
-	case 'x':
-		p.fmt.fmt_bx(v, ldigits)
-	case 'X':
-		p.fmt.fmt_bx(v, udigits)
-	case 'q':
-		p.fmt.fmt_q(string(v))
-	default:
-		p.badVerb(verb)
-	}
-}
-
-func (p *pp) fmtPointer(value reflect.Value, verb rune, goSyntax bool) {
-	use0x64 := true
-	switch verb {
-	case 'p', 'v':
-		// ok
-	case 'b', 'd', 'o', 'x', 'X':
-		use0x64 = false
-		// ok
-	default:
-		p.badVerb(verb)
-		return
-	}
-
-	var u uintptr
-	switch value.Kind() {
-	case reflect.Chan, reflect.Func, reflect.Map, reflect.Ptr, reflect.Slice, reflect.UnsafePointer:
-		u = value.Pointer()
-	default:
-		p.badVerb(verb)
-		return
-	}
-
-	if goSyntax {
-		p.add('(')
-		p.buf.WriteString(value.Type().String())
-		p.add(')')
-		p.add('(')
-		if u == 0 {
-			p.buf.Write(nilBytes)
-		} else {
-			p.fmt0x64(uint64(u), true)
-		}
-		p.add(')')
-	} else if verb == 'v' && u == 0 {
-		p.buf.Write(nilAngleBytes)
-	} else {
-		if use0x64 {
-			p.fmt0x64(uint64(u), !p.fmt.sharp)
-		} else {
-			p.fmtUint64(uint64(u), verb, false)
-		}
-	}
-}
-
-var (
-	intBits     = reflect.TypeOf(0).Bits()
-	uintptrBits = reflect.TypeOf(uintptr(0)).Bits()
-)
-
-func (p *pp) catchPanic(arg interface{}, verb rune) {
-	if err := recover(); err != nil {
-		// If it's a nil pointer, just say "<nil>". The likeliest causes are a
-		// Stringer that fails to guard against nil or a nil pointer for a
-		// value receiver, and in either case, "<nil>" is a nice result.
-		if v := reflect.ValueOf(arg); v.Kind() == reflect.Ptr && v.IsNil() {
-			p.buf.Write(nilAngleBytes)
-			return
-		}
-		// Otherwise print a concise panic message. Most of the time the panic
-		// value will print itself nicely.
-		if p.panicking {
-			// Nested panics; the recursion in printArg cannot succeed.
-			panic(err)
-		}
-		p.buf.Write(percentBangBytes)
-		p.add(verb)
-		p.buf.Write(panicBytes)
-		p.panicking = true
-		p.printArg(err, 'v', false, false, 0)
-		p.panicking = false
-		p.buf.WriteByte(')')
-	}
-}
-
-func (p *pp) handleMethods(verb rune, plus, goSyntax bool, depth int) (wasString, handled bool) {
-	if p.erroring {
-		return
-	}
-	// Is it a Formatter?
-	if formatter, ok := p.arg.(Formatter); ok {
-		handled = true
-		wasString = false
-		defer p.catchPanic(p.arg, verb)
-		formatter.Format(p, verb)
-		return
-	}
-	// Must not touch flags before Formatter looks at them.
-	if plus {
-		p.fmt.plus = false
-	}
-
-	// If we're doing Go syntax and the argument knows how to supply it, take care of it now.
-	if goSyntax {
-		p.fmt.sharp = false
-		if stringer, ok := p.arg.(GoStringer); ok {
-			wasString = false
-			handled = true
-			defer p.catchPanic(p.arg, verb)
-			// Print the result of GoString unadorned.
-			p.fmtString(stringer.GoString(), 's', false)
-			return
-		}
-	} else {
-		// If a string is acceptable according to the format, see if
-		// the value satisfies one of the string-valued interfaces.
-		// Println etc. set verb to %v, which is "stringable".
-		switch verb {
-		case 'v', 's', 'x', 'X', 'q':
-			// Is it an error or Stringer?
-			// The duplication in the bodies is necessary:
-			// setting wasString and handled, and deferring catchPanic,
-			// must happen before calling the method.
-			switch v := p.arg.(type) {
-			case error:
-				wasString = false
-				handled = true
-				defer p.catchPanic(p.arg, verb)
-				p.printArg(v.Error(), verb, plus, false, depth)
-				return
-
-			case Stringer:
-				wasString = false
-				handled = true
-				defer p.catchPanic(p.arg, verb)
-				p.printArg(v.String(), verb, plus, false, depth)
-				return
-			}
-		}
-	}
-	handled = false
-	return
-}
-
-func (p *pp) printArg(arg interface{}, verb rune, plus, goSyntax bool, depth int) (wasString bool) {
-	p.arg = arg
-	p.value = reflect.Value{}
-
-	if arg == nil {
-		if verb == 'T' || verb == 'v' {
-			p.fmt.pad(nilAngleBytes)
-		} else {
-			p.badVerb(verb)
-		}
-		return false
-	}
-
-	// Special processing considerations.
-	// %T (the value's type) and %p (its address) are special; we always do them first.
-	switch verb {
-	case 'T':
-		p.printArg(reflect.TypeOf(arg).String(), 's', false, false, 0)
-		return false
-	case 'p':
-		p.fmtPointer(reflect.ValueOf(arg), verb, goSyntax)
-		return false
-	}
-
-	// Clear flags for base formatters.
-	// handleMethods needs them, so we must restore them later.
-	// We could call handleMethods here and avoid this work, but
-	// handleMethods is expensive enough to be worth delaying.
-	oldPlus := p.fmt.plus
-	oldSharp := p.fmt.sharp
-	if plus {
-		p.fmt.plus = false
-	}
-	if goSyntax {
-		p.fmt.sharp = false
-	}
-
-	// Some types can be done without reflection.
-	switch f := arg.(type) {
-	case bool:
-		p.fmtBool(f, verb)
-	case float32:
-		p.fmtFloat32(f, verb)
-	case float64:
-		p.fmtFloat64(f, verb)
-	case complex64:
-		p.fmtComplex64(f, verb)
-	case complex128:
-		p.fmtComplex128(f, verb)
-	case int:
-		p.fmtInt64(int64(f), verb)
-	case int8:
-		p.fmtInt64(int64(f), verb)
-	case int16:
-		p.fmtInt64(int64(f), verb)
-	case int32:
-		p.fmtInt64(int64(f), verb)
-	case int64:
-		p.fmtInt64(f, verb)
-	case uint:
-		p.fmtUint64(uint64(f), verb, goSyntax)
-	case uint8:
-		p.fmtUint64(uint64(f), verb, goSyntax)
-	case uint16:
-		p.fmtUint64(uint64(f), verb, goSyntax)
-	case uint32:
-		p.fmtUint64(uint64(f), verb, goSyntax)
-	case uint64:
-		p.fmtUint64(f, verb, goSyntax)
-	case uintptr:
-		p.fmtUint64(uint64(f), verb, goSyntax)
-	case string:
-		p.fmtString(f, verb, goSyntax)
-		wasString = verb == 's' || verb == 'v'
-	case []byte:
-		p.fmtBytes(f, verb, goSyntax, nil, depth)
-		wasString = verb == 's'
-	default:
-		// Restore flags in case handleMethods finds a Formatter.
-		p.fmt.plus = oldPlus
-		p.fmt.sharp = oldSharp
-		// If the type is not simple, it might have methods.
-		if isString, handled := p.handleMethods(verb, plus, goSyntax, depth); handled {
-			return isString
-		}
-		// Need to use reflection
-		return p.printReflectValue(reflect.ValueOf(arg), verb, plus, goSyntax, depth)
-	}
-	p.arg = nil
-	return
-}
-
-// printValue is like printArg but starts with a reflect value, not an interface{} value.
-func (p *pp) printValue(value reflect.Value, verb rune, plus, goSyntax bool, depth int) (wasString bool) {
-	if !value.IsValid() {
-		if verb == 'T' || verb == 'v' {
-			p.buf.Write(nilAngleBytes)
-		} else {
-			p.badVerb(verb)
-		}
-		return false
-	}
-
-	// Special processing considerations.
-	// %T (the value's type) and %p (its address) are special; we always do them first.
-	switch verb {
-	case 'T':
-		p.printArg(value.Type().String(), 's', false, false, 0)
-		return false
-	case 'p':
-		p.fmtPointer(value, verb, goSyntax)
-		return false
-	}
-
-	// Handle values with special methods.
-	// Call always, even when arg == nil, because handleMethods clears p.fmt.plus for us.
-	p.arg = nil // Make sure it's cleared, for safety.
-	if value.CanInterface() {
-		p.arg = value.Interface()
-	}
-	if isString, handled := p.handleMethods(verb, plus, goSyntax, depth); handled {
-		return isString
-	}
-
-	return p.printReflectValue(value, verb, plus, goSyntax, depth)
-}
-
-// printReflectValue is the fallback for both printArg and printValue.
-// It uses reflect to print the value.
-func (p *pp) printReflectValue(value reflect.Value, verb rune, plus, goSyntax bool, depth int) (wasString bool) {
-	oldValue := p.value
-	p.value = value
-BigSwitch:
-	switch f := value; f.Kind() {
-	case reflect.Bool:
-		p.fmtBool(f.Bool(), verb)
-	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-		p.fmtInt64(f.Int(), verb)
-	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
-		p.fmtUint64(f.Uint(), verb, goSyntax)
-	case reflect.Float32, reflect.Float64:
-		if f.Type().Size() == 4 {
-			p.fmtFloat32(float32(f.Float()), verb)
-		} else {
-			p.fmtFloat64(f.Float(), verb)
-		}
-	case reflect.Complex64, reflect.Complex128:
-		if f.Type().Size() == 8 {
-			p.fmtComplex64(complex64(f.Complex()), verb)
-		} else {
-			p.fmtComplex128(f.Complex(), verb)
-		}
-	case reflect.String:
-		p.fmtString(f.String(), verb, goSyntax)
-	case reflect.Map:
-		if goSyntax {
-			p.buf.WriteString(f.Type().String())
-			if f.IsNil() {
-				p.buf.WriteString("(nil)")
-				break
-			}
-			p.buf.WriteByte('{')
-		} else {
-			p.buf.Write(mapBytes)
-		}
-		keys := f.MapKeys()
-		for i, key := range keys {
-			if i > 0 {
-				if goSyntax {
-					p.buf.Write(commaSpaceBytes)
-				} else {
-					p.buf.WriteByte(' ')
-				}
-			}
-			p.printValue(key, verb, plus, goSyntax, depth+1)
-			p.buf.WriteByte(':')
-			p.printValue(f.MapIndex(key), verb, plus, goSyntax, depth+1)
-		}
-		if goSyntax {
-			p.buf.WriteByte('}')
-		} else {
-			p.buf.WriteByte(']')
-		}
-	case reflect.Struct:
-		if goSyntax {
-			p.buf.WriteString(value.Type().String())
-		}
-		p.add('{')
-		v := f
-		t := v.Type()
-		for i := 0; i < v.NumField(); i++ {
-			if i > 0 {
-				if goSyntax {
-					p.buf.Write(commaSpaceBytes)
-				} else {
-					p.buf.WriteByte(' ')
-				}
-			}
-			if plus || goSyntax {
-				if f := t.Field(i); f.Name != "" {
-					p.buf.WriteString(f.Name)
-					p.buf.WriteByte(':')
-				}
-			}
-			p.printValue(getField(v, i), verb, plus, goSyntax, depth+1)
-		}
-		p.buf.WriteByte('}')
-	case reflect.Interface:
-		value := f.Elem()
-		if !value.IsValid() {
-			if goSyntax {
-				p.buf.WriteString(f.Type().String())
-				p.buf.Write(nilParenBytes)
-			} else {
-				p.buf.Write(nilAngleBytes)
-			}
-		} else {
-			wasString = p.printValue(value, verb, plus, goSyntax, depth+1)
-		}
-	case reflect.Array, reflect.Slice:
-		// Byte slices are special.
-		if typ := f.Type(); typ.Elem().Kind() == reflect.Uint8 {
-			var bytes []byte
-			if f.Kind() == reflect.Slice {
-				bytes = f.Bytes()
-			} else if f.CanAddr() {
-				bytes = f.Slice(0, f.Len()).Bytes()
-			} else {
-				// We have an array, but we cannot Slice() a non-addressable array,
-				// so we build a slice by hand. This is a rare case but it would be nice
-				// if reflection could help a little more.
-				bytes = make([]byte, f.Len())
-				for i := range bytes {
-					bytes[i] = byte(f.Index(i).Uint())
-				}
-			}
-			p.fmtBytes(bytes, verb, goSyntax, typ, depth)
-			wasString = verb == 's'
-			break
-		}
-		if goSyntax {
-			p.buf.WriteString(value.Type().String())
-			if f.Kind() == reflect.Slice && f.IsNil() {
-				p.buf.WriteString("(nil)")
-				break
-			}
-			p.buf.WriteByte('{')
-		} else {
-			p.buf.WriteByte('[')
-		}
-		for i := 0; i < f.Len(); i++ {
-			if i > 0 {
-				if goSyntax {
-					p.buf.Write(commaSpaceBytes)
-				} else {
-					p.buf.WriteByte(' ')
-				}
-			}
-			p.printValue(f.Index(i), verb, plus, goSyntax, depth+1)
-		}
-		if goSyntax {
-			p.buf.WriteByte('}')
-		} else {
-			p.buf.WriteByte(']')
-		}
-	case reflect.Ptr:
-		v := f.Pointer()
-		// pointer to array or slice or struct?  ok at top level
-		// but not embedded (avoid loops)
-		if v != 0 && depth == 0 {
-			switch a := f.Elem(); a.Kind() {
-			case reflect.Array, reflect.Slice:
-				p.buf.WriteByte('&')
-				p.printValue(a, verb, plus, goSyntax, depth+1)
-				break BigSwitch
-			case reflect.Struct:
-				p.buf.WriteByte('&')
-				p.printValue(a, verb, plus, goSyntax, depth+1)
-				break BigSwitch
-			}
-		}
-		fallthrough
-	case reflect.Chan, reflect.Func, reflect.UnsafePointer:
-		p.fmtPointer(value, verb, goSyntax)
-	default:
-		p.unknownType(f)
-	}
-	p.value = oldValue
-	return wasString
-}
-
-// intFromArg gets the argNumth element of a. On return, isInt reports whether the argument has type int.
-func intFromArg(a []interface{}, argNum int) (num int, isInt bool, newArgNum int) {
-	newArgNum = argNum
-	if argNum < len(a) {
-		num, isInt = a[argNum].(int)
-		newArgNum = argNum + 1
-	}
-	return
-}
-
-// parseArgNumber returns the value of the bracketed number, minus 1
-// (explicit argument numbers are one-indexed but we want zero-indexed).
-// The opening bracket is known to be present at format[0].
-// The returned values are the index, the number of bytes to consume
-// up to the closing paren, if present, and whether the number parsed
-// ok. The bytes to consume will be 1 if no closing paren is present.
-func parseArgNumber(format string) (index int, wid int, ok bool) {
-	// Find closing bracket.
-	for i := 1; i < len(format); i++ {
-		if format[i] == ']' {
-			width, ok, newi := parsenum(format, 1, i)
-			if !ok || newi != i {
-				return 0, i + 1, false
-			}
-			return width - 1, i + 1, true // arg numbers are one-indexed and skip paren.
-		}
-	}
-	return 0, 1, false
-}
-
-// argNumber returns the next argument to evaluate, which is either the value of the passed-in
-// argNum or the value of the bracketed integer that begins format[i:]. It also returns
-// the new value of i, that is, the index of the next byte of the format to process.
-func (p *pp) argNumber(argNum int, format string, i int, numArgs int) (newArgNum, newi int, found bool) {
-	if len(format) <= i || format[i] != '[' {
-		return argNum, i, false
-	}
-	p.reordered = true
-	index, wid, ok := parseArgNumber(format[i:])
-	if ok && 0 <= index && index < numArgs {
-		return index, i + wid, true
-	}
-	p.goodArgNum = false
-	return argNum, i + wid, true
-}
-
-func (p *pp) doPrintf(format string, a []interface{}) {
-	end := len(format)
-	argNum := 0         // we process one argument per non-trivial format
-	afterIndex := false // previous item in format was an index like [3].
-	p.reordered = false
-	for i := 0; i < end; {
-		p.goodArgNum = true
-		lasti := i
-		for i < end && format[i] != '%' {
-			i++
-		}
-		if i > lasti {
-			p.buf.WriteString(format[lasti:i])
-		}
-		if i >= end {
-			// done processing format string
-			break
-		}
-
-		// Process one verb
-		i++
-
-		// Do we have flags?
-		p.fmt.clearflags()
-	F:
-		for ; i < end; i++ {
-			switch format[i] {
-			case '#':
-				p.fmt.sharp = true
-			case '0':
-				p.fmt.zero = true
-			case '+':
-				p.fmt.plus = true
-			case '-':
-				p.fmt.minus = true
-			case ' ':
-				p.fmt.space = true
-			default:
-				break F
-			}
-		}
-
-		// Do we have an explicit argument index?
-		argNum, i, afterIndex = p.argNumber(argNum, format, i, len(a))
-
-		// Do we have width?
-		if i < end && format[i] == '*' {
-			i++
-			p.fmt.wid, p.fmt.widPresent, argNum = intFromArg(a, argNum)
-			if !p.fmt.widPresent {
-				p.buf.Write(badWidthBytes)
-			}
-			afterIndex = false
-		} else {
-			p.fmt.wid, p.fmt.widPresent, i = parsenum(format, i, end)
-			if afterIndex && p.fmt.widPresent { // "%[3]2d"
-				p.goodArgNum = false
-			}
-		}
-
-		// Do we have precision?
-		if i+1 < end && format[i] == '.' {
-			i++
-			if afterIndex { // "%[3].2d"
-				p.goodArgNum = false
-			}
-			argNum, i, afterIndex = p.argNumber(argNum, format, i, len(a))
-			if format[i] == '*' {
-				i++
-				p.fmt.prec, p.fmt.precPresent, argNum = intFromArg(a, argNum)
-				if !p.fmt.precPresent {
-					p.buf.Write(badPrecBytes)
-				}
-				afterIndex = false
-			} else {
-				p.fmt.prec, p.fmt.precPresent, i = parsenum(format, i, end)
-				if !p.fmt.precPresent {
-					p.fmt.prec = 0
-					p.fmt.precPresent = true
-				}
-			}
-		}
-
-		if !afterIndex {
-			argNum, i, afterIndex = p.argNumber(argNum, format, i, len(a))
-		}
-
-		if i >= end {
-			p.buf.Write(noVerbBytes)
-			continue
-		}
-		c, w := utf8.DecodeRuneInString(format[i:])
-		i += w
-		// percent is special - absorbs no operand
-		if c == '%' {
-			p.buf.WriteByte('%') // We ignore width and prec.
-			continue
-		}
-		if !p.goodArgNum {
-			p.buf.Write(percentBangBytes)
-			p.add(c)
-			p.buf.Write(badIndexBytes)
-			continue
-		} else if argNum >= len(a) { // out of operands
-			p.buf.Write(percentBangBytes)
-			p.add(c)
-			p.buf.Write(missingBytes)
-			continue
-		}
-		arg := a[argNum]
-		argNum++
-
-		goSyntax := c == 'v' && p.fmt.sharp
-		plus := c == 'v' && p.fmt.plus
-		p.printArg(arg, c, plus, goSyntax, 0)
-	}
-
-	// Check for extra arguments unless the call accessed the arguments
-	// out of order, in which case it's too expensive to detect if they've all
-	// been used and arguably OK if they're not.
-	if !p.reordered && argNum < len(a) {
-		p.buf.Write(extraBytes)
-		for ; argNum < len(a); argNum++ {
-			arg := a[argNum]
-			if arg != nil {
-				p.buf.WriteString(reflect.TypeOf(arg).String())
-				p.buf.WriteByte('=')
-			}
-			p.printArg(arg, 'v', false, false, 0)
-			if argNum+1 < len(a) {
-				p.buf.Write(commaSpaceBytes)
-			}
-		}
-		p.buf.WriteByte(')')
-	}
-}
-
-func (p *pp) doPrint(a []interface{}, addspace, addnewline bool) {
-	prevString := false
-	for argNum := 0; argNum < len(a); argNum++ {
-		p.fmt.clearflags()
-		// always add spaces if we're doing Println
-		arg := a[argNum]
-		if argNum > 0 {
-			isString := arg != nil && reflect.TypeOf(arg).Kind() == reflect.String
-			if addspace || !isString && !prevString {
-				p.buf.WriteByte(' ')
-			}
-		}
-		prevString = p.printArg(arg, 'v', false, false, 0)
-	}
-	if addnewline {
-		p.buf.WriteByte('\n')
-	}
-}
diff --git a/src/pkg/fmt/scan.go b/src/pkg/fmt/scan.go
deleted file mode 100644
index 8a337e4..0000000
--- a/src/pkg/fmt/scan.go
+++ /dev/null
@@ -1,1168 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package fmt
-
-import (
-	"errors"
-	"io"
-	"math"
-	"os"
-	"reflect"
-	"strconv"
-	"sync"
-	"unicode/utf8"
-)
-
-// runeUnreader is the interface to something that can unread runes.
-// If the object provided to Scan does not satisfy this interface,
-// a local buffer will be used to back up the input, but its contents
-// will be lost when Scan returns.
-type runeUnreader interface {
-	UnreadRune() error
-}
-
-// ScanState represents the scanner state passed to custom scanners.
-// Scanners may do rune-at-a-time scanning or ask the ScanState
-// to discover the next space-delimited token.
-type ScanState interface {
-	// ReadRune reads the next rune (Unicode code point) from the input.
-	// If invoked during Scanln, Fscanln, or Sscanln, ReadRune() will
-	// return EOF after returning the first '\n' or when reading beyond
-	// the specified width.
-	ReadRune() (r rune, size int, err error)
-	// UnreadRune causes the next call to ReadRune to return the same rune.
-	UnreadRune() error
-	// SkipSpace skips space in the input. Newlines are treated as space
-	// unless the scan operation is Scanln, Fscanln or Sscanln, in which case
-	// a newline is treated as EOF.
-	SkipSpace()
-	// Token skips space in the input if skipSpace is true, then returns the
-	// run of Unicode code points c satisfying f(c).  If f is nil,
-	// !unicode.IsSpace(c) is used; that is, the token will hold non-space
-	// characters.  Newlines are treated as space unless the scan operation
-	// is Scanln, Fscanln or Sscanln, in which case a newline is treated as
-	// EOF.  The returned slice points to shared data that may be overwritten
-	// by the next call to Token, a call to a Scan function using the ScanState
-	// as input, or when the calling Scan method returns.
-	Token(skipSpace bool, f func(rune) bool) (token []byte, err error)
-	// Width returns the value of the width option and whether it has been set.
-	// The unit is Unicode code points.
-	Width() (wid int, ok bool)
-	// Because ReadRune is implemented by the interface, Read should never be
-	// called by the scanning routines and a valid implementation of
-	// ScanState may choose always to return an error from Read.
-	Read(buf []byte) (n int, err error)
-}
-
-// Scanner is implemented by any value that has a Scan method, which scans
-// the input for the representation of a value and stores the result in the
-// receiver, which must be a pointer to be useful.  The Scan method is called
-// for any argument to Scan, Scanf, or Scanln that implements it.
-type Scanner interface {
-	Scan(state ScanState, verb rune) error
-}
-
-// Scan scans text read from standard input, storing successive
-// space-separated values into successive arguments.  Newlines count
-// as space.  It returns the number of items successfully scanned.
-// If that is less than the number of arguments, err will report why.
-func Scan(a ...interface{}) (n int, err error) {
-	return Fscan(os.Stdin, a...)
-}
-
-// Scanln is similar to Scan, but stops scanning at a newline and
-// after the final item there must be a newline or EOF.
-func Scanln(a ...interface{}) (n int, err error) {
-	return Fscanln(os.Stdin, a...)
-}
-
-// Scanf scans text read from standard input, storing successive
-// space-separated values into successive arguments as determined by
-// the format.  It returns the number of items successfully scanned.
-func Scanf(format string, a ...interface{}) (n int, err error) {
-	return Fscanf(os.Stdin, format, a...)
-}
-
-type stringReader string
-
-func (r *stringReader) Read(b []byte) (n int, err error) {
-	n = copy(b, *r)
-	*r = (*r)[n:]
-	if n == 0 {
-		err = io.EOF
-	}
-	return
-}
-
-// Sscan scans the argument string, storing successive space-separated
-// values into successive arguments.  Newlines count as space.  It
-// returns the number of items successfully scanned.  If that is less
-// than the number of arguments, err will report why.
-func Sscan(str string, a ...interface{}) (n int, err error) {
-	return Fscan((*stringReader)(&str), a...)
-}
-
-// Sscanln is similar to Sscan, but stops scanning at a newline and
-// after the final item there must be a newline or EOF.
-func Sscanln(str string, a ...interface{}) (n int, err error) {
-	return Fscanln((*stringReader)(&str), a...)
-}
-
-// Sscanf scans the argument string, storing successive space-separated
-// values into successive arguments as determined by the format.  It
-// returns the number of items successfully parsed.
-func Sscanf(str string, format string, a ...interface{}) (n int, err error) {
-	return Fscanf((*stringReader)(&str), format, a...)
-}
-
-// Fscan scans text read from r, storing successive space-separated
-// values into successive arguments.  Newlines count as space.  It
-// returns the number of items successfully scanned.  If that is less
-// than the number of arguments, err will report why.
-func Fscan(r io.Reader, a ...interface{}) (n int, err error) {
-	s, old := newScanState(r, true, false)
-	n, err = s.doScan(a)
-	s.free(old)
-	return
-}
-
-// Fscanln is similar to Fscan, but stops scanning at a newline and
-// after the final item there must be a newline or EOF.
-func Fscanln(r io.Reader, a ...interface{}) (n int, err error) {
-	s, old := newScanState(r, false, true)
-	n, err = s.doScan(a)
-	s.free(old)
-	return
-}
-
-// Fscanf scans text read from r, storing successive space-separated
-// values into successive arguments as determined by the format.  It
-// returns the number of items successfully parsed.
-func Fscanf(r io.Reader, format string, a ...interface{}) (n int, err error) {
-	s, old := newScanState(r, false, false)
-	n, err = s.doScanf(format, a)
-	s.free(old)
-	return
-}
-
-// scanError represents an error generated by the scanning software.
-// It's used as a unique signature to identify such errors when recovering.
-type scanError struct {
-	err error
-}
-
-const eof = -1
-
-// ss is the internal implementation of ScanState.
-type ss struct {
-	rr       io.RuneReader // where to read input
-	buf      buffer        // token accumulator
-	peekRune rune          // one-rune lookahead
-	prevRune rune          // last rune returned by ReadRune
-	count    int           // runes consumed so far.
-	atEOF    bool          // already read EOF
-	ssave
-}
-
-// ssave holds the parts of ss that need to be
-// saved and restored on recursive scans.
-type ssave struct {
-	validSave bool // is or was a part of an actual ss.
-	nlIsEnd   bool // whether newline terminates scan
-	nlIsSpace bool // whether newline counts as white space
-	argLimit  int  // max value of ss.count for this arg; argLimit <= limit
-	limit     int  // max value of ss.count.
-	maxWid    int  // width of this arg.
-}
-
-// The Read method is only in ScanState so that ScanState
-// satisfies io.Reader. It will never be called when used as
-// intended, so there is no need to make it actually work.
-func (s *ss) Read(buf []byte) (n int, err error) {
-	return 0, errors.New("ScanState's Read should not be called. Use ReadRune")
-}
-
-func (s *ss) ReadRune() (r rune, size int, err error) {
-	if s.peekRune >= 0 {
-		s.count++
-		r = s.peekRune
-		size = utf8.RuneLen(r)
-		s.prevRune = r
-		s.peekRune = -1
-		return
-	}
-	if s.atEOF || s.nlIsEnd && s.prevRune == '\n' || s.count >= s.argLimit {
-		err = io.EOF
-		return
-	}
-
-	r, size, err = s.rr.ReadRune()
-	if err == nil {
-		s.count++
-		s.prevRune = r
-	} else if err == io.EOF {
-		s.atEOF = true
-	}
-	return
-}
-
-func (s *ss) Width() (wid int, ok bool) {
-	if s.maxWid == hugeWid {
-		return 0, false
-	}
-	return s.maxWid, true
-}
-
-// The public method returns an error; this private one panics.
-// If getRune reaches EOF, the return value is EOF (-1).
-func (s *ss) getRune() (r rune) {
-	r, _, err := s.ReadRune()
-	if err != nil {
-		if err == io.EOF {
-			return eof
-		}
-		s.error(err)
-	}
-	return
-}
-
-// mustReadRune turns io.EOF into a panic(io.ErrUnexpectedEOF).
-// It is called in cases such as string scanning where an EOF is a
-// syntax error.
-func (s *ss) mustReadRune() (r rune) {
-	r = s.getRune()
-	if r == eof {
-		s.error(io.ErrUnexpectedEOF)
-	}
-	return
-}
-
-func (s *ss) UnreadRune() error {
-	if u, ok := s.rr.(runeUnreader); ok {
-		u.UnreadRune()
-	} else {
-		s.peekRune = s.prevRune
-	}
-	s.prevRune = -1
-	s.count--
-	return nil
-}
-
-func (s *ss) error(err error) {
-	panic(scanError{err})
-}
-
-func (s *ss) errorString(err string) {
-	panic(scanError{errors.New(err)})
-}
-
-func (s *ss) Token(skipSpace bool, f func(rune) bool) (tok []byte, err error) {
-	defer func() {
-		if e := recover(); e != nil {
-			if se, ok := e.(scanError); ok {
-				err = se.err
-			} else {
-				panic(e)
-			}
-		}
-	}()
-	if f == nil {
-		f = notSpace
-	}
-	s.buf = s.buf[:0]
-	tok = s.token(skipSpace, f)
-	return
-}
-
-// space is a copy of the unicode.White_Space ranges,
-// to avoid depending on package unicode.
-var space = [][2]uint16{
-	{0x0009, 0x000d},
-	{0x0020, 0x0020},
-	{0x0085, 0x0085},
-	{0x00a0, 0x00a0},
-	{0x1680, 0x1680},
-	{0x2000, 0x200a},
-	{0x2028, 0x2029},
-	{0x202f, 0x202f},
-	{0x205f, 0x205f},
-	{0x3000, 0x3000},
-}
-
-func isSpace(r rune) bool {
-	if r >= 1<<16 {
-		return false
-	}
-	rx := uint16(r)
-	for _, rng := range space {
-		if rx < rng[0] {
-			return false
-		}
-		if rx <= rng[1] {
-			return true
-		}
-	}
-	return false
-}
-
-// notSpace is the default scanning function used in Token.
-func notSpace(r rune) bool {
-	return !isSpace(r)
-}
-
-// SkipSpace provides Scan methods the ability to skip space and newline
-// characters in keeping with the current scanning mode set by format strings
-// and Scan/Scanln.
-func (s *ss) SkipSpace() {
-	s.skipSpace(false)
-}
-
-// readRune is a structure to enable reading UTF-8 encoded code points
-// from an io.Reader.  It is used if the Reader given to the scanner does
-// not already implement io.RuneReader.
-type readRune struct {
-	reader  io.Reader
-	buf     [utf8.UTFMax]byte // used only inside ReadRune
-	pending int               // number of bytes in pendBuf; only >0 for bad UTF-8
-	pendBuf [utf8.UTFMax]byte // bytes left over
-}
-
-// readByte returns the next byte from the input, which may be
-// left over from a previous read if the UTF-8 was ill-formed.
-func (r *readRune) readByte() (b byte, err error) {
-	if r.pending > 0 {
-		b = r.pendBuf[0]
-		copy(r.pendBuf[0:], r.pendBuf[1:])
-		r.pending--
-		return
-	}
-	n, err := io.ReadFull(r.reader, r.pendBuf[0:1])
-	if n != 1 {
-		return 0, err
-	}
-	return r.pendBuf[0], err
-}
-
-// unread saves the bytes for the next read.
-func (r *readRune) unread(buf []byte) {
-	copy(r.pendBuf[r.pending:], buf)
-	r.pending += len(buf)
-}
-
-// ReadRune returns the next UTF-8 encoded code point from the
-// io.Reader inside r.
-func (r *readRune) ReadRune() (rr rune, size int, err error) {
-	r.buf[0], err = r.readByte()
-	if err != nil {
-		return 0, 0, err
-	}
-	if r.buf[0] < utf8.RuneSelf { // fast check for common ASCII case
-		rr = rune(r.buf[0])
-		return
-	}
-	var n int
-	for n = 1; !utf8.FullRune(r.buf[0:n]); n++ {
-		r.buf[n], err = r.readByte()
-		if err != nil {
-			if err == io.EOF {
-				err = nil
-				break
-			}
-			return
-		}
-	}
-	rr, size = utf8.DecodeRune(r.buf[0:n])
-	if size < n { // an error
-		r.unread(r.buf[size:n])
-	}
-	return
-}
-
-var ssFree = sync.Pool{
-	New: func() interface{} { return new(ss) },
-}
-
-// newScanState allocates a new ss struct or grab a cached one.
-func newScanState(r io.Reader, nlIsSpace, nlIsEnd bool) (s *ss, old ssave) {
-	// If the reader is a *ss, then we've got a recursive
-	// call to Scan, so re-use the scan state.
-	s, ok := r.(*ss)
-	if ok {
-		old = s.ssave
-		s.limit = s.argLimit
-		s.nlIsEnd = nlIsEnd || s.nlIsEnd
-		s.nlIsSpace = nlIsSpace
-		return
-	}
-
-	s = ssFree.Get().(*ss)
-	if rr, ok := r.(io.RuneReader); ok {
-		s.rr = rr
-	} else {
-		s.rr = &readRune{reader: r}
-	}
-	s.nlIsSpace = nlIsSpace
-	s.nlIsEnd = nlIsEnd
-	s.prevRune = -1
-	s.peekRune = -1
-	s.atEOF = false
-	s.limit = hugeWid
-	s.argLimit = hugeWid
-	s.maxWid = hugeWid
-	s.validSave = true
-	s.count = 0
-	return
-}
-
-// free saves used ss structs in ssFree; avoid an allocation per invocation.
-func (s *ss) free(old ssave) {
-	// If it was used recursively, just restore the old state.
-	if old.validSave {
-		s.ssave = old
-		return
-	}
-	// Don't hold on to ss structs with large buffers.
-	if cap(s.buf) > 1024 {
-		return
-	}
-	s.buf = s.buf[:0]
-	s.rr = nil
-	ssFree.Put(s)
-}
-
-// skipSpace skips spaces and maybe newlines.
-func (s *ss) skipSpace(stopAtNewline bool) {
-	for {
-		r := s.getRune()
-		if r == eof {
-			return
-		}
-		if r == '\r' && s.peek("\n") {
-			continue
-		}
-		if r == '\n' {
-			if stopAtNewline {
-				break
-			}
-			if s.nlIsSpace {
-				continue
-			}
-			s.errorString("unexpected newline")
-			return
-		}
-		if !isSpace(r) {
-			s.UnreadRune()
-			break
-		}
-	}
-}
-
-// token returns the next space-delimited string from the input.  It
-// skips white space.  For Scanln, it stops at newlines.  For Scan,
-// newlines are treated as spaces.
-func (s *ss) token(skipSpace bool, f func(rune) bool) []byte {
-	if skipSpace {
-		s.skipSpace(false)
-	}
-	// read until white space or newline
-	for {
-		r := s.getRune()
-		if r == eof {
-			break
-		}
-		if !f(r) {
-			s.UnreadRune()
-			break
-		}
-		s.buf.WriteRune(r)
-	}
-	return s.buf
-}
-
-var complexError = errors.New("syntax error scanning complex number")
-var boolError = errors.New("syntax error scanning boolean")
-
-func indexRune(s string, r rune) int {
-	for i, c := range s {
-		if c == r {
-			return i
-		}
-	}
-	return -1
-}
-
-// consume reads the next rune in the input and reports whether it is in the ok string.
-// If accept is true, it puts the character into the input token.
-func (s *ss) consume(ok string, accept bool) bool {
-	r := s.getRune()
-	if r == eof {
-		return false
-	}
-	if indexRune(ok, r) >= 0 {
-		if accept {
-			s.buf.WriteRune(r)
-		}
-		return true
-	}
-	if r != eof && accept {
-		s.UnreadRune()
-	}
-	return false
-}
-
-// peek reports whether the next character is in the ok string, without consuming it.
-func (s *ss) peek(ok string) bool {
-	r := s.getRune()
-	if r != eof {
-		s.UnreadRune()
-	}
-	return indexRune(ok, r) >= 0
-}
-
-func (s *ss) notEOF() {
-	// Guarantee there is data to be read.
-	if r := s.getRune(); r == eof {
-		panic(io.EOF)
-	}
-	s.UnreadRune()
-}
-
-// accept checks the next rune in the input.  If it's a byte (sic) in the string, it puts it in the
-// buffer and returns true. Otherwise it return false.
-func (s *ss) accept(ok string) bool {
-	return s.consume(ok, true)
-}
-
-// okVerb verifies that the verb is present in the list, setting s.err appropriately if not.
-func (s *ss) okVerb(verb rune, okVerbs, typ string) bool {
-	for _, v := range okVerbs {
-		if v == verb {
-			return true
-		}
-	}
-	s.errorString("bad verb %" + string(verb) + " for " + typ)
-	return false
-}
-
-// scanBool returns the value of the boolean represented by the next token.
-func (s *ss) scanBool(verb rune) bool {
-	s.skipSpace(false)
-	s.notEOF()
-	if !s.okVerb(verb, "tv", "boolean") {
-		return false
-	}
-	// Syntax-checking a boolean is annoying.  We're not fastidious about case.
-	switch s.getRune() {
-	case '0':
-		return false
-	case '1':
-		return true
-	case 't', 'T':
-		if s.accept("rR") && (!s.accept("uU") || !s.accept("eE")) {
-			s.error(boolError)
-		}
-		return true
-	case 'f', 'F':
-		if s.accept("aA") && (!s.accept("lL") || !s.accept("sS") || !s.accept("eE")) {
-			s.error(boolError)
-		}
-		return false
-	}
-	return false
-}
-
-// Numerical elements
-const (
-	binaryDigits      = "01"
-	octalDigits       = "01234567"
-	decimalDigits     = "0123456789"
-	hexadecimalDigits = "0123456789aAbBcCdDeEfF"
-	sign              = "+-"
-	period            = "."
-	exponent          = "eEp"
-)
-
-// getBase returns the numeric base represented by the verb and its digit string.
-func (s *ss) getBase(verb rune) (base int, digits string) {
-	s.okVerb(verb, "bdoUxXv", "integer") // sets s.err
-	base = 10
-	digits = decimalDigits
-	switch verb {
-	case 'b':
-		base = 2
-		digits = binaryDigits
-	case 'o':
-		base = 8
-		digits = octalDigits
-	case 'x', 'X', 'U':
-		base = 16
-		digits = hexadecimalDigits
-	}
-	return
-}
-
-// scanNumber returns the numerical string with specified digits starting here.
-func (s *ss) scanNumber(digits string, haveDigits bool) string {
-	if !haveDigits {
-		s.notEOF()
-		if !s.accept(digits) {
-			s.errorString("expected integer")
-		}
-	}
-	for s.accept(digits) {
-	}
-	return string(s.buf)
-}
-
-// scanRune returns the next rune value in the input.
-func (s *ss) scanRune(bitSize int) int64 {
-	s.notEOF()
-	r := int64(s.getRune())
-	n := uint(bitSize)
-	x := (r << (64 - n)) >> (64 - n)
-	if x != r {
-		s.errorString("overflow on character value " + string(r))
-	}
-	return r
-}
-
-// scanBasePrefix reports whether the integer begins with a 0 or 0x,
-// and returns the base, digit string, and whether a zero was found.
-// It is called only if the verb is %v.
-func (s *ss) scanBasePrefix() (base int, digits string, found bool) {
-	if !s.peek("0") {
-		return 10, decimalDigits, false
-	}
-	s.accept("0")
-	found = true // We've put a digit into the token buffer.
-	// Special cases for '0' && '0x'
-	base, digits = 8, octalDigits
-	if s.peek("xX") {
-		s.consume("xX", false)
-		base, digits = 16, hexadecimalDigits
-	}
-	return
-}
-
-// scanInt returns the value of the integer represented by the next
-// token, checking for overflow.  Any error is stored in s.err.
-func (s *ss) scanInt(verb rune, bitSize int) int64 {
-	if verb == 'c' {
-		return s.scanRune(bitSize)
-	}
-	s.skipSpace(false)
-	s.notEOF()
-	base, digits := s.getBase(verb)
-	haveDigits := false
-	if verb == 'U' {
-		if !s.consume("U", false) || !s.consume("+", false) {
-			s.errorString("bad unicode format ")
-		}
-	} else {
-		s.accept(sign) // If there's a sign, it will be left in the token buffer.
-		if verb == 'v' {
-			base, digits, haveDigits = s.scanBasePrefix()
-		}
-	}
-	tok := s.scanNumber(digits, haveDigits)
-	i, err := strconv.ParseInt(tok, base, 64)
-	if err != nil {
-		s.error(err)
-	}
-	n := uint(bitSize)
-	x := (i << (64 - n)) >> (64 - n)
-	if x != i {
-		s.errorString("integer overflow on token " + tok)
-	}
-	return i
-}
-
-// scanUint returns the value of the unsigned integer represented
-// by the next token, checking for overflow.  Any error is stored in s.err.
-func (s *ss) scanUint(verb rune, bitSize int) uint64 {
-	if verb == 'c' {
-		return uint64(s.scanRune(bitSize))
-	}
-	s.skipSpace(false)
-	s.notEOF()
-	base, digits := s.getBase(verb)
-	haveDigits := false
-	if verb == 'U' {
-		if !s.consume("U", false) || !s.consume("+", false) {
-			s.errorString("bad unicode format ")
-		}
-	} else if verb == 'v' {
-		base, digits, haveDigits = s.scanBasePrefix()
-	}
-	tok := s.scanNumber(digits, haveDigits)
-	i, err := strconv.ParseUint(tok, base, 64)
-	if err != nil {
-		s.error(err)
-	}
-	n := uint(bitSize)
-	x := (i << (64 - n)) >> (64 - n)
-	if x != i {
-		s.errorString("unsigned integer overflow on token " + tok)
-	}
-	return i
-}
-
-// floatToken returns the floating-point number starting here, no longer than swid
-// if the width is specified. It's not rigorous about syntax because it doesn't check that
-// we have at least some digits, but Atof will do that.
-func (s *ss) floatToken() string {
-	s.buf = s.buf[:0]
-	// NaN?
-	if s.accept("nN") && s.accept("aA") && s.accept("nN") {
-		return string(s.buf)
-	}
-	// leading sign?
-	s.accept(sign)
-	// Inf?
-	if s.accept("iI") && s.accept("nN") && s.accept("fF") {
-		return string(s.buf)
-	}
-	// digits?
-	for s.accept(decimalDigits) {
-	}
-	// decimal point?
-	if s.accept(period) {
-		// fraction?
-		for s.accept(decimalDigits) {
-		}
-	}
-	// exponent?
-	if s.accept(exponent) {
-		// leading sign?
-		s.accept(sign)
-		// digits?
-		for s.accept(decimalDigits) {
-		}
-	}
-	return string(s.buf)
-}
-
-// complexTokens returns the real and imaginary parts of the complex number starting here.
-// The number might be parenthesized and has the format (N+Ni) where N is a floating-point
-// number and there are no spaces within.
-func (s *ss) complexTokens() (real, imag string) {
-	// TODO: accept N and Ni independently?
-	parens := s.accept("(")
-	real = s.floatToken()
-	s.buf = s.buf[:0]
-	// Must now have a sign.
-	if !s.accept("+-") {
-		s.error(complexError)
-	}
-	// Sign is now in buffer
-	imagSign := string(s.buf)
-	imag = s.floatToken()
-	if !s.accept("i") {
-		s.error(complexError)
-	}
-	if parens && !s.accept(")") {
-		s.error(complexError)
-	}
-	return real, imagSign + imag
-}
-
-// convertFloat converts the string to a float64value.
-func (s *ss) convertFloat(str string, n int) float64 {
-	if p := indexRune(str, 'p'); p >= 0 {
-		// Atof doesn't handle power-of-2 exponents,
-		// but they're easy to evaluate.
-		f, err := strconv.ParseFloat(str[:p], n)
-		if err != nil {
-			// Put full string into error.
-			if e, ok := err.(*strconv.NumError); ok {
-				e.Num = str
-			}
-			s.error(err)
-		}
-		m, err := strconv.Atoi(str[p+1:])
-		if err != nil {
-			// Put full string into error.
-			if e, ok := err.(*strconv.NumError); ok {
-				e.Num = str
-			}
-			s.error(err)
-		}
-		return math.Ldexp(f, m)
-	}
-	f, err := strconv.ParseFloat(str, n)
-	if err != nil {
-		s.error(err)
-	}
-	return f
-}
-
-// convertComplex converts the next token to a complex128 value.
-// The atof argument is a type-specific reader for the underlying type.
-// If we're reading complex64, atof will parse float32s and convert them
-// to float64's to avoid reproducing this code for each complex type.
-func (s *ss) scanComplex(verb rune, n int) complex128 {
-	if !s.okVerb(verb, floatVerbs, "complex") {
-		return 0
-	}
-	s.skipSpace(false)
-	s.notEOF()
-	sreal, simag := s.complexTokens()
-	real := s.convertFloat(sreal, n/2)
-	imag := s.convertFloat(simag, n/2)
-	return complex(real, imag)
-}
-
-// convertString returns the string represented by the next input characters.
-// The format of the input is determined by the verb.
-func (s *ss) convertString(verb rune) (str string) {
-	if !s.okVerb(verb, "svqx", "string") {
-		return ""
-	}
-	s.skipSpace(false)
-	s.notEOF()
-	switch verb {
-	case 'q':
-		str = s.quotedString()
-	case 'x':
-		str = s.hexString()
-	default:
-		str = string(s.token(true, notSpace)) // %s and %v just return the next word
-	}
-	return
-}
-
-// quotedString returns the double- or back-quoted string represented by the next input characters.
-func (s *ss) quotedString() string {
-	s.notEOF()
-	quote := s.getRune()
-	switch quote {
-	case '`':
-		// Back-quoted: Anything goes until EOF or back quote.
-		for {
-			r := s.mustReadRune()
-			if r == quote {
-				break
-			}
-			s.buf.WriteRune(r)
-		}
-		return string(s.buf)
-	case '"':
-		// Double-quoted: Include the quotes and let strconv.Unquote do the backslash escapes.
-		s.buf.WriteRune(quote)
-		for {
-			r := s.mustReadRune()
-			s.buf.WriteRune(r)
-			if r == '\\' {
-				// In a legal backslash escape, no matter how long, only the character
-				// immediately after the escape can itself be a backslash or quote.
-				// Thus we only need to protect the first character after the backslash.
-				s.buf.WriteRune(s.mustReadRune())
-			} else if r == '"' {
-				break
-			}
-		}
-		result, err := strconv.Unquote(string(s.buf))
-		if err != nil {
-			s.error(err)
-		}
-		return result
-	default:
-		s.errorString("expected quoted string")
-	}
-	return ""
-}
-
-// hexDigit returns the value of the hexadecimal digit
-func (s *ss) hexDigit(d rune) int {
-	digit := int(d)
-	switch digit {
-	case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
-		return digit - '0'
-	case 'a', 'b', 'c', 'd', 'e', 'f':
-		return 10 + digit - 'a'
-	case 'A', 'B', 'C', 'D', 'E', 'F':
-		return 10 + digit - 'A'
-	}
-	s.errorString("illegal hex digit")
-	return 0
-}
-
-// hexByte returns the next hex-encoded (two-character) byte from the input.
-// There must be either two hexadecimal digits or a space character in the input.
-func (s *ss) hexByte() (b byte, ok bool) {
-	rune1 := s.getRune()
-	if rune1 == eof {
-		return
-	}
-	if isSpace(rune1) {
-		s.UnreadRune()
-		return
-	}
-	rune2 := s.mustReadRune()
-	return byte(s.hexDigit(rune1)<<4 | s.hexDigit(rune2)), true
-}
-
-// hexString returns the space-delimited hexpair-encoded string.
-func (s *ss) hexString() string {
-	s.notEOF()
-	for {
-		b, ok := s.hexByte()
-		if !ok {
-			break
-		}
-		s.buf.WriteByte(b)
-	}
-	if len(s.buf) == 0 {
-		s.errorString("no hex data for %x string")
-		return ""
-	}
-	return string(s.buf)
-}
-
-const floatVerbs = "beEfFgGv"
-
-const hugeWid = 1 << 30
-
-// scanOne scans a single value, deriving the scanner from the type of the argument.
-func (s *ss) scanOne(verb rune, arg interface{}) {
-	s.buf = s.buf[:0]
-	var err error
-	// If the parameter has its own Scan method, use that.
-	if v, ok := arg.(Scanner); ok {
-		err = v.Scan(s, verb)
-		if err != nil {
-			if err == io.EOF {
-				err = io.ErrUnexpectedEOF
-			}
-			s.error(err)
-		}
-		return
-	}
-
-	switch v := arg.(type) {
-	case *bool:
-		*v = s.scanBool(verb)
-	case *complex64:
-		*v = complex64(s.scanComplex(verb, 64))
-	case *complex128:
-		*v = s.scanComplex(verb, 128)
-	case *int:
-		*v = int(s.scanInt(verb, intBits))
-	case *int8:
-		*v = int8(s.scanInt(verb, 8))
-	case *int16:
-		*v = int16(s.scanInt(verb, 16))
-	case *int32:
-		*v = int32(s.scanInt(verb, 32))
-	case *int64:
-		*v = s.scanInt(verb, 64)
-	case *uint:
-		*v = uint(s.scanUint(verb, intBits))
-	case *uint8:
-		*v = uint8(s.scanUint(verb, 8))
-	case *uint16:
-		*v = uint16(s.scanUint(verb, 16))
-	case *uint32:
-		*v = uint32(s.scanUint(verb, 32))
-	case *uint64:
-		*v = s.scanUint(verb, 64)
-	case *uintptr:
-		*v = uintptr(s.scanUint(verb, uintptrBits))
-	// Floats are tricky because you want to scan in the precision of the result, not
-	// scan in high precision and convert, in order to preserve the correct error condition.
-	case *float32:
-		if s.okVerb(verb, floatVerbs, "float32") {
-			s.skipSpace(false)
-			s.notEOF()
-			*v = float32(s.convertFloat(s.floatToken(), 32))
-		}
-	case *float64:
-		if s.okVerb(verb, floatVerbs, "float64") {
-			s.skipSpace(false)
-			s.notEOF()
-			*v = s.convertFloat(s.floatToken(), 64)
-		}
-	case *string:
-		*v = s.convertString(verb)
-	case *[]byte:
-		// We scan to string and convert so we get a copy of the data.
-		// If we scanned to bytes, the slice would point at the buffer.
-		*v = []byte(s.convertString(verb))
-	default:
-		val := reflect.ValueOf(v)
-		ptr := val
-		if ptr.Kind() != reflect.Ptr {
-			s.errorString("type not a pointer: " + val.Type().String())
-			return
-		}
-		switch v := ptr.Elem(); v.Kind() {
-		case reflect.Bool:
-			v.SetBool(s.scanBool(verb))
-		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-			v.SetInt(s.scanInt(verb, v.Type().Bits()))
-		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
-			v.SetUint(s.scanUint(verb, v.Type().Bits()))
-		case reflect.String:
-			v.SetString(s.convertString(verb))
-		case reflect.Slice:
-			// For now, can only handle (renamed) []byte.
-			typ := v.Type()
-			if typ.Elem().Kind() != reflect.Uint8 {
-				s.errorString("can't scan type: " + val.Type().String())
-			}
-			str := s.convertString(verb)
-			v.Set(reflect.MakeSlice(typ, len(str), len(str)))
-			for i := 0; i < len(str); i++ {
-				v.Index(i).SetUint(uint64(str[i]))
-			}
-		case reflect.Float32, reflect.Float64:
-			s.skipSpace(false)
-			s.notEOF()
-			v.SetFloat(s.convertFloat(s.floatToken(), v.Type().Bits()))
-		case reflect.Complex64, reflect.Complex128:
-			v.SetComplex(s.scanComplex(verb, v.Type().Bits()))
-		default:
-			s.errorString("can't scan type: " + val.Type().String())
-		}
-	}
-}
-
-// errorHandler turns local panics into error returns.
-func errorHandler(errp *error) {
-	if e := recover(); e != nil {
-		if se, ok := e.(scanError); ok { // catch local error
-			*errp = se.err
-		} else if eof, ok := e.(error); ok && eof == io.EOF { // out of input
-			*errp = eof
-		} else {
-			panic(e)
-		}
-	}
-}
-
-// doScan does the real work for scanning without a format string.
-func (s *ss) doScan(a []interface{}) (numProcessed int, err error) {
-	defer errorHandler(&err)
-	for _, arg := range a {
-		s.scanOne('v', arg)
-		numProcessed++
-	}
-	// Check for newline if required.
-	if !s.nlIsSpace {
-		for {
-			r := s.getRune()
-			if r == '\n' || r == eof {
-				break
-			}
-			if !isSpace(r) {
-				s.errorString("expected newline")
-				break
-			}
-		}
-	}
-	return
-}
-
-// advance determines whether the next characters in the input match
-// those of the format.  It returns the number of bytes (sic) consumed
-// in the format. Newlines included, all runs of space characters in
-// either input or format behave as a single space. This routine also
-// handles the %% case.  If the return value is zero, either format
-// starts with a % (with no following %) or the input is empty.
-// If it is negative, the input did not match the string.
-func (s *ss) advance(format string) (i int) {
-	for i < len(format) {
-		fmtc, w := utf8.DecodeRuneInString(format[i:])
-		if fmtc == '%' {
-			// %% acts like a real percent
-			nextc, _ := utf8.DecodeRuneInString(format[i+w:]) // will not match % if string is empty
-			if nextc != '%' {
-				return
-			}
-			i += w // skip the first %
-		}
-		sawSpace := false
-		for isSpace(fmtc) && i < len(format) {
-			sawSpace = true
-			i += w
-			fmtc, w = utf8.DecodeRuneInString(format[i:])
-		}
-		if sawSpace {
-			// There was space in the format, so there should be space (EOF)
-			// in the input.
-			inputc := s.getRune()
-			if inputc == eof || inputc == '\n' {
-				// If we've reached a newline, stop now; don't read ahead.
-				return
-			}
-			if !isSpace(inputc) {
-				// Space in format but not in input: error
-				s.errorString("expected space in input to match format")
-			}
-			s.skipSpace(true)
-			continue
-		}
-		inputc := s.mustReadRune()
-		if fmtc != inputc {
-			s.UnreadRune()
-			return -1
-		}
-		i += w
-	}
-	return
-}
-
-// doScanf does the real work when scanning with a format string.
-//  At the moment, it handles only pointers to basic types.
-func (s *ss) doScanf(format string, a []interface{}) (numProcessed int, err error) {
-	defer errorHandler(&err)
-	end := len(format) - 1
-	// We process one item per non-trivial format
-	for i := 0; i <= end; {
-		w := s.advance(format[i:])
-		if w > 0 {
-			i += w
-			continue
-		}
-		// Either we failed to advance, we have a percent character, or we ran out of input.
-		if format[i] != '%' {
-			// Can't advance format.  Why not?
-			if w < 0 {
-				s.errorString("input does not match format")
-			}
-			// Otherwise at EOF; "too many operands" error handled below
-			break
-		}
-		i++ // % is one byte
-
-		// do we have 20 (width)?
-		var widPresent bool
-		s.maxWid, widPresent, i = parsenum(format, i, end)
-		if !widPresent {
-			s.maxWid = hugeWid
-		}
-		s.argLimit = s.limit
-		if f := s.count + s.maxWid; f < s.argLimit {
-			s.argLimit = f
-		}
-
-		c, w := utf8.DecodeRuneInString(format[i:])
-		i += w
-
-		if numProcessed >= len(a) { // out of operands
-			s.errorString("too few operands for format %" + format[i-w:])
-			break
-		}
-		arg := a[numProcessed]
-
-		s.scanOne(c, arg)
-		numProcessed++
-		s.argLimit = s.limit
-	}
-	if numProcessed < len(a) {
-		s.errorString("too many operands")
-	}
-	return
-}
diff --git a/src/pkg/fmt/scan_test.go b/src/pkg/fmt/scan_test.go
deleted file mode 100644
index d903f0c..0000000
--- a/src/pkg/fmt/scan_test.go
+++ /dev/null
@@ -1,960 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package fmt_test
-
-import (
-	"bufio"
-	"bytes"
-	"errors"
-	. "fmt"
-	"io"
-	"math"
-	"reflect"
-	"regexp"
-	"strings"
-	"testing"
-	"unicode/utf8"
-)
-
-type ScanTest struct {
-	text string
-	in   interface{}
-	out  interface{}
-}
-
-type ScanfTest struct {
-	format string
-	text   string
-	in     interface{}
-	out    interface{}
-}
-
-type ScanfMultiTest struct {
-	format string
-	text   string
-	in     []interface{}
-	out    []interface{}
-	err    string
-}
-
-var (
-	boolVal              bool
-	intVal               int
-	int8Val              int8
-	int16Val             int16
-	int32Val             int32
-	int64Val             int64
-	uintVal              uint
-	uint8Val             uint8
-	uint16Val            uint16
-	uint32Val            uint32
-	uint64Val            uint64
-	float32Val           float32
-	float64Val           float64
-	stringVal            string
-	bytesVal             []byte
-	runeVal              rune
-	complex64Val         complex64
-	complex128Val        complex128
-	renamedBoolVal       renamedBool
-	renamedIntVal        renamedInt
-	renamedInt8Val       renamedInt8
-	renamedInt16Val      renamedInt16
-	renamedInt32Val      renamedInt32
-	renamedInt64Val      renamedInt64
-	renamedUintVal       renamedUint
-	renamedUint8Val      renamedUint8
-	renamedUint16Val     renamedUint16
-	renamedUint32Val     renamedUint32
-	renamedUint64Val     renamedUint64
-	renamedUintptrVal    renamedUintptr
-	renamedStringVal     renamedString
-	renamedBytesVal      renamedBytes
-	renamedFloat32Val    renamedFloat32
-	renamedFloat64Val    renamedFloat64
-	renamedComplex64Val  renamedComplex64
-	renamedComplex128Val renamedComplex128
-)
-
-type FloatTest struct {
-	text string
-	in   float64
-	out  float64
-}
-
-// Xs accepts any non-empty run of the verb character
-type Xs string
-
-func (x *Xs) Scan(state ScanState, verb rune) error {
-	tok, err := state.Token(true, func(r rune) bool { return r == verb })
-	if err != nil {
-		return err
-	}
-	s := string(tok)
-	if !regexp.MustCompile("^" + string(verb) + "+$").MatchString(s) {
-		return errors.New("syntax error for xs")
-	}
-	*x = Xs(s)
-	return nil
-}
-
-var xVal Xs
-
-// IntString accepts an integer followed immediately by a string.
-// It tests the embedding of a scan within a scan.
-type IntString struct {
-	i int
-	s string
-}
-
-func (s *IntString) Scan(state ScanState, verb rune) error {
-	if _, err := Fscan(state, &s.i); err != nil {
-		return err
-	}
-
-	tok, err := state.Token(true, nil)
-	if err != nil {
-		return err
-	}
-	s.s = string(tok)
-	return nil
-}
-
-var intStringVal IntString
-
-// myStringReader implements Read but not ReadRune, allowing us to test our readRune wrapper
-// type that creates something that can read runes given only Read().
-type myStringReader struct {
-	r *strings.Reader
-}
-
-func (s *myStringReader) Read(p []byte) (n int, err error) {
-	return s.r.Read(p)
-}
-
-func newReader(s string) *myStringReader {
-	return &myStringReader{strings.NewReader(s)}
-}
-
-var scanTests = []ScanTest{
-	// Basic types
-	{"T\n", &boolVal, true},  // boolean test vals toggle to be sure they are written
-	{"F\n", &boolVal, false}, // restored to zero value
-	{"21\n", &intVal, 21},
-	{"0\n", &intVal, 0},
-	{"000\n", &intVal, 0},
-	{"0x10\n", &intVal, 0x10},
-	{"-0x10\n", &intVal, -0x10},
-	{"0377\n", &intVal, 0377},
-	{"-0377\n", &intVal, -0377},
-	{"0\n", &uintVal, uint(0)},
-	{"000\n", &uintVal, uint(0)},
-	{"0x10\n", &uintVal, uint(0x10)},
-	{"0377\n", &uintVal, uint(0377)},
-	{"22\n", &int8Val, int8(22)},
-	{"23\n", &int16Val, int16(23)},
-	{"24\n", &int32Val, int32(24)},
-	{"25\n", &int64Val, int64(25)},
-	{"127\n", &int8Val, int8(127)},
-	{"-21\n", &intVal, -21},
-	{"-22\n", &int8Val, int8(-22)},
-	{"-23\n", &int16Val, int16(-23)},
-	{"-24\n", &int32Val, int32(-24)},
-	{"-25\n", &int64Val, int64(-25)},
-	{"-128\n", &int8Val, int8(-128)},
-	{"+21\n", &intVal, +21},
-	{"+22\n", &int8Val, int8(+22)},
-	{"+23\n", &int16Val, int16(+23)},
-	{"+24\n", &int32Val, int32(+24)},
-	{"+25\n", &int64Val, int64(+25)},
-	{"+127\n", &int8Val, int8(+127)},
-	{"26\n", &uintVal, uint(26)},
-	{"27\n", &uint8Val, uint8(27)},
-	{"28\n", &uint16Val, uint16(28)},
-	{"29\n", &uint32Val, uint32(29)},
-	{"30\n", &uint64Val, uint64(30)},
-	{"255\n", &uint8Val, uint8(255)},
-	{"32767\n", &int16Val, int16(32767)},
-	{"2.3\n", &float64Val, 2.3},
-	{"2.3e1\n", &float32Val, float32(2.3e1)},
-	{"2.3e2\n", &float64Val, 2.3e2},
-	{"2.3p2\n", &float64Val, 2.3 * 4},
-	{"2.3p+2\n", &float64Val, 2.3 * 4},
-	{"2.3p+66\n", &float64Val, 2.3 * (1 << 32) * (1 << 32) * 4},
-	{"2.3p-66\n", &float64Val, 2.3 / ((1 << 32) * (1 << 32) * 4)},
-	{"2.35\n", &stringVal, "2.35"},
-	{"2345678\n", &bytesVal, []byte("2345678")},
-	{"(3.4e1-2i)\n", &complex128Val, 3.4e1 - 2i},
-	{"-3.45e1-3i\n", &complex64Val, complex64(-3.45e1 - 3i)},
-	{"-.45e1-1e2i\n", &complex128Val, complex128(-.45e1 - 100i)},
-	{"hello\n", &stringVal, "hello"},
-
-	// Carriage-return followed by newline. (We treat \r\n as \n always.)
-	{"hello\r\n", &stringVal, "hello"},
-	{"27\r\n", &uint8Val, uint8(27)},
-
-	// Renamed types
-	{"true\n", &renamedBoolVal, renamedBool(true)},
-	{"F\n", &renamedBoolVal, renamedBool(false)},
-	{"101\n", &renamedIntVal, renamedInt(101)},
-	{"102\n", &renamedIntVal, renamedInt(102)},
-	{"103\n", &renamedUintVal, renamedUint(103)},
-	{"104\n", &renamedUintVal, renamedUint(104)},
-	{"105\n", &renamedInt8Val, renamedInt8(105)},
-	{"106\n", &renamedInt16Val, renamedInt16(106)},
-	{"107\n", &renamedInt32Val, renamedInt32(107)},
-	{"108\n", &renamedInt64Val, renamedInt64(108)},
-	{"109\n", &renamedUint8Val, renamedUint8(109)},
-	{"110\n", &renamedUint16Val, renamedUint16(110)},
-	{"111\n", &renamedUint32Val, renamedUint32(111)},
-	{"112\n", &renamedUint64Val, renamedUint64(112)},
-	{"113\n", &renamedUintptrVal, renamedUintptr(113)},
-	{"114\n", &renamedStringVal, renamedString("114")},
-	{"115\n", &renamedBytesVal, renamedBytes([]byte("115"))},
-
-	// Custom scanners.
-	{"  vvv ", &xVal, Xs("vvv")},
-	{" 1234hello", &intStringVal, IntString{1234, "hello"}},
-
-	// Fixed bugs
-	{"2147483648\n", &int64Val, int64(2147483648)}, // was: integer overflow
-}
-
-var scanfTests = []ScanfTest{
-	{"%v", "TRUE\n", &boolVal, true},
-	{"%t", "false\n", &boolVal, false},
-	{"%v", "-71\n", &intVal, -71},
-	{"%v", "0377\n", &intVal, 0377},
-	{"%v", "0x44\n", &intVal, 0x44},
-	{"%d", "72\n", &intVal, 72},
-	{"%c", "a\n", &runeVal, 'a'},
-	{"%c", "\u5072\n", &runeVal, '\u5072'},
-	{"%c", "\u1234\n", &runeVal, '\u1234'},
-	{"%d", "73\n", &int8Val, int8(73)},
-	{"%d", "+74\n", &int16Val, int16(74)},
-	{"%d", "75\n", &int32Val, int32(75)},
-	{"%d", "76\n", &int64Val, int64(76)},
-	{"%b", "1001001\n", &intVal, 73},
-	{"%o", "075\n", &intVal, 075},
-	{"%x", "a75\n", &intVal, 0xa75},
-	{"%v", "71\n", &uintVal, uint(71)},
-	{"%d", "72\n", &uintVal, uint(72)},
-	{"%d", "73\n", &uint8Val, uint8(73)},
-	{"%d", "74\n", &uint16Val, uint16(74)},
-	{"%d", "75\n", &uint32Val, uint32(75)},
-	{"%d", "76\n", &uint64Val, uint64(76)},
-	{"%b", "1001001\n", &uintVal, uint(73)},
-	{"%o", "075\n", &uintVal, uint(075)},
-	{"%x", "a75\n", &uintVal, uint(0xa75)},
-	{"%x", "A75\n", &uintVal, uint(0xa75)},
-	{"%U", "U+1234\n", &intVal, int(0x1234)},
-	{"%U", "U+4567\n", &uintVal, uint(0x4567)},
-
-	// Strings
-	{"%s", "using-%s\n", &stringVal, "using-%s"},
-	{"%x", "7573696e672d2578\n", &stringVal, "using-%x"},
-	{"%q", `"quoted\twith\\do\u0075bl\x65s"` + "\n", &stringVal, "quoted\twith\\doubles"},
-	{"%q", "`quoted with backs`\n", &stringVal, "quoted with backs"},
-
-	// Byte slices
-	{"%s", "bytes-%s\n", &bytesVal, []byte("bytes-%s")},
-	{"%x", "62797465732d2578\n", &bytesVal, []byte("bytes-%x")},
-	{"%q", `"bytes\rwith\vdo\u0075bl\x65s"` + "\n", &bytesVal, []byte("bytes\rwith\vdoubles")},
-	{"%q", "`bytes with backs`\n", &bytesVal, []byte("bytes with backs")},
-
-	// Renamed types
-	{"%v\n", "true\n", &renamedBoolVal, renamedBool(true)},
-	{"%t\n", "F\n", &renamedBoolVal, renamedBool(false)},
-	{"%v", "101\n", &renamedIntVal, renamedInt(101)},
-	{"%c", "\u0101\n", &renamedIntVal, renamedInt('\u0101')},
-	{"%o", "0146\n", &renamedIntVal, renamedInt(102)},
-	{"%v", "103\n", &renamedUintVal, renamedUint(103)},
-	{"%d", "104\n", &renamedUintVal, renamedUint(104)},
-	{"%d", "105\n", &renamedInt8Val, renamedInt8(105)},
-	{"%d", "106\n", &renamedInt16Val, renamedInt16(106)},
-	{"%d", "107\n", &renamedInt32Val, renamedInt32(107)},
-	{"%d", "108\n", &renamedInt64Val, renamedInt64(108)},
-	{"%x", "6D\n", &renamedUint8Val, renamedUint8(109)},
-	{"%o", "0156\n", &renamedUint16Val, renamedUint16(110)},
-	{"%d", "111\n", &renamedUint32Val, renamedUint32(111)},
-	{"%d", "112\n", &renamedUint64Val, renamedUint64(112)},
-	{"%d", "113\n", &renamedUintptrVal, renamedUintptr(113)},
-	{"%s", "114\n", &renamedStringVal, renamedString("114")},
-	{"%q", "\"1155\"\n", &renamedBytesVal, renamedBytes([]byte("1155"))},
-	{"%g", "116e1\n", &renamedFloat32Val, renamedFloat32(116e1)},
-	{"%g", "-11.7e+1", &renamedFloat64Val, renamedFloat64(-11.7e+1)},
-	{"%g", "11+6e1i\n", &renamedComplex64Val, renamedComplex64(11 + 6e1i)},
-	{"%g", "-11.+7e+1i", &renamedComplex128Val, renamedComplex128(-11. + 7e+1i)},
-
-	// Interesting formats
-	{"here is\tthe value:%d", "here is   the\tvalue:118\n", &intVal, 118},
-	{"%% %%:%d", "% %:119\n", &intVal, 119},
-
-	// Corner cases
-	{"%x", "FFFFFFFF\n", &uint32Val, uint32(0xFFFFFFFF)},
-
-	// Custom scanner.
-	{"%s", "  sss ", &xVal, Xs("sss")},
-	{"%2s", "sssss", &xVal, Xs("ss")},
-
-	// Fixed bugs
-	{"%d\n", "27\n", &intVal, 27},  // ok
-	{"%d\n", "28 \n", &intVal, 28}, // was: "unexpected newline"
-	{"%v", "0", &intVal, 0},        // was: "EOF"; 0 was taken as base prefix and not counted.
-	{"%v", "0", &uintVal, uint(0)}, // was: "EOF"; 0 was taken as base prefix and not counted.
-}
-
-var overflowTests = []ScanTest{
-	{"128", &int8Val, 0},
-	{"32768", &int16Val, 0},
-	{"-129", &int8Val, 0},
-	{"-32769", &int16Val, 0},
-	{"256", &uint8Val, 0},
-	{"65536", &uint16Val, 0},
-	{"1e100", &float32Val, 0},
-	{"1e500", &float64Val, 0},
-	{"(1e100+0i)", &complex64Val, 0},
-	{"(1+1e100i)", &complex64Val, 0},
-	{"(1-1e500i)", &complex128Val, 0},
-}
-
-var truth bool
-var i, j, k int
-var f float64
-var s, t string
-var c complex128
-var x, y Xs
-var z IntString
-var r1, r2, r3 rune
-
-var multiTests = []ScanfMultiTest{
-	{"", "", []interface{}{}, []interface{}{}, ""},
-	{"%d", "23", args(&i), args(23), ""},
-	{"%2s%3s", "22333", args(&s, &t), args("22", "333"), ""},
-	{"%2d%3d", "44555", args(&i, &j), args(44, 555), ""},
-	{"%2d.%3d", "66.777", args(&i, &j), args(66, 777), ""},
-	{"%d, %d", "23, 18", args(&i, &j), args(23, 18), ""},
-	{"%3d22%3d", "33322333", args(&i, &j), args(333, 333), ""},
-	{"%6vX=%3fY", "3+2iX=2.5Y", args(&c, &f), args((3 + 2i), 2.5), ""},
-	{"%d%s", "123abc", args(&i, &s), args(123, "abc"), ""},
-	{"%c%c%c", "2\u50c2X", args(&r1, &r2, &r3), args('2', '\u50c2', 'X'), ""},
-
-	// Custom scanners.
-	{"%e%f", "eefffff", args(&x, &y), args(Xs("ee"), Xs("fffff")), ""},
-	{"%4v%s", "12abcd", args(&z, &s), args(IntString{12, "ab"}, "cd"), ""},
-
-	// Errors
-	{"%t", "23 18", args(&i), nil, "bad verb"},
-	{"%d %d %d", "23 18", args(&i, &j), args(23, 18), "too few operands"},
-	{"%d %d", "23 18 27", args(&i, &j, &k), args(23, 18), "too many operands"},
-	{"%c", "\u0100", args(&int8Val), nil, "overflow"},
-	{"X%d", "10X", args(&intVal), nil, "input does not match format"},
-
-	// Bad UTF-8: should see every byte.
-	{"%c%c%c", "\xc2X\xc2", args(&r1, &r2, &r3), args(utf8.RuneError, 'X', utf8.RuneError), ""},
-
-	// Fixed bugs
-	{"%v%v", "FALSE23", args(&truth, &i), args(false, 23), ""},
-}
-
-func testScan(name string, t *testing.T, scan func(r io.Reader, a ...interface{}) (int, error)) {
-	for _, test := range scanTests {
-		var r io.Reader
-		if name == "StringReader" {
-			r = strings.NewReader(test.text)
-		} else {
-			r = newReader(test.text)
-		}
-		n, err := scan(r, test.in)
-		if err != nil {
-			m := ""
-			if n > 0 {
-				m = Sprintf(" (%d fields ok)", n)
-			}
-			t.Errorf("%s got error scanning %q: %s%s", name, test.text, err, m)
-			continue
-		}
-		if n != 1 {
-			t.Errorf("%s count error on entry %q: got %d", name, test.text, n)
-			continue
-		}
-		// The incoming value may be a pointer
-		v := reflect.ValueOf(test.in)
-		if p := v; p.Kind() == reflect.Ptr {
-			v = p.Elem()
-		}
-		val := v.Interface()
-		if !reflect.DeepEqual(val, test.out) {
-			t.Errorf("%s scanning %q: expected %#v got %#v, type %T", name, test.text, test.out, val, val)
-		}
-	}
-}
-
-func TestScan(t *testing.T) {
-	testScan("StringReader", t, Fscan)
-}
-
-func TestMyReaderScan(t *testing.T) {
-	testScan("myStringReader", t, Fscan)
-}
-
-func TestScanln(t *testing.T) {
-	testScan("StringReader", t, Fscanln)
-}
-
-func TestMyReaderScanln(t *testing.T) {
-	testScan("myStringReader", t, Fscanln)
-}
-
-func TestScanf(t *testing.T) {
-	for _, test := range scanfTests {
-		n, err := Sscanf(test.text, test.format, test.in)
-		if err != nil {
-			t.Errorf("got error scanning (%q, %q): %s", test.format, test.text, err)
-			continue
-		}
-		if n != 1 {
-			t.Errorf("count error on entry (%q, %q): got %d", test.format, test.text, n)
-			continue
-		}
-		// The incoming value may be a pointer
-		v := reflect.ValueOf(test.in)
-		if p := v; p.Kind() == reflect.Ptr {
-			v = p.Elem()
-		}
-		val := v.Interface()
-		if !reflect.DeepEqual(val, test.out) {
-			t.Errorf("scanning (%q, %q): expected %#v got %#v, type %T", test.format, test.text, test.out, val, val)
-		}
-	}
-}
-
-func TestScanOverflow(t *testing.T) {
-	// different machines and different types report errors with different strings.
-	re := regexp.MustCompile("overflow|too large|out of range|not representable")
-	for _, test := range overflowTests {
-		_, err := Sscan(test.text, test.in)
-		if err == nil {
-			t.Errorf("expected overflow scanning %q", test.text)
-			continue
-		}
-		if !re.MatchString(err.Error()) {
-			t.Errorf("expected overflow error scanning %q: %s", test.text, err)
-		}
-	}
-}
-
-func verifyNaN(str string, t *testing.T) {
-	var f float64
-	var f32 float32
-	var f64 float64
-	text := str + " " + str + " " + str
-	n, err := Fscan(strings.NewReader(text), &f, &f32, &f64)
-	if err != nil {
-		t.Errorf("got error scanning %q: %s", text, err)
-	}
-	if n != 3 {
-		t.Errorf("count error scanning %q: got %d", text, n)
-	}
-	if !math.IsNaN(float64(f)) || !math.IsNaN(float64(f32)) || !math.IsNaN(f64) {
-		t.Errorf("didn't get NaNs scanning %q: got %g %g %g", text, f, f32, f64)
-	}
-}
-
-func TestNaN(t *testing.T) {
-	for _, s := range []string{"nan", "NAN", "NaN"} {
-		verifyNaN(s, t)
-	}
-}
-
-func verifyInf(str string, t *testing.T) {
-	var f float64
-	var f32 float32
-	var f64 float64
-	text := str + " " + str + " " + str
-	n, err := Fscan(strings.NewReader(text), &f, &f32, &f64)
-	if err != nil {
-		t.Errorf("got error scanning %q: %s", text, err)
-	}
-	if n != 3 {
-		t.Errorf("count error scanning %q: got %d", text, n)
-	}
-	sign := 1
-	if str[0] == '-' {
-		sign = -1
-	}
-	if !math.IsInf(float64(f), sign) || !math.IsInf(float64(f32), sign) || !math.IsInf(f64, sign) {
-		t.Errorf("didn't get right Infs scanning %q: got %g %g %g", text, f, f32, f64)
-	}
-}
-
-func TestInf(t *testing.T) {
-	for _, s := range []string{"inf", "+inf", "-inf", "INF", "-INF", "+INF", "Inf", "-Inf", "+Inf"} {
-		verifyInf(s, t)
-	}
-}
-
-func testScanfMulti(name string, t *testing.T) {
-	sliceType := reflect.TypeOf(make([]interface{}, 1))
-	for _, test := range multiTests {
-		var r io.Reader
-		if name == "StringReader" {
-			r = strings.NewReader(test.text)
-		} else {
-			r = newReader(test.text)
-		}
-		n, err := Fscanf(r, test.format, test.in...)
-		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 {
-				t.Errorf("got wrong error scanning (%q, %q): %q; expected %q", test.format, test.text, err, test.err)
-			}
-			continue
-		}
-		if test.err != "" {
-			t.Errorf("expected error %q error scanning (%q, %q)", test.err, test.format, test.text)
-		}
-		if n != len(test.out) {
-			t.Errorf("count error on entry (%q, %q): expected %d got %d", test.format, test.text, len(test.out), n)
-			continue
-		}
-		// Convert the slice of pointers into a slice of values
-		resultVal := reflect.MakeSlice(sliceType, n, n)
-		for i := 0; i < n; i++ {
-			v := reflect.ValueOf(test.in[i]).Elem()
-			resultVal.Index(i).Set(v)
-		}
-		result := resultVal.Interface()
-		if !reflect.DeepEqual(result, test.out) {
-			t.Errorf("scanning (%q, %q): expected %#v got %#v", test.format, test.text, test.out, result)
-		}
-	}
-}
-
-func TestScanfMulti(t *testing.T) {
-	testScanfMulti("StringReader", t)
-}
-
-func TestMyReaderScanfMulti(t *testing.T) {
-	testScanfMulti("myStringReader", t)
-}
-
-func TestScanMultiple(t *testing.T) {
-	var a int
-	var s string
-	n, err := Sscan("123abc", &a, &s)
-	if n != 2 {
-		t.Errorf("Sscan count error: expected 2: got %d", n)
-	}
-	if err != nil {
-		t.Errorf("Sscan expected no error; got %s", err)
-	}
-	if a != 123 || s != "abc" {
-		t.Errorf("Sscan wrong values: got (%d %q) expected (123 \"abc\")", a, s)
-	}
-	n, err = Sscan("asdf", &s, &a)
-	if n != 1 {
-		t.Errorf("Sscan count error: expected 1: got %d", n)
-	}
-	if err == nil {
-		t.Errorf("Sscan expected error; got none: %s", err)
-	}
-	if s != "asdf" {
-		t.Errorf("Sscan wrong values: got %q expected \"asdf\"", s)
-	}
-}
-
-// Empty strings are not valid input when scanning a string.
-func TestScanEmpty(t *testing.T) {
-	var s1, s2 string
-	n, err := Sscan("abc", &s1, &s2)
-	if n != 1 {
-		t.Errorf("Sscan count error: expected 1: got %d", n)
-	}
-	if err == nil {
-		t.Error("Sscan <one item> expected error; got none")
-	}
-	if s1 != "abc" {
-		t.Errorf("Sscan wrong values: got %q expected \"abc\"", s1)
-	}
-	n, err = Sscan("", &s1, &s2)
-	if n != 0 {
-		t.Errorf("Sscan count error: expected 0: got %d", n)
-	}
-	if err == nil {
-		t.Error("Sscan <empty> expected error; got none")
-	}
-	// Quoted empty string is OK.
-	n, err = Sscanf(`""`, "%q", &s1)
-	if n != 1 {
-		t.Errorf("Sscanf count error: expected 1: got %d", n)
-	}
-	if err != nil {
-		t.Errorf("Sscanf <empty> expected no error with quoted string; got %s", err)
-	}
-}
-
-func TestScanNotPointer(t *testing.T) {
-	r := strings.NewReader("1")
-	var a int
-	_, err := Fscan(r, a)
-	if err == nil {
-		t.Error("expected error scanning non-pointer")
-	} else if strings.Index(err.Error(), "pointer") < 0 {
-		t.Errorf("expected pointer error scanning non-pointer, got: %s", err)
-	}
-}
-
-func TestScanlnNoNewline(t *testing.T) {
-	var a int
-	_, 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 {
-		t.Errorf("expected newline error scanning string missing newline, got: %s", err)
-	}
-}
-
-func TestScanlnWithMiddleNewline(t *testing.T) {
-	r := strings.NewReader("123\n456\n")
-	var a, b int
-	_, 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 {
-		t.Errorf("expected newline error scanning string with extra newline, got: %s", err)
-	}
-}
-
-// eofCounter is a special Reader that counts reads at end of file.
-type eofCounter struct {
-	reader   *strings.Reader
-	eofCount int
-}
-
-func (ec *eofCounter) Read(b []byte) (n int, err error) {
-	n, err = ec.reader.Read(b)
-	if n == 0 {
-		ec.eofCount++
-	}
-	return
-}
-
-// TestEOF verifies that when we scan, we see at most EOF once per call to a
-// Scan function, and then only when it's really an EOF.
-func TestEOF(t *testing.T) {
-	ec := &eofCounter{strings.NewReader("123\n"), 0}
-	var a int
-	n, err := Fscanln(ec, &a)
-	if err != nil {
-		t.Error("unexpected error", err)
-	}
-	if n != 1 {
-		t.Error("expected to scan one item, got", n)
-	}
-	if ec.eofCount != 0 {
-		t.Error("expected zero EOFs", ec.eofCount)
-		ec.eofCount = 0 // reset for next test
-	}
-	n, err = Fscanln(ec, &a)
-	if err == nil {
-		t.Error("expected error scanning empty string")
-	}
-	if n != 0 {
-		t.Error("expected to scan zero items, got", n)
-	}
-	if ec.eofCount != 1 {
-		t.Error("expected one EOF, got", ec.eofCount)
-	}
-}
-
-// TestEOFAtEndOfInput verifies that we see an EOF error if we run out of input.
-// This was a buglet: we used to get "expected integer".
-func TestEOFAtEndOfInput(t *testing.T) {
-	var i, j int
-	n, err := Sscanf("23", "%d %d", &i, &j)
-	if n != 1 || i != 23 {
-		t.Errorf("Sscanf expected one value of 23; got %d %d", n, i)
-	}
-	if err != io.EOF {
-		t.Errorf("Sscanf expected EOF; got %q", err)
-	}
-	n, err = Sscan("234", &i, &j)
-	if n != 1 || i != 234 {
-		t.Errorf("Sscan expected one value of 234; got %d %d", n, i)
-	}
-	if err != io.EOF {
-		t.Errorf("Sscan expected EOF; got %q", err)
-	}
-	// Trailing space is tougher.
-	n, err = Sscan("234 ", &i, &j)
-	if n != 1 || i != 234 {
-		t.Errorf("Sscan expected one value of 234; got %d %d", n, i)
-	}
-	if err != io.EOF {
-		t.Errorf("Sscan expected EOF; got %q", err)
-	}
-}
-
-var eofTests = []struct {
-	format string
-	v      interface{}
-}{
-	{"%s", &stringVal},
-	{"%q", &stringVal},
-	{"%x", &stringVal},
-	{"%v", &stringVal},
-	{"%v", &bytesVal},
-	{"%v", &intVal},
-	{"%v", &uintVal},
-	{"%v", &boolVal},
-	{"%v", &float32Val},
-	{"%v", &complex64Val},
-	{"%v", &renamedStringVal},
-	{"%v", &renamedBytesVal},
-	{"%v", &renamedIntVal},
-	{"%v", &renamedUintVal},
-	{"%v", &renamedBoolVal},
-	{"%v", &renamedFloat32Val},
-	{"%v", &renamedComplex64Val},
-}
-
-func TestEOFAllTypes(t *testing.T) {
-	for i, test := range eofTests {
-		if _, err := Sscanf("", test.format, test.v); err != io.EOF {
-			t.Errorf("#%d: %s %T not eof on empty string: %s", i, test.format, test.v, err)
-		}
-		if _, err := Sscanf("   ", test.format, test.v); err != io.EOF {
-			t.Errorf("#%d: %s %T not eof on trailing blanks: %s", i, test.format, test.v, err)
-		}
-	}
-}
-
-// TestUnreadRuneWithBufio verifies that, at least when using bufio, successive
-// calls to Fscan do not lose runes.
-func TestUnreadRuneWithBufio(t *testing.T) {
-	r := bufio.NewReader(strings.NewReader("123αb"))
-	var i int
-	var a string
-	n, err := Fscanf(r, "%d", &i)
-	if n != 1 || err != nil {
-		t.Errorf("reading int expected one item, no errors; got %d %q", n, err)
-	}
-	if i != 123 {
-		t.Errorf("expected 123; got %d", i)
-	}
-	n, err = Fscanf(r, "%s", &a)
-	if n != 1 || err != nil {
-		t.Errorf("reading string expected one item, no errors; got %d %q", n, err)
-	}
-	if a != "αb" {
-		t.Errorf("expected αb; got %q", a)
-	}
-}
-
-type TwoLines string
-
-// Scan attempts to read two lines into the object.  Scanln should prevent this
-// because it stops at newline; Scan and Scanf should be fine.
-func (t *TwoLines) Scan(state ScanState, verb rune) error {
-	chars := make([]rune, 0, 100)
-	for nlCount := 0; nlCount < 2; {
-		c, _, err := state.ReadRune()
-		if err != nil {
-			return err
-		}
-		chars = append(chars, c)
-		if c == '\n' {
-			nlCount++
-		}
-	}
-	*t = TwoLines(string(chars))
-	return nil
-}
-
-func TestMultiLine(t *testing.T) {
-	input := "abc\ndef\n"
-	// Sscan should work
-	var tscan TwoLines
-	n, err := Sscan(input, &tscan)
-	if n != 1 {
-		t.Errorf("Sscan: expected 1 item; got %d", n)
-	}
-	if err != nil {
-		t.Errorf("Sscan: expected no error; got %s", err)
-	}
-	if string(tscan) != input {
-		t.Errorf("Sscan: expected %q; got %q", input, tscan)
-	}
-	// Sscanf should work
-	var tscanf TwoLines
-	n, err = Sscanf(input, "%s", &tscanf)
-	if n != 1 {
-		t.Errorf("Sscanf: expected 1 item; got %d", n)
-	}
-	if err != nil {
-		t.Errorf("Sscanf: expected no error; got %s", err)
-	}
-	if string(tscanf) != input {
-		t.Errorf("Sscanf: expected %q; got %q", input, tscanf)
-	}
-	// Sscanln should not work
-	var tscanln TwoLines
-	n, err = Sscanln(input, &tscanln)
-	if n != 0 {
-		t.Errorf("Sscanln: expected 0 items; got %d: %q", n, tscanln)
-	}
-	if err == nil {
-		t.Error("Sscanln: expected error; got none")
-	} else if err != io.ErrUnexpectedEOF {
-		t.Errorf("Sscanln: expected io.ErrUnexpectedEOF (ha!); got %s", err)
-	}
-}
-
-// simpleReader is a strings.Reader that implements only Read, not ReadRune.
-// Good for testing readahead.
-type simpleReader struct {
-	sr *strings.Reader
-}
-
-func (s *simpleReader) Read(b []byte) (n int, err error) {
-	return s.sr.Read(b)
-}
-
-// TestLineByLineFscanf tests that Fscanf does not read past newline. Issue
-// 3481.
-func TestLineByLineFscanf(t *testing.T) {
-	r := &simpleReader{strings.NewReader("1\n2\n")}
-	var i, j int
-	n, err := Fscanf(r, "%v\n", &i)
-	if n != 1 || err != nil {
-		t.Fatalf("first read: %d %q", n, err)
-	}
-	n, err = Fscanf(r, "%v\n", &j)
-	if n != 1 || err != nil {
-		t.Fatalf("second read: %d %q", n, err)
-	}
-	if i != 1 || j != 2 {
-		t.Errorf("wrong values; wanted 1 2 got %d %d", i, j)
-	}
-}
-
-// RecursiveInt accepts a string matching %d.%d.%d....
-// and parses it into a linked list.
-// It allows us to benchmark recursive descent style scanners.
-type RecursiveInt struct {
-	i    int
-	next *RecursiveInt
-}
-
-func (r *RecursiveInt) Scan(state ScanState, verb rune) (err error) {
-	_, err = Fscan(state, &r.i)
-	if err != nil {
-		return
-	}
-	next := new(RecursiveInt)
-	_, err = Fscanf(state, ".%v", next)
-	if err != nil {
-		if err == io.ErrUnexpectedEOF {
-			err = nil
-		}
-		return
-	}
-	r.next = next
-	return
-}
-
-// scanInts performs the same scanning task as RecursiveInt.Scan
-// but without recurring through scanner, so we can compare
-// performance more directly.
-func scanInts(r *RecursiveInt, b *bytes.Buffer) (err error) {
-	r.next = nil
-	_, err = Fscan(b, &r.i)
-	if err != nil {
-		return
-	}
-	c, _, err := b.ReadRune()
-	if err != nil {
-		if err == io.EOF {
-			err = nil
-		}
-		return
-	}
-	if c != '.' {
-		return
-	}
-	next := new(RecursiveInt)
-	err = scanInts(next, b)
-	if err == nil {
-		r.next = next
-	}
-	return
-}
-
-func makeInts(n int) []byte {
-	var buf bytes.Buffer
-	Fprintf(&buf, "1")
-	for i := 1; i < n; i++ {
-		Fprintf(&buf, ".%d", i+1)
-	}
-	return buf.Bytes()
-}
-
-func TestScanInts(t *testing.T) {
-	testScanInts(t, scanInts)
-	testScanInts(t, func(r *RecursiveInt, b *bytes.Buffer) (err error) {
-		_, err = Fscan(b, r)
-		return
-	})
-}
-
-// 800 is small enough to not overflow the stack when using gccgo on a
-// platform that does not support split stack.
-const intCount = 800
-
-func testScanInts(t *testing.T, scan func(*RecursiveInt, *bytes.Buffer) error) {
-	r := new(RecursiveInt)
-	ints := makeInts(intCount)
-	buf := bytes.NewBuffer(ints)
-	err := scan(r, buf)
-	if err != nil {
-		t.Error("unexpected error", err)
-	}
-	i := 1
-	for ; r != nil; r = r.next {
-		if r.i != i {
-			t.Fatalf("bad scan: expected %d got %d", i, r.i)
-		}
-		i++
-	}
-	if i-1 != intCount {
-		t.Fatalf("bad scan count: expected %d got %d", intCount, i-1)
-	}
-}
-
-func BenchmarkScanInts(b *testing.B) {
-	b.ResetTimer()
-	ints := makeInts(intCount)
-	var r RecursiveInt
-	for i := b.N - 1; i >= 0; i-- {
-		buf := bytes.NewBuffer(ints)
-		b.StartTimer()
-		scanInts(&r, buf)
-		b.StopTimer()
-	}
-}
-
-func BenchmarkScanRecursiveInt(b *testing.B) {
-	b.ResetTimer()
-	ints := makeInts(intCount)
-	var r RecursiveInt
-	for i := b.N - 1; i >= 0; i-- {
-		buf := bytes.NewBuffer(ints)
-		b.StartTimer()
-		Fscan(buf, &r)
-		b.StopTimer()
-	}
-}
diff --git a/src/pkg/go/ast/ast.go b/src/pkg/go/ast/ast.go
deleted file mode 100644
index 6e635cd..0000000
--- a/src/pkg/go/ast/ast.go
+++ /dev/null
@@ -1,995 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package ast declares the types used to represent syntax trees for Go
-// packages.
-//
-package ast
-
-import (
-	"go/token"
-	"strings"
-	"unicode"
-	"unicode/utf8"
-)
-
-// ----------------------------------------------------------------------------
-// Interfaces
-//
-// There are 3 main classes of nodes: Expressions and type nodes,
-// statement nodes, and declaration nodes. The node names usually
-// match the corresponding Go spec production names to which they
-// correspond. The node fields correspond to the individual parts
-// of the respective productions.
-//
-// All nodes contain position information marking the beginning of
-// the corresponding source text segment; it is accessible via the
-// Pos accessor method. Nodes may contain additional position info
-// for language constructs where comments may be found between parts
-// of the construct (typically any larger, parenthesized subpart).
-// That position information is needed to properly position comments
-// when printing the construct.
-
-// All node types implement the Node interface.
-type Node interface {
-	Pos() token.Pos // position of first character belonging to the node
-	End() token.Pos // position of first character immediately after the node
-}
-
-// All expression nodes implement the Expr interface.
-type Expr interface {
-	Node
-	exprNode()
-}
-
-// All statement nodes implement the Stmt interface.
-type Stmt interface {
-	Node
-	stmtNode()
-}
-
-// All declaration nodes implement the Decl interface.
-type Decl interface {
-	Node
-	declNode()
-}
-
-// ----------------------------------------------------------------------------
-// Comments
-
-// A Comment node represents a single //-style or /*-style comment.
-type Comment struct {
-	Slash token.Pos // position of "/" starting the comment
-	Text  string    // comment text (excluding '\n' for //-style comments)
-}
-
-func (c *Comment) Pos() token.Pos { return c.Slash }
-func (c *Comment) End() token.Pos { return token.Pos(int(c.Slash) + len(c.Text)) }
-
-// A CommentGroup represents a sequence of comments
-// with no other tokens and no empty lines between.
-//
-type CommentGroup struct {
-	List []*Comment // len(List) > 0
-}
-
-func (g *CommentGroup) Pos() token.Pos { return g.List[0].Pos() }
-func (g *CommentGroup) End() token.Pos { return g.List[len(g.List)-1].End() }
-
-func isWhitespace(ch byte) bool { return ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r' }
-
-func stripTrailingWhitespace(s string) string {
-	i := len(s)
-	for i > 0 && isWhitespace(s[i-1]) {
-		i--
-	}
-	return s[0:i]
-}
-
-// Text returns the text of the comment.
-// Comment markers (//, /*, and */), the first space of a line comment, and
-// leading and trailing empty lines are removed. Multiple empty lines are
-// reduced to one, and trailing space on lines is trimmed. Unless the result
-// is empty, it is newline-terminated.
-//
-func (g *CommentGroup) Text() string {
-	if g == nil {
-		return ""
-	}
-	comments := make([]string, len(g.List))
-	for i, c := range g.List {
-		comments[i] = string(c.Text)
-	}
-
-	lines := make([]string, 0, 10) // most comments are less than 10 lines
-	for _, c := range comments {
-		// Remove comment markers.
-		// The parser has given us exactly the comment text.
-		switch c[1] {
-		case '/':
-			//-style comment (no newline at the end)
-			c = c[2:]
-			// strip first space - required for Example tests
-			if len(c) > 0 && c[0] == ' ' {
-				c = c[1:]
-			}
-		case '*':
-			/*-style comment */
-			c = c[2 : len(c)-2]
-		}
-
-		// Split on newlines.
-		cl := strings.Split(c, "\n")
-
-		// Walk lines, stripping trailing white space and adding to list.
-		for _, l := range cl {
-			lines = append(lines, stripTrailingWhitespace(l))
-		}
-	}
-
-	// Remove leading blank lines; convert runs of
-	// interior blank lines to a single blank line.
-	n := 0
-	for _, line := range lines {
-		if line != "" || n > 0 && lines[n-1] != "" {
-			lines[n] = line
-			n++
-		}
-	}
-	lines = lines[0:n]
-
-	// Add final "" entry to get trailing newline from Join.
-	if n > 0 && lines[n-1] != "" {
-		lines = append(lines, "")
-	}
-
-	return strings.Join(lines, "\n")
-}
-
-// ----------------------------------------------------------------------------
-// Expressions and types
-
-// A Field represents a Field declaration list in a struct type,
-// a method list in an interface type, or a parameter/result declaration
-// in a signature.
-//
-type Field struct {
-	Doc     *CommentGroup // associated documentation; or nil
-	Names   []*Ident      // field/method/parameter names; or nil if anonymous field
-	Type    Expr          // field/method/parameter type
-	Tag     *BasicLit     // field tag; or nil
-	Comment *CommentGroup // line comments; or nil
-}
-
-func (f *Field) Pos() token.Pos {
-	if len(f.Names) > 0 {
-		return f.Names[0].Pos()
-	}
-	return f.Type.Pos()
-}
-
-func (f *Field) End() token.Pos {
-	if f.Tag != nil {
-		return f.Tag.End()
-	}
-	return f.Type.End()
-}
-
-// A FieldList represents a list of Fields, enclosed by parentheses or braces.
-type FieldList struct {
-	Opening token.Pos // position of opening parenthesis/brace, if any
-	List    []*Field  // field list; or nil
-	Closing token.Pos // position of closing parenthesis/brace, if any
-}
-
-func (f *FieldList) Pos() token.Pos {
-	if f.Opening.IsValid() {
-		return f.Opening
-	}
-	// the list should not be empty in this case;
-	// be conservative and guard against bad ASTs
-	if len(f.List) > 0 {
-		return f.List[0].Pos()
-	}
-	return token.NoPos
-}
-
-func (f *FieldList) End() token.Pos {
-	if f.Closing.IsValid() {
-		return f.Closing + 1
-	}
-	// the list should not be empty in this case;
-	// be conservative and guard against bad ASTs
-	if n := len(f.List); n > 0 {
-		return f.List[n-1].End()
-	}
-	return token.NoPos
-}
-
-// NumFields returns the number of (named and anonymous fields) in a FieldList.
-func (f *FieldList) NumFields() int {
-	n := 0
-	if f != nil {
-		for _, g := range f.List {
-			m := len(g.Names)
-			if m == 0 {
-				m = 1 // anonymous field
-			}
-			n += m
-		}
-	}
-	return n
-}
-
-// An expression is represented by a tree consisting of one
-// or more of the following concrete expression nodes.
-//
-type (
-	// A BadExpr node is a placeholder for expressions containing
-	// syntax errors for which no correct expression nodes can be
-	// created.
-	//
-	BadExpr struct {
-		From, To token.Pos // position range of bad expression
-	}
-
-	// An Ident node represents an identifier.
-	Ident struct {
-		NamePos token.Pos // identifier position
-		Name    string    // identifier name
-		Obj     *Object   // denoted object; or nil
-	}
-
-	// An Ellipsis node stands for the "..." type in a
-	// parameter list or the "..." length in an array type.
-	//
-	Ellipsis struct {
-		Ellipsis token.Pos // position of "..."
-		Elt      Expr      // ellipsis element type (parameter lists only); or nil
-	}
-
-	// A BasicLit node represents a literal of basic type.
-	BasicLit struct {
-		ValuePos token.Pos   // literal position
-		Kind     token.Token // token.INT, token.FLOAT, token.IMAG, token.CHAR, or token.STRING
-		Value    string      // literal string; e.g. 42, 0x7f, 3.14, 1e-9, 2.4i, 'a', '\x7f', "foo" or `\m\n\o`
-	}
-
-	// A FuncLit node represents a function literal.
-	FuncLit struct {
-		Type *FuncType  // function type
-		Body *BlockStmt // function body
-	}
-
-	// A CompositeLit node represents a composite literal.
-	CompositeLit struct {
-		Type   Expr      // literal type; or nil
-		Lbrace token.Pos // position of "{"
-		Elts   []Expr    // list of composite elements; or nil
-		Rbrace token.Pos // position of "}"
-	}
-
-	// A ParenExpr node represents a parenthesized expression.
-	ParenExpr struct {
-		Lparen token.Pos // position of "("
-		X      Expr      // parenthesized expression
-		Rparen token.Pos // position of ")"
-	}
-
-	// A SelectorExpr node represents an expression followed by a selector.
-	SelectorExpr struct {
-		X   Expr   // expression
-		Sel *Ident // field selector
-	}
-
-	// An IndexExpr node represents an expression followed by an index.
-	IndexExpr struct {
-		X      Expr      // expression
-		Lbrack token.Pos // position of "["
-		Index  Expr      // index expression
-		Rbrack token.Pos // position of "]"
-	}
-
-	// An SliceExpr node represents an expression followed by slice indices.
-	SliceExpr struct {
-		X      Expr      // expression
-		Lbrack token.Pos // position of "["
-		Low    Expr      // begin of slice range; or nil
-		High   Expr      // end of slice range; or nil
-		Max    Expr      // maximum capacity of slice; or nil
-		Slice3 bool      // true if 3-index slice (2 colons present)
-		Rbrack token.Pos // position of "]"
-	}
-
-	// A TypeAssertExpr node represents an expression followed by a
-	// type assertion.
-	//
-	TypeAssertExpr struct {
-		X      Expr      // expression
-		Lparen token.Pos // position of "("
-		Type   Expr      // asserted type; nil means type switch X.(type)
-		Rparen token.Pos // position of ")"
-	}
-
-	// A CallExpr node represents an expression followed by an argument list.
-	CallExpr struct {
-		Fun      Expr      // function expression
-		Lparen   token.Pos // position of "("
-		Args     []Expr    // function arguments; or nil
-		Ellipsis token.Pos // position of "...", if any
-		Rparen   token.Pos // position of ")"
-	}
-
-	// A StarExpr node represents an expression of the form "*" Expression.
-	// Semantically it could be a unary "*" expression, or a pointer type.
-	//
-	StarExpr struct {
-		Star token.Pos // position of "*"
-		X    Expr      // operand
-	}
-
-	// A UnaryExpr node represents a unary expression.
-	// Unary "*" expressions are represented via StarExpr nodes.
-	//
-	UnaryExpr struct {
-		OpPos token.Pos   // position of Op
-		Op    token.Token // operator
-		X     Expr        // operand
-	}
-
-	// A BinaryExpr node represents a binary expression.
-	BinaryExpr struct {
-		X     Expr        // left operand
-		OpPos token.Pos   // position of Op
-		Op    token.Token // operator
-		Y     Expr        // right operand
-	}
-
-	// A KeyValueExpr node represents (key : value) pairs
-	// in composite literals.
-	//
-	KeyValueExpr struct {
-		Key   Expr
-		Colon token.Pos // position of ":"
-		Value Expr
-	}
-)
-
-// The direction of a channel type is indicated by one
-// of the following constants.
-//
-type ChanDir int
-
-const (
-	SEND ChanDir = 1 << iota
-	RECV
-)
-
-// A type is represented by a tree consisting of one
-// or more of the following type-specific expression
-// nodes.
-//
-type (
-	// An ArrayType node represents an array or slice type.
-	ArrayType struct {
-		Lbrack token.Pos // position of "["
-		Len    Expr      // Ellipsis node for [...]T array types, nil for slice types
-		Elt    Expr      // element type
-	}
-
-	// A StructType node represents a struct type.
-	StructType struct {
-		Struct     token.Pos  // position of "struct" keyword
-		Fields     *FieldList // list of field declarations
-		Incomplete bool       // true if (source) fields are missing in the Fields list
-	}
-
-	// Pointer types are represented via StarExpr nodes.
-
-	// A FuncType node represents a function type.
-	FuncType struct {
-		Func    token.Pos  // position of "func" keyword (token.NoPos if there is no "func")
-		Params  *FieldList // (incoming) parameters; non-nil
-		Results *FieldList // (outgoing) results; or nil
-	}
-
-	// An InterfaceType node represents an interface type.
-	InterfaceType struct {
-		Interface  token.Pos  // position of "interface" keyword
-		Methods    *FieldList // list of methods
-		Incomplete bool       // true if (source) methods are missing in the Methods list
-	}
-
-	// A MapType node represents a map type.
-	MapType struct {
-		Map   token.Pos // position of "map" keyword
-		Key   Expr
-		Value Expr
-	}
-
-	// A ChanType node represents a channel type.
-	ChanType struct {
-		Begin token.Pos // position of "chan" keyword or "<-" (whichever comes first)
-		Arrow token.Pos // position of "<-" (token.NoPos if there is no "<-")
-		Dir   ChanDir   // channel direction
-		Value Expr      // value type
-	}
-)
-
-// Pos and End implementations for expression/type nodes.
-//
-func (x *BadExpr) Pos() token.Pos  { return x.From }
-func (x *Ident) Pos() token.Pos    { return x.NamePos }
-func (x *Ellipsis) Pos() token.Pos { return x.Ellipsis }
-func (x *BasicLit) Pos() token.Pos { return x.ValuePos }
-func (x *FuncLit) Pos() token.Pos  { return x.Type.Pos() }
-func (x *CompositeLit) Pos() token.Pos {
-	if x.Type != nil {
-		return x.Type.Pos()
-	}
-	return x.Lbrace
-}
-func (x *ParenExpr) Pos() token.Pos      { return x.Lparen }
-func (x *SelectorExpr) Pos() token.Pos   { return x.X.Pos() }
-func (x *IndexExpr) Pos() token.Pos      { return x.X.Pos() }
-func (x *SliceExpr) Pos() token.Pos      { return x.X.Pos() }
-func (x *TypeAssertExpr) Pos() token.Pos { return x.X.Pos() }
-func (x *CallExpr) Pos() token.Pos       { return x.Fun.Pos() }
-func (x *StarExpr) Pos() token.Pos       { return x.Star }
-func (x *UnaryExpr) Pos() token.Pos      { return x.OpPos }
-func (x *BinaryExpr) Pos() token.Pos     { return x.X.Pos() }
-func (x *KeyValueExpr) Pos() token.Pos   { return x.Key.Pos() }
-func (x *ArrayType) Pos() token.Pos      { return x.Lbrack }
-func (x *StructType) Pos() token.Pos     { return x.Struct }
-func (x *FuncType) Pos() token.Pos {
-	if x.Func.IsValid() || x.Params == nil { // see issue 3870
-		return x.Func
-	}
-	return x.Params.Pos() // interface method declarations have no "func" keyword
-}
-func (x *InterfaceType) Pos() token.Pos { return x.Interface }
-func (x *MapType) Pos() token.Pos       { return x.Map }
-func (x *ChanType) Pos() token.Pos      { return x.Begin }
-
-func (x *BadExpr) End() token.Pos { return x.To }
-func (x *Ident) End() token.Pos   { return token.Pos(int(x.NamePos) + len(x.Name)) }
-func (x *Ellipsis) End() token.Pos {
-	if x.Elt != nil {
-		return x.Elt.End()
-	}
-	return x.Ellipsis + 3 // len("...")
-}
-func (x *BasicLit) End() token.Pos       { return token.Pos(int(x.ValuePos) + len(x.Value)) }
-func (x *FuncLit) End() token.Pos        { return x.Body.End() }
-func (x *CompositeLit) End() token.Pos   { return x.Rbrace + 1 }
-func (x *ParenExpr) End() token.Pos      { return x.Rparen + 1 }
-func (x *SelectorExpr) End() token.Pos   { return x.Sel.End() }
-func (x *IndexExpr) End() token.Pos      { return x.Rbrack + 1 }
-func (x *SliceExpr) End() token.Pos      { return x.Rbrack + 1 }
-func (x *TypeAssertExpr) End() token.Pos { return x.Rparen + 1 }
-func (x *CallExpr) End() token.Pos       { return x.Rparen + 1 }
-func (x *StarExpr) End() token.Pos       { return x.X.End() }
-func (x *UnaryExpr) End() token.Pos      { return x.X.End() }
-func (x *BinaryExpr) End() token.Pos     { return x.Y.End() }
-func (x *KeyValueExpr) End() token.Pos   { return x.Value.End() }
-func (x *ArrayType) End() token.Pos      { return x.Elt.End() }
-func (x *StructType) End() token.Pos     { return x.Fields.End() }
-func (x *FuncType) End() token.Pos {
-	if x.Results != nil {
-		return x.Results.End()
-	}
-	return x.Params.End()
-}
-func (x *InterfaceType) End() token.Pos { return x.Methods.End() }
-func (x *MapType) End() token.Pos       { return x.Value.End() }
-func (x *ChanType) End() token.Pos      { return x.Value.End() }
-
-// exprNode() ensures that only expression/type nodes can be
-// assigned to an ExprNode.
-//
-func (*BadExpr) exprNode()        {}
-func (*Ident) exprNode()          {}
-func (*Ellipsis) exprNode()       {}
-func (*BasicLit) exprNode()       {}
-func (*FuncLit) exprNode()        {}
-func (*CompositeLit) exprNode()   {}
-func (*ParenExpr) exprNode()      {}
-func (*SelectorExpr) exprNode()   {}
-func (*IndexExpr) exprNode()      {}
-func (*SliceExpr) exprNode()      {}
-func (*TypeAssertExpr) exprNode() {}
-func (*CallExpr) exprNode()       {}
-func (*StarExpr) exprNode()       {}
-func (*UnaryExpr) exprNode()      {}
-func (*BinaryExpr) exprNode()     {}
-func (*KeyValueExpr) exprNode()   {}
-
-func (*ArrayType) exprNode()     {}
-func (*StructType) exprNode()    {}
-func (*FuncType) exprNode()      {}
-func (*InterfaceType) exprNode() {}
-func (*MapType) exprNode()       {}
-func (*ChanType) exprNode()      {}
-
-// ----------------------------------------------------------------------------
-// Convenience functions for Idents
-
-// NewIdent creates a new Ident without position.
-// Useful for ASTs generated by code other than the Go parser.
-//
-func NewIdent(name string) *Ident { return &Ident{token.NoPos, name, nil} }
-
-// IsExported reports whether name is an exported Go symbol
-// (that is, whether it begins with an upper-case letter).
-//
-func IsExported(name string) bool {
-	ch, _ := utf8.DecodeRuneInString(name)
-	return unicode.IsUpper(ch)
-}
-
-// IsExported reports whether id is an exported Go symbol
-// (that is, whether it begins with an uppercase letter).
-//
-func (id *Ident) IsExported() bool { return IsExported(id.Name) }
-
-func (id *Ident) String() string {
-	if id != nil {
-		return id.Name
-	}
-	return "<nil>"
-}
-
-// ----------------------------------------------------------------------------
-// Statements
-
-// A statement is represented by a tree consisting of one
-// or more of the following concrete statement nodes.
-//
-type (
-	// A BadStmt node is a placeholder for statements containing
-	// syntax errors for which no correct statement nodes can be
-	// created.
-	//
-	BadStmt struct {
-		From, To token.Pos // position range of bad statement
-	}
-
-	// A DeclStmt node represents a declaration in a statement list.
-	DeclStmt struct {
-		Decl Decl // *GenDecl with CONST, TYPE, or VAR token
-	}
-
-	// An EmptyStmt node represents an empty statement.
-	// The "position" of the empty statement is the position
-	// of the immediately preceding semicolon.
-	//
-	EmptyStmt struct {
-		Semicolon token.Pos // position of preceding ";"
-	}
-
-	// A LabeledStmt node represents a labeled statement.
-	LabeledStmt struct {
-		Label *Ident
-		Colon token.Pos // position of ":"
-		Stmt  Stmt
-	}
-
-	// An ExprStmt node represents a (stand-alone) expression
-	// in a statement list.
-	//
-	ExprStmt struct {
-		X Expr // expression
-	}
-
-	// A SendStmt node represents a send statement.
-	SendStmt struct {
-		Chan  Expr
-		Arrow token.Pos // position of "<-"
-		Value Expr
-	}
-
-	// An IncDecStmt node represents an increment or decrement statement.
-	IncDecStmt struct {
-		X      Expr
-		TokPos token.Pos   // position of Tok
-		Tok    token.Token // INC or DEC
-	}
-
-	// An AssignStmt node represents an assignment or
-	// a short variable declaration.
-	//
-	AssignStmt struct {
-		Lhs    []Expr
-		TokPos token.Pos   // position of Tok
-		Tok    token.Token // assignment token, DEFINE
-		Rhs    []Expr
-	}
-
-	// A GoStmt node represents a go statement.
-	GoStmt struct {
-		Go   token.Pos // position of "go" keyword
-		Call *CallExpr
-	}
-
-	// A DeferStmt node represents a defer statement.
-	DeferStmt struct {
-		Defer token.Pos // position of "defer" keyword
-		Call  *CallExpr
-	}
-
-	// A ReturnStmt node represents a return statement.
-	ReturnStmt struct {
-		Return  token.Pos // position of "return" keyword
-		Results []Expr    // result expressions; or nil
-	}
-
-	// A BranchStmt node represents a break, continue, goto,
-	// or fallthrough statement.
-	//
-	BranchStmt struct {
-		TokPos token.Pos   // position of Tok
-		Tok    token.Token // keyword token (BREAK, CONTINUE, GOTO, FALLTHROUGH)
-		Label  *Ident      // label name; or nil
-	}
-
-	// A BlockStmt node represents a braced statement list.
-	BlockStmt struct {
-		Lbrace token.Pos // position of "{"
-		List   []Stmt
-		Rbrace token.Pos // position of "}"
-	}
-
-	// An IfStmt node represents an if statement.
-	IfStmt struct {
-		If   token.Pos // position of "if" keyword
-		Init Stmt      // initialization statement; or nil
-		Cond Expr      // condition
-		Body *BlockStmt
-		Else Stmt // else branch; or nil
-	}
-
-	// A CaseClause represents a case of an expression or type switch statement.
-	CaseClause struct {
-		Case  token.Pos // position of "case" or "default" keyword
-		List  []Expr    // list of expressions or types; nil means default case
-		Colon token.Pos // position of ":"
-		Body  []Stmt    // statement list; or nil
-	}
-
-	// A SwitchStmt node represents an expression switch statement.
-	SwitchStmt struct {
-		Switch token.Pos  // position of "switch" keyword
-		Init   Stmt       // initialization statement; or nil
-		Tag    Expr       // tag expression; or nil
-		Body   *BlockStmt // CaseClauses only
-	}
-
-	// An TypeSwitchStmt node represents a type switch statement.
-	TypeSwitchStmt struct {
-		Switch token.Pos  // position of "switch" keyword
-		Init   Stmt       // initialization statement; or nil
-		Assign Stmt       // x := y.(type) or y.(type)
-		Body   *BlockStmt // CaseClauses only
-	}
-
-	// A CommClause node represents a case of a select statement.
-	CommClause struct {
-		Case  token.Pos // position of "case" or "default" keyword
-		Comm  Stmt      // send or receive statement; nil means default case
-		Colon token.Pos // position of ":"
-		Body  []Stmt    // statement list; or nil
-	}
-
-	// An SelectStmt node represents a select statement.
-	SelectStmt struct {
-		Select token.Pos  // position of "select" keyword
-		Body   *BlockStmt // CommClauses only
-	}
-
-	// A ForStmt represents a for statement.
-	ForStmt struct {
-		For  token.Pos // position of "for" keyword
-		Init Stmt      // initialization statement; or nil
-		Cond Expr      // condition; or nil
-		Post Stmt      // post iteration statement; or nil
-		Body *BlockStmt
-	}
-
-	// A RangeStmt represents a for statement with a range clause.
-	RangeStmt struct {
-		For        token.Pos   // position of "for" keyword
-		Key, Value Expr        // Value may be nil
-		TokPos     token.Pos   // position of Tok
-		Tok        token.Token // ASSIGN, DEFINE
-		X          Expr        // value to range over
-		Body       *BlockStmt
-	}
-)
-
-// Pos and End implementations for statement nodes.
-//
-func (s *BadStmt) Pos() token.Pos        { return s.From }
-func (s *DeclStmt) Pos() token.Pos       { return s.Decl.Pos() }
-func (s *EmptyStmt) Pos() token.Pos      { return s.Semicolon }
-func (s *LabeledStmt) Pos() token.Pos    { return s.Label.Pos() }
-func (s *ExprStmt) Pos() token.Pos       { return s.X.Pos() }
-func (s *SendStmt) Pos() token.Pos       { return s.Chan.Pos() }
-func (s *IncDecStmt) Pos() token.Pos     { return s.X.Pos() }
-func (s *AssignStmt) Pos() token.Pos     { return s.Lhs[0].Pos() }
-func (s *GoStmt) Pos() token.Pos         { return s.Go }
-func (s *DeferStmt) Pos() token.Pos      { return s.Defer }
-func (s *ReturnStmt) Pos() token.Pos     { return s.Return }
-func (s *BranchStmt) Pos() token.Pos     { return s.TokPos }
-func (s *BlockStmt) Pos() token.Pos      { return s.Lbrace }
-func (s *IfStmt) Pos() token.Pos         { return s.If }
-func (s *CaseClause) Pos() token.Pos     { return s.Case }
-func (s *SwitchStmt) Pos() token.Pos     { return s.Switch }
-func (s *TypeSwitchStmt) Pos() token.Pos { return s.Switch }
-func (s *CommClause) Pos() token.Pos     { return s.Case }
-func (s *SelectStmt) Pos() token.Pos     { return s.Select }
-func (s *ForStmt) Pos() token.Pos        { return s.For }
-func (s *RangeStmt) Pos() token.Pos      { return s.For }
-
-func (s *BadStmt) End() token.Pos  { return s.To }
-func (s *DeclStmt) End() token.Pos { return s.Decl.End() }
-func (s *EmptyStmt) End() token.Pos {
-	return s.Semicolon + 1 /* len(";") */
-}
-func (s *LabeledStmt) End() token.Pos { return s.Stmt.End() }
-func (s *ExprStmt) End() token.Pos    { return s.X.End() }
-func (s *SendStmt) End() token.Pos    { return s.Value.End() }
-func (s *IncDecStmt) End() token.Pos {
-	return s.TokPos + 2 /* len("++") */
-}
-func (s *AssignStmt) End() token.Pos { return s.Rhs[len(s.Rhs)-1].End() }
-func (s *GoStmt) End() token.Pos     { return s.Call.End() }
-func (s *DeferStmt) End() token.Pos  { return s.Call.End() }
-func (s *ReturnStmt) End() token.Pos {
-	if n := len(s.Results); n > 0 {
-		return s.Results[n-1].End()
-	}
-	return s.Return + 6 // len("return")
-}
-func (s *BranchStmt) End() token.Pos {
-	if s.Label != nil {
-		return s.Label.End()
-	}
-	return token.Pos(int(s.TokPos) + len(s.Tok.String()))
-}
-func (s *BlockStmt) End() token.Pos { return s.Rbrace + 1 }
-func (s *IfStmt) End() token.Pos {
-	if s.Else != nil {
-		return s.Else.End()
-	}
-	return s.Body.End()
-}
-func (s *CaseClause) End() token.Pos {
-	if n := len(s.Body); n > 0 {
-		return s.Body[n-1].End()
-	}
-	return s.Colon + 1
-}
-func (s *SwitchStmt) End() token.Pos     { return s.Body.End() }
-func (s *TypeSwitchStmt) End() token.Pos { return s.Body.End() }
-func (s *CommClause) End() token.Pos {
-	if n := len(s.Body); n > 0 {
-		return s.Body[n-1].End()
-	}
-	return s.Colon + 1
-}
-func (s *SelectStmt) End() token.Pos { return s.Body.End() }
-func (s *ForStmt) End() token.Pos    { return s.Body.End() }
-func (s *RangeStmt) End() token.Pos  { return s.Body.End() }
-
-// stmtNode() ensures that only statement nodes can be
-// assigned to a StmtNode.
-//
-func (*BadStmt) stmtNode()        {}
-func (*DeclStmt) stmtNode()       {}
-func (*EmptyStmt) stmtNode()      {}
-func (*LabeledStmt) stmtNode()    {}
-func (*ExprStmt) stmtNode()       {}
-func (*SendStmt) stmtNode()       {}
-func (*IncDecStmt) stmtNode()     {}
-func (*AssignStmt) stmtNode()     {}
-func (*GoStmt) stmtNode()         {}
-func (*DeferStmt) stmtNode()      {}
-func (*ReturnStmt) stmtNode()     {}
-func (*BranchStmt) stmtNode()     {}
-func (*BlockStmt) stmtNode()      {}
-func (*IfStmt) stmtNode()         {}
-func (*CaseClause) stmtNode()     {}
-func (*SwitchStmt) stmtNode()     {}
-func (*TypeSwitchStmt) stmtNode() {}
-func (*CommClause) stmtNode()     {}
-func (*SelectStmt) stmtNode()     {}
-func (*ForStmt) stmtNode()        {}
-func (*RangeStmt) stmtNode()      {}
-
-// ----------------------------------------------------------------------------
-// Declarations
-
-// A Spec node represents a single (non-parenthesized) import,
-// constant, type, or variable declaration.
-//
-type (
-	// The Spec type stands for any of *ImportSpec, *ValueSpec, and *TypeSpec.
-	Spec interface {
-		Node
-		specNode()
-	}
-
-	// An ImportSpec node represents a single package import.
-	ImportSpec struct {
-		Doc     *CommentGroup // associated documentation; or nil
-		Name    *Ident        // local package name (including "."); or nil
-		Path    *BasicLit     // import path
-		Comment *CommentGroup // line comments; or nil
-		EndPos  token.Pos     // end of spec (overrides Path.Pos if nonzero)
-	}
-
-	// A ValueSpec node represents a constant or variable declaration
-	// (ConstSpec or VarSpec production).
-	//
-	ValueSpec struct {
-		Doc     *CommentGroup // associated documentation; or nil
-		Names   []*Ident      // value names (len(Names) > 0)
-		Type    Expr          // value type; or nil
-		Values  []Expr        // initial values; or nil
-		Comment *CommentGroup // line comments; or nil
-	}
-
-	// A TypeSpec node represents a type declaration (TypeSpec production).
-	TypeSpec struct {
-		Doc     *CommentGroup // associated documentation; or nil
-		Name    *Ident        // type name
-		Type    Expr          // *Ident, *ParenExpr, *SelectorExpr, *StarExpr, or any of the *XxxTypes
-		Comment *CommentGroup // line comments; or nil
-	}
-)
-
-// Pos and End implementations for spec nodes.
-//
-func (s *ImportSpec) Pos() token.Pos {
-	if s.Name != nil {
-		return s.Name.Pos()
-	}
-	return s.Path.Pos()
-}
-func (s *ValueSpec) Pos() token.Pos { return s.Names[0].Pos() }
-func (s *TypeSpec) Pos() token.Pos  { return s.Name.Pos() }
-
-func (s *ImportSpec) End() token.Pos {
-	if s.EndPos != 0 {
-		return s.EndPos
-	}
-	return s.Path.End()
-}
-
-func (s *ValueSpec) End() token.Pos {
-	if n := len(s.Values); n > 0 {
-		return s.Values[n-1].End()
-	}
-	if s.Type != nil {
-		return s.Type.End()
-	}
-	return s.Names[len(s.Names)-1].End()
-}
-func (s *TypeSpec) End() token.Pos { return s.Type.End() }
-
-// specNode() ensures that only spec nodes can be
-// assigned to a Spec.
-//
-func (*ImportSpec) specNode() {}
-func (*ValueSpec) specNode()  {}
-func (*TypeSpec) specNode()   {}
-
-// A declaration is represented by one of the following declaration nodes.
-//
-type (
-	// A BadDecl node is a placeholder for declarations containing
-	// syntax errors for which no correct declaration nodes can be
-	// created.
-	//
-	BadDecl struct {
-		From, To token.Pos // position range of bad declaration
-	}
-
-	// A GenDecl node (generic declaration node) represents an import,
-	// constant, type or variable declaration. A valid Lparen position
-	// (Lparen.Line > 0) indicates a parenthesized declaration.
-	//
-	// Relationship between Tok value and Specs element type:
-	//
-	//	token.IMPORT  *ImportSpec
-	//	token.CONST   *ValueSpec
-	//	token.TYPE    *TypeSpec
-	//	token.VAR     *ValueSpec
-	//
-	GenDecl struct {
-		Doc    *CommentGroup // associated documentation; or nil
-		TokPos token.Pos     // position of Tok
-		Tok    token.Token   // IMPORT, CONST, TYPE, VAR
-		Lparen token.Pos     // position of '(', if any
-		Specs  []Spec
-		Rparen token.Pos // position of ')', if any
-	}
-
-	// A FuncDecl node represents a function declaration.
-	FuncDecl struct {
-		Doc  *CommentGroup // associated documentation; or nil
-		Recv *FieldList    // receiver (methods); or nil (functions)
-		Name *Ident        // function/method name
-		Type *FuncType     // function signature: parameters, results, and position of "func" keyword
-		Body *BlockStmt    // function body; or nil (forward declaration)
-	}
-)
-
-// Pos and End implementations for declaration nodes.
-//
-func (d *BadDecl) Pos() token.Pos  { return d.From }
-func (d *GenDecl) Pos() token.Pos  { return d.TokPos }
-func (d *FuncDecl) Pos() token.Pos { return d.Type.Pos() }
-
-func (d *BadDecl) End() token.Pos { return d.To }
-func (d *GenDecl) End() token.Pos {
-	if d.Rparen.IsValid() {
-		return d.Rparen + 1
-	}
-	return d.Specs[0].End()
-}
-func (d *FuncDecl) End() token.Pos {
-	if d.Body != nil {
-		return d.Body.End()
-	}
-	return d.Type.End()
-}
-
-// declNode() ensures that only declaration nodes can be
-// assigned to a DeclNode.
-//
-func (*BadDecl) declNode()  {}
-func (*GenDecl) declNode()  {}
-func (*FuncDecl) declNode() {}
-
-// ----------------------------------------------------------------------------
-// Files and packages
-
-// A File node represents a Go source file.
-//
-// The Comments list contains all comments in the source file in order of
-// appearance, including the comments that are pointed to from other nodes
-// via Doc and Comment fields.
-//
-type File struct {
-	Doc        *CommentGroup   // associated documentation; or nil
-	Package    token.Pos       // position of "package" keyword
-	Name       *Ident          // package name
-	Decls      []Decl          // top-level declarations; or nil
-	Scope      *Scope          // package scope (this file only)
-	Imports    []*ImportSpec   // imports in this file
-	Unresolved []*Ident        // unresolved identifiers in this file
-	Comments   []*CommentGroup // list of all comments in the source file
-}
-
-func (f *File) Pos() token.Pos { return f.Package }
-func (f *File) End() token.Pos {
-	if n := len(f.Decls); n > 0 {
-		return f.Decls[n-1].End()
-	}
-	return f.Name.End()
-}
-
-// A Package node represents a set of source files
-// collectively building a Go package.
-//
-type Package struct {
-	Name    string             // package name
-	Scope   *Scope             // package scope across all files
-	Imports map[string]*Object // map of package id -> package object
-	Files   map[string]*File   // Go source files by filename
-}
-
-func (p *Package) Pos() token.Pos { return token.NoPos }
-func (p *Package) End() token.Pos { return token.NoPos }
diff --git a/src/pkg/go/ast/scope.go b/src/pkg/go/ast/scope.go
deleted file mode 100644
index 8df5b2c..0000000
--- a/src/pkg/go/ast/scope.go
+++ /dev/null
@@ -1,162 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// This file implements scopes and the objects they contain.
-
-package ast
-
-import (
-	"bytes"
-	"fmt"
-	"go/token"
-)
-
-// A Scope maintains the set of named language entities declared
-// in the scope and a link to the immediately surrounding (outer)
-// scope.
-//
-type Scope struct {
-	Outer   *Scope
-	Objects map[string]*Object
-}
-
-// NewScope creates a new scope nested in the outer scope.
-func NewScope(outer *Scope) *Scope {
-	const n = 4 // initial scope capacity
-	return &Scope{outer, make(map[string]*Object, n)}
-}
-
-// Lookup returns the object with the given name if it is
-// found in scope s, otherwise it returns nil. Outer scopes
-// are ignored.
-//
-func (s *Scope) Lookup(name string) *Object {
-	return s.Objects[name]
-}
-
-// Insert attempts to insert a named object obj into the scope s.
-// If the scope already contains an object alt with the same name,
-// Insert leaves the scope unchanged and returns alt. Otherwise
-// it inserts obj and returns nil."
-//
-func (s *Scope) Insert(obj *Object) (alt *Object) {
-	if alt = s.Objects[obj.Name]; alt == nil {
-		s.Objects[obj.Name] = obj
-	}
-	return
-}
-
-// Debugging support
-func (s *Scope) String() string {
-	var buf bytes.Buffer
-	fmt.Fprintf(&buf, "scope %p {", s)
-	if s != nil && len(s.Objects) > 0 {
-		fmt.Fprintln(&buf)
-		for _, obj := range s.Objects {
-			fmt.Fprintf(&buf, "\t%s %s\n", obj.Kind, obj.Name)
-		}
-	}
-	fmt.Fprintf(&buf, "}\n")
-	return buf.String()
-}
-
-// ----------------------------------------------------------------------------
-// Objects
-
-// An Object describes a named language entity such as a package,
-// constant, type, variable, function (incl. methods), or label.
-//
-// The Data fields contains object-specific data:
-//
-//	Kind    Data type         Data value
-//	Pkg	*types.Package    package scope
-//	Con     int               iota for the respective declaration
-//	Con     != nil            constant value
-//	Typ     *Scope            (used as method scope during type checking - transient)
-//
-type Object struct {
-	Kind ObjKind
-	Name string      // declared name
-	Decl interface{} // corresponding Field, XxxSpec, FuncDecl, LabeledStmt, AssignStmt, Scope; or nil
-	Data interface{} // object-specific data; or nil
-	Type interface{} // place holder for type information; may be nil
-}
-
-// NewObj creates a new object of a given kind and name.
-func NewObj(kind ObjKind, name string) *Object {
-	return &Object{Kind: kind, Name: name}
-}
-
-// Pos computes the source position of the declaration of an object name.
-// The result may be an invalid position if it cannot be computed
-// (obj.Decl may be nil or not correct).
-func (obj *Object) Pos() token.Pos {
-	name := obj.Name
-	switch d := obj.Decl.(type) {
-	case *Field:
-		for _, n := range d.Names {
-			if n.Name == name {
-				return n.Pos()
-			}
-		}
-	case *ImportSpec:
-		if d.Name != nil && d.Name.Name == name {
-			return d.Name.Pos()
-		}
-		return d.Path.Pos()
-	case *ValueSpec:
-		for _, n := range d.Names {
-			if n.Name == name {
-				return n.Pos()
-			}
-		}
-	case *TypeSpec:
-		if d.Name.Name == name {
-			return d.Name.Pos()
-		}
-	case *FuncDecl:
-		if d.Name.Name == name {
-			return d.Name.Pos()
-		}
-	case *LabeledStmt:
-		if d.Label.Name == name {
-			return d.Label.Pos()
-		}
-	case *AssignStmt:
-		for _, x := range d.Lhs {
-			if ident, isIdent := x.(*Ident); isIdent && ident.Name == name {
-				return ident.Pos()
-			}
-		}
-	case *Scope:
-		// predeclared object - nothing to do for now
-	}
-	return token.NoPos
-}
-
-// ObjKind describes what an object represents.
-type ObjKind int
-
-// The list of possible Object kinds.
-const (
-	Bad ObjKind = iota // for error handling
-	Pkg                // package
-	Con                // constant
-	Typ                // type
-	Var                // variable
-	Fun                // function or method
-	Lbl                // label
-)
-
-var objKindStrings = [...]string{
-	Bad: "bad",
-	Pkg: "package",
-	Con: "const",
-	Typ: "type",
-	Var: "var",
-	Fun: "func",
-	Lbl: "label",
-}
-
-func (kind ObjKind) String() string { return objKindStrings[kind] }
diff --git a/src/pkg/go/ast/walk.go b/src/pkg/go/ast/walk.go
deleted file mode 100644
index fedffb3..0000000
--- a/src/pkg/go/ast/walk.go
+++ /dev/null
@@ -1,384 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package ast
-
-import "fmt"
-
-// A Visitor's Visit method is invoked for each node encountered by Walk.
-// If the result visitor w is not nil, Walk visits each of the children
-// of node with the visitor w, followed by a call of w.Visit(nil).
-type Visitor interface {
-	Visit(node Node) (w Visitor)
-}
-
-// Helper functions for common node lists. They may be empty.
-
-func walkIdentList(v Visitor, list []*Ident) {
-	for _, x := range list {
-		Walk(v, x)
-	}
-}
-
-func walkExprList(v Visitor, list []Expr) {
-	for _, x := range list {
-		Walk(v, x)
-	}
-}
-
-func walkStmtList(v Visitor, list []Stmt) {
-	for _, x := range list {
-		Walk(v, x)
-	}
-}
-
-func walkDeclList(v Visitor, list []Decl) {
-	for _, x := range list {
-		Walk(v, x)
-	}
-}
-
-// TODO(gri): Investigate if providing a closure to Walk leads to
-//            simpler use (and may help eliminate Inspect in turn).
-
-// Walk traverses an AST in depth-first order: It starts by calling
-// v.Visit(node); node must not be nil. If the visitor w returned by
-// v.Visit(node) is not nil, Walk is invoked recursively with visitor
-// w for each of the non-nil children of node, followed by a call of
-// w.Visit(nil).
-//
-func Walk(v Visitor, node Node) {
-	if v = v.Visit(node); v == nil {
-		return
-	}
-
-	// walk children
-	// (the order of the cases matches the order
-	// of the corresponding node types in ast.go)
-	switch n := node.(type) {
-	// Comments and fields
-	case *Comment:
-		// nothing to do
-
-	case *CommentGroup:
-		for _, c := range n.List {
-			Walk(v, c)
-		}
-
-	case *Field:
-		if n.Doc != nil {
-			Walk(v, n.Doc)
-		}
-		walkIdentList(v, n.Names)
-		Walk(v, n.Type)
-		if n.Tag != nil {
-			Walk(v, n.Tag)
-		}
-		if n.Comment != nil {
-			Walk(v, n.Comment)
-		}
-
-	case *FieldList:
-		for _, f := range n.List {
-			Walk(v, f)
-		}
-
-	// Expressions
-	case *BadExpr, *Ident, *BasicLit:
-		// nothing to do
-
-	case *Ellipsis:
-		if n.Elt != nil {
-			Walk(v, n.Elt)
-		}
-
-	case *FuncLit:
-		Walk(v, n.Type)
-		Walk(v, n.Body)
-
-	case *CompositeLit:
-		if n.Type != nil {
-			Walk(v, n.Type)
-		}
-		walkExprList(v, n.Elts)
-
-	case *ParenExpr:
-		Walk(v, n.X)
-
-	case *SelectorExpr:
-		Walk(v, n.X)
-		Walk(v, n.Sel)
-
-	case *IndexExpr:
-		Walk(v, n.X)
-		Walk(v, n.Index)
-
-	case *SliceExpr:
-		Walk(v, n.X)
-		if n.Low != nil {
-			Walk(v, n.Low)
-		}
-		if n.High != nil {
-			Walk(v, n.High)
-		}
-		if n.Max != nil {
-			Walk(v, n.Max)
-		}
-
-	case *TypeAssertExpr:
-		Walk(v, n.X)
-		if n.Type != nil {
-			Walk(v, n.Type)
-		}
-
-	case *CallExpr:
-		Walk(v, n.Fun)
-		walkExprList(v, n.Args)
-
-	case *StarExpr:
-		Walk(v, n.X)
-
-	case *UnaryExpr:
-		Walk(v, n.X)
-
-	case *BinaryExpr:
-		Walk(v, n.X)
-		Walk(v, n.Y)
-
-	case *KeyValueExpr:
-		Walk(v, n.Key)
-		Walk(v, n.Value)
-
-	// Types
-	case *ArrayType:
-		if n.Len != nil {
-			Walk(v, n.Len)
-		}
-		Walk(v, n.Elt)
-
-	case *StructType:
-		Walk(v, n.Fields)
-
-	case *FuncType:
-		if n.Params != nil {
-			Walk(v, n.Params)
-		}
-		if n.Results != nil {
-			Walk(v, n.Results)
-		}
-
-	case *InterfaceType:
-		Walk(v, n.Methods)
-
-	case *MapType:
-		Walk(v, n.Key)
-		Walk(v, n.Value)
-
-	case *ChanType:
-		Walk(v, n.Value)
-
-	// Statements
-	case *BadStmt:
-		// nothing to do
-
-	case *DeclStmt:
-		Walk(v, n.Decl)
-
-	case *EmptyStmt:
-		// nothing to do
-
-	case *LabeledStmt:
-		Walk(v, n.Label)
-		Walk(v, n.Stmt)
-
-	case *ExprStmt:
-		Walk(v, n.X)
-
-	case *SendStmt:
-		Walk(v, n.Chan)
-		Walk(v, n.Value)
-
-	case *IncDecStmt:
-		Walk(v, n.X)
-
-	case *AssignStmt:
-		walkExprList(v, n.Lhs)
-		walkExprList(v, n.Rhs)
-
-	case *GoStmt:
-		Walk(v, n.Call)
-
-	case *DeferStmt:
-		Walk(v, n.Call)
-
-	case *ReturnStmt:
-		walkExprList(v, n.Results)
-
-	case *BranchStmt:
-		if n.Label != nil {
-			Walk(v, n.Label)
-		}
-
-	case *BlockStmt:
-		walkStmtList(v, n.List)
-
-	case *IfStmt:
-		if n.Init != nil {
-			Walk(v, n.Init)
-		}
-		Walk(v, n.Cond)
-		Walk(v, n.Body)
-		if n.Else != nil {
-			Walk(v, n.Else)
-		}
-
-	case *CaseClause:
-		walkExprList(v, n.List)
-		walkStmtList(v, n.Body)
-
-	case *SwitchStmt:
-		if n.Init != nil {
-			Walk(v, n.Init)
-		}
-		if n.Tag != nil {
-			Walk(v, n.Tag)
-		}
-		Walk(v, n.Body)
-
-	case *TypeSwitchStmt:
-		if n.Init != nil {
-			Walk(v, n.Init)
-		}
-		Walk(v, n.Assign)
-		Walk(v, n.Body)
-
-	case *CommClause:
-		if n.Comm != nil {
-			Walk(v, n.Comm)
-		}
-		walkStmtList(v, n.Body)
-
-	case *SelectStmt:
-		Walk(v, n.Body)
-
-	case *ForStmt:
-		if n.Init != nil {
-			Walk(v, n.Init)
-		}
-		if n.Cond != nil {
-			Walk(v, n.Cond)
-		}
-		if n.Post != nil {
-			Walk(v, n.Post)
-		}
-		Walk(v, n.Body)
-
-	case *RangeStmt:
-		Walk(v, n.Key)
-		if n.Value != nil {
-			Walk(v, n.Value)
-		}
-		Walk(v, n.X)
-		Walk(v, n.Body)
-
-	// Declarations
-	case *ImportSpec:
-		if n.Doc != nil {
-			Walk(v, n.Doc)
-		}
-		if n.Name != nil {
-			Walk(v, n.Name)
-		}
-		Walk(v, n.Path)
-		if n.Comment != nil {
-			Walk(v, n.Comment)
-		}
-
-	case *ValueSpec:
-		if n.Doc != nil {
-			Walk(v, n.Doc)
-		}
-		walkIdentList(v, n.Names)
-		if n.Type != nil {
-			Walk(v, n.Type)
-		}
-		walkExprList(v, n.Values)
-		if n.Comment != nil {
-			Walk(v, n.Comment)
-		}
-
-	case *TypeSpec:
-		if n.Doc != nil {
-			Walk(v, n.Doc)
-		}
-		Walk(v, n.Name)
-		Walk(v, n.Type)
-		if n.Comment != nil {
-			Walk(v, n.Comment)
-		}
-
-	case *BadDecl:
-		// nothing to do
-
-	case *GenDecl:
-		if n.Doc != nil {
-			Walk(v, n.Doc)
-		}
-		for _, s := range n.Specs {
-			Walk(v, s)
-		}
-
-	case *FuncDecl:
-		if n.Doc != nil {
-			Walk(v, n.Doc)
-		}
-		if n.Recv != nil {
-			Walk(v, n.Recv)
-		}
-		Walk(v, n.Name)
-		Walk(v, n.Type)
-		if n.Body != nil {
-			Walk(v, n.Body)
-		}
-
-	// Files and packages
-	case *File:
-		if n.Doc != nil {
-			Walk(v, n.Doc)
-		}
-		Walk(v, n.Name)
-		walkDeclList(v, n.Decls)
-		// don't walk n.Comments - they have been
-		// visited already through the individual
-		// nodes
-
-	case *Package:
-		for _, f := range n.Files {
-			Walk(v, f)
-		}
-
-	default:
-		fmt.Printf("ast.Walk: unexpected node type %T", n)
-		panic("ast.Walk")
-	}
-
-	v.Visit(nil)
-}
-
-type inspector func(Node) bool
-
-func (f inspector) Visit(node Node) Visitor {
-	if f(node) {
-		return f
-	}
-	return nil
-}
-
-// Inspect traverses an AST in depth-first order: It starts by calling
-// f(node); node must not be nil. If f returns true, Inspect invokes f
-// for all the non-nil children of node, recursively.
-//
-func Inspect(node Node, f func(Node) bool) {
-	Walk(inspector(f), node)
-}
diff --git a/src/pkg/go/build/build.go b/src/pkg/go/build/build.go
deleted file mode 100644
index 412abea..0000000
--- a/src/pkg/go/build/build.go
+++ /dev/null
@@ -1,1219 +0,0 @@
-// Copyright 2011 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package build
-
-import (
-	"bytes"
-	"errors"
-	"fmt"
-	"go/ast"
-	"go/doc"
-	"go/parser"
-	"go/token"
-	"io"
-	"io/ioutil"
-	"log"
-	"os"
-	pathpkg "path"
-	"path/filepath"
-	"runtime"
-	"sort"
-	"strconv"
-	"strings"
-	"unicode"
-)
-
-// A Context specifies the supporting context for a build.
-type Context struct {
-	GOARCH      string // target architecture
-	GOOS        string // target operating system
-	GOROOT      string // Go root
-	GOPATH      string // Go path
-	CgoEnabled  bool   // whether cgo can be used
-	UseAllFiles bool   // use files regardless of +build lines, file names
-	Compiler    string // compiler to assume when computing target paths
-
-	// The build and release tags specify build constraints
-	// that should be considered satisfied when processing +build lines.
-	// Clients creating a new context may customize BuildTags, which
-	// defaults to empty, but it is usually an error to customize ReleaseTags,
-	// which defaults to the list of Go releases the current release is compatible with.
-	// In addition to the BuildTags and ReleaseTags, build constraints
-	// consider the values of GOARCH and GOOS as satisfied tags.
-	BuildTags   []string
-	ReleaseTags []string
-
-	// The install suffix specifies a suffix to use in the name of the installation
-	// directory. By default it is empty, but custom builds that need to keep
-	// their outputs separate can set InstallSuffix to do so. For example, when
-	// using the race detector, the go command uses InstallSuffix = "race", so
-	// that on a Linux/386 system, packages are written to a directory named
-	// "linux_386_race" instead of the usual "linux_386".
-	InstallSuffix string
-
-	// By default, Import uses the operating system's file system calls
-	// to read directories and files.  To read from other sources,
-	// callers can set the following functions.  They all have default
-	// behaviors that use the local file system, so clients need only set
-	// the functions whose behaviors they wish to change.
-
-	// JoinPath joins the sequence of path fragments into a single path.
-	// If JoinPath is nil, Import uses filepath.Join.
-	JoinPath func(elem ...string) string
-
-	// SplitPathList splits the path list into a slice of individual paths.
-	// If SplitPathList is nil, Import uses filepath.SplitList.
-	SplitPathList func(list string) []string
-
-	// IsAbsPath reports whether path is an absolute path.
-	// If IsAbsPath is nil, Import uses filepath.IsAbs.
-	IsAbsPath func(path string) bool
-
-	// IsDir reports whether the path names a directory.
-	// If IsDir is nil, Import calls os.Stat and uses the result's IsDir method.
-	IsDir func(path string) bool
-
-	// HasSubdir reports whether dir is a subdirectory of
-	// (perhaps multiple levels below) root.
-	// If so, HasSubdir sets rel to a slash-separated path that
-	// can be joined to root to produce a path equivalent to dir.
-	// If HasSubdir is nil, Import uses an implementation built on
-	// filepath.EvalSymlinks.
-	HasSubdir func(root, dir string) (rel string, ok bool)
-
-	// ReadDir returns a slice of os.FileInfo, sorted by Name,
-	// describing the content of the named directory.
-	// If ReadDir is nil, Import uses ioutil.ReadDir.
-	ReadDir func(dir string) (fi []os.FileInfo, err error)
-
-	// OpenFile opens a file (not a directory) for reading.
-	// If OpenFile is nil, Import uses os.Open.
-	OpenFile func(path string) (r io.ReadCloser, err error)
-}
-
-// joinPath calls ctxt.JoinPath (if not nil) or else filepath.Join.
-func (ctxt *Context) joinPath(elem ...string) string {
-	if f := ctxt.JoinPath; f != nil {
-		return f(elem...)
-	}
-	return filepath.Join(elem...)
-}
-
-// splitPathList calls ctxt.SplitPathList (if not nil) or else filepath.SplitList.
-func (ctxt *Context) splitPathList(s string) []string {
-	if f := ctxt.SplitPathList; f != nil {
-		return f(s)
-	}
-	return filepath.SplitList(s)
-}
-
-// isAbsPath calls ctxt.IsAbsSPath (if not nil) or else filepath.IsAbs.
-func (ctxt *Context) isAbsPath(path string) bool {
-	if f := ctxt.IsAbsPath; f != nil {
-		return f(path)
-	}
-	return filepath.IsAbs(path)
-}
-
-// isDir calls ctxt.IsDir (if not nil) or else uses os.Stat.
-func (ctxt *Context) isDir(path string) bool {
-	if f := ctxt.IsDir; f != nil {
-		return f(path)
-	}
-	fi, err := os.Stat(path)
-	return err == nil && fi.IsDir()
-}
-
-// hasSubdir calls ctxt.HasSubdir (if not nil) or else uses
-// the local file system to answer the question.
-func (ctxt *Context) hasSubdir(root, dir string) (rel string, ok bool) {
-	if f := ctxt.HasSubdir; f != nil {
-		return f(root, dir)
-	}
-
-	// Try using paths we received.
-	if rel, ok = hasSubdir(root, dir); ok {
-		return
-	}
-
-	// Try expanding symlinks and comparing
-	// expanded against unexpanded and
-	// expanded against expanded.
-	rootSym, _ := filepath.EvalSymlinks(root)
-	dirSym, _ := filepath.EvalSymlinks(dir)
-
-	if rel, ok = hasSubdir(rootSym, dir); ok {
-		return
-	}
-	if rel, ok = hasSubdir(root, dirSym); ok {
-		return
-	}
-	return hasSubdir(rootSym, dirSym)
-}
-
-func hasSubdir(root, dir string) (rel string, ok bool) {
-	const sep = string(filepath.Separator)
-	root = filepath.Clean(root)
-	if !strings.HasSuffix(root, sep) {
-		root += sep
-	}
-	dir = filepath.Clean(dir)
-	if !strings.HasPrefix(dir, root) {
-		return "", false
-	}
-	return filepath.ToSlash(dir[len(root):]), true
-}
-
-// readDir calls ctxt.ReadDir (if not nil) or else ioutil.ReadDir.
-func (ctxt *Context) readDir(path string) ([]os.FileInfo, error) {
-	if f := ctxt.ReadDir; f != nil {
-		return f(path)
-	}
-	return ioutil.ReadDir(path)
-}
-
-// openFile calls ctxt.OpenFile (if not nil) or else os.Open.
-func (ctxt *Context) openFile(path string) (io.ReadCloser, error) {
-	if fn := ctxt.OpenFile; fn != nil {
-		return fn(path)
-	}
-
-	f, err := os.Open(path)
-	if err != nil {
-		return nil, err // nil interface
-	}
-	return f, nil
-}
-
-// isFile determines whether path is a file by trying to open it.
-// It reuses openFile instead of adding another function to the
-// list in Context.
-func (ctxt *Context) isFile(path string) bool {
-	f, err := ctxt.openFile(path)
-	if err != nil {
-		return false
-	}
-	f.Close()
-	return true
-}
-
-// gopath returns the list of Go path directories.
-func (ctxt *Context) gopath() []string {
-	var all []string
-	for _, p := range ctxt.splitPathList(ctxt.GOPATH) {
-		if p == "" || p == ctxt.GOROOT {
-			// Empty paths are uninteresting.
-			// If the path is the GOROOT, ignore it.
-			// People sometimes set GOPATH=$GOROOT, which is useless
-			// but would cause us to find packages with import paths
-			// like "pkg/math".
-			// Do not get confused by this common mistake.
-			continue
-		}
-		if strings.HasPrefix(p, "~") {
-			// Path segments starting with ~ on Unix are almost always
-			// users who have incorrectly quoted ~ while setting GOPATH,
-			// preventing it from expanding to $HOME.
-			// The situation is made more confusing by the fact that
-			// bash allows quoted ~ in $PATH (most shells do not).
-			// Do not get confused by this, and do not try to use the path.
-			// It does not exist, and printing errors about it confuses
-			// those users even more, because they think "sure ~ exists!".
-			// The go command diagnoses this situation and prints a
-			// useful error.
-			// On Windows, ~ is used in short names, such as c:\progra~1
-			// for c:\program files.
-			continue
-		}
-		all = append(all, p)
-	}
-	return all
-}
-
-// SrcDirs returns a list of package source root directories.
-// It draws from the current Go root and Go path but omits directories
-// that do not exist.
-func (ctxt *Context) SrcDirs() []string {
-	var all []string
-	if ctxt.GOROOT != "" {
-		dir := ctxt.joinPath(ctxt.GOROOT, "src", "pkg")
-		if ctxt.isDir(dir) {
-			all = append(all, dir)
-		}
-	}
-	for _, p := range ctxt.gopath() {
-		dir := ctxt.joinPath(p, "src")
-		if ctxt.isDir(dir) {
-			all = append(all, dir)
-		}
-	}
-	return all
-}
-
-// Default is the default Context for builds.
-// It uses the GOARCH, GOOS, GOROOT, and GOPATH environment variables
-// if set, or else the compiled code's GOARCH, GOOS, and GOROOT.
-var Default Context = defaultContext()
-
-var cgoEnabled = map[string]bool{
-	"darwin/386":      true,
-	"darwin/amd64":    true,
-	"dragonfly/386":   true,
-	"dragonfly/amd64": true,
-	"freebsd/386":     true,
-	"freebsd/amd64":   true,
-	"freebsd/arm":     true,
-	"linux/386":       true,
-	"linux/amd64":     true,
-	"linux/arm":       true,
-	"netbsd/386":      true,
-	"netbsd/amd64":    true,
-	"netbsd/arm":      true,
-	"openbsd/386":     true,
-	"openbsd/amd64":   true,
-	"windows/386":     true,
-	"windows/amd64":   true,
-}
-
-func defaultContext() Context {
-	var c Context
-
-	c.GOARCH = envOr("GOARCH", runtime.GOARCH)
-	c.GOOS = envOr("GOOS", runtime.GOOS)
-	c.GOROOT = runtime.GOROOT()
-	c.GOPATH = envOr("GOPATH", "")
-	c.Compiler = runtime.Compiler
-
-	// Each major Go release in the Go 1.x series should add a tag here.
-	// Old tags should not be removed. That is, the go1.x tag is present
-	// in all releases >= Go 1.x. Code that requires Go 1.x or later should
-	// say "+build go1.x", and code that should only be built before Go 1.x
-	// (perhaps it is the stub to use in that case) should say "+build !go1.x".
-	//
-	// When we reach Go 1.4 the line will read
-	//	c.ReleaseTags = []string{"go1.1", "go1.2", "go1.3", "go1.4"}
-	// and so on.
-	c.ReleaseTags = []string{"go1.1", "go1.2", "go1.3"}
-
-	switch os.Getenv("CGO_ENABLED") {
-	case "1":
-		c.CgoEnabled = true
-	case "0":
-		c.CgoEnabled = false
-	default:
-		// cgo must be explicitly enabled for cross compilation builds
-		if runtime.GOARCH == c.GOARCH && runtime.GOOS == c.GOOS {
-			c.CgoEnabled = cgoEnabled[c.GOOS+"/"+c.GOARCH]
-			break
-		}
-		c.CgoEnabled = false
-	}
-
-	return c
-}
-
-func envOr(name, def string) string {
-	s := os.Getenv(name)
-	if s == "" {
-		return def
-	}
-	return s
-}
-
-// An ImportMode controls the behavior of the Import method.
-type ImportMode uint
-
-const (
-	// If FindOnly is set, Import stops after locating the directory
-	// that should contain the sources for a package.  It does not
-	// read any files in the directory.
-	FindOnly ImportMode = 1 << iota
-
-	// If AllowBinary is set, Import can be satisfied by a compiled
-	// package object without corresponding sources.
-	AllowBinary
-)
-
-// A Package describes the Go package found in a directory.
-type Package struct {
-	Dir         string   // directory containing package sources
-	Name        string   // package name
-	Doc         string   // documentation synopsis
-	ImportPath  string   // import path of package ("" if unknown)
-	Root        string   // root of Go tree where this package lives
-	SrcRoot     string   // package source root directory ("" if unknown)
-	PkgRoot     string   // package install root directory ("" if unknown)
-	BinDir      string   // command install directory ("" if unknown)
-	Goroot      bool     // package found in Go root
-	PkgObj      string   // installed .a file
-	AllTags     []string // tags that can influence file selection in this directory
-	ConflictDir string   // this directory shadows Dir in $GOPATH
-
-	// Source files
-	GoFiles        []string // .go source files (excluding CgoFiles, TestGoFiles, XTestGoFiles)
-	CgoFiles       []string // .go source files that import "C"
-	IgnoredGoFiles []string // .go source files ignored for this build
-	CFiles         []string // .c source files
-	CXXFiles       []string // .cc, .cpp and .cxx source files
-	MFiles         []string // .m (Objective-C) source files
-	HFiles         []string // .h, .hh, .hpp and .hxx source files
-	SFiles         []string // .s source files
-	SwigFiles      []string // .swig files
-	SwigCXXFiles   []string // .swigcxx files
-	SysoFiles      []string // .syso system object files to add to archive
-
-	// Cgo directives
-	CgoCFLAGS    []string // Cgo CFLAGS directives
-	CgoCPPFLAGS  []string // Cgo CPPFLAGS directives
-	CgoCXXFLAGS  []string // Cgo CXXFLAGS directives
-	CgoLDFLAGS   []string // Cgo LDFLAGS directives
-	CgoPkgConfig []string // Cgo pkg-config directives
-
-	// Dependency information
-	Imports   []string                    // imports from GoFiles, CgoFiles
-	ImportPos map[string][]token.Position // line information for Imports
-
-	// Test information
-	TestGoFiles    []string                    // _test.go files in package
-	TestImports    []string                    // imports from TestGoFiles
-	TestImportPos  map[string][]token.Position // line information for TestImports
-	XTestGoFiles   []string                    // _test.go files outside package
-	XTestImports   []string                    // imports from XTestGoFiles
-	XTestImportPos map[string][]token.Position // line information for XTestImports
-}
-
-// IsCommand reports whether the package is considered a
-// command to be installed (not just a library).
-// Packages named "main" are treated as commands.
-func (p *Package) IsCommand() bool {
-	return p.Name == "main"
-}
-
-// ImportDir is like Import but processes the Go package found in
-// the named directory.
-func (ctxt *Context) ImportDir(dir string, mode ImportMode) (*Package, error) {
-	return ctxt.Import(".", dir, mode)
-}
-
-// NoGoError is the error used by Import to describe a directory
-// containing no buildable Go source files. (It may still contain
-// test files, files hidden by build tags, and so on.)
-type NoGoError struct {
-	Dir string
-}
-
-func (e *NoGoError) Error() string {
-	return "no buildable Go source files in " + e.Dir
-}
-
-func nameExt(name string) string {
-	i := strings.LastIndex(name, ".")
-	if i < 0 {
-		return ""
-	}
-	return name[i:]
-}
-
-// Import returns details about the Go package named by the import path,
-// interpreting local import paths relative to the srcDir directory.
-// If the path is a local import path naming a package that can be imported
-// using a standard import path, the returned package will set p.ImportPath
-// to that path.
-//
-// In the directory containing the package, .go, .c, .h, and .s files are
-// considered part of the package except for:
-//
-//	- .go files in package documentation
-//	- files starting with _ or . (likely editor temporary files)
-//	- files with build constraints not satisfied by the context
-//
-// If an error occurs, Import returns a non-nil error and a non-nil
-// *Package containing partial information.
-//
-func (ctxt *Context) Import(path string, srcDir string, mode ImportMode) (*Package, error) {
-	p := &Package{
-		ImportPath: path,
-	}
-	if path == "" {
-		return p, fmt.Errorf("import %q: invalid import path", path)
-	}
-
-	var pkga string
-	var pkgerr error
-	switch ctxt.Compiler {
-	case "gccgo":
-		dir, elem := pathpkg.Split(p.ImportPath)
-		pkga = "pkg/gccgo_" + ctxt.GOOS + "_" + ctxt.GOARCH + "/" + dir + "lib" + elem + ".a"
-	case "gc":
-		suffix := ""
-		if ctxt.InstallSuffix != "" {
-			suffix = "_" + ctxt.InstallSuffix
-		}
-		pkga = "pkg/" + ctxt.GOOS + "_" + ctxt.GOARCH + suffix + "/" + p.ImportPath + ".a"
-	default:
-		// Save error for end of function.
-		pkgerr = fmt.Errorf("import %q: unknown compiler %q", path, ctxt.Compiler)
-	}
-
-	binaryOnly := false
-	if IsLocalImport(path) {
-		pkga = "" // local imports have no installed path
-		if srcDir == "" {
-			return p, fmt.Errorf("import %q: import relative to unknown directory", path)
-		}
-		if !ctxt.isAbsPath(path) {
-			p.Dir = ctxt.joinPath(srcDir, path)
-		}
-		// Determine canonical import path, if any.
-		if ctxt.GOROOT != "" {
-			root := ctxt.joinPath(ctxt.GOROOT, "src", "pkg")
-			if sub, ok := ctxt.hasSubdir(root, p.Dir); ok {
-				p.Goroot = true
-				p.ImportPath = sub
-				p.Root = ctxt.GOROOT
-				goto Found
-			}
-		}
-		all := ctxt.gopath()
-		for i, root := range all {
-			rootsrc := ctxt.joinPath(root, "src")
-			if sub, ok := ctxt.hasSubdir(rootsrc, p.Dir); ok {
-				// We found a potential import path for dir,
-				// but check that using it wouldn't find something
-				// else first.
-				if ctxt.GOROOT != "" {
-					if dir := ctxt.joinPath(ctxt.GOROOT, "src", "pkg", sub); ctxt.isDir(dir) {
-						p.ConflictDir = dir
-						goto Found
-					}
-				}
-				for _, earlyRoot := range all[:i] {
-					if dir := ctxt.joinPath(earlyRoot, "src", sub); ctxt.isDir(dir) {
-						p.ConflictDir = dir
-						goto Found
-					}
-				}
-
-				// sub would not name some other directory instead of this one.
-				// Record it.
-				p.ImportPath = sub
-				p.Root = root
-				goto Found
-			}
-		}
-		// It's okay that we didn't find a root containing dir.
-		// Keep going with the information we have.
-	} else {
-		if strings.HasPrefix(path, "/") {
-			return p, fmt.Errorf("import %q: cannot import absolute path", path)
-		}
-
-		// tried records the location of unsuccessful package lookups
-		var tried struct {
-			goroot string
-			gopath []string
-		}
-
-		// Determine directory from import path.
-		if ctxt.GOROOT != "" {
-			dir := ctxt.joinPath(ctxt.GOROOT, "src", "pkg", path)
-			isDir := ctxt.isDir(dir)
-			binaryOnly = !isDir && mode&AllowBinary != 0 && pkga != "" && ctxt.isFile(ctxt.joinPath(ctxt.GOROOT, pkga))
-			if isDir || binaryOnly {
-				p.Dir = dir
-				p.Goroot = true
-				p.Root = ctxt.GOROOT
-				goto Found
-			}
-			tried.goroot = dir
-		}
-		for _, root := range ctxt.gopath() {
-			dir := ctxt.joinPath(root, "src", path)
-			isDir := ctxt.isDir(dir)
-			binaryOnly = !isDir && mode&AllowBinary != 0 && pkga != "" && ctxt.isFile(ctxt.joinPath(root, pkga))
-			if isDir || binaryOnly {
-				p.Dir = dir
-				p.Root = root
-				goto Found
-			}
-			tried.gopath = append(tried.gopath, dir)
-		}
-
-		// package was not found
-		var paths []string
-		if tried.goroot != "" {
-			paths = append(paths, fmt.Sprintf("\t%s (from $GOROOT)", tried.goroot))
-		} else {
-			paths = append(paths, "\t($GOROOT not set)")
-		}
-		var i int
-		var format = "\t%s (from $GOPATH)"
-		for ; i < len(tried.gopath); i++ {
-			if i > 0 {
-				format = "\t%s"
-			}
-			paths = append(paths, fmt.Sprintf(format, tried.gopath[i]))
-		}
-		if i == 0 {
-			paths = append(paths, "\t($GOPATH not set)")
-		}
-		return p, fmt.Errorf("cannot find package %q in any of:\n%s", path, strings.Join(paths, "\n"))
-	}
-
-Found:
-	if p.Root != "" {
-		if p.Goroot {
-			p.SrcRoot = ctxt.joinPath(p.Root, "src", "pkg")
-		} else {
-			p.SrcRoot = ctxt.joinPath(p.Root, "src")
-		}
-		p.PkgRoot = ctxt.joinPath(p.Root, "pkg")
-		p.BinDir = ctxt.joinPath(p.Root, "bin")
-		if pkga != "" {
-			p.PkgObj = ctxt.joinPath(p.Root, pkga)
-		}
-	}
-
-	if mode&FindOnly != 0 {
-		return p, pkgerr
-	}
-	if binaryOnly && (mode&AllowBinary) != 0 {
-		return p, pkgerr
-	}
-
-	dirs, err := ctxt.readDir(p.Dir)
-	if err != nil {
-		return p, err
-	}
-
-	var Sfiles []string // files with ".S" (capital S)
-	var firstFile string
-	imported := make(map[string][]token.Position)
-	testImported := make(map[string][]token.Position)
-	xTestImported := make(map[string][]token.Position)
-	allTags := make(map[string]bool)
-	fset := token.NewFileSet()
-	for _, d := range dirs {
-		if d.IsDir() {
-			continue
-		}
-
-		name := d.Name()
-		ext := nameExt(name)
-
-		match, data, filename, err := ctxt.matchFile(p.Dir, name, true, allTags)
-		if err != nil {
-			return p, err
-		}
-		if !match {
-			if ext == ".go" {
-				p.IgnoredGoFiles = append(p.IgnoredGoFiles, name)
-			}
-			continue
-		}
-
-		// Going to save the file.  For non-Go files, can stop here.
-		switch ext {
-		case ".c":
-			p.CFiles = append(p.CFiles, name)
-			continue
-		case ".cc", ".cpp", ".cxx":
-			p.CXXFiles = append(p.CXXFiles, name)
-			continue
-		case ".m":
-			p.MFiles = append(p.MFiles, name)
-			continue
-		case ".h", ".hh", ".hpp", ".hxx":
-			p.HFiles = append(p.HFiles, name)
-			continue
-		case ".s":
-			p.SFiles = append(p.SFiles, name)
-			continue
-		case ".S":
-			Sfiles = append(Sfiles, name)
-			continue
-		case ".swig":
-			p.SwigFiles = append(p.SwigFiles, name)
-			continue
-		case ".swigcxx":
-			p.SwigCXXFiles = append(p.SwigCXXFiles, name)
-			continue
-		case ".syso":
-			// binary objects to add to package archive
-			// Likely of the form foo_windows.syso, but
-			// the name was vetted above with goodOSArchFile.
-			p.SysoFiles = append(p.SysoFiles, name)
-			continue
-		}
-
-		pf, err := parser.ParseFile(fset, filename, data, parser.ImportsOnly|parser.ParseComments)
-		if err != nil {
-			return p, err
-		}
-
-		pkg := pf.Name.Name
-		if pkg == "documentation" {
-			p.IgnoredGoFiles = append(p.IgnoredGoFiles, name)
-			continue
-		}
-
-		isTest := strings.HasSuffix(name, "_test.go")
-		isXTest := false
-		if isTest && strings.HasSuffix(pkg, "_test") {
-			isXTest = true
-			pkg = pkg[:len(pkg)-len("_test")]
-		}
-
-		if p.Name == "" {
-			p.Name = pkg
-			firstFile = name
-		} else if pkg != p.Name {
-			return p, fmt.Errorf("found packages %s (%s) and %s (%s) in %s", p.Name, firstFile, pkg, name, p.Dir)
-		}
-		if pf.Doc != nil && p.Doc == "" {
-			p.Doc = doc.Synopsis(pf.Doc.Text())
-		}
-
-		// Record imports and information about cgo.
-		isCgo := false
-		for _, decl := range pf.Decls {
-			d, ok := decl.(*ast.GenDecl)
-			if !ok {
-				continue
-			}
-			for _, dspec := range d.Specs {
-				spec, ok := dspec.(*ast.ImportSpec)
-				if !ok {
-					continue
-				}
-				quoted := spec.Path.Value
-				path, err := strconv.Unquote(quoted)
-				if err != nil {
-					log.Panicf("%s: parser returned invalid quoted string: <%s>", filename, quoted)
-				}
-				if isXTest {
-					xTestImported[path] = append(xTestImported[path], fset.Position(spec.Pos()))
-				} else if isTest {
-					testImported[path] = append(testImported[path], fset.Position(spec.Pos()))
-				} else {
-					imported[path] = append(imported[path], fset.Position(spec.Pos()))
-				}
-				if path == "C" {
-					if isTest {
-						return p, fmt.Errorf("use of cgo in test %s not supported", filename)
-					}
-					cg := spec.Doc
-					if cg == nil && len(d.Specs) == 1 {
-						cg = d.Doc
-					}
-					if cg != nil {
-						if err := ctxt.saveCgo(filename, p, cg); err != nil {
-							return p, err
-						}
-					}
-					isCgo = true
-				}
-			}
-		}
-		if isCgo {
-			allTags["cgo"] = true
-			if ctxt.CgoEnabled {
-				p.CgoFiles = append(p.CgoFiles, name)
-			} else {
-				p.IgnoredGoFiles = append(p.IgnoredGoFiles, name)
-			}
-		} else if isXTest {
-			p.XTestGoFiles = append(p.XTestGoFiles, name)
-		} else if isTest {
-			p.TestGoFiles = append(p.TestGoFiles, name)
-		} else {
-			p.GoFiles = append(p.GoFiles, name)
-		}
-	}
-	if len(p.GoFiles)+len(p.CgoFiles)+len(p.TestGoFiles)+len(p.XTestGoFiles) == 0 {
-		return p, &NoGoError{p.Dir}
-	}
-
-	for tag := range allTags {
-		p.AllTags = append(p.AllTags, tag)
-	}
-	sort.Strings(p.AllTags)
-
-	p.Imports, p.ImportPos = cleanImports(imported)
-	p.TestImports, p.TestImportPos = cleanImports(testImported)
-	p.XTestImports, p.XTestImportPos = cleanImports(xTestImported)
-
-	// add the .S files only if we are using cgo
-	// (which means gcc will compile them).
-	// The standard assemblers expect .s files.
-	if len(p.CgoFiles) > 0 {
-		p.SFiles = append(p.SFiles, Sfiles...)
-		sort.Strings(p.SFiles)
-	}
-
-	return p, pkgerr
-}
-
-// MatchFile reports whether the file with the given name in the given directory
-// matches the context and would be included in a Package created by ImportDir
-// of that directory.
-//
-// MatchFile considers the name of the file and may use ctxt.OpenFile to
-// read some or all of the file's content.
-func (ctxt *Context) MatchFile(dir, name string) (match bool, err error) {
-	match, _, _, err = ctxt.matchFile(dir, name, false, nil)
-	return
-}
-
-// matchFile determines whether the file with the given name in the given directory
-// should be included in the package being constructed.
-// It returns the data read from the file.
-// If returnImports is true and name denotes a Go program, matchFile reads
-// until the end of the imports (and returns that data) even though it only
-// considers text until the first non-comment.
-// If allTags is non-nil, matchFile records any encountered build tag
-// by setting allTags[tag] = true.
-func (ctxt *Context) matchFile(dir, name string, returnImports bool, allTags map[string]bool) (match bool, data []byte, filename string, err error) {
-	if strings.HasPrefix(name, "_") ||
-		strings.HasPrefix(name, ".") {
-		return
-	}
-
-	i := strings.LastIndex(name, ".")
-	if i < 0 {
-		i = len(name)
-	}
-	ext := name[i:]
-
-	if !ctxt.goodOSArchFile(name, allTags) && !ctxt.UseAllFiles {
-		return
-	}
-
-	switch ext {
-	case ".go", ".c", ".cc", ".cxx", ".cpp", ".m", ".s", ".h", ".hh", ".hpp", ".hxx", ".S", ".swig", ".swigcxx":
-		// tentatively okay - read to make sure
-	case ".syso":
-		// binary, no reading
-		match = true
-		return
-	default:
-		// skip
-		return
-	}
-
-	filename = ctxt.joinPath(dir, name)
-	f, err := ctxt.openFile(filename)
-	if err != nil {
-		return
-	}
-
-	if strings.HasSuffix(filename, ".go") {
-		data, err = readImports(f, false)
-	} else {
-		data, err = readComments(f)
-	}
-	f.Close()
-	if err != nil {
-		err = fmt.Errorf("read %s: %v", filename, err)
-		return
-	}
-
-	// Look for +build comments to accept or reject the file.
-	if !ctxt.shouldBuild(data, allTags) && !ctxt.UseAllFiles {
-		return
-	}
-
-	match = true
-	return
-}
-
-func cleanImports(m map[string][]token.Position) ([]string, map[string][]token.Position) {
-	all := make([]string, 0, len(m))
-	for path := range m {
-		all = append(all, path)
-	}
-	sort.Strings(all)
-	return all, m
-}
-
-// Import is shorthand for Default.Import.
-func Import(path, srcDir string, mode ImportMode) (*Package, error) {
-	return Default.Import(path, srcDir, mode)
-}
-
-// ImportDir is shorthand for Default.ImportDir.
-func ImportDir(dir string, mode ImportMode) (*Package, error) {
-	return Default.ImportDir(dir, mode)
-}
-
-var slashslash = []byte("//")
-
-// shouldBuild reports whether it is okay to use this file,
-// The rule is that in the file's leading run of // comments
-// and blank lines, which must be followed by a blank line
-// (to avoid including a Go package clause doc comment),
-// lines beginning with '// +build' are taken as build directives.
-//
-// The file is accepted only if each such line lists something
-// matching the file.  For example:
-//
-//	// +build windows linux
-//
-// marks the file as applicable only on Windows and Linux.
-//
-func (ctxt *Context) shouldBuild(content []byte, allTags map[string]bool) bool {
-	// Pass 1. Identify leading run of // comments and blank lines,
-	// which must be followed by a blank line.
-	end := 0
-	p := content
-	for len(p) > 0 {
-		line := p
-		if i := bytes.IndexByte(line, '\n'); i >= 0 {
-			line, p = line[:i], p[i+1:]
-		} else {
-			p = p[len(p):]
-		}
-		line = bytes.TrimSpace(line)
-		if len(line) == 0 { // Blank line
-			end = len(content) - len(p)
-			continue
-		}
-		if !bytes.HasPrefix(line, slashslash) { // Not comment line
-			break
-		}
-	}
-	content = content[:end]
-
-	// Pass 2.  Process each line in the run.
-	p = content
-	allok := true
-	for len(p) > 0 {
-		line := p
-		if i := bytes.IndexByte(line, '\n'); i >= 0 {
-			line, p = line[:i], p[i+1:]
-		} else {
-			p = p[len(p):]
-		}
-		line = bytes.TrimSpace(line)
-		if bytes.HasPrefix(line, slashslash) {
-			line = bytes.TrimSpace(line[len(slashslash):])
-			if len(line) > 0 && line[0] == '+' {
-				// Looks like a comment +line.
-				f := strings.Fields(string(line))
-				if f[0] == "+build" {
-					ok := false
-					for _, tok := range f[1:] {
-						if ctxt.match(tok, allTags) {
-							ok = true
-						}
-					}
-					if !ok {
-						allok = false
-					}
-				}
-			}
-		}
-	}
-
-	return allok
-}
-
-// saveCgo saves the information from the #cgo lines in the import "C" comment.
-// These lines set CFLAGS, CPPFLAGS, CXXFLAGS and LDFLAGS and pkg-config directives
-// that affect the way cgo's C code is built.
-//
-// TODO(rsc): This duplicates code in cgo.
-// Once the dust settles, remove this code from cgo.
-func (ctxt *Context) saveCgo(filename string, di *Package, cg *ast.CommentGroup) error {
-	text := cg.Text()
-	for _, line := range strings.Split(text, "\n") {
-		orig := line
-
-		// Line is
-		//	#cgo [GOOS/GOARCH...] LDFLAGS: stuff
-		//
-		line = strings.TrimSpace(line)
-		if len(line) < 5 || line[:4] != "#cgo" || (line[4] != ' ' && line[4] != '\t') {
-			continue
-		}
-
-		// Split at colon.
-		line = strings.TrimSpace(line[4:])
-		i := strings.Index(line, ":")
-		if i < 0 {
-			return fmt.Errorf("%s: invalid #cgo line: %s", filename, orig)
-		}
-		line, argstr := line[:i], line[i+1:]
-
-		// Parse GOOS/GOARCH stuff.
-		f := strings.Fields(line)
-		if len(f) < 1 {
-			return fmt.Errorf("%s: invalid #cgo line: %s", filename, orig)
-		}
-
-		cond, verb := f[:len(f)-1], f[len(f)-1]
-		if len(cond) > 0 {
-			ok := false
-			for _, c := range cond {
-				if ctxt.match(c, nil) {
-					ok = true
-					break
-				}
-			}
-			if !ok {
-				continue
-			}
-		}
-
-		args, err := splitQuoted(argstr)
-		if err != nil {
-			return fmt.Errorf("%s: invalid #cgo line: %s", filename, orig)
-		}
-		for _, arg := range args {
-			if !safeCgoName(arg) {
-				return fmt.Errorf("%s: malformed #cgo argument: %s", filename, arg)
-			}
-		}
-
-		switch verb {
-		case "CFLAGS":
-			di.CgoCFLAGS = append(di.CgoCFLAGS, args...)
-		case "CPPFLAGS":
-			di.CgoCPPFLAGS = append(di.CgoCPPFLAGS, args...)
-		case "CXXFLAGS":
-			di.CgoCXXFLAGS = append(di.CgoCXXFLAGS, args...)
-		case "LDFLAGS":
-			di.CgoLDFLAGS = append(di.CgoLDFLAGS, args...)
-		case "pkg-config":
-			di.CgoPkgConfig = append(di.CgoPkgConfig, args...)
-		default:
-			return fmt.Errorf("%s: invalid #cgo verb: %s", filename, orig)
-		}
-	}
-	return nil
-}
-
-// NOTE: $ is not safe for the shell, but it is allowed here because of linker options like -Wl,$ORIGIN.
-// We never pass these arguments to a shell (just to programs we construct argv for), so this should be okay.
-// See golang.org/issue/6038.
-var safeBytes = []byte("+-.,/0123456789=ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz:$")
-
-func safeCgoName(s string) bool {
-	if s == "" {
-		return false
-	}
-	for i := 0; i < len(s); i++ {
-		if c := s[i]; c < 0x80 && bytes.IndexByte(safeBytes, c) < 0 {
-			return false
-		}
-	}
-	return true
-}
-
-// splitQuoted splits the string s around each instance of one or more consecutive
-// white space characters while taking into account quotes and escaping, and
-// returns an array of substrings of s or an empty list if s contains only white space.
-// Single quotes and double quotes are recognized to prevent splitting within the
-// quoted region, and are removed from the resulting substrings. If a quote in s
-// isn't closed err will be set and r will have the unclosed argument as the
-// last element.  The backslash is used for escaping.
-//
-// For example, the following string:
-//
-//     a b:"c d" 'e''f'  "g\""
-//
-// Would be parsed as:
-//
-//     []string{"a", "b:c d", "ef", `g"`}
-//
-func splitQuoted(s string) (r []string, err error) {
-	var args []string
-	arg := make([]rune, len(s))
-	escaped := false
-	quoted := false
-	quote := '\x00'
-	i := 0
-	for _, rune := range s {
-		switch {
-		case escaped:
-			escaped = false
-		case rune == '\\':
-			escaped = true
-			continue
-		case quote != '\x00':
-			if rune == quote {
-				quote = '\x00'
-				continue
-			}
-		case rune == '"' || rune == '\'':
-			quoted = true
-			quote = rune
-			continue
-		case unicode.IsSpace(rune):
-			if quoted || i > 0 {
-				quoted = false
-				args = append(args, string(arg[:i]))
-				i = 0
-			}
-			continue
-		}
-		arg[i] = rune
-		i++
-	}
-	if quoted || i > 0 {
-		args = append(args, string(arg[:i]))
-	}
-	if quote != 0 {
-		err = errors.New("unclosed quote")
-	} else if escaped {
-		err = errors.New("unfinished escaping")
-	}
-	return args, err
-}
-
-// match returns true if the name is one of:
-//
-//	$GOOS
-//	$GOARCH
-//	cgo (if cgo is enabled)
-//	!cgo (if cgo is disabled)
-//	ctxt.Compiler
-//	!ctxt.Compiler
-//	tag (if tag is listed in ctxt.BuildTags or ctxt.ReleaseTags)
-//	!tag (if tag is not listed in ctxt.BuildTags or ctxt.ReleaseTags)
-//	a comma-separated list of any of these
-//
-func (ctxt *Context) match(name string, allTags map[string]bool) bool {
-	if name == "" {
-		if allTags != nil {
-			allTags[name] = true
-		}
-		return false
-	}
-	if i := strings.Index(name, ","); i >= 0 {
-		// comma-separated list
-		ok1 := ctxt.match(name[:i], allTags)
-		ok2 := ctxt.match(name[i+1:], allTags)
-		return ok1 && ok2
-	}
-	if strings.HasPrefix(name, "!!") { // bad syntax, reject always
-		return false
-	}
-	if strings.HasPrefix(name, "!") { // negation
-		return len(name) > 1 && !ctxt.match(name[1:], allTags)
-	}
-
-	if allTags != nil {
-		allTags[name] = true
-	}
-
-	// Tags must be letters, digits, underscores or dots.
-	// Unlike in Go identifiers, all digits are fine (e.g., "386").
-	for _, c := range name {
-		if !unicode.IsLetter(c) && !unicode.IsDigit(c) && c != '_' && c != '.' {
-			return false
-		}
-	}
-
-	// special tags
-	if ctxt.CgoEnabled && name == "cgo" {
-		return true
-	}
-	if name == ctxt.GOOS || name == ctxt.GOARCH || name == ctxt.Compiler {
-		return true
-	}
-
-	// other tags
-	for _, tag := range ctxt.BuildTags {
-		if tag == name {
-			return true
-		}
-	}
-	for _, tag := range ctxt.ReleaseTags {
-		if tag == name {
-			return true
-		}
-	}
-
-	return false
-}
-
-// goodOSArchFile returns false if the name contains a $GOOS or $GOARCH
-// suffix which does not match the current system.
-// The recognized name formats are:
-//
-//     name_$(GOOS).*
-//     name_$(GOARCH).*
-//     name_$(GOOS)_$(GOARCH).*
-//     name_$(GOOS)_test.*
-//     name_$(GOARCH)_test.*
-//     name_$(GOOS)_$(GOARCH)_test.*
-//
-func (ctxt *Context) goodOSArchFile(name string, allTags map[string]bool) bool {
-	if dot := strings.Index(name, "."); dot != -1 {
-		name = name[:dot]
-	}
-	l := strings.Split(name, "_")
-	if n := len(l); n > 0 && l[n-1] == "test" {
-		l = l[:n-1]
-	}
-	n := len(l)
-	if n >= 2 && knownOS[l[n-2]] && knownArch[l[n-1]] {
-		if allTags != nil {
-			allTags[l[n-2]] = true
-			allTags[l[n-1]] = true
-		}
-		return l[n-2] == ctxt.GOOS && l[n-1] == ctxt.GOARCH
-	}
-	if n >= 1 && knownOS[l[n-1]] {
-		if allTags != nil {
-			allTags[l[n-1]] = true
-		}
-		return l[n-1] == ctxt.GOOS
-	}
-	if n >= 1 && knownArch[l[n-1]] {
-		if allTags != nil {
-			allTags[l[n-1]] = true
-		}
-		return l[n-1] == ctxt.GOARCH
-	}
-	return true
-}
-
-var knownOS = make(map[string]bool)
-var knownArch = make(map[string]bool)
-
-func init() {
-	for _, v := range strings.Fields(goosList) {
-		knownOS[v] = true
-	}
-	for _, v := range strings.Fields(goarchList) {
-		knownArch[v] = true
-	}
-}
-
-// ToolDir is the directory containing build tools.
-var ToolDir = filepath.Join(runtime.GOROOT(), "pkg/tool/"+runtime.GOOS+"_"+runtime.GOARCH)
-
-// IsLocalImport reports whether the import path is
-// a local import path, like ".", "..", "./foo", or "../foo".
-func IsLocalImport(path string) bool {
-	return path == "." || path == ".." ||
-		strings.HasPrefix(path, "./") || strings.HasPrefix(path, "../")
-}
-
-// ArchChar returns the architecture character for the given goarch.
-// For example, ArchChar("amd64") returns "6".
-func ArchChar(goarch string) (string, error) {
-	switch goarch {
-	case "386":
-		return "8", nil
-	case "amd64", "amd64p32":
-		return "6", nil
-	case "arm":
-		return "5", nil
-	}
-	return "", errors.New("unsupported GOARCH " + goarch)
-}
diff --git a/src/pkg/go/build/build_test.go b/src/pkg/go/build/build_test.go
deleted file mode 100644
index fca8d4b..0000000
--- a/src/pkg/go/build/build_test.go
+++ /dev/null
@@ -1,186 +0,0 @@
-// Copyright 2011 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package build
-
-import (
-	"io"
-	"os"
-	"path/filepath"
-	"reflect"
-	"runtime"
-	"strings"
-	"testing"
-)
-
-func TestMatch(t *testing.T) {
-	ctxt := Default
-	what := "default"
-	match := func(tag string, want map[string]bool) {
-		m := make(map[string]bool)
-		if !ctxt.match(tag, m) {
-			t.Errorf("%s context should match %s, does not", what, tag)
-		}
-		if !reflect.DeepEqual(m, want) {
-			t.Errorf("%s tags = %v, want %v", tag, m, want)
-		}
-	}
-	nomatch := func(tag string, want map[string]bool) {
-		m := make(map[string]bool)
-		if ctxt.match(tag, m) {
-			t.Errorf("%s context should NOT match %s, does", what, tag)
-		}
-		if !reflect.DeepEqual(m, want) {
-			t.Errorf("%s tags = %v, want %v", tag, m, want)
-		}
-	}
-
-	match(runtime.GOOS+","+runtime.GOARCH, map[string]bool{runtime.GOOS: true, runtime.GOARCH: true})
-	match(runtime.GOOS+","+runtime.GOARCH+",!foo", map[string]bool{runtime.GOOS: true, runtime.GOARCH: true, "foo": true})
-	nomatch(runtime.GOOS+","+runtime.GOARCH+",foo", map[string]bool{runtime.GOOS: true, runtime.GOARCH: true, "foo": true})
-
-	what = "modified"
-	ctxt.BuildTags = []string{"foo"}
-	match(runtime.GOOS+","+runtime.GOARCH, map[string]bool{runtime.GOOS: true, runtime.GOARCH: true})
-	match(runtime.GOOS+","+runtime.GOARCH+",foo", map[string]bool{runtime.GOOS: true, runtime.GOARCH: true, "foo": true})
-	nomatch(runtime.GOOS+","+runtime.GOARCH+",!foo", map[string]bool{runtime.GOOS: true, runtime.GOARCH: true, "foo": true})
-	match(runtime.GOOS+","+runtime.GOARCH+",!bar", map[string]bool{runtime.GOOS: true, runtime.GOARCH: true, "bar": true})
-	nomatch(runtime.GOOS+","+runtime.GOARCH+",bar", map[string]bool{runtime.GOOS: true, runtime.GOARCH: true, "bar": true})
-	nomatch("!", map[string]bool{})
-}
-
-func TestDotSlashImport(t *testing.T) {
-	p, err := ImportDir("testdata/other", 0)
-	if err != nil {
-		t.Fatal(err)
-	}
-	if len(p.Imports) != 1 || p.Imports[0] != "./file" {
-		t.Fatalf("testdata/other: Imports=%v, want [./file]", p.Imports)
-	}
-
-	p1, err := Import("./file", "testdata/other", 0)
-	if err != nil {
-		t.Fatal(err)
-	}
-	if p1.Name != "file" {
-		t.Fatalf("./file: Name=%q, want %q", p1.Name, "file")
-	}
-	dir := filepath.Clean("testdata/other/file") // Clean to use \ on Windows
-	if p1.Dir != dir {
-		t.Fatalf("./file: Dir=%q, want %q", p1.Name, dir)
-	}
-}
-
-func TestEmptyImport(t *testing.T) {
-	p, err := Import("", Default.GOROOT, FindOnly)
-	if err == nil {
-		t.Fatal(`Import("") returned nil error.`)
-	}
-	if p == nil {
-		t.Fatal(`Import("") returned nil package.`)
-	}
-	if p.ImportPath != "" {
-		t.Fatalf("ImportPath=%q, want %q.", p.ImportPath, "")
-	}
-}
-
-func TestLocalDirectory(t *testing.T) {
-	cwd, err := os.Getwd()
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	p, err := ImportDir(cwd, 0)
-	if err != nil {
-		t.Fatal(err)
-	}
-	if p.ImportPath != "go/build" {
-		t.Fatalf("ImportPath=%q, want %q", p.ImportPath, "go/build")
-	}
-}
-
-func TestShouldBuild(t *testing.T) {
-	const file1 = "// +build tag1\n\n" +
-		"package main\n"
-	want1 := map[string]bool{"tag1": true}
-
-	const file2 = "// +build cgo\n\n" +
-		"// This package implements parsing of tags like\n" +
-		"// +build tag1\n" +
-		"package build"
-	want2 := map[string]bool{"cgo": true}
-
-	const file3 = "// Copyright The Go Authors.\n\n" +
-		"package build\n\n" +
-		"// shouldBuild checks tags given by lines of the form\n" +
-		"// +build tag\n" +
-		"func shouldBuild(content []byte)\n"
-	want3 := map[string]bool{}
-
-	ctx := &Context{BuildTags: []string{"tag1"}}
-	m := map[string]bool{}
-	if !ctx.shouldBuild([]byte(file1), m) {
-		t.Errorf("shouldBuild(file1) = false, want true")
-	}
-	if !reflect.DeepEqual(m, want1) {
-		t.Errorf("shoudBuild(file1) tags = %v, want %v", m, want1)
-	}
-
-	m = map[string]bool{}
-	if ctx.shouldBuild([]byte(file2), m) {
-		t.Errorf("shouldBuild(file2) = true, want fakse")
-	}
-	if !reflect.DeepEqual(m, want2) {
-		t.Errorf("shoudBuild(file2) tags = %v, want %v", m, want2)
-	}
-
-	m = map[string]bool{}
-	ctx = &Context{BuildTags: nil}
-	if !ctx.shouldBuild([]byte(file3), m) {
-		t.Errorf("shouldBuild(file3) = false, want true")
-	}
-	if !reflect.DeepEqual(m, want3) {
-		t.Errorf("shoudBuild(file3) tags = %v, want %v", m, want3)
-	}
-}
-
-type readNopCloser struct {
-	io.Reader
-}
-
-func (r readNopCloser) Close() error {
-	return nil
-}
-
-var matchFileTests = []struct {
-	name  string
-	data  string
-	match bool
-}{
-	{"foo_arm.go", "", true},
-	{"foo1_arm.go", "// +build linux\n\npackage main\n", false},
-	{"foo_darwin.go", "", false},
-	{"foo.go", "", true},
-	{"foo1.go", "// +build linux\n\npackage main\n", false},
-	{"foo.badsuffix", "", false},
-}
-
-func TestMatchFile(t *testing.T) {
-	for _, tt := range matchFileTests {
-		ctxt := Context{GOARCH: "arm", GOOS: "plan9"}
-		ctxt.OpenFile = func(path string) (r io.ReadCloser, err error) {
-			if path != "x+"+tt.name {
-				t.Fatalf("OpenFile asked for %q, expected %q", path, "x+"+tt.name)
-			}
-			return &readNopCloser{strings.NewReader(tt.data)}, nil
-		}
-		ctxt.JoinPath = func(elem ...string) string {
-			return strings.Join(elem, "+")
-		}
-		match, err := ctxt.MatchFile("x", tt.name)
-		if match != tt.match || err != nil {
-			t.Fatalf("MatchFile(%q) = %v, %v, want %v, nil", tt.name, match, err, tt.match)
-		}
-	}
-}
diff --git a/src/pkg/go/build/deps_test.go b/src/pkg/go/build/deps_test.go
deleted file mode 100644
index 7421e14..0000000
--- a/src/pkg/go/build/deps_test.go
+++ /dev/null
@@ -1,442 +0,0 @@
-// Copyright 2012 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// This file exercises the import parser but also checks that
-// some low-level packages do not have new dependencies added.
-
-package build
-
-import (
-	"runtime"
-	"sort"
-	"testing"
-)
-
-// pkgDeps defines the expected dependencies between packages in
-// the Go source tree.  It is a statement of policy.
-// Changes should not be made to this map without prior discussion.
-//
-// The map contains two kinds of entries:
-// 1) Lower-case keys are standard import paths and list the
-// allowed imports in that package.
-// 2) Upper-case keys define aliases for package sets, which can then
-// be used as dependencies by other rules.
-//
-// DO NOT CHANGE THIS DATA TO FIX BUILDS.
-//
-var pkgDeps = map[string][]string{
-	// L0 is the lowest level, core, nearly unavoidable packages.
-	"errors":      {},
-	"io":          {"errors", "sync"},
-	"runtime":     {"unsafe"},
-	"sync":        {"runtime", "sync/atomic", "unsafe"},
-	"sync/atomic": {"unsafe"},
-	"unsafe":      {},
-
-	"L0": {
-		"errors",
-		"io",
-		"runtime",
-		"sync",
-		"sync/atomic",
-		"unsafe",
-	},
-
-	// L1 adds simple functions and strings processing,
-	// but not Unicode tables.
-	"math":          {"unsafe"},
-	"math/cmplx":    {"math"},
-	"math/rand":     {"L0", "math"},
-	"sort":          {},
-	"strconv":       {"L0", "unicode/utf8", "math"},
-	"unicode/utf16": {},
-	"unicode/utf8":  {},
-
-	"L1": {
-		"L0",
-		"math",
-		"math/cmplx",
-		"math/rand",
-		"sort",
-		"strconv",
-		"unicode/utf16",
-		"unicode/utf8",
-	},
-
-	// L2 adds Unicode and strings processing.
-	"bufio":   {"L0", "unicode/utf8", "bytes"},
-	"bytes":   {"L0", "unicode", "unicode/utf8"},
-	"path":    {"L0", "unicode/utf8", "strings"},
-	"strings": {"L0", "unicode", "unicode/utf8"},
-	"unicode": {},
-
-	"L2": {
-		"L1",
-		"bufio",
-		"bytes",
-		"path",
-		"strings",
-		"unicode",
-	},
-
-	// L3 adds reflection and some basic utility packages
-	// and interface definitions, but nothing that makes
-	// system calls.
-	"crypto":              {"L2", "hash"},          // interfaces
-	"crypto/cipher":       {"L2", "crypto/subtle"}, // interfaces
-	"crypto/subtle":       {},
-	"encoding/base32":     {"L2"},
-	"encoding/base64":     {"L2"},
-	"encoding/binary":     {"L2", "reflect"},
-	"hash":                {"L2"}, // interfaces
-	"hash/adler32":        {"L2", "hash"},
-	"hash/crc32":          {"L2", "hash"},
-	"hash/crc64":          {"L2", "hash"},
-	"hash/fnv":            {"L2", "hash"},
-	"image":               {"L2", "image/color"}, // interfaces
-	"image/color":         {"L2"},                // interfaces
-	"image/color/palette": {"L2", "image/color"},
-	"reflect":             {"L2"},
-
-	"L3": {
-		"L2",
-		"crypto",
-		"crypto/cipher",
-		"crypto/subtle",
-		"encoding/base32",
-		"encoding/base64",
-		"encoding/binary",
-		"hash",
-		"hash/adler32",
-		"hash/crc32",
-		"hash/crc64",
-		"hash/fnv",
-		"image",
-		"image/color",
-		"image/color/palette",
-		"reflect",
-	},
-
-	// End of linear dependency definitions.
-
-	// Operating system access.
-	"syscall":       {"L0", "unicode/utf16"},
-	"time":          {"L0", "syscall"},
-	"os":            {"L1", "os", "syscall", "time"},
-	"path/filepath": {"L2", "os", "syscall"},
-	"io/ioutil":     {"L2", "os", "path/filepath", "time"},
-	"os/exec":       {"L2", "os", "path/filepath", "syscall"},
-	"os/signal":     {"L2", "os", "syscall"},
-
-	// OS enables basic operating system functionality,
-	// but not direct use of package syscall, nor os/signal.
-	"OS": {
-		"io/ioutil",
-		"os",
-		"os/exec",
-		"path/filepath",
-		"time",
-	},
-
-	// Formatted I/O: few dependencies (L1) but we must add reflect.
-	"fmt": {"L1", "os", "reflect"},
-	"log": {"L1", "os", "fmt", "time"},
-
-	// Packages used by testing must be low-level (L2+fmt).
-	"regexp":         {"L2", "regexp/syntax"},
-	"regexp/syntax":  {"L2"},
-	"runtime/debug":  {"L2", "fmt", "io/ioutil", "os", "time"},
-	"runtime/pprof":  {"L2", "fmt", "text/tabwriter"},
-	"text/tabwriter": {"L2"},
-
-	"testing":        {"L2", "flag", "fmt", "os", "runtime/pprof", "time"},
-	"testing/iotest": {"L2", "log"},
-	"testing/quick":  {"L2", "flag", "fmt", "reflect"},
-
-	// L4 is defined as L3+fmt+log+time, because in general once
-	// you're using L3 packages, use of fmt, log, or time is not a big deal.
-	"L4": {
-		"L3",
-		"fmt",
-		"log",
-		"time",
-	},
-
-	// Go parser.
-	"go/ast":     {"L4", "OS", "go/scanner", "go/token"},
-	"go/doc":     {"L4", "go/ast", "go/token", "regexp", "text/template"},
-	"go/parser":  {"L4", "OS", "go/ast", "go/scanner", "go/token"},
-	"go/printer": {"L4", "OS", "go/ast", "go/scanner", "go/token", "text/tabwriter"},
-	"go/scanner": {"L4", "OS", "go/token"},
-	"go/token":   {"L4"},
-
-	"GOPARSER": {
-		"go/ast",
-		"go/doc",
-		"go/parser",
-		"go/printer",
-		"go/scanner",
-		"go/token",
-	},
-
-	// One of a kind.
-	"archive/tar":         {"L4", "OS", "syscall"},
-	"archive/zip":         {"L4", "OS", "compress/flate"},
-	"compress/bzip2":      {"L4"},
-	"compress/flate":      {"L4"},
-	"compress/gzip":       {"L4", "compress/flate"},
-	"compress/lzw":        {"L4"},
-	"compress/zlib":       {"L4", "compress/flate"},
-	"database/sql":        {"L4", "container/list", "database/sql/driver"},
-	"database/sql/driver": {"L4", "time"},
-	"debug/dwarf":         {"L4"},
-	"debug/elf":           {"L4", "OS", "debug/dwarf"},
-	"debug/gosym":         {"L4"},
-	"debug/macho":         {"L4", "OS", "debug/dwarf"},
-	"debug/pe":            {"L4", "OS", "debug/dwarf"},
-	"encoding":            {"L4"},
-	"encoding/ascii85":    {"L4"},
-	"encoding/asn1":       {"L4", "math/big"},
-	"encoding/csv":        {"L4"},
-	"encoding/gob":        {"L4", "OS", "encoding"},
-	"encoding/hex":        {"L4"},
-	"encoding/json":       {"L4", "encoding"},
-	"encoding/pem":        {"L4"},
-	"encoding/xml":        {"L4", "encoding"},
-	"flag":                {"L4", "OS"},
-	"go/build":            {"L4", "OS", "GOPARSER"},
-	"html":                {"L4"},
-	"image/draw":          {"L4"},
-	"image/gif":           {"L4", "compress/lzw", "image/color/palette", "image/draw"},
-	"image/jpeg":          {"L4"},
-	"image/png":           {"L4", "compress/zlib"},
-	"index/suffixarray":   {"L4", "regexp"},
-	"math/big":            {"L4"},
-	"mime":                {"L4", "OS", "syscall"},
-	"net/url":             {"L4"},
-	"text/scanner":        {"L4", "OS"},
-	"text/template/parse": {"L4"},
-
-	"html/template": {
-		"L4", "OS", "encoding/json", "html", "text/template",
-		"text/template/parse",
-	},
-	"text/template": {
-		"L4", "OS", "net/url", "text/template/parse",
-	},
-
-	// Cgo.
-	"runtime/cgo": {"L0", "C"},
-	"CGO":         {"C", "runtime/cgo"},
-
-	// Fake entry to satisfy the pseudo-import "C"
-	// that shows up in programs that use cgo.
-	"C": {},
-
-	// Plan 9 alone needs io/ioutil and os.
-	"os/user": {"L4", "CGO", "io/ioutil", "os", "syscall"},
-
-	// Basic networking.
-	// Because net must be used by any package that wants to
-	// do networking portably, it must have a small dependency set: just L1+basic os.
-	"net": {"L1", "CGO", "os", "syscall", "time"},
-
-	// NET enables use of basic network-related packages.
-	"NET": {
-		"net",
-		"mime",
-		"net/textproto",
-		"net/url",
-	},
-
-	// Uses of networking.
-	"log/syslog":    {"L4", "OS", "net"},
-	"net/mail":      {"L4", "NET", "OS"},
-	"net/textproto": {"L4", "OS", "net"},
-
-	// Core crypto.
-	"crypto/aes":    {"L3"},
-	"crypto/des":    {"L3"},
-	"crypto/hmac":   {"L3"},
-	"crypto/md5":    {"L3"},
-	"crypto/rc4":    {"L3"},
-	"crypto/sha1":   {"L3"},
-	"crypto/sha256": {"L3"},
-	"crypto/sha512": {"L3"},
-
-	"CRYPTO": {
-		"crypto/aes",
-		"crypto/des",
-		"crypto/hmac",
-		"crypto/md5",
-		"crypto/rc4",
-		"crypto/sha1",
-		"crypto/sha256",
-		"crypto/sha512",
-	},
-
-	// Random byte, number generation.
-	// This would be part of core crypto except that it imports
-	// math/big, which imports fmt.
-	"crypto/rand": {"L4", "CRYPTO", "OS", "math/big", "syscall"},
-
-	// Mathematical crypto: dependencies on fmt (L4) and math/big.
-	// We could avoid some of the fmt, but math/big imports fmt anyway.
-	"crypto/dsa":      {"L4", "CRYPTO", "math/big"},
-	"crypto/ecdsa":    {"L4", "CRYPTO", "crypto/elliptic", "math/big"},
-	"crypto/elliptic": {"L4", "CRYPTO", "math/big"},
-	"crypto/rsa":      {"L4", "CRYPTO", "crypto/rand", "math/big"},
-
-	"CRYPTO-MATH": {
-		"CRYPTO",
-		"crypto/dsa",
-		"crypto/ecdsa",
-		"crypto/elliptic",
-		"crypto/rand",
-		"crypto/rsa",
-		"encoding/asn1",
-		"math/big",
-	},
-
-	// SSL/TLS.
-	"crypto/tls": {
-		"L4", "CRYPTO-MATH", "CGO", "OS",
-		"container/list", "crypto/x509", "encoding/pem", "net", "syscall",
-	},
-	"crypto/x509": {
-		"L4", "CRYPTO-MATH", "OS", "CGO",
-		"crypto/x509/pkix", "encoding/pem", "encoding/hex", "net", "syscall",
-	},
-	"crypto/x509/pkix": {"L4", "CRYPTO-MATH"},
-
-	// Simple net+crypto-aware packages.
-	"mime/multipart": {"L4", "OS", "mime", "crypto/rand", "net/textproto"},
-	"net/smtp":       {"L4", "CRYPTO", "NET", "crypto/tls"},
-
-	// HTTP, kingpin of dependencies.
-	"net/http": {
-		"L4", "NET", "OS",
-		"compress/gzip", "crypto/tls", "mime/multipart", "runtime/debug",
-	},
-
-	// HTTP-using packages.
-	"expvar":            {"L4", "OS", "encoding/json", "net/http"},
-	"net/http/cgi":      {"L4", "NET", "OS", "crypto/tls", "net/http", "regexp"},
-	"net/http/fcgi":     {"L4", "NET", "OS", "net/http", "net/http/cgi"},
-	"net/http/httptest": {"L4", "NET", "OS", "crypto/tls", "flag", "net/http"},
-	"net/http/httputil": {"L4", "NET", "OS", "net/http"},
-	"net/http/pprof":    {"L4", "OS", "html/template", "net/http", "runtime/pprof"},
-	"net/rpc":           {"L4", "NET", "encoding/gob", "net/http", "text/template"},
-	"net/rpc/jsonrpc":   {"L4", "NET", "encoding/json", "net/rpc"},
-}
-
-// isMacro reports whether p is a package dependency macro
-// (uppercase name).
-func isMacro(p string) bool {
-	return 'A' <= p[0] && p[0] <= 'Z'
-}
-
-func allowed(pkg string) map[string]bool {
-	m := map[string]bool{}
-	var allow func(string)
-	allow = func(p string) {
-		if m[p] {
-			return
-		}
-		m[p] = true // set even for macros, to avoid loop on cycle
-
-		// Upper-case names are macro-expanded.
-		if isMacro(p) {
-			for _, pp := range pkgDeps[p] {
-				allow(pp)
-			}
-		}
-	}
-	for _, pp := range pkgDeps[pkg] {
-		allow(pp)
-	}
-	return m
-}
-
-var bools = []bool{false, true}
-var geese = []string{"darwin", "dragonfly", "freebsd", "linux", "nacl", "netbsd", "openbsd", "plan9", "solaris", "windows"}
-var goarches = []string{"386", "amd64", "arm"}
-
-type osPkg struct {
-	goos, pkg string
-}
-
-// allowedErrors are the operating systems and packages known to contain errors
-// (currently just "no Go source files")
-var allowedErrors = map[osPkg]bool{
-	osPkg{"windows", "log/syslog"}: true,
-	osPkg{"plan9", "log/syslog"}:   true,
-}
-
-func TestDependencies(t *testing.T) {
-	if runtime.GOOS == "nacl" {
-		// NaCl tests run in a limited file system and we do not
-		// provide access to every source file.
-		t.Skip("skipping on NaCl")
-	}
-	var all []string
-
-	for k := range pkgDeps {
-		all = append(all, k)
-	}
-	sort.Strings(all)
-
-	ctxt := Default
-	test := func(mustImport bool) {
-		for _, pkg := range all {
-			if isMacro(pkg) {
-				continue
-			}
-			if pkg == "runtime/cgo" && !ctxt.CgoEnabled {
-				continue
-			}
-			p, err := ctxt.Import(pkg, "", 0)
-			if err != nil {
-				if allowedErrors[osPkg{ctxt.GOOS, pkg}] {
-					continue
-				}
-				if !ctxt.CgoEnabled && pkg == "runtime/cgo" {
-					continue
-				}
-				// Some of the combinations we try might not
-				// be reasonable (like arm,plan9,cgo), so ignore
-				// errors for the auto-generated combinations.
-				if !mustImport {
-					continue
-				}
-				t.Errorf("%s/%s/cgo=%v %v", ctxt.GOOS, ctxt.GOARCH, ctxt.CgoEnabled, err)
-				continue
-			}
-			ok := allowed(pkg)
-			var bad []string
-			for _, imp := range p.Imports {
-				if !ok[imp] {
-					bad = append(bad, imp)
-				}
-			}
-			if bad != nil {
-				t.Errorf("%s/%s/cgo=%v unexpected dependency: %s imports %v", ctxt.GOOS, ctxt.GOARCH, ctxt.CgoEnabled, pkg, bad)
-			}
-		}
-	}
-	test(true)
-
-	if testing.Short() {
-		t.Logf("skipping other systems")
-		return
-	}
-
-	for _, ctxt.GOOS = range geese {
-		for _, ctxt.GOARCH = range goarches {
-			for _, ctxt.CgoEnabled = range bools {
-				test(false)
-			}
-		}
-	}
-}
diff --git a/src/pkg/go/build/doc.go b/src/pkg/go/build/doc.go
deleted file mode 100644
index f17f76c..0000000
--- a/src/pkg/go/build/doc.go
+++ /dev/null
@@ -1,137 +0,0 @@
-// Copyright 2011 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package build gathers information about Go packages.
-//
-// Go Path
-//
-// The Go path is a list of directory trees containing Go source code.
-// It is consulted to resolve imports that cannot be found in the standard
-// Go tree.  The default path is the value of the GOPATH environment
-// variable, interpreted as a path list appropriate to the operating system
-// (on Unix, the variable is a colon-separated string;
-// on Windows, a semicolon-separated string;
-// on Plan 9, a list).
-//
-// Each directory listed in the Go path must have a prescribed structure:
-//
-// The src/ directory holds source code.  The path below 'src' determines
-// the import path or executable name.
-//
-// The pkg/ directory holds installed package objects.
-// As in the Go tree, each target operating system and
-// architecture pair has its own subdirectory of pkg
-// (pkg/GOOS_GOARCH).
-//
-// If DIR is a directory listed in the Go path, a package with
-// source in DIR/src/foo/bar can be imported as "foo/bar" and
-// has its compiled form installed to "DIR/pkg/GOOS_GOARCH/foo/bar.a"
-// (or, for gccgo, "DIR/pkg/gccgo/foo/libbar.a").
-//
-// The bin/ directory holds compiled commands.
-// Each command is named for its source directory, but only
-// using the final element, not the entire path.  That is, the
-// command with source in DIR/src/foo/quux is installed into
-// DIR/bin/quux, not DIR/bin/foo/quux.  The foo/ is stripped
-// so that you can add DIR/bin to your PATH to get at the
-// installed commands.
-//
-// Here's an example directory layout:
-//
-//	GOPATH=/home/user/gocode
-//
-//	/home/user/gocode/
-//	    src/
-//	        foo/
-//	            bar/               (go code in package bar)
-//	                x.go
-//	            quux/              (go code in package main)
-//	                y.go
-//	    bin/
-//	        quux                   (installed command)
-//	    pkg/
-//	        linux_amd64/
-//	            foo/
-//	                bar.a          (installed package object)
-//
-// Build Constraints
-//
-// A build constraint, also known as a build tag, is a line comment that begins
-//
-//	// +build
-//
-// that lists the conditions under which a file should be included in the package.
-// Constraints may appear in any kind of source file (not just Go), but
-// they must appear near the top of the file, preceded
-// only by blank lines and other line comments. These rules mean that in Go
-// files a build constraint must appear before the package clause.
-//
-// To distinguish build constraints from package documentation, a series of
-// build constraints must be followed by a blank line.
-//
-// A build constraint is evaluated as the OR of space-separated options;
-// each option evaluates as the AND of its comma-separated terms;
-// and each term is an alphanumeric word or, preceded by !, its negation.
-// That is, the build constraint:
-//
-//	// +build linux,386 darwin,!cgo
-//
-// corresponds to the boolean formula:
-//
-//	(linux AND 386) OR (darwin AND (NOT cgo))
-//
-// A file may have multiple build constraints. The overall constraint is the AND
-// of the individual constraints. That is, the build constraints:
-//
-//	// +build linux darwin
-//	// +build 386
-//
-// corresponds to the boolean formula:
-//
-//	(linux OR darwin) AND 386
-//
-// During a particular build, the following words are satisfied:
-//
-//	- the target operating system, as spelled by runtime.GOOS
-//	- the target architecture, as spelled by runtime.GOARCH
-//	- the compiler being used, either "gc" or "gccgo"
-//	- "cgo", if ctxt.CgoEnabled is true
-//	- "go1.1", from Go version 1.1 onward
-//	- "go1.2", from Go version 1.2 onward
-//	- "go1.3", from Go version 1.3 onward
-//	- any additional words listed in ctxt.BuildTags
-//
-// If a file's name, after stripping the extension and a possible _test suffix,
-// matches any of the following patterns:
-//	*_GOOS
-// 	*_GOARCH
-// 	*_GOOS_GOARCH
-// (example: source_windows_amd64.go) or the literals:
-//	GOOS
-// 	GOARCH
-// (example: windows.go) where GOOS and GOARCH represent any known operating
-// system and architecture values respectively, then the file is considered to
-// have an implicit build constraint requiring those terms.
-//
-// To keep a file from being considered for the build:
-//
-//	// +build ignore
-//
-// (any other unsatisfied word will work as well, but ``ignore'' is conventional.)
-//
-// To build a file only when using cgo, and only on Linux and OS X:
-//
-//	// +build linux,cgo darwin,cgo
-//
-// Such a file is usually paired with another file implementing the
-// default functionality for other systems, which in this case would
-// carry the constraint:
-//
-//	// +build !linux,!darwin !cgo
-//
-// Naming a file dns_windows.go will cause it to be included only when
-// building the package for Windows; similarly, math_386.s will be included
-// only when building the package for 32-bit x86.
-//
-package build
diff --git a/src/pkg/go/build/syslist.go b/src/pkg/go/build/syslist.go
deleted file mode 100644
index 5c42b94..0000000
--- a/src/pkg/go/build/syslist.go
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright 2011 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package build
-
-const goosList = "darwin dragonfly freebsd linux nacl netbsd openbsd plan9 solaris windows "
-const goarchList = "386 amd64 amd64p32 arm "
diff --git a/src/pkg/go/doc/exports.go b/src/pkg/go/doc/exports.go
deleted file mode 100644
index ff01285..0000000
--- a/src/pkg/go/doc/exports.go
+++ /dev/null
@@ -1,199 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// This file implements export filtering of an AST.
-
-package doc
-
-import "go/ast"
-
-// filterIdentList removes unexported names from list in place
-// and returns the resulting list.
-//
-func filterIdentList(list []*ast.Ident) []*ast.Ident {
-	j := 0
-	for _, x := range list {
-		if ast.IsExported(x.Name) {
-			list[j] = x
-			j++
-		}
-	}
-	return list[0:j]
-}
-
-// removeErrorField removes anonymous fields named "error" from an interface.
-// This is called when "error" has been determined to be a local name,
-// not the predeclared type.
-//
-func removeErrorField(ityp *ast.InterfaceType) {
-	list := ityp.Methods.List // we know that ityp.Methods != nil
-	j := 0
-	for _, field := range list {
-		keepField := true
-		if n := len(field.Names); n == 0 {
-			// anonymous field
-			if fname, _ := baseTypeName(field.Type); fname == "error" {
-				keepField = false
-			}
-		}
-		if keepField {
-			list[j] = field
-			j++
-		}
-	}
-	if j < len(list) {
-		ityp.Incomplete = true
-	}
-	ityp.Methods.List = list[0:j]
-}
-
-// filterFieldList removes unexported fields (field names) from the field list
-// in place and returns true if fields were removed. Anonymous fields are
-// recorded with the parent type. filterType is called with the types of
-// all remaining fields.
-//
-func (r *reader) filterFieldList(parent *namedType, fields *ast.FieldList, ityp *ast.InterfaceType) (removedFields bool) {
-	if fields == nil {
-		return
-	}
-	list := fields.List
-	j := 0
-	for _, field := range list {
-		keepField := false
-		if n := len(field.Names); n == 0 {
-			// anonymous field
-			fname := r.recordAnonymousField(parent, field.Type)
-			if ast.IsExported(fname) {
-				keepField = true
-			} else if ityp != nil && fname == "error" {
-				// possibly the predeclared error interface; keep
-				// it for now but remember this interface so that
-				// it can be fixed if error is also defined locally
-				keepField = true
-				r.remember(ityp)
-			}
-		} else {
-			field.Names = filterIdentList(field.Names)
-			if len(field.Names) < n {
-				removedFields = true
-			}
-			if len(field.Names) > 0 {
-				keepField = true
-			}
-		}
-		if keepField {
-			r.filterType(nil, field.Type)
-			list[j] = field
-			j++
-		}
-	}
-	if j < len(list) {
-		removedFields = true
-	}
-	fields.List = list[0:j]
-	return
-}
-
-// filterParamList applies filterType to each parameter type in fields.
-//
-func (r *reader) filterParamList(fields *ast.FieldList) {
-	if fields != nil {
-		for _, f := range fields.List {
-			r.filterType(nil, f.Type)
-		}
-	}
-}
-
-// filterType strips any unexported struct fields or method types from typ
-// in place. If fields (or methods) have been removed, the corresponding
-// struct or interface type has the Incomplete field set to true.
-//
-func (r *reader) filterType(parent *namedType, typ ast.Expr) {
-	switch t := typ.(type) {
-	case *ast.Ident:
-		// nothing to do
-	case *ast.ParenExpr:
-		r.filterType(nil, t.X)
-	case *ast.ArrayType:
-		r.filterType(nil, t.Elt)
-	case *ast.StructType:
-		if r.filterFieldList(parent, t.Fields, nil) {
-			t.Incomplete = true
-		}
-	case *ast.FuncType:
-		r.filterParamList(t.Params)
-		r.filterParamList(t.Results)
-	case *ast.InterfaceType:
-		if r.filterFieldList(parent, t.Methods, t) {
-			t.Incomplete = true
-		}
-	case *ast.MapType:
-		r.filterType(nil, t.Key)
-		r.filterType(nil, t.Value)
-	case *ast.ChanType:
-		r.filterType(nil, t.Value)
-	}
-}
-
-func (r *reader) filterSpec(spec ast.Spec) bool {
-	switch s := spec.(type) {
-	case *ast.ImportSpec:
-		// always keep imports so we can collect them
-		return true
-	case *ast.ValueSpec:
-		s.Names = filterIdentList(s.Names)
-		if len(s.Names) > 0 {
-			r.filterType(nil, s.Type)
-			return true
-		}
-	case *ast.TypeSpec:
-		if name := s.Name.Name; ast.IsExported(name) {
-			r.filterType(r.lookupType(s.Name.Name), s.Type)
-			return true
-		} else if name == "error" {
-			// special case: remember that error is declared locally
-			r.errorDecl = true
-		}
-	}
-	return false
-}
-
-func (r *reader) filterSpecList(list []ast.Spec) []ast.Spec {
-	j := 0
-	for _, s := range list {
-		if r.filterSpec(s) {
-			list[j] = s
-			j++
-		}
-	}
-	return list[0:j]
-}
-
-func (r *reader) filterDecl(decl ast.Decl) bool {
-	switch d := decl.(type) {
-	case *ast.GenDecl:
-		d.Specs = r.filterSpecList(d.Specs)
-		return len(d.Specs) > 0
-	case *ast.FuncDecl:
-		// ok to filter these methods early because any
-		// conflicting method will be filtered here, too -
-		// thus, removing these methods early will not lead
-		// to the false removal of possible conflicts
-		return ast.IsExported(d.Name.Name)
-	}
-	return false
-}
-
-// fileExports removes unexported declarations from src in place.
-//
-func (r *reader) fileExports(src *ast.File) {
-	j := 0
-	for _, d := range src.Decls {
-		if r.filterDecl(d) {
-			src.Decls[j] = d
-			j++
-		}
-	}
-	src.Decls = src.Decls[0:j]
-}
diff --git a/src/pkg/go/doc/headscan.go b/src/pkg/go/doc/headscan.go
deleted file mode 100644
index f559347..0000000
--- a/src/pkg/go/doc/headscan.go
+++ /dev/null
@@ -1,113 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build ignore
-
-/*
-	The headscan command extracts comment headings from package files;
-	it is used to detect false positives which may require an adjustment
-	to the comment formatting heuristics in comment.go.
-
-	Usage: headscan [-root root_directory]
-
-	By default, the $GOROOT/src directory is scanned.
-*/
-package main
-
-import (
-	"bytes"
-	"flag"
-	"fmt"
-	"go/doc"
-	"go/parser"
-	"go/token"
-	"os"
-	"path/filepath"
-	"runtime"
-	"strings"
-)
-
-var (
-	root    = flag.String("root", filepath.Join(runtime.GOROOT(), "src"), "root of filesystem tree to scan")
-	verbose = flag.Bool("v", false, "verbose mode")
-)
-
-const (
-	html_h    = "<h3>"
-	html_endh = "</h3>\n"
-)
-
-func isGoFile(fi os.FileInfo) bool {
-	return strings.HasSuffix(fi.Name(), ".go") &&
-		!strings.HasSuffix(fi.Name(), "_test.go")
-}
-
-func appendHeadings(list []string, comment string) []string {
-	var buf bytes.Buffer
-	doc.ToHTML(&buf, comment, nil)
-	for s := buf.String(); ; {
-		i := strings.Index(s, html_h)
-		if i < 0 {
-			break
-		}
-		i += len(html_h)
-		j := strings.Index(s, html_endh)
-		if j < 0 {
-			list = append(list, s[i:]) // incorrect HTML
-			break
-		}
-		list = append(list, s[i:j])
-		s = s[j+len(html_endh):]
-	}
-	return list
-}
-
-func main() {
-	flag.Parse()
-	fset := token.NewFileSet()
-	nheadings := 0
-	err := filepath.Walk(*root, func(path string, fi os.FileInfo, err error) error {
-		if !fi.IsDir() {
-			return nil
-		}
-		pkgs, err := parser.ParseDir(fset, path, isGoFile, parser.ParseComments)
-		if err != nil {
-			if *verbose {
-				fmt.Fprintln(os.Stderr, err)
-			}
-			return nil
-		}
-		for _, pkg := range pkgs {
-			d := doc.New(pkg, path, doc.Mode(0))
-			list := appendHeadings(nil, d.Doc)
-			for _, d := range d.Consts {
-				list = appendHeadings(list, d.Doc)
-			}
-			for _, d := range d.Types {
-				list = appendHeadings(list, d.Doc)
-			}
-			for _, d := range d.Vars {
-				list = appendHeadings(list, d.Doc)
-			}
-			for _, d := range d.Funcs {
-				list = appendHeadings(list, d.Doc)
-			}
-			if len(list) > 0 {
-				// directories may contain multiple packages;
-				// print path and package name
-				fmt.Printf("%s (package %s)\n", path, pkg.Name)
-				for _, h := range list {
-					fmt.Printf("\t%s\n", h)
-				}
-				nheadings += len(list)
-			}
-		}
-		return nil
-	})
-	if err != nil {
-		fmt.Fprintln(os.Stderr, err)
-		os.Exit(1)
-	}
-	fmt.Println(nheadings, "headings found")
-}
diff --git a/src/pkg/go/format/format.go b/src/pkg/go/format/format.go
deleted file mode 100644
index 3d00a64..0000000
--- a/src/pkg/go/format/format.go
+++ /dev/null
@@ -1,199 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package format implements standard formatting of Go source.
-package format
-
-import (
-	"bytes"
-	"fmt"
-	"go/ast"
-	"go/parser"
-	"go/printer"
-	"go/token"
-	"io"
-	"strings"
-)
-
-var config = printer.Config{Mode: printer.UseSpaces | printer.TabIndent, Tabwidth: 8}
-
-// Node formats node in canonical gofmt style and writes the result to dst.
-//
-// The node type must be *ast.File, *printer.CommentedNode, []ast.Decl,
-// []ast.Stmt, or assignment-compatible to ast.Expr, ast.Decl, ast.Spec,
-// or ast.Stmt. Node does not modify node. Imports are not sorted for
-// nodes representing partial source files (i.e., if the node is not an
-// *ast.File or a *printer.CommentedNode not wrapping an *ast.File).
-//
-// The function may return early (before the entire result is written)
-// and return a formatting error, for instance due to an incorrect AST.
-//
-func Node(dst io.Writer, fset *token.FileSet, node interface{}) error {
-	// Determine if we have a complete source file (file != nil).
-	var file *ast.File
-	var cnode *printer.CommentedNode
-	switch n := node.(type) {
-	case *ast.File:
-		file = n
-	case *printer.CommentedNode:
-		if f, ok := n.Node.(*ast.File); ok {
-			file = f
-			cnode = n
-		}
-	}
-
-	// Sort imports if necessary.
-	if file != nil && hasUnsortedImports(file) {
-		// Make a copy of the AST because ast.SortImports is destructive.
-		// TODO(gri) Do this more efficiently.
-		var buf bytes.Buffer
-		err := config.Fprint(&buf, fset, file)
-		if err != nil {
-			return err
-		}
-		file, err = parser.ParseFile(fset, "", buf.Bytes(), parser.ParseComments)
-		if err != nil {
-			// We should never get here. If we do, provide good diagnostic.
-			return fmt.Errorf("format.Node internal error (%s)", err)
-		}
-		ast.SortImports(fset, file)
-
-		// Use new file with sorted imports.
-		node = file
-		if cnode != nil {
-			node = &printer.CommentedNode{Node: file, Comments: cnode.Comments}
-		}
-	}
-
-	return config.Fprint(dst, fset, node)
-}
-
-// Source formats src in canonical gofmt style and returns the result
-// or an (I/O or syntax) error. src is expected to be a syntactically
-// correct Go source file, or a list of Go declarations or statements.
-//
-// If src is a partial source file, the leading and trailing space of src
-// is applied to the result (such that it has the same leading and trailing
-// space as src), and the result is indented by the same amount as the first
-// line of src containing code. Imports are not sorted for partial source files.
-//
-func Source(src []byte) ([]byte, error) {
-	fset := token.NewFileSet()
-	node, err := parse(fset, src)
-	if err != nil {
-		return nil, err
-	}
-
-	var buf bytes.Buffer
-	if file, ok := node.(*ast.File); ok {
-		// Complete source file.
-		ast.SortImports(fset, file)
-		err := config.Fprint(&buf, fset, file)
-		if err != nil {
-			return nil, err
-		}
-
-	} else {
-		// Partial source file.
-		// Determine and prepend leading space.
-		i, j := 0, 0
-		for j < len(src) && isSpace(src[j]) {
-			if src[j] == '\n' {
-				i = j + 1 // index of last line in leading space
-			}
-			j++
-		}
-		buf.Write(src[:i])
-
-		// Determine indentation of first code line.
-		// Spaces are ignored unless there are no tabs,
-		// in which case spaces count as one tab.
-		indent := 0
-		hasSpace := false
-		for _, b := range src[i:j] {
-			switch b {
-			case ' ':
-				hasSpace = true
-			case '\t':
-				indent++
-			}
-		}
-		if indent == 0 && hasSpace {
-			indent = 1
-		}
-
-		// Format the source.
-		cfg := config
-		cfg.Indent = indent
-		err := cfg.Fprint(&buf, fset, node)
-		if err != nil {
-			return nil, err
-		}
-
-		// Determine and append trailing space.
-		i = len(src)
-		for i > 0 && isSpace(src[i-1]) {
-			i--
-		}
-		buf.Write(src[i:])
-	}
-
-	return buf.Bytes(), nil
-}
-
-func hasUnsortedImports(file *ast.File) bool {
-	for _, d := range file.Decls {
-		d, ok := d.(*ast.GenDecl)
-		if !ok || d.Tok != token.IMPORT {
-			// Not an import declaration, so we're done.
-			// Imports are always first.
-			return false
-		}
-		if d.Lparen.IsValid() {
-			// For now assume all grouped imports are unsorted.
-			// TODO(gri) Should check if they are sorted already.
-			return true
-		}
-		// Ungrouped imports are sorted by default.
-	}
-	return false
-}
-
-func isSpace(b byte) bool {
-	return b == ' ' || b == '\t' || b == '\n' || b == '\r'
-}
-
-func parse(fset *token.FileSet, src []byte) (interface{}, error) {
-	// Try as a complete source file.
-	file, err := parser.ParseFile(fset, "", src, parser.ParseComments)
-	if err == nil {
-		return file, nil
-	}
-	// If the source is missing a package clause, try as a source fragment; otherwise fail.
-	if !strings.Contains(err.Error(), "expected 'package'") {
-		return nil, err
-	}
-
-	// Try as a declaration list by prepending a package clause in front of src.
-	// Use ';' not '\n' to keep line numbers intact.
-	psrc := append([]byte("package p;"), src...)
-	file, err = parser.ParseFile(fset, "", psrc, parser.ParseComments)
-	if err == nil {
-		return file.Decls, nil
-	}
-	// If the source is missing a declaration, try as a statement list; otherwise fail.
-	if !strings.Contains(err.Error(), "expected declaration") {
-		return nil, err
-	}
-
-	// Try as statement list by wrapping a function around src.
-	fsrc := append(append([]byte("package p; func _() {"), src...), '}')
-	file, err = parser.ParseFile(fset, "", fsrc, parser.ParseComments)
-	if err == nil {
-		return file.Decls[0].(*ast.FuncDecl).Body.List, nil
-	}
-
-	// Failed, and out of options.
-	return nil, err
-}
diff --git a/src/pkg/go/format/format_test.go b/src/pkg/go/format/format_test.go
deleted file mode 100644
index 93f0992..0000000
--- a/src/pkg/go/format/format_test.go
+++ /dev/null
@@ -1,124 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package format
-
-import (
-	"bytes"
-	"go/parser"
-	"go/token"
-	"io/ioutil"
-	"strings"
-	"testing"
-)
-
-const testfile = "format_test.go"
-
-func diff(t *testing.T, dst, src []byte) {
-	line := 1
-	offs := 0 // line offset
-	for i := 0; i < len(dst) && i < len(src); i++ {
-		d := dst[i]
-		s := src[i]
-		if d != s {
-			t.Errorf("dst:%d: %s\n", line, dst[offs:i+1])
-			t.Errorf("src:%d: %s\n", line, src[offs:i+1])
-			return
-		}
-		if s == '\n' {
-			line++
-			offs = i + 1
-		}
-	}
-	if len(dst) != len(src) {
-		t.Errorf("len(dst) = %d, len(src) = %d\nsrc = %q", len(dst), len(src), src)
-	}
-}
-
-func TestNode(t *testing.T) {
-	src, err := ioutil.ReadFile(testfile)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	fset := token.NewFileSet()
-	file, err := parser.ParseFile(fset, testfile, src, parser.ParseComments)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	var buf bytes.Buffer
-
-	if err = Node(&buf, fset, file); err != nil {
-		t.Fatal("Node failed:", err)
-	}
-
-	diff(t, buf.Bytes(), src)
-}
-
-func TestSource(t *testing.T) {
-	src, err := ioutil.ReadFile(testfile)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	res, err := Source(src)
-	if err != nil {
-		t.Fatal("Source failed:", err)
-	}
-
-	diff(t, res, src)
-}
-
-// Test cases that are expected to fail are marked by the prefix "ERROR".
-var tests = []string{
-	// declaration lists
-	`import "go/format"`,
-	"var x int",
-	"var x int\n\ntype T struct{}",
-
-	// statement lists
-	"x := 0",
-	"f(a, b, c)\nvar x int = f(1, 2, 3)",
-
-	// indentation, leading and trailing space
-	"\tx := 0\n\tgo f()",
-	"\tx := 0\n\tgo f()\n\n\n",
-	"\n\t\t\n\n\tx := 0\n\tgo f()\n\n\n",
-	"\n\t\t\n\n\t\t\tx := 0\n\t\t\tgo f()\n\n\n",
-	"\n\t\t\n\n\t\t\tx := 0\n\t\t\tconst s = `\nfoo\n`\n\n\n", // no indentation inside raw strings
-
-	// erroneous programs
-	"ERROR1 + 2 +",
-	"ERRORx :=  0",
-}
-
-func String(s string) (string, error) {
-	res, err := Source([]byte(s))
-	if err != nil {
-		return "", err
-	}
-	return string(res), nil
-}
-
-func TestPartial(t *testing.T) {
-	for _, src := range tests {
-		if strings.HasPrefix(src, "ERROR") {
-			// test expected to fail
-			src = src[5:] // remove ERROR prefix
-			res, err := String(src)
-			if err == nil && res == src {
-				t.Errorf("formatting succeeded but was expected to fail:\n%q", src)
-			}
-		} else {
-			// test expected to succeed
-			res, err := String(src)
-			if err != nil {
-				t.Errorf("formatting failed (%s):\n%q", err, src)
-			} else if res != src {
-				t.Errorf("formatting incorrect:\nsource: %q\nresult: %q", src, res)
-			}
-		}
-	}
-}
diff --git a/src/pkg/go/parser/error_test.go b/src/pkg/go/parser/error_test.go
deleted file mode 100644
index 8506077..0000000
--- a/src/pkg/go/parser/error_test.go
+++ /dev/null
@@ -1,183 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// This file implements a parser test harness. The files in the testdata
-// directory are parsed and the errors reported are compared against the
-// error messages expected in the test files. The test files must end in
-// .src rather than .go so that they are not disturbed by gofmt runs.
-//
-// Expected errors are indicated in the test files by putting a comment
-// of the form /* ERROR "rx" */ immediately following an offending token.
-// The harness will verify that an error matching the regular expression
-// rx is reported at that source position.
-//
-// For instance, the following test file indicates that a "not declared"
-// error should be reported for the undeclared variable x:
-//
-//	package p
-//	func f() {
-//		_ = x /* ERROR "not declared" */ + 1
-//	}
-
-package parser
-
-import (
-	"go/scanner"
-	"go/token"
-	"io/ioutil"
-	"path/filepath"
-	"regexp"
-	"strings"
-	"testing"
-)
-
-const testdata = "testdata"
-
-var fsetErrs *token.FileSet
-
-// getFile assumes that each filename occurs at most once
-func getFile(filename string) (file *token.File) {
-	fsetErrs.Iterate(func(f *token.File) bool {
-		if f.Name() == filename {
-			if file != nil {
-				panic(filename + " used multiple times")
-			}
-			file = f
-		}
-		return true
-	})
-	return file
-}
-
-func getPos(filename string, offset int) token.Pos {
-	if f := getFile(filename); f != nil {
-		return f.Pos(offset)
-	}
-	return token.NoPos
-}
-
-// ERROR comments must be of the form /* ERROR "rx" */ and rx is
-// a regular expression that matches the expected error message.
-// The special form /* ERROR HERE "rx" */ must be used for error
-// messages that appear immediately after a token, rather than at
-// a token's position.
-//
-var errRx = regexp.MustCompile(`^/\* *ERROR *(HERE)? *"([^"]*)" *\*/$`)
-
-// expectedErrors collects the regular expressions of ERROR comments found
-// in files and returns them as a map of error positions to error messages.
-//
-func expectedErrors(t *testing.T, filename string, src []byte) map[token.Pos]string {
-	errors := make(map[token.Pos]string)
-
-	var s scanner.Scanner
-	// file was parsed already - do not add it again to the file
-	// set otherwise the position information returned here will
-	// not match the position information collected by the parser
-	s.Init(getFile(filename), src, nil, scanner.ScanComments)
-	var prev token.Pos // position of last non-comment, non-semicolon token
-	var here token.Pos // position immediately after the token at position prev
-
-	for {
-		pos, tok, lit := s.Scan()
-		switch tok {
-		case token.EOF:
-			return errors
-		case token.COMMENT:
-			s := errRx.FindStringSubmatch(lit)
-			if len(s) == 3 {
-				pos := prev
-				if s[1] == "HERE" {
-					pos = here
-				}
-				errors[pos] = string(s[2])
-			}
-		default:
-			prev = pos
-			var l int // token length
-			if tok.IsLiteral() {
-				l = len(lit)
-			} else {
-				l = len(tok.String())
-			}
-			here = prev + token.Pos(l)
-		}
-	}
-}
-
-// compareErrors compares the map of expected error messages with the list
-// of found errors and reports discrepancies.
-//
-func compareErrors(t *testing.T, expected map[token.Pos]string, found scanner.ErrorList) {
-	for _, error := range found {
-		// error.Pos is a token.Position, but we want
-		// a token.Pos so we can do a map lookup
-		pos := getPos(error.Pos.Filename, error.Pos.Offset)
-		if msg, found := expected[pos]; found {
-			// we expect a message at pos; check if it matches
-			rx, err := regexp.Compile(msg)
-			if err != nil {
-				t.Errorf("%s: %v", error.Pos, err)
-				continue
-			}
-			if match := rx.MatchString(error.Msg); !match {
-				t.Errorf("%s: %q does not match %q", error.Pos, error.Msg, msg)
-				continue
-			}
-			// we have a match - eliminate this error
-			delete(expected, pos)
-		} else {
-			// To keep in mind when analyzing failed test output:
-			// If the same error position occurs multiple times in errors,
-			// this message will be triggered (because the first error at
-			// the position removes this position from the expected errors).
-			t.Errorf("%s: unexpected error: %s", error.Pos, error.Msg)
-		}
-	}
-
-	// there should be no expected errors left
-	if len(expected) > 0 {
-		t.Errorf("%d errors not reported:", len(expected))
-		for pos, msg := range expected {
-			t.Errorf("%s: %s\n", fsetErrs.Position(pos), msg)
-		}
-	}
-}
-
-func checkErrors(t *testing.T, filename string, input interface{}) {
-	src, err := readSource(filename, input)
-	if err != nil {
-		t.Error(err)
-		return
-	}
-
-	_, err = ParseFile(fsetErrs, filename, src, DeclarationErrors|AllErrors)
-	found, ok := err.(scanner.ErrorList)
-	if err != nil && !ok {
-		t.Error(err)
-		return
-	}
-	found.RemoveMultiples()
-
-	// we are expecting the following errors
-	// (collect these after parsing a file so that it is found in the file set)
-	expected := expectedErrors(t, filename, src)
-
-	// verify errors returned by the parser
-	compareErrors(t, expected, found)
-}
-
-func TestErrors(t *testing.T) {
-	fsetErrs = token.NewFileSet()
-	list, err := ioutil.ReadDir(testdata)
-	if err != nil {
-		t.Fatal(err)
-	}
-	for _, fi := range list {
-		name := fi.Name()
-		if !fi.IsDir() && !strings.HasPrefix(name, ".") && strings.HasSuffix(name, ".src") {
-			checkErrors(t, filepath.Join(testdata, name), nil)
-		}
-	}
-}
diff --git a/src/pkg/go/parser/interface.go b/src/pkg/go/parser/interface.go
deleted file mode 100644
index 57da4dd..0000000
--- a/src/pkg/go/parser/interface.go
+++ /dev/null
@@ -1,198 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// This file contains the exported entry points for invoking the parser.
-
-package parser
-
-import (
-	"bytes"
-	"errors"
-	"go/ast"
-	"go/token"
-	"io"
-	"io/ioutil"
-	"os"
-	"path/filepath"
-	"strings"
-)
-
-// If src != nil, readSource converts src to a []byte if possible;
-// otherwise it returns an error. If src == nil, readSource returns
-// the result of reading the file specified by filename.
-//
-func readSource(filename string, src interface{}) ([]byte, error) {
-	if src != nil {
-		switch s := src.(type) {
-		case string:
-			return []byte(s), nil
-		case []byte:
-			return s, nil
-		case *bytes.Buffer:
-			// is io.Reader, but src is already available in []byte form
-			if s != nil {
-				return s.Bytes(), nil
-			}
-		case io.Reader:
-			var buf bytes.Buffer
-			if _, err := io.Copy(&buf, s); err != nil {
-				return nil, err
-			}
-			return buf.Bytes(), nil
-		}
-		return nil, errors.New("invalid source")
-	}
-	return ioutil.ReadFile(filename)
-}
-
-// A Mode value is a set of flags (or 0).
-// They control the amount of source code parsed and other optional
-// parser functionality.
-//
-type Mode uint
-
-const (
-	PackageClauseOnly Mode             = 1 << iota // stop parsing after package clause
-	ImportsOnly                                    // stop parsing after import declarations
-	ParseComments                                  // parse comments and add them to AST
-	Trace                                          // print a trace of parsed productions
-	DeclarationErrors                              // report declaration errors
-	SpuriousErrors                                 // same as AllErrors, for backward-compatibility
-	AllErrors         = SpuriousErrors             // report all errors (not just the first 10 on different lines)
-)
-
-// ParseFile parses the source code of a single Go source file and returns
-// the corresponding ast.File node. The source code may be provided via
-// the filename of the source file, or via the src parameter.
-//
-// If src != nil, ParseFile parses the source from src and the filename is
-// only used when recording position information. The type of the argument
-// for the src parameter must be string, []byte, or io.Reader.
-// If src == nil, ParseFile parses the file specified by filename.
-//
-// The mode parameter controls the amount of source text parsed and other
-// optional parser functionality. Position information is recorded in the
-// file set fset.
-//
-// If the source couldn't be read, the returned AST is nil and the error
-// indicates the specific failure. If the source was read but syntax
-// errors were found, the result is a partial AST (with ast.Bad* nodes
-// representing the fragments of erroneous source code). Multiple errors
-// are returned via a scanner.ErrorList which is sorted by file position.
-//
-func ParseFile(fset *token.FileSet, filename string, src interface{}, mode Mode) (f *ast.File, err error) {
-	// get source
-	text, err := readSource(filename, src)
-	if err != nil {
-		return nil, err
-	}
-
-	var p parser
-	defer func() {
-		if e := recover(); e != nil {
-			_ = e.(bailout) // re-panics if it's not a bailout
-		}
-
-		// set result values
-		if f == nil {
-			// source is not a valid Go source file - satisfy
-			// ParseFile API and return a valid (but) empty
-			// *ast.File
-			f = &ast.File{
-				Name:  new(ast.Ident),
-				Scope: ast.NewScope(nil),
-			}
-		}
-
-		p.errors.Sort()
-		err = p.errors.Err()
-	}()
-
-	// parse source
-	p.init(fset, filename, text, mode)
-	f = p.parseFile()
-
-	return
-}
-
-// ParseDir calls ParseFile for all files with names ending in ".go" in the
-// directory specified by path and returns a map of package name -> package
-// AST with all the packages found.
-//
-// If filter != nil, only the files with os.FileInfo entries passing through
-// the filter (and ending in ".go") are considered. The mode bits are passed
-// to ParseFile unchanged. Position information is recorded in fset.
-//
-// If the directory couldn't be read, a nil map and the respective error are
-// returned. If a parse error occurred, a non-nil but incomplete map and the
-// first error encountered are returned.
-//
-func ParseDir(fset *token.FileSet, path string, filter func(os.FileInfo) bool, mode Mode) (pkgs map[string]*ast.Package, first error) {
-	fd, err := os.Open(path)
-	if err != nil {
-		return nil, err
-	}
-	defer fd.Close()
-
-	list, err := fd.Readdir(-1)
-	if err != nil {
-		return nil, err
-	}
-
-	pkgs = make(map[string]*ast.Package)
-	for _, d := range list {
-		if strings.HasSuffix(d.Name(), ".go") && (filter == nil || filter(d)) {
-			filename := filepath.Join(path, d.Name())
-			if src, err := ParseFile(fset, filename, nil, mode); err == nil {
-				name := src.Name.Name
-				pkg, found := pkgs[name]
-				if !found {
-					pkg = &ast.Package{
-						Name:  name,
-						Files: make(map[string]*ast.File),
-					}
-					pkgs[name] = pkg
-				}
-				pkg.Files[filename] = src
-			} else if first == nil {
-				first = err
-			}
-		}
-	}
-
-	return
-}
-
-// ParseExpr is a convenience function for obtaining the AST of an expression x.
-// The position information recorded in the AST is undefined. The filename used
-// in error messages is the empty string.
-//
-func ParseExpr(x string) (ast.Expr, error) {
-	var p parser
-	p.init(token.NewFileSet(), "", []byte(x), 0)
-
-	// Set up pkg-level scopes to avoid nil-pointer errors.
-	// This is not needed for a correct expression x as the
-	// parser will be ok with a nil topScope, but be cautious
-	// in case of an erroneous x.
-	p.openScope()
-	p.pkgScope = p.topScope
-	e := p.parseRhsOrType()
-	p.closeScope()
-	assert(p.topScope == nil, "unbalanced scopes")
-
-	// If a semicolon was inserted, consume it;
-	// report an error if there's more tokens.
-	if p.tok == token.SEMICOLON {
-		p.next()
-	}
-	p.expect(token.EOF)
-
-	if p.errors.Len() > 0 {
-		p.errors.Sort()
-		return nil, p.errors.Err()
-	}
-
-	return e, nil
-}
diff --git a/src/pkg/go/parser/parser.go b/src/pkg/go/parser/parser.go
deleted file mode 100644
index 00dd532..0000000
--- a/src/pkg/go/parser/parser.go
+++ /dev/null
@@ -1,2478 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package parser implements a parser for Go source files. Input may be
-// provided in a variety of forms (see the various Parse* functions); the
-// output is an abstract syntax tree (AST) representing the Go source. The
-// parser is invoked through one of the Parse* functions.
-//
-package parser
-
-import (
-	"fmt"
-	"go/ast"
-	"go/scanner"
-	"go/token"
-	"strconv"
-	"strings"
-	"unicode"
-)
-
-// The parser structure holds the parser's internal state.
-type parser struct {
-	file    *token.File
-	errors  scanner.ErrorList
-	scanner scanner.Scanner
-
-	// Tracing/debugging
-	mode   Mode // parsing mode
-	trace  bool // == (mode & Trace != 0)
-	indent int  // indentation used for tracing output
-
-	// Comments
-	comments    []*ast.CommentGroup
-	leadComment *ast.CommentGroup // last lead comment
-	lineComment *ast.CommentGroup // last line comment
-
-	// Next token
-	pos token.Pos   // token position
-	tok token.Token // one token look-ahead
-	lit string      // token literal
-
-	// Error recovery
-	// (used to limit the number of calls to syncXXX functions
-	// w/o making scanning progress - avoids potential endless
-	// loops across multiple parser functions during error recovery)
-	syncPos token.Pos // last synchronization position
-	syncCnt int       // number of calls to syncXXX without progress
-
-	// Non-syntactic parser control
-	exprLev int  // < 0: in control clause, >= 0: in expression
-	inRhs   bool // if set, the parser is parsing a rhs expression
-
-	// Ordinary identifier scopes
-	pkgScope   *ast.Scope        // pkgScope.Outer == nil
-	topScope   *ast.Scope        // top-most scope; may be pkgScope
-	unresolved []*ast.Ident      // unresolved identifiers
-	imports    []*ast.ImportSpec // list of imports
-
-	// Label scopes
-	// (maintained by open/close LabelScope)
-	labelScope  *ast.Scope     // label scope for current function
-	targetStack [][]*ast.Ident // stack of unresolved labels
-}
-
-func (p *parser) init(fset *token.FileSet, filename string, src []byte, mode Mode) {
-	p.file = fset.AddFile(filename, -1, len(src))
-	var m scanner.Mode
-	if mode&ParseComments != 0 {
-		m = scanner.ScanComments
-	}
-	eh := func(pos token.Position, msg string) { p.errors.Add(pos, msg) }
-	p.scanner.Init(p.file, src, eh, m)
-
-	p.mode = mode
-	p.trace = mode&Trace != 0 // for convenience (p.trace is used frequently)
-
-	p.next()
-}
-
-// ----------------------------------------------------------------------------
-// Scoping support
-
-func (p *parser) openScope() {
-	p.topScope = ast.NewScope(p.topScope)
-}
-
-func (p *parser) closeScope() {
-	p.topScope = p.topScope.Outer
-}
-
-func (p *parser) openLabelScope() {
-	p.labelScope = ast.NewScope(p.labelScope)
-	p.targetStack = append(p.targetStack, nil)
-}
-
-func (p *parser) closeLabelScope() {
-	// resolve labels
-	n := len(p.targetStack) - 1
-	scope := p.labelScope
-	for _, ident := range p.targetStack[n] {
-		ident.Obj = scope.Lookup(ident.Name)
-		if ident.Obj == nil && p.mode&DeclarationErrors != 0 {
-			p.error(ident.Pos(), fmt.Sprintf("label %s undefined", ident.Name))
-		}
-	}
-	// pop label scope
-	p.targetStack = p.targetStack[0:n]
-	p.labelScope = p.labelScope.Outer
-}
-
-func (p *parser) declare(decl, data interface{}, scope *ast.Scope, kind ast.ObjKind, idents ...*ast.Ident) {
-	for _, ident := range idents {
-		assert(ident.Obj == nil, "identifier already declared or resolved")
-		obj := ast.NewObj(kind, ident.Name)
-		// remember the corresponding declaration for redeclaration
-		// errors and global variable resolution/typechecking phase
-		obj.Decl = decl
-		obj.Data = data
-		ident.Obj = obj
-		if ident.Name != "_" {
-			if alt := scope.Insert(obj); alt != nil && p.mode&DeclarationErrors != 0 {
-				prevDecl := ""
-				if pos := alt.Pos(); pos.IsValid() {
-					prevDecl = fmt.Sprintf("\n\tprevious declaration at %s", p.file.Position(pos))
-				}
-				p.error(ident.Pos(), fmt.Sprintf("%s redeclared in this block%s", ident.Name, prevDecl))
-			}
-		}
-	}
-}
-
-func (p *parser) shortVarDecl(decl *ast.AssignStmt, list []ast.Expr) {
-	// Go spec: A short variable declaration may redeclare variables
-	// provided they were originally declared in the same block with
-	// the same type, and at least one of the non-blank variables is new.
-	n := 0 // number of new variables
-	for _, x := range list {
-		if ident, isIdent := x.(*ast.Ident); isIdent {
-			assert(ident.Obj == nil, "identifier already declared or resolved")
-			obj := ast.NewObj(ast.Var, ident.Name)
-			// remember corresponding assignment for other tools
-			obj.Decl = decl
-			ident.Obj = obj
-			if ident.Name != "_" {
-				if alt := p.topScope.Insert(obj); alt != nil {
-					ident.Obj = alt // redeclaration
-				} else {
-					n++ // new declaration
-				}
-			}
-		} else {
-			p.errorExpected(x.Pos(), "identifier on left side of :=")
-		}
-	}
-	if n == 0 && p.mode&DeclarationErrors != 0 {
-		p.error(list[0].Pos(), "no new variables on left side of :=")
-	}
-}
-
-// The unresolved object is a sentinel to mark identifiers that have been added
-// to the list of unresolved identifiers. The sentinel is only used for verifying
-// internal consistency.
-var unresolved = new(ast.Object)
-
-// If x is an identifier, tryResolve attempts to resolve x by looking up
-// the object it denotes. If no object is found and collectUnresolved is
-// set, x is marked as unresolved and collected in the list of unresolved
-// identifiers.
-//
-func (p *parser) tryResolve(x ast.Expr, collectUnresolved bool) {
-	// nothing to do if x is not an identifier or the blank identifier
-	ident, _ := x.(*ast.Ident)
-	if ident == nil {
-		return
-	}
-	assert(ident.Obj == nil, "identifier already declared or resolved")
-	if ident.Name == "_" {
-		return
-	}
-	// try to resolve the identifier
-	for s := p.topScope; s != nil; s = s.Outer {
-		if obj := s.Lookup(ident.Name); obj != nil {
-			ident.Obj = obj
-			return
-		}
-	}
-	// all local scopes are known, so any unresolved identifier
-	// must be found either in the file scope, package scope
-	// (perhaps in another file), or universe scope --- collect
-	// them so that they can be resolved later
-	if collectUnresolved {
-		ident.Obj = unresolved
-		p.unresolved = append(p.unresolved, ident)
-	}
-}
-
-func (p *parser) resolve(x ast.Expr) {
-	p.tryResolve(x, true)
-}
-
-// ----------------------------------------------------------------------------
-// Parsing support
-
-func (p *parser) printTrace(a ...interface{}) {
-	const dots = ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . "
-	const n = len(dots)
-	pos := p.file.Position(p.pos)
-	fmt.Printf("%5d:%3d: ", pos.Line, pos.Column)
-	i := 2 * p.indent
-	for i > n {
-		fmt.Print(dots)
-		i -= n
-	}
-	// i <= n
-	fmt.Print(dots[0:i])
-	fmt.Println(a...)
-}
-
-func trace(p *parser, msg string) *parser {
-	p.printTrace(msg, "(")
-	p.indent++
-	return p
-}
-
-// Usage pattern: defer un(trace(p, "..."))
-func un(p *parser) {
-	p.indent--
-	p.printTrace(")")
-}
-
-// Advance to the next token.
-func (p *parser) next0() {
-	// Because of one-token look-ahead, print the previous token
-	// when tracing as it provides a more readable output. The
-	// very first token (!p.pos.IsValid()) is not initialized
-	// (it is token.ILLEGAL), so don't print it .
-	if p.trace && p.pos.IsValid() {
-		s := p.tok.String()
-		switch {
-		case p.tok.IsLiteral():
-			p.printTrace(s, p.lit)
-		case p.tok.IsOperator(), p.tok.IsKeyword():
-			p.printTrace("\"" + s + "\"")
-		default:
-			p.printTrace(s)
-		}
-	}
-
-	p.pos, p.tok, p.lit = p.scanner.Scan()
-}
-
-// Consume a comment and return it and the line on which it ends.
-func (p *parser) consumeComment() (comment *ast.Comment, endline int) {
-	// /*-style comments may end on a different line than where they start.
-	// Scan the comment for '\n' chars and adjust endline accordingly.
-	endline = p.file.Line(p.pos)
-	if p.lit[1] == '*' {
-		// don't use range here - no need to decode Unicode code points
-		for i := 0; i < len(p.lit); i++ {
-			if p.lit[i] == '\n' {
-				endline++
-			}
-		}
-	}
-
-	comment = &ast.Comment{Slash: p.pos, Text: p.lit}
-	p.next0()
-
-	return
-}
-
-// Consume a group of adjacent comments, add it to the parser's
-// comments list, and return it together with the line at which
-// the last comment in the group ends. A non-comment token or n
-// empty lines terminate a comment group.
-//
-func (p *parser) consumeCommentGroup(n int) (comments *ast.CommentGroup, endline int) {
-	var list []*ast.Comment
-	endline = p.file.Line(p.pos)
-	for p.tok == token.COMMENT && p.file.Line(p.pos) <= endline+n {
-		var comment *ast.Comment
-		comment, endline = p.consumeComment()
-		list = append(list, comment)
-	}
-
-	// add comment group to the comments list
-	comments = &ast.CommentGroup{List: list}
-	p.comments = append(p.comments, comments)
-
-	return
-}
-
-// Advance to the next non-comment token. In the process, collect
-// any comment groups encountered, and remember the last lead and
-// and line comments.
-//
-// A lead comment is a comment group that starts and ends in a
-// line without any other tokens and that is followed by a non-comment
-// token on the line immediately after the comment group.
-//
-// A line comment is a comment group that follows a non-comment
-// token on the same line, and that has no tokens after it on the line
-// where it ends.
-//
-// Lead and line comments may be considered documentation that is
-// stored in the AST.
-//
-func (p *parser) next() {
-	p.leadComment = nil
-	p.lineComment = nil
-	prev := p.pos
-	p.next0()
-
-	if p.tok == token.COMMENT {
-		var comment *ast.CommentGroup
-		var endline int
-
-		if p.file.Line(p.pos) == p.file.Line(prev) {
-			// The comment is on same line as the previous token; it
-			// cannot be a lead comment but may be a line comment.
-			comment, endline = p.consumeCommentGroup(0)
-			if p.file.Line(p.pos) != endline {
-				// The next token is on a different line, thus
-				// the last comment group is a line comment.
-				p.lineComment = comment
-			}
-		}
-
-		// consume successor comments, if any
-		endline = -1
-		for p.tok == token.COMMENT {
-			comment, endline = p.consumeCommentGroup(1)
-		}
-
-		if endline+1 == p.file.Line(p.pos) {
-			// The next token is following on the line immediately after the
-			// comment group, thus the last comment group is a lead comment.
-			p.leadComment = comment
-		}
-	}
-}
-
-// A bailout panic is raised to indicate early termination.
-type bailout struct{}
-
-func (p *parser) error(pos token.Pos, msg string) {
-	epos := p.file.Position(pos)
-
-	// If AllErrors is not set, discard errors reported on the same line
-	// as the last recorded error and stop parsing if there are more than
-	// 10 errors.
-	if p.mode&AllErrors == 0 {
-		n := len(p.errors)
-		if n > 0 && p.errors[n-1].Pos.Line == epos.Line {
-			return // discard - likely a spurious error
-		}
-		if n > 10 {
-			panic(bailout{})
-		}
-	}
-
-	p.errors.Add(epos, msg)
-}
-
-func (p *parser) errorExpected(pos token.Pos, msg string) {
-	msg = "expected " + msg
-	if pos == p.pos {
-		// the error happened at the current position;
-		// make the error message more specific
-		if p.tok == token.SEMICOLON && p.lit == "\n" {
-			msg += ", found newline"
-		} else {
-			msg += ", found '" + p.tok.String() + "'"
-			if p.tok.IsLiteral() {
-				msg += " " + p.lit
-			}
-		}
-	}
-	p.error(pos, msg)
-}
-
-func (p *parser) expect(tok token.Token) token.Pos {
-	pos := p.pos
-	if p.tok != tok {
-		p.errorExpected(pos, "'"+tok.String()+"'")
-	}
-	p.next() // make progress
-	return pos
-}
-
-// expectClosing is like expect but provides a better error message
-// for the common case of a missing comma before a newline.
-//
-func (p *parser) expectClosing(tok token.Token, context string) token.Pos {
-	if p.tok != tok && p.tok == token.SEMICOLON && p.lit == "\n" {
-		p.error(p.pos, "missing ',' before newline in "+context)
-		p.next()
-	}
-	return p.expect(tok)
-}
-
-func (p *parser) expectSemi() {
-	// semicolon is optional before a closing ')' or '}'
-	if p.tok != token.RPAREN && p.tok != token.RBRACE {
-		if p.tok == token.SEMICOLON {
-			p.next()
-		} else {
-			p.errorExpected(p.pos, "';'")
-			syncStmt(p)
-		}
-	}
-}
-
-func (p *parser) atComma(context string) bool {
-	if p.tok == token.COMMA {
-		return true
-	}
-	if p.tok == token.SEMICOLON && p.lit == "\n" {
-		p.error(p.pos, "missing ',' before newline in "+context)
-		return true // "insert" the comma and continue
-
-	}
-	return false
-}
-
-func assert(cond bool, msg string) {
-	if !cond {
-		panic("go/parser internal error: " + msg)
-	}
-}
-
-// syncStmt advances to the next statement.
-// Used for synchronization after an error.
-//
-func syncStmt(p *parser) {
-	for {
-		switch p.tok {
-		case token.BREAK, token.CONST, token.CONTINUE, token.DEFER,
-			token.FALLTHROUGH, token.FOR, token.GO, token.GOTO,
-			token.IF, token.RETURN, token.SELECT, token.SWITCH,
-			token.TYPE, token.VAR:
-			// Return only if parser made some progress since last
-			// sync or if it has not reached 10 sync calls without
-			// progress. Otherwise consume at least one token to
-			// avoid an endless parser loop (it is possible that
-			// both parseOperand and parseStmt call syncStmt and
-			// correctly do not advance, thus the need for the
-			// invocation limit p.syncCnt).
-			if p.pos == p.syncPos && p.syncCnt < 10 {
-				p.syncCnt++
-				return
-			}
-			if p.pos > p.syncPos {
-				p.syncPos = p.pos
-				p.syncCnt = 0
-				return
-			}
-			// Reaching here indicates a parser bug, likely an
-			// incorrect token list in this function, but it only
-			// leads to skipping of possibly correct code if a
-			// previous error is present, and thus is preferred
-			// over a non-terminating parse.
-		case token.EOF:
-			return
-		}
-		p.next()
-	}
-}
-
-// syncDecl advances to the next declaration.
-// Used for synchronization after an error.
-//
-func syncDecl(p *parser) {
-	for {
-		switch p.tok {
-		case token.CONST, token.TYPE, token.VAR:
-			// see comments in syncStmt
-			if p.pos == p.syncPos && p.syncCnt < 10 {
-				p.syncCnt++
-				return
-			}
-			if p.pos > p.syncPos {
-				p.syncPos = p.pos
-				p.syncCnt = 0
-				return
-			}
-		case token.EOF:
-			return
-		}
-		p.next()
-	}
-}
-
-// safePos returns a valid file position for a given position: If pos
-// is valid to begin with, safePos returns pos. If pos is out-of-range,
-// safePos returns the EOF position.
-//
-// This is hack to work around "artificial" end positions in the AST which
-// are computed by adding 1 to (presumably valid) token positions. If the
-// token positions are invalid due to parse errors, the resulting end position
-// may be past the file's EOF position, which would lead to panics if used
-// later on.
-//
-func (p *parser) safePos(pos token.Pos) (res token.Pos) {
-	defer func() {
-		if recover() != nil {
-			res = token.Pos(p.file.Base() + p.file.Size()) // EOF position
-		}
-	}()
-	_ = p.file.Offset(pos) // trigger a panic if position is out-of-range
-	return pos
-}
-
-// ----------------------------------------------------------------------------
-// Identifiers
-
-func (p *parser) parseIdent() *ast.Ident {
-	pos := p.pos
-	name := "_"
-	if p.tok == token.IDENT {
-		name = p.lit
-		p.next()
-	} else {
-		p.expect(token.IDENT) // use expect() error handling
-	}
-	return &ast.Ident{NamePos: pos, Name: name}
-}
-
-func (p *parser) parseIdentList() (list []*ast.Ident) {
-	if p.trace {
-		defer un(trace(p, "IdentList"))
-	}
-
-	list = append(list, p.parseIdent())
-	for p.tok == token.COMMA {
-		p.next()
-		list = append(list, p.parseIdent())
-	}
-
-	return
-}
-
-// ----------------------------------------------------------------------------
-// Common productions
-
-// If lhs is set, result list elements which are identifiers are not resolved.
-func (p *parser) parseExprList(lhs bool) (list []ast.Expr) {
-	if p.trace {
-		defer un(trace(p, "ExpressionList"))
-	}
-
-	list = append(list, p.checkExpr(p.parseExpr(lhs)))
-	for p.tok == token.COMMA {
-		p.next()
-		list = append(list, p.checkExpr(p.parseExpr(lhs)))
-	}
-
-	return
-}
-
-func (p *parser) parseLhsList() []ast.Expr {
-	old := p.inRhs
-	p.inRhs = false
-	list := p.parseExprList(true)
-	switch p.tok {
-	case token.DEFINE:
-		// lhs of a short variable declaration
-		// but doesn't enter scope until later:
-		// caller must call p.shortVarDecl(p.makeIdentList(list))
-		// at appropriate time.
-	case token.COLON:
-		// lhs of a label declaration or a communication clause of a select
-		// statement (parseLhsList is not called when parsing the case clause
-		// of a switch statement):
-		// - labels are declared by the caller of parseLhsList
-		// - for communication clauses, if there is a stand-alone identifier
-		//   followed by a colon, we have a syntax error; there is no need
-		//   to resolve the identifier in that case
-	default:
-		// identifiers must be declared elsewhere
-		for _, x := range list {
-			p.resolve(x)
-		}
-	}
-	p.inRhs = old
-	return list
-}
-
-func (p *parser) parseRhsList() []ast.Expr {
-	old := p.inRhs
-	p.inRhs = true
-	list := p.parseExprList(false)
-	p.inRhs = old
-	return list
-}
-
-// ----------------------------------------------------------------------------
-// Types
-
-func (p *parser) parseType() ast.Expr {
-	if p.trace {
-		defer un(trace(p, "Type"))
-	}
-
-	typ := p.tryType()
-
-	if typ == nil {
-		pos := p.pos
-		p.errorExpected(pos, "type")
-		p.next() // make progress
-		return &ast.BadExpr{From: pos, To: p.pos}
-	}
-
-	return typ
-}
-
-// If the result is an identifier, it is not resolved.
-func (p *parser) parseTypeName() ast.Expr {
-	if p.trace {
-		defer un(trace(p, "TypeName"))
-	}
-
-	ident := p.parseIdent()
-	// don't resolve ident yet - it may be a parameter or field name
-
-	if p.tok == token.PERIOD {
-		// ident is a package name
-		p.next()
-		p.resolve(ident)
-		sel := p.parseIdent()
-		return &ast.SelectorExpr{X: ident, Sel: sel}
-	}
-
-	return ident
-}
-
-func (p *parser) parseArrayType() ast.Expr {
-	if p.trace {
-		defer un(trace(p, "ArrayType"))
-	}
-
-	lbrack := p.expect(token.LBRACK)
-	var len ast.Expr
-	// always permit ellipsis for more fault-tolerant parsing
-	if p.tok == token.ELLIPSIS {
-		len = &ast.Ellipsis{Ellipsis: p.pos}
-		p.next()
-	} else if p.tok != token.RBRACK {
-		len = p.parseRhs()
-	}
-	p.expect(token.RBRACK)
-	elt := p.parseType()
-
-	return &ast.ArrayType{Lbrack: lbrack, Len: len, Elt: elt}
-}
-
-func (p *parser) makeIdentList(list []ast.Expr) []*ast.Ident {
-	idents := make([]*ast.Ident, len(list))
-	for i, x := range list {
-		ident, isIdent := x.(*ast.Ident)
-		if !isIdent {
-			if _, isBad := x.(*ast.BadExpr); !isBad {
-				// only report error if it's a new one
-				p.errorExpected(x.Pos(), "identifier")
-			}
-			ident = &ast.Ident{NamePos: x.Pos(), Name: "_"}
-		}
-		idents[i] = ident
-	}
-	return idents
-}
-
-func (p *parser) parseFieldDecl(scope *ast.Scope) *ast.Field {
-	if p.trace {
-		defer un(trace(p, "FieldDecl"))
-	}
-
-	doc := p.leadComment
-
-	// FieldDecl
-	list, typ := p.parseVarList(false)
-
-	// Tag
-	var tag *ast.BasicLit
-	if p.tok == token.STRING {
-		tag = &ast.BasicLit{ValuePos: p.pos, Kind: p.tok, Value: p.lit}
-		p.next()
-	}
-
-	// analyze case
-	var idents []*ast.Ident
-	if typ != nil {
-		// IdentifierList Type
-		idents = p.makeIdentList(list)
-	} else {
-		// ["*"] TypeName (AnonymousField)
-		typ = list[0] // we always have at least one element
-		if n := len(list); n > 1 || !isTypeName(deref(typ)) {
-			pos := typ.Pos()
-			p.errorExpected(pos, "anonymous field")
-			typ = &ast.BadExpr{From: pos, To: p.safePos(list[n-1].End())}
-		}
-	}
-
-	p.expectSemi() // call before accessing p.linecomment
-
-	field := &ast.Field{Doc: doc, Names: idents, Type: typ, Tag: tag, Comment: p.lineComment}
-	p.declare(field, nil, scope, ast.Var, idents...)
-	p.resolve(typ)
-
-	return field
-}
-
-func (p *parser) parseStructType() *ast.StructType {
-	if p.trace {
-		defer un(trace(p, "StructType"))
-	}
-
-	pos := p.expect(token.STRUCT)
-	lbrace := p.expect(token.LBRACE)
-	scope := ast.NewScope(nil) // struct scope
-	var list []*ast.Field
-	for p.tok == token.IDENT || p.tok == token.MUL || p.tok == token.LPAREN {
-		// a field declaration cannot start with a '(' but we accept
-		// it here for more robust parsing and better error messages
-		// (parseFieldDecl will check and complain if necessary)
-		list = append(list, p.parseFieldDecl(scope))
-	}
-	rbrace := p.expect(token.RBRACE)
-
-	return &ast.StructType{
-		Struct: pos,
-		Fields: &ast.FieldList{
-			Opening: lbrace,
-			List:    list,
-			Closing: rbrace,
-		},
-	}
-}
-
-func (p *parser) parsePointerType() *ast.StarExpr {
-	if p.trace {
-		defer un(trace(p, "PointerType"))
-	}
-
-	star := p.expect(token.MUL)
-	base := p.parseType()
-
-	return &ast.StarExpr{Star: star, X: base}
-}
-
-// If the result is an identifier, it is not resolved.
-func (p *parser) tryVarType(isParam bool) ast.Expr {
-	if isParam && p.tok == token.ELLIPSIS {
-		pos := p.pos
-		p.next()
-		typ := p.tryIdentOrType() // don't use parseType so we can provide better error message
-		if typ != nil {
-			p.resolve(typ)
-		} else {
-			p.error(pos, "'...' parameter is missing type")
-			typ = &ast.BadExpr{From: pos, To: p.pos}
-		}
-		return &ast.Ellipsis{Ellipsis: pos, Elt: typ}
-	}
-	return p.tryIdentOrType()
-}
-
-// If the result is an identifier, it is not resolved.
-func (p *parser) parseVarType(isParam bool) ast.Expr {
-	typ := p.tryVarType(isParam)
-	if typ == nil {
-		pos := p.pos
-		p.errorExpected(pos, "type")
-		p.next() // make progress
-		typ = &ast.BadExpr{From: pos, To: p.pos}
-	}
-	return typ
-}
-
-// If any of the results are identifiers, they are not resolved.
-func (p *parser) parseVarList(isParam bool) (list []ast.Expr, typ ast.Expr) {
-	if p.trace {
-		defer un(trace(p, "VarList"))
-	}
-
-	// a list of identifiers looks like a list of type names
-	//
-	// parse/tryVarType accepts any type (including parenthesized
-	// ones) even though the syntax does not permit them here: we
-	// accept them all for more robust parsing and complain later
-	for typ := p.parseVarType(isParam); typ != nil; {
-		list = append(list, typ)
-		if p.tok != token.COMMA {
-			break
-		}
-		p.next()
-		typ = p.tryVarType(isParam) // maybe nil as in: func f(int,) {}
-	}
-
-	// if we had a list of identifiers, it must be followed by a type
-	typ = p.tryVarType(isParam)
-
-	return
-}
-
-func (p *parser) parseParameterList(scope *ast.Scope, ellipsisOk bool) (params []*ast.Field) {
-	if p.trace {
-		defer un(trace(p, "ParameterList"))
-	}
-
-	// ParameterDecl
-	list, typ := p.parseVarList(ellipsisOk)
-
-	// analyze case
-	if typ != nil {
-		// IdentifierList Type
-		idents := p.makeIdentList(list)
-		field := &ast.Field{Names: idents, Type: typ}
-		params = append(params, field)
-		// Go spec: The scope of an identifier denoting a function
-		// parameter or result variable is the function body.
-		p.declare(field, nil, scope, ast.Var, idents...)
-		p.resolve(typ)
-		if p.tok == token.COMMA {
-			p.next()
-		}
-		for p.tok != token.RPAREN && p.tok != token.EOF {
-			idents := p.parseIdentList()
-			typ := p.parseVarType(ellipsisOk)
-			field := &ast.Field{Names: idents, Type: typ}
-			params = append(params, field)
-			// Go spec: The scope of an identifier denoting a function
-			// parameter or result variable is the function body.
-			p.declare(field, nil, scope, ast.Var, idents...)
-			p.resolve(typ)
-			if !p.atComma("parameter list") {
-				break
-			}
-			p.next()
-		}
-	} else {
-		// Type { "," Type } (anonymous parameters)
-		params = make([]*ast.Field, len(list))
-		for i, typ := range list {
-			p.resolve(typ)
-			params[i] = &ast.Field{Type: typ}
-		}
-	}
-
-	return
-}
-
-func (p *parser) parseParameters(scope *ast.Scope, ellipsisOk bool) *ast.FieldList {
-	if p.trace {
-		defer un(trace(p, "Parameters"))
-	}
-
-	var params []*ast.Field
-	lparen := p.expect(token.LPAREN)
-	if p.tok != token.RPAREN {
-		params = p.parseParameterList(scope, ellipsisOk)
-	}
-	rparen := p.expect(token.RPAREN)
-
-	return &ast.FieldList{Opening: lparen, List: params, Closing: rparen}
-}
-
-func (p *parser) parseResult(scope *ast.Scope) *ast.FieldList {
-	if p.trace {
-		defer un(trace(p, "Result"))
-	}
-
-	if p.tok == token.LPAREN {
-		return p.parseParameters(scope, false)
-	}
-
-	typ := p.tryType()
-	if typ != nil {
-		list := make([]*ast.Field, 1)
-		list[0] = &ast.Field{Type: typ}
-		return &ast.FieldList{List: list}
-	}
-
-	return nil
-}
-
-func (p *parser) parseSignature(scope *ast.Scope) (params, results *ast.FieldList) {
-	if p.trace {
-		defer un(trace(p, "Signature"))
-	}
-
-	params = p.parseParameters(scope, true)
-	results = p.parseResult(scope)
-
-	return
-}
-
-func (p *parser) parseFuncType() (*ast.FuncType, *ast.Scope) {
-	if p.trace {
-		defer un(trace(p, "FuncType"))
-	}
-
-	pos := p.expect(token.FUNC)
-	scope := ast.NewScope(p.topScope) // function scope
-	params, results := p.parseSignature(scope)
-
-	return &ast.FuncType{Func: pos, Params: params, Results: results}, scope
-}
-
-func (p *parser) parseMethodSpec(scope *ast.Scope) *ast.Field {
-	if p.trace {
-		defer un(trace(p, "MethodSpec"))
-	}
-
-	doc := p.leadComment
-	var idents []*ast.Ident
-	var typ ast.Expr
-	x := p.parseTypeName()
-	if ident, isIdent := x.(*ast.Ident); isIdent && p.tok == token.LPAREN {
-		// method
-		idents = []*ast.Ident{ident}
-		scope := ast.NewScope(nil) // method scope
-		params, results := p.parseSignature(scope)
-		typ = &ast.FuncType{Func: token.NoPos, Params: params, Results: results}
-	} else {
-		// embedded interface
-		typ = x
-		p.resolve(typ)
-	}
-	p.expectSemi() // call before accessing p.linecomment
-
-	spec := &ast.Field{Doc: doc, Names: idents, Type: typ, Comment: p.lineComment}
-	p.declare(spec, nil, scope, ast.Fun, idents...)
-
-	return spec
-}
-
-func (p *parser) parseInterfaceType() *ast.InterfaceType {
-	if p.trace {
-		defer un(trace(p, "InterfaceType"))
-	}
-
-	pos := p.expect(token.INTERFACE)
-	lbrace := p.expect(token.LBRACE)
-	scope := ast.NewScope(nil) // interface scope
-	var list []*ast.Field
-	for p.tok == token.IDENT {
-		list = append(list, p.parseMethodSpec(scope))
-	}
-	rbrace := p.expect(token.RBRACE)
-
-	return &ast.InterfaceType{
-		Interface: pos,
-		Methods: &ast.FieldList{
-			Opening: lbrace,
-			List:    list,
-			Closing: rbrace,
-		},
-	}
-}
-
-func (p *parser) parseMapType() *ast.MapType {
-	if p.trace {
-		defer un(trace(p, "MapType"))
-	}
-
-	pos := p.expect(token.MAP)
-	p.expect(token.LBRACK)
-	key := p.parseType()
-	p.expect(token.RBRACK)
-	value := p.parseType()
-
-	return &ast.MapType{Map: pos, Key: key, Value: value}
-}
-
-func (p *parser) parseChanType() *ast.ChanType {
-	if p.trace {
-		defer un(trace(p, "ChanType"))
-	}
-
-	pos := p.pos
-	dir := ast.SEND | ast.RECV
-	var arrow token.Pos
-	if p.tok == token.CHAN {
-		p.next()
-		if p.tok == token.ARROW {
-			arrow = p.pos
-			p.next()
-			dir = ast.SEND
-		}
-	} else {
-		arrow = p.expect(token.ARROW)
-		p.expect(token.CHAN)
-		dir = ast.RECV
-	}
-	value := p.parseType()
-
-	return &ast.ChanType{Begin: pos, Arrow: arrow, Dir: dir, Value: value}
-}
-
-// If the result is an identifier, it is not resolved.
-func (p *parser) tryIdentOrType() ast.Expr {
-	switch p.tok {
-	case token.IDENT:
-		return p.parseTypeName()
-	case token.LBRACK:
-		return p.parseArrayType()
-	case token.STRUCT:
-		return p.parseStructType()
-	case token.MUL:
-		return p.parsePointerType()
-	case token.FUNC:
-		typ, _ := p.parseFuncType()
-		return typ
-	case token.INTERFACE:
-		return p.parseInterfaceType()
-	case token.MAP:
-		return p.parseMapType()
-	case token.CHAN, token.ARROW:
-		return p.parseChanType()
-	case token.LPAREN:
-		lparen := p.pos
-		p.next()
-		typ := p.parseType()
-		rparen := p.expect(token.RPAREN)
-		return &ast.ParenExpr{Lparen: lparen, X: typ, Rparen: rparen}
-	}
-
-	// no type found
-	return nil
-}
-
-func (p *parser) tryType() ast.Expr {
-	typ := p.tryIdentOrType()
-	if typ != nil {
-		p.resolve(typ)
-	}
-	return typ
-}
-
-// ----------------------------------------------------------------------------
-// Blocks
-
-func (p *parser) parseStmtList() (list []ast.Stmt) {
-	if p.trace {
-		defer un(trace(p, "StatementList"))
-	}
-
-	for p.tok != token.CASE && p.tok != token.DEFAULT && p.tok != token.RBRACE && p.tok != token.EOF {
-		list = append(list, p.parseStmt())
-	}
-
-	return
-}
-
-func (p *parser) parseBody(scope *ast.Scope) *ast.BlockStmt {
-	if p.trace {
-		defer un(trace(p, "Body"))
-	}
-
-	lbrace := p.expect(token.LBRACE)
-	p.topScope = scope // open function scope
-	p.openLabelScope()
-	list := p.parseStmtList()
-	p.closeLabelScope()
-	p.closeScope()
-	rbrace := p.expect(token.RBRACE)
-
-	return &ast.BlockStmt{Lbrace: lbrace, List: list, Rbrace: rbrace}
-}
-
-func (p *parser) parseBlockStmt() *ast.BlockStmt {
-	if p.trace {
-		defer un(trace(p, "BlockStmt"))
-	}
-
-	lbrace := p.expect(token.LBRACE)
-	p.openScope()
-	list := p.parseStmtList()
-	p.closeScope()
-	rbrace := p.expect(token.RBRACE)
-
-	return &ast.BlockStmt{Lbrace: lbrace, List: list, Rbrace: rbrace}
-}
-
-// ----------------------------------------------------------------------------
-// Expressions
-
-func (p *parser) parseFuncTypeOrLit() ast.Expr {
-	if p.trace {
-		defer un(trace(p, "FuncTypeOrLit"))
-	}
-
-	typ, scope := p.parseFuncType()
-	if p.tok != token.LBRACE {
-		// function type only
-		return typ
-	}
-
-	p.exprLev++
-	body := p.parseBody(scope)
-	p.exprLev--
-
-	return &ast.FuncLit{Type: typ, Body: body}
-}
-
-// parseOperand may return an expression or a raw type (incl. array
-// types of the form [...]T. Callers must verify the result.
-// If lhs is set and the result is an identifier, it is not resolved.
-//
-func (p *parser) parseOperand(lhs bool) ast.Expr {
-	if p.trace {
-		defer un(trace(p, "Operand"))
-	}
-
-	switch p.tok {
-	case token.IDENT:
-		x := p.parseIdent()
-		if !lhs {
-			p.resolve(x)
-		}
-		return x
-
-	case token.INT, token.FLOAT, token.IMAG, token.CHAR, token.STRING:
-		x := &ast.BasicLit{ValuePos: p.pos, Kind: p.tok, Value: p.lit}
-		p.next()
-		return x
-
-	case token.LPAREN:
-		lparen := p.pos
-		p.next()
-		p.exprLev++
-		x := p.parseRhsOrType() // types may be parenthesized: (some type)
-		p.exprLev--
-		rparen := p.expect(token.RPAREN)
-		return &ast.ParenExpr{Lparen: lparen, X: x, Rparen: rparen}
-
-	case token.FUNC:
-		return p.parseFuncTypeOrLit()
-	}
-
-	if typ := p.tryIdentOrType(); typ != nil {
-		// could be type for composite literal or conversion
-		_, isIdent := typ.(*ast.Ident)
-		assert(!isIdent, "type cannot be identifier")
-		return typ
-	}
-
-	// we have an error
-	pos := p.pos
-	p.errorExpected(pos, "operand")
-	syncStmt(p)
-	return &ast.BadExpr{From: pos, To: p.pos}
-}
-
-func (p *parser) parseSelector(x ast.Expr) ast.Expr {
-	if p.trace {
-		defer un(trace(p, "Selector"))
-	}
-
-	sel := p.parseIdent()
-
-	return &ast.SelectorExpr{X: x, Sel: sel}
-}
-
-func (p *parser) parseTypeAssertion(x ast.Expr) ast.Expr {
-	if p.trace {
-		defer un(trace(p, "TypeAssertion"))
-	}
-
-	lparen := p.expect(token.LPAREN)
-	var typ ast.Expr
-	if p.tok == token.TYPE {
-		// type switch: typ == nil
-		p.next()
-	} else {
-		typ = p.parseType()
-	}
-	rparen := p.expect(token.RPAREN)
-
-	return &ast.TypeAssertExpr{X: x, Type: typ, Lparen: lparen, Rparen: rparen}
-}
-
-func (p *parser) parseIndexOrSlice(x ast.Expr) ast.Expr {
-	if p.trace {
-		defer un(trace(p, "IndexOrSlice"))
-	}
-
-	const N = 3 // change the 3 to 2 to disable 3-index slices
-	lbrack := p.expect(token.LBRACK)
-	p.exprLev++
-	var index [N]ast.Expr
-	var colons [N - 1]token.Pos
-	if p.tok != token.COLON {
-		index[0] = p.parseRhs()
-	}
-	ncolons := 0
-	for p.tok == token.COLON && ncolons < len(colons) {
-		colons[ncolons] = p.pos
-		ncolons++
-		p.next()
-		if p.tok != token.COLON && p.tok != token.RBRACK && p.tok != token.EOF {
-			index[ncolons] = p.parseRhs()
-		}
-	}
-	p.exprLev--
-	rbrack := p.expect(token.RBRACK)
-
-	if ncolons > 0 {
-		// slice expression
-		slice3 := false
-		if ncolons == 2 {
-			slice3 = true
-			// Check presence of 2nd and 3rd index here rather than during type-checking
-			// to prevent erroneous programs from passing through gofmt (was issue 7305).
-			if index[1] == nil {
-				p.error(colons[0], "2nd index required in 3-index slice")
-				index[1] = &ast.BadExpr{From: colons[0] + 1, To: colons[1]}
-			}
-			if index[2] == nil {
-				p.error(colons[1], "3rd index required in 3-index slice")
-				index[2] = &ast.BadExpr{From: colons[1] + 1, To: rbrack}
-			}
-		}
-		return &ast.SliceExpr{X: x, Lbrack: lbrack, Low: index[0], High: index[1], Max: index[2], Slice3: slice3, Rbrack: rbrack}
-	}
-
-	return &ast.IndexExpr{X: x, Lbrack: lbrack, Index: index[0], Rbrack: rbrack}
-}
-
-func (p *parser) parseCallOrConversion(fun ast.Expr) *ast.CallExpr {
-	if p.trace {
-		defer un(trace(p, "CallOrConversion"))
-	}
-
-	lparen := p.expect(token.LPAREN)
-	p.exprLev++
-	var list []ast.Expr
-	var ellipsis token.Pos
-	for p.tok != token.RPAREN && p.tok != token.EOF && !ellipsis.IsValid() {
-		list = append(list, p.parseRhsOrType()) // builtins may expect a type: make(some type, ...)
-		if p.tok == token.ELLIPSIS {
-			ellipsis = p.pos
-			p.next()
-		}
-		if !p.atComma("argument list") {
-			break
-		}
-		p.next()
-	}
-	p.exprLev--
-	rparen := p.expectClosing(token.RPAREN, "argument list")
-
-	return &ast.CallExpr{Fun: fun, Lparen: lparen, Args: list, Ellipsis: ellipsis, Rparen: rparen}
-}
-
-func (p *parser) parseElement(keyOk bool) ast.Expr {
-	if p.trace {
-		defer un(trace(p, "Element"))
-	}
-
-	if p.tok == token.LBRACE {
-		return p.parseLiteralValue(nil)
-	}
-
-	// Because the parser doesn't know the composite literal type, it cannot
-	// know if a key that's an identifier is a struct field name or a name
-	// denoting a value. The former is not resolved by the parser or the
-	// resolver.
-	//
-	// Instead, _try_ to resolve such a key if possible. If it resolves,
-	// it a) has correctly resolved, or b) incorrectly resolved because
-	// the key is a struct field with a name matching another identifier.
-	// In the former case we are done, and in the latter case we don't
-	// care because the type checker will do a separate field lookup.
-	//
-	// If the key does not resolve, it a) must be defined at the top
-	// level in another file of the same package, the universe scope, or be
-	// undeclared; or b) it is a struct field. In the former case, the type
-	// checker can do a top-level lookup, and in the latter case it will do
-	// a separate field lookup.
-	x := p.checkExpr(p.parseExpr(keyOk))
-	if keyOk {
-		if p.tok == token.COLON {
-			colon := p.pos
-			p.next()
-			// Try to resolve the key but don't collect it
-			// as unresolved identifier if it fails so that
-			// we don't get (possibly false) errors about
-			// undeclared names.
-			p.tryResolve(x, false)
-			return &ast.KeyValueExpr{Key: x, Colon: colon, Value: p.parseElement(false)}
-		}
-		p.resolve(x) // not a key
-	}
-
-	return x
-}
-
-func (p *parser) parseElementList() (list []ast.Expr) {
-	if p.trace {
-		defer un(trace(p, "ElementList"))
-	}
-
-	for p.tok != token.RBRACE && p.tok != token.EOF {
-		list = append(list, p.parseElement(true))
-		if !p.atComma("composite literal") {
-			break
-		}
-		p.next()
-	}
-
-	return
-}
-
-func (p *parser) parseLiteralValue(typ ast.Expr) ast.Expr {
-	if p.trace {
-		defer un(trace(p, "LiteralValue"))
-	}
-
-	lbrace := p.expect(token.LBRACE)
-	var elts []ast.Expr
-	p.exprLev++
-	if p.tok != token.RBRACE {
-		elts = p.parseElementList()
-	}
-	p.exprLev--
-	rbrace := p.expectClosing(token.RBRACE, "composite literal")
-	return &ast.CompositeLit{Type: typ, Lbrace: lbrace, Elts: elts, Rbrace: rbrace}
-}
-
-// checkExpr checks that x is an expression (and not a type).
-func (p *parser) checkExpr(x ast.Expr) ast.Expr {
-	switch unparen(x).(type) {
-	case *ast.BadExpr:
-	case *ast.Ident:
-	case *ast.BasicLit:
-	case *ast.FuncLit:
-	case *ast.CompositeLit:
-	case *ast.ParenExpr:
-		panic("unreachable")
-	case *ast.SelectorExpr:
-	case *ast.IndexExpr:
-	case *ast.SliceExpr:
-	case *ast.TypeAssertExpr:
-		// If t.Type == nil we have a type assertion of the form
-		// y.(type), which is only allowed in type switch expressions.
-		// It's hard to exclude those but for the case where we are in
-		// a type switch. Instead be lenient and test this in the type
-		// checker.
-	case *ast.CallExpr:
-	case *ast.StarExpr:
-	case *ast.UnaryExpr:
-	case *ast.BinaryExpr:
-	default:
-		// all other nodes are not proper expressions
-		p.errorExpected(x.Pos(), "expression")
-		x = &ast.BadExpr{From: x.Pos(), To: p.safePos(x.End())}
-	}
-	return x
-}
-
-// isTypeName returns true iff x is a (qualified) TypeName.
-func isTypeName(x ast.Expr) bool {
-	switch t := x.(type) {
-	case *ast.BadExpr:
-	case *ast.Ident:
-	case *ast.SelectorExpr:
-		_, isIdent := t.X.(*ast.Ident)
-		return isIdent
-	default:
-		return false // all other nodes are not type names
-	}
-	return true
-}
-
-// isLiteralType returns true iff x is a legal composite literal type.
-func isLiteralType(x ast.Expr) bool {
-	switch t := x.(type) {
-	case *ast.BadExpr:
-	case *ast.Ident:
-	case *ast.SelectorExpr:
-		_, isIdent := t.X.(*ast.Ident)
-		return isIdent
-	case *ast.ArrayType:
-	case *ast.StructType:
-	case *ast.MapType:
-	default:
-		return false // all other nodes are not legal composite literal types
-	}
-	return true
-}
-
-// If x is of the form *T, deref returns T, otherwise it returns x.
-func deref(x ast.Expr) ast.Expr {
-	if p, isPtr := x.(*ast.StarExpr); isPtr {
-		x = p.X
-	}
-	return x
-}
-
-// If x is of the form (T), unparen returns unparen(T), otherwise it returns x.
-func unparen(x ast.Expr) ast.Expr {
-	if p, isParen := x.(*ast.ParenExpr); isParen {
-		x = unparen(p.X)
-	}
-	return x
-}
-
-// checkExprOrType checks that x is an expression or a type
-// (and not a raw type such as [...]T).
-//
-func (p *parser) checkExprOrType(x ast.Expr) ast.Expr {
-	switch t := unparen(x).(type) {
-	case *ast.ParenExpr:
-		panic("unreachable")
-	case *ast.UnaryExpr:
-	case *ast.ArrayType:
-		if len, isEllipsis := t.Len.(*ast.Ellipsis); isEllipsis {
-			p.error(len.Pos(), "expected array length, found '...'")
-			x = &ast.BadExpr{From: x.Pos(), To: p.safePos(x.End())}
-		}
-	}
-
-	// all other nodes are expressions or types
-	return x
-}
-
-// If lhs is set and the result is an identifier, it is not resolved.
-func (p *parser) parsePrimaryExpr(lhs bool) ast.Expr {
-	if p.trace {
-		defer un(trace(p, "PrimaryExpr"))
-	}
-
-	x := p.parseOperand(lhs)
-L:
-	for {
-		switch p.tok {
-		case token.PERIOD:
-			p.next()
-			if lhs {
-				p.resolve(x)
-			}
-			switch p.tok {
-			case token.IDENT:
-				x = p.parseSelector(p.checkExprOrType(x))
-			case token.LPAREN:
-				x = p.parseTypeAssertion(p.checkExpr(x))
-			default:
-				pos := p.pos
-				p.errorExpected(pos, "selector or type assertion")
-				p.next() // make progress
-				x = &ast.BadExpr{From: pos, To: p.pos}
-			}
-		case token.LBRACK:
-			if lhs {
-				p.resolve(x)
-			}
-			x = p.parseIndexOrSlice(p.checkExpr(x))
-		case token.LPAREN:
-			if lhs {
-				p.resolve(x)
-			}
-			x = p.parseCallOrConversion(p.checkExprOrType(x))
-		case token.LBRACE:
-			if isLiteralType(x) && (p.exprLev >= 0 || !isTypeName(x)) {
-				if lhs {
-					p.resolve(x)
-				}
-				x = p.parseLiteralValue(x)
-			} else {
-				break L
-			}
-		default:
-			break L
-		}
-		lhs = false // no need to try to resolve again
-	}
-
-	return x
-}
-
-// If lhs is set and the result is an identifier, it is not resolved.
-func (p *parser) parseUnaryExpr(lhs bool) ast.Expr {
-	if p.trace {
-		defer un(trace(p, "UnaryExpr"))
-	}
-
-	switch p.tok {
-	case token.ADD, token.SUB, token.NOT, token.XOR, token.AND:
-		pos, op := p.pos, p.tok
-		p.next()
-		x := p.parseUnaryExpr(false)
-		return &ast.UnaryExpr{OpPos: pos, Op: op, X: p.checkExpr(x)}
-
-	case token.ARROW:
-		// channel type or receive expression
-		arrow := p.pos
-		p.next()
-
-		// If the next token is token.CHAN we still don't know if it
-		// is a channel type or a receive operation - we only know
-		// once we have found the end of the unary expression. There
-		// are two cases:
-		//
-		//   <- type  => (<-type) must be channel type
-		//   <- expr  => <-(expr) is a receive from an expression
-		//
-		// In the first case, the arrow must be re-associated with
-		// the channel type parsed already:
-		//
-		//   <- (chan type)    =>  (<-chan type)
-		//   <- (chan<- type)  =>  (<-chan (<-type))
-
-		x := p.parseUnaryExpr(false)
-
-		// determine which case we have
-		if typ, ok := x.(*ast.ChanType); ok {
-			// (<-type)
-
-			// re-associate position info and <-
-			dir := ast.SEND
-			for ok && dir == ast.SEND {
-				if typ.Dir == ast.RECV {
-					// error: (<-type) is (<-(<-chan T))
-					p.errorExpected(typ.Arrow, "'chan'")
-				}
-				arrow, typ.Begin, typ.Arrow = typ.Arrow, arrow, arrow
-				dir, typ.Dir = typ.Dir, ast.RECV
-				typ, ok = typ.Value.(*ast.ChanType)
-			}
-			if dir == ast.SEND {
-				p.errorExpected(arrow, "channel type")
-			}
-
-			return x
-		}
-
-		// <-(expr)
-		return &ast.UnaryExpr{OpPos: arrow, Op: token.ARROW, X: p.checkExpr(x)}
-
-	case token.MUL:
-		// pointer type or unary "*" expression
-		pos := p.pos
-		p.next()
-		x := p.parseUnaryExpr(false)
-		return &ast.StarExpr{Star: pos, X: p.checkExprOrType(x)}
-	}
-
-	return p.parsePrimaryExpr(lhs)
-}
-
-func (p *parser) tokPrec() (token.Token, int) {
-	tok := p.tok
-	if p.inRhs && tok == token.ASSIGN {
-		tok = token.EQL
-	}
-	return tok, tok.Precedence()
-}
-
-// If lhs is set and the result is an identifier, it is not resolved.
-func (p *parser) parseBinaryExpr(lhs bool, prec1 int) ast.Expr {
-	if p.trace {
-		defer un(trace(p, "BinaryExpr"))
-	}
-
-	x := p.parseUnaryExpr(lhs)
-	for _, prec := p.tokPrec(); prec >= prec1; prec-- {
-		for {
-			op, oprec := p.tokPrec()
-			if oprec != prec {
-				break
-			}
-			pos := p.expect(op)
-			if lhs {
-				p.resolve(x)
-				lhs = false
-			}
-			y := p.parseBinaryExpr(false, prec+1)
-			x = &ast.BinaryExpr{X: p.checkExpr(x), OpPos: pos, Op: op, Y: p.checkExpr(y)}
-		}
-	}
-
-	return x
-}
-
-// If lhs is set and the result is an identifier, it is not resolved.
-// The result may be a type or even a raw type ([...]int). Callers must
-// check the result (using checkExpr or checkExprOrType), depending on
-// context.
-func (p *parser) parseExpr(lhs bool) ast.Expr {
-	if p.trace {
-		defer un(trace(p, "Expression"))
-	}
-
-	return p.parseBinaryExpr(lhs, token.LowestPrec+1)
-}
-
-func (p *parser) parseRhs() ast.Expr {
-	old := p.inRhs
-	p.inRhs = true
-	x := p.checkExpr(p.parseExpr(false))
-	p.inRhs = old
-	return x
-}
-
-func (p *parser) parseRhsOrType() ast.Expr {
-	old := p.inRhs
-	p.inRhs = true
-	x := p.checkExprOrType(p.parseExpr(false))
-	p.inRhs = old
-	return x
-}
-
-// ----------------------------------------------------------------------------
-// Statements
-
-// Parsing modes for parseSimpleStmt.
-const (
-	basic = iota
-	labelOk
-	rangeOk
-)
-
-// parseSimpleStmt returns true as 2nd result if it parsed the assignment
-// of a range clause (with mode == rangeOk). The returned statement is an
-// assignment with a right-hand side that is a single unary expression of
-// the form "range x". No guarantees are given for the left-hand side.
-func (p *parser) parseSimpleStmt(mode int) (ast.Stmt, bool) {
-	if p.trace {
-		defer un(trace(p, "SimpleStmt"))
-	}
-
-	x := p.parseLhsList()
-
-	switch p.tok {
-	case
-		token.DEFINE, token.ASSIGN, token.ADD_ASSIGN,
-		token.SUB_ASSIGN, token.MUL_ASSIGN, token.QUO_ASSIGN,
-		token.REM_ASSIGN, token.AND_ASSIGN, token.OR_ASSIGN,
-		token.XOR_ASSIGN, token.SHL_ASSIGN, token.SHR_ASSIGN, token.AND_NOT_ASSIGN:
-		// assignment statement, possibly part of a range clause
-		pos, tok := p.pos, p.tok
-		p.next()
-		var y []ast.Expr
-		isRange := false
-		if mode == rangeOk && p.tok == token.RANGE && (tok == token.DEFINE || tok == token.ASSIGN) {
-			pos := p.pos
-			p.next()
-			y = []ast.Expr{&ast.UnaryExpr{OpPos: pos, Op: token.RANGE, X: p.parseRhs()}}
-			isRange = true
-		} else {
-			y = p.parseRhsList()
-		}
-		as := &ast.AssignStmt{Lhs: x, TokPos: pos, Tok: tok, Rhs: y}
-		if tok == token.DEFINE {
-			p.shortVarDecl(as, x)
-		}
-		return as, isRange
-	}
-
-	if len(x) > 1 {
-		p.errorExpected(x[0].Pos(), "1 expression")
-		// continue with first expression
-	}
-
-	switch p.tok {
-	case token.COLON:
-		// labeled statement
-		colon := p.pos
-		p.next()
-		if label, isIdent := x[0].(*ast.Ident); mode == labelOk && isIdent {
-			// Go spec: The scope of a label is the body of the function
-			// in which it is declared and excludes the body of any nested
-			// function.
-			stmt := &ast.LabeledStmt{Label: label, Colon: colon, Stmt: p.parseStmt()}
-			p.declare(stmt, nil, p.labelScope, ast.Lbl, label)
-			return stmt, false
-		}
-		// The label declaration typically starts at x[0].Pos(), but the label
-		// declaration may be erroneous due to a token after that position (and
-		// before the ':'). If SpuriousErrors is not set, the (only) error re-
-		// ported for the line is the illegal label error instead of the token
-		// before the ':' that caused the problem. Thus, use the (latest) colon
-		// position for error reporting.
-		p.error(colon, "illegal label declaration")
-		return &ast.BadStmt{From: x[0].Pos(), To: colon + 1}, false
-
-	case token.ARROW:
-		// send statement
-		arrow := p.pos
-		p.next()
-		y := p.parseRhs()
-		return &ast.SendStmt{Chan: x[0], Arrow: arrow, Value: y}, false
-
-	case token.INC, token.DEC:
-		// increment or decrement
-		s := &ast.IncDecStmt{X: x[0], TokPos: p.pos, Tok: p.tok}
-		p.next()
-		return s, false
-	}
-
-	// expression
-	return &ast.ExprStmt{X: x[0]}, false
-}
-
-func (p *parser) parseCallExpr(callType string) *ast.CallExpr {
-	x := p.parseRhsOrType() // could be a conversion: (some type)(x)
-	if call, isCall := x.(*ast.CallExpr); isCall {
-		return call
-	}
-	if _, isBad := x.(*ast.BadExpr); !isBad {
-		// only report error if it's a new one
-		p.error(p.safePos(x.End()), fmt.Sprintf("function must be invoked in %s statement", callType))
-	}
-	return nil
-}
-
-func (p *parser) parseGoStmt() ast.Stmt {
-	if p.trace {
-		defer un(trace(p, "GoStmt"))
-	}
-
-	pos := p.expect(token.GO)
-	call := p.parseCallExpr("go")
-	p.expectSemi()
-	if call == nil {
-		return &ast.BadStmt{From: pos, To: pos + 2} // len("go")
-	}
-
-	return &ast.GoStmt{Go: pos, Call: call}
-}
-
-func (p *parser) parseDeferStmt() ast.Stmt {
-	if p.trace {
-		defer un(trace(p, "DeferStmt"))
-	}
-
-	pos := p.expect(token.DEFER)
-	call := p.parseCallExpr("defer")
-	p.expectSemi()
-	if call == nil {
-		return &ast.BadStmt{From: pos, To: pos + 5} // len("defer")
-	}
-
-	return &ast.DeferStmt{Defer: pos, Call: call}
-}
-
-func (p *parser) parseReturnStmt() *ast.ReturnStmt {
-	if p.trace {
-		defer un(trace(p, "ReturnStmt"))
-	}
-
-	pos := p.pos
-	p.expect(token.RETURN)
-	var x []ast.Expr
-	if p.tok != token.SEMICOLON && p.tok != token.RBRACE {
-		x = p.parseRhsList()
-	}
-	p.expectSemi()
-
-	return &ast.ReturnStmt{Return: pos, Results: x}
-}
-
-func (p *parser) parseBranchStmt(tok token.Token) *ast.BranchStmt {
-	if p.trace {
-		defer un(trace(p, "BranchStmt"))
-	}
-
-	pos := p.expect(tok)
-	var label *ast.Ident
-	if tok != token.FALLTHROUGH && p.tok == token.IDENT {
-		label = p.parseIdent()
-		// add to list of unresolved targets
-		n := len(p.targetStack) - 1
-		p.targetStack[n] = append(p.targetStack[n], label)
-	}
-	p.expectSemi()
-
-	return &ast.BranchStmt{TokPos: pos, Tok: tok, Label: label}
-}
-
-func (p *parser) makeExpr(s ast.Stmt, kind string) ast.Expr {
-	if s == nil {
-		return nil
-	}
-	if es, isExpr := s.(*ast.ExprStmt); isExpr {
-		return p.checkExpr(es.X)
-	}
-	p.error(s.Pos(), fmt.Sprintf("expected %s, found simple statement (missing parentheses around composite literal?)", kind))
-	return &ast.BadExpr{From: s.Pos(), To: p.safePos(s.End())}
-}
-
-func (p *parser) parseIfStmt() *ast.IfStmt {
-	if p.trace {
-		defer un(trace(p, "IfStmt"))
-	}
-
-	pos := p.expect(token.IF)
-	p.openScope()
-	defer p.closeScope()
-
-	var s ast.Stmt
-	var x ast.Expr
-	{
-		prevLev := p.exprLev
-		p.exprLev = -1
-		if p.tok == token.SEMICOLON {
-			p.next()
-			x = p.parseRhs()
-		} else {
-			s, _ = p.parseSimpleStmt(basic)
-			if p.tok == token.SEMICOLON {
-				p.next()
-				x = p.parseRhs()
-			} else {
-				x = p.makeExpr(s, "boolean expression")
-				s = nil
-			}
-		}
-		p.exprLev = prevLev
-	}
-
-	body := p.parseBlockStmt()
-	var else_ ast.Stmt
-	if p.tok == token.ELSE {
-		p.next()
-		else_ = p.parseStmt()
-	} else {
-		p.expectSemi()
-	}
-
-	return &ast.IfStmt{If: pos, Init: s, Cond: x, Body: body, Else: else_}
-}
-
-func (p *parser) parseTypeList() (list []ast.Expr) {
-	if p.trace {
-		defer un(trace(p, "TypeList"))
-	}
-
-	list = append(list, p.parseType())
-	for p.tok == token.COMMA {
-		p.next()
-		list = append(list, p.parseType())
-	}
-
-	return
-}
-
-func (p *parser) parseCaseClause(typeSwitch bool) *ast.CaseClause {
-	if p.trace {
-		defer un(trace(p, "CaseClause"))
-	}
-
-	pos := p.pos
-	var list []ast.Expr
-	if p.tok == token.CASE {
-		p.next()
-		if typeSwitch {
-			list = p.parseTypeList()
-		} else {
-			list = p.parseRhsList()
-		}
-	} else {
-		p.expect(token.DEFAULT)
-	}
-
-	colon := p.expect(token.COLON)
-	p.openScope()
-	body := p.parseStmtList()
-	p.closeScope()
-
-	return &ast.CaseClause{Case: pos, List: list, Colon: colon, Body: body}
-}
-
-func isTypeSwitchAssert(x ast.Expr) bool {
-	a, ok := x.(*ast.TypeAssertExpr)
-	return ok && a.Type == nil
-}
-
-func isTypeSwitchGuard(s ast.Stmt) bool {
-	switch t := s.(type) {
-	case *ast.ExprStmt:
-		// x.(nil)
-		return isTypeSwitchAssert(t.X)
-	case *ast.AssignStmt:
-		// v := x.(nil)
-		return len(t.Lhs) == 1 && t.Tok == token.DEFINE && len(t.Rhs) == 1 && isTypeSwitchAssert(t.Rhs[0])
-	}
-	return false
-}
-
-func (p *parser) parseSwitchStmt() ast.Stmt {
-	if p.trace {
-		defer un(trace(p, "SwitchStmt"))
-	}
-
-	pos := p.expect(token.SWITCH)
-	p.openScope()
-	defer p.closeScope()
-
-	var s1, s2 ast.Stmt
-	if p.tok != token.LBRACE {
-		prevLev := p.exprLev
-		p.exprLev = -1
-		if p.tok != token.SEMICOLON {
-			s2, _ = p.parseSimpleStmt(basic)
-		}
-		if p.tok == token.SEMICOLON {
-			p.next()
-			s1 = s2
-			s2 = nil
-			if p.tok != token.LBRACE {
-				// A TypeSwitchGuard may declare a variable in addition
-				// to the variable declared in the initial SimpleStmt.
-				// Introduce extra scope to avoid redeclaration errors:
-				//
-				//	switch t := 0; t := x.(T) { ... }
-				//
-				// (this code is not valid Go because the first t
-				// cannot be accessed and thus is never used, the extra
-				// scope is needed for the correct error message).
-				//
-				// If we don't have a type switch, s2 must be an expression.
-				// Having the extra nested but empty scope won't affect it.
-				p.openScope()
-				defer p.closeScope()
-				s2, _ = p.parseSimpleStmt(basic)
-			}
-		}
-		p.exprLev = prevLev
-	}
-
-	typeSwitch := isTypeSwitchGuard(s2)
-	lbrace := p.expect(token.LBRACE)
-	var list []ast.Stmt
-	for p.tok == token.CASE || p.tok == token.DEFAULT {
-		list = append(list, p.parseCaseClause(typeSwitch))
-	}
-	rbrace := p.expect(token.RBRACE)
-	p.expectSemi()
-	body := &ast.BlockStmt{Lbrace: lbrace, List: list, Rbrace: rbrace}
-
-	if typeSwitch {
-		return &ast.TypeSwitchStmt{Switch: pos, Init: s1, Assign: s2, Body: body}
-	}
-
-	return &ast.SwitchStmt{Switch: pos, Init: s1, Tag: p.makeExpr(s2, "switch expression"), Body: body}
-}
-
-func (p *parser) parseCommClause() *ast.CommClause {
-	if p.trace {
-		defer un(trace(p, "CommClause"))
-	}
-
-	p.openScope()
-	pos := p.pos
-	var comm ast.Stmt
-	if p.tok == token.CASE {
-		p.next()
-		lhs := p.parseLhsList()
-		if p.tok == token.ARROW {
-			// SendStmt
-			if len(lhs) > 1 {
-				p.errorExpected(lhs[0].Pos(), "1 expression")
-				// continue with first expression
-			}
-			arrow := p.pos
-			p.next()
-			rhs := p.parseRhs()
-			comm = &ast.SendStmt{Chan: lhs[0], Arrow: arrow, Value: rhs}
-		} else {
-			// RecvStmt
-			if tok := p.tok; tok == token.ASSIGN || tok == token.DEFINE {
-				// RecvStmt with assignment
-				if len(lhs) > 2 {
-					p.errorExpected(lhs[0].Pos(), "1 or 2 expressions")
-					// continue with first two expressions
-					lhs = lhs[0:2]
-				}
-				pos := p.pos
-				p.next()
-				rhs := p.parseRhs()
-				as := &ast.AssignStmt{Lhs: lhs, TokPos: pos, Tok: tok, Rhs: []ast.Expr{rhs}}
-				if tok == token.DEFINE {
-					p.shortVarDecl(as, lhs)
-				}
-				comm = as
-			} else {
-				// lhs must be single receive operation
-				if len(lhs) > 1 {
-					p.errorExpected(lhs[0].Pos(), "1 expression")
-					// continue with first expression
-				}
-				comm = &ast.ExprStmt{X: lhs[0]}
-			}
-		}
-	} else {
-		p.expect(token.DEFAULT)
-	}
-
-	colon := p.expect(token.COLON)
-	body := p.parseStmtList()
-	p.closeScope()
-
-	return &ast.CommClause{Case: pos, Comm: comm, Colon: colon, Body: body}
-}
-
-func (p *parser) parseSelectStmt() *ast.SelectStmt {
-	if p.trace {
-		defer un(trace(p, "SelectStmt"))
-	}
-
-	pos := p.expect(token.SELECT)
-	lbrace := p.expect(token.LBRACE)
-	var list []ast.Stmt
-	for p.tok == token.CASE || p.tok == token.DEFAULT {
-		list = append(list, p.parseCommClause())
-	}
-	rbrace := p.expect(token.RBRACE)
-	p.expectSemi()
-	body := &ast.BlockStmt{Lbrace: lbrace, List: list, Rbrace: rbrace}
-
-	return &ast.SelectStmt{Select: pos, Body: body}
-}
-
-func (p *parser) parseForStmt() ast.Stmt {
-	if p.trace {
-		defer un(trace(p, "ForStmt"))
-	}
-
-	pos := p.expect(token.FOR)
-	p.openScope()
-	defer p.closeScope()
-
-	var s1, s2, s3 ast.Stmt
-	var isRange bool
-	if p.tok != token.LBRACE {
-		prevLev := p.exprLev
-		p.exprLev = -1
-		if p.tok != token.SEMICOLON {
-			s2, isRange = p.parseSimpleStmt(rangeOk)
-		}
-		if !isRange && p.tok == token.SEMICOLON {
-			p.next()
-			s1 = s2
-			s2 = nil
-			if p.tok != token.SEMICOLON {
-				s2, _ = p.parseSimpleStmt(basic)
-			}
-			p.expectSemi()
-			if p.tok != token.LBRACE {
-				s3, _ = p.parseSimpleStmt(basic)
-			}
-		}
-		p.exprLev = prevLev
-	}
-
-	body := p.parseBlockStmt()
-	p.expectSemi()
-
-	if isRange {
-		as := s2.(*ast.AssignStmt)
-		// check lhs
-		var key, value ast.Expr
-		switch len(as.Lhs) {
-		case 2:
-			key, value = as.Lhs[0], as.Lhs[1]
-		case 1:
-			key = as.Lhs[0]
-		default:
-			p.errorExpected(as.Lhs[0].Pos(), "1 or 2 expressions")
-			return &ast.BadStmt{From: pos, To: p.safePos(body.End())}
-		}
-		// parseSimpleStmt returned a right-hand side that
-		// is a single unary expression of the form "range x"
-		x := as.Rhs[0].(*ast.UnaryExpr).X
-		return &ast.RangeStmt{
-			For:    pos,
-			Key:    key,
-			Value:  value,
-			TokPos: as.TokPos,
-			Tok:    as.Tok,
-			X:      x,
-			Body:   body,
-		}
-	}
-
-	// regular for statement
-	return &ast.ForStmt{
-		For:  pos,
-		Init: s1,
-		Cond: p.makeExpr(s2, "boolean or range expression"),
-		Post: s3,
-		Body: body,
-	}
-}
-
-func (p *parser) parseStmt() (s ast.Stmt) {
-	if p.trace {
-		defer un(trace(p, "Statement"))
-	}
-
-	switch p.tok {
-	case token.CONST, token.TYPE, token.VAR:
-		s = &ast.DeclStmt{Decl: p.parseDecl(syncStmt)}
-	case
-		// tokens that may start an expression
-		token.IDENT, token.INT, token.FLOAT, token.IMAG, token.CHAR, token.STRING, token.FUNC, token.LPAREN, // operands
-		token.LBRACK, token.STRUCT, // composite types
-		token.ADD, token.SUB, token.MUL, token.AND, token.XOR, token.ARROW, token.NOT: // unary operators
-		s, _ = p.parseSimpleStmt(labelOk)
-		// because of the required look-ahead, labeled statements are
-		// parsed by parseSimpleStmt - don't expect a semicolon after
-		// them
-		if _, isLabeledStmt := s.(*ast.LabeledStmt); !isLabeledStmt {
-			p.expectSemi()
-		}
-	case token.GO:
-		s = p.parseGoStmt()
-	case token.DEFER:
-		s = p.parseDeferStmt()
-	case token.RETURN:
-		s = p.parseReturnStmt()
-	case token.BREAK, token.CONTINUE, token.GOTO, token.FALLTHROUGH:
-		s = p.parseBranchStmt(p.tok)
-	case token.LBRACE:
-		s = p.parseBlockStmt()
-		p.expectSemi()
-	case token.IF:
-		s = p.parseIfStmt()
-	case token.SWITCH:
-		s = p.parseSwitchStmt()
-	case token.SELECT:
-		s = p.parseSelectStmt()
-	case token.FOR:
-		s = p.parseForStmt()
-	case token.SEMICOLON:
-		s = &ast.EmptyStmt{Semicolon: p.pos}
-		p.next()
-	case token.RBRACE:
-		// a semicolon may be omitted before a closing "}"
-		s = &ast.EmptyStmt{Semicolon: p.pos}
-	default:
-		// no statement found
-		pos := p.pos
-		p.errorExpected(pos, "statement")
-		syncStmt(p)
-		s = &ast.BadStmt{From: pos, To: p.pos}
-	}
-
-	return
-}
-
-// ----------------------------------------------------------------------------
-// Declarations
-
-type parseSpecFunction func(doc *ast.CommentGroup, keyword token.Token, iota int) ast.Spec
-
-func isValidImport(lit string) bool {
-	const illegalChars = `!"#$%&'()*,:;<=>?[\]^{|}` + "`\uFFFD"
-	s, _ := strconv.Unquote(lit) // go/scanner returns a legal string literal
-	for _, r := range s {
-		if !unicode.IsGraphic(r) || unicode.IsSpace(r) || strings.ContainsRune(illegalChars, r) {
-			return false
-		}
-	}
-	return s != ""
-}
-
-func (p *parser) parseImportSpec(doc *ast.CommentGroup, _ token.Token, _ int) ast.Spec {
-	if p.trace {
-		defer un(trace(p, "ImportSpec"))
-	}
-
-	var ident *ast.Ident
-	switch p.tok {
-	case token.PERIOD:
-		ident = &ast.Ident{NamePos: p.pos, Name: "."}
-		p.next()
-	case token.IDENT:
-		ident = p.parseIdent()
-	}
-
-	pos := p.pos
-	var path string
-	if p.tok == token.STRING {
-		path = p.lit
-		if !isValidImport(path) {
-			p.error(pos, "invalid import path: "+path)
-		}
-		p.next()
-	} else {
-		p.expect(token.STRING) // use expect() error handling
-	}
-	p.expectSemi() // call before accessing p.linecomment
-
-	// collect imports
-	spec := &ast.ImportSpec{
-		Doc:     doc,
-		Name:    ident,
-		Path:    &ast.BasicLit{ValuePos: pos, Kind: token.STRING, Value: path},
-		Comment: p.lineComment,
-	}
-	p.imports = append(p.imports, spec)
-
-	return spec
-}
-
-func (p *parser) parseValueSpec(doc *ast.CommentGroup, keyword token.Token, iota int) ast.Spec {
-	if p.trace {
-		defer un(trace(p, keyword.String()+"Spec"))
-	}
-
-	idents := p.parseIdentList()
-	typ := p.tryType()
-	var values []ast.Expr
-	// always permit optional initialization for more tolerant parsing
-	if p.tok == token.ASSIGN {
-		p.next()
-		values = p.parseRhsList()
-	}
-	p.expectSemi() // call before accessing p.linecomment
-
-	// Go spec: The scope of a constant or variable identifier declared inside
-	// a function begins at the end of the ConstSpec or VarSpec and ends at
-	// the end of the innermost containing block.
-	// (Global identifiers are resolved in a separate phase after parsing.)
-	spec := &ast.ValueSpec{
-		Doc:     doc,
-		Names:   idents,
-		Type:    typ,
-		Values:  values,
-		Comment: p.lineComment,
-	}
-	kind := ast.Con
-	if keyword == token.VAR {
-		kind = ast.Var
-	}
-	p.declare(spec, iota, p.topScope, kind, idents...)
-
-	return spec
-}
-
-func (p *parser) parseTypeSpec(doc *ast.CommentGroup, _ token.Token, _ int) ast.Spec {
-	if p.trace {
-		defer un(trace(p, "TypeSpec"))
-	}
-
-	ident := p.parseIdent()
-
-	// Go spec: The scope of a type identifier declared inside a function begins
-	// at the identifier in the TypeSpec and ends at the end of the innermost
-	// containing block.
-	// (Global identifiers are resolved in a separate phase after parsing.)
-	spec := &ast.TypeSpec{Doc: doc, Name: ident}
-	p.declare(spec, nil, p.topScope, ast.Typ, ident)
-
-	spec.Type = p.parseType()
-	p.expectSemi() // call before accessing p.linecomment
-	spec.Comment = p.lineComment
-
-	return spec
-}
-
-func (p *parser) parseGenDecl(keyword token.Token, f parseSpecFunction) *ast.GenDecl {
-	if p.trace {
-		defer un(trace(p, "GenDecl("+keyword.String()+")"))
-	}
-
-	doc := p.leadComment
-	pos := p.expect(keyword)
-	var lparen, rparen token.Pos
-	var list []ast.Spec
-	if p.tok == token.LPAREN {
-		lparen = p.pos
-		p.next()
-		for iota := 0; p.tok != token.RPAREN && p.tok != token.EOF; iota++ {
-			list = append(list, f(p.leadComment, keyword, iota))
-		}
-		rparen = p.expect(token.RPAREN)
-		p.expectSemi()
-	} else {
-		list = append(list, f(nil, keyword, 0))
-	}
-
-	return &ast.GenDecl{
-		Doc:    doc,
-		TokPos: pos,
-		Tok:    keyword,
-		Lparen: lparen,
-		Specs:  list,
-		Rparen: rparen,
-	}
-}
-
-func (p *parser) parseReceiver(scope *ast.Scope) *ast.FieldList {
-	if p.trace {
-		defer un(trace(p, "Receiver"))
-	}
-
-	par := p.parseParameters(scope, false)
-
-	// must have exactly one receiver
-	if par.NumFields() != 1 {
-		p.errorExpected(par.Opening, "exactly one receiver")
-		par.List = []*ast.Field{{Type: &ast.BadExpr{From: par.Opening, To: par.Closing + 1}}}
-		return par
-	}
-
-	// recv type must be of the form ["*"] identifier
-	recv := par.List[0]
-	base := deref(recv.Type)
-	if _, isIdent := base.(*ast.Ident); !isIdent {
-		if _, isBad := base.(*ast.BadExpr); !isBad {
-			// only report error if it's a new one
-			p.errorExpected(base.Pos(), "(unqualified) identifier")
-		}
-		par.List = []*ast.Field{
-			{Type: &ast.BadExpr{From: recv.Pos(), To: p.safePos(recv.End())}},
-		}
-	}
-
-	return par
-}
-
-func (p *parser) parseFuncDecl() *ast.FuncDecl {
-	if p.trace {
-		defer un(trace(p, "FunctionDecl"))
-	}
-
-	doc := p.leadComment
-	pos := p.expect(token.FUNC)
-	scope := ast.NewScope(p.topScope) // function scope
-
-	var recv *ast.FieldList
-	if p.tok == token.LPAREN {
-		recv = p.parseReceiver(scope)
-	}
-
-	ident := p.parseIdent()
-
-	params, results := p.parseSignature(scope)
-
-	var body *ast.BlockStmt
-	if p.tok == token.LBRACE {
-		body = p.parseBody(scope)
-	}
-	p.expectSemi()
-
-	decl := &ast.FuncDecl{
-		Doc:  doc,
-		Recv: recv,
-		Name: ident,
-		Type: &ast.FuncType{
-			Func:    pos,
-			Params:  params,
-			Results: results,
-		},
-		Body: body,
-	}
-	if recv == nil {
-		// Go spec: The scope of an identifier denoting a constant, type,
-		// variable, or function (but not method) declared at top level
-		// (outside any function) is the package block.
-		//
-		// init() functions cannot be referred to and there may
-		// be more than one - don't put them in the pkgScope
-		if ident.Name != "init" {
-			p.declare(decl, nil, p.pkgScope, ast.Fun, ident)
-		}
-	}
-
-	return decl
-}
-
-func (p *parser) parseDecl(sync func(*parser)) ast.Decl {
-	if p.trace {
-		defer un(trace(p, "Declaration"))
-	}
-
-	var f parseSpecFunction
-	switch p.tok {
-	case token.CONST, token.VAR:
-		f = p.parseValueSpec
-
-	case token.TYPE:
-		f = p.parseTypeSpec
-
-	case token.FUNC:
-		return p.parseFuncDecl()
-
-	default:
-		pos := p.pos
-		p.errorExpected(pos, "declaration")
-		sync(p)
-		return &ast.BadDecl{From: pos, To: p.pos}
-	}
-
-	return p.parseGenDecl(p.tok, f)
-}
-
-// ----------------------------------------------------------------------------
-// Source files
-
-func (p *parser) parseFile() *ast.File {
-	if p.trace {
-		defer un(trace(p, "File"))
-	}
-
-	// Don't bother parsing the rest if we had errors scanning the first token.
-	// Likely not a Go source file at all.
-	if p.errors.Len() != 0 {
-		return nil
-	}
-
-	// package clause
-	doc := p.leadComment
-	pos := p.expect(token.PACKAGE)
-	// Go spec: The package clause is not a declaration;
-	// the package name does not appear in any scope.
-	ident := p.parseIdent()
-	if ident.Name == "_" && p.mode&DeclarationErrors != 0 {
-		p.error(p.pos, "invalid package name _")
-	}
-	p.expectSemi()
-
-	// Don't bother parsing the rest if we had errors parsing the package clause.
-	// Likely not a Go source file at all.
-	if p.errors.Len() != 0 {
-		return nil
-	}
-
-	p.openScope()
-	p.pkgScope = p.topScope
-	var decls []ast.Decl
-	if p.mode&PackageClauseOnly == 0 {
-		// import decls
-		for p.tok == token.IMPORT {
-			decls = append(decls, p.parseGenDecl(token.IMPORT, p.parseImportSpec))
-		}
-
-		if p.mode&ImportsOnly == 0 {
-			// rest of package body
-			for p.tok != token.EOF {
-				decls = append(decls, p.parseDecl(syncDecl))
-			}
-		}
-	}
-	p.closeScope()
-	assert(p.topScope == nil, "unbalanced scopes")
-	assert(p.labelScope == nil, "unbalanced label scopes")
-
-	// resolve global identifiers within the same file
-	i := 0
-	for _, ident := range p.unresolved {
-		// i <= index for current ident
-		assert(ident.Obj == unresolved, "object already resolved")
-		ident.Obj = p.pkgScope.Lookup(ident.Name) // also removes unresolved sentinel
-		if ident.Obj == nil {
-			p.unresolved[i] = ident
-			i++
-		}
-	}
-
-	return &ast.File{
-		Doc:        doc,
-		Package:    pos,
-		Name:       ident,
-		Decls:      decls,
-		Scope:      p.pkgScope,
-		Imports:    p.imports,
-		Unresolved: p.unresolved[0:i],
-		Comments:   p.comments,
-	}
-}
diff --git a/src/pkg/go/parser/parser_test.go b/src/pkg/go/parser/parser_test.go
deleted file mode 100644
index 2797ea5..0000000
--- a/src/pkg/go/parser/parser_test.go
+++ /dev/null
@@ -1,431 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package parser
-
-import (
-	"bytes"
-	"fmt"
-	"go/ast"
-	"go/token"
-	"os"
-	"strings"
-	"testing"
-)
-
-var fset = token.NewFileSet()
-
-var validFiles = []string{
-	"parser.go",
-	"parser_test.go",
-	"error_test.go",
-	"short_test.go",
-}
-
-func TestParse(t *testing.T) {
-	for _, filename := range validFiles {
-		_, err := ParseFile(fset, filename, nil, DeclarationErrors)
-		if err != nil {
-			t.Fatalf("ParseFile(%s): %v", filename, err)
-		}
-	}
-}
-
-func nameFilter(filename string) bool {
-	switch filename {
-	case "parser.go", "interface.go", "parser_test.go":
-		return true
-	case "parser.go.orig":
-		return true // permit but should be ignored by ParseDir
-	}
-	return false
-}
-
-func dirFilter(f os.FileInfo) bool { return nameFilter(f.Name()) }
-
-func TestParseDir(t *testing.T) {
-	path := "."
-	pkgs, err := ParseDir(fset, path, dirFilter, 0)
-	if err != nil {
-		t.Fatalf("ParseDir(%s): %v", path, err)
-	}
-	if n := len(pkgs); n != 1 {
-		t.Errorf("got %d packages; want 1", n)
-	}
-	pkg := pkgs["parser"]
-	if pkg == nil {
-		t.Errorf(`package "parser" not found`)
-		return
-	}
-	if n := len(pkg.Files); n != 3 {
-		t.Errorf("got %d package files; want 3", n)
-	}
-	for filename := range pkg.Files {
-		if !nameFilter(filename) {
-			t.Errorf("unexpected package file: %s", filename)
-		}
-	}
-}
-
-func TestParseExpr(t *testing.T) {
-	// just kicking the tires:
-	// a valid arithmetic expression
-	src := "a + b"
-	x, err := ParseExpr(src)
-	if err != nil {
-		t.Fatalf("ParseExpr(%s): %v", src, err)
-	}
-	// sanity check
-	if _, ok := x.(*ast.BinaryExpr); !ok {
-		t.Errorf("ParseExpr(%s): got %T, want *ast.BinaryExpr", src, x)
-	}
-
-	// a valid type expression
-	src = "struct{x *int}"
-	x, err = ParseExpr(src)
-	if err != nil {
-		t.Fatalf("ParseExpr(%s): %v", src, err)
-	}
-	// sanity check
-	if _, ok := x.(*ast.StructType); !ok {
-		t.Errorf("ParseExpr(%s): got %T, want *ast.StructType", src, x)
-	}
-
-	// an invalid expression
-	src = "a + *"
-	_, err = ParseExpr(src)
-	if err == nil {
-		t.Fatalf("ParseExpr(%s): got no error", src)
-	}
-
-	// a valid expression followed by extra tokens is invalid
-	src = "a[i] := x"
-	_, err = ParseExpr(src)
-	if err == nil {
-		t.Fatalf("ParseExpr(%s): got no error", src)
-	}
-
-	// ParseExpr must not crash
-	for _, src := range valids {
-		ParseExpr(src)
-	}
-}
-
-func TestColonEqualsScope(t *testing.T) {
-	f, err := ParseFile(fset, "", `package p; func f() { x, y, z := x, y, z }`, 0)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	// RHS refers to undefined globals; LHS does not.
-	as := f.Decls[0].(*ast.FuncDecl).Body.List[0].(*ast.AssignStmt)
-	for _, v := range as.Rhs {
-		id := v.(*ast.Ident)
-		if id.Obj != nil {
-			t.Errorf("rhs %s has Obj, should not", id.Name)
-		}
-	}
-	for _, v := range as.Lhs {
-		id := v.(*ast.Ident)
-		if id.Obj == nil {
-			t.Errorf("lhs %s does not have Obj, should", id.Name)
-		}
-	}
-}
-
-func TestVarScope(t *testing.T) {
-	f, err := ParseFile(fset, "", `package p; func f() { var x, y, z = x, y, z }`, 0)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	// RHS refers to undefined globals; LHS does not.
-	as := f.Decls[0].(*ast.FuncDecl).Body.List[0].(*ast.DeclStmt).Decl.(*ast.GenDecl).Specs[0].(*ast.ValueSpec)
-	for _, v := range as.Values {
-		id := v.(*ast.Ident)
-		if id.Obj != nil {
-			t.Errorf("rhs %s has Obj, should not", id.Name)
-		}
-	}
-	for _, id := range as.Names {
-		if id.Obj == nil {
-			t.Errorf("lhs %s does not have Obj, should", id.Name)
-		}
-	}
-}
-
-func TestObjects(t *testing.T) {
-	const src = `
-package p
-import fmt "fmt"
-const pi = 3.14
-type T struct{}
-var x int
-func f() { L: }
-`
-
-	f, err := ParseFile(fset, "", src, 0)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	objects := map[string]ast.ObjKind{
-		"p":   ast.Bad, // not in a scope
-		"fmt": ast.Bad, // not resolved yet
-		"pi":  ast.Con,
-		"T":   ast.Typ,
-		"x":   ast.Var,
-		"int": ast.Bad, // not resolved yet
-		"f":   ast.Fun,
-		"L":   ast.Lbl,
-	}
-
-	ast.Inspect(f, func(n ast.Node) bool {
-		if ident, ok := n.(*ast.Ident); ok {
-			obj := ident.Obj
-			if obj == nil {
-				if objects[ident.Name] != ast.Bad {
-					t.Errorf("no object for %s", ident.Name)
-				}
-				return true
-			}
-			if obj.Name != ident.Name {
-				t.Errorf("names don't match: obj.Name = %s, ident.Name = %s", obj.Name, ident.Name)
-			}
-			kind := objects[ident.Name]
-			if obj.Kind != kind {
-				t.Errorf("%s: obj.Kind = %s; want %s", ident.Name, obj.Kind, kind)
-			}
-		}
-		return true
-	})
-}
-
-func TestUnresolved(t *testing.T) {
-	f, err := ParseFile(fset, "", `
-package p
-//
-func f1a(int)
-func f2a(byte, int, float)
-func f3a(a, b int, c float)
-func f4a(...complex)
-func f5a(a s1a, b ...complex)
-//
-func f1b(*int)
-func f2b([]byte, (int), *float)
-func f3b(a, b *int, c []float)
-func f4b(...*complex)
-func f5b(a s1a, b ...[]complex)
-//
-type s1a struct { int }
-type s2a struct { byte; int; s1a }
-type s3a struct { a, b int; c float }
-//
-type s1b struct { *int }
-type s2b struct { byte; int; *float }
-type s3b struct { a, b *s3b; c []float }
-`, 0)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	want := "int " + // f1a
-		"byte int float " + // f2a
-		"int float " + // f3a
-		"complex " + // f4a
-		"complex " + // f5a
-		//
-		"int " + // f1b
-		"byte int float " + // f2b
-		"int float " + // f3b
-		"complex " + // f4b
-		"complex " + // f5b
-		//
-		"int " + // s1a
-		"byte int " + // s2a
-		"int float " + // s3a
-		//
-		"int " + // s1a
-		"byte int float " + // s2a
-		"float " // s3a
-
-	// collect unresolved identifiers
-	var buf bytes.Buffer
-	for _, u := range f.Unresolved {
-		buf.WriteString(u.Name)
-		buf.WriteByte(' ')
-	}
-	got := buf.String()
-
-	if got != want {
-		t.Errorf("\ngot:  %s\nwant: %s", got, want)
-	}
-}
-
-var imports = map[string]bool{
-	`"a"`:        true,
-	"`a`":        true,
-	`"a/b"`:      true,
-	`"a.b"`:      true,
-	`"m\x61th"`:  true,
-	`"greek/αβ"`: true,
-	`""`:         false,
-
-	// Each of these pairs tests both `` vs "" strings
-	// and also use of invalid characters spelled out as
-	// escape sequences and written directly.
-	// For example `"\x00"` tests import "\x00"
-	// while "`\x00`" tests import `<actual-NUL-byte>`.
-	`"\x00"`:     false,
-	"`\x00`":     false,
-	`"\x7f"`:     false,
-	"`\x7f`":     false,
-	`"a!"`:       false,
-	"`a!`":       false,
-	`"a b"`:      false,
-	"`a b`":      false,
-	`"a\\b"`:     false,
-	"`a\\b`":     false,
-	"\"`a`\"":    false,
-	"`\"a\"`":    false,
-	`"\x80\x80"`: false,
-	"`\x80\x80`": false,
-	`"\xFFFD"`:   false,
-	"`\xFFFD`":   false,
-}
-
-func TestImports(t *testing.T) {
-	for path, isValid := range imports {
-		src := fmt.Sprintf("package p; import %s", path)
-		_, err := ParseFile(fset, "", src, 0)
-		switch {
-		case err != nil && isValid:
-			t.Errorf("ParseFile(%s): got %v; expected no error", src, err)
-		case err == nil && !isValid:
-			t.Errorf("ParseFile(%s): got no error; expected one", src)
-		}
-	}
-}
-
-func TestCommentGroups(t *testing.T) {
-	f, err := ParseFile(fset, "", `
-package p /* 1a */ /* 1b */      /* 1c */ // 1d
-/* 2a
-*/
-// 2b
-const pi = 3.1415
-/* 3a */ // 3b
-/* 3c */ const e = 2.7182
-
-// Example from issue 3139
-func ExampleCount() {
-	fmt.Println(strings.Count("cheese", "e"))
-	fmt.Println(strings.Count("five", "")) // before & after each rune
-	// Output:
-	// 3
-	// 5
-}
-`, ParseComments)
-	if err != nil {
-		t.Fatal(err)
-	}
-	expected := [][]string{
-		{"/* 1a */", "/* 1b */", "/* 1c */", "// 1d"},
-		{"/* 2a\n*/", "// 2b"},
-		{"/* 3a */", "// 3b", "/* 3c */"},
-		{"// Example from issue 3139"},
-		{"// before & after each rune"},
-		{"// Output:", "// 3", "// 5"},
-	}
-	if len(f.Comments) != len(expected) {
-		t.Fatalf("got %d comment groups; expected %d", len(f.Comments), len(expected))
-	}
-	for i, exp := range expected {
-		got := f.Comments[i].List
-		if len(got) != len(exp) {
-			t.Errorf("got %d comments in group %d; expected %d", len(got), i, len(exp))
-			continue
-		}
-		for j, exp := range exp {
-			got := got[j].Text
-			if got != exp {
-				t.Errorf("got %q in group %d; expected %q", got, i, exp)
-			}
-		}
-	}
-}
-
-func getField(file *ast.File, fieldname string) *ast.Field {
-	parts := strings.Split(fieldname, ".")
-	for _, d := range file.Decls {
-		if d, ok := d.(*ast.GenDecl); ok && d.Tok == token.TYPE {
-			for _, s := range d.Specs {
-				if s, ok := s.(*ast.TypeSpec); ok && s.Name.Name == parts[0] {
-					if s, ok := s.Type.(*ast.StructType); ok {
-						for _, f := range s.Fields.List {
-							for _, name := range f.Names {
-								if name.Name == parts[1] {
-									return f
-								}
-							}
-						}
-					}
-				}
-			}
-		}
-	}
-	return nil
-}
-
-// Don't use ast.CommentGroup.Text() - we want to see exact comment text.
-func commentText(c *ast.CommentGroup) string {
-	var buf bytes.Buffer
-	if c != nil {
-		for _, c := range c.List {
-			buf.WriteString(c.Text)
-		}
-	}
-	return buf.String()
-}
-
-func checkFieldComments(t *testing.T, file *ast.File, fieldname, lead, line string) {
-	f := getField(file, fieldname)
-	if f == nil {
-		t.Fatalf("field not found: %s", fieldname)
-	}
-	if got := commentText(f.Doc); got != lead {
-		t.Errorf("got lead comment %q; expected %q", got, lead)
-	}
-	if got := commentText(f.Comment); got != line {
-		t.Errorf("got line comment %q; expected %q", got, line)
-	}
-}
-
-func TestLeadAndLineComments(t *testing.T) {
-	f, err := ParseFile(fset, "", `
-package p
-type T struct {
-	/* F1 lead comment */
-	//
-	F1 int  /* F1 */ // line comment
-	// F2 lead
-	// comment
-	F2 int  // F2 line comment
-	// f3 lead comment
-	f3 int  // f3 line comment
-}
-`, ParseComments)
-	if err != nil {
-		t.Fatal(err)
-	}
-	checkFieldComments(t, f, "T.F1", "/* F1 lead comment *///", "/* F1 */// line comment")
-	checkFieldComments(t, f, "T.F2", "// F2 lead// comment", "// F2 line comment")
-	checkFieldComments(t, f, "T.f3", "// f3 lead comment", "// f3 line comment")
-	ast.FileExports(f)
-	checkFieldComments(t, f, "T.F1", "/* F1 lead comment *///", "/* F1 */// line comment")
-	checkFieldComments(t, f, "T.F2", "// F2 lead// comment", "// F2 line comment")
-	if getField(f, "T.f3") != nil {
-		t.Error("not expected to find T.f3")
-	}
-}
diff --git a/src/pkg/go/parser/short_test.go b/src/pkg/go/parser/short_test.go
deleted file mode 100644
index b794060..0000000
--- a/src/pkg/go/parser/short_test.go
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// This file contains test cases for short valid and invalid programs.
-
-package parser
-
-import "testing"
-
-var valids = []string{
-	"package p\n",
-	`package p;`,
-	`package p; import "fmt"; func f() { fmt.Println("Hello, World!") };`,
-	`package p; func f() { if f(T{}) {} };`,
-	`package p; func f() { _ = <-chan int(nil) };`,
-	`package p; func f() { _ = (<-chan int)(nil) };`,
-	`package p; func f() { _ = (<-chan <-chan int)(nil) };`,
-	`package p; func f() { _ = <-chan <-chan <-chan <-chan <-int(nil) };`,
-	`package p; func f(func() func() func());`,
-	`package p; func f(...T);`,
-	`package p; func f(float, ...int);`,
-	`package p; func f(x int, a ...int) { f(0, a...); f(1, a...,) };`,
-	`package p; func f(int,) {};`,
-	`package p; func f(...int,) {};`,
-	`package p; func f(x ...int,) {};`,
-	`package p; type T []int; var a []bool; func f() { if a[T{42}[0]] {} };`,
-	`package p; type T []int; func g(int) bool { return true }; func f() { if g(T{42}[0]) {} };`,
-	`package p; type T []int; func f() { for _ = range []int{T{42}[0]} {} };`,
-	`package p; var a = T{{1, 2}, {3, 4}}`,
-	`package p; func f() { select { case <- c: case c <- d: case c <- <- d: case <-c <- d: } };`,
-	`package p; func f() { select { case x := (<-c): } };`,
-	`package p; func f() { if ; true {} };`,
-	`package p; func f() { switch ; {} };`,
-	`package p; func f() { for _ = range "foo" + "bar" {} };`,
-	`package p; func f() { var s []int; g(s[:], s[i:], s[:j], s[i:j], s[i:j:k], s[:j:k]) };`,
-	`package p; var ( _ = (struct {*T}).m; _ = (interface {T}).m )`,
-}
-
-func TestValid(t *testing.T) {
-	for _, src := range valids {
-		checkErrors(t, src, src)
-	}
-}
-
-var invalids = []string{
-	`foo /* ERROR "expected 'package'" */ !`,
-	`package p; func f() { if { /* ERROR "expected operand" */ } };`,
-	`package p; func f() { if ; { /* ERROR "expected operand" */ } };`,
-	`package p; func f() { if f(); { /* ERROR "expected operand" */ } };`,
-	`package p; func f() { if _ /* ERROR "expected boolean expression" */ = range x; true {} };`,
-	`package p; func f() { switch _ /* ERROR "expected switch expression" */ = range x; true {} };`,
-	`package p; func f() { for _ = range x ; /* ERROR "expected '{'" */ ; {} };`,
-	`package p; func f() { for ; ; _ = range /* ERROR "expected operand" */ x {} };`,
-	`package p; func f() { for ; _ /* ERROR "expected boolean or range expression" */ = range x ; {} };`,
-	`package p; func f() { switch t /* ERROR "expected switch expression" */ = t.(type) {} };`,
-	`package p; func f() { switch t /* ERROR "expected switch expression" */ , t = t.(type) {} };`,
-	`package p; func f() { switch t /* ERROR "expected switch expression" */ = t.(type), t {} };`,
-	`package p; var a = [ /* ERROR "expected expression" */ 1]int;`,
-	`package p; var a = [ /* ERROR "expected expression" */ ...]int;`,
-	`package p; var a = struct /* ERROR "expected expression" */ {}`,
-	`package p; var a = func /* ERROR "expected expression" */ ();`,
-	`package p; var a = interface /* ERROR "expected expression" */ {}`,
-	`package p; var a = [ /* ERROR "expected expression" */ ]int`,
-	`package p; var a = map /* ERROR "expected expression" */ [int]int`,
-	`package p; var a = chan /* ERROR "expected expression" */ int;`,
-	`package p; var a = []int{[ /* ERROR "expected expression" */ ]int};`,
-	`package p; var a = ( /* ERROR "expected expression" */ []int);`,
-	`package p; var a = a[[ /* ERROR "expected expression" */ ]int:[]int];`,
-	`package p; var a = <- /* ERROR "expected expression" */ chan int;`,
-	`package p; func f() { select { case _ <- chan /* ERROR "expected expression" */ int: } };`,
-	`package p; func f() { _ = (<-<- /* ERROR "expected 'chan'" */ chan int)(nil) };`,
-	`package p; func f() { _ = (<-chan<-chan<-chan<-chan<-chan<- /* ERROR "expected channel type" */ int)(nil) };`,
-	`package p; func f() { var t []int; t /* ERROR "expected identifier on left side of :=" */ [0] := 0 };`,
-	`package p; func f() { if x := g(); x = /* ERROR "expected '=='" */ 0 {}};`,
-	`package p; func f() { _ = x = /* ERROR "expected '=='" */ 0 {}};`,
-	`package p; func f() { _ = 1 == func()int { var x bool; x = x = /* ERROR "expected '=='" */ true; return x }() };`,
-	`package p; func f() { var s []int; _ = s[] /* ERROR "expected operand" */ };`,
-	`package p; func f() { var s []int; _ = s[i:j: /* ERROR "3rd index required" */ ] };`,
-	`package p; func f() { var s []int; _ = s[i: /* ERROR "2nd index required" */ :k] };`,
-	`package p; func f() { var s []int; _ = s[i: /* ERROR "2nd index required" */ :] };`,
-	`package p; func f() { var s []int; _ = s[: /* ERROR "2nd index required" */ :] };`,
-	`package p; func f() { var s []int; _ = s[: /* ERROR "2nd index required" */ ::] };`,
-	`package p; func f() { var s []int; _ = s[i:j:k: /* ERROR "expected ']'" */ l] };`,
-	`package p; func f() { for x /* ERROR "boolean or range expression" */ = []string {} }`,
-	`package p; func f() { for x /* ERROR "boolean or range expression" */ := []string {} }`,
-	`package p; func f() { for i /* ERROR "boolean or range expression" */ , x = []string {} }`,
-	`package p; func f() { for i /* ERROR "boolean or range expression" */ , x := []string {} }`,
-	`package p; func f() { go f /* ERROR HERE "function must be invoked" */ }`,
-	`package p; func f() { defer func() {} /* ERROR HERE "function must be invoked" */ }`,
-	`package p; func f() { go func() { func() { f(x func /* ERROR "expected '\)'" */ (){}) } } }`,
-}
-
-func TestInvalid(t *testing.T) {
-	for _, src := range invalids {
-		checkErrors(t, src, src)
-	}
-}
diff --git a/src/pkg/go/printer/nodes.go b/src/pkg/go/printer/nodes.go
deleted file mode 100644
index 04b5f1a..0000000
--- a/src/pkg/go/printer/nodes.go
+++ /dev/null
@@ -1,1599 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// This file implements printing of AST nodes; specifically
-// expressions, statements, declarations, and files. It uses
-// the print functionality implemented in printer.go.
-
-package printer
-
-import (
-	"bytes"
-	"go/ast"
-	"go/token"
-	"unicode/utf8"
-)
-
-// Formatting issues:
-// - better comment formatting for /*-style comments at the end of a line (e.g. a declaration)
-//   when the comment spans multiple lines; if such a comment is just two lines, formatting is
-//   not idempotent
-// - formatting of expression lists
-// - should use blank instead of tab to separate one-line function bodies from
-//   the function header unless there is a group of consecutive one-liners
-
-// ----------------------------------------------------------------------------
-// Common AST nodes.
-
-// Print as many newlines as necessary (but at least min newlines) to get to
-// the current line. ws is printed before the first line break. If newSection
-// is set, the first line break is printed as formfeed. Returns true if any
-// line break was printed; returns false otherwise.
-//
-// TODO(gri): linebreak may add too many lines if the next statement at "line"
-//            is preceded by comments because the computation of n assumes
-//            the current position before the comment and the target position
-//            after the comment. Thus, after interspersing such comments, the
-//            space taken up by them is not considered to reduce the number of
-//            linebreaks. At the moment there is no easy way to know about
-//            future (not yet interspersed) comments in this function.
-//
-func (p *printer) linebreak(line, min int, ws whiteSpace, newSection bool) (printedBreak bool) {
-	n := nlimit(line - p.pos.Line)
-	if n < min {
-		n = min
-	}
-	if n > 0 {
-		p.print(ws)
-		if newSection {
-			p.print(formfeed)
-			n--
-		}
-		for ; n > 0; n-- {
-			p.print(newline)
-		}
-		printedBreak = true
-	}
-	return
-}
-
-// setComment sets g as the next comment if g != nil and if node comments
-// are enabled - this mode is used when printing source code fragments such
-// as exports only. It assumes that there is no pending comment in p.comments
-// and at most one pending comment in the p.comment cache.
-func (p *printer) setComment(g *ast.CommentGroup) {
-	if g == nil || !p.useNodeComments {
-		return
-	}
-	if p.comments == nil {
-		// initialize p.comments lazily
-		p.comments = make([]*ast.CommentGroup, 1)
-	} else if p.cindex < len(p.comments) {
-		// for some reason there are pending comments; this
-		// should never happen - handle gracefully and flush
-		// all comments up to g, ignore anything after that
-		p.flush(p.posFor(g.List[0].Pos()), token.ILLEGAL)
-		p.comments = p.comments[0:1]
-		// in debug mode, report error
-		p.internalError("setComment found pending comments")
-	}
-	p.comments[0] = g
-	p.cindex = 0
-	// don't overwrite any pending comment in the p.comment cache
-	// (there may be a pending comment when a line comment is
-	// immediately followed by a lead comment with no other
-	// tokens between)
-	if p.commentOffset == infinity {
-		p.nextComment() // get comment ready for use
-	}
-}
-
-type exprListMode uint
-
-const (
-	commaTerm exprListMode = 1 << iota // list is optionally terminated by a comma
-	noIndent                           // no extra indentation in multi-line lists
-)
-
-// If indent is set, a multi-line identifier list is indented after the
-// first linebreak encountered.
-func (p *printer) identList(list []*ast.Ident, indent bool) {
-	// convert into an expression list so we can re-use exprList formatting
-	xlist := make([]ast.Expr, len(list))
-	for i, x := range list {
-		xlist[i] = x
-	}
-	var mode exprListMode
-	if !indent {
-		mode = noIndent
-	}
-	p.exprList(token.NoPos, xlist, 1, mode, token.NoPos)
-}
-
-// Print a list of expressions. If the list spans multiple
-// source lines, the original line breaks are respected between
-// expressions.
-//
-// TODO(gri) Consider rewriting this to be independent of []ast.Expr
-//           so that we can use the algorithm for any kind of list
-//           (e.g., pass list via a channel over which to range).
-func (p *printer) exprList(prev0 token.Pos, list []ast.Expr, depth int, mode exprListMode, next0 token.Pos) {
-	if len(list) == 0 {
-		return
-	}
-
-	prev := p.posFor(prev0)
-	next := p.posFor(next0)
-	line := p.lineFor(list[0].Pos())
-	endLine := p.lineFor(list[len(list)-1].End())
-
-	if prev.IsValid() && prev.Line == line && line == endLine {
-		// all list entries on a single line
-		for i, x := range list {
-			if i > 0 {
-				// use position of expression following the comma as
-				// comma position for correct comment placement
-				p.print(x.Pos(), token.COMMA, blank)
-			}
-			p.expr0(x, depth)
-		}
-		return
-	}
-
-	// list entries span multiple lines;
-	// use source code positions to guide line breaks
-
-	// don't add extra indentation if noIndent is set;
-	// i.e., pretend that the first line is already indented
-	ws := ignore
-	if mode&noIndent == 0 {
-		ws = indent
-	}
-
-	// the first linebreak is always a formfeed since this section must not
-	// depend on any previous formatting
-	prevBreak := -1 // index of last expression that was followed by a linebreak
-	if prev.IsValid() && prev.Line < line && p.linebreak(line, 0, ws, true) {
-		ws = ignore
-		prevBreak = 0
-	}
-
-	// initialize expression/key size: a zero value indicates expr/key doesn't fit on a single line
-	size := 0
-
-	// print all list elements
-	for i, x := range list {
-		prevLine := line
-		line = p.lineFor(x.Pos())
-
-		// determine if the next linebreak, if any, needs to use formfeed:
-		// in general, use the entire node size to make the decision; for
-		// key:value expressions, use the key size
-		// TODO(gri) for a better result, should probably incorporate both
-		//           the key and the node size into the decision process
-		useFF := true
-
-		// determine element size: all bets are off if we don't have
-		// position information for the previous and next token (likely
-		// generated code - simply ignore the size in this case by setting
-		// it to 0)
-		prevSize := size
-		const infinity = 1e6 // larger than any source line
-		size = p.nodeSize(x, infinity)
-		pair, isPair := x.(*ast.KeyValueExpr)
-		if size <= infinity && prev.IsValid() && next.IsValid() {
-			// x fits on a single line
-			if isPair {
-				size = p.nodeSize(pair.Key, infinity) // size <= infinity
-			}
-		} else {
-			// size too large or we don't have good layout information
-			size = 0
-		}
-
-		// if the previous line and the current line had single-
-		// line-expressions and the key sizes are small or the
-		// the ratio between the key sizes does not exceed a
-		// threshold, align columns and do not use formfeed
-		if prevSize > 0 && size > 0 {
-			const smallSize = 20
-			if prevSize <= smallSize && size <= smallSize {
-				useFF = false
-			} else {
-				const r = 4 // threshold
-				ratio := float64(size) / float64(prevSize)
-				useFF = ratio <= 1.0/r || r <= ratio
-			}
-		}
-
-		if i > 0 {
-			needsLinebreak := prevLine < line && prevLine > 0 && line > 0
-			// use position of expression following the comma as
-			// comma position for correct comment placement, but
-			// only if the expression is on the same line
-			if !needsLinebreak {
-				p.print(x.Pos())
-			}
-			p.print(token.COMMA)
-			needsBlank := true
-			if needsLinebreak {
-				// lines are broken using newlines so comments remain aligned
-				// unless forceFF is set or there are multiple expressions on
-				// the same line in which case formfeed is used
-				if p.linebreak(line, 0, ws, useFF || prevBreak+1 < i) {
-					ws = ignore
-					prevBreak = i
-					needsBlank = false // we got a line break instead
-				}
-			}
-			if needsBlank {
-				p.print(blank)
-			}
-		}
-
-		if isPair && size > 0 && len(list) > 1 {
-			// we have a key:value expression that fits onto one line and
-			// is in a list with more then one entry: use a column for the
-			// key such that consecutive entries can align if possible
-			p.expr(pair.Key)
-			p.print(pair.Colon, token.COLON, vtab)
-			p.expr(pair.Value)
-		} else {
-			p.expr0(x, depth)
-		}
-	}
-
-	if mode&commaTerm != 0 && next.IsValid() && p.pos.Line < next.Line {
-		// print a terminating comma if the next token is on a new line
-		p.print(token.COMMA)
-		if ws == ignore && mode&noIndent == 0 {
-			// unindent if we indented
-			p.print(unindent)
-		}
-		p.print(formfeed) // terminating comma needs a line break to look good
-		return
-	}
-
-	if ws == ignore && mode&noIndent == 0 {
-		// unindent if we indented
-		p.print(unindent)
-	}
-}
-
-func (p *printer) parameters(fields *ast.FieldList) {
-	p.print(fields.Opening, token.LPAREN)
-	if len(fields.List) > 0 {
-		prevLine := p.lineFor(fields.Opening)
-		ws := indent
-		for i, par := range fields.List {
-			// determine par begin and end line (may be different
-			// if there are multiple parameter names for this par
-			// or the type is on a separate line)
-			var parLineBeg int
-			if len(par.Names) > 0 {
-				parLineBeg = p.lineFor(par.Names[0].Pos())
-			} else {
-				parLineBeg = p.lineFor(par.Type.Pos())
-			}
-			var parLineEnd = p.lineFor(par.Type.End())
-			// separating "," if needed
-			needsLinebreak := 0 < prevLine && prevLine < parLineBeg
-			if i > 0 {
-				// use position of parameter following the comma as
-				// comma position for correct comma placement, but
-				// only if the next parameter is on the same line
-				if !needsLinebreak {
-					p.print(par.Pos())
-				}
-				p.print(token.COMMA)
-			}
-			// separator if needed (linebreak or blank)
-			if needsLinebreak && p.linebreak(parLineBeg, 0, ws, true) {
-				// break line if the opening "(" or previous parameter ended on a different line
-				ws = ignore
-			} else if i > 0 {
-				p.print(blank)
-			}
-			// parameter names
-			if len(par.Names) > 0 {
-				// Very subtle: If we indented before (ws == ignore), identList
-				// won't indent again. If we didn't (ws == indent), identList will
-				// indent if the identList spans multiple lines, and it will outdent
-				// again at the end (and still ws == indent). Thus, a subsequent indent
-				// by a linebreak call after a type, or in the next multi-line identList
-				// will do the right thing.
-				p.identList(par.Names, ws == indent)
-				p.print(blank)
-			}
-			// parameter type
-			p.expr(stripParensAlways(par.Type))
-			prevLine = parLineEnd
-		}
-		// if the closing ")" is on a separate line from the last parameter,
-		// print an additional "," and line break
-		if closing := p.lineFor(fields.Closing); 0 < prevLine && prevLine < closing {
-			p.print(token.COMMA)
-			p.linebreak(closing, 0, ignore, true)
-		}
-		// unindent if we indented
-		if ws == ignore {
-			p.print(unindent)
-		}
-	}
-	p.print(fields.Closing, token.RPAREN)
-}
-
-func (p *printer) signature(params, result *ast.FieldList) {
-	if params != nil {
-		p.parameters(params)
-	} else {
-		p.print(token.LPAREN, token.RPAREN)
-	}
-	n := result.NumFields()
-	if n > 0 {
-		// result != nil
-		p.print(blank)
-		if n == 1 && result.List[0].Names == nil {
-			// single anonymous result; no ()'s
-			p.expr(stripParensAlways(result.List[0].Type))
-			return
-		}
-		p.parameters(result)
-	}
-}
-
-func identListSize(list []*ast.Ident, maxSize int) (size int) {
-	for i, x := range list {
-		if i > 0 {
-			size += len(", ")
-		}
-		size += utf8.RuneCountInString(x.Name)
-		if size >= maxSize {
-			break
-		}
-	}
-	return
-}
-
-func (p *printer) isOneLineFieldList(list []*ast.Field) bool {
-	if len(list) != 1 {
-		return false // allow only one field
-	}
-	f := list[0]
-	if f.Tag != nil || f.Comment != nil {
-		return false // don't allow tags or comments
-	}
-	// only name(s) and type
-	const maxSize = 30 // adjust as appropriate, this is an approximate value
-	namesSize := identListSize(f.Names, maxSize)
-	if namesSize > 0 {
-		namesSize = 1 // blank between names and types
-	}
-	typeSize := p.nodeSize(f.Type, maxSize)
-	return namesSize+typeSize <= maxSize
-}
-
-func (p *printer) setLineComment(text string) {
-	p.setComment(&ast.CommentGroup{List: []*ast.Comment{{Slash: token.NoPos, Text: text}}})
-}
-
-func (p *printer) fieldList(fields *ast.FieldList, isStruct, isIncomplete bool) {
-	lbrace := fields.Opening
-	list := fields.List
-	rbrace := fields.Closing
-	hasComments := isIncomplete || p.commentBefore(p.posFor(rbrace))
-	srcIsOneLine := lbrace.IsValid() && rbrace.IsValid() && p.lineFor(lbrace) == p.lineFor(rbrace)
-
-	if !hasComments && srcIsOneLine {
-		// possibly a one-line struct/interface
-		if len(list) == 0 {
-			// no blank between keyword and {} in this case
-			p.print(lbrace, token.LBRACE, rbrace, token.RBRACE)
-			return
-		} else if isStruct && p.isOneLineFieldList(list) { // for now ignore interfaces
-			// small enough - print on one line
-			// (don't use identList and ignore source line breaks)
-			p.print(lbrace, token.LBRACE, blank)
-			f := list[0]
-			for i, x := range f.Names {
-				if i > 0 {
-					// no comments so no need for comma position
-					p.print(token.COMMA, blank)
-				}
-				p.expr(x)
-			}
-			if len(f.Names) > 0 {
-				p.print(blank)
-			}
-			p.expr(f.Type)
-			p.print(blank, rbrace, token.RBRACE)
-			return
-		}
-	}
-	// hasComments || !srcIsOneLine
-
-	p.print(blank, lbrace, token.LBRACE, indent)
-	if hasComments || len(list) > 0 {
-		p.print(formfeed)
-	}
-
-	if isStruct {
-
-		sep := vtab
-		if len(list) == 1 {
-			sep = blank
-		}
-		var line int
-		for i, f := range list {
-			if i > 0 {
-				p.linebreak(p.lineFor(f.Pos()), 1, ignore, p.linesFrom(line) > 0)
-			}
-			extraTabs := 0
-			p.setComment(f.Doc)
-			p.recordLine(&line)
-			if len(f.Names) > 0 {
-				// named fields
-				p.identList(f.Names, false)
-				p.print(sep)
-				p.expr(f.Type)
-				extraTabs = 1
-			} else {
-				// anonymous field
-				p.expr(f.Type)
-				extraTabs = 2
-			}
-			if f.Tag != nil {
-				if len(f.Names) > 0 && sep == vtab {
-					p.print(sep)
-				}
-				p.print(sep)
-				p.expr(f.Tag)
-				extraTabs = 0
-			}
-			if f.Comment != nil {
-				for ; extraTabs > 0; extraTabs-- {
-					p.print(sep)
-				}
-				p.setComment(f.Comment)
-			}
-		}
-		if isIncomplete {
-			if len(list) > 0 {
-				p.print(formfeed)
-			}
-			p.flush(p.posFor(rbrace), token.RBRACE) // make sure we don't lose the last line comment
-			p.setLineComment("// contains filtered or unexported fields")
-		}
-
-	} else { // interface
-
-		var line int
-		for i, f := range list {
-			if i > 0 {
-				p.linebreak(p.lineFor(f.Pos()), 1, ignore, p.linesFrom(line) > 0)
-			}
-			p.setComment(f.Doc)
-			p.recordLine(&line)
-			if ftyp, isFtyp := f.Type.(*ast.FuncType); isFtyp {
-				// method
-				p.expr(f.Names[0])
-				p.signature(ftyp.Params, ftyp.Results)
-			} else {
-				// embedded interface
-				p.expr(f.Type)
-			}
-			p.setComment(f.Comment)
-		}
-		if isIncomplete {
-			if len(list) > 0 {
-				p.print(formfeed)
-			}
-			p.flush(p.posFor(rbrace), token.RBRACE) // make sure we don't lose the last line comment
-			p.setLineComment("// contains filtered or unexported methods")
-		}
-
-	}
-	p.print(unindent, formfeed, rbrace, token.RBRACE)
-}
-
-// ----------------------------------------------------------------------------
-// Expressions
-
-func walkBinary(e *ast.BinaryExpr) (has4, has5 bool, maxProblem int) {
-	switch e.Op.Precedence() {
-	case 4:
-		has4 = true
-	case 5:
-		has5 = true
-	}
-
-	switch l := e.X.(type) {
-	case *ast.BinaryExpr:
-		if l.Op.Precedence() < e.Op.Precedence() {
-			// parens will be inserted.
-			// pretend this is an *ast.ParenExpr and do nothing.
-			break
-		}
-		h4, h5, mp := walkBinary(l)
-		has4 = has4 || h4
-		has5 = has5 || h5
-		if maxProblem < mp {
-			maxProblem = mp
-		}
-	}
-
-	switch r := e.Y.(type) {
-	case *ast.BinaryExpr:
-		if r.Op.Precedence() <= e.Op.Precedence() {
-			// parens will be inserted.
-			// pretend this is an *ast.ParenExpr and do nothing.
-			break
-		}
-		h4, h5, mp := walkBinary(r)
-		has4 = has4 || h4
-		has5 = has5 || h5
-		if maxProblem < mp {
-			maxProblem = mp
-		}
-
-	case *ast.StarExpr:
-		if e.Op == token.QUO { // `*/`
-			maxProblem = 5
-		}
-
-	case *ast.UnaryExpr:
-		switch e.Op.String() + r.Op.String() {
-		case "/*", "&&", "&^":
-			maxProblem = 5
-		case "++", "--":
-			if maxProblem < 4 {
-				maxProblem = 4
-			}
-		}
-	}
-	return
-}
-
-func cutoff(e *ast.BinaryExpr, depth int) int {
-	has4, has5, maxProblem := walkBinary(e)
-	if maxProblem > 0 {
-		return maxProblem + 1
-	}
-	if has4 && has5 {
-		if depth == 1 {
-			return 5
-		}
-		return 4
-	}
-	if depth == 1 {
-		return 6
-	}
-	return 4
-}
-
-func diffPrec(expr ast.Expr, prec int) int {
-	x, ok := expr.(*ast.BinaryExpr)
-	if !ok || prec != x.Op.Precedence() {
-		return 1
-	}
-	return 0
-}
-
-func reduceDepth(depth int) int {
-	depth--
-	if depth < 1 {
-		depth = 1
-	}
-	return depth
-}
-
-// Format the binary expression: decide the cutoff and then format.
-// Let's call depth == 1 Normal mode, and depth > 1 Compact mode.
-// (Algorithm suggestion by Russ Cox.)
-//
-// The precedences are:
-//	5             *  /  %  <<  >>  &  &^
-//	4             +  -  |  ^
-//	3             ==  !=  <  <=  >  >=
-//	2             &&
-//	1             ||
-//
-// The only decision is whether there will be spaces around levels 4 and 5.
-// There are never spaces at level 6 (unary), and always spaces at levels 3 and below.
-//
-// To choose the cutoff, look at the whole expression but excluding primary
-// expressions (function calls, parenthesized exprs), and apply these rules:
-//
-//	1) If there is a binary operator with a right side unary operand
-//	   that would clash without a space, the cutoff must be (in order):
-//
-//		/*	6
-//		&&	6
-//		&^	6
-//		++	5
-//		--	5
-//
-//         (Comparison operators always have spaces around them.)
-//
-//	2) If there is a mix of level 5 and level 4 operators, then the cutoff
-//	   is 5 (use spaces to distinguish precedence) in Normal mode
-//	   and 4 (never use spaces) in Compact mode.
-//
-//	3) If there are no level 4 operators or no level 5 operators, then the
-//	   cutoff is 6 (always use spaces) in Normal mode
-//	   and 4 (never use spaces) in Compact mode.
-//
-func (p *printer) binaryExpr(x *ast.BinaryExpr, prec1, cutoff, depth int) {
-	prec := x.Op.Precedence()
-	if prec < prec1 {
-		// parenthesis needed
-		// Note: The parser inserts an ast.ParenExpr node; thus this case
-		//       can only occur if the AST is created in a different way.
-		p.print(token.LPAREN)
-		p.expr0(x, reduceDepth(depth)) // parentheses undo one level of depth
-		p.print(token.RPAREN)
-		return
-	}
-
-	printBlank := prec < cutoff
-
-	ws := indent
-	p.expr1(x.X, prec, depth+diffPrec(x.X, prec))
-	if printBlank {
-		p.print(blank)
-	}
-	xline := p.pos.Line // before the operator (it may be on the next line!)
-	yline := p.lineFor(x.Y.Pos())
-	p.print(x.OpPos, x.Op)
-	if xline != yline && xline > 0 && yline > 0 {
-		// at least one line break, but respect an extra empty line
-		// in the source
-		if p.linebreak(yline, 1, ws, true) {
-			ws = ignore
-			printBlank = false // no blank after line break
-		}
-	}
-	if printBlank {
-		p.print(blank)
-	}
-	p.expr1(x.Y, prec+1, depth+1)
-	if ws == ignore {
-		p.print(unindent)
-	}
-}
-
-func isBinary(expr ast.Expr) bool {
-	_, ok := expr.(*ast.BinaryExpr)
-	return ok
-}
-
-func (p *printer) expr1(expr ast.Expr, prec1, depth int) {
-	p.print(expr.Pos())
-
-	switch x := expr.(type) {
-	case *ast.BadExpr:
-		p.print("BadExpr")
-
-	case *ast.Ident:
-		p.print(x)
-
-	case *ast.BinaryExpr:
-		if depth < 1 {
-			p.internalError("depth < 1:", depth)
-			depth = 1
-		}
-		p.binaryExpr(x, prec1, cutoff(x, depth), depth)
-
-	case *ast.KeyValueExpr:
-		p.expr(x.Key)
-		p.print(x.Colon, token.COLON, blank)
-		p.expr(x.Value)
-
-	case *ast.StarExpr:
-		const prec = token.UnaryPrec
-		if prec < prec1 {
-			// parenthesis needed
-			p.print(token.LPAREN)
-			p.print(token.MUL)
-			p.expr(x.X)
-			p.print(token.RPAREN)
-		} else {
-			// no parenthesis needed
-			p.print(token.MUL)
-			p.expr(x.X)
-		}
-
-	case *ast.UnaryExpr:
-		const prec = token.UnaryPrec
-		if prec < prec1 {
-			// parenthesis needed
-			p.print(token.LPAREN)
-			p.expr(x)
-			p.print(token.RPAREN)
-		} else {
-			// no parenthesis needed
-			p.print(x.Op)
-			if x.Op == token.RANGE {
-				// TODO(gri) Remove this code if it cannot be reached.
-				p.print(blank)
-			}
-			p.expr1(x.X, prec, depth)
-		}
-
-	case *ast.BasicLit:
-		p.print(x)
-
-	case *ast.FuncLit:
-		p.expr(x.Type)
-		p.adjBlock(p.distanceFrom(x.Type.Pos()), blank, x.Body)
-
-	case *ast.ParenExpr:
-		if _, hasParens := x.X.(*ast.ParenExpr); hasParens {
-			// don't print parentheses around an already parenthesized expression
-			// TODO(gri) consider making this more general and incorporate precedence levels
-			p.expr0(x.X, reduceDepth(depth)) // parentheses undo one level of depth
-		} else {
-			p.print(token.LPAREN)
-			p.expr0(x.X, reduceDepth(depth)) // parentheses undo one level of depth
-			p.print(x.Rparen, token.RPAREN)
-		}
-
-	case *ast.SelectorExpr:
-		p.expr1(x.X, token.HighestPrec, depth)
-		p.print(token.PERIOD)
-		if line := p.lineFor(x.Sel.Pos()); p.pos.IsValid() && p.pos.Line < line {
-			p.print(indent, newline, x.Sel.Pos(), x.Sel, unindent)
-		} else {
-			p.print(x.Sel.Pos(), x.Sel)
-		}
-
-	case *ast.TypeAssertExpr:
-		p.expr1(x.X, token.HighestPrec, depth)
-		p.print(token.PERIOD, x.Lparen, token.LPAREN)
-		if x.Type != nil {
-			p.expr(x.Type)
-		} else {
-			p.print(token.TYPE)
-		}
-		p.print(x.Rparen, token.RPAREN)
-
-	case *ast.IndexExpr:
-		// TODO(gri): should treat[] like parentheses and undo one level of depth
-		p.expr1(x.X, token.HighestPrec, 1)
-		p.print(x.Lbrack, token.LBRACK)
-		p.expr0(x.Index, depth+1)
-		p.print(x.Rbrack, token.RBRACK)
-
-	case *ast.SliceExpr:
-		// TODO(gri): should treat[] like parentheses and undo one level of depth
-		p.expr1(x.X, token.HighestPrec, 1)
-		p.print(x.Lbrack, token.LBRACK)
-		indices := []ast.Expr{x.Low, x.High}
-		if x.Max != nil {
-			indices = append(indices, x.Max)
-		}
-		for i, y := range indices {
-			if i > 0 {
-				// blanks around ":" if both sides exist and either side is a binary expression
-				// TODO(gri) once we have committed a variant of a[i:j:k] we may want to fine-
-				//           tune the formatting here
-				x := indices[i-1]
-				if depth <= 1 && x != nil && y != nil && (isBinary(x) || isBinary(y)) {
-					p.print(blank, token.COLON, blank)
-				} else {
-					p.print(token.COLON)
-				}
-			}
-			if y != nil {
-				p.expr0(y, depth+1)
-			}
-		}
-		p.print(x.Rbrack, token.RBRACK)
-
-	case *ast.CallExpr:
-		if len(x.Args) > 1 {
-			depth++
-		}
-		if _, ok := x.Fun.(*ast.FuncType); ok {
-			// conversions to literal function types require parentheses around the type
-			p.print(token.LPAREN)
-			p.expr1(x.Fun, token.HighestPrec, depth)
-			p.print(token.RPAREN)
-		} else {
-			p.expr1(x.Fun, token.HighestPrec, depth)
-		}
-		p.print(x.Lparen, token.LPAREN)
-		if x.Ellipsis.IsValid() {
-			p.exprList(x.Lparen, x.Args, depth, 0, x.Ellipsis)
-			p.print(x.Ellipsis, token.ELLIPSIS)
-			if x.Rparen.IsValid() && p.lineFor(x.Ellipsis) < p.lineFor(x.Rparen) {
-				p.print(token.COMMA, formfeed)
-			}
-		} else {
-			p.exprList(x.Lparen, x.Args, depth, commaTerm, x.Rparen)
-		}
-		p.print(x.Rparen, token.RPAREN)
-
-	case *ast.CompositeLit:
-		// composite literal elements that are composite literals themselves may have the type omitted
-		if x.Type != nil {
-			p.expr1(x.Type, token.HighestPrec, depth)
-		}
-		p.print(x.Lbrace, token.LBRACE)
-		p.exprList(x.Lbrace, x.Elts, 1, commaTerm, x.Rbrace)
-		// do not insert extra line break following a /*-style comment
-		// before the closing '}' as it might break the code if there
-		// is no trailing ','
-		mode := noExtraLinebreak
-		// do not insert extra blank following a /*-style comment
-		// before the closing '}' unless the literal is empty
-		if len(x.Elts) > 0 {
-			mode |= noExtraBlank
-		}
-		p.print(mode, x.Rbrace, token.RBRACE, mode)
-
-	case *ast.Ellipsis:
-		p.print(token.ELLIPSIS)
-		if x.Elt != nil {
-			p.expr(x.Elt)
-		}
-
-	case *ast.ArrayType:
-		p.print(token.LBRACK)
-		if x.Len != nil {
-			p.expr(x.Len)
-		}
-		p.print(token.RBRACK)
-		p.expr(x.Elt)
-
-	case *ast.StructType:
-		p.print(token.STRUCT)
-		p.fieldList(x.Fields, true, x.Incomplete)
-
-	case *ast.FuncType:
-		p.print(token.FUNC)
-		p.signature(x.Params, x.Results)
-
-	case *ast.InterfaceType:
-		p.print(token.INTERFACE)
-		p.fieldList(x.Methods, false, x.Incomplete)
-
-	case *ast.MapType:
-		p.print(token.MAP, token.LBRACK)
-		p.expr(x.Key)
-		p.print(token.RBRACK)
-		p.expr(x.Value)
-
-	case *ast.ChanType:
-		switch x.Dir {
-		case ast.SEND | ast.RECV:
-			p.print(token.CHAN)
-		case ast.RECV:
-			p.print(token.ARROW, token.CHAN) // x.Arrow and x.Pos() are the same
-		case ast.SEND:
-			p.print(token.CHAN, x.Arrow, token.ARROW)
-		}
-		p.print(blank)
-		p.expr(x.Value)
-
-	default:
-		panic("unreachable")
-	}
-
-	return
-}
-
-func (p *printer) expr0(x ast.Expr, depth int) {
-	p.expr1(x, token.LowestPrec, depth)
-}
-
-func (p *printer) expr(x ast.Expr) {
-	const depth = 1
-	p.expr1(x, token.LowestPrec, depth)
-}
-
-// ----------------------------------------------------------------------------
-// Statements
-
-// Print the statement list indented, but without a newline after the last statement.
-// Extra line breaks between statements in the source are respected but at most one
-// empty line is printed between statements.
-func (p *printer) stmtList(list []ast.Stmt, nindent int, nextIsRBrace bool) {
-	if nindent > 0 {
-		p.print(indent)
-	}
-	var line int
-	i := 0
-	for _, s := range list {
-		// ignore empty statements (was issue 3466)
-		if _, isEmpty := s.(*ast.EmptyStmt); !isEmpty {
-			// nindent == 0 only for lists of switch/select case clauses;
-			// in those cases each clause is a new section
-			if len(p.output) > 0 {
-				// only print line break if we are not at the beginning of the output
-				// (i.e., we are not printing only a partial program)
-				p.linebreak(p.lineFor(s.Pos()), 1, ignore, i == 0 || nindent == 0 || p.linesFrom(line) > 0)
-			}
-			p.recordLine(&line)
-			p.stmt(s, nextIsRBrace && i == len(list)-1)
-			// labeled statements put labels on a separate line, but here
-			// we only care about the start line of the actual statement
-			// without label - correct line for each label
-			for t := s; ; {
-				lt, _ := t.(*ast.LabeledStmt)
-				if lt == nil {
-					break
-				}
-				line++
-				t = lt.Stmt
-			}
-			i++
-		}
-	}
-	if nindent > 0 {
-		p.print(unindent)
-	}
-}
-
-// block prints an *ast.BlockStmt; it always spans at least two lines.
-func (p *printer) block(b *ast.BlockStmt, nindent int) {
-	p.print(b.Lbrace, token.LBRACE)
-	p.stmtList(b.List, nindent, true)
-	p.linebreak(p.lineFor(b.Rbrace), 1, ignore, true)
-	p.print(b.Rbrace, token.RBRACE)
-}
-
-func isTypeName(x ast.Expr) bool {
-	switch t := x.(type) {
-	case *ast.Ident:
-		return true
-	case *ast.SelectorExpr:
-		return isTypeName(t.X)
-	}
-	return false
-}
-
-func stripParens(x ast.Expr) ast.Expr {
-	if px, strip := x.(*ast.ParenExpr); strip {
-		// parentheses must not be stripped if there are any
-		// unparenthesized composite literals starting with
-		// a type name
-		ast.Inspect(px.X, func(node ast.Node) bool {
-			switch x := node.(type) {
-			case *ast.ParenExpr:
-				// parentheses protect enclosed composite literals
-				return false
-			case *ast.CompositeLit:
-				if isTypeName(x.Type) {
-					strip = false // do not strip parentheses
-				}
-				return false
-			}
-			// in all other cases, keep inspecting
-			return true
-		})
-		if strip {
-			return stripParens(px.X)
-		}
-	}
-	return x
-}
-
-func stripParensAlways(x ast.Expr) ast.Expr {
-	if x, ok := x.(*ast.ParenExpr); ok {
-		return stripParensAlways(x.X)
-	}
-	return x
-}
-
-func (p *printer) controlClause(isForStmt bool, init ast.Stmt, expr ast.Expr, post ast.Stmt) {
-	p.print(blank)
-	needsBlank := false
-	if init == nil && post == nil {
-		// no semicolons required
-		if expr != nil {
-			p.expr(stripParens(expr))
-			needsBlank = true
-		}
-	} else {
-		// all semicolons required
-		// (they are not separators, print them explicitly)
-		if init != nil {
-			p.stmt(init, false)
-		}
-		p.print(token.SEMICOLON, blank)
-		if expr != nil {
-			p.expr(stripParens(expr))
-			needsBlank = true
-		}
-		if isForStmt {
-			p.print(token.SEMICOLON, blank)
-			needsBlank = false
-			if post != nil {
-				p.stmt(post, false)
-				needsBlank = true
-			}
-		}
-	}
-	if needsBlank {
-		p.print(blank)
-	}
-}
-
-// indentList reports whether an expression list would look better if it
-// were indented wholesale (starting with the very first element, rather
-// than starting at the first line break).
-//
-func (p *printer) indentList(list []ast.Expr) bool {
-	// Heuristic: indentList returns true if there are more than one multi-
-	// line element in the list, or if there is any element that is not
-	// starting on the same line as the previous one ends.
-	if len(list) >= 2 {
-		var b = p.lineFor(list[0].Pos())
-		var e = p.lineFor(list[len(list)-1].End())
-		if 0 < b && b < e {
-			// list spans multiple lines
-			n := 0 // multi-line element count
-			line := b
-			for _, x := range list {
-				xb := p.lineFor(x.Pos())
-				xe := p.lineFor(x.End())
-				if line < xb {
-					// x is not starting on the same
-					// line as the previous one ended
-					return true
-				}
-				if xb < xe {
-					// x is a multi-line element
-					n++
-				}
-				line = xe
-			}
-			return n > 1
-		}
-	}
-	return false
-}
-
-func (p *printer) stmt(stmt ast.Stmt, nextIsRBrace bool) {
-	p.print(stmt.Pos())
-
-	switch s := stmt.(type) {
-	case *ast.BadStmt:
-		p.print("BadStmt")
-
-	case *ast.DeclStmt:
-		p.decl(s.Decl)
-
-	case *ast.EmptyStmt:
-		// nothing to do
-
-	case *ast.LabeledStmt:
-		// a "correcting" unindent immediately following a line break
-		// is applied before the line break if there is no comment
-		// between (see writeWhitespace)
-		p.print(unindent)
-		p.expr(s.Label)
-		p.print(s.Colon, token.COLON, indent)
-		if e, isEmpty := s.Stmt.(*ast.EmptyStmt); isEmpty {
-			if !nextIsRBrace {
-				p.print(newline, e.Pos(), token.SEMICOLON)
-				break
-			}
-		} else {
-			p.linebreak(p.lineFor(s.Stmt.Pos()), 1, ignore, true)
-		}
-		p.stmt(s.Stmt, nextIsRBrace)
-
-	case *ast.ExprStmt:
-		const depth = 1
-		p.expr0(s.X, depth)
-
-	case *ast.SendStmt:
-		const depth = 1
-		p.expr0(s.Chan, depth)
-		p.print(blank, s.Arrow, token.ARROW, blank)
-		p.expr0(s.Value, depth)
-
-	case *ast.IncDecStmt:
-		const depth = 1
-		p.expr0(s.X, depth+1)
-		p.print(s.TokPos, s.Tok)
-
-	case *ast.AssignStmt:
-		var depth = 1
-		if len(s.Lhs) > 1 && len(s.Rhs) > 1 {
-			depth++
-		}
-		p.exprList(s.Pos(), s.Lhs, depth, 0, s.TokPos)
-		p.print(blank, s.TokPos, s.Tok, blank)
-		p.exprList(s.TokPos, s.Rhs, depth, 0, token.NoPos)
-
-	case *ast.GoStmt:
-		p.print(token.GO, blank)
-		p.expr(s.Call)
-
-	case *ast.DeferStmt:
-		p.print(token.DEFER, blank)
-		p.expr(s.Call)
-
-	case *ast.ReturnStmt:
-		p.print(token.RETURN)
-		if s.Results != nil {
-			p.print(blank)
-			// Use indentList heuristic to make corner cases look
-			// better (issue 1207). A more systematic approach would
-			// always indent, but this would cause significant
-			// reformatting of the code base and not necessarily
-			// lead to more nicely formatted code in general.
-			if p.indentList(s.Results) {
-				p.print(indent)
-				p.exprList(s.Pos(), s.Results, 1, noIndent, token.NoPos)
-				p.print(unindent)
-			} else {
-				p.exprList(s.Pos(), s.Results, 1, 0, token.NoPos)
-			}
-		}
-
-	case *ast.BranchStmt:
-		p.print(s.Tok)
-		if s.Label != nil {
-			p.print(blank)
-			p.expr(s.Label)
-		}
-
-	case *ast.BlockStmt:
-		p.block(s, 1)
-
-	case *ast.IfStmt:
-		p.print(token.IF)
-		p.controlClause(false, s.Init, s.Cond, nil)
-		p.block(s.Body, 1)
-		if s.Else != nil {
-			p.print(blank, token.ELSE, blank)
-			switch s.Else.(type) {
-			case *ast.BlockStmt, *ast.IfStmt:
-				p.stmt(s.Else, nextIsRBrace)
-			default:
-				p.print(token.LBRACE, indent, formfeed)
-				p.stmt(s.Else, true)
-				p.print(unindent, formfeed, token.RBRACE)
-			}
-		}
-
-	case *ast.CaseClause:
-		if s.List != nil {
-			p.print(token.CASE, blank)
-			p.exprList(s.Pos(), s.List, 1, 0, s.Colon)
-		} else {
-			p.print(token.DEFAULT)
-		}
-		p.print(s.Colon, token.COLON)
-		p.stmtList(s.Body, 1, nextIsRBrace)
-
-	case *ast.SwitchStmt:
-		p.print(token.SWITCH)
-		p.controlClause(false, s.Init, s.Tag, nil)
-		p.block(s.Body, 0)
-
-	case *ast.TypeSwitchStmt:
-		p.print(token.SWITCH)
-		if s.Init != nil {
-			p.print(blank)
-			p.stmt(s.Init, false)
-			p.print(token.SEMICOLON)
-		}
-		p.print(blank)
-		p.stmt(s.Assign, false)
-		p.print(blank)
-		p.block(s.Body, 0)
-
-	case *ast.CommClause:
-		if s.Comm != nil {
-			p.print(token.CASE, blank)
-			p.stmt(s.Comm, false)
-		} else {
-			p.print(token.DEFAULT)
-		}
-		p.print(s.Colon, token.COLON)
-		p.stmtList(s.Body, 1, nextIsRBrace)
-
-	case *ast.SelectStmt:
-		p.print(token.SELECT, blank)
-		body := s.Body
-		if len(body.List) == 0 && !p.commentBefore(p.posFor(body.Rbrace)) {
-			// print empty select statement w/o comments on one line
-			p.print(body.Lbrace, token.LBRACE, body.Rbrace, token.RBRACE)
-		} else {
-			p.block(body, 0)
-		}
-
-	case *ast.ForStmt:
-		p.print(token.FOR)
-		p.controlClause(true, s.Init, s.Cond, s.Post)
-		p.block(s.Body, 1)
-
-	case *ast.RangeStmt:
-		p.print(token.FOR, blank)
-		p.expr(s.Key)
-		if s.Value != nil {
-			// use position of value following the comma as
-			// comma position for correct comment placement
-			p.print(s.Value.Pos(), token.COMMA, blank)
-			p.expr(s.Value)
-		}
-		p.print(blank, s.TokPos, s.Tok, blank, token.RANGE, blank)
-		p.expr(stripParens(s.X))
-		p.print(blank)
-		p.block(s.Body, 1)
-
-	default:
-		panic("unreachable")
-	}
-
-	return
-}
-
-// ----------------------------------------------------------------------------
-// Declarations
-
-// The keepTypeColumn function determines if the type column of a series of
-// consecutive const or var declarations must be kept, or if initialization
-// values (V) can be placed in the type column (T) instead. The i'th entry
-// in the result slice is true if the type column in spec[i] must be kept.
-//
-// For example, the declaration:
-//
-//	const (
-//		foobar int = 42 // comment
-//		x          = 7  // comment
-//		foo
-//              bar = 991
-//	)
-//
-// leads to the type/values matrix below. A run of value columns (V) can
-// be moved into the type column if there is no type for any of the values
-// in that column (we only move entire columns so that they align properly).
-//
-//	matrix        formatted     result
-//                    matrix
-//	T  V    ->    T  V     ->   true      there is a T and so the type
-//	-  V          -  V          true      column must be kept
-//	-  -          -  -          false
-//	-  V          V  -          false     V is moved into T column
-//
-func keepTypeColumn(specs []ast.Spec) []bool {
-	m := make([]bool, len(specs))
-
-	populate := func(i, j int, keepType bool) {
-		if keepType {
-			for ; i < j; i++ {
-				m[i] = true
-			}
-		}
-	}
-
-	i0 := -1 // if i0 >= 0 we are in a run and i0 is the start of the run
-	var keepType bool
-	for i, s := range specs {
-		t := s.(*ast.ValueSpec)
-		if t.Values != nil {
-			if i0 < 0 {
-				// start of a run of ValueSpecs with non-nil Values
-				i0 = i
-				keepType = false
-			}
-		} else {
-			if i0 >= 0 {
-				// end of a run
-				populate(i0, i, keepType)
-				i0 = -1
-			}
-		}
-		if t.Type != nil {
-			keepType = true
-		}
-	}
-	if i0 >= 0 {
-		// end of a run
-		populate(i0, len(specs), keepType)
-	}
-
-	return m
-}
-
-func (p *printer) valueSpec(s *ast.ValueSpec, keepType bool) {
-	p.setComment(s.Doc)
-	p.identList(s.Names, false) // always present
-	extraTabs := 3
-	if s.Type != nil || keepType {
-		p.print(vtab)
-		extraTabs--
-	}
-	if s.Type != nil {
-		p.expr(s.Type)
-	}
-	if s.Values != nil {
-		p.print(vtab, token.ASSIGN, blank)
-		p.exprList(token.NoPos, s.Values, 1, 0, token.NoPos)
-		extraTabs--
-	}
-	if s.Comment != nil {
-		for ; extraTabs > 0; extraTabs-- {
-			p.print(vtab)
-		}
-		p.setComment(s.Comment)
-	}
-}
-
-// The parameter n is the number of specs in the group. If doIndent is set,
-// multi-line identifier lists in the spec are indented when the first
-// linebreak is encountered.
-//
-func (p *printer) spec(spec ast.Spec, n int, doIndent bool) {
-	switch s := spec.(type) {
-	case *ast.ImportSpec:
-		p.setComment(s.Doc)
-		if s.Name != nil {
-			p.expr(s.Name)
-			p.print(blank)
-		}
-		p.expr(s.Path)
-		p.setComment(s.Comment)
-		p.print(s.EndPos)
-
-	case *ast.ValueSpec:
-		if n != 1 {
-			p.internalError("expected n = 1; got", n)
-		}
-		p.setComment(s.Doc)
-		p.identList(s.Names, doIndent) // always present
-		if s.Type != nil {
-			p.print(blank)
-			p.expr(s.Type)
-		}
-		if s.Values != nil {
-			p.print(blank, token.ASSIGN, blank)
-			p.exprList(token.NoPos, s.Values, 1, 0, token.NoPos)
-		}
-		p.setComment(s.Comment)
-
-	case *ast.TypeSpec:
-		p.setComment(s.Doc)
-		p.expr(s.Name)
-		if n == 1 {
-			p.print(blank)
-		} else {
-			p.print(vtab)
-		}
-		p.expr(s.Type)
-		p.setComment(s.Comment)
-
-	default:
-		panic("unreachable")
-	}
-}
-
-func (p *printer) genDecl(d *ast.GenDecl) {
-	p.setComment(d.Doc)
-	p.print(d.Pos(), d.Tok, blank)
-
-	if d.Lparen.IsValid() {
-		// group of parenthesized declarations
-		p.print(d.Lparen, token.LPAREN)
-		if n := len(d.Specs); n > 0 {
-			p.print(indent, formfeed)
-			if n > 1 && (d.Tok == token.CONST || d.Tok == token.VAR) {
-				// two or more grouped const/var declarations:
-				// determine if the type column must be kept
-				keepType := keepTypeColumn(d.Specs)
-				var line int
-				for i, s := range d.Specs {
-					if i > 0 {
-						p.linebreak(p.lineFor(s.Pos()), 1, ignore, p.linesFrom(line) > 0)
-					}
-					p.recordLine(&line)
-					p.valueSpec(s.(*ast.ValueSpec), keepType[i])
-				}
-			} else {
-				var line int
-				for i, s := range d.Specs {
-					if i > 0 {
-						p.linebreak(p.lineFor(s.Pos()), 1, ignore, p.linesFrom(line) > 0)
-					}
-					p.recordLine(&line)
-					p.spec(s, n, false)
-				}
-			}
-			p.print(unindent, formfeed)
-		}
-		p.print(d.Rparen, token.RPAREN)
-
-	} else {
-		// single declaration
-		p.spec(d.Specs[0], 1, true)
-	}
-}
-
-// nodeSize determines the size of n in chars after formatting.
-// The result is <= maxSize if the node fits on one line with at
-// most maxSize chars and the formatted output doesn't contain
-// any control chars. Otherwise, the result is > maxSize.
-//
-func (p *printer) nodeSize(n ast.Node, maxSize int) (size int) {
-	// nodeSize invokes the printer, which may invoke nodeSize
-	// recursively. For deep composite literal nests, this can
-	// lead to an exponential algorithm. Remember previous
-	// results to prune the recursion (was issue 1628).
-	if size, found := p.nodeSizes[n]; found {
-		return size
-	}
-
-	size = maxSize + 1 // assume n doesn't fit
-	p.nodeSizes[n] = size
-
-	// nodeSize computation must be independent of particular
-	// style so that we always get the same decision; print
-	// in RawFormat
-	cfg := Config{Mode: RawFormat}
-	var buf bytes.Buffer
-	if err := cfg.fprint(&buf, p.fset, n, p.nodeSizes); err != nil {
-		return
-	}
-	if buf.Len() <= maxSize {
-		for _, ch := range buf.Bytes() {
-			if ch < ' ' {
-				return
-			}
-		}
-		size = buf.Len() // n fits
-		p.nodeSizes[n] = size
-	}
-	return
-}
-
-// bodySize is like nodeSize but it is specialized for *ast.BlockStmt's.
-func (p *printer) bodySize(b *ast.BlockStmt, maxSize int) int {
-	pos1 := b.Pos()
-	pos2 := b.Rbrace
-	if pos1.IsValid() && pos2.IsValid() && p.lineFor(pos1) != p.lineFor(pos2) {
-		// opening and closing brace are on different lines - don't make it a one-liner
-		return maxSize + 1
-	}
-	if len(b.List) > 5 {
-		// too many statements - don't make it a one-liner
-		return maxSize + 1
-	}
-	// otherwise, estimate body size
-	bodySize := p.commentSizeBefore(p.posFor(pos2))
-	for i, s := range b.List {
-		if bodySize > maxSize {
-			break // no need to continue
-		}
-		if i > 0 {
-			bodySize += 2 // space for a semicolon and blank
-		}
-		bodySize += p.nodeSize(s, maxSize)
-	}
-	return bodySize
-}
-
-// adjBlock prints an "adjacent" block (e.g., a for-loop or function body) following
-// a header (e.g., a for-loop control clause or function signature) of given headerSize.
-// If the header's and block's size are "small enough" and the block is "simple enough",
-// the block is printed on the current line, without line breaks, spaced from the header
-// by sep. Otherwise the block's opening "{" is printed on the current line, followed by
-// lines for the block's statements and its closing "}".
-//
-func (p *printer) adjBlock(headerSize int, sep whiteSpace, b *ast.BlockStmt) {
-	if b == nil {
-		return
-	}
-
-	const maxSize = 100
-	if headerSize+p.bodySize(b, maxSize) <= maxSize {
-		p.print(sep, b.Lbrace, token.LBRACE)
-		if len(b.List) > 0 {
-			p.print(blank)
-			for i, s := range b.List {
-				if i > 0 {
-					p.print(token.SEMICOLON, blank)
-				}
-				p.stmt(s, i == len(b.List)-1)
-			}
-			p.print(blank)
-		}
-		p.print(noExtraLinebreak, b.Rbrace, token.RBRACE, noExtraLinebreak)
-		return
-	}
-
-	if sep != ignore {
-		p.print(blank) // always use blank
-	}
-	p.block(b, 1)
-}
-
-// distanceFrom returns the column difference between from and p.pos (the current
-// estimated position) if both are on the same line; if they are on different lines
-// (or unknown) the result is infinity.
-func (p *printer) distanceFrom(from token.Pos) int {
-	if from.IsValid() && p.pos.IsValid() {
-		if f := p.posFor(from); f.Line == p.pos.Line {
-			return p.pos.Column - f.Column
-		}
-	}
-	return infinity
-}
-
-func (p *printer) funcDecl(d *ast.FuncDecl) {
-	p.setComment(d.Doc)
-	p.print(d.Pos(), token.FUNC, blank)
-	if d.Recv != nil {
-		p.parameters(d.Recv) // method: print receiver
-		p.print(blank)
-	}
-	p.expr(d.Name)
-	p.signature(d.Type.Params, d.Type.Results)
-	p.adjBlock(p.distanceFrom(d.Pos()), vtab, d.Body)
-}
-
-func (p *printer) decl(decl ast.Decl) {
-	switch d := decl.(type) {
-	case *ast.BadDecl:
-		p.print(d.Pos(), "BadDecl")
-	case *ast.GenDecl:
-		p.genDecl(d)
-	case *ast.FuncDecl:
-		p.funcDecl(d)
-	default:
-		panic("unreachable")
-	}
-}
-
-// ----------------------------------------------------------------------------
-// Files
-
-func declToken(decl ast.Decl) (tok token.Token) {
-	tok = token.ILLEGAL
-	switch d := decl.(type) {
-	case *ast.GenDecl:
-		tok = d.Tok
-	case *ast.FuncDecl:
-		tok = token.FUNC
-	}
-	return
-}
-
-func (p *printer) declList(list []ast.Decl) {
-	tok := token.ILLEGAL
-	for _, d := range list {
-		prev := tok
-		tok = declToken(d)
-		// If the declaration token changed (e.g., from CONST to TYPE)
-		// or the next declaration has documentation associated with it,
-		// print an empty line between top-level declarations.
-		// (because p.linebreak is called with the position of d, which
-		// is past any documentation, the minimum requirement is satisfied
-		// even w/o the extra getDoc(d) nil-check - leave it in case the
-		// linebreak logic improves - there's already a TODO).
-		if len(p.output) > 0 {
-			// only print line break if we are not at the beginning of the output
-			// (i.e., we are not printing only a partial program)
-			min := 1
-			if prev != tok || getDoc(d) != nil {
-				min = 2
-			}
-			p.linebreak(p.lineFor(d.Pos()), min, ignore, false)
-		}
-		p.decl(d)
-	}
-}
-
-func (p *printer) file(src *ast.File) {
-	p.setComment(src.Doc)
-	p.print(src.Pos(), token.PACKAGE, blank)
-	p.expr(src.Name)
-	p.declList(src.Decls)
-	p.print(newline)
-}
diff --git a/src/pkg/go/printer/printer_test.go b/src/pkg/go/printer/printer_test.go
deleted file mode 100644
index 306928a..0000000
--- a/src/pkg/go/printer/printer_test.go
+++ /dev/null
@@ -1,569 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package printer
-
-import (
-	"bytes"
-	"errors"
-	"flag"
-	"fmt"
-	"go/ast"
-	"go/parser"
-	"go/token"
-	"io/ioutil"
-	"path/filepath"
-	"testing"
-	"time"
-)
-
-const (
-	dataDir  = "testdata"
-	tabwidth = 8
-)
-
-var update = flag.Bool("update", false, "update golden files")
-
-var fset = token.NewFileSet()
-
-type checkMode uint
-
-const (
-	export checkMode = 1 << iota
-	rawFormat
-	idempotent
-)
-
-// format parses src, prints the corresponding AST, verifies the resulting
-// src is syntactically correct, and returns the resulting src or an error
-// if any.
-func format(src []byte, mode checkMode) ([]byte, error) {
-	// parse src
-	f, err := parser.ParseFile(fset, "", src, parser.ParseComments)
-	if err != nil {
-		return nil, fmt.Errorf("parse: %s\n%s", err, src)
-	}
-
-	// filter exports if necessary
-	if mode&export != 0 {
-		ast.FileExports(f) // ignore result
-		f.Comments = nil   // don't print comments that are not in AST
-	}
-
-	// determine printer configuration
-	cfg := Config{Tabwidth: tabwidth}
-	if mode&rawFormat != 0 {
-		cfg.Mode |= RawFormat
-	}
-
-	// print AST
-	var buf bytes.Buffer
-	if err := cfg.Fprint(&buf, fset, f); err != nil {
-		return nil, fmt.Errorf("print: %s", err)
-	}
-
-	// make sure formatted output is syntactically correct
-	res := buf.Bytes()
-	if _, err := parser.ParseFile(fset, "", res, 0); err != nil {
-		return nil, fmt.Errorf("re-parse: %s\n%s", err, buf.Bytes())
-	}
-
-	return res, nil
-}
-
-// lineAt returns the line in text starting at offset offs.
-func lineAt(text []byte, offs int) []byte {
-	i := offs
-	for i < len(text) && text[i] != '\n' {
-		i++
-	}
-	return text[offs:i]
-}
-
-// diff compares a and b.
-func diff(aname, bname string, a, b []byte) error {
-	var buf bytes.Buffer // holding long error message
-
-	// compare lengths
-	if len(a) != len(b) {
-		fmt.Fprintf(&buf, "\nlength changed: len(%s) = %d, len(%s) = %d", aname, len(a), bname, len(b))
-	}
-
-	// compare contents
-	line := 1
-	offs := 1
-	for i := 0; i < len(a) && i < len(b); i++ {
-		ch := a[i]
-		if ch != b[i] {
-			fmt.Fprintf(&buf, "\n%s:%d:%d: %s", aname, line, i-offs+1, lineAt(a, offs))
-			fmt.Fprintf(&buf, "\n%s:%d:%d: %s", bname, line, i-offs+1, lineAt(b, offs))
-			fmt.Fprintf(&buf, "\n\n")
-			break
-		}
-		if ch == '\n' {
-			line++
-			offs = i + 1
-		}
-	}
-
-	if buf.Len() > 0 {
-		return errors.New(buf.String())
-	}
-	return nil
-}
-
-func runcheck(t *testing.T, source, golden string, mode checkMode) {
-	src, err := ioutil.ReadFile(source)
-	if err != nil {
-		t.Error(err)
-		return
-	}
-
-	res, err := format(src, mode)
-	if err != nil {
-		t.Error(err)
-		return
-	}
-
-	// update golden files if necessary
-	if *update {
-		if err := ioutil.WriteFile(golden, res, 0644); err != nil {
-			t.Error(err)
-		}
-		return
-	}
-
-	// get golden
-	gld, err := ioutil.ReadFile(golden)
-	if err != nil {
-		t.Error(err)
-		return
-	}
-
-	// formatted source and golden must be the same
-	if err := diff(source, golden, res, gld); err != nil {
-		t.Error(err)
-		return
-	}
-
-	if mode&idempotent != 0 {
-		// formatting golden must be idempotent
-		// (This is very difficult to achieve in general and for now
-		// it is only checked for files explicitly marked as such.)
-		res, err = format(gld, mode)
-		if err := diff(golden, fmt.Sprintf("format(%s)", golden), gld, res); err != nil {
-			t.Errorf("golden is not idempotent: %s", err)
-		}
-	}
-}
-
-func check(t *testing.T, source, golden string, mode checkMode) {
-	// start a timer to produce a time-out signal
-	tc := make(chan int)
-	go func() {
-		time.Sleep(10 * time.Second) // plenty of a safety margin, even for very slow machines
-		tc <- 0
-	}()
-
-	// run the test
-	cc := make(chan int)
-	go func() {
-		runcheck(t, source, golden, mode)
-		cc <- 0
-	}()
-
-	// wait for the first finisher
-	select {
-	case <-tc:
-		// test running past time out
-		t.Errorf("%s: running too slowly", source)
-	case <-cc:
-		// test finished within allotted time margin
-	}
-}
-
-type entry struct {
-	source, golden string
-	mode           checkMode
-}
-
-// Use go test -update to create/update the respective golden files.
-var data = []entry{
-	{"empty.input", "empty.golden", idempotent},
-	{"comments.input", "comments.golden", 0},
-	{"comments.input", "comments.x", export},
-	{"comments2.input", "comments2.golden", idempotent},
-	{"linebreaks.input", "linebreaks.golden", idempotent},
-	{"expressions.input", "expressions.golden", idempotent},
-	{"expressions.input", "expressions.raw", rawFormat | idempotent},
-	{"declarations.input", "declarations.golden", 0},
-	{"statements.input", "statements.golden", 0},
-	{"slow.input", "slow.golden", idempotent},
-}
-
-func TestFiles(t *testing.T) {
-	for _, e := range data {
-		source := filepath.Join(dataDir, e.source)
-		golden := filepath.Join(dataDir, e.golden)
-		check(t, source, golden, e.mode)
-		// TODO(gri) check that golden is idempotent
-		//check(t, golden, golden, e.mode)
-	}
-}
-
-// TestLineComments, using a simple test case, checks that consecutive line
-// comments are properly terminated with a newline even if the AST position
-// information is incorrect.
-//
-func TestLineComments(t *testing.T) {
-	const src = `// comment 1
-	// comment 2
-	// comment 3
-	package main
-	`
-
-	fset := token.NewFileSet()
-	f, err := parser.ParseFile(fset, "", src, parser.ParseComments)
-	if err != nil {
-		panic(err) // error in test
-	}
-
-	var buf bytes.Buffer
-	fset = token.NewFileSet() // use the wrong file set
-	Fprint(&buf, fset, f)
-
-	nlines := 0
-	for _, ch := range buf.Bytes() {
-		if ch == '\n' {
-			nlines++
-		}
-	}
-
-	const expected = 3
-	if nlines < expected {
-		t.Errorf("got %d, expected %d\n", nlines, expected)
-		t.Errorf("result:\n%s", buf.Bytes())
-	}
-}
-
-// Verify that the printer can be invoked during initialization.
-func init() {
-	const name = "foobar"
-	var buf bytes.Buffer
-	if err := Fprint(&buf, fset, &ast.Ident{Name: name}); err != nil {
-		panic(err) // error in test
-	}
-	// in debug mode, the result contains additional information;
-	// ignore it
-	if s := buf.String(); !debug && s != name {
-		panic("got " + s + ", want " + name)
-	}
-}
-
-// Verify that the printer doesn't crash if the AST contains BadXXX nodes.
-func TestBadNodes(t *testing.T) {
-	const src = "package p\n("
-	const res = "package p\nBadDecl\n"
-	f, err := parser.ParseFile(fset, "", src, parser.ParseComments)
-	if err == nil {
-		t.Error("expected illegal program") // error in test
-	}
-	var buf bytes.Buffer
-	Fprint(&buf, fset, f)
-	if buf.String() != res {
-		t.Errorf("got %q, expected %q", buf.String(), res)
-	}
-}
-
-// testComment verifies that f can be parsed again after printing it
-// with its first comment set to comment at any possible source offset.
-func testComment(t *testing.T, f *ast.File, srclen int, comment *ast.Comment) {
-	f.Comments[0].List[0] = comment
-	var buf bytes.Buffer
-	for offs := 0; offs <= srclen; offs++ {
-		buf.Reset()
-		// Printing f should result in a correct program no
-		// matter what the (incorrect) comment position is.
-		if err := Fprint(&buf, fset, f); err != nil {
-			t.Error(err)
-		}
-		if _, err := parser.ParseFile(fset, "", buf.Bytes(), 0); err != nil {
-			t.Fatalf("incorrect program for pos = %d:\n%s", comment.Slash, buf.String())
-		}
-		// Position information is just an offset.
-		// Move comment one byte down in the source.
-		comment.Slash++
-	}
-}
-
-// Verify that the printer produces a correct program
-// even if the position information of comments introducing newlines
-// is incorrect.
-func TestBadComments(t *testing.T) {
-	const src = `
-// first comment - text and position changed by test
-package p
-import "fmt"
-const pi = 3.14 // rough circle
-var (
-	x, y, z int = 1, 2, 3
-	u, v float64
-)
-func fibo(n int) {
-	if n < 2 {
-		return n /* seed values */
-	}
-	return fibo(n-1) + fibo(n-2)
-}
-`
-
-	f, err := parser.ParseFile(fset, "", src, parser.ParseComments)
-	if err != nil {
-		t.Error(err) // error in test
-	}
-
-	comment := f.Comments[0].List[0]
-	pos := comment.Pos()
-	if fset.Position(pos).Offset != 1 {
-		t.Error("expected offset 1") // error in test
-	}
-
-	testComment(t, f, len(src), &ast.Comment{Slash: pos, Text: "//-style comment"})
-	testComment(t, f, len(src), &ast.Comment{Slash: pos, Text: "/*-style comment */"})
-	testComment(t, f, len(src), &ast.Comment{Slash: pos, Text: "/*-style \n comment */"})
-	testComment(t, f, len(src), &ast.Comment{Slash: pos, Text: "/*-style comment \n\n\n */"})
-}
-
-type visitor chan *ast.Ident
-
-func (v visitor) Visit(n ast.Node) (w ast.Visitor) {
-	if ident, ok := n.(*ast.Ident); ok {
-		v <- ident
-	}
-	return v
-}
-
-// idents is an iterator that returns all idents in f via the result channel.
-func idents(f *ast.File) <-chan *ast.Ident {
-	v := make(visitor)
-	go func() {
-		ast.Walk(v, f)
-		close(v)
-	}()
-	return v
-}
-
-// identCount returns the number of identifiers found in f.
-func identCount(f *ast.File) int {
-	n := 0
-	for _ = range idents(f) {
-		n++
-	}
-	return n
-}
-
-// Verify that the SourcePos mode emits correct //line comments
-// by testing that position information for matching identifiers
-// is maintained.
-func TestSourcePos(t *testing.T) {
-	const src = `
-package p
-import ( "go/printer"; "math" )
-const pi = 3.14; var x = 0
-type t struct{ x, y, z int; u, v, w float32 }
-func (t *t) foo(a, b, c int) int {
-	return a*t.x + b*t.y +
-		// two extra lines here
-		// ...
-		c*t.z
-}
-`
-
-	// parse original
-	f1, err := parser.ParseFile(fset, "src", src, parser.ParseComments)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	// pretty-print original
-	var buf bytes.Buffer
-	err = (&Config{Mode: UseSpaces | SourcePos, Tabwidth: 8}).Fprint(&buf, fset, f1)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	// parse pretty printed original
-	// (//line comments must be interpreted even w/o parser.ParseComments set)
-	f2, err := parser.ParseFile(fset, "", buf.Bytes(), 0)
-	if err != nil {
-		t.Fatalf("%s\n%s", err, buf.Bytes())
-	}
-
-	// At this point the position information of identifiers in f2 should
-	// match the position information of corresponding identifiers in f1.
-
-	// number of identifiers must be > 0 (test should run) and must match
-	n1 := identCount(f1)
-	n2 := identCount(f2)
-	if n1 == 0 {
-		t.Fatal("got no idents")
-	}
-	if n2 != n1 {
-		t.Errorf("got %d idents; want %d", n2, n1)
-	}
-
-	// verify that all identifiers have correct line information
-	i2range := idents(f2)
-	for i1 := range idents(f1) {
-		i2 := <-i2range
-
-		if i2.Name != i1.Name {
-			t.Errorf("got ident %s; want %s", i2.Name, i1.Name)
-		}
-
-		l1 := fset.Position(i1.Pos()).Line
-		l2 := fset.Position(i2.Pos()).Line
-		if l2 != l1 {
-			t.Errorf("got line %d; want %d for %s", l2, l1, i1.Name)
-		}
-	}
-
-	if t.Failed() {
-		t.Logf("\n%s", buf.Bytes())
-	}
-}
-
-var decls = []string{
-	`import "fmt"`,
-	"const pi = 3.1415\nconst e = 2.71828\n\nvar x = pi",
-	"func sum(x, y int) int\t{ return x + y }",
-}
-
-func TestDeclLists(t *testing.T) {
-	for _, src := range decls {
-		file, err := parser.ParseFile(fset, "", "package p;"+src, parser.ParseComments)
-		if err != nil {
-			panic(err) // error in test
-		}
-
-		var buf bytes.Buffer
-		err = Fprint(&buf, fset, file.Decls) // only print declarations
-		if err != nil {
-			panic(err) // error in test
-		}
-
-		out := buf.String()
-		if out != src {
-			t.Errorf("\ngot : %q\nwant: %q\n", out, src)
-		}
-	}
-}
-
-var stmts = []string{
-	"i := 0",
-	"select {}\nvar a, b = 1, 2\nreturn a + b",
-	"go f()\ndefer func() {}()",
-}
-
-func TestStmtLists(t *testing.T) {
-	for _, src := range stmts {
-		file, err := parser.ParseFile(fset, "", "package p; func _() {"+src+"}", parser.ParseComments)
-		if err != nil {
-			panic(err) // error in test
-		}
-
-		var buf bytes.Buffer
-		err = Fprint(&buf, fset, file.Decls[0].(*ast.FuncDecl).Body.List) // only print statements
-		if err != nil {
-			panic(err) // error in test
-		}
-
-		out := buf.String()
-		if out != src {
-			t.Errorf("\ngot : %q\nwant: %q\n", out, src)
-		}
-	}
-}
-
-func TestBaseIndent(t *testing.T) {
-	// The testfile must not contain multi-line raw strings since those
-	// are not indented (because their values must not change) and make
-	// this test fail.
-	const filename = "printer.go"
-	src, err := ioutil.ReadFile(filename)
-	if err != nil {
-		panic(err) // error in test
-	}
-
-	file, err := parser.ParseFile(fset, filename, src, 0)
-	if err != nil {
-		panic(err) // error in test
-	}
-
-	var buf bytes.Buffer
-	for indent := 0; indent < 4; indent++ {
-		buf.Reset()
-		(&Config{Tabwidth: tabwidth, Indent: indent}).Fprint(&buf, fset, file)
-		// all code must be indented by at least 'indent' tabs
-		lines := bytes.Split(buf.Bytes(), []byte{'\n'})
-		for i, line := range lines {
-			if len(line) == 0 {
-				continue // empty lines don't have indentation
-			}
-			n := 0
-			for j, b := range line {
-				if b != '\t' {
-					// end of indentation
-					n = j
-					break
-				}
-			}
-			if n < indent {
-				t.Errorf("line %d: got only %d tabs; want at least %d: %q", i, n, indent, line)
-			}
-		}
-	}
-}
-
-// TestFuncType tests that an ast.FuncType with a nil Params field
-// can be printed (per go/ast specification). Test case for issue 3870.
-func TestFuncType(t *testing.T) {
-	src := &ast.File{
-		Name: &ast.Ident{Name: "p"},
-		Decls: []ast.Decl{
-			&ast.FuncDecl{
-				Name: &ast.Ident{Name: "f"},
-				Type: &ast.FuncType{},
-			},
-		},
-	}
-
-	var buf bytes.Buffer
-	if err := Fprint(&buf, fset, src); err != nil {
-		t.Fatal(err)
-	}
-	got := buf.String()
-
-	const want = `package p
-
-func f()
-`
-
-	if got != want {
-		t.Fatalf("got:\n%s\nwant:\n%s\n", got, want)
-	}
-}
-
-// TextX is a skeleton test that can be filled in for debugging one-off cases.
-// Do not remove.
-func TestX(t *testing.T) {
-	const src = `
-package p
-func _() {}
-`
-	_, err := format([]byte(src), 0)
-	if err != nil {
-		t.Error(err)
-	}
-}
diff --git a/src/pkg/go/printer/testdata/declarations.golden b/src/pkg/go/printer/testdata/declarations.golden
deleted file mode 100644
index a27f21f..0000000
--- a/src/pkg/go/printer/testdata/declarations.golden
+++ /dev/null
@@ -1,955 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package imports
-
-import "io"
-
-import (
-	_ "io"
-)
-
-import _ "io"
-
-import (
-	"io"
-	"io"
-	"io"
-)
-
-import (
-	"io"
-	aLongRename "io"
-
-	b "io"
-)
-
-import (
-	"unrenamed"
-	renamed "renameMe"
-	. "io"
-	_ "io"
-	"io"
-	. "os"
-)
-
-// no newlines between consecutive single imports, but
-// respect extra line breaks in the source (at most one empty line)
-import _ "io"
-import _ "io"
-import _ "io"
-
-import _ "os"
-import _ "os"
-import _ "os"
-
-import _ "fmt"
-import _ "fmt"
-import _ "fmt"
-
-import "foo"	// a comment
-import "bar"	// a comment
-
-import (
-	_ "foo"
-	// a comment
-	"bar"
-	"foo"	// a comment
-	"bar"	// a comment
-)
-
-// comments + renames
-import (
-	"unrenamed"	// a comment
-	renamed "renameMe"
-	. "io"		/* a comment */
-	_ "io/ioutil"	// a comment
-	"io"		// testing alignment
-	. "os"
-	// a comment
-)
-
-// a case that caused problems in the past (comment placement)
-import (
-	. "fmt"
-	"io"
-	"malloc"	// for the malloc count test only
-	"math"
-	"strings"
-	"testing"
-)
-
-// more import examples
-import (
-	"xxx"
-	"much_longer_name"	// comment
-	"short_name"		// comment
-)
-
-import (
-	_ "xxx"
-	"much_longer_name"	// comment
-)
-
-import (
-	mymath "math"
-	"/foo/bar/long_package_path"	// a comment
-)
-
-import (
-	"package_a"	// comment
-	"package_b"
-	my_better_c "package_c"	// comment
-	"package_d"		// comment
-	my_e "package_e"	// comment
-
-	"package_a"	// comment
-	"package_bb"
-	"package_ccc"	// comment
-	"package_dddd"	// comment
-)
-
-// at least one empty line between declarations of different kind
-import _ "io"
-
-var _ int
-
-// at least one empty line between declarations of the same kind
-// if there is associated documentation (was issue 2570)
-type T1 struct{}
-
-// T2 comment
-type T2 struct {
-}	// should be a two-line struct
-
-// T3 comment
-type T2 struct {
-}	// should be a two-line struct
-
-// printing of constant literals
-const (
-	_	= "foobar"
-	_	= "a۰۱۸"
-	_	= "foo६४"
-	_	= "bar9876"
-	_	= 0
-	_	= 1
-	_	= 123456789012345678890
-	_	= 01234567
-	_	= 0xcafebabe
-	_	= 0.
-	_	= .0
-	_	= 3.14159265
-	_	= 1e0
-	_	= 1e+100
-	_	= 1e-100
-	_	= 2.71828e-1000
-	_	= 0i
-	_	= 1i
-	_	= 012345678901234567889i
-	_	= 123456789012345678890i
-	_	= 0.i
-	_	= .0i
-	_	= 3.14159265i
-	_	= 1e0i
-	_	= 1e+100i
-	_	= 1e-100i
-	_	= 2.71828e-1000i
-	_	= 'a'
-	_	= '\000'
-	_	= '\xFF'
-	_	= '\uff16'
-	_	= '\U0000ff16'
-	_	= `foobar`
-	_	= `foo
----
----
-bar`
-)
-
-func _() {
-	type _ int
-	type _ *int
-	type _ []int
-	type _ map[string]int
-	type _ chan int
-	type _ func() int
-
-	var _ int
-	var _ *int
-	var _ []int
-	var _ map[string]int
-	var _ chan int
-	var _ func() int
-
-	type _ struct{}
-	type _ *struct{}
-	type _ []struct{}
-	type _ map[string]struct{}
-	type _ chan struct{}
-	type _ func() struct{}
-
-	type _ interface{}
-	type _ *interface{}
-	type _ []interface{}
-	type _ map[string]interface{}
-	type _ chan interface{}
-	type _ func() interface{}
-
-	var _ struct{}
-	var _ *struct{}
-	var _ []struct{}
-	var _ map[string]struct{}
-	var _ chan struct{}
-	var _ func() struct{}
-
-	var _ interface{}
-	var _ *interface{}
-	var _ []interface{}
-	var _ map[string]interface{}
-	var _ chan interface{}
-	var _ func() interface{}
-}
-
-// don't lose blank lines in grouped declarations
-const (
-	_	int	= 0
-	_	float	= 1
-
-	_	string	= "foo"
-
-	_	= iota
-	_
-
-	// a comment
-	_
-
-	_
-)
-
-type (
-	_	int
-	_	struct{}
-
-	_	interface{}
-
-	// a comment
-	_	map[string]int
-)
-
-var (
-	_	int	= 0
-	_	float	= 1
-
-	_	string	= "foo"
-
-	_	bool
-
-	// a comment
-	_	bool
-)
-
-// don't lose blank lines in this struct
-type _ struct {
-	String	struct {
-		Str, Len int
-	}
-	Slice	struct {
-		Array, Len, Cap int
-	}
-	Eface	struct {
-		Typ, Ptr int
-	}
-
-	UncommonType	struct {
-		Name, PkgPath int
-	}
-	CommonType	struct {
-		Size, Hash, Alg, Align, FieldAlign, String, UncommonType int
-	}
-	Type	struct {
-		Typ, Ptr int
-	}
-	StructField	struct {
-		Name, PkgPath, Typ, Tag, Offset int
-	}
-	StructType	struct {
-		Fields int
-	}
-	PtrType	struct {
-		Elem int
-	}
-	SliceType	struct {
-		Elem int
-	}
-	ArrayType	struct {
-		Elem, Len int
-	}
-
-	Stktop	struct {
-		Stackguard, Stackbase, Gobuf int
-	}
-	Gobuf	struct {
-		Sp, Pc, G int
-	}
-	G	struct {
-		Stackbase, Sched, Status, Alllink int
-	}
-}
-
-// no blank lines in empty structs and interfaces, but leave 1- or 2-line layout alone
-type _ struct{}
-type _ struct {
-}
-
-type _ interface{}
-type _ interface {
-}
-
-// no tabs for single or ungrouped decls
-func _() {
-	const xxxxxx = 0
-	type x int
-	var xxx int
-	var yyyy float = 3.14
-	var zzzzz = "bar"
-
-	const (
-		xxxxxx = 0
-	)
-	type (
-		x int
-	)
-	var (
-		xxx int
-	)
-	var (
-		yyyy float = 3.14
-	)
-	var (
-		zzzzz = "bar"
-	)
-}
-
-// tabs for multiple or grouped decls
-func _() {
-	// no entry has a type
-	const (
-		zzzzzz	= 1
-		z	= 2
-		zzz	= 3
-	)
-	// some entries have a type
-	const (
-		xxxxxx			= 1
-		x			= 2
-		xxx			= 3
-		yyyyyyyy	float	= iota
-		yyyy			= "bar"
-		yyy
-		yy	= 2
-	)
-}
-
-func _() {
-	// no entry has a type
-	var (
-		zzzzzz	= 1
-		z	= 2
-		zzz	= 3
-	)
-	// no entry has a value
-	var (
-		_	int
-		_	float
-		_	string
-
-		_	int	// comment
-		_	float	// comment
-		_	string	// comment
-	)
-	// some entries have a type
-	var (
-		xxxxxx		int
-		x		float
-		xxx		string
-		yyyyyyyy	int	= 1234
-		y		float	= 3.14
-		yyyy			= "bar"
-		yyy		string	= "foo"
-	)
-	// mixed entries - all comments should be aligned
-	var (
-		a, b, c			int
-		x			= 10
-		d			int			// comment
-		y				= 20		// comment
-		f, ff, fff, ffff	int	= 0, 1, 2, 3	// comment
-	)
-	// respect original line breaks
-	var _ = []T{
-		T{0x20, "Telugu"},
-	}
-	var _ = []T{
-		// respect original line breaks
-		T{0x20, "Telugu"},
-	}
-}
-
-// use the formatted output rather than the input to decide when to align
-// (was issue 4505)
-const (
-	short		= 2 * (1 + 2)
-	aMuchLongerName	= 3
-)
-
-var (
-	short		= X{}
-	aMuchLongerName	= X{}
-
-	x1	= X{}	// foo
-	x2	= X{}	// foo
-)
-
-func _() {
-	type (
-		xxxxxx	int
-		x	float
-		xxx	string
-		xxxxx	[]x
-		xx	struct{}
-		xxxxxxx	struct {
-			_, _	int
-			_	float
-		}
-		xxxx	chan<- string
-	)
-}
-
-// alignment of "=" in consecutive lines (extended example from issue 1414)
-const (
-	umax	uint	= ^uint(0)		// maximum value for a uint
-	bpu		= 1 << (5 + umax>>63)	// bits per uint
-	foo
-	bar	= -1
-)
-
-// typical enum
-const (
-	a	MyType	= iota
-	abcd
-	b
-	c
-	def
-)
-
-// excerpt from godoc.go
-var (
-	goroot		= flag.String("goroot", runtime.GOROOT(), "Go root directory")
-	testDir		= flag.String("testdir", "", "Go root subdirectory - for testing only (faster startups)")
-	pkgPath		= flag.String("path", "", "additional package directories (colon-separated)")
-	filter		= flag.String("filter", "", "filter file containing permitted package directory paths")
-	filterMin	= flag.Int("filter_minutes", 0, "filter file update interval in minutes; disabled if <= 0")
-	filterDelay	delayTime	// actual filter update interval in minutes; usually filterDelay == filterMin, but filterDelay may back off exponentially
-)
-
-// formatting of structs
-type _ struct{}
-
-type _ struct { /* this comment should be visible */
-}
-
-type _ struct {
-	// this comment should be visible and properly indented
-}
-
-type _ struct {	// this comment must not change indentation
-	f			int
-	f, ff, fff, ffff	int
-}
-
-type _ struct {
-	string
-}
-
-type _ struct {
-	string	// comment
-}
-
-type _ struct {
-	string "tag"
-}
-
-type _ struct {
-	string "tag"	// comment
-}
-
-type _ struct {
-	f int
-}
-
-type _ struct {
-	f int	// comment
-}
-
-type _ struct {
-	f int "tag"
-}
-
-type _ struct {
-	f int "tag"	// comment
-}
-
-type _ struct {
-	bool
-	a, b, c			int
-	int			"tag"
-	ES				// comment
-	float			"tag"	// comment
-	f			int	// comment
-	f, ff, fff, ffff	int	// comment
-	g			float	"tag"
-	h			float	"tag"	// comment
-}
-
-type _ struct {
-	a, b,
-	c, d	int	// this line should be indented
-	u, v, w, x	float	// this line should be indented
-	p, q,
-	r, s	float	// this line should be indented
-}
-
-// difficult cases
-type _ struct {
-	bool		// comment
-	text	[]byte	// comment
-}
-
-// formatting of interfaces
-type EI interface{}
-
-type _ interface {
-	EI
-}
-
-type _ interface {
-	f()
-	fffff()
-}
-
-type _ interface {
-	EI
-	f()
-	fffffg()
-}
-
-type _ interface {	// this comment must not change indentation
-	EI				// here's a comment
-	f()				// no blank between identifier and ()
-	fffff()				// no blank between identifier and ()
-	gggggggggggg(x, y, z int)	// hurray
-}
-
-// formatting of variable declarations
-func _() {
-	type day struct {
-		n		int
-		short, long	string
-	}
-	var (
-		Sunday		= day{0, "SUN", "Sunday"}
-		Monday		= day{1, "MON", "Monday"}
-		Tuesday		= day{2, "TUE", "Tuesday"}
-		Wednesday	= day{3, "WED", "Wednesday"}
-		Thursday	= day{4, "THU", "Thursday"}
-		Friday		= day{5, "FRI", "Friday"}
-		Saturday	= day{6, "SAT", "Saturday"}
-	)
-}
-
-// formatting of multi-line variable declarations
-var a1, b1, c1 int	// all on one line
-
-var a2, b2,
-	c2 int	// this line should be indented
-
-var (
-	a3, b3,
-	c3, d3	int	// this line should be indented
-	a4, b4, c4	int	// this line should be indented
-)
-
-// Test case from issue 3304: multi-line declarations must end
-// a formatting section and not influence indentation of the
-// next line.
-var (
-	minRefreshTimeSec	= flag.Int64("min_refresh_time_sec", 604800,
-		"minimum time window between two refreshes for a given user.")
-	x	= flag.Int64("refresh_user_rollout_percent", 100,
-		"temporary flag to ramp up the refresh user rpc")
-	aVeryLongVariableName	= stats.GetVarInt("refresh-user-count")
-)
-
-func _() {
-	var privateKey2 = &Block{Type:	"RSA PRIVATE KEY",
-		Headers:	map[string]string{},
-		Bytes: []uint8{0x30, 0x82, 0x1, 0x3a, 0x2, 0x1, 0x0, 0x2,
-			0x41, 0x0, 0xb2, 0x99, 0xf, 0x49, 0xc4, 0x7d, 0xfa, 0x8c,
-			0xd4, 0x0, 0xae, 0x6a, 0x4d, 0x1b, 0x8a, 0x3b, 0x6a, 0x13,
-			0x64, 0x2b, 0x23, 0xf2, 0x8b, 0x0, 0x3b, 0xfb, 0x97, 0x79,
-		},
-	}
-}
-
-func _() {
-	var Universe = Scope{
-		Names: map[string]*Ident{
-			// basic types
-			"bool":		nil,
-			"byte":		nil,
-			"int8":		nil,
-			"int16":	nil,
-			"int32":	nil,
-			"int64":	nil,
-			"uint8":	nil,
-			"uint16":	nil,
-			"uint32":	nil,
-			"uint64":	nil,
-			"float32":	nil,
-			"float64":	nil,
-			"string":	nil,
-
-			// convenience types
-			"int":		nil,
-			"uint":		nil,
-			"uintptr":	nil,
-			"float":	nil,
-
-			// constants
-			"false":	nil,
-			"true":		nil,
-			"iota":		nil,
-			"nil":		nil,
-
-			// functions
-			"cap":		nil,
-			"len":		nil,
-			"new":		nil,
-			"make":		nil,
-			"panic":	nil,
-			"panicln":	nil,
-			"print":	nil,
-			"println":	nil,
-		},
-	}
-}
-
-// alignment of map composite entries
-var _ = map[int]int{
-	// small key sizes: always align even if size ratios are large
-	a:			a,
-	abcdefghabcdefgh:	a,
-	ab:			a,
-	abc:			a,
-	abcdefgabcdefg:		a,
-	abcd:			a,
-	abcde:			a,
-	abcdef:			a,
-
-	// mixed key sizes: align when key sizes change within accepted ratio
-	abcdefgh:		a,
-	abcdefghabcdefg:	a,
-	abcdefghij:		a,
-	abcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghij:	a,	// outlier - do not align with previous line
-	abcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghij:		a,	// align with previous line
-
-	ab:	a,	// do not align with previous line
-	abcde:	a,	// align with previous line
-}
-
-// alignment of map composite entries: test cases from issue 3965
-// aligned
-var _ = T1{
-	a:			x,
-	b:			y,
-	cccccccccccccccccccc:	z,
-}
-
-// not aligned
-var _ = T2{
-	a:	x,
-	b:	y,
-	ccccccccccccccccccccc:	z,
-}
-
-// aligned
-var _ = T3{
-	aaaaaaaaaaaaaaaaaaaa:	x,
-	b:			y,
-	c:			z,
-}
-
-// not aligned
-var _ = T4{
-	aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:	x,
-	b:	y,
-	c:	z,
-}
-
-func _() {
-	var _ = T{
-		a,	// must introduce trailing comma
-	}
-}
-
-// formatting of function results
-func _() func()				{}
-func _() func(int)			{ return nil }
-func _() func(int) int			{ return nil }
-func _() func(int) func(int) func()	{ return nil }
-
-// formatting of consecutive single-line functions
-func _()	{}
-func _()	{}
-func _()	{}
-
-func _()	{}	// an empty line before this function
-func _()	{}
-func _()	{}
-
-func _()		{ f(1, 2, 3) }
-func _(x int) int	{ y := x; return y + 1 }
-func _() int		{ type T struct{}; var x T; return x }
-
-// these must remain multi-line since they are multi-line in the source
-func _() {
-	f(1, 2, 3)
-}
-func _(x int) int {
-	y := x
-	return y + 1
-}
-func _() int {
-	type T struct{}
-	var x T
-	return x
-}
-
-// making function declarations safe for new semicolon rules
-func _()	{ /* single-line function because of "short-ish" comment */ }
-func _() { /* multi-line function because of "long-ish" comment - much more comment text is following here */ /* and more */
-}
-
-func _() {
-	/* multi-line func because block is on multiple lines */
-}
-
-// ellipsis parameters
-func _(...int)
-func _(...*int)
-func _(...[]int)
-func _(...struct{})
-func _(bool, ...interface{})
-func _(bool, ...func())
-func _(bool, ...func(...int))
-func _(bool, ...map[string]int)
-func _(bool, ...chan int)
-
-func _(b bool, x ...int)
-func _(b bool, x ...*int)
-func _(b bool, x ...[]int)
-func _(b bool, x ...struct{})
-func _(x ...interface{})
-func _(x ...func())
-func _(x ...func(...int))
-func _(x ...map[string]int)
-func _(x ...chan int)
-
-// these parameter lists must remain multi-line since they are multi-line in the source
-func _(bool,
-	int) {
-}
-func _(x bool,
-	y int) {
-}
-func _(x,
-	y bool) {
-}
-func _(bool,	// comment
-	int) {
-}
-func _(x bool,	// comment
-	y int) {
-}
-func _(x,	// comment
-	y bool) {
-}
-func _(bool,	// comment
-	// comment
-	int) {
-}
-func _(x bool,	// comment
-	// comment
-	y int) {
-}
-func _(x,	// comment
-	// comment
-	y bool) {
-}
-func _(bool,
-	// comment
-	int) {
-}
-func _(x bool,
-	// comment
-	y int) {
-}
-func _(x,
-	// comment
-	y bool) {
-}
-func _(x,	// comment
-	y,	// comment
-	z bool) {
-}
-func _(x,	// comment
-	y,	// comment
-	z bool) {
-}
-func _(x int,	// comment
-	y float,	// comment
-	z bool) {
-}
-
-// properly indent multi-line signatures
-func ManageStatus(in <-chan *Status, req <-chan Request,
-	stat chan<- *TargetInfo,
-	TargetHistorySize int) {
-}
-
-func MultiLineSignature0(
-	a, b, c int,
-) {
-}
-
-func MultiLineSignature1(
-	a, b, c int,
-	u, v, w float,
-) {
-}
-
-func MultiLineSignature2(
-	a, b,
-	c int,
-) {
-}
-
-func MultiLineSignature3(
-	a, b,
-	c int, u, v,
-	w float,
-	x ...int) {
-}
-
-func MultiLineSignature4(
-	a, b, c int,
-	u, v,
-	w float,
-	x ...int) {
-}
-
-func MultiLineSignature5(
-	a, b, c int,
-	u, v, w float,
-	p, q,
-	r string,
-	x ...int) {
-}
-
-// make sure it also works for methods in interfaces
-type _ interface {
-	MultiLineSignature0(
-		a, b, c int,
-	)
-
-	MultiLineSignature1(
-		a, b, c int,
-		u, v, w float,
-	)
-
-	MultiLineSignature2(
-		a, b,
-		c int,
-	)
-
-	MultiLineSignature3(
-		a, b,
-		c int, u, v,
-		w float,
-		x ...int)
-
-	MultiLineSignature4(
-		a, b, c int,
-		u, v,
-		w float,
-		x ...int)
-
-	MultiLineSignature5(
-		a, b, c int,
-		u, v, w float,
-		p, q,
-		r string,
-		x ...int)
-}
-
-// omit superfluous parentheses in parameter lists
-func _(int)
-func _(int)
-func _(x int)
-func _(x int)
-func _(x, y int)
-func _(x, y int)
-
-func _() int
-func _() int
-func _() int
-
-func _() (x int)
-func _() (x int)
-func _() (x int)
-
-// special cases: some channel types require parentheses
-func _(x chan (<-chan int))
-func _(x chan (<-chan int))
-func _(x chan (<-chan int))
-
-func _(x chan<- (chan int))
-func _(x chan<- (chan int))
-func _(x chan<- (chan int))
-
-// don't introduce comma after last parameter if the closing ) is on the same line
-// even if the parameter type itself is multi-line (test cases from issue 4533)
-func _(...interface{})
-func _(...interface {
-	m()
-	n()
-})	// no extra comma between } and )
-
-func (t *T) _(...interface{})
-func (t *T) _(...interface {
-	m()
-	n()
-})	// no extra comma between } and )
-
-func _(interface{})
-func _(interface {
-	m()
-})	// no extra comma between } and )
-
-func _(struct{})
-func _(struct {
-	x	int
-	y	int
-})	// no extra comma between } and )
diff --git a/src/pkg/go/printer/testdata/declarations.input b/src/pkg/go/printer/testdata/declarations.input
deleted file mode 100644
index d9951d3..0000000
--- a/src/pkg/go/printer/testdata/declarations.input
+++ /dev/null
@@ -1,967 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package imports
-
-import "io"
-
-import (
-	_ "io"
-)
-
-import _ "io"
-
-import (
-	"io"
-	"io"
-	"io"
-)
-
-import (
-	"io"
-	aLongRename "io"
-
-	b "io"
-)
-
-import (
-       "unrenamed"
-       renamed "renameMe"
-       . "io"
-       _ "io"
-       "io"
-       . "os"
-)
-
-// no newlines between consecutive single imports, but
-// respect extra line breaks in the source (at most one empty line)
-import _ "io"
-import _ "io"
-import _ "io"
-
-import _ "os"
-import _ "os"
-import _ "os"
-
-
-import _ "fmt"
-import _ "fmt"
-import _ "fmt"
-
-import "foo"  // a comment
-import "bar"  // a comment
-
-import (
-	_ "foo"
-	// a comment
-	"bar"
-	"foo"  // a comment
-	"bar"  // a comment
-)
-
-// comments + renames
-import (
-       "unrenamed" // a comment
-       renamed "renameMe"
-       . "io" /* a comment */
-       _ "io/ioutil" // a comment
-       "io" // testing alignment
-       . "os"
-       // a comment
-)
-
-// a case that caused problems in the past (comment placement)
-import (
-	. "fmt"
-	"io"
-	"malloc"	// for the malloc count test only
-	"math"
-	"strings"
-	"testing"
-)
-
-// more import examples
-import (
-	"xxx"
-	"much_longer_name" // comment
-	"short_name" // comment
-)
-
-import (
-	_ "xxx"
-	"much_longer_name" // comment
-)
-
-import (
-	mymath "math"
-	"/foo/bar/long_package_path" // a comment
-)
-
-import (
-	"package_a" // comment
-	"package_b"
-	my_better_c "package_c" // comment
-	"package_d" // comment
-	my_e "package_e" // comment
-
-	"package_a"    // comment
-	"package_bb"
-	"package_ccc"  // comment
-	"package_dddd" // comment
-)
-
-// at least one empty line between declarations of different kind
-import _ "io"
-var _ int
-
-// at least one empty line between declarations of the same kind
-// if there is associated documentation (was issue 2570)
-type T1 struct{}
-// T2 comment
-type T2 struct {
-} // should be a two-line struct
-
-
-// T3 comment
-type T2 struct {
-
-
-} // should be a two-line struct
-
-
-// printing of constant literals
-const (
-	_ = "foobar"
-	_ = "a۰۱۸"
-	_ = "foo६४"
-	_ = "bar9876"
-	_ = 0
-	_ = 1
-	_ = 123456789012345678890
-	_ = 01234567
-	_ = 0xcafebabe
-	_ = 0.
-	_ = .0
-	_ = 3.14159265
-	_ = 1e0
-	_ = 1e+100
-	_ = 1e-100
-	_ = 2.71828e-1000
-	_ = 0i
-	_ = 1i
-	_ = 012345678901234567889i
-	_ = 123456789012345678890i
-	_ = 0.i
-	_ = .0i
-	_ = 3.14159265i
-	_ = 1e0i
-	_ = 1e+100i
-	_ = 1e-100i
-	_ = 2.71828e-1000i
-	_ = 'a'
-	_ = '\000'
-	_ = '\xFF'
-	_ = '\uff16'
-	_ = '\U0000ff16'
-	_ = `foobar`
-	_ = `foo
----
----
-bar`
-)
-
-
-func _() {
-	type _ int
-	type _ *int
-	type _ []int
-	type _ map[string]int
-	type _ chan int
-	type _ func() int
-
-	var _ int
-	var _ *int
-	var _ []int
-	var _ map[string]int
-	var _ chan int
-	var _ func() int
-
-	type _ struct{}
-	type _ *struct{}
-	type _ []struct{}
-	type _ map[string]struct{}
-	type _ chan struct{}
-	type _ func() struct{}
-
-	type _ interface{}
-	type _ *interface{}
-	type _ []interface{}
-	type _ map[string]interface{}
-	type _ chan interface{}
-	type _ func() interface{}
-
-	var _ struct{}
-	var _ *struct{}
-	var _ []struct{}
-	var _ map[string]struct{}
-	var _ chan struct{}
-	var _ func() struct{}
-
-	var _ interface{}
-	var _ *interface{}
-	var _ []interface{}
-	var _ map[string]interface{}
-	var _ chan interface{}
-	var _ func() interface{}
-}
-
-
-// don't lose blank lines in grouped declarations
-const (
-	_ int = 0
-	_ float = 1
-
-	_ string = "foo"
-
-	_ = iota
-	_
-	
-	// a comment
-	_
-
-	_
-)
-
-
-type (
-	_ int
-	_ struct {}
-	
-	_ interface{}
-	
-	// a comment
-	_ map[string]int
-)
-
-
-var (
-	_ int = 0
-	_ float = 1
-
-	_ string = "foo"
-
-	_ bool
-	
-	// a comment
-	_ bool
-)
-
-
-// don't lose blank lines in this struct
-type _ struct {
-	String struct {
-		Str, Len int
-	}
-	Slice struct {
-		Array, Len, Cap int
-	}
-	Eface struct {
-		Typ, Ptr int
-	}
-
-	UncommonType struct {
-		Name, PkgPath int
-	}
-	CommonType struct {
-		Size, Hash, Alg, Align, FieldAlign, String, UncommonType int
-	}
-	Type struct {
-		Typ, Ptr int
-	}
-	StructField struct {
-		Name, PkgPath, Typ, Tag, Offset int
-	}
-	StructType struct {
-		Fields int
-	}
-	PtrType struct {
-		Elem int
-	}
-	SliceType struct {
-		Elem int
-	}
-	ArrayType struct {
-		Elem, Len int
-	}
-
-	Stktop struct {
-		Stackguard, Stackbase, Gobuf int
-	}
-	Gobuf struct {
-		Sp, Pc, G int
-	}
-	G struct {
-		Stackbase, Sched, Status, Alllink int
-	}
-}
-
-
-// no blank lines in empty structs and interfaces, but leave 1- or 2-line layout alone
-type _ struct{            }
-type _ struct {
-
-}
-
-type _ interface{            }
-type _ interface {
-
-}
-
-
-// no tabs for single or ungrouped decls
-func _() {
-	const xxxxxx = 0
-	type x int
-	var xxx int
-	var yyyy float = 3.14
-	var zzzzz = "bar"
-
-	const (
-		xxxxxx = 0
-	)
-	type (
-		x int
-	)
-	var (
-		xxx int
-	)
-	var (
-		yyyy float = 3.14
-	)
-	var (
-		zzzzz = "bar"
-	)
-}
-
-// tabs for multiple or grouped decls
-func _() {
-	// no entry has a type
-	const (
-		zzzzzz = 1
-		z = 2
-		zzz = 3
-	)
-	// some entries have a type
-	const (
-		xxxxxx = 1
-		x = 2
-		xxx = 3
-		yyyyyyyy float = iota
-		yyyy = "bar"
-		yyy
-		yy = 2
-	)
-}
-
-func _() {
-	// no entry has a type
-	var (
-		zzzzzz = 1
-		z = 2
-		zzz = 3
-	)
-	// no entry has a value
-	var (
-		_ int
-		_ float
-		_ string
-
-		_ int  // comment
-		_ float  // comment
-		_ string  // comment
-	)
-	// some entries have a type
-	var (
-		xxxxxx int
-		x float
-		xxx string
-		yyyyyyyy int = 1234
-		y float = 3.14
-		yyyy = "bar"
-		yyy string = "foo"
-	)
-	// mixed entries - all comments should be aligned
-	var (
-		a, b, c int
-		x = 10
-		d int  // comment
-		y = 20  // comment
-		f, ff, fff, ffff int = 0, 1, 2, 3  // comment
-	)
-	// respect original line breaks
-	var _ = []T {
-		T{0x20,	"Telugu"},
-	}
-	var _ = []T {
-		// respect original line breaks
-		T{0x20,	"Telugu"},
-	}
-}
-
-// use the formatted output rather than the input to decide when to align
-// (was issue 4505)
-const (
-	short = 2 * (
-	1 + 2)
-	aMuchLongerName = 3
-)
-
-var (
-	short = X{
-	}
-	aMuchLongerName = X{}
-
-	x1 = X{} // foo
-	x2 = X{
-	} // foo
-)
-
-func _() {
-	type (
-		xxxxxx int
-		x float
-		xxx string
-		xxxxx []x
-		xx struct{}
-		xxxxxxx struct {
-			_, _ int
-			_ float
-		}
-		xxxx chan<- string
-	)
-}
-
-// alignment of "=" in consecutive lines (extended example from issue 1414)
-const (
-	umax uint                  = ^uint(0) // maximum value for a uint
-	bpu  = 1 << (5 + umax>>63)            // bits per uint
-	foo
-	bar  = -1
-)
-
-// typical enum
-const (
-	a MyType = iota
-	abcd
-	b
-	c
-	def
-)
-
-// excerpt from godoc.go
-var (
-	goroot = flag.String("goroot", runtime.GOROOT(), "Go root directory")
-	testDir = flag.String("testdir", "", "Go root subdirectory - for testing only (faster startups)")
-	pkgPath = flag.String("path", "", "additional package directories (colon-separated)")
-	filter = flag.String("filter", "", "filter file containing permitted package directory paths")
-	filterMin = flag.Int("filter_minutes", 0, "filter file update interval in minutes; disabled if <= 0")
-	filterDelay delayTime // actual filter update interval in minutes; usually filterDelay == filterMin, but filterDelay may back off exponentially
-)
-
-
-// formatting of structs
-type _ struct{}
-
-type _ struct{ /* this comment should be visible */ }
-
-type _ struct{
-	// this comment should be visible and properly indented
-}
-
-type _ struct {  // this comment must not change indentation
-	f int
-	f, ff, fff, ffff int
-}
-
-type _ struct {
-	string
-}
-
-type _ struct {
-	string  // comment
-}
-
-type _ struct {
-	string "tag"
-}
-
-type _ struct {
-	string "tag"  // comment
-}
-
-type _ struct {
-	f int
-}
-
-type _ struct {
-	f int  // comment
-}
-
-type _ struct {
-	f int "tag"
-}
-
-type _ struct {
-	f int "tag"  // comment
-}
-
-type _ struct {
-	bool
-	a, b, c int
-	int "tag"
-	ES // comment
-	float "tag"  // comment
-	f int  // comment
-	f, ff, fff, ffff int  // comment
-	g float "tag"
-	h float "tag"  // comment
-}
-
-type _ struct { a, b,
-c, d int  // this line should be indented
-u, v, w, x float // this line should be indented
-p, q,
-r, s float // this line should be indented
-}
-
-
-// difficult cases
-type _ struct {
-	bool  // comment
-	text []byte  // comment
-}
-
-
-// formatting of interfaces
-type EI interface{}
-
-type _ interface {
-	EI
-}
-
-type _ interface {
-	f()
-	fffff()
-}
-
-type _ interface {
-	EI
-	f()
-	fffffg()
-}
-
-type _ interface {  // this comment must not change indentation
-	EI  // here's a comment
-	f()  // no blank between identifier and ()
-	fffff()  // no blank between identifier and ()
-	gggggggggggg(x, y, z int) ()  // hurray
-}
-
-
-// formatting of variable declarations
-func _() {
-	type day struct { n int; short, long string }
-	var (
-		Sunday = day{ 0, "SUN", "Sunday" }
-		Monday = day{ 1, "MON", "Monday" }
-		Tuesday = day{ 2, "TUE", "Tuesday" }
-		Wednesday = day{ 3, "WED", "Wednesday" }
-		Thursday = day{ 4, "THU", "Thursday" }
-		Friday = day{ 5, "FRI", "Friday" }
-		Saturday = day{ 6, "SAT", "Saturday" }
-	)
-}
-
-
-// formatting of multi-line variable declarations
-var a1, b1, c1 int  // all on one line
-
-var a2, b2,
-c2 int  // this line should be indented
-
-var (a3, b3,
-c3, d3 int  // this line should be indented
-a4, b4, c4 int  // this line should be indented
-)
-
-// Test case from issue 3304: multi-line declarations must end
-// a formatting section and not influence indentation of the
-// next line.
-var (
-	minRefreshTimeSec = flag.Int64("min_refresh_time_sec", 604800,
-		"minimum time window between two refreshes for a given user.")
-	x = flag.Int64("refresh_user_rollout_percent", 100,
-		"temporary flag to ramp up the refresh user rpc")
-	aVeryLongVariableName = stats.GetVarInt("refresh-user-count")
-)
-
-func _() {
-	var privateKey2 = &Block{Type: "RSA PRIVATE KEY",
-					Headers: map[string]string{},
-					Bytes: []uint8{0x30, 0x82, 0x1, 0x3a, 0x2, 0x1, 0x0, 0x2,
-			0x41, 0x0, 0xb2, 0x99, 0xf, 0x49, 0xc4, 0x7d, 0xfa, 0x8c,
-			0xd4, 0x0, 0xae, 0x6a, 0x4d, 0x1b, 0x8a, 0x3b, 0x6a, 0x13,
-			0x64, 0x2b, 0x23, 0xf2, 0x8b, 0x0, 0x3b, 0xfb, 0x97, 0x79,
-		},
-	}
-}
-
-
-func _() {
-	var Universe = Scope {
-		Names: map[string]*Ident {
-			// basic types
-			"bool": nil,
-			"byte": nil,
-			"int8": nil,
-			"int16": nil,
-			"int32": nil,
-			"int64": nil,
-			"uint8": nil,
-			"uint16": nil,
-			"uint32": nil,
-			"uint64": nil,
-			"float32": nil,
-			"float64": nil,
-			"string": nil,
-
-			// convenience types
-			"int": nil,
-			"uint": nil,
-			"uintptr": nil,
-			"float": nil,
-
-			// constants
-			"false": nil,
-			"true": nil,
-			"iota": nil,
-			"nil": nil,
-
-			// functions
-			"cap": nil,
-			"len": nil,
-			"new": nil,
-			"make": nil,
-			"panic": nil,
-			"panicln": nil,
-			"print": nil,
-			"println": nil,
-		},
-	}
-}
-
-
-// alignment of map composite entries
-var _ = map[int]int{
-	// small key sizes: always align even if size ratios are large
-	a: a,
-	abcdefghabcdefgh: a,
-	ab: a,
-	abc: a,
-	abcdefgabcdefg: a,
-	abcd: a,
-	abcde: a,
-	abcdef: a,
-
-	// mixed key sizes: align when key sizes change within accepted ratio
-	abcdefgh: a,
-	abcdefghabcdefg: a,
-	abcdefghij: a,
-	abcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghij: a, // outlier - do not align with previous line
-	abcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghij: a, // align with previous line
-
-	ab: a, // do not align with previous line
-	abcde: a, // align with previous line
-}
-
-// alignment of map composite entries: test cases from issue 3965
-// aligned
-var _ = T1{
-	a:                    x,
-	b:                    y,
-	cccccccccccccccccccc: z,
-}
-
-// not aligned
-var _ = T2{
-	a: x,
-	b: y,
-	ccccccccccccccccccccc: z,
-}
-
-// aligned
-var _ = T3{
-	aaaaaaaaaaaaaaaaaaaa: x,
-	b:                    y,
-	c:                    z,
-}
-
-// not aligned
-var _ = T4{
-	aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: x,
-	b:                                       y,
-	c:                                       z,
-}
-
-
-func _() {
-	var _ = T{
-		a,	// must introduce trailing comma
-	}
-}
-
-
-// formatting of function results
-func _() func() {}
-func _() func(int) { return nil }
-func _() func(int) int { return nil }
-func _() func(int) func(int) func() { return nil }
-
-
-// formatting of consecutive single-line functions
-func _() {}
-func _() {}
-func _() {}
-
-func _() {}  // an empty line before this function
-func _() {}
-func _() {}
-
-func _() { f(1, 2, 3) }
-func _(x int) int { y := x; return y+1 }
-func _() int { type T struct{}; var x T; return x }
-
-// these must remain multi-line since they are multi-line in the source
-func _() {
-	f(1, 2, 3)
-}
-func _(x int) int {
-	y := x; return y+1
-}
-func _() int {
-	type T struct{}; var x T; return x
-}
-
-
-// making function declarations safe for new semicolon rules
-func _() { /* single-line function because of "short-ish" comment */ }
-func _() { /* multi-line function because of "long-ish" comment - much more comment text is following here */ /* and more */ }
-
-func _() {
-/* multi-line func because block is on multiple lines */ }
-
-
-// ellipsis parameters
-func _(...int)
-func _(...*int)
-func _(...[]int)
-func _(...struct{})
-func _(bool, ...interface{})
-func _(bool, ...func())
-func _(bool, ...func(...int))
-func _(bool, ...map[string]int)
-func _(bool, ...chan int)
-
-func _(b bool, x ...int)
-func _(b bool, x ...*int)
-func _(b bool, x ...[]int)
-func _(b bool, x ...struct{})
-func _(x ...interface{})
-func _(x ...func())
-func _(x ...func(...int))
-func _(x ...map[string]int)
-func _(x ...chan int)
-
-
-// these parameter lists must remain multi-line since they are multi-line in the source
-func _(bool,
-int) {
-}
-func _(x bool,
-y int) {
-}
-func _(x,
-y bool) {
-}
-func _(bool, // comment
-int) {
-}
-func _(x bool, // comment
-y int) {
-}
-func _(x, // comment
-y bool) {
-}
-func _(bool, // comment
-// comment
-int) {
-}
-func _(x bool, // comment
-// comment
-y int) {
-}
-func _(x, // comment
-// comment
-y bool) {
-}
-func _(bool,
-// comment
-int) {
-}
-func _(x bool,
-// comment
-y int) {
-}
-func _(x,
-// comment
-y bool) {
-}
-func _(x, // comment
-y,// comment
-z bool) {
-}
-func _(x, // comment
-	y,// comment
-	z bool) {
-}
-func _(x int,	// comment
-	y float,	// comment
-	z bool) {
-}
-
-
-// properly indent multi-line signatures
-func ManageStatus(in <-chan *Status, req <-chan Request,
-stat chan<- *TargetInfo,
-TargetHistorySize int) {
-}
-
-func MultiLineSignature0(
-a, b, c int,
-) {}
-
-func MultiLineSignature1(
-a, b, c int,
-u, v, w float,
-) {}
-
-func MultiLineSignature2(
-a, b,
-c int,
-) {}
-
-func MultiLineSignature3(
-a, b,
-c int, u, v,
-w float,
-		x ...int) {}
-
-func MultiLineSignature4(
-a, b, c int,
-u, v,
-w float,
-		x ...int) {}
-
-func MultiLineSignature5(
-a, b, c int,
-u, v, w float,
-p, q,
-r string,
-		x ...int) {}
-
-// make sure it also works for methods in interfaces
-type _ interface {
-MultiLineSignature0(
-a, b, c int,
-)
-
-MultiLineSignature1(
-a, b, c int,
-u, v, w float,
-)
-
-MultiLineSignature2(
-a, b,
-c int,
-)
-
-MultiLineSignature3(
-a, b,
-c int, u, v,
-w float,
-		x ...int)
-
-MultiLineSignature4(
-a, b, c int,
-u, v,
-w float,
-		x ...int)
-
-MultiLineSignature5(
-a, b, c int,
-u, v, w float,
-p, q,
-r string,
-		x ...int)
-}
-
-// omit superfluous parentheses in parameter lists
-func _((int))
-func _((((((int))))))
-func _(x (int))
-func _(x (((((int))))))
-func _(x, y (int))
-func _(x, y (((((int))))))
-
-func _() (int)
-func _() ((int))
-func _() ((((((int))))))
-
-func _() (x int)
-func _() (x (int))
-func _() (x (((((int))))))
-
-// special cases: some channel types require parentheses
-func _(x chan(<-chan int))
-func _(x (chan(<-chan int)))
-func _(x ((((chan(<-chan int))))))
-
-func _(x chan<-(chan int))
-func _(x (chan<-(chan int)))
-func _(x ((((chan<-(chan int))))))
-
-// don't introduce comma after last parameter if the closing ) is on the same line
-// even if the parameter type itself is multi-line (test cases from issue 4533)
-func _(...interface{})
-func _(...interface {
-	m()
-	n()
-}) // no extra comma between } and )
-
-func (t *T) _(...interface{})
-func (t *T) _(...interface {
-	m()
-	n()
-}) // no extra comma between } and )
-
-func _(interface{})
-func _(interface {
-	m()
-}) // no extra comma between } and )
-
-func _(struct{})
-func _(struct {
-	x int
-	y int
-}) // no extra comma between } and )
diff --git a/src/pkg/go/printer/testdata/expressions.golden b/src/pkg/go/printer/testdata/expressions.golden
deleted file mode 100644
index fbe8275..0000000
--- a/src/pkg/go/printer/testdata/expressions.golden
+++ /dev/null
@@ -1,681 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package expressions
-
-type T struct {
-	x, y, z int
-}
-
-var (
-	a, b, c, d, e						int
-	under_bar						int
-	longIdentifier1, longIdentifier2, longIdentifier3	int
-	t0, t1, t2						T
-	s							string
-	p							*int
-)
-
-func _() {
-	// no spaces around simple or parenthesized expressions
-	_ = (a + 0)
-	_ = a + b
-	_ = a + b + c
-	_ = a + b - c
-	_ = a - b - c
-	_ = a + (b * c)
-	_ = a + (b / c)
-	_ = a - (b % c)
-	_ = 1 + a
-	_ = a + 1
-	_ = a + b + 1
-	_ = s[a]
-	_ = s[a:]
-	_ = s[:b]
-	_ = s[1:2]
-	_ = s[a:b]
-	_ = s[0:len(s)]
-	_ = s[0] << 1
-	_ = (s[0] << 1) & 0xf
-	_ = s[0]<<2 | s[1]>>4
-	_ = "foo" + s
-	_ = s + "foo"
-	_ = 'a' + 'b'
-	_ = len(s) / 2
-	_ = len(t0.x) / a
-
-	// spaces around expressions of different precedence or expressions containing spaces
-	_ = a + -b
-	_ = a - ^b
-	_ = a / *p
-	_ = a + b*c
-	_ = 1 + b*c
-	_ = a + 2*c
-	_ = a + c*2
-	_ = 1 + 2*3
-	_ = s[1 : 2*3]
-	_ = s[a : b-c]
-	_ = s[0:]
-	_ = s[a+b]
-	_ = s[:b-c]
-	_ = s[a+b:]
-	_ = a[a<<b+1]
-	_ = a[a<<b+1:]
-	_ = s[a+b : len(s)]
-	_ = s[len(s):-a]
-	_ = s[a : len(s)+1]
-	_ = s[a:len(s)+1] + s
-
-	// spaces around operators with equal or lower precedence than comparisons
-	_ = a == b
-	_ = a != b
-	_ = a > b
-	_ = a >= b
-	_ = a < b
-	_ = a <= b
-	_ = a < b && c > d
-	_ = a < b || c > d
-
-	// spaces around "long" operands
-	_ = a + longIdentifier1
-	_ = longIdentifier1 + a
-	_ = longIdentifier1 + longIdentifier2*longIdentifier3
-	_ = s + "a longer string"
-
-	// some selected cases
-	_ = a + t0.x
-	_ = a + t0.x + t1.x*t2.x
-	_ = a + b + c + d + e + 2*3
-	_ = a + b + c + 2*3 + d + e
-	_ = (a + b + c) * 2
-	_ = a - b + c - d + (a + b + c) + d&e
-	_ = under_bar - 1
-	_ = Open(dpath+"/file", O_WRONLY|O_CREAT, 0666)
-	_ = int(c0&_Mask4)<<18 | int(c1&_Maskx)<<12 | int(c2&_Maskx)<<6 | int(c3&_Maskx)
-
-	// the parser does not restrict expressions that may appear as statements
-	true
-	42
-	"foo"
-	x
-	(x)
-	a + b
-	a + b + c
-	a + (b * c)
-	a + (b / c)
-	1 + a
-	a + 1
-	s[a]
-	x << 1
-	(s[0] << 1) & 0xf
-	"foo" + s
-	x == y
-	x < y || z > 42
-}
-
-// slice expressions with cap
-func _() {
-	_ = x[a:b:c]
-	_ = x[a:b : c+d]
-	_ = x[a : b+d : c]
-	_ = x[a : b+d : c+d]
-	_ = x[a+d : b:c]
-	_ = x[a+d : b : c+d]
-	_ = x[a+d : b+d : c]
-	_ = x[a+d : b+d : c+d]
-
-	_ = x[:b:c]
-	_ = x[:b : c+d]
-	_ = x[:b+d : c]
-	_ = x[:b+d : c+d]
-}
-
-func _() {
-	_ = a + b
-	_ = a + b + c
-	_ = a + b*c
-	_ = a + (b * c)
-	_ = (a + b) * c
-	_ = a + (b * c * d)
-	_ = a + (b*c + d)
-
-	_ = 1 << x
-	_ = -1 << x
-	_ = 1<<x - 1
-	_ = -1<<x - 1
-
-	_ = f(a + b)
-	_ = f(a + b + c)
-	_ = f(a + b*c)
-	_ = f(a + (b * c))
-	_ = f(1<<x-1, 1<<x-2)
-
-	_ = 1<<d.logWindowSize - 1
-
-	buf = make(x, 2*cap(b.buf)+n)
-
-	dst[i*3+2] = dbuf[0] << 2
-	dst[i*3+2] = dbuf[0]<<2 | dbuf[1]>>4
-
-	b.buf = b.buf[0 : b.off+m+n]
-	b.buf = b.buf[0 : b.off+m*n]
-	f(b.buf[0 : b.off+m+n])
-
-	signed += ' ' * 8
-	tw.octal(header[148:155], chksum)
-
-	_ = x > 0 && i >= 0
-
-	x1, x0 := x>>w2, x&m2
-	z0 = t1<<w2 + t0
-	z1 = (t1 + t0>>w2) >> w2
-	q1, r1 := x1/d1, x1%d1
-	r1 = r1*b2 | x0>>w2
-	x1 = (x1 << z) | (x0 >> (uint(w) - z))
-	x1 = x1<<z | x0>>(uint(w)-z)
-
-	_ = buf[0 : len(buf)+1]
-	_ = buf[0 : n+1]
-
-	a, b = b, a
-	a = b + c
-	a = b*c + d
-	_ = a*b + c
-	_ = a - b - c
-	_ = a - (b - c)
-	_ = a - b*c
-	_ = a - (b * c)
-	_ = a * b / c
-	_ = a / *b
-	_ = x[a|^b]
-	_ = x[a / *b]
-	_ = a & ^b
-	_ = a + +b
-	_ = a - -b
-	_ = x[a*-b]
-	_ = x[a + +b]
-	_ = x ^ y ^ z
-	_ = b[a>>24] ^ b[(a>>16)&0xFF] ^ b[(a>>8)&0xFF] ^ b[a&0xFF]
-	_ = len(longVariableName) * 2
-
-	_ = token(matchType + xlength<<lengthShift + xoffset)
-}
-
-func f(x int, args ...int) {
-	f(0, args...)
-	f(1, args)
-	f(2, args[0])
-
-	// make sure syntactically legal code remains syntactically legal
-	f(3, 42 ...)	// a blank must remain between 42 and ...
-	f(4, 42....)
-	f(5, 42....)
-	f(6, 42.0...)
-	f(7, 42.0...)
-	f(8, .42...)
-	f(9, .42...)
-	f(10, 42e0...)
-	f(11, 42e0...)
-
-	_ = 42 .x	// a blank must remain between 42 and .x
-	_ = 42..x
-	_ = 42..x
-	_ = 42.0.x
-	_ = 42.0.x
-	_ = .42.x
-	_ = .42.x
-	_ = 42e0.x
-	_ = 42e0.x
-
-	// a blank must remain between the binary operator and the 2nd operand
-	_ = x / *y
-	_ = x < -1
-	_ = x < <-1
-	_ = x + +1
-	_ = x - -1
-	_ = x & &x
-	_ = x & ^x
-
-	_ = f(x / *y, x < -1, x < <-1, x + +1, x - -1, x & &x, x & ^x)
-}
-
-func _() {
-	_ = T{}
-	_ = struct{}{}
-	_ = [10]T{}
-	_ = [...]T{}
-	_ = []T{}
-	_ = map[int]T{}
-}
-
-// one-line structs/interfaces in composite literals (up to a threshold)
-func _() {
-	_ = struct{}{}
-	_ = struct{ x int }{0}
-	_ = struct{ x, y, z int }{0, 1, 2}
-	_ = struct{ int }{0}
-	_ = struct{ s struct{ int } }{struct{ int }{0}}
-}
-
-func _() {
-	// do not modify literals
-	_ = "tab1	tab2	tab3	end"	// string contains 3 tabs
-	_ = "tab1 tab2 tab3 end"	// same string with 3 blanks - may be unaligned because editors see tabs in strings
-	_ = ""				// this comment should be aligned with the one on the previous line
-	_ = ``
-	_ = `
-`
-	_ = `foo
-		bar`
-	_ = `three spaces before the end of the line starting here:   
-they must not be removed`
-}
-
-func _() {
-	// smart handling of indentation for multi-line raw strings
-	var _ = ``
-	var _ = `foo`
-	var _ = `foo
-bar`
-
-	var _ = ``
-	var _ = `foo`
-	var _ =
-	// the next line should remain indented
-	`foo
-bar`
-
-	var _ =	// comment
-	``
-	var _ =	// comment
-	`foo`
-	var _ =	// comment
-	// the next line should remain indented
-	`foo
-bar`
-
-	var _ = /* comment */ ``
-	var _ = /* comment */ `foo`
-	var _ = /* comment */ `foo
-bar`
-
-	var _ =	/* comment */
-	``
-	var _ =	/* comment */
-	`foo`
-	var _ =	/* comment */
-	// the next line should remain indented
-	`foo
-bar`
-
-	var board = []int(
-		`...........
-...........
-....●●●....
-....●●●....
-..●●●●●●●..
-..●●●○●●●..
-..●●●●●●●..
-....●●●....
-....●●●....
-...........
-...........
-`)
-
-	var state = S{
-		"foo",
-		// the next line should remain indented
-		`...........
-...........
-....●●●....
-....●●●....
-..●●●●●●●..
-..●●●○●●●..
-..●●●●●●●..
-....●●●....
-....●●●....
-...........
-...........
-`,
-		"bar",
-	}
-}
-
-func _() {
-	// one-line function literals (body is on a single line)
-	_ = func() {}
-	_ = func() int { return 0 }
-	_ = func(x, y int) bool { m := (x + y) / 2; return m < 0 }
-
-	// multi-line function literals (body is not on one line)
-	_ = func() {
-	}
-	_ = func() int {
-		return 0
-	}
-	_ = func(x, y int) bool {
-		m := (x + y) / 2
-		return x < y
-	}
-
-	f(func() {
-	})
-	f(func() int {
-		return 0
-	})
-	f(func(x, y int) bool {
-		m := (x + y) / 2
-		return x < y
-	})
-}
-
-func _() {
-	_ = [][]int{
-		[]int{1},
-		[]int{1, 2},
-		[]int{1, 2, 3},
-	}
-	_ = [][]int{
-		{1},
-		[]int{1, 2},
-		[]int{1, 2, 3},
-	}
-	_ = [][]int{
-		{1},
-		{1, 2},
-		{1, 2, 3},
-	}
-	_ = [][]int{{1}, {1, 2}, {1, 2, 3}}
-}
-
-// various multi-line expressions
-func _() {
-	// do not add extra indentation to multi-line string lists
-	_ = "foo" + "bar"
-	_ = "foo" +
-		"bar" +
-		"bah"
-	_ = []string{
-		"abc" +
-			"def",
-		"foo" +
-			"bar",
-	}
-}
-
-const _ = F1 +
-	`string = "%s";` +
-	`ptr = *;` +
-	`datafmt.T2 = s ["-" p "-"];`
-
-const _ = `datafmt "datafmt";` +
-	`default = "%v";` +
-	`array = *;` +
-	`datafmt.T3 = s  {" " a a / ","};`
-
-const _ = `datafmt "datafmt";` +
-	`default = "%v";` +
-	`array = *;` +
-	`datafmt.T3 = s  {" " a a / ","};`
-
-func _() {
-	_ = F1 +
-		`string = "%s";` +
-		`ptr = *;` +
-		`datafmt.T2 = s ["-" p "-"];`
-
-	_ =
-		`datafmt "datafmt";` +
-			`default = "%v";` +
-			`array = *;` +
-			`datafmt.T3 = s  {" " a a / ","};`
-
-	_ = `datafmt "datafmt";` +
-		`default = "%v";` +
-		`array = *;` +
-		`datafmt.T3 = s  {" " a a / ","};`
-}
-
-func _() {
-	// respect source lines in multi-line expressions
-	_ = a +
-		b +
-		c
-	_ = a < b ||
-		b < a
-	_ = "933262154439441526816992388562667004907159682643816214685929" +
-		"638952175999932299156089414639761565182862536979208272237582" +
-		"51185210916864000000000000000000000000"	// 100!
-	_ = "170141183460469231731687303715884105727"	// prime
-}
-
-// Alignment after overlong lines
-const (
-	_	= "991"
-	_	= "2432902008176640000"	// 20!
-	_	= "933262154439441526816992388562667004907159682643816214685929" +
-		"638952175999932299156089414639761565182862536979208272237582" +
-		"51185210916864000000000000000000000000"	// 100!
-	_	= "170141183460469231731687303715884105727"	// prime
-)
-
-// Correct placement of operators and comments in multi-line expressions
-func _() {
-	_ = a +	// comment
-		b +	// comment
-		c
-	_ = "a" +
-		"b" +	// comment
-		"c"
-	_ = "ba0408" + "7265717569726564"	// field 71, encoding 2, string "required"
-}
-
-// Correct placement of terminating comma/closing parentheses in multi-line calls.
-func _() {
-	f(1,
-		2,
-		3)
-	f(1,
-		2,
-		3,
-	)
-	f(1,
-		2,
-		3)	// comment
-	f(1,
-		2,
-		3,	// comment
-	)
-	f(1,
-		2,
-		3)	// comment
-	f(1,
-		2,
-		3,	// comment
-	)
-}
-
-// Align comments in multi-line lists of single-line expressions.
-var txpix = [NCOL]draw.Color{
-	draw.Yellow,		// yellow
-	draw.Cyan,		// cyan
-	draw.Green,		// lime green
-	draw.GreyBlue,		// slate
-	draw.Red,		/* red */
-	draw.GreyGreen,		/* olive green */
-	draw.Blue,		/* blue */
-	draw.Color(0xFF55AAFF),	/* pink */
-	draw.Color(0xFFAAFFFF),	/* lavender */
-	draw.Color(0xBB005DFF),	/* maroon */
-}
-
-func same(t, u *Time) bool {
-	// respect source lines in multi-line expressions
-	return t.Year == u.Year &&
-		t.Month == u.Month &&
-		t.Day == u.Day &&
-		t.Hour == u.Hour &&
-		t.Minute == u.Minute &&
-		t.Second == u.Second &&
-		t.Weekday == u.Weekday &&
-		t.ZoneOffset == u.ZoneOffset &&
-		t.Zone == u.Zone
-}
-
-func (p *parser) charClass() {
-	// respect source lines in multi-line expressions
-	if cc.negate && len(cc.ranges) == 2 &&
-		cc.ranges[0] == '\n' && cc.ranges[1] == '\n' {
-		nl := new(_NotNl)
-		p.re.add(nl)
-	}
-}
-
-func addState(s []state, inst instr, match []int) {
-	// handle comments correctly in multi-line expressions
-	for i := 0; i < l; i++ {
-		if s[i].inst.index() == index &&	// same instruction
-			s[i].match[0] < pos {	// earlier match already going; leftmost wins
-			return s
-		}
-	}
-}
-
-func (self *T) foo(x int) *T	{ return self }
-
-func _()	{ module.Func1().Func2() }
-
-func _() {
-	_ = new(T).
-		foo(1).
-		foo(2).
-		foo(3)
-
-	_ = new(T).
-		foo(1).
-		foo(2).	// inline comments
-		foo(3)
-
-	_ = new(T).foo(1).foo(2).foo(3)
-
-	// handle multiline argument list correctly
-	_ = new(T).
-		foo(
-		1).
-		foo(2)
-
-	_ = new(T).foo(
-		1).foo(2)
-
-	_ = Array[3+
-		4]
-
-	_ = Method(1, 2,
-		3)
-
-	_ = new(T).
-		foo().
-		bar().(*Type)
-
-	_ = new(T).
-		foo().
-		bar().(*Type).
-		baz()
-
-	_ = new(T).
-		foo().
-		bar()["idx"]
-
-	_ = new(T).
-		foo().
-		bar()["idx"].
-		baz()
-
-	_ = new(T).
-		foo().
-		bar()[1:2]
-
-	_ = new(T).
-		foo().
-		bar()[1:2].
-		baz()
-
-	_ = new(T).
-		Field.
-		Array[3+
-		4].
-		Table["foo"].
-		Blob.(*Type).
-		Slices[1:4].
-		Method(1, 2,
-		3).
-		Thingy
-
-	_ = a.b.c
-	_ = a.
-		b.
-		c
-	_ = a.b().c
-	_ = a.
-		b().
-		c
-	_ = a.b[0].c
-	_ = a.
-		b[0].
-		c
-	_ = a.b[0:].c
-	_ = a.
-		b[0:].
-		c
-	_ = a.b.(T).c
-	_ = a.
-		b.(T).
-		c
-}
-
-// Don't introduce extra newlines in strangely formatted expression lists.
-func f() {
-	// os.Open parameters should remain on two lines
-	if writer, err = os.Open(outfile, s.O_WRONLY|os.O_CREATE|
-		os.O_TRUNC, 0666); err != nil {
-		log.Fatal(err)
-	}
-}
-
-// Handle multi-line argument lists ending in ... correctly.
-// Was issue 3130.
-func _() {
-	_ = append(s, a...)
-	_ = append(
-		s, a...)
-	_ = append(s,
-		a...)
-	_ = append(
-		s,
-		a...)
-	_ = append(s, a...,
-	)
-	_ = append(s,
-		a...,
-	)
-	_ = append(
-		s,
-		a...,
-	)
-}
-
-// Literal function types in conversions must be parenthesized;
-// for now go/parser accepts the unparenthesized form where it
-// is non-ambiguous.
-func _() {
-	// these conversions should be rewritten to look
-	// the same as the parenthesized conversions below
-	_ = (func())(nil)
-	_ = (func(x int) float)(nil)
-	_ = (func() func() func())(nil)
-
-	_ = (func())(nil)
-	_ = (func(x int) float)(nil)
-	_ = (func() func() func())(nil)
-}
diff --git a/src/pkg/go/printer/testdata/expressions.input b/src/pkg/go/printer/testdata/expressions.input
deleted file mode 100644
index f4d20fa..0000000
--- a/src/pkg/go/printer/testdata/expressions.input
+++ /dev/null
@@ -1,710 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package expressions
-
-type T struct {
-	x, y, z int
-}
-
-var (
-	a, b, c, d, e int
-	under_bar int
-	longIdentifier1, longIdentifier2, longIdentifier3 int
-	t0, t1, t2 T
-	s string
-	p *int
-)
-
-
-func _() {
-	// no spaces around simple or parenthesized expressions
-	_ = (a+0)
-	_ = a+b
-	_ = a+b+c
-	_ = a+b-c
-	_ = a-b-c
-	_ = a+(b*c)
-	_ = a+(b/c)
-	_ = a-(b%c)
-	_ = 1+a
-	_ = a+1
-	_ = a+b+1
-	_ = s[a]
-	_ = s[a:]
-	_ = s[:b]
-	_ = s[1:2]
-	_ = s[a:b]
-	_ = s[0:len(s)]
-	_ = s[0]<<1
-	_ = (s[0]<<1)&0xf
-	_ = s[0] << 2 | s[1] >> 4
-	_ = "foo"+s
-	_ = s+"foo"
-	_ = 'a'+'b'
-	_ = len(s)/2
-	_ = len(t0.x)/a
-
-	// spaces around expressions of different precedence or expressions containing spaces
-	_ = a + -b
-	_ = a - ^b
-	_ = a / *p
-	_ = a + b*c
-	_ = 1 + b*c
-	_ = a + 2*c
-	_ = a + c*2
-	_ = 1 + 2*3
-	_ = s[1 : 2*3]
-	_ = s[a : b-c]
-	_ = s[0:]
-	_ = s[a+b]
-	_ = s[: b-c]
-	_ = s[a+b :]
-	_ = a[a<<b+1]
-	_ = a[a<<b+1 :]
-	_ = s[a+b : len(s)]
-	_ = s[len(s) : -a]
-	_ = s[a : len(s)+1]
-	_ = s[a : len(s)+1]+s
-
-	// spaces around operators with equal or lower precedence than comparisons
-	_ = a == b
-	_ = a != b
-	_ = a > b
-	_ = a >= b
-	_ = a < b
-	_ = a <= b
-	_ = a < b && c > d
-	_ = a < b || c > d
-
-	// spaces around "long" operands
-	_ = a + longIdentifier1
-	_ = longIdentifier1 + a
-	_ = longIdentifier1 + longIdentifier2 * longIdentifier3
-	_ = s + "a longer string"
-
-	// some selected cases
-	_ = a + t0.x
-	_ = a + t0.x + t1.x * t2.x
-	_ = a + b + c + d + e + 2*3
-	_ = a + b + c + 2*3 + d + e
-	_ = (a+b+c)*2
-	_ = a - b + c - d + (a+b+c) + d&e
-	_ = under_bar-1
-	_ = Open(dpath + "/file", O_WRONLY | O_CREAT, 0666)
-	_ = int(c0&_Mask4)<<18 | int(c1&_Maskx)<<12 | int(c2&_Maskx)<<6 | int(c3&_Maskx)
-
-	// the parser does not restrict expressions that may appear as statements
-	true
-	42
-	"foo"
-	x
-	(x)
-	a+b
-	a+b+c
-	a+(b*c)
-	a+(b/c)
-	1+a
-	a+1
-	s[a]
-	x<<1
-	(s[0]<<1)&0xf
-	"foo"+s
-	x == y
-	x < y || z > 42
-}
-
-
-// slice expressions with cap
-func _() {
-	_ = x[a:b:c]
-	_ = x[a:b:c+d]
-	_ = x[a:b+d:c]
-	_ = x[a:b+d:c+d]
-	_ = x[a+d:b:c]
-	_ = x[a+d:b:c+d]
-	_ = x[a+d:b+d:c]
-	_ = x[a+d:b+d:c+d]
-
-	_ = x[:b:c]
-	_ = x[:b:c+d]
-	_ = x[:b+d:c]
-	_ = x[:b+d:c+d]
-}
-
-func _() {
-	_ = a+b
-	_ = a+b+c
-	_ = a+b*c
-	_ = a+(b*c)
-	_ = (a+b)*c
-	_ = a+(b*c*d)
-	_ = a+(b*c+d)
-
-	_ = 1<<x
-	_ = -1<<x
-	_ = 1<<x-1
-	_ = -1<<x-1
-
-	_ = f(a+b)
-	_ = f(a+b+c)
-	_ = f(a+b*c)
-	_ = f(a+(b*c))
-	_ = f(1<<x-1, 1<<x-2)
-
-	_ = 1<<d.logWindowSize-1
-
-	buf = make(x, 2*cap(b.buf) + n)
-
-	dst[i*3+2] = dbuf[0]<<2
-	dst[i*3+2] = dbuf[0]<<2 | dbuf[1]>>4
-
-	b.buf = b.buf[0:b.off+m+n]
-	b.buf = b.buf[0:b.off+m*n]
-	f(b.buf[0:b.off+m+n])
-
-	signed += ' '*8
-	tw.octal(header[148:155], chksum)
-
-	_ = x > 0 && i >= 0
-
-	x1, x0 := x>>w2, x&m2
-	z0 = t1<<w2+t0
-	z1 = (t1+t0>>w2)>>w2
-	q1, r1 := x1/d1, x1%d1
-	r1 = r1*b2 | x0>>w2
-	x1 = (x1<<z)|(x0>>(uint(w)-z))
-	x1 = x1<<z | x0>>(uint(w)-z)
-
-	_ = buf[0:len(buf)+1]
-	_ = buf[0:n+1]
-
-	a,b = b,a
-	a = b+c
-	a = b*c+d
-	_ = a*b+c
-	_ = a-b-c
-	_ = a-(b-c)
-	_ = a-b*c
-	_ = a-(b*c)
-	_ = a*b/c
-	_ = a/ *b
-	_ = x[a|^b]
-	_ = x[a/ *b]
-	_ = a& ^b
-	_ = a+ +b
-	_ = a- -b
-	_ = x[a*-b]
-	_ = x[a+ +b]
-	_ = x^y^z
-	_ = b[a>>24] ^ b[(a>>16)&0xFF] ^ b[(a>>8)&0xFF] ^ b[a&0xFF]
-	_ = len(longVariableName)*2
-
-	_ = token(matchType + xlength<<lengthShift + xoffset)
-}
-
-
-func f(x int, args ...int) {
-	f(0, args...)
-	f(1, args)
-	f(2, args[0])
-
-	// make sure syntactically legal code remains syntactically legal
-	f(3, 42 ...) // a blank must remain between 42 and ...
-	f(4, 42. ...)
-	f(5, 42....)
-	f(6, 42.0 ...)
-	f(7, 42.0...)
-	f(8, .42 ...)
-	f(9, .42...)
-	f(10, 42e0 ...)
-	f(11, 42e0...)
-
-	_ = 42 .x // a blank must remain between 42 and .x
-	_ = 42. .x
-	_ = 42..x
-	_ = 42.0 .x
-	_ = 42.0.x
-	_ = .42 .x
-	_ = .42.x
-	_ = 42e0 .x
-	_ = 42e0.x
-
-	// a blank must remain between the binary operator and the 2nd operand
-	_ = x/ *y
-	_ = x< -1
-	_ = x< <-1
-	_ = x+ +1
-	_ = x- -1
-	_ = x& &x
-	_ = x& ^x
-
-	_ = f(x/ *y, x< -1, x< <-1, x+ +1, x- -1, x& &x, x& ^x)
-}
-
-
-func _() {
-	_ = T{}
-	_ = struct{}{}
-	_ = [10]T{}
-	_ = [...]T{}
-	_ = []T{}
-	_ = map[int]T{}
-}
-
-
-// one-line structs/interfaces in composite literals (up to a threshold)
-func _() {
-	_ = struct{}{}
-	_ = struct{ x int }{0}
-	_ = struct{ x, y, z int }{0, 1, 2}
-	_ = struct{ int }{0}
-	_ = struct{ s struct { int } }{struct{ int}{0} }
-}
-
-
-func _() {
-	// do not modify literals
-	_ = "tab1	tab2	tab3	end"  // string contains 3 tabs
-	_ = "tab1 tab2 tab3 end"  // same string with 3 blanks - may be unaligned because editors see tabs in strings
-	_ = ""  // this comment should be aligned with the one on the previous line
-	_ = ``
-	_ = `
-`
-_ = `foo
-		bar`
-	_ = `three spaces before the end of the line starting here:   
-they must not be removed`
-}
-
-
-func _() {
-	// smart handling of indentation for multi-line raw strings
-	var _ = ``
-	var _ = `foo`
-	var _ = `foo
-bar`
-
-
-var _ =
-	``
-var _ =
-	`foo`
-var _ =
-	// the next line should remain indented
-	`foo
-bar`
-
-
-	var _ = // comment
-		``
-	var _ = // comment
-		`foo`
-	var _ = // comment
-		// the next line should remain indented
-		`foo
-bar`
-
-
-var _ = /* comment */ ``
-var _ = /* comment */ `foo`
-var _ = /* comment */ `foo
-bar`
-
-
-	var _ = /* comment */
-		``
-	var _ = /* comment */
-		`foo`
-	var _ = /* comment */
-		// the next line should remain indented
-		`foo
-bar`
-
-
-var board = []int(
-	`...........
-...........
-....●●●....
-....●●●....
-..●●●●●●●..
-..●●●○●●●..
-..●●●●●●●..
-....●●●....
-....●●●....
-...........
-...........
-`)
-
-
-	var state = S{
-		"foo",
-		// the next line should remain indented
-		`...........
-...........
-....●●●....
-....●●●....
-..●●●●●●●..
-..●●●○●●●..
-..●●●●●●●..
-....●●●....
-....●●●....
-...........
-...........
-`,
-		"bar",
-	}
-}
-
-
-func _() {
-	// one-line function literals (body is on a single line)
-	_ = func() {}
-	_ = func() int { return 0 }
-	_ = func(x, y int) bool { m := (x+y)/2; return m < 0 }
-
-	// multi-line function literals (body is not on one line)
-	_ = func() {
-	}
-	_ = func() int {
-		return 0
-	}
-	_ = func(x, y int) bool {
-		m := (x+y)/2; return x < y }
-
-	f(func() {
-	})
-	f(func() int {
-		return 0
-	})
-	f(func(x, y int) bool {
-		m := (x+y)/2; return x < y })
-}
-
-
-func _() {
-	_ = [][]int {
-		[]int{1},
-		[]int{1, 2},
-		[]int{1, 2, 3},
-	}
-	_ = [][]int {
-		{1},
-		[]int{1, 2},
-		[]int{1, 2, 3},
-	}
-	_ = [][]int {
-		{1},
-		{1, 2},
-		{1, 2, 3},
-	}
-	_ = [][]int {{1}, {1, 2}, {1, 2, 3}}
-}
-
-
-// various multi-line expressions
-func _() {
-	// do not add extra indentation to multi-line string lists
-	_ = "foo" + "bar"
-	_ = "foo" +
-	"bar" +
-	"bah"
-	_ = []string {
-		"abc" +
-		"def",
-		"foo" +
-		"bar",
-	}
-}
-
-
-const _ = F1 +
-	`string = "%s";` +
-	`ptr = *;` +
-	`datafmt.T2 = s ["-" p "-"];`
-
-
-const _ =
-	`datafmt "datafmt";` +
-	`default = "%v";` +
-	`array = *;` +
-	`datafmt.T3 = s  {" " a a / ","};`
-
-
-const _ = `datafmt "datafmt";` +
-`default = "%v";` +
-`array = *;` +
-`datafmt.T3 = s  {" " a a / ","};`
-
-
-func _() {
-	_ = F1 +
-		`string = "%s";` +
-		`ptr = *;` +
-		`datafmt.T2 = s ["-" p "-"];`
-
-	_ =
-		`datafmt "datafmt";` +
-		`default = "%v";` +
-		`array = *;` +
-		`datafmt.T3 = s  {" " a a / ","};`
-
-	_ = `datafmt "datafmt";` +
-	`default = "%v";` +
-	`array = *;` +
-	`datafmt.T3 = s  {" " a a / ","};`
-}
-
-
-func _() {
-	// respect source lines in multi-line expressions
-	_ = a+
-	b+
-	c
-	_ = a < b ||
-		b < a
-	_ = "933262154439441526816992388562667004907159682643816214685929" +
-	"638952175999932299156089414639761565182862536979208272237582" +
-	"51185210916864000000000000000000000000"  // 100!
-	_ = "170141183460469231731687303715884105727"  // prime
-}
-
-
-// Alignment after overlong lines
-const (
-	_ = "991"
-	_ = "2432902008176640000"  // 20!
-	_ = "933262154439441526816992388562667004907159682643816214685929" +
-	"638952175999932299156089414639761565182862536979208272237582" +
-	"51185210916864000000000000000000000000"  // 100!
-	_ = "170141183460469231731687303715884105727"  // prime
-)
-
-
-// Correct placement of operators and comments in multi-line expressions
-func _() {
-	_ = a +  // comment
-		b +  // comment
-		c
-	_ = "a"	+
-		"b" +	// comment
-		"c"
-	_ = "ba0408" + "7265717569726564"     // field 71, encoding 2, string "required"
-}
-
-
-// Correct placement of terminating comma/closing parentheses in multi-line calls.
-func _() {
-	f(1,
-		2,
-		3)
-	f(1,
-		2,
-		3,
-	)
-	f(1,
-		2,
-		3)  // comment
-	f(1,
-		2,
-		3,  // comment
-	)
-	f(1,
-		2,
-		3)// comment
-	f(1,
-		2,
-		3,// comment
-	)
-}
-
-
-// Align comments in multi-line lists of single-line expressions.
-var txpix = [NCOL]draw.Color{
-	draw.Yellow, // yellow
-	draw.Cyan, // cyan
-	draw.Green, // lime green
-	draw.GreyBlue, // slate
-	draw.Red, /* red */
-	draw.GreyGreen, /* olive green */
-	draw.Blue, /* blue */
-	draw.Color(0xFF55AAFF), /* pink */
-	draw.Color(0xFFAAFFFF), /* lavender */
-	draw.Color(0xBB005DFF), /* maroon */
-}
-
-
-func same(t, u *Time) bool {
-	// respect source lines in multi-line expressions
-	return t.Year == u.Year &&
-		t.Month == u.Month &&
-		t.Day == u.Day &&
-		t.Hour == u.Hour &&
-		t.Minute == u.Minute &&
-		t.Second == u.Second &&
-		t.Weekday == u.Weekday &&
-		t.ZoneOffset == u.ZoneOffset &&
-		t.Zone == u.Zone
-}
-
-
-func (p *parser) charClass() {
-	// respect source lines in multi-line expressions
-	if cc.negate && len(cc.ranges) == 2 &&
-		cc.ranges[0] == '\n' && cc.ranges[1] == '\n' {
-		nl := new(_NotNl)
-		p.re.add(nl)
-	}
-}
-
-
-func addState(s []state, inst instr, match []int) {
-	// handle comments correctly in multi-line expressions
-	for i := 0; i < l; i++ {
-		if s[i].inst.index() == index && // same instruction
-		   s[i].match[0] < pos {	// earlier match already going; leftmost wins
-		   	return s
-		 }
-	}
-}
-
-func (self *T) foo(x int) *T { return self }
-
-func _() { module.Func1().Func2() }
-
-func _() {
-	_ = new(T).
-		foo(1).
-			foo(2).
-		foo(3)
-
-	_ = new(T).
-	foo(1).
-	foo(2). // inline comments
-	foo(3)
-
-	_ = new(T).foo(1).foo(2).foo(3)
-
-	// handle multiline argument list correctly
-	_ = new(T).
-	foo(
-		1).
-		foo(2)
-
-	_ = new(T).foo(
-		1).foo(2)
-
-	_ = Array[3 +
-4]
-
-	_ = Method(1, 2,
-		3)
-
-	_ = new(T).
-   foo().
-   bar() . (*Type)
-
-	_ = new(T).
-foo().
-bar().(*Type).
-baz()
-
-	_ = new(T).
-	foo().
-	bar()["idx"]
-
-	_ = new(T).
-	foo().
-	bar()["idx"]	.
-	baz()
-
-	_ = new(T).
-	foo().
-	bar()[1:2]
-
-	_ = new(T).
-	foo().
-	bar()[1:2].
-	baz()
-
-	_ = new(T).
-		Field.
-		Array[3+
-       		4].
-		Table ["foo"].
-		Blob. (*Type).
-	Slices[1:4].
-	Method(1, 2,
-	3).
-		Thingy
-
-	_ = a.b.c
-	_ = a.
-	b.
-	c
-	_ = a.b().c
-	_ = a.
-	b().
-	c
-	_ = a.b[0].c
-	_ = a.
-	b[0].
-	c
-	_ = a.b[0:].c
-	_ = a.
-	b[0:].
-	c
-	_ = a.b.(T).c
-	_ = a.
-	b.
-	(T).
-	c
-}
-
-
-// Don't introduce extra newlines in strangely formatted expression lists.
-func f() {
-	// os.Open parameters should remain on two lines
-	if writer, err = os.Open(outfile, s.O_WRONLY|os.O_CREATE|
-		os.O_TRUNC, 0666); err != nil {
-	    log.Fatal(err)
-	}
-}
-
-// Handle multi-line argument lists ending in ... correctly.
-// Was issue 3130.
-func _() {
-	_ = append(s, a...)
-	_ = append(
-		s, a...)
-	_ = append(s,
-		a...)
-	_ = append(
-		s,
-		a...)
-	_ = append(s, a...,
-	)
-	_ = append(s,
-		a...,
-	)
-	_ = append(
-		s,
-		a...,
-	)
-}
-
-// Literal function types in conversions must be parenthesized;
-// for now go/parser accepts the unparenthesized form where it
-// is non-ambiguous.
-func _() {
-	// these conversions should be rewritten to look
-	// the same as the parenthesized conversions below
-	_ = func()()(nil)
-	_ = func(x int)(float)(nil)
-	_ = func() func() func()()(nil)
-
-	_ = (func()())(nil)
-	_ = (func(x int)(float))(nil)
-	_ = (func() func() func()())(nil)
-}
diff --git a/src/pkg/go/printer/testdata/expressions.raw b/src/pkg/go/printer/testdata/expressions.raw
deleted file mode 100644
index 97bc81d..0000000
--- a/src/pkg/go/printer/testdata/expressions.raw
+++ /dev/null
@@ -1,681 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package expressions
-
-type T struct {
-	x, y, z int
-}
-
-var (
-	a, b, c, d, e	int
-	under_bar	int
-	longIdentifier1, longIdentifier2, longIdentifier3	int
-	t0, t1, t2	T
-	s	string
-	p	*int
-)
-
-func _() {
-	// no spaces around simple or parenthesized expressions
-	_ = (a + 0)
-	_ = a + b
-	_ = a + b + c
-	_ = a + b - c
-	_ = a - b - c
-	_ = a + (b * c)
-	_ = a + (b / c)
-	_ = a - (b % c)
-	_ = 1 + a
-	_ = a + 1
-	_ = a + b + 1
-	_ = s[a]
-	_ = s[a:]
-	_ = s[:b]
-	_ = s[1:2]
-	_ = s[a:b]
-	_ = s[0:len(s)]
-	_ = s[0] << 1
-	_ = (s[0] << 1) & 0xf
-	_ = s[0]<<2 | s[1]>>4
-	_ = "foo" + s
-	_ = s + "foo"
-	_ = 'a' + 'b'
-	_ = len(s) / 2
-	_ = len(t0.x) / a
-
-	// spaces around expressions of different precedence or expressions containing spaces
-	_ = a + -b
-	_ = a - ^b
-	_ = a / *p
-	_ = a + b*c
-	_ = 1 + b*c
-	_ = a + 2*c
-	_ = a + c*2
-	_ = 1 + 2*3
-	_ = s[1 : 2*3]
-	_ = s[a : b-c]
-	_ = s[0:]
-	_ = s[a+b]
-	_ = s[:b-c]
-	_ = s[a+b:]
-	_ = a[a<<b+1]
-	_ = a[a<<b+1:]
-	_ = s[a+b : len(s)]
-	_ = s[len(s):-a]
-	_ = s[a : len(s)+1]
-	_ = s[a:len(s)+1] + s
-
-	// spaces around operators with equal or lower precedence than comparisons
-	_ = a == b
-	_ = a != b
-	_ = a > b
-	_ = a >= b
-	_ = a < b
-	_ = a <= b
-	_ = a < b && c > d
-	_ = a < b || c > d
-
-	// spaces around "long" operands
-	_ = a + longIdentifier1
-	_ = longIdentifier1 + a
-	_ = longIdentifier1 + longIdentifier2*longIdentifier3
-	_ = s + "a longer string"
-
-	// some selected cases
-	_ = a + t0.x
-	_ = a + t0.x + t1.x*t2.x
-	_ = a + b + c + d + e + 2*3
-	_ = a + b + c + 2*3 + d + e
-	_ = (a + b + c) * 2
-	_ = a - b + c - d + (a + b + c) + d&e
-	_ = under_bar - 1
-	_ = Open(dpath+"/file", O_WRONLY|O_CREAT, 0666)
-	_ = int(c0&_Mask4)<<18 | int(c1&_Maskx)<<12 | int(c2&_Maskx)<<6 | int(c3&_Maskx)
-
-	// the parser does not restrict expressions that may appear as statements
-	true
-	42
-	"foo"
-	x
-	(x)
-	a + b
-	a + b + c
-	a + (b * c)
-	a + (b / c)
-	1 + a
-	a + 1
-	s[a]
-	x << 1
-	(s[0] << 1) & 0xf
-	"foo" + s
-	x == y
-	x < y || z > 42
-}
-
-// slice expressions with cap
-func _() {
-	_ = x[a:b:c]
-	_ = x[a:b : c+d]
-	_ = x[a : b+d : c]
-	_ = x[a : b+d : c+d]
-	_ = x[a+d : b:c]
-	_ = x[a+d : b : c+d]
-	_ = x[a+d : b+d : c]
-	_ = x[a+d : b+d : c+d]
-
-	_ = x[:b:c]
-	_ = x[:b : c+d]
-	_ = x[:b+d : c]
-	_ = x[:b+d : c+d]
-}
-
-func _() {
-	_ = a + b
-	_ = a + b + c
-	_ = a + b*c
-	_ = a + (b * c)
-	_ = (a + b) * c
-	_ = a + (b * c * d)
-	_ = a + (b*c + d)
-
-	_ = 1 << x
-	_ = -1 << x
-	_ = 1<<x - 1
-	_ = -1<<x - 1
-
-	_ = f(a + b)
-	_ = f(a + b + c)
-	_ = f(a + b*c)
-	_ = f(a + (b * c))
-	_ = f(1<<x-1, 1<<x-2)
-
-	_ = 1<<d.logWindowSize - 1
-
-	buf = make(x, 2*cap(b.buf)+n)
-
-	dst[i*3+2] = dbuf[0] << 2
-	dst[i*3+2] = dbuf[0]<<2 | dbuf[1]>>4
-
-	b.buf = b.buf[0 : b.off+m+n]
-	b.buf = b.buf[0 : b.off+m*n]
-	f(b.buf[0 : b.off+m+n])
-
-	signed += ' ' * 8
-	tw.octal(header[148:155], chksum)
-
-	_ = x > 0 && i >= 0
-
-	x1, x0 := x>>w2, x&m2
-	z0 = t1<<w2 + t0
-	z1 = (t1 + t0>>w2) >> w2
-	q1, r1 := x1/d1, x1%d1
-	r1 = r1*b2 | x0>>w2
-	x1 = (x1 << z) | (x0 >> (uint(w) - z))
-	x1 = x1<<z | x0>>(uint(w)-z)
-
-	_ = buf[0 : len(buf)+1]
-	_ = buf[0 : n+1]
-
-	a, b = b, a
-	a = b + c
-	a = b*c + d
-	_ = a*b + c
-	_ = a - b - c
-	_ = a - (b - c)
-	_ = a - b*c
-	_ = a - (b * c)
-	_ = a * b / c
-	_ = a / *b
-	_ = x[a|^b]
-	_ = x[a / *b]
-	_ = a & ^b
-	_ = a + +b
-	_ = a - -b
-	_ = x[a*-b]
-	_ = x[a + +b]
-	_ = x ^ y ^ z
-	_ = b[a>>24] ^ b[(a>>16)&0xFF] ^ b[(a>>8)&0xFF] ^ b[a&0xFF]
-	_ = len(longVariableName) * 2
-
-	_ = token(matchType + xlength<<lengthShift + xoffset)
-}
-
-func f(x int, args ...int) {
-	f(0, args...)
-	f(1, args)
-	f(2, args[0])
-
-	// make sure syntactically legal code remains syntactically legal
-	f(3, 42 ...)	// a blank must remain between 42 and ...
-	f(4, 42....)
-	f(5, 42....)
-	f(6, 42.0...)
-	f(7, 42.0...)
-	f(8, .42...)
-	f(9, .42...)
-	f(10, 42e0...)
-	f(11, 42e0...)
-
-	_ = 42 .x	// a blank must remain between 42 and .x
-	_ = 42..x
-	_ = 42..x
-	_ = 42.0.x
-	_ = 42.0.x
-	_ = .42.x
-	_ = .42.x
-	_ = 42e0.x
-	_ = 42e0.x
-
-	// a blank must remain between the binary operator and the 2nd operand
-	_ = x / *y
-	_ = x < -1
-	_ = x < <-1
-	_ = x + +1
-	_ = x - -1
-	_ = x & &x
-	_ = x & ^x
-
-	_ = f(x / *y, x < -1, x < <-1, x + +1, x - -1, x & &x, x & ^x)
-}
-
-func _() {
-	_ = T{}
-	_ = struct{}{}
-	_ = [10]T{}
-	_ = [...]T{}
-	_ = []T{}
-	_ = map[int]T{}
-}
-
-// one-line structs/interfaces in composite literals (up to a threshold)
-func _() {
-	_ = struct{}{}
-	_ = struct{ x int }{0}
-	_ = struct{ x, y, z int }{0, 1, 2}
-	_ = struct{ int }{0}
-	_ = struct{ s struct{ int } }{struct{ int }{0}}
-}
-
-func _() {
-	// do not modify literals
-	_ = "tab1	tab2	tab3	end"	// string contains 3 tabs
-	_ = "tab1 tab2 tab3 end"	// same string with 3 blanks - may be unaligned because editors see tabs in strings
-	_ = ""	// this comment should be aligned with the one on the previous line
-	_ = ``
-	_ = `
-`
-	_ = `foo
-		bar`
-	_ = `three spaces before the end of the line starting here:   
-they must not be removed`
-}
-
-func _() {
-	// smart handling of indentation for multi-line raw strings
-	var _ = ``
-	var _ = `foo`
-	var _ = `foo
-bar`
-
-	var _ = ``
-	var _ = `foo`
-	var _ =
-	// the next line should remain indented
-	`foo
-bar`
-
-	var _ =	// comment
-	``
-	var _ =	// comment
-	`foo`
-	var _ =	// comment
-	// the next line should remain indented
-	`foo
-bar`
-
-	var _ = /* comment */ ``
-	var _ = /* comment */ `foo`
-	var _ = /* comment */ `foo
-bar`
-
-	var _ =	/* comment */
-	``
-	var _ =	/* comment */
-	`foo`
-	var _ =	/* comment */
-	// the next line should remain indented
-	`foo
-bar`
-
-	var board = []int(
-		`...........
-...........
-....●●●....
-....●●●....
-..●●●●●●●..
-..●●●○●●●..
-..●●●●●●●..
-....●●●....
-....●●●....
-...........
-...........
-`)
-
-	var state = S{
-		"foo",
-		// the next line should remain indented
-		`...........
-...........
-....●●●....
-....●●●....
-..●●●●●●●..
-..●●●○●●●..
-..●●●●●●●..
-....●●●....
-....●●●....
-...........
-...........
-`,
-		"bar",
-	}
-}
-
-func _() {
-	// one-line function literals (body is on a single line)
-	_ = func() {}
-	_ = func() int { return 0 }
-	_ = func(x, y int) bool { m := (x + y) / 2; return m < 0 }
-
-	// multi-line function literals (body is not on one line)
-	_ = func() {
-	}
-	_ = func() int {
-		return 0
-	}
-	_ = func(x, y int) bool {
-		m := (x + y) / 2
-		return x < y
-	}
-
-	f(func() {
-	})
-	f(func() int {
-		return 0
-	})
-	f(func(x, y int) bool {
-		m := (x + y) / 2
-		return x < y
-	})
-}
-
-func _() {
-	_ = [][]int{
-		[]int{1},
-		[]int{1, 2},
-		[]int{1, 2, 3},
-	}
-	_ = [][]int{
-		{1},
-		[]int{1, 2},
-		[]int{1, 2, 3},
-	}
-	_ = [][]int{
-		{1},
-		{1, 2},
-		{1, 2, 3},
-	}
-	_ = [][]int{{1}, {1, 2}, {1, 2, 3}}
-}
-
-// various multi-line expressions
-func _() {
-	// do not add extra indentation to multi-line string lists
-	_ = "foo" + "bar"
-	_ = "foo" +
-		"bar" +
-		"bah"
-	_ = []string{
-		"abc" +
-			"def",
-		"foo" +
-			"bar",
-	}
-}
-
-const _ = F1 +
-	`string = "%s";` +
-	`ptr = *;` +
-	`datafmt.T2 = s ["-" p "-"];`
-
-const _ = `datafmt "datafmt";` +
-	`default = "%v";` +
-	`array = *;` +
-	`datafmt.T3 = s  {" " a a / ","};`
-
-const _ = `datafmt "datafmt";` +
-	`default = "%v";` +
-	`array = *;` +
-	`datafmt.T3 = s  {" " a a / ","};`
-
-func _() {
-	_ = F1 +
-		`string = "%s";` +
-		`ptr = *;` +
-		`datafmt.T2 = s ["-" p "-"];`
-
-	_ =
-		`datafmt "datafmt";` +
-			`default = "%v";` +
-			`array = *;` +
-			`datafmt.T3 = s  {" " a a / ","};`
-
-	_ = `datafmt "datafmt";` +
-		`default = "%v";` +
-		`array = *;` +
-		`datafmt.T3 = s  {" " a a / ","};`
-}
-
-func _() {
-	// respect source lines in multi-line expressions
-	_ = a +
-		b +
-		c
-	_ = a < b ||
-		b < a
-	_ = "933262154439441526816992388562667004907159682643816214685929" +
-		"638952175999932299156089414639761565182862536979208272237582" +
-		"51185210916864000000000000000000000000"	// 100!
-	_ = "170141183460469231731687303715884105727"	// prime
-}
-
-// Alignment after overlong lines
-const (
-	_	= "991"
-	_	= "2432902008176640000"		// 20!
-	_	= "933262154439441526816992388562667004907159682643816214685929" +
-		"638952175999932299156089414639761565182862536979208272237582" +
-		"51185210916864000000000000000000000000"	// 100!
-	_	= "170141183460469231731687303715884105727"		// prime
-)
-
-// Correct placement of operators and comments in multi-line expressions
-func _() {
-	_ = a +	// comment
-		b +	// comment
-		c
-	_ = "a" +
-		"b" +	// comment
-		"c"
-	_ = "ba0408" + "7265717569726564"	// field 71, encoding 2, string "required"
-}
-
-// Correct placement of terminating comma/closing parentheses in multi-line calls.
-func _() {
-	f(1,
-		2,
-		3)
-	f(1,
-		2,
-		3,
-	)
-	f(1,
-		2,
-		3)	// comment
-	f(1,
-		2,
-		3,	// comment
-	)
-	f(1,
-		2,
-		3)	// comment
-	f(1,
-		2,
-		3,	// comment
-	)
-}
-
-// Align comments in multi-line lists of single-line expressions.
-var txpix = [NCOL]draw.Color{
-	draw.Yellow,	// yellow
-	draw.Cyan,	// cyan
-	draw.Green,	// lime green
-	draw.GreyBlue,	// slate
-	draw.Red,	/* red */
-	draw.GreyGreen,	/* olive green */
-	draw.Blue,	/* blue */
-	draw.Color(0xFF55AAFF),	/* pink */
-	draw.Color(0xFFAAFFFF),	/* lavender */
-	draw.Color(0xBB005DFF),	/* maroon */
-}
-
-func same(t, u *Time) bool {
-	// respect source lines in multi-line expressions
-	return t.Year == u.Year &&
-		t.Month == u.Month &&
-		t.Day == u.Day &&
-		t.Hour == u.Hour &&
-		t.Minute == u.Minute &&
-		t.Second == u.Second &&
-		t.Weekday == u.Weekday &&
-		t.ZoneOffset == u.ZoneOffset &&
-		t.Zone == u.Zone
-}
-
-func (p *parser) charClass() {
-	// respect source lines in multi-line expressions
-	if cc.negate && len(cc.ranges) == 2 &&
-		cc.ranges[0] == '\n' && cc.ranges[1] == '\n' {
-		nl := new(_NotNl)
-		p.re.add(nl)
-	}
-}
-
-func addState(s []state, inst instr, match []int) {
-	// handle comments correctly in multi-line expressions
-	for i := 0; i < l; i++ {
-		if s[i].inst.index() == index &&	// same instruction
-			s[i].match[0] < pos {	// earlier match already going; leftmost wins
-			return s
-		}
-	}
-}
-
-func (self *T) foo(x int) *T	{ return self }
-
-func _()	{ module.Func1().Func2() }
-
-func _() {
-	_ = new(T).
-		foo(1).
-		foo(2).
-		foo(3)
-
-	_ = new(T).
-		foo(1).
-		foo(2).	// inline comments
-		foo(3)
-
-	_ = new(T).foo(1).foo(2).foo(3)
-
-	// handle multiline argument list correctly
-	_ = new(T).
-		foo(
-		1).
-		foo(2)
-
-	_ = new(T).foo(
-		1).foo(2)
-
-	_ = Array[3+
-		4]
-
-	_ = Method(1, 2,
-		3)
-
-	_ = new(T).
-		foo().
-		bar().(*Type)
-
-	_ = new(T).
-		foo().
-		bar().(*Type).
-		baz()
-
-	_ = new(T).
-		foo().
-		bar()["idx"]
-
-	_ = new(T).
-		foo().
-		bar()["idx"].
-		baz()
-
-	_ = new(T).
-		foo().
-		bar()[1:2]
-
-	_ = new(T).
-		foo().
-		bar()[1:2].
-		baz()
-
-	_ = new(T).
-		Field.
-		Array[3+
-		4].
-		Table["foo"].
-		Blob.(*Type).
-		Slices[1:4].
-		Method(1, 2,
-		3).
-		Thingy
-
-	_ = a.b.c
-	_ = a.
-		b.
-		c
-	_ = a.b().c
-	_ = a.
-		b().
-		c
-	_ = a.b[0].c
-	_ = a.
-		b[0].
-		c
-	_ = a.b[0:].c
-	_ = a.
-		b[0:].
-		c
-	_ = a.b.(T).c
-	_ = a.
-		b.(T).
-		c
-}
-
-// Don't introduce extra newlines in strangely formatted expression lists.
-func f() {
-	// os.Open parameters should remain on two lines
-	if writer, err = os.Open(outfile, s.O_WRONLY|os.O_CREATE|
-		os.O_TRUNC, 0666); err != nil {
-		log.Fatal(err)
-	}
-}
-
-// Handle multi-line argument lists ending in ... correctly.
-// Was issue 3130.
-func _() {
-	_ = append(s, a...)
-	_ = append(
-		s, a...)
-	_ = append(s,
-		a...)
-	_ = append(
-		s,
-		a...)
-	_ = append(s, a...,
-	)
-	_ = append(s,
-		a...,
-	)
-	_ = append(
-		s,
-		a...,
-	)
-}
-
-// Literal function types in conversions must be parenthesized;
-// for now go/parser accepts the unparenthesized form where it
-// is non-ambiguous.
-func _() {
-	// these conversions should be rewritten to look
-	// the same as the parenthesized conversions below
-	_ = (func())(nil)
-	_ = (func(x int) float)(nil)
-	_ = (func() func() func())(nil)
-
-	_ = (func())(nil)
-	_ = (func(x int) float)(nil)
-	_ = (func() func() func())(nil)
-}
diff --git a/src/pkg/go/printer/testdata/statements.golden b/src/pkg/go/printer/testdata/statements.golden
deleted file mode 100644
index 3b298f9..0000000
--- a/src/pkg/go/printer/testdata/statements.golden
+++ /dev/null
@@ -1,635 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package statements
-
-var expr bool
-
-func use(x interface{})	{}
-
-// Formatting of multi-line return statements.
-func _f() {
-	return
-	return x, y, z
-	return T{}
-	return T{1, 2, 3},
-		x, y, z
-	return T{1, 2, 3},
-		x, y,
-		z
-	return T{1,
-		2,
-		3}
-	return T{1,
-		2,
-		3,
-	}
-	return T{
-		1,
-		2,
-		3}
-	return T{
-		1,
-		2,
-		3,
-	}
-	return T{
-		1,
-		T{1, 2, 3},
-		3,
-	}
-	return T{
-		1,
-		T{1,
-			2, 3},
-		3,
-	}
-	return T{
-		1,
-		T{1,
-			2,
-			3},
-		3,
-	}
-	return T{
-		1,
-		2,
-	}, nil
-	return T{
-			1,
-			2,
-		},
-		T{
-			x:	3,
-			y:	4,
-		}, nil
-	return T{
-			1,
-			2,
-		},
-		nil
-	return T{
-			1,
-			2,
-		},
-		T{
-			x:	3,
-			y:	4,
-		},
-		nil
-	return x + y +
-		z
-	return func() {}
-	return func() {
-			_ = 0
-		}, T{
-			1, 2,
-		}
-	return func() {
-		_ = 0
-	}
-	return func() T {
-		return T{
-			1, 2,
-		}
-	}
-}
-
-// Formatting of multi-line returns: test cases from issue 1207.
-func F() (*T, os.Error) {
-	return &T{
-			X:	1,
-			Y:	2,
-		},
-		nil
-}
-
-func G() (*T, *T, os.Error) {
-	return &T{
-			X:	1,
-			Y:	2,
-		},
-		&T{
-			X:	3,
-			Y:	4,
-		},
-		nil
-}
-
-func _() interface{} {
-	return &fileStat{
-		name:		basename(file.name),
-		size:		mkSize(d.FileSizeHigh, d.FileSizeLow),
-		modTime:	mkModTime(d.LastWriteTime),
-		mode:		mkMode(d.FileAttributes),
-		sys:		mkSysFromFI(&d),
-	}, nil
-}
-
-// Formatting of if-statement headers.
-func _() {
-	if true {
-	}
-	if true {
-	}	// no semicolon printed
-	if expr {
-	}
-	if expr {
-	}	// no semicolon printed
-	if expr {
-	}	// no parens printed
-	if expr {
-	}	// no semicolon and parens printed
-	if x := expr; true {
-		use(x)
-	}
-	if x := expr; expr {
-		use(x)
-	}
-}
-
-// Formatting of switch-statement headers.
-func _() {
-	switch {
-	}
-	switch {
-	}	// no semicolon printed
-	switch expr {
-	}
-	switch expr {
-	}	// no semicolon printed
-	switch expr {
-	}	// no parens printed
-	switch expr {
-	}	// no semicolon and parens printed
-	switch x := expr; {
-	default:
-		use(
-			x)
-	}
-	switch x := expr; expr {
-	default:
-		use(x)
-	}
-}
-
-// Formatting of switch statement bodies.
-func _() {
-	switch {
-	}
-
-	switch x := 0; x {
-	case 1:
-		use(x)
-		use(x)	// followed by an empty line
-
-	case 2:	// followed by an empty line
-
-		use(x)	// followed by an empty line
-
-	case 3:	// no empty lines
-		use(x)
-		use(x)
-	}
-
-	switch x {
-	case 0:
-		use(x)
-	case 1:	// this comment should have no effect on the previous or next line
-		use(x)
-	}
-
-	switch x := 0; x {
-	case 1:
-		x = 0
-		// this comment should be indented
-	case 2:
-		x = 0
-	// this comment should not be indented, it is aligned with the next case
-	case 3:
-		x = 0
-		/* indented comment
-		   aligned
-		   aligned
-		*/
-		// bla
-		/* and more */
-	case 4:
-		x = 0
-	/* not indented comment
-	   aligned
-	   aligned
-	*/
-	// bla
-	/* and more */
-	case 5:
-	}
-}
-
-// Formatting of selected select statements.
-func _() {
-	select {}
-	select { /* this comment should not be tab-aligned because the closing } is on the same line */
-	}
-	select {	/* this comment should be tab-aligned */
-	}
-	select {	// this comment should be tab-aligned
-	}
-	select {
-	case <-c:
-	}
-}
-
-// Formatting of for-statement headers for single-line for-loops.
-func _() {
-	for {
-	}
-	for expr {
-	}
-	for expr {
-	}	// no parens printed
-	for {
-	}	// no semicolons printed
-	for x := expr; ; {
-		use(x)
-	}
-	for expr {
-	}	// no semicolons printed
-	for expr {
-	}	// no semicolons and parens printed
-	for ; ; expr = false {
-	}
-	for x := expr; expr; {
-		use(x)
-	}
-	for x := expr; ; expr = false {
-		use(x)
-	}
-	for ; expr; expr = false {
-	}
-	for x := expr; expr; expr = false {
-		use(x)
-	}
-	for x := range []int{} {
-		use(x)
-	}
-	for x := range []int{} {
-		use(x)
-	}	// no parens printed
-}
-
-// Formatting of for-statement headers for multi-line for-loops.
-func _() {
-	for {
-	}
-	for expr {
-	}
-	for expr {
-	}	// no parens printed
-	for {
-	}	// no semicolons printed
-	for x := expr; ; {
-		use(x)
-	}
-	for expr {
-	}	// no semicolons printed
-	for expr {
-	}	// no semicolons and parens printed
-	for ; ; expr = false {
-	}
-	for x := expr; expr; {
-		use(x)
-	}
-	for x := expr; ; expr = false {
-		use(x)
-	}
-	for ; expr; expr = false {
-	}
-	for x := expr; expr; expr = false {
-		use(x)
-	}
-	for x := range []int{} {
-		use(x)
-	}
-	for x := range []int{} {
-		use(x)
-	}	// no parens printed
-}
-
-// Formatting of selected short single- and multi-line statements.
-func _() {
-	if cond {
-	}
-	if cond {
-	}	// multiple lines
-	if cond {
-	} else {
-	}	// else clause always requires multiple lines
-
-	for {
-	}
-	for i := 0; i < len(a); 1++ {
-	}
-	for i := 0; i < len(a); 1++ {
-		a[i] = i
-	}
-	for i := 0; i < len(a); 1++ {
-		a[i] = i
-	}	// multiple lines
-
-	for i := range a {
-	}
-	for i := range a {
-		a[i] = i
-	}
-	for i := range a {
-		a[i] = i
-	}	// multiple lines
-
-	go func() {
-		for {
-			a <- <-b
-		}
-	}()
-	defer func() {
-		if x := recover(); x != nil {
-			err = fmt.Sprintf("error: %s", x.msg)
-		}
-	}()
-}
-
-// Don't remove mandatory parentheses around composite literals in control clauses.
-func _() {
-	// strip parentheses - no composite literals or composite literals don't start with a type name
-	if x {
-	}
-	if x {
-	}
-	if []T{} {
-	}
-	if []T{} {
-	}
-	if []T{} {
-	}
-
-	for x {
-	}
-	for x {
-	}
-	for []T{} {
-	}
-	for []T{} {
-	}
-	for []T{} {
-	}
-
-	switch x {
-	}
-	switch x {
-	}
-	switch []T{} {
-	}
-	switch []T{} {
-	}
-
-	for _ = range []T{T{42}} {
-	}
-
-	// leave parentheses - composite literals start with a type name
-	if (T{}) {
-	}
-	if (T{}) {
-	}
-	if (T{}) {
-	}
-
-	for (T{}) {
-	}
-	for (T{}) {
-	}
-	for (T{}) {
-	}
-
-	switch (T{}) {
-	}
-	switch (T{}) {
-	}
-
-	for _ = range (T1{T{42}}) {
-	}
-
-	if x == (T{42}[0]) {
-	}
-	if (x == T{42}[0]) {
-	}
-	if x == (T{42}[0]) {
-	}
-	if x == (T{42}[0]) {
-	}
-	if x == (T{42}[0]) {
-	}
-	if x == a+b*(T{42}[0]) {
-	}
-	if (x == a+b*T{42}[0]) {
-	}
-	if x == a+b*(T{42}[0]) {
-	}
-	if x == a+(b * (T{42}[0])) {
-	}
-	if x == a+b*(T{42}[0]) {
-	}
-	if (a + b*(T{42}[0])) == x {
-	}
-	if (a + b*(T{42}[0])) == x {
-	}
-
-	if struct{ x bool }{false}.x {
-	}
-	if (struct{ x bool }{false}.x) == false {
-	}
-	if struct{ x bool }{false}.x == false {
-	}
-}
-
-// Extra empty lines inside functions. Do respect source code line
-// breaks between statement boundaries but print at most one empty
-// line at a time.
-func _() {
-
-	const _ = 0
-
-	const _ = 1
-	type _ int
-	type _ float
-
-	var _ = 0
-	var x = 1
-
-	// Each use(x) call below should have at most one empty line before and after.
-	// Known bug: The first use call may have more than one empty line before
-	//            (see go/printer/nodes.go, func linebreak).
-
-	use(x)
-
-	if x < x {
-
-		use(x)
-
-	} else {
-
-		use(x)
-
-	}
-}
-
-// Formatting around labels.
-func _() {
-L:
-}
-
-func _() {
-	// this comment should be indented
-L:	// no semicolon needed
-}
-
-func _() {
-	switch 0 {
-	case 0:
-	L0:
-		;	// semicolon required
-	case 1:
-	L1:
-		;	// semicolon required
-	default:
-	L2:	// no semicolon needed
-	}
-}
-
-func _() {
-	f()
-L1:
-	f()
-L2:
-	;
-L3:
-}
-
-func _() {
-	// this comment should be indented
-L:
-}
-
-func _() {
-L:
-	_ = 0
-}
-
-func _() {
-	// this comment should be indented
-L:
-	_ = 0
-}
-
-func _() {
-	for {
-	L1:
-		_ = 0
-	L2:
-		_ = 0
-	}
-}
-
-func _() {
-	// this comment should be indented
-	for {
-	L1:
-		_ = 0
-	L2:
-		_ = 0
-	}
-}
-
-func _() {
-	if true {
-		_ = 0
-	}
-	_ = 0	// the indentation here should not be affected by the long label name
-AnOverlongLabel:
-	_ = 0
-
-	if true {
-		_ = 0
-	}
-	_ = 0
-
-L:
-	_ = 0
-}
-
-func _() {
-	for {
-		goto L
-	}
-L:
-
-	MoreCode()
-}
-
-func _() {
-	for {
-		goto L
-	}
-L:	// A comment on the same line as the label, followed by a single empty line.
-	// Known bug: There may be more than one empty line before MoreCode()
-	//            (see go/printer/nodes.go, func linebreak).
-
-	MoreCode()
-}
-
-func _() {
-	for {
-		goto L
-	}
-L:
-
-	// There should be a single empty line before this comment.
-	MoreCode()
-}
-
-func _() {
-	for {
-		goto AVeryLongLabelThatShouldNotAffectFormatting
-	}
-AVeryLongLabelThatShouldNotAffectFormatting:
-	// There should be a single empty line after this comment.
-
-	// There should be a single empty line before this comment.
-	MoreCode()
-}
-
-// Formatting of empty statements.
-func _() {
-
-}
-
-func _() {
-}
-
-func _() {
-}
-
-func _() {
-	f()
-}
-
-func _() {
-L:
-	;
-}
-
-func _() {
-L:
-	;
-	f()
-}
diff --git a/src/pkg/go/printer/testdata/statements.input b/src/pkg/go/printer/testdata/statements.input
deleted file mode 100644
index e7fcc0e..0000000
--- a/src/pkg/go/printer/testdata/statements.input
+++ /dev/null
@@ -1,550 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package statements
-
-var expr bool
-
-func use(x interface{}) {}
-
-// Formatting of multi-line return statements.
-func _f() {
-	return
-	return x, y, z
-	return T{}
-	return T{1, 2, 3},
-		x, y, z
-	return T{1, 2, 3},
-		x, y,
-		z
-	return T{1,
-		2,
-		3}
-	return T{1,
-		2,
-		3,
-	}
-	return T{
-		1,
-		2,
-		3}
-	return T{
-		1,
-		2,
-		3,
-	}
-	return T{
-		1,
-		T{1, 2, 3},
-		3,
-	}
-	return T{
-		1,
-		T{1,
-			2, 3},
-		3,
-	}
-	return T{
-		1,
-		T{1,
-			2,
-			3},
-		3,
-	}
-	return T{
-			1,
-			2,
-		}, nil
-	return T{
-			1,
-			2,
-		},
-		T{
-			x: 3,
-			y: 4,
-		}, nil
-	return T{
-			1,
-			2,
-		},
-		nil
-	return T{
-			1,
-			2,
-		},
-		T{
-			x: 3,
-			y: 4,
-		},
-		nil
-	return x + y +
-		z
-	return func() {}
-	return func() {
-		_ = 0
-	}, T{
-		1, 2,
-	}
-	return func() {
-		_ = 0
-	}
-	return func() T {
-		return T {
-			1, 2,
-		}
-	}
-}
-
-// Formatting of multi-line returns: test cases from issue 1207.
-func F() (*T, os.Error) {
-       return &T{
-               X: 1,
-               Y: 2,
-       },
-               nil
-}
-
-func G() (*T, *T, os.Error) {
-       return &T{
-               X: 1,
-               Y: 2,
-       },
-               &T{
-                       X: 3,
-                       Y: 4,
-               },
-               nil
-}
-
-func _() interface{} {
-	return &fileStat{
-			name:    basename(file.name),
-			size:    mkSize(d.FileSizeHigh, d.FileSizeLow),
-			modTime: mkModTime(d.LastWriteTime),
-			mode:    mkMode(d.FileAttributes),
-			sys:     mkSysFromFI(&d),
-		}, nil
-}
-
-// Formatting of if-statement headers.
-func _() {
-	if true {}
-	if; true {}  // no semicolon printed
-	if expr{}
-	if;expr{}  // no semicolon printed
-	if (expr){}  // no parens printed
-	if;((expr)){}  // no semicolon and parens printed
-	if x:=expr;true{
-	use(x)}
-	if x:=expr; expr {use(x)}
-}
-
-
-// Formatting of switch-statement headers.
-func _() {
-	switch {}
-	switch;{}  // no semicolon printed
-	switch expr {}
-	switch;expr{}  // no semicolon printed
-	switch (expr) {}  // no parens printed
-	switch;((expr)){}  // no semicolon and parens printed
-	switch x := expr; { default:use(
-x)
-	}
-	switch x := expr; expr {default:use(x)}
-}
-
-
-// Formatting of switch statement bodies.
-func _() {
-	switch {
-	}
-
-	switch x := 0; x {
-	case 1:
-		use(x)
-		use(x)  // followed by an empty line
-
-	case 2:  // followed by an empty line
-
-		use(x)  // followed by an empty line
-
-	case 3:  // no empty lines
-		use(x)
-		use(x)
-	}
-
-	switch x {
-	case 0:
-		use(x)
-	case 1:  // this comment should have no effect on the previous or next line
-		use(x)
-	}
-
-	switch x := 0; x {
-	case 1:
-		x = 0
-		// this comment should be indented
-	case 2:
-		x = 0
-	// this comment should not be indented, it is aligned with the next case
-	case 3:
-		x = 0
-		/* indented comment
-		   aligned
-		   aligned
-		*/
-		// bla
-		/* and more */
-	case 4:
-		x = 0
-	/* not indented comment
-	   aligned
-	   aligned
-	*/
-	// bla
-	/* and more */
-	case 5:
-	}
-}
-
-
-// Formatting of selected select statements.
-func _() {
-	select {
-	}
-	select { /* this comment should not be tab-aligned because the closing } is on the same line */ }
-	select { /* this comment should be tab-aligned */
-	}
-	select { // this comment should be tab-aligned
-	}
-	select { case <-c: }
-}
-
-
-// Formatting of for-statement headers for single-line for-loops.
-func _() {
-	for{}
-	for expr {}
-	for (expr) {}  // no parens printed
-	for;;{}  // no semicolons printed
-	for x :=expr;; {use( x)}
-	for; expr;{}  // no semicolons printed
-	for; ((expr));{}  // no semicolons and parens printed
-	for; ; expr = false {}
-	for x :=expr; expr; {use(x)}
-	for x := expr;; expr=false {use(x)}
-	for;expr;expr =false {}
-	for x := expr;expr;expr = false { use(x) }
-	for x := range []int{} { use(x) }
-	for x := range (([]int{})) { use(x) }  // no parens printed
-}
-
-
-// Formatting of for-statement headers for multi-line for-loops.
-func _() {
-	for{
-	}
-	for expr {
-	}
-	for (expr) {
-	}  // no parens printed
-	for;;{
-	}  // no semicolons printed
-	for x :=expr;; {use( x)
-	}
-	for; expr;{
-	}  // no semicolons printed
-	for; ((expr));{
-	}  // no semicolons and parens printed
-	for; ; expr = false {
-	}
-	for x :=expr; expr; {use(x)
-	}
-	for x := expr;; expr=false {use(x)
-	}
-	for;expr;expr =false {
-	}
-	for x := expr;expr;expr = false {
-	use(x)
-	}
-	for x := range []int{} {
-	use(x) }
-	for x := range (([]int{})) {
-	use(x) }  // no parens printed
-}
-
-
-// Formatting of selected short single- and multi-line statements.
-func _() {
-	if cond {}
-	if cond {
-	} // multiple lines
-	if cond {} else {} // else clause always requires multiple lines
-
-	for {}
-	for i := 0; i < len(a); 1++ {}
-	for i := 0; i < len(a); 1++ { a[i] = i }
-	for i := 0; i < len(a); 1++ { a[i] = i
-	} // multiple lines
-
-	for i := range a {}
-	for i := range a { a[i] = i }
-	for i := range a { a[i] = i
-	} // multiple lines
-
-	go func() { for { a <- <-b } }()
-	defer func() { if x := recover(); x != nil { err = fmt.Sprintf("error: %s", x.msg) } }()
-}
-
-
-// Don't remove mandatory parentheses around composite literals in control clauses.
-func _() {
-	// strip parentheses - no composite literals or composite literals don't start with a type name
-	if (x) {}
-	if (((x))) {}
-	if ([]T{}) {}
-	if (([]T{})) {}
-	if ; (((([]T{})))) {}
-
-	for (x) {}
-	for (((x))) {}
-	for ([]T{}) {}
-	for (([]T{})) {}
-	for ; (((([]T{})))) ; {}
-
-	switch (x) {}
-	switch (((x))) {}
-	switch ([]T{}) {}
-	switch ; (((([]T{})))) {}
-
-	for _ = range ((([]T{T{42}}))) {}
-
-	// leave parentheses - composite literals start with a type name
-	if (T{}) {}
-	if ((T{})) {}
-	if ; ((((T{})))) {}
-
-	for (T{}) {}
-	for ((T{})) {}
-	for ; ((((T{})))) ; {}
-
-	switch (T{}) {}
-	switch ; ((((T{})))) {}
-
-	for _ = range (((T1{T{42}}))) {}
-
-	if x == (T{42}[0]) {}
-	if (x == T{42}[0]) {}
-	if (x == (T{42}[0])) {}
-	if (x == (((T{42}[0])))) {}
-	if (((x == (T{42}[0])))) {}
-	if x == a + b*(T{42}[0]) {}
-	if (x == a + b*T{42}[0]) {}
-	if (x == a + b*(T{42}[0])) {}
-	if (x == a + ((b * (T{42}[0])))) {}
-	if (((x == a + b * (T{42}[0])))) {}
-	if (((a + b * (T{42}[0])) == x)) {}
-	if (((a + b * (T{42}[0])))) == x {}
-
-	if (struct{x bool}{false}.x) {}
-	if (struct{x bool}{false}.x) == false {}
-	if (struct{x bool}{false}.x == false) {}
-}
-
-
-// Extra empty lines inside functions. Do respect source code line
-// breaks between statement boundaries but print at most one empty
-// line at a time.
-func _() {
-
-	const _ = 0
-
-	const _ = 1
-	type _ int
-	type _ float
-
-	var _ = 0
-	var x = 1
-
-	// Each use(x) call below should have at most one empty line before and after.
-	// Known bug: The first use call may have more than one empty line before
-	//            (see go/printer/nodes.go, func linebreak).
-
-
-
-	use(x)
-
-	if x < x {
-
-		use(x)
-
-	} else {
-
-		use(x)
-
-	}
-}
-
-
-// Formatting around labels.
-func _() {
-	L:
-}
-
-
-func _() {
-	// this comment should be indented
-	L: ;  // no semicolon needed
-}
-
-
-func _() {
-	switch 0 {
-	case 0:
-		L0: ;  // semicolon required
-	case 1:
-		L1: ;  // semicolon required
-	default:
-		L2: ;  // no semicolon needed
-	}
-}
-
-
-func _() {
-	f()
-L1:
-	f()
-L2:
-	;
-L3:
-}
-
-
-func _() {
-	// this comment should be indented
-	L:
-}
-
-
-func _() {
-	L: _ = 0
-}
-
-
-func _() {
-	// this comment should be indented
-	L: _ = 0
-}
-
-
-func _() {
-	for {
-	L1: _ = 0
-	L2:
-		_ = 0
-	}
-}
-
-
-func _() {
-		// this comment should be indented
-	for {
-	L1: _ = 0
-	L2:
-		_ = 0
-	}
-}
-
-
-func _() {
-	if true {
-		_ = 0
-	}
-	_ = 0  // the indentation here should not be affected by the long label name
-AnOverlongLabel:
-	_ = 0
-	
-	if true {
-		_ = 0
-	}
-	_ = 0
-
-L:	_ = 0
-}
-
-
-func _() {
-	for {
-		goto L
-	}
-L:
-
-	MoreCode()
-}
-
-
-func _() {
-	for {
-		goto L
-	}
-L:	// A comment on the same line as the label, followed by a single empty line.
-	// Known bug: There may be more than one empty line before MoreCode()
-	//            (see go/printer/nodes.go, func linebreak).
-
-
-
-
-	MoreCode()
-}
-
-
-func _() {
-	for {
-		goto L
-	}
-L:
-
-
-
-
-	// There should be a single empty line before this comment.
-	MoreCode()
-}
-
-
-func _() {
-	for {
-		goto AVeryLongLabelThatShouldNotAffectFormatting
-	}
-AVeryLongLabelThatShouldNotAffectFormatting:
-	// There should be a single empty line after this comment.
-
-	// There should be a single empty line before this comment.
-	MoreCode()
-}
-
-
-// Formatting of empty statements.
-func _() {
-	;;;;;;;;;;;;;;;;;;;;;;;;;
-}
-
-func _() {;;;;;;;;;;;;;;;;;;;;;;;;;
-}
-
-func _() {;;;;;;;;;;;;;;;;;;;;;;;;;}
-
-func _() {
-f();;;;;;;;;;;;;;;;;;;;;;;;;
-}
-
-func _() {
-L:;;;;;;;;;;;;
-}
-
-func _() {
-L:;;;;;;;;;;;;
-	f()
-}
diff --git a/src/pkg/go/token/position.go b/src/pkg/go/token/position.go
deleted file mode 100644
index e6f0ae6..0000000
--- a/src/pkg/go/token/position.go
+++ /dev/null
@@ -1,464 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// TODO(gri) consider making this a separate package outside the go directory.
-
-package token
-
-import (
-	"fmt"
-	"sort"
-	"sync"
-)
-
-// -----------------------------------------------------------------------------
-// Positions
-
-// Position describes an arbitrary source position
-// including the file, line, and column location.
-// A Position is valid if the line number is > 0.
-//
-type Position struct {
-	Filename string // filename, if any
-	Offset   int    // offset, starting at 0
-	Line     int    // line number, starting at 1
-	Column   int    // column number, starting at 1 (character count)
-}
-
-// IsValid returns true if the position is valid.
-func (pos *Position) IsValid() bool { return pos.Line > 0 }
-
-// String returns a string in one of several forms:
-//
-//	file:line:column    valid position with file name
-//	line:column         valid position without file name
-//	file                invalid position with file name
-//	-                   invalid position without file name
-//
-func (pos Position) String() string {
-	s := pos.Filename
-	if pos.IsValid() {
-		if s != "" {
-			s += ":"
-		}
-		s += fmt.Sprintf("%d:%d", pos.Line, pos.Column)
-	}
-	if s == "" {
-		s = "-"
-	}
-	return s
-}
-
-// Pos is a compact encoding of a source position within a file set.
-// It can be converted into a Position for a more convenient, but much
-// larger, representation.
-//
-// The Pos value for a given file is a number in the range [base, base+size],
-// where base and size are specified when adding the file to the file set via
-// AddFile.
-//
-// To create the Pos value for a specific source offset, first add
-// the respective file to the current file set (via FileSet.AddFile)
-// and then call File.Pos(offset) for that file. Given a Pos value p
-// for a specific file set fset, the corresponding Position value is
-// obtained by calling fset.Position(p).
-//
-// Pos values can be compared directly with the usual comparison operators:
-// If two Pos values p and q are in the same file, comparing p and q is
-// equivalent to comparing the respective source file offsets. If p and q
-// are in different files, p < q is true if the file implied by p was added
-// to the respective file set before the file implied by q.
-//
-type Pos int
-
-// The zero value for Pos is NoPos; there is no file and line information
-// associated with it, and NoPos().IsValid() is false. NoPos is always
-// smaller than any other Pos value. The corresponding Position value
-// for NoPos is the zero value for Position.
-//
-const NoPos Pos = 0
-
-// IsValid returns true if the position is valid.
-func (p Pos) IsValid() bool {
-	return p != NoPos
-}
-
-// -----------------------------------------------------------------------------
-// File
-
-// A File is a handle for a file belonging to a FileSet.
-// A File has a name, size, and line offset table.
-//
-type File struct {
-	set  *FileSet
-	name string // file name as provided to AddFile
-	base int    // Pos value range for this file is [base...base+size]
-	size int    // file size as provided to AddFile
-
-	// lines and infos are protected by set.mutex
-	lines []int // lines contains the offset of the first character for each line (the first entry is always 0)
-	infos []lineInfo
-}
-
-// Name returns the file name of file f as registered with AddFile.
-func (f *File) Name() string {
-	return f.name
-}
-
-// Base returns the base offset of file f as registered with AddFile.
-func (f *File) Base() int {
-	return f.base
-}
-
-// Size returns the size of file f as registered with AddFile.
-func (f *File) Size() int {
-	return f.size
-}
-
-// LineCount returns the number of lines in file f.
-func (f *File) LineCount() int {
-	f.set.mutex.RLock()
-	n := len(f.lines)
-	f.set.mutex.RUnlock()
-	return n
-}
-
-// AddLine adds the line offset for a new line.
-// The line offset must be larger than the offset for the previous line
-// and smaller than the file size; otherwise the line offset is ignored.
-//
-func (f *File) AddLine(offset int) {
-	f.set.mutex.Lock()
-	if i := len(f.lines); (i == 0 || f.lines[i-1] < offset) && offset < f.size {
-		f.lines = append(f.lines, offset)
-	}
-	f.set.mutex.Unlock()
-}
-
-// MergeLine merges a line with the following line. It is akin to replacing
-// the newline character at the end of the line with a space (to not change the
-// remaining offsets). To obtain the line number, consult e.g. Position.Line.
-// MergeLine will panic if given an invalid line number.
-//
-func (f *File) MergeLine(line int) {
-	if line <= 0 {
-		panic("illegal line number (line numbering starts at 1)")
-	}
-	f.set.mutex.Lock()
-	defer f.set.mutex.Unlock()
-	if line >= len(f.lines) {
-		panic("illegal line number")
-	}
-	// To merge the line numbered <line> with the line numbered <line+1>,
-	// we need to remove the entry in lines corresponding to the line
-	// numbered <line+1>. The entry in lines corresponding to the line
-	// numbered <line+1> is located at index <line>, since indices in lines
-	// are 0-based and line numbers are 1-based.
-	copy(f.lines[line:], f.lines[line+1:])
-	f.lines = f.lines[:len(f.lines)-1]
-}
-
-// SetLines sets the line offsets for a file and returns true if successful.
-// The line offsets are the offsets of the first character of each line;
-// for instance for the content "ab\nc\n" the line offsets are {0, 3}.
-// An empty file has an empty line offset table.
-// Each line offset must be larger than the offset for the previous line
-// and smaller than the file size; otherwise SetLines fails and returns
-// false.
-//
-func (f *File) SetLines(lines []int) bool {
-	// verify validity of lines table
-	size := f.size
-	for i, offset := range lines {
-		if i > 0 && offset <= lines[i-1] || size <= offset {
-			return false
-		}
-	}
-
-	// set lines table
-	f.set.mutex.Lock()
-	f.lines = lines
-	f.set.mutex.Unlock()
-	return true
-}
-
-// SetLinesForContent sets the line offsets for the given file content.
-func (f *File) SetLinesForContent(content []byte) {
-	var lines []int
-	line := 0
-	for offset, b := range content {
-		if line >= 0 {
-			lines = append(lines, line)
-		}
-		line = -1
-		if b == '\n' {
-			line = offset + 1
-		}
-	}
-
-	// set lines table
-	f.set.mutex.Lock()
-	f.lines = lines
-	f.set.mutex.Unlock()
-}
-
-// A lineInfo object describes alternative file and line number
-// information (such as provided via a //line comment in a .go
-// file) for a given file offset.
-type lineInfo struct {
-	// fields are exported to make them accessible to gob
-	Offset   int
-	Filename string
-	Line     int
-}
-
-// AddLineInfo adds alternative file and line number information for
-// a given file offset. The offset must be larger than the offset for
-// the previously added alternative line info and smaller than the
-// file size; otherwise the information is ignored.
-//
-// AddLineInfo is typically used to register alternative position
-// information for //line filename:line comments in source files.
-//
-func (f *File) AddLineInfo(offset int, filename string, line int) {
-	f.set.mutex.Lock()
-	if i := len(f.infos); i == 0 || f.infos[i-1].Offset < offset && offset < f.size {
-		f.infos = append(f.infos, lineInfo{offset, filename, line})
-	}
-	f.set.mutex.Unlock()
-}
-
-// Pos returns the Pos value for the given file offset;
-// the offset must be <= f.Size().
-// f.Pos(f.Offset(p)) == p.
-//
-func (f *File) Pos(offset int) Pos {
-	if offset > f.size {
-		panic("illegal file offset")
-	}
-	return Pos(f.base + offset)
-}
-
-// Offset returns the offset for the given file position p;
-// p must be a valid Pos value in that file.
-// f.Offset(f.Pos(offset)) == offset.
-//
-func (f *File) Offset(p Pos) int {
-	if int(p) < f.base || int(p) > f.base+f.size {
-		panic("illegal Pos value")
-	}
-	return int(p) - f.base
-}
-
-// Line returns the line number for the given file position p;
-// p must be a Pos value in that file or NoPos.
-//
-func (f *File) Line(p Pos) int {
-	// TODO(gri) this can be implemented much more efficiently
-	return f.Position(p).Line
-}
-
-func searchLineInfos(a []lineInfo, x int) int {
-	return sort.Search(len(a), func(i int) bool { return a[i].Offset > x }) - 1
-}
-
-// info returns the file name, line, and column number for a file offset.
-func (f *File) info(offset int) (filename string, line, column int) {
-	filename = f.name
-	if i := searchInts(f.lines, offset); i >= 0 {
-		line, column = i+1, offset-f.lines[i]+1
-	}
-	if len(f.infos) > 0 {
-		// almost no files have extra line infos
-		if i := searchLineInfos(f.infos, offset); i >= 0 {
-			alt := &f.infos[i]
-			filename = alt.Filename
-			if i := searchInts(f.lines, alt.Offset); i >= 0 {
-				line += alt.Line - i - 1
-			}
-		}
-	}
-	return
-}
-
-func (f *File) position(p Pos) (pos Position) {
-	offset := int(p) - f.base
-	pos.Offset = offset
-	pos.Filename, pos.Line, pos.Column = f.info(offset)
-	return
-}
-
-// Position returns the Position value for the given file position p;
-// p must be a Pos value in that file or NoPos.
-//
-func (f *File) Position(p Pos) (pos Position) {
-	if p != NoPos {
-		if int(p) < f.base || int(p) > f.base+f.size {
-			panic("illegal Pos value")
-		}
-		pos = f.position(p)
-	}
-	return
-}
-
-// -----------------------------------------------------------------------------
-// FileSet
-
-// A FileSet represents a set of source files.
-// Methods of file sets are synchronized; multiple goroutines
-// may invoke them concurrently.
-//
-type FileSet struct {
-	mutex sync.RWMutex // protects the file set
-	base  int          // base offset for the next file
-	files []*File      // list of files in the order added to the set
-	last  *File        // cache of last file looked up
-}
-
-// NewFileSet creates a new file set.
-func NewFileSet() *FileSet {
-	return &FileSet{
-		base: 1, // 0 == NoPos
-	}
-}
-
-// Base returns the minimum base offset that must be provided to
-// AddFile when adding the next file.
-//
-func (s *FileSet) Base() int {
-	s.mutex.RLock()
-	b := s.base
-	s.mutex.RUnlock()
-	return b
-
-}
-
-// AddFile adds a new file with a given filename, base offset, and file size
-// to the file set s and returns the file. Multiple files may have the same
-// name. The base offset must not be smaller than the FileSet's Base(), and
-// size must not be negative. As a special case, if a negative base is provided,
-// the current value of the FileSet's Base() is used instead.
-//
-// Adding the file will set the file set's Base() value to base + size + 1
-// as the minimum base value for the next file. The following relationship
-// exists between a Pos value p for a given file offset offs:
-//
-//	int(p) = base + offs
-//
-// with offs in the range [0, size] and thus p in the range [base, base+size].
-// For convenience, File.Pos may be used to create file-specific position
-// values from a file offset.
-//
-func (s *FileSet) AddFile(filename string, base, size int) *File {
-	s.mutex.Lock()
-	defer s.mutex.Unlock()
-	if base < 0 {
-		base = s.base
-	}
-	if base < s.base || size < 0 {
-		panic("illegal base or size")
-	}
-	// base >= s.base && size >= 0
-	f := &File{s, filename, base, size, []int{0}, nil}
-	base += size + 1 // +1 because EOF also has a position
-	if base < 0 {
-		panic("token.Pos offset overflow (> 2G of source code in file set)")
-	}
-	// add the file to the file set
-	s.base = base
-	s.files = append(s.files, f)
-	s.last = f
-	return f
-}
-
-// Iterate calls f for the files in the file set in the order they were added
-// until f returns false.
-//
-func (s *FileSet) Iterate(f func(*File) bool) {
-	for i := 0; ; i++ {
-		var file *File
-		s.mutex.RLock()
-		if i < len(s.files) {
-			file = s.files[i]
-		}
-		s.mutex.RUnlock()
-		if file == nil || !f(file) {
-			break
-		}
-	}
-}
-
-func searchFiles(a []*File, x int) int {
-	return sort.Search(len(a), func(i int) bool { return a[i].base > x }) - 1
-}
-
-func (s *FileSet) file(p Pos) *File {
-	s.mutex.RLock()
-	// common case: p is in last file
-	if f := s.last; f != nil && f.base <= int(p) && int(p) <= f.base+f.size {
-		s.mutex.RUnlock()
-		return f
-	}
-	// p is not in last file - search all files
-	if i := searchFiles(s.files, int(p)); i >= 0 {
-		f := s.files[i]
-		// f.base <= int(p) by definition of searchFiles
-		if int(p) <= f.base+f.size {
-			s.mutex.RUnlock()
-			s.mutex.Lock()
-			s.last = f // race is ok - s.last is only a cache
-			s.mutex.Unlock()
-			return f
-		}
-	}
-	s.mutex.RUnlock()
-	return nil
-}
-
-// File returns the file that contains the position p.
-// If no such file is found (for instance for p == NoPos),
-// the result is nil.
-//
-func (s *FileSet) File(p Pos) (f *File) {
-	if p != NoPos {
-		f = s.file(p)
-	}
-	return
-}
-
-// Position converts a Pos in the fileset into a general Position.
-func (s *FileSet) Position(p Pos) (pos Position) {
-	if p != NoPos {
-		if f := s.file(p); f != nil {
-			pos = f.position(p)
-		}
-	}
-	return
-}
-
-// -----------------------------------------------------------------------------
-// Helper functions
-
-func searchInts(a []int, x int) int {
-	// This function body is a manually inlined version of:
-	//
-	//   return sort.Search(len(a), func(i int) bool { return a[i] > x }) - 1
-	//
-	// With better compiler optimizations, this may not be needed in the
-	// future, but at the moment this change improves the go/printer
-	// benchmark performance by ~30%. This has a direct impact on the
-	// speed of gofmt and thus seems worthwhile (2011-04-29).
-	// TODO(gri): Remove this when compilers have caught up.
-	i, j := 0, len(a)
-	for i < j {
-		h := i + (j-i)/2 // avoid overflow when computing h
-		// i ≤ h < j
-		if a[h] <= x {
-			i = h + 1
-		} else {
-			j = h
-		}
-	}
-	return i - 1
-}
diff --git a/src/pkg/go/token/position_test.go b/src/pkg/go/token/position_test.go
deleted file mode 100644
index ef6cfd9..0000000
--- a/src/pkg/go/token/position_test.go
+++ /dev/null
@@ -1,238 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package token
-
-import (
-	"fmt"
-	"math/rand"
-	"sync"
-	"testing"
-)
-
-func checkPos(t *testing.T, msg string, p, q Position) {
-	if p.Filename != q.Filename {
-		t.Errorf("%s: expected filename = %q; got %q", msg, q.Filename, p.Filename)
-	}
-	if p.Offset != q.Offset {
-		t.Errorf("%s: expected offset = %d; got %d", msg, q.Offset, p.Offset)
-	}
-	if p.Line != q.Line {
-		t.Errorf("%s: expected line = %d; got %d", msg, q.Line, p.Line)
-	}
-	if p.Column != q.Column {
-		t.Errorf("%s: expected column = %d; got %d", msg, q.Column, p.Column)
-	}
-}
-
-func TestNoPos(t *testing.T) {
-	if NoPos.IsValid() {
-		t.Errorf("NoPos should not be valid")
-	}
-	var fset *FileSet
-	checkPos(t, "nil NoPos", fset.Position(NoPos), Position{})
-	fset = NewFileSet()
-	checkPos(t, "fset NoPos", fset.Position(NoPos), Position{})
-}
-
-var tests = []struct {
-	filename string
-	source   []byte // may be nil
-	size     int
-	lines    []int
-}{
-	{"a", []byte{}, 0, []int{}},
-	{"b", []byte("01234"), 5, []int{0}},
-	{"c", []byte("\n\n\n\n\n\n\n\n\n"), 9, []int{0, 1, 2, 3, 4, 5, 6, 7, 8}},
-	{"d", nil, 100, []int{0, 5, 10, 20, 30, 70, 71, 72, 80, 85, 90, 99}},
-	{"e", nil, 777, []int{0, 80, 100, 120, 130, 180, 267, 455, 500, 567, 620}},
-	{"f", []byte("package p\n\nimport \"fmt\""), 23, []int{0, 10, 11}},
-	{"g", []byte("package p\n\nimport \"fmt\"\n"), 24, []int{0, 10, 11}},
-	{"h", []byte("package p\n\nimport \"fmt\"\n "), 25, []int{0, 10, 11, 24}},
-}
-
-func linecol(lines []int, offs int) (int, int) {
-	prevLineOffs := 0
-	for line, lineOffs := range lines {
-		if offs < lineOffs {
-			return line, offs - prevLineOffs + 1
-		}
-		prevLineOffs = lineOffs
-	}
-	return len(lines), offs - prevLineOffs + 1
-}
-
-func verifyPositions(t *testing.T, fset *FileSet, f *File, lines []int) {
-	for offs := 0; offs < f.Size(); offs++ {
-		p := f.Pos(offs)
-		offs2 := f.Offset(p)
-		if offs2 != offs {
-			t.Errorf("%s, Offset: expected offset %d; got %d", f.Name(), offs, offs2)
-		}
-		line, col := linecol(lines, offs)
-		msg := fmt.Sprintf("%s (offs = %d, p = %d)", f.Name(), offs, p)
-		checkPos(t, msg, f.Position(f.Pos(offs)), Position{f.Name(), offs, line, col})
-		checkPos(t, msg, fset.Position(p), Position{f.Name(), offs, line, col})
-	}
-}
-
-func makeTestSource(size int, lines []int) []byte {
-	src := make([]byte, size)
-	for _, offs := range lines {
-		if offs > 0 {
-			src[offs-1] = '\n'
-		}
-	}
-	return src
-}
-
-func TestPositions(t *testing.T) {
-	const delta = 7 // a non-zero base offset increment
-	fset := NewFileSet()
-	for _, test := range tests {
-		// verify consistency of test case
-		if test.source != nil && len(test.source) != test.size {
-			t.Errorf("%s: inconsistent test case: expected file size %d; got %d", test.filename, test.size, len(test.source))
-		}
-
-		// add file and verify name and size
-		f := fset.AddFile(test.filename, fset.Base()+delta, test.size)
-		if f.Name() != test.filename {
-			t.Errorf("expected filename %q; got %q", test.filename, f.Name())
-		}
-		if f.Size() != test.size {
-			t.Errorf("%s: expected file size %d; got %d", f.Name(), test.size, f.Size())
-		}
-		if fset.File(f.Pos(0)) != f {
-			t.Errorf("%s: f.Pos(0) was not found in f", f.Name())
-		}
-
-		// add lines individually and verify all positions
-		for i, offset := range test.lines {
-			f.AddLine(offset)
-			if f.LineCount() != i+1 {
-				t.Errorf("%s, AddLine: expected line count %d; got %d", f.Name(), i+1, f.LineCount())
-			}
-			// adding the same offset again should be ignored
-			f.AddLine(offset)
-			if f.LineCount() != i+1 {
-				t.Errorf("%s, AddLine: expected unchanged line count %d; got %d", f.Name(), i+1, f.LineCount())
-			}
-			verifyPositions(t, fset, f, test.lines[0:i+1])
-		}
-
-		// add lines with SetLines and verify all positions
-		if ok := f.SetLines(test.lines); !ok {
-			t.Errorf("%s: SetLines failed", f.Name())
-		}
-		if f.LineCount() != len(test.lines) {
-			t.Errorf("%s, SetLines: expected line count %d; got %d", f.Name(), len(test.lines), f.LineCount())
-		}
-		verifyPositions(t, fset, f, test.lines)
-
-		// add lines with SetLinesForContent and verify all positions
-		src := test.source
-		if src == nil {
-			// no test source available - create one from scratch
-			src = makeTestSource(test.size, test.lines)
-		}
-		f.SetLinesForContent(src)
-		if f.LineCount() != len(test.lines) {
-			t.Errorf("%s, SetLinesForContent: expected line count %d; got %d", f.Name(), len(test.lines), f.LineCount())
-		}
-		verifyPositions(t, fset, f, test.lines)
-	}
-}
-
-func TestLineInfo(t *testing.T) {
-	fset := NewFileSet()
-	f := fset.AddFile("foo", fset.Base(), 500)
-	lines := []int{0, 42, 77, 100, 210, 220, 277, 300, 333, 401}
-	// add lines individually and provide alternative line information
-	for _, offs := range lines {
-		f.AddLine(offs)
-		f.AddLineInfo(offs, "bar", 42)
-	}
-	// verify positions for all offsets
-	for offs := 0; offs <= f.Size(); offs++ {
-		p := f.Pos(offs)
-		_, col := linecol(lines, offs)
-		msg := fmt.Sprintf("%s (offs = %d, p = %d)", f.Name(), offs, p)
-		checkPos(t, msg, f.Position(f.Pos(offs)), Position{"bar", offs, 42, col})
-		checkPos(t, msg, fset.Position(p), Position{"bar", offs, 42, col})
-	}
-}
-
-func TestFiles(t *testing.T) {
-	fset := NewFileSet()
-	for i, test := range tests {
-		base := fset.Base()
-		if i%2 == 1 {
-			// Setting a negative base is equivalent to
-			// fset.Base(), so test some of each.
-			base = -1
-		}
-		fset.AddFile(test.filename, base, test.size)
-		j := 0
-		fset.Iterate(func(f *File) bool {
-			if f.Name() != tests[j].filename {
-				t.Errorf("expected filename = %s; got %s", tests[j].filename, f.Name())
-			}
-			j++
-			return true
-		})
-		if j != i+1 {
-			t.Errorf("expected %d files; got %d", i+1, j)
-		}
-	}
-}
-
-// FileSet.File should return nil if Pos is past the end of the FileSet.
-func TestFileSetPastEnd(t *testing.T) {
-	fset := NewFileSet()
-	for _, test := range tests {
-		fset.AddFile(test.filename, fset.Base(), test.size)
-	}
-	if f := fset.File(Pos(fset.Base())); f != nil {
-		t.Errorf("expected nil, got %v", f)
-	}
-}
-
-func TestFileSetCacheUnlikely(t *testing.T) {
-	fset := NewFileSet()
-	offsets := make(map[string]int)
-	for _, test := range tests {
-		offsets[test.filename] = fset.Base()
-		fset.AddFile(test.filename, fset.Base(), test.size)
-	}
-	for file, pos := range offsets {
-		f := fset.File(Pos(pos))
-		if f.Name() != file {
-			t.Errorf("expecting %q at position %d, got %q", file, pos, f.Name())
-		}
-	}
-}
-
-// issue 4345. Test concurrent use of FileSet.Pos does not trigger a
-// race in the FileSet position cache.
-func TestFileSetRace(t *testing.T) {
-	fset := NewFileSet()
-	for i := 0; i < 100; i++ {
-		fset.AddFile(fmt.Sprintf("file-%d", i), fset.Base(), 1031)
-	}
-	max := int32(fset.Base())
-	var stop sync.WaitGroup
-	r := rand.New(rand.NewSource(7))
-	for i := 0; i < 2; i++ {
-		r := rand.New(rand.NewSource(r.Int63()))
-		stop.Add(1)
-		go func() {
-			for i := 0; i < 1000; i++ {
-				fset.Position(Pos(r.Int31n(max)))
-			}
-			stop.Done()
-		}()
-	}
-	stop.Wait()
-}
diff --git a/src/pkg/hash/crc32/crc32.go b/src/pkg/hash/crc32/crc32.go
deleted file mode 100644
index a2a21a0..0000000
--- a/src/pkg/hash/crc32/crc32.go
+++ /dev/null
@@ -1,135 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package crc32 implements the 32-bit cyclic redundancy check, or CRC-32,
-// checksum. See http://en.wikipedia.org/wiki/Cyclic_redundancy_check for
-// information.
-package crc32
-
-import (
-	"hash"
-	"sync"
-)
-
-// The size of a CRC-32 checksum in bytes.
-const Size = 4
-
-// Predefined polynomials.
-const (
-	// Far and away the most common CRC-32 polynomial.
-	// Used by ethernet (IEEE 802.3), v.42, fddi, gzip, zip, png, mpeg-2, ...
-	IEEE = 0xedb88320
-
-	// Castagnoli's polynomial, used in iSCSI.
-	// Has better error detection characteristics than IEEE.
-	// http://dx.doi.org/10.1109/26.231911
-	Castagnoli = 0x82f63b78
-
-	// Koopman's polynomial.
-	// Also has better error detection characteristics than IEEE.
-	// http://dx.doi.org/10.1109/DSN.2002.1028931
-	Koopman = 0xeb31d82e
-)
-
-// Table is a 256-word table representing the polynomial for efficient processing.
-type Table [256]uint32
-
-// castagnoliTable points to a lazily initialized Table for the Castagnoli
-// polynomial. MakeTable will always return this value when asked to make a
-// Castagnoli table so we can compare against it to find when the caller is
-// using this polynomial.
-var castagnoliTable *Table
-var castagnoliOnce sync.Once
-
-func castagnoliInit() {
-	castagnoliTable = makeTable(Castagnoli)
-}
-
-// IEEETable is the table for the IEEE polynomial.
-var IEEETable = makeTable(IEEE)
-
-// MakeTable returns the Table constructed from the specified polynomial.
-func MakeTable(poly uint32) *Table {
-	switch poly {
-	case IEEE:
-		return IEEETable
-	case Castagnoli:
-		castagnoliOnce.Do(castagnoliInit)
-		return castagnoliTable
-	}
-	return makeTable(poly)
-}
-
-// makeTable returns the Table constructed from the specified polynomial.
-func makeTable(poly uint32) *Table {
-	t := new(Table)
-	for i := 0; i < 256; i++ {
-		crc := uint32(i)
-		for j := 0; j < 8; j++ {
-			if crc&1 == 1 {
-				crc = (crc >> 1) ^ poly
-			} else {
-				crc >>= 1
-			}
-		}
-		t[i] = crc
-	}
-	return t
-}
-
-// digest represents the partial evaluation of a checksum.
-type digest struct {
-	crc uint32
-	tab *Table
-}
-
-// New creates a new hash.Hash32 computing the CRC-32 checksum
-// using the polynomial represented by the Table.
-func New(tab *Table) hash.Hash32 { return &digest{0, tab} }
-
-// NewIEEE creates a new hash.Hash32 computing the CRC-32 checksum
-// using the IEEE polynomial.
-func NewIEEE() hash.Hash32 { return New(IEEETable) }
-
-func (d *digest) Size() int { return Size }
-
-func (d *digest) BlockSize() int { return 1 }
-
-func (d *digest) Reset() { d.crc = 0 }
-
-func update(crc uint32, tab *Table, p []byte) uint32 {
-	crc = ^crc
-	for _, v := range p {
-		crc = tab[byte(crc)^v] ^ (crc >> 8)
-	}
-	return ^crc
-}
-
-// Update returns the result of adding the bytes in p to the crc.
-func Update(crc uint32, tab *Table, p []byte) uint32 {
-	if tab == castagnoliTable {
-		return updateCastagnoli(crc, p)
-	}
-	return update(crc, tab, p)
-}
-
-func (d *digest) Write(p []byte) (n int, err error) {
-	d.crc = Update(d.crc, d.tab, p)
-	return len(p), nil
-}
-
-func (d *digest) Sum32() uint32 { return d.crc }
-
-func (d *digest) Sum(in []byte) []byte {
-	s := d.Sum32()
-	return append(in, byte(s>>24), byte(s>>16), byte(s>>8), byte(s))
-}
-
-// Checksum returns the CRC-32 checksum of data
-// using the polynomial represented by the Table.
-func Checksum(data []byte, tab *Table) uint32 { return Update(0, tab, data) }
-
-// ChecksumIEEE returns the CRC-32 checksum of data
-// using the IEEE polynomial.
-func ChecksumIEEE(data []byte) uint32 { return update(0, IEEETable, data) }
diff --git a/src/pkg/hash/crc32/crc32_amd64.s b/src/pkg/hash/crc32/crc32_amd64.s
deleted file mode 100644
index 95dc8bf..0000000
--- a/src/pkg/hash/crc32/crc32_amd64.s
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../../cmd/ld/textflag.h"
-
-// func castagnoliSSE42(crc uint32, p []byte) uint32
-TEXT ·castagnoliSSE42(SB),NOSPLIT,$0
-	MOVL crc+0(FP), AX  // CRC value
-	MOVQ p+8(FP), SI  // data pointer
-	MOVQ p_len+16(FP), CX  // len(p)
-
-	NOTL AX
-
-	/* If there's less than 8 bytes to process, we do it byte-by-byte. */
-	CMPQ CX, $8
-	JL cleanup
-
-	/* Process individual bytes until the input is 8-byte aligned. */
-startup:
-	MOVQ SI, BX
-	ANDQ $7, BX
-	JZ aligned
-
-	CRC32B (SI), AX
-	DECQ CX
-	INCQ SI
-	JMP startup
-
-aligned:
-	/* The input is now 8-byte aligned and we can process 8-byte chunks. */
-	CMPQ CX, $8
-	JL cleanup
-
-	CRC32Q (SI), AX
-	ADDQ $8, SI
-	SUBQ $8, CX
-	JMP aligned
-
-cleanup:
-	/* We may have some bytes left over that we process one at a time. */
-	CMPQ CX, $0
-	JE done
-
-	CRC32B (SI), AX
-	INCQ SI
-	DECQ CX
-	JMP cleanup
-
-done:
-	NOTL AX
-	MOVL AX, ret+32(FP)
-	RET
-
-// func haveSSE42() bool
-TEXT ·haveSSE42(SB),NOSPLIT,$0
-	XORQ AX, AX
-	INCL AX
-	CPUID
-	SHRQ $20, CX
-	ANDQ $1, CX
-	MOVB CX, ret+0(FP)
-	RET
-
diff --git a/src/pkg/hash/crc32/crc32_amd64p32.s b/src/pkg/hash/crc32/crc32_amd64p32.s
deleted file mode 100644
index e34f208..0000000
--- a/src/pkg/hash/crc32/crc32_amd64p32.s
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../../cmd/ld/textflag.h"
-
-// func castagnoliSSE42(crc uint32, p []byte) uint32
-TEXT ·castagnoliSSE42(SB),NOSPLIT,$0
-	MOVL crc+0(FP), AX  // CRC value
-	MOVL p+4(FP), SI  // data pointer
-	MOVL p_len+8(FP), CX  // len(p)
-
-	NOTL AX
-
-	/* If there's less than 8 bytes to process, we do it byte-by-byte. */
-	CMPQ CX, $8
-	JL cleanup
-
-	/* Process individual bytes until the input is 8-byte aligned. */
-startup:
-	MOVQ SI, BX
-	ANDQ $7, BX
-	JZ aligned
-
-	CRC32B (SI), AX
-	DECQ CX
-	INCQ SI
-	JMP startup
-
-aligned:
-	/* The input is now 8-byte aligned and we can process 8-byte chunks. */
-	CMPQ CX, $8
-	JL cleanup
-
-	CRC32Q (SI), AX
-	ADDQ $8, SI
-	SUBQ $8, CX
-	JMP aligned
-
-cleanup:
-	/* We may have some bytes left over that we process one at a time. */
-	CMPQ CX, $0
-	JE done
-
-	CRC32B (SI), AX
-	INCQ SI
-	DECQ CX
-	JMP cleanup
-
-done:
-	NOTL AX
-	MOVL AX, ret+16(FP)
-	RET
-
-// func haveSSE42() bool
-TEXT ·haveSSE42(SB),NOSPLIT,$0
-	XORQ AX, AX
-	INCL AX
-	CPUID
-	SHRQ $20, CX
-	ANDQ $1, CX
-	MOVB CX, ret+0(FP)
-	RET
-
diff --git a/src/pkg/html/template/error.go b/src/pkg/html/template/error.go
deleted file mode 100644
index 46e49cc..0000000
--- a/src/pkg/html/template/error.go
+++ /dev/null
@@ -1,197 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package template
-
-import (
-	"fmt"
-)
-
-// Error describes a problem encountered during template Escaping.
-type Error struct {
-	// ErrorCode describes the kind of error.
-	ErrorCode ErrorCode
-	// Name is the name of the template in which the error was encountered.
-	Name string
-	// Line is the line number of the error in the template source or 0.
-	Line int
-	// Description is a human-readable description of the problem.
-	Description string
-}
-
-// ErrorCode is a code for a kind of error.
-type ErrorCode int
-
-// We define codes for each error that manifests while escaping templates, but
-// escaped templates may also fail at runtime.
-//
-// Output: "ZgotmplZ"
-// Example:
-//   <img src="{{.X}}">
-//   where {{.X}} evaluates to `javascript:...`
-// Discussion:
-//   "ZgotmplZ" is a special value that indicates that unsafe content reached a
-//   CSS or URL context at runtime. The output of the example will be
-//     <img src="#ZgotmplZ">
-//   If the data comes from a trusted source, use content types to exempt it
-//   from filtering: URL(`javascript:...`).
-const (
-	// OK indicates the lack of an error.
-	OK ErrorCode = iota
-
-	// ErrAmbigContext: "... appears in an ambiguous URL context"
-	// Example:
-	//   <a href="
-	//      {{if .C}}
-	//        /path/
-	//      {{else}}
-	//        /search?q=
-	//      {{end}}
-	//      {{.X}}
-	//   ">
-	// Discussion:
-	//   {{.X}} is in an ambiguous URL context since, depending on {{.C}},
-	//  it may be either a URL suffix or a query parameter.
-	//   Moving {{.X}} into the condition removes the ambiguity:
-	//   <a href="{{if .C}}/path/{{.X}}{{else}}/search?q={{.X}}">
-	ErrAmbigContext
-
-	// ErrBadHTML: "expected space, attr name, or end of tag, but got ...",
-	//   "... in unquoted attr", "... in attribute name"
-	// Example:
-	//   <a href = /search?q=foo>
-	//   <href=foo>
-	//   <form na<e=...>
-	//   <option selected<
-	// Discussion:
-	//   This is often due to a typo in an HTML element, but some runes
-	//   are banned in tag names, attribute names, and unquoted attribute
-	//   values because they can tickle parser ambiguities.
-	//   Quoting all attributes is the best policy.
-	ErrBadHTML
-
-	// ErrBranchEnd: "{{if}} branches end in different contexts"
-	// Example:
-	//   {{if .C}}<a href="{{end}}{{.X}}
-	// Discussion:
-	//   Package html/template statically examines each path through an
-	//   {{if}}, {{range}}, or {{with}} to escape any following pipelines.
-	//   The example is ambiguous since {{.X}} might be an HTML text node,
-	//   or a URL prefix in an HTML attribute. The context of {{.X}} is
-	//   used to figure out how to escape it, but that context depends on
-	//   the run-time value of {{.C}} which is not statically known.
-	//
-	//   The problem is usually something like missing quotes or angle
-	//   brackets, or can be avoided by refactoring to put the two contexts
-	//   into different branches of an if, range or with. If the problem
-	//   is in a {{range}} over a collection that should never be empty,
-	//   adding a dummy {{else}} can help.
-	ErrBranchEnd
-
-	// ErrEndContext: "... ends in a non-text context: ..."
-	// Examples:
-	//   <div
-	//   <div title="no close quote>
-	//   <script>f()
-	// Discussion:
-	//   Executed templates should produce a DocumentFragment of HTML.
-	//   Templates that end without closing tags will trigger this error.
-	//   Templates that should not be used in an HTML context or that
-	//   produce incomplete Fragments should not be executed directly.
-	//
-	//   {{define "main"}} <script>{{template "helper"}}</script> {{end}}
-	//   {{define "helper"}} document.write(' <div title=" ') {{end}}
-	//
-	//   "helper" does not produce a valid document fragment, so should
-	//   not be Executed directly.
-	ErrEndContext
-
-	// ErrNoSuchTemplate: "no such template ..."
-	// Examples:
-	//   {{define "main"}}<div {{template "attrs"}}>{{end}}
-	//   {{define "attrs"}}href="{{.URL}}"{{end}}
-	// Discussion:
-	//   Package html/template looks through template calls to compute the
-	//   context.
-	//   Here the {{.URL}} in "attrs" must be treated as a URL when called
-	//   from "main", but you will get this error if "attrs" is not defined
-	//   when "main" is parsed.
-	ErrNoSuchTemplate
-
-	// ErrOutputContext: "cannot compute output context for template ..."
-	// Examples:
-	//   {{define "t"}}{{if .T}}{{template "t" .T}}{{end}}{{.H}}",{{end}}
-	// Discussion:
-	//   A recursive template does not end in the same context in which it
-	//   starts, and a reliable output context cannot be computed.
-	//   Look for typos in the named template.
-	//   If the template should not be called in the named start context,
-	//   look for calls to that template in unexpected contexts.
-	//   Maybe refactor recursive templates to not be recursive.
-	ErrOutputContext
-
-	// ErrPartialCharset: "unfinished JS regexp charset in ..."
-	// Example:
-	//     <script>var pattern = /foo[{{.Chars}}]/</script>
-	// Discussion:
-	//   Package html/template does not support interpolation into regular
-	//   expression literal character sets.
-	ErrPartialCharset
-
-	// ErrPartialEscape: "unfinished escape sequence in ..."
-	// Example:
-	//   <script>alert("\{{.X}}")</script>
-	// Discussion:
-	//   Package html/template does not support actions following a
-	//   backslash.
-	//   This is usually an error and there are better solutions; for
-	//   example
-	//     <script>alert("{{.X}}")</script>
-	//   should work, and if {{.X}} is a partial escape sequence such as
-	//   "xA0", mark the whole sequence as safe content: JSStr(`\xA0`)
-	ErrPartialEscape
-
-	// ErrRangeLoopReentry: "on range loop re-entry: ..."
-	// Example:
-	//   <script>var x = [{{range .}}'{{.}},{{end}}]</script>
-	// Discussion:
-	//   If an iteration through a range would cause it to end in a
-	//   different context than an earlier pass, there is no single context.
-	//   In the example, there is missing a quote, so it is not clear
-	//   whether {{.}} is meant to be inside a JS string or in a JS value
-	//   context.  The second iteration would produce something like
-	//
-	//     <script>var x = ['firstValue,'secondValue]</script>
-	ErrRangeLoopReentry
-
-	// ErrSlashAmbig: '/' could start a division or regexp.
-	// Example:
-	//   <script>
-	//     {{if .C}}var x = 1{{end}}
-	//     /-{{.N}}/i.test(x) ? doThis : doThat();
-	//   </script>
-	// Discussion:
-	//   The example above could produce `var x = 1/-2/i.test(s)...`
-	//   in which the first '/' is a mathematical division operator or it
-	//   could produce `/-2/i.test(s)` in which the first '/' starts a
-	//   regexp literal.
-	//   Look for missing semicolons inside branches, and maybe add
-	//   parentheses to make it clear which interpretation you intend.
-	ErrSlashAmbig
-)
-
-func (e *Error) Error() string {
-	if e.Line != 0 {
-		return fmt.Sprintf("html/template:%s:%d: %s", e.Name, e.Line, e.Description)
-	} else if e.Name != "" {
-		return fmt.Sprintf("html/template:%s: %s", e.Name, e.Description)
-	}
-	return "html/template: " + e.Description
-}
-
-// errorf creates an error given a format string f and args.
-// The template Name still needs to be supplied.
-func errorf(k ErrorCode, line int, f string, args ...interface{}) *Error {
-	return &Error{k, "", line, fmt.Sprintf(f, args...)}
-}
diff --git a/src/pkg/html/template/escape.go b/src/pkg/html/template/escape.go
deleted file mode 100644
index 4e37982..0000000
--- a/src/pkg/html/template/escape.go
+++ /dev/null
@@ -1,815 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package template
-
-import (
-	"bytes"
-	"fmt"
-	"html"
-	"io"
-	"text/template"
-	"text/template/parse"
-)
-
-// escapeTemplates rewrites the named templates, which must be
-// associated with t, to guarantee that the output of any of the named
-// templates is properly escaped.  Names should include the names of
-// all templates that might be Executed but need not include helper
-// templates.  If no error is returned, then the named templates have
-// been modified.  Otherwise the named templates have been rendered
-// unusable.
-func escapeTemplates(tmpl *Template, names ...string) error {
-	e := newEscaper(tmpl)
-	for _, name := range names {
-		c, _ := e.escapeTree(context{}, name, 0)
-		var err error
-		if c.err != nil {
-			err, c.err.Name = c.err, name
-		} else if c.state != stateText {
-			err = &Error{ErrEndContext, name, 0, fmt.Sprintf("ends in a non-text context: %v", c)}
-		}
-		if err != nil {
-			// Prevent execution of unsafe templates.
-			for _, name := range names {
-				if t := tmpl.set[name]; t != nil {
-					t.text.Tree = nil
-					t.Tree = nil
-				}
-			}
-			return err
-		}
-	}
-	e.commit()
-	for _, name := range names {
-		if t := tmpl.set[name]; t != nil {
-			t.escaped = true
-			t.Tree = t.text.Tree
-		}
-	}
-	return nil
-}
-
-// funcMap maps command names to functions that render their inputs safe.
-var funcMap = template.FuncMap{
-	"html_template_attrescaper":     attrEscaper,
-	"html_template_commentescaper":  commentEscaper,
-	"html_template_cssescaper":      cssEscaper,
-	"html_template_cssvaluefilter":  cssValueFilter,
-	"html_template_htmlnamefilter":  htmlNameFilter,
-	"html_template_htmlescaper":     htmlEscaper,
-	"html_template_jsregexpescaper": jsRegexpEscaper,
-	"html_template_jsstrescaper":    jsStrEscaper,
-	"html_template_jsvalescaper":    jsValEscaper,
-	"html_template_nospaceescaper":  htmlNospaceEscaper,
-	"html_template_rcdataescaper":   rcdataEscaper,
-	"html_template_urlescaper":      urlEscaper,
-	"html_template_urlfilter":       urlFilter,
-	"html_template_urlnormalizer":   urlNormalizer,
-}
-
-// equivEscapers matches contextual escapers to equivalent template builtins.
-var equivEscapers = map[string]string{
-	"html_template_attrescaper":    "html",
-	"html_template_htmlescaper":    "html",
-	"html_template_nospaceescaper": "html",
-	"html_template_rcdataescaper":  "html",
-	"html_template_urlescaper":     "urlquery",
-	"html_template_urlnormalizer":  "urlquery",
-}
-
-// escaper collects type inferences about templates and changes needed to make
-// templates injection safe.
-type escaper struct {
-	tmpl *Template
-	// output[templateName] is the output context for a templateName that
-	// has been mangled to include its input context.
-	output map[string]context
-	// derived[c.mangle(name)] maps to a template derived from the template
-	// named name templateName for the start context c.
-	derived map[string]*template.Template
-	// called[templateName] is a set of called mangled template names.
-	called map[string]bool
-	// xxxNodeEdits are the accumulated edits to apply during commit.
-	// Such edits are not applied immediately in case a template set
-	// executes a given template in different escaping contexts.
-	actionNodeEdits   map[*parse.ActionNode][]string
-	templateNodeEdits map[*parse.TemplateNode]string
-	textNodeEdits     map[*parse.TextNode][]byte
-}
-
-// newEscaper creates a blank escaper for the given set.
-func newEscaper(t *Template) *escaper {
-	return &escaper{
-		t,
-		map[string]context{},
-		map[string]*template.Template{},
-		map[string]bool{},
-		map[*parse.ActionNode][]string{},
-		map[*parse.TemplateNode]string{},
-		map[*parse.TextNode][]byte{},
-	}
-}
-
-// filterFailsafe is an innocuous word that is emitted in place of unsafe values
-// by sanitizer functions. It is not a keyword in any programming language,
-// contains no special characters, is not empty, and when it appears in output
-// it is distinct enough that a developer can find the source of the problem
-// via a search engine.
-const filterFailsafe = "ZgotmplZ"
-
-// escape escapes a template node.
-func (e *escaper) escape(c context, n parse.Node) context {
-	switch n := n.(type) {
-	case *parse.ActionNode:
-		return e.escapeAction(c, n)
-	case *parse.IfNode:
-		return e.escapeBranch(c, &n.BranchNode, "if")
-	case *parse.ListNode:
-		return e.escapeList(c, n)
-	case *parse.RangeNode:
-		return e.escapeBranch(c, &n.BranchNode, "range")
-	case *parse.TemplateNode:
-		return e.escapeTemplate(c, n)
-	case *parse.TextNode:
-		return e.escapeText(c, n)
-	case *parse.WithNode:
-		return e.escapeBranch(c, &n.BranchNode, "with")
-	}
-	panic("escaping " + n.String() + " is unimplemented")
-}
-
-// escapeAction escapes an action template node.
-func (e *escaper) escapeAction(c context, n *parse.ActionNode) context {
-	if len(n.Pipe.Decl) != 0 {
-		// A local variable assignment, not an interpolation.
-		return c
-	}
-	c = nudge(c)
-	s := make([]string, 0, 3)
-	switch c.state {
-	case stateError:
-		return c
-	case stateURL, stateCSSDqStr, stateCSSSqStr, stateCSSDqURL, stateCSSSqURL, stateCSSURL:
-		switch c.urlPart {
-		case urlPartNone:
-			s = append(s, "html_template_urlfilter")
-			fallthrough
-		case urlPartPreQuery:
-			switch c.state {
-			case stateCSSDqStr, stateCSSSqStr:
-				s = append(s, "html_template_cssescaper")
-			default:
-				s = append(s, "html_template_urlnormalizer")
-			}
-		case urlPartQueryOrFrag:
-			s = append(s, "html_template_urlescaper")
-		case urlPartUnknown:
-			return context{
-				state: stateError,
-				err:   errorf(ErrAmbigContext, n.Line, "%s appears in an ambiguous URL context", n),
-			}
-		default:
-			panic(c.urlPart.String())
-		}
-	case stateJS:
-		s = append(s, "html_template_jsvalescaper")
-		// A slash after a value starts a div operator.
-		c.jsCtx = jsCtxDivOp
-	case stateJSDqStr, stateJSSqStr:
-		s = append(s, "html_template_jsstrescaper")
-	case stateJSRegexp:
-		s = append(s, "html_template_jsregexpescaper")
-	case stateCSS:
-		s = append(s, "html_template_cssvaluefilter")
-	case stateText:
-		s = append(s, "html_template_htmlescaper")
-	case stateRCDATA:
-		s = append(s, "html_template_rcdataescaper")
-	case stateAttr:
-		// Handled below in delim check.
-	case stateAttrName, stateTag:
-		c.state = stateAttrName
-		s = append(s, "html_template_htmlnamefilter")
-	default:
-		if isComment(c.state) {
-			s = append(s, "html_template_commentescaper")
-		} else {
-			panic("unexpected state " + c.state.String())
-		}
-	}
-	switch c.delim {
-	case delimNone:
-		// No extra-escaping needed for raw text content.
-	case delimSpaceOrTagEnd:
-		s = append(s, "html_template_nospaceescaper")
-	default:
-		s = append(s, "html_template_attrescaper")
-	}
-	e.editActionNode(n, s)
-	return c
-}
-
-// allIdents returns the names of the identifiers under the Ident field of the node,
-// which might be a singleton (Identifier) or a slice (Field).
-func allIdents(node parse.Node) []string {
-	switch node := node.(type) {
-	case *parse.IdentifierNode:
-		return []string{node.Ident}
-	case *parse.FieldNode:
-		return node.Ident
-	}
-	panic("unidentified node type in allIdents")
-}
-
-// ensurePipelineContains ensures that the pipeline has commands with
-// the identifiers in s in order.
-// If the pipeline already has some of the sanitizers, do not interfere.
-// For example, if p is (.X | html) and s is ["escapeJSVal", "html"] then it
-// has one matching, "html", and one to insert, "escapeJSVal", to produce
-// (.X | escapeJSVal | html).
-func ensurePipelineContains(p *parse.PipeNode, s []string) {
-	if len(s) == 0 {
-		return
-	}
-	n := len(p.Cmds)
-	// Find the identifiers at the end of the command chain.
-	idents := p.Cmds
-	for i := n - 1; i >= 0; i-- {
-		if cmd := p.Cmds[i]; len(cmd.Args) != 0 {
-			if _, ok := cmd.Args[0].(*parse.IdentifierNode); ok {
-				continue
-			}
-		}
-		idents = p.Cmds[i+1:]
-	}
-	dups := 0
-	for _, idNode := range idents {
-		for _, ident := range allIdents(idNode.Args[0]) {
-			if escFnsEq(s[dups], ident) {
-				dups++
-				if dups == len(s) {
-					return
-				}
-			}
-		}
-	}
-	newCmds := make([]*parse.CommandNode, n-len(idents), n+len(s)-dups)
-	copy(newCmds, p.Cmds)
-	// Merge existing identifier commands with the sanitizers needed.
-	for _, idNode := range idents {
-		pos := idNode.Args[0].Position()
-		for _, ident := range allIdents(idNode.Args[0]) {
-			i := indexOfStr(ident, s, escFnsEq)
-			if i != -1 {
-				for _, name := range s[:i] {
-					newCmds = appendCmd(newCmds, newIdentCmd(name, pos))
-				}
-				s = s[i+1:]
-			}
-		}
-		newCmds = appendCmd(newCmds, idNode)
-	}
-	// Create any remaining sanitizers.
-	for _, name := range s {
-		newCmds = appendCmd(newCmds, newIdentCmd(name, p.Position()))
-	}
-	p.Cmds = newCmds
-}
-
-// redundantFuncs[a][b] implies that funcMap[b](funcMap[a](x)) == funcMap[a](x)
-// for all x.
-var redundantFuncs = map[string]map[string]bool{
-	"html_template_commentescaper": {
-		"html_template_attrescaper":    true,
-		"html_template_nospaceescaper": true,
-		"html_template_htmlescaper":    true,
-	},
-	"html_template_cssescaper": {
-		"html_template_attrescaper": true,
-	},
-	"html_template_jsregexpescaper": {
-		"html_template_attrescaper": true,
-	},
-	"html_template_jsstrescaper": {
-		"html_template_attrescaper": true,
-	},
-	"html_template_urlescaper": {
-		"html_template_urlnormalizer": true,
-	},
-}
-
-// appendCmd appends the given command to the end of the command pipeline
-// unless it is redundant with the last command.
-func appendCmd(cmds []*parse.CommandNode, cmd *parse.CommandNode) []*parse.CommandNode {
-	if n := len(cmds); n != 0 {
-		last, ok := cmds[n-1].Args[0].(*parse.IdentifierNode)
-		next, _ := cmd.Args[0].(*parse.IdentifierNode)
-		if ok && redundantFuncs[last.Ident][next.Ident] {
-			return cmds
-		}
-	}
-	return append(cmds, cmd)
-}
-
-// indexOfStr is the first i such that eq(s, strs[i]) or -1 if s was not found.
-func indexOfStr(s string, strs []string, eq func(a, b string) bool) int {
-	for i, t := range strs {
-		if eq(s, t) {
-			return i
-		}
-	}
-	return -1
-}
-
-// escFnsEq reports whether the two escaping functions are equivalent.
-func escFnsEq(a, b string) bool {
-	if e := equivEscapers[a]; e != "" {
-		a = e
-	}
-	if e := equivEscapers[b]; e != "" {
-		b = e
-	}
-	return a == b
-}
-
-// newIdentCmd produces a command containing a single identifier node.
-func newIdentCmd(identifier string, pos parse.Pos) *parse.CommandNode {
-	return &parse.CommandNode{
-		NodeType: parse.NodeCommand,
-		Args:     []parse.Node{parse.NewIdentifier(identifier).SetPos(pos)},
-	}
-}
-
-// nudge returns the context that would result from following empty string
-// transitions from the input context.
-// For example, parsing:
-//     `<a href=`
-// will end in context{stateBeforeValue, attrURL}, but parsing one extra rune:
-//     `<a href=x`
-// will end in context{stateURL, delimSpaceOrTagEnd, ...}.
-// There are two transitions that happen when the 'x' is seen:
-// (1) Transition from a before-value state to a start-of-value state without
-//     consuming any character.
-// (2) Consume 'x' and transition past the first value character.
-// In this case, nudging produces the context after (1) happens.
-func nudge(c context) context {
-	switch c.state {
-	case stateTag:
-		// In `<foo {{.}}`, the action should emit an attribute.
-		c.state = stateAttrName
-	case stateBeforeValue:
-		// In `<foo bar={{.}}`, the action is an undelimited value.
-		c.state, c.delim, c.attr = attrStartStates[c.attr], delimSpaceOrTagEnd, attrNone
-	case stateAfterName:
-		// In `<foo bar {{.}}`, the action is an attribute name.
-		c.state, c.attr = stateAttrName, attrNone
-	}
-	return c
-}
-
-// join joins the two contexts of a branch template node. The result is an
-// error context if either of the input contexts are error contexts, or if the
-// the input contexts differ.
-func join(a, b context, line int, nodeName string) context {
-	if a.state == stateError {
-		return a
-	}
-	if b.state == stateError {
-		return b
-	}
-	if a.eq(b) {
-		return a
-	}
-
-	c := a
-	c.urlPart = b.urlPart
-	if c.eq(b) {
-		// The contexts differ only by urlPart.
-		c.urlPart = urlPartUnknown
-		return c
-	}
-
-	c = a
-	c.jsCtx = b.jsCtx
-	if c.eq(b) {
-		// The contexts differ only by jsCtx.
-		c.jsCtx = jsCtxUnknown
-		return c
-	}
-
-	// Allow a nudged context to join with an unnudged one.
-	// This means that
-	//   <p title={{if .C}}{{.}}{{end}}
-	// ends in an unquoted value state even though the else branch
-	// ends in stateBeforeValue.
-	if c, d := nudge(a), nudge(b); !(c.eq(a) && d.eq(b)) {
-		if e := join(c, d, line, nodeName); e.state != stateError {
-			return e
-		}
-	}
-
-	return context{
-		state: stateError,
-		err:   errorf(ErrBranchEnd, line, "{{%s}} branches end in different contexts: %v, %v", nodeName, a, b),
-	}
-}
-
-// escapeBranch escapes a branch template node: "if", "range" and "with".
-func (e *escaper) escapeBranch(c context, n *parse.BranchNode, nodeName string) context {
-	c0 := e.escapeList(c, n.List)
-	if nodeName == "range" && c0.state != stateError {
-		// The "true" branch of a "range" node can execute multiple times.
-		// We check that executing n.List once results in the same context
-		// as executing n.List twice.
-		c1, _ := e.escapeListConditionally(c0, n.List, nil)
-		c0 = join(c0, c1, n.Line, nodeName)
-		if c0.state == stateError {
-			// Make clear that this is a problem on loop re-entry
-			// since developers tend to overlook that branch when
-			// debugging templates.
-			c0.err.Line = n.Line
-			c0.err.Description = "on range loop re-entry: " + c0.err.Description
-			return c0
-		}
-	}
-	c1 := e.escapeList(c, n.ElseList)
-	return join(c0, c1, n.Line, nodeName)
-}
-
-// escapeList escapes a list template node.
-func (e *escaper) escapeList(c context, n *parse.ListNode) context {
-	if n == nil {
-		return c
-	}
-	for _, m := range n.Nodes {
-		c = e.escape(c, m)
-	}
-	return c
-}
-
-// escapeListConditionally escapes a list node but only preserves edits and
-// inferences in e if the inferences and output context satisfy filter.
-// It returns the best guess at an output context, and the result of the filter
-// which is the same as whether e was updated.
-func (e *escaper) escapeListConditionally(c context, n *parse.ListNode, filter func(*escaper, context) bool) (context, bool) {
-	e1 := newEscaper(e.tmpl)
-	// Make type inferences available to f.
-	for k, v := range e.output {
-		e1.output[k] = v
-	}
-	c = e1.escapeList(c, n)
-	ok := filter != nil && filter(e1, c)
-	if ok {
-		// Copy inferences and edits from e1 back into e.
-		for k, v := range e1.output {
-			e.output[k] = v
-		}
-		for k, v := range e1.derived {
-			e.derived[k] = v
-		}
-		for k, v := range e1.called {
-			e.called[k] = v
-		}
-		for k, v := range e1.actionNodeEdits {
-			e.editActionNode(k, v)
-		}
-		for k, v := range e1.templateNodeEdits {
-			e.editTemplateNode(k, v)
-		}
-		for k, v := range e1.textNodeEdits {
-			e.editTextNode(k, v)
-		}
-	}
-	return c, ok
-}
-
-// escapeTemplate escapes a {{template}} call node.
-func (e *escaper) escapeTemplate(c context, n *parse.TemplateNode) context {
-	c, name := e.escapeTree(c, n.Name, n.Line)
-	if name != n.Name {
-		e.editTemplateNode(n, name)
-	}
-	return c
-}
-
-// escapeTree escapes the named template starting in the given context as
-// necessary and returns its output context.
-func (e *escaper) escapeTree(c context, name string, line int) (context, string) {
-	// Mangle the template name with the input context to produce a reliable
-	// identifier.
-	dname := c.mangle(name)
-	e.called[dname] = true
-	if out, ok := e.output[dname]; ok {
-		// Already escaped.
-		return out, dname
-	}
-	t := e.template(name)
-	if t == nil {
-		// Two cases: The template exists but is empty, or has never been mentioned at
-		// all. Distinguish the cases in the error messages.
-		if e.tmpl.set[name] != nil {
-			return context{
-				state: stateError,
-				err:   errorf(ErrNoSuchTemplate, line, "%q is an incomplete or empty template", name),
-			}, dname
-		}
-		return context{
-			state: stateError,
-			err:   errorf(ErrNoSuchTemplate, line, "no such template %q", name),
-		}, dname
-	}
-	if dname != name {
-		// Use any template derived during an earlier call to escapeTemplate
-		// with different top level templates, or clone if necessary.
-		dt := e.template(dname)
-		if dt == nil {
-			dt = template.New(dname)
-			dt.Tree = &parse.Tree{Name: dname, Root: t.Root.CopyList()}
-			e.derived[dname] = dt
-		}
-		t = dt
-	}
-	return e.computeOutCtx(c, t), dname
-}
-
-// computeOutCtx takes a template and its start context and computes the output
-// context while storing any inferences in e.
-func (e *escaper) computeOutCtx(c context, t *template.Template) context {
-	// Propagate context over the body.
-	c1, ok := e.escapeTemplateBody(c, t)
-	if !ok {
-		// Look for a fixed point by assuming c1 as the output context.
-		if c2, ok2 := e.escapeTemplateBody(c1, t); ok2 {
-			c1, ok = c2, true
-		}
-		// Use c1 as the error context if neither assumption worked.
-	}
-	if !ok && c1.state != stateError {
-		return context{
-			state: stateError,
-			// TODO: Find the first node with a line in t.text.Tree.Root
-			err: errorf(ErrOutputContext, 0, "cannot compute output context for template %s", t.Name()),
-		}
-	}
-	return c1
-}
-
-// escapeTemplateBody escapes the given template assuming the given output
-// context, and returns the best guess at the output context and whether the
-// assumption was correct.
-func (e *escaper) escapeTemplateBody(c context, t *template.Template) (context, bool) {
-	filter := func(e1 *escaper, c1 context) bool {
-		if c1.state == stateError {
-			// Do not update the input escaper, e.
-			return false
-		}
-		if !e1.called[t.Name()] {
-			// If t is not recursively called, then c1 is an
-			// accurate output context.
-			return true
-		}
-		// c1 is accurate if it matches our assumed output context.
-		return c.eq(c1)
-	}
-	// We need to assume an output context so that recursive template calls
-	// take the fast path out of escapeTree instead of infinitely recursing.
-	// Naively assuming that the input context is the same as the output
-	// works >90% of the time.
-	e.output[t.Name()] = c
-	return e.escapeListConditionally(c, t.Tree.Root, filter)
-}
-
-// delimEnds maps each delim to a string of characters that terminate it.
-var delimEnds = [...]string{
-	delimDoubleQuote: `"`,
-	delimSingleQuote: "'",
-	// Determined empirically by running the below in various browsers.
-	// var div = document.createElement("DIV");
-	// for (var i = 0; i < 0x10000; ++i) {
-	//   div.innerHTML = "<span title=x" + String.fromCharCode(i) + "-bar>";
-	//   if (div.getElementsByTagName("SPAN")[0].title.indexOf("bar") < 0)
-	//     document.write("<p>U+" + i.toString(16));
-	// }
-	delimSpaceOrTagEnd: " \t\n\f\r>",
-}
-
-var doctypeBytes = []byte("<!DOCTYPE")
-
-// escapeText escapes a text template node.
-func (e *escaper) escapeText(c context, n *parse.TextNode) context {
-	s, written, i, b := n.Text, 0, 0, new(bytes.Buffer)
-	for i != len(s) {
-		c1, nread := contextAfterText(c, s[i:])
-		i1 := i + nread
-		if c.state == stateText || c.state == stateRCDATA {
-			end := i1
-			if c1.state != c.state {
-				for j := end - 1; j >= i; j-- {
-					if s[j] == '<' {
-						end = j
-						break
-					}
-				}
-			}
-			for j := i; j < end; j++ {
-				if s[j] == '<' && !bytes.HasPrefix(bytes.ToUpper(s[j:]), doctypeBytes) {
-					b.Write(s[written:j])
-					b.WriteString("<")
-					written = j + 1
-				}
-			}
-		} else if isComment(c.state) && c.delim == delimNone {
-			switch c.state {
-			case stateJSBlockCmt:
-				// http://es5.github.com/#x7.4:
-				// "Comments behave like white space and are
-				// discarded except that, if a MultiLineComment
-				// contains a line terminator character, then
-				// the entire comment is considered to be a
-				// LineTerminator for purposes of parsing by
-				// the syntactic grammar."
-				if bytes.IndexAny(s[written:i1], "\n\r\u2028\u2029") != -1 {
-					b.WriteByte('\n')
-				} else {
-					b.WriteByte(' ')
-				}
-			case stateCSSBlockCmt:
-				b.WriteByte(' ')
-			}
-			written = i1
-		}
-		if c.state != c1.state && isComment(c1.state) && c1.delim == delimNone {
-			// Preserve the portion between written and the comment start.
-			cs := i1 - 2
-			if c1.state == stateHTMLCmt {
-				// "<!--" instead of "/*" or "//"
-				cs -= 2
-			}
-			b.Write(s[written:cs])
-			written = i1
-		}
-		if i == i1 && c.state == c1.state {
-			panic(fmt.Sprintf("infinite loop from %v to %v on %q..%q", c, c1, s[:i], s[i:]))
-		}
-		c, i = c1, i1
-	}
-
-	if written != 0 && c.state != stateError {
-		if !isComment(c.state) || c.delim != delimNone {
-			b.Write(n.Text[written:])
-		}
-		e.editTextNode(n, b.Bytes())
-	}
-	return c
-}
-
-// contextAfterText starts in context c, consumes some tokens from the front of
-// s, then returns the context after those tokens and the unprocessed suffix.
-func contextAfterText(c context, s []byte) (context, int) {
-	if c.delim == delimNone {
-		c1, i := tSpecialTagEnd(c, s)
-		if i == 0 {
-			// A special end tag (`</script>`) has been seen and
-			// all content preceding it has been consumed.
-			return c1, 0
-		}
-		// Consider all content up to any end tag.
-		return transitionFunc[c.state](c, s[:i])
-	}
-
-	i := bytes.IndexAny(s, delimEnds[c.delim])
-	if i == -1 {
-		i = len(s)
-	}
-	if c.delim == delimSpaceOrTagEnd {
-		// http://www.w3.org/TR/html5/syntax.html#attribute-value-(unquoted)-state
-		// lists the runes below as error characters.
-		// Error out because HTML parsers may differ on whether
-		// "<a id= onclick=f("     ends inside id's or onclick's value,
-		// "<a class=`foo "        ends inside a value,
-		// "<a style=font:'Arial'" needs open-quote fixup.
-		// IE treats '`' as a quotation character.
-		if j := bytes.IndexAny(s[:i], "\"'<=`"); j >= 0 {
-			return context{
-				state: stateError,
-				err:   errorf(ErrBadHTML, 0, "%q in unquoted attr: %q", s[j:j+1], s[:i]),
-			}, len(s)
-		}
-	}
-	if i == len(s) {
-		// Remain inside the attribute.
-		// Decode the value so non-HTML rules can easily handle
-		//     <button onclick="alert("Hi!")">
-		// without having to entity decode token boundaries.
-		for u := []byte(html.UnescapeString(string(s))); len(u) != 0; {
-			c1, i1 := transitionFunc[c.state](c, u)
-			c, u = c1, u[i1:]
-		}
-		return c, len(s)
-	}
-	if c.delim != delimSpaceOrTagEnd {
-		// Consume any quote.
-		i++
-	}
-	// On exiting an attribute, we discard all state information
-	// except the state and element.
-	return context{state: stateTag, element: c.element}, i
-}
-
-// editActionNode records a change to an action pipeline for later commit.
-func (e *escaper) editActionNode(n *parse.ActionNode, cmds []string) {
-	if _, ok := e.actionNodeEdits[n]; ok {
-		panic(fmt.Sprintf("node %s shared between templates", n))
-	}
-	e.actionNodeEdits[n] = cmds
-}
-
-// editTemplateNode records a change to a {{template}} callee for later commit.
-func (e *escaper) editTemplateNode(n *parse.TemplateNode, callee string) {
-	if _, ok := e.templateNodeEdits[n]; ok {
-		panic(fmt.Sprintf("node %s shared between templates", n))
-	}
-	e.templateNodeEdits[n] = callee
-}
-
-// editTextNode records a change to a text node for later commit.
-func (e *escaper) editTextNode(n *parse.TextNode, text []byte) {
-	if _, ok := e.textNodeEdits[n]; ok {
-		panic(fmt.Sprintf("node %s shared between templates", n))
-	}
-	e.textNodeEdits[n] = text
-}
-
-// commit applies changes to actions and template calls needed to contextually
-// autoescape content and adds any derived templates to the set.
-func (e *escaper) commit() {
-	for name := range e.output {
-		e.template(name).Funcs(funcMap)
-	}
-	for _, t := range e.derived {
-		if _, err := e.tmpl.text.AddParseTree(t.Name(), t.Tree); err != nil {
-			panic("error adding derived template")
-		}
-	}
-	for n, s := range e.actionNodeEdits {
-		ensurePipelineContains(n.Pipe, s)
-	}
-	for n, name := range e.templateNodeEdits {
-		n.Name = name
-	}
-	for n, s := range e.textNodeEdits {
-		n.Text = s
-	}
-}
-
-// template returns the named template given a mangled template name.
-func (e *escaper) template(name string) *template.Template {
-	t := e.tmpl.text.Lookup(name)
-	if t == nil {
-		t = e.derived[name]
-	}
-	return t
-}
-
-// Forwarding functions so that clients need only import this package
-// to reach the general escaping functions of text/template.
-
-// HTMLEscape writes to w the escaped HTML equivalent of the plain text data b.
-func HTMLEscape(w io.Writer, b []byte) {
-	template.HTMLEscape(w, b)
-}
-
-// HTMLEscapeString returns the escaped HTML equivalent of the plain text data s.
-func HTMLEscapeString(s string) string {
-	return template.HTMLEscapeString(s)
-}
-
-// HTMLEscaper returns the escaped HTML equivalent of the textual
-// representation of its arguments.
-func HTMLEscaper(args ...interface{}) string {
-	return template.HTMLEscaper(args...)
-}
-
-// JSEscape writes to w the escaped JavaScript equivalent of the plain text data b.
-func JSEscape(w io.Writer, b []byte) {
-	template.JSEscape(w, b)
-}
-
-// JSEscapeString returns the escaped JavaScript equivalent of the plain text data s.
-func JSEscapeString(s string) string {
-	return template.JSEscapeString(s)
-}
-
-// JSEscaper returns the escaped JavaScript equivalent of the textual
-// representation of its arguments.
-func JSEscaper(args ...interface{}) string {
-	return template.JSEscaper(args...)
-}
-
-// URLQueryEscaper returns the escaped value of the textual representation of
-// its arguments in a form suitable for embedding in a URL query.
-func URLQueryEscaper(args ...interface{}) string {
-	return template.URLQueryEscaper(args...)
-}
diff --git a/src/pkg/html/template/escape_test.go b/src/pkg/html/template/escape_test.go
deleted file mode 100644
index 3ccf93e..0000000
--- a/src/pkg/html/template/escape_test.go
+++ /dev/null
@@ -1,1692 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package template
-
-import (
-	"bytes"
-	"encoding/json"
-	"fmt"
-	"os"
-	"strings"
-	"testing"
-	"text/template"
-	"text/template/parse"
-)
-
-type badMarshaler struct{}
-
-func (x *badMarshaler) MarshalJSON() ([]byte, error) {
-	// Keys in valid JSON must be double quoted as must all strings.
-	return []byte("{ foo: 'not quite valid JSON' }"), nil
-}
-
-type goodMarshaler struct{}
-
-func (x *goodMarshaler) MarshalJSON() ([]byte, error) {
-	return []byte(`{ "<foo>": "O'Reilly" }`), nil
-}
-
-func TestEscape(t *testing.T) {
-	data := struct {
-		F, T    bool
-		C, G, H string
-		A, E    []string
-		B, M    json.Marshaler
-		N       int
-		Z       *int
-		W       HTML
-	}{
-		F: false,
-		T: true,
-		C: "<Cincinatti>",
-		G: "<Goodbye>",
-		H: "<Hello>",
-		A: []string{"<a>", "<b>"},
-		E: []string{},
-		N: 42,
-		B: &badMarshaler{},
-		M: &goodMarshaler{},
-		Z: nil,
-		W: HTML(`¡<b class="foo">Hello</b>, <textarea>O'World</textarea>!`),
-	}
-	pdata := &data
-
-	tests := []struct {
-		name   string
-		input  string
-		output string
-	}{
-		{
-			"if",
-			"{{if .T}}Hello{{end}}, {{.C}}!",
-			"Hello, <Cincinatti>!",
-		},
-		{
-			"else",
-			"{{if .F}}{{.H}}{{else}}{{.G}}{{end}}!",
-			"<Goodbye>!",
-		},
-		{
-			"overescaping1",
-			"Hello, {{.C | html}}!",
-			"Hello, <Cincinatti>!",
-		},
-		{
-			"overescaping2",
-			"Hello, {{html .C}}!",
-			"Hello, <Cincinatti>!",
-		},
-		{
-			"overescaping3",
-			"{{with .C}}{{$msg := .}}Hello, {{$msg}}!{{end}}",
-			"Hello, <Cincinatti>!",
-		},
-		{
-			"assignment",
-			"{{if $x := .H}}{{$x}}{{end}}",
-			"<Hello>",
-		},
-		{
-			"withBody",
-			"{{with .H}}{{.}}{{end}}",
-			"<Hello>",
-		},
-		{
-			"withElse",
-			"{{with .E}}{{.}}{{else}}{{.H}}{{end}}",
-			"<Hello>",
-		},
-		{
-			"rangeBody",
-			"{{range .A}}{{.}}{{end}}",
-			"<a><b>",
-		},
-		{
-			"rangeElse",
-			"{{range .E}}{{.}}{{else}}{{.H}}{{end}}",
-			"<Hello>",
-		},
-		{
-			"nonStringValue",
-			"{{.T}}",
-			"true",
-		},
-		{
-			"constant",
-			`<a href="/search?q={{"'a<b'"}}">`,
-			`<a href="/search?q=%27a%3cb%27">`,
-		},
-		{
-			"multipleAttrs",
-			"<a b=1 c={{.H}}>",
-			"<a b=1 c=<Hello>>",
-		},
-		{
-			"urlStartRel",
-			`<a href='{{"/foo/bar?a=b&c=d"}}'>`,
-			`<a href='/foo/bar?a=b&c=d'>`,
-		},
-		{
-			"urlStartAbsOk",
-			`<a href='{{"http://example.com/foo/bar?a=b&c=d"}}'>`,
-			`<a href='http://example.com/foo/bar?a=b&c=d'>`,
-		},
-		{
-			"protocolRelativeURLStart",
-			`<a href='{{"//example.com:8000/foo/bar?a=b&c=d"}}'>`,
-			`<a href='//example.com:8000/foo/bar?a=b&c=d'>`,
-		},
-		{
-			"pathRelativeURLStart",
-			`<a href="{{"/javascript:80/foo/bar"}}">`,
-			`<a href="/javascript:80/foo/bar">`,
-		},
-		{
-			"dangerousURLStart",
-			`<a href='{{"javascript:alert(%22pwned%22)"}}'>`,
-			`<a href='#ZgotmplZ'>`,
-		},
-		{
-			"dangerousURLStart2",
-			`<a href='  {{"javascript:alert(%22pwned%22)"}}'>`,
-			`<a href='  #ZgotmplZ'>`,
-		},
-		{
-			"nonHierURL",
-			`<a href={{"mailto:Muhammed \"The Greatest\" Ali <m.ali at example.com>"}}>`,
-			`<a href=mailto:Muhammed%20%22The%20Greatest%22%20Ali%20%3cm.ali at example.com%3e>`,
-		},
-		{
-			"urlPath",
-			`<a href='http://{{"javascript:80"}}/foo'>`,
-			`<a href='http://javascript:80/foo'>`,
-		},
-		{
-			"urlQuery",
-			`<a href='/search?q={{.H}}'>`,
-			`<a href='/search?q=%3cHello%3e'>`,
-		},
-		{
-			"urlFragment",
-			`<a href='/faq#{{.H}}'>`,
-			`<a href='/faq#%3cHello%3e'>`,
-		},
-		{
-			"urlBranch",
-			`<a href="{{if .F}}/foo?a=b{{else}}/bar{{end}}">`,
-			`<a href="/bar">`,
-		},
-		{
-			"urlBranchConflictMoot",
-			`<a href="{{if .T}}/foo?a={{else}}/bar#{{end}}{{.C}}">`,
-			`<a href="/foo?a=%3cCincinatti%3e">`,
-		},
-		{
-			"jsStrValue",
-			"<button onclick='alert({{.H}})'>",
-			`<button onclick='alert("\u003cHello\u003e")'>`,
-		},
-		{
-			"jsNumericValue",
-			"<button onclick='alert({{.N}})'>",
-			`<button onclick='alert( 42 )'>`,
-		},
-		{
-			"jsBoolValue",
-			"<button onclick='alert({{.T}})'>",
-			`<button onclick='alert( true )'>`,
-		},
-		{
-			"jsNilValue",
-			"<button onclick='alert(typeof{{.Z}})'>",
-			`<button onclick='alert(typeof null )'>`,
-		},
-		{
-			"jsObjValue",
-			"<button onclick='alert({{.A}})'>",
-			`<button onclick='alert(["\u003ca\u003e","\u003cb\u003e"])'>`,
-		},
-		{
-			"jsObjValueScript",
-			"<script>alert({{.A}})</script>",
-			`<script>alert(["\u003ca\u003e","\u003cb\u003e"])</script>`,
-		},
-		{
-			"jsObjValueNotOverEscaped",
-			"<button onclick='alert({{.A | html}})'>",
-			`<button onclick='alert(["\u003ca\u003e","\u003cb\u003e"])'>`,
-		},
-		{
-			"jsStr",
-			"<button onclick='alert("{{.H}}")'>",
-			`<button onclick='alert("\x3cHello\x3e")'>`,
-		},
-		{
-			"badMarshaler",
-			`<button onclick='alert(1/{{.B}}in numbers)'>`,
-			`<button onclick='alert(1/ /* json: error calling MarshalJSON for type *template.badMarshaler: invalid character 'f' looking for beginning of object key string */null in numbers)'>`,
-		},
-		{
-			"jsMarshaler",
-			`<button onclick='alert({{.M}})'>`,
-			`<button onclick='alert({"\u003cfoo\u003e":"O'Reilly"})'>`,
-		},
-		{
-			"jsStrNotUnderEscaped",
-			"<button onclick='alert({{.C | urlquery}})'>",
-			// URL escaped, then quoted for JS.
-			`<button onclick='alert("%3CCincinatti%3E")'>`,
-		},
-		{
-			"jsRe",
-			`<button onclick='alert(/{{"foo+bar"}}/.test(""))'>`,
-			`<button onclick='alert(/foo\x2bbar/.test(""))'>`,
-		},
-		{
-			"jsReBlank",
-			`<script>alert(/{{""}}/.test(""));</script>`,
-			`<script>alert(/(?:)/.test(""));</script>`,
-		},
-		{
-			"jsReAmbigOk",
-			`<script>{{if true}}var x = 1{{end}}</script>`,
-			// The {if} ends in an ambiguous jsCtx but there is
-			// no slash following so we shouldn't care.
-			`<script>var x = 1</script>`,
-		},
-		{
-			"styleBidiKeywordPassed",
-			`<p style="dir: {{"ltr"}}">`,
-			`<p style="dir: ltr">`,
-		},
-		{
-			"styleBidiPropNamePassed",
-			`<p style="border-{{"left"}}: 0; border-{{"right"}}: 1in">`,
-			`<p style="border-left: 0; border-right: 1in">`,
-		},
-		{
-			"styleExpressionBlocked",
-			`<p style="width: {{"expression(alert(1337))"}}">`,
-			`<p style="width: ZgotmplZ">`,
-		},
-		{
-			"styleTagSelectorPassed",
-			`<style>{{"p"}} { color: pink }</style>`,
-			`<style>p { color: pink }</style>`,
-		},
-		{
-			"styleIDPassed",
-			`<style>p{{"#my-ID"}} { font: Arial }</style>`,
-			`<style>p#my-ID { font: Arial }</style>`,
-		},
-		{
-			"styleClassPassed",
-			`<style>p{{".my_class"}} { font: Arial }</style>`,
-			`<style>p.my_class { font: Arial }</style>`,
-		},
-		{
-			"styleQuantityPassed",
-			`<a style="left: {{"2em"}}; top: {{0}}">`,
-			`<a style="left: 2em; top: 0">`,
-		},
-		{
-			"stylePctPassed",
-			`<table style=width:{{"100%"}}>`,
-			`<table style=width:100%>`,
-		},
-		{
-			"styleColorPassed",
-			`<p style="color: {{"#8ff"}}; background: {{"#000"}}">`,
-			`<p style="color: #8ff; background: #000">`,
-		},
-		{
-			"styleObfuscatedExpressionBlocked",
-			`<p style="width: {{"  e\\78preS\x00Sio/**/n(alert(1337))"}}">`,
-			`<p style="width: ZgotmplZ">`,
-		},
-		{
-			"styleMozBindingBlocked",
-			`<p style="{{"-moz-binding(alert(1337))"}}: ...">`,
-			`<p style="ZgotmplZ: ...">`,
-		},
-		{
-			"styleObfuscatedMozBindingBlocked",
-			`<p style="{{"  -mo\\7a-B\x00I/**/nding(alert(1337))"}}: ...">`,
-			`<p style="ZgotmplZ: ...">`,
-		},
-		{
-			"styleFontNameString",
-			`<p style='font-family: "{{"Times New Roman"}}"'>`,
-			`<p style='font-family: "Times New Roman"'>`,
-		},
-		{
-			"styleFontNameString",
-			`<p style='font-family: "{{"Times New Roman"}}", "{{"sans-serif"}}"'>`,
-			`<p style='font-family: "Times New Roman", "sans-serif"'>`,
-		},
-		{
-			"styleFontNameUnquoted",
-			`<p style='font-family: {{"Times New Roman"}}'>`,
-			`<p style='font-family: Times New Roman'>`,
-		},
-		{
-			"styleURLQueryEncoded",
-			`<p style="background: url(/img?name={{"O'Reilly Animal(1)<2>.png"}})">`,
-			`<p style="background: url(/img?name=O%27Reilly%20Animal%281%29%3c2%3e.png)">`,
-		},
-		{
-			"styleQuotedURLQueryEncoded",
-			`<p style="background: url('/img?name={{"O'Reilly Animal(1)<2>.png"}}')">`,
-			`<p style="background: url('/img?name=O%27Reilly%20Animal%281%29%3c2%3e.png')">`,
-		},
-		{
-			"styleStrQueryEncoded",
-			`<p style="background: '/img?name={{"O'Reilly Animal(1)<2>.png"}}'">`,
-			`<p style="background: '/img?name=O%27Reilly%20Animal%281%29%3c2%3e.png'">`,
-		},
-		{
-			"styleURLBadProtocolBlocked",
-			`<a style="background: url('{{"javascript:alert(1337)"}}')">`,
-			`<a style="background: url('#ZgotmplZ')">`,
-		},
-		{
-			"styleStrBadProtocolBlocked",
-			`<a style="background: '{{"vbscript:alert(1337)"}}'">`,
-			`<a style="background: '#ZgotmplZ'">`,
-		},
-		{
-			"styleStrEncodedProtocolEncoded",
-			`<a style="background: '{{"javascript\\3a alert(1337)"}}'">`,
-			// The CSS string 'javascript\\3a alert(1337)' does not contains a colon.
-			`<a style="background: 'javascript\\3a alert\28 1337\29 '">`,
-		},
-		{
-			"styleURLGoodProtocolPassed",
-			`<a style="background: url('{{"http://oreilly.com/O'Reilly Animals(1)<2>;{}.html"}}')">`,
-			`<a style="background: url('http://oreilly.com/O%27Reilly%20Animals%281%29%3c2%3e;%7b%7d.html')">`,
-		},
-		{
-			"styleStrGoodProtocolPassed",
-			`<a style="background: '{{"http://oreilly.com/O'Reilly Animals(1)<2>;{}.html"}}'">`,
-			`<a style="background: 'http\3a\2f\2foreilly.com\2fO\27Reilly Animals\28 1\29\3c 2\3e\3b\7b\7d.html'">`,
-		},
-		{
-			"styleURLEncodedForHTMLInAttr",
-			`<a style="background: url('{{"/search?img=foo&size=icon"}}')">`,
-			`<a style="background: url('/search?img=foo&size=icon')">`,
-		},
-		{
-			"styleURLNotEncodedForHTMLInCdata",
-			`<style>body { background: url('{{"/search?img=foo&size=icon"}}') }</style>`,
-			`<style>body { background: url('/search?img=foo&size=icon') }</style>`,
-		},
-		{
-			"styleURLMixedCase",
-			`<p style="background: URL(#{{.H}})">`,
-			`<p style="background: URL(#%3cHello%3e)">`,
-		},
-		{
-			"stylePropertyPairPassed",
-			`<a style='{{"color: red"}}'>`,
-			`<a style='color: red'>`,
-		},
-		{
-			"styleStrSpecialsEncoded",
-			`<a style="font-family: '{{"/**/'\";:// \\"}}', "{{"/**/'\";:// \\"}}"">`,
-			`<a style="font-family: '\2f**\2f\27\22\3b\3a\2f\2f  \\', "\2f**\2f\27\22\3b\3a\2f\2f  \\"">`,
-		},
-		{
-			"styleURLSpecialsEncoded",
-			`<a style="border-image: url({{"/**/'\";:// \\"}}), url("{{"/**/'\";:// \\"}}"), url('{{"/**/'\";:// \\"}}'), 'http://www.example.com/?q={{"/**/'\";:// \\"}}''">`,
-			`<a style="border-image: url(/**/%27%22;://%20%5c), url("/**/%27%22;://%20%5c"), url('/**/%27%22;://%20%5c'), 'http://www.example.com/?q=%2f%2a%2a%2f%27%22%3b%3a%2f%2f%20%5c''">`,
-		},
-		{
-			"HTML comment",
-			"<b>Hello, <!-- name of world -->{{.C}}</b>",
-			"<b>Hello, <Cincinatti></b>",
-		},
-		{
-			"HTML comment not first < in text node.",
-			"<<!-- -->!--",
-			"<!--",
-		},
-		{
-			"HTML normalization 1",
-			"a < b",
-			"a < b",
-		},
-		{
-			"HTML normalization 2",
-			"a << b",
-			"a << b",
-		},
-		{
-			"HTML normalization 3",
-			"a<<!-- --><!-- -->b",
-			"a<b",
-		},
-		{
-			"HTML doctype not normalized",
-			"<!DOCTYPE html>Hello, World!",
-			"<!DOCTYPE html>Hello, World!",
-		},
-		{
-			"HTML doctype not case-insensitive",
-			"<!doCtYPE htMl>Hello, World!",
-			"<!doCtYPE htMl>Hello, World!",
-		},
-		{
-			"No doctype injection",
-			`<!{{"DOCTYPE"}}`,
-			"<!DOCTYPE",
-		},
-		{
-			"Split HTML comment",
-			"<b>Hello, <!-- name of {{if .T}}city -->{{.C}}{{else}}world -->{{.W}}{{end}}</b>",
-			"<b>Hello, <Cincinatti></b>",
-		},
-		{
-			"JS line comment",
-			"<script>for (;;) { if (c()) break// foo not a label\n" +
-				"foo({{.T}});}</script>",
-			"<script>for (;;) { if (c()) break\n" +
-				"foo( true );}</script>",
-		},
-		{
-			"JS multiline block comment",
-			"<script>for (;;) { if (c()) break/* foo not a label\n" +
-				" */foo({{.T}});}</script>",
-			// Newline separates break from call. If newline
-			// removed, then break will consume label leaving
-			// code invalid.
-			"<script>for (;;) { if (c()) break\n" +
-				"foo( true );}</script>",
-		},
-		{
-			"JS single-line block comment",
-			"<script>for (;;) {\n" +
-				"if (c()) break/* foo a label */foo;" +
-				"x({{.T}});}</script>",
-			// Newline separates break from call. If newline
-			// removed, then break will consume label leaving
-			// code invalid.
-			"<script>for (;;) {\n" +
-				"if (c()) break foo;" +
-				"x( true );}</script>",
-		},
-		{
-			"JS block comment flush with mathematical division",
-			"<script>var a/*b*//c\nd</script>",
-			"<script>var a /c\nd</script>",
-		},
-		{
-			"JS mixed comments",
-			"<script>var a/*b*///c\nd</script>",
-			"<script>var a \nd</script>",
-		},
-		{
-			"CSS comments",
-			"<style>p// paragraph\n" +
-				`{border: 1px/* color */{{"#00f"}}}</style>`,
-			"<style>p\n" +
-				"{border: 1px #00f}</style>",
-		},
-		{
-			"JS attr block comment",
-			`<a onclick="f(""); /* alert({{.H}}) */">`,
-			// Attribute comment tests should pass if the comments
-			// are successfully elided.
-			`<a onclick="f(""); /* alert() */">`,
-		},
-		{
-			"JS attr line comment",
-			`<a onclick="// alert({{.G}})">`,
-			`<a onclick="// alert()">`,
-		},
-		{
-			"CSS attr block comment",
-			`<a style="/* color: {{.H}} */">`,
-			`<a style="/* color:  */">`,
-		},
-		{
-			"CSS attr line comment",
-			`<a style="// color: {{.G}}">`,
-			`<a style="// color: ">`,
-		},
-		{
-			"HTML substitution commented out",
-			"<p><!-- {{.H}} --></p>",
-			"<p></p>",
-		},
-		{
-			"Comment ends flush with start",
-			"<!--{{.}}--><script>/*{{.}}*///{{.}}\n</script><style>/*{{.}}*///{{.}}\n</style><a onclick='/*{{.}}*///{{.}}' style='/*{{.}}*///{{.}}'>",
-			"<script> \n</script><style> \n</style><a onclick='/**///' style='/**///'>",
-		},
-		{
-			"typed HTML in text",
-			`{{.W}}`,
-			`¡<b class="foo">Hello</b>, <textarea>O'World</textarea>!`,
-		},
-		{
-			"typed HTML in attribute",
-			`<div title="{{.W}}">`,
-			`<div title="¡Hello, O'World!">`,
-		},
-		{
-			"typed HTML in script",
-			`<button onclick="alert({{.W}})">`,
-			`<button onclick="alert("\u0026iexcl;\u003cb class=\"foo\"\u003eHello\u003c/b\u003e, \u003ctextarea\u003eO'World\u003c/textarea\u003e!")">`,
-		},
-		{
-			"typed HTML in RCDATA",
-			`<textarea>{{.W}}</textarea>`,
-			`<textarea>¡<b class="foo">Hello</b>, <textarea>O'World</textarea>!</textarea>`,
-		},
-		{
-			"range in textarea",
-			"<textarea>{{range .A}}{{.}}{{end}}</textarea>",
-			"<textarea><a><b></textarea>",
-		},
-		{
-			"No tag injection",
-			`{{"10$"}}<{{"script src,evil.org/pwnd.js"}}...`,
-			`10$<script src,evil.org/pwnd.js...`,
-		},
-		{
-			"No comment injection",
-			`<{{"!--"}}`,
-			`<!--`,
-		},
-		{
-			"No RCDATA end tag injection",
-			`<textarea><{{"/textarea "}}...</textarea>`,
-			`<textarea></textarea ...</textarea>`,
-		},
-		{
-			"optional attrs",
-			`<img class="{{"iconClass"}}"` +
-				`{{if .T}} id="{{"<iconId>"}}"{{end}}` +
-				// Double quotes inside if/else.
-				` src=` +
-				`{{if .T}}"?{{"<iconPath>"}}"` +
-				`{{else}}"images/cleardot.gif"{{end}}` +
-				// Missing space before title, but it is not a
-				// part of the src attribute.
-				`{{if .T}}title="{{"<title>"}}"{{end}}` +
-				// Quotes outside if/else.
-				` alt="` +
-				`{{if .T}}{{"<alt>"}}` +
-				`{{else}}{{if .F}}{{"<title>"}}{{end}}` +
-				`{{end}}"` +
-				`>`,
-			`<img class="iconClass" id="<iconId>" src="?%3ciconPath%3e"title="<title>" alt="<alt>">`,
-		},
-		{
-			"conditional valueless attr name",
-			`<input{{if .T}} checked{{end}} name=n>`,
-			`<input checked name=n>`,
-		},
-		{
-			"conditional dynamic valueless attr name 1",
-			`<input{{if .T}} {{"checked"}}{{end}} name=n>`,
-			`<input checked name=n>`,
-		},
-		{
-			"conditional dynamic valueless attr name 2",
-			`<input {{if .T}}{{"checked"}} {{end}}name=n>`,
-			`<input checked name=n>`,
-		},
-		{
-			"dynamic attribute name",
-			`<img on{{"load"}}="alert({{"loaded"}})">`,
-			// Treated as JS since quotes are inserted.
-			`<img onload="alert("loaded")">`,
-		},
-		{
-			"bad dynamic attribute name 1",
-			// Allow checked, selected, disabled, but not JS or
-			// CSS attributes.
-			`<input {{"onchange"}}="{{"doEvil()"}}">`,
-			`<input ZgotmplZ="doEvil()">`,
-		},
-		{
-			"bad dynamic attribute name 2",
-			`<div {{"sTyle"}}="{{"color: expression(alert(1337))"}}">`,
-			`<div ZgotmplZ="color: expression(alert(1337))">`,
-		},
-		{
-			"bad dynamic attribute name 3",
-			// Allow title or alt, but not a URL.
-			`<img {{"src"}}="{{"javascript:doEvil()"}}">`,
-			`<img ZgotmplZ="javascript:doEvil()">`,
-		},
-		{
-			"bad dynamic attribute name 4",
-			// Structure preservation requires values to associate
-			// with a consistent attribute.
-			`<input checked {{""}}="Whose value am I?">`,
-			`<input checked ZgotmplZ="Whose value am I?">`,
-		},
-		{
-			"dynamic element name",
-			`<h{{3}}><table><t{{"head"}}>...</h{{3}}>`,
-			`<h3><table><thead>...</h3>`,
-		},
-		{
-			"bad dynamic element name",
-			// Dynamic element names are typically used to switch
-			// between (thead, tfoot, tbody), (ul, ol), (th, td),
-			// and other replaceable sets.
-			// We do not currently easily support (ul, ol).
-			// If we do change to support that, this test should
-			// catch failures to filter out special tag names which
-			// would violate the structure preservation property --
-			// if any special tag name could be substituted, then
-			// the content could be raw text/RCDATA for some inputs
-			// and regular HTML content for others.
-			`<{{"script"}}>{{"doEvil()"}}</{{"script"}}>`,
-			`<script>doEvil()</script>`,
-		},
-	}
-
-	for _, test := range tests {
-		tmpl := New(test.name)
-		tmpl = Must(tmpl.Parse(test.input))
-		// Check for bug 6459: Tree field was not set in Parse.
-		if tmpl.Tree != tmpl.text.Tree {
-			t.Errorf("%s: tree not set properly", test.name)
-			continue
-		}
-		b := new(bytes.Buffer)
-		if err := tmpl.Execute(b, data); err != nil {
-			t.Errorf("%s: template execution failed: %s", test.name, err)
-			continue
-		}
-		if w, g := test.output, b.String(); w != g {
-			t.Errorf("%s: escaped output: want\n\t%q\ngot\n\t%q", test.name, w, g)
-			continue
-		}
-		b.Reset()
-		if err := tmpl.Execute(b, pdata); err != nil {
-			t.Errorf("%s: template execution failed for pointer: %s", test.name, err)
-			continue
-		}
-		if w, g := test.output, b.String(); w != g {
-			t.Errorf("%s: escaped output for pointer: want\n\t%q\ngot\n\t%q", test.name, w, g)
-			continue
-		}
-		if tmpl.Tree != tmpl.text.Tree {
-			t.Errorf("%s: tree mismatch", test.name)
-			continue
-		}
-	}
-}
-
-func TestEscapeSet(t *testing.T) {
-	type dataItem struct {
-		Children []*dataItem
-		X        string
-	}
-
-	data := dataItem{
-		Children: []*dataItem{
-			{X: "foo"},
-			{X: "<bar>"},
-			{
-				Children: []*dataItem{
-					{X: "baz"},
-				},
-			},
-		},
-	}
-
-	tests := []struct {
-		inputs map[string]string
-		want   string
-	}{
-		// The trivial set.
-		{
-			map[string]string{
-				"main": ``,
-			},
-			``,
-		},
-		// A template called in the start context.
-		{
-			map[string]string{
-				"main": `Hello, {{template "helper"}}!`,
-				// Not a valid top level HTML template.
-				// "<b" is not a full tag.
-				"helper": `{{"<World>"}}`,
-			},
-			`Hello, <World>!`,
-		},
-		// A template called in a context other than the start.
-		{
-			map[string]string{
-				"main": `<a onclick='a = {{template "helper"}};'>`,
-				// Not a valid top level HTML template.
-				// "<b" is not a full tag.
-				"helper": `{{"<a>"}}<b`,
-			},
-			`<a onclick='a = "\u003ca\u003e"<b;'>`,
-		},
-		// A recursive template that ends in its start context.
-		{
-			map[string]string{
-				"main": `{{range .Children}}{{template "main" .}}{{else}}{{.X}} {{end}}`,
-			},
-			`foo <bar> baz `,
-		},
-		// A recursive helper template that ends in its start context.
-		{
-			map[string]string{
-				"main":   `{{template "helper" .}}`,
-				"helper": `{{if .Children}}<ul>{{range .Children}}<li>{{template "main" .}}</li>{{end}}</ul>{{else}}{{.X}}{{end}}`,
-			},
-			`<ul><li>foo</li><li><bar></li><li><ul><li>baz</li></ul></li></ul>`,
-		},
-		// Co-recursive templates that end in its start context.
-		{
-			map[string]string{
-				"main":   `<blockquote>{{range .Children}}{{template "helper" .}}{{end}}</blockquote>`,
-				"helper": `{{if .Children}}{{template "main" .}}{{else}}{{.X}}<br>{{end}}`,
-			},
-			`<blockquote>foo<br><bar><br><blockquote>baz<br></blockquote></blockquote>`,
-		},
-		// A template that is called in two different contexts.
-		{
-			map[string]string{
-				"main":   `<button onclick="title='{{template "helper"}}'; ...">{{template "helper"}}</button>`,
-				"helper": `{{11}} of {{"<100>"}}`,
-			},
-			`<button onclick="title='11 of \x3c100\x3e'; ...">11 of <100></button>`,
-		},
-		// A non-recursive template that ends in a different context.
-		// helper starts in jsCtxRegexp and ends in jsCtxDivOp.
-		{
-			map[string]string{
-				"main":   `<script>var x={{template "helper"}}/{{"42"}};</script>`,
-				"helper": "{{126}}",
-			},
-			`<script>var x= 126 /"42";</script>`,
-		},
-		// A recursive template that ends in a similar context.
-		{
-			map[string]string{
-				"main":      `<script>var x=[{{template "countdown" 4}}];</script>`,
-				"countdown": `{{.}}{{if .}},{{template "countdown" . | pred}}{{end}}`,
-			},
-			`<script>var x=[ 4 , 3 , 2 , 1 , 0 ];</script>`,
-		},
-		// A recursive template that ends in a different context.
-		/*
-			{
-				map[string]string{
-					"main":   `<a href="/foo{{template "helper" .}}">`,
-					"helper": `{{if .Children}}{{range .Children}}{{template "helper" .}}{{end}}{{else}}?x={{.X}}{{end}}`,
-				},
-				`<a href="/foo?x=foo?x=%3cbar%3e?x=baz">`,
-			},
-		*/
-	}
-
-	// pred is a template function that returns the predecessor of a
-	// natural number for testing recursive templates.
-	fns := FuncMap{"pred": func(a ...interface{}) (interface{}, error) {
-		if len(a) == 1 {
-			if i, _ := a[0].(int); i > 0 {
-				return i - 1, nil
-			}
-		}
-		return nil, fmt.Errorf("undefined pred(%v)", a)
-	}}
-
-	for _, test := range tests {
-		source := ""
-		for name, body := range test.inputs {
-			source += fmt.Sprintf("{{define %q}}%s{{end}} ", name, body)
-		}
-		tmpl, err := New("root").Funcs(fns).Parse(source)
-		if err != nil {
-			t.Errorf("error parsing %q: %v", source, err)
-			continue
-		}
-		var b bytes.Buffer
-
-		if err := tmpl.ExecuteTemplate(&b, "main", data); err != nil {
-			t.Errorf("%q executing %v", err.Error(), tmpl.Lookup("main"))
-			continue
-		}
-		if got := b.String(); test.want != got {
-			t.Errorf("want\n\t%q\ngot\n\t%q", test.want, got)
-		}
-	}
-
-}
-
-func TestErrors(t *testing.T) {
-	tests := []struct {
-		input string
-		err   string
-	}{
-		// Non-error cases.
-		{
-			"{{if .Cond}}<a>{{else}}<b>{{end}}",
-			"",
-		},
-		{
-			"{{if .Cond}}<a>{{end}}",
-			"",
-		},
-		{
-			"{{if .Cond}}{{else}}<b>{{end}}",
-			"",
-		},
-		{
-			"{{with .Cond}}<div>{{end}}",
-			"",
-		},
-		{
-			"{{range .Items}}<a>{{end}}",
-			"",
-		},
-		{
-			"<a href='/foo?{{range .Items}}&{{.K}}={{.V}}{{end}}'>",
-			"",
-		},
-		// Error cases.
-		{
-			"{{if .Cond}}<a{{end}}",
-			"z:1: {{if}} branches",
-		},
-		{
-			"{{if .Cond}}\n{{else}}\n<a{{end}}",
-			"z:1: {{if}} branches",
-		},
-		{
-			// Missing quote in the else branch.
-			`{{if .Cond}}<a href="foo">{{else}}<a href="bar>{{end}}`,
-			"z:1: {{if}} branches",
-		},
-		{
-			// Different kind of attribute: href implies a URL.
-			"<a {{if .Cond}}href='{{else}}title='{{end}}{{.X}}'>",
-			"z:1: {{if}} branches",
-		},
-		{
-			"\n{{with .X}}<a{{end}}",
-			"z:2: {{with}} branches",
-		},
-		{
-			"\n{{with .X}}<a>{{else}}<a{{end}}",
-			"z:2: {{with}} branches",
-		},
-		{
-			"{{range .Items}}<a{{end}}",
-			`z:1: on range loop re-entry: "<" in attribute name: "<a"`,
-		},
-		{
-			"\n{{range .Items}} x='<a{{end}}",
-			"z:2: on range loop re-entry: {{range}} branches",
-		},
-		{
-			"<a b=1 c={{.H}}",
-			"z: ends in a non-text context: {stateAttr delimSpaceOrTagEnd",
-		},
-		{
-			"<script>foo();",
-			"z: ends in a non-text context: {stateJS",
-		},
-		{
-			`<a href="{{if .F}}/foo?a={{else}}/bar/{{end}}{{.H}}">`,
-			"z:1: {{.H}} appears in an ambiguous URL context",
-		},
-		{
-			`<a onclick="alert('Hello \`,
-			`unfinished escape sequence in JS string: "Hello \\"`,
-		},
-		{
-			`<a onclick='alert("Hello\, World\`,
-			`unfinished escape sequence in JS string: "Hello\\, World\\"`,
-		},
-		{
-			`<a onclick='alert(/x+\`,
-			`unfinished escape sequence in JS string: "x+\\"`,
-		},
-		{
-			`<a onclick="/foo[\]/`,
-			`unfinished JS regexp charset: "foo[\\]/"`,
-		},
-		{
-			// It is ambiguous whether 1.5 should be 1\.5 or 1.5.
-			// Either `var x = 1/- 1.5 /i.test(x)`
-			// where `i.test(x)` is a method call of reference i,
-			// or `/-1\.5/i.test(x)` which is a method call on a
-			// case insensitive regular expression.
-			`<script>{{if false}}var x = 1{{end}}/-{{"1.5"}}/i.test(x)</script>`,
-			`'/' could start a division or regexp: "/-"`,
-		},
-		{
-			`{{template "foo"}}`,
-			"z:1: no such template \"foo\"",
-		},
-		{
-			`<div{{template "y"}}>` +
-				// Illegal starting in stateTag but not in stateText.
-				`{{define "y"}} foo<b{{end}}`,
-			`"<" in attribute name: " foo<b"`,
-		},
-		{
-			`<script>reverseList = [{{template "t"}}]</script>` +
-				// Missing " after recursive call.
-				`{{define "t"}}{{if .Tail}}{{template "t" .Tail}}{{end}}{{.Head}}",{{end}}`,
-			`: cannot compute output context for template t$htmltemplate_stateJS_elementScript`,
-		},
-		{
-			`<input type=button value=onclick=>`,
-			`html/template:z: "=" in unquoted attr: "onclick="`,
-		},
-		{
-			`<input type=button value= onclick=>`,
-			`html/template:z: "=" in unquoted attr: "onclick="`,
-		},
-		{
-			`<input type=button value= 1+1=2>`,
-			`html/template:z: "=" in unquoted attr: "1+1=2"`,
-		},
-		{
-			"<a class=`foo>",
-			"html/template:z: \"`\" in unquoted attr: \"`foo\"",
-		},
-		{
-			`<a style=font:'Arial'>`,
-			`html/template:z: "'" in unquoted attr: "font:'Arial'"`,
-		},
-		{
-			`<a=foo>`,
-			`: expected space, attr name, or end of tag, but got "=foo>"`,
-		},
-	}
-
-	for _, test := range tests {
-		buf := new(bytes.Buffer)
-		tmpl, err := New("z").Parse(test.input)
-		if err != nil {
-			t.Errorf("input=%q: unexpected parse error %s\n", test.input, err)
-			continue
-		}
-		err = tmpl.Execute(buf, nil)
-		var got string
-		if err != nil {
-			got = err.Error()
-		}
-		if test.err == "" {
-			if got != "" {
-				t.Errorf("input=%q: unexpected error %q", test.input, got)
-			}
-			continue
-		}
-		if strings.Index(got, test.err) == -1 {
-			t.Errorf("input=%q: error\n\t%q\ndoes not contain expected string\n\t%q", test.input, got, test.err)
-			continue
-		}
-	}
-}
-
-func TestEscapeText(t *testing.T) {
-	tests := []struct {
-		input  string
-		output context
-	}{
-		{
-			``,
-			context{},
-		},
-		{
-			`Hello, World!`,
-			context{},
-		},
-		{
-			// An orphaned "<" is OK.
-			`I <3 Ponies!`,
-			context{},
-		},
-		{
-			`<a`,
-			context{state: stateTag},
-		},
-		{
-			`<a `,
-			context{state: stateTag},
-		},
-		{
-			`<a>`,
-			context{state: stateText},
-		},
-		{
-			`<a href`,
-			context{state: stateAttrName, attr: attrURL},
-		},
-		{
-			`<a on`,
-			context{state: stateAttrName, attr: attrScript},
-		},
-		{
-			`<a href `,
-			context{state: stateAfterName, attr: attrURL},
-		},
-		{
-			`<a style  =  `,
-			context{state: stateBeforeValue, attr: attrStyle},
-		},
-		{
-			`<a href=`,
-			context{state: stateBeforeValue, attr: attrURL},
-		},
-		{
-			`<a href=x`,
-			context{state: stateURL, delim: delimSpaceOrTagEnd, urlPart: urlPartPreQuery},
-		},
-		{
-			`<a href=x `,
-			context{state: stateTag},
-		},
-		{
-			`<a href=>`,
-			context{state: stateText},
-		},
-		{
-			`<a href=x>`,
-			context{state: stateText},
-		},
-		{
-			`<a href ='`,
-			context{state: stateURL, delim: delimSingleQuote},
-		},
-		{
-			`<a href=''`,
-			context{state: stateTag},
-		},
-		{
-			`<a href= "`,
-			context{state: stateURL, delim: delimDoubleQuote},
-		},
-		{
-			`<a href=""`,
-			context{state: stateTag},
-		},
-		{
-			`<a title="`,
-			context{state: stateAttr, delim: delimDoubleQuote},
-		},
-		{
-			`<a HREF='http:`,
-			context{state: stateURL, delim: delimSingleQuote, urlPart: urlPartPreQuery},
-		},
-		{
-			`<a Href='/`,
-			context{state: stateURL, delim: delimSingleQuote, urlPart: urlPartPreQuery},
-		},
-		{
-			`<a href='"`,
-			context{state: stateURL, delim: delimSingleQuote, urlPart: urlPartPreQuery},
-		},
-		{
-			`<a href="'`,
-			context{state: stateURL, delim: delimDoubleQuote, urlPart: urlPartPreQuery},
-		},
-		{
-			`<a href=''`,
-			context{state: stateURL, delim: delimSingleQuote, urlPart: urlPartPreQuery},
-		},
-		{
-			`<a href=""`,
-			context{state: stateURL, delim: delimDoubleQuote, urlPart: urlPartPreQuery},
-		},
-		{
-			`<a href=""`,
-			context{state: stateURL, delim: delimDoubleQuote, urlPart: urlPartPreQuery},
-		},
-		{
-			`<a href="`,
-			context{state: stateURL, delim: delimSpaceOrTagEnd, urlPart: urlPartPreQuery},
-		},
-		{
-			`<img alt="1">`,
-			context{state: stateText},
-		},
-		{
-			`<img alt="1>"`,
-			context{state: stateTag},
-		},
-		{
-			`<img alt="1>">`,
-			context{state: stateText},
-		},
-		{
-			`<input checked type="checkbox"`,
-			context{state: stateTag},
-		},
-		{
-			`<a onclick="`,
-			context{state: stateJS, delim: delimDoubleQuote},
-		},
-		{
-			`<a onclick="//foo`,
-			context{state: stateJSLineCmt, delim: delimDoubleQuote},
-		},
-		{
-			"<a onclick='//\n",
-			context{state: stateJS, delim: delimSingleQuote},
-		},
-		{
-			"<a onclick='//\r\n",
-			context{state: stateJS, delim: delimSingleQuote},
-		},
-		{
-			"<a onclick='//\u2028",
-			context{state: stateJS, delim: delimSingleQuote},
-		},
-		{
-			`<a onclick="/*`,
-			context{state: stateJSBlockCmt, delim: delimDoubleQuote},
-		},
-		{
-			`<a onclick="/*/`,
-			context{state: stateJSBlockCmt, delim: delimDoubleQuote},
-		},
-		{
-			`<a onclick="/**/`,
-			context{state: stateJS, delim: delimDoubleQuote},
-		},
-		{
-			`<a onkeypress=""`,
-			context{state: stateJSDqStr, delim: delimDoubleQuote},
-		},
-		{
-			`<a onclick='"foo"`,
-			context{state: stateJS, delim: delimSingleQuote, jsCtx: jsCtxDivOp},
-		},
-		{
-			`<a onclick='foo'`,
-			context{state: stateJS, delim: delimSpaceOrTagEnd, jsCtx: jsCtxDivOp},
-		},
-		{
-			`<a onclick='foo`,
-			context{state: stateJSSqStr, delim: delimSpaceOrTagEnd},
-		},
-		{
-			`<a onclick=""foo'`,
-			context{state: stateJSDqStr, delim: delimDoubleQuote},
-		},
-		{
-			`<a onclick="'foo"`,
-			context{state: stateJSSqStr, delim: delimDoubleQuote},
-		},
-		{
-			`<A ONCLICK="'`,
-			context{state: stateJSSqStr, delim: delimDoubleQuote},
-		},
-		{
-			`<a onclick="/`,
-			context{state: stateJSRegexp, delim: delimDoubleQuote},
-		},
-		{
-			`<a onclick="'foo'`,
-			context{state: stateJS, delim: delimDoubleQuote, jsCtx: jsCtxDivOp},
-		},
-		{
-			`<a onclick="'foo\'`,
-			context{state: stateJSSqStr, delim: delimDoubleQuote},
-		},
-		{
-			`<a onclick="'foo\'`,
-			context{state: stateJSSqStr, delim: delimDoubleQuote},
-		},
-		{
-			`<a onclick="/foo/`,
-			context{state: stateJS, delim: delimDoubleQuote, jsCtx: jsCtxDivOp},
-		},
-		{
-			`<script>/foo/ /=`,
-			context{state: stateJS, element: elementScript},
-		},
-		{
-			`<a onclick="1 /foo`,
-			context{state: stateJS, delim: delimDoubleQuote, jsCtx: jsCtxDivOp},
-		},
-		{
-			`<a onclick="1 /*c*/ /foo`,
-			context{state: stateJS, delim: delimDoubleQuote, jsCtx: jsCtxDivOp},
-		},
-		{
-			`<a onclick="/foo[/]`,
-			context{state: stateJSRegexp, delim: delimDoubleQuote},
-		},
-		{
-			`<a onclick="/foo\/`,
-			context{state: stateJSRegexp, delim: delimDoubleQuote},
-		},
-		{
-			`<a onclick="/foo/`,
-			context{state: stateJS, delim: delimDoubleQuote, jsCtx: jsCtxDivOp},
-		},
-		{
-			`<input checked style="`,
-			context{state: stateCSS, delim: delimDoubleQuote},
-		},
-		{
-			`<a style="//`,
-			context{state: stateCSSLineCmt, delim: delimDoubleQuote},
-		},
-		{
-			`<a style="//</script>`,
-			context{state: stateCSSLineCmt, delim: delimDoubleQuote},
-		},
-		{
-			"<a style='//\n",
-			context{state: stateCSS, delim: delimSingleQuote},
-		},
-		{
-			"<a style='//\r",
-			context{state: stateCSS, delim: delimSingleQuote},
-		},
-		{
-			`<a style="/*`,
-			context{state: stateCSSBlockCmt, delim: delimDoubleQuote},
-		},
-		{
-			`<a style="/*/`,
-			context{state: stateCSSBlockCmt, delim: delimDoubleQuote},
-		},
-		{
-			`<a style="/**/`,
-			context{state: stateCSS, delim: delimDoubleQuote},
-		},
-		{
-			`<a style="background: '`,
-			context{state: stateCSSSqStr, delim: delimDoubleQuote},
-		},
-		{
-			`<a style="background: "`,
-			context{state: stateCSSDqStr, delim: delimDoubleQuote},
-		},
-		{
-			`<a style="background: '/foo?img=`,
-			context{state: stateCSSSqStr, delim: delimDoubleQuote, urlPart: urlPartQueryOrFrag},
-		},
-		{
-			`<a style="background: '/`,
-			context{state: stateCSSSqStr, delim: delimDoubleQuote, urlPart: urlPartPreQuery},
-		},
-		{
-			`<a style="background: url(&#x22;/`,
-			context{state: stateCSSDqURL, delim: delimDoubleQuote, urlPart: urlPartPreQuery},
-		},
-		{
-			`<a style="background: url('/`,
-			context{state: stateCSSSqURL, delim: delimDoubleQuote, urlPart: urlPartPreQuery},
-		},
-		{
-			`<a style="background: url('/)`,
-			context{state: stateCSSSqURL, delim: delimDoubleQuote, urlPart: urlPartPreQuery},
-		},
-		{
-			`<a style="background: url('/ `,
-			context{state: stateCSSSqURL, delim: delimDoubleQuote, urlPart: urlPartPreQuery},
-		},
-		{
-			`<a style="background: url(/`,
-			context{state: stateCSSURL, delim: delimDoubleQuote, urlPart: urlPartPreQuery},
-		},
-		{
-			`<a style="background: url( `,
-			context{state: stateCSSURL, delim: delimDoubleQuote},
-		},
-		{
-			`<a style="background: url( /image?name=`,
-			context{state: stateCSSURL, delim: delimDoubleQuote, urlPart: urlPartQueryOrFrag},
-		},
-		{
-			`<a style="background: url(x)`,
-			context{state: stateCSS, delim: delimDoubleQuote},
-		},
-		{
-			`<a style="background: url('x'`,
-			context{state: stateCSS, delim: delimDoubleQuote},
-		},
-		{
-			`<a style="background: url( x `,
-			context{state: stateCSS, delim: delimDoubleQuote},
-		},
-		{
-			`<!-- foo`,
-			context{state: stateHTMLCmt},
-		},
-		{
-			`<!-->`,
-			context{state: stateHTMLCmt},
-		},
-		{
-			`<!--->`,
-			context{state: stateHTMLCmt},
-		},
-		{
-			`<!-- foo -->`,
-			context{state: stateText},
-		},
-		{
-			`<script`,
-			context{state: stateTag, element: elementScript},
-		},
-		{
-			`<script `,
-			context{state: stateTag, element: elementScript},
-		},
-		{
-			`<script src="foo.js" `,
-			context{state: stateTag, element: elementScript},
-		},
-		{
-			`<script src='foo.js' `,
-			context{state: stateTag, element: elementScript},
-		},
-		{
-			`<script type=text/javascript `,
-			context{state: stateTag, element: elementScript},
-		},
-		{
-			`<script>foo`,
-			context{state: stateJS, jsCtx: jsCtxDivOp, element: elementScript},
-		},
-		{
-			`<script>foo</script>`,
-			context{state: stateText},
-		},
-		{
-			`<script>foo</script><!--`,
-			context{state: stateHTMLCmt},
-		},
-		{
-			`<script>document.write("<p>foo</p>");`,
-			context{state: stateJS, element: elementScript},
-		},
-		{
-			`<script>document.write("<p>foo<\/script>");`,
-			context{state: stateJS, element: elementScript},
-		},
-		{
-			`<script>document.write("<script>alert(1)</script>");`,
-			context{state: stateText},
-		},
-		{
-			`<Script>`,
-			context{state: stateJS, element: elementScript},
-		},
-		{
-			`<SCRIPT>foo`,
-			context{state: stateJS, jsCtx: jsCtxDivOp, element: elementScript},
-		},
-		{
-			`<textarea>value`,
-			context{state: stateRCDATA, element: elementTextarea},
-		},
-		{
-			`<textarea>value</TEXTAREA>`,
-			context{state: stateText},
-		},
-		{
-			`<textarea name=html><b`,
-			context{state: stateRCDATA, element: elementTextarea},
-		},
-		{
-			`<title>value`,
-			context{state: stateRCDATA, element: elementTitle},
-		},
-		{
-			`<style>value`,
-			context{state: stateCSS, element: elementStyle},
-		},
-		{
-			`<a xlink:href`,
-			context{state: stateAttrName, attr: attrURL},
-		},
-		{
-			`<a xmlns`,
-			context{state: stateAttrName, attr: attrURL},
-		},
-		{
-			`<a xmlns:foo`,
-			context{state: stateAttrName, attr: attrURL},
-		},
-		{
-			`<a xmlnsxyz`,
-			context{state: stateAttrName},
-		},
-		{
-			`<a data-url`,
-			context{state: stateAttrName, attr: attrURL},
-		},
-		{
-			`<a data-iconUri`,
-			context{state: stateAttrName, attr: attrURL},
-		},
-		{
-			`<a data-urlItem`,
-			context{state: stateAttrName, attr: attrURL},
-		},
-		{
-			`<a g:`,
-			context{state: stateAttrName},
-		},
-		{
-			`<a g:url`,
-			context{state: stateAttrName, attr: attrURL},
-		},
-		{
-			`<a g:iconUri`,
-			context{state: stateAttrName, attr: attrURL},
-		},
-		{
-			`<a g:urlItem`,
-			context{state: stateAttrName, attr: attrURL},
-		},
-		{
-			`<a g:value`,
-			context{state: stateAttrName},
-		},
-		{
-			`<a svg:style='`,
-			context{state: stateCSS, delim: delimSingleQuote},
-		},
-		{
-			`<svg:font-face`,
-			context{state: stateTag},
-		},
-		{
-			`<svg:a svg:onclick="`,
-			context{state: stateJS, delim: delimDoubleQuote},
-		},
-	}
-
-	for _, test := range tests {
-		b, e := []byte(test.input), newEscaper(nil)
-		c := e.escapeText(context{}, &parse.TextNode{NodeType: parse.NodeText, Text: b})
-		if !test.output.eq(c) {
-			t.Errorf("input %q: want context\n\t%v\ngot\n\t%v", test.input, test.output, c)
-			continue
-		}
-		if test.input != string(b) {
-			t.Errorf("input %q: text node was modified: want %q got %q", test.input, test.input, b)
-			continue
-		}
-	}
-}
-
-func TestEnsurePipelineContains(t *testing.T) {
-	tests := []struct {
-		input, output string
-		ids           []string
-	}{
-		{
-			"{{.X}}",
-			".X",
-			[]string{},
-		},
-		{
-			"{{.X | html}}",
-			".X | html",
-			[]string{},
-		},
-		{
-			"{{.X}}",
-			".X | html",
-			[]string{"html"},
-		},
-		{
-			"{{.X | html}}",
-			".X | html | urlquery",
-			[]string{"urlquery"},
-		},
-		{
-			"{{.X | html | urlquery}}",
-			".X | html | urlquery",
-			[]string{"urlquery"},
-		},
-		{
-			"{{.X | html | urlquery}}",
-			".X | html | urlquery",
-			[]string{"html", "urlquery"},
-		},
-		{
-			"{{.X | html | urlquery}}",
-			".X | html | urlquery",
-			[]string{"html"},
-		},
-		{
-			"{{.X | urlquery}}",
-			".X | html | urlquery",
-			[]string{"html", "urlquery"},
-		},
-		{
-			"{{.X | html | print}}",
-			".X | urlquery | html | print",
-			[]string{"urlquery", "html"},
-		},
-		{
-			"{{($).X | html | print}}",
-			"($).X | urlquery | html | print",
-			[]string{"urlquery", "html"},
-		},
-	}
-	for i, test := range tests {
-		tmpl := template.Must(template.New("test").Parse(test.input))
-		action, ok := (tmpl.Tree.Root.Nodes[0].(*parse.ActionNode))
-		if !ok {
-			t.Errorf("#%d: First node is not an action: %s", i, test.input)
-			continue
-		}
-		pipe := action.Pipe
-		ensurePipelineContains(pipe, test.ids)
-		got := pipe.String()
-		if got != test.output {
-			t.Errorf("#%d: %s, %v: want\n\t%s\ngot\n\t%s", i, test.input, test.ids, test.output, got)
-		}
-	}
-}
-
-func TestEscapeErrorsNotIgnorable(t *testing.T) {
-	var b bytes.Buffer
-	tmpl, _ := New("dangerous").Parse("<a")
-	err := tmpl.Execute(&b, nil)
-	if err == nil {
-		t.Errorf("Expected error")
-	} else if b.Len() != 0 {
-		t.Errorf("Emitted output despite escaping failure")
-	}
-}
-
-func TestEscapeSetErrorsNotIgnorable(t *testing.T) {
-	var b bytes.Buffer
-	tmpl, err := New("root").Parse(`{{define "t"}}<a{{end}}`)
-	if err != nil {
-		t.Errorf("failed to parse set: %q", err)
-	}
-	err = tmpl.ExecuteTemplate(&b, "t", nil)
-	if err == nil {
-		t.Errorf("Expected error")
-	} else if b.Len() != 0 {
-		t.Errorf("Emitted output despite escaping failure")
-	}
-}
-
-func TestRedundantFuncs(t *testing.T) {
-	inputs := []interface{}{
-		"\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f" +
-			"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" +
-			` !"#$%&'()*+,-./` +
-			`0123456789:;<=>?` +
-			`@ABCDEFGHIJKLMNO` +
-			`PQRSTUVWXYZ[\]^_` +
-			"`abcdefghijklmno" +
-			"pqrstuvwxyz{|}~\x7f" +
-			"\u00A0\u0100\u2028\u2029\ufeff\ufdec\ufffd\uffff\U0001D11E" +
-			"&%22\\",
-		CSS(`a[href =~ "//example.com"]#foo`),
-		HTML(`Hello, <b>World</b> &tc!`),
-		HTMLAttr(` dir="ltr"`),
-		JS(`c && alert("Hello, World!");`),
-		JSStr(`Hello, World & O'Reilly\x21`),
-		URL(`greeting=H%69&addressee=(World)`),
-	}
-
-	for n0, m := range redundantFuncs {
-		f0 := funcMap[n0].(func(...interface{}) string)
-		for n1 := range m {
-			f1 := funcMap[n1].(func(...interface{}) string)
-			for _, input := range inputs {
-				want := f0(input)
-				if got := f1(want); want != got {
-					t.Errorf("%s %s with %T %q: want\n\t%q,\ngot\n\t%q", n0, n1, input, input, want, got)
-				}
-			}
-		}
-	}
-}
-
-func TestIndirectPrint(t *testing.T) {
-	a := 3
-	ap := &a
-	b := "hello"
-	bp := &b
-	bpp := &bp
-	tmpl := Must(New("t").Parse(`{{.}}`))
-	var buf bytes.Buffer
-	err := tmpl.Execute(&buf, ap)
-	if err != nil {
-		t.Errorf("Unexpected error: %s", err)
-	} else if buf.String() != "3" {
-		t.Errorf(`Expected "3"; got %q`, buf.String())
-	}
-	buf.Reset()
-	err = tmpl.Execute(&buf, bpp)
-	if err != nil {
-		t.Errorf("Unexpected error: %s", err)
-	} else if buf.String() != "hello" {
-		t.Errorf(`Expected "hello"; got %q`, buf.String())
-	}
-}
-
-// This is a test for issue 3272.
-func TestEmptyTemplate(t *testing.T) {
-	page := Must(New("page").ParseFiles(os.DevNull))
-	if err := page.ExecuteTemplate(os.Stdout, "page", "nothing"); err == nil {
-		t.Fatal("expected error")
-	}
-}
-
-type Issue7379 int
-
-func (Issue7379) SomeMethod(x int) string {
-	return fmt.Sprintf("<%d>", x)
-}
-
-// This is a test for issue 7379: type assertion error caused panic, and then
-// the code to handle the panic breaks escaping. It's hard to see the second
-// problem once the first is fixed, but its fix is trivial so we let that go. See
-// the discussion for issue 7379.
-func TestPipeToMethodIsEscaped(t *testing.T) {
-	tmpl := Must(New("x").Parse("<html>{{0 | .SomeMethod}}</html>\n"))
-	tryExec := func() string {
-		defer func() {
-			panicValue := recover()
-			if panicValue != nil {
-				t.Errorf("panicked: %v\n", panicValue)
-			}
-		}()
-		var b bytes.Buffer
-		tmpl.Execute(&b, Issue7379(0))
-		return b.String()
-	}
-	for i := 0; i < 3; i++ {
-		str := tryExec()
-		const expect = "<html><0></html>\n"
-		if str != expect {
-			t.Errorf("expected %q got %q", expect, str)
-		}
-	}
-}
-
-func BenchmarkEscapedExecute(b *testing.B) {
-	tmpl := Must(New("t").Parse(`<a onclick="alert('{{.}}')">{{.}}</a>`))
-	var buf bytes.Buffer
-	b.ResetTimer()
-	for i := 0; i < b.N; i++ {
-		tmpl.Execute(&buf, "foo & 'bar' & baz")
-		buf.Reset()
-	}
-}
diff --git a/src/pkg/html/template/js_test.go b/src/pkg/html/template/js_test.go
deleted file mode 100644
index 311e1d2..0000000
--- a/src/pkg/html/template/js_test.go
+++ /dev/null
@@ -1,401 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package template
-
-import (
-	"bytes"
-	"math"
-	"strings"
-	"testing"
-)
-
-func TestNextJsCtx(t *testing.T) {
-	tests := []struct {
-		jsCtx jsCtx
-		s     string
-	}{
-		// Statement terminators precede regexps.
-		{jsCtxRegexp, ";"},
-		// This is not airtight.
-		//     ({ valueOf: function () { return 1 } } / 2)
-		// is valid JavaScript but in practice, devs do not do this.
-		// A block followed by a statement starting with a RegExp is
-		// much more common:
-		//     while (x) {...} /foo/.test(x) || panic()
-		{jsCtxRegexp, "}"},
-		// But member, call, grouping, and array expression terminators
-		// precede div ops.
-		{jsCtxDivOp, ")"},
-		{jsCtxDivOp, "]"},
-		// At the start of a primary expression, array, or expression
-		// statement, expect a regexp.
-		{jsCtxRegexp, "("},
-		{jsCtxRegexp, "["},
-		{jsCtxRegexp, "{"},
-		// Assignment operators precede regexps as do all exclusively
-		// prefix and binary operators.
-		{jsCtxRegexp, "="},
-		{jsCtxRegexp, "+="},
-		{jsCtxRegexp, "*="},
-		{jsCtxRegexp, "*"},
-		{jsCtxRegexp, "!"},
-		// Whether the + or - is infix or prefix, it cannot precede a
-		// div op.
-		{jsCtxRegexp, "+"},
-		{jsCtxRegexp, "-"},
-		// An incr/decr op precedes a div operator.
-		// This is not airtight. In (g = ++/h/i) a regexp follows a
-		// pre-increment operator, but in practice devs do not try to
-		// increment or decrement regular expressions.
-		// (g++/h/i) where ++ is a postfix operator on g is much more
-		// common.
-		{jsCtxDivOp, "--"},
-		{jsCtxDivOp, "++"},
-		{jsCtxDivOp, "x--"},
-		// When we have many dashes or pluses, then they are grouped
-		// left to right.
-		{jsCtxRegexp, "x---"}, // A postfix -- then a -.
-		// return followed by a slash returns the regexp literal or the
-		// slash starts a regexp literal in an expression statement that
-		// is dead code.
-		{jsCtxRegexp, "return"},
-		{jsCtxRegexp, "return "},
-		{jsCtxRegexp, "return\t"},
-		{jsCtxRegexp, "return\n"},
-		{jsCtxRegexp, "return\u2028"},
-		// Identifiers can be divided and cannot validly be preceded by
-		// a regular expressions. Semicolon insertion cannot happen
-		// between an identifier and a regular expression on a new line
-		// because the one token lookahead for semicolon insertion has
-		// to conclude that it could be a div binary op and treat it as
-		// such.
-		{jsCtxDivOp, "x"},
-		{jsCtxDivOp, "x "},
-		{jsCtxDivOp, "x\t"},
-		{jsCtxDivOp, "x\n"},
-		{jsCtxDivOp, "x\u2028"},
-		{jsCtxDivOp, "preturn"},
-		// Numbers precede div ops.
-		{jsCtxDivOp, "0"},
-		// Dots that are part of a number are div preceders.
-		{jsCtxDivOp, "0."},
-	}
-
-	for _, test := range tests {
-		if nextJSCtx([]byte(test.s), jsCtxRegexp) != test.jsCtx {
-			t.Errorf("want %s got %q", test.jsCtx, test.s)
-		}
-		if nextJSCtx([]byte(test.s), jsCtxDivOp) != test.jsCtx {
-			t.Errorf("want %s got %q", test.jsCtx, test.s)
-		}
-	}
-
-	if nextJSCtx([]byte("   "), jsCtxRegexp) != jsCtxRegexp {
-		t.Error("Blank tokens")
-	}
-
-	if nextJSCtx([]byte("   "), jsCtxDivOp) != jsCtxDivOp {
-		t.Error("Blank tokens")
-	}
-}
-
-func TestJSValEscaper(t *testing.T) {
-	tests := []struct {
-		x  interface{}
-		js string
-	}{
-		{int(42), " 42 "},
-		{uint(42), " 42 "},
-		{int16(42), " 42 "},
-		{uint16(42), " 42 "},
-		{int32(-42), " -42 "},
-		{uint32(42), " 42 "},
-		{int16(-42), " -42 "},
-		{uint16(42), " 42 "},
-		{int64(-42), " -42 "},
-		{uint64(42), " 42 "},
-		{uint64(1) << 53, " 9007199254740992 "},
-		// ulp(1 << 53) > 1 so this loses precision in JS
-		// but it is still a representable integer literal.
-		{uint64(1)<<53 + 1, " 9007199254740993 "},
-		{float32(1.0), " 1 "},
-		{float32(-1.0), " -1 "},
-		{float32(0.5), " 0.5 "},
-		{float32(-0.5), " -0.5 "},
-		{float32(1.0) / float32(256), " 0.00390625 "},
-		{float32(0), " 0 "},
-		{math.Copysign(0, -1), " -0 "},
-		{float64(1.0), " 1 "},
-		{float64(-1.0), " -1 "},
-		{float64(0.5), " 0.5 "},
-		{float64(-0.5), " -0.5 "},
-		{float64(0), " 0 "},
-		{math.Copysign(0, -1), " -0 "},
-		{"", `""`},
-		{"foo", `"foo"`},
-		// Newlines.
-		{"\r\n\u2028\u2029", `"\r\n\u2028\u2029"`},
-		// "\v" == "v" on IE 6 so use "\x0b" instead.
-		{"\t\x0b", `"\u0009\u000b"`},
-		{struct{ X, Y int }{1, 2}, `{"X":1,"Y":2}`},
-		{[]interface{}{}, "[]"},
-		{[]interface{}{42, "foo", nil}, `[42,"foo",null]`},
-		{[]string{"<!--", "</script>", "-->"}, `["\u003c!--","\u003c/script\u003e","--\u003e"]`},
-		{"<!--", `"\u003c!--"`},
-		{"-->", `"--\u003e"`},
-		{"<![CDATA[", `"\u003c![CDATA["`},
-		{"]]>", `"]]\u003e"`},
-		{"</script", `"\u003c/script"`},
-		{"\U0001D11E", "\"\U0001D11E\""}, // or "\uD834\uDD1E"
-	}
-
-	for _, test := range tests {
-		if js := jsValEscaper(test.x); js != test.js {
-			t.Errorf("%+v: want\n\t%q\ngot\n\t%q", test.x, test.js, js)
-		}
-		// Make sure that escaping corner cases are not broken
-		// by nesting.
-		a := []interface{}{test.x}
-		want := "[" + strings.TrimSpace(test.js) + "]"
-		if js := jsValEscaper(a); js != want {
-			t.Errorf("%+v: want\n\t%q\ngot\n\t%q", a, want, js)
-		}
-	}
-}
-
-func TestJSStrEscaper(t *testing.T) {
-	tests := []struct {
-		x   interface{}
-		esc string
-	}{
-		{"", ``},
-		{"foo", `foo`},
-		{"\u0000", `\0`},
-		{"\t", `\t`},
-		{"\n", `\n`},
-		{"\r", `\r`},
-		{"\u2028", `\u2028`},
-		{"\u2029", `\u2029`},
-		{"\\", `\\`},
-		{"\\n", `\\n`},
-		{"foo\r\nbar", `foo\r\nbar`},
-		// Preserve attribute boundaries.
-		{`"`, `\x22`},
-		{`'`, `\x27`},
-		// Allow embedding in HTML without further escaping.
-		{`&`, `\x26amp;`},
-		// Prevent breaking out of text node and element boundaries.
-		{"</script>", `\x3c\/script\x3e`},
-		{"<![CDATA[", `\x3c![CDATA[`},
-		{"]]>", `]]\x3e`},
-		// http://dev.w3.org/html5/markup/aria/syntax.html#escaping-text-span
-		//   "The text in style, script, title, and textarea elements
-		//   must not have an escaping text span start that is not
-		//   followed by an escaping text span end."
-		// Furthermore, spoofing an escaping text span end could lead
-		// to different interpretation of a </script> sequence otherwise
-		// masked by the escaping text span, and spoofing a start could
-		// allow regular text content to be interpreted as script
-		// allowing script execution via a combination of a JS string
-		// injection followed by an HTML text injection.
-		{"<!--", `\x3c!--`},
-		{"-->", `--\x3e`},
-		// From http://code.google.com/p/doctype/wiki/ArticleUtf7
-		{"+ADw-script+AD4-alert(1)+ADw-/script+AD4-",
-			`\x2bADw-script\x2bAD4-alert(1)\x2bADw-\/script\x2bAD4-`,
-		},
-		// Invalid UTF-8 sequence
-		{"foo\xA0bar", "foo\xA0bar"},
-		// Invalid unicode scalar value.
-		{"foo\xed\xa0\x80bar", "foo\xed\xa0\x80bar"},
-	}
-
-	for _, test := range tests {
-		esc := jsStrEscaper(test.x)
-		if esc != test.esc {
-			t.Errorf("%q: want %q got %q", test.x, test.esc, esc)
-		}
-	}
-}
-
-func TestJSRegexpEscaper(t *testing.T) {
-	tests := []struct {
-		x   interface{}
-		esc string
-	}{
-		{"", `(?:)`},
-		{"foo", `foo`},
-		{"\u0000", `\0`},
-		{"\t", `\t`},
-		{"\n", `\n`},
-		{"\r", `\r`},
-		{"\u2028", `\u2028`},
-		{"\u2029", `\u2029`},
-		{"\\", `\\`},
-		{"\\n", `\\n`},
-		{"foo\r\nbar", `foo\r\nbar`},
-		// Preserve attribute boundaries.
-		{`"`, `\x22`},
-		{`'`, `\x27`},
-		// Allow embedding in HTML without further escaping.
-		{`&`, `\x26amp;`},
-		// Prevent breaking out of text node and element boundaries.
-		{"</script>", `\x3c\/script\x3e`},
-		{"<![CDATA[", `\x3c!\[CDATA\[`},
-		{"]]>", `\]\]\x3e`},
-		// Escaping text spans.
-		{"<!--", `\x3c!\-\-`},
-		{"-->", `\-\-\x3e`},
-		{"*", `\*`},
-		{"+", `\x2b`},
-		{"?", `\?`},
-		{"[](){}", `\[\]\(\)\{\}`},
-		{"$foo|x.y", `\$foo\|x\.y`},
-		{"x^y", `x\^y`},
-	}
-
-	for _, test := range tests {
-		esc := jsRegexpEscaper(test.x)
-		if esc != test.esc {
-			t.Errorf("%q: want %q got %q", test.x, test.esc, esc)
-		}
-	}
-}
-
-func TestEscapersOnLower7AndSelectHighCodepoints(t *testing.T) {
-	input := ("\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f" +
-		"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" +
-		` !"#$%&'()*+,-./` +
-		`0123456789:;<=>?` +
-		`@ABCDEFGHIJKLMNO` +
-		`PQRSTUVWXYZ[\]^_` +
-		"`abcdefghijklmno" +
-		"pqrstuvwxyz{|}~\x7f" +
-		"\u00A0\u0100\u2028\u2029\ufeff\U0001D11E")
-
-	tests := []struct {
-		name    string
-		escaper func(...interface{}) string
-		escaped string
-	}{
-		{
-			"jsStrEscaper",
-			jsStrEscaper,
-			"\\0\x01\x02\x03\x04\x05\x06\x07" +
-				"\x08\\t\\n\\x0b\\f\\r\x0E\x0F" +
-				"\x10\x11\x12\x13\x14\x15\x16\x17" +
-				"\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" +
-				` !\x22#$%\x26\x27()*\x2b,-.\/` +
-				`0123456789:;\x3c=\x3e?` +
-				`@ABCDEFGHIJKLMNO` +
-				`PQRSTUVWXYZ[\\]^_` +
-				"`abcdefghijklmno" +
-				"pqrstuvwxyz{|}~\x7f" +
-				"\u00A0\u0100\\u2028\\u2029\ufeff\U0001D11E",
-		},
-		{
-			"jsRegexpEscaper",
-			jsRegexpEscaper,
-			"\\0\x01\x02\x03\x04\x05\x06\x07" +
-				"\x08\\t\\n\\x0b\\f\\r\x0E\x0F" +
-				"\x10\x11\x12\x13\x14\x15\x16\x17" +
-				"\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" +
-				` !\x22#\$%\x26\x27\(\)\*\x2b,\-\.\/` +
-				`0123456789:;\x3c=\x3e\?` +
-				`@ABCDEFGHIJKLMNO` +
-				`PQRSTUVWXYZ\[\\\]\^_` +
-				"`abcdefghijklmno" +
-				`pqrstuvwxyz\{\|\}~` + "\u007f" +
-				"\u00A0\u0100\\u2028\\u2029\ufeff\U0001D11E",
-		},
-	}
-
-	for _, test := range tests {
-		if s := test.escaper(input); s != test.escaped {
-			t.Errorf("%s once: want\n\t%q\ngot\n\t%q", test.name, test.escaped, s)
-			continue
-		}
-
-		// Escape it rune by rune to make sure that any
-		// fast-path checking does not break escaping.
-		var buf bytes.Buffer
-		for _, c := range input {
-			buf.WriteString(test.escaper(string(c)))
-		}
-
-		if s := buf.String(); s != test.escaped {
-			t.Errorf("%s rune-wise: want\n\t%q\ngot\n\t%q", test.name, test.escaped, s)
-			continue
-		}
-	}
-}
-
-func BenchmarkJSValEscaperWithNum(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		jsValEscaper(3.141592654)
-	}
-}
-
-func BenchmarkJSValEscaperWithStr(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		jsValEscaper("The <i>quick</i>,\r\n<span style='color:brown'>brown</span> fox jumps\u2028over the <canine class=\"lazy\">dog</canine>")
-	}
-}
-
-func BenchmarkJSValEscaperWithStrNoSpecials(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		jsValEscaper("The quick, brown fox jumps over the lazy dog")
-	}
-}
-
-func BenchmarkJSValEscaperWithObj(b *testing.B) {
-	o := struct {
-		S string
-		N int
-	}{
-		"The <i>quick</i>,\r\n<span style='color:brown'>brown</span> fox jumps\u2028over the <canine class=\"lazy\">dog</canine>\u2028",
-		42,
-	}
-	for i := 0; i < b.N; i++ {
-		jsValEscaper(o)
-	}
-}
-
-func BenchmarkJSValEscaperWithObjNoSpecials(b *testing.B) {
-	o := struct {
-		S string
-		N int
-	}{
-		"The quick, brown fox jumps over the lazy dog",
-		42,
-	}
-	for i := 0; i < b.N; i++ {
-		jsValEscaper(o)
-	}
-}
-
-func BenchmarkJSStrEscaperNoSpecials(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		jsStrEscaper("The quick, brown fox jumps over the lazy dog.")
-	}
-}
-
-func BenchmarkJSStrEscaper(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		jsStrEscaper("The <i>quick</i>,\r\n<span style='color:brown'>brown</span> fox jumps\u2028over the <canine class=\"lazy\">dog</canine>")
-	}
-}
-
-func BenchmarkJSRegexpEscaperNoSpecials(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		jsRegexpEscaper("The quick, brown fox jumps over the lazy dog")
-	}
-}
-
-func BenchmarkJSRegexpEscaper(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		jsRegexpEscaper("The <i>quick</i>,\r\n<span style='color:brown'>brown</span> fox jumps\u2028over the <canine class=\"lazy\">dog</canine>")
-	}
-}
diff --git a/src/pkg/html/template/template.go b/src/pkg/html/template/template.go
deleted file mode 100644
index d389658..0000000
--- a/src/pkg/html/template/template.go
+++ /dev/null
@@ -1,381 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package template
-
-import (
-	"fmt"
-	"io"
-	"io/ioutil"
-	"path/filepath"
-	"sync"
-	"text/template"
-	"text/template/parse"
-)
-
-// Template is a specialized Template from "text/template" that produces a safe
-// HTML document fragment.
-type Template struct {
-	escaped bool
-	// We could embed the text/template field, but it's safer not to because
-	// we need to keep our version of the name space and the underlying
-	// template's in sync.
-	text *template.Template
-	// The underlying template's parse tree, updated to be HTML-safe.
-	Tree       *parse.Tree
-	*nameSpace // common to all associated templates
-}
-
-// nameSpace is the data structure shared by all templates in an association.
-type nameSpace struct {
-	mu  sync.Mutex
-	set map[string]*Template
-}
-
-// Templates returns a slice of the templates associated with t, including t
-// itself.
-func (t *Template) Templates() []*Template {
-	ns := t.nameSpace
-	ns.mu.Lock()
-	defer ns.mu.Unlock()
-	// Return a slice so we don't expose the map.
-	m := make([]*Template, 0, len(ns.set))
-	for _, v := range ns.set {
-		m = append(m, v)
-	}
-	return m
-}
-
-// escape escapes all associated templates.
-func (t *Template) escape() error {
-	t.nameSpace.mu.Lock()
-	defer t.nameSpace.mu.Unlock()
-	if !t.escaped {
-		if err := escapeTemplates(t, t.Name()); err != nil {
-			return err
-		}
-		t.escaped = true
-	}
-	return nil
-}
-
-// Execute applies a parsed template to the specified data object,
-// writing the output to wr.
-// If an error occurs executing the template or writing its output,
-// execution stops, but partial results may already have been written to
-// the output writer.
-// A template may be executed safely in parallel.
-func (t *Template) Execute(wr io.Writer, data interface{}) error {
-	if err := t.escape(); err != nil {
-		return err
-	}
-	return t.text.Execute(wr, data)
-}
-
-// ExecuteTemplate applies the template associated with t that has the given
-// name to the specified data object and writes the output to wr.
-// If an error occurs executing the template or writing its output,
-// execution stops, but partial results may already have been written to
-// the output writer.
-// A template may be executed safely in parallel.
-func (t *Template) ExecuteTemplate(wr io.Writer, name string, data interface{}) error {
-	tmpl, err := t.lookupAndEscapeTemplate(name)
-	if err != nil {
-		return err
-	}
-	return tmpl.text.Execute(wr, data)
-}
-
-// lookupAndEscapeTemplate guarantees that the template with the given name
-// is escaped, or returns an error if it cannot be. It returns the named
-// template.
-func (t *Template) lookupAndEscapeTemplate(name string) (tmpl *Template, err error) {
-	t.nameSpace.mu.Lock()
-	defer t.nameSpace.mu.Unlock()
-	tmpl = t.set[name]
-	if tmpl == nil {
-		return nil, fmt.Errorf("html/template: %q is undefined", name)
-	}
-	if tmpl.text.Tree == nil || tmpl.text.Root == nil {
-		return nil, fmt.Errorf("html/template: %q is an incomplete template", name)
-	}
-	if t.text.Lookup(name) == nil {
-		panic("html/template internal error: template escaping out of sync")
-	}
-	if tmpl != nil && !tmpl.escaped {
-		err = escapeTemplates(tmpl, name)
-	}
-	return tmpl, err
-}
-
-// Parse parses a string into a template. Nested template definitions
-// will be associated with the top-level template t. Parse may be
-// called multiple times to parse definitions of templates to associate
-// with t. It is an error if a resulting template is non-empty (contains
-// content other than template definitions) and would replace a
-// non-empty template with the same name.  (In multiple calls to Parse
-// with the same receiver template, only one call can contain text
-// other than space, comments, and template definitions.)
-func (t *Template) Parse(src string) (*Template, error) {
-	t.nameSpace.mu.Lock()
-	t.escaped = false
-	t.nameSpace.mu.Unlock()
-	ret, err := t.text.Parse(src)
-	if err != nil {
-		return nil, err
-	}
-	// In general, all the named templates might have changed underfoot.
-	// Regardless, some new ones may have been defined.
-	// The template.Template set has been updated; update ours.
-	t.nameSpace.mu.Lock()
-	defer t.nameSpace.mu.Unlock()
-	for _, v := range ret.Templates() {
-		name := v.Name()
-		tmpl := t.set[name]
-		if tmpl == nil {
-			tmpl = t.new(name)
-		}
-		// Restore our record of this text/template to its unescaped original state.
-		tmpl.escaped = false
-		tmpl.text = v
-		tmpl.Tree = v.Tree
-	}
-	return t, nil
-}
-
-// AddParseTree creates a new template with the name and parse tree
-// and associates it with t.
-//
-// It returns an error if t has already been executed.
-func (t *Template) AddParseTree(name string, tree *parse.Tree) (*Template, error) {
-	t.nameSpace.mu.Lock()
-	defer t.nameSpace.mu.Unlock()
-	if t.escaped {
-		return nil, fmt.Errorf("html/template: cannot AddParseTree to %q after it has executed", t.Name())
-	}
-	text, err := t.text.AddParseTree(name, tree)
-	if err != nil {
-		return nil, err
-	}
-	ret := &Template{
-		false,
-		text,
-		text.Tree,
-		t.nameSpace,
-	}
-	t.set[name] = ret
-	return ret, nil
-}
-
-// Clone returns a duplicate of the template, including all associated
-// templates. The actual representation is not copied, but the name space of
-// associated templates is, so further calls to Parse in the copy will add
-// templates to the copy but not to the original. Clone can be used to prepare
-// common templates and use them with variant definitions for other templates
-// by adding the variants after the clone is made.
-//
-// It returns an error if t has already been executed.
-func (t *Template) Clone() (*Template, error) {
-	t.nameSpace.mu.Lock()
-	defer t.nameSpace.mu.Unlock()
-	if t.escaped {
-		return nil, fmt.Errorf("html/template: cannot Clone %q after it has executed", t.Name())
-	}
-	textClone, err := t.text.Clone()
-	if err != nil {
-		return nil, err
-	}
-	ret := &Template{
-		false,
-		textClone,
-		textClone.Tree,
-		&nameSpace{
-			set: make(map[string]*Template),
-		},
-	}
-	for _, x := range textClone.Templates() {
-		name := x.Name()
-		src := t.set[name]
-		if src == nil || src.escaped {
-			return nil, fmt.Errorf("html/template: cannot Clone %q after it has executed", t.Name())
-		}
-		x.Tree = x.Tree.Copy()
-		ret.set[name] = &Template{
-			false,
-			x,
-			x.Tree,
-			ret.nameSpace,
-		}
-	}
-	return ret, nil
-}
-
-// New allocates a new HTML template with the given name.
-func New(name string) *Template {
-	tmpl := &Template{
-		false,
-		template.New(name),
-		nil,
-		&nameSpace{
-			set: make(map[string]*Template),
-		},
-	}
-	tmpl.set[name] = tmpl
-	return tmpl
-}
-
-// New allocates a new HTML template associated with the given one
-// and with the same delimiters. The association, which is transitive,
-// allows one template to invoke another with a {{template}} action.
-func (t *Template) New(name string) *Template {
-	t.nameSpace.mu.Lock()
-	defer t.nameSpace.mu.Unlock()
-	return t.new(name)
-}
-
-// new is the implementation of New, without the lock.
-func (t *Template) new(name string) *Template {
-	tmpl := &Template{
-		false,
-		t.text.New(name),
-		nil,
-		t.nameSpace,
-	}
-	tmpl.set[name] = tmpl
-	return tmpl
-}
-
-// Name returns the name of the template.
-func (t *Template) Name() string {
-	return t.text.Name()
-}
-
-// FuncMap is the type of the map defining the mapping from names to
-// functions. Each function must have either a single return value, or two
-// return values of which the second has type error. In that case, if the
-// second (error) argument evaluates to non-nil during execution, execution
-// terminates and Execute returns that error. FuncMap has the same base type
-// as FuncMap in "text/template", copied here so clients need not import
-// "text/template".
-type FuncMap map[string]interface{}
-
-// Funcs adds the elements of the argument map to the template's function map.
-// It panics if a value in the map is not a function with appropriate return
-// type. However, it is legal to overwrite elements of the map. The return
-// value is the template, so calls can be chained.
-func (t *Template) Funcs(funcMap FuncMap) *Template {
-	t.text.Funcs(template.FuncMap(funcMap))
-	return t
-}
-
-// Delims sets the action delimiters to the specified strings, to be used in
-// subsequent calls to Parse, ParseFiles, or ParseGlob. Nested template
-// definitions will inherit the settings. An empty delimiter stands for the
-// corresponding default: {{ or }}.
-// The return value is the template, so calls can be chained.
-func (t *Template) Delims(left, right string) *Template {
-	t.text.Delims(left, right)
-	return t
-}
-
-// Lookup returns the template with the given name that is associated with t,
-// or nil if there is no such template.
-func (t *Template) Lookup(name string) *Template {
-	t.nameSpace.mu.Lock()
-	defer t.nameSpace.mu.Unlock()
-	return t.set[name]
-}
-
-// Must is a helper that wraps a call to a function returning (*Template, error)
-// and panics if the error is non-nil. It is intended for use in variable initializations
-// such as
-//	var t = template.Must(template.New("name").Parse("html"))
-func Must(t *Template, err error) *Template {
-	if err != nil {
-		panic(err)
-	}
-	return t
-}
-
-// ParseFiles creates a new Template and parses the template definitions from
-// the named files. The returned template's name will have the (base) name and
-// (parsed) contents of the first file. There must be at least one file.
-// If an error occurs, parsing stops and the returned *Template is nil.
-func ParseFiles(filenames ...string) (*Template, error) {
-	return parseFiles(nil, filenames...)
-}
-
-// ParseFiles parses the named files and associates the resulting templates with
-// t. If an error occurs, parsing stops and the returned template is nil;
-// otherwise it is t. There must be at least one file.
-func (t *Template) ParseFiles(filenames ...string) (*Template, error) {
-	return parseFiles(t, filenames...)
-}
-
-// parseFiles is the helper for the method and function. If the argument
-// template is nil, it is created from the first file.
-func parseFiles(t *Template, filenames ...string) (*Template, error) {
-	if len(filenames) == 0 {
-		// Not really a problem, but be consistent.
-		return nil, fmt.Errorf("html/template: no files named in call to ParseFiles")
-	}
-	for _, filename := range filenames {
-		b, err := ioutil.ReadFile(filename)
-		if err != nil {
-			return nil, err
-		}
-		s := string(b)
-		name := filepath.Base(filename)
-		// First template becomes return value if not already defined,
-		// and we use that one for subsequent New calls to associate
-		// all the templates together. Also, if this file has the same name
-		// as t, this file becomes the contents of t, so
-		//  t, err := New(name).Funcs(xxx).ParseFiles(name)
-		// works. Otherwise we create a new template associated with t.
-		var tmpl *Template
-		if t == nil {
-			t = New(name)
-		}
-		if name == t.Name() {
-			tmpl = t
-		} else {
-			tmpl = t.New(name)
-		}
-		_, err = tmpl.Parse(s)
-		if err != nil {
-			return nil, err
-		}
-	}
-	return t, nil
-}
-
-// ParseGlob creates a new Template and parses the template definitions from the
-// files identified by the pattern, which must match at least one file. The
-// returned template will have the (base) name and (parsed) contents of the
-// first file matched by the pattern. ParseGlob is equivalent to calling
-// ParseFiles with the list of files matched by the pattern.
-func ParseGlob(pattern string) (*Template, error) {
-	return parseGlob(nil, pattern)
-}
-
-// ParseGlob parses the template definitions in the files identified by the
-// pattern and associates the resulting templates with t. The pattern is
-// processed by filepath.Glob and must match at least one file. ParseGlob is
-// equivalent to calling t.ParseFiles with the list of files matched by the
-// pattern.
-func (t *Template) ParseGlob(pattern string) (*Template, error) {
-	return parseGlob(t, pattern)
-}
-
-// parseGlob is the implementation of the function and method ParseGlob.
-func parseGlob(t *Template, pattern string) (*Template, error) {
-	filenames, err := filepath.Glob(pattern)
-	if err != nil {
-		return nil, err
-	}
-	if len(filenames) == 0 {
-		return nil, fmt.Errorf("html/template: pattern matches no files: %#q", pattern)
-	}
-	return parseFiles(t, filenames...)
-}
diff --git a/src/pkg/html/template/transition.go b/src/pkg/html/template/transition.go
deleted file mode 100644
index 7f30a7a..0000000
--- a/src/pkg/html/template/transition.go
+++ /dev/null
@@ -1,550 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package template
-
-import (
-	"bytes"
-	"strings"
-)
-
-// transitionFunc is the array of context transition functions for text nodes.
-// A transition function takes a context and template text input, and returns
-// the updated context and the number of bytes consumed from the front of the
-// input.
-var transitionFunc = [...]func(context, []byte) (context, int){
-	stateText:        tText,
-	stateTag:         tTag,
-	stateAttrName:    tAttrName,
-	stateAfterName:   tAfterName,
-	stateBeforeValue: tBeforeValue,
-	stateHTMLCmt:     tHTMLCmt,
-	stateRCDATA:      tSpecialTagEnd,
-	stateAttr:        tAttr,
-	stateURL:         tURL,
-	stateJS:          tJS,
-	stateJSDqStr:     tJSDelimited,
-	stateJSSqStr:     tJSDelimited,
-	stateJSRegexp:    tJSDelimited,
-	stateJSBlockCmt:  tBlockCmt,
-	stateJSLineCmt:   tLineCmt,
-	stateCSS:         tCSS,
-	stateCSSDqStr:    tCSSStr,
-	stateCSSSqStr:    tCSSStr,
-	stateCSSDqURL:    tCSSStr,
-	stateCSSSqURL:    tCSSStr,
-	stateCSSURL:      tCSSStr,
-	stateCSSBlockCmt: tBlockCmt,
-	stateCSSLineCmt:  tLineCmt,
-	stateError:       tError,
-}
-
-var commentStart = []byte("<!--")
-var commentEnd = []byte("-->")
-
-// tText is the context transition function for the text state.
-func tText(c context, s []byte) (context, int) {
-	k := 0
-	for {
-		i := k + bytes.IndexByte(s[k:], '<')
-		if i < k || i+1 == len(s) {
-			return c, len(s)
-		} else if i+4 <= len(s) && bytes.Equal(commentStart, s[i:i+4]) {
-			return context{state: stateHTMLCmt}, i + 4
-		}
-		i++
-		end := false
-		if s[i] == '/' {
-			if i+1 == len(s) {
-				return c, len(s)
-			}
-			end, i = true, i+1
-		}
-		j, e := eatTagName(s, i)
-		if j != i {
-			if end {
-				e = elementNone
-			}
-			// We've found an HTML tag.
-			return context{state: stateTag, element: e}, j
-		}
-		k = j
-	}
-}
-
-var elementContentType = [...]state{
-	elementNone:     stateText,
-	elementScript:   stateJS,
-	elementStyle:    stateCSS,
-	elementTextarea: stateRCDATA,
-	elementTitle:    stateRCDATA,
-}
-
-// tTag is the context transition function for the tag state.
-func tTag(c context, s []byte) (context, int) {
-	// Find the attribute name.
-	i := eatWhiteSpace(s, 0)
-	if i == len(s) {
-		return c, len(s)
-	}
-	if s[i] == '>' {
-		return context{
-			state:   elementContentType[c.element],
-			element: c.element,
-		}, i + 1
-	}
-	j, err := eatAttrName(s, i)
-	if err != nil {
-		return context{state: stateError, err: err}, len(s)
-	}
-	state, attr := stateTag, attrNone
-	if i == j {
-		return context{
-			state: stateError,
-			err:   errorf(ErrBadHTML, 0, "expected space, attr name, or end of tag, but got %q", s[i:]),
-		}, len(s)
-	}
-	switch attrType(string(s[i:j])) {
-	case contentTypeURL:
-		attr = attrURL
-	case contentTypeCSS:
-		attr = attrStyle
-	case contentTypeJS:
-		attr = attrScript
-	}
-	if j == len(s) {
-		state = stateAttrName
-	} else {
-		state = stateAfterName
-	}
-	return context{state: state, element: c.element, attr: attr}, j
-}
-
-// tAttrName is the context transition function for stateAttrName.
-func tAttrName(c context, s []byte) (context, int) {
-	i, err := eatAttrName(s, 0)
-	if err != nil {
-		return context{state: stateError, err: err}, len(s)
-	} else if i != len(s) {
-		c.state = stateAfterName
-	}
-	return c, i
-}
-
-// tAfterName is the context transition function for stateAfterName.
-func tAfterName(c context, s []byte) (context, int) {
-	// Look for the start of the value.
-	i := eatWhiteSpace(s, 0)
-	if i == len(s) {
-		return c, len(s)
-	} else if s[i] != '=' {
-		// Occurs due to tag ending '>', and valueless attribute.
-		c.state = stateTag
-		return c, i
-	}
-	c.state = stateBeforeValue
-	// Consume the "=".
-	return c, i + 1
-}
-
-var attrStartStates = [...]state{
-	attrNone:   stateAttr,
-	attrScript: stateJS,
-	attrStyle:  stateCSS,
-	attrURL:    stateURL,
-}
-
-// tBeforeValue is the context transition function for stateBeforeValue.
-func tBeforeValue(c context, s []byte) (context, int) {
-	i := eatWhiteSpace(s, 0)
-	if i == len(s) {
-		return c, len(s)
-	}
-	// Find the attribute delimiter.
-	delim := delimSpaceOrTagEnd
-	switch s[i] {
-	case '\'':
-		delim, i = delimSingleQuote, i+1
-	case '"':
-		delim, i = delimDoubleQuote, i+1
-	}
-	c.state, c.delim, c.attr = attrStartStates[c.attr], delim, attrNone
-	return c, i
-}
-
-// tHTMLCmt is the context transition function for stateHTMLCmt.
-func tHTMLCmt(c context, s []byte) (context, int) {
-	if i := bytes.Index(s, commentEnd); i != -1 {
-		return context{}, i + 3
-	}
-	return c, len(s)
-}
-
-// specialTagEndMarkers maps element types to the character sequence that
-// case-insensitively signals the end of the special tag body.
-var specialTagEndMarkers = [...]string{
-	elementScript:   "</script",
-	elementStyle:    "</style",
-	elementTextarea: "</textarea",
-	elementTitle:    "</title",
-}
-
-// tSpecialTagEnd is the context transition function for raw text and RCDATA
-// element states.
-func tSpecialTagEnd(c context, s []byte) (context, int) {
-	if c.element != elementNone {
-		if i := strings.Index(strings.ToLower(string(s)), specialTagEndMarkers[c.element]); i != -1 {
-			return context{}, i
-		}
-	}
-	return c, len(s)
-}
-
-// tAttr is the context transition function for the attribute state.
-func tAttr(c context, s []byte) (context, int) {
-	return c, len(s)
-}
-
-// tURL is the context transition function for the URL state.
-func tURL(c context, s []byte) (context, int) {
-	if bytes.IndexAny(s, "#?") >= 0 {
-		c.urlPart = urlPartQueryOrFrag
-	} else if len(s) != eatWhiteSpace(s, 0) && c.urlPart == urlPartNone {
-		// HTML5 uses "Valid URL potentially surrounded by spaces" for
-		// attrs: http://www.w3.org/TR/html5/index.html#attributes-1
-		c.urlPart = urlPartPreQuery
-	}
-	return c, len(s)
-}
-
-// tJS is the context transition function for the JS state.
-func tJS(c context, s []byte) (context, int) {
-	i := bytes.IndexAny(s, `"'/`)
-	if i == -1 {
-		// Entire input is non string, comment, regexp tokens.
-		c.jsCtx = nextJSCtx(s, c.jsCtx)
-		return c, len(s)
-	}
-	c.jsCtx = nextJSCtx(s[:i], c.jsCtx)
-	switch s[i] {
-	case '"':
-		c.state, c.jsCtx = stateJSDqStr, jsCtxRegexp
-	case '\'':
-		c.state, c.jsCtx = stateJSSqStr, jsCtxRegexp
-	case '/':
-		switch {
-		case i+1 < len(s) && s[i+1] == '/':
-			c.state, i = stateJSLineCmt, i+1
-		case i+1 < len(s) && s[i+1] == '*':
-			c.state, i = stateJSBlockCmt, i+1
-		case c.jsCtx == jsCtxRegexp:
-			c.state = stateJSRegexp
-		case c.jsCtx == jsCtxDivOp:
-			c.jsCtx = jsCtxRegexp
-		default:
-			return context{
-				state: stateError,
-				err:   errorf(ErrSlashAmbig, 0, "'/' could start a division or regexp: %.32q", s[i:]),
-			}, len(s)
-		}
-	default:
-		panic("unreachable")
-	}
-	return c, i + 1
-}
-
-// tJSDelimited is the context transition function for the JS string and regexp
-// states.
-func tJSDelimited(c context, s []byte) (context, int) {
-	specials := `\"`
-	switch c.state {
-	case stateJSSqStr:
-		specials = `\'`
-	case stateJSRegexp:
-		specials = `\/[]`
-	}
-
-	k, inCharset := 0, false
-	for {
-		i := k + bytes.IndexAny(s[k:], specials)
-		if i < k {
-			break
-		}
-		switch s[i] {
-		case '\\':
-			i++
-			if i == len(s) {
-				return context{
-					state: stateError,
-					err:   errorf(ErrPartialEscape, 0, "unfinished escape sequence in JS string: %q", s),
-				}, len(s)
-			}
-		case '[':
-			inCharset = true
-		case ']':
-			inCharset = false
-		default:
-			// end delimiter
-			if !inCharset {
-				c.state, c.jsCtx = stateJS, jsCtxDivOp
-				return c, i + 1
-			}
-		}
-		k = i + 1
-	}
-
-	if inCharset {
-		// This can be fixed by making context richer if interpolation
-		// into charsets is desired.
-		return context{
-			state: stateError,
-			err:   errorf(ErrPartialCharset, 0, "unfinished JS regexp charset: %q", s),
-		}, len(s)
-	}
-
-	return c, len(s)
-}
-
-var blockCommentEnd = []byte("*/")
-
-// tBlockCmt is the context transition function for /*comment*/ states.
-func tBlockCmt(c context, s []byte) (context, int) {
-	i := bytes.Index(s, blockCommentEnd)
-	if i == -1 {
-		return c, len(s)
-	}
-	switch c.state {
-	case stateJSBlockCmt:
-		c.state = stateJS
-	case stateCSSBlockCmt:
-		c.state = stateCSS
-	default:
-		panic(c.state.String())
-	}
-	return c, i + 2
-}
-
-// tLineCmt is the context transition function for //comment states.
-func tLineCmt(c context, s []byte) (context, int) {
-	var lineTerminators string
-	var endState state
-	switch c.state {
-	case stateJSLineCmt:
-		lineTerminators, endState = "\n\r\u2028\u2029", stateJS
-	case stateCSSLineCmt:
-		lineTerminators, endState = "\n\f\r", stateCSS
-		// Line comments are not part of any published CSS standard but
-		// are supported by the 4 major browsers.
-		// This defines line comments as
-		//     LINECOMMENT ::= "//" [^\n\f\d]*
-		// since http://www.w3.org/TR/css3-syntax/#SUBTOK-nl defines
-		// newlines:
-		//     nl ::= #xA | #xD #xA | #xD | #xC
-	default:
-		panic(c.state.String())
-	}
-
-	i := bytes.IndexAny(s, lineTerminators)
-	if i == -1 {
-		return c, len(s)
-	}
-	c.state = endState
-	// Per section 7.4 of EcmaScript 5 : http://es5.github.com/#x7.4
-	// "However, the LineTerminator at the end of the line is not
-	// considered to be part of the single-line comment; it is
-	// recognized separately by the lexical grammar and becomes part
-	// of the stream of input elements for the syntactic grammar."
-	return c, i
-}
-
-// tCSS is the context transition function for the CSS state.
-func tCSS(c context, s []byte) (context, int) {
-	// CSS quoted strings are almost never used except for:
-	// (1) URLs as in background: "/foo.png"
-	// (2) Multiword font-names as in font-family: "Times New Roman"
-	// (3) List separators in content values as in inline-lists:
-	//    <style>
-	//    ul.inlineList { list-style: none; padding:0 }
-	//    ul.inlineList > li { display: inline }
-	//    ul.inlineList > li:before { content: ", " }
-	//    ul.inlineList > li:first-child:before { content: "" }
-	//    </style>
-	//    <ul class=inlineList><li>One<li>Two<li>Three</ul>
-	// (4) Attribute value selectors as in a[href="http://example.com/"]
-	//
-	// We conservatively treat all strings as URLs, but make some
-	// allowances to avoid confusion.
-	//
-	// In (1), our conservative assumption is justified.
-	// In (2), valid font names do not contain ':', '?', or '#', so our
-	// conservative assumption is fine since we will never transition past
-	// urlPartPreQuery.
-	// In (3), our protocol heuristic should not be tripped, and there
-	// should not be non-space content after a '?' or '#', so as long as
-	// we only %-encode RFC 3986 reserved characters we are ok.
-	// In (4), we should URL escape for URL attributes, and for others we
-	// have the attribute name available if our conservative assumption
-	// proves problematic for real code.
-
-	k := 0
-	for {
-		i := k + bytes.IndexAny(s[k:], `("'/`)
-		if i < k {
-			return c, len(s)
-		}
-		switch s[i] {
-		case '(':
-			// Look for url to the left.
-			p := bytes.TrimRight(s[:i], "\t\n\f\r ")
-			if endsWithCSSKeyword(p, "url") {
-				j := len(s) - len(bytes.TrimLeft(s[i+1:], "\t\n\f\r "))
-				switch {
-				case j != len(s) && s[j] == '"':
-					c.state, j = stateCSSDqURL, j+1
-				case j != len(s) && s[j] == '\'':
-					c.state, j = stateCSSSqURL, j+1
-				default:
-					c.state = stateCSSURL
-				}
-				return c, j
-			}
-		case '/':
-			if i+1 < len(s) {
-				switch s[i+1] {
-				case '/':
-					c.state = stateCSSLineCmt
-					return c, i + 2
-				case '*':
-					c.state = stateCSSBlockCmt
-					return c, i + 2
-				}
-			}
-		case '"':
-			c.state = stateCSSDqStr
-			return c, i + 1
-		case '\'':
-			c.state = stateCSSSqStr
-			return c, i + 1
-		}
-		k = i + 1
-	}
-}
-
-// tCSSStr is the context transition function for the CSS string and URL states.
-func tCSSStr(c context, s []byte) (context, int) {
-	var endAndEsc string
-	switch c.state {
-	case stateCSSDqStr, stateCSSDqURL:
-		endAndEsc = `\"`
-	case stateCSSSqStr, stateCSSSqURL:
-		endAndEsc = `\'`
-	case stateCSSURL:
-		// Unquoted URLs end with a newline or close parenthesis.
-		// The below includes the wc (whitespace character) and nl.
-		endAndEsc = "\\\t\n\f\r )"
-	default:
-		panic(c.state.String())
-	}
-
-	k := 0
-	for {
-		i := k + bytes.IndexAny(s[k:], endAndEsc)
-		if i < k {
-			c, nread := tURL(c, decodeCSS(s[k:]))
-			return c, k + nread
-		}
-		if s[i] == '\\' {
-			i++
-			if i == len(s) {
-				return context{
-					state: stateError,
-					err:   errorf(ErrPartialEscape, 0, "unfinished escape sequence in CSS string: %q", s),
-				}, len(s)
-			}
-		} else {
-			c.state = stateCSS
-			return c, i + 1
-		}
-		c, _ = tURL(c, decodeCSS(s[:i+1]))
-		k = i + 1
-	}
-}
-
-// tError is the context transition function for the error state.
-func tError(c context, s []byte) (context, int) {
-	return c, len(s)
-}
-
-// eatAttrName returns the largest j such that s[i:j] is an attribute name.
-// It returns an error if s[i:] does not look like it begins with an
-// attribute name, such as encountering a quote mark without a preceding
-// equals sign.
-func eatAttrName(s []byte, i int) (int, *Error) {
-	for j := i; j < len(s); j++ {
-		switch s[j] {
-		case ' ', '\t', '\n', '\f', '\r', '=', '>':
-			return j, nil
-		case '\'', '"', '<':
-			// These result in a parse warning in HTML5 and are
-			// indicative of serious problems if seen in an attr
-			// name in a template.
-			return -1, errorf(ErrBadHTML, 0, "%q in attribute name: %.32q", s[j:j+1], s)
-		default:
-			// No-op.
-		}
-	}
-	return len(s), nil
-}
-
-var elementNameMap = map[string]element{
-	"script":   elementScript,
-	"style":    elementStyle,
-	"textarea": elementTextarea,
-	"title":    elementTitle,
-}
-
-// asciiAlpha reports whether c is an ASCII letter.
-func asciiAlpha(c byte) bool {
-	return 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z'
-}
-
-// asciiAlphaNum reports whether c is an ASCII letter or digit.
-func asciiAlphaNum(c byte) bool {
-	return asciiAlpha(c) || '0' <= c && c <= '9'
-}
-
-// eatTagName returns the largest j such that s[i:j] is a tag name and the tag type.
-func eatTagName(s []byte, i int) (int, element) {
-	if i == len(s) || !asciiAlpha(s[i]) {
-		return i, elementNone
-	}
-	j := i + 1
-	for j < len(s) {
-		x := s[j]
-		if asciiAlphaNum(x) {
-			j++
-			continue
-		}
-		// Allow "x-y" or "x:y" but not "x-", "-y", or "x--y".
-		if (x == ':' || x == '-') && j+1 < len(s) && asciiAlphaNum(s[j+1]) {
-			j += 2
-			continue
-		}
-		break
-	}
-	return j, elementNameMap[strings.ToLower(string(s[i:j]))]
-}
-
-// eatWhiteSpace returns the largest j such that s[i:j] is white space.
-func eatWhiteSpace(s []byte, i int) int {
-	for j := i; j < len(s); j++ {
-		switch s[j] {
-		case ' ', '\t', '\n', '\f', '\r':
-			// No-op.
-		default:
-			return j
-		}
-	}
-	return len(s)
-}
diff --git a/src/pkg/image/color/palette/gen.go b/src/pkg/image/color/palette/gen.go
deleted file mode 100644
index 4f4d883..0000000
--- a/src/pkg/image/color/palette/gen.go
+++ /dev/null
@@ -1,101 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build ignore
-
-package main
-
-// This program generates palette.go. Invoke it as
-//	go run gen.go | gofmt > palette.go
-
-import (
-	"fmt"
-)
-
-func main() {
-	fmt.Println(`// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.`)
-	fmt.Println()
-	fmt.Println("// generated by go run gen.go; DO NOT EDIT")
-	fmt.Println()
-	fmt.Println("// Package palette provides standard color palettes.")
-	fmt.Println("package palette")
-	fmt.Println()
-	fmt.Println(`import "image/color"`)
-	fmt.Println()
-	printPlan9()
-	printWebSafe()
-}
-
-func printPlan9() {
-	c, lines := [3]int{}, [256]string{}
-	for r, i := 0, 0; r != 4; r++ {
-		for v := 0; v != 4; v, i = v+1, i+16 {
-			for g, j := 0, v-r; g != 4; g++ {
-				for b := 0; b != 4; b, j = b+1, j+1 {
-					den := r
-					if g > den {
-						den = g
-					}
-					if b > den {
-						den = b
-					}
-					if den == 0 {
-						c[0] = 0x11 * v
-						c[1] = 0x11 * v
-						c[2] = 0x11 * v
-					} else {
-						num := 17 * (4*den + v)
-						c[0] = r * num / den
-						c[1] = g * num / den
-						c[2] = b * num / den
-					}
-					lines[i+(j&0x0f)] =
-						fmt.Sprintf("\tcolor.RGBA{0x%02x, 0x%02x, 0x%02x, 0xff},", c[0], c[1], c[2])
-				}
-			}
-		}
-	}
-	fmt.Println("// Plan9 is a 256-color palette that partitions the 24-bit RGB space")
-	fmt.Println("// into 4×4×4 subdivision, with 4 shades in each subcube. Compared to the")
-	fmt.Println("// WebSafe, the idea is to reduce the color resolution by dicing the")
-	fmt.Println("// color cube into fewer cells, and to use the extra space to increase the")
-	fmt.Println("// intensity resolution. This results in 16 gray shades (4 gray subcubes with")
-	fmt.Println("// 4 samples in each), 13 shades of each primary and secondary color (3")
-	fmt.Println("// subcubes with 4 samples plus black) and a reasonable selection of colors")
-	fmt.Println("// covering the rest of the color cube. The advantage is better representation")
-	fmt.Println("// of continuous tones.")
-	fmt.Println("//")
-	fmt.Println("// This palette was used in the Plan 9 Operating System, described at")
-	fmt.Println("// http://plan9.bell-labs.com/magic/man2html/6/color")
-	fmt.Println("var Plan9 = []color.Color{")
-	for _, line := range lines {
-		fmt.Println(line)
-	}
-	fmt.Println("}")
-	fmt.Println()
-}
-
-func printWebSafe() {
-	lines := [6 * 6 * 6]string{}
-	for r := 0; r < 6; r++ {
-		for g := 0; g < 6; g++ {
-			for b := 0; b < 6; b++ {
-				lines[36*r+6*g+b] =
-					fmt.Sprintf("\tcolor.RGBA{0x%02x, 0x%02x, 0x%02x, 0xff},", 0x33*r, 0x33*g, 0x33*b)
-			}
-		}
-	}
-	fmt.Println("// WebSafe is a 216-color palette that was popularized by early versions")
-	fmt.Println("// of Netscape Navigator. It is also known as the Netscape Color Cube.")
-	fmt.Println("//")
-	fmt.Println("// See http://en.wikipedia.org/wiki/Web_colors#Web-safe_colors for details.")
-	fmt.Println("var WebSafe = []color.Color{")
-	for _, line := range lines {
-		fmt.Println(line)
-	}
-	fmt.Println("}")
-	fmt.Println()
-}
diff --git a/src/pkg/image/color/palette/palette.go b/src/pkg/image/color/palette/palette.go
deleted file mode 100644
index f761e53..0000000
--- a/src/pkg/image/color/palette/palette.go
+++ /dev/null
@@ -1,504 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// generated by go run gen.go; DO NOT EDIT
-
-// Package palette provides standard color palettes.
-package palette
-
-import "image/color"
-
-// Plan9 is a 256-color palette that partitions the 24-bit RGB space
-// into 4×4×4 subdivision, with 4 shades in each subcube. Compared to the
-// WebSafe, the idea is to reduce the color resolution by dicing the
-// color cube into fewer cells, and to use the extra space to increase the
-// intensity resolution. This results in 16 gray shades (4 gray subcubes with
-// 4 samples in each), 13 shades of each primary and secondary color (3
-// subcubes with 4 samples plus black) and a reasonable selection of colors
-// covering the rest of the color cube. The advantage is better representation
-// of continuous tones.
-//
-// This palette was used in the Plan 9 Operating System, described at
-// http://plan9.bell-labs.com/magic/man2html/6/color
-var Plan9 = []color.Color{
-	color.RGBA{0x00, 0x00, 0x00, 0xff},
-	color.RGBA{0x00, 0x00, 0x44, 0xff},
-	color.RGBA{0x00, 0x00, 0x88, 0xff},
-	color.RGBA{0x00, 0x00, 0xcc, 0xff},
-	color.RGBA{0x00, 0x44, 0x00, 0xff},
-	color.RGBA{0x00, 0x44, 0x44, 0xff},
-	color.RGBA{0x00, 0x44, 0x88, 0xff},
-	color.RGBA{0x00, 0x44, 0xcc, 0xff},
-	color.RGBA{0x00, 0x88, 0x00, 0xff},
-	color.RGBA{0x00, 0x88, 0x44, 0xff},
-	color.RGBA{0x00, 0x88, 0x88, 0xff},
-	color.RGBA{0x00, 0x88, 0xcc, 0xff},
-	color.RGBA{0x00, 0xcc, 0x00, 0xff},
-	color.RGBA{0x00, 0xcc, 0x44, 0xff},
-	color.RGBA{0x00, 0xcc, 0x88, 0xff},
-	color.RGBA{0x00, 0xcc, 0xcc, 0xff},
-	color.RGBA{0x00, 0xdd, 0xdd, 0xff},
-	color.RGBA{0x11, 0x11, 0x11, 0xff},
-	color.RGBA{0x00, 0x00, 0x55, 0xff},
-	color.RGBA{0x00, 0x00, 0x99, 0xff},
-	color.RGBA{0x00, 0x00, 0xdd, 0xff},
-	color.RGBA{0x00, 0x55, 0x00, 0xff},
-	color.RGBA{0x00, 0x55, 0x55, 0xff},
-	color.RGBA{0x00, 0x4c, 0x99, 0xff},
-	color.RGBA{0x00, 0x49, 0xdd, 0xff},
-	color.RGBA{0x00, 0x99, 0x00, 0xff},
-	color.RGBA{0x00, 0x99, 0x4c, 0xff},
-	color.RGBA{0x00, 0x99, 0x99, 0xff},
-	color.RGBA{0x00, 0x93, 0xdd, 0xff},
-	color.RGBA{0x00, 0xdd, 0x00, 0xff},
-	color.RGBA{0x00, 0xdd, 0x49, 0xff},
-	color.RGBA{0x00, 0xdd, 0x93, 0xff},
-	color.RGBA{0x00, 0xee, 0x9e, 0xff},
-	color.RGBA{0x00, 0xee, 0xee, 0xff},
-	color.RGBA{0x22, 0x22, 0x22, 0xff},
-	color.RGBA{0x00, 0x00, 0x66, 0xff},
-	color.RGBA{0x00, 0x00, 0xaa, 0xff},
-	color.RGBA{0x00, 0x00, 0xee, 0xff},
-	color.RGBA{0x00, 0x66, 0x00, 0xff},
-	color.RGBA{0x00, 0x66, 0x66, 0xff},
-	color.RGBA{0x00, 0x55, 0xaa, 0xff},
-	color.RGBA{0x00, 0x4f, 0xee, 0xff},
-	color.RGBA{0x00, 0xaa, 0x00, 0xff},
-	color.RGBA{0x00, 0xaa, 0x55, 0xff},
-	color.RGBA{0x00, 0xaa, 0xaa, 0xff},
-	color.RGBA{0x00, 0x9e, 0xee, 0xff},
-	color.RGBA{0x00, 0xee, 0x00, 0xff},
-	color.RGBA{0x00, 0xee, 0x4f, 0xff},
-	color.RGBA{0x00, 0xff, 0x55, 0xff},
-	color.RGBA{0x00, 0xff, 0xaa, 0xff},
-	color.RGBA{0x00, 0xff, 0xff, 0xff},
-	color.RGBA{0x33, 0x33, 0x33, 0xff},
-	color.RGBA{0x00, 0x00, 0x77, 0xff},
-	color.RGBA{0x00, 0x00, 0xbb, 0xff},
-	color.RGBA{0x00, 0x00, 0xff, 0xff},
-	color.RGBA{0x00, 0x77, 0x00, 0xff},
-	color.RGBA{0x00, 0x77, 0x77, 0xff},
-	color.RGBA{0x00, 0x5d, 0xbb, 0xff},
-	color.RGBA{0x00, 0x55, 0xff, 0xff},
-	color.RGBA{0x00, 0xbb, 0x00, 0xff},
-	color.RGBA{0x00, 0xbb, 0x5d, 0xff},
-	color.RGBA{0x00, 0xbb, 0xbb, 0xff},
-	color.RGBA{0x00, 0xaa, 0xff, 0xff},
-	color.RGBA{0x00, 0xff, 0x00, 0xff},
-	color.RGBA{0x44, 0x00, 0x44, 0xff},
-	color.RGBA{0x44, 0x00, 0x88, 0xff},
-	color.RGBA{0x44, 0x00, 0xcc, 0xff},
-	color.RGBA{0x44, 0x44, 0x00, 0xff},
-	color.RGBA{0x44, 0x44, 0x44, 0xff},
-	color.RGBA{0x44, 0x44, 0x88, 0xff},
-	color.RGBA{0x44, 0x44, 0xcc, 0xff},
-	color.RGBA{0x44, 0x88, 0x00, 0xff},
-	color.RGBA{0x44, 0x88, 0x44, 0xff},
-	color.RGBA{0x44, 0x88, 0x88, 0xff},
-	color.RGBA{0x44, 0x88, 0xcc, 0xff},
-	color.RGBA{0x44, 0xcc, 0x00, 0xff},
-	color.RGBA{0x44, 0xcc, 0x44, 0xff},
-	color.RGBA{0x44, 0xcc, 0x88, 0xff},
-	color.RGBA{0x44, 0xcc, 0xcc, 0xff},
-	color.RGBA{0x44, 0x00, 0x00, 0xff},
-	color.RGBA{0x55, 0x00, 0x00, 0xff},
-	color.RGBA{0x55, 0x00, 0x55, 0xff},
-	color.RGBA{0x4c, 0x00, 0x99, 0xff},
-	color.RGBA{0x49, 0x00, 0xdd, 0xff},
-	color.RGBA{0x55, 0x55, 0x00, 0xff},
-	color.RGBA{0x55, 0x55, 0x55, 0xff},
-	color.RGBA{0x4c, 0x4c, 0x99, 0xff},
-	color.RGBA{0x49, 0x49, 0xdd, 0xff},
-	color.RGBA{0x4c, 0x99, 0x00, 0xff},
-	color.RGBA{0x4c, 0x99, 0x4c, 0xff},
-	color.RGBA{0x4c, 0x99, 0x99, 0xff},
-	color.RGBA{0x49, 0x93, 0xdd, 0xff},
-	color.RGBA{0x49, 0xdd, 0x00, 0xff},
-	color.RGBA{0x49, 0xdd, 0x49, 0xff},
-	color.RGBA{0x49, 0xdd, 0x93, 0xff},
-	color.RGBA{0x49, 0xdd, 0xdd, 0xff},
-	color.RGBA{0x4f, 0xee, 0xee, 0xff},
-	color.RGBA{0x66, 0x00, 0x00, 0xff},
-	color.RGBA{0x66, 0x00, 0x66, 0xff},
-	color.RGBA{0x55, 0x00, 0xaa, 0xff},
-	color.RGBA{0x4f, 0x00, 0xee, 0xff},
-	color.RGBA{0x66, 0x66, 0x00, 0xff},
-	color.RGBA{0x66, 0x66, 0x66, 0xff},
-	color.RGBA{0x55, 0x55, 0xaa, 0xff},
-	color.RGBA{0x4f, 0x4f, 0xee, 0xff},
-	color.RGBA{0x55, 0xaa, 0x00, 0xff},
-	color.RGBA{0x55, 0xaa, 0x55, 0xff},
-	color.RGBA{0x55, 0xaa, 0xaa, 0xff},
-	color.RGBA{0x4f, 0x9e, 0xee, 0xff},
-	color.RGBA{0x4f, 0xee, 0x00, 0xff},
-	color.RGBA{0x4f, 0xee, 0x4f, 0xff},
-	color.RGBA{0x4f, 0xee, 0x9e, 0xff},
-	color.RGBA{0x55, 0xff, 0xaa, 0xff},
-	color.RGBA{0x55, 0xff, 0xff, 0xff},
-	color.RGBA{0x77, 0x00, 0x00, 0xff},
-	color.RGBA{0x77, 0x00, 0x77, 0xff},
-	color.RGBA{0x5d, 0x00, 0xbb, 0xff},
-	color.RGBA{0x55, 0x00, 0xff, 0xff},
-	color.RGBA{0x77, 0x77, 0x00, 0xff},
-	color.RGBA{0x77, 0x77, 0x77, 0xff},
-	color.RGBA{0x5d, 0x5d, 0xbb, 0xff},
-	color.RGBA{0x55, 0x55, 0xff, 0xff},
-	color.RGBA{0x5d, 0xbb, 0x00, 0xff},
-	color.RGBA{0x5d, 0xbb, 0x5d, 0xff},
-	color.RGBA{0x5d, 0xbb, 0xbb, 0xff},
-	color.RGBA{0x55, 0xaa, 0xff, 0xff},
-	color.RGBA{0x55, 0xff, 0x00, 0xff},
-	color.RGBA{0x55, 0xff, 0x55, 0xff},
-	color.RGBA{0x88, 0x00, 0x88, 0xff},
-	color.RGBA{0x88, 0x00, 0xcc, 0xff},
-	color.RGBA{0x88, 0x44, 0x00, 0xff},
-	color.RGBA{0x88, 0x44, 0x44, 0xff},
-	color.RGBA{0x88, 0x44, 0x88, 0xff},
-	color.RGBA{0x88, 0x44, 0xcc, 0xff},
-	color.RGBA{0x88, 0x88, 0x00, 0xff},
-	color.RGBA{0x88, 0x88, 0x44, 0xff},
-	color.RGBA{0x88, 0x88, 0x88, 0xff},
-	color.RGBA{0x88, 0x88, 0xcc, 0xff},
-	color.RGBA{0x88, 0xcc, 0x00, 0xff},
-	color.RGBA{0x88, 0xcc, 0x44, 0xff},
-	color.RGBA{0x88, 0xcc, 0x88, 0xff},
-	color.RGBA{0x88, 0xcc, 0xcc, 0xff},
-	color.RGBA{0x88, 0x00, 0x00, 0xff},
-	color.RGBA{0x88, 0x00, 0x44, 0xff},
-	color.RGBA{0x99, 0x00, 0x4c, 0xff},
-	color.RGBA{0x99, 0x00, 0x99, 0xff},
-	color.RGBA{0x93, 0x00, 0xdd, 0xff},
-	color.RGBA{0x99, 0x4c, 0x00, 0xff},
-	color.RGBA{0x99, 0x4c, 0x4c, 0xff},
-	color.RGBA{0x99, 0x4c, 0x99, 0xff},
-	color.RGBA{0x93, 0x49, 0xdd, 0xff},
-	color.RGBA{0x99, 0x99, 0x00, 0xff},
-	color.RGBA{0x99, 0x99, 0x4c, 0xff},
-	color.RGBA{0x99, 0x99, 0x99, 0xff},
-	color.RGBA{0x93, 0x93, 0xdd, 0xff},
-	color.RGBA{0x93, 0xdd, 0x00, 0xff},
-	color.RGBA{0x93, 0xdd, 0x49, 0xff},
-	color.RGBA{0x93, 0xdd, 0x93, 0xff},
-	color.RGBA{0x93, 0xdd, 0xdd, 0xff},
-	color.RGBA{0x99, 0x00, 0x00, 0xff},
-	color.RGBA{0xaa, 0x00, 0x00, 0xff},
-	color.RGBA{0xaa, 0x00, 0x55, 0xff},
-	color.RGBA{0xaa, 0x00, 0xaa, 0xff},
-	color.RGBA{0x9e, 0x00, 0xee, 0xff},
-	color.RGBA{0xaa, 0x55, 0x00, 0xff},
-	color.RGBA{0xaa, 0x55, 0x55, 0xff},
-	color.RGBA{0xaa, 0x55, 0xaa, 0xff},
-	color.RGBA{0x9e, 0x4f, 0xee, 0xff},
-	color.RGBA{0xaa, 0xaa, 0x00, 0xff},
-	color.RGBA{0xaa, 0xaa, 0x55, 0xff},
-	color.RGBA{0xaa, 0xaa, 0xaa, 0xff},
-	color.RGBA{0x9e, 0x9e, 0xee, 0xff},
-	color.RGBA{0x9e, 0xee, 0x00, 0xff},
-	color.RGBA{0x9e, 0xee, 0x4f, 0xff},
-	color.RGBA{0x9e, 0xee, 0x9e, 0xff},
-	color.RGBA{0x9e, 0xee, 0xee, 0xff},
-	color.RGBA{0xaa, 0xff, 0xff, 0xff},
-	color.RGBA{0xbb, 0x00, 0x00, 0xff},
-	color.RGBA{0xbb, 0x00, 0x5d, 0xff},
-	color.RGBA{0xbb, 0x00, 0xbb, 0xff},
-	color.RGBA{0xaa, 0x00, 0xff, 0xff},
-	color.RGBA{0xbb, 0x5d, 0x00, 0xff},
-	color.RGBA{0xbb, 0x5d, 0x5d, 0xff},
-	color.RGBA{0xbb, 0x5d, 0xbb, 0xff},
-	color.RGBA{0xaa, 0x55, 0xff, 0xff},
-	color.RGBA{0xbb, 0xbb, 0x00, 0xff},
-	color.RGBA{0xbb, 0xbb, 0x5d, 0xff},
-	color.RGBA{0xbb, 0xbb, 0xbb, 0xff},
-	color.RGBA{0xaa, 0xaa, 0xff, 0xff},
-	color.RGBA{0xaa, 0xff, 0x00, 0xff},
-	color.RGBA{0xaa, 0xff, 0x55, 0xff},
-	color.RGBA{0xaa, 0xff, 0xaa, 0xff},
-	color.RGBA{0xcc, 0x00, 0xcc, 0xff},
-	color.RGBA{0xcc, 0x44, 0x00, 0xff},
-	color.RGBA{0xcc, 0x44, 0x44, 0xff},
-	color.RGBA{0xcc, 0x44, 0x88, 0xff},
-	color.RGBA{0xcc, 0x44, 0xcc, 0xff},
-	color.RGBA{0xcc, 0x88, 0x00, 0xff},
-	color.RGBA{0xcc, 0x88, 0x44, 0xff},
-	color.RGBA{0xcc, 0x88, 0x88, 0xff},
-	color.RGBA{0xcc, 0x88, 0xcc, 0xff},
-	color.RGBA{0xcc, 0xcc, 0x00, 0xff},
-	color.RGBA{0xcc, 0xcc, 0x44, 0xff},
-	color.RGBA{0xcc, 0xcc, 0x88, 0xff},
-	color.RGBA{0xcc, 0xcc, 0xcc, 0xff},
-	color.RGBA{0xcc, 0x00, 0x00, 0xff},
-	color.RGBA{0xcc, 0x00, 0x44, 0xff},
-	color.RGBA{0xcc, 0x00, 0x88, 0xff},
-	color.RGBA{0xdd, 0x00, 0x93, 0xff},
-	color.RGBA{0xdd, 0x00, 0xdd, 0xff},
-	color.RGBA{0xdd, 0x49, 0x00, 0xff},
-	color.RGBA{0xdd, 0x49, 0x49, 0xff},
-	color.RGBA{0xdd, 0x49, 0x93, 0xff},
-	color.RGBA{0xdd, 0x49, 0xdd, 0xff},
-	color.RGBA{0xdd, 0x93, 0x00, 0xff},
-	color.RGBA{0xdd, 0x93, 0x49, 0xff},
-	color.RGBA{0xdd, 0x93, 0x93, 0xff},
-	color.RGBA{0xdd, 0x93, 0xdd, 0xff},
-	color.RGBA{0xdd, 0xdd, 0x00, 0xff},
-	color.RGBA{0xdd, 0xdd, 0x49, 0xff},
-	color.RGBA{0xdd, 0xdd, 0x93, 0xff},
-	color.RGBA{0xdd, 0xdd, 0xdd, 0xff},
-	color.RGBA{0xdd, 0x00, 0x00, 0xff},
-	color.RGBA{0xdd, 0x00, 0x49, 0xff},
-	color.RGBA{0xee, 0x00, 0x4f, 0xff},
-	color.RGBA{0xee, 0x00, 0x9e, 0xff},
-	color.RGBA{0xee, 0x00, 0xee, 0xff},
-	color.RGBA{0xee, 0x4f, 0x00, 0xff},
-	color.RGBA{0xee, 0x4f, 0x4f, 0xff},
-	color.RGBA{0xee, 0x4f, 0x9e, 0xff},
-	color.RGBA{0xee, 0x4f, 0xee, 0xff},
-	color.RGBA{0xee, 0x9e, 0x00, 0xff},
-	color.RGBA{0xee, 0x9e, 0x4f, 0xff},
-	color.RGBA{0xee, 0x9e, 0x9e, 0xff},
-	color.RGBA{0xee, 0x9e, 0xee, 0xff},
-	color.RGBA{0xee, 0xee, 0x00, 0xff},
-	color.RGBA{0xee, 0xee, 0x4f, 0xff},
-	color.RGBA{0xee, 0xee, 0x9e, 0xff},
-	color.RGBA{0xee, 0xee, 0xee, 0xff},
-	color.RGBA{0xee, 0x00, 0x00, 0xff},
-	color.RGBA{0xff, 0x00, 0x00, 0xff},
-	color.RGBA{0xff, 0x00, 0x55, 0xff},
-	color.RGBA{0xff, 0x00, 0xaa, 0xff},
-	color.RGBA{0xff, 0x00, 0xff, 0xff},
-	color.RGBA{0xff, 0x55, 0x00, 0xff},
-	color.RGBA{0xff, 0x55, 0x55, 0xff},
-	color.RGBA{0xff, 0x55, 0xaa, 0xff},
-	color.RGBA{0xff, 0x55, 0xff, 0xff},
-	color.RGBA{0xff, 0xaa, 0x00, 0xff},
-	color.RGBA{0xff, 0xaa, 0x55, 0xff},
-	color.RGBA{0xff, 0xaa, 0xaa, 0xff},
-	color.RGBA{0xff, 0xaa, 0xff, 0xff},
-	color.RGBA{0xff, 0xff, 0x00, 0xff},
-	color.RGBA{0xff, 0xff, 0x55, 0xff},
-	color.RGBA{0xff, 0xff, 0xaa, 0xff},
-	color.RGBA{0xff, 0xff, 0xff, 0xff},
-}
-
-// WebSafe is a 216-color palette that was popularized by early versions
-// of Netscape Navigator. It is also known as the Netscape Color Cube.
-//
-// See http://en.wikipedia.org/wiki/Web_colors#Web-safe_colors for details.
-var WebSafe = []color.Color{
-	color.RGBA{0x00, 0x00, 0x00, 0xff},
-	color.RGBA{0x00, 0x00, 0x33, 0xff},
-	color.RGBA{0x00, 0x00, 0x66, 0xff},
-	color.RGBA{0x00, 0x00, 0x99, 0xff},
-	color.RGBA{0x00, 0x00, 0xcc, 0xff},
-	color.RGBA{0x00, 0x00, 0xff, 0xff},
-	color.RGBA{0x00, 0x33, 0x00, 0xff},
-	color.RGBA{0x00, 0x33, 0x33, 0xff},
-	color.RGBA{0x00, 0x33, 0x66, 0xff},
-	color.RGBA{0x00, 0x33, 0x99, 0xff},
-	color.RGBA{0x00, 0x33, 0xcc, 0xff},
-	color.RGBA{0x00, 0x33, 0xff, 0xff},
-	color.RGBA{0x00, 0x66, 0x00, 0xff},
-	color.RGBA{0x00, 0x66, 0x33, 0xff},
-	color.RGBA{0x00, 0x66, 0x66, 0xff},
-	color.RGBA{0x00, 0x66, 0x99, 0xff},
-	color.RGBA{0x00, 0x66, 0xcc, 0xff},
-	color.RGBA{0x00, 0x66, 0xff, 0xff},
-	color.RGBA{0x00, 0x99, 0x00, 0xff},
-	color.RGBA{0x00, 0x99, 0x33, 0xff},
-	color.RGBA{0x00, 0x99, 0x66, 0xff},
-	color.RGBA{0x00, 0x99, 0x99, 0xff},
-	color.RGBA{0x00, 0x99, 0xcc, 0xff},
-	color.RGBA{0x00, 0x99, 0xff, 0xff},
-	color.RGBA{0x00, 0xcc, 0x00, 0xff},
-	color.RGBA{0x00, 0xcc, 0x33, 0xff},
-	color.RGBA{0x00, 0xcc, 0x66, 0xff},
-	color.RGBA{0x00, 0xcc, 0x99, 0xff},
-	color.RGBA{0x00, 0xcc, 0xcc, 0xff},
-	color.RGBA{0x00, 0xcc, 0xff, 0xff},
-	color.RGBA{0x00, 0xff, 0x00, 0xff},
-	color.RGBA{0x00, 0xff, 0x33, 0xff},
-	color.RGBA{0x00, 0xff, 0x66, 0xff},
-	color.RGBA{0x00, 0xff, 0x99, 0xff},
-	color.RGBA{0x00, 0xff, 0xcc, 0xff},
-	color.RGBA{0x00, 0xff, 0xff, 0xff},
-	color.RGBA{0x33, 0x00, 0x00, 0xff},
-	color.RGBA{0x33, 0x00, 0x33, 0xff},
-	color.RGBA{0x33, 0x00, 0x66, 0xff},
-	color.RGBA{0x33, 0x00, 0x99, 0xff},
-	color.RGBA{0x33, 0x00, 0xcc, 0xff},
-	color.RGBA{0x33, 0x00, 0xff, 0xff},
-	color.RGBA{0x33, 0x33, 0x00, 0xff},
-	color.RGBA{0x33, 0x33, 0x33, 0xff},
-	color.RGBA{0x33, 0x33, 0x66, 0xff},
-	color.RGBA{0x33, 0x33, 0x99, 0xff},
-	color.RGBA{0x33, 0x33, 0xcc, 0xff},
-	color.RGBA{0x33, 0x33, 0xff, 0xff},
-	color.RGBA{0x33, 0x66, 0x00, 0xff},
-	color.RGBA{0x33, 0x66, 0x33, 0xff},
-	color.RGBA{0x33, 0x66, 0x66, 0xff},
-	color.RGBA{0x33, 0x66, 0x99, 0xff},
-	color.RGBA{0x33, 0x66, 0xcc, 0xff},
-	color.RGBA{0x33, 0x66, 0xff, 0xff},
-	color.RGBA{0x33, 0x99, 0x00, 0xff},
-	color.RGBA{0x33, 0x99, 0x33, 0xff},
-	color.RGBA{0x33, 0x99, 0x66, 0xff},
-	color.RGBA{0x33, 0x99, 0x99, 0xff},
-	color.RGBA{0x33, 0x99, 0xcc, 0xff},
-	color.RGBA{0x33, 0x99, 0xff, 0xff},
-	color.RGBA{0x33, 0xcc, 0x00, 0xff},
-	color.RGBA{0x33, 0xcc, 0x33, 0xff},
-	color.RGBA{0x33, 0xcc, 0x66, 0xff},
-	color.RGBA{0x33, 0xcc, 0x99, 0xff},
-	color.RGBA{0x33, 0xcc, 0xcc, 0xff},
-	color.RGBA{0x33, 0xcc, 0xff, 0xff},
-	color.RGBA{0x33, 0xff, 0x00, 0xff},
-	color.RGBA{0x33, 0xff, 0x33, 0xff},
-	color.RGBA{0x33, 0xff, 0x66, 0xff},
-	color.RGBA{0x33, 0xff, 0x99, 0xff},
-	color.RGBA{0x33, 0xff, 0xcc, 0xff},
-	color.RGBA{0x33, 0xff, 0xff, 0xff},
-	color.RGBA{0x66, 0x00, 0x00, 0xff},
-	color.RGBA{0x66, 0x00, 0x33, 0xff},
-	color.RGBA{0x66, 0x00, 0x66, 0xff},
-	color.RGBA{0x66, 0x00, 0x99, 0xff},
-	color.RGBA{0x66, 0x00, 0xcc, 0xff},
-	color.RGBA{0x66, 0x00, 0xff, 0xff},
-	color.RGBA{0x66, 0x33, 0x00, 0xff},
-	color.RGBA{0x66, 0x33, 0x33, 0xff},
-	color.RGBA{0x66, 0x33, 0x66, 0xff},
-	color.RGBA{0x66, 0x33, 0x99, 0xff},
-	color.RGBA{0x66, 0x33, 0xcc, 0xff},
-	color.RGBA{0x66, 0x33, 0xff, 0xff},
-	color.RGBA{0x66, 0x66, 0x00, 0xff},
-	color.RGBA{0x66, 0x66, 0x33, 0xff},
-	color.RGBA{0x66, 0x66, 0x66, 0xff},
-	color.RGBA{0x66, 0x66, 0x99, 0xff},
-	color.RGBA{0x66, 0x66, 0xcc, 0xff},
-	color.RGBA{0x66, 0x66, 0xff, 0xff},
-	color.RGBA{0x66, 0x99, 0x00, 0xff},
-	color.RGBA{0x66, 0x99, 0x33, 0xff},
-	color.RGBA{0x66, 0x99, 0x66, 0xff},
-	color.RGBA{0x66, 0x99, 0x99, 0xff},
-	color.RGBA{0x66, 0x99, 0xcc, 0xff},
-	color.RGBA{0x66, 0x99, 0xff, 0xff},
-	color.RGBA{0x66, 0xcc, 0x00, 0xff},
-	color.RGBA{0x66, 0xcc, 0x33, 0xff},
-	color.RGBA{0x66, 0xcc, 0x66, 0xff},
-	color.RGBA{0x66, 0xcc, 0x99, 0xff},
-	color.RGBA{0x66, 0xcc, 0xcc, 0xff},
-	color.RGBA{0x66, 0xcc, 0xff, 0xff},
-	color.RGBA{0x66, 0xff, 0x00, 0xff},
-	color.RGBA{0x66, 0xff, 0x33, 0xff},
-	color.RGBA{0x66, 0xff, 0x66, 0xff},
-	color.RGBA{0x66, 0xff, 0x99, 0xff},
-	color.RGBA{0x66, 0xff, 0xcc, 0xff},
-	color.RGBA{0x66, 0xff, 0xff, 0xff},
-	color.RGBA{0x99, 0x00, 0x00, 0xff},
-	color.RGBA{0x99, 0x00, 0x33, 0xff},
-	color.RGBA{0x99, 0x00, 0x66, 0xff},
-	color.RGBA{0x99, 0x00, 0x99, 0xff},
-	color.RGBA{0x99, 0x00, 0xcc, 0xff},
-	color.RGBA{0x99, 0x00, 0xff, 0xff},
-	color.RGBA{0x99, 0x33, 0x00, 0xff},
-	color.RGBA{0x99, 0x33, 0x33, 0xff},
-	color.RGBA{0x99, 0x33, 0x66, 0xff},
-	color.RGBA{0x99, 0x33, 0x99, 0xff},
-	color.RGBA{0x99, 0x33, 0xcc, 0xff},
-	color.RGBA{0x99, 0x33, 0xff, 0xff},
-	color.RGBA{0x99, 0x66, 0x00, 0xff},
-	color.RGBA{0x99, 0x66, 0x33, 0xff},
-	color.RGBA{0x99, 0x66, 0x66, 0xff},
-	color.RGBA{0x99, 0x66, 0x99, 0xff},
-	color.RGBA{0x99, 0x66, 0xcc, 0xff},
-	color.RGBA{0x99, 0x66, 0xff, 0xff},
-	color.RGBA{0x99, 0x99, 0x00, 0xff},
-	color.RGBA{0x99, 0x99, 0x33, 0xff},
-	color.RGBA{0x99, 0x99, 0x66, 0xff},
-	color.RGBA{0x99, 0x99, 0x99, 0xff},
-	color.RGBA{0x99, 0x99, 0xcc, 0xff},
-	color.RGBA{0x99, 0x99, 0xff, 0xff},
-	color.RGBA{0x99, 0xcc, 0x00, 0xff},
-	color.RGBA{0x99, 0xcc, 0x33, 0xff},
-	color.RGBA{0x99, 0xcc, 0x66, 0xff},
-	color.RGBA{0x99, 0xcc, 0x99, 0xff},
-	color.RGBA{0x99, 0xcc, 0xcc, 0xff},
-	color.RGBA{0x99, 0xcc, 0xff, 0xff},
-	color.RGBA{0x99, 0xff, 0x00, 0xff},
-	color.RGBA{0x99, 0xff, 0x33, 0xff},
-	color.RGBA{0x99, 0xff, 0x66, 0xff},
-	color.RGBA{0x99, 0xff, 0x99, 0xff},
-	color.RGBA{0x99, 0xff, 0xcc, 0xff},
-	color.RGBA{0x99, 0xff, 0xff, 0xff},
-	color.RGBA{0xcc, 0x00, 0x00, 0xff},
-	color.RGBA{0xcc, 0x00, 0x33, 0xff},
-	color.RGBA{0xcc, 0x00, 0x66, 0xff},
-	color.RGBA{0xcc, 0x00, 0x99, 0xff},
-	color.RGBA{0xcc, 0x00, 0xcc, 0xff},
-	color.RGBA{0xcc, 0x00, 0xff, 0xff},
-	color.RGBA{0xcc, 0x33, 0x00, 0xff},
-	color.RGBA{0xcc, 0x33, 0x33, 0xff},
-	color.RGBA{0xcc, 0x33, 0x66, 0xff},
-	color.RGBA{0xcc, 0x33, 0x99, 0xff},
-	color.RGBA{0xcc, 0x33, 0xcc, 0xff},
-	color.RGBA{0xcc, 0x33, 0xff, 0xff},
-	color.RGBA{0xcc, 0x66, 0x00, 0xff},
-	color.RGBA{0xcc, 0x66, 0x33, 0xff},
-	color.RGBA{0xcc, 0x66, 0x66, 0xff},
-	color.RGBA{0xcc, 0x66, 0x99, 0xff},
-	color.RGBA{0xcc, 0x66, 0xcc, 0xff},
-	color.RGBA{0xcc, 0x66, 0xff, 0xff},
-	color.RGBA{0xcc, 0x99, 0x00, 0xff},
-	color.RGBA{0xcc, 0x99, 0x33, 0xff},
-	color.RGBA{0xcc, 0x99, 0x66, 0xff},
-	color.RGBA{0xcc, 0x99, 0x99, 0xff},
-	color.RGBA{0xcc, 0x99, 0xcc, 0xff},
-	color.RGBA{0xcc, 0x99, 0xff, 0xff},
-	color.RGBA{0xcc, 0xcc, 0x00, 0xff},
-	color.RGBA{0xcc, 0xcc, 0x33, 0xff},
-	color.RGBA{0xcc, 0xcc, 0x66, 0xff},
-	color.RGBA{0xcc, 0xcc, 0x99, 0xff},
-	color.RGBA{0xcc, 0xcc, 0xcc, 0xff},
-	color.RGBA{0xcc, 0xcc, 0xff, 0xff},
-	color.RGBA{0xcc, 0xff, 0x00, 0xff},
-	color.RGBA{0xcc, 0xff, 0x33, 0xff},
-	color.RGBA{0xcc, 0xff, 0x66, 0xff},
-	color.RGBA{0xcc, 0xff, 0x99, 0xff},
-	color.RGBA{0xcc, 0xff, 0xcc, 0xff},
-	color.RGBA{0xcc, 0xff, 0xff, 0xff},
-	color.RGBA{0xff, 0x00, 0x00, 0xff},
-	color.RGBA{0xff, 0x00, 0x33, 0xff},
-	color.RGBA{0xff, 0x00, 0x66, 0xff},
-	color.RGBA{0xff, 0x00, 0x99, 0xff},
-	color.RGBA{0xff, 0x00, 0xcc, 0xff},
-	color.RGBA{0xff, 0x00, 0xff, 0xff},
-	color.RGBA{0xff, 0x33, 0x00, 0xff},
-	color.RGBA{0xff, 0x33, 0x33, 0xff},
-	color.RGBA{0xff, 0x33, 0x66, 0xff},
-	color.RGBA{0xff, 0x33, 0x99, 0xff},
-	color.RGBA{0xff, 0x33, 0xcc, 0xff},
-	color.RGBA{0xff, 0x33, 0xff, 0xff},
-	color.RGBA{0xff, 0x66, 0x00, 0xff},
-	color.RGBA{0xff, 0x66, 0x33, 0xff},
-	color.RGBA{0xff, 0x66, 0x66, 0xff},
-	color.RGBA{0xff, 0x66, 0x99, 0xff},
-	color.RGBA{0xff, 0x66, 0xcc, 0xff},
-	color.RGBA{0xff, 0x66, 0xff, 0xff},
-	color.RGBA{0xff, 0x99, 0x00, 0xff},
-	color.RGBA{0xff, 0x99, 0x33, 0xff},
-	color.RGBA{0xff, 0x99, 0x66, 0xff},
-	color.RGBA{0xff, 0x99, 0x99, 0xff},
-	color.RGBA{0xff, 0x99, 0xcc, 0xff},
-	color.RGBA{0xff, 0x99, 0xff, 0xff},
-	color.RGBA{0xff, 0xcc, 0x00, 0xff},
-	color.RGBA{0xff, 0xcc, 0x33, 0xff},
-	color.RGBA{0xff, 0xcc, 0x66, 0xff},
-	color.RGBA{0xff, 0xcc, 0x99, 0xff},
-	color.RGBA{0xff, 0xcc, 0xcc, 0xff},
-	color.RGBA{0xff, 0xcc, 0xff, 0xff},
-	color.RGBA{0xff, 0xff, 0x00, 0xff},
-	color.RGBA{0xff, 0xff, 0x33, 0xff},
-	color.RGBA{0xff, 0xff, 0x66, 0xff},
-	color.RGBA{0xff, 0xff, 0x99, 0xff},
-	color.RGBA{0xff, 0xff, 0xcc, 0xff},
-	color.RGBA{0xff, 0xff, 0xff, 0xff},
-}
diff --git a/src/pkg/image/gif/reader.go b/src/pkg/image/gif/reader.go
deleted file mode 100644
index 926710a..0000000
--- a/src/pkg/image/gif/reader.go
+++ /dev/null
@@ -1,460 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package gif implements a GIF image decoder and encoder.
-//
-// The GIF specification is at http://www.w3.org/Graphics/GIF/spec-gif89a.txt.
-package gif
-
-import (
-	"bufio"
-	"compress/lzw"
-	"errors"
-	"fmt"
-	"image"
-	"image/color"
-	"io"
-)
-
-var (
-	errNotEnough = errors.New("gif: not enough image data")
-	errTooMuch   = errors.New("gif: too much image data")
-	errBadPixel  = errors.New("gif: invalid pixel value")
-)
-
-// If the io.Reader does not also have ReadByte, then decode will introduce its own buffering.
-type reader interface {
-	io.Reader
-	io.ByteReader
-}
-
-// Masks etc.
-const (
-	// Fields.
-	fColorMapFollows = 1 << 7
-
-	// Image fields.
-	ifLocalColorTable = 1 << 7
-	ifInterlace       = 1 << 6
-	ifPixelSizeMask   = 7
-
-	// Graphic control flags.
-	gcTransparentColorSet = 1 << 0
-)
-
-// Section indicators.
-const (
-	sExtension       = 0x21
-	sImageDescriptor = 0x2C
-	sTrailer         = 0x3B
-)
-
-// Extensions.
-const (
-	eText           = 0x01 // Plain Text
-	eGraphicControl = 0xF9 // Graphic Control
-	eComment        = 0xFE // Comment
-	eApplication    = 0xFF // Application
-)
-
-// decoder is the type used to decode a GIF file.
-type decoder struct {
-	r reader
-
-	// From header.
-	vers            string
-	width           int
-	height          int
-	flags           byte
-	headerFields    byte
-	backgroundIndex byte
-	loopCount       int
-	delayTime       int
-
-	// Unused from header.
-	aspect byte
-
-	// From image descriptor.
-	imageFields byte
-
-	// From graphics control.
-	transparentIndex    byte
-	hasTransparentIndex bool
-
-	// Computed.
-	pixelSize      uint
-	globalColorMap color.Palette
-
-	// Used when decoding.
-	delay []int
-	image []*image.Paletted
-	tmp   [1024]byte // must be at least 768 so we can read color map
-}
-
-// blockReader parses the block structure of GIF image data, which
-// comprises (n, (n bytes)) blocks, with 1 <= n <= 255.  It is the
-// reader given to the LZW decoder, which is thus immune to the
-// blocking.  After the LZW decoder completes, there will be a 0-byte
-// block remaining (0, ()), which is consumed when checking that the
-// blockReader is exhausted.
-type blockReader struct {
-	r     reader
-	slice []byte
-	err   error
-	tmp   [256]byte
-}
-
-func (b *blockReader) Read(p []byte) (int, error) {
-	if b.err != nil {
-		return 0, b.err
-	}
-	if len(p) == 0 {
-		return 0, nil
-	}
-	if len(b.slice) == 0 {
-		var blockLen uint8
-		blockLen, b.err = b.r.ReadByte()
-		if b.err != nil {
-			return 0, b.err
-		}
-		if blockLen == 0 {
-			b.err = io.EOF
-			return 0, b.err
-		}
-		b.slice = b.tmp[0:blockLen]
-		if _, b.err = io.ReadFull(b.r, b.slice); b.err != nil {
-			return 0, b.err
-		}
-	}
-	n := copy(p, b.slice)
-	b.slice = b.slice[n:]
-	return n, nil
-}
-
-// decode reads a GIF image from r and stores the result in d.
-func (d *decoder) decode(r io.Reader, configOnly bool) error {
-	// Add buffering if r does not provide ReadByte.
-	if rr, ok := r.(reader); ok {
-		d.r = rr
-	} else {
-		d.r = bufio.NewReader(r)
-	}
-
-	err := d.readHeaderAndScreenDescriptor()
-	if err != nil {
-		return err
-	}
-	if configOnly {
-		return nil
-	}
-
-	if d.headerFields&fColorMapFollows != 0 {
-		if d.globalColorMap, err = d.readColorMap(); err != nil {
-			return err
-		}
-	}
-
-	for {
-		c, err := d.r.ReadByte()
-		if err != nil {
-			return err
-		}
-		switch c {
-		case sExtension:
-			if err = d.readExtension(); err != nil {
-				return err
-			}
-
-		case sImageDescriptor:
-			m, err := d.newImageFromDescriptor()
-			if err != nil {
-				return err
-			}
-			if d.imageFields&fColorMapFollows != 0 {
-				m.Palette, err = d.readColorMap()
-				if err != nil {
-					return err
-				}
-			} else {
-				m.Palette = d.globalColorMap
-			}
-			if d.hasTransparentIndex && int(d.transparentIndex) < len(m.Palette) {
-				m.Palette[d.transparentIndex] = color.RGBA{}
-			}
-			litWidth, err := d.r.ReadByte()
-			if err != nil {
-				return err
-			}
-			if litWidth < 2 || litWidth > 8 {
-				return fmt.Errorf("gif: pixel size in decode out of range: %d", litWidth)
-			}
-			// A wonderfully Go-like piece of magic.
-			br := &blockReader{r: d.r}
-			lzwr := lzw.NewReader(br, lzw.LSB, int(litWidth))
-			defer lzwr.Close()
-			if _, err = io.ReadFull(lzwr, m.Pix); err != nil {
-				if err != io.ErrUnexpectedEOF {
-					return err
-				}
-				return errNotEnough
-			}
-			// Both lzwr and br should be exhausted. Reading from them
-			// should yield (0, io.EOF).
-			if n, err := lzwr.Read(d.tmp[:1]); n != 0 || err != io.EOF {
-				if err != nil {
-					return err
-				}
-				return errTooMuch
-			}
-			if n, err := br.Read(d.tmp[:1]); n != 0 || err != io.EOF {
-				if err != nil {
-					return err
-				}
-				return errTooMuch
-			}
-
-			// Check that the color indexes are inside the palette.
-			if len(m.Palette) < 256 {
-				for _, pixel := range m.Pix {
-					if int(pixel) >= len(m.Palette) {
-						return errBadPixel
-					}
-				}
-			}
-
-			// Undo the interlacing if necessary.
-			if d.imageFields&ifInterlace != 0 {
-				uninterlace(m)
-			}
-
-			d.image = append(d.image, m)
-			d.delay = append(d.delay, d.delayTime)
-			// The GIF89a spec, Section 23 (Graphic Control Extension) says:
-			// "The scope of this extension is the first graphic rendering block
-			// to follow." We therefore reset the GCE fields to zero.
-			d.delayTime = 0
-			d.hasTransparentIndex = false
-
-		case sTrailer:
-			if len(d.image) == 0 {
-				return io.ErrUnexpectedEOF
-			}
-			return nil
-
-		default:
-			return fmt.Errorf("gif: unknown block type: 0x%.2x", c)
-		}
-	}
-}
-
-func (d *decoder) readHeaderAndScreenDescriptor() error {
-	_, err := io.ReadFull(d.r, d.tmp[0:13])
-	if err != nil {
-		return err
-	}
-	d.vers = string(d.tmp[0:6])
-	if d.vers != "GIF87a" && d.vers != "GIF89a" {
-		return fmt.Errorf("gif: can't recognize format %s", d.vers)
-	}
-	d.width = int(d.tmp[6]) + int(d.tmp[7])<<8
-	d.height = int(d.tmp[8]) + int(d.tmp[9])<<8
-	d.headerFields = d.tmp[10]
-	d.backgroundIndex = d.tmp[11]
-	d.aspect = d.tmp[12]
-	d.loopCount = -1
-	d.pixelSize = uint(d.headerFields&7) + 1
-	return nil
-}
-
-func (d *decoder) readColorMap() (color.Palette, error) {
-	if d.pixelSize > 8 {
-		return nil, fmt.Errorf("gif: can't handle %d bits per pixel", d.pixelSize)
-	}
-	numColors := 1 << d.pixelSize
-	if d.imageFields&ifLocalColorTable != 0 {
-		numColors = 1 << ((d.imageFields & ifPixelSizeMask) + 1)
-	}
-	numValues := 3 * numColors
-	_, err := io.ReadFull(d.r, d.tmp[0:numValues])
-	if err != nil {
-		return nil, fmt.Errorf("gif: short read on color map: %s", err)
-	}
-	colorMap := make(color.Palette, numColors)
-	j := 0
-	for i := range colorMap {
-		colorMap[i] = color.RGBA{d.tmp[j+0], d.tmp[j+1], d.tmp[j+2], 0xFF}
-		j += 3
-	}
-	return colorMap, nil
-}
-
-func (d *decoder) readExtension() error {
-	extension, err := d.r.ReadByte()
-	if err != nil {
-		return err
-	}
-	size := 0
-	switch extension {
-	case eText:
-		size = 13
-	case eGraphicControl:
-		return d.readGraphicControl()
-	case eComment:
-		// nothing to do but read the data.
-	case eApplication:
-		b, err := d.r.ReadByte()
-		if err != nil {
-			return err
-		}
-		// The spec requires size be 11, but Adobe sometimes uses 10.
-		size = int(b)
-	default:
-		return fmt.Errorf("gif: unknown extension 0x%.2x", extension)
-	}
-	if size > 0 {
-		if _, err := io.ReadFull(d.r, d.tmp[0:size]); err != nil {
-			return err
-		}
-	}
-
-	// Application Extension with "NETSCAPE2.0" as string and 1 in data means
-	// this extension defines a loop count.
-	if extension == eApplication && string(d.tmp[:size]) == "NETSCAPE2.0" {
-		n, err := d.readBlock()
-		if n == 0 || err != nil {
-			return err
-		}
-		if n == 3 && d.tmp[0] == 1 {
-			d.loopCount = int(d.tmp[1]) | int(d.tmp[2])<<8
-		}
-	}
-	for {
-		n, err := d.readBlock()
-		if n == 0 || err != nil {
-			return err
-		}
-	}
-}
-
-func (d *decoder) readGraphicControl() error {
-	if _, err := io.ReadFull(d.r, d.tmp[0:6]); err != nil {
-		return fmt.Errorf("gif: can't read graphic control: %s", err)
-	}
-	d.flags = d.tmp[1]
-	d.delayTime = int(d.tmp[2]) | int(d.tmp[3])<<8
-	if d.flags&gcTransparentColorSet != 0 {
-		d.transparentIndex = d.tmp[4]
-		d.hasTransparentIndex = true
-	}
-	return nil
-}
-
-func (d *decoder) newImageFromDescriptor() (*image.Paletted, error) {
-	if _, err := io.ReadFull(d.r, d.tmp[0:9]); err != nil {
-		return nil, fmt.Errorf("gif: can't read image descriptor: %s", err)
-	}
-	left := int(d.tmp[0]) + int(d.tmp[1])<<8
-	top := int(d.tmp[2]) + int(d.tmp[3])<<8
-	width := int(d.tmp[4]) + int(d.tmp[5])<<8
-	height := int(d.tmp[6]) + int(d.tmp[7])<<8
-	d.imageFields = d.tmp[8]
-
-	// The GIF89a spec, Section 20 (Image Descriptor) says:
-	// "Each image must fit within the boundaries of the Logical
-	// Screen, as defined in the Logical Screen Descriptor."
-	bounds := image.Rect(left, top, left+width, top+height)
-	if bounds != bounds.Intersect(image.Rect(0, 0, d.width, d.height)) {
-		return nil, errors.New("gif: frame bounds larger than image bounds")
-	}
-	return image.NewPaletted(bounds, nil), nil
-}
-
-func (d *decoder) readBlock() (int, error) {
-	n, err := d.r.ReadByte()
-	if n == 0 || err != nil {
-		return 0, err
-	}
-	return io.ReadFull(d.r, d.tmp[0:n])
-}
-
-// interlaceScan defines the ordering for a pass of the interlace algorithm.
-type interlaceScan struct {
-	skip, start int
-}
-
-// interlacing represents the set of scans in an interlaced GIF image.
-var interlacing = []interlaceScan{
-	{8, 0}, // Group 1 : Every 8th. row, starting with row 0.
-	{8, 4}, // Group 2 : Every 8th. row, starting with row 4.
-	{4, 2}, // Group 3 : Every 4th. row, starting with row 2.
-	{2, 1}, // Group 4 : Every 2nd. row, starting with row 1.
-}
-
-// uninterlace rearranges the pixels in m to account for interlaced input.
-func uninterlace(m *image.Paletted) {
-	var nPix []uint8
-	dx := m.Bounds().Dx()
-	dy := m.Bounds().Dy()
-	nPix = make([]uint8, dx*dy)
-	offset := 0 // steps through the input by sequential scan lines.
-	for _, pass := range interlacing {
-		nOffset := pass.start * dx // steps through the output as defined by pass.
-		for y := pass.start; y < dy; y += pass.skip {
-			copy(nPix[nOffset:nOffset+dx], m.Pix[offset:offset+dx])
-			offset += dx
-			nOffset += dx * pass.skip
-		}
-	}
-	m.Pix = nPix
-}
-
-// Decode reads a GIF image from r and returns the first embedded
-// image as an image.Image.
-func Decode(r io.Reader) (image.Image, error) {
-	var d decoder
-	if err := d.decode(r, false); err != nil {
-		return nil, err
-	}
-	return d.image[0], nil
-}
-
-// GIF represents the possibly multiple images stored in a GIF file.
-type GIF struct {
-	Image     []*image.Paletted // The successive images.
-	Delay     []int             // The successive delay times, one per frame, in 100ths of a second.
-	LoopCount int               // The loop count.
-}
-
-// DecodeAll reads a GIF image from r and returns the sequential frames
-// and timing information.
-func DecodeAll(r io.Reader) (*GIF, error) {
-	var d decoder
-	if err := d.decode(r, false); err != nil {
-		return nil, err
-	}
-	gif := &GIF{
-		Image:     d.image,
-		LoopCount: d.loopCount,
-		Delay:     d.delay,
-	}
-	return gif, nil
-}
-
-// DecodeConfig returns the global color model and dimensions of a GIF image
-// without decoding the entire image.
-func DecodeConfig(r io.Reader) (image.Config, error) {
-	var d decoder
-	if err := d.decode(r, true); err != nil {
-		return image.Config{}, err
-	}
-	return image.Config{
-		ColorModel: d.globalColorMap,
-		Width:      d.width,
-		Height:     d.height,
-	}, nil
-}
-
-func init() {
-	image.RegisterFormat("gif", "GIF8?a", Decode, DecodeConfig)
-}
diff --git a/src/pkg/image/gif/reader_test.go b/src/pkg/image/gif/reader_test.go
deleted file mode 100644
index fc2041e..0000000
--- a/src/pkg/image/gif/reader_test.go
+++ /dev/null
@@ -1,201 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package gif
-
-import (
-	"bytes"
-	"compress/lzw"
-	"image"
-	"image/color"
-	"reflect"
-	"testing"
-)
-
-// header, palette and trailer are parts of a valid 2x1 GIF image.
-const (
-	headerStr = "GIF89a" +
-		"\x02\x00\x01\x00" + // width=2, height=1
-		"\x80\x00\x00" // headerFields=(a color map of 2 pixels), backgroundIndex, aspect
-	paletteStr = "\x10\x20\x30\x40\x50\x60" // the color map, also known as a palette
-	trailerStr = "\x3b"
-)
-
-func TestDecode(t *testing.T) {
-	// lzwEncode returns an LZW encoding (with 2-bit literals) of n zeroes.
-	lzwEncode := func(n int) []byte {
-		b := &bytes.Buffer{}
-		w := lzw.NewWriter(b, lzw.LSB, 2)
-		w.Write(make([]byte, n))
-		w.Close()
-		return b.Bytes()
-	}
-
-	testCases := []struct {
-		nPix    int  // The number of pixels in the image data.
-		extra   bool // Whether to write an extra block after the LZW-encoded data.
-		wantErr error
-	}{
-		{0, false, errNotEnough},
-		{1, false, errNotEnough},
-		{2, false, nil},
-		{2, true, errTooMuch},
-		{3, false, errTooMuch},
-	}
-	for _, tc := range testCases {
-		b := &bytes.Buffer{}
-		b.WriteString(headerStr)
-		b.WriteString(paletteStr)
-		// Write an image with bounds 2x1 but tc.nPix pixels. If tc.nPix != 2
-		// then this should result in an invalid GIF image. First, write a
-		// magic 0x2c (image descriptor) byte, bounds=(0,0)-(2,1), a flags
-		// byte, and 2-bit LZW literals.
-		b.WriteString("\x2c\x00\x00\x00\x00\x02\x00\x01\x00\x00\x02")
-		if tc.nPix > 0 {
-			enc := lzwEncode(tc.nPix)
-			if len(enc) > 0xff {
-				t.Errorf("nPix=%d, extra=%t: compressed length %d is too large", tc.nPix, tc.extra, len(enc))
-				continue
-			}
-			b.WriteByte(byte(len(enc)))
-			b.Write(enc)
-		}
-		if tc.extra {
-			b.WriteString("\x01\x02") // A 1-byte payload with an 0x02 byte.
-		}
-		b.WriteByte(0x00) // An empty block signifies the end of the image data.
-		b.WriteString(trailerStr)
-
-		got, err := Decode(b)
-		if err != tc.wantErr {
-			t.Errorf("nPix=%d, extra=%t\ngot  %v\nwant %v", tc.nPix, tc.extra, err, tc.wantErr)
-		}
-
-		if tc.wantErr != nil {
-			continue
-		}
-		want := &image.Paletted{
-			Pix:    []uint8{0, 0},
-			Stride: 2,
-			Rect:   image.Rect(0, 0, 2, 1),
-			Palette: color.Palette{
-				color.RGBA{0x10, 0x20, 0x30, 0xff},
-				color.RGBA{0x40, 0x50, 0x60, 0xff},
-			},
-		}
-		if !reflect.DeepEqual(got, want) {
-			t.Errorf("nPix=%d, extra=%t\ngot  %v\nwant %v", tc.nPix, tc.extra, got, want)
-		}
-	}
-}
-
-// testGIF is a simple GIF that we can modify to test different scenarios.
-var testGIF = []byte{
-	'G', 'I', 'F', '8', '9', 'a',
-	1, 0, 1, 0, // w=1, h=1 (6)
-	128, 0, 0, // headerFields, bg, aspect (10)
-	0, 0, 0, 1, 1, 1, // color map and graphics control (13)
-	0x21, 0xf9, 0x04, 0x00, 0x00, 0x00, 0xff, 0x00, // (19)
-	// frame 1 (0,0 - 1,1)
-	0x2c,
-	0x00, 0x00, 0x00, 0x00,
-	0x01, 0x00, 0x01, 0x00, // (32)
-	0x00,
-	0x02, 0x02, 0x4c, 0x01, 0x00, // lzw pixels
-	// trailer
-	0x3b,
-}
-
-func try(t *testing.T, b []byte, want string) {
-	_, err := DecodeAll(bytes.NewReader(b))
-	var got string
-	if err != nil {
-		got = err.Error()
-	}
-	if got != want {
-		t.Fatalf("got %v, want %v", got, want)
-	}
-}
-
-func TestBounds(t *testing.T) {
-	// Make a local copy of testGIF.
-	gif := make([]byte, len(testGIF))
-	copy(gif, testGIF)
-	// Make the bounds too big, just by one.
-	gif[32] = 2
-	want := "gif: frame bounds larger than image bounds"
-	try(t, gif, want)
-
-	// Make the bounds too small; does not trigger bounds
-	// check, but now there's too much data.
-	gif[32] = 0
-	want = "gif: too much image data"
-	try(t, gif, want)
-	gif[32] = 1
-
-	// Make the bounds really big, expect an error.
-	want = "gif: frame bounds larger than image bounds"
-	for i := 0; i < 4; i++ {
-		gif[32+i] = 0xff
-	}
-	try(t, gif, want)
-}
-
-func TestNoPalette(t *testing.T) {
-	b := &bytes.Buffer{}
-
-	// Manufacture a GIF with no palette, so any pixel at all
-	// will be invalid.
-	b.WriteString(headerStr[:len(headerStr)-3])
-	b.WriteString("\x00\x00\x00") // No global palette.
-
-	// Image descriptor: 2x1, no local palette.
-	b.WriteString("\x2c\x00\x00\x00\x00\x02\x00\x01\x00\x00\x02")
-
-	// Encode the pixels: neither is in range, because there is no palette.
-	pix := []byte{0, 128}
-	enc := &bytes.Buffer{}
-	w := lzw.NewWriter(enc, lzw.LSB, 2)
-	w.Write(pix)
-	w.Close()
-	b.WriteByte(byte(len(enc.Bytes())))
-	b.Write(enc.Bytes())
-	b.WriteByte(0x00) // An empty block signifies the end of the image data.
-
-	b.WriteString(trailerStr)
-
-	try(t, b.Bytes(), "gif: invalid pixel value")
-}
-
-func TestPixelOutsidePaletteRange(t *testing.T) {
-	for _, pval := range []byte{0, 1, 2, 3, 255} {
-		b := &bytes.Buffer{}
-
-		// Manufacture a GIF with a 2 color palette.
-		b.WriteString(headerStr)
-		b.WriteString(paletteStr)
-
-		// Image descriptor: 2x1, no local palette.
-		b.WriteString("\x2c\x00\x00\x00\x00\x02\x00\x01\x00\x00\x02")
-
-		// Encode the pixels; some pvals trigger the expected error.
-		pix := []byte{pval, pval}
-		enc := &bytes.Buffer{}
-		w := lzw.NewWriter(enc, lzw.LSB, 2)
-		w.Write(pix)
-		w.Close()
-		b.WriteByte(byte(len(enc.Bytes())))
-		b.Write(enc.Bytes())
-		b.WriteByte(0x00) // An empty block signifies the end of the image data.
-
-		b.WriteString(trailerStr)
-
-		// No error expected, unless the pixels are beyond the 2 color palette.
-		want := ""
-		if pval >= 2 {
-			want = "gif: invalid pixel value"
-		}
-		try(t, b.Bytes(), want)
-	}
-}
diff --git a/src/pkg/image/gif/writer.go b/src/pkg/image/gif/writer.go
deleted file mode 100644
index 15cd40f..0000000
--- a/src/pkg/image/gif/writer.go
+++ /dev/null
@@ -1,323 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package gif
-
-import (
-	"bufio"
-	"compress/lzw"
-	"errors"
-	"image"
-	"image/color"
-	"image/color/palette"
-	"image/draw"
-	"io"
-)
-
-// Graphic control extension fields.
-const (
-	gcLabel     = 0xF9
-	gcBlockSize = 0x04
-)
-
-var log2Lookup = [8]int{2, 4, 8, 16, 32, 64, 128, 256}
-
-func log2(x int) int {
-	for i, v := range log2Lookup {
-		if x <= v {
-			return i
-		}
-	}
-	return -1
-}
-
-// Little-endian.
-func writeUint16(b []uint8, u uint16) {
-	b[0] = uint8(u)
-	b[1] = uint8(u >> 8)
-}
-
-// writer is a buffered writer.
-type writer interface {
-	Flush() error
-	io.Writer
-	io.ByteWriter
-}
-
-// encoder encodes an image to the GIF format.
-type encoder struct {
-	// w is the writer to write to. err is the first error encountered during
-	// writing. All attempted writes after the first error become no-ops.
-	w   writer
-	err error
-	// g is a reference to the data that is being encoded.
-	g *GIF
-	// buf is a scratch buffer. It must be at least 768 so we can write the color map.
-	buf [1024]byte
-}
-
-// blockWriter writes the block structure of GIF image data, which
-// comprises (n, (n bytes)) blocks, with 1 <= n <= 255. It is the
-// writer given to the LZW encoder, which is thus immune to the
-// blocking.
-type blockWriter struct {
-	e *encoder
-}
-
-func (b blockWriter) Write(data []byte) (int, error) {
-	if b.e.err != nil {
-		return 0, b.e.err
-	}
-	if len(data) == 0 {
-		return 0, nil
-	}
-	total := 0
-	for total < len(data) {
-		n := copy(b.e.buf[1:256], data[total:])
-		total += n
-		b.e.buf[0] = uint8(n)
-
-		n, b.e.err = b.e.w.Write(b.e.buf[:n+1])
-		if b.e.err != nil {
-			return 0, b.e.err
-		}
-	}
-	return total, b.e.err
-}
-
-func (e *encoder) flush() {
-	if e.err != nil {
-		return
-	}
-	e.err = e.w.Flush()
-}
-
-func (e *encoder) write(p []byte) {
-	if e.err != nil {
-		return
-	}
-	_, e.err = e.w.Write(p)
-}
-
-func (e *encoder) writeByte(b byte) {
-	if e.err != nil {
-		return
-	}
-	e.err = e.w.WriteByte(b)
-}
-
-func (e *encoder) writeHeader() {
-	if e.err != nil {
-		return
-	}
-	_, e.err = io.WriteString(e.w, "GIF89a")
-	if e.err != nil {
-		return
-	}
-
-	pm := e.g.Image[0]
-	// Logical screen width and height.
-	writeUint16(e.buf[0:2], uint16(pm.Bounds().Dx()))
-	writeUint16(e.buf[2:4], uint16(pm.Bounds().Dy()))
-	e.write(e.buf[:4])
-
-	// All frames have a local color table, so a global color table
-	// is not needed.
-	e.buf[0] = 0x00
-	e.buf[1] = 0x00 // Background Color Index.
-	e.buf[2] = 0x00 // Pixel Aspect Ratio.
-	e.write(e.buf[:3])
-
-	// Add animation info if necessary.
-	if len(e.g.Image) > 1 {
-		e.buf[0] = 0x21 // Extension Introducer.
-		e.buf[1] = 0xff // Application Label.
-		e.buf[2] = 0x0b // Block Size.
-		e.write(e.buf[:3])
-		_, e.err = io.WriteString(e.w, "NETSCAPE2.0") // Application Identifier.
-		if e.err != nil {
-			return
-		}
-		e.buf[0] = 0x03 // Block Size.
-		e.buf[1] = 0x01 // Sub-block Index.
-		writeUint16(e.buf[2:4], uint16(e.g.LoopCount))
-		e.buf[4] = 0x00 // Block Terminator.
-		e.write(e.buf[:5])
-	}
-}
-
-func (e *encoder) writeColorTable(p color.Palette, size int) {
-	if e.err != nil {
-		return
-	}
-
-	for i := 0; i < log2Lookup[size]; i++ {
-		if i < len(p) {
-			r, g, b, _ := p[i].RGBA()
-			e.buf[3*i+0] = uint8(r >> 8)
-			e.buf[3*i+1] = uint8(g >> 8)
-			e.buf[3*i+2] = uint8(b >> 8)
-		} else {
-			// Pad with black.
-			e.buf[3*i+0] = 0x00
-			e.buf[3*i+1] = 0x00
-			e.buf[3*i+2] = 0x00
-		}
-	}
-	e.write(e.buf[:3*log2Lookup[size]])
-}
-
-func (e *encoder) writeImageBlock(pm *image.Paletted, delay int) {
-	if e.err != nil {
-		return
-	}
-
-	if len(pm.Palette) == 0 {
-		e.err = errors.New("gif: cannot encode image block with empty palette")
-		return
-	}
-
-	b := pm.Bounds()
-	if b.Dx() >= 1<<16 || b.Dy() >= 1<<16 || b.Min.X < 0 || b.Min.X >= 1<<16 || b.Min.Y < 0 || b.Min.Y >= 1<<16 {
-		e.err = errors.New("gif: image block is too large to encode")
-		return
-	}
-
-	transparentIndex := -1
-	for i, c := range pm.Palette {
-		if _, _, _, a := c.RGBA(); a == 0 {
-			transparentIndex = i
-			break
-		}
-	}
-
-	if delay > 0 || transparentIndex != -1 {
-		e.buf[0] = sExtension  // Extension Introducer.
-		e.buf[1] = gcLabel     // Graphic Control Label.
-		e.buf[2] = gcBlockSize // Block Size.
-		if transparentIndex != -1 {
-			e.buf[3] = 0x01
-		} else {
-			e.buf[3] = 0x00
-		}
-		writeUint16(e.buf[4:6], uint16(delay)) // Delay Time (1/100ths of a second)
-
-		// Transparent color index.
-		if transparentIndex != -1 {
-			e.buf[6] = uint8(transparentIndex)
-		} else {
-			e.buf[6] = 0x00
-		}
-		e.buf[7] = 0x00 // Block Terminator.
-		e.write(e.buf[:8])
-	}
-	e.buf[0] = sImageDescriptor
-	writeUint16(e.buf[1:3], uint16(b.Min.X))
-	writeUint16(e.buf[3:5], uint16(b.Min.Y))
-	writeUint16(e.buf[5:7], uint16(b.Dx()))
-	writeUint16(e.buf[7:9], uint16(b.Dy()))
-	e.write(e.buf[:9])
-
-	paddedSize := log2(len(pm.Palette)) // Size of Local Color Table: 2^(1+n).
-	// Interlacing is not supported.
-	e.writeByte(0x80 | uint8(paddedSize))
-
-	// Local Color Table.
-	e.writeColorTable(pm.Palette, paddedSize)
-
-	litWidth := paddedSize + 1
-	if litWidth < 2 {
-		litWidth = 2
-	}
-	e.writeByte(uint8(litWidth)) // LZW Minimum Code Size.
-
-	lzww := lzw.NewWriter(blockWriter{e: e}, lzw.LSB, litWidth)
-	_, e.err = lzww.Write(pm.Pix)
-	if e.err != nil {
-		lzww.Close()
-		return
-	}
-	lzww.Close()
-	e.writeByte(0x00) // Block Terminator.
-}
-
-// Options are the encoding parameters.
-type Options struct {
-	// NumColors is the maximum number of colors used in the image.
-	// It ranges from 1 to 256.
-	NumColors int
-
-	// Quantizer is used to produce a palette with size NumColors.
-	// palette.Plan9 is used in place of a nil Quantizer.
-	Quantizer draw.Quantizer
-
-	// Drawer is used to convert the source image to the desired palette.
-	// draw.FloydSteinberg is used in place of a nil Drawer.
-	Drawer draw.Drawer
-}
-
-// EncodeAll writes the images in g to w in GIF format with the
-// given loop count and delay between frames.
-func EncodeAll(w io.Writer, g *GIF) error {
-	if len(g.Image) == 0 {
-		return errors.New("gif: must provide at least one image")
-	}
-
-	if len(g.Image) != len(g.Delay) {
-		return errors.New("gif: mismatched image and delay lengths")
-	}
-	if g.LoopCount < 0 {
-		g.LoopCount = 0
-	}
-
-	e := encoder{g: g}
-	if ww, ok := w.(writer); ok {
-		e.w = ww
-	} else {
-		e.w = bufio.NewWriter(w)
-	}
-
-	e.writeHeader()
-	for i, pm := range g.Image {
-		e.writeImageBlock(pm, g.Delay[i])
-	}
-	e.writeByte(sTrailer)
-	e.flush()
-	return e.err
-}
-
-// Encode writes the Image m to w in GIF format.
-func Encode(w io.Writer, m image.Image, o *Options) error {
-	// Check for bounds and size restrictions.
-	b := m.Bounds()
-	if b.Dx() >= 1<<16 || b.Dy() >= 1<<16 {
-		return errors.New("gif: image is too large to encode")
-	}
-
-	opts := Options{}
-	if o != nil {
-		opts = *o
-	}
-	if opts.NumColors < 1 || 256 < opts.NumColors {
-		opts.NumColors = 256
-	}
-	if opts.Drawer == nil {
-		opts.Drawer = draw.FloydSteinberg
-	}
-
-	pm, ok := m.(*image.Paletted)
-	if !ok || len(pm.Palette) > opts.NumColors {
-		// TODO: Pick a better sub-sample of the Plan 9 palette.
-		pm = image.NewPaletted(b, palette.Plan9[:opts.NumColors])
-		if opts.Quantizer != nil {
-			pm.Palette = opts.Quantizer.Quantize(make(color.Palette, 0, opts.NumColors), m)
-		}
-		opts.Drawer.Draw(pm, b, m, image.ZP)
-	}
-
-	return EncodeAll(w, &GIF{
-		Image: []*image.Paletted{pm},
-		Delay: []int{0},
-	})
-}
diff --git a/src/pkg/image/gif/writer_test.go b/src/pkg/image/gif/writer_test.go
deleted file mode 100644
index c1ada76..0000000
--- a/src/pkg/image/gif/writer_test.go
+++ /dev/null
@@ -1,204 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package gif
-
-import (
-	"bytes"
-	"image"
-	"image/color"
-	_ "image/png"
-	"io/ioutil"
-	"math/rand"
-	"os"
-	"testing"
-)
-
-func readImg(filename string) (image.Image, error) {
-	f, err := os.Open(filename)
-	if err != nil {
-		return nil, err
-	}
-	defer f.Close()
-	m, _, err := image.Decode(f)
-	return m, err
-}
-
-func readGIF(filename string) (*GIF, error) {
-	f, err := os.Open(filename)
-	if err != nil {
-		return nil, err
-	}
-	defer f.Close()
-	return DecodeAll(f)
-}
-
-func delta(u0, u1 uint32) int64 {
-	d := int64(u0) - int64(u1)
-	if d < 0 {
-		return -d
-	}
-	return d
-}
-
-// averageDelta returns the average delta in RGB space. The two images must
-// have the same bounds.
-func averageDelta(m0, m1 image.Image) int64 {
-	b := m0.Bounds()
-	var sum, n int64
-	for y := b.Min.Y; y < b.Max.Y; y++ {
-		for x := b.Min.X; x < b.Max.X; x++ {
-			c0 := m0.At(x, y)
-			c1 := m1.At(x, y)
-			r0, g0, b0, _ := c0.RGBA()
-			r1, g1, b1, _ := c1.RGBA()
-			sum += delta(r0, r1)
-			sum += delta(g0, g1)
-			sum += delta(b0, b1)
-			n += 3
-		}
-	}
-	return sum / n
-}
-
-var testCase = []struct {
-	filename  string
-	tolerance int64
-}{
-	{"../testdata/video-001.png", 1 << 12},
-	{"../testdata/video-001.gif", 0},
-	{"../testdata/video-001.interlaced.gif", 0},
-}
-
-func TestWriter(t *testing.T) {
-	for _, tc := range testCase {
-		m0, err := readImg(tc.filename)
-		if err != nil {
-			t.Error(tc.filename, err)
-			continue
-		}
-		var buf bytes.Buffer
-		err = Encode(&buf, m0, nil)
-		if err != nil {
-			t.Error(tc.filename, err)
-			continue
-		}
-		m1, err := Decode(&buf)
-		if err != nil {
-			t.Error(tc.filename, err)
-			continue
-		}
-		if m0.Bounds() != m1.Bounds() {
-			t.Errorf("%s, bounds differ: %v and %v", tc.filename, m0.Bounds(), m1.Bounds())
-			continue
-		}
-		// Compare the average delta to the tolerance level.
-		avgDelta := averageDelta(m0, m1)
-		if avgDelta > tc.tolerance {
-			t.Errorf("%s: average delta is too high. expected: %d, got %d", tc.filename, tc.tolerance, avgDelta)
-			continue
-		}
-	}
-}
-
-var frames = []string{
-	"../testdata/video-001.gif",
-	"../testdata/video-005.gray.gif",
-}
-
-func TestEncodeAll(t *testing.T) {
-	g0 := &GIF{
-		Image:     make([]*image.Paletted, len(frames)),
-		Delay:     make([]int, len(frames)),
-		LoopCount: 5,
-	}
-	for i, f := range frames {
-		m, err := readGIF(f)
-		if err != nil {
-			t.Error(f, err)
-		}
-		g0.Image[i] = m.Image[0]
-	}
-	var buf bytes.Buffer
-	if err := EncodeAll(&buf, g0); err != nil {
-		t.Fatal("EncodeAll:", err)
-	}
-	g1, err := DecodeAll(&buf)
-	if err != nil {
-		t.Fatal("DecodeAll:", err)
-	}
-	if g0.LoopCount != g1.LoopCount {
-		t.Errorf("loop counts differ: %d and %d", g0.LoopCount, g1.LoopCount)
-	}
-	for i := range g0.Image {
-		m0, m1 := g0.Image[i], g1.Image[i]
-		if m0.Bounds() != m1.Bounds() {
-			t.Errorf("%s, bounds differ: %v and %v", frames[i], m0.Bounds(), m1.Bounds())
-		}
-		d0, d1 := g0.Delay[i], g1.Delay[i]
-		if d0 != d1 {
-			t.Errorf("%s: delay values differ: %d and %d", frames[i], d0, d1)
-		}
-	}
-
-	g1.Delay = make([]int, 1)
-	if err := EncodeAll(ioutil.Discard, g1); err == nil {
-		t.Error("expected error from mismatched delay and image slice lengths")
-	}
-	if err := EncodeAll(ioutil.Discard, &GIF{}); err == nil {
-		t.Error("expected error from providing empty gif")
-	}
-}
-
-func BenchmarkEncode(b *testing.B) {
-	b.StopTimer()
-
-	bo := image.Rect(0, 0, 640, 480)
-	rnd := rand.New(rand.NewSource(123))
-
-	// Restrict to a 256-color paletted image to avoid quantization path.
-	palette := make(color.Palette, 256)
-	for i := range palette {
-		palette[i] = color.RGBA{
-			uint8(rnd.Intn(256)),
-			uint8(rnd.Intn(256)),
-			uint8(rnd.Intn(256)),
-			255,
-		}
-	}
-	img := image.NewPaletted(image.Rect(0, 0, 640, 480), palette)
-	for y := bo.Min.Y; y < bo.Max.Y; y++ {
-		for x := bo.Min.X; x < bo.Max.X; x++ {
-			img.Set(x, y, palette[rnd.Intn(256)])
-		}
-	}
-
-	b.SetBytes(640 * 480 * 4)
-	b.StartTimer()
-	for i := 0; i < b.N; i++ {
-		Encode(ioutil.Discard, img, nil)
-	}
-}
-
-func BenchmarkQuantizedEncode(b *testing.B) {
-	b.StopTimer()
-	img := image.NewRGBA(image.Rect(0, 0, 640, 480))
-	bo := img.Bounds()
-	rnd := rand.New(rand.NewSource(123))
-	for y := bo.Min.Y; y < bo.Max.Y; y++ {
-		for x := bo.Min.X; x < bo.Max.X; x++ {
-			img.SetRGBA(x, y, color.RGBA{
-				uint8(rnd.Intn(256)),
-				uint8(rnd.Intn(256)),
-				uint8(rnd.Intn(256)),
-				255,
-			})
-		}
-	}
-	b.SetBytes(640 * 480 * 4)
-	b.StartTimer()
-	for i := 0; i < b.N; i++ {
-		Encode(ioutil.Discard, img, nil)
-	}
-}
diff --git a/src/pkg/image/image.go b/src/pkg/image/image.go
deleted file mode 100644
index 32a89ef..0000000
--- a/src/pkg/image/image.go
+++ /dev/null
@@ -1,904 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package image implements a basic 2-D image library.
-//
-// The fundamental interface is called Image. An Image contains colors, which
-// are described in the image/color package.
-//
-// Values of the Image interface are created either by calling functions such
-// as NewRGBA and NewPaletted, or by calling Decode on an io.Reader containing
-// image data in a format such as GIF, JPEG or PNG. Decoding any particular
-// image format requires the prior registration of a decoder function.
-// Registration is typically automatic as a side effect of initializing that
-// format's package so that, to decode a PNG image, it suffices to have
-//	import _ "image/png"
-// in a program's main package. The _ means to import a package purely for its
-// initialization side effects.
-//
-// See "The Go image package" for more details:
-// http://golang.org/doc/articles/image_package.html
-package image
-
-import (
-	"image/color"
-)
-
-// Config holds an image's color model and dimensions.
-type Config struct {
-	ColorModel    color.Model
-	Width, Height int
-}
-
-// Image is a finite rectangular grid of color.Color values taken from a color
-// model.
-type Image interface {
-	// ColorModel returns the Image's color model.
-	ColorModel() color.Model
-	// Bounds returns the domain for which At can return non-zero color.
-	// The bounds do not necessarily contain the point (0, 0).
-	Bounds() Rectangle
-	// At returns the color of the pixel at (x, y).
-	// At(Bounds().Min.X, Bounds().Min.Y) returns the upper-left pixel of the grid.
-	// At(Bounds().Max.X-1, Bounds().Max.Y-1) returns the lower-right one.
-	At(x, y int) color.Color
-}
-
-// PalettedImage is an image whose colors may come from a limited palette.
-// If m is a PalettedImage and m.ColorModel() returns a PalettedColorModel p,
-// then m.At(x, y) should be equivalent to p[m.ColorIndexAt(x, y)]. If m's
-// color model is not a PalettedColorModel, then ColorIndexAt's behavior is
-// undefined.
-type PalettedImage interface {
-	// ColorIndexAt returns the palette index of the pixel at (x, y).
-	ColorIndexAt(x, y int) uint8
-	Image
-}
-
-// RGBA is an in-memory image whose At method returns color.RGBA values.
-type RGBA struct {
-	// Pix holds the image's pixels, in R, G, B, A order. The pixel at
-	// (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*4].
-	Pix []uint8
-	// Stride is the Pix stride (in bytes) between vertically adjacent pixels.
-	Stride int
-	// Rect is the image's bounds.
-	Rect Rectangle
-}
-
-func (p *RGBA) ColorModel() color.Model { return color.RGBAModel }
-
-func (p *RGBA) Bounds() Rectangle { return p.Rect }
-
-func (p *RGBA) At(x, y int) color.Color {
-	if !(Point{x, y}.In(p.Rect)) {
-		return color.RGBA{}
-	}
-	i := p.PixOffset(x, y)
-	return color.RGBA{p.Pix[i+0], p.Pix[i+1], p.Pix[i+2], p.Pix[i+3]}
-}
-
-// PixOffset returns the index of the first element of Pix that corresponds to
-// the pixel at (x, y).
-func (p *RGBA) PixOffset(x, y int) int {
-	return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*4
-}
-
-func (p *RGBA) Set(x, y int, c color.Color) {
-	if !(Point{x, y}.In(p.Rect)) {
-		return
-	}
-	i := p.PixOffset(x, y)
-	c1 := color.RGBAModel.Convert(c).(color.RGBA)
-	p.Pix[i+0] = c1.R
-	p.Pix[i+1] = c1.G
-	p.Pix[i+2] = c1.B
-	p.Pix[i+3] = c1.A
-}
-
-func (p *RGBA) SetRGBA(x, y int, c color.RGBA) {
-	if !(Point{x, y}.In(p.Rect)) {
-		return
-	}
-	i := p.PixOffset(x, y)
-	p.Pix[i+0] = c.R
-	p.Pix[i+1] = c.G
-	p.Pix[i+2] = c.B
-	p.Pix[i+3] = c.A
-}
-
-// SubImage returns an image representing the portion of the image p visible
-// through r. The returned value shares pixels with the original image.
-func (p *RGBA) SubImage(r Rectangle) Image {
-	r = r.Intersect(p.Rect)
-	// If r1 and r2 are Rectangles, r1.Intersect(r2) is not guaranteed to be inside
-	// either r1 or r2 if the intersection is empty. Without explicitly checking for
-	// this, the Pix[i:] expression below can panic.
-	if r.Empty() {
-		return &RGBA{}
-	}
-	i := p.PixOffset(r.Min.X, r.Min.Y)
-	return &RGBA{
-		Pix:    p.Pix[i:],
-		Stride: p.Stride,
-		Rect:   r,
-	}
-}
-
-// Opaque scans the entire image and reports whether it is fully opaque.
-func (p *RGBA) Opaque() bool {
-	if p.Rect.Empty() {
-		return true
-	}
-	i0, i1 := 3, p.Rect.Dx()*4
-	for y := p.Rect.Min.Y; y < p.Rect.Max.Y; y++ {
-		for i := i0; i < i1; i += 4 {
-			if p.Pix[i] != 0xff {
-				return false
-			}
-		}
-		i0 += p.Stride
-		i1 += p.Stride
-	}
-	return true
-}
-
-// NewRGBA returns a new RGBA with the given bounds.
-func NewRGBA(r Rectangle) *RGBA {
-	w, h := r.Dx(), r.Dy()
-	buf := make([]uint8, 4*w*h)
-	return &RGBA{buf, 4 * w, r}
-}
-
-// RGBA64 is an in-memory image whose At method returns color.RGBA64 values.
-type RGBA64 struct {
-	// Pix holds the image's pixels, in R, G, B, A order and big-endian format. The pixel at
-	// (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*8].
-	Pix []uint8
-	// Stride is the Pix stride (in bytes) between vertically adjacent pixels.
-	Stride int
-	// Rect is the image's bounds.
-	Rect Rectangle
-}
-
-func (p *RGBA64) ColorModel() color.Model { return color.RGBA64Model }
-
-func (p *RGBA64) Bounds() Rectangle { return p.Rect }
-
-func (p *RGBA64) At(x, y int) color.Color {
-	if !(Point{x, y}.In(p.Rect)) {
-		return color.RGBA64{}
-	}
-	i := p.PixOffset(x, y)
-	return color.RGBA64{
-		uint16(p.Pix[i+0])<<8 | uint16(p.Pix[i+1]),
-		uint16(p.Pix[i+2])<<8 | uint16(p.Pix[i+3]),
-		uint16(p.Pix[i+4])<<8 | uint16(p.Pix[i+5]),
-		uint16(p.Pix[i+6])<<8 | uint16(p.Pix[i+7]),
-	}
-}
-
-// PixOffset returns the index of the first element of Pix that corresponds to
-// the pixel at (x, y).
-func (p *RGBA64) PixOffset(x, y int) int {
-	return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*8
-}
-
-func (p *RGBA64) Set(x, y int, c color.Color) {
-	if !(Point{x, y}.In(p.Rect)) {
-		return
-	}
-	i := p.PixOffset(x, y)
-	c1 := color.RGBA64Model.Convert(c).(color.RGBA64)
-	p.Pix[i+0] = uint8(c1.R >> 8)
-	p.Pix[i+1] = uint8(c1.R)
-	p.Pix[i+2] = uint8(c1.G >> 8)
-	p.Pix[i+3] = uint8(c1.G)
-	p.Pix[i+4] = uint8(c1.B >> 8)
-	p.Pix[i+5] = uint8(c1.B)
-	p.Pix[i+6] = uint8(c1.A >> 8)
-	p.Pix[i+7] = uint8(c1.A)
-}
-
-func (p *RGBA64) SetRGBA64(x, y int, c color.RGBA64) {
-	if !(Point{x, y}.In(p.Rect)) {
-		return
-	}
-	i := p.PixOffset(x, y)
-	p.Pix[i+0] = uint8(c.R >> 8)
-	p.Pix[i+1] = uint8(c.R)
-	p.Pix[i+2] = uint8(c.G >> 8)
-	p.Pix[i+3] = uint8(c.G)
-	p.Pix[i+4] = uint8(c.B >> 8)
-	p.Pix[i+5] = uint8(c.B)
-	p.Pix[i+6] = uint8(c.A >> 8)
-	p.Pix[i+7] = uint8(c.A)
-}
-
-// SubImage returns an image representing the portion of the image p visible
-// through r. The returned value shares pixels with the original image.
-func (p *RGBA64) SubImage(r Rectangle) Image {
-	r = r.Intersect(p.Rect)
-	// If r1 and r2 are Rectangles, r1.Intersect(r2) is not guaranteed to be inside
-	// either r1 or r2 if the intersection is empty. Without explicitly checking for
-	// this, the Pix[i:] expression below can panic.
-	if r.Empty() {
-		return &RGBA64{}
-	}
-	i := p.PixOffset(r.Min.X, r.Min.Y)
-	return &RGBA64{
-		Pix:    p.Pix[i:],
-		Stride: p.Stride,
-		Rect:   r,
-	}
-}
-
-// Opaque scans the entire image and reports whether it is fully opaque.
-func (p *RGBA64) Opaque() bool {
-	if p.Rect.Empty() {
-		return true
-	}
-	i0, i1 := 6, p.Rect.Dx()*8
-	for y := p.Rect.Min.Y; y < p.Rect.Max.Y; y++ {
-		for i := i0; i < i1; i += 8 {
-			if p.Pix[i+0] != 0xff || p.Pix[i+1] != 0xff {
-				return false
-			}
-		}
-		i0 += p.Stride
-		i1 += p.Stride
-	}
-	return true
-}
-
-// NewRGBA64 returns a new RGBA64 with the given bounds.
-func NewRGBA64(r Rectangle) *RGBA64 {
-	w, h := r.Dx(), r.Dy()
-	pix := make([]uint8, 8*w*h)
-	return &RGBA64{pix, 8 * w, r}
-}
-
-// NRGBA is an in-memory image whose At method returns color.NRGBA values.
-type NRGBA struct {
-	// Pix holds the image's pixels, in R, G, B, A order. The pixel at
-	// (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*4].
-	Pix []uint8
-	// Stride is the Pix stride (in bytes) between vertically adjacent pixels.
-	Stride int
-	// Rect is the image's bounds.
-	Rect Rectangle
-}
-
-func (p *NRGBA) ColorModel() color.Model { return color.NRGBAModel }
-
-func (p *NRGBA) Bounds() Rectangle { return p.Rect }
-
-func (p *NRGBA) At(x, y int) color.Color {
-	if !(Point{x, y}.In(p.Rect)) {
-		return color.NRGBA{}
-	}
-	i := p.PixOffset(x, y)
-	return color.NRGBA{p.Pix[i+0], p.Pix[i+1], p.Pix[i+2], p.Pix[i+3]}
-}
-
-// PixOffset returns the index of the first element of Pix that corresponds to
-// the pixel at (x, y).
-func (p *NRGBA) PixOffset(x, y int) int {
-	return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*4
-}
-
-func (p *NRGBA) Set(x, y int, c color.Color) {
-	if !(Point{x, y}.In(p.Rect)) {
-		return
-	}
-	i := p.PixOffset(x, y)
-	c1 := color.NRGBAModel.Convert(c).(color.NRGBA)
-	p.Pix[i+0] = c1.R
-	p.Pix[i+1] = c1.G
-	p.Pix[i+2] = c1.B
-	p.Pix[i+3] = c1.A
-}
-
-func (p *NRGBA) SetNRGBA(x, y int, c color.NRGBA) {
-	if !(Point{x, y}.In(p.Rect)) {
-		return
-	}
-	i := p.PixOffset(x, y)
-	p.Pix[i+0] = c.R
-	p.Pix[i+1] = c.G
-	p.Pix[i+2] = c.B
-	p.Pix[i+3] = c.A
-}
-
-// SubImage returns an image representing the portion of the image p visible
-// through r. The returned value shares pixels with the original image.
-func (p *NRGBA) SubImage(r Rectangle) Image {
-	r = r.Intersect(p.Rect)
-	// If r1 and r2 are Rectangles, r1.Intersect(r2) is not guaranteed to be inside
-	// either r1 or r2 if the intersection is empty. Without explicitly checking for
-	// this, the Pix[i:] expression below can panic.
-	if r.Empty() {
-		return &NRGBA{}
-	}
-	i := p.PixOffset(r.Min.X, r.Min.Y)
-	return &NRGBA{
-		Pix:    p.Pix[i:],
-		Stride: p.Stride,
-		Rect:   r,
-	}
-}
-
-// Opaque scans the entire image and reports whether it is fully opaque.
-func (p *NRGBA) Opaque() bool {
-	if p.Rect.Empty() {
-		return true
-	}
-	i0, i1 := 3, p.Rect.Dx()*4
-	for y := p.Rect.Min.Y; y < p.Rect.Max.Y; y++ {
-		for i := i0; i < i1; i += 4 {
-			if p.Pix[i] != 0xff {
-				return false
-			}
-		}
-		i0 += p.Stride
-		i1 += p.Stride
-	}
-	return true
-}
-
-// NewNRGBA returns a new NRGBA with the given bounds.
-func NewNRGBA(r Rectangle) *NRGBA {
-	w, h := r.Dx(), r.Dy()
-	pix := make([]uint8, 4*w*h)
-	return &NRGBA{pix, 4 * w, r}
-}
-
-// NRGBA64 is an in-memory image whose At method returns color.NRGBA64 values.
-type NRGBA64 struct {
-	// Pix holds the image's pixels, in R, G, B, A order and big-endian format. The pixel at
-	// (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*8].
-	Pix []uint8
-	// Stride is the Pix stride (in bytes) between vertically adjacent pixels.
-	Stride int
-	// Rect is the image's bounds.
-	Rect Rectangle
-}
-
-func (p *NRGBA64) ColorModel() color.Model { return color.NRGBA64Model }
-
-func (p *NRGBA64) Bounds() Rectangle { return p.Rect }
-
-func (p *NRGBA64) At(x, y int) color.Color {
-	if !(Point{x, y}.In(p.Rect)) {
-		return color.NRGBA64{}
-	}
-	i := p.PixOffset(x, y)
-	return color.NRGBA64{
-		uint16(p.Pix[i+0])<<8 | uint16(p.Pix[i+1]),
-		uint16(p.Pix[i+2])<<8 | uint16(p.Pix[i+3]),
-		uint16(p.Pix[i+4])<<8 | uint16(p.Pix[i+5]),
-		uint16(p.Pix[i+6])<<8 | uint16(p.Pix[i+7]),
-	}
-}
-
-// PixOffset returns the index of the first element of Pix that corresponds to
-// the pixel at (x, y).
-func (p *NRGBA64) PixOffset(x, y int) int {
-	return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*8
-}
-
-func (p *NRGBA64) Set(x, y int, c color.Color) {
-	if !(Point{x, y}.In(p.Rect)) {
-		return
-	}
-	i := p.PixOffset(x, y)
-	c1 := color.NRGBA64Model.Convert(c).(color.NRGBA64)
-	p.Pix[i+0] = uint8(c1.R >> 8)
-	p.Pix[i+1] = uint8(c1.R)
-	p.Pix[i+2] = uint8(c1.G >> 8)
-	p.Pix[i+3] = uint8(c1.G)
-	p.Pix[i+4] = uint8(c1.B >> 8)
-	p.Pix[i+5] = uint8(c1.B)
-	p.Pix[i+6] = uint8(c1.A >> 8)
-	p.Pix[i+7] = uint8(c1.A)
-}
-
-func (p *NRGBA64) SetNRGBA64(x, y int, c color.NRGBA64) {
-	if !(Point{x, y}.In(p.Rect)) {
-		return
-	}
-	i := p.PixOffset(x, y)
-	p.Pix[i+0] = uint8(c.R >> 8)
-	p.Pix[i+1] = uint8(c.R)
-	p.Pix[i+2] = uint8(c.G >> 8)
-	p.Pix[i+3] = uint8(c.G)
-	p.Pix[i+4] = uint8(c.B >> 8)
-	p.Pix[i+5] = uint8(c.B)
-	p.Pix[i+6] = uint8(c.A >> 8)
-	p.Pix[i+7] = uint8(c.A)
-}
-
-// SubImage returns an image representing the portion of the image p visible
-// through r. The returned value shares pixels with the original image.
-func (p *NRGBA64) SubImage(r Rectangle) Image {
-	r = r.Intersect(p.Rect)
-	// If r1 and r2 are Rectangles, r1.Intersect(r2) is not guaranteed to be inside
-	// either r1 or r2 if the intersection is empty. Without explicitly checking for
-	// this, the Pix[i:] expression below can panic.
-	if r.Empty() {
-		return &NRGBA64{}
-	}
-	i := p.PixOffset(r.Min.X, r.Min.Y)
-	return &NRGBA64{
-		Pix:    p.Pix[i:],
-		Stride: p.Stride,
-		Rect:   r,
-	}
-}
-
-// Opaque scans the entire image and reports whether it is fully opaque.
-func (p *NRGBA64) Opaque() bool {
-	if p.Rect.Empty() {
-		return true
-	}
-	i0, i1 := 6, p.Rect.Dx()*8
-	for y := p.Rect.Min.Y; y < p.Rect.Max.Y; y++ {
-		for i := i0; i < i1; i += 8 {
-			if p.Pix[i+0] != 0xff || p.Pix[i+1] != 0xff {
-				return false
-			}
-		}
-		i0 += p.Stride
-		i1 += p.Stride
-	}
-	return true
-}
-
-// NewNRGBA64 returns a new NRGBA64 with the given bounds.
-func NewNRGBA64(r Rectangle) *NRGBA64 {
-	w, h := r.Dx(), r.Dy()
-	pix := make([]uint8, 8*w*h)
-	return &NRGBA64{pix, 8 * w, r}
-}
-
-// Alpha is an in-memory image whose At method returns color.Alpha values.
-type Alpha struct {
-	// Pix holds the image's pixels, as alpha values. The pixel at
-	// (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*1].
-	Pix []uint8
-	// Stride is the Pix stride (in bytes) between vertically adjacent pixels.
-	Stride int
-	// Rect is the image's bounds.
-	Rect Rectangle
-}
-
-func (p *Alpha) ColorModel() color.Model { return color.AlphaModel }
-
-func (p *Alpha) Bounds() Rectangle { return p.Rect }
-
-func (p *Alpha) At(x, y int) color.Color {
-	if !(Point{x, y}.In(p.Rect)) {
-		return color.Alpha{}
-	}
-	i := p.PixOffset(x, y)
-	return color.Alpha{p.Pix[i]}
-}
-
-// PixOffset returns the index of the first element of Pix that corresponds to
-// the pixel at (x, y).
-func (p *Alpha) PixOffset(x, y int) int {
-	return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*1
-}
-
-func (p *Alpha) Set(x, y int, c color.Color) {
-	if !(Point{x, y}.In(p.Rect)) {
-		return
-	}
-	i := p.PixOffset(x, y)
-	p.Pix[i] = color.AlphaModel.Convert(c).(color.Alpha).A
-}
-
-func (p *Alpha) SetAlpha(x, y int, c color.Alpha) {
-	if !(Point{x, y}.In(p.Rect)) {
-		return
-	}
-	i := p.PixOffset(x, y)
-	p.Pix[i] = c.A
-}
-
-// SubImage returns an image representing the portion of the image p visible
-// through r. The returned value shares pixels with the original image.
-func (p *Alpha) SubImage(r Rectangle) Image {
-	r = r.Intersect(p.Rect)
-	// If r1 and r2 are Rectangles, r1.Intersect(r2) is not guaranteed to be inside
-	// either r1 or r2 if the intersection is empty. Without explicitly checking for
-	// this, the Pix[i:] expression below can panic.
-	if r.Empty() {
-		return &Alpha{}
-	}
-	i := p.PixOffset(r.Min.X, r.Min.Y)
-	return &Alpha{
-		Pix:    p.Pix[i:],
-		Stride: p.Stride,
-		Rect:   r,
-	}
-}
-
-// Opaque scans the entire image and reports whether it is fully opaque.
-func (p *Alpha) Opaque() bool {
-	if p.Rect.Empty() {
-		return true
-	}
-	i0, i1 := 0, p.Rect.Dx()
-	for y := p.Rect.Min.Y; y < p.Rect.Max.Y; y++ {
-		for i := i0; i < i1; i++ {
-			if p.Pix[i] != 0xff {
-				return false
-			}
-		}
-		i0 += p.Stride
-		i1 += p.Stride
-	}
-	return true
-}
-
-// NewAlpha returns a new Alpha with the given bounds.
-func NewAlpha(r Rectangle) *Alpha {
-	w, h := r.Dx(), r.Dy()
-	pix := make([]uint8, 1*w*h)
-	return &Alpha{pix, 1 * w, r}
-}
-
-// Alpha16 is an in-memory image whose At method returns color.Alpha64 values.
-type Alpha16 struct {
-	// Pix holds the image's pixels, as alpha values in big-endian format. The pixel at
-	// (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*2].
-	Pix []uint8
-	// Stride is the Pix stride (in bytes) between vertically adjacent pixels.
-	Stride int
-	// Rect is the image's bounds.
-	Rect Rectangle
-}
-
-func (p *Alpha16) ColorModel() color.Model { return color.Alpha16Model }
-
-func (p *Alpha16) Bounds() Rectangle { return p.Rect }
-
-func (p *Alpha16) At(x, y int) color.Color {
-	if !(Point{x, y}.In(p.Rect)) {
-		return color.Alpha16{}
-	}
-	i := p.PixOffset(x, y)
-	return color.Alpha16{uint16(p.Pix[i+0])<<8 | uint16(p.Pix[i+1])}
-}
-
-// PixOffset returns the index of the first element of Pix that corresponds to
-// the pixel at (x, y).
-func (p *Alpha16) PixOffset(x, y int) int {
-	return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*2
-}
-
-func (p *Alpha16) Set(x, y int, c color.Color) {
-	if !(Point{x, y}.In(p.Rect)) {
-		return
-	}
-	i := p.PixOffset(x, y)
-	c1 := color.Alpha16Model.Convert(c).(color.Alpha16)
-	p.Pix[i+0] = uint8(c1.A >> 8)
-	p.Pix[i+1] = uint8(c1.A)
-}
-
-func (p *Alpha16) SetAlpha16(x, y int, c color.Alpha16) {
-	if !(Point{x, y}.In(p.Rect)) {
-		return
-	}
-	i := p.PixOffset(x, y)
-	p.Pix[i+0] = uint8(c.A >> 8)
-	p.Pix[i+1] = uint8(c.A)
-}
-
-// SubImage returns an image representing the portion of the image p visible
-// through r. The returned value shares pixels with the original image.
-func (p *Alpha16) SubImage(r Rectangle) Image {
-	r = r.Intersect(p.Rect)
-	// If r1 and r2 are Rectangles, r1.Intersect(r2) is not guaranteed to be inside
-	// either r1 or r2 if the intersection is empty. Without explicitly checking for
-	// this, the Pix[i:] expression below can panic.
-	if r.Empty() {
-		return &Alpha16{}
-	}
-	i := p.PixOffset(r.Min.X, r.Min.Y)
-	return &Alpha16{
-		Pix:    p.Pix[i:],
-		Stride: p.Stride,
-		Rect:   r,
-	}
-}
-
-// Opaque scans the entire image and reports whether it is fully opaque.
-func (p *Alpha16) Opaque() bool {
-	if p.Rect.Empty() {
-		return true
-	}
-	i0, i1 := 0, p.Rect.Dx()*2
-	for y := p.Rect.Min.Y; y < p.Rect.Max.Y; y++ {
-		for i := i0; i < i1; i += 2 {
-			if p.Pix[i+0] != 0xff || p.Pix[i+1] != 0xff {
-				return false
-			}
-		}
-		i0 += p.Stride
-		i1 += p.Stride
-	}
-	return true
-}
-
-// NewAlpha16 returns a new Alpha16 with the given bounds.
-func NewAlpha16(r Rectangle) *Alpha16 {
-	w, h := r.Dx(), r.Dy()
-	pix := make([]uint8, 2*w*h)
-	return &Alpha16{pix, 2 * w, r}
-}
-
-// Gray is an in-memory image whose At method returns color.Gray values.
-type Gray struct {
-	// Pix holds the image's pixels, as gray values. The pixel at
-	// (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*1].
-	Pix []uint8
-	// Stride is the Pix stride (in bytes) between vertically adjacent pixels.
-	Stride int
-	// Rect is the image's bounds.
-	Rect Rectangle
-}
-
-func (p *Gray) ColorModel() color.Model { return color.GrayModel }
-
-func (p *Gray) Bounds() Rectangle { return p.Rect }
-
-func (p *Gray) At(x, y int) color.Color {
-	if !(Point{x, y}.In(p.Rect)) {
-		return color.Gray{}
-	}
-	i := p.PixOffset(x, y)
-	return color.Gray{p.Pix[i]}
-}
-
-// PixOffset returns the index of the first element of Pix that corresponds to
-// the pixel at (x, y).
-func (p *Gray) PixOffset(x, y int) int {
-	return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*1
-}
-
-func (p *Gray) Set(x, y int, c color.Color) {
-	if !(Point{x, y}.In(p.Rect)) {
-		return
-	}
-	i := p.PixOffset(x, y)
-	p.Pix[i] = color.GrayModel.Convert(c).(color.Gray).Y
-}
-
-func (p *Gray) SetGray(x, y int, c color.Gray) {
-	if !(Point{x, y}.In(p.Rect)) {
-		return
-	}
-	i := p.PixOffset(x, y)
-	p.Pix[i] = c.Y
-}
-
-// SubImage returns an image representing the portion of the image p visible
-// through r. The returned value shares pixels with the original image.
-func (p *Gray) SubImage(r Rectangle) Image {
-	r = r.Intersect(p.Rect)
-	// If r1 and r2 are Rectangles, r1.Intersect(r2) is not guaranteed to be inside
-	// either r1 or r2 if the intersection is empty. Without explicitly checking for
-	// this, the Pix[i:] expression below can panic.
-	if r.Empty() {
-		return &Gray{}
-	}
-	i := p.PixOffset(r.Min.X, r.Min.Y)
-	return &Gray{
-		Pix:    p.Pix[i:],
-		Stride: p.Stride,
-		Rect:   r,
-	}
-}
-
-// Opaque scans the entire image and reports whether it is fully opaque.
-func (p *Gray) Opaque() bool {
-	return true
-}
-
-// NewGray returns a new Gray with the given bounds.
-func NewGray(r Rectangle) *Gray {
-	w, h := r.Dx(), r.Dy()
-	pix := make([]uint8, 1*w*h)
-	return &Gray{pix, 1 * w, r}
-}
-
-// Gray16 is an in-memory image whose At method returns color.Gray16 values.
-type Gray16 struct {
-	// Pix holds the image's pixels, as gray values in big-endian format. The pixel at
-	// (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*2].
-	Pix []uint8
-	// Stride is the Pix stride (in bytes) between vertically adjacent pixels.
-	Stride int
-	// Rect is the image's bounds.
-	Rect Rectangle
-}
-
-func (p *Gray16) ColorModel() color.Model { return color.Gray16Model }
-
-func (p *Gray16) Bounds() Rectangle { return p.Rect }
-
-func (p *Gray16) At(x, y int) color.Color {
-	if !(Point{x, y}.In(p.Rect)) {
-		return color.Gray16{}
-	}
-	i := p.PixOffset(x, y)
-	return color.Gray16{uint16(p.Pix[i+0])<<8 | uint16(p.Pix[i+1])}
-}
-
-// PixOffset returns the index of the first element of Pix that corresponds to
-// the pixel at (x, y).
-func (p *Gray16) PixOffset(x, y int) int {
-	return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*2
-}
-
-func (p *Gray16) Set(x, y int, c color.Color) {
-	if !(Point{x, y}.In(p.Rect)) {
-		return
-	}
-	i := p.PixOffset(x, y)
-	c1 := color.Gray16Model.Convert(c).(color.Gray16)
-	p.Pix[i+0] = uint8(c1.Y >> 8)
-	p.Pix[i+1] = uint8(c1.Y)
-}
-
-func (p *Gray16) SetGray16(x, y int, c color.Gray16) {
-	if !(Point{x, y}.In(p.Rect)) {
-		return
-	}
-	i := p.PixOffset(x, y)
-	p.Pix[i+0] = uint8(c.Y >> 8)
-	p.Pix[i+1] = uint8(c.Y)
-}
-
-// SubImage returns an image representing the portion of the image p visible
-// through r. The returned value shares pixels with the original image.
-func (p *Gray16) SubImage(r Rectangle) Image {
-	r = r.Intersect(p.Rect)
-	// If r1 and r2 are Rectangles, r1.Intersect(r2) is not guaranteed to be inside
-	// either r1 or r2 if the intersection is empty. Without explicitly checking for
-	// this, the Pix[i:] expression below can panic.
-	if r.Empty() {
-		return &Gray16{}
-	}
-	i := p.PixOffset(r.Min.X, r.Min.Y)
-	return &Gray16{
-		Pix:    p.Pix[i:],
-		Stride: p.Stride,
-		Rect:   r,
-	}
-}
-
-// Opaque scans the entire image and reports whether it is fully opaque.
-func (p *Gray16) Opaque() bool {
-	return true
-}
-
-// NewGray16 returns a new Gray16 with the given bounds.
-func NewGray16(r Rectangle) *Gray16 {
-	w, h := r.Dx(), r.Dy()
-	pix := make([]uint8, 2*w*h)
-	return &Gray16{pix, 2 * w, r}
-}
-
-// Paletted is an in-memory image of uint8 indices into a given palette.
-type Paletted struct {
-	// Pix holds the image's pixels, as palette indices. The pixel at
-	// (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*1].
-	Pix []uint8
-	// Stride is the Pix stride (in bytes) between vertically adjacent pixels.
-	Stride int
-	// Rect is the image's bounds.
-	Rect Rectangle
-	// Palette is the image's palette.
-	Palette color.Palette
-}
-
-func (p *Paletted) ColorModel() color.Model { return p.Palette }
-
-func (p *Paletted) Bounds() Rectangle { return p.Rect }
-
-func (p *Paletted) At(x, y int) color.Color {
-	if len(p.Palette) == 0 {
-		return nil
-	}
-	if !(Point{x, y}.In(p.Rect)) {
-		return p.Palette[0]
-	}
-	i := p.PixOffset(x, y)
-	return p.Palette[p.Pix[i]]
-}
-
-// PixOffset returns the index of the first element of Pix that corresponds to
-// the pixel at (x, y).
-func (p *Paletted) PixOffset(x, y int) int {
-	return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*1
-}
-
-func (p *Paletted) Set(x, y int, c color.Color) {
-	if !(Point{x, y}.In(p.Rect)) {
-		return
-	}
-	i := p.PixOffset(x, y)
-	p.Pix[i] = uint8(p.Palette.Index(c))
-}
-
-func (p *Paletted) ColorIndexAt(x, y int) uint8 {
-	if !(Point{x, y}.In(p.Rect)) {
-		return 0
-	}
-	i := p.PixOffset(x, y)
-	return p.Pix[i]
-}
-
-func (p *Paletted) SetColorIndex(x, y int, index uint8) {
-	if !(Point{x, y}.In(p.Rect)) {
-		return
-	}
-	i := p.PixOffset(x, y)
-	p.Pix[i] = index
-}
-
-// SubImage returns an image representing the portion of the image p visible
-// through r. The returned value shares pixels with the original image.
-func (p *Paletted) SubImage(r Rectangle) Image {
-	r = r.Intersect(p.Rect)
-	// If r1 and r2 are Rectangles, r1.Intersect(r2) is not guaranteed to be inside
-	// either r1 or r2 if the intersection is empty. Without explicitly checking for
-	// this, the Pix[i:] expression below can panic.
-	if r.Empty() {
-		return &Paletted{
-			Palette: p.Palette,
-		}
-	}
-	i := p.PixOffset(r.Min.X, r.Min.Y)
-	return &Paletted{
-		Pix:     p.Pix[i:],
-		Stride:  p.Stride,
-		Rect:    p.Rect.Intersect(r),
-		Palette: p.Palette,
-	}
-}
-
-// Opaque scans the entire image and reports whether it is fully opaque.
-func (p *Paletted) Opaque() bool {
-	var present [256]bool
-	i0, i1 := 0, p.Rect.Dx()
-	for y := p.Rect.Min.Y; y < p.Rect.Max.Y; y++ {
-		for _, c := range p.Pix[i0:i1] {
-			present[c] = true
-		}
-		i0 += p.Stride
-		i1 += p.Stride
-	}
-	for i, c := range p.Palette {
-		if !present[i] {
-			continue
-		}
-		_, _, _, a := c.RGBA()
-		if a != 0xffff {
-			return false
-		}
-	}
-	return true
-}
-
-// NewPaletted returns a new Paletted with the given width, height and palette.
-func NewPaletted(r Rectangle, p color.Palette) *Paletted {
-	w, h := r.Dx(), r.Dy()
-	pix := make([]uint8, 1*w*h)
-	return &Paletted{pix, 1 * w, r, p}
-}
diff --git a/src/pkg/image/jpeg/huffman.go b/src/pkg/image/jpeg/huffman.go
deleted file mode 100644
index f53d873..0000000
--- a/src/pkg/image/jpeg/huffman.go
+++ /dev/null
@@ -1,219 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package jpeg
-
-import "io"
-
-// Each code is at most 16 bits long.
-const maxCodeLength = 16
-
-// Each decoded value is a uint8, so there are at most 256 such values.
-const maxNumValues = 256
-
-// Bit stream for the Huffman decoder.
-// The n least significant bits of a form the unread bits, to be read in MSB to LSB order.
-type bits struct {
-	a uint32 // accumulator.
-	m uint32 // mask. m==1<<(n-1) when n>0, with m==0 when n==0.
-	n int    // the number of unread bits in a.
-}
-
-// Huffman table decoder, specified in section C.
-type huffman struct {
-	l        [maxCodeLength]int
-	length   int                 // sum of l[i].
-	val      [maxNumValues]uint8 // the decoded values, as sorted by their encoding.
-	size     [maxNumValues]int   // size[i] is the number of bits to encode val[i].
-	code     [maxNumValues]int   // code[i] is the encoding of val[i].
-	minCode  [maxCodeLength]int  // min codes of length i, or -1 if no codes of that length.
-	maxCode  [maxCodeLength]int  // max codes of length i, or -1 if no codes of that length.
-	valIndex [maxCodeLength]int  // index into val of minCode[i].
-}
-
-// Reads bytes from the io.Reader to ensure that bits.n is at least n.
-func (d *decoder) ensureNBits(n int) error {
-	for d.b.n < n {
-		c, err := d.r.ReadByte()
-		if err != nil {
-			if err == io.EOF {
-				return FormatError("short Huffman data")
-			}
-			return err
-		}
-		d.b.a = d.b.a<<8 | uint32(c)
-		d.b.n += 8
-		if d.b.m == 0 {
-			d.b.m = 1 << 7
-		} else {
-			d.b.m <<= 8
-		}
-		// Byte stuffing, specified in section F.1.2.3.
-		if c == 0xff {
-			c, err = d.r.ReadByte()
-			if err != nil {
-				if err == io.EOF {
-					return FormatError("short Huffman data")
-				}
-				return err
-			}
-			if c != 0x00 {
-				return FormatError("missing 0xff00 sequence")
-			}
-		}
-	}
-	return nil
-}
-
-// The composition of RECEIVE and EXTEND, specified in section F.2.2.1.
-func (d *decoder) receiveExtend(t uint8) (int32, error) {
-	if d.b.n < int(t) {
-		if err := d.ensureNBits(int(t)); err != nil {
-			return 0, err
-		}
-	}
-	d.b.n -= int(t)
-	d.b.m >>= t
-	s := int32(1) << t
-	x := int32(d.b.a>>uint8(d.b.n)) & (s - 1)
-	if x < s>>1 {
-		x += ((-1) << t) + 1
-	}
-	return x, nil
-}
-
-// Processes a Define Huffman Table marker, and initializes a huffman struct from its contents.
-// Specified in section B.2.4.2.
-func (d *decoder) processDHT(n int) error {
-	for n > 0 {
-		if n < 17 {
-			return FormatError("DHT has wrong length")
-		}
-		_, err := io.ReadFull(d.r, d.tmp[0:17])
-		if err != nil {
-			return err
-		}
-		tc := d.tmp[0] >> 4
-		if tc > maxTc {
-			return FormatError("bad Tc value")
-		}
-		th := d.tmp[0] & 0x0f
-		if th > maxTh || !d.progressive && th > 1 {
-			return FormatError("bad Th value")
-		}
-		h := &d.huff[tc][th]
-
-		// Read l and val (and derive length).
-		h.length = 0
-		for i := 0; i < maxCodeLength; i++ {
-			h.l[i] = int(d.tmp[i+1])
-			h.length += h.l[i]
-		}
-		if h.length == 0 {
-			return FormatError("Huffman table has zero length")
-		}
-		if h.length > maxNumValues {
-			return FormatError("Huffman table has excessive length")
-		}
-		n -= h.length + 17
-		if n < 0 {
-			return FormatError("DHT has wrong length")
-		}
-		_, err = io.ReadFull(d.r, h.val[0:h.length])
-		if err != nil {
-			return err
-		}
-
-		// Derive size.
-		k := 0
-		for i := 0; i < maxCodeLength; i++ {
-			for j := 0; j < h.l[i]; j++ {
-				h.size[k] = i + 1
-				k++
-			}
-		}
-
-		// Derive code.
-		code := 0
-		size := h.size[0]
-		for i := 0; i < h.length; i++ {
-			if size != h.size[i] {
-				code <<= uint8(h.size[i] - size)
-				size = h.size[i]
-			}
-			h.code[i] = code
-			code++
-		}
-
-		// Derive minCode, maxCode, and valIndex.
-		k = 0
-		index := 0
-		for i := 0; i < maxCodeLength; i++ {
-			if h.l[i] == 0 {
-				h.minCode[i] = -1
-				h.maxCode[i] = -1
-				h.valIndex[i] = -1
-			} else {
-				h.minCode[i] = k
-				h.maxCode[i] = k + h.l[i] - 1
-				h.valIndex[i] = index
-				k += h.l[i]
-				index += h.l[i]
-			}
-			k <<= 1
-		}
-	}
-	return nil
-}
-
-// Returns the next Huffman-coded value from the bit stream, decoded according to h.
-// TODO(nigeltao): This decoding algorithm is simple, but slow. A lookahead table, instead of always
-// peeling off only 1 bit at time, ought to be faster.
-func (d *decoder) decodeHuffman(h *huffman) (uint8, error) {
-	if h.length == 0 {
-		return 0, FormatError("uninitialized Huffman table")
-	}
-	for i, code := 0, 0; i < maxCodeLength; i++ {
-		if d.b.n == 0 {
-			if err := d.ensureNBits(1); err != nil {
-				return 0, err
-			}
-		}
-		if d.b.a&d.b.m != 0 {
-			code |= 1
-		}
-		d.b.n--
-		d.b.m >>= 1
-		if code <= h.maxCode[i] {
-			return h.val[h.valIndex[i]+code-h.minCode[i]], nil
-		}
-		code <<= 1
-	}
-	return 0, FormatError("bad Huffman code")
-}
-
-func (d *decoder) decodeBit() (bool, error) {
-	if d.b.n == 0 {
-		if err := d.ensureNBits(1); err != nil {
-			return false, err
-		}
-	}
-	ret := d.b.a&d.b.m != 0
-	d.b.n--
-	d.b.m >>= 1
-	return ret, nil
-}
-
-func (d *decoder) decodeBits(n int) (uint32, error) {
-	if d.b.n < n {
-		if err := d.ensureNBits(n); err != nil {
-			return 0, err
-		}
-	}
-	ret := d.b.a >> uint(d.b.n-n)
-	ret &= (1 << uint(n)) - 1
-	d.b.n -= n
-	d.b.m >>= uint(n)
-	return ret, nil
-}
diff --git a/src/pkg/image/jpeg/reader.go b/src/pkg/image/jpeg/reader.go
deleted file mode 100644
index 356d562..0000000
--- a/src/pkg/image/jpeg/reader.go
+++ /dev/null
@@ -1,377 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package jpeg implements a JPEG image decoder and encoder.
-//
-// JPEG is defined in ITU-T T.81: http://www.w3.org/Graphics/JPEG/itu-t81.pdf.
-package jpeg
-
-import (
-	"bufio"
-	"image"
-	"image/color"
-	"io"
-)
-
-// TODO(nigeltao): fix up the doc comment style so that sentences start with
-// the name of the type or function that they annotate.
-
-// A FormatError reports that the input is not a valid JPEG.
-type FormatError string
-
-func (e FormatError) Error() string { return "invalid JPEG format: " + string(e) }
-
-// An UnsupportedError reports that the input uses a valid but unimplemented JPEG feature.
-type UnsupportedError string
-
-func (e UnsupportedError) Error() string { return "unsupported JPEG feature: " + string(e) }
-
-// Component specification, specified in section B.2.2.
-type component struct {
-	h  int   // Horizontal sampling factor.
-	v  int   // Vertical sampling factor.
-	c  uint8 // Component identifier.
-	tq uint8 // Quantization table destination selector.
-}
-
-const (
-	dcTable = 0
-	acTable = 1
-	maxTc   = 1
-	maxTh   = 3
-	maxTq   = 3
-
-	// A grayscale JPEG image has only a Y component.
-	nGrayComponent = 1
-	// A color JPEG image has Y, Cb and Cr components.
-	nColorComponent = 3
-
-	// We only support 4:4:4, 4:4:0, 4:2:2 and 4:2:0 downsampling, and therefore the
-	// number of luma samples per chroma sample is at most 2 in the horizontal
-	// and 2 in the vertical direction.
-	maxH = 2
-	maxV = 2
-)
-
-const (
-	soiMarker   = 0xd8 // Start Of Image.
-	eoiMarker   = 0xd9 // End Of Image.
-	sof0Marker  = 0xc0 // Start Of Frame (Baseline).
-	sof2Marker  = 0xc2 // Start Of Frame (Progressive).
-	dhtMarker   = 0xc4 // Define Huffman Table.
-	dqtMarker   = 0xdb // Define Quantization Table.
-	sosMarker   = 0xda // Start Of Scan.
-	driMarker   = 0xdd // Define Restart Interval.
-	rst0Marker  = 0xd0 // ReSTart (0).
-	rst7Marker  = 0xd7 // ReSTart (7).
-	app0Marker  = 0xe0 // APPlication specific (0).
-	app15Marker = 0xef // APPlication specific (15).
-	comMarker   = 0xfe // COMment.
-)
-
-// unzig maps from the zig-zag ordering to the natural ordering. For example,
-// unzig[3] is the column and row of the fourth element in zig-zag order. The
-// value is 16, which means first column (16%8 == 0) and third row (16/8 == 2).
-var unzig = [blockSize]int{
-	0, 1, 8, 16, 9, 2, 3, 10,
-	17, 24, 32, 25, 18, 11, 4, 5,
-	12, 19, 26, 33, 40, 48, 41, 34,
-	27, 20, 13, 6, 7, 14, 21, 28,
-	35, 42, 49, 56, 57, 50, 43, 36,
-	29, 22, 15, 23, 30, 37, 44, 51,
-	58, 59, 52, 45, 38, 31, 39, 46,
-	53, 60, 61, 54, 47, 55, 62, 63,
-}
-
-// If the passed in io.Reader does not also have ReadByte, then Decode will introduce its own buffering.
-type Reader interface {
-	io.Reader
-	ReadByte() (c byte, err error)
-}
-
-type decoder struct {
-	r             Reader
-	b             bits
-	width, height int
-	img1          *image.Gray
-	img3          *image.YCbCr
-	ri            int // Restart Interval.
-	nComp         int
-	progressive   bool
-	eobRun        uint16 // End-of-Band run, specified in section G.1.2.2.
-	comp          [nColorComponent]component
-	progCoeffs    [nColorComponent][]block // Saved state between progressive-mode scans.
-	huff          [maxTc + 1][maxTh + 1]huffman
-	quant         [maxTq + 1]block // Quantization tables, in zig-zag order.
-	tmp           [1024]byte
-}
-
-// Reads and ignores the next n bytes.
-func (d *decoder) ignore(n int) error {
-	for n > 0 {
-		m := len(d.tmp)
-		if m > n {
-			m = n
-		}
-		_, err := io.ReadFull(d.r, d.tmp[0:m])
-		if err != nil {
-			return err
-		}
-		n -= m
-	}
-	return nil
-}
-
-// Specified in section B.2.2.
-func (d *decoder) processSOF(n int) error {
-	switch n {
-	case 6 + 3*nGrayComponent:
-		d.nComp = nGrayComponent
-	case 6 + 3*nColorComponent:
-		d.nComp = nColorComponent
-	default:
-		return UnsupportedError("SOF has wrong length")
-	}
-	_, err := io.ReadFull(d.r, d.tmp[:n])
-	if err != nil {
-		return err
-	}
-	// We only support 8-bit precision.
-	if d.tmp[0] != 8 {
-		return UnsupportedError("precision")
-	}
-	d.height = int(d.tmp[1])<<8 + int(d.tmp[2])
-	d.width = int(d.tmp[3])<<8 + int(d.tmp[4])
-	if int(d.tmp[5]) != d.nComp {
-		return UnsupportedError("SOF has wrong number of image components")
-	}
-	for i := 0; i < d.nComp; i++ {
-		d.comp[i].c = d.tmp[6+3*i]
-		d.comp[i].tq = d.tmp[8+3*i]
-		if d.nComp == nGrayComponent {
-			// If a JPEG image has only one component, section A.2 says "this data
-			// is non-interleaved by definition" and section A.2.2 says "[in this
-			// case...] the order of data units within a scan shall be left-to-right
-			// and top-to-bottom... regardless of the values of H_1 and V_1". Section
-			// 4.8.2 also says "[for non-interleaved data], the MCU is defined to be
-			// one data unit". Similarly, section A.1.1 explains that it is the ratio
-			// of H_i to max_j(H_j) that matters, and similarly for V. For grayscale
-			// images, H_1 is the maximum H_j for all components j, so that ratio is
-			// always 1. The component's (h, v) is effectively always (1, 1): even if
-			// the nominal (h, v) is (2, 1), a 20x5 image is encoded in three 8x8
-			// MCUs, not two 16x8 MCUs.
-			d.comp[i].h = 1
-			d.comp[i].v = 1
-			continue
-		}
-		hv := d.tmp[7+3*i]
-		d.comp[i].h = int(hv >> 4)
-		d.comp[i].v = int(hv & 0x0f)
-		// For color images, we only support 4:4:4, 4:4:0, 4:2:2 or 4:2:0 chroma
-		// downsampling ratios. This implies that the (h, v) values for the Y
-		// component are either (1, 1), (1, 2), (2, 1) or (2, 2), and the (h, v)
-		// values for the Cr and Cb components must be (1, 1).
-		if i == 0 {
-			if hv != 0x11 && hv != 0x21 && hv != 0x22 && hv != 0x12 {
-				return UnsupportedError("luma/chroma downsample ratio")
-			}
-		} else if hv != 0x11 {
-			return UnsupportedError("luma/chroma downsample ratio")
-		}
-	}
-	return nil
-}
-
-// Specified in section B.2.4.1.
-func (d *decoder) processDQT(n int) error {
-	const qtLength = 1 + blockSize
-	for ; n >= qtLength; n -= qtLength {
-		_, err := io.ReadFull(d.r, d.tmp[0:qtLength])
-		if err != nil {
-			return err
-		}
-		pq := d.tmp[0] >> 4
-		if pq != 0 {
-			return UnsupportedError("bad Pq value")
-		}
-		tq := d.tmp[0] & 0x0f
-		if tq > maxTq {
-			return FormatError("bad Tq value")
-		}
-		for i := range d.quant[tq] {
-			d.quant[tq][i] = int32(d.tmp[i+1])
-		}
-	}
-	if n != 0 {
-		return FormatError("DQT has wrong length")
-	}
-	return nil
-}
-
-// Specified in section B.2.4.4.
-func (d *decoder) processDRI(n int) error {
-	if n != 2 {
-		return FormatError("DRI has wrong length")
-	}
-	_, err := io.ReadFull(d.r, d.tmp[0:2])
-	if err != nil {
-		return err
-	}
-	d.ri = int(d.tmp[0])<<8 + int(d.tmp[1])
-	return nil
-}
-
-// decode reads a JPEG image from r and returns it as an image.Image.
-func (d *decoder) decode(r io.Reader, configOnly bool) (image.Image, error) {
-	if rr, ok := r.(Reader); ok {
-		d.r = rr
-	} else {
-		d.r = bufio.NewReader(r)
-	}
-
-	// Check for the Start Of Image marker.
-	_, err := io.ReadFull(d.r, d.tmp[0:2])
-	if err != nil {
-		return nil, err
-	}
-	if d.tmp[0] != 0xff || d.tmp[1] != soiMarker {
-		return nil, FormatError("missing SOI marker")
-	}
-
-	// Process the remaining segments until the End Of Image marker.
-	for {
-		_, err := io.ReadFull(d.r, d.tmp[0:2])
-		if err != nil {
-			return nil, err
-		}
-		for d.tmp[0] != 0xff {
-			// Strictly speaking, this is a format error. However, libjpeg is
-			// liberal in what it accepts. As of version 9, next_marker in
-			// jdmarker.c treats this as a warning (JWRN_EXTRANEOUS_DATA) and
-			// continues to decode the stream. Even before next_marker sees
-			// extraneous data, jpeg_fill_bit_buffer in jdhuff.c reads as many
-			// bytes as it can, possibly past the end of a scan's data. It
-			// effectively puts back any markers that it overscanned (e.g. an
-			// "\xff\xd9" EOI marker), but it does not put back non-marker data,
-			// and thus it can silently ignore a small number of extraneous
-			// non-marker bytes before next_marker has a chance to see them (and
-			// print a warning).
-			//
-			// We are therefore also liberal in what we accept. Extraneous data
-			// is silently ignored.
-			//
-			// This is similar to, but not exactly the same as, the restart
-			// mechanism within a scan (the RST[0-7] markers).
-			//
-			// Note that extraneous 0xff bytes in e.g. SOS data are escaped as
-			// "\xff\x00", and so are detected a little further down below.
-			d.tmp[0] = d.tmp[1]
-			d.tmp[1], err = d.r.ReadByte()
-			if err != nil {
-				return nil, err
-			}
-		}
-		marker := d.tmp[1]
-		if marker == 0 {
-			// Treat "\xff\x00" as extraneous data.
-			continue
-		}
-		for marker == 0xff {
-			// Section B.1.1.2 says, "Any marker may optionally be preceded by any
-			// number of fill bytes, which are bytes assigned code X'FF'".
-			marker, err = d.r.ReadByte()
-			if err != nil {
-				return nil, err
-			}
-		}
-		if marker == eoiMarker { // End Of Image.
-			break
-		}
-		if rst0Marker <= marker && marker <= rst7Marker {
-			// Figures B.2 and B.16 of the specification suggest that restart markers should
-			// only occur between Entropy Coded Segments and not after the final ECS.
-			// However, some encoders may generate incorrect JPEGs with a final restart
-			// marker. That restart marker will be seen here instead of inside the processSOS
-			// method, and is ignored as a harmless error. Restart markers have no extra data,
-			// so we check for this before we read the 16-bit length of the segment.
-			continue
-		}
-
-		// Read the 16-bit length of the segment. The value includes the 2 bytes for the
-		// length itself, so we subtract 2 to get the number of remaining bytes.
-		_, err = io.ReadFull(d.r, d.tmp[0:2])
-		if err != nil {
-			return nil, err
-		}
-		n := int(d.tmp[0])<<8 + int(d.tmp[1]) - 2
-		if n < 0 {
-			return nil, FormatError("short segment length")
-		}
-
-		switch {
-		case marker == sof0Marker || marker == sof2Marker: // Start Of Frame.
-			d.progressive = marker == sof2Marker
-			err = d.processSOF(n)
-			if configOnly {
-				return nil, err
-			}
-		case marker == dhtMarker: // Define Huffman Table.
-			err = d.processDHT(n)
-		case marker == dqtMarker: // Define Quantization Table.
-			err = d.processDQT(n)
-		case marker == sosMarker: // Start Of Scan.
-			err = d.processSOS(n)
-		case marker == driMarker: // Define Restart Interval.
-			err = d.processDRI(n)
-		case app0Marker <= marker && marker <= app15Marker || marker == comMarker: // APPlication specific, or COMment.
-			err = d.ignore(n)
-		default:
-			err = UnsupportedError("unknown marker")
-		}
-		if err != nil {
-			return nil, err
-		}
-	}
-	if d.img1 != nil {
-		return d.img1, nil
-	}
-	if d.img3 != nil {
-		return d.img3, nil
-	}
-	return nil, FormatError("missing SOS marker")
-}
-
-// Decode reads a JPEG image from r and returns it as an image.Image.
-func Decode(r io.Reader) (image.Image, error) {
-	var d decoder
-	return d.decode(r, false)
-}
-
-// DecodeConfig returns the color model and dimensions of a JPEG image without
-// decoding the entire image.
-func DecodeConfig(r io.Reader) (image.Config, error) {
-	var d decoder
-	if _, err := d.decode(r, true); err != nil {
-		return image.Config{}, err
-	}
-	switch d.nComp {
-	case nGrayComponent:
-		return image.Config{
-			ColorModel: color.GrayModel,
-			Width:      d.width,
-			Height:     d.height,
-		}, nil
-	case nColorComponent:
-		return image.Config{
-			ColorModel: color.YCbCrModel,
-			Width:      d.width,
-			Height:     d.height,
-		}, nil
-	}
-	return image.Config{}, FormatError("missing SOF marker")
-}
-
-func init() {
-	image.RegisterFormat("jpeg", "\xff\xd8", Decode, DecodeConfig)
-}
diff --git a/src/pkg/image/jpeg/reader_test.go b/src/pkg/image/jpeg/reader_test.go
deleted file mode 100644
index 926bb04..0000000
--- a/src/pkg/image/jpeg/reader_test.go
+++ /dev/null
@@ -1,225 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package jpeg
-
-import (
-	"bytes"
-	"fmt"
-	"image"
-	"image/color"
-	"io/ioutil"
-	"math/rand"
-	"os"
-	"strings"
-	"testing"
-)
-
-// TestDecodeProgressive tests that decoding the baseline and progressive
-// versions of the same image result in exactly the same pixel data, in YCbCr
-// space for color images, and Y space for grayscale images.
-func TestDecodeProgressive(t *testing.T) {
-	testCases := []string{
-		"../testdata/video-001",
-		"../testdata/video-001.q50.420",
-		"../testdata/video-001.q50.422",
-		"../testdata/video-001.q50.440",
-		"../testdata/video-001.q50.444",
-		"../testdata/video-005.gray.q50",
-		"../testdata/video-005.gray.q50.2x2",
-		"../testdata/video-001.separate.dc.progression",
-	}
-	for _, tc := range testCases {
-		m0, err := decodeFile(tc + ".jpeg")
-		if err != nil {
-			t.Errorf("%s: %v", tc+".jpeg", err)
-			continue
-		}
-		m1, err := decodeFile(tc + ".progressive.jpeg")
-		if err != nil {
-			t.Errorf("%s: %v", tc+".progressive.jpeg", err)
-			continue
-		}
-		if m0.Bounds() != m1.Bounds() {
-			t.Errorf("%s: bounds differ: %v and %v", tc, m0.Bounds(), m1.Bounds())
-			continue
-		}
-		// All of the video-*.jpeg files are 150x103.
-		if m0.Bounds() != image.Rect(0, 0, 150, 103) {
-			t.Errorf("%s: bad bounds: %v", tc, m0.Bounds())
-			continue
-		}
-
-		switch m0 := m0.(type) {
-		case *image.YCbCr:
-			m1 := m1.(*image.YCbCr)
-			if err := check(m0.Bounds(), m0.Y, m1.Y, m0.YStride, m1.YStride); err != nil {
-				t.Errorf("%s (Y): %v", tc, err)
-				continue
-			}
-			if err := check(m0.Bounds(), m0.Cb, m1.Cb, m0.CStride, m1.CStride); err != nil {
-				t.Errorf("%s (Cb): %v", tc, err)
-				continue
-			}
-			if err := check(m0.Bounds(), m0.Cr, m1.Cr, m0.CStride, m1.CStride); err != nil {
-				t.Errorf("%s (Cr): %v", tc, err)
-				continue
-			}
-		case *image.Gray:
-			m1 := m1.(*image.Gray)
-			if err := check(m0.Bounds(), m0.Pix, m1.Pix, m0.Stride, m1.Stride); err != nil {
-				t.Errorf("%s: %v", tc, err)
-				continue
-			}
-		default:
-			t.Errorf("%s: unexpected image type %T", tc, m0)
-			continue
-		}
-	}
-}
-
-func decodeFile(filename string) (image.Image, error) {
-	f, err := os.Open(filename)
-	if err != nil {
-		return nil, err
-	}
-	defer f.Close()
-	return Decode(f)
-
-}
-
-// check checks that the two pix data are equal, within the given bounds.
-func check(bounds image.Rectangle, pix0, pix1 []byte, stride0, stride1 int) error {
-	if stride0 <= 0 || stride0%8 != 0 {
-		return fmt.Errorf("bad stride %d", stride0)
-	}
-	if stride1 <= 0 || stride1%8 != 0 {
-		return fmt.Errorf("bad stride %d", stride1)
-	}
-	// Compare the two pix data, one 8x8 block at a time.
-	for y := 0; y < len(pix0)/stride0 && y < len(pix1)/stride1; y += 8 {
-		for x := 0; x < stride0 && x < stride1; x += 8 {
-			if x >= bounds.Max.X || y >= bounds.Max.Y {
-				// We don't care if the two pix data differ if the 8x8 block is
-				// entirely outside of the image's bounds. For example, this can
-				// occur with a 4:2:0 chroma subsampling and a 1x1 image. Baseline
-				// decoding works on the one 16x16 MCU as a whole; progressive
-				// decoding's first pass works on that 16x16 MCU as a whole but
-				// refinement passes only process one 8x8 block within the MCU.
-				continue
-			}
-
-			for j := 0; j < 8; j++ {
-				for i := 0; i < 8; i++ {
-					index0 := (y+j)*stride0 + (x + i)
-					index1 := (y+j)*stride1 + (x + i)
-					if pix0[index0] != pix1[index1] {
-						return fmt.Errorf("blocks at (%d, %d) differ:\n%sand\n%s", x, y,
-							pixString(pix0, stride0, x, y),
-							pixString(pix1, stride1, x, y),
-						)
-					}
-				}
-			}
-		}
-	}
-	return nil
-}
-
-func pixString(pix []byte, stride, x, y int) string {
-	s := bytes.NewBuffer(nil)
-	for j := 0; j < 8; j++ {
-		fmt.Fprintf(s, "\t")
-		for i := 0; i < 8; i++ {
-			fmt.Fprintf(s, "%02x ", pix[(y+j)*stride+(x+i)])
-		}
-		fmt.Fprintf(s, "\n")
-	}
-	return s.String()
-}
-
-func TestExtraneousData(t *testing.T) {
-	// Encode a 1x1 red image.
-	src := image.NewRGBA(image.Rect(0, 0, 1, 1))
-	src.Set(0, 0, color.RGBA{0xff, 0x00, 0x00, 0xff})
-	buf := new(bytes.Buffer)
-	if err := Encode(buf, src, nil); err != nil {
-		t.Fatalf("encode: %v", err)
-	}
-	enc := buf.String()
-	// Sanity check that the encoded JPEG is long enough, that it ends in a
-	// "\xff\xd9" EOI marker, and that it contains a "\xff\xda" SOS marker
-	// somewhere in the final 64 bytes.
-	if len(enc) < 64 {
-		t.Fatalf("encoded JPEG is too short: %d bytes", len(enc))
-	}
-	if got, want := enc[len(enc)-2:], "\xff\xd9"; got != want {
-		t.Fatalf("encoded JPEG ends with %q, want %q", got, want)
-	}
-	if s := enc[len(enc)-64:]; !strings.Contains(s, "\xff\xda") {
-		t.Fatalf("encoded JPEG does not contain a SOS marker (ff da) near the end: % x", s)
-	}
-	// Test that adding some random junk between the SOS marker and the
-	// EOI marker does not affect the decoding.
-	rnd := rand.New(rand.NewSource(1))
-	for i, nerr := 0, 0; i < 1000 && nerr < 10; i++ {
-		buf.Reset()
-		// Write all but the trailing "\xff\xd9" EOI marker.
-		buf.WriteString(enc[:len(enc)-2])
-		// Write some random extraneous data.
-		for n := rnd.Intn(10); n > 0; n-- {
-			if x := byte(rnd.Intn(256)); x != 0xff {
-				buf.WriteByte(x)
-			} else {
-				// The JPEG format escapes a SOS 0xff data byte as "\xff\x00".
-				buf.WriteString("\xff\x00")
-			}
-		}
-		// Write the "\xff\xd9" EOI marker.
-		buf.WriteString("\xff\xd9")
-
-		// Check that we can still decode the resultant image.
-		got, err := Decode(buf)
-		if err != nil {
-			t.Errorf("could not decode image #%d: %v", i, err)
-			nerr++
-			continue
-		}
-		if got.Bounds() != src.Bounds() {
-			t.Errorf("image #%d, bounds differ: %v and %v", i, got.Bounds(), src.Bounds())
-			nerr++
-			continue
-		}
-		if averageDelta(got, src) > 2<<8 {
-			t.Errorf("image #%d changed too much after a round trip", i)
-			nerr++
-			continue
-		}
-	}
-}
-
-func benchmarkDecode(b *testing.B, filename string) {
-	b.StopTimer()
-	data, err := ioutil.ReadFile(filename)
-	if err != nil {
-		b.Fatal(err)
-	}
-	cfg, err := DecodeConfig(bytes.NewReader(data))
-	if err != nil {
-		b.Fatal(err)
-	}
-	b.SetBytes(int64(cfg.Width * cfg.Height * 4))
-	b.StartTimer()
-	for i := 0; i < b.N; i++ {
-		Decode(bytes.NewReader(data))
-	}
-}
-
-func BenchmarkDecodeBaseline(b *testing.B) {
-	benchmarkDecode(b, "../testdata/video-001.jpeg")
-}
-
-func BenchmarkDecodeProgressive(b *testing.B) {
-	benchmarkDecode(b, "../testdata/video-001.progressive.jpeg")
-}
diff --git a/src/pkg/image/jpeg/scan.go b/src/pkg/image/jpeg/scan.go
deleted file mode 100644
index 559235d..0000000
--- a/src/pkg/image/jpeg/scan.go
+++ /dev/null
@@ -1,439 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package jpeg
-
-import (
-	"image"
-	"io"
-)
-
-// makeImg allocates and initializes the destination image.
-func (d *decoder) makeImg(h0, v0, mxx, myy int) {
-	if d.nComp == nGrayComponent {
-		m := image.NewGray(image.Rect(0, 0, 8*mxx, 8*myy))
-		d.img1 = m.SubImage(image.Rect(0, 0, d.width, d.height)).(*image.Gray)
-		return
-	}
-	var subsampleRatio image.YCbCrSubsampleRatio
-	switch {
-	case h0 == 1 && v0 == 1:
-		subsampleRatio = image.YCbCrSubsampleRatio444
-	case h0 == 1 && v0 == 2:
-		subsampleRatio = image.YCbCrSubsampleRatio440
-	case h0 == 2 && v0 == 1:
-		subsampleRatio = image.YCbCrSubsampleRatio422
-	case h0 == 2 && v0 == 2:
-		subsampleRatio = image.YCbCrSubsampleRatio420
-	default:
-		panic("unreachable")
-	}
-	m := image.NewYCbCr(image.Rect(0, 0, 8*h0*mxx, 8*v0*myy), subsampleRatio)
-	d.img3 = m.SubImage(image.Rect(0, 0, d.width, d.height)).(*image.YCbCr)
-}
-
-// Specified in section B.2.3.
-func (d *decoder) processSOS(n int) error {
-	if d.nComp == 0 {
-		return FormatError("missing SOF marker")
-	}
-	if n < 6 || 4+2*d.nComp < n || n%2 != 0 {
-		return FormatError("SOS has wrong length")
-	}
-	_, err := io.ReadFull(d.r, d.tmp[:n])
-	if err != nil {
-		return err
-	}
-	nComp := int(d.tmp[0])
-	if n != 4+2*nComp {
-		return FormatError("SOS length inconsistent with number of components")
-	}
-	var scan [nColorComponent]struct {
-		compIndex uint8
-		td        uint8 // DC table selector.
-		ta        uint8 // AC table selector.
-	}
-	for i := 0; i < nComp; i++ {
-		cs := d.tmp[1+2*i] // Component selector.
-		compIndex := -1
-		for j, comp := range d.comp {
-			if cs == comp.c {
-				compIndex = j
-			}
-		}
-		if compIndex < 0 {
-			return FormatError("unknown component selector")
-		}
-		scan[i].compIndex = uint8(compIndex)
-		scan[i].td = d.tmp[2+2*i] >> 4
-		scan[i].ta = d.tmp[2+2*i] & 0x0f
-	}
-
-	// zigStart and zigEnd are the spectral selection bounds.
-	// ah and al are the successive approximation high and low values.
-	// The spec calls these values Ss, Se, Ah and Al.
-	//
-	// For progressive JPEGs, these are the two more-or-less independent
-	// aspects of progression. Spectral selection progression is when not
-	// all of a block's 64 DCT coefficients are transmitted in one pass.
-	// For example, three passes could transmit coefficient 0 (the DC
-	// component), coefficients 1-5, and coefficients 6-63, in zig-zag
-	// order. Successive approximation is when not all of the bits of a
-	// band of coefficients are transmitted in one pass. For example,
-	// three passes could transmit the 6 most significant bits, followed
-	// by the second-least significant bit, followed by the least
-	// significant bit.
-	//
-	// For baseline JPEGs, these parameters are hard-coded to 0/63/0/0.
-	zigStart, zigEnd, ah, al := int32(0), int32(blockSize-1), uint32(0), uint32(0)
-	if d.progressive {
-		zigStart = int32(d.tmp[1+2*nComp])
-		zigEnd = int32(d.tmp[2+2*nComp])
-		ah = uint32(d.tmp[3+2*nComp] >> 4)
-		al = uint32(d.tmp[3+2*nComp] & 0x0f)
-		if (zigStart == 0 && zigEnd != 0) || zigStart > zigEnd || blockSize <= zigEnd {
-			return FormatError("bad spectral selection bounds")
-		}
-		if zigStart != 0 && nComp != 1 {
-			return FormatError("progressive AC coefficients for more than one component")
-		}
-		if ah != 0 && ah != al+1 {
-			return FormatError("bad successive approximation values")
-		}
-	}
-
-	// mxx and myy are the number of MCUs (Minimum Coded Units) in the image.
-	h0, v0 := d.comp[0].h, d.comp[0].v // The h and v values from the Y components.
-	mxx := (d.width + 8*h0 - 1) / (8 * h0)
-	myy := (d.height + 8*v0 - 1) / (8 * v0)
-	if d.img1 == nil && d.img3 == nil {
-		d.makeImg(h0, v0, mxx, myy)
-	}
-	if d.progressive {
-		for i := 0; i < nComp; i++ {
-			compIndex := scan[i].compIndex
-			if d.progCoeffs[compIndex] == nil {
-				d.progCoeffs[compIndex] = make([]block, mxx*myy*d.comp[compIndex].h*d.comp[compIndex].v)
-			}
-		}
-	}
-
-	d.b = bits{}
-	mcu, expectedRST := 0, uint8(rst0Marker)
-	var (
-		// b is the decoded coefficients, in natural (not zig-zag) order.
-		b  block
-		dc [nColorComponent]int32
-		// mx0 and my0 are the location of the current (in terms of 8x8 blocks).
-		// For example, with 4:2:0 chroma subsampling, the block whose top left
-		// pixel co-ordinates are (16, 8) is the third block in the first row:
-		// mx0 is 2 and my0 is 0, even though the pixel is in the second MCU.
-		// TODO(nigeltao): rename mx0 and my0 to bx and by?
-		mx0, my0   int
-		blockCount int
-	)
-	for my := 0; my < myy; my++ {
-		for mx := 0; mx < mxx; mx++ {
-			for i := 0; i < nComp; i++ {
-				compIndex := scan[i].compIndex
-				qt := &d.quant[d.comp[compIndex].tq]
-				for j := 0; j < d.comp[compIndex].h*d.comp[compIndex].v; j++ {
-					// The blocks are traversed one MCU at a time. For 4:2:0 chroma
-					// subsampling, there are four Y 8x8 blocks in every 16x16 MCU.
-					//
-					// For a baseline 32x16 pixel image, the Y blocks visiting order is:
-					//	0 1 4 5
-					//	2 3 6 7
-					//
-					// For progressive images, the interleaved scans (those with nComp > 1)
-					// are traversed as above, but non-interleaved scans are traversed left
-					// to right, top to bottom:
-					//	0 1 2 3
-					//	4 5 6 7
-					// Only DC scans (zigStart == 0) can be interleaved. AC scans must have
-					// only one component.
-					//
-					// To further complicate matters, for non-interleaved scans, there is no
-					// data for any blocks that are inside the image at the MCU level but
-					// outside the image at the pixel level. For example, a 24x16 pixel 4:2:0
-					// progressive image consists of two 16x16 MCUs. The interleaved scans
-					// will process 8 Y blocks:
-					//	0 1 4 5
-					//	2 3 6 7
-					// The non-interleaved scans will process only 6 Y blocks:
-					//	0 1 2
-					//	3 4 5
-					if nComp != 1 {
-						mx0, my0 = d.comp[compIndex].h*mx, d.comp[compIndex].v*my
-						if h0 == 1 {
-							my0 += j
-						} else {
-							mx0 += j % 2
-							my0 += j / 2
-						}
-					} else {
-						q := mxx * d.comp[compIndex].h
-						mx0 = blockCount % q
-						my0 = blockCount / q
-						blockCount++
-						if mx0*8 >= d.width || my0*8 >= d.height {
-							continue
-						}
-					}
-
-					// Load the previous partially decoded coefficients, if applicable.
-					if d.progressive {
-						b = d.progCoeffs[compIndex][my0*mxx*d.comp[compIndex].h+mx0]
-					} else {
-						b = block{}
-					}
-
-					if ah != 0 {
-						if err := d.refine(&b, &d.huff[acTable][scan[i].ta], zigStart, zigEnd, 1<<al); err != nil {
-							return err
-						}
-					} else {
-						zig := zigStart
-						if zig == 0 {
-							zig++
-							// Decode the DC coefficient, as specified in section F.2.2.1.
-							value, err := d.decodeHuffman(&d.huff[dcTable][scan[i].td])
-							if err != nil {
-								return err
-							}
-							if value > 16 {
-								return UnsupportedError("excessive DC component")
-							}
-							dcDelta, err := d.receiveExtend(value)
-							if err != nil {
-								return err
-							}
-							dc[compIndex] += dcDelta
-							b[0] = dc[compIndex] << al
-						}
-
-						if zig <= zigEnd && d.eobRun > 0 {
-							d.eobRun--
-						} else {
-							// Decode the AC coefficients, as specified in section F.2.2.2.
-							for ; zig <= zigEnd; zig++ {
-								value, err := d.decodeHuffman(&d.huff[acTable][scan[i].ta])
-								if err != nil {
-									return err
-								}
-								val0 := value >> 4
-								val1 := value & 0x0f
-								if val1 != 0 {
-									zig += int32(val0)
-									if zig > zigEnd {
-										break
-									}
-									ac, err := d.receiveExtend(val1)
-									if err != nil {
-										return err
-									}
-									b[unzig[zig]] = ac << al
-								} else {
-									if val0 != 0x0f {
-										d.eobRun = uint16(1 << val0)
-										if val0 != 0 {
-											bits, err := d.decodeBits(int(val0))
-											if err != nil {
-												return err
-											}
-											d.eobRun |= uint16(bits)
-										}
-										d.eobRun--
-										break
-									}
-									zig += 0x0f
-								}
-							}
-						}
-					}
-
-					if d.progressive {
-						if zigEnd != blockSize-1 || al != 0 {
-							// We haven't completely decoded this 8x8 block. Save the coefficients.
-							d.progCoeffs[compIndex][my0*mxx*d.comp[compIndex].h+mx0] = b
-							// At this point, we could execute the rest of the loop body to dequantize and
-							// perform the inverse DCT, to save early stages of a progressive image to the
-							// *image.YCbCr buffers (the whole point of progressive encoding), but in Go,
-							// the jpeg.Decode function does not return until the entire image is decoded,
-							// so we "continue" here to avoid wasted computation.
-							continue
-						}
-					}
-
-					// Dequantize, perform the inverse DCT and store the block to the image.
-					for zig := 0; zig < blockSize; zig++ {
-						b[unzig[zig]] *= qt[zig]
-					}
-					idct(&b)
-					dst, stride := []byte(nil), 0
-					if d.nComp == nGrayComponent {
-						dst, stride = d.img1.Pix[8*(my0*d.img1.Stride+mx0):], d.img1.Stride
-					} else {
-						switch compIndex {
-						case 0:
-							dst, stride = d.img3.Y[8*(my0*d.img3.YStride+mx0):], d.img3.YStride
-						case 1:
-							dst, stride = d.img3.Cb[8*(my0*d.img3.CStride+mx0):], d.img3.CStride
-						case 2:
-							dst, stride = d.img3.Cr[8*(my0*d.img3.CStride+mx0):], d.img3.CStride
-						default:
-							return UnsupportedError("too many components")
-						}
-					}
-					// Level shift by +128, clip to [0, 255], and write to dst.
-					for y := 0; y < 8; y++ {
-						y8 := y * 8
-						yStride := y * stride
-						for x := 0; x < 8; x++ {
-							c := b[y8+x]
-							if c < -128 {
-								c = 0
-							} else if c > 127 {
-								c = 255
-							} else {
-								c += 128
-							}
-							dst[yStride+x] = uint8(c)
-						}
-					}
-				} // for j
-			} // for i
-			mcu++
-			if d.ri > 0 && mcu%d.ri == 0 && mcu < mxx*myy {
-				// A more sophisticated decoder could use RST[0-7] markers to resynchronize from corrupt input,
-				// but this one assumes well-formed input, and hence the restart marker follows immediately.
-				_, err := io.ReadFull(d.r, d.tmp[0:2])
-				if err != nil {
-					return err
-				}
-				if d.tmp[0] != 0xff || d.tmp[1] != expectedRST {
-					return FormatError("bad RST marker")
-				}
-				expectedRST++
-				if expectedRST == rst7Marker+1 {
-					expectedRST = rst0Marker
-				}
-				// Reset the Huffman decoder.
-				d.b = bits{}
-				// Reset the DC components, as per section F.2.1.3.1.
-				dc = [nColorComponent]int32{}
-				// Reset the progressive decoder state, as per section G.1.2.2.
-				d.eobRun = 0
-			}
-		} // for mx
-	} // for my
-
-	return nil
-}
-
-// refine decodes a successive approximation refinement block, as specified in
-// section G.1.2.
-func (d *decoder) refine(b *block, h *huffman, zigStart, zigEnd, delta int32) error {
-	// Refining a DC component is trivial.
-	if zigStart == 0 {
-		if zigEnd != 0 {
-			panic("unreachable")
-		}
-		bit, err := d.decodeBit()
-		if err != nil {
-			return err
-		}
-		if bit {
-			b[0] |= delta
-		}
-		return nil
-	}
-
-	// Refining AC components is more complicated; see sections G.1.2.2 and G.1.2.3.
-	zig := zigStart
-	if d.eobRun == 0 {
-	loop:
-		for ; zig <= zigEnd; zig++ {
-			z := int32(0)
-			value, err := d.decodeHuffman(h)
-			if err != nil {
-				return err
-			}
-			val0 := value >> 4
-			val1 := value & 0x0f
-
-			switch val1 {
-			case 0:
-				if val0 != 0x0f {
-					d.eobRun = uint16(1 << val0)
-					if val0 != 0 {
-						bits, err := d.decodeBits(int(val0))
-						if err != nil {
-							return err
-						}
-						d.eobRun |= uint16(bits)
-					}
-					break loop
-				}
-			case 1:
-				z = delta
-				bit, err := d.decodeBit()
-				if err != nil {
-					return err
-				}
-				if !bit {
-					z = -z
-				}
-			default:
-				return FormatError("unexpected Huffman code")
-			}
-
-			zig, err = d.refineNonZeroes(b, zig, zigEnd, int32(val0), delta)
-			if err != nil {
-				return err
-			}
-			if zig > zigEnd {
-				return FormatError("too many coefficients")
-			}
-			if z != 0 {
-				b[unzig[zig]] = z
-			}
-		}
-	}
-	if d.eobRun > 0 {
-		d.eobRun--
-		if _, err := d.refineNonZeroes(b, zig, zigEnd, -1, delta); err != nil {
-			return err
-		}
-	}
-	return nil
-}
-
-// refineNonZeroes refines non-zero entries of b in zig-zag order. If nz >= 0,
-// the first nz zero entries are skipped over.
-func (d *decoder) refineNonZeroes(b *block, zig, zigEnd, nz, delta int32) (int32, error) {
-	for ; zig <= zigEnd; zig++ {
-		u := unzig[zig]
-		if b[u] == 0 {
-			if nz == 0 {
-				break
-			}
-			nz--
-			continue
-		}
-		bit, err := d.decodeBit()
-		if err != nil {
-			return 0, err
-		}
-		if !bit {
-			continue
-		}
-		if b[u] >= 0 {
-			b[u] += delta
-		} else {
-			b[u] -= delta
-		}
-	}
-	return zig, nil
-}
diff --git a/src/pkg/image/jpeg/writer.go b/src/pkg/image/jpeg/writer.go
deleted file mode 100644
index c58fbf3..0000000
--- a/src/pkg/image/jpeg/writer.go
+++ /dev/null
@@ -1,553 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package jpeg
-
-import (
-	"bufio"
-	"errors"
-	"image"
-	"image/color"
-	"io"
-)
-
-// min returns the minimum of two integers.
-func min(x, y int) int {
-	if x < y {
-		return x
-	}
-	return y
-}
-
-// div returns a/b rounded to the nearest integer, instead of rounded to zero.
-func div(a, b int32) int32 {
-	if a >= 0 {
-		return (a + (b >> 1)) / b
-	}
-	return -((-a + (b >> 1)) / b)
-}
-
-// bitCount counts the number of bits needed to hold an integer.
-var bitCount = [256]byte{
-	0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
-	5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
-	6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
-	6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
-	7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-	7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-	7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-	7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
-	8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
-	8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
-	8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
-	8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
-	8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
-	8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
-	8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
-	8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
-}
-
-type quantIndex int
-
-const (
-	quantIndexLuminance quantIndex = iota
-	quantIndexChrominance
-	nQuantIndex
-)
-
-// unscaledQuant are the unscaled quantization tables in zig-zag order. Each
-// encoder copies and scales the tables according to its quality parameter.
-// The values are derived from section K.1 after converting from natural to
-// zig-zag order.
-var unscaledQuant = [nQuantIndex][blockSize]byte{
-	// Luminance.
-	{
-		16, 11, 12, 14, 12, 10, 16, 14,
-		13, 14, 18, 17, 16, 19, 24, 40,
-		26, 24, 22, 22, 24, 49, 35, 37,
-		29, 40, 58, 51, 61, 60, 57, 51,
-		56, 55, 64, 72, 92, 78, 64, 68,
-		87, 69, 55, 56, 80, 109, 81, 87,
-		95, 98, 103, 104, 103, 62, 77, 113,
-		121, 112, 100, 120, 92, 101, 103, 99,
-	},
-	// Chrominance.
-	{
-		17, 18, 18, 24, 21, 24, 47, 26,
-		26, 47, 99, 66, 56, 66, 99, 99,
-		99, 99, 99, 99, 99, 99, 99, 99,
-		99, 99, 99, 99, 99, 99, 99, 99,
-		99, 99, 99, 99, 99, 99, 99, 99,
-		99, 99, 99, 99, 99, 99, 99, 99,
-		99, 99, 99, 99, 99, 99, 99, 99,
-		99, 99, 99, 99, 99, 99, 99, 99,
-	},
-}
-
-type huffIndex int
-
-const (
-	huffIndexLuminanceDC huffIndex = iota
-	huffIndexLuminanceAC
-	huffIndexChrominanceDC
-	huffIndexChrominanceAC
-	nHuffIndex
-)
-
-// huffmanSpec specifies a Huffman encoding.
-type huffmanSpec struct {
-	// count[i] is the number of codes of length i bits.
-	count [16]byte
-	// value[i] is the decoded value of the i'th codeword.
-	value []byte
-}
-
-// theHuffmanSpec is the Huffman encoding specifications.
-// This encoder uses the same Huffman encoding for all images.
-var theHuffmanSpec = [nHuffIndex]huffmanSpec{
-	// Luminance DC.
-	{
-		[16]byte{0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0},
-		[]byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11},
-	},
-	// Luminance AC.
-	{
-		[16]byte{0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 125},
-		[]byte{
-			0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
-			0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
-			0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
-			0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
-			0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
-			0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
-			0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
-			0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
-			0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
-			0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
-			0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
-			0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
-			0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
-			0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
-			0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
-			0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
-			0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
-			0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
-			0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
-			0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
-			0xf9, 0xfa,
-		},
-	},
-	// Chrominance DC.
-	{
-		[16]byte{0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0},
-		[]byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11},
-	},
-	// Chrominance AC.
-	{
-		[16]byte{0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 119},
-		[]byte{
-			0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
-			0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
-			0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
-			0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
-			0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,
-			0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
-			0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
-			0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
-			0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
-			0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
-			0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
-			0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
-			0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
-			0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
-			0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
-			0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
-			0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
-			0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
-			0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
-			0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
-			0xf9, 0xfa,
-		},
-	},
-}
-
-// huffmanLUT is a compiled look-up table representation of a huffmanSpec.
-// Each value maps to a uint32 of which the 8 most significant bits hold the
-// codeword size in bits and the 24 least significant bits hold the codeword.
-// The maximum codeword size is 16 bits.
-type huffmanLUT []uint32
-
-func (h *huffmanLUT) init(s huffmanSpec) {
-	maxValue := 0
-	for _, v := range s.value {
-		if int(v) > maxValue {
-			maxValue = int(v)
-		}
-	}
-	*h = make([]uint32, maxValue+1)
-	code, k := uint32(0), 0
-	for i := 0; i < len(s.count); i++ {
-		nBits := uint32(i+1) << 24
-		for j := uint8(0); j < s.count[i]; j++ {
-			(*h)[s.value[k]] = nBits | code
-			code++
-			k++
-		}
-		code <<= 1
-	}
-}
-
-// theHuffmanLUT are compiled representations of theHuffmanSpec.
-var theHuffmanLUT [4]huffmanLUT
-
-func init() {
-	for i, s := range theHuffmanSpec {
-		theHuffmanLUT[i].init(s)
-	}
-}
-
-// writer is a buffered writer.
-type writer interface {
-	Flush() error
-	io.Writer
-	io.ByteWriter
-}
-
-// encoder encodes an image to the JPEG format.
-type encoder struct {
-	// w is the writer to write to. err is the first error encountered during
-	// writing. All attempted writes after the first error become no-ops.
-	w   writer
-	err error
-	// buf is a scratch buffer.
-	buf [16]byte
-	// bits and nBits are accumulated bits to write to w.
-	bits, nBits uint32
-	// quant is the scaled quantization tables, in zig-zag order.
-	quant [nQuantIndex][blockSize]byte
-}
-
-func (e *encoder) flush() {
-	if e.err != nil {
-		return
-	}
-	e.err = e.w.Flush()
-}
-
-func (e *encoder) write(p []byte) {
-	if e.err != nil {
-		return
-	}
-	_, e.err = e.w.Write(p)
-}
-
-func (e *encoder) writeByte(b byte) {
-	if e.err != nil {
-		return
-	}
-	e.err = e.w.WriteByte(b)
-}
-
-// emit emits the least significant nBits bits of bits to the bitstream.
-// The precondition is bits < 1<<nBits && nBits <= 16.
-func (e *encoder) emit(bits, nBits uint32) {
-	nBits += e.nBits
-	bits <<= 32 - nBits
-	bits |= e.bits
-	for nBits >= 8 {
-		b := uint8(bits >> 24)
-		e.writeByte(b)
-		if b == 0xff {
-			e.writeByte(0x00)
-		}
-		bits <<= 8
-		nBits -= 8
-	}
-	e.bits, e.nBits = bits, nBits
-}
-
-// emitHuff emits the given value with the given Huffman encoder.
-func (e *encoder) emitHuff(h huffIndex, value int32) {
-	x := theHuffmanLUT[h][value]
-	e.emit(x&(1<<24-1), x>>24)
-}
-
-// emitHuffRLE emits a run of runLength copies of value encoded with the given
-// Huffman encoder.
-func (e *encoder) emitHuffRLE(h huffIndex, runLength, value int32) {
-	a, b := value, value
-	if a < 0 {
-		a, b = -value, value-1
-	}
-	var nBits uint32
-	if a < 0x100 {
-		nBits = uint32(bitCount[a])
-	} else {
-		nBits = 8 + uint32(bitCount[a>>8])
-	}
-	e.emitHuff(h, runLength<<4|int32(nBits))
-	if nBits > 0 {
-		e.emit(uint32(b)&(1<<nBits-1), nBits)
-	}
-}
-
-// writeMarkerHeader writes the header for a marker with the given length.
-func (e *encoder) writeMarkerHeader(marker uint8, markerlen int) {
-	e.buf[0] = 0xff
-	e.buf[1] = marker
-	e.buf[2] = uint8(markerlen >> 8)
-	e.buf[3] = uint8(markerlen & 0xff)
-	e.write(e.buf[:4])
-}
-
-// writeDQT writes the Define Quantization Table marker.
-func (e *encoder) writeDQT() {
-	const markerlen = 2 + int(nQuantIndex)*(1+blockSize)
-	e.writeMarkerHeader(dqtMarker, markerlen)
-	for i := range e.quant {
-		e.writeByte(uint8(i))
-		e.write(e.quant[i][:])
-	}
-}
-
-// writeSOF0 writes the Start Of Frame (Baseline) marker.
-func (e *encoder) writeSOF0(size image.Point) {
-	const markerlen = 8 + 3*nColorComponent
-	e.writeMarkerHeader(sof0Marker, markerlen)
-	e.buf[0] = 8 // 8-bit color.
-	e.buf[1] = uint8(size.Y >> 8)
-	e.buf[2] = uint8(size.Y & 0xff)
-	e.buf[3] = uint8(size.X >> 8)
-	e.buf[4] = uint8(size.X & 0xff)
-	e.buf[5] = nColorComponent
-	for i := 0; i < nColorComponent; i++ {
-		e.buf[3*i+6] = uint8(i + 1)
-		// We use 4:2:0 chroma subsampling.
-		e.buf[3*i+7] = "\x22\x11\x11"[i]
-		e.buf[3*i+8] = "\x00\x01\x01"[i]
-	}
-	e.write(e.buf[:3*(nColorComponent-1)+9])
-}
-
-// writeDHT writes the Define Huffman Table marker.
-func (e *encoder) writeDHT() {
-	markerlen := 2
-	for _, s := range theHuffmanSpec {
-		markerlen += 1 + 16 + len(s.value)
-	}
-	e.writeMarkerHeader(dhtMarker, markerlen)
-	for i, s := range theHuffmanSpec {
-		e.writeByte("\x00\x10\x01\x11"[i])
-		e.write(s.count[:])
-		e.write(s.value)
-	}
-}
-
-// writeBlock writes a block of pixel data using the given quantization table,
-// returning the post-quantized DC value of the DCT-transformed block.
-// b is in natural (not zig-zag) order.
-func (e *encoder) writeBlock(b *block, q quantIndex, prevDC int32) int32 {
-	fdct(b)
-	// Emit the DC delta.
-	dc := div(b[0], 8*int32(e.quant[q][0]))
-	e.emitHuffRLE(huffIndex(2*q+0), 0, dc-prevDC)
-	// Emit the AC components.
-	h, runLength := huffIndex(2*q+1), int32(0)
-	for zig := 1; zig < blockSize; zig++ {
-		ac := div(b[unzig[zig]], 8*int32(e.quant[q][zig]))
-		if ac == 0 {
-			runLength++
-		} else {
-			for runLength > 15 {
-				e.emitHuff(h, 0xf0)
-				runLength -= 16
-			}
-			e.emitHuffRLE(h, runLength, ac)
-			runLength = 0
-		}
-	}
-	if runLength > 0 {
-		e.emitHuff(h, 0x00)
-	}
-	return dc
-}
-
-// toYCbCr converts the 8x8 region of m whose top-left corner is p to its
-// YCbCr values.
-func toYCbCr(m image.Image, p image.Point, yBlock, cbBlock, crBlock *block) {
-	b := m.Bounds()
-	xmax := b.Max.X - 1
-	ymax := b.Max.Y - 1
-	for j := 0; j < 8; j++ {
-		for i := 0; i < 8; i++ {
-			r, g, b, _ := m.At(min(p.X+i, xmax), min(p.Y+j, ymax)).RGBA()
-			yy, cb, cr := color.RGBToYCbCr(uint8(r>>8), uint8(g>>8), uint8(b>>8))
-			yBlock[8*j+i] = int32(yy)
-			cbBlock[8*j+i] = int32(cb)
-			crBlock[8*j+i] = int32(cr)
-		}
-	}
-}
-
-// rgbaToYCbCr is a specialized version of toYCbCr for image.RGBA images.
-func rgbaToYCbCr(m *image.RGBA, p image.Point, yBlock, cbBlock, crBlock *block) {
-	b := m.Bounds()
-	xmax := b.Max.X - 1
-	ymax := b.Max.Y - 1
-	for j := 0; j < 8; j++ {
-		sj := p.Y + j
-		if sj > ymax {
-			sj = ymax
-		}
-		offset := (sj-b.Min.Y)*m.Stride - b.Min.X*4
-		for i := 0; i < 8; i++ {
-			sx := p.X + i
-			if sx > xmax {
-				sx = xmax
-			}
-			pix := m.Pix[offset+sx*4:]
-			yy, cb, cr := color.RGBToYCbCr(pix[0], pix[1], pix[2])
-			yBlock[8*j+i] = int32(yy)
-			cbBlock[8*j+i] = int32(cb)
-			crBlock[8*j+i] = int32(cr)
-		}
-	}
-}
-
-// scale scales the 16x16 region represented by the 4 src blocks to the 8x8
-// dst block.
-func scale(dst *block, src *[4]block) {
-	for i := 0; i < 4; i++ {
-		dstOff := (i&2)<<4 | (i&1)<<2
-		for y := 0; y < 4; y++ {
-			for x := 0; x < 4; x++ {
-				j := 16*y + 2*x
-				sum := src[i][j] + src[i][j+1] + src[i][j+8] + src[i][j+9]
-				dst[8*y+x+dstOff] = (sum + 2) >> 2
-			}
-		}
-	}
-}
-
-// sosHeader is the SOS marker "\xff\xda" followed by 12 bytes:
-//	- the marker length "\x00\x0c",
-//	- the number of components "\x03",
-//	- component 1 uses DC table 0 and AC table 0 "\x01\x00",
-//	- component 2 uses DC table 1 and AC table 1 "\x02\x11",
-//	- component 3 uses DC table 1 and AC table 1 "\x03\x11",
-//	- the bytes "\x00\x3f\x00". Section B.2.3 of the spec says that for
-//	  sequential DCTs, those bytes (8-bit Ss, 8-bit Se, 4-bit Ah, 4-bit Al)
-//	  should be 0x00, 0x3f, 0x00<<4 | 0x00.
-var sosHeader = []byte{
-	0xff, 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02,
-	0x11, 0x03, 0x11, 0x00, 0x3f, 0x00,
-}
-
-// writeSOS writes the StartOfScan marker.
-func (e *encoder) writeSOS(m image.Image) {
-	e.write(sosHeader)
-	var (
-		// Scratch buffers to hold the YCbCr values.
-		// The blocks are in natural (not zig-zag) order.
-		b      block
-		cb, cr [4]block
-		// DC components are delta-encoded.
-		prevDCY, prevDCCb, prevDCCr int32
-	)
-	bounds := m.Bounds()
-	rgba, _ := m.(*image.RGBA)
-	for y := bounds.Min.Y; y < bounds.Max.Y; y += 16 {
-		for x := bounds.Min.X; x < bounds.Max.X; x += 16 {
-			for i := 0; i < 4; i++ {
-				xOff := (i & 1) * 8
-				yOff := (i & 2) * 4
-				p := image.Pt(x+xOff, y+yOff)
-				if rgba != nil {
-					rgbaToYCbCr(rgba, p, &b, &cb[i], &cr[i])
-				} else {
-					toYCbCr(m, p, &b, &cb[i], &cr[i])
-				}
-				prevDCY = e.writeBlock(&b, 0, prevDCY)
-			}
-			scale(&b, &cb)
-			prevDCCb = e.writeBlock(&b, 1, prevDCCb)
-			scale(&b, &cr)
-			prevDCCr = e.writeBlock(&b, 1, prevDCCr)
-		}
-	}
-	// Pad the last byte with 1's.
-	e.emit(0x7f, 7)
-}
-
-// DefaultQuality is the default quality encoding parameter.
-const DefaultQuality = 75
-
-// Options are the encoding parameters.
-// Quality ranges from 1 to 100 inclusive, higher is better.
-type Options struct {
-	Quality int
-}
-
-// Encode writes the Image m to w in JPEG 4:2:0 baseline format with the given
-// options. Default parameters are used if a nil *Options is passed.
-func Encode(w io.Writer, m image.Image, o *Options) error {
-	b := m.Bounds()
-	if b.Dx() >= 1<<16 || b.Dy() >= 1<<16 {
-		return errors.New("jpeg: image is too large to encode")
-	}
-	var e encoder
-	if ww, ok := w.(writer); ok {
-		e.w = ww
-	} else {
-		e.w = bufio.NewWriter(w)
-	}
-	// Clip quality to [1, 100].
-	quality := DefaultQuality
-	if o != nil {
-		quality = o.Quality
-		if quality < 1 {
-			quality = 1
-		} else if quality > 100 {
-			quality = 100
-		}
-	}
-	// Convert from a quality rating to a scaling factor.
-	var scale int
-	if quality < 50 {
-		scale = 5000 / quality
-	} else {
-		scale = 200 - quality*2
-	}
-	// Initialize the quantization tables.
-	for i := range e.quant {
-		for j := range e.quant[i] {
-			x := int(unscaledQuant[i][j])
-			x = (x*scale + 50) / 100
-			if x < 1 {
-				x = 1
-			} else if x > 255 {
-				x = 255
-			}
-			e.quant[i][j] = uint8(x)
-		}
-	}
-	// Write the Start Of Image marker.
-	e.buf[0] = 0xff
-	e.buf[1] = 0xd8
-	e.write(e.buf[:2])
-	// Write the quantization tables.
-	e.writeDQT()
-	// Write the image dimensions.
-	e.writeSOF0(b.Size())
-	// Write the Huffman tables.
-	e.writeDHT()
-	// Write the image data.
-	e.writeSOS(m)
-	// Write the End Of Image marker.
-	e.buf[0] = 0xff
-	e.buf[1] = 0xd9
-	e.write(e.buf[:2])
-	e.flush()
-	return e.err
-}
diff --git a/src/pkg/image/jpeg/writer_test.go b/src/pkg/image/jpeg/writer_test.go
deleted file mode 100644
index 514b455..0000000
--- a/src/pkg/image/jpeg/writer_test.go
+++ /dev/null
@@ -1,204 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package jpeg
-
-import (
-	"bytes"
-	"fmt"
-	"image"
-	"image/color"
-	"image/png"
-	"io/ioutil"
-	"math/rand"
-	"os"
-	"testing"
-)
-
-// zigzag maps from the natural ordering to the zig-zag ordering. For example,
-// zigzag[0*8 + 3] is the zig-zag sequence number of the element in the fourth
-// column and first row.
-var zigzag = [blockSize]int{
-	0, 1, 5, 6, 14, 15, 27, 28,
-	2, 4, 7, 13, 16, 26, 29, 42,
-	3, 8, 12, 17, 25, 30, 41, 43,
-	9, 11, 18, 24, 31, 40, 44, 53,
-	10, 19, 23, 32, 39, 45, 52, 54,
-	20, 22, 33, 38, 46, 51, 55, 60,
-	21, 34, 37, 47, 50, 56, 59, 61,
-	35, 36, 48, 49, 57, 58, 62, 63,
-}
-
-func TestZigUnzig(t *testing.T) {
-	for i := 0; i < blockSize; i++ {
-		if unzig[zigzag[i]] != i {
-			t.Errorf("unzig[zigzag[%d]] == %d", i, unzig[zigzag[i]])
-		}
-		if zigzag[unzig[i]] != i {
-			t.Errorf("zigzag[unzig[%d]] == %d", i, zigzag[unzig[i]])
-		}
-	}
-}
-
-// unscaledQuantInNaturalOrder are the unscaled quantization tables in
-// natural (not zig-zag) order, as specified in section K.1.
-var unscaledQuantInNaturalOrder = [nQuantIndex][blockSize]byte{
-	// Luminance.
-	{
-		16, 11, 10, 16, 24, 40, 51, 61,
-		12, 12, 14, 19, 26, 58, 60, 55,
-		14, 13, 16, 24, 40, 57, 69, 56,
-		14, 17, 22, 29, 51, 87, 80, 62,
-		18, 22, 37, 56, 68, 109, 103, 77,
-		24, 35, 55, 64, 81, 104, 113, 92,
-		49, 64, 78, 87, 103, 121, 120, 101,
-		72, 92, 95, 98, 112, 100, 103, 99,
-	},
-	// Chrominance.
-	{
-		17, 18, 24, 47, 99, 99, 99, 99,
-		18, 21, 26, 66, 99, 99, 99, 99,
-		24, 26, 56, 99, 99, 99, 99, 99,
-		47, 66, 99, 99, 99, 99, 99, 99,
-		99, 99, 99, 99, 99, 99, 99, 99,
-		99, 99, 99, 99, 99, 99, 99, 99,
-		99, 99, 99, 99, 99, 99, 99, 99,
-		99, 99, 99, 99, 99, 99, 99, 99,
-	},
-}
-
-func TestUnscaledQuant(t *testing.T) {
-	bad := false
-	for i := quantIndex(0); i < nQuantIndex; i++ {
-		for zig := 0; zig < blockSize; zig++ {
-			got := unscaledQuant[i][zig]
-			want := unscaledQuantInNaturalOrder[i][unzig[zig]]
-			if got != want {
-				t.Errorf("i=%d, zig=%d: got %d, want %d", i, zig, got, want)
-				bad = true
-			}
-		}
-	}
-	if bad {
-		names := [nQuantIndex]string{"Luminance", "Chrominance"}
-		buf := &bytes.Buffer{}
-		for i, name := range names {
-			fmt.Fprintf(buf, "// %s.\n{\n", name)
-			for zig := 0; zig < blockSize; zig++ {
-				fmt.Fprintf(buf, "%d, ", unscaledQuantInNaturalOrder[i][unzig[zig]])
-				if zig%8 == 7 {
-					buf.WriteString("\n")
-				}
-			}
-			buf.WriteString("},\n")
-		}
-		t.Logf("expected unscaledQuant values:\n%s", buf.String())
-	}
-}
-
-var testCase = []struct {
-	filename  string
-	quality   int
-	tolerance int64
-}{
-	{"../testdata/video-001.png", 1, 24 << 8},
-	{"../testdata/video-001.png", 20, 12 << 8},
-	{"../testdata/video-001.png", 60, 8 << 8},
-	{"../testdata/video-001.png", 80, 6 << 8},
-	{"../testdata/video-001.png", 90, 4 << 8},
-	{"../testdata/video-001.png", 100, 2 << 8},
-}
-
-func delta(u0, u1 uint32) int64 {
-	d := int64(u0) - int64(u1)
-	if d < 0 {
-		return -d
-	}
-	return d
-}
-
-func readPng(filename string) (image.Image, error) {
-	f, err := os.Open(filename)
-	if err != nil {
-		return nil, err
-	}
-	defer f.Close()
-	return png.Decode(f)
-}
-
-func TestWriter(t *testing.T) {
-	for _, tc := range testCase {
-		// Read the image.
-		m0, err := readPng(tc.filename)
-		if err != nil {
-			t.Error(tc.filename, err)
-			continue
-		}
-		// Encode that image as JPEG.
-		var buf bytes.Buffer
-		err = Encode(&buf, m0, &Options{Quality: tc.quality})
-		if err != nil {
-			t.Error(tc.filename, err)
-			continue
-		}
-		// Decode that JPEG.
-		m1, err := Decode(&buf)
-		if err != nil {
-			t.Error(tc.filename, err)
-			continue
-		}
-		if m0.Bounds() != m1.Bounds() {
-			t.Errorf("%s, bounds differ: %v and %v", tc.filename, m0.Bounds(), m1.Bounds())
-			continue
-		}
-		// Compare the average delta to the tolerance level.
-		if averageDelta(m0, m1) > tc.tolerance {
-			t.Errorf("%s, quality=%d: average delta is too high", tc.filename, tc.quality)
-			continue
-		}
-	}
-}
-
-// averageDelta returns the average delta in RGB space. The two images must
-// have the same bounds.
-func averageDelta(m0, m1 image.Image) int64 {
-	b := m0.Bounds()
-	var sum, n int64
-	for y := b.Min.Y; y < b.Max.Y; y++ {
-		for x := b.Min.X; x < b.Max.X; x++ {
-			c0 := m0.At(x, y)
-			c1 := m1.At(x, y)
-			r0, g0, b0, _ := c0.RGBA()
-			r1, g1, b1, _ := c1.RGBA()
-			sum += delta(r0, r1)
-			sum += delta(g0, g1)
-			sum += delta(b0, b1)
-			n += 3
-		}
-	}
-	return sum / n
-}
-
-func BenchmarkEncode(b *testing.B) {
-	b.StopTimer()
-	img := image.NewRGBA(image.Rect(0, 0, 640, 480))
-	bo := img.Bounds()
-	rnd := rand.New(rand.NewSource(123))
-	for y := bo.Min.Y; y < bo.Max.Y; y++ {
-		for x := bo.Min.X; x < bo.Max.X; x++ {
-			img.SetRGBA(x, y, color.RGBA{
-				uint8(rnd.Intn(256)),
-				uint8(rnd.Intn(256)),
-				uint8(rnd.Intn(256)),
-				255,
-			})
-		}
-	}
-	b.SetBytes(640 * 480 * 4)
-	b.StartTimer()
-	options := &Options{Quality: 90}
-	for i := 0; i < b.N; i++ {
-		Encode(ioutil.Discard, img, options)
-	}
-}
diff --git a/src/pkg/image/png/paeth.go b/src/pkg/image/png/paeth.go
deleted file mode 100644
index 37978aa..0000000
--- a/src/pkg/image/png/paeth.go
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package png
-
-// paeth implements the Paeth filter function, as per the PNG specification.
-func paeth(a, b, c uint8) uint8 {
-	// This is an optimized version of the sample code in the PNG spec.
-	// For example, the sample code starts with:
-	//	p := int(a) + int(b) - int(c)
-	//	pa := abs(p - int(a))
-	// but the optimized form uses fewer arithmetic operations:
-	//	pa := int(b) - int(c)
-	//	pa = abs(pa)
-	pc := int(c)
-	pa := int(b) - pc
-	pb := int(a) - pc
-	pc = pa + pb
-	if pa < 0 {
-		pa = -pa
-	}
-	if pb < 0 {
-		pb = -pb
-	}
-	if pc < 0 {
-		pc = -pc
-	}
-	if pa <= pb && pa <= pc {
-		return a
-	} else if pb <= pc {
-		return b
-	}
-	return c
-}
-
-// filterPaeth applies the Paeth filter to the cdat slice.
-// cdat is the current row's data, pdat is the previous row's data.
-func filterPaeth(cdat, pdat []byte, bytesPerPixel int) {
-	var a, b, c, pa, pb, pc int
-	for i := 0; i < bytesPerPixel; i++ {
-		a, c = 0, 0
-		for j := i; j < len(cdat); j += bytesPerPixel {
-			b = int(pdat[j])
-			pa = b - c
-			pb = a - c
-			pc = pa + pb
-			if pa < 0 {
-				pa = -pa
-			}
-			if pb < 0 {
-				pb = -pb
-			}
-			if pc < 0 {
-				pc = -pc
-			}
-			if pa <= pb && pa <= pc {
-				// No-op.
-			} else if pb <= pc {
-				a = b
-			} else {
-				a = c
-			}
-			a += int(cdat[j])
-			a &= 0xff
-			cdat[j] = uint8(a)
-			c = b
-		}
-	}
-}
diff --git a/src/pkg/image/png/paeth_test.go b/src/pkg/image/png/paeth_test.go
deleted file mode 100644
index bb08486..0000000
--- a/src/pkg/image/png/paeth_test.go
+++ /dev/null
@@ -1,91 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package png
-
-import (
-	"bytes"
-	"math/rand"
-	"testing"
-)
-
-func abs(x int) int {
-	if x < 0 {
-		return -x
-	}
-	return x
-}
-
-// slowPaeth is a slow but simple implementation of the Paeth function.
-// It is a straight port of the sample code in the PNG spec, section 9.4.
-func slowPaeth(a, b, c uint8) uint8 {
-	p := int(a) + int(b) - int(c)
-	pa := abs(p - int(a))
-	pb := abs(p - int(b))
-	pc := abs(p - int(c))
-	if pa <= pb && pa <= pc {
-		return a
-	} else if pb <= pc {
-		return b
-	}
-	return c
-}
-
-// slowFilterPaeth is a slow but simple implementation of func filterPaeth.
-func slowFilterPaeth(cdat, pdat []byte, bytesPerPixel int) {
-	for i := 0; i < bytesPerPixel; i++ {
-		cdat[i] += paeth(0, pdat[i], 0)
-	}
-	for i := bytesPerPixel; i < len(cdat); i++ {
-		cdat[i] += paeth(cdat[i-bytesPerPixel], pdat[i], pdat[i-bytesPerPixel])
-	}
-}
-
-func TestPaeth(t *testing.T) {
-	for a := 0; a < 256; a += 15 {
-		for b := 0; b < 256; b += 15 {
-			for c := 0; c < 256; c += 15 {
-				got := paeth(uint8(a), uint8(b), uint8(c))
-				want := slowPaeth(uint8(a), uint8(b), uint8(c))
-				if got != want {
-					t.Errorf("a, b, c = %d, %d, %d: got %d, want %d", a, b, c, got, want)
-				}
-			}
-		}
-	}
-}
-
-func BenchmarkPaeth(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		paeth(uint8(i>>16), uint8(i>>8), uint8(i))
-	}
-}
-
-func TestPaethDecode(t *testing.T) {
-	pdat0 := make([]byte, 32)
-	pdat1 := make([]byte, 32)
-	pdat2 := make([]byte, 32)
-	cdat0 := make([]byte, 32)
-	cdat1 := make([]byte, 32)
-	cdat2 := make([]byte, 32)
-	r := rand.New(rand.NewSource(1))
-	for bytesPerPixel := 1; bytesPerPixel <= 8; bytesPerPixel++ {
-		for i := 0; i < 100; i++ {
-			for j := range pdat0 {
-				pdat0[j] = uint8(r.Uint32())
-				cdat0[j] = uint8(r.Uint32())
-			}
-			copy(pdat1, pdat0)
-			copy(pdat2, pdat0)
-			copy(cdat1, cdat0)
-			copy(cdat2, cdat0)
-			filterPaeth(cdat1, pdat1, bytesPerPixel)
-			slowFilterPaeth(cdat2, pdat2, bytesPerPixel)
-			if !bytes.Equal(cdat1, cdat2) {
-				t.Errorf("bytesPerPixel: %d\npdat0: % x\ncdat0: % x\ngot:   % x\nwant:  % x", bytesPerPixel, pdat0, cdat0, cdat1, cdat2)
-				break
-			}
-		}
-	}
-}
diff --git a/src/pkg/image/png/reader.go b/src/pkg/image/png/reader.go
deleted file mode 100644
index dfe2991..0000000
--- a/src/pkg/image/png/reader.go
+++ /dev/null
@@ -1,699 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package png implements a PNG image decoder and encoder.
-//
-// The PNG specification is at http://www.w3.org/TR/PNG/.
-package png
-
-import (
-	"compress/zlib"
-	"encoding/binary"
-	"fmt"
-	"hash"
-	"hash/crc32"
-	"image"
-	"image/color"
-	"io"
-)
-
-// Color type, as per the PNG spec.
-const (
-	ctGrayscale      = 0
-	ctTrueColor      = 2
-	ctPaletted       = 3
-	ctGrayscaleAlpha = 4
-	ctTrueColorAlpha = 6
-)
-
-// A cb is a combination of color type and bit depth.
-const (
-	cbInvalid = iota
-	cbG1
-	cbG2
-	cbG4
-	cbG8
-	cbGA8
-	cbTC8
-	cbP1
-	cbP2
-	cbP4
-	cbP8
-	cbTCA8
-	cbG16
-	cbGA16
-	cbTC16
-	cbTCA16
-)
-
-// Filter type, as per the PNG spec.
-const (
-	ftNone    = 0
-	ftSub     = 1
-	ftUp      = 2
-	ftAverage = 3
-	ftPaeth   = 4
-	nFilter   = 5
-)
-
-// Decoding stage.
-// The PNG specification says that the IHDR, PLTE (if present), IDAT and IEND
-// chunks must appear in that order. There may be multiple IDAT chunks, and
-// IDAT chunks must be sequential (i.e. they may not have any other chunks
-// between them).
-// http://www.w3.org/TR/PNG/#5ChunkOrdering
-const (
-	dsStart = iota
-	dsSeenIHDR
-	dsSeenPLTE
-	dsSeenIDAT
-	dsSeenIEND
-)
-
-const pngHeader = "\x89PNG\r\n\x1a\n"
-
-type decoder struct {
-	r             io.Reader
-	img           image.Image
-	crc           hash.Hash32
-	width, height int
-	depth         int
-	palette       color.Palette
-	cb            int
-	stage         int
-	idatLength    uint32
-	tmp           [3 * 256]byte
-}
-
-// A FormatError reports that the input is not a valid PNG.
-type FormatError string
-
-func (e FormatError) Error() string { return "png: invalid format: " + string(e) }
-
-var chunkOrderError = FormatError("chunk out of order")
-
-// An UnsupportedError reports that the input uses a valid but unimplemented PNG feature.
-type UnsupportedError string
-
-func (e UnsupportedError) Error() string { return "png: unsupported feature: " + string(e) }
-
-func min(a, b int) int {
-	if a < b {
-		return a
-	}
-	return b
-}
-
-func (d *decoder) parseIHDR(length uint32) error {
-	if length != 13 {
-		return FormatError("bad IHDR length")
-	}
-	if _, err := io.ReadFull(d.r, d.tmp[:13]); err != nil {
-		return err
-	}
-	d.crc.Write(d.tmp[:13])
-	if d.tmp[10] != 0 || d.tmp[11] != 0 || d.tmp[12] != 0 {
-		return UnsupportedError("compression, filter or interlace method")
-	}
-	w := int32(binary.BigEndian.Uint32(d.tmp[0:4]))
-	h := int32(binary.BigEndian.Uint32(d.tmp[4:8]))
-	if w < 0 || h < 0 {
-		return FormatError("negative dimension")
-	}
-	nPixels := int64(w) * int64(h)
-	if nPixels != int64(int(nPixels)) {
-		return UnsupportedError("dimension overflow")
-	}
-	d.cb = cbInvalid
-	d.depth = int(d.tmp[8])
-	switch d.depth {
-	case 1:
-		switch d.tmp[9] {
-		case ctGrayscale:
-			d.cb = cbG1
-		case ctPaletted:
-			d.cb = cbP1
-		}
-	case 2:
-		switch d.tmp[9] {
-		case ctGrayscale:
-			d.cb = cbG2
-		case ctPaletted:
-			d.cb = cbP2
-		}
-	case 4:
-		switch d.tmp[9] {
-		case ctGrayscale:
-			d.cb = cbG4
-		case ctPaletted:
-			d.cb = cbP4
-		}
-	case 8:
-		switch d.tmp[9] {
-		case ctGrayscale:
-			d.cb = cbG8
-		case ctTrueColor:
-			d.cb = cbTC8
-		case ctPaletted:
-			d.cb = cbP8
-		case ctGrayscaleAlpha:
-			d.cb = cbGA8
-		case ctTrueColorAlpha:
-			d.cb = cbTCA8
-		}
-	case 16:
-		switch d.tmp[9] {
-		case ctGrayscale:
-			d.cb = cbG16
-		case ctTrueColor:
-			d.cb = cbTC16
-		case ctGrayscaleAlpha:
-			d.cb = cbGA16
-		case ctTrueColorAlpha:
-			d.cb = cbTCA16
-		}
-	}
-	if d.cb == cbInvalid {
-		return UnsupportedError(fmt.Sprintf("bit depth %d, color type %d", d.tmp[8], d.tmp[9]))
-	}
-	d.width, d.height = int(w), int(h)
-	return d.verifyChecksum()
-}
-
-func (d *decoder) parsePLTE(length uint32) error {
-	np := int(length / 3) // The number of palette entries.
-	if length%3 != 0 || np <= 0 || np > 256 || np > 1<<uint(d.depth) {
-		return FormatError("bad PLTE length")
-	}
-	n, err := io.ReadFull(d.r, d.tmp[:3*np])
-	if err != nil {
-		return err
-	}
-	d.crc.Write(d.tmp[:n])
-	switch d.cb {
-	case cbP1, cbP2, cbP4, cbP8:
-		d.palette = make(color.Palette, 256)
-		for i := 0; i < np; i++ {
-			d.palette[i] = color.RGBA{d.tmp[3*i+0], d.tmp[3*i+1], d.tmp[3*i+2], 0xff}
-		}
-		for i := np; i < 256; i++ {
-			// Initialize the rest of the palette to opaque black. The spec (section
-			// 11.2.3) says that "any out-of-range pixel value found in the image data
-			// is an error", but some real-world PNG files have out-of-range pixel
-			// values. We fall back to opaque black, the same as libpng 1.5.13;
-			// ImageMagick 6.5.7 returns an error.
-			d.palette[i] = color.RGBA{0x00, 0x00, 0x00, 0xff}
-		}
-		d.palette = d.palette[:np]
-	case cbTC8, cbTCA8, cbTC16, cbTCA16:
-		// As per the PNG spec, a PLTE chunk is optional (and for practical purposes,
-		// ignorable) for the ctTrueColor and ctTrueColorAlpha color types (section 4.1.2).
-	default:
-		return FormatError("PLTE, color type mismatch")
-	}
-	return d.verifyChecksum()
-}
-
-func (d *decoder) parsetRNS(length uint32) error {
-	if length > 256 {
-		return FormatError("bad tRNS length")
-	}
-	n, err := io.ReadFull(d.r, d.tmp[:length])
-	if err != nil {
-		return err
-	}
-	d.crc.Write(d.tmp[:n])
-	switch d.cb {
-	case cbG8, cbG16:
-		return UnsupportedError("grayscale transparency")
-	case cbTC8, cbTC16:
-		return UnsupportedError("truecolor transparency")
-	case cbP1, cbP2, cbP4, cbP8:
-		if len(d.palette) < n {
-			d.palette = d.palette[:n]
-		}
-		for i := 0; i < n; i++ {
-			rgba := d.palette[i].(color.RGBA)
-			d.palette[i] = color.NRGBA{rgba.R, rgba.G, rgba.B, d.tmp[i]}
-		}
-	case cbGA8, cbGA16, cbTCA8, cbTCA16:
-		return FormatError("tRNS, color type mismatch")
-	}
-	return d.verifyChecksum()
-}
-
-// Read presents one or more IDAT chunks as one continuous stream (minus the
-// intermediate chunk headers and footers). If the PNG data looked like:
-//   ... len0 IDAT xxx crc0 len1 IDAT yy crc1 len2 IEND crc2
-// then this reader presents xxxyy. For well-formed PNG data, the decoder state
-// immediately before the first Read call is that d.r is positioned between the
-// first IDAT and xxx, and the decoder state immediately after the last Read
-// call is that d.r is positioned between yy and crc1.
-func (d *decoder) Read(p []byte) (int, error) {
-	if len(p) == 0 {
-		return 0, nil
-	}
-	for d.idatLength == 0 {
-		// We have exhausted an IDAT chunk. Verify the checksum of that chunk.
-		if err := d.verifyChecksum(); err != nil {
-			return 0, err
-		}
-		// Read the length and chunk type of the next chunk, and check that
-		// it is an IDAT chunk.
-		if _, err := io.ReadFull(d.r, d.tmp[:8]); err != nil {
-			return 0, err
-		}
-		d.idatLength = binary.BigEndian.Uint32(d.tmp[:4])
-		if string(d.tmp[4:8]) != "IDAT" {
-			return 0, FormatError("not enough pixel data")
-		}
-		d.crc.Reset()
-		d.crc.Write(d.tmp[4:8])
-	}
-	if int(d.idatLength) < 0 {
-		return 0, UnsupportedError("IDAT chunk length overflow")
-	}
-	n, err := d.r.Read(p[:min(len(p), int(d.idatLength))])
-	d.crc.Write(p[:n])
-	d.idatLength -= uint32(n)
-	return n, err
-}
-
-// decode decodes the IDAT data into an image.
-func (d *decoder) decode() (image.Image, error) {
-	r, err := zlib.NewReader(d)
-	if err != nil {
-		return nil, err
-	}
-	defer r.Close()
-	bitsPerPixel := 0
-	pixOffset := 0
-	var (
-		gray     *image.Gray
-		rgba     *image.RGBA
-		paletted *image.Paletted
-		nrgba    *image.NRGBA
-		gray16   *image.Gray16
-		rgba64   *image.RGBA64
-		nrgba64  *image.NRGBA64
-		img      image.Image
-	)
-	switch d.cb {
-	case cbG1, cbG2, cbG4, cbG8:
-		bitsPerPixel = d.depth
-		gray = image.NewGray(image.Rect(0, 0, d.width, d.height))
-		img = gray
-	case cbGA8:
-		bitsPerPixel = 16
-		nrgba = image.NewNRGBA(image.Rect(0, 0, d.width, d.height))
-		img = nrgba
-	case cbTC8:
-		bitsPerPixel = 24
-		rgba = image.NewRGBA(image.Rect(0, 0, d.width, d.height))
-		img = rgba
-	case cbP1, cbP2, cbP4, cbP8:
-		bitsPerPixel = d.depth
-		paletted = image.NewPaletted(image.Rect(0, 0, d.width, d.height), d.palette)
-		img = paletted
-	case cbTCA8:
-		bitsPerPixel = 32
-		nrgba = image.NewNRGBA(image.Rect(0, 0, d.width, d.height))
-		img = nrgba
-	case cbG16:
-		bitsPerPixel = 16
-		gray16 = image.NewGray16(image.Rect(0, 0, d.width, d.height))
-		img = gray16
-	case cbGA16:
-		bitsPerPixel = 32
-		nrgba64 = image.NewNRGBA64(image.Rect(0, 0, d.width, d.height))
-		img = nrgba64
-	case cbTC16:
-		bitsPerPixel = 48
-		rgba64 = image.NewRGBA64(image.Rect(0, 0, d.width, d.height))
-		img = rgba64
-	case cbTCA16:
-		bitsPerPixel = 64
-		nrgba64 = image.NewNRGBA64(image.Rect(0, 0, d.width, d.height))
-		img = nrgba64
-	}
-	bytesPerPixel := (bitsPerPixel + 7) / 8
-
-	// cr and pr are the bytes for the current and previous row.
-	// The +1 is for the per-row filter type, which is at cr[0].
-	cr := make([]uint8, 1+(bitsPerPixel*d.width+7)/8)
-	pr := make([]uint8, 1+(bitsPerPixel*d.width+7)/8)
-
-	for y := 0; y < d.height; y++ {
-		// Read the decompressed bytes.
-		_, err := io.ReadFull(r, cr)
-		if err != nil {
-			return nil, err
-		}
-
-		// Apply the filter.
-		cdat := cr[1:]
-		pdat := pr[1:]
-		switch cr[0] {
-		case ftNone:
-			// No-op.
-		case ftSub:
-			for i := bytesPerPixel; i < len(cdat); i++ {
-				cdat[i] += cdat[i-bytesPerPixel]
-			}
-		case ftUp:
-			for i, p := range pdat {
-				cdat[i] += p
-			}
-		case ftAverage:
-			for i := 0; i < bytesPerPixel; i++ {
-				cdat[i] += pdat[i] / 2
-			}
-			for i := bytesPerPixel; i < len(cdat); i++ {
-				cdat[i] += uint8((int(cdat[i-bytesPerPixel]) + int(pdat[i])) / 2)
-			}
-		case ftPaeth:
-			filterPaeth(cdat, pdat, bytesPerPixel)
-		default:
-			return nil, FormatError("bad filter type")
-		}
-
-		// Convert from bytes to colors.
-		switch d.cb {
-		case cbG1:
-			for x := 0; x < d.width; x += 8 {
-				b := cdat[x/8]
-				for x2 := 0; x2 < 8 && x+x2 < d.width; x2++ {
-					gray.SetGray(x+x2, y, color.Gray{(b >> 7) * 0xff})
-					b <<= 1
-				}
-			}
-		case cbG2:
-			for x := 0; x < d.width; x += 4 {
-				b := cdat[x/4]
-				for x2 := 0; x2 < 4 && x+x2 < d.width; x2++ {
-					gray.SetGray(x+x2, y, color.Gray{(b >> 6) * 0x55})
-					b <<= 2
-				}
-			}
-		case cbG4:
-			for x := 0; x < d.width; x += 2 {
-				b := cdat[x/2]
-				for x2 := 0; x2 < 2 && x+x2 < d.width; x2++ {
-					gray.SetGray(x+x2, y, color.Gray{(b >> 4) * 0x11})
-					b <<= 4
-				}
-			}
-		case cbG8:
-			copy(gray.Pix[pixOffset:], cdat)
-			pixOffset += gray.Stride
-		case cbGA8:
-			for x := 0; x < d.width; x++ {
-				ycol := cdat[2*x+0]
-				nrgba.SetNRGBA(x, y, color.NRGBA{ycol, ycol, ycol, cdat[2*x+1]})
-			}
-		case cbTC8:
-			pix, i, j := rgba.Pix, pixOffset, 0
-			for x := 0; x < d.width; x++ {
-				pix[i+0] = cdat[j+0]
-				pix[i+1] = cdat[j+1]
-				pix[i+2] = cdat[j+2]
-				pix[i+3] = 0xff
-				i += 4
-				j += 3
-			}
-			pixOffset += rgba.Stride
-		case cbP1:
-			for x := 0; x < d.width; x += 8 {
-				b := cdat[x/8]
-				for x2 := 0; x2 < 8 && x+x2 < d.width; x2++ {
-					idx := b >> 7
-					if len(paletted.Palette) <= int(idx) {
-						paletted.Palette = paletted.Palette[:int(idx)+1]
-					}
-					paletted.SetColorIndex(x+x2, y, idx)
-					b <<= 1
-				}
-			}
-		case cbP2:
-			for x := 0; x < d.width; x += 4 {
-				b := cdat[x/4]
-				for x2 := 0; x2 < 4 && x+x2 < d.width; x2++ {
-					idx := b >> 6
-					if len(paletted.Palette) <= int(idx) {
-						paletted.Palette = paletted.Palette[:int(idx)+1]
-					}
-					paletted.SetColorIndex(x+x2, y, idx)
-					b <<= 2
-				}
-			}
-		case cbP4:
-			for x := 0; x < d.width; x += 2 {
-				b := cdat[x/2]
-				for x2 := 0; x2 < 2 && x+x2 < d.width; x2++ {
-					idx := b >> 4
-					if len(paletted.Palette) <= int(idx) {
-						paletted.Palette = paletted.Palette[:int(idx)+1]
-					}
-					paletted.SetColorIndex(x+x2, y, idx)
-					b <<= 4
-				}
-			}
-		case cbP8:
-			if len(paletted.Palette) != 255 {
-				for x := 0; x < d.width; x++ {
-					if len(paletted.Palette) <= int(cdat[x]) {
-						paletted.Palette = paletted.Palette[:int(cdat[x])+1]
-					}
-				}
-			}
-			copy(paletted.Pix[pixOffset:], cdat)
-			pixOffset += paletted.Stride
-		case cbTCA8:
-			copy(nrgba.Pix[pixOffset:], cdat)
-			pixOffset += nrgba.Stride
-		case cbG16:
-			for x := 0; x < d.width; x++ {
-				ycol := uint16(cdat[2*x+0])<<8 | uint16(cdat[2*x+1])
-				gray16.SetGray16(x, y, color.Gray16{ycol})
-			}
-		case cbGA16:
-			for x := 0; x < d.width; x++ {
-				ycol := uint16(cdat[4*x+0])<<8 | uint16(cdat[4*x+1])
-				acol := uint16(cdat[4*x+2])<<8 | uint16(cdat[4*x+3])
-				nrgba64.SetNRGBA64(x, y, color.NRGBA64{ycol, ycol, ycol, acol})
-			}
-		case cbTC16:
-			for x := 0; x < d.width; x++ {
-				rcol := uint16(cdat[6*x+0])<<8 | uint16(cdat[6*x+1])
-				gcol := uint16(cdat[6*x+2])<<8 | uint16(cdat[6*x+3])
-				bcol := uint16(cdat[6*x+4])<<8 | uint16(cdat[6*x+5])
-				rgba64.SetRGBA64(x, y, color.RGBA64{rcol, gcol, bcol, 0xffff})
-			}
-		case cbTCA16:
-			for x := 0; x < d.width; x++ {
-				rcol := uint16(cdat[8*x+0])<<8 | uint16(cdat[8*x+1])
-				gcol := uint16(cdat[8*x+2])<<8 | uint16(cdat[8*x+3])
-				bcol := uint16(cdat[8*x+4])<<8 | uint16(cdat[8*x+5])
-				acol := uint16(cdat[8*x+6])<<8 | uint16(cdat[8*x+7])
-				nrgba64.SetNRGBA64(x, y, color.NRGBA64{rcol, gcol, bcol, acol})
-			}
-		}
-
-		// The current row for y is the previous row for y+1.
-		pr, cr = cr, pr
-	}
-
-	// Check for EOF, to verify the zlib checksum.
-	n := 0
-	for i := 0; n == 0 && err == nil; i++ {
-		if i == 100 {
-			return nil, io.ErrNoProgress
-		}
-		n, err = r.Read(pr[:1])
-	}
-	if err != nil && err != io.EOF {
-		return nil, FormatError(err.Error())
-	}
-	if n != 0 || d.idatLength != 0 {
-		return nil, FormatError("too much pixel data")
-	}
-
-	return img, nil
-}
-
-func (d *decoder) parseIDAT(length uint32) (err error) {
-	d.idatLength = length
-	d.img, err = d.decode()
-	if err != nil {
-		return err
-	}
-	return d.verifyChecksum()
-}
-
-func (d *decoder) parseIEND(length uint32) error {
-	if length != 0 {
-		return FormatError("bad IEND length")
-	}
-	return d.verifyChecksum()
-}
-
-func (d *decoder) parseChunk() error {
-	// Read the length and chunk type.
-	n, err := io.ReadFull(d.r, d.tmp[:8])
-	if err != nil {
-		return err
-	}
-	length := binary.BigEndian.Uint32(d.tmp[:4])
-	d.crc.Reset()
-	d.crc.Write(d.tmp[4:8])
-
-	// Read the chunk data.
-	switch string(d.tmp[4:8]) {
-	case "IHDR":
-		if d.stage != dsStart {
-			return chunkOrderError
-		}
-		d.stage = dsSeenIHDR
-		return d.parseIHDR(length)
-	case "PLTE":
-		if d.stage != dsSeenIHDR {
-			return chunkOrderError
-		}
-		d.stage = dsSeenPLTE
-		return d.parsePLTE(length)
-	case "tRNS":
-		if d.stage != dsSeenPLTE {
-			return chunkOrderError
-		}
-		return d.parsetRNS(length)
-	case "IDAT":
-		if d.stage < dsSeenIHDR || d.stage > dsSeenIDAT || (d.cb == cbP8 && d.stage == dsSeenIHDR) {
-			return chunkOrderError
-		}
-		d.stage = dsSeenIDAT
-		return d.parseIDAT(length)
-	case "IEND":
-		if d.stage != dsSeenIDAT {
-			return chunkOrderError
-		}
-		d.stage = dsSeenIEND
-		return d.parseIEND(length)
-	}
-	// Ignore this chunk (of a known length).
-	var ignored [4096]byte
-	for length > 0 {
-		n, err = io.ReadFull(d.r, ignored[:min(len(ignored), int(length))])
-		if err != nil {
-			return err
-		}
-		d.crc.Write(ignored[:n])
-		length -= uint32(n)
-	}
-	return d.verifyChecksum()
-}
-
-func (d *decoder) verifyChecksum() error {
-	if _, err := io.ReadFull(d.r, d.tmp[:4]); err != nil {
-		return err
-	}
-	if binary.BigEndian.Uint32(d.tmp[:4]) != d.crc.Sum32() {
-		return FormatError("invalid checksum")
-	}
-	return nil
-}
-
-func (d *decoder) checkHeader() error {
-	_, err := io.ReadFull(d.r, d.tmp[:len(pngHeader)])
-	if err != nil {
-		return err
-	}
-	if string(d.tmp[:len(pngHeader)]) != pngHeader {
-		return FormatError("not a PNG file")
-	}
-	return nil
-}
-
-// Decode reads a PNG image from r and returns it as an image.Image.
-// The type of Image returned depends on the PNG contents.
-func Decode(r io.Reader) (image.Image, error) {
-	d := &decoder{
-		r:   r,
-		crc: crc32.NewIEEE(),
-	}
-	if err := d.checkHeader(); err != nil {
-		if err == io.EOF {
-			err = io.ErrUnexpectedEOF
-		}
-		return nil, err
-	}
-	for d.stage != dsSeenIEND {
-		if err := d.parseChunk(); err != nil {
-			if err == io.EOF {
-				err = io.ErrUnexpectedEOF
-			}
-			return nil, err
-		}
-	}
-	return d.img, nil
-}
-
-// DecodeConfig returns the color model and dimensions of a PNG image without
-// decoding the entire image.
-func DecodeConfig(r io.Reader) (image.Config, error) {
-	d := &decoder{
-		r:   r,
-		crc: crc32.NewIEEE(),
-	}
-	if err := d.checkHeader(); err != nil {
-		if err == io.EOF {
-			err = io.ErrUnexpectedEOF
-		}
-		return image.Config{}, err
-	}
-	for {
-		if err := d.parseChunk(); err != nil {
-			if err == io.EOF {
-				err = io.ErrUnexpectedEOF
-			}
-			return image.Config{}, err
-		}
-		paletted := d.cb == cbP8 || d.cb == cbP4 || d.cb == cbP2 || d.cb == cbP1
-		if d.stage == dsSeenIHDR && !paletted {
-			break
-		}
-		if d.stage == dsSeenPLTE && paletted {
-			break
-		}
-	}
-	var cm color.Model
-	switch d.cb {
-	case cbG1, cbG2, cbG4, cbG8:
-		cm = color.GrayModel
-	case cbGA8:
-		cm = color.NRGBAModel
-	case cbTC8:
-		cm = color.RGBAModel
-	case cbP1, cbP2, cbP4, cbP8:
-		cm = d.palette
-	case cbTCA8:
-		cm = color.NRGBAModel
-	case cbG16:
-		cm = color.Gray16Model
-	case cbGA16:
-		cm = color.NRGBA64Model
-	case cbTC16:
-		cm = color.RGBA64Model
-	case cbTCA16:
-		cm = color.NRGBA64Model
-	}
-	return image.Config{
-		ColorModel: cm,
-		Width:      d.width,
-		Height:     d.height,
-	}, nil
-}
-
-func init() {
-	image.RegisterFormat("png", pngHeader, Decode, DecodeConfig)
-}
diff --git a/src/pkg/image/png/reader_test.go b/src/pkg/image/png/reader_test.go
deleted file mode 100644
index ac0d949..0000000
--- a/src/pkg/image/png/reader_test.go
+++ /dev/null
@@ -1,350 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package png
-
-import (
-	"bufio"
-	"fmt"
-	"image"
-	"image/color"
-	"io"
-	"io/ioutil"
-	"os"
-	"strings"
-	"testing"
-)
-
-var filenames = []string{
-	"basn0g01",
-	"basn0g01-30",
-	"basn0g02",
-	"basn0g02-29",
-	"basn0g04",
-	"basn0g04-31",
-	"basn0g08",
-	"basn0g16",
-	"basn2c08",
-	"basn2c16",
-	"basn3p01",
-	"basn3p02",
-	"basn3p04",
-	"basn3p08",
-	"basn3p08-trns",
-	"basn4a08",
-	"basn4a16",
-	"basn6a08",
-	"basn6a16",
-}
-
-var filenamesPaletted = []string{
-	"basn3p01",
-	"basn3p02",
-	"basn3p04",
-	"basn3p08",
-	"basn3p08-trns",
-}
-
-var filenamesShort = []string{
-	"basn0g01",
-	"basn0g04-31",
-	"basn6a16",
-}
-
-func readPNG(filename string) (image.Image, error) {
-	f, err := os.Open(filename)
-	if err != nil {
-		return nil, err
-	}
-	defer f.Close()
-	return Decode(f)
-}
-
-// An approximation of the sng command-line tool.
-func sng(w io.WriteCloser, filename string, png image.Image) {
-	defer w.Close()
-	bounds := png.Bounds()
-	cm := png.ColorModel()
-	var bitdepth int
-	switch cm {
-	case color.RGBAModel, color.NRGBAModel, color.AlphaModel, color.GrayModel:
-		bitdepth = 8
-	default:
-		bitdepth = 16
-	}
-	cpm, _ := cm.(color.Palette)
-	var paletted *image.Paletted
-	if cpm != nil {
-		switch {
-		case len(cpm) <= 2:
-			bitdepth = 1
-		case len(cpm) <= 4:
-			bitdepth = 2
-		case len(cpm) <= 16:
-			bitdepth = 4
-		default:
-			bitdepth = 8
-		}
-		paletted = png.(*image.Paletted)
-	}
-
-	// Write the filename and IHDR.
-	io.WriteString(w, "#SNG: from "+filename+".png\nIHDR {\n")
-	fmt.Fprintf(w, "    width: %d; height: %d; bitdepth: %d;\n", bounds.Dx(), bounds.Dy(), bitdepth)
-	switch {
-	case cm == color.RGBAModel, cm == color.RGBA64Model:
-		io.WriteString(w, "    using color;\n")
-	case cm == color.NRGBAModel, cm == color.NRGBA64Model:
-		io.WriteString(w, "    using color alpha;\n")
-	case cm == color.GrayModel, cm == color.Gray16Model:
-		io.WriteString(w, "    using grayscale;\n")
-	case cpm != nil:
-		io.WriteString(w, "    using color palette;\n")
-	default:
-		io.WriteString(w, "unknown PNG decoder color model\n")
-	}
-	io.WriteString(w, "}\n")
-
-	// We fake a gAMA output. The test files have a gAMA chunk but the go PNG parser ignores it
-	// (the PNG spec section 11.3 says "Ancillary chunks may be ignored by a decoder").
-	io.WriteString(w, "gAMA {1.0000}\n")
-
-	// Write the PLTE and tRNS (if applicable).
-	if cpm != nil {
-		lastAlpha := -1
-		io.WriteString(w, "PLTE {\n")
-		for i, c := range cpm {
-			var r, g, b, a uint8
-			switch c := c.(type) {
-			case color.RGBA:
-				r, g, b, a = c.R, c.G, c.B, 0xff
-			case color.NRGBA:
-				r, g, b, a = c.R, c.G, c.B, c.A
-			default:
-				panic("unknown palette color type")
-			}
-			if a != 0xff {
-				lastAlpha = i
-			}
-			fmt.Fprintf(w, "    (%3d,%3d,%3d)     # rgb = (0x%02x,0x%02x,0x%02x)\n", r, g, b, r, g, b)
-		}
-		io.WriteString(w, "}\n")
-		if lastAlpha != -1 {
-			io.WriteString(w, "tRNS {\n")
-			for i := 0; i <= lastAlpha; i++ {
-				_, _, _, a := cpm[i].RGBA()
-				a >>= 8
-				fmt.Fprintf(w, " %d", a)
-			}
-			io.WriteString(w, "}\n")
-		}
-	}
-
-	// Write the IMAGE.
-	io.WriteString(w, "IMAGE {\n    pixels hex\n")
-	for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
-		switch {
-		case cm == color.GrayModel:
-			for x := bounds.Min.X; x < bounds.Max.X; x++ {
-				gray := png.At(x, y).(color.Gray)
-				fmt.Fprintf(w, "%02x", gray.Y)
-			}
-		case cm == color.Gray16Model:
-			for x := bounds.Min.X; x < bounds.Max.X; x++ {
-				gray16 := png.At(x, y).(color.Gray16)
-				fmt.Fprintf(w, "%04x ", gray16.Y)
-			}
-		case cm == color.RGBAModel:
-			for x := bounds.Min.X; x < bounds.Max.X; x++ {
-				rgba := png.At(x, y).(color.RGBA)
-				fmt.Fprintf(w, "%02x%02x%02x ", rgba.R, rgba.G, rgba.B)
-			}
-		case cm == color.RGBA64Model:
-			for x := bounds.Min.X; x < bounds.Max.X; x++ {
-				rgba64 := png.At(x, y).(color.RGBA64)
-				fmt.Fprintf(w, "%04x%04x%04x ", rgba64.R, rgba64.G, rgba64.B)
-			}
-		case cm == color.NRGBAModel:
-			for x := bounds.Min.X; x < bounds.Max.X; x++ {
-				nrgba := png.At(x, y).(color.NRGBA)
-				fmt.Fprintf(w, "%02x%02x%02x%02x ", nrgba.R, nrgba.G, nrgba.B, nrgba.A)
-			}
-		case cm == color.NRGBA64Model:
-			for x := bounds.Min.X; x < bounds.Max.X; x++ {
-				nrgba64 := png.At(x, y).(color.NRGBA64)
-				fmt.Fprintf(w, "%04x%04x%04x%04x ", nrgba64.R, nrgba64.G, nrgba64.B, nrgba64.A)
-			}
-		case cpm != nil:
-			var b, c int
-			for x := bounds.Min.X; x < bounds.Max.X; x++ {
-				b = b<<uint(bitdepth) | int(paletted.ColorIndexAt(x, y))
-				c++
-				if c == 8/bitdepth {
-					fmt.Fprintf(w, "%02x", b)
-					b = 0
-					c = 0
-				}
-			}
-		}
-		io.WriteString(w, "\n")
-	}
-	io.WriteString(w, "}\n")
-}
-
-func TestReader(t *testing.T) {
-	names := filenames
-	if testing.Short() {
-		names = filenamesShort
-	}
-	for _, fn := range names {
-		// Read the .png file.
-		img, err := readPNG("testdata/pngsuite/" + fn + ".png")
-		if err != nil {
-			t.Error(fn, err)
-			continue
-		}
-
-		if fn == "basn4a16" {
-			// basn4a16.sng is gray + alpha but sng() will produce true color + alpha
-			// so we just check a single random pixel.
-			c := img.At(2, 1).(color.NRGBA64)
-			if c.R != 0x11a7 || c.G != 0x11a7 || c.B != 0x11a7 || c.A != 0x1085 {
-				t.Error(fn, fmt.Errorf("wrong pixel value at (2, 1): %x", c))
-			}
-			continue
-		}
-
-		piper, pipew := io.Pipe()
-		pb := bufio.NewScanner(piper)
-		go sng(pipew, fn, img)
-		defer piper.Close()
-
-		// Read the .sng file.
-		sf, err := os.Open("testdata/pngsuite/" + fn + ".sng")
-		if err != nil {
-			t.Error(fn, err)
-			continue
-		}
-		defer sf.Close()
-		sb := bufio.NewScanner(sf)
-		if err != nil {
-			t.Error(fn, err)
-			continue
-		}
-
-		// Compare the two, in SNG format, line by line.
-		for {
-			pdone := pb.Scan()
-			sdone := sb.Scan()
-			if pdone && sdone {
-				break
-			}
-			if pdone || sdone {
-				t.Errorf("%s: Different sizes", fn)
-				break
-			}
-			ps := pb.Text()
-			ss := sb.Text()
-			if ps != ss {
-				t.Errorf("%s: Mismatch\n%sversus\n%s\n", fn, ps, ss)
-				break
-			}
-		}
-		if pb.Err() != nil {
-			t.Error(fn, pb.Err())
-		}
-		if sb.Err() != nil {
-			t.Error(fn, sb.Err())
-		}
-	}
-}
-
-var readerErrors = []struct {
-	file string
-	err  string
-}{
-	{"invalid-zlib.png", "zlib: invalid checksum"},
-	{"invalid-crc32.png", "invalid checksum"},
-	{"invalid-noend.png", "unexpected EOF"},
-	{"invalid-trunc.png", "unexpected EOF"},
-}
-
-func TestReaderError(t *testing.T) {
-	for _, tt := range readerErrors {
-		img, err := readPNG("testdata/" + tt.file)
-		if err == nil {
-			t.Errorf("decoding %s: missing error", tt.file)
-			continue
-		}
-		if !strings.Contains(err.Error(), tt.err) {
-			t.Errorf("decoding %s: %s, want %s", tt.file, err, tt.err)
-		}
-		if img != nil {
-			t.Errorf("decoding %s: have image + error", tt.file)
-		}
-	}
-}
-
-func TestPalettedDecodeConfig(t *testing.T) {
-	for _, fn := range filenamesPaletted {
-		f, err := os.Open("testdata/pngsuite/" + fn + ".png")
-		if err != nil {
-			t.Errorf("%s: open failed: %v", fn, err)
-			continue
-		}
-		defer f.Close()
-		cfg, err := DecodeConfig(f)
-		if err != nil {
-			t.Errorf("%s: %v", fn, err)
-			continue
-		}
-		pal, ok := cfg.ColorModel.(color.Palette)
-		if !ok {
-			t.Errorf("%s: expected paletted color model", fn)
-			continue
-		}
-		if pal == nil {
-			t.Errorf("%s: palette not initialized", fn)
-			continue
-		}
-	}
-}
-
-func benchmarkDecode(b *testing.B, filename string, bytesPerPixel int) {
-	b.StopTimer()
-	data, err := ioutil.ReadFile(filename)
-	if err != nil {
-		b.Fatal(err)
-	}
-	s := string(data)
-	cfg, err := DecodeConfig(strings.NewReader(s))
-	if err != nil {
-		b.Fatal(err)
-	}
-	b.SetBytes(int64(cfg.Width * cfg.Height * bytesPerPixel))
-	b.StartTimer()
-	for i := 0; i < b.N; i++ {
-		Decode(strings.NewReader(s))
-	}
-}
-
-func BenchmarkDecodeGray(b *testing.B) {
-	benchmarkDecode(b, "testdata/benchGray.png", 1)
-}
-
-func BenchmarkDecodeNRGBAGradient(b *testing.B) {
-	benchmarkDecode(b, "testdata/benchNRGBA-gradient.png", 4)
-}
-
-func BenchmarkDecodeNRGBAOpaque(b *testing.B) {
-	benchmarkDecode(b, "testdata/benchNRGBA-opaque.png", 4)
-}
-
-func BenchmarkDecodePaletted(b *testing.B) {
-	benchmarkDecode(b, "testdata/benchPaletted.png", 1)
-}
-
-func BenchmarkDecodeRGB(b *testing.B) {
-	benchmarkDecode(b, "testdata/benchRGB.png", 4)
-}
diff --git a/src/pkg/image/png/writer.go b/src/pkg/image/png/writer.go
deleted file mode 100644
index 629452c..0000000
--- a/src/pkg/image/png/writer.go
+++ /dev/null
@@ -1,482 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package png
-
-import (
-	"bufio"
-	"compress/zlib"
-	"hash/crc32"
-	"image"
-	"image/color"
-	"io"
-	"strconv"
-)
-
-type encoder struct {
-	w      io.Writer
-	m      image.Image
-	cb     int
-	err    error
-	header [8]byte
-	footer [4]byte
-	tmp    [4 * 256]byte
-}
-
-// Big-endian.
-func writeUint32(b []uint8, u uint32) {
-	b[0] = uint8(u >> 24)
-	b[1] = uint8(u >> 16)
-	b[2] = uint8(u >> 8)
-	b[3] = uint8(u >> 0)
-}
-
-type opaquer interface {
-	Opaque() bool
-}
-
-// Returns whether or not the image is fully opaque.
-func opaque(m image.Image) bool {
-	if o, ok := m.(opaquer); ok {
-		return o.Opaque()
-	}
-	b := m.Bounds()
-	for y := b.Min.Y; y < b.Max.Y; y++ {
-		for x := b.Min.X; x < b.Max.X; x++ {
-			_, _, _, a := m.At(x, y).RGBA()
-			if a != 0xffff {
-				return false
-			}
-		}
-	}
-	return true
-}
-
-// The absolute value of a byte interpreted as a signed int8.
-func abs8(d uint8) int {
-	if d < 128 {
-		return int(d)
-	}
-	return 256 - int(d)
-}
-
-func (e *encoder) writeChunk(b []byte, name string) {
-	if e.err != nil {
-		return
-	}
-	n := uint32(len(b))
-	if int(n) != len(b) {
-		e.err = UnsupportedError(name + " chunk is too large: " + strconv.Itoa(len(b)))
-		return
-	}
-	writeUint32(e.header[:4], n)
-	e.header[4] = name[0]
-	e.header[5] = name[1]
-	e.header[6] = name[2]
-	e.header[7] = name[3]
-	crc := crc32.NewIEEE()
-	crc.Write(e.header[4:8])
-	crc.Write(b)
-	writeUint32(e.footer[:4], crc.Sum32())
-
-	_, e.err = e.w.Write(e.header[:8])
-	if e.err != nil {
-		return
-	}
-	_, e.err = e.w.Write(b)
-	if e.err != nil {
-		return
-	}
-	_, e.err = e.w.Write(e.footer[:4])
-}
-
-func (e *encoder) writeIHDR() {
-	b := e.m.Bounds()
-	writeUint32(e.tmp[0:4], uint32(b.Dx()))
-	writeUint32(e.tmp[4:8], uint32(b.Dy()))
-	// Set bit depth and color type.
-	switch e.cb {
-	case cbG8:
-		e.tmp[8] = 8
-		e.tmp[9] = ctGrayscale
-	case cbTC8:
-		e.tmp[8] = 8
-		e.tmp[9] = ctTrueColor
-	case cbP8:
-		e.tmp[8] = 8
-		e.tmp[9] = ctPaletted
-	case cbTCA8:
-		e.tmp[8] = 8
-		e.tmp[9] = ctTrueColorAlpha
-	case cbG16:
-		e.tmp[8] = 16
-		e.tmp[9] = ctGrayscale
-	case cbTC16:
-		e.tmp[8] = 16
-		e.tmp[9] = ctTrueColor
-	case cbTCA16:
-		e.tmp[8] = 16
-		e.tmp[9] = ctTrueColorAlpha
-	}
-	e.tmp[10] = 0 // default compression method
-	e.tmp[11] = 0 // default filter method
-	e.tmp[12] = 0 // non-interlaced
-	e.writeChunk(e.tmp[:13], "IHDR")
-}
-
-func (e *encoder) writePLTEAndTRNS(p color.Palette) {
-	if len(p) < 1 || len(p) > 256 {
-		e.err = FormatError("bad palette length: " + strconv.Itoa(len(p)))
-		return
-	}
-	last := -1
-	for i, c := range p {
-		c1 := color.NRGBAModel.Convert(c).(color.NRGBA)
-		e.tmp[3*i+0] = c1.R
-		e.tmp[3*i+1] = c1.G
-		e.tmp[3*i+2] = c1.B
-		if c1.A != 0xff {
-			last = i
-		}
-		e.tmp[3*256+i] = c1.A
-	}
-	e.writeChunk(e.tmp[:3*len(p)], "PLTE")
-	if last != -1 {
-		e.writeChunk(e.tmp[3*256:3*256+1+last], "tRNS")
-	}
-}
-
-// An encoder is an io.Writer that satisfies writes by writing PNG IDAT chunks,
-// including an 8-byte header and 4-byte CRC checksum per Write call. Such calls
-// should be relatively infrequent, since writeIDATs uses a bufio.Writer.
-//
-// This method should only be called from writeIDATs (via writeImage).
-// No other code should treat an encoder as an io.Writer.
-func (e *encoder) Write(b []byte) (int, error) {
-	e.writeChunk(b, "IDAT")
-	if e.err != nil {
-		return 0, e.err
-	}
-	return len(b), nil
-}
-
-// Chooses the filter to use for encoding the current row, and applies it.
-// The return value is the index of the filter and also of the row in cr that has had it applied.
-func filter(cr *[nFilter][]byte, pr []byte, bpp int) int {
-	// We try all five filter types, and pick the one that minimizes the sum of absolute differences.
-	// This is the same heuristic that libpng uses, although the filters are attempted in order of
-	// estimated most likely to be minimal (ftUp, ftPaeth, ftNone, ftSub, ftAverage), rather than
-	// in their enumeration order (ftNone, ftSub, ftUp, ftAverage, ftPaeth).
-	cdat0 := cr[0][1:]
-	cdat1 := cr[1][1:]
-	cdat2 := cr[2][1:]
-	cdat3 := cr[3][1:]
-	cdat4 := cr[4][1:]
-	pdat := pr[1:]
-	n := len(cdat0)
-
-	// The up filter.
-	sum := 0
-	for i := 0; i < n; i++ {
-		cdat2[i] = cdat0[i] - pdat[i]
-		sum += abs8(cdat2[i])
-	}
-	best := sum
-	filter := ftUp
-
-	// The Paeth filter.
-	sum = 0
-	for i := 0; i < bpp; i++ {
-		cdat4[i] = cdat0[i] - paeth(0, pdat[i], 0)
-		sum += abs8(cdat4[i])
-	}
-	for i := bpp; i < n; i++ {
-		cdat4[i] = cdat0[i] - paeth(cdat0[i-bpp], pdat[i], pdat[i-bpp])
-		sum += abs8(cdat4[i])
-		if sum >= best {
-			break
-		}
-	}
-	if sum < best {
-		best = sum
-		filter = ftPaeth
-	}
-
-	// The none filter.
-	sum = 0
-	for i := 0; i < n; i++ {
-		sum += abs8(cdat0[i])
-		if sum >= best {
-			break
-		}
-	}
-	if sum < best {
-		best = sum
-		filter = ftNone
-	}
-
-	// The sub filter.
-	sum = 0
-	for i := 0; i < bpp; i++ {
-		cdat1[i] = cdat0[i]
-		sum += abs8(cdat1[i])
-	}
-	for i := bpp; i < n; i++ {
-		cdat1[i] = cdat0[i] - cdat0[i-bpp]
-		sum += abs8(cdat1[i])
-		if sum >= best {
-			break
-		}
-	}
-	if sum < best {
-		best = sum
-		filter = ftSub
-	}
-
-	// The average filter.
-	sum = 0
-	for i := 0; i < bpp; i++ {
-		cdat3[i] = cdat0[i] - pdat[i]/2
-		sum += abs8(cdat3[i])
-	}
-	for i := bpp; i < n; i++ {
-		cdat3[i] = cdat0[i] - uint8((int(cdat0[i-bpp])+int(pdat[i]))/2)
-		sum += abs8(cdat3[i])
-		if sum >= best {
-			break
-		}
-	}
-	if sum < best {
-		best = sum
-		filter = ftAverage
-	}
-
-	return filter
-}
-
-func writeImage(w io.Writer, m image.Image, cb int) error {
-	zw := zlib.NewWriter(w)
-	defer zw.Close()
-
-	bpp := 0 // Bytes per pixel.
-
-	switch cb {
-	case cbG8:
-		bpp = 1
-	case cbTC8:
-		bpp = 3
-	case cbP8:
-		bpp = 1
-	case cbTCA8:
-		bpp = 4
-	case cbTC16:
-		bpp = 6
-	case cbTCA16:
-		bpp = 8
-	case cbG16:
-		bpp = 2
-	}
-	// cr[*] and pr are the bytes for the current and previous row.
-	// cr[0] is unfiltered (or equivalently, filtered with the ftNone filter).
-	// cr[ft], for non-zero filter types ft, are buffers for transforming cr[0] under the
-	// other PNG filter types. These buffers are allocated once and re-used for each row.
-	// The +1 is for the per-row filter type, which is at cr[*][0].
-	b := m.Bounds()
-	var cr [nFilter][]uint8
-	for i := range cr {
-		cr[i] = make([]uint8, 1+bpp*b.Dx())
-		cr[i][0] = uint8(i)
-	}
-	pr := make([]uint8, 1+bpp*b.Dx())
-
-	gray, _ := m.(*image.Gray)
-	rgba, _ := m.(*image.RGBA)
-	paletted, _ := m.(*image.Paletted)
-	nrgba, _ := m.(*image.NRGBA)
-
-	for y := b.Min.Y; y < b.Max.Y; y++ {
-		// Convert from colors to bytes.
-		i := 1
-		switch cb {
-		case cbG8:
-			if gray != nil {
-				offset := (y - b.Min.Y) * gray.Stride
-				copy(cr[0][1:], gray.Pix[offset:offset+b.Dx()])
-			} else {
-				for x := b.Min.X; x < b.Max.X; x++ {
-					c := color.GrayModel.Convert(m.At(x, y)).(color.Gray)
-					cr[0][i] = c.Y
-					i++
-				}
-			}
-		case cbTC8:
-			// We have previously verified that the alpha value is fully opaque.
-			cr0 := cr[0]
-			stride, pix := 0, []byte(nil)
-			if rgba != nil {
-				stride, pix = rgba.Stride, rgba.Pix
-			} else if nrgba != nil {
-				stride, pix = nrgba.Stride, nrgba.Pix
-			}
-			if stride != 0 {
-				j0 := (y - b.Min.Y) * stride
-				j1 := j0 + b.Dx()*4
-				for j := j0; j < j1; j += 4 {
-					cr0[i+0] = pix[j+0]
-					cr0[i+1] = pix[j+1]
-					cr0[i+2] = pix[j+2]
-					i += 3
-				}
-			} else {
-				for x := b.Min.X; x < b.Max.X; x++ {
-					r, g, b, _ := m.At(x, y).RGBA()
-					cr0[i+0] = uint8(r >> 8)
-					cr0[i+1] = uint8(g >> 8)
-					cr0[i+2] = uint8(b >> 8)
-					i += 3
-				}
-			}
-		case cbP8:
-			if paletted != nil {
-				offset := (y - b.Min.Y) * paletted.Stride
-				copy(cr[0][1:], paletted.Pix[offset:offset+b.Dx()])
-			} else {
-				pi := m.(image.PalettedImage)
-				for x := b.Min.X; x < b.Max.X; x++ {
-					cr[0][i] = pi.ColorIndexAt(x, y)
-					i += 1
-				}
-			}
-		case cbTCA8:
-			if nrgba != nil {
-				offset := (y - b.Min.Y) * nrgba.Stride
-				copy(cr[0][1:], nrgba.Pix[offset:offset+b.Dx()*4])
-			} else {
-				// Convert from image.Image (which is alpha-premultiplied) to PNG's non-alpha-premultiplied.
-				for x := b.Min.X; x < b.Max.X; x++ {
-					c := color.NRGBAModel.Convert(m.At(x, y)).(color.NRGBA)
-					cr[0][i+0] = c.R
-					cr[0][i+1] = c.G
-					cr[0][i+2] = c.B
-					cr[0][i+3] = c.A
-					i += 4
-				}
-			}
-		case cbG16:
-			for x := b.Min.X; x < b.Max.X; x++ {
-				c := color.Gray16Model.Convert(m.At(x, y)).(color.Gray16)
-				cr[0][i+0] = uint8(c.Y >> 8)
-				cr[0][i+1] = uint8(c.Y)
-				i += 2
-			}
-		case cbTC16:
-			// We have previously verified that the alpha value is fully opaque.
-			for x := b.Min.X; x < b.Max.X; x++ {
-				r, g, b, _ := m.At(x, y).RGBA()
-				cr[0][i+0] = uint8(r >> 8)
-				cr[0][i+1] = uint8(r)
-				cr[0][i+2] = uint8(g >> 8)
-				cr[0][i+3] = uint8(g)
-				cr[0][i+4] = uint8(b >> 8)
-				cr[0][i+5] = uint8(b)
-				i += 6
-			}
-		case cbTCA16:
-			// Convert from image.Image (which is alpha-premultiplied) to PNG's non-alpha-premultiplied.
-			for x := b.Min.X; x < b.Max.X; x++ {
-				c := color.NRGBA64Model.Convert(m.At(x, y)).(color.NRGBA64)
-				cr[0][i+0] = uint8(c.R >> 8)
-				cr[0][i+1] = uint8(c.R)
-				cr[0][i+2] = uint8(c.G >> 8)
-				cr[0][i+3] = uint8(c.G)
-				cr[0][i+4] = uint8(c.B >> 8)
-				cr[0][i+5] = uint8(c.B)
-				cr[0][i+6] = uint8(c.A >> 8)
-				cr[0][i+7] = uint8(c.A)
-				i += 8
-			}
-		}
-
-		// Apply the filter.
-		f := filter(&cr, pr, bpp)
-
-		// Write the compressed bytes.
-		if _, err := zw.Write(cr[f]); err != nil {
-			return err
-		}
-
-		// The current row for y is the previous row for y+1.
-		pr, cr[0] = cr[0], pr
-	}
-	return nil
-}
-
-// Write the actual image data to one or more IDAT chunks.
-func (e *encoder) writeIDATs() {
-	if e.err != nil {
-		return
-	}
-	var bw *bufio.Writer
-	bw = bufio.NewWriterSize(e, 1<<15)
-	e.err = writeImage(bw, e.m, e.cb)
-	if e.err != nil {
-		return
-	}
-	e.err = bw.Flush()
-}
-
-func (e *encoder) writeIEND() { e.writeChunk(nil, "IEND") }
-
-// Encode writes the Image m to w in PNG format. Any Image may be encoded, but
-// images that are not image.NRGBA might be encoded lossily.
-func Encode(w io.Writer, m image.Image) error {
-	// Obviously, negative widths and heights are invalid. Furthermore, the PNG
-	// spec section 11.2.2 says that zero is invalid. Excessively large images are
-	// also rejected.
-	mw, mh := int64(m.Bounds().Dx()), int64(m.Bounds().Dy())
-	if mw <= 0 || mh <= 0 || mw >= 1<<32 || mh >= 1<<32 {
-		return FormatError("invalid image size: " + strconv.FormatInt(mw, 10) + "x" + strconv.FormatInt(mh, 10))
-	}
-
-	var e encoder
-	e.w = w
-	e.m = m
-
-	var pal color.Palette
-	// cbP8 encoding needs PalettedImage's ColorIndexAt method.
-	if _, ok := m.(image.PalettedImage); ok {
-		pal, _ = m.ColorModel().(color.Palette)
-	}
-	if pal != nil {
-		e.cb = cbP8
-	} else {
-		switch m.ColorModel() {
-		case color.GrayModel:
-			e.cb = cbG8
-		case color.Gray16Model:
-			e.cb = cbG16
-		case color.RGBAModel, color.NRGBAModel, color.AlphaModel:
-			if opaque(m) {
-				e.cb = cbTC8
-			} else {
-				e.cb = cbTCA8
-			}
-		default:
-			if opaque(m) {
-				e.cb = cbTC16
-			} else {
-				e.cb = cbTCA16
-			}
-		}
-	}
-
-	_, e.err = io.WriteString(w, pngHeader)
-	e.writeIHDR()
-	if pal != nil {
-		e.writePLTEAndTRNS(pal)
-	}
-	e.writeIDATs()
-	e.writeIEND()
-	return e.err
-}
diff --git a/src/pkg/image/png/writer_test.go b/src/pkg/image/png/writer_test.go
deleted file mode 100644
index 3116fc9..0000000
--- a/src/pkg/image/png/writer_test.go
+++ /dev/null
@@ -1,191 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package png
-
-import (
-	"bytes"
-	"fmt"
-	"image"
-	"image/color"
-	"io/ioutil"
-	"testing"
-)
-
-func diff(m0, m1 image.Image) error {
-	b0, b1 := m0.Bounds(), m1.Bounds()
-	if !b0.Size().Eq(b1.Size()) {
-		return fmt.Errorf("dimensions differ: %v vs %v", b0, b1)
-	}
-	dx := b1.Min.X - b0.Min.X
-	dy := b1.Min.Y - b0.Min.Y
-	for y := b0.Min.Y; y < b0.Max.Y; y++ {
-		for x := b0.Min.X; x < b0.Max.X; x++ {
-			c0 := m0.At(x, y)
-			c1 := m1.At(x+dx, y+dy)
-			r0, g0, b0, a0 := c0.RGBA()
-			r1, g1, b1, a1 := c1.RGBA()
-			if r0 != r1 || g0 != g1 || b0 != b1 || a0 != a1 {
-				return fmt.Errorf("colors differ at (%d, %d): %v vs %v", x, y, c0, c1)
-			}
-		}
-	}
-	return nil
-}
-
-func encodeDecode(m image.Image) (image.Image, error) {
-	var b bytes.Buffer
-	err := Encode(&b, m)
-	if err != nil {
-		return nil, err
-	}
-	m, err = Decode(&b)
-	if err != nil {
-		return nil, err
-	}
-	return m, nil
-}
-
-func TestWriter(t *testing.T) {
-	// The filenames variable is declared in reader_test.go.
-	names := filenames
-	if testing.Short() {
-		names = filenamesShort
-	}
-	for _, fn := range names {
-		qfn := "testdata/pngsuite/" + fn + ".png"
-		// Read the image.
-		m0, err := readPNG(qfn)
-		if err != nil {
-			t.Error(fn, err)
-			continue
-		}
-		// Read the image again, encode it, and decode it.
-		m1, err := readPNG(qfn)
-		if err != nil {
-			t.Error(fn, err)
-			return
-		}
-		m2, err := encodeDecode(m1)
-		if err != nil {
-			t.Error(fn, err)
-			return
-		}
-		// Compare the two.
-		err = diff(m0, m2)
-		if err != nil {
-			t.Error(fn, err)
-			continue
-		}
-	}
-}
-
-func TestSubImage(t *testing.T) {
-	m0 := image.NewRGBA(image.Rect(0, 0, 256, 256))
-	for y := 0; y < 256; y++ {
-		for x := 0; x < 256; x++ {
-			m0.Set(x, y, color.RGBA{uint8(x), uint8(y), 0, 255})
-		}
-	}
-	m0 = m0.SubImage(image.Rect(50, 30, 250, 130)).(*image.RGBA)
-	m1, err := encodeDecode(m0)
-	if err != nil {
-		t.Error(err)
-		return
-	}
-	err = diff(m0, m1)
-	if err != nil {
-		t.Error(err)
-		return
-	}
-}
-
-func BenchmarkEncodeGray(b *testing.B) {
-	b.StopTimer()
-	img := image.NewGray(image.Rect(0, 0, 640, 480))
-	b.SetBytes(640 * 480 * 1)
-	b.StartTimer()
-	for i := 0; i < b.N; i++ {
-		Encode(ioutil.Discard, img)
-	}
-}
-
-func BenchmarkEncodeNRGBOpaque(b *testing.B) {
-	b.StopTimer()
-	img := image.NewNRGBA(image.Rect(0, 0, 640, 480))
-	// Set all pixels to 0xFF alpha to force opaque mode.
-	bo := img.Bounds()
-	for y := bo.Min.Y; y < bo.Max.Y; y++ {
-		for x := bo.Min.X; x < bo.Max.X; x++ {
-			img.Set(x, y, color.NRGBA{0, 0, 0, 255})
-		}
-	}
-	if !img.Opaque() {
-		b.Fatal("expected image to be opaque")
-	}
-	b.SetBytes(640 * 480 * 4)
-	b.StartTimer()
-	for i := 0; i < b.N; i++ {
-		Encode(ioutil.Discard, img)
-	}
-}
-
-func BenchmarkEncodeNRGBA(b *testing.B) {
-	b.StopTimer()
-	img := image.NewNRGBA(image.Rect(0, 0, 640, 480))
-	if img.Opaque() {
-		b.Fatal("expected image not to be opaque")
-	}
-	b.SetBytes(640 * 480 * 4)
-	b.StartTimer()
-	for i := 0; i < b.N; i++ {
-		Encode(ioutil.Discard, img)
-	}
-}
-
-func BenchmarkEncodePaletted(b *testing.B) {
-	b.StopTimer()
-	img := image.NewPaletted(image.Rect(0, 0, 640, 480), color.Palette{
-		color.RGBA{0, 0, 0, 255},
-		color.RGBA{255, 255, 255, 255},
-	})
-	b.SetBytes(640 * 480 * 1)
-	b.StartTimer()
-	for i := 0; i < b.N; i++ {
-		Encode(ioutil.Discard, img)
-	}
-}
-
-func BenchmarkEncodeRGBOpaque(b *testing.B) {
-	b.StopTimer()
-	img := image.NewRGBA(image.Rect(0, 0, 640, 480))
-	// Set all pixels to 0xFF alpha to force opaque mode.
-	bo := img.Bounds()
-	for y := bo.Min.Y; y < bo.Max.Y; y++ {
-		for x := bo.Min.X; x < bo.Max.X; x++ {
-			img.Set(x, y, color.RGBA{0, 0, 0, 255})
-		}
-	}
-	if !img.Opaque() {
-		b.Fatal("expected image to be opaque")
-	}
-	b.SetBytes(640 * 480 * 4)
-	b.StartTimer()
-	for i := 0; i < b.N; i++ {
-		Encode(ioutil.Discard, img)
-	}
-}
-
-func BenchmarkEncodeRGBA(b *testing.B) {
-	b.StopTimer()
-	img := image.NewRGBA(image.Rect(0, 0, 640, 480))
-	if img.Opaque() {
-		b.Fatal("expected image not to be opaque")
-	}
-	b.SetBytes(640 * 480 * 4)
-	b.StartTimer()
-	for i := 0; i < b.N; i++ {
-		Encode(ioutil.Discard, img)
-	}
-}
diff --git a/src/pkg/image/ycbcr.go b/src/pkg/image/ycbcr.go
deleted file mode 100644
index 5b73bef..0000000
--- a/src/pkg/image/ycbcr.go
+++ /dev/null
@@ -1,153 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package image
-
-import (
-	"image/color"
-)
-
-// YCbCrSubsampleRatio is the chroma subsample ratio used in a YCbCr image.
-type YCbCrSubsampleRatio int
-
-const (
-	YCbCrSubsampleRatio444 YCbCrSubsampleRatio = iota
-	YCbCrSubsampleRatio422
-	YCbCrSubsampleRatio420
-	YCbCrSubsampleRatio440
-)
-
-func (s YCbCrSubsampleRatio) String() string {
-	switch s {
-	case YCbCrSubsampleRatio444:
-		return "YCbCrSubsampleRatio444"
-	case YCbCrSubsampleRatio422:
-		return "YCbCrSubsampleRatio422"
-	case YCbCrSubsampleRatio420:
-		return "YCbCrSubsampleRatio420"
-	case YCbCrSubsampleRatio440:
-		return "YCbCrSubsampleRatio440"
-	}
-	return "YCbCrSubsampleRatioUnknown"
-}
-
-// YCbCr is an in-memory image of Y'CbCr colors. There is one Y sample per
-// pixel, but each Cb and Cr sample can span one or more pixels.
-// YStride is the Y slice index delta between vertically adjacent pixels.
-// CStride is the Cb and Cr slice index delta between vertically adjacent pixels
-// that map to separate chroma samples.
-// It is not an absolute requirement, but YStride and len(Y) are typically
-// multiples of 8, and:
-//	For 4:4:4, CStride == YStride/1 && len(Cb) == len(Cr) == len(Y)/1.
-//	For 4:2:2, CStride == YStride/2 && len(Cb) == len(Cr) == len(Y)/2.
-//	For 4:2:0, CStride == YStride/2 && len(Cb) == len(Cr) == len(Y)/4.
-//	For 4:4:0, CStride == YStride/1 && len(Cb) == len(Cr) == len(Y)/2.
-type YCbCr struct {
-	Y, Cb, Cr      []uint8
-	YStride        int
-	CStride        int
-	SubsampleRatio YCbCrSubsampleRatio
-	Rect           Rectangle
-}
-
-func (p *YCbCr) ColorModel() color.Model {
-	return color.YCbCrModel
-}
-
-func (p *YCbCr) Bounds() Rectangle {
-	return p.Rect
-}
-
-func (p *YCbCr) At(x, y int) color.Color {
-	if !(Point{x, y}.In(p.Rect)) {
-		return color.YCbCr{}
-	}
-	yi := p.YOffset(x, y)
-	ci := p.COffset(x, y)
-	return color.YCbCr{
-		p.Y[yi],
-		p.Cb[ci],
-		p.Cr[ci],
-	}
-}
-
-// YOffset returns the index of the first element of Y that corresponds to
-// the pixel at (x, y).
-func (p *YCbCr) YOffset(x, y int) int {
-	return (y-p.Rect.Min.Y)*p.YStride + (x - p.Rect.Min.X)
-}
-
-// COffset returns the index of the first element of Cb or Cr that corresponds
-// to the pixel at (x, y).
-func (p *YCbCr) COffset(x, y int) int {
-	switch p.SubsampleRatio {
-	case YCbCrSubsampleRatio422:
-		return (y-p.Rect.Min.Y)*p.CStride + (x/2 - p.Rect.Min.X/2)
-	case YCbCrSubsampleRatio420:
-		return (y/2-p.Rect.Min.Y/2)*p.CStride + (x/2 - p.Rect.Min.X/2)
-	case YCbCrSubsampleRatio440:
-		return (y/2-p.Rect.Min.Y/2)*p.CStride + (x - p.Rect.Min.X)
-	}
-	// Default to 4:4:4 subsampling.
-	return (y-p.Rect.Min.Y)*p.CStride + (x - p.Rect.Min.X)
-}
-
-// SubImage returns an image representing the portion of the image p visible
-// through r. The returned value shares pixels with the original image.
-func (p *YCbCr) SubImage(r Rectangle) Image {
-	r = r.Intersect(p.Rect)
-	// If r1 and r2 are Rectangles, r1.Intersect(r2) is not guaranteed to be inside
-	// either r1 or r2 if the intersection is empty. Without explicitly checking for
-	// this, the Pix[i:] expression below can panic.
-	if r.Empty() {
-		return &YCbCr{
-			SubsampleRatio: p.SubsampleRatio,
-		}
-	}
-	yi := p.YOffset(r.Min.X, r.Min.Y)
-	ci := p.COffset(r.Min.X, r.Min.Y)
-	return &YCbCr{
-		Y:              p.Y[yi:],
-		Cb:             p.Cb[ci:],
-		Cr:             p.Cr[ci:],
-		SubsampleRatio: p.SubsampleRatio,
-		YStride:        p.YStride,
-		CStride:        p.CStride,
-		Rect:           r,
-	}
-}
-
-func (p *YCbCr) Opaque() bool {
-	return true
-}
-
-// NewYCbCr returns a new YCbCr with the given bounds and subsample ratio.
-func NewYCbCr(r Rectangle, subsampleRatio YCbCrSubsampleRatio) *YCbCr {
-	w, h, cw, ch := r.Dx(), r.Dy(), 0, 0
-	switch subsampleRatio {
-	case YCbCrSubsampleRatio422:
-		cw = (r.Max.X+1)/2 - r.Min.X/2
-		ch = h
-	case YCbCrSubsampleRatio420:
-		cw = (r.Max.X+1)/2 - r.Min.X/2
-		ch = (r.Max.Y+1)/2 - r.Min.Y/2
-	case YCbCrSubsampleRatio440:
-		cw = w
-		ch = (r.Max.Y+1)/2 - r.Min.Y/2
-	default:
-		// Default to 4:4:4 subsampling.
-		cw = w
-		ch = h
-	}
-	b := make([]byte, w*h+2*cw*ch)
-	return &YCbCr{
-		Y:              b[:w*h],
-		Cb:             b[w*h+0*cw*ch : w*h+1*cw*ch],
-		Cr:             b[w*h+1*cw*ch : w*h+2*cw*ch],
-		SubsampleRatio: subsampleRatio,
-		YStride:        w,
-		CStride:        cw,
-		Rect:           r,
-	}
-}
diff --git a/src/pkg/index/suffixarray/suffixarray_test.go b/src/pkg/index/suffixarray/suffixarray_test.go
deleted file mode 100644
index df3e449..0000000
--- a/src/pkg/index/suffixarray/suffixarray_test.go
+++ /dev/null
@@ -1,304 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package suffixarray
-
-import (
-	"bytes"
-	"math/rand"
-	"regexp"
-	"sort"
-	"strings"
-	"testing"
-)
-
-type testCase struct {
-	name     string   // name of test case
-	source   string   // source to index
-	patterns []string // patterns to lookup
-}
-
-var testCases = []testCase{
-	{
-		"empty string",
-		"",
-		[]string{
-			"",
-			"foo",
-			"(foo)",
-			".*",
-			"a*",
-		},
-	},
-
-	{
-		"all a's",
-		"aaaaaaaaaa", // 10 a's
-		[]string{
-			"",
-			"a",
-			"aa",
-			"aaa",
-			"aaaa",
-			"aaaaa",
-			"aaaaaa",
-			"aaaaaaa",
-			"aaaaaaaa",
-			"aaaaaaaaa",
-			"aaaaaaaaaa",
-			"aaaaaaaaaaa", // 11 a's
-			".",
-			".*",
-			"a+",
-			"aa+",
-			"aaaa[b]?",
-			"aaa*",
-		},
-	},
-
-	{
-		"abc",
-		"abc",
-		[]string{
-			"a",
-			"b",
-			"c",
-			"ab",
-			"bc",
-			"abc",
-			"a.c",
-			"a(b|c)",
-			"abc?",
-		},
-	},
-
-	{
-		"barbara*3",
-		"barbarabarbarabarbara",
-		[]string{
-			"a",
-			"bar",
-			"rab",
-			"arab",
-			"barbar",
-			"bara?bar",
-		},
-	},
-
-	{
-		"typing drill",
-		"Now is the time for all good men to come to the aid of their country.",
-		[]string{
-			"Now",
-			"the time",
-			"to come the aid",
-			"is the time for all good men to come to the aid of their",
-			"to (come|the)?",
-		},
-	},
-
-	{
-		"godoc simulation",
-		"package main\n\nimport(\n    \"rand\"\n    ",
-		[]string{},
-	},
-}
-
-// find all occurrences of s in source; report at most n occurrences
-func find(src, s string, n int) []int {
-	var res []int
-	if s != "" && n != 0 {
-		// find at most n occurrences of s in src
-		for i := -1; n < 0 || len(res) < n; {
-			j := strings.Index(src[i+1:], s)
-			if j < 0 {
-				break
-			}
-			i += j + 1
-			res = append(res, i)
-		}
-	}
-	return res
-}
-
-func testLookup(t *testing.T, tc *testCase, x *Index, s string, n int) {
-	res := x.Lookup([]byte(s), n)
-	exp := find(tc.source, s, n)
-
-	// check that the lengths match
-	if len(res) != len(exp) {
-		t.Errorf("test %q, lookup %q (n = %d): expected %d results; got %d", tc.name, s, n, len(exp), len(res))
-	}
-
-	// if n >= 0 the number of results is limited --- unless n >= all results,
-	// we may obtain different positions from the Index and from find (because
-	// Index may not find the results in the same order as find) => in general
-	// we cannot simply check that the res and exp lists are equal
-
-	// check that each result is in fact a correct match and there are no duplicates
-	sort.Ints(res)
-	for i, r := range res {
-		if r < 0 || len(tc.source) <= r {
-			t.Errorf("test %q, lookup %q, result %d (n = %d): index %d out of range [0, %d[", tc.name, s, i, n, r, len(tc.source))
-		} else if !strings.HasPrefix(tc.source[r:], s) {
-			t.Errorf("test %q, lookup %q, result %d (n = %d): index %d not a match", tc.name, s, i, n, r)
-		}
-		if i > 0 && res[i-1] == r {
-			t.Errorf("test %q, lookup %q, result %d (n = %d): found duplicate index %d", tc.name, s, i, n, r)
-		}
-	}
-
-	if n < 0 {
-		// all results computed - sorted res and exp must be equal
-		for i, r := range res {
-			e := exp[i]
-			if r != e {
-				t.Errorf("test %q, lookup %q, result %d: expected index %d; got %d", tc.name, s, i, e, r)
-			}
-		}
-	}
-}
-
-func testFindAllIndex(t *testing.T, tc *testCase, x *Index, rx *regexp.Regexp, n int) {
-	res := x.FindAllIndex(rx, n)
-	exp := rx.FindAllStringIndex(tc.source, n)
-
-	// check that the lengths match
-	if len(res) != len(exp) {
-		t.Errorf("test %q, FindAllIndex %q (n = %d): expected %d results; got %d", tc.name, rx, n, len(exp), len(res))
-	}
-
-	// if n >= 0 the number of results is limited --- unless n >= all results,
-	// we may obtain different positions from the Index and from regexp (because
-	// Index may not find the results in the same order as regexp) => in general
-	// we cannot simply check that the res and exp lists are equal
-
-	// check that each result is in fact a correct match and the result is sorted
-	for i, r := range res {
-		if r[0] < 0 || r[0] > r[1] || len(tc.source) < r[1] {
-			t.Errorf("test %q, FindAllIndex %q, result %d (n == %d): illegal match [%d, %d]", tc.name, rx, i, n, r[0], r[1])
-		} else if !rx.MatchString(tc.source[r[0]:r[1]]) {
-			t.Errorf("test %q, FindAllIndex %q, result %d (n = %d): [%d, %d] not a match", tc.name, rx, i, n, r[0], r[1])
-		}
-	}
-
-	if n < 0 {
-		// all results computed - sorted res and exp must be equal
-		for i, r := range res {
-			e := exp[i]
-			if r[0] != e[0] || r[1] != e[1] {
-				t.Errorf("test %q, FindAllIndex %q, result %d: expected match [%d, %d]; got [%d, %d]",
-					tc.name, rx, i, e[0], e[1], r[0], r[1])
-			}
-		}
-	}
-}
-
-func testLookups(t *testing.T, tc *testCase, x *Index, n int) {
-	for _, pat := range tc.patterns {
-		testLookup(t, tc, x, pat, n)
-		if rx, err := regexp.Compile(pat); err == nil {
-			testFindAllIndex(t, tc, x, rx, n)
-		}
-	}
-}
-
-// index is used to hide the sort.Interface
-type index Index
-
-func (x *index) Len() int           { return len(x.sa) }
-func (x *index) Less(i, j int) bool { return bytes.Compare(x.at(i), x.at(j)) < 0 }
-func (x *index) Swap(i, j int)      { x.sa[i], x.sa[j] = x.sa[j], x.sa[i] }
-func (a *index) at(i int) []byte    { return a.data[a.sa[i]:] }
-
-func testConstruction(t *testing.T, tc *testCase, x *Index) {
-	if !sort.IsSorted((*index)(x)) {
-		t.Errorf("failed testConstruction %s", tc.name)
-	}
-}
-
-func equal(x, y *Index) bool {
-	if !bytes.Equal(x.data, y.data) {
-		return false
-	}
-	for i, j := range x.sa {
-		if j != y.sa[i] {
-			return false
-		}
-	}
-	return true
-}
-
-// returns the serialized index size
-func testSaveRestore(t *testing.T, tc *testCase, x *Index) int {
-	var buf bytes.Buffer
-	if err := x.Write(&buf); err != nil {
-		t.Errorf("failed writing index %s (%s)", tc.name, err)
-	}
-	size := buf.Len()
-	var y Index
-	if err := y.Read(&buf); err != nil {
-		t.Errorf("failed reading index %s (%s)", tc.name, err)
-	}
-	if !equal(x, &y) {
-		t.Errorf("restored index doesn't match saved index %s", tc.name)
-	}
-	return size
-}
-
-func TestIndex(t *testing.T) {
-	for _, tc := range testCases {
-		x := New([]byte(tc.source))
-		testConstruction(t, &tc, x)
-		testSaveRestore(t, &tc, x)
-		testLookups(t, &tc, x, 0)
-		testLookups(t, &tc, x, 1)
-		testLookups(t, &tc, x, 10)
-		testLookups(t, &tc, x, 2e9)
-		testLookups(t, &tc, x, -1)
-	}
-}
-
-// Of all possible inputs, the random bytes have the least amount of substring
-// repetition, and the repeated bytes have the most. For most algorithms,
-// the running time of every input will be between these two.
-func benchmarkNew(b *testing.B, random bool) {
-	b.StopTimer()
-	data := make([]byte, 1e6)
-	if random {
-		for i := range data {
-			data[i] = byte(rand.Intn(256))
-		}
-	}
-	b.StartTimer()
-	for i := 0; i < b.N; i++ {
-		New(data)
-	}
-}
-
-func BenchmarkNewIndexRandom(b *testing.B) {
-	benchmarkNew(b, true)
-}
-func BenchmarkNewIndexRepeat(b *testing.B) {
-	benchmarkNew(b, false)
-}
-
-func BenchmarkSaveRestore(b *testing.B) {
-	b.StopTimer()
-	r := rand.New(rand.NewSource(0x5a77a1)) // guarantee always same sequence
-	data := make([]byte, 10<<20)            // 10MB of data to index
-	for i := range data {
-		data[i] = byte(r.Intn(256))
-	}
-	x := New(data)
-	size := testSaveRestore(nil, nil, x)       // verify correctness
-	buf := bytes.NewBuffer(make([]byte, size)) // avoid growing
-	b.SetBytes(int64(size))
-	b.StartTimer()
-	for i := 0; i < b.N; i++ {
-		x.Write(buf)
-		var y Index
-		y.Read(buf)
-	}
-}
diff --git a/src/pkg/io/io.go b/src/pkg/io/io.go
deleted file mode 100644
index 022fdb6..0000000
--- a/src/pkg/io/io.go
+++ /dev/null
@@ -1,493 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package io provides basic interfaces to I/O primitives.
-// Its primary job is to wrap existing implementations of such primitives,
-// such as those in package os, into shared public interfaces that
-// abstract the functionality, plus some other related primitives.
-//
-// Because these interfaces and primitives wrap lower-level operations with
-// various implementations, unless otherwise informed clients should not
-// assume they are safe for parallel execution.
-package io
-
-import (
-	"errors"
-)
-
-// ErrShortWrite means that a write accepted fewer bytes than requested
-// but failed to return an explicit error.
-var ErrShortWrite = errors.New("short write")
-
-// ErrShortBuffer means that a read required a longer buffer than was provided.
-var ErrShortBuffer = errors.New("short buffer")
-
-// EOF is the error returned by Read when no more input is available.
-// Functions should return EOF only to signal a graceful end of input.
-// If the EOF occurs unexpectedly in a structured data stream,
-// the appropriate error is either ErrUnexpectedEOF or some other error
-// giving more detail.
-var EOF = errors.New("EOF")
-
-// ErrUnexpectedEOF means that EOF was encountered in the
-// middle of reading a fixed-size block or data structure.
-var ErrUnexpectedEOF = errors.New("unexpected EOF")
-
-// ErrNoProgress is returned by some clients of an io.Reader when
-// many calls to Read have failed to return any data or error,
-// usually the sign of a broken io.Reader implementation.
-var ErrNoProgress = errors.New("multiple Read calls return no data or error")
-
-// Reader is the interface that wraps the basic Read method.
-//
-// Read reads up to len(p) bytes into p.  It returns the number of bytes
-// read (0 <= n <= len(p)) and any error encountered.  Even if Read
-// returns n < len(p), it may use all of p as scratch space during the call.
-// If some data is available but not len(p) bytes, Read conventionally
-// returns what is available instead of waiting for more.
-//
-// When Read encounters an error or end-of-file condition after
-// successfully reading n > 0 bytes, it returns the number of
-// bytes read.  It may return the (non-nil) error from the same call
-// or return the error (and n == 0) from a subsequent call.
-// An instance of this general case is that a Reader returning
-// a non-zero number of bytes at the end of the input stream may
-// return either err == EOF or err == nil.  The next Read should
-// return 0, EOF regardless.
-//
-// Callers should always process the n > 0 bytes returned before
-// considering the error err.  Doing so correctly handles I/O errors
-// that happen after reading some bytes and also both of the
-// allowed EOF behaviors.
-//
-// Implementations of Read are discouraged from returning a
-// zero byte count with a nil error, and callers should treat
-// that situation as a no-op.
-type Reader interface {
-	Read(p []byte) (n int, err error)
-}
-
-// Writer is the interface that wraps the basic Write method.
-//
-// Write writes len(p) bytes from p to the underlying data stream.
-// It returns the number of bytes written from p (0 <= n <= len(p))
-// and any error encountered that caused the write to stop early.
-// Write must return a non-nil error if it returns n < len(p).
-// Write must not modify the slice data, even temporarily.
-type Writer interface {
-	Write(p []byte) (n int, err error)
-}
-
-// Closer is the interface that wraps the basic Close method.
-//
-// The behavior of Close after the first call is undefined.
-// Specific implementations may document their own behavior.
-type Closer interface {
-	Close() error
-}
-
-// Seeker is the interface that wraps the basic Seek method.
-//
-// Seek sets the offset for the next Read or Write to offset,
-// interpreted according to whence: 0 means relative to the origin of
-// the file, 1 means relative to the current offset, and 2 means
-// relative to the end.  Seek returns the new offset and an error, if
-// any.
-//
-// Seeking to a negative offset is an error. Seeking to any positive
-// offset is legal, but the behavior of subsequent I/O operations on
-// the underlying object is implementation-dependent.
-type Seeker interface {
-	Seek(offset int64, whence int) (int64, error)
-}
-
-// ReadWriter is the interface that groups the basic Read and Write methods.
-type ReadWriter interface {
-	Reader
-	Writer
-}
-
-// ReadCloser is the interface that groups the basic Read and Close methods.
-type ReadCloser interface {
-	Reader
-	Closer
-}
-
-// WriteCloser is the interface that groups the basic Write and Close methods.
-type WriteCloser interface {
-	Writer
-	Closer
-}
-
-// ReadWriteCloser is the interface that groups the basic Read, Write and Close methods.
-type ReadWriteCloser interface {
-	Reader
-	Writer
-	Closer
-}
-
-// ReadSeeker is the interface that groups the basic Read and Seek methods.
-type ReadSeeker interface {
-	Reader
-	Seeker
-}
-
-// WriteSeeker is the interface that groups the basic Write and Seek methods.
-type WriteSeeker interface {
-	Writer
-	Seeker
-}
-
-// ReadWriteSeeker is the interface that groups the basic Read, Write and Seek methods.
-type ReadWriteSeeker interface {
-	Reader
-	Writer
-	Seeker
-}
-
-// ReaderFrom is the interface that wraps the ReadFrom method.
-//
-// ReadFrom reads data from r until EOF or error.
-// The return value n is the number of bytes read.
-// Any error except io.EOF encountered during the read is also returned.
-//
-// The Copy function uses ReaderFrom if available.
-type ReaderFrom interface {
-	ReadFrom(r Reader) (n int64, err error)
-}
-
-// WriterTo is the interface that wraps the WriteTo method.
-//
-// WriteTo writes data to w until there's no more data to write or
-// when an error occurs. The return value n is the number of bytes
-// written. Any error encountered during the write is also returned.
-//
-// The Copy function uses WriterTo if available.
-type WriterTo interface {
-	WriteTo(w Writer) (n int64, err error)
-}
-
-// ReaderAt is the interface that wraps the basic ReadAt method.
-//
-// ReadAt reads len(p) bytes into p starting at offset off in the
-// underlying input source.  It returns the number of bytes
-// read (0 <= n <= len(p)) and any error encountered.
-//
-// When ReadAt returns n < len(p), it returns a non-nil error
-// explaining why more bytes were not returned.  In this respect,
-// ReadAt is stricter than Read.
-//
-// Even if ReadAt returns n < len(p), it may use all of p as scratch
-// space during the call.  If some data is available but not len(p) bytes,
-// ReadAt blocks until either all the data is available or an error occurs.
-// In this respect ReadAt is different from Read.
-//
-// If the n = len(p) bytes returned by ReadAt are at the end of the
-// input source, ReadAt may return either err == EOF or err == nil.
-//
-// If ReadAt is reading from an input source with a seek offset,
-// ReadAt should not affect nor be affected by the underlying
-// seek offset.
-//
-// Clients of ReadAt can execute parallel ReadAt calls on the
-// same input source.
-type ReaderAt interface {
-	ReadAt(p []byte, off int64) (n int, err error)
-}
-
-// WriterAt is the interface that wraps the basic WriteAt method.
-//
-// WriteAt writes len(p) bytes from p to the underlying data stream
-// at offset off.  It returns the number of bytes written from p (0 <= n <= len(p))
-// and any error encountered that caused the write to stop early.
-// WriteAt must return a non-nil error if it returns n < len(p).
-//
-// If WriteAt is writing to a destination with a seek offset,
-// WriteAt should not affect nor be affected by the underlying
-// seek offset.
-//
-// Clients of WriteAt can execute parallel WriteAt calls on the same
-// destination if the ranges do not overlap.
-type WriterAt interface {
-	WriteAt(p []byte, off int64) (n int, err error)
-}
-
-// ByteReader is the interface that wraps the ReadByte method.
-//
-// ReadByte reads and returns the next byte from the input.
-// If no byte is available, err will be set.
-type ByteReader interface {
-	ReadByte() (c byte, err error)
-}
-
-// ByteScanner is the interface that adds the UnreadByte method to the
-// basic ReadByte method.
-//
-// UnreadByte causes the next call to ReadByte to return the same byte
-// as the previous call to ReadByte.
-// It may be an error to call UnreadByte twice without an intervening
-// call to ReadByte.
-type ByteScanner interface {
-	ByteReader
-	UnreadByte() error
-}
-
-// ByteWriter is the interface that wraps the WriteByte method.
-type ByteWriter interface {
-	WriteByte(c byte) error
-}
-
-// RuneReader is the interface that wraps the ReadRune method.
-//
-// ReadRune reads a single UTF-8 encoded Unicode character
-// and returns the rune and its size in bytes. If no character is
-// available, err will be set.
-type RuneReader interface {
-	ReadRune() (r rune, size int, err error)
-}
-
-// RuneScanner is the interface that adds the UnreadRune method to the
-// basic ReadRune method.
-//
-// UnreadRune causes the next call to ReadRune to return the same rune
-// as the previous call to ReadRune.
-// It may be an error to call UnreadRune twice without an intervening
-// call to ReadRune.
-type RuneScanner interface {
-	RuneReader
-	UnreadRune() error
-}
-
-// stringWriter is the interface that wraps the WriteString method.
-type stringWriter interface {
-	WriteString(s string) (n int, err error)
-}
-
-// WriteString writes the contents of the string s to w, which accepts an array of bytes.
-// If w already implements a WriteString method, it is invoked directly.
-func WriteString(w Writer, s string) (n int, err error) {
-	if sw, ok := w.(stringWriter); ok {
-		return sw.WriteString(s)
-	}
-	return w.Write([]byte(s))
-}
-
-// ReadAtLeast reads from r into buf until it has read at least min bytes.
-// It returns the number of bytes copied and an error if fewer bytes were read.
-// The error is EOF only if no bytes were read.
-// If an EOF happens after reading fewer than min bytes,
-// ReadAtLeast returns ErrUnexpectedEOF.
-// If min is greater than the length of buf, ReadAtLeast returns ErrShortBuffer.
-// On return, n >= min if and only if err == nil.
-func ReadAtLeast(r Reader, buf []byte, min int) (n int, err error) {
-	if len(buf) < min {
-		return 0, ErrShortBuffer
-	}
-	for n < min && err == nil {
-		var nn int
-		nn, err = r.Read(buf[n:])
-		n += nn
-	}
-	if n >= min {
-		err = nil
-	} else if n > 0 && err == EOF {
-		err = ErrUnexpectedEOF
-	}
-	return
-}
-
-// ReadFull reads exactly len(buf) bytes from r into buf.
-// It returns the number of bytes copied and an error if fewer bytes were read.
-// The error is EOF only if no bytes were read.
-// If an EOF happens after reading some but not all the bytes,
-// ReadFull returns ErrUnexpectedEOF.
-// On return, n == len(buf) if and only if err == nil.
-func ReadFull(r Reader, buf []byte) (n int, err error) {
-	return ReadAtLeast(r, buf, len(buf))
-}
-
-// CopyN copies n bytes (or until an error) from src to dst.
-// It returns the number of bytes copied and the earliest
-// error encountered while copying.
-// On return, written == n if and only if err == nil.
-//
-// If dst implements the ReaderFrom interface,
-// the copy is implemented using it.
-func CopyN(dst Writer, src Reader, n int64) (written int64, err error) {
-	written, err = Copy(dst, LimitReader(src, n))
-	if written == n {
-		return n, nil
-	}
-	if written < n && err == nil {
-		// src stopped early; must have been EOF.
-		err = EOF
-	}
-	return
-}
-
-// Copy copies from src to dst until either EOF is reached
-// on src or an error occurs.  It returns the number of bytes
-// copied and the first error encountered while copying, if any.
-//
-// A successful Copy returns err == nil, not err == EOF.
-// Because Copy is defined to read from src until EOF, it does
-// not treat an EOF from Read as an error to be reported.
-//
-// If src implements the WriterTo interface,
-// the copy is implemented by calling src.WriteTo(dst).
-// Otherwise, if dst implements the ReaderFrom interface,
-// the copy is implemented by calling dst.ReadFrom(src).
-func Copy(dst Writer, src Reader) (written int64, err error) {
-	// If the reader has a WriteTo method, use it to do the copy.
-	// Avoids an allocation and a copy.
-	if wt, ok := src.(WriterTo); ok {
-		return wt.WriteTo(dst)
-	}
-	// Similarly, if the writer has a ReadFrom method, use it to do the copy.
-	if rt, ok := dst.(ReaderFrom); ok {
-		return rt.ReadFrom(src)
-	}
-	buf := make([]byte, 32*1024)
-	for {
-		nr, er := src.Read(buf)
-		if nr > 0 {
-			nw, ew := dst.Write(buf[0:nr])
-			if nw > 0 {
-				written += int64(nw)
-			}
-			if ew != nil {
-				err = ew
-				break
-			}
-			if nr != nw {
-				err = ErrShortWrite
-				break
-			}
-		}
-		if er == EOF {
-			break
-		}
-		if er != nil {
-			err = er
-			break
-		}
-	}
-	return written, err
-}
-
-// LimitReader returns a Reader that reads from r
-// but stops with EOF after n bytes.
-// The underlying implementation is a *LimitedReader.
-func LimitReader(r Reader, n int64) Reader { return &LimitedReader{r, n} }
-
-// A LimitedReader reads from R but limits the amount of
-// data returned to just N bytes. Each call to Read
-// updates N to reflect the new amount remaining.
-type LimitedReader struct {
-	R Reader // underlying reader
-	N int64  // max bytes remaining
-}
-
-func (l *LimitedReader) Read(p []byte) (n int, err error) {
-	if l.N <= 0 {
-		return 0, EOF
-	}
-	if int64(len(p)) > l.N {
-		p = p[0:l.N]
-	}
-	n, err = l.R.Read(p)
-	l.N -= int64(n)
-	return
-}
-
-// NewSectionReader returns a SectionReader that reads from r
-// starting at offset off and stops with EOF after n bytes.
-func NewSectionReader(r ReaderAt, off int64, n int64) *SectionReader {
-	return &SectionReader{r, off, off, off + n}
-}
-
-// SectionReader implements Read, Seek, and ReadAt on a section
-// of an underlying ReaderAt.
-type SectionReader struct {
-	r     ReaderAt
-	base  int64
-	off   int64
-	limit int64
-}
-
-func (s *SectionReader) Read(p []byte) (n int, err error) {
-	if s.off >= s.limit {
-		return 0, EOF
-	}
-	if max := s.limit - s.off; int64(len(p)) > max {
-		p = p[0:max]
-	}
-	n, err = s.r.ReadAt(p, s.off)
-	s.off += int64(n)
-	return
-}
-
-var errWhence = errors.New("Seek: invalid whence")
-var errOffset = errors.New("Seek: invalid offset")
-
-func (s *SectionReader) Seek(offset int64, whence int) (int64, error) {
-	switch whence {
-	default:
-		return 0, errWhence
-	case 0:
-		offset += s.base
-	case 1:
-		offset += s.off
-	case 2:
-		offset += s.limit
-	}
-	if offset < s.base {
-		return 0, errOffset
-	}
-	s.off = offset
-	return offset - s.base, nil
-}
-
-func (s *SectionReader) ReadAt(p []byte, off int64) (n int, err error) {
-	if off < 0 || off >= s.limit-s.base {
-		return 0, EOF
-	}
-	off += s.base
-	if max := s.limit - off; int64(len(p)) > max {
-		p = p[0:max]
-		n, err = s.r.ReadAt(p, off)
-		if err == nil {
-			err = EOF
-		}
-		return n, err
-	}
-	return s.r.ReadAt(p, off)
-}
-
-// Size returns the size of the section in bytes.
-func (s *SectionReader) Size() int64 { return s.limit - s.base }
-
-// TeeReader returns a Reader that writes to w what it reads from r.
-// All reads from r performed through it are matched with
-// corresponding writes to w.  There is no internal buffering -
-// the write must complete before the read completes.
-// Any error encountered while writing is reported as a read error.
-func TeeReader(r Reader, w Writer) Reader {
-	return &teeReader{r, w}
-}
-
-type teeReader struct {
-	r Reader
-	w Writer
-}
-
-func (t *teeReader) Read(p []byte) (n int, err error) {
-	n, err = t.r.Read(p)
-	if n > 0 {
-		if n, err := t.w.Write(p[:n]); err != nil {
-			return n, err
-		}
-	}
-	return
-}
diff --git a/src/pkg/log/syslog/syslog_test.go b/src/pkg/log/syslog/syslog_test.go
deleted file mode 100644
index 24a460f..0000000
--- a/src/pkg/log/syslog/syslog_test.go
+++ /dev/null
@@ -1,358 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build !windows,!nacl,!plan9
-
-package syslog
-
-import (
-	"bufio"
-	"fmt"
-	"io"
-	"io/ioutil"
-	"log"
-	"net"
-	"os"
-	"sync"
-	"testing"
-	"time"
-)
-
-func runPktSyslog(c net.PacketConn, done chan<- string) {
-	var buf [4096]byte
-	var rcvd string
-	ct := 0
-	for {
-		var n int
-		var err error
-
-		c.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
-		n, _, err = c.ReadFrom(buf[:])
-		rcvd += string(buf[:n])
-		if err != nil {
-			if oe, ok := err.(*net.OpError); ok {
-				if ct < 3 && oe.Temporary() {
-					ct++
-					continue
-				}
-			}
-			break
-		}
-	}
-	c.Close()
-	done <- rcvd
-}
-
-var crashy = false
-
-func runStreamSyslog(l net.Listener, done chan<- string, wg *sync.WaitGroup) {
-	for {
-		var c net.Conn
-		var err error
-		if c, err = l.Accept(); err != nil {
-			return
-		}
-		wg.Add(1)
-		go func(c net.Conn) {
-			defer wg.Done()
-			c.SetReadDeadline(time.Now().Add(5 * time.Second))
-			b := bufio.NewReader(c)
-			for ct := 1; !crashy || ct&7 != 0; ct++ {
-				s, err := b.ReadString('\n')
-				if err != nil {
-					break
-				}
-				done <- s
-			}
-			c.Close()
-		}(c)
-	}
-}
-
-func startServer(n, la string, done chan<- string) (addr string, sock io.Closer, wg *sync.WaitGroup) {
-	if n == "udp" || n == "tcp" {
-		la = "127.0.0.1:0"
-	} else {
-		// unix and unixgram: choose an address if none given
-		if la == "" {
-			// use ioutil.TempFile to get a name that is unique
-			f, err := ioutil.TempFile("", "syslogtest")
-			if err != nil {
-				log.Fatal("TempFile: ", err)
-			}
-			f.Close()
-			la = f.Name()
-		}
-		os.Remove(la)
-	}
-
-	wg = new(sync.WaitGroup)
-	if n == "udp" || n == "unixgram" {
-		l, e := net.ListenPacket(n, la)
-		if e != nil {
-			log.Fatalf("startServer failed: %v", e)
-		}
-		addr = l.LocalAddr().String()
-		sock = l
-		wg.Add(1)
-		go func() {
-			defer wg.Done()
-			runPktSyslog(l, done)
-		}()
-	} else {
-		l, e := net.Listen(n, la)
-		if e != nil {
-			log.Fatalf("startServer failed: %v", e)
-		}
-		addr = l.Addr().String()
-		sock = l
-		wg.Add(1)
-		go func() {
-			defer wg.Done()
-			runStreamSyslog(l, done, wg)
-		}()
-	}
-	return
-}
-
-func TestWithSimulated(t *testing.T) {
-	msg := "Test 123"
-	transport := []string{"unix", "unixgram", "udp", "tcp"}
-
-	for _, tr := range transport {
-		done := make(chan string)
-		addr, sock, srvWG := startServer(tr, "", done)
-		defer srvWG.Wait()
-		defer sock.Close()
-		if tr == "unix" || tr == "unixgram" {
-			defer os.Remove(addr)
-		}
-		s, err := Dial(tr, addr, LOG_INFO|LOG_USER, "syslog_test")
-		if err != nil {
-			t.Fatalf("Dial() failed: %v", err)
-		}
-		err = s.Info(msg)
-		if err != nil {
-			t.Fatalf("log failed: %v", err)
-		}
-		check(t, msg, <-done)
-		s.Close()
-	}
-}
-
-func TestFlap(t *testing.T) {
-	net := "unix"
-	done := make(chan string)
-	addr, sock, srvWG := startServer(net, "", done)
-	defer srvWG.Wait()
-	defer os.Remove(addr)
-	defer sock.Close()
-
-	s, err := Dial(net, addr, LOG_INFO|LOG_USER, "syslog_test")
-	if err != nil {
-		t.Fatalf("Dial() failed: %v", err)
-	}
-	msg := "Moo 2"
-	err = s.Info(msg)
-	if err != nil {
-		t.Fatalf("log failed: %v", err)
-	}
-	check(t, msg, <-done)
-
-	// restart the server
-	_, sock2, srvWG2 := startServer(net, addr, done)
-	defer srvWG2.Wait()
-	defer sock2.Close()
-
-	// and try retransmitting
-	msg = "Moo 3"
-	err = s.Info(msg)
-	if err != nil {
-		t.Fatalf("log failed: %v", err)
-	}
-	check(t, msg, <-done)
-
-	s.Close()
-}
-
-func TestNew(t *testing.T) {
-	if LOG_LOCAL7 != 23<<3 {
-		t.Fatalf("LOG_LOCAL7 has wrong value")
-	}
-	if testing.Short() {
-		// Depends on syslog daemon running, and sometimes it's not.
-		t.Skip("skipping syslog test during -short")
-	}
-
-	s, err := New(LOG_INFO|LOG_USER, "the_tag")
-	if err != nil {
-		t.Fatalf("New() failed: %s", err)
-	}
-	// Don't send any messages.
-	s.Close()
-}
-
-func TestNewLogger(t *testing.T) {
-	if testing.Short() {
-		t.Skip("skipping syslog test during -short")
-	}
-	f, err := NewLogger(LOG_USER|LOG_INFO, 0)
-	if f == nil {
-		t.Error(err)
-	}
-}
-
-func TestDial(t *testing.T) {
-	if testing.Short() {
-		t.Skip("skipping syslog test during -short")
-	}
-	f, err := Dial("", "", (LOG_LOCAL7|LOG_DEBUG)+1, "syslog_test")
-	if f != nil {
-		t.Fatalf("Should have trapped bad priority")
-	}
-	f, err = Dial("", "", -1, "syslog_test")
-	if f != nil {
-		t.Fatalf("Should have trapped bad priority")
-	}
-	l, err := Dial("", "", LOG_USER|LOG_ERR, "syslog_test")
-	if err != nil {
-		t.Fatalf("Dial() failed: %s", err)
-	}
-	l.Close()
-}
-
-func check(t *testing.T, in, out string) {
-	tmpl := fmt.Sprintf("<%d>%%s %%s syslog_test[%%d]: %s\n", LOG_USER+LOG_INFO, in)
-	if hostname, err := os.Hostname(); err != nil {
-		t.Error("Error retrieving hostname")
-	} else {
-		var parsedHostname, timestamp string
-		var pid int
-		if n, err := fmt.Sscanf(out, tmpl, &timestamp, &parsedHostname, &pid); n != 3 || err != nil || hostname != parsedHostname {
-			t.Errorf("Got %q, does not match template %q (%d %s)", out, tmpl, n, err)
-		}
-	}
-}
-
-func TestWrite(t *testing.T) {
-	tests := []struct {
-		pri Priority
-		pre string
-		msg string
-		exp string
-	}{
-		{LOG_USER | LOG_ERR, "syslog_test", "", "%s %s syslog_test[%d]: \n"},
-		{LOG_USER | LOG_ERR, "syslog_test", "write test", "%s %s syslog_test[%d]: write test\n"},
-		// Write should not add \n if there already is one
-		{LOG_USER | LOG_ERR, "syslog_test", "write test 2\n", "%s %s syslog_test[%d]: write test 2\n"},
-	}
-
-	if hostname, err := os.Hostname(); err != nil {
-		t.Fatalf("Error retrieving hostname")
-	} else {
-		for _, test := range tests {
-			done := make(chan string)
-			addr, sock, srvWG := startServer("udp", "", done)
-			defer srvWG.Wait()
-			defer sock.Close()
-			l, err := Dial("udp", addr, test.pri, test.pre)
-			if err != nil {
-				t.Fatalf("syslog.Dial() failed: %v", err)
-			}
-			defer l.Close()
-			_, err = io.WriteString(l, test.msg)
-			if err != nil {
-				t.Fatalf("WriteString() failed: %v", err)
-			}
-			rcvd := <-done
-			test.exp = fmt.Sprintf("<%d>", test.pri) + test.exp
-			var parsedHostname, timestamp string
-			var pid int
-			if n, err := fmt.Sscanf(rcvd, test.exp, &timestamp, &parsedHostname, &pid); n != 3 || err != nil || hostname != parsedHostname {
-				t.Errorf("s.Info() = '%q', didn't match '%q' (%d %s)", rcvd, test.exp, n, err)
-			}
-		}
-	}
-}
-
-func TestConcurrentWrite(t *testing.T) {
-	addr, sock, srvWG := startServer("udp", "", make(chan string, 1))
-	defer srvWG.Wait()
-	defer sock.Close()
-	w, err := Dial("udp", addr, LOG_USER|LOG_ERR, "how's it going?")
-	if err != nil {
-		t.Fatalf("syslog.Dial() failed: %v", err)
-	}
-	var wg sync.WaitGroup
-	for i := 0; i < 10; i++ {
-		wg.Add(1)
-		go func() {
-			defer wg.Done()
-			err := w.Info("test")
-			if err != nil {
-				t.Errorf("Info() failed: %v", err)
-				return
-			}
-		}()
-	}
-	wg.Wait()
-}
-
-func TestConcurrentReconnect(t *testing.T) {
-	crashy = true
-	defer func() { crashy = false }()
-
-	const N = 10
-	const M = 100
-	net := "unix"
-	done := make(chan string, N*M)
-	addr, sock, srvWG := startServer(net, "", done)
-	defer os.Remove(addr)
-
-	// count all the messages arriving
-	count := make(chan int)
-	go func() {
-		ct := 0
-		for _ = range done {
-			ct++
-			// we are looking for 500 out of 1000 events
-			// here because lots of log messages are lost
-			// in buffers (kernel and/or bufio)
-			if ct > N*M/2 {
-				break
-			}
-		}
-		count <- ct
-	}()
-
-	var wg sync.WaitGroup
-	wg.Add(N)
-	for i := 0; i < N; i++ {
-		go func() {
-			defer wg.Done()
-			w, err := Dial(net, addr, LOG_USER|LOG_ERR, "tag")
-			if err != nil {
-				t.Fatalf("syslog.Dial() failed: %v", err)
-			}
-			defer w.Close()
-			for i := 0; i < M; i++ {
-				err := w.Info("test")
-				if err != nil {
-					t.Errorf("Info() failed: %v", err)
-					return
-				}
-			}
-		}()
-	}
-	wg.Wait()
-	sock.Close()
-	srvWG.Wait()
-	close(done)
-
-	select {
-	case <-count:
-	case <-time.After(100 * time.Millisecond):
-		t.Error("timeout in concurrent reconnect")
-	}
-}
diff --git a/src/pkg/log/syslog/syslog_unix.go b/src/pkg/log/syslog/syslog_unix.go
deleted file mode 100644
index f6d2f1b..0000000
--- a/src/pkg/log/syslog/syslog_unix.go
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build !windows,!nacl,!plan9
-
-package syslog
-
-import (
-	"errors"
-	"net"
-)
-
-// unixSyslog opens a connection to the syslog daemon running on the
-// local machine using a Unix domain socket.
-
-func unixSyslog() (conn serverConn, err error) {
-	logTypes := []string{"unixgram", "unix"}
-	logPaths := []string{"/dev/log", "/var/run/syslog"}
-	for _, network := range logTypes {
-		for _, path := range logPaths {
-			conn, err := net.Dial(network, path)
-			if err != nil {
-				continue
-			} else {
-				return &netConn{conn: conn, local: true}, nil
-			}
-		}
-	}
-	return nil, errors.New("Unix syslog delivery error")
-}
diff --git a/src/pkg/math/abs_386.s b/src/pkg/math/abs_386.s
deleted file mode 100644
index 3490cf6..0000000
--- a/src/pkg/math/abs_386.s
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright 2010 The Go 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 "../../cmd/ld/textflag.h"
-
-// func Abs(x float64) float64
-TEXT ·Abs(SB),NOSPLIT,$0
-	FMOVD   x+0(FP), F0  // F0=x
-	FABS                 // F0=|x|
-	FMOVDP  F0, ret+8(FP)
-	RET
diff --git a/src/pkg/math/abs_amd64.s b/src/pkg/math/abs_amd64.s
deleted file mode 100644
index 779c8f5..0000000
--- a/src/pkg/math/abs_amd64.s
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2010 The Go 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 "../../cmd/ld/textflag.h"
-
-// func Abs(x float64) float64
-TEXT ·Abs(SB),NOSPLIT,$0
-	MOVQ   $(1<<63), BX
-	MOVQ   BX, X0 // movsd $(-0.0), x0
-	MOVSD  x+0(FP), X1
-	ANDNPD X1, X0
-	MOVSD  X0, ret+8(FP)
-	RET
diff --git a/src/pkg/math/abs_arm.s b/src/pkg/math/abs_arm.s
deleted file mode 100644
index b5117ab..0000000
--- a/src/pkg/math/abs_arm.s
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2011 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../cmd/ld/textflag.h"
-
-TEXT ·Abs(SB),NOSPLIT,$0
-	MOVW	x_lo+0(FP), R0
-	MOVW	x_hi+4(FP), R1
-	AND 	$((1<<31)-1), R1
-	MOVW	R0, ret_lo+8(FP)
-	MOVW	R1, ret_hi+12(FP)
-	RET
diff --git a/src/pkg/math/all_test.go b/src/pkg/math/all_test.go
deleted file mode 100644
index 0d8b10f..0000000
--- a/src/pkg/math/all_test.go
+++ /dev/null
@@ -1,2935 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package math_test
-
-import (
-	"fmt"
-	. "math"
-	"testing"
-)
-
-var vf = []float64{
-	4.9790119248836735e+00,
-	7.7388724745781045e+00,
-	-2.7688005719200159e-01,
-	-5.0106036182710749e+00,
-	9.6362937071984173e+00,
-	2.9263772392439646e+00,
-	5.2290834314593066e+00,
-	2.7279399104360102e+00,
-	1.8253080916808550e+00,
-	-8.6859247685756013e+00,
-}
-
-// The expected results below were computed by the high precision calculators
-// at http://keisan.casio.com/.  More exact input values (array vf[], above)
-// were obtained by printing them with "%.26f".  The answers were calculated
-// to 26 digits (by using the "Digit number" drop-down control of each
-// calculator).
-var acos = []float64{
-	1.0496193546107222142571536e+00,
-	6.8584012813664425171660692e-01,
-	1.5984878714577160325521819e+00,
-	2.0956199361475859327461799e+00,
-	2.7053008467824138592616927e-01,
-	1.2738121680361776018155625e+00,
-	1.0205369421140629186287407e+00,
-	1.2945003481781246062157835e+00,
-	1.3872364345374451433846657e+00,
-	2.6231510803970463967294145e+00,
-}
-var acosh = []float64{
-	2.4743347004159012494457618e+00,
-	2.8576385344292769649802701e+00,
-	7.2796961502981066190593175e-01,
-	2.4796794418831451156471977e+00,
-	3.0552020742306061857212962e+00,
-	2.044238592688586588942468e+00,
-	2.5158701513104513595766636e+00,
-	1.99050839282411638174299e+00,
-	1.6988625798424034227205445e+00,
-	2.9611454842470387925531875e+00,
-}
-var asin = []float64{
-	5.2117697218417440497416805e-01,
-	8.8495619865825236751471477e-01,
-	-02.769154466281941332086016e-02,
-	-5.2482360935268931351485822e-01,
-	1.3002662421166552333051524e+00,
-	2.9698415875871901741575922e-01,
-	5.5025938468083370060258102e-01,
-	2.7629597861677201301553823e-01,
-	1.83559892257451475846656e-01,
-	-1.0523547536021497774980928e+00,
-}
-var asinh = []float64{
-	2.3083139124923523427628243e+00,
-	2.743551594301593620039021e+00,
-	-2.7345908534880091229413487e-01,
-	-2.3145157644718338650499085e+00,
-	2.9613652154015058521951083e+00,
-	1.7949041616585821933067568e+00,
-	2.3564032905983506405561554e+00,
-	1.7287118790768438878045346e+00,
-	1.3626658083714826013073193e+00,
-	-2.8581483626513914445234004e+00,
-}
-var atan = []float64{
-	1.372590262129621651920085e+00,
-	1.442290609645298083020664e+00,
-	-2.7011324359471758245192595e-01,
-	-1.3738077684543379452781531e+00,
-	1.4673921193587666049154681e+00,
-	1.2415173565870168649117764e+00,
-	1.3818396865615168979966498e+00,
-	1.2194305844639670701091426e+00,
-	1.0696031952318783760193244e+00,
-	-1.4561721938838084990898679e+00,
-}
-var atanh = []float64{
-	5.4651163712251938116878204e-01,
-	1.0299474112843111224914709e+00,
-	-2.7695084420740135145234906e-02,
-	-5.5072096119207195480202529e-01,
-	1.9943940993171843235906642e+00,
-	3.01448604578089708203017e-01,
-	5.8033427206942188834370595e-01,
-	2.7987997499441511013958297e-01,
-	1.8459947964298794318714228e-01,
-	-1.3273186910532645867272502e+00,
-}
-var atan2 = []float64{
-	1.1088291730037004444527075e+00,
-	9.1218183188715804018797795e-01,
-	1.5984772603216203736068915e+00,
-	2.0352918654092086637227327e+00,
-	8.0391819139044720267356014e-01,
-	1.2861075249894661588866752e+00,
-	1.0889904479131695712182587e+00,
-	1.3044821793397925293797357e+00,
-	1.3902530903455392306872261e+00,
-	2.2859857424479142655411058e+00,
-}
-var cbrt = []float64{
-	1.7075799841925094446722675e+00,
-	1.9779982212970353936691498e+00,
-	-6.5177429017779910853339447e-01,
-	-1.7111838886544019873338113e+00,
-	2.1279920909827937423960472e+00,
-	1.4303536770460741452312367e+00,
-	1.7357021059106154902341052e+00,
-	1.3972633462554328350552916e+00,
-	1.2221149580905388454977636e+00,
-	-2.0556003730500069110343596e+00,
-}
-var ceil = []float64{
-	5.0000000000000000e+00,
-	8.0000000000000000e+00,
-	0.0000000000000000e+00,
-	-5.0000000000000000e+00,
-	1.0000000000000000e+01,
-	3.0000000000000000e+00,
-	6.0000000000000000e+00,
-	3.0000000000000000e+00,
-	2.0000000000000000e+00,
-	-8.0000000000000000e+00,
-}
-var copysign = []float64{
-	-4.9790119248836735e+00,
-	-7.7388724745781045e+00,
-	-2.7688005719200159e-01,
-	-5.0106036182710749e+00,
-	-9.6362937071984173e+00,
-	-2.9263772392439646e+00,
-	-5.2290834314593066e+00,
-	-2.7279399104360102e+00,
-	-1.8253080916808550e+00,
-	-8.6859247685756013e+00,
-}
-var cos = []float64{
-	2.634752140995199110787593e-01,
-	1.148551260848219865642039e-01,
-	9.6191297325640768154550453e-01,
-	2.938141150061714816890637e-01,
-	-9.777138189897924126294461e-01,
-	-9.7693041344303219127199518e-01,
-	4.940088096948647263961162e-01,
-	-9.1565869021018925545016502e-01,
-	-2.517729313893103197176091e-01,
-	-7.39241351595676573201918e-01,
-}
-
-// Results for 100000 * Pi + vf[i]
-var cosLarge = []float64{
-	2.634752141185559426744e-01,
-	1.14855126055543100712e-01,
-	9.61912973266488928113e-01,
-	2.9381411499556122552e-01,
-	-9.777138189880161924641e-01,
-	-9.76930413445147608049e-01,
-	4.940088097314976789841e-01,
-	-9.15658690217517835002e-01,
-	-2.51772931436786954751e-01,
-	-7.3924135157173099849e-01,
-}
-var cosh = []float64{
-	7.2668796942212842775517446e+01,
-	1.1479413465659254502011135e+03,
-	1.0385767908766418550935495e+00,
-	7.5000957789658051428857788e+01,
-	7.655246669605357888468613e+03,
-	9.3567491758321272072888257e+00,
-	9.331351599270605471131735e+01,
-	7.6833430994624643209296404e+00,
-	3.1829371625150718153881164e+00,
-	2.9595059261916188501640911e+03,
-}
-var erf = []float64{
-	5.1865354817738701906913566e-01,
-	7.2623875834137295116929844e-01,
-	-3.123458688281309990629839e-02,
-	-5.2143121110253302920437013e-01,
-	8.2704742671312902508629582e-01,
-	3.2101767558376376743993945e-01,
-	5.403990312223245516066252e-01,
-	3.0034702916738588551174831e-01,
-	2.0369924417882241241559589e-01,
-	-7.8069386968009226729944677e-01,
-}
-var erfc = []float64{
-	4.8134645182261298093086434e-01,
-	2.7376124165862704883070156e-01,
-	1.0312345868828130999062984e+00,
-	1.5214312111025330292043701e+00,
-	1.7295257328687097491370418e-01,
-	6.7898232441623623256006055e-01,
-	4.596009687776754483933748e-01,
-	6.9965297083261411448825169e-01,
-	7.9630075582117758758440411e-01,
-	1.7806938696800922672994468e+00,
-}
-var exp = []float64{
-	1.4533071302642137507696589e+02,
-	2.2958822575694449002537581e+03,
-	7.5814542574851666582042306e-01,
-	6.6668778421791005061482264e-03,
-	1.5310493273896033740861206e+04,
-	1.8659907517999328638667732e+01,
-	1.8662167355098714543942057e+02,
-	1.5301332413189378961665788e+01,
-	6.2047063430646876349125085e+00,
-	1.6894712385826521111610438e-04,
-}
-var expm1 = []float64{
-	5.105047796122957327384770212e-02,
-	8.046199708567344080562675439e-02,
-	-2.764970978891639815187418703e-03,
-	-4.8871434888875355394330300273e-02,
-	1.0115864277221467777117227494e-01,
-	2.969616407795910726014621657e-02,
-	5.368214487944892300914037972e-02,
-	2.765488851131274068067445335e-02,
-	1.842068661871398836913874273e-02,
-	-8.3193870863553801814961137573e-02,
-}
-var exp2 = []float64{
-	3.1537839463286288034313104e+01,
-	2.1361549283756232296144849e+02,
-	8.2537402562185562902577219e-01,
-	3.1021158628740294833424229e-02,
-	7.9581744110252191462569661e+02,
-	7.6019905892596359262696423e+00,
-	3.7506882048388096973183084e+01,
-	6.6250893439173561733216375e+00,
-	3.5438267900243941544605339e+00,
-	2.4281533133513300984289196e-03,
-}
-var fabs = []float64{
-	4.9790119248836735e+00,
-	7.7388724745781045e+00,
-	2.7688005719200159e-01,
-	5.0106036182710749e+00,
-	9.6362937071984173e+00,
-	2.9263772392439646e+00,
-	5.2290834314593066e+00,
-	2.7279399104360102e+00,
-	1.8253080916808550e+00,
-	8.6859247685756013e+00,
-}
-var fdim = []float64{
-	4.9790119248836735e+00,
-	7.7388724745781045e+00,
-	0.0000000000000000e+00,
-	0.0000000000000000e+00,
-	9.6362937071984173e+00,
-	2.9263772392439646e+00,
-	5.2290834314593066e+00,
-	2.7279399104360102e+00,
-	1.8253080916808550e+00,
-	0.0000000000000000e+00,
-}
-var floor = []float64{
-	4.0000000000000000e+00,
-	7.0000000000000000e+00,
-	-1.0000000000000000e+00,
-	-6.0000000000000000e+00,
-	9.0000000000000000e+00,
-	2.0000000000000000e+00,
-	5.0000000000000000e+00,
-	2.0000000000000000e+00,
-	1.0000000000000000e+00,
-	-9.0000000000000000e+00,
-}
-var fmod = []float64{
-	4.197615023265299782906368e-02,
-	2.261127525421895434476482e+00,
-	3.231794108794261433104108e-02,
-	4.989396381728925078391512e+00,
-	3.637062928015826201999516e-01,
-	1.220868282268106064236690e+00,
-	4.770916568540693347699744e+00,
-	1.816180268691969246219742e+00,
-	8.734595415957246977711748e-01,
-	1.314075231424398637614104e+00,
-}
-
-type fi struct {
-	f float64
-	i int
-}
-
-var frexp = []fi{
-	{6.2237649061045918750e-01, 3},
-	{9.6735905932226306250e-01, 3},
-	{-5.5376011438400318000e-01, -1},
-	{-6.2632545228388436250e-01, 3},
-	{6.02268356699901081250e-01, 4},
-	{7.3159430981099115000e-01, 2},
-	{6.5363542893241332500e-01, 3},
-	{6.8198497760900255000e-01, 2},
-	{9.1265404584042750000e-01, 1},
-	{-5.4287029803597508250e-01, 4},
-}
-var gamma = []float64{
-	2.3254348370739963835386613898e+01,
-	2.991153837155317076427529816e+03,
-	-4.561154336726758060575129109e+00,
-	7.719403468842639065959210984e-01,
-	1.6111876618855418534325755566e+05,
-	1.8706575145216421164173224946e+00,
-	3.4082787447257502836734201635e+01,
-	1.579733951448952054898583387e+00,
-	9.3834586598354592860187267089e-01,
-	-2.093995902923148389186189429e-05,
-}
-var j0 = []float64{
-	-1.8444682230601672018219338e-01,
-	2.27353668906331975435892e-01,
-	9.809259936157051116270273e-01,
-	-1.741170131426226587841181e-01,
-	-2.1389448451144143352039069e-01,
-	-2.340905848928038763337414e-01,
-	-1.0029099691890912094586326e-01,
-	-1.5466726714884328135358907e-01,
-	3.252650187653420388714693e-01,
-	-8.72218484409407250005360235e-03,
-}
-var j1 = []float64{
-	-3.251526395295203422162967e-01,
-	1.893581711430515718062564e-01,
-	-1.3711761352467242914491514e-01,
-	3.287486536269617297529617e-01,
-	1.3133899188830978473849215e-01,
-	3.660243417832986825301766e-01,
-	-3.4436769271848174665420672e-01,
-	4.329481396640773768835036e-01,
-	5.8181350531954794639333955e-01,
-	-2.7030574577733036112996607e-01,
-}
-var j2 = []float64{
-	5.3837518920137802565192769e-02,
-	-1.7841678003393207281244667e-01,
-	9.521746934916464142495821e-03,
-	4.28958355470987397983072e-02,
-	2.4115371837854494725492872e-01,
-	4.842458532394520316844449e-01,
-	-3.142145220618633390125946e-02,
-	4.720849184745124761189957e-01,
-	3.122312022520957042957497e-01,
-	7.096213118930231185707277e-02,
-}
-var jM3 = []float64{
-	-3.684042080996403091021151e-01,
-	2.8157665936340887268092661e-01,
-	4.401005480841948348343589e-04,
-	3.629926999056814081597135e-01,
-	3.123672198825455192489266e-02,
-	-2.958805510589623607540455e-01,
-	-3.2033177696533233403289416e-01,
-	-2.592737332129663376736604e-01,
-	-1.0241334641061485092351251e-01,
-	-2.3762660886100206491674503e-01,
-}
-var lgamma = []fi{
-	{3.146492141244545774319734e+00, 1},
-	{8.003414490659126375852113e+00, 1},
-	{1.517575735509779707488106e+00, -1},
-	{-2.588480028182145853558748e-01, 1},
-	{1.1989897050205555002007985e+01, 1},
-	{6.262899811091257519386906e-01, 1},
-	{3.5287924899091566764846037e+00, 1},
-	{4.5725644770161182299423372e-01, 1},
-	{-6.363667087767961257654854e-02, 1},
-	{-1.077385130910300066425564e+01, -1},
-}
-var log = []float64{
-	1.605231462693062999102599e+00,
-	2.0462560018708770653153909e+00,
-	-1.2841708730962657801275038e+00,
-	1.6115563905281545116286206e+00,
-	2.2655365644872016636317461e+00,
-	1.0737652208918379856272735e+00,
-	1.6542360106073546632707956e+00,
-	1.0035467127723465801264487e+00,
-	6.0174879014578057187016475e-01,
-	2.161703872847352815363655e+00,
-}
-var logb = []float64{
-	2.0000000000000000e+00,
-	2.0000000000000000e+00,
-	-2.0000000000000000e+00,
-	2.0000000000000000e+00,
-	3.0000000000000000e+00,
-	1.0000000000000000e+00,
-	2.0000000000000000e+00,
-	1.0000000000000000e+00,
-	0.0000000000000000e+00,
-	3.0000000000000000e+00,
-}
-var log10 = []float64{
-	6.9714316642508290997617083e-01,
-	8.886776901739320576279124e-01,
-	-5.5770832400658929815908236e-01,
-	6.998900476822994346229723e-01,
-	9.8391002850684232013281033e-01,
-	4.6633031029295153334285302e-01,
-	7.1842557117242328821552533e-01,
-	4.3583479968917773161304553e-01,
-	2.6133617905227038228626834e-01,
-	9.3881606348649405716214241e-01,
-}
-var log1p = []float64{
-	4.8590257759797794104158205e-02,
-	7.4540265965225865330849141e-02,
-	-2.7726407903942672823234024e-03,
-	-5.1404917651627649094953380e-02,
-	9.1998280672258624681335010e-02,
-	2.8843762576593352865894824e-02,
-	5.0969534581863707268992645e-02,
-	2.6913947602193238458458594e-02,
-	1.8088493239630770262045333e-02,
-	-9.0865245631588989681559268e-02,
-}
-var log2 = []float64{
-	2.3158594707062190618898251e+00,
-	2.9521233862883917703341018e+00,
-	-1.8526669502700329984917062e+00,
-	2.3249844127278861543568029e+00,
-	3.268478366538305087466309e+00,
-	1.5491157592596970278166492e+00,
-	2.3865580889631732407886495e+00,
-	1.447811865817085365540347e+00,
-	8.6813999540425116282815557e-01,
-	3.118679457227342224364709e+00,
-}
-var modf = [][2]float64{
-	{4.0000000000000000e+00, 9.7901192488367350108546816e-01},
-	{7.0000000000000000e+00, 7.3887247457810456552351752e-01},
-	{0.0000000000000000e+00, -2.7688005719200159404635997e-01},
-	{-5.0000000000000000e+00, -1.060361827107492160848778e-02},
-	{9.0000000000000000e+00, 6.3629370719841737980004837e-01},
-	{2.0000000000000000e+00, 9.2637723924396464525443662e-01},
-	{5.0000000000000000e+00, 2.2908343145930665230025625e-01},
-	{2.0000000000000000e+00, 7.2793991043601025126008608e-01},
-	{1.0000000000000000e+00, 8.2530809168085506044576505e-01},
-	{-8.0000000000000000e+00, -6.8592476857560136238589621e-01},
-}
-var nextafter = []float64{
-	4.97901192488367438926388786e+00,
-	7.73887247457810545370193722e+00,
-	-2.7688005719200153853520874e-01,
-	-5.01060361827107403343006808e+00,
-	9.63629370719841915615688777e+00,
-	2.92637723924396508934364647e+00,
-	5.22908343145930754047867595e+00,
-	2.72793991043601069534929593e+00,
-	1.82530809168085528249036997e+00,
-	-8.68592476857559958602905681e+00,
-}
-var pow = []float64{
-	9.5282232631648411840742957e+04,
-	5.4811599352999901232411871e+07,
-	5.2859121715894396531132279e-01,
-	9.7587991957286474464259698e-06,
-	4.328064329346044846740467e+09,
-	8.4406761805034547437659092e+02,
-	1.6946633276191194947742146e+05,
-	5.3449040147551939075312879e+02,
-	6.688182138451414936380374e+01,
-	2.0609869004248742886827439e-09,
-}
-var remainder = []float64{
-	4.197615023265299782906368e-02,
-	2.261127525421895434476482e+00,
-	3.231794108794261433104108e-02,
-	-2.120723654214984321697556e-02,
-	3.637062928015826201999516e-01,
-	1.220868282268106064236690e+00,
-	-4.581668629186133046005125e-01,
-	-9.117596417440410050403443e-01,
-	8.734595415957246977711748e-01,
-	1.314075231424398637614104e+00,
-}
-var signbit = []bool{
-	false,
-	false,
-	true,
-	true,
-	false,
-	false,
-	false,
-	false,
-	false,
-	true,
-}
-var sin = []float64{
-	-9.6466616586009283766724726e-01,
-	9.9338225271646545763467022e-01,
-	-2.7335587039794393342449301e-01,
-	9.5586257685042792878173752e-01,
-	-2.099421066779969164496634e-01,
-	2.135578780799860532750616e-01,
-	-8.694568971167362743327708e-01,
-	4.019566681155577786649878e-01,
-	9.6778633541687993721617774e-01,
-	-6.734405869050344734943028e-01,
-}
-
-// Results for 100000 * Pi + vf[i]
-var sinLarge = []float64{
-	-9.646661658548936063912e-01,
-	9.933822527198506903752e-01,
-	-2.7335587036246899796e-01,
-	9.55862576853689321268e-01,
-	-2.099421066862688873691e-01,
-	2.13557878070308981163e-01,
-	-8.694568970959221300497e-01,
-	4.01956668098863248917e-01,
-	9.67786335404528727927e-01,
-	-6.7344058693131973066e-01,
-}
-var sinh = []float64{
-	7.2661916084208532301448439e+01,
-	1.1479409110035194500526446e+03,
-	-2.8043136512812518927312641e-01,
-	-7.499429091181587232835164e+01,
-	7.6552466042906758523925934e+03,
-	9.3031583421672014313789064e+00,
-	9.330815755828109072810322e+01,
-	7.6179893137269146407361477e+00,
-	3.021769180549615819524392e+00,
-	-2.95950575724449499189888e+03,
-}
-var sqrt = []float64{
-	2.2313699659365484748756904e+00,
-	2.7818829009464263511285458e+00,
-	5.2619393496314796848143251e-01,
-	2.2384377628763938724244104e+00,
-	3.1042380236055381099288487e+00,
-	1.7106657298385224403917771e+00,
-	2.286718922705479046148059e+00,
-	1.6516476350711159636222979e+00,
-	1.3510396336454586262419247e+00,
-	2.9471892997524949215723329e+00,
-}
-var tan = []float64{
-	-3.661316565040227801781974e+00,
-	8.64900232648597589369854e+00,
-	-2.8417941955033612725238097e-01,
-	3.253290185974728640827156e+00,
-	2.147275640380293804770778e-01,
-	-2.18600910711067004921551e-01,
-	-1.760002817872367935518928e+00,
-	-4.389808914752818126249079e-01,
-	-3.843885560201130679995041e+00,
-	9.10988793377685105753416e-01,
-}
-
-// Results for 100000 * Pi + vf[i]
-var tanLarge = []float64{
-	-3.66131656475596512705e+00,
-	8.6490023287202547927e+00,
-	-2.841794195104782406e-01,
-	3.2532901861033120983e+00,
-	2.14727564046880001365e-01,
-	-2.18600910700688062874e-01,
-	-1.760002817699722747043e+00,
-	-4.38980891453536115952e-01,
-	-3.84388555942723509071e+00,
-	9.1098879344275101051e-01,
-}
-var tanh = []float64{
-	9.9990531206936338549262119e-01,
-	9.9999962057085294197613294e-01,
-	-2.7001505097318677233756845e-01,
-	-9.9991110943061718603541401e-01,
-	9.9999999146798465745022007e-01,
-	9.9427249436125236705001048e-01,
-	9.9994257600983138572705076e-01,
-	9.9149409509772875982054701e-01,
-	9.4936501296239685514466577e-01,
-	-9.9999994291374030946055701e-01,
-}
-var trunc = []float64{
-	4.0000000000000000e+00,
-	7.0000000000000000e+00,
-	-0.0000000000000000e+00,
-	-5.0000000000000000e+00,
-	9.0000000000000000e+00,
-	2.0000000000000000e+00,
-	5.0000000000000000e+00,
-	2.0000000000000000e+00,
-	1.0000000000000000e+00,
-	-8.0000000000000000e+00,
-}
-var y0 = []float64{
-	-3.053399153780788357534855e-01,
-	1.7437227649515231515503649e-01,
-	-8.6221781263678836910392572e-01,
-	-3.100664880987498407872839e-01,
-	1.422200649300982280645377e-01,
-	4.000004067997901144239363e-01,
-	-3.3340749753099352392332536e-01,
-	4.5399790746668954555205502e-01,
-	4.8290004112497761007536522e-01,
-	2.7036697826604756229601611e-01,
-}
-var y1 = []float64{
-	0.15494213737457922210218611,
-	-0.2165955142081145245075746,
-	-2.4644949631241895201032829,
-	0.1442740489541836405154505,
-	0.2215379960518984777080163,
-	0.3038800915160754150565448,
-	0.0691107642452362383808547,
-	0.2380116417809914424860165,
-	-0.20849492979459761009678934,
-	0.0242503179793232308250804,
-}
-var y2 = []float64{
-	0.3675780219390303613394936,
-	-0.23034826393250119879267257,
-	-16.939677983817727205631397,
-	0.367653980523052152867791,
-	-0.0962401471767804440353136,
-	-0.1923169356184851105200523,
-	0.35984072054267882391843766,
-	-0.2794987252299739821654982,
-	-0.7113490692587462579757954,
-	-0.2647831587821263302087457,
-}
-var yM3 = []float64{
-	-0.14035984421094849100895341,
-	-0.097535139617792072703973,
-	242.25775994555580176377379,
-	-0.1492267014802818619511046,
-	0.26148702629155918694500469,
-	0.56675383593895176530394248,
-	-0.206150264009006981070575,
-	0.64784284687568332737963658,
-	1.3503631555901938037008443,
-	0.1461869756579956803341844,
-}
-
-// arguments and expected results for special cases
-var vfacosSC = []float64{
-	-Pi,
-	1,
-	Pi,
-	NaN(),
-}
-var acosSC = []float64{
-	NaN(),
-	0,
-	NaN(),
-	NaN(),
-}
-
-var vfacoshSC = []float64{
-	Inf(-1),
-	0.5,
-	1,
-	Inf(1),
-	NaN(),
-}
-var acoshSC = []float64{
-	NaN(),
-	NaN(),
-	0,
-	Inf(1),
-	NaN(),
-}
-
-var vfasinSC = []float64{
-	-Pi,
-	Copysign(0, -1),
-	0,
-	Pi,
-	NaN(),
-}
-var asinSC = []float64{
-	NaN(),
-	Copysign(0, -1),
-	0,
-	NaN(),
-	NaN(),
-}
-
-var vfasinhSC = []float64{
-	Inf(-1),
-	Copysign(0, -1),
-	0,
-	Inf(1),
-	NaN(),
-}
-var asinhSC = []float64{
-	Inf(-1),
-	Copysign(0, -1),
-	0,
-	Inf(1),
-	NaN(),
-}
-
-var vfatanSC = []float64{
-	Inf(-1),
-	Copysign(0, -1),
-	0,
-	Inf(1),
-	NaN(),
-}
-var atanSC = []float64{
-	-Pi / 2,
-	Copysign(0, -1),
-	0,
-	Pi / 2,
-	NaN(),
-}
-
-var vfatanhSC = []float64{
-	Inf(-1),
-	-Pi,
-	-1,
-	Copysign(0, -1),
-	0,
-	1,
-	Pi,
-	Inf(1),
-	NaN(),
-}
-var atanhSC = []float64{
-	NaN(),
-	NaN(),
-	Inf(-1),
-	Copysign(0, -1),
-	0,
-	Inf(1),
-	NaN(),
-	NaN(),
-	NaN(),
-}
-var vfatan2SC = [][2]float64{
-	{Inf(-1), Inf(-1)},
-	{Inf(-1), -Pi},
-	{Inf(-1), 0},
-	{Inf(-1), +Pi},
-	{Inf(-1), Inf(1)},
-	{Inf(-1), NaN()},
-	{-Pi, Inf(-1)},
-	{-Pi, 0},
-	{-Pi, Inf(1)},
-	{-Pi, NaN()},
-	{Copysign(0, -1), Inf(-1)},
-	{Copysign(0, -1), -Pi},
-	{Copysign(0, -1), Copysign(0, -1)},
-	{Copysign(0, -1), 0},
-	{Copysign(0, -1), +Pi},
-	{Copysign(0, -1), Inf(1)},
-	{Copysign(0, -1), NaN()},
-	{0, Inf(-1)},
-	{0, -Pi},
-	{0, Copysign(0, -1)},
-	{0, 0},
-	{0, +Pi},
-	{0, Inf(1)},
-	{0, NaN()},
-	{+Pi, Inf(-1)},
-	{+Pi, 0},
-	{+Pi, Inf(1)},
-	{+Pi, NaN()},
-	{Inf(1), Inf(-1)},
-	{Inf(1), -Pi},
-	{Inf(1), 0},
-	{Inf(1), +Pi},
-	{Inf(1), Inf(1)},
-	{Inf(1), NaN()},
-	{NaN(), NaN()},
-}
-var atan2SC = []float64{
-	-3 * Pi / 4,     // atan2(-Inf, -Inf)
-	-Pi / 2,         // atan2(-Inf, -Pi)
-	-Pi / 2,         // atan2(-Inf, +0)
-	-Pi / 2,         // atan2(-Inf, +Pi)
-	-Pi / 4,         // atan2(-Inf, +Inf)
-	NaN(),           // atan2(-Inf, NaN)
-	-Pi,             // atan2(-Pi, -Inf)
-	-Pi / 2,         // atan2(-Pi, +0)
-	Copysign(0, -1), // atan2(-Pi, Inf)
-	NaN(),           // atan2(-Pi, NaN)
-	-Pi,             // atan2(-0, -Inf)
-	-Pi,             // atan2(-0, -Pi)
-	-Pi,             // atan2(-0, -0)
-	Copysign(0, -1), // atan2(-0, +0)
-	Copysign(0, -1), // atan2(-0, +Pi)
-	Copysign(0, -1), // atan2(-0, +Inf)
-	NaN(),           // atan2(-0, NaN)
-	Pi,              // atan2(+0, -Inf)
-	Pi,              // atan2(+0, -Pi)
-	Pi,              // atan2(+0, -0)
-	0,               // atan2(+0, +0)
-	0,               // atan2(+0, +Pi)
-	0,               // atan2(+0, +Inf)
-	NaN(),           // atan2(+0, NaN)
-	Pi,              // atan2(+Pi, -Inf)
-	Pi / 2,          // atan2(+Pi, +0)
-	0,               // atan2(+Pi, +Inf)
-	NaN(),           // atan2(+Pi, NaN)
-	3 * Pi / 4,      // atan2(+Inf, -Inf)
-	Pi / 2,          // atan2(+Inf, -Pi)
-	Pi / 2,          // atan2(+Inf, +0)
-	Pi / 2,          // atan2(+Inf, +Pi)
-	Pi / 4,          // atan2(+Inf, +Inf)
-	NaN(),           // atan2(+Inf, NaN)
-	NaN(),           // atan2(NaN, NaN)
-}
-
-var vfcbrtSC = []float64{
-	Inf(-1),
-	Copysign(0, -1),
-	0,
-	Inf(1),
-	NaN(),
-}
-var cbrtSC = []float64{
-	Inf(-1),
-	Copysign(0, -1),
-	0,
-	Inf(1),
-	NaN(),
-}
-
-var vfceilSC = []float64{
-	Inf(-1),
-	Copysign(0, -1),
-	0,
-	Inf(1),
-	NaN(),
-}
-var ceilSC = []float64{
-	Inf(-1),
-	Copysign(0, -1),
-	0,
-	Inf(1),
-	NaN(),
-}
-
-var vfcopysignSC = []float64{
-	Inf(-1),
-	Inf(1),
-	NaN(),
-}
-var copysignSC = []float64{
-	Inf(-1),
-	Inf(-1),
-	NaN(),
-}
-
-var vfcosSC = []float64{
-	Inf(-1),
-	Inf(1),
-	NaN(),
-}
-var cosSC = []float64{
-	NaN(),
-	NaN(),
-	NaN(),
-}
-
-var vfcoshSC = []float64{
-	Inf(-1),
-	Copysign(0, -1),
-	0,
-	Inf(1),
-	NaN(),
-}
-var coshSC = []float64{
-	Inf(1),
-	1,
-	1,
-	Inf(1),
-	NaN(),
-}
-
-var vferfSC = []float64{
-	Inf(-1),
-	Copysign(0, -1),
-	0,
-	Inf(1),
-	NaN(),
-}
-var erfSC = []float64{
-	-1,
-	Copysign(0, -1),
-	0,
-	1,
-	NaN(),
-}
-
-var vferfcSC = []float64{
-	Inf(-1),
-	Inf(1),
-	NaN(),
-}
-var erfcSC = []float64{
-	2,
-	0,
-	NaN(),
-}
-
-var vfexpSC = []float64{
-	Inf(-1),
-	-2000,
-	2000,
-	Inf(1),
-	NaN(),
-}
-var expSC = []float64{
-	0,
-	0,
-	Inf(1),
-	Inf(1),
-	NaN(),
-}
-
-var vfexpm1SC = []float64{
-	Inf(-1),
-	Copysign(0, -1),
-	0,
-	Inf(1),
-	NaN(),
-}
-var expm1SC = []float64{
-	-1,
-	Copysign(0, -1),
-	0,
-	Inf(1),
-	NaN(),
-}
-
-var vffabsSC = []float64{
-	Inf(-1),
-	Copysign(0, -1),
-	0,
-	Inf(1),
-	NaN(),
-}
-var fabsSC = []float64{
-	Inf(1),
-	0,
-	0,
-	Inf(1),
-	NaN(),
-}
-
-var vffdimSC = [][2]float64{
-	{Inf(-1), Inf(-1)},
-	{Inf(-1), Inf(1)},
-	{Inf(-1), NaN()},
-	{Copysign(0, -1), Copysign(0, -1)},
-	{Copysign(0, -1), 0},
-	{0, Copysign(0, -1)},
-	{0, 0},
-	{Inf(1), Inf(-1)},
-	{Inf(1), Inf(1)},
-	{Inf(1), NaN()},
-	{NaN(), Inf(-1)},
-	{NaN(), Copysign(0, -1)},
-	{NaN(), 0},
-	{NaN(), Inf(1)},
-	{NaN(), NaN()},
-}
-var fdimSC = []float64{
-	NaN(),
-	0,
-	NaN(),
-	0,
-	0,
-	0,
-	0,
-	Inf(1),
-	NaN(),
-	NaN(),
-	NaN(),
-	NaN(),
-	NaN(),
-	NaN(),
-	NaN(),
-}
-var fmaxSC = []float64{
-	Inf(-1),
-	Inf(1),
-	NaN(),
-	Copysign(0, -1),
-	0,
-	0,
-	0,
-	Inf(1),
-	Inf(1),
-	Inf(1),
-	NaN(),
-	NaN(),
-	NaN(),
-	Inf(1),
-	NaN(),
-}
-var fminSC = []float64{
-	Inf(-1),
-	Inf(-1),
-	Inf(-1),
-	Copysign(0, -1),
-	Copysign(0, -1),
-	Copysign(0, -1),
-	0,
-	Inf(-1),
-	Inf(1),
-	NaN(),
-	Inf(-1),
-	NaN(),
-	NaN(),
-	NaN(),
-	NaN(),
-}
-
-var vffmodSC = [][2]float64{
-	{Inf(-1), Inf(-1)},
-	{Inf(-1), -Pi},
-	{Inf(-1), 0},
-	{Inf(-1), Pi},
-	{Inf(-1), Inf(1)},
-	{Inf(-1), NaN()},
-	{-Pi, Inf(-1)},
-	{-Pi, 0},
-	{-Pi, Inf(1)},
-	{-Pi, NaN()},
-	{Copysign(0, -1), Inf(-1)},
-	{Copysign(0, -1), 0},
-	{Copysign(0, -1), Inf(1)},
-	{Copysign(0, -1), NaN()},
-	{0, Inf(-1)},
-	{0, 0},
-	{0, Inf(1)},
-	{0, NaN()},
-	{Pi, Inf(-1)},
-	{Pi, 0},
-	{Pi, Inf(1)},
-	{Pi, NaN()},
-	{Inf(1), Inf(-1)},
-	{Inf(1), -Pi},
-	{Inf(1), 0},
-	{Inf(1), Pi},
-	{Inf(1), Inf(1)},
-	{Inf(1), NaN()},
-	{NaN(), Inf(-1)},
-	{NaN(), -Pi},
-	{NaN(), 0},
-	{NaN(), Pi},
-	{NaN(), Inf(1)},
-	{NaN(), NaN()},
-}
-var fmodSC = []float64{
-	NaN(),           // fmod(-Inf, -Inf)
-	NaN(),           // fmod(-Inf, -Pi)
-	NaN(),           // fmod(-Inf, 0)
-	NaN(),           // fmod(-Inf, Pi)
-	NaN(),           // fmod(-Inf, +Inf)
-	NaN(),           // fmod(-Inf, NaN)
-	-Pi,             // fmod(-Pi, -Inf)
-	NaN(),           // fmod(-Pi, 0)
-	-Pi,             // fmod(-Pi, +Inf)
-	NaN(),           // fmod(-Pi, NaN)
-	Copysign(0, -1), // fmod(-0, -Inf)
-	NaN(),           // fmod(-0, 0)
-	Copysign(0, -1), // fmod(-0, Inf)
-	NaN(),           // fmod(-0, NaN)
-	0,               // fmod(0, -Inf)
-	NaN(),           // fmod(0, 0)
-	0,               // fmod(0, +Inf)
-	NaN(),           // fmod(0, NaN)
-	Pi,              // fmod(Pi, -Inf)
-	NaN(),           // fmod(Pi, 0)
-	Pi,              // fmod(Pi, +Inf)
-	NaN(),           // fmod(Pi, NaN)
-	NaN(),           // fmod(+Inf, -Inf)
-	NaN(),           // fmod(+Inf, -Pi)
-	NaN(),           // fmod(+Inf, 0)
-	NaN(),           // fmod(+Inf, Pi)
-	NaN(),           // fmod(+Inf, +Inf)
-	NaN(),           // fmod(+Inf, NaN)
-	NaN(),           // fmod(NaN, -Inf)
-	NaN(),           // fmod(NaN, -Pi)
-	NaN(),           // fmod(NaN, 0)
-	NaN(),           // fmod(NaN, Pi)
-	NaN(),           // fmod(NaN, +Inf)
-	NaN(),           // fmod(NaN, NaN)
-}
-
-var vffrexpSC = []float64{
-	Inf(-1),
-	Copysign(0, -1),
-	0,
-	Inf(1),
-	NaN(),
-}
-var frexpSC = []fi{
-	{Inf(-1), 0},
-	{Copysign(0, -1), 0},
-	{0, 0},
-	{Inf(1), 0},
-	{NaN(), 0},
-}
-
-var vfgammaSC = []float64{
-	Inf(-1),
-	-3,
-	Copysign(0, -1),
-	0,
-	Inf(1),
-	NaN(),
-}
-var gammaSC = []float64{
-	NaN(),
-	NaN(),
-	Inf(-1),
-	Inf(1),
-	Inf(1),
-	NaN(),
-}
-
-var vfhypotSC = [][2]float64{
-	{Inf(-1), Inf(-1)},
-	{Inf(-1), 0},
-	{Inf(-1), Inf(1)},
-	{Inf(-1), NaN()},
-	{Copysign(0, -1), Copysign(0, -1)},
-	{Copysign(0, -1), 0},
-	{0, Copysign(0, -1)},
-	{0, 0}, // +0, +0
-	{0, Inf(-1)},
-	{0, Inf(1)},
-	{0, NaN()},
-	{Inf(1), Inf(-1)},
-	{Inf(1), 0},
-	{Inf(1), Inf(1)},
-	{Inf(1), NaN()},
-	{NaN(), Inf(-1)},
-	{NaN(), 0},
-	{NaN(), Inf(1)},
-	{NaN(), NaN()},
-}
-var hypotSC = []float64{
-	Inf(1),
-	Inf(1),
-	Inf(1),
-	Inf(1),
-	0,
-	0,
-	0,
-	0,
-	Inf(1),
-	Inf(1),
-	NaN(),
-	Inf(1),
-	Inf(1),
-	Inf(1),
-	Inf(1),
-	Inf(1),
-	NaN(),
-	Inf(1),
-	NaN(),
-}
-
-var vfilogbSC = []float64{
-	Inf(-1),
-	0,
-	Inf(1),
-	NaN(),
-}
-var ilogbSC = []int{
-	MaxInt32,
-	MinInt32,
-	MaxInt32,
-	MaxInt32,
-}
-
-var vfj0SC = []float64{
-	Inf(-1),
-	0,
-	Inf(1),
-	NaN(),
-}
-var j0SC = []float64{
-	0,
-	1,
-	0,
-	NaN(),
-}
-var j1SC = []float64{
-	0,
-	0,
-	0,
-	NaN(),
-}
-var j2SC = []float64{
-	0,
-	0,
-	0,
-	NaN(),
-}
-var jM3SC = []float64{
-	0,
-	0,
-	0,
-	NaN(),
-}
-
-var vfldexpSC = []fi{
-	{0, 0},
-	{0, -1075},
-	{0, 1024},
-	{Copysign(0, -1), 0},
-	{Copysign(0, -1), -1075},
-	{Copysign(0, -1), 1024},
-	{Inf(1), 0},
-	{Inf(1), -1024},
-	{Inf(-1), 0},
-	{Inf(-1), -1024},
-	{NaN(), -1024},
-}
-var ldexpSC = []float64{
-	0,
-	0,
-	0,
-	Copysign(0, -1),
-	Copysign(0, -1),
-	Copysign(0, -1),
-	Inf(1),
-	Inf(1),
-	Inf(-1),
-	Inf(-1),
-	NaN(),
-}
-
-var vflgammaSC = []float64{
-	Inf(-1),
-	-3,
-	0,
-	1,
-	2,
-	Inf(1),
-	NaN(),
-}
-var lgammaSC = []fi{
-	{Inf(-1), 1},
-	{Inf(1), 1},
-	{Inf(1), 1},
-	{0, 1},
-	{0, 1},
-	{Inf(1), 1},
-	{NaN(), 1},
-}
-
-var vflogSC = []float64{
-	Inf(-1),
-	-Pi,
-	Copysign(0, -1),
-	0,
-	1,
-	Inf(1),
-	NaN(),
-}
-var logSC = []float64{
-	NaN(),
-	NaN(),
-	Inf(-1),
-	Inf(-1),
-	0,
-	Inf(1),
-	NaN(),
-}
-
-var vflogbSC = []float64{
-	Inf(-1),
-	0,
-	Inf(1),
-	NaN(),
-}
-var logbSC = []float64{
-	Inf(1),
-	Inf(-1),
-	Inf(1),
-	NaN(),
-}
-
-var vflog1pSC = []float64{
-	Inf(-1),
-	-Pi,
-	-1,
-	Copysign(0, -1),
-	0,
-	Inf(1),
-	NaN(),
-}
-var log1pSC = []float64{
-	NaN(),
-	NaN(),
-	Inf(-1),
-	Copysign(0, -1),
-	0,
-	Inf(1),
-	NaN(),
-}
-
-var vfmodfSC = []float64{
-	Inf(-1),
-	Inf(1),
-	NaN(),
-}
-var modfSC = [][2]float64{
-	{Inf(-1), NaN()}, // [2]float64{Copysign(0, -1), Inf(-1)},
-	{Inf(1), NaN()},  // [2]float64{0, Inf(1)},
-	{NaN(), NaN()},
-}
-
-var vfnextafterSC = [][2]float64{
-	{0, 0},
-	{0, Copysign(0, -1)},
-	{0, -1},
-	{0, NaN()},
-	{Copysign(0, -1), 1},
-	{Copysign(0, -1), 0},
-	{Copysign(0, -1), Copysign(0, -1)},
-	{Copysign(0, -1), -1},
-	{NaN(), 0},
-	{NaN(), NaN()},
-}
-var nextafterSC = []float64{
-	0,
-	0,
-	-4.9406564584124654418e-324, // Float64frombits(0x8000000000000001)
-	NaN(),
-	4.9406564584124654418e-324, // Float64frombits(0x0000000000000001)
-	Copysign(0, -1),
-	Copysign(0, -1),
-	-4.9406564584124654418e-324, // Float64frombits(0x8000000000000001)
-	NaN(),
-	NaN(),
-}
-
-var vfpowSC = [][2]float64{
-	{Inf(-1), -Pi},
-	{Inf(-1), -3},
-	{Inf(-1), Copysign(0, -1)},
-	{Inf(-1), 0},
-	{Inf(-1), 1},
-	{Inf(-1), 3},
-	{Inf(-1), Pi},
-	{Inf(-1), NaN()},
-
-	{-Pi, Inf(-1)},
-	{-Pi, -Pi},
-	{-Pi, Copysign(0, -1)},
-	{-Pi, 0},
-	{-Pi, 1},
-	{-Pi, Pi},
-	{-Pi, Inf(1)},
-	{-Pi, NaN()},
-
-	{-1, Inf(-1)},
-	{-1, Inf(1)},
-	{-1, NaN()},
-	{-1 / 2, Inf(-1)},
-	{-1 / 2, Inf(1)},
-	{Copysign(0, -1), Inf(-1)},
-	{Copysign(0, -1), -Pi},
-	{Copysign(0, -1), -3},
-	{Copysign(0, -1), 3},
-	{Copysign(0, -1), Pi},
-	{Copysign(0, -1), Inf(1)},
-
-	{0, Inf(-1)},
-	{0, -Pi},
-	{0, -3},
-	{0, Copysign(0, -1)},
-	{0, 0},
-	{0, 3},
-	{0, Pi},
-	{0, Inf(1)},
-	{0, NaN()},
-
-	{1 / 2, Inf(-1)},
-	{1 / 2, Inf(1)},
-	{1, Inf(-1)},
-	{1, Inf(1)},
-	{1, NaN()},
-
-	{Pi, Inf(-1)},
-	{Pi, Copysign(0, -1)},
-	{Pi, 0},
-	{Pi, 1},
-	{Pi, Inf(1)},
-	{Pi, NaN()},
-	{Inf(1), -Pi},
-	{Inf(1), Copysign(0, -1)},
-	{Inf(1), 0},
-	{Inf(1), 1},
-	{Inf(1), Pi},
-	{Inf(1), NaN()},
-	{NaN(), -Pi},
-	{NaN(), Copysign(0, -1)},
-	{NaN(), 0},
-	{NaN(), 1},
-	{NaN(), Pi},
-	{NaN(), NaN()},
-}
-var powSC = []float64{
-	0,               // pow(-Inf, -Pi)
-	Copysign(0, -1), // pow(-Inf, -3)
-	1,               // pow(-Inf, -0)
-	1,               // pow(-Inf, +0)
-	Inf(-1),         // pow(-Inf, 1)
-	Inf(-1),         // pow(-Inf, 3)
-	Inf(1),          // pow(-Inf, Pi)
-	NaN(),           // pow(-Inf, NaN)
-	0,               // pow(-Pi, -Inf)
-	NaN(),           // pow(-Pi, -Pi)
-	1,               // pow(-Pi, -0)
-	1,               // pow(-Pi, +0)
-	-Pi,             // pow(-Pi, 1)
-	NaN(),           // pow(-Pi, Pi)
-	Inf(1),          // pow(-Pi, +Inf)
-	NaN(),           // pow(-Pi, NaN)
-	1,               // pow(-1, -Inf) IEEE 754-2008
-	1,               // pow(-1, +Inf) IEEE 754-2008
-	NaN(),           // pow(-1, NaN)
-	Inf(1),          // pow(-1/2, -Inf)
-	0,               // pow(-1/2, +Inf)
-	Inf(1),          // pow(-0, -Inf)
-	Inf(1),          // pow(-0, -Pi)
-	Inf(-1),         // pow(-0, -3) IEEE 754-2008
-	Copysign(0, -1), // pow(-0, 3) IEEE 754-2008
-	0,               // pow(-0, +Pi)
-	0,               // pow(-0, +Inf)
-	Inf(1),          // pow(+0, -Inf)
-	Inf(1),          // pow(+0, -Pi)
-	Inf(1),          // pow(+0, -3)
-	1,               // pow(+0, -0)
-	1,               // pow(+0, +0)
-	0,               // pow(+0, 3)
-	0,               // pow(+0, +Pi)
-	0,               // pow(+0, +Inf)
-	NaN(),           // pow(+0, NaN)
-	Inf(1),          // pow(1/2, -Inf)
-	0,               // pow(1/2, +Inf)
-	1,               // pow(1, -Inf) IEEE 754-2008
-	1,               // pow(1, +Inf) IEEE 754-2008
-	1,               // pow(1, NaN) IEEE 754-2008
-	0,               // pow(+Pi, -Inf)
-	1,               // pow(+Pi, -0)
-	1,               // pow(+Pi, +0)
-	Pi,              // pow(+Pi, 1)
-	Inf(1),          // pow(+Pi, +Inf)
-	NaN(),           // pow(+Pi, NaN)
-	0,               // pow(+Inf, -Pi)
-	1,               // pow(+Inf, -0)
-	1,               // pow(+Inf, +0)
-	Inf(1),          // pow(+Inf, 1)
-	Inf(1),          // pow(+Inf, Pi)
-	NaN(),           // pow(+Inf, NaN)
-	NaN(),           // pow(NaN, -Pi)
-	1,               // pow(NaN, -0)
-	1,               // pow(NaN, +0)
-	NaN(),           // pow(NaN, 1)
-	NaN(),           // pow(NaN, +Pi)
-	NaN(),           // pow(NaN, NaN)
-}
-
-var vfpow10SC = []int{
-	MinInt32,
-	MaxInt32,
-	-325,
-	309,
-}
-
-var pow10SC = []float64{
-	0,      // pow10(MinInt32)
-	Inf(1), // pow10(MaxInt32)
-	0,      // pow10(-325)
-	Inf(1), // pow10(309)
-}
-
-var vfsignbitSC = []float64{
-	Inf(-1),
-	Copysign(0, -1),
-	0,
-	Inf(1),
-	NaN(),
-}
-var signbitSC = []bool{
-	true,
-	true,
-	false,
-	false,
-	false,
-}
-
-var vfsinSC = []float64{
-	Inf(-1),
-	Copysign(0, -1),
-	0,
-	Inf(1),
-	NaN(),
-}
-var sinSC = []float64{
-	NaN(),
-	Copysign(0, -1),
-	0,
-	NaN(),
-	NaN(),
-}
-
-var vfsinhSC = []float64{
-	Inf(-1),
-	Copysign(0, -1),
-	0,
-	Inf(1),
-	NaN(),
-}
-var sinhSC = []float64{
-	Inf(-1),
-	Copysign(0, -1),
-	0,
-	Inf(1),
-	NaN(),
-}
-
-var vfsqrtSC = []float64{
-	Inf(-1),
-	-Pi,
-	Copysign(0, -1),
-	0,
-	Inf(1),
-	NaN(),
-}
-var sqrtSC = []float64{
-	NaN(),
-	NaN(),
-	Copysign(0, -1),
-	0,
-	Inf(1),
-	NaN(),
-}
-
-var vftanhSC = []float64{
-	Inf(-1),
-	Copysign(0, -1),
-	0,
-	Inf(1),
-	NaN(),
-}
-var tanhSC = []float64{
-	-1,
-	Copysign(0, -1),
-	0,
-	1,
-	NaN(),
-}
-
-var vfy0SC = []float64{
-	Inf(-1),
-	0,
-	Inf(1),
-	NaN(),
-}
-var y0SC = []float64{
-	NaN(),
-	Inf(-1),
-	0,
-	NaN(),
-}
-var y1SC = []float64{
-	NaN(),
-	Inf(-1),
-	0,
-	NaN(),
-}
-var y2SC = []float64{
-	NaN(),
-	Inf(-1),
-	0,
-	NaN(),
-}
-var yM3SC = []float64{
-	NaN(),
-	Inf(1),
-	0,
-	NaN(),
-}
-
-// arguments and expected results for boundary cases
-const (
-	SmallestNormalFloat64   = 2.2250738585072014e-308 // 2**-1022
-	LargestSubnormalFloat64 = SmallestNormalFloat64 - SmallestNonzeroFloat64
-)
-
-var vffrexpBC = []float64{
-	SmallestNormalFloat64,
-	LargestSubnormalFloat64,
-	SmallestNonzeroFloat64,
-	MaxFloat64,
-	-SmallestNormalFloat64,
-	-LargestSubnormalFloat64,
-	-SmallestNonzeroFloat64,
-	-MaxFloat64,
-}
-var frexpBC = []fi{
-	{0.5, -1021},
-	{0.99999999999999978, -1022},
-	{0.5, -1073},
-	{0.99999999999999989, 1024},
-	{-0.5, -1021},
-	{-0.99999999999999978, -1022},
-	{-0.5, -1073},
-	{-0.99999999999999989, 1024},
-}
-
-var vfldexpBC = []fi{
-	{SmallestNormalFloat64, -52},
-	{LargestSubnormalFloat64, -51},
-	{SmallestNonzeroFloat64, 1074},
-	{MaxFloat64, -(1023 + 1074)},
-	{1, -1075},
-	{-1, -1075},
-	{1, 1024},
-	{-1, 1024},
-}
-var ldexpBC = []float64{
-	SmallestNonzeroFloat64,
-	1e-323, // 2**-1073
-	1,
-	1e-323, // 2**-1073
-	0,
-	Copysign(0, -1),
-	Inf(1),
-	Inf(-1),
-}
-
-var logbBC = []float64{
-	-1022,
-	-1023,
-	-1074,
-	1023,
-	-1022,
-	-1023,
-	-1074,
-	1023,
-}
-
-func tolerance(a, b, e float64) bool {
-	d := a - b
-	if d < 0 {
-		d = -d
-	}
-
-	if a != 0 {
-		e = e * a
-		if e < 0 {
-			e = -e
-		}
-	}
-	return d < e
-}
-func kindaclose(a, b float64) bool { return tolerance(a, b, 1e-8) }
-func close(a, b float64) bool      { return tolerance(a, b, 1e-14) }
-func veryclose(a, b float64) bool  { return tolerance(a, b, 4e-16) }
-func soclose(a, b, e float64) bool { return tolerance(a, b, e) }
-func alike(a, b float64) bool {
-	switch {
-	case IsNaN(a) && IsNaN(b):
-		return true
-	case a == b:
-		return Signbit(a) == Signbit(b)
-	}
-	return false
-}
-
-func TestNaN(t *testing.T) {
-	f64 := NaN()
-	if f64 == f64 {
-		t.Fatalf("NaN() returns %g, expected NaN", f64)
-	}
-	f32 := float32(f64)
-	if f32 == f32 {
-		t.Fatalf("float32(NaN()) is %g, expected NaN", f32)
-	}
-}
-
-func TestAcos(t *testing.T) {
-	for i := 0; i < len(vf); i++ {
-		a := vf[i] / 10
-		if f := Acos(a); !close(acos[i], f) {
-			t.Errorf("Acos(%g) = %g, want %g", a, f, acos[i])
-		}
-	}
-	for i := 0; i < len(vfacosSC); i++ {
-		if f := Acos(vfacosSC[i]); !alike(acosSC[i], f) {
-			t.Errorf("Acos(%g) = %g, want %g", vfacosSC[i], f, acosSC[i])
-		}
-	}
-}
-
-func TestAcosh(t *testing.T) {
-	for i := 0; i < len(vf); i++ {
-		a := 1 + Abs(vf[i])
-		if f := Acosh(a); !veryclose(acosh[i], f) {
-			t.Errorf("Acosh(%g) = %g, want %g", a, f, acosh[i])
-		}
-	}
-	for i := 0; i < len(vfacoshSC); i++ {
-		if f := Acosh(vfacoshSC[i]); !alike(acoshSC[i], f) {
-			t.Errorf("Acosh(%g) = %g, want %g", vfacoshSC[i], f, acoshSC[i])
-		}
-	}
-}
-
-func TestAsin(t *testing.T) {
-	for i := 0; i < len(vf); i++ {
-		a := vf[i] / 10
-		if f := Asin(a); !veryclose(asin[i], f) {
-			t.Errorf("Asin(%g) = %g, want %g", a, f, asin[i])
-		}
-	}
-	for i := 0; i < len(vfasinSC); i++ {
-		if f := Asin(vfasinSC[i]); !alike(asinSC[i], f) {
-			t.Errorf("Asin(%g) = %g, want %g", vfasinSC[i], f, asinSC[i])
-		}
-	}
-}
-
-func TestAsinh(t *testing.T) {
-	for i := 0; i < len(vf); i++ {
-		if f := Asinh(vf[i]); !veryclose(asinh[i], f) {
-			t.Errorf("Asinh(%g) = %g, want %g", vf[i], f, asinh[i])
-		}
-	}
-	for i := 0; i < len(vfasinhSC); i++ {
-		if f := Asinh(vfasinhSC[i]); !alike(asinhSC[i], f) {
-			t.Errorf("Asinh(%g) = %g, want %g", vfasinhSC[i], f, asinhSC[i])
-		}
-	}
-}
-
-func TestAtan(t *testing.T) {
-	for i := 0; i < len(vf); i++ {
-		if f := Atan(vf[i]); !veryclose(atan[i], f) {
-			t.Errorf("Atan(%g) = %g, want %g", vf[i], f, atan[i])
-		}
-	}
-	for i := 0; i < len(vfatanSC); i++ {
-		if f := Atan(vfatanSC[i]); !alike(atanSC[i], f) {
-			t.Errorf("Atan(%g) = %g, want %g", vfatanSC[i], f, atanSC[i])
-		}
-	}
-}
-
-func TestAtanh(t *testing.T) {
-	for i := 0; i < len(vf); i++ {
-		a := vf[i] / 10
-		if f := Atanh(a); !veryclose(atanh[i], f) {
-			t.Errorf("Atanh(%g) = %g, want %g", a, f, atanh[i])
-		}
-	}
-	for i := 0; i < len(vfatanhSC); i++ {
-		if f := Atanh(vfatanhSC[i]); !alike(atanhSC[i], f) {
-			t.Errorf("Atanh(%g) = %g, want %g", vfatanhSC[i], f, atanhSC[i])
-		}
-	}
-}
-
-func TestAtan2(t *testing.T) {
-	for i := 0; i < len(vf); i++ {
-		if f := Atan2(10, vf[i]); !veryclose(atan2[i], f) {
-			t.Errorf("Atan2(10, %g) = %g, want %g", vf[i], f, atan2[i])
-		}
-	}
-	for i := 0; i < len(vfatan2SC); i++ {
-		if f := Atan2(vfatan2SC[i][0], vfatan2SC[i][1]); !alike(atan2SC[i], f) {
-			t.Errorf("Atan2(%g, %g) = %g, want %g", vfatan2SC[i][0], vfatan2SC[i][1], f, atan2SC[i])
-		}
-	}
-}
-
-func TestCbrt(t *testing.T) {
-	for i := 0; i < len(vf); i++ {
-		if f := Cbrt(vf[i]); !veryclose(cbrt[i], f) {
-			t.Errorf("Cbrt(%g) = %g, want %g", vf[i], f, cbrt[i])
-		}
-	}
-	for i := 0; i < len(vfcbrtSC); i++ {
-		if f := Cbrt(vfcbrtSC[i]); !alike(cbrtSC[i], f) {
-			t.Errorf("Cbrt(%g) = %g, want %g", vfcbrtSC[i], f, cbrtSC[i])
-		}
-	}
-}
-
-func TestCeil(t *testing.T) {
-	for i := 0; i < len(vf); i++ {
-		if f := Ceil(vf[i]); ceil[i] != f {
-			t.Errorf("Ceil(%g) = %g, want %g", vf[i], f, ceil[i])
-		}
-	}
-	for i := 0; i < len(vfceilSC); i++ {
-		if f := Ceil(vfceilSC[i]); !alike(ceilSC[i], f) {
-			t.Errorf("Ceil(%g) = %g, want %g", vfceilSC[i], f, ceilSC[i])
-		}
-	}
-}
-
-func TestCopysign(t *testing.T) {
-	for i := 0; i < len(vf); i++ {
-		if f := Copysign(vf[i], -1); copysign[i] != f {
-			t.Errorf("Copysign(%g, -1) = %g, want %g", vf[i], f, copysign[i])
-		}
-	}
-	for i := 0; i < len(vf); i++ {
-		if f := Copysign(vf[i], 1); -copysign[i] != f {
-			t.Errorf("Copysign(%g, 1) = %g, want %g", vf[i], f, -copysign[i])
-		}
-	}
-	for i := 0; i < len(vfcopysignSC); i++ {
-		if f := Copysign(vfcopysignSC[i], -1); !alike(copysignSC[i], f) {
-			t.Errorf("Copysign(%g, -1) = %g, want %g", vfcopysignSC[i], f, copysignSC[i])
-		}
-	}
-}
-
-func TestCos(t *testing.T) {
-	for i := 0; i < len(vf); i++ {
-		if f := Cos(vf[i]); !veryclose(cos[i], f) {
-			t.Errorf("Cos(%g) = %g, want %g", vf[i], f, cos[i])
-		}
-	}
-	for i := 0; i < len(vfcosSC); i++ {
-		if f := Cos(vfcosSC[i]); !alike(cosSC[i], f) {
-			t.Errorf("Cos(%g) = %g, want %g", vfcosSC[i], f, cosSC[i])
-		}
-	}
-}
-
-func TestCosh(t *testing.T) {
-	for i := 0; i < len(vf); i++ {
-		if f := Cosh(vf[i]); !close(cosh[i], f) {
-			t.Errorf("Cosh(%g) = %g, want %g", vf[i], f, cosh[i])
-		}
-	}
-	for i := 0; i < len(vfcoshSC); i++ {
-		if f := Cosh(vfcoshSC[i]); !alike(coshSC[i], f) {
-			t.Errorf("Cosh(%g) = %g, want %g", vfcoshSC[i], f, coshSC[i])
-		}
-	}
-}
-
-func TestErf(t *testing.T) {
-	for i := 0; i < len(vf); i++ {
-		a := vf[i] / 10
-		if f := Erf(a); !veryclose(erf[i], f) {
-			t.Errorf("Erf(%g) = %g, want %g", a, f, erf[i])
-		}
-	}
-	for i := 0; i < len(vferfSC); i++ {
-		if f := Erf(vferfSC[i]); !alike(erfSC[i], f) {
-			t.Errorf("Erf(%g) = %g, want %g", vferfSC[i], f, erfSC[i])
-		}
-	}
-}
-
-func TestErfc(t *testing.T) {
-	for i := 0; i < len(vf); i++ {
-		a := vf[i] / 10
-		if f := Erfc(a); !veryclose(erfc[i], f) {
-			t.Errorf("Erfc(%g) = %g, want %g", a, f, erfc[i])
-		}
-	}
-	for i := 0; i < len(vferfcSC); i++ {
-		if f := Erfc(vferfcSC[i]); !alike(erfcSC[i], f) {
-			t.Errorf("Erfc(%g) = %g, want %g", vferfcSC[i], f, erfcSC[i])
-		}
-	}
-}
-
-func TestExp(t *testing.T) {
-	testExp(t, Exp, "Exp")
-	testExp(t, ExpGo, "ExpGo")
-}
-
-func testExp(t *testing.T, Exp func(float64) float64, name string) {
-	for i := 0; i < len(vf); i++ {
-		if f := Exp(vf[i]); !close(exp[i], f) {
-			t.Errorf("%s(%g) = %g, want %g", name, vf[i], f, exp[i])
-		}
-	}
-	for i := 0; i < len(vfexpSC); i++ {
-		if f := Exp(vfexpSC[i]); !alike(expSC[i], f) {
-			t.Errorf("%s(%g) = %g, want %g", name, vfexpSC[i], f, expSC[i])
-		}
-	}
-}
-
-func TestExpm1(t *testing.T) {
-	for i := 0; i < len(vf); i++ {
-		a := vf[i] / 100
-		if f := Expm1(a); !veryclose(expm1[i], f) {
-			t.Errorf("Expm1(%g) = %g, want %g", a, f, expm1[i])
-		}
-	}
-	for i := 0; i < len(vfexpm1SC); i++ {
-		if f := Expm1(vfexpm1SC[i]); !alike(expm1SC[i], f) {
-			t.Errorf("Expm1(%g) = %g, want %g", vfexpm1SC[i], f, expm1SC[i])
-		}
-	}
-}
-
-func TestExp2(t *testing.T) {
-	testExp2(t, Exp2, "Exp2")
-	testExp2(t, Exp2Go, "Exp2Go")
-}
-
-func testExp2(t *testing.T, Exp2 func(float64) float64, name string) {
-	for i := 0; i < len(vf); i++ {
-		if f := Exp2(vf[i]); !close(exp2[i], f) {
-			t.Errorf("%s(%g) = %g, want %g", name, vf[i], f, exp2[i])
-		}
-	}
-	for i := 0; i < len(vfexpSC); i++ {
-		if f := Exp2(vfexpSC[i]); !alike(expSC[i], f) {
-			t.Errorf("%s(%g) = %g, want %g", name, vfexpSC[i], f, expSC[i])
-		}
-	}
-	for n := -1074; n < 1024; n++ {
-		f := Exp2(float64(n))
-		vf := Ldexp(1, n)
-		if f != vf {
-			t.Errorf("%s(%d) = %g, want %g", name, n, f, vf)
-		}
-	}
-}
-
-func TestAbs(t *testing.T) {
-	for i := 0; i < len(vf); i++ {
-		if f := Abs(vf[i]); fabs[i] != f {
-			t.Errorf("Abs(%g) = %g, want %g", vf[i], f, fabs[i])
-		}
-	}
-	for i := 0; i < len(vffabsSC); i++ {
-		if f := Abs(vffabsSC[i]); !alike(fabsSC[i], f) {
-			t.Errorf("Abs(%g) = %g, want %g", vffabsSC[i], f, fabsSC[i])
-		}
-	}
-}
-
-func TestDim(t *testing.T) {
-	for i := 0; i < len(vf); i++ {
-		if f := Dim(vf[i], 0); fdim[i] != f {
-			t.Errorf("Dim(%g, %g) = %g, want %g", vf[i], 0.0, f, fdim[i])
-		}
-	}
-	for i := 0; i < len(vffdimSC); i++ {
-		if f := Dim(vffdimSC[i][0], vffdimSC[i][1]); !alike(fdimSC[i], f) {
-			t.Errorf("Dim(%g, %g) = %g, want %g", vffdimSC[i][0], vffdimSC[i][1], f, fdimSC[i])
-		}
-	}
-}
-
-func TestFloor(t *testing.T) {
-	for i := 0; i < len(vf); i++ {
-		if f := Floor(vf[i]); floor[i] != f {
-			t.Errorf("Floor(%g) = %g, want %g", vf[i], f, floor[i])
-		}
-	}
-	for i := 0; i < len(vfceilSC); i++ {
-		if f := Floor(vfceilSC[i]); !alike(ceilSC[i], f) {
-			t.Errorf("Floor(%g) = %g, want %g", vfceilSC[i], f, ceilSC[i])
-		}
-	}
-}
-
-func TestMax(t *testing.T) {
-	for i := 0; i < len(vf); i++ {
-		if f := Max(vf[i], ceil[i]); ceil[i] != f {
-			t.Errorf("Max(%g, %g) = %g, want %g", vf[i], ceil[i], f, ceil[i])
-		}
-	}
-	for i := 0; i < len(vffdimSC); i++ {
-		if f := Max(vffdimSC[i][0], vffdimSC[i][1]); !alike(fmaxSC[i], f) {
-			t.Errorf("Max(%g, %g) = %g, want %g", vffdimSC[i][0], vffdimSC[i][1], f, fmaxSC[i])
-		}
-	}
-}
-
-func TestMin(t *testing.T) {
-	for i := 0; i < len(vf); i++ {
-		if f := Min(vf[i], floor[i]); floor[i] != f {
-			t.Errorf("Min(%g, %g) = %g, want %g", vf[i], floor[i], f, floor[i])
-		}
-	}
-	for i := 0; i < len(vffdimSC); i++ {
-		if f := Min(vffdimSC[i][0], vffdimSC[i][1]); !alike(fminSC[i], f) {
-			t.Errorf("Min(%g, %g) = %g, want %g", vffdimSC[i][0], vffdimSC[i][1], f, fminSC[i])
-		}
-	}
-}
-
-func TestMod(t *testing.T) {
-	for i := 0; i < len(vf); i++ {
-		if f := Mod(10, vf[i]); fmod[i] != f {
-			t.Errorf("Mod(10, %g) = %g, want %g", vf[i], f, fmod[i])
-		}
-	}
-	for i := 0; i < len(vffmodSC); i++ {
-		if f := Mod(vffmodSC[i][0], vffmodSC[i][1]); !alike(fmodSC[i], f) {
-			t.Errorf("Mod(%g, %g) = %g, want %g", vffmodSC[i][0], vffmodSC[i][1], f, fmodSC[i])
-		}
-	}
-}
-
-func TestFrexp(t *testing.T) {
-	for i := 0; i < len(vf); i++ {
-		if f, j := Frexp(vf[i]); !veryclose(frexp[i].f, f) || frexp[i].i != j {
-			t.Errorf("Frexp(%g) = %g, %d, want %g, %d", vf[i], f, j, frexp[i].f, frexp[i].i)
-		}
-	}
-	for i := 0; i < len(vffrexpSC); i++ {
-		if f, j := Frexp(vffrexpSC[i]); !alike(frexpSC[i].f, f) || frexpSC[i].i != j {
-			t.Errorf("Frexp(%g) = %g, %d, want %g, %d", vffrexpSC[i], f, j, frexpSC[i].f, frexpSC[i].i)
-		}
-	}
-	for i := 0; i < len(vffrexpBC); i++ {
-		if f, j := Frexp(vffrexpBC[i]); !alike(frexpBC[i].f, f) || frexpBC[i].i != j {
-			t.Errorf("Frexp(%g) = %g, %d, want %g, %d", vffrexpBC[i], f, j, frexpBC[i].f, frexpBC[i].i)
-		}
-	}
-}
-
-func TestGamma(t *testing.T) {
-	for i := 0; i < len(vf); i++ {
-		if f := Gamma(vf[i]); !close(gamma[i], f) {
-			t.Errorf("Gamma(%g) = %g, want %g", vf[i], f, gamma[i])
-		}
-	}
-	for i := 0; i < len(vfgammaSC); i++ {
-		if f := Gamma(vfgammaSC[i]); !alike(gammaSC[i], f) {
-			t.Errorf("Gamma(%g) = %g, want %g", vfgammaSC[i], f, gammaSC[i])
-		}
-	}
-}
-
-func TestHypot(t *testing.T) {
-	for i := 0; i < len(vf); i++ {
-		a := Abs(1e200 * tanh[i] * Sqrt(2))
-		if f := Hypot(1e200*tanh[i], 1e200*tanh[i]); !veryclose(a, f) {
-			t.Errorf("Hypot(%g, %g) = %g, want %g", 1e200*tanh[i], 1e200*tanh[i], f, a)
-		}
-	}
-	for i := 0; i < len(vfhypotSC); i++ {
-		if f := Hypot(vfhypotSC[i][0], vfhypotSC[i][1]); !alike(hypotSC[i], f) {
-			t.Errorf("Hypot(%g, %g) = %g, want %g", vfhypotSC[i][0], vfhypotSC[i][1], f, hypotSC[i])
-		}
-	}
-}
-
-func TestHypotGo(t *testing.T) {
-	for i := 0; i < len(vf); i++ {
-		a := Abs(1e200 * tanh[i] * Sqrt(2))
-		if f := HypotGo(1e200*tanh[i], 1e200*tanh[i]); !veryclose(a, f) {
-			t.Errorf("HypotGo(%g, %g) = %g, want %g", 1e200*tanh[i], 1e200*tanh[i], f, a)
-		}
-	}
-	for i := 0; i < len(vfhypotSC); i++ {
-		if f := HypotGo(vfhypotSC[i][0], vfhypotSC[i][1]); !alike(hypotSC[i], f) {
-			t.Errorf("HypotGo(%g, %g) = %g, want %g", vfhypotSC[i][0], vfhypotSC[i][1], f, hypotSC[i])
-		}
-	}
-}
-
-func TestIlogb(t *testing.T) {
-	for i := 0; i < len(vf); i++ {
-		a := frexp[i].i - 1 // adjust because fr in the interval [½, 1)
-		if e := Ilogb(vf[i]); a != e {
-			t.Errorf("Ilogb(%g) = %d, want %d", vf[i], e, a)
-		}
-	}
-	for i := 0; i < len(vflogbSC); i++ {
-		if e := Ilogb(vflogbSC[i]); ilogbSC[i] != e {
-			t.Errorf("Ilogb(%g) = %d, want %d", vflogbSC[i], e, ilogbSC[i])
-		}
-	}
-	for i := 0; i < len(vffrexpBC); i++ {
-		if e := Ilogb(vffrexpBC[i]); int(logbBC[i]) != e {
-			t.Errorf("Ilogb(%g) = %d, want %d", vffrexpBC[i], e, int(logbBC[i]))
-		}
-	}
-}
-
-func TestJ0(t *testing.T) {
-	for i := 0; i < len(vf); i++ {
-		if f := J0(vf[i]); !soclose(j0[i], f, 4e-14) {
-			t.Errorf("J0(%g) = %g, want %g", vf[i], f, j0[i])
-		}
-	}
-	for i := 0; i < len(vfj0SC); i++ {
-		if f := J0(vfj0SC[i]); !alike(j0SC[i], f) {
-			t.Errorf("J0(%g) = %g, want %g", vfj0SC[i], f, j0SC[i])
-		}
-	}
-}
-
-func TestJ1(t *testing.T) {
-	for i := 0; i < len(vf); i++ {
-		if f := J1(vf[i]); !close(j1[i], f) {
-			t.Errorf("J1(%g) = %g, want %g", vf[i], f, j1[i])
-		}
-	}
-	for i := 0; i < len(vfj0SC); i++ {
-		if f := J1(vfj0SC[i]); !alike(j1SC[i], f) {
-			t.Errorf("J1(%g) = %g, want %g", vfj0SC[i], f, j1SC[i])
-		}
-	}
-}
-
-func TestJn(t *testing.T) {
-	for i := 0; i < len(vf); i++ {
-		if f := Jn(2, vf[i]); !close(j2[i], f) {
-			t.Errorf("Jn(2, %g) = %g, want %g", vf[i], f, j2[i])
-		}
-		if f := Jn(-3, vf[i]); !close(jM3[i], f) {
-			t.Errorf("Jn(-3, %g) = %g, want %g", vf[i], f, jM3[i])
-		}
-	}
-	for i := 0; i < len(vfj0SC); i++ {
-		if f := Jn(2, vfj0SC[i]); !alike(j2SC[i], f) {
-			t.Errorf("Jn(2, %g) = %g, want %g", vfj0SC[i], f, j2SC[i])
-		}
-		if f := Jn(-3, vfj0SC[i]); !alike(jM3SC[i], f) {
-			t.Errorf("Jn(-3, %g) = %g, want %g", vfj0SC[i], f, jM3SC[i])
-		}
-	}
-}
-
-func TestLdexp(t *testing.T) {
-	for i := 0; i < len(vf); i++ {
-		if f := Ldexp(frexp[i].f, frexp[i].i); !veryclose(vf[i], f) {
-			t.Errorf("Ldexp(%g, %d) = %g, want %g", frexp[i].f, frexp[i].i, f, vf[i])
-		}
-	}
-	for i := 0; i < len(vffrexpSC); i++ {
-		if f := Ldexp(frexpSC[i].f, frexpSC[i].i); !alike(vffrexpSC[i], f) {
-			t.Errorf("Ldexp(%g, %d) = %g, want %g", frexpSC[i].f, frexpSC[i].i, f, vffrexpSC[i])
-		}
-	}
-	for i := 0; i < len(vfldexpSC); i++ {
-		if f := Ldexp(vfldexpSC[i].f, vfldexpSC[i].i); !alike(ldexpSC[i], f) {
-			t.Errorf("Ldexp(%g, %d) = %g, want %g", vfldexpSC[i].f, vfldexpSC[i].i, f, ldexpSC[i])
-		}
-	}
-	for i := 0; i < len(vffrexpBC); i++ {
-		if f := Ldexp(frexpBC[i].f, frexpBC[i].i); !alike(vffrexpBC[i], f) {
-			t.Errorf("Ldexp(%g, %d) = %g, want %g", frexpBC[i].f, frexpBC[i].i, f, vffrexpBC[i])
-		}
-	}
-	for i := 0; i < len(vfldexpBC); i++ {
-		if f := Ldexp(vfldexpBC[i].f, vfldexpBC[i].i); !alike(ldexpBC[i], f) {
-			t.Errorf("Ldexp(%g, %d) = %g, want %g", vfldexpBC[i].f, vfldexpBC[i].i, f, ldexpBC[i])
-		}
-	}
-}
-
-func TestLgamma(t *testing.T) {
-	for i := 0; i < len(vf); i++ {
-		if f, s := Lgamma(vf[i]); !close(lgamma[i].f, f) || lgamma[i].i != s {
-			t.Errorf("Lgamma(%g) = %g, %d, want %g, %d", vf[i], f, s, lgamma[i].f, lgamma[i].i)
-		}
-	}
-	for i := 0; i < len(vflgammaSC); i++ {
-		if f, s := Lgamma(vflgammaSC[i]); !alike(lgammaSC[i].f, f) || lgammaSC[i].i != s {
-			t.Errorf("Lgamma(%g) = %g, %d, want %g, %d", vflgammaSC[i], f, s, lgammaSC[i].f, lgammaSC[i].i)
-		}
-	}
-}
-
-func TestLog(t *testing.T) {
-	for i := 0; i < len(vf); i++ {
-		a := Abs(vf[i])
-		if f := Log(a); log[i] != f {
-			t.Errorf("Log(%g) = %g, want %g", a, f, log[i])
-		}
-	}
-	if f := Log(10); f != Ln10 {
-		t.Errorf("Log(%g) = %g, want %g", 10.0, f, Ln10)
-	}
-	for i := 0; i < len(vflogSC); i++ {
-		if f := Log(vflogSC[i]); !alike(logSC[i], f) {
-			t.Errorf("Log(%g) = %g, want %g", vflogSC[i], f, logSC[i])
-		}
-	}
-}
-
-func TestLogb(t *testing.T) {
-	for i := 0; i < len(vf); i++ {
-		if f := Logb(vf[i]); logb[i] != f {
-			t.Errorf("Logb(%g) = %g, want %g", vf[i], f, logb[i])
-		}
-	}
-	for i := 0; i < len(vflogbSC); i++ {
-		if f := Logb(vflogbSC[i]); !alike(logbSC[i], f) {
-			t.Errorf("Logb(%g) = %g, want %g", vflogbSC[i], f, logbSC[i])
-		}
-	}
-	for i := 0; i < len(vffrexpBC); i++ {
-		if f := Logb(vffrexpBC[i]); !alike(logbBC[i], f) {
-			t.Errorf("Logb(%g) = %g, want %g", vffrexpBC[i], f, logbBC[i])
-		}
-	}
-}
-
-func TestLog10(t *testing.T) {
-	for i := 0; i < len(vf); i++ {
-		a := Abs(vf[i])
-		if f := Log10(a); !veryclose(log10[i], f) {
-			t.Errorf("Log10(%g) = %g, want %g", a, f, log10[i])
-		}
-	}
-	if f := Log10(E); f != Log10E {
-		t.Errorf("Log10(%g) = %g, want %g", E, f, Log10E)
-	}
-	for i := 0; i < len(vflogSC); i++ {
-		if f := Log10(vflogSC[i]); !alike(logSC[i], f) {
-			t.Errorf("Log10(%g) = %g, want %g", vflogSC[i], f, logSC[i])
-		}
-	}
-}
-
-func TestLog1p(t *testing.T) {
-	for i := 0; i < len(vf); i++ {
-		a := vf[i] / 100
-		if f := Log1p(a); !veryclose(log1p[i], f) {
-			t.Errorf("Log1p(%g) = %g, want %g", a, f, log1p[i])
-		}
-	}
-	a := 9.0
-	if f := Log1p(a); f != Ln10 {
-		t.Errorf("Log1p(%g) = %g, want %g", a, f, Ln10)
-	}
-	for i := 0; i < len(vflogSC); i++ {
-		if f := Log1p(vflog1pSC[i]); !alike(log1pSC[i], f) {
-			t.Errorf("Log1p(%g) = %g, want %g", vflog1pSC[i], f, log1pSC[i])
-		}
-	}
-}
-
-func TestLog2(t *testing.T) {
-	for i := 0; i < len(vf); i++ {
-		a := Abs(vf[i])
-		if f := Log2(a); !veryclose(log2[i], f) {
-			t.Errorf("Log2(%g) = %g, want %g", a, f, log2[i])
-		}
-	}
-	if f := Log2(E); f != Log2E {
-		t.Errorf("Log2(%g) = %g, want %g", E, f, Log2E)
-	}
-	for i := 0; i < len(vflogSC); i++ {
-		if f := Log2(vflogSC[i]); !alike(logSC[i], f) {
-			t.Errorf("Log2(%g) = %g, want %g", vflogSC[i], f, logSC[i])
-		}
-	}
-	for i := -1074; i <= 1023; i++ {
-		f := Ldexp(1, i)
-		l := Log2(f)
-		if l != float64(i) {
-			t.Errorf("Log2(2**%d) = %g, want %d", i, l, i)
-		}
-	}
-}
-
-func TestModf(t *testing.T) {
-	for i := 0; i < len(vf); i++ {
-		if f, g := Modf(vf[i]); !veryclose(modf[i][0], f) || !veryclose(modf[i][1], g) {
-			t.Errorf("Modf(%g) = %g, %g, want %g, %g", vf[i], f, g, modf[i][0], modf[i][1])
-		}
-	}
-	for i := 0; i < len(vfmodfSC); i++ {
-		if f, g := Modf(vfmodfSC[i]); !alike(modfSC[i][0], f) || !alike(modfSC[i][1], g) {
-			t.Errorf("Modf(%g) = %g, %g, want %g, %g", vfmodfSC[i], f, g, modfSC[i][0], modfSC[i][1])
-		}
-	}
-}
-
-func TestNextafter(t *testing.T) {
-	for i := 0; i < len(vf); i++ {
-		if f := Nextafter(vf[i], 10); nextafter[i] != f {
-			t.Errorf("Nextafter(%g, %g) = %g want %g", vf[i], 10.0, f, nextafter[i])
-		}
-	}
-	for i := 0; i < len(vfnextafterSC); i++ {
-		if f := Nextafter(vfnextafterSC[i][0], vfnextafterSC[i][1]); !alike(nextafterSC[i], f) {
-			t.Errorf("Nextafter(%g, %g) = %g want %g", vfnextafterSC[i][0], vfnextafterSC[i][1], f, nextafterSC[i])
-		}
-	}
-}
-
-func TestPow(t *testing.T) {
-	for i := 0; i < len(vf); i++ {
-		if f := Pow(10, vf[i]); !close(pow[i], f) {
-			t.Errorf("Pow(10, %g) = %g, want %g", vf[i], f, pow[i])
-		}
-	}
-	for i := 0; i < len(vfpowSC); i++ {
-		if f := Pow(vfpowSC[i][0], vfpowSC[i][1]); !alike(powSC[i], f) {
-			t.Errorf("Pow(%g, %g) = %g, want %g", vfpowSC[i][0], vfpowSC[i][1], f, powSC[i])
-		}
-	}
-}
-
-func TestPow10(t *testing.T) {
-	for i := 0; i < len(vfpow10SC); i++ {
-		if f := Pow10(vfpow10SC[i]); !alike(pow10SC[i], f) {
-			t.Errorf("Pow10(%d) = %g, want %g", vfpow10SC[i], f, pow10SC[i])
-		}
-	}
-}
-
-func TestRemainder(t *testing.T) {
-	for i := 0; i < len(vf); i++ {
-		if f := Remainder(10, vf[i]); remainder[i] != f {
-			t.Errorf("Remainder(10, %g) = %g, want %g", vf[i], f, remainder[i])
-		}
-	}
-	for i := 0; i < len(vffmodSC); i++ {
-		if f := Remainder(vffmodSC[i][0], vffmodSC[i][1]); !alike(fmodSC[i], f) {
-			t.Errorf("Remainder(%g, %g) = %g, want %g", vffmodSC[i][0], vffmodSC[i][1], f, fmodSC[i])
-		}
-	}
-}
-
-func TestSignbit(t *testing.T) {
-	for i := 0; i < len(vf); i++ {
-		if f := Signbit(vf[i]); signbit[i] != f {
-			t.Errorf("Signbit(%g) = %t, want %t", vf[i], f, signbit[i])
-		}
-	}
-	for i := 0; i < len(vfsignbitSC); i++ {
-		if f := Signbit(vfsignbitSC[i]); signbitSC[i] != f {
-			t.Errorf("Signbit(%g) = %t, want %t", vfsignbitSC[i], f, signbitSC[i])
-		}
-	}
-}
-func TestSin(t *testing.T) {
-	for i := 0; i < len(vf); i++ {
-		if f := Sin(vf[i]); !veryclose(sin[i], f) {
-			t.Errorf("Sin(%g) = %g, want %g", vf[i], f, sin[i])
-		}
-	}
-	for i := 0; i < len(vfsinSC); i++ {
-		if f := Sin(vfsinSC[i]); !alike(sinSC[i], f) {
-			t.Errorf("Sin(%g) = %g, want %g", vfsinSC[i], f, sinSC[i])
-		}
-	}
-}
-
-func TestSincos(t *testing.T) {
-	for i := 0; i < len(vf); i++ {
-		if s, c := Sincos(vf[i]); !veryclose(sin[i], s) || !veryclose(cos[i], c) {
-			t.Errorf("Sincos(%g) = %g, %g want %g, %g", vf[i], s, c, sin[i], cos[i])
-		}
-	}
-}
-
-func TestSinh(t *testing.T) {
-	for i := 0; i < len(vf); i++ {
-		if f := Sinh(vf[i]); !close(sinh[i], f) {
-			t.Errorf("Sinh(%g) = %g, want %g", vf[i], f, sinh[i])
-		}
-	}
-	for i := 0; i < len(vfsinhSC); i++ {
-		if f := Sinh(vfsinhSC[i]); !alike(sinhSC[i], f) {
-			t.Errorf("Sinh(%g) = %g, want %g", vfsinhSC[i], f, sinhSC[i])
-		}
-	}
-}
-
-func TestSqrt(t *testing.T) {
-	for i := 0; i < len(vf); i++ {
-		a := Abs(vf[i])
-		if f := SqrtGo(a); sqrt[i] != f {
-			t.Errorf("SqrtGo(%g) = %g, want %g", a, f, sqrt[i])
-		}
-		a = Abs(vf[i])
-		if f := Sqrt(a); sqrt[i] != f {
-			t.Errorf("Sqrt(%g) = %g, want %g", a, f, sqrt[i])
-		}
-	}
-	for i := 0; i < len(vfsqrtSC); i++ {
-		if f := SqrtGo(vfsqrtSC[i]); !alike(sqrtSC[i], f) {
-			t.Errorf("SqrtGo(%g) = %g, want %g", vfsqrtSC[i], f, sqrtSC[i])
-		}
-		if f := Sqrt(vfsqrtSC[i]); !alike(sqrtSC[i], f) {
-			t.Errorf("Sqrt(%g) = %g, want %g", vfsqrtSC[i], f, sqrtSC[i])
-		}
-	}
-}
-
-func TestTan(t *testing.T) {
-	for i := 0; i < len(vf); i++ {
-		if f := Tan(vf[i]); !veryclose(tan[i], f) {
-			t.Errorf("Tan(%g) = %g, want %g", vf[i], f, tan[i])
-		}
-	}
-	// same special cases as Sin
-	for i := 0; i < len(vfsinSC); i++ {
-		if f := Tan(vfsinSC[i]); !alike(sinSC[i], f) {
-			t.Errorf("Tan(%g) = %g, want %g", vfsinSC[i], f, sinSC[i])
-		}
-	}
-}
-
-func TestTanh(t *testing.T) {
-	for i := 0; i < len(vf); i++ {
-		if f := Tanh(vf[i]); !veryclose(tanh[i], f) {
-			t.Errorf("Tanh(%g) = %g, want %g", vf[i], f, tanh[i])
-		}
-	}
-	for i := 0; i < len(vftanhSC); i++ {
-		if f := Tanh(vftanhSC[i]); !alike(tanhSC[i], f) {
-			t.Errorf("Tanh(%g) = %g, want %g", vftanhSC[i], f, tanhSC[i])
-		}
-	}
-}
-
-func TestTrunc(t *testing.T) {
-	for i := 0; i < len(vf); i++ {
-		if f := Trunc(vf[i]); trunc[i] != f {
-			t.Errorf("Trunc(%g) = %g, want %g", vf[i], f, trunc[i])
-		}
-	}
-	for i := 0; i < len(vfceilSC); i++ {
-		if f := Trunc(vfceilSC[i]); !alike(ceilSC[i], f) {
-			t.Errorf("Trunc(%g) = %g, want %g", vfceilSC[i], f, ceilSC[i])
-		}
-	}
-}
-
-func TestY0(t *testing.T) {
-	for i := 0; i < len(vf); i++ {
-		a := Abs(vf[i])
-		if f := Y0(a); !close(y0[i], f) {
-			t.Errorf("Y0(%g) = %g, want %g", a, f, y0[i])
-		}
-	}
-	for i := 0; i < len(vfy0SC); i++ {
-		if f := Y0(vfy0SC[i]); !alike(y0SC[i], f) {
-			t.Errorf("Y0(%g) = %g, want %g", vfy0SC[i], f, y0SC[i])
-		}
-	}
-}
-
-func TestY1(t *testing.T) {
-	for i := 0; i < len(vf); i++ {
-		a := Abs(vf[i])
-		if f := Y1(a); !soclose(y1[i], f, 2e-14) {
-			t.Errorf("Y1(%g) = %g, want %g", a, f, y1[i])
-		}
-	}
-	for i := 0; i < len(vfy0SC); i++ {
-		if f := Y1(vfy0SC[i]); !alike(y1SC[i], f) {
-			t.Errorf("Y1(%g) = %g, want %g", vfy0SC[i], f, y1SC[i])
-		}
-	}
-}
-
-func TestYn(t *testing.T) {
-	for i := 0; i < len(vf); i++ {
-		a := Abs(vf[i])
-		if f := Yn(2, a); !close(y2[i], f) {
-			t.Errorf("Yn(2, %g) = %g, want %g", a, f, y2[i])
-		}
-		if f := Yn(-3, a); !close(yM3[i], f) {
-			t.Errorf("Yn(-3, %g) = %g, want %g", a, f, yM3[i])
-		}
-	}
-	for i := 0; i < len(vfy0SC); i++ {
-		if f := Yn(2, vfy0SC[i]); !alike(y2SC[i], f) {
-			t.Errorf("Yn(2, %g) = %g, want %g", vfy0SC[i], f, y2SC[i])
-		}
-		if f := Yn(-3, vfy0SC[i]); !alike(yM3SC[i], f) {
-			t.Errorf("Yn(-3, %g) = %g, want %g", vfy0SC[i], f, yM3SC[i])
-		}
-	}
-}
-
-// Check that math functions of high angle values
-// return accurate results. [Since (vf[i] + large) - large != vf[i],
-// testing for Trig(vf[i] + large) == Trig(vf[i]), where large is
-// a multiple of 2*Pi, is misleading.]
-func TestLargeCos(t *testing.T) {
-	large := float64(100000 * Pi)
-	for i := 0; i < len(vf); i++ {
-		f1 := cosLarge[i]
-		f2 := Cos(vf[i] + large)
-		if !close(f1, f2) {
-			t.Errorf("Cos(%g) = %g, want %g", vf[i]+large, f2, f1)
-		}
-	}
-}
-
-func TestLargeSin(t *testing.T) {
-	large := float64(100000 * Pi)
-	for i := 0; i < len(vf); i++ {
-		f1 := sinLarge[i]
-		f2 := Sin(vf[i] + large)
-		if !close(f1, f2) {
-			t.Errorf("Sin(%g) = %g, want %g", vf[i]+large, f2, f1)
-		}
-	}
-}
-
-func TestLargeSincos(t *testing.T) {
-	large := float64(100000 * Pi)
-	for i := 0; i < len(vf); i++ {
-		f1, g1 := sinLarge[i], cosLarge[i]
-		f2, g2 := Sincos(vf[i] + large)
-		if !close(f1, f2) || !close(g1, g2) {
-			t.Errorf("Sincos(%g) = %g, %g, want %g, %g", vf[i]+large, f2, g2, f1, g1)
-		}
-	}
-}
-
-func TestLargeTan(t *testing.T) {
-	large := float64(100000 * Pi)
-	for i := 0; i < len(vf); i++ {
-		f1 := tanLarge[i]
-		f2 := Tan(vf[i] + large)
-		if !close(f1, f2) {
-			t.Errorf("Tan(%g) = %g, want %g", vf[i]+large, f2, f1)
-		}
-	}
-}
-
-// Check that math constants are accepted by compiler
-// and have right value (assumes strconv.ParseFloat works).
-// http://code.google.com/p/go/issues/detail?id=201
-
-type floatTest struct {
-	val  interface{}
-	name string
-	str  string
-}
-
-var floatTests = []floatTest{
-	{float64(MaxFloat64), "MaxFloat64", "1.7976931348623157e+308"},
-	{float64(SmallestNonzeroFloat64), "SmallestNonzeroFloat64", "5e-324"},
-	{float32(MaxFloat32), "MaxFloat32", "3.4028235e+38"},
-	{float32(SmallestNonzeroFloat32), "SmallestNonzeroFloat32", "1e-45"},
-}
-
-func TestFloatMinMax(t *testing.T) {
-	for _, tt := range floatTests {
-		s := fmt.Sprint(tt.val)
-		if s != tt.str {
-			t.Errorf("Sprint(%v) = %s, want %s", tt.name, s, tt.str)
-		}
-	}
-}
-
-// Benchmarks
-
-func BenchmarkAcos(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		Acos(.5)
-	}
-}
-
-func BenchmarkAcosh(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		Acosh(1.5)
-	}
-}
-
-func BenchmarkAsin(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		Asin(.5)
-	}
-}
-
-func BenchmarkAsinh(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		Asinh(.5)
-	}
-}
-
-func BenchmarkAtan(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		Atan(.5)
-	}
-}
-
-func BenchmarkAtanh(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		Atanh(.5)
-	}
-}
-
-func BenchmarkAtan2(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		Atan2(.5, 1)
-	}
-}
-
-func BenchmarkCbrt(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		Cbrt(10)
-	}
-}
-
-func BenchmarkCeil(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		Ceil(.5)
-	}
-}
-
-func BenchmarkCopysign(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		Copysign(.5, -1)
-	}
-}
-
-func BenchmarkCos(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		Cos(.5)
-	}
-}
-
-func BenchmarkCosh(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		Cosh(2.5)
-	}
-}
-
-func BenchmarkErf(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		Erf(.5)
-	}
-}
-
-func BenchmarkErfc(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		Erfc(.5)
-	}
-}
-
-func BenchmarkExp(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		Exp(.5)
-	}
-}
-
-func BenchmarkExpGo(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		ExpGo(.5)
-	}
-}
-
-func BenchmarkExpm1(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		Expm1(.5)
-	}
-}
-
-func BenchmarkExp2(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		Exp2(.5)
-	}
-}
-
-func BenchmarkExp2Go(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		Exp2Go(.5)
-	}
-}
-
-func BenchmarkAbs(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		Abs(.5)
-	}
-}
-
-func BenchmarkDim(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		Dim(10, 3)
-	}
-}
-
-func BenchmarkFloor(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		Floor(.5)
-	}
-}
-
-func BenchmarkMax(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		Max(10, 3)
-	}
-}
-
-func BenchmarkMin(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		Min(10, 3)
-	}
-}
-
-func BenchmarkMod(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		Mod(10, 3)
-	}
-}
-
-func BenchmarkFrexp(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		Frexp(8)
-	}
-}
-
-func BenchmarkGamma(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		Gamma(2.5)
-	}
-}
-
-func BenchmarkHypot(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		Hypot(3, 4)
-	}
-}
-
-func BenchmarkHypotGo(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		HypotGo(3, 4)
-	}
-}
-
-func BenchmarkIlogb(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		Ilogb(.5)
-	}
-}
-
-func BenchmarkJ0(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		J0(2.5)
-	}
-}
-
-func BenchmarkJ1(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		J1(2.5)
-	}
-}
-
-func BenchmarkJn(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		Jn(2, 2.5)
-	}
-}
-
-func BenchmarkLdexp(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		Ldexp(.5, 2)
-	}
-}
-
-func BenchmarkLgamma(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		Lgamma(2.5)
-	}
-}
-
-func BenchmarkLog(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		Log(.5)
-	}
-}
-
-func BenchmarkLogb(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		Logb(.5)
-	}
-}
-
-func BenchmarkLog1p(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		Log1p(.5)
-	}
-}
-
-func BenchmarkLog10(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		Log10(.5)
-	}
-}
-
-func BenchmarkLog2(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		Log2(.5)
-	}
-}
-
-func BenchmarkModf(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		Modf(1.5)
-	}
-}
-
-func BenchmarkNextafter(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		Nextafter(.5, 1)
-	}
-}
-
-func BenchmarkPowInt(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		Pow(2, 2)
-	}
-}
-
-func BenchmarkPowFrac(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		Pow(2.5, 1.5)
-	}
-}
-
-func BenchmarkPow10Pos(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		Pow10(300)
-	}
-}
-
-func BenchmarkPow10Neg(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		Pow10(-300)
-	}
-}
-
-func BenchmarkRemainder(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		Remainder(10, 3)
-	}
-}
-
-func BenchmarkSignbit(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		Signbit(2.5)
-	}
-}
-
-func BenchmarkSin(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		Sin(.5)
-	}
-}
-
-func BenchmarkSincos(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		Sincos(.5)
-	}
-}
-
-func BenchmarkSinh(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		Sinh(2.5)
-	}
-}
-
-func BenchmarkSqrt(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		Sqrt(10)
-	}
-}
-
-func BenchmarkSqrtGo(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		SqrtGo(10)
-	}
-}
-
-func BenchmarkTan(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		Tan(.5)
-	}
-}
-
-func BenchmarkTanh(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		Tanh(2.5)
-	}
-}
-func BenchmarkTrunc(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		Trunc(.5)
-	}
-}
-
-func BenchmarkY0(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		Y0(2.5)
-	}
-}
-
-func BenchmarkY1(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		Y1(2.5)
-	}
-}
-
-func BenchmarkYn(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		Yn(2, 2.5)
-	}
-}
diff --git a/src/pkg/math/asin_386.s b/src/pkg/math/asin_386.s
deleted file mode 100644
index 2c1d270..0000000
--- a/src/pkg/math/asin_386.s
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2010 The Go 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 "../../cmd/ld/textflag.h"
-
-// func Asin(x float64) float64
-TEXT ·Asin(SB),NOSPLIT,$0
-	FMOVD   x+0(FP), F0  // F0=sin(x)
-	FMOVD   F0, F1       // F0=sin(x), F1=sin(x)
-	FMULD   F0, F0       // F0=sin(x)*sin(x), F1=sin(x)
-	FLD1                 // F0=1, F1=sin(x)*sin(x), F2=sin(x)
-	FSUBRDP F0, F1       // F0=1-sin(x)*sin(x) (=cos(x)*cos(x)), F1=sin(x)
-	FSQRT                // F0=cos(x), F1=sin(x)
-	FPATAN               // F0=arcsin(sin(x))=x
-	FMOVDP  F0, ret+8(FP)
-	RET
-
-// func Acos(x float64) float64
-TEXT ·Acos(SB),NOSPLIT,$0
-	FMOVD   x+0(FP), F0  // F0=cos(x)
-	FMOVD   F0, F1       // F0=cos(x), F1=cos(x)
-	FMULD   F0, F0       // F0=cos(x)*cos(x), F1=cos(x)
-	FLD1                 // F0=1, F1=cos(x)*cos(x), F2=cos(x)
-	FSUBRDP F0, F1       // F0=1-cos(x)*cos(x) (=sin(x)*sin(x)), F1=cos(x)
-	FSQRT                // F0=sin(x), F1=cos(x)
-	FXCHD   F0, F1       // F0=cos(x), F1=sin(x)
-	FPATAN               // F0=arccos(cos(x))=x
-	FMOVDP	F0, ret+8(FP)
-	RET
diff --git a/src/pkg/math/asin_amd64.s b/src/pkg/math/asin_amd64.s
deleted file mode 100644
index ea48104..0000000
--- a/src/pkg/math/asin_amd64.s
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2011 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../cmd/ld/textflag.h"
-
-TEXT ·Asin(SB),NOSPLIT,$0
-	JMP ·asin(SB)
-
-TEXT ·Acos(SB),NOSPLIT,$0
-	JMP ·acos(SB)
diff --git a/src/pkg/math/asin_arm.s b/src/pkg/math/asin_arm.s
deleted file mode 100644
index b905260..0000000
--- a/src/pkg/math/asin_arm.s
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2011 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../cmd/ld/textflag.h"
-
-TEXT ·Asin(SB),NOSPLIT,$0
-	B ·asin(SB)
-
-TEXT ·Acos(SB),NOSPLIT,$0
-	B ·acos(SB)
diff --git a/src/pkg/math/atan2_386.s b/src/pkg/math/atan2_386.s
deleted file mode 100644
index fb64931..0000000
--- a/src/pkg/math/atan2_386.s
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2010 The Go 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 "../../cmd/ld/textflag.h"
-
-// func Atan2(y, x float64) float64	// =atan(y/x)
-TEXT ·Atan2(SB),NOSPLIT,$0
-	FMOVD   y+0(FP), F0  // F0=y
-	FMOVD   x+8(FP), F0  // F0=x, F1=y
-	FPATAN               // F0=atan(F1/F0)
-	FMOVDP  F0, ret+16(FP)
-	RET
diff --git a/src/pkg/math/atan2_amd64.s b/src/pkg/math/atan2_amd64.s
deleted file mode 100644
index f7a5a11..0000000
--- a/src/pkg/math/atan2_amd64.s
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright 2011 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../cmd/ld/textflag.h"
-
-TEXT ·Atan2(SB),NOSPLIT,$0
-	JMP ·atan2(SB)
diff --git a/src/pkg/math/atan2_arm.s b/src/pkg/math/atan2_arm.s
deleted file mode 100644
index 24bff2c..0000000
--- a/src/pkg/math/atan2_arm.s
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright 2011 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../cmd/ld/textflag.h"
-
-TEXT ·Atan2(SB),NOSPLIT,$0
-	B ·atan2(SB)
diff --git a/src/pkg/math/atan_386.s b/src/pkg/math/atan_386.s
deleted file mode 100644
index aad8ffc..0000000
--- a/src/pkg/math/atan_386.s
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2010 The Go 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 "../../cmd/ld/textflag.h"
-
-// func Atan(x float64) float64
-TEXT ·Atan(SB),NOSPLIT,$0
-	FMOVD   x+0(FP), F0  // F0=x
-	FLD1                 // F0=1, F1=x
-	FPATAN               // F0=atan(F1/F0)
-	FMOVDP  F0, ret+8(FP)
-	RET
diff --git a/src/pkg/math/atan_amd64.s b/src/pkg/math/atan_amd64.s
deleted file mode 100644
index fc4a91b..0000000
--- a/src/pkg/math/atan_amd64.s
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright 2011 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../cmd/ld/textflag.h"
-
-TEXT ·Atan(SB),NOSPLIT,$0
-	JMP ·atan(SB)
diff --git a/src/pkg/math/atan_arm.s b/src/pkg/math/atan_arm.s
deleted file mode 100644
index defa93a..0000000
--- a/src/pkg/math/atan_arm.s
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright 2011 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../cmd/ld/textflag.h"
-
-TEXT ·Atan(SB),NOSPLIT,$0
-	B ·atan(SB)
diff --git a/src/pkg/math/big/arith_386.s b/src/pkg/math/big/arith_386.s
deleted file mode 100644
index 15b036c..0000000
--- a/src/pkg/math/big/arith_386.s
+++ /dev/null
@@ -1,278 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../../cmd/ld/textflag.h"
-
-// This file provides fast assembly versions for the elementary
-// arithmetic operations on vectors implemented in arith.go.
-
-// func mulWW(x, y Word) (z1, z0 Word)
-TEXT ·mulWW(SB),NOSPLIT,$0
-	MOVL x+0(FP), AX
-	MULL y+4(FP)
-	MOVL DX, z1+8(FP)
-	MOVL AX, z0+12(FP)
-	RET
-
-
-// func divWW(x1, x0, y Word) (q, r Word)
-TEXT ·divWW(SB),NOSPLIT,$0
-	MOVL x1+0(FP), DX
-	MOVL x0+4(FP), AX
-	DIVL y+8(FP)
-	MOVL AX, q+12(FP)
-	MOVL DX, r+16(FP)
-	RET
-
-
-// func addVV(z, x, y []Word) (c Word)
-TEXT ·addVV(SB),NOSPLIT,$0
-	MOVL z+0(FP), DI
-	MOVL x+12(FP), SI
-	MOVL y+24(FP), CX
-	MOVL z_len+4(FP), BP
-	MOVL $0, BX		// i = 0
-	MOVL $0, DX		// c = 0
-	JMP E1
-
-L1:	MOVL (SI)(BX*4), AX
-	RCRL $1, DX
-	ADCL (CX)(BX*4), AX
-	RCLL $1, DX
-	MOVL AX, (DI)(BX*4)
-	ADDL $1, BX		// i++
-
-E1:	CMPL BX, BP		// i < n
-	JL L1
-
-	MOVL DX, c+36(FP)
-	RET
-
-
-// func subVV(z, x, y []Word) (c Word)
-// (same as addVV except for SBBL instead of ADCL and label names)
-TEXT ·subVV(SB),NOSPLIT,$0
-	MOVL z+0(FP), DI
-	MOVL x+12(FP), SI
-	MOVL y+24(FP), CX
-	MOVL z_len+4(FP), BP
-	MOVL $0, BX		// i = 0
-	MOVL $0, DX		// c = 0
-	JMP E2
-
-L2:	MOVL (SI)(BX*4), AX
-	RCRL $1, DX
-	SBBL (CX)(BX*4), AX
-	RCLL $1, DX
-	MOVL AX, (DI)(BX*4)
-	ADDL $1, BX		// i++
-
-E2:	CMPL BX, BP		// i < n
-	JL L2
-
-	MOVL DX, c+36(FP)
-	RET
-
-
-// func addVW(z, x []Word, y Word) (c Word)
-TEXT ·addVW(SB),NOSPLIT,$0
-	MOVL z+0(FP), DI
-	MOVL x+12(FP), SI
-	MOVL y+24(FP), AX	// c = y
-	MOVL z_len+4(FP), BP
-	MOVL $0, BX		// i = 0
-	JMP E3
-
-L3:	ADDL (SI)(BX*4), AX
-	MOVL AX, (DI)(BX*4)
-	RCLL $1, AX
-	ANDL $1, AX
-	ADDL $1, BX		// i++
-
-E3:	CMPL BX, BP		// i < n
-	JL L3
-
-	MOVL AX, c+28(FP)
-	RET
-
-
-// func subVW(z, x []Word, y Word) (c Word)
-TEXT ·subVW(SB),NOSPLIT,$0
-	MOVL z+0(FP), DI
-	MOVL x+12(FP), SI
-	MOVL y+24(FP), AX	// c = y
-	MOVL z_len+4(FP), BP
-	MOVL $0, BX		// i = 0
-	JMP E4
-
-L4:	MOVL (SI)(BX*4), DX	// TODO(gri) is there a reverse SUBL?
-	SUBL AX, DX
-	MOVL DX, (DI)(BX*4)
-	RCLL $1, AX
-	ANDL $1, AX
-	ADDL $1, BX		// i++
-
-E4:	CMPL BX, BP		// i < n
-	JL L4
-
-	MOVL AX, c+28(FP)
-	RET
-
-
-// func shlVU(z, x []Word, s uint) (c Word)
-TEXT ·shlVU(SB),NOSPLIT,$0
-	MOVL z_len+4(FP), BX	// i = z
-	SUBL $1, BX		// i--
-	JL X8b			// i < 0	(n <= 0)
-
-	// n > 0
-	MOVL z+0(FP), DI
-	MOVL x+12(FP), SI
-	MOVL s+24(FP), CX
-	MOVL (SI)(BX*4), AX	// w1 = x[n-1]
-	MOVL $0, DX
-	SHLL CX, DX:AX		// w1>>ŝ
-	MOVL DX, c+28(FP)
-
-	CMPL BX, $0
-	JLE X8a			// i <= 0
-
-	// i > 0
-L8:	MOVL AX, DX		// w = w1
-	MOVL -4(SI)(BX*4), AX	// w1 = x[i-1]
-	SHLL CX, DX:AX		// w<<s | w1>>ŝ
-	MOVL DX, (DI)(BX*4)	// z[i] = w<<s | w1>>ŝ
-	SUBL $1, BX		// i--
-	JG L8			// i > 0
-
-	// i <= 0
-X8a:	SHLL CX, AX		// w1<<s
-	MOVL AX, (DI)		// z[0] = w1<<s
-	RET
-
-X8b:	MOVL $0, c+28(FP)
-	RET
-
-
-// func shrVU(z, x []Word, s uint) (c Word)
-TEXT ·shrVU(SB),NOSPLIT,$0
-	MOVL z_len+4(FP), BP
-	SUBL $1, BP		// n--
-	JL X9b			// n < 0	(n <= 0)
-
-	// n > 0
-	MOVL z+0(FP), DI
-	MOVL x+12(FP), SI
-	MOVL s+24(FP), CX
-	MOVL (SI), AX		// w1 = x[0]
-	MOVL $0, DX
-	SHRL CX, DX:AX		// w1<<ŝ
-	MOVL DX, c+28(FP)
-
-	MOVL $0, BX		// i = 0
-	JMP E9
-
-	// i < n-1
-L9:	MOVL AX, DX		// w = w1
-	MOVL 4(SI)(BX*4), AX	// w1 = x[i+1]
-	SHRL CX, DX:AX		// w>>s | w1<<ŝ
-	MOVL DX, (DI)(BX*4)	// z[i] = w>>s | w1<<ŝ
-	ADDL $1, BX		// i++
-	
-E9:	CMPL BX, BP
-	JL L9			// i < n-1
-
-	// i >= n-1
-X9a:	SHRL CX, AX		// w1>>s
-	MOVL AX, (DI)(BP*4)	// z[n-1] = w1>>s
-	RET
-
-X9b:	MOVL $0, c+28(FP)
-	RET
-
-
-// func mulAddVWW(z, x []Word, y, r Word) (c Word)
-TEXT ·mulAddVWW(SB),NOSPLIT,$0
-	MOVL z+0(FP), DI
-	MOVL x+12(FP), SI
-	MOVL y+24(FP), BP
-	MOVL r+28(FP), CX	// c = r
-	MOVL z_len+4(FP), BX
-	LEAL (DI)(BX*4), DI
-	LEAL (SI)(BX*4), SI
-	NEGL BX			// i = -n
-	JMP E5
-
-L5:	MOVL (SI)(BX*4), AX
-	MULL BP
-	ADDL CX, AX
-	ADCL $0, DX
-	MOVL AX, (DI)(BX*4)
-	MOVL DX, CX
-	ADDL $1, BX		// i++
-
-E5:	CMPL BX, $0		// i < 0
-	JL L5
-
-	MOVL CX, c+32(FP)
-	RET
-
-
-// func addMulVVW(z, x []Word, y Word) (c Word)
-TEXT ·addMulVVW(SB),NOSPLIT,$0
-	MOVL z+0(FP), DI
-	MOVL x+12(FP), SI
-	MOVL y+24(FP), BP
-	MOVL z_len+4(FP), BX
-	LEAL (DI)(BX*4), DI
-	LEAL (SI)(BX*4), SI
-	NEGL BX			// i = -n
-	MOVL $0, CX		// c = 0
-	JMP E6
-
-L6:	MOVL (SI)(BX*4), AX
-	MULL BP
-	ADDL CX, AX
-	ADCL $0, DX
-	ADDL AX, (DI)(BX*4)
-	ADCL $0, DX
-	MOVL DX, CX
-	ADDL $1, BX		// i++
-
-E6:	CMPL BX, $0		// i < 0
-	JL L6
-
-	MOVL CX, c+28(FP)
-	RET
-
-
-// func divWVW(z* Word, xn Word, x []Word, y Word) (r Word)
-TEXT ·divWVW(SB),NOSPLIT,$0
-	MOVL z+0(FP), DI
-	MOVL xn+12(FP), DX	// r = xn
-	MOVL x+16(FP), SI
-	MOVL y+28(FP), CX
-	MOVL z_len+4(FP), BX	// i = z
-	JMP E7
-
-L7:	MOVL (SI)(BX*4), AX
-	DIVL CX
-	MOVL AX, (DI)(BX*4)
-
-E7:	SUBL $1, BX		// i--
-	JGE L7			// i >= 0
-
-	MOVL DX, r+32(FP)
-	RET
-
-// func bitLen(x Word) (n int)
-TEXT ·bitLen(SB),NOSPLIT,$0
-	BSRL x+0(FP), AX
-	JZ Z1
-	INCL AX
-	MOVL AX, n+4(FP)
-	RET
-
-Z1:	MOVL $0, n+4(FP)
-	RET
diff --git a/src/pkg/math/big/arith_amd64.s b/src/pkg/math/big/arith_amd64.s
deleted file mode 100644
index e2113a7..0000000
--- a/src/pkg/math/big/arith_amd64.s
+++ /dev/null
@@ -1,401 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../../cmd/ld/textflag.h"
-
-// This file provides fast assembly versions for the elementary
-// arithmetic operations on vectors implemented in arith.go.
-
-// Literal instruction for MOVQ $0, CX.
-// (MOVQ $0, reg is translated to XORQ reg, reg and clears CF.)
-#define ZERO_CX BYTE $0x48; \
-		BYTE $0xc7; \
-		BYTE $0xc1; \
-		BYTE $0x00; \
-		BYTE $0x00; \
-		BYTE $0x00; \
-		BYTE $0x00
-
-// func mulWW(x, y Word) (z1, z0 Word)
-TEXT ·mulWW(SB),NOSPLIT,$0
-	MOVQ x+0(FP), AX
-	MULQ y+8(FP)
-	MOVQ DX, z1+16(FP)
-	MOVQ AX, z0+24(FP)
-	RET
-
-
-// func divWW(x1, x0, y Word) (q, r Word)
-TEXT ·divWW(SB),NOSPLIT,$0
-	MOVQ x1+0(FP), DX
-	MOVQ x0+8(FP), AX
-	DIVQ y+16(FP)
-	MOVQ AX, q+24(FP)
-	MOVQ DX, r+32(FP)
-	RET
-
-
-// func addVV(z, x, y []Word) (c Word)
-TEXT ·addVV(SB),NOSPLIT,$0
-	MOVQ z_len+8(FP), DI
-	MOVQ x+24(FP), R8
-	MOVQ y+48(FP), R9
-	MOVQ z+0(FP), R10
-
-	MOVQ $0, CX		// c = 0
-	MOVQ $0, SI		// i = 0
-
-	// s/JL/JMP/ below to disable the unrolled loop
-	SUBQ $4, DI		// n -= 4
-	JL V1			// if n < 0 goto V1
-
-U1:	// n >= 0
-	// regular loop body unrolled 4x
-	RCRQ $1, CX		// CF = c
-	MOVQ 0(R8)(SI*8), R11
-	MOVQ 8(R8)(SI*8), R12
-	MOVQ 16(R8)(SI*8), R13
-	MOVQ 24(R8)(SI*8), R14
-	ADCQ 0(R9)(SI*8), R11
-	ADCQ 8(R9)(SI*8), R12
-	ADCQ 16(R9)(SI*8), R13
-	ADCQ 24(R9)(SI*8), R14
-	MOVQ R11, 0(R10)(SI*8)
-	MOVQ R12, 8(R10)(SI*8)
-	MOVQ R13, 16(R10)(SI*8)
-	MOVQ R14, 24(R10)(SI*8)
-	RCLQ $1, CX		// c = CF
-
-	ADDQ $4, SI		// i += 4
-	SUBQ $4, DI		// n -= 4
-	JGE U1			// if n >= 0 goto U1
-
-V1:	ADDQ $4, DI		// n += 4
-	JLE E1			// if n <= 0 goto E1
-
-L1:	// n > 0
-	RCRQ $1, CX		// CF = c
-	MOVQ 0(R8)(SI*8), R11
-	ADCQ 0(R9)(SI*8), R11
-	MOVQ R11, 0(R10)(SI*8)
-	RCLQ $1, CX		// c = CF
-
-	ADDQ $1, SI		// i++
-	SUBQ $1, DI		// n--
-	JG L1			// if n > 0 goto L1
-
-E1:	MOVQ CX, c+72(FP)	// return c
-	RET
-
-
-// func subVV(z, x, y []Word) (c Word)
-// (same as addVV except for SBBQ instead of ADCQ and label names)
-TEXT ·subVV(SB),NOSPLIT,$0
-	MOVQ z_len+8(FP), DI
-	MOVQ x+24(FP), R8
-	MOVQ y+48(FP), R9
-	MOVQ z+0(FP), R10
-
-	MOVQ $0, CX		// c = 0
-	MOVQ $0, SI		// i = 0
-
-	// s/JL/JMP/ below to disable the unrolled loop
-	SUBQ $4, DI		// n -= 4
-	JL V2			// if n < 0 goto V2
-
-U2:	// n >= 0
-	// regular loop body unrolled 4x
-	RCRQ $1, CX		// CF = c
-	MOVQ 0(R8)(SI*8), R11
-	MOVQ 8(R8)(SI*8), R12
-	MOVQ 16(R8)(SI*8), R13
-	MOVQ 24(R8)(SI*8), R14
-	SBBQ 0(R9)(SI*8), R11
-	SBBQ 8(R9)(SI*8), R12
-	SBBQ 16(R9)(SI*8), R13
-	SBBQ 24(R9)(SI*8), R14
-	MOVQ R11, 0(R10)(SI*8)
-	MOVQ R12, 8(R10)(SI*8)
-	MOVQ R13, 16(R10)(SI*8)
-	MOVQ R14, 24(R10)(SI*8)
-	RCLQ $1, CX		// c = CF
-
-	ADDQ $4, SI		// i += 4
-	SUBQ $4, DI		// n -= 4
-	JGE U2			// if n >= 0 goto U2
-
-V2:	ADDQ $4, DI		// n += 4
-	JLE E2			// if n <= 0 goto E2
-
-L2:	// n > 0
-	RCRQ $1, CX		// CF = c
-	MOVQ 0(R8)(SI*8), R11
-	SBBQ 0(R9)(SI*8), R11
-	MOVQ R11, 0(R10)(SI*8)
-	RCLQ $1, CX		// c = CF
-
-	ADDQ $1, SI		// i++
-	SUBQ $1, DI		// n--
-	JG L2			// if n > 0 goto L2
-
-E2:	MOVQ CX, c+72(FP)	// return c
-	RET
-
-
-// func addVW(z, x []Word, y Word) (c Word)
-TEXT ·addVW(SB),NOSPLIT,$0
-	MOVQ z_len+8(FP), DI
-	MOVQ x+24(FP), R8
-	MOVQ y+48(FP), CX	// c = y
-	MOVQ z+0(FP), R10
-
-	MOVQ $0, SI		// i = 0
-
-	// s/JL/JMP/ below to disable the unrolled loop
-	SUBQ $4, DI		// n -= 4
-	JL V3			// if n < 4 goto V3
-
-U3:	// n >= 0
-	// regular loop body unrolled 4x
-	MOVQ 0(R8)(SI*8), R11
-	MOVQ 8(R8)(SI*8), R12
-	MOVQ 16(R8)(SI*8), R13
-	MOVQ 24(R8)(SI*8), R14
-	ADDQ CX, R11
-	ZERO_CX
-	ADCQ $0, R12
-	ADCQ $0, R13
-	ADCQ $0, R14
-	SETCS CX		// c = CF
-	MOVQ R11, 0(R10)(SI*8)
-	MOVQ R12, 8(R10)(SI*8)
-	MOVQ R13, 16(R10)(SI*8)
-	MOVQ R14, 24(R10)(SI*8)
-
-	ADDQ $4, SI		// i += 4
-	SUBQ $4, DI		// n -= 4
-	JGE U3			// if n >= 0 goto U3
-
-V3:	ADDQ $4, DI		// n += 4
-	JLE E3			// if n <= 0 goto E3
-
-L3:	// n > 0
-	ADDQ 0(R8)(SI*8), CX
-	MOVQ CX, 0(R10)(SI*8)
-	ZERO_CX
-	RCLQ $1, CX		// c = CF
-
-	ADDQ $1, SI		// i++
-	SUBQ $1, DI		// n--
-	JG L3			// if n > 0 goto L3
-
-E3:	MOVQ CX, c+56(FP)	// return c
-	RET
-
-
-// func subVW(z, x []Word, y Word) (c Word)
-// (same as addVW except for SUBQ/SBBQ instead of ADDQ/ADCQ and label names)
-TEXT ·subVW(SB),NOSPLIT,$0
-	MOVQ z_len+8(FP), DI
-	MOVQ x+24(FP), R8
-	MOVQ y+48(FP), CX	// c = y
-	MOVQ z+0(FP), R10
-	
-	MOVQ $0, SI		// i = 0
-
-	// s/JL/JMP/ below to disable the unrolled loop
-	SUBQ $4, DI		// n -= 4
-	JL V4			// if n < 4 goto V4
-
-U4:	// n >= 0
-	// regular loop body unrolled 4x
-	MOVQ 0(R8)(SI*8), R11
-	MOVQ 8(R8)(SI*8), R12
-	MOVQ 16(R8)(SI*8), R13
-	MOVQ 24(R8)(SI*8), R14
-	SUBQ CX, R11
-	ZERO_CX
-	SBBQ $0, R12
-	SBBQ $0, R13
-	SBBQ $0, R14
-	SETCS CX		// c = CF
-	MOVQ R11, 0(R10)(SI*8)
-	MOVQ R12, 8(R10)(SI*8)
-	MOVQ R13, 16(R10)(SI*8)
-	MOVQ R14, 24(R10)(SI*8)
-
-	ADDQ $4, SI		// i += 4
-	SUBQ $4, DI		// n -= 4
-	JGE U4			// if n >= 0 goto U4
-
-V4:	ADDQ $4, DI		// n += 4
-	JLE E4			// if n <= 0 goto E4
-
-L4:	// n > 0
-	MOVQ 0(R8)(SI*8), R11
-	SUBQ CX, R11
-	MOVQ R11, 0(R10)(SI*8)
-	ZERO_CX
-	RCLQ $1, CX		// c = CF
-
-	ADDQ $1, SI		// i++
-	SUBQ $1, DI		// n--
-	JG L4			// if n > 0 goto L4
-
-E4:	MOVQ CX, c+56(FP)	// return c
-	RET
-
-
-// func shlVU(z, x []Word, s uint) (c Word)
-TEXT ·shlVU(SB),NOSPLIT,$0
-	MOVQ z_len+8(FP), BX	// i = z
-	SUBQ $1, BX		// i--
-	JL X8b			// i < 0	(n <= 0)
-
-	// n > 0
-	MOVQ z+0(FP), R10
-	MOVQ x+24(FP), R8
-	MOVQ s+48(FP), CX
-	MOVQ (R8)(BX*8), AX	// w1 = x[n-1]
-	MOVQ $0, DX
-	SHLQ CX, DX:AX		// w1>>ŝ
-	MOVQ DX, c+56(FP)
-
-	CMPQ BX, $0
-	JLE X8a			// i <= 0
-
-	// i > 0
-L8:	MOVQ AX, DX		// w = w1
-	MOVQ -8(R8)(BX*8), AX	// w1 = x[i-1]
-	SHLQ CX, DX:AX		// w<<s | w1>>ŝ
-	MOVQ DX, (R10)(BX*8)	// z[i] = w<<s | w1>>ŝ
-	SUBQ $1, BX		// i--
-	JG L8			// i > 0
-
-	// i <= 0
-X8a:	SHLQ CX, AX		// w1<<s
-	MOVQ AX, (R10)		// z[0] = w1<<s
-	RET
-
-X8b:	MOVQ $0, c+56(FP)
-	RET
-
-
-// func shrVU(z, x []Word, s uint) (c Word)
-TEXT ·shrVU(SB),NOSPLIT,$0
-	MOVQ z_len+8(FP), R11
-	SUBQ $1, R11		// n--
-	JL X9b			// n < 0	(n <= 0)
-
-	// n > 0
-	MOVQ z+0(FP), R10
-	MOVQ x+24(FP), R8
-	MOVQ s+48(FP), CX
-	MOVQ (R8), AX		// w1 = x[0]
-	MOVQ $0, DX
-	SHRQ CX, DX:AX		// w1<<ŝ
-	MOVQ DX, c+56(FP)
-
-	MOVQ $0, BX		// i = 0
-	JMP E9
-
-	// i < n-1
-L9:	MOVQ AX, DX		// w = w1
-	MOVQ 8(R8)(BX*8), AX	// w1 = x[i+1]
-	SHRQ CX, DX:AX		// w>>s | w1<<ŝ
-	MOVQ DX, (R10)(BX*8)	// z[i] = w>>s | w1<<ŝ
-	ADDQ $1, BX		// i++
-	
-E9:	CMPQ BX, R11
-	JL L9			// i < n-1
-
-	// i >= n-1
-X9a:	SHRQ CX, AX		// w1>>s
-	MOVQ AX, (R10)(R11*8)	// z[n-1] = w1>>s
-	RET
-
-X9b:	MOVQ $0, c+56(FP)
-	RET
-
-
-// func mulAddVWW(z, x []Word, y, r Word) (c Word)
-TEXT ·mulAddVWW(SB),NOSPLIT,$0
-	MOVQ z+0(FP), R10
-	MOVQ x+24(FP), R8
-	MOVQ y+48(FP), R9
-	MOVQ r+56(FP), CX	// c = r
-	MOVQ z_len+8(FP), R11
-	MOVQ $0, BX		// i = 0
-	JMP E5
-
-L5:	MOVQ (R8)(BX*8), AX
-	MULQ R9
-	ADDQ CX, AX
-	ADCQ $0, DX
-	MOVQ AX, (R10)(BX*8)
-	MOVQ DX, CX
-	ADDQ $1, BX		// i++
-
-E5:	CMPQ BX, R11		// i < n
-	JL L5
-
-	MOVQ CX, c+64(FP)
-	RET
-
-
-// func addMulVVW(z, x []Word, y Word) (c Word)
-TEXT ·addMulVVW(SB),NOSPLIT,$0
-	MOVQ z+0(FP), R10
-	MOVQ x+24(FP), R8
-	MOVQ y+48(FP), R9
-	MOVQ z_len+8(FP), R11
-	MOVQ $0, BX		// i = 0
-	MOVQ $0, CX		// c = 0
-	JMP E6
-
-L6:	MOVQ (R8)(BX*8), AX
-	MULQ R9
-	ADDQ CX, AX
-	ADCQ $0, DX
-	ADDQ AX, (R10)(BX*8)
-	ADCQ $0, DX
-	MOVQ DX, CX
-	ADDQ $1, BX		// i++
-
-E6:	CMPQ BX, R11		// i < n
-	JL L6
-
-	MOVQ CX, c+56(FP)
-	RET
-
-
-// func divWVW(z []Word, xn Word, x []Word, y Word) (r Word)
-TEXT ·divWVW(SB),NOSPLIT,$0
-	MOVQ z+0(FP), R10
-	MOVQ xn+24(FP), DX	// r = xn
-	MOVQ x+32(FP), R8
-	MOVQ y+56(FP), R9
-	MOVQ z_len+8(FP), BX	// i = z
-	JMP E7
-
-L7:	MOVQ (R8)(BX*8), AX
-	DIVQ R9
-	MOVQ AX, (R10)(BX*8)
-
-E7:	SUBQ $1, BX		// i--
-	JGE L7			// i >= 0
-
-	MOVQ DX, r+64(FP)
-	RET
-
-// func bitLen(x Word) (n int)
-TEXT ·bitLen(SB),NOSPLIT,$0
-	BSRQ x+0(FP), AX
-	JZ Z1
-	ADDQ $1, AX
-	MOVQ AX, n+8(FP)
-	RET
-
-Z1:	MOVQ $0, n+8(FP)
-	RET
diff --git a/src/pkg/math/big/arith_amd64p32.s b/src/pkg/math/big/arith_amd64p32.s
deleted file mode 100644
index 227870a..0000000
--- a/src/pkg/math/big/arith_amd64p32.s
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2013 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../../cmd/ld/textflag.h"
-
-TEXT ·mulWW(SB),NOSPLIT,$0
-	JMP ·mulWW_g(SB)
-
-TEXT ·divWW(SB),NOSPLIT,$0
-	JMP ·divWW_g(SB)
-
-TEXT ·addVV(SB),NOSPLIT,$0
-	JMP ·addVV_g(SB)
-
-TEXT ·subVV(SB),NOSPLIT,$0
-	JMP ·subVV_g(SB)
-
-TEXT ·addVW(SB),NOSPLIT,$0
-	JMP ·addVW_g(SB)
-
-TEXT ·subVW(SB),NOSPLIT,$0
-	JMP ·subVW_g(SB)
-
-TEXT ·shlVU(SB),NOSPLIT,$0
-	JMP ·shlVU_g(SB)
-
-TEXT ·shrVU(SB),NOSPLIT,$0
-	JMP ·shrVU_g(SB)
-
-TEXT ·mulAddVWW(SB),NOSPLIT,$0
-	JMP ·mulAddVWW_g(SB)
-
-TEXT ·addMulVVW(SB),NOSPLIT,$0
-	JMP ·addMulVVW_g(SB)
-
-TEXT ·divWVW(SB),NOSPLIT,$0
-	JMP ·divWVW_g(SB)
-
-TEXT ·bitLen(SB),NOSPLIT,$0
-	JMP ·bitLen_g(SB)
diff --git a/src/pkg/math/big/arith_arm.s b/src/pkg/math/big/arith_arm.s
deleted file mode 100644
index 8d36761..0000000
--- a/src/pkg/math/big/arith_arm.s
+++ /dev/null
@@ -1,300 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../../cmd/ld/textflag.h"
-
-// This file provides fast assembly versions for the elementary
-// arithmetic operations on vectors implemented in arith.go.
-
-// func addVV(z, x, y []Word) (c Word)
-TEXT ·addVV(SB),NOSPLIT,$0
-	ADD.S	$0, R0		// clear carry flag
-	MOVW	z+0(FP), R1
-	MOVW	z_len+4(FP), R4
-	MOVW	x+12(FP), R2
-	MOVW	y+24(FP), R3
-	ADD	R4<<2, R1, R4
-	B E1
-L1:
-	MOVW.P	4(R2), R5
-	MOVW.P	4(R3), R6
-	ADC.S	R6, R5
-	MOVW.P	R5, 4(R1)
-E1:
-	TEQ	R1, R4
-	BNE L1
-
-	MOVW	$0, R0
-	MOVW.CS	$1, R0
-	MOVW	R0, c+36(FP)
-	RET
-
-
-// func subVV(z, x, y []Word) (c Word)
-// (same as addVV except for SBC instead of ADC and label names)
-TEXT ·subVV(SB),NOSPLIT,$0
-	SUB.S	$0, R0		// clear borrow flag
-	MOVW	z+0(FP), R1
-	MOVW	z_len+4(FP), R4
-	MOVW	x+12(FP), R2
-	MOVW	y+24(FP), R3
-	ADD	R4<<2, R1, R4
-	B E2
-L2:
-	MOVW.P	4(R2), R5
-	MOVW.P	4(R3), R6
-	SBC.S	R6, R5
-	MOVW.P	R5, 4(R1)
-E2:
-	TEQ	R1, R4
-	BNE L2
-
-	MOVW	$0, R0
-	MOVW.CC	$1, R0
-	MOVW	R0, c+36(FP)
-	RET
-
-
-// func addVW(z, x []Word, y Word) (c Word)
-TEXT ·addVW(SB),NOSPLIT,$0
-	MOVW	z+0(FP), R1
-	MOVW	z_len+4(FP), R4
-	MOVW	x+12(FP), R2
-	MOVW	y+24(FP), R3
-	ADD	R4<<2, R1, R4
-	TEQ	R1, R4
-	BNE L3a
-	MOVW	R3, c+28(FP)
-	RET
-L3a:
-	MOVW.P	4(R2), R5
-	ADD.S	R3, R5
-	MOVW.P	R5, 4(R1)
-	B	E3
-L3:
-	MOVW.P	4(R2), R5
-	ADC.S	$0, R5
-	MOVW.P	R5, 4(R1)
-E3:
-	TEQ	R1, R4
-	BNE	L3
-
-	MOVW	$0, R0
-	MOVW.CS	$1, R0
-	MOVW	R0, c+28(FP)
-	RET
-
-
-// func subVW(z, x []Word, y Word) (c Word)
-TEXT ·subVW(SB),NOSPLIT,$0
-	MOVW	z+0(FP), R1
-	MOVW	z_len+4(FP), R4
-	MOVW	x+12(FP), R2
-	MOVW	y+24(FP), R3
-	ADD	R4<<2, R1, R4
-	TEQ	R1, R4
-	BNE L4a
-	MOVW	R3, c+28(FP)
-	RET
-L4a:
-	MOVW.P	4(R2), R5
-	SUB.S	R3, R5
-	MOVW.P	R5, 4(R1)
-	B	E4
-L4:
-	MOVW.P	4(R2), R5
-	SBC.S	$0, R5
-	MOVW.P	R5, 4(R1)
-E4:
-	TEQ	R1, R4
-	BNE	L4
-
-	MOVW	$0, R0
-	MOVW.CC	$1, R0
-	MOVW	R0, c+28(FP)
-	RET
-
-
-// func shlVU(z, x []Word, s uint) (c Word)
-TEXT ·shlVU(SB),NOSPLIT,$0
-	MOVW	z_len+4(FP), R5
-	TEQ	$0, R5
-	BEQ	X7
-	
-	MOVW	z+0(FP), R1
-	MOVW	x+12(FP), R2
-	ADD	R5<<2, R2, R2
-	ADD	R5<<2, R1, R5
-	MOVW	s+24(FP), R3
-	TEQ	$0, R3	// shift 0 is special
-	BEQ	Y7
-	ADD	$4, R1	// stop one word early
-	MOVW	$32, R4
-	SUB	R3, R4
-	MOVW	$0, R7
-	
-	MOVW.W	-4(R2), R6
-	MOVW	R6<<R3, R7
-	MOVW	R6>>R4, R6
-	MOVW	R6, c+28(FP)
-	B E7
-
-L7:
-	MOVW.W	-4(R2), R6
-	ORR	R6>>R4, R7
-	MOVW.W	R7, -4(R5)
-	MOVW	R6<<R3, R7
-E7:
-	TEQ	R1, R5
-	BNE	L7
-
-	MOVW	R7, -4(R5)
-	RET
-
-Y7:	// copy loop, because shift 0 == shift 32
-	MOVW.W	-4(R2), R6
-	MOVW.W	R6, -4(R5)
-	TEQ	R1, R5
-	BNE Y7
-
-X7:
-	MOVW	$0, R1
-	MOVW	R1, c+28(FP)
-	RET
-
-
-// func shrVU(z, x []Word, s uint) (c Word)
-TEXT ·shrVU(SB),NOSPLIT,$0
-	MOVW	z_len+4(FP), R5
-	TEQ	$0, R5
-	BEQ	X6
-
-	MOVW	z+0(FP), R1
-	MOVW	x+12(FP), R2
-	ADD	R5<<2, R1, R5
-	MOVW	s+24(FP), R3
-	TEQ	$0, R3	// shift 0 is special
-	BEQ Y6
-	SUB	$4, R5	// stop one word early
-	MOVW	$32, R4
-	SUB	R3, R4
-	MOVW	$0, R7
-
-	// first word
-	MOVW.P	4(R2), R6
-	MOVW	R6>>R3, R7
-	MOVW	R6<<R4, R6
-	MOVW	R6, c+28(FP)
-	B E6
-
-	// word loop
-L6:
-	MOVW.P	4(R2), R6
-	ORR	R6<<R4, R7
-	MOVW.P	R7, 4(R1)
-	MOVW	R6>>R3, R7
-E6:
-	TEQ	R1, R5
-	BNE	L6
-
-	MOVW	R7, 0(R1)
-	RET
-
-Y6:	// copy loop, because shift 0 == shift 32
-	MOVW.P	4(R2), R6
-	MOVW.P	R6, 4(R1)
-	TEQ R1, R5
-	BNE Y6
-
-X6:
-	MOVW	$0, R1
-	MOVW	R1, c+28(FP)
-	RET
-
-
-// func mulAddVWW(z, x []Word, y, r Word) (c Word)
-TEXT ·mulAddVWW(SB),NOSPLIT,$0
-	MOVW	$0, R0
-	MOVW	z+0(FP), R1
-	MOVW	z_len+4(FP), R5
-	MOVW	x+12(FP), R2
-	MOVW	y+24(FP), R3
-	MOVW	r+28(FP), R4
-	ADD	R5<<2, R1, R5
-	B E8
-
-	// word loop
-L8:
-	MOVW.P	4(R2), R6
-	MULLU	R6, R3, (R7, R6)
-	ADD.S	R4, R6
-	ADC	R0, R7
-	MOVW.P	R6, 4(R1)
-	MOVW	R7, R4
-E8:
-	TEQ	R1, R5
-	BNE	L8
-
-	MOVW	R4, c+32(FP)
-	RET
-
-
-// func addMulVVW(z, x []Word, y Word) (c Word)
-TEXT ·addMulVVW(SB),NOSPLIT,$0
-	MOVW	$0, R0
-	MOVW	z+0(FP), R1
-	MOVW	z_len+4(FP), R5
-	MOVW	x+12(FP), R2
-	MOVW	y+24(FP), R3
-	ADD	R5<<2, R1, R5
-	MOVW	$0, R4
-	B E9
-
-	// word loop
-L9:
-	MOVW.P	4(R2), R6
-	MULLU	R6, R3, (R7, R6)
-	ADD.S	R4, R6
-	ADC	R0, R7
-	MOVW	0(R1), R4
-	ADD.S	R4, R6
-	ADC	R0, R7
-	MOVW.P	R6, 4(R1)
-	MOVW	R7, R4
-E9:
-	TEQ	R1, R5
-	BNE	L9
-
-	MOVW	R4, c+28(FP)
-	RET
-
-
-// func divWVW(z* Word, xn Word, x []Word, y Word) (r Word)
-TEXT ·divWVW(SB),NOSPLIT,$0
-	// ARM has no multiword division, so use portable code.
-	B ·divWVW_g(SB)
-
-
-// func divWW(x1, x0, y Word) (q, r Word)
-TEXT ·divWW(SB),NOSPLIT,$0
-	// ARM has no multiword division, so use portable code.
-	B ·divWW_g(SB)
-
-
-// func mulWW(x, y Word) (z1, z0 Word)
-TEXT ·mulWW(SB),NOSPLIT,$0
-	MOVW	x+0(FP), R1
-	MOVW	y+4(FP), R2
-	MULLU	R1, R2, (R4, R3)
-	MOVW	R4, z1+8(FP)
-	MOVW	R3, z0+12(FP)
-	RET
-
-// func bitLen(x Word) (n int)
-TEXT ·bitLen(SB),NOSPLIT,$0
-	MOVW	x+0(FP), R0
-	CLZ 	R0, R0
-	RSB	$32, R0
-	MOVW	R0, n+4(FP)
-	RET
diff --git a/src/pkg/math/big/int.go b/src/pkg/math/big/int.go
deleted file mode 100644
index 269949d..0000000
--- a/src/pkg/math/big/int.go
+++ /dev/null
@@ -1,1011 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// This file implements signed multi-precision integers.
-
-package big
-
-import (
-	"errors"
-	"fmt"
-	"io"
-	"math/rand"
-	"strings"
-)
-
-// An Int represents a signed multi-precision integer.
-// The zero value for an Int represents the value 0.
-type Int struct {
-	neg bool // sign
-	abs nat  // absolute value of the integer
-}
-
-var intOne = &Int{false, natOne}
-
-// Sign returns:
-//
-//	-1 if x <  0
-//	 0 if x == 0
-//	+1 if x >  0
-//
-func (x *Int) Sign() int {
-	if len(x.abs) == 0 {
-		return 0
-	}
-	if x.neg {
-		return -1
-	}
-	return 1
-}
-
-// SetInt64 sets z to x and returns z.
-func (z *Int) SetInt64(x int64) *Int {
-	neg := false
-	if x < 0 {
-		neg = true
-		x = -x
-	}
-	z.abs = z.abs.setUint64(uint64(x))
-	z.neg = neg
-	return z
-}
-
-// SetUint64 sets z to x and returns z.
-func (z *Int) SetUint64(x uint64) *Int {
-	z.abs = z.abs.setUint64(x)
-	z.neg = false
-	return z
-}
-
-// NewInt allocates and returns a new Int set to x.
-func NewInt(x int64) *Int {
-	return new(Int).SetInt64(x)
-}
-
-// Set sets z to x and returns z.
-func (z *Int) Set(x *Int) *Int {
-	if z != x {
-		z.abs = z.abs.set(x.abs)
-		z.neg = x.neg
-	}
-	return z
-}
-
-// Bits provides raw (unchecked but fast) access to x by returning its
-// absolute value as a little-endian Word slice. The result and x share
-// the same underlying array.
-// Bits is intended to support implementation of missing low-level Int
-// functionality outside this package; it should be avoided otherwise.
-func (x *Int) Bits() []Word {
-	return x.abs
-}
-
-// SetBits provides raw (unchecked but fast) access to z by setting its
-// value to abs, interpreted as a little-endian Word slice, and returning
-// z. The result and abs share the same underlying array.
-// SetBits is intended to support implementation of missing low-level Int
-// functionality outside this package; it should be avoided otherwise.
-func (z *Int) SetBits(abs []Word) *Int {
-	z.abs = nat(abs).norm()
-	z.neg = false
-	return z
-}
-
-// Abs sets z to |x| (the absolute value of x) and returns z.
-func (z *Int) Abs(x *Int) *Int {
-	z.Set(x)
-	z.neg = false
-	return z
-}
-
-// Neg sets z to -x and returns z.
-func (z *Int) Neg(x *Int) *Int {
-	z.Set(x)
-	z.neg = len(z.abs) > 0 && !z.neg // 0 has no sign
-	return z
-}
-
-// Add sets z to the sum x+y and returns z.
-func (z *Int) Add(x, y *Int) *Int {
-	neg := x.neg
-	if x.neg == y.neg {
-		// x + y == x + y
-		// (-x) + (-y) == -(x + y)
-		z.abs = z.abs.add(x.abs, y.abs)
-	} else {
-		// x + (-y) == x - y == -(y - x)
-		// (-x) + y == y - x == -(x - y)
-		if x.abs.cmp(y.abs) >= 0 {
-			z.abs = z.abs.sub(x.abs, y.abs)
-		} else {
-			neg = !neg
-			z.abs = z.abs.sub(y.abs, x.abs)
-		}
-	}
-	z.neg = len(z.abs) > 0 && neg // 0 has no sign
-	return z
-}
-
-// Sub sets z to the difference x-y and returns z.
-func (z *Int) Sub(x, y *Int) *Int {
-	neg := x.neg
-	if x.neg != y.neg {
-		// x - (-y) == x + y
-		// (-x) - y == -(x + y)
-		z.abs = z.abs.add(x.abs, y.abs)
-	} else {
-		// x - y == x - y == -(y - x)
-		// (-x) - (-y) == y - x == -(x - y)
-		if x.abs.cmp(y.abs) >= 0 {
-			z.abs = z.abs.sub(x.abs, y.abs)
-		} else {
-			neg = !neg
-			z.abs = z.abs.sub(y.abs, x.abs)
-		}
-	}
-	z.neg = len(z.abs) > 0 && neg // 0 has no sign
-	return z
-}
-
-// Mul sets z to the product x*y and returns z.
-func (z *Int) Mul(x, y *Int) *Int {
-	// x * y == x * y
-	// x * (-y) == -(x * y)
-	// (-x) * y == -(x * y)
-	// (-x) * (-y) == x * y
-	z.abs = z.abs.mul(x.abs, y.abs)
-	z.neg = len(z.abs) > 0 && x.neg != y.neg // 0 has no sign
-	return z
-}
-
-// MulRange sets z to the product of all integers
-// in the range [a, b] inclusively and returns z.
-// If a > b (empty range), the result is 1.
-func (z *Int) MulRange(a, b int64) *Int {
-	switch {
-	case a > b:
-		return z.SetInt64(1) // empty range
-	case a <= 0 && b >= 0:
-		return z.SetInt64(0) // range includes 0
-	}
-	// a <= b && (b < 0 || a > 0)
-
-	neg := false
-	if a < 0 {
-		neg = (b-a)&1 == 0
-		a, b = -b, -a
-	}
-
-	z.abs = z.abs.mulRange(uint64(a), uint64(b))
-	z.neg = neg
-	return z
-}
-
-// Binomial sets z to the binomial coefficient of (n, k) and returns z.
-func (z *Int) Binomial(n, k int64) *Int {
-	var a, b Int
-	a.MulRange(n-k+1, n)
-	b.MulRange(1, k)
-	return z.Quo(&a, &b)
-}
-
-// Quo sets z to the quotient x/y for y != 0 and returns z.
-// If y == 0, a division-by-zero run-time panic occurs.
-// Quo implements truncated division (like Go); see QuoRem for more details.
-func (z *Int) Quo(x, y *Int) *Int {
-	z.abs, _ = z.abs.div(nil, x.abs, y.abs)
-	z.neg = len(z.abs) > 0 && x.neg != y.neg // 0 has no sign
-	return z
-}
-
-// Rem sets z to the remainder x%y for y != 0 and returns z.
-// If y == 0, a division-by-zero run-time panic occurs.
-// Rem implements truncated modulus (like Go); see QuoRem for more details.
-func (z *Int) Rem(x, y *Int) *Int {
-	_, z.abs = nat(nil).div(z.abs, x.abs, y.abs)
-	z.neg = len(z.abs) > 0 && x.neg // 0 has no sign
-	return z
-}
-
-// QuoRem sets z to the quotient x/y and r to the remainder x%y
-// and returns the pair (z, r) for y != 0.
-// If y == 0, a division-by-zero run-time panic occurs.
-//
-// QuoRem implements T-division and modulus (like Go):
-//
-//	q = x/y      with the result truncated to zero
-//	r = x - y*q
-//
-// (See Daan Leijen, ``Division and Modulus for Computer Scientists''.)
-// See DivMod for Euclidean division and modulus (unlike Go).
-//
-func (z *Int) QuoRem(x, y, r *Int) (*Int, *Int) {
-	z.abs, r.abs = z.abs.div(r.abs, x.abs, y.abs)
-	z.neg, r.neg = len(z.abs) > 0 && x.neg != y.neg, len(r.abs) > 0 && x.neg // 0 has no sign
-	return z, r
-}
-
-// Div sets z to the quotient x/y for y != 0 and returns z.
-// If y == 0, a division-by-zero run-time panic occurs.
-// Div implements Euclidean division (unlike Go); see DivMod for more details.
-func (z *Int) Div(x, y *Int) *Int {
-	y_neg := y.neg // z may be an alias for y
-	var r Int
-	z.QuoRem(x, y, &r)
-	if r.neg {
-		if y_neg {
-			z.Add(z, intOne)
-		} else {
-			z.Sub(z, intOne)
-		}
-	}
-	return z
-}
-
-// Mod sets z to the modulus x%y for y != 0 and returns z.
-// If y == 0, a division-by-zero run-time panic occurs.
-// Mod implements Euclidean modulus (unlike Go); see DivMod for more details.
-func (z *Int) Mod(x, y *Int) *Int {
-	y0 := y // save y
-	if z == y || alias(z.abs, y.abs) {
-		y0 = new(Int).Set(y)
-	}
-	var q Int
-	q.QuoRem(x, y, z)
-	if z.neg {
-		if y0.neg {
-			z.Sub(z, y0)
-		} else {
-			z.Add(z, y0)
-		}
-	}
-	return z
-}
-
-// DivMod sets z to the quotient x div y and m to the modulus x mod y
-// and returns the pair (z, m) for y != 0.
-// If y == 0, a division-by-zero run-time panic occurs.
-//
-// DivMod implements Euclidean division and modulus (unlike Go):
-//
-//	q = x div y  such that
-//	m = x - y*q  with 0 <= m < |q|
-//
-// (See Raymond T. Boute, ``The Euclidean definition of the functions
-// div and mod''. ACM Transactions on Programming Languages and
-// Systems (TOPLAS), 14(2):127-144, New York, NY, USA, 4/1992.
-// ACM press.)
-// See QuoRem for T-division and modulus (like Go).
-//
-func (z *Int) DivMod(x, y, m *Int) (*Int, *Int) {
-	y0 := y // save y
-	if z == y || alias(z.abs, y.abs) {
-		y0 = new(Int).Set(y)
-	}
-	z.QuoRem(x, y, m)
-	if m.neg {
-		if y0.neg {
-			z.Add(z, intOne)
-			m.Sub(m, y0)
-		} else {
-			z.Sub(z, intOne)
-			m.Add(m, y0)
-		}
-	}
-	return z, m
-}
-
-// Cmp compares x and y and returns:
-//
-//   -1 if x <  y
-//    0 if x == y
-//   +1 if x >  y
-//
-func (x *Int) Cmp(y *Int) (r int) {
-	// x cmp y == x cmp y
-	// x cmp (-y) == x
-	// (-x) cmp y == y
-	// (-x) cmp (-y) == -(x cmp y)
-	switch {
-	case x.neg == y.neg:
-		r = x.abs.cmp(y.abs)
-		if x.neg {
-			r = -r
-		}
-	case x.neg:
-		r = -1
-	default:
-		r = 1
-	}
-	return
-}
-
-func (x *Int) String() string {
-	switch {
-	case x == nil:
-		return "<nil>"
-	case x.neg:
-		return "-" + x.abs.decimalString()
-	}
-	return x.abs.decimalString()
-}
-
-func charset(ch rune) string {
-	switch ch {
-	case 'b':
-		return lowercaseDigits[0:2]
-	case 'o':
-		return lowercaseDigits[0:8]
-	case 'd', 's', 'v':
-		return lowercaseDigits[0:10]
-	case 'x':
-		return lowercaseDigits[0:16]
-	case 'X':
-		return uppercaseDigits[0:16]
-	}
-	return "" // unknown format
-}
-
-// write count copies of text to s
-func writeMultiple(s fmt.State, text string, count int) {
-	if len(text) > 0 {
-		b := []byte(text)
-		for ; count > 0; count-- {
-			s.Write(b)
-		}
-	}
-}
-
-// Format is a support routine for fmt.Formatter. It accepts
-// the formats 'b' (binary), 'o' (octal), 'd' (decimal), 'x'
-// (lowercase hexadecimal), and 'X' (uppercase hexadecimal).
-// Also supported are the full suite of package fmt's format
-// verbs for integral types, including '+', '-', and ' '
-// for sign control, '#' for leading zero in octal and for
-// hexadecimal, a leading "0x" or "0X" for "%#x" and "%#X"
-// respectively, specification of minimum digits precision,
-// output field width, space or zero padding, and left or
-// right justification.
-//
-func (x *Int) Format(s fmt.State, ch rune) {
-	cs := charset(ch)
-
-	// special cases
-	switch {
-	case cs == "":
-		// unknown format
-		fmt.Fprintf(s, "%%!%c(big.Int=%s)", ch, x.String())
-		return
-	case x == nil:
-		fmt.Fprint(s, "<nil>")
-		return
-	}
-
-	// determine sign character
-	sign := ""
-	switch {
-	case x.neg:
-		sign = "-"
-	case s.Flag('+'): // supersedes ' ' when both specified
-		sign = "+"
-	case s.Flag(' '):
-		sign = " "
-	}
-
-	// determine prefix characters for indicating output base
-	prefix := ""
-	if s.Flag('#') {
-		switch ch {
-		case 'o': // octal
-			prefix = "0"
-		case 'x': // hexadecimal
-			prefix = "0x"
-		case 'X':
-			prefix = "0X"
-		}
-	}
-
-	// determine digits with base set by len(cs) and digit characters from cs
-	digits := x.abs.string(cs)
-
-	// number of characters for the three classes of number padding
-	var left int   // space characters to left of digits for right justification ("%8d")
-	var zeroes int // zero characters (actually cs[0]) as left-most digits ("%.8d")
-	var right int  // space characters to right of digits for left justification ("%-8d")
-
-	// determine number padding from precision: the least number of digits to output
-	precision, precisionSet := s.Precision()
-	if precisionSet {
-		switch {
-		case len(digits) < precision:
-			zeroes = precision - len(digits) // count of zero padding
-		case digits == "0" && precision == 0:
-			return // print nothing if zero value (x == 0) and zero precision ("." or ".0")
-		}
-	}
-
-	// determine field pad from width: the least number of characters to output
-	length := len(sign) + len(prefix) + zeroes + len(digits)
-	if width, widthSet := s.Width(); widthSet && length < width { // pad as specified
-		switch d := width - length; {
-		case s.Flag('-'):
-			// pad on the right with spaces; supersedes '0' when both specified
-			right = d
-		case s.Flag('0') && !precisionSet:
-			// pad with zeroes unless precision also specified
-			zeroes = d
-		default:
-			// pad on the left with spaces
-			left = d
-		}
-	}
-
-	// print number as [left pad][sign][prefix][zero pad][digits][right pad]
-	writeMultiple(s, " ", left)
-	writeMultiple(s, sign, 1)
-	writeMultiple(s, prefix, 1)
-	writeMultiple(s, "0", zeroes)
-	writeMultiple(s, digits, 1)
-	writeMultiple(s, " ", right)
-}
-
-// scan sets z to the integer value corresponding to the longest possible prefix
-// read from r representing a signed integer number in a given conversion base.
-// It returns z, the actual conversion base used, and an error, if any. In the
-// error case, the value of z is undefined but the returned value is nil. The
-// syntax follows the syntax of integer literals in Go.
-//
-// The base argument must be 0 or a value from 2 through MaxBase. If the base
-// is 0, the string prefix determines the actual conversion base. A prefix of
-// ``0x'' or ``0X'' selects base 16; the ``0'' prefix selects base 8, and a
-// ``0b'' or ``0B'' prefix selects base 2. Otherwise the selected base is 10.
-//
-func (z *Int) scan(r io.RuneScanner, base int) (*Int, int, error) {
-	// determine sign
-	ch, _, err := r.ReadRune()
-	if err != nil {
-		return nil, 0, err
-	}
-	neg := false
-	switch ch {
-	case '-':
-		neg = true
-	case '+': // nothing to do
-	default:
-		r.UnreadRune()
-	}
-
-	// determine mantissa
-	z.abs, base, err = z.abs.scan(r, base)
-	if err != nil {
-		return nil, base, err
-	}
-	z.neg = len(z.abs) > 0 && neg // 0 has no sign
-
-	return z, base, nil
-}
-
-// Scan is a support routine for fmt.Scanner; it sets z to the value of
-// the scanned number. It accepts the formats 'b' (binary), 'o' (octal),
-// 'd' (decimal), 'x' (lowercase hexadecimal), and 'X' (uppercase hexadecimal).
-func (z *Int) Scan(s fmt.ScanState, ch rune) error {
-	s.SkipSpace() // skip leading space characters
-	base := 0
-	switch ch {
-	case 'b':
-		base = 2
-	case 'o':
-		base = 8
-	case 'd':
-		base = 10
-	case 'x', 'X':
-		base = 16
-	case 's', 'v':
-		// let scan determine the base
-	default:
-		return errors.New("Int.Scan: invalid verb")
-	}
-	_, _, err := z.scan(s, base)
-	return err
-}
-
-// Int64 returns the int64 representation of x.
-// If x cannot be represented in an int64, the result is undefined.
-func (x *Int) Int64() int64 {
-	v := int64(x.Uint64())
-	if x.neg {
-		v = -v
-	}
-	return v
-}
-
-// Uint64 returns the uint64 representation of x.
-// If x cannot be represented in a uint64, the result is undefined.
-func (x *Int) Uint64() uint64 {
-	if len(x.abs) == 0 {
-		return 0
-	}
-	v := uint64(x.abs[0])
-	if _W == 32 && len(x.abs) > 1 {
-		v |= uint64(x.abs[1]) << 32
-	}
-	return v
-}
-
-// SetString sets z to the value of s, interpreted in the given base,
-// and returns z and a boolean indicating success. If SetString fails,
-// the value of z is undefined but the returned value is nil.
-//
-// The base argument must be 0 or a value from 2 through MaxBase. If the base
-// is 0, the string prefix determines the actual conversion base. A prefix of
-// ``0x'' or ``0X'' selects base 16; the ``0'' prefix selects base 8, and a
-// ``0b'' or ``0B'' prefix selects base 2. Otherwise the selected base is 10.
-//
-func (z *Int) SetString(s string, base int) (*Int, bool) {
-	r := strings.NewReader(s)
-	_, _, err := z.scan(r, base)
-	if err != nil {
-		return nil, false
-	}
-	_, _, err = r.ReadRune()
-	if err != io.EOF {
-		return nil, false
-	}
-	return z, true // err == io.EOF => scan consumed all of s
-}
-
-// SetBytes interprets buf as the bytes of a big-endian unsigned
-// integer, sets z to that value, and returns z.
-func (z *Int) SetBytes(buf []byte) *Int {
-	z.abs = z.abs.setBytes(buf)
-	z.neg = false
-	return z
-}
-
-// Bytes returns the absolute value of x as a big-endian byte slice.
-func (x *Int) Bytes() []byte {
-	buf := make([]byte, len(x.abs)*_S)
-	return buf[x.abs.bytes(buf):]
-}
-
-// BitLen returns the length of the absolute value of x in bits.
-// The bit length of 0 is 0.
-func (x *Int) BitLen() int {
-	return x.abs.bitLen()
-}
-
-// Exp sets z = x**y mod |m| (i.e. the sign of m is ignored), and returns z.
-// If y <= 0, the result is 1 mod |m|; if m == nil or m == 0, z = x**y.
-// See Knuth, volume 2, section 4.6.3.
-func (z *Int) Exp(x, y, m *Int) *Int {
-	var yWords nat
-	if !y.neg {
-		yWords = y.abs
-	}
-	// y >= 0
-
-	var mWords nat
-	if m != nil {
-		mWords = m.abs // m.abs may be nil for m == 0
-	}
-
-	z.abs = z.abs.expNN(x.abs, yWords, mWords)
-	z.neg = len(z.abs) > 0 && x.neg && len(yWords) > 0 && yWords[0]&1 == 1 // 0 has no sign
-	return z
-}
-
-// GCD sets z to the greatest common divisor of a and b, which both must
-// be > 0, and returns z.
-// If x and y are not nil, GCD sets x and y such that z = a*x + b*y.
-// If either a or b is <= 0, GCD sets z = x = y = 0.
-func (z *Int) GCD(x, y, a, b *Int) *Int {
-	if a.Sign() <= 0 || b.Sign() <= 0 {
-		z.SetInt64(0)
-		if x != nil {
-			x.SetInt64(0)
-		}
-		if y != nil {
-			y.SetInt64(0)
-		}
-		return z
-	}
-	if x == nil && y == nil {
-		return z.binaryGCD(a, b)
-	}
-
-	A := new(Int).Set(a)
-	B := new(Int).Set(b)
-
-	X := new(Int)
-	Y := new(Int).SetInt64(1)
-
-	lastX := new(Int).SetInt64(1)
-	lastY := new(Int)
-
-	q := new(Int)
-	temp := new(Int)
-
-	for len(B.abs) > 0 {
-		r := new(Int)
-		q, r = q.QuoRem(A, B, r)
-
-		A, B = B, r
-
-		temp.Set(X)
-		X.Mul(X, q)
-		X.neg = !X.neg
-		X.Add(X, lastX)
-		lastX.Set(temp)
-
-		temp.Set(Y)
-		Y.Mul(Y, q)
-		Y.neg = !Y.neg
-		Y.Add(Y, lastY)
-		lastY.Set(temp)
-	}
-
-	if x != nil {
-		*x = *lastX
-	}
-
-	if y != nil {
-		*y = *lastY
-	}
-
-	*z = *A
-	return z
-}
-
-// binaryGCD sets z to the greatest common divisor of a and b, which both must
-// be > 0, and returns z.
-// See Knuth, The Art of Computer Programming, Vol. 2, Section 4.5.2, Algorithm B.
-func (z *Int) binaryGCD(a, b *Int) *Int {
-	u := z
-	v := new(Int)
-
-	// use one Euclidean iteration to ensure that u and v are approx. the same size
-	switch {
-	case len(a.abs) > len(b.abs):
-		u.Set(b)
-		v.Rem(a, b)
-	case len(a.abs) < len(b.abs):
-		u.Set(a)
-		v.Rem(b, a)
-	default:
-		u.Set(a)
-		v.Set(b)
-	}
-
-	// v might be 0 now
-	if len(v.abs) == 0 {
-		return u
-	}
-	// u > 0 && v > 0
-
-	// determine largest k such that u = u' << k, v = v' << k
-	k := u.abs.trailingZeroBits()
-	if vk := v.abs.trailingZeroBits(); vk < k {
-		k = vk
-	}
-	u.Rsh(u, k)
-	v.Rsh(v, k)
-
-	// determine t (we know that u > 0)
-	t := new(Int)
-	if u.abs[0]&1 != 0 {
-		// u is odd
-		t.Neg(v)
-	} else {
-		t.Set(u)
-	}
-
-	for len(t.abs) > 0 {
-		// reduce t
-		t.Rsh(t, t.abs.trailingZeroBits())
-		if t.neg {
-			v, t = t, v
-			v.neg = len(v.abs) > 0 && !v.neg // 0 has no sign
-		} else {
-			u, t = t, u
-		}
-		t.Sub(u, v)
-	}
-
-	return z.Lsh(u, k)
-}
-
-// ProbablyPrime performs n Miller-Rabin tests to check whether x is prime.
-// If it returns true, x is prime with probability 1 - 1/4^n.
-// If it returns false, x is not prime.
-func (x *Int) ProbablyPrime(n int) bool {
-	return !x.neg && x.abs.probablyPrime(n)
-}
-
-// Rand sets z to a pseudo-random number in [0, n) and returns z.
-func (z *Int) Rand(rnd *rand.Rand, n *Int) *Int {
-	z.neg = false
-	if n.neg == true || len(n.abs) == 0 {
-		z.abs = nil
-		return z
-	}
-	z.abs = z.abs.random(rnd, n.abs, n.abs.bitLen())
-	return z
-}
-
-// ModInverse sets z to the multiplicative inverse of g in the group ℤ/pℤ (where
-// p is a prime) and returns z.
-func (z *Int) ModInverse(g, p *Int) *Int {
-	var d Int
-	d.GCD(z, nil, g, p)
-	// x and y are such that g*x + p*y = d. Since p is prime, d = 1. Taking
-	// that modulo p results in g*x = 1, therefore x is the inverse element.
-	if z.neg {
-		z.Add(z, p)
-	}
-	return z
-}
-
-// Lsh sets z = x << n and returns z.
-func (z *Int) Lsh(x *Int, n uint) *Int {
-	z.abs = z.abs.shl(x.abs, n)
-	z.neg = x.neg
-	return z
-}
-
-// Rsh sets z = x >> n and returns z.
-func (z *Int) Rsh(x *Int, n uint) *Int {
-	if x.neg {
-		// (-x) >> s == ^(x-1) >> s == ^((x-1) >> s) == -(((x-1) >> s) + 1)
-		t := z.abs.sub(x.abs, natOne) // no underflow because |x| > 0
-		t = t.shr(t, n)
-		z.abs = t.add(t, natOne)
-		z.neg = true // z cannot be zero if x is negative
-		return z
-	}
-
-	z.abs = z.abs.shr(x.abs, n)
-	z.neg = false
-	return z
-}
-
-// Bit returns the value of the i'th bit of x. That is, it
-// returns (x>>i)&1. The bit index i must be >= 0.
-func (x *Int) Bit(i int) uint {
-	if i == 0 {
-		// optimization for common case: odd/even test of x
-		if len(x.abs) > 0 {
-			return uint(x.abs[0] & 1) // bit 0 is same for -x
-		}
-		return 0
-	}
-	if i < 0 {
-		panic("negative bit index")
-	}
-	if x.neg {
-		t := nat(nil).sub(x.abs, natOne)
-		return t.bit(uint(i)) ^ 1
-	}
-
-	return x.abs.bit(uint(i))
-}
-
-// SetBit sets z to x, with x's i'th bit set to b (0 or 1).
-// That is, if b is 1 SetBit sets z = x | (1 << i);
-// if b is 0 SetBit sets z = x &^ (1 << i). If b is not 0 or 1,
-// SetBit will panic.
-func (z *Int) SetBit(x *Int, i int, b uint) *Int {
-	if i < 0 {
-		panic("negative bit index")
-	}
-	if x.neg {
-		t := z.abs.sub(x.abs, natOne)
-		t = t.setBit(t, uint(i), b^1)
-		z.abs = t.add(t, natOne)
-		z.neg = len(z.abs) > 0
-		return z
-	}
-	z.abs = z.abs.setBit(x.abs, uint(i), b)
-	z.neg = false
-	return z
-}
-
-// And sets z = x & y and returns z.
-func (z *Int) And(x, y *Int) *Int {
-	if x.neg == y.neg {
-		if x.neg {
-			// (-x) & (-y) == ^(x-1) & ^(y-1) == ^((x-1) | (y-1)) == -(((x-1) | (y-1)) + 1)
-			x1 := nat(nil).sub(x.abs, natOne)
-			y1 := nat(nil).sub(y.abs, natOne)
-			z.abs = z.abs.add(z.abs.or(x1, y1), natOne)
-			z.neg = true // z cannot be zero if x and y are negative
-			return z
-		}
-
-		// x & y == x & y
-		z.abs = z.abs.and(x.abs, y.abs)
-		z.neg = false
-		return z
-	}
-
-	// x.neg != y.neg
-	if x.neg {
-		x, y = y, x // & is symmetric
-	}
-
-	// x & (-y) == x & ^(y-1) == x &^ (y-1)
-	y1 := nat(nil).sub(y.abs, natOne)
-	z.abs = z.abs.andNot(x.abs, y1)
-	z.neg = false
-	return z
-}
-
-// AndNot sets z = x &^ y and returns z.
-func (z *Int) AndNot(x, y *Int) *Int {
-	if x.neg == y.neg {
-		if x.neg {
-			// (-x) &^ (-y) == ^(x-1) &^ ^(y-1) == ^(x-1) & (y-1) == (y-1) &^ (x-1)
-			x1 := nat(nil).sub(x.abs, natOne)
-			y1 := nat(nil).sub(y.abs, natOne)
-			z.abs = z.abs.andNot(y1, x1)
-			z.neg = false
-			return z
-		}
-
-		// x &^ y == x &^ y
-		z.abs = z.abs.andNot(x.abs, y.abs)
-		z.neg = false
-		return z
-	}
-
-	if x.neg {
-		// (-x) &^ y == ^(x-1) &^ y == ^(x-1) & ^y == ^((x-1) | y) == -(((x-1) | y) + 1)
-		x1 := nat(nil).sub(x.abs, natOne)
-		z.abs = z.abs.add(z.abs.or(x1, y.abs), natOne)
-		z.neg = true // z cannot be zero if x is negative and y is positive
-		return z
-	}
-
-	// x &^ (-y) == x &^ ^(y-1) == x & (y-1)
-	y1 := nat(nil).add(y.abs, natOne)
-	z.abs = z.abs.and(x.abs, y1)
-	z.neg = false
-	return z
-}
-
-// Or sets z = x | y and returns z.
-func (z *Int) Or(x, y *Int) *Int {
-	if x.neg == y.neg {
-		if x.neg {
-			// (-x) | (-y) == ^(x-1) | ^(y-1) == ^((x-1) & (y-1)) == -(((x-1) & (y-1)) + 1)
-			x1 := nat(nil).sub(x.abs, natOne)
-			y1 := nat(nil).sub(y.abs, natOne)
-			z.abs = z.abs.add(z.abs.and(x1, y1), natOne)
-			z.neg = true // z cannot be zero if x and y are negative
-			return z
-		}
-
-		// x | y == x | y
-		z.abs = z.abs.or(x.abs, y.abs)
-		z.neg = false
-		return z
-	}
-
-	// x.neg != y.neg
-	if x.neg {
-		x, y = y, x // | is symmetric
-	}
-
-	// x | (-y) == x | ^(y-1) == ^((y-1) &^ x) == -(^((y-1) &^ x) + 1)
-	y1 := nat(nil).sub(y.abs, natOne)
-	z.abs = z.abs.add(z.abs.andNot(y1, x.abs), natOne)
-	z.neg = true // z cannot be zero if one of x or y is negative
-	return z
-}
-
-// Xor sets z = x ^ y and returns z.
-func (z *Int) Xor(x, y *Int) *Int {
-	if x.neg == y.neg {
-		if x.neg {
-			// (-x) ^ (-y) == ^(x-1) ^ ^(y-1) == (x-1) ^ (y-1)
-			x1 := nat(nil).sub(x.abs, natOne)
-			y1 := nat(nil).sub(y.abs, natOne)
-			z.abs = z.abs.xor(x1, y1)
-			z.neg = false
-			return z
-		}
-
-		// x ^ y == x ^ y
-		z.abs = z.abs.xor(x.abs, y.abs)
-		z.neg = false
-		return z
-	}
-
-	// x.neg != y.neg
-	if x.neg {
-		x, y = y, x // ^ is symmetric
-	}
-
-	// x ^ (-y) == x ^ ^(y-1) == ^(x ^ (y-1)) == -((x ^ (y-1)) + 1)
-	y1 := nat(nil).sub(y.abs, natOne)
-	z.abs = z.abs.add(z.abs.xor(x.abs, y1), natOne)
-	z.neg = true // z cannot be zero if only one of x or y is negative
-	return z
-}
-
-// Not sets z = ^x and returns z.
-func (z *Int) Not(x *Int) *Int {
-	if x.neg {
-		// ^(-x) == ^(^(x-1)) == x-1
-		z.abs = z.abs.sub(x.abs, natOne)
-		z.neg = false
-		return z
-	}
-
-	// ^x == -x-1 == -(x+1)
-	z.abs = z.abs.add(x.abs, natOne)
-	z.neg = true // z cannot be zero if x is positive
-	return z
-}
-
-// Gob codec version. Permits backward-compatible changes to the encoding.
-const intGobVersion byte = 1
-
-// GobEncode implements the gob.GobEncoder interface.
-func (x *Int) GobEncode() ([]byte, error) {
-	if x == nil {
-		return nil, nil
-	}
-	buf := make([]byte, 1+len(x.abs)*_S) // extra byte for version and sign bit
-	i := x.abs.bytes(buf) - 1            // i >= 0
-	b := intGobVersion << 1              // make space for sign bit
-	if x.neg {
-		b |= 1
-	}
-	buf[i] = b
-	return buf[i:], nil
-}
-
-// GobDecode implements the gob.GobDecoder interface.
-func (z *Int) GobDecode(buf []byte) error {
-	if len(buf) == 0 {
-		// Other side sent a nil or default value.
-		*z = Int{}
-		return nil
-	}
-	b := buf[0]
-	if b>>1 != intGobVersion {
-		return errors.New(fmt.Sprintf("Int.GobDecode: encoding version %d not supported", b>>1))
-	}
-	z.neg = b&1 != 0
-	z.abs = z.abs.setBytes(buf[1:])
-	return nil
-}
-
-// MarshalJSON implements the json.Marshaler interface.
-func (z *Int) MarshalJSON() ([]byte, error) {
-	// TODO(gri): get rid of the []byte/string conversions
-	return []byte(z.String()), nil
-}
-
-// UnmarshalJSON implements the json.Unmarshaler interface.
-func (z *Int) UnmarshalJSON(text []byte) error {
-	// TODO(gri): get rid of the []byte/string conversions
-	if _, ok := z.SetString(string(text), 0); !ok {
-		return fmt.Errorf("math/big: cannot unmarshal %q into a *big.Int", text)
-	}
-	return nil
-}
-
-// MarshalText implements the encoding.TextMarshaler interface
-func (z *Int) MarshalText() (text []byte, err error) {
-	return []byte(z.String()), nil
-}
-
-// UnmarshalText implements the encoding.TextUnmarshaler interface
-func (z *Int) UnmarshalText(text []byte) error {
-	if _, ok := z.SetString(string(text), 0); !ok {
-		return fmt.Errorf("math/big: cannot unmarshal %q into a *big.Int", text)
-	}
-	return nil
-}
diff --git a/src/pkg/math/big/int_test.go b/src/pkg/math/big/int_test.go
deleted file mode 100644
index 299dc72..0000000
--- a/src/pkg/math/big/int_test.go
+++ /dev/null
@@ -1,1601 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package big
-
-import (
-	"bytes"
-	"encoding/gob"
-	"encoding/hex"
-	"encoding/json"
-	"encoding/xml"
-	"fmt"
-	"math/rand"
-	"testing"
-	"testing/quick"
-)
-
-func isNormalized(x *Int) bool {
-	if len(x.abs) == 0 {
-		return !x.neg
-	}
-	// len(x.abs) > 0
-	return x.abs[len(x.abs)-1] != 0
-}
-
-type funZZ func(z, x, y *Int) *Int
-type argZZ struct {
-	z, x, y *Int
-}
-
-var sumZZ = []argZZ{
-	{NewInt(0), NewInt(0), NewInt(0)},
-	{NewInt(1), NewInt(1), NewInt(0)},
-	{NewInt(1111111110), NewInt(123456789), NewInt(987654321)},
-	{NewInt(-1), NewInt(-1), NewInt(0)},
-	{NewInt(864197532), NewInt(-123456789), NewInt(987654321)},
-	{NewInt(-1111111110), NewInt(-123456789), NewInt(-987654321)},
-}
-
-var prodZZ = []argZZ{
-	{NewInt(0), NewInt(0), NewInt(0)},
-	{NewInt(0), NewInt(1), NewInt(0)},
-	{NewInt(1), NewInt(1), NewInt(1)},
-	{NewInt(-991 * 991), NewInt(991), NewInt(-991)},
-	// TODO(gri) add larger products
-}
-
-func TestSignZ(t *testing.T) {
-	var zero Int
-	for _, a := range sumZZ {
-		s := a.z.Sign()
-		e := a.z.Cmp(&zero)
-		if s != e {
-			t.Errorf("got %d; want %d for z = %v", s, e, a.z)
-		}
-	}
-}
-
-func TestSetZ(t *testing.T) {
-	for _, a := range sumZZ {
-		var z Int
-		z.Set(a.z)
-		if !isNormalized(&z) {
-			t.Errorf("%v is not normalized", z)
-		}
-		if (&z).Cmp(a.z) != 0 {
-			t.Errorf("got z = %v; want %v", z, a.z)
-		}
-	}
-}
-
-func TestAbsZ(t *testing.T) {
-	var zero Int
-	for _, a := range sumZZ {
-		var z Int
-		z.Abs(a.z)
-		var e Int
-		e.Set(a.z)
-		if e.Cmp(&zero) < 0 {
-			e.Sub(&zero, &e)
-		}
-		if z.Cmp(&e) != 0 {
-			t.Errorf("got z = %v; want %v", z, e)
-		}
-	}
-}
-
-func testFunZZ(t *testing.T, msg string, f funZZ, a argZZ) {
-	var z Int
-	f(&z, a.x, a.y)
-	if !isNormalized(&z) {
-		t.Errorf("%s%v is not normalized", msg, z)
-	}
-	if (&z).Cmp(a.z) != 0 {
-		t.Errorf("%s%+v\n\tgot z = %v; want %v", msg, a, &z, a.z)
-	}
-}
-
-func TestSumZZ(t *testing.T) {
-	AddZZ := func(z, x, y *Int) *Int { return z.Add(x, y) }
-	SubZZ := func(z, x, y *Int) *Int { return z.Sub(x, y) }
-	for _, a := range sumZZ {
-		arg := a
-		testFunZZ(t, "AddZZ", AddZZ, arg)
-
-		arg = argZZ{a.z, a.y, a.x}
-		testFunZZ(t, "AddZZ symmetric", AddZZ, arg)
-
-		arg = argZZ{a.x, a.z, a.y}
-		testFunZZ(t, "SubZZ", SubZZ, arg)
-
-		arg = argZZ{a.y, a.z, a.x}
-		testFunZZ(t, "SubZZ symmetric", SubZZ, arg)
-	}
-}
-
-func TestProdZZ(t *testing.T) {
-	MulZZ := func(z, x, y *Int) *Int { return z.Mul(x, y) }
-	for _, a := range prodZZ {
-		arg := a
-		testFunZZ(t, "MulZZ", MulZZ, arg)
-
-		arg = argZZ{a.z, a.y, a.x}
-		testFunZZ(t, "MulZZ symmetric", MulZZ, arg)
-	}
-}
-
-// mulBytes returns x*y via grade school multiplication. Both inputs
-// and the result are assumed to be in big-endian representation (to
-// match the semantics of Int.Bytes and Int.SetBytes).
-func mulBytes(x, y []byte) []byte {
-	z := make([]byte, len(x)+len(y))
-
-	// multiply
-	k0 := len(z) - 1
-	for j := len(y) - 1; j >= 0; j-- {
-		d := int(y[j])
-		if d != 0 {
-			k := k0
-			carry := 0
-			for i := len(x) - 1; i >= 0; i-- {
-				t := int(z[k]) + int(x[i])*d + carry
-				z[k], carry = byte(t), t>>8
-				k--
-			}
-			z[k] = byte(carry)
-		}
-		k0--
-	}
-
-	// normalize (remove leading 0's)
-	i := 0
-	for i < len(z) && z[i] == 0 {
-		i++
-	}
-
-	return z[i:]
-}
-
-func checkMul(a, b []byte) bool {
-	var x, y, z1 Int
-	x.SetBytes(a)
-	y.SetBytes(b)
-	z1.Mul(&x, &y)
-
-	var z2 Int
-	z2.SetBytes(mulBytes(a, b))
-
-	return z1.Cmp(&z2) == 0
-}
-
-func TestMul(t *testing.T) {
-	if err := quick.Check(checkMul, nil); err != nil {
-		t.Error(err)
-	}
-}
-
-var mulRangesZ = []struct {
-	a, b int64
-	prod string
-}{
-	// entirely positive ranges are covered by mulRangesN
-	{-1, 1, "0"},
-	{-2, -1, "2"},
-	{-3, -2, "6"},
-	{-3, -1, "-6"},
-	{1, 3, "6"},
-	{-10, -10, "-10"},
-	{0, -1, "1"},                      // empty range
-	{-1, -100, "1"},                   // empty range
-	{-1, 1, "0"},                      // range includes 0
-	{-1e9, 0, "0"},                    // range includes 0
-	{-1e9, 1e9, "0"},                  // range includes 0
-	{-10, -1, "3628800"},              // 10!
-	{-20, -2, "-2432902008176640000"}, // -20!
-	{-99, -1,
-		"-933262154439441526816992388562667004907159682643816214685929" +
-			"638952175999932299156089414639761565182862536979208272237582" +
-			"511852109168640000000000000000000000", // -99!
-	},
-}
-
-func TestMulRangeZ(t *testing.T) {
-	var tmp Int
-	// test entirely positive ranges
-	for i, r := range mulRangesN {
-		prod := tmp.MulRange(int64(r.a), int64(r.b)).String()
-		if prod != r.prod {
-			t.Errorf("#%da: got %s; want %s", i, prod, r.prod)
-		}
-	}
-	// test other ranges
-	for i, r := range mulRangesZ {
-		prod := tmp.MulRange(r.a, r.b).String()
-		if prod != r.prod {
-			t.Errorf("#%db: got %s; want %s", i, prod, r.prod)
-		}
-	}
-}
-
-var stringTests = []struct {
-	in   string
-	out  string
-	base int
-	val  int64
-	ok   bool
-}{
-	{in: "", ok: false},
-	{in: "a", ok: false},
-	{in: "z", ok: false},
-	{in: "+", ok: false},
-	{in: "-", ok: false},
-	{in: "0b", ok: false},
-	{in: "0x", ok: false},
-	{in: "2", base: 2, ok: false},
-	{in: "0b2", base: 0, ok: false},
-	{in: "08", ok: false},
-	{in: "8", base: 8, ok: false},
-	{in: "0xg", base: 0, ok: false},
-	{in: "g", base: 16, ok: false},
-	{"0", "0", 0, 0, true},
-	{"0", "0", 10, 0, true},
-	{"0", "0", 16, 0, true},
-	{"+0", "0", 0, 0, true},
-	{"-0", "0", 0, 0, true},
-	{"10", "10", 0, 10, true},
-	{"10", "10", 10, 10, true},
-	{"10", "10", 16, 16, true},
-	{"-10", "-10", 16, -16, true},
-	{"+10", "10", 16, 16, true},
-	{"0x10", "16", 0, 16, true},
-	{in: "0x10", base: 16, ok: false},
-	{"-0x10", "-16", 0, -16, true},
-	{"+0x10", "16", 0, 16, true},
-	{"00", "0", 0, 0, true},
-	{"0", "0", 8, 0, true},
-	{"07", "7", 0, 7, true},
-	{"7", "7", 8, 7, true},
-	{"023", "19", 0, 19, true},
-	{"23", "23", 8, 19, true},
-	{"cafebabe", "cafebabe", 16, 0xcafebabe, true},
-	{"0b0", "0", 0, 0, true},
-	{"-111", "-111", 2, -7, true},
-	{"-0b111", "-7", 0, -7, true},
-	{"0b1001010111", "599", 0, 0x257, true},
-	{"1001010111", "1001010111", 2, 0x257, true},
-}
-
-func format(base int) string {
-	switch base {
-	case 2:
-		return "%b"
-	case 8:
-		return "%o"
-	case 16:
-		return "%x"
-	}
-	return "%d"
-}
-
-func TestGetString(t *testing.T) {
-	z := new(Int)
-	for i, test := range stringTests {
-		if !test.ok {
-			continue
-		}
-		z.SetInt64(test.val)
-
-		if test.base == 10 {
-			s := z.String()
-			if s != test.out {
-				t.Errorf("#%da got %s; want %s", i, s, test.out)
-			}
-		}
-
-		s := fmt.Sprintf(format(test.base), z)
-		if s != test.out {
-			t.Errorf("#%db got %s; want %s", i, s, test.out)
-		}
-	}
-}
-
-func TestSetString(t *testing.T) {
-	tmp := new(Int)
-	for i, test := range stringTests {
-		// initialize to a non-zero value so that issues with parsing
-		// 0 are detected
-		tmp.SetInt64(1234567890)
-		n1, ok1 := new(Int).SetString(test.in, test.base)
-		n2, ok2 := tmp.SetString(test.in, test.base)
-		expected := NewInt(test.val)
-		if ok1 != test.ok || ok2 != test.ok {
-			t.Errorf("#%d (input '%s') ok incorrect (should be %t)", i, test.in, test.ok)
-			continue
-		}
-		if !ok1 {
-			if n1 != nil {
-				t.Errorf("#%d (input '%s') n1 != nil", i, test.in)
-			}
-			continue
-		}
-		if !ok2 {
-			if n2 != nil {
-				t.Errorf("#%d (input '%s') n2 != nil", i, test.in)
-			}
-			continue
-		}
-
-		if ok1 && !isNormalized(n1) {
-			t.Errorf("#%d (input '%s'): %v is not normalized", i, test.in, *n1)
-		}
-		if ok2 && !isNormalized(n2) {
-			t.Errorf("#%d (input '%s'): %v is not normalized", i, test.in, *n2)
-		}
-
-		if n1.Cmp(expected) != 0 {
-			t.Errorf("#%d (input '%s') got: %s want: %d", i, test.in, n1, test.val)
-		}
-		if n2.Cmp(expected) != 0 {
-			t.Errorf("#%d (input '%s') got: %s want: %d", i, test.in, n2, test.val)
-		}
-	}
-}
-
-var formatTests = []struct {
-	input  string
-	format string
-	output string
-}{
-	{"<nil>", "%x", "<nil>"},
-	{"<nil>", "%#x", "<nil>"},
-	{"<nil>", "%#y", "%!y(big.Int=<nil>)"},
-
-	{"10", "%b", "1010"},
-	{"10", "%o", "12"},
-	{"10", "%d", "10"},
-	{"10", "%v", "10"},
-	{"10", "%x", "a"},
-	{"10", "%X", "A"},
-	{"-10", "%X", "-A"},
-	{"10", "%y", "%!y(big.Int=10)"},
-	{"-10", "%y", "%!y(big.Int=-10)"},
-
-	{"10", "%#b", "1010"},
-	{"10", "%#o", "012"},
-	{"10", "%#d", "10"},
-	{"10", "%#v", "10"},
-	{"10", "%#x", "0xa"},
-	{"10", "%#X", "0XA"},
-	{"-10", "%#X", "-0XA"},
-	{"10", "%#y", "%!y(big.Int=10)"},
-	{"-10", "%#y", "%!y(big.Int=-10)"},
-
-	{"1234", "%d", "1234"},
-	{"1234", "%3d", "1234"},
-	{"1234", "%4d", "1234"},
-	{"-1234", "%d", "-1234"},
-	{"1234", "% 5d", " 1234"},
-	{"1234", "%+5d", "+1234"},
-	{"1234", "%-5d", "1234 "},
-	{"1234", "%x", "4d2"},
-	{"1234", "%X", "4D2"},
-	{"-1234", "%3x", "-4d2"},
-	{"-1234", "%4x", "-4d2"},
-	{"-1234", "%5x", " -4d2"},
-	{"-1234", "%-5x", "-4d2 "},
-	{"1234", "%03d", "1234"},
-	{"1234", "%04d", "1234"},
-	{"1234", "%05d", "01234"},
-	{"1234", "%06d", "001234"},
-	{"-1234", "%06d", "-01234"},
-	{"1234", "%+06d", "+01234"},
-	{"1234", "% 06d", " 01234"},
-	{"1234", "%-6d", "1234  "},
-	{"1234", "%-06d", "1234  "},
-	{"-1234", "%-06d", "-1234 "},
-
-	{"1234", "%.3d", "1234"},
-	{"1234", "%.4d", "1234"},
-	{"1234", "%.5d", "01234"},
-	{"1234", "%.6d", "001234"},
-	{"-1234", "%.3d", "-1234"},
-	{"-1234", "%.4d", "-1234"},
-	{"-1234", "%.5d", "-01234"},
-	{"-1234", "%.6d", "-001234"},
-
-	{"1234", "%8.3d", "    1234"},
-	{"1234", "%8.4d", "    1234"},
-	{"1234", "%8.5d", "   01234"},
-	{"1234", "%8.6d", "  001234"},
-	{"-1234", "%8.3d", "   -1234"},
-	{"-1234", "%8.4d", "   -1234"},
-	{"-1234", "%8.5d", "  -01234"},
-	{"-1234", "%8.6d", " -001234"},
-
-	{"1234", "%+8.3d", "   +1234"},
-	{"1234", "%+8.4d", "   +1234"},
-	{"1234", "%+8.5d", "  +01234"},
-	{"1234", "%+8.6d", " +001234"},
-	{"-1234", "%+8.3d", "   -1234"},
-	{"-1234", "%+8.4d", "   -1234"},
-	{"-1234", "%+8.5d", "  -01234"},
-	{"-1234", "%+8.6d", " -001234"},
-
-	{"1234", "% 8.3d", "    1234"},
-	{"1234", "% 8.4d", "    1234"},
-	{"1234", "% 8.5d", "   01234"},
-	{"1234", "% 8.6d", "  001234"},
-	{"-1234", "% 8.3d", "   -1234"},
-	{"-1234", "% 8.4d", "   -1234"},
-	{"-1234", "% 8.5d", "  -01234"},
-	{"-1234", "% 8.6d", " -001234"},
-
-	{"1234", "%.3x", "4d2"},
-	{"1234", "%.4x", "04d2"},
-	{"1234", "%.5x", "004d2"},
-	{"1234", "%.6x", "0004d2"},
-	{"-1234", "%.3x", "-4d2"},
-	{"-1234", "%.4x", "-04d2"},
-	{"-1234", "%.5x", "-004d2"},
-	{"-1234", "%.6x", "-0004d2"},
-
-	{"1234", "%8.3x", "     4d2"},
-	{"1234", "%8.4x", "    04d2"},
-	{"1234", "%8.5x", "   004d2"},
-	{"1234", "%8.6x", "  0004d2"},
-	{"-1234", "%8.3x", "    -4d2"},
-	{"-1234", "%8.4x", "   -04d2"},
-	{"-1234", "%8.5x", "  -004d2"},
-	{"-1234", "%8.6x", " -0004d2"},
-
-	{"1234", "%+8.3x", "    +4d2"},
-	{"1234", "%+8.4x", "   +04d2"},
-	{"1234", "%+8.5x", "  +004d2"},
-	{"1234", "%+8.6x", " +0004d2"},
-	{"-1234", "%+8.3x", "    -4d2"},
-	{"-1234", "%+8.4x", "   -04d2"},
-	{"-1234", "%+8.5x", "  -004d2"},
-	{"-1234", "%+8.6x", " -0004d2"},
-
-	{"1234", "% 8.3x", "     4d2"},
-	{"1234", "% 8.4x", "    04d2"},
-	{"1234", "% 8.5x", "   004d2"},
-	{"1234", "% 8.6x", "  0004d2"},
-	{"1234", "% 8.7x", " 00004d2"},
-	{"1234", "% 8.8x", " 000004d2"},
-	{"-1234", "% 8.3x", "    -4d2"},
-	{"-1234", "% 8.4x", "   -04d2"},
-	{"-1234", "% 8.5x", "  -004d2"},
-	{"-1234", "% 8.6x", " -0004d2"},
-	{"-1234", "% 8.7x", "-00004d2"},
-	{"-1234", "% 8.8x", "-000004d2"},
-
-	{"1234", "%-8.3d", "1234    "},
-	{"1234", "%-8.4d", "1234    "},
-	{"1234", "%-8.5d", "01234   "},
-	{"1234", "%-8.6d", "001234  "},
-	{"1234", "%-8.7d", "0001234 "},
-	{"1234", "%-8.8d", "00001234"},
-	{"-1234", "%-8.3d", "-1234   "},
-	{"-1234", "%-8.4d", "-1234   "},
-	{"-1234", "%-8.5d", "-01234  "},
-	{"-1234", "%-8.6d", "-001234 "},
-	{"-1234", "%-8.7d", "-0001234"},
-	{"-1234", "%-8.8d", "-00001234"},
-
-	{"16777215", "%b", "111111111111111111111111"}, // 2**24 - 1
-
-	{"0", "%.d", ""},
-	{"0", "%.0d", ""},
-	{"0", "%3.d", ""},
-}
-
-func TestFormat(t *testing.T) {
-	for i, test := range formatTests {
-		var x *Int
-		if test.input != "<nil>" {
-			var ok bool
-			x, ok = new(Int).SetString(test.input, 0)
-			if !ok {
-				t.Errorf("#%d failed reading input %s", i, test.input)
-			}
-		}
-		output := fmt.Sprintf(test.format, x)
-		if output != test.output {
-			t.Errorf("#%d got %q; want %q, {%q, %q, %q}", i, output, test.output, test.input, test.format, test.output)
-		}
-	}
-}
-
-var scanTests = []struct {
-	input     string
-	format    string
-	output    string
-	remaining int
-}{
-	{"1010", "%b", "10", 0},
-	{"0b1010", "%v", "10", 0},
-	{"12", "%o", "10", 0},
-	{"012", "%v", "10", 0},
-	{"10", "%d", "10", 0},
-	{"10", "%v", "10", 0},
-	{"a", "%x", "10", 0},
-	{"0xa", "%v", "10", 0},
-	{"A", "%X", "10", 0},
-	{"-A", "%X", "-10", 0},
-	{"+0b1011001", "%v", "89", 0},
-	{"0xA", "%v", "10", 0},
-	{"0 ", "%v", "0", 1},
-	{"2+3", "%v", "2", 2},
-	{"0XABC 12", "%v", "2748", 3},
-}
-
-func TestScan(t *testing.T) {
-	var buf bytes.Buffer
-	for i, test := range scanTests {
-		x := new(Int)
-		buf.Reset()
-		buf.WriteString(test.input)
-		if _, err := fmt.Fscanf(&buf, test.format, x); err != nil {
-			t.Errorf("#%d error: %s", i, err)
-		}
-		if x.String() != test.output {
-			t.Errorf("#%d got %s; want %s", i, x.String(), test.output)
-		}
-		if buf.Len() != test.remaining {
-			t.Errorf("#%d got %d bytes remaining; want %d", i, buf.Len(), test.remaining)
-		}
-	}
-}
-
-// Examples from the Go Language Spec, section "Arithmetic operators"
-var divisionSignsTests = []struct {
-	x, y int64
-	q, r int64 // T-division
-	d, m int64 // Euclidian division
-}{
-	{5, 3, 1, 2, 1, 2},
-	{-5, 3, -1, -2, -2, 1},
-	{5, -3, -1, 2, -1, 2},
-	{-5, -3, 1, -2, 2, 1},
-	{1, 2, 0, 1, 0, 1},
-	{8, 4, 2, 0, 2, 0},
-}
-
-func TestDivisionSigns(t *testing.T) {
-	for i, test := range divisionSignsTests {
-		x := NewInt(test.x)
-		y := NewInt(test.y)
-		q := NewInt(test.q)
-		r := NewInt(test.r)
-		d := NewInt(test.d)
-		m := NewInt(test.m)
-
-		q1 := new(Int).Quo(x, y)
-		r1 := new(Int).Rem(x, y)
-		if !isNormalized(q1) {
-			t.Errorf("#%d Quo: %v is not normalized", i, *q1)
-		}
-		if !isNormalized(r1) {
-			t.Errorf("#%d Rem: %v is not normalized", i, *r1)
-		}
-		if q1.Cmp(q) != 0 || r1.Cmp(r) != 0 {
-			t.Errorf("#%d QuoRem: got (%s, %s), want (%s, %s)", i, q1, r1, q, r)
-		}
-
-		q2, r2 := new(Int).QuoRem(x, y, new(Int))
-		if !isNormalized(q2) {
-			t.Errorf("#%d Quo: %v is not normalized", i, *q2)
-		}
-		if !isNormalized(r2) {
-			t.Errorf("#%d Rem: %v is not normalized", i, *r2)
-		}
-		if q2.Cmp(q) != 0 || r2.Cmp(r) != 0 {
-			t.Errorf("#%d QuoRem: got (%s, %s), want (%s, %s)", i, q2, r2, q, r)
-		}
-
-		d1 := new(Int).Div(x, y)
-		m1 := new(Int).Mod(x, y)
-		if !isNormalized(d1) {
-			t.Errorf("#%d Div: %v is not normalized", i, *d1)
-		}
-		if !isNormalized(m1) {
-			t.Errorf("#%d Mod: %v is not normalized", i, *m1)
-		}
-		if d1.Cmp(d) != 0 || m1.Cmp(m) != 0 {
-			t.Errorf("#%d DivMod: got (%s, %s), want (%s, %s)", i, d1, m1, d, m)
-		}
-
-		d2, m2 := new(Int).DivMod(x, y, new(Int))
-		if !isNormalized(d2) {
-			t.Errorf("#%d Div: %v is not normalized", i, *d2)
-		}
-		if !isNormalized(m2) {
-			t.Errorf("#%d Mod: %v is not normalized", i, *m2)
-		}
-		if d2.Cmp(d) != 0 || m2.Cmp(m) != 0 {
-			t.Errorf("#%d DivMod: got (%s, %s), want (%s, %s)", i, d2, m2, d, m)
-		}
-	}
-}
-
-func checkSetBytes(b []byte) bool {
-	hex1 := hex.EncodeToString(new(Int).SetBytes(b).Bytes())
-	hex2 := hex.EncodeToString(b)
-
-	for len(hex1) < len(hex2) {
-		hex1 = "0" + hex1
-	}
-
-	for len(hex1) > len(hex2) {
-		hex2 = "0" + hex2
-	}
-
-	return hex1 == hex2
-}
-
-func TestSetBytes(t *testing.T) {
-	if err := quick.Check(checkSetBytes, nil); err != nil {
-		t.Error(err)
-	}
-}
-
-func checkBytes(b []byte) bool {
-	b2 := new(Int).SetBytes(b).Bytes()
-	return bytes.Equal(b, b2)
-}
-
-func TestBytes(t *testing.T) {
-	if err := quick.Check(checkSetBytes, nil); err != nil {
-		t.Error(err)
-	}
-}
-
-func checkQuo(x, y []byte) bool {
-	u := new(Int).SetBytes(x)
-	v := new(Int).SetBytes(y)
-
-	if len(v.abs) == 0 {
-		return true
-	}
-
-	r := new(Int)
-	q, r := new(Int).QuoRem(u, v, r)
-
-	if r.Cmp(v) >= 0 {
-		return false
-	}
-
-	uprime := new(Int).Set(q)
-	uprime.Mul(uprime, v)
-	uprime.Add(uprime, r)
-
-	return uprime.Cmp(u) == 0
-}
-
-var quoTests = []struct {
-	x, y string
-	q, r string
-}{
-	{
-		"476217953993950760840509444250624797097991362735329973741718102894495832294430498335824897858659711275234906400899559094370964723884706254265559534144986498357",
-		"9353930466774385905609975137998169297361893554149986716853295022578535724979483772383667534691121982974895531435241089241440253066816724367338287092081996",
-		"50911",
-		"1",
-	},
-	{
-		"11510768301994997771168",
-		"1328165573307167369775",
-		"8",
-		"885443715537658812968",
-	},
-}
-
-func TestQuo(t *testing.T) {
-	if err := quick.Check(checkQuo, nil); err != nil {
-		t.Error(err)
-	}
-
-	for i, test := range quoTests {
-		x, _ := new(Int).SetString(test.x, 10)
-		y, _ := new(Int).SetString(test.y, 10)
-		expectedQ, _ := new(Int).SetString(test.q, 10)
-		expectedR, _ := new(Int).SetString(test.r, 10)
-
-		r := new(Int)
-		q, r := new(Int).QuoRem(x, y, r)
-
-		if q.Cmp(expectedQ) != 0 || r.Cmp(expectedR) != 0 {
-			t.Errorf("#%d got (%s, %s) want (%s, %s)", i, q, r, expectedQ, expectedR)
-		}
-	}
-}
-
-func TestQuoStepD6(t *testing.T) {
-	// See Knuth, Volume 2, section 4.3.1, exercise 21. This code exercises
-	// a code path which only triggers 1 in 10^{-19} cases.
-
-	u := &Int{false, nat{0, 0, 1 + 1<<(_W-1), _M ^ (1 << (_W - 1))}}
-	v := &Int{false, nat{5, 2 + 1<<(_W-1), 1 << (_W - 1)}}
-
-	r := new(Int)
-	q, r := new(Int).QuoRem(u, v, r)
-	const expectedQ64 = "18446744073709551613"
-	const expectedR64 = "3138550867693340382088035895064302439801311770021610913807"
-	const expectedQ32 = "4294967293"
-	const expectedR32 = "39614081266355540837921718287"
-	if q.String() != expectedQ64 && q.String() != expectedQ32 ||
-		r.String() != expectedR64 && r.String() != expectedR32 {
-		t.Errorf("got (%s, %s) want (%s, %s) or (%s, %s)", q, r, expectedQ64, expectedR64, expectedQ32, expectedR32)
-	}
-}
-
-var bitLenTests = []struct {
-	in  string
-	out int
-}{
-	{"-1", 1},
-	{"0", 0},
-	{"1", 1},
-	{"2", 2},
-	{"4", 3},
-	{"0xabc", 12},
-	{"0x8000", 16},
-	{"0x80000000", 32},
-	{"0x800000000000", 48},
-	{"0x8000000000000000", 64},
-	{"0x80000000000000000000", 80},
-	{"-0x4000000000000000000000", 87},
-}
-
-func TestBitLen(t *testing.T) {
-	for i, test := range bitLenTests {
-		x, ok := new(Int).SetString(test.in, 0)
-		if !ok {
-			t.Errorf("#%d test input invalid: %s", i, test.in)
-			continue
-		}
-
-		if n := x.BitLen(); n != test.out {
-			t.Errorf("#%d got %d want %d", i, n, test.out)
-		}
-	}
-}
-
-var expTests = []struct {
-	x, y, m string
-	out     string
-}{
-	// y <= 0
-	{"0", "0", "", "1"},
-	{"1", "0", "", "1"},
-	{"-10", "0", "", "1"},
-	{"1234", "-1", "", "1"},
-
-	// m == 1
-	{"0", "0", "1", "0"},
-	{"1", "0", "1", "0"},
-	{"-10", "0", "1", "0"},
-	{"1234", "-1", "1", "0"},
-
-	// misc
-	{"5", "-7", "", "1"},
-	{"-5", "-7", "", "1"},
-	{"5", "0", "", "1"},
-	{"-5", "0", "", "1"},
-	{"5", "1", "", "5"},
-	{"-5", "1", "", "-5"},
-	{"-2", "3", "2", "0"},
-	{"5", "2", "", "25"},
-	{"1", "65537", "2", "1"},
-	{"0x8000000000000000", "2", "", "0x40000000000000000000000000000000"},
-	{"0x8000000000000000", "2", "6719", "4944"},
-	{"0x8000000000000000", "3", "6719", "5447"},
-	{"0x8000000000000000", "1000", "6719", "1603"},
-	{"0x8000000000000000", "1000000", "6719", "3199"},
-	{"0x8000000000000000", "-1000000", "6719", "1"},
-	{
-		"2938462938472983472983659726349017249287491026512746239764525612965293865296239471239874193284792387498274256129746192347",
-		"298472983472983471903246121093472394872319615612417471234712061",
-		"29834729834729834729347290846729561262544958723956495615629569234729836259263598127342374289365912465901365498236492183464",
-		"23537740700184054162508175125554701713153216681790245129157191391322321508055833908509185839069455749219131480588829346291",
-	},
-}
-
-func TestExp(t *testing.T) {
-	for i, test := range expTests {
-		x, ok1 := new(Int).SetString(test.x, 0)
-		y, ok2 := new(Int).SetString(test.y, 0)
-		out, ok3 := new(Int).SetString(test.out, 0)
-
-		var ok4 bool
-		var m *Int
-
-		if len(test.m) == 0 {
-			m, ok4 = nil, true
-		} else {
-			m, ok4 = new(Int).SetString(test.m, 0)
-		}
-
-		if !ok1 || !ok2 || !ok3 || !ok4 {
-			t.Errorf("#%d: error in input", i)
-			continue
-		}
-
-		z1 := new(Int).Exp(x, y, m)
-		if !isNormalized(z1) {
-			t.Errorf("#%d: %v is not normalized", i, *z1)
-		}
-		if z1.Cmp(out) != 0 {
-			t.Errorf("#%d: got %s want %s", i, z1, out)
-		}
-
-		if m == nil {
-			// the result should be the same as for m == 0;
-			// specifically, there should be no div-zero panic
-			m = &Int{abs: nat{}} // m != nil && len(m.abs) == 0
-			z2 := new(Int).Exp(x, y, m)
-			if z2.Cmp(z1) != 0 {
-				t.Errorf("#%d: got %s want %s", i, z1, z2)
-			}
-		}
-	}
-}
-
-func checkGcd(aBytes, bBytes []byte) bool {
-	x := new(Int)
-	y := new(Int)
-	a := new(Int).SetBytes(aBytes)
-	b := new(Int).SetBytes(bBytes)
-
-	d := new(Int).GCD(x, y, a, b)
-	x.Mul(x, a)
-	y.Mul(y, b)
-	x.Add(x, y)
-
-	return x.Cmp(d) == 0
-}
-
-var gcdTests = []struct {
-	d, x, y, a, b string
-}{
-	// a <= 0 || b <= 0
-	{"0", "0", "0", "0", "0"},
-	{"0", "0", "0", "0", "7"},
-	{"0", "0", "0", "11", "0"},
-	{"0", "0", "0", "-77", "35"},
-	{"0", "0", "0", "64515", "-24310"},
-	{"0", "0", "0", "-64515", "-24310"},
-
-	{"1", "-9", "47", "120", "23"},
-	{"7", "1", "-2", "77", "35"},
-	{"935", "-3", "8", "64515", "24310"},
-	{"935000000000000000", "-3", "8", "64515000000000000000", "24310000000000000000"},
-	{"1", "-221", "22059940471369027483332068679400581064239780177629666810348940098015901108344", "98920366548084643601728869055592650835572950932266967461790948584315647051443", "991"},
-
-	// test early exit (after one Euclidean iteration) in binaryGCD
-	{"1", "", "", "1", "98920366548084643601728869055592650835572950932266967461790948584315647051443"},
-}
-
-func testGcd(t *testing.T, d, x, y, a, b *Int) {
-	var X *Int
-	if x != nil {
-		X = new(Int)
-	}
-	var Y *Int
-	if y != nil {
-		Y = new(Int)
-	}
-
-	D := new(Int).GCD(X, Y, a, b)
-	if D.Cmp(d) != 0 {
-		t.Errorf("GCD(%s, %s): got d = %s, want %s", a, b, D, d)
-	}
-	if x != nil && X.Cmp(x) != 0 {
-		t.Errorf("GCD(%s, %s): got x = %s, want %s", a, b, X, x)
-	}
-	if y != nil && Y.Cmp(y) != 0 {
-		t.Errorf("GCD(%s, %s): got y = %s, want %s", a, b, Y, y)
-	}
-
-	// binaryGCD requires a > 0 && b > 0
-	if a.Sign() <= 0 || b.Sign() <= 0 {
-		return
-	}
-
-	D.binaryGCD(a, b)
-	if D.Cmp(d) != 0 {
-		t.Errorf("binaryGcd(%s, %s): got d = %s, want %s", a, b, D, d)
-	}
-}
-
-func TestGcd(t *testing.T) {
-	for _, test := range gcdTests {
-		d, _ := new(Int).SetString(test.d, 0)
-		x, _ := new(Int).SetString(test.x, 0)
-		y, _ := new(Int).SetString(test.y, 0)
-		a, _ := new(Int).SetString(test.a, 0)
-		b, _ := new(Int).SetString(test.b, 0)
-
-		testGcd(t, d, nil, nil, a, b)
-		testGcd(t, d, x, nil, a, b)
-		testGcd(t, d, nil, y, a, b)
-		testGcd(t, d, x, y, a, b)
-	}
-
-	quick.Check(checkGcd, nil)
-}
-
-var primes = []string{
-	"2",
-	"3",
-	"5",
-	"7",
-	"11",
-
-	"13756265695458089029",
-	"13496181268022124907",
-	"10953742525620032441",
-	"17908251027575790097",
-
-	// http://code.google.com/p/go/issues/detail?id=638
-	"18699199384836356663",
-
-	"98920366548084643601728869055592650835572950932266967461790948584315647051443",
-	"94560208308847015747498523884063394671606671904944666360068158221458669711639",
-
-	// http://primes.utm.edu/lists/small/small3.html
-	"449417999055441493994709297093108513015373787049558499205492347871729927573118262811508386655998299074566974373711472560655026288668094291699357843464363003144674940345912431129144354948751003607115263071543163",
-	"230975859993204150666423538988557839555560243929065415434980904258310530753006723857139742334640122533598517597674807096648905501653461687601339782814316124971547968912893214002992086353183070342498989426570593",
-	"5521712099665906221540423207019333379125265462121169655563495403888449493493629943498064604536961775110765377745550377067893607246020694972959780839151452457728855382113555867743022746090187341871655890805971735385789993",
-	"203956878356401977405765866929034577280193993314348263094772646453283062722701277632936616063144088173312372882677123879538709400158306567338328279154499698366071906766440037074217117805690872792848149112022286332144876183376326512083574821647933992961249917319836219304274280243803104015000563790123",
-}
-
-var composites = []string{
-	"21284175091214687912771199898307297748211672914763848041968395774954376176754",
-	"6084766654921918907427900243509372380954290099172559290432744450051395395951",
-	"84594350493221918389213352992032324280367711247940675652888030554255915464401",
-	"82793403787388584738507275144194252681",
-}
-
-func TestProbablyPrime(t *testing.T) {
-	nreps := 20
-	if testing.Short() {
-		nreps = 1
-	}
-	for i, s := range primes {
-		p, _ := new(Int).SetString(s, 10)
-		if !p.ProbablyPrime(nreps) {
-			t.Errorf("#%d prime found to be non-prime (%s)", i, s)
-		}
-	}
-
-	for i, s := range composites {
-		c, _ := new(Int).SetString(s, 10)
-		if c.ProbablyPrime(nreps) {
-			t.Errorf("#%d composite found to be prime (%s)", i, s)
-		}
-		if testing.Short() {
-			break
-		}
-	}
-}
-
-type intShiftTest struct {
-	in    string
-	shift uint
-	out   string
-}
-
-var rshTests = []intShiftTest{
-	{"0", 0, "0"},
-	{"-0", 0, "0"},
-	{"0", 1, "0"},
-	{"0", 2, "0"},
-	{"1", 0, "1"},
-	{"1", 1, "0"},
-	{"1", 2, "0"},
-	{"2", 0, "2"},
-	{"2", 1, "1"},
-	{"-1", 0, "-1"},
-	{"-1", 1, "-1"},
-	{"-1", 10, "-1"},
-	{"-100", 2, "-25"},
-	{"-100", 3, "-13"},
-	{"-100", 100, "-1"},
-	{"4294967296", 0, "4294967296"},
-	{"4294967296", 1, "2147483648"},
-	{"4294967296", 2, "1073741824"},
-	{"18446744073709551616", 0, "18446744073709551616"},
-	{"18446744073709551616", 1, "9223372036854775808"},
-	{"18446744073709551616", 2, "4611686018427387904"},
-	{"18446744073709551616", 64, "1"},
-	{"340282366920938463463374607431768211456", 64, "18446744073709551616"},
-	{"340282366920938463463374607431768211456", 128, "1"},
-}
-
-func TestRsh(t *testing.T) {
-	for i, test := range rshTests {
-		in, _ := new(Int).SetString(test.in, 10)
-		expected, _ := new(Int).SetString(test.out, 10)
-		out := new(Int).Rsh(in, test.shift)
-
-		if !isNormalized(out) {
-			t.Errorf("#%d: %v is not normalized", i, *out)
-		}
-		if out.Cmp(expected) != 0 {
-			t.Errorf("#%d: got %s want %s", i, out, expected)
-		}
-	}
-}
-
-func TestRshSelf(t *testing.T) {
-	for i, test := range rshTests {
-		z, _ := new(Int).SetString(test.in, 10)
-		expected, _ := new(Int).SetString(test.out, 10)
-		z.Rsh(z, test.shift)
-
-		if !isNormalized(z) {
-			t.Errorf("#%d: %v is not normalized", i, *z)
-		}
-		if z.Cmp(expected) != 0 {
-			t.Errorf("#%d: got %s want %s", i, z, expected)
-		}
-	}
-}
-
-var lshTests = []intShiftTest{
-	{"0", 0, "0"},
-	{"0", 1, "0"},
-	{"0", 2, "0"},
-	{"1", 0, "1"},
-	{"1", 1, "2"},
-	{"1", 2, "4"},
-	{"2", 0, "2"},
-	{"2", 1, "4"},
-	{"2", 2, "8"},
-	{"-87", 1, "-174"},
-	{"4294967296", 0, "4294967296"},
-	{"4294967296", 1, "8589934592"},
-	{"4294967296", 2, "17179869184"},
-	{"18446744073709551616", 0, "18446744073709551616"},
-	{"9223372036854775808", 1, "18446744073709551616"},
-	{"4611686018427387904", 2, "18446744073709551616"},
-	{"1", 64, "18446744073709551616"},
-	{"18446744073709551616", 64, "340282366920938463463374607431768211456"},
-	{"1", 128, "340282366920938463463374607431768211456"},
-}
-
-func TestLsh(t *testing.T) {
-	for i, test := range lshTests {
-		in, _ := new(Int).SetString(test.in, 10)
-		expected, _ := new(Int).SetString(test.out, 10)
-		out := new(Int).Lsh(in, test.shift)
-
-		if !isNormalized(out) {
-			t.Errorf("#%d: %v is not normalized", i, *out)
-		}
-		if out.Cmp(expected) != 0 {
-			t.Errorf("#%d: got %s want %s", i, out, expected)
-		}
-	}
-}
-
-func TestLshSelf(t *testing.T) {
-	for i, test := range lshTests {
-		z, _ := new(Int).SetString(test.in, 10)
-		expected, _ := new(Int).SetString(test.out, 10)
-		z.Lsh(z, test.shift)
-
-		if !isNormalized(z) {
-			t.Errorf("#%d: %v is not normalized", i, *z)
-		}
-		if z.Cmp(expected) != 0 {
-			t.Errorf("#%d: got %s want %s", i, z, expected)
-		}
-	}
-}
-
-func TestLshRsh(t *testing.T) {
-	for i, test := range rshTests {
-		in, _ := new(Int).SetString(test.in, 10)
-		out := new(Int).Lsh(in, test.shift)
-		out = out.Rsh(out, test.shift)
-
-		if !isNormalized(out) {
-			t.Errorf("#%d: %v is not normalized", i, *out)
-		}
-		if in.Cmp(out) != 0 {
-			t.Errorf("#%d: got %s want %s", i, out, in)
-		}
-	}
-	for i, test := range lshTests {
-		in, _ := new(Int).SetString(test.in, 10)
-		out := new(Int).Lsh(in, test.shift)
-		out.Rsh(out, test.shift)
-
-		if !isNormalized(out) {
-			t.Errorf("#%d: %v is not normalized", i, *out)
-		}
-		if in.Cmp(out) != 0 {
-			t.Errorf("#%d: got %s want %s", i, out, in)
-		}
-	}
-}
-
-var int64Tests = []int64{
-	0,
-	1,
-	-1,
-	4294967295,
-	-4294967295,
-	4294967296,
-	-4294967296,
-	9223372036854775807,
-	-9223372036854775807,
-	-9223372036854775808,
-}
-
-func TestInt64(t *testing.T) {
-	for i, testVal := range int64Tests {
-		in := NewInt(testVal)
-		out := in.Int64()
-
-		if out != testVal {
-			t.Errorf("#%d got %d want %d", i, out, testVal)
-		}
-	}
-}
-
-var uint64Tests = []uint64{
-	0,
-	1,
-	4294967295,
-	4294967296,
-	8589934591,
-	8589934592,
-	9223372036854775807,
-	9223372036854775808,
-	18446744073709551615, // 1<<64 - 1
-}
-
-func TestUint64(t *testing.T) {
-	in := new(Int)
-	for i, testVal := range uint64Tests {
-		in.SetUint64(testVal)
-		out := in.Uint64()
-
-		if out != testVal {
-			t.Errorf("#%d got %d want %d", i, out, testVal)
-		}
-
-		str := fmt.Sprint(testVal)
-		strOut := in.String()
-		if strOut != str {
-			t.Errorf("#%d.String got %s want %s", i, strOut, str)
-		}
-	}
-}
-
-var bitwiseTests = []struct {
-	x, y                 string
-	and, or, xor, andNot string
-}{
-	{"0x00", "0x00", "0x00", "0x00", "0x00", "0x00"},
-	{"0x00", "0x01", "0x00", "0x01", "0x01", "0x00"},
-	{"0x01", "0x00", "0x00", "0x01", "0x01", "0x01"},
-	{"-0x01", "0x00", "0x00", "-0x01", "-0x01", "-0x01"},
-	{"-0xaf", "-0x50", "-0xf0", "-0x0f", "0xe1", "0x41"},
-	{"0x00", "-0x01", "0x00", "-0x01", "-0x01", "0x00"},
-	{"0x01", "0x01", "0x01", "0x01", "0x00", "0x00"},
-	{"-0x01", "-0x01", "-0x01", "-0x01", "0x00", "0x00"},
-	{"0x07", "0x08", "0x00", "0x0f", "0x0f", "0x07"},
-	{"0x05", "0x0f", "0x05", "0x0f", "0x0a", "0x00"},
-	{"0x013ff6", "0x9a4e", "0x1a46", "0x01bffe", "0x01a5b8", "0x0125b0"},
-	{"-0x013ff6", "0x9a4e", "0x800a", "-0x0125b2", "-0x01a5bc", "-0x01c000"},
-	{"-0x013ff6", "-0x9a4e", "-0x01bffe", "-0x1a46", "0x01a5b8", "0x8008"},
-	{
-		"0x1000009dc6e3d9822cba04129bcbe3401",
-		"0xb9bd7d543685789d57cb918e833af352559021483cdb05cc21fd",
-		"0x1000001186210100001000009048c2001",
-		"0xb9bd7d543685789d57cb918e8bfeff7fddb2ebe87dfbbdfe35fd",
-		"0xb9bd7d543685789d57ca918e8ae69d6fcdb2eae87df2b97215fc",
-		"0x8c40c2d8822caa04120b8321400",
-	},
-	{
-		"0x1000009dc6e3d9822cba04129bcbe3401",
-		"-0xb9bd7d543685789d57cb918e833af352559021483cdb05cc21fd",
-		"0x8c40c2d8822caa04120b8321401",
-		"-0xb9bd7d543685789d57ca918e82229142459020483cd2014001fd",
-		"-0xb9bd7d543685789d57ca918e8ae69d6fcdb2eae87df2b97215fe",
-		"0x1000001186210100001000009048c2000",
-	},
-	{
-		"-0x1000009dc6e3d9822cba04129bcbe3401",
-		"-0xb9bd7d543685789d57cb918e833af352559021483cdb05cc21fd",
-		"-0xb9bd7d543685789d57cb918e8bfeff7fddb2ebe87dfbbdfe35fd",
-		"-0x1000001186210100001000009048c2001",
-		"0xb9bd7d543685789d57ca918e8ae69d6fcdb2eae87df2b97215fc",
-		"0xb9bd7d543685789d57ca918e82229142459020483cd2014001fc",
-	},
-}
-
-type bitFun func(z, x, y *Int) *Int
-
-func testBitFun(t *testing.T, msg string, f bitFun, x, y *Int, exp string) {
-	expected := new(Int)
-	expected.SetString(exp, 0)
-
-	out := f(new(Int), x, y)
-	if out.Cmp(expected) != 0 {
-		t.Errorf("%s: got %s want %s", msg, out, expected)
-	}
-}
-
-func testBitFunSelf(t *testing.T, msg string, f bitFun, x, y *Int, exp string) {
-	self := new(Int)
-	self.Set(x)
-	expected := new(Int)
-	expected.SetString(exp, 0)
-
-	self = f(self, self, y)
-	if self.Cmp(expected) != 0 {
-		t.Errorf("%s: got %s want %s", msg, self, expected)
-	}
-}
-
-func altBit(x *Int, i int) uint {
-	z := new(Int).Rsh(x, uint(i))
-	z = z.And(z, NewInt(1))
-	if z.Cmp(new(Int)) != 0 {
-		return 1
-	}
-	return 0
-}
-
-func altSetBit(z *Int, x *Int, i int, b uint) *Int {
-	one := NewInt(1)
-	m := one.Lsh(one, uint(i))
-	switch b {
-	case 1:
-		return z.Or(x, m)
-	case 0:
-		return z.AndNot(x, m)
-	}
-	panic("set bit is not 0 or 1")
-}
-
-func testBitset(t *testing.T, x *Int) {
-	n := x.BitLen()
-	z := new(Int).Set(x)
-	z1 := new(Int).Set(x)
-	for i := 0; i < n+10; i++ {
-		old := z.Bit(i)
-		old1 := altBit(z1, i)
-		if old != old1 {
-			t.Errorf("bitset: inconsistent value for Bit(%s, %d), got %v want %v", z1, i, old, old1)
-		}
-		z := new(Int).SetBit(z, i, 1)
-		z1 := altSetBit(new(Int), z1, i, 1)
-		if z.Bit(i) == 0 {
-			t.Errorf("bitset: bit %d of %s got 0 want 1", i, x)
-		}
-		if z.Cmp(z1) != 0 {
-			t.Errorf("bitset: inconsistent value after SetBit 1, got %s want %s", z, z1)
-		}
-		z.SetBit(z, i, 0)
-		altSetBit(z1, z1, i, 0)
-		if z.Bit(i) != 0 {
-			t.Errorf("bitset: bit %d of %s got 1 want 0", i, x)
-		}
-		if z.Cmp(z1) != 0 {
-			t.Errorf("bitset: inconsistent value after SetBit 0, got %s want %s", z, z1)
-		}
-		altSetBit(z1, z1, i, old)
-		z.SetBit(z, i, old)
-		if z.Cmp(z1) != 0 {
-			t.Errorf("bitset: inconsistent value after SetBit old, got %s want %s", z, z1)
-		}
-	}
-	if z.Cmp(x) != 0 {
-		t.Errorf("bitset: got %s want %s", z, x)
-	}
-}
-
-var bitsetTests = []struct {
-	x string
-	i int
-	b uint
-}{
-	{"0", 0, 0},
-	{"0", 200, 0},
-	{"1", 0, 1},
-	{"1", 1, 0},
-	{"-1", 0, 1},
-	{"-1", 200, 1},
-	{"0x2000000000000000000000000000", 108, 0},
-	{"0x2000000000000000000000000000", 109, 1},
-	{"0x2000000000000000000000000000", 110, 0},
-	{"-0x2000000000000000000000000001", 108, 1},
-	{"-0x2000000000000000000000000001", 109, 0},
-	{"-0x2000000000000000000000000001", 110, 1},
-}
-
-func TestBitSet(t *testing.T) {
-	for _, test := range bitwiseTests {
-		x := new(Int)
-		x.SetString(test.x, 0)
-		testBitset(t, x)
-		x = new(Int)
-		x.SetString(test.y, 0)
-		testBitset(t, x)
-	}
-	for i, test := range bitsetTests {
-		x := new(Int)
-		x.SetString(test.x, 0)
-		b := x.Bit(test.i)
-		if b != test.b {
-			t.Errorf("#%d got %v want %v", i, b, test.b)
-		}
-	}
-	z := NewInt(1)
-	z.SetBit(NewInt(0), 2, 1)
-	if z.Cmp(NewInt(4)) != 0 {
-		t.Errorf("destination leaked into result; got %s want 4", z)
-	}
-}
-
-func BenchmarkBitset(b *testing.B) {
-	z := new(Int)
-	z.SetBit(z, 512, 1)
-	b.ResetTimer()
-	b.StartTimer()
-	for i := b.N - 1; i >= 0; i-- {
-		z.SetBit(z, i&512, 1)
-	}
-}
-
-func BenchmarkBitsetNeg(b *testing.B) {
-	z := NewInt(-1)
-	z.SetBit(z, 512, 0)
-	b.ResetTimer()
-	b.StartTimer()
-	for i := b.N - 1; i >= 0; i-- {
-		z.SetBit(z, i&512, 0)
-	}
-}
-
-func BenchmarkBitsetOrig(b *testing.B) {
-	z := new(Int)
-	altSetBit(z, z, 512, 1)
-	b.ResetTimer()
-	b.StartTimer()
-	for i := b.N - 1; i >= 0; i-- {
-		altSetBit(z, z, i&512, 1)
-	}
-}
-
-func BenchmarkBitsetNegOrig(b *testing.B) {
-	z := NewInt(-1)
-	altSetBit(z, z, 512, 0)
-	b.ResetTimer()
-	b.StartTimer()
-	for i := b.N - 1; i >= 0; i-- {
-		altSetBit(z, z, i&512, 0)
-	}
-}
-
-func TestBitwise(t *testing.T) {
-	x := new(Int)
-	y := new(Int)
-	for _, test := range bitwiseTests {
-		x.SetString(test.x, 0)
-		y.SetString(test.y, 0)
-
-		testBitFun(t, "and", (*Int).And, x, y, test.and)
-		testBitFunSelf(t, "and", (*Int).And, x, y, test.and)
-		testBitFun(t, "andNot", (*Int).AndNot, x, y, test.andNot)
-		testBitFunSelf(t, "andNot", (*Int).AndNot, x, y, test.andNot)
-		testBitFun(t, "or", (*Int).Or, x, y, test.or)
-		testBitFunSelf(t, "or", (*Int).Or, x, y, test.or)
-		testBitFun(t, "xor", (*Int).Xor, x, y, test.xor)
-		testBitFunSelf(t, "xor", (*Int).Xor, x, y, test.xor)
-	}
-}
-
-var notTests = []struct {
-	in  string
-	out string
-}{
-	{"0", "-1"},
-	{"1", "-2"},
-	{"7", "-8"},
-	{"0", "-1"},
-	{"-81910", "81909"},
-	{
-		"298472983472983471903246121093472394872319615612417471234712061",
-		"-298472983472983471903246121093472394872319615612417471234712062",
-	},
-}
-
-func TestNot(t *testing.T) {
-	in := new(Int)
-	out := new(Int)
-	expected := new(Int)
-	for i, test := range notTests {
-		in.SetString(test.in, 10)
-		expected.SetString(test.out, 10)
-		out = out.Not(in)
-		if out.Cmp(expected) != 0 {
-			t.Errorf("#%d: got %s want %s", i, out, expected)
-		}
-		out = out.Not(out)
-		if out.Cmp(in) != 0 {
-			t.Errorf("#%d: got %s want %s", i, out, in)
-		}
-	}
-}
-
-var modInverseTests = []struct {
-	element string
-	prime   string
-}{
-	{"1", "7"},
-	{"1", "13"},
-	{"239487239847", "2410312426921032588552076022197566074856950548502459942654116941958108831682612228890093858261341614673227141477904012196503648957050582631942730706805009223062734745341073406696246014589361659774041027169249453200378729434170325843778659198143763193776859869524088940195577346119843545301547043747207749969763750084308926339295559968882457872412993810129130294592999947926365264059284647209730384947211681434464714438488520940127459844288859336526896320919633919"},
-}
-
-func TestModInverse(t *testing.T) {
-	var element, prime Int
-	one := NewInt(1)
-	for i, test := range modInverseTests {
-		(&element).SetString(test.element, 10)
-		(&prime).SetString(test.prime, 10)
-		inverse := new(Int).ModInverse(&element, &prime)
-		inverse.Mul(inverse, &element)
-		inverse.Mod(inverse, &prime)
-		if inverse.Cmp(one) != 0 {
-			t.Errorf("#%d: failed (e·e^(-1)=%s)", i, inverse)
-		}
-	}
-}
-
-var encodingTests = []string{
-	"-539345864568634858364538753846587364875430589374589",
-	"-678645873",
-	"-100",
-	"-2",
-	"-1",
-	"0",
-	"1",
-	"2",
-	"10",
-	"42",
-	"1234567890",
-	"298472983472983471903246121093472394872319615612417471234712061",
-}
-
-func TestIntGobEncoding(t *testing.T) {
-	var medium bytes.Buffer
-	enc := gob.NewEncoder(&medium)
-	dec := gob.NewDecoder(&medium)
-	for _, test := range encodingTests {
-		medium.Reset() // empty buffer for each test case (in case of failures)
-		var tx Int
-		tx.SetString(test, 10)
-		if err := enc.Encode(&tx); err != nil {
-			t.Errorf("encoding of %s failed: %s", &tx, err)
-		}
-		var rx Int
-		if err := dec.Decode(&rx); err != nil {
-			t.Errorf("decoding of %s failed: %s", &tx, err)
-		}
-		if rx.Cmp(&tx) != 0 {
-			t.Errorf("transmission of %s failed: got %s want %s", &tx, &rx, &tx)
-		}
-	}
-}
-
-// Sending a nil Int pointer (inside a slice) on a round trip through gob should yield a zero.
-// TODO: top-level nils.
-func TestGobEncodingNilIntInSlice(t *testing.T) {
-	buf := new(bytes.Buffer)
-	enc := gob.NewEncoder(buf)
-	dec := gob.NewDecoder(buf)
-
-	var in = make([]*Int, 1)
-	err := enc.Encode(&in)
-	if err != nil {
-		t.Errorf("gob encode failed: %q", err)
-	}
-	var out []*Int
-	err = dec.Decode(&out)
-	if err != nil {
-		t.Fatalf("gob decode failed: %q", err)
-	}
-	if len(out) != 1 {
-		t.Fatalf("wrong len; want 1 got %d", len(out))
-	}
-	var zero Int
-	if out[0].Cmp(&zero) != 0 {
-		t.Errorf("transmission of (*Int)(nill) failed: got %s want 0", out)
-	}
-}
-
-func TestIntJSONEncoding(t *testing.T) {
-	for _, test := range encodingTests {
-		var tx Int
-		tx.SetString(test, 10)
-		b, err := json.Marshal(&tx)
-		if err != nil {
-			t.Errorf("marshaling of %s failed: %s", &tx, err)
-		}
-		var rx Int
-		if err := json.Unmarshal(b, &rx); err != nil {
-			t.Errorf("unmarshaling of %s failed: %s", &tx, err)
-		}
-		if rx.Cmp(&tx) != 0 {
-			t.Errorf("JSON encoding of %s failed: got %s want %s", &tx, &rx, &tx)
-		}
-	}
-}
-
-var intVals = []string{
-	"-141592653589793238462643383279502884197169399375105820974944592307816406286",
-	"-1415926535897932384626433832795028841971",
-	"-141592653589793",
-	"-1",
-	"0",
-	"1",
-	"141592653589793",
-	"1415926535897932384626433832795028841971",
-	"141592653589793238462643383279502884197169399375105820974944592307816406286",
-}
-
-func TestIntJSONEncodingTextMarshaller(t *testing.T) {
-	for _, num := range intVals {
-		var tx Int
-		tx.SetString(num, 0)
-		b, err := json.Marshal(&tx)
-		if err != nil {
-			t.Errorf("marshaling of %s failed: %s", &tx, err)
-			continue
-		}
-		var rx Int
-		if err := json.Unmarshal(b, &rx); err != nil {
-			t.Errorf("unmarshaling of %s failed: %s", &tx, err)
-			continue
-		}
-		if rx.Cmp(&tx) != 0 {
-			t.Errorf("JSON encoding of %s failed: got %s want %s", &tx, &rx, &tx)
-		}
-	}
-}
-
-func TestIntXMLEncodingTextMarshaller(t *testing.T) {
-	for _, num := range intVals {
-		var tx Int
-		tx.SetString(num, 0)
-		b, err := xml.Marshal(&tx)
-		if err != nil {
-			t.Errorf("marshaling of %s failed: %s", &tx, err)
-			continue
-		}
-		var rx Int
-		if err := xml.Unmarshal(b, &rx); err != nil {
-			t.Errorf("unmarshaling of %s failed: %s", &tx, err)
-			continue
-		}
-		if rx.Cmp(&tx) != 0 {
-			t.Errorf("XML encoding of %s failed: got %s want %s", &tx, &rx, &tx)
-		}
-	}
-}
-
-func TestIssue2607(t *testing.T) {
-	// This code sequence used to hang.
-	n := NewInt(10)
-	n.Rand(rand.New(rand.NewSource(9)), n)
-}
diff --git a/src/pkg/math/big/rat.go b/src/pkg/math/big/rat.go
deleted file mode 100644
index f0973b3..0000000
--- a/src/pkg/math/big/rat.go
+++ /dev/null
@@ -1,600 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// This file implements multi-precision rational numbers.
-
-package big
-
-import (
-	"encoding/binary"
-	"errors"
-	"fmt"
-	"math"
-	"strings"
-)
-
-// A Rat represents a quotient a/b of arbitrary precision.
-// The zero value for a Rat represents the value 0.
-type Rat struct {
-	// To make zero values for Rat work w/o initialization,
-	// a zero value of b (len(b) == 0) acts like b == 1.
-	// a.neg determines the sign of the Rat, b.neg is ignored.
-	a, b Int
-}
-
-// NewRat creates a new Rat with numerator a and denominator b.
-func NewRat(a, b int64) *Rat {
-	return new(Rat).SetFrac64(a, b)
-}
-
-// SetFloat64 sets z to exactly f and returns z.
-// If f is not finite, SetFloat returns nil.
-func (z *Rat) SetFloat64(f float64) *Rat {
-	const expMask = 1<<11 - 1
-	bits := math.Float64bits(f)
-	mantissa := bits & (1<<52 - 1)
-	exp := int((bits >> 52) & expMask)
-	switch exp {
-	case expMask: // non-finite
-		return nil
-	case 0: // denormal
-		exp -= 1022
-	default: // normal
-		mantissa |= 1 << 52
-		exp -= 1023
-	}
-
-	shift := 52 - exp
-
-	// Optimization (?): partially pre-normalise.
-	for mantissa&1 == 0 && shift > 0 {
-		mantissa >>= 1
-		shift--
-	}
-
-	z.a.SetUint64(mantissa)
-	z.a.neg = f < 0
-	z.b.Set(intOne)
-	if shift > 0 {
-		z.b.Lsh(&z.b, uint(shift))
-	} else {
-		z.a.Lsh(&z.a, uint(-shift))
-	}
-	return z.norm()
-}
-
-// isFinite reports whether f represents a finite rational value.
-// It is equivalent to !math.IsNan(f) && !math.IsInf(f, 0).
-func isFinite(f float64) bool {
-	return math.Abs(f) <= math.MaxFloat64
-}
-
-// low64 returns the least significant 64 bits of natural number z.
-func low64(z nat) uint64 {
-	if len(z) == 0 {
-		return 0
-	}
-	if _W == 32 && len(z) > 1 {
-		return uint64(z[1])<<32 | uint64(z[0])
-	}
-	return uint64(z[0])
-}
-
-// quotToFloat returns the non-negative IEEE 754 double-precision
-// value nearest to the quotient a/b, using round-to-even in halfway
-// cases.  It does not mutate its arguments.
-// Preconditions: b is non-zero; a and b have no common factors.
-func quotToFloat(a, b nat) (f float64, exact bool) {
-	// TODO(adonovan): specialize common degenerate cases: 1.0, integers.
-	alen := a.bitLen()
-	if alen == 0 {
-		return 0, true
-	}
-	blen := b.bitLen()
-	if blen == 0 {
-		panic("division by zero")
-	}
-
-	// 1. Left-shift A or B such that quotient A/B is in [1<<53, 1<<55).
-	// (54 bits if A<B when they are left-aligned, 55 bits if A>=B.)
-	// This is 2 or 3 more than the float64 mantissa field width of 52:
-	// - the optional extra bit is shifted away in step 3 below.
-	// - the high-order 1 is omitted in float64 "normal" representation;
-	// - the low-order 1 will be used during rounding then discarded.
-	exp := alen - blen
-	var a2, b2 nat
-	a2 = a2.set(a)
-	b2 = b2.set(b)
-	if shift := 54 - exp; shift > 0 {
-		a2 = a2.shl(a2, uint(shift))
-	} else if shift < 0 {
-		b2 = b2.shl(b2, uint(-shift))
-	}
-
-	// 2. Compute quotient and remainder (q, r).  NB: due to the
-	// extra shift, the low-order bit of q is logically the
-	// high-order bit of r.
-	var q nat
-	q, r := q.div(a2, a2, b2) // (recycle a2)
-	mantissa := low64(q)
-	haveRem := len(r) > 0 // mantissa&1 && !haveRem => remainder is exactly half
-
-	// 3. If quotient didn't fit in 54 bits, re-do division by b2<<1
-	// (in effect---we accomplish this incrementally).
-	if mantissa>>54 == 1 {
-		if mantissa&1 == 1 {
-			haveRem = true
-		}
-		mantissa >>= 1
-		exp++
-	}
-	if mantissa>>53 != 1 {
-		panic("expected exactly 54 bits of result")
-	}
-
-	// 4. Rounding.
-	if -1022-52 <= exp && exp <= -1022 {
-		// Denormal case; lose 'shift' bits of precision.
-		shift := uint64(-1022 - (exp - 1)) // [1..53)
-		lostbits := mantissa & (1<<shift - 1)
-		haveRem = haveRem || lostbits != 0
-		mantissa >>= shift
-		exp = -1023 + 2
-	}
-	// Round q using round-half-to-even.
-	exact = !haveRem
-	if mantissa&1 != 0 {
-		exact = false
-		if haveRem || mantissa&2 != 0 {
-			if mantissa++; mantissa >= 1<<54 {
-				// Complete rollover 11...1 => 100...0, so shift is safe
-				mantissa >>= 1
-				exp++
-			}
-		}
-	}
-	mantissa >>= 1 // discard rounding bit.  Mantissa now scaled by 2^53.
-
-	f = math.Ldexp(float64(mantissa), exp-53)
-	if math.IsInf(f, 0) {
-		exact = false
-	}
-	return
-}
-
-// Float64 returns the nearest float64 value for x and a bool indicating
-// whether f represents x exactly. If the magnitude of x is too large to
-// be represented by a float64, f is an infinity and exact is false.
-// The sign of f always matches the sign of x, even if f == 0.
-func (x *Rat) Float64() (f float64, exact bool) {
-	b := x.b.abs
-	if len(b) == 0 {
-		b = b.set(natOne) // materialize denominator
-	}
-	f, exact = quotToFloat(x.a.abs, b)
-	if x.a.neg {
-		f = -f
-	}
-	return
-}
-
-// SetFrac sets z to a/b and returns z.
-func (z *Rat) SetFrac(a, b *Int) *Rat {
-	z.a.neg = a.neg != b.neg
-	babs := b.abs
-	if len(babs) == 0 {
-		panic("division by zero")
-	}
-	if &z.a == b || alias(z.a.abs, babs) {
-		babs = nat(nil).set(babs) // make a copy
-	}
-	z.a.abs = z.a.abs.set(a.abs)
-	z.b.abs = z.b.abs.set(babs)
-	return z.norm()
-}
-
-// SetFrac64 sets z to a/b and returns z.
-func (z *Rat) SetFrac64(a, b int64) *Rat {
-	z.a.SetInt64(a)
-	if b == 0 {
-		panic("division by zero")
-	}
-	if b < 0 {
-		b = -b
-		z.a.neg = !z.a.neg
-	}
-	z.b.abs = z.b.abs.setUint64(uint64(b))
-	return z.norm()
-}
-
-// SetInt sets z to x (by making a copy of x) and returns z.
-func (z *Rat) SetInt(x *Int) *Rat {
-	z.a.Set(x)
-	z.b.abs = z.b.abs.make(0)
-	return z
-}
-
-// SetInt64 sets z to x and returns z.
-func (z *Rat) SetInt64(x int64) *Rat {
-	z.a.SetInt64(x)
-	z.b.abs = z.b.abs.make(0)
-	return z
-}
-
-// Set sets z to x (by making a copy of x) and returns z.
-func (z *Rat) Set(x *Rat) *Rat {
-	if z != x {
-		z.a.Set(&x.a)
-		z.b.Set(&x.b)
-	}
-	return z
-}
-
-// Abs sets z to |x| (the absolute value of x) and returns z.
-func (z *Rat) Abs(x *Rat) *Rat {
-	z.Set(x)
-	z.a.neg = false
-	return z
-}
-
-// Neg sets z to -x and returns z.
-func (z *Rat) Neg(x *Rat) *Rat {
-	z.Set(x)
-	z.a.neg = len(z.a.abs) > 0 && !z.a.neg // 0 has no sign
-	return z
-}
-
-// Inv sets z to 1/x and returns z.
-func (z *Rat) Inv(x *Rat) *Rat {
-	if len(x.a.abs) == 0 {
-		panic("division by zero")
-	}
-	z.Set(x)
-	a := z.b.abs
-	if len(a) == 0 {
-		a = a.set(natOne) // materialize numerator
-	}
-	b := z.a.abs
-	if b.cmp(natOne) == 0 {
-		b = b.make(0) // normalize denominator
-	}
-	z.a.abs, z.b.abs = a, b // sign doesn't change
-	return z
-}
-
-// Sign returns:
-//
-//	-1 if x <  0
-//	 0 if x == 0
-//	+1 if x >  0
-//
-func (x *Rat) Sign() int {
-	return x.a.Sign()
-}
-
-// IsInt returns true if the denominator of x is 1.
-func (x *Rat) IsInt() bool {
-	return len(x.b.abs) == 0 || x.b.abs.cmp(natOne) == 0
-}
-
-// Num returns the numerator of x; it may be <= 0.
-// The result is a reference to x's numerator; it
-// may change if a new value is assigned to x, and vice versa.
-// The sign of the numerator corresponds to the sign of x.
-func (x *Rat) Num() *Int {
-	return &x.a
-}
-
-// Denom returns the denominator of x; it is always > 0.
-// The result is a reference to x's denominator; it
-// may change if a new value is assigned to x, and vice versa.
-func (x *Rat) Denom() *Int {
-	x.b.neg = false // the result is always >= 0
-	if len(x.b.abs) == 0 {
-		x.b.abs = x.b.abs.set(natOne) // materialize denominator
-	}
-	return &x.b
-}
-
-func (z *Rat) norm() *Rat {
-	switch {
-	case len(z.a.abs) == 0:
-		// z == 0 - normalize sign and denominator
-		z.a.neg = false
-		z.b.abs = z.b.abs.make(0)
-	case len(z.b.abs) == 0:
-		// z is normalized int - nothing to do
-	case z.b.abs.cmp(natOne) == 0:
-		// z is int - normalize denominator
-		z.b.abs = z.b.abs.make(0)
-	default:
-		neg := z.a.neg
-		z.a.neg = false
-		z.b.neg = false
-		if f := NewInt(0).binaryGCD(&z.a, &z.b); f.Cmp(intOne) != 0 {
-			z.a.abs, _ = z.a.abs.div(nil, z.a.abs, f.abs)
-			z.b.abs, _ = z.b.abs.div(nil, z.b.abs, f.abs)
-			if z.b.abs.cmp(natOne) == 0 {
-				// z is int - normalize denominator
-				z.b.abs = z.b.abs.make(0)
-			}
-		}
-		z.a.neg = neg
-	}
-	return z
-}
-
-// mulDenom sets z to the denominator product x*y (by taking into
-// account that 0 values for x or y must be interpreted as 1) and
-// returns z.
-func mulDenom(z, x, y nat) nat {
-	switch {
-	case len(x) == 0:
-		return z.set(y)
-	case len(y) == 0:
-		return z.set(x)
-	}
-	return z.mul(x, y)
-}
-
-// scaleDenom computes x*f.
-// If f == 0 (zero value of denominator), the result is (a copy of) x.
-func scaleDenom(x *Int, f nat) *Int {
-	var z Int
-	if len(f) == 0 {
-		return z.Set(x)
-	}
-	z.abs = z.abs.mul(x.abs, f)
-	z.neg = x.neg
-	return &z
-}
-
-// Cmp compares x and y and returns:
-//
-//   -1 if x <  y
-//    0 if x == y
-//   +1 if x >  y
-//
-func (x *Rat) Cmp(y *Rat) int {
-	return scaleDenom(&x.a, y.b.abs).Cmp(scaleDenom(&y.a, x.b.abs))
-}
-
-// Add sets z to the sum x+y and returns z.
-func (z *Rat) Add(x, y *Rat) *Rat {
-	a1 := scaleDenom(&x.a, y.b.abs)
-	a2 := scaleDenom(&y.a, x.b.abs)
-	z.a.Add(a1, a2)
-	z.b.abs = mulDenom(z.b.abs, x.b.abs, y.b.abs)
-	return z.norm()
-}
-
-// Sub sets z to the difference x-y and returns z.
-func (z *Rat) Sub(x, y *Rat) *Rat {
-	a1 := scaleDenom(&x.a, y.b.abs)
-	a2 := scaleDenom(&y.a, x.b.abs)
-	z.a.Sub(a1, a2)
-	z.b.abs = mulDenom(z.b.abs, x.b.abs, y.b.abs)
-	return z.norm()
-}
-
-// Mul sets z to the product x*y and returns z.
-func (z *Rat) Mul(x, y *Rat) *Rat {
-	z.a.Mul(&x.a, &y.a)
-	z.b.abs = mulDenom(z.b.abs, x.b.abs, y.b.abs)
-	return z.norm()
-}
-
-// Quo sets z to the quotient x/y and returns z.
-// If y == 0, a division-by-zero run-time panic occurs.
-func (z *Rat) Quo(x, y *Rat) *Rat {
-	if len(y.a.abs) == 0 {
-		panic("division by zero")
-	}
-	a := scaleDenom(&x.a, y.b.abs)
-	b := scaleDenom(&y.a, x.b.abs)
-	z.a.abs = a.abs
-	z.b.abs = b.abs
-	z.a.neg = a.neg != b.neg
-	return z.norm()
-}
-
-func ratTok(ch rune) bool {
-	return strings.IndexRune("+-/0123456789.eE", ch) >= 0
-}
-
-// Scan is a support routine for fmt.Scanner. It accepts the formats
-// 'e', 'E', 'f', 'F', 'g', 'G', and 'v'. All formats are equivalent.
-func (z *Rat) Scan(s fmt.ScanState, ch rune) error {
-	tok, err := s.Token(true, ratTok)
-	if err != nil {
-		return err
-	}
-	if strings.IndexRune("efgEFGv", ch) < 0 {
-		return errors.New("Rat.Scan: invalid verb")
-	}
-	if _, ok := z.SetString(string(tok)); !ok {
-		return errors.New("Rat.Scan: invalid syntax")
-	}
-	return nil
-}
-
-// SetString sets z to the value of s and returns z and a boolean indicating
-// success. s can be given as a fraction "a/b" or as a floating-point number
-// optionally followed by an exponent. If the operation failed, the value of
-// z is undefined but the returned value is nil.
-func (z *Rat) SetString(s string) (*Rat, bool) {
-	if len(s) == 0 {
-		return nil, false
-	}
-
-	// check for a quotient
-	sep := strings.Index(s, "/")
-	if sep >= 0 {
-		if _, ok := z.a.SetString(s[0:sep], 10); !ok {
-			return nil, false
-		}
-		s = s[sep+1:]
-		var err error
-		if z.b.abs, _, err = z.b.abs.scan(strings.NewReader(s), 10); err != nil {
-			return nil, false
-		}
-		return z.norm(), true
-	}
-
-	// check for a decimal point
-	sep = strings.Index(s, ".")
-	// check for an exponent
-	e := strings.IndexAny(s, "eE")
-	var exp Int
-	if e >= 0 {
-		if e < sep {
-			// The E must come after the decimal point.
-			return nil, false
-		}
-		if _, ok := exp.SetString(s[e+1:], 10); !ok {
-			return nil, false
-		}
-		s = s[0:e]
-	}
-	if sep >= 0 {
-		s = s[0:sep] + s[sep+1:]
-		exp.Sub(&exp, NewInt(int64(len(s)-sep)))
-	}
-
-	if _, ok := z.a.SetString(s, 10); !ok {
-		return nil, false
-	}
-	powTen := nat(nil).expNN(natTen, exp.abs, nil)
-	if exp.neg {
-		z.b.abs = powTen
-		z.norm()
-	} else {
-		z.a.abs = z.a.abs.mul(z.a.abs, powTen)
-		z.b.abs = z.b.abs.make(0)
-	}
-
-	return z, true
-}
-
-// String returns a string representation of x in the form "a/b" (even if b == 1).
-func (x *Rat) String() string {
-	s := "/1"
-	if len(x.b.abs) != 0 {
-		s = "/" + x.b.abs.decimalString()
-	}
-	return x.a.String() + s
-}
-
-// RatString returns a string representation of x in the form "a/b" if b != 1,
-// and in the form "a" if b == 1.
-func (x *Rat) RatString() string {
-	if x.IsInt() {
-		return x.a.String()
-	}
-	return x.String()
-}
-
-// FloatString returns a string representation of x in decimal form with prec
-// digits of precision after the decimal point and the last digit rounded.
-func (x *Rat) FloatString(prec int) string {
-	if x.IsInt() {
-		s := x.a.String()
-		if prec > 0 {
-			s += "." + strings.Repeat("0", prec)
-		}
-		return s
-	}
-	// x.b.abs != 0
-
-	q, r := nat(nil).div(nat(nil), x.a.abs, x.b.abs)
-
-	p := natOne
-	if prec > 0 {
-		p = nat(nil).expNN(natTen, nat(nil).setUint64(uint64(prec)), nil)
-	}
-
-	r = r.mul(r, p)
-	r, r2 := r.div(nat(nil), r, x.b.abs)
-
-	// see if we need to round up
-	r2 = r2.add(r2, r2)
-	if x.b.abs.cmp(r2) <= 0 {
-		r = r.add(r, natOne)
-		if r.cmp(p) >= 0 {
-			q = nat(nil).add(q, natOne)
-			r = nat(nil).sub(r, p)
-		}
-	}
-
-	s := q.decimalString()
-	if x.a.neg {
-		s = "-" + s
-	}
-
-	if prec > 0 {
-		rs := r.decimalString()
-		leadingZeros := prec - len(rs)
-		s += "." + strings.Repeat("0", leadingZeros) + rs
-	}
-
-	return s
-}
-
-// Gob codec version. Permits backward-compatible changes to the encoding.
-const ratGobVersion byte = 1
-
-// GobEncode implements the gob.GobEncoder interface.
-func (x *Rat) GobEncode() ([]byte, error) {
-	if x == nil {
-		return nil, nil
-	}
-	buf := make([]byte, 1+4+(len(x.a.abs)+len(x.b.abs))*_S) // extra bytes for version and sign bit (1), and numerator length (4)
-	i := x.b.abs.bytes(buf)
-	j := x.a.abs.bytes(buf[0:i])
-	n := i - j
-	if int(uint32(n)) != n {
-		// this should never happen
-		return nil, errors.New("Rat.GobEncode: numerator too large")
-	}
-	binary.BigEndian.PutUint32(buf[j-4:j], uint32(n))
-	j -= 1 + 4
-	b := ratGobVersion << 1 // make space for sign bit
-	if x.a.neg {
-		b |= 1
-	}
-	buf[j] = b
-	return buf[j:], nil
-}
-
-// GobDecode implements the gob.GobDecoder interface.
-func (z *Rat) GobDecode(buf []byte) error {
-	if len(buf) == 0 {
-		// Other side sent a nil or default value.
-		*z = Rat{}
-		return nil
-	}
-	b := buf[0]
-	if b>>1 != ratGobVersion {
-		return errors.New(fmt.Sprintf("Rat.GobDecode: encoding version %d not supported", b>>1))
-	}
-	const j = 1 + 4
-	i := j + binary.BigEndian.Uint32(buf[j-4:j])
-	z.a.neg = b&1 != 0
-	z.a.abs = z.a.abs.setBytes(buf[j:i])
-	z.b.abs = z.b.abs.setBytes(buf[i:])
-	return nil
-}
-
-// MarshalText implements the encoding.TextMarshaler interface
-func (r *Rat) MarshalText() (text []byte, err error) {
-	return []byte(r.RatString()), nil
-}
-
-// UnmarshalText implements the encoding.TextUnmarshaler interface
-func (r *Rat) UnmarshalText(text []byte) error {
-	if _, ok := r.SetString(string(text)); !ok {
-		return fmt.Errorf("math/big: cannot unmarshal %q into a *big.Rat", text)
-	}
-	return nil
-}
diff --git a/src/pkg/math/big/rat_test.go b/src/pkg/math/big/rat_test.go
deleted file mode 100644
index 414a67d..0000000
--- a/src/pkg/math/big/rat_test.go
+++ /dev/null
@@ -1,994 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package big
-
-import (
-	"bytes"
-	"encoding/gob"
-	"encoding/json"
-	"encoding/xml"
-	"fmt"
-	"math"
-	"strconv"
-	"strings"
-	"testing"
-)
-
-func TestZeroRat(t *testing.T) {
-	var x, y, z Rat
-	y.SetFrac64(0, 42)
-
-	if x.Cmp(&y) != 0 {
-		t.Errorf("x and y should be both equal and zero")
-	}
-
-	if s := x.String(); s != "0/1" {
-		t.Errorf("got x = %s, want 0/1", s)
-	}
-
-	if s := x.RatString(); s != "0" {
-		t.Errorf("got x = %s, want 0", s)
-	}
-
-	z.Add(&x, &y)
-	if s := z.RatString(); s != "0" {
-		t.Errorf("got x+y = %s, want 0", s)
-	}
-
-	z.Sub(&x, &y)
-	if s := z.RatString(); s != "0" {
-		t.Errorf("got x-y = %s, want 0", s)
-	}
-
-	z.Mul(&x, &y)
-	if s := z.RatString(); s != "0" {
-		t.Errorf("got x*y = %s, want 0", s)
-	}
-
-	// check for division by zero
-	defer func() {
-		if s := recover(); s == nil || s.(string) != "division by zero" {
-			panic(s)
-		}
-	}()
-	z.Quo(&x, &y)
-}
-
-var setStringTests = []struct {
-	in, out string
-	ok      bool
-}{
-	{"0", "0", true},
-	{"-0", "0", true},
-	{"1", "1", true},
-	{"-1", "-1", true},
-	{"1.", "1", true},
-	{"1e0", "1", true},
-	{"1.e1", "10", true},
-	{in: "1e", ok: false},
-	{in: "1.e", ok: false},
-	{in: "1e+14e-5", ok: false},
-	{in: "1e4.5", ok: false},
-	{in: "r", ok: false},
-	{in: "a/b", ok: false},
-	{in: "a.b", ok: false},
-	{"-0.1", "-1/10", true},
-	{"-.1", "-1/10", true},
-	{"2/4", "1/2", true},
-	{".25", "1/4", true},
-	{"-1/5", "-1/5", true},
-	{"8129567.7690E14", "812956776900000000000", true},
-	{"78189e+4", "781890000", true},
-	{"553019.8935e+8", "55301989350000", true},
-	{"98765432109876543210987654321e-10", "98765432109876543210987654321/10000000000", true},
-	{"9877861857500000E-7", "3951144743/4", true},
-	{"2169378.417e-3", "2169378417/1000000", true},
-	{"884243222337379604041632732738665534", "884243222337379604041632732738665534", true},
-	{"53/70893980658822810696", "53/70893980658822810696", true},
-	{"106/141787961317645621392", "53/70893980658822810696", true},
-	{"204211327800791583.81095", "4084226556015831676219/20000", true},
-}
-
-func TestRatSetString(t *testing.T) {
-	for i, test := range setStringTests {
-		x, ok := new(Rat).SetString(test.in)
-
-		if ok {
-			if !test.ok {
-				t.Errorf("#%d SetString(%q) expected failure", i, test.in)
-			} else if x.RatString() != test.out {
-				t.Errorf("#%d SetString(%q) got %s want %s", i, test.in, x.RatString(), test.out)
-			}
-		} else if x != nil {
-			t.Errorf("#%d SetString(%q) got %p want nil", i, test.in, x)
-		}
-	}
-}
-
-func TestRatScan(t *testing.T) {
-	var buf bytes.Buffer
-	for i, test := range setStringTests {
-		x := new(Rat)
-		buf.Reset()
-		buf.WriteString(test.in)
-
-		_, err := fmt.Fscanf(&buf, "%v", x)
-		if err == nil != test.ok {
-			if test.ok {
-				t.Errorf("#%d error: %s", i, err)
-			} else {
-				t.Errorf("#%d expected error", i)
-			}
-			continue
-		}
-		if err == nil && x.RatString() != test.out {
-			t.Errorf("#%d got %s want %s", i, x.RatString(), test.out)
-		}
-	}
-}
-
-var floatStringTests = []struct {
-	in   string
-	prec int
-	out  string
-}{
-	{"0", 0, "0"},
-	{"0", 4, "0.0000"},
-	{"1", 0, "1"},
-	{"1", 2, "1.00"},
-	{"-1", 0, "-1"},
-	{".25", 2, "0.25"},
-	{".25", 1, "0.3"},
-	{".25", 3, "0.250"},
-	{"-1/3", 3, "-0.333"},
-	{"-2/3", 4, "-0.6667"},
-	{"0.96", 1, "1.0"},
-	{"0.999", 2, "1.00"},
-	{"0.9", 0, "1"},
-	{".25", -1, "0"},
-	{".55", -1, "1"},
-}
-
-func TestFloatString(t *testing.T) {
-	for i, test := range floatStringTests {
-		x, _ := new(Rat).SetString(test.in)
-
-		if x.FloatString(test.prec) != test.out {
-			t.Errorf("#%d got %s want %s", i, x.FloatString(test.prec), test.out)
-		}
-	}
-}
-
-func TestRatSign(t *testing.T) {
-	zero := NewRat(0, 1)
-	for _, a := range setStringTests {
-		x, ok := new(Rat).SetString(a.in)
-		if !ok {
-			continue
-		}
-		s := x.Sign()
-		e := x.Cmp(zero)
-		if s != e {
-			t.Errorf("got %d; want %d for z = %v", s, e, &x)
-		}
-	}
-}
-
-var ratCmpTests = []struct {
-	rat1, rat2 string
-	out        int
-}{
-	{"0", "0/1", 0},
-	{"1/1", "1", 0},
-	{"-1", "-2/2", 0},
-	{"1", "0", 1},
-	{"0/1", "1/1", -1},
-	{"-5/1434770811533343057144", "-5/1434770811533343057145", -1},
-	{"49832350382626108453/8964749413", "49832350382626108454/8964749413", -1},
-	{"-37414950961700930/7204075375675961", "37414950961700930/7204075375675961", -1},
-	{"37414950961700930/7204075375675961", "74829901923401860/14408150751351922", 0},
-}
-
-func TestRatCmp(t *testing.T) {
-	for i, test := range ratCmpTests {
-		x, _ := new(Rat).SetString(test.rat1)
-		y, _ := new(Rat).SetString(test.rat2)
-
-		out := x.Cmp(y)
-		if out != test.out {
-			t.Errorf("#%d got out = %v; want %v", i, out, test.out)
-		}
-	}
-}
-
-func TestIsInt(t *testing.T) {
-	one := NewInt(1)
-	for _, a := range setStringTests {
-		x, ok := new(Rat).SetString(a.in)
-		if !ok {
-			continue
-		}
-		i := x.IsInt()
-		e := x.Denom().Cmp(one) == 0
-		if i != e {
-			t.Errorf("got IsInt(%v) == %v; want %v", x, i, e)
-		}
-	}
-}
-
-func TestRatAbs(t *testing.T) {
-	zero := new(Rat)
-	for _, a := range setStringTests {
-		x, ok := new(Rat).SetString(a.in)
-		if !ok {
-			continue
-		}
-		e := new(Rat).Set(x)
-		if e.Cmp(zero) < 0 {
-			e.Sub(zero, e)
-		}
-		z := new(Rat).Abs(x)
-		if z.Cmp(e) != 0 {
-			t.Errorf("got Abs(%v) = %v; want %v", x, z, e)
-		}
-	}
-}
-
-func TestRatNeg(t *testing.T) {
-	zero := new(Rat)
-	for _, a := range setStringTests {
-		x, ok := new(Rat).SetString(a.in)
-		if !ok {
-			continue
-		}
-		e := new(Rat).Sub(zero, x)
-		z := new(Rat).Neg(x)
-		if z.Cmp(e) != 0 {
-			t.Errorf("got Neg(%v) = %v; want %v", x, z, e)
-		}
-	}
-}
-
-func TestRatInv(t *testing.T) {
-	zero := new(Rat)
-	for _, a := range setStringTests {
-		x, ok := new(Rat).SetString(a.in)
-		if !ok {
-			continue
-		}
-		if x.Cmp(zero) == 0 {
-			continue // avoid division by zero
-		}
-		e := new(Rat).SetFrac(x.Denom(), x.Num())
-		z := new(Rat).Inv(x)
-		if z.Cmp(e) != 0 {
-			t.Errorf("got Inv(%v) = %v; want %v", x, z, e)
-		}
-	}
-}
-
-type ratBinFun func(z, x, y *Rat) *Rat
-type ratBinArg struct {
-	x, y, z string
-}
-
-func testRatBin(t *testing.T, i int, name string, f ratBinFun, a ratBinArg) {
-	x, _ := new(Rat).SetString(a.x)
-	y, _ := new(Rat).SetString(a.y)
-	z, _ := new(Rat).SetString(a.z)
-	out := f(new(Rat), x, y)
-
-	if out.Cmp(z) != 0 {
-		t.Errorf("%s #%d got %s want %s", name, i, out, z)
-	}
-}
-
-var ratBinTests = []struct {
-	x, y      string
-	sum, prod string
-}{
-	{"0", "0", "0", "0"},
-	{"0", "1", "1", "0"},
-	{"-1", "0", "-1", "0"},
-	{"-1", "1", "0", "-1"},
-	{"1", "1", "2", "1"},
-	{"1/2", "1/2", "1", "1/4"},
-	{"1/4", "1/3", "7/12", "1/12"},
-	{"2/5", "-14/3", "-64/15", "-28/15"},
-	{"4707/49292519774798173060", "-3367/70976135186689855734", "84058377121001851123459/1749296273614329067191168098769082663020", "-1760941/388732505247628681598037355282018369560"},
-	{"-61204110018146728334/3", "-31052192278051565633/2", "-215564796870448153567/6", "950260896245257153059642991192710872711/3"},
-	{"-854857841473707320655/4237645934602118692642972629634714039", "-18/31750379913563777419", "-27/133467566250814981", "15387441146526731771790/134546868362786310073779084329032722548987800600710485341"},
-	{"618575745270541348005638912139/19198433543745179392300736", "-19948846211000086/637313996471", "27674141753240653/30123979153216", "-6169936206128396568797607742807090270137721977/6117715203873571641674006593837351328"},
-	{"-3/26206484091896184128", "5/2848423294177090248", "15310893822118706237/9330894968229805033368778458685147968", "-5/24882386581946146755650075889827061248"},
-	{"26946729/330400702820", "41563965/225583428284", "1238218672302860271/4658307703098666660055", "224002580204097/14906584649915733312176"},
-	{"-8259900599013409474/7", "-84829337473700364773/56707961321161574960", "-468402123685491748914621885145127724451/396955729248131024720", "350340947706464153265156004876107029701/198477864624065512360"},
-	{"575775209696864/1320203974639986246357", "29/712593081308", "410331716733912717985762465/940768218243776489278275419794956", "808/45524274987585732633"},
-	{"1786597389946320496771/2066653520653241", "6269770/1992362624741777", "3559549865190272133656109052308126637/4117523232840525481453983149257", "8967230/3296219033"},
-	{"-36459180403360509753/32150500941194292113930", "9381566963714/9633539", "301622077145533298008420642898530153/309723104686531919656937098270", "-3784609207827/3426986245"},
-}
-
-func TestRatBin(t *testing.T) {
-	for i, test := range ratBinTests {
-		arg := ratBinArg{test.x, test.y, test.sum}
-		testRatBin(t, i, "Add", (*Rat).Add, arg)
-
-		arg = ratBinArg{test.y, test.x, test.sum}
-		testRatBin(t, i, "Add symmetric", (*Rat).Add, arg)
-
-		arg = ratBinArg{test.sum, test.x, test.y}
-		testRatBin(t, i, "Sub", (*Rat).Sub, arg)
-
-		arg = ratBinArg{test.sum, test.y, test.x}
-		testRatBin(t, i, "Sub symmetric", (*Rat).Sub, arg)
-
-		arg = ratBinArg{test.x, test.y, test.prod}
-		testRatBin(t, i, "Mul", (*Rat).Mul, arg)
-
-		arg = ratBinArg{test.y, test.x, test.prod}
-		testRatBin(t, i, "Mul symmetric", (*Rat).Mul, arg)
-
-		if test.x != "0" {
-			arg = ratBinArg{test.prod, test.x, test.y}
-			testRatBin(t, i, "Quo", (*Rat).Quo, arg)
-		}
-
-		if test.y != "0" {
-			arg = ratBinArg{test.prod, test.y, test.x}
-			testRatBin(t, i, "Quo symmetric", (*Rat).Quo, arg)
-		}
-	}
-}
-
-func TestIssue820(t *testing.T) {
-	x := NewRat(3, 1)
-	y := NewRat(2, 1)
-	z := y.Quo(x, y)
-	q := NewRat(3, 2)
-	if z.Cmp(q) != 0 {
-		t.Errorf("got %s want %s", z, q)
-	}
-
-	y = NewRat(3, 1)
-	x = NewRat(2, 1)
-	z = y.Quo(x, y)
-	q = NewRat(2, 3)
-	if z.Cmp(q) != 0 {
-		t.Errorf("got %s want %s", z, q)
-	}
-
-	x = NewRat(3, 1)
-	z = x.Quo(x, x)
-	q = NewRat(3, 3)
-	if z.Cmp(q) != 0 {
-		t.Errorf("got %s want %s", z, q)
-	}
-}
-
-var setFrac64Tests = []struct {
-	a, b int64
-	out  string
-}{
-	{0, 1, "0"},
-	{0, -1, "0"},
-	{1, 1, "1"},
-	{-1, 1, "-1"},
-	{1, -1, "-1"},
-	{-1, -1, "1"},
-	{-9223372036854775808, -9223372036854775808, "1"},
-}
-
-func TestRatSetFrac64Rat(t *testing.T) {
-	for i, test := range setFrac64Tests {
-		x := new(Rat).SetFrac64(test.a, test.b)
-		if x.RatString() != test.out {
-			t.Errorf("#%d got %s want %s", i, x.RatString(), test.out)
-		}
-	}
-}
-
-func TestRatGobEncoding(t *testing.T) {
-	var medium bytes.Buffer
-	enc := gob.NewEncoder(&medium)
-	dec := gob.NewDecoder(&medium)
-	for _, test := range encodingTests {
-		medium.Reset() // empty buffer for each test case (in case of failures)
-		var tx Rat
-		tx.SetString(test + ".14159265")
-		if err := enc.Encode(&tx); err != nil {
-			t.Errorf("encoding of %s failed: %s", &tx, err)
-		}
-		var rx Rat
-		if err := dec.Decode(&rx); err != nil {
-			t.Errorf("decoding of %s failed: %s", &tx, err)
-		}
-		if rx.Cmp(&tx) != 0 {
-			t.Errorf("transmission of %s failed: got %s want %s", &tx, &rx, &tx)
-		}
-	}
-}
-
-// Sending a nil Rat pointer (inside a slice) on a round trip through gob should yield a zero.
-// TODO: top-level nils.
-func TestGobEncodingNilRatInSlice(t *testing.T) {
-	buf := new(bytes.Buffer)
-	enc := gob.NewEncoder(buf)
-	dec := gob.NewDecoder(buf)
-
-	var in = make([]*Rat, 1)
-	err := enc.Encode(&in)
-	if err != nil {
-		t.Errorf("gob encode failed: %q", err)
-	}
-	var out []*Rat
-	err = dec.Decode(&out)
-	if err != nil {
-		t.Fatalf("gob decode failed: %q", err)
-	}
-	if len(out) != 1 {
-		t.Fatalf("wrong len; want 1 got %d", len(out))
-	}
-	var zero Rat
-	if out[0].Cmp(&zero) != 0 {
-		t.Errorf("transmission of (*Int)(nill) failed: got %s want 0", out)
-	}
-}
-
-var ratNums = []string{
-	"-141592653589793238462643383279502884197169399375105820974944592307816406286",
-	"-1415926535897932384626433832795028841971",
-	"-141592653589793",
-	"-1",
-	"0",
-	"1",
-	"141592653589793",
-	"1415926535897932384626433832795028841971",
-	"141592653589793238462643383279502884197169399375105820974944592307816406286",
-}
-
-var ratDenoms = []string{
-	"1",
-	"718281828459045",
-	"7182818284590452353602874713526624977572",
-	"718281828459045235360287471352662497757247093699959574966967627724076630353",
-}
-
-func TestRatJSONEncoding(t *testing.T) {
-	for _, num := range ratNums {
-		for _, denom := range ratDenoms {
-			var tx Rat
-			tx.SetString(num + "/" + denom)
-			b, err := json.Marshal(&tx)
-			if err != nil {
-				t.Errorf("marshaling of %s failed: %s", &tx, err)
-				continue
-			}
-			var rx Rat
-			if err := json.Unmarshal(b, &rx); err != nil {
-				t.Errorf("unmarshaling of %s failed: %s", &tx, err)
-				continue
-			}
-			if rx.Cmp(&tx) != 0 {
-				t.Errorf("JSON encoding of %s failed: got %s want %s", &tx, &rx, &tx)
-			}
-		}
-	}
-}
-
-func TestRatXMLEncoding(t *testing.T) {
-	for _, num := range ratNums {
-		for _, denom := range ratDenoms {
-			var tx Rat
-			tx.SetString(num + "/" + denom)
-			b, err := xml.Marshal(&tx)
-			if err != nil {
-				t.Errorf("marshaling of %s failed: %s", &tx, err)
-				continue
-			}
-			var rx Rat
-			if err := xml.Unmarshal(b, &rx); err != nil {
-				t.Errorf("unmarshaling of %s failed: %s", &tx, err)
-				continue
-			}
-			if rx.Cmp(&tx) != 0 {
-				t.Errorf("XML encoding of %s failed: got %s want %s", &tx, &rx, &tx)
-			}
-		}
-	}
-}
-
-func TestIssue2379(t *testing.T) {
-	// 1) no aliasing
-	q := NewRat(3, 2)
-	x := new(Rat)
-	x.SetFrac(NewInt(3), NewInt(2))
-	if x.Cmp(q) != 0 {
-		t.Errorf("1) got %s want %s", x, q)
-	}
-
-	// 2) aliasing of numerator
-	x = NewRat(2, 3)
-	x.SetFrac(NewInt(3), x.Num())
-	if x.Cmp(q) != 0 {
-		t.Errorf("2) got %s want %s", x, q)
-	}
-
-	// 3) aliasing of denominator
-	x = NewRat(2, 3)
-	x.SetFrac(x.Denom(), NewInt(2))
-	if x.Cmp(q) != 0 {
-		t.Errorf("3) got %s want %s", x, q)
-	}
-
-	// 4) aliasing of numerator and denominator
-	x = NewRat(2, 3)
-	x.SetFrac(x.Denom(), x.Num())
-	if x.Cmp(q) != 0 {
-		t.Errorf("4) got %s want %s", x, q)
-	}
-
-	// 5) numerator and denominator are the same
-	q = NewRat(1, 1)
-	x = new(Rat)
-	n := NewInt(7)
-	x.SetFrac(n, n)
-	if x.Cmp(q) != 0 {
-		t.Errorf("5) got %s want %s", x, q)
-	}
-}
-
-func TestIssue3521(t *testing.T) {
-	a := new(Int)
-	b := new(Int)
-	a.SetString("64375784358435883458348587", 0)
-	b.SetString("4789759874531", 0)
-
-	// 0) a raw zero value has 1 as denominator
-	zero := new(Rat)
-	one := NewInt(1)
-	if zero.Denom().Cmp(one) != 0 {
-		t.Errorf("0) got %s want %s", zero.Denom(), one)
-	}
-
-	// 1a) a zero value remains zero independent of denominator
-	x := new(Rat)
-	x.Denom().Set(new(Int).Neg(b))
-	if x.Cmp(zero) != 0 {
-		t.Errorf("1a) got %s want %s", x, zero)
-	}
-
-	// 1b) a zero value may have a denominator != 0 and != 1
-	x.Num().Set(a)
-	qab := new(Rat).SetFrac(a, b)
-	if x.Cmp(qab) != 0 {
-		t.Errorf("1b) got %s want %s", x, qab)
-	}
-
-	// 2a) an integral value becomes a fraction depending on denominator
-	x.SetFrac64(10, 2)
-	x.Denom().SetInt64(3)
-	q53 := NewRat(5, 3)
-	if x.Cmp(q53) != 0 {
-		t.Errorf("2a) got %s want %s", x, q53)
-	}
-
-	// 2b) an integral value becomes a fraction depending on denominator
-	x = NewRat(10, 2)
-	x.Denom().SetInt64(3)
-	if x.Cmp(q53) != 0 {
-		t.Errorf("2b) got %s want %s", x, q53)
-	}
-
-	// 3) changing the numerator/denominator of a Rat changes the Rat
-	x.SetFrac(a, b)
-	a = x.Num()
-	b = x.Denom()
-	a.SetInt64(5)
-	b.SetInt64(3)
-	if x.Cmp(q53) != 0 {
-		t.Errorf("3) got %s want %s", x, q53)
-	}
-}
-
-// Test inputs to Rat.SetString.  The prefix "long:" causes the test
-// to be skipped in --test.short mode.  (The threshold is about 500us.)
-var float64inputs = []string{
-	// Constants plundered from strconv/testfp.txt.
-
-	// Table 1: Stress Inputs for Conversion to 53-bit Binary, < 1/2 ULP
-	"5e+125",
-	"69e+267",
-	"999e-026",
-	"7861e-034",
-	"75569e-254",
-	"928609e-261",
-	"9210917e+080",
-	"84863171e+114",
-	"653777767e+273",
-	"5232604057e-298",
-	"27235667517e-109",
-	"653532977297e-123",
-	"3142213164987e-294",
-	"46202199371337e-072",
-	"231010996856685e-073",
-	"9324754620109615e+212",
-	"78459735791271921e+049",
-	"272104041512242479e+200",
-	"6802601037806061975e+198",
-	"20505426358836677347e-221",
-	"836168422905420598437e-234",
-	"4891559871276714924261e+222",
-
-	// Table 2: Stress Inputs for Conversion to 53-bit Binary, > 1/2 ULP
-	"9e-265",
-	"85e-037",
-	"623e+100",
-	"3571e+263",
-	"81661e+153",
-	"920657e-023",
-	"4603285e-024",
-	"87575437e-309",
-	"245540327e+122",
-	"6138508175e+120",
-	"83356057653e+193",
-	"619534293513e+124",
-	"2335141086879e+218",
-	"36167929443327e-159",
-	"609610927149051e-255",
-	"3743626360493413e-165",
-	"94080055902682397e-242",
-	"899810892172646163e+283",
-	"7120190517612959703e+120",
-	"25188282901709339043e-252",
-	"308984926168550152811e-052",
-	"6372891218502368041059e+064",
-
-	// Table 14: Stress Inputs for Conversion to 24-bit Binary, <1/2 ULP
-	"5e-20",
-	"67e+14",
-	"985e+15",
-	"7693e-42",
-	"55895e-16",
-	"996622e-44",
-	"7038531e-32",
-	"60419369e-46",
-	"702990899e-20",
-	"6930161142e-48",
-	"25933168707e+13",
-	"596428896559e+20",
-
-	// Table 15: Stress Inputs for Conversion to 24-bit Binary, >1/2 ULP
-	"3e-23",
-	"57e+18",
-	"789e-35",
-	"2539e-18",
-	"76173e+28",
-	"887745e-11",
-	"5382571e-37",
-	"82381273e-35",
-	"750486563e-38",
-	"3752432815e-39",
-	"75224575729e-45",
-	"459926601011e+15",
-
-	// Constants plundered from strconv/atof_test.go.
-
-	"0",
-	"1",
-	"+1",
-	"1e23",
-	"1E23",
-	"100000000000000000000000",
-	"1e-100",
-	"123456700",
-	"99999999999999974834176",
-	"100000000000000000000001",
-	"100000000000000008388608",
-	"100000000000000016777215",
-	"100000000000000016777216",
-	"-1",
-	"-0.1",
-	"-0", // NB: exception made for this input
-	"1e-20",
-	"625e-3",
-
-	// largest float64
-	"1.7976931348623157e308",
-	"-1.7976931348623157e308",
-	// next float64 - too large
-	"1.7976931348623159e308",
-	"-1.7976931348623159e308",
-	// the border is ...158079
-	// borderline - okay
-	"1.7976931348623158e308",
-	"-1.7976931348623158e308",
-	// borderline - too large
-	"1.797693134862315808e308",
-	"-1.797693134862315808e308",
-
-	// a little too large
-	"1e308",
-	"2e308",
-	"1e309",
-
-	// way too large
-	"1e310",
-	"-1e310",
-	"1e400",
-	"-1e400",
-	"long:1e400000",
-	"long:-1e400000",
-
-	// denormalized
-	"1e-305",
-	"1e-306",
-	"1e-307",
-	"1e-308",
-	"1e-309",
-	"1e-310",
-	"1e-322",
-	// smallest denormal
-	"5e-324",
-	"4e-324",
-	"3e-324",
-	// too small
-	"2e-324",
-	// way too small
-	"1e-350",
-	"long:1e-400000",
-	// way too small, negative
-	"-1e-350",
-	"long:-1e-400000",
-
-	// try to overflow exponent
-	// [Disabled: too slow and memory-hungry with rationals.]
-	// "1e-4294967296",
-	// "1e+4294967296",
-	// "1e-18446744073709551616",
-	// "1e+18446744073709551616",
-
-	// http://www.exploringbinary.com/java-hangs-when-converting-2-2250738585072012e-308/
-	"2.2250738585072012e-308",
-	// http://www.exploringbinary.com/php-hangs-on-numeric-value-2-2250738585072011e-308/
-
-	"2.2250738585072011e-308",
-
-	// A very large number (initially wrongly parsed by the fast algorithm).
-	"4.630813248087435e+307",
-
-	// A different kind of very large number.
-	"22.222222222222222",
-	"long:2." + strings.Repeat("2", 4000) + "e+1",
-
-	// Exactly halfway between 1 and math.Nextafter(1, 2).
-	// Round to even (down).
-	"1.00000000000000011102230246251565404236316680908203125",
-	// Slightly lower; still round down.
-	"1.00000000000000011102230246251565404236316680908203124",
-	// Slightly higher; round up.
-	"1.00000000000000011102230246251565404236316680908203126",
-	// Slightly higher, but you have to read all the way to the end.
-	"long:1.00000000000000011102230246251565404236316680908203125" + strings.Repeat("0", 10000) + "1",
-
-	// Smallest denormal, 2^(-1022-52)
-	"4.940656458412465441765687928682213723651e-324",
-	// Half of smallest denormal, 2^(-1022-53)
-	"2.470328229206232720882843964341106861825e-324",
-	// A little more than the exact half of smallest denormal
-	// 2^-1075 + 2^-1100.  (Rounds to 1p-1074.)
-	"2.470328302827751011111470718709768633275e-324",
-	// The exact halfway between smallest normal and largest denormal:
-	// 2^-1022 - 2^-1075.  (Rounds to 2^-1022.)
-	"2.225073858507201136057409796709131975935e-308",
-
-	"1152921504606846975",  //   1<<60 - 1
-	"-1152921504606846975", // -(1<<60 - 1)
-	"1152921504606846977",  //   1<<60 + 1
-	"-1152921504606846977", // -(1<<60 + 1)
-
-	"1/3",
-}
-
-func TestFloat64SpecialCases(t *testing.T) {
-	for _, input := range float64inputs {
-		if strings.HasPrefix(input, "long:") {
-			if testing.Short() {
-				continue
-			}
-			input = input[len("long:"):]
-		}
-
-		r, ok := new(Rat).SetString(input)
-		if !ok {
-			t.Errorf("Rat.SetString(%q) failed", input)
-			continue
-		}
-		f, exact := r.Float64()
-
-		// 1. Check string -> Rat -> float64 conversions are
-		// consistent with strconv.ParseFloat.
-		// Skip this check if the input uses "a/b" rational syntax.
-		if !strings.Contains(input, "/") {
-			e, _ := strconv.ParseFloat(input, 64)
-
-			// Careful: negative Rats too small for
-			// float64 become -0, but Rat obviously cannot
-			// preserve the sign from SetString("-0").
-			switch {
-			case math.Float64bits(e) == math.Float64bits(f):
-				// Ok: bitwise equal.
-			case f == 0 && r.Num().BitLen() == 0:
-				// Ok: Rat(0) is equivalent to both +/- float64(0).
-			default:
-				t.Errorf("strconv.ParseFloat(%q) = %g (%b), want %g (%b); delta = %g", input, e, e, f, f, f-e)
-			}
-		}
-
-		if !isFinite(f) {
-			continue
-		}
-
-		// 2. Check f is best approximation to r.
-		if !checkIsBestApprox(t, f, r) {
-			// Append context information.
-			t.Errorf("(input was %q)", input)
-		}
-
-		// 3. Check f->R->f roundtrip is non-lossy.
-		checkNonLossyRoundtrip(t, f)
-
-		// 4. Check exactness using slow algorithm.
-		if wasExact := new(Rat).SetFloat64(f).Cmp(r) == 0; wasExact != exact {
-			t.Errorf("Rat.SetString(%q).Float64().exact = %t, want %t", input, exact, wasExact)
-		}
-	}
-}
-
-func TestFloat64Distribution(t *testing.T) {
-	// Generate a distribution of (sign, mantissa, exp) values
-	// broader than the float64 range, and check Rat.Float64()
-	// always picks the closest float64 approximation.
-	var add = []int64{
-		0,
-		1,
-		3,
-		5,
-		7,
-		9,
-		11,
-	}
-	var winc, einc = uint64(1), int(1) // soak test (~75s on x86-64)
-	if testing.Short() {
-		winc, einc = 10, 500 // quick test (~12ms on x86-64)
-	}
-
-	for _, sign := range "+-" {
-		for _, a := range add {
-			for wid := uint64(0); wid < 60; wid += winc {
-				b := int64(1<<wid + a)
-				if sign == '-' {
-					b = -b
-				}
-				for exp := -1100; exp < 1100; exp += einc {
-					num, den := NewInt(b), NewInt(1)
-					if exp > 0 {
-						num.Lsh(num, uint(exp))
-					} else {
-						den.Lsh(den, uint(-exp))
-					}
-					r := new(Rat).SetFrac(num, den)
-					f, _ := r.Float64()
-
-					if !checkIsBestApprox(t, f, r) {
-						// Append context information.
-						t.Errorf("(input was mantissa %#x, exp %d; f = %g (%b); f ~ %g; r = %v)",
-							b, exp, f, f, math.Ldexp(float64(b), exp), r)
-					}
-
-					checkNonLossyRoundtrip(t, f)
-				}
-			}
-		}
-	}
-}
-
-// TestFloat64NonFinite checks that SetFloat64 of a non-finite value
-// returns nil.
-func TestSetFloat64NonFinite(t *testing.T) {
-	for _, f := range []float64{math.NaN(), math.Inf(+1), math.Inf(-1)} {
-		var r Rat
-		if r2 := r.SetFloat64(f); r2 != nil {
-			t.Errorf("SetFloat64(%g) was %v, want nil", f, r2)
-		}
-	}
-}
-
-// checkNonLossyRoundtrip checks that a float->Rat->float roundtrip is
-// non-lossy for finite f.
-func checkNonLossyRoundtrip(t *testing.T, f float64) {
-	if !isFinite(f) {
-		return
-	}
-	r := new(Rat).SetFloat64(f)
-	if r == nil {
-		t.Errorf("Rat.SetFloat64(%g (%b)) == nil", f, f)
-		return
-	}
-	f2, exact := r.Float64()
-	if f != f2 || !exact {
-		t.Errorf("Rat.SetFloat64(%g).Float64() = %g (%b), %v, want %g (%b), %v; delta = %b",
-			f, f2, f2, exact, f, f, true, f2-f)
-	}
-}
-
-// delta returns the absolute difference between r and f.
-func delta(r *Rat, f float64) *Rat {
-	d := new(Rat).Sub(r, new(Rat).SetFloat64(f))
-	return d.Abs(d)
-}
-
-// checkIsBestApprox checks that f is the best possible float64
-// approximation of r.
-// Returns true on success.
-func checkIsBestApprox(t *testing.T, f float64, r *Rat) bool {
-	if math.Abs(f) >= math.MaxFloat64 {
-		// Cannot check +Inf, -Inf, nor the float next to them (MaxFloat64).
-		// But we have tests for these special cases.
-		return true
-	}
-
-	// r must be strictly between f0 and f1, the floats bracketing f.
-	f0 := math.Nextafter(f, math.Inf(-1))
-	f1 := math.Nextafter(f, math.Inf(+1))
-
-	// For f to be correct, r must be closer to f than to f0 or f1.
-	df := delta(r, f)
-	df0 := delta(r, f0)
-	df1 := delta(r, f1)
-	if df.Cmp(df0) > 0 {
-		t.Errorf("Rat(%v).Float64() = %g (%b), but previous float64 %g (%b) is closer", r, f, f, f0, f0)
-		return false
-	}
-	if df.Cmp(df1) > 0 {
-		t.Errorf("Rat(%v).Float64() = %g (%b), but next float64 %g (%b) is closer", r, f, f, f1, f1)
-		return false
-	}
-	if df.Cmp(df0) == 0 && !isEven(f) {
-		t.Errorf("Rat(%v).Float64() = %g (%b); halfway should have rounded to %g (%b) instead", r, f, f, f0, f0)
-		return false
-	}
-	if df.Cmp(df1) == 0 && !isEven(f) {
-		t.Errorf("Rat(%v).Float64() = %g (%b); halfway should have rounded to %g (%b) instead", r, f, f, f1, f1)
-		return false
-	}
-	return true
-}
-
-func isEven(f float64) bool { return math.Float64bits(f)&1 == 0 }
-
-func TestIsFinite(t *testing.T) {
-	finites := []float64{
-		1.0 / 3,
-		4891559871276714924261e+222,
-		math.MaxFloat64,
-		math.SmallestNonzeroFloat64,
-		-math.MaxFloat64,
-		-math.SmallestNonzeroFloat64,
-	}
-	for _, f := range finites {
-		if !isFinite(f) {
-			t.Errorf("!IsFinite(%g (%b))", f, f)
-		}
-	}
-	nonfinites := []float64{
-		math.NaN(),
-		math.Inf(-1),
-		math.Inf(+1),
-	}
-	for _, f := range nonfinites {
-		if isFinite(f) {
-			t.Errorf("IsFinite(%g, (%b))", f, f)
-		}
-	}
-}
diff --git a/src/pkg/math/dim_386.s b/src/pkg/math/dim_386.s
deleted file mode 100644
index f715114..0000000
--- a/src/pkg/math/dim_386.s
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2011 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../cmd/ld/textflag.h"
-
-TEXT ·Dim(SB),NOSPLIT,$0
-	JMP ·dim(SB)
-
-TEXT ·Max(SB),NOSPLIT,$0
-	JMP ·max(SB)
-
-TEXT ·Min(SB),NOSPLIT,$0
-	JMP ·min(SB)
diff --git a/src/pkg/math/dim_amd64.s b/src/pkg/math/dim_amd64.s
deleted file mode 100644
index 38423ef..0000000
--- a/src/pkg/math/dim_amd64.s
+++ /dev/null
@@ -1,144 +0,0 @@
-// Copyright 2010 The Go 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 "../../cmd/ld/textflag.h"
-
-#define PosInf 0x7FF0000000000000
-#define NaN    0x7FF8000000000001
-#define NegInf 0xFFF0000000000000
-
-// func Dim(x, y float64) float64
-TEXT ·Dim(SB),NOSPLIT,$0
-	// (+Inf, +Inf) special case
-	MOVQ    x+0(FP), BX
-	MOVQ    y+8(FP), CX
-	MOVQ    $PosInf, AX
-	CMPQ    AX, BX
-	JNE     dim2
-	CMPQ    AX, CX
-	JEQ     bothInf
-dim2:	// (-Inf, -Inf) special case
-	MOVQ    $NegInf, AX
-	CMPQ    AX, BX
-	JNE     dim3
-	CMPQ    AX, CX
-	JEQ     bothInf
-dim3:	// (NaN, x) or (x, NaN)
-	MOVQ    $~(1<<63), DX
-	MOVQ    $NaN, AX
-	ANDQ    DX, BX // x = |x|
-	CMPQ    AX, BX
-	JLE     isDimNaN
-	ANDQ    DX, CX // y = |y|
-	CMPQ    AX, CX
-	JLE     isDimNaN
-
-	MOVSD x+0(FP), X0
-	SUBSD y+8(FP), X0
-	MOVSD $(0.0), X1
-	MAXSD X1, X0
-	MOVSD X0, ret+16(FP)
-	RET
-bothInf: // Dim(-Inf, -Inf) or Dim(+Inf, +Inf)
-	MOVQ    $NaN, AX
-isDimNaN:
-	MOVQ    AX, ret+16(FP)
-	RET
-
-// func ·Max(x, y float64) float64
-TEXT ·Max(SB),NOSPLIT,$0
-	// +Inf special cases
-	MOVQ    $PosInf, AX
-	MOVQ    x+0(FP), R8
-	CMPQ    AX, R8
-	JEQ     isPosInf
-	MOVQ    y+8(FP), R9
-	CMPQ    AX, R9
-	JEQ     isPosInf
-	// NaN special cases
-	MOVQ    $~(1<<63), DX // bit mask
-	MOVQ    $NaN, AX
-	MOVQ    R8, BX
-	ANDQ    DX, BX // x = |x|
-	CMPQ    AX, BX
-	JLE     isMaxNaN
-	MOVQ    R9, CX
-	ANDQ    DX, CX // y = |y|
-	CMPQ    AX, CX
-	JLE     isMaxNaN
-	// ±0 special cases
-	ORQ     CX, BX
-	JEQ     isMaxZero
-
-	MOVQ    R8, X0
-	MOVQ    R9, X1
-	MAXSD   X1, X0
-	MOVSD   X0, ret+16(FP)
-	RET
-isMaxNaN: // return NaN
-isPosInf: // return +Inf
-	MOVQ    AX, ret+16(FP)
-	RET
-isMaxZero:
-	MOVQ    $(1<<63), AX // -0.0
-	CMPQ    AX, R8
-	JEQ     +3(PC)
-	MOVQ    R8, ret+16(FP) // return 0
-	RET
-	MOVQ    R9, ret+16(FP) // return other 0
-	RET
-
-/*
-	MOVQ    $0, AX
-	CMPQ    AX, R8
-	JNE     +3(PC)
-	MOVQ    R8, ret+16(FP) // return 0
-	RET
-	MOVQ    R9, ret+16(FP) // return other 0
-	RET
-*/
-
-// func Min(x, y float64) float64
-TEXT ·Min(SB),NOSPLIT,$0
-	// -Inf special cases
-	MOVQ    $NegInf, AX
-	MOVQ    x+0(FP), R8
-	CMPQ    AX, R8
-	JEQ     isNegInf
-	MOVQ    y+8(FP), R9
-	CMPQ    AX, R9
-	JEQ     isNegInf
-	// NaN special cases
-	MOVQ    $~(1<<63), DX
-	MOVQ    $NaN, AX
-	MOVQ    R8, BX
-	ANDQ    DX, BX // x = |x|
-	CMPQ    AX, BX
-	JLE     isMinNaN
-	MOVQ    R9, CX
-	ANDQ    DX, CX // y = |y|
-	CMPQ    AX, CX
-	JLE     isMinNaN
-	// ±0 special cases
-	ORQ     CX, BX
-	JEQ     isMinZero
-
-	MOVQ    R8, X0
-	MOVQ    R9, X1
-	MINSD   X1, X0
-	MOVSD X0, ret+16(FP)
-	RET
-isMinNaN: // return NaN
-isNegInf: // return -Inf
-	MOVQ    AX, ret+16(FP)
-	RET
-isMinZero:
-	MOVQ    $(1<<63), AX // -0.0
-	CMPQ    AX, R8
-	JEQ     +3(PC)
-	MOVQ    R9, ret+16(FP) // return other 0
-	RET
-	MOVQ    R8, ret+16(FP) // return -0
-	RET
-
diff --git a/src/pkg/math/dim_arm.s b/src/pkg/math/dim_arm.s
deleted file mode 100644
index 162f08c..0000000
--- a/src/pkg/math/dim_arm.s
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2011 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../cmd/ld/textflag.h"
-
-TEXT ·Dim(SB),NOSPLIT,$0
-	B ·dim(SB)
-
-TEXT ·Min(SB),NOSPLIT,$0
-	B ·min(SB)
-
-TEXT ·Max(SB),NOSPLIT,$0
-	B ·max(SB)
diff --git a/src/pkg/math/exp2_386.s b/src/pkg/math/exp2_386.s
deleted file mode 100644
index 71959d9..0000000
--- a/src/pkg/math/exp2_386.s
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2010 The Go 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 "../../cmd/ld/textflag.h"
-
-// func Exp2(x float64) float64
-TEXT ·Exp2(SB),NOSPLIT,$0
-// test bits for not-finite
-	MOVL    x_hi+4(FP), AX
-	ANDL    $0x7ff00000, AX
-	CMPL    AX, $0x7ff00000
-	JEQ     not_finite
-	FMOVD   x+0(FP), F0   // F0=x
-	FMOVD   F0, F1        // F0=x, F1=x
-	FRNDINT               // F0=int(x), F1=x
-	FSUBD   F0, F1        // F0=int(x), F1=x-int(x)
-	FXCHD   F0, F1        // F0=x-int(x), F1=int(x)
-	F2XM1                 // F0=2**(x-int(x))-1, F1=int(x)
-	FLD1                  // F0=1, F1=2**(x-int(x))-1, F2=int(x)
-	FADDDP  F0, F1        // F0=2**(x-int(x)), F1=int(x)
-	FSCALE                // F0=2**x, F1=int(x)
-	FMOVDP  F0, F1        // F0=2**x
-	FMOVDP  F0, ret+8(FP)
-	RET
-not_finite:
-// test bits for -Inf
-	MOVL    x_hi+4(FP), BX
-	MOVL    x_lo+0(FP), CX
-	CMPL    BX, $0xfff00000
-	JNE     not_neginf
-	CMPL    CX, $0
-	JNE     not_neginf
-	MOVL    $0, ret_lo+8(FP)
-	MOVL    $0, ret_hi+12(FP)
-	RET
-not_neginf:
-	MOVL    CX, ret_lo+8(FP)
-	MOVL    BX, ret_hi+12(FP)
-	RET
diff --git a/src/pkg/math/exp2_amd64.s b/src/pkg/math/exp2_amd64.s
deleted file mode 100644
index 77a53da..0000000
--- a/src/pkg/math/exp2_amd64.s
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright 2011 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../cmd/ld/textflag.h"
-
-TEXT ·Exp2(SB),NOSPLIT,$0
-	JMP ·exp2(SB)
diff --git a/src/pkg/math/exp2_arm.s b/src/pkg/math/exp2_arm.s
deleted file mode 100644
index fe51f25..0000000
--- a/src/pkg/math/exp2_arm.s
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright 2011 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../cmd/ld/textflag.h"
-
-TEXT ·Exp2(SB),NOSPLIT,$0
-	B ·exp2(SB)
diff --git a/src/pkg/math/exp_386.s b/src/pkg/math/exp_386.s
deleted file mode 100644
index af2d680..0000000
--- a/src/pkg/math/exp_386.s
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2010 The Go 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 "../../cmd/ld/textflag.h"
-
-// func Exp(x float64) float64
-TEXT ·Exp(SB),NOSPLIT,$0
-// test bits for not-finite
-	MOVL    x_hi+4(FP), AX
-	ANDL    $0x7ff00000, AX
-	CMPL    AX, $0x7ff00000
-	JEQ     not_finite
-	FLDL2E                // F0=log2(e)
-	FMULD   x+0(FP), F0   // F0=x*log2(e)
-	FMOVD   F0, F1        // F0=x*log2(e), F1=x*log2(e)
-	FRNDINT               // F0=int(x*log2(e)), F1=x*log2(e)
-	FSUBD   F0, F1        // F0=int(x*log2(e)), F1=x*log2(e)-int(x*log2(e))
-	FXCHD   F0, F1        // F0=x*log2(e)-int(x*log2(e)), F1=int(x*log2(e))
-	F2XM1                 // F0=2**(x*log2(e)-int(x*log2(e)))-1, F1=int(x*log2(e))
-	FLD1                  // F0=1, F1=2**(x*log2(e)-int(x*log2(e)))-1, F2=int(x*log2(e))
-	FADDDP  F0, F1        // F0=2**(x*log2(e)-int(x*log2(e))), F1=int(x*log2(e))
-	FSCALE                // F0=e**x, F1=int(x*log2(e))
-	FMOVDP  F0, F1        // F0=e**x
-	FMOVDP  F0, ret+8(FP)
-	RET
-not_finite:
-// test bits for -Inf
-	MOVL    x_hi+4(FP), BX
-	MOVL    x_lo+0(FP), CX
-	CMPL    BX, $0xfff00000
-	JNE     not_neginf
-	CMPL    CX, $0
-	JNE     not_neginf
-	FLDZ                  // F0=0
-	FMOVDP  F0, ret+8(FP)
-	RET
-not_neginf:
-	MOVL    CX, ret_lo+8(FP)
-	MOVL    BX, ret_hi+12(FP)
-	RET
diff --git a/src/pkg/math/exp_amd64.s b/src/pkg/math/exp_amd64.s
deleted file mode 100644
index 070b452..0000000
--- a/src/pkg/math/exp_amd64.s
+++ /dev/null
@@ -1,114 +0,0 @@
-// Copyright 2010 The Go 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 "../../cmd/ld/textflag.h"
-
-// The method is based on a paper by Naoki Shibata: "Efficient evaluation
-// methods of elementary functions suitable for SIMD computation", Proc.
-// of International Supercomputing Conference 2010 (ISC'10), pp. 25 -- 32
-// (May 2010). The paper is available at
-// http://www.springerlink.com/content/340228x165742104/
-//
-// The original code and the constants below are from the author's
-// implementation available at http://freshmeat.net/projects/sleef.
-// The README file says, "The software is in public domain.
-// You can use the software without any obligation."
-//
-// This code is a simplified version of the original.
-
-#define LN2 0.6931471805599453094172321214581766 // log_e(2)
-#define LOG2E 1.4426950408889634073599246810018920 // 1/LN2
-#define LN2U 0.69314718055966295651160180568695068359375 // upper half LN2
-#define LN2L 0.28235290563031577122588448175013436025525412068e-12 // lower half LN2
-#define T0 1.0
-#define T1 0.5
-#define T2 1.6666666666666666667e-1
-#define T3 4.1666666666666666667e-2
-#define T4 8.3333333333333333333e-3
-#define T5 1.3888888888888888889e-3
-#define T6 1.9841269841269841270e-4
-#define T7 2.4801587301587301587e-5
-#define PosInf 0x7FF0000000000000
-#define NegInf 0xFFF0000000000000
-
-// func Exp(x float64) float64
-TEXT ·Exp(SB),NOSPLIT,$0
-// test bits for not-finite
-	MOVQ    x+0(FP), BX
-	MOVQ    $~(1<<63), AX // sign bit mask
-	MOVQ    BX, DX
-	ANDQ    AX, DX
-	MOVQ    $PosInf, AX
-	CMPQ    AX, DX
-	JLE     notFinite
-	MOVQ    BX, X0
-	MOVSD   $LOG2E, X1
-	MULSD   X0, X1
-	CVTSD2SL X1, BX // BX = exponent
-	CVTSL2SD BX, X1
-	MOVSD   $LN2U, X2
-	MULSD   X1, X2
-	SUBSD   X2, X0
-	MOVSD   $LN2L, X2
-	MULSD   X1, X2
-	SUBSD   X2, X0
-	// reduce argument
-	MULSD   $0.0625, X0
-	// Taylor series evaluation
-	MOVSD   $T7, X1
-	MULSD   X0, X1
-	ADDSD   $T6, X1
-	MULSD   X0, X1
-	ADDSD   $T5, X1
-	MULSD   X0, X1
-	ADDSD   $T4, X1
-	MULSD   X0, X1
-	ADDSD   $T3, X1
-	MULSD   X0, X1
-	ADDSD   $T2, X1
-	MULSD   X0, X1
-	ADDSD   $T1, X1
-	MULSD   X0, X1
-	ADDSD   $T0, X1
-	MULSD   X1, X0
-	MOVSD   $2.0, X1
-	ADDSD   X0, X1
-	MULSD   X1, X0
-	MOVSD   $2.0, X1
-	ADDSD   X0, X1
-	MULSD   X1, X0
-	MOVSD   $2.0, X1
-	ADDSD   X0, X1
-	MULSD   X1, X0
-	MOVSD   $2.0, X1
-	ADDSD   X0, X1
-	MULSD   X1, X0
-	ADDSD   $1.0, X0
-	// return fr * 2**exponent
-	MOVL    $0x3FF, AX // bias
-	ADDL    AX, BX
-	JLE     underflow
-	CMPL    BX, $0x7FF
-	JGE     overflow
-	MOVL    $52, CX
-	SHLQ    CX, BX
-	MOVQ    BX, X1
-	MULSD   X1, X0
-	MOVSD   X0, ret+8(FP)
-	RET
-notFinite:
-	// test bits for -Inf
-	MOVQ    $NegInf, AX
-	CMPQ    AX, BX
-	JNE     notNegInf
-	// -Inf, return 0
-underflow: // return 0
-	MOVQ    $0, AX
-	MOVQ    AX, ret+8(FP)
-	RET
-overflow: // return +Inf
-	MOVQ    $PosInf, BX
-notNegInf: // NaN or +Inf, return x
-	MOVQ    BX, ret+8(FP)
-	RET
diff --git a/src/pkg/math/exp_arm.s b/src/pkg/math/exp_arm.s
deleted file mode 100644
index 130b502..0000000
--- a/src/pkg/math/exp_arm.s
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright 2011 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../cmd/ld/textflag.h"
-
-TEXT ·Exp(SB),NOSPLIT,$0
-	B ·exp(SB)
diff --git a/src/pkg/math/expm1_386.s b/src/pkg/math/expm1_386.s
deleted file mode 100644
index b268c58..0000000
--- a/src/pkg/math/expm1_386.s
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright 2010 The Go 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 "../../cmd/ld/textflag.h"
-
-// func Expm1(x float64) float64
-TEXT ·Expm1(SB),NOSPLIT,$0
-	FLDLN2               // F0=log(2) = 1/log2(e) ~ 0.693147
-	FMOVD   x+0(FP), F0  // F0=x, F1=1/log2(e)
-	FABS                 // F0=|x|, F1=1/log2(e) 
-	FUCOMPP F0, F1       // compare F0 to F1
-	FSTSW   AX
-	SAHF
-	JCC     use_exp      // jump if F0 >= F1
-	FLDL2E                // F0=log2(e)
-	FMULD   x+0(FP), F0   // F0=x*log2(e) (-1<F0<1)
-	F2XM1                 // F0=e**x-1 = 2**(x*log2(e))-1
-	FMOVDP  F0, ret+8(FP)
-	RET
-use_exp:
-// test bits for not-finite
-	MOVL    x_hi+4(FP), AX
-	ANDL    $0x7ff00000, AX
-	CMPL    AX, $0x7ff00000
-	JEQ     not_finite
-	FLDL2E                // F0=log2(e)
-	FMULD   x+0(FP), F0   // F0=x*log2(e)
-	FMOVD   F0, F1        // F0=x*log2(e), F1=x*log2(e)
-	FRNDINT               // F0=int(x*log2(e)), F1=x*log2(e)
-	FSUBD   F0, F1        // F0=int(x*log2(e)), F1=x*log2(e)-int(x*log2(e))
-	FXCHD   F0, F1        // F0=x*log2(e)-int(x*log2(e)), F1=int(x*log2(e))
-	F2XM1                 // F0=2**(x*log2(e)-int(x*log2(e)))-1, F1=int(x*log2(e))
-	FLD1                  // F0=1, F1=2**(x*log2(e)-int(x*log2(e)))-1, F2=int(x*log2(e))
-	FADDDP  F0, F1        // F0=2**(x*log2(e)-int(x*log2(e))), F1=int(x*log2(e))
-	FSCALE                // F0=e**x, F1=int(x*log2(e))
-	FMOVDP  F0, F1        // F0=e**x
-	FLD1                  // F0=1, F1=e**x
-	FSUBDP  F0, F1        // F0=e**x-1 
-	FMOVDP  F0, ret+8(FP)
-	RET
-not_finite:
-// test bits for -Inf
-	MOVL    x_hi+4(FP), BX
-	MOVL    x_lo+0(FP), CX
-	CMPL    BX, $0xfff00000
-	JNE     not_neginf
-	CMPL    CX, $0
-	JNE     not_neginf
-	FLD1                 // F0=1
-	FCHS                 // F0=-1
-	FMOVDP  F0, ret+8(FP)
-	RET
-not_neginf:
-	MOVL    CX, ret_lo+8(FP)
-	MOVL    BX, ret_hi+12(FP)
-	RET
diff --git a/src/pkg/math/expm1_amd64.s b/src/pkg/math/expm1_amd64.s
deleted file mode 100644
index 66a75b3..0000000
--- a/src/pkg/math/expm1_amd64.s
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright 2011 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../cmd/ld/textflag.h"
-
-TEXT ·Expm1(SB),NOSPLIT,$0
-	JMP ·expm1(SB)
diff --git a/src/pkg/math/expm1_arm.s b/src/pkg/math/expm1_arm.s
deleted file mode 100644
index 8387444..0000000
--- a/src/pkg/math/expm1_arm.s
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright 2011 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../cmd/ld/textflag.h"
-
-TEXT ·Expm1(SB),NOSPLIT,$0
-	B ·expm1(SB)
diff --git a/src/pkg/math/floor_386.s b/src/pkg/math/floor_386.s
deleted file mode 100644
index 37d5a45..0000000
--- a/src/pkg/math/floor_386.s
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2010 The Go 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 "../../cmd/ld/textflag.h"
-
-// func Ceil(x float64) float64
-TEXT ·Ceil(SB),NOSPLIT,$0
-	FMOVD   x+0(FP), F0  // F0=x
-	FSTCW   -2(SP)       // save old Control Word
-	MOVW    -2(SP), AX
-	ANDW    $0xf3ff, AX
-	ORW     $0x0800, AX  // Rounding Control set to +Inf
-	MOVW    AX, -4(SP)   // store new Control Word
-	FLDCW   -4(SP)       // load new Control Word
-	FRNDINT              // F0=Ceil(x)
-	FLDCW   -2(SP)       // load old Control Word
-	FMOVDP  F0, ret+8(FP)
-	RET
-
-// func Floor(x float64) float64
-TEXT ·Floor(SB),NOSPLIT,$0
-	FMOVD   x+0(FP), F0  // F0=x
-	FSTCW   -2(SP)       // save old Control Word
-	MOVW    -2(SP), AX
-	ANDW    $0xf3ff, AX
-	ORW     $0x0400, AX  // Rounding Control set to -Inf
-	MOVW    AX, -4(SP)   // store new Control Word
-	FLDCW   -4(SP)       // load new Control Word
-	FRNDINT              // F0=Floor(x)
-	FLDCW   -2(SP)       // load old Control Word
-	FMOVDP  F0, ret+8(FP)
-	RET
-
-// func Trunc(x float64) float64
-TEXT ·Trunc(SB),NOSPLIT,$0
-	FMOVD   x+0(FP), F0  // F0=x
-	FSTCW   -2(SP)       // save old Control Word
-	MOVW    -2(SP), AX
-	ORW     $0x0c00, AX  // Rounding Control set to truncate
-	MOVW    AX, -4(SP)   // store new Control Word
-	FLDCW   -4(SP)       // load new Control Word
-	FRNDINT              // F0=Trunc(x)
-	FLDCW   -2(SP)       // load old Control Word
-	FMOVDP  F0, ret+8(FP)
-	RET
diff --git a/src/pkg/math/floor_amd64.s b/src/pkg/math/floor_amd64.s
deleted file mode 100644
index 2fd31c4..0000000
--- a/src/pkg/math/floor_amd64.s
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright 2012 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../cmd/ld/textflag.h"
-
-#define Big		0x4330000000000000 // 2**52
-
-// func Floor(x float64) float64
-TEXT ·Floor(SB),NOSPLIT,$0
-	MOVQ	x+0(FP), AX
-	MOVQ	$~(1<<63), DX // sign bit mask
-	ANDQ	AX,DX // DX = |x|
-	SUBQ	$1,DX
-	MOVQ    $(Big - 1), CX // if |x| >= 2**52-1 or IsNaN(x) or |x| == 0, return x
-	CMPQ	DX,CX
-	JAE     isBig_floor
-	MOVQ	AX, X0 // X0 = x
-	CVTTSD2SQ	X0, AX
-	CVTSQ2SD	AX, X1 // X1 = float(int(x))
-	CMPSD	X1, X0, 1 // compare LT; X0 = 0xffffffffffffffff or 0
-	MOVSD	$(-1.0), X2
-	ANDPD	X2, X0 // if x < float(int(x)) {X0 = -1} else {X0 = 0}
-	ADDSD	X1, X0
-	MOVSD	X0, ret+8(FP)
-	RET
-isBig_floor:
-	MOVQ    AX, ret+8(FP) // return x
-	RET
-
-// func Ceil(x float64) float64
-TEXT ·Ceil(SB),NOSPLIT,$0
-	MOVQ	x+0(FP), AX
-	MOVQ	$~(1<<63), DX // sign bit mask
-	MOVQ	AX, BX // BX = copy of x
-	ANDQ    DX, BX // BX = |x|
-	MOVQ    $Big, CX // if |x| >= 2**52 or IsNaN(x), return x
-	CMPQ    BX, CX
-	JAE     isBig_ceil
-	MOVQ	AX, X0 // X0 = x
-	MOVQ	DX, X2 // X2 = sign bit mask
-	CVTTSD2SQ	X0, AX
-	ANDNPD	X0, X2 // X2 = sign
-	CVTSQ2SD	AX, X1	// X1 = float(int(x))
-	CMPSD	X1, X0, 2 // compare LE; X0 = 0xffffffffffffffff or 0
-	ORPD	X2, X1 // if X1 = 0.0, incorporate sign
-	MOVSD	$1.0, X3
-	ANDNPD	X3, X0
-	ORPD	X2, X0 // if float(int(x)) <= x {X0 = 1} else {X0 = -0}
-	ADDSD	X1, X0
-	MOVSD	X0, ret+8(FP)
-	RET
-isBig_ceil:
-	MOVQ	AX, ret+8(FP)
-	RET
-
-// func Trunc(x float64) float64
-TEXT ·Trunc(SB),NOSPLIT,$0
-	MOVQ	x+0(FP), AX
-	MOVQ	$~(1<<63), DX // sign bit mask
-	MOVQ	AX, BX // BX = copy of x
-	ANDQ    DX, BX // BX = |x|
-	MOVQ    $Big, CX // if |x| >= 2**52 or IsNaN(x), return x
-	CMPQ    BX, CX
-	JAE     isBig_trunc
-	MOVQ	AX, X0
-	MOVQ	DX, X2 // X2 = sign bit mask
-	CVTTSD2SQ	X0, AX
-	ANDNPD	X0, X2 // X2 = sign
-	CVTSQ2SD	AX, X0 // X0 = float(int(x))
-	ORPD	X2, X0 // if X0 = 0.0, incorporate sign
-	MOVSD	X0, ret+8(FP)
-	RET
-isBig_trunc:
-	MOVQ    AX, ret+8(FP) // return x
-	RET
diff --git a/src/pkg/math/floor_arm.s b/src/pkg/math/floor_arm.s
deleted file mode 100644
index cb3b98e..0000000
--- a/src/pkg/math/floor_arm.s
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2011 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../cmd/ld/textflag.h"
-
-TEXT ·Floor(SB),NOSPLIT,$0
-	B	·floor(SB)
-
-TEXT ·Ceil(SB),NOSPLIT,$0
-	B	·ceil(SB)
-
-TEXT ·Trunc(SB),NOSPLIT,$0
-	B	·trunc(SB)
diff --git a/src/pkg/math/frexp_386.s b/src/pkg/math/frexp_386.s
deleted file mode 100644
index c6d0a80..0000000
--- a/src/pkg/math/frexp_386.s
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2010 The Go 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 "../../cmd/ld/textflag.h"
-
-// func Frexp(f float64) (frac float64, exp int)
-TEXT ·Frexp(SB),NOSPLIT,$0
-	FMOVD   f+0(FP), F0   // F0=f
-	FXAM
-	FSTSW   AX
-	SAHF
-	JNP     nan_zero_inf
-	JCS     nan_zero_inf
-	FXTRACT               // F0=f (0<=f<1), F1=e
-	FMULD  $(0.5), F0     // F0=f (0.5<=f<1), F1=e
-	FMOVDP  F0, frac+8(FP)   // F0=e
-	FLD1                  // F0=1, F1=e
-	FADDDP  F0, F1        // F0=e+1
-	FMOVLP  F0, exp+16(FP)  // (int=int32)
-	RET
-nan_zero_inf:
-	FMOVDP  F0, frac+8(FP)   // F0=e
-	MOVL    $0, exp+16(FP)  // exp=0
-	RET
diff --git a/src/pkg/math/frexp_amd64.s b/src/pkg/math/frexp_amd64.s
deleted file mode 100644
index 03d1012..0000000
--- a/src/pkg/math/frexp_amd64.s
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright 2011 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../cmd/ld/textflag.h"
-
-TEXT ·Frexp(SB),NOSPLIT,$0
-	JMP ·frexp(SB)
diff --git a/src/pkg/math/frexp_arm.s b/src/pkg/math/frexp_arm.s
deleted file mode 100644
index 9d40ae4..0000000
--- a/src/pkg/math/frexp_arm.s
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright 2011 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../cmd/ld/textflag.h"
-
-TEXT ·Frexp(SB),NOSPLIT,$0
-	B ·frexp(SB)
diff --git a/src/pkg/math/hypot_386.s b/src/pkg/math/hypot_386.s
deleted file mode 100644
index eec1bf5..0000000
--- a/src/pkg/math/hypot_386.s
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2010 The Go 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 "../../cmd/ld/textflag.h"
-
-// func Hypot(p, q float64) float64
-TEXT ·Hypot(SB),NOSPLIT,$0
-// test bits for not-finite
-	MOVL    p_hi+4(FP), AX   // high word p
-	ANDL    $0x7ff00000, AX
-	CMPL    AX, $0x7ff00000
-	JEQ     not_finite
-	MOVL    q_hi+12(FP), AX   // high word q
-	ANDL    $0x7ff00000, AX
-	CMPL    AX, $0x7ff00000
-	JEQ     not_finite
-	FMOVD   p+0(FP), F0  // F0=p
-	FABS                 // F0=|p|
-	FMOVD   q+8(FP), F0  // F0=q, F1=|p|
-	FABS                 // F0=|q|, F1=|p|
-	FUCOMI  F0, F1       // compare F0 to F1
-	JCC     2(PC)        // jump if F0 >= F1
-	FXCHD   F0, F1       // F0=|p| (larger), F1=|q| (smaller)
-	FTST                 // compare F0 to 0
-	FSTSW	AX
-	ANDW    $0x4000, AX
-	JNE     10(PC)       // jump if F0 = 0
-	FXCHD   F0, F1       // F0=q (smaller), F1=p (larger)
-	FDIVD   F1, F0       // F0=q(=q/p), F1=p
-	FMULD   F0, F0       // F0=q*q, F1=p
-	FLD1                 // F0=1, F1=q*q, F2=p
-	FADDDP  F0, F1       // F0=1+q*q, F1=p
-	FSQRT                // F0=sqrt(1+q*q), F1=p
-	FMULDP  F0, F1       // F0=p*sqrt(1+q*q)
-	FMOVDP  F0, ret+16(FP)
-	RET
-	FMOVDP  F0, F1       // F0=0
-	FMOVDP  F0, ret+16(FP)
-	RET
-not_finite:
-// test bits for -Inf or +Inf
-	MOVL    p_hi+4(FP), AX  // high word p
-	ORL     p_lo+0(FP), AX  // low word p
-	ANDL    $0x7fffffff, AX
-	CMPL    AX, $0x7ff00000
-	JEQ     is_inf
-	MOVL    q_hi+12(FP), AX  // high word q
-	ORL     q_lo+8(FP), AX   // low word q
-	ANDL    $0x7fffffff, AX
-	CMPL    AX, $0x7ff00000
-	JEQ     is_inf
-	MOVL    $0x7ff80000, ret_hi+20(FP)  // return NaN = 0x7FF8000000000001
-	MOVL    $0x00000001, ret_lo+16(FP)
-	RET
-is_inf:
-	MOVL    AX, ret_hi+20(FP)  // return +Inf = 0x7FF0000000000000
-	MOVL    $0x00000000, ret_lo+16(FP)
-	RET
diff --git a/src/pkg/math/hypot_amd64.s b/src/pkg/math/hypot_amd64.s
deleted file mode 100644
index 5c0ff4d..0000000
--- a/src/pkg/math/hypot_amd64.s
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2010 The Go 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 "../../cmd/ld/textflag.h"
-
-#define PosInf 0x7FF0000000000000
-#define NaN 0x7FF8000000000001
-
-// func Hypot(p, q float64) float64
-TEXT ·Hypot(SB),NOSPLIT,$0
-	// test bits for special cases
-	MOVQ    p+0(FP), BX
-	MOVQ    $~(1<<63), AX
-	ANDQ    AX, BX // p = |p|
-	MOVQ    q+8(FP), CX
-	ANDQ    AX, CX // q = |q|
-	MOVQ    $PosInf, AX
-	CMPQ    AX, BX
-	JLE     isInfOrNaN
-	CMPQ    AX, CX
-	JLE     isInfOrNaN
-	// hypot = max * sqrt(1 + (min/max)**2)
-	MOVQ    BX, X0
-	MOVQ    CX, X1
-	ORQ     CX, BX
-	JEQ     isZero
-	MOVAPD  X0, X2
-	MAXSD   X1, X0
-	MINSD   X2, X1
-	DIVSD   X0, X1
-	MULSD   X1, X1
-	ADDSD   $1.0, X1
-	SQRTSD  X1, X1
-	MULSD   X1, X0
-	MOVSD   X0, ret+16(FP)
-	RET
-isInfOrNaN:
-	CMPQ    AX, BX
-	JEQ     isInf
-	CMPQ    AX, CX
-	JEQ     isInf
-	MOVQ    $NaN, AX
-	MOVQ    AX, ret+16(FP) // return NaN
-	RET
-isInf:
-	MOVQ    AX, ret+16(FP) // return +Inf
-	RET
-isZero:
-	MOVQ    $0, AX
-	MOVQ    AX, ret+16(FP) // return 0
-	RET
diff --git a/src/pkg/math/hypot_arm.s b/src/pkg/math/hypot_arm.s
deleted file mode 100644
index 2562aa8..0000000
--- a/src/pkg/math/hypot_arm.s
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright 2011 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../cmd/ld/textflag.h"
-
-TEXT ·Hypot(SB),NOSPLIT,$0
-	B ·hypot(SB)
diff --git a/src/pkg/math/ldexp_386.s b/src/pkg/math/ldexp_386.s
deleted file mode 100644
index baf377e..0000000
--- a/src/pkg/math/ldexp_386.s
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2010 The Go 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 "../../cmd/ld/textflag.h"
-
-// func Ldexp(frac float64, exp int) float64
-TEXT ·Ldexp(SB),NOSPLIT,$0
-	FMOVL   exp+8(FP), F0   // F0=exp
-	FMOVD   frac+0(FP), F0   // F0=frac, F1=e
-	FSCALE                // F0=x*2**e, F1=e
-	FMOVDP  F0, F1        // F0=x*2**e
-	FMOVDP  F0, ret+12(FP)
-	RET
diff --git a/src/pkg/math/ldexp_amd64.s b/src/pkg/math/ldexp_amd64.s
deleted file mode 100644
index c7fc226..0000000
--- a/src/pkg/math/ldexp_amd64.s
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright 2011 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../cmd/ld/textflag.h"
-
-TEXT ·Ldexp(SB),NOSPLIT,$0
-	JMP ·ldexp(SB)
diff --git a/src/pkg/math/ldexp_arm.s b/src/pkg/math/ldexp_arm.s
deleted file mode 100644
index 16744ea..0000000
--- a/src/pkg/math/ldexp_arm.s
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright 2011 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../cmd/ld/textflag.h"
-
-TEXT ·Ldexp(SB),NOSPLIT,$0
-	B ·ldexp(SB)
diff --git a/src/pkg/math/log10_386.s b/src/pkg/math/log10_386.s
deleted file mode 100644
index 4ae069d..0000000
--- a/src/pkg/math/log10_386.s
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2010 The Go 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 "../../cmd/ld/textflag.h"
-
-// func Log10(x float64) float64
-TEXT ·Log10(SB),NOSPLIT,$0
-	FLDLG2               // F0=log10(2)
-	FMOVD   x+0(FP), F0  // F0=x, F1=log10(2)
-	FYL2X                // F0=log10(x)=log2(x)*log10(2)
-	FMOVDP  F0, ret+8(FP)
-	RET
-
-// func Log2(x float64) float64
-TEXT ·Log2(SB),NOSPLIT,$0
-	FLD1                 // F0=1
-	FMOVD   x+0(FP), F0  // F0=x, F1=1
-	FYL2X                // F0=log2(x)
-	FMOVDP  F0, ret+8(FP)
-	RET
diff --git a/src/pkg/math/log10_amd64.s b/src/pkg/math/log10_amd64.s
deleted file mode 100644
index b9ae832..0000000
--- a/src/pkg/math/log10_amd64.s
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2011 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../cmd/ld/textflag.h"
-
-TEXT ·Log10(SB),NOSPLIT,$0
-	JMP ·log10(SB)
-
-TEXT ·Log2(SB),NOSPLIT,$0
-	JMP ·log2(SB)
diff --git a/src/pkg/math/log10_arm.s b/src/pkg/math/log10_arm.s
deleted file mode 100644
index fa7580f..0000000
--- a/src/pkg/math/log10_arm.s
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2011 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../cmd/ld/textflag.h"
-
-TEXT ·Log10(SB),NOSPLIT,$0
-	B ·log10(SB)
-
-TEXT ·Log2(SB),NOSPLIT,$0
-	B ·log2(SB)
diff --git a/src/pkg/math/log1p_386.s b/src/pkg/math/log1p_386.s
deleted file mode 100644
index 3b30fd5..0000000
--- a/src/pkg/math/log1p_386.s
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2010 The Go 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 "../../cmd/ld/textflag.h"
-
-// func Log1p(x float64) float64
-TEXT ·Log1p(SB),NOSPLIT,$0
-	FMOVD   $(2.928932188134524e-01), F0
-	FMOVD   x+0(FP), F0  // F0=x, F1=1-sqrt(2)/2 = 0.29289321881345247559915564
-	FABS                 // F0=|x|, F1=1-sqrt(2)/2
-	FUCOMPP F0, F1       // compare F0 to F1
-	FSTSW   AX
-	FLDLN2               // F0=log(2)
-	ANDW    $0x0100, AX
-	JEQ     use_fyl2x    // jump if F0 >= F1
-	FMOVD   x+0(FP), F0  // F0=x, F1=log(2)
-	FYL2XP1              // F0=log(1+x)=log2(1+x)*log(2)
-	FMOVDP  F0, ret+8(FP)
-	RET
-use_fyl2x:
-	FLD1                 // F0=1, F2=log(2)
-	FADDD   x+0(FP), F0  // F0=1+x, F1=log(2)
-	FYL2X                // F0=log(1+x)=log2(1+x)*log(2)
-	FMOVDP  F0, ret+8(FP)
-	RET
-
diff --git a/src/pkg/math/log1p_amd64.s b/src/pkg/math/log1p_amd64.s
deleted file mode 100644
index 48c24f4..0000000
--- a/src/pkg/math/log1p_amd64.s
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright 2011 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../cmd/ld/textflag.h"
-
-TEXT ·Log1p(SB),NOSPLIT,$0
-	JMP ·log1p(SB)
diff --git a/src/pkg/math/log1p_arm.s b/src/pkg/math/log1p_arm.s
deleted file mode 100644
index fd2740d..0000000
--- a/src/pkg/math/log1p_arm.s
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright 2011 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../cmd/ld/textflag.h"
-
-TEXT ·Log1p(SB),NOSPLIT,$0
-	B ·log1p(SB)
diff --git a/src/pkg/math/log_386.s b/src/pkg/math/log_386.s
deleted file mode 100644
index 21a0633..0000000
--- a/src/pkg/math/log_386.s
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2010 The Go 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 "../../cmd/ld/textflag.h"
-
-// func Log(x float64) float64
-TEXT ·Log(SB),NOSPLIT,$0
-	FLDLN2               // F0=log(2)
-	FMOVD   x+0(FP), F0  // F0=x, F1=log(2)
-	FYL2X                // F0=log(x)=log2(x)*log(2)
-	FMOVDP  F0, ret+8(FP)
-	RET
diff --git a/src/pkg/math/log_amd64.s b/src/pkg/math/log_amd64.s
deleted file mode 100644
index dffc5ae..0000000
--- a/src/pkg/math/log_amd64.s
+++ /dev/null
@@ -1,111 +0,0 @@
-// Copyright 2010 The Go 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 "../../cmd/ld/textflag.h"
-
-#define HSqrt2 7.07106781186547524401e-01 // sqrt(2)/2
-#define Ln2Hi  6.93147180369123816490e-01 // 0x3fe62e42fee00000
-#define Ln2Lo  1.90821492927058770002e-10 // 0x3dea39ef35793c76
-#define L1     6.666666666666735130e-01   // 0x3FE5555555555593
-#define L2     3.999999999940941908e-01   // 0x3FD999999997FA04
-#define L3     2.857142874366239149e-01   // 0x3FD2492494229359
-#define L4     2.222219843214978396e-01   // 0x3FCC71C51D8E78AF
-#define L5     1.818357216161805012e-01   // 0x3FC7466496CB03DE
-#define L6     1.531383769920937332e-01   // 0x3FC39A09D078C69F
-#define L7     1.479819860511658591e-01   // 0x3FC2F112DF3E5244
-#define NaN    0x7FF8000000000001
-#define NegInf 0xFFF0000000000000
-#define PosInf 0x7FF0000000000000
-
-// func Log(x float64) float64
-TEXT ·Log(SB),NOSPLIT,$0
-	// test bits for special cases
-	MOVQ    x+0(FP), BX
-	MOVQ    $~(1<<63), AX // sign bit mask
-	ANDQ    BX, AX
-	JEQ     isZero
-	MOVQ    $0, AX
-	CMPQ    AX, BX
-	JGT     isNegative
-	MOVQ    $PosInf, AX
-	CMPQ    AX, BX
-	JLE     isInfOrNaN
-	// f1, ki := math.Frexp(x); k := float64(ki)
-	MOVQ    BX, X0
-	MOVQ    $0x000FFFFFFFFFFFFF, AX
-	MOVQ    AX, X2
-	ANDPD   X0, X2
-	MOVSD   $0.5, X0 // 0x3FE0000000000000
-	ORPD    X0, X2 // X2= f1
-	SHRQ    $52, BX
-	ANDL    $0x7FF, BX
-	SUBL    $0x3FE, BX
-	CVTSL2SD BX, X1 // x1= k, x2= f1
-	// if f1 < math.Sqrt2/2 { k -= 1; f1 *= 2 }
-	MOVSD   $HSqrt2, X0 // x0= 0.7071, x1= k, x2= f1
-	CMPSD   X2, X0, 5 // cmpnlt; x0= 0 or ^0, x1= k, x2 = f1
-	MOVSD   $1.0, X3 // x0= 0 or ^0, x1= k, x2 = f1, x3= 1
-	ANDPD   X0, X3 // x0= 0 or ^0, x1= k, x2 = f1, x3= 0 or 1
-	SUBSD   X3, X1 // x0= 0 or ^0, x1= k, x2 = f1, x3= 0 or 1
-	MOVSD   $1.0, X0 // x0= 1, x1= k, x2= f1, x3= 0 or 1
-	ADDSD   X0, X3 // x0= 1, x1= k, x2= f1, x3= 1 or 2
-	MULSD   X3, X2 // x0= 1, x1= k, x2= f1
-	// f := f1 - 1
-	SUBSD   X0, X2 // x1= k, x2= f
-	// s := f / (2 + f)
-	MOVSD   $2.0, X0
-	ADDSD   X2, X0
-	MOVAPD  X2, X3
-	DIVSD   X0, X3 // x1=k, x2= f, x3= s
-	// s2 := s * s
-	MOVAPD  X3, X4 // x1= k, x2= f, x3= s
-	MULSD   X4, X4 // x1= k, x2= f, x3= s, x4= s2
-	// s4 := s2 * s2
-	MOVAPD  X4, X5 // x1= k, x2= f, x3= s, x4= s2
-	MULSD   X5, X5 // x1= k, x2= f, x3= s, x4= s2, x5= s4
-	// t1 := s2 * (L1 + s4*(L3+s4*(L5+s4*L7)))
-	MOVSD   $L7, X6
-	MULSD   X5, X6
-	ADDSD   $L5, X6
-	MULSD   X5, X6
-	ADDSD   $L3, X6
-	MULSD   X5, X6
-	ADDSD   $L1, X6
-	MULSD   X6, X4 // x1= k, x2= f, x3= s, x4= t1, x5= s4
-	// t2 := s4 * (L2 + s4*(L4+s4*L6))
-	MOVSD   $L6, X6
-	MULSD   X5, X6
-	ADDSD   $L4, X6
-	MULSD   X5, X6
-	ADDSD   $L2, X6
-	MULSD   X6, X5 // x1= k, x2= f, x3= s, x4= t1, x5= t2
-	// R := t1 + t2
-	ADDSD   X5, X4 // x1= k, x2= f, x3= s, x4= R
-	// hfsq := 0.5 * f * f
-	MOVSD   $0.5, X0
-	MULSD   X2, X0
-	MULSD   X2, X0 // x0= hfsq, x1= k, x2= f, x3= s, x4= R
-	// return k*Ln2Hi - ((hfsq - (s*(hfsq+R) + k*Ln2Lo)) - f)
-	ADDSD   X0, X4 // x0= hfsq, x1= k, x2= f, x3= s, x4= hfsq+R
-	MULSD   X4, X3 // x0= hfsq, x1= k, x2= f, x3= s*(hfsq+R)
-	MOVSD   $Ln2Lo, X4
-	MULSD   X1, X4 // x4= k*Ln2Lo
-	ADDSD   X4, X3 // x0= hfsq, x1= k, x2= f, x3= s*(hfsq+R)+k*Ln2Lo
-	SUBSD   X3, X0 // x0= hfsq-(s*(hfsq+R)+k*Ln2Lo), x1= k, x2= f
-	SUBSD   X2, X0 // x0= (hfsq-(s*(hfsq+R)+k*Ln2Lo))-f, x1= k
-	MULSD   $Ln2Hi, X1 // x0= (hfsq-(s*(hfsq+R)+k*Ln2Lo))-f, x1= k*Ln2Hi
-	SUBSD   X0, X1 // x1= k*Ln2Hi-((hfsq-(s*(hfsq+R)+k*Ln2Lo))-f)
-  	MOVSD   X1, ret+8(FP)
-	RET
-isInfOrNaN:
-	MOVQ    BX, ret+8(FP) // +Inf or NaN, return x
-	RET
-isNegative:
-	MOVQ    $NaN, AX
-	MOVQ    AX, ret+8(FP) // return NaN
-	RET
-isZero:
-	MOVQ    $NegInf, AX
-	MOVQ    AX, ret+8(FP) // return -Inf
-	RET
diff --git a/src/pkg/math/log_arm.s b/src/pkg/math/log_arm.s
deleted file mode 100644
index 28448ae..0000000
--- a/src/pkg/math/log_arm.s
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright 2011 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../cmd/ld/textflag.h"
-
-TEXT ·Log(SB),NOSPLIT,$0
-	B ·log(SB)
diff --git a/src/pkg/math/mod_386.s b/src/pkg/math/mod_386.s
deleted file mode 100644
index 9b3b6bd..0000000
--- a/src/pkg/math/mod_386.s
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2010 The Go 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 "../../cmd/ld/textflag.h"
-
-// func Mod(x, y float64) float64
-TEXT ·Mod(SB),NOSPLIT,$0
-	FMOVD   y+8(FP), F0  // F0=y
-	FMOVD   x+0(FP), F0  // F0=x, F1=y
-	FPREM                // F0=reduced_x, F1=y
-	FSTSW   AX           // AX=status word
-	ANDW    $0x0400, AX
-	JNE     -3(PC)       // jump if reduction incomplete
-	FMOVDP  F0, F1       // F0=x-q*y
-	FMOVDP  F0, ret+16(FP)
-	RET
diff --git a/src/pkg/math/mod_amd64.s b/src/pkg/math/mod_amd64.s
deleted file mode 100644
index bef83fc..0000000
--- a/src/pkg/math/mod_amd64.s
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright 2011 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../cmd/ld/textflag.h"
-
-TEXT ·Mod(SB),NOSPLIT,$0
-	JMP ·mod(SB)
diff --git a/src/pkg/math/mod_arm.s b/src/pkg/math/mod_arm.s
deleted file mode 100644
index 1f51588..0000000
--- a/src/pkg/math/mod_arm.s
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright 2011 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../cmd/ld/textflag.h"
-
-TEXT ·Mod(SB),NOSPLIT,$0
-	B ·mod(SB)
diff --git a/src/pkg/math/modf_386.s b/src/pkg/math/modf_386.s
deleted file mode 100644
index 07a0dc5..0000000
--- a/src/pkg/math/modf_386.s
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2010 The Go 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 "../../cmd/ld/textflag.h"
-
-// func Modf(f float64) (int float64, frac float64)
-TEXT ·Modf(SB),NOSPLIT,$0
-	FMOVD   f+0(FP), F0  // F0=f
-	FMOVD   F0, F1       // F0=f, F1=f
-	FSTCW   -2(SP)       // save old Control Word
-	MOVW    -2(SP), AX
-	ORW     $0x0c00, AX  // Rounding Control set to truncate
-	MOVW    AX, -4(SP)   // store new Control Word
-	FLDCW   -4(SP)       // load new Control Word
-	FRNDINT              // F0=trunc(f), F1=f
-	FLDCW   -2(SP)       // load old Control Word
-	FSUBD   F0, F1       // F0=trunc(f), F1=f-trunc(f)
-	FMOVDP  F0, int+8(FP)  // F0=f-trunc(f)
-	FMOVDP  F0, frac+16(FP)
-	RET
diff --git a/src/pkg/math/modf_amd64.s b/src/pkg/math/modf_amd64.s
deleted file mode 100644
index 05feb4b..0000000
--- a/src/pkg/math/modf_amd64.s
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright 2011 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../cmd/ld/textflag.h"
-
-TEXT ·Modf(SB),NOSPLIT,$0
-	JMP ·modf(SB)
diff --git a/src/pkg/math/modf_arm.s b/src/pkg/math/modf_arm.s
deleted file mode 100644
index e6bd26d..0000000
--- a/src/pkg/math/modf_arm.s
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright 2011 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../cmd/ld/textflag.h"
-
-TEXT ·Modf(SB),NOSPLIT,$0
-	B ·modf(SB)
diff --git a/src/pkg/math/nextafter.go b/src/pkg/math/nextafter.go
deleted file mode 100644
index 7c4b5bc..0000000
--- a/src/pkg/math/nextafter.go
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package math
-
-// Nextafter returns the next representable value after x towards y.
-// If x == y, then x is returned.
-//
-// Special cases are:
-//      Nextafter(NaN, y) = NaN
-//      Nextafter(x, NaN) = NaN
-func Nextafter(x, y float64) (r float64) {
-	switch {
-	case IsNaN(x) || IsNaN(y): // special case
-		r = NaN()
-	case x == y:
-		r = x
-	case x == 0:
-		r = Copysign(Float64frombits(1), y)
-	case (y > x) == (x > 0):
-		r = Float64frombits(Float64bits(x) + 1)
-	default:
-		r = Float64frombits(Float64bits(x) - 1)
-	}
-	return
-}
diff --git a/src/pkg/math/remainder_386.s b/src/pkg/math/remainder_386.s
deleted file mode 100644
index bbe13a0..0000000
--- a/src/pkg/math/remainder_386.s
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2010 The Go 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 "../../cmd/ld/textflag.h"
-
-// func Remainder(x, y float64) float64
-TEXT ·Remainder(SB),NOSPLIT,$0
-	FMOVD   y+8(FP), F0  // F0=y
-	FMOVD   x+0(FP), F0  // F0=x, F1=y
-	FPREM1               // F0=reduced_x, F1=y
-	FSTSW   AX           // AX=status word
-	ANDW    $0x0400, AX
-	JNE     -3(PC)       // jump if reduction incomplete
-	FMOVDP  F0, F1       // F0=x-q*y
-	FMOVDP  F0, ret+16(FP)
-	RET
diff --git a/src/pkg/math/remainder_amd64.s b/src/pkg/math/remainder_amd64.s
deleted file mode 100644
index e5e23c7..0000000
--- a/src/pkg/math/remainder_amd64.s
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright 2011 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../cmd/ld/textflag.h"
-
-TEXT ·Remainder(SB),NOSPLIT,$0
-	JMP ·remainder(SB)
diff --git a/src/pkg/math/remainder_arm.s b/src/pkg/math/remainder_arm.s
deleted file mode 100644
index 8728afe..0000000
--- a/src/pkg/math/remainder_arm.s
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright 2011 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../cmd/ld/textflag.h"
-
-TEXT ·Remainder(SB),NOSPLIT,$0
-	B ·remainder(SB)
diff --git a/src/pkg/math/sin_386.s b/src/pkg/math/sin_386.s
deleted file mode 100644
index 09271c0..0000000
--- a/src/pkg/math/sin_386.s
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2009 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../cmd/ld/textflag.h"
-
-// func Cos(x float64) float64
-TEXT ·Cos(SB),NOSPLIT,$0
-	FMOVD   x+0(FP), F0  // F0=x
-	FCOS                 // F0=cos(x) if -2**63 < x < 2**63
-	FSTSW   AX           // AX=status word
-	ANDW    $0x0400, AX
-	JNE     3(PC)        // jump if x outside range
-	FMOVDP  F0, ret+8(FP)
-	RET
-	FLDPI                // F0=Pi, F1=x
-	FADDD   F0, F0       // F0=2*Pi, F1=x
-	FXCHD   F0, F1       // F0=x, F1=2*Pi
-	FPREM1               // F0=reduced_x, F1=2*Pi
-	FSTSW   AX           // AX=status word
-	ANDW    $0x0400, AX
-	JNE     -3(PC)       // jump if reduction incomplete
-	FMOVDP  F0, F1       // F0=reduced_x
-	FCOS                 // F0=cos(reduced_x)
-	FMOVDP  F0, ret+8(FP)
-	RET
-	
-// func Sin(x float64) float64
-TEXT ·Sin(SB),NOSPLIT,$0
-	FMOVD   x+0(FP), F0  // F0=x
-	FSIN                 // F0=sin(x) if -2**63 < x < 2**63
-	FSTSW   AX           // AX=status word
-	ANDW    $0x0400, AX
-	JNE     3(PC)        // jump if x outside range
-	FMOVDP  F0, ret+8(FP)
-	RET
-	FLDPI                // F0=Pi, F1=x
-	FADDD   F0, F0       // F0=2*Pi, F1=x
-	FXCHD   F0, F1       // F0=x, F1=2*Pi
-	FPREM1               // F0=reduced_x, F1=2*Pi
-	FSTSW   AX           // AX=status word
-	ANDW    $0x0400, AX
-	JNE     -3(PC)       // jump if reduction incomplete
-	FMOVDP  F0, F1       // F0=reduced_x
-	FSIN                 // F0=sin(reduced_x)
-	FMOVDP  F0, ret+8(FP)
-	RET
diff --git a/src/pkg/math/sin_amd64.s b/src/pkg/math/sin_amd64.s
deleted file mode 100644
index 008bf4b..0000000
--- a/src/pkg/math/sin_amd64.s
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2010 The Go 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 "../../cmd/ld/textflag.h"
-
-TEXT ·Sin(SB),NOSPLIT,$0
-	JMP	·sin(SB)
-
-TEXT ·Cos(SB),NOSPLIT,$0
-	JMP	·cos(SB)
diff --git a/src/pkg/math/sin_arm.s b/src/pkg/math/sin_arm.s
deleted file mode 100644
index a057b4f..0000000
--- a/src/pkg/math/sin_arm.s
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2010 The Go 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 "../../cmd/ld/textflag.h"
-
-TEXT ·Sin(SB),NOSPLIT,$0
-	B	·sin(SB)
-
-TEXT ·Cos(SB),NOSPLIT,$0
-	B	·cos(SB)
diff --git a/src/pkg/math/sincos_386.s b/src/pkg/math/sincos_386.s
deleted file mode 100644
index bf964b1..0000000
--- a/src/pkg/math/sincos_386.s
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2010 The Go 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 "../../cmd/ld/textflag.h"
-
-// func Sincos(x float64) (sin, cos float64)
-TEXT ·Sincos(SB),NOSPLIT,$0
-	FMOVD   x+0(FP), F0  // F0=x
-	FSINCOS              // F0=cos(x), F1=sin(x) if -2**63 < x < 2**63
-	FSTSW   AX           // AX=status word
-	ANDW    $0x0400, AX
-	JNE     4(PC)        // jump if x outside range
-	FMOVDP  F0, cos+16(FP) // F0=sin(x)
-	FMOVDP  F0, sin+8(FP)
-	RET
-	FLDPI                // F0=Pi, F1=x
-	FADDD   F0, F0       // F0=2*Pi, F1=x
-	FXCHD   F0, F1       // F0=x, F1=2*Pi
-	FPREM1               // F0=reduced_x, F1=2*Pi
-	FSTSW   AX           // AX=status word
-	ANDW    $0x0400, AX
-	JNE     -3(PC)       // jump if reduction incomplete
-	FMOVDP  F0, F1       // F0=reduced_x
-	FSINCOS              // F0=cos(reduced_x), F1=sin(reduced_x)
-	FMOVDP  F0, cos+16(FP) // F0=sin(reduced_x)
-	FMOVDP  F0, sin+8(FP)
-	RET
diff --git a/src/pkg/math/sincos_amd64.s b/src/pkg/math/sincos_amd64.s
deleted file mode 100644
index bccc1ad..0000000
--- a/src/pkg/math/sincos_amd64.s
+++ /dev/null
@@ -1,145 +0,0 @@
-// Copyright 2010 The Go 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 "../../cmd/ld/textflag.h"
-
-// The method is based on a paper by Naoki Shibata: "Efficient evaluation
-// methods of elementary functions suitable for SIMD computation", Proc.
-// of International Supercomputing Conference 2010 (ISC'10), pp. 25 -- 32
-// (May 2010). The paper is available at
-// http://www.springerlink.com/content/340228x165742104/
-//
-// The original code and the constants below are from the author's
-// implementation available at http://freshmeat.net/projects/sleef.
-// The README file says, "The software is in public domain.
-// You can use the software without any obligation."
-//
-// This code is a simplified version of the original.  The CMPSD
-// instruction, not generated by the compiler, eliminates jumps in the
-// body of the calculation.
-
-#define PosOne 0x3FF0000000000000
-#define PosInf 0x7FF0000000000000
-#define NaN    0x7FF8000000000001
-#define PI4A 0.7853981554508209228515625 // pi/4 split into three parts
-#define PI4B 0.794662735614792836713604629039764404296875e-8
-#define PI4C 0.306161699786838294306516483068750264552437361480769e-16
-#define M4PI 1.273239544735162542821171882678754627704620361328125 // 4/pi
-#define T0 1.0
-#define T1 -8.33333333333333333333333e-02 // (-1.0/12)
-#define T2 2.77777777777777777777778e-03 // (+1.0/360)
-#define T3 -4.96031746031746031746032e-05 // (-1.0/20160)
-#define T4 5.51146384479717813051146e-07 // (+1.0/1814400)
-
-// func Sincos(d float64) (sin, cos float64)
-TEXT ·Sincos(SB),NOSPLIT,$0
-	// test for special cases
-	MOVQ    $~(1<<63), DX // sign bit mask
-	MOVQ    x+0(FP), BX
-	ANDQ    BX, DX
-	JEQ     isZero
-	MOVQ    $PosInf, AX
-	CMPQ    AX, DX
-	JLE     isInfOrNaN
-	// Reduce argument
-	MOVQ    BX, X7 // x7= d
-	MOVQ    DX, X0 // x0= |d|
-	MOVSD   $M4PI, X2
-	MULSD   X0, X2
-	CVTTSD2SQ X2, BX // bx= q
-	MOVQ    $1, AX
-	ANDQ    BX, AX
-	ADDQ    BX, AX
-	CVTSQ2SD AX, X2
-	MOVSD   $PI4A, X3
-	MULSD   X2, X3
-	SUBSD   X3, X0
-	MOVSD   $PI4B, X3
-	MULSD   X2, X3
-	SUBSD   X3, X0
-	MOVSD   $PI4C, X3
-	MULSD   X2, X3
-	SUBSD   X3, X0
-	MULSD   $0.125, X0 // x0= x, x7= d, bx= q
-	// Evaluate Taylor series
-	MULSD   X0, X0
-	MOVSD   $T4, X2
-	MULSD   X0, X2
-	ADDSD   $T3, X2
-	MULSD   X0, X2
-	ADDSD   $T2, X2
-	MULSD   X0, X2
-	ADDSD   $T1, X2
-	MULSD   X0, X2
-	ADDSD   $T0, X2
-	MULSD   X2, X0 // x0= x, x7= d, bx= q
-	// Apply double angle formula
-	MOVSD   $4.0, X2
-	SUBSD   X0, X2
-	MULSD   X2, X0
-	MOVSD   $4.0, X2
-	SUBSD   X0, X2
-	MULSD   X2, X0
-	MOVSD   $4.0, X2
-	SUBSD   X0, X2
-	MULSD   X2, X0
-	MULSD   $0.5, X0 // x0= x, x7= d, bx= q
-	// sin = sqrt((2 - x) * x)
-	MOVSD   $2.0, X2
-	SUBSD   X0, X2
-	MULSD   X0, X2
-	SQRTSD  X2, X2 // x0= x, x2= z, x7= d, bx= q
-	// cos = 1 - x
-	MOVSD   $1.0, X1
-	SUBSD   X0, X1 // x1= x, x2= z, x7= d, bx= q
-	// if ((q + 1) & 2) != 0 { sin, cos = cos, sin }
-	MOVQ    $1, DX
-	ADDQ    BX, DX
-	MOVQ    $2, AX
-	ANDQ    AX, DX
-	MOVQ    DX, X0
-	MOVSD   $0.0, X3
-	CMPSD   X0, X3, 0 // cmpeq; x1= x, x2= z, x3 = y, x7= d, bx= q
-	// sin = (y & z) | (^y & x)
-	MOVAPD  X2, X0
-	ANDPD   X3, X0 // x0= sin
-	MOVAPD  X3, X4
-	ANDNPD  X1, X4
-	ORPD    X4, X0 // x0= sin, x1= x, x2= z, x3= y, x7= d, bx= q
-	// cos = (y & x) | (^y & z)
-	ANDPD   X3, X1 // x1= cos
-	ANDNPD  X2, X3
-	ORPD    X3, X1 // x0= sin, x1= cos, x7= d, bx= q
-	// if ((q & 4) != 0) != (d < 0) { sin = -sin }
-	MOVQ    BX, AX
-	MOVQ    $61, CX
-	SHLQ    CX, AX
-	MOVQ    AX, X3
-	XORPD   X7, X3
-	MOVQ    $(1<<63), AX
-	MOVQ    AX, X2 // x2= -0.0
-	ANDPD   X2, X3
-	ORPD    X3, X0 // x0= sin, x1= cos, x2= -0.0, bx= q
-	// if ((q + 2) & 4) != 0 { cos = -cos }
-	MOVQ    $2, AX
-	ADDQ    AX, BX
-	MOVQ    $61, CX
-	SHLQ    CX, BX
-	MOVQ    BX, X3
-	ANDPD   X2, X3
-	ORPD    X3, X1 // x0= sin, x1= cos
-	// return (sin, cos)
-	MOVSD   X0, sin+8(FP)
-	MOVSD   X1, cos+16(FP)
-	RET
-isZero: // return (±0.0, 1.0)
-	MOVQ    BX, sin+8(FP)
-	MOVQ    $PosOne, AX
-	MOVQ    AX, cos+16(FP)
-	RET
-isInfOrNaN: // return (NaN, NaN)
-	MOVQ    $NaN, AX
-	MOVQ    AX, sin+8(FP)
-	MOVQ    AX, cos+16(FP)
-	RET
diff --git a/src/pkg/math/sincos_arm.s b/src/pkg/math/sincos_arm.s
deleted file mode 100644
index b6866af..0000000
--- a/src/pkg/math/sincos_arm.s
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright 2011 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../cmd/ld/textflag.h"
-
-TEXT ·Sincos(SB),NOSPLIT,$0
-	B ·sincos(SB)
diff --git a/src/pkg/math/sqrt.go b/src/pkg/math/sqrt.go
deleted file mode 100644
index 1bd4437..0000000
--- a/src/pkg/math/sqrt.go
+++ /dev/null
@@ -1,143 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package math
-
-// The original C code and the long comment below are
-// from FreeBSD's /usr/src/lib/msun/src/e_sqrt.c and
-// came with this notice.  The go code is a simplified
-// version of the original C.
-//
-// ====================================================
-// Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
-//
-// Developed at SunPro, a Sun Microsystems, Inc. business.
-// Permission to use, copy, modify, and distribute this
-// software is freely granted, provided that this notice
-// is preserved.
-// ====================================================
-//
-// __ieee754_sqrt(x)
-// Return correctly rounded sqrt.
-//           -----------------------------------------
-//           | Use the hardware sqrt if you have one |
-//           -----------------------------------------
-// Method:
-//   Bit by bit method using integer arithmetic. (Slow, but portable)
-//   1. Normalization
-//      Scale x to y in [1,4) with even powers of 2:
-//      find an integer k such that  1 <= (y=x*2**(2k)) < 4, then
-//              sqrt(x) = 2**k * sqrt(y)
-//   2. Bit by bit computation
-//      Let q  = sqrt(y) truncated to i bit after binary point (q = 1),
-//           i                                                   0
-//                                     i+1         2
-//          s  = 2*q , and      y  =  2   * ( y - q  ).          (1)
-//           i      i            i                 i
-//
-//      To compute q    from q , one checks whether
-//                  i+1       i
-//
-//                            -(i+1) 2
-//                      (q + 2      )  <= y.                     (2)
-//                        i
-//                                                            -(i+1)
-//      If (2) is false, then q   = q ; otherwise q   = q  + 2      .
-//                             i+1   i             i+1   i
-//
-//      With some algebraic manipulation, it is not difficult to see
-//      that (2) is equivalent to
-//                             -(i+1)
-//                      s  +  2       <= y                       (3)
-//                       i                i
-//
-//      The advantage of (3) is that s  and y  can be computed by
-//                                    i      i
-//      the following recurrence formula:
-//          if (3) is false
-//
-//          s     =  s  ,       y    = y   ;                     (4)
-//           i+1      i          i+1    i
-//
-//      otherwise,
-//                         -i                      -(i+1)
-//          s     =  s  + 2  ,  y    = y  -  s  - 2              (5)
-//           i+1      i          i+1    i     i
-//
-//      One may easily use induction to prove (4) and (5).
-//      Note. Since the left hand side of (3) contain only i+2 bits,
-//            it does not necessary to do a full (53-bit) comparison
-//            in (3).
-//   3. Final rounding
-//      After generating the 53 bits result, we compute one more bit.
-//      Together with the remainder, we can decide whether the
-//      result is exact, bigger than 1/2ulp, or less than 1/2ulp
-//      (it will never equal to 1/2ulp).
-//      The rounding mode can be detected by checking whether
-//      huge + tiny is equal to huge, and whether huge - tiny is
-//      equal to huge for some floating point number "huge" and "tiny".
-//
-//
-// Notes:  Rounding mode detection omitted.  The constants "mask", "shift",
-// and "bias" are found in src/pkg/math/bits.go
-
-// Sqrt returns the square root of x.
-//
-// Special cases are:
-//	Sqrt(+Inf) = +Inf
-//	Sqrt(±0) = ±0
-//	Sqrt(x < 0) = NaN
-//	Sqrt(NaN) = NaN
-func Sqrt(x float64) float64
-
-func sqrt(x float64) float64 {
-	// special cases
-	switch {
-	case x == 0 || IsNaN(x) || IsInf(x, 1):
-		return x
-	case x < 0:
-		return NaN()
-	}
-	ix := Float64bits(x)
-	// normalize x
-	exp := int((ix >> shift) & mask)
-	if exp == 0 { // subnormal x
-		for ix&1<<shift == 0 {
-			ix <<= 1
-			exp--
-		}
-		exp++
-	}
-	exp -= bias // unbias exponent
-	ix &^= mask << shift
-	ix |= 1 << shift
-	if exp&1 == 1 { // odd exp, double x to make it even
-		ix <<= 1
-	}
-	exp >>= 1 // exp = exp/2, exponent of square root
-	// generate sqrt(x) bit by bit
-	ix <<= 1
-	var q, s uint64               // q = sqrt(x)
-	r := uint64(1 << (shift + 1)) // r = moving bit from MSB to LSB
-	for r != 0 {
-		t := s + r
-		if t <= ix {
-			s = t + r
-			ix -= t
-			q += r
-		}
-		ix <<= 1
-		r >>= 1
-	}
-	// final rounding
-	if ix != 0 { // remainder, result not exact
-		q += q & 1 // round according to extra bit
-	}
-	ix = q>>1 + uint64(exp-1+bias)<<shift // significand + biased exponent
-	return Float64frombits(ix)
-}
-
-func sqrtC(f float64, r *float64) {
-	*r = sqrt(f)
-}
diff --git a/src/pkg/math/sqrt_386.s b/src/pkg/math/sqrt_386.s
deleted file mode 100644
index 2d0c786..0000000
--- a/src/pkg/math/sqrt_386.s
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright 2009 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../cmd/ld/textflag.h"
-
-// func Sqrt(x float64) float64	
-TEXT ·Sqrt(SB),NOSPLIT,$0
-	FMOVD   x+0(FP),F0
-	FSQRT
-	FMOVDP  F0,ret+8(FP)
-	RET
diff --git a/src/pkg/math/sqrt_amd64.s b/src/pkg/math/sqrt_amd64.s
deleted file mode 100644
index 1508944..0000000
--- a/src/pkg/math/sqrt_amd64.s
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2009 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../cmd/ld/textflag.h"
-
-// func Sqrt(x float64) float64
-TEXT ·Sqrt(SB),NOSPLIT,$0
-	SQRTSD x+0(FP), X0
-	MOVSD X0, ret+8(FP)
-	RET
diff --git a/src/pkg/math/sqrt_arm.s b/src/pkg/math/sqrt_arm.s
deleted file mode 100644
index f731ee9..0000000
--- a/src/pkg/math/sqrt_arm.s
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright 2011 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../cmd/ld/textflag.h"
-
-// func Sqrt(x float64) float64	
-TEXT ·Sqrt(SB),NOSPLIT,$0
-	MOVD   x+0(FP),F0
-	SQRTD  F0,F0
-	MOVD  F0,ret+8(FP)
-	RET
diff --git a/src/pkg/math/tan_386.s b/src/pkg/math/tan_386.s
deleted file mode 100644
index 2320326..0000000
--- a/src/pkg/math/tan_386.s
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2010 The Go 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 "../../cmd/ld/textflag.h"
-
-// func Tan(x float64) float64
-TEXT ·Tan(SB),NOSPLIT,$0
-	FMOVD   x+0(FP), F0  // F0=x
-	FPTAN                // F0=1, F1=tan(x) if -2**63 < x < 2**63
-	FSTSW   AX           // AX=status word
-	ANDW    $0x0400, AX
-	JNE     4(PC)        // jump if x outside range
-	FMOVDP  F0, F0       // F0=tan(x)
-	FMOVDP  F0, ret+8(FP)
-	RET
-	FLDPI                // F0=Pi, F1=x
-	FADDD   F0, F0       // F0=2*Pi, F1=x
-	FXCHD   F0, F1       // F0=x, F1=2*Pi
-	FPREM1               // F0=reduced_x, F1=2*Pi
-	FSTSW   AX           // AX=status word
-	ANDW    $0x0400, AX
-	JNE     -3(PC)       // jump if reduction incomplete
-	FMOVDP  F0, F1       // F0=reduced_x
-	FPTAN                // F0=1, F1=tan(reduced_x)
-	FMOVDP  F0, F0       // F0=tan(reduced_x)
-	FMOVDP  F0, ret+8(FP)
-	RET
diff --git a/src/pkg/math/tan_amd64.s b/src/pkg/math/tan_amd64.s
deleted file mode 100644
index 9fa5f14..0000000
--- a/src/pkg/math/tan_amd64.s
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright 2011 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../cmd/ld/textflag.h"
-
-TEXT ·Tan(SB),NOSPLIT,$0
-	JMP ·tan(SB)
diff --git a/src/pkg/math/tan_arm.s b/src/pkg/math/tan_arm.s
deleted file mode 100644
index 68fea31..0000000
--- a/src/pkg/math/tan_arm.s
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright 2011 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../cmd/ld/textflag.h"
-
-TEXT ·Tan(SB),NOSPLIT,$0
-	B ·tan(SB)
diff --git a/src/pkg/mime/multipart/example_test.go b/src/pkg/mime/multipart/example_test.go
deleted file mode 100644
index 26135b7..0000000
--- a/src/pkg/mime/multipart/example_test.go
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package multipart_test
-
-import (
-	"fmt"
-	"io"
-	"io/ioutil"
-	"log"
-	"mime"
-	"mime/multipart"
-	"net/mail"
-	"strings"
-)
-
-func ExampleNewReader() {
-	msg := &mail.Message{
-		Header: map[string][]string{
-			"Content-Type": []string{"multipart/mixed; boundary=foo"},
-		},
-		Body: strings.NewReader(
-			"--foo\r\nFoo: one\r\n\r\nA section\r\n" +
-				"--foo\r\nFoo: two\r\n\r\nAnd another\r\n" +
-				"--foo--\r\n"),
-	}
-	mediaType, params, err := mime.ParseMediaType(msg.Header.Get("Content-Type"))
-	if err != nil {
-		log.Fatal(err)
-	}
-	if strings.HasPrefix(mediaType, "multipart/") {
-		mr := multipart.NewReader(msg.Body, params["boundary"])
-		for {
-			p, err := mr.NextPart()
-			if err == io.EOF {
-				return
-			}
-			if err != nil {
-				log.Fatal(err)
-			}
-			slurp, err := ioutil.ReadAll(p)
-			if err != nil {
-				log.Fatal(err)
-			}
-			fmt.Printf("Part %q: %q\n", p.Header.Get("Foo"), slurp)
-		}
-	}
-
-	// Output:
-	// Part "one": "A section"
-	// Part "two": "And another"
-}
diff --git a/src/pkg/mime/multipart/multipart.go b/src/pkg/mime/multipart/multipart.go
deleted file mode 100644
index 7382efa..0000000
--- a/src/pkg/mime/multipart/multipart.go
+++ /dev/null
@@ -1,349 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-//
-
-/*
-Package multipart implements MIME multipart parsing, as defined in RFC
-2046.
-
-The implementation is sufficient for HTTP (RFC 2388) and the multipart
-bodies generated by popular browsers.
-*/
-package multipart
-
-import (
-	"bufio"
-	"bytes"
-	"fmt"
-	"io"
-	"io/ioutil"
-	"mime"
-	"net/textproto"
-)
-
-var emptyParams = make(map[string]string)
-
-// A Part represents a single part in a multipart body.
-type Part struct {
-	// The headers of the body, if any, with the keys canonicalized
-	// in the same fashion that the Go http.Request headers are.
-	// For example, "foo-bar" changes case to "Foo-Bar"
-	//
-	// As a special case, if the "Content-Transfer-Encoding" header
-	// has a value of "quoted-printable", that header is instead
-	// hidden from this map and the body is transparently decoded
-	// during Read calls.
-	Header textproto.MIMEHeader
-
-	buffer    *bytes.Buffer
-	mr        *Reader
-	bytesRead int
-
-	disposition       string
-	dispositionParams map[string]string
-
-	// r is either a reader directly reading from mr, or it's a
-	// wrapper around such a reader, decoding the
-	// Content-Transfer-Encoding
-	r io.Reader
-}
-
-// FormName returns the name parameter if p has a Content-Disposition
-// of type "form-data".  Otherwise it returns the empty string.
-func (p *Part) FormName() string {
-	// See http://tools.ietf.org/html/rfc2183 section 2 for EBNF
-	// of Content-Disposition value format.
-	if p.dispositionParams == nil {
-		p.parseContentDisposition()
-	}
-	if p.disposition != "form-data" {
-		return ""
-	}
-	return p.dispositionParams["name"]
-}
-
-// FileName returns the filename parameter of the Part's
-// Content-Disposition header.
-func (p *Part) FileName() string {
-	if p.dispositionParams == nil {
-		p.parseContentDisposition()
-	}
-	return p.dispositionParams["filename"]
-}
-
-func (p *Part) parseContentDisposition() {
-	v := p.Header.Get("Content-Disposition")
-	var err error
-	p.disposition, p.dispositionParams, err = mime.ParseMediaType(v)
-	if err != nil {
-		p.dispositionParams = emptyParams
-	}
-}
-
-// NewReader creates a new multipart Reader reading from r using the
-// given MIME boundary.
-//
-// The boundary is usually obtained from the "boundary" parameter of
-// the message's "Content-Type" header. Use mime.ParseMediaType to
-// parse such headers.
-func NewReader(r io.Reader, boundary string) *Reader {
-	b := []byte("\r\n--" + boundary + "--")
-	return &Reader{
-		bufReader: bufio.NewReader(r),
-
-		nl:               b[:2],
-		nlDashBoundary:   b[:len(b)-2],
-		dashBoundaryDash: b[2:],
-		dashBoundary:     b[2 : len(b)-2],
-	}
-}
-
-func newPart(mr *Reader) (*Part, error) {
-	bp := &Part{
-		Header: make(map[string][]string),
-		mr:     mr,
-		buffer: new(bytes.Buffer),
-	}
-	if err := bp.populateHeaders(); err != nil {
-		return nil, err
-	}
-	bp.r = partReader{bp}
-	const cte = "Content-Transfer-Encoding"
-	if bp.Header.Get(cte) == "quoted-printable" {
-		bp.Header.Del(cte)
-		bp.r = newQuotedPrintableReader(bp.r)
-	}
-	return bp, nil
-}
-
-func (bp *Part) populateHeaders() error {
-	r := textproto.NewReader(bp.mr.bufReader)
-	header, err := r.ReadMIMEHeader()
-	if err == nil {
-		bp.Header = header
-	}
-	return err
-}
-
-// Read reads the body of a part, after its headers and before the
-// next part (if any) begins.
-func (p *Part) Read(d []byte) (n int, err error) {
-	return p.r.Read(d)
-}
-
-// partReader implements io.Reader by reading raw bytes directly from the
-// wrapped *Part, without doing any Transfer-Encoding decoding.
-type partReader struct {
-	p *Part
-}
-
-func (pr partReader) Read(d []byte) (n int, err error) {
-	p := pr.p
-	defer func() {
-		p.bytesRead += n
-	}()
-	if p.buffer.Len() >= len(d) {
-		// Internal buffer of unconsumed data is large enough for
-		// the read request.  No need to parse more at the moment.
-		return p.buffer.Read(d)
-	}
-	peek, err := p.mr.bufReader.Peek(4096) // TODO(bradfitz): add buffer size accessor
-
-	// Look for an immediate empty part without a leading \r\n
-	// before the boundary separator.  Some MIME code makes empty
-	// parts like this. Most browsers, however, write the \r\n
-	// before the subsequent boundary even for empty parts and
-	// won't hit this path.
-	if p.bytesRead == 0 && p.mr.peekBufferIsEmptyPart(peek) {
-		return 0, io.EOF
-	}
-	unexpectedEOF := err == io.EOF
-	if err != nil && !unexpectedEOF {
-		return 0, fmt.Errorf("multipart: Part Read: %v", err)
-	}
-	if peek == nil {
-		panic("nil peek buf")
-	}
-
-	// Search the peek buffer for "\r\n--boundary". If found,
-	// consume everything up to the boundary. If not, consume only
-	// as much of the peek buffer as cannot hold the boundary
-	// string.
-	nCopy := 0
-	foundBoundary := false
-	if idx := bytes.Index(peek, p.mr.nlDashBoundary); idx != -1 {
-		nCopy = idx
-		foundBoundary = true
-	} else if safeCount := len(peek) - len(p.mr.nlDashBoundary); safeCount > 0 {
-		nCopy = safeCount
-	} else if unexpectedEOF {
-		// If we've run out of peek buffer and the boundary
-		// wasn't found (and can't possibly fit), we must have
-		// hit the end of the file unexpectedly.
-		return 0, io.ErrUnexpectedEOF
-	}
-	if nCopy > 0 {
-		if _, err := io.CopyN(p.buffer, p.mr.bufReader, int64(nCopy)); err != nil {
-			return 0, err
-		}
-	}
-	n, err = p.buffer.Read(d)
-	if err == io.EOF && !foundBoundary {
-		// If the boundary hasn't been reached there's more to
-		// read, so don't pass through an EOF from the buffer
-		err = nil
-	}
-	return
-}
-
-func (p *Part) Close() error {
-	io.Copy(ioutil.Discard, p)
-	return nil
-}
-
-// Reader is an iterator over parts in a MIME multipart body.
-// Reader's underlying parser consumes its input as needed.  Seeking
-// isn't supported.
-type Reader struct {
-	bufReader *bufio.Reader
-
-	currentPart *Part
-	partsRead   int
-
-	nl               []byte // "\r\n" or "\n" (set after seeing first boundary line)
-	nlDashBoundary   []byte // nl + "--boundary"
-	dashBoundaryDash []byte // "--boundary--"
-	dashBoundary     []byte // "--boundary"
-}
-
-// NextPart returns the next part in the multipart or an error.
-// When there are no more parts, the error io.EOF is returned.
-func (r *Reader) NextPart() (*Part, error) {
-	if r.currentPart != nil {
-		r.currentPart.Close()
-	}
-
-	expectNewPart := false
-	for {
-		line, err := r.bufReader.ReadSlice('\n')
-		if err == io.EOF && r.isFinalBoundary(line) {
-			// If the buffer ends in "--boundary--" without the
-			// trailing "\r\n", ReadSlice will return an error
-			// (since it's missing the '\n'), but this is a valid
-			// multipart EOF so we need to return io.EOF instead of
-			// a fmt-wrapped one.
-			return nil, io.EOF
-		}
-		if err != nil {
-			return nil, fmt.Errorf("multipart: NextPart: %v", err)
-		}
-
-		if r.isBoundaryDelimiterLine(line) {
-			r.partsRead++
-			bp, err := newPart(r)
-			if err != nil {
-				return nil, err
-			}
-			r.currentPart = bp
-			return bp, nil
-		}
-
-		if r.isFinalBoundary(line) {
-			// Expected EOF
-			return nil, io.EOF
-		}
-
-		if expectNewPart {
-			return nil, fmt.Errorf("multipart: expecting a new Part; got line %q", string(line))
-		}
-
-		if r.partsRead == 0 {
-			// skip line
-			continue
-		}
-
-		// Consume the "\n" or "\r\n" separator between the
-		// body of the previous part and the boundary line we
-		// now expect will follow. (either a new part or the
-		// end boundary)
-		if bytes.Equal(line, r.nl) {
-			expectNewPart = true
-			continue
-		}
-
-		return nil, fmt.Errorf("multipart: unexpected line in Next(): %q", line)
-	}
-}
-
-// isFinalBoundary reports whether line is the final boundary line
-// indicating that all parts are over.
-// It matches `^--boundary--[ \t]*(\r\n)?$`
-func (mr *Reader) isFinalBoundary(line []byte) bool {
-	if !bytes.HasPrefix(line, mr.dashBoundaryDash) {
-		return false
-	}
-	rest := line[len(mr.dashBoundaryDash):]
-	rest = skipLWSPChar(rest)
-	return len(rest) == 0 || bytes.Equal(rest, mr.nl)
-}
-
-func (mr *Reader) isBoundaryDelimiterLine(line []byte) (ret bool) {
-	// http://tools.ietf.org/html/rfc2046#section-5.1
-	//   The boundary delimiter line is then defined as a line
-	//   consisting entirely of two hyphen characters ("-",
-	//   decimal value 45) followed by the boundary parameter
-	//   value from the Content-Type header field, optional linear
-	//   whitespace, and a terminating CRLF.
-	if !bytes.HasPrefix(line, mr.dashBoundary) {
-		return false
-	}
-	rest := line[len(mr.dashBoundary):]
-	rest = skipLWSPChar(rest)
-
-	// On the first part, see our lines are ending in \n instead of \r\n
-	// and switch into that mode if so.  This is a violation of the spec,
-	// but occurs in practice.
-	if mr.partsRead == 0 && len(rest) == 1 && rest[0] == '\n' {
-		mr.nl = mr.nl[1:]
-		mr.nlDashBoundary = mr.nlDashBoundary[1:]
-	}
-	return bytes.Equal(rest, mr.nl)
-}
-
-// peekBufferIsEmptyPart reports whether the provided peek-ahead
-// buffer represents an empty part. It is called only if we've not
-// already read any bytes in this part and checks for the case of MIME
-// software not writing the \r\n on empty parts. Some does, some
-// doesn't.
-//
-// This checks that what follows the "--boundary" is actually the end
-// ("--boundary--" with optional whitespace) or optional whitespace
-// and then a newline, so we don't catch "--boundaryFAKE", in which
-// case the whole line is part of the data.
-func (mr *Reader) peekBufferIsEmptyPart(peek []byte) bool {
-	// End of parts case.
-	// Test whether peek matches `^--boundary--[ \t]*(?:\r\n|$)`
-	if bytes.HasPrefix(peek, mr.dashBoundaryDash) {
-		rest := peek[len(mr.dashBoundaryDash):]
-		rest = skipLWSPChar(rest)
-		return bytes.HasPrefix(rest, mr.nl) || len(rest) == 0
-	}
-	if !bytes.HasPrefix(peek, mr.dashBoundary) {
-		return false
-	}
-	// Test whether rest matches `^[ \t]*\r\n`)
-	rest := peek[len(mr.dashBoundary):]
-	rest = skipLWSPChar(rest)
-	return bytes.HasPrefix(rest, mr.nl)
-}
-
-// skipLWSPChar returns b with leading spaces and tabs removed.
-// RFC 822 defines:
-//    LWSP-char = SPACE / HTAB
-func skipLWSPChar(b []byte) []byte {
-	for len(b) > 0 && (b[0] == ' ' || b[0] == '\t') {
-		b = b[1:]
-	}
-	return b
-}
diff --git a/src/pkg/mime/multipart/writer_test.go b/src/pkg/mime/multipart/writer_test.go
deleted file mode 100644
index 52d68bc..0000000
--- a/src/pkg/mime/multipart/writer_test.go
+++ /dev/null
@@ -1,113 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package multipart
-
-import (
-	"bytes"
-	"io/ioutil"
-	"strings"
-	"testing"
-)
-
-func TestWriter(t *testing.T) {
-	fileContents := []byte("my file contents")
-
-	var b bytes.Buffer
-	w := NewWriter(&b)
-	{
-		part, err := w.CreateFormFile("myfile", "my-file.txt")
-		if err != nil {
-			t.Fatalf("CreateFormFile: %v", err)
-		}
-		part.Write(fileContents)
-		err = w.WriteField("key", "val")
-		if err != nil {
-			t.Fatalf("WriteField: %v", err)
-		}
-		part.Write([]byte("val"))
-		err = w.Close()
-		if err != nil {
-			t.Fatalf("Close: %v", err)
-		}
-		s := b.String()
-		if len(s) == 0 {
-			t.Fatal("String: unexpected empty result")
-		}
-		if s[0] == '\r' || s[0] == '\n' {
-			t.Fatal("String: unexpected newline")
-		}
-	}
-
-	r := NewReader(&b, w.Boundary())
-
-	part, err := r.NextPart()
-	if err != nil {
-		t.Fatalf("part 1: %v", err)
-	}
-	if g, e := part.FormName(), "myfile"; g != e {
-		t.Errorf("part 1: want form name %q, got %q", e, g)
-	}
-	slurp, err := ioutil.ReadAll(part)
-	if err != nil {
-		t.Fatalf("part 1: ReadAll: %v", err)
-	}
-	if e, g := string(fileContents), string(slurp); e != g {
-		t.Errorf("part 1: want contents %q, got %q", e, g)
-	}
-
-	part, err = r.NextPart()
-	if err != nil {
-		t.Fatalf("part 2: %v", err)
-	}
-	if g, e := part.FormName(), "key"; g != e {
-		t.Errorf("part 2: want form name %q, got %q", e, g)
-	}
-	slurp, err = ioutil.ReadAll(part)
-	if err != nil {
-		t.Fatalf("part 2: ReadAll: %v", err)
-	}
-	if e, g := "val", string(slurp); e != g {
-		t.Errorf("part 2: want contents %q, got %q", e, g)
-	}
-
-	part, err = r.NextPart()
-	if part != nil || err == nil {
-		t.Fatalf("expected end of parts; got %v, %v", part, err)
-	}
-}
-
-func TestWriterSetBoundary(t *testing.T) {
-	var b bytes.Buffer
-	w := NewWriter(&b)
-	tests := []struct {
-		b  string
-		ok bool
-	}{
-		{"abc", true},
-		{"", false},
-		{"ungültig", false},
-		{"!", false},
-		{strings.Repeat("x", 69), true},
-		{strings.Repeat("x", 70), false},
-		{"bad!ascii!", false},
-		{"my-separator", true},
-	}
-	for i, tt := range tests {
-		err := w.SetBoundary(tt.b)
-		got := err == nil
-		if got != tt.ok {
-			t.Errorf("%d. boundary %q = %v (%v); want %v", i, tt.b, got, err, tt.ok)
-		} else if tt.ok {
-			got := w.Boundary()
-			if got != tt.b {
-				t.Errorf("boundary = %q; want %q", got, tt.b)
-			}
-		}
-	}
-	w.Close()
-	if got := b.String(); !strings.Contains(got, "\r\n--my-separator--\r\n") {
-		t.Errorf("expected my-separator in output. got: %q", got)
-	}
-}
diff --git a/src/pkg/mime/type.go b/src/pkg/mime/type.go
deleted file mode 100644
index 00cff26..0000000
--- a/src/pkg/mime/type.go
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package mime implements parts of the MIME spec.
-package mime
-
-import (
-	"fmt"
-	"strings"
-	"sync"
-)
-
-var mimeTypes = map[string]string{
-	".css":  "text/css; charset=utf-8",
-	".gif":  "image/gif",
-	".htm":  "text/html; charset=utf-8",
-	".html": "text/html; charset=utf-8",
-	".jpg":  "image/jpeg",
-	".js":   "application/x-javascript",
-	".pdf":  "application/pdf",
-	".png":  "image/png",
-	".xml":  "text/xml; charset=utf-8",
-}
-
-var mimeLock sync.RWMutex
-
-var once sync.Once
-
-// TypeByExtension returns the MIME type associated with the file extension ext.
-// The extension ext should begin with a leading dot, as in ".html".
-// When ext has no associated type, TypeByExtension returns "".
-//
-// The built-in table is small but on unix it is augmented by the local
-// system's mime.types file(s) if available under one or more of these
-// names:
-//
-//   /etc/mime.types
-//   /etc/apache2/mime.types
-//   /etc/apache/mime.types
-//
-// Windows system mime types are extracted from registry.
-//
-// Text types have the charset parameter set to "utf-8" by default.
-func TypeByExtension(ext string) string {
-	once.Do(initMime)
-	mimeLock.RLock()
-	typename := mimeTypes[ext]
-	mimeLock.RUnlock()
-	return typename
-}
-
-// AddExtensionType sets the MIME type associated with
-// the extension ext to typ.  The extension should begin with
-// a leading dot, as in ".html".
-func AddExtensionType(ext, typ string) error {
-	if ext == "" || ext[0] != '.' {
-		return fmt.Errorf(`mime: extension "%s" misses dot`, ext)
-	}
-	once.Do(initMime)
-	return setExtensionType(ext, typ)
-}
-
-func setExtensionType(extension, mimeType string) error {
-	_, param, err := ParseMediaType(mimeType)
-	if err != nil {
-		return err
-	}
-	if strings.HasPrefix(mimeType, "text/") && param["charset"] == "" {
-		param["charset"] = "utf-8"
-		mimeType = FormatMediaType(mimeType, param)
-	}
-	mimeLock.Lock()
-	mimeTypes[extension] = mimeType
-	mimeLock.Unlock()
-	return nil
-}
diff --git a/src/pkg/mime/type_plan9.go b/src/pkg/mime/type_plan9.go
deleted file mode 100644
index b8f0511..0000000
--- a/src/pkg/mime/type_plan9.go
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package mime
-
-import (
-	"bufio"
-	"os"
-	"strings"
-)
-
-var typeFiles = []string{
-	"/sys/lib/mimetypes",
-}
-
-func loadMimeFile(filename string) {
-	f, err := os.Open(filename)
-	if err != nil {
-		return
-	}
-	defer f.Close()
-
-	scanner := bufio.NewScanner(f)
-	for scanner.Scan() {
-		fields := strings.Fields(scanner.Text())
-		if len(fields) <= 2 || fields[0][0] != '.' {
-			continue
-		}
-		if fields[1] == "-" || fields[2] == "-" {
-			continue
-		}
-		setExtensionType(fields[0], fields[1]+"/"+fields[2])
-	}
-	if err := scanner.Err(); err != nil {
-		panic(err)
-	}
-}
-
-func initMime() {
-	for _, filename := range typeFiles {
-		loadMimeFile(filename)
-	}
-}
-
-func initMimeForTests() map[string]string {
-	typeFiles = []string{"testdata/test.types.plan9"}
-	return map[string]string{
-		".t1":  "application/test",
-		".t2":  "text/test; charset=utf-8",
-		".png": "image/png",
-	}
-}
diff --git a/src/pkg/mime/type_test.go b/src/pkg/mime/type_test.go
deleted file mode 100644
index 07e1cd5..0000000
--- a/src/pkg/mime/type_test.go
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package mime
-
-import "testing"
-
-var typeTests = initMimeForTests()
-
-func TestTypeByExtension(t *testing.T) {
-	for ext, want := range typeTests {
-		val := TypeByExtension(ext)
-		if val != want {
-			t.Errorf("TypeByExtension(%q) = %q, want %q", ext, val, want)
-		}
-
-	}
-}
-
-func TestCustomExtension(t *testing.T) {
-	custom := "text/xml; charset=iso-8859-1"
-	if error := AddExtensionType(".xml", custom); error != nil {
-		t.Fatalf("error %s for AddExtension(%s)", error, custom)
-	}
-	if registered := TypeByExtension(".xml"); registered != custom {
-		t.Fatalf("registered %s instead of %s", registered, custom)
-	}
-}
diff --git a/src/pkg/mime/type_unix.go b/src/pkg/mime/type_unix.go
deleted file mode 100644
index 1d39431..0000000
--- a/src/pkg/mime/type_unix.go
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris
-
-package mime
-
-import (
-	"bufio"
-	"os"
-	"strings"
-)
-
-var typeFiles = []string{
-	"/etc/mime.types",
-	"/etc/apache2/mime.types",
-	"/etc/apache/mime.types",
-}
-
-func loadMimeFile(filename string) {
-	f, err := os.Open(filename)
-	if err != nil {
-		return
-	}
-	defer f.Close()
-
-	scanner := bufio.NewScanner(f)
-	for scanner.Scan() {
-		fields := strings.Fields(scanner.Text())
-		if len(fields) <= 1 || fields[0][0] == '#' {
-			continue
-		}
-		mimeType := fields[0]
-		for _, ext := range fields[1:] {
-			if ext[0] == '#' {
-				break
-			}
-			setExtensionType("."+ext, mimeType)
-		}
-	}
-	if err := scanner.Err(); err != nil {
-		panic(err)
-	}
-}
-
-func initMime() {
-	for _, filename := range typeFiles {
-		loadMimeFile(filename)
-	}
-}
-
-func initMimeForTests() map[string]string {
-	typeFiles = []string{"testdata/test.types"}
-	return map[string]string{
-		".t1":  "application/test",
-		".t2":  "text/test; charset=utf-8",
-		".png": "image/png",
-	}
-}
diff --git a/src/pkg/mime/type_windows.go b/src/pkg/mime/type_windows.go
deleted file mode 100644
index 180f948..0000000
--- a/src/pkg/mime/type_windows.go
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package mime
-
-import (
-	"syscall"
-	"unsafe"
-)
-
-func initMime() {
-	var root syscall.Handle
-	rootpathp, _ := syscall.UTF16PtrFromString(`\`)
-	if syscall.RegOpenKeyEx(syscall.HKEY_CLASSES_ROOT, rootpathp,
-		0, syscall.KEY_READ, &root) != nil {
-		return
-	}
-	defer syscall.RegCloseKey(root)
-	var count uint32
-	if syscall.RegQueryInfoKey(root, nil, nil, nil, &count, nil, nil, nil, nil, nil, nil, nil) != nil {
-		return
-	}
-	var buf [1 << 10]uint16
-	for i := uint32(0); i < count; i++ {
-		n := uint32(len(buf))
-		if syscall.RegEnumKeyEx(root, i, &buf[0], &n, nil, nil, nil, nil) != nil {
-			continue
-		}
-		ext := syscall.UTF16ToString(buf[:])
-		if len(ext) < 2 || ext[0] != '.' { // looking for extensions only
-			continue
-		}
-		var h syscall.Handle
-		extpathp, _ := syscall.UTF16PtrFromString(`\` + ext)
-		if syscall.RegOpenKeyEx(
-			syscall.HKEY_CLASSES_ROOT, extpathp,
-			0, syscall.KEY_READ, &h) != nil {
-			continue
-		}
-		var typ uint32
-		n = uint32(len(buf) * 2) // api expects array of bytes, not uint16
-		contenttypep, _ := syscall.UTF16PtrFromString("Content Type")
-		if syscall.RegQueryValueEx(
-			h, contenttypep,
-			nil, &typ, (*byte)(unsafe.Pointer(&buf[0])), &n) != nil {
-			syscall.RegCloseKey(h)
-			continue
-		}
-		syscall.RegCloseKey(h)
-		if typ != syscall.REG_SZ { // null terminated strings only
-			continue
-		}
-		mimeType := syscall.UTF16ToString(buf[:])
-		setExtensionType(ext, mimeType)
-	}
-}
-
-func initMimeForTests() map[string]string {
-	return map[string]string{
-		".png": "image/png",
-	}
-}
diff --git a/src/pkg/net/cgo_linux.go b/src/pkg/net/cgo_linux.go
deleted file mode 100644
index 693aef0..0000000
--- a/src/pkg/net/cgo_linux.go
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2011 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build cgo,!netgo
-
-package net
-
-/*
-#include <netdb.h>
-*/
-import "C"
-
-func cgoAddrInfoFlags() C.int {
-	// NOTE(rsc): In theory there are approximately balanced
-	// arguments for and against including AI_ADDRCONFIG
-	// in the flags (it includes IPv4 results only on IPv4 systems,
-	// and similarly for IPv6), but in practice setting it causes
-	// getaddrinfo to return the wrong canonical name on Linux.
-	// So definitely leave it out.
-	return C.AI_CANONNAME | C.AI_V4MAPPED | C.AI_ALL
-}
diff --git a/src/pkg/net/conn_test.go b/src/pkg/net/conn_test.go
deleted file mode 100644
index 37bb4e2..0000000
--- a/src/pkg/net/conn_test.go
+++ /dev/null
@@ -1,124 +0,0 @@
-// Copyright 2012 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// This file implements API tests across platforms and will never have a build
-// tag.
-
-package net
-
-import (
-	"os"
-	"runtime"
-	"testing"
-	"time"
-)
-
-var connTests = []struct {
-	net  string
-	addr string
-}{
-	{"tcp", "127.0.0.1:0"},
-	{"unix", testUnixAddr()},
-	{"unixpacket", testUnixAddr()},
-}
-
-// someTimeout is used just to test that net.Conn implementations
-// don't explode when their SetFooDeadline methods are called.
-// It isn't actually used for testing timeouts.
-const someTimeout = 10 * time.Second
-
-func TestConnAndListener(t *testing.T) {
-	for _, tt := range connTests {
-		switch tt.net {
-		case "unix":
-			switch runtime.GOOS {
-			case "nacl", "plan9", "windows":
-				continue
-			}
-		case "unixpacket":
-			switch runtime.GOOS {
-			case "darwin", "nacl", "openbsd", "plan9", "windows":
-				continue
-			case "freebsd": // FreeBSD 8 doesn't support unixpacket
-				continue
-			}
-		}
-
-		ln, err := Listen(tt.net, tt.addr)
-		if err != nil {
-			t.Fatalf("Listen failed: %v", err)
-		}
-		defer func(ln Listener, net, addr string) {
-			ln.Close()
-			switch net {
-			case "unix", "unixpacket":
-				os.Remove(addr)
-			}
-		}(ln, tt.net, tt.addr)
-		if ln.Addr().Network() != tt.net {
-			t.Fatalf("got %v; expected %v", ln.Addr().Network(), tt.net)
-		}
-
-		done := make(chan int)
-		go transponder(t, ln, done)
-
-		c, err := Dial(tt.net, ln.Addr().String())
-		if err != nil {
-			t.Fatalf("Dial failed: %v", err)
-		}
-		defer c.Close()
-		if c.LocalAddr().Network() != tt.net || c.LocalAddr().Network() != tt.net {
-			t.Fatalf("got %v->%v; expected %v->%v", c.LocalAddr().Network(), c.RemoteAddr().Network(), tt.net, tt.net)
-		}
-		c.SetDeadline(time.Now().Add(someTimeout))
-		c.SetReadDeadline(time.Now().Add(someTimeout))
-		c.SetWriteDeadline(time.Now().Add(someTimeout))
-
-		if _, err := c.Write([]byte("CONN TEST")); err != nil {
-			t.Fatalf("Conn.Write failed: %v", err)
-		}
-		rb := make([]byte, 128)
-		if _, err := c.Read(rb); err != nil {
-			t.Fatalf("Conn.Read failed: %v", err)
-		}
-
-		<-done
-	}
-}
-
-func transponder(t *testing.T, ln Listener, done chan<- int) {
-	defer func() { done <- 1 }()
-
-	switch ln := ln.(type) {
-	case *TCPListener:
-		ln.SetDeadline(time.Now().Add(someTimeout))
-	case *UnixListener:
-		ln.SetDeadline(time.Now().Add(someTimeout))
-	}
-	c, err := ln.Accept()
-	if err != nil {
-		t.Errorf("Listener.Accept failed: %v", err)
-		return
-	}
-	defer c.Close()
-	network := ln.Addr().Network()
-	if c.LocalAddr().Network() != network || c.LocalAddr().Network() != network {
-		t.Errorf("got %v->%v; expected %v->%v", c.LocalAddr().Network(), c.RemoteAddr().Network(), network, network)
-		return
-	}
-	c.SetDeadline(time.Now().Add(someTimeout))
-	c.SetReadDeadline(time.Now().Add(someTimeout))
-	c.SetWriteDeadline(time.Now().Add(someTimeout))
-
-	b := make([]byte, 128)
-	n, err := c.Read(b)
-	if err != nil {
-		t.Errorf("Conn.Read failed: %v", err)
-		return
-	}
-	if _, err := c.Write(b[:n]); err != nil {
-		t.Errorf("Conn.Write failed: %v", err)
-		return
-	}
-}
diff --git a/src/pkg/net/dial.go b/src/pkg/net/dial.go
deleted file mode 100644
index 93569c2..0000000
--- a/src/pkg/net/dial.go
+++ /dev/null
@@ -1,305 +0,0 @@
-// Copyright 2010 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package net
-
-import (
-	"errors"
-	"time"
-)
-
-// A Dialer contains options for connecting to an address.
-//
-// The zero value for each field is equivalent to dialing
-// without that option. Dialing with the zero value of Dialer
-// is therefore equivalent to just calling the Dial function.
-type Dialer struct {
-	// Timeout is the maximum amount of time a dial will wait for
-	// a connect to complete. If Deadline is also set, it may fail
-	// earlier.
-	//
-	// The default is no timeout.
-	//
-	// With or without a timeout, the operating system may impose
-	// its own earlier timeout. For instance, TCP timeouts are
-	// often around 3 minutes.
-	Timeout time.Duration
-
-	// Deadline is the absolute point in time after which dials
-	// will fail. If Timeout is set, it may fail earlier.
-	// Zero means no deadline, or dependent on the operating system
-	// as with the Timeout option.
-	Deadline time.Time
-
-	// LocalAddr is the local address to use when dialing an
-	// address. The address must be of a compatible type for the
-	// network being dialed.
-	// If nil, a local address is automatically chosen.
-	LocalAddr Addr
-
-	// DualStack allows a single dial to attempt to establish
-	// multiple IPv4 and IPv6 connections and to return the first
-	// established connection when the network is "tcp" and the
-	// destination is a host name that has multiple address family
-	// DNS records.
-	DualStack bool
-
-	// KeepAlive specifies the keep-alive period for an active
-	// network connection.
-	// If zero, keep-alives are not enabled. Network protocols
-	// that do not support keep-alives ignore this field.
-	KeepAlive time.Duration
-}
-
-// Return either now+Timeout or Deadline, whichever comes first.
-// Or zero, if neither is set.
-func (d *Dialer) deadline() time.Time {
-	if d.Timeout == 0 {
-		return d.Deadline
-	}
-	timeoutDeadline := time.Now().Add(d.Timeout)
-	if d.Deadline.IsZero() || timeoutDeadline.Before(d.Deadline) {
-		return timeoutDeadline
-	} else {
-		return d.Deadline
-	}
-}
-
-func parseNetwork(net string) (afnet string, proto int, err error) {
-	i := last(net, ':')
-	if i < 0 { // no colon
-		switch net {
-		case "tcp", "tcp4", "tcp6":
-		case "udp", "udp4", "udp6":
-		case "ip", "ip4", "ip6":
-		case "unix", "unixgram", "unixpacket":
-		default:
-			return "", 0, UnknownNetworkError(net)
-		}
-		return net, 0, nil
-	}
-	afnet = net[:i]
-	switch afnet {
-	case "ip", "ip4", "ip6":
-		protostr := net[i+1:]
-		proto, i, ok := dtoi(protostr, 0)
-		if !ok || i != len(protostr) {
-			proto, err = lookupProtocol(protostr)
-			if err != nil {
-				return "", 0, err
-			}
-		}
-		return afnet, proto, nil
-	}
-	return "", 0, UnknownNetworkError(net)
-}
-
-func resolveAddr(op, net, addr string, deadline time.Time) (netaddr, error) {
-	afnet, _, err := parseNetwork(net)
-	if err != nil {
-		return nil, err
-	}
-	if op == "dial" && addr == "" {
-		return nil, errMissingAddress
-	}
-	switch afnet {
-	case "unix", "unixgram", "unixpacket":
-		return ResolveUnixAddr(afnet, addr)
-	}
-	return resolveInternetAddr(afnet, addr, deadline)
-}
-
-// Dial connects to the address on the named network.
-//
-// Known networks are "tcp", "tcp4" (IPv4-only), "tcp6" (IPv6-only),
-// "udp", "udp4" (IPv4-only), "udp6" (IPv6-only), "ip", "ip4"
-// (IPv4-only), "ip6" (IPv6-only), "unix", "unixgram" and
-// "unixpacket".
-//
-// For TCP and UDP networks, addresses have the form host:port.
-// If host is a literal IPv6 address or host name, it must be enclosed
-// in square brackets as in "[::1]:80", "[ipv6-host]:http" or
-// "[ipv6-host%zone]:80".
-// The functions JoinHostPort and SplitHostPort manipulate addresses
-// in this form.
-//
-// Examples:
-//	Dial("tcp", "12.34.56.78:80")
-//	Dial("tcp", "google.com:http")
-//	Dial("tcp", "[2001:db8::1]:http")
-//	Dial("tcp", "[fe80::1%lo0]:80")
-//
-// For IP networks, the network must be "ip", "ip4" or "ip6" followed
-// by a colon and a protocol number or name and the addr must be a
-// literal IP address.
-//
-// Examples:
-//	Dial("ip4:1", "127.0.0.1")
-//	Dial("ip6:ospf", "::1")
-//
-// For Unix networks, the address must be a file system path.
-func Dial(network, address string) (Conn, error) {
-	var d Dialer
-	return d.Dial(network, address)
-}
-
-// DialTimeout acts like Dial but takes a timeout.
-// The timeout includes name resolution, if required.
-func DialTimeout(network, address string, timeout time.Duration) (Conn, error) {
-	d := Dialer{Timeout: timeout}
-	return d.Dial(network, address)
-}
-
-// Dial connects to the address on the named network.
-//
-// See func Dial for a description of the network and address
-// parameters.
-func (d *Dialer) Dial(network, address string) (Conn, error) {
-	ra, err := resolveAddr("dial", network, address, d.deadline())
-	if err != nil {
-		return nil, &OpError{Op: "dial", Net: network, Addr: nil, Err: err}
-	}
-	dialer := func(deadline time.Time) (Conn, error) {
-		return dialSingle(network, address, d.LocalAddr, ra.toAddr(), deadline)
-	}
-	if ras, ok := ra.(addrList); ok && d.DualStack && network == "tcp" {
-		dialer = func(deadline time.Time) (Conn, error) {
-			return dialMulti(network, address, d.LocalAddr, ras, deadline)
-		}
-	}
-	c, err := dial(network, ra.toAddr(), dialer, d.deadline())
-	if d.KeepAlive > 0 && err == nil {
-		if tc, ok := c.(*TCPConn); ok {
-			tc.SetKeepAlive(true)
-			tc.SetKeepAlivePeriod(d.KeepAlive)
-			testHookSetKeepAlive()
-		}
-	}
-	return c, err
-}
-
-var testHookSetKeepAlive = func() {} // changed by dial_test.go
-
-// dialMulti attempts to establish connections to each destination of
-// the list of addresses. It will return the first established
-// connection and close the other connections. Otherwise it returns
-// error on the last attempt.
-func dialMulti(net, addr string, la Addr, ras addrList, deadline time.Time) (Conn, error) {
-	type racer struct {
-		Conn
-		error
-	}
-	// Sig controls the flow of dial results on lane. It passes a
-	// token to the next racer and also indicates the end of flow
-	// by using closed channel.
-	sig := make(chan bool, 1)
-	lane := make(chan racer, 1)
-	for _, ra := range ras {
-		go func(ra Addr) {
-			c, err := dialSingle(net, addr, la, ra, deadline)
-			if _, ok := <-sig; ok {
-				lane <- racer{c, err}
-			} else if err == nil {
-				// We have to return the resources
-				// that belong to the other
-				// connections here for avoiding
-				// unnecessary resource starvation.
-				c.Close()
-			}
-		}(ra.toAddr())
-	}
-	defer close(sig)
-	lastErr := errTimeout
-	nracers := len(ras)
-	for nracers > 0 {
-		sig <- true
-		select {
-		case racer := <-lane:
-			if racer.error == nil {
-				return racer.Conn, nil
-			}
-			lastErr = racer.error
-			nracers--
-		}
-	}
-	return nil, lastErr
-}
-
-// dialSingle attempts to establish and returns a single connection to
-// the destination address.
-func dialSingle(net, addr string, la, ra Addr, deadline time.Time) (c Conn, err error) {
-	if la != nil && la.Network() != ra.Network() {
-		return nil, &OpError{Op: "dial", Net: net, Addr: ra, Err: errors.New("mismatched local address type " + la.Network())}
-	}
-	switch ra := ra.(type) {
-	case *TCPAddr:
-		la, _ := la.(*TCPAddr)
-		c, err = dialTCP(net, la, ra, deadline)
-	case *UDPAddr:
-		la, _ := la.(*UDPAddr)
-		c, err = dialUDP(net, la, ra, deadline)
-	case *IPAddr:
-		la, _ := la.(*IPAddr)
-		c, err = dialIP(net, la, ra, deadline)
-	case *UnixAddr:
-		la, _ := la.(*UnixAddr)
-		c, err = dialUnix(net, la, ra, deadline)
-	default:
-		return nil, &OpError{Op: "dial", Net: net, Addr: ra, Err: &AddrError{Err: "unexpected address type", Addr: addr}}
-	}
-	if err != nil {
-		return nil, err // c is non-nil interface containing nil pointer
-	}
-	return c, nil
-}
-
-// Listen announces on the local network address laddr.
-// The network net must be a stream-oriented network: "tcp", "tcp4",
-// "tcp6", "unix" or "unixpacket".
-// See Dial for the syntax of laddr.
-func Listen(net, laddr string) (Listener, error) {
-	la, err := resolveAddr("listen", net, laddr, noDeadline)
-	if err != nil {
-		return nil, &OpError{Op: "listen", Net: net, Addr: nil, Err: err}
-	}
-	var l Listener
-	switch la := la.toAddr().(type) {
-	case *TCPAddr:
-		l, err = ListenTCP(net, la)
-	case *UnixAddr:
-		l, err = ListenUnix(net, la)
-	default:
-		return nil, &OpError{Op: "listen", Net: net, Addr: la, Err: &AddrError{Err: "unexpected address type", Addr: laddr}}
-	}
-	if err != nil {
-		return nil, err // l is non-nil interface containing nil pointer
-	}
-	return l, nil
-}
-
-// ListenPacket announces on the local network address laddr.
-// The network net must be a packet-oriented network: "udp", "udp4",
-// "udp6", "ip", "ip4", "ip6" or "unixgram".
-// See Dial for the syntax of laddr.
-func ListenPacket(net, laddr string) (PacketConn, error) {
-	la, err := resolveAddr("listen", net, laddr, noDeadline)
-	if err != nil {
-		return nil, &OpError{Op: "listen", Net: net, Addr: nil, Err: err}
-	}
-	var l PacketConn
-	switch la := la.toAddr().(type) {
-	case *UDPAddr:
-		l, err = ListenUDP(net, la)
-	case *IPAddr:
-		l, err = ListenIP(net, la)
-	case *UnixAddr:
-		l, err = ListenUnixgram(net, la)
-	default:
-		return nil, &OpError{Op: "listen", Net: net, Addr: la, Err: &AddrError{Err: "unexpected address type", Addr: laddr}}
-	}
-	if err != nil {
-		return nil, err // l is non-nil interface containing nil pointer
-	}
-	return l, nil
-}
diff --git a/src/pkg/net/dial_test.go b/src/pkg/net/dial_test.go
deleted file mode 100644
index f9260fd..0000000
--- a/src/pkg/net/dial_test.go
+++ /dev/null
@@ -1,536 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package net
-
-import (
-	"bytes"
-	"flag"
-	"fmt"
-	"io"
-	"os"
-	"os/exec"
-	"reflect"
-	"regexp"
-	"runtime"
-	"strconv"
-	"sync"
-	"testing"
-	"time"
-)
-
-func newLocalListener(t *testing.T) Listener {
-	ln, err := Listen("tcp", "127.0.0.1:0")
-	if err != nil {
-		ln, err = Listen("tcp6", "[::1]:0")
-	}
-	if err != nil {
-		t.Fatal(err)
-	}
-	return ln
-}
-
-func TestDialTimeout(t *testing.T) {
-	origBacklog := listenerBacklog
-	defer func() {
-		listenerBacklog = origBacklog
-	}()
-	listenerBacklog = 1
-
-	ln := newLocalListener(t)
-	defer ln.Close()
-
-	errc := make(chan error)
-
-	numConns := listenerBacklog + 100
-
-	// TODO(bradfitz): It's hard to test this in a portable
-	// way. This is unfortunate, but works for now.
-	switch runtime.GOOS {
-	case "linux":
-		// The kernel will start accepting TCP connections before userspace
-		// gets a chance to not accept them, so fire off a bunch to fill up
-		// the kernel's backlog.  Then we test we get a failure after that.
-		for i := 0; i < numConns; i++ {
-			go func() {
-				_, err := DialTimeout("tcp", ln.Addr().String(), 200*time.Millisecond)
-				errc <- err
-			}()
-		}
-	case "darwin", "plan9", "windows":
-		// At least OS X 10.7 seems to accept any number of
-		// connections, ignoring listen's backlog, so resort
-		// to connecting to a hopefully-dead 127/8 address.
-		// Same for windows.
-		//
-		// Use an IANA reserved port (49151) instead of 80, because
-		// on our 386 builder, this Dial succeeds, connecting
-		// to an IIS web server somewhere.  The data center
-		// or VM or firewall must be stealing the TCP connection.
-		//
-		// IANA Service Name and Transport Protocol Port Number Registry
-		// <http://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xml>
-		go func() {
-			c, err := DialTimeout("tcp", "127.0.71.111:49151", 200*time.Millisecond)
-			if err == nil {
-				err = fmt.Errorf("unexpected: connected to %s!", c.RemoteAddr())
-				c.Close()
-			}
-			errc <- err
-		}()
-	default:
-		// TODO(bradfitz):
-		// OpenBSD may have a reject route to 127/8 except 127.0.0.1/32
-		// by default. FreeBSD likely works, but is untested.
-		// TODO(rsc):
-		// The timeout never happens on Windows.  Why?  Issue 3016.
-		t.Skipf("skipping test on %q; untested.", runtime.GOOS)
-	}
-
-	connected := 0
-	for {
-		select {
-		case <-time.After(15 * time.Second):
-			t.Fatal("too slow")
-		case err := <-errc:
-			if err == nil {
-				connected++
-				if connected == numConns {
-					t.Fatal("all connections connected; expected some to time out")
-				}
-			} else {
-				terr, ok := err.(timeout)
-				if !ok {
-					t.Fatalf("got error %q; want error with timeout interface", err)
-				}
-				if !terr.Timeout() {
-					t.Fatalf("got error %q; not a timeout", err)
-				}
-				// Pass. We saw a timeout error.
-				return
-			}
-		}
-	}
-}
-
-func TestSelfConnect(t *testing.T) {
-	if runtime.GOOS == "windows" {
-		// TODO(brainman): do not know why it hangs.
-		t.Skip("skipping known-broken test on windows")
-	}
-	// Test that Dial does not honor self-connects.
-	// See the comment in DialTCP.
-
-	// Find a port that would be used as a local address.
-	l, err := Listen("tcp", "127.0.0.1:0")
-	if err != nil {
-		t.Fatal(err)
-	}
-	c, err := Dial("tcp", l.Addr().String())
-	if err != nil {
-		t.Fatal(err)
-	}
-	addr := c.LocalAddr().String()
-	c.Close()
-	l.Close()
-
-	// Try to connect to that address repeatedly.
-	n := 100000
-	if testing.Short() {
-		n = 1000
-	}
-	switch runtime.GOOS {
-	case "darwin", "dragonfly", "freebsd", "netbsd", "openbsd", "plan9", "solaris", "windows":
-		// Non-Linux systems take a long time to figure
-		// out that there is nothing listening on localhost.
-		n = 100
-	}
-	for i := 0; i < n; i++ {
-		c, err := DialTimeout("tcp", addr, time.Millisecond)
-		if err == nil {
-			c.Close()
-			t.Errorf("#%d: Dial %q succeeded", i, addr)
-		}
-	}
-}
-
-var runErrorTest = flag.Bool("run_error_test", false, "let TestDialError check for dns errors")
-
-type DialErrorTest struct {
-	Net     string
-	Raddr   string
-	Pattern string
-}
-
-var dialErrorTests = []DialErrorTest{
-	{
-		"datakit", "mh/astro/r70",
-		"dial datakit mh/astro/r70: unknown network datakit",
-	},
-	{
-		"tcp", "127.0.0.1:☺",
-		"dial tcp 127.0.0.1:☺: unknown port tcp/☺",
-	},
-	{
-		"tcp", "no-such-name.google.com.:80",
-		"dial tcp no-such-name.google.com.:80: lookup no-such-name.google.com.( on .*)?: no (.*)",
-	},
-	{
-		"tcp", "no-such-name.no-such-top-level-domain.:80",
-		"dial tcp no-such-name.no-such-top-level-domain.:80: lookup no-such-name.no-such-top-level-domain.( on .*)?: no (.*)",
-	},
-	{
-		"tcp", "no-such-name:80",
-		`dial tcp no-such-name:80: lookup no-such-name\.(.*\.)?( on .*)?: no (.*)`,
-	},
-	{
-		"tcp", "mh/astro/r70:http",
-		"dial tcp mh/astro/r70:http: lookup mh/astro/r70: invalid domain name",
-	},
-	{
-		"unix", "/etc/file-not-found",
-		"dial unix /etc/file-not-found: no such file or directory",
-	},
-	{
-		"unix", "/etc/",
-		"dial unix /etc/: (permission denied|socket operation on non-socket|connection refused)",
-	},
-	{
-		"unixpacket", "/etc/file-not-found",
-		"dial unixpacket /etc/file-not-found: no such file or directory",
-	},
-	{
-		"unixpacket", "/etc/",
-		"dial unixpacket /etc/: (permission denied|socket operation on non-socket|connection refused)",
-	},
-}
-
-var duplicateErrorPattern = `dial (.*) dial (.*)`
-
-func TestDialError(t *testing.T) {
-	if !*runErrorTest {
-		t.Logf("test disabled; use -run_error_test to enable")
-		return
-	}
-	for i, tt := range dialErrorTests {
-		c, err := Dial(tt.Net, tt.Raddr)
-		if c != nil {
-			c.Close()
-		}
-		if err == nil {
-			t.Errorf("#%d: nil error, want match for %#q", i, tt.Pattern)
-			continue
-		}
-		s := err.Error()
-		match, _ := regexp.MatchString(tt.Pattern, s)
-		if !match {
-			t.Errorf("#%d: %q, want match for %#q", i, s, tt.Pattern)
-		}
-		match, _ = regexp.MatchString(duplicateErrorPattern, s)
-		if match {
-			t.Errorf("#%d: %q, duplicate error return from Dial", i, s)
-		}
-	}
-}
-
-var invalidDialAndListenArgTests = []struct {
-	net  string
-	addr string
-	err  error
-}{
-	{"foo", "bar", &OpError{Op: "dial", Net: "foo", Addr: nil, Err: UnknownNetworkError("foo")}},
-	{"baz", "", &OpError{Op: "listen", Net: "baz", Addr: nil, Err: UnknownNetworkError("baz")}},
-	{"tcp", "", &OpError{Op: "dial", Net: "tcp", Addr: nil, Err: errMissingAddress}},
-}
-
-func TestInvalidDialAndListenArgs(t *testing.T) {
-	for _, tt := range invalidDialAndListenArgTests {
-		var err error
-		switch tt.err.(*OpError).Op {
-		case "dial":
-			_, err = Dial(tt.net, tt.addr)
-		case "listen":
-			_, err = Listen(tt.net, tt.addr)
-		}
-		if !reflect.DeepEqual(tt.err, err) {
-			t.Fatalf("got %#v; expected %#v", err, tt.err)
-		}
-	}
-}
-
-func TestDialTimeoutFDLeak(t *testing.T) {
-	if runtime.GOOS != "linux" {
-		// TODO(bradfitz): test on other platforms
-		t.Skipf("skipping test on %q", runtime.GOOS)
-	}
-
-	ln := newLocalListener(t)
-	defer ln.Close()
-
-	type connErr struct {
-		conn Conn
-		err  error
-	}
-	dials := listenerBacklog + 100
-	// used to be listenerBacklog + 5, but was found to be unreliable, issue 4384.
-	maxGoodConnect := listenerBacklog + runtime.NumCPU()*10
-	resc := make(chan connErr)
-	for i := 0; i < dials; i++ {
-		go func() {
-			conn, err := DialTimeout("tcp", ln.Addr().String(), 500*time.Millisecond)
-			resc <- connErr{conn, err}
-		}()
-	}
-
-	var firstErr string
-	var ngood int
-	var toClose []io.Closer
-	for i := 0; i < dials; i++ {
-		ce := <-resc
-		if ce.err == nil {
-			ngood++
-			if ngood > maxGoodConnect {
-				t.Errorf("%d good connects; expected at most %d", ngood, maxGoodConnect)
-			}
-			toClose = append(toClose, ce.conn)
-			continue
-		}
-		err := ce.err
-		if firstErr == "" {
-			firstErr = err.Error()
-		} else if err.Error() != firstErr {
-			t.Fatalf("inconsistent error messages: first was %q, then later %q", firstErr, err)
-		}
-	}
-	for _, c := range toClose {
-		c.Close()
-	}
-	for i := 0; i < 100; i++ {
-		if got := numFD(); got < dials {
-			// Test passes.
-			return
-		}
-		time.Sleep(10 * time.Millisecond)
-	}
-	if got := numFD(); got >= dials {
-		t.Errorf("num fds after %d timeouts = %d; want <%d", dials, got, dials)
-	}
-}
-
-func numTCP() (ntcp, nopen, nclose int, err error) {
-	lsof, err := exec.Command("lsof", "-n", "-p", strconv.Itoa(os.Getpid())).Output()
-	if err != nil {
-		return 0, 0, 0, err
-	}
-	ntcp += bytes.Count(lsof, []byte("TCP"))
-	for _, state := range []string{"LISTEN", "SYN_SENT", "SYN_RECEIVED", "ESTABLISHED"} {
-		nopen += bytes.Count(lsof, []byte(state))
-	}
-	for _, state := range []string{"CLOSED", "CLOSE_WAIT", "LAST_ACK", "FIN_WAIT_1", "FIN_WAIT_2", "CLOSING", "TIME_WAIT"} {
-		nclose += bytes.Count(lsof, []byte(state))
-	}
-	return ntcp, nopen, nclose, nil
-}
-
-func TestDialMultiFDLeak(t *testing.T) {
-	if !supportsIPv4 || !supportsIPv6 {
-		t.Skip("neither ipv4 nor ipv6 is supported")
-	}
-
-	halfDeadServer := func(dss *dualStackServer, ln Listener) {
-		for {
-			if c, err := ln.Accept(); err != nil {
-				return
-			} else {
-				// It just keeps established
-				// connections like a half-dead server
-				// does.
-				dss.putConn(c)
-			}
-		}
-	}
-	dss, err := newDualStackServer([]streamListener{
-		{net: "tcp4", addr: "127.0.0.1"},
-		{net: "tcp6", addr: "[::1]"},
-	})
-	if err != nil {
-		t.Fatalf("newDualStackServer failed: %v", err)
-	}
-	defer dss.teardown()
-	if err := dss.buildup(halfDeadServer); err != nil {
-		t.Fatalf("dualStackServer.buildup failed: %v", err)
-	}
-
-	_, before, _, err := numTCP()
-	if err != nil {
-		t.Skipf("skipping test; error finding or running lsof: %v", err)
-	}
-
-	var wg sync.WaitGroup
-	portnum, _, _ := dtoi(dss.port, 0)
-	ras := addrList{
-		// Losers that will fail to connect, see RFC 6890.
-		&TCPAddr{IP: IPv4(198, 18, 0, 254), Port: portnum},
-		&TCPAddr{IP: ParseIP("2001:2::254"), Port: portnum},
-
-		// Winner candidates of this race.
-		&TCPAddr{IP: IPv4(127, 0, 0, 1), Port: portnum},
-		&TCPAddr{IP: IPv6loopback, Port: portnum},
-
-		// Losers that will have established connections.
-		&TCPAddr{IP: IPv4(127, 0, 0, 1), Port: portnum},
-		&TCPAddr{IP: IPv6loopback, Port: portnum},
-	}
-	const T1 = 10 * time.Millisecond
-	const T2 = 2 * T1
-	const N = 10
-	for i := 0; i < N; i++ {
-		wg.Add(1)
-		go func() {
-			defer wg.Done()
-			if c, err := dialMulti("tcp", "fast failover test", nil, ras, time.Now().Add(T1)); err == nil {
-				c.Close()
-			}
-		}()
-	}
-	wg.Wait()
-	time.Sleep(T2)
-
-	ntcp, after, nclose, err := numTCP()
-	if err != nil {
-		t.Skipf("skipping test; error finding or running lsof: %v", err)
-	}
-	t.Logf("tcp sessions: %v, open sessions: %v, closing sessions: %v", ntcp, after, nclose)
-
-	if after != before {
-		t.Fatalf("got %v open sessions; expected %v", after, before)
-	}
-}
-
-func numFD() int {
-	if runtime.GOOS == "linux" {
-		f, err := os.Open("/proc/self/fd")
-		if err != nil {
-			panic(err)
-		}
-		defer f.Close()
-		names, err := f.Readdirnames(0)
-		if err != nil {
-			panic(err)
-		}
-		return len(names)
-	}
-	// All tests using this should be skipped anyway, but:
-	panic("numFDs not implemented on " + runtime.GOOS)
-}
-
-func TestDialer(t *testing.T) {
-	ln, err := Listen("tcp4", "127.0.0.1:0")
-	if err != nil {
-		t.Fatalf("Listen failed: %v", err)
-	}
-	defer ln.Close()
-	ch := make(chan error, 1)
-	go func() {
-		c, err := ln.Accept()
-		if err != nil {
-			ch <- fmt.Errorf("Accept failed: %v", err)
-			return
-		}
-		defer c.Close()
-		ch <- nil
-	}()
-
-	laddr, err := ResolveTCPAddr("tcp4", "127.0.0.1:0")
-	if err != nil {
-		t.Fatalf("ResolveTCPAddr failed: %v", err)
-	}
-	d := &Dialer{LocalAddr: laddr}
-	c, err := d.Dial("tcp4", ln.Addr().String())
-	if err != nil {
-		t.Fatalf("Dial failed: %v", err)
-	}
-	defer c.Close()
-	c.Read(make([]byte, 1))
-	err = <-ch
-	if err != nil {
-		t.Error(err)
-	}
-}
-
-func TestDialDualStackLocalhost(t *testing.T) {
-	if ips, err := LookupIP("localhost"); err != nil {
-		t.Fatalf("LookupIP failed: %v", err)
-	} else if len(ips) < 2 || !supportsIPv4 || !supportsIPv6 {
-		t.Skip("localhost doesn't have a pair of different address family IP addresses")
-	}
-
-	touchAndByeServer := func(dss *dualStackServer, ln Listener) {
-		for {
-			if c, err := ln.Accept(); err != nil {
-				return
-			} else {
-				c.Close()
-			}
-		}
-	}
-	dss, err := newDualStackServer([]streamListener{
-		{net: "tcp4", addr: "127.0.0.1"},
-		{net: "tcp6", addr: "[::1]"},
-	})
-	if err != nil {
-		t.Fatalf("newDualStackServer failed: %v", err)
-	}
-	defer dss.teardown()
-	if err := dss.buildup(touchAndByeServer); err != nil {
-		t.Fatalf("dualStackServer.buildup failed: %v", err)
-	}
-
-	d := &Dialer{DualStack: true}
-	for _ = range dss.lns {
-		if c, err := d.Dial("tcp", "localhost:"+dss.port); err != nil {
-			t.Errorf("Dial failed: %v", err)
-		} else {
-			if addr := c.LocalAddr().(*TCPAddr); addr.IP.To4() != nil {
-				dss.teardownNetwork("tcp4")
-			} else if addr.IP.To16() != nil && addr.IP.To4() == nil {
-				dss.teardownNetwork("tcp6")
-			}
-			c.Close()
-		}
-	}
-}
-
-func TestDialerKeepAlive(t *testing.T) {
-	ln := newLocalListener(t)
-	defer ln.Close()
-	defer func() {
-		testHookSetKeepAlive = func() {}
-	}()
-	go func() {
-		for {
-			c, err := ln.Accept()
-			if err != nil {
-				return
-			}
-			c.Close()
-		}
-	}()
-	for _, keepAlive := range []bool{false, true} {
-		got := false
-		testHookSetKeepAlive = func() { got = true }
-		var d Dialer
-		if keepAlive {
-			d.KeepAlive = 30 * time.Second
-		}
-		c, err := d.Dial("tcp", ln.Addr().String())
-		if err != nil {
-			t.Fatal(err)
-		}
-		c.Close()
-		if got != keepAlive {
-			t.Errorf("Dialer.KeepAlive = %v: SetKeepAlive called = %v, want %v", d.KeepAlive, got, !got)
-		}
-	}
-}
diff --git a/src/pkg/net/dnsclient.go b/src/pkg/net/dnsclient.go
deleted file mode 100644
index 9bffa11..0000000
--- a/src/pkg/net/dnsclient.go
+++ /dev/null
@@ -1,251 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package net
-
-import (
-	"math/rand"
-	"sort"
-)
-
-// DNSError represents a DNS lookup error.
-type DNSError struct {
-	Err       string // description of the error
-	Name      string // name looked for
-	Server    string // server used
-	IsTimeout bool
-}
-
-func (e *DNSError) Error() string {
-	if e == nil {
-		return "<nil>"
-	}
-	s := "lookup " + e.Name
-	if e.Server != "" {
-		s += " on " + e.Server
-	}
-	s += ": " + e.Err
-	return s
-}
-
-func (e *DNSError) Timeout() bool   { return e.IsTimeout }
-func (e *DNSError) Temporary() bool { return e.IsTimeout }
-
-const noSuchHost = "no such host"
-
-// reverseaddr returns the in-addr.arpa. or ip6.arpa. hostname of the IP
-// address addr suitable for rDNS (PTR) record lookup or an error if it fails
-// to parse the IP address.
-func reverseaddr(addr string) (arpa string, err error) {
-	ip := ParseIP(addr)
-	if ip == nil {
-		return "", &DNSError{Err: "unrecognized address", Name: addr}
-	}
-	if ip.To4() != nil {
-		return itoa(int(ip[15])) + "." + itoa(int(ip[14])) + "." + itoa(int(ip[13])) + "." +
-			itoa(int(ip[12])) + ".in-addr.arpa.", nil
-	}
-	// Must be IPv6
-	buf := make([]byte, 0, len(ip)*4+len("ip6.arpa."))
-	// Add it, in reverse, to the buffer
-	for i := len(ip) - 1; i >= 0; i-- {
-		v := ip[i]
-		buf = append(buf, hexDigit[v&0xF])
-		buf = append(buf, '.')
-		buf = append(buf, hexDigit[v>>4])
-		buf = append(buf, '.')
-	}
-	// Append "ip6.arpa." and return (buf already has the final .)
-	buf = append(buf, "ip6.arpa."...)
-	return string(buf), nil
-}
-
-// Find answer for name in dns message.
-// On return, if err == nil, addrs != nil.
-func answer(name, server string, dns *dnsMsg, qtype uint16) (cname string, addrs []dnsRR, err error) {
-	addrs = make([]dnsRR, 0, len(dns.answer))
-
-	if dns.rcode == dnsRcodeNameError && dns.recursion_available {
-		return "", nil, &DNSError{Err: noSuchHost, Name: name}
-	}
-	if dns.rcode != dnsRcodeSuccess {
-		// None of the error codes make sense
-		// for the query we sent.  If we didn't get
-		// a name error and we didn't get success,
-		// the server is behaving incorrectly.
-		return "", nil, &DNSError{Err: "server misbehaving", Name: name, Server: server}
-	}
-
-	// Look for the name.
-	// Presotto says it's okay to assume that servers listed in
-	// /etc/resolv.conf are recursive resolvers.
-	// We asked for recursion, so it should have included
-	// all the answers we need in this one packet.
-Cname:
-	for cnameloop := 0; cnameloop < 10; cnameloop++ {
-		addrs = addrs[0:0]
-		for _, rr := range dns.answer {
-			if _, justHeader := rr.(*dnsRR_Header); justHeader {
-				// Corrupt record: we only have a
-				// header. That header might say it's
-				// of type qtype, but we don't
-				// actually have it. Skip.
-				continue
-			}
-			h := rr.Header()
-			if h.Class == dnsClassINET && h.Name == name {
-				switch h.Rrtype {
-				case qtype:
-					addrs = append(addrs, rr)
-				case dnsTypeCNAME:
-					// redirect to cname
-					name = rr.(*dnsRR_CNAME).Cname
-					continue Cname
-				}
-			}
-		}
-		if len(addrs) == 0 {
-			return "", nil, &DNSError{Err: noSuchHost, Name: name, Server: server}
-		}
-		return name, addrs, nil
-	}
-
-	return "", nil, &DNSError{Err: "too many redirects", Name: name, Server: server}
-}
-
-func isDomainName(s string) bool {
-	// See RFC 1035, RFC 3696.
-	if len(s) == 0 {
-		return false
-	}
-	if len(s) > 255 {
-		return false
-	}
-
-	last := byte('.')
-	ok := false // Ok once we've seen a letter.
-	partlen := 0
-	for i := 0; i < len(s); i++ {
-		c := s[i]
-		switch {
-		default:
-			return false
-		case 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' || c == '_':
-			ok = true
-			partlen++
-		case '0' <= c && c <= '9':
-			// fine
-			partlen++
-		case c == '-':
-			// Byte before dash cannot be dot.
-			if last == '.' {
-				return false
-			}
-			partlen++
-		case c == '.':
-			// Byte before dot cannot be dot, dash.
-			if last == '.' || last == '-' {
-				return false
-			}
-			if partlen > 63 || partlen == 0 {
-				return false
-			}
-			partlen = 0
-		}
-		last = c
-	}
-	if last == '-' || partlen > 63 {
-		return false
-	}
-
-	return ok
-}
-
-// An SRV represents a single DNS SRV record.
-type SRV struct {
-	Target   string
-	Port     uint16
-	Priority uint16
-	Weight   uint16
-}
-
-// byPriorityWeight sorts SRV records by ascending priority and weight.
-type byPriorityWeight []*SRV
-
-func (s byPriorityWeight) Len() int { return len(s) }
-
-func (s byPriorityWeight) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
-
-func (s byPriorityWeight) Less(i, j int) bool {
-	return s[i].Priority < s[j].Priority ||
-		(s[i].Priority == s[j].Priority && s[i].Weight < s[j].Weight)
-}
-
-// shuffleByWeight shuffles SRV records by weight using the algorithm
-// described in RFC 2782.
-func (addrs byPriorityWeight) shuffleByWeight() {
-	sum := 0
-	for _, addr := range addrs {
-		sum += int(addr.Weight)
-	}
-	for sum > 0 && len(addrs) > 1 {
-		s := 0
-		n := rand.Intn(sum)
-		for i := range addrs {
-			s += int(addrs[i].Weight)
-			if s > n {
-				if i > 0 {
-					t := addrs[i]
-					copy(addrs[1:i+1], addrs[0:i])
-					addrs[0] = t
-				}
-				break
-			}
-		}
-		sum -= int(addrs[0].Weight)
-		addrs = addrs[1:]
-	}
-}
-
-// sort reorders SRV records as specified in RFC 2782.
-func (addrs byPriorityWeight) sort() {
-	sort.Sort(addrs)
-	i := 0
-	for j := 1; j < len(addrs); j++ {
-		if addrs[i].Priority != addrs[j].Priority {
-			addrs[i:j].shuffleByWeight()
-			i = j
-		}
-	}
-	addrs[i:].shuffleByWeight()
-}
-
-// An MX represents a single DNS MX record.
-type MX struct {
-	Host string
-	Pref uint16
-}
-
-// byPref implements sort.Interface to sort MX records by preference
-type byPref []*MX
-
-func (s byPref) Len() int { return len(s) }
-
-func (s byPref) Less(i, j int) bool { return s[i].Pref < s[j].Pref }
-
-func (s byPref) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
-
-// sort reorders MX records as specified in RFC 5321.
-func (s byPref) sort() {
-	for i := range s {
-		j := rand.Intn(i + 1)
-		s[i], s[j] = s[j], s[i]
-	}
-	sort.Sort(s)
-}
-
-// An NS represents a single DNS NS record.
-type NS struct {
-	Host string
-}
diff --git a/src/pkg/net/dnsclient_unix.go b/src/pkg/net/dnsclient_unix.go
deleted file mode 100644
index 3713efd..0000000
--- a/src/pkg/net/dnsclient_unix.go
+++ /dev/null
@@ -1,364 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris
-
-// DNS client: see RFC 1035.
-// Has to be linked into package net for Dial.
-
-// TODO(rsc):
-//	Could potentially handle many outstanding lookups faster.
-//	Could have a small cache.
-//	Random UDP source port (net.Dial should do that for us).
-//	Random request IDs.
-
-package net
-
-import (
-	"io"
-	"math/rand"
-	"os"
-	"sync"
-	"time"
-)
-
-// Send a request on the connection and hope for a reply.
-// Up to cfg.attempts attempts.
-func exchange(cfg *dnsConfig, c Conn, name string, qtype uint16) (*dnsMsg, error) {
-	_, useTCP := c.(*TCPConn)
-	if len(name) >= 256 {
-		return nil, &DNSError{Err: "name too long", Name: name}
-	}
-	out := new(dnsMsg)
-	out.id = uint16(rand.Int()) ^ uint16(time.Now().UnixNano())
-	out.question = []dnsQuestion{
-		{name, qtype, dnsClassINET},
-	}
-	out.recursion_desired = true
-	msg, ok := out.Pack()
-	if !ok {
-		return nil, &DNSError{Err: "internal error - cannot pack message", Name: name}
-	}
-	if useTCP {
-		mlen := uint16(len(msg))
-		msg = append([]byte{byte(mlen >> 8), byte(mlen)}, msg...)
-	}
-	for attempt := 0; attempt < cfg.attempts; attempt++ {
-		n, err := c.Write(msg)
-		if err != nil {
-			return nil, err
-		}
-
-		if cfg.timeout == 0 {
-			c.SetReadDeadline(noDeadline)
-		} else {
-			c.SetReadDeadline(time.Now().Add(time.Duration(cfg.timeout) * time.Second))
-		}
-		buf := make([]byte, 2000)
-		if useTCP {
-			n, err = io.ReadFull(c, buf[:2])
-			if err != nil {
-				if e, ok := err.(Error); ok && e.Timeout() {
-					continue
-				}
-			}
-			mlen := int(buf[0])<<8 | int(buf[1])
-			if mlen > len(buf) {
-				buf = make([]byte, mlen)
-			}
-			n, err = io.ReadFull(c, buf[:mlen])
-		} else {
-			n, err = c.Read(buf)
-		}
-		if err != nil {
-			if e, ok := err.(Error); ok && e.Timeout() {
-				continue
-			}
-			return nil, err
-		}
-		buf = buf[:n]
-		in := new(dnsMsg)
-		if !in.Unpack(buf) || in.id != out.id {
-			continue
-		}
-		return in, nil
-	}
-	var server string
-	if a := c.RemoteAddr(); a != nil {
-		server = a.String()
-	}
-	return nil, &DNSError{Err: "no answer from server", Name: name, Server: server, IsTimeout: true}
-}
-
-// Do a lookup for a single name, which must be rooted
-// (otherwise answer will not find the answers).
-func tryOneName(cfg *dnsConfig, name string, qtype uint16) (cname string, addrs []dnsRR, err error) {
-	if len(cfg.servers) == 0 {
-		return "", nil, &DNSError{Err: "no DNS servers", Name: name}
-	}
-	for i := 0; i < len(cfg.servers); i++ {
-		// Calling Dial here is scary -- we have to be sure
-		// not to dial a name that will require a DNS lookup,
-		// or Dial will call back here to translate it.
-		// The DNS config parser has already checked that
-		// all the cfg.servers[i] are IP addresses, which
-		// Dial will use without a DNS lookup.
-		server := cfg.servers[i] + ":53"
-		c, cerr := Dial("udp", server)
-		if cerr != nil {
-			err = cerr
-			continue
-		}
-		msg, merr := exchange(cfg, c, name, qtype)
-		c.Close()
-		if merr != nil {
-			err = merr
-			continue
-		}
-		if msg.truncated { // see RFC 5966
-			c, cerr = Dial("tcp", server)
-			if cerr != nil {
-				err = cerr
-				continue
-			}
-			msg, merr = exchange(cfg, c, name, qtype)
-			c.Close()
-			if merr != nil {
-				err = merr
-				continue
-			}
-		}
-		cname, addrs, err = answer(name, server, msg, qtype)
-		if err == nil || err.(*DNSError).Err == noSuchHost {
-			break
-		}
-	}
-	return
-}
-
-func convertRR_A(records []dnsRR) []IP {
-	addrs := make([]IP, len(records))
-	for i, rr := range records {
-		a := rr.(*dnsRR_A).A
-		addrs[i] = IPv4(byte(a>>24), byte(a>>16), byte(a>>8), byte(a))
-	}
-	return addrs
-}
-
-func convertRR_AAAA(records []dnsRR) []IP {
-	addrs := make([]IP, len(records))
-	for i, rr := range records {
-		a := make(IP, IPv6len)
-		copy(a, rr.(*dnsRR_AAAA).AAAA[:])
-		addrs[i] = a
-	}
-	return addrs
-}
-
-var cfg struct {
-	ch        chan struct{}
-	mu        sync.RWMutex // protects dnsConfig and dnserr
-	dnsConfig *dnsConfig
-	dnserr    error
-}
-var onceLoadConfig sync.Once
-
-// Assume dns config file is /etc/resolv.conf here
-func loadDefaultConfig() {
-	loadConfig("/etc/resolv.conf", 5*time.Second, nil)
-}
-
-func loadConfig(resolvConfPath string, reloadTime time.Duration, quit <-chan chan struct{}) {
-	var mtime time.Time
-	cfg.ch = make(chan struct{}, 1)
-	if fi, err := os.Stat(resolvConfPath); err != nil {
-		cfg.dnserr = err
-	} else {
-		mtime = fi.ModTime()
-		cfg.dnsConfig, cfg.dnserr = dnsReadConfig(resolvConfPath)
-	}
-	go func() {
-		for {
-			time.Sleep(reloadTime)
-			select {
-			case qresp := <-quit:
-				qresp <- struct{}{}
-				return
-			case <-cfg.ch:
-			}
-
-			// In case of error, we keep the previous config
-			fi, err := os.Stat(resolvConfPath)
-			if err != nil {
-				continue
-			}
-			// If the resolv.conf mtime didn't change, do not reload
-			m := fi.ModTime()
-			if m.Equal(mtime) {
-				continue
-			}
-			mtime = m
-			// In case of error, we keep the previous config
-			ncfg, err := dnsReadConfig(resolvConfPath)
-			if err != nil || len(ncfg.servers) == 0 {
-				continue
-			}
-			cfg.mu.Lock()
-			cfg.dnsConfig = ncfg
-			cfg.dnserr = nil
-			cfg.mu.Unlock()
-		}
-	}()
-}
-
-func lookup(name string, qtype uint16) (cname string, addrs []dnsRR, err error) {
-	if !isDomainName(name) {
-		return name, nil, &DNSError{Err: "invalid domain name", Name: name}
-	}
-	onceLoadConfig.Do(loadDefaultConfig)
-
-	select {
-	case cfg.ch <- struct{}{}:
-	default:
-	}
-
-	cfg.mu.RLock()
-	defer cfg.mu.RUnlock()
-
-	if cfg.dnserr != nil || cfg.dnsConfig == nil {
-		err = cfg.dnserr
-		return
-	}
-	// If name is rooted (trailing dot) or has enough dots,
-	// try it by itself first.
-	rooted := len(name) > 0 && name[len(name)-1] == '.'
-	if rooted || count(name, '.') >= cfg.dnsConfig.ndots {
-		rname := name
-		if !rooted {
-			rname += "."
-		}
-		// Can try as ordinary name.
-		cname, addrs, err = tryOneName(cfg.dnsConfig, rname, qtype)
-		if err == nil {
-			return
-		}
-	}
-	if rooted {
-		return
-	}
-
-	// Otherwise, try suffixes.
-	for i := 0; i < len(cfg.dnsConfig.search); i++ {
-		rname := name + "." + cfg.dnsConfig.search[i]
-		if rname[len(rname)-1] != '.' {
-			rname += "."
-		}
-		cname, addrs, err = tryOneName(cfg.dnsConfig, rname, qtype)
-		if err == nil {
-			return
-		}
-	}
-
-	// Last ditch effort: try unsuffixed.
-	rname := name
-	if !rooted {
-		rname += "."
-	}
-	cname, addrs, err = tryOneName(cfg.dnsConfig, rname, qtype)
-	if err == nil {
-		return
-	}
-	if e, ok := err.(*DNSError); ok {
-		// Show original name passed to lookup, not suffixed one.
-		// In general we might have tried many suffixes; showing
-		// just one is misleading. See also golang.org/issue/6324.
-		e.Name = name
-	}
-	return
-}
-
-// goLookupHost is the native Go implementation of LookupHost.
-// Used only if cgoLookupHost refuses to handle the request
-// (that is, only if cgoLookupHost is the stub in cgo_stub.go).
-// Normally we let cgo use the C library resolver instead of
-// depending on our lookup code, so that Go and C get the same
-// answers.
-func goLookupHost(name string) (addrs []string, err error) {
-	// Use entries from /etc/hosts if they match.
-	addrs = lookupStaticHost(name)
-	if len(addrs) > 0 {
-		return
-	}
-	ips, err := goLookupIP(name)
-	if err != nil {
-		return
-	}
-	addrs = make([]string, 0, len(ips))
-	for _, ip := range ips {
-		addrs = append(addrs, ip.String())
-	}
-	return
-}
-
-// goLookupIP is the native Go implementation of LookupIP.
-// Used only if cgoLookupIP refuses to handle the request
-// (that is, only if cgoLookupIP is the stub in cgo_stub.go).
-// Normally we let cgo use the C library resolver instead of
-// depending on our lookup code, so that Go and C get the same
-// answers.
-func goLookupIP(name string) (addrs []IP, err error) {
-	// Use entries from /etc/hosts if possible.
-	haddrs := lookupStaticHost(name)
-	if len(haddrs) > 0 {
-		for _, haddr := range haddrs {
-			if ip := ParseIP(haddr); ip != nil {
-				addrs = append(addrs, ip)
-			}
-		}
-		if len(addrs) > 0 {
-			return
-		}
-	}
-	var records []dnsRR
-	var cname string
-	var err4, err6 error
-	cname, records, err4 = lookup(name, dnsTypeA)
-	addrs = convertRR_A(records)
-	if cname != "" {
-		name = cname
-	}
-	_, records, err6 = lookup(name, dnsTypeAAAA)
-	if err4 != nil && err6 == nil {
-		// Ignore A error because AAAA lookup succeeded.
-		err4 = nil
-	}
-	if err6 != nil && len(addrs) > 0 {
-		// Ignore AAAA error because A lookup succeeded.
-		err6 = nil
-	}
-	if err4 != nil {
-		return nil, err4
-	}
-	if err6 != nil {
-		return nil, err6
-	}
-
-	addrs = append(addrs, convertRR_AAAA(records)...)
-	return addrs, nil
-}
-
-// goLookupCNAME is the native Go implementation of LookupCNAME.
-// Used only if cgoLookupCNAME refuses to handle the request
-// (that is, only if cgoLookupCNAME is the stub in cgo_stub.go).
-// Normally we let cgo use the C library resolver instead of
-// depending on our lookup code, so that Go and C get the same
-// answers.
-func goLookupCNAME(name string) (cname string, err error) {
-	_, rr, err := lookup(name, dnsTypeCNAME)
-	if err != nil {
-		return
-	}
-	cname = rr[0].(*dnsRR_CNAME).Cname
-	return
-}
diff --git a/src/pkg/net/dnsclient_unix_test.go b/src/pkg/net/dnsclient_unix_test.go
deleted file mode 100644
index 2350142..0000000
--- a/src/pkg/net/dnsclient_unix_test.go
+++ /dev/null
@@ -1,159 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build darwin dragonfly freebsd linux netbsd openbsd solaris
-
-package net
-
-import (
-	"io"
-	"io/ioutil"
-	"os"
-	"path"
-	"reflect"
-	"testing"
-	"time"
-)
-
-func TestTCPLookup(t *testing.T) {
-	if testing.Short() || !*testExternal {
-		t.Skip("skipping test to avoid external network")
-	}
-	c, err := Dial("tcp", "8.8.8.8:53")
-	if err != nil {
-		t.Fatalf("Dial failed: %v", err)
-	}
-	defer c.Close()
-	cfg := &dnsConfig{timeout: 10, attempts: 3}
-	_, err = exchange(cfg, c, "com.", dnsTypeALL)
-	if err != nil {
-		t.Fatalf("exchange failed: %v", err)
-	}
-}
-
-type resolvConfTest struct {
-	*testing.T
-	dir     string
-	path    string
-	started bool
-	quitc   chan chan struct{}
-}
-
-func newResolvConfTest(t *testing.T) *resolvConfTest {
-	dir, err := ioutil.TempDir("", "resolvConfTest")
-	if err != nil {
-		t.Fatalf("could not create temp dir: %v", err)
-	}
-
-	// Disable the default loadConfig
-	onceLoadConfig.Do(func() {})
-
-	r := &resolvConfTest{
-		T:     t,
-		dir:   dir,
-		path:  path.Join(dir, "resolv.conf"),
-		quitc: make(chan chan struct{}),
-	}
-
-	return r
-}
-
-func (r *resolvConfTest) Start() {
-	loadConfig(r.path, 100*time.Millisecond, r.quitc)
-	r.started = true
-}
-
-func (r *resolvConfTest) SetConf(s string) {
-	// Make sure the file mtime will be different once we're done here,
-	// even on systems with coarse (1s) mtime resolution.
-	time.Sleep(time.Second)
-
-	f, err := os.OpenFile(r.path, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0600)
-	if err != nil {
-		r.Fatalf("failed to create temp file %s: %v", r.path, err)
-	}
-	if _, err := io.WriteString(f, s); err != nil {
-		f.Close()
-		r.Fatalf("failed to write temp file: %v", err)
-	}
-	f.Close()
-
-	if r.started {
-		cfg.ch <- struct{}{} // fill buffer
-		cfg.ch <- struct{}{} // wait for reload to begin
-		cfg.ch <- struct{}{} // wait for reload to complete
-	}
-}
-
-func (r *resolvConfTest) WantServers(want []string) {
-	cfg.mu.RLock()
-	defer cfg.mu.RUnlock()
-	if got := cfg.dnsConfig.servers; !reflect.DeepEqual(got, want) {
-		r.Fatalf("Unexpected dns server loaded, got %v want %v", got, want)
-	}
-}
-
-func (r *resolvConfTest) Close() {
-	resp := make(chan struct{})
-	r.quitc <- resp
-	<-resp
-	if err := os.RemoveAll(r.dir); err != nil {
-		r.Logf("failed to remove temp dir %s: %v", r.dir, err)
-	}
-}
-
-func TestReloadResolvConfFail(t *testing.T) {
-	if testing.Short() || !*testExternal {
-		t.Skip("skipping test to avoid external network")
-	}
-
-	r := newResolvConfTest(t)
-	defer r.Close()
-
-	// resolv.conf.tmp does not exist yet
-	r.Start()
-	if _, err := goLookupIP("golang.org"); err == nil {
-		t.Fatal("goLookupIP(missing) succeeded")
-	}
-
-	r.SetConf("nameserver 8.8.8.8")
-	if _, err := goLookupIP("golang.org"); err != nil {
-		t.Fatalf("goLookupIP(missing; good) failed: %v", err)
-	}
-
-	// Using a bad resolv.conf while we had a good
-	// one before should not update the config
-	r.SetConf("")
-	if _, err := goLookupIP("golang.org"); err != nil {
-		t.Fatalf("goLookupIP(missing; good; bad) failed: %v", err)
-	}
-}
-
-func TestReloadResolvConfChange(t *testing.T) {
-	if testing.Short() || !*testExternal {
-		t.Skip("skipping test to avoid external network")
-	}
-
-	r := newResolvConfTest(t)
-	defer r.Close()
-
-	r.SetConf("nameserver 8.8.8.8")
-	r.Start()
-
-	if _, err := goLookupIP("golang.org"); err != nil {
-		t.Fatalf("goLookupIP(good) failed: %v", err)
-	}
-	r.WantServers([]string{"[8.8.8.8]"})
-
-	// Using a bad resolv.conf when we had a good one
-	// before should not update the config
-	r.SetConf("")
-	if _, err := goLookupIP("golang.org"); err != nil {
-		t.Fatalf("goLookupIP(good; bad) failed: %v", err)
-	}
-
-	// A new good config should get picked up
-	r.SetConf("nameserver 8.8.4.4")
-	r.WantServers([]string{"[8.8.4.4]"})
-}
diff --git a/src/pkg/net/dnsconfig_unix.go b/src/pkg/net/dnsconfig_unix.go
deleted file mode 100644
index db45716..0000000
--- a/src/pkg/net/dnsconfig_unix.go
+++ /dev/null
@@ -1,109 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris
-
-// Read system DNS config from /etc/resolv.conf
-
-package net
-
-type dnsConfig struct {
-	servers  []string // servers to use
-	search   []string // suffixes to append to local name
-	ndots    int      // number of dots in name to trigger absolute lookup
-	timeout  int      // seconds before giving up on packet
-	attempts int      // lost packets before giving up on server
-	rotate   bool     // round robin among servers
-}
-
-// See resolv.conf(5) on a Linux machine.
-// TODO(rsc): Supposed to call uname() and chop the beginning
-// of the host name to get the default search domain.
-func dnsReadConfig(filename string) (*dnsConfig, error) {
-	file, err := open(filename)
-	if err != nil {
-		return nil, &DNSConfigError{err}
-	}
-	conf := new(dnsConfig)
-	conf.servers = make([]string, 0, 3) // small, but the standard limit
-	conf.search = make([]string, 0)
-	conf.ndots = 1
-	conf.timeout = 5
-	conf.attempts = 2
-	conf.rotate = false
-	for line, ok := file.readLine(); ok; line, ok = file.readLine() {
-		f := getFields(line)
-		if len(f) < 1 {
-			continue
-		}
-		switch f[0] {
-		case "nameserver": // add one name server
-			a := conf.servers
-			n := len(a)
-			if len(f) > 1 && n < cap(a) {
-				// One more check: make sure server name is
-				// just an IP address.  Otherwise we need DNS
-				// to look it up.
-				name := f[1]
-				switch len(ParseIP(name)) {
-				case 16:
-					name = "[" + name + "]"
-					fallthrough
-				case 4:
-					a = a[0 : n+1]
-					a[n] = name
-					conf.servers = a
-				}
-			}
-
-		case "domain": // set search path to just this domain
-			if len(f) > 1 {
-				conf.search = make([]string, 1)
-				conf.search[0] = f[1]
-			} else {
-				conf.search = make([]string, 0)
-			}
-
-		case "search": // set search path to given servers
-			conf.search = make([]string, len(f)-1)
-			for i := 0; i < len(conf.search); i++ {
-				conf.search[i] = f[i+1]
-			}
-
-		case "options": // magic options
-			for i := 1; i < len(f); i++ {
-				s := f[i]
-				switch {
-				case hasPrefix(s, "ndots:"):
-					n, _, _ := dtoi(s, 6)
-					if n < 1 {
-						n = 1
-					}
-					conf.ndots = n
-				case hasPrefix(s, "timeout:"):
-					n, _, _ := dtoi(s, 8)
-					if n < 1 {
-						n = 1
-					}
-					conf.timeout = n
-				case hasPrefix(s, "attempts:"):
-					n, _, _ := dtoi(s, 9)
-					if n < 1 {
-						n = 1
-					}
-					conf.attempts = n
-				case s == "rotate":
-					conf.rotate = true
-				}
-			}
-		}
-	}
-	file.close()
-
-	return conf, nil
-}
-
-func hasPrefix(s, prefix string) bool {
-	return len(s) >= len(prefix) && s[:len(prefix)] == prefix
-}
diff --git a/src/pkg/net/dnsconfig_unix_test.go b/src/pkg/net/dnsconfig_unix_test.go
deleted file mode 100644
index 37ed493..0000000
--- a/src/pkg/net/dnsconfig_unix_test.go
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build darwin dragonfly freebsd linux netbsd openbsd solaris
-
-package net
-
-import "testing"
-
-func TestDNSReadConfig(t *testing.T) {
-	dnsConfig, err := dnsReadConfig("testdata/resolv.conf")
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	if len(dnsConfig.servers) != 1 {
-		t.Errorf("len(dnsConfig.servers) = %d; want %d", len(dnsConfig.servers), 1)
-	}
-	if dnsConfig.servers[0] != "[192.168.1.1]" {
-		t.Errorf("dnsConfig.servers[0] = %s; want %s", dnsConfig.servers[0], "[192.168.1.1]")
-	}
-
-	if len(dnsConfig.search) != 1 {
-		t.Errorf("len(dnsConfig.search) = %d; want %d", len(dnsConfig.search), 1)
-	}
-	if dnsConfig.search[0] != "Home" {
-		t.Errorf("dnsConfig.search[0] = %s; want %s", dnsConfig.search[0], "Home")
-	}
-
-	if dnsConfig.ndots != 5 {
-		t.Errorf("dnsConfig.ndots = %d; want %d", dnsConfig.ndots, 5)
-	}
-
-	if dnsConfig.timeout != 10 {
-		t.Errorf("dnsConfig.timeout = %d; want %d", dnsConfig.timeout, 10)
-	}
-
-	if dnsConfig.attempts != 3 {
-		t.Errorf("dnsConfig.attempts = %d; want %d", dnsConfig.attempts, 3)
-	}
-
-	if dnsConfig.rotate != true {
-		t.Errorf("dnsConfig.rotate = %t; want %t", dnsConfig.rotate, true)
-	}
-}
diff --git a/src/pkg/net/empty.c b/src/pkg/net/empty.c
deleted file mode 100644
index a515c2f..0000000
--- a/src/pkg/net/empty.c
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// This file is required to prevent compiler errors
-// when the package built with CGO_ENABLED=0.
-// Otherwise the compiler says:
-// pkg/net/fd_poll_runtime.go:15: missing function body
diff --git a/src/pkg/net/fd_unix.go b/src/pkg/net/fd_unix.go
deleted file mode 100644
index e22861a..0000000
--- a/src/pkg/net/fd_unix.go
+++ /dev/null
@@ -1,518 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris
-
-package net
-
-import (
-	"io"
-	"os"
-	"runtime"
-	"sync/atomic"
-	"syscall"
-	"time"
-)
-
-// Network file descriptor.
-type netFD struct {
-	// locking/lifetime of sysfd + serialize access to Read and Write methods
-	fdmu fdMutex
-
-	// immutable until Close
-	sysfd       int
-	family      int
-	sotype      int
-	isConnected bool
-	net         string
-	laddr       Addr
-	raddr       Addr
-
-	// wait server
-	pd pollDesc
-}
-
-func sysInit() {
-}
-
-func dial(network string, ra Addr, dialer func(time.Time) (Conn, error), deadline time.Time) (Conn, error) {
-	return dialer(deadline)
-}
-
-func newFD(sysfd, family, sotype int, net string) (*netFD, error) {
-	return &netFD{sysfd: sysfd, family: family, sotype: sotype, net: net}, nil
-}
-
-func (fd *netFD) init() error {
-	if err := fd.pd.Init(fd); err != nil {
-		return err
-	}
-	return nil
-}
-
-func (fd *netFD) setAddr(laddr, raddr Addr) {
-	fd.laddr = laddr
-	fd.raddr = raddr
-	runtime.SetFinalizer(fd, (*netFD).Close)
-}
-
-func (fd *netFD) name() string {
-	var ls, rs string
-	if fd.laddr != nil {
-		ls = fd.laddr.String()
-	}
-	if fd.raddr != nil {
-		rs = fd.raddr.String()
-	}
-	return fd.net + ":" + ls + "->" + rs
-}
-
-func (fd *netFD) connect(la, ra syscall.Sockaddr, deadline time.Time) error {
-	// Do not need to call fd.writeLock here,
-	// because fd is not yet accessible to user,
-	// so no concurrent operations are possible.
-	switch err := syscall.Connect(fd.sysfd, ra); err {
-	case syscall.EINPROGRESS, syscall.EALREADY, syscall.EINTR:
-	case nil, syscall.EISCONN:
-		if !deadline.IsZero() && deadline.Before(time.Now()) {
-			return errTimeout
-		}
-		if err := fd.init(); err != nil {
-			return err
-		}
-		return nil
-	case syscall.EINVAL:
-		// On Solaris we can see EINVAL if the socket has
-		// already been accepted and closed by the server.
-		// Treat this as a successful connection--writes to
-		// the socket will see EOF.  For details and a test
-		// case in C see http://golang.org/issue/6828.
-		if runtime.GOOS == "solaris" {
-			return nil
-		}
-		fallthrough
-	default:
-		return err
-	}
-	if err := fd.init(); err != nil {
-		return err
-	}
-	if !deadline.IsZero() {
-		fd.setWriteDeadline(deadline)
-		defer fd.setWriteDeadline(noDeadline)
-	}
-	for {
-		// Performing multiple connect system calls on a
-		// non-blocking socket under Unix variants does not
-		// necessarily result in earlier errors being
-		// returned. Instead, once runtime-integrated network
-		// poller tells us that the socket is ready, get the
-		// SO_ERROR socket option to see if the connection
-		// succeeded or failed. See issue 7474 for further
-		// details.
-		if err := fd.pd.WaitWrite(); err != nil {
-			return err
-		}
-		nerr, err := syscall.GetsockoptInt(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_ERROR)
-		if err != nil {
-			return err
-		}
-		switch err := syscall.Errno(nerr); err {
-		case syscall.EINPROGRESS, syscall.EALREADY, syscall.EINTR:
-		case syscall.Errno(0), syscall.EISCONN:
-			return nil
-		default:
-			return err
-		}
-	}
-}
-
-func (fd *netFD) destroy() {
-	// Poller may want to unregister fd in readiness notification mechanism,
-	// so this must be executed before closesocket.
-	fd.pd.Close()
-	closesocket(fd.sysfd)
-	fd.sysfd = -1
-	runtime.SetFinalizer(fd, nil)
-}
-
-// Add a reference to this fd.
-// Returns an error if the fd cannot be used.
-func (fd *netFD) incref() error {
-	if !fd.fdmu.Incref() {
-		return errClosing
-	}
-	return nil
-}
-
-// Remove a reference to this FD and close if we've been asked to do so
-// (and there are no references left).
-func (fd *netFD) decref() {
-	if fd.fdmu.Decref() {
-		fd.destroy()
-	}
-}
-
-// Add a reference to this fd and lock for reading.
-// Returns an error if the fd cannot be used.
-func (fd *netFD) readLock() error {
-	if !fd.fdmu.RWLock(true) {
-		return errClosing
-	}
-	return nil
-}
-
-// Unlock for reading and remove a reference to this FD.
-func (fd *netFD) readUnlock() {
-	if fd.fdmu.RWUnlock(true) {
-		fd.destroy()
-	}
-}
-
-// Add a reference to this fd and lock for writing.
-// Returns an error if the fd cannot be used.
-func (fd *netFD) writeLock() error {
-	if !fd.fdmu.RWLock(false) {
-		return errClosing
-	}
-	return nil
-}
-
-// Unlock for writing and remove a reference to this FD.
-func (fd *netFD) writeUnlock() {
-	if fd.fdmu.RWUnlock(false) {
-		fd.destroy()
-	}
-}
-
-func (fd *netFD) Close() error {
-	fd.pd.Lock() // needed for both fd.incref(true) and pollDesc.Evict
-	if !fd.fdmu.IncrefAndClose() {
-		fd.pd.Unlock()
-		return errClosing
-	}
-	// Unblock any I/O.  Once it all unblocks and returns,
-	// so that it cannot be referring to fd.sysfd anymore,
-	// the final decref will close fd.sysfd.  This should happen
-	// fairly quickly, since all the I/O is non-blocking, and any
-	// attempts to block in the pollDesc will return errClosing.
-	doWakeup := fd.pd.Evict()
-	fd.pd.Unlock()
-	fd.decref()
-	if doWakeup {
-		fd.pd.Wakeup()
-	}
-	return nil
-}
-
-func (fd *netFD) shutdown(how int) error {
-	if err := fd.incref(); err != nil {
-		return err
-	}
-	defer fd.decref()
-	err := syscall.Shutdown(fd.sysfd, how)
-	if err != nil {
-		return &OpError{"shutdown", fd.net, fd.laddr, err}
-	}
-	return nil
-}
-
-func (fd *netFD) closeRead() error {
-	return fd.shutdown(syscall.SHUT_RD)
-}
-
-func (fd *netFD) closeWrite() error {
-	return fd.shutdown(syscall.SHUT_WR)
-}
-
-func (fd *netFD) Read(p []byte) (n int, err error) {
-	if err := fd.readLock(); err != nil {
-		return 0, err
-	}
-	defer fd.readUnlock()
-	if err := fd.pd.PrepareRead(); err != nil {
-		return 0, &OpError{"read", fd.net, fd.raddr, err}
-	}
-	for {
-		n, err = syscall.Read(int(fd.sysfd), p)
-		if err != nil {
-			n = 0
-			if err == syscall.EAGAIN {
-				if err = fd.pd.WaitRead(); err == nil {
-					continue
-				}
-			}
-		}
-		err = chkReadErr(n, err, fd)
-		break
-	}
-	if err != nil && err != io.EOF {
-		err = &OpError{"read", fd.net, fd.raddr, err}
-	}
-	return
-}
-
-func (fd *netFD) readFrom(p []byte) (n int, sa syscall.Sockaddr, err error) {
-	if err := fd.readLock(); err != nil {
-		return 0, nil, err
-	}
-	defer fd.readUnlock()
-	if err := fd.pd.PrepareRead(); err != nil {
-		return 0, nil, &OpError{"read", fd.net, fd.laddr, err}
-	}
-	for {
-		n, sa, err = syscall.Recvfrom(fd.sysfd, p, 0)
-		if err != nil {
-			n = 0
-			if err == syscall.EAGAIN {
-				if err = fd.pd.WaitRead(); err == nil {
-					continue
-				}
-			}
-		}
-		err = chkReadErr(n, err, fd)
-		break
-	}
-	if err != nil && err != io.EOF {
-		err = &OpError{"read", fd.net, fd.laddr, err}
-	}
-	return
-}
-
-func (fd *netFD) readMsg(p []byte, oob []byte) (n, oobn, flags int, sa syscall.Sockaddr, err error) {
-	if err := fd.readLock(); err != nil {
-		return 0, 0, 0, nil, err
-	}
-	defer fd.readUnlock()
-	if err := fd.pd.PrepareRead(); err != nil {
-		return 0, 0, 0, nil, &OpError{"read", fd.net, fd.laddr, err}
-	}
-	for {
-		n, oobn, flags, sa, err = syscall.Recvmsg(fd.sysfd, p, oob, 0)
-		if err != nil {
-			// TODO(dfc) should n and oobn be set to 0
-			if err == syscall.EAGAIN {
-				if err = fd.pd.WaitRead(); err == nil {
-					continue
-				}
-			}
-		}
-		err = chkReadErr(n, err, fd)
-		break
-	}
-	if err != nil && err != io.EOF {
-		err = &OpError{"read", fd.net, fd.laddr, err}
-	}
-	return
-}
-
-func chkReadErr(n int, err error, fd *netFD) error {
-	if n == 0 && err == nil && fd.sotype != syscall.SOCK_DGRAM && fd.sotype != syscall.SOCK_RAW {
-		return io.EOF
-	}
-	return err
-}
-
-func (fd *netFD) Write(p []byte) (nn int, err error) {
-	if err := fd.writeLock(); err != nil {
-		return 0, err
-	}
-	defer fd.writeUnlock()
-	if err := fd.pd.PrepareWrite(); err != nil {
-		return 0, &OpError{"write", fd.net, fd.raddr, err}
-	}
-	for {
-		var n int
-		n, err = syscall.Write(int(fd.sysfd), p[nn:])
-		if n > 0 {
-			nn += n
-		}
-		if nn == len(p) {
-			break
-		}
-		if err == syscall.EAGAIN {
-			if err = fd.pd.WaitWrite(); err == nil {
-				continue
-			}
-		}
-		if err != nil {
-			n = 0
-			break
-		}
-		if n == 0 {
-			err = io.ErrUnexpectedEOF
-			break
-		}
-	}
-	if err != nil {
-		err = &OpError{"write", fd.net, fd.raddr, err}
-	}
-	return nn, err
-}
-
-func (fd *netFD) writeTo(p []byte, sa syscall.Sockaddr) (n int, err error) {
-	if err := fd.writeLock(); err != nil {
-		return 0, err
-	}
-	defer fd.writeUnlock()
-	if err := fd.pd.PrepareWrite(); err != nil {
-		return 0, &OpError{"write", fd.net, fd.raddr, err}
-	}
-	for {
-		err = syscall.Sendto(fd.sysfd, p, 0, sa)
-		if err == syscall.EAGAIN {
-			if err = fd.pd.WaitWrite(); err == nil {
-				continue
-			}
-		}
-		break
-	}
-	if err == nil {
-		n = len(p)
-	} else {
-		err = &OpError{"write", fd.net, fd.raddr, err}
-	}
-	return
-}
-
-func (fd *netFD) writeMsg(p []byte, oob []byte, sa syscall.Sockaddr) (n int, oobn int, err error) {
-	if err := fd.writeLock(); err != nil {
-		return 0, 0, err
-	}
-	defer fd.writeUnlock()
-	if err := fd.pd.PrepareWrite(); err != nil {
-		return 0, 0, &OpError{"write", fd.net, fd.raddr, err}
-	}
-	for {
-		n, err = syscall.SendmsgN(fd.sysfd, p, oob, sa, 0)
-		if err == syscall.EAGAIN {
-			if err = fd.pd.WaitWrite(); err == nil {
-				continue
-			}
-		}
-		break
-	}
-	if err == nil {
-		oobn = len(oob)
-	} else {
-		err = &OpError{"write", fd.net, fd.raddr, err}
-	}
-	return
-}
-
-func (fd *netFD) accept(toAddr func(syscall.Sockaddr) Addr) (netfd *netFD, err error) {
-	if err := fd.readLock(); err != nil {
-		return nil, err
-	}
-	defer fd.readUnlock()
-
-	var s int
-	var rsa syscall.Sockaddr
-	if err = fd.pd.PrepareRead(); err != nil {
-		return nil, &OpError{"accept", fd.net, fd.laddr, err}
-	}
-	for {
-		s, rsa, err = accept(fd.sysfd)
-		if err != nil {
-			if err == syscall.EAGAIN {
-				if err = fd.pd.WaitRead(); err == nil {
-					continue
-				}
-			} else if err == syscall.ECONNABORTED {
-				// This means that a socket on the listen queue was closed
-				// before we Accept()ed it; it's a silly error, so try again.
-				continue
-			}
-			return nil, &OpError{"accept", fd.net, fd.laddr, err}
-		}
-		break
-	}
-
-	if netfd, err = newFD(s, fd.family, fd.sotype, fd.net); err != nil {
-		closesocket(s)
-		return nil, err
-	}
-	if err = netfd.init(); err != nil {
-		fd.Close()
-		return nil, err
-	}
-	lsa, _ := syscall.Getsockname(netfd.sysfd)
-	netfd.setAddr(toAddr(lsa), toAddr(rsa))
-	return netfd, nil
-}
-
-// tryDupCloexec indicates whether F_DUPFD_CLOEXEC should be used.
-// If the kernel doesn't support it, this is set to 0.
-var tryDupCloexec = int32(1)
-
-func dupCloseOnExec(fd int) (newfd int, err error) {
-	if atomic.LoadInt32(&tryDupCloexec) == 1 {
-		r0, _, e1 := syscall.Syscall(syscall.SYS_FCNTL, uintptr(fd), syscall.F_DUPFD_CLOEXEC, 0)
-		if runtime.GOOS == "darwin" && e1 == syscall.EBADF {
-			// On OS X 10.6 and below (but we only support
-			// >= 10.6), F_DUPFD_CLOEXEC is unsupported
-			// and fcntl there falls back (undocumented)
-			// to doing an ioctl instead, returning EBADF
-			// in this case because fd is not of the
-			// expected device fd type.  Treat it as
-			// EINVAL instead, so we fall back to the
-			// normal dup path.
-			// TODO: only do this on 10.6 if we can detect 10.6
-			// cheaply.
-			e1 = syscall.EINVAL
-		}
-		switch e1 {
-		case 0:
-			return int(r0), nil
-		case syscall.EINVAL:
-			// Old kernel. Fall back to the portable way
-			// from now on.
-			atomic.StoreInt32(&tryDupCloexec, 0)
-		default:
-			return -1, e1
-		}
-	}
-	return dupCloseOnExecOld(fd)
-}
-
-// dupCloseOnExecUnixOld is the traditional way to dup an fd and
-// set its O_CLOEXEC bit, using two system calls.
-func dupCloseOnExecOld(fd int) (newfd int, err error) {
-	syscall.ForkLock.RLock()
-	defer syscall.ForkLock.RUnlock()
-	newfd, err = syscall.Dup(fd)
-	if err != nil {
-		return -1, err
-	}
-	syscall.CloseOnExec(newfd)
-	return
-}
-
-func (fd *netFD) dup() (f *os.File, err error) {
-	ns, err := dupCloseOnExec(fd.sysfd)
-	if err != nil {
-		return nil, &OpError{"dup", fd.net, fd.laddr, err}
-	}
-
-	// We want blocking mode for the new fd, hence the double negative.
-	// This also puts the old fd into blocking mode, meaning that
-	// I/O will block the thread instead of letting us use the epoll server.
-	// Everything will still work, just with more threads.
-	if err = syscall.SetNonblock(ns, false); err != nil {
-		return nil, &OpError{"setnonblock", fd.net, fd.laddr, err}
-	}
-
-	return os.NewFile(uintptr(ns), fd.name()), nil
-}
-
-func closesocket(s int) error {
-	return syscall.Close(s)
-}
-
-func skipRawSocketTests() (skip bool, skipmsg string, err error) {
-	if os.Getuid() != 0 {
-		return true, "skipping test; must be root", nil
-	}
-	return false, "", nil
-}
diff --git a/src/pkg/net/fd_windows.go b/src/pkg/net/fd_windows.go
deleted file mode 100644
index d1129dc..0000000
--- a/src/pkg/net/fd_windows.go
+++ /dev/null
@@ -1,644 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package net
-
-import (
-	"errors"
-	"io"
-	"os"
-	"runtime"
-	"sync"
-	"syscall"
-	"time"
-	"unsafe"
-)
-
-var (
-	initErr error
-	ioSync  uint64
-)
-
-// CancelIo Windows API cancels all outstanding IO for a particular
-// socket on current thread. To overcome that limitation, we run
-// special goroutine, locked to OS single thread, that both starts
-// and cancels IO. It means, there are 2 unavoidable thread switches
-// for every IO.
-// Some newer versions of Windows has new CancelIoEx API, that does
-// not have that limitation and can be used from any thread. This
-// package uses CancelIoEx API, if present, otherwise it fallback
-// to CancelIo.
-
-var (
-	canCancelIO                               bool // determines if CancelIoEx API is present
-	skipSyncNotif                             bool
-	hasLoadSetFileCompletionNotificationModes bool
-)
-
-func sysInit() {
-	var d syscall.WSAData
-	e := syscall.WSAStartup(uint32(0x202), &d)
-	if e != nil {
-		initErr = os.NewSyscallError("WSAStartup", e)
-	}
-	canCancelIO = syscall.LoadCancelIoEx() == nil
-	if syscall.LoadGetAddrInfo() == nil {
-		lookupPort = newLookupPort
-		lookupIP = newLookupIP
-	}
-
-	hasLoadSetFileCompletionNotificationModes = syscall.LoadSetFileCompletionNotificationModes() == nil
-	if hasLoadSetFileCompletionNotificationModes {
-		// It's not safe to use FILE_SKIP_COMPLETION_PORT_ON_SUCCESS if non IFS providers are installed:
-		// http://support.microsoft.com/kb/2568167
-		skipSyncNotif = true
-		protos := [2]int32{syscall.IPPROTO_TCP, 0}
-		var buf [32]syscall.WSAProtocolInfo
-		len := uint32(unsafe.Sizeof(buf))
-		n, err := syscall.WSAEnumProtocols(&protos[0], &buf[0], &len)
-		if err != nil {
-			skipSyncNotif = false
-		} else {
-			for i := int32(0); i < n; i++ {
-				if buf[i].ServiceFlags1&syscall.XP1_IFS_HANDLES == 0 {
-					skipSyncNotif = false
-					break
-				}
-			}
-		}
-	}
-}
-
-func closesocket(s syscall.Handle) error {
-	return syscall.Closesocket(s)
-}
-
-func canUseConnectEx(net string) bool {
-	switch net {
-	case "udp", "udp4", "udp6", "ip", "ip4", "ip6":
-		// ConnectEx windows API does not support connectionless sockets.
-		return false
-	}
-	return syscall.LoadConnectEx() == nil
-}
-
-func dial(net string, ra Addr, dialer func(time.Time) (Conn, error), deadline time.Time) (Conn, error) {
-	if !canUseConnectEx(net) {
-		// Use the relatively inefficient goroutine-racing
-		// implementation of DialTimeout.
-		return dialChannel(net, ra, dialer, deadline)
-	}
-	return dialer(deadline)
-}
-
-// operation contains superset of data necessary to perform all async IO.
-type operation struct {
-	// Used by IOCP interface, it must be first field
-	// of the struct, as our code rely on it.
-	o syscall.Overlapped
-
-	// fields used by runtime.netpoll
-	runtimeCtx uintptr
-	mode       int32
-	errno      int32
-	qty        uint32
-
-	// fields used only by net package
-	fd     *netFD
-	errc   chan error
-	buf    syscall.WSABuf
-	sa     syscall.Sockaddr
-	rsa    *syscall.RawSockaddrAny
-	rsan   int32
-	handle syscall.Handle
-	flags  uint32
-}
-
-func (o *operation) InitBuf(buf []byte) {
-	o.buf.Len = uint32(len(buf))
-	o.buf.Buf = nil
-	if len(buf) != 0 {
-		o.buf.Buf = &buf[0]
-	}
-}
-
-// ioSrv executes net IO requests.
-type ioSrv struct {
-	req chan ioSrvReq
-}
-
-type ioSrvReq struct {
-	o      *operation
-	submit func(o *operation) error // if nil, cancel the operation
-}
-
-// ProcessRemoteIO will execute submit IO requests on behalf
-// of other goroutines, all on a single os thread, so it can
-// cancel them later. Results of all operations will be sent
-// back to their requesters via channel supplied in request.
-// It is used only when the CancelIoEx API is unavailable.
-func (s *ioSrv) ProcessRemoteIO() {
-	runtime.LockOSThread()
-	defer runtime.UnlockOSThread()
-	for r := range s.req {
-		if r.submit != nil {
-			r.o.errc <- r.submit(r.o)
-		} else {
-			r.o.errc <- syscall.CancelIo(r.o.fd.sysfd)
-		}
-	}
-}
-
-// ExecIO executes a single IO operation o. It submits and cancels
-// IO in the current thread for systems where Windows CancelIoEx API
-// is available. Alternatively, it passes the request onto
-// runtime netpoll and waits for completion or cancels request.
-func (s *ioSrv) ExecIO(o *operation, name string, submit func(o *operation) error) (int, error) {
-	fd := o.fd
-	// Notify runtime netpoll about starting IO.
-	err := fd.pd.Prepare(int(o.mode))
-	if err != nil {
-		return 0, &OpError{name, fd.net, fd.laddr, err}
-	}
-	// Start IO.
-	if canCancelIO {
-		err = submit(o)
-	} else {
-		// Send request to a special dedicated thread,
-		// so it can stop the IO with CancelIO later.
-		s.req <- ioSrvReq{o, submit}
-		err = <-o.errc
-	}
-	switch err {
-	case nil:
-		// IO completed immediately
-		if o.fd.skipSyncNotif {
-			// No completion message will follow, so return immediately.
-			return int(o.qty), nil
-		}
-		// Need to get our completion message anyway.
-	case syscall.ERROR_IO_PENDING:
-		// IO started, and we have to wait for its completion.
-		err = nil
-	default:
-		return 0, &OpError{name, fd.net, fd.laddr, err}
-	}
-	// Wait for our request to complete.
-	err = fd.pd.Wait(int(o.mode))
-	if err == nil {
-		// All is good. Extract our IO results and return.
-		if o.errno != 0 {
-			err = syscall.Errno(o.errno)
-			return 0, &OpError{name, fd.net, fd.laddr, err}
-		}
-		return int(o.qty), nil
-	}
-	// IO is interrupted by "close" or "timeout"
-	netpollErr := err
-	switch netpollErr {
-	case errClosing, errTimeout:
-		// will deal with those.
-	default:
-		panic("net: unexpected runtime.netpoll error: " + netpollErr.Error())
-	}
-	// Cancel our request.
-	if canCancelIO {
-		err := syscall.CancelIoEx(fd.sysfd, &o.o)
-		// Assuming ERROR_NOT_FOUND is returned, if IO is completed.
-		if err != nil && err != syscall.ERROR_NOT_FOUND {
-			// TODO(brainman): maybe do something else, but panic.
-			panic(err)
-		}
-	} else {
-		s.req <- ioSrvReq{o, nil}
-		<-o.errc
-	}
-	// Wait for cancellation to complete.
-	fd.pd.WaitCanceled(int(o.mode))
-	if o.errno != 0 {
-		err = syscall.Errno(o.errno)
-		if err == syscall.ERROR_OPERATION_ABORTED { // IO Canceled
-			err = netpollErr
-		}
-		return 0, &OpError{name, fd.net, fd.laddr, err}
-	}
-	// We issued cancellation request. But, it seems, IO operation succeeded
-	// before cancellation request run. We need to treat IO operation as
-	// succeeded (the bytes are actually sent/recv from network).
-	return int(o.qty), nil
-}
-
-// Start helper goroutines.
-var rsrv, wsrv *ioSrv
-var onceStartServer sync.Once
-
-func startServer() {
-	rsrv = new(ioSrv)
-	wsrv = new(ioSrv)
-	if !canCancelIO {
-		// Only CancelIo API is available. Lets start two special goroutines
-		// locked to an OS thread, that both starts and cancels IO. One will
-		// process read requests, while other will do writes.
-		rsrv.req = make(chan ioSrvReq)
-		go rsrv.ProcessRemoteIO()
-		wsrv.req = make(chan ioSrvReq)
-		go wsrv.ProcessRemoteIO()
-	}
-}
-
-// Network file descriptor.
-type netFD struct {
-	// locking/lifetime of sysfd + serialize access to Read and Write methods
-	fdmu fdMutex
-
-	// immutable until Close
-	sysfd         syscall.Handle
-	family        int
-	sotype        int
-	isConnected   bool
-	skipSyncNotif bool
-	net           string
-	laddr         Addr
-	raddr         Addr
-
-	rop operation // read operation
-	wop operation // write operation
-
-	// wait server
-	pd pollDesc
-}
-
-func newFD(sysfd syscall.Handle, family, sotype int, net string) (*netFD, error) {
-	if initErr != nil {
-		return nil, initErr
-	}
-	onceStartServer.Do(startServer)
-	return &netFD{sysfd: sysfd, family: family, sotype: sotype, net: net}, nil
-}
-
-func (fd *netFD) init() error {
-	if err := fd.pd.Init(fd); err != nil {
-		return err
-	}
-	if hasLoadSetFileCompletionNotificationModes {
-		// We do not use events, so we can skip them always.
-		flags := uint8(syscall.FILE_SKIP_SET_EVENT_ON_HANDLE)
-		// It's not safe to skip completion notifications for UDP:
-		// http://blogs.technet.com/b/winserverperformance/archive/2008/06/26/designing-applications-for-high-performance-part-iii.aspx
-		if skipSyncNotif && fd.net == "tcp" {
-			flags |= syscall.FILE_SKIP_COMPLETION_PORT_ON_SUCCESS
-		}
-		err := syscall.SetFileCompletionNotificationModes(fd.sysfd, flags)
-		if err == nil && flags&syscall.FILE_SKIP_COMPLETION_PORT_ON_SUCCESS != 0 {
-			fd.skipSyncNotif = true
-		}
-	}
-	fd.rop.mode = 'r'
-	fd.wop.mode = 'w'
-	fd.rop.fd = fd
-	fd.wop.fd = fd
-	fd.rop.runtimeCtx = fd.pd.runtimeCtx
-	fd.wop.runtimeCtx = fd.pd.runtimeCtx
-	if !canCancelIO {
-		fd.rop.errc = make(chan error)
-		fd.wop.errc = make(chan error)
-	}
-	return nil
-}
-
-func (fd *netFD) setAddr(laddr, raddr Addr) {
-	fd.laddr = laddr
-	fd.raddr = raddr
-	runtime.SetFinalizer(fd, (*netFD).Close)
-}
-
-func (fd *netFD) connect(la, ra syscall.Sockaddr, deadline time.Time) error {
-	// Do not need to call fd.writeLock here,
-	// because fd is not yet accessible to user,
-	// so no concurrent operations are possible.
-	if err := fd.init(); err != nil {
-		return err
-	}
-	if !deadline.IsZero() {
-		fd.setWriteDeadline(deadline)
-		defer fd.setWriteDeadline(noDeadline)
-	}
-	if !canUseConnectEx(fd.net) {
-		return syscall.Connect(fd.sysfd, ra)
-	}
-	// ConnectEx windows API requires an unconnected, previously bound socket.
-	if la == nil {
-		switch ra.(type) {
-		case *syscall.SockaddrInet4:
-			la = &syscall.SockaddrInet4{}
-		case *syscall.SockaddrInet6:
-			la = &syscall.SockaddrInet6{}
-		default:
-			panic("unexpected type in connect")
-		}
-		if err := syscall.Bind(fd.sysfd, la); err != nil {
-			return err
-		}
-	}
-	// Call ConnectEx API.
-	o := &fd.wop
-	o.sa = ra
-	_, err := wsrv.ExecIO(o, "ConnectEx", func(o *operation) error {
-		return syscall.ConnectEx(o.fd.sysfd, o.sa, nil, 0, nil, &o.o)
-	})
-	if err != nil {
-		return err
-	}
-	// Refresh socket properties.
-	return syscall.Setsockopt(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_UPDATE_CONNECT_CONTEXT, (*byte)(unsafe.Pointer(&fd.sysfd)), int32(unsafe.Sizeof(fd.sysfd)))
-}
-
-func (fd *netFD) destroy() {
-	if fd.sysfd == syscall.InvalidHandle {
-		return
-	}
-	// Poller may want to unregister fd in readiness notification mechanism,
-	// so this must be executed before closesocket.
-	fd.pd.Close()
-	closesocket(fd.sysfd)
-	fd.sysfd = syscall.InvalidHandle
-	// no need for a finalizer anymore
-	runtime.SetFinalizer(fd, nil)
-}
-
-// Add a reference to this fd.
-// Returns an error if the fd cannot be used.
-func (fd *netFD) incref() error {
-	if !fd.fdmu.Incref() {
-		return errClosing
-	}
-	return nil
-}
-
-// Remove a reference to this FD and close if we've been asked to do so
-// (and there are no references left).
-func (fd *netFD) decref() {
-	if fd.fdmu.Decref() {
-		fd.destroy()
-	}
-}
-
-// Add a reference to this fd and lock for reading.
-// Returns an error if the fd cannot be used.
-func (fd *netFD) readLock() error {
-	if !fd.fdmu.RWLock(true) {
-		return errClosing
-	}
-	return nil
-}
-
-// Unlock for reading and remove a reference to this FD.
-func (fd *netFD) readUnlock() {
-	if fd.fdmu.RWUnlock(true) {
-		fd.destroy()
-	}
-}
-
-// Add a reference to this fd and lock for writing.
-// Returns an error if the fd cannot be used.
-func (fd *netFD) writeLock() error {
-	if !fd.fdmu.RWLock(false) {
-		return errClosing
-	}
-	return nil
-}
-
-// Unlock for writing and remove a reference to this FD.
-func (fd *netFD) writeUnlock() {
-	if fd.fdmu.RWUnlock(false) {
-		fd.destroy()
-	}
-}
-
-func (fd *netFD) Close() error {
-	if !fd.fdmu.IncrefAndClose() {
-		return errClosing
-	}
-	// unblock pending reader and writer
-	fd.pd.Evict()
-	fd.decref()
-	return nil
-}
-
-func (fd *netFD) shutdown(how int) error {
-	if err := fd.incref(); err != nil {
-		return err
-	}
-	defer fd.decref()
-	err := syscall.Shutdown(fd.sysfd, how)
-	if err != nil {
-		return &OpError{"shutdown", fd.net, fd.laddr, err}
-	}
-	return nil
-}
-
-func (fd *netFD) closeRead() error {
-	return fd.shutdown(syscall.SHUT_RD)
-}
-
-func (fd *netFD) closeWrite() error {
-	return fd.shutdown(syscall.SHUT_WR)
-}
-
-func (fd *netFD) Read(buf []byte) (int, error) {
-	if err := fd.readLock(); err != nil {
-		return 0, err
-	}
-	defer fd.readUnlock()
-	o := &fd.rop
-	o.InitBuf(buf)
-	n, err := rsrv.ExecIO(o, "WSARecv", func(o *operation) error {
-		return syscall.WSARecv(o.fd.sysfd, &o.buf, 1, &o.qty, &o.flags, &o.o, nil)
-	})
-	if err == nil && n == 0 {
-		err = io.EOF
-	}
-	if raceenabled {
-		raceAcquire(unsafe.Pointer(&ioSync))
-	}
-	return n, err
-}
-
-func (fd *netFD) readFrom(buf []byte) (n int, sa syscall.Sockaddr, err error) {
-	if len(buf) == 0 {
-		return 0, nil, nil
-	}
-	if err := fd.readLock(); err != nil {
-		return 0, nil, err
-	}
-	defer fd.readUnlock()
-	o := &fd.rop
-	o.InitBuf(buf)
-	n, err = rsrv.ExecIO(o, "WSARecvFrom", func(o *operation) error {
-		if o.rsa == nil {
-			o.rsa = new(syscall.RawSockaddrAny)
-		}
-		o.rsan = int32(unsafe.Sizeof(*o.rsa))
-		return syscall.WSARecvFrom(o.fd.sysfd, &o.buf, 1, &o.qty, &o.flags, o.rsa, &o.rsan, &o.o, nil)
-	})
-	if err != nil {
-		return 0, nil, err
-	}
-	sa, _ = o.rsa.Sockaddr()
-	return
-}
-
-func (fd *netFD) Write(buf []byte) (int, error) {
-	if err := fd.writeLock(); err != nil {
-		return 0, err
-	}
-	defer fd.writeUnlock()
-	if raceenabled {
-		raceReleaseMerge(unsafe.Pointer(&ioSync))
-	}
-	o := &fd.wop
-	o.InitBuf(buf)
-	return wsrv.ExecIO(o, "WSASend", func(o *operation) error {
-		return syscall.WSASend(o.fd.sysfd, &o.buf, 1, &o.qty, 0, &o.o, nil)
-	})
-}
-
-func (fd *netFD) writeTo(buf []byte, sa syscall.Sockaddr) (int, error) {
-	if len(buf) == 0 {
-		return 0, nil
-	}
-	if err := fd.writeLock(); err != nil {
-		return 0, err
-	}
-	defer fd.writeUnlock()
-	o := &fd.wop
-	o.InitBuf(buf)
-	o.sa = sa
-	return wsrv.ExecIO(o, "WSASendto", func(o *operation) error {
-		return syscall.WSASendto(o.fd.sysfd, &o.buf, 1, &o.qty, 0, o.sa, &o.o, nil)
-	})
-}
-
-func (fd *netFD) acceptOne(toAddr func(syscall.Sockaddr) Addr, rawsa []syscall.RawSockaddrAny, o *operation) (*netFD, error) {
-	// Get new socket.
-	s, err := sysSocket(fd.family, fd.sotype, 0)
-	if err != nil {
-		return nil, &OpError{"socket", fd.net, fd.laddr, err}
-	}
-
-	// Associate our new socket with IOCP.
-	netfd, err := newFD(s, fd.family, fd.sotype, fd.net)
-	if err != nil {
-		closesocket(s)
-		return nil, &OpError{"accept", fd.net, fd.laddr, err}
-	}
-	if err := netfd.init(); err != nil {
-		fd.Close()
-		return nil, err
-	}
-
-	// Submit accept request.
-	o.handle = s
-	o.rsan = int32(unsafe.Sizeof(rawsa[0]))
-	_, err = rsrv.ExecIO(o, "AcceptEx", func(o *operation) error {
-		return syscall.AcceptEx(o.fd.sysfd, o.handle, (*byte)(unsafe.Pointer(&rawsa[0])), 0, uint32(o.rsan), uint32(o.rsan), &o.qty, &o.o)
-	})
-	if err != nil {
-		netfd.Close()
-		return nil, err
-	}
-
-	// Inherit properties of the listening socket.
-	err = syscall.Setsockopt(s, syscall.SOL_SOCKET, syscall.SO_UPDATE_ACCEPT_CONTEXT, (*byte)(unsafe.Pointer(&fd.sysfd)), int32(unsafe.Sizeof(fd.sysfd)))
-	if err != nil {
-		netfd.Close()
-		return nil, &OpError{"Setsockopt", fd.net, fd.laddr, err}
-	}
-
-	return netfd, nil
-}
-
-func (fd *netFD) accept(toAddr func(syscall.Sockaddr) Addr) (*netFD, error) {
-	if err := fd.readLock(); err != nil {
-		return nil, err
-	}
-	defer fd.readUnlock()
-
-	o := &fd.rop
-	var netfd *netFD
-	var err error
-	var rawsa [2]syscall.RawSockaddrAny
-	for {
-		netfd, err = fd.acceptOne(toAddr, rawsa[:], o)
-		if err == nil {
-			break
-		}
-		// Sometimes we see WSAECONNRESET and ERROR_NETNAME_DELETED is
-		// returned here. These happen if connection reset is received
-		// before AcceptEx could complete. These errors relate to new
-		// connection, not to AcceptEx, so ignore broken connection and
-		// try AcceptEx again for more connections.
-		operr, ok := err.(*OpError)
-		if !ok {
-			return nil, err
-		}
-		errno, ok := operr.Err.(syscall.Errno)
-		if !ok {
-			return nil, err
-		}
-		switch errno {
-		case syscall.ERROR_NETNAME_DELETED, syscall.WSAECONNRESET:
-			// ignore these and try again
-		default:
-			return nil, err
-		}
-	}
-
-	// Get local and peer addr out of AcceptEx buffer.
-	var lrsa, rrsa *syscall.RawSockaddrAny
-	var llen, rlen int32
-	syscall.GetAcceptExSockaddrs((*byte)(unsafe.Pointer(&rawsa[0])),
-		0, uint32(o.rsan), uint32(o.rsan), &lrsa, &llen, &rrsa, &rlen)
-	lsa, _ := lrsa.Sockaddr()
-	rsa, _ := rrsa.Sockaddr()
-
-	netfd.setAddr(toAddr(lsa), toAddr(rsa))
-	return netfd, nil
-}
-
-func skipRawSocketTests() (skip bool, skipmsg string, err error) {
-	// From http://msdn.microsoft.com/en-us/library/windows/desktop/ms740548.aspx:
-	// Note: To use a socket of type SOCK_RAW requires administrative privileges.
-	// Users running Winsock applications that use raw sockets must be a member of
-	// the Administrators group on the local computer, otherwise raw socket calls
-	// will fail with an error code of WSAEACCES. On Windows Vista and later, access
-	// for raw sockets is enforced at socket creation. In earlier versions of Windows,
-	// access for raw sockets is enforced during other socket operations.
-	s, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_RAW, 0)
-	if err == syscall.WSAEACCES {
-		return true, "skipping test; no access to raw socket allowed", nil
-	}
-	if err != nil {
-		return true, "", err
-	}
-	defer syscall.Closesocket(s)
-	return false, "", nil
-}
-
-// Unimplemented functions.
-
-func (fd *netFD) dup() (*os.File, error) {
-	// TODO: Implement this
-	return nil, os.NewSyscallError("dup", syscall.EWINDOWS)
-}
-
-var errNoSupport = errors.New("address family not supported")
-
-func (fd *netFD) readMsg(p []byte, oob []byte) (n, oobn, flags int, sa syscall.Sockaddr, err error) {
-	return 0, 0, 0, nil, errNoSupport
-}
-
-func (fd *netFD) writeMsg(p []byte, oob []byte, sa syscall.Sockaddr) (n int, oobn int, err error) {
-	return 0, 0, errNoSupport
-}
diff --git a/src/pkg/net/file_test.go b/src/pkg/net/file_test.go
deleted file mode 100644
index d81bca7..0000000
--- a/src/pkg/net/file_test.go
+++ /dev/null
@@ -1,205 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package net
-
-import (
-	"os"
-	"reflect"
-	"runtime"
-	"testing"
-)
-
-type listenerFile interface {
-	Listener
-	File() (f *os.File, err error)
-}
-
-type packetConnFile interface {
-	PacketConn
-	File() (f *os.File, err error)
-}
-
-type connFile interface {
-	Conn
-	File() (f *os.File, err error)
-}
-
-func testFileListener(t *testing.T, net, laddr string) {
-	switch net {
-	case "tcp", "tcp4", "tcp6":
-		laddr += ":0" // any available port
-	}
-	l, err := Listen(net, laddr)
-	if err != nil {
-		t.Fatalf("Listen failed: %v", err)
-	}
-	defer l.Close()
-	lf := l.(listenerFile)
-	f, err := lf.File()
-	if err != nil {
-		t.Fatalf("File failed: %v", err)
-	}
-	c, err := FileListener(f)
-	if err != nil {
-		t.Fatalf("FileListener failed: %v", err)
-	}
-	if !reflect.DeepEqual(l.Addr(), c.Addr()) {
-		t.Fatalf("Addrs not equal: %#v != %#v", l.Addr(), c.Addr())
-	}
-	if err := c.Close(); err != nil {
-		t.Fatalf("Close failed: %v", err)
-	}
-	if err := f.Close(); err != nil {
-		t.Fatalf("Close failed: %v", err)
-	}
-}
-
-var fileListenerTests = []struct {
-	net   string
-	laddr string
-	ipv6  bool // test with underlying AF_INET6 socket
-	linux bool // test with abstract unix domain socket, a Linux-ism
-}{
-	{net: "tcp", laddr: ""},
-	{net: "tcp", laddr: "0.0.0.0"},
-	{net: "tcp", laddr: "[::ffff:0.0.0.0]"},
-	{net: "tcp", laddr: "[::]", ipv6: true},
-
-	{net: "tcp", laddr: "127.0.0.1"},
-	{net: "tcp", laddr: "[::ffff:127.0.0.1]"},
-	{net: "tcp", laddr: "[::1]", ipv6: true},
-
-	{net: "tcp4", laddr: ""},
-	{net: "tcp4", laddr: "0.0.0.0"},
-	{net: "tcp4", laddr: "[::ffff:0.0.0.0]"},
-
-	{net: "tcp4", laddr: "127.0.0.1"},
-	{net: "tcp4", laddr: "[::ffff:127.0.0.1]"},
-
-	{net: "tcp6", laddr: "", ipv6: true},
-	{net: "tcp6", laddr: "[::]", ipv6: true},
-
-	{net: "tcp6", laddr: "[::1]", ipv6: true},
-
-	{net: "unix", laddr: "@gotest/net", linux: true},
-	{net: "unixpacket", laddr: "@gotest/net", linux: true},
-}
-
-func TestFileListener(t *testing.T) {
-	switch runtime.GOOS {
-	case "windows":
-		t.Skipf("skipping test on %q", runtime.GOOS)
-	}
-
-	for _, tt := range fileListenerTests {
-		if skipServerTest(tt.net, "unix", tt.laddr, tt.ipv6, false, tt.linux) {
-			continue
-		}
-		if skipServerTest(tt.net, "unixpacket", tt.laddr, tt.ipv6, false, tt.linux) {
-			continue
-		}
-		testFileListener(t, tt.net, tt.laddr)
-	}
-}
-
-func testFilePacketConn(t *testing.T, pcf packetConnFile, listen bool) {
-	f, err := pcf.File()
-	if err != nil {
-		t.Fatalf("File failed: %v", err)
-	}
-	c, err := FilePacketConn(f)
-	if err != nil {
-		t.Fatalf("FilePacketConn failed: %v", err)
-	}
-	if !reflect.DeepEqual(pcf.LocalAddr(), c.LocalAddr()) {
-		t.Fatalf("LocalAddrs not equal: %#v != %#v", pcf.LocalAddr(), c.LocalAddr())
-	}
-	if listen {
-		if _, err := c.WriteTo([]byte{}, c.LocalAddr()); err != nil {
-			t.Fatalf("WriteTo failed: %v", err)
-		}
-	}
-	if err := c.Close(); err != nil {
-		t.Fatalf("Close failed: %v", err)
-	}
-	if err := f.Close(); err != nil {
-		t.Fatalf("Close failed: %v", err)
-	}
-}
-
-func testFilePacketConnListen(t *testing.T, net, laddr string) {
-	switch net {
-	case "udp", "udp4", "udp6":
-		laddr += ":0" // any available port
-	}
-	l, err := ListenPacket(net, laddr)
-	if err != nil {
-		t.Fatalf("ListenPacket failed: %v", err)
-	}
-	testFilePacketConn(t, l.(packetConnFile), true)
-	if err := l.Close(); err != nil {
-		t.Fatalf("Close failed: %v", err)
-	}
-}
-
-func testFilePacketConnDial(t *testing.T, net, raddr string) {
-	switch net {
-	case "udp", "udp4", "udp6":
-		raddr += ":12345"
-	}
-	c, err := Dial(net, raddr)
-	if err != nil {
-		t.Fatalf("Dial failed: %v", err)
-	}
-	testFilePacketConn(t, c.(packetConnFile), false)
-	if err := c.Close(); err != nil {
-		t.Fatalf("Close failed: %v", err)
-	}
-}
-
-var filePacketConnTests = []struct {
-	net   string
-	addr  string
-	ipv6  bool // test with underlying AF_INET6 socket
-	linux bool // test with abstract unix domain socket, a Linux-ism
-}{
-	{net: "udp", addr: "127.0.0.1"},
-	{net: "udp", addr: "[::ffff:127.0.0.1]"},
-	{net: "udp", addr: "[::1]", ipv6: true},
-
-	{net: "udp4", addr: "127.0.0.1"},
-	{net: "udp4", addr: "[::ffff:127.0.0.1]"},
-
-	{net: "udp6", addr: "[::1]", ipv6: true},
-
-	{net: "ip4:icmp", addr: "127.0.0.1"},
-
-	{net: "unixgram", addr: "@gotest3/net", linux: true},
-}
-
-func TestFilePacketConn(t *testing.T) {
-	switch runtime.GOOS {
-	case "nacl", "plan9", "windows":
-		t.Skipf("skipping test on %q", runtime.GOOS)
-	}
-
-	for _, tt := range filePacketConnTests {
-		if skipServerTest(tt.net, "unixgram", tt.addr, tt.ipv6, false, tt.linux) {
-			continue
-		}
-		if os.Getuid() != 0 && tt.net == "ip4:icmp" {
-			t.Log("skipping test; must be root")
-			continue
-		}
-		testFilePacketConnListen(t, tt.net, tt.addr)
-		switch tt.addr {
-		case "", "0.0.0.0", "[::ffff:0.0.0.0]", "[::]":
-		default:
-			if tt.net != "unixgram" {
-				testFilePacketConnDial(t, tt.net, tt.addr)
-			}
-		}
-	}
-}
diff --git a/src/pkg/net/file_unix.go b/src/pkg/net/file_unix.go
deleted file mode 100644
index 07b3ecf..0000000
--- a/src/pkg/net/file_unix.go
+++ /dev/null
@@ -1,139 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris
-
-package net
-
-import (
-	"os"
-	"syscall"
-)
-
-func newFileFD(f *os.File) (*netFD, error) {
-	fd, err := dupCloseOnExec(int(f.Fd()))
-	if err != nil {
-		return nil, os.NewSyscallError("dup", err)
-	}
-
-	if err = syscall.SetNonblock(fd, true); err != nil {
-		closesocket(fd)
-		return nil, err
-	}
-
-	sotype, err := syscall.GetsockoptInt(fd, syscall.SOL_SOCKET, syscall.SO_TYPE)
-	if err != nil {
-		closesocket(fd)
-		return nil, os.NewSyscallError("getsockopt", err)
-	}
-
-	family := syscall.AF_UNSPEC
-	toAddr := sockaddrToTCP
-	lsa, _ := syscall.Getsockname(fd)
-	switch lsa.(type) {
-	default:
-		closesocket(fd)
-		return nil, syscall.EINVAL
-	case *syscall.SockaddrInet4:
-		family = syscall.AF_INET
-		if sotype == syscall.SOCK_DGRAM {
-			toAddr = sockaddrToUDP
-		} else if sotype == syscall.SOCK_RAW {
-			toAddr = sockaddrToIP
-		}
-	case *syscall.SockaddrInet6:
-		family = syscall.AF_INET6
-		if sotype == syscall.SOCK_DGRAM {
-			toAddr = sockaddrToUDP
-		} else if sotype == syscall.SOCK_RAW {
-			toAddr = sockaddrToIP
-		}
-	case *syscall.SockaddrUnix:
-		family = syscall.AF_UNIX
-		toAddr = sockaddrToUnix
-		if sotype == syscall.SOCK_DGRAM {
-			toAddr = sockaddrToUnixgram
-		} else if sotype == syscall.SOCK_SEQPACKET {
-			toAddr = sockaddrToUnixpacket
-		}
-	}
-	laddr := toAddr(lsa)
-	rsa, _ := syscall.Getpeername(fd)
-	raddr := toAddr(rsa)
-
-	netfd, err := newFD(fd, family, sotype, laddr.Network())
-	if err != nil {
-		closesocket(fd)
-		return nil, err
-	}
-	if err := netfd.init(); err != nil {
-		netfd.Close()
-		return nil, err
-	}
-	netfd.setAddr(laddr, raddr)
-	return netfd, nil
-}
-
-// FileConn returns a copy of the network connection corresponding to
-// the open file f.  It is the caller's responsibility to close f when
-// finished.  Closing c does not affect f, and closing f does not
-// affect c.
-func FileConn(f *os.File) (c Conn, err error) {
-	fd, err := newFileFD(f)
-	if err != nil {
-		return nil, err
-	}
-	switch fd.laddr.(type) {
-	case *TCPAddr:
-		return newTCPConn(fd), nil
-	case *UDPAddr:
-		return newUDPConn(fd), nil
-	case *IPAddr:
-		return newIPConn(fd), nil
-	case *UnixAddr:
-		return newUnixConn(fd), nil
-	}
-	fd.Close()
-	return nil, syscall.EINVAL
-}
-
-// FileListener returns a copy of the network listener corresponding
-// to the open file f.  It is the caller's responsibility to close l
-// when finished.  Closing l does not affect f, and closing f does not
-// affect l.
-func FileListener(f *os.File) (l Listener, err error) {
-	fd, err := newFileFD(f)
-	if err != nil {
-		return nil, err
-	}
-	switch laddr := fd.laddr.(type) {
-	case *TCPAddr:
-		return &TCPListener{fd}, nil
-	case *UnixAddr:
-		return &UnixListener{fd, laddr.Name}, nil
-	}
-	fd.Close()
-	return nil, syscall.EINVAL
-}
-
-// FilePacketConn returns a copy of the packet network connection
-// corresponding to the open file f.  It is the caller's
-// responsibility to close f when finished.  Closing c does not affect
-// f, and closing f does not affect c.
-func FilePacketConn(f *os.File) (c PacketConn, err error) {
-	fd, err := newFileFD(f)
-	if err != nil {
-		return nil, err
-	}
-	switch fd.laddr.(type) {
-	case *UDPAddr:
-		return newUDPConn(fd), nil
-	case *IPAddr:
-		return newIPConn(fd), nil
-	case *UnixAddr:
-		return newUnixConn(fd), nil
-	}
-	fd.Close()
-	return nil, syscall.EINVAL
-}
diff --git a/src/pkg/net/hosts.go b/src/pkg/net/hosts.go
deleted file mode 100644
index e6674ba..0000000
--- a/src/pkg/net/hosts.go
+++ /dev/null
@@ -1,86 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Read static host/IP entries from /etc/hosts.
-
-package net
-
-import (
-	"sync"
-	"time"
-)
-
-const cacheMaxAge = 5 * time.Minute
-
-// hostsPath points to the file with static IP/address entries.
-var hostsPath = "/etc/hosts"
-
-// Simple cache.
-var hosts struct {
-	sync.Mutex
-	byName map[string][]string
-	byAddr map[string][]string
-	expire time.Time
-	path   string
-}
-
-func readHosts() {
-	now := time.Now()
-	hp := hostsPath
-	if len(hosts.byName) == 0 || now.After(hosts.expire) || hosts.path != hp {
-		hs := make(map[string][]string)
-		is := make(map[string][]string)
-		var file *file
-		if file, _ = open(hp); file == nil {
-			return
-		}
-		for line, ok := file.readLine(); ok; line, ok = file.readLine() {
-			if i := byteIndex(line, '#'); i >= 0 {
-				// Discard comments.
-				line = line[0:i]
-			}
-			f := getFields(line)
-			if len(f) < 2 || ParseIP(f[0]) == nil {
-				continue
-			}
-			for i := 1; i < len(f); i++ {
-				h := f[i]
-				hs[h] = append(hs[h], f[0])
-				is[f[0]] = append(is[f[0]], h)
-			}
-		}
-		// Update the data cache.
-		hosts.expire = time.Now().Add(cacheMaxAge)
-		hosts.path = hp
-		hosts.byName = hs
-		hosts.byAddr = is
-		file.close()
-	}
-}
-
-// lookupStaticHost looks up the addresses for the given host from /etc/hosts.
-func lookupStaticHost(host string) []string {
-	hosts.Lock()
-	defer hosts.Unlock()
-	readHosts()
-	if len(hosts.byName) != 0 {
-		if ips, ok := hosts.byName[host]; ok {
-			return ips
-		}
-	}
-	return nil
-}
-
-// lookupStaticAddr looks up the hosts for the given address from /etc/hosts.
-func lookupStaticAddr(addr string) []string {
-	hosts.Lock()
-	defer hosts.Unlock()
-	readHosts()
-	if len(hosts.byAddr) != 0 {
-		if hosts, ok := hosts.byAddr[addr]; ok {
-			return hosts
-		}
-	}
-	return nil
-}
diff --git a/src/pkg/net/http/chunked.go b/src/pkg/net/http/chunked.go
deleted file mode 100644
index 749f29d..0000000
--- a/src/pkg/net/http/chunked.go
+++ /dev/null
@@ -1,203 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// The wire protocol for HTTP's "chunked" Transfer-Encoding.
-
-// This code is duplicated in net/http and net/http/httputil.
-// Please make any changes in both files.
-
-package http
-
-import (
-	"bufio"
-	"bytes"
-	"errors"
-	"fmt"
-	"io"
-)
-
-const maxLineLength = 4096 // assumed <= bufio.defaultBufSize
-
-var ErrLineTooLong = errors.New("header line too long")
-
-// newChunkedReader returns a new chunkedReader that translates the data read from r
-// out of HTTP "chunked" format before returning it.
-// The chunkedReader returns io.EOF when the final 0-length chunk is read.
-//
-// newChunkedReader is not needed by normal applications. The http package
-// automatically decodes chunking when reading response bodies.
-func newChunkedReader(r io.Reader) io.Reader {
-	br, ok := r.(*bufio.Reader)
-	if !ok {
-		br = bufio.NewReader(r)
-	}
-	return &chunkedReader{r: br}
-}
-
-type chunkedReader struct {
-	r   *bufio.Reader
-	n   uint64 // unread bytes in chunk
-	err error
-	buf [2]byte
-}
-
-func (cr *chunkedReader) beginChunk() {
-	// chunk-size CRLF
-	var line []byte
-	line, cr.err = readLine(cr.r)
-	if cr.err != nil {
-		return
-	}
-	cr.n, cr.err = parseHexUint(line)
-	if cr.err != nil {
-		return
-	}
-	if cr.n == 0 {
-		cr.err = io.EOF
-	}
-}
-
-func (cr *chunkedReader) chunkHeaderAvailable() bool {
-	n := cr.r.Buffered()
-	if n > 0 {
-		peek, _ := cr.r.Peek(n)
-		return bytes.IndexByte(peek, '\n') >= 0
-	}
-	return false
-}
-
-func (cr *chunkedReader) Read(b []uint8) (n int, err error) {
-	for cr.err == nil {
-		if cr.n == 0 {
-			if n > 0 && !cr.chunkHeaderAvailable() {
-				// We've read enough. Don't potentially block
-				// reading a new chunk header.
-				break
-			}
-			cr.beginChunk()
-			continue
-		}
-		if len(b) == 0 {
-			break
-		}
-		rbuf := b
-		if uint64(len(rbuf)) > cr.n {
-			rbuf = rbuf[:cr.n]
-		}
-		var n0 int
-		n0, cr.err = cr.r.Read(rbuf)
-		n += n0
-		b = b[n0:]
-		cr.n -= uint64(n0)
-		// If we're at the end of a chunk, read the next two
-		// bytes to verify they are "\r\n".
-		if cr.n == 0 && cr.err == nil {
-			if _, cr.err = io.ReadFull(cr.r, cr.buf[:2]); cr.err == nil {
-				if cr.buf[0] != '\r' || cr.buf[1] != '\n' {
-					cr.err = errors.New("malformed chunked encoding")
-				}
-			}
-		}
-	}
-	return n, cr.err
-}
-
-// Read a line of bytes (up to \n) from b.
-// Give up if the line exceeds maxLineLength.
-// The returned bytes are a pointer into storage in
-// the bufio, so they are only valid until the next bufio read.
-func readLine(b *bufio.Reader) (p []byte, err error) {
-	if p, err = b.ReadSlice('\n'); err != nil {
-		// We always know when EOF is coming.
-		// If the caller asked for a line, there should be a line.
-		if err == io.EOF {
-			err = io.ErrUnexpectedEOF
-		} else if err == bufio.ErrBufferFull {
-			err = ErrLineTooLong
-		}
-		return nil, err
-	}
-	if len(p) >= maxLineLength {
-		return nil, ErrLineTooLong
-	}
-	return trimTrailingWhitespace(p), nil
-}
-
-func trimTrailingWhitespace(b []byte) []byte {
-	for len(b) > 0 && isASCIISpace(b[len(b)-1]) {
-		b = b[:len(b)-1]
-	}
-	return b
-}
-
-func isASCIISpace(b byte) bool {
-	return b == ' ' || b == '\t' || b == '\n' || b == '\r'
-}
-
-// newChunkedWriter returns a new chunkedWriter that translates writes into HTTP
-// "chunked" format before writing them to w. Closing the returned chunkedWriter
-// sends the final 0-length chunk that marks the end of the stream.
-//
-// newChunkedWriter is not needed by normal applications. The http
-// package adds chunking automatically if handlers don't set a
-// Content-Length header. Using newChunkedWriter inside a handler
-// would result in double chunking or chunking with a Content-Length
-// length, both of which are wrong.
-func newChunkedWriter(w io.Writer) io.WriteCloser {
-	return &chunkedWriter{w}
-}
-
-// Writing to chunkedWriter translates to writing in HTTP chunked Transfer
-// Encoding wire format to the underlying Wire chunkedWriter.
-type chunkedWriter struct {
-	Wire io.Writer
-}
-
-// Write the contents of data as one chunk to Wire.
-// NOTE: Note that the corresponding chunk-writing procedure in Conn.Write has
-// a bug since it does not check for success of io.WriteString
-func (cw *chunkedWriter) Write(data []byte) (n int, err error) {
-
-	// Don't send 0-length data. It looks like EOF for chunked encoding.
-	if len(data) == 0 {
-		return 0, nil
-	}
-
-	if _, err = fmt.Fprintf(cw.Wire, "%x\r\n", len(data)); err != nil {
-		return 0, err
-	}
-	if n, err = cw.Wire.Write(data); err != nil {
-		return
-	}
-	if n != len(data) {
-		err = io.ErrShortWrite
-		return
-	}
-	_, err = io.WriteString(cw.Wire, "\r\n")
-
-	return
-}
-
-func (cw *chunkedWriter) Close() error {
-	_, err := io.WriteString(cw.Wire, "0\r\n")
-	return err
-}
-
-func parseHexUint(v []byte) (n uint64, err error) {
-	for _, b := range v {
-		n <<= 4
-		switch {
-		case '0' <= b && b <= '9':
-			b = b - '0'
-		case 'a' <= b && b <= 'f':
-			b = b - 'a' + 10
-		case 'A' <= b && b <= 'F':
-			b = b - 'A' + 10
-		default:
-			return 0, errors.New("invalid byte in chunk length")
-		}
-		n |= uint64(b)
-	}
-	return
-}
diff --git a/src/pkg/net/http/chunked_test.go b/src/pkg/net/http/chunked_test.go
deleted file mode 100644
index 3454479..0000000
--- a/src/pkg/net/http/chunked_test.go
+++ /dev/null
@@ -1,159 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// This code is duplicated in net/http and net/http/httputil.
-// Please make any changes in both files.
-
-package http
-
-import (
-	"bufio"
-	"bytes"
-	"fmt"
-	"io"
-	"io/ioutil"
-	"strings"
-	"testing"
-)
-
-func TestChunk(t *testing.T) {
-	var b bytes.Buffer
-
-	w := newChunkedWriter(&b)
-	const chunk1 = "hello, "
-	const chunk2 = "world! 0123456789abcdef"
-	w.Write([]byte(chunk1))
-	w.Write([]byte(chunk2))
-	w.Close()
-
-	if g, e := b.String(), "7\r\nhello, \r\n17\r\nworld! 0123456789abcdef\r\n0\r\n"; g != e {
-		t.Fatalf("chunk writer wrote %q; want %q", g, e)
-	}
-
-	r := newChunkedReader(&b)
-	data, err := ioutil.ReadAll(r)
-	if err != nil {
-		t.Logf(`data: "%s"`, data)
-		t.Fatalf("ReadAll from reader: %v", err)
-	}
-	if g, e := string(data), chunk1+chunk2; g != e {
-		t.Errorf("chunk reader read %q; want %q", g, e)
-	}
-}
-
-func TestChunkReadMultiple(t *testing.T) {
-	// Bunch of small chunks, all read together.
-	{
-		var b bytes.Buffer
-		w := newChunkedWriter(&b)
-		w.Write([]byte("foo"))
-		w.Write([]byte("bar"))
-		w.Close()
-
-		r := newChunkedReader(&b)
-		buf := make([]byte, 10)
-		n, err := r.Read(buf)
-		if n != 6 || err != io.EOF {
-			t.Errorf("Read = %d, %v; want 6, EOF", n, err)
-		}
-		buf = buf[:n]
-		if string(buf) != "foobar" {
-			t.Errorf("Read = %q; want %q", buf, "foobar")
-		}
-	}
-
-	// One big chunk followed by a little chunk, but the small bufio.Reader size
-	// should prevent the second chunk header from being read.
-	{
-		var b bytes.Buffer
-		w := newChunkedWriter(&b)
-		// fillBufChunk is 11 bytes + 3 bytes header + 2 bytes footer = 16 bytes,
-		// the same as the bufio ReaderSize below (the minimum), so even
-		// though we're going to try to Read with a buffer larger enough to also
-		// receive "foo", the second chunk header won't be read yet.
-		const fillBufChunk = "0123456789a"
-		const shortChunk = "foo"
-		w.Write([]byte(fillBufChunk))
-		w.Write([]byte(shortChunk))
-		w.Close()
-
-		r := newChunkedReader(bufio.NewReaderSize(&b, 16))
-		buf := make([]byte, len(fillBufChunk)+len(shortChunk))
-		n, err := r.Read(buf)
-		if n != len(fillBufChunk) || err != nil {
-			t.Errorf("Read = %d, %v; want %d, nil", n, err, len(fillBufChunk))
-		}
-		buf = buf[:n]
-		if string(buf) != fillBufChunk {
-			t.Errorf("Read = %q; want %q", buf, fillBufChunk)
-		}
-
-		n, err = r.Read(buf)
-		if n != len(shortChunk) || err != io.EOF {
-			t.Errorf("Read = %d, %v; want %d, EOF", n, err, len(shortChunk))
-		}
-	}
-
-	// And test that we see an EOF chunk, even though our buffer is already full:
-	{
-		r := newChunkedReader(bufio.NewReader(strings.NewReader("3\r\nfoo\r\n0\r\n")))
-		buf := make([]byte, 3)
-		n, err := r.Read(buf)
-		if n != 3 || err != io.EOF {
-			t.Errorf("Read = %d, %v; want 3, EOF", n, err)
-		}
-		if string(buf) != "foo" {
-			t.Errorf("buf = %q; want foo", buf)
-		}
-	}
-}
-
-func TestChunkReaderAllocs(t *testing.T) {
-	if testing.Short() {
-		t.Skip("skipping in short mode")
-	}
-	var buf bytes.Buffer
-	w := newChunkedWriter(&buf)
-	a, b, c := []byte("aaaaaa"), []byte("bbbbbbbbbbbb"), []byte("cccccccccccccccccccccccc")
-	w.Write(a)
-	w.Write(b)
-	w.Write(c)
-	w.Close()
-
-	readBuf := make([]byte, len(a)+len(b)+len(c)+1)
-	byter := bytes.NewReader(buf.Bytes())
-	bufr := bufio.NewReader(byter)
-	mallocs := testing.AllocsPerRun(100, func() {
-		byter.Seek(0, 0)
-		bufr.Reset(byter)
-		r := newChunkedReader(bufr)
-		n, err := io.ReadFull(r, readBuf)
-		if n != len(readBuf)-1 {
-			t.Fatalf("read %d bytes; want %d", n, len(readBuf)-1)
-		}
-		if err != io.ErrUnexpectedEOF {
-			t.Fatalf("read error = %v; want ErrUnexpectedEOF", err)
-		}
-	})
-	if mallocs > 1.5 {
-		t.Errorf("mallocs = %v; want 1", mallocs)
-	}
-}
-
-func TestParseHexUint(t *testing.T) {
-	for i := uint64(0); i <= 1234; i++ {
-		line := []byte(fmt.Sprintf("%x", i))
-		got, err := parseHexUint(line)
-		if err != nil {
-			t.Fatalf("on %d: %v", i, err)
-		}
-		if got != i {
-			t.Errorf("for input %q = %d; want %d", line, got, i)
-		}
-	}
-	_, err := parseHexUint([]byte("bogus"))
-	if err == nil {
-		t.Error("expected error on bogus input")
-	}
-}
diff --git a/src/pkg/net/http/client.go b/src/pkg/net/http/client.go
deleted file mode 100644
index a5a3abe..0000000
--- a/src/pkg/net/http/client.go
+++ /dev/null
@@ -1,487 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// HTTP client. See RFC 2616.
-//
-// This is the high-level Client interface.
-// The low-level implementation is in transport.go.
-
-package http
-
-import (
-	"encoding/base64"
-	"errors"
-	"fmt"
-	"io"
-	"io/ioutil"
-	"log"
-	"net/url"
-	"strings"
-	"sync"
-	"time"
-)
-
-// A Client is an HTTP client. Its zero value (DefaultClient) is a
-// usable client that uses DefaultTransport.
-//
-// The Client's Transport typically has internal state (cached TCP
-// connections), so Clients should be reused instead of created as
-// needed. Clients are safe for concurrent use by multiple goroutines.
-//
-// A Client is higher-level than a RoundTripper (such as Transport)
-// and additionally handles HTTP details such as cookies and
-// redirects.
-type Client struct {
-	// Transport specifies the mechanism by which individual
-	// HTTP requests are made.
-	// If nil, DefaultTransport is used.
-	Transport RoundTripper
-
-	// CheckRedirect specifies the policy for handling redirects.
-	// If CheckRedirect is not nil, the client calls it before
-	// following an HTTP redirect. The arguments req and via are
-	// the upcoming request and the requests made already, oldest
-	// first. If CheckRedirect returns an error, the Client's Get
-	// method returns both the previous Response and
-	// CheckRedirect's error (wrapped in a url.Error) instead of
-	// issuing the Request req.
-	//
-	// If CheckRedirect is nil, the Client uses its default policy,
-	// which is to stop after 10 consecutive requests.
-	CheckRedirect func(req *Request, via []*Request) error
-
-	// Jar specifies the cookie jar.
-	// If Jar is nil, cookies are not sent in requests and ignored
-	// in responses.
-	Jar CookieJar
-
-	// Timeout specifies a time limit for requests made by this
-	// Client. The timeout includes connection time, any
-	// redirects, and reading the response body. The timer remains
-	// running after Get, Head, Post, or Do return and will
-	// interrupt reading of the Response.Body.
-	//
-	// A Timeout of zero means no timeout.
-	//
-	// The Client's Transport must support the CancelRequest
-	// method or Client will return errors when attempting to make
-	// a request with Get, Head, Post, or Do. Client's default
-	// Transport (DefaultTransport) supports CancelRequest.
-	Timeout time.Duration
-}
-
-// DefaultClient is the default Client and is used by Get, Head, and Post.
-var DefaultClient = &Client{}
-
-// RoundTripper is an interface representing the ability to execute a
-// single HTTP transaction, obtaining the Response for a given Request.
-//
-// A RoundTripper must be safe for concurrent use by multiple
-// goroutines.
-type RoundTripper interface {
-	// RoundTrip executes a single HTTP transaction, returning
-	// the Response for the request req.  RoundTrip should not
-	// attempt to interpret the response.  In particular,
-	// RoundTrip must return err == nil if it obtained a response,
-	// regardless of the response's HTTP status code.  A non-nil
-	// err should be reserved for failure to obtain a response.
-	// Similarly, RoundTrip should not attempt to handle
-	// higher-level protocol details such as redirects,
-	// authentication, or cookies.
-	//
-	// RoundTrip should not modify the request, except for
-	// consuming and closing the Body, including on errors. The
-	// request's URL and Header fields are guaranteed to be
-	// initialized.
-	RoundTrip(*Request) (*Response, error)
-}
-
-// Given a string of the form "host", "host:port", or "[ipv6::address]:port",
-// return true if the string includes a port.
-func hasPort(s string) bool { return strings.LastIndex(s, ":") > strings.LastIndex(s, "]") }
-
-// Used in Send to implement io.ReadCloser by bundling together the
-// bufio.Reader through which we read the response, and the underlying
-// network connection.
-type readClose struct {
-	io.Reader
-	io.Closer
-}
-
-func (c *Client) send(req *Request) (*Response, error) {
-	if c.Jar != nil {
-		for _, cookie := range c.Jar.Cookies(req.URL) {
-			req.AddCookie(cookie)
-		}
-	}
-	resp, err := send(req, c.transport())
-	if err != nil {
-		return nil, err
-	}
-	if c.Jar != nil {
-		if rc := resp.Cookies(); len(rc) > 0 {
-			c.Jar.SetCookies(req.URL, rc)
-		}
-	}
-	return resp, err
-}
-
-// Do sends an HTTP request and returns an HTTP response, following
-// policy (e.g. redirects, cookies, auth) as configured on the client.
-//
-// An error is returned if caused by client policy (such as
-// CheckRedirect), or if there was an HTTP protocol error.
-// A non-2xx response doesn't cause an error.
-//
-// When err is nil, resp always contains a non-nil resp.Body.
-//
-// Callers should close resp.Body when done reading from it. If
-// resp.Body is not closed, the Client's underlying RoundTripper
-// (typically Transport) may not be able to re-use a persistent TCP
-// connection to the server for a subsequent "keep-alive" request.
-//
-// The request Body, if non-nil, will be closed by the underlying
-// Transport, even on errors.
-//
-// Generally Get, Post, or PostForm will be used instead of Do.
-func (c *Client) Do(req *Request) (resp *Response, err error) {
-	if req.Method == "GET" || req.Method == "HEAD" {
-		return c.doFollowingRedirects(req, shouldRedirectGet)
-	}
-	if req.Method == "POST" || req.Method == "PUT" {
-		return c.doFollowingRedirects(req, shouldRedirectPost)
-	}
-	return c.send(req)
-}
-
-func (c *Client) transport() RoundTripper {
-	if c.Transport != nil {
-		return c.Transport
-	}
-	return DefaultTransport
-}
-
-// send issues an HTTP request.
-// Caller should close resp.Body when done reading from it.
-func send(req *Request, t RoundTripper) (resp *Response, err error) {
-	if t == nil {
-		req.closeBody()
-		return nil, errors.New("http: no Client.Transport or DefaultTransport")
-	}
-
-	if req.URL == nil {
-		req.closeBody()
-		return nil, errors.New("http: nil Request.URL")
-	}
-
-	if req.RequestURI != "" {
-		req.closeBody()
-		return nil, errors.New("http: Request.RequestURI can't be set in client requests.")
-	}
-
-	// Most the callers of send (Get, Post, et al) don't need
-	// Headers, leaving it uninitialized.  We guarantee to the
-	// Transport that this has been initialized, though.
-	if req.Header == nil {
-		req.Header = make(Header)
-	}
-
-	if u := req.URL.User; u != nil {
-		username := u.Username()
-		password, _ := u.Password()
-		req.Header.Set("Authorization", "Basic "+basicAuth(username, password))
-	}
-	resp, err = t.RoundTrip(req)
-	if err != nil {
-		if resp != nil {
-			log.Printf("RoundTripper returned a response & error; ignoring response")
-		}
-		return nil, err
-	}
-	return resp, nil
-}
-
-// See 2 (end of page 4) http://www.ietf.org/rfc/rfc2617.txt
-// "To receive authorization, the client sends the userid and password,
-// separated by a single colon (":") character, within a base64
-// encoded string in the credentials."
-// It is not meant to be urlencoded.
-func basicAuth(username, password string) string {
-	auth := username + ":" + password
-	return base64.StdEncoding.EncodeToString([]byte(auth))
-}
-
-// True if the specified HTTP status code is one for which the Get utility should
-// automatically redirect.
-func shouldRedirectGet(statusCode int) bool {
-	switch statusCode {
-	case StatusMovedPermanently, StatusFound, StatusSeeOther, StatusTemporaryRedirect:
-		return true
-	}
-	return false
-}
-
-// True if the specified HTTP status code is one for which the Post utility should
-// automatically redirect.
-func shouldRedirectPost(statusCode int) bool {
-	switch statusCode {
-	case StatusFound, StatusSeeOther:
-		return true
-	}
-	return false
-}
-
-// Get issues a GET to the specified URL.  If the response is one of the following
-// redirect codes, Get follows the redirect, up to a maximum of 10 redirects:
-//
-//    301 (Moved Permanently)
-//    302 (Found)
-//    303 (See Other)
-//    307 (Temporary Redirect)
-//
-// An error is returned if there were too many redirects or if there
-// was an HTTP protocol error. A non-2xx response doesn't cause an
-// error.
-//
-// When err is nil, resp always contains a non-nil resp.Body.
-// Caller should close resp.Body when done reading from it.
-//
-// Get is a wrapper around DefaultClient.Get.
-func Get(url string) (resp *Response, err error) {
-	return DefaultClient.Get(url)
-}
-
-// Get issues a GET to the specified URL.  If the response is one of the
-// following redirect codes, Get follows the redirect after calling the
-// Client's CheckRedirect function.
-//
-//    301 (Moved Permanently)
-//    302 (Found)
-//    303 (See Other)
-//    307 (Temporary Redirect)
-//
-// An error is returned if the Client's CheckRedirect function fails
-// or if there was an HTTP protocol error. A non-2xx response doesn't
-// cause an error.
-//
-// When err is nil, resp always contains a non-nil resp.Body.
-// Caller should close resp.Body when done reading from it.
-func (c *Client) Get(url string) (resp *Response, err error) {
-	req, err := NewRequest("GET", url, nil)
-	if err != nil {
-		return nil, err
-	}
-	return c.doFollowingRedirects(req, shouldRedirectGet)
-}
-
-func (c *Client) doFollowingRedirects(ireq *Request, shouldRedirect func(int) bool) (resp *Response, err error) {
-	var base *url.URL
-	redirectChecker := c.CheckRedirect
-	if redirectChecker == nil {
-		redirectChecker = defaultCheckRedirect
-	}
-	var via []*Request
-
-	if ireq.URL == nil {
-		ireq.closeBody()
-		return nil, errors.New("http: nil Request.URL")
-	}
-
-	var reqmu sync.Mutex // guards req
-	req := ireq
-
-	var timer *time.Timer
-	if c.Timeout > 0 {
-		type canceler interface {
-			CancelRequest(*Request)
-		}
-		tr, ok := c.transport().(canceler)
-		if !ok {
-			return nil, fmt.Errorf("net/http: Client Transport of type %T doesn't support CancelRequest; Timeout not supported", c.transport())
-		}
-		timer = time.AfterFunc(c.Timeout, func() {
-			reqmu.Lock()
-			defer reqmu.Unlock()
-			tr.CancelRequest(req)
-		})
-	}
-
-	urlStr := "" // next relative or absolute URL to fetch (after first request)
-	redirectFailed := false
-	for redirect := 0; ; redirect++ {
-		if redirect != 0 {
-			nreq := new(Request)
-			nreq.Method = ireq.Method
-			if ireq.Method == "POST" || ireq.Method == "PUT" {
-				nreq.Method = "GET"
-			}
-			nreq.Header = make(Header)
-			nreq.URL, err = base.Parse(urlStr)
-			if err != nil {
-				break
-			}
-			if len(via) > 0 {
-				// Add the Referer header.
-				lastReq := via[len(via)-1]
-				if lastReq.URL.Scheme != "https" {
-					nreq.Header.Set("Referer", lastReq.URL.String())
-				}
-
-				err = redirectChecker(nreq, via)
-				if err != nil {
-					redirectFailed = true
-					break
-				}
-			}
-			reqmu.Lock()
-			req = nreq
-			reqmu.Unlock()
-		}
-
-		urlStr = req.URL.String()
-		if resp, err = c.send(req); err != nil {
-			break
-		}
-
-		if shouldRedirect(resp.StatusCode) {
-			// Read the body if small so underlying TCP connection will be re-used.
-			// No need to check for errors: if it fails, Transport won't reuse it anyway.
-			const maxBodySlurpSize = 2 << 10
-			if resp.ContentLength == -1 || resp.ContentLength <= maxBodySlurpSize {
-				io.CopyN(ioutil.Discard, resp.Body, maxBodySlurpSize)
-			}
-			resp.Body.Close()
-			if urlStr = resp.Header.Get("Location"); urlStr == "" {
-				err = errors.New(fmt.Sprintf("%d response missing Location header", resp.StatusCode))
-				break
-			}
-			base = req.URL
-			via = append(via, req)
-			continue
-		}
-		if timer != nil {
-			resp.Body = &cancelTimerBody{timer, resp.Body}
-		}
-		return resp, nil
-	}
-
-	method := ireq.Method
-	urlErr := &url.Error{
-		Op:  method[0:1] + strings.ToLower(method[1:]),
-		URL: urlStr,
-		Err: err,
-	}
-
-	if redirectFailed {
-		// Special case for Go 1 compatibility: return both the response
-		// and an error if the CheckRedirect function failed.
-		// See http://golang.org/issue/3795
-		return resp, urlErr
-	}
-
-	if resp != nil {
-		resp.Body.Close()
-	}
-	return nil, urlErr
-}
-
-func defaultCheckRedirect(req *Request, via []*Request) error {
-	if len(via) >= 10 {
-		return errors.New("stopped after 10 redirects")
-	}
-	return nil
-}
-
-// Post issues a POST to the specified URL.
-//
-// Caller should close resp.Body when done reading from it.
-//
-// Post is a wrapper around DefaultClient.Post
-func Post(url string, bodyType string, body io.Reader) (resp *Response, err error) {
-	return DefaultClient.Post(url, bodyType, body)
-}
-
-// Post issues a POST to the specified URL.
-//
-// Caller should close resp.Body when done reading from it.
-//
-// If the provided body is also an io.Closer, it is closed after the
-// request.
-func (c *Client) Post(url string, bodyType string, body io.Reader) (resp *Response, err error) {
-	req, err := NewRequest("POST", url, body)
-	if err != nil {
-		return nil, err
-	}
-	req.Header.Set("Content-Type", bodyType)
-	return c.doFollowingRedirects(req, shouldRedirectPost)
-}
-
-// PostForm issues a POST to the specified URL, with data's keys and
-// values URL-encoded as the request body.
-//
-// When err is nil, resp always contains a non-nil resp.Body.
-// Caller should close resp.Body when done reading from it.
-//
-// PostForm is a wrapper around DefaultClient.PostForm
-func PostForm(url string, data url.Values) (resp *Response, err error) {
-	return DefaultClient.PostForm(url, data)
-}
-
-// PostForm issues a POST to the specified URL,
-// with data's keys and values urlencoded as the request body.
-//
-// When err is nil, resp always contains a non-nil resp.Body.
-// Caller should close resp.Body when done reading from it.
-func (c *Client) PostForm(url string, data url.Values) (resp *Response, err error) {
-	return c.Post(url, "application/x-www-form-urlencoded", strings.NewReader(data.Encode()))
-}
-
-// Head issues a HEAD to the specified URL.  If the response is one of the
-// following redirect codes, Head follows the redirect after calling the
-// Client's CheckRedirect function.
-//
-//    301 (Moved Permanently)
-//    302 (Found)
-//    303 (See Other)
-//    307 (Temporary Redirect)
-//
-// Head is a wrapper around DefaultClient.Head
-func Head(url string) (resp *Response, err error) {
-	return DefaultClient.Head(url)
-}
-
-// Head issues a HEAD to the specified URL.  If the response is one of the
-// following redirect codes, Head follows the redirect after calling the
-// Client's CheckRedirect function.
-//
-//    301 (Moved Permanently)
-//    302 (Found)
-//    303 (See Other)
-//    307 (Temporary Redirect)
-func (c *Client) Head(url string) (resp *Response, err error) {
-	req, err := NewRequest("HEAD", url, nil)
-	if err != nil {
-		return nil, err
-	}
-	return c.doFollowingRedirects(req, shouldRedirectGet)
-}
-
-type cancelTimerBody struct {
-	t  *time.Timer
-	rc io.ReadCloser
-}
-
-func (b *cancelTimerBody) Read(p []byte) (n int, err error) {
-	n, err = b.rc.Read(p)
-	if err == io.EOF {
-		b.t.Stop()
-	}
-	return
-}
-
-func (b *cancelTimerBody) Close() error {
-	err := b.rc.Close()
-	b.t.Stop()
-	return err
-}
diff --git a/src/pkg/net/http/client_test.go b/src/pkg/net/http/client_test.go
deleted file mode 100644
index 6392c1b..0000000
--- a/src/pkg/net/http/client_test.go
+++ /dev/null
@@ -1,1038 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Tests for client.go
-
-package http_test
-
-import (
-	"bytes"
-	"crypto/tls"
-	"crypto/x509"
-	"encoding/base64"
-	"errors"
-	"fmt"
-	"io"
-	"io/ioutil"
-	"log"
-	"net"
-	. "net/http"
-	"net/http/httptest"
-	"net/url"
-	"reflect"
-	"sort"
-	"strconv"
-	"strings"
-	"sync"
-	"testing"
-	"time"
-)
-
-var robotsTxtHandler = HandlerFunc(func(w ResponseWriter, r *Request) {
-	w.Header().Set("Last-Modified", "sometime")
-	fmt.Fprintf(w, "User-agent: go\nDisallow: /something/")
-})
-
-// pedanticReadAll works like ioutil.ReadAll but additionally
-// verifies that r obeys the documented io.Reader contract.
-func pedanticReadAll(r io.Reader) (b []byte, err error) {
-	var bufa [64]byte
-	buf := bufa[:]
-	for {
-		n, err := r.Read(buf)
-		if n == 0 && err == nil {
-			return nil, fmt.Errorf("Read: n=0 with err=nil")
-		}
-		b = append(b, buf[:n]...)
-		if err == io.EOF {
-			n, err := r.Read(buf)
-			if n != 0 || err != io.EOF {
-				return nil, fmt.Errorf("Read: n=%d err=%#v after EOF", n, err)
-			}
-			return b, nil
-		}
-		if err != nil {
-			return b, err
-		}
-	}
-}
-
-type chanWriter chan string
-
-func (w chanWriter) Write(p []byte) (n int, err error) {
-	w <- string(p)
-	return len(p), nil
-}
-
-func TestClient(t *testing.T) {
-	defer afterTest(t)
-	ts := httptest.NewServer(robotsTxtHandler)
-	defer ts.Close()
-
-	r, err := Get(ts.URL)
-	var b []byte
-	if err == nil {
-		b, err = pedanticReadAll(r.Body)
-		r.Body.Close()
-	}
-	if err != nil {
-		t.Error(err)
-	} else if s := string(b); !strings.HasPrefix(s, "User-agent:") {
-		t.Errorf("Incorrect page body (did not begin with User-agent): %q", s)
-	}
-}
-
-func TestClientHead(t *testing.T) {
-	defer afterTest(t)
-	ts := httptest.NewServer(robotsTxtHandler)
-	defer ts.Close()
-
-	r, err := Head(ts.URL)
-	if err != nil {
-		t.Fatal(err)
-	}
-	if _, ok := r.Header["Last-Modified"]; !ok {
-		t.Error("Last-Modified header not found.")
-	}
-}
-
-type recordingTransport struct {
-	req *Request
-}
-
-func (t *recordingTransport) RoundTrip(req *Request) (resp *Response, err error) {
-	t.req = req
-	return nil, errors.New("dummy impl")
-}
-
-func TestGetRequestFormat(t *testing.T) {
-	defer afterTest(t)
-	tr := &recordingTransport{}
-	client := &Client{Transport: tr}
-	url := "http://dummy.faketld/"
-	client.Get(url) // Note: doesn't hit network
-	if tr.req.Method != "GET" {
-		t.Errorf("expected method %q; got %q", "GET", tr.req.Method)
-	}
-	if tr.req.URL.String() != url {
-		t.Errorf("expected URL %q; got %q", url, tr.req.URL.String())
-	}
-	if tr.req.Header == nil {
-		t.Errorf("expected non-nil request Header")
-	}
-}
-
-func TestPostRequestFormat(t *testing.T) {
-	defer afterTest(t)
-	tr := &recordingTransport{}
-	client := &Client{Transport: tr}
-
-	url := "http://dummy.faketld/"
-	json := `{"key":"value"}`
-	b := strings.NewReader(json)
-	client.Post(url, "application/json", b) // Note: doesn't hit network
-
-	if tr.req.Method != "POST" {
-		t.Errorf("got method %q, want %q", tr.req.Method, "POST")
-	}
-	if tr.req.URL.String() != url {
-		t.Errorf("got URL %q, want %q", tr.req.URL.String(), url)
-	}
-	if tr.req.Header == nil {
-		t.Fatalf("expected non-nil request Header")
-	}
-	if tr.req.Close {
-		t.Error("got Close true, want false")
-	}
-	if g, e := tr.req.ContentLength, int64(len(json)); g != e {
-		t.Errorf("got ContentLength %d, want %d", g, e)
-	}
-}
-
-func TestPostFormRequestFormat(t *testing.T) {
-	defer afterTest(t)
-	tr := &recordingTransport{}
-	client := &Client{Transport: tr}
-
-	urlStr := "http://dummy.faketld/"
-	form := make(url.Values)
-	form.Set("foo", "bar")
-	form.Add("foo", "bar2")
-	form.Set("bar", "baz")
-	client.PostForm(urlStr, form) // Note: doesn't hit network
-
-	if tr.req.Method != "POST" {
-		t.Errorf("got method %q, want %q", tr.req.Method, "POST")
-	}
-	if tr.req.URL.String() != urlStr {
-		t.Errorf("got URL %q, want %q", tr.req.URL.String(), urlStr)
-	}
-	if tr.req.Header == nil {
-		t.Fatalf("expected non-nil request Header")
-	}
-	if g, e := tr.req.Header.Get("Content-Type"), "application/x-www-form-urlencoded"; g != e {
-		t.Errorf("got Content-Type %q, want %q", g, e)
-	}
-	if tr.req.Close {
-		t.Error("got Close true, want false")
-	}
-	// Depending on map iteration, body can be either of these.
-	expectedBody := "foo=bar&foo=bar2&bar=baz"
-	expectedBody1 := "bar=baz&foo=bar&foo=bar2"
-	if g, e := tr.req.ContentLength, int64(len(expectedBody)); g != e {
-		t.Errorf("got ContentLength %d, want %d", g, e)
-	}
-	bodyb, err := ioutil.ReadAll(tr.req.Body)
-	if err != nil {
-		t.Fatalf("ReadAll on req.Body: %v", err)
-	}
-	if g := string(bodyb); g != expectedBody && g != expectedBody1 {
-		t.Errorf("got body %q, want %q or %q", g, expectedBody, expectedBody1)
-	}
-}
-
-func TestClientRedirects(t *testing.T) {
-	defer afterTest(t)
-	var ts *httptest.Server
-	ts = httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
-		n, _ := strconv.Atoi(r.FormValue("n"))
-		// Test Referer header. (7 is arbitrary position to test at)
-		if n == 7 {
-			if g, e := r.Referer(), ts.URL+"/?n=6"; e != g {
-				t.Errorf("on request ?n=7, expected referer of %q; got %q", e, g)
-			}
-		}
-		if n < 15 {
-			Redirect(w, r, fmt.Sprintf("/?n=%d", n+1), StatusFound)
-			return
-		}
-		fmt.Fprintf(w, "n=%d", n)
-	}))
-	defer ts.Close()
-
-	c := &Client{}
-	_, err := c.Get(ts.URL)
-	if e, g := "Get /?n=10: stopped after 10 redirects", fmt.Sprintf("%v", err); e != g {
-		t.Errorf("with default client Get, expected error %q, got %q", e, g)
-	}
-
-	// HEAD request should also have the ability to follow redirects.
-	_, err = c.Head(ts.URL)
-	if e, g := "Head /?n=10: stopped after 10 redirects", fmt.Sprintf("%v", err); e != g {
-		t.Errorf("with default client Head, expected error %q, got %q", e, g)
-	}
-
-	// Do should also follow redirects.
-	greq, _ := NewRequest("GET", ts.URL, nil)
-	_, err = c.Do(greq)
-	if e, g := "Get /?n=10: stopped after 10 redirects", fmt.Sprintf("%v", err); e != g {
-		t.Errorf("with default client Do, expected error %q, got %q", e, g)
-	}
-
-	var checkErr error
-	var lastVia []*Request
-	c = &Client{CheckRedirect: func(_ *Request, via []*Request) error {
-		lastVia = via
-		return checkErr
-	}}
-	res, err := c.Get(ts.URL)
-	if err != nil {
-		t.Fatalf("Get error: %v", err)
-	}
-	res.Body.Close()
-	finalUrl := res.Request.URL.String()
-	if e, g := "<nil>", fmt.Sprintf("%v", err); e != g {
-		t.Errorf("with custom client, expected error %q, got %q", e, g)
-	}
-	if !strings.HasSuffix(finalUrl, "/?n=15") {
-		t.Errorf("expected final url to end in /?n=15; got url %q", finalUrl)
-	}
-	if e, g := 15, len(lastVia); e != g {
-		t.Errorf("expected lastVia to have contained %d elements; got %d", e, g)
-	}
-
-	checkErr = errors.New("no redirects allowed")
-	res, err = c.Get(ts.URL)
-	if urlError, ok := err.(*url.Error); !ok || urlError.Err != checkErr {
-		t.Errorf("with redirects forbidden, expected a *url.Error with our 'no redirects allowed' error inside; got %#v (%q)", err, err)
-	}
-	if res == nil {
-		t.Fatalf("Expected a non-nil Response on CheckRedirect failure (http://golang.org/issue/3795)")
-	}
-	res.Body.Close()
-	if res.Header.Get("Location") == "" {
-		t.Errorf("no Location header in Response")
-	}
-}
-
-func TestPostRedirects(t *testing.T) {
-	defer afterTest(t)
-	var log struct {
-		sync.Mutex
-		bytes.Buffer
-	}
-	var ts *httptest.Server
-	ts = httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
-		log.Lock()
-		fmt.Fprintf(&log.Buffer, "%s %s ", r.Method, r.RequestURI)
-		log.Unlock()
-		if v := r.URL.Query().Get("code"); v != "" {
-			code, _ := strconv.Atoi(v)
-			if code/100 == 3 {
-				w.Header().Set("Location", ts.URL)
-			}
-			w.WriteHeader(code)
-		}
-	}))
-	defer ts.Close()
-	tests := []struct {
-		suffix string
-		want   int // response code
-	}{
-		{"/", 200},
-		{"/?code=301", 301},
-		{"/?code=302", 200},
-		{"/?code=303", 200},
-		{"/?code=404", 404},
-	}
-	for _, tt := range tests {
-		res, err := Post(ts.URL+tt.suffix, "text/plain", strings.NewReader("Some content"))
-		if err != nil {
-			t.Fatal(err)
-		}
-		if res.StatusCode != tt.want {
-			t.Errorf("POST %s: status code = %d; want %d", tt.suffix, res.StatusCode, tt.want)
-		}
-	}
-	log.Lock()
-	got := log.String()
-	log.Unlock()
-	want := "POST / POST /?code=301 POST /?code=302 GET / POST /?code=303 GET / POST /?code=404 "
-	if got != want {
-		t.Errorf("Log differs.\n Got: %q\nWant: %q", got, want)
-	}
-}
-
-var expectedCookies = []*Cookie{
-	{Name: "ChocolateChip", Value: "tasty"},
-	{Name: "First", Value: "Hit"},
-	{Name: "Second", Value: "Hit"},
-}
-
-var echoCookiesRedirectHandler = HandlerFunc(func(w ResponseWriter, r *Request) {
-	for _, cookie := range r.Cookies() {
-		SetCookie(w, cookie)
-	}
-	if r.URL.Path == "/" {
-		SetCookie(w, expectedCookies[1])
-		Redirect(w, r, "/second", StatusMovedPermanently)
-	} else {
-		SetCookie(w, expectedCookies[2])
-		w.Write([]byte("hello"))
-	}
-})
-
-func TestClientSendsCookieFromJar(t *testing.T) {
-	tr := &recordingTransport{}
-	client := &Client{Transport: tr}
-	client.Jar = &TestJar{perURL: make(map[string][]*Cookie)}
-	us := "http://dummy.faketld/"
-	u, _ := url.Parse(us)
-	client.Jar.SetCookies(u, expectedCookies)
-
-	client.Get(us) // Note: doesn't hit network
-	matchReturnedCookies(t, expectedCookies, tr.req.Cookies())
-
-	client.Head(us) // Note: doesn't hit network
-	matchReturnedCookies(t, expectedCookies, tr.req.Cookies())
-
-	client.Post(us, "text/plain", strings.NewReader("body")) // Note: doesn't hit network
-	matchReturnedCookies(t, expectedCookies, tr.req.Cookies())
-
-	client.PostForm(us, url.Values{}) // Note: doesn't hit network
-	matchReturnedCookies(t, expectedCookies, tr.req.Cookies())
-
-	req, _ := NewRequest("GET", us, nil)
-	client.Do(req) // Note: doesn't hit network
-	matchReturnedCookies(t, expectedCookies, tr.req.Cookies())
-
-	req, _ = NewRequest("POST", us, nil)
-	client.Do(req) // Note: doesn't hit network
-	matchReturnedCookies(t, expectedCookies, tr.req.Cookies())
-}
-
-// Just enough correctness for our redirect tests. Uses the URL.Host as the
-// scope of all cookies.
-type TestJar struct {
-	m      sync.Mutex
-	perURL map[string][]*Cookie
-}
-
-func (j *TestJar) SetCookies(u *url.URL, cookies []*Cookie) {
-	j.m.Lock()
-	defer j.m.Unlock()
-	if j.perURL == nil {
-		j.perURL = make(map[string][]*Cookie)
-	}
-	j.perURL[u.Host] = cookies
-}
-
-func (j *TestJar) Cookies(u *url.URL) []*Cookie {
-	j.m.Lock()
-	defer j.m.Unlock()
-	return j.perURL[u.Host]
-}
-
-func TestRedirectCookiesJar(t *testing.T) {
-	defer afterTest(t)
-	var ts *httptest.Server
-	ts = httptest.NewServer(echoCookiesRedirectHandler)
-	defer ts.Close()
-	c := &Client{
-		Jar: new(TestJar),
-	}
-	u, _ := url.Parse(ts.URL)
-	c.Jar.SetCookies(u, []*Cookie{expectedCookies[0]})
-	resp, err := c.Get(ts.URL)
-	if err != nil {
-		t.Fatalf("Get: %v", err)
-	}
-	resp.Body.Close()
-	matchReturnedCookies(t, expectedCookies, resp.Cookies())
-}
-
-func matchReturnedCookies(t *testing.T, expected, given []*Cookie) {
-	if len(given) != len(expected) {
-		t.Logf("Received cookies: %v", given)
-		t.Errorf("Expected %d cookies, got %d", len(expected), len(given))
-	}
-	for _, ec := range expected {
-		foundC := false
-		for _, c := range given {
-			if ec.Name == c.Name && ec.Value == c.Value {
-				foundC = true
-				break
-			}
-		}
-		if !foundC {
-			t.Errorf("Missing cookie %v", ec)
-		}
-	}
-}
-
-func TestJarCalls(t *testing.T) {
-	defer afterTest(t)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
-		pathSuffix := r.RequestURI[1:]
-		if r.RequestURI == "/nosetcookie" {
-			return // dont set cookies for this path
-		}
-		SetCookie(w, &Cookie{Name: "name" + pathSuffix, Value: "val" + pathSuffix})
-		if r.RequestURI == "/" {
-			Redirect(w, r, "http://secondhost.fake/secondpath", 302)
-		}
-	}))
-	defer ts.Close()
-	jar := new(RecordingJar)
-	c := &Client{
-		Jar: jar,
-		Transport: &Transport{
-			Dial: func(_ string, _ string) (net.Conn, error) {
-				return net.Dial("tcp", ts.Listener.Addr().String())
-			},
-		},
-	}
-	_, err := c.Get("http://firsthost.fake/")
-	if err != nil {
-		t.Fatal(err)
-	}
-	_, err = c.Get("http://firsthost.fake/nosetcookie")
-	if err != nil {
-		t.Fatal(err)
-	}
-	got := jar.log.String()
-	want := `Cookies("http://firsthost.fake/")
-SetCookie("http://firsthost.fake/", [name=val])
-Cookies("http://secondhost.fake/secondpath")
-SetCookie("http://secondhost.fake/secondpath", [namesecondpath=valsecondpath])
-Cookies("http://firsthost.fake/nosetcookie")
-`
-	if got != want {
-		t.Errorf("Got Jar calls:\n%s\nWant:\n%s", got, want)
-	}
-}
-
-// RecordingJar keeps a log of calls made to it, without
-// tracking any cookies.
-type RecordingJar struct {
-	mu  sync.Mutex
-	log bytes.Buffer
-}
-
-func (j *RecordingJar) SetCookies(u *url.URL, cookies []*Cookie) {
-	j.logf("SetCookie(%q, %v)\n", u, cookies)
-}
-
-func (j *RecordingJar) Cookies(u *url.URL) []*Cookie {
-	j.logf("Cookies(%q)\n", u)
-	return nil
-}
-
-func (j *RecordingJar) logf(format string, args ...interface{}) {
-	j.mu.Lock()
-	defer j.mu.Unlock()
-	fmt.Fprintf(&j.log, format, args...)
-}
-
-func TestStreamingGet(t *testing.T) {
-	defer afterTest(t)
-	say := make(chan string)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
-		w.(Flusher).Flush()
-		for str := range say {
-			w.Write([]byte(str))
-			w.(Flusher).Flush()
-		}
-	}))
-	defer ts.Close()
-
-	c := &Client{}
-	res, err := c.Get(ts.URL)
-	if err != nil {
-		t.Fatal(err)
-	}
-	var buf [10]byte
-	for _, str := range []string{"i", "am", "also", "known", "as", "comet"} {
-		say <- str
-		n, err := io.ReadFull(res.Body, buf[0:len(str)])
-		if err != nil {
-			t.Fatalf("ReadFull on %q: %v", str, err)
-		}
-		if n != len(str) {
-			t.Fatalf("Receiving %q, only read %d bytes", str, n)
-		}
-		got := string(buf[0:n])
-		if got != str {
-			t.Fatalf("Expected %q, got %q", str, got)
-		}
-	}
-	close(say)
-	_, err = io.ReadFull(res.Body, buf[0:1])
-	if err != io.EOF {
-		t.Fatalf("at end expected EOF, got %v", err)
-	}
-}
-
-type writeCountingConn struct {
-	net.Conn
-	count *int
-}
-
-func (c *writeCountingConn) Write(p []byte) (int, error) {
-	*c.count++
-	return c.Conn.Write(p)
-}
-
-// TestClientWrites verifies that client requests are buffered and we
-// don't send a TCP packet per line of the http request + body.
-func TestClientWrites(t *testing.T) {
-	defer afterTest(t)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
-	}))
-	defer ts.Close()
-
-	writes := 0
-	dialer := func(netz string, addr string) (net.Conn, error) {
-		c, err := net.Dial(netz, addr)
-		if err == nil {
-			c = &writeCountingConn{c, &writes}
-		}
-		return c, err
-	}
-	c := &Client{Transport: &Transport{Dial: dialer}}
-
-	_, err := c.Get(ts.URL)
-	if err != nil {
-		t.Fatal(err)
-	}
-	if writes != 1 {
-		t.Errorf("Get request did %d Write calls, want 1", writes)
-	}
-
-	writes = 0
-	_, err = c.PostForm(ts.URL, url.Values{"foo": {"bar"}})
-	if err != nil {
-		t.Fatal(err)
-	}
-	if writes != 1 {
-		t.Errorf("Post request did %d Write calls, want 1", writes)
-	}
-}
-
-func TestClientInsecureTransport(t *testing.T) {
-	defer afterTest(t)
-	ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) {
-		w.Write([]byte("Hello"))
-	}))
-	errc := make(chanWriter, 10) // but only expecting 1
-	ts.Config.ErrorLog = log.New(errc, "", 0)
-	defer ts.Close()
-
-	// TODO(bradfitz): add tests for skipping hostname checks too?
-	// would require a new cert for testing, and probably
-	// redundant with these tests.
-	for _, insecure := range []bool{true, false} {
-		tr := &Transport{
-			TLSClientConfig: &tls.Config{
-				InsecureSkipVerify: insecure,
-			},
-		}
-		defer tr.CloseIdleConnections()
-		c := &Client{Transport: tr}
-		res, err := c.Get(ts.URL)
-		if (err == nil) != insecure {
-			t.Errorf("insecure=%v: got unexpected err=%v", insecure, err)
-		}
-		if res != nil {
-			res.Body.Close()
-		}
-	}
-
-	select {
-	case v := <-errc:
-		if !strings.Contains(v, "TLS handshake error") {
-			t.Errorf("expected an error log message containing 'TLS handshake error'; got %q", v)
-		}
-	case <-time.After(5 * time.Second):
-		t.Errorf("timeout waiting for logged error")
-	}
-
-}
-
-func TestClientErrorWithRequestURI(t *testing.T) {
-	defer afterTest(t)
-	req, _ := NewRequest("GET", "http://localhost:1234/", nil)
-	req.RequestURI = "/this/field/is/illegal/and/should/error/"
-	_, err := DefaultClient.Do(req)
-	if err == nil {
-		t.Fatalf("expected an error")
-	}
-	if !strings.Contains(err.Error(), "RequestURI") {
-		t.Errorf("wanted error mentioning RequestURI; got error: %v", err)
-	}
-}
-
-func newTLSTransport(t *testing.T, ts *httptest.Server) *Transport {
-	certs := x509.NewCertPool()
-	for _, c := range ts.TLS.Certificates {
-		roots, err := x509.ParseCertificates(c.Certificate[len(c.Certificate)-1])
-		if err != nil {
-			t.Fatalf("error parsing server's root cert: %v", err)
-		}
-		for _, root := range roots {
-			certs.AddCert(root)
-		}
-	}
-	return &Transport{
-		TLSClientConfig: &tls.Config{RootCAs: certs},
-	}
-}
-
-func TestClientWithCorrectTLSServerName(t *testing.T) {
-	defer afterTest(t)
-	ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) {
-		if r.TLS.ServerName != "127.0.0.1" {
-			t.Errorf("expected client to set ServerName 127.0.0.1, got: %q", r.TLS.ServerName)
-		}
-	}))
-	defer ts.Close()
-
-	c := &Client{Transport: newTLSTransport(t, ts)}
-	if _, err := c.Get(ts.URL); err != nil {
-		t.Fatalf("expected successful TLS connection, got error: %v", err)
-	}
-}
-
-func TestClientWithIncorrectTLSServerName(t *testing.T) {
-	defer afterTest(t)
-	ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) {}))
-	defer ts.Close()
-	errc := make(chanWriter, 10) // but only expecting 1
-	ts.Config.ErrorLog = log.New(errc, "", 0)
-
-	trans := newTLSTransport(t, ts)
-	trans.TLSClientConfig.ServerName = "badserver"
-	c := &Client{Transport: trans}
-	_, err := c.Get(ts.URL)
-	if err == nil {
-		t.Fatalf("expected an error")
-	}
-	if !strings.Contains(err.Error(), "127.0.0.1") || !strings.Contains(err.Error(), "badserver") {
-		t.Errorf("wanted error mentioning 127.0.0.1 and badserver; got error: %v", err)
-	}
-	select {
-	case v := <-errc:
-		if !strings.Contains(v, "TLS handshake error") {
-			t.Errorf("expected an error log message containing 'TLS handshake error'; got %q", v)
-		}
-	case <-time.After(5 * time.Second):
-		t.Errorf("timeout waiting for logged error")
-	}
-}
-
-// Test for golang.org/issue/5829; the Transport should respect TLSClientConfig.ServerName
-// when not empty.
-//
-// tls.Config.ServerName (non-empty, set to "example.com") takes
-// precedence over "some-other-host.tld" which previously incorrectly
-// took precedence. We don't actually connect to (or even resolve)
-// "some-other-host.tld", though, because of the Transport.Dial hook.
-//
-// The httptest.Server has a cert with "example.com" as its name.
-func TestTransportUsesTLSConfigServerName(t *testing.T) {
-	defer afterTest(t)
-	ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) {
-		w.Write([]byte("Hello"))
-	}))
-	defer ts.Close()
-
-	tr := newTLSTransport(t, ts)
-	tr.TLSClientConfig.ServerName = "example.com" // one of httptest's Server cert names
-	tr.Dial = func(netw, addr string) (net.Conn, error) {
-		return net.Dial(netw, ts.Listener.Addr().String())
-	}
-	defer tr.CloseIdleConnections()
-	c := &Client{Transport: tr}
-	res, err := c.Get("https://some-other-host.tld/")
-	if err != nil {
-		t.Fatal(err)
-	}
-	res.Body.Close()
-}
-
-func TestResponseSetsTLSConnectionState(t *testing.T) {
-	defer afterTest(t)
-	ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) {
-		w.Write([]byte("Hello"))
-	}))
-	defer ts.Close()
-
-	tr := newTLSTransport(t, ts)
-	tr.TLSClientConfig.CipherSuites = []uint16{tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA}
-	tr.Dial = func(netw, addr string) (net.Conn, error) {
-		return net.Dial(netw, ts.Listener.Addr().String())
-	}
-	defer tr.CloseIdleConnections()
-	c := &Client{Transport: tr}
-	res, err := c.Get("https://example.com/")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer res.Body.Close()
-	if res.TLS == nil {
-		t.Fatal("Response didn't set TLS Connection State.")
-	}
-	if got, want := res.TLS.CipherSuite, tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA; got != want {
-		t.Errorf("TLS Cipher Suite = %d; want %d", got, want)
-	}
-}
-
-// Verify Response.ContentLength is populated. http://golang.org/issue/4126
-func TestClientHeadContentLength(t *testing.T) {
-	defer afterTest(t)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
-		if v := r.FormValue("cl"); v != "" {
-			w.Header().Set("Content-Length", v)
-		}
-	}))
-	defer ts.Close()
-	tests := []struct {
-		suffix string
-		want   int64
-	}{
-		{"/?cl=1234", 1234},
-		{"/?cl=0", 0},
-		{"", -1},
-	}
-	for _, tt := range tests {
-		req, _ := NewRequest("HEAD", ts.URL+tt.suffix, nil)
-		res, err := DefaultClient.Do(req)
-		if err != nil {
-			t.Fatal(err)
-		}
-		if res.ContentLength != tt.want {
-			t.Errorf("Content-Length = %d; want %d", res.ContentLength, tt.want)
-		}
-		bs, err := ioutil.ReadAll(res.Body)
-		if err != nil {
-			t.Fatal(err)
-		}
-		if len(bs) != 0 {
-			t.Errorf("Unexpected content: %q", bs)
-		}
-	}
-}
-
-func TestEmptyPasswordAuth(t *testing.T) {
-	defer afterTest(t)
-	gopher := "gopher"
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
-		auth := r.Header.Get("Authorization")
-		if strings.HasPrefix(auth, "Basic ") {
-			encoded := auth[6:]
-			decoded, err := base64.StdEncoding.DecodeString(encoded)
-			if err != nil {
-				t.Fatal(err)
-			}
-			expected := gopher + ":"
-			s := string(decoded)
-			if expected != s {
-				t.Errorf("Invalid Authorization header. Got %q, wanted %q", s, expected)
-			}
-		} else {
-			t.Errorf("Invalid auth %q", auth)
-		}
-	}))
-	defer ts.Close()
-	c := &Client{}
-	req, err := NewRequest("GET", ts.URL, nil)
-	if err != nil {
-		t.Fatal(err)
-	}
-	req.URL.User = url.User(gopher)
-	resp, err := c.Do(req)
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer resp.Body.Close()
-}
-
-func TestBasicAuth(t *testing.T) {
-	defer afterTest(t)
-	tr := &recordingTransport{}
-	client := &Client{Transport: tr}
-
-	url := "http://My%20User:My%20Pass@dummy.faketld/"
-	expected := "My User:My Pass"
-	client.Get(url)
-
-	if tr.req.Method != "GET" {
-		t.Errorf("got method %q, want %q", tr.req.Method, "GET")
-	}
-	if tr.req.URL.String() != url {
-		t.Errorf("got URL %q, want %q", tr.req.URL.String(), url)
-	}
-	if tr.req.Header == nil {
-		t.Fatalf("expected non-nil request Header")
-	}
-	auth := tr.req.Header.Get("Authorization")
-	if strings.HasPrefix(auth, "Basic ") {
-		encoded := auth[6:]
-		decoded, err := base64.StdEncoding.DecodeString(encoded)
-		if err != nil {
-			t.Fatal(err)
-		}
-		s := string(decoded)
-		if expected != s {
-			t.Errorf("Invalid Authorization header. Got %q, wanted %q", s, expected)
-		}
-	} else {
-		t.Errorf("Invalid auth %q", auth)
-	}
-}
-
-func TestClientTimeout(t *testing.T) {
-	if testing.Short() {
-		t.Skip("skipping in short mode")
-	}
-	defer afterTest(t)
-	sawRoot := make(chan bool, 1)
-	sawSlow := make(chan bool, 1)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
-		if r.URL.Path == "/" {
-			sawRoot <- true
-			Redirect(w, r, "/slow", StatusFound)
-			return
-		}
-		if r.URL.Path == "/slow" {
-			w.Write([]byte("Hello"))
-			w.(Flusher).Flush()
-			sawSlow <- true
-			time.Sleep(2 * time.Second)
-			return
-		}
-	}))
-	defer ts.Close()
-	const timeout = 500 * time.Millisecond
-	c := &Client{
-		Timeout: timeout,
-	}
-
-	res, err := c.Get(ts.URL)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	select {
-	case <-sawRoot:
-		// good.
-	default:
-		t.Fatal("handler never got / request")
-	}
-
-	select {
-	case <-sawSlow:
-		// good.
-	default:
-		t.Fatal("handler never got /slow request")
-	}
-
-	errc := make(chan error, 1)
-	go func() {
-		_, err := ioutil.ReadAll(res.Body)
-		errc <- err
-		res.Body.Close()
-	}()
-
-	const failTime = timeout * 2
-	select {
-	case err := <-errc:
-		if err == nil {
-			t.Error("expected error from ReadAll")
-		}
-		// Expected error.
-	case <-time.After(failTime):
-		t.Errorf("timeout after %v waiting for timeout of %v", failTime, timeout)
-	}
-}
-
-func TestClientRedirectEatsBody(t *testing.T) {
-	defer afterTest(t)
-	saw := make(chan string, 2)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
-		saw <- r.RemoteAddr
-		if r.URL.Path == "/" {
-			Redirect(w, r, "/foo", StatusFound) // which includes a body
-		}
-	}))
-	defer ts.Close()
-
-	res, err := Get(ts.URL)
-	if err != nil {
-		t.Fatal(err)
-	}
-	_, err = ioutil.ReadAll(res.Body)
-	if err != nil {
-		t.Fatal(err)
-	}
-	res.Body.Close()
-
-	var first string
-	select {
-	case first = <-saw:
-	default:
-		t.Fatal("server didn't see a request")
-	}
-
-	var second string
-	select {
-	case second = <-saw:
-	default:
-		t.Fatal("server didn't see a second request")
-	}
-
-	if first != second {
-		t.Fatal("server saw different client ports before & after the redirect")
-	}
-}
-
-// eofReaderFunc is an io.Reader that runs itself, and then returns io.EOF.
-type eofReaderFunc func()
-
-func (f eofReaderFunc) Read(p []byte) (n int, err error) {
-	f()
-	return 0, io.EOF
-}
-
-func TestClientTrailers(t *testing.T) {
-	defer afterTest(t)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
-		w.Header().Set("Connection", "close")
-		w.Header().Set("Trailer", "Server-Trailer-A, Server-Trailer-B")
-		w.Header().Add("Trailer", "Server-Trailer-C")
-
-		var decl []string
-		for k := range r.Trailer {
-			decl = append(decl, k)
-		}
-		sort.Strings(decl)
-
-		slurp, err := ioutil.ReadAll(r.Body)
-		if err != nil {
-			t.Errorf("Server reading request body: %v", err)
-		}
-		if string(slurp) != "foo" {
-			t.Errorf("Server read request body %q; want foo", slurp)
-		}
-		if r.Trailer == nil {
-			io.WriteString(w, "nil Trailer")
-		} else {
-			fmt.Fprintf(w, "decl: %v, vals: %s, %s",
-				decl,
-				r.Trailer.Get("Client-Trailer-A"),
-				r.Trailer.Get("Client-Trailer-B"))
-		}
-
-		// TODO: golang.org/issue/7759: there's no way yet for
-		// the server to set trailers without hijacking, so do
-		// that for now, just to test the client.  Later, in
-		// Go 1.4, it should be implicit that any mutations
-		// to w.Header() after the initial write are the
-		// trailers to be sent, if and only if they were
-		// previously declared with w.Header().Set("Trailer",
-		// ..keys..)
-		w.(Flusher).Flush()
-		conn, buf, _ := w.(Hijacker).Hijack()
-		t := Header{}
-		t.Set("Server-Trailer-A", "valuea")
-		t.Set("Server-Trailer-C", "valuec") // skipping B
-		buf.WriteString("0\r\n")            // eof
-		t.Write(buf)
-		buf.WriteString("\r\n") // end of trailers
-		buf.Flush()
-		conn.Close()
-	}))
-	defer ts.Close()
-
-	var req *Request
-	req, _ = NewRequest("POST", ts.URL, io.MultiReader(
-		eofReaderFunc(func() {
-			req.Trailer["Client-Trailer-A"] = []string{"valuea"}
-		}),
-		strings.NewReader("foo"),
-		eofReaderFunc(func() {
-			req.Trailer["Client-Trailer-B"] = []string{"valueb"}
-		}),
-	))
-	req.Trailer = Header{
-		"Client-Trailer-A": nil, //  to be set later
-		"Client-Trailer-B": nil, //  to be set later
-	}
-	req.ContentLength = -1
-	res, err := DefaultClient.Do(req)
-	if err != nil {
-		t.Fatal(err)
-	}
-	if err := wantBody(res, err, "decl: [Client-Trailer-A Client-Trailer-B], vals: valuea, valueb"); err != nil {
-		t.Error(err)
-	}
-	want := Header{
-		"Server-Trailer-A": []string{"valuea"},
-		"Server-Trailer-B": nil,
-		"Server-Trailer-C": []string{"valuec"},
-	}
-	if !reflect.DeepEqual(res.Trailer, want) {
-		t.Errorf("Response trailers = %#v; want %#v", res.Trailer, want)
-	}
-}
diff --git a/src/pkg/net/http/cookie.go b/src/pkg/net/http/cookie.go
deleted file mode 100644
index dc60ba8..0000000
--- a/src/pkg/net/http/cookie.go
+++ /dev/null
@@ -1,363 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package http
-
-import (
-	"bytes"
-	"fmt"
-	"log"
-	"net"
-	"strconv"
-	"strings"
-	"time"
-)
-
-// This implementation is done according to RFC 6265:
-//
-//    http://tools.ietf.org/html/rfc6265
-
-// A Cookie represents an HTTP cookie as sent in the Set-Cookie header of an
-// HTTP response or the Cookie header of an HTTP request.
-type Cookie struct {
-	Name       string
-	Value      string
-	Path       string
-	Domain     string
-	Expires    time.Time
-	RawExpires string
-
-	// MaxAge=0 means no 'Max-Age' attribute specified.
-	// MaxAge<0 means delete cookie now, equivalently 'Max-Age: 0'
-	// MaxAge>0 means Max-Age attribute present and given in seconds
-	MaxAge   int
-	Secure   bool
-	HttpOnly bool
-	Raw      string
-	Unparsed []string // Raw text of unparsed attribute-value pairs
-}
-
-// readSetCookies parses all "Set-Cookie" values from
-// the header h and returns the successfully parsed Cookies.
-func readSetCookies(h Header) []*Cookie {
-	cookies := []*Cookie{}
-	for _, line := range h["Set-Cookie"] {
-		parts := strings.Split(strings.TrimSpace(line), ";")
-		if len(parts) == 1 && parts[0] == "" {
-			continue
-		}
-		parts[0] = strings.TrimSpace(parts[0])
-		j := strings.Index(parts[0], "=")
-		if j < 0 {
-			continue
-		}
-		name, value := parts[0][:j], parts[0][j+1:]
-		if !isCookieNameValid(name) {
-			continue
-		}
-		value, success := parseCookieValue(value)
-		if !success {
-			continue
-		}
-		c := &Cookie{
-			Name:  name,
-			Value: value,
-			Raw:   line,
-		}
-		for i := 1; i < len(parts); i++ {
-			parts[i] = strings.TrimSpace(parts[i])
-			if len(parts[i]) == 0 {
-				continue
-			}
-
-			attr, val := parts[i], ""
-			if j := strings.Index(attr, "="); j >= 0 {
-				attr, val = attr[:j], attr[j+1:]
-			}
-			lowerAttr := strings.ToLower(attr)
-			val, success = parseCookieValue(val)
-			if !success {
-				c.Unparsed = append(c.Unparsed, parts[i])
-				continue
-			}
-			switch lowerAttr {
-			case "secure":
-				c.Secure = true
-				continue
-			case "httponly":
-				c.HttpOnly = true
-				continue
-			case "domain":
-				c.Domain = val
-				continue
-			case "max-age":
-				secs, err := strconv.Atoi(val)
-				if err != nil || secs != 0 && val[0] == '0' {
-					break
-				}
-				if secs <= 0 {
-					c.MaxAge = -1
-				} else {
-					c.MaxAge = secs
-				}
-				continue
-			case "expires":
-				c.RawExpires = val
-				exptime, err := time.Parse(time.RFC1123, val)
-				if err != nil {
-					exptime, err = time.Parse("Mon, 02-Jan-2006 15:04:05 MST", val)
-					if err != nil {
-						c.Expires = time.Time{}
-						break
-					}
-				}
-				c.Expires = exptime.UTC()
-				continue
-			case "path":
-				c.Path = val
-				continue
-			}
-			c.Unparsed = append(c.Unparsed, parts[i])
-		}
-		cookies = append(cookies, c)
-	}
-	return cookies
-}
-
-// SetCookie adds a Set-Cookie header to the provided ResponseWriter's headers.
-func SetCookie(w ResponseWriter, cookie *Cookie) {
-	w.Header().Add("Set-Cookie", cookie.String())
-}
-
-// String returns the serialization of the cookie for use in a Cookie
-// header (if only Name and Value are set) or a Set-Cookie response
-// header (if other fields are set).
-func (c *Cookie) String() string {
-	var b bytes.Buffer
-	fmt.Fprintf(&b, "%s=%s", sanitizeCookieName(c.Name), sanitizeCookieValue(c.Value))
-	if len(c.Path) > 0 {
-		fmt.Fprintf(&b, "; Path=%s", sanitizeCookiePath(c.Path))
-	}
-	if len(c.Domain) > 0 {
-		if validCookieDomain(c.Domain) {
-			// A c.Domain containing illegal characters is not
-			// sanitized but simply dropped which turns the cookie
-			// into a host-only cookie. A leading dot is okay
-			// but won't be sent.
-			d := c.Domain
-			if d[0] == '.' {
-				d = d[1:]
-			}
-			fmt.Fprintf(&b, "; Domain=%s", d)
-		} else {
-			log.Printf("net/http: invalid Cookie.Domain %q; dropping domain attribute",
-				c.Domain)
-		}
-	}
-	if c.Expires.Unix() > 0 {
-		fmt.Fprintf(&b, "; Expires=%s", c.Expires.UTC().Format(time.RFC1123))
-	}
-	if c.MaxAge > 0 {
-		fmt.Fprintf(&b, "; Max-Age=%d", c.MaxAge)
-	} else if c.MaxAge < 0 {
-		fmt.Fprintf(&b, "; Max-Age=0")
-	}
-	if c.HttpOnly {
-		fmt.Fprintf(&b, "; HttpOnly")
-	}
-	if c.Secure {
-		fmt.Fprintf(&b, "; Secure")
-	}
-	return b.String()
-}
-
-// readCookies parses all "Cookie" values from the header h and
-// returns the successfully parsed Cookies.
-//
-// if filter isn't empty, only cookies of that name are returned
-func readCookies(h Header, filter string) []*Cookie {
-	cookies := []*Cookie{}
-	lines, ok := h["Cookie"]
-	if !ok {
-		return cookies
-	}
-
-	for _, line := range lines {
-		parts := strings.Split(strings.TrimSpace(line), ";")
-		if len(parts) == 1 && parts[0] == "" {
-			continue
-		}
-		// Per-line attributes
-		parsedPairs := 0
-		for i := 0; i < len(parts); i++ {
-			parts[i] = strings.TrimSpace(parts[i])
-			if len(parts[i]) == 0 {
-				continue
-			}
-			name, val := parts[i], ""
-			if j := strings.Index(name, "="); j >= 0 {
-				name, val = name[:j], name[j+1:]
-			}
-			if !isCookieNameValid(name) {
-				continue
-			}
-			if filter != "" && filter != name {
-				continue
-			}
-			val, success := parseCookieValue(val)
-			if !success {
-				continue
-			}
-			cookies = append(cookies, &Cookie{Name: name, Value: val})
-			parsedPairs++
-		}
-	}
-	return cookies
-}
-
-// validCookieDomain returns wheter v is a valid cookie domain-value.
-func validCookieDomain(v string) bool {
-	if isCookieDomainName(v) {
-		return true
-	}
-	if net.ParseIP(v) != nil && !strings.Contains(v, ":") {
-		return true
-	}
-	return false
-}
-
-// isCookieDomainName returns whether s is a valid domain name or a valid
-// domain name with a leading dot '.'.  It is almost a direct copy of
-// package net's isDomainName.
-func isCookieDomainName(s string) bool {
-	if len(s) == 0 {
-		return false
-	}
-	if len(s) > 255 {
-		return false
-	}
-
-	if s[0] == '.' {
-		// A cookie a domain attribute may start with a leading dot.
-		s = s[1:]
-	}
-	last := byte('.')
-	ok := false // Ok once we've seen a letter.
-	partlen := 0
-	for i := 0; i < len(s); i++ {
-		c := s[i]
-		switch {
-		default:
-			return false
-		case 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z':
-			// No '_' allowed here (in contrast to package net).
-			ok = true
-			partlen++
-		case '0' <= c && c <= '9':
-			// fine
-			partlen++
-		case c == '-':
-			// Byte before dash cannot be dot.
-			if last == '.' {
-				return false
-			}
-			partlen++
-		case c == '.':
-			// Byte before dot cannot be dot, dash.
-			if last == '.' || last == '-' {
-				return false
-			}
-			if partlen > 63 || partlen == 0 {
-				return false
-			}
-			partlen = 0
-		}
-		last = c
-	}
-	if last == '-' || partlen > 63 {
-		return false
-	}
-
-	return ok
-}
-
-var cookieNameSanitizer = strings.NewReplacer("\n", "-", "\r", "-")
-
-func sanitizeCookieName(n string) string {
-	return cookieNameSanitizer.Replace(n)
-}
-
-// http://tools.ietf.org/html/rfc6265#section-4.1.1
-// cookie-value      = *cookie-octet / ( DQUOTE *cookie-octet DQUOTE )
-// cookie-octet      = %x21 / %x23-2B / %x2D-3A / %x3C-5B / %x5D-7E
-//           ; US-ASCII characters excluding CTLs,
-//           ; whitespace DQUOTE, comma, semicolon,
-//           ; and backslash
-// We loosen this as spaces and commas are common in cookie values
-// but we produce a quoted cookie-value in when value starts or ends
-// with a comma or space.
-// See http://golang.org/issue/7243 for the discussion.
-func sanitizeCookieValue(v string) string {
-	v = sanitizeOrWarn("Cookie.Value", validCookieValueByte, v)
-	if len(v) == 0 {
-		return v
-	}
-	if v[0] == ' ' || v[0] == ',' || v[len(v)-1] == ' ' || v[len(v)-1] == ',' {
-		return `"` + v + `"`
-	}
-	return v
-}
-
-func validCookieValueByte(b byte) bool {
-	return 0x20 <= b && b < 0x7f && b != '"' && b != ';' && b != '\\'
-}
-
-// path-av           = "Path=" path-value
-// path-value        = <any CHAR except CTLs or ";">
-func sanitizeCookiePath(v string) string {
-	return sanitizeOrWarn("Cookie.Path", validCookiePathByte, v)
-}
-
-func validCookiePathByte(b byte) bool {
-	return 0x20 <= b && b < 0x7f && b != ';'
-}
-
-func sanitizeOrWarn(fieldName string, valid func(byte) bool, v string) string {
-	ok := true
-	for i := 0; i < len(v); i++ {
-		if valid(v[i]) {
-			continue
-		}
-		log.Printf("net/http: invalid byte %q in %s; dropping invalid bytes", v[i], fieldName)
-		ok = false
-		break
-	}
-	if ok {
-		return v
-	}
-	buf := make([]byte, 0, len(v))
-	for i := 0; i < len(v); i++ {
-		if b := v[i]; valid(b) {
-			buf = append(buf, b)
-		}
-	}
-	return string(buf)
-}
-
-func parseCookieValue(raw string) (string, bool) {
-	// Strip the quotes, if present.
-	if len(raw) > 1 && raw[0] == '"' && raw[len(raw)-1] == '"' {
-		raw = raw[1 : len(raw)-1]
-	}
-	for i := 0; i < len(raw); i++ {
-		if !validCookieValueByte(raw[i]) {
-			return "", false
-		}
-	}
-	return raw, true
-}
-
-func isCookieNameValid(raw string) bool {
-	return strings.IndexFunc(raw, isNotToken) < 0
-}
diff --git a/src/pkg/net/http/cookie_test.go b/src/pkg/net/http/cookie_test.go
deleted file mode 100644
index f78f372..0000000
--- a/src/pkg/net/http/cookie_test.go
+++ /dev/null
@@ -1,380 +0,0 @@
-// Copyright 2010 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package http
-
-import (
-	"bytes"
-	"encoding/json"
-	"fmt"
-	"log"
-	"os"
-	"reflect"
-	"strings"
-	"testing"
-	"time"
-)
-
-var writeSetCookiesTests = []struct {
-	Cookie *Cookie
-	Raw    string
-}{
-	{
-		&Cookie{Name: "cookie-1", Value: "v$1"},
-		"cookie-1=v$1",
-	},
-	{
-		&Cookie{Name: "cookie-2", Value: "two", MaxAge: 3600},
-		"cookie-2=two; Max-Age=3600",
-	},
-	{
-		&Cookie{Name: "cookie-3", Value: "three", Domain: ".example.com"},
-		"cookie-3=three; Domain=example.com",
-	},
-	{
-		&Cookie{Name: "cookie-4", Value: "four", Path: "/restricted/"},
-		"cookie-4=four; Path=/restricted/",
-	},
-	{
-		&Cookie{Name: "cookie-5", Value: "five", Domain: "wrong;bad.abc"},
-		"cookie-5=five",
-	},
-	{
-		&Cookie{Name: "cookie-6", Value: "six", Domain: "bad-.abc"},
-		"cookie-6=six",
-	},
-	{
-		&Cookie{Name: "cookie-7", Value: "seven", Domain: "127.0.0.1"},
-		"cookie-7=seven; Domain=127.0.0.1",
-	},
-	{
-		&Cookie{Name: "cookie-8", Value: "eight", Domain: "::1"},
-		"cookie-8=eight",
-	},
-	// The "special" cookies have values containing commas or spaces which
-	// are disallowed by RFC 6265 but are common in the wild.
-	{
-		&Cookie{Name: "special-1", Value: "a z"},
-		`special-1=a z`,
-	},
-	{
-		&Cookie{Name: "special-2", Value: " z"},
-		`special-2=" z"`,
-	},
-	{
-		&Cookie{Name: "special-3", Value: "a "},
-		`special-3="a "`,
-	},
-	{
-		&Cookie{Name: "special-4", Value: " "},
-		`special-4=" "`,
-	},
-	{
-		&Cookie{Name: "special-5", Value: "a,z"},
-		`special-5=a,z`,
-	},
-	{
-		&Cookie{Name: "special-6", Value: ",z"},
-		`special-6=",z"`,
-	},
-	{
-		&Cookie{Name: "special-7", Value: "a,"},
-		`special-7="a,"`,
-	},
-	{
-		&Cookie{Name: "special-8", Value: ","},
-		`special-8=","`,
-	},
-	{
-		&Cookie{Name: "empty-value", Value: ""},
-		`empty-value=`,
-	},
-}
-
-func TestWriteSetCookies(t *testing.T) {
-	defer log.SetOutput(os.Stderr)
-	var logbuf bytes.Buffer
-	log.SetOutput(&logbuf)
-
-	for i, tt := range writeSetCookiesTests {
-		if g, e := tt.Cookie.String(), tt.Raw; g != e {
-			t.Errorf("Test %d, expecting:\n%s\nGot:\n%s\n", i, e, g)
-			continue
-		}
-	}
-
-	if got, sub := logbuf.String(), "dropping domain attribute"; !strings.Contains(got, sub) {
-		t.Errorf("Expected substring %q in log output. Got:\n%s", sub, got)
-	}
-}
-
-type headerOnlyResponseWriter Header
-
-func (ho headerOnlyResponseWriter) Header() Header {
-	return Header(ho)
-}
-
-func (ho headerOnlyResponseWriter) Write([]byte) (int, error) {
-	panic("NOIMPL")
-}
-
-func (ho headerOnlyResponseWriter) WriteHeader(int) {
-	panic("NOIMPL")
-}
-
-func TestSetCookie(t *testing.T) {
-	m := make(Header)
-	SetCookie(headerOnlyResponseWriter(m), &Cookie{Name: "cookie-1", Value: "one", Path: "/restricted/"})
-	SetCookie(headerOnlyResponseWriter(m), &Cookie{Name: "cookie-2", Value: "two", MaxAge: 3600})
-	if l := len(m["Set-Cookie"]); l != 2 {
-		t.Fatalf("expected %d cookies, got %d", 2, l)
-	}
-	if g, e := m["Set-Cookie"][0], "cookie-1=one; Path=/restricted/"; g != e {
-		t.Errorf("cookie #1: want %q, got %q", e, g)
-	}
-	if g, e := m["Set-Cookie"][1], "cookie-2=two; Max-Age=3600"; g != e {
-		t.Errorf("cookie #2: want %q, got %q", e, g)
-	}
-}
-
-var addCookieTests = []struct {
-	Cookies []*Cookie
-	Raw     string
-}{
-	{
-		[]*Cookie{},
-		"",
-	},
-	{
-		[]*Cookie{{Name: "cookie-1", Value: "v$1"}},
-		"cookie-1=v$1",
-	},
-	{
-		[]*Cookie{
-			{Name: "cookie-1", Value: "v$1"},
-			{Name: "cookie-2", Value: "v$2"},
-			{Name: "cookie-3", Value: "v$3"},
-		},
-		"cookie-1=v$1; cookie-2=v$2; cookie-3=v$3",
-	},
-}
-
-func TestAddCookie(t *testing.T) {
-	for i, tt := range addCookieTests {
-		req, _ := NewRequest("GET", "http://example.com/", nil)
-		for _, c := range tt.Cookies {
-			req.AddCookie(c)
-		}
-		if g := req.Header.Get("Cookie"); g != tt.Raw {
-			t.Errorf("Test %d:\nwant: %s\n got: %s\n", i, tt.Raw, g)
-			continue
-		}
-	}
-}
-
-var readSetCookiesTests = []struct {
-	Header  Header
-	Cookies []*Cookie
-}{
-	{
-		Header{"Set-Cookie": {"Cookie-1=v$1"}},
-		[]*Cookie{{Name: "Cookie-1", Value: "v$1", Raw: "Cookie-1=v$1"}},
-	},
-	{
-		Header{"Set-Cookie": {"NID=99=YsDT5i3E-CXax-; expires=Wed, 23-Nov-2011 01:05:03 GMT; path=/; domain=.google.ch; HttpOnly"}},
-		[]*Cookie{{
-			Name:       "NID",
-			Value:      "99=YsDT5i3E-CXax-",
-			Path:       "/",
-			Domain:     ".google.ch",
-			HttpOnly:   true,
-			Expires:    time.Date(2011, 11, 23, 1, 5, 3, 0, time.UTC),
-			RawExpires: "Wed, 23-Nov-2011 01:05:03 GMT",
-			Raw:        "NID=99=YsDT5i3E-CXax-; expires=Wed, 23-Nov-2011 01:05:03 GMT; path=/; domain=.google.ch; HttpOnly",
-		}},
-	},
-	{
-		Header{"Set-Cookie": {".ASPXAUTH=7E3AA; expires=Wed, 07-Mar-2012 14:25:06 GMT; path=/; HttpOnly"}},
-		[]*Cookie{{
-			Name:       ".ASPXAUTH",
-			Value:      "7E3AA",
-			Path:       "/",
-			Expires:    time.Date(2012, 3, 7, 14, 25, 6, 0, time.UTC),
-			RawExpires: "Wed, 07-Mar-2012 14:25:06 GMT",
-			HttpOnly:   true,
-			Raw:        ".ASPXAUTH=7E3AA; expires=Wed, 07-Mar-2012 14:25:06 GMT; path=/; HttpOnly",
-		}},
-	},
-	{
-		Header{"Set-Cookie": {"ASP.NET_SessionId=foo; path=/; HttpOnly"}},
-		[]*Cookie{{
-			Name:     "ASP.NET_SessionId",
-			Value:    "foo",
-			Path:     "/",
-			HttpOnly: true,
-			Raw:      "ASP.NET_SessionId=foo; path=/; HttpOnly",
-		}},
-	},
-	// Make sure we can properly read back the Set-Cookie headers we create
-	// for values containing spaces or commas:
-	{
-		Header{"Set-Cookie": {`special-1=a z`}},
-		[]*Cookie{{Name: "special-1", Value: "a z", Raw: `special-1=a z`}},
-	},
-	{
-		Header{"Set-Cookie": {`special-2=" z"`}},
-		[]*Cookie{{Name: "special-2", Value: " z", Raw: `special-2=" z"`}},
-	},
-	{
-		Header{"Set-Cookie": {`special-3="a "`}},
-		[]*Cookie{{Name: "special-3", Value: "a ", Raw: `special-3="a "`}},
-	},
-	{
-		Header{"Set-Cookie": {`special-4=" "`}},
-		[]*Cookie{{Name: "special-4", Value: " ", Raw: `special-4=" "`}},
-	},
-	{
-		Header{"Set-Cookie": {`special-5=a,z`}},
-		[]*Cookie{{Name: "special-5", Value: "a,z", Raw: `special-5=a,z`}},
-	},
-	{
-		Header{"Set-Cookie": {`special-6=",z"`}},
-		[]*Cookie{{Name: "special-6", Value: ",z", Raw: `special-6=",z"`}},
-	},
-	{
-		Header{"Set-Cookie": {`special-7=a,`}},
-		[]*Cookie{{Name: "special-7", Value: "a,", Raw: `special-7=a,`}},
-	},
-	{
-		Header{"Set-Cookie": {`special-8=","`}},
-		[]*Cookie{{Name: "special-8", Value: ",", Raw: `special-8=","`}},
-	},
-
-	// TODO(bradfitz): users have reported seeing this in the
-	// wild, but do browsers handle it? RFC 6265 just says "don't
-	// do that" (section 3) and then never mentions header folding
-	// again.
-	// Header{"Set-Cookie": {"ASP.NET_SessionId=foo; path=/; HttpOnly, .ASPXAUTH=7E3AA; expires=Wed, 07-Mar-2012 14:25:06 GMT; path=/; HttpOnly"}},
-}
-
-func toJSON(v interface{}) string {
-	b, err := json.Marshal(v)
-	if err != nil {
-		return fmt.Sprintf("%#v", v)
-	}
-	return string(b)
-}
-
-func TestReadSetCookies(t *testing.T) {
-	for i, tt := range readSetCookiesTests {
-		for n := 0; n < 2; n++ { // to verify readSetCookies doesn't mutate its input
-			c := readSetCookies(tt.Header)
-			if !reflect.DeepEqual(c, tt.Cookies) {
-				t.Errorf("#%d readSetCookies: have\n%s\nwant\n%s\n", i, toJSON(c), toJSON(tt.Cookies))
-				continue
-			}
-		}
-	}
-}
-
-var readCookiesTests = []struct {
-	Header  Header
-	Filter  string
-	Cookies []*Cookie
-}{
-	{
-		Header{"Cookie": {"Cookie-1=v$1", "c2=v2"}},
-		"",
-		[]*Cookie{
-			{Name: "Cookie-1", Value: "v$1"},
-			{Name: "c2", Value: "v2"},
-		},
-	},
-	{
-		Header{"Cookie": {"Cookie-1=v$1", "c2=v2"}},
-		"c2",
-		[]*Cookie{
-			{Name: "c2", Value: "v2"},
-		},
-	},
-	{
-		Header{"Cookie": {"Cookie-1=v$1; c2=v2"}},
-		"",
-		[]*Cookie{
-			{Name: "Cookie-1", Value: "v$1"},
-			{Name: "c2", Value: "v2"},
-		},
-	},
-	{
-		Header{"Cookie": {"Cookie-1=v$1; c2=v2"}},
-		"c2",
-		[]*Cookie{
-			{Name: "c2", Value: "v2"},
-		},
-	},
-}
-
-func TestReadCookies(t *testing.T) {
-	for i, tt := range readCookiesTests {
-		for n := 0; n < 2; n++ { // to verify readCookies doesn't mutate its input
-			c := readCookies(tt.Header, tt.Filter)
-			if !reflect.DeepEqual(c, tt.Cookies) {
-				t.Errorf("#%d readCookies:\nhave: %s\nwant: %s\n", i, toJSON(c), toJSON(tt.Cookies))
-				continue
-			}
-		}
-	}
-}
-
-func TestCookieSanitizeValue(t *testing.T) {
-	defer log.SetOutput(os.Stderr)
-	var logbuf bytes.Buffer
-	log.SetOutput(&logbuf)
-
-	tests := []struct {
-		in, want string
-	}{
-		{"foo", "foo"},
-		{"foo;bar", "foobar"},
-		{"foo\\bar", "foobar"},
-		{"foo\"bar", "foobar"},
-		{"\x00\x7e\x7f\x80", "\x7e"},
-		{`"withquotes"`, "withquotes"},
-		{"a z", "a z"},
-		{" z", `" z"`},
-		{"a ", `"a "`},
-	}
-	for _, tt := range tests {
-		if got := sanitizeCookieValue(tt.in); got != tt.want {
-			t.Errorf("sanitizeCookieValue(%q) = %q; want %q", tt.in, got, tt.want)
-		}
-	}
-
-	if got, sub := logbuf.String(), "dropping invalid bytes"; !strings.Contains(got, sub) {
-		t.Errorf("Expected substring %q in log output. Got:\n%s", sub, got)
-	}
-}
-
-func TestCookieSanitizePath(t *testing.T) {
-	defer log.SetOutput(os.Stderr)
-	var logbuf bytes.Buffer
-	log.SetOutput(&logbuf)
-
-	tests := []struct {
-		in, want string
-	}{
-		{"/path", "/path"},
-		{"/path with space/", "/path with space/"},
-		{"/just;no;semicolon\x00orstuff/", "/justnosemicolonorstuff/"},
-	}
-	for _, tt := range tests {
-		if got := sanitizeCookiePath(tt.in); got != tt.want {
-			t.Errorf("sanitizeCookiePath(%q) = %q; want %q", tt.in, got, tt.want)
-		}
-	}
-
-	if got, sub := logbuf.String(), "dropping invalid bytes"; !strings.Contains(got, sub) {
-		t.Errorf("Expected substring %q in log output. Got:\n%s", sub, got)
-	}
-}
diff --git a/src/pkg/net/http/cookiejar/jar.go b/src/pkg/net/http/cookiejar/jar.go
deleted file mode 100644
index 389ab58..0000000
--- a/src/pkg/net/http/cookiejar/jar.go
+++ /dev/null
@@ -1,497 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package cookiejar implements an in-memory RFC 6265-compliant http.CookieJar.
-package cookiejar
-
-import (
-	"errors"
-	"fmt"
-	"net"
-	"net/http"
-	"net/url"
-	"sort"
-	"strings"
-	"sync"
-	"time"
-)
-
-// PublicSuffixList provides the public suffix of a domain. For example:
-//      - the public suffix of "example.com" is "com",
-//      - the public suffix of "foo1.foo2.foo3.co.uk" is "co.uk", and
-//      - the public suffix of "bar.pvt.k12.ma.us" is "pvt.k12.ma.us".
-//
-// Implementations of PublicSuffixList must be safe for concurrent use by
-// multiple goroutines.
-//
-// An implementation that always returns "" is valid and may be useful for
-// testing but it is not secure: it means that the HTTP server for foo.com can
-// set a cookie for bar.com.
-//
-// A public suffix list implementation is in the package
-// code.google.com/p/go.net/publicsuffix.
-type PublicSuffixList interface {
-	// PublicSuffix returns the public suffix of domain.
-	//
-	// TODO: specify which of the caller and callee is responsible for IP
-	// addresses, for leading and trailing dots, for case sensitivity, and
-	// for IDN/Punycode.
-	PublicSuffix(domain string) string
-
-	// String returns a description of the source of this public suffix
-	// list. The description will typically contain something like a time
-	// stamp or version number.
-	String() string
-}
-
-// Options are the options for creating a new Jar.
-type Options struct {
-	// PublicSuffixList is the public suffix list that determines whether
-	// an HTTP server can set a cookie for a domain.
-	//
-	// A nil value is valid and may be useful for testing but it is not
-	// secure: it means that the HTTP server for foo.co.uk can set a cookie
-	// for bar.co.uk.
-	PublicSuffixList PublicSuffixList
-}
-
-// Jar implements the http.CookieJar interface from the net/http package.
-type Jar struct {
-	psList PublicSuffixList
-
-	// mu locks the remaining fields.
-	mu sync.Mutex
-
-	// entries is a set of entries, keyed by their eTLD+1 and subkeyed by
-	// their name/domain/path.
-	entries map[string]map[string]entry
-
-	// nextSeqNum is the next sequence number assigned to a new cookie
-	// created SetCookies.
-	nextSeqNum uint64
-}
-
-// New returns a new cookie jar. A nil *Options is equivalent to a zero
-// Options.
-func New(o *Options) (*Jar, error) {
-	jar := &Jar{
-		entries: make(map[string]map[string]entry),
-	}
-	if o != nil {
-		jar.psList = o.PublicSuffixList
-	}
-	return jar, nil
-}
-
-// entry is the internal representation of a cookie.
-//
-// This struct type is not used outside of this package per se, but the exported
-// fields are those of RFC 6265.
-type entry struct {
-	Name       string
-	Value      string
-	Domain     string
-	Path       string
-	Secure     bool
-	HttpOnly   bool
-	Persistent bool
-	HostOnly   bool
-	Expires    time.Time
-	Creation   time.Time
-	LastAccess time.Time
-
-	// seqNum is a sequence number so that Cookies returns cookies in a
-	// deterministic order, even for cookies that have equal Path length and
-	// equal Creation time. This simplifies testing.
-	seqNum uint64
-}
-
-// Id returns the domain;path;name triple of e as an id.
-func (e *entry) id() string {
-	return fmt.Sprintf("%s;%s;%s", e.Domain, e.Path, e.Name)
-}
-
-// shouldSend determines whether e's cookie qualifies to be included in a
-// request to host/path. It is the caller's responsibility to check if the
-// cookie is expired.
-func (e *entry) shouldSend(https bool, host, path string) bool {
-	return e.domainMatch(host) && e.pathMatch(path) && (https || !e.Secure)
-}
-
-// domainMatch implements "domain-match" of RFC 6265 section 5.1.3.
-func (e *entry) domainMatch(host string) bool {
-	if e.Domain == host {
-		return true
-	}
-	return !e.HostOnly && hasDotSuffix(host, e.Domain)
-}
-
-// pathMatch implements "path-match" according to RFC 6265 section 5.1.4.
-func (e *entry) pathMatch(requestPath string) bool {
-	if requestPath == e.Path {
-		return true
-	}
-	if strings.HasPrefix(requestPath, e.Path) {
-		if e.Path[len(e.Path)-1] == '/' {
-			return true // The "/any/" matches "/any/path" case.
-		} else if requestPath[len(e.Path)] == '/' {
-			return true // The "/any" matches "/any/path" case.
-		}
-	}
-	return false
-}
-
-// hasDotSuffix reports whether s ends in "."+suffix.
-func hasDotSuffix(s, suffix string) bool {
-	return len(s) > len(suffix) && s[len(s)-len(suffix)-1] == '.' && s[len(s)-len(suffix):] == suffix
-}
-
-// byPathLength is a []entry sort.Interface that sorts according to RFC 6265
-// section 5.4 point 2: by longest path and then by earliest creation time.
-type byPathLength []entry
-
-func (s byPathLength) Len() int { return len(s) }
-
-func (s byPathLength) Less(i, j int) bool {
-	if len(s[i].Path) != len(s[j].Path) {
-		return len(s[i].Path) > len(s[j].Path)
-	}
-	if !s[i].Creation.Equal(s[j].Creation) {
-		return s[i].Creation.Before(s[j].Creation)
-	}
-	return s[i].seqNum < s[j].seqNum
-}
-
-func (s byPathLength) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
-
-// Cookies implements the Cookies method of the http.CookieJar interface.
-//
-// It returns an empty slice if the URL's scheme is not HTTP or HTTPS.
-func (j *Jar) Cookies(u *url.URL) (cookies []*http.Cookie) {
-	return j.cookies(u, time.Now())
-}
-
-// cookies is like Cookies but takes the current time as a parameter.
-func (j *Jar) cookies(u *url.URL, now time.Time) (cookies []*http.Cookie) {
-	if u.Scheme != "http" && u.Scheme != "https" {
-		return cookies
-	}
-	host, err := canonicalHost(u.Host)
-	if err != nil {
-		return cookies
-	}
-	key := jarKey(host, j.psList)
-
-	j.mu.Lock()
-	defer j.mu.Unlock()
-
-	submap := j.entries[key]
-	if submap == nil {
-		return cookies
-	}
-
-	https := u.Scheme == "https"
-	path := u.Path
-	if path == "" {
-		path = "/"
-	}
-
-	modified := false
-	var selected []entry
-	for id, e := range submap {
-		if e.Persistent && !e.Expires.After(now) {
-			delete(submap, id)
-			modified = true
-			continue
-		}
-		if !e.shouldSend(https, host, path) {
-			continue
-		}
-		e.LastAccess = now
-		submap[id] = e
-		selected = append(selected, e)
-		modified = true
-	}
-	if modified {
-		if len(submap) == 0 {
-			delete(j.entries, key)
-		} else {
-			j.entries[key] = submap
-		}
-	}
-
-	sort.Sort(byPathLength(selected))
-	for _, e := range selected {
-		cookies = append(cookies, &http.Cookie{Name: e.Name, Value: e.Value})
-	}
-
-	return cookies
-}
-
-// SetCookies implements the SetCookies method of the http.CookieJar interface.
-//
-// It does nothing if the URL's scheme is not HTTP or HTTPS.
-func (j *Jar) SetCookies(u *url.URL, cookies []*http.Cookie) {
-	j.setCookies(u, cookies, time.Now())
-}
-
-// setCookies is like SetCookies but takes the current time as parameter.
-func (j *Jar) setCookies(u *url.URL, cookies []*http.Cookie, now time.Time) {
-	if len(cookies) == 0 {
-		return
-	}
-	if u.Scheme != "http" && u.Scheme != "https" {
-		return
-	}
-	host, err := canonicalHost(u.Host)
-	if err != nil {
-		return
-	}
-	key := jarKey(host, j.psList)
-	defPath := defaultPath(u.Path)
-
-	j.mu.Lock()
-	defer j.mu.Unlock()
-
-	submap := j.entries[key]
-
-	modified := false
-	for _, cookie := range cookies {
-		e, remove, err := j.newEntry(cookie, now, defPath, host)
-		if err != nil {
-			continue
-		}
-		id := e.id()
-		if remove {
-			if submap != nil {
-				if _, ok := submap[id]; ok {
-					delete(submap, id)
-					modified = true
-				}
-			}
-			continue
-		}
-		if submap == nil {
-			submap = make(map[string]entry)
-		}
-
-		if old, ok := submap[id]; ok {
-			e.Creation = old.Creation
-			e.seqNum = old.seqNum
-		} else {
-			e.Creation = now
-			e.seqNum = j.nextSeqNum
-			j.nextSeqNum++
-		}
-		e.LastAccess = now
-		submap[id] = e
-		modified = true
-	}
-
-	if modified {
-		if len(submap) == 0 {
-			delete(j.entries, key)
-		} else {
-			j.entries[key] = submap
-		}
-	}
-}
-
-// canonicalHost strips port from host if present and returns the canonicalized
-// host name.
-func canonicalHost(host string) (string, error) {
-	var err error
-	host = strings.ToLower(host)
-	if hasPort(host) {
-		host, _, err = net.SplitHostPort(host)
-		if err != nil {
-			return "", err
-		}
-	}
-	if strings.HasSuffix(host, ".") {
-		// Strip trailing dot from fully qualified domain names.
-		host = host[:len(host)-1]
-	}
-	return toASCII(host)
-}
-
-// hasPort reports whether host contains a port number. host may be a host
-// name, an IPv4 or an IPv6 address.
-func hasPort(host string) bool {
-	colons := strings.Count(host, ":")
-	if colons == 0 {
-		return false
-	}
-	if colons == 1 {
-		return true
-	}
-	return host[0] == '[' && strings.Contains(host, "]:")
-}
-
-// jarKey returns the key to use for a jar.
-func jarKey(host string, psl PublicSuffixList) string {
-	if isIP(host) {
-		return host
-	}
-
-	var i int
-	if psl == nil {
-		i = strings.LastIndex(host, ".")
-		if i == -1 {
-			return host
-		}
-	} else {
-		suffix := psl.PublicSuffix(host)
-		if suffix == host {
-			return host
-		}
-		i = len(host) - len(suffix)
-		if i <= 0 || host[i-1] != '.' {
-			// The provided public suffix list psl is broken.
-			// Storing cookies under host is a safe stopgap.
-			return host
-		}
-	}
-	prevDot := strings.LastIndex(host[:i-1], ".")
-	return host[prevDot+1:]
-}
-
-// isIP reports whether host is an IP address.
-func isIP(host string) bool {
-	return net.ParseIP(host) != nil
-}
-
-// defaultPath returns the directory part of an URL's path according to
-// RFC 6265 section 5.1.4.
-func defaultPath(path string) string {
-	if len(path) == 0 || path[0] != '/' {
-		return "/" // Path is empty or malformed.
-	}
-
-	i := strings.LastIndex(path, "/") // Path starts with "/", so i != -1.
-	if i == 0 {
-		return "/" // Path has the form "/abc".
-	}
-	return path[:i] // Path is either of form "/abc/xyz" or "/abc/xyz/".
-}
-
-// newEntry creates an entry from a http.Cookie c. now is the current time and
-// is compared to c.Expires to determine deletion of c. defPath and host are the
-// default-path and the canonical host name of the URL c was received from.
-//
-// remove records whether the jar should delete this cookie, as it has already
-// expired with respect to now. In this case, e may be incomplete, but it will
-// be valid to call e.id (which depends on e's Name, Domain and Path).
-//
-// A malformed c.Domain will result in an error.
-func (j *Jar) newEntry(c *http.Cookie, now time.Time, defPath, host string) (e entry, remove bool, err error) {
-	e.Name = c.Name
-
-	if c.Path == "" || c.Path[0] != '/' {
-		e.Path = defPath
-	} else {
-		e.Path = c.Path
-	}
-
-	e.Domain, e.HostOnly, err = j.domainAndType(host, c.Domain)
-	if err != nil {
-		return e, false, err
-	}
-
-	// MaxAge takes precedence over Expires.
-	if c.MaxAge < 0 {
-		return e, true, nil
-	} else if c.MaxAge > 0 {
-		e.Expires = now.Add(time.Duration(c.MaxAge) * time.Second)
-		e.Persistent = true
-	} else {
-		if c.Expires.IsZero() {
-			e.Expires = endOfTime
-			e.Persistent = false
-		} else {
-			if !c.Expires.After(now) {
-				return e, true, nil
-			}
-			e.Expires = c.Expires
-			e.Persistent = true
-		}
-	}
-
-	e.Value = c.Value
-	e.Secure = c.Secure
-	e.HttpOnly = c.HttpOnly
-
-	return e, false, nil
-}
-
-var (
-	errIllegalDomain   = errors.New("cookiejar: illegal cookie domain attribute")
-	errMalformedDomain = errors.New("cookiejar: malformed cookie domain attribute")
-	errNoHostname      = errors.New("cookiejar: no host name available (IP only)")
-)
-
-// endOfTime is the time when session (non-persistent) cookies expire.
-// This instant is representable in most date/time formats (not just
-// Go's time.Time) and should be far enough in the future.
-var endOfTime = time.Date(9999, 12, 31, 23, 59, 59, 0, time.UTC)
-
-// domainAndType determines the cookie's domain and hostOnly attribute.
-func (j *Jar) domainAndType(host, domain string) (string, bool, error) {
-	if domain == "" {
-		// No domain attribute in the SetCookie header indicates a
-		// host cookie.
-		return host, true, nil
-	}
-
-	if isIP(host) {
-		// According to RFC 6265 domain-matching includes not being
-		// an IP address.
-		// TODO: This might be relaxed as in common browsers.
-		return "", false, errNoHostname
-	}
-
-	// From here on: If the cookie is valid, it is a domain cookie (with
-	// the one exception of a public suffix below).
-	// See RFC 6265 section 5.2.3.
-	if domain[0] == '.' {
-		domain = domain[1:]
-	}
-
-	if len(domain) == 0 || domain[0] == '.' {
-		// Received either "Domain=." or "Domain=..some.thing",
-		// both are illegal.
-		return "", false, errMalformedDomain
-	}
-	domain = strings.ToLower(domain)
-
-	if domain[len(domain)-1] == '.' {
-		// We received stuff like "Domain=www.example.com.".
-		// Browsers do handle such stuff (actually differently) but
-		// RFC 6265 seems to be clear here (e.g. section 4.1.2.3) in
-		// requiring a reject.  4.1.2.3 is not normative, but
-		// "Domain Matching" (5.1.3) and "Canonicalized Host Names"
-		// (5.1.2) are.
-		return "", false, errMalformedDomain
-	}
-
-	// See RFC 6265 section 5.3 #5.
-	if j.psList != nil {
-		if ps := j.psList.PublicSuffix(domain); ps != "" && !hasDotSuffix(domain, ps) {
-			if host == domain {
-				// This is the one exception in which a cookie
-				// with a domain attribute is a host cookie.
-				return host, true, nil
-			}
-			return "", false, errIllegalDomain
-		}
-	}
-
-	// The domain must domain-match host: www.mycompany.com cannot
-	// set cookies for .ourcompetitors.com.
-	if host != domain && !hasDotSuffix(host, domain) {
-		return "", false, errIllegalDomain
-	}
-
-	return domain, false, nil
-}
diff --git a/src/pkg/net/http/export_test.go b/src/pkg/net/http/export_test.go
deleted file mode 100644
index 960563b..0000000
--- a/src/pkg/net/http/export_test.go
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright 2011 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Bridge package to expose http internals to tests in the http_test
-// package.
-
-package http
-
-import (
-	"net"
-	"time"
-)
-
-func NewLoggingConn(baseName string, c net.Conn) net.Conn {
-	return newLoggingConn(baseName, c)
-}
-
-var ExportAppendTime = appendTime
-
-func (t *Transport) NumPendingRequestsForTesting() int {
-	t.reqMu.Lock()
-	defer t.reqMu.Unlock()
-	return len(t.reqCanceler)
-}
-
-func (t *Transport) IdleConnKeysForTesting() (keys []string) {
-	keys = make([]string, 0)
-	t.idleMu.Lock()
-	defer t.idleMu.Unlock()
-	if t.idleConn == nil {
-		return
-	}
-	for key := range t.idleConn {
-		keys = append(keys, key.String())
-	}
-	return
-}
-
-func (t *Transport) IdleConnCountForTesting(cacheKey string) int {
-	t.idleMu.Lock()
-	defer t.idleMu.Unlock()
-	if t.idleConn == nil {
-		return 0
-	}
-	for k, conns := range t.idleConn {
-		if k.String() == cacheKey {
-			return len(conns)
-		}
-	}
-	return 0
-}
-
-func (t *Transport) IdleConnChMapSizeForTesting() int {
-	t.idleMu.Lock()
-	defer t.idleMu.Unlock()
-	return len(t.idleConnCh)
-}
-
-func NewTestTimeoutHandler(handler Handler, ch <-chan time.Time) Handler {
-	f := func() <-chan time.Time {
-		return ch
-	}
-	return &timeoutHandler{handler, f, ""}
-}
-
-func ResetCachedEnvironment() {
-	httpProxyEnv.reset()
-	noProxyEnv.reset()
-}
-
-var DefaultUserAgent = defaultUserAgent
diff --git a/src/pkg/net/http/fs.go b/src/pkg/net/http/fs.go
deleted file mode 100644
index 8576cf8..0000000
--- a/src/pkg/net/http/fs.go
+++ /dev/null
@@ -1,549 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// HTTP file system request handler
-
-package http
-
-import (
-	"errors"
-	"fmt"
-	"io"
-	"mime"
-	"mime/multipart"
-	"net/textproto"
-	"net/url"
-	"os"
-	"path"
-	"path/filepath"
-	"strconv"
-	"strings"
-	"time"
-)
-
-// A Dir implements http.FileSystem using the native file
-// system restricted to a specific directory tree.
-//
-// An empty Dir is treated as ".".
-type Dir string
-
-func (d Dir) Open(name string) (File, error) {
-	if filepath.Separator != '/' && strings.IndexRune(name, filepath.Separator) >= 0 ||
-		strings.Contains(name, "\x00") {
-		return nil, errors.New("http: invalid character in file path")
-	}
-	dir := string(d)
-	if dir == "" {
-		dir = "."
-	}
-	f, err := os.Open(filepath.Join(dir, filepath.FromSlash(path.Clean("/"+name))))
-	if err != nil {
-		return nil, err
-	}
-	return f, nil
-}
-
-// A FileSystem implements access to a collection of named files.
-// The elements in a file path are separated by slash ('/', U+002F)
-// characters, regardless of host operating system convention.
-type FileSystem interface {
-	Open(name string) (File, error)
-}
-
-// A File is returned by a FileSystem's Open method and can be
-// served by the FileServer implementation.
-//
-// The methods should behave the same as those on an *os.File.
-type File interface {
-	io.Closer
-	io.Reader
-	Readdir(count int) ([]os.FileInfo, error)
-	Seek(offset int64, whence int) (int64, error)
-	Stat() (os.FileInfo, error)
-}
-
-func dirList(w ResponseWriter, f File) {
-	w.Header().Set("Content-Type", "text/html; charset=utf-8")
-	fmt.Fprintf(w, "<pre>\n")
-	for {
-		dirs, err := f.Readdir(100)
-		if err != nil || len(dirs) == 0 {
-			break
-		}
-		for _, d := range dirs {
-			name := d.Name()
-			if d.IsDir() {
-				name += "/"
-			}
-			// name may contain '?' or '#', which must be escaped to remain
-			// part of the URL path, and not indicate the start of a query
-			// string or fragment.
-			url := url.URL{Path: name}
-			fmt.Fprintf(w, "<a href=\"%s\">%s</a>\n", url.String(), htmlReplacer.Replace(name))
-		}
-	}
-	fmt.Fprintf(w, "</pre>\n")
-}
-
-// ServeContent replies to the request using the content in the
-// provided ReadSeeker.  The main benefit of ServeContent over io.Copy
-// is that it handles Range requests properly, sets the MIME type, and
-// handles If-Modified-Since requests.
-//
-// If the response's Content-Type header is not set, ServeContent
-// first tries to deduce the type from name's file extension and,
-// if that fails, falls back to reading the first block of the content
-// and passing it to DetectContentType.
-// The name is otherwise unused; in particular it can be empty and is
-// never sent in the response.
-//
-// If modtime is not the zero time, ServeContent includes it in a
-// Last-Modified header in the response.  If the request includes an
-// If-Modified-Since header, ServeContent uses modtime to decide
-// whether the content needs to be sent at all.
-//
-// The content's Seek method must work: ServeContent uses
-// a seek to the end of the content to determine its size.
-//
-// If the caller has set w's ETag header, ServeContent uses it to
-// handle requests using If-Range and If-None-Match.
-//
-// Note that *os.File implements the io.ReadSeeker interface.
-func ServeContent(w ResponseWriter, req *Request, name string, modtime time.Time, content io.ReadSeeker) {
-	sizeFunc := func() (int64, error) {
-		size, err := content.Seek(0, os.SEEK_END)
-		if err != nil {
-			return 0, errSeeker
-		}
-		_, err = content.Seek(0, os.SEEK_SET)
-		if err != nil {
-			return 0, errSeeker
-		}
-		return size, nil
-	}
-	serveContent(w, req, name, modtime, sizeFunc, content)
-}
-
-// errSeeker is returned by ServeContent's sizeFunc when the content
-// doesn't seek properly. The underlying Seeker's error text isn't
-// included in the sizeFunc reply so it's not sent over HTTP to end
-// users.
-var errSeeker = errors.New("seeker can't seek")
-
-// if name is empty, filename is unknown. (used for mime type, before sniffing)
-// if modtime.IsZero(), modtime is unknown.
-// content must be seeked to the beginning of the file.
-// The sizeFunc is called at most once. Its error, if any, is sent in the HTTP response.
-func serveContent(w ResponseWriter, r *Request, name string, modtime time.Time, sizeFunc func() (int64, error), content io.ReadSeeker) {
-	if checkLastModified(w, r, modtime) {
-		return
-	}
-	rangeReq, done := checkETag(w, r)
-	if done {
-		return
-	}
-
-	code := StatusOK
-
-	// If Content-Type isn't set, use the file's extension to find it, but
-	// if the Content-Type is unset explicitly, do not sniff the type.
-	ctypes, haveType := w.Header()["Content-Type"]
-	var ctype string
-	if !haveType {
-		ctype = mime.TypeByExtension(filepath.Ext(name))
-		if ctype == "" {
-			// read a chunk to decide between utf-8 text and binary
-			var buf [sniffLen]byte
-			n, _ := io.ReadFull(content, buf[:])
-			ctype = DetectContentType(buf[:n])
-			_, err := content.Seek(0, os.SEEK_SET) // rewind to output whole file
-			if err != nil {
-				Error(w, "seeker can't seek", StatusInternalServerError)
-				return
-			}
-		}
-		w.Header().Set("Content-Type", ctype)
-	} else if len(ctypes) > 0 {
-		ctype = ctypes[0]
-	}
-
-	size, err := sizeFunc()
-	if err != nil {
-		Error(w, err.Error(), StatusInternalServerError)
-		return
-	}
-
-	// handle Content-Range header.
-	sendSize := size
-	var sendContent io.Reader = content
-	if size >= 0 {
-		ranges, err := parseRange(rangeReq, size)
-		if err != nil {
-			Error(w, err.Error(), StatusRequestedRangeNotSatisfiable)
-			return
-		}
-		if sumRangesSize(ranges) > size {
-			// The total number of bytes in all the ranges
-			// is larger than the size of the file by
-			// itself, so this is probably an attack, or a
-			// dumb client.  Ignore the range request.
-			ranges = nil
-		}
-		switch {
-		case len(ranges) == 1:
-			// RFC 2616, Section 14.16:
-			// "When an HTTP message includes the content of a single
-			// range (for example, a response to a request for a
-			// single range, or to a request for a set of ranges
-			// that overlap without any holes), this content is
-			// transmitted with a Content-Range header, and a
-			// Content-Length header showing the number of bytes
-			// actually transferred.
-			// ...
-			// A response to a request for a single range MUST NOT
-			// be sent using the multipart/byteranges media type."
-			ra := ranges[0]
-			if _, err := content.Seek(ra.start, os.SEEK_SET); err != nil {
-				Error(w, err.Error(), StatusRequestedRangeNotSatisfiable)
-				return
-			}
-			sendSize = ra.length
-			code = StatusPartialContent
-			w.Header().Set("Content-Range", ra.contentRange(size))
-		case len(ranges) > 1:
-			for _, ra := range ranges {
-				if ra.start > size {
-					Error(w, err.Error(), StatusRequestedRangeNotSatisfiable)
-					return
-				}
-			}
-			sendSize = rangesMIMESize(ranges, ctype, size)
-			code = StatusPartialContent
-
-			pr, pw := io.Pipe()
-			mw := multipart.NewWriter(pw)
-			w.Header().Set("Content-Type", "multipart/byteranges; boundary="+mw.Boundary())
-			sendContent = pr
-			defer pr.Close() // cause writing goroutine to fail and exit if CopyN doesn't finish.
-			go func() {
-				for _, ra := range ranges {
-					part, err := mw.CreatePart(ra.mimeHeader(ctype, size))
-					if err != nil {
-						pw.CloseWithError(err)
-						return
-					}
-					if _, err := content.Seek(ra.start, os.SEEK_SET); err != nil {
-						pw.CloseWithError(err)
-						return
-					}
-					if _, err := io.CopyN(part, content, ra.length); err != nil {
-						pw.CloseWithError(err)
-						return
-					}
-				}
-				mw.Close()
-				pw.Close()
-			}()
-		}
-
-		w.Header().Set("Accept-Ranges", "bytes")
-		if w.Header().Get("Content-Encoding") == "" {
-			w.Header().Set("Content-Length", strconv.FormatInt(sendSize, 10))
-		}
-	}
-
-	w.WriteHeader(code)
-
-	if r.Method != "HEAD" {
-		io.CopyN(w, sendContent, sendSize)
-	}
-}
-
-// modtime is the modification time of the resource to be served, or IsZero().
-// return value is whether this request is now complete.
-func checkLastModified(w ResponseWriter, r *Request, modtime time.Time) bool {
-	if modtime.IsZero() {
-		return false
-	}
-
-	// The Date-Modified header truncates sub-second precision, so
-	// use mtime < t+1s instead of mtime <= t to check for unmodified.
-	if t, err := time.Parse(TimeFormat, r.Header.Get("If-Modified-Since")); err == nil && modtime.Before(t.Add(1*time.Second)) {
-		h := w.Header()
-		delete(h, "Content-Type")
-		delete(h, "Content-Length")
-		w.WriteHeader(StatusNotModified)
-		return true
-	}
-	w.Header().Set("Last-Modified", modtime.UTC().Format(TimeFormat))
-	return false
-}
-
-// checkETag implements If-None-Match and If-Range checks.
-// The ETag must have been previously set in the ResponseWriter's headers.
-//
-// The return value is the effective request "Range" header to use and
-// whether this request is now considered done.
-func checkETag(w ResponseWriter, r *Request) (rangeReq string, done bool) {
-	etag := w.Header().get("Etag")
-	rangeReq = r.Header.get("Range")
-
-	// Invalidate the range request if the entity doesn't match the one
-	// the client was expecting.
-	// "If-Range: version" means "ignore the Range: header unless version matches the
-	// current file."
-	// We only support ETag versions.
-	// The caller must have set the ETag on the response already.
-	if ir := r.Header.get("If-Range"); ir != "" && ir != etag {
-		// TODO(bradfitz): handle If-Range requests with Last-Modified
-		// times instead of ETags? I'd rather not, at least for
-		// now. That seems like a bug/compromise in the RFC 2616, and
-		// I've never heard of anybody caring about that (yet).
-		rangeReq = ""
-	}
-
-	if inm := r.Header.get("If-None-Match"); inm != "" {
-		// Must know ETag.
-		if etag == "" {
-			return rangeReq, false
-		}
-
-		// TODO(bradfitz): non-GET/HEAD requests require more work:
-		// sending a different status code on matches, and
-		// also can't use weak cache validators (those with a "W/
-		// prefix).  But most users of ServeContent will be using
-		// it on GET or HEAD, so only support those for now.
-		if r.Method != "GET" && r.Method != "HEAD" {
-			return rangeReq, false
-		}
-
-		// TODO(bradfitz): deal with comma-separated or multiple-valued
-		// list of If-None-match values.  For now just handle the common
-		// case of a single item.
-		if inm == etag || inm == "*" {
-			h := w.Header()
-			delete(h, "Content-Type")
-			delete(h, "Content-Length")
-			w.WriteHeader(StatusNotModified)
-			return "", true
-		}
-	}
-	return rangeReq, false
-}
-
-// name is '/'-separated, not filepath.Separator.
-func serveFile(w ResponseWriter, r *Request, fs FileSystem, name string, redirect bool) {
-	const indexPage = "/index.html"
-
-	// redirect .../index.html to .../
-	// can't use Redirect() because that would make the path absolute,
-	// which would be a problem running under StripPrefix
-	if strings.HasSuffix(r.URL.Path, indexPage) {
-		localRedirect(w, r, "./")
-		return
-	}
-
-	f, err := fs.Open(name)
-	if err != nil {
-		// TODO expose actual error?
-		NotFound(w, r)
-		return
-	}
-	defer f.Close()
-
-	d, err1 := f.Stat()
-	if err1 != nil {
-		// TODO expose actual error?
-		NotFound(w, r)
-		return
-	}
-
-	if redirect {
-		// redirect to canonical path: / at end of directory url
-		// r.URL.Path always begins with /
-		url := r.URL.Path
-		if d.IsDir() {
-			if url[len(url)-1] != '/' {
-				localRedirect(w, r, path.Base(url)+"/")
-				return
-			}
-		} else {
-			if url[len(url)-1] == '/' {
-				localRedirect(w, r, "../"+path.Base(url))
-				return
-			}
-		}
-	}
-
-	// use contents of index.html for directory, if present
-	if d.IsDir() {
-		index := name + indexPage
-		ff, err := fs.Open(index)
-		if err == nil {
-			defer ff.Close()
-			dd, err := ff.Stat()
-			if err == nil {
-				name = index
-				d = dd
-				f = ff
-			}
-		}
-	}
-
-	// Still a directory? (we didn't find an index.html file)
-	if d.IsDir() {
-		if checkLastModified(w, r, d.ModTime()) {
-			return
-		}
-		dirList(w, f)
-		return
-	}
-
-	// serverContent will check modification time
-	sizeFunc := func() (int64, error) { return d.Size(), nil }
-	serveContent(w, r, d.Name(), d.ModTime(), sizeFunc, f)
-}
-
-// localRedirect gives a Moved Permanently response.
-// It does not convert relative paths to absolute paths like Redirect does.
-func localRedirect(w ResponseWriter, r *Request, newPath string) {
-	if q := r.URL.RawQuery; q != "" {
-		newPath += "?" + q
-	}
-	w.Header().Set("Location", newPath)
-	w.WriteHeader(StatusMovedPermanently)
-}
-
-// ServeFile replies to the request with the contents of the named file or directory.
-func ServeFile(w ResponseWriter, r *Request, name string) {
-	dir, file := filepath.Split(name)
-	serveFile(w, r, Dir(dir), file, false)
-}
-
-type fileHandler struct {
-	root FileSystem
-}
-
-// FileServer returns a handler that serves HTTP requests
-// with the contents of the file system rooted at root.
-//
-// To use the operating system's file system implementation,
-// use http.Dir:
-//
-//     http.Handle("/", http.FileServer(http.Dir("/tmp")))
-func FileServer(root FileSystem) Handler {
-	return &fileHandler{root}
-}
-
-func (f *fileHandler) ServeHTTP(w ResponseWriter, r *Request) {
-	upath := r.URL.Path
-	if !strings.HasPrefix(upath, "/") {
-		upath = "/" + upath
-		r.URL.Path = upath
-	}
-	serveFile(w, r, f.root, path.Clean(upath), true)
-}
-
-// httpRange specifies the byte range to be sent to the client.
-type httpRange struct {
-	start, length int64
-}
-
-func (r httpRange) contentRange(size int64) string {
-	return fmt.Sprintf("bytes %d-%d/%d", r.start, r.start+r.length-1, size)
-}
-
-func (r httpRange) mimeHeader(contentType string, size int64) textproto.MIMEHeader {
-	return textproto.MIMEHeader{
-		"Content-Range": {r.contentRange(size)},
-		"Content-Type":  {contentType},
-	}
-}
-
-// parseRange parses a Range header string as per RFC 2616.
-func parseRange(s string, size int64) ([]httpRange, error) {
-	if s == "" {
-		return nil, nil // header not present
-	}
-	const b = "bytes="
-	if !strings.HasPrefix(s, b) {
-		return nil, errors.New("invalid range")
-	}
-	var ranges []httpRange
-	for _, ra := range strings.Split(s[len(b):], ",") {
-		ra = strings.TrimSpace(ra)
-		if ra == "" {
-			continue
-		}
-		i := strings.Index(ra, "-")
-		if i < 0 {
-			return nil, errors.New("invalid range")
-		}
-		start, end := strings.TrimSpace(ra[:i]), strings.TrimSpace(ra[i+1:])
-		var r httpRange
-		if start == "" {
-			// If no start is specified, end specifies the
-			// range start relative to the end of the file.
-			i, err := strconv.ParseInt(end, 10, 64)
-			if err != nil {
-				return nil, errors.New("invalid range")
-			}
-			if i > size {
-				i = size
-			}
-			r.start = size - i
-			r.length = size - r.start
-		} else {
-			i, err := strconv.ParseInt(start, 10, 64)
-			if err != nil || i > size || i < 0 {
-				return nil, errors.New("invalid range")
-			}
-			r.start = i
-			if end == "" {
-				// If no end is specified, range extends to end of the file.
-				r.length = size - r.start
-			} else {
-				i, err := strconv.ParseInt(end, 10, 64)
-				if err != nil || r.start > i {
-					return nil, errors.New("invalid range")
-				}
-				if i >= size {
-					i = size - 1
-				}
-				r.length = i - r.start + 1
-			}
-		}
-		ranges = append(ranges, r)
-	}
-	return ranges, nil
-}
-
-// countingWriter counts how many bytes have been written to it.
-type countingWriter int64
-
-func (w *countingWriter) Write(p []byte) (n int, err error) {
-	*w += countingWriter(len(p))
-	return len(p), nil
-}
-
-// rangesMIMESize returns the number of bytes it takes to encode the
-// provided ranges as a multipart response.
-func rangesMIMESize(ranges []httpRange, contentType string, contentSize int64) (encSize int64) {
-	var w countingWriter
-	mw := multipart.NewWriter(&w)
-	for _, ra := range ranges {
-		mw.CreatePart(ra.mimeHeader(contentType, contentSize))
-		encSize += ra.length
-	}
-	mw.Close()
-	encSize += int64(w)
-	return
-}
-
-func sumRangesSize(ranges []httpRange) (size int64) {
-	for _, ra := range ranges {
-		size += ra.length
-	}
-	return
-}
diff --git a/src/pkg/net/http/fs_test.go b/src/pkg/net/http/fs_test.go
deleted file mode 100644
index f968565..0000000
--- a/src/pkg/net/http/fs_test.go
+++ /dev/null
@@ -1,858 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package http_test
-
-import (
-	"bytes"
-	"errors"
-	"fmt"
-	"io"
-	"io/ioutil"
-	"mime"
-	"mime/multipart"
-	"net"
-	. "net/http"
-	"net/http/httptest"
-	"net/url"
-	"os"
-	"os/exec"
-	"path"
-	"path/filepath"
-	"reflect"
-	"regexp"
-	"runtime"
-	"strconv"
-	"strings"
-	"testing"
-	"time"
-)
-
-const (
-	testFile    = "testdata/file"
-	testFileLen = 11
-)
-
-type wantRange struct {
-	start, end int64 // range [start,end)
-}
-
-var itoa = strconv.Itoa
-
-var ServeFileRangeTests = []struct {
-	r      string
-	code   int
-	ranges []wantRange
-}{
-	{r: "", code: StatusOK},
-	{r: "bytes=0-4", code: StatusPartialContent, ranges: []wantRange{{0, 5}}},
-	{r: "bytes=2-", code: StatusPartialContent, ranges: []wantRange{{2, testFileLen}}},
-	{r: "bytes=-5", code: StatusPartialContent, ranges: []wantRange{{testFileLen - 5, testFileLen}}},
-	{r: "bytes=3-7", code: StatusPartialContent, ranges: []wantRange{{3, 8}}},
-	{r: "bytes=20-", code: StatusRequestedRangeNotSatisfiable},
-	{r: "bytes=0-0,-2", code: StatusPartialContent, ranges: []wantRange{{0, 1}, {testFileLen - 2, testFileLen}}},
-	{r: "bytes=0-1,5-8", code: StatusPartialContent, ranges: []wantRange{{0, 2}, {5, 9}}},
-	{r: "bytes=0-1,5-", code: StatusPartialContent, ranges: []wantRange{{0, 2}, {5, testFileLen}}},
-	{r: "bytes=5-1000", code: StatusPartialContent, ranges: []wantRange{{5, testFileLen}}},
-	{r: "bytes=0-,1-,2-,3-,4-", code: StatusOK}, // ignore wasteful range request
-	{r: "bytes=0-" + itoa(testFileLen-2), code: StatusPartialContent, ranges: []wantRange{{0, testFileLen - 1}}},
-	{r: "bytes=0-" + itoa(testFileLen-1), code: StatusPartialContent, ranges: []wantRange{{0, testFileLen}}},
-	{r: "bytes=0-" + itoa(testFileLen), code: StatusPartialContent, ranges: []wantRange{{0, testFileLen}}},
-}
-
-func TestServeFile(t *testing.T) {
-	defer afterTest(t)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
-		ServeFile(w, r, "testdata/file")
-	}))
-	defer ts.Close()
-
-	var err error
-
-	file, err := ioutil.ReadFile(testFile)
-	if err != nil {
-		t.Fatal("reading file:", err)
-	}
-
-	// set up the Request (re-used for all tests)
-	var req Request
-	req.Header = make(Header)
-	if req.URL, err = url.Parse(ts.URL); err != nil {
-		t.Fatal("ParseURL:", err)
-	}
-	req.Method = "GET"
-
-	// straight GET
-	_, body := getBody(t, "straight get", req)
-	if !bytes.Equal(body, file) {
-		t.Fatalf("body mismatch: got %q, want %q", body, file)
-	}
-
-	// Range tests
-Cases:
-	for _, rt := range ServeFileRangeTests {
-		if rt.r != "" {
-			req.Header.Set("Range", rt.r)
-		}
-		resp, body := getBody(t, fmt.Sprintf("range test %q", rt.r), req)
-		if resp.StatusCode != rt.code {
-			t.Errorf("range=%q: StatusCode=%d, want %d", rt.r, resp.StatusCode, rt.code)
-		}
-		if rt.code == StatusRequestedRangeNotSatisfiable {
-			continue
-		}
-		wantContentRange := ""
-		if len(rt.ranges) == 1 {
-			rng := rt.ranges[0]
-			wantContentRange = fmt.Sprintf("bytes %d-%d/%d", rng.start, rng.end-1, testFileLen)
-		}
-		cr := resp.Header.Get("Content-Range")
-		if cr != wantContentRange {
-			t.Errorf("range=%q: Content-Range = %q, want %q", rt.r, cr, wantContentRange)
-		}
-		ct := resp.Header.Get("Content-Type")
-		if len(rt.ranges) == 1 {
-			rng := rt.ranges[0]
-			wantBody := file[rng.start:rng.end]
-			if !bytes.Equal(body, wantBody) {
-				t.Errorf("range=%q: body = %q, want %q", rt.r, body, wantBody)
-			}
-			if strings.HasPrefix(ct, "multipart/byteranges") {
-				t.Errorf("range=%q content-type = %q; unexpected multipart/byteranges", rt.r, ct)
-			}
-		}
-		if len(rt.ranges) > 1 {
-			typ, params, err := mime.ParseMediaType(ct)
-			if err != nil {
-				t.Errorf("range=%q content-type = %q; %v", rt.r, ct, err)
-				continue
-			}
-			if typ != "multipart/byteranges" {
-				t.Errorf("range=%q content-type = %q; want multipart/byteranges", rt.r, typ)
-				continue
-			}
-			if params["boundary"] == "" {
-				t.Errorf("range=%q content-type = %q; lacks boundary", rt.r, ct)
-				continue
-			}
-			if g, w := resp.ContentLength, int64(len(body)); g != w {
-				t.Errorf("range=%q Content-Length = %d; want %d", rt.r, g, w)
-				continue
-			}
-			mr := multipart.NewReader(bytes.NewReader(body), params["boundary"])
-			for ri, rng := range rt.ranges {
-				part, err := mr.NextPart()
-				if err != nil {
-					t.Errorf("range=%q, reading part index %d: %v", rt.r, ri, err)
-					continue Cases
-				}
-				wantContentRange = fmt.Sprintf("bytes %d-%d/%d", rng.start, rng.end-1, testFileLen)
-				if g, w := part.Header.Get("Content-Range"), wantContentRange; g != w {
-					t.Errorf("range=%q: part Content-Range = %q; want %q", rt.r, g, w)
-				}
-				body, err := ioutil.ReadAll(part)
-				if err != nil {
-					t.Errorf("range=%q, reading part index %d body: %v", rt.r, ri, err)
-					continue Cases
-				}
-				wantBody := file[rng.start:rng.end]
-				if !bytes.Equal(body, wantBody) {
-					t.Errorf("range=%q: body = %q, want %q", rt.r, body, wantBody)
-				}
-			}
-			_, err = mr.NextPart()
-			if err != io.EOF {
-				t.Errorf("range=%q; expected final error io.EOF; got %v", rt.r, err)
-			}
-		}
-	}
-}
-
-var fsRedirectTestData = []struct {
-	original, redirect string
-}{
-	{"/test/index.html", "/test/"},
-	{"/test/testdata", "/test/testdata/"},
-	{"/test/testdata/file/", "/test/testdata/file"},
-}
-
-func TestFSRedirect(t *testing.T) {
-	defer afterTest(t)
-	ts := httptest.NewServer(StripPrefix("/test", FileServer(Dir("."))))
-	defer ts.Close()
-
-	for _, data := range fsRedirectTestData {
-		res, err := Get(ts.URL + data.original)
-		if err != nil {
-			t.Fatal(err)
-		}
-		res.Body.Close()
-		if g, e := res.Request.URL.Path, data.redirect; g != e {
-			t.Errorf("redirect from %s: got %s, want %s", data.original, g, e)
-		}
-	}
-}
-
-type testFileSystem struct {
-	open func(name string) (File, error)
-}
-
-func (fs *testFileSystem) Open(name string) (File, error) {
-	return fs.open(name)
-}
-
-func TestFileServerCleans(t *testing.T) {
-	defer afterTest(t)
-	ch := make(chan string, 1)
-	fs := FileServer(&testFileSystem{func(name string) (File, error) {
-		ch <- name
-		return nil, errors.New("file does not exist")
-	}})
-	tests := []struct {
-		reqPath, openArg string
-	}{
-		{"/foo.txt", "/foo.txt"},
-		{"//foo.txt", "/foo.txt"},
-		{"/../foo.txt", "/foo.txt"},
-	}
-	req, _ := NewRequest("GET", "http://example.com", nil)
-	for n, test := range tests {
-		rec := httptest.NewRecorder()
-		req.URL.Path = test.reqPath
-		fs.ServeHTTP(rec, req)
-		if got := <-ch; got != test.openArg {
-			t.Errorf("test %d: got %q, want %q", n, got, test.openArg)
-		}
-	}
-}
-
-func TestFileServerEscapesNames(t *testing.T) {
-	defer afterTest(t)
-	const dirListPrefix = "<pre>\n"
-	const dirListSuffix = "\n</pre>\n"
-	tests := []struct {
-		name, escaped string
-	}{
-		{`simple_name`, `<a href="simple_name">simple_name</a>`},
-		{`"'<>&`, `<a href="%22%27%3C%3E&">"'<>&</a>`},
-		{`?foo=bar#baz`, `<a href="%3Ffoo=bar%23baz">?foo=bar#baz</a>`},
-		{`<combo>?foo`, `<a href="%3Ccombo%3E%3Ffoo"><combo>?foo</a>`},
-	}
-
-	// We put each test file in its own directory in the fakeFS so we can look at it in isolation.
-	fs := make(fakeFS)
-	for i, test := range tests {
-		testFile := &fakeFileInfo{basename: test.name}
-		fs[fmt.Sprintf("/%d", i)] = &fakeFileInfo{
-			dir:     true,
-			modtime: time.Unix(1000000000, 0).UTC(),
-			ents:    []*fakeFileInfo{testFile},
-		}
-		fs[fmt.Sprintf("/%d/%s", i, test.name)] = testFile
-	}
-
-	ts := httptest.NewServer(FileServer(&fs))
-	defer ts.Close()
-	for i, test := range tests {
-		url := fmt.Sprintf("%s/%d", ts.URL, i)
-		res, err := Get(url)
-		if err != nil {
-			t.Fatalf("test %q: Get: %v", test.name, err)
-		}
-		b, err := ioutil.ReadAll(res.Body)
-		if err != nil {
-			t.Fatalf("test %q: read Body: %v", test.name, err)
-		}
-		s := string(b)
-		if !strings.HasPrefix(s, dirListPrefix) || !strings.HasSuffix(s, dirListSuffix) {
-			t.Errorf("test %q: listing dir, full output is %q, want prefix %q and suffix %q", test.name, s, dirListPrefix, dirListSuffix)
-		}
-		if trimmed := strings.TrimSuffix(strings.TrimPrefix(s, dirListPrefix), dirListSuffix); trimmed != test.escaped {
-			t.Errorf("test %q: listing dir, filename escaped to %q, want %q", test.name, trimmed, test.escaped)
-		}
-		res.Body.Close()
-	}
-}
-
-func mustRemoveAll(dir string) {
-	err := os.RemoveAll(dir)
-	if err != nil {
-		panic(err)
-	}
-}
-
-func TestFileServerImplicitLeadingSlash(t *testing.T) {
-	defer afterTest(t)
-	tempDir, err := ioutil.TempDir("", "")
-	if err != nil {
-		t.Fatalf("TempDir: %v", err)
-	}
-	defer mustRemoveAll(tempDir)
-	if err := ioutil.WriteFile(filepath.Join(tempDir, "foo.txt"), []byte("Hello world"), 0644); err != nil {
-		t.Fatalf("WriteFile: %v", err)
-	}
-	ts := httptest.NewServer(StripPrefix("/bar/", FileServer(Dir(tempDir))))
-	defer ts.Close()
-	get := func(suffix string) string {
-		res, err := Get(ts.URL + suffix)
-		if err != nil {
-			t.Fatalf("Get %s: %v", suffix, err)
-		}
-		b, err := ioutil.ReadAll(res.Body)
-		if err != nil {
-			t.Fatalf("ReadAll %s: %v", suffix, err)
-		}
-		res.Body.Close()
-		return string(b)
-	}
-	if s := get("/bar/"); !strings.Contains(s, ">foo.txt<") {
-		t.Logf("expected a directory listing with foo.txt, got %q", s)
-	}
-	if s := get("/bar/foo.txt"); s != "Hello world" {
-		t.Logf("expected %q, got %q", "Hello world", s)
-	}
-}
-
-func TestDirJoin(t *testing.T) {
-	if runtime.GOOS == "windows" {
-		t.Skip("skipping test on windows")
-	}
-	wfi, err := os.Stat("/etc/hosts")
-	if err != nil {
-		t.Skip("skipping test; no /etc/hosts file")
-	}
-	test := func(d Dir, name string) {
-		f, err := d.Open(name)
-		if err != nil {
-			t.Fatalf("open of %s: %v", name, err)
-		}
-		defer f.Close()
-		gfi, err := f.Stat()
-		if err != nil {
-			t.Fatalf("stat of %s: %v", name, err)
-		}
-		if !os.SameFile(gfi, wfi) {
-			t.Errorf("%s got different file", name)
-		}
-	}
-	test(Dir("/etc/"), "/hosts")
-	test(Dir("/etc/"), "hosts")
-	test(Dir("/etc/"), "../../../../hosts")
-	test(Dir("/etc"), "/hosts")
-	test(Dir("/etc"), "hosts")
-	test(Dir("/etc"), "../../../../hosts")
-
-	// Not really directories, but since we use this trick in
-	// ServeFile, test it:
-	test(Dir("/etc/hosts"), "")
-	test(Dir("/etc/hosts"), "/")
-	test(Dir("/etc/hosts"), "../")
-}
-
-func TestEmptyDirOpenCWD(t *testing.T) {
-	test := func(d Dir) {
-		name := "fs_test.go"
-		f, err := d.Open(name)
-		if err != nil {
-			t.Fatalf("open of %s: %v", name, err)
-		}
-		defer f.Close()
-	}
-	test(Dir(""))
-	test(Dir("."))
-	test(Dir("./"))
-}
-
-func TestServeFileContentType(t *testing.T) {
-	defer afterTest(t)
-	const ctype = "icecream/chocolate"
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
-		switch r.FormValue("override") {
-		case "1":
-			w.Header().Set("Content-Type", ctype)
-		case "2":
-			// Explicitly inhibit sniffing.
-			w.Header()["Content-Type"] = []string{}
-		}
-		ServeFile(w, r, "testdata/file")
-	}))
-	defer ts.Close()
-	get := func(override string, want []string) {
-		resp, err := Get(ts.URL + "?override=" + override)
-		if err != nil {
-			t.Fatal(err)
-		}
-		if h := resp.Header["Content-Type"]; !reflect.DeepEqual(h, want) {
-			t.Errorf("Content-Type mismatch: got %v, want %v", h, want)
-		}
-		resp.Body.Close()
-	}
-	get("0", []string{"text/plain; charset=utf-8"})
-	get("1", []string{ctype})
-	get("2", nil)
-}
-
-func TestServeFileMimeType(t *testing.T) {
-	defer afterTest(t)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
-		ServeFile(w, r, "testdata/style.css")
-	}))
-	defer ts.Close()
-	resp, err := Get(ts.URL)
-	if err != nil {
-		t.Fatal(err)
-	}
-	resp.Body.Close()
-	want := "text/css; charset=utf-8"
-	if h := resp.Header.Get("Content-Type"); h != want {
-		t.Errorf("Content-Type mismatch: got %q, want %q", h, want)
-	}
-}
-
-func TestServeFileFromCWD(t *testing.T) {
-	defer afterTest(t)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
-		ServeFile(w, r, "fs_test.go")
-	}))
-	defer ts.Close()
-	r, err := Get(ts.URL)
-	if err != nil {
-		t.Fatal(err)
-	}
-	r.Body.Close()
-	if r.StatusCode != 200 {
-		t.Fatalf("expected 200 OK, got %s", r.Status)
-	}
-}
-
-func TestServeFileWithContentEncoding(t *testing.T) {
-	defer afterTest(t)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
-		w.Header().Set("Content-Encoding", "foo")
-		ServeFile(w, r, "testdata/file")
-	}))
-	defer ts.Close()
-	resp, err := Get(ts.URL)
-	if err != nil {
-		t.Fatal(err)
-	}
-	resp.Body.Close()
-	if g, e := resp.ContentLength, int64(-1); g != e {
-		t.Errorf("Content-Length mismatch: got %d, want %d", g, e)
-	}
-}
-
-func TestServeIndexHtml(t *testing.T) {
-	defer afterTest(t)
-	const want = "index.html says hello\n"
-	ts := httptest.NewServer(FileServer(Dir(".")))
-	defer ts.Close()
-
-	for _, path := range []string{"/testdata/", "/testdata/index.html"} {
-		res, err := Get(ts.URL + path)
-		if err != nil {
-			t.Fatal(err)
-		}
-		b, err := ioutil.ReadAll(res.Body)
-		if err != nil {
-			t.Fatal("reading Body:", err)
-		}
-		if s := string(b); s != want {
-			t.Errorf("for path %q got %q, want %q", path, s, want)
-		}
-		res.Body.Close()
-	}
-}
-
-func TestFileServerZeroByte(t *testing.T) {
-	defer afterTest(t)
-	ts := httptest.NewServer(FileServer(Dir(".")))
-	defer ts.Close()
-
-	res, err := Get(ts.URL + "/..\x00")
-	if err != nil {
-		t.Fatal(err)
-	}
-	b, err := ioutil.ReadAll(res.Body)
-	if err != nil {
-		t.Fatal("reading Body:", err)
-	}
-	if res.StatusCode == 200 {
-		t.Errorf("got status 200; want an error. Body is:\n%s", string(b))
-	}
-}
-
-type fakeFileInfo struct {
-	dir      bool
-	basename string
-	modtime  time.Time
-	ents     []*fakeFileInfo
-	contents string
-}
-
-func (f *fakeFileInfo) Name() string       { return f.basename }
-func (f *fakeFileInfo) Sys() interface{}   { return nil }
-func (f *fakeFileInfo) ModTime() time.Time { return f.modtime }
-func (f *fakeFileInfo) IsDir() bool        { return f.dir }
-func (f *fakeFileInfo) Size() int64        { return int64(len(f.contents)) }
-func (f *fakeFileInfo) Mode() os.FileMode {
-	if f.dir {
-		return 0755 | os.ModeDir
-	}
-	return 0644
-}
-
-type fakeFile struct {
-	io.ReadSeeker
-	fi     *fakeFileInfo
-	path   string // as opened
-	entpos int
-}
-
-func (f *fakeFile) Close() error               { return nil }
-func (f *fakeFile) Stat() (os.FileInfo, error) { return f.fi, nil }
-func (f *fakeFile) Readdir(count int) ([]os.FileInfo, error) {
-	if !f.fi.dir {
-		return nil, os.ErrInvalid
-	}
-	var fis []os.FileInfo
-
-	limit := f.entpos + count
-	if count <= 0 || limit > len(f.fi.ents) {
-		limit = len(f.fi.ents)
-	}
-	for ; f.entpos < limit; f.entpos++ {
-		fis = append(fis, f.fi.ents[f.entpos])
-	}
-
-	if len(fis) == 0 && count > 0 {
-		return fis, io.EOF
-	} else {
-		return fis, nil
-	}
-}
-
-type fakeFS map[string]*fakeFileInfo
-
-func (fs fakeFS) Open(name string) (File, error) {
-	name = path.Clean(name)
-	f, ok := fs[name]
-	if !ok {
-		return nil, os.ErrNotExist
-	}
-	return &fakeFile{ReadSeeker: strings.NewReader(f.contents), fi: f, path: name}, nil
-}
-
-func TestDirectoryIfNotModified(t *testing.T) {
-	defer afterTest(t)
-	const indexContents = "I am a fake index.html file"
-	fileMod := time.Unix(1000000000, 0).UTC()
-	fileModStr := fileMod.Format(TimeFormat)
-	dirMod := time.Unix(123, 0).UTC()
-	indexFile := &fakeFileInfo{
-		basename: "index.html",
-		modtime:  fileMod,
-		contents: indexContents,
-	}
-	fs := fakeFS{
-		"/": &fakeFileInfo{
-			dir:     true,
-			modtime: dirMod,
-			ents:    []*fakeFileInfo{indexFile},
-		},
-		"/index.html": indexFile,
-	}
-
-	ts := httptest.NewServer(FileServer(fs))
-	defer ts.Close()
-
-	res, err := Get(ts.URL)
-	if err != nil {
-		t.Fatal(err)
-	}
-	b, err := ioutil.ReadAll(res.Body)
-	if err != nil {
-		t.Fatal(err)
-	}
-	if string(b) != indexContents {
-		t.Fatalf("Got body %q; want %q", b, indexContents)
-	}
-	res.Body.Close()
-
-	lastMod := res.Header.Get("Last-Modified")
-	if lastMod != fileModStr {
-		t.Fatalf("initial Last-Modified = %q; want %q", lastMod, fileModStr)
-	}
-
-	req, _ := NewRequest("GET", ts.URL, nil)
-	req.Header.Set("If-Modified-Since", lastMod)
-
-	res, err = DefaultClient.Do(req)
-	if err != nil {
-		t.Fatal(err)
-	}
-	if res.StatusCode != 304 {
-		t.Fatalf("Code after If-Modified-Since request = %v; want 304", res.StatusCode)
-	}
-	res.Body.Close()
-
-	// Advance the index.html file's modtime, but not the directory's.
-	indexFile.modtime = indexFile.modtime.Add(1 * time.Hour)
-
-	res, err = DefaultClient.Do(req)
-	if err != nil {
-		t.Fatal(err)
-	}
-	if res.StatusCode != 200 {
-		t.Fatalf("Code after second If-Modified-Since request = %v; want 200; res is %#v", res.StatusCode, res)
-	}
-	res.Body.Close()
-}
-
-func mustStat(t *testing.T, fileName string) os.FileInfo {
-	fi, err := os.Stat(fileName)
-	if err != nil {
-		t.Fatal(err)
-	}
-	return fi
-}
-
-func TestServeContent(t *testing.T) {
-	defer afterTest(t)
-	type serveParam struct {
-		name        string
-		modtime     time.Time
-		content     io.ReadSeeker
-		contentType string
-		etag        string
-	}
-	servec := make(chan serveParam, 1)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
-		p := <-servec
-		if p.etag != "" {
-			w.Header().Set("ETag", p.etag)
-		}
-		if p.contentType != "" {
-			w.Header().Set("Content-Type", p.contentType)
-		}
-		ServeContent(w, r, p.name, p.modtime, p.content)
-	}))
-	defer ts.Close()
-
-	type testCase struct {
-		// One of file or content must be set:
-		file    string
-		content io.ReadSeeker
-
-		modtime          time.Time
-		serveETag        string // optional
-		serveContentType string // optional
-		reqHeader        map[string]string
-		wantLastMod      string
-		wantContentType  string
-		wantStatus       int
-	}
-	htmlModTime := mustStat(t, "testdata/index.html").ModTime()
-	tests := map[string]testCase{
-		"no_last_modified": {
-			file:            "testdata/style.css",
-			wantContentType: "text/css; charset=utf-8",
-			wantStatus:      200,
-		},
-		"with_last_modified": {
-			file:            "testdata/index.html",
-			wantContentType: "text/html; charset=utf-8",
-			modtime:         htmlModTime,
-			wantLastMod:     htmlModTime.UTC().Format(TimeFormat),
-			wantStatus:      200,
-		},
-		"not_modified_modtime": {
-			file:    "testdata/style.css",
-			modtime: htmlModTime,
-			reqHeader: map[string]string{
-				"If-Modified-Since": htmlModTime.UTC().Format(TimeFormat),
-			},
-			wantStatus: 304,
-		},
-		"not_modified_modtime_with_contenttype": {
-			file:             "testdata/style.css",
-			serveContentType: "text/css", // explicit content type
-			modtime:          htmlModTime,
-			reqHeader: map[string]string{
-				"If-Modified-Since": htmlModTime.UTC().Format(TimeFormat),
-			},
-			wantStatus: 304,
-		},
-		"not_modified_etag": {
-			file:      "testdata/style.css",
-			serveETag: `"foo"`,
-			reqHeader: map[string]string{
-				"If-None-Match": `"foo"`,
-			},
-			wantStatus: 304,
-		},
-		"not_modified_etag_no_seek": {
-			content:   panicOnSeek{nil}, // should never be called
-			serveETag: `"foo"`,
-			reqHeader: map[string]string{
-				"If-None-Match": `"foo"`,
-			},
-			wantStatus: 304,
-		},
-		"range_good": {
-			file:      "testdata/style.css",
-			serveETag: `"A"`,
-			reqHeader: map[string]string{
-				"Range": "bytes=0-4",
-			},
-			wantStatus:      StatusPartialContent,
-			wantContentType: "text/css; charset=utf-8",
-		},
-		// An If-Range resource for entity "A", but entity "B" is now current.
-		// The Range request should be ignored.
-		"range_no_match": {
-			file:      "testdata/style.css",
-			serveETag: `"A"`,
-			reqHeader: map[string]string{
-				"Range":    "bytes=0-4",
-				"If-Range": `"B"`,
-			},
-			wantStatus:      200,
-			wantContentType: "text/css; charset=utf-8",
-		},
-	}
-	for testName, tt := range tests {
-		var content io.ReadSeeker
-		if tt.file != "" {
-			f, err := os.Open(tt.file)
-			if err != nil {
-				t.Fatalf("test %q: %v", testName, err)
-			}
-			defer f.Close()
-			content = f
-		} else {
-			content = tt.content
-		}
-
-		servec <- serveParam{
-			name:        filepath.Base(tt.file),
-			content:     content,
-			modtime:     tt.modtime,
-			etag:        tt.serveETag,
-			contentType: tt.serveContentType,
-		}
-		req, err := NewRequest("GET", ts.URL, nil)
-		if err != nil {
-			t.Fatal(err)
-		}
-		for k, v := range tt.reqHeader {
-			req.Header.Set(k, v)
-		}
-		res, err := DefaultClient.Do(req)
-		if err != nil {
-			t.Fatal(err)
-		}
-		io.Copy(ioutil.Discard, res.Body)
-		res.Body.Close()
-		if res.StatusCode != tt.wantStatus {
-			t.Errorf("test %q: status = %d; want %d", testName, res.StatusCode, tt.wantStatus)
-		}
-		if g, e := res.Header.Get("Content-Type"), tt.wantContentType; g != e {
-			t.Errorf("test %q: content-type = %q, want %q", testName, g, e)
-		}
-		if g, e := res.Header.Get("Last-Modified"), tt.wantLastMod; g != e {
-			t.Errorf("test %q: last-modified = %q, want %q", testName, g, e)
-		}
-	}
-}
-
-// verifies that sendfile is being used on Linux
-func TestLinuxSendfile(t *testing.T) {
-	defer afterTest(t)
-	if runtime.GOOS != "linux" {
-		t.Skip("skipping; linux-only test")
-	}
-	if _, err := exec.LookPath("strace"); err != nil {
-		t.Skip("skipping; strace not found in path")
-	}
-
-	ln, err := net.Listen("tcp", "127.0.0.1:0")
-	if err != nil {
-		t.Fatal(err)
-	}
-	lnf, err := ln.(*net.TCPListener).File()
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer ln.Close()
-
-	var buf bytes.Buffer
-	child := exec.Command("strace", "-f", "-q", "-e", "trace=sendfile,sendfile64", os.Args[0], "-test.run=TestLinuxSendfileChild")
-	child.ExtraFiles = append(child.ExtraFiles, lnf)
-	child.Env = append([]string{"GO_WANT_HELPER_PROCESS=1"}, os.Environ()...)
-	child.Stdout = &buf
-	child.Stderr = &buf
-	if err := child.Start(); err != nil {
-		t.Skipf("skipping; failed to start straced child: %v", err)
-	}
-
-	res, err := Get(fmt.Sprintf("http://%s/", ln.Addr()))
-	if err != nil {
-		t.Fatalf("http client error: %v", err)
-	}
-	_, err = io.Copy(ioutil.Discard, res.Body)
-	if err != nil {
-		t.Fatalf("client body read error: %v", err)
-	}
-	res.Body.Close()
-
-	// Force child to exit cleanly.
-	Get(fmt.Sprintf("http://%s/quit", ln.Addr()))
-	child.Wait()
-
-	rx := regexp.MustCompile(`sendfile(64)?\(\d+,\s*\d+,\s*NULL,\s*\d+\)\s*=\s*\d+\s*\n`)
-	rxResume := regexp.MustCompile(`<\.\.\. sendfile(64)? resumed> \)\s*=\s*\d+\s*\n`)
-	out := buf.String()
-	if !rx.MatchString(out) && !rxResume.MatchString(out) {
-		t.Errorf("no sendfile system call found in:\n%s", out)
-	}
-}
-
-func getBody(t *testing.T, testName string, req Request) (*Response, []byte) {
-	r, err := DefaultClient.Do(&req)
-	if err != nil {
-		t.Fatalf("%s: for URL %q, send error: %v", testName, req.URL.String(), err)
-	}
-	b, err := ioutil.ReadAll(r.Body)
-	if err != nil {
-		t.Fatalf("%s: for URL %q, reading body: %v", testName, req.URL.String(), err)
-	}
-	return r, b
-}
-
-// TestLinuxSendfileChild isn't a real test. It's used as a helper process
-// for TestLinuxSendfile.
-func TestLinuxSendfileChild(*testing.T) {
-	if os.Getenv("GO_WANT_HELPER_PROCESS") != "1" {
-		return
-	}
-	defer os.Exit(0)
-	fd3 := os.NewFile(3, "ephemeral-port-listener")
-	ln, err := net.FileListener(fd3)
-	if err != nil {
-		panic(err)
-	}
-	mux := NewServeMux()
-	mux.Handle("/", FileServer(Dir("testdata")))
-	mux.HandleFunc("/quit", func(ResponseWriter, *Request) {
-		os.Exit(0)
-	})
-	s := &Server{Handler: mux}
-	err = s.Serve(ln)
-	if err != nil {
-		panic(err)
-	}
-}
-
-type panicOnSeek struct{ io.ReadSeeker }
diff --git a/src/pkg/net/http/httptest/server.go b/src/pkg/net/http/httptest/server.go
deleted file mode 100644
index 7f26555..0000000
--- a/src/pkg/net/http/httptest/server.go
+++ /dev/null
@@ -1,228 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Implementation of Server
-
-package httptest
-
-import (
-	"crypto/tls"
-	"flag"
-	"fmt"
-	"net"
-	"net/http"
-	"os"
-	"sync"
-)
-
-// A Server is an HTTP server listening on a system-chosen port on the
-// local loopback interface, for use in end-to-end HTTP tests.
-type Server struct {
-	URL      string // base URL of form http://ipaddr:port with no trailing slash
-	Listener net.Listener
-
-	// TLS is the optional TLS configuration, populated with a new config
-	// after TLS is started. If set on an unstarted server before StartTLS
-	// is called, existing fields are copied into the new config.
-	TLS *tls.Config
-
-	// Config may be changed after calling NewUnstartedServer and
-	// before Start or StartTLS.
-	Config *http.Server
-
-	// wg counts the number of outstanding HTTP requests on this server.
-	// Close blocks until all requests are finished.
-	wg sync.WaitGroup
-}
-
-// historyListener keeps track of all connections that it's ever
-// accepted.
-type historyListener struct {
-	net.Listener
-	sync.Mutex // protects history
-	history    []net.Conn
-}
-
-func (hs *historyListener) Accept() (c net.Conn, err error) {
-	c, err = hs.Listener.Accept()
-	if err == nil {
-		hs.Lock()
-		hs.history = append(hs.history, c)
-		hs.Unlock()
-	}
-	return
-}
-
-func newLocalListener() net.Listener {
-	if *serve != "" {
-		l, err := net.Listen("tcp", *serve)
-		if err != nil {
-			panic(fmt.Sprintf("httptest: failed to listen on %v: %v", *serve, err))
-		}
-		return l
-	}
-	l, err := net.Listen("tcp", "127.0.0.1:0")
-	if err != nil {
-		if l, err = net.Listen("tcp6", "[::1]:0"); err != nil {
-			panic(fmt.Sprintf("httptest: failed to listen on a port: %v", err))
-		}
-	}
-	return l
-}
-
-// When debugging a particular http server-based test,
-// this flag lets you run
-//	go test -run=BrokenTest -httptest.serve=127.0.0.1:8000
-// to start the broken server so you can interact with it manually.
-var serve = flag.String("httptest.serve", "", "if non-empty, httptest.NewServer serves on this address and blocks")
-
-// NewServer starts and returns a new Server.
-// The caller should call Close when finished, to shut it down.
-func NewServer(handler http.Handler) *Server {
-	ts := NewUnstartedServer(handler)
-	ts.Start()
-	return ts
-}
-
-// NewUnstartedServer returns a new Server but doesn't start it.
-//
-// After changing its configuration, the caller should call Start or
-// StartTLS.
-//
-// The caller should call Close when finished, to shut it down.
-func NewUnstartedServer(handler http.Handler) *Server {
-	return &Server{
-		Listener: newLocalListener(),
-		Config:   &http.Server{Handler: handler},
-	}
-}
-
-// Start starts a server from NewUnstartedServer.
-func (s *Server) Start() {
-	if s.URL != "" {
-		panic("Server already started")
-	}
-	s.Listener = &historyListener{Listener: s.Listener}
-	s.URL = "http://" + s.Listener.Addr().String()
-	s.wrapHandler()
-	go s.Config.Serve(s.Listener)
-	if *serve != "" {
-		fmt.Fprintln(os.Stderr, "httptest: serving on", s.URL)
-		select {}
-	}
-}
-
-// StartTLS starts TLS on a server from NewUnstartedServer.
-func (s *Server) StartTLS() {
-	if s.URL != "" {
-		panic("Server already started")
-	}
-	cert, err := tls.X509KeyPair(localhostCert, localhostKey)
-	if err != nil {
-		panic(fmt.Sprintf("httptest: NewTLSServer: %v", err))
-	}
-
-	existingConfig := s.TLS
-	s.TLS = new(tls.Config)
-	if existingConfig != nil {
-		*s.TLS = *existingConfig
-	}
-	if s.TLS.NextProtos == nil {
-		s.TLS.NextProtos = []string{"http/1.1"}
-	}
-	if len(s.TLS.Certificates) == 0 {
-		s.TLS.Certificates = []tls.Certificate{cert}
-	}
-	tlsListener := tls.NewListener(s.Listener, s.TLS)
-
-	s.Listener = &historyListener{Listener: tlsListener}
-	s.URL = "https://" + s.Listener.Addr().String()
-	s.wrapHandler()
-	go s.Config.Serve(s.Listener)
-}
-
-func (s *Server) wrapHandler() {
-	h := s.Config.Handler
-	if h == nil {
-		h = http.DefaultServeMux
-	}
-	s.Config.Handler = &waitGroupHandler{
-		s: s,
-		h: h,
-	}
-}
-
-// NewTLSServer starts and returns a new Server using TLS.
-// The caller should call Close when finished, to shut it down.
-func NewTLSServer(handler http.Handler) *Server {
-	ts := NewUnstartedServer(handler)
-	ts.StartTLS()
-	return ts
-}
-
-// Close shuts down the server and blocks until all outstanding
-// requests on this server have completed.
-func (s *Server) Close() {
-	s.Listener.Close()
-	s.wg.Wait()
-	s.CloseClientConnections()
-	if t, ok := http.DefaultTransport.(*http.Transport); ok {
-		t.CloseIdleConnections()
-	}
-}
-
-// CloseClientConnections closes any currently open HTTP connections
-// to the test Server.
-func (s *Server) CloseClientConnections() {
-	hl, ok := s.Listener.(*historyListener)
-	if !ok {
-		return
-	}
-	hl.Lock()
-	for _, conn := range hl.history {
-		conn.Close()
-	}
-	hl.Unlock()
-}
-
-// waitGroupHandler wraps a handler, incrementing and decrementing a
-// sync.WaitGroup on each request, to enable Server.Close to block
-// until outstanding requests are finished.
-type waitGroupHandler struct {
-	s *Server
-	h http.Handler // non-nil
-}
-
-func (h *waitGroupHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
-	h.s.wg.Add(1)
-	defer h.s.wg.Done() // a defer, in case ServeHTTP below panics
-	h.h.ServeHTTP(w, r)
-}
-
-// localhostCert is a PEM-encoded TLS cert with SAN IPs
-// "127.0.0.1" and "[::1]", expiring at the last second of 2049 (the end
-// of ASN.1 time).
-// generated from src/pkg/crypto/tls:
-// go run generate_cert.go  --rsa-bits 512 --host 127.0.0.1,::1,example.com --ca --start-date "Jan 1 00:00:00 1970" --duration=1000000h
-var localhostCert = []byte(`-----BEGIN CERTIFICATE-----
-MIIBdzCCASOgAwIBAgIBADALBgkqhkiG9w0BAQUwEjEQMA4GA1UEChMHQWNtZSBD
-bzAeFw03MDAxMDEwMDAwMDBaFw00OTEyMzEyMzU5NTlaMBIxEDAOBgNVBAoTB0Fj
-bWUgQ28wWjALBgkqhkiG9w0BAQEDSwAwSAJBAN55NcYKZeInyTuhcCwFMhDHCmwa
-IUSdtXdcbItRB/yfXGBhiex00IaLXQnSU+QZPRZWYqeTEbFSgihqi1PUDy8CAwEA
-AaNoMGYwDgYDVR0PAQH/BAQDAgCkMBMGA1UdJQQMMAoGCCsGAQUFBwMBMA8GA1Ud
-EwEB/wQFMAMBAf8wLgYDVR0RBCcwJYILZXhhbXBsZS5jb22HBH8AAAGHEAAAAAAA
-AAAAAAAAAAAAAAEwCwYJKoZIhvcNAQEFA0EAAoQn/ytgqpiLcZu9XKbCJsJcvkgk
-Se6AbGXgSlq+ZCEVo0qIwSgeBqmsJxUu7NCSOwVJLYNEBO2DtIxoYVk+MA==
------END CERTIFICATE-----`)
-
-// localhostKey is the private key for localhostCert.
-var localhostKey = []byte(`-----BEGIN RSA PRIVATE KEY-----
-MIIBPAIBAAJBAN55NcYKZeInyTuhcCwFMhDHCmwaIUSdtXdcbItRB/yfXGBhiex0
-0IaLXQnSU+QZPRZWYqeTEbFSgihqi1PUDy8CAwEAAQJBAQdUx66rfh8sYsgfdcvV
-NoafYpnEcB5s4m/vSVe6SU7dCK6eYec9f9wpT353ljhDUHq3EbmE4foNzJngh35d
-AekCIQDhRQG5Li0Wj8TM4obOnnXUXf1jRv0UkzE9AHWLG5q3AwIhAPzSjpYUDjVW
-MCUXgckTpKCuGwbJk7424Nb8bLzf3kllAiA5mUBgjfr/WtFSJdWcPQ4Zt9KTMNKD
-EUO0ukpTwEIl6wIhAMbGqZK3zAAFdq8DD2jPx+UJXnh0rnOkZBzDtJ6/iN69AiEA
-1Aq8MJgTaYsDQWyU/hDq5YkDJc9e9DSCvUIzqxQWMQE=
------END RSA PRIVATE KEY-----`)
diff --git a/src/pkg/net/http/httptest/server_test.go b/src/pkg/net/http/httptest/server_test.go
deleted file mode 100644
index 4fc4c70..0000000
--- a/src/pkg/net/http/httptest/server_test.go
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package httptest
-
-import (
-	"io/ioutil"
-	"net/http"
-	"testing"
-	"time"
-)
-
-func TestServer(t *testing.T) {
-	ts := NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
-		w.Write([]byte("hello"))
-	}))
-	defer ts.Close()
-	res, err := http.Get(ts.URL)
-	if err != nil {
-		t.Fatal(err)
-	}
-	got, err := ioutil.ReadAll(res.Body)
-	if err != nil {
-		t.Fatal(err)
-	}
-	if string(got) != "hello" {
-		t.Errorf("got %q, want hello", string(got))
-	}
-}
-
-func TestIssue7264(t *testing.T) {
-	t.Skip("broken test - removed at tip")
-	for i := 0; i < 1000; i++ {
-		func() {
-			inHandler := make(chan bool, 1)
-			ts := NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
-				inHandler <- true
-			}))
-			defer ts.Close()
-			tr := &http.Transport{
-				ResponseHeaderTimeout: time.Nanosecond,
-			}
-			defer tr.CloseIdleConnections()
-			c := &http.Client{Transport: tr}
-			res, err := c.Get(ts.URL)
-			<-inHandler
-			if err == nil {
-				res.Body.Close()
-			}
-		}()
-	}
-}
diff --git a/src/pkg/net/http/httputil/chunked.go b/src/pkg/net/http/httputil/chunked.go
deleted file mode 100644
index 9632bfd..0000000
--- a/src/pkg/net/http/httputil/chunked.go
+++ /dev/null
@@ -1,203 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// The wire protocol for HTTP's "chunked" Transfer-Encoding.
-
-// This code is duplicated in net/http and net/http/httputil.
-// Please make any changes in both files.
-
-package httputil
-
-import (
-	"bufio"
-	"bytes"
-	"errors"
-	"fmt"
-	"io"
-)
-
-const maxLineLength = 4096 // assumed <= bufio.defaultBufSize
-
-var ErrLineTooLong = errors.New("header line too long")
-
-// newChunkedReader returns a new chunkedReader that translates the data read from r
-// out of HTTP "chunked" format before returning it.
-// The chunkedReader returns io.EOF when the final 0-length chunk is read.
-//
-// newChunkedReader is not needed by normal applications. The http package
-// automatically decodes chunking when reading response bodies.
-func newChunkedReader(r io.Reader) io.Reader {
-	br, ok := r.(*bufio.Reader)
-	if !ok {
-		br = bufio.NewReader(r)
-	}
-	return &chunkedReader{r: br}
-}
-
-type chunkedReader struct {
-	r   *bufio.Reader
-	n   uint64 // unread bytes in chunk
-	err error
-	buf [2]byte
-}
-
-func (cr *chunkedReader) beginChunk() {
-	// chunk-size CRLF
-	var line []byte
-	line, cr.err = readLine(cr.r)
-	if cr.err != nil {
-		return
-	}
-	cr.n, cr.err = parseHexUint(line)
-	if cr.err != nil {
-		return
-	}
-	if cr.n == 0 {
-		cr.err = io.EOF
-	}
-}
-
-func (cr *chunkedReader) chunkHeaderAvailable() bool {
-	n := cr.r.Buffered()
-	if n > 0 {
-		peek, _ := cr.r.Peek(n)
-		return bytes.IndexByte(peek, '\n') >= 0
-	}
-	return false
-}
-
-func (cr *chunkedReader) Read(b []uint8) (n int, err error) {
-	for cr.err == nil {
-		if cr.n == 0 {
-			if n > 0 && !cr.chunkHeaderAvailable() {
-				// We've read enough. Don't potentially block
-				// reading a new chunk header.
-				break
-			}
-			cr.beginChunk()
-			continue
-		}
-		if len(b) == 0 {
-			break
-		}
-		rbuf := b
-		if uint64(len(rbuf)) > cr.n {
-			rbuf = rbuf[:cr.n]
-		}
-		var n0 int
-		n0, cr.err = cr.r.Read(rbuf)
-		n += n0
-		b = b[n0:]
-		cr.n -= uint64(n0)
-		// If we're at the end of a chunk, read the next two
-		// bytes to verify they are "\r\n".
-		if cr.n == 0 && cr.err == nil {
-			if _, cr.err = io.ReadFull(cr.r, cr.buf[:2]); cr.err == nil {
-				if cr.buf[0] != '\r' || cr.buf[1] != '\n' {
-					cr.err = errors.New("malformed chunked encoding")
-				}
-			}
-		}
-	}
-	return n, cr.err
-}
-
-// Read a line of bytes (up to \n) from b.
-// Give up if the line exceeds maxLineLength.
-// The returned bytes are a pointer into storage in
-// the bufio, so they are only valid until the next bufio read.
-func readLine(b *bufio.Reader) (p []byte, err error) {
-	if p, err = b.ReadSlice('\n'); err != nil {
-		// We always know when EOF is coming.
-		// If the caller asked for a line, there should be a line.
-		if err == io.EOF {
-			err = io.ErrUnexpectedEOF
-		} else if err == bufio.ErrBufferFull {
-			err = ErrLineTooLong
-		}
-		return nil, err
-	}
-	if len(p) >= maxLineLength {
-		return nil, ErrLineTooLong
-	}
-	return trimTrailingWhitespace(p), nil
-}
-
-func trimTrailingWhitespace(b []byte) []byte {
-	for len(b) > 0 && isASCIISpace(b[len(b)-1]) {
-		b = b[:len(b)-1]
-	}
-	return b
-}
-
-func isASCIISpace(b byte) bool {
-	return b == ' ' || b == '\t' || b == '\n' || b == '\r'
-}
-
-// newChunkedWriter returns a new chunkedWriter that translates writes into HTTP
-// "chunked" format before writing them to w. Closing the returned chunkedWriter
-// sends the final 0-length chunk that marks the end of the stream.
-//
-// newChunkedWriter is not needed by normal applications. The http
-// package adds chunking automatically if handlers don't set a
-// Content-Length header. Using newChunkedWriter inside a handler
-// would result in double chunking or chunking with a Content-Length
-// length, both of which are wrong.
-func newChunkedWriter(w io.Writer) io.WriteCloser {
-	return &chunkedWriter{w}
-}
-
-// Writing to chunkedWriter translates to writing in HTTP chunked Transfer
-// Encoding wire format to the underlying Wire chunkedWriter.
-type chunkedWriter struct {
-	Wire io.Writer
-}
-
-// Write the contents of data as one chunk to Wire.
-// NOTE: Note that the corresponding chunk-writing procedure in Conn.Write has
-// a bug since it does not check for success of io.WriteString
-func (cw *chunkedWriter) Write(data []byte) (n int, err error) {
-
-	// Don't send 0-length data. It looks like EOF for chunked encoding.
-	if len(data) == 0 {
-		return 0, nil
-	}
-
-	if _, err = fmt.Fprintf(cw.Wire, "%x\r\n", len(data)); err != nil {
-		return 0, err
-	}
-	if n, err = cw.Wire.Write(data); err != nil {
-		return
-	}
-	if n != len(data) {
-		err = io.ErrShortWrite
-		return
-	}
-	_, err = io.WriteString(cw.Wire, "\r\n")
-
-	return
-}
-
-func (cw *chunkedWriter) Close() error {
-	_, err := io.WriteString(cw.Wire, "0\r\n")
-	return err
-}
-
-func parseHexUint(v []byte) (n uint64, err error) {
-	for _, b := range v {
-		n <<= 4
-		switch {
-		case '0' <= b && b <= '9':
-			b = b - '0'
-		case 'a' <= b && b <= 'f':
-			b = b - 'a' + 10
-		case 'A' <= b && b <= 'F':
-			b = b - 'A' + 10
-		default:
-			return 0, errors.New("invalid byte in chunk length")
-		}
-		n |= uint64(b)
-	}
-	return
-}
diff --git a/src/pkg/net/http/httputil/chunked_test.go b/src/pkg/net/http/httputil/chunked_test.go
deleted file mode 100644
index a7a5774..0000000
--- a/src/pkg/net/http/httputil/chunked_test.go
+++ /dev/null
@@ -1,159 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// This code is duplicated in net/http and net/http/httputil.
-// Please make any changes in both files.
-
-package httputil
-
-import (
-	"bufio"
-	"bytes"
-	"fmt"
-	"io"
-	"io/ioutil"
-	"strings"
-	"testing"
-)
-
-func TestChunk(t *testing.T) {
-	var b bytes.Buffer
-
-	w := newChunkedWriter(&b)
-	const chunk1 = "hello, "
-	const chunk2 = "world! 0123456789abcdef"
-	w.Write([]byte(chunk1))
-	w.Write([]byte(chunk2))
-	w.Close()
-
-	if g, e := b.String(), "7\r\nhello, \r\n17\r\nworld! 0123456789abcdef\r\n0\r\n"; g != e {
-		t.Fatalf("chunk writer wrote %q; want %q", g, e)
-	}
-
-	r := newChunkedReader(&b)
-	data, err := ioutil.ReadAll(r)
-	if err != nil {
-		t.Logf(`data: "%s"`, data)
-		t.Fatalf("ReadAll from reader: %v", err)
-	}
-	if g, e := string(data), chunk1+chunk2; g != e {
-		t.Errorf("chunk reader read %q; want %q", g, e)
-	}
-}
-
-func TestChunkReadMultiple(t *testing.T) {
-	// Bunch of small chunks, all read together.
-	{
-		var b bytes.Buffer
-		w := newChunkedWriter(&b)
-		w.Write([]byte("foo"))
-		w.Write([]byte("bar"))
-		w.Close()
-
-		r := newChunkedReader(&b)
-		buf := make([]byte, 10)
-		n, err := r.Read(buf)
-		if n != 6 || err != io.EOF {
-			t.Errorf("Read = %d, %v; want 6, EOF", n, err)
-		}
-		buf = buf[:n]
-		if string(buf) != "foobar" {
-			t.Errorf("Read = %q; want %q", buf, "foobar")
-		}
-	}
-
-	// One big chunk followed by a little chunk, but the small bufio.Reader size
-	// should prevent the second chunk header from being read.
-	{
-		var b bytes.Buffer
-		w := newChunkedWriter(&b)
-		// fillBufChunk is 11 bytes + 3 bytes header + 2 bytes footer = 16 bytes,
-		// the same as the bufio ReaderSize below (the minimum), so even
-		// though we're going to try to Read with a buffer larger enough to also
-		// receive "foo", the second chunk header won't be read yet.
-		const fillBufChunk = "0123456789a"
-		const shortChunk = "foo"
-		w.Write([]byte(fillBufChunk))
-		w.Write([]byte(shortChunk))
-		w.Close()
-
-		r := newChunkedReader(bufio.NewReaderSize(&b, 16))
-		buf := make([]byte, len(fillBufChunk)+len(shortChunk))
-		n, err := r.Read(buf)
-		if n != len(fillBufChunk) || err != nil {
-			t.Errorf("Read = %d, %v; want %d, nil", n, err, len(fillBufChunk))
-		}
-		buf = buf[:n]
-		if string(buf) != fillBufChunk {
-			t.Errorf("Read = %q; want %q", buf, fillBufChunk)
-		}
-
-		n, err = r.Read(buf)
-		if n != len(shortChunk) || err != io.EOF {
-			t.Errorf("Read = %d, %v; want %d, EOF", n, err, len(shortChunk))
-		}
-	}
-
-	// And test that we see an EOF chunk, even though our buffer is already full:
-	{
-		r := newChunkedReader(bufio.NewReader(strings.NewReader("3\r\nfoo\r\n0\r\n")))
-		buf := make([]byte, 3)
-		n, err := r.Read(buf)
-		if n != 3 || err != io.EOF {
-			t.Errorf("Read = %d, %v; want 3, EOF", n, err)
-		}
-		if string(buf) != "foo" {
-			t.Errorf("buf = %q; want foo", buf)
-		}
-	}
-}
-
-func TestChunkReaderAllocs(t *testing.T) {
-	if testing.Short() {
-		t.Skip("skipping in short mode")
-	}
-	var buf bytes.Buffer
-	w := newChunkedWriter(&buf)
-	a, b, c := []byte("aaaaaa"), []byte("bbbbbbbbbbbb"), []byte("cccccccccccccccccccccccc")
-	w.Write(a)
-	w.Write(b)
-	w.Write(c)
-	w.Close()
-
-	readBuf := make([]byte, len(a)+len(b)+len(c)+1)
-	byter := bytes.NewReader(buf.Bytes())
-	bufr := bufio.NewReader(byter)
-	mallocs := testing.AllocsPerRun(100, func() {
-		byter.Seek(0, 0)
-		bufr.Reset(byter)
-		r := newChunkedReader(bufr)
-		n, err := io.ReadFull(r, readBuf)
-		if n != len(readBuf)-1 {
-			t.Fatalf("read %d bytes; want %d", n, len(readBuf)-1)
-		}
-		if err != io.ErrUnexpectedEOF {
-			t.Fatalf("read error = %v; want ErrUnexpectedEOF", err)
-		}
-	})
-	if mallocs > 1.5 {
-		t.Errorf("mallocs = %v; want 1", mallocs)
-	}
-}
-
-func TestParseHexUint(t *testing.T) {
-	for i := uint64(0); i <= 1234; i++ {
-		line := []byte(fmt.Sprintf("%x", i))
-		got, err := parseHexUint(line)
-		if err != nil {
-			t.Fatalf("on %d: %v", i, err)
-		}
-		if got != i {
-			t.Errorf("for input %q = %d; want %d", line, got, i)
-		}
-	}
-	_, err := parseHexUint([]byte("bogus"))
-	if err == nil {
-		t.Error("expected error on bogus input")
-	}
-}
diff --git a/src/pkg/net/http/httputil/dump.go b/src/pkg/net/http/httputil/dump.go
deleted file mode 100644
index 2a7a413..0000000
--- a/src/pkg/net/http/httputil/dump.go
+++ /dev/null
@@ -1,276 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package httputil
-
-import (
-	"bufio"
-	"bytes"
-	"errors"
-	"fmt"
-	"io"
-	"io/ioutil"
-	"net"
-	"net/http"
-	"net/url"
-	"strings"
-	"time"
-)
-
-// One of the copies, say from b to r2, could be avoided by using a more
-// elaborate trick where the other copy is made during Request/Response.Write.
-// This would complicate things too much, given that these functions are for
-// debugging only.
-func drainBody(b io.ReadCloser) (r1, r2 io.ReadCloser, err error) {
-	var buf bytes.Buffer
-	if _, err = buf.ReadFrom(b); err != nil {
-		return nil, nil, err
-	}
-	if err = b.Close(); err != nil {
-		return nil, nil, err
-	}
-	return ioutil.NopCloser(&buf), ioutil.NopCloser(bytes.NewReader(buf.Bytes())), nil
-}
-
-// dumpConn is a net.Conn which writes to Writer and reads from Reader
-type dumpConn struct {
-	io.Writer
-	io.Reader
-}
-
-func (c *dumpConn) Close() error                       { return nil }
-func (c *dumpConn) LocalAddr() net.Addr                { return nil }
-func (c *dumpConn) RemoteAddr() net.Addr               { return nil }
-func (c *dumpConn) SetDeadline(t time.Time) error      { return nil }
-func (c *dumpConn) SetReadDeadline(t time.Time) error  { return nil }
-func (c *dumpConn) SetWriteDeadline(t time.Time) error { return nil }
-
-type neverEnding byte
-
-func (b neverEnding) Read(p []byte) (n int, err error) {
-	for i := range p {
-		p[i] = byte(b)
-	}
-	return len(p), nil
-}
-
-// DumpRequestOut is like DumpRequest but includes
-// headers that the standard http.Transport adds,
-// such as User-Agent.
-func DumpRequestOut(req *http.Request, body bool) ([]byte, error) {
-	save := req.Body
-	dummyBody := false
-	if !body || req.Body == nil {
-		req.Body = nil
-		if req.ContentLength != 0 {
-			req.Body = ioutil.NopCloser(io.LimitReader(neverEnding('x'), req.ContentLength))
-			dummyBody = true
-		}
-	} else {
-		var err error
-		save, req.Body, err = drainBody(req.Body)
-		if err != nil {
-			return nil, err
-		}
-	}
-
-	// Since we're using the actual Transport code to write the request,
-	// switch to http so the Transport doesn't try to do an SSL
-	// negotiation with our dumpConn and its bytes.Buffer & pipe.
-	// The wire format for https and http are the same, anyway.
-	reqSend := req
-	if req.URL.Scheme == "https" {
-		reqSend = new(http.Request)
-		*reqSend = *req
-		reqSend.URL = new(url.URL)
-		*reqSend.URL = *req.URL
-		reqSend.URL.Scheme = "http"
-	}
-
-	// Use the actual Transport code to record what we would send
-	// on the wire, but not using TCP.  Use a Transport with a
-	// custom dialer that returns a fake net.Conn that waits
-	// for the full input (and recording it), and then responds
-	// with a dummy response.
-	var buf bytes.Buffer // records the output
-	pr, pw := io.Pipe()
-	dr := &delegateReader{c: make(chan io.Reader)}
-	// Wait for the request before replying with a dummy response:
-	go func() {
-		http.ReadRequest(bufio.NewReader(pr))
-		dr.c <- strings.NewReader("HTTP/1.1 204 No Content\r\n\r\n")
-	}()
-
-	t := &http.Transport{
-		Dial: func(net, addr string) (net.Conn, error) {
-			return &dumpConn{io.MultiWriter(&buf, pw), dr}, nil
-		},
-	}
-	defer t.CloseIdleConnections()
-
-	_, err := t.RoundTrip(reqSend)
-
-	req.Body = save
-	if err != nil {
-		return nil, err
-	}
-	dump := buf.Bytes()
-
-	// If we used a dummy body above, remove it now.
-	// TODO: if the req.ContentLength is large, we allocate memory
-	// unnecessarily just to slice it off here.  But this is just
-	// a debug function, so this is acceptable for now. We could
-	// discard the body earlier if this matters.
-	if dummyBody {
-		if i := bytes.Index(dump, []byte("\r\n\r\n")); i >= 0 {
-			dump = dump[:i+4]
-		}
-	}
-	return dump, nil
-}
-
-// delegateReader is a reader that delegates to another reader,
-// once it arrives on a channel.
-type delegateReader struct {
-	c chan io.Reader
-	r io.Reader // nil until received from c
-}
-
-func (r *delegateReader) Read(p []byte) (int, error) {
-	if r.r == nil {
-		r.r = <-r.c
-	}
-	return r.r.Read(p)
-}
-
-// Return value if nonempty, def otherwise.
-func valueOrDefault(value, def string) string {
-	if value != "" {
-		return value
-	}
-	return def
-}
-
-var reqWriteExcludeHeaderDump = map[string]bool{
-	"Host":              true, // not in Header map anyway
-	"Content-Length":    true,
-	"Transfer-Encoding": true,
-	"Trailer":           true,
-}
-
-// dumpAsReceived writes req to w in the form as it was received, or
-// at least as accurately as possible from the information retained in
-// the request.
-func dumpAsReceived(req *http.Request, w io.Writer) error {
-	return nil
-}
-
-// DumpRequest returns the as-received wire representation of req,
-// optionally including the request body, for debugging.
-// DumpRequest is semantically a no-op, but in order to
-// dump the body, it reads the body data into memory and
-// changes req.Body to refer to the in-memory copy.
-// The documentation for http.Request.Write details which fields
-// of req are used.
-func DumpRequest(req *http.Request, body bool) (dump []byte, err error) {
-	save := req.Body
-	if !body || req.Body == nil {
-		req.Body = nil
-	} else {
-		save, req.Body, err = drainBody(req.Body)
-		if err != nil {
-			return
-		}
-	}
-
-	var b bytes.Buffer
-
-	fmt.Fprintf(&b, "%s %s HTTP/%d.%d\r\n", valueOrDefault(req.Method, "GET"),
-		req.URL.RequestURI(), req.ProtoMajor, req.ProtoMinor)
-
-	host := req.Host
-	if host == "" && req.URL != nil {
-		host = req.URL.Host
-	}
-	if host != "" {
-		fmt.Fprintf(&b, "Host: %s\r\n", host)
-	}
-
-	chunked := len(req.TransferEncoding) > 0 && req.TransferEncoding[0] == "chunked"
-	if len(req.TransferEncoding) > 0 {
-		fmt.Fprintf(&b, "Transfer-Encoding: %s\r\n", strings.Join(req.TransferEncoding, ","))
-	}
-	if req.Close {
-		fmt.Fprintf(&b, "Connection: close\r\n")
-	}
-
-	err = req.Header.WriteSubset(&b, reqWriteExcludeHeaderDump)
-	if err != nil {
-		return
-	}
-
-	io.WriteString(&b, "\r\n")
-
-	if req.Body != nil {
-		var dest io.Writer = &b
-		if chunked {
-			dest = NewChunkedWriter(dest)
-		}
-		_, err = io.Copy(dest, req.Body)
-		if chunked {
-			dest.(io.Closer).Close()
-			io.WriteString(&b, "\r\n")
-		}
-	}
-
-	req.Body = save
-	if err != nil {
-		return
-	}
-	dump = b.Bytes()
-	return
-}
-
-// errNoBody is a sentinel error value used by failureToReadBody so we can detect
-// that the lack of body was intentional.
-var errNoBody = errors.New("sentinel error value")
-
-// failureToReadBody is a io.ReadCloser that just returns errNoBody on
-// Read.  It's swapped in when we don't actually want to consume the
-// body, but need a non-nil one, and want to distinguish the error
-// from reading the dummy body.
-type failureToReadBody struct{}
-
-func (failureToReadBody) Read([]byte) (int, error) { return 0, errNoBody }
-func (failureToReadBody) Close() error             { return nil }
-
-var emptyBody = ioutil.NopCloser(strings.NewReader(""))
-
-// DumpResponse is like DumpRequest but dumps a response.
-func DumpResponse(resp *http.Response, body bool) (dump []byte, err error) {
-	var b bytes.Buffer
-	save := resp.Body
-	savecl := resp.ContentLength
-
-	if !body {
-		resp.Body = failureToReadBody{}
-	} else if resp.Body == nil {
-		resp.Body = emptyBody
-	} else {
-		save, resp.Body, err = drainBody(resp.Body)
-		if err != nil {
-			return
-		}
-	}
-	err = resp.Write(&b)
-	if err == errNoBody {
-		err = nil
-	}
-	resp.Body = save
-	resp.ContentLength = savecl
-	if err != nil {
-		return nil, err
-	}
-	return b.Bytes(), nil
-}
diff --git a/src/pkg/net/http/httputil/dump_test.go b/src/pkg/net/http/httputil/dump_test.go
deleted file mode 100644
index e1ffb39..0000000
--- a/src/pkg/net/http/httputil/dump_test.go
+++ /dev/null
@@ -1,263 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package httputil
-
-import (
-	"bytes"
-	"fmt"
-	"io"
-	"io/ioutil"
-	"net/http"
-	"net/url"
-	"runtime"
-	"strings"
-	"testing"
-)
-
-type dumpTest struct {
-	Req  http.Request
-	Body interface{} // optional []byte or func() io.ReadCloser to populate Req.Body
-
-	WantDump    string
-	WantDumpOut string
-	NoBody      bool // if true, set DumpRequest{,Out} body to false
-}
-
-var dumpTests = []dumpTest{
-
-	// HTTP/1.1 => chunked coding; body; empty trailer
-	{
-		Req: http.Request{
-			Method: "GET",
-			URL: &url.URL{
-				Scheme: "http",
-				Host:   "www.google.com",
-				Path:   "/search",
-			},
-			ProtoMajor:       1,
-			ProtoMinor:       1,
-			TransferEncoding: []string{"chunked"},
-		},
-
-		Body: []byte("abcdef"),
-
-		WantDump: "GET /search HTTP/1.1\r\n" +
-			"Host: www.google.com\r\n" +
-			"Transfer-Encoding: chunked\r\n\r\n" +
-			chunk("abcdef") + chunk(""),
-	},
-
-	// Verify that DumpRequest preserves the HTTP version number, doesn't add a Host,
-	// and doesn't add a User-Agent.
-	{
-		Req: http.Request{
-			Method:     "GET",
-			URL:        mustParseURL("/foo"),
-			ProtoMajor: 1,
-			ProtoMinor: 0,
-			Header: http.Header{
-				"X-Foo": []string{"X-Bar"},
-			},
-		},
-
-		WantDump: "GET /foo HTTP/1.0\r\n" +
-			"X-Foo: X-Bar\r\n\r\n",
-	},
-
-	{
-		Req: *mustNewRequest("GET", "http://example.com/foo", nil),
-
-		WantDumpOut: "GET /foo HTTP/1.1\r\n" +
-			"Host: example.com\r\n" +
-			"User-Agent: Go 1.1 package http\r\n" +
-			"Accept-Encoding: gzip\r\n\r\n",
-	},
-
-	// Test that an https URL doesn't try to do an SSL negotiation
-	// with a bytes.Buffer and hang with all goroutines not
-	// runnable.
-	{
-		Req: *mustNewRequest("GET", "https://example.com/foo", nil),
-
-		WantDumpOut: "GET /foo HTTP/1.1\r\n" +
-			"Host: example.com\r\n" +
-			"User-Agent: Go 1.1 package http\r\n" +
-			"Accept-Encoding: gzip\r\n\r\n",
-	},
-
-	// Request with Body, but Dump requested without it.
-	{
-		Req: http.Request{
-			Method: "POST",
-			URL: &url.URL{
-				Scheme: "http",
-				Host:   "post.tld",
-				Path:   "/",
-			},
-			ContentLength: 6,
-			ProtoMajor:    1,
-			ProtoMinor:    1,
-		},
-
-		Body: []byte("abcdef"),
-
-		WantDumpOut: "POST / HTTP/1.1\r\n" +
-			"Host: post.tld\r\n" +
-			"User-Agent: Go 1.1 package http\r\n" +
-			"Content-Length: 6\r\n" +
-			"Accept-Encoding: gzip\r\n\r\n",
-
-		NoBody: true,
-	},
-}
-
-func TestDumpRequest(t *testing.T) {
-	numg0 := runtime.NumGoroutine()
-	for i, tt := range dumpTests {
-		setBody := func() {
-			if tt.Body == nil {
-				return
-			}
-			switch b := tt.Body.(type) {
-			case []byte:
-				tt.Req.Body = ioutil.NopCloser(bytes.NewReader(b))
-			case func() io.ReadCloser:
-				tt.Req.Body = b()
-			}
-		}
-		setBody()
-		if tt.Req.Header == nil {
-			tt.Req.Header = make(http.Header)
-		}
-
-		if tt.WantDump != "" {
-			setBody()
-			dump, err := DumpRequest(&tt.Req, !tt.NoBody)
-			if err != nil {
-				t.Errorf("DumpRequest #%d: %s", i, err)
-				continue
-			}
-			if string(dump) != tt.WantDump {
-				t.Errorf("DumpRequest %d, expecting:\n%s\nGot:\n%s\n", i, tt.WantDump, string(dump))
-				continue
-			}
-		}
-
-		if tt.WantDumpOut != "" {
-			setBody()
-			dump, err := DumpRequestOut(&tt.Req, !tt.NoBody)
-			if err != nil {
-				t.Errorf("DumpRequestOut #%d: %s", i, err)
-				continue
-			}
-			if string(dump) != tt.WantDumpOut {
-				t.Errorf("DumpRequestOut %d, expecting:\n%s\nGot:\n%s\n", i, tt.WantDumpOut, string(dump))
-				continue
-			}
-		}
-	}
-	if dg := runtime.NumGoroutine() - numg0; dg > 4 {
-		t.Errorf("Unexpectedly large number of new goroutines: %d new", dg)
-	}
-}
-
-func chunk(s string) string {
-	return fmt.Sprintf("%x\r\n%s\r\n", len(s), s)
-}
-
-func mustParseURL(s string) *url.URL {
-	u, err := url.Parse(s)
-	if err != nil {
-		panic(fmt.Sprintf("Error parsing URL %q: %v", s, err))
-	}
-	return u
-}
-
-func mustNewRequest(method, url string, body io.Reader) *http.Request {
-	req, err := http.NewRequest(method, url, body)
-	if err != nil {
-		panic(fmt.Sprintf("NewRequest(%q, %q, %p) err = %v", method, url, body, err))
-	}
-	return req
-}
-
-var dumpResTests = []struct {
-	res  *http.Response
-	body bool
-	want string
-}{
-	{
-		res: &http.Response{
-			Status:        "200 OK",
-			StatusCode:    200,
-			Proto:         "HTTP/1.1",
-			ProtoMajor:    1,
-			ProtoMinor:    1,
-			ContentLength: 50,
-			Header: http.Header{
-				"Foo": []string{"Bar"},
-			},
-			Body: ioutil.NopCloser(strings.NewReader("foo")), // shouldn't be used
-		},
-		body: false, // to verify we see 50, not empty or 3.
-		want: `HTTP/1.1 200 OK
-Content-Length: 50
-Foo: Bar`,
-	},
-
-	{
-		res: &http.Response{
-			Status:        "200 OK",
-			StatusCode:    200,
-			Proto:         "HTTP/1.1",
-			ProtoMajor:    1,
-			ProtoMinor:    1,
-			ContentLength: 3,
-			Body:          ioutil.NopCloser(strings.NewReader("foo")),
-		},
-		body: true,
-		want: `HTTP/1.1 200 OK
-Content-Length: 3
-
-foo`,
-	},
-
-	{
-		res: &http.Response{
-			Status:           "200 OK",
-			StatusCode:       200,
-			Proto:            "HTTP/1.1",
-			ProtoMajor:       1,
-			ProtoMinor:       1,
-			ContentLength:    -1,
-			Body:             ioutil.NopCloser(strings.NewReader("foo")),
-			TransferEncoding: []string{"chunked"},
-		},
-		body: true,
-		want: `HTTP/1.1 200 OK
-Transfer-Encoding: chunked
-
-3
-foo
-0`,
-	},
-}
-
-func TestDumpResponse(t *testing.T) {
-	for i, tt := range dumpResTests {
-		gotb, err := DumpResponse(tt.res, tt.body)
-		if err != nil {
-			t.Errorf("%d. DumpResponse = %v", i, err)
-			continue
-		}
-		got := string(gotb)
-		got = strings.TrimSpace(got)
-		got = strings.Replace(got, "\r", "", -1)
-
-		if got != tt.want {
-			t.Errorf("%d.\nDumpResponse got:\n%s\n\nWant:\n%s\n", i, got, tt.want)
-		}
-	}
-}
diff --git a/src/pkg/net/http/httputil/httputil.go b/src/pkg/net/http/httputil/httputil.go
deleted file mode 100644
index 74fb6c6..0000000
--- a/src/pkg/net/http/httputil/httputil.go
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package httputil provides HTTP utility functions, complementing the
-// more common ones in the net/http package.
-package httputil
-
-import "io"
-
-// NewChunkedReader returns a new chunkedReader that translates the data read from r
-// out of HTTP "chunked" format before returning it.
-// The chunkedReader returns io.EOF when the final 0-length chunk is read.
-//
-// NewChunkedReader is not needed by normal applications. The http package
-// automatically decodes chunking when reading response bodies.
-func NewChunkedReader(r io.Reader) io.Reader {
-	return newChunkedReader(r)
-}
-
-// NewChunkedWriter returns a new chunkedWriter that translates writes into HTTP
-// "chunked" format before writing them to w. Closing the returned chunkedWriter
-// sends the final 0-length chunk that marks the end of the stream.
-//
-// NewChunkedWriter is not needed by normal applications. The http
-// package adds chunking automatically if handlers don't set a
-// Content-Length header. Using NewChunkedWriter inside a handler
-// would result in double chunking or chunking with a Content-Length
-// length, both of which are wrong.
-func NewChunkedWriter(w io.Writer) io.WriteCloser {
-	return newChunkedWriter(w)
-}
diff --git a/src/pkg/net/http/httputil/reverseproxy.go b/src/pkg/net/http/httputil/reverseproxy.go
deleted file mode 100644
index 48ada5f..0000000
--- a/src/pkg/net/http/httputil/reverseproxy.go
+++ /dev/null
@@ -1,211 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// HTTP reverse proxy handler
-
-package httputil
-
-import (
-	"io"
-	"log"
-	"net"
-	"net/http"
-	"net/url"
-	"strings"
-	"sync"
-	"time"
-)
-
-// onExitFlushLoop is a callback set by tests to detect the state of the
-// flushLoop() goroutine.
-var onExitFlushLoop func()
-
-// ReverseProxy is an HTTP Handler that takes an incoming request and
-// sends it to another server, proxying the response back to the
-// client.
-type ReverseProxy struct {
-	// Director must be a function which modifies
-	// the request into a new request to be sent
-	// using Transport. Its response is then copied
-	// back to the original client unmodified.
-	Director func(*http.Request)
-
-	// The transport used to perform proxy requests.
-	// If nil, http.DefaultTransport is used.
-	Transport http.RoundTripper
-
-	// FlushInterval specifies the flush interval
-	// to flush to the client while copying the
-	// response body.
-	// If zero, no periodic flushing is done.
-	FlushInterval time.Duration
-}
-
-func singleJoiningSlash(a, b string) string {
-	aslash := strings.HasSuffix(a, "/")
-	bslash := strings.HasPrefix(b, "/")
-	switch {
-	case aslash && bslash:
-		return a + b[1:]
-	case !aslash && !bslash:
-		return a + "/" + b
-	}
-	return a + b
-}
-
-// NewSingleHostReverseProxy returns a new ReverseProxy that rewrites
-// URLs to the scheme, host, and base path provided in target. If the
-// target's path is "/base" and the incoming request was for "/dir",
-// the target request will be for /base/dir.
-func NewSingleHostReverseProxy(target *url.URL) *ReverseProxy {
-	targetQuery := target.RawQuery
-	director := func(req *http.Request) {
-		req.URL.Scheme = target.Scheme
-		req.URL.Host = target.Host
-		req.URL.Path = singleJoiningSlash(target.Path, req.URL.Path)
-		if targetQuery == "" || req.URL.RawQuery == "" {
-			req.URL.RawQuery = targetQuery + req.URL.RawQuery
-		} else {
-			req.URL.RawQuery = targetQuery + "&" + req.URL.RawQuery
-		}
-	}
-	return &ReverseProxy{Director: director}
-}
-
-func copyHeader(dst, src http.Header) {
-	for k, vv := range src {
-		for _, v := range vv {
-			dst.Add(k, v)
-		}
-	}
-}
-
-// Hop-by-hop headers. These are removed when sent to the backend.
-// http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html
-var hopHeaders = []string{
-	"Connection",
-	"Keep-Alive",
-	"Proxy-Authenticate",
-	"Proxy-Authorization",
-	"Te", // canonicalized version of "TE"
-	"Trailers",
-	"Transfer-Encoding",
-	"Upgrade",
-}
-
-func (p *ReverseProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
-	transport := p.Transport
-	if transport == nil {
-		transport = http.DefaultTransport
-	}
-
-	outreq := new(http.Request)
-	*outreq = *req // includes shallow copies of maps, but okay
-
-	p.Director(outreq)
-	outreq.Proto = "HTTP/1.1"
-	outreq.ProtoMajor = 1
-	outreq.ProtoMinor = 1
-	outreq.Close = false
-
-	// Remove hop-by-hop headers to the backend.  Especially
-	// important is "Connection" because we want a persistent
-	// connection, regardless of what the client sent to us.  This
-	// is modifying the same underlying map from req (shallow
-	// copied above) so we only copy it if necessary.
-	copiedHeaders := false
-	for _, h := range hopHeaders {
-		if outreq.Header.Get(h) != "" {
-			if !copiedHeaders {
-				outreq.Header = make(http.Header)
-				copyHeader(outreq.Header, req.Header)
-				copiedHeaders = true
-			}
-			outreq.Header.Del(h)
-		}
-	}
-
-	if clientIP, _, err := net.SplitHostPort(req.RemoteAddr); err == nil {
-		// If we aren't the first proxy retain prior
-		// X-Forwarded-For information as a comma+space
-		// separated list and fold multiple headers into one.
-		if prior, ok := outreq.Header["X-Forwarded-For"]; ok {
-			clientIP = strings.Join(prior, ", ") + ", " + clientIP
-		}
-		outreq.Header.Set("X-Forwarded-For", clientIP)
-	}
-
-	res, err := transport.RoundTrip(outreq)
-	if err != nil {
-		log.Printf("http: proxy error: %v", err)
-		rw.WriteHeader(http.StatusInternalServerError)
-		return
-	}
-	defer res.Body.Close()
-
-	for _, h := range hopHeaders {
-		res.Header.Del(h)
-	}
-
-	copyHeader(rw.Header(), res.Header)
-
-	rw.WriteHeader(res.StatusCode)
-	p.copyResponse(rw, res.Body)
-}
-
-func (p *ReverseProxy) copyResponse(dst io.Writer, src io.Reader) {
-	if p.FlushInterval != 0 {
-		if wf, ok := dst.(writeFlusher); ok {
-			mlw := &maxLatencyWriter{
-				dst:     wf,
-				latency: p.FlushInterval,
-				done:    make(chan bool),
-			}
-			go mlw.flushLoop()
-			defer mlw.stop()
-			dst = mlw
-		}
-	}
-
-	io.Copy(dst, src)
-}
-
-type writeFlusher interface {
-	io.Writer
-	http.Flusher
-}
-
-type maxLatencyWriter struct {
-	dst     writeFlusher
-	latency time.Duration
-
-	lk   sync.Mutex // protects Write + Flush
-	done chan bool
-}
-
-func (m *maxLatencyWriter) Write(p []byte) (int, error) {
-	m.lk.Lock()
-	defer m.lk.Unlock()
-	return m.dst.Write(p)
-}
-
-func (m *maxLatencyWriter) flushLoop() {
-	t := time.NewTicker(m.latency)
-	defer t.Stop()
-	for {
-		select {
-		case <-m.done:
-			if onExitFlushLoop != nil {
-				onExitFlushLoop()
-			}
-			return
-		case <-t.C:
-			m.lk.Lock()
-			m.dst.Flush()
-			m.lk.Unlock()
-		}
-	}
-}
-
-func (m *maxLatencyWriter) stop() { m.done <- true }
diff --git a/src/pkg/net/http/pprof/pprof.go b/src/pkg/net/http/pprof/pprof.go
deleted file mode 100644
index 0c7548e..0000000
--- a/src/pkg/net/http/pprof/pprof.go
+++ /dev/null
@@ -1,205 +0,0 @@
-// Copyright 2010 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package pprof serves via its HTTP server runtime profiling data
-// in the format expected by the pprof visualization tool.
-// For more information about pprof, see
-// http://code.google.com/p/google-perftools/.
-//
-// The package is typically only imported for the side effect of
-// registering its HTTP handlers.
-// The handled paths all begin with /debug/pprof/.
-//
-// To use pprof, link this package into your program:
-//	import _ "net/http/pprof"
-//
-// If your application is not already running an http server, you
-// need to start one.  Add "net/http" and "log" to your imports and
-// the following code to your main function:
-//
-// 	go func() {
-// 		log.Println(http.ListenAndServe("localhost:6060", nil))
-// 	}()
-//
-// Then use the pprof tool to look at the heap profile:
-//
-//	go tool pprof http://localhost:6060/debug/pprof/heap
-//
-// Or to look at a 30-second CPU profile:
-//
-//	go tool pprof http://localhost:6060/debug/pprof/profile
-//
-// Or to look at the goroutine blocking profile:
-//
-//	go tool pprof http://localhost:6060/debug/pprof/block
-//
-// To view all available profiles, open http://localhost:6060/debug/pprof/
-// in your browser.
-//
-// For a study of the facility in action, visit
-//
-//	http://blog.golang.org/2011/06/profiling-go-programs.html
-//
-package pprof
-
-import (
-	"bufio"
-	"bytes"
-	"fmt"
-	"html/template"
-	"io"
-	"log"
-	"net/http"
-	"os"
-	"runtime"
-	"runtime/pprof"
-	"strconv"
-	"strings"
-	"time"
-)
-
-func init() {
-	http.Handle("/debug/pprof/", http.HandlerFunc(Index))
-	http.Handle("/debug/pprof/cmdline", http.HandlerFunc(Cmdline))
-	http.Handle("/debug/pprof/profile", http.HandlerFunc(Profile))
-	http.Handle("/debug/pprof/symbol", http.HandlerFunc(Symbol))
-}
-
-// Cmdline responds with the running program's
-// command line, with arguments separated by NUL bytes.
-// The package initialization registers it as /debug/pprof/cmdline.
-func Cmdline(w http.ResponseWriter, r *http.Request) {
-	w.Header().Set("Content-Type", "text/plain; charset=utf-8")
-	fmt.Fprintf(w, strings.Join(os.Args, "\x00"))
-}
-
-// Profile responds with the pprof-formatted cpu profile.
-// The package initialization registers it as /debug/pprof/profile.
-func Profile(w http.ResponseWriter, r *http.Request) {
-	sec, _ := strconv.ParseInt(r.FormValue("seconds"), 10, 64)
-	if sec == 0 {
-		sec = 30
-	}
-
-	// Set Content Type assuming StartCPUProfile will work,
-	// because if it does it starts writing.
-	w.Header().Set("Content-Type", "application/octet-stream")
-	if err := pprof.StartCPUProfile(w); err != nil {
-		// StartCPUProfile failed, so no writes yet.
-		// Can change header back to text content
-		// and send error code.
-		w.Header().Set("Content-Type", "text/plain; charset=utf-8")
-		w.WriteHeader(http.StatusInternalServerError)
-		fmt.Fprintf(w, "Could not enable CPU profiling: %s\n", err)
-		return
-	}
-	time.Sleep(time.Duration(sec) * time.Second)
-	pprof.StopCPUProfile()
-}
-
-// Symbol looks up the program counters listed in the request,
-// responding with a table mapping program counters to function names.
-// The package initialization registers it as /debug/pprof/symbol.
-func Symbol(w http.ResponseWriter, r *http.Request) {
-	w.Header().Set("Content-Type", "text/plain; charset=utf-8")
-
-	// We have to read the whole POST body before
-	// writing any output.  Buffer the output here.
-	var buf bytes.Buffer
-
-	// We don't know how many symbols we have, but we
-	// do have symbol information.  Pprof only cares whether
-	// this number is 0 (no symbols available) or > 0.
-	fmt.Fprintf(&buf, "num_symbols: 1\n")
-
-	var b *bufio.Reader
-	if r.Method == "POST" {
-		b = bufio.NewReader(r.Body)
-	} else {
-		b = bufio.NewReader(strings.NewReader(r.URL.RawQuery))
-	}
-
-	for {
-		word, err := b.ReadSlice('+')
-		if err == nil {
-			word = word[0 : len(word)-1] // trim +
-		}
-		pc, _ := strconv.ParseUint(string(word), 0, 64)
-		if pc != 0 {
-			f := runtime.FuncForPC(uintptr(pc))
-			if f != nil {
-				fmt.Fprintf(&buf, "%#x %s\n", pc, f.Name())
-			}
-		}
-
-		// Wait until here to check for err; the last
-		// symbol will have an err because it doesn't end in +.
-		if err != nil {
-			if err != io.EOF {
-				fmt.Fprintf(&buf, "reading request: %v\n", err)
-			}
-			break
-		}
-	}
-
-	w.Write(buf.Bytes())
-}
-
-// Handler returns an HTTP handler that serves the named profile.
-func Handler(name string) http.Handler {
-	return handler(name)
-}
-
-type handler string
-
-func (name handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
-	w.Header().Set("Content-Type", "text/plain; charset=utf-8")
-	debug, _ := strconv.Atoi(r.FormValue("debug"))
-	p := pprof.Lookup(string(name))
-	if p == nil {
-		w.WriteHeader(404)
-		fmt.Fprintf(w, "Unknown profile: %s\n", name)
-		return
-	}
-	p.WriteTo(w, debug)
-	return
-}
-
-// Index responds with the pprof-formatted profile named by the request.
-// For example, "/debug/pprof/heap" serves the "heap" profile.
-// Index responds to a request for "/debug/pprof/" with an HTML page
-// listing the available profiles.
-func Index(w http.ResponseWriter, r *http.Request) {
-	if strings.HasPrefix(r.URL.Path, "/debug/pprof/") {
-		name := strings.TrimPrefix(r.URL.Path, "/debug/pprof/")
-		if name != "" {
-			handler(name).ServeHTTP(w, r)
-			return
-		}
-	}
-
-	profiles := pprof.Profiles()
-	if err := indexTmpl.Execute(w, profiles); err != nil {
-		log.Print(err)
-	}
-}
-
-var indexTmpl = template.Must(template.New("index").Parse(`<html>
-<head>
-<title>/debug/pprof/</title>
-</head>
-/debug/pprof/<br>
-<br>
-<body>
-profiles:<br>
-<table>
-{{range .}}
-<tr><td align=right>{{.Count}}<td><a href="/debug/pprof/{{.Name}}?debug=1">{{.Name}}</a>
-{{end}}
-</table>
-<br>
-<a href="/debug/pprof/goroutine?debug=2">full goroutine stack dump</a><br>
-</body>
-</html>
-`))
diff --git a/src/pkg/net/http/readrequest_test.go b/src/pkg/net/http/readrequest_test.go
deleted file mode 100644
index ffdd6a8..0000000
--- a/src/pkg/net/http/readrequest_test.go
+++ /dev/null
@@ -1,331 +0,0 @@
-// Copyright 2010 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package http
-
-import (
-	"bufio"
-	"bytes"
-	"fmt"
-	"io"
-	"net/url"
-	"reflect"
-	"testing"
-)
-
-type reqTest struct {
-	Raw     string
-	Req     *Request
-	Body    string
-	Trailer Header
-	Error   string
-}
-
-var noError = ""
-var noBody = ""
-var noTrailer Header = nil
-
-var reqTests = []reqTest{
-	// Baseline test; All Request fields included for template use
-	{
-		"GET http://www.techcrunch.com/ HTTP/1.1\r\n" +
-			"Host: www.techcrunch.com\r\n" +
-			"User-Agent: Fake\r\n" +
-			"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n" +
-			"Accept-Language: en-us,en;q=0.5\r\n" +
-			"Accept-Encoding: gzip,deflate\r\n" +
-			"Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n" +
-			"Keep-Alive: 300\r\n" +
-			"Content-Length: 7\r\n" +
-			"Proxy-Connection: keep-alive\r\n\r\n" +
-			"abcdef\n???",
-
-		&Request{
-			Method: "GET",
-			URL: &url.URL{
-				Scheme: "http",
-				Host:   "www.techcrunch.com",
-				Path:   "/",
-			},
-			Proto:      "HTTP/1.1",
-			ProtoMajor: 1,
-			ProtoMinor: 1,
-			Header: Header{
-				"Accept":           {"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"},
-				"Accept-Language":  {"en-us,en;q=0.5"},
-				"Accept-Encoding":  {"gzip,deflate"},
-				"Accept-Charset":   {"ISO-8859-1,utf-8;q=0.7,*;q=0.7"},
-				"Keep-Alive":       {"300"},
-				"Proxy-Connection": {"keep-alive"},
-				"Content-Length":   {"7"},
-				"User-Agent":       {"Fake"},
-			},
-			Close:         false,
-			ContentLength: 7,
-			Host:          "www.techcrunch.com",
-			RequestURI:    "http://www.techcrunch.com/",
-		},
-
-		"abcdef\n",
-
-		noTrailer,
-		noError,
-	},
-
-	// GET request with no body (the normal case)
-	{
-		"GET / HTTP/1.1\r\n" +
-			"Host: foo.com\r\n\r\n",
-
-		&Request{
-			Method: "GET",
-			URL: &url.URL{
-				Path: "/",
-			},
-			Proto:         "HTTP/1.1",
-			ProtoMajor:    1,
-			ProtoMinor:    1,
-			Header:        Header{},
-			Close:         false,
-			ContentLength: 0,
-			Host:          "foo.com",
-			RequestURI:    "/",
-		},
-
-		noBody,
-		noTrailer,
-		noError,
-	},
-
-	// Tests that we don't parse a path that looks like a
-	// scheme-relative URI as a scheme-relative URI.
-	{
-		"GET //user at host/is/actually/a/path/ HTTP/1.1\r\n" +
-			"Host: test\r\n\r\n",
-
-		&Request{
-			Method: "GET",
-			URL: &url.URL{
-				Path: "//user at host/is/actually/a/path/",
-			},
-			Proto:         "HTTP/1.1",
-			ProtoMajor:    1,
-			ProtoMinor:    1,
-			Header:        Header{},
-			Close:         false,
-			ContentLength: 0,
-			Host:          "test",
-			RequestURI:    "//user at host/is/actually/a/path/",
-		},
-
-		noBody,
-		noTrailer,
-		noError,
-	},
-
-	// Tests a bogus abs_path on the Request-Line (RFC 2616 section 5.1.2)
-	{
-		"GET ../../../../etc/passwd HTTP/1.1\r\n" +
-			"Host: test\r\n\r\n",
-		nil,
-		noBody,
-		noTrailer,
-		"parse ../../../../etc/passwd: invalid URI for request",
-	},
-
-	// Tests missing URL:
-	{
-		"GET  HTTP/1.1\r\n" +
-			"Host: test\r\n\r\n",
-		nil,
-		noBody,
-		noTrailer,
-		"parse : empty url",
-	},
-
-	// Tests chunked body with trailer:
-	{
-		"POST / HTTP/1.1\r\n" +
-			"Host: foo.com\r\n" +
-			"Transfer-Encoding: chunked\r\n\r\n" +
-			"3\r\nfoo\r\n" +
-			"3\r\nbar\r\n" +
-			"0\r\n" +
-			"Trailer-Key: Trailer-Value\r\n" +
-			"\r\n",
-		&Request{
-			Method: "POST",
-			URL: &url.URL{
-				Path: "/",
-			},
-			TransferEncoding: []string{"chunked"},
-			Proto:            "HTTP/1.1",
-			ProtoMajor:       1,
-			ProtoMinor:       1,
-			Header:           Header{},
-			ContentLength:    -1,
-			Host:             "foo.com",
-			RequestURI:       "/",
-		},
-
-		"foobar",
-		Header{
-			"Trailer-Key": {"Trailer-Value"},
-		},
-		noError,
-	},
-
-	// CONNECT request with domain name:
-	{
-		"CONNECT www.google.com:443 HTTP/1.1\r\n\r\n",
-
-		&Request{
-			Method: "CONNECT",
-			URL: &url.URL{
-				Host: "www.google.com:443",
-			},
-			Proto:         "HTTP/1.1",
-			ProtoMajor:    1,
-			ProtoMinor:    1,
-			Header:        Header{},
-			Close:         false,
-			ContentLength: 0,
-			Host:          "www.google.com:443",
-			RequestURI:    "www.google.com:443",
-		},
-
-		noBody,
-		noTrailer,
-		noError,
-	},
-
-	// CONNECT request with IP address:
-	{
-		"CONNECT 127.0.0.1:6060 HTTP/1.1\r\n\r\n",
-
-		&Request{
-			Method: "CONNECT",
-			URL: &url.URL{
-				Host: "127.0.0.1:6060",
-			},
-			Proto:         "HTTP/1.1",
-			ProtoMajor:    1,
-			ProtoMinor:    1,
-			Header:        Header{},
-			Close:         false,
-			ContentLength: 0,
-			Host:          "127.0.0.1:6060",
-			RequestURI:    "127.0.0.1:6060",
-		},
-
-		noBody,
-		noTrailer,
-		noError,
-	},
-
-	// CONNECT request for RPC:
-	{
-		"CONNECT /_goRPC_ HTTP/1.1\r\n\r\n",
-
-		&Request{
-			Method: "CONNECT",
-			URL: &url.URL{
-				Path: "/_goRPC_",
-			},
-			Proto:         "HTTP/1.1",
-			ProtoMajor:    1,
-			ProtoMinor:    1,
-			Header:        Header{},
-			Close:         false,
-			ContentLength: 0,
-			Host:          "",
-			RequestURI:    "/_goRPC_",
-		},
-
-		noBody,
-		noTrailer,
-		noError,
-	},
-
-	// SSDP Notify request. golang.org/issue/3692
-	{
-		"NOTIFY * HTTP/1.1\r\nServer: foo\r\n\r\n",
-		&Request{
-			Method: "NOTIFY",
-			URL: &url.URL{
-				Path: "*",
-			},
-			Proto:      "HTTP/1.1",
-			ProtoMajor: 1,
-			ProtoMinor: 1,
-			Header: Header{
-				"Server": []string{"foo"},
-			},
-			Close:         false,
-			ContentLength: 0,
-			RequestURI:    "*",
-		},
-
-		noBody,
-		noTrailer,
-		noError,
-	},
-
-	// OPTIONS request. Similar to golang.org/issue/3692
-	{
-		"OPTIONS * HTTP/1.1\r\nServer: foo\r\n\r\n",
-		&Request{
-			Method: "OPTIONS",
-			URL: &url.URL{
-				Path: "*",
-			},
-			Proto:      "HTTP/1.1",
-			ProtoMajor: 1,
-			ProtoMinor: 1,
-			Header: Header{
-				"Server": []string{"foo"},
-			},
-			Close:         false,
-			ContentLength: 0,
-			RequestURI:    "*",
-		},
-
-		noBody,
-		noTrailer,
-		noError,
-	},
-}
-
-func TestReadRequest(t *testing.T) {
-	for i := range reqTests {
-		tt := &reqTests[i]
-		var braw bytes.Buffer
-		braw.WriteString(tt.Raw)
-		req, err := ReadRequest(bufio.NewReader(&braw))
-		if err != nil {
-			if err.Error() != tt.Error {
-				t.Errorf("#%d: error %q, want error %q", i, err.Error(), tt.Error)
-			}
-			continue
-		}
-		rbody := req.Body
-		req.Body = nil
-		diff(t, fmt.Sprintf("#%d Request", i), req, tt.Req)
-		var bout bytes.Buffer
-		if rbody != nil {
-			_, err := io.Copy(&bout, rbody)
-			if err != nil {
-				t.Fatalf("#%d. copying body: %v", i, err)
-			}
-			rbody.Close()
-		}
-		body := bout.String()
-		if body != tt.Body {
-			t.Errorf("#%d: Body = %q want %q", i, body, tt.Body)
-		}
-		if !reflect.DeepEqual(tt.Trailer, req.Trailer) {
-			t.Errorf("#%d. Trailers differ.\n got: %v\nwant: %v", i, req.Trailer, tt.Trailer)
-		}
-	}
-}
diff --git a/src/pkg/net/http/request.go b/src/pkg/net/http/request.go
deleted file mode 100644
index a670920..0000000
--- a/src/pkg/net/http/request.go
+++ /dev/null
@@ -1,875 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// HTTP Request reading and parsing.
-
-package http
-
-import (
-	"bufio"
-	"bytes"
-	"crypto/tls"
-	"errors"
-	"fmt"
-	"io"
-	"io/ioutil"
-	"mime"
-	"mime/multipart"
-	"net/textproto"
-	"net/url"
-	"strconv"
-	"strings"
-	"sync"
-)
-
-const (
-	maxValueLength   = 4096
-	maxHeaderLines   = 1024
-	chunkSize        = 4 << 10  // 4 KB chunks
-	defaultMaxMemory = 32 << 20 // 32 MB
-)
-
-// ErrMissingFile is returned by FormFile when the provided file field name
-// is either not present in the request or not a file field.
-var ErrMissingFile = errors.New("http: no such file")
-
-// HTTP request parsing errors.
-type ProtocolError struct {
-	ErrorString string
-}
-
-func (err *ProtocolError) Error() string { return err.ErrorString }
-
-var (
-	ErrHeaderTooLong        = &ProtocolError{"header too long"}
-	ErrShortBody            = &ProtocolError{"entity body too short"}
-	ErrNotSupported         = &ProtocolError{"feature not supported"}
-	ErrUnexpectedTrailer    = &ProtocolError{"trailer header without chunked transfer encoding"}
-	ErrMissingContentLength = &ProtocolError{"missing ContentLength in HEAD response"}
-	ErrNotMultipart         = &ProtocolError{"request Content-Type isn't multipart/form-data"}
-	ErrMissingBoundary      = &ProtocolError{"no multipart boundary param in Content-Type"}
-)
-
-type badStringError struct {
-	what string
-	str  string
-}
-
-func (e *badStringError) Error() string { return fmt.Sprintf("%s %q", e.what, e.str) }
-
-// Headers that Request.Write handles itself and should be skipped.
-var reqWriteExcludeHeader = map[string]bool{
-	"Host":              true, // not in Header map anyway
-	"User-Agent":        true,
-	"Content-Length":    true,
-	"Transfer-Encoding": true,
-	"Trailer":           true,
-}
-
-// A Request represents an HTTP request received by a server
-// or to be sent by a client.
-//
-// The field semantics differ slightly between client and server
-// usage. In addition to the notes on the fields below, see the
-// documentation for Request.Write and RoundTripper.
-type Request struct {
-	// Method specifies the HTTP method (GET, POST, PUT, etc.).
-	// For client requests an empty string means GET.
-	Method string
-
-	// URL specifies either the URI being requested (for server
-	// requests) or the URL to access (for client requests).
-	//
-	// For server requests the URL is parsed from the URI
-	// supplied on the Request-Line as stored in RequestURI.  For
-	// most requests, fields other than Path and RawQuery will be
-	// empty. (See RFC 2616, Section 5.1.2)
-	//
-	// For client requests, the URL's Host specifies the server to
-	// connect to, while the Request's Host field optionally
-	// specifies the Host header value to send in the HTTP
-	// request.
-	URL *url.URL
-
-	// The protocol version for incoming requests.
-	// Client requests always use HTTP/1.1.
-	Proto      string // "HTTP/1.0"
-	ProtoMajor int    // 1
-	ProtoMinor int    // 0
-
-	// A header maps request lines to their values.
-	// If the header says
-	//
-	//	accept-encoding: gzip, deflate
-	//	Accept-Language: en-us
-	//	Connection: keep-alive
-	//
-	// then
-	//
-	//	Header = map[string][]string{
-	//		"Accept-Encoding": {"gzip, deflate"},
-	//		"Accept-Language": {"en-us"},
-	//		"Connection": {"keep-alive"},
-	//	}
-	//
-	// HTTP defines that header names are case-insensitive.
-	// The request parser implements this by canonicalizing the
-	// name, making the first character and any characters
-	// following a hyphen uppercase and the rest lowercase.
-	//
-	// For client requests certain headers are automatically
-	// added and may override values in Header.
-	//
-	// See the documentation for the Request.Write method.
-	Header Header
-
-	// Body is the request's body.
-	//
-	// For client requests a nil body means the request has no
-	// body, such as a GET request. The HTTP Client's Transport
-	// is responsible for calling the Close method.
-	//
-	// For server requests the Request Body is always non-nil
-	// but will return EOF immediately when no body is present.
-	// The Server will close the request body. The ServeHTTP
-	// Handler does not need to.
-	Body io.ReadCloser
-
-	// ContentLength records the length of the associated content.
-	// The value -1 indicates that the length is unknown.
-	// Values >= 0 indicate that the given number of bytes may
-	// be read from Body.
-	// For client requests, a value of 0 means unknown if Body is not nil.
-	ContentLength int64
-
-	// TransferEncoding lists the transfer encodings from outermost to
-	// innermost. An empty list denotes the "identity" encoding.
-	// TransferEncoding can usually be ignored; chunked encoding is
-	// automatically added and removed as necessary when sending and
-	// receiving requests.
-	TransferEncoding []string
-
-	// Close indicates whether to close the connection after
-	// replying to this request (for servers) or after sending
-	// the request (for clients).
-	Close bool
-
-	// For server requests Host specifies the host on which the
-	// URL is sought. Per RFC 2616, this is either the value of
-	// the "Host" header or the host name given in the URL itself.
-	// It may be of the form "host:port".
-	//
-	// For client requests Host optionally overrides the Host
-	// header to send. If empty, the Request.Write method uses
-	// the value of URL.Host.
-	Host string
-
-	// Form contains the parsed form data, including both the URL
-	// field's query parameters and the POST or PUT form data.
-	// This field is only available after ParseForm is called.
-	// The HTTP client ignores Form and uses Body instead.
-	Form url.Values
-
-	// PostForm contains the parsed form data from POST or PUT
-	// body parameters.
-	// This field is only available after ParseForm is called.
-	// The HTTP client ignores PostForm and uses Body instead.
-	PostForm url.Values
-
-	// MultipartForm is the parsed multipart form, including file uploads.
-	// This field is only available after ParseMultipartForm is called.
-	// The HTTP client ignores MultipartForm and uses Body instead.
-	MultipartForm *multipart.Form
-
-	// Trailer specifies additional headers that are sent after the request
-	// body.
-	//
-	// For server requests the Trailer map initially contains only the
-	// trailer keys, with nil values. (The client declares which trailers it
-	// will later send.)  While the handler is reading from Body, it must
-	// not reference Trailer. After reading from Body returns EOF, Trailer
-	// can be read again and will contain non-nil values, if they were sent
-	// by the client.
-	//
-	// For client requests Trailer must be initialized to a map containing
-	// the trailer keys to later send. The values may be nil or their final
-	// values. The ContentLength must be 0 or -1, to send a chunked request.
-	// After the HTTP request is sent the map values can be updated while
-	// the request body is read. Once the body returns EOF, the caller must
-	// not mutate Trailer.
-	//
-	// Few HTTP clients, servers, or proxies support HTTP trailers.
-	Trailer Header
-
-	// RemoteAddr allows HTTP servers and other software to record
-	// the network address that sent the request, usually for
-	// logging. This field is not filled in by ReadRequest and
-	// has no defined format. The HTTP server in this package
-	// sets RemoteAddr to an "IP:port" address before invoking a
-	// handler.
-	// This field is ignored by the HTTP client.
-	RemoteAddr string
-
-	// RequestURI is the unmodified Request-URI of the
-	// Request-Line (RFC 2616, Section 5.1) as sent by the client
-	// to a server. Usually the URL field should be used instead.
-	// It is an error to set this field in an HTTP client request.
-	RequestURI string
-
-	// TLS allows HTTP servers and other software to record
-	// information about the TLS connection on which the request
-	// was received. This field is not filled in by ReadRequest.
-	// The HTTP server in this package sets the field for
-	// TLS-enabled connections before invoking a handler;
-	// otherwise it leaves the field nil.
-	// This field is ignored by the HTTP client.
-	TLS *tls.ConnectionState
-}
-
-// ProtoAtLeast reports whether the HTTP protocol used
-// in the request is at least major.minor.
-func (r *Request) ProtoAtLeast(major, minor int) bool {
-	return r.ProtoMajor > major ||
-		r.ProtoMajor == major && r.ProtoMinor >= minor
-}
-
-// UserAgent returns the client's User-Agent, if sent in the request.
-func (r *Request) UserAgent() string {
-	return r.Header.Get("User-Agent")
-}
-
-// Cookies parses and returns the HTTP cookies sent with the request.
-func (r *Request) Cookies() []*Cookie {
-	return readCookies(r.Header, "")
-}
-
-var ErrNoCookie = errors.New("http: named cookie not present")
-
-// Cookie returns the named cookie provided in the request or
-// ErrNoCookie if not found.
-func (r *Request) Cookie(name string) (*Cookie, error) {
-	for _, c := range readCookies(r.Header, name) {
-		return c, nil
-	}
-	return nil, ErrNoCookie
-}
-
-// AddCookie adds a cookie to the request.  Per RFC 6265 section 5.4,
-// AddCookie does not attach more than one Cookie header field.  That
-// means all cookies, if any, are written into the same line,
-// separated by semicolon.
-func (r *Request) AddCookie(c *Cookie) {
-	s := fmt.Sprintf("%s=%s", sanitizeCookieName(c.Name), sanitizeCookieValue(c.Value))
-	if c := r.Header.Get("Cookie"); c != "" {
-		r.Header.Set("Cookie", c+"; "+s)
-	} else {
-		r.Header.Set("Cookie", s)
-	}
-}
-
-// Referer returns the referring URL, if sent in the request.
-//
-// Referer is misspelled as in the request itself, a mistake from the
-// earliest days of HTTP.  This value can also be fetched from the
-// Header map as Header["Referer"]; the benefit of making it available
-// as a method is that the compiler can diagnose programs that use the
-// alternate (correct English) spelling req.Referrer() but cannot
-// diagnose programs that use Header["Referrer"].
-func (r *Request) Referer() string {
-	return r.Header.Get("Referer")
-}
-
-// multipartByReader is a sentinel value.
-// Its presence in Request.MultipartForm indicates that parsing of the request
-// body has been handed off to a MultipartReader instead of ParseMultipartFrom.
-var multipartByReader = &multipart.Form{
-	Value: make(map[string][]string),
-	File:  make(map[string][]*multipart.FileHeader),
-}
-
-// MultipartReader returns a MIME multipart reader if this is a
-// multipart/form-data POST request, else returns nil and an error.
-// Use this function instead of ParseMultipartForm to
-// process the request body as a stream.
-func (r *Request) MultipartReader() (*multipart.Reader, error) {
-	if r.MultipartForm == multipartByReader {
-		return nil, errors.New("http: MultipartReader called twice")
-	}
-	if r.MultipartForm != nil {
-		return nil, errors.New("http: multipart handled by ParseMultipartForm")
-	}
-	r.MultipartForm = multipartByReader
-	return r.multipartReader()
-}
-
-func (r *Request) multipartReader() (*multipart.Reader, error) {
-	v := r.Header.Get("Content-Type")
-	if v == "" {
-		return nil, ErrNotMultipart
-	}
-	d, params, err := mime.ParseMediaType(v)
-	if err != nil || d != "multipart/form-data" {
-		return nil, ErrNotMultipart
-	}
-	boundary, ok := params["boundary"]
-	if !ok {
-		return nil, ErrMissingBoundary
-	}
-	return multipart.NewReader(r.Body, boundary), nil
-}
-
-// Return value if nonempty, def otherwise.
-func valueOrDefault(value, def string) string {
-	if value != "" {
-		return value
-	}
-	return def
-}
-
-// NOTE: This is not intended to reflect the actual Go version being used.
-// It was changed from "Go http package" to "Go 1.1 package http" at the
-// time of the Go 1.1 release because the former User-Agent had ended up
-// on a blacklist for some intrusion detection systems.
-// See https://codereview.appspot.com/7532043.
-const defaultUserAgent = "Go 1.1 package http"
-
-// Write writes an HTTP/1.1 request -- header and body -- in wire format.
-// This method consults the following fields of the request:
-//	Host
-//	URL
-//	Method (defaults to "GET")
-//	Header
-//	ContentLength
-//	TransferEncoding
-//	Body
-//
-// If Body is present, Content-Length is <= 0 and TransferEncoding
-// hasn't been set to "identity", Write adds "Transfer-Encoding:
-// chunked" to the header. Body is closed after it is sent.
-func (r *Request) Write(w io.Writer) error {
-	return r.write(w, false, nil)
-}
-
-// WriteProxy is like Write but writes the request in the form
-// expected by an HTTP proxy.  In particular, WriteProxy writes the
-// initial Request-URI line of the request with an absolute URI, per
-// section 5.1.2 of RFC 2616, including the scheme and host.
-// In either case, WriteProxy also writes a Host header, using
-// either r.Host or r.URL.Host.
-func (r *Request) WriteProxy(w io.Writer) error {
-	return r.write(w, true, nil)
-}
-
-// extraHeaders may be nil
-func (req *Request) write(w io.Writer, usingProxy bool, extraHeaders Header) error {
-	host := req.Host
-	if host == "" {
-		if req.URL == nil {
-			return errors.New("http: Request.Write on Request with no Host or URL set")
-		}
-		host = req.URL.Host
-	}
-
-	ruri := req.URL.RequestURI()
-	if usingProxy && req.URL.Scheme != "" && req.URL.Opaque == "" {
-		ruri = req.URL.Scheme + "://" + host + ruri
-	} else if req.Method == "CONNECT" && req.URL.Path == "" {
-		// CONNECT requests normally give just the host and port, not a full URL.
-		ruri = host
-	}
-	// TODO(bradfitz): escape at least newlines in ruri?
-
-	// Wrap the writer in a bufio Writer if it's not already buffered.
-	// Don't always call NewWriter, as that forces a bytes.Buffer
-	// and other small bufio Writers to have a minimum 4k buffer
-	// size.
-	var bw *bufio.Writer
-	if _, ok := w.(io.ByteWriter); !ok {
-		bw = bufio.NewWriter(w)
-		w = bw
-	}
-
-	fmt.Fprintf(w, "%s %s HTTP/1.1\r\n", valueOrDefault(req.Method, "GET"), ruri)
-
-	// Header lines
-	fmt.Fprintf(w, "Host: %s\r\n", host)
-
-	// Use the defaultUserAgent unless the Header contains one, which
-	// may be blank to not send the header.
-	userAgent := defaultUserAgent
-	if req.Header != nil {
-		if ua := req.Header["User-Agent"]; len(ua) > 0 {
-			userAgent = ua[0]
-		}
-	}
-	if userAgent != "" {
-		fmt.Fprintf(w, "User-Agent: %s\r\n", userAgent)
-	}
-
-	// Process Body,ContentLength,Close,Trailer
-	tw, err := newTransferWriter(req)
-	if err != nil {
-		return err
-	}
-	err = tw.WriteHeader(w)
-	if err != nil {
-		return err
-	}
-
-	err = req.Header.WriteSubset(w, reqWriteExcludeHeader)
-	if err != nil {
-		return err
-	}
-
-	if extraHeaders != nil {
-		err = extraHeaders.Write(w)
-		if err != nil {
-			return err
-		}
-	}
-
-	io.WriteString(w, "\r\n")
-
-	// Write body and trailer
-	err = tw.WriteBody(w)
-	if err != nil {
-		return err
-	}
-
-	if bw != nil {
-		return bw.Flush()
-	}
-	return nil
-}
-
-// ParseHTTPVersion parses a HTTP version string.
-// "HTTP/1.0" returns (1, 0, true).
-func ParseHTTPVersion(vers string) (major, minor int, ok bool) {
-	const Big = 1000000 // arbitrary upper bound
-	switch vers {
-	case "HTTP/1.1":
-		return 1, 1, true
-	case "HTTP/1.0":
-		return 1, 0, true
-	}
-	if !strings.HasPrefix(vers, "HTTP/") {
-		return 0, 0, false
-	}
-	dot := strings.Index(vers, ".")
-	if dot < 0 {
-		return 0, 0, false
-	}
-	major, err := strconv.Atoi(vers[5:dot])
-	if err != nil || major < 0 || major > Big {
-		return 0, 0, false
-	}
-	minor, err = strconv.Atoi(vers[dot+1:])
-	if err != nil || minor < 0 || minor > Big {
-		return 0, 0, false
-	}
-	return major, minor, true
-}
-
-// NewRequest returns a new Request given a method, URL, and optional body.
-//
-// If the provided body is also an io.Closer, the returned
-// Request.Body is set to body and will be closed by the Client
-// methods Do, Post, and PostForm, and Transport.RoundTrip.
-func NewRequest(method, urlStr string, body io.Reader) (*Request, error) {
-	u, err := url.Parse(urlStr)
-	if err != nil {
-		return nil, err
-	}
-	rc, ok := body.(io.ReadCloser)
-	if !ok && body != nil {
-		rc = ioutil.NopCloser(body)
-	}
-	req := &Request{
-		Method:     method,
-		URL:        u,
-		Proto:      "HTTP/1.1",
-		ProtoMajor: 1,
-		ProtoMinor: 1,
-		Header:     make(Header),
-		Body:       rc,
-		Host:       u.Host,
-	}
-	if body != nil {
-		switch v := body.(type) {
-		case *bytes.Buffer:
-			req.ContentLength = int64(v.Len())
-		case *bytes.Reader:
-			req.ContentLength = int64(v.Len())
-		case *strings.Reader:
-			req.ContentLength = int64(v.Len())
-		}
-	}
-
-	return req, nil
-}
-
-// SetBasicAuth sets the request's Authorization header to use HTTP
-// Basic Authentication with the provided username and password.
-//
-// With HTTP Basic Authentication the provided username and password
-// are not encrypted.
-func (r *Request) SetBasicAuth(username, password string) {
-	r.Header.Set("Authorization", "Basic "+basicAuth(username, password))
-}
-
-// parseRequestLine parses "GET /foo HTTP/1.1" into its three parts.
-func parseRequestLine(line string) (method, requestURI, proto string, ok bool) {
-	s1 := strings.Index(line, " ")
-	s2 := strings.Index(line[s1+1:], " ")
-	if s1 < 0 || s2 < 0 {
-		return
-	}
-	s2 += s1 + 1
-	return line[:s1], line[s1+1 : s2], line[s2+1:], true
-}
-
-var textprotoReaderPool sync.Pool
-
-func newTextprotoReader(br *bufio.Reader) *textproto.Reader {
-	if v := textprotoReaderPool.Get(); v != nil {
-		tr := v.(*textproto.Reader)
-		tr.R = br
-		return tr
-	}
-	return textproto.NewReader(br)
-}
-
-func putTextprotoReader(r *textproto.Reader) {
-	r.R = nil
-	textprotoReaderPool.Put(r)
-}
-
-// ReadRequest reads and parses a request from b.
-func ReadRequest(b *bufio.Reader) (req *Request, err error) {
-
-	tp := newTextprotoReader(b)
-	req = new(Request)
-
-	// First line: GET /index.html HTTP/1.0
-	var s string
-	if s, err = tp.ReadLine(); err != nil {
-		return nil, err
-	}
-	defer func() {
-		putTextprotoReader(tp)
-		if err == io.EOF {
-			err = io.ErrUnexpectedEOF
-		}
-	}()
-
-	var ok bool
-	req.Method, req.RequestURI, req.Proto, ok = parseRequestLine(s)
-	if !ok {
-		return nil, &badStringError{"malformed HTTP request", s}
-	}
-	rawurl := req.RequestURI
-	if req.ProtoMajor, req.ProtoMinor, ok = ParseHTTPVersion(req.Proto); !ok {
-		return nil, &badStringError{"malformed HTTP version", req.Proto}
-	}
-
-	// CONNECT requests are used two different ways, and neither uses a full URL:
-	// The standard use is to tunnel HTTPS through an HTTP proxy.
-	// It looks like "CONNECT www.google.com:443 HTTP/1.1", and the parameter is
-	// just the authority section of a URL. This information should go in req.URL.Host.
-	//
-	// The net/rpc package also uses CONNECT, but there the parameter is a path
-	// that starts with a slash. It can be parsed with the regular URL parser,
-	// and the path will end up in req.URL.Path, where it needs to be in order for
-	// RPC to work.
-	justAuthority := req.Method == "CONNECT" && !strings.HasPrefix(rawurl, "/")
-	if justAuthority {
-		rawurl = "http://" + rawurl
-	}
-
-	if req.URL, err = url.ParseRequestURI(rawurl); err != nil {
-		return nil, err
-	}
-
-	if justAuthority {
-		// Strip the bogus "http://" back off.
-		req.URL.Scheme = ""
-	}
-
-	// Subsequent lines: Key: value.
-	mimeHeader, err := tp.ReadMIMEHeader()
-	if err != nil {
-		return nil, err
-	}
-	req.Header = Header(mimeHeader)
-
-	// RFC2616: Must treat
-	//	GET /index.html HTTP/1.1
-	//	Host: www.google.com
-	// and
-	//	GET http://www.google.com/index.html HTTP/1.1
-	//	Host: doesntmatter
-	// the same.  In the second case, any Host line is ignored.
-	req.Host = req.URL.Host
-	if req.Host == "" {
-		req.Host = req.Header.get("Host")
-	}
-	delete(req.Header, "Host")
-
-	fixPragmaCacheControl(req.Header)
-
-	err = readTransfer(req, b)
-	if err != nil {
-		return nil, err
-	}
-
-	return req, nil
-}
-
-// MaxBytesReader is similar to io.LimitReader but is intended for
-// limiting the size of incoming request bodies. In contrast to
-// io.LimitReader, MaxBytesReader's result is a ReadCloser, returns a
-// non-EOF error for a Read beyond the limit, and Closes the
-// underlying reader when its Close method is called.
-//
-// MaxBytesReader prevents clients from accidentally or maliciously
-// sending a large request and wasting server resources.
-func MaxBytesReader(w ResponseWriter, r io.ReadCloser, n int64) io.ReadCloser {
-	return &maxBytesReader{w: w, r: r, n: n}
-}
-
-type maxBytesReader struct {
-	w       ResponseWriter
-	r       io.ReadCloser // underlying reader
-	n       int64         // max bytes remaining
-	stopped bool
-}
-
-func (l *maxBytesReader) Read(p []byte) (n int, err error) {
-	if l.n <= 0 {
-		if !l.stopped {
-			l.stopped = true
-			if res, ok := l.w.(*response); ok {
-				res.requestTooLarge()
-			}
-		}
-		return 0, errors.New("http: request body too large")
-	}
-	if int64(len(p)) > l.n {
-		p = p[:l.n]
-	}
-	n, err = l.r.Read(p)
-	l.n -= int64(n)
-	return
-}
-
-func (l *maxBytesReader) Close() error {
-	return l.r.Close()
-}
-
-func copyValues(dst, src url.Values) {
-	for k, vs := range src {
-		for _, value := range vs {
-			dst.Add(k, value)
-		}
-	}
-}
-
-func parsePostForm(r *Request) (vs url.Values, err error) {
-	if r.Body == nil {
-		err = errors.New("missing form body")
-		return
-	}
-	ct := r.Header.Get("Content-Type")
-	// RFC 2616, section 7.2.1 - empty type
-	//   SHOULD be treated as application/octet-stream
-	if ct == "" {
-		ct = "application/octet-stream"
-	}
-	ct, _, err = mime.ParseMediaType(ct)
-	switch {
-	case ct == "application/x-www-form-urlencoded":
-		var reader io.Reader = r.Body
-		maxFormSize := int64(1<<63 - 1)
-		if _, ok := r.Body.(*maxBytesReader); !ok {
-			maxFormSize = int64(10 << 20) // 10 MB is a lot of text.
-			reader = io.LimitReader(r.Body, maxFormSize+1)
-		}
-		b, e := ioutil.ReadAll(reader)
-		if e != nil {
-			if err == nil {
-				err = e
-			}
-			break
-		}
-		if int64(len(b)) > maxFormSize {
-			err = errors.New("http: POST too large")
-			return
-		}
-		vs, e = url.ParseQuery(string(b))
-		if err == nil {
-			err = e
-		}
-	case ct == "multipart/form-data":
-		// handled by ParseMultipartForm (which is calling us, or should be)
-		// TODO(bradfitz): there are too many possible
-		// orders to call too many functions here.
-		// Clean this up and write more tests.
-		// request_test.go contains the start of this,
-		// in TestParseMultipartFormOrder and others.
-	}
-	return
-}
-
-// ParseForm parses the raw query from the URL and updates r.Form.
-//
-// For POST or PUT requests, it also parses the request body as a form and
-// put the results into both r.PostForm and r.Form.
-// POST and PUT body parameters take precedence over URL query string values
-// in r.Form.
-//
-// If the request Body's size has not already been limited by MaxBytesReader,
-// the size is capped at 10MB.
-//
-// ParseMultipartForm calls ParseForm automatically.
-// It is idempotent.
-func (r *Request) ParseForm() error {
-	var err error
-	if r.PostForm == nil {
-		if r.Method == "POST" || r.Method == "PUT" || r.Method == "PATCH" {
-			r.PostForm, err = parsePostForm(r)
-		}
-		if r.PostForm == nil {
-			r.PostForm = make(url.Values)
-		}
-	}
-	if r.Form == nil {
-		if len(r.PostForm) > 0 {
-			r.Form = make(url.Values)
-			copyValues(r.Form, r.PostForm)
-		}
-		var newValues url.Values
-		if r.URL != nil {
-			var e error
-			newValues, e = url.ParseQuery(r.URL.RawQuery)
-			if err == nil {
-				err = e
-			}
-		}
-		if newValues == nil {
-			newValues = make(url.Values)
-		}
-		if r.Form == nil {
-			r.Form = newValues
-		} else {
-			copyValues(r.Form, newValues)
-		}
-	}
-	return err
-}
-
-// ParseMultipartForm parses a request body as multipart/form-data.
-// The whole request body is parsed and up to a total of maxMemory bytes of
-// its file parts are stored in memory, with the remainder stored on
-// disk in temporary files.
-// ParseMultipartForm calls ParseForm if necessary.
-// After one call to ParseMultipartForm, subsequent calls have no effect.
-func (r *Request) ParseMultipartForm(maxMemory int64) error {
-	if r.MultipartForm == multipartByReader {
-		return errors.New("http: multipart handled by MultipartReader")
-	}
-	if r.Form == nil {
-		err := r.ParseForm()
-		if err != nil {
-			return err
-		}
-	}
-	if r.MultipartForm != nil {
-		return nil
-	}
-
-	mr, err := r.multipartReader()
-	if err != nil {
-		return err
-	}
-
-	f, err := mr.ReadForm(maxMemory)
-	if err != nil {
-		return err
-	}
-	for k, v := range f.Value {
-		r.Form[k] = append(r.Form[k], v...)
-	}
-	r.MultipartForm = f
-
-	return nil
-}
-
-// FormValue returns the first value for the named component of the query.
-// POST and PUT body parameters take precedence over URL query string values.
-// FormValue calls ParseMultipartForm and ParseForm if necessary.
-// To access multiple values of the same key use ParseForm.
-func (r *Request) FormValue(key string) string {
-	if r.Form == nil {
-		r.ParseMultipartForm(defaultMaxMemory)
-	}
-	if vs := r.Form[key]; len(vs) > 0 {
-		return vs[0]
-	}
-	return ""
-}
-
-// PostFormValue returns the first value for the named component of the POST
-// or PUT request body. URL query parameters are ignored.
-// PostFormValue calls ParseMultipartForm and ParseForm if necessary.
-func (r *Request) PostFormValue(key string) string {
-	if r.PostForm == nil {
-		r.ParseMultipartForm(defaultMaxMemory)
-	}
-	if vs := r.PostForm[key]; len(vs) > 0 {
-		return vs[0]
-	}
-	return ""
-}
-
-// FormFile returns the first file for the provided form key.
-// FormFile calls ParseMultipartForm and ParseForm if necessary.
-func (r *Request) FormFile(key string) (multipart.File, *multipart.FileHeader, error) {
-	if r.MultipartForm == multipartByReader {
-		return nil, nil, errors.New("http: multipart handled by MultipartReader")
-	}
-	if r.MultipartForm == nil {
-		err := r.ParseMultipartForm(defaultMaxMemory)
-		if err != nil {
-			return nil, nil, err
-		}
-	}
-	if r.MultipartForm != nil && r.MultipartForm.File != nil {
-		if fhs := r.MultipartForm.File[key]; len(fhs) > 0 {
-			f, err := fhs[0].Open()
-			return f, fhs[0], err
-		}
-	}
-	return nil, nil, ErrMissingFile
-}
-
-func (r *Request) expectsContinue() bool {
-	return hasToken(r.Header.get("Expect"), "100-continue")
-}
-
-func (r *Request) wantsHttp10KeepAlive() bool {
-	if r.ProtoMajor != 1 || r.ProtoMinor != 0 {
-		return false
-	}
-	return hasToken(r.Header.get("Connection"), "keep-alive")
-}
-
-func (r *Request) wantsClose() bool {
-	return hasToken(r.Header.get("Connection"), "close")
-}
-
-func (r *Request) closeBody() {
-	if r.Body != nil {
-		r.Body.Close()
-	}
-}
diff --git a/src/pkg/net/http/request_test.go b/src/pkg/net/http/request_test.go
deleted file mode 100644
index b9fa3c2..0000000
--- a/src/pkg/net/http/request_test.go
+++ /dev/null
@@ -1,610 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package http_test
-
-import (
-	"bufio"
-	"bytes"
-	"fmt"
-	"io"
-	"io/ioutil"
-	"mime/multipart"
-	. "net/http"
-	"net/http/httptest"
-	"net/url"
-	"os"
-	"reflect"
-	"regexp"
-	"strings"
-	"testing"
-)
-
-func TestQuery(t *testing.T) {
-	req := &Request{Method: "GET"}
-	req.URL, _ = url.Parse("http://www.google.com/search?q=foo&q=bar")
-	if q := req.FormValue("q"); q != "foo" {
-		t.Errorf(`req.FormValue("q") = %q, want "foo"`, q)
-	}
-}
-
-func TestPostQuery(t *testing.T) {
-	req, _ := NewRequest("POST", "http://www.google.com/search?q=foo&q=bar&both=x&prio=1&empty=not",
-		strings.NewReader("z=post&both=y&prio=2&empty="))
-	req.Header.Set("Content-Type", "application/x-www-form-urlencoded; param=value")
-
-	if q := req.FormValue("q"); q != "foo" {
-		t.Errorf(`req.FormValue("q") = %q, want "foo"`, q)
-	}
-	if z := req.FormValue("z"); z != "post" {
-		t.Errorf(`req.FormValue("z") = %q, want "post"`, z)
-	}
-	if bq, found := req.PostForm["q"]; found {
-		t.Errorf(`req.PostForm["q"] = %q, want no entry in map`, bq)
-	}
-	if bz := req.PostFormValue("z"); bz != "post" {
-		t.Errorf(`req.PostFormValue("z") = %q, want "post"`, bz)
-	}
-	if qs := req.Form["q"]; !reflect.DeepEqual(qs, []string{"foo", "bar"}) {
-		t.Errorf(`req.Form["q"] = %q, want ["foo", "bar"]`, qs)
-	}
-	if both := req.Form["both"]; !reflect.DeepEqual(both, []string{"y", "x"}) {
-		t.Errorf(`req.Form["both"] = %q, want ["y", "x"]`, both)
-	}
-	if prio := req.FormValue("prio"); prio != "2" {
-		t.Errorf(`req.FormValue("prio") = %q, want "2" (from body)`, prio)
-	}
-	if empty := req.FormValue("empty"); empty != "" {
-		t.Errorf(`req.FormValue("empty") = %q, want "" (from body)`, empty)
-	}
-}
-
-func TestPatchQuery(t *testing.T) {
-	req, _ := NewRequest("PATCH", "http://www.google.com/search?q=foo&q=bar&both=x&prio=1&empty=not",
-		strings.NewReader("z=post&both=y&prio=2&empty="))
-	req.Header.Set("Content-Type", "application/x-www-form-urlencoded; param=value")
-
-	if q := req.FormValue("q"); q != "foo" {
-		t.Errorf(`req.FormValue("q") = %q, want "foo"`, q)
-	}
-	if z := req.FormValue("z"); z != "post" {
-		t.Errorf(`req.FormValue("z") = %q, want "post"`, z)
-	}
-	if bq, found := req.PostForm["q"]; found {
-		t.Errorf(`req.PostForm["q"] = %q, want no entry in map`, bq)
-	}
-	if bz := req.PostFormValue("z"); bz != "post" {
-		t.Errorf(`req.PostFormValue("z") = %q, want "post"`, bz)
-	}
-	if qs := req.Form["q"]; !reflect.DeepEqual(qs, []string{"foo", "bar"}) {
-		t.Errorf(`req.Form["q"] = %q, want ["foo", "bar"]`, qs)
-	}
-	if both := req.Form["both"]; !reflect.DeepEqual(both, []string{"y", "x"}) {
-		t.Errorf(`req.Form["both"] = %q, want ["y", "x"]`, both)
-	}
-	if prio := req.FormValue("prio"); prio != "2" {
-		t.Errorf(`req.FormValue("prio") = %q, want "2" (from body)`, prio)
-	}
-	if empty := req.FormValue("empty"); empty != "" {
-		t.Errorf(`req.FormValue("empty") = %q, want "" (from body)`, empty)
-	}
-}
-
-type stringMap map[string][]string
-type parseContentTypeTest struct {
-	shouldError bool
-	contentType stringMap
-}
-
-var parseContentTypeTests = []parseContentTypeTest{
-	{false, stringMap{"Content-Type": {"text/plain"}}},
-	// Empty content type is legal - shoult be treated as
-	// application/octet-stream (RFC 2616, section 7.2.1)
-	{false, stringMap{}},
-	{true, stringMap{"Content-Type": {"text/plain; boundary="}}},
-	{false, stringMap{"Content-Type": {"application/unknown"}}},
-}
-
-func TestParseFormUnknownContentType(t *testing.T) {
-	for i, test := range parseContentTypeTests {
-		req := &Request{
-			Method: "POST",
-			Header: Header(test.contentType),
-			Body:   ioutil.NopCloser(strings.NewReader("body")),
-		}
-		err := req.ParseForm()
-		switch {
-		case err == nil && test.shouldError:
-			t.Errorf("test %d should have returned error", i)
-		case err != nil && !test.shouldError:
-			t.Errorf("test %d should not have returned error, got %v", i, err)
-		}
-	}
-}
-
-func TestParseFormInitializeOnError(t *testing.T) {
-	nilBody, _ := NewRequest("POST", "http://www.google.com/search?q=foo", nil)
-	tests := []*Request{
-		nilBody,
-		{Method: "GET", URL: nil},
-	}
-	for i, req := range tests {
-		err := req.ParseForm()
-		if req.Form == nil {
-			t.Errorf("%d. Form not initialized, error %v", i, err)
-		}
-		if req.PostForm == nil {
-			t.Errorf("%d. PostForm not initialized, error %v", i, err)
-		}
-	}
-}
-
-func TestMultipartReader(t *testing.T) {
-	req := &Request{
-		Method: "POST",
-		Header: Header{"Content-Type": {`multipart/form-data; boundary="foo123"`}},
-		Body:   ioutil.NopCloser(new(bytes.Buffer)),
-	}
-	multipart, err := req.MultipartReader()
-	if multipart == nil {
-		t.Errorf("expected multipart; error: %v", err)
-	}
-
-	req.Header = Header{"Content-Type": {"text/plain"}}
-	multipart, err = req.MultipartReader()
-	if multipart != nil {
-		t.Error("unexpected multipart for text/plain")
-	}
-}
-
-func TestParseMultipartForm(t *testing.T) {
-	req := &Request{
-		Method: "POST",
-		Header: Header{"Content-Type": {`multipart/form-data; boundary="foo123"`}},
-		Body:   ioutil.NopCloser(new(bytes.Buffer)),
-	}
-	err := req.ParseMultipartForm(25)
-	if err == nil {
-		t.Error("expected multipart EOF, got nil")
-	}
-
-	req.Header = Header{"Content-Type": {"text/plain"}}
-	err = req.ParseMultipartForm(25)
-	if err != ErrNotMultipart {
-		t.Error("expected ErrNotMultipart for text/plain")
-	}
-}
-
-func TestRedirect(t *testing.T) {
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
-		switch r.URL.Path {
-		case "/":
-			w.Header().Set("Location", "/foo/")
-			w.WriteHeader(StatusSeeOther)
-		case "/foo/":
-			fmt.Fprintf(w, "foo")
-		default:
-			w.WriteHeader(StatusBadRequest)
-		}
-	}))
-	defer ts.Close()
-
-	var end = regexp.MustCompile("/foo/$")
-	r, err := Get(ts.URL)
-	if err != nil {
-		t.Fatal(err)
-	}
-	r.Body.Close()
-	url := r.Request.URL.String()
-	if r.StatusCode != 200 || !end.MatchString(url) {
-		t.Fatalf("Get got status %d at %q, want 200 matching /foo/$", r.StatusCode, url)
-	}
-}
-
-func TestSetBasicAuth(t *testing.T) {
-	r, _ := NewRequest("GET", "http://example.com/", nil)
-	r.SetBasicAuth("Aladdin", "open sesame")
-	if g, e := r.Header.Get("Authorization"), "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=="; g != e {
-		t.Errorf("got header %q, want %q", g, e)
-	}
-}
-
-func TestMultipartRequest(t *testing.T) {
-	// Test that we can read the values and files of a
-	// multipart request with FormValue and FormFile,
-	// and that ParseMultipartForm can be called multiple times.
-	req := newTestMultipartRequest(t)
-	if err := req.ParseMultipartForm(25); err != nil {
-		t.Fatal("ParseMultipartForm first call:", err)
-	}
-	defer req.MultipartForm.RemoveAll()
-	validateTestMultipartContents(t, req, false)
-	if err := req.ParseMultipartForm(25); err != nil {
-		t.Fatal("ParseMultipartForm second call:", err)
-	}
-	validateTestMultipartContents(t, req, false)
-}
-
-func TestMultipartRequestAuto(t *testing.T) {
-	// Test that FormValue and FormFile automatically invoke
-	// ParseMultipartForm and return the right values.
-	req := newTestMultipartRequest(t)
-	defer func() {
-		if req.MultipartForm != nil {
-			req.MultipartForm.RemoveAll()
-		}
-	}()
-	validateTestMultipartContents(t, req, true)
-}
-
-func TestMissingFileMultipartRequest(t *testing.T) {
-	// Test that FormFile returns an error if
-	// the named file is missing.
-	req := newTestMultipartRequest(t)
-	testMissingFile(t, req)
-}
-
-// Test that FormValue invokes ParseMultipartForm.
-func TestFormValueCallsParseMultipartForm(t *testing.T) {
-	req, _ := NewRequest("POST", "http://www.google.com/", strings.NewReader("z=post"))
-	req.Header.Set("Content-Type", "application/x-www-form-urlencoded; param=value")
-	if req.Form != nil {
-		t.Fatal("Unexpected request Form, want nil")
-	}
-	req.FormValue("z")
-	if req.Form == nil {
-		t.Fatal("ParseMultipartForm not called by FormValue")
-	}
-}
-
-// Test that FormFile invokes ParseMultipartForm.
-func TestFormFileCallsParseMultipartForm(t *testing.T) {
-	req := newTestMultipartRequest(t)
-	if req.Form != nil {
-		t.Fatal("Unexpected request Form, want nil")
-	}
-	req.FormFile("")
-	if req.Form == nil {
-		t.Fatal("ParseMultipartForm not called by FormFile")
-	}
-}
-
-// Test that ParseMultipartForm errors if called
-// after MultipartReader on the same request.
-func TestParseMultipartFormOrder(t *testing.T) {
-	req := newTestMultipartRequest(t)
-	if _, err := req.MultipartReader(); err != nil {
-		t.Fatalf("MultipartReader: %v", err)
-	}
-	if err := req.ParseMultipartForm(1024); err == nil {
-		t.Fatal("expected an error from ParseMultipartForm after call to MultipartReader")
-	}
-}
-
-// Test that MultipartReader errors if called
-// after ParseMultipartForm on the same request.
-func TestMultipartReaderOrder(t *testing.T) {
-	req := newTestMultipartRequest(t)
-	if err := req.ParseMultipartForm(25); err != nil {
-		t.Fatalf("ParseMultipartForm: %v", err)
-	}
-	defer req.MultipartForm.RemoveAll()
-	if _, err := req.MultipartReader(); err == nil {
-		t.Fatal("expected an error from MultipartReader after call to ParseMultipartForm")
-	}
-}
-
-// Test that FormFile errors if called after
-// MultipartReader on the same request.
-func TestFormFileOrder(t *testing.T) {
-	req := newTestMultipartRequest(t)
-	if _, err := req.MultipartReader(); err != nil {
-		t.Fatalf("MultipartReader: %v", err)
-	}
-	if _, _, err := req.FormFile(""); err == nil {
-		t.Fatal("expected an error from FormFile after call to MultipartReader")
-	}
-}
-
-var readRequestErrorTests = []struct {
-	in  string
-	err error
-}{
-	{"GET / HTTP/1.1\r\nheader:foo\r\n\r\n", nil},
-	{"GET / HTTP/1.1\r\nheader:foo\r\n", io.ErrUnexpectedEOF},
-	{"", io.EOF},
-}
-
-func TestReadRequestErrors(t *testing.T) {
-	for i, tt := range readRequestErrorTests {
-		_, err := ReadRequest(bufio.NewReader(strings.NewReader(tt.in)))
-		if err != tt.err {
-			t.Errorf("%d. got error = %v; want %v", i, err, tt.err)
-		}
-	}
-}
-
-func TestNewRequestHost(t *testing.T) {
-	req, err := NewRequest("GET", "http://localhost:1234/", nil)
-	if err != nil {
-		t.Fatal(err)
-	}
-	if req.Host != "localhost:1234" {
-		t.Errorf("Host = %q; want localhost:1234", req.Host)
-	}
-}
-
-func TestNewRequestContentLength(t *testing.T) {
-	readByte := func(r io.Reader) io.Reader {
-		var b [1]byte
-		r.Read(b[:])
-		return r
-	}
-	tests := []struct {
-		r    io.Reader
-		want int64
-	}{
-		{bytes.NewReader([]byte("123")), 3},
-		{bytes.NewBuffer([]byte("1234")), 4},
-		{strings.NewReader("12345"), 5},
-		// Not detected:
-		{struct{ io.Reader }{strings.NewReader("xyz")}, 0},
-		{io.NewSectionReader(strings.NewReader("x"), 0, 6), 0},
-		{readByte(io.NewSectionReader(strings.NewReader("xy"), 0, 6)), 0},
-	}
-	for _, tt := range tests {
-		req, err := NewRequest("POST", "http://localhost/", tt.r)
-		if err != nil {
-			t.Fatal(err)
-		}
-		if req.ContentLength != tt.want {
-			t.Errorf("ContentLength(%T) = %d; want %d", tt.r, req.ContentLength, tt.want)
-		}
-	}
-}
-
-var parseHTTPVersionTests = []struct {
-	vers         string
-	major, minor int
-	ok           bool
-}{
-	{"HTTP/0.9", 0, 9, true},
-	{"HTTP/1.0", 1, 0, true},
-	{"HTTP/1.1", 1, 1, true},
-	{"HTTP/3.14", 3, 14, true},
-
-	{"HTTP", 0, 0, false},
-	{"HTTP/one.one", 0, 0, false},
-	{"HTTP/1.1/", 0, 0, false},
-	{"HTTP/-1,0", 0, 0, false},
-	{"HTTP/0,-1", 0, 0, false},
-	{"HTTP/", 0, 0, false},
-	{"HTTP/1,1", 0, 0, false},
-}
-
-func TestParseHTTPVersion(t *testing.T) {
-	for _, tt := range parseHTTPVersionTests {
-		major, minor, ok := ParseHTTPVersion(tt.vers)
-		if ok != tt.ok || major != tt.major || minor != tt.minor {
-			type version struct {
-				major, minor int
-				ok           bool
-			}
-			t.Errorf("failed to parse %q, expected: %#v, got %#v", tt.vers, version{tt.major, tt.minor, tt.ok}, version{major, minor, ok})
-		}
-	}
-}
-
-type logWrites struct {
-	t   *testing.T
-	dst *[]string
-}
-
-func (l logWrites) WriteByte(c byte) error {
-	l.t.Fatalf("unexpected WriteByte call")
-	return nil
-}
-
-func (l logWrites) Write(p []byte) (n int, err error) {
-	*l.dst = append(*l.dst, string(p))
-	return len(p), nil
-}
-
-func TestRequestWriteBufferedWriter(t *testing.T) {
-	got := []string{}
-	req, _ := NewRequest("GET", "http://foo.com/", nil)
-	req.Write(logWrites{t, &got})
-	want := []string{
-		"GET / HTTP/1.1\r\n",
-		"Host: foo.com\r\n",
-		"User-Agent: " + DefaultUserAgent + "\r\n",
-		"\r\n",
-	}
-	if !reflect.DeepEqual(got, want) {
-		t.Errorf("Writes = %q\n  Want = %q", got, want)
-	}
-}
-
-func testMissingFile(t *testing.T, req *Request) {
-	f, fh, err := req.FormFile("missing")
-	if f != nil {
-		t.Errorf("FormFile file = %v, want nil", f)
-	}
-	if fh != nil {
-		t.Errorf("FormFile file header = %q, want nil", fh)
-	}
-	if err != ErrMissingFile {
-		t.Errorf("FormFile err = %q, want ErrMissingFile", err)
-	}
-}
-
-func newTestMultipartRequest(t *testing.T) *Request {
-	b := strings.NewReader(strings.Replace(message, "\n", "\r\n", -1))
-	req, err := NewRequest("POST", "/", b)
-	if err != nil {
-		t.Fatal("NewRequest:", err)
-	}
-	ctype := fmt.Sprintf(`multipart/form-data; boundary="%s"`, boundary)
-	req.Header.Set("Content-type", ctype)
-	return req
-}
-
-func validateTestMultipartContents(t *testing.T, req *Request, allMem bool) {
-	if g, e := req.FormValue("texta"), textaValue; g != e {
-		t.Errorf("texta value = %q, want %q", g, e)
-	}
-	if g, e := req.FormValue("textb"), textbValue; g != e {
-		t.Errorf("textb value = %q, want %q", g, e)
-	}
-	if g := req.FormValue("missing"); g != "" {
-		t.Errorf("missing value = %q, want empty string", g)
-	}
-
-	assertMem := func(n string, fd multipart.File) {
-		if _, ok := fd.(*os.File); ok {
-			t.Error(n, " is *os.File, should not be")
-		}
-	}
-	fda := testMultipartFile(t, req, "filea", "filea.txt", fileaContents)
-	defer fda.Close()
-	assertMem("filea", fda)
-	fdb := testMultipartFile(t, req, "fileb", "fileb.txt", filebContents)
-	defer fdb.Close()
-	if allMem {
-		assertMem("fileb", fdb)
-	} else {
-		if _, ok := fdb.(*os.File); !ok {
-			t.Errorf("fileb has unexpected underlying type %T", fdb)
-		}
-	}
-
-	testMissingFile(t, req)
-}
-
-func testMultipartFile(t *testing.T, req *Request, key, expectFilename, expectContent string) multipart.File {
-	f, fh, err := req.FormFile(key)
-	if err != nil {
-		t.Fatalf("FormFile(%q): %q", key, err)
-	}
-	if fh.Filename != expectFilename {
-		t.Errorf("filename = %q, want %q", fh.Filename, expectFilename)
-	}
-	var b bytes.Buffer
-	_, err = io.Copy(&b, f)
-	if err != nil {
-		t.Fatal("copying contents:", err)
-	}
-	if g := b.String(); g != expectContent {
-		t.Errorf("contents = %q, want %q", g, expectContent)
-	}
-	return f
-}
-
-const (
-	fileaContents = "This is a test file."
-	filebContents = "Another test file."
-	textaValue    = "foo"
-	textbValue    = "bar"
-	boundary      = `MyBoundary`
-)
-
-const message = `
---MyBoundary
-Content-Disposition: form-data; name="filea"; filename="filea.txt"
-Content-Type: text/plain
-
-` + fileaContents + `
---MyBoundary
-Content-Disposition: form-data; name="fileb"; filename="fileb.txt"
-Content-Type: text/plain
-
-` + filebContents + `
---MyBoundary
-Content-Disposition: form-data; name="texta"
-
-` + textaValue + `
---MyBoundary
-Content-Disposition: form-data; name="textb"
-
-` + textbValue + `
---MyBoundary--
-`
-
-func benchmarkReadRequest(b *testing.B, request string) {
-	request = request + "\n"                             // final \n
-	request = strings.Replace(request, "\n", "\r\n", -1) // expand \n to \r\n
-	b.SetBytes(int64(len(request)))
-	r := bufio.NewReader(&infiniteReader{buf: []byte(request)})
-	b.ReportAllocs()
-	b.ResetTimer()
-	for i := 0; i < b.N; i++ {
-		_, err := ReadRequest(r)
-		if err != nil {
-			b.Fatalf("failed to read request: %v", err)
-		}
-	}
-}
-
-// infiniteReader satisfies Read requests as if the contents of buf
-// loop indefinitely.
-type infiniteReader struct {
-	buf    []byte
-	offset int
-}
-
-func (r *infiniteReader) Read(b []byte) (int, error) {
-	n := copy(b, r.buf[r.offset:])
-	r.offset = (r.offset + n) % len(r.buf)
-	return n, nil
-}
-
-func BenchmarkReadRequestChrome(b *testing.B) {
-	// https://github.com/felixge/node-http-perf/blob/master/fixtures/get.http
-	benchmarkReadRequest(b, `GET / HTTP/1.1
-Host: localhost:8080
-Connection: keep-alive
-Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
-User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.52 Safari/537.17
-Accept-Encoding: gzip,deflate,sdch
-Accept-Language: en-US,en;q=0.8
-Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
-Cookie: __utma=1.1978842379.1323102373.1323102373.1323102373.1; EPi:NumberOfVisits=1,2012-02-28T13:42:18; CrmSession=5b707226b9563e1bc69084d07a107c98; plushContainerWidth=100%25; plushNoTopMenu=0; hudson_auto_refresh=false
-`)
-}
-
-func BenchmarkReadRequestCurl(b *testing.B) {
-	// curl http://localhost:8080/
-	benchmarkReadRequest(b, `GET / HTTP/1.1
-User-Agent: curl/7.27.0
-Host: localhost:8080
-Accept: */*
-`)
-}
-
-func BenchmarkReadRequestApachebench(b *testing.B) {
-	// ab -n 1 -c 1 http://localhost:8080/
-	benchmarkReadRequest(b, `GET / HTTP/1.0
-Host: localhost:8080
-User-Agent: ApacheBench/2.3
-Accept: */*
-`)
-}
-
-func BenchmarkReadRequestSiege(b *testing.B) {
-	// siege -r 1 -c 1 http://localhost:8080/
-	benchmarkReadRequest(b, `GET / HTTP/1.1
-Host: localhost:8080
-Accept: */*
-Accept-Encoding: gzip
-User-Agent: JoeDog/1.00 [en] (X11; I; Siege 2.70)
-Connection: keep-alive
-`)
-}
-
-func BenchmarkReadRequestWrk(b *testing.B) {
-	// wrk -t 1 -r 1 -c 1 http://localhost:8080/
-	benchmarkReadRequest(b, `GET / HTTP/1.1
-Host: localhost:8080
-`)
-}
diff --git a/src/pkg/net/http/requestwrite_test.go b/src/pkg/net/http/requestwrite_test.go
deleted file mode 100644
index dc0e204..0000000
--- a/src/pkg/net/http/requestwrite_test.go
+++ /dev/null
@@ -1,565 +0,0 @@
-// Copyright 2010 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package http
-
-import (
-	"bytes"
-	"errors"
-	"fmt"
-	"io"
-	"io/ioutil"
-	"net/url"
-	"strings"
-	"testing"
-)
-
-type reqWriteTest struct {
-	Req  Request
-	Body interface{} // optional []byte or func() io.ReadCloser to populate Req.Body
-
-	// Any of these three may be empty to skip that test.
-	WantWrite string // Request.Write
-	WantProxy string // Request.WriteProxy
-
-	WantError error // wanted error from Request.Write
-}
-
-var reqWriteTests = []reqWriteTest{
-	// HTTP/1.1 => chunked coding; no body; no trailer
-	{
-		Req: Request{
-			Method: "GET",
-			URL: &url.URL{
-				Scheme: "http",
-				Host:   "www.techcrunch.com",
-				Path:   "/",
-			},
-			Proto:      "HTTP/1.1",
-			ProtoMajor: 1,
-			ProtoMinor: 1,
-			Header: Header{
-				"Accept":           {"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"},
-				"Accept-Charset":   {"ISO-8859-1,utf-8;q=0.7,*;q=0.7"},
-				"Accept-Encoding":  {"gzip,deflate"},
-				"Accept-Language":  {"en-us,en;q=0.5"},
-				"Keep-Alive":       {"300"},
-				"Proxy-Connection": {"keep-alive"},
-				"User-Agent":       {"Fake"},
-			},
-			Body:  nil,
-			Close: false,
-			Host:  "www.techcrunch.com",
-			Form:  map[string][]string{},
-		},
-
-		WantWrite: "GET / HTTP/1.1\r\n" +
-			"Host: www.techcrunch.com\r\n" +
-			"User-Agent: Fake\r\n" +
-			"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n" +
-			"Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n" +
-			"Accept-Encoding: gzip,deflate\r\n" +
-			"Accept-Language: en-us,en;q=0.5\r\n" +
-			"Keep-Alive: 300\r\n" +
-			"Proxy-Connection: keep-alive\r\n\r\n",
-
-		WantProxy: "GET http://www.techcrunch.com/ HTTP/1.1\r\n" +
-			"Host: www.techcrunch.com\r\n" +
-			"User-Agent: Fake\r\n" +
-			"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n" +
-			"Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n" +
-			"Accept-Encoding: gzip,deflate\r\n" +
-			"Accept-Language: en-us,en;q=0.5\r\n" +
-			"Keep-Alive: 300\r\n" +
-			"Proxy-Connection: keep-alive\r\n\r\n",
-	},
-	// HTTP/1.1 => chunked coding; body; empty trailer
-	{
-		Req: Request{
-			Method: "GET",
-			URL: &url.URL{
-				Scheme: "http",
-				Host:   "www.google.com",
-				Path:   "/search",
-			},
-			ProtoMajor:       1,
-			ProtoMinor:       1,
-			Header:           Header{},
-			TransferEncoding: []string{"chunked"},
-		},
-
-		Body: []byte("abcdef"),
-
-		WantWrite: "GET /search HTTP/1.1\r\n" +
-			"Host: www.google.com\r\n" +
-			"User-Agent: Go 1.1 package http\r\n" +
-			"Transfer-Encoding: chunked\r\n\r\n" +
-			chunk("abcdef") + chunk(""),
-
-		WantProxy: "GET http://www.google.com/search HTTP/1.1\r\n" +
-			"Host: www.google.com\r\n" +
-			"User-Agent: Go 1.1 package http\r\n" +
-			"Transfer-Encoding: chunked\r\n\r\n" +
-			chunk("abcdef") + chunk(""),
-	},
-	// HTTP/1.1 POST => chunked coding; body; empty trailer
-	{
-		Req: Request{
-			Method: "POST",
-			URL: &url.URL{
-				Scheme: "http",
-				Host:   "www.google.com",
-				Path:   "/search",
-			},
-			ProtoMajor:       1,
-			ProtoMinor:       1,
-			Header:           Header{},
-			Close:            true,
-			TransferEncoding: []string{"chunked"},
-		},
-
-		Body: []byte("abcdef"),
-
-		WantWrite: "POST /search HTTP/1.1\r\n" +
-			"Host: www.google.com\r\n" +
-			"User-Agent: Go 1.1 package http\r\n" +
-			"Connection: close\r\n" +
-			"Transfer-Encoding: chunked\r\n\r\n" +
-			chunk("abcdef") + chunk(""),
-
-		WantProxy: "POST http://www.google.com/search HTTP/1.1\r\n" +
-			"Host: www.google.com\r\n" +
-			"User-Agent: Go 1.1 package http\r\n" +
-			"Connection: close\r\n" +
-			"Transfer-Encoding: chunked\r\n\r\n" +
-			chunk("abcdef") + chunk(""),
-	},
-
-	// HTTP/1.1 POST with Content-Length, no chunking
-	{
-		Req: Request{
-			Method: "POST",
-			URL: &url.URL{
-				Scheme: "http",
-				Host:   "www.google.com",
-				Path:   "/search",
-			},
-			ProtoMajor:    1,
-			ProtoMinor:    1,
-			Header:        Header{},
-			Close:         true,
-			ContentLength: 6,
-		},
-
-		Body: []byte("abcdef"),
-
-		WantWrite: "POST /search HTTP/1.1\r\n" +
-			"Host: www.google.com\r\n" +
-			"User-Agent: Go 1.1 package http\r\n" +
-			"Connection: close\r\n" +
-			"Content-Length: 6\r\n" +
-			"\r\n" +
-			"abcdef",
-
-		WantProxy: "POST http://www.google.com/search HTTP/1.1\r\n" +
-			"Host: www.google.com\r\n" +
-			"User-Agent: Go 1.1 package http\r\n" +
-			"Connection: close\r\n" +
-			"Content-Length: 6\r\n" +
-			"\r\n" +
-			"abcdef",
-	},
-
-	// HTTP/1.1 POST with Content-Length in headers
-	{
-		Req: Request{
-			Method: "POST",
-			URL:    mustParseURL("http://example.com/"),
-			Host:   "example.com",
-			Header: Header{
-				"Content-Length": []string{"10"}, // ignored
-			},
-			ContentLength: 6,
-		},
-
-		Body: []byte("abcdef"),
-
-		WantWrite: "POST / HTTP/1.1\r\n" +
-			"Host: example.com\r\n" +
-			"User-Agent: Go 1.1 package http\r\n" +
-			"Content-Length: 6\r\n" +
-			"\r\n" +
-			"abcdef",
-
-		WantProxy: "POST http://example.com/ HTTP/1.1\r\n" +
-			"Host: example.com\r\n" +
-			"User-Agent: Go 1.1 package http\r\n" +
-			"Content-Length: 6\r\n" +
-			"\r\n" +
-			"abcdef",
-	},
-
-	// default to HTTP/1.1
-	{
-		Req: Request{
-			Method: "GET",
-			URL:    mustParseURL("/search"),
-			Host:   "www.google.com",
-		},
-
-		WantWrite: "GET /search HTTP/1.1\r\n" +
-			"Host: www.google.com\r\n" +
-			"User-Agent: Go 1.1 package http\r\n" +
-			"\r\n",
-	},
-
-	// Request with a 0 ContentLength and a 0 byte body.
-	{
-		Req: Request{
-			Method:        "POST",
-			URL:           mustParseURL("/"),
-			Host:          "example.com",
-			ProtoMajor:    1,
-			ProtoMinor:    1,
-			ContentLength: 0, // as if unset by user
-		},
-
-		Body: func() io.ReadCloser { return ioutil.NopCloser(io.LimitReader(strings.NewReader("xx"), 0)) },
-
-		// RFC 2616 Section 14.13 says Content-Length should be specified
-		// unless body is prohibited by the request method.
-		// Also, nginx expects it for POST and PUT.
-		WantWrite: "POST / HTTP/1.1\r\n" +
-			"Host: example.com\r\n" +
-			"User-Agent: Go 1.1 package http\r\n" +
-			"Content-Length: 0\r\n" +
-			"\r\n",
-
-		WantProxy: "POST / HTTP/1.1\r\n" +
-			"Host: example.com\r\n" +
-			"User-Agent: Go 1.1 package http\r\n" +
-			"Content-Length: 0\r\n" +
-			"\r\n",
-	},
-
-	// Request with a 0 ContentLength and a 1 byte body.
-	{
-		Req: Request{
-			Method:        "POST",
-			URL:           mustParseURL("/"),
-			Host:          "example.com",
-			ProtoMajor:    1,
-			ProtoMinor:    1,
-			ContentLength: 0, // as if unset by user
-		},
-
-		Body: func() io.ReadCloser { return ioutil.NopCloser(io.LimitReader(strings.NewReader("xx"), 1)) },
-
-		WantWrite: "POST / HTTP/1.1\r\n" +
-			"Host: example.com\r\n" +
-			"User-Agent: Go 1.1 package http\r\n" +
-			"Transfer-Encoding: chunked\r\n\r\n" +
-			chunk("x") + chunk(""),
-
-		WantProxy: "POST / HTTP/1.1\r\n" +
-			"Host: example.com\r\n" +
-			"User-Agent: Go 1.1 package http\r\n" +
-			"Transfer-Encoding: chunked\r\n\r\n" +
-			chunk("x") + chunk(""),
-	},
-
-	// Request with a ContentLength of 10 but a 5 byte body.
-	{
-		Req: Request{
-			Method:        "POST",
-			URL:           mustParseURL("/"),
-			Host:          "example.com",
-			ProtoMajor:    1,
-			ProtoMinor:    1,
-			ContentLength: 10, // but we're going to send only 5 bytes
-		},
-		Body:      []byte("12345"),
-		WantError: errors.New("http: Request.ContentLength=10 with Body length 5"),
-	},
-
-	// Request with a ContentLength of 4 but an 8 byte body.
-	{
-		Req: Request{
-			Method:        "POST",
-			URL:           mustParseURL("/"),
-			Host:          "example.com",
-			ProtoMajor:    1,
-			ProtoMinor:    1,
-			ContentLength: 4, // but we're going to try to send 8 bytes
-		},
-		Body:      []byte("12345678"),
-		WantError: errors.New("http: Request.ContentLength=4 with Body length 8"),
-	},
-
-	// Request with a 5 ContentLength and nil body.
-	{
-		Req: Request{
-			Method:        "POST",
-			URL:           mustParseURL("/"),
-			Host:          "example.com",
-			ProtoMajor:    1,
-			ProtoMinor:    1,
-			ContentLength: 5, // but we'll omit the body
-		},
-		WantError: errors.New("http: Request.ContentLength=5 with nil Body"),
-	},
-
-	// Request with a 0 ContentLength and a body with 1 byte content and an error.
-	{
-		Req: Request{
-			Method:        "POST",
-			URL:           mustParseURL("/"),
-			Host:          "example.com",
-			ProtoMajor:    1,
-			ProtoMinor:    1,
-			ContentLength: 0, // as if unset by user
-		},
-
-		Body: func() io.ReadCloser {
-			err := errors.New("Custom reader error")
-			errReader := &errorReader{err}
-			return ioutil.NopCloser(io.MultiReader(strings.NewReader("x"), errReader))
-		},
-
-		WantError: errors.New("Custom reader error"),
-	},
-
-	// Request with a 0 ContentLength and a body without content and an error.
-	{
-		Req: Request{
-			Method:        "POST",
-			URL:           mustParseURL("/"),
-			Host:          "example.com",
-			ProtoMajor:    1,
-			ProtoMinor:    1,
-			ContentLength: 0, // as if unset by user
-		},
-
-		Body: func() io.ReadCloser {
-			err := errors.New("Custom reader error")
-			errReader := &errorReader{err}
-			return ioutil.NopCloser(errReader)
-		},
-
-		WantError: errors.New("Custom reader error"),
-	},
-
-	// Verify that DumpRequest preserves the HTTP version number, doesn't add a Host,
-	// and doesn't add a User-Agent.
-	{
-		Req: Request{
-			Method:     "GET",
-			URL:        mustParseURL("/foo"),
-			ProtoMajor: 1,
-			ProtoMinor: 0,
-			Header: Header{
-				"X-Foo": []string{"X-Bar"},
-			},
-		},
-
-		WantWrite: "GET /foo HTTP/1.1\r\n" +
-			"Host: \r\n" +
-			"User-Agent: Go 1.1 package http\r\n" +
-			"X-Foo: X-Bar\r\n\r\n",
-	},
-
-	// If no Request.Host and no Request.URL.Host, we send
-	// an empty Host header, and don't use
-	// Request.Header["Host"]. This is just testing that
-	// we don't change Go 1.0 behavior.
-	{
-		Req: Request{
-			Method: "GET",
-			Host:   "",
-			URL: &url.URL{
-				Scheme: "http",
-				Host:   "",
-				Path:   "/search",
-			},
-			ProtoMajor: 1,
-			ProtoMinor: 1,
-			Header: Header{
-				"Host": []string{"bad.example.com"},
-			},
-		},
-
-		WantWrite: "GET /search HTTP/1.1\r\n" +
-			"Host: \r\n" +
-			"User-Agent: Go 1.1 package http\r\n\r\n",
-	},
-
-	// Opaque test #1 from golang.org/issue/4860
-	{
-		Req: Request{
-			Method: "GET",
-			URL: &url.URL{
-				Scheme: "http",
-				Host:   "www.google.com",
-				Opaque: "/%2F/%2F/",
-			},
-			ProtoMajor: 1,
-			ProtoMinor: 1,
-			Header:     Header{},
-		},
-
-		WantWrite: "GET /%2F/%2F/ HTTP/1.1\r\n" +
-			"Host: www.google.com\r\n" +
-			"User-Agent: Go 1.1 package http\r\n\r\n",
-	},
-
-	// Opaque test #2 from golang.org/issue/4860
-	{
-		Req: Request{
-			Method: "GET",
-			URL: &url.URL{
-				Scheme: "http",
-				Host:   "x.google.com",
-				Opaque: "//y.google.com/%2F/%2F/",
-			},
-			ProtoMajor: 1,
-			ProtoMinor: 1,
-			Header:     Header{},
-		},
-
-		WantWrite: "GET http://y.google.com/%2F/%2F/ HTTP/1.1\r\n" +
-			"Host: x.google.com\r\n" +
-			"User-Agent: Go 1.1 package http\r\n\r\n",
-	},
-
-	// Testing custom case in header keys. Issue 5022.
-	{
-		Req: Request{
-			Method: "GET",
-			URL: &url.URL{
-				Scheme: "http",
-				Host:   "www.google.com",
-				Path:   "/",
-			},
-			Proto:      "HTTP/1.1",
-			ProtoMajor: 1,
-			ProtoMinor: 1,
-			Header: Header{
-				"ALL-CAPS": {"x"},
-			},
-		},
-
-		WantWrite: "GET / HTTP/1.1\r\n" +
-			"Host: www.google.com\r\n" +
-			"User-Agent: Go 1.1 package http\r\n" +
-			"ALL-CAPS: x\r\n" +
-			"\r\n",
-	},
-}
-
-func TestRequestWrite(t *testing.T) {
-	for i := range reqWriteTests {
-		tt := &reqWriteTests[i]
-
-		setBody := func() {
-			if tt.Body == nil {
-				return
-			}
-			switch b := tt.Body.(type) {
-			case []byte:
-				tt.Req.Body = ioutil.NopCloser(bytes.NewReader(b))
-			case func() io.ReadCloser:
-				tt.Req.Body = b()
-			}
-		}
-		setBody()
-		if tt.Req.Header == nil {
-			tt.Req.Header = make(Header)
-		}
-
-		var braw bytes.Buffer
-		err := tt.Req.Write(&braw)
-		if g, e := fmt.Sprintf("%v", err), fmt.Sprintf("%v", tt.WantError); g != e {
-			t.Errorf("writing #%d, err = %q, want %q", i, g, e)
-			continue
-		}
-		if err != nil {
-			continue
-		}
-
-		if tt.WantWrite != "" {
-			sraw := braw.String()
-			if sraw != tt.WantWrite {
-				t.Errorf("Test %d, expecting:\n%s\nGot:\n%s\n", i, tt.WantWrite, sraw)
-				continue
-			}
-		}
-
-		if tt.WantProxy != "" {
-			setBody()
-			var praw bytes.Buffer
-			err = tt.Req.WriteProxy(&praw)
-			if err != nil {
-				t.Errorf("WriteProxy #%d: %s", i, err)
-				continue
-			}
-			sraw := praw.String()
-			if sraw != tt.WantProxy {
-				t.Errorf("Test Proxy %d, expecting:\n%s\nGot:\n%s\n", i, tt.WantProxy, sraw)
-				continue
-			}
-		}
-	}
-}
-
-type closeChecker struct {
-	io.Reader
-	closed bool
-}
-
-func (rc *closeChecker) Close() error {
-	rc.closed = true
-	return nil
-}
-
-// TestRequestWriteClosesBody tests that Request.Write does close its request.Body.
-// It also indirectly tests NewRequest and that it doesn't wrap an existing Closer
-// inside a NopCloser, and that it serializes it correctly.
-func TestRequestWriteClosesBody(t *testing.T) {
-	rc := &closeChecker{Reader: strings.NewReader("my body")}
-	req, _ := NewRequest("POST", "http://foo.com/", rc)
-	if req.ContentLength != 0 {
-		t.Errorf("got req.ContentLength %d, want 0", req.ContentLength)
-	}
-	buf := new(bytes.Buffer)
-	req.Write(buf)
-	if !rc.closed {
-		t.Error("body not closed after write")
-	}
-	expected := "POST / HTTP/1.1\r\n" +
-		"Host: foo.com\r\n" +
-		"User-Agent: Go 1.1 package http\r\n" +
-		"Transfer-Encoding: chunked\r\n\r\n" +
-		// TODO: currently we don't buffer before chunking, so we get a
-		// single "m" chunk before the other chunks, as this was the 1-byte
-		// read from our MultiReader where we stiched the Body back together
-		// after sniffing whether the Body was 0 bytes or not.
-		chunk("m") +
-		chunk("y body") +
-		chunk("")
-	if buf.String() != expected {
-		t.Errorf("write:\n got: %s\nwant: %s", buf.String(), expected)
-	}
-}
-
-func chunk(s string) string {
-	return fmt.Sprintf("%x\r\n%s\r\n", len(s), s)
-}
-
-func mustParseURL(s string) *url.URL {
-	u, err := url.Parse(s)
-	if err != nil {
-		panic(fmt.Sprintf("Error parsing URL %q: %v", s, err))
-	}
-	return u
-}
diff --git a/src/pkg/net/http/response_test.go b/src/pkg/net/http/response_test.go
deleted file mode 100644
index 4b8946f..0000000
--- a/src/pkg/net/http/response_test.go
+++ /dev/null
@@ -1,645 +0,0 @@
-// Copyright 2010 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package http
-
-import (
-	"bufio"
-	"bytes"
-	"compress/gzip"
-	"crypto/rand"
-	"fmt"
-	"io"
-	"io/ioutil"
-	"net/url"
-	"reflect"
-	"regexp"
-	"strings"
-	"testing"
-)
-
-type respTest struct {
-	Raw  string
-	Resp Response
-	Body string
-}
-
-func dummyReq(method string) *Request {
-	return &Request{Method: method}
-}
-
-func dummyReq11(method string) *Request {
-	return &Request{Method: method, Proto: "HTTP/1.1", ProtoMajor: 1, ProtoMinor: 1}
-}
-
-var respTests = []respTest{
-	// Unchunked response without Content-Length.
-	{
-		"HTTP/1.0 200 OK\r\n" +
-			"Connection: close\r\n" +
-			"\r\n" +
-			"Body here\n",
-
-		Response{
-			Status:     "200 OK",
-			StatusCode: 200,
-			Proto:      "HTTP/1.0",
-			ProtoMajor: 1,
-			ProtoMinor: 0,
-			Request:    dummyReq("GET"),
-			Header: Header{
-				"Connection": {"close"}, // TODO(rsc): Delete?
-			},
-			Close:         true,
-			ContentLength: -1,
-		},
-
-		"Body here\n",
-	},
-
-	// Unchunked HTTP/1.1 response without Content-Length or
-	// Connection headers.
-	{
-		"HTTP/1.1 200 OK\r\n" +
-			"\r\n" +
-			"Body here\n",
-
-		Response{
-			Status:        "200 OK",
-			StatusCode:    200,
-			Proto:         "HTTP/1.1",
-			ProtoMajor:    1,
-			ProtoMinor:    1,
-			Header:        Header{},
-			Request:       dummyReq("GET"),
-			Close:         true,
-			ContentLength: -1,
-		},
-
-		"Body here\n",
-	},
-
-	// Unchunked HTTP/1.1 204 response without Content-Length.
-	{
-		"HTTP/1.1 204 No Content\r\n" +
-			"\r\n" +
-			"Body should not be read!\n",
-
-		Response{
-			Status:        "204 No Content",
-			StatusCode:    204,
-			Proto:         "HTTP/1.1",
-			ProtoMajor:    1,
-			ProtoMinor:    1,
-			Header:        Header{},
-			Request:       dummyReq("GET"),
-			Close:         false,
-			ContentLength: 0,
-		},
-
-		"",
-	},
-
-	// Unchunked response with Content-Length.
-	{
-		"HTTP/1.0 200 OK\r\n" +
-			"Content-Length: 10\r\n" +
-			"Connection: close\r\n" +
-			"\r\n" +
-			"Body here\n",
-
-		Response{
-			Status:     "200 OK",
-			StatusCode: 200,
-			Proto:      "HTTP/1.0",
-			ProtoMajor: 1,
-			ProtoMinor: 0,
-			Request:    dummyReq("GET"),
-			Header: Header{
-				"Connection":     {"close"},
-				"Content-Length": {"10"},
-			},
-			Close:         true,
-			ContentLength: 10,
-		},
-
-		"Body here\n",
-	},
-
-	// Chunked response without Content-Length.
-	{
-		"HTTP/1.1 200 OK\r\n" +
-			"Transfer-Encoding: chunked\r\n" +
-			"\r\n" +
-			"0a\r\n" +
-			"Body here\n\r\n" +
-			"09\r\n" +
-			"continued\r\n" +
-			"0\r\n" +
-			"\r\n",
-
-		Response{
-			Status:           "200 OK",
-			StatusCode:       200,
-			Proto:            "HTTP/1.1",
-			ProtoMajor:       1,
-			ProtoMinor:       1,
-			Request:          dummyReq("GET"),
-			Header:           Header{},
-			Close:            false,
-			ContentLength:    -1,
-			TransferEncoding: []string{"chunked"},
-		},
-
-		"Body here\ncontinued",
-	},
-
-	// Chunked response with Content-Length.
-	{
-		"HTTP/1.1 200 OK\r\n" +
-			"Transfer-Encoding: chunked\r\n" +
-			"Content-Length: 10\r\n" +
-			"\r\n" +
-			"0a\r\n" +
-			"Body here\n\r\n" +
-			"0\r\n" +
-			"\r\n",
-
-		Response{
-			Status:           "200 OK",
-			StatusCode:       200,
-			Proto:            "HTTP/1.1",
-			ProtoMajor:       1,
-			ProtoMinor:       1,
-			Request:          dummyReq("GET"),
-			Header:           Header{},
-			Close:            false,
-			ContentLength:    -1,
-			TransferEncoding: []string{"chunked"},
-		},
-
-		"Body here\n",
-	},
-
-	// Chunked response in response to a HEAD request
-	{
-		"HTTP/1.1 200 OK\r\n" +
-			"Transfer-Encoding: chunked\r\n" +
-			"\r\n",
-
-		Response{
-			Status:           "200 OK",
-			StatusCode:       200,
-			Proto:            "HTTP/1.1",
-			ProtoMajor:       1,
-			ProtoMinor:       1,
-			Request:          dummyReq("HEAD"),
-			Header:           Header{},
-			TransferEncoding: []string{"chunked"},
-			Close:            false,
-			ContentLength:    -1,
-		},
-
-		"",
-	},
-
-	// Content-Length in response to a HEAD request
-	{
-		"HTTP/1.0 200 OK\r\n" +
-			"Content-Length: 256\r\n" +
-			"\r\n",
-
-		Response{
-			Status:           "200 OK",
-			StatusCode:       200,
-			Proto:            "HTTP/1.0",
-			ProtoMajor:       1,
-			ProtoMinor:       0,
-			Request:          dummyReq("HEAD"),
-			Header:           Header{"Content-Length": {"256"}},
-			TransferEncoding: nil,
-			Close:            true,
-			ContentLength:    256,
-		},
-
-		"",
-	},
-
-	// Content-Length in response to a HEAD request with HTTP/1.1
-	{
-		"HTTP/1.1 200 OK\r\n" +
-			"Content-Length: 256\r\n" +
-			"\r\n",
-
-		Response{
-			Status:           "200 OK",
-			StatusCode:       200,
-			Proto:            "HTTP/1.1",
-			ProtoMajor:       1,
-			ProtoMinor:       1,
-			Request:          dummyReq("HEAD"),
-			Header:           Header{"Content-Length": {"256"}},
-			TransferEncoding: nil,
-			Close:            false,
-			ContentLength:    256,
-		},
-
-		"",
-	},
-
-	// No Content-Length or Chunked in response to a HEAD request
-	{
-		"HTTP/1.0 200 OK\r\n" +
-			"\r\n",
-
-		Response{
-			Status:           "200 OK",
-			StatusCode:       200,
-			Proto:            "HTTP/1.0",
-			ProtoMajor:       1,
-			ProtoMinor:       0,
-			Request:          dummyReq("HEAD"),
-			Header:           Header{},
-			TransferEncoding: nil,
-			Close:            true,
-			ContentLength:    -1,
-		},
-
-		"",
-	},
-
-	// explicit Content-Length of 0.
-	{
-		"HTTP/1.1 200 OK\r\n" +
-			"Content-Length: 0\r\n" +
-			"\r\n",
-
-		Response{
-			Status:     "200 OK",
-			StatusCode: 200,
-			Proto:      "HTTP/1.1",
-			ProtoMajor: 1,
-			ProtoMinor: 1,
-			Request:    dummyReq("GET"),
-			Header: Header{
-				"Content-Length": {"0"},
-			},
-			Close:         false,
-			ContentLength: 0,
-		},
-
-		"",
-	},
-
-	// Status line without a Reason-Phrase, but trailing space.
-	// (permitted by RFC 2616)
-	{
-		"HTTP/1.0 303 \r\n\r\n",
-		Response{
-			Status:        "303 ",
-			StatusCode:    303,
-			Proto:         "HTTP/1.0",
-			ProtoMajor:    1,
-			ProtoMinor:    0,
-			Request:       dummyReq("GET"),
-			Header:        Header{},
-			Close:         true,
-			ContentLength: -1,
-		},
-
-		"",
-	},
-
-	// Status line without a Reason-Phrase, and no trailing space.
-	// (not permitted by RFC 2616, but we'll accept it anyway)
-	{
-		"HTTP/1.0 303\r\n\r\n",
-		Response{
-			Status:        "303 ",
-			StatusCode:    303,
-			Proto:         "HTTP/1.0",
-			ProtoMajor:    1,
-			ProtoMinor:    0,
-			Request:       dummyReq("GET"),
-			Header:        Header{},
-			Close:         true,
-			ContentLength: -1,
-		},
-
-		"",
-	},
-
-	// golang.org/issue/4767: don't special-case multipart/byteranges responses
-	{
-		`HTTP/1.1 206 Partial Content
-Connection: close
-Content-Type: multipart/byteranges; boundary=18a75608c8f47cef
-
-some body`,
-		Response{
-			Status:     "206 Partial Content",
-			StatusCode: 206,
-			Proto:      "HTTP/1.1",
-			ProtoMajor: 1,
-			ProtoMinor: 1,
-			Request:    dummyReq("GET"),
-			Header: Header{
-				"Content-Type": []string{"multipart/byteranges; boundary=18a75608c8f47cef"},
-			},
-			Close:         true,
-			ContentLength: -1,
-		},
-
-		"some body",
-	},
-
-	// Unchunked response without Content-Length, Request is nil
-	{
-		"HTTP/1.0 200 OK\r\n" +
-			"Connection: close\r\n" +
-			"\r\n" +
-			"Body here\n",
-
-		Response{
-			Status:     "200 OK",
-			StatusCode: 200,
-			Proto:      "HTTP/1.0",
-			ProtoMajor: 1,
-			ProtoMinor: 0,
-			Header: Header{
-				"Connection": {"close"}, // TODO(rsc): Delete?
-			},
-			Close:         true,
-			ContentLength: -1,
-		},
-
-		"Body here\n",
-	},
-}
-
-func TestReadResponse(t *testing.T) {
-	for i, tt := range respTests {
-		resp, err := ReadResponse(bufio.NewReader(strings.NewReader(tt.Raw)), tt.Resp.Request)
-		if err != nil {
-			t.Errorf("#%d: %v", i, err)
-			continue
-		}
-		rbody := resp.Body
-		resp.Body = nil
-		diff(t, fmt.Sprintf("#%d Response", i), resp, &tt.Resp)
-		var bout bytes.Buffer
-		if rbody != nil {
-			_, err = io.Copy(&bout, rbody)
-			if err != nil {
-				t.Errorf("#%d: %v", i, err)
-				continue
-			}
-			rbody.Close()
-		}
-		body := bout.String()
-		if body != tt.Body {
-			t.Errorf("#%d: Body = %q want %q", i, body, tt.Body)
-		}
-	}
-}
-
-func TestWriteResponse(t *testing.T) {
-	for i, tt := range respTests {
-		resp, err := ReadResponse(bufio.NewReader(strings.NewReader(tt.Raw)), tt.Resp.Request)
-		if err != nil {
-			t.Errorf("#%d: %v", i, err)
-			continue
-		}
-		err = resp.Write(ioutil.Discard)
-		if err != nil {
-			t.Errorf("#%d: %v", i, err)
-			continue
-		}
-	}
-}
-
-var readResponseCloseInMiddleTests = []struct {
-	chunked, compressed bool
-}{
-	{false, false},
-	{true, false},
-	{true, true},
-}
-
-// TestReadResponseCloseInMiddle tests that closing a body after
-// reading only part of its contents advances the read to the end of
-// the request, right up until the next request.
-func TestReadResponseCloseInMiddle(t *testing.T) {
-	for _, test := range readResponseCloseInMiddleTests {
-		fatalf := func(format string, args ...interface{}) {
-			args = append([]interface{}{test.chunked, test.compressed}, args...)
-			t.Fatalf("on test chunked=%v, compressed=%v: "+format, args...)
-		}
-		checkErr := func(err error, msg string) {
-			if err == nil {
-				return
-			}
-			fatalf(msg+": %v", err)
-		}
-		var buf bytes.Buffer
-		buf.WriteString("HTTP/1.1 200 OK\r\n")
-		if test.chunked {
-			buf.WriteString("Transfer-Encoding: chunked\r\n")
-		} else {
-			buf.WriteString("Content-Length: 1000000\r\n")
-		}
-		var wr io.Writer = &buf
-		if test.chunked {
-			wr = newChunkedWriter(wr)
-		}
-		if test.compressed {
-			buf.WriteString("Content-Encoding: gzip\r\n")
-			wr = gzip.NewWriter(wr)
-		}
-		buf.WriteString("\r\n")
-
-		chunk := bytes.Repeat([]byte{'x'}, 1000)
-		for i := 0; i < 1000; i++ {
-			if test.compressed {
-				// Otherwise this compresses too well.
-				_, err := io.ReadFull(rand.Reader, chunk)
-				checkErr(err, "rand.Reader ReadFull")
-			}
-			wr.Write(chunk)
-		}
-		if test.compressed {
-			err := wr.(*gzip.Writer).Close()
-			checkErr(err, "compressor close")
-		}
-		if test.chunked {
-			buf.WriteString("0\r\n\r\n")
-		}
-		buf.WriteString("Next Request Here")
-
-		bufr := bufio.NewReader(&buf)
-		resp, err := ReadResponse(bufr, dummyReq("GET"))
-		checkErr(err, "ReadResponse")
-		expectedLength := int64(-1)
-		if !test.chunked {
-			expectedLength = 1000000
-		}
-		if resp.ContentLength != expectedLength {
-			fatalf("expected response length %d, got %d", expectedLength, resp.ContentLength)
-		}
-		if resp.Body == nil {
-			fatalf("nil body")
-		}
-		if test.compressed {
-			gzReader, err := gzip.NewReader(resp.Body)
-			checkErr(err, "gzip.NewReader")
-			resp.Body = &readerAndCloser{gzReader, resp.Body}
-		}
-
-		rbuf := make([]byte, 2500)
-		n, err := io.ReadFull(resp.Body, rbuf)
-		checkErr(err, "2500 byte ReadFull")
-		if n != 2500 {
-			fatalf("ReadFull only read %d bytes", n)
-		}
-		if test.compressed == false && !bytes.Equal(bytes.Repeat([]byte{'x'}, 2500), rbuf) {
-			fatalf("ReadFull didn't read 2500 'x'; got %q", string(rbuf))
-		}
-		resp.Body.Close()
-
-		rest, err := ioutil.ReadAll(bufr)
-		checkErr(err, "ReadAll on remainder")
-		if e, g := "Next Request Here", string(rest); e != g {
-			g = regexp.MustCompile(`(xx+)`).ReplaceAllStringFunc(g, func(match string) string {
-				return fmt.Sprintf("x(repeated x%d)", len(match))
-			})
-			fatalf("remainder = %q, expected %q", g, e)
-		}
-	}
-}
-
-func diff(t *testing.T, prefix string, have, want interface{}) {
-	hv := reflect.ValueOf(have).Elem()
-	wv := reflect.ValueOf(want).Elem()
-	if hv.Type() != wv.Type() {
-		t.Errorf("%s: type mismatch %v want %v", prefix, hv.Type(), wv.Type())
-	}
-	for i := 0; i < hv.NumField(); i++ {
-		hf := hv.Field(i).Interface()
-		wf := wv.Field(i).Interface()
-		if !reflect.DeepEqual(hf, wf) {
-			t.Errorf("%s: %s = %v want %v", prefix, hv.Type().Field(i).Name, hf, wf)
-		}
-	}
-}
-
-type responseLocationTest struct {
-	location string // Response's Location header or ""
-	requrl   string // Response.Request.URL or ""
-	want     string
-	wantErr  error
-}
-
-var responseLocationTests = []responseLocationTest{
-	{"/foo", "http://bar.com/baz", "http://bar.com/foo", nil},
-	{"http://foo.com/", "http://bar.com/baz", "http://foo.com/", nil},
-	{"", "http://bar.com/baz", "", ErrNoLocation},
-}
-
-func TestLocationResponse(t *testing.T) {
-	for i, tt := range responseLocationTests {
-		res := new(Response)
-		res.Header = make(Header)
-		res.Header.Set("Location", tt.location)
-		if tt.requrl != "" {
-			res.Request = &Request{}
-			var err error
-			res.Request.URL, err = url.Parse(tt.requrl)
-			if err != nil {
-				t.Fatalf("bad test URL %q: %v", tt.requrl, err)
-			}
-		}
-
-		got, err := res.Location()
-		if tt.wantErr != nil {
-			if err == nil {
-				t.Errorf("%d. err=nil; want %q", i, tt.wantErr)
-				continue
-			}
-			if g, e := err.Error(), tt.wantErr.Error(); g != e {
-				t.Errorf("%d. err=%q; want %q", i, g, e)
-				continue
-			}
-			continue
-		}
-		if err != nil {
-			t.Errorf("%d. err=%q", i, err)
-			continue
-		}
-		if g, e := got.String(), tt.want; g != e {
-			t.Errorf("%d. Location=%q; want %q", i, g, e)
-		}
-	}
-}
-
-func TestResponseStatusStutter(t *testing.T) {
-	r := &Response{
-		Status:     "123 some status",
-		StatusCode: 123,
-		ProtoMajor: 1,
-		ProtoMinor: 3,
-	}
-	var buf bytes.Buffer
-	r.Write(&buf)
-	if strings.Contains(buf.String(), "123 123") {
-		t.Errorf("stutter in status: %s", buf.String())
-	}
-}
-
-func TestResponseContentLengthShortBody(t *testing.T) {
-	const shortBody = "Short body, not 123 bytes."
-	br := bufio.NewReader(strings.NewReader("HTTP/1.1 200 OK\r\n" +
-		"Content-Length: 123\r\n" +
-		"\r\n" +
-		shortBody))
-	res, err := ReadResponse(br, &Request{Method: "GET"})
-	if err != nil {
-		t.Fatal(err)
-	}
-	if res.ContentLength != 123 {
-		t.Fatalf("Content-Length = %d; want 123", res.ContentLength)
-	}
-	var buf bytes.Buffer
-	n, err := io.Copy(&buf, res.Body)
-	if n != int64(len(shortBody)) {
-		t.Errorf("Copied %d bytes; want %d, len(%q)", n, len(shortBody), shortBody)
-	}
-	if buf.String() != shortBody {
-		t.Errorf("Read body %q; want %q", buf.String(), shortBody)
-	}
-	if err != io.ErrUnexpectedEOF {
-		t.Errorf("io.Copy error = %#v; want io.ErrUnexpectedEOF", err)
-	}
-}
-
-func TestReadResponseUnexpectedEOF(t *testing.T) {
-	br := bufio.NewReader(strings.NewReader("HTTP/1.1 301 Moved Permanently\r\n" +
-		"Location: http://example.com"))
-	_, err := ReadResponse(br, nil)
-	if err != io.ErrUnexpectedEOF {
-		t.Errorf("ReadResponse = %v; want io.ErrUnexpectedEOF", err)
-	}
-}
-
-func TestNeedsSniff(t *testing.T) {
-	// needsSniff returns true with an empty response.
-	r := &response{}
-	if got, want := r.needsSniff(), true; got != want {
-		t.Errorf("needsSniff = %t; want %t", got, want)
-	}
-	// needsSniff returns false when Content-Type = nil.
-	r.handlerHeader = Header{"Content-Type": nil}
-	if got, want := r.needsSniff(), false; got != want {
-		t.Errorf("needsSniff empty Content-Type = %t; want %t", got, want)
-	}
-}
diff --git a/src/pkg/net/http/serve_test.go b/src/pkg/net/http/serve_test.go
deleted file mode 100644
index 9e4d226..0000000
--- a/src/pkg/net/http/serve_test.go
+++ /dev/null
@@ -1,2848 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// End-to-end serving tests
-
-package http_test
-
-import (
-	"bufio"
-	"bytes"
-	"crypto/tls"
-	"errors"
-	"fmt"
-	"io"
-	"io/ioutil"
-	"log"
-	"net"
-	. "net/http"
-	"net/http/httptest"
-	"net/http/httputil"
-	"net/url"
-	"os"
-	"os/exec"
-	"reflect"
-	"runtime"
-	"strconv"
-	"strings"
-	"sync"
-	"sync/atomic"
-	"syscall"
-	"testing"
-	"time"
-)
-
-type dummyAddr string
-type oneConnListener struct {
-	conn net.Conn
-}
-
-func (l *oneConnListener) Accept() (c net.Conn, err error) {
-	c = l.conn
-	if c == nil {
-		err = io.EOF
-		return
-	}
-	err = nil
-	l.conn = nil
-	return
-}
-
-func (l *oneConnListener) Close() error {
-	return nil
-}
-
-func (l *oneConnListener) Addr() net.Addr {
-	return dummyAddr("test-address")
-}
-
-func (a dummyAddr) Network() string {
-	return string(a)
-}
-
-func (a dummyAddr) String() string {
-	return string(a)
-}
-
-type noopConn struct{}
-
-func (noopConn) LocalAddr() net.Addr                { return dummyAddr("local-addr") }
-func (noopConn) RemoteAddr() net.Addr               { return dummyAddr("remote-addr") }
-func (noopConn) SetDeadline(t time.Time) error      { return nil }
-func (noopConn) SetReadDeadline(t time.Time) error  { return nil }
-func (noopConn) SetWriteDeadline(t time.Time) error { return nil }
-
-type rwTestConn struct {
-	io.Reader
-	io.Writer
-	noopConn
-
-	closeFunc func() error // called if non-nil
-	closec    chan bool    // else, if non-nil, send value to it on close
-}
-
-func (c *rwTestConn) Close() error {
-	if c.closeFunc != nil {
-		return c.closeFunc()
-	}
-	select {
-	case c.closec <- true:
-	default:
-	}
-	return nil
-}
-
-type testConn struct {
-	readBuf  bytes.Buffer
-	writeBuf bytes.Buffer
-	closec   chan bool // if non-nil, send value to it on close
-	noopConn
-}
-
-func (c *testConn) Read(b []byte) (int, error) {
-	return c.readBuf.Read(b)
-}
-
-func (c *testConn) Write(b []byte) (int, error) {
-	return c.writeBuf.Write(b)
-}
-
-func (c *testConn) Close() error {
-	select {
-	case c.closec <- true:
-	default:
-	}
-	return nil
-}
-
-// reqBytes treats req as a request (with \n delimiters) and returns it with \r\n delimiters,
-// ending in \r\n\r\n
-func reqBytes(req string) []byte {
-	return []byte(strings.Replace(strings.TrimSpace(req), "\n", "\r\n", -1) + "\r\n\r\n")
-}
-
-type handlerTest struct {
-	handler Handler
-}
-
-func newHandlerTest(h Handler) handlerTest {
-	return handlerTest{h}
-}
-
-func (ht handlerTest) rawResponse(req string) string {
-	reqb := reqBytes(req)
-	var output bytes.Buffer
-	conn := &rwTestConn{
-		Reader: bytes.NewReader(reqb),
-		Writer: &output,
-		closec: make(chan bool, 1),
-	}
-	ln := &oneConnListener{conn: conn}
-	go Serve(ln, ht.handler)
-	<-conn.closec
-	return output.String()
-}
-
-func TestConsumingBodyOnNextConn(t *testing.T) {
-	conn := new(testConn)
-	for i := 0; i < 2; i++ {
-		conn.readBuf.Write([]byte(
-			"POST / HTTP/1.1\r\n" +
-				"Host: test\r\n" +
-				"Content-Length: 11\r\n" +
-				"\r\n" +
-				"foo=1&bar=1"))
-	}
-
-	reqNum := 0
-	ch := make(chan *Request)
-	servech := make(chan error)
-	listener := &oneConnListener{conn}
-	handler := func(res ResponseWriter, req *Request) {
-		reqNum++
-		ch <- req
-	}
-
-	go func() {
-		servech <- Serve(listener, HandlerFunc(handler))
-	}()
-
-	var req *Request
-	req = <-ch
-	if req == nil {
-		t.Fatal("Got nil first request.")
-	}
-	if req.Method != "POST" {
-		t.Errorf("For request #1's method, got %q; expected %q",
-			req.Method, "POST")
-	}
-
-	req = <-ch
-	if req == nil {
-		t.Fatal("Got nil first request.")
-	}
-	if req.Method != "POST" {
-		t.Errorf("For request #2's method, got %q; expected %q",
-			req.Method, "POST")
-	}
-
-	if serveerr := <-servech; serveerr != io.EOF {
-		t.Errorf("Serve returned %q; expected EOF", serveerr)
-	}
-}
-
-type stringHandler string
-
-func (s stringHandler) ServeHTTP(w ResponseWriter, r *Request) {
-	w.Header().Set("Result", string(s))
-}
-
-var handlers = []struct {
-	pattern string
-	msg     string
-}{
-	{"/", "Default"},
-	{"/someDir/", "someDir"},
-	{"someHost.com/someDir/", "someHost.com/someDir"},
-}
-
-var vtests = []struct {
-	url      string
-	expected string
-}{
-	{"http://localhost/someDir/apage", "someDir"},
-	{"http://localhost/otherDir/apage", "Default"},
-	{"http://someHost.com/someDir/apage", "someHost.com/someDir"},
-	{"http://otherHost.com/someDir/apage", "someDir"},
-	{"http://otherHost.com/aDir/apage", "Default"},
-	// redirections for trees
-	{"http://localhost/someDir", "/someDir/"},
-	{"http://someHost.com/someDir", "/someDir/"},
-}
-
-func TestHostHandlers(t *testing.T) {
-	defer afterTest(t)
-	mux := NewServeMux()
-	for _, h := range handlers {
-		mux.Handle(h.pattern, stringHandler(h.msg))
-	}
-	ts := httptest.NewServer(mux)
-	defer ts.Close()
-
-	conn, err := net.Dial("tcp", ts.Listener.Addr().String())
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer conn.Close()
-	cc := httputil.NewClientConn(conn, nil)
-	for _, vt := range vtests {
-		var r *Response
-		var req Request
-		if req.URL, err = url.Parse(vt.url); err != nil {
-			t.Errorf("cannot parse url: %v", err)
-			continue
-		}
-		if err := cc.Write(&req); err != nil {
-			t.Errorf("writing request: %v", err)
-			continue
-		}
-		r, err := cc.Read(&req)
-		if err != nil {
-			t.Errorf("reading response: %v", err)
-			continue
-		}
-		switch r.StatusCode {
-		case StatusOK:
-			s := r.Header.Get("Result")
-			if s != vt.expected {
-				t.Errorf("Get(%q) = %q, want %q", vt.url, s, vt.expected)
-			}
-		case StatusMovedPermanently:
-			s := r.Header.Get("Location")
-			if s != vt.expected {
-				t.Errorf("Get(%q) = %q, want %q", vt.url, s, vt.expected)
-			}
-		default:
-			t.Errorf("Get(%q) unhandled status code %d", vt.url, r.StatusCode)
-		}
-	}
-}
-
-var serveMuxRegister = []struct {
-	pattern string
-	h       Handler
-}{
-	{"/dir/", serve(200)},
-	{"/search", serve(201)},
-	{"codesearch.google.com/search", serve(202)},
-	{"codesearch.google.com/", serve(203)},
-	{"example.com/", HandlerFunc(checkQueryStringHandler)},
-}
-
-// serve returns a handler that sends a response with the given code.
-func serve(code int) HandlerFunc {
-	return func(w ResponseWriter, r *Request) {
-		w.WriteHeader(code)
-	}
-}
-
-// checkQueryStringHandler checks if r.URL.RawQuery has the same value
-// as the URL excluding the scheme and the query string and sends 200
-// response code if it is, 500 otherwise.
-func checkQueryStringHandler(w ResponseWriter, r *Request) {
-	u := *r.URL
-	u.Scheme = "http"
-	u.Host = r.Host
-	u.RawQuery = ""
-	if "http://"+r.URL.RawQuery == u.String() {
-		w.WriteHeader(200)
-	} else {
-		w.WriteHeader(500)
-	}
-}
-
-var serveMuxTests = []struct {
-	method  string
-	host    string
-	path    string
-	code    int
-	pattern string
-}{
-	{"GET", "google.com", "/", 404, ""},
-	{"GET", "google.com", "/dir", 301, "/dir/"},
-	{"GET", "google.com", "/dir/", 200, "/dir/"},
-	{"GET", "google.com", "/dir/file", 200, "/dir/"},
-	{"GET", "google.com", "/search", 201, "/search"},
-	{"GET", "google.com", "/search/", 404, ""},
-	{"GET", "google.com", "/search/foo", 404, ""},
-	{"GET", "codesearch.google.com", "/search", 202, "codesearch.google.com/search"},
-	{"GET", "codesearch.google.com", "/search/", 203, "codesearch.google.com/"},
-	{"GET", "codesearch.google.com", "/search/foo", 203, "codesearch.google.com/"},
-	{"GET", "codesearch.google.com", "/", 203, "codesearch.google.com/"},
-	{"GET", "images.google.com", "/search", 201, "/search"},
-	{"GET", "images.google.com", "/search/", 404, ""},
-	{"GET", "images.google.com", "/search/foo", 404, ""},
-	{"GET", "google.com", "/../search", 301, "/search"},
-	{"GET", "google.com", "/dir/..", 301, ""},
-	{"GET", "google.com", "/dir/..", 301, ""},
-	{"GET", "google.com", "/dir/./file", 301, "/dir/"},
-
-	// The /foo -> /foo/ redirect applies to CONNECT requests
-	// but the path canonicalization does not.
-	{"CONNECT", "google.com", "/dir", 301, "/dir/"},
-	{"CONNECT", "google.com", "/../search", 404, ""},
-	{"CONNECT", "google.com", "/dir/..", 200, "/dir/"},
-	{"CONNECT", "google.com", "/dir/..", 200, "/dir/"},
-	{"CONNECT", "google.com", "/dir/./file", 200, "/dir/"},
-}
-
-func TestServeMuxHandler(t *testing.T) {
-	mux := NewServeMux()
-	for _, e := range serveMuxRegister {
-		mux.Handle(e.pattern, e.h)
-	}
-
-	for _, tt := range serveMuxTests {
-		r := &Request{
-			Method: tt.method,
-			Host:   tt.host,
-			URL: &url.URL{
-				Path: tt.path,
-			},
-		}
-		h, pattern := mux.Handler(r)
-		rr := httptest.NewRecorder()
-		h.ServeHTTP(rr, r)
-		if pattern != tt.pattern || rr.Code != tt.code {
-			t.Errorf("%s %s %s = %d, %q, want %d, %q", tt.method, tt.host, tt.path, rr.Code, pattern, tt.code, tt.pattern)
-		}
-	}
-}
-
-var serveMuxTests2 = []struct {
-	method  string
-	host    string
-	url     string
-	code    int
-	redirOk bool
-}{
-	{"GET", "google.com", "/", 404, false},
-	{"GET", "example.com", "/test/?example.com/test/", 200, false},
-	{"GET", "example.com", "test/?example.com/test/", 200, true},
-}
-
-// TestServeMuxHandlerRedirects tests that automatic redirects generated by
-// mux.Handler() shouldn't clear the request's query string.
-func TestServeMuxHandlerRedirects(t *testing.T) {
-	mux := NewServeMux()
-	for _, e := range serveMuxRegister {
-		mux.Handle(e.pattern, e.h)
-	}
-
-	for _, tt := range serveMuxTests2 {
-		tries := 1
-		turl := tt.url
-		for tries > 0 {
-			u, e := url.Parse(turl)
-			if e != nil {
-				t.Fatal(e)
-			}
-			r := &Request{
-				Method: tt.method,
-				Host:   tt.host,
-				URL:    u,
-			}
-			h, _ := mux.Handler(r)
-			rr := httptest.NewRecorder()
-			h.ServeHTTP(rr, r)
-			if rr.Code != 301 {
-				if rr.Code != tt.code {
-					t.Errorf("%s %s %s = %d, want %d", tt.method, tt.host, tt.url, rr.Code, tt.code)
-				}
-				break
-			}
-			if !tt.redirOk {
-				t.Errorf("%s %s %s, unexpected redirect", tt.method, tt.host, tt.url)
-				break
-			}
-			turl = rr.HeaderMap.Get("Location")
-			tries--
-		}
-		if tries < 0 {
-			t.Errorf("%s %s %s, too many redirects", tt.method, tt.host, tt.url)
-		}
-	}
-}
-
-// Tests for http://code.google.com/p/go/issues/detail?id=900
-func TestMuxRedirectLeadingSlashes(t *testing.T) {
-	paths := []string{"//foo.txt", "///foo.txt", "/../../foo.txt"}
-	for _, path := range paths {
-		req, err := ReadRequest(bufio.NewReader(strings.NewReader("GET " + path + " HTTP/1.1\r\nHost: test\r\n\r\n")))
-		if err != nil {
-			t.Errorf("%s", err)
-		}
-		mux := NewServeMux()
-		resp := httptest.NewRecorder()
-
-		mux.ServeHTTP(resp, req)
-
-		if loc, expected := resp.Header().Get("Location"), "/foo.txt"; loc != expected {
-			t.Errorf("Expected Location header set to %q; got %q", expected, loc)
-			return
-		}
-
-		if code, expected := resp.Code, StatusMovedPermanently; code != expected {
-			t.Errorf("Expected response code of StatusMovedPermanently; got %d", code)
-			return
-		}
-	}
-}
-
-func TestServerTimeouts(t *testing.T) {
-	if runtime.GOOS == "plan9" {
-		t.Skip("skipping test; see http://golang.org/issue/7237")
-	}
-	defer afterTest(t)
-	reqNum := 0
-	ts := httptest.NewUnstartedServer(HandlerFunc(func(res ResponseWriter, req *Request) {
-		reqNum++
-		fmt.Fprintf(res, "req=%d", reqNum)
-	}))
-	ts.Config.ReadTimeout = 250 * time.Millisecond
-	ts.Config.WriteTimeout = 250 * time.Millisecond
-	ts.Start()
-	defer ts.Close()
-
-	// Hit the HTTP server successfully.
-	tr := &Transport{DisableKeepAlives: true} // they interfere with this test
-	defer tr.CloseIdleConnections()
-	c := &Client{Transport: tr}
-	r, err := c.Get(ts.URL)
-	if err != nil {
-		t.Fatalf("http Get #1: %v", err)
-	}
-	got, _ := ioutil.ReadAll(r.Body)
-	expected := "req=1"
-	if string(got) != expected {
-		t.Errorf("Unexpected response for request #1; got %q; expected %q",
-			string(got), expected)
-	}
-
-	// Slow client that should timeout.
-	t1 := time.Now()
-	conn, err := net.Dial("tcp", ts.Listener.Addr().String())
-	if err != nil {
-		t.Fatalf("Dial: %v", err)
-	}
-	buf := make([]byte, 1)
-	n, err := conn.Read(buf)
-	latency := time.Since(t1)
-	if n != 0 || err != io.EOF {
-		t.Errorf("Read = %v, %v, wanted %v, %v", n, err, 0, io.EOF)
-	}
-	if latency < 200*time.Millisecond /* fudge from 250 ms above */ {
-		t.Errorf("got EOF after %s, want >= %s", latency, 200*time.Millisecond)
-	}
-
-	// Hit the HTTP server successfully again, verifying that the
-	// previous slow connection didn't run our handler.  (that we
-	// get "req=2", not "req=3")
-	r, err = Get(ts.URL)
-	if err != nil {
-		t.Fatalf("http Get #2: %v", err)
-	}
-	got, _ = ioutil.ReadAll(r.Body)
-	expected = "req=2"
-	if string(got) != expected {
-		t.Errorf("Get #2 got %q, want %q", string(got), expected)
-	}
-
-	if !testing.Short() {
-		conn, err := net.Dial("tcp", ts.Listener.Addr().String())
-		if err != nil {
-			t.Fatalf("Dial: %v", err)
-		}
-		defer conn.Close()
-		go io.Copy(ioutil.Discard, conn)
-		for i := 0; i < 5; i++ {
-			_, err := conn.Write([]byte("GET / HTTP/1.1\r\nHost: foo\r\n\r\n"))
-			if err != nil {
-				t.Fatalf("on write %d: %v", i, err)
-			}
-			time.Sleep(ts.Config.ReadTimeout / 2)
-		}
-	}
-}
-
-// golang.org/issue/4741 -- setting only a write timeout that triggers
-// shouldn't cause a handler to block forever on reads (next HTTP
-// request) that will never happen.
-func TestOnlyWriteTimeout(t *testing.T) {
-	if runtime.GOOS == "plan9" {
-		t.Skip("skipping test; see http://golang.org/issue/7237")
-	}
-	defer afterTest(t)
-	var conn net.Conn
-	var afterTimeoutErrc = make(chan error, 1)
-	ts := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, req *Request) {
-		buf := make([]byte, 512<<10)
-		_, err := w.Write(buf)
-		if err != nil {
-			t.Errorf("handler Write error: %v", err)
-			return
-		}
-		conn.SetWriteDeadline(time.Now().Add(-30 * time.Second))
-		_, err = w.Write(buf)
-		afterTimeoutErrc <- err
-	}))
-	ts.Listener = trackLastConnListener{ts.Listener, &conn}
-	ts.Start()
-	defer ts.Close()
-
-	tr := &Transport{DisableKeepAlives: false}
-	defer tr.CloseIdleConnections()
-	c := &Client{Transport: tr}
-
-	errc := make(chan error)
-	go func() {
-		res, err := c.Get(ts.URL)
-		if err != nil {
-			errc <- err
-			return
-		}
-		_, err = io.Copy(ioutil.Discard, res.Body)
-		errc <- err
-	}()
-	select {
-	case err := <-errc:
-		if err == nil {
-			t.Errorf("expected an error from Get request")
-		}
-	case <-time.After(5 * time.Second):
-		t.Fatal("timeout waiting for Get error")
-	}
-	if err := <-afterTimeoutErrc; err == nil {
-		t.Error("expected write error after timeout")
-	}
-}
-
-// trackLastConnListener tracks the last net.Conn that was accepted.
-type trackLastConnListener struct {
-	net.Listener
-	last *net.Conn // destination
-}
-
-func (l trackLastConnListener) Accept() (c net.Conn, err error) {
-	c, err = l.Listener.Accept()
-	*l.last = c
-	return
-}
-
-// TestIdentityResponse verifies that a handler can unset
-func TestIdentityResponse(t *testing.T) {
-	defer afterTest(t)
-	handler := HandlerFunc(func(rw ResponseWriter, req *Request) {
-		rw.Header().Set("Content-Length", "3")
-		rw.Header().Set("Transfer-Encoding", req.FormValue("te"))
-		switch {
-		case req.FormValue("overwrite") == "1":
-			_, err := rw.Write([]byte("foo TOO LONG"))
-			if err != ErrContentLength {
-				t.Errorf("expected ErrContentLength; got %v", err)
-			}
-		case req.FormValue("underwrite") == "1":
-			rw.Header().Set("Content-Length", "500")
-			rw.Write([]byte("too short"))
-		default:
-			rw.Write([]byte("foo"))
-		}
-	})
-
-	ts := httptest.NewServer(handler)
-	defer ts.Close()
-
-	// Note: this relies on the assumption (which is true) that
-	// Get sends HTTP/1.1 or greater requests.  Otherwise the
-	// server wouldn't have the choice to send back chunked
-	// responses.
-	for _, te := range []string{"", "identity"} {
-		url := ts.URL + "/?te=" + te
-		res, err := Get(url)
-		if err != nil {
-			t.Fatalf("error with Get of %s: %v", url, err)
-		}
-		if cl, expected := res.ContentLength, int64(3); cl != expected {
-			t.Errorf("for %s expected res.ContentLength of %d; got %d", url, expected, cl)
-		}
-		if cl, expected := res.Header.Get("Content-Length"), "3"; cl != expected {
-			t.Errorf("for %s expected Content-Length header of %q; got %q", url, expected, cl)
-		}
-		if tl, expected := len(res.TransferEncoding), 0; tl != expected {
-			t.Errorf("for %s expected len(res.TransferEncoding) of %d; got %d (%v)",
-				url, expected, tl, res.TransferEncoding)
-		}
-		res.Body.Close()
-	}
-
-	// Verify that ErrContentLength is returned
-	url := ts.URL + "/?overwrite=1"
-	res, err := Get(url)
-	if err != nil {
-		t.Fatalf("error with Get of %s: %v", url, err)
-	}
-	res.Body.Close()
-
-	// Verify that the connection is closed when the declared Content-Length
-	// is larger than what the handler wrote.
-	conn, err := net.Dial("tcp", ts.Listener.Addr().String())
-	if err != nil {
-		t.Fatalf("error dialing: %v", err)
-	}
-	_, err = conn.Write([]byte("GET /?underwrite=1 HTTP/1.1\r\nHost: foo\r\n\r\n"))
-	if err != nil {
-		t.Fatalf("error writing: %v", err)
-	}
-
-	// The ReadAll will hang for a failing test, so use a Timer to
-	// fail explicitly.
-	goTimeout(t, 2*time.Second, func() {
-		got, _ := ioutil.ReadAll(conn)
-		expectedSuffix := "\r\n\r\ntoo short"
-		if !strings.HasSuffix(string(got), expectedSuffix) {
-			t.Errorf("Expected output to end with %q; got response body %q",
-				expectedSuffix, string(got))
-		}
-	})
-}
-
-func testTCPConnectionCloses(t *testing.T, req string, h Handler) {
-	defer afterTest(t)
-	s := httptest.NewServer(h)
-	defer s.Close()
-
-	conn, err := net.Dial("tcp", s.Listener.Addr().String())
-	if err != nil {
-		t.Fatal("dial error:", err)
-	}
-	defer conn.Close()
-
-	_, err = fmt.Fprint(conn, req)
-	if err != nil {
-		t.Fatal("print error:", err)
-	}
-
-	r := bufio.NewReader(conn)
-	res, err := ReadResponse(r, &Request{Method: "GET"})
-	if err != nil {
-		t.Fatal("ReadResponse error:", err)
-	}
-
-	didReadAll := make(chan bool, 1)
-	go func() {
-		select {
-		case <-time.After(5 * time.Second):
-			t.Error("body not closed after 5s")
-			return
-		case <-didReadAll:
-		}
-	}()
-
-	_, err = ioutil.ReadAll(r)
-	if err != nil {
-		t.Fatal("read error:", err)
-	}
-	didReadAll <- true
-
-	if !res.Close {
-		t.Errorf("Response.Close = false; want true")
-	}
-}
-
-// TestServeHTTP10Close verifies that HTTP/1.0 requests won't be kept alive.
-func TestServeHTTP10Close(t *testing.T) {
-	testTCPConnectionCloses(t, "GET / HTTP/1.0\r\n\r\n", HandlerFunc(func(w ResponseWriter, r *Request) {
-		ServeFile(w, r, "testdata/file")
-	}))
-}
-
-// TestClientCanClose verifies that clients can also force a connection to close.
-func TestClientCanClose(t *testing.T) {
-	testTCPConnectionCloses(t, "GET / HTTP/1.1\r\nConnection: close\r\n\r\n", HandlerFunc(func(w ResponseWriter, r *Request) {
-		// Nothing.
-	}))
-}
-
-// TestHandlersCanSetConnectionClose verifies that handlers can force a connection to close,
-// even for HTTP/1.1 requests.
-func TestHandlersCanSetConnectionClose11(t *testing.T) {
-	testTCPConnectionCloses(t, "GET / HTTP/1.1\r\n\r\n", HandlerFunc(func(w ResponseWriter, r *Request) {
-		w.Header().Set("Connection", "close")
-	}))
-}
-
-func TestHandlersCanSetConnectionClose10(t *testing.T) {
-	testTCPConnectionCloses(t, "GET / HTTP/1.0\r\nConnection: keep-alive\r\n\r\n", HandlerFunc(func(w ResponseWriter, r *Request) {
-		w.Header().Set("Connection", "close")
-	}))
-}
-
-func TestSetsRemoteAddr(t *testing.T) {
-	defer afterTest(t)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
-		fmt.Fprintf(w, "%s", r.RemoteAddr)
-	}))
-	defer ts.Close()
-
-	res, err := Get(ts.URL)
-	if err != nil {
-		t.Fatalf("Get error: %v", err)
-	}
-	body, err := ioutil.ReadAll(res.Body)
-	if err != nil {
-		t.Fatalf("ReadAll error: %v", err)
-	}
-	ip := string(body)
-	if !strings.HasPrefix(ip, "127.0.0.1:") && !strings.HasPrefix(ip, "[::1]:") {
-		t.Fatalf("Expected local addr; got %q", ip)
-	}
-}
-
-func TestChunkedResponseHeaders(t *testing.T) {
-	defer afterTest(t)
-	log.SetOutput(ioutil.Discard) // is noisy otherwise
-	defer log.SetOutput(os.Stderr)
-
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
-		w.Header().Set("Content-Length", "intentional gibberish") // we check that this is deleted
-		w.(Flusher).Flush()
-		fmt.Fprintf(w, "I am a chunked response.")
-	}))
-	defer ts.Close()
-
-	res, err := Get(ts.URL)
-	if err != nil {
-		t.Fatalf("Get error: %v", err)
-	}
-	defer res.Body.Close()
-	if g, e := res.ContentLength, int64(-1); g != e {
-		t.Errorf("expected ContentLength of %d; got %d", e, g)
-	}
-	if g, e := res.TransferEncoding, []string{"chunked"}; !reflect.DeepEqual(g, e) {
-		t.Errorf("expected TransferEncoding of %v; got %v", e, g)
-	}
-	if _, haveCL := res.Header["Content-Length"]; haveCL {
-		t.Errorf("Unexpected Content-Length")
-	}
-}
-
-// Test304Responses verifies that 304s don't declare that they're
-// chunking in their response headers and aren't allowed to produce
-// output.
-func Test304Responses(t *testing.T) {
-	defer afterTest(t)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
-		w.WriteHeader(StatusNotModified)
-		_, err := w.Write([]byte("illegal body"))
-		if err != ErrBodyNotAllowed {
-			t.Errorf("on Write, expected ErrBodyNotAllowed, got %v", err)
-		}
-	}))
-	defer ts.Close()
-	res, err := Get(ts.URL)
-	if err != nil {
-		t.Error(err)
-	}
-	if len(res.TransferEncoding) > 0 {
-		t.Errorf("expected no TransferEncoding; got %v", res.TransferEncoding)
-	}
-	body, err := ioutil.ReadAll(res.Body)
-	if err != nil {
-		t.Error(err)
-	}
-	if len(body) > 0 {
-		t.Errorf("got unexpected body %q", string(body))
-	}
-}
-
-// TestHeadResponses verifies that all MIME type sniffing and Content-Length
-// counting of GET requests also happens on HEAD requests.
-func TestHeadResponses(t *testing.T) {
-	defer afterTest(t)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
-		_, err := w.Write([]byte("<html>"))
-		if err != nil {
-			t.Errorf("ResponseWriter.Write: %v", err)
-		}
-
-		// Also exercise the ReaderFrom path
-		_, err = io.Copy(w, strings.NewReader("789a"))
-		if err != nil {
-			t.Errorf("Copy(ResponseWriter, ...): %v", err)
-		}
-	}))
-	defer ts.Close()
-	res, err := Head(ts.URL)
-	if err != nil {
-		t.Error(err)
-	}
-	if len(res.TransferEncoding) > 0 {
-		t.Errorf("expected no TransferEncoding; got %v", res.TransferEncoding)
-	}
-	if ct := res.Header.Get("Content-Type"); ct != "text/html; charset=utf-8" {
-		t.Errorf("Content-Type: %q; want text/html; charset=utf-8", ct)
-	}
-	if v := res.ContentLength; v != 10 {
-		t.Errorf("Content-Length: %d; want 10", v)
-	}
-	body, err := ioutil.ReadAll(res.Body)
-	if err != nil {
-		t.Error(err)
-	}
-	if len(body) > 0 {
-		t.Errorf("got unexpected body %q", string(body))
-	}
-}
-
-func TestTLSHandshakeTimeout(t *testing.T) {
-	if runtime.GOOS == "plan9" {
-		t.Skip("skipping test; see http://golang.org/issue/7237")
-	}
-	defer afterTest(t)
-	ts := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, r *Request) {}))
-	errc := make(chanWriter, 10) // but only expecting 1
-	ts.Config.ReadTimeout = 250 * time.Millisecond
-	ts.Config.ErrorLog = log.New(errc, "", 0)
-	ts.StartTLS()
-	defer ts.Close()
-	conn, err := net.Dial("tcp", ts.Listener.Addr().String())
-	if err != nil {
-		t.Fatalf("Dial: %v", err)
-	}
-	defer conn.Close()
-	goTimeout(t, 10*time.Second, func() {
-		var buf [1]byte
-		n, err := conn.Read(buf[:])
-		if err == nil || n != 0 {
-			t.Errorf("Read = %d, %v; want an error and no bytes", n, err)
-		}
-	})
-	select {
-	case v := <-errc:
-		if !strings.Contains(v, "timeout") && !strings.Contains(v, "TLS handshake") {
-			t.Errorf("expected a TLS handshake timeout error; got %q", v)
-		}
-	case <-time.After(5 * time.Second):
-		t.Errorf("timeout waiting for logged error")
-	}
-}
-
-func TestTLSServer(t *testing.T) {
-	defer afterTest(t)
-	ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) {
-		if r.TLS != nil {
-			w.Header().Set("X-TLS-Set", "true")
-			if r.TLS.HandshakeComplete {
-				w.Header().Set("X-TLS-HandshakeComplete", "true")
-			}
-		}
-	}))
-	ts.Config.ErrorLog = log.New(ioutil.Discard, "", 0)
-	defer ts.Close()
-
-	// Connect an idle TCP connection to this server before we run
-	// our real tests.  This idle connection used to block forever
-	// in the TLS handshake, preventing future connections from
-	// being accepted. It may prevent future accidental blocking
-	// in newConn.
-	idleConn, err := net.Dial("tcp", ts.Listener.Addr().String())
-	if err != nil {
-		t.Fatalf("Dial: %v", err)
-	}
-	defer idleConn.Close()
-	goTimeout(t, 10*time.Second, func() {
-		if !strings.HasPrefix(ts.URL, "https://") {
-			t.Errorf("expected test TLS server to start with https://, got %q", ts.URL)
-			return
-		}
-		noVerifyTransport := &Transport{
-			TLSClientConfig: &tls.Config{
-				InsecureSkipVerify: true,
-			},
-		}
-		client := &Client{Transport: noVerifyTransport}
-		res, err := client.Get(ts.URL)
-		if err != nil {
-			t.Error(err)
-			return
-		}
-		if res == nil {
-			t.Errorf("got nil Response")
-			return
-		}
-		defer res.Body.Close()
-		if res.Header.Get("X-TLS-Set") != "true" {
-			t.Errorf("expected X-TLS-Set response header")
-			return
-		}
-		if res.Header.Get("X-TLS-HandshakeComplete") != "true" {
-			t.Errorf("expected X-TLS-HandshakeComplete header")
-		}
-	})
-}
-
-type serverExpectTest struct {
-	contentLength    int // of request body
-	chunked          bool
-	expectation      string // e.g. "100-continue"
-	readBody         bool   // whether handler should read the body (if false, sends StatusUnauthorized)
-	expectedResponse string // expected substring in first line of http response
-}
-
-func expectTest(contentLength int, expectation string, readBody bool, expectedResponse string) serverExpectTest {
-	return serverExpectTest{
-		contentLength:    contentLength,
-		expectation:      expectation,
-		readBody:         readBody,
-		expectedResponse: expectedResponse,
-	}
-}
-
-var serverExpectTests = []serverExpectTest{
-	// Normal 100-continues, case-insensitive.
-	expectTest(100, "100-continue", true, "100 Continue"),
-	expectTest(100, "100-cOntInUE", true, "100 Continue"),
-
-	// No 100-continue.
-	expectTest(100, "", true, "200 OK"),
-
-	// 100-continue but requesting client to deny us,
-	// so it never reads the body.
-	expectTest(100, "100-continue", false, "401 Unauthorized"),
-	// Likewise without 100-continue:
-	expectTest(100, "", false, "401 Unauthorized"),
-
-	// Non-standard expectations are failures
-	expectTest(0, "a-pony", false, "417 Expectation Failed"),
-
-	// Expect-100 requested but no body (is apparently okay: Issue 7625)
-	expectTest(0, "100-continue", true, "200 OK"),
-	// Expect-100 requested but handler doesn't read the body
-	expectTest(0, "100-continue", false, "401 Unauthorized"),
-	// Expect-100 continue with no body, but a chunked body.
-	{
-		expectation:      "100-continue",
-		readBody:         true,
-		chunked:          true,
-		expectedResponse: "100 Continue",
-	},
-}
-
-// Tests that the server responds to the "Expect" request header
-// correctly.
-func TestServerExpect(t *testing.T) {
-	defer afterTest(t)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
-		// Note using r.FormValue("readbody") because for POST
-		// requests that would read from r.Body, which we only
-		// conditionally want to do.
-		if strings.Contains(r.URL.RawQuery, "readbody=true") {
-			ioutil.ReadAll(r.Body)
-			w.Write([]byte("Hi"))
-		} else {
-			w.WriteHeader(StatusUnauthorized)
-		}
-	}))
-	defer ts.Close()
-
-	runTest := func(test serverExpectTest) {
-		conn, err := net.Dial("tcp", ts.Listener.Addr().String())
-		if err != nil {
-			t.Fatalf("Dial: %v", err)
-		}
-		defer conn.Close()
-
-		// Only send the body immediately if we're acting like an HTTP client
-		// that doesn't send 100-continue expectations.
-		writeBody := test.contentLength != 0 && strings.ToLower(test.expectation) != "100-continue"
-
-		go func() {
-			contentLen := fmt.Sprintf("Content-Length: %d", test.contentLength)
-			if test.chunked {
-				contentLen = "Transfer-Encoding: chunked"
-			}
-			_, err := fmt.Fprintf(conn, "POST /?readbody=%v HTTP/1.1\r\n"+
-				"Connection: close\r\n"+
-				"%s\r\n"+
-				"Expect: %s\r\nHost: foo\r\n\r\n",
-				test.readBody, contentLen, test.expectation)
-			if err != nil {
-				t.Errorf("On test %#v, error writing request headers: %v", test, err)
-				return
-			}
-			if writeBody {
-				var targ io.WriteCloser = struct {
-					io.Writer
-					io.Closer
-				}{
-					conn,
-					ioutil.NopCloser(nil),
-				}
-				if test.chunked {
-					targ = httputil.NewChunkedWriter(conn)
-				}
-				body := strings.Repeat("A", test.contentLength)
-				_, err = fmt.Fprint(targ, body)
-				if err == nil {
-					err = targ.Close()
-				}
-				if err != nil {
-					if !test.readBody {
-						// Server likely already hung up on us.
-						// See larger comment below.
-						t.Logf("On test %#v, acceptable error writing request body: %v", test, err)
-						return
-					}
-					t.Errorf("On test %#v, error writing request body: %v", test, err)
-				}
-			}
-		}()
-		bufr := bufio.NewReader(conn)
-		line, err := bufr.ReadString('\n')
-		if err != nil {
-			if writeBody && !test.readBody {
-				// This is an acceptable failure due to a possible TCP race:
-				// We were still writing data and the server hung up on us. A TCP
-				// implementation may send a RST if our request body data was known
-				// to be lost, which may trigger our reads to fail.
-				// See RFC 1122 page 88.
-				t.Logf("On test %#v, acceptable error from ReadString: %v", test, err)
-				return
-			}
-			t.Fatalf("On test %#v, ReadString: %v", test, err)
-		}
-		if !strings.Contains(line, test.expectedResponse) {
-			t.Errorf("On test %#v, got first line = %q; want %q", test, line, test.expectedResponse)
-		}
-	}
-
-	for _, test := range serverExpectTests {
-		runTest(test)
-	}
-}
-
-// Under a ~256KB (maxPostHandlerReadBytes) threshold, the server
-// should consume client request bodies that a handler didn't read.
-func TestServerUnreadRequestBodyLittle(t *testing.T) {
-	conn := new(testConn)
-	body := strings.Repeat("x", 100<<10)
-	conn.readBuf.Write([]byte(fmt.Sprintf(
-		"POST / HTTP/1.1\r\n"+
-			"Host: test\r\n"+
-			"Content-Length: %d\r\n"+
-			"\r\n", len(body))))
-	conn.readBuf.Write([]byte(body))
-
-	done := make(chan bool)
-
-	ls := &oneConnListener{conn}
-	go Serve(ls, HandlerFunc(func(rw ResponseWriter, req *Request) {
-		defer close(done)
-		if conn.readBuf.Len() < len(body)/2 {
-			t.Errorf("on request, read buffer length is %d; expected about 100 KB", conn.readBuf.Len())
-		}
-		rw.WriteHeader(200)
-		rw.(Flusher).Flush()
-		if g, e := conn.readBuf.Len(), 0; g != e {
-			t.Errorf("after WriteHeader, read buffer length is %d; want %d", g, e)
-		}
-		if c := rw.Header().Get("Connection"); c != "" {
-			t.Errorf(`Connection header = %q; want ""`, c)
-		}
-	}))
-	<-done
-}
-
-// Over a ~256KB (maxPostHandlerReadBytes) threshold, the server
-// should ignore client request bodies that a handler didn't read
-// and close the connection.
-func TestServerUnreadRequestBodyLarge(t *testing.T) {
-	conn := new(testConn)
-	body := strings.Repeat("x", 1<<20)
-	conn.readBuf.Write([]byte(fmt.Sprintf(
-		"POST / HTTP/1.1\r\n"+
-			"Host: test\r\n"+
-			"Content-Length: %d\r\n"+
-			"\r\n", len(body))))
-	conn.readBuf.Write([]byte(body))
-	conn.closec = make(chan bool, 1)
-
-	ls := &oneConnListener{conn}
-	go Serve(ls, HandlerFunc(func(rw ResponseWriter, req *Request) {
-		if conn.readBuf.Len() < len(body)/2 {
-			t.Errorf("on request, read buffer length is %d; expected about 1MB", conn.readBuf.Len())
-		}
-		rw.WriteHeader(200)
-		rw.(Flusher).Flush()
-		if conn.readBuf.Len() < len(body)/2 {
-			t.Errorf("post-WriteHeader, read buffer length is %d; expected about 1MB", conn.readBuf.Len())
-		}
-	}))
-	<-conn.closec
-
-	if res := conn.writeBuf.String(); !strings.Contains(res, "Connection: close") {
-		t.Errorf("Expected a Connection: close header; got response: %s", res)
-	}
-}
-
-func TestTimeoutHandler(t *testing.T) {
-	defer afterTest(t)
-	sendHi := make(chan bool, 1)
-	writeErrors := make(chan error, 1)
-	sayHi := HandlerFunc(func(w ResponseWriter, r *Request) {
-		<-sendHi
-		_, werr := w.Write([]byte("hi"))
-		writeErrors <- werr
-	})
-	timeout := make(chan time.Time, 1) // write to this to force timeouts
-	ts := httptest.NewServer(NewTestTimeoutHandler(sayHi, timeout))
-	defer ts.Close()
-
-	// Succeed without timing out:
-	sendHi <- true
-	res, err := Get(ts.URL)
-	if err != nil {
-		t.Error(err)
-	}
-	if g, e := res.StatusCode, StatusOK; g != e {
-		t.Errorf("got res.StatusCode %d; expected %d", g, e)
-	}
-	body, _ := ioutil.ReadAll(res.Body)
-	if g, e := string(body), "hi"; g != e {
-		t.Errorf("got body %q; expected %q", g, e)
-	}
-	if g := <-writeErrors; g != nil {
-		t.Errorf("got unexpected Write error on first request: %v", g)
-	}
-
-	// Times out:
-	timeout <- time.Time{}
-	res, err = Get(ts.URL)
-	if err != nil {
-		t.Error(err)
-	}
-	if g, e := res.StatusCode, StatusServiceUnavailable; g != e {
-		t.Errorf("got res.StatusCode %d; expected %d", g, e)
-	}
-	body, _ = ioutil.ReadAll(res.Body)
-	if !strings.Contains(string(body), "<title>Timeout</title>") {
-		t.Errorf("expected timeout body; got %q", string(body))
-	}
-
-	// Now make the previously-timed out handler speak again,
-	// which verifies the panic is handled:
-	sendHi <- true
-	if g, e := <-writeErrors, ErrHandlerTimeout; g != e {
-		t.Errorf("expected Write error of %v; got %v", e, g)
-	}
-}
-
-// Verifies we don't path.Clean() on the wrong parts in redirects.
-func TestRedirectMunging(t *testing.T) {
-	req, _ := NewRequest("GET", "http://example.com/", nil)
-
-	resp := httptest.NewRecorder()
-	Redirect(resp, req, "/foo?next=http://bar.com/", 302)
-	if g, e := resp.Header().Get("Location"), "/foo?next=http://bar.com/"; g != e {
-		t.Errorf("Location header was %q; want %q", g, e)
-	}
-
-	resp = httptest.NewRecorder()
-	Redirect(resp, req, "http://localhost:8080/_ah/login?continue=http://localhost:8080/", 302)
-	if g, e := resp.Header().Get("Location"), "http://localhost:8080/_ah/login?continue=http://localhost:8080/"; g != e {
-		t.Errorf("Location header was %q; want %q", g, e)
-	}
-}
-
-func TestRedirectBadPath(t *testing.T) {
-	// This used to crash. It's not valid input (bad path), but it
-	// shouldn't crash.
-	rr := httptest.NewRecorder()
-	req := &Request{
-		Method: "GET",
-		URL: &url.URL{
-			Scheme: "http",
-			Path:   "not-empty-but-no-leading-slash", // bogus
-		},
-	}
-	Redirect(rr, req, "", 304)
-	if rr.Code != 304 {
-		t.Errorf("Code = %d; want 304", rr.Code)
-	}
-}
-
-// TestZeroLengthPostAndResponse exercises an optimization done by the Transport:
-// when there is no body (either because the method doesn't permit a body, or an
-// explicit Content-Length of zero is present), then the transport can re-use the
-// connection immediately. But when it re-uses the connection, it typically closes
-// the previous request's body, which is not optimal for zero-lengthed bodies,
-// as the client would then see http.ErrBodyReadAfterClose and not 0, io.EOF.
-func TestZeroLengthPostAndResponse(t *testing.T) {
-	defer afterTest(t)
-	ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, r *Request) {
-		all, err := ioutil.ReadAll(r.Body)
-		if err != nil {
-			t.Fatalf("handler ReadAll: %v", err)
-		}
-		if len(all) != 0 {
-			t.Errorf("handler got %d bytes; expected 0", len(all))
-		}
-		rw.Header().Set("Content-Length", "0")
-	}))
-	defer ts.Close()
-
-	req, err := NewRequest("POST", ts.URL, strings.NewReader(""))
-	if err != nil {
-		t.Fatal(err)
-	}
-	req.ContentLength = 0
-
-	var resp [5]*Response
-	for i := range resp {
-		resp[i], err = DefaultClient.Do(req)
-		if err != nil {
-			t.Fatalf("client post #%d: %v", i, err)
-		}
-	}
-
-	for i := range resp {
-		all, err := ioutil.ReadAll(resp[i].Body)
-		if err != nil {
-			t.Fatalf("req #%d: client ReadAll: %v", i, err)
-		}
-		if len(all) != 0 {
-			t.Errorf("req #%d: client got %d bytes; expected 0", i, len(all))
-		}
-	}
-}
-
-func TestHandlerPanicNil(t *testing.T) {
-	testHandlerPanic(t, false, nil)
-}
-
-func TestHandlerPanic(t *testing.T) {
-	testHandlerPanic(t, false, "intentional death for testing")
-}
-
-func TestHandlerPanicWithHijack(t *testing.T) {
-	testHandlerPanic(t, true, "intentional death for testing")
-}
-
-func testHandlerPanic(t *testing.T, withHijack bool, panicValue interface{}) {
-	defer afterTest(t)
-	// Unlike the other tests that set the log output to ioutil.Discard
-	// to quiet the output, this test uses a pipe.  The pipe serves three
-	// purposes:
-	//
-	//   1) The log.Print from the http server (generated by the caught
-	//      panic) will go to the pipe instead of stderr, making the
-	//      output quiet.
-	//
-	//   2) We read from the pipe to verify that the handler
-	//      actually caught the panic and logged something.
-	//
-	//   3) The blocking Read call prevents this TestHandlerPanic
-	//      function from exiting before the HTTP server handler
-	//      finishes crashing. If this text function exited too
-	//      early (and its defer log.SetOutput(os.Stderr) ran),
-	//      then the crash output could spill into the next test.
-	pr, pw := io.Pipe()
-	log.SetOutput(pw)
-	defer log.SetOutput(os.Stderr)
-	defer pw.Close()
-
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
-		if withHijack {
-			rwc, _, err := w.(Hijacker).Hijack()
-			if err != nil {
-				t.Logf("unexpected error: %v", err)
-			}
-			defer rwc.Close()
-		}
-		panic(panicValue)
-	}))
-	defer ts.Close()
-
-	// Do a blocking read on the log output pipe so its logging
-	// doesn't bleed into the next test.  But wait only 5 seconds
-	// for it.
-	done := make(chan bool, 1)
-	go func() {
-		buf := make([]byte, 4<<10)
-		_, err := pr.Read(buf)
-		pr.Close()
-		if err != nil && err != io.EOF {
-			t.Error(err)
-		}
-		done <- true
-	}()
-
-	_, err := Get(ts.URL)
-	if err == nil {
-		t.Logf("expected an error")
-	}
-
-	if panicValue == nil {
-		return
-	}
-
-	select {
-	case <-done:
-		return
-	case <-time.After(5 * time.Second):
-		t.Fatal("expected server handler to log an error")
-	}
-}
-
-func TestNoDate(t *testing.T) {
-	defer afterTest(t)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
-		w.Header()["Date"] = nil
-	}))
-	defer ts.Close()
-	res, err := Get(ts.URL)
-	if err != nil {
-		t.Fatal(err)
-	}
-	_, present := res.Header["Date"]
-	if present {
-		t.Fatalf("Expected no Date header; got %v", res.Header["Date"])
-	}
-}
-
-func TestStripPrefix(t *testing.T) {
-	defer afterTest(t)
-	h := HandlerFunc(func(w ResponseWriter, r *Request) {
-		w.Header().Set("X-Path", r.URL.Path)
-	})
-	ts := httptest.NewServer(StripPrefix("/foo", h))
-	defer ts.Close()
-
-	res, err := Get(ts.URL + "/foo/bar")
-	if err != nil {
-		t.Fatal(err)
-	}
-	if g, e := res.Header.Get("X-Path"), "/bar"; g != e {
-		t.Errorf("test 1: got %s, want %s", g, e)
-	}
-	res.Body.Close()
-
-	res, err = Get(ts.URL + "/bar")
-	if err != nil {
-		t.Fatal(err)
-	}
-	if g, e := res.StatusCode, 404; g != e {
-		t.Errorf("test 2: got status %v, want %v", g, e)
-	}
-	res.Body.Close()
-}
-
-func TestRequestLimit(t *testing.T) {
-	defer afterTest(t)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
-		t.Fatalf("didn't expect to get request in Handler")
-	}))
-	defer ts.Close()
-	req, _ := NewRequest("GET", ts.URL, nil)
-	var bytesPerHeader = len("header12345: val12345\r\n")
-	for i := 0; i < ((DefaultMaxHeaderBytes+4096)/bytesPerHeader)+1; i++ {
-		req.Header.Set(fmt.Sprintf("header%05d", i), fmt.Sprintf("val%05d", i))
-	}
-	res, err := DefaultClient.Do(req)
-	if err != nil {
-		// Some HTTP clients may fail on this undefined behavior (server replying and
-		// closing the connection while the request is still being written), but
-		// we do support it (at least currently), so we expect a response below.
-		t.Fatalf("Do: %v", err)
-	}
-	defer res.Body.Close()
-	if res.StatusCode != 413 {
-		t.Fatalf("expected 413 response status; got: %d %s", res.StatusCode, res.Status)
-	}
-}
-
-type neverEnding byte
-
-func (b neverEnding) Read(p []byte) (n int, err error) {
-	for i := range p {
-		p[i] = byte(b)
-	}
-	return len(p), nil
-}
-
-type countReader struct {
-	r io.Reader
-	n *int64
-}
-
-func (cr countReader) Read(p []byte) (n int, err error) {
-	n, err = cr.r.Read(p)
-	atomic.AddInt64(cr.n, int64(n))
-	return
-}
-
-func TestRequestBodyLimit(t *testing.T) {
-	defer afterTest(t)
-	const limit = 1 << 20
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
-		r.Body = MaxBytesReader(w, r.Body, limit)
-		n, err := io.Copy(ioutil.Discard, r.Body)
-		if err == nil {
-			t.Errorf("expected error from io.Copy")
-		}
-		if n != limit {
-			t.Errorf("io.Copy = %d, want %d", n, limit)
-		}
-	}))
-	defer ts.Close()
-
-	nWritten := new(int64)
-	req, _ := NewRequest("POST", ts.URL, io.LimitReader(countReader{neverEnding('a'), nWritten}, limit*200))
-
-	// Send the POST, but don't care it succeeds or not.  The
-	// remote side is going to reply and then close the TCP
-	// connection, and HTTP doesn't really define if that's
-	// allowed or not.  Some HTTP clients will get the response
-	// and some (like ours, currently) will complain that the
-	// request write failed, without reading the response.
-	//
-	// But that's okay, since what we're really testing is that
-	// the remote side hung up on us before we wrote too much.
-	_, _ = DefaultClient.Do(req)
-
-	if atomic.LoadInt64(nWritten) > limit*100 {
-		t.Errorf("handler restricted the request body to %d bytes, but client managed to write %d",
-			limit, nWritten)
-	}
-}
-
-// TestClientWriteShutdown tests that if the client shuts down the write
-// side of their TCP connection, the server doesn't send a 400 Bad Request.
-func TestClientWriteShutdown(t *testing.T) {
-	if runtime.GOOS == "plan9" {
-		t.Skip("skipping test; see http://golang.org/issue/7237")
-	}
-	defer afterTest(t)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {}))
-	defer ts.Close()
-	conn, err := net.Dial("tcp", ts.Listener.Addr().String())
-	if err != nil {
-		t.Fatalf("Dial: %v", err)
-	}
-	err = conn.(*net.TCPConn).CloseWrite()
-	if err != nil {
-		t.Fatalf("Dial: %v", err)
-	}
-	donec := make(chan bool)
-	go func() {
-		defer close(donec)
-		bs, err := ioutil.ReadAll(conn)
-		if err != nil {
-			t.Fatalf("ReadAll: %v", err)
-		}
-		got := string(bs)
-		if got != "" {
-			t.Errorf("read %q from server; want nothing", got)
-		}
-	}()
-	select {
-	case <-donec:
-	case <-time.After(10 * time.Second):
-		t.Fatalf("timeout")
-	}
-}
-
-// Tests that chunked server responses that write 1 byte at a time are
-// buffered before chunk headers are added, not after chunk headers.
-func TestServerBufferedChunking(t *testing.T) {
-	conn := new(testConn)
-	conn.readBuf.Write([]byte("GET / HTTP/1.1\r\n\r\n"))
-	conn.closec = make(chan bool, 1)
-	ls := &oneConnListener{conn}
-	go Serve(ls, HandlerFunc(func(rw ResponseWriter, req *Request) {
-		rw.(Flusher).Flush() // force the Header to be sent, in chunking mode, not counting the length
-		rw.Write([]byte{'x'})
-		rw.Write([]byte{'y'})
-		rw.Write([]byte{'z'})
-	}))
-	<-conn.closec
-	if !bytes.HasSuffix(conn.writeBuf.Bytes(), []byte("\r\n\r\n3\r\nxyz\r\n0\r\n\r\n")) {
-		t.Errorf("response didn't end with a single 3 byte 'xyz' chunk; got:\n%q",
-			conn.writeBuf.Bytes())
-	}
-}
-
-// Tests that the server flushes its response headers out when it's
-// ignoring the response body and waits a bit before forcefully
-// closing the TCP connection, causing the client to get a RST.
-// See http://golang.org/issue/3595
-func TestServerGracefulClose(t *testing.T) {
-	defer afterTest(t)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
-		Error(w, "bye", StatusUnauthorized)
-	}))
-	defer ts.Close()
-
-	conn, err := net.Dial("tcp", ts.Listener.Addr().String())
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer conn.Close()
-	const bodySize = 5 << 20
-	req := []byte(fmt.Sprintf("POST / HTTP/1.1\r\nHost: foo.com\r\nContent-Length: %d\r\n\r\n", bodySize))
-	for i := 0; i < bodySize; i++ {
-		req = append(req, 'x')
-	}
-	writeErr := make(chan error)
-	go func() {
-		_, err := conn.Write(req)
-		writeErr <- err
-	}()
-	br := bufio.NewReader(conn)
-	lineNum := 0
-	for {
-		line, err := br.ReadString('\n')
-		if err == io.EOF {
-			break
-		}
-		if err != nil {
-			t.Fatalf("ReadLine: %v", err)
-		}
-		lineNum++
-		if lineNum == 1 && !strings.Contains(line, "401 Unauthorized") {
-			t.Errorf("Response line = %q; want a 401", line)
-		}
-	}
-	// Wait for write to finish. This is a broken pipe on both
-	// Darwin and Linux, but checking this isn't the point of
-	// the test.
-	<-writeErr
-}
-
-func TestCaseSensitiveMethod(t *testing.T) {
-	defer afterTest(t)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
-		if r.Method != "get" {
-			t.Errorf(`Got method %q; want "get"`, r.Method)
-		}
-	}))
-	defer ts.Close()
-	req, _ := NewRequest("get", ts.URL, nil)
-	res, err := DefaultClient.Do(req)
-	if err != nil {
-		t.Error(err)
-		return
-	}
-	res.Body.Close()
-}
-
-// TestContentLengthZero tests that for both an HTTP/1.0 and HTTP/1.1
-// request (both keep-alive), when a Handler never writes any
-// response, the net/http package adds a "Content-Length: 0" response
-// header.
-func TestContentLengthZero(t *testing.T) {
-	ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) {}))
-	defer ts.Close()
-
-	for _, version := range []string{"HTTP/1.0", "HTTP/1.1"} {
-		conn, err := net.Dial("tcp", ts.Listener.Addr().String())
-		if err != nil {
-			t.Fatalf("error dialing: %v", err)
-		}
-		_, err = fmt.Fprintf(conn, "GET / %v\r\nConnection: keep-alive\r\nHost: foo\r\n\r\n", version)
-		if err != nil {
-			t.Fatalf("error writing: %v", err)
-		}
-		req, _ := NewRequest("GET", "/", nil)
-		res, err := ReadResponse(bufio.NewReader(conn), req)
-		if err != nil {
-			t.Fatalf("error reading response: %v", err)
-		}
-		if te := res.TransferEncoding; len(te) > 0 {
-			t.Errorf("For version %q, Transfer-Encoding = %q; want none", version, te)
-		}
-		if cl := res.ContentLength; cl != 0 {
-			t.Errorf("For version %q, Content-Length = %v; want 0", version, cl)
-		}
-		conn.Close()
-	}
-}
-
-func TestCloseNotifier(t *testing.T) {
-	defer afterTest(t)
-	gotReq := make(chan bool, 1)
-	sawClose := make(chan bool, 1)
-	ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) {
-		gotReq <- true
-		cc := rw.(CloseNotifier).CloseNotify()
-		<-cc
-		sawClose <- true
-	}))
-	conn, err := net.Dial("tcp", ts.Listener.Addr().String())
-	if err != nil {
-		t.Fatalf("error dialing: %v", err)
-	}
-	diec := make(chan bool)
-	go func() {
-		_, err = fmt.Fprintf(conn, "GET / HTTP/1.1\r\nConnection: keep-alive\r\nHost: foo\r\n\r\n")
-		if err != nil {
-			t.Fatal(err)
-		}
-		<-diec
-		conn.Close()
-	}()
-For:
-	for {
-		select {
-		case <-gotReq:
-			diec <- true
-		case <-sawClose:
-			break For
-		case <-time.After(5 * time.Second):
-			t.Fatal("timeout")
-		}
-	}
-	ts.Close()
-}
-
-func TestCloseNotifierChanLeak(t *testing.T) {
-	defer afterTest(t)
-	req := reqBytes("GET / HTTP/1.0\nHost: golang.org")
-	for i := 0; i < 20; i++ {
-		var output bytes.Buffer
-		conn := &rwTestConn{
-			Reader: bytes.NewReader(req),
-			Writer: &output,
-			closec: make(chan bool, 1),
-		}
-		ln := &oneConnListener{conn: conn}
-		handler := HandlerFunc(func(rw ResponseWriter, r *Request) {
-			// Ignore the return value and never read from
-			// it, testing that we don't leak goroutines
-			// on the sending side:
-			_ = rw.(CloseNotifier).CloseNotify()
-		})
-		go Serve(ln, handler)
-		<-conn.closec
-	}
-}
-
-func TestOptions(t *testing.T) {
-	uric := make(chan string, 2) // only expect 1, but leave space for 2
-	mux := NewServeMux()
-	mux.HandleFunc("/", func(w ResponseWriter, r *Request) {
-		uric <- r.RequestURI
-	})
-	ts := httptest.NewServer(mux)
-	defer ts.Close()
-
-	conn, err := net.Dial("tcp", ts.Listener.Addr().String())
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer conn.Close()
-
-	// An OPTIONS * request should succeed.
-	_, err = conn.Write([]byte("OPTIONS * HTTP/1.1\r\nHost: foo.com\r\n\r\n"))
-	if err != nil {
-		t.Fatal(err)
-	}
-	br := bufio.NewReader(conn)
-	res, err := ReadResponse(br, &Request{Method: "OPTIONS"})
-	if err != nil {
-		t.Fatal(err)
-	}
-	if res.StatusCode != 200 {
-		t.Errorf("Got non-200 response to OPTIONS *: %#v", res)
-	}
-
-	// A GET * request on a ServeMux should fail.
-	_, err = conn.Write([]byte("GET * HTTP/1.1\r\nHost: foo.com\r\n\r\n"))
-	if err != nil {
-		t.Fatal(err)
-	}
-	res, err = ReadResponse(br, &Request{Method: "GET"})
-	if err != nil {
-		t.Fatal(err)
-	}
-	if res.StatusCode != 400 {
-		t.Errorf("Got non-400 response to GET *: %#v", res)
-	}
-
-	res, err = Get(ts.URL + "/second")
-	if err != nil {
-		t.Fatal(err)
-	}
-	res.Body.Close()
-	if got := <-uric; got != "/second" {
-		t.Errorf("Handler saw request for %q; want /second", got)
-	}
-}
-
-// Tests regarding the ordering of Write, WriteHeader, Header, and
-// Flush calls.  In Go 1.0, rw.WriteHeader immediately flushed the
-// (*response).header to the wire. In Go 1.1, the actual wire flush is
-// delayed, so we could maybe tack on a Content-Length and better
-// Content-Type after we see more (or all) of the output. To preserve
-// compatibility with Go 1, we need to be careful to track which
-// headers were live at the time of WriteHeader, so we write the same
-// ones, even if the handler modifies them (~erroneously) after the
-// first Write.
-func TestHeaderToWire(t *testing.T) {
-	tests := []struct {
-		name    string
-		handler func(ResponseWriter, *Request)
-		check   func(output string) error
-	}{
-		{
-			name: "write without Header",
-			handler: func(rw ResponseWriter, r *Request) {
-				rw.Write([]byte("hello world"))
-			},
-			check: func(got string) error {
-				if !strings.Contains(got, "Content-Length:") {
-					return errors.New("no content-length")
-				}
-				if !strings.Contains(got, "Content-Type: text/plain") {
-					return errors.New("no content-length")
-				}
-				return nil
-			},
-		},
-		{
-			name: "Header mutation before write",
-			handler: func(rw ResponseWriter, r *Request) {
-				h := rw.Header()
-				h.Set("Content-Type", "some/type")
-				rw.Write([]byte("hello world"))
-				h.Set("Too-Late", "bogus")
-			},
-			check: func(got string) error {
-				if !strings.Contains(got, "Content-Length:") {
-					return errors.New("no content-length")
-				}
-				if !strings.Contains(got, "Content-Type: some/type") {
-					return errors.New("wrong content-type")
-				}
-				if strings.Contains(got, "Too-Late") {
-					return errors.New("don't want too-late header")
-				}
-				return nil
-			},
-		},
-		{
-			name: "write then useless Header mutation",
-			handler: func(rw ResponseWriter, r *Request) {
-				rw.Write([]byte("hello world"))
-				rw.Header().Set("Too-Late", "Write already wrote headers")
-			},
-			check: func(got string) error {
-				if strings.Contains(got, "Too-Late") {
-					return errors.New("header appeared from after WriteHeader")
-				}
-				return nil
-			},
-		},
-		{
-			name: "flush then write",
-			handler: func(rw ResponseWriter, r *Request) {
-				rw.(Flusher).Flush()
-				rw.Write([]byte("post-flush"))
-				rw.Header().Set("Too-Late", "Write already wrote headers")
-			},
-			check: func(got string) error {
-				if !strings.Contains(got, "Transfer-Encoding: chunked") {
-					return errors.New("not chunked")
-				}
-				if strings.Contains(got, "Too-Late") {
-					return errors.New("header appeared from after WriteHeader")
-				}
-				return nil
-			},
-		},
-		{
-			name: "header then flush",
-			handler: func(rw ResponseWriter, r *Request) {
-				rw.Header().Set("Content-Type", "some/type")
-				rw.(Flusher).Flush()
-				rw.Write([]byte("post-flush"))
-				rw.Header().Set("Too-Late", "Write already wrote headers")
-			},
-			check: func(got string) error {
-				if !strings.Contains(got, "Transfer-Encoding: chunked") {
-					return errors.New("not chunked")
-				}
-				if strings.Contains(got, "Too-Late") {
-					return errors.New("header appeared from after WriteHeader")
-				}
-				if !strings.Contains(got, "Content-Type: some/type") {
-					return errors.New("wrong content-length")
-				}
-				return nil
-			},
-		},
-		{
-			name: "sniff-on-first-write content-type",
-			handler: func(rw ResponseWriter, r *Request) {
-				rw.Write([]byte("<html><head></head><body>some html</body></html>"))
-				rw.Header().Set("Content-Type", "x/wrong")
-			},
-			check: func(got string) error {
-				if !strings.Contains(got, "Content-Type: text/html") {
-					return errors.New("wrong content-length; want html")
-				}
-				return nil
-			},
-		},
-		{
-			name: "explicit content-type wins",
-			handler: func(rw ResponseWriter, r *Request) {
-				rw.Header().Set("Content-Type", "some/type")
-				rw.Write([]byte("<html><head></head><body>some html</body></html>"))
-			},
-			check: func(got string) error {
-				if !strings.Contains(got, "Content-Type: some/type") {
-					return errors.New("wrong content-length; want html")
-				}
-				return nil
-			},
-		},
-		{
-			name: "empty handler",
-			handler: func(rw ResponseWriter, r *Request) {
-			},
-			check: func(got string) error {
-				if !strings.Contains(got, "Content-Type: text/plain") {
-					return errors.New("wrong content-length; want text/plain")
-				}
-				if !strings.Contains(got, "Content-Length: 0") {
-					return errors.New("want 0 content-length")
-				}
-				return nil
-			},
-		},
-		{
-			name: "only Header, no write",
-			handler: func(rw ResponseWriter, r *Request) {
-				rw.Header().Set("Some-Header", "some-value")
-			},
-			check: func(got string) error {
-				if !strings.Contains(got, "Some-Header") {
-					return errors.New("didn't get header")
-				}
-				return nil
-			},
-		},
-		{
-			name: "WriteHeader call",
-			handler: func(rw ResponseWriter, r *Request) {
-				rw.WriteHeader(404)
-				rw.Header().Set("Too-Late", "some-value")
-			},
-			check: func(got string) error {
-				if !strings.Contains(got, "404") {
-					return errors.New("wrong status")
-				}
-				if strings.Contains(got, "Some-Header") {
-					return errors.New("shouldn't have seen Too-Late")
-				}
-				return nil
-			},
-		},
-	}
-	for _, tc := range tests {
-		ht := newHandlerTest(HandlerFunc(tc.handler))
-		got := ht.rawResponse("GET / HTTP/1.1\nHost: golang.org")
-		if err := tc.check(got); err != nil {
-			t.Errorf("%s: %v\nGot response:\n%s", tc.name, err, got)
-		}
-	}
-}
-
-// goTimeout runs f, failing t if f takes more than ns to complete.
-func goTimeout(t *testing.T, d time.Duration, f func()) {
-	ch := make(chan bool, 2)
-	timer := time.AfterFunc(d, func() {
-		t.Errorf("Timeout expired after %v", d)
-		ch <- true
-	})
-	defer timer.Stop()
-	go func() {
-		defer func() { ch <- true }()
-		f()
-	}()
-	<-ch
-}
-
-type errorListener struct {
-	errs []error
-}
-
-func (l *errorListener) Accept() (c net.Conn, err error) {
-	if len(l.errs) == 0 {
-		return nil, io.EOF
-	}
-	err = l.errs[0]
-	l.errs = l.errs[1:]
-	return
-}
-
-func (l *errorListener) Close() error {
-	return nil
-}
-
-func (l *errorListener) Addr() net.Addr {
-	return dummyAddr("test-address")
-}
-
-func TestAcceptMaxFds(t *testing.T) {
-	log.SetOutput(ioutil.Discard) // is noisy otherwise
-	defer log.SetOutput(os.Stderr)
-
-	ln := &errorListener{[]error{
-		&net.OpError{
-			Op:  "accept",
-			Err: syscall.EMFILE,
-		}}}
-	err := Serve(ln, HandlerFunc(HandlerFunc(func(ResponseWriter, *Request) {})))
-	if err != io.EOF {
-		t.Errorf("got error %v, want EOF", err)
-	}
-}
-
-func TestWriteAfterHijack(t *testing.T) {
-	req := reqBytes("GET / HTTP/1.1\nHost: golang.org")
-	var buf bytes.Buffer
-	wrotec := make(chan bool, 1)
-	conn := &rwTestConn{
-		Reader: bytes.NewReader(req),
-		Writer: &buf,
-		closec: make(chan bool, 1),
-	}
-	handler := HandlerFunc(func(rw ResponseWriter, r *Request) {
-		conn, bufrw, err := rw.(Hijacker).Hijack()
-		if err != nil {
-			t.Error(err)
-			return
-		}
-		go func() {
-			bufrw.Write([]byte("[hijack-to-bufw]"))
-			bufrw.Flush()
-			conn.Write([]byte("[hijack-to-conn]"))
-			conn.Close()
-			wrotec <- true
-		}()
-	})
-	ln := &oneConnListener{conn: conn}
-	go Serve(ln, handler)
-	<-conn.closec
-	<-wrotec
-	if g, w := buf.String(), "[hijack-to-bufw][hijack-to-conn]"; g != w {
-		t.Errorf("wrote %q; want %q", g, w)
-	}
-}
-
-func TestDoubleHijack(t *testing.T) {
-	req := reqBytes("GET / HTTP/1.1\nHost: golang.org")
-	var buf bytes.Buffer
-	conn := &rwTestConn{
-		Reader: bytes.NewReader(req),
-		Writer: &buf,
-		closec: make(chan bool, 1),
-	}
-	handler := HandlerFunc(func(rw ResponseWriter, r *Request) {
-		conn, _, err := rw.(Hijacker).Hijack()
-		if err != nil {
-			t.Error(err)
-			return
-		}
-		_, _, err = rw.(Hijacker).Hijack()
-		if err == nil {
-			t.Errorf("got err = nil;  want err != nil")
-		}
-		conn.Close()
-	})
-	ln := &oneConnListener{conn: conn}
-	go Serve(ln, handler)
-	<-conn.closec
-}
-
-// http://code.google.com/p/go/issues/detail?id=5955
-// Note that this does not test the "request too large"
-// exit path from the http server. This is intentional;
-// not sending Connection: close is just a minor wire
-// optimization and is pointless if dealing with a
-// badly behaved client.
-func TestHTTP10ConnectionHeader(t *testing.T) {
-	defer afterTest(t)
-
-	mux := NewServeMux()
-	mux.Handle("/", HandlerFunc(func(resp ResponseWriter, req *Request) {}))
-	ts := httptest.NewServer(mux)
-	defer ts.Close()
-
-	// net/http uses HTTP/1.1 for requests, so write requests manually
-	tests := []struct {
-		req    string   // raw http request
-		expect []string // expected Connection header(s)
-	}{
-		{
-			req:    "GET / HTTP/1.0\r\n\r\n",
-			expect: nil,
-		},
-		{
-			req:    "OPTIONS * HTTP/1.0\r\n\r\n",
-			expect: nil,
-		},
-		{
-			req:    "GET / HTTP/1.0\r\nConnection: keep-alive\r\n\r\n",
-			expect: []string{"keep-alive"},
-		},
-	}
-
-	for _, tt := range tests {
-		conn, err := net.Dial("tcp", ts.Listener.Addr().String())
-		if err != nil {
-			t.Fatal("dial err:", err)
-		}
-
-		_, err = fmt.Fprint(conn, tt.req)
-		if err != nil {
-			t.Fatal("conn write err:", err)
-		}
-
-		resp, err := ReadResponse(bufio.NewReader(conn), &Request{Method: "GET"})
-		if err != nil {
-			t.Fatal("ReadResponse err:", err)
-		}
-		conn.Close()
-		resp.Body.Close()
-
-		got := resp.Header["Connection"]
-		if !reflect.DeepEqual(got, tt.expect) {
-			t.Errorf("wrong Connection headers for request %q. Got %q expect %q", tt.req, got, tt.expect)
-		}
-	}
-}
-
-// See golang.org/issue/5660
-func TestServerReaderFromOrder(t *testing.T) {
-	defer afterTest(t)
-	pr, pw := io.Pipe()
-	const size = 3 << 20
-	ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) {
-		rw.Header().Set("Content-Type", "text/plain") // prevent sniffing path
-		done := make(chan bool)
-		go func() {
-			io.Copy(rw, pr)
-			close(done)
-		}()
-		time.Sleep(25 * time.Millisecond) // give Copy a chance to break things
-		n, err := io.Copy(ioutil.Discard, req.Body)
-		if err != nil {
-			t.Errorf("handler Copy: %v", err)
-			return
-		}
-		if n != size {
-			t.Errorf("handler Copy = %d; want %d", n, size)
-		}
-		pw.Write([]byte("hi"))
-		pw.Close()
-		<-done
-	}))
-	defer ts.Close()
-
-	req, err := NewRequest("POST", ts.URL, io.LimitReader(neverEnding('a'), size))
-	if err != nil {
-		t.Fatal(err)
-	}
-	res, err := DefaultClient.Do(req)
-	if err != nil {
-		t.Fatal(err)
-	}
-	all, err := ioutil.ReadAll(res.Body)
-	if err != nil {
-		t.Fatal(err)
-	}
-	res.Body.Close()
-	if string(all) != "hi" {
-		t.Errorf("Body = %q; want hi", all)
-	}
-}
-
-// Issue 6157, Issue 6685
-func TestCodesPreventingContentTypeAndBody(t *testing.T) {
-	for _, code := range []int{StatusNotModified, StatusNoContent, StatusContinue} {
-		ht := newHandlerTest(HandlerFunc(func(w ResponseWriter, r *Request) {
-			if r.URL.Path == "/header" {
-				w.Header().Set("Content-Length", "123")
-			}
-			w.WriteHeader(code)
-			if r.URL.Path == "/more" {
-				w.Write([]byte("stuff"))
-			}
-		}))
-		for _, req := range []string{
-			"GET / HTTP/1.0",
-			"GET /header HTTP/1.0",
-			"GET /more HTTP/1.0",
-			"GET / HTTP/1.1",
-			"GET /header HTTP/1.1",
-			"GET /more HTTP/1.1",
-		} {
-			got := ht.rawResponse(req)
-			wantStatus := fmt.Sprintf("%d %s", code, StatusText(code))
-			if !strings.Contains(got, wantStatus) {
-				t.Errorf("Code %d: Wanted %q Modified for %q: %s", code, wantStatus, req, got)
-			} else if strings.Contains(got, "Content-Length") {
-				t.Errorf("Code %d: Got a Content-Length from %q: %s", code, req, got)
-			} else if strings.Contains(got, "stuff") {
-				t.Errorf("Code %d: Response contains a body from %q: %s", code, req, got)
-			}
-		}
-	}
-}
-
-func TestContentTypeOkayOn204(t *testing.T) {
-	ht := newHandlerTest(HandlerFunc(func(w ResponseWriter, r *Request) {
-		w.Header().Set("Content-Length", "123") // suppressed
-		w.Header().Set("Content-Type", "foo/bar")
-		w.WriteHeader(204)
-	}))
-	got := ht.rawResponse("GET / HTTP/1.1")
-	if !strings.Contains(got, "Content-Type: foo/bar") {
-		t.Errorf("Response = %q; want Content-Type: foo/bar", got)
-	}
-	if strings.Contains(got, "Content-Length: 123") {
-		t.Errorf("Response = %q; don't want a Content-Length", got)
-	}
-}
-
-// Issue 6995
-// A server Handler can receive a Request, and then turn around and
-// give a copy of that Request.Body out to the Transport (e.g. any
-// proxy).  So then two people own that Request.Body (both the server
-// and the http client), and both think they can close it on failure.
-// Therefore, all incoming server requests Bodies need to be thread-safe.
-func TestTransportAndServerSharedBodyRace(t *testing.T) {
-	defer afterTest(t)
-
-	const bodySize = 1 << 20
-
-	unblockBackend := make(chan bool)
-	backend := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) {
-		io.CopyN(rw, req.Body, bodySize/2)
-		<-unblockBackend
-	}))
-	defer backend.Close()
-
-	backendRespc := make(chan *Response, 1)
-	proxy := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) {
-		if req.RequestURI == "/foo" {
-			rw.Write([]byte("bar"))
-			return
-		}
-		req2, _ := NewRequest("POST", backend.URL, req.Body)
-		req2.ContentLength = bodySize
-
-		bresp, err := DefaultClient.Do(req2)
-		if err != nil {
-			t.Errorf("Proxy outbound request: %v", err)
-			return
-		}
-		_, err = io.CopyN(ioutil.Discard, bresp.Body, bodySize/4)
-		if err != nil {
-			t.Errorf("Proxy copy error: %v", err)
-			return
-		}
-		backendRespc <- bresp // to close later
-
-		// Try to cause a race: Both the DefaultTransport and the proxy handler's Server
-		// will try to read/close req.Body (aka req2.Body)
-		DefaultTransport.(*Transport).CancelRequest(req2)
-		rw.Write([]byte("OK"))
-	}))
-	defer proxy.Close()
-
-	req, _ := NewRequest("POST", proxy.URL, io.LimitReader(neverEnding('a'), bodySize))
-	res, err := DefaultClient.Do(req)
-	if err != nil {
-		t.Fatalf("Original request: %v", err)
-	}
-
-	// Cleanup, so we don't leak goroutines.
-	res.Body.Close()
-	close(unblockBackend)
-	(<-backendRespc).Body.Close()
-}
-
-// Test that a hanging Request.Body.Read from another goroutine can't
-// cause the Handler goroutine's Request.Body.Close to block.
-func TestRequestBodyCloseDoesntBlock(t *testing.T) {
-	t.Skipf("Skipping known issue; see golang.org/issue/7121")
-	if testing.Short() {
-		t.Skip("skipping in -short mode")
-	}
-	defer afterTest(t)
-
-	readErrCh := make(chan error, 1)
-	errCh := make(chan error, 2)
-
-	server := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) {
-		go func(body io.Reader) {
-			_, err := body.Read(make([]byte, 100))
-			readErrCh <- err
-		}(req.Body)
-		time.Sleep(500 * time.Millisecond)
-	}))
-	defer server.Close()
-
-	closeConn := make(chan bool)
-	defer close(closeConn)
-	go func() {
-		conn, err := net.Dial("tcp", server.Listener.Addr().String())
-		if err != nil {
-			errCh <- err
-			return
-		}
-		defer conn.Close()
-		_, err = conn.Write([]byte("POST / HTTP/1.1\r\nConnection: close\r\nHost: foo\r\nContent-Length: 100000\r\n\r\n"))
-		if err != nil {
-			errCh <- err
-			return
-		}
-		// And now just block, making the server block on our
-		// 100000 bytes of body that will never arrive.
-		<-closeConn
-	}()
-	select {
-	case err := <-readErrCh:
-		if err == nil {
-			t.Error("Read was nil. Expected error.")
-		}
-	case err := <-errCh:
-		t.Error(err)
-	case <-time.After(5 * time.Second):
-		t.Error("timeout")
-	}
-}
-
-func TestResponseWriterWriteStringAllocs(t *testing.T) {
-	ht := newHandlerTest(HandlerFunc(func(w ResponseWriter, r *Request) {
-		if r.URL.Path == "/s" {
-			io.WriteString(w, "Hello world")
-		} else {
-			w.Write([]byte("Hello world"))
-		}
-	}))
-	before := testing.AllocsPerRun(50, func() { ht.rawResponse("GET / HTTP/1.0") })
-	after := testing.AllocsPerRun(50, func() { ht.rawResponse("GET /s HTTP/1.0") })
-	if int(after) >= int(before) {
-		t.Errorf("WriteString allocs of %v >= Write allocs of %v", after, before)
-	}
-}
-
-func TestAppendTime(t *testing.T) {
-	var b [len(TimeFormat)]byte
-	t1 := time.Date(2013, 9, 21, 15, 41, 0, 0, time.FixedZone("CEST", 2*60*60))
-	res := ExportAppendTime(b[:0], t1)
-	t2, err := ParseTime(string(res))
-	if err != nil {
-		t.Fatalf("Error parsing time: %s", err)
-	}
-	if !t1.Equal(t2) {
-		t.Fatalf("Times differ; expected: %v, got %v (%s)", t1, t2, string(res))
-	}
-}
-
-func TestServerConnState(t *testing.T) {
-	defer afterTest(t)
-	handler := map[string]func(w ResponseWriter, r *Request){
-		"/": func(w ResponseWriter, r *Request) {
-			fmt.Fprintf(w, "Hello.")
-		},
-		"/close": func(w ResponseWriter, r *Request) {
-			w.Header().Set("Connection", "close")
-			fmt.Fprintf(w, "Hello.")
-		},
-		"/hijack": func(w ResponseWriter, r *Request) {
-			c, _, _ := w.(Hijacker).Hijack()
-			c.Write([]byte("HTTP/1.0 200 OK\r\nConnection: close\r\n\r\nHello."))
-			c.Close()
-		},
-		"/hijack-panic": func(w ResponseWriter, r *Request) {
-			c, _, _ := w.(Hijacker).Hijack()
-			c.Write([]byte("HTTP/1.0 200 OK\r\nConnection: close\r\n\r\nHello."))
-			c.Close()
-			panic("intentional panic")
-		},
-	}
-	ts := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, r *Request) {
-		handler[r.URL.Path](w, r)
-	}))
-	defer ts.Close()
-
-	var mu sync.Mutex // guard stateLog and connID
-	var stateLog = map[int][]ConnState{}
-	var connID = map[net.Conn]int{}
-
-	ts.Config.ErrorLog = log.New(ioutil.Discard, "", 0)
-	ts.Config.ConnState = func(c net.Conn, state ConnState) {
-		if c == nil {
-			t.Errorf("nil conn seen in state %s", state)
-			return
-		}
-		mu.Lock()
-		defer mu.Unlock()
-		id, ok := connID[c]
-		if !ok {
-			id = len(connID) + 1
-			connID[c] = id
-		}
-		stateLog[id] = append(stateLog[id], state)
-	}
-	ts.Start()
-
-	mustGet(t, ts.URL+"/")
-	mustGet(t, ts.URL+"/close")
-
-	mustGet(t, ts.URL+"/")
-	mustGet(t, ts.URL+"/", "Connection", "close")
-
-	mustGet(t, ts.URL+"/hijack")
-	mustGet(t, ts.URL+"/hijack-panic")
-
-	// New->Closed
-	{
-		c, err := net.Dial("tcp", ts.Listener.Addr().String())
-		if err != nil {
-			t.Fatal(err)
-		}
-		c.Close()
-	}
-
-	// New->Active->Closed
-	{
-		c, err := net.Dial("tcp", ts.Listener.Addr().String())
-		if err != nil {
-			t.Fatal(err)
-		}
-		if _, err := io.WriteString(c, "BOGUS REQUEST\r\n\r\n"); err != nil {
-			t.Fatal(err)
-		}
-		c.Close()
-	}
-
-	// New->Idle->Closed
-	{
-		c, err := net.Dial("tcp", ts.Listener.Addr().String())
-		if err != nil {
-			t.Fatal(err)
-		}
-		if _, err := io.WriteString(c, "GET / HTTP/1.1\r\nHost: foo\r\n\r\n"); err != nil {
-			t.Fatal(err)
-		}
-		res, err := ReadResponse(bufio.NewReader(c), nil)
-		if err != nil {
-			t.Fatal(err)
-		}
-		if _, err := io.Copy(ioutil.Discard, res.Body); err != nil {
-			t.Fatal(err)
-		}
-		c.Close()
-	}
-
-	want := map[int][]ConnState{
-		1: []ConnState{StateNew, StateActive, StateIdle, StateActive, StateClosed},
-		2: []ConnState{StateNew, StateActive, StateIdle, StateActive, StateClosed},
-		3: []ConnState{StateNew, StateActive, StateHijacked},
-		4: []ConnState{StateNew, StateActive, StateHijacked},
-		5: []ConnState{StateNew, StateClosed},
-		6: []ConnState{StateNew, StateActive, StateClosed},
-		7: []ConnState{StateNew, StateActive, StateIdle, StateClosed},
-	}
-	logString := func(m map[int][]ConnState) string {
-		var b bytes.Buffer
-		for id, l := range m {
-			fmt.Fprintf(&b, "Conn %d: ", id)
-			for _, s := range l {
-				fmt.Fprintf(&b, "%s ", s)
-			}
-			b.WriteString("\n")
-		}
-		return b.String()
-	}
-
-	for i := 0; i < 5; i++ {
-		time.Sleep(time.Duration(i) * 50 * time.Millisecond)
-		mu.Lock()
-		match := reflect.DeepEqual(stateLog, want)
-		mu.Unlock()
-		if match {
-			return
-		}
-	}
-
-	mu.Lock()
-	t.Errorf("Unexpected events.\nGot log: %s\n   Want: %s\n", logString(stateLog), logString(want))
-	mu.Unlock()
-}
-
-func mustGet(t *testing.T, url string, headers ...string) {
-	req, err := NewRequest("GET", url, nil)
-	if err != nil {
-		t.Fatal(err)
-	}
-	for len(headers) > 0 {
-		req.Header.Add(headers[0], headers[1])
-		headers = headers[2:]
-	}
-	res, err := DefaultClient.Do(req)
-	if err != nil {
-		t.Errorf("Error fetching %s: %v", url, err)
-		return
-	}
-	_, err = ioutil.ReadAll(res.Body)
-	defer res.Body.Close()
-	if err != nil {
-		t.Errorf("Error reading %s: %v", url, err)
-	}
-}
-
-func TestServerKeepAlivesEnabled(t *testing.T) {
-	defer afterTest(t)
-	ts := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, r *Request) {}))
-	ts.Config.SetKeepAlivesEnabled(false)
-	ts.Start()
-	defer ts.Close()
-	res, err := Get(ts.URL)
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer res.Body.Close()
-	if !res.Close {
-		t.Errorf("Body.Close == false; want true")
-	}
-}
-
-// golang.org/issue/7856
-func TestServerEmptyBodyRace(t *testing.T) {
-	defer afterTest(t)
-	var n int32
-	ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) {
-		atomic.AddInt32(&n, 1)
-	}))
-	defer ts.Close()
-	var wg sync.WaitGroup
-	const reqs = 20
-	for i := 0; i < reqs; i++ {
-		wg.Add(1)
-		go func() {
-			defer wg.Done()
-			res, err := Get(ts.URL)
-			if err != nil {
-				t.Error(err)
-				return
-			}
-			defer res.Body.Close()
-			_, err = io.Copy(ioutil.Discard, res.Body)
-			if err != nil {
-				t.Error(err)
-				return
-			}
-		}()
-	}
-	wg.Wait()
-	if got := atomic.LoadInt32(&n); got != reqs {
-		t.Errorf("handler ran %d times; want %d", got, reqs)
-	}
-}
-
-func TestServerConnStateNew(t *testing.T) {
-	sawNew := false // if the test is buggy, we'll race on this variable.
-	srv := &Server{
-		ConnState: func(c net.Conn, state ConnState) {
-			if state == StateNew {
-				sawNew = true // testing that this write isn't racy
-			}
-		},
-		Handler: HandlerFunc(func(w ResponseWriter, r *Request) {}), // irrelevant
-	}
-	srv.Serve(&oneConnListener{
-		conn: &rwTestConn{
-			Reader: strings.NewReader("GET / HTTP/1.1\r\nHost: foo\r\n\r\n"),
-			Writer: ioutil.Discard,
-		},
-	})
-	if !sawNew { // testing that this read isn't racy
-		t.Error("StateNew not seen")
-	}
-}
-
-func BenchmarkClientServer(b *testing.B) {
-	b.ReportAllocs()
-	b.StopTimer()
-	ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, r *Request) {
-		fmt.Fprintf(rw, "Hello world.\n")
-	}))
-	defer ts.Close()
-	b.StartTimer()
-
-	for i := 0; i < b.N; i++ {
-		res, err := Get(ts.URL)
-		if err != nil {
-			b.Fatal("Get:", err)
-		}
-		all, err := ioutil.ReadAll(res.Body)
-		res.Body.Close()
-		if err != nil {
-			b.Fatal("ReadAll:", err)
-		}
-		body := string(all)
-		if body != "Hello world.\n" {
-			b.Fatal("Got body:", body)
-		}
-	}
-
-	b.StopTimer()
-}
-
-func BenchmarkClientServerParallel4(b *testing.B) {
-	benchmarkClientServerParallel(b, 4)
-}
-
-func BenchmarkClientServerParallel64(b *testing.B) {
-	benchmarkClientServerParallel(b, 64)
-}
-
-func benchmarkClientServerParallel(b *testing.B, parallelism int) {
-	b.ReportAllocs()
-	ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, r *Request) {
-		fmt.Fprintf(rw, "Hello world.\n")
-	}))
-	defer ts.Close()
-	b.ResetTimer()
-	b.SetParallelism(parallelism)
-	b.RunParallel(func(pb *testing.PB) {
-		for pb.Next() {
-			res, err := Get(ts.URL)
-			if err != nil {
-				b.Logf("Get: %v", err)
-				continue
-			}
-			all, err := ioutil.ReadAll(res.Body)
-			res.Body.Close()
-			if err != nil {
-				b.Logf("ReadAll: %v", err)
-				continue
-			}
-			body := string(all)
-			if body != "Hello world.\n" {
-				panic("Got body: " + body)
-			}
-		}
-	})
-}
-
-// A benchmark for profiling the server without the HTTP client code.
-// The client code runs in a subprocess.
-//
-// For use like:
-//   $ go test -c
-//   $ ./http.test -test.run=XX -test.bench=BenchmarkServer -test.benchtime=15s -test.cpuprofile=http.prof
-//   $ go tool pprof http.test http.prof
-//   (pprof) web
-func BenchmarkServer(b *testing.B) {
-	b.ReportAllocs()
-	// Child process mode;
-	if url := os.Getenv("TEST_BENCH_SERVER_URL"); url != "" {
-		n, err := strconv.Atoi(os.Getenv("TEST_BENCH_CLIENT_N"))
-		if err != nil {
-			panic(err)
-		}
-		for i := 0; i < n; i++ {
-			res, err := Get(url)
-			if err != nil {
-				log.Panicf("Get: %v", err)
-			}
-			all, err := ioutil.ReadAll(res.Body)
-			res.Body.Close()
-			if err != nil {
-				log.Panicf("ReadAll: %v", err)
-			}
-			body := string(all)
-			if body != "Hello world.\n" {
-				log.Panicf("Got body: %q", body)
-			}
-		}
-		os.Exit(0)
-		return
-	}
-
-	var res = []byte("Hello world.\n")
-	b.StopTimer()
-	ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, r *Request) {
-		rw.Header().Set("Content-Type", "text/html; charset=utf-8")
-		rw.Write(res)
-	}))
-	defer ts.Close()
-	b.StartTimer()
-
-	cmd := exec.Command(os.Args[0], "-test.run=XXXX", "-test.bench=BenchmarkServer")
-	cmd.Env = append([]string{
-		fmt.Sprintf("TEST_BENCH_CLIENT_N=%d", b.N),
-		fmt.Sprintf("TEST_BENCH_SERVER_URL=%s", ts.URL),
-	}, os.Environ()...)
-	out, err := cmd.CombinedOutput()
-	if err != nil {
-		b.Errorf("Test failure: %v, with output: %s", err, out)
-	}
-}
-
-func BenchmarkServerFakeConnNoKeepAlive(b *testing.B) {
-	b.ReportAllocs()
-	req := reqBytes(`GET / HTTP/1.0
-Host: golang.org
-Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
-User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.52 Safari/537.17
-Accept-Encoding: gzip,deflate,sdch
-Accept-Language: en-US,en;q=0.8
-Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
-`)
-	res := []byte("Hello world!\n")
-
-	conn := &testConn{
-		// testConn.Close will not push into the channel
-		// if it's full.
-		closec: make(chan bool, 1),
-	}
-	handler := HandlerFunc(func(rw ResponseWriter, r *Request) {
-		rw.Header().Set("Content-Type", "text/html; charset=utf-8")
-		rw.Write(res)
-	})
-	ln := new(oneConnListener)
-	for i := 0; i < b.N; i++ {
-		conn.readBuf.Reset()
-		conn.writeBuf.Reset()
-		conn.readBuf.Write(req)
-		ln.conn = conn
-		Serve(ln, handler)
-		<-conn.closec
-	}
-}
-
-// repeatReader reads content count times, then EOFs.
-type repeatReader struct {
-	content []byte
-	count   int
-	off     int
-}
-
-func (r *repeatReader) Read(p []byte) (n int, err error) {
-	if r.count <= 0 {
-		return 0, io.EOF
-	}
-	n = copy(p, r.content[r.off:])
-	r.off += n
-	if r.off == len(r.content) {
-		r.count--
-		r.off = 0
-	}
-	return
-}
-
-func BenchmarkServerFakeConnWithKeepAlive(b *testing.B) {
-	b.ReportAllocs()
-
-	req := reqBytes(`GET / HTTP/1.1
-Host: golang.org
-Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
-User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.52 Safari/537.17
-Accept-Encoding: gzip,deflate,sdch
-Accept-Language: en-US,en;q=0.8
-Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
-`)
-	res := []byte("Hello world!\n")
-
-	conn := &rwTestConn{
-		Reader: &repeatReader{content: req, count: b.N},
-		Writer: ioutil.Discard,
-		closec: make(chan bool, 1),
-	}
-	handled := 0
-	handler := HandlerFunc(func(rw ResponseWriter, r *Request) {
-		handled++
-		rw.Header().Set("Content-Type", "text/html; charset=utf-8")
-		rw.Write(res)
-	})
-	ln := &oneConnListener{conn: conn}
-	go Serve(ln, handler)
-	<-conn.closec
-	if b.N != handled {
-		b.Errorf("b.N=%d but handled %d", b.N, handled)
-	}
-}
-
-// same as above, but representing the most simple possible request
-// and handler. Notably: the handler does not call rw.Header().
-func BenchmarkServerFakeConnWithKeepAliveLite(b *testing.B) {
-	b.ReportAllocs()
-
-	req := reqBytes(`GET / HTTP/1.1
-Host: golang.org
-`)
-	res := []byte("Hello world!\n")
-
-	conn := &rwTestConn{
-		Reader: &repeatReader{content: req, count: b.N},
-		Writer: ioutil.Discard,
-		closec: make(chan bool, 1),
-	}
-	handled := 0
-	handler := HandlerFunc(func(rw ResponseWriter, r *Request) {
-		handled++
-		rw.Write(res)
-	})
-	ln := &oneConnListener{conn: conn}
-	go Serve(ln, handler)
-	<-conn.closec
-	if b.N != handled {
-		b.Errorf("b.N=%d but handled %d", b.N, handled)
-	}
-}
-
-const someResponse = "<html>some response</html>"
-
-// A Response that's just no bigger than 2KB, the buffer-before-chunking threshold.
-var response = bytes.Repeat([]byte(someResponse), 2<<10/len(someResponse))
-
-// Both Content-Type and Content-Length set. Should be no buffering.
-func BenchmarkServerHandlerTypeLen(b *testing.B) {
-	benchmarkHandler(b, HandlerFunc(func(w ResponseWriter, r *Request) {
-		w.Header().Set("Content-Type", "text/html")
-		w.Header().Set("Content-Length", strconv.Itoa(len(response)))
-		w.Write(response)
-	}))
-}
-
-// A Content-Type is set, but no length. No sniffing, but will count the Content-Length.
-func BenchmarkServerHandlerNoLen(b *testing.B) {
-	benchmarkHandler(b, HandlerFunc(func(w ResponseWriter, r *Request) {
-		w.Header().Set("Content-Type", "text/html")
-		w.Write(response)
-	}))
-}
-
-// A Content-Length is set, but the Content-Type will be sniffed.
-func BenchmarkServerHandlerNoType(b *testing.B) {
-	benchmarkHandler(b, HandlerFunc(func(w ResponseWriter, r *Request) {
-		w.Header().Set("Content-Length", strconv.Itoa(len(response)))
-		w.Write(response)
-	}))
-}
-
-// Neither a Content-Type or Content-Length, so sniffed and counted.
-func BenchmarkServerHandlerNoHeader(b *testing.B) {
-	benchmarkHandler(b, HandlerFunc(func(w ResponseWriter, r *Request) {
-		w.Write(response)
-	}))
-}
-
-func benchmarkHandler(b *testing.B, h Handler) {
-	b.ReportAllocs()
-	req := reqBytes(`GET / HTTP/1.1
-Host: golang.org
-`)
-	conn := &rwTestConn{
-		Reader: &repeatReader{content: req, count: b.N},
-		Writer: ioutil.Discard,
-		closec: make(chan bool, 1),
-	}
-	handled := 0
-	handler := HandlerFunc(func(rw ResponseWriter, r *Request) {
-		handled++
-		h.ServeHTTP(rw, r)
-	})
-	ln := &oneConnListener{conn: conn}
-	go Serve(ln, handler)
-	<-conn.closec
-	if b.N != handled {
-		b.Errorf("b.N=%d but handled %d", b.N, handled)
-	}
-}
-
-func BenchmarkServerHijack(b *testing.B) {
-	b.ReportAllocs()
-	req := reqBytes(`GET / HTTP/1.1
-Host: golang.org
-`)
-	h := HandlerFunc(func(w ResponseWriter, r *Request) {
-		conn, _, err := w.(Hijacker).Hijack()
-		if err != nil {
-			panic(err)
-		}
-		conn.Close()
-	})
-	conn := &rwTestConn{
-		Writer: ioutil.Discard,
-		closec: make(chan bool, 1),
-	}
-	ln := &oneConnListener{conn: conn}
-	for i := 0; i < b.N; i++ {
-		conn.Reader = bytes.NewReader(req)
-		ln.conn = conn
-		Serve(ln, h)
-		<-conn.closec
-	}
-}
diff --git a/src/pkg/net/http/server.go b/src/pkg/net/http/server.go
deleted file mode 100644
index eae097e..0000000
--- a/src/pkg/net/http/server.go
+++ /dev/null
@@ -1,2052 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// HTTP server.  See RFC 2616.
-
-package http
-
-import (
-	"bufio"
-	"crypto/tls"
-	"errors"
-	"fmt"
-	"io"
-	"io/ioutil"
-	"log"
-	"net"
-	"net/url"
-	"os"
-	"path"
-	"runtime"
-	"strconv"
-	"strings"
-	"sync"
-	"sync/atomic"
-	"time"
-)
-
-// Errors introduced by the HTTP server.
-var (
-	ErrWriteAfterFlush = errors.New("Conn.Write called after Flush")
-	ErrBodyNotAllowed  = errors.New("http: request method or response status code does not allow body")
-	ErrHijacked        = errors.New("Conn has been hijacked")
-	ErrContentLength   = errors.New("Conn.Write wrote more than the declared Content-Length")
-)
-
-// Objects implementing the Handler interface can be
-// registered to serve a particular path or subtree
-// in the HTTP server.
-//
-// ServeHTTP should write reply headers and data to the ResponseWriter
-// and then return.  Returning signals that the request is finished
-// and that the HTTP server can move on to the next request on
-// the connection.
-type Handler interface {
-	ServeHTTP(ResponseWriter, *Request)
-}
-
-// A ResponseWriter interface is used by an HTTP handler to
-// construct an HTTP response.
-type ResponseWriter interface {
-	// Header returns the header map that will be sent by WriteHeader.
-	// Changing the header after a call to WriteHeader (or Write) has
-	// no effect.
-	Header() Header
-
-	// Write writes the data to the connection as part of an HTTP reply.
-	// If WriteHeader has not yet been called, Write calls WriteHeader(http.StatusOK)
-	// before writing the data.  If the Header does not contain a
-	// Content-Type line, Write adds a Content-Type set to the result of passing
-	// the initial 512 bytes of written data to DetectContentType.
-	Write([]byte) (int, error)
-
-	// WriteHeader sends an HTTP response header with status code.
-	// If WriteHeader is not called explicitly, the first call to Write
-	// will trigger an implicit WriteHeader(http.StatusOK).
-	// Thus explicit calls to WriteHeader are mainly used to
-	// send error codes.
-	WriteHeader(int)
-}
-
-// The Flusher interface is implemented by ResponseWriters that allow
-// an HTTP handler to flush buffered data to the client.
-//
-// Note that even for ResponseWriters that support Flush,
-// if the client is connected through an HTTP proxy,
-// the buffered data may not reach the client until the response
-// completes.
-type Flusher interface {
-	// Flush sends any buffered data to the client.
-	Flush()
-}
-
-// The Hijacker interface is implemented by ResponseWriters that allow
-// an HTTP handler to take over the connection.
-type Hijacker interface {
-	// Hijack lets the caller take over the connection.
-	// After a call to Hijack(), the HTTP server library
-	// will not do anything else with the connection.
-	// It becomes the caller's responsibility to manage
-	// and close the connection.
-	Hijack() (net.Conn, *bufio.ReadWriter, error)
-}
-
-// The CloseNotifier interface is implemented by ResponseWriters which
-// allow detecting when the underlying connection has gone away.
-//
-// This mechanism can be used to cancel long operations on the server
-// if the client has disconnected before the response is ready.
-type CloseNotifier interface {
-	// CloseNotify returns a channel that receives a single value
-	// when the client connection has gone away.
-	CloseNotify() <-chan bool
-}
-
-// A conn represents the server side of an HTTP connection.
-type conn struct {
-	remoteAddr string               // network address of remote side
-	server     *Server              // the Server on which the connection arrived
-	rwc        net.Conn             // i/o connection
-	sr         liveSwitchReader     // where the LimitReader reads from; usually the rwc
-	lr         *io.LimitedReader    // io.LimitReader(sr)
-	buf        *bufio.ReadWriter    // buffered(lr,rwc), reading from bufio->limitReader->sr->rwc
-	tlsState   *tls.ConnectionState // or nil when not using TLS
-
-	mu           sync.Mutex // guards the following
-	clientGone   bool       // if client has disconnected mid-request
-	closeNotifyc chan bool  // made lazily
-	hijackedv    bool       // connection has been hijacked by handler
-}
-
-func (c *conn) hijacked() bool {
-	c.mu.Lock()
-	defer c.mu.Unlock()
-	return c.hijackedv
-}
-
-func (c *conn) hijack() (rwc net.Conn, buf *bufio.ReadWriter, err error) {
-	c.mu.Lock()
-	defer c.mu.Unlock()
-	if c.hijackedv {
-		return nil, nil, ErrHijacked
-	}
-	if c.closeNotifyc != nil {
-		return nil, nil, errors.New("http: Hijack is incompatible with use of CloseNotifier")
-	}
-	c.hijackedv = true
-	rwc = c.rwc
-	buf = c.buf
-	c.rwc = nil
-	c.buf = nil
-	c.setState(rwc, StateHijacked)
-	return
-}
-
-func (c *conn) closeNotify() <-chan bool {
-	c.mu.Lock()
-	defer c.mu.Unlock()
-	if c.closeNotifyc == nil {
-		c.closeNotifyc = make(chan bool, 1)
-		if c.hijackedv {
-			// to obey the function signature, even though
-			// it'll never receive a value.
-			return c.closeNotifyc
-		}
-		pr, pw := io.Pipe()
-
-		readSource := c.sr.r
-		c.sr.Lock()
-		c.sr.r = pr
-		c.sr.Unlock()
-		go func() {
-			_, err := io.Copy(pw, readSource)
-			if err == nil {
-				err = io.EOF
-			}
-			pw.CloseWithError(err)
-			c.noteClientGone()
-		}()
-	}
-	return c.closeNotifyc
-}
-
-func (c *conn) noteClientGone() {
-	c.mu.Lock()
-	defer c.mu.Unlock()
-	if c.closeNotifyc != nil && !c.clientGone {
-		c.closeNotifyc <- true
-	}
-	c.clientGone = true
-}
-
-// A switchReader can have its Reader changed at runtime.
-// It's not safe for concurrent Reads and switches.
-type switchReader struct {
-	io.Reader
-}
-
-// A switchWriter can have its Writer changed at runtime.
-// It's not safe for concurrent Writes and switches.
-type switchWriter struct {
-	io.Writer
-}
-
-// A liveSwitchReader is a switchReader that's safe for concurrent
-// reads and switches, if its mutex is held.
-type liveSwitchReader struct {
-	sync.Mutex
-	r io.Reader
-}
-
-func (sr *liveSwitchReader) Read(p []byte) (n int, err error) {
-	sr.Lock()
-	r := sr.r
-	sr.Unlock()
-	return r.Read(p)
-}
-
-// This should be >= 512 bytes for DetectContentType,
-// but otherwise it's somewhat arbitrary.
-const bufferBeforeChunkingSize = 2048
-
-// chunkWriter writes to a response's conn buffer, and is the writer
-// wrapped by the response.bufw buffered writer.
-//
-// chunkWriter also is responsible for finalizing the Header, including
-// conditionally setting the Content-Type and setting a Content-Length
-// in cases where the handler's final output is smaller than the buffer
-// size. It also conditionally adds chunk headers, when in chunking mode.
-//
-// See the comment above (*response).Write for the entire write flow.
-type chunkWriter struct {
-	res *response
-
-	// header is either nil or a deep clone of res.handlerHeader
-	// at the time of res.WriteHeader, if res.WriteHeader is
-	// called and extra buffering is being done to calculate
-	// Content-Type and/or Content-Length.
-	header Header
-
-	// wroteHeader tells whether the header's been written to "the
-	// wire" (or rather: w.conn.buf). this is unlike
-	// (*response).wroteHeader, which tells only whether it was
-	// logically written.
-	wroteHeader bool
-
-	// set by the writeHeader method:
-	chunking bool // using chunked transfer encoding for reply body
-}
-
-var (
-	crlf       = []byte("\r\n")
-	colonSpace = []byte(": ")
-)
-
-func (cw *chunkWriter) Write(p []byte) (n int, err error) {
-	if !cw.wroteHeader {
-		cw.writeHeader(p)
-	}
-	if cw.res.req.Method == "HEAD" {
-		// Eat writes.
-		return len(p), nil
-	}
-	if cw.chunking {
-		_, err = fmt.Fprintf(cw.res.conn.buf, "%x\r\n", len(p))
-		if err != nil {
-			cw.res.conn.rwc.Close()
-			return
-		}
-	}
-	n, err = cw.res.conn.buf.Write(p)
-	if cw.chunking && err == nil {
-		_, err = cw.res.conn.buf.Write(crlf)
-	}
-	if err != nil {
-		cw.res.conn.rwc.Close()
-	}
-	return
-}
-
-func (cw *chunkWriter) flush() {
-	if !cw.wroteHeader {
-		cw.writeHeader(nil)
-	}
-	cw.res.conn.buf.Flush()
-}
-
-func (cw *chunkWriter) close() {
-	if !cw.wroteHeader {
-		cw.writeHeader(nil)
-	}
-	if cw.chunking {
-		// zero EOF chunk, trailer key/value pairs (currently
-		// unsupported in Go's server), followed by a blank
-		// line.
-		cw.res.conn.buf.WriteString("0\r\n\r\n")
-	}
-}
-
-// A response represents the server side of an HTTP response.
-type response struct {
-	conn          *conn
-	req           *Request // request for this response
-	wroteHeader   bool     // reply header has been (logically) written
-	wroteContinue bool     // 100 Continue response was written
-
-	w  *bufio.Writer // buffers output in chunks to chunkWriter
-	cw chunkWriter
-	sw *switchWriter // of the bufio.Writer, for return to putBufioWriter
-
-	// handlerHeader is the Header that Handlers get access to,
-	// which may be retained and mutated even after WriteHeader.
-	// handlerHeader is copied into cw.header at WriteHeader
-	// time, and privately mutated thereafter.
-	handlerHeader Header
-	calledHeader  bool // handler accessed handlerHeader via Header
-
-	written       int64 // number of bytes written in body
-	contentLength int64 // explicitly-declared Content-Length; or -1
-	status        int   // status code passed to WriteHeader
-
-	// close connection after this reply.  set on request and
-	// updated after response from handler if there's a
-	// "Connection: keep-alive" response header and a
-	// Content-Length.
-	closeAfterReply bool
-
-	// requestBodyLimitHit is set by requestTooLarge when
-	// maxBytesReader hits its max size. It is checked in
-	// WriteHeader, to make sure we don't consume the
-	// remaining request body to try to advance to the next HTTP
-	// request. Instead, when this is set, we stop reading
-	// subsequent requests on this connection and stop reading
-	// input from it.
-	requestBodyLimitHit bool
-
-	handlerDone bool // set true when the handler exits
-
-	// Buffers for Date and Content-Length
-	dateBuf [len(TimeFormat)]byte
-	clenBuf [10]byte
-}
-
-// requestTooLarge is called by maxBytesReader when too much input has
-// been read from the client.
-func (w *response) requestTooLarge() {
-	w.closeAfterReply = true
-	w.requestBodyLimitHit = true
-	if !w.wroteHeader {
-		w.Header().Set("Connection", "close")
-	}
-}
-
-// needsSniff reports whether a Content-Type still needs to be sniffed.
-func (w *response) needsSniff() bool {
-	_, haveType := w.handlerHeader["Content-Type"]
-	return !w.cw.wroteHeader && !haveType && w.written < sniffLen
-}
-
-// writerOnly hides an io.Writer value's optional ReadFrom method
-// from io.Copy.
-type writerOnly struct {
-	io.Writer
-}
-
-func srcIsRegularFile(src io.Reader) (isRegular bool, err error) {
-	switch v := src.(type) {
-	case *os.File:
-		fi, err := v.Stat()
-		if err != nil {
-			return false, err
-		}
-		return fi.Mode().IsRegular(), nil
-	case *io.LimitedReader:
-		return srcIsRegularFile(v.R)
-	default:
-		return
-	}
-}
-
-// ReadFrom is here to optimize copying from an *os.File regular file
-// to a *net.TCPConn with sendfile.
-func (w *response) ReadFrom(src io.Reader) (n int64, err error) {
-	// Our underlying w.conn.rwc is usually a *TCPConn (with its
-	// own ReadFrom method). If not, or if our src isn't a regular
-	// file, just fall back to the normal copy method.
-	rf, ok := w.conn.rwc.(io.ReaderFrom)
-	regFile, err := srcIsRegularFile(src)
-	if err != nil {
-		return 0, err
-	}
-	if !ok || !regFile {
-		return io.Copy(writerOnly{w}, src)
-	}
-
-	// sendfile path:
-
-	if !w.wroteHeader {
-		w.WriteHeader(StatusOK)
-	}
-
-	if w.needsSniff() {
-		n0, err := io.Copy(writerOnly{w}, io.LimitReader(src, sniffLen))
-		n += n0
-		if err != nil {
-			return n, err
-		}
-	}
-
-	w.w.Flush()  // get rid of any previous writes
-	w.cw.flush() // make sure Header is written; flush data to rwc
-
-	// Now that cw has been flushed, its chunking field is guaranteed initialized.
-	if !w.cw.chunking && w.bodyAllowed() {
-		n0, err := rf.ReadFrom(src)
-		n += n0
-		w.written += n0
-		return n, err
-	}
-
-	n0, err := io.Copy(writerOnly{w}, src)
-	n += n0
-	return n, err
-}
-
-// noLimit is an effective infinite upper bound for io.LimitedReader
-const noLimit int64 = (1 << 63) - 1
-
-// debugServerConnections controls whether all server connections are wrapped
-// with a verbose logging wrapper.
-const debugServerConnections = false
-
-// Create new connection from rwc.
-func (srv *Server) newConn(rwc net.Conn) (c *conn, err error) {
-	c = new(conn)
-	c.remoteAddr = rwc.RemoteAddr().String()
-	c.server = srv
-	c.rwc = rwc
-	if debugServerConnections {
-		c.rwc = newLoggingConn("server", c.rwc)
-	}
-	c.sr = liveSwitchReader{r: c.rwc}
-	c.lr = io.LimitReader(&c.sr, noLimit).(*io.LimitedReader)
-	br := newBufioReader(c.lr)
-	bw := newBufioWriterSize(c.rwc, 4<<10)
-	c.buf = bufio.NewReadWriter(br, bw)
-	return c, nil
-}
-
-var (
-	bufioReaderPool   sync.Pool
-	bufioWriter2kPool sync.Pool
-	bufioWriter4kPool sync.Pool
-)
-
-func bufioWriterPool(size int) *sync.Pool {
-	switch size {
-	case 2 << 10:
-		return &bufioWriter2kPool
-	case 4 << 10:
-		return &bufioWriter4kPool
-	}
-	return nil
-}
-
-func newBufioReader(r io.Reader) *bufio.Reader {
-	if v := bufioReaderPool.Get(); v != nil {
-		br := v.(*bufio.Reader)
-		br.Reset(r)
-		return br
-	}
-	return bufio.NewReader(r)
-}
-
-func putBufioReader(br *bufio.Reader) {
-	br.Reset(nil)
-	bufioReaderPool.Put(br)
-}
-
-func newBufioWriterSize(w io.Writer, size int) *bufio.Writer {
-	pool := bufioWriterPool(size)
-	if pool != nil {
-		if v := pool.Get(); v != nil {
-			bw := v.(*bufio.Writer)
-			bw.Reset(w)
-			return bw
-		}
-	}
-	return bufio.NewWriterSize(w, size)
-}
-
-func putBufioWriter(bw *bufio.Writer) {
-	bw.Reset(nil)
-	if pool := bufioWriterPool(bw.Available()); pool != nil {
-		pool.Put(bw)
-	}
-}
-
-// DefaultMaxHeaderBytes is the maximum permitted size of the headers
-// in an HTTP request.
-// This can be overridden by setting Server.MaxHeaderBytes.
-const DefaultMaxHeaderBytes = 1 << 20 // 1 MB
-
-func (srv *Server) maxHeaderBytes() int {
-	if srv.MaxHeaderBytes > 0 {
-		return srv.MaxHeaderBytes
-	}
-	return DefaultMaxHeaderBytes
-}
-
-func (srv *Server) initialLimitedReaderSize() int64 {
-	return int64(srv.maxHeaderBytes()) + 4096 // bufio slop
-}
-
-// wrapper around io.ReaderCloser which on first read, sends an
-// HTTP/1.1 100 Continue header
-type expectContinueReader struct {
-	resp       *response
-	readCloser io.ReadCloser
-	closed     bool
-}
-
-func (ecr *expectContinueReader) Read(p []byte) (n int, err error) {
-	if ecr.closed {
-		return 0, ErrBodyReadAfterClose
-	}
-	if !ecr.resp.wroteContinue && !ecr.resp.conn.hijacked() {
-		ecr.resp.wroteContinue = true
-		ecr.resp.conn.buf.WriteString("HTTP/1.1 100 Continue\r\n\r\n")
-		ecr.resp.conn.buf.Flush()
-	}
-	return ecr.readCloser.Read(p)
-}
-
-func (ecr *expectContinueReader) Close() error {
-	ecr.closed = true
-	return ecr.readCloser.Close()
-}
-
-// TimeFormat is the time format to use with
-// time.Parse and time.Time.Format when parsing
-// or generating times in HTTP headers.
-// It is like time.RFC1123 but hard codes GMT as the time zone.
-const TimeFormat = "Mon, 02 Jan 2006 15:04:05 GMT"
-
-// appendTime is a non-allocating version of []byte(t.UTC().Format(TimeFormat))
-func appendTime(b []byte, t time.Time) []byte {
-	const days = "SunMonTueWedThuFriSat"
-	const months = "JanFebMarAprMayJunJulAugSepOctNovDec"
-
-	t = t.UTC()
-	yy, mm, dd := t.Date()
-	hh, mn, ss := t.Clock()
-	day := days[3*t.Weekday():]
-	mon := months[3*(mm-1):]
-
-	return append(b,
-		day[0], day[1], day[2], ',', ' ',
-		byte('0'+dd/10), byte('0'+dd%10), ' ',
-		mon[0], mon[1], mon[2], ' ',
-		byte('0'+yy/1000), byte('0'+(yy/100)%10), byte('0'+(yy/10)%10), byte('0'+yy%10), ' ',
-		byte('0'+hh/10), byte('0'+hh%10), ':',
-		byte('0'+mn/10), byte('0'+mn%10), ':',
-		byte('0'+ss/10), byte('0'+ss%10), ' ',
-		'G', 'M', 'T')
-}
-
-var errTooLarge = errors.New("http: request too large")
-
-// Read next request from connection.
-func (c *conn) readRequest() (w *response, err error) {
-	if c.hijacked() {
-		return nil, ErrHijacked
-	}
-
-	if d := c.server.ReadTimeout; d != 0 {
-		c.rwc.SetReadDeadline(time.Now().Add(d))
-	}
-	if d := c.server.WriteTimeout; d != 0 {
-		defer func() {
-			c.rwc.SetWriteDeadline(time.Now().Add(d))
-		}()
-	}
-
-	c.lr.N = c.server.initialLimitedReaderSize()
-	var req *Request
-	if req, err = ReadRequest(c.buf.Reader); err != nil {
-		if c.lr.N == 0 {
-			return nil, errTooLarge
-		}
-		return nil, err
-	}
-	c.lr.N = noLimit
-
-	req.RemoteAddr = c.remoteAddr
-	req.TLS = c.tlsState
-
-	w = &response{
-		conn:          c,
-		req:           req,
-		handlerHeader: make(Header),
-		contentLength: -1,
-	}
-	w.cw.res = w
-	w.w = newBufioWriterSize(&w.cw, bufferBeforeChunkingSize)
-	return w, nil
-}
-
-func (w *response) Header() Header {
-	if w.cw.header == nil && w.wroteHeader && !w.cw.wroteHeader {
-		// Accessing the header between logically writing it
-		// and physically writing it means we need to allocate
-		// a clone to snapshot the logically written state.
-		w.cw.header = w.handlerHeader.clone()
-	}
-	w.calledHeader = true
-	return w.handlerHeader
-}
-
-// maxPostHandlerReadBytes is the max number of Request.Body bytes not
-// consumed by a handler that the server will read from the client
-// in order to keep a connection alive.  If there are more bytes than
-// this then the server to be paranoid instead sends a "Connection:
-// close" response.
-//
-// This number is approximately what a typical machine's TCP buffer
-// size is anyway.  (if we have the bytes on the machine, we might as
-// well read them)
-const maxPostHandlerReadBytes = 256 << 10
-
-func (w *response) WriteHeader(code int) {
-	if w.conn.hijacked() {
-		w.conn.server.logf("http: response.WriteHeader on hijacked connection")
-		return
-	}
-	if w.wroteHeader {
-		w.conn.server.logf("http: multiple response.WriteHeader calls")
-		return
-	}
-	w.wroteHeader = true
-	w.status = code
-
-	if w.calledHeader && w.cw.header == nil {
-		w.cw.header = w.handlerHeader.clone()
-	}
-
-	if cl := w.handlerHeader.get("Content-Length"); cl != "" {
-		v, err := strconv.ParseInt(cl, 10, 64)
-		if err == nil && v >= 0 {
-			w.contentLength = v
-		} else {
-			w.conn.server.logf("http: invalid Content-Length of %q", cl)
-			w.handlerHeader.Del("Content-Length")
-		}
-	}
-}
-
-// extraHeader is the set of headers sometimes added by chunkWriter.writeHeader.
-// This type is used to avoid extra allocations from cloning and/or populating
-// the response Header map and all its 1-element slices.
-type extraHeader struct {
-	contentType      string
-	connection       string
-	transferEncoding string
-	date             []byte // written if not nil
-	contentLength    []byte // written if not nil
-}
-
-// Sorted the same as extraHeader.Write's loop.
-var extraHeaderKeys = [][]byte{
-	[]byte("Content-Type"),
-	[]byte("Connection"),
-	[]byte("Transfer-Encoding"),
-}
-
-var (
-	headerContentLength = []byte("Content-Length: ")
-	headerDate          = []byte("Date: ")
-)
-
-// Write writes the headers described in h to w.
-//
-// This method has a value receiver, despite the somewhat large size
-// of h, because it prevents an allocation. The escape analysis isn't
-// smart enough to realize this function doesn't mutate h.
-func (h extraHeader) Write(w *bufio.Writer) {
-	if h.date != nil {
-		w.Write(headerDate)
-		w.Write(h.date)
-		w.Write(crlf)
-	}
-	if h.contentLength != nil {
-		w.Write(headerContentLength)
-		w.Write(h.contentLength)
-		w.Write(crlf)
-	}
-	for i, v := range []string{h.contentType, h.connection, h.transferEncoding} {
-		if v != "" {
-			w.Write(extraHeaderKeys[i])
-			w.Write(colonSpace)
-			w.WriteString(v)
-			w.Write(crlf)
-		}
-	}
-}
-
-// writeHeader finalizes the header sent to the client and writes it
-// to cw.res.conn.buf.
-//
-// p is not written by writeHeader, but is the first chunk of the body
-// that will be written.  It is sniffed for a Content-Type if none is
-// set explicitly.  It's also used to set the Content-Length, if the
-// total body size was small and the handler has already finished
-// running.
-func (cw *chunkWriter) writeHeader(p []byte) {
-	if cw.wroteHeader {
-		return
-	}
-	cw.wroteHeader = true
-
-	w := cw.res
-	keepAlivesEnabled := w.conn.server.doKeepAlives()
-	isHEAD := w.req.Method == "HEAD"
-
-	// header is written out to w.conn.buf below. Depending on the
-	// state of the handler, we either own the map or not. If we
-	// don't own it, the exclude map is created lazily for
-	// WriteSubset to remove headers. The setHeader struct holds
-	// headers we need to add.
-	header := cw.header
-	owned := header != nil
-	if !owned {
-		header = w.handlerHeader
-	}
-	var excludeHeader map[string]bool
-	delHeader := func(key string) {
-		if owned {
-			header.Del(key)
-			return
-		}
-		if _, ok := header[key]; !ok {
-			return
-		}
-		if excludeHeader == nil {
-			excludeHeader = make(map[string]bool)
-		}
-		excludeHeader[key] = true
-	}
-	var setHeader extraHeader
-
-	// If the handler is done but never sent a Content-Length
-	// response header and this is our first (and last) write, set
-	// it, even to zero. This helps HTTP/1.0 clients keep their
-	// "keep-alive" connections alive.
-	// Exceptions: 304/204/1xx responses never get Content-Length, and if
-	// it was a HEAD request, we don't know the difference between
-	// 0 actual bytes and 0 bytes because the handler noticed it
-	// was a HEAD request and chose not to write anything.  So for
-	// HEAD, the handler should either write the Content-Length or
-	// write non-zero bytes.  If it's actually 0 bytes and the
-	// handler never looked at the Request.Method, we just don't
-	// send a Content-Length header.
-	if w.handlerDone && bodyAllowedForStatus(w.status) && header.get("Content-Length") == "" && (!isHEAD || len(p) > 0) {
-		w.contentLength = int64(len(p))
-		setHeader.contentLength = strconv.AppendInt(cw.res.clenBuf[:0], int64(len(p)), 10)
-	}
-
-	// If this was an HTTP/1.0 request with keep-alive and we sent a
-	// Content-Length back, we can make this a keep-alive response ...
-	if w.req.wantsHttp10KeepAlive() && keepAlivesEnabled {
-		sentLength := header.get("Content-Length") != ""
-		if sentLength && header.get("Connection") == "keep-alive" {
-			w.closeAfterReply = false
-		}
-	}
-
-	// Check for a explicit (and valid) Content-Length header.
-	hasCL := w.contentLength != -1
-
-	if w.req.wantsHttp10KeepAlive() && (isHEAD || hasCL) {
-		_, connectionHeaderSet := header["Connection"]
-		if !connectionHeaderSet {
-			setHeader.connection = "keep-alive"
-		}
-	} else if !w.req.ProtoAtLeast(1, 1) || w.req.wantsClose() {
-		w.closeAfterReply = true
-	}
-
-	if header.get("Connection") == "close" || !keepAlivesEnabled {
-		w.closeAfterReply = true
-	}
-
-	// Per RFC 2616, we should consume the request body before
-	// replying, if the handler hasn't already done so.  But we
-	// don't want to do an unbounded amount of reading here for
-	// DoS reasons, so we only try up to a threshold.
-	if w.req.ContentLength != 0 && !w.closeAfterReply {
-		ecr, isExpecter := w.req.Body.(*expectContinueReader)
-		if !isExpecter || ecr.resp.wroteContinue {
-			n, _ := io.CopyN(ioutil.Discard, w.req.Body, maxPostHandlerReadBytes+1)
-			if n >= maxPostHandlerReadBytes {
-				w.requestTooLarge()
-				delHeader("Connection")
-				setHeader.connection = "close"
-			} else {
-				w.req.Body.Close()
-			}
-		}
-	}
-
-	code := w.status
-	if bodyAllowedForStatus(code) {
-		// If no content type, apply sniffing algorithm to body.
-		_, haveType := header["Content-Type"]
-		if !haveType {
-			setHeader.contentType = DetectContentType(p)
-		}
-	} else {
-		for _, k := range suppressedHeaders(code) {
-			delHeader(k)
-		}
-	}
-
-	if _, ok := header["Date"]; !ok {
-		setHeader.date = appendTime(cw.res.dateBuf[:0], time.Now())
-	}
-
-	te := header.get("Transfer-Encoding")
-	hasTE := te != ""
-	if hasCL && hasTE && te != "identity" {
-		// TODO: return an error if WriteHeader gets a return parameter
-		// For now just ignore the Content-Length.
-		w.conn.server.logf("http: WriteHeader called with both Transfer-Encoding of %q and a Content-Length of %d",
-			te, w.contentLength)
-		delHeader("Content-Length")
-		hasCL = false
-	}
-
-	if w.req.Method == "HEAD" || !bodyAllowedForStatus(code) {
-		// do nothing
-	} else if code == StatusNoContent {
-		delHeader("Transfer-Encoding")
-	} else if hasCL {
-		delHeader("Transfer-Encoding")
-	} else if w.req.ProtoAtLeast(1, 1) {
-		// HTTP/1.1 or greater: use chunked transfer encoding
-		// to avoid closing the connection at EOF.
-		// TODO: this blows away any custom or stacked Transfer-Encoding they
-		// might have set.  Deal with that as need arises once we have a valid
-		// use case.
-		cw.chunking = true
-		setHeader.transferEncoding = "chunked"
-	} else {
-		// HTTP version < 1.1: cannot do chunked transfer
-		// encoding and we don't know the Content-Length so
-		// signal EOF by closing connection.
-		w.closeAfterReply = true
-		delHeader("Transfer-Encoding") // in case already set
-	}
-
-	// Cannot use Content-Length with non-identity Transfer-Encoding.
-	if cw.chunking {
-		delHeader("Content-Length")
-	}
-	if !w.req.ProtoAtLeast(1, 0) {
-		return
-	}
-
-	if w.closeAfterReply && (!keepAlivesEnabled || !hasToken(cw.header.get("Connection"), "close")) {
-		delHeader("Connection")
-		if w.req.ProtoAtLeast(1, 1) {
-			setHeader.connection = "close"
-		}
-	}
-
-	w.conn.buf.WriteString(statusLine(w.req, code))
-	cw.header.WriteSubset(w.conn.buf, excludeHeader)
-	setHeader.Write(w.conn.buf.Writer)
-	w.conn.buf.Write(crlf)
-}
-
-// statusLines is a cache of Status-Line strings, keyed by code (for
-// HTTP/1.1) or negative code (for HTTP/1.0). This is faster than a
-// map keyed by struct of two fields. This map's max size is bounded
-// by 2*len(statusText), two protocol types for each known official
-// status code in the statusText map.
-var (
-	statusMu    sync.RWMutex
-	statusLines = make(map[int]string)
-)
-
-// statusLine returns a response Status-Line (RFC 2616 Section 6.1)
-// for the given request and response status code.
-func statusLine(req *Request, code int) string {
-	// Fast path:
-	key := code
-	proto11 := req.ProtoAtLeast(1, 1)
-	if !proto11 {
-		key = -key
-	}
-	statusMu.RLock()
-	line, ok := statusLines[key]
-	statusMu.RUnlock()
-	if ok {
-		return line
-	}
-
-	// Slow path:
-	proto := "HTTP/1.0"
-	if proto11 {
-		proto = "HTTP/1.1"
-	}
-	codestring := strconv.Itoa(code)
-	text, ok := statusText[code]
-	if !ok {
-		text = "status code " + codestring
-	}
-	line = proto + " " + codestring + " " + text + "\r\n"
-	if ok {
-		statusMu.Lock()
-		defer statusMu.Unlock()
-		statusLines[key] = line
-	}
-	return line
-}
-
-// bodyAllowed returns true if a Write is allowed for this response type.
-// It's illegal to call this before the header has been flushed.
-func (w *response) bodyAllowed() bool {
-	if !w.wroteHeader {
-		panic("")
-	}
-	return bodyAllowedForStatus(w.status)
-}
-
-// The Life Of A Write is like this:
-//
-// Handler starts. No header has been sent. The handler can either
-// write a header, or just start writing.  Writing before sending a header
-// sends an implicitly empty 200 OK header.
-//
-// If the handler didn't declare a Content-Length up front, we either
-// go into chunking mode or, if the handler finishes running before
-// the chunking buffer size, we compute a Content-Length and send that
-// in the header instead.
-//
-// Likewise, if the handler didn't set a Content-Type, we sniff that
-// from the initial chunk of output.
-//
-// The Writers are wired together like:
-//
-// 1. *response (the ResponseWriter) ->
-// 2. (*response).w, a *bufio.Writer of bufferBeforeChunkingSize bytes
-// 3. chunkWriter.Writer (whose writeHeader finalizes Content-Length/Type)
-//    and which writes the chunk headers, if needed.
-// 4. conn.buf, a bufio.Writer of default (4kB) bytes
-// 5. the rwc, the net.Conn.
-//
-// TODO(bradfitz): short-circuit some of the buffering when the
-// initial header contains both a Content-Type and Content-Length.
-// Also short-circuit in (1) when the header's been sent and not in
-// chunking mode, writing directly to (4) instead, if (2) has no
-// buffered data.  More generally, we could short-circuit from (1) to
-// (3) even in chunking mode if the write size from (1) is over some
-// threshold and nothing is in (2).  The answer might be mostly making
-// bufferBeforeChunkingSize smaller and having bufio's fast-paths deal
-// with this instead.
-func (w *response) Write(data []byte) (n int, err error) {
-	return w.write(len(data), data, "")
-}
-
-func (w *response) WriteString(data string) (n int, err error) {
-	return w.write(len(data), nil, data)
-}
-
-// either dataB or dataS is non-zero.
-func (w *response) write(lenData int, dataB []byte, dataS string) (n int, err error) {
-	if w.conn.hijacked() {
-		w.conn.server.logf("http: response.Write on hijacked connection")
-		return 0, ErrHijacked
-	}
-	if !w.wroteHeader {
-		w.WriteHeader(StatusOK)
-	}
-	if lenData == 0 {
-		return 0, nil
-	}
-	if !w.bodyAllowed() {
-		return 0, ErrBodyNotAllowed
-	}
-
-	w.written += int64(lenData) // ignoring errors, for errorKludge
-	if w.contentLength != -1 && w.written > w.contentLength {
-		return 0, ErrContentLength
-	}
-	if dataB != nil {
-		return w.w.Write(dataB)
-	} else {
-		return w.w.WriteString(dataS)
-	}
-}
-
-func (w *response) finishRequest() {
-	w.handlerDone = true
-
-	if !w.wroteHeader {
-		w.WriteHeader(StatusOK)
-	}
-
-	w.w.Flush()
-	putBufioWriter(w.w)
-	w.cw.close()
-	w.conn.buf.Flush()
-
-	// Close the body (regardless of w.closeAfterReply) so we can
-	// re-use its bufio.Reader later safely.
-	w.req.Body.Close()
-
-	if w.req.MultipartForm != nil {
-		w.req.MultipartForm.RemoveAll()
-	}
-
-	if w.req.Method != "HEAD" && w.contentLength != -1 && w.bodyAllowed() && w.contentLength != w.written {
-		// Did not write enough. Avoid getting out of sync.
-		w.closeAfterReply = true
-	}
-}
-
-func (w *response) Flush() {
-	if !w.wroteHeader {
-		w.WriteHeader(StatusOK)
-	}
-	w.w.Flush()
-	w.cw.flush()
-}
-
-func (c *conn) finalFlush() {
-	if c.buf != nil {
-		c.buf.Flush()
-
-		// Steal the bufio.Reader (~4KB worth of memory) and its associated
-		// reader for a future connection.
-		putBufioReader(c.buf.Reader)
-
-		// Steal the bufio.Writer (~4KB worth of memory) and its associated
-		// writer for a future connection.
-		putBufioWriter(c.buf.Writer)
-
-		c.buf = nil
-	}
-}
-
-// Close the connection.
-func (c *conn) close() {
-	c.finalFlush()
-	if c.rwc != nil {
-		c.rwc.Close()
-		c.rwc = nil
-	}
-}
-
-// rstAvoidanceDelay is the amount of time we sleep after closing the
-// write side of a TCP connection before closing the entire socket.
-// By sleeping, we increase the chances that the client sees our FIN
-// and processes its final data before they process the subsequent RST
-// from closing a connection with known unread data.
-// This RST seems to occur mostly on BSD systems. (And Windows?)
-// This timeout is somewhat arbitrary (~latency around the planet).
-const rstAvoidanceDelay = 500 * time.Millisecond
-
-// closeWrite flushes any outstanding data and sends a FIN packet (if
-// client is connected via TCP), signalling that we're done.  We then
-// pause for a bit, hoping the client processes it before `any
-// subsequent RST.
-//
-// See http://golang.org/issue/3595
-func (c *conn) closeWriteAndWait() {
-	c.finalFlush()
-	if tcp, ok := c.rwc.(*net.TCPConn); ok {
-		tcp.CloseWrite()
-	}
-	time.Sleep(rstAvoidanceDelay)
-}
-
-// validNPN reports whether the proto is not a blacklisted Next
-// Protocol Negotiation protocol.  Empty and built-in protocol types
-// are blacklisted and can't be overridden with alternate
-// implementations.
-func validNPN(proto string) bool {
-	switch proto {
-	case "", "http/1.1", "http/1.0":
-		return false
-	}
-	return true
-}
-
-func (c *conn) setState(nc net.Conn, state ConnState) {
-	if hook := c.server.ConnState; hook != nil {
-		hook(nc, state)
-	}
-}
-
-// Serve a new connection.
-func (c *conn) serve() {
-	origConn := c.rwc // copy it before it's set nil on Close or Hijack
-	defer func() {
-		if err := recover(); err != nil {
-			const size = 64 << 10
-			buf := make([]byte, size)
-			buf = buf[:runtime.Stack(buf, false)]
-			c.server.logf("http: panic serving %v: %v\n%s", c.remoteAddr, err, buf)
-		}
-		if !c.hijacked() {
-			c.close()
-			c.setState(origConn, StateClosed)
-		}
-	}()
-
-	if tlsConn, ok := c.rwc.(*tls.Conn); ok {
-		if d := c.server.ReadTimeout; d != 0 {
-			c.rwc.SetReadDeadline(time.Now().Add(d))
-		}
-		if d := c.server.WriteTimeout; d != 0 {
-			c.rwc.SetWriteDeadline(time.Now().Add(d))
-		}
-		if err := tlsConn.Handshake(); err != nil {
-			c.server.logf("http: TLS handshake error from %s: %v", c.rwc.RemoteAddr(), err)
-			return
-		}
-		c.tlsState = new(tls.ConnectionState)
-		*c.tlsState = tlsConn.ConnectionState()
-		if proto := c.tlsState.NegotiatedProtocol; validNPN(proto) {
-			if fn := c.server.TLSNextProto[proto]; fn != nil {
-				h := initNPNRequest{tlsConn, serverHandler{c.server}}
-				fn(c.server, tlsConn, h)
-			}
-			return
-		}
-	}
-
-	for {
-		w, err := c.readRequest()
-		if c.lr.N != c.server.initialLimitedReaderSize() {
-			// If we read any bytes off the wire, we're active.
-			c.setState(c.rwc, StateActive)
-		}
-		if err != nil {
-			if err == errTooLarge {
-				// Their HTTP client may or may not be
-				// able to read this if we're
-				// responding to them and hanging up
-				// while they're still writing their
-				// request.  Undefined behavior.
-				io.WriteString(c.rwc, "HTTP/1.1 413 Request Entity Too Large\r\n\r\n")
-				c.closeWriteAndWait()
-				break
-			} else if err == io.EOF {
-				break // Don't reply
-			} else if neterr, ok := err.(net.Error); ok && neterr.Timeout() {
-				break // Don't reply
-			}
-			io.WriteString(c.rwc, "HTTP/1.1 400 Bad Request\r\n\r\n")
-			break
-		}
-
-		// Expect 100 Continue support
-		req := w.req
-		if req.expectsContinue() {
-			if req.ProtoAtLeast(1, 1) && req.ContentLength != 0 {
-				// Wrap the Body reader with one that replies on the connection
-				req.Body = &expectContinueReader{readCloser: req.Body, resp: w}
-			}
-			req.Header.Del("Expect")
-		} else if req.Header.get("Expect") != "" {
-			w.sendExpectationFailed()
-			break
-		}
-
-		// HTTP cannot have multiple simultaneous active requests.[*]
-		// Until the server replies to this request, it can't read another,
-		// so we might as well run the handler in this goroutine.
-		// [*] Not strictly true: HTTP pipelining.  We could let them all process
-		// in parallel even if their responses need to be serialized.
-		serverHandler{c.server}.ServeHTTP(w, w.req)
-		if c.hijacked() {
-			return
-		}
-		w.finishRequest()
-		if w.closeAfterReply {
-			if w.requestBodyLimitHit {
-				c.closeWriteAndWait()
-			}
-			break
-		}
-		c.setState(c.rwc, StateIdle)
-	}
-}
-
-func (w *response) sendExpectationFailed() {
-	// TODO(bradfitz): let ServeHTTP handlers handle
-	// requests with non-standard expectation[s]? Seems
-	// theoretical at best, and doesn't fit into the
-	// current ServeHTTP model anyway.  We'd need to
-	// make the ResponseWriter an optional
-	// "ExpectReplier" interface or something.
-	//
-	// For now we'll just obey RFC 2616 14.20 which says
-	// "If a server receives a request containing an
-	// Expect field that includes an expectation-
-	// extension that it does not support, it MUST
-	// respond with a 417 (Expectation Failed) status."
-	w.Header().Set("Connection", "close")
-	w.WriteHeader(StatusExpectationFailed)
-	w.finishRequest()
-}
-
-// Hijack implements the Hijacker.Hijack method. Our response is both a ResponseWriter
-// and a Hijacker.
-func (w *response) Hijack() (rwc net.Conn, buf *bufio.ReadWriter, err error) {
-	if w.wroteHeader {
-		w.cw.flush()
-	}
-	// Release the bufioWriter that writes to the chunk writer, it is not
-	// used after a connection has been hijacked.
-	rwc, buf, err = w.conn.hijack()
-	if err == nil {
-		putBufioWriter(w.w)
-		w.w = nil
-	}
-	return rwc, buf, err
-}
-
-func (w *response) CloseNotify() <-chan bool {
-	return w.conn.closeNotify()
-}
-
-// The HandlerFunc type is an adapter to allow the use of
-// ordinary functions as HTTP handlers.  If f is a function
-// with the appropriate signature, HandlerFunc(f) is a
-// Handler object that calls f.
-type HandlerFunc func(ResponseWriter, *Request)
-
-// ServeHTTP calls f(w, r).
-func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
-	f(w, r)
-}
-
-// Helper handlers
-
-// Error replies to the request with the specified error message and HTTP code.
-// The error message should be plain text.
-func Error(w ResponseWriter, error string, code int) {
-	w.Header().Set("Content-Type", "text/plain; charset=utf-8")
-	w.WriteHeader(code)
-	fmt.Fprintln(w, error)
-}
-
-// NotFound replies to the request with an HTTP 404 not found error.
-func NotFound(w ResponseWriter, r *Request) { Error(w, "404 page not found", StatusNotFound) }
-
-// NotFoundHandler returns a simple request handler
-// that replies to each request with a ``404 page not found'' reply.
-func NotFoundHandler() Handler { return HandlerFunc(NotFound) }
-
-// StripPrefix returns a handler that serves HTTP requests
-// by removing the given prefix from the request URL's Path
-// and invoking the handler h. StripPrefix handles a
-// request for a path that doesn't begin with prefix by
-// replying with an HTTP 404 not found error.
-func StripPrefix(prefix string, h Handler) Handler {
-	if prefix == "" {
-		return h
-	}
-	return HandlerFunc(func(w ResponseWriter, r *Request) {
-		if p := strings.TrimPrefix(r.URL.Path, prefix); len(p) < len(r.URL.Path) {
-			r.URL.Path = p
-			h.ServeHTTP(w, r)
-		} else {
-			NotFound(w, r)
-		}
-	})
-}
-
-// Redirect replies to the request with a redirect to url,
-// which may be a path relative to the request path.
-func Redirect(w ResponseWriter, r *Request, urlStr string, code int) {
-	if u, err := url.Parse(urlStr); err == nil {
-		// If url was relative, make absolute by
-		// combining with request path.
-		// The browser would probably do this for us,
-		// but doing it ourselves is more reliable.
-
-		// NOTE(rsc): RFC 2616 says that the Location
-		// line must be an absolute URI, like
-		// "http://www.google.com/redirect/",
-		// not a path like "/redirect/".
-		// Unfortunately, we don't know what to
-		// put in the host name section to get the
-		// client to connect to us again, so we can't
-		// know the right absolute URI to send back.
-		// Because of this problem, no one pays attention
-		// to the RFC; they all send back just a new path.
-		// So do we.
-		oldpath := r.URL.Path
-		if oldpath == "" { // should not happen, but avoid a crash if it does
-			oldpath = "/"
-		}
-		if u.Scheme == "" {
-			// no leading http://server
-			if urlStr == "" || urlStr[0] != '/' {
-				// make relative path absolute
-				olddir, _ := path.Split(oldpath)
-				urlStr = olddir + urlStr
-			}
-
-			var query string
-			if i := strings.Index(urlStr, "?"); i != -1 {
-				urlStr, query = urlStr[:i], urlStr[i:]
-			}
-
-			// clean up but preserve trailing slash
-			trailing := strings.HasSuffix(urlStr, "/")
-			urlStr = path.Clean(urlStr)
-			if trailing && !strings.HasSuffix(urlStr, "/") {
-				urlStr += "/"
-			}
-			urlStr += query
-		}
-	}
-
-	w.Header().Set("Location", urlStr)
-	w.WriteHeader(code)
-
-	// RFC2616 recommends that a short note "SHOULD" be included in the
-	// response because older user agents may not understand 301/307.
-	// Shouldn't send the response for POST or HEAD; that leaves GET.
-	if r.Method == "GET" {
-		note := "<a href=\"" + htmlEscape(urlStr) + "\">" + statusText[code] + "</a>.\n"
-		fmt.Fprintln(w, note)
-	}
-}
-
-var htmlReplacer = strings.NewReplacer(
-	"&", "&",
-	"<", "<",
-	">", ">",
-	// """ is shorter than """.
-	`"`, """,
-	// "'" is shorter than "'" and apos was not in HTML until HTML5.
-	"'", "'",
-)
-
-func htmlEscape(s string) string {
-	return htmlReplacer.Replace(s)
-}
-
-// Redirect to a fixed URL
-type redirectHandler struct {
-	url  string
-	code int
-}
-
-func (rh *redirectHandler) ServeHTTP(w ResponseWriter, r *Request) {
-	Redirect(w, r, rh.url, rh.code)
-}
-
-// RedirectHandler returns a request handler that redirects
-// each request it receives to the given url using the given
-// status code.
-func RedirectHandler(url string, code int) Handler {
-	return &redirectHandler{url, code}
-}
-
-// ServeMux is an HTTP request multiplexer.
-// It matches the URL of each incoming request against a list of registered
-// patterns and calls the handler for the pattern that
-// most closely matches the URL.
-//
-// Patterns name fixed, rooted paths, like "/favicon.ico",
-// or rooted subtrees, like "/images/" (note the trailing slash).
-// Longer patterns take precedence over shorter ones, so that
-// if there are handlers registered for both "/images/"
-// and "/images/thumbnails/", the latter handler will be
-// called for paths beginning "/images/thumbnails/" and the
-// former will receive requests for any other paths in the
-// "/images/" subtree.
-//
-// Note that since a pattern ending in a slash names a rooted subtree,
-// the pattern "/" matches all paths not matched by other registered
-// patterns, not just the URL with Path == "/".
-//
-// Patterns may optionally begin with a host name, restricting matches to
-// URLs on that host only.  Host-specific patterns take precedence over
-// general patterns, so that a handler might register for the two patterns
-// "/codesearch" and "codesearch.google.com/" without also taking over
-// requests for "http://www.google.com/".
-//
-// ServeMux also takes care of sanitizing the URL request path,
-// redirecting any request containing . or .. elements to an
-// equivalent .- and ..-free URL.
-type ServeMux struct {
-	mu    sync.RWMutex
-	m     map[string]muxEntry
-	hosts bool // whether any patterns contain hostnames
-}
-
-type muxEntry struct {
-	explicit bool
-	h        Handler
-	pattern  string
-}
-
-// NewServeMux allocates and returns a new ServeMux.
-func NewServeMux() *ServeMux { return &ServeMux{m: make(map[string]muxEntry)} }
-
-// DefaultServeMux is the default ServeMux used by Serve.
-var DefaultServeMux = NewServeMux()
-
-// Does path match pattern?
-func pathMatch(pattern, path string) bool {
-	if len(pattern) == 0 {
-		// should not happen
-		return false
-	}
-	n := len(pattern)
-	if pattern[n-1] != '/' {
-		return pattern == path
-	}
-	return len(path) >= n && path[0:n] == pattern
-}
-
-// Return the canonical path for p, eliminating . and .. elements.
-func cleanPath(p string) string {
-	if p == "" {
-		return "/"
-	}
-	if p[0] != '/' {
-		p = "/" + p
-	}
-	np := path.Clean(p)
-	// path.Clean removes trailing slash except for root;
-	// put the trailing slash back if necessary.
-	if p[len(p)-1] == '/' && np != "/" {
-		np += "/"
-	}
-	return np
-}
-
-// Find a handler on a handler map given a path string
-// Most-specific (longest) pattern wins
-func (mux *ServeMux) match(path string) (h Handler, pattern string) {
-	var n = 0
-	for k, v := range mux.m {
-		if !pathMatch(k, path) {
-			continue
-		}
-		if h == nil || len(k) > n {
-			n = len(k)
-			h = v.h
-			pattern = v.pattern
-		}
-	}
-	return
-}
-
-// Handler returns the handler to use for the given request,
-// consulting r.Method, r.Host, and r.URL.Path. It always returns
-// a non-nil handler. If the path is not in its canonical form, the
-// handler will be an internally-generated handler that redirects
-// to the canonical path.
-//
-// Handler also returns the registered pattern that matches the
-// request or, in the case of internally-generated redirects,
-// the pattern that will match after following the redirect.
-//
-// If there is no registered handler that applies to the request,
-// Handler returns a ``page not found'' handler and an empty pattern.
-func (mux *ServeMux) Handler(r *Request) (h Handler, pattern string) {
-	if r.Method != "CONNECT" {
-		if p := cleanPath(r.URL.Path); p != r.URL.Path {
-			_, pattern = mux.handler(r.Host, p)
-			url := *r.URL
-			url.Path = p
-			return RedirectHandler(url.String(), StatusMovedPermanently), pattern
-		}
-	}
-
-	return mux.handler(r.Host, r.URL.Path)
-}
-
-// handler is the main implementation of Handler.
-// The path is known to be in canonical form, except for CONNECT methods.
-func (mux *ServeMux) handler(host, path string) (h Handler, pattern string) {
-	mux.mu.RLock()
-	defer mux.mu.RUnlock()
-
-	// Host-specific pattern takes precedence over generic ones
-	if mux.hosts {
-		h, pattern = mux.match(host + path)
-	}
-	if h == nil {
-		h, pattern = mux.match(path)
-	}
-	if h == nil {
-		h, pattern = NotFoundHandler(), ""
-	}
-	return
-}
-
-// ServeHTTP dispatches the request to the handler whose
-// pattern most closely matches the request URL.
-func (mux *ServeMux) ServeHTTP(w ResponseWriter, r *Request) {
-	if r.RequestURI == "*" {
-		if r.ProtoAtLeast(1, 1) {
-			w.Header().Set("Connection", "close")
-		}
-		w.WriteHeader(StatusBadRequest)
-		return
-	}
-	h, _ := mux.Handler(r)
-	h.ServeHTTP(w, r)
-}
-
-// Handle registers the handler for the given pattern.
-// If a handler already exists for pattern, Handle panics.
-func (mux *ServeMux) Handle(pattern string, handler Handler) {
-	mux.mu.Lock()
-	defer mux.mu.Unlock()
-
-	if pattern == "" {
-		panic("http: invalid pattern " + pattern)
-	}
-	if handler == nil {
-		panic("http: nil handler")
-	}
-	if mux.m[pattern].explicit {
-		panic("http: multiple registrations for " + pattern)
-	}
-
-	mux.m[pattern] = muxEntry{explicit: true, h: handler, pattern: pattern}
-
-	if pattern[0] != '/' {
-		mux.hosts = true
-	}
-
-	// Helpful behavior:
-	// If pattern is /tree/, insert an implicit permanent redirect for /tree.
-	// It can be overridden by an explicit registration.
-	n := len(pattern)
-	if n > 0 && pattern[n-1] == '/' && !mux.m[pattern[0:n-1]].explicit {
-		// If pattern contains a host name, strip it and use remaining
-		// path for redirect.
-		path := pattern
-		if pattern[0] != '/' {
-			// In pattern, at least the last character is a '/', so
-			// strings.Index can't be -1.
-			path = pattern[strings.Index(pattern, "/"):]
-		}
-		mux.m[pattern[0:n-1]] = muxEntry{h: RedirectHandler(path, StatusMovedPermanently), pattern: pattern}
-	}
-}
-
-// HandleFunc registers the handler function for the given pattern.
-func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
-	mux.Handle(pattern, HandlerFunc(handler))
-}
-
-// Handle registers the handler for the given pattern
-// in the DefaultServeMux.
-// The documentation for ServeMux explains how patterns are matched.
-func Handle(pattern string, handler Handler) { DefaultServeMux.Handle(pattern, handler) }
-
-// HandleFunc registers the handler function for the given pattern
-// in the DefaultServeMux.
-// The documentation for ServeMux explains how patterns are matched.
-func HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
-	DefaultServeMux.HandleFunc(pattern, handler)
-}
-
-// Serve accepts incoming HTTP connections on the listener l,
-// creating a new service goroutine for each.  The service goroutines
-// read requests and then call handler to reply to them.
-// Handler is typically nil, in which case the DefaultServeMux is used.
-func Serve(l net.Listener, handler Handler) error {
-	srv := &Server{Handler: handler}
-	return srv.Serve(l)
-}
-
-// A Server defines parameters for running an HTTP server.
-// The zero value for Server is a valid configuration.
-type Server struct {
-	Addr           string        // TCP address to listen on, ":http" if empty
-	Handler        Handler       // handler to invoke, http.DefaultServeMux if nil
-	ReadTimeout    time.Duration // maximum duration before timing out read of the request
-	WriteTimeout   time.Duration // maximum duration before timing out write of the response
-	MaxHeaderBytes int           // maximum size of request headers, DefaultMaxHeaderBytes if 0
-	TLSConfig      *tls.Config   // optional TLS config, used by ListenAndServeTLS
-
-	// TLSNextProto optionally specifies a function to take over
-	// ownership of the provided TLS connection when an NPN
-	// protocol upgrade has occurred.  The map key is the protocol
-	// name negotiated. The Handler argument should be used to
-	// handle HTTP requests and will initialize the Request's TLS
-	// and RemoteAddr if not already set.  The connection is
-	// automatically closed when the function returns.
-	TLSNextProto map[string]func(*Server, *tls.Conn, Handler)
-
-	// ConnState specifies an optional callback function that is
-	// called when a client connection changes state. See the
-	// ConnState type and associated constants for details.
-	ConnState func(net.Conn, ConnState)
-
-	// ErrorLog specifies an optional logger for errors accepting
-	// connections and unexpected behavior from handlers.
-	// If nil, logging goes to os.Stderr via the log package's
-	// standard logger.
-	ErrorLog *log.Logger
-
-	disableKeepAlives int32 // accessed atomically.
-}
-
-// A ConnState represents the state of a client connection to a server.
-// It's used by the optional Server.ConnState hook.
-type ConnState int
-
-const (
-	// StateNew represents a new connection that is expected to
-	// send a request immediately. Connections begin at this
-	// state and then transition to either StateActive or
-	// StateClosed.
-	StateNew ConnState = iota
-
-	// StateActive represents a connection that has read 1 or more
-	// bytes of a request. The Server.ConnState hook for
-	// StateActive fires before the request has entered a handler
-	// and doesn't fire again until the request has been
-	// handled. After the request is handled, the state
-	// transitions to StateClosed, StateHijacked, or StateIdle.
-	StateActive
-
-	// StateIdle represents a connection that has finished
-	// handling a request and is in the keep-alive state, waiting
-	// for a new request. Connections transition from StateIdle
-	// to either StateActive or StateClosed.
-	StateIdle
-
-	// StateHijacked represents a hijacked connection.
-	// This is a terminal state. It does not transition to StateClosed.
-	StateHijacked
-
-	// StateClosed represents a closed connection.
-	// This is a terminal state. Hijacked connections do not
-	// transition to StateClosed.
-	StateClosed
-)
-
-var stateName = map[ConnState]string{
-	StateNew:      "new",
-	StateActive:   "active",
-	StateIdle:     "idle",
-	StateHijacked: "hijacked",
-	StateClosed:   "closed",
-}
-
-func (c ConnState) String() string {
-	return stateName[c]
-}
-
-// serverHandler delegates to either the server's Handler or
-// DefaultServeMux and also handles "OPTIONS *" requests.
-type serverHandler struct {
-	srv *Server
-}
-
-func (sh serverHandler) ServeHTTP(rw ResponseWriter, req *Request) {
-	handler := sh.srv.Handler
-	if handler == nil {
-		handler = DefaultServeMux
-	}
-	if req.RequestURI == "*" && req.Method == "OPTIONS" {
-		handler = globalOptionsHandler{}
-	}
-	handler.ServeHTTP(rw, req)
-}
-
-// ListenAndServe listens on the TCP network address srv.Addr and then
-// calls Serve to handle requests on incoming connections.  If
-// srv.Addr is blank, ":http" is used.
-func (srv *Server) ListenAndServe() error {
-	addr := srv.Addr
-	if addr == "" {
-		addr = ":http"
-	}
-	ln, err := net.Listen("tcp", addr)
-	if err != nil {
-		return err
-	}
-	return srv.Serve(tcpKeepAliveListener{ln.(*net.TCPListener)})
-}
-
-// Serve accepts incoming connections on the Listener l, creating a
-// new service goroutine for each.  The service goroutines read requests and
-// then call srv.Handler to reply to them.
-func (srv *Server) Serve(l net.Listener) error {
-	defer l.Close()
-	var tempDelay time.Duration // how long to sleep on accept failure
-	for {
-		rw, e := l.Accept()
-		if e != nil {
-			if ne, ok := e.(net.Error); ok && ne.Temporary() {
-				if tempDelay == 0 {
-					tempDelay = 5 * time.Millisecond
-				} else {
-					tempDelay *= 2
-				}
-				if max := 1 * time.Second; tempDelay > max {
-					tempDelay = max
-				}
-				srv.logf("http: Accept error: %v; retrying in %v", e, tempDelay)
-				time.Sleep(tempDelay)
-				continue
-			}
-			return e
-		}
-		tempDelay = 0
-		c, err := srv.newConn(rw)
-		if err != nil {
-			continue
-		}
-		c.setState(c.rwc, StateNew) // before Serve can return
-		go c.serve()
-	}
-}
-
-func (s *Server) doKeepAlives() bool {
-	return atomic.LoadInt32(&s.disableKeepAlives) == 0
-}
-
-// SetKeepAlivesEnabled controls whether HTTP keep-alives are enabled.
-// By default, keep-alives are always enabled. Only very
-// resource-constrained environments or servers in the process of
-// shutting down should disable them.
-func (s *Server) SetKeepAlivesEnabled(v bool) {
-	if v {
-		atomic.StoreInt32(&s.disableKeepAlives, 0)
-	} else {
-		atomic.StoreInt32(&s.disableKeepAlives, 1)
-	}
-}
-
-func (s *Server) logf(format string, args ...interface{}) {
-	if s.ErrorLog != nil {
-		s.ErrorLog.Printf(format, args...)
-	} else {
-		log.Printf(format, args...)
-	}
-}
-
-// ListenAndServe listens on the TCP network address addr
-// and then calls Serve with handler to handle requests
-// on incoming connections.  Handler is typically nil,
-// in which case the DefaultServeMux is used.
-//
-// A trivial example server is:
-//
-//	package main
-//
-//	import (
-//		"io"
-//		"net/http"
-//		"log"
-//	)
-//
-//	// hello world, the web server
-//	func HelloServer(w http.ResponseWriter, req *http.Request) {
-//		io.WriteString(w, "hello, world!\n")
-//	}
-//
-//	func main() {
-//		http.HandleFunc("/hello", HelloServer)
-//		err := http.ListenAndServe(":12345", nil)
-//		if err != nil {
-//			log.Fatal("ListenAndServe: ", err)
-//		}
-//	}
-func ListenAndServe(addr string, handler Handler) error {
-	server := &Server{Addr: addr, Handler: handler}
-	return server.ListenAndServe()
-}
-
-// ListenAndServeTLS acts identically to ListenAndServe, except that it
-// expects HTTPS connections. Additionally, files containing a certificate and
-// matching private key for the server must be provided. If the certificate
-// is signed by a certificate authority, the certFile should be the concatenation
-// of the server's certificate followed by the CA's certificate.
-//
-// A trivial example server is:
-//
-//	import (
-//		"log"
-//		"net/http"
-//	)
-//
-//	func handler(w http.ResponseWriter, req *http.Request) {
-//		w.Header().Set("Content-Type", "text/plain")
-//		w.Write([]byte("This is an example server.\n"))
-//	}
-//
-//	func main() {
-//		http.HandleFunc("/", handler)
-//		log.Printf("About to listen on 10443. Go to https://127.0.0.1:10443/")
-//		err := http.ListenAndServeTLS(":10443", "cert.pem", "key.pem", nil)
-//		if err != nil {
-//			log.Fatal(err)
-//		}
-//	}
-//
-// One can use generate_cert.go in crypto/tls to generate cert.pem and key.pem.
-func ListenAndServeTLS(addr string, certFile string, keyFile string, handler Handler) error {
-	server := &Server{Addr: addr, Handler: handler}
-	return server.ListenAndServeTLS(certFile, keyFile)
-}
-
-// ListenAndServeTLS listens on the TCP network address srv.Addr and
-// then calls Serve to handle requests on incoming TLS connections.
-//
-// Filenames containing a certificate and matching private key for
-// the server must be provided. If the certificate is signed by a
-// certificate authority, the certFile should be the concatenation
-// of the server's certificate followed by the CA's certificate.
-//
-// If srv.Addr is blank, ":https" is used.
-func (srv *Server) ListenAndServeTLS(certFile, keyFile string) error {
-	addr := srv.Addr
-	if addr == "" {
-		addr = ":https"
-	}
-	config := &tls.Config{}
-	if srv.TLSConfig != nil {
-		*config = *srv.TLSConfig
-	}
-	if config.NextProtos == nil {
-		config.NextProtos = []string{"http/1.1"}
-	}
-
-	var err error
-	config.Certificates = make([]tls.Certificate, 1)
-	config.Certificates[0], err = tls.LoadX509KeyPair(certFile, keyFile)
-	if err != nil {
-		return err
-	}
-
-	ln, err := net.Listen("tcp", addr)
-	if err != nil {
-		return err
-	}
-
-	tlsListener := tls.NewListener(tcpKeepAliveListener{ln.(*net.TCPListener)}, config)
-	return srv.Serve(tlsListener)
-}
-
-// TimeoutHandler returns a Handler that runs h with the given time limit.
-//
-// The new Handler calls h.ServeHTTP to handle each request, but if a
-// call runs for longer than its time limit, the handler responds with
-// a 503 Service Unavailable error and the given message in its body.
-// (If msg is empty, a suitable default message will be sent.)
-// After such a timeout, writes by h to its ResponseWriter will return
-// ErrHandlerTimeout.
-func TimeoutHandler(h Handler, dt time.Duration, msg string) Handler {
-	f := func() <-chan time.Time {
-		return time.After(dt)
-	}
-	return &timeoutHandler{h, f, msg}
-}
-
-// ErrHandlerTimeout is returned on ResponseWriter Write calls
-// in handlers which have timed out.
-var ErrHandlerTimeout = errors.New("http: Handler timeout")
-
-type timeoutHandler struct {
-	handler Handler
-	timeout func() <-chan time.Time // returns channel producing a timeout
-	body    string
-}
-
-func (h *timeoutHandler) errorBody() string {
-	if h.body != "" {
-		return h.body
-	}
-	return "<html><head><title>Timeout</title></head><body><h1>Timeout</h1></body></html>"
-}
-
-func (h *timeoutHandler) ServeHTTP(w ResponseWriter, r *Request) {
-	done := make(chan bool, 1)
-	tw := &timeoutWriter{w: w}
-	go func() {
-		h.handler.ServeHTTP(tw, r)
-		done <- true
-	}()
-	select {
-	case <-done:
-		return
-	case <-h.timeout():
-		tw.mu.Lock()
-		defer tw.mu.Unlock()
-		if !tw.wroteHeader {
-			tw.w.WriteHeader(StatusServiceUnavailable)
-			tw.w.Write([]byte(h.errorBody()))
-		}
-		tw.timedOut = true
-	}
-}
-
-type timeoutWriter struct {
-	w ResponseWriter
-
-	mu          sync.Mutex
-	timedOut    bool
-	wroteHeader bool
-}
-
-func (tw *timeoutWriter) Header() Header {
-	return tw.w.Header()
-}
-
-func (tw *timeoutWriter) Write(p []byte) (int, error) {
-	tw.mu.Lock()
-	timedOut := tw.timedOut
-	tw.mu.Unlock()
-	if timedOut {
-		return 0, ErrHandlerTimeout
-	}
-	return tw.w.Write(p)
-}
-
-func (tw *timeoutWriter) WriteHeader(code int) {
-	tw.mu.Lock()
-	if tw.timedOut || tw.wroteHeader {
-		tw.mu.Unlock()
-		return
-	}
-	tw.wroteHeader = true
-	tw.mu.Unlock()
-	tw.w.WriteHeader(code)
-}
-
-// tcpKeepAliveListener sets TCP keep-alive timeouts on accepted
-// connections. It's used by ListenAndServe and ListenAndServeTLS so
-// dead TCP connections (e.g. closing laptop mid-download) eventually
-// go away.
-type tcpKeepAliveListener struct {
-	*net.TCPListener
-}
-
-func (ln tcpKeepAliveListener) Accept() (c net.Conn, err error) {
-	tc, err := ln.AcceptTCP()
-	if err != nil {
-		return
-	}
-	tc.SetKeepAlive(true)
-	tc.SetKeepAlivePeriod(3 * time.Minute)
-	return tc, nil
-}
-
-// globalOptionsHandler responds to "OPTIONS *" requests.
-type globalOptionsHandler struct{}
-
-func (globalOptionsHandler) ServeHTTP(w ResponseWriter, r *Request) {
-	w.Header().Set("Content-Length", "0")
-	if r.ContentLength != 0 {
-		// Read up to 4KB of OPTIONS body (as mentioned in the
-		// spec as being reserved for future use), but anything
-		// over that is considered a waste of server resources
-		// (or an attack) and we abort and close the connection,
-		// courtesy of MaxBytesReader's EOF behavior.
-		mb := MaxBytesReader(w, r.Body, 4<<10)
-		io.Copy(ioutil.Discard, mb)
-	}
-}
-
-type eofReaderWithWriteTo struct{}
-
-func (eofReaderWithWriteTo) WriteTo(io.Writer) (int64, error) { return 0, nil }
-func (eofReaderWithWriteTo) Read([]byte) (int, error)         { return 0, io.EOF }
-
-// eofReader is a non-nil io.ReadCloser that always returns EOF.
-// It has a WriteTo method so io.Copy won't need a buffer.
-var eofReader = &struct {
-	eofReaderWithWriteTo
-	io.Closer
-}{
-	eofReaderWithWriteTo{},
-	ioutil.NopCloser(nil),
-}
-
-// Verify that an io.Copy from an eofReader won't require a buffer.
-var _ io.WriterTo = eofReader
-
-// initNPNRequest is an HTTP handler that initializes certain
-// uninitialized fields in its *Request. Such partially-initialized
-// Requests come from NPN protocol handlers.
-type initNPNRequest struct {
-	c *tls.Conn
-	h serverHandler
-}
-
-func (h initNPNRequest) ServeHTTP(rw ResponseWriter, req *Request) {
-	if req.TLS == nil {
-		req.TLS = &tls.ConnectionState{}
-		*req.TLS = h.c.ConnectionState()
-	}
-	if req.Body == nil {
-		req.Body = eofReader
-	}
-	if req.RemoteAddr == "" {
-		req.RemoteAddr = h.c.RemoteAddr().String()
-	}
-	h.h.ServeHTTP(rw, req)
-}
-
-// loggingConn is used for debugging.
-type loggingConn struct {
-	name string
-	net.Conn
-}
-
-var (
-	uniqNameMu   sync.Mutex
-	uniqNameNext = make(map[string]int)
-)
-
-func newLoggingConn(baseName string, c net.Conn) net.Conn {
-	uniqNameMu.Lock()
-	defer uniqNameMu.Unlock()
-	uniqNameNext[baseName]++
-	return &loggingConn{
-		name: fmt.Sprintf("%s-%d", baseName, uniqNameNext[baseName]),
-		Conn: c,
-	}
-}
-
-func (c *loggingConn) Write(p []byte) (n int, err error) {
-	log.Printf("%s.Write(%d) = ....", c.name, len(p))
-	n, err = c.Conn.Write(p)
-	log.Printf("%s.Write(%d) = %d, %v", c.name, len(p), n, err)
-	return
-}
-
-func (c *loggingConn) Read(p []byte) (n int, err error) {
-	log.Printf("%s.Read(%d) = ....", c.name, len(p))
-	n, err = c.Conn.Read(p)
-	log.Printf("%s.Read(%d) = %d, %v", c.name, len(p), n, err)
-	return
-}
-
-func (c *loggingConn) Close() (err error) {
-	log.Printf("%s.Close() = ...", c.name)
-	err = c.Conn.Close()
-	log.Printf("%s.Close() = %v", c.name, err)
-	return
-}
diff --git a/src/pkg/net/http/transfer.go b/src/pkg/net/http/transfer.go
deleted file mode 100644
index 7f63686..0000000
--- a/src/pkg/net/http/transfer.go
+++ /dev/null
@@ -1,730 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package http
-
-import (
-	"bufio"
-	"bytes"
-	"errors"
-	"fmt"
-	"io"
-	"io/ioutil"
-	"net/textproto"
-	"sort"
-	"strconv"
-	"strings"
-	"sync"
-)
-
-type errorReader struct {
-	err error
-}
-
-func (r *errorReader) Read(p []byte) (n int, err error) {
-	return 0, r.err
-}
-
-// transferWriter inspects the fields of a user-supplied Request or Response,
-// sanitizes them without changing the user object and provides methods for
-// writing the respective header, body and trailer in wire format.
-type transferWriter struct {
-	Method           string
-	Body             io.Reader
-	BodyCloser       io.Closer
-	ResponseToHEAD   bool
-	ContentLength    int64 // -1 means unknown, 0 means exactly none
-	Close            bool
-	TransferEncoding []string
-	Trailer          Header
-}
-
-func newTransferWriter(r interface{}) (t *transferWriter, err error) {
-	t = &transferWriter{}
-
-	// Extract relevant fields
-	atLeastHTTP11 := false
-	switch rr := r.(type) {
-	case *Request:
-		if rr.ContentLength != 0 && rr.Body == nil {
-			return nil, fmt.Errorf("http: Request.ContentLength=%d with nil Body", rr.ContentLength)
-		}
-		t.Method = rr.Method
-		t.Body = rr.Body
-		t.BodyCloser = rr.Body
-		t.ContentLength = rr.ContentLength
-		t.Close = rr.Close
-		t.TransferEncoding = rr.TransferEncoding
-		t.Trailer = rr.Trailer
-		atLeastHTTP11 = rr.ProtoAtLeast(1, 1)
-		if t.Body != nil && len(t.TransferEncoding) == 0 && atLeastHTTP11 {
-			if t.ContentLength == 0 {
-				// Test to see if it's actually zero or just unset.
-				var buf [1]byte
-				n, rerr := io.ReadFull(t.Body, buf[:])
-				if rerr != nil && rerr != io.EOF {
-					t.ContentLength = -1
-					t.Body = &errorReader{rerr}
-				} else if n == 1 {
-					// Oh, guess there is data in this Body Reader after all.
-					// The ContentLength field just wasn't set.
-					// Stich the Body back together again, re-attaching our
-					// consumed byte.
-					t.ContentLength = -1
-					t.Body = io.MultiReader(bytes.NewReader(buf[:]), t.Body)
-				} else {
-					// Body is actually empty.
-					t.Body = nil
-					t.BodyCloser = nil
-				}
-			}
-			if t.ContentLength < 0 {
-				t.TransferEncoding = []string{"chunked"}
-			}
-		}
-	case *Response:
-		if rr.Request != nil {
-			t.Method = rr.Request.Method
-		}
-		t.Body = rr.Body
-		t.BodyCloser = rr.Body
-		t.ContentLength = rr.ContentLength
-		t.Close = rr.Close
-		t.TransferEncoding = rr.TransferEncoding
-		t.Trailer = rr.Trailer
-		atLeastHTTP11 = rr.ProtoAtLeast(1, 1)
-		t.ResponseToHEAD = noBodyExpected(t.Method)
-	}
-
-	// Sanitize Body,ContentLength,TransferEncoding
-	if t.ResponseToHEAD {
-		t.Body = nil
-		if chunked(t.TransferEncoding) {
-			t.ContentLength = -1
-		}
-	} else {
-		if !atLeastHTTP11 || t.Body == nil {
-			t.TransferEncoding = nil
-		}
-		if chunked(t.TransferEncoding) {
-			t.ContentLength = -1
-		} else if t.Body == nil { // no chunking, no body
-			t.ContentLength = 0
-		}
-	}
-
-	// Sanitize Trailer
-	if !chunked(t.TransferEncoding) {
-		t.Trailer = nil
-	}
-
-	return t, nil
-}
-
-func noBodyExpected(requestMethod string) bool {
-	return requestMethod == "HEAD"
-}
-
-func (t *transferWriter) shouldSendContentLength() bool {
-	if chunked(t.TransferEncoding) {
-		return false
-	}
-	if t.ContentLength > 0 {
-		return true
-	}
-	// Many servers expect a Content-Length for these methods
-	if t.Method == "POST" || t.Method == "PUT" {
-		return true
-	}
-	if t.ContentLength == 0 && isIdentity(t.TransferEncoding) {
-		return true
-	}
-
-	return false
-}
-
-func (t *transferWriter) WriteHeader(w io.Writer) error {
-	if t.Close {
-		if _, err := io.WriteString(w, "Connection: close\r\n"); err != nil {
-			return err
-		}
-	}
-
-	// Write Content-Length and/or Transfer-Encoding whose values are a
-	// function of the sanitized field triple (Body, ContentLength,
-	// TransferEncoding)
-	if t.shouldSendContentLength() {
-		if _, err := io.WriteString(w, "Content-Length: "); err != nil {
-			return err
-		}
-		if _, err := io.WriteString(w, strconv.FormatInt(t.ContentLength, 10)+"\r\n"); err != nil {
-			return err
-		}
-	} else if chunked(t.TransferEncoding) {
-		if _, err := io.WriteString(w, "Transfer-Encoding: chunked\r\n"); err != nil {
-			return err
-		}
-	}
-
-	// Write Trailer header
-	if t.Trailer != nil {
-		keys := make([]string, 0, len(t.Trailer))
-		for k := range t.Trailer {
-			k = CanonicalHeaderKey(k)
-			switch k {
-			case "Transfer-Encoding", "Trailer", "Content-Length":
-				return &badStringError{"invalid Trailer key", k}
-			}
-			keys = append(keys, k)
-		}
-		if len(keys) > 0 {
-			sort.Strings(keys)
-			// TODO: could do better allocation-wise here, but trailers are rare,
-			// so being lazy for now.
-			if _, err := io.WriteString(w, "Trailer: "+strings.Join(keys, ",")+"\r\n"); err != nil {
-				return err
-			}
-		}
-	}
-
-	return nil
-}
-
-func (t *transferWriter) WriteBody(w io.Writer) error {
-	var err error
-	var ncopy int64
-
-	// Write body
-	if t.Body != nil {
-		if chunked(t.TransferEncoding) {
-			cw := newChunkedWriter(w)
-			_, err = io.Copy(cw, t.Body)
-			if err == nil {
-				err = cw.Close()
-			}
-		} else if t.ContentLength == -1 {
-			ncopy, err = io.Copy(w, t.Body)
-		} else {
-			ncopy, err = io.Copy(w, io.LimitReader(t.Body, t.ContentLength))
-			if err != nil {
-				return err
-			}
-			var nextra int64
-			nextra, err = io.Copy(ioutil.Discard, t.Body)
-			ncopy += nextra
-		}
-		if err != nil {
-			return err
-		}
-		if err = t.BodyCloser.Close(); err != nil {
-			return err
-		}
-	}
-
-	if !t.ResponseToHEAD && t.ContentLength != -1 && t.ContentLength != ncopy {
-		return fmt.Errorf("http: Request.ContentLength=%d with Body length %d",
-			t.ContentLength, ncopy)
-	}
-
-	// TODO(petar): Place trailer writer code here.
-	if chunked(t.TransferEncoding) {
-		// Write Trailer header
-		if t.Trailer != nil {
-			if err := t.Trailer.Write(w); err != nil {
-				return err
-			}
-		}
-		// Last chunk, empty trailer
-		_, err = io.WriteString(w, "\r\n")
-	}
-	return err
-}
-
-type transferReader struct {
-	// Input
-	Header        Header
-	StatusCode    int
-	RequestMethod string
-	ProtoMajor    int
-	ProtoMinor    int
-	// Output
-	Body             io.ReadCloser
-	ContentLength    int64
-	TransferEncoding []string
-	Close            bool
-	Trailer          Header
-}
-
-// bodyAllowedForStatus reports whether a given response status code
-// permits a body.  See RFC2616, section 4.4.
-func bodyAllowedForStatus(status int) bool {
-	switch {
-	case status >= 100 && status <= 199:
-		return false
-	case status == 204:
-		return false
-	case status == 304:
-		return false
-	}
-	return true
-}
-
-var (
-	suppressedHeaders304    = []string{"Content-Type", "Content-Length", "Transfer-Encoding"}
-	suppressedHeadersNoBody = []string{"Content-Length", "Transfer-Encoding"}
-)
-
-func suppressedHeaders(status int) []string {
-	switch {
-	case status == 304:
-		// RFC 2616 section 10.3.5: "the response MUST NOT include other entity-headers"
-		return suppressedHeaders304
-	case !bodyAllowedForStatus(status):
-		return suppressedHeadersNoBody
-	}
-	return nil
-}
-
-// msg is *Request or *Response.
-func readTransfer(msg interface{}, r *bufio.Reader) (err error) {
-	t := &transferReader{RequestMethod: "GET"}
-
-	// Unify input
-	isResponse := false
-	switch rr := msg.(type) {
-	case *Response:
-		t.Header = rr.Header
-		t.StatusCode = rr.StatusCode
-		t.ProtoMajor = rr.ProtoMajor
-		t.ProtoMinor = rr.ProtoMinor
-		t.Close = shouldClose(t.ProtoMajor, t.ProtoMinor, t.Header)
-		isResponse = true
-		if rr.Request != nil {
-			t.RequestMethod = rr.Request.Method
-		}
-	case *Request:
-		t.Header = rr.Header
-		t.ProtoMajor = rr.ProtoMajor
-		t.ProtoMinor = rr.ProtoMinor
-		// Transfer semantics for Requests are exactly like those for
-		// Responses with status code 200, responding to a GET method
-		t.StatusCode = 200
-	default:
-		panic("unexpected type")
-	}
-
-	// Default to HTTP/1.1
-	if t.ProtoMajor == 0 && t.ProtoMinor == 0 {
-		t.ProtoMajor, t.ProtoMinor = 1, 1
-	}
-
-	// Transfer encoding, content length
-	t.TransferEncoding, err = fixTransferEncoding(t.RequestMethod, t.Header)
-	if err != nil {
-		return err
-	}
-
-	realLength, err := fixLength(isResponse, t.StatusCode, t.RequestMethod, t.Header, t.TransferEncoding)
-	if err != nil {
-		return err
-	}
-	if isResponse && t.RequestMethod == "HEAD" {
-		if n, err := parseContentLength(t.Header.get("Content-Length")); err != nil {
-			return err
-		} else {
-			t.ContentLength = n
-		}
-	} else {
-		t.ContentLength = realLength
-	}
-
-	// Trailer
-	t.Trailer, err = fixTrailer(t.Header, t.TransferEncoding)
-	if err != nil {
-		return err
-	}
-
-	// If there is no Content-Length or chunked Transfer-Encoding on a *Response
-	// and the status is not 1xx, 204 or 304, then the body is unbounded.
-	// See RFC2616, section 4.4.
-	switch msg.(type) {
-	case *Response:
-		if realLength == -1 &&
-			!chunked(t.TransferEncoding) &&
-			bodyAllowedForStatus(t.StatusCode) {
-			// Unbounded body.
-			t.Close = true
-		}
-	}
-
-	// Prepare body reader.  ContentLength < 0 means chunked encoding
-	// or close connection when finished, since multipart is not supported yet
-	switch {
-	case chunked(t.TransferEncoding):
-		if noBodyExpected(t.RequestMethod) {
-			t.Body = eofReader
-		} else {
-			t.Body = &body{src: newChunkedReader(r), hdr: msg, r: r, closing: t.Close}
-		}
-	case realLength == 0:
-		t.Body = eofReader
-	case realLength > 0:
-		t.Body = &body{src: io.LimitReader(r, realLength), closing: t.Close}
-	default:
-		// realLength < 0, i.e. "Content-Length" not mentioned in header
-		if t.Close {
-			// Close semantics (i.e. HTTP/1.0)
-			t.Body = &body{src: r, closing: t.Close}
-		} else {
-			// Persistent connection (i.e. HTTP/1.1)
-			t.Body = eofReader
-		}
-	}
-
-	// Unify output
-	switch rr := msg.(type) {
-	case *Request:
-		rr.Body = t.Body
-		rr.ContentLength = t.ContentLength
-		rr.TransferEncoding = t.TransferEncoding
-		rr.Close = t.Close
-		rr.Trailer = t.Trailer
-	case *Response:
-		rr.Body = t.Body
-		rr.ContentLength = t.ContentLength
-		rr.TransferEncoding = t.TransferEncoding
-		rr.Close = t.Close
-		rr.Trailer = t.Trailer
-	}
-
-	return nil
-}
-
-// Checks whether chunked is part of the encodings stack
-func chunked(te []string) bool { return len(te) > 0 && te[0] == "chunked" }
-
-// Checks whether the encoding is explicitly "identity".
-func isIdentity(te []string) bool { return len(te) == 1 && te[0] == "identity" }
-
-// Sanitize transfer encoding
-func fixTransferEncoding(requestMethod string, header Header) ([]string, error) {
-	raw, present := header["Transfer-Encoding"]
-	if !present {
-		return nil, nil
-	}
-
-	delete(header, "Transfer-Encoding")
-
-	encodings := strings.Split(raw[0], ",")
-	te := make([]string, 0, len(encodings))
-	// TODO: Even though we only support "identity" and "chunked"
-	// encodings, the loop below is designed with foresight. One
-	// invariant that must be maintained is that, if present,
-	// chunked encoding must always come first.
-	for _, encoding := range encodings {
-		encoding = strings.ToLower(strings.TrimSpace(encoding))
-		// "identity" encoding is not recorded
-		if encoding == "identity" {
-			break
-		}
-		if encoding != "chunked" {
-			return nil, &badStringError{"unsupported transfer encoding", encoding}
-		}
-		te = te[0 : len(te)+1]
-		te[len(te)-1] = encoding
-	}
-	if len(te) > 1 {
-		return nil, &badStringError{"too many transfer encodings", strings.Join(te, ",")}
-	}
-	if len(te) > 0 {
-		// Chunked encoding trumps Content-Length. See RFC 2616
-		// Section 4.4. Currently len(te) > 0 implies chunked
-		// encoding.
-		delete(header, "Content-Length")
-		return te, nil
-	}
-
-	return nil, nil
-}
-
-// Determine the expected body length, using RFC 2616 Section 4.4. This
-// function is not a method, because ultimately it should be shared by
-// ReadResponse and ReadRequest.
-func fixLength(isResponse bool, status int, requestMethod string, header Header, te []string) (int64, error) {
-
-	// Logic based on response type or status
-	if noBodyExpected(requestMethod) {
-		return 0, nil
-	}
-	if status/100 == 1 {
-		return 0, nil
-	}
-	switch status {
-	case 204, 304:
-		return 0, nil
-	}
-
-	// Logic based on Transfer-Encoding
-	if chunked(te) {
-		return -1, nil
-	}
-
-	// Logic based on Content-Length
-	cl := strings.TrimSpace(header.get("Content-Length"))
-	if cl != "" {
-		n, err := parseContentLength(cl)
-		if err != nil {
-			return -1, err
-		}
-		return n, nil
-	} else {
-		header.Del("Content-Length")
-	}
-
-	if !isResponse && requestMethod == "GET" {
-		// RFC 2616 doesn't explicitly permit nor forbid an
-		// entity-body on a GET request so we permit one if
-		// declared, but we default to 0 here (not -1 below)
-		// if there's no mention of a body.
-		return 0, nil
-	}
-
-	// Body-EOF logic based on other methods (like closing, or chunked coding)
-	return -1, nil
-}
-
-// Determine whether to hang up after sending a request and body, or
-// receiving a response and body
-// 'header' is the request headers
-func shouldClose(major, minor int, header Header) bool {
-	if major < 1 {
-		return true
-	} else if major == 1 && minor == 0 {
-		if !strings.Contains(strings.ToLower(header.get("Connection")), "keep-alive") {
-			return true
-		}
-		return false
-	} else {
-		// TODO: Should split on commas, toss surrounding white space,
-		// and check each field.
-		if strings.ToLower(header.get("Connection")) == "close" {
-			header.Del("Connection")
-			return true
-		}
-	}
-	return false
-}
-
-// Parse the trailer header
-func fixTrailer(header Header, te []string) (Header, error) {
-	raw := header.get("Trailer")
-	if raw == "" {
-		return nil, nil
-	}
-
-	header.Del("Trailer")
-	trailer := make(Header)
-	keys := strings.Split(raw, ",")
-	for _, key := range keys {
-		key = CanonicalHeaderKey(strings.TrimSpace(key))
-		switch key {
-		case "Transfer-Encoding", "Trailer", "Content-Length":
-			return nil, &badStringError{"bad trailer key", key}
-		}
-		trailer[key] = nil
-	}
-	if len(trailer) == 0 {
-		return nil, nil
-	}
-	if !chunked(te) {
-		// Trailer and no chunking
-		return nil, ErrUnexpectedTrailer
-	}
-	return trailer, nil
-}
-
-// body turns a Reader into a ReadCloser.
-// Close ensures that the body has been fully read
-// and then reads the trailer if necessary.
-type body struct {
-	src     io.Reader
-	hdr     interface{}   // non-nil (Response or Request) value means read trailer
-	r       *bufio.Reader // underlying wire-format reader for the trailer
-	closing bool          // is the connection to be closed after reading body?
-
-	mu     sync.Mutex // guards closed, and calls to Read and Close
-	closed bool
-}
-
-// ErrBodyReadAfterClose is returned when reading a Request or Response
-// Body after the body has been closed. This typically happens when the body is
-// read after an HTTP Handler calls WriteHeader or Write on its
-// ResponseWriter.
-var ErrBodyReadAfterClose = errors.New("http: invalid Read on closed Body")
-
-func (b *body) Read(p []byte) (n int, err error) {
-	b.mu.Lock()
-	defer b.mu.Unlock()
-	if b.closed {
-		return 0, ErrBodyReadAfterClose
-	}
-	return b.readLocked(p)
-}
-
-// Must hold b.mu.
-func (b *body) readLocked(p []byte) (n int, err error) {
-	n, err = b.src.Read(p)
-
-	if err == io.EOF {
-		// Chunked case. Read the trailer.
-		if b.hdr != nil {
-			if e := b.readTrailer(); e != nil {
-				err = e
-			}
-			b.hdr = nil
-		} else {
-			// If the server declared the Content-Length, our body is a LimitedReader
-			// and we need to check whether this EOF arrived early.
-			if lr, ok := b.src.(*io.LimitedReader); ok && lr.N > 0 {
-				err = io.ErrUnexpectedEOF
-			}
-		}
-	}
-
-	// If we can return an EOF here along with the read data, do
-	// so. This is optional per the io.Reader contract, but doing
-	// so helps the HTTP transport code recycle its connection
-	// earlier (since it will see this EOF itself), even if the
-	// client doesn't do future reads or Close.
-	if err == nil && n > 0 {
-		if lr, ok := b.src.(*io.LimitedReader); ok && lr.N == 0 {
-			err = io.EOF
-		}
-	}
-
-	return n, err
-}
-
-var (
-	singleCRLF = []byte("\r\n")
-	doubleCRLF = []byte("\r\n\r\n")
-)
-
-func seeUpcomingDoubleCRLF(r *bufio.Reader) bool {
-	for peekSize := 4; ; peekSize++ {
-		// This loop stops when Peek returns an error,
-		// which it does when r's buffer has been filled.
-		buf, err := r.Peek(peekSize)
-		if bytes.HasSuffix(buf, doubleCRLF) {
-			return true
-		}
-		if err != nil {
-			break
-		}
-	}
-	return false
-}
-
-var errTrailerEOF = errors.New("http: unexpected EOF reading trailer")
-
-func (b *body) readTrailer() error {
-	// The common case, since nobody uses trailers.
-	buf, err := b.r.Peek(2)
-	if bytes.Equal(buf, singleCRLF) {
-		b.r.ReadByte()
-		b.r.ReadByte()
-		return nil
-	}
-	if len(buf) < 2 {
-		return errTrailerEOF
-	}
-	if err != nil {
-		return err
-	}
-
-	// Make sure there's a header terminator coming up, to prevent
-	// a DoS with an unbounded size Trailer.  It's not easy to
-	// slip in a LimitReader here, as textproto.NewReader requires
-	// a concrete *bufio.Reader.  Also, we can't get all the way
-	// back up to our conn's LimitedReader that *might* be backing
-	// this bufio.Reader.  Instead, a hack: we iteratively Peek up
-	// to the bufio.Reader's max size, looking for a double CRLF.
-	// This limits the trailer to the underlying buffer size, typically 4kB.
-	if !seeUpcomingDoubleCRLF(b.r) {
-		return errors.New("http: suspiciously long trailer after chunked body")
-	}
-
-	hdr, err := textproto.NewReader(b.r).ReadMIMEHeader()
-	if err != nil {
-		if err == io.EOF {
-			return errTrailerEOF
-		}
-		return err
-	}
-	switch rr := b.hdr.(type) {
-	case *Request:
-		mergeSetHeader(&rr.Trailer, Header(hdr))
-	case *Response:
-		mergeSetHeader(&rr.Trailer, Header(hdr))
-	}
-	return nil
-}
-
-func mergeSetHeader(dst *Header, src Header) {
-	if *dst == nil {
-		*dst = src
-		return
-	}
-	for k, vv := range src {
-		(*dst)[k] = vv
-	}
-}
-
-func (b *body) Close() error {
-	b.mu.Lock()
-	defer b.mu.Unlock()
-	if b.closed {
-		return nil
-	}
-	var err error
-	switch {
-	case b.hdr == nil && b.closing:
-		// no trailer and closing the connection next.
-		// no point in reading to EOF.
-	default:
-		// Fully consume the body, which will also lead to us reading
-		// the trailer headers after the body, if present.
-		_, err = io.Copy(ioutil.Discard, bodyLocked{b})
-	}
-	b.closed = true
-	return err
-}
-
-// bodyLocked is a io.Reader reading from a *body when its mutex is
-// already held.
-type bodyLocked struct {
-	b *body
-}
-
-func (bl bodyLocked) Read(p []byte) (n int, err error) {
-	if bl.b.closed {
-		return 0, ErrBodyReadAfterClose
-	}
-	return bl.b.readLocked(p)
-}
-
-// parseContentLength trims whitespace from s and returns -1 if no value
-// is set, or the value if it's >= 0.
-func parseContentLength(cl string) (int64, error) {
-	cl = strings.TrimSpace(cl)
-	if cl == "" {
-		return -1, nil
-	}
-	n, err := strconv.ParseInt(cl, 10, 64)
-	if err != nil || n < 0 {
-		return 0, &badStringError{"bad Content-Length", cl}
-	}
-	return n, nil
-
-}
diff --git a/src/pkg/net/http/transport.go b/src/pkg/net/http/transport.go
deleted file mode 100644
index b1cc632..0000000
--- a/src/pkg/net/http/transport.go
+++ /dev/null
@@ -1,1208 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// HTTP client implementation. See RFC 2616.
-//
-// This is the low-level Transport implementation of RoundTripper.
-// The high-level interface is in client.go.
-
-package http
-
-import (
-	"bufio"
-	"compress/gzip"
-	"crypto/tls"
-	"errors"
-	"fmt"
-	"io"
-	"log"
-	"net"
-	"net/url"
-	"os"
-	"strings"
-	"sync"
-	"time"
-)
-
-// DefaultTransport is the default implementation of Transport and is
-// used by DefaultClient. It establishes network connections as needed
-// and caches them for reuse by subsequent calls. It uses HTTP proxies
-// as directed by the $HTTP_PROXY and $NO_PROXY (or $http_proxy and
-// $no_proxy) environment variables.
-var DefaultTransport RoundTripper = &Transport{
-	Proxy: ProxyFromEnvironment,
-	Dial: (&net.Dialer{
-		Timeout:   30 * time.Second,
-		KeepAlive: 30 * time.Second,
-	}).Dial,
-	TLSHandshakeTimeout: 10 * time.Second,
-}
-
-// DefaultMaxIdleConnsPerHost is the default value of Transport's
-// MaxIdleConnsPerHost.
-const DefaultMaxIdleConnsPerHost = 2
-
-// Transport is an implementation of RoundTripper that supports http,
-// https, and http proxies (for either http or https with CONNECT).
-// Transport can also cache connections for future re-use.
-type Transport struct {
-	idleMu      sync.Mutex
-	idleConn    map[connectMethodKey][]*persistConn
-	idleConnCh  map[connectMethodKey]chan *persistConn
-	reqMu       sync.Mutex
-	reqCanceler map[*Request]func()
-	altMu       sync.RWMutex
-	altProto    map[string]RoundTripper // nil or map of URI scheme => RoundTripper
-
-	// Proxy specifies a function to return a proxy for a given
-	// Request. If the function returns a non-nil error, the
-	// request is aborted with the provided error.
-	// If Proxy is nil or returns a nil *URL, no proxy is used.
-	Proxy func(*Request) (*url.URL, error)
-
-	// Dial specifies the dial function for creating TCP
-	// connections.
-	// If Dial is nil, net.Dial is used.
-	Dial func(network, addr string) (net.Conn, error)
-
-	// TLSClientConfig specifies the TLS configuration to use with
-	// tls.Client. If nil, the default configuration is used.
-	TLSClientConfig *tls.Config
-
-	// TLSHandshakeTimeout specifies the maximum amount of time waiting to
-	// wait for a TLS handshake. Zero means no timeout.
-	TLSHandshakeTimeout time.Duration
-
-	// DisableKeepAlives, if true, prevents re-use of TCP connections
-	// between different HTTP requests.
-	DisableKeepAlives bool
-
-	// DisableCompression, if true, prevents the Transport from
-	// requesting compression with an "Accept-Encoding: gzip"
-	// request header when the Request contains no existing
-	// Accept-Encoding value. If the Transport requests gzip on
-	// its own and gets a gzipped response, it's transparently
-	// decoded in the Response.Body. However, if the user
-	// explicitly requested gzip it is not automatically
-	// uncompressed.
-	DisableCompression bool
-
-	// MaxIdleConnsPerHost, if non-zero, controls the maximum idle
-	// (keep-alive) to keep per-host.  If zero,
-	// DefaultMaxIdleConnsPerHost is used.
-	MaxIdleConnsPerHost int
-
-	// ResponseHeaderTimeout, if non-zero, specifies the amount of
-	// time to wait for a server's response headers after fully
-	// writing the request (including its body, if any). This
-	// time does not include the time to read the response body.
-	ResponseHeaderTimeout time.Duration
-
-	// TODO: tunable on global max cached connections
-	// TODO: tunable on timeout on cached connections
-}
-
-// ProxyFromEnvironment returns the URL of the proxy to use for a
-// given request, as indicated by the environment variables
-// $HTTP_PROXY and $NO_PROXY (or $http_proxy and $no_proxy).
-// An error is returned if the proxy environment is invalid.
-// A nil URL and nil error are returned if no proxy is defined in the
-// environment, or a proxy should not be used for the given request.
-//
-// As a special case, if req.URL.Host is "localhost" (with or without
-// a port number), then a nil URL and nil error will be returned.
-func ProxyFromEnvironment(req *Request) (*url.URL, error) {
-	proxy := httpProxyEnv.Get()
-	if proxy == "" {
-		return nil, nil
-	}
-	if !useProxy(canonicalAddr(req.URL)) {
-		return nil, nil
-	}
-	proxyURL, err := url.Parse(proxy)
-	if err != nil || !strings.HasPrefix(proxyURL.Scheme, "http") {
-		// proxy was bogus. Try prepending "http://" to it and
-		// see if that parses correctly. If not, we fall
-		// through and complain about the original one.
-		if proxyURL, err := url.Parse("http://" + proxy); err == nil {
-			return proxyURL, nil
-		}
-	}
-	if err != nil {
-		return nil, fmt.Errorf("invalid proxy address %q: %v", proxy, err)
-	}
-	return proxyURL, nil
-}
-
-// ProxyURL returns a proxy function (for use in a Transport)
-// that always returns the same URL.
-func ProxyURL(fixedURL *url.URL) func(*Request) (*url.URL, error) {
-	return func(*Request) (*url.URL, error) {
-		return fixedURL, nil
-	}
-}
-
-// transportRequest is a wrapper around a *Request that adds
-// optional extra headers to write.
-type transportRequest struct {
-	*Request        // original request, not to be mutated
-	extra    Header // extra headers to write, or nil
-}
-
-func (tr *transportRequest) extraHeaders() Header {
-	if tr.extra == nil {
-		tr.extra = make(Header)
-	}
-	return tr.extra
-}
-
-// RoundTrip implements the RoundTripper interface.
-//
-// For higher-level HTTP client support (such as handling of cookies
-// and redirects), see Get, Post, and the Client type.
-func (t *Transport) RoundTrip(req *Request) (resp *Response, err error) {
-	if req.URL == nil {
-		req.closeBody()
-		return nil, errors.New("http: nil Request.URL")
-	}
-	if req.Header == nil {
-		req.closeBody()
-		return nil, errors.New("http: nil Request.Header")
-	}
-	if req.URL.Scheme != "http" && req.URL.Scheme != "https" {
-		t.altMu.RLock()
-		var rt RoundTripper
-		if t.altProto != nil {
-			rt = t.altProto[req.URL.Scheme]
-		}
-		t.altMu.RUnlock()
-		if rt == nil {
-			req.closeBody()
-			return nil, &badStringError{"unsupported protocol scheme", req.URL.Scheme}
-		}
-		return rt.RoundTrip(req)
-	}
-	if req.URL.Host == "" {
-		req.closeBody()
-		return nil, errors.New("http: no Host in request URL")
-	}
-	treq := &transportRequest{Request: req}
-	cm, err := t.connectMethodForRequest(treq)
-	if err != nil {
-		req.closeBody()
-		return nil, err
-	}
-
-	// Get the cached or newly-created connection to either the
-	// host (for http or https), the http proxy, or the http proxy
-	// pre-CONNECTed to https server.  In any case, we'll be ready
-	// to send it requests.
-	pconn, err := t.getConn(req, cm)
-	if err != nil {
-		t.setReqCanceler(req, nil)
-		req.closeBody()
-		return nil, err
-	}
-
-	return pconn.roundTrip(treq)
-}
-
-// RegisterProtocol registers a new protocol with scheme.
-// The Transport will pass requests using the given scheme to rt.
-// It is rt's responsibility to simulate HTTP request semantics.
-//
-// RegisterProtocol can be used by other packages to provide
-// implementations of protocol schemes like "ftp" or "file".
-func (t *Transport) RegisterProtocol(scheme string, rt RoundTripper) {
-	if scheme == "http" || scheme == "https" {
-		panic("protocol " + scheme + " already registered")
-	}
-	t.altMu.Lock()
-	defer t.altMu.Unlock()
-	if t.altProto == nil {
-		t.altProto = make(map[string]RoundTripper)
-	}
-	if _, exists := t.altProto[scheme]; exists {
-		panic("protocol " + scheme + " already registered")
-	}
-	t.altProto[scheme] = rt
-}
-
-// CloseIdleConnections closes any connections which were previously
-// connected from previous requests but are now sitting idle in
-// a "keep-alive" state. It does not interrupt any connections currently
-// in use.
-func (t *Transport) CloseIdleConnections() {
-	t.idleMu.Lock()
-	m := t.idleConn
-	t.idleConn = nil
-	t.idleConnCh = nil
-	t.idleMu.Unlock()
-	for _, conns := range m {
-		for _, pconn := range conns {
-			pconn.close()
-		}
-	}
-}
-
-// CancelRequest cancels an in-flight request by closing its
-// connection.
-func (t *Transport) CancelRequest(req *Request) {
-	t.reqMu.Lock()
-	cancel := t.reqCanceler[req]
-	t.reqMu.Unlock()
-	if cancel != nil {
-		cancel()
-	}
-}
-
-//
-// Private implementation past this point.
-//
-
-var (
-	httpProxyEnv = &envOnce{
-		names: []string{"HTTP_PROXY", "http_proxy"},
-	}
-	noProxyEnv = &envOnce{
-		names: []string{"NO_PROXY", "no_proxy"},
-	}
-)
-
-// envOnce looks up an environment variable (optionally by multiple
-// names) once. It mitigates expensive lookups on some platforms
-// (e.g. Windows).
-type envOnce struct {
-	names []string
-	once  sync.Once
-	val   string
-}
-
-func (e *envOnce) Get() string {
-	e.once.Do(e.init)
-	return e.val
-}
-
-func (e *envOnce) init() {
-	for _, n := range e.names {
-		e.val = os.Getenv(n)
-		if e.val != "" {
-			return
-		}
-	}
-}
-
-// reset is used by tests
-func (e *envOnce) reset() {
-	e.once = sync.Once{}
-	e.val = ""
-}
-
-func (t *Transport) connectMethodForRequest(treq *transportRequest) (cm connectMethod, err error) {
-	cm.targetScheme = treq.URL.Scheme
-	cm.targetAddr = canonicalAddr(treq.URL)
-	if t.Proxy != nil {
-		cm.proxyURL, err = t.Proxy(treq.Request)
-	}
-	return cm, nil
-}
-
-// proxyAuth returns the Proxy-Authorization header to set
-// on requests, if applicable.
-func (cm *connectMethod) proxyAuth() string {
-	if cm.proxyURL == nil {
-		return ""
-	}
-	if u := cm.proxyURL.User; u != nil {
-		username := u.Username()
-		password, _ := u.Password()
-		return "Basic " + basicAuth(username, password)
-	}
-	return ""
-}
-
-// putIdleConn adds pconn to the list of idle persistent connections awaiting
-// a new request.
-// If pconn is no longer needed or not in a good state, putIdleConn
-// returns false.
-func (t *Transport) putIdleConn(pconn *persistConn) bool {
-	if t.DisableKeepAlives || t.MaxIdleConnsPerHost < 0 {
-		pconn.close()
-		return false
-	}
-	if pconn.isBroken() {
-		return false
-	}
-	key := pconn.cacheKey
-	max := t.MaxIdleConnsPerHost
-	if max == 0 {
-		max = DefaultMaxIdleConnsPerHost
-	}
-	t.idleMu.Lock()
-
-	waitingDialer := t.idleConnCh[key]
-	select {
-	case waitingDialer <- pconn:
-		// We're done with this pconn and somebody else is
-		// currently waiting for a conn of this type (they're
-		// actively dialing, but this conn is ready
-		// first). Chrome calls this socket late binding.  See
-		// https://insouciant.org/tech/connection-management-in-chromium/
-		t.idleMu.Unlock()
-		return true
-	default:
-		if waitingDialer != nil {
-			// They had populated this, but their dial won
-			// first, so we can clean up this map entry.
-			delete(t.idleConnCh, key)
-		}
-	}
-	if t.idleConn == nil {
-		t.idleConn = make(map[connectMethodKey][]*persistConn)
-	}
-	if len(t.idleConn[key]) >= max {
-		t.idleMu.Unlock()
-		pconn.close()
-		return false
-	}
-	for _, exist := range t.idleConn[key] {
-		if exist == pconn {
-			log.Fatalf("dup idle pconn %p in freelist", pconn)
-		}
-	}
-	t.idleConn[key] = append(t.idleConn[key], pconn)
-	t.idleMu.Unlock()
-	return true
-}
-
-// getIdleConnCh returns a channel to receive and return idle
-// persistent connection for the given connectMethod.
-// It may return nil, if persistent connections are not being used.
-func (t *Transport) getIdleConnCh(cm connectMethod) chan *persistConn {
-	if t.DisableKeepAlives {
-		return nil
-	}
-	key := cm.key()
-	t.idleMu.Lock()
-	defer t.idleMu.Unlock()
-	if t.idleConnCh == nil {
-		t.idleConnCh = make(map[connectMethodKey]chan *persistConn)
-	}
-	ch, ok := t.idleConnCh[key]
-	if !ok {
-		ch = make(chan *persistConn)
-		t.idleConnCh[key] = ch
-	}
-	return ch
-}
-
-func (t *Transport) getIdleConn(cm connectMethod) (pconn *persistConn) {
-	key := cm.key()
-	t.idleMu.Lock()
-	defer t.idleMu.Unlock()
-	if t.idleConn == nil {
-		return nil
-	}
-	for {
-		pconns, ok := t.idleConn[key]
-		if !ok {
-			return nil
-		}
-		if len(pconns) == 1 {
-			pconn = pconns[0]
-			delete(t.idleConn, key)
-		} else {
-			// 2 or more cached connections; pop last
-			// TODO: queue?
-			pconn = pconns[len(pconns)-1]
-			t.idleConn[key] = pconns[:len(pconns)-1]
-		}
-		if !pconn.isBroken() {
-			return
-		}
-	}
-}
-
-func (t *Transport) setReqCanceler(r *Request, fn func()) {
-	t.reqMu.Lock()
-	defer t.reqMu.Unlock()
-	if t.reqCanceler == nil {
-		t.reqCanceler = make(map[*Request]func())
-	}
-	if fn != nil {
-		t.reqCanceler[r] = fn
-	} else {
-		delete(t.reqCanceler, r)
-	}
-}
-
-func (t *Transport) dial(network, addr string) (c net.Conn, err error) {
-	if t.Dial != nil {
-		return t.Dial(network, addr)
-	}
-	return net.Dial(network, addr)
-}
-
-// getConn dials and creates a new persistConn to the target as
-// specified in the connectMethod.  This includes doing a proxy CONNECT
-// and/or setting up TLS.  If this doesn't return an error, the persistConn
-// is ready to write requests to.
-func (t *Transport) getConn(req *Request, cm connectMethod) (*persistConn, error) {
-	if pc := t.getIdleConn(cm); pc != nil {
-		return pc, nil
-	}
-
-	type dialRes struct {
-		pc  *persistConn
-		err error
-	}
-	dialc := make(chan dialRes)
-
-	handlePendingDial := func() {
-		if v := <-dialc; v.err == nil {
-			t.putIdleConn(v.pc)
-		}
-	}
-
-	cancelc := make(chan struct{})
-	t.setReqCanceler(req, func() { close(cancelc) })
-
-	go func() {
-		pc, err := t.dialConn(cm)
-		dialc <- dialRes{pc, err}
-	}()
-
-	idleConnCh := t.getIdleConnCh(cm)
-	select {
-	case v := <-dialc:
-		// Our dial finished.
-		return v.pc, v.err
-	case pc := <-idleConnCh:
-		// Another request finished first and its net.Conn
-		// became available before our dial. Or somebody
-		// else's dial that they didn't use.
-		// But our dial is still going, so give it away
-		// when it finishes:
-		go handlePendingDial()
-		return pc, nil
-	case <-cancelc:
-		go handlePendingDial()
-		return nil, errors.New("net/http: request canceled while waiting for connection")
-	}
-}
-
-func (t *Transport) dialConn(cm connectMethod) (*persistConn, error) {
-	conn, err := t.dial("tcp", cm.addr())
-	if err != nil {
-		if cm.proxyURL != nil {
-			err = fmt.Errorf("http: error connecting to proxy %s: %v", cm.proxyURL, err)
-		}
-		return nil, err
-	}
-
-	pa := cm.proxyAuth()
-
-	pconn := &persistConn{
-		t:          t,
-		cacheKey:   cm.key(),
-		conn:       conn,
-		reqch:      make(chan requestAndChan, 1),
-		writech:    make(chan writeRequest, 1),
-		closech:    make(chan struct{}),
-		writeErrCh: make(chan error, 1),
-	}
-
-	switch {
-	case cm.proxyURL == nil:
-		// Do nothing.
-	case cm.targetScheme == "http":
-		pconn.isProxy = true
-		if pa != "" {
-			pconn.mutateHeaderFunc = func(h Header) {
-				h.Set("Proxy-Authorization", pa)
-			}
-		}
-	case cm.targetScheme == "https":
-		connectReq := &Request{
-			Method: "CONNECT",
-			URL:    &url.URL{Opaque: cm.targetAddr},
-			Host:   cm.targetAddr,
-			Header: make(Header),
-		}
-		if pa != "" {
-			connectReq.Header.Set("Proxy-Authorization", pa)
-		}
-		connectReq.Write(conn)
-
-		// Read response.
-		// Okay to use and discard buffered reader here, because
-		// TLS server will not speak until spoken to.
-		br := bufio.NewReader(conn)
-		resp, err := ReadResponse(br, connectReq)
-		if err != nil {
-			conn.Close()
-			return nil, err
-		}
-		if resp.StatusCode != 200 {
-			f := strings.SplitN(resp.Status, " ", 2)
-			conn.Close()
-			return nil, errors.New(f[1])
-		}
-	}
-
-	if cm.targetScheme == "https" {
-		// Initiate TLS and check remote host name against certificate.
-		cfg := t.TLSClientConfig
-		if cfg == nil || cfg.ServerName == "" {
-			host := cm.tlsHost()
-			if cfg == nil {
-				cfg = &tls.Config{ServerName: host}
-			} else {
-				clone := *cfg // shallow clone
-				clone.ServerName = host
-				cfg = &clone
-			}
-		}
-		plainConn := conn
-		tlsConn := tls.Client(plainConn, cfg)
-		errc := make(chan error, 2)
-		var timer *time.Timer // for canceling TLS handshake
-		if d := t.TLSHandshakeTimeout; d != 0 {
-			timer = time.AfterFunc(d, func() {
-				errc <- tlsHandshakeTimeoutError{}
-			})
-		}
-		go func() {
-			err := tlsConn.Handshake()
-			if timer != nil {
-				timer.Stop()
-			}
-			errc <- err
-		}()
-		if err := <-errc; err != nil {
-			plainConn.Close()
-			return nil, err
-		}
-		if !cfg.InsecureSkipVerify {
-			if err := tlsConn.VerifyHostname(cfg.ServerName); err != nil {
-				plainConn.Close()
-				return nil, err
-			}
-		}
-		cs := tlsConn.ConnectionState()
-		pconn.tlsState = &cs
-		pconn.conn = tlsConn
-	}
-
-	pconn.br = bufio.NewReader(noteEOFReader{pconn.conn, &pconn.sawEOF})
-	pconn.bw = bufio.NewWriter(pconn.conn)
-	go pconn.readLoop()
-	go pconn.writeLoop()
-	return pconn, nil
-}
-
-// useProxy returns true if requests to addr should use a proxy,
-// according to the NO_PROXY or no_proxy environment variable.
-// addr is always a canonicalAddr with a host and port.
-func useProxy(addr string) bool {
-	if len(addr) == 0 {
-		return true
-	}
-	host, _, err := net.SplitHostPort(addr)
-	if err != nil {
-		return false
-	}
-	if host == "localhost" {
-		return false
-	}
-	if ip := net.ParseIP(host); ip != nil {
-		if ip.IsLoopback() {
-			return false
-		}
-	}
-
-	no_proxy := noProxyEnv.Get()
-	if no_proxy == "*" {
-		return false
-	}
-
-	addr = strings.ToLower(strings.TrimSpace(addr))
-	if hasPort(addr) {
-		addr = addr[:strings.LastIndex(addr, ":")]
-	}
-
-	for _, p := range strings.Split(no_proxy, ",") {
-		p = strings.ToLower(strings.TrimSpace(p))
-		if len(p) == 0 {
-			continue
-		}
-		if hasPort(p) {
-			p = p[:strings.LastIndex(p, ":")]
-		}
-		if addr == p {
-			return false
-		}
-		if p[0] == '.' && (strings.HasSuffix(addr, p) || addr == p[1:]) {
-			// no_proxy ".foo.com" matches "bar.foo.com" or "foo.com"
-			return false
-		}
-		if p[0] != '.' && strings.HasSuffix(addr, p) && addr[len(addr)-len(p)-1] == '.' {
-			// no_proxy "foo.com" matches "bar.foo.com"
-			return false
-		}
-	}
-	return true
-}
-
-// connectMethod is the map key (in its String form) for keeping persistent
-// TCP connections alive for subsequent HTTP requests.
-//
-// A connect method may be of the following types:
-//
-// Cache key form                Description
-// -----------------             -------------------------
-// |http|foo.com                 http directly to server, no proxy
-// |https|foo.com                https directly to server, no proxy
-// http://proxy.com|https|foo.com  http to proxy, then CONNECT to foo.com
-// http://proxy.com|http           http to proxy, http to anywhere after that
-//
-// Note: no support to https to the proxy yet.
-//
-type connectMethod struct {
-	proxyURL     *url.URL // nil for no proxy, else full proxy URL
-	targetScheme string   // "http" or "https"
-	targetAddr   string   // Not used if proxy + http targetScheme (4th example in table)
-}
-
-func (cm *connectMethod) key() connectMethodKey {
-	proxyStr := ""
-	targetAddr := cm.targetAddr
-	if cm.proxyURL != nil {
-		proxyStr = cm.proxyURL.String()
-		if cm.targetScheme == "http" {
-			targetAddr = ""
-		}
-	}
-	return connectMethodKey{
-		proxy:  proxyStr,
-		scheme: cm.targetScheme,
-		addr:   targetAddr,
-	}
-}
-
-// addr returns the first hop "host:port" to which we need to TCP connect.
-func (cm *connectMethod) addr() string {
-	if cm.proxyURL != nil {
-		return canonicalAddr(cm.proxyURL)
-	}
-	return cm.targetAddr
-}
-
-// tlsHost returns the host name to match against the peer's
-// TLS certificate.
-func (cm *connectMethod) tlsHost() string {
-	h := cm.targetAddr
-	if hasPort(h) {
-		h = h[:strings.LastIndex(h, ":")]
-	}
-	return h
-}
-
-// connectMethodKey is the map key version of connectMethod, with a
-// stringified proxy URL (or the empty string) instead of a pointer to
-// a URL.
-type connectMethodKey struct {
-	proxy, scheme, addr string
-}
-
-func (k connectMethodKey) String() string {
-	// Only used by tests.
-	return fmt.Sprintf("%s|%s|%s", k.proxy, k.scheme, k.addr)
-}
-
-// persistConn wraps a connection, usually a persistent one
-// (but may be used for non-keep-alive requests as well)
-type persistConn struct {
-	t        *Transport
-	cacheKey connectMethodKey
-	conn     net.Conn
-	tlsState *tls.ConnectionState
-	br       *bufio.Reader       // from conn
-	sawEOF   bool                // whether we've seen EOF from conn; owned by readLoop
-	bw       *bufio.Writer       // to conn
-	reqch    chan requestAndChan // written by roundTrip; read by readLoop
-	writech  chan writeRequest   // written by roundTrip; read by writeLoop
-	closech  chan struct{}       // closed when conn closed
-	isProxy  bool
-	// writeErrCh passes the request write error (usually nil)
-	// from the writeLoop goroutine to the readLoop which passes
-	// it off to the res.Body reader, which then uses it to decide
-	// whether or not a connection can be reused. Issue 7569.
-	writeErrCh chan error
-
-	lk                   sync.Mutex // guards following fields
-	numExpectedResponses int
-	closed               bool // whether conn has been closed
-	broken               bool // an error has happened on this connection; marked broken so it's not reused.
-	// mutateHeaderFunc is an optional func to modify extra
-	// headers on each outbound request before it's written. (the
-	// original Request given to RoundTrip is not modified)
-	mutateHeaderFunc func(Header)
-}
-
-// isBroken reports whether this connection is in a known broken state.
-func (pc *persistConn) isBroken() bool {
-	pc.lk.Lock()
-	b := pc.broken
-	pc.lk.Unlock()
-	return b
-}
-
-func (pc *persistConn) cancelRequest() {
-	pc.conn.Close()
-}
-
-var remoteSideClosedFunc func(error) bool // or nil to use default
-
-func remoteSideClosed(err error) bool {
-	if err == io.EOF {
-		return true
-	}
-	if remoteSideClosedFunc != nil {
-		return remoteSideClosedFunc(err)
-	}
-	return false
-}
-
-func (pc *persistConn) readLoop() {
-	alive := true
-
-	for alive {
-		pb, err := pc.br.Peek(1)
-
-		pc.lk.Lock()
-		if pc.numExpectedResponses == 0 {
-			if !pc.closed {
-				pc.closeLocked()
-				if len(pb) > 0 {
-					log.Printf("Unsolicited response received on idle HTTP channel starting with %q; err=%v",
-						string(pb), err)
-				}
-			}
-			pc.lk.Unlock()
-			return
-		}
-		pc.lk.Unlock()
-
-		rc := <-pc.reqch
-
-		var resp *Response
-		if err == nil {
-			resp, err = ReadResponse(pc.br, rc.req)
-			if err == nil && resp.StatusCode == 100 {
-				// Skip any 100-continue for now.
-				// TODO(bradfitz): if rc.req had "Expect: 100-continue",
-				// actually block the request body write and signal the
-				// writeLoop now to begin sending it. (Issue 2184) For now we
-				// eat it, since we're never expecting one.
-				resp, err = ReadResponse(pc.br, rc.req)
-			}
-		}
-
-		if resp != nil {
-			resp.TLS = pc.tlsState
-		}
-
-		hasBody := resp != nil && rc.req.Method != "HEAD" && resp.ContentLength != 0
-
-		if err != nil {
-			pc.close()
-		} else {
-			if rc.addedGzip && hasBody && resp.Header.Get("Content-Encoding") == "gzip" {
-				resp.Header.Del("Content-Encoding")
-				resp.Header.Del("Content-Length")
-				resp.ContentLength = -1
-				resp.Body = &gzipReader{body: resp.Body}
-			}
-			resp.Body = &bodyEOFSignal{body: resp.Body}
-		}
-
-		if err != nil || resp.Close || rc.req.Close || resp.StatusCode <= 199 {
-			// Don't do keep-alive on error if either party requested a close
-			// or we get an unexpected informational (1xx) response.
-			// StatusCode 100 is already handled above.
-			alive = false
-		}
-
-		var waitForBodyRead chan bool
-		if hasBody {
-			waitForBodyRead = make(chan bool, 2)
-			resp.Body.(*bodyEOFSignal).earlyCloseFn = func() error {
-				// Sending false here sets alive to
-				// false and closes the connection
-				// below.
-				waitForBodyRead <- false
-				return nil
-			}
-			resp.Body.(*bodyEOFSignal).fn = func(err error) {
-				waitForBodyRead <- alive &&
-					err == nil &&
-					!pc.sawEOF &&
-					pc.wroteRequest() &&
-					pc.t.putIdleConn(pc)
-			}
-		}
-
-		if alive && !hasBody {
-			alive = !pc.sawEOF &&
-				pc.wroteRequest() &&
-				pc.t.putIdleConn(pc)
-		}
-
-		rc.ch <- responseAndError{resp, err}
-
-		// Wait for the just-returned response body to be fully consumed
-		// before we race and peek on the underlying bufio reader.
-		if waitForBodyRead != nil {
-			select {
-			case alive = <-waitForBodyRead:
-			case <-pc.closech:
-				alive = false
-			}
-		}
-
-		pc.t.setReqCanceler(rc.req, nil)
-
-		if !alive {
-			pc.close()
-		}
-	}
-}
-
-func (pc *persistConn) writeLoop() {
-	for {
-		select {
-		case wr := <-pc.writech:
-			if pc.isBroken() {
-				wr.ch <- errors.New("http: can't write HTTP request on broken connection")
-				continue
-			}
-			err := wr.req.Request.write(pc.bw, pc.isProxy, wr.req.extra)
-			if err == nil {
-				err = pc.bw.Flush()
-			}
-			if err != nil {
-				pc.markBroken()
-				wr.req.Request.closeBody()
-			}
-			pc.writeErrCh <- err // to the body reader, which might recycle us
-			wr.ch <- err         // to the roundTrip function
-		case <-pc.closech:
-			return
-		}
-	}
-}
-
-// wroteRequest is a check before recycling a connection that the previous write
-// (from writeLoop above) happened and was successful.
-func (pc *persistConn) wroteRequest() bool {
-	select {
-	case err := <-pc.writeErrCh:
-		// Common case: the write happened well before the response, so
-		// avoid creating a timer.
-		return err == nil
-	default:
-		// Rare case: the request was written in writeLoop above but
-		// before it could send to pc.writeErrCh, the reader read it
-		// all, processed it, and called us here. In this case, give the
-		// write goroutine a bit of time to finish its send.
-		//
-		// Less rare case: We also get here in the legitimate case of
-		// Issue 7569, where the writer is still writing (or stalled),
-		// but the server has already replied. In this case, we don't
-		// want to wait too long, and we want to return false so this
-		// connection isn't re-used.
-		select {
-		case err := <-pc.writeErrCh:
-			return err == nil
-		case <-time.After(50 * time.Millisecond):
-			return false
-		}
-	}
-}
-
-type responseAndError struct {
-	res *Response
-	err error
-}
-
-type requestAndChan struct {
-	req *Request
-	ch  chan responseAndError
-
-	// did the Transport (as opposed to the client code) add an
-	// Accept-Encoding gzip header? only if it we set it do
-	// we transparently decode the gzip.
-	addedGzip bool
-}
-
-// A writeRequest is sent by the readLoop's goroutine to the
-// writeLoop's goroutine to write a request while the read loop
-// concurrently waits on both the write response and the server's
-// reply.
-type writeRequest struct {
-	req *transportRequest
-	ch  chan<- error
-}
-
-type httpError struct {
-	err     string
-	timeout bool
-}
-
-func (e *httpError) Error() string   { return e.err }
-func (e *httpError) Timeout() bool   { return e.timeout }
-func (e *httpError) Temporary() bool { return true }
-
-var errTimeout error = &httpError{err: "net/http: timeout awaiting response headers", timeout: true}
-var errClosed error = &httpError{err: "net/http: transport closed before response was received"}
-
-func (pc *persistConn) roundTrip(req *transportRequest) (resp *Response, err error) {
-	pc.t.setReqCanceler(req.Request, pc.cancelRequest)
-	pc.lk.Lock()
-	pc.numExpectedResponses++
-	headerFn := pc.mutateHeaderFunc
-	pc.lk.Unlock()
-
-	if headerFn != nil {
-		headerFn(req.extraHeaders())
-	}
-
-	// Ask for a compressed version if the caller didn't set their
-	// own value for Accept-Encoding. We only attempted to
-	// uncompress the gzip stream if we were the layer that
-	// requested it.
-	requestedGzip := false
-	if !pc.t.DisableCompression && req.Header.Get("Accept-Encoding") == "" && req.Method != "HEAD" {
-		// Request gzip only, not deflate. Deflate is ambiguous and
-		// not as universally supported anyway.
-		// See: http://www.gzip.org/zlib/zlib_faq.html#faq38
-		//
-		// Note that we don't request this for HEAD requests,
-		// due to a bug in nginx:
-		//   http://trac.nginx.org/nginx/ticket/358
-		//   http://golang.org/issue/5522
-		requestedGzip = true
-		req.extraHeaders().Set("Accept-Encoding", "gzip")
-	}
-
-	// Write the request concurrently with waiting for a response,
-	// in case the server decides to reply before reading our full
-	// request body.
-	writeErrCh := make(chan error, 1)
-	pc.writech <- writeRequest{req, writeErrCh}
-
-	resc := make(chan responseAndError, 1)
-	pc.reqch <- requestAndChan{req.Request, resc, requestedGzip}
-
-	var re responseAndError
-	var pconnDeadCh = pc.closech
-	var failTicker <-chan time.Time
-	var respHeaderTimer <-chan time.Time
-WaitResponse:
-	for {
-		select {
-		case err := <-writeErrCh:
-			if err != nil {
-				re = responseAndError{nil, err}
-				pc.close()
-				break WaitResponse
-			}
-			if d := pc.t.ResponseHeaderTimeout; d > 0 {
-				respHeaderTimer = time.After(d)
-			}
-		case <-pconnDeadCh:
-			// The persist connection is dead. This shouldn't
-			// usually happen (only with Connection: close responses
-			// with no response bodies), but if it does happen it
-			// means either a) the remote server hung up on us
-			// prematurely, or b) the readLoop sent us a response &
-			// closed its closech at roughly the same time, and we
-			// selected this case first, in which case a response
-			// might still be coming soon.
-			//
-			// We can't avoid the select race in b) by using a unbuffered
-			// resc channel instead, because then goroutines can
-			// leak if we exit due to other errors.
-			pconnDeadCh = nil                               // avoid spinning
-			failTicker = time.After(100 * time.Millisecond) // arbitrary time to wait for resc
-		case <-failTicker:
-			re = responseAndError{err: errClosed}
-			break WaitResponse
-		case <-respHeaderTimer:
-			pc.close()
-			re = responseAndError{err: errTimeout}
-			break WaitResponse
-		case re = <-resc:
-			break WaitResponse
-		}
-	}
-
-	pc.lk.Lock()
-	pc.numExpectedResponses--
-	pc.lk.Unlock()
-
-	if re.err != nil {
-		pc.t.setReqCanceler(req.Request, nil)
-	}
-	return re.res, re.err
-}
-
-// markBroken marks a connection as broken (so it's not reused).
-// It differs from close in that it doesn't close the underlying
-// connection for use when it's still being read.
-func (pc *persistConn) markBroken() {
-	pc.lk.Lock()
-	defer pc.lk.Unlock()
-	pc.broken = true
-}
-
-func (pc *persistConn) close() {
-	pc.lk.Lock()
-	defer pc.lk.Unlock()
-	pc.closeLocked()
-}
-
-func (pc *persistConn) closeLocked() {
-	pc.broken = true
-	if !pc.closed {
-		pc.conn.Close()
-		pc.closed = true
-		close(pc.closech)
-	}
-	pc.mutateHeaderFunc = nil
-}
-
-var portMap = map[string]string{
-	"http":  "80",
-	"https": "443",
-}
-
-// canonicalAddr returns url.Host but always with a ":port" suffix
-func canonicalAddr(url *url.URL) string {
-	addr := url.Host
-	if !hasPort(addr) {
-		return addr + ":" + portMap[url.Scheme]
-	}
-	return addr
-}
-
-// bodyEOFSignal wraps a ReadCloser but runs fn (if non-nil) at most
-// once, right before its final (error-producing) Read or Close call
-// returns. If earlyCloseFn is non-nil and Close is called before
-// io.EOF is seen, earlyCloseFn is called instead of fn, and its
-// return value is the return value from Close.
-type bodyEOFSignal struct {
-	body         io.ReadCloser
-	mu           sync.Mutex   // guards following 4 fields
-	closed       bool         // whether Close has been called
-	rerr         error        // sticky Read error
-	fn           func(error)  // error will be nil on Read io.EOF
-	earlyCloseFn func() error // optional alt Close func used if io.EOF not seen
-}
-
-func (es *bodyEOFSignal) Read(p []byte) (n int, err error) {
-	es.mu.Lock()
-	closed, rerr := es.closed, es.rerr
-	es.mu.Unlock()
-	if closed {
-		return 0, errors.New("http: read on closed response body")
-	}
-	if rerr != nil {
-		return 0, rerr
-	}
-
-	n, err = es.body.Read(p)
-	if err != nil {
-		es.mu.Lock()
-		defer es.mu.Unlock()
-		if es.rerr == nil {
-			es.rerr = err
-		}
-		es.condfn(err)
-	}
-	return
-}
-
-func (es *bodyEOFSignal) Close() error {
-	es.mu.Lock()
-	defer es.mu.Unlock()
-	if es.closed {
-		return nil
-	}
-	es.closed = true
-	if es.earlyCloseFn != nil && es.rerr != io.EOF {
-		return es.earlyCloseFn()
-	}
-	err := es.body.Close()
-	es.condfn(err)
-	return err
-}
-
-// caller must hold es.mu.
-func (es *bodyEOFSignal) condfn(err error) {
-	if es.fn == nil {
-		return
-	}
-	if err == io.EOF {
-		err = nil
-	}
-	es.fn(err)
-	es.fn = nil
-}
-
-// gzipReader wraps a response body so it can lazily
-// call gzip.NewReader on the first call to Read
-type gzipReader struct {
-	body io.ReadCloser // underlying Response.Body
-	zr   io.Reader     // lazily-initialized gzip reader
-}
-
-func (gz *gzipReader) Read(p []byte) (n int, err error) {
-	if gz.zr == nil {
-		gz.zr, err = gzip.NewReader(gz.body)
-		if err != nil {
-			return 0, err
-		}
-	}
-	return gz.zr.Read(p)
-}
-
-func (gz *gzipReader) Close() error {
-	return gz.body.Close()
-}
-
-type readerAndCloser struct {
-	io.Reader
-	io.Closer
-}
-
-type tlsHandshakeTimeoutError struct{}
-
-func (tlsHandshakeTimeoutError) Timeout() bool   { return true }
-func (tlsHandshakeTimeoutError) Temporary() bool { return true }
-func (tlsHandshakeTimeoutError) Error() string   { return "net/http: TLS handshake timeout" }
-
-type noteEOFReader struct {
-	r      io.Reader
-	sawEOF *bool
-}
-
-func (nr noteEOFReader) Read(p []byte) (n int, err error) {
-	n, err = nr.r.Read(p)
-	if err == io.EOF {
-		*nr.sawEOF = true
-	}
-	return
-}
diff --git a/src/pkg/net/http/transport_test.go b/src/pkg/net/http/transport_test.go
deleted file mode 100644
index 964ca0f..0000000
--- a/src/pkg/net/http/transport_test.go
+++ /dev/null
@@ -1,2173 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Tests for transport.go
-
-package http_test
-
-import (
-	"bufio"
-	"bytes"
-	"compress/gzip"
-	"crypto/rand"
-	"crypto/tls"
-	"errors"
-	"fmt"
-	"io"
-	"io/ioutil"
-	"log"
-	"net"
-	"net/http"
-	. "net/http"
-	"net/http/httptest"
-	"net/url"
-	"os"
-	"runtime"
-	"strconv"
-	"strings"
-	"sync"
-	"testing"
-	"time"
-)
-
-// TODO: test 5 pipelined requests with responses: 1) OK, 2) OK, Connection: Close
-//       and then verify that the final 2 responses get errors back.
-
-// hostPortHandler writes back the client's "host:port".
-var hostPortHandler = HandlerFunc(func(w ResponseWriter, r *Request) {
-	if r.FormValue("close") == "true" {
-		w.Header().Set("Connection", "close")
-	}
-	w.Write([]byte(r.RemoteAddr))
-})
-
-// testCloseConn is a net.Conn tracked by a testConnSet.
-type testCloseConn struct {
-	net.Conn
-	set *testConnSet
-}
-
-func (c *testCloseConn) Close() error {
-	c.set.remove(c)
-	return c.Conn.Close()
-}
-
-// testConnSet tracks a set of TCP connections and whether they've
-// been closed.
-type testConnSet struct {
-	t      *testing.T
-	mu     sync.Mutex // guards closed and list
-	closed map[net.Conn]bool
-	list   []net.Conn // in order created
-}
-
-func (tcs *testConnSet) insert(c net.Conn) {
-	tcs.mu.Lock()
-	defer tcs.mu.Unlock()
-	tcs.closed[c] = false
-	tcs.list = append(tcs.list, c)
-}
-
-func (tcs *testConnSet) remove(c net.Conn) {
-	tcs.mu.Lock()
-	defer tcs.mu.Unlock()
-	tcs.closed[c] = true
-}
-
-// some tests use this to manage raw tcp connections for later inspection
-func makeTestDial(t *testing.T) (*testConnSet, func(n, addr string) (net.Conn, error)) {
-	connSet := &testConnSet{
-		t:      t,
-		closed: make(map[net.Conn]bool),
-	}
-	dial := func(n, addr string) (net.Conn, error) {
-		c, err := net.Dial(n, addr)
-		if err != nil {
-			return nil, err
-		}
-		tc := &testCloseConn{c, connSet}
-		connSet.insert(tc)
-		return tc, nil
-	}
-	return connSet, dial
-}
-
-func (tcs *testConnSet) check(t *testing.T) {
-	tcs.mu.Lock()
-	defer tcs.mu.Unlock()
-	for i := 4; i >= 0; i-- {
-		for i, c := range tcs.list {
-			if tcs.closed[c] {
-				continue
-			}
-			if i != 0 {
-				tcs.mu.Unlock()
-				time.Sleep(50 * time.Millisecond)
-				tcs.mu.Lock()
-				continue
-			}
-			t.Errorf("TCP connection #%d, %p (of %d total) was not closed", i+1, c, len(tcs.list))
-		}
-	}
-}
-
-// Two subsequent requests and verify their response is the same.
-// The response from the server is our own IP:port
-func TestTransportKeepAlives(t *testing.T) {
-	defer afterTest(t)
-	ts := httptest.NewServer(hostPortHandler)
-	defer ts.Close()
-
-	for _, disableKeepAlive := range []bool{false, true} {
-		tr := &Transport{DisableKeepAlives: disableKeepAlive}
-		defer tr.CloseIdleConnections()
-		c := &Client{Transport: tr}
-
-		fetch := func(n int) string {
-			res, err := c.Get(ts.URL)
-			if err != nil {
-				t.Fatalf("error in disableKeepAlive=%v, req #%d, GET: %v", disableKeepAlive, n, err)
-			}
-			body, err := ioutil.ReadAll(res.Body)
-			if err != nil {
-				t.Fatalf("error in disableKeepAlive=%v, req #%d, ReadAll: %v", disableKeepAlive, n, err)
-			}
-			return string(body)
-		}
-
-		body1 := fetch(1)
-		body2 := fetch(2)
-
-		bodiesDiffer := body1 != body2
-		if bodiesDiffer != disableKeepAlive {
-			t.Errorf("error in disableKeepAlive=%v. unexpected bodiesDiffer=%v; body1=%q; body2=%q",
-				disableKeepAlive, bodiesDiffer, body1, body2)
-		}
-	}
-}
-
-func TestTransportConnectionCloseOnResponse(t *testing.T) {
-	defer afterTest(t)
-	ts := httptest.NewServer(hostPortHandler)
-	defer ts.Close()
-
-	connSet, testDial := makeTestDial(t)
-
-	for _, connectionClose := range []bool{false, true} {
-		tr := &Transport{
-			Dial: testDial,
-		}
-		c := &Client{Transport: tr}
-
-		fetch := func(n int) string {
-			req := new(Request)
-			var err error
-			req.URL, err = url.Parse(ts.URL + fmt.Sprintf("/?close=%v", connectionClose))
-			if err != nil {
-				t.Fatalf("URL parse error: %v", err)
-			}
-			req.Method = "GET"
-			req.Proto = "HTTP/1.1"
-			req.ProtoMajor = 1
-			req.ProtoMinor = 1
-
-			res, err := c.Do(req)
-			if err != nil {
-				t.Fatalf("error in connectionClose=%v, req #%d, Do: %v", connectionClose, n, err)
-			}
-			defer res.Body.Close()
-			body, err := ioutil.ReadAll(res.Body)
-			if err != nil {
-				t.Fatalf("error in connectionClose=%v, req #%d, ReadAll: %v", connectionClose, n, err)
-			}
-			return string(body)
-		}
-
-		body1 := fetch(1)
-		body2 := fetch(2)
-		bodiesDiffer := body1 != body2
-		if bodiesDiffer != connectionClose {
-			t.Errorf("error in connectionClose=%v. unexpected bodiesDiffer=%v; body1=%q; body2=%q",
-				connectionClose, bodiesDiffer, body1, body2)
-		}
-
-		tr.CloseIdleConnections()
-	}
-
-	connSet.check(t)
-}
-
-func TestTransportConnectionCloseOnRequest(t *testing.T) {
-	defer afterTest(t)
-	ts := httptest.NewServer(hostPortHandler)
-	defer ts.Close()
-
-	connSet, testDial := makeTestDial(t)
-
-	for _, connectionClose := range []bool{false, true} {
-		tr := &Transport{
-			Dial: testDial,
-		}
-		c := &Client{Transport: tr}
-
-		fetch := func(n int) string {
-			req := new(Request)
-			var err error
-			req.URL, err = url.Parse(ts.URL)
-			if err != nil {
-				t.Fatalf("URL parse error: %v", err)
-			}
-			req.Method = "GET"
-			req.Proto = "HTTP/1.1"
-			req.ProtoMajor = 1
-			req.ProtoMinor = 1
-			req.Close = connectionClose
-
-			res, err := c.Do(req)
-			if err != nil {
-				t.Fatalf("error in connectionClose=%v, req #%d, Do: %v", connectionClose, n, err)
-			}
-			body, err := ioutil.ReadAll(res.Body)
-			if err != nil {
-				t.Fatalf("error in connectionClose=%v, req #%d, ReadAll: %v", connectionClose, n, err)
-			}
-			return string(body)
-		}
-
-		body1 := fetch(1)
-		body2 := fetch(2)
-		bodiesDiffer := body1 != body2
-		if bodiesDiffer != connectionClose {
-			t.Errorf("error in connectionClose=%v. unexpected bodiesDiffer=%v; body1=%q; body2=%q",
-				connectionClose, bodiesDiffer, body1, body2)
-		}
-
-		tr.CloseIdleConnections()
-	}
-
-	connSet.check(t)
-}
-
-func TestTransportIdleCacheKeys(t *testing.T) {
-	defer afterTest(t)
-	ts := httptest.NewServer(hostPortHandler)
-	defer ts.Close()
-
-	tr := &Transport{DisableKeepAlives: false}
-	c := &Client{Transport: tr}
-
-	if e, g := 0, len(tr.IdleConnKeysForTesting()); e != g {
-		t.Errorf("After CloseIdleConnections expected %d idle conn cache keys; got %d", e, g)
-	}
-
-	resp, err := c.Get(ts.URL)
-	if err != nil {
-		t.Error(err)
-	}
-	ioutil.ReadAll(resp.Body)
-
-	keys := tr.IdleConnKeysForTesting()
-	if e, g := 1, len(keys); e != g {
-		t.Fatalf("After Get expected %d idle conn cache keys; got %d", e, g)
-	}
-
-	if e := "|http|" + ts.Listener.Addr().String(); keys[0] != e {
-		t.Errorf("Expected idle cache key %q; got %q", e, keys[0])
-	}
-
-	tr.CloseIdleConnections()
-	if e, g := 0, len(tr.IdleConnKeysForTesting()); e != g {
-		t.Errorf("After CloseIdleConnections expected %d idle conn cache keys; got %d", e, g)
-	}
-}
-
-// Tests that the HTTP transport re-uses connections when a client
-// reads to the end of a response Body without closing it.
-func TestTransportReadToEndReusesConn(t *testing.T) {
-	defer afterTest(t)
-	const msg = "foobar"
-
-	var addrSeen map[string]int
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
-		addrSeen[r.RemoteAddr]++
-		if r.URL.Path == "/chunked/" {
-			w.WriteHeader(200)
-			w.(http.Flusher).Flush()
-		} else {
-			w.Header().Set("Content-Type", strconv.Itoa(len(msg)))
-			w.WriteHeader(200)
-		}
-		w.Write([]byte(msg))
-	}))
-	defer ts.Close()
-
-	buf := make([]byte, len(msg))
-
-	for pi, path := range []string{"/content-length/", "/chunked/"} {
-		wantLen := []int{len(msg), -1}[pi]
-		addrSeen = make(map[string]int)
-		for i := 0; i < 3; i++ {
-			res, err := http.Get(ts.URL + path)
-			if err != nil {
-				t.Errorf("Get %s: %v", path, err)
-				continue
-			}
-			// We want to close this body eventually (before the
-			// defer afterTest at top runs), but not before the
-			// len(addrSeen) check at the bottom of this test,
-			// since Closing this early in the loop would risk
-			// making connections be re-used for the wrong reason.
-			defer res.Body.Close()
-
-			if res.ContentLength != int64(wantLen) {
-				t.Errorf("%s res.ContentLength = %d; want %d", path, res.ContentLength, wantLen)
-			}
-			n, err := res.Body.Read(buf)
-			if n != len(msg) || err != io.EOF {
-				t.Errorf("%s Read = %v, %v; want %d, EOF", path, n, err, len(msg))
-			}
-		}
-		if len(addrSeen) != 1 {
-			t.Errorf("for %s, server saw %d distinct client addresses; want 1", path, len(addrSeen))
-		}
-	}
-}
-
-func TestTransportMaxPerHostIdleConns(t *testing.T) {
-	defer afterTest(t)
-	resch := make(chan string)
-	gotReq := make(chan bool)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
-		gotReq <- true
-		msg := <-resch
-		_, err := w.Write([]byte(msg))
-		if err != nil {
-			t.Fatalf("Write: %v", err)
-		}
-	}))
-	defer ts.Close()
-	maxIdleConns := 2
-	tr := &Transport{DisableKeepAlives: false, MaxIdleConnsPerHost: maxIdleConns}
-	c := &Client{Transport: tr}
-
-	// Start 3 outstanding requests and wait for the server to get them.
-	// Their responses will hang until we write to resch, though.
-	donech := make(chan bool)
-	doReq := func() {
-		resp, err := c.Get(ts.URL)
-		if err != nil {
-			t.Error(err)
-			return
-		}
-		if _, err := ioutil.ReadAll(resp.Body); err != nil {
-			t.Errorf("ReadAll: %v", err)
-			return
-		}
-		donech <- true
-	}
-	go doReq()
-	<-gotReq
-	go doReq()
-	<-gotReq
-	go doReq()
-	<-gotReq
-
-	if e, g := 0, len(tr.IdleConnKeysForTesting()); e != g {
-		t.Fatalf("Before writes, expected %d idle conn cache keys; got %d", e, g)
-	}
-
-	resch <- "res1"
-	<-donech
-	keys := tr.IdleConnKeysForTesting()
-	if e, g := 1, len(keys); e != g {
-		t.Fatalf("after first response, expected %d idle conn cache keys; got %d", e, g)
-	}
-	cacheKey := "|http|" + ts.Listener.Addr().String()
-	if keys[0] != cacheKey {
-		t.Fatalf("Expected idle cache key %q; got %q", cacheKey, keys[0])
-	}
-	if e, g := 1, tr.IdleConnCountForTesting(cacheKey); e != g {
-		t.Errorf("after first response, expected %d idle conns; got %d", e, g)
-	}
-
-	resch <- "res2"
-	<-donech
-	if e, g := 2, tr.IdleConnCountForTesting(cacheKey); e != g {
-		t.Errorf("after second response, expected %d idle conns; got %d", e, g)
-	}
-
-	resch <- "res3"
-	<-donech
-	if e, g := maxIdleConns, tr.IdleConnCountForTesting(cacheKey); e != g {
-		t.Errorf("after third response, still expected %d idle conns; got %d", e, g)
-	}
-}
-
-func TestTransportServerClosingUnexpectedly(t *testing.T) {
-	defer afterTest(t)
-	ts := httptest.NewServer(hostPortHandler)
-	defer ts.Close()
-
-	tr := &Transport{}
-	c := &Client{Transport: tr}
-
-	fetch := func(n, retries int) string {
-		condFatalf := func(format string, arg ...interface{}) {
-			if retries <= 0 {
-				t.Fatalf(format, arg...)
-			}
-			t.Logf("retrying shortly after expected error: "+format, arg...)
-			time.Sleep(time.Second / time.Duration(retries))
-		}
-		for retries >= 0 {
-			retries--
-			res, err := c.Get(ts.URL)
-			if err != nil {
-				condFatalf("error in req #%d, GET: %v", n, err)
-				continue
-			}
-			body, err := ioutil.ReadAll(res.Body)
-			if err != nil {
-				condFatalf("error in req #%d, ReadAll: %v", n, err)
-				continue
-			}
-			res.Body.Close()
-			return string(body)
-		}
-		panic("unreachable")
-	}
-
-	body1 := fetch(1, 0)
-	body2 := fetch(2, 0)
-
-	ts.CloseClientConnections() // surprise!
-
-	// This test has an expected race. Sleeping for 25 ms prevents
-	// it on most fast machines, causing the next fetch() call to
-	// succeed quickly.  But if we do get errors, fetch() will retry 5
-	// times with some delays between.
-	time.Sleep(25 * time.Millisecond)
-
-	body3 := fetch(3, 5)
-
-	if body1 != body2 {
-		t.Errorf("expected body1 and body2 to be equal")
-	}
-	if body2 == body3 {
-		t.Errorf("expected body2 and body3 to be different")
-	}
-}
-
-// Test for http://golang.org/issue/2616 (appropriate issue number)
-// This fails pretty reliably with GOMAXPROCS=100 or something high.
-func TestStressSurpriseServerCloses(t *testing.T) {
-	defer afterTest(t)
-	if testing.Short() {
-		t.Skip("skipping test in short mode")
-	}
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
-		w.Header().Set("Content-Length", "5")
-		w.Header().Set("Content-Type", "text/plain")
-		w.Write([]byte("Hello"))
-		w.(Flusher).Flush()
-		conn, buf, _ := w.(Hijacker).Hijack()
-		buf.Flush()
-		conn.Close()
-	}))
-	defer ts.Close()
-
-	tr := &Transport{DisableKeepAlives: false}
-	c := &Client{Transport: tr}
-
-	// Do a bunch of traffic from different goroutines. Send to activityc
-	// after each request completes, regardless of whether it failed.
-	const (
-		numClients    = 50
-		reqsPerClient = 250
-	)
-	activityc := make(chan bool)
-	for i := 0; i < numClients; i++ {
-		go func() {
-			for i := 0; i < reqsPerClient; i++ {
-				res, err := c.Get(ts.URL)
-				if err == nil {
-					// We expect errors since the server is
-					// hanging up on us after telling us to
-					// send more requests, so we don't
-					// actually care what the error is.
-					// But we want to close the body in cases
-					// where we won the race.
-					res.Body.Close()
-				}
-				activityc <- true
-			}
-		}()
-	}
-
-	// Make sure all the request come back, one way or another.
-	for i := 0; i < numClients*reqsPerClient; i++ {
-		select {
-		case <-activityc:
-		case <-time.After(5 * time.Second):
-			t.Fatalf("presumed deadlock; no HTTP client activity seen in awhile")
-		}
-	}
-}
-
-// TestTransportHeadResponses verifies that we deal with Content-Lengths
-// with no bodies properly
-func TestTransportHeadResponses(t *testing.T) {
-	defer afterTest(t)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
-		if r.Method != "HEAD" {
-			panic("expected HEAD; got " + r.Method)
-		}
-		w.Header().Set("Content-Length", "123")
-		w.WriteHeader(200)
-	}))
-	defer ts.Close()
-
-	tr := &Transport{DisableKeepAlives: false}
-	c := &Client{Transport: tr}
-	for i := 0; i < 2; i++ {
-		res, err := c.Head(ts.URL)
-		if err != nil {
-			t.Errorf("error on loop %d: %v", i, err)
-			continue
-		}
-		if e, g := "123", res.Header.Get("Content-Length"); e != g {
-			t.Errorf("loop %d: expected Content-Length header of %q, got %q", i, e, g)
-		}
-		if e, g := int64(123), res.ContentLength; e != g {
-			t.Errorf("loop %d: expected res.ContentLength of %v, got %v", i, e, g)
-		}
-		if all, err := ioutil.ReadAll(res.Body); err != nil {
-			t.Errorf("loop %d: Body ReadAll: %v", i, err)
-		} else if len(all) != 0 {
-			t.Errorf("Bogus body %q", all)
-		}
-	}
-}
-
-// TestTransportHeadChunkedResponse verifies that we ignore chunked transfer-encoding
-// on responses to HEAD requests.
-func TestTransportHeadChunkedResponse(t *testing.T) {
-	defer afterTest(t)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
-		if r.Method != "HEAD" {
-			panic("expected HEAD; got " + r.Method)
-		}
-		w.Header().Set("Transfer-Encoding", "chunked") // client should ignore
-		w.Header().Set("x-client-ipport", r.RemoteAddr)
-		w.WriteHeader(200)
-	}))
-	defer ts.Close()
-
-	tr := &Transport{DisableKeepAlives: false}
-	c := &Client{Transport: tr}
-
-	res1, err := c.Head(ts.URL)
-	if err != nil {
-		t.Fatalf("request 1 error: %v", err)
-	}
-	res2, err := c.Head(ts.URL)
-	if err != nil {
-		t.Fatalf("request 2 error: %v", err)
-	}
-	if v1, v2 := res1.Header.Get("x-client-ipport"), res2.Header.Get("x-client-ipport"); v1 != v2 {
-		t.Errorf("ip/ports differed between head requests: %q vs %q", v1, v2)
-	}
-}
-
-var roundTripTests = []struct {
-	accept       string
-	expectAccept string
-	compressed   bool
-}{
-	// Requests with no accept-encoding header use transparent compression
-	{"", "gzip", false},
-	// Requests with other accept-encoding should pass through unmodified
-	{"foo", "foo", false},
-	// Requests with accept-encoding == gzip should be passed through
-	{"gzip", "gzip", true},
-}
-
-// Test that the modification made to the Request by the RoundTripper is cleaned up
-func TestRoundTripGzip(t *testing.T) {
-	defer afterTest(t)
-	const responseBody = "test response body"
-	ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) {
-		accept := req.Header.Get("Accept-Encoding")
-		if expect := req.FormValue("expect_accept"); accept != expect {
-			t.Errorf("in handler, test %v: Accept-Encoding = %q, want %q",
-				req.FormValue("testnum"), accept, expect)
-		}
-		if accept == "gzip" {
-			rw.Header().Set("Content-Encoding", "gzip")
-			gz := gzip.NewWriter(rw)
-			gz.Write([]byte(responseBody))
-			gz.Close()
-		} else {
-			rw.Header().Set("Content-Encoding", accept)
-			rw.Write([]byte(responseBody))
-		}
-	}))
-	defer ts.Close()
-
-	for i, test := range roundTripTests {
-		// Test basic request (no accept-encoding)
-		req, _ := NewRequest("GET", fmt.Sprintf("%s/?testnum=%d&expect_accept=%s", ts.URL, i, test.expectAccept), nil)
-		if test.accept != "" {
-			req.Header.Set("Accept-Encoding", test.accept)
-		}
-		res, err := DefaultTransport.RoundTrip(req)
-		var body []byte
-		if test.compressed {
-			var r *gzip.Reader
-			r, err = gzip.NewReader(res.Body)
-			if err != nil {
-				t.Errorf("%d. gzip NewReader: %v", i, err)
-				continue
-			}
-			body, err = ioutil.ReadAll(r)
-			res.Body.Close()
-		} else {
-			body, err = ioutil.ReadAll(res.Body)
-		}
-		if err != nil {
-			t.Errorf("%d. Error: %q", i, err)
-			continue
-		}
-		if g, e := string(body), responseBody; g != e {
-			t.Errorf("%d. body = %q; want %q", i, g, e)
-		}
-		if g, e := req.Header.Get("Accept-Encoding"), test.accept; g != e {
-			t.Errorf("%d. Accept-Encoding = %q; want %q (it was mutated, in violation of RoundTrip contract)", i, g, e)
-		}
-		if g, e := res.Header.Get("Content-Encoding"), test.accept; g != e {
-			t.Errorf("%d. Content-Encoding = %q; want %q", i, g, e)
-		}
-	}
-
-}
-
-func TestTransportGzip(t *testing.T) {
-	defer afterTest(t)
-	const testString = "The test string aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-	const nRandBytes = 1024 * 1024
-	ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) {
-		if req.Method == "HEAD" {
-			if g := req.Header.Get("Accept-Encoding"); g != "" {
-				t.Errorf("HEAD request sent with Accept-Encoding of %q; want none", g)
-			}
-			return
-		}
-		if g, e := req.Header.Get("Accept-Encoding"), "gzip"; g != e {
-			t.Errorf("Accept-Encoding = %q, want %q", g, e)
-		}
-		rw.Header().Set("Content-Encoding", "gzip")
-
-		var w io.Writer = rw
-		var buf bytes.Buffer
-		if req.FormValue("chunked") == "0" {
-			w = &buf
-			defer io.Copy(rw, &buf)
-			defer func() {
-				rw.Header().Set("Content-Length", strconv.Itoa(buf.Len()))
-			}()
-		}
-		gz := gzip.NewWriter(w)
-		gz.Write([]byte(testString))
-		if req.FormValue("body") == "large" {
-			io.CopyN(gz, rand.Reader, nRandBytes)
-		}
-		gz.Close()
-	}))
-	defer ts.Close()
-
-	for _, chunked := range []string{"1", "0"} {
-		c := &Client{Transport: &Transport{}}
-
-		// First fetch something large, but only read some of it.
-		res, err := c.Get(ts.URL + "/?body=large&chunked=" + chunked)
-		if err != nil {
-			t.Fatalf("large get: %v", err)
-		}
-		buf := make([]byte, len(testString))
-		n, err := io.ReadFull(res.Body, buf)
-		if err != nil {
-			t.Fatalf("partial read of large response: size=%d, %v", n, err)
-		}
-		if e, g := testString, string(buf); e != g {
-			t.Errorf("partial read got %q, expected %q", g, e)
-		}
-		res.Body.Close()
-		// Read on the body, even though it's closed
-		n, err = res.Body.Read(buf)
-		if n != 0 || err == nil {
-			t.Errorf("expected error post-closed large Read; got = %d, %v", n, err)
-		}
-
-		// Then something small.
-		res, err = c.Get(ts.URL + "/?chunked=" + chunked)
-		if err != nil {
-			t.Fatal(err)
-		}
-		body, err := ioutil.ReadAll(res.Body)
-		if err != nil {
-			t.Fatal(err)
-		}
-		if g, e := string(body), testString; g != e {
-			t.Fatalf("body = %q; want %q", g, e)
-		}
-		if g, e := res.Header.Get("Content-Encoding"), ""; g != e {
-			t.Fatalf("Content-Encoding = %q; want %q", g, e)
-		}
-
-		// Read on the body after it's been fully read:
-		n, err = res.Body.Read(buf)
-		if n != 0 || err == nil {
-			t.Errorf("expected Read error after exhausted reads; got %d, %v", n, err)
-		}
-		res.Body.Close()
-		n, err = res.Body.Read(buf)
-		if n != 0 || err == nil {
-			t.Errorf("expected Read error after Close; got %d, %v", n, err)
-		}
-	}
-
-	// And a HEAD request too, because they're always weird.
-	c := &Client{Transport: &Transport{}}
-	res, err := c.Head(ts.URL)
-	if err != nil {
-		t.Fatalf("Head: %v", err)
-	}
-	if res.StatusCode != 200 {
-		t.Errorf("Head status=%d; want=200", res.StatusCode)
-	}
-}
-
-func TestTransportProxy(t *testing.T) {
-	defer afterTest(t)
-	ch := make(chan string, 1)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
-		ch <- "real server"
-	}))
-	defer ts.Close()
-	proxy := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
-		ch <- "proxy for " + r.URL.String()
-	}))
-	defer proxy.Close()
-
-	pu, err := url.Parse(proxy.URL)
-	if err != nil {
-		t.Fatal(err)
-	}
-	c := &Client{Transport: &Transport{Proxy: ProxyURL(pu)}}
-	c.Head(ts.URL)
-	got := <-ch
-	want := "proxy for " + ts.URL + "/"
-	if got != want {
-		t.Errorf("want %q, got %q", want, got)
-	}
-}
-
-// TestTransportGzipRecursive sends a gzip quine and checks that the
-// client gets the same value back. This is more cute than anything,
-// but checks that we don't recurse forever, and checks that
-// Content-Encoding is removed.
-func TestTransportGzipRecursive(t *testing.T) {
-	defer afterTest(t)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
-		w.Header().Set("Content-Encoding", "gzip")
-		w.Write(rgz)
-	}))
-	defer ts.Close()
-
-	c := &Client{Transport: &Transport{}}
-	res, err := c.Get(ts.URL)
-	if err != nil {
-		t.Fatal(err)
-	}
-	body, err := ioutil.ReadAll(res.Body)
-	if err != nil {
-		t.Fatal(err)
-	}
-	if !bytes.Equal(body, rgz) {
-		t.Fatalf("Incorrect result from recursive gz:\nhave=%x\nwant=%x",
-			body, rgz)
-	}
-	if g, e := res.Header.Get("Content-Encoding"), ""; g != e {
-		t.Fatalf("Content-Encoding = %q; want %q", g, e)
-	}
-}
-
-// golang.org/issue/7750: request fails when server replies with
-// a short gzip body
-func TestTransportGzipShort(t *testing.T) {
-	defer afterTest(t)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
-		w.Header().Set("Content-Encoding", "gzip")
-		w.Write([]byte{0x1f, 0x8b})
-	}))
-	defer ts.Close()
-
-	tr := &Transport{}
-	defer tr.CloseIdleConnections()
-	c := &Client{Transport: tr}
-	res, err := c.Get(ts.URL)
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer res.Body.Close()
-	_, err = ioutil.ReadAll(res.Body)
-	if err == nil {
-		t.Fatal("Expect an error from reading a body.")
-	}
-	if err != io.ErrUnexpectedEOF {
-		t.Errorf("ReadAll error = %v; want io.ErrUnexpectedEOF", err)
-	}
-}
-
-// tests that persistent goroutine connections shut down when no longer desired.
-func TestTransportPersistConnLeak(t *testing.T) {
-	if runtime.GOOS == "plan9" {
-		t.Skip("skipping test; see http://golang.org/issue/7237")
-	}
-	defer afterTest(t)
-	gotReqCh := make(chan bool)
-	unblockCh := make(chan bool)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
-		gotReqCh <- true
-		<-unblockCh
-		w.Header().Set("Content-Length", "0")
-		w.WriteHeader(204)
-	}))
-	defer ts.Close()
-
-	tr := &Transport{}
-	c := &Client{Transport: tr}
-
-	n0 := runtime.NumGoroutine()
-
-	const numReq = 25
-	didReqCh := make(chan bool)
-	for i := 0; i < numReq; i++ {
-		go func() {
-			res, err := c.Get(ts.URL)
-			didReqCh <- true
-			if err != nil {
-				t.Errorf("client fetch error: %v", err)
-				return
-			}
-			res.Body.Close()
-		}()
-	}
-
-	// Wait for all goroutines to be stuck in the Handler.
-	for i := 0; i < numReq; i++ {
-		<-gotReqCh
-	}
-
-	nhigh := runtime.NumGoroutine()
-
-	// Tell all handlers to unblock and reply.
-	for i := 0; i < numReq; i++ {
-		unblockCh <- true
-	}
-
-	// Wait for all HTTP clients to be done.
-	for i := 0; i < numReq; i++ {
-		<-didReqCh
-	}
-
-	tr.CloseIdleConnections()
-	time.Sleep(100 * time.Millisecond)
-	runtime.GC()
-	runtime.GC() // even more.
-	nfinal := runtime.NumGoroutine()
-
-	growth := nfinal - n0
-
-	// We expect 0 or 1 extra goroutine, empirically.  Allow up to 5.
-	// Previously we were leaking one per numReq.
-	if int(growth) > 5 {
-		t.Logf("goroutine growth: %d -> %d -> %d (delta: %d)", n0, nhigh, nfinal, growth)
-		t.Error("too many new goroutines")
-	}
-}
-
-// golang.org/issue/4531: Transport leaks goroutines when
-// request.ContentLength is explicitly short
-func TestTransportPersistConnLeakShortBody(t *testing.T) {
-	if runtime.GOOS == "plan9" {
-		t.Skip("skipping test; see http://golang.org/issue/7237")
-	}
-	defer afterTest(t)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
-	}))
-	defer ts.Close()
-
-	tr := &Transport{}
-	c := &Client{Transport: tr}
-
-	n0 := runtime.NumGoroutine()
-	body := []byte("Hello")
-	for i := 0; i < 20; i++ {
-		req, err := NewRequest("POST", ts.URL, bytes.NewReader(body))
-		if err != nil {
-			t.Fatal(err)
-		}
-		req.ContentLength = int64(len(body) - 2) // explicitly short
-		_, err = c.Do(req)
-		if err == nil {
-			t.Fatal("Expect an error from writing too long of a body.")
-		}
-	}
-	nhigh := runtime.NumGoroutine()
-	tr.CloseIdleConnections()
-	time.Sleep(400 * time.Millisecond)
-	runtime.GC()
-	nfinal := runtime.NumGoroutine()
-
-	growth := nfinal - n0
-
-	// We expect 0 or 1 extra goroutine, empirically.  Allow up to 5.
-	// Previously we were leaking one per numReq.
-	t.Logf("goroutine growth: %d -> %d -> %d (delta: %d)", n0, nhigh, nfinal, growth)
-	if int(growth) > 5 {
-		t.Error("too many new goroutines")
-	}
-}
-
-// This used to crash; http://golang.org/issue/3266
-func TestTransportIdleConnCrash(t *testing.T) {
-	defer afterTest(t)
-	tr := &Transport{}
-	c := &Client{Transport: tr}
-
-	unblockCh := make(chan bool, 1)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
-		<-unblockCh
-		tr.CloseIdleConnections()
-	}))
-	defer ts.Close()
-
-	didreq := make(chan bool)
-	go func() {
-		res, err := c.Get(ts.URL)
-		if err != nil {
-			t.Error(err)
-		} else {
-			res.Body.Close() // returns idle conn
-		}
-		didreq <- true
-	}()
-	unblockCh <- true
-	<-didreq
-}
-
-// Test that the transport doesn't close the TCP connection early,
-// before the response body has been read.  This was a regression
-// which sadly lacked a triggering test.  The large response body made
-// the old race easier to trigger.
-func TestIssue3644(t *testing.T) {
-	defer afterTest(t)
-	const numFoos = 5000
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
-		w.Header().Set("Connection", "close")
-		for i := 0; i < numFoos; i++ {
-			w.Write([]byte("foo "))
-		}
-	}))
-	defer ts.Close()
-	tr := &Transport{}
-	c := &Client{Transport: tr}
-	res, err := c.Get(ts.URL)
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer res.Body.Close()
-	bs, err := ioutil.ReadAll(res.Body)
-	if err != nil {
-		t.Fatal(err)
-	}
-	if len(bs) != numFoos*len("foo ") {
-		t.Errorf("unexpected response length")
-	}
-}
-
-// Test that a client receives a server's reply, even if the server doesn't read
-// the entire request body.
-func TestIssue3595(t *testing.T) {
-	defer afterTest(t)
-	const deniedMsg = "sorry, denied."
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
-		Error(w, deniedMsg, StatusUnauthorized)
-	}))
-	defer ts.Close()
-	tr := &Transport{}
-	c := &Client{Transport: tr}
-	res, err := c.Post(ts.URL, "application/octet-stream", neverEnding('a'))
-	if err != nil {
-		t.Errorf("Post: %v", err)
-		return
-	}
-	got, err := ioutil.ReadAll(res.Body)
-	if err != nil {
-		t.Fatalf("Body ReadAll: %v", err)
-	}
-	if !strings.Contains(string(got), deniedMsg) {
-		t.Errorf("Known bug: response %q does not contain %q", got, deniedMsg)
-	}
-}
-
-// From http://golang.org/issue/4454 ,
-// "client fails to handle requests with no body and chunked encoding"
-func TestChunkedNoContent(t *testing.T) {
-	defer afterTest(t)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
-		w.WriteHeader(StatusNoContent)
-	}))
-	defer ts.Close()
-
-	for _, closeBody := range []bool{true, false} {
-		c := &Client{Transport: &Transport{}}
-		const n = 4
-		for i := 1; i <= n; i++ {
-			res, err := c.Get(ts.URL)
-			if err != nil {
-				t.Errorf("closingBody=%v, req %d/%d: %v", closeBody, i, n, err)
-			} else {
-				if closeBody {
-					res.Body.Close()
-				}
-			}
-		}
-	}
-}
-
-func TestTransportConcurrency(t *testing.T) {
-	defer afterTest(t)
-	maxProcs, numReqs := 16, 500
-	if testing.Short() {
-		maxProcs, numReqs = 4, 50
-	}
-	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(maxProcs))
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
-		fmt.Fprintf(w, "%v", r.FormValue("echo"))
-	}))
-	defer ts.Close()
-
-	var wg sync.WaitGroup
-	wg.Add(numReqs)
-
-	tr := &Transport{
-		Dial: func(netw, addr string) (c net.Conn, err error) {
-			// Due to the Transport's "socket late
-			// binding" (see idleConnCh in transport.go),
-			// the numReqs HTTP requests below can finish
-			// with a dial still outstanding.  So count
-			// our dials as work too so the leak checker
-			// doesn't complain at us.
-			wg.Add(1)
-			defer wg.Done()
-			return net.Dial(netw, addr)
-		},
-	}
-	defer tr.CloseIdleConnections()
-	c := &Client{Transport: tr}
-	reqs := make(chan string)
-	defer close(reqs)
-
-	for i := 0; i < maxProcs*2; i++ {
-		go func() {
-			for req := range reqs {
-				res, err := c.Get(ts.URL + "/?echo=" + req)
-				if err != nil {
-					t.Errorf("error on req %s: %v", req, err)
-					wg.Done()
-					continue
-				}
-				all, err := ioutil.ReadAll(res.Body)
-				if err != nil {
-					t.Errorf("read error on req %s: %v", req, err)
-					wg.Done()
-					continue
-				}
-				if string(all) != req {
-					t.Errorf("body of req %s = %q; want %q", req, all, req)
-				}
-				res.Body.Close()
-				wg.Done()
-			}
-		}()
-	}
-	for i := 0; i < numReqs; i++ {
-		reqs <- fmt.Sprintf("request-%d", i)
-	}
-	wg.Wait()
-}
-
-func TestIssue4191_InfiniteGetTimeout(t *testing.T) {
-	if runtime.GOOS == "plan9" {
-		t.Skip("skipping test; see http://golang.org/issue/7237")
-	}
-	defer afterTest(t)
-	const debug = false
-	mux := NewServeMux()
-	mux.HandleFunc("/get", func(w ResponseWriter, r *Request) {
-		io.Copy(w, neverEnding('a'))
-	})
-	ts := httptest.NewServer(mux)
-	timeout := 100 * time.Millisecond
-
-	client := &Client{
-		Transport: &Transport{
-			Dial: func(n, addr string) (net.Conn, error) {
-				conn, err := net.Dial(n, addr)
-				if err != nil {
-					return nil, err
-				}
-				conn.SetDeadline(time.Now().Add(timeout))
-				if debug {
-					conn = NewLoggingConn("client", conn)
-				}
-				return conn, nil
-			},
-			DisableKeepAlives: true,
-		},
-	}
-
-	getFailed := false
-	nRuns := 5
-	if testing.Short() {
-		nRuns = 1
-	}
-	for i := 0; i < nRuns; i++ {
-		if debug {
-			println("run", i+1, "of", nRuns)
-		}
-		sres, err := client.Get(ts.URL + "/get")
-		if err != nil {
-			if !getFailed {
-				// Make the timeout longer, once.
-				getFailed = true
-				t.Logf("increasing timeout")
-				i--
-				timeout *= 10
-				continue
-			}
-			t.Errorf("Error issuing GET: %v", err)
-			break
-		}
-		_, err = io.Copy(ioutil.Discard, sres.Body)
-		if err == nil {
-			t.Errorf("Unexpected successful copy")
-			break
-		}
-	}
-	if debug {
-		println("tests complete; waiting for handlers to finish")
-	}
-	ts.Close()
-}
-
-func TestIssue4191_InfiniteGetToPutTimeout(t *testing.T) {
-	if runtime.GOOS == "plan9" {
-		t.Skip("skipping test; see http://golang.org/issue/7237")
-	}
-	defer afterTest(t)
-	const debug = false
-	mux := NewServeMux()
-	mux.HandleFunc("/get", func(w ResponseWriter, r *Request) {
-		io.Copy(w, neverEnding('a'))
-	})
-	mux.HandleFunc("/put", func(w ResponseWriter, r *Request) {
-		defer r.Body.Close()
-		io.Copy(ioutil.Discard, r.Body)
-	})
-	ts := httptest.NewServer(mux)
-	timeout := 100 * time.Millisecond
-
-	client := &Client{
-		Transport: &Transport{
-			Dial: func(n, addr string) (net.Conn, error) {
-				conn, err := net.Dial(n, addr)
-				if err != nil {
-					return nil, err
-				}
-				conn.SetDeadline(time.Now().Add(timeout))
-				if debug {
-					conn = NewLoggingConn("client", conn)
-				}
-				return conn, nil
-			},
-			DisableKeepAlives: true,
-		},
-	}
-
-	getFailed := false
-	nRuns := 5
-	if testing.Short() {
-		nRuns = 1
-	}
-	for i := 0; i < nRuns; i++ {
-		if debug {
-			println("run", i+1, "of", nRuns)
-		}
-		sres, err := client.Get(ts.URL + "/get")
-		if err != nil {
-			if !getFailed {
-				// Make the timeout longer, once.
-				getFailed = true
-				t.Logf("increasing timeout")
-				i--
-				timeout *= 10
-				continue
-			}
-			t.Errorf("Error issuing GET: %v", err)
-			break
-		}
-		req, _ := NewRequest("PUT", ts.URL+"/put", sres.Body)
-		_, err = client.Do(req)
-		if err == nil {
-			sres.Body.Close()
-			t.Errorf("Unexpected successful PUT")
-			break
-		}
-		sres.Body.Close()
-	}
-	if debug {
-		println("tests complete; waiting for handlers to finish")
-	}
-	ts.Close()
-}
-
-func TestTransportResponseHeaderTimeout(t *testing.T) {
-	defer afterTest(t)
-	if testing.Short() {
-		t.Skip("skipping timeout test in -short mode")
-	}
-	inHandler := make(chan bool, 1)
-	mux := NewServeMux()
-	mux.HandleFunc("/fast", func(w ResponseWriter, r *Request) {
-		inHandler <- true
-	})
-	mux.HandleFunc("/slow", func(w ResponseWriter, r *Request) {
-		inHandler <- true
-		time.Sleep(2 * time.Second)
-	})
-	ts := httptest.NewServer(mux)
-	defer ts.Close()
-
-	tr := &Transport{
-		ResponseHeaderTimeout: 500 * time.Millisecond,
-	}
-	defer tr.CloseIdleConnections()
-	c := &Client{Transport: tr}
-
-	tests := []struct {
-		path    string
-		want    int
-		wantErr string
-	}{
-		{path: "/fast", want: 200},
-		{path: "/slow", wantErr: "timeout awaiting response headers"},
-		{path: "/fast", want: 200},
-	}
-	for i, tt := range tests {
-		res, err := c.Get(ts.URL + tt.path)
-		select {
-		case <-inHandler:
-		case <-time.After(5 * time.Second):
-			t.Errorf("never entered handler for test index %d, %s", i, tt.path)
-			continue
-		}
-		if err != nil {
-			uerr, ok := err.(*url.Error)
-			if !ok {
-				t.Errorf("error is not an url.Error; got: %#v", err)
-				continue
-			}
-			nerr, ok := uerr.Err.(net.Error)
-			if !ok {
-				t.Errorf("error does not satisfy net.Error interface; got: %#v", err)
-				continue
-			}
-			if !nerr.Timeout() {
-				t.Errorf("want timeout error; got: %q", nerr)
-				continue
-			}
-			if strings.Contains(err.Error(), tt.wantErr) {
-				continue
-			}
-			t.Errorf("%d. unexpected error: %v", i, err)
-			continue
-		}
-		if tt.wantErr != "" {
-			t.Errorf("%d. no error. expected error: %v", i, tt.wantErr)
-			continue
-		}
-		if res.StatusCode != tt.want {
-			t.Errorf("%d for path %q status = %d; want %d", i, tt.path, res.StatusCode, tt.want)
-		}
-	}
-}
-
-func TestTransportCancelRequest(t *testing.T) {
-	defer afterTest(t)
-	if testing.Short() {
-		t.Skip("skipping test in -short mode")
-	}
-	unblockc := make(chan bool)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
-		fmt.Fprintf(w, "Hello")
-		w.(Flusher).Flush() // send headers and some body
-		<-unblockc
-	}))
-	defer ts.Close()
-	defer close(unblockc)
-
-	tr := &Transport{}
-	defer tr.CloseIdleConnections()
-	c := &Client{Transport: tr}
-
-	req, _ := NewRequest("GET", ts.URL, nil)
-	res, err := c.Do(req)
-	if err != nil {
-		t.Fatal(err)
-	}
-	go func() {
-		time.Sleep(1 * time.Second)
-		tr.CancelRequest(req)
-	}()
-	t0 := time.Now()
-	body, err := ioutil.ReadAll(res.Body)
-	d := time.Since(t0)
-
-	if err == nil {
-		t.Error("expected an error reading the body")
-	}
-	if string(body) != "Hello" {
-		t.Errorf("Body = %q; want Hello", body)
-	}
-	if d < 500*time.Millisecond {
-		t.Errorf("expected ~1 second delay; got %v", d)
-	}
-	// Verify no outstanding requests after readLoop/writeLoop
-	// goroutines shut down.
-	for tries := 3; tries > 0; tries-- {
-		n := tr.NumPendingRequestsForTesting()
-		if n == 0 {
-			break
-		}
-		time.Sleep(100 * time.Millisecond)
-		if tries == 1 {
-			t.Errorf("pending requests = %d; want 0", n)
-		}
-	}
-}
-
-func TestTransportCancelRequestInDial(t *testing.T) {
-	defer afterTest(t)
-	if testing.Short() {
-		t.Skip("skipping test in -short mode")
-	}
-	var logbuf bytes.Buffer
-	eventLog := log.New(&logbuf, "", 0)
-
-	unblockDial := make(chan bool)
-	defer close(unblockDial)
-
-	inDial := make(chan bool)
-	tr := &Transport{
-		Dial: func(network, addr string) (net.Conn, error) {
-			eventLog.Println("dial: blocking")
-			inDial <- true
-			<-unblockDial
-			return nil, errors.New("nope")
-		},
-	}
-	cl := &Client{Transport: tr}
-	gotres := make(chan bool)
-	req, _ := NewRequest("GET", "http://something.no-network.tld/", nil)
-	go func() {
-		_, err := cl.Do(req)
-		eventLog.Printf("Get = %v", err)
-		gotres <- true
-	}()
-
-	select {
-	case <-inDial:
-	case <-time.After(5 * time.Second):
-		t.Fatal("timeout; never saw blocking dial")
-	}
-
-	eventLog.Printf("canceling")
-	tr.CancelRequest(req)
-
-	select {
-	case <-gotres:
-	case <-time.After(5 * time.Second):
-		panic("hang. events are: " + logbuf.String())
-	}
-
-	got := logbuf.String()
-	want := `dial: blocking
-canceling
-Get = Get http://something.no-network.tld/: net/http: request canceled while waiting for connection
-`
-	if got != want {
-		t.Errorf("Got events:\n%s\nWant:\n%s", got, want)
-	}
-}
-
-// golang.org/issue/3672 -- Client can't close HTTP stream
-// Calling Close on a Response.Body used to just read until EOF.
-// Now it actually closes the TCP connection.
-func TestTransportCloseResponseBody(t *testing.T) {
-	defer afterTest(t)
-	writeErr := make(chan error, 1)
-	msg := []byte("young\n")
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
-		for {
-			_, err := w.Write(msg)
-			if err != nil {
-				writeErr <- err
-				return
-			}
-			w.(Flusher).Flush()
-		}
-	}))
-	defer ts.Close()
-
-	tr := &Transport{}
-	defer tr.CloseIdleConnections()
-	c := &Client{Transport: tr}
-
-	req, _ := NewRequest("GET", ts.URL, nil)
-	defer tr.CancelRequest(req)
-
-	res, err := c.Do(req)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	const repeats = 3
-	buf := make([]byte, len(msg)*repeats)
-	want := bytes.Repeat(msg, repeats)
-
-	_, err = io.ReadFull(res.Body, buf)
-	if err != nil {
-		t.Fatal(err)
-	}
-	if !bytes.Equal(buf, want) {
-		t.Fatalf("read %q; want %q", buf, want)
-	}
-	didClose := make(chan error, 1)
-	go func() {
-		didClose <- res.Body.Close()
-	}()
-	select {
-	case err := <-didClose:
-		if err != nil {
-			t.Errorf("Close = %v", err)
-		}
-	case <-time.After(10 * time.Second):
-		t.Fatal("too long waiting for close")
-	}
-	select {
-	case err := <-writeErr:
-		if err == nil {
-			t.Errorf("expected non-nil write error")
-		}
-	case <-time.After(10 * time.Second):
-		t.Fatal("too long waiting for write error")
-	}
-}
-
-type fooProto struct{}
-
-func (fooProto) RoundTrip(req *Request) (*Response, error) {
-	res := &Response{
-		Status:     "200 OK",
-		StatusCode: 200,
-		Header:     make(Header),
-		Body:       ioutil.NopCloser(strings.NewReader("You wanted " + req.URL.String())),
-	}
-	return res, nil
-}
-
-func TestTransportAltProto(t *testing.T) {
-	defer afterTest(t)
-	tr := &Transport{}
-	c := &Client{Transport: tr}
-	tr.RegisterProtocol("foo", fooProto{})
-	res, err := c.Get("foo://bar.com/path")
-	if err != nil {
-		t.Fatal(err)
-	}
-	bodyb, err := ioutil.ReadAll(res.Body)
-	if err != nil {
-		t.Fatal(err)
-	}
-	body := string(bodyb)
-	if e := "You wanted foo://bar.com/path"; body != e {
-		t.Errorf("got response %q, want %q", body, e)
-	}
-}
-
-func TestTransportNoHost(t *testing.T) {
-	defer afterTest(t)
-	tr := &Transport{}
-	_, err := tr.RoundTrip(&Request{
-		Header: make(Header),
-		URL: &url.URL{
-			Scheme: "http",
-		},
-	})
-	want := "http: no Host in request URL"
-	if got := fmt.Sprint(err); got != want {
-		t.Errorf("error = %v; want %q", err, want)
-	}
-}
-
-func TestTransportSocketLateBinding(t *testing.T) {
-	defer afterTest(t)
-
-	mux := NewServeMux()
-	fooGate := make(chan bool, 1)
-	mux.HandleFunc("/foo", func(w ResponseWriter, r *Request) {
-		w.Header().Set("foo-ipport", r.RemoteAddr)
-		w.(Flusher).Flush()
-		<-fooGate
-	})
-	mux.HandleFunc("/bar", func(w ResponseWriter, r *Request) {
-		w.Header().Set("bar-ipport", r.RemoteAddr)
-	})
-	ts := httptest.NewServer(mux)
-	defer ts.Close()
-
-	dialGate := make(chan bool, 1)
-	tr := &Transport{
-		Dial: func(n, addr string) (net.Conn, error) {
-			if <-dialGate {
-				return net.Dial(n, addr)
-			}
-			return nil, errors.New("manually closed")
-		},
-		DisableKeepAlives: false,
-	}
-	defer tr.CloseIdleConnections()
-	c := &Client{
-		Transport: tr,
-	}
-
-	dialGate <- true // only allow one dial
-	fooRes, err := c.Get(ts.URL + "/foo")
-	if err != nil {
-		t.Fatal(err)
-	}
-	fooAddr := fooRes.Header.Get("foo-ipport")
-	if fooAddr == "" {
-		t.Fatal("No addr on /foo request")
-	}
-	time.AfterFunc(200*time.Millisecond, func() {
-		// let the foo response finish so we can use its
-		// connection for /bar
-		fooGate <- true
-		io.Copy(ioutil.Discard, fooRes.Body)
-		fooRes.Body.Close()
-	})
-
-	barRes, err := c.Get(ts.URL + "/bar")
-	if err != nil {
-		t.Fatal(err)
-	}
-	barAddr := barRes.Header.Get("bar-ipport")
-	if barAddr != fooAddr {
-		t.Fatalf("/foo came from conn %q; /bar came from %q instead", fooAddr, barAddr)
-	}
-	barRes.Body.Close()
-	dialGate <- false
-}
-
-// Issue 2184
-func TestTransportReading100Continue(t *testing.T) {
-	defer afterTest(t)
-
-	const numReqs = 5
-	reqBody := func(n int) string { return fmt.Sprintf("request body %d", n) }
-	reqID := func(n int) string { return fmt.Sprintf("REQ-ID-%d", n) }
-
-	send100Response := func(w *io.PipeWriter, r *io.PipeReader) {
-		defer w.Close()
-		defer r.Close()
-		br := bufio.NewReader(r)
-		n := 0
-		for {
-			n++
-			req, err := ReadRequest(br)
-			if err == io.EOF {
-				return
-			}
-			if err != nil {
-				t.Error(err)
-				return
-			}
-			slurp, err := ioutil.ReadAll(req.Body)
-			if err != nil {
-				t.Errorf("Server request body slurp: %v", err)
-				return
-			}
-			id := req.Header.Get("Request-Id")
-			resCode := req.Header.Get("X-Want-Response-Code")
-			if resCode == "" {
-				resCode = "100 Continue"
-				if string(slurp) != reqBody(n) {
-					t.Errorf("Server got %q, %v; want %q", slurp, err, reqBody(n))
-				}
-			}
-			body := fmt.Sprintf("Response number %d", n)
-			v := []byte(strings.Replace(fmt.Sprintf(`HTTP/1.1 %s
-Date: Thu, 28 Feb 2013 17:55:41 GMT
-
-HTTP/1.1 200 OK
-Content-Type: text/html
-Echo-Request-Id: %s
-Content-Length: %d
-
-%s`, resCode, id, len(body), body), "\n", "\r\n", -1))
-			w.Write(v)
-			if id == reqID(numReqs) {
-				return
-			}
-		}
-
-	}
-
-	tr := &Transport{
-		Dial: func(n, addr string) (net.Conn, error) {
-			sr, sw := io.Pipe() // server read/write
-			cr, cw := io.Pipe() // client read/write
-			conn := &rwTestConn{
-				Reader: cr,
-				Writer: sw,
-				closeFunc: func() error {
-					sw.Close()
-					cw.Close()
-					return nil
-				},
-			}
-			go send100Response(cw, sr)
-			return conn, nil
-		},
-		DisableKeepAlives: false,
-	}
-	defer tr.CloseIdleConnections()
-	c := &Client{Transport: tr}
-
-	testResponse := func(req *Request, name string, wantCode int) {
-		res, err := c.Do(req)
-		if err != nil {
-			t.Fatalf("%s: Do: %v", name, err)
-		}
-		if res.StatusCode != wantCode {
-			t.Fatalf("%s: Response Statuscode=%d; want %d", name, res.StatusCode, wantCode)
-		}
-		if id, idBack := req.Header.Get("Request-Id"), res.Header.Get("Echo-Request-Id"); id != "" && id != idBack {
-			t.Errorf("%s: response id %q != request id %q", name, idBack, id)
-		}
-		_, err = ioutil.ReadAll(res.Body)
-		if err != nil {
-			t.Fatalf("%s: Slurp error: %v", name, err)
-		}
-	}
-
-	// Few 100 responses, making sure we're not off-by-one.
-	for i := 1; i <= numReqs; i++ {
-		req, _ := NewRequest("POST", "http://dummy.tld/", strings.NewReader(reqBody(i)))
-		req.Header.Set("Request-Id", reqID(i))
-		testResponse(req, fmt.Sprintf("100, %d/%d", i, numReqs), 200)
-	}
-
-	// And some other informational 1xx but non-100 responses, to test
-	// we return them but don't re-use the connection.
-	for i := 1; i <= numReqs; i++ {
-		req, _ := NewRequest("POST", "http://other.tld/", strings.NewReader(reqBody(i)))
-		req.Header.Set("X-Want-Response-Code", "123 Sesame Street")
-		testResponse(req, fmt.Sprintf("123, %d/%d", i, numReqs), 123)
-	}
-}
-
-type proxyFromEnvTest struct {
-	req     string // URL to fetch; blank means "http://example.com"
-	env     string
-	noenv   string
-	want    string
-	wanterr error
-}
-
-func (t proxyFromEnvTest) String() string {
-	var buf bytes.Buffer
-	if t.env != "" {
-		fmt.Fprintf(&buf, "http_proxy=%q", t.env)
-	}
-	if t.noenv != "" {
-		fmt.Fprintf(&buf, " no_proxy=%q", t.noenv)
-	}
-	req := "http://example.com"
-	if t.req != "" {
-		req = t.req
-	}
-	fmt.Fprintf(&buf, " req=%q", req)
-	return strings.TrimSpace(buf.String())
-}
-
-var proxyFromEnvTests = []proxyFromEnvTest{
-	{env: "127.0.0.1:8080", want: "http://127.0.0.1:8080"},
-	{env: "cache.corp.example.com:1234", want: "http://cache.corp.example.com:1234"},
-	{env: "cache.corp.example.com", want: "http://cache.corp.example.com"},
-	{env: "https://cache.corp.example.com", want: "https://cache.corp.example.com"},
-	{env: "http://127.0.0.1:8080", want: "http://127.0.0.1:8080"},
-	{env: "https://127.0.0.1:8080", want: "https://127.0.0.1:8080"},
-	{want: "<nil>"},
-	{noenv: "example.com", req: "http://example.com/", env: "proxy", want: "<nil>"},
-	{noenv: ".example.com", req: "http://example.com/", env: "proxy", want: "<nil>"},
-	{noenv: "ample.com", req: "http://example.com/", env: "proxy", want: "http://proxy"},
-	{noenv: "example.com", req: "http://foo.example.com/", env: "proxy", want: "<nil>"},
-	{noenv: ".foo.com", req: "http://example.com/", env: "proxy", want: "http://proxy"},
-}
-
-func TestProxyFromEnvironment(t *testing.T) {
-	ResetProxyEnv()
-	for _, tt := range proxyFromEnvTests {
-		os.Setenv("HTTP_PROXY", tt.env)
-		os.Setenv("NO_PROXY", tt.noenv)
-		ResetCachedEnvironment()
-		reqURL := tt.req
-		if reqURL == "" {
-			reqURL = "http://example.com"
-		}
-		req, _ := NewRequest("GET", reqURL, nil)
-		url, err := ProxyFromEnvironment(req)
-		if g, e := fmt.Sprintf("%v", err), fmt.Sprintf("%v", tt.wanterr); g != e {
-			t.Errorf("%v: got error = %q, want %q", tt, g, e)
-			continue
-		}
-		if got := fmt.Sprintf("%s", url); got != tt.want {
-			t.Errorf("%v: got URL = %q, want %q", tt, url, tt.want)
-		}
-	}
-}
-
-func TestIdleConnChannelLeak(t *testing.T) {
-	var mu sync.Mutex
-	var n int
-
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
-		mu.Lock()
-		n++
-		mu.Unlock()
-	}))
-	defer ts.Close()
-
-	tr := &Transport{
-		Dial: func(netw, addr string) (net.Conn, error) {
-			return net.Dial(netw, ts.Listener.Addr().String())
-		},
-	}
-	defer tr.CloseIdleConnections()
-
-	c := &Client{Transport: tr}
-
-	// First, without keep-alives.
-	for _, disableKeep := range []bool{true, false} {
-		tr.DisableKeepAlives = disableKeep
-		for i := 0; i < 5; i++ {
-			_, err := c.Get(fmt.Sprintf("http://foo-host-%d.tld/", i))
-			if err != nil {
-				t.Fatal(err)
-			}
-		}
-		if got := tr.IdleConnChMapSizeForTesting(); got != 0 {
-			t.Fatalf("ForDisableKeepAlives = %v, map size = %d; want 0", disableKeep, got)
-		}
-	}
-}
-
-// Verify the status quo: that the Client.Post function coerces its
-// body into a ReadCloser if it's a Closer, and that the Transport
-// then closes it.
-func TestTransportClosesRequestBody(t *testing.T) {
-	defer afterTest(t)
-	ts := httptest.NewServer(http.HandlerFunc(func(w ResponseWriter, r *Request) {
-		io.Copy(ioutil.Discard, r.Body)
-	}))
-	defer ts.Close()
-
-	tr := &Transport{}
-	defer tr.CloseIdleConnections()
-	cl := &Client{Transport: tr}
-
-	closes := 0
-
-	res, err := cl.Post(ts.URL, "text/plain", countCloseReader{&closes, strings.NewReader("hello")})
-	if err != nil {
-		t.Fatal(err)
-	}
-	res.Body.Close()
-	if closes != 1 {
-		t.Errorf("closes = %d; want 1", closes)
-	}
-}
-
-func TestTransportTLSHandshakeTimeout(t *testing.T) {
-	defer afterTest(t)
-	if testing.Short() {
-		t.Skip("skipping in short mode")
-	}
-	ln := newLocalListener(t)
-	defer ln.Close()
-	testdonec := make(chan struct{})
-	defer close(testdonec)
-
-	go func() {
-		c, err := ln.Accept()
-		if err != nil {
-			t.Error(err)
-			return
-		}
-		<-testdonec
-		c.Close()
-	}()
-
-	getdonec := make(chan struct{})
-	go func() {
-		defer close(getdonec)
-		tr := &Transport{
-			Dial: func(_, _ string) (net.Conn, error) {
-				return net.Dial("tcp", ln.Addr().String())
-			},
-			TLSHandshakeTimeout: 250 * time.Millisecond,
-		}
-		cl := &Client{Transport: tr}
-		_, err := cl.Get("https://dummy.tld/")
-		if err == nil {
-			t.Error("expected error")
-			return
-		}
-		ue, ok := err.(*url.Error)
-		if !ok {
-			t.Errorf("expected url.Error; got %#v", err)
-			return
-		}
-		ne, ok := ue.Err.(net.Error)
-		if !ok {
-			t.Errorf("expected net.Error; got %#v", err)
-			return
-		}
-		if !ne.Timeout() {
-			t.Errorf("expected timeout error; got %v", err)
-		}
-		if !strings.Contains(err.Error(), "handshake timeout") {
-			t.Errorf("expected 'handshake timeout' in error; got %v", err)
-		}
-	}()
-	select {
-	case <-getdonec:
-	case <-time.After(5 * time.Second):
-		t.Error("test timeout; TLS handshake hung?")
-	}
-}
-
-// Trying to repro golang.org/issue/3514
-func TestTLSServerClosesConnection(t *testing.T) {
-	defer afterTest(t)
-	if runtime.GOOS == "windows" {
-		t.Skip("skipping flaky test on Windows; golang.org/issue/7634")
-	}
-	closedc := make(chan bool, 1)
-	ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) {
-		if strings.Contains(r.URL.Path, "/keep-alive-then-die") {
-			conn, _, _ := w.(Hijacker).Hijack()
-			conn.Write([]byte("HTTP/1.1 200 OK\r\nContent-Length: 3\r\n\r\nfoo"))
-			conn.Close()
-			closedc <- true
-			return
-		}
-		fmt.Fprintf(w, "hello")
-	}))
-	defer ts.Close()
-	tr := &Transport{
-		TLSClientConfig: &tls.Config{
-			InsecureSkipVerify: true,
-		},
-	}
-	defer tr.CloseIdleConnections()
-	client := &Client{Transport: tr}
-
-	var nSuccess = 0
-	var errs []error
-	const trials = 20
-	for i := 0; i < trials; i++ {
-		tr.CloseIdleConnections()
-		res, err := client.Get(ts.URL + "/keep-alive-then-die")
-		if err != nil {
-			t.Fatal(err)
-		}
-		<-closedc
-		slurp, err := ioutil.ReadAll(res.Body)
-		if err != nil {
-			t.Fatal(err)
-		}
-		if string(slurp) != "foo" {
-			t.Errorf("Got %q, want foo", slurp)
-		}
-
-		// Now try again and see if we successfully
-		// pick a new connection.
-		res, err = client.Get(ts.URL + "/")
-		if err != nil {
-			errs = append(errs, err)
-			continue
-		}
-		slurp, err = ioutil.ReadAll(res.Body)
-		if err != nil {
-			errs = append(errs, err)
-			continue
-		}
-		nSuccess++
-	}
-	if nSuccess > 0 {
-		t.Logf("successes = %d of %d", nSuccess, trials)
-	} else {
-		t.Errorf("All runs failed:")
-	}
-	for _, err := range errs {
-		t.Logf("  err: %v", err)
-	}
-}
-
-// byteFromChanReader is an io.Reader that reads a single byte at a
-// time from the channel.  When the channel is closed, the reader
-// returns io.EOF.
-type byteFromChanReader chan byte
-
-func (c byteFromChanReader) Read(p []byte) (n int, err error) {
-	if len(p) == 0 {
-		return
-	}
-	b, ok := <-c
-	if !ok {
-		return 0, io.EOF
-	}
-	p[0] = b
-	return 1, nil
-}
-
-// Verifies that the Transport doesn't reuse a connection in the case
-// where the server replies before the request has been fully
-// written. We still honor that reply (see TestIssue3595), but don't
-// send future requests on the connection because it's then in a
-// questionable state.
-// golang.org/issue/7569
-func TestTransportNoReuseAfterEarlyResponse(t *testing.T) {
-	defer afterTest(t)
-	var sconn struct {
-		sync.Mutex
-		c net.Conn
-	}
-	var getOkay bool
-	closeConn := func() {
-		sconn.Lock()
-		defer sconn.Unlock()
-		if sconn.c != nil {
-			sconn.c.Close()
-			sconn.c = nil
-			if !getOkay {
-				t.Logf("Closed server connection")
-			}
-		}
-	}
-	defer closeConn()
-
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
-		if r.Method == "GET" {
-			io.WriteString(w, "bar")
-			return
-		}
-		conn, _, _ := w.(Hijacker).Hijack()
-		sconn.Lock()
-		sconn.c = conn
-		sconn.Unlock()
-		conn.Write([]byte("HTTP/1.1 200 OK\r\nContent-Length: 3\r\n\r\nfoo")) // keep-alive
-		go io.Copy(ioutil.Discard, conn)
-	}))
-	defer ts.Close()
-	tr := &Transport{}
-	defer tr.CloseIdleConnections()
-	client := &Client{Transport: tr}
-
-	const bodySize = 256 << 10
-	finalBit := make(byteFromChanReader, 1)
-	req, _ := NewRequest("POST", ts.URL, io.MultiReader(io.LimitReader(neverEnding('x'), bodySize-1), finalBit))
-	req.ContentLength = bodySize
-	res, err := client.Do(req)
-	if err := wantBody(res, err, "foo"); err != nil {
-		t.Errorf("POST response: %v", err)
-	}
-	donec := make(chan bool)
-	go func() {
-		defer close(donec)
-		res, err = client.Get(ts.URL)
-		if err := wantBody(res, err, "bar"); err != nil {
-			t.Errorf("GET response: %v", err)
-			return
-		}
-		getOkay = true // suppress test noise
-	}()
-	time.AfterFunc(5*time.Second, closeConn)
-	select {
-	case <-donec:
-		finalBit <- 'x' // unblock the writeloop of the first Post
-		close(finalBit)
-	case <-time.After(7 * time.Second):
-		t.Fatal("timeout waiting for GET request to finish")
-	}
-}
-
-type errorReader struct {
-	err error
-}
-
-func (e errorReader) Read(p []byte) (int, error) { return 0, e.err }
-
-type closerFunc func() error
-
-func (f closerFunc) Close() error { return f() }
-
-// Issue 6981
-func TestTransportClosesBodyOnError(t *testing.T) {
-	if runtime.GOOS == "plan9" {
-		t.Skip("skipping test; see http://golang.org/issue/7782")
-	}
-	defer afterTest(t)
-	readBody := make(chan error, 1)
-	ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
-		_, err := ioutil.ReadAll(r.Body)
-		readBody <- err
-	}))
-	defer ts.Close()
-	fakeErr := errors.New("fake error")
-	didClose := make(chan bool, 1)
-	req, _ := NewRequest("POST", ts.URL, struct {
-		io.Reader
-		io.Closer
-	}{
-		io.MultiReader(io.LimitReader(neverEnding('x'), 1<<20), errorReader{fakeErr}),
-		closerFunc(func() error {
-			select {
-			case didClose <- true:
-			default:
-			}
-			return nil
-		}),
-	})
-	res, err := DefaultClient.Do(req)
-	if res != nil {
-		defer res.Body.Close()
-	}
-	if err == nil || !strings.Contains(err.Error(), fakeErr.Error()) {
-		t.Fatalf("Do error = %v; want something containing %q", err, fakeErr.Error())
-	}
-	select {
-	case err := <-readBody:
-		if err == nil {
-			t.Errorf("Unexpected success reading request body from handler; want 'unexpected EOF reading trailer'")
-		}
-	case <-time.After(5 * time.Second):
-		t.Error("timeout waiting for server handler to complete")
-	}
-	select {
-	case <-didClose:
-	default:
-		t.Errorf("didn't see Body.Close")
-	}
-}
-
-func wantBody(res *http.Response, err error, want string) error {
-	if err != nil {
-		return err
-	}
-	slurp, err := ioutil.ReadAll(res.Body)
-	if err != nil {
-		return fmt.Errorf("error reading body: %v", err)
-	}
-	if string(slurp) != want {
-		return fmt.Errorf("body = %q; want %q", slurp, want)
-	}
-	if err := res.Body.Close(); err != nil {
-		return fmt.Errorf("body Close = %v", err)
-	}
-	return nil
-}
-
-func newLocalListener(t *testing.T) net.Listener {
-	ln, err := net.Listen("tcp", "127.0.0.1:0")
-	if err != nil {
-		ln, err = net.Listen("tcp6", "[::1]:0")
-	}
-	if err != nil {
-		t.Fatal(err)
-	}
-	return ln
-}
-
-type countCloseReader struct {
-	n *int
-	io.Reader
-}
-
-func (cr countCloseReader) Close() error {
-	(*cr.n)++
-	return nil
-}
-
-// rgz is a gzip quine that uncompresses to itself.
-var rgz = []byte{
-	0x1f, 0x8b, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x72, 0x65, 0x63, 0x75, 0x72, 0x73,
-	0x69, 0x76, 0x65, 0x00, 0x92, 0xef, 0xe6, 0xe0,
-	0x60, 0x00, 0x83, 0xa2, 0xd4, 0xe4, 0xd2, 0xa2,
-	0xe2, 0xcc, 0xb2, 0x54, 0x06, 0x00, 0x00, 0x17,
-	0x00, 0xe8, 0xff, 0x92, 0xef, 0xe6, 0xe0, 0x60,
-	0x00, 0x83, 0xa2, 0xd4, 0xe4, 0xd2, 0xa2, 0xe2,
-	0xcc, 0xb2, 0x54, 0x06, 0x00, 0x00, 0x17, 0x00,
-	0xe8, 0xff, 0x42, 0x12, 0x46, 0x16, 0x06, 0x00,
-	0x05, 0x00, 0xfa, 0xff, 0x42, 0x12, 0x46, 0x16,
-	0x06, 0x00, 0x05, 0x00, 0xfa, 0xff, 0x00, 0x05,
-	0x00, 0xfa, 0xff, 0x00, 0x14, 0x00, 0xeb, 0xff,
-	0x42, 0x12, 0x46, 0x16, 0x06, 0x00, 0x05, 0x00,
-	0xfa, 0xff, 0x00, 0x05, 0x00, 0xfa, 0xff, 0x00,
-	0x14, 0x00, 0xeb, 0xff, 0x42, 0x88, 0x21, 0xc4,
-	0x00, 0x00, 0x14, 0x00, 0xeb, 0xff, 0x42, 0x88,
-	0x21, 0xc4, 0x00, 0x00, 0x14, 0x00, 0xeb, 0xff,
-	0x42, 0x88, 0x21, 0xc4, 0x00, 0x00, 0x14, 0x00,
-	0xeb, 0xff, 0x42, 0x88, 0x21, 0xc4, 0x00, 0x00,
-	0x14, 0x00, 0xeb, 0xff, 0x42, 0x88, 0x21, 0xc4,
-	0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
-	0x00, 0xff, 0xff, 0x00, 0x17, 0x00, 0xe8, 0xff,
-	0x42, 0x88, 0x21, 0xc4, 0x00, 0x00, 0x00, 0x00,
-	0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00,
-	0x17, 0x00, 0xe8, 0xff, 0x42, 0x12, 0x46, 0x16,
-	0x06, 0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x08,
-	0x00, 0xf7, 0xff, 0x3d, 0xb1, 0x20, 0x85, 0xfa,
-	0x00, 0x00, 0x00, 0x42, 0x12, 0x46, 0x16, 0x06,
-	0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0x08, 0x00,
-	0xf7, 0xff, 0x3d, 0xb1, 0x20, 0x85, 0xfa, 0x00,
-	0x00, 0x00, 0x3d, 0xb1, 0x20, 0x85, 0xfa, 0x00,
-	0x00, 0x00,
-}
diff --git a/src/pkg/net/http/z_last_test.go b/src/pkg/net/http/z_last_test.go
deleted file mode 100644
index 5a0cc11..0000000
--- a/src/pkg/net/http/z_last_test.go
+++ /dev/null
@@ -1,97 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package http_test
-
-import (
-	"net/http"
-	"runtime"
-	"sort"
-	"strings"
-	"testing"
-	"time"
-)
-
-func interestingGoroutines() (gs []string) {
-	buf := make([]byte, 2<<20)
-	buf = buf[:runtime.Stack(buf, true)]
-	for _, g := range strings.Split(string(buf), "\n\n") {
-		sl := strings.SplitN(g, "\n", 2)
-		if len(sl) != 2 {
-			continue
-		}
-		stack := strings.TrimSpace(sl[1])
-		if stack == "" ||
-			strings.Contains(stack, "created by net.startServer") ||
-			strings.Contains(stack, "created by testing.RunTests") ||
-			strings.Contains(stack, "closeWriteAndWait") ||
-			strings.Contains(stack, "testing.Main(") ||
-			// These only show up with GOTRACEBACK=2; Issue 5005 (comment 28)
-			strings.Contains(stack, "runtime.goexit") ||
-			strings.Contains(stack, "created by runtime.gc") ||
-			strings.Contains(stack, "runtime.MHeap_Scavenger") {
-			continue
-		}
-		gs = append(gs, stack)
-	}
-	sort.Strings(gs)
-	return
-}
-
-// Verify the other tests didn't leave any goroutines running.
-// This is in a file named z_last_test.go so it sorts at the end.
-func TestGoroutinesRunning(t *testing.T) {
-	if testing.Short() {
-		t.Skip("not counting goroutines for leakage in -short mode")
-	}
-	gs := interestingGoroutines()
-
-	n := 0
-	stackCount := make(map[string]int)
-	for _, g := range gs {
-		stackCount[g]++
-		n++
-	}
-
-	t.Logf("num goroutines = %d", n)
-	if n > 0 {
-		t.Error("Too many goroutines.")
-		for stack, count := range stackCount {
-			t.Logf("%d instances of:\n%s", count, stack)
-		}
-	}
-}
-
-func afterTest(t *testing.T) {
-	http.DefaultTransport.(*http.Transport).CloseIdleConnections()
-	if testing.Short() {
-		return
-	}
-	var bad string
-	badSubstring := map[string]string{
-		").readLoop(":                                  "a Transport",
-		").writeLoop(":                                 "a Transport",
-		"created by net/http/httptest.(*Server).Start": "an httptest.Server",
-		"timeoutHandler":                               "a TimeoutHandler",
-		"net.(*netFD).connect(":                        "a timing out dial",
-		").noteClientGone(":                            "a closenotifier sender",
-	}
-	var stacks string
-	for i := 0; i < 4; i++ {
-		bad = ""
-		stacks = strings.Join(interestingGoroutines(), "\n\n")
-		for substr, what := range badSubstring {
-			if strings.Contains(stacks, substr) {
-				bad = what
-			}
-		}
-		if bad == "" {
-			return
-		}
-		// Bad stuff found, but goroutines might just still be
-		// shutting down, so give it some time.
-		time.Sleep(250 * time.Millisecond)
-	}
-	t.Errorf("Test appears to have leaked %s:\n%s", bad, stacks)
-}
diff --git a/src/pkg/net/ip.go b/src/pkg/net/ip.go
deleted file mode 100644
index 0582009..0000000
--- a/src/pkg/net/ip.go
+++ /dev/null
@@ -1,681 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// IP address manipulations
-//
-// IPv4 addresses are 4 bytes; IPv6 addresses are 16 bytes.
-// An IPv4 address can be converted to an IPv6 address by
-// adding a canonical prefix (10 zeros, 2 0xFFs).
-// This library accepts either size of byte slice but always
-// returns 16-byte addresses.
-
-package net
-
-import "errors"
-
-// IP address lengths (bytes).
-const (
-	IPv4len = 4
-	IPv6len = 16
-)
-
-// An IP is a single IP address, a slice of bytes.
-// Functions in this package accept either 4-byte (IPv4)
-// or 16-byte (IPv6) slices as input.
-//
-// Note that in this documentation, referring to an
-// IP address as an IPv4 address or an IPv6 address
-// is a semantic property of the address, not just the
-// length of the byte slice: a 16-byte slice can still
-// be an IPv4 address.
-type IP []byte
-
-// An IP mask is an IP address.
-type IPMask []byte
-
-// An IPNet represents an IP network.
-type IPNet struct {
-	IP   IP     // network number
-	Mask IPMask // network mask
-}
-
-// IPv4 returns the IP address (in 16-byte form) of the
-// IPv4 address a.b.c.d.
-func IPv4(a, b, c, d byte) IP {
-	p := make(IP, IPv6len)
-	copy(p, v4InV6Prefix)
-	p[12] = a
-	p[13] = b
-	p[14] = c
-	p[15] = d
-	return p
-}
-
-var v4InV6Prefix = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff}
-
-// IPv4Mask returns the IP mask (in 4-byte form) of the
-// IPv4 mask a.b.c.d.
-func IPv4Mask(a, b, c, d byte) IPMask {
-	p := make(IPMask, IPv4len)
-	p[0] = a
-	p[1] = b
-	p[2] = c
-	p[3] = d
-	return p
-}
-
-// CIDRMask returns an IPMask consisting of `ones' 1 bits
-// followed by 0s up to a total length of `bits' bits.
-// For a mask of this form, CIDRMask is the inverse of IPMask.Size.
-func CIDRMask(ones, bits int) IPMask {
-	if bits != 8*IPv4len && bits != 8*IPv6len {
-		return nil
-	}
-	if ones < 0 || ones > bits {
-		return nil
-	}
-	l := bits / 8
-	m := make(IPMask, l)
-	n := uint(ones)
-	for i := 0; i < l; i++ {
-		if n >= 8 {
-			m[i] = 0xff
-			n -= 8
-			continue
-		}
-		m[i] = ^byte(0xff >> n)
-		n = 0
-	}
-	return m
-}
-
-// Well-known IPv4 addresses
-var (
-	IPv4bcast     = IPv4(255, 255, 255, 255) // broadcast
-	IPv4allsys    = IPv4(224, 0, 0, 1)       // all systems
-	IPv4allrouter = IPv4(224, 0, 0, 2)       // all routers
-	IPv4zero      = IPv4(0, 0, 0, 0)         // all zeros
-)
-
-// Well-known IPv6 addresses
-var (
-	IPv6zero                   = IP{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
-	IPv6unspecified            = IP{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
-	IPv6loopback               = IP{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}
-	IPv6interfacelocalallnodes = IP{0xff, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01}
-	IPv6linklocalallnodes      = IP{0xff, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01}
-	IPv6linklocalallrouters    = IP{0xff, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x02}
-)
-
-// IsUnspecified returns true if ip is an unspecified address.
-func (ip IP) IsUnspecified() bool {
-	if ip.Equal(IPv4zero) || ip.Equal(IPv6unspecified) {
-		return true
-	}
-	return false
-}
-
-// IsLoopback returns true if ip is a loopback address.
-func (ip IP) IsLoopback() bool {
-	if ip4 := ip.To4(); ip4 != nil && ip4[0] == 127 {
-		return true
-	}
-	return ip.Equal(IPv6loopback)
-}
-
-// IsMulticast returns true if ip is a multicast address.
-func (ip IP) IsMulticast() bool {
-	if ip4 := ip.To4(); ip4 != nil && ip4[0]&0xf0 == 0xe0 {
-		return true
-	}
-	return ip[0] == 0xff
-}
-
-// IsInterfaceLinkLocalMulticast returns true if ip is
-// an interface-local multicast address.
-func (ip IP) IsInterfaceLocalMulticast() bool {
-	return len(ip) == IPv6len && ip[0] == 0xff && ip[1]&0x0f == 0x01
-}
-
-// IsLinkLocalMulticast returns true if ip is a link-local
-// multicast address.
-func (ip IP) IsLinkLocalMulticast() bool {
-	if ip4 := ip.To4(); ip4 != nil && ip4[0] == 224 && ip4[1] == 0 && ip4[2] == 0 {
-		return true
-	}
-	return ip[0] == 0xff && ip[1]&0x0f == 0x02
-}
-
-// IsLinkLocalUnicast returns true if ip is a link-local
-// unicast address.
-func (ip IP) IsLinkLocalUnicast() bool {
-	if ip4 := ip.To4(); ip4 != nil && ip4[0] == 169 && ip4[1] == 254 {
-		return true
-	}
-	return ip[0] == 0xfe && ip[1]&0xc0 == 0x80
-}
-
-// IsGlobalUnicast returns true if ip is a global unicast
-// address.
-func (ip IP) IsGlobalUnicast() bool {
-	return !ip.IsUnspecified() &&
-		!ip.IsLoopback() &&
-		!ip.IsMulticast() &&
-		!ip.IsLinkLocalUnicast()
-}
-
-// Is p all zeros?
-func isZeros(p IP) bool {
-	for i := 0; i < len(p); i++ {
-		if p[i] != 0 {
-			return false
-		}
-	}
-	return true
-}
-
-// To4 converts the IPv4 address ip to a 4-byte representation.
-// If ip is not an IPv4 address, To4 returns nil.
-func (ip IP) To4() IP {
-	if len(ip) == IPv4len {
-		return ip
-	}
-	if len(ip) == IPv6len &&
-		isZeros(ip[0:10]) &&
-		ip[10] == 0xff &&
-		ip[11] == 0xff {
-		return ip[12:16]
-	}
-	return nil
-}
-
-// To16 converts the IP address ip to a 16-byte representation.
-// If ip is not an IP address (it is the wrong length), To16 returns nil.
-func (ip IP) To16() IP {
-	if len(ip) == IPv4len {
-		return IPv4(ip[0], ip[1], ip[2], ip[3])
-	}
-	if len(ip) == IPv6len {
-		return ip
-	}
-	return nil
-}
-
-// Default route masks for IPv4.
-var (
-	classAMask = IPv4Mask(0xff, 0, 0, 0)
-	classBMask = IPv4Mask(0xff, 0xff, 0, 0)
-	classCMask = IPv4Mask(0xff, 0xff, 0xff, 0)
-)
-
-// DefaultMask returns the default IP mask for the IP address ip.
-// Only IPv4 addresses have default masks; DefaultMask returns
-// nil if ip is not a valid IPv4 address.
-func (ip IP) DefaultMask() IPMask {
-	if ip = ip.To4(); ip == nil {
-		return nil
-	}
-	switch true {
-	case ip[0] < 0x80:
-		return classAMask
-	case ip[0] < 0xC0:
-		return classBMask
-	default:
-		return classCMask
-	}
-}
-
-func allFF(b []byte) bool {
-	for _, c := range b {
-		if c != 0xff {
-			return false
-		}
-	}
-	return true
-}
-
-// Mask returns the result of masking the IP address ip with mask.
-func (ip IP) Mask(mask IPMask) IP {
-	if len(mask) == IPv6len && len(ip) == IPv4len && allFF(mask[:12]) {
-		mask = mask[12:]
-	}
-	if len(mask) == IPv4len && len(ip) == IPv6len && bytesEqual(ip[:12], v4InV6Prefix) {
-		ip = ip[12:]
-	}
-	n := len(ip)
-	if n != len(mask) {
-		return nil
-	}
-	out := make(IP, n)
-	for i := 0; i < n; i++ {
-		out[i] = ip[i] & mask[i]
-	}
-	return out
-}
-
-// String returns the string form of the IP address ip.
-// If the address is an IPv4 address, the string representation
-// is dotted decimal ("74.125.19.99").  Otherwise the representation
-// is IPv6 ("2001:4860:0:2001::68").
-func (ip IP) String() string {
-	p := ip
-
-	if len(ip) == 0 {
-		return "<nil>"
-	}
-
-	// If IPv4, use dotted notation.
-	if p4 := p.To4(); len(p4) == IPv4len {
-		return itod(uint(p4[0])) + "." +
-			itod(uint(p4[1])) + "." +
-			itod(uint(p4[2])) + "." +
-			itod(uint(p4[3]))
-	}
-	if len(p) != IPv6len {
-		return "?"
-	}
-
-	// Find longest run of zeros.
-	e0 := -1
-	e1 := -1
-	for i := 0; i < IPv6len; i += 2 {
-		j := i
-		for j < IPv6len && p[j] == 0 && p[j+1] == 0 {
-			j += 2
-		}
-		if j > i && j-i > e1-e0 {
-			e0 = i
-			e1 = j
-		}
-	}
-	// The symbol "::" MUST NOT be used to shorten just one 16 bit 0 field.
-	if e1-e0 <= 2 {
-		e0 = -1
-		e1 = -1
-	}
-
-	// Print with possible :: in place of run of zeros
-	var s string
-	for i := 0; i < IPv6len; i += 2 {
-		if i == e0 {
-			s += "::"
-			i = e1
-			if i >= IPv6len {
-				break
-			}
-		} else if i > 0 {
-			s += ":"
-		}
-		s += itox((uint(p[i])<<8)|uint(p[i+1]), 1)
-	}
-	return s
-}
-
-// ipEmptyString is like ip.String except that it returns
-// an empty string when ip is unset.
-func ipEmptyString(ip IP) string {
-	if len(ip) == 0 {
-		return ""
-	}
-	return ip.String()
-}
-
-// MarshalText implements the encoding.TextMarshaler interface.
-// The encoding is the same as returned by String.
-func (ip IP) MarshalText() ([]byte, error) {
-	if len(ip) == 0 {
-		return []byte(""), nil
-	}
-	if len(ip) != IPv4len && len(ip) != IPv6len {
-		return nil, errors.New("invalid IP address")
-	}
-	return []byte(ip.String()), nil
-}
-
-// UnmarshalText implements the encoding.TextUnmarshaler interface.
-// The IP address is expected in a form accepted by ParseIP.
-func (ip *IP) UnmarshalText(text []byte) error {
-	if len(text) == 0 {
-		*ip = nil
-		return nil
-	}
-	s := string(text)
-	x := ParseIP(s)
-	if x == nil {
-		return &ParseError{"IP address", s}
-	}
-	*ip = x
-	return nil
-}
-
-// Equal returns true if ip and x are the same IP address.
-// An IPv4 address and that same address in IPv6 form are
-// considered to be equal.
-func (ip IP) Equal(x IP) bool {
-	if len(ip) == len(x) {
-		return bytesEqual(ip, x)
-	}
-	if len(ip) == IPv4len && len(x) == IPv6len {
-		return bytesEqual(x[0:12], v4InV6Prefix) && bytesEqual(ip, x[12:])
-	}
-	if len(ip) == IPv6len && len(x) == IPv4len {
-		return bytesEqual(ip[0:12], v4InV6Prefix) && bytesEqual(ip[12:], x)
-	}
-	return false
-}
-
-func bytesEqual(x, y []byte) bool {
-	if len(x) != len(y) {
-		return false
-	}
-	for i, b := range x {
-		if y[i] != b {
-			return false
-		}
-	}
-	return true
-}
-
-// If mask is a sequence of 1 bits followed by 0 bits,
-// return the number of 1 bits.
-func simpleMaskLength(mask IPMask) int {
-	var n int
-	for i, v := range mask {
-		if v == 0xff {
-			n += 8
-			continue
-		}
-		// found non-ff byte
-		// count 1 bits
-		for v&0x80 != 0 {
-			n++
-			v <<= 1
-		}
-		// rest must be 0 bits
-		if v != 0 {
-			return -1
-		}
-		for i++; i < len(mask); i++ {
-			if mask[i] != 0 {
-				return -1
-			}
-		}
-		break
-	}
-	return n
-}
-
-// Size returns the number of leading ones and total bits in the mask.
-// If the mask is not in the canonical form--ones followed by zeros--then
-// Size returns 0, 0.
-func (m IPMask) Size() (ones, bits int) {
-	ones, bits = simpleMaskLength(m), len(m)*8
-	if ones == -1 {
-		return 0, 0
-	}
-	return
-}
-
-// String returns the hexadecimal form of m, with no punctuation.
-func (m IPMask) String() string {
-	s := ""
-	for _, b := range m {
-		s += itox(uint(b), 2)
-	}
-	if len(s) == 0 {
-		return "<nil>"
-	}
-	return s
-}
-
-func networkNumberAndMask(n *IPNet) (ip IP, m IPMask) {
-	if ip = n.IP.To4(); ip == nil {
-		ip = n.IP
-		if len(ip) != IPv6len {
-			return nil, nil
-		}
-	}
-	m = n.Mask
-	switch len(m) {
-	case IPv4len:
-		if len(ip) != IPv4len {
-			return nil, nil
-		}
-	case IPv6len:
-		if len(ip) == IPv4len {
-			m = m[12:]
-		}
-	default:
-		return nil, nil
-	}
-	return
-}
-
-// Contains reports whether the network includes ip.
-func (n *IPNet) Contains(ip IP) bool {
-	nn, m := networkNumberAndMask(n)
-	if x := ip.To4(); x != nil {
-		ip = x
-	}
-	l := len(ip)
-	if l != len(nn) {
-		return false
-	}
-	for i := 0; i < l; i++ {
-		if nn[i]&m[i] != ip[i]&m[i] {
-			return false
-		}
-	}
-	return true
-}
-
-// Network returns the address's network name, "ip+net".
-func (n *IPNet) Network() string { return "ip+net" }
-
-// String returns the CIDR notation of n like "192.168.100.1/24"
-// or "2001:DB8::/48" as defined in RFC 4632 and RFC 4291.
-// If the mask is not in the canonical form, it returns the
-// string which consists of an IP address, followed by a slash
-// character and a mask expressed as hexadecimal form with no
-// punctuation like "192.168.100.1/c000ff00".
-func (n *IPNet) String() string {
-	nn, m := networkNumberAndMask(n)
-	if nn == nil || m == nil {
-		return "<nil>"
-	}
-	l := simpleMaskLength(m)
-	if l == -1 {
-		return nn.String() + "/" + m.String()
-	}
-	return nn.String() + "/" + itod(uint(l))
-}
-
-// Parse IPv4 address (d.d.d.d).
-func parseIPv4(s string) IP {
-	var p [IPv4len]byte
-	i := 0
-	for j := 0; j < IPv4len; j++ {
-		if i >= len(s) {
-			// Missing octets.
-			return nil
-		}
-		if j > 0 {
-			if s[i] != '.' {
-				return nil
-			}
-			i++
-		}
-		var (
-			n  int
-			ok bool
-		)
-		n, i, ok = dtoi(s, i)
-		if !ok || n > 0xFF {
-			return nil
-		}
-		p[j] = byte(n)
-	}
-	if i != len(s) {
-		return nil
-	}
-	return IPv4(p[0], p[1], p[2], p[3])
-}
-
-// parseIPv6 parses s as a literal IPv6 address described in RFC 4291
-// and RFC 5952.  It can also parse a literal scoped IPv6 address with
-// zone identifier which is described in RFC 4007 when zoneAllowed is
-// true.
-func parseIPv6(s string, zoneAllowed bool) (ip IP, zone string) {
-	ip = make(IP, IPv6len)
-	ellipsis := -1 // position of ellipsis in p
-	i := 0         // index in string s
-
-	if zoneAllowed {
-		s, zone = splitHostZone(s)
-	}
-
-	// Might have leading ellipsis
-	if len(s) >= 2 && s[0] == ':' && s[1] == ':' {
-		ellipsis = 0
-		i = 2
-		// Might be only ellipsis
-		if i == len(s) {
-			return ip, zone
-		}
-	}
-
-	// Loop, parsing hex numbers followed by colon.
-	j := 0
-	for j < IPv6len {
-		// Hex number.
-		n, i1, ok := xtoi(s, i)
-		if !ok || n > 0xFFFF {
-			return nil, zone
-		}
-
-		// If followed by dot, might be in trailing IPv4.
-		if i1 < len(s) && s[i1] == '.' {
-			if ellipsis < 0 && j != IPv6len-IPv4len {
-				// Not the right place.
-				return nil, zone
-			}
-			if j+IPv4len > IPv6len {
-				// Not enough room.
-				return nil, zone
-			}
-			ip4 := parseIPv4(s[i:])
-			if ip4 == nil {
-				return nil, zone
-			}
-			ip[j] = ip4[12]
-			ip[j+1] = ip4[13]
-			ip[j+2] = ip4[14]
-			ip[j+3] = ip4[15]
-			i = len(s)
-			j += IPv4len
-			break
-		}
-
-		// Save this 16-bit chunk.
-		ip[j] = byte(n >> 8)
-		ip[j+1] = byte(n)
-		j += 2
-
-		// Stop at end of string.
-		i = i1
-		if i == len(s) {
-			break
-		}
-
-		// Otherwise must be followed by colon and more.
-		if s[i] != ':' || i+1 == len(s) {
-			return nil, zone
-		}
-		i++
-
-		// Look for ellipsis.
-		if s[i] == ':' {
-			if ellipsis >= 0 { // already have one
-				return nil, zone
-			}
-			ellipsis = j
-			if i++; i == len(s) { // can be at end
-				break
-			}
-		}
-	}
-
-	// Must have used entire string.
-	if i != len(s) {
-		return nil, zone
-	}
-
-	// If didn't parse enough, expand ellipsis.
-	if j < IPv6len {
-		if ellipsis < 0 {
-			return nil, zone
-		}
-		n := IPv6len - j
-		for k := j - 1; k >= ellipsis; k-- {
-			ip[k+n] = ip[k]
-		}
-		for k := ellipsis + n - 1; k >= ellipsis; k-- {
-			ip[k] = 0
-		}
-	} else if ellipsis >= 0 {
-		// Ellipsis must represent at least one 0 group.
-		return nil, zone
-	}
-	return ip, zone
-}
-
-// A ParseError represents a malformed text string and the type of string that was expected.
-type ParseError struct {
-	Type string
-	Text string
-}
-
-func (e *ParseError) Error() string {
-	return "invalid " + e.Type + ": " + e.Text
-}
-
-// ParseIP parses s as an IP address, returning the result.
-// The string s can be in dotted decimal ("74.125.19.99")
-// or IPv6 ("2001:4860:0:2001::68") form.
-// If s is not a valid textual representation of an IP address,
-// ParseIP returns nil.
-func ParseIP(s string) IP {
-	if ip := parseIPv4(s); ip != nil {
-		return ip
-	}
-	ip, _ := parseIPv6(s, false)
-	return ip
-}
-
-// ParseCIDR parses s as a CIDR notation IP address and mask,
-// like "192.168.100.1/24" or "2001:DB8::/48", as defined in
-// RFC 4632 and RFC 4291.
-//
-// It returns the IP address and the network implied by the IP
-// and mask.  For example, ParseCIDR("192.168.100.1/16") returns
-// the IP address 192.168.100.1 and the network 192.168.0.0/16.
-func ParseCIDR(s string) (IP, *IPNet, error) {
-	i := byteIndex(s, '/')
-	if i < 0 {
-		return nil, nil, &ParseError{"CIDR address", s}
-	}
-	addr, mask := s[:i], s[i+1:]
-	iplen := IPv4len
-	ip := parseIPv4(addr)
-	if ip == nil {
-		iplen = IPv6len
-		ip, _ = parseIPv6(addr, false)
-	}
-	n, i, ok := dtoi(mask, 0)
-	if ip == nil || !ok || i != len(mask) || n < 0 || n > 8*iplen {
-		return nil, nil, &ParseError{"CIDR address", s}
-	}
-	m := CIDRMask(n, 8*iplen)
-	return ip, &IPNet{IP: ip.Mask(m), Mask: m}, nil
-}
diff --git a/src/pkg/net/ip_test.go b/src/pkg/net/ip_test.go
deleted file mode 100644
index ffeb9d3..0000000
--- a/src/pkg/net/ip_test.go
+++ /dev/null
@@ -1,439 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package net
-
-import (
-	"reflect"
-	"runtime"
-	"testing"
-)
-
-var parseIPTests = []struct {
-	in  string
-	out IP
-}{
-	{"127.0.1.2", IPv4(127, 0, 1, 2)},
-	{"127.0.0.1", IPv4(127, 0, 0, 1)},
-	{"127.0.0.256", nil},
-	{"abc", nil},
-	{"123:", nil},
-	{"::ffff:127.0.0.1", IPv4(127, 0, 0, 1)},
-	{"2001:4860:0:2001::68", IP{0x20, 0x01, 0x48, 0x60, 0, 0, 0x20, 0x01, 0, 0, 0, 0, 0, 0, 0x00, 0x68}},
-	{"::ffff:4a7d:1363", IPv4(74, 125, 19, 99)},
-	{"fe80::1%lo0", nil},
-	{"fe80::1%911", nil},
-	{"", nil},
-	{"a1:a2:a3:a4::b1:b2:b3:b4", nil}, // Issue 6628
-}
-
-func TestParseIP(t *testing.T) {
-	for _, tt := range parseIPTests {
-		if out := ParseIP(tt.in); !reflect.DeepEqual(out, tt.out) {
-			t.Errorf("ParseIP(%q) = %v, want %v", tt.in, out, tt.out)
-		}
-		if tt.in == "" {
-			// Tested in TestMarshalEmptyIP below.
-			continue
-		}
-		var out IP
-		if err := out.UnmarshalText([]byte(tt.in)); !reflect.DeepEqual(out, tt.out) || (tt.out == nil) != (err != nil) {
-			t.Errorf("IP.UnmarshalText(%q) = %v, %v, want %v", tt.in, out, err, tt.out)
-		}
-	}
-}
-
-// Issue 6339
-func TestMarshalEmptyIP(t *testing.T) {
-	for _, in := range [][]byte{nil, []byte("")} {
-		var out = IP{1, 2, 3, 4}
-		if err := out.UnmarshalText(in); err != nil || out != nil {
-			t.Errorf("UnmarshalText(%v) = %v, %v; want nil, nil", in, out, err)
-		}
-	}
-	var ip IP
-	got, err := ip.MarshalText()
-	if err != nil {
-		t.Fatal(err)
-	}
-	if !reflect.DeepEqual(got, []byte("")) {
-		t.Errorf(`got %#v, want []byte("")`, got)
-	}
-}
-
-var ipStringTests = []struct {
-	in  IP
-	out string // see RFC 5952
-}{
-	{IP{0x20, 0x1, 0xd, 0xb8, 0, 0, 0, 0, 0, 0, 0x1, 0x23, 0, 0x12, 0, 0x1}, "2001:db8::123:12:1"},
-	{IP{0x20, 0x1, 0xd, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1}, "2001:db8::1"},
-	{IP{0x20, 0x1, 0xd, 0xb8, 0, 0, 0, 0x1, 0, 0, 0, 0x1, 0, 0, 0, 0x1}, "2001:db8:0:1:0:1:0:1"},
-	{IP{0x20, 0x1, 0xd, 0xb8, 0, 0x1, 0, 0, 0, 0x1, 0, 0, 0, 0x1, 0, 0}, "2001:db8:1:0:1:0:1:0"},
-	{IP{0x20, 0x1, 0, 0, 0, 0, 0, 0, 0, 0x1, 0, 0, 0, 0, 0, 0x1}, "2001::1:0:0:1"},
-	{IP{0x20, 0x1, 0xd, 0xb8, 0, 0, 0, 0, 0, 0x1, 0, 0, 0, 0, 0, 0}, "2001:db8:0:0:1::"},
-	{IP{0x20, 0x1, 0xd, 0xb8, 0, 0, 0, 0, 0, 0x1, 0, 0, 0, 0, 0, 0x1}, "2001:db8::1:0:0:1"},
-	{IP{0x20, 0x1, 0xD, 0xB8, 0, 0, 0, 0, 0, 0xA, 0, 0xB, 0, 0xC, 0, 0xD}, "2001:db8::a:b:c:d"},
-	{IPv4(192, 168, 0, 1), "192.168.0.1"},
-	{nil, ""},
-}
-
-func TestIPString(t *testing.T) {
-	for _, tt := range ipStringTests {
-		if tt.in != nil {
-			if out := tt.in.String(); out != tt.out {
-				t.Errorf("IP.String(%v) = %q, want %q", tt.in, out, tt.out)
-			}
-		}
-		if out, err := tt.in.MarshalText(); string(out) != tt.out || err != nil {
-			t.Errorf("IP.MarshalText(%v) = %q, %v, want %q, nil", tt.in, out, err, tt.out)
-		}
-	}
-}
-
-var ipMaskTests = []struct {
-	in   IP
-	mask IPMask
-	out  IP
-}{
-	{IPv4(192, 168, 1, 127), IPv4Mask(255, 255, 255, 128), IPv4(192, 168, 1, 0)},
-	{IPv4(192, 168, 1, 127), IPMask(ParseIP("255.255.255.192")), IPv4(192, 168, 1, 64)},
-	{IPv4(192, 168, 1, 127), IPMask(ParseIP("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffe0")), IPv4(192, 168, 1, 96)},
-	{IPv4(192, 168, 1, 127), IPv4Mask(255, 0, 255, 0), IPv4(192, 0, 1, 0)},
-	{ParseIP("2001:db8::1"), IPMask(ParseIP("ffff:ff80::")), ParseIP("2001:d80::")},
-	{ParseIP("2001:db8::1"), IPMask(ParseIP("f0f0:0f0f::")), ParseIP("2000:d08::")},
-}
-
-func TestIPMask(t *testing.T) {
-	for _, tt := range ipMaskTests {
-		if out := tt.in.Mask(tt.mask); out == nil || !tt.out.Equal(out) {
-			t.Errorf("IP(%v).Mask(%v) = %v, want %v", tt.in, tt.mask, out, tt.out)
-		}
-	}
-}
-
-var ipMaskStringTests = []struct {
-	in  IPMask
-	out string
-}{
-	{IPv4Mask(255, 255, 255, 240), "fffffff0"},
-	{IPv4Mask(255, 0, 128, 0), "ff008000"},
-	{IPMask(ParseIP("ffff:ff80::")), "ffffff80000000000000000000000000"},
-	{IPMask(ParseIP("ef00:ff80::cafe:0")), "ef00ff800000000000000000cafe0000"},
-	{nil, "<nil>"},
-}
-
-func TestIPMaskString(t *testing.T) {
-	for _, tt := range ipMaskStringTests {
-		if out := tt.in.String(); out != tt.out {
-			t.Errorf("IPMask.String(%v) = %q, want %q", tt.in, out, tt.out)
-		}
-	}
-}
-
-var parseCIDRTests = []struct {
-	in  string
-	ip  IP
-	net *IPNet
-	err error
-}{
-	{"135.104.0.0/32", IPv4(135, 104, 0, 0), &IPNet{IP: IPv4(135, 104, 0, 0), Mask: IPv4Mask(255, 255, 255, 255)}, nil},
-	{"0.0.0.0/24", IPv4(0, 0, 0, 0), &IPNet{IP: IPv4(0, 0, 0, 0), Mask: IPv4Mask(255, 255, 255, 0)}, nil},
-	{"135.104.0.0/24", IPv4(135, 104, 0, 0), &IPNet{IP: IPv4(135, 104, 0, 0), Mask: IPv4Mask(255, 255, 255, 0)}, nil},
-	{"135.104.0.1/32", IPv4(135, 104, 0, 1), &IPNet{IP: IPv4(135, 104, 0, 1), Mask: IPv4Mask(255, 255, 255, 255)}, nil},
-	{"135.104.0.1/24", IPv4(135, 104, 0, 1), &IPNet{IP: IPv4(135, 104, 0, 0), Mask: IPv4Mask(255, 255, 255, 0)}, nil},
-	{"::1/128", ParseIP("::1"), &IPNet{IP: ParseIP("::1"), Mask: IPMask(ParseIP("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"))}, nil},
-	{"abcd:2345::/127", ParseIP("abcd:2345::"), &IPNet{IP: ParseIP("abcd:2345::"), Mask: IPMask(ParseIP("ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffe"))}, nil},
-	{"abcd:2345::/65", ParseIP("abcd:2345::"), &IPNet{IP: ParseIP("abcd:2345::"), Mask: IPMask(ParseIP("ffff:ffff:ffff:ffff:8000::"))}, nil},
-	{"abcd:2345::/64", ParseIP("abcd:2345::"), &IPNet{IP: ParseIP("abcd:2345::"), Mask: IPMask(ParseIP("ffff:ffff:ffff:ffff::"))}, nil},
-	{"abcd:2345::/63", ParseIP("abcd:2345::"), &IPNet{IP: ParseIP("abcd:2345::"), Mask: IPMask(ParseIP("ffff:ffff:ffff:fffe::"))}, nil},
-	{"abcd:2345::/33", ParseIP("abcd:2345::"), &IPNet{IP: ParseIP("abcd:2345::"), Mask: IPMask(ParseIP("ffff:ffff:8000::"))}, nil},
-	{"abcd:2345::/32", ParseIP("abcd:2345::"), &IPNet{IP: ParseIP("abcd:2345::"), Mask: IPMask(ParseIP("ffff:ffff::"))}, nil},
-	{"abcd:2344::/31", ParseIP("abcd:2344::"), &IPNet{IP: ParseIP("abcd:2344::"), Mask: IPMask(ParseIP("ffff:fffe::"))}, nil},
-	{"abcd:2300::/24", ParseIP("abcd:2300::"), &IPNet{IP: ParseIP("abcd:2300::"), Mask: IPMask(ParseIP("ffff:ff00::"))}, nil},
-	{"abcd:2345::/24", ParseIP("abcd:2345::"), &IPNet{IP: ParseIP("abcd:2300::"), Mask: IPMask(ParseIP("ffff:ff00::"))}, nil},
-	{"2001:DB8::/48", ParseIP("2001:DB8::"), &IPNet{IP: ParseIP("2001:DB8::"), Mask: IPMask(ParseIP("ffff:ffff:ffff::"))}, nil},
-	{"2001:DB8::1/48", ParseIP("2001:DB8::1"), &IPNet{IP: ParseIP("2001:DB8::"), Mask: IPMask(ParseIP("ffff:ffff:ffff::"))}, nil},
-	{"192.168.1.1/255.255.255.0", nil, nil, &ParseError{"CIDR address", "192.168.1.1/255.255.255.0"}},
-	{"192.168.1.1/35", nil, nil, &ParseError{"CIDR address", "192.168.1.1/35"}},
-	{"2001:db8::1/-1", nil, nil, &ParseError{"CIDR address", "2001:db8::1/-1"}},
-	{"", nil, nil, &ParseError{"CIDR address", ""}},
-}
-
-func TestParseCIDR(t *testing.T) {
-	for _, tt := range parseCIDRTests {
-		ip, net, err := ParseCIDR(tt.in)
-		if !reflect.DeepEqual(err, tt.err) {
-			t.Errorf("ParseCIDR(%q) = %v, %v; want %v, %v", tt.in, ip, net, tt.ip, tt.net)
-		}
-		if err == nil && (!tt.ip.Equal(ip) || !tt.net.IP.Equal(net.IP) || !reflect.DeepEqual(net.Mask, tt.net.Mask)) {
-			t.Errorf("ParseCIDR(%q) = %v, {%v, %v}; want %v, {%v, %v}", tt.in, ip, net.IP, net.Mask, tt.ip, tt.net.IP, tt.net.Mask)
-		}
-	}
-}
-
-var ipNetContainsTests = []struct {
-	ip  IP
-	net *IPNet
-	ok  bool
-}{
-	{IPv4(172, 16, 1, 1), &IPNet{IP: IPv4(172, 16, 0, 0), Mask: CIDRMask(12, 32)}, true},
-	{IPv4(172, 24, 0, 1), &IPNet{IP: IPv4(172, 16, 0, 0), Mask: CIDRMask(13, 32)}, false},
-	{IPv4(192, 168, 0, 3), &IPNet{IP: IPv4(192, 168, 0, 0), Mask: IPv4Mask(0, 0, 255, 252)}, true},
-	{IPv4(192, 168, 0, 4), &IPNet{IP: IPv4(192, 168, 0, 0), Mask: IPv4Mask(0, 255, 0, 252)}, false},
-	{ParseIP("2001:db8:1:2::1"), &IPNet{IP: ParseIP("2001:db8:1::"), Mask: CIDRMask(47, 128)}, true},
-	{ParseIP("2001:db8:1:2::1"), &IPNet{IP: ParseIP("2001:db8:2::"), Mask: CIDRMask(47, 128)}, false},
-	{ParseIP("2001:db8:1:2::1"), &IPNet{IP: ParseIP("2001:db8:1::"), Mask: IPMask(ParseIP("ffff:0:ffff::"))}, true},
-	{ParseIP("2001:db8:1:2::1"), &IPNet{IP: ParseIP("2001:db8:1::"), Mask: IPMask(ParseIP("0:0:0:ffff::"))}, false},
-}
-
-func TestIPNetContains(t *testing.T) {
-	for _, tt := range ipNetContainsTests {
-		if ok := tt.net.Contains(tt.ip); ok != tt.ok {
-			t.Errorf("IPNet(%v).Contains(%v) = %v, want %v", tt.net, tt.ip, ok, tt.ok)
-		}
-	}
-}
-
-var ipNetStringTests = []struct {
-	in  *IPNet
-	out string
-}{
-	{&IPNet{IP: IPv4(192, 168, 1, 0), Mask: CIDRMask(26, 32)}, "192.168.1.0/26"},
-	{&IPNet{IP: IPv4(192, 168, 1, 0), Mask: IPv4Mask(255, 0, 255, 0)}, "192.168.1.0/ff00ff00"},
-	{&IPNet{IP: ParseIP("2001:db8::"), Mask: CIDRMask(55, 128)}, "2001:db8::/55"},
-	{&IPNet{IP: ParseIP("2001:db8::"), Mask: IPMask(ParseIP("8000:f123:0:cafe::"))}, "2001:db8::/8000f1230000cafe0000000000000000"},
-}
-
-func TestIPNetString(t *testing.T) {
-	for _, tt := range ipNetStringTests {
-		if out := tt.in.String(); out != tt.out {
-			t.Errorf("IPNet.String(%v) = %q, want %q", tt.in, out, tt.out)
-		}
-	}
-}
-
-var cidrMaskTests = []struct {
-	ones int
-	bits int
-	out  IPMask
-}{
-	{0, 32, IPv4Mask(0, 0, 0, 0)},
-	{12, 32, IPv4Mask(255, 240, 0, 0)},
-	{24, 32, IPv4Mask(255, 255, 255, 0)},
-	{32, 32, IPv4Mask(255, 255, 255, 255)},
-	{0, 128, IPMask{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
-	{4, 128, IPMask{0xf0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
-	{48, 128, IPMask{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
-	{128, 128, IPMask{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}},
-	{33, 32, nil},
-	{32, 33, nil},
-	{-1, 128, nil},
-	{128, -1, nil},
-}
-
-func TestCIDRMask(t *testing.T) {
-	for _, tt := range cidrMaskTests {
-		if out := CIDRMask(tt.ones, tt.bits); !reflect.DeepEqual(out, tt.out) {
-			t.Errorf("CIDRMask(%v, %v) = %v, want %v", tt.ones, tt.bits, out, tt.out)
-		}
-	}
-}
-
-var (
-	v4addr         = IP{192, 168, 0, 1}
-	v4mappedv6addr = IP{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 192, 168, 0, 1}
-	v6addr         = IP{0x20, 0x1, 0xd, 0xb8, 0, 0, 0, 0, 0, 0, 0x1, 0x23, 0, 0x12, 0, 0x1}
-	v4mask         = IPMask{255, 255, 255, 0}
-	v4mappedv6mask = IPMask{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 255, 255, 255, 0}
-	v6mask         = IPMask{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0}
-	badaddr        = IP{192, 168, 0}
-	badmask        = IPMask{255, 255, 0}
-	v4maskzero     = IPMask{0, 0, 0, 0}
-)
-
-var networkNumberAndMaskTests = []struct {
-	in  IPNet
-	out IPNet
-}{
-	{IPNet{IP: v4addr, Mask: v4mask}, IPNet{IP: v4addr, Mask: v4mask}},
-	{IPNet{IP: v4addr, Mask: v4mappedv6mask}, IPNet{IP: v4addr, Mask: v4mask}},
-	{IPNet{IP: v4mappedv6addr, Mask: v4mappedv6mask}, IPNet{IP: v4addr, Mask: v4mask}},
-	{IPNet{IP: v4mappedv6addr, Mask: v6mask}, IPNet{IP: v4addr, Mask: v4maskzero}},
-	{IPNet{IP: v4addr, Mask: v6mask}, IPNet{IP: v4addr, Mask: v4maskzero}},
-	{IPNet{IP: v6addr, Mask: v6mask}, IPNet{IP: v6addr, Mask: v6mask}},
-	{IPNet{IP: v6addr, Mask: v4mappedv6mask}, IPNet{IP: v6addr, Mask: v4mappedv6mask}},
-	{in: IPNet{IP: v6addr, Mask: v4mask}},
-	{in: IPNet{IP: v4addr, Mask: badmask}},
-	{in: IPNet{IP: v4mappedv6addr, Mask: badmask}},
-	{in: IPNet{IP: v6addr, Mask: badmask}},
-	{in: IPNet{IP: badaddr, Mask: v4mask}},
-	{in: IPNet{IP: badaddr, Mask: v4mappedv6mask}},
-	{in: IPNet{IP: badaddr, Mask: v6mask}},
-	{in: IPNet{IP: badaddr, Mask: badmask}},
-}
-
-func TestNetworkNumberAndMask(t *testing.T) {
-	for _, tt := range networkNumberAndMaskTests {
-		ip, m := networkNumberAndMask(&tt.in)
-		out := &IPNet{IP: ip, Mask: m}
-		if !reflect.DeepEqual(&tt.out, out) {
-			t.Errorf("networkNumberAndMask(%v) = %v, want %v", tt.in, out, &tt.out)
-		}
-	}
-}
-
-var splitJoinTests = []struct {
-	host string
-	port string
-	join string
-}{
-	{"www.google.com", "80", "www.google.com:80"},
-	{"127.0.0.1", "1234", "127.0.0.1:1234"},
-	{"::1", "80", "[::1]:80"},
-	{"fe80::1%lo0", "80", "[fe80::1%lo0]:80"},
-	{"localhost%lo0", "80", "[localhost%lo0]:80"},
-	{"", "0", ":0"},
-
-	{"google.com", "https%foo", "google.com:https%foo"}, // Go 1.0 behavior
-	{"127.0.0.1", "", "127.0.0.1:"},                     // Go 1.0 behaviour
-	{"www.google.com", "", "www.google.com:"},           // Go 1.0 behaviour
-}
-
-var splitFailureTests = []struct {
-	hostPort string
-	err      string
-}{
-	{"www.google.com", "missing port in address"},
-	{"127.0.0.1", "missing port in address"},
-	{"[::1]", "missing port in address"},
-	{"[fe80::1%lo0]", "missing port in address"},
-	{"[localhost%lo0]", "missing port in address"},
-	{"localhost%lo0", "missing port in address"},
-
-	{"::1", "too many colons in address"},
-	{"fe80::1%lo0", "too many colons in address"},
-	{"fe80::1%lo0:80", "too many colons in address"},
-
-	{"localhost%lo0:80", "missing brackets in address"},
-
-	// Test cases that didn't fail in Go 1.0
-
-	{"[foo:bar]", "missing port in address"},
-	{"[foo:bar]baz", "missing port in address"},
-	{"[foo]bar:baz", "missing port in address"},
-
-	{"[foo]:[bar]:baz", "too many colons in address"},
-
-	{"[foo]:[bar]baz", "unexpected '[' in address"},
-	{"foo[bar]:baz", "unexpected '[' in address"},
-
-	{"foo]bar:baz", "unexpected ']' in address"},
-}
-
-func TestSplitHostPort(t *testing.T) {
-	for _, tt := range splitJoinTests {
-		if host, port, err := SplitHostPort(tt.join); host != tt.host || port != tt.port || err != nil {
-			t.Errorf("SplitHostPort(%q) = %q, %q, %v; want %q, %q, nil", tt.join, host, port, err, tt.host, tt.port)
-		}
-	}
-	for _, tt := range splitFailureTests {
-		if _, _, err := SplitHostPort(tt.hostPort); err == nil {
-			t.Errorf("SplitHostPort(%q) should have failed", tt.hostPort)
-		} else {
-			e := err.(*AddrError)
-			if e.Err != tt.err {
-				t.Errorf("SplitHostPort(%q) = _, _, %q; want %q", tt.hostPort, e.Err, tt.err)
-			}
-		}
-	}
-}
-
-func TestJoinHostPort(t *testing.T) {
-	for _, tt := range splitJoinTests {
-		if join := JoinHostPort(tt.host, tt.port); join != tt.join {
-			t.Errorf("JoinHostPort(%q, %q) = %q; want %q", tt.host, tt.port, join, tt.join)
-		}
-	}
-}
-
-var ipAddrFamilyTests = []struct {
-	in  IP
-	af4 bool
-	af6 bool
-}{
-	{IPv4bcast, true, false},
-	{IPv4allsys, true, false},
-	{IPv4allrouter, true, false},
-	{IPv4zero, true, false},
-	{IPv4(224, 0, 0, 1), true, false},
-	{IPv4(127, 0, 0, 1), true, false},
-	{IPv4(240, 0, 0, 1), true, false},
-	{IPv6unspecified, false, true},
-	{IPv6loopback, false, true},
-	{IPv6interfacelocalallnodes, false, true},
-	{IPv6linklocalallnodes, false, true},
-	{IPv6linklocalallrouters, false, true},
-	{ParseIP("ff05::a:b:c:d"), false, true},
-	{ParseIP("fe80::1:2:3:4"), false, true},
-	{ParseIP("2001:db8::123:12:1"), false, true},
-}
-
-func TestIPAddrFamily(t *testing.T) {
-	for _, tt := range ipAddrFamilyTests {
-		if af := tt.in.To4() != nil; af != tt.af4 {
-			t.Errorf("verifying IPv4 address family for %q = %v, want %v", tt.in, af, tt.af4)
-		}
-		if af := len(tt.in) == IPv6len && tt.in.To4() == nil; af != tt.af6 {
-			t.Errorf("verifying IPv6 address family for %q = %v, want %v", tt.in, af, tt.af6)
-		}
-	}
-}
-
-var ipAddrScopeTests = []struct {
-	scope func(IP) bool
-	in    IP
-	ok    bool
-}{
-	{IP.IsUnspecified, IPv4zero, true},
-	{IP.IsUnspecified, IPv4(127, 0, 0, 1), false},
-	{IP.IsUnspecified, IPv6unspecified, true},
-	{IP.IsUnspecified, IPv6interfacelocalallnodes, false},
-	{IP.IsLoopback, IPv4(127, 0, 0, 1), true},
-	{IP.IsLoopback, IPv4(127, 255, 255, 254), true},
-	{IP.IsLoopback, IPv4(128, 1, 2, 3), false},
-	{IP.IsLoopback, IPv6loopback, true},
-	{IP.IsLoopback, IPv6linklocalallrouters, false},
-	{IP.IsMulticast, IPv4(224, 0, 0, 0), true},
-	{IP.IsMulticast, IPv4(239, 0, 0, 0), true},
-	{IP.IsMulticast, IPv4(240, 0, 0, 0), false},
-	{IP.IsMulticast, IPv6linklocalallnodes, true},
-	{IP.IsMulticast, IP{0xff, 0x05, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, true},
-	{IP.IsMulticast, IP{0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, false},
-	{IP.IsLinkLocalMulticast, IPv4(224, 0, 0, 0), true},
-	{IP.IsLinkLocalMulticast, IPv4(239, 0, 0, 0), false},
-	{IP.IsLinkLocalMulticast, IPv6linklocalallrouters, true},
-	{IP.IsLinkLocalMulticast, IP{0xff, 0x05, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, false},
-	{IP.IsLinkLocalUnicast, IPv4(169, 254, 0, 0), true},
-	{IP.IsLinkLocalUnicast, IPv4(169, 255, 0, 0), false},
-	{IP.IsLinkLocalUnicast, IP{0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, true},
-	{IP.IsLinkLocalUnicast, IP{0xfe, 0xc0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, false},
-	{IP.IsGlobalUnicast, IPv4(240, 0, 0, 0), true},
-	{IP.IsGlobalUnicast, IPv4(232, 0, 0, 0), false},
-	{IP.IsGlobalUnicast, IPv4(169, 254, 0, 0), false},
-	{IP.IsGlobalUnicast, IP{0x20, 0x1, 0xd, 0xb8, 0, 0, 0, 0, 0, 0, 0x1, 0x23, 0, 0x12, 0, 0x1}, true},
-	{IP.IsGlobalUnicast, IP{0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, false},
-	{IP.IsGlobalUnicast, IP{0xff, 0x05, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, false},
-}
-
-func name(f interface{}) string {
-	return runtime.FuncForPC(reflect.ValueOf(f).Pointer()).Name()
-}
-
-func TestIPAddrScope(t *testing.T) {
-	for _, tt := range ipAddrScopeTests {
-		if ok := tt.scope(tt.in); ok != tt.ok {
-			t.Errorf("%s(%q) = %v, want %v", name(tt.scope), tt.in, ok, tt.ok)
-		}
-	}
-}
diff --git a/src/pkg/net/ipraw_test.go b/src/pkg/net/ipraw_test.go
deleted file mode 100644
index 0632daf..0000000
--- a/src/pkg/net/ipraw_test.go
+++ /dev/null
@@ -1,289 +0,0 @@
-// Copyright 2009 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package net
-
-import (
-	"bytes"
-	"fmt"
-	"os"
-	"reflect"
-	"runtime"
-	"testing"
-	"time"
-)
-
-type resolveIPAddrTest struct {
-	net           string
-	litAddrOrName string
-	addr          *IPAddr
-	err           error
-}
-
-var resolveIPAddrTests = []resolveIPAddrTest{
-	{"ip", "127.0.0.1", &IPAddr{IP: IPv4(127, 0, 0, 1)}, nil},
-	{"ip4", "127.0.0.1", &IPAddr{IP: IPv4(127, 0, 0, 1)}, nil},
-	{"ip4:icmp", "127.0.0.1", &IPAddr{IP: IPv4(127, 0, 0, 1)}, nil},
-
-	{"ip", "::1", &IPAddr{IP: ParseIP("::1")}, nil},
-	{"ip6", "::1", &IPAddr{IP: ParseIP("::1")}, nil},
-	{"ip6:ipv6-icmp", "::1", &IPAddr{IP: ParseIP("::1")}, nil},
-	{"ip6:IPv6-ICMP", "::1", &IPAddr{IP: ParseIP("::1")}, nil},
-
-	{"ip", "::1%en0", &IPAddr{IP: ParseIP("::1"), Zone: "en0"}, nil},
-	{"ip6", "::1%911", &IPAddr{IP: ParseIP("::1"), Zone: "911"}, nil},
-
-	{"", "127.0.0.1", &IPAddr{IP: IPv4(127, 0, 0, 1)}, nil}, // Go 1.0 behavior
-	{"", "::1", &IPAddr{IP: ParseIP("::1")}, nil},           // Go 1.0 behavior
-
-	{"l2tp", "127.0.0.1", nil, UnknownNetworkError("l2tp")},
-	{"l2tp:gre", "127.0.0.1", nil, UnknownNetworkError("l2tp:gre")},
-	{"tcp", "1.2.3.4:123", nil, UnknownNetworkError("tcp")},
-}
-
-func init() {
-	if ifi := loopbackInterface(); ifi != nil {
-		index := fmt.Sprintf("%v", ifi.Index)
-		resolveIPAddrTests = append(resolveIPAddrTests, []resolveIPAddrTest{
-			{"ip6", "fe80::1%" + ifi.Name, &IPAddr{IP: ParseIP("fe80::1"), Zone: zoneToString(ifi.Index)}, nil},
-			{"ip6", "fe80::1%" + index, &IPAddr{IP: ParseIP("fe80::1"), Zone: index}, nil},
-		}...)
-	}
-	if ips, err := LookupIP("localhost"); err == nil && len(ips) > 1 && supportsIPv4 && supportsIPv6 {
-		resolveIPAddrTests = append(resolveIPAddrTests, []resolveIPAddrTest{
-			{"ip", "localhost", &IPAddr{IP: IPv4(127, 0, 0, 1)}, nil},
-			{"ip4", "localhost", &IPAddr{IP: IPv4(127, 0, 0, 1)}, nil},
-			{"ip6", "localhost", &IPAddr{IP: IPv6loopback}, nil},
-		}...)
-	}
-}
-
-func skipRawSocketTest(t *testing.T) (skip bool, skipmsg string) {
-	skip, skipmsg, err := skipRawSocketTests()
-	if err != nil {
-		t.Fatal(err)
-	}
-	return skip, skipmsg
-}
-
-func TestResolveIPAddr(t *testing.T) {
-	for _, tt := range resolveIPAddrTests {
-		addr, err := ResolveIPAddr(tt.net, tt.litAddrOrName)
-		if err != tt.err {
-			t.Fatalf("ResolveIPAddr(%v, %v) failed: %v", tt.net, tt.litAddrOrName, err)
-		} else if !reflect.DeepEqual(addr, tt.addr) {
-			t.Fatalf("got %#v; expected %#v", addr, tt.addr)
-		}
-	}
-}
-
-var icmpEchoTests = []struct {
-	net   string
-	laddr string
-	raddr string
-}{
-	{"ip4:icmp", "0.0.0.0", "127.0.0.1"},
-	{"ip6:ipv6-icmp", "::", "::1"},
-}
-
-func TestConnICMPEcho(t *testing.T) {
-	if skip, skipmsg := skipRawSocketTest(t); skip {
-		t.Skip(skipmsg)
-	}
-
-	for i, tt := range icmpEchoTests {
-		net, _, err := parseNetwork(tt.net)
-		if err != nil {
-			t.Fatalf("parseNetwork failed: %v", err)
-		}
-		if net == "ip6" && !supportsIPv6 {
-			continue
-		}
-
-		c, err := Dial(tt.net, tt.raddr)
-		if err != nil {
-			t.Fatalf("Dial failed: %v", err)
-		}
-		c.SetDeadline(time.Now().Add(100 * time.Millisecond))
-		defer c.Close()
-
-		typ := icmpv4EchoRequest
-		if net == "ip6" {
-			typ = icmpv6EchoRequest
-		}
-		xid, xseq := os.Getpid()&0xffff, i+1
-		wb, err := (&icmpMessage{
-			Type: typ, Code: 0,
-			Body: &icmpEcho{
-				ID: xid, Seq: xseq,
-				Data: bytes.Repeat([]byte("Go Go Gadget Ping!!!"), 3),
-			},
-		}).Marshal()
-		if err != nil {
-			t.Fatalf("icmpMessage.Marshal failed: %v", err)
-		}
-		if _, err := c.Write(wb); err != nil {
-			t.Fatalf("Conn.Write failed: %v", err)
-		}
-		var m *icmpMessage
-		rb := make([]byte, 20+len(wb))
-		for {
-			if _, err := c.Read(rb); err != nil {
-				t.Fatalf("Conn.Read failed: %v", err)
-			}
-			if net == "ip4" {
-				rb = ipv4Payload(rb)
-			}
-			if m, err = parseICMPMessage(rb); err != nil {
-				t.Fatalf("parseICMPMessage failed: %v", err)
-			}
-			switch m.Type {
-			case icmpv4EchoRequest, icmpv6EchoRequest:
-				continue
-			}
-			break
-		}
-		switch p := m.Body.(type) {
-		case *icmpEcho:
-			if p.ID != xid || p.Seq != xseq {
-				t.Fatalf("got id=%v, seqnum=%v; expected id=%v, seqnum=%v", p.ID, p.Seq, xid, xseq)
-			}
-		default:
-			t.Fatalf("got type=%v, code=%v; expected type=%v, code=%v", m.Type, m.Code, typ, 0)
-		}
-	}
-}
-
-func TestPacketConnICMPEcho(t *testing.T) {
-	if skip, skipmsg := skipRawSocketTest(t); skip {
-		t.Skip(skipmsg)
-	}
-
-	for i, tt := range icmpEchoTests {
-		net, _, err := parseNetwork(tt.net)
-		if err != nil {
-			t.Fatalf("parseNetwork failed: %v", err)
-		}
-		if net == "ip6" && !supportsIPv6 {
-			continue
-		}
-
-		c, err := ListenPacket(tt.net, tt.laddr)
-		if err != nil {
-			t.Fatalf("ListenPacket failed: %v", err)
-		}
-		c.SetDeadline(time.Now().Add(100 * time.Millisecond))
-		defer c.Close()
-
-		ra, err := ResolveIPAddr(tt.net, tt.raddr)
-		if err != nil {
-			t.Fatalf("ResolveIPAddr failed: %v", err)
-		}
-		typ := icmpv4EchoRequest
-		if net == "ip6" {
-			typ = icmpv6EchoRequest
-		}
-		xid, xseq := os.Getpid()&0xffff, i+1
-		wb, err := (&icmpMessage{
-			Type: typ, Code: 0,
-			Body: &icmpEcho{
-				ID: xid, Seq: xseq,
-				Data: bytes.Repeat([]byte("Go Go Gadget Ping!!!"), 3),
-			},
-		}).Marshal()
-		if err != nil {
-			t.Fatalf("icmpMessage.Marshal failed: %v", err)
-		}
-		if _, err := c.WriteTo(wb, ra); err != nil {
-			t.Fatalf("PacketConn.WriteTo failed: %v", err)
-		}
-		var m *icmpMessage
-		rb := make([]byte, 20+len(wb))
-		for {
-			if _, _, err := c.ReadFrom(rb); err != nil {
-				t.Fatalf("PacketConn.ReadFrom failed: %v", err)
-			}
-			// See BUG section.
-			//if net == "ip4" {
-			//	rb = ipv4Payload(rb)
-			//}
-			if m, err = parseICMPMessage(rb); err != nil {
-				t.Fatalf("parseICMPMessage failed: %v", err)
-			}
-			switch m.Type {
-			case icmpv4EchoRequest, icmpv6EchoRequest:
-				continue
-			}
-			break
-		}
-		switch p := m.Body.(type) {
-		case *icmpEcho:
-			if p.ID != xid || p.Seq != xseq {
-				t.Fatalf("got id=%v, seqnum=%v; expected id=%v, seqnum=%v", p.ID, p.Seq, xid, xseq)
-			}
-		default:
-			t.Fatalf("got type=%v, code=%v; expected type=%v, code=%v", m.Type, m.Code, typ, 0)
-		}
-	}
-}
-
-func ipv4Payload(b []byte) []byte {
-	if len(b) < 20 {
-		return b
-	}
-	hdrlen := int(b[0]&0x0f) << 2
-	return b[hdrlen:]
-}
-
-var ipConnLocalNameTests = []struct {
-	net   string
-	laddr *IPAddr
-}{
-	{"ip4:icmp", &IPAddr{IP: IPv4(127, 0, 0, 1)}},
-	{"ip4:icmp", &IPAddr{}},
-	{"ip4:icmp", nil},
-}
-
-func TestIPConnLocalName(t *testing.T) {
-	switch runtime.GOOS {
-	case "nacl", "plan9", "windows":
-		t.Skipf("skipping test on %q", runtime.GOOS)
-	default:
-		if os.Getuid() != 0 {
-			t.Skip("skipping test; must be root")
-		}
-	}
-
-	for _, tt := range ipConnLocalNameTests {
-		c, err := ListenIP(tt.net, tt.laddr)
-		if err != nil {
-			t.Fatalf("ListenIP failed: %v", err)
-		}
-		defer c.Close()
-		if la := c.LocalAddr(); la == nil {
-			t.Fatal("IPConn.LocalAddr failed")
-		}
-	}
-}
-
-func TestIPConnRemoteName(t *testing.T) {
-	switch runtime.GOOS {
-	case "plan9", "windows":
-		t.Skipf("skipping test on %q", runtime.GOOS)
-	default:
-		if os.Getuid() != 0 {
-			t.Skip("skipping test; must be root")
-		}
-	}
-
-	raddr := &IPAddr{IP: IPv4(127, 0, 0, 1).To4()}
-	c, err := DialIP("ip:tcp", &IPAddr{IP: IPv4(127, 0, 0, 1)}, raddr)
-	if err != nil {
-		t.Fatalf("DialIP failed: %v", err)
-	}
-	defer c.Close()
-	if !reflect.DeepEqual(raddr, c.RemoteAddr()) {
-		t.Fatalf("got %#v, expected %#v", c.RemoteAddr(), raddr)
-	}
-}
diff --git a/src/pkg/net/iprawsock_posix.go b/src/pkg/net/iprawsock_posix.go
deleted file mode 100644
index bbb3f3e..0000000
--- a/src/pkg/net/iprawsock_posix.go
+++ /dev/null
@@ -1,227 +0,0 @@
-// Copyright 2010 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris windows
-
-package net
-
-import (
-	"syscall"
-	"time"
-)
-
-// BUG(mikio): On every POSIX platform, reads from the "ip4" network
-// using the ReadFrom or ReadFromIP method might not return a complete
-// IPv4 packet, including its header, even if there is space
-// available. This can occur even in cases where Read or ReadMsgIP
-// could return a complete packet. For this reason, it is recommended
-// that you do not uses these methods if it is important to receive a
-// full packet.
-//
-// The Go 1 compatibility guidelines make it impossible for us to
-// change the behavior of these methods; use Read or ReadMsgIP
-// instead.
-
-func sockaddrToIP(sa syscall.Sockaddr) Addr {
-	switch sa := sa.(type) {
-	case *syscall.SockaddrInet4:
-		return &IPAddr{IP: sa.Addr[0:]}
-	case *syscall.SockaddrInet6:
-		return &IPAddr{IP: sa.Addr[0:], Zone: zoneToString(int(sa.ZoneId))}
-	}
-	return nil
-}
-
-func (a *IPAddr) family() int {
-	if a == nil || len(a.IP) <= IPv4len {
-		return syscall.AF_INET
-	}
-	if a.IP.To4() != nil {
-		return syscall.AF_INET
-	}
-	return syscall.AF_INET6
-}
-
-func (a *IPAddr) isWildcard() bool {
-	if a == nil || a.IP == nil {
-		return true
-	}
-	return a.IP.IsUnspecified()
-}
-
-func (a *IPAddr) sockaddr(family int) (syscall.Sockaddr, error) {
-	if a == nil {
-		return nil, nil
-	}
-	return ipToSockaddr(family, a.IP, 0, a.Zone)
-}
-
-// IPConn is the implementation of the Conn and PacketConn interfaces
-// for IP network connections.
-type IPConn struct {
-	conn
-}
-
-func newIPConn(fd *netFD) *IPConn { return &IPConn{conn{fd}} }
-
-// ReadFromIP reads an IP packet from c, copying the payload into b.
-// It returns the number of bytes copied into b and the return address
-// that was on the packet.
-//
-// ReadFromIP can be made to time out and return an error with
-// Timeout() == true after a fixed time limit; see SetDeadline and
-// SetReadDeadline.
-func (c *IPConn) ReadFromIP(b []byte) (int, *IPAddr, error) {
-	if !c.ok() {
-		return 0, nil, syscall.EINVAL
-	}
-	// TODO(cw,rsc): consider using readv if we know the family
-	// type to avoid the header trim/copy
-	var addr *IPAddr
-	n, sa, err := c.fd.readFrom(b)
-	switch sa := sa.(type) {
-	case *syscall.SockaddrInet4:
-		addr = &IPAddr{IP: sa.Addr[0:]}
-		if len(b) >= IPv4len { // discard ipv4 header
-			hsize := (int(b[0]) & 0xf) * 4
-			copy(b, b[hsize:])
-			n -= hsize
-		}
-	case *syscall.SockaddrInet6:
-		addr = &IPAddr{IP: sa.Addr[0:], Zone: zoneToString(int(sa.ZoneId))}
-	}
-	return n, addr, err
-}
-
-// ReadFrom implements the PacketConn ReadFrom method.
-func (c *IPConn) ReadFrom(b []byte) (int, Addr, error) {
-	if !c.ok() {
-		return 0, nil, syscall.EINVAL
-	}
-	n, addr, err := c.ReadFromIP(b)
-	return n, addr.toAddr(), err
-}
-
-// ReadMsgIP reads a packet from c, copying the payload into b and the
-// associated out-of-band data into oob.  It returns the number of
-// bytes copied into b, the number of bytes copied into oob, the flags
-// that were set on the packet and the source address of the packet.
-func (c *IPConn) ReadMsgIP(b, oob []byte) (n, oobn, flags int, addr *IPAddr, err error) {
-	if !c.ok() {
-		return 0, 0, 0, nil, syscall.EINVAL
-	}
-	var sa syscall.Sockaddr
-	n, oobn, flags, sa, err = c.fd.readMsg(b, oob)
-	switch sa := sa.(type) {
-	case *syscall.SockaddrInet4:
-		addr = &IPAddr{IP: sa.Addr[0:]}
-	case *syscall.SockaddrInet6:
-		addr = &IPAddr{IP: sa.Addr[0:], Zone: zoneToString(int(sa.ZoneId))}
-	}
-	return
-}
-
-// WriteToIP writes an IP packet to addr via c, copying the payload
-// from b.
-//
-// WriteToIP can be made to time out and return an error with
-// Timeout() == true after a fixed time limit; see SetDeadline and
-// SetWriteDeadline.  On packet-oriented connections, write timeouts
-// are rare.
-func (c *IPConn) WriteToIP(b []byte, addr *IPAddr) (int, error) {
-	if !c.ok() {
-		return 0, syscall.EINVAL
-	}
-	if c.fd.isConnected {
-		return 0, &OpError{Op: "write", Net: c.fd.net, Addr: addr, Err: ErrWriteToConnected}
-	}
-	if addr == nil {
-		return 0, &OpError{Op: "write", Net: c.fd.net, Addr: nil, Err: errMissingAddress}
-	}
-	sa, err := addr.sockaddr(c.fd.family)
-	if err != nil {
-		return 0, &OpError{"write", c.fd.net, addr, err}
-	}
-	return c.fd.writeTo(b, sa)
-}
-
-// WriteTo implements the PacketConn WriteTo method.
-func (c *IPConn) WriteTo(b []byte, addr Addr) (int, error) {
-	if !c.ok() {
-		return 0, syscall.EINVAL
-	}
-	a, ok := addr.(*IPAddr)
-	if !ok {
-		return 0, &OpError{"write", c.fd.net, addr, syscall.EINVAL}
-	}
-	return c.WriteToIP(b, a)
-}
-
-// WriteMsgIP writes a packet to addr via c, copying the payload from
-// b and the associated out-of-band data from oob.  It returns the
-// number of payload and out-of-band bytes written.
-func (c *IPConn) WriteMsgIP(b, oob []byte, addr *IPAddr) (n, oobn int, err error) {
-	if !c.ok() {
-		return 0, 0, syscall.EINVAL
-	}
-	if c.fd.isConnected {
-		return 0, 0, &OpError{Op: "write", Net: c.fd.net, Addr: addr, Err: ErrWriteToConnected}
-	}
-	if addr == nil {
-		return 0, 0, &OpError{Op: "write", Net: c.fd.net, Addr: nil, Err: errMissingAddress}
-	}
-	sa, err := addr.sockaddr(c.fd.family)
-	if err != nil {
-		return 0, 0, &OpError{"write", c.fd.net, addr, err}
-	}
-	return c.fd.writeMsg(b, oob, sa)
-}
-
-// DialIP connects to the remote address raddr on the network protocol
-// netProto, which must be "ip", "ip4", or "ip6" followed by a colon
-// and a protocol number or name.
-func DialIP(netProto string, laddr, raddr *IPAddr) (*IPConn, error) {
-	return dialIP(netProto, laddr, raddr, noDeadline)
-}
-
-func dialIP(netProto string, laddr, raddr *IPAddr, deadline time.Time) (*IPConn, error) {
-	net, proto, err := parseNetwork(netProto)
-	if err != nil {
-		return nil, &OpError{Op: "dial", Net: netProto, Addr: raddr, Err: err}
-	}
-	switch net {
-	case "ip", "ip4", "ip6":
-	default:
-		return nil, &OpError{Op: "dial", Net: netProto, Addr: raddr, Err: UnknownNetworkError(netProto)}
-	}
-	if raddr == nil {
-		return nil, &OpError{Op: "dial", Net: netProto, Addr: nil, Err: errMissingAddress}
-	}
-	fd, err := internetSocket(net, laddr, raddr, deadline, syscall.SOCK_RAW, proto, "dial", sockaddrToIP)
-	if err != nil {
-		return nil, &OpError{Op: "dial", Net: netProto, Addr: raddr, Err: err}
-	}
-	return newIPConn(fd), nil
-}
-
-// ListenIP listens for incoming IP packets addressed to the local
-// address laddr.  The returned connection's ReadFrom and WriteTo
-// methods can be used to receive and send IP packets with per-packet
-// addressing.
-func ListenIP(netProto string, laddr *IPAddr) (*IPConn, error) {
-	net, proto, err := parseNetwork(netProto)
-	if err != nil {
-		return nil, &OpError{Op: "dial", Net: netProto, Addr: laddr, Err: err}
-	}
-	switch net {
-	case "ip", "ip4", "ip6":
-	default:
-		return nil, &OpError{Op: "listen", Net: netProto, Addr: laddr, Err: UnknownNetworkError(netProto)}
-	}
-	fd, err := internetSocket(net, laddr, nil, noDeadline, syscall.SOCK_RAW, proto, "listen", sockaddrToIP)
-	if err != nil {
-		return nil, &OpError{Op: "listen", Net: netProto, Addr: laddr, Err: err}
-	}
-	return newIPConn(fd), nil
-}
diff --git a/src/pkg/net/ipsock_posix.go b/src/pkg/net/ipsock_posix.go
deleted file mode 100644
index 2ba4c8e..0000000
--- a/src/pkg/net/ipsock_posix.go
+++ /dev/null
@@ -1,177 +0,0 @@
-// Copyright 2009 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris windows
-
-// Internet protocol family sockets for POSIX
-
-package net
-
-import (
-	"syscall"
-	"time"
-)
-
-func probeIPv4Stack() bool {
-	s, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_STREAM, syscall.IPPROTO_TCP)
-	switch err {
-	case syscall.EAFNOSUPPORT, syscall.EPROTONOSUPPORT:
-		return false
-	case nil:
-		closesocket(s)
-	}
-	return true
-}
-
-// Should we try to use the IPv4 socket interface if we're
-// only dealing with IPv4 sockets?  As long as the host system
-// understands IPv6, it's okay to pass IPv4 addresses to the IPv6
-// interface.  That simplifies our code and is most general.
-// Unfortunately, we need to run on kernels built without IPv6
-// support too.  So probe the kernel to figure it out.
-//
-// probeIPv6Stack probes both basic IPv6 capability and IPv6 IPv4-
-// mapping capability which is controlled by IPV6_V6ONLY socket
-// option and/or kernel state "net.inet6.ip6.v6only".
-// It returns two boolean values.  If the first boolean value is
-// true, kernel supports basic IPv6 functionality.  If the second
-// boolean value is true, kernel supports IPv6 IPv4-mapping.
-func probeIPv6Stack() (supportsIPv6, supportsIPv4map bool) {
-	var probes = []struct {
-		laddr TCPAddr
-		value int
-		ok    bool
-	}{
-		// IPv6 communication capability
-		{laddr: TCPAddr{IP: ParseIP("::1")}, value: 1},
-		// IPv6 IPv4-mapped address communication capability
-		{laddr: TCPAddr{IP: IPv4(127, 0, 0, 1)}, value: 0},
-	}
-
-	for i := range probes {
-		s, err := syscall.Socket(syscall.AF_INET6, syscall.SOCK_STREAM, syscall.IPPROTO_TCP)
-		if err != nil {
-			continue
-		}
-		defer closesocket(s)
-		syscall.SetsockoptInt(s, syscall.IPPROTO_IPV6, syscall.IPV6_V6ONLY, probes[i].value)
-		sa, err := probes[i].laddr.sockaddr(syscall.AF_INET6)
-		if err != nil {
-			continue
-		}
-		if err := syscall.Bind(s, sa); err != nil {
-			continue
-		}
-		probes[i].ok = true
-	}
-
-	return probes[0].ok, probes[1].ok
-}
-
-// favoriteAddrFamily returns the appropriate address family to
-// the given net, laddr, raddr and mode.  At first it figures
-// address family out from the net.  If mode indicates "listen"
-// and laddr is a wildcard, it assumes that the user wants to
-// make a passive connection with a wildcard address family, both
-// AF_INET and AF_INET6, and a wildcard address like following:
-//
-//	1. A wild-wild listen, "tcp" + ""
-//	If the platform supports both IPv6 and IPv6 IPv4-mapping
-//	capabilities, we assume that the user want to listen on
-//	both IPv4 and IPv6 wildcard address over an AF_INET6
-//	socket with IPV6_V6ONLY=0.  Otherwise we prefer an IPv4
-//	wildcard address listen over an AF_INET socket.
-//
-//	2. A wild-ipv4wild listen, "tcp" + "0.0.0.0"
-//	Same as 1.
-//
-//	3. A wild-ipv6wild listen, "tcp" + "[::]"
-//	Almost same as 1 but we prefer an IPv6 wildcard address
-//	listen over an AF_INET6 socket with IPV6_V6ONLY=0 when
-//	the platform supports IPv6 capability but not IPv6 IPv4-
-//	mapping capability.
-//
-//	4. A ipv4-ipv4wild listen, "tcp4" + "" or "0.0.0.0"
-//	We use an IPv4 (AF_INET) wildcard address listen.
-//
-//	5. A ipv6-ipv6wild listen, "tcp6" + "" or "[::]"
-//	We use an IPv6 (AF_INET6, IPV6_V6ONLY=1) wildcard address
-//	listen.
-//
-// Otherwise guess: if the addresses are IPv4 then returns AF_INET,
-// or else returns AF_INET6.  It also returns a boolean value what
-// designates IPV6_V6ONLY option.
-//
-// Note that OpenBSD allows neither "net.inet6.ip6.v6only=1" change
-// nor IPPROTO_IPV6 level IPV6_V6ONLY socket option setting.
-func favoriteAddrFamily(net string, laddr, raddr sockaddr, mode string) (family int, ipv6only bool) {
-	switch net[len(net)-1] {
-	case '4':
-		return syscall.AF_INET, false
-	case '6':
-		return syscall.AF_INET6, true
-	}
-
-	if mode == "listen" && (laddr == nil || laddr.isWildcard()) {
-		if supportsIPv4map {
-			return syscall.AF_INET6, false
-		}
-		if laddr == nil {
-			return syscall.AF_INET, false
-		}
-		return laddr.family(), false
-	}
-
-	if (laddr == nil || laddr.family() == syscall.AF_INET) &&
-		(raddr == nil || raddr.family() == syscall.AF_INET) {
-		return syscall.AF_INET, false
-	}
-	return syscall.AF_INET6, false
-}
-
-// Internet sockets (TCP, UDP, IP)
-
-func internetSocket(net string, laddr, raddr sockaddr, deadline time.Time, sotype, proto int, mode string, toAddr func(syscall.Sockaddr) Addr) (fd *netFD, err error) {
-	family, ipv6only := favoriteAddrFamily(net, laddr, raddr, mode)
-	return socket(net, family, sotype, proto, ipv6only, laddr, raddr, deadline, toAddr)
-}
-
-func ipToSockaddr(family int, ip IP, port int, zone string) (syscall.Sockaddr, error) {
-	switch family {
-	case syscall.AF_INET:
-		if len(ip) == 0 {
-			ip = IPv4zero
-		}
-		if ip = ip.To4(); ip == nil {
-			return nil, InvalidAddrError("non-IPv4 address")
-		}
-		sa := new(syscall.SockaddrInet4)
-		for i := 0; i < IPv4len; i++ {
-			sa.Addr[i] = ip[i]
-		}
-		sa.Port = port
-		return sa, nil
-	case syscall.AF_INET6:
-		if len(ip) == 0 {
-			ip = IPv6zero
-		}
-		// IPv4 callers use 0.0.0.0 to mean "announce on any available address".
-		// In IPv6 mode, Linux treats that as meaning "announce on 0.0.0.0",
-		// which it refuses to do.  Rewrite to the IPv6 unspecified address.
-		if ip.Equal(IPv4zero) {
-			ip = IPv6zero
-		}
-		if ip = ip.To16(); ip == nil {
-			return nil, InvalidAddrError("non-IPv6 address")
-		}
-		sa := new(syscall.SockaddrInet6)
-		for i := 0; i < IPv6len; i++ {
-			sa.Addr[i] = ip[i]
-		}
-		sa.Port = port
-		sa.ZoneId = uint32(zoneToInt(zone))
-		return sa, nil
-	}
-	return nil, InvalidAddrError("unexpected socket family")
-}
diff --git a/src/pkg/net/lookup.go b/src/pkg/net/lookup.go
deleted file mode 100644
index 20f2057..0000000
--- a/src/pkg/net/lookup.go
+++ /dev/null
@@ -1,137 +0,0 @@
-// Copyright 2012 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package net
-
-import "time"
-
-// protocols contains minimal mappings between internet protocol
-// names and numbers for platforms that don't have a complete list of
-// protocol numbers.
-//
-// See http://www.iana.org/assignments/protocol-numbers
-var protocols = map[string]int{
-	"icmp": 1, "ICMP": 1,
-	"igmp": 2, "IGMP": 2,
-	"tcp": 6, "TCP": 6,
-	"udp": 17, "UDP": 17,
-	"ipv6-icmp": 58, "IPV6-ICMP": 58, "IPv6-ICMP": 58,
-}
-
-// LookupHost looks up the given host using the local resolver.
-// It returns an array of that host's addresses.
-func LookupHost(host string) (addrs []string, err error) {
-	return lookupHost(host)
-}
-
-// LookupIP looks up host using the local resolver.
-// It returns an array of that host's IPv4 and IPv6 addresses.
-func LookupIP(host string) (addrs []IP, err error) {
-	return lookupIPMerge(host)
-}
-
-var lookupGroup singleflight
-
-// lookupIPMerge wraps lookupIP, but makes sure that for any given
-// host, only one lookup is in-flight at a time. The returned memory
-// is always owned by the caller.
-func lookupIPMerge(host string) (addrs []IP, err error) {
-	addrsi, err, shared := lookupGroup.Do(host, func() (interface{}, error) {
-		return lookupIP(host)
-	})
-	if err != nil {
-		return nil, err
-	}
-	addrs = addrsi.([]IP)
-	if shared {
-		clone := make([]IP, len(addrs))
-		copy(clone, addrs)
-		addrs = clone
-	}
-	return addrs, nil
-}
-
-func lookupIPDeadline(host string, deadline time.Time) (addrs []IP, err error) {
-	if deadline.IsZero() {
-		return lookupIPMerge(host)
-	}
-
-	// TODO(bradfitz): consider pushing the deadline down into the
-	// name resolution functions. But that involves fixing it for
-	// the native Go resolver, cgo, Windows, etc.
-	//
-	// In the meantime, just use a goroutine. Most users affected
-	// by http://golang.org/issue/2631 are due to TCP connections
-	// to unresponsive hosts, not DNS.
-	timeout := deadline.Sub(time.Now())
-	if timeout <= 0 {
-		err = errTimeout
-		return
-	}
-	t := time.NewTimer(timeout)
-	defer t.Stop()
-	type res struct {
-		addrs []IP
-		err   error
-	}
-	resc := make(chan res, 1)
-	go func() {
-		a, err := lookupIPMerge(host)
-		resc <- res{a, err}
-	}()
-	select {
-	case <-t.C:
-		err = errTimeout
-	case r := <-resc:
-		addrs, err = r.addrs, r.err
-	}
-	return
-}
-
-// LookupPort looks up the port for the given network and service.
-func LookupPort(network, service string) (port int, err error) {
-	return lookupPort(network, service)
-}
-
-// LookupCNAME returns the canonical DNS host for the given name.
-// Callers that do not care about the canonical name can call
-// LookupHost or LookupIP directly; both take care of resolving
-// the canonical name as part of the lookup.
-func LookupCNAME(name string) (cname string, err error) {
-	return lookupCNAME(name)
-}
-
-// LookupSRV tries to resolve an SRV query of the given service,
-// protocol, and domain name.  The proto is "tcp" or "udp".
-// The returned records are sorted by priority and randomized
-// by weight within a priority.
-//
-// LookupSRV constructs the DNS name to look up following RFC 2782.
-// That is, it looks up _service._proto.name.  To accommodate services
-// publishing SRV records under non-standard names, if both service
-// and proto are empty strings, LookupSRV looks up name directly.
-func LookupSRV(service, proto, name string) (cname string, addrs []*SRV, err error) {
-	return lookupSRV(service, proto, name)
-}
-
-// LookupMX returns the DNS MX records for the given domain name sorted by preference.
-func LookupMX(name string) (mx []*MX, err error) {
-	return lookupMX(name)
-}
-
-// LookupNS returns the DNS NS records for the given domain name.
-func LookupNS(name string) (ns []*NS, err error) {
-	return lookupNS(name)
-}
-
-// LookupTXT returns the DNS TXT records for the given domain name.
-func LookupTXT(name string) (txt []string, err error) {
-	return lookupTXT(name)
-}
-
-// LookupAddr performs a reverse lookup for the given address, returning a list
-// of names mapping to that address.
-func LookupAddr(addr string) (name []string, err error) {
-	return lookupAddr(addr)
-}
diff --git a/src/pkg/net/lookup_test.go b/src/pkg/net/lookup_test.go
deleted file mode 100644
index 3355e46..0000000
--- a/src/pkg/net/lookup_test.go
+++ /dev/null
@@ -1,137 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// TODO It would be nice to use a mock DNS server, to eliminate
-// external dependencies.
-
-package net
-
-import (
-	"flag"
-	"strings"
-	"testing"
-)
-
-var testExternal = flag.Bool("external", true, "allow use of external networks during long test")
-
-func TestGoogleSRV(t *testing.T) {
-	if testing.Short() || !*testExternal {
-		t.Skip("skipping test to avoid external network")
-	}
-	_, addrs, err := LookupSRV("xmpp-server", "tcp", "google.com")
-	if err != nil {
-		t.Errorf("failed: %s", err)
-	}
-	if len(addrs) == 0 {
-		t.Errorf("no results")
-	}
-
-	// Non-standard back door.
-	_, addrs, err = LookupSRV("", "", "_xmpp-server._tcp.google.com")
-	if err != nil {
-		t.Errorf("back door failed: %s", err)
-	}
-	if len(addrs) == 0 {
-		t.Errorf("back door no results")
-	}
-}
-
-func TestGmailMX(t *testing.T) {
-	if testing.Short() || !*testExternal {
-		t.Skip("skipping test to avoid external network")
-	}
-	mx, err := LookupMX("gmail.com")
-	if err != nil {
-		t.Errorf("failed: %s", err)
-	}
-	if len(mx) == 0 {
-		t.Errorf("no results")
-	}
-}
-
-func TestGmailNS(t *testing.T) {
-	if testing.Short() || !*testExternal {
-		t.Skip("skipping test to avoid external network")
-	}
-	ns, err := LookupNS("gmail.com")
-	if err != nil {
-		t.Errorf("failed: %s", err)
-	}
-	if len(ns) == 0 {
-		t.Errorf("no results")
-	}
-}
-
-func TestGmailTXT(t *testing.T) {
-	if testing.Short() || !*testExternal {
-		t.Skip("skipping test to avoid external network")
-	}
-	txt, err := LookupTXT("gmail.com")
-	if err != nil {
-		t.Errorf("failed: %s", err)
-	}
-	if len(txt) == 0 || len(txt[0]) == 0 {
-		t.Errorf("no results")
-	}
-}
-
-func TestGoogleDNSAddr(t *testing.T) {
-	if testing.Short() || !*testExternal {
-		t.Skip("skipping test to avoid external network")
-	}
-	names, err := LookupAddr("8.8.8.8")
-	if err != nil {
-		t.Errorf("failed: %s", err)
-	}
-	if len(names) == 0 {
-		t.Errorf("no results")
-	}
-}
-
-func TestLookupIANACNAME(t *testing.T) {
-	if testing.Short() || !*testExternal {
-		t.Skip("skipping test to avoid external network")
-	}
-	cname, err := LookupCNAME("www.iana.org")
-	if !strings.HasSuffix(cname, ".icann.org.") || err != nil {
-		t.Errorf(`LookupCNAME("www.iana.org.") = %q, %v, want "*.icann.org.", nil`, cname, err)
-	}
-}
-
-var revAddrTests = []struct {
-	Addr      string
-	Reverse   string
-	ErrPrefix string
-}{
-	{"1.2.3.4", "4.3.2.1.in-addr.arpa.", ""},
-	{"245.110.36.114", "114.36.110.245.in-addr.arpa.", ""},
-	{"::ffff:12.34.56.78", "78.56.34.12.in-addr.arpa.", ""},
-	{"::1", "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa.", ""},
-	{"1::", "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.1.0.0.0.ip6.arpa.", ""},
-	{"1234:567::89a:bcde", "e.d.c.b.a.9.8.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.7.6.5.0.4.3.2.1.ip6.arpa.", ""},
-	{"1234:567:fefe:bcbc:adad:9e4a:89a:bcde", "e.d.c.b.a.9.8.0.a.4.e.9.d.a.d.a.c.b.c.b.e.f.e.f.7.6.5.0.4.3.2.1.ip6.arpa.", ""},
-	{"1.2.3", "", "unrecognized address"},
-	{"1.2.3.4.5", "", "unrecognized address"},
-	{"1234:567:bcbca::89a:bcde", "", "unrecognized address"},
-	{"1234:567::bcbc:adad::89a:bcde", "", "unrecognized address"},
-}
-
-func TestReverseAddress(t *testing.T) {
-	for i, tt := range revAddrTests {
-		a, err := reverseaddr(tt.Addr)
-		if len(tt.ErrPrefix) > 0 && err == nil {
-			t.Errorf("#%d: expected %q, got <nil> (error)", i, tt.ErrPrefix)
-			continue
-		}
-		if len(tt.ErrPrefix) == 0 && err != nil {
-			t.Errorf("#%d: expected <nil>, got %q (error)", i, err)
-		}
-		if err != nil && err.(*DNSError).Err != tt.ErrPrefix {
-			t.Errorf("#%d: expected %q, got %q (mismatched error)", i, tt.ErrPrefix, err.(*DNSError).Err)
-		}
-		if a != tt.Reverse {
-			t.Errorf("#%d: expected %q, got %q (reverse address)", i, tt.Reverse, a)
-		}
-	}
-}
diff --git a/src/pkg/net/lookup_unix.go b/src/pkg/net/lookup_unix.go
deleted file mode 100644
index b1d2f8f..0000000
--- a/src/pkg/net/lookup_unix.go
+++ /dev/null
@@ -1,168 +0,0 @@
-// Copyright 2011 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris
-
-package net
-
-import (
-	"errors"
-	"sync"
-)
-
-var onceReadProtocols sync.Once
-
-// readProtocols loads contents of /etc/protocols into protocols map
-// for quick access.
-func readProtocols() {
-	if file, err := open("/etc/protocols"); err == nil {
-		for line, ok := file.readLine(); ok; line, ok = file.readLine() {
-			// tcp    6   TCP    # transmission control protocol
-			if i := byteIndex(line, '#'); i >= 0 {
-				line = line[0:i]
-			}
-			f := getFields(line)
-			if len(f) < 2 {
-				continue
-			}
-			if proto, _, ok := dtoi(f[1], 0); ok {
-				if _, ok := protocols[f[0]]; !ok {
-					protocols[f[0]] = proto
-				}
-				for _, alias := range f[2:] {
-					if _, ok := protocols[alias]; !ok {
-						protocols[alias] = proto
-					}
-				}
-			}
-		}
-		file.close()
-	}
-}
-
-// lookupProtocol looks up IP protocol name in /etc/protocols and
-// returns correspondent protocol number.
-func lookupProtocol(name string) (proto int, err error) {
-	onceReadProtocols.Do(readProtocols)
-	proto, found := protocols[name]
-	if !found {
-		return 0, errors.New("unknown IP protocol specified: " + name)
-	}
-	return
-}
-
-func lookupHost(host string) (addrs []string, err error) {
-	addrs, err, ok := cgoLookupHost(host)
-	if !ok {
-		addrs, err = goLookupHost(host)
-	}
-	return
-}
-
-func lookupIP(host string) (addrs []IP, err error) {
-	addrs, err, ok := cgoLookupIP(host)
-	if !ok {
-		addrs, err = goLookupIP(host)
-	}
-	return
-}
-
-func lookupPort(network, service string) (port int, err error) {
-	port, err, ok := cgoLookupPort(network, service)
-	if !ok {
-		port, err = goLookupPort(network, service)
-	}
-	return
-}
-
-func lookupCNAME(name string) (cname string, err error) {
-	cname, err, ok := cgoLookupCNAME(name)
-	if !ok {
-		cname, err = goLookupCNAME(name)
-	}
-	return
-}
-
-func lookupSRV(service, proto, name string) (cname string, addrs []*SRV, err error) {
-	var target string
-	if service == "" && proto == "" {
-		target = name
-	} else {
-		target = "_" + service + "._" + proto + "." + name
-	}
-	var records []dnsRR
-	cname, records, err = lookup(target, dnsTypeSRV)
-	if err != nil {
-		return
-	}
-	addrs = make([]*SRV, len(records))
-	for i, rr := range records {
-		r := rr.(*dnsRR_SRV)
-		addrs[i] = &SRV{r.Target, r.Port, r.Priority, r.Weight}
-	}
-	byPriorityWeight(addrs).sort()
-	return
-}
-
-func lookupMX(name string) (mx []*MX, err error) {
-	_, records, err := lookup(name, dnsTypeMX)
-	if err != nil {
-		return
-	}
-	mx = make([]*MX, len(records))
-	for i, rr := range records {
-		r := rr.(*dnsRR_MX)
-		mx[i] = &MX{r.Mx, r.Pref}
-	}
-	byPref(mx).sort()
-	return
-}
-
-func lookupNS(name string) (ns []*NS, err error) {
-	_, records, err := lookup(name, dnsTypeNS)
-	if err != nil {
-		return
-	}
-	ns = make([]*NS, len(records))
-	for i, r := range records {
-		r := r.(*dnsRR_NS)
-		ns[i] = &NS{r.Ns}
-	}
-	return
-}
-
-func lookupTXT(name string) (txt []string, err error) {
-	_, records, err := lookup(name, dnsTypeTXT)
-	if err != nil {
-		return
-	}
-	txt = make([]string, len(records))
-	for i, r := range records {
-		txt[i] = r.(*dnsRR_TXT).Txt
-	}
-	return
-}
-
-func lookupAddr(addr string) (name []string, err error) {
-	name = lookupStaticAddr(addr)
-	if len(name) > 0 {
-		return
-	}
-	var arpa string
-	arpa, err = reverseaddr(addr)
-	if err != nil {
-		return
-	}
-	var records []dnsRR
-	_, records, err = lookup(arpa, dnsTypePTR)
-	if err != nil {
-		return
-	}
-	name = make([]string, len(records))
-	for i := range records {
-		r := records[i].(*dnsRR_PTR)
-		name[i] = r.Ptr
-	}
-	return
-}
diff --git a/src/pkg/net/lookup_windows.go b/src/pkg/net/lookup_windows.go
deleted file mode 100644
index 1303642..0000000
--- a/src/pkg/net/lookup_windows.go
+++ /dev/null
@@ -1,322 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package net
-
-import (
-	"os"
-	"runtime"
-	"syscall"
-	"unsafe"
-)
-
-var (
-	lookupPort = oldLookupPort
-	lookupIP   = oldLookupIP
-)
-
-func getprotobyname(name string) (proto int, err error) {
-	p, err := syscall.GetProtoByName(name)
-	if err != nil {
-		return 0, os.NewSyscallError("GetProtoByName", err)
-	}
-	return int(p.Proto), nil
-}
-
-// lookupProtocol looks up IP protocol name and returns correspondent protocol number.
-func lookupProtocol(name string) (proto int, err error) {
-	// GetProtoByName return value is stored in thread local storage.
-	// Start new os thread before the call to prevent races.
-	type result struct {
-		proto int
-		err   error
-	}
-	ch := make(chan result)
-	go func() {
-		acquireThread()
-		defer releaseThread()
-		runtime.LockOSThread()
-		defer runtime.UnlockOSThread()
-		proto, err := getprotobyname(name)
-		ch <- result{proto: proto, err: err}
-	}()
-	r := <-ch
-	if r.err != nil {
-		if proto, ok := protocols[name]; ok {
-			return proto, nil
-		}
-	}
-	return r.proto, r.err
-}
-
-func lookupHost(name string) (addrs []string, err error) {
-	ips, err := LookupIP(name)
-	if err != nil {
-		return
-	}
-	addrs = make([]string, 0, len(ips))
-	for _, ip := range ips {
-		addrs = append(addrs, ip.String())
-	}
-	return
-}
-
-func gethostbyname(name string) (addrs []IP, err error) {
-	// caller already acquired thread
-	h, err := syscall.GetHostByName(name)
-	if err != nil {
-		return nil, os.NewSyscallError("GetHostByName", err)
-	}
-	switch h.AddrType {
-	case syscall.AF_INET:
-		i := 0
-		addrs = make([]IP, 100) // plenty of room to grow
-		for p := (*[100](*[4]byte))(unsafe.Pointer(h.AddrList)); i < cap(addrs) && p[i] != nil; i++ {
-			addrs[i] = IPv4(p[i][0], p[i][1], p[i][2], p[i][3])
-		}
-		addrs = addrs[0:i]
-	default: // TODO(vcc): Implement non IPv4 address lookups.
-		return nil, os.NewSyscallError("LookupIP", syscall.EWINDOWS)
-	}
-	return addrs, nil
-}
-
-func oldLookupIP(name string) (addrs []IP, err error) {
-	// GetHostByName return value is stored in thread local storage.
-	// Start new os thread before the call to prevent races.
-	type result struct {
-		addrs []IP
-		err   error
-	}
-	ch := make(chan result)
-	go func() {
-		acquireThread()
-		defer releaseThread()
-		runtime.LockOSThread()
-		defer runtime.UnlockOSThread()
-		addrs, err := gethostbyname(name)
-		ch <- result{addrs: addrs, err: err}
-	}()
-	r := <-ch
-	return r.addrs, r.err
-}
-
-func newLookupIP(name string) (addrs []IP, err error) {
-	acquireThread()
-	defer releaseThread()
-	hints := syscall.AddrinfoW{
-		Family:   syscall.AF_UNSPEC,
-		Socktype: syscall.SOCK_STREAM,
-		Protocol: syscall.IPPROTO_IP,
-	}
-	var result *syscall.AddrinfoW
-	e := syscall.GetAddrInfoW(syscall.StringToUTF16Ptr(name), nil, &hints, &result)
-	if e != nil {
-		return nil, os.NewSyscallError("GetAddrInfoW", e)
-	}
-	defer syscall.FreeAddrInfoW(result)
-	addrs = make([]IP, 0, 5)
-	for ; result != nil; result = result.Next {
-		addr := unsafe.Pointer(result.Addr)
-		switch result.Family {
-		case syscall.AF_INET:
-			a := (*syscall.RawSockaddrInet4)(addr).Addr
-			addrs = append(addrs, IPv4(a[0], a[1], a[2], a[3]))
-		case syscall.AF_INET6:
-			a := (*syscall.RawSockaddrInet6)(addr).Addr
-			addrs = append(addrs, IP{a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]})
-		default:
-			return nil, os.NewSyscallError("LookupIP", syscall.EWINDOWS)
-		}
-	}
-	return addrs, nil
-}
-
-func getservbyname(network, service string) (port int, err error) {
-	acquireThread()
-	defer releaseThread()
-	switch network {
-	case "tcp4", "tcp6":
-		network = "tcp"
-	case "udp4", "udp6":
-		network = "udp"
-	}
-	s, err := syscall.GetServByName(service, network)
-	if err != nil {
-		return 0, os.NewSyscallError("GetServByName", err)
-	}
-	return int(syscall.Ntohs(s.Port)), nil
-}
-
-func oldLookupPort(network, service string) (port int, err error) {
-	// GetServByName return value is stored in thread local storage.
-	// Start new os thread before the call to prevent races.
-	type result struct {
-		port int
-		err  error
-	}
-	ch := make(chan result)
-	go func() {
-		acquireThread()
-		defer releaseThread()
-		runtime.LockOSThread()
-		defer runtime.UnlockOSThread()
-		port, err := getservbyname(network, service)
-		ch <- result{port: port, err: err}
-	}()
-	r := <-ch
-	return r.port, r.err
-}
-
-func newLookupPort(network, service string) (port int, err error) {
-	acquireThread()
-	defer releaseThread()
-	var stype int32
-	switch network {
-	case "tcp4", "tcp6":
-		stype = syscall.SOCK_STREAM
-	case "udp4", "udp6":
-		stype = syscall.SOCK_DGRAM
-	}
-	hints := syscall.AddrinfoW{
-		Family:   syscall.AF_UNSPEC,
-		Socktype: stype,
-		Protocol: syscall.IPPROTO_IP,
-	}
-	var result *syscall.AddrinfoW
-	e := syscall.GetAddrInfoW(nil, syscall.StringToUTF16Ptr(service), &hints, &result)
-	if e != nil {
-		return 0, os.NewSyscallError("GetAddrInfoW", e)
-	}
-	defer syscall.FreeAddrInfoW(result)
-	if result == nil {
-		return 0, os.NewSyscallError("LookupPort", syscall.EINVAL)
-	}
-	addr := unsafe.Pointer(result.Addr)
-	switch result.Family {
-	case syscall.AF_INET:
-		a := (*syscall.RawSockaddrInet4)(addr)
-		return int(syscall.Ntohs(a.Port)), nil
-	case syscall.AF_INET6:
-		a := (*syscall.RawSockaddrInet6)(addr)
-		return int(syscall.Ntohs(a.Port)), nil
-	}
-	return 0, os.NewSyscallError("LookupPort", syscall.EINVAL)
-}
-
-func lookupCNAME(name string) (cname string, err error) {
-	acquireThread()
-	defer releaseThread()
-	var r *syscall.DNSRecord
-	e := syscall.DnsQuery(name, syscall.DNS_TYPE_CNAME, 0, nil, &r, nil)
-	if e != nil {
-		return "", os.NewSyscallError("LookupCNAME", e)
-	}
-	defer syscall.DnsRecordListFree(r, 1)
-	if r != nil && r.Type == syscall.DNS_TYPE_CNAME {
-		v := (*syscall.DNSPTRData)(unsafe.Pointer(&r.Data[0]))
-		cname = syscall.UTF16ToString((*[256]uint16)(unsafe.Pointer(v.Host))[:]) + "."
-	}
-	return
-}
-
-func lookupSRV(service, proto, name string) (cname string, addrs []*SRV, err error) {
-	acquireThread()
-	defer releaseThread()
-	var target string
-	if service == "" && proto == "" {
-		target = name
-	} else {
-		target = "_" + service + "._" + proto + "." + name
-	}
-	var r *syscall.DNSRecord
-	e := syscall.DnsQuery(target, syscall.DNS_TYPE_SRV, 0, nil, &r, nil)
-	if e != nil {
-		return "", nil, os.NewSyscallError("LookupSRV", e)
-	}
-	defer syscall.DnsRecordListFree(r, 1)
-	addrs = make([]*SRV, 0, 10)
-	for p := r; p != nil && p.Type == syscall.DNS_TYPE_SRV; p = p.Next {
-		v := (*syscall.DNSSRVData)(unsafe.Pointer(&p.Data[0]))
-		addrs = append(addrs, &SRV{syscall.UTF16ToString((*[256]uint16)(unsafe.Pointer(v.Target))[:]), v.Port, v.Priority, v.Weight})
-	}
-	byPriorityWeight(addrs).sort()
-	return name, addrs, nil
-}
-
-func lookupMX(name string) (mx []*MX, err error) {
-	acquireThread()
-	defer releaseThread()
-	var r *syscall.DNSRecord
-	e := syscall.DnsQuery(name, syscall.DNS_TYPE_MX, 0, nil, &r, nil)
-	if e != nil {
-		return nil, os.NewSyscallError("LookupMX", e)
-	}
-	defer syscall.DnsRecordListFree(r, 1)
-	mx = make([]*MX, 0, 10)
-	for p := r; p != nil && p.Type == syscall.DNS_TYPE_MX; p = p.Next {
-		v := (*syscall.DNSMXData)(unsafe.Pointer(&p.Data[0]))
-		mx = append(mx, &MX{syscall.UTF16ToString((*[256]uint16)(unsafe.Pointer(v.NameExchange))[:]) + ".", v.Preference})
-	}
-	byPref(mx).sort()
-	return mx, nil
-}
-
-func lookupNS(name string) (ns []*NS, err error) {
-	acquireThread()
-	defer releaseThread()
-	var r *syscall.DNSRecord
-	e := syscall.DnsQuery(name, syscall.DNS_TYPE_NS, 0, nil, &r, nil)
-	if e != nil {
-		return nil, os.NewSyscallError("LookupNS", e)
-	}
-	defer syscall.DnsRecordListFree(r, 1)
-	ns = make([]*NS, 0, 10)
-	for p := r; p != nil && p.Type == syscall.DNS_TYPE_NS; p = p.Next {
-		v := (*syscall.DNSPTRData)(unsafe.Pointer(&p.Data[0]))
-		ns = append(ns, &NS{syscall.UTF16ToString((*[256]uint16)(unsafe.Pointer(v.Host))[:]) + "."})
-	}
-	return ns, nil
-}
-
-func lookupTXT(name string) (txt []string, err error) {
-	acquireThread()
-	defer releaseThread()
-	var r *syscall.DNSRecord
-	e := syscall.DnsQuery(name, syscall.DNS_TYPE_TEXT, 0, nil, &r, nil)
-	if e != nil {
-		return nil, os.NewSyscallError("LookupTXT", e)
-	}
-	defer syscall.DnsRecordListFree(r, 1)
-	txt = make([]string, 0, 10)
-	if r != nil && r.Type == syscall.DNS_TYPE_TEXT {
-		d := (*syscall.DNSTXTData)(unsafe.Pointer(&r.Data[0]))
-		for _, v := range (*[1 << 10]*uint16)(unsafe.Pointer(&(d.StringArray[0])))[:d.StringCount] {
-			s := syscall.UTF16ToString((*[1 << 20]uint16)(unsafe.Pointer(v))[:])
-			txt = append(txt, s)
-		}
-	}
-	return
-}
-
-func lookupAddr(addr string) (name []string, err error) {
-	acquireThread()
-	defer releaseThread()
-	arpa, err := reverseaddr(addr)
-	if err != nil {
-		return nil, err
-	}
-	var r *syscall.DNSRecord
-	e := syscall.DnsQuery(arpa, syscall.DNS_TYPE_PTR, 0, nil, &r, nil)
-	if e != nil {
-		return nil, os.NewSyscallError("LookupAddr", e)
-	}
-	defer syscall.DnsRecordListFree(r, 1)
-	name = make([]string, 0, 10)
-	for p := r; p != nil && p.Type == syscall.DNS_TYPE_PTR; p = p.Next {
-		v := (*syscall.DNSPTRData)(unsafe.Pointer(&p.Data[0]))
-		name = append(name, syscall.UTF16ToString((*[256]uint16)(unsafe.Pointer(v.Host))[:]))
-	}
-	return name, nil
-}
diff --git a/src/pkg/net/mail/message.go b/src/pkg/net/mail/message.go
deleted file mode 100644
index ba0778c..0000000
--- a/src/pkg/net/mail/message.go
+++ /dev/null
@@ -1,545 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-/*
-Package mail implements parsing of mail messages.
-
-For the most part, this package follows the syntax as specified by RFC 5322.
-Notable divergences:
-	* Obsolete address formats are not parsed, including addresses with
-	  embedded route information.
-	* Group addresses are not parsed.
-	* The full range of spacing (the CFWS syntax element) is not supported,
-	  such as breaking addresses across lines.
-*/
-package mail
-
-import (
-	"bufio"
-	"bytes"
-	"encoding/base64"
-	"errors"
-	"fmt"
-	"io"
-	"io/ioutil"
-	"log"
-	"net/textproto"
-	"strconv"
-	"strings"
-	"time"
-)
-
-var debug = debugT(false)
-
-type debugT bool
-
-func (d debugT) Printf(format string, args ...interface{}) {
-	if d {
-		log.Printf(format, args...)
-	}
-}
-
-// A Message represents a parsed mail message.
-type Message struct {
-	Header Header
-	Body   io.Reader
-}
-
-// ReadMessage reads a message from r.
-// The headers are parsed, and the body of the message will be available
-// for reading from r.
-func ReadMessage(r io.Reader) (msg *Message, err error) {
-	tp := textproto.NewReader(bufio.NewReader(r))
-
-	hdr, err := tp.ReadMIMEHeader()
-	if err != nil {
-		return nil, err
-	}
-
-	return &Message{
-		Header: Header(hdr),
-		Body:   tp.R,
-	}, nil
-}
-
-// Layouts suitable for passing to time.Parse.
-// These are tried in order.
-var dateLayouts []string
-
-func init() {
-	// Generate layouts based on RFC 5322, section 3.3.
-
-	dows := [...]string{"", "Mon, "}   // day-of-week
-	days := [...]string{"2", "02"}     // day = 1*2DIGIT
-	years := [...]string{"2006", "06"} // year = 4*DIGIT / 2*DIGIT
-	seconds := [...]string{":05", ""}  // second
-	// "-0700 (MST)" is not in RFC 5322, but is common.
-	zones := [...]string{"-0700", "MST", "-0700 (MST)"} // zone = (("+" / "-") 4DIGIT) / "GMT" / ...
-
-	for _, dow := range dows {
-		for _, day := range days {
-			for _, year := range years {
-				for _, second := range seconds {
-					for _, zone := range zones {
-						s := dow + day + " Jan " + year + " 15:04" + second + " " + zone
-						dateLayouts = append(dateLayouts, s)
-					}
-				}
-			}
-		}
-	}
-}
-
-func parseDate(date string) (time.Time, error) {
-	for _, layout := range dateLayouts {
-		t, err := time.Parse(layout, date)
-		if err == nil {
-			return t, nil
-		}
-	}
-	return time.Time{}, errors.New("mail: header could not be parsed")
-}
-
-// A Header represents the key-value pairs in a mail message header.
-type Header map[string][]string
-
-// Get gets the first value associated with the given key.
-// If there are no values associated with the key, Get returns "".
-func (h Header) Get(key string) string {
-	return textproto.MIMEHeader(h).Get(key)
-}
-
-var ErrHeaderNotPresent = errors.New("mail: header not in message")
-
-// Date parses the Date header field.
-func (h Header) Date() (time.Time, error) {
-	hdr := h.Get("Date")
-	if hdr == "" {
-		return time.Time{}, ErrHeaderNotPresent
-	}
-	return parseDate(hdr)
-}
-
-// AddressList parses the named header field as a list of addresses.
-func (h Header) AddressList(key string) ([]*Address, error) {
-	hdr := h.Get(key)
-	if hdr == "" {
-		return nil, ErrHeaderNotPresent
-	}
-	return ParseAddressList(hdr)
-}
-
-// Address represents a single mail address.
-// An address such as "Barry Gibbs <bg at example.com>" is represented
-// as Address{Name: "Barry Gibbs", Address: "bg at example.com"}.
-type Address struct {
-	Name    string // Proper name; may be empty.
-	Address string // user at domain
-}
-
-// Parses a single RFC 5322 address, e.g. "Barry Gibbs <bg at example.com>"
-func ParseAddress(address string) (*Address, error) {
-	return newAddrParser(address).parseAddress()
-}
-
-// ParseAddressList parses the given string as a list of addresses.
-func ParseAddressList(list string) ([]*Address, error) {
-	return newAddrParser(list).parseAddressList()
-}
-
-// String formats the address as a valid RFC 5322 address.
-// If the address's name contains non-ASCII characters
-// the name will be rendered according to RFC 2047.
-func (a *Address) String() string {
-	s := "<" + a.Address + ">"
-	if a.Name == "" {
-		return s
-	}
-	// If every character is printable ASCII, quoting is simple.
-	allPrintable := true
-	for i := 0; i < len(a.Name); i++ {
-		// isWSP here should actually be isFWS,
-		// but we don't support folding yet.
-		if !isVchar(a.Name[i]) && !isWSP(a.Name[i]) {
-			allPrintable = false
-			break
-		}
-	}
-	if allPrintable {
-		b := bytes.NewBufferString(`"`)
-		for i := 0; i < len(a.Name); i++ {
-			if !isQtext(a.Name[i]) && !isWSP(a.Name[i]) {
-				b.WriteByte('\\')
-			}
-			b.WriteByte(a.Name[i])
-		}
-		b.WriteString(`" `)
-		b.WriteString(s)
-		return b.String()
-	}
-
-	// UTF-8 "Q" encoding
-	b := bytes.NewBufferString("=?utf-8?q?")
-	for i := 0; i < len(a.Name); i++ {
-		switch c := a.Name[i]; {
-		case c == ' ':
-			b.WriteByte('_')
-		case isVchar(c) && c != '=' && c != '?' && c != '_':
-			b.WriteByte(c)
-		default:
-			fmt.Fprintf(b, "=%02X", c)
-		}
-	}
-	b.WriteString("?= ")
-	b.WriteString(s)
-	return b.String()
-}
-
-type addrParser []byte
-
-func newAddrParser(s string) *addrParser {
-	p := addrParser(s)
-	return &p
-}
-
-func (p *addrParser) parseAddressList() ([]*Address, error) {
-	var list []*Address
-	for {
-		p.skipSpace()
-		addr, err := p.parseAddress()
-		if err != nil {
-			return nil, err
-		}
-		list = append(list, addr)
-
-		p.skipSpace()
-		if p.empty() {
-			break
-		}
-		if !p.consume(',') {
-			return nil, errors.New("mail: expected comma")
-		}
-	}
-	return list, nil
-}
-
-// parseAddress parses a single RFC 5322 address at the start of p.
-func (p *addrParser) parseAddress() (addr *Address, err error) {
-	debug.Printf("parseAddress: %q", *p)
-	p.skipSpace()
-	if p.empty() {
-		return nil, errors.New("mail: no address")
-	}
-
-	// address = name-addr / addr-spec
-	// TODO(dsymonds): Support parsing group address.
-
-	// addr-spec has a more restricted grammar than name-addr,
-	// so try parsing it first, and fallback to name-addr.
-	// TODO(dsymonds): Is this really correct?
-	spec, err := p.consumeAddrSpec()
-	if err == nil {
-		return &Address{
-			Address: spec,
-		}, err
-	}
-	debug.Printf("parseAddress: not an addr-spec: %v", err)
-	debug.Printf("parseAddress: state is now %q", *p)
-
-	// display-name
-	var displayName string
-	if p.peek() != '<' {
-		displayName, err = p.consumePhrase()
-		if err != nil {
-			return nil, err
-		}
-	}
-	debug.Printf("parseAddress: displayName=%q", displayName)
-
-	// angle-addr = "<" addr-spec ">"
-	p.skipSpace()
-	if !p.consume('<') {
-		return nil, errors.New("mail: no angle-addr")
-	}
-	spec, err = p.consumeAddrSpec()
-	if err != nil {
-		return nil, err
-	}
-	if !p.consume('>') {
-		return nil, errors.New("mail: unclosed angle-addr")
-	}
-	debug.Printf("parseAddress: spec=%q", spec)
-
-	return &Address{
-		Name:    displayName,
-		Address: spec,
-	}, nil
-}
-
-// consumeAddrSpec parses a single RFC 5322 addr-spec at the start of p.
-func (p *addrParser) consumeAddrSpec() (spec string, err error) {
-	debug.Printf("consumeAddrSpec: %q", *p)
-
-	orig := *p
-	defer func() {
-		if err != nil {
-			*p = orig
-		}
-	}()
-
-	// local-part = dot-atom / quoted-string
-	var localPart string
-	p.skipSpace()
-	if p.empty() {
-		return "", errors.New("mail: no addr-spec")
-	}
-	if p.peek() == '"' {
-		// quoted-string
-		debug.Printf("consumeAddrSpec: parsing quoted-string")
-		localPart, err = p.consumeQuotedString()
-	} else {
-		// dot-atom
-		debug.Printf("consumeAddrSpec: parsing dot-atom")
-		localPart, err = p.consumeAtom(true)
-	}
-	if err != nil {
-		debug.Printf("consumeAddrSpec: failed: %v", err)
-		return "", err
-	}
-
-	if !p.consume('@') {
-		return "", errors.New("mail: missing @ in addr-spec")
-	}
-
-	// domain = dot-atom / domain-literal
-	var domain string
-	p.skipSpace()
-	if p.empty() {
-		return "", errors.New("mail: no domain in addr-spec")
-	}
-	// TODO(dsymonds): Handle domain-literal
-	domain, err = p.consumeAtom(true)
-	if err != nil {
-		return "", err
-	}
-
-	return localPart + "@" + domain, nil
-}
-
-// consumePhrase parses the RFC 5322 phrase at the start of p.
-func (p *addrParser) consumePhrase() (phrase string, err error) {
-	debug.Printf("consumePhrase: [%s]", *p)
-	// phrase = 1*word
-	var words []string
-	for {
-		// word = atom / quoted-string
-		var word string
-		p.skipSpace()
-		if p.empty() {
-			return "", errors.New("mail: missing phrase")
-		}
-		if p.peek() == '"' {
-			// quoted-string
-			word, err = p.consumeQuotedString()
-		} else {
-			// atom
-			// We actually parse dot-atom here to be more permissive
-			// than what RFC 5322 specifies.
-			word, err = p.consumeAtom(true)
-		}
-
-		// RFC 2047 encoded-word starts with =?, ends with ?=, and has two other ?s.
-		if err == nil && strings.HasPrefix(word, "=?") && strings.HasSuffix(word, "?=") && strings.Count(word, "?") == 4 {
-			word, err = decodeRFC2047Word(word)
-		}
-
-		if err != nil {
-			break
-		}
-		debug.Printf("consumePhrase: consumed %q", word)
-		words = append(words, word)
-	}
-	// Ignore any error if we got at least one word.
-	if err != nil && len(words) == 0 {
-		debug.Printf("consumePhrase: hit err: %v", err)
-		return "", fmt.Errorf("mail: missing word in phrase: %v", err)
-	}
-	phrase = strings.Join(words, " ")
-	return phrase, nil
-}
-
-// consumeQuotedString parses the quoted string at the start of p.
-func (p *addrParser) consumeQuotedString() (qs string, err error) {
-	// Assume first byte is '"'.
-	i := 1
-	qsb := make([]byte, 0, 10)
-Loop:
-	for {
-		if i >= p.len() {
-			return "", errors.New("mail: unclosed quoted-string")
-		}
-		switch c := (*p)[i]; {
-		case c == '"':
-			break Loop
-		case c == '\\':
-			if i+1 == p.len() {
-				return "", errors.New("mail: unclosed quoted-string")
-			}
-			qsb = append(qsb, (*p)[i+1])
-			i += 2
-		case isQtext(c), c == ' ' || c == '\t':
-			// qtext (printable US-ASCII excluding " and \), or
-			// FWS (almost; we're ignoring CRLF)
-			qsb = append(qsb, c)
-			i++
-		default:
-			return "", fmt.Errorf("mail: bad character in quoted-string: %q", c)
-		}
-	}
-	*p = (*p)[i+1:]
-	return string(qsb), nil
-}
-
-// consumeAtom parses an RFC 5322 atom at the start of p.
-// If dot is true, consumeAtom parses an RFC 5322 dot-atom instead.
-func (p *addrParser) consumeAtom(dot bool) (atom string, err error) {
-	if !isAtext(p.peek(), false) {
-		return "", errors.New("mail: invalid string")
-	}
-	i := 1
-	for ; i < p.len() && isAtext((*p)[i], dot); i++ {
-	}
-	atom, *p = string((*p)[:i]), (*p)[i:]
-	return atom, nil
-}
-
-func (p *addrParser) consume(c byte) bool {
-	if p.empty() || p.peek() != c {
-		return false
-	}
-	*p = (*p)[1:]
-	return true
-}
-
-// skipSpace skips the leading space and tab characters.
-func (p *addrParser) skipSpace() {
-	*p = bytes.TrimLeft(*p, " \t")
-}
-
-func (p *addrParser) peek() byte {
-	return (*p)[0]
-}
-
-func (p *addrParser) empty() bool {
-	return p.len() == 0
-}
-
-func (p *addrParser) len() int {
-	return len(*p)
-}
-
-func decodeRFC2047Word(s string) (string, error) {
-	fields := strings.Split(s, "?")
-	if len(fields) != 5 || fields[0] != "=" || fields[4] != "=" {
-		return "", errors.New("address not RFC 2047 encoded")
-	}
-	charset, enc := strings.ToLower(fields[1]), strings.ToLower(fields[2])
-	if charset != "iso-8859-1" && charset != "utf-8" {
-		return "", fmt.Errorf("charset not supported: %q", charset)
-	}
-
-	in := bytes.NewBufferString(fields[3])
-	var r io.Reader
-	switch enc {
-	case "b":
-		r = base64.NewDecoder(base64.StdEncoding, in)
-	case "q":
-		r = qDecoder{r: in}
-	default:
-		return "", fmt.Errorf("RFC 2047 encoding not supported: %q", enc)
-	}
-
-	dec, err := ioutil.ReadAll(r)
-	if err != nil {
-		return "", err
-	}
-
-	switch charset {
-	case "iso-8859-1":
-		b := new(bytes.Buffer)
-		for _, c := range dec {
-			b.WriteRune(rune(c))
-		}
-		return b.String(), nil
-	case "utf-8":
-		return string(dec), nil
-	}
-	panic("unreachable")
-}
-
-type qDecoder struct {
-	r       io.Reader
-	scratch [2]byte
-}
-
-func (qd qDecoder) Read(p []byte) (n int, err error) {
-	// This method writes at most one byte into p.
-	if len(p) == 0 {
-		return 0, nil
-	}
-	if _, err := qd.r.Read(qd.scratch[:1]); err != nil {
-		return 0, err
-	}
-	switch c := qd.scratch[0]; {
-	case c == '=':
-		if _, err := io.ReadFull(qd.r, qd.scratch[:2]); err != nil {
-			return 0, err
-		}
-		x, err := strconv.ParseInt(string(qd.scratch[:2]), 16, 64)
-		if err != nil {
-			return 0, fmt.Errorf("mail: invalid RFC 2047 encoding: %q", qd.scratch[:2])
-		}
-		p[0] = byte(x)
-	case c == '_':
-		p[0] = ' '
-	default:
-		p[0] = c
-	}
-	return 1, nil
-}
-
-var atextChars = []byte("ABCDEFGHIJKLMNOPQRSTUVWXYZ" +
-	"abcdefghijklmnopqrstuvwxyz" +
-	"0123456789" +
-	"!#$%&'*+-/=?^_`{|}~")
-
-// isAtext returns true if c is an RFC 5322 atext character.
-// If dot is true, period is included.
-func isAtext(c byte, dot bool) bool {
-	if dot && c == '.' {
-		return true
-	}
-	return bytes.IndexByte(atextChars, c) >= 0
-}
-
-// isQtext returns true if c is an RFC 5322 qtext character.
-func isQtext(c byte) bool {
-	// Printable US-ASCII, excluding backslash or quote.
-	if c == '\\' || c == '"' {
-		return false
-	}
-	return '!' <= c && c <= '~'
-}
-
-// isVchar returns true if c is an RFC 5322 VCHAR character.
-func isVchar(c byte) bool {
-	// Visible (printing) characters.
-	return '!' <= c && c <= '~'
-}
-
-// isWSP returns true if c is a WSP (white space).
-// WSP is a space or horizontal tab (RFC5234 Appendix B).
-func isWSP(c byte) bool {
-	return c == ' ' || c == '\t'
-}
diff --git a/src/pkg/net/mail/message_test.go b/src/pkg/net/mail/message_test.go
deleted file mode 100644
index eb9c8cb..0000000
--- a/src/pkg/net/mail/message_test.go
+++ /dev/null
@@ -1,304 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package mail
-
-import (
-	"bytes"
-	"io/ioutil"
-	"reflect"
-	"strings"
-	"testing"
-	"time"
-)
-
-var parseTests = []struct {
-	in     string
-	header Header
-	body   string
-}{
-	{
-		// RFC 5322, Appendix A.1.1
-		in: `From: John Doe <jdoe at machine.example>
-To: Mary Smith <mary at example.net>
-Subject: Saying Hello
-Date: Fri, 21 Nov 1997 09:55:06 -0600
-Message-ID: <1234 at local.machine.example>
-
-This is a message just to say hello.
-So, "Hello".
-`,
-		header: Header{
-			"From":       []string{"John Doe <jdoe at machine.example>"},
-			"To":         []string{"Mary Smith <mary at example.net>"},
-			"Subject":    []string{"Saying Hello"},
-			"Date":       []string{"Fri, 21 Nov 1997 09:55:06 -0600"},
-			"Message-Id": []string{"<1234 at local.machine.example>"},
-		},
-		body: "This is a message just to say hello.\nSo, \"Hello\".\n",
-	},
-}
-
-func TestParsing(t *testing.T) {
-	for i, test := range parseTests {
-		msg, err := ReadMessage(bytes.NewBuffer([]byte(test.in)))
-		if err != nil {
-			t.Errorf("test #%d: Failed parsing message: %v", i, err)
-			continue
-		}
-		if !headerEq(msg.Header, test.header) {
-			t.Errorf("test #%d: Incorrectly parsed message header.\nGot:\n%+v\nWant:\n%+v",
-				i, msg.Header, test.header)
-		}
-		body, err := ioutil.ReadAll(msg.Body)
-		if err != nil {
-			t.Errorf("test #%d: Failed reading body: %v", i, err)
-			continue
-		}
-		bodyStr := string(body)
-		if bodyStr != test.body {
-			t.Errorf("test #%d: Incorrectly parsed message body.\nGot:\n%+v\nWant:\n%+v",
-				i, bodyStr, test.body)
-		}
-	}
-}
-
-func headerEq(a, b Header) bool {
-	if len(a) != len(b) {
-		return false
-	}
-	for k, as := range a {
-		bs, ok := b[k]
-		if !ok {
-			return false
-		}
-		if !reflect.DeepEqual(as, bs) {
-			return false
-		}
-	}
-	return true
-}
-
-func TestDateParsing(t *testing.T) {
-	tests := []struct {
-		dateStr string
-		exp     time.Time
-	}{
-		// RFC 5322, Appendix A.1.1
-		{
-			"Fri, 21 Nov 1997 09:55:06 -0600",
-			time.Date(1997, 11, 21, 9, 55, 6, 0, time.FixedZone("", -6*60*60)),
-		},
-		// RFC5322, Appendix A.6.2
-		// Obsolete date.
-		{
-			"21 Nov 97 09:55:06 GMT",
-			time.Date(1997, 11, 21, 9, 55, 6, 0, time.FixedZone("GMT", 0)),
-		},
-		// Commonly found format not specified by RFC 5322.
-		{
-			"Fri, 21 Nov 1997 09:55:06 -0600 (MDT)",
-			time.Date(1997, 11, 21, 9, 55, 6, 0, time.FixedZone("", -6*60*60)),
-		},
-	}
-	for _, test := range tests {
-		hdr := Header{
-			"Date": []string{test.dateStr},
-		}
-		date, err := hdr.Date()
-		if err != nil {
-			t.Errorf("Failed parsing %q: %v", test.dateStr, err)
-			continue
-		}
-		if !date.Equal(test.exp) {
-			t.Errorf("Parse of %q: got %+v, want %+v", test.dateStr, date, test.exp)
-		}
-	}
-}
-
-func TestAddressParsingError(t *testing.T) {
-	const txt = "=?iso-8859-2?Q?Bogl=E1rka_Tak=E1cs?= <unknown at gmail.com>"
-	_, err := ParseAddress(txt)
-	if err == nil || !strings.Contains(err.Error(), "charset not supported") {
-		t.Errorf(`mail.ParseAddress(%q) err: %q, want ".*charset not supported.*"`, txt, err)
-	}
-}
-
-func TestAddressParsing(t *testing.T) {
-	tests := []struct {
-		addrsStr string
-		exp      []*Address
-	}{
-		// Bare address
-		{
-			`jdoe at machine.example`,
-			[]*Address{{
-				Address: "jdoe at machine.example",
-			}},
-		},
-		// RFC 5322, Appendix A.1.1
-		{
-			`John Doe <jdoe at machine.example>`,
-			[]*Address{{
-				Name:    "John Doe",
-				Address: "jdoe at machine.example",
-			}},
-		},
-		// RFC 5322, Appendix A.1.2
-		{
-			`"Joe Q. Public" <john.q.public at example.com>`,
-			[]*Address{{
-				Name:    "Joe Q. Public",
-				Address: "john.q.public at example.com",
-			}},
-		},
-		{
-			`Mary Smith <mary at x.test>, jdoe at example.org, Who? <one at y.test>`,
-			[]*Address{
-				{
-					Name:    "Mary Smith",
-					Address: "mary at x.test",
-				},
-				{
-					Address: "jdoe at example.org",
-				},
-				{
-					Name:    "Who?",
-					Address: "one at y.test",
-				},
-			},
-		},
-		{
-			`<boss at nil.test>, "Giant; \"Big\" Box" <sysservices at example.net>`,
-			[]*Address{
-				{
-					Address: "boss at nil.test",
-				},
-				{
-					Name:    `Giant; "Big" Box`,
-					Address: "sysservices at example.net",
-				},
-			},
-		},
-		// RFC 5322, Appendix A.1.3
-		// TODO(dsymonds): Group addresses.
-
-		// RFC 2047 "Q"-encoded ISO-8859-1 address.
-		{
-			`=?iso-8859-1?q?J=F6rg_Doe?= <joerg at example.com>`,
-			[]*Address{
-				{
-					Name:    `Jörg Doe`,
-					Address: "joerg at example.com",
-				},
-			},
-		},
-		// RFC 2047 "Q"-encoded UTF-8 address.
-		{
-			`=?utf-8?q?J=C3=B6rg_Doe?= <joerg at example.com>`,
-			[]*Address{
-				{
-					Name:    `Jörg Doe`,
-					Address: "joerg at example.com",
-				},
-			},
-		},
-		// RFC 2047, Section 8.
-		{
-			`=?ISO-8859-1?Q?Andr=E9?= Pirard <PIRARD at vm1.ulg.ac.be>`,
-			[]*Address{
-				{
-					Name:    `André Pirard`,
-					Address: "PIRARD at vm1.ulg.ac.be",
-				},
-			},
-		},
-		// Custom example of RFC 2047 "B"-encoded ISO-8859-1 address.
-		{
-			`=?ISO-8859-1?B?SvZyZw==?= <joerg at example.com>`,
-			[]*Address{
-				{
-					Name:    `Jörg`,
-					Address: "joerg at example.com",
-				},
-			},
-		},
-		// Custom example of RFC 2047 "B"-encoded UTF-8 address.
-		{
-			`=?UTF-8?B?SsO2cmc=?= <joerg at example.com>`,
-			[]*Address{
-				{
-					Name:    `Jörg`,
-					Address: "joerg at example.com",
-				},
-			},
-		},
-		// Custom example with "." in name. For issue 4938
-		{
-			`Asem H. <noreply at example.com>`,
-			[]*Address{
-				{
-					Name:    `Asem H.`,
-					Address: "noreply at example.com",
-				},
-			},
-		},
-	}
-	for _, test := range tests {
-		if len(test.exp) == 1 {
-			addr, err := ParseAddress(test.addrsStr)
-			if err != nil {
-				t.Errorf("Failed parsing (single) %q: %v", test.addrsStr, err)
-				continue
-			}
-			if !reflect.DeepEqual([]*Address{addr}, test.exp) {
-				t.Errorf("Parse (single) of %q: got %+v, want %+v", test.addrsStr, addr, test.exp)
-			}
-		}
-
-		addrs, err := ParseAddressList(test.addrsStr)
-		if err != nil {
-			t.Errorf("Failed parsing (list) %q: %v", test.addrsStr, err)
-			continue
-		}
-		if !reflect.DeepEqual(addrs, test.exp) {
-			t.Errorf("Parse (list) of %q: got %+v, want %+v", test.addrsStr, addrs, test.exp)
-		}
-	}
-}
-
-func TestAddressFormatting(t *testing.T) {
-	tests := []struct {
-		addr *Address
-		exp  string
-	}{
-		{
-			&Address{Address: "bob at example.com"},
-			"<bob at example.com>",
-		},
-		{
-			&Address{Name: "Bob", Address: "bob at example.com"},
-			`"Bob" <bob at example.com>`,
-		},
-		{
-			// note the ö (o with an umlaut)
-			&Address{Name: "Böb", Address: "bob at example.com"},
-			`=?utf-8?q?B=C3=B6b?= <bob at example.com>`,
-		},
-		{
-			&Address{Name: "Bob Jane", Address: "bob at example.com"},
-			`"Bob Jane" <bob at example.com>`,
-		},
-		{
-			&Address{Name: "Böb Jacöb", Address: "bob at example.com"},
-			`=?utf-8?q?B=C3=B6b_Jac=C3=B6b?= <bob at example.com>`,
-		},
-	}
-	for _, test := range tests {
-		s := test.addr.String()
-		if s != test.exp {
-			t.Errorf("Address%+v.String() = %v, want %v", *test.addr, s, test.exp)
-		}
-	}
-}
diff --git a/src/pkg/net/multicast_test.go b/src/pkg/net/multicast_test.go
deleted file mode 100644
index 63dbce8..0000000
--- a/src/pkg/net/multicast_test.go
+++ /dev/null
@@ -1,188 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package net
-
-import (
-	"fmt"
-	"os"
-	"runtime"
-	"testing"
-)
-
-var ipv4MulticastListenerTests = []struct {
-	net   string
-	gaddr *UDPAddr // see RFC 4727
-}{
-	{"udp", &UDPAddr{IP: IPv4(224, 0, 0, 254), Port: 12345}},
-
-	{"udp4", &UDPAddr{IP: IPv4(224, 0, 0, 254), Port: 12345}},
-}
-
-// TestIPv4MulticastListener tests both single and double listen to a
-// test listener with same address family, same group address and same
-// port.
-func TestIPv4MulticastListener(t *testing.T) {
-	switch runtime.GOOS {
-	case "nacl", "plan9":
-		t.Skipf("skipping test on %q", runtime.GOOS)
-	case "solaris":
-		t.Skipf("skipping test on solaris, see issue 7399")
-	}
-
-	closer := func(cs []*UDPConn) {
-		for _, c := range cs {
-			if c != nil {
-				c.Close()
-			}
-		}
-	}
-
-	for _, ifi := range []*Interface{loopbackInterface(), nil} {
-		// Note that multicast interface assignment by system
-		// is not recommended because it usually relies on
-		// routing stuff for finding out an appropriate
-		// nexthop containing both network and link layer
-		// adjacencies.
-		if ifi == nil && !*testExternal {
-			continue
-		}
-		for _, tt := range ipv4MulticastListenerTests {
-			var err error
-			cs := make([]*UDPConn, 2)
-			if cs[0], err = ListenMulticastUDP(tt.net, ifi, tt.gaddr); err != nil {
-				t.Fatalf("First ListenMulticastUDP on %v failed: %v", ifi, err)
-			}
-			if err := checkMulticastListener(cs[0], tt.gaddr.IP); err != nil {
-				closer(cs)
-				t.Fatal(err)
-			}
-			if cs[1], err = ListenMulticastUDP(tt.net, ifi, tt.gaddr); err != nil {
-				closer(cs)
-				t.Fatalf("Second ListenMulticastUDP on %v failed: %v", ifi, err)
-			}
-			if err := checkMulticastListener(cs[1], tt.gaddr.IP); err != nil {
-				closer(cs)
-				t.Fatal(err)
-			}
-			closer(cs)
-		}
-	}
-}
-
-var ipv6MulticastListenerTests = []struct {
-	net   string
-	gaddr *UDPAddr // see RFC 4727
-}{
-	{"udp", &UDPAddr{IP: ParseIP("ff01::114"), Port: 12345}},
-	{"udp", &UDPAddr{IP: ParseIP("ff02::114"), Port: 12345}},
-	{"udp", &UDPAddr{IP: ParseIP("ff04::114"), Port: 12345}},
-	{"udp", &UDPAddr{IP: ParseIP("ff05::114"), Port: 12345}},
-	{"udp", &UDPAddr{IP: ParseIP("ff08::114"), Port: 12345}},
-	{"udp", &UDPAddr{IP: ParseIP("ff0e::114"), Port: 12345}},
-
-	{"udp6", &UDPAddr{IP: ParseIP("ff01::114"), Port: 12345}},
-	{"udp6", &UDPAddr{IP: ParseIP("ff02::114"), Port: 12345}},
-	{"udp6", &UDPAddr{IP: ParseIP("ff04::114"), Port: 12345}},
-	{"udp6", &UDPAddr{IP: ParseIP("ff05::114"), Port: 12345}},
-	{"udp6", &UDPAddr{IP: ParseIP("ff08::114"), Port: 12345}},
-	{"udp6", &UDPAddr{IP: ParseIP("ff0e::114"), Port: 12345}},
-}
-
-// TestIPv6MulticastListener tests both single and double listen to a
-// test listener with same address family, same group address and same
-// port.
-func TestIPv6MulticastListener(t *testing.T) {
-	switch runtime.GOOS {
-	case "plan9":
-		t.Skipf("skipping test on %q", runtime.GOOS)
-	case "solaris":
-		t.Skipf("skipping test on solaris, see issue 7399")
-	}
-	if !supportsIPv6 {
-		t.Skip("ipv6 is not supported")
-	}
-	if os.Getuid() != 0 {
-		t.Skip("skipping test; must be root")
-	}
-
-	closer := func(cs []*UDPConn) {
-		for _, c := range cs {
-			if c != nil {
-				c.Close()
-			}
-		}
-	}
-
-	for _, ifi := range []*Interface{loopbackInterface(), nil} {
-		// Note that multicast interface assignment by system
-		// is not recommended because it usually relies on
-		// routing stuff for finding out an appropriate
-		// nexthop containing both network and link layer
-		// adjacencies.
-		if ifi == nil && (!*testExternal || !*testIPv6) {
-			continue
-		}
-		for _, tt := range ipv6MulticastListenerTests {
-			var err error
-			cs := make([]*UDPConn, 2)
-			if cs[0], err = ListenMulticastUDP(tt.net, ifi, tt.gaddr); err != nil {
-				t.Fatalf("First ListenMulticastUDP on %v failed: %v", ifi, err)
-			}
-			if err := checkMulticastListener(cs[0], tt.gaddr.IP); err != nil {
-				closer(cs)
-				t.Fatal(err)
-			}
-			if cs[1], err = ListenMulticastUDP(tt.net, ifi, tt.gaddr); err != nil {
-				closer(cs)
-				t.Fatalf("Second ListenMulticastUDP on %v failed: %v", ifi, err)
-			}
-			if err := checkMulticastListener(cs[1], tt.gaddr.IP); err != nil {
-				closer(cs)
-				t.Fatal(err)
-			}
-			closer(cs)
-		}
-	}
-}
-
-func checkMulticastListener(c *UDPConn, ip IP) error {
-	if ok, err := multicastRIBContains(ip); err != nil {
-		return err
-	} else if !ok {
-		return fmt.Errorf("%q not found in multicast RIB", ip.String())
-	}
-	la := c.LocalAddr()
-	if la, ok := la.(*UDPAddr); !ok || la.Port == 0 {
-		return fmt.Errorf("got %v; expected a proper address with non-zero port number", la)
-	}
-	return nil
-}
-
-func multicastRIBContains(ip IP) (bool, error) {
-	switch runtime.GOOS {
-	case "dragonfly", "netbsd", "openbsd", "plan9", "solaris", "windows":
-		return true, nil // not implemented yet
-	case "linux":
-		if runtime.GOARCH == "arm" || runtime.GOARCH == "alpha" {
-			return true, nil // not implemented yet
-		}
-	}
-	ift, err := Interfaces()
-	if err != nil {
-		return false, err
-	}
-	for _, ifi := range ift {
-		ifmat, err := ifi.MulticastAddrs()
-		if err != nil {
-			return false, err
-		}
-		for _, ifma := range ifmat {
-			if ifma.(*IPAddr).IP.Equal(ip) {
-				return true, nil
-			}
-		}
-	}
-	return false, nil
-}
diff --git a/src/pkg/net/net.go b/src/pkg/net/net.go
deleted file mode 100644
index ca56af5..0000000
--- a/src/pkg/net/net.go
+++ /dev/null
@@ -1,426 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-/*
-Package net provides a portable interface for network I/O, including
-TCP/IP, UDP, domain name resolution, and Unix domain sockets.
-
-Although the package provides access to low-level networking
-primitives, most clients will need only the basic interface provided
-by the Dial, Listen, and Accept functions and the associated
-Conn and Listener interfaces. The crypto/tls package uses
-the same interfaces and similar Dial and Listen functions.
-
-The Dial function connects to a server:
-
-	conn, err := net.Dial("tcp", "google.com:80")
-	if err != nil {
-		// handle error
-	}
-	fmt.Fprintf(conn, "GET / HTTP/1.0\r\n\r\n")
-	status, err := bufio.NewReader(conn).ReadString('\n')
-	// ...
-
-The Listen function creates servers:
-
-	ln, err := net.Listen("tcp", ":8080")
-	if err != nil {
-		// handle error
-	}
-	for {
-		conn, err := ln.Accept()
-		if err != nil {
-			// handle error
-			continue
-		}
-		go handleConnection(conn)
-	}
-*/
-package net
-
-// TODO(rsc):
-//	support for raw ethernet sockets
-
-import (
-	"errors"
-	"io"
-	"os"
-	"syscall"
-	"time"
-)
-
-// Addr represents a network end point address.
-type Addr interface {
-	Network() string // name of the network
-	String() string  // string form of address
-}
-
-// Conn is a generic stream-oriented network connection.
-//
-// Multiple goroutines may invoke methods on a Conn simultaneously.
-type Conn interface {
-	// Read reads data from the connection.
-	// Read can be made to time out and return a Error with Timeout() == true
-	// after a fixed time limit; see SetDeadline and SetReadDeadline.
-	Read(b []byte) (n int, err error)
-
-	// Write writes data to the connection.
-	// Write can be made to time out and return a Error with Timeout() == true
-	// after a fixed time limit; see SetDeadline and SetWriteDeadline.
-	Write(b []byte) (n int, err error)
-
-	// Close closes the connection.
-	// Any blocked Read or Write operations will be unblocked and return errors.
-	Close() error
-
-	// LocalAddr returns the local network address.
-	LocalAddr() Addr
-
-	// RemoteAddr returns the remote network address.
-	RemoteAddr() Addr
-
-	// SetDeadline sets the read and write deadlines associated
-	// with the connection. It is equivalent to calling both
-	// SetReadDeadline and SetWriteDeadline.
-	//
-	// A deadline is an absolute time after which I/O operations
-	// fail with a timeout (see type Error) instead of
-	// blocking. The deadline applies to all future I/O, not just
-	// the immediately following call to Read or Write.
-	//
-	// An idle timeout can be implemented by repeatedly extending
-	// the deadline after successful Read or Write calls.
-	//
-	// A zero value for t means I/O operations will not time out.
-	SetDeadline(t time.Time) error
-
-	// SetReadDeadline sets the deadline for future Read calls.
-	// A zero value for t means Read will not time out.
-	SetReadDeadline(t time.Time) error
-
-	// SetWriteDeadline sets the deadline for future Write calls.
-	// Even if write times out, it may return n > 0, indicating that
-	// some of the data was successfully written.
-	// A zero value for t means Write will not time out.
-	SetWriteDeadline(t time.Time) error
-}
-
-type conn struct {
-	fd *netFD
-}
-
-func (c *conn) ok() bool { return c != nil && c.fd != nil }
-
-// Implementation of the Conn interface.
-
-// Read implements the Conn Read method.
-func (c *conn) Read(b []byte) (int, error) {
-	if !c.ok() {
-		return 0, syscall.EINVAL
-	}
-	return c.fd.Read(b)
-}
-
-// Write implements the Conn Write method.
-func (c *conn) Write(b []byte) (int, error) {
-	if !c.ok() {
-		return 0, syscall.EINVAL
-	}
-	return c.fd.Write(b)
-}
-
-// Close closes the connection.
-func (c *conn) Close() error {
-	if !c.ok() {
-		return syscall.EINVAL
-	}
-	return c.fd.Close()
-}
-
-// LocalAddr returns the local network address.
-func (c *conn) LocalAddr() Addr {
-	if !c.ok() {
-		return nil
-	}
-	return c.fd.laddr
-}
-
-// RemoteAddr returns the remote network address.
-func (c *conn) RemoteAddr() Addr {
-	if !c.ok() {
-		return nil
-	}
-	return c.fd.raddr
-}
-
-// SetDeadline implements the Conn SetDeadline method.
-func (c *conn) SetDeadline(t time.Time) error {
-	if !c.ok() {
-		return syscall.EINVAL
-	}
-	return c.fd.setDeadline(t)
-}
-
-// SetReadDeadline implements the Conn SetReadDeadline method.
-func (c *conn) SetReadDeadline(t time.Time) error {
-	if !c.ok() {
-		return syscall.EINVAL
-	}
-	return c.fd.setReadDeadline(t)
-}
-
-// SetWriteDeadline implements the Conn SetWriteDeadline method.
-func (c *conn) SetWriteDeadline(t time.Time) error {
-	if !c.ok() {
-		return syscall.EINVAL
-	}
-	return c.fd.setWriteDeadline(t)
-}
-
-// SetReadBuffer sets the size of the operating system's
-// receive buffer associated with the connection.
-func (c *conn) SetReadBuffer(bytes int) error {
-	if !c.ok() {
-		return syscall.EINVAL
-	}
-	return setReadBuffer(c.fd, bytes)
-}
-
-// SetWriteBuffer sets the size of the operating system's
-// transmit buffer associated with the connection.
-func (c *conn) SetWriteBuffer(bytes int) error {
-	if !c.ok() {
-		return syscall.EINVAL
-	}
-	return setWriteBuffer(c.fd, bytes)
-}
-
-// File sets the underlying os.File to blocking mode and returns a copy.
-// It is the caller's responsibility to close f when finished.
-// Closing c does not affect f, and closing f does not affect c.
-//
-// The returned os.File's file descriptor is different from the connection's.
-// Attempting to change properties of the original using this duplicate
-// may or may not have the desired effect.
-func (c *conn) File() (f *os.File, err error) { return c.fd.dup() }
-
-// An Error represents a network error.
-type Error interface {
-	error
-	Timeout() bool   // Is the error a timeout?
-	Temporary() bool // Is the error temporary?
-}
-
-// PacketConn is a generic packet-oriented network connection.
-//
-// Multiple goroutines may invoke methods on a PacketConn simultaneously.
-type PacketConn interface {
-	// ReadFrom reads a packet from the connection,
-	// copying the payload into b.  It returns the number of
-	// bytes copied into b and the return address that
-	// was on the packet.
-	// ReadFrom can be made to time out and return
-	// an error with Timeout() == true after a fixed time limit;
-	// see SetDeadline and SetReadDeadline.
-	ReadFrom(b []byte) (n int, addr Addr, err error)
-
-	// WriteTo writes a packet with payload b to addr.
-	// WriteTo can be made to time out and return
-	// an error with Timeout() == true after a fixed time limit;
-	// see SetDeadline and SetWriteDeadline.
-	// On packet-oriented connections, write timeouts are rare.
-	WriteTo(b []byte, addr Addr) (n int, err error)
-
-	// Close closes the connection.
-	// Any blocked ReadFrom or WriteTo operations will be unblocked and return errors.
-	Close() error
-
-	// LocalAddr returns the local network address.
-	LocalAddr() Addr
-
-	// SetDeadline sets the read and write deadlines associated
-	// with the connection.
-	SetDeadline(t time.Time) error
-
-	// SetReadDeadline sets the deadline for future Read calls.
-	// If the deadline is reached, Read will fail with a timeout
-	// (see type Error) instead of blocking.
-	// A zero value for t means Read will not time out.
-	SetReadDeadline(t time.Time) error
-
-	// SetWriteDeadline sets the deadline for future Write calls.
-	// If the deadline is reached, Write will fail with a timeout
-	// (see type Error) instead of blocking.
-	// A zero value for t means Write will not time out.
-	// Even if write times out, it may return n > 0, indicating that
-	// some of the data was successfully written.
-	SetWriteDeadline(t time.Time) error
-}
-
-var listenerBacklog = maxListenerBacklog()
-
-// A Listener is a generic network listener for stream-oriented protocols.
-//
-// Multiple goroutines may invoke methods on a Listener simultaneously.
-type Listener interface {
-	// Accept waits for and returns the next connection to the listener.
-	Accept() (c Conn, err error)
-
-	// Close closes the listener.
-	// Any blocked Accept operations will be unblocked and return errors.
-	Close() error
-
-	// Addr returns the listener's network address.
-	Addr() Addr
-}
-
-// Various errors contained in OpError.
-var (
-	// For connection setup and write operations.
-	errMissingAddress = errors.New("missing address")
-
-	// For both read and write operations.
-	errTimeout          error = &timeoutError{}
-	errClosing                = errors.New("use of closed network connection")
-	ErrWriteToConnected       = errors.New("use of WriteTo with pre-connected connection")
-)
-
-// OpError is the error type usually returned by functions in the net
-// package. It describes the operation, network type, and address of
-// an error.
-type OpError struct {
-	// Op is the operation which caused the error, such as
-	// "read" or "write".
-	Op string
-
-	// Net is the network type on which this error occurred,
-	// such as "tcp" or "udp6".
-	Net string
-
-	// Addr is the network address on which this error occurred.
-	Addr Addr
-
-	// Err is the error that occurred during the operation.
-	Err error
-}
-
-func (e *OpError) Error() string {
-	if e == nil {
-		return "<nil>"
-	}
-	s := e.Op
-	if e.Net != "" {
-		s += " " + e.Net
-	}
-	if e.Addr != nil {
-		s += " " + e.Addr.String()
-	}
-	s += ": " + e.Err.Error()
-	return s
-}
-
-type temporary interface {
-	Temporary() bool
-}
-
-func (e *OpError) Temporary() bool {
-	t, ok := e.Err.(temporary)
-	return ok && t.Temporary()
-}
-
-var noDeadline = time.Time{}
-
-type timeout interface {
-	Timeout() bool
-}
-
-func (e *OpError) Timeout() bool {
-	t, ok := e.Err.(timeout)
-	return ok && t.Timeout()
-}
-
-type timeoutError struct{}
-
-func (e *timeoutError) Error() string   { return "i/o timeout" }
-func (e *timeoutError) Timeout() bool   { return true }
-func (e *timeoutError) Temporary() bool { return true }
-
-type AddrError struct {
-	Err  string
-	Addr string
-}
-
-func (e *AddrError) Error() string {
-	if e == nil {
-		return "<nil>"
-	}
-	s := e.Err
-	if e.Addr != "" {
-		s += " " + e.Addr
-	}
-	return s
-}
-
-func (e *AddrError) Temporary() bool {
-	return false
-}
-
-func (e *AddrError) Timeout() bool {
-	return false
-}
-
-type UnknownNetworkError string
-
-func (e UnknownNetworkError) Error() string   { return "unknown network " + string(e) }
-func (e UnknownNetworkError) Temporary() bool { return false }
-func (e UnknownNetworkError) Timeout() bool   { return false }
-
-type InvalidAddrError string
-
-func (e InvalidAddrError) Error() string   { return string(e) }
-func (e InvalidAddrError) Timeout() bool   { return false }
-func (e InvalidAddrError) Temporary() bool { return false }
-
-// DNSConfigError represents an error reading the machine's DNS configuration.
-type DNSConfigError struct {
-	Err error
-}
-
-func (e *DNSConfigError) Error() string {
-	return "error reading DNS config: " + e.Err.Error()
-}
-
-func (e *DNSConfigError) Timeout() bool   { return false }
-func (e *DNSConfigError) Temporary() bool { return false }
-
-type writerOnly struct {
-	io.Writer
-}
-
-// Fallback implementation of io.ReaderFrom's ReadFrom, when sendfile isn't
-// applicable.
-func genericReadFrom(w io.Writer, r io.Reader) (n int64, err error) {
-	// Use wrapper to hide existing r.ReadFrom from io.Copy.
-	return io.Copy(writerOnly{w}, r)
-}
-
-// Limit the number of concurrent cgo-using goroutines, because
-// each will block an entire operating system thread. The usual culprit
-// is resolving many DNS names in separate goroutines but the DNS
-// server is not responding. Then the many lookups each use a different
-// thread, and the system or the program runs out of threads.
-
-var threadLimit = make(chan struct{}, 500)
-
-// Using send for acquire is fine here because we are not using this
-// to protect any memory. All we care about is the number of goroutines
-// making calls at a time.
-
-func acquireThread() {
-	threadLimit <- struct{}{}
-}
-
-func releaseThread() {
-	<-threadLimit
-}
diff --git a/src/pkg/net/parse.go b/src/pkg/net/parse.go
deleted file mode 100644
index ee6e7e9..0000000
--- a/src/pkg/net/parse.go
+++ /dev/null
@@ -1,247 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Simple file i/o and string manipulation, to avoid
-// depending on strconv and bufio and strings.
-
-package net
-
-import (
-	"io"
-	"os"
-)
-
-type file struct {
-	file  *os.File
-	data  []byte
-	atEOF bool
-}
-
-func (f *file) close() { f.file.Close() }
-
-func (f *file) getLineFromData() (s string, ok bool) {
-	data := f.data
-	i := 0
-	for i = 0; i < len(data); i++ {
-		if data[i] == '\n' {
-			s = string(data[0:i])
-			ok = true
-			// move data
-			i++
-			n := len(data) - i
-			copy(data[0:], data[i:])
-			f.data = data[0:n]
-			return
-		}
-	}
-	if f.atEOF && len(f.data) > 0 {
-		// EOF, return all we have
-		s = string(data)
-		f.data = f.data[0:0]
-		ok = true
-	}
-	return
-}
-
-func (f *file) readLine() (s string, ok bool) {
-	if s, ok = f.getLineFromData(); ok {
-		return
-	}
-	if len(f.data) < cap(f.data) {
-		ln := len(f.data)
-		n, err := io.ReadFull(f.file, f.data[ln:cap(f.data)])
-		if n >= 0 {
-			f.data = f.data[0 : ln+n]
-		}
-		if err == io.EOF || err == io.ErrUnexpectedEOF {
-			f.atEOF = true
-		}
-	}
-	s, ok = f.getLineFromData()
-	return
-}
-
-func open(name string) (*file, error) {
-	fd, err := os.Open(name)
-	if err != nil {
-		return nil, err
-	}
-	return &file{fd, make([]byte, 0, os.Getpagesize()), false}, nil
-}
-
-func byteIndex(s string, c byte) int {
-	for i := 0; i < len(s); i++ {
-		if s[i] == c {
-			return i
-		}
-	}
-	return -1
-}
-
-// Count occurrences in s of any bytes in t.
-func countAnyByte(s string, t string) int {
-	n := 0
-	for i := 0; i < len(s); i++ {
-		if byteIndex(t, s[i]) >= 0 {
-			n++
-		}
-	}
-	return n
-}
-
-// Split s at any bytes in t.
-func splitAtBytes(s string, t string) []string {
-	a := make([]string, 1+countAnyByte(s, t))
-	n := 0
-	last := 0
-	for i := 0; i < len(s); i++ {
-		if byteIndex(t, s[i]) >= 0 {
-			if last < i {
-				a[n] = string(s[last:i])
-				n++
-			}
-			last = i + 1
-		}
-	}
-	if last < len(s) {
-		a[n] = string(s[last:])
-		n++
-	}
-	return a[0:n]
-}
-
-func getFields(s string) []string { return splitAtBytes(s, " \r\t\n") }
-
-// Bigger than we need, not too big to worry about overflow
-const big = 0xFFFFFF
-
-// Decimal to integer starting at &s[i0].
-// Returns number, new offset, success.
-func dtoi(s string, i0 int) (n int, i int, ok bool) {
-	n = 0
-	for i = i0; i < len(s) && '0' <= s[i] && s[i] <= '9'; i++ {
-		n = n*10 + int(s[i]-'0')
-		if n >= big {
-			return 0, i, false
-		}
-	}
-	if i == i0 {
-		return 0, i, false
-	}
-	return n, i, true
-}
-
-// Hexadecimal to integer starting at &s[i0].
-// Returns number, new offset, success.
-func xtoi(s string, i0 int) (n int, i int, ok bool) {
-	n = 0
-	for i = i0; i < len(s); i++ {
-		if '0' <= s[i] && s[i] <= '9' {
-			n *= 16
-			n += int(s[i] - '0')
-		} else if 'a' <= s[i] && s[i] <= 'f' {
-			n *= 16
-			n += int(s[i]-'a') + 10
-		} else if 'A' <= s[i] && s[i] <= 'F' {
-			n *= 16
-			n += int(s[i]-'A') + 10
-		} else {
-			break
-		}
-		if n >= big {
-			return 0, i, false
-		}
-	}
-	if i == i0 {
-		return 0, i, false
-	}
-	return n, i, true
-}
-
-// xtoi2 converts the next two hex digits of s into a byte.
-// If s is longer than 2 bytes then the third byte must be e.
-// If the first two bytes of s are not hex digits or the third byte
-// does not match e, false is returned.
-func xtoi2(s string, e byte) (byte, bool) {
-	if len(s) > 2 && s[2] != e {
-		return 0, false
-	}
-	n, ei, ok := xtoi(s[:2], 0)
-	return byte(n), ok && ei == 2
-}
-
-// Integer to decimal.
-func itoa(i int) string {
-	var buf [30]byte
-	n := len(buf)
-	neg := false
-	if i < 0 {
-		i = -i
-		neg = true
-	}
-	ui := uint(i)
-	for ui > 0 || n == len(buf) {
-		n--
-		buf[n] = byte('0' + ui%10)
-		ui /= 10
-	}
-	if neg {
-		n--
-		buf[n] = '-'
-	}
-	return string(buf[n:])
-}
-
-// Convert i to decimal string.
-func itod(i uint) string {
-	if i == 0 {
-		return "0"
-	}
-
-	// Assemble decimal in reverse order.
-	var b [32]byte
-	bp := len(b)
-	for ; i > 0; i /= 10 {
-		bp--
-		b[bp] = byte(i%10) + '0'
-	}
-
-	return string(b[bp:])
-}
-
-// Convert i to hexadecimal string.
-func itox(i uint, min int) string {
-	// Assemble hexadecimal in reverse order.
-	var b [32]byte
-	bp := len(b)
-	for ; i > 0 || min > 0; i /= 16 {
-		bp--
-		b[bp] = "0123456789abcdef"[byte(i%16)]
-		min--
-	}
-
-	return string(b[bp:])
-}
-
-// Number of occurrences of b in s.
-func count(s string, b byte) int {
-	n := 0
-	for i := 0; i < len(s); i++ {
-		if s[i] == b {
-			n++
-		}
-	}
-	return n
-}
-
-// Index of rightmost occurrence of b in s.
-func last(s string, b byte) int {
-	i := len(s)
-	for i--; i >= 0; i-- {
-		if s[i] == b {
-			break
-		}
-	}
-	return i
-}
diff --git a/src/pkg/net/parse_test.go b/src/pkg/net/parse_test.go
deleted file mode 100644
index b86bc32..0000000
--- a/src/pkg/net/parse_test.go
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package net
-
-import (
-	"bufio"
-	"os"
-	"runtime"
-	"testing"
-)
-
-func TestReadLine(t *testing.T) {
-	// /etc/services file does not exist on windows and Plan 9.
-	switch runtime.GOOS {
-	case "plan9", "windows":
-		t.Skipf("skipping test on %q", runtime.GOOS)
-	}
-	filename := "/etc/services" // a nice big file
-
-	fd, err := os.Open(filename)
-	if err != nil {
-		t.Fatalf("open %s: %v", filename, err)
-	}
-	defer fd.Close()
-	br := bufio.NewReader(fd)
-
-	file, err := open(filename)
-	if file == nil {
-		t.Fatalf("net.open(%s) = nil", filename)
-	}
-	defer file.close()
-
-	lineno := 1
-	byteno := 0
-	for {
-		bline, berr := br.ReadString('\n')
-		if n := len(bline); n > 0 {
-			bline = bline[0 : n-1]
-		}
-		line, ok := file.readLine()
-		if (berr != nil) != !ok || bline != line {
-			t.Fatalf("%s:%d (#%d)\nbufio => %q, %v\nnet => %q, %v",
-				filename, lineno, byteno, bline, berr, line, ok)
-		}
-		if !ok {
-			break
-		}
-		lineno++
-		byteno += len(line) + 1
-	}
-}
diff --git a/src/pkg/net/port_test.go b/src/pkg/net/port_test.go
deleted file mode 100644
index 9e8968f..0000000
--- a/src/pkg/net/port_test.go
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package net
-
-import (
-	"testing"
-)
-
-type portTest struct {
-	netw string
-	name string
-	port int
-	ok   bool
-}
-
-var porttests = []portTest{
-	{"tcp", "echo", 7, true},
-	{"tcp", "discard", 9, true},
-	{"tcp", "systat", 11, true},
-	{"tcp", "daytime", 13, true},
-	{"tcp", "chargen", 19, true},
-	{"tcp", "ftp-data", 20, true},
-	{"tcp", "ftp", 21, true},
-	{"tcp", "telnet", 23, true},
-	{"tcp", "smtp", 25, true},
-	{"tcp", "time", 37, true},
-	{"tcp", "domain", 53, true},
-	{"tcp", "finger", 79, true},
-
-	{"udp", "echo", 7, true},
-	{"udp", "tftp", 69, true},
-	{"udp", "bootpc", 68, true},
-	{"udp", "bootps", 67, true},
-	{"udp", "domain", 53, true},
-	{"udp", "ntp", 123, true},
-	{"udp", "snmp", 161, true},
-	{"udp", "syslog", 514, true},
-
-	{"--badnet--", "zzz", 0, false},
-	{"tcp", "--badport--", 0, false},
-}
-
-func TestLookupPort(t *testing.T) {
-	for i := 0; i < len(porttests); i++ {
-		tt := porttests[i]
-		if port, err := LookupPort(tt.netw, tt.name); port != tt.port || (err == nil) != tt.ok {
-			t.Errorf("LookupPort(%q, %q) = %v, %v; want %v",
-				tt.netw, tt.name, port, err, tt.port)
-		}
-	}
-}
diff --git a/src/pkg/net/port_unix.go b/src/pkg/net/port_unix.go
deleted file mode 100644
index 89558c1..0000000
--- a/src/pkg/net/port_unix.go
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris
-
-// Read system port mappings from /etc/services
-
-package net
-
-import "sync"
-
-// services contains minimal mappings between services names and port
-// numbers for platforms that don't have a complete list of port numbers
-// (some Solaris distros).
-var services = map[string]map[string]int{
-	"tcp": {"http": 80},
-}
-var servicesError error
-var onceReadServices sync.Once
-
-func readServices() {
-	var file *file
-	if file, servicesError = open("/etc/services"); servicesError != nil {
-		return
-	}
-	for line, ok := file.readLine(); ok; line, ok = file.readLine() {
-		// "http 80/tcp www www-http # World Wide Web HTTP"
-		if i := byteIndex(line, '#'); i >= 0 {
-			line = line[0:i]
-		}
-		f := getFields(line)
-		if len(f) < 2 {
-			continue
-		}
-		portnet := f[1] // "80/tcp"
-		port, j, ok := dtoi(portnet, 0)
-		if !ok || port <= 0 || j >= len(portnet) || portnet[j] != '/' {
-			continue
-		}
-		netw := portnet[j+1:] // "tcp"
-		m, ok1 := services[netw]
-		if !ok1 {
-			m = make(map[string]int)
-			services[netw] = m
-		}
-		for i := 0; i < len(f); i++ {
-			if i != 1 { // f[1] was port/net
-				m[f[i]] = port
-			}
-		}
-	}
-	file.close()
-}
-
-// goLookupPort is the native Go implementation of LookupPort.
-func goLookupPort(network, service string) (port int, err error) {
-	onceReadServices.Do(readServices)
-
-	switch network {
-	case "tcp4", "tcp6":
-		network = "tcp"
-	case "udp4", "udp6":
-		network = "udp"
-	}
-
-	if m, ok := services[network]; ok {
-		if port, ok = m[service]; ok {
-			return
-		}
-	}
-	return 0, &AddrError{"unknown port", network + "/" + service}
-}
diff --git a/src/pkg/net/rpc/client.go b/src/pkg/net/rpc/client.go
deleted file mode 100644
index 21f79b0..0000000
--- a/src/pkg/net/rpc/client.go
+++ /dev/null
@@ -1,317 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package rpc
-
-import (
-	"bufio"
-	"encoding/gob"
-	"errors"
-	"io"
-	"log"
-	"net"
-	"net/http"
-	"sync"
-)
-
-// ServerError represents an error that has been returned from
-// the remote side of the RPC connection.
-type ServerError string
-
-func (e ServerError) Error() string {
-	return string(e)
-}
-
-var ErrShutdown = errors.New("connection is shut down")
-
-// Call represents an active RPC.
-type Call struct {
-	ServiceMethod string      // The name of the service and method to call.
-	Args          interface{} // The argument to the function (*struct).
-	Reply         interface{} // The reply from the function (*struct).
-	Error         error       // After completion, the error status.
-	Done          chan *Call  // Strobes when call is complete.
-}
-
-// Client represents an RPC Client.
-// There may be multiple outstanding Calls associated
-// with a single Client, and a Client may be used by
-// multiple goroutines simultaneously.
-type Client struct {
-	codec ClientCodec
-
-	sending sync.Mutex
-
-	mutex    sync.Mutex // protects following
-	request  Request
-	seq      uint64
-	pending  map[uint64]*Call
-	closing  bool // user has called Close
-	shutdown bool // server has told us to stop
-}
-
-// A ClientCodec implements writing of RPC requests and
-// reading of RPC responses for the client side of an RPC session.
-// The client calls WriteRequest to write a request to the connection
-// and calls ReadResponseHeader and ReadResponseBody in pairs
-// to read responses.  The client calls Close when finished with the
-// connection. ReadResponseBody may be called with a nil
-// argument to force the body of the response to be read and then
-// discarded.
-type ClientCodec interface {
-	// WriteRequest must be safe for concurrent use by multiple goroutines.
-	WriteRequest(*Request, interface{}) error
-	ReadResponseHeader(*Response) error
-	ReadResponseBody(interface{}) error
-
-	Close() error
-}
-
-func (client *Client) send(call *Call) {
-	client.sending.Lock()
-	defer client.sending.Unlock()
-
-	// Register this call.
-	client.mutex.Lock()
-	if client.shutdown || client.closing {
-		call.Error = ErrShutdown
-		client.mutex.Unlock()
-		call.done()
-		return
-	}
-	seq := client.seq
-	client.seq++
-	client.pending[seq] = call
-	client.mutex.Unlock()
-
-	// Encode and send the request.
-	client.request.Seq = seq
-	client.request.ServiceMethod = call.ServiceMethod
-	err := client.codec.WriteRequest(&client.request, call.Args)
-	if err != nil {
-		client.mutex.Lock()
-		call = client.pending[seq]
-		delete(client.pending, seq)
-		client.mutex.Unlock()
-		if call != nil {
-			call.Error = err
-			call.done()
-		}
-	}
-}
-
-func (client *Client) input() {
-	var err error
-	var response Response
-	for err == nil {
-		response = Response{}
-		err = client.codec.ReadResponseHeader(&response)
-		if err != nil {
-			break
-		}
-		seq := response.Seq
-		client.mutex.Lock()
-		call := client.pending[seq]
-		delete(client.pending, seq)
-		client.mutex.Unlock()
-
-		switch {
-		case call == nil:
-			// We've got no pending call. That usually means that
-			// WriteRequest partially failed, and call was already
-			// removed; response is a server telling us about an
-			// error reading request body. We should still attempt
-			// to read error body, but there's no one to give it to.
-			err = client.codec.ReadResponseBody(nil)
-			if err != nil {
-				err = errors.New("reading error body: " + err.Error())
-			}
-		case response.Error != "":
-			// We've got an error response. Give this to the request;
-			// any subsequent requests will get the ReadResponseBody
-			// error if there is one.
-			call.Error = ServerError(response.Error)
-			err = client.codec.ReadResponseBody(nil)
-			if err != nil {
-				err = errors.New("reading error body: " + err.Error())
-			}
-			call.done()
-		default:
-			err = client.codec.ReadResponseBody(call.Reply)
-			if err != nil {
-				call.Error = errors.New("reading body " + err.Error())
-			}
-			call.done()
-		}
-	}
-	// Terminate pending calls.
-	client.sending.Lock()
-	client.mutex.Lock()
-	client.shutdown = true
-	closing := client.closing
-	if err == io.EOF {
-		if closing {
-			err = ErrShutdown
-		} else {
-			err = io.ErrUnexpectedEOF
-		}
-	}
-	for _, call := range client.pending {
-		call.Error = err
-		call.done()
-	}
-	client.mutex.Unlock()
-	client.sending.Unlock()
-	if debugLog && err != io.EOF && !closing {
-		log.Println("rpc: client protocol error:", err)
-	}
-}
-
-func (call *Call) done() {
-	select {
-	case call.Done <- call:
-		// ok
-	default:
-		// We don't want to block here.  It is the caller's responsibility to make
-		// sure the channel has enough buffer space. See comment in Go().
-		if debugLog {
-			log.Println("rpc: discarding Call reply due to insufficient Done chan capacity")
-		}
-	}
-}
-
-// NewClient returns a new Client to handle requests to the
-// set of services at the other end of the connection.
-// It adds a buffer to the write side of the connection so
-// the header and payload are sent as a unit.
-func NewClient(conn io.ReadWriteCloser) *Client {
-	encBuf := bufio.NewWriter(conn)
-	client := &gobClientCodec{conn, gob.NewDecoder(conn), gob.NewEncoder(encBuf), encBuf}
-	return NewClientWithCodec(client)
-}
-
-// NewClientWithCodec is like NewClient but uses the specified
-// codec to encode requests and decode responses.
-func NewClientWithCodec(codec ClientCodec) *Client {
-	client := &Client{
-		codec:   codec,
-		pending: make(map[uint64]*Call),
-	}
-	go client.input()
-	return client
-}
-
-type gobClientCodec struct {
-	rwc    io.ReadWriteCloser
-	dec    *gob.Decoder
-	enc    *gob.Encoder
-	encBuf *bufio.Writer
-}
-
-func (c *gobClientCodec) WriteRequest(r *Request, body interface{}) (err error) {
-	if err = c.enc.Encode(r); err != nil {
-		return
-	}
-	if err = c.enc.Encode(body); err != nil {
-		return
-	}
-	return c.encBuf.Flush()
-}
-
-func (c *gobClientCodec) ReadResponseHeader(r *Response) error {
-	return c.dec.Decode(r)
-}
-
-func (c *gobClientCodec) ReadResponseBody(body interface{}) error {
-	return c.dec.Decode(body)
-}
-
-func (c *gobClientCodec) Close() error {
-	return c.rwc.Close()
-}
-
-// DialHTTP connects to an HTTP RPC server at the specified network address
-// listening on the default HTTP RPC path.
-func DialHTTP(network, address string) (*Client, error) {
-	return DialHTTPPath(network, address, DefaultRPCPath)
-}
-
-// DialHTTPPath connects to an HTTP RPC server
-// at the specified network address and path.
-func DialHTTPPath(network, address, path string) (*Client, error) {
-	var err error
-	conn, err := net.Dial(network, address)
-	if err != nil {
-		return nil, err
-	}
-	io.WriteString(conn, "CONNECT "+path+" HTTP/1.0\n\n")
-
-	// Require successful HTTP response
-	// before switching to RPC protocol.
-	resp, err := http.ReadResponse(bufio.NewReader(conn), &http.Request{Method: "CONNECT"})
-	if err == nil && resp.Status == connected {
-		return NewClient(conn), nil
-	}
-	if err == nil {
-		err = errors.New("unexpected HTTP response: " + resp.Status)
-	}
-	conn.Close()
-	return nil, &net.OpError{
-		Op:   "dial-http",
-		Net:  network + " " + address,
-		Addr: nil,
-		Err:  err,
-	}
-}
-
-// Dial connects to an RPC server at the specified network address.
-func Dial(network, address string) (*Client, error) {
-	conn, err := net.Dial(network, address)
-	if err != nil {
-		return nil, err
-	}
-	return NewClient(conn), nil
-}
-
-func (client *Client) Close() error {
-	client.mutex.Lock()
-	if client.closing {
-		client.mutex.Unlock()
-		return ErrShutdown
-	}
-	client.closing = true
-	client.mutex.Unlock()
-	return client.codec.Close()
-}
-
-// Go invokes the function asynchronously.  It returns the Call structure representing
-// the invocation.  The done channel will signal when the call is complete by returning
-// the same Call object.  If done is nil, Go will allocate a new channel.
-// If non-nil, done must be buffered or Go will deliberately crash.
-func (client *Client) Go(serviceMethod string, args interface{}, reply interface{}, done chan *Call) *Call {
-	call := new(Call)
-	call.ServiceMethod = serviceMethod
-	call.Args = args
-	call.Reply = reply
-	if done == nil {
-		done = make(chan *Call, 10) // buffered.
-	} else {
-		// If caller passes done != nil, it must arrange that
-		// done has enough buffer for the number of simultaneous
-		// RPCs that will be using that channel.  If the channel
-		// is totally unbuffered, it's best not to run at all.
-		if cap(done) == 0 {
-			log.Panic("rpc: done channel is unbuffered")
-		}
-	}
-	call.Done = done
-	client.send(call)
-	return call
-}
-
-// Call invokes the named function, waits for it to complete, and returns its error status.
-func (client *Client) Call(serviceMethod string, args interface{}, reply interface{}) error {
-	call := <-client.Go(serviceMethod, args, reply, make(chan *Call, 1)).Done
-	return call.Error
-}
diff --git a/src/pkg/net/rpc/client_test.go b/src/pkg/net/rpc/client_test.go
deleted file mode 100644
index bbfc1ec..0000000
--- a/src/pkg/net/rpc/client_test.go
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package rpc
-
-import (
-	"errors"
-	"testing"
-)
-
-type shutdownCodec struct {
-	responded chan int
-	closed    bool
-}
-
-func (c *shutdownCodec) WriteRequest(*Request, interface{}) error { return nil }
-func (c *shutdownCodec) ReadResponseBody(interface{}) error       { return nil }
-func (c *shutdownCodec) ReadResponseHeader(*Response) error {
-	c.responded <- 1
-	return errors.New("shutdownCodec ReadResponseHeader")
-}
-func (c *shutdownCodec) Close() error {
-	c.closed = true
-	return nil
-}
-
-func TestCloseCodec(t *testing.T) {
-	codec := &shutdownCodec{responded: make(chan int)}
-	client := NewClientWithCodec(codec)
-	<-codec.responded
-	client.Close()
-	if !codec.closed {
-		t.Error("client.Close did not close codec")
-	}
-}
diff --git a/src/pkg/net/rpc/debug.go b/src/pkg/net/rpc/debug.go
deleted file mode 100644
index 926466d..0000000
--- a/src/pkg/net/rpc/debug.go
+++ /dev/null
@@ -1,93 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package rpc
-
-/*
-	Some HTML presented at http://machine:port/debug/rpc
-	Lists services, their methods, and some statistics, still rudimentary.
-*/
-
-import (
-	"fmt"
-	"net/http"
-	"sort"
-	"text/template"
-)
-
-const debugText = `<html>
-	<body>
-	<title>Services</title>
-	{{range .}}
-	<hr>
-	Service {{.Name}}
-	<hr>
-		<table>
-		<th align=center>Method</th><th align=center>Calls</th>
-		{{range .Method}}
-			<tr>
-			<td align=left font=fixed>{{.Name}}({{.Type.ArgType}}, {{.Type.ReplyType}}) error</td>
-			<td align=center>{{.Type.NumCalls}}</td>
-			</tr>
-		{{end}}
-		</table>
-	{{end}}
-	</body>
-	</html>`
-
-var debug = template.Must(template.New("RPC debug").Parse(debugText))
-
-// If set, print log statements for internal and I/O errors.
-var debugLog = false
-
-type debugMethod struct {
-	Type *methodType
-	Name string
-}
-
-type methodArray []debugMethod
-
-type debugService struct {
-	Service *service
-	Name    string
-	Method  methodArray
-}
-
-type serviceArray []debugService
-
-func (s serviceArray) Len() int           { return len(s) }
-func (s serviceArray) Less(i, j int) bool { return s[i].Name < s[j].Name }
-func (s serviceArray) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
-
-func (m methodArray) Len() int           { return len(m) }
-func (m methodArray) Less(i, j int) bool { return m[i].Name < m[j].Name }
-func (m methodArray) Swap(i, j int)      { m[i], m[j] = m[j], m[i] }
-
-type debugHTTP struct {
-	*Server
-}
-
-// Runs at /debug/rpc
-func (server debugHTTP) ServeHTTP(w http.ResponseWriter, req *http.Request) {
-	// Build a sorted version of the data.
-	var services = make(serviceArray, len(server.serviceMap))
-	i := 0
-	server.mu.Lock()
-	for sname, service := range server.serviceMap {
-		services[i] = debugService{service, sname, make(methodArray, len(service.method))}
-		j := 0
-		for mname, method := range service.method {
-			services[i].Method[j] = debugMethod{method, mname}
-			j++
-		}
-		sort.Sort(services[i].Method)
-		i++
-	}
-	server.mu.Unlock()
-	sort.Sort(services)
-	err := debug.Execute(w, services)
-	if err != nil {
-		fmt.Fprintln(w, "rpc: error executing template:", err.Error())
-	}
-}
diff --git a/src/pkg/net/rpc/server.go b/src/pkg/net/rpc/server.go
deleted file mode 100644
index 6b264b4..0000000
--- a/src/pkg/net/rpc/server.go
+++ /dev/null
@@ -1,686 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-/*
-	Package rpc provides access to the exported methods of an object across a
-	network or other I/O connection.  A server registers an object, making it visible
-	as a service with the name of the type of the object.  After registration, exported
-	methods of the object will be accessible remotely.  A server may register multiple
-	objects (services) of different types but it is an error to register multiple
-	objects of the same type.
-
-	Only methods that satisfy these criteria will be made available for remote access;
-	other methods will be ignored:
-
-		- the method is exported.
-		- the method has two arguments, both exported (or builtin) types.
-		- the method's second argument is a pointer.
-		- the method has return type error.
-
-	In effect, the method must look schematically like
-
-		func (t *T) MethodName(argType T1, replyType *T2) error
-
-	where T, T1 and T2 can be marshaled by encoding/gob.
-	These requirements apply even if a different codec is used.
-	(In the future, these requirements may soften for custom codecs.)
-
-	The method's first argument represents the arguments provided by the caller; the
-	second argument represents the result parameters to be returned to the caller.
-	The method's return value, if non-nil, is passed back as a string that the client
-	sees as if created by errors.New.  If an error is returned, the reply parameter
-	will not be sent back to the client.
-
-	The server may handle requests on a single connection by calling ServeConn.  More
-	typically it will create a network listener and call Accept or, for an HTTP
-	listener, HandleHTTP and http.Serve.
-
-	A client wishing to use the service establishes a connection and then invokes
-	NewClient on the connection.  The convenience function Dial (DialHTTP) performs
-	both steps for a raw network connection (an HTTP connection).  The resulting
-	Client object has two methods, Call and Go, that specify the service and method to
-	call, a pointer containing the arguments, and a pointer to receive the result
-	parameters.
-
-	The Call method waits for the remote call to complete while the Go method
-	launches the call asynchronously and signals completion using the Call
-	structure's Done channel.
-
-	Unless an explicit codec is set up, package encoding/gob is used to
-	transport the data.
-
-	Here is a simple example.  A server wishes to export an object of type Arith:
-
-		package server
-
-		type Args struct {
-			A, B int
-		}
-
-		type Quotient struct {
-			Quo, Rem int
-		}
-
-		type Arith int
-
-		func (t *Arith) Multiply(args *Args, reply *int) error {
-			*reply = args.A * args.B
-			return nil
-		}
-
-		func (t *Arith) Divide(args *Args, quo *Quotient) error {
-			if args.B == 0 {
-				return errors.New("divide by zero")
-			}
-			quo.Quo = args.A / args.B
-			quo.Rem = args.A % args.B
-			return nil
-		}
-
-	The server calls (for HTTP service):
-
-		arith := new(Arith)
-		rpc.Register(arith)
-		rpc.HandleHTTP()
-		l, e := net.Listen("tcp", ":1234")
-		if e != nil {
-			log.Fatal("listen error:", e)
-		}
-		go http.Serve(l, nil)
-
-	At this point, clients can see a service "Arith" with methods "Arith.Multiply" and
-	"Arith.Divide".  To invoke one, a client first dials the server:
-
-		client, err := rpc.DialHTTP("tcp", serverAddress + ":1234")
-		if err != nil {
-			log.Fatal("dialing:", err)
-		}
-
-	Then it can make a remote call:
-
-		// Synchronous call
-		args := &server.Args{7,8}
-		var reply int
-		err = client.Call("Arith.Multiply", args, &reply)
-		if err != nil {
-			log.Fatal("arith error:", err)
-		}
-		fmt.Printf("Arith: %d*%d=%d", args.A, args.B, reply)
-
-	or
-
-		// Asynchronous call
-		quotient := new(Quotient)
-		divCall := client.Go("Arith.Divide", args, quotient, nil)
-		replyCall := <-divCall.Done	// will be equal to divCall
-		// check errors, print, etc.
-
-	A server implementation will often provide a simple, type-safe wrapper for the
-	client.
-*/
-package rpc
-
-import (
-	"bufio"
-	"encoding/gob"
-	"errors"
-	"io"
-	"log"
-	"net"
-	"net/http"
-	"reflect"
-	"strings"
-	"sync"
-	"unicode"
-	"unicode/utf8"
-)
-
-const (
-	// Defaults used by HandleHTTP
-	DefaultRPCPath   = "/_goRPC_"
-	DefaultDebugPath = "/debug/rpc"
-)
-
-// Precompute the reflect type for error.  Can't use error directly
-// because Typeof takes an empty interface value.  This is annoying.
-var typeOfError = reflect.TypeOf((*error)(nil)).Elem()
-
-type methodType struct {
-	sync.Mutex // protects counters
-	method     reflect.Method
-	ArgType    reflect.Type
-	ReplyType  reflect.Type
-	numCalls   uint
-}
-
-type service struct {
-	name   string                 // name of service
-	rcvr   reflect.Value          // receiver of methods for the service
-	typ    reflect.Type           // type of the receiver
-	method map[string]*methodType // registered methods
-}
-
-// Request is a header written before every RPC call.  It is used internally
-// but documented here as an aid to debugging, such as when analyzing
-// network traffic.
-type Request struct {
-	ServiceMethod string   // format: "Service.Method"
-	Seq           uint64   // sequence number chosen by client
-	next          *Request // for free list in Server
-}
-
-// Response is a header written before every RPC return.  It is used internally
-// but documented here as an aid to debugging, such as when analyzing
-// network traffic.
-type Response struct {
-	ServiceMethod string    // echoes that of the Request
-	Seq           uint64    // echoes that of the request
-	Error         string    // error, if any.
-	next          *Response // for free list in Server
-}
-
-// Server represents an RPC Server.
-type Server struct {
-	mu         sync.RWMutex // protects the serviceMap
-	serviceMap map[string]*service
-	reqLock    sync.Mutex // protects freeReq
-	freeReq    *Request
-	respLock   sync.Mutex // protects freeResp
-	freeResp   *Response
-}
-
-// NewServer returns a new Server.
-func NewServer() *Server {
-	return &Server{serviceMap: make(map[string]*service)}
-}
-
-// DefaultServer is the default instance of *Server.
-var DefaultServer = NewServer()
-
-// Is this an exported - upper case - name?
-func isExported(name string) bool {
-	rune, _ := utf8.DecodeRuneInString(name)
-	return unicode.IsUpper(rune)
-}
-
-// Is this type exported or a builtin?
-func isExportedOrBuiltinType(t reflect.Type) bool {
-	for t.Kind() == reflect.Ptr {
-		t = t.Elem()
-	}
-	// PkgPath will be non-empty even for an exported type,
-	// so we need to check the type name as well.
-	return isExported(t.Name()) || t.PkgPath() == ""
-}
-
-// Register publishes in the server the set of methods of the
-// receiver value that satisfy the following conditions:
-//	- exported method
-//	- two arguments, both of exported type
-//	- the second argument is a pointer
-//	- one return value, of type error
-// It returns an error if the receiver is not an exported type or has
-// no suitable methods. It also logs the error using package log.
-// The client accesses each method using a string of the form "Type.Method",
-// where Type is the receiver's concrete type.
-func (server *Server) Register(rcvr interface{}) error {
-	return server.register(rcvr, "", false)
-}
-
-// RegisterName is like Register but uses the provided name for the type
-// instead of the receiver's concrete type.
-func (server *Server) RegisterName(name string, rcvr interface{}) error {
-	return server.register(rcvr, name, true)
-}
-
-func (server *Server) register(rcvr interface{}, name string, useName bool) error {
-	server.mu.Lock()
-	defer server.mu.Unlock()
-	if server.serviceMap == nil {
-		server.serviceMap = make(map[string]*service)
-	}
-	s := new(service)
-	s.typ = reflect.TypeOf(rcvr)
-	s.rcvr = reflect.ValueOf(rcvr)
-	sname := reflect.Indirect(s.rcvr).Type().Name()
-	if useName {
-		sname = name
-	}
-	if sname == "" {
-		s := "rpc.Register: no service name for type " + s.typ.String()
-		log.Print(s)
-		return errors.New(s)
-	}
-	if !isExported(sname) && !useName {
-		s := "rpc.Register: type " + sname + " is not exported"
-		log.Print(s)
-		return errors.New(s)
-	}
-	if _, present := server.serviceMap[sname]; present {
-		return errors.New("rpc: service already defined: " + sname)
-	}
-	s.name = sname
-
-	// Install the methods
-	s.method = suitableMethods(s.typ, true)
-
-	if len(s.method) == 0 {
-		str := ""
-
-		// To help the user, see if a pointer receiver would work.
-		method := suitableMethods(reflect.PtrTo(s.typ), false)
-		if len(method) != 0 {
-			str = "rpc.Register: type " + sname + " has no exported methods of suitable type (hint: pass a pointer to value of that type)"
-		} else {
-			str = "rpc.Register: type " + sname + " has no exported methods of suitable type"
-		}
-		log.Print(str)
-		return errors.New(str)
-	}
-	server.serviceMap[s.name] = s
-	return nil
-}
-
-// suitableMethods returns suitable Rpc methods of typ, it will report
-// error using log if reportErr is true.
-func suitableMethods(typ reflect.Type, reportErr bool) map[string]*methodType {
-	methods := make(map[string]*methodType)
-	for m := 0; m < typ.NumMethod(); m++ {
-		method := typ.Method(m)
-		mtype := method.Type
-		mname := method.Name
-		// Method must be exported.
-		if method.PkgPath != "" {
-			continue
-		}
-		// Method needs three ins: receiver, *args, *reply.
-		if mtype.NumIn() != 3 {
-			if reportErr {
-				log.Println("method", mname, "has wrong number of ins:", mtype.NumIn())
-			}
-			continue
-		}
-		// First arg need not be a pointer.
-		argType := mtype.In(1)
-		if !isExportedOrBuiltinType(argType) {
-			if reportErr {
-				log.Println(mname, "argument type not exported:", argType)
-			}
-			continue
-		}
-		// Second arg must be a pointer.
-		replyType := mtype.In(2)
-		if replyType.Kind() != reflect.Ptr {
-			if reportErr {
-				log.Println("method", mname, "reply type not a pointer:", replyType)
-			}
-			continue
-		}
-		// Reply type must be exported.
-		if !isExportedOrBuiltinType(replyType) {
-			if reportErr {
-				log.Println("method", mname, "reply type not exported:", replyType)
-			}
-			continue
-		}
-		// Method needs one out.
-		if mtype.NumOut() != 1 {
-			if reportErr {
-				log.Println("method", mname, "has wrong number of outs:", mtype.NumOut())
-			}
-			continue
-		}
-		// The return type of the method must be error.
-		if returnType := mtype.Out(0); returnType != typeOfError {
-			if reportErr {
-				log.Println("method", mname, "returns", returnType.String(), "not error")
-			}
-			continue
-		}
-		methods[mname] = &methodType{method: method, ArgType: argType, ReplyType: replyType}
-	}
-	return methods
-}
-
-// A value sent as a placeholder for the server's response value when the server
-// receives an invalid request. It is never decoded by the client since the Response
-// contains an error when it is used.
-var invalidRequest = struct{}{}
-
-func (server *Server) sendResponse(sending *sync.Mutex, req *Request, reply interface{}, codec ServerCodec, errmsg string) {
-	resp := server.getResponse()
-	// Encode the response header
-	resp.ServiceMethod = req.ServiceMethod
-	if errmsg != "" {
-		resp.Error = errmsg
-		reply = invalidRequest
-	}
-	resp.Seq = req.Seq
-	sending.Lock()
-	err := codec.WriteResponse(resp, reply)
-	if debugLog && err != nil {
-		log.Println("rpc: writing response:", err)
-	}
-	sending.Unlock()
-	server.freeResponse(resp)
-}
-
-func (m *methodType) NumCalls() (n uint) {
-	m.Lock()
-	n = m.numCalls
-	m.Unlock()
-	return n
-}
-
-func (s *service) call(server *Server, sending *sync.Mutex, mtype *methodType, req *Request, argv, replyv reflect.Value, codec ServerCodec) {
-	mtype.Lock()
-	mtype.numCalls++
-	mtype.Unlock()
-	function := mtype.method.Func
-	// Invoke the method, providing a new value for the reply.
-	returnValues := function.Call([]reflect.Value{s.rcvr, argv, replyv})
-	// The return value for the method is an error.
-	errInter := returnValues[0].Interface()
-	errmsg := ""
-	if errInter != nil {
-		errmsg = errInter.(error).Error()
-	}
-	server.sendResponse(sending, req, replyv.Interface(), codec, errmsg)
-	server.freeRequest(req)
-}
-
-type gobServerCodec struct {
-	rwc    io.ReadWriteCloser
-	dec    *gob.Decoder
-	enc    *gob.Encoder
-	encBuf *bufio.Writer
-}
-
-func (c *gobServerCodec) ReadRequestHeader(r *Request) error {
-	return c.dec.Decode(r)
-}
-
-func (c *gobServerCodec) ReadRequestBody(body interface{}) error {
-	return c.dec.Decode(body)
-}
-
-func (c *gobServerCodec) WriteResponse(r *Response, body interface{}) (err error) {
-	if err = c.enc.Encode(r); err != nil {
-		return
-	}
-	if err = c.enc.Encode(body); err != nil {
-		return
-	}
-	return c.encBuf.Flush()
-}
-
-func (c *gobServerCodec) Close() error {
-	return c.rwc.Close()
-}
-
-// ServeConn runs the server on a single connection.
-// ServeConn blocks, serving the connection until the client hangs up.
-// The caller typically invokes ServeConn in a go statement.
-// ServeConn uses the gob wire format (see package gob) on the
-// connection.  To use an alternate codec, use ServeCodec.
-func (server *Server) ServeConn(conn io.ReadWriteCloser) {
-	buf := bufio.NewWriter(conn)
-	srv := &gobServerCodec{conn, gob.NewDecoder(conn), gob.NewEncoder(buf), buf}
-	server.ServeCodec(srv)
-}
-
-// ServeCodec is like ServeConn but uses the specified codec to
-// decode requests and encode responses.
-func (server *Server) ServeCodec(codec ServerCodec) {
-	sending := new(sync.Mutex)
-	for {
-		service, mtype, req, argv, replyv, keepReading, err := server.readRequest(codec)
-		if err != nil {
-			if debugLog && err != io.EOF {
-				log.Println("rpc:", err)
-			}
-			if !keepReading {
-				break
-			}
-			// send a response if we actually managed to read a header.
-			if req != nil {
-				server.sendResponse(sending, req, invalidRequest, codec, err.Error())
-				server.freeRequest(req)
-			}
-			continue
-		}
-		go service.call(server, sending, mtype, req, argv, replyv, codec)
-	}
-	codec.Close()
-}
-
-// ServeRequest is like ServeCodec but synchronously serves a single request.
-// It does not close the codec upon completion.
-func (server *Server) ServeRequest(codec ServerCodec) error {
-	sending := new(sync.Mutex)
-	service, mtype, req, argv, replyv, keepReading, err := server.readRequest(codec)
-	if err != nil {
-		if !keepReading {
-			return err
-		}
-		// send a response if we actually managed to read a header.
-		if req != nil {
-			server.sendResponse(sending, req, invalidRequest, codec, err.Error())
-			server.freeRequest(req)
-		}
-		return err
-	}
-	service.call(server, sending, mtype, req, argv, replyv, codec)
-	return nil
-}
-
-func (server *Server) getRequest() *Request {
-	server.reqLock.Lock()
-	req := server.freeReq
-	if req == nil {
-		req = new(Request)
-	} else {
-		server.freeReq = req.next
-		*req = Request{}
-	}
-	server.reqLock.Unlock()
-	return req
-}
-
-func (server *Server) freeRequest(req *Request) {
-	server.reqLock.Lock()
-	req.next = server.freeReq
-	server.freeReq = req
-	server.reqLock.Unlock()
-}
-
-func (server *Server) getResponse() *Response {
-	server.respLock.Lock()
-	resp := server.freeResp
-	if resp == nil {
-		resp = new(Response)
-	} else {
-		server.freeResp = resp.next
-		*resp = Response{}
-	}
-	server.respLock.Unlock()
-	return resp
-}
-
-func (server *Server) freeResponse(resp *Response) {
-	server.respLock.Lock()
-	resp.next = server.freeResp
-	server.freeResp = resp
-	server.respLock.Unlock()
-}
-
-func (server *Server) readRequest(codec ServerCodec) (service *service, mtype *methodType, req *Request, argv, replyv reflect.Value, keepReading bool, err error) {
-	service, mtype, req, keepReading, err = server.readRequestHeader(codec)
-	if err != nil {
-		if !keepReading {
-			return
-		}
-		// discard body
-		codec.ReadRequestBody(nil)
-		return
-	}
-
-	// Decode the argument value.
-	argIsValue := false // if true, need to indirect before calling.
-	if mtype.ArgType.Kind() == reflect.Ptr {
-		argv = reflect.New(mtype.ArgType.Elem())
-	} else {
-		argv = reflect.New(mtype.ArgType)
-		argIsValue = true
-	}
-	// argv guaranteed to be a pointer now.
-	if err = codec.ReadRequestBody(argv.Interface()); err != nil {
-		return
-	}
-	if argIsValue {
-		argv = argv.Elem()
-	}
-
-	replyv = reflect.New(mtype.ReplyType.Elem())
-	return
-}
-
-func (server *Server) readRequestHeader(codec ServerCodec) (service *service, mtype *methodType, req *Request, keepReading bool, err error) {
-	// Grab the request header.
-	req = server.getRequest()
-	err = codec.ReadRequestHeader(req)
-	if err != nil {
-		req = nil
-		if err == io.EOF || err == io.ErrUnexpectedEOF {
-			return
-		}
-		err = errors.New("rpc: server cannot decode request: " + err.Error())
-		return
-	}
-
-	// We read the header successfully.  If we see an error now,
-	// we can still recover and move on to the next request.
-	keepReading = true
-
-	dot := strings.LastIndex(req.ServiceMethod, ".")
-	if dot < 0 {
-		err = errors.New("rpc: service/method request ill-formed: " + req.ServiceMethod)
-		return
-	}
-	serviceName := req.ServiceMethod[:dot]
-	methodName := req.ServiceMethod[dot+1:]
-
-	// Look up the request.
-	server.mu.RLock()
-	service = server.serviceMap[serviceName]
-	server.mu.RUnlock()
-	if service == nil {
-		err = errors.New("rpc: can't find service " + req.ServiceMethod)
-		return
-	}
-	mtype = service.method[methodName]
-	if mtype == nil {
-		err = errors.New("rpc: can't find method " + req.ServiceMethod)
-	}
-	return
-}
-
-// Accept accepts connections on the listener and serves requests
-// for each incoming connection.  Accept blocks; the caller typically
-// invokes it in a go statement.
-func (server *Server) Accept(lis net.Listener) {
-	for {
-		conn, err := lis.Accept()
-		if err != nil {
-			log.Fatal("rpc.Serve: accept:", err.Error()) // TODO(r): exit?
-		}
-		go server.ServeConn(conn)
-	}
-}
-
-// Register publishes the receiver's methods in the DefaultServer.
-func Register(rcvr interface{}) error { return DefaultServer.Register(rcvr) }
-
-// RegisterName is like Register but uses the provided name for the type
-// instead of the receiver's concrete type.
-func RegisterName(name string, rcvr interface{}) error {
-	return DefaultServer.RegisterName(name, rcvr)
-}
-
-// A ServerCodec implements reading of RPC requests and writing of
-// RPC responses for the server side of an RPC session.
-// The server calls ReadRequestHeader and ReadRequestBody in pairs
-// to read requests from the connection, and it calls WriteResponse to
-// write a response back.  The server calls Close when finished with the
-// connection. ReadRequestBody may be called with a nil
-// argument to force the body of the request to be read and discarded.
-type ServerCodec interface {
-	ReadRequestHeader(*Request) error
-	ReadRequestBody(interface{}) error
-	// WriteResponse must be safe for concurrent use by multiple goroutines.
-	WriteResponse(*Response, interface{}) error
-
-	Close() error
-}
-
-// ServeConn runs the DefaultServer on a single connection.
-// ServeConn blocks, serving the connection until the client hangs up.
-// The caller typically invokes ServeConn in a go statement.
-// ServeConn uses the gob wire format (see package gob) on the
-// connection.  To use an alternate codec, use ServeCodec.
-func ServeConn(conn io.ReadWriteCloser) {
-	DefaultServer.ServeConn(conn)
-}
-
-// ServeCodec is like ServeConn but uses the specified codec to
-// decode requests and encode responses.
-func ServeCodec(codec ServerCodec) {
-	DefaultServer.ServeCodec(codec)
-}
-
-// ServeRequest is like ServeCodec but synchronously serves a single request.
-// It does not close the codec upon completion.
-func ServeRequest(codec ServerCodec) error {
-	return DefaultServer.ServeRequest(codec)
-}
-
-// Accept accepts connections on the listener and serves requests
-// to DefaultServer for each incoming connection.
-// Accept blocks; the caller typically invokes it in a go statement.
-func Accept(lis net.Listener) { DefaultServer.Accept(lis) }
-
-// Can connect to RPC service using HTTP CONNECT to rpcPath.
-var connected = "200 Connected to Go RPC"
-
-// ServeHTTP implements an http.Handler that answers RPC requests.
-func (server *Server) ServeHTTP(w http.ResponseWriter, req *http.Request) {
-	if req.Method != "CONNECT" {
-		w.Header().Set("Content-Type", "text/plain; charset=utf-8")
-		w.WriteHeader(http.StatusMethodNotAllowed)
-		io.WriteString(w, "405 must CONNECT\n")
-		return
-	}
-	conn, _, err := w.(http.Hijacker).Hijack()
-	if err != nil {
-		log.Print("rpc hijacking ", req.RemoteAddr, ": ", err.Error())
-		return
-	}
-	io.WriteString(conn, "HTTP/1.0 "+connected+"\n\n")
-	server.ServeConn(conn)
-}
-
-// HandleHTTP registers an HTTP handler for RPC messages on rpcPath,
-// and a debugging handler on debugPath.
-// It is still necessary to invoke http.Serve(), typically in a go statement.
-func (server *Server) HandleHTTP(rpcPath, debugPath string) {
-	http.Handle(rpcPath, server)
-	http.Handle(debugPath, debugHTTP{server})
-}
-
-// HandleHTTP registers an HTTP handler for RPC messages to DefaultServer
-// on DefaultRPCPath and a debugging handler on DefaultDebugPath.
-// It is still necessary to invoke http.Serve(), typically in a go statement.
-func HandleHTTP() {
-	DefaultServer.HandleHTTP(DefaultRPCPath, DefaultDebugPath)
-}
diff --git a/src/pkg/net/singleflight.go b/src/pkg/net/singleflight.go
deleted file mode 100644
index dc58aff..0000000
--- a/src/pkg/net/singleflight.go
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2013 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package net
-
-import "sync"
-
-// call is an in-flight or completed singleflight.Do call
-type call struct {
-	wg   sync.WaitGroup
-	val  interface{}
-	err  error
-	dups int
-}
-
-// singleflight represents a class of work and forms a namespace in
-// which units of work can be executed with duplicate suppression.
-type singleflight struct {
-	mu sync.Mutex       // protects m
-	m  map[string]*call // lazily initialized
-}
-
-// Do executes and returns the results of the given function, making
-// sure that only one execution is in-flight for a given key at a
-// time. If a duplicate comes in, the duplicate caller waits for the
-// original to complete and receives the same results.
-// The return value shared indicates whether v was given to multiple callers.
-func (g *singleflight) Do(key string, fn func() (interface{}, error)) (v interface{}, err error, shared bool) {
-	g.mu.Lock()
-	if g.m == nil {
-		g.m = make(map[string]*call)
-	}
-	if c, ok := g.m[key]; ok {
-		c.dups++
-		g.mu.Unlock()
-		c.wg.Wait()
-		return c.val, c.err, true
-	}
-	c := new(call)
-	c.wg.Add(1)
-	g.m[key] = c
-	g.mu.Unlock()
-
-	c.val, c.err = fn()
-	c.wg.Done()
-
-	g.mu.Lock()
-	delete(g.m, key)
-	g.mu.Unlock()
-
-	return c.val, c.err, c.dups > 0
-}
diff --git a/src/pkg/net/smtp/smtp_test.go b/src/pkg/net/smtp/smtp_test.go
deleted file mode 100644
index 3fba1ea..0000000
--- a/src/pkg/net/smtp/smtp_test.go
+++ /dev/null
@@ -1,694 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package smtp
-
-import (
-	"bufio"
-	"bytes"
-	"crypto/tls"
-	"crypto/x509"
-	"io"
-	"net"
-	"net/textproto"
-	"strings"
-	"testing"
-	"time"
-)
-
-type authTest struct {
-	auth       Auth
-	challenges []string
-	name       string
-	responses  []string
-}
-
-var authTests = []authTest{
-	{PlainAuth("", "user", "pass", "testserver"), []string{}, "PLAIN", []string{"\x00user\x00pass"}},
-	{PlainAuth("foo", "bar", "baz", "testserver"), []string{}, "PLAIN", []string{"foo\x00bar\x00baz"}},
-	{CRAMMD5Auth("user", "pass"), []string{"<123456.1322876914 at testserver>"}, "CRAM-MD5", []string{"", "user 287eb355114cf5c471c26a875f1ca4ae"}},
-}
-
-func TestAuth(t *testing.T) {
-testLoop:
-	for i, test := range authTests {
-		name, resp, err := test.auth.Start(&ServerInfo{"testserver", true, nil})
-		if name != test.name {
-			t.Errorf("#%d got name %s, expected %s", i, name, test.name)
-		}
-		if !bytes.Equal(resp, []byte(test.responses[0])) {
-			t.Errorf("#%d got response %s, expected %s", i, resp, test.responses[0])
-		}
-		if err != nil {
-			t.Errorf("#%d error: %s", i, err)
-		}
-		for j := range test.challenges {
-			challenge := []byte(test.challenges[j])
-			expected := []byte(test.responses[j+1])
-			resp, err := test.auth.Next(challenge, true)
-			if err != nil {
-				t.Errorf("#%d error: %s", i, err)
-				continue testLoop
-			}
-			if !bytes.Equal(resp, expected) {
-				t.Errorf("#%d got %s, expected %s", i, resp, expected)
-				continue testLoop
-			}
-		}
-	}
-}
-
-func TestAuthPlain(t *testing.T) {
-	auth := PlainAuth("foo", "bar", "baz", "servername")
-
-	tests := []struct {
-		server *ServerInfo
-		err    string
-	}{
-		{
-			server: &ServerInfo{Name: "servername", TLS: true},
-		},
-		{
-			// Okay; explicitly advertised by server.
-			server: &ServerInfo{Name: "servername", Auth: []string{"PLAIN"}},
-		},
-		{
-			server: &ServerInfo{Name: "servername", Auth: []string{"CRAM-MD5"}},
-			err:    "unencrypted connection",
-		},
-		{
-			server: &ServerInfo{Name: "attacker", TLS: true},
-			err:    "wrong host name",
-		},
-	}
-	for i, tt := range tests {
-		_, _, err := auth.Start(tt.server)
-		got := ""
-		if err != nil {
-			got = err.Error()
-		}
-		if got != tt.err {
-			t.Errorf("%d. got error = %q; want %q", i, got, tt.err)
-		}
-	}
-}
-
-type faker struct {
-	io.ReadWriter
-}
-
-func (f faker) Close() error                     { return nil }
-func (f faker) LocalAddr() net.Addr              { return nil }
-func (f faker) RemoteAddr() net.Addr             { return nil }
-func (f faker) SetDeadline(time.Time) error      { return nil }
-func (f faker) SetReadDeadline(time.Time) error  { return nil }
-func (f faker) SetWriteDeadline(time.Time) error { return nil }
-
-func TestBasic(t *testing.T) {
-	server := strings.Join(strings.Split(basicServer, "\n"), "\r\n")
-	client := strings.Join(strings.Split(basicClient, "\n"), "\r\n")
-
-	var cmdbuf bytes.Buffer
-	bcmdbuf := bufio.NewWriter(&cmdbuf)
-	var fake faker
-	fake.ReadWriter = bufio.NewReadWriter(bufio.NewReader(strings.NewReader(server)), bcmdbuf)
-	c := &Client{Text: textproto.NewConn(fake), localName: "localhost"}
-
-	if err := c.helo(); err != nil {
-		t.Fatalf("HELO failed: %s", err)
-	}
-	if err := c.ehlo(); err == nil {
-		t.Fatalf("Expected first EHLO to fail")
-	}
-	if err := c.ehlo(); err != nil {
-		t.Fatalf("Second EHLO failed: %s", err)
-	}
-
-	c.didHello = true
-	if ok, args := c.Extension("aUtH"); !ok || args != "LOGIN PLAIN" {
-		t.Fatalf("Expected AUTH supported")
-	}
-	if ok, _ := c.Extension("DSN"); ok {
-		t.Fatalf("Shouldn't support DSN")
-	}
-
-	if err := c.Mail("user at gmail.com"); err == nil {
-		t.Fatalf("MAIL should require authentication")
-	}
-
-	if err := c.Verify("user1 at gmail.com"); err == nil {
-		t.Fatalf("First VRFY: expected no verification")
-	}
-	if err := c.Verify("user2 at gmail.com"); err != nil {
-		t.Fatalf("Second VRFY: expected verification, got %s", err)
-	}
-
-	// fake TLS so authentication won't complain
-	c.tls = true
-	c.serverName = "smtp.google.com"
-	if err := c.Auth(PlainAuth("", "user", "pass", "smtp.google.com")); err != nil {
-		t.Fatalf("AUTH failed: %s", err)
-	}
-
-	if err := c.Mail("user at gmail.com"); err != nil {
-		t.Fatalf("MAIL failed: %s", err)
-	}
-	if err := c.Rcpt("golang-nuts at googlegroups.com"); err != nil {
-		t.Fatalf("RCPT failed: %s", err)
-	}
-	msg := `From: user at gmail.com
-To: golang-nuts at googlegroups.com
-Subject: Hooray for Go
-
-Line 1
-.Leading dot line .
-Goodbye.`
-	w, err := c.Data()
-	if err != nil {
-		t.Fatalf("DATA failed: %s", err)
-	}
-	if _, err := w.Write([]byte(msg)); err != nil {
-		t.Fatalf("Data write failed: %s", err)
-	}
-	if err := w.Close(); err != nil {
-		t.Fatalf("Bad data response: %s", err)
-	}
-
-	if err := c.Quit(); err != nil {
-		t.Fatalf("QUIT failed: %s", err)
-	}
-
-	bcmdbuf.Flush()
-	actualcmds := cmdbuf.String()
-	if client != actualcmds {
-		t.Fatalf("Got:\n%s\nExpected:\n%s", actualcmds, client)
-	}
-}
-
-var basicServer = `250 mx.google.com at your service
-502 Unrecognized command.
-250-mx.google.com at your service
-250-SIZE 35651584
-250-AUTH LOGIN PLAIN
-250 8BITMIME
-530 Authentication required
-252 Send some mail, I'll try my best
-250 User is valid
-235 Accepted
-250 Sender OK
-250 Receiver OK
-354 Go ahead
-250 Data OK
-221 OK
-`
-
-var basicClient = `HELO localhost
-EHLO localhost
-EHLO localhost
-MAIL FROM:<user at gmail.com> BODY=8BITMIME
-VRFY user1 at gmail.com
-VRFY user2 at gmail.com
-AUTH PLAIN AHVzZXIAcGFzcw==
-MAIL FROM:<user at gmail.com> BODY=8BITMIME
-RCPT TO:<golang-nuts at googlegroups.com>
-DATA
-From: user at gmail.com
-To: golang-nuts at googlegroups.com
-Subject: Hooray for Go
-
-Line 1
-..Leading dot line .
-Goodbye.
-.
-QUIT
-`
-
-func TestNewClient(t *testing.T) {
-	server := strings.Join(strings.Split(newClientServer, "\n"), "\r\n")
-	client := strings.Join(strings.Split(newClientClient, "\n"), "\r\n")
-
-	var cmdbuf bytes.Buffer
-	bcmdbuf := bufio.NewWriter(&cmdbuf)
-	out := func() string {
-		bcmdbuf.Flush()
-		return cmdbuf.String()
-	}
-	var fake faker
-	fake.ReadWriter = bufio.NewReadWriter(bufio.NewReader(strings.NewReader(server)), bcmdbuf)
-	c, err := NewClient(fake, "fake.host")
-	if err != nil {
-		t.Fatalf("NewClient: %v\n(after %v)", err, out())
-	}
-	defer c.Close()
-	if ok, args := c.Extension("aUtH"); !ok || args != "LOGIN PLAIN" {
-		t.Fatalf("Expected AUTH supported")
-	}
-	if ok, _ := c.Extension("DSN"); ok {
-		t.Fatalf("Shouldn't support DSN")
-	}
-	if err := c.Quit(); err != nil {
-		t.Fatalf("QUIT failed: %s", err)
-	}
-
-	actualcmds := out()
-	if client != actualcmds {
-		t.Fatalf("Got:\n%s\nExpected:\n%s", actualcmds, client)
-	}
-}
-
-var newClientServer = `220 hello world
-250-mx.google.com at your service
-250-SIZE 35651584
-250-AUTH LOGIN PLAIN
-250 8BITMIME
-221 OK
-`
-
-var newClientClient = `EHLO localhost
-QUIT
-`
-
-func TestNewClient2(t *testing.T) {
-	server := strings.Join(strings.Split(newClient2Server, "\n"), "\r\n")
-	client := strings.Join(strings.Split(newClient2Client, "\n"), "\r\n")
-
-	var cmdbuf bytes.Buffer
-	bcmdbuf := bufio.NewWriter(&cmdbuf)
-	var fake faker
-	fake.ReadWriter = bufio.NewReadWriter(bufio.NewReader(strings.NewReader(server)), bcmdbuf)
-	c, err := NewClient(fake, "fake.host")
-	if err != nil {
-		t.Fatalf("NewClient: %v", err)
-	}
-	defer c.Close()
-	if ok, _ := c.Extension("DSN"); ok {
-		t.Fatalf("Shouldn't support DSN")
-	}
-	if err := c.Quit(); err != nil {
-		t.Fatalf("QUIT failed: %s", err)
-	}
-
-	bcmdbuf.Flush()
-	actualcmds := cmdbuf.String()
-	if client != actualcmds {
-		t.Fatalf("Got:\n%s\nExpected:\n%s", actualcmds, client)
-	}
-}
-
-var newClient2Server = `220 hello world
-502 EH?
-250-mx.google.com at your service
-250-SIZE 35651584
-250-AUTH LOGIN PLAIN
-250 8BITMIME
-221 OK
-`
-
-var newClient2Client = `EHLO localhost
-HELO localhost
-QUIT
-`
-
-func TestHello(t *testing.T) {
-
-	if len(helloServer) != len(helloClient) {
-		t.Fatalf("Hello server and client size mismatch")
-	}
-
-	for i := 0; i < len(helloServer); i++ {
-		server := strings.Join(strings.Split(baseHelloServer+helloServer[i], "\n"), "\r\n")
-		client := strings.Join(strings.Split(baseHelloClient+helloClient[i], "\n"), "\r\n")
-		var cmdbuf bytes.Buffer
-		bcmdbuf := bufio.NewWriter(&cmdbuf)
-		var fake faker
-		fake.ReadWriter = bufio.NewReadWriter(bufio.NewReader(strings.NewReader(server)), bcmdbuf)
-		c, err := NewClient(fake, "fake.host")
-		if err != nil {
-			t.Fatalf("NewClient: %v", err)
-		}
-		defer c.Close()
-		c.localName = "customhost"
-		err = nil
-
-		switch i {
-		case 0:
-			err = c.Hello("customhost")
-		case 1:
-			err = c.StartTLS(nil)
-			if err.Error() == "502 Not implemented" {
-				err = nil
-			}
-		case 2:
-			err = c.Verify("test at example.com")
-		case 3:
-			c.tls = true
-			c.serverName = "smtp.google.com"
-			err = c.Auth(PlainAuth("", "user", "pass", "smtp.google.com"))
-		case 4:
-			err = c.Mail("test at example.com")
-		case 5:
-			ok, _ := c.Extension("feature")
-			if ok {
-				t.Errorf("Expected FEATURE not to be supported")
-			}
-		case 6:
-			err = c.Reset()
-		case 7:
-			err = c.Quit()
-		case 8:
-			err = c.Verify("test at example.com")
-			if err != nil {
-				err = c.Hello("customhost")
-				if err != nil {
-					t.Errorf("Want error, got none")
-				}
-			}
-		default:
-			t.Fatalf("Unhandled command")
-		}
-
-		if err != nil {
-			t.Errorf("Command %d failed: %v", i, err)
-		}
-
-		bcmdbuf.Flush()
-		actualcmds := cmdbuf.String()
-		if client != actualcmds {
-			t.Errorf("Got:\n%s\nExpected:\n%s", actualcmds, client)
-		}
-	}
-}
-
-var baseHelloServer = `220 hello world
-502 EH?
-250-mx.google.com at your service
-250 FEATURE
-`
-
-var helloServer = []string{
-	"",
-	"502 Not implemented\n",
-	"250 User is valid\n",
-	"235 Accepted\n",
-	"250 Sender ok\n",
-	"",
-	"250 Reset ok\n",
-	"221 Goodbye\n",
-	"250 Sender ok\n",
-}
-
-var baseHelloClient = `EHLO customhost
-HELO customhost
-`
-
-var helloClient = []string{
-	"",
-	"STARTTLS\n",
-	"VRFY test at example.com\n",
-	"AUTH PLAIN AHVzZXIAcGFzcw==\n",
-	"MAIL FROM:<test at example.com>\n",
-	"",
-	"RSET\n",
-	"QUIT\n",
-	"VRFY test at example.com\n",
-}
-
-func TestSendMail(t *testing.T) {
-	server := strings.Join(strings.Split(sendMailServer, "\n"), "\r\n")
-	client := strings.Join(strings.Split(sendMailClient, "\n"), "\r\n")
-	var cmdbuf bytes.Buffer
-	bcmdbuf := bufio.NewWriter(&cmdbuf)
-	l, err := net.Listen("tcp", "127.0.0.1:0")
-	if err != nil {
-		t.Fatalf("Unable to to create listener: %v", err)
-	}
-	defer l.Close()
-
-	// prevent data race on bcmdbuf
-	var done = make(chan struct{})
-	go func(data []string) {
-
-		defer close(done)
-
-		conn, err := l.Accept()
-		if err != nil {
-			t.Errorf("Accept error: %v", err)
-			return
-		}
-		defer conn.Close()
-
-		tc := textproto.NewConn(conn)
-		for i := 0; i < len(data) && data[i] != ""; i++ {
-			tc.PrintfLine(data[i])
-			for len(data[i]) >= 4 && data[i][3] == '-' {
-				i++
-				tc.PrintfLine(data[i])
-			}
-			if data[i] == "221 Goodbye" {
-				return
-			}
-			read := false
-			for !read || data[i] == "354 Go ahead" {
-				msg, err := tc.ReadLine()
-				bcmdbuf.Write([]byte(msg + "\r\n"))
-				read = true
-				if err != nil {
-					t.Errorf("Read error: %v", err)
-					return
-				}
-				if data[i] == "354 Go ahead" && msg == "." {
-					break
-				}
-			}
-		}
-	}(strings.Split(server, "\r\n"))
-
-	err = SendMail(l.Addr().String(), nil, "test at example.com", []string{"other at example.com"}, []byte(strings.Replace(`From: test at example.com
-To: other at example.com
-Subject: SendMail test
-
-SendMail is working for me.
-`, "\n", "\r\n", -1)))
-
-	if err != nil {
-		t.Errorf("%v", err)
-	}
-
-	<-done
-	bcmdbuf.Flush()
-	actualcmds := cmdbuf.String()
-	if client != actualcmds {
-		t.Errorf("Got:\n%s\nExpected:\n%s", actualcmds, client)
-	}
-}
-
-var sendMailServer = `220 hello world
-502 EH?
-250 mx.google.com at your service
-250 Sender ok
-250 Receiver ok
-354 Go ahead
-250 Data ok
-221 Goodbye
-`
-
-var sendMailClient = `EHLO localhost
-HELO localhost
-MAIL FROM:<test at example.com>
-RCPT TO:<other at example.com>
-DATA
-From: test at example.com
-To: other at example.com
-Subject: SendMail test
-
-SendMail is working for me.
-.
-QUIT
-`
-
-func TestAuthFailed(t *testing.T) {
-	server := strings.Join(strings.Split(authFailedServer, "\n"), "\r\n")
-	client := strings.Join(strings.Split(authFailedClient, "\n"), "\r\n")
-	var cmdbuf bytes.Buffer
-	bcmdbuf := bufio.NewWriter(&cmdbuf)
-	var fake faker
-	fake.ReadWriter = bufio.NewReadWriter(bufio.NewReader(strings.NewReader(server)), bcmdbuf)
-	c, err := NewClient(fake, "fake.host")
-	if err != nil {
-		t.Fatalf("NewClient: %v", err)
-	}
-	defer c.Close()
-
-	c.tls = true
-	c.serverName = "smtp.google.com"
-	err = c.Auth(PlainAuth("", "user", "pass", "smtp.google.com"))
-
-	if err == nil {
-		t.Error("Auth: expected error; got none")
-	} else if err.Error() != "535 Invalid credentials\nplease see www.example.com" {
-		t.Errorf("Auth: got error: %v, want: %s", err, "535 Invalid credentials\nplease see www.example.com")
-	}
-
-	bcmdbuf.Flush()
-	actualcmds := cmdbuf.String()
-	if client != actualcmds {
-		t.Errorf("Got:\n%s\nExpected:\n%s", actualcmds, client)
-	}
-}
-
-var authFailedServer = `220 hello world
-250-mx.google.com at your service
-250 AUTH LOGIN PLAIN
-535-Invalid credentials
-535 please see www.example.com
-221 Goodbye
-`
-
-var authFailedClient = `EHLO localhost
-AUTH PLAIN AHVzZXIAcGFzcw==
-*
-QUIT
-`
-
-func TestTLSClient(t *testing.T) {
-	ln := newLocalListener(t)
-	defer ln.Close()
-	errc := make(chan error)
-	go func() {
-		errc <- sendMail(ln.Addr().String())
-	}()
-	conn, err := ln.Accept()
-	if err != nil {
-		t.Fatalf("failed to accept connection: %v", err)
-	}
-	defer conn.Close()
-	if err := serverHandle(conn, t); err != nil {
-		t.Fatalf("failed to handle connection: %v", err)
-	}
-	if err := <-errc; err != nil {
-		t.Fatalf("client error: %v", err)
-	}
-}
-
-func newLocalListener(t *testing.T) net.Listener {
-	ln, err := net.Listen("tcp", "127.0.0.1:0")
-	if err != nil {
-		ln, err = net.Listen("tcp6", "[::1]:0")
-	}
-	if err != nil {
-		t.Fatal(err)
-	}
-	return ln
-}
-
-type smtpSender struct {
-	w io.Writer
-}
-
-func (s smtpSender) send(f string) {
-	s.w.Write([]byte(f + "\r\n"))
-}
-
-// smtp server, finely tailored to deal with our own client only!
-func serverHandle(c net.Conn, t *testing.T) error {
-	send := smtpSender{c}.send
-	send("220 127.0.0.1 ESMTP service ready")
-	s := bufio.NewScanner(c)
-	for s.Scan() {
-		switch s.Text() {
-		case "EHLO localhost":
-			send("250-127.0.0.1 ESMTP offers a warm hug of welcome")
-			send("250-STARTTLS")
-			send("250 Ok")
-		case "STARTTLS":
-			send("220 Go ahead")
-			keypair, err := tls.X509KeyPair(localhostCert, localhostKey)
-			if err != nil {
-				return err
-			}
-			config := &tls.Config{Certificates: []tls.Certificate{keypair}}
-			c = tls.Server(c, config)
-			defer c.Close()
-			return serverHandleTLS(c, t)
-		default:
-			t.Fatalf("unrecognized command: %q", s.Text())
-		}
-	}
-	return s.Err()
-}
-
-func serverHandleTLS(c net.Conn, t *testing.T) error {
-	send := smtpSender{c}.send
-	s := bufio.NewScanner(c)
-	for s.Scan() {
-		switch s.Text() {
-		case "EHLO localhost":
-			send("250 Ok")
-		case "MAIL FROM:<joe1 at example.com>":
-			send("250 Ok")
-		case "RCPT TO:<joe2 at example.com>":
-			send("250 Ok")
-		case "DATA":
-			send("354 send the mail data, end with .")
-			send("250 Ok")
-		case "Subject: test":
-		case "":
-		case "howdy!":
-		case ".":
-		case "QUIT":
-			send("221 127.0.0.1 Service closing transmission channel")
-			return nil
-		default:
-			t.Fatalf("unrecognized command during TLS: %q", s.Text())
-		}
-	}
-	return s.Err()
-}
-
-func init() {
-	testRootCAs := x509.NewCertPool()
-	testRootCAs.AppendCertsFromPEM(localhostCert)
-	testHookStartTLS = func(config *tls.Config) {
-		config.RootCAs = testRootCAs
-	}
-}
-
-func sendMail(hostPort string) error {
-	host, _, err := net.SplitHostPort(hostPort)
-	if err != nil {
-		return err
-	}
-	auth := PlainAuth("", "", "", host)
-	from := "joe1 at example.com"
-	to := []string{"joe2 at example.com"}
-	return SendMail(hostPort, auth, from, to, []byte("Subject: test\n\nhowdy!"))
-}
-
-// (copied from net/http/httptest)
-// localhostCert is a PEM-encoded TLS cert with SAN IPs
-// "127.0.0.1" and "[::1]", expiring at the last second of 2049 (the end
-// of ASN.1 time).
-// generated from src/pkg/crypto/tls:
-// go run generate_cert.go  --rsa-bits 512 --host 127.0.0.1,::1,example.com --ca --start-date "Jan 1 00:00:00 1970" --duration=1000000h
-var localhostCert = []byte(`-----BEGIN CERTIFICATE-----
-MIIBdzCCASOgAwIBAgIBADALBgkqhkiG9w0BAQUwEjEQMA4GA1UEChMHQWNtZSBD
-bzAeFw03MDAxMDEwMDAwMDBaFw00OTEyMzEyMzU5NTlaMBIxEDAOBgNVBAoTB0Fj
-bWUgQ28wWjALBgkqhkiG9w0BAQEDSwAwSAJBAN55NcYKZeInyTuhcCwFMhDHCmwa
-IUSdtXdcbItRB/yfXGBhiex00IaLXQnSU+QZPRZWYqeTEbFSgihqi1PUDy8CAwEA
-AaNoMGYwDgYDVR0PAQH/BAQDAgCkMBMGA1UdJQQMMAoGCCsGAQUFBwMBMA8GA1Ud
-EwEB/wQFMAMBAf8wLgYDVR0RBCcwJYILZXhhbXBsZS5jb22HBH8AAAGHEAAAAAAA
-AAAAAAAAAAAAAAEwCwYJKoZIhvcNAQEFA0EAAoQn/ytgqpiLcZu9XKbCJsJcvkgk
-Se6AbGXgSlq+ZCEVo0qIwSgeBqmsJxUu7NCSOwVJLYNEBO2DtIxoYVk+MA==
------END CERTIFICATE-----`)
-
-// localhostKey is the private key for localhostCert.
-var localhostKey = []byte(`-----BEGIN RSA PRIVATE KEY-----
-MIIBPAIBAAJBAN55NcYKZeInyTuhcCwFMhDHCmwaIUSdtXdcbItRB/yfXGBhiex0
-0IaLXQnSU+QZPRZWYqeTEbFSgihqi1PUDy8CAwEAAQJBAQdUx66rfh8sYsgfdcvV
-NoafYpnEcB5s4m/vSVe6SU7dCK6eYec9f9wpT353ljhDUHq3EbmE4foNzJngh35d
-AekCIQDhRQG5Li0Wj8TM4obOnnXUXf1jRv0UkzE9AHWLG5q3AwIhAPzSjpYUDjVW
-MCUXgckTpKCuGwbJk7424Nb8bLzf3kllAiA5mUBgjfr/WtFSJdWcPQ4Zt9KTMNKD
-EUO0ukpTwEIl6wIhAMbGqZK3zAAFdq8DD2jPx+UJXnh0rnOkZBzDtJ6/iN69AiEA
-1Aq8MJgTaYsDQWyU/hDq5YkDJc9e9DSCvUIzqxQWMQE=
------END RSA PRIVATE KEY-----`)
diff --git a/src/pkg/net/sock_bsd.go b/src/pkg/net/sock_bsd.go
deleted file mode 100644
index 48fb785..0000000
--- a/src/pkg/net/sock_bsd.go
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2009 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build darwin dragonfly freebsd nacl netbsd openbsd
-
-package net
-
-import (
-	"runtime"
-	"syscall"
-)
-
-func maxListenerBacklog() int {
-	var (
-		n   uint32
-		err error
-	)
-	switch runtime.GOOS {
-	case "darwin", "freebsd":
-		n, err = syscall.SysctlUint32("kern.ipc.somaxconn")
-	case "netbsd":
-		// NOTE: NetBSD has no somaxconn-like kernel state so far
-	case "openbsd":
-		n, err = syscall.SysctlUint32("kern.somaxconn")
-	}
-	if n == 0 || err != nil {
-		return syscall.SOMAXCONN
-	}
-	// FreeBSD stores the backlog in a uint16, as does Linux.
-	// Assume the other BSDs do too. Truncate number to avoid wrapping.
-	// See issue 5030.
-	if n > 1<<16-1 {
-		n = 1<<16 - 1
-	}
-	return int(n)
-}
diff --git a/src/pkg/net/sock_posix.go b/src/pkg/net/sock_posix.go
deleted file mode 100644
index c80c7d6..0000000
--- a/src/pkg/net/sock_posix.go
+++ /dev/null
@@ -1,192 +0,0 @@
-// Copyright 2009 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris windows
-
-package net
-
-import (
-	"os"
-	"syscall"
-	"time"
-)
-
-// A sockaddr represents a TCP, UDP, IP or Unix network endpoint
-// address that can be converted into a syscall.Sockaddr.
-type sockaddr interface {
-	Addr
-
-	netaddr
-
-	// family returns the platform-dependent address family
-	// identifier.
-	family() int
-
-	// isWildcard reports whether the address is a wildcard
-	// address.
-	isWildcard() bool
-
-	// sockaddr returns the address converted into a syscall
-	// sockaddr type that implements syscall.Sockaddr
-	// interface. It returns a nil interface when the address is
-	// nil.
-	sockaddr(family int) (syscall.Sockaddr, error)
-}
-
-// socket returns a network file descriptor that is ready for
-// asynchronous I/O using the network poller.
-func socket(net string, family, sotype, proto int, ipv6only bool, laddr, raddr sockaddr, deadline time.Time, toAddr func(syscall.Sockaddr) Addr) (fd *netFD, err error) {
-	s, err := sysSocket(family, sotype, proto)
-	if err != nil {
-		return nil, err
-	}
-	if err = setDefaultSockopts(s, family, sotype, ipv6only); err != nil {
-		closesocket(s)
-		return nil, err
-	}
-	if fd, err = newFD(s, family, sotype, net); err != nil {
-		closesocket(s)
-		return nil, err
-	}
-
-	// This function makes a network file descriptor for the
-	// following applications:
-	//
-	// - An endpoint holder that opens a passive stream
-	//   connenction, known as a stream listener
-	//
-	// - An endpoint holder that opens a destination-unspecific
-	//   datagram connection, known as a datagram listener
-	//
-	// - An endpoint holder that opens an active stream or a
-	//   destination-specific datagram connection, known as a
-	//   dialer
-	//
-	// - An endpoint holder that opens the other connection, such
-	//   as talking to the protocol stack inside the kernel
-	//
-	// For stream and datagram listeners, they will only require
-	// named sockets, so we can assume that it's just a request
-	// from stream or datagram listeners when laddr is not nil but
-	// raddr is nil. Otherwise we assume it's just for dialers or
-	// the other connection holders.
-
-	if laddr != nil && raddr == nil {
-		switch sotype {
-		case syscall.SOCK_STREAM, syscall.SOCK_SEQPACKET:
-			if err := fd.listenStream(laddr, listenerBacklog, toAddr); err != nil {
-				fd.Close()
-				return nil, err
-			}
-			return fd, nil
-		case syscall.SOCK_DGRAM:
-			if err := fd.listenDatagram(laddr, toAddr); err != nil {
-				fd.Close()
-				return nil, err
-			}
-			return fd, nil
-		}
-	}
-	if err := fd.dial(laddr, raddr, deadline, toAddr); err != nil {
-		fd.Close()
-		return nil, err
-	}
-	return fd, nil
-}
-
-func (fd *netFD) dial(laddr, raddr sockaddr, deadline time.Time, toAddr func(syscall.Sockaddr) Addr) error {
-	var err error
-	var lsa syscall.Sockaddr
-	if laddr != nil {
-		if lsa, err = laddr.sockaddr(fd.family); err != nil {
-			return err
-		} else if lsa != nil {
-			if err := syscall.Bind(fd.sysfd, lsa); err != nil {
-				return os.NewSyscallError("bind", err)
-			}
-		}
-	}
-	var rsa syscall.Sockaddr
-	if raddr != nil {
-		if rsa, err = raddr.sockaddr(fd.family); err != nil {
-			return err
-		}
-		if err := fd.connect(lsa, rsa, deadline); err != nil {
-			return err
-		}
-		fd.isConnected = true
-	} else {
-		if err := fd.init(); err != nil {
-			return err
-		}
-	}
-	lsa, _ = syscall.Getsockname(fd.sysfd)
-	if rsa, _ = syscall.Getpeername(fd.sysfd); rsa != nil {
-		fd.setAddr(toAddr(lsa), toAddr(rsa))
-	} else {
-		fd.setAddr(toAddr(lsa), raddr)
-	}
-	return nil
-}
-
-func (fd *netFD) listenStream(laddr sockaddr, backlog int, toAddr func(syscall.Sockaddr) Addr) error {
-	if err := setDefaultListenerSockopts(fd.sysfd); err != nil {
-		return err
-	}
-	if lsa, err := laddr.sockaddr(fd.family); err != nil {
-		return err
-	} else if lsa != nil {
-		if err := syscall.Bind(fd.sysfd, lsa); err != nil {
-			return os.NewSyscallError("bind", err)
-		}
-	}
-	if err := syscall.Listen(fd.sysfd, backlog); err != nil {
-		return os.NewSyscallError("listen", err)
-	}
-	if err := fd.init(); err != nil {
-		return err
-	}
-	lsa, _ := syscall.Getsockname(fd.sysfd)
-	fd.setAddr(toAddr(lsa), nil)
-	return nil
-}
-
-func (fd *netFD) listenDatagram(laddr sockaddr, toAddr func(syscall.Sockaddr) Addr) error {
-	switch addr := laddr.(type) {
-	case *UDPAddr:
-		// We provide a socket that listens to a wildcard
-		// address with reusable UDP port when the given laddr
-		// is an appropriate UDP multicast address prefix.
-		// This makes it possible for a single UDP listener to
-		// join multiple different group addresses, for
-		// multiple UDP listeners that listen on the same UDP
-		// port to join the same group address.
-		if addr.IP != nil && addr.IP.IsMulticast() {
-			if err := setDefaultMulticastSockopts(fd.sysfd); err != nil {
-				return err
-			}
-			addr := *addr
-			switch fd.family {
-			case syscall.AF_INET:
-				addr.IP = IPv4zero
-			case syscall.AF_INET6:
-				addr.IP = IPv6unspecified
-			}
-			laddr = &addr
-		}
-	}
-	if lsa, err := laddr.sockaddr(fd.family); err != nil {
-		return err
-	} else if lsa != nil {
-		if err := syscall.Bind(fd.sysfd, lsa); err != nil {
-			return os.NewSyscallError("bind", err)
-		}
-	}
-	if err := fd.init(); err != nil {
-		return err
-	}
-	lsa, _ := syscall.Getsockname(fd.sysfd)
-	fd.setAddr(toAddr(lsa), nil)
-	return nil
-}
diff --git a/src/pkg/net/sock_solaris.go b/src/pkg/net/sock_solaris.go
deleted file mode 100644
index 90fe9de..0000000
--- a/src/pkg/net/sock_solaris.go
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2009 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package net
-
-import "syscall"
-
-func maxListenerBacklog() int {
-	// TODO: Implement this
-	// NOTE: Never return a number bigger than 1<<16 - 1. See issue 5030.
-	return syscall.SOMAXCONN
-}
diff --git a/src/pkg/net/sockopt_bsd.go b/src/pkg/net/sockopt_bsd.go
deleted file mode 100644
index 77d51d7..0000000
--- a/src/pkg/net/sockopt_bsd.go
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2011 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build darwin dragonfly freebsd nacl netbsd openbsd
-
-package net
-
-import (
-	"os"
-	"runtime"
-	"syscall"
-)
-
-func setDefaultSockopts(s, family, sotype int, ipv6only bool) error {
-	if runtime.GOOS == "dragonfly" && sotype != syscall.SOCK_RAW {
-		// On DragonFly BSD, we adjust the ephemeral port
-		// range because unlike other BSD systems its default
-		// port range doesn't conform to IANA recommendation
-		// as described in RFC 6355 and is pretty narrow.
-		switch family {
-		case syscall.AF_INET:
-			syscall.SetsockoptInt(s, syscall.IPPROTO_IP, syscall.IP_PORTRANGE, syscall.IP_PORTRANGE_HIGH)
-		case syscall.AF_INET6:
-			syscall.SetsockoptInt(s, syscall.IPPROTO_IPV6, syscall.IPV6_PORTRANGE, syscall.IPV6_PORTRANGE_HIGH)
-		}
-	}
-	if family == syscall.AF_INET6 && sotype != syscall.SOCK_RAW {
-		// Allow both IP versions even if the OS default
-		// is otherwise.  Note that some operating systems
-		// never admit this option.
-		syscall.SetsockoptInt(s, syscall.IPPROTO_IPV6, syscall.IPV6_V6ONLY, boolint(ipv6only))
-	}
-	// Allow broadcast.
-	return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_BROADCAST, 1))
-}
-
-func setDefaultListenerSockopts(s int) error {
-	// Allow reuse of recently-used addresses.
-	return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1))
-}
-
-func setDefaultMulticastSockopts(s int) error {
-	// Allow multicast UDP and raw IP datagram sockets to listen
-	// concurrently across multiple listeners.
-	if err := syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1); err != nil {
-		return os.NewSyscallError("setsockopt", err)
-	}
-	// Allow reuse of recently-used ports.
-	// This option is supported only in descendants of 4.4BSD,
-	// to make an effective multicast application that requires
-	// quick draw possible.
-	return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_REUSEPORT, 1))
-}
diff --git a/src/pkg/net/sockopt_posix.go b/src/pkg/net/sockopt_posix.go
deleted file mode 100644
index 921918c..0000000
--- a/src/pkg/net/sockopt_posix.go
+++ /dev/null
@@ -1,141 +0,0 @@
-// Copyright 2009 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris windows
-
-package net
-
-import (
-	"os"
-	"syscall"
-)
-
-// Boolean to int.
-func boolint(b bool) int {
-	if b {
-		return 1
-	}
-	return 0
-}
-
-func ipv4AddrToInterface(ip IP) (*Interface, error) {
-	ift, err := Interfaces()
-	if err != nil {
-		return nil, err
-	}
-	for _, ifi := range ift {
-		ifat, err := ifi.Addrs()
-		if err != nil {
-			return nil, err
-		}
-		for _, ifa := range ifat {
-			switch v := ifa.(type) {
-			case *IPAddr:
-				if ip.Equal(v.IP) {
-					return &ifi, nil
-				}
-			case *IPNet:
-				if ip.Equal(v.IP) {
-					return &ifi, nil
-				}
-			}
-		}
-	}
-	if ip.Equal(IPv4zero) {
-		return nil, nil
-	}
-	return nil, errNoSuchInterface
-}
-
-func interfaceToIPv4Addr(ifi *Interface) (IP, error) {
-	if ifi == nil {
-		return IPv4zero, nil
-	}
-	ifat, err := ifi.Addrs()
-	if err != nil {
-		return nil, err
-	}
-	for _, ifa := range ifat {
-		switch v := ifa.(type) {
-		case *IPAddr:
-			if v.IP.To4() != nil {
-				return v.IP, nil
-			}
-		case *IPNet:
-			if v.IP.To4() != nil {
-				return v.IP, nil
-			}
-		}
-	}
-	return nil, errNoSuchInterface
-}
-
-func setIPv4MreqToInterface(mreq *syscall.IPMreq, ifi *Interface) error {
-	if ifi == nil {
-		return nil
-	}
-	ifat, err := ifi.Addrs()
-	if err != nil {
-		return err
-	}
-	for _, ifa := range ifat {
-		switch v := ifa.(type) {
-		case *IPAddr:
-			if a := v.IP.To4(); a != nil {
-				copy(mreq.Interface[:], a)
-				goto done
-			}
-		case *IPNet:
-			if a := v.IP.To4(); a != nil {
-				copy(mreq.Interface[:], a)
-				goto done
-			}
-		}
-	}
-done:
-	if bytesEqual(mreq.Multiaddr[:], IPv4zero.To4()) {
-		return errNoSuchMulticastInterface
-	}
-	return nil
-}
-
-func setReadBuffer(fd *netFD, bytes int) error {
-	if err := fd.incref(); err != nil {
-		return err
-	}
-	defer fd.decref()
-	return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_RCVBUF, bytes))
-}
-
-func setWriteBuffer(fd *netFD, bytes int) error {
-	if err := fd.incref(); err != nil {
-		return err
-	}
-	defer fd.decref()
-	return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_SNDBUF, bytes))
-}
-
-func setKeepAlive(fd *netFD, keepalive bool) error {
-	if err := fd.incref(); err != nil {
-		return err
-	}
-	defer fd.decref()
-	return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_KEEPALIVE, boolint(keepalive)))
-}
-
-func setLinger(fd *netFD, sec int) error {
-	var l syscall.Linger
-	if sec >= 0 {
-		l.Onoff = 1
-		l.Linger = int32(sec)
-	} else {
-		l.Onoff = 0
-		l.Linger = 0
-	}
-	if err := fd.incref(); err != nil {
-		return err
-	}
-	defer fd.decref()
-	return os.NewSyscallError("setsockopt", syscall.SetsockoptLinger(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_LINGER, &l))
-}
diff --git a/src/pkg/net/sockoptip_bsd.go b/src/pkg/net/sockoptip_bsd.go
deleted file mode 100644
index 87132f0..0000000
--- a/src/pkg/net/sockoptip_bsd.go
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2011 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build darwin dragonfly freebsd nacl netbsd openbsd
-
-package net
-
-import (
-	"os"
-	"syscall"
-)
-
-func setIPv4MulticastInterface(fd *netFD, ifi *Interface) error {
-	ip, err := interfaceToIPv4Addr(ifi)
-	if err != nil {
-		return os.NewSyscallError("setsockopt", err)
-	}
-	var a [4]byte
-	copy(a[:], ip.To4())
-	if err := fd.incref(); err != nil {
-		return err
-	}
-	defer fd.decref()
-	return os.NewSyscallError("setsockopt", syscall.SetsockoptInet4Addr(fd.sysfd, syscall.IPPROTO_IP, syscall.IP_MULTICAST_IF, a))
-}
-
-func setIPv4MulticastLoopback(fd *netFD, v bool) error {
-	if err := fd.incref(); err != nil {
-		return err
-	}
-	defer fd.decref()
-	return os.NewSyscallError("setsockopt", syscall.SetsockoptByte(fd.sysfd, syscall.IPPROTO_IP, syscall.IP_MULTICAST_LOOP, byte(boolint(v))))
-}
diff --git a/src/pkg/net/sockoptip_posix.go b/src/pkg/net/sockoptip_posix.go
deleted file mode 100644
index b5c80e4..0000000
--- a/src/pkg/net/sockoptip_posix.go
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright 2011 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build darwin dragonfly freebsd linux nacl netbsd openbsd windows
-
-package net
-
-import (
-	"os"
-	"syscall"
-)
-
-func joinIPv4Group(fd *netFD, ifi *Interface, ip IP) error {
-	mreq := &syscall.IPMreq{Multiaddr: [4]byte{ip[0], ip[1], ip[2], ip[3]}}
-	if err := setIPv4MreqToInterface(mreq, ifi); err != nil {
-		return err
-	}
-	if err := fd.incref(); err != nil {
-		return err
-	}
-	defer fd.decref()
-	return os.NewSyscallError("setsockopt", syscall.SetsockoptIPMreq(fd.sysfd, syscall.IPPROTO_IP, syscall.IP_ADD_MEMBERSHIP, mreq))
-}
-
-func setIPv6MulticastInterface(fd *netFD, ifi *Interface) error {
-	var v int
-	if ifi != nil {
-		v = ifi.Index
-	}
-	if err := fd.incref(); err != nil {
-		return err
-	}
-	defer fd.decref()
-	return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd.sysfd, syscall.IPPROTO_IPV6, syscall.IPV6_MULTICAST_IF, v))
-}
-
-func setIPv6MulticastLoopback(fd *netFD, v bool) error {
-	if err := fd.incref(); err != nil {
-		return err
-	}
-	defer fd.decref()
-	return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd.sysfd, syscall.IPPROTO_IPV6, syscall.IPV6_MULTICAST_LOOP, boolint(v)))
-}
-
-func joinIPv6Group(fd *netFD, ifi *Interface, ip IP) error {
-	mreq := &syscall.IPv6Mreq{}
-	copy(mreq.Multiaddr[:], ip)
-	if ifi != nil {
-		mreq.Interface = uint32(ifi.Index)
-	}
-	if err := fd.incref(); err != nil {
-		return err
-	}
-	defer fd.decref()
-	return os.NewSyscallError("setsockopt", syscall.SetsockoptIPv6Mreq(fd.sysfd, syscall.IPPROTO_IPV6, syscall.IPV6_JOIN_GROUP, mreq))
-}
diff --git a/src/pkg/net/sockoptip_stub.go b/src/pkg/net/sockoptip_stub.go
deleted file mode 100644
index dcd3a22..0000000
--- a/src/pkg/net/sockoptip_stub.go
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2011 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build solaris
-
-package net
-
-import "syscall"
-
-func setIPv4MulticastInterface(fd *netFD, ifi *Interface) error {
-	// See golang.org/issue/7399.
-	return syscall.EINVAL
-}
-
-func setIPv4MulticastLoopback(fd *netFD, v bool) error {
-	// See golang.org/issue/7399.
-	return syscall.EINVAL
-}
-
-func joinIPv4Group(fd *netFD, ifi *Interface, ip IP) error {
-	// See golang.org/issue/7399.
-	return syscall.EINVAL
-}
-
-func setIPv6MulticastInterface(fd *netFD, ifi *Interface) error {
-	// See golang.org/issue/7399.
-	return syscall.EINVAL
-}
-
-func setIPv6MulticastLoopback(fd *netFD, v bool) error {
-	// See golang.org/issue/7399.
-	return syscall.EINVAL
-}
-
-func joinIPv6Group(fd *netFD, ifi *Interface, ip IP) error {
-	// See golang.org/issue/7399.
-	return syscall.EINVAL
-}
diff --git a/src/pkg/net/tcpsock_posix.go b/src/pkg/net/tcpsock_posix.go
deleted file mode 100644
index b79b115..0000000
--- a/src/pkg/net/tcpsock_posix.go
+++ /dev/null
@@ -1,299 +0,0 @@
-// Copyright 2009 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris windows
-
-package net
-
-import (
-	"io"
-	"os"
-	"syscall"
-	"time"
-)
-
-// BUG(rsc): On OpenBSD, listening on the "tcp" network does not listen for
-// both IPv4 and IPv6 connections. This is due to the fact that IPv4 traffic
-// will not be routed to an IPv6 socket - two separate sockets are required
-// if both AFs are to be supported. See inet6(4) on OpenBSD for details.
-
-func sockaddrToTCP(sa syscall.Sockaddr) Addr {
-	switch sa := sa.(type) {
-	case *syscall.SockaddrInet4:
-		return &TCPAddr{IP: sa.Addr[0:], Port: sa.Port}
-	case *syscall.SockaddrInet6:
-		return &TCPAddr{IP: sa.Addr[0:], Port: sa.Port, Zone: zoneToString(int(sa.ZoneId))}
-	}
-	return nil
-}
-
-func (a *TCPAddr) family() int {
-	if a == nil || len(a.IP) <= IPv4len {
-		return syscall.AF_INET
-	}
-	if a.IP.To4() != nil {
-		return syscall.AF_INET
-	}
-	return syscall.AF_INET6
-}
-
-func (a *TCPAddr) isWildcard() bool {
-	if a == nil || a.IP == nil {
-		return true
-	}
-	return a.IP.IsUnspecified()
-}
-
-func (a *TCPAddr) sockaddr(family int) (syscall.Sockaddr, error) {
-	if a == nil {
-		return nil, nil
-	}
-	return ipToSockaddr(family, a.IP, a.Port, a.Zone)
-}
-
-// TCPConn is an implementation of the Conn interface for TCP network
-// connections.
-type TCPConn struct {
-	conn
-}
-
-func newTCPConn(fd *netFD) *TCPConn {
-	c := &TCPConn{conn{fd}}
-	c.SetNoDelay(true)
-	return c
-}
-
-// ReadFrom implements the io.ReaderFrom ReadFrom method.
-func (c *TCPConn) ReadFrom(r io.Reader) (int64, error) {
-	if n, err, handled := sendFile(c.fd, r); handled {
-		return n, err
-	}
-	return genericReadFrom(c, r)
-}
-
-// CloseRead shuts down the reading side of the TCP connection.
-// Most callers should just use Close.
-func (c *TCPConn) CloseRead() error {
-	if !c.ok() {
-		return syscall.EINVAL
-	}
-	return c.fd.closeRead()
-}
-
-// CloseWrite shuts down the writing side of the TCP connection.
-// Most callers should just use Close.
-func (c *TCPConn) CloseWrite() error {
-	if !c.ok() {
-		return syscall.EINVAL
-	}
-	return c.fd.closeWrite()
-}
-
-// SetLinger sets the behavior of Close on a connection which still
-// has data waiting to be sent or to be acknowledged.
-//
-// If sec < 0 (the default), the operating system finishes sending the
-// data in the background.
-//
-// If sec == 0, the operating system discards any unsent or
-// unacknowledged data.
-//
-// If sec > 0, the data is sent in the background as with sec < 0. On
-// some operating systems after sec seconds have elapsed any remaining
-// unsent data may be discarded.
-func (c *TCPConn) SetLinger(sec int) error {
-	if !c.ok() {
-		return syscall.EINVAL
-	}
-	return setLinger(c.fd, sec)
-}
-
-// SetKeepAlive sets whether the operating system should send
-// keepalive messages on the connection.
-func (c *TCPConn) SetKeepAlive(keepalive bool) error {
-	if !c.ok() {
-		return syscall.EINVAL
-	}
-	return setKeepAlive(c.fd, keepalive)
-}
-
-// SetKeepAlivePeriod sets period between keep alives.
-func (c *TCPConn) SetKeepAlivePeriod(d time.Duration) error {
-	if !c.ok() {
-		return syscall.EINVAL
-	}
-	return setKeepAlivePeriod(c.fd, d)
-}
-
-// SetNoDelay controls whether the operating system should delay
-// packet transmission in hopes of sending fewer packets (Nagle's
-// algorithm).  The default is true (no delay), meaning that data is
-// sent as soon as possible after a Write.
-func (c *TCPConn) SetNoDelay(noDelay bool) error {
-	if !c.ok() {
-		return syscall.EINVAL
-	}
-	return setNoDelay(c.fd, noDelay)
-}
-
-// DialTCP connects to the remote address raddr on the network net,
-// which must be "tcp", "tcp4", or "tcp6".  If laddr is not nil, it is
-// used as the local address for the connection.
-func DialTCP(net string, laddr, raddr *TCPAddr) (*TCPConn, error) {
-	switch net {
-	case "tcp", "tcp4", "tcp6":
-	default:
-		return nil, &OpError{Op: "dial", Net: net, Addr: raddr, Err: UnknownNetworkError(net)}
-	}
-	if raddr == nil {
-		return nil, &OpError{Op: "dial", Net: net, Addr: nil, Err: errMissingAddress}
-	}
-	return dialTCP(net, laddr, raddr, noDeadline)
-}
-
-func dialTCP(net string, laddr, raddr *TCPAddr, deadline time.Time) (*TCPConn, error) {
-	fd, err := internetSocket(net, laddr, raddr, deadline, syscall.SOCK_STREAM, 0, "dial", sockaddrToTCP)
-
-	// TCP has a rarely used mechanism called a 'simultaneous connection' in
-	// which Dial("tcp", addr1, addr2) run on the machine at addr1 can
-	// connect to a simultaneous Dial("tcp", addr2, addr1) run on the machine
-	// at addr2, without either machine executing Listen.  If laddr == nil,
-	// it means we want the kernel to pick an appropriate originating local
-	// address.  Some Linux kernels cycle blindly through a fixed range of
-	// local ports, regardless of destination port.  If a kernel happens to
-	// pick local port 50001 as the source for a Dial("tcp", "", "localhost:50001"),
-	// then the Dial will succeed, having simultaneously connected to itself.
-	// This can only happen when we are letting the kernel pick a port (laddr == nil)
-	// and when there is no listener for the destination address.
-	// It's hard to argue this is anything other than a kernel bug.  If we
-	// see this happen, rather than expose the buggy effect to users, we
-	// close the fd and try again.  If it happens twice more, we relent and
-	// use the result.  See also:
-	//	http://golang.org/issue/2690
-	//	http://stackoverflow.com/questions/4949858/
-	//
-	// The opposite can also happen: if we ask the kernel to pick an appropriate
-	// originating local address, sometimes it picks one that is already in use.
-	// So if the error is EADDRNOTAVAIL, we have to try again too, just for
-	// a different reason.
-	//
-	// The kernel socket code is no doubt enjoying watching us squirm.
-	for i := 0; i < 2 && (laddr == nil || laddr.Port == 0) && (selfConnect(fd, err) || spuriousENOTAVAIL(err)); i++ {
-		if err == nil {
-			fd.Close()
-		}
-		fd, err = internetSocket(net, laddr, raddr, deadline, syscall.SOCK_STREAM, 0, "dial", sockaddrToTCP)
-	}
-
-	if err != nil {
-		return nil, &OpError{Op: "dial", Net: net, Addr: raddr, Err: err}
-	}
-	return newTCPConn(fd), nil
-}
-
-func selfConnect(fd *netFD, err error) bool {
-	// If the connect failed, we clearly didn't connect to ourselves.
-	if err != nil {
-		return false
-	}
-
-	// The socket constructor can return an fd with raddr nil under certain
-	// unknown conditions. The errors in the calls there to Getpeername
-	// are discarded, but we can't catch the problem there because those
-	// calls are sometimes legally erroneous with a "socket not connected".
-	// Since this code (selfConnect) is already trying to work around
-	// a problem, we make sure if this happens we recognize trouble and
-	// ask the DialTCP routine to try again.
-	// TODO: try to understand what's really going on.
-	if fd.laddr == nil || fd.raddr == nil {
-		return true
-	}
-	l := fd.laddr.(*TCPAddr)
-	r := fd.raddr.(*TCPAddr)
-	return l.Port == r.Port && l.IP.Equal(r.IP)
-}
-
-func spuriousENOTAVAIL(err error) bool {
-	e, ok := err.(*OpError)
-	return ok && e.Err == syscall.EADDRNOTAVAIL
-}
-
-// TCPListener is a TCP network listener.  Clients should typically
-// use variables of type Listener instead of assuming TCP.
-type TCPListener struct {
-	fd *netFD
-}
-
-// AcceptTCP accepts the next incoming call and returns the new
-// connection.
-func (l *TCPListener) AcceptTCP() (*TCPConn, error) {
-	if l == nil || l.fd == nil {
-		return nil, syscall.EINVAL
-	}
-	fd, err := l.fd.accept(sockaddrToTCP)
-	if err != nil {
-		return nil, err
-	}
-	return newTCPConn(fd), nil
-}
-
-// Accept implements the Accept method in the Listener interface; it
-// waits for the next call and returns a generic Conn.
-func (l *TCPListener) Accept() (Conn, error) {
-	c, err := l.AcceptTCP()
-	if err != nil {
-		return nil, err
-	}
-	return c, nil
-}
-
-// Close stops listening on the TCP address.
-// Already Accepted connections are not closed.
-func (l *TCPListener) Close() error {
-	if l == nil || l.fd == nil {
-		return syscall.EINVAL
-	}
-	return l.fd.Close()
-}
-
-// Addr returns the listener's network address, a *TCPAddr.
-func (l *TCPListener) Addr() Addr { return l.fd.laddr }
-
-// SetDeadline sets the deadline associated with the listener.
-// A zero time value disables the deadline.
-func (l *TCPListener) SetDeadline(t time.Time) error {
-	if l == nil || l.fd == nil {
-		return syscall.EINVAL
-	}
-	return l.fd.setDeadline(t)
-}
-
-// File returns a copy of the underlying os.File, set to blocking
-// mode.  It is the caller's responsibility to close f when finished.
-// Closing l does not affect f, and closing f does not affect l.
-//
-// The returned os.File's file descriptor is different from the
-// connection's.  Attempting to change properties of the original
-// using this duplicate may or may not have the desired effect.
-func (l *TCPListener) File() (f *os.File, err error) { return l.fd.dup() }
-
-// ListenTCP announces on the TCP address laddr and returns a TCP
-// listener.  Net must be "tcp", "tcp4", or "tcp6".  If laddr has a
-// port of 0, ListenTCP will choose an available port.  The caller can
-// use the Addr method of TCPListener to retrieve the chosen address.
-func ListenTCP(net string, laddr *TCPAddr) (*TCPListener, error) {
-	switch net {
-	case "tcp", "tcp4", "tcp6":
-	default:
-		return nil, &OpError{Op: "listen", Net: net, Addr: laddr, Err: UnknownNetworkError(net)}
-	}
-	if laddr == nil {
-		laddr = &TCPAddr{}
-	}
-	fd, err := internetSocket(net, laddr, nil, noDeadline, syscall.SOCK_STREAM, 0, "listen", sockaddrToTCP)
-	if err != nil {
-		return nil, &OpError{Op: "listen", Net: net, Addr: laddr, Err: err}
-	}
-	return &TCPListener{fd}, nil
-}
diff --git a/src/pkg/net/tcpsockopt_darwin.go b/src/pkg/net/tcpsockopt_darwin.go
deleted file mode 100644
index 3314084..0000000
--- a/src/pkg/net/tcpsockopt_darwin.go
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2009 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// TCP socket options for darwin
-
-package net
-
-import (
-	"os"
-	"syscall"
-	"time"
-)
-
-// Set keep alive period.
-func setKeepAlivePeriod(fd *netFD, d time.Duration) error {
-	if err := fd.incref(); err != nil {
-		return err
-	}
-	defer fd.decref()
-
-	// The kernel expects seconds so round to next highest second.
-	d += (time.Second - time.Nanosecond)
-	secs := int(d.Seconds())
-
-	return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd.sysfd, syscall.IPPROTO_TCP, syscall.TCP_KEEPALIVE, secs))
-}
diff --git a/src/pkg/net/tcpsockopt_dragonfly.go b/src/pkg/net/tcpsockopt_dragonfly.go
deleted file mode 100644
index d10a777..0000000
--- a/src/pkg/net/tcpsockopt_dragonfly.go
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2009 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package net
-
-import (
-	"os"
-	"syscall"
-	"time"
-)
-
-// Set keep alive period.
-func setKeepAlivePeriod(fd *netFD, d time.Duration) error {
-	if err := fd.incref(); err != nil {
-		return err
-	}
-	defer fd.decref()
-
-	// The kernel expects milliseconds so round to next highest millisecond.
-	d += (time.Millisecond - time.Nanosecond)
-	msecs := int(time.Duration(d.Nanoseconds()) / time.Millisecond)
-
-	err := os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd.sysfd, syscall.IPPROTO_TCP, syscall.TCP_KEEPINTVL, msecs))
-	if err != nil {
-		return err
-	}
-	return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd.sysfd, syscall.IPPROTO_TCP, syscall.TCP_KEEPIDLE, msecs))
-}
diff --git a/src/pkg/net/tcpsockopt_openbsd.go b/src/pkg/net/tcpsockopt_openbsd.go
deleted file mode 100644
index 3480f93..0000000
--- a/src/pkg/net/tcpsockopt_openbsd.go
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2009 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// TCP socket options for openbsd
-
-package net
-
-import (
-	"os"
-	"syscall"
-	"time"
-)
-
-// Set keep alive period.
-func setKeepAlivePeriod(fd *netFD, d time.Duration) error {
-	if err := fd.incref(); err != nil {
-		return err
-	}
-	defer fd.decref()
-
-	// The kernel expects seconds so round to next highest second.
-	d += (time.Second - time.Nanosecond)
-	secs := int(d.Seconds())
-
-	return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd.sysfd, syscall.IPPROTO_TCP, syscall.SO_KEEPALIVE, secs))
-}
diff --git a/src/pkg/net/tcpsockopt_posix.go b/src/pkg/net/tcpsockopt_posix.go
deleted file mode 100644
index 6484bad..0000000
--- a/src/pkg/net/tcpsockopt_posix.go
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2009 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris windows
-
-package net
-
-import (
-	"os"
-	"syscall"
-)
-
-func setNoDelay(fd *netFD, noDelay bool) error {
-	if err := fd.incref(); err != nil {
-		return err
-	}
-	defer fd.decref()
-	return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd.sysfd, syscall.IPPROTO_TCP, syscall.TCP_NODELAY, boolint(noDelay)))
-}
diff --git a/src/pkg/net/tcpsockopt_solaris.go b/src/pkg/net/tcpsockopt_solaris.go
deleted file mode 100644
index eaab6b6..0000000
--- a/src/pkg/net/tcpsockopt_solaris.go
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// TCP socket options for solaris
-
-package net
-
-import (
-	"os"
-	"syscall"
-	"time"
-)
-
-// Set keep alive period.
-func setKeepAlivePeriod(fd *netFD, d time.Duration) error {
-	if err := fd.incref(); err != nil {
-		return err
-	}
-	defer fd.decref()
-
-	// The kernel expects seconds so round to next highest second.
-	d += (time.Second - time.Nanosecond)
-	secs := int(d.Seconds())
-
-	return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd.sysfd, syscall.IPPROTO_TCP, syscall.SO_KEEPALIVE, secs))
-}
diff --git a/src/pkg/net/tcpsockopt_unix.go b/src/pkg/net/tcpsockopt_unix.go
deleted file mode 100644
index 2693a54..0000000
--- a/src/pkg/net/tcpsockopt_unix.go
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2009 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build freebsd linux nacl netbsd
-
-package net
-
-import (
-	"os"
-	"syscall"
-	"time"
-)
-
-// Set keep alive period.
-func setKeepAlivePeriod(fd *netFD, d time.Duration) error {
-	if err := fd.incref(); err != nil {
-		return err
-	}
-	defer fd.decref()
-
-	// The kernel expects seconds so round to next highest second.
-	d += (time.Second - time.Nanosecond)
-	secs := int(d.Seconds())
-
-	err := os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd.sysfd, syscall.IPPROTO_TCP, syscall.TCP_KEEPINTVL, secs))
-	if err != nil {
-		return err
-	}
-	return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd.sysfd, syscall.IPPROTO_TCP, syscall.TCP_KEEPIDLE, secs))
-}
diff --git a/src/pkg/net/tcpsockopt_windows.go b/src/pkg/net/tcpsockopt_windows.go
deleted file mode 100644
index 8ef1407..0000000
--- a/src/pkg/net/tcpsockopt_windows.go
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2009 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// TCP socket options for windows
-
-package net
-
-import (
-	"os"
-	"syscall"
-	"time"
-	"unsafe"
-)
-
-func setKeepAlivePeriod(fd *netFD, d time.Duration) error {
-	if err := fd.incref(); err != nil {
-		return err
-	}
-	defer fd.decref()
-
-	// Windows expects milliseconds so round to next highest millisecond.
-	d += (time.Millisecond - time.Nanosecond)
-	millis := uint32(d / time.Millisecond)
-	ka := syscall.TCPKeepalive{
-		OnOff:    1,
-		Time:     millis,
-		Interval: millis,
-	}
-	ret := uint32(0)
-	size := uint32(unsafe.Sizeof(ka))
-	err := syscall.WSAIoctl(fd.sysfd, syscall.SIO_KEEPALIVE_VALS, (*byte)(unsafe.Pointer(&ka)), size, nil, 0, &ret, nil, 0)
-	return os.NewSyscallError("WSAIoctl", err)
-}
diff --git a/src/pkg/net/testdata/resolv.conf b/src/pkg/net/testdata/resolv.conf
deleted file mode 100644
index 3841bbf..0000000
--- a/src/pkg/net/testdata/resolv.conf
+++ /dev/null
@@ -1,6 +0,0 @@
-# /etc/resolv.conf
-
-domain Home
-nameserver 192.168.1.1
-options ndots:5 timeout:10 attempts:3 rotate
-options attempts 3
diff --git a/src/pkg/net/udp_test.go b/src/pkg/net/udp_test.go
deleted file mode 100644
index e177877..0000000
--- a/src/pkg/net/udp_test.go
+++ /dev/null
@@ -1,257 +0,0 @@
-// Copyright 2012 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package net
-
-import (
-	"reflect"
-	"runtime"
-	"strings"
-	"testing"
-)
-
-func TestResolveUDPAddr(t *testing.T) {
-	for _, tt := range resolveTCPAddrTests {
-		net := strings.Replace(tt.net, "tcp", "udp", -1)
-		addr, err := ResolveUDPAddr(net, tt.litAddrOrName)
-		if err != tt.err {
-			t.Fatalf("ResolveUDPAddr(%q, %q) failed: %v", net, tt.litAddrOrName, err)
-		}
-		if !reflect.DeepEqual(addr, (*UDPAddr)(tt.addr)) {
-			t.Fatalf("ResolveUDPAddr(%q, %q) = %#v, want %#v", net, tt.litAddrOrName, addr, tt.addr)
-		}
-		if err == nil {
-			str := addr.String()
-			addr1, err := ResolveUDPAddr(net, str)
-			if err != nil {
-				t.Fatalf("ResolveUDPAddr(%q, %q) [from %q]: %v", net, str, tt.litAddrOrName, err)
-			}
-			if !reflect.DeepEqual(addr1, addr) {
-				t.Fatalf("ResolveUDPAddr(%q, %q) [from %q] = %#v, want %#v", net, str, tt.litAddrOrName, addr1, addr)
-			}
-		}
-	}
-}
-
-func TestWriteToUDP(t *testing.T) {
-	switch runtime.GOOS {
-	case "plan9":
-		t.Skipf("skipping test on %q", runtime.GOOS)
-	}
-
-	l, err := ListenPacket("udp", "127.0.0.1:0")
-	if err != nil {
-		t.Fatalf("Listen failed: %v", err)
-	}
-	defer l.Close()
-
-	testWriteToConn(t, l.LocalAddr().String())
-	testWriteToPacketConn(t, l.LocalAddr().String())
-}
-
-func testWriteToConn(t *testing.T, raddr string) {
-	c, err := Dial("udp", raddr)
-	if err != nil {
-		t.Fatalf("Dial failed: %v", err)
-	}
-	defer c.Close()
-
-	ra, err := ResolveUDPAddr("udp", raddr)
-	if err != nil {
-		t.Fatalf("ResolveUDPAddr failed: %v", err)
-	}
-
-	_, err = c.(*UDPConn).WriteToUDP([]byte("Connection-oriented mode socket"), ra)
-	if err == nil {
-		t.Fatal("WriteToUDP should fail")
-	}
-	if err != nil && err.(*OpError).Err != ErrWriteToConnected {
-		t.Fatalf("WriteToUDP should fail as ErrWriteToConnected: %v", err)
-	}
-
-	_, err = c.(*UDPConn).WriteTo([]byte("Connection-oriented mode socket"), ra)
-	if err == nil {
-		t.Fatal("WriteTo should fail")
-	}
-	if err != nil && err.(*OpError).Err != ErrWriteToConnected {
-		t.Fatalf("WriteTo should fail as ErrWriteToConnected: %v", err)
-	}
-
-	_, err = c.Write([]byte("Connection-oriented mode socket"))
-	if err != nil {
-		t.Fatalf("Write failed: %v", err)
-	}
-}
-
-func testWriteToPacketConn(t *testing.T, raddr string) {
-	c, err := ListenPacket("udp", "127.0.0.1:0")
-	if err != nil {
-		t.Fatalf("ListenPacket failed: %v", err)
-	}
-	defer c.Close()
-
-	ra, err := ResolveUDPAddr("udp", raddr)
-	if err != nil {
-		t.Fatalf("ResolveUDPAddr failed: %v", err)
-	}
-
-	_, err = c.(*UDPConn).WriteToUDP([]byte("Connection-less mode socket"), ra)
-	if err != nil {
-		t.Fatalf("WriteToUDP failed: %v", err)
-	}
-
-	_, err = c.WriteTo([]byte("Connection-less mode socket"), ra)
-	if err != nil {
-		t.Fatalf("WriteTo failed: %v", err)
-	}
-
-	_, err = c.(*UDPConn).Write([]byte("Connection-less mode socket"))
-	if err == nil {
-		t.Fatal("Write should fail")
-	}
-}
-
-var udpConnLocalNameTests = []struct {
-	net   string
-	laddr *UDPAddr
-}{
-	{"udp4", &UDPAddr{IP: IPv4(127, 0, 0, 1)}},
-	{"udp4", &UDPAddr{}},
-	{"udp4", nil},
-}
-
-func TestUDPConnLocalName(t *testing.T) {
-	if testing.Short() || !*testExternal {
-		t.Skip("skipping test to avoid external network")
-	}
-
-	for _, tt := range udpConnLocalNameTests {
-		c, err := ListenUDP(tt.net, tt.laddr)
-		if err != nil {
-			t.Fatalf("ListenUDP failed: %v", err)
-		}
-		defer c.Close()
-		la := c.LocalAddr()
-		if a, ok := la.(*UDPAddr); !ok || a.Port == 0 {
-			t.Fatalf("got %v; expected a proper address with non-zero port number", la)
-		}
-	}
-}
-
-func TestUDPConnLocalAndRemoteNames(t *testing.T) {
-	for _, laddr := range []string{"", "127.0.0.1:0"} {
-		c1, err := ListenPacket("udp", "127.0.0.1:0")
-		if err != nil {
-			t.Fatalf("ListenUDP failed: %v", err)
-		}
-		defer c1.Close()
-
-		var la *UDPAddr
-		if laddr != "" {
-			var err error
-			if la, err = ResolveUDPAddr("udp", laddr); err != nil {
-				t.Fatalf("ResolveUDPAddr failed: %v", err)
-			}
-		}
-		c2, err := DialUDP("udp", la, c1.LocalAddr().(*UDPAddr))
-		if err != nil {
-			t.Fatalf("DialUDP failed: %v", err)
-		}
-		defer c2.Close()
-
-		var connAddrs = [4]struct {
-			got Addr
-			ok  bool
-		}{
-			{c1.LocalAddr(), true},
-			{c1.(*UDPConn).RemoteAddr(), false},
-			{c2.LocalAddr(), true},
-			{c2.RemoteAddr(), true},
-		}
-		for _, ca := range connAddrs {
-			if a, ok := ca.got.(*UDPAddr); ok != ca.ok || ok && a.Port == 0 {
-				t.Fatalf("got %v; expected a proper address with non-zero port number", ca.got)
-			}
-		}
-	}
-}
-
-func TestIPv6LinkLocalUnicastUDP(t *testing.T) {
-	if testing.Short() || !*testExternal {
-		t.Skip("skipping test to avoid external network")
-	}
-	if !supportsIPv6 {
-		t.Skip("ipv6 is not supported")
-	}
-	ifi := loopbackInterface()
-	if ifi == nil {
-		t.Skip("loopback interface not found")
-	}
-	laddr := ipv6LinkLocalUnicastAddr(ifi)
-	if laddr == "" {
-		t.Skip("ipv6 unicast address on loopback not found")
-	}
-
-	type test struct {
-		net, addr  string
-		nameLookup bool
-	}
-	var tests = []test{
-		{"udp", "[" + laddr + "%" + ifi.Name + "]:0", false},
-		{"udp6", "[" + laddr + "%" + ifi.Name + "]:0", false},
-	}
-	// The first udp test fails on DragonFly - see issue 7473.
-	if runtime.GOOS == "dragonfly" {
-		tests = tests[1:]
-	}
-	switch runtime.GOOS {
-	case "darwin", "dragonfly", "freebsd", "openbsd", "netbsd":
-		tests = append(tests, []test{
-			{"udp", "[localhost%" + ifi.Name + "]:0", true},
-			{"udp6", "[localhost%" + ifi.Name + "]:0", true},
-		}...)
-	case "linux":
-		tests = append(tests, []test{
-			{"udp", "[ip6-localhost%" + ifi.Name + "]:0", true},
-			{"udp6", "[ip6-localhost%" + ifi.Name + "]:0", true},
-		}...)
-	}
-	for _, tt := range tests {
-		c1, err := ListenPacket(tt.net, tt.addr)
-		if err != nil {
-			// It might return "LookupHost returned no
-			// suitable address" error on some platforms.
-			t.Logf("ListenPacket failed: %v", err)
-			continue
-		}
-		defer c1.Close()
-		if la, ok := c1.LocalAddr().(*UDPAddr); !ok || !tt.nameLookup && la.Zone == "" {
-			t.Fatalf("got %v; expected a proper address with zone identifier", la)
-		}
-
-		c2, err := Dial(tt.net, c1.LocalAddr().String())
-		if err != nil {
-			t.Fatalf("Dial failed: %v", err)
-		}
-		defer c2.Close()
-		if la, ok := c2.LocalAddr().(*UDPAddr); !ok || !tt.nameLookup && la.Zone == "" {
-			t.Fatalf("got %v; expected a proper address with zone identifier", la)
-		}
-		if ra, ok := c2.RemoteAddr().(*UDPAddr); !ok || !tt.nameLookup && ra.Zone == "" {
-			t.Fatalf("got %v; expected a proper address with zone identifier", ra)
-		}
-
-		if _, err := c2.Write([]byte("UDP OVER IPV6 LINKLOCAL TEST")); err != nil {
-			t.Fatalf("Conn.Write failed: %v", err)
-		}
-		b := make([]byte, 32)
-		if _, from, err := c1.ReadFrom(b); err != nil {
-			t.Fatalf("PacketConn.ReadFrom failed: %v", err)
-		} else {
-			if ra, ok := from.(*UDPAddr); !ok || !tt.nameLookup && ra.Zone == "" {
-				t.Fatalf("got %v; expected a proper address with zone identifier", ra)
-			}
-		}
-	}
-}
diff --git a/src/pkg/net/udpsock_posix.go b/src/pkg/net/udpsock_posix.go
deleted file mode 100644
index 5dfba94..0000000
--- a/src/pkg/net/udpsock_posix.go
+++ /dev/null
@@ -1,268 +0,0 @@
-// Copyright 2009 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris windows
-
-package net
-
-import (
-	"syscall"
-	"time"
-)
-
-func sockaddrToUDP(sa syscall.Sockaddr) Addr {
-	switch sa := sa.(type) {
-	case *syscall.SockaddrInet4:
-		return &UDPAddr{IP: sa.Addr[0:], Port: sa.Port}
-	case *syscall.SockaddrInet6:
-		return &UDPAddr{IP: sa.Addr[0:], Port: sa.Port, Zone: zoneToString(int(sa.ZoneId))}
-	}
-	return nil
-}
-
-func (a *UDPAddr) family() int {
-	if a == nil || len(a.IP) <= IPv4len {
-		return syscall.AF_INET
-	}
-	if a.IP.To4() != nil {
-		return syscall.AF_INET
-	}
-	return syscall.AF_INET6
-}
-
-func (a *UDPAddr) isWildcard() bool {
-	if a == nil || a.IP == nil {
-		return true
-	}
-	return a.IP.IsUnspecified()
-}
-
-func (a *UDPAddr) sockaddr(family int) (syscall.Sockaddr, error) {
-	if a == nil {
-		return nil, nil
-	}
-	return ipToSockaddr(family, a.IP, a.Port, a.Zone)
-}
-
-// UDPConn is the implementation of the Conn and PacketConn interfaces
-// for UDP network connections.
-type UDPConn struct {
-	conn
-}
-
-func newUDPConn(fd *netFD) *UDPConn { return &UDPConn{conn{fd}} }
-
-// ReadFromUDP reads a UDP packet from c, copying the payload into b.
-// It returns the number of bytes copied into b and the return address
-// that was on the packet.
-//
-// ReadFromUDP can be made to time out and return an error with
-// Timeout() == true after a fixed time limit; see SetDeadline and
-// SetReadDeadline.
-func (c *UDPConn) ReadFromUDP(b []byte) (n int, addr *UDPAddr, err error) {
-	if !c.ok() {
-		return 0, nil, syscall.EINVAL
-	}
-	n, sa, err := c.fd.readFrom(b)
-	switch sa := sa.(type) {
-	case *syscall.SockaddrInet4:
-		addr = &UDPAddr{IP: sa.Addr[0:], Port: sa.Port}
-	case *syscall.SockaddrInet6:
-		addr = &UDPAddr{IP: sa.Addr[0:], Port: sa.Port, Zone: zoneToString(int(sa.ZoneId))}
-	}
-	return
-}
-
-// ReadFrom implements the PacketConn ReadFrom method.
-func (c *UDPConn) ReadFrom(b []byte) (int, Addr, error) {
-	if !c.ok() {
-		return 0, nil, syscall.EINVAL
-	}
-	n, addr, err := c.ReadFromUDP(b)
-	return n, addr.toAddr(), err
-}
-
-// ReadMsgUDP reads a packet from c, copying the payload into b and
-// the associated out-of-band data into oob.  It returns the number
-// of bytes copied into b, the number of bytes copied into oob, the
-// flags that were set on the packet and the source address of the
-// packet.
-func (c *UDPConn) ReadMsgUDP(b, oob []byte) (n, oobn, flags int, addr *UDPAddr, err error) {
-	if !c.ok() {
-		return 0, 0, 0, nil, syscall.EINVAL
-	}
-	var sa syscall.Sockaddr
-	n, oobn, flags, sa, err = c.fd.readMsg(b, oob)
-	switch sa := sa.(type) {
-	case *syscall.SockaddrInet4:
-		addr = &UDPAddr{IP: sa.Addr[0:], Port: sa.Port}
-	case *syscall.SockaddrInet6:
-		addr = &UDPAddr{IP: sa.Addr[0:], Port: sa.Port, Zone: zoneToString(int(sa.ZoneId))}
-	}
-	return
-}
-
-// WriteToUDP writes a UDP packet to addr via c, copying the payload
-// from b.
-//
-// WriteToUDP can be made to time out and return an error with
-// Timeout() == true after a fixed time limit; see SetDeadline and
-// SetWriteDeadline.  On packet-oriented connections, write timeouts
-// are rare.
-func (c *UDPConn) WriteToUDP(b []byte, addr *UDPAddr) (int, error) {
-	if !c.ok() {
-		return 0, syscall.EINVAL
-	}
-	if c.fd.isConnected {
-		return 0, &OpError{"write", c.fd.net, addr, ErrWriteToConnected}
-	}
-	if addr == nil {
-		return 0, &OpError{Op: "write", Net: c.fd.net, Addr: nil, Err: errMissingAddress}
-	}
-	sa, err := addr.sockaddr(c.fd.family)
-	if err != nil {
-		return 0, &OpError{"write", c.fd.net, addr, err}
-	}
-	return c.fd.writeTo(b, sa)
-}
-
-// WriteTo implements the PacketConn WriteTo method.
-func (c *UDPConn) WriteTo(b []byte, addr Addr) (int, error) {
-	if !c.ok() {
-		return 0, syscall.EINVAL
-	}
-	a, ok := addr.(*UDPAddr)
-	if !ok {
-		return 0, &OpError{"write", c.fd.net, addr, syscall.EINVAL}
-	}
-	return c.WriteToUDP(b, a)
-}
-
-// WriteMsgUDP writes a packet to addr via c, copying the payload from
-// b and the associated out-of-band data from oob.  It returns the
-// number of payload and out-of-band bytes written.
-func (c *UDPConn) WriteMsgUDP(b, oob []byte, addr *UDPAddr) (n, oobn int, err error) {
-	if !c.ok() {
-		return 0, 0, syscall.EINVAL
-	}
-	if c.fd.isConnected {
-		return 0, 0, &OpError{"write", c.fd.net, addr, ErrWriteToConnected}
-	}
-	if addr == nil {
-		return 0, 0, &OpError{Op: "write", Net: c.fd.net, Addr: nil, Err: errMissingAddress}
-	}
-	sa, err := addr.sockaddr(c.fd.family)
-	if err != nil {
-		return 0, 0, &OpError{"write", c.fd.net, addr, err}
-	}
-	return c.fd.writeMsg(b, oob, sa)
-}
-
-// DialUDP connects to the remote address raddr on the network net,
-// which must be "udp", "udp4", or "udp6".  If laddr is not nil, it is
-// used as the local address for the connection.
-func DialUDP(net string, laddr, raddr *UDPAddr) (*UDPConn, error) {
-	switch net {
-	case "udp", "udp4", "udp6":
-	default:
-		return nil, &OpError{Op: "dial", Net: net, Addr: raddr, Err: UnknownNetworkError(net)}
-	}
-	if raddr == nil {
-		return nil, &OpError{Op: "dial", Net: net, Addr: nil, Err: errMissingAddress}
-	}
-	return dialUDP(net, laddr, raddr, noDeadline)
-}
-
-func dialUDP(net string, laddr, raddr *UDPAddr, deadline time.Time) (*UDPConn, error) {
-	fd, err := internetSocket(net, laddr, raddr, deadline, syscall.SOCK_DGRAM, 0, "dial", sockaddrToUDP)
-	if err != nil {
-		return nil, &OpError{Op: "dial", Net: net, Addr: raddr, Err: err}
-	}
-	return newUDPConn(fd), nil
-}
-
-// ListenUDP listens for incoming UDP packets addressed to the local
-// address laddr.  Net must be "udp", "udp4", or "udp6".  If laddr has
-// a port of 0, ListenUDP will choose an available port.
-// The LocalAddr method of the returned UDPConn can be used to
-// discover the port.  The returned connection's ReadFrom and WriteTo
-// methods can be used to receive and send UDP packets with per-packet
-// addressing.
-func ListenUDP(net string, laddr *UDPAddr) (*UDPConn, error) {
-	switch net {
-	case "udp", "udp4", "udp6":
-	default:
-		return nil, &OpError{Op: "listen", Net: net, Addr: laddr, Err: UnknownNetworkError(net)}
-	}
-	if laddr == nil {
-		laddr = &UDPAddr{}
-	}
-	fd, err := internetSocket(net, laddr, nil, noDeadline, syscall.SOCK_DGRAM, 0, "listen", sockaddrToUDP)
-	if err != nil {
-		return nil, &OpError{Op: "listen", Net: net, Addr: laddr, Err: err}
-	}
-	return newUDPConn(fd), nil
-}
-
-// ListenMulticastUDP listens for incoming multicast UDP packets
-// addressed to the group address gaddr on ifi, which specifies the
-// interface to join.  ListenMulticastUDP uses default multicast
-// interface if ifi is nil.
-func ListenMulticastUDP(net string, ifi *Interface, gaddr *UDPAddr) (*UDPConn, error) {
-	switch net {
-	case "udp", "udp4", "udp6":
-	default:
-		return nil, &OpError{Op: "listen", Net: net, Addr: gaddr, Err: UnknownNetworkError(net)}
-	}
-	if gaddr == nil || gaddr.IP == nil {
-		return nil, &OpError{Op: "listen", Net: net, Addr: nil, Err: errMissingAddress}
-	}
-	fd, err := internetSocket(net, gaddr, nil, noDeadline, syscall.SOCK_DGRAM, 0, "listen", sockaddrToUDP)
-	if err != nil {
-		return nil, &OpError{Op: "listen", Net: net, Addr: gaddr, Err: err}
-	}
-	c := newUDPConn(fd)
-	if ip4 := gaddr.IP.To4(); ip4 != nil {
-		if err := listenIPv4MulticastUDP(c, ifi, ip4); err != nil {
-			c.Close()
-			return nil, &OpError{Op: "listen", Net: net, Addr: &IPAddr{IP: ip4}, Err: err}
-		}
-	} else {
-		if err := listenIPv6MulticastUDP(c, ifi, gaddr.IP); err != nil {
-			c.Close()
-			return nil, &OpError{Op: "listen", Net: net, Addr: &IPAddr{IP: gaddr.IP}, Err: err}
-		}
-	}
-	return c, nil
-}
-
-func listenIPv4MulticastUDP(c *UDPConn, ifi *Interface, ip IP) error {
-	if ifi != nil {
-		if err := setIPv4MulticastInterface(c.fd, ifi); err != nil {
-			return err
-		}
-	}
-	if err := setIPv4MulticastLoopback(c.fd, false); err != nil {
-		return err
-	}
-	if err := joinIPv4Group(c.fd, ifi, ip); err != nil {
-		return err
-	}
-	return nil
-}
-
-func listenIPv6MulticastUDP(c *UDPConn, ifi *Interface, ip IP) error {
-	if ifi != nil {
-		if err := setIPv6MulticastInterface(c.fd, ifi); err != nil {
-			return err
-		}
-	}
-	if err := setIPv6MulticastLoopback(c.fd, false); err != nil {
-		return err
-	}
-	if err := joinIPv6Group(c.fd, ifi, ip); err != nil {
-		return err
-	}
-	return nil
-}
diff --git a/src/pkg/net/unicast_posix_test.go b/src/pkg/net/unicast_posix_test.go
deleted file mode 100644
index 452ac92..0000000
--- a/src/pkg/net/unicast_posix_test.go
+++ /dev/null
@@ -1,466 +0,0 @@
-// Copyright 2011 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build !plan9
-
-package net
-
-import (
-	"runtime"
-	"syscall"
-	"testing"
-)
-
-var listenerTests = []struct {
-	net      string
-	laddr    string
-	ipv6     bool // test with underlying AF_INET6 socket
-	wildcard bool // test with wildcard address
-}{
-	{net: "tcp", laddr: "", wildcard: true},
-	{net: "tcp", laddr: "0.0.0.0", wildcard: true},
-	{net: "tcp", laddr: "[::ffff:0.0.0.0]", wildcard: true},
-	{net: "tcp", laddr: "[::]", ipv6: true, wildcard: true},
-
-	{net: "tcp", laddr: "127.0.0.1"},
-	{net: "tcp", laddr: "[::ffff:127.0.0.1]"},
-	{net: "tcp", laddr: "[::1]", ipv6: true},
-
-	{net: "tcp4", laddr: "", wildcard: true},
-	{net: "tcp4", laddr: "0.0.0.0", wildcard: true},
-	{net: "tcp4", laddr: "[::ffff:0.0.0.0]", wildcard: true},
-
-	{net: "tcp4", laddr: "127.0.0.1"},
-	{net: "tcp4", laddr: "[::ffff:127.0.0.1]"},
-
-	{net: "tcp6", laddr: "", ipv6: true, wildcard: true},
-	{net: "tcp6", laddr: "[::]", ipv6: true, wildcard: true},
-
-	{net: "tcp6", laddr: "[::1]", ipv6: true},
-}
-
-// TestTCPListener tests both single and double listen to a test
-// listener with same address family, same listening address and
-// same port.
-func TestTCPListener(t *testing.T) {
-	switch runtime.GOOS {
-	case "plan9":
-		t.Skipf("skipping test on %q", runtime.GOOS)
-	}
-
-	for _, tt := range listenerTests {
-		if tt.wildcard && (testing.Short() || !*testExternal) {
-			continue
-		}
-		if tt.ipv6 && !supportsIPv6 {
-			continue
-		}
-		l1, port := usableListenPort(t, tt.net, tt.laddr)
-		checkFirstListener(t, tt.net, tt.laddr+":"+port, l1)
-		l2, err := Listen(tt.net, tt.laddr+":"+port)
-		checkSecondListener(t, tt.net, tt.laddr+":"+port, err, l2)
-		l1.Close()
-	}
-}
-
-// TestUDPListener tests both single and double listen to a test
-// listener with same address family, same listening address and
-// same port.
-func TestUDPListener(t *testing.T) {
-	switch runtime.GOOS {
-	case "plan9":
-		t.Skipf("skipping test on %q", runtime.GOOS)
-	}
-
-	toudpnet := func(net string) string {
-		switch net {
-		case "tcp":
-			return "udp"
-		case "tcp4":
-			return "udp4"
-		case "tcp6":
-			return "udp6"
-		}
-		return "<nil>"
-	}
-
-	for _, tt := range listenerTests {
-		if tt.wildcard && (testing.Short() || !*testExternal) {
-			continue
-		}
-		if tt.ipv6 && !supportsIPv6 {
-			continue
-		}
-		tt.net = toudpnet(tt.net)
-		l1, port := usableListenPacketPort(t, tt.net, tt.laddr)
-		checkFirstListener(t, tt.net, tt.laddr+":"+port, l1)
-		l2, err := ListenPacket(tt.net, tt.laddr+":"+port)
-		checkSecondListener(t, tt.net, tt.laddr+":"+port, err, l2)
-		l1.Close()
-	}
-}
-
-var dualStackListenerTests = []struct {
-	net1     string // first listener
-	laddr1   string
-	net2     string // second listener
-	laddr2   string
-	wildcard bool  // test with wildcard address
-	xerr     error // expected error value, nil or other
-}{
-	// Test cases and expected results for the attemping 2nd listen on the same port
-	// 1st listen                2nd listen                 darwin  freebsd  linux  openbsd
-	// ------------------------------------------------------------------------------------
-	// "tcp"  ""                 "tcp"  ""                    -        -       -       -
-	// "tcp"  ""                 "tcp"  "0.0.0.0"             -        -       -       -
-	// "tcp"  "0.0.0.0"          "tcp"  ""                    -        -       -       -
-	// ------------------------------------------------------------------------------------
-	// "tcp"  ""                 "tcp"  "[::]"                -        -       -       ok
-	// "tcp"  "[::]"             "tcp"  ""                    -        -       -       ok
-	// "tcp"  "0.0.0.0"          "tcp"  "[::]"                -        -       -       ok
-	// "tcp"  "[::]"             "tcp"  "0.0.0.0"             -        -       -       ok
-	// "tcp"  "[::ffff:0.0.0.0]" "tcp"  "[::]"                -        -       -       ok
-	// "tcp"  "[::]"             "tcp"  "[::ffff:0.0.0.0]"    -        -       -       ok
-	// ------------------------------------------------------------------------------------
-	// "tcp4" ""                 "tcp6" ""                    ok       ok      ok      ok
-	// "tcp6" ""                 "tcp4" ""                    ok       ok      ok      ok
-	// "tcp4" "0.0.0.0"          "tcp6" "[::]"                ok       ok      ok      ok
-	// "tcp6" "[::]"             "tcp4" "0.0.0.0"             ok       ok      ok      ok
-	// ------------------------------------------------------------------------------------
-	// "tcp"  "127.0.0.1"        "tcp"  "[::1]"               ok       ok      ok      ok
-	// "tcp"  "[::1]"            "tcp"  "127.0.0.1"           ok       ok      ok      ok
-	// "tcp4" "127.0.0.1"        "tcp6" "[::1]"               ok       ok      ok      ok
-	// "tcp6" "[::1]"            "tcp4" "127.0.0.1"           ok       ok      ok      ok
-	//
-	// Platform default configurations:
-	// darwin, kernel version 11.3.0
-	//	net.inet6.ip6.v6only=0 (overridable by sysctl or IPV6_V6ONLY option)
-	// freebsd, kernel version 8.2
-	//	net.inet6.ip6.v6only=1 (overridable by sysctl or IPV6_V6ONLY option)
-	// linux, kernel version 3.0.0
-	//	net.ipv6.bindv6only=0 (overridable by sysctl or IPV6_V6ONLY option)
-	// openbsd, kernel version 5.0
-	//	net.inet6.ip6.v6only=1 (overriding is prohibited)
-
-	{net1: "tcp", laddr1: "", net2: "tcp", laddr2: "", wildcard: true, xerr: syscall.EADDRINUSE},
-	{net1: "tcp", laddr1: "", net2: "tcp", laddr2: "0.0.0.0", wildcard: true, xerr: syscall.EADDRINUSE},
-	{net1: "tcp", laddr1: "0.0.0.0", net2: "tcp", laddr2: "", wildcard: true, xerr: syscall.EADDRINUSE},
-
-	{net1: "tcp", laddr1: "", net2: "tcp", laddr2: "[::]", wildcard: true, xerr: syscall.EADDRINUSE},
-	{net1: "tcp", laddr1: "[::]", net2: "tcp", laddr2: "", wildcard: true, xerr: syscall.EADDRINUSE},
-	{net1: "tcp", laddr1: "0.0.0.0", net2: "tcp", laddr2: "[::]", wildcard: true, xerr: syscall.EADDRINUSE},
-	{net1: "tcp", laddr1: "[::]", net2: "tcp", laddr2: "0.0.0.0", wildcard: true, xerr: syscall.EADDRINUSE},
-	{net1: "tcp", laddr1: "[::ffff:0.0.0.0]", net2: "tcp", laddr2: "[::]", wildcard: true, xerr: syscall.EADDRINUSE},
-	{net1: "tcp", laddr1: "[::]", net2: "tcp", laddr2: "[::ffff:0.0.0.0]", wildcard: true, xerr: syscall.EADDRINUSE},
-
-	{net1: "tcp4", laddr1: "", net2: "tcp6", laddr2: "", wildcard: true},
-	{net1: "tcp6", laddr1: "", net2: "tcp4", laddr2: "", wildcard: true},
-	{net1: "tcp4", laddr1: "0.0.0.0", net2: "tcp6", laddr2: "[::]", wildcard: true},
-	{net1: "tcp6", laddr1: "[::]", net2: "tcp4", laddr2: "0.0.0.0", wildcard: true},
-
-	{net1: "tcp", laddr1: "127.0.0.1", net2: "tcp", laddr2: "[::1]"},
-	{net1: "tcp", laddr1: "[::1]", net2: "tcp", laddr2: "127.0.0.1"},
-	{net1: "tcp4", laddr1: "127.0.0.1", net2: "tcp6", laddr2: "[::1]"},
-	{net1: "tcp6", laddr1: "[::1]", net2: "tcp4", laddr2: "127.0.0.1"},
-}
-
-// TestDualStackTCPListener tests both single and double listen
-// to a test listener with various address families, different
-// listening address and same port.
-func TestDualStackTCPListener(t *testing.T) {
-	if testing.Short() {
-		t.Skip("skipping in -short mode, see issue 5001")
-	}
-	switch runtime.GOOS {
-	case "plan9":
-		t.Skipf("skipping test on %q", runtime.GOOS)
-	}
-	if !supportsIPv6 {
-		t.Skip("ipv6 is not supported")
-	}
-
-	for _, tt := range dualStackListenerTests {
-		if tt.wildcard && !*testExternal {
-			continue
-		}
-		switch runtime.GOOS {
-		case "openbsd":
-			if tt.wildcard && differentWildcardAddr(tt.laddr1, tt.laddr2) {
-				tt.xerr = nil
-			}
-		}
-		l1, port := usableListenPort(t, tt.net1, tt.laddr1)
-		laddr := tt.laddr1 + ":" + port
-		checkFirstListener(t, tt.net1, laddr, l1)
-		laddr = tt.laddr2 + ":" + port
-		l2, err := Listen(tt.net2, laddr)
-		checkDualStackSecondListener(t, tt.net2, laddr, tt.xerr, err, l2)
-		l1.Close()
-	}
-}
-
-// TestDualStackUDPListener tests both single and double listen
-// to a test listener with various address families, differnet
-// listening address and same port.
-func TestDualStackUDPListener(t *testing.T) {
-	switch runtime.GOOS {
-	case "plan9":
-		t.Skipf("skipping test on %q", runtime.GOOS)
-	}
-	if !supportsIPv6 {
-		t.Skip("ipv6 is not supported")
-	}
-
-	toudpnet := func(net string) string {
-		switch net {
-		case "tcp":
-			return "udp"
-		case "tcp4":
-			return "udp4"
-		case "tcp6":
-			return "udp6"
-		}
-		return "<nil>"
-	}
-
-	for _, tt := range dualStackListenerTests {
-		if tt.wildcard && (testing.Short() || !*testExternal) {
-			continue
-		}
-		tt.net1 = toudpnet(tt.net1)
-		tt.net2 = toudpnet(tt.net2)
-		switch runtime.GOOS {
-		case "openbsd":
-			if tt.wildcard && differentWildcardAddr(tt.laddr1, tt.laddr2) {
-				tt.xerr = nil
-			}
-		}
-		l1, port := usableListenPacketPort(t, tt.net1, tt.laddr1)
-		laddr := tt.laddr1 + ":" + port
-		checkFirstListener(t, tt.net1, laddr, l1)
-		laddr = tt.laddr2 + ":" + port
-		l2, err := ListenPacket(tt.net2, laddr)
-		checkDualStackSecondListener(t, tt.net2, laddr, tt.xerr, err, l2)
-		l1.Close()
-	}
-}
-
-func usableListenPort(t *testing.T, net, laddr string) (l Listener, port string) {
-	var nladdr string
-	var err error
-	switch net {
-	default:
-		panic("usableListenPort net=" + net)
-	case "tcp", "tcp4", "tcp6":
-		l, err = Listen(net, laddr+":0")
-		if err != nil {
-			t.Fatalf("Probe Listen(%q, %q) failed: %v", net, laddr, err)
-		}
-		nladdr = l.(*TCPListener).Addr().String()
-	}
-	_, port, err = SplitHostPort(nladdr)
-	if err != nil {
-		t.Fatalf("SplitHostPort failed: %v", err)
-	}
-	return l, port
-}
-
-func usableListenPacketPort(t *testing.T, net, laddr string) (l PacketConn, port string) {
-	var nladdr string
-	var err error
-	switch net {
-	default:
-		panic("usableListenPacketPort net=" + net)
-	case "udp", "udp4", "udp6":
-		l, err = ListenPacket(net, laddr+":0")
-		if err != nil {
-			t.Fatalf("Probe ListenPacket(%q, %q) failed: %v", net, laddr, err)
-		}
-		nladdr = l.(*UDPConn).LocalAddr().String()
-	}
-	_, port, err = SplitHostPort(nladdr)
-	if err != nil {
-		t.Fatalf("SplitHostPort failed: %v", err)
-	}
-	return l, port
-}
-
-func differentWildcardAddr(i, j string) bool {
-	if (i == "" || i == "0.0.0.0" || i == "::ffff:0.0.0.0") && (j == "" || j == "0.0.0.0" || j == "::ffff:0.0.0.0") {
-		return false
-	}
-	if i == "[::]" && j == "[::]" {
-		return false
-	}
-	return true
-}
-
-func checkFirstListener(t *testing.T, net, laddr string, l interface{}) {
-	switch net {
-	case "tcp":
-		fd := l.(*TCPListener).fd
-		checkDualStackAddrFamily(t, net, laddr, fd)
-	case "tcp4":
-		fd := l.(*TCPListener).fd
-		if fd.family != syscall.AF_INET {
-			t.Fatalf("First Listen(%q, %q) returns address family %v, expected %v", net, laddr, fd.family, syscall.AF_INET)
-		}
-	case "tcp6":
-		fd := l.(*TCPListener).fd
-		if fd.family != syscall.AF_INET6 {
-			t.Fatalf("First Listen(%q, %q) returns address family %v, expected %v", net, laddr, fd.family, syscall.AF_INET6)
-		}
-	case "udp":
-		fd := l.(*UDPConn).fd
-		checkDualStackAddrFamily(t, net, laddr, fd)
-	case "udp4":
-		fd := l.(*UDPConn).fd
-		if fd.family != syscall.AF_INET {
-			t.Fatalf("First ListenPacket(%q, %q) returns address family %v, expected %v", net, laddr, fd.family, syscall.AF_INET)
-		}
-	case "udp6":
-		fd := l.(*UDPConn).fd
-		if fd.family != syscall.AF_INET6 {
-			t.Fatalf("First ListenPacket(%q, %q) returns address family %v, expected %v", net, laddr, fd.family, syscall.AF_INET6)
-		}
-	default:
-		t.Fatalf("Unexpected network: %q", net)
-	}
-}
-
-func checkSecondListener(t *testing.T, net, laddr string, err error, l interface{}) {
-	switch net {
-	case "tcp", "tcp4", "tcp6":
-		if err == nil {
-			l.(*TCPListener).Close()
-			t.Fatalf("Second Listen(%q, %q) should fail", net, laddr)
-		}
-	case "udp", "udp4", "udp6":
-		if err == nil {
-			l.(*UDPConn).Close()
-			t.Fatalf("Second ListenPacket(%q, %q) should fail", net, laddr)
-		}
-	default:
-		t.Fatalf("Unexpected network: %q", net)
-	}
-}
-
-func checkDualStackSecondListener(t *testing.T, net, laddr string, xerr, err error, l interface{}) {
-	switch net {
-	case "tcp", "tcp4", "tcp6":
-		if xerr == nil && err != nil || xerr != nil && err == nil {
-			t.Fatalf("Second Listen(%q, %q) returns %v, expected %v", net, laddr, err, xerr)
-		}
-		if err == nil {
-			l.(*TCPListener).Close()
-		}
-	case "udp", "udp4", "udp6":
-		if xerr == nil && err != nil || xerr != nil && err == nil {
-			t.Fatalf("Second ListenPacket(%q, %q) returns %v, expected %v", net, laddr, err, xerr)
-		}
-		if err == nil {
-			l.(*UDPConn).Close()
-		}
-	default:
-		t.Fatalf("Unexpected network: %q", net)
-	}
-}
-
-func checkDualStackAddrFamily(t *testing.T, net, laddr string, fd *netFD) {
-	switch a := fd.laddr.(type) {
-	case *TCPAddr:
-		// If a node under test supports both IPv6 capability
-		// and IPv6 IPv4-mapping capability, we can assume
-		// that the node listens on a wildcard address with an
-		// AF_INET6 socket.
-		if supportsIPv4map && fd.laddr.(*TCPAddr).isWildcard() {
-			if fd.family != syscall.AF_INET6 {
-				t.Fatalf("Listen(%q, %q) returns address family %v, expected %v", net, laddr, fd.family, syscall.AF_INET6)
-			}
-		} else {
-			if fd.family != a.family() {
-				t.Fatalf("Listen(%q, %q) returns address family %v, expected %v", net, laddr, fd.family, a.family())
-			}
-		}
-	case *UDPAddr:
-		// If a node under test supports both IPv6 capability
-		// and IPv6 IPv4-mapping capability, we can assume
-		// that the node listens on a wildcard address with an
-		// AF_INET6 socket.
-		if supportsIPv4map && fd.laddr.(*UDPAddr).isWildcard() {
-			if fd.family != syscall.AF_INET6 {
-				t.Fatalf("ListenPacket(%q, %q) returns address family %v, expected %v", net, laddr, fd.family, syscall.AF_INET6)
-			}
-		} else {
-			if fd.family != a.family() {
-				t.Fatalf("ListenPacket(%q, %q) returns address family %v, expected %v", net, laddr, fd.family, a.family())
-			}
-		}
-	default:
-		t.Fatalf("Unexpected protocol address type: %T", a)
-	}
-}
-
-var prohibitionaryDialArgTests = []struct {
-	net  string
-	addr string
-}{
-	{"tcp6", "127.0.0.1"},
-	{"tcp6", "[::ffff:127.0.0.1]"},
-}
-
-func TestProhibitionaryDialArgs(t *testing.T) {
-	switch runtime.GOOS {
-	case "plan9":
-		t.Skipf("skipping test on %q", runtime.GOOS)
-	}
-	// This test requires both IPv6 and IPv6 IPv4-mapping functionality.
-	if !supportsIPv4map || testing.Short() || !*testExternal {
-		return
-	}
-
-	l, port := usableListenPort(t, "tcp", "[::]")
-	defer l.Close()
-
-	for _, tt := range prohibitionaryDialArgTests {
-		c, err := Dial(tt.net, tt.addr+":"+port)
-		if err == nil {
-			c.Close()
-			t.Fatalf("Dial(%q, %q) should fail", tt.net, tt.addr)
-		}
-	}
-}
-
-func TestWildWildcardListener(t *testing.T) {
-	switch runtime.GOOS {
-	case "plan9":
-		t.Skipf("skipping test on %q", runtime.GOOS)
-	}
-
-	if testing.Short() || !*testExternal {
-		t.Skip("skipping test to avoid external network")
-	}
-
-	defer func() {
-		if p := recover(); p != nil {
-			t.Fatalf("Listen, ListenPacket or protocol-specific Listen panicked: %v", p)
-		}
-	}()
-
-	if ln, err := Listen("tcp", ""); err == nil {
-		ln.Close()
-	}
-	if ln, err := ListenPacket("udp", ""); err == nil {
-		ln.Close()
-	}
-	if ln, err := ListenTCP("tcp", nil); err == nil {
-		ln.Close()
-	}
-	if ln, err := ListenUDP("udp", nil); err == nil {
-		ln.Close()
-	}
-	if ln, err := ListenIP("ip:icmp", nil); err == nil {
-		ln.Close()
-	}
-}
diff --git a/src/pkg/net/unix_test.go b/src/pkg/net/unix_test.go
deleted file mode 100644
index 05643dd..0000000
--- a/src/pkg/net/unix_test.go
+++ /dev/null
@@ -1,326 +0,0 @@
-// Copyright 2013 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build !nacl,!plan9,!windows
-
-package net
-
-import (
-	"bytes"
-	"os"
-	"reflect"
-	"runtime"
-	"syscall"
-	"testing"
-	"time"
-)
-
-func TestReadUnixgramWithUnnamedSocket(t *testing.T) {
-	addr := testUnixAddr()
-	la, err := ResolveUnixAddr("unixgram", addr)
-	if err != nil {
-		t.Fatalf("ResolveUnixAddr failed: %v", err)
-	}
-	c, err := ListenUnixgram("unixgram", la)
-	if err != nil {
-		t.Fatalf("ListenUnixgram failed: %v", err)
-	}
-	defer func() {
-		c.Close()
-		os.Remove(addr)
-	}()
-
-	off := make(chan bool)
-	data := [5]byte{1, 2, 3, 4, 5}
-	go func() {
-		defer func() { off <- true }()
-		s, err := syscall.Socket(syscall.AF_UNIX, syscall.SOCK_DGRAM, 0)
-		if err != nil {
-			t.Errorf("syscall.Socket failed: %v", err)
-			return
-		}
-		defer syscall.Close(s)
-		rsa := &syscall.SockaddrUnix{Name: addr}
-		if err := syscall.Sendto(s, data[:], 0, rsa); err != nil {
-			t.Errorf("syscall.Sendto failed: %v", err)
-			return
-		}
-	}()
-
-	<-off
-	b := make([]byte, 64)
-	c.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
-	n, from, err := c.ReadFrom(b)
-	if err != nil {
-		t.Fatalf("UnixConn.ReadFrom failed: %v", err)
-	}
-	if from != nil {
-		t.Fatalf("neighbor address is %v", from)
-	}
-	if !bytes.Equal(b[:n], data[:]) {
-		t.Fatalf("got %v, want %v", b[:n], data[:])
-	}
-}
-
-func TestReadUnixgramWithZeroBytesBuffer(t *testing.T) {
-	// issue 4352: Recvfrom failed with "address family not
-	// supported by protocol family" if zero-length buffer provided
-
-	addr := testUnixAddr()
-	la, err := ResolveUnixAddr("unixgram", addr)
-	if err != nil {
-		t.Fatalf("ResolveUnixAddr failed: %v", err)
-	}
-	c, err := ListenUnixgram("unixgram", la)
-	if err != nil {
-		t.Fatalf("ListenUnixgram failed: %v", err)
-	}
-	defer func() {
-		c.Close()
-		os.Remove(addr)
-	}()
-
-	off := make(chan bool)
-	go func() {
-		defer func() { off <- true }()
-		c, err := DialUnix("unixgram", nil, la)
-		if err != nil {
-			t.Errorf("DialUnix failed: %v", err)
-			return
-		}
-		defer c.Close()
-		if _, err := c.Write([]byte{1, 2, 3, 4, 5}); err != nil {
-			t.Errorf("UnixConn.Write failed: %v", err)
-			return
-		}
-	}()
-
-	<-off
-	c.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
-	_, from, err := c.ReadFrom(nil)
-	if err != nil {
-		t.Fatalf("UnixConn.ReadFrom failed: %v", err)
-	}
-	if from != nil {
-		t.Fatalf("neighbor address is %v", from)
-	}
-}
-
-func TestUnixgramAutobind(t *testing.T) {
-	if runtime.GOOS != "linux" {
-		t.Skip("skipping: autobind is linux only")
-	}
-
-	laddr := &UnixAddr{Name: "", Net: "unixgram"}
-	c1, err := ListenUnixgram("unixgram", laddr)
-	if err != nil {
-		t.Fatalf("ListenUnixgram failed: %v", err)
-	}
-	defer c1.Close()
-
-	// retrieve the autobind address
-	autoAddr := c1.LocalAddr().(*UnixAddr)
-	if len(autoAddr.Name) <= 1 {
-		t.Fatalf("invalid autobind address: %v", autoAddr)
-	}
-	if autoAddr.Name[0] != '@' {
-		t.Fatalf("invalid autobind address: %v", autoAddr)
-	}
-
-	c2, err := DialUnix("unixgram", nil, autoAddr)
-	if err != nil {
-		t.Fatalf("DialUnix failed: %v", err)
-	}
-	defer c2.Close()
-
-	if !reflect.DeepEqual(c1.LocalAddr(), c2.RemoteAddr()) {
-		t.Fatalf("expected autobind address %v, got %v", c1.LocalAddr(), c2.RemoteAddr())
-	}
-}
-
-func TestUnixAutobindClose(t *testing.T) {
-	if runtime.GOOS != "linux" {
-		t.Skip("skipping: autobind is linux only")
-	}
-	laddr := &UnixAddr{Name: "", Net: "unix"}
-	ln, err := ListenUnix("unix", laddr)
-	if err != nil {
-		t.Fatalf("ListenUnix failed: %v", err)
-	}
-	ln.Close()
-}
-
-func TestUnixgramWrite(t *testing.T) {
-	addr := testUnixAddr()
-	laddr, err := ResolveUnixAddr("unixgram", addr)
-	if err != nil {
-		t.Fatalf("ResolveUnixAddr failed: %v", err)
-	}
-	c, err := ListenPacket("unixgram", addr)
-	if err != nil {
-		t.Fatalf("ListenPacket failed: %v", err)
-	}
-	defer os.Remove(addr)
-	defer c.Close()
-
-	testUnixgramWriteConn(t, laddr)
-	testUnixgramWritePacketConn(t, laddr)
-}
-
-func testUnixgramWriteConn(t *testing.T, raddr *UnixAddr) {
-	c, err := Dial("unixgram", raddr.String())
-	if err != nil {
-		t.Fatalf("Dial failed: %v", err)
-	}
-	defer c.Close()
-
-	if _, err := c.(*UnixConn).WriteToUnix([]byte("Connection-oriented mode socket"), raddr); err == nil {
-		t.Fatal("WriteToUnix should fail")
-	} else if err.(*OpError).Err != ErrWriteToConnected {
-		t.Fatalf("WriteToUnix should fail as ErrWriteToConnected: %v", err)
-	}
-	if _, err = c.(*UnixConn).WriteTo([]byte("Connection-oriented mode socket"), raddr); err == nil {
-		t.Fatal("WriteTo should fail")
-	} else if err.(*OpError).Err != ErrWriteToConnected {
-		t.Fatalf("WriteTo should fail as ErrWriteToConnected: %v", err)
-	}
-	if _, _, err = c.(*UnixConn).WriteMsgUnix([]byte("Connection-oriented mode socket"), nil, raddr); err == nil {
-		t.Fatal("WriteTo should fail")
-	} else if err.(*OpError).Err != ErrWriteToConnected {
-		t.Fatalf("WriteMsgUnix should fail as ErrWriteToConnected: %v", err)
-	}
-	if _, err := c.Write([]byte("Connection-oriented mode socket")); err != nil {
-		t.Fatalf("Write failed: %v", err)
-	}
-}
-
-func testUnixgramWritePacketConn(t *testing.T, raddr *UnixAddr) {
-	addr := testUnixAddr()
-	c, err := ListenPacket("unixgram", addr)
-	if err != nil {
-		t.Fatalf("ListenPacket failed: %v", err)
-	}
-	defer os.Remove(addr)
-	defer c.Close()
-
-	if _, err := c.(*UnixConn).WriteToUnix([]byte("Connectionless mode socket"), raddr); err != nil {
-		t.Fatalf("WriteToUnix failed: %v", err)
-	}
-	if _, err := c.WriteTo([]byte("Connectionless mode socket"), raddr); err != nil {
-		t.Fatalf("WriteTo failed: %v", err)
-	}
-	if _, _, err := c.(*UnixConn).WriteMsgUnix([]byte("Connectionless mode socket"), nil, raddr); err != nil {
-		t.Fatalf("WriteMsgUnix failed: %v", err)
-	}
-	if _, err := c.(*UnixConn).Write([]byte("Connectionless mode socket")); err == nil {
-		t.Fatal("Write should fail")
-	}
-}
-
-func TestUnixConnLocalAndRemoteNames(t *testing.T) {
-	for _, laddr := range []string{"", testUnixAddr()} {
-		laddr := laddr
-		taddr := testUnixAddr()
-		ta, err := ResolveUnixAddr("unix", taddr)
-		if err != nil {
-			t.Fatalf("ResolveUnixAddr failed: %v", err)
-		}
-		ln, err := ListenUnix("unix", ta)
-		if err != nil {
-			t.Fatalf("ListenUnix failed: %v", err)
-		}
-		defer func() {
-			ln.Close()
-			os.Remove(taddr)
-		}()
-
-		done := make(chan int)
-		go transponder(t, ln, done)
-
-		la, err := ResolveUnixAddr("unix", laddr)
-		if err != nil {
-			t.Fatalf("ResolveUnixAddr failed: %v", err)
-		}
-		c, err := DialUnix("unix", la, ta)
-		if err != nil {
-			t.Fatalf("DialUnix failed: %v", err)
-		}
-		defer func() {
-			c.Close()
-			if la != nil {
-				defer os.Remove(laddr)
-			}
-		}()
-		if _, err := c.Write([]byte("UNIXCONN LOCAL AND REMOTE NAME TEST")); err != nil {
-			t.Fatalf("UnixConn.Write failed: %v", err)
-		}
-
-		if runtime.GOOS == "linux" && laddr == "" {
-			laddr = "@" // autobind feature
-		}
-		var connAddrs = [3]struct{ got, want Addr }{
-			{ln.Addr(), ta},
-			{c.LocalAddr(), &UnixAddr{Name: laddr, Net: "unix"}},
-			{c.RemoteAddr(), ta},
-		}
-		for _, ca := range connAddrs {
-			if !reflect.DeepEqual(ca.got, ca.want) {
-				t.Fatalf("got %#v, expected %#v", ca.got, ca.want)
-			}
-		}
-
-		<-done
-	}
-}
-
-func TestUnixgramConnLocalAndRemoteNames(t *testing.T) {
-	for _, laddr := range []string{"", testUnixAddr()} {
-		laddr := laddr
-		taddr := testUnixAddr()
-		ta, err := ResolveUnixAddr("unixgram", taddr)
-		if err != nil {
-			t.Fatalf("ResolveUnixAddr failed: %v", err)
-		}
-		c1, err := ListenUnixgram("unixgram", ta)
-		if err != nil {
-			t.Fatalf("ListenUnixgram failed: %v", err)
-		}
-		defer func() {
-			c1.Close()
-			os.Remove(taddr)
-		}()
-
-		var la *UnixAddr
-		if laddr != "" {
-			if la, err = ResolveUnixAddr("unixgram", laddr); err != nil {
-				t.Fatalf("ResolveUnixAddr failed: %v", err)
-			}
-		}
-		c2, err := DialUnix("unixgram", la, ta)
-		if err != nil {
-			t.Fatalf("DialUnix failed: %v", err)
-		}
-		defer func() {
-			c2.Close()
-			if la != nil {
-				defer os.Remove(laddr)
-			}
-		}()
-
-		if runtime.GOOS == "linux" && laddr == "" {
-			laddr = "@" // autobind feature
-		}
-		var connAddrs = [4]struct{ got, want Addr }{
-			{c1.LocalAddr(), ta},
-			{c1.RemoteAddr(), nil},
-			{c2.LocalAddr(), &UnixAddr{Name: laddr, Net: "unixgram"}},
-			{c2.RemoteAddr(), ta},
-		}
-		for _, ca := range connAddrs {
-			if !reflect.DeepEqual(ca.got, ca.want) {
-				t.Fatalf("got %#v, expected %#v", ca.got, ca.want)
-			}
-		}
-	}
-}
diff --git a/src/pkg/net/unixsock_posix.go b/src/pkg/net/unixsock_posix.go
deleted file mode 100644
index 2610779..0000000
--- a/src/pkg/net/unixsock_posix.go
+++ /dev/null
@@ -1,373 +0,0 @@
-// Copyright 2009 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris windows
-
-package net
-
-import (
-	"errors"
-	"os"
-	"syscall"
-	"time"
-)
-
-func unixSocket(net string, laddr, raddr sockaddr, mode string, deadline time.Time) (*netFD, error) {
-	var sotype int
-	switch net {
-	case "unix":
-		sotype = syscall.SOCK_STREAM
-	case "unixgram":
-		sotype = syscall.SOCK_DGRAM
-	case "unixpacket":
-		sotype = syscall.SOCK_SEQPACKET
-	default:
-		return nil, UnknownNetworkError(net)
-	}
-
-	switch mode {
-	case "dial":
-		if laddr != nil && laddr.isWildcard() {
-			laddr = nil
-		}
-		if raddr != nil && raddr.isWildcard() {
-			raddr = nil
-		}
-		if raddr == nil && (sotype != syscall.SOCK_DGRAM || laddr == nil) {
-			return nil, errMissingAddress
-		}
-	case "listen":
-	default:
-		return nil, errors.New("unknown mode: " + mode)
-	}
-
-	f := sockaddrToUnix
-	if sotype == syscall.SOCK_DGRAM {
-		f = sockaddrToUnixgram
-	} else if sotype == syscall.SOCK_SEQPACKET {
-		f = sockaddrToUnixpacket
-	}
-
-	fd, err := socket(net, syscall.AF_UNIX, sotype, 0, false, laddr, raddr, deadline, f)
-	if err != nil {
-		return nil, err
-	}
-	return fd, nil
-}
-
-func sockaddrToUnix(sa syscall.Sockaddr) Addr {
-	if s, ok := sa.(*syscall.SockaddrUnix); ok {
-		return &UnixAddr{Name: s.Name, Net: "unix"}
-	}
-	return nil
-}
-
-func sockaddrToUnixgram(sa syscall.Sockaddr) Addr {
-	if s, ok := sa.(*syscall.SockaddrUnix); ok {
-		return &UnixAddr{Name: s.Name, Net: "unixgram"}
-	}
-	return nil
-}
-
-func sockaddrToUnixpacket(sa syscall.Sockaddr) Addr {
-	if s, ok := sa.(*syscall.SockaddrUnix); ok {
-		return &UnixAddr{Name: s.Name, Net: "unixpacket"}
-	}
-	return nil
-}
-
-func sotypeToNet(sotype int) string {
-	switch sotype {
-	case syscall.SOCK_STREAM:
-		return "unix"
-	case syscall.SOCK_DGRAM:
-		return "unixgram"
-	case syscall.SOCK_SEQPACKET:
-		return "unixpacket"
-	default:
-		panic("sotypeToNet unknown socket type")
-	}
-}
-
-func (a *UnixAddr) family() int {
-	return syscall.AF_UNIX
-}
-
-func (a *UnixAddr) isWildcard() bool {
-	return a == nil || a.Name == ""
-}
-
-func (a *UnixAddr) sockaddr(family int) (syscall.Sockaddr, error) {
-	if a == nil {
-		return nil, nil
-	}
-	return &syscall.SockaddrUnix{Name: a.Name}, nil
-}
-
-// UnixConn is an implementation of the Conn interface for connections
-// to Unix domain sockets.
-type UnixConn struct {
-	conn
-}
-
-func newUnixConn(fd *netFD) *UnixConn { return &UnixConn{conn{fd}} }
-
-// ReadFromUnix reads a packet from c, copying the payload into b.  It
-// returns the number of bytes copied into b and the source address of
-// the packet.
-//
-// ReadFromUnix can be made to time out and return an error with
-// Timeout() == true after a fixed time limit; see SetDeadline and
-// SetReadDeadline.
-func (c *UnixConn) ReadFromUnix(b []byte) (n int, addr *UnixAddr, err error) {
-	if !c.ok() {
-		return 0, nil, syscall.EINVAL
-	}
-	n, sa, err := c.fd.readFrom(b)
-	switch sa := sa.(type) {
-	case *syscall.SockaddrUnix:
-		if sa.Name != "" {
-			addr = &UnixAddr{Name: sa.Name, Net: sotypeToNet(c.fd.sotype)}
-		}
-	}
-	return
-}
-
-// ReadFrom implements the PacketConn ReadFrom method.
-func (c *UnixConn) ReadFrom(b []byte) (int, Addr, error) {
-	if !c.ok() {
-		return 0, nil, syscall.EINVAL
-	}
-	n, addr, err := c.ReadFromUnix(b)
-	return n, addr.toAddr(), err
-}
-
-// ReadMsgUnix reads a packet from c, copying the payload into b and
-// the associated out-of-band data into oob.  It returns the number of
-// bytes copied into b, the number of bytes copied into oob, the flags
-// that were set on the packet, and the source address of the packet.
-func (c *UnixConn) ReadMsgUnix(b, oob []byte) (n, oobn, flags int, addr *UnixAddr, err error) {
-	if !c.ok() {
-		return 0, 0, 0, nil, syscall.EINVAL
-	}
-	n, oobn, flags, sa, err := c.fd.readMsg(b, oob)
-	switch sa := sa.(type) {
-	case *syscall.SockaddrUnix:
-		if sa.Name != "" {
-			addr = &UnixAddr{Name: sa.Name, Net: sotypeToNet(c.fd.sotype)}
-		}
-	}
-	return
-}
-
-// WriteToUnix writes a packet to addr via c, copying the payload from b.
-//
-// WriteToUnix can be made to time out and return an error with
-// Timeout() == true after a fixed time limit; see SetDeadline and
-// SetWriteDeadline.  On packet-oriented connections, write timeouts
-// are rare.
-func (c *UnixConn) WriteToUnix(b []byte, addr *UnixAddr) (n int, err error) {
-	if !c.ok() {
-		return 0, syscall.EINVAL
-	}
-	if c.fd.isConnected {
-		return 0, &OpError{Op: "write", Net: c.fd.net, Addr: addr, Err: ErrWriteToConnected}
-	}
-	if addr == nil {
-		return 0, &OpError{Op: "write", Net: c.fd.net, Addr: nil, Err: errMissingAddress}
-	}
-	if addr.Net != sotypeToNet(c.fd.sotype) {
-		return 0, syscall.EAFNOSUPPORT
-	}
-	sa := &syscall.SockaddrUnix{Name: addr.Name}
-	return c.fd.writeTo(b, sa)
-}
-
-// WriteTo implements the PacketConn WriteTo method.
-func (c *UnixConn) WriteTo(b []byte, addr Addr) (n int, err error) {
-	if !c.ok() {
-		return 0, syscall.EINVAL
-	}
-	a, ok := addr.(*UnixAddr)
-	if !ok {
-		return 0, &OpError{"write", c.fd.net, addr, syscall.EINVAL}
-	}
-	return c.WriteToUnix(b, a)
-}
-
-// WriteMsgUnix writes a packet to addr via c, copying the payload
-// from b and the associated out-of-band data from oob.  It returns
-// the number of payload and out-of-band bytes written.
-func (c *UnixConn) WriteMsgUnix(b, oob []byte, addr *UnixAddr) (n, oobn int, err error) {
-	if !c.ok() {
-		return 0, 0, syscall.EINVAL
-	}
-	if c.fd.sotype == syscall.SOCK_DGRAM && c.fd.isConnected {
-		return 0, 0, &OpError{Op: "write", Net: c.fd.net, Addr: addr, Err: ErrWriteToConnected}
-	}
-	if addr != nil {
-		if addr.Net != sotypeToNet(c.fd.sotype) {
-			return 0, 0, syscall.EAFNOSUPPORT
-		}
-		sa := &syscall.SockaddrUnix{Name: addr.Name}
-		return c.fd.writeMsg(b, oob, sa)
-	}
-	return c.fd.writeMsg(b, oob, nil)
-}
-
-// CloseRead shuts down the reading side of the Unix domain connection.
-// Most callers should just use Close.
-func (c *UnixConn) CloseRead() error {
-	if !c.ok() {
-		return syscall.EINVAL
-	}
-	return c.fd.closeRead()
-}
-
-// CloseWrite shuts down the writing side of the Unix domain connection.
-// Most callers should just use Close.
-func (c *UnixConn) CloseWrite() error {
-	if !c.ok() {
-		return syscall.EINVAL
-	}
-	return c.fd.closeWrite()
-}
-
-// DialUnix connects to the remote address raddr on the network net,
-// which must be "unix", "unixgram" or "unixpacket".  If laddr is not
-// nil, it is used as the local address for the connection.
-func DialUnix(net string, laddr, raddr *UnixAddr) (*UnixConn, error) {
-	switch net {
-	case "unix", "unixgram", "unixpacket":
-	default:
-		return nil, &OpError{Op: "dial", Net: net, Addr: raddr, Err: UnknownNetworkError(net)}
-	}
-	return dialUnix(net, laddr, raddr, noDeadline)
-}
-
-func dialUnix(net string, laddr, raddr *UnixAddr, deadline time.Time) (*UnixConn, error) {
-	fd, err := unixSocket(net, laddr, raddr, "dial", deadline)
-	if err != nil {
-		return nil, &OpError{Op: "dial", Net: net, Addr: raddr, Err: err}
-	}
-	return newUnixConn(fd), nil
-}
-
-// UnixListener is a Unix domain socket listener.  Clients should
-// typically use variables of type Listener instead of assuming Unix
-// domain sockets.
-type UnixListener struct {
-	fd   *netFD
-	path string
-}
-
-// ListenUnix announces on the Unix domain socket laddr and returns a
-// Unix listener.  The network net must be "unix" or "unixpacket".
-func ListenUnix(net string, laddr *UnixAddr) (*UnixListener, error) {
-	switch net {
-	case "unix", "unixpacket":
-	default:
-		return nil, &OpError{Op: "listen", Net: net, Addr: laddr, Err: UnknownNetworkError(net)}
-	}
-	if laddr == nil {
-		return nil, &OpError{Op: "listen", Net: net, Addr: nil, Err: errMissingAddress}
-	}
-	fd, err := unixSocket(net, laddr, nil, "listen", noDeadline)
-	if err != nil {
-		return nil, &OpError{Op: "listen", Net: net, Addr: laddr, Err: err}
-	}
-	return &UnixListener{fd, fd.laddr.String()}, nil
-}
-
-// AcceptUnix accepts the next incoming call and returns the new
-// connection.
-func (l *UnixListener) AcceptUnix() (*UnixConn, error) {
-	if l == nil || l.fd == nil {
-		return nil, syscall.EINVAL
-	}
-	toAddr := sockaddrToUnix
-	if l.fd.sotype == syscall.SOCK_SEQPACKET {
-		toAddr = sockaddrToUnixpacket
-	}
-	fd, err := l.fd.accept(toAddr)
-	if err != nil {
-		return nil, err
-	}
-	c := newUnixConn(fd)
-	return c, nil
-}
-
-// Accept implements the Accept method in the Listener interface; it
-// waits for the next call and returns a generic Conn.
-func (l *UnixListener) Accept() (c Conn, err error) {
-	c1, err := l.AcceptUnix()
-	if err != nil {
-		return nil, err
-	}
-	return c1, nil
-}
-
-// Close stops listening on the Unix address.  Already accepted
-// connections are not closed.
-func (l *UnixListener) Close() error {
-	if l == nil || l.fd == nil {
-		return syscall.EINVAL
-	}
-
-	// The operating system doesn't clean up
-	// the file that announcing created, so
-	// we have to clean it up ourselves.
-	// There's a race here--we can't know for
-	// sure whether someone else has come along
-	// and replaced our socket name already--
-	// but this sequence (remove then close)
-	// is at least compatible with the auto-remove
-	// sequence in ListenUnix.  It's only non-Go
-	// programs that can mess us up.
-	if l.path[0] != '@' {
-		syscall.Unlink(l.path)
-	}
-	return l.fd.Close()
-}
-
-// Addr returns the listener's network address.
-func (l *UnixListener) Addr() Addr { return l.fd.laddr }
-
-// SetDeadline sets the deadline associated with the listener.
-// A zero time value disables the deadline.
-func (l *UnixListener) SetDeadline(t time.Time) (err error) {
-	if l == nil || l.fd == nil {
-		return syscall.EINVAL
-	}
-	return l.fd.setDeadline(t)
-}
-
-// File returns a copy of the underlying os.File, set to blocking
-// mode.  It is the caller's responsibility to close f when finished.
-// Closing l does not affect f, and closing f does not affect l.
-//
-// The returned os.File's file descriptor is different from the
-// connection's.  Attempting to change properties of the original
-// using this duplicate may or may not have the desired effect.
-func (l *UnixListener) File() (f *os.File, err error) { return l.fd.dup() }
-
-// ListenUnixgram listens for incoming Unix datagram packets addressed
-// to the local address laddr.  The network net must be "unixgram".
-// The returned connection's ReadFrom and WriteTo methods can be used
-// to receive and send packets with per-packet addressing.
-func ListenUnixgram(net string, laddr *UnixAddr) (*UnixConn, error) {
-	switch net {
-	case "unixgram":
-	default:
-		return nil, &OpError{Op: "listen", Net: net, Addr: laddr, Err: UnknownNetworkError(net)}
-	}
-	if laddr == nil {
-		return nil, &OpError{Op: "listen", Net: net, Addr: nil, Err: errMissingAddress}
-	}
-	fd, err := unixSocket(net, laddr, nil, "listen", noDeadline)
-	if err != nil {
-		return nil, &OpError{Op: "listen", Net: net, Addr: laddr, Err: err}
-	}
-	return newUnixConn(fd), nil
-}
diff --git a/src/pkg/net/url/example_test.go b/src/pkg/net/url/example_test.go
deleted file mode 100644
index 56c5dc6..0000000
--- a/src/pkg/net/url/example_test.go
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package url_test
-
-import (
-	"fmt"
-	"log"
-	"net/url"
-)
-
-func ExampleValues() {
-	v := url.Values{}
-	v.Set("name", "Ava")
-	v.Add("friend", "Jess")
-	v.Add("friend", "Sarah")
-	v.Add("friend", "Zoe")
-	// v.Encode() == "name=Ava&friend=Jess&friend=Sarah&friend=Zoe"
-	fmt.Println(v.Get("name"))
-	fmt.Println(v.Get("friend"))
-	fmt.Println(v["friend"])
-	// Output:
-	// Ava
-	// Jess
-	// [Jess Sarah Zoe]
-}
-
-func ExampleURL() {
-	u, err := url.Parse("http://bing.com/search?q=dotnet")
-	if err != nil {
-		log.Fatal(err)
-	}
-	u.Scheme = "https"
-	u.Host = "google.com"
-	q := u.Query()
-	q.Set("q", "golang")
-	u.RawQuery = q.Encode()
-	fmt.Println(u)
-	// Output: https://google.com/search?q=golang
-}
diff --git a/src/pkg/net/url/url.go b/src/pkg/net/url/url.go
deleted file mode 100644
index 75f650a..0000000
--- a/src/pkg/net/url/url.go
+++ /dev/null
@@ -1,700 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package url parses URLs and implements query escaping.
-// See RFC 3986.
-package url
-
-import (
-	"bytes"
-	"errors"
-	"sort"
-	"strconv"
-	"strings"
-)
-
-// Error reports an error and the operation and URL that caused it.
-type Error struct {
-	Op  string
-	URL string
-	Err error
-}
-
-func (e *Error) Error() string { return e.Op + " " + e.URL + ": " + e.Err.Error() }
-
-func ishex(c byte) bool {
-	switch {
-	case '0' <= c && c <= '9':
-		return true
-	case 'a' <= c && c <= 'f':
-		return true
-	case 'A' <= c && c <= 'F':
-		return true
-	}
-	return false
-}
-
-func unhex(c byte) byte {
-	switch {
-	case '0' <= c && c <= '9':
-		return c - '0'
-	case 'a' <= c && c <= 'f':
-		return c - 'a' + 10
-	case 'A' <= c && c <= 'F':
-		return c - 'A' + 10
-	}
-	return 0
-}
-
-type encoding int
-
-const (
-	encodePath encoding = 1 + iota
-	encodeUserPassword
-	encodeQueryComponent
-	encodeFragment
-)
-
-type EscapeError string
-
-func (e EscapeError) Error() string {
-	return "invalid URL escape " + strconv.Quote(string(e))
-}
-
-// Return true if the specified character should be escaped when
-// appearing in a URL string, according to RFC 3986.
-// When 'all' is true the full range of reserved characters are matched.
-func shouldEscape(c byte, mode encoding) bool {
-	// §2.3 Unreserved characters (alphanum)
-	if 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || '0' <= c && c <= '9' {
-		return false
-	}
-
-	switch c {
-	case '-', '_', '.', '~': // §2.3 Unreserved characters (mark)
-		return false
-
-	case '$', '&', '+', ',', '/', ':', ';', '=', '?', '@': // §2.2 Reserved characters (reserved)
-		// Different sections of the URL allow a few of
-		// the reserved characters to appear unescaped.
-		switch mode {
-		case encodePath: // §3.3
-			// The RFC allows : @ & = + $ but saves / ; , for assigning
-			// meaning to individual path segments. This package
-			// only manipulates the path as a whole, so we allow those
-			// last two as well. That leaves only ? to escape.
-			return c == '?'
-
-		case encodeUserPassword: // §3.2.2
-			// The RFC allows ; : & = + $ , in userinfo, so we must escape only @ and /.
-			// The parsing of userinfo treats : as special so we must escape that too.
-			return c == '@' || c == '/' || c == ':'
-
-		case encodeQueryComponent: // §3.4
-			// The RFC reserves (so we must escape) everything.
-			return true
-
-		case encodeFragment: // §4.1
-			// The RFC text is silent but the grammar allows
-			// everything, so escape nothing.
-			return false
-		}
-	}
-
-	// Everything else must be escaped.
-	return true
-}
-
-// QueryUnescape does the inverse transformation of QueryEscape, converting
-// %AB into the byte 0xAB and '+' into ' ' (space). It returns an error if
-// any % is not followed by two hexadecimal digits.
-func QueryUnescape(s string) (string, error) {
-	return unescape(s, encodeQueryComponent)
-}
-
-// unescape unescapes a string; the mode specifies
-// which section of the URL string is being unescaped.
-func unescape(s string, mode encoding) (string, error) {
-	// Count %, check that they're well-formed.
-	n := 0
-	hasPlus := false
-	for i := 0; i < len(s); {
-		switch s[i] {
-		case '%':
-			n++
-			if i+2 >= len(s) || !ishex(s[i+1]) || !ishex(s[i+2]) {
-				s = s[i:]
-				if len(s) > 3 {
-					s = s[0:3]
-				}
-				return "", EscapeError(s)
-			}
-			i += 3
-		case '+':
-			hasPlus = mode == encodeQueryComponent
-			i++
-		default:
-			i++
-		}
-	}
-
-	if n == 0 && !hasPlus {
-		return s, nil
-	}
-
-	t := make([]byte, len(s)-2*n)
-	j := 0
-	for i := 0; i < len(s); {
-		switch s[i] {
-		case '%':
-			t[j] = unhex(s[i+1])<<4 | unhex(s[i+2])
-			j++
-			i += 3
-		case '+':
-			if mode == encodeQueryComponent {
-				t[j] = ' '
-			} else {
-				t[j] = '+'
-			}
-			j++
-			i++
-		default:
-			t[j] = s[i]
-			j++
-			i++
-		}
-	}
-	return string(t), nil
-}
-
-// QueryEscape escapes the string so it can be safely placed
-// inside a URL query.
-func QueryEscape(s string) string {
-	return escape(s, encodeQueryComponent)
-}
-
-func escape(s string, mode encoding) string {
-	spaceCount, hexCount := 0, 0
-	for i := 0; i < len(s); i++ {
-		c := s[i]
-		if shouldEscape(c, mode) {
-			if c == ' ' && mode == encodeQueryComponent {
-				spaceCount++
-			} else {
-				hexCount++
-			}
-		}
-	}
-
-	if spaceCount == 0 && hexCount == 0 {
-		return s
-	}
-
-	t := make([]byte, len(s)+2*hexCount)
-	j := 0
-	for i := 0; i < len(s); i++ {
-		switch c := s[i]; {
-		case c == ' ' && mode == encodeQueryComponent:
-			t[j] = '+'
-			j++
-		case shouldEscape(c, mode):
-			t[j] = '%'
-			t[j+1] = "0123456789ABCDEF"[c>>4]
-			t[j+2] = "0123456789ABCDEF"[c&15]
-			j += 3
-		default:
-			t[j] = s[i]
-			j++
-		}
-	}
-	return string(t)
-}
-
-// A URL represents a parsed URL (technically, a URI reference).
-// The general form represented is:
-//
-//	scheme://[userinfo@]host/path[?query][#fragment]
-//
-// URLs that do not start with a slash after the scheme are interpreted as:
-//
-//	scheme:opaque[?query][#fragment]
-//
-// Note that the Path field is stored in decoded form: /%47%6f%2f becomes /Go/.
-// A consequence is that it is impossible to tell which slashes in the Path were
-// slashes in the raw URL and which were %2f. This distinction is rarely important,
-// but when it is a client must use other routines to parse the raw URL or construct
-// the parsed URL. For example, an HTTP server can consult req.RequestURI, and
-// an HTTP client can use URL{Host: "example.com", Opaque: "//example.com/Go%2f"}
-// instead of URL{Host: "example.com", Path: "/Go/"}.
-type URL struct {
-	Scheme   string
-	Opaque   string    // encoded opaque data
-	User     *Userinfo // username and password information
-	Host     string    // host or host:port
-	Path     string
-	RawQuery string // encoded query values, without '?'
-	Fragment string // fragment for references, without '#'
-}
-
-// User returns a Userinfo containing the provided username
-// and no password set.
-func User(username string) *Userinfo {
-	return &Userinfo{username, "", false}
-}
-
-// UserPassword returns a Userinfo containing the provided username
-// and password.
-// This functionality should only be used with legacy web sites.
-// RFC 2396 warns that interpreting Userinfo this way
-// ``is NOT RECOMMENDED, because the passing of authentication
-// information in clear text (such as URI) has proven to be a
-// security risk in almost every case where it has been used.''
-func UserPassword(username, password string) *Userinfo {
-	return &Userinfo{username, password, true}
-}
-
-// The Userinfo type is an immutable encapsulation of username and
-// password details for a URL. An existing Userinfo value is guaranteed
-// to have a username set (potentially empty, as allowed by RFC 2396),
-// and optionally a password.
-type Userinfo struct {
-	username    string
-	password    string
-	passwordSet bool
-}
-
-// Username returns the username.
-func (u *Userinfo) Username() string {
-	return u.username
-}
-
-// Password returns the password in case it is set, and whether it is set.
-func (u *Userinfo) Password() (string, bool) {
-	if u.passwordSet {
-		return u.password, true
-	}
-	return "", false
-}
-
-// String returns the encoded userinfo information in the standard form
-// of "username[:password]".
-func (u *Userinfo) String() string {
-	s := escape(u.username, encodeUserPassword)
-	if u.passwordSet {
-		s += ":" + escape(u.password, encodeUserPassword)
-	}
-	return s
-}
-
-// Maybe rawurl is of the form scheme:path.
-// (Scheme must be [a-zA-Z][a-zA-Z0-9+-.]*)
-// If so, return scheme, path; else return "", rawurl.
-func getscheme(rawurl string) (scheme, path string, err error) {
-	for i := 0; i < len(rawurl); i++ {
-		c := rawurl[i]
-		switch {
-		case 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z':
-		// do nothing
-		case '0' <= c && c <= '9' || c == '+' || c == '-' || c == '.':
-			if i == 0 {
-				return "", rawurl, nil
-			}
-		case c == ':':
-			if i == 0 {
-				return "", "", errors.New("missing protocol scheme")
-			}
-			return rawurl[0:i], rawurl[i+1:], nil
-		default:
-			// we have encountered an invalid character,
-			// so there is no valid scheme
-			return "", rawurl, nil
-		}
-	}
-	return "", rawurl, nil
-}
-
-// Maybe s is of the form t c u.
-// If so, return t, c u (or t, u if cutc == true).
-// If not, return s, "".
-func split(s string, c string, cutc bool) (string, string) {
-	i := strings.Index(s, c)
-	if i < 0 {
-		return s, ""
-	}
-	if cutc {
-		return s[0:i], s[i+len(c):]
-	}
-	return s[0:i], s[i:]
-}
-
-// Parse parses rawurl into a URL structure.
-// The rawurl may be relative or absolute.
-func Parse(rawurl string) (url *URL, err error) {
-	// Cut off #frag
-	u, frag := split(rawurl, "#", true)
-	if url, err = parse(u, false); err != nil {
-		return nil, err
-	}
-	if frag == "" {
-		return url, nil
-	}
-	if url.Fragment, err = unescape(frag, encodeFragment); err != nil {
-		return nil, &Error{"parse", rawurl, err}
-	}
-	return url, nil
-}
-
-// ParseRequestURI parses rawurl into a URL structure.  It assumes that
-// rawurl was received in an HTTP request, so the rawurl is interpreted
-// only as an absolute URI or an absolute path.
-// The string rawurl is assumed not to have a #fragment suffix.
-// (Web browsers strip #fragment before sending the URL to a web server.)
-func ParseRequestURI(rawurl string) (url *URL, err error) {
-	return parse(rawurl, true)
-}
-
-// parse parses a URL from a string in one of two contexts.  If
-// viaRequest is true, the URL is assumed to have arrived via an HTTP request,
-// in which case only absolute URLs or path-absolute relative URLs are allowed.
-// If viaRequest is false, all forms of relative URLs are allowed.
-func parse(rawurl string, viaRequest bool) (url *URL, err error) {
-	var rest string
-
-	if rawurl == "" && viaRequest {
-		err = errors.New("empty url")
-		goto Error
-	}
-	url = new(URL)
-
-	if rawurl == "*" {
-		url.Path = "*"
-		return
-	}
-
-	// Split off possible leading "http:", "mailto:", etc.
-	// Cannot contain escaped characters.
-	if url.Scheme, rest, err = getscheme(rawurl); err != nil {
-		goto Error
-	}
-	url.Scheme = strings.ToLower(url.Scheme)
-
-	rest, url.RawQuery = split(rest, "?", true)
-
-	if !strings.HasPrefix(rest, "/") {
-		if url.Scheme != "" {
-			// We consider rootless paths per RFC 3986 as opaque.
-			url.Opaque = rest
-			return url, nil
-		}
-		if viaRequest {
-			err = errors.New("invalid URI for request")
-			goto Error
-		}
-	}
-
-	if (url.Scheme != "" || !viaRequest && !strings.HasPrefix(rest, "///")) && strings.HasPrefix(rest, "//") {
-		var authority string
-		authority, rest = split(rest[2:], "/", false)
-		url.User, url.Host, err = parseAuthority(authority)
-		if err != nil {
-			goto Error
-		}
-		if strings.Contains(url.Host, "%") {
-			err = errors.New("hexadecimal escape in host")
-			goto Error
-		}
-	}
-	if url.Path, err = unescape(rest, encodePath); err != nil {
-		goto Error
-	}
-	return url, nil
-
-Error:
-	return nil, &Error{"parse", rawurl, err}
-}
-
-func parseAuthority(authority string) (user *Userinfo, host string, err error) {
-	i := strings.LastIndex(authority, "@")
-	if i < 0 {
-		host = authority
-		return
-	}
-	userinfo, host := authority[:i], authority[i+1:]
-	if strings.Index(userinfo, ":") < 0 {
-		if userinfo, err = unescape(userinfo, encodeUserPassword); err != nil {
-			return
-		}
-		user = User(userinfo)
-	} else {
-		username, password := split(userinfo, ":", true)
-		if username, err = unescape(username, encodeUserPassword); err != nil {
-			return
-		}
-		if password, err = unescape(password, encodeUserPassword); err != nil {
-			return
-		}
-		user = UserPassword(username, password)
-	}
-	return
-}
-
-// String reassembles the URL into a valid URL string.
-func (u *URL) String() string {
-	var buf bytes.Buffer
-	if u.Scheme != "" {
-		buf.WriteString(u.Scheme)
-		buf.WriteByte(':')
-	}
-	if u.Opaque != "" {
-		buf.WriteString(u.Opaque)
-	} else {
-		if u.Scheme != "" || u.Host != "" || u.User != nil {
-			buf.WriteString("//")
-			if ui := u.User; ui != nil {
-				buf.WriteString(ui.String())
-				buf.WriteByte('@')
-			}
-			if h := u.Host; h != "" {
-				buf.WriteString(h)
-			}
-		}
-		if u.Path != "" && u.Path[0] != '/' && u.Host != "" {
-			buf.WriteByte('/')
-		}
-		buf.WriteString(escape(u.Path, encodePath))
-	}
-	if u.RawQuery != "" {
-		buf.WriteByte('?')
-		buf.WriteString(u.RawQuery)
-	}
-	if u.Fragment != "" {
-		buf.WriteByte('#')
-		buf.WriteString(escape(u.Fragment, encodeFragment))
-	}
-	return buf.String()
-}
-
-// Values maps a string key to a list of values.
-// It is typically used for query parameters and form values.
-// Unlike in the http.Header map, the keys in a Values map
-// are case-sensitive.
-type Values map[string][]string
-
-// Get gets the first value associated with the given key.
-// If there are no values associated with the key, Get returns
-// the empty string. To access multiple values, use the map
-// directly.
-func (v Values) Get(key string) string {
-	if v == nil {
-		return ""
-	}
-	vs, ok := v[key]
-	if !ok || len(vs) == 0 {
-		return ""
-	}
-	return vs[0]
-}
-
-// Set sets the key to value. It replaces any existing
-// values.
-func (v Values) Set(key, value string) {
-	v[key] = []string{value}
-}
-
-// Add adds the value to key. It appends to any existing
-// values associated with key.
-func (v Values) Add(key, value string) {
-	v[key] = append(v[key], value)
-}
-
-// Del deletes the values associated with key.
-func (v Values) Del(key string) {
-	delete(v, key)
-}
-
-// ParseQuery parses the URL-encoded query string and returns
-// a map listing the values specified for each key.
-// ParseQuery always returns a non-nil map containing all the
-// valid query parameters found; err describes the first decoding error
-// encountered, if any.
-func ParseQuery(query string) (m Values, err error) {
-	m = make(Values)
-	err = parseQuery(m, query)
-	return
-}
-
-func parseQuery(m Values, query string) (err error) {
-	for query != "" {
-		key := query
-		if i := strings.IndexAny(key, "&;"); i >= 0 {
-			key, query = key[:i], key[i+1:]
-		} else {
-			query = ""
-		}
-		if key == "" {
-			continue
-		}
-		value := ""
-		if i := strings.Index(key, "="); i >= 0 {
-			key, value = key[:i], key[i+1:]
-		}
-		key, err1 := QueryUnescape(key)
-		if err1 != nil {
-			if err == nil {
-				err = err1
-			}
-			continue
-		}
-		value, err1 = QueryUnescape(value)
-		if err1 != nil {
-			if err == nil {
-				err = err1
-			}
-			continue
-		}
-		m[key] = append(m[key], value)
-	}
-	return err
-}
-
-// Encode encodes the values into ``URL encoded'' form
-// ("bar=baz&foo=quux") sorted by key.
-func (v Values) Encode() string {
-	if v == nil {
-		return ""
-	}
-	var buf bytes.Buffer
-	keys := make([]string, 0, len(v))
-	for k := range v {
-		keys = append(keys, k)
-	}
-	sort.Strings(keys)
-	for _, k := range keys {
-		vs := v[k]
-		prefix := QueryEscape(k) + "="
-		for _, v := range vs {
-			if buf.Len() > 0 {
-				buf.WriteByte('&')
-			}
-			buf.WriteString(prefix)
-			buf.WriteString(QueryEscape(v))
-		}
-	}
-	return buf.String()
-}
-
-// resolvePath applies special path segments from refs and applies
-// them to base, per RFC 3986.
-func resolvePath(base, ref string) string {
-	var full string
-	if ref == "" {
-		full = base
-	} else if ref[0] != '/' {
-		i := strings.LastIndex(base, "/")
-		full = base[:i+1] + ref
-	} else {
-		full = ref
-	}
-	if full == "" {
-		return ""
-	}
-	var dst []string
-	src := strings.Split(full, "/")
-	for _, elem := range src {
-		switch elem {
-		case ".":
-			// drop
-		case "..":
-			if len(dst) > 0 {
-				dst = dst[:len(dst)-1]
-			}
-		default:
-			dst = append(dst, elem)
-		}
-	}
-	if last := src[len(src)-1]; last == "." || last == ".." {
-		// Add final slash to the joined path.
-		dst = append(dst, "")
-	}
-	return "/" + strings.TrimLeft(strings.Join(dst, "/"), "/")
-}
-
-// IsAbs returns true if the URL is absolute.
-func (u *URL) IsAbs() bool {
-	return u.Scheme != ""
-}
-
-// Parse parses a URL in the context of the receiver.  The provided URL
-// may be relative or absolute.  Parse returns nil, err on parse
-// failure, otherwise its return value is the same as ResolveReference.
-func (u *URL) Parse(ref string) (*URL, error) {
-	refurl, err := Parse(ref)
-	if err != nil {
-		return nil, err
-	}
-	return u.ResolveReference(refurl), nil
-}
-
-// ResolveReference resolves a URI reference to an absolute URI from
-// an absolute base URI, per RFC 3986 Section 5.2.  The URI reference
-// may be relative or absolute.  ResolveReference always returns a new
-// URL instance, even if the returned URL is identical to either the
-// base or reference. If ref is an absolute URL, then ResolveReference
-// ignores base and returns a copy of ref.
-func (u *URL) ResolveReference(ref *URL) *URL {
-	url := *ref
-	if ref.Scheme == "" {
-		url.Scheme = u.Scheme
-	}
-	if ref.Scheme != "" || ref.Host != "" || ref.User != nil {
-		// The "absoluteURI" or "net_path" cases.
-		url.Path = resolvePath(ref.Path, "")
-		return &url
-	}
-	if ref.Opaque != "" {
-		url.User = nil
-		url.Host = ""
-		url.Path = ""
-		return &url
-	}
-	if ref.Path == "" {
-		if ref.RawQuery == "" {
-			url.RawQuery = u.RawQuery
-			if ref.Fragment == "" {
-				url.Fragment = u.Fragment
-			}
-		}
-	}
-	// The "abs_path" or "rel_path" cases.
-	url.Host = u.Host
-	url.User = u.User
-	url.Path = resolvePath(u.Path, ref.Path)
-	return &url
-}
-
-// Query parses RawQuery and returns the corresponding values.
-func (u *URL) Query() Values {
-	v, _ := ParseQuery(u.RawQuery)
-	return v
-}
-
-// RequestURI returns the encoded path?query or opaque?query
-// string that would be used in an HTTP request for u.
-func (u *URL) RequestURI() string {
-	result := u.Opaque
-	if result == "" {
-		result = escape(u.Path, encodePath)
-		if result == "" {
-			result = "/"
-		}
-	} else {
-		if strings.HasPrefix(result, "//") {
-			result = u.Scheme + ":" + result
-		}
-	}
-	if u.RawQuery != "" {
-		result += "?" + u.RawQuery
-	}
-	return result
-}
diff --git a/src/pkg/net/url/url_test.go b/src/pkg/net/url/url_test.go
deleted file mode 100644
index cad758f..0000000
--- a/src/pkg/net/url/url_test.go
+++ /dev/null
@@ -1,905 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package url
-
-import (
-	"fmt"
-	"reflect"
-	"strings"
-	"testing"
-)
-
-type URLTest struct {
-	in        string
-	out       *URL
-	roundtrip string // expected result of reserializing the URL; empty means same as "in".
-}
-
-var urltests = []URLTest{
-	// no path
-	{
-		"http://www.google.com",
-		&URL{
-			Scheme: "http",
-			Host:   "www.google.com",
-		},
-		"",
-	},
-	// path
-	{
-		"http://www.google.com/",
-		&URL{
-			Scheme: "http",
-			Host:   "www.google.com",
-			Path:   "/",
-		},
-		"",
-	},
-	// path with hex escaping
-	{
-		"http://www.google.com/file%20one%26two",
-		&URL{
-			Scheme: "http",
-			Host:   "www.google.com",
-			Path:   "/file one&two",
-		},
-		"http://www.google.com/file%20one&two",
-	},
-	// user
-	{
-		"ftp://webmaster@www.google.com/",
-		&URL{
-			Scheme: "ftp",
-			User:   User("webmaster"),
-			Host:   "www.google.com",
-			Path:   "/",
-		},
-		"",
-	},
-	// escape sequence in username
-	{
-		"ftp://john%20doe@www.google.com/",
-		&URL{
-			Scheme: "ftp",
-			User:   User("john doe"),
-			Host:   "www.google.com",
-			Path:   "/",
-		},
-		"ftp://john%20doe@www.google.com/",
-	},
-	// query
-	{
-		"http://www.google.com/?q=go+language",
-		&URL{
-			Scheme:   "http",
-			Host:     "www.google.com",
-			Path:     "/",
-			RawQuery: "q=go+language",
-		},
-		"",
-	},
-	// query with hex escaping: NOT parsed
-	{
-		"http://www.google.com/?q=go%20language",
-		&URL{
-			Scheme:   "http",
-			Host:     "www.google.com",
-			Path:     "/",
-			RawQuery: "q=go%20language",
-		},
-		"",
-	},
-	// %20 outside query
-	{
-		"http://www.google.com/a%20b?q=c+d",
-		&URL{
-			Scheme:   "http",
-			Host:     "www.google.com",
-			Path:     "/a b",
-			RawQuery: "q=c+d",
-		},
-		"",
-	},
-	// path without leading /, so no parsing
-	{
-		"http:www.google.com/?q=go+language",
-		&URL{
-			Scheme:   "http",
-			Opaque:   "www.google.com/",
-			RawQuery: "q=go+language",
-		},
-		"http:www.google.com/?q=go+language",
-	},
-	// path without leading /, so no parsing
-	{
-		"http:%2f%2fwww.google.com/?q=go+language",
-		&URL{
-			Scheme:   "http",
-			Opaque:   "%2f%2fwww.google.com/",
-			RawQuery: "q=go+language",
-		},
-		"http:%2f%2fwww.google.com/?q=go+language",
-	},
-	// non-authority with path
-	{
-		"mailto:/webmaster at golang.org",
-		&URL{
-			Scheme: "mailto",
-			Path:   "/webmaster at golang.org",
-		},
-		"mailto:///webmaster@golang.org", // unfortunate compromise
-	},
-	// non-authority
-	{
-		"mailto:webmaster at golang.org",
-		&URL{
-			Scheme: "mailto",
-			Opaque: "webmaster at golang.org",
-		},
-		"",
-	},
-	// unescaped :// in query should not create a scheme
-	{
-		"/foo?query=http://bad",
-		&URL{
-			Path:     "/foo",
-			RawQuery: "query=http://bad",
-		},
-		"",
-	},
-	// leading // without scheme should create an authority
-	{
-		"//foo",
-		&URL{
-			Host: "foo",
-		},
-		"",
-	},
-	// leading // without scheme, with userinfo, path, and query
-	{
-		"//user at foo/path?a=b",
-		&URL{
-			User:     User("user"),
-			Host:     "foo",
-			Path:     "/path",
-			RawQuery: "a=b",
-		},
-		"",
-	},
-	// Three leading slashes isn't an authority, but doesn't return an error.
-	// (We can't return an error, as this code is also used via
-	// ServeHTTP -> ReadRequest -> Parse, which is arguably a
-	// different URL parsing context, but currently shares the
-	// same codepath)
-	{
-		"///threeslashes",
-		&URL{
-			Path: "///threeslashes",
-		},
-		"",
-	},
-	{
-		"http://user:password@google.com",
-		&URL{
-			Scheme: "http",
-			User:   UserPassword("user", "password"),
-			Host:   "google.com",
-		},
-		"http://user:password@google.com",
-	},
-	// unescaped @ in username should not confuse host
-	{
-		"http://j@ne:password@google.com",
-		&URL{
-			Scheme: "http",
-			User:   UserPassword("j at ne", "password"),
-			Host:   "google.com",
-		},
-		"http://j%40ne:password@google.com",
-	},
-	// unescaped @ in password should not confuse host
-	{
-		"http://jane:p@ssword@google.com",
-		&URL{
-			Scheme: "http",
-			User:   UserPassword("jane", "p at ssword"),
-			Host:   "google.com",
-		},
-		"http://jane:p%40ssword@google.com",
-	},
-	{
-		"http://j@ne:password@google.com/p@th?q=@go",
-		&URL{
-			Scheme:   "http",
-			User:     UserPassword("j at ne", "password"),
-			Host:     "google.com",
-			Path:     "/p at th",
-			RawQuery: "q=@go",
-		},
-		"http://j%40ne:password@google.com/p@th?q=@go",
-	},
-	{
-		"http://www.google.com/?q=go+language#foo",
-		&URL{
-			Scheme:   "http",
-			Host:     "www.google.com",
-			Path:     "/",
-			RawQuery: "q=go+language",
-			Fragment: "foo",
-		},
-		"",
-	},
-	{
-		"http://www.google.com/?q=go+language#foo%26bar",
-		&URL{
-			Scheme:   "http",
-			Host:     "www.google.com",
-			Path:     "/",
-			RawQuery: "q=go+language",
-			Fragment: "foo&bar",
-		},
-		"http://www.google.com/?q=go+language#foo&bar",
-	},
-	{
-		"file:///home/adg/rabbits",
-		&URL{
-			Scheme: "file",
-			Host:   "",
-			Path:   "/home/adg/rabbits",
-		},
-		"file:///home/adg/rabbits",
-	},
-	// "Windows" paths are no exception to the rule.
-	// See golang.org/issue/6027, especially comment #9.
-	{
-		"file:///C:/FooBar/Baz.txt",
-		&URL{
-			Scheme: "file",
-			Host:   "",
-			Path:   "/C:/FooBar/Baz.txt",
-		},
-		"file:///C:/FooBar/Baz.txt",
-	},
-	// case-insensitive scheme
-	{
-		"MaIlTo:webmaster at golang.org",
-		&URL{
-			Scheme: "mailto",
-			Opaque: "webmaster at golang.org",
-		},
-		"mailto:webmaster at golang.org",
-	},
-	// Relative path
-	{
-		"a/b/c",
-		&URL{
-			Path: "a/b/c",
-		},
-		"a/b/c",
-	},
-}
-
-// more useful string for debugging than fmt's struct printer
-func ufmt(u *URL) string {
-	var user, pass interface{}
-	if u.User != nil {
-		user = u.User.Username()
-		if p, ok := u.User.Password(); ok {
-			pass = p
-		}
-	}
-	return fmt.Sprintf("opaque=%q, scheme=%q, user=%#v, pass=%#v, host=%q, path=%q, rawq=%q, frag=%q",
-		u.Opaque, u.Scheme, user, pass, u.Host, u.Path, u.RawQuery, u.Fragment)
-}
-
-func DoTest(t *testing.T, parse func(string) (*URL, error), name string, tests []URLTest) {
-	for _, tt := range tests {
-		u, err := parse(tt.in)
-		if err != nil {
-			t.Errorf("%s(%q) returned error %s", name, tt.in, err)
-			continue
-		}
-		if !reflect.DeepEqual(u, tt.out) {
-			t.Errorf("%s(%q):\n\thave %v\n\twant %v\n",
-				name, tt.in, ufmt(u), ufmt(tt.out))
-		}
-	}
-}
-
-func BenchmarkString(b *testing.B) {
-	b.StopTimer()
-	b.ReportAllocs()
-	for _, tt := range urltests {
-		u, err := Parse(tt.in)
-		if err != nil {
-			b.Errorf("Parse(%q) returned error %s", tt.in, err)
-			continue
-		}
-		if tt.roundtrip == "" {
-			continue
-		}
-		b.StartTimer()
-		var g string
-		for i := 0; i < b.N; i++ {
-			g = u.String()
-		}
-		b.StopTimer()
-		if w := tt.roundtrip; g != w {
-			b.Errorf("Parse(%q).String() == %q, want %q", tt.in, g, w)
-		}
-	}
-}
-
-func TestParse(t *testing.T) {
-	DoTest(t, Parse, "Parse", urltests)
-}
-
-const pathThatLooksSchemeRelative = "//not.a.user at not.a.host/just/a/path"
-
-var parseRequestURLTests = []struct {
-	url           string
-	expectedValid bool
-}{
-	{"http://foo.com", true},
-	{"http://foo.com/", true},
-	{"http://foo.com/path", true},
-	{"/", true},
-	{pathThatLooksSchemeRelative, true},
-	{"//not.a.user@%66%6f%6f.com/just/a/path/also", true},
-	{"foo.html", false},
-	{"../dir/", false},
-	{"*", true},
-}
-
-func TestParseRequestURI(t *testing.T) {
-	for _, test := range parseRequestURLTests {
-		_, err := ParseRequestURI(test.url)
-		valid := err == nil
-		if valid != test.expectedValid {
-			t.Errorf("Expected valid=%v for %q; got %v", test.expectedValid, test.url, valid)
-		}
-	}
-
-	url, err := ParseRequestURI(pathThatLooksSchemeRelative)
-	if err != nil {
-		t.Fatalf("Unexpected error %v", err)
-	}
-	if url.Path != pathThatLooksSchemeRelative {
-		t.Errorf("Expected path %q; got %q", pathThatLooksSchemeRelative, url.Path)
-	}
-}
-
-func DoTestString(t *testing.T, parse func(string) (*URL, error), name string, tests []URLTest) {
-	for _, tt := range tests {
-		u, err := parse(tt.in)
-		if err != nil {
-			t.Errorf("%s(%q) returned error %s", name, tt.in, err)
-			continue
-		}
-		expected := tt.in
-		if len(tt.roundtrip) > 0 {
-			expected = tt.roundtrip
-		}
-		s := u.String()
-		if s != expected {
-			t.Errorf("%s(%q).String() == %q (expected %q)", name, tt.in, s, expected)
-		}
-	}
-}
-
-func TestURLString(t *testing.T) {
-	DoTestString(t, Parse, "Parse", urltests)
-
-	// no leading slash on path should prepend
-	// slash on String() call
-	noslash := URLTest{
-		"http://www.google.com/search",
-		&URL{
-			Scheme: "http",
-			Host:   "www.google.com",
-			Path:   "search",
-		},
-		"",
-	}
-	s := noslash.out.String()
-	if s != noslash.in {
-		t.Errorf("Expected %s; go %s", noslash.in, s)
-	}
-}
-
-type EscapeTest struct {
-	in  string
-	out string
-	err error
-}
-
-var unescapeTests = []EscapeTest{
-	{
-		"",
-		"",
-		nil,
-	},
-	{
-		"abc",
-		"abc",
-		nil,
-	},
-	{
-		"1%41",
-		"1A",
-		nil,
-	},
-	{
-		"1%41%42%43",
-		"1ABC",
-		nil,
-	},
-	{
-		"%4a",
-		"J",
-		nil,
-	},
-	{
-		"%6F",
-		"o",
-		nil,
-	},
-	{
-		"%", // not enough characters after %
-		"",
-		EscapeError("%"),
-	},
-	{
-		"%a", // not enough characters after %
-		"",
-		EscapeError("%a"),
-	},
-	{
-		"%1", // not enough characters after %
-		"",
-		EscapeError("%1"),
-	},
-	{
-		"123%45%6", // not enough characters after %
-		"",
-		EscapeError("%6"),
-	},
-	{
-		"%zzzzz", // invalid hex digits
-		"",
-		EscapeError("%zz"),
-	},
-}
-
-func TestUnescape(t *testing.T) {
-	for _, tt := range unescapeTests {
-		actual, err := QueryUnescape(tt.in)
-		if actual != tt.out || (err != nil) != (tt.err != nil) {
-			t.Errorf("QueryUnescape(%q) = %q, %s; want %q, %s", tt.in, actual, err, tt.out, tt.err)
-		}
-	}
-}
-
-var escapeTests = []EscapeTest{
-	{
-		"",
-		"",
-		nil,
-	},
-	{
-		"abc",
-		"abc",
-		nil,
-	},
-	{
-		"one two",
-		"one+two",
-		nil,
-	},
-	{
-		"10%",
-		"10%25",
-		nil,
-	},
-	{
-		" ?&=#+%!<>#\"{}|\\^[]`☺\t:/@$'()*,;",
-		"+%3F%26%3D%23%2B%25%21%3C%3E%23%22%7B%7D%7C%5C%5E%5B%5D%60%E2%98%BA%09%3A%2F%40%24%27%28%29%2A%2C%3B",
-		nil,
-	},
-}
-
-func TestEscape(t *testing.T) {
-	for _, tt := range escapeTests {
-		actual := QueryEscape(tt.in)
-		if tt.out != actual {
-			t.Errorf("QueryEscape(%q) = %q, want %q", tt.in, actual, tt.out)
-		}
-
-		// for bonus points, verify that escape:unescape is an identity.
-		roundtrip, err := QueryUnescape(actual)
-		if roundtrip != tt.in || err != nil {
-			t.Errorf("QueryUnescape(%q) = %q, %s; want %q, %s", actual, roundtrip, err, tt.in, "[no error]")
-		}
-	}
-}
-
-//var userinfoTests = []UserinfoTest{
-//	{"user", "password", "user:password"},
-//	{"foo:bar", "~!@#$%^&*()_+{}|[]\\-=`:;'\"<>?,./",
-//		"foo%3Abar:~!%40%23$%25%5E&*()_+%7B%7D%7C%5B%5D%5C-=%60%3A;'%22%3C%3E?,.%2F"},
-//}
-
-type EncodeQueryTest struct {
-	m        Values
-	expected string
-}
-
-var encodeQueryTests = []EncodeQueryTest{
-	{nil, ""},
-	{Values{"q": {"puppies"}, "oe": {"utf8"}}, "oe=utf8&q=puppies"},
-	{Values{"q": {"dogs", "&", "7"}}, "q=dogs&q=%26&q=7"},
-	{Values{
-		"a": {"a1", "a2", "a3"},
-		"b": {"b1", "b2", "b3"},
-		"c": {"c1", "c2", "c3"},
-	}, "a=a1&a=a2&a=a3&b=b1&b=b2&b=b3&c=c1&c=c2&c=c3"},
-}
-
-func TestEncodeQuery(t *testing.T) {
-	for _, tt := range encodeQueryTests {
-		if q := tt.m.Encode(); q != tt.expected {
-			t.Errorf(`EncodeQuery(%+v) = %q, want %q`, tt.m, q, tt.expected)
-		}
-	}
-}
-
-var resolvePathTests = []struct {
-	base, ref, expected string
-}{
-	{"a/b", ".", "/a/"},
-	{"a/b", "c", "/a/c"},
-	{"a/b", "..", "/"},
-	{"a/", "..", "/"},
-	{"a/", "../..", "/"},
-	{"a/b/c", "..", "/a/"},
-	{"a/b/c", "../d", "/a/d"},
-	{"a/b/c", ".././d", "/a/d"},
-	{"a/b", "./..", "/"},
-	{"a/./b", ".", "/a/"},
-	{"a/../", ".", "/"},
-	{"a/.././b", "c", "/c"},
-}
-
-func TestResolvePath(t *testing.T) {
-	for _, test := range resolvePathTests {
-		got := resolvePath(test.base, test.ref)
-		if got != test.expected {
-			t.Errorf("For %q + %q got %q; expected %q", test.base, test.ref, got, test.expected)
-		}
-	}
-}
-
-var resolveReferenceTests = []struct {
-	base, rel, expected string
-}{
-	// Absolute URL references
-	{"http://foo.com?a=b", "https://bar.com/", "https://bar.com/"},
-	{"http://foo.com/", "https://bar.com/?a=b", "https://bar.com/?a=b"},
-	{"http://foo.com/bar", "mailto:foo at example.com", "mailto:foo at example.com"},
-
-	// Path-absolute references
-	{"http://foo.com/bar", "/baz", "http://foo.com/baz"},
-	{"http://foo.com/bar?a=b#f", "/baz", "http://foo.com/baz"},
-	{"http://foo.com/bar?a=b", "/baz?c=d", "http://foo.com/baz?c=d"},
-
-	// Scheme-relative
-	{"https://foo.com/bar?a=b", "//bar.com/quux", "https://bar.com/quux"},
-
-	// Path-relative references:
-
-	// ... current directory
-	{"http://foo.com", ".", "http://foo.com/"},
-	{"http://foo.com/bar", ".", "http://foo.com/"},
-	{"http://foo.com/bar/", ".", "http://foo.com/bar/"},
-
-	// ... going down
-	{"http://foo.com", "bar", "http://foo.com/bar"},
-	{"http://foo.com/", "bar", "http://foo.com/bar"},
-	{"http://foo.com/bar/baz", "quux", "http://foo.com/bar/quux"},
-
-	// ... going up
-	{"http://foo.com/bar/baz", "../quux", "http://foo.com/quux"},
-	{"http://foo.com/bar/baz", "../../../../../quux", "http://foo.com/quux"},
-	{"http://foo.com/bar", "..", "http://foo.com/"},
-	{"http://foo.com/bar/baz", "./..", "http://foo.com/"},
-	// ".." in the middle (issue 3560)
-	{"http://foo.com/bar/baz", "quux/dotdot/../tail", "http://foo.com/bar/quux/tail"},
-	{"http://foo.com/bar/baz", "quux/./dotdot/../tail", "http://foo.com/bar/quux/tail"},
-	{"http://foo.com/bar/baz", "quux/./dotdot/.././tail", "http://foo.com/bar/quux/tail"},
-	{"http://foo.com/bar/baz", "quux/./dotdot/./../tail", "http://foo.com/bar/quux/tail"},
-	{"http://foo.com/bar/baz", "quux/./dotdot/dotdot/././../../tail", "http://foo.com/bar/quux/tail"},
-	{"http://foo.com/bar/baz", "quux/./dotdot/dotdot/./.././../tail", "http://foo.com/bar/quux/tail"},
-	{"http://foo.com/bar/baz", "quux/./dotdot/dotdot/dotdot/./../../.././././tail", "http://foo.com/bar/quux/tail"},
-	{"http://foo.com/bar/baz", "quux/./dotdot/../dotdot/../dot/./tail/..", "http://foo.com/bar/quux/dot/"},
-
-	// Remove any dot-segments prior to forming the target URI.
-	// http://tools.ietf.org/html/rfc3986#section-5.2.4
-	{"http://foo.com/dot/./dotdot/../foo/bar", "../baz", "http://foo.com/dot/baz"},
-
-	// Triple dot isn't special
-	{"http://foo.com/bar", "...", "http://foo.com/..."},
-
-	// Fragment
-	{"http://foo.com/bar", ".#frag", "http://foo.com/#frag"},
-
-	// RFC 3986: Normal Examples
-	// http://tools.ietf.org/html/rfc3986#section-5.4.1
-	{"http://a/b/c/d;p?q", "g:h", "g:h"},
-	{"http://a/b/c/d;p?q", "g", "http://a/b/c/g"},
-	{"http://a/b/c/d;p?q", "./g", "http://a/b/c/g"},
-	{"http://a/b/c/d;p?q", "g/", "http://a/b/c/g/"},
-	{"http://a/b/c/d;p?q", "/g", "http://a/g"},
-	{"http://a/b/c/d;p?q", "//g", "http://g"},
-	{"http://a/b/c/d;p?q", "?y", "http://a/b/c/d;p?y"},
-	{"http://a/b/c/d;p?q", "g?y", "http://a/b/c/g?y"},
-	{"http://a/b/c/d;p?q", "#s", "http://a/b/c/d;p?q#s"},
-	{"http://a/b/c/d;p?q", "g#s", "http://a/b/c/g#s"},
-	{"http://a/b/c/d;p?q", "g?y#s", "http://a/b/c/g?y#s"},
-	{"http://a/b/c/d;p?q", ";x", "http://a/b/c/;x"},
-	{"http://a/b/c/d;p?q", "g;x", "http://a/b/c/g;x"},
-	{"http://a/b/c/d;p?q", "g;x?y#s", "http://a/b/c/g;x?y#s"},
-	{"http://a/b/c/d;p?q", "", "http://a/b/c/d;p?q"},
-	{"http://a/b/c/d;p?q", ".", "http://a/b/c/"},
-	{"http://a/b/c/d;p?q", "./", "http://a/b/c/"},
-	{"http://a/b/c/d;p?q", "..", "http://a/b/"},
-	{"http://a/b/c/d;p?q", "../", "http://a/b/"},
-	{"http://a/b/c/d;p?q", "../g", "http://a/b/g"},
-	{"http://a/b/c/d;p?q", "../..", "http://a/"},
-	{"http://a/b/c/d;p?q", "../../", "http://a/"},
-	{"http://a/b/c/d;p?q", "../../g", "http://a/g"},
-
-	// RFC 3986: Abnormal Examples
-	// http://tools.ietf.org/html/rfc3986#section-5.4.2
-	{"http://a/b/c/d;p?q", "../../../g", "http://a/g"},
-	{"http://a/b/c/d;p?q", "../../../../g", "http://a/g"},
-	{"http://a/b/c/d;p?q", "/./g", "http://a/g"},
-	{"http://a/b/c/d;p?q", "/../g", "http://a/g"},
-	{"http://a/b/c/d;p?q", "g.", "http://a/b/c/g."},
-	{"http://a/b/c/d;p?q", ".g", "http://a/b/c/.g"},
-	{"http://a/b/c/d;p?q", "g..", "http://a/b/c/g.."},
-	{"http://a/b/c/d;p?q", "..g", "http://a/b/c/..g"},
-	{"http://a/b/c/d;p?q", "./../g", "http://a/b/g"},
-	{"http://a/b/c/d;p?q", "./g/.", "http://a/b/c/g/"},
-	{"http://a/b/c/d;p?q", "g/./h", "http://a/b/c/g/h"},
-	{"http://a/b/c/d;p?q", "g/../h", "http://a/b/c/h"},
-	{"http://a/b/c/d;p?q", "g;x=1/./y", "http://a/b/c/g;x=1/y"},
-	{"http://a/b/c/d;p?q", "g;x=1/../y", "http://a/b/c/y"},
-	{"http://a/b/c/d;p?q", "g?y/./x", "http://a/b/c/g?y/./x"},
-	{"http://a/b/c/d;p?q", "g?y/../x", "http://a/b/c/g?y/../x"},
-	{"http://a/b/c/d;p?q", "g#s/./x", "http://a/b/c/g#s/./x"},
-	{"http://a/b/c/d;p?q", "g#s/../x", "http://a/b/c/g#s/../x"},
-
-	// Extras.
-	{"https://a/b/c/d;p?q", "//g?q", "https://g?q"},
-	{"https://a/b/c/d;p?q", "//g#s", "https://g#s"},
-	{"https://a/b/c/d;p?q", "//g/d/e/f?y#s", "https://g/d/e/f?y#s"},
-	{"https://a/b/c/d;p#s", "?y", "https://a/b/c/d;p?y"},
-	{"https://a/b/c/d;p?q#s", "?y", "https://a/b/c/d;p?y"},
-}
-
-func TestResolveReference(t *testing.T) {
-	mustParse := func(url string) *URL {
-		u, err := Parse(url)
-		if err != nil {
-			t.Fatalf("Expected URL to parse: %q, got error: %v", url, err)
-		}
-		return u
-	}
-	opaque := &URL{Scheme: "scheme", Opaque: "opaque"}
-	for _, test := range resolveReferenceTests {
-		base := mustParse(test.base)
-		rel := mustParse(test.rel)
-		url := base.ResolveReference(rel)
-		if url.String() != test.expected {
-			t.Errorf("URL(%q).ResolveReference(%q) == %q, got %q", test.base, test.rel, test.expected, url.String())
-		}
-		// Ensure that new instances are returned.
-		if base == url {
-			t.Errorf("Expected URL.ResolveReference to return new URL instance.")
-		}
-		// Test the convenience wrapper too.
-		url, err := base.Parse(test.rel)
-		if err != nil {
-			t.Errorf("URL(%q).Parse(%q) failed: %v", test.base, test.rel, err)
-		} else if url.String() != test.expected {
-			t.Errorf("URL(%q).Parse(%q) == %q, got %q", test.base, test.rel, test.expected, url.String())
-		} else if base == url {
-			// Ensure that new instances are returned for the wrapper too.
-			t.Errorf("Expected URL.Parse to return new URL instance.")
-		}
-		// Ensure Opaque resets the URL.
-		url = base.ResolveReference(opaque)
-		if *url != *opaque {
-			t.Errorf("ResolveReference failed to resolve opaque URL: want %#v, got %#v", url, opaque)
-		}
-		// Test the convenience wrapper with an opaque URL too.
-		url, err = base.Parse("scheme:opaque")
-		if err != nil {
-			t.Errorf(`URL(%q).Parse("scheme:opaque") failed: %v`, test.base, err)
-		} else if *url != *opaque {
-			t.Errorf("Parse failed to resolve opaque URL: want %#v, got %#v", url, opaque)
-		} else if base == url {
-			// Ensure that new instances are returned, again.
-			t.Errorf("Expected URL.Parse to return new URL instance.")
-		}
-	}
-}
-
-func TestQueryValues(t *testing.T) {
-	u, _ := Parse("http://x.com?foo=bar&bar=1&bar=2")
-	v := u.Query()
-	if len(v) != 2 {
-		t.Errorf("got %d keys in Query values, want 2", len(v))
-	}
-	if g, e := v.Get("foo"), "bar"; g != e {
-		t.Errorf("Get(foo) = %q, want %q", g, e)
-	}
-	// Case sensitive:
-	if g, e := v.Get("Foo"), ""; g != e {
-		t.Errorf("Get(Foo) = %q, want %q", g, e)
-	}
-	if g, e := v.Get("bar"), "1"; g != e {
-		t.Errorf("Get(bar) = %q, want %q", g, e)
-	}
-	if g, e := v.Get("baz"), ""; g != e {
-		t.Errorf("Get(baz) = %q, want %q", g, e)
-	}
-	v.Del("bar")
-	if g, e := v.Get("bar"), ""; g != e {
-		t.Errorf("second Get(bar) = %q, want %q", g, e)
-	}
-}
-
-type parseTest struct {
-	query string
-	out   Values
-}
-
-var parseTests = []parseTest{
-	{
-		query: "a=1&b=2",
-		out:   Values{"a": []string{"1"}, "b": []string{"2"}},
-	},
-	{
-		query: "a=1&a=2&a=banana",
-		out:   Values{"a": []string{"1", "2", "banana"}},
-	},
-	{
-		query: "ascii=%3Ckey%3A+0x90%3E",
-		out:   Values{"ascii": []string{"<key: 0x90>"}},
-	},
-	{
-		query: "a=1;b=2",
-		out:   Values{"a": []string{"1"}, "b": []string{"2"}},
-	},
-	{
-		query: "a=1&a=2;a=banana",
-		out:   Values{"a": []string{"1", "2", "banana"}},
-	},
-}
-
-func TestParseQuery(t *testing.T) {
-	for i, test := range parseTests {
-		form, err := ParseQuery(test.query)
-		if err != nil {
-			t.Errorf("test %d: Unexpected error: %v", i, err)
-			continue
-		}
-		if len(form) != len(test.out) {
-			t.Errorf("test %d: len(form) = %d, want %d", i, len(form), len(test.out))
-		}
-		for k, evs := range test.out {
-			vs, ok := form[k]
-			if !ok {
-				t.Errorf("test %d: Missing key %q", i, k)
-				continue
-			}
-			if len(vs) != len(evs) {
-				t.Errorf("test %d: len(form[%q]) = %d, want %d", i, k, len(vs), len(evs))
-				continue
-			}
-			for j, ev := range evs {
-				if v := vs[j]; v != ev {
-					t.Errorf("test %d: form[%q][%d] = %q, want %q", i, k, j, v, ev)
-				}
-			}
-		}
-	}
-}
-
-type RequestURITest struct {
-	url *URL
-	out string
-}
-
-var requritests = []RequestURITest{
-	{
-		&URL{
-			Scheme: "http",
-			Host:   "example.com",
-			Path:   "",
-		},
-		"/",
-	},
-	{
-		&URL{
-			Scheme: "http",
-			Host:   "example.com",
-			Path:   "/a b",
-		},
-		"/a%20b",
-	},
-	// golang.org/issue/4860 variant 1
-	{
-		&URL{
-			Scheme: "http",
-			Host:   "example.com",
-			Opaque: "/%2F/%2F/",
-		},
-		"/%2F/%2F/",
-	},
-	// golang.org/issue/4860 variant 2
-	{
-		&URL{
-			Scheme: "http",
-			Host:   "example.com",
-			Opaque: "//other.example.com/%2F/%2F/",
-		},
-		"http://other.example.com/%2F/%2F/",
-	},
-	{
-		&URL{
-			Scheme:   "http",
-			Host:     "example.com",
-			Path:     "/a b",
-			RawQuery: "q=go+language",
-		},
-		"/a%20b?q=go+language",
-	},
-	{
-		&URL{
-			Scheme: "myschema",
-			Opaque: "opaque",
-		},
-		"opaque",
-	},
-	{
-		&URL{
-			Scheme:   "myschema",
-			Opaque:   "opaque",
-			RawQuery: "q=go+language",
-		},
-		"opaque?q=go+language",
-	},
-}
-
-func TestRequestURI(t *testing.T) {
-	for _, tt := range requritests {
-		s := tt.url.RequestURI()
-		if s != tt.out {
-			t.Errorf("%#v.RequestURI() == %q (expected %q)", tt.url, s, tt.out)
-		}
-	}
-}
-
-func TestParseFailure(t *testing.T) {
-	// Test that the first parse error is returned.
-	const url = "%gh&%ij"
-	_, err := ParseQuery(url)
-	errStr := fmt.Sprint(err)
-	if !strings.Contains(errStr, "%gh") {
-		t.Errorf(`ParseQuery(%q) returned error %q, want something containing %q"`, url, errStr, "%gh")
-	}
-}
diff --git a/src/pkg/net/z_last_test.go b/src/pkg/net/z_last_test.go
deleted file mode 100644
index 4f6a54a..0000000
--- a/src/pkg/net/z_last_test.go
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package net
-
-import (
-	"flag"
-	"fmt"
-	"testing"
-)
-
-var testDNSFlood = flag.Bool("dnsflood", false, "whether to test dns query flooding")
-
-func TestDNSThreadLimit(t *testing.T) {
-	if !*testDNSFlood {
-		t.Skip("test disabled; use -dnsflood to enable")
-	}
-
-	const N = 10000
-	c := make(chan int, N)
-	for i := 0; i < N; i++ {
-		go func(i int) {
-			LookupIP(fmt.Sprintf("%d.net-test.golang.org", i))
-			c <- 1
-		}(i)
-	}
-	// Don't bother waiting for the stragglers; stop at 0.9 N.
-	for i := 0; i < N*9/10; i++ {
-		if i%100 == 0 {
-			//println("TestDNSThreadLimit:", i)
-		}
-		<-c
-	}
-
-	// If we're still here, it worked.
-}
diff --git a/src/pkg/os/dir_unix.go b/src/pkg/os/dir_unix.go
deleted file mode 100644
index d353e40..0000000
--- a/src/pkg/os/dir_unix.go
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris
-
-package os
-
-import (
-	"io"
-	"syscall"
-)
-
-const (
-	blockSize = 4096
-)
-
-func (f *File) readdirnames(n int) (names []string, err error) {
-	// If this file has no dirinfo, create one.
-	if f.dirinfo == nil {
-		f.dirinfo = new(dirInfo)
-		// The buffer must be at least a block long.
-		f.dirinfo.buf = make([]byte, blockSize)
-	}
-	d := f.dirinfo
-
-	size := n
-	if size <= 0 {
-		size = 100
-		n = -1
-	}
-
-	names = make([]string, 0, size) // Empty with room to grow.
-	for n != 0 {
-		// Refill the buffer if necessary
-		if d.bufp >= d.nbuf {
-			d.bufp = 0
-			var errno error
-			d.nbuf, errno = syscall.ReadDirent(f.fd, d.buf)
-			if errno != nil {
-				return names, NewSyscallError("readdirent", errno)
-			}
-			if d.nbuf <= 0 {
-				break // EOF
-			}
-		}
-
-		// Drain the buffer
-		var nb, nc int
-		nb, nc, names = syscall.ParseDirent(d.buf[d.bufp:d.nbuf], n, names)
-		d.bufp += nb
-		n -= nc
-	}
-	if n >= 0 && len(names) == 0 {
-		return names, io.EOF
-	}
-	return names, nil
-}
diff --git a/src/pkg/os/env.go b/src/pkg/os/env.go
deleted file mode 100644
index db7fc72..0000000
--- a/src/pkg/os/env.go
+++ /dev/null
@@ -1,103 +0,0 @@
-// Copyright 2010 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// General environment variables.
-
-package os
-
-import "syscall"
-
-// Expand replaces ${var} or $var in the string based on the mapping function.
-// For example, os.ExpandEnv(s) is equivalent to os.Expand(s, os.Getenv).
-func Expand(s string, mapping func(string) string) string {
-	buf := make([]byte, 0, 2*len(s))
-	// ${} is all ASCII, so bytes are fine for this operation.
-	i := 0
-	for j := 0; j < len(s); j++ {
-		if s[j] == '$' && j+1 < len(s) {
-			buf = append(buf, s[i:j]...)
-			name, w := getShellName(s[j+1:])
-			buf = append(buf, mapping(name)...)
-			j += w
-			i = j + 1
-		}
-	}
-	return string(buf) + s[i:]
-}
-
-// ExpandEnv replaces ${var} or $var in the string according to the values
-// of the current environment variables.  References to undefined
-// variables are replaced by the empty string.
-func ExpandEnv(s string) string {
-	return Expand(s, Getenv)
-}
-
-// isSpellSpecialVar reports whether the character identifies a special
-// shell variable such as $*.
-func isShellSpecialVar(c uint8) bool {
-	switch c {
-	case '*', '#', '$', '@', '!', '?', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
-		return true
-	}
-	return false
-}
-
-// isAlphaNum reports whether the byte is an ASCII letter, number, or underscore
-func isAlphaNum(c uint8) bool {
-	return c == '_' || '0' <= c && c <= '9' || 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z'
-}
-
-// getName returns the name that begins the string and the number of bytes
-// consumed to extract it.  If the name is enclosed in {}, it's part of a ${}
-// expansion and two more bytes are needed than the length of the name.
-func getShellName(s string) (string, int) {
-	switch {
-	case s[0] == '{':
-		if len(s) > 2 && isShellSpecialVar(s[1]) && s[2] == '}' {
-			return s[1:2], 3
-		}
-		// Scan to closing brace
-		for i := 1; i < len(s); i++ {
-			if s[i] == '}' {
-				return s[1:i], i + 1
-			}
-		}
-		return "", 1 // Bad syntax; just eat the brace.
-	case isShellSpecialVar(s[0]):
-		return s[0:1], 1
-	}
-	// Scan alphanumerics.
-	var i int
-	for i = 0; i < len(s) && isAlphaNum(s[i]); i++ {
-	}
-	return s[:i], i
-}
-
-// Getenv retrieves the value of the environment variable named by the key.
-// It returns the value, which will be empty if the variable is not present.
-func Getenv(key string) string {
-	v, _ := syscall.Getenv(key)
-	return v
-}
-
-// Setenv sets the value of the environment variable named by the key.
-// It returns an error, if any.
-func Setenv(key, value string) error {
-	err := syscall.Setenv(key, value)
-	if err != nil {
-		return NewSyscallError("setenv", err)
-	}
-	return nil
-}
-
-// Clearenv deletes all environment variables.
-func Clearenv() {
-	syscall.Clearenv()
-}
-
-// Environ returns a copy of strings representing the environment,
-// in the form "key=value".
-func Environ() []string {
-	return syscall.Environ()
-}
diff --git a/src/pkg/os/env_test.go b/src/pkg/os/env_test.go
deleted file mode 100644
index 991fa4d..0000000
--- a/src/pkg/os/env_test.go
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package os_test
-
-import (
-	. "os"
-	"reflect"
-	"testing"
-)
-
-// testGetenv gives us a controlled set of variables for testing Expand.
-func testGetenv(s string) string {
-	switch s {
-	case "*":
-		return "all the args"
-	case "#":
-		return "NARGS"
-	case "$":
-		return "PID"
-	case "1":
-		return "ARGUMENT1"
-	case "HOME":
-		return "/usr/gopher"
-	case "H":
-		return "(Value of H)"
-	case "home_1":
-		return "/usr/foo"
-	case "_":
-		return "underscore"
-	}
-	return ""
-}
-
-var expandTests = []struct {
-	in, out string
-}{
-	{"", ""},
-	{"$*", "all the args"},
-	{"$$", "PID"},
-	{"${*}", "all the args"},
-	{"$1", "ARGUMENT1"},
-	{"${1}", "ARGUMENT1"},
-	{"now is the time", "now is the time"},
-	{"$HOME", "/usr/gopher"},
-	{"$home_1", "/usr/foo"},
-	{"${HOME}", "/usr/gopher"},
-	{"${H}OME", "(Value of H)OME"},
-	{"A$$$#$1$H$home_1*B", "APIDNARGSARGUMENT1(Value of H)/usr/foo*B"},
-}
-
-func TestExpand(t *testing.T) {
-	for _, test := range expandTests {
-		result := Expand(test.in, testGetenv)
-		if result != test.out {
-			t.Errorf("Expand(%q)=%q; expected %q", test.in, result, test.out)
-		}
-	}
-}
-
-func TestConsistentEnviron(t *testing.T) {
-	e0 := Environ()
-	for i := 0; i < 10; i++ {
-		e1 := Environ()
-		if !reflect.DeepEqual(e0, e1) {
-			t.Fatalf("environment changed")
-		}
-	}
-}
diff --git a/src/pkg/os/error_plan9.go b/src/pkg/os/error_plan9.go
deleted file mode 100644
index 85260c8..0000000
--- a/src/pkg/os/error_plan9.go
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package os
-
-func isExist(err error) bool {
-	switch pe := err.(type) {
-	case nil:
-		return false
-	case *PathError:
-		err = pe.Err
-	case *LinkError:
-		err = pe.Err
-	}
-	return contains(err.Error(), " exists")
-}
-
-func isNotExist(err error) bool {
-	switch pe := err.(type) {
-	case nil:
-		return false
-	case *PathError:
-		err = pe.Err
-	case *LinkError:
-		err = pe.Err
-	}
-	return contains(err.Error(), "does not exist")
-}
-
-func isPermission(err error) bool {
-	switch pe := err.(type) {
-	case nil:
-		return false
-	case *PathError:
-		err = pe.Err
-	case *LinkError:
-		err = pe.Err
-	}
-	return contains(err.Error(), "permission denied")
-}
-
-// contains is a local version of strings.Contains. It knows len(sep) > 1.
-func contains(s, sep string) bool {
-	n := len(sep)
-	c := sep[0]
-	for i := 0; i+n <= len(s); i++ {
-		if s[i] == c && s[i:i+n] == sep {
-			return true
-		}
-	}
-	return false
-}
diff --git a/src/pkg/os/exec/exec.go b/src/pkg/os/exec/exec.go
deleted file mode 100644
index a70ed0d..0000000
--- a/src/pkg/os/exec/exec.go
+++ /dev/null
@@ -1,493 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package exec runs external commands. It wraps os.StartProcess to make it
-// easier to remap stdin and stdout, connect I/O with pipes, and do other
-// adjustments.
-package exec
-
-import (
-	"bytes"
-	"errors"
-	"io"
-	"os"
-	"path/filepath"
-	"runtime"
-	"strconv"
-	"strings"
-	"sync"
-	"syscall"
-)
-
-// Error records the name of a binary that failed to be executed
-// and the reason it failed.
-type Error struct {
-	Name string
-	Err  error
-}
-
-func (e *Error) Error() string {
-	return "exec: " + strconv.Quote(e.Name) + ": " + e.Err.Error()
-}
-
-// Cmd represents an external command being prepared or run.
-type Cmd struct {
-	// Path is the path of the command to run.
-	//
-	// This is the only field that must be set to a non-zero
-	// value. If Path is relative, it is evaluated relative
-	// to Dir.
-	Path string
-
-	// Args holds command line arguments, including the command as Args[0].
-	// If the Args field is empty or nil, Run uses {Path}.
-	//
-	// In typical use, both Path and Args are set by calling Command.
-	Args []string
-
-	// Env specifies the environment of the process.
-	// If Env is nil, Run uses the current process's environment.
-	Env []string
-
-	// Dir specifies the working directory of the command.
-	// If Dir is the empty string, Run runs the command in the
-	// calling process's current directory.
-	Dir string
-
-	// Stdin specifies the process's standard input. If Stdin is
-	// nil, the process reads from the null device (os.DevNull).
-	Stdin io.Reader
-
-	// Stdout and Stderr specify the process's standard output and error.
-	//
-	// If either is nil, Run connects the corresponding file descriptor
-	// to the null device (os.DevNull).
-	//
-	// If Stdout and Stderr are the same writer, at most one
-	// goroutine at a time will call Write.
-	Stdout io.Writer
-	Stderr io.Writer
-
-	// ExtraFiles specifies additional open files to be inherited by the
-	// new process. It does not include standard input, standard output, or
-	// standard error. If non-nil, entry i becomes file descriptor 3+i.
-	//
-	// BUG: on OS X 10.6, child processes may sometimes inherit unwanted fds.
-	// http://golang.org/issue/2603
-	ExtraFiles []*os.File
-
-	// SysProcAttr holds optional, operating system-specific attributes.
-	// Run passes it to os.StartProcess as the os.ProcAttr's Sys field.
-	SysProcAttr *syscall.SysProcAttr
-
-	// Process is the underlying process, once started.
-	Process *os.Process
-
-	// ProcessState contains information about an exited process,
-	// available after a call to Wait or Run.
-	ProcessState *os.ProcessState
-
-	lookPathErr     error // LookPath error, if any.
-	finished        bool  // when Wait was called
-	childFiles      []*os.File
-	closeAfterStart []io.Closer
-	closeAfterWait  []io.Closer
-	goroutine       []func() error
-	errch           chan error // one send per goroutine
-}
-
-// Command returns the Cmd struct to execute the named program with
-// the given arguments.
-//
-// It sets only the Path and Args in the returned structure.
-//
-// If name contains no path separators, Command uses LookPath to
-// resolve the path to a complete name if possible. Otherwise it uses
-// name directly.
-//
-// The returned Cmd's Args field is constructed from the command name
-// followed by the elements of arg, so arg should not include the
-// command name itself. For example, Command("echo", "hello")
-func Command(name string, arg ...string) *Cmd {
-	cmd := &Cmd{
-		Path: name,
-		Args: append([]string{name}, arg...),
-	}
-	if filepath.Base(name) == name {
-		if lp, err := LookPath(name); err != nil {
-			cmd.lookPathErr = err
-		} else {
-			cmd.Path = lp
-		}
-	}
-	return cmd
-}
-
-// interfaceEqual protects against panics from doing equality tests on
-// two interfaces with non-comparable underlying types.
-func interfaceEqual(a, b interface{}) bool {
-	defer func() {
-		recover()
-	}()
-	return a == b
-}
-
-func (c *Cmd) envv() []string {
-	if c.Env != nil {
-		return c.Env
-	}
-	return os.Environ()
-}
-
-func (c *Cmd) argv() []string {
-	if len(c.Args) > 0 {
-		return c.Args
-	}
-	return []string{c.Path}
-}
-
-func (c *Cmd) stdin() (f *os.File, err error) {
-	if c.Stdin == nil {
-		f, err = os.Open(os.DevNull)
-		if err != nil {
-			return
-		}
-		c.closeAfterStart = append(c.closeAfterStart, f)
-		return
-	}
-
-	if f, ok := c.Stdin.(*os.File); ok {
-		return f, nil
-	}
-
-	pr, pw, err := os.Pipe()
-	if err != nil {
-		return
-	}
-
-	c.closeAfterStart = append(c.closeAfterStart, pr)
-	c.closeAfterWait = append(c.closeAfterWait, pw)
-	c.goroutine = append(c.goroutine, func() error {
-		_, err := io.Copy(pw, c.Stdin)
-		if err1 := pw.Close(); err == nil {
-			err = err1
-		}
-		return err
-	})
-	return pr, nil
-}
-
-func (c *Cmd) stdout() (f *os.File, err error) {
-	return c.writerDescriptor(c.Stdout)
-}
-
-func (c *Cmd) stderr() (f *os.File, err error) {
-	if c.Stderr != nil && interfaceEqual(c.Stderr, c.Stdout) {
-		return c.childFiles[1], nil
-	}
-	return c.writerDescriptor(c.Stderr)
-}
-
-func (c *Cmd) writerDescriptor(w io.Writer) (f *os.File, err error) {
-	if w == nil {
-		f, err = os.OpenFile(os.DevNull, os.O_WRONLY, 0)
-		if err != nil {
-			return
-		}
-		c.closeAfterStart = append(c.closeAfterStart, f)
-		return
-	}
-
-	if f, ok := w.(*os.File); ok {
-		return f, nil
-	}
-
-	pr, pw, err := os.Pipe()
-	if err != nil {
-		return
-	}
-
-	c.closeAfterStart = append(c.closeAfterStart, pw)
-	c.closeAfterWait = append(c.closeAfterWait, pr)
-	c.goroutine = append(c.goroutine, func() error {
-		_, err := io.Copy(w, pr)
-		return err
-	})
-	return pw, nil
-}
-
-func (c *Cmd) closeDescriptors(closers []io.Closer) {
-	for _, fd := range closers {
-		fd.Close()
-	}
-}
-
-// Run starts the specified command and waits for it to complete.
-//
-// The returned error is nil if the command runs, has no problems
-// copying stdin, stdout, and stderr, and exits with a zero exit
-// status.
-//
-// If the command fails to run or doesn't complete successfully, the
-// error is of type *ExitError. Other error types may be
-// returned for I/O problems.
-func (c *Cmd) Run() error {
-	if err := c.Start(); err != nil {
-		return err
-	}
-	return c.Wait()
-}
-
-// lookExtensions finds windows executable by its dir and path.
-// It uses LookPath to try appropriate extensions.
-// lookExtensions does not search PATH, instead it converts `prog` into `.\prog`.
-func lookExtensions(path, dir string) (string, error) {
-	if filepath.Base(path) == path {
-		path = filepath.Join(".", path)
-	}
-	if dir == "" {
-		return LookPath(path)
-	}
-	if filepath.VolumeName(path) != "" {
-		return LookPath(path)
-	}
-	if len(path) > 1 && os.IsPathSeparator(path[0]) {
-		return LookPath(path)
-	}
-	dirandpath := filepath.Join(dir, path)
-	// We assume that LookPath will only add file extension.
-	lp, err := LookPath(dirandpath)
-	if err != nil {
-		return "", err
-	}
-	ext := strings.TrimPrefix(lp, dirandpath)
-	return path + ext, nil
-}
-
-// Start starts the specified command but does not wait for it to complete.
-//
-// The Wait method will return the exit code and release associated resources
-// once the command exits.
-func (c *Cmd) Start() error {
-	if c.lookPathErr != nil {
-		c.closeDescriptors(c.closeAfterStart)
-		c.closeDescriptors(c.closeAfterWait)
-		return c.lookPathErr
-	}
-	if runtime.GOOS == "windows" {
-		lp, err := lookExtensions(c.Path, c.Dir)
-		if err != nil {
-			c.closeDescriptors(c.closeAfterStart)
-			c.closeDescriptors(c.closeAfterWait)
-			return err
-		}
-		c.Path = lp
-	}
-	if c.Process != nil {
-		return errors.New("exec: already started")
-	}
-
-	type F func(*Cmd) (*os.File, error)
-	for _, setupFd := range []F{(*Cmd).stdin, (*Cmd).stdout, (*Cmd).stderr} {
-		fd, err := setupFd(c)
-		if err != nil {
-			c.closeDescriptors(c.closeAfterStart)
-			c.closeDescriptors(c.closeAfterWait)
-			return err
-		}
-		c.childFiles = append(c.childFiles, fd)
-	}
-	c.childFiles = append(c.childFiles, c.ExtraFiles...)
-
-	var err error
-	c.Process, err = os.StartProcess(c.Path, c.argv(), &os.ProcAttr{
-		Dir:   c.Dir,
-		Files: c.childFiles,
-		Env:   c.envv(),
-		Sys:   c.SysProcAttr,
-	})
-	if err != nil {
-		c.closeDescriptors(c.closeAfterStart)
-		c.closeDescriptors(c.closeAfterWait)
-		return err
-	}
-
-	c.closeDescriptors(c.closeAfterStart)
-
-	c.errch = make(chan error, len(c.goroutine))
-	for _, fn := range c.goroutine {
-		go func(fn func() error) {
-			c.errch <- fn()
-		}(fn)
-	}
-
-	return nil
-}
-
-// An ExitError reports an unsuccessful exit by a command.
-type ExitError struct {
-	*os.ProcessState
-}
-
-func (e *ExitError) Error() string {
-	return e.ProcessState.String()
-}
-
-// Wait waits for the command to exit.
-// It must have been started by Start.
-//
-// The returned error is nil if the command runs, has no problems
-// copying stdin, stdout, and stderr, and exits with a zero exit
-// status.
-//
-// If the command fails to run or doesn't complete successfully, the
-// error is of type *ExitError. Other error types may be
-// returned for I/O problems.
-//
-// Wait releases any resources associated with the Cmd.
-func (c *Cmd) Wait() error {
-	if c.Process == nil {
-		return errors.New("exec: not started")
-	}
-	if c.finished {
-		return errors.New("exec: Wait was already called")
-	}
-	c.finished = true
-	state, err := c.Process.Wait()
-	c.ProcessState = state
-
-	var copyError error
-	for _ = range c.goroutine {
-		if err := <-c.errch; err != nil && copyError == nil {
-			copyError = err
-		}
-	}
-
-	c.closeDescriptors(c.closeAfterWait)
-
-	if err != nil {
-		return err
-	} else if !state.Success() {
-		return &ExitError{state}
-	}
-
-	return copyError
-}
-
-// Output runs the command and returns its standard output.
-func (c *Cmd) Output() ([]byte, error) {
-	if c.Stdout != nil {
-		return nil, errors.New("exec: Stdout already set")
-	}
-	var b bytes.Buffer
-	c.Stdout = &b
-	err := c.Run()
-	return b.Bytes(), err
-}
-
-// CombinedOutput runs the command and returns its combined standard
-// output and standard error.
-func (c *Cmd) CombinedOutput() ([]byte, error) {
-	if c.Stdout != nil {
-		return nil, errors.New("exec: Stdout already set")
-	}
-	if c.Stderr != nil {
-		return nil, errors.New("exec: Stderr already set")
-	}
-	var b bytes.Buffer
-	c.Stdout = &b
-	c.Stderr = &b
-	err := c.Run()
-	return b.Bytes(), err
-}
-
-// StdinPipe returns a pipe that will be connected to the command's
-// standard input when the command starts.
-// The pipe will be closed automatically after Wait sees the command exit.
-// A caller need only call Close to force the pipe to close sooner.
-// For example, if the command being run will not exit until standard input
-// is closed, the caller must close the pipe.
-func (c *Cmd) StdinPipe() (io.WriteCloser, error) {
-	if c.Stdin != nil {
-		return nil, errors.New("exec: Stdin already set")
-	}
-	if c.Process != nil {
-		return nil, errors.New("exec: StdinPipe after process started")
-	}
-	pr, pw, err := os.Pipe()
-	if err != nil {
-		return nil, err
-	}
-	c.Stdin = pr
-	c.closeAfterStart = append(c.closeAfterStart, pr)
-	wc := &closeOnce{File: pw}
-	c.closeAfterWait = append(c.closeAfterWait, wc)
-	return wc, nil
-}
-
-type closeOnce struct {
-	*os.File
-
-	once sync.Once
-	err  error
-}
-
-func (c *closeOnce) Close() error {
-	c.once.Do(c.close)
-	return c.err
-}
-
-func (c *closeOnce) close() {
-	c.err = c.File.Close()
-}
-
-// StdoutPipe returns a pipe that will be connected to the command's
-// standard output when the command starts.
-//
-// Wait will close the pipe after seeing the command exit, so most callers
-// need not close the pipe themselves; however, an implication is that
-// it is incorrect to call Wait before all reads from the pipe have completed.
-// For the same reason, it is incorrect to call Run when using StdoutPipe.
-// See the example for idiomatic usage.
-func (c *Cmd) StdoutPipe() (io.ReadCloser, error) {
-	if c.Stdout != nil {
-		return nil, errors.New("exec: Stdout already set")
-	}
-	if c.Process != nil {
-		return nil, errors.New("exec: StdoutPipe after process started")
-	}
-	pr, pw, err := os.Pipe()
-	if err != nil {
-		return nil, err
-	}
-	c.Stdout = pw
-	c.closeAfterStart = append(c.closeAfterStart, pw)
-	c.closeAfterWait = append(c.closeAfterWait, pr)
-	return pr, nil
-}
-
-// StderrPipe returns a pipe that will be connected to the command's
-// standard error when the command starts.
-//
-// Wait will close the pipe after seeing the command exit, so most callers
-// need not close the pipe themselves; however, an implication is that
-// it is incorrect to call Wait before all reads from the pipe have completed.
-// For the same reason, it is incorrect to use Run when using StderrPipe.
-// See the StdoutPipe example for idiomatic usage.
-func (c *Cmd) StderrPipe() (io.ReadCloser, error) {
-	if c.Stderr != nil {
-		return nil, errors.New("exec: Stderr already set")
-	}
-	if c.Process != nil {
-		return nil, errors.New("exec: StderrPipe after process started")
-	}
-	pr, pw, err := os.Pipe()
-	if err != nil {
-		return nil, err
-	}
-	c.Stderr = pw
-	c.closeAfterStart = append(c.closeAfterStart, pw)
-	c.closeAfterWait = append(c.closeAfterWait, pr)
-	return pr, nil
-}
diff --git a/src/pkg/os/exec/exec_test.go b/src/pkg/os/exec/exec_test.go
deleted file mode 100644
index 6f77ac3..0000000
--- a/src/pkg/os/exec/exec_test.go
+++ /dev/null
@@ -1,726 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Use an external test to avoid os/exec -> net/http -> crypto/x509 -> os/exec
-// circular dependency on non-cgo darwin.
-
-package exec_test
-
-import (
-	"bufio"
-	"bytes"
-	"fmt"
-	"io"
-	"io/ioutil"
-	"log"
-	"net"
-	"net/http"
-	"net/http/httptest"
-	"os"
-	"os/exec"
-	"path/filepath"
-	"runtime"
-	"strconv"
-	"strings"
-	"testing"
-	"time"
-)
-
-func helperCommand(t *testing.T, s ...string) *exec.Cmd {
-	if runtime.GOOS == "nacl" {
-		t.Skip("skipping on nacl")
-	}
-	cs := []string{"-test.run=TestHelperProcess", "--"}
-	cs = append(cs, s...)
-	cmd := exec.Command(os.Args[0], cs...)
-	cmd.Env = []string{"GO_WANT_HELPER_PROCESS=1"}
-	return cmd
-}
-
-func TestEcho(t *testing.T) {
-	bs, err := helperCommand(t, "echo", "foo bar", "baz").Output()
-	if err != nil {
-		t.Errorf("echo: %v", err)
-	}
-	if g, e := string(bs), "foo bar baz\n"; g != e {
-		t.Errorf("echo: want %q, got %q", e, g)
-	}
-}
-
-func TestCommandRelativeName(t *testing.T) {
-	// Run our own binary as a relative path
-	// (e.g. "_test/exec.test") our parent directory.
-	base := filepath.Base(os.Args[0]) // "exec.test"
-	dir := filepath.Dir(os.Args[0])   // "/tmp/go-buildNNNN/os/exec/_test"
-	if dir == "." {
-		t.Skip("skipping; running test at root somehow")
-	}
-	parentDir := filepath.Dir(dir) // "/tmp/go-buildNNNN/os/exec"
-	dirBase := filepath.Base(dir)  // "_test"
-	if dirBase == "." {
-		t.Skipf("skipping; unexpected shallow dir of %q", dir)
-	}
-
-	cmd := exec.Command(filepath.Join(dirBase, base), "-test.run=TestHelperProcess", "--", "echo", "foo")
-	cmd.Dir = parentDir
-	cmd.Env = []string{"GO_WANT_HELPER_PROCESS=1"}
-
-	out, err := cmd.Output()
-	if err != nil {
-		t.Errorf("echo: %v", err)
-	}
-	if g, e := string(out), "foo\n"; g != e {
-		t.Errorf("echo: want %q, got %q", e, g)
-	}
-}
-
-func TestCatStdin(t *testing.T) {
-	// Cat, testing stdin and stdout.
-	input := "Input string\nLine 2"
-	p := helperCommand(t, "cat")
-	p.Stdin = strings.NewReader(input)
-	bs, err := p.Output()
-	if err != nil {
-		t.Errorf("cat: %v", err)
-	}
-	s := string(bs)
-	if s != input {
-		t.Errorf("cat: want %q, got %q", input, s)
-	}
-}
-
-func TestCatGoodAndBadFile(t *testing.T) {
-	// Testing combined output and error values.
-	bs, err := helperCommand(t, "cat", "/bogus/file.foo", "exec_test.go").CombinedOutput()
-	if _, ok := err.(*exec.ExitError); !ok {
-		t.Errorf("expected *exec.ExitError from cat combined; got %T: %v", err, err)
-	}
-	s := string(bs)
-	sp := strings.SplitN(s, "\n", 2)
-	if len(sp) != 2 {
-		t.Fatalf("expected two lines from cat; got %q", s)
-	}
-	errLine, body := sp[0], sp[1]
-	if !strings.HasPrefix(errLine, "Error: open /bogus/file.foo") {
-		t.Errorf("expected stderr to complain about file; got %q", errLine)
-	}
-	if !strings.Contains(body, "func TestHelperProcess(t *testing.T)") {
-		t.Errorf("expected test code; got %q (len %d)", body, len(body))
-	}
-}
-
-func TestNoExistBinary(t *testing.T) {
-	// Can't run a non-existent binary
-	err := exec.Command("/no-exist-binary").Run()
-	if err == nil {
-		t.Error("expected error from /no-exist-binary")
-	}
-}
-
-func TestExitStatus(t *testing.T) {
-	// Test that exit values are returned correctly
-	cmd := helperCommand(t, "exit", "42")
-	err := cmd.Run()
-	want := "exit status 42"
-	switch runtime.GOOS {
-	case "plan9":
-		want = fmt.Sprintf("exit status: '%s %d: 42'", filepath.Base(cmd.Path), cmd.ProcessState.Pid())
-	}
-	if werr, ok := err.(*exec.ExitError); ok {
-		if s := werr.Error(); s != want {
-			t.Errorf("from exit 42 got exit %q, want %q", s, want)
-		}
-	} else {
-		t.Fatalf("expected *exec.ExitError from exit 42; got %T: %v", err, err)
-	}
-}
-
-func TestPipes(t *testing.T) {
-	check := func(what string, err error) {
-		if err != nil {
-			t.Fatalf("%s: %v", what, err)
-		}
-	}
-	// Cat, testing stdin and stdout.
-	c := helperCommand(t, "pipetest")
-	stdin, err := c.StdinPipe()
-	check("StdinPipe", err)
-	stdout, err := c.StdoutPipe()
-	check("StdoutPipe", err)
-	stderr, err := c.StderrPipe()
-	check("StderrPipe", err)
-
-	outbr := bufio.NewReader(stdout)
-	errbr := bufio.NewReader(stderr)
-	line := func(what string, br *bufio.Reader) string {
-		line, _, err := br.ReadLine()
-		if err != nil {
-			t.Fatalf("%s: %v", what, err)
-		}
-		return string(line)
-	}
-
-	err = c.Start()
-	check("Start", err)
-
-	_, err = stdin.Write([]byte("O:I am output\n"))
-	check("first stdin Write", err)
-	if g, e := line("first output line", outbr), "O:I am output"; g != e {
-		t.Errorf("got %q, want %q", g, e)
-	}
-
-	_, err = stdin.Write([]byte("E:I am error\n"))
-	check("second stdin Write", err)
-	if g, e := line("first error line", errbr), "E:I am error"; g != e {
-		t.Errorf("got %q, want %q", g, e)
-	}
-
-	_, err = stdin.Write([]byte("O:I am output2\n"))
-	check("third stdin Write 3", err)
-	if g, e := line("second output line", outbr), "O:I am output2"; g != e {
-		t.Errorf("got %q, want %q", g, e)
-	}
-
-	stdin.Close()
-	err = c.Wait()
-	check("Wait", err)
-}
-
-const stdinCloseTestString = "Some test string."
-
-// Issue 6270.
-func TestStdinClose(t *testing.T) {
-	check := func(what string, err error) {
-		if err != nil {
-			t.Fatalf("%s: %v", what, err)
-		}
-	}
-	cmd := helperCommand(t, "stdinClose")
-	stdin, err := cmd.StdinPipe()
-	check("StdinPipe", err)
-	// Check that we can access methods of the underlying os.File.`
-	if _, ok := stdin.(interface {
-		Fd() uintptr
-	}); !ok {
-		t.Error("can't access methods of underlying *os.File")
-	}
-	check("Start", cmd.Start())
-	go func() {
-		_, err := io.Copy(stdin, strings.NewReader(stdinCloseTestString))
-		check("Copy", err)
-		// Before the fix, this next line would race with cmd.Wait.
-		check("Close", stdin.Close())
-	}()
-	check("Wait", cmd.Wait())
-}
-
-// Issue 5071
-func TestPipeLookPathLeak(t *testing.T) {
-	fd0, lsof0 := numOpenFDS(t)
-	for i := 0; i < 4; i++ {
-		cmd := exec.Command("something-that-does-not-exist-binary")
-		cmd.StdoutPipe()
-		cmd.StderrPipe()
-		cmd.StdinPipe()
-		if err := cmd.Run(); err == nil {
-			t.Fatal("unexpected success")
-		}
-	}
-	for triesLeft := 3; triesLeft >= 0; triesLeft-- {
-		open, lsof := numOpenFDS(t)
-		fdGrowth := open - fd0
-		if fdGrowth > 2 {
-			if triesLeft > 0 {
-				// Work around what appears to be a race with Linux's
-				// proc filesystem (as used by lsof). It seems to only
-				// be eventually consistent. Give it awhile to settle.
-				// See golang.org/issue/7808
-				time.Sleep(100 * time.Millisecond)
-				continue
-			}
-			t.Errorf("leaked %d fds; want ~0; have:\n%s\noriginally:\n%s", fdGrowth, lsof, lsof0)
-		}
-		break
-	}
-}
-
-func numOpenFDS(t *testing.T) (n int, lsof []byte) {
-	lsof, err := exec.Command("lsof", "-n", "-p", strconv.Itoa(os.Getpid())).Output()
-	if err != nil {
-		t.Skip("skipping test; error finding or running lsof")
-	}
-	return bytes.Count(lsof, []byte("\n")), lsof
-}
-
-var testedAlreadyLeaked = false
-
-// basefds returns the number of expected file descriptors
-// to be present in a process at start.
-func basefds() uintptr {
-	n := os.Stderr.Fd() + 1
-
-	// Go runtime for 32-bit Plan 9 requires that /dev/bintime
-	// be kept open.
-	// See ../../runtime/time_plan9_386.c:/^runtime·nanotime
-	if runtime.GOOS == "plan9" && runtime.GOARCH == "386" {
-		n++
-	}
-	return n
-}
-
-func closeUnexpectedFds(t *testing.T, m string) {
-	for fd := basefds(); fd <= 101; fd++ {
-		err := os.NewFile(fd, "").Close()
-		if err == nil {
-			t.Logf("%s: Something already leaked - closed fd %d", m, fd)
-		}
-	}
-}
-
-func TestExtraFilesFDShuffle(t *testing.T) {
-	t.Skip("flaky test; see http://golang.org/issue/5780")
-	switch runtime.GOOS {
-	case "darwin":
-		// TODO(cnicolaou): http://golang.org/issue/2603
-		// leads to leaked file descriptors in this test when it's
-		// run from a builder.
-		closeUnexpectedFds(t, "TestExtraFilesFDShuffle")
-	case "netbsd":
-		// http://golang.org/issue/3955
-		closeUnexpectedFds(t, "TestExtraFilesFDShuffle")
-	case "windows":
-		t.Skip("no operating system support; skipping")
-	}
-
-	// syscall.StartProcess maps all the FDs passed to it in
-	// ProcAttr.Files (the concatenation of stdin,stdout,stderr and
-	// ExtraFiles) into consecutive FDs in the child, that is:
-	// Files{11, 12, 6, 7, 9, 3} should result in the file
-	// represented by FD 11 in the parent being made available as 0
-	// in the child, 12 as 1, etc.
-	//
-	// We want to test that FDs in the child do not get overwritten
-	// by one another as this shuffle occurs. The original implementation
-	// was buggy in that in some data dependent cases it would ovewrite
-	// stderr in the child with one of the ExtraFile members.
-	// Testing for this case is difficult because it relies on using
-	// the same FD values as that case. In particular, an FD of 3
-	// must be at an index of 4 or higher in ProcAttr.Files and
-	// the FD of the write end of the Stderr pipe (as obtained by
-	// StderrPipe()) must be the same as the size of ProcAttr.Files;
-	// therefore we test that the read end of this pipe (which is what
-	// is returned to the parent by StderrPipe() being one less than
-	// the size of ProcAttr.Files, i.e. 3+len(cmd.ExtraFiles).
-	//
-	// Moving this test case around within the overall tests may
-	// affect the FDs obtained and hence the checks to catch these cases.
-	npipes := 2
-	c := helperCommand(t, "extraFilesAndPipes", strconv.Itoa(npipes+1))
-	rd, wr, _ := os.Pipe()
-	defer rd.Close()
-	if rd.Fd() != 3 {
-		t.Errorf("bad test value for test pipe: fd %d", rd.Fd())
-	}
-	stderr, _ := c.StderrPipe()
-	wr.WriteString("_LAST")
-	wr.Close()
-
-	pipes := make([]struct {
-		r, w *os.File
-	}, npipes)
-	data := []string{"a", "b"}
-
-	for i := 0; i < npipes; i++ {
-		r, w, err := os.Pipe()
-		if err != nil {
-			t.Fatalf("unexpected error creating pipe: %s", err)
-		}
-		pipes[i].r = r
-		pipes[i].w = w
-		w.WriteString(data[i])
-		c.ExtraFiles = append(c.ExtraFiles, pipes[i].r)
-		defer func() {
-			r.Close()
-			w.Close()
-		}()
-	}
-	// Put fd 3 at the end.
-	c.ExtraFiles = append(c.ExtraFiles, rd)
-
-	stderrFd := int(stderr.(*os.File).Fd())
-	if stderrFd != ((len(c.ExtraFiles) + 3) - 1) {
-		t.Errorf("bad test value for stderr pipe")
-	}
-
-	expected := "child: " + strings.Join(data, "") + "_LAST"
-
-	err := c.Start()
-	if err != nil {
-		t.Fatalf("Run: %v", err)
-	}
-	ch := make(chan string, 1)
-	go func(ch chan string) {
-		buf := make([]byte, 512)
-		n, err := stderr.Read(buf)
-		if err != nil {
-			t.Fatalf("Read: %s", err)
-			ch <- err.Error()
-		} else {
-			ch <- string(buf[:n])
-		}
-		close(ch)
-	}(ch)
-	select {
-	case m := <-ch:
-		if m != expected {
-			t.Errorf("Read: '%s' not '%s'", m, expected)
-		}
-	case <-time.After(5 * time.Second):
-		t.Errorf("Read timedout")
-	}
-	c.Wait()
-}
-
-func TestExtraFiles(t *testing.T) {
-	if runtime.GOOS == "windows" {
-		t.Skip("no operating system support; skipping")
-	}
-
-	// Ensure that file descriptors have not already been leaked into
-	// our environment.
-	if !testedAlreadyLeaked {
-		testedAlreadyLeaked = true
-		closeUnexpectedFds(t, "TestExtraFiles")
-	}
-
-	// Force network usage, to verify the epoll (or whatever) fd
-	// doesn't leak to the child,
-	ln, err := net.Listen("tcp", "127.0.0.1:0")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer ln.Close()
-
-	// Make sure duplicated fds don't leak to the child.
-	f, err := ln.(*net.TCPListener).File()
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer f.Close()
-	ln2, err := net.FileListener(f)
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer ln2.Close()
-
-	// Force TLS root certs to be loaded (which might involve
-	// cgo), to make sure none of that potential C code leaks fds.
-	ts := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {}))
-	// quiet expected TLS handshake error "remote error: bad certificate"
-	ts.Config.ErrorLog = log.New(ioutil.Discard, "", 0)
-	ts.StartTLS()
-	defer ts.Close()
-	_, err = http.Get(ts.URL)
-	if err == nil {
-		t.Errorf("success trying to fetch %s; want an error", ts.URL)
-	}
-
-	tf, err := ioutil.TempFile("", "")
-	if err != nil {
-		t.Fatalf("TempFile: %v", err)
-	}
-	defer os.Remove(tf.Name())
-	defer tf.Close()
-
-	const text = "Hello, fd 3!"
-	_, err = tf.Write([]byte(text))
-	if err != nil {
-		t.Fatalf("Write: %v", err)
-	}
-	_, err = tf.Seek(0, os.SEEK_SET)
-	if err != nil {
-		t.Fatalf("Seek: %v", err)
-	}
-
-	c := helperCommand(t, "read3")
-	var stdout, stderr bytes.Buffer
-	c.Stdout = &stdout
-	c.Stderr = &stderr
-	c.ExtraFiles = []*os.File{tf}
-	err = c.Run()
-	if err != nil {
-		t.Fatalf("Run: %v; stdout %q, stderr %q", err, stdout.Bytes(), stderr.Bytes())
-	}
-	if stdout.String() != text {
-		t.Errorf("got stdout %q, stderr %q; want %q on stdout", stdout.String(), stderr.String(), text)
-	}
-}
-
-func TestExtraFilesRace(t *testing.T) {
-	if runtime.GOOS == "windows" {
-		t.Skip("no operating system support; skipping")
-	}
-	listen := func() net.Listener {
-		ln, err := net.Listen("tcp", "127.0.0.1:0")
-		if err != nil {
-			t.Fatal(err)
-		}
-		return ln
-	}
-	listenerFile := func(ln net.Listener) *os.File {
-		f, err := ln.(*net.TCPListener).File()
-		if err != nil {
-			t.Fatal(err)
-		}
-		return f
-	}
-	runCommand := func(c *exec.Cmd, out chan<- string) {
-		bout, err := c.CombinedOutput()
-		if err != nil {
-			out <- "ERROR:" + err.Error()
-		} else {
-			out <- string(bout)
-		}
-	}
-
-	for i := 0; i < 10; i++ {
-		la := listen()
-		ca := helperCommand(t, "describefiles")
-		ca.ExtraFiles = []*os.File{listenerFile(la)}
-		lb := listen()
-		cb := helperCommand(t, "describefiles")
-		cb.ExtraFiles = []*os.File{listenerFile(lb)}
-		ares := make(chan string)
-		bres := make(chan string)
-		go runCommand(ca, ares)
-		go runCommand(cb, bres)
-		if got, want := <-ares, fmt.Sprintf("fd3: listener %s\n", la.Addr()); got != want {
-			t.Errorf("iteration %d, process A got:\n%s\nwant:\n%s\n", i, got, want)
-		}
-		if got, want := <-bres, fmt.Sprintf("fd3: listener %s\n", lb.Addr()); got != want {
-			t.Errorf("iteration %d, process B got:\n%s\nwant:\n%s\n", i, got, want)
-		}
-		la.Close()
-		lb.Close()
-		for _, f := range ca.ExtraFiles {
-			f.Close()
-		}
-		for _, f := range cb.ExtraFiles {
-			f.Close()
-		}
-
-	}
-}
-
-// TestHelperProcess isn't a real test. It's used as a helper process
-// for TestParameterRun.
-func TestHelperProcess(*testing.T) {
-	if os.Getenv("GO_WANT_HELPER_PROCESS") != "1" {
-		return
-	}
-	defer os.Exit(0)
-
-	// Determine which command to use to display open files.
-	ofcmd := "lsof"
-	switch runtime.GOOS {
-	case "dragonfly", "freebsd", "netbsd", "openbsd":
-		ofcmd = "fstat"
-	case "plan9":
-		ofcmd = "/bin/cat"
-	}
-
-	args := os.Args
-	for len(args) > 0 {
-		if args[0] == "--" {
-			args = args[1:]
-			break
-		}
-		args = args[1:]
-	}
-	if len(args) == 0 {
-		fmt.Fprintf(os.Stderr, "No command\n")
-		os.Exit(2)
-	}
-
-	cmd, args := args[0], args[1:]
-	switch cmd {
-	case "echo":
-		iargs := []interface{}{}
-		for _, s := range args {
-			iargs = append(iargs, s)
-		}
-		fmt.Println(iargs...)
-	case "cat":
-		if len(args) == 0 {
-			io.Copy(os.Stdout, os.Stdin)
-			return
-		}
-		exit := 0
-		for _, fn := range args {
-			f, err := os.Open(fn)
-			if err != nil {
-				fmt.Fprintf(os.Stderr, "Error: %v\n", err)
-				exit = 2
-			} else {
-				defer f.Close()
-				io.Copy(os.Stdout, f)
-			}
-		}
-		os.Exit(exit)
-	case "pipetest":
-		bufr := bufio.NewReader(os.Stdin)
-		for {
-			line, _, err := bufr.ReadLine()
-			if err == io.EOF {
-				break
-			} else if err != nil {
-				os.Exit(1)
-			}
-			if bytes.HasPrefix(line, []byte("O:")) {
-				os.Stdout.Write(line)
-				os.Stdout.Write([]byte{'\n'})
-			} else if bytes.HasPrefix(line, []byte("E:")) {
-				os.Stderr.Write(line)
-				os.Stderr.Write([]byte{'\n'})
-			} else {
-				os.Exit(1)
-			}
-		}
-	case "stdinClose":
-		b, err := ioutil.ReadAll(os.Stdin)
-		if err != nil {
-			fmt.Fprintf(os.Stderr, "Error: %v\n", err)
-			os.Exit(1)
-		}
-		if s := string(b); s != stdinCloseTestString {
-			fmt.Fprintf(os.Stderr, "Error: Read %q, want %q", s, stdinCloseTestString)
-			os.Exit(1)
-		}
-		os.Exit(0)
-	case "read3": // read fd 3
-		fd3 := os.NewFile(3, "fd3")
-		bs, err := ioutil.ReadAll(fd3)
-		if err != nil {
-			fmt.Printf("ReadAll from fd 3: %v", err)
-			os.Exit(1)
-		}
-		switch runtime.GOOS {
-		case "dragonfly":
-			// TODO(jsing): Determine why DragonFly is leaking
-			// file descriptors...
-		case "darwin":
-			// TODO(bradfitz): broken? Sometimes.
-			// http://golang.org/issue/2603
-			// Skip this additional part of the test for now.
-		case "netbsd":
-			// TODO(jsing): This currently fails on NetBSD due to
-			// the cloned file descriptors that result from opening
-			// /dev/urandom.
-			// http://golang.org/issue/3955
-		case "plan9":
-			// TODO(0intro): Determine why Plan 9 is leaking
-			// file descriptors.
-			// http://golang.org/issue/7118
-		case "solaris":
-			// TODO(aram): This fails on Solaris because libc opens
-			// its own files, as it sees fit. Darwin does the same,
-			// see: http://golang.org/issue/2603
-		default:
-			// Now verify that there are no other open fds.
-			var files []*os.File
-			for wantfd := basefds() + 1; wantfd <= 100; wantfd++ {
-				f, err := os.Open(os.Args[0])
-				if err != nil {
-					fmt.Printf("error opening file with expected fd %d: %v", wantfd, err)
-					os.Exit(1)
-				}
-				if got := f.Fd(); got != wantfd {
-					fmt.Printf("leaked parent file. fd = %d; want %d\n", got, wantfd)
-					var args []string
-					switch runtime.GOOS {
-					case "plan9":
-						args = []string{fmt.Sprintf("/proc/%d/fd", os.Getpid())}
-					default:
-						args = []string{"-p", fmt.Sprint(os.Getpid())}
-					}
-					out, _ := exec.Command(ofcmd, args...).CombinedOutput()
-					fmt.Print(string(out))
-					os.Exit(1)
-				}
-				files = append(files, f)
-			}
-			for _, f := range files {
-				f.Close()
-			}
-		}
-		// Referring to fd3 here ensures that it is not
-		// garbage collected, and therefore closed, while
-		// executing the wantfd loop above.  It doesn't matter
-		// what we do with fd3 as long as we refer to it;
-		// closing it is the easy choice.
-		fd3.Close()
-		os.Stdout.Write(bs)
-	case "exit":
-		n, _ := strconv.Atoi(args[0])
-		os.Exit(n)
-	case "describefiles":
-		f := os.NewFile(3, fmt.Sprintf("fd3"))
-		ln, err := net.FileListener(f)
-		if err == nil {
-			fmt.Printf("fd3: listener %s\n", ln.Addr())
-			ln.Close()
-		}
-		os.Exit(0)
-	case "extraFilesAndPipes":
-		n, _ := strconv.Atoi(args[0])
-		pipes := make([]*os.File, n)
-		for i := 0; i < n; i++ {
-			pipes[i] = os.NewFile(uintptr(3+i), strconv.Itoa(i))
-		}
-		response := ""
-		for i, r := range pipes {
-			ch := make(chan string, 1)
-			go func(c chan string) {
-				buf := make([]byte, 10)
-				n, err := r.Read(buf)
-				if err != nil {
-					fmt.Fprintf(os.Stderr, "Child: read error: %v on pipe %d\n", err, i)
-					os.Exit(1)
-				}
-				c <- string(buf[:n])
-				close(c)
-			}(ch)
-			select {
-			case m := <-ch:
-				response = response + m
-			case <-time.After(5 * time.Second):
-				fmt.Fprintf(os.Stderr, "Child: Timeout reading from pipe: %d\n", i)
-				os.Exit(1)
-			}
-		}
-		fmt.Fprintf(os.Stderr, "child: %s", response)
-		os.Exit(0)
-	case "exec":
-		cmd := exec.Command(args[1])
-		cmd.Dir = args[0]
-		output, err := cmd.CombinedOutput()
-		if err != nil {
-			fmt.Fprintf(os.Stderr, "Child: %s %s", err, string(output))
-			os.Exit(1)
-		}
-		fmt.Printf("%s", string(output))
-		os.Exit(0)
-	case "lookpath":
-		p, err := exec.LookPath(args[0])
-		if err != nil {
-			fmt.Fprintf(os.Stderr, "LookPath failed: %v\n", err)
-			os.Exit(1)
-		}
-		fmt.Print(p)
-		os.Exit(0)
-	default:
-		fmt.Fprintf(os.Stderr, "Unknown command %q\n", cmd)
-		os.Exit(2)
-	}
-}
diff --git a/src/pkg/os/exec_unix.go b/src/pkg/os/exec_unix.go
deleted file mode 100644
index 1b1e335..0000000
--- a/src/pkg/os/exec_unix.go
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris
-
-package os
-
-import (
-	"errors"
-	"runtime"
-	"syscall"
-	"time"
-)
-
-func (p *Process) wait() (ps *ProcessState, err error) {
-	if p.Pid == -1 {
-		return nil, syscall.EINVAL
-	}
-	var status syscall.WaitStatus
-	var rusage syscall.Rusage
-	pid1, e := syscall.Wait4(p.Pid, &status, 0, &rusage)
-	if e != nil {
-		return nil, NewSyscallError("wait", e)
-	}
-	if pid1 != 0 {
-		p.setDone()
-	}
-	ps = &ProcessState{
-		pid:    pid1,
-		status: status,
-		rusage: &rusage,
-	}
-	return ps, nil
-}
-
-func (p *Process) signal(sig Signal) error {
-	if p.done() {
-		return errors.New("os: process already finished")
-	}
-	if p.Pid == -1 {
-		return errors.New("os: process already released")
-	}
-	s, ok := sig.(syscall.Signal)
-	if !ok {
-		return errors.New("os: unsupported signal type")
-	}
-	if e := syscall.Kill(p.Pid, s); e != nil {
-		return e
-	}
-	return nil
-}
-
-func (p *Process) release() error {
-	// NOOP for unix.
-	p.Pid = -1
-	// no need for a finalizer anymore
-	runtime.SetFinalizer(p, nil)
-	return nil
-}
-
-func findProcess(pid int) (p *Process, err error) {
-	// NOOP for unix.
-	return newProcess(pid, 0), nil
-}
-
-func (p *ProcessState) userTime() time.Duration {
-	return time.Duration(p.rusage.Utime.Nano()) * time.Nanosecond
-}
-
-func (p *ProcessState) systemTime() time.Duration {
-	return time.Duration(p.rusage.Stime.Nano()) * time.Nanosecond
-}
diff --git a/src/pkg/os/exec_windows.go b/src/pkg/os/exec_windows.go
deleted file mode 100644
index c4f3d4f..0000000
--- a/src/pkg/os/exec_windows.go
+++ /dev/null
@@ -1,115 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package os
-
-import (
-	"errors"
-	"runtime"
-	"syscall"
-	"time"
-	"unsafe"
-)
-
-func (p *Process) wait() (ps *ProcessState, err error) {
-	s, e := syscall.WaitForSingleObject(syscall.Handle(p.handle), syscall.INFINITE)
-	switch s {
-	case syscall.WAIT_OBJECT_0:
-		break
-	case syscall.WAIT_FAILED:
-		return nil, NewSyscallError("WaitForSingleObject", e)
-	default:
-		return nil, errors.New("os: unexpected result from WaitForSingleObject")
-	}
-	var ec uint32
-	e = syscall.GetExitCodeProcess(syscall.Handle(p.handle), &ec)
-	if e != nil {
-		return nil, NewSyscallError("GetExitCodeProcess", e)
-	}
-	var u syscall.Rusage
-	e = syscall.GetProcessTimes(syscall.Handle(p.handle), &u.CreationTime, &u.ExitTime, &u.KernelTime, &u.UserTime)
-	if e != nil {
-		return nil, NewSyscallError("GetProcessTimes", e)
-	}
-	p.setDone()
-	// NOTE(brainman): It seems that sometimes process is not dead
-	// when WaitForSingleObject returns. But we do not know any
-	// other way to wait for it. Sleeping for a while seems to do
-	// the trick sometimes. So we will sleep and smell the roses.
-	defer time.Sleep(5 * time.Millisecond)
-	defer p.Release()
-	return &ProcessState{p.Pid, syscall.WaitStatus{ExitCode: ec}, &u}, nil
-}
-
-func terminateProcess(pid, exitcode int) error {
-	h, e := syscall.OpenProcess(syscall.PROCESS_TERMINATE, false, uint32(pid))
-	if e != nil {
-		return NewSyscallError("OpenProcess", e)
-	}
-	defer syscall.CloseHandle(h)
-	e = syscall.TerminateProcess(h, uint32(exitcode))
-	return NewSyscallError("TerminateProcess", e)
-}
-
-func (p *Process) signal(sig Signal) error {
-	if p.done() {
-		return errors.New("os: process already finished")
-	}
-	if sig == Kill {
-		return terminateProcess(p.Pid, 1)
-	}
-	// TODO(rsc): Handle Interrupt too?
-	return syscall.Errno(syscall.EWINDOWS)
-}
-
-func (p *Process) release() error {
-	if p.handle == uintptr(syscall.InvalidHandle) {
-		return syscall.EINVAL
-	}
-	e := syscall.CloseHandle(syscall.Handle(p.handle))
-	if e != nil {
-		return NewSyscallError("CloseHandle", e)
-	}
-	p.handle = uintptr(syscall.InvalidHandle)
-	// no need for a finalizer anymore
-	runtime.SetFinalizer(p, nil)
-	return nil
-}
-
-func findProcess(pid int) (p *Process, err error) {
-	const da = syscall.STANDARD_RIGHTS_READ |
-		syscall.PROCESS_QUERY_INFORMATION | syscall.SYNCHRONIZE
-	h, e := syscall.OpenProcess(da, false, uint32(pid))
-	if e != nil {
-		return nil, NewSyscallError("OpenProcess", e)
-	}
-	return newProcess(pid, uintptr(h)), nil
-}
-
-func init() {
-	var argc int32
-	cmd := syscall.GetCommandLine()
-	argv, e := syscall.CommandLineToArgv(cmd, &argc)
-	if e != nil {
-		return
-	}
-	defer syscall.LocalFree(syscall.Handle(uintptr(unsafe.Pointer(argv))))
-	Args = make([]string, argc)
-	for i, v := range (*argv)[:argc] {
-		Args[i] = string(syscall.UTF16ToString((*v)[:]))
-	}
-}
-
-func ftToDuration(ft *syscall.Filetime) time.Duration {
-	n := int64(ft.HighDateTime)<<32 + int64(ft.LowDateTime) // in 100-nanosecond intervals
-	return time.Duration(n*100) * time.Nanosecond
-}
-
-func (p *ProcessState) userTime() time.Duration {
-	return ftToDuration(&p.rusage.UserTime)
-}
-
-func (p *ProcessState) systemTime() time.Duration {
-	return ftToDuration(&p.rusage.KernelTime)
-}
diff --git a/src/pkg/os/file.go b/src/pkg/os/file.go
deleted file mode 100644
index b4a7458..0000000
--- a/src/pkg/os/file.go
+++ /dev/null
@@ -1,257 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package os provides a platform-independent interface to operating system
-// functionality. The design is Unix-like, although the error handling is
-// Go-like; failing calls return values of type error rather than error numbers.
-// Often, more information is available within the error. For example,
-// if a call that takes a file name fails, such as Open or Stat, the error
-// will include the failing file name when printed and will be of type
-// *PathError, which may be unpacked for more information.
-//
-// The os interface is intended to be uniform across all operating systems.
-// Features not generally available appear in the system-specific package syscall.
-//
-// Here is a simple example, opening a file and reading some of it.
-//
-//	file, err := os.Open("file.go") // For read access.
-//	if err != nil {
-//		log.Fatal(err)
-//	}
-//
-// If the open fails, the error string will be self-explanatory, like
-//
-//	open file.go: no such file or directory
-//
-// The file's data can then be read into a slice of bytes. Read and
-// Write take their byte counts from the length of the argument slice.
-//
-//	data := make([]byte, 100)
-//	count, err := file.Read(data)
-//	if err != nil {
-//		log.Fatal(err)
-//	}
-//	fmt.Printf("read %d bytes: %q\n", count, data[:count])
-//
-package os
-
-import (
-	"io"
-	"syscall"
-)
-
-// Name returns the name of the file as presented to Open.
-func (f *File) Name() string { return f.name }
-
-// Stdin, Stdout, and Stderr are open Files pointing to the standard input,
-// standard output, and standard error file descriptors.
-var (
-	Stdin  = NewFile(uintptr(syscall.Stdin), "/dev/stdin")
-	Stdout = NewFile(uintptr(syscall.Stdout), "/dev/stdout")
-	Stderr = NewFile(uintptr(syscall.Stderr), "/dev/stderr")
-)
-
-// Flags to Open wrapping those of the underlying system. Not all flags
-// may be implemented on a given system.
-const (
-	O_RDONLY int = syscall.O_RDONLY // open the file read-only.
-	O_WRONLY int = syscall.O_WRONLY // open the file write-only.
-	O_RDWR   int = syscall.O_RDWR   // open the file read-write.
-	O_APPEND int = syscall.O_APPEND // append data to the file when writing.
-	O_CREATE int = syscall.O_CREAT  // create a new file if none exists.
-	O_EXCL   int = syscall.O_EXCL   // used with O_CREATE, file must not exist
-	O_SYNC   int = syscall.O_SYNC   // open for synchronous I/O.
-	O_TRUNC  int = syscall.O_TRUNC  // if possible, truncate file when opened.
-)
-
-// Seek whence values.
-const (
-	SEEK_SET int = 0 // seek relative to the origin of the file
-	SEEK_CUR int = 1 // seek relative to the current offset
-	SEEK_END int = 2 // seek relative to the end
-)
-
-// LinkError records an error during a link or symlink or rename
-// system call and the paths that caused it.
-type LinkError struct {
-	Op  string
-	Old string
-	New string
-	Err error
-}
-
-func (e *LinkError) Error() string {
-	return e.Op + " " + e.Old + " " + e.New + ": " + e.Err.Error()
-}
-
-// Read reads up to len(b) bytes from the File.
-// It returns the number of bytes read and an error, if any.
-// EOF is signaled by a zero count with err set to io.EOF.
-func (f *File) Read(b []byte) (n int, err error) {
-	if f == nil {
-		return 0, ErrInvalid
-	}
-	n, e := f.read(b)
-	if n < 0 {
-		n = 0
-	}
-	if n == 0 && len(b) > 0 && e == nil {
-		return 0, io.EOF
-	}
-	if e != nil {
-		err = &PathError{"read", f.name, e}
-	}
-	return n, err
-}
-
-// ReadAt reads len(b) bytes from the File starting at byte offset off.
-// It returns the number of bytes read and the error, if any.
-// ReadAt always returns a non-nil error when n < len(b).
-// At end of file, that error is io.EOF.
-func (f *File) ReadAt(b []byte, off int64) (n int, err error) {
-	if f == nil {
-		return 0, ErrInvalid
-	}
-	for len(b) > 0 {
-		m, e := f.pread(b, off)
-		if m == 0 && e == nil {
-			return n, io.EOF
-		}
-		if e != nil {
-			err = &PathError{"read", f.name, e}
-			break
-		}
-		n += m
-		b = b[m:]
-		off += int64(m)
-	}
-	return
-}
-
-// Write writes len(b) bytes to the File.
-// It returns the number of bytes written and an error, if any.
-// Write returns a non-nil error when n != len(b).
-func (f *File) Write(b []byte) (n int, err error) {
-	if f == nil {
-		return 0, ErrInvalid
-	}
-	n, e := f.write(b)
-	if n < 0 {
-		n = 0
-	}
-	if n != len(b) {
-		err = io.ErrShortWrite
-	}
-
-	epipecheck(f, e)
-
-	if e != nil {
-		err = &PathError{"write", f.name, e}
-	}
-	return n, err
-}
-
-// WriteAt writes len(b) bytes to the File starting at byte offset off.
-// It returns the number of bytes written and an error, if any.
-// WriteAt returns a non-nil error when n != len(b).
-func (f *File) WriteAt(b []byte, off int64) (n int, err error) {
-	if f == nil {
-		return 0, ErrInvalid
-	}
-	for len(b) > 0 {
-		m, e := f.pwrite(b, off)
-		if e != nil {
-			err = &PathError{"write", f.name, e}
-			break
-		}
-		n += m
-		b = b[m:]
-		off += int64(m)
-	}
-	return
-}
-
-// Seek sets the offset for the next Read or Write on file to offset, interpreted
-// according to whence: 0 means relative to the origin of the file, 1 means
-// relative to the current offset, and 2 means relative to the end.
-// It returns the new offset and an error, if any.
-func (f *File) Seek(offset int64, whence int) (ret int64, err error) {
-	if f == nil {
-		return 0, ErrInvalid
-	}
-	r, e := f.seek(offset, whence)
-	if e == nil && f.dirinfo != nil && r != 0 {
-		e = syscall.EISDIR
-	}
-	if e != nil {
-		return 0, &PathError{"seek", f.name, e}
-	}
-	return r, nil
-}
-
-// WriteString is like Write, but writes the contents of string s rather than
-// a slice of bytes.
-func (f *File) WriteString(s string) (ret int, err error) {
-	if f == nil {
-		return 0, ErrInvalid
-	}
-	return f.Write([]byte(s))
-}
-
-// Mkdir creates a new directory with the specified name and permission bits.
-// If there is an error, it will be of type *PathError.
-func Mkdir(name string, perm FileMode) error {
-	e := syscall.Mkdir(name, syscallMode(perm))
-	if e != nil {
-		return &PathError{"mkdir", name, e}
-	}
-	return nil
-}
-
-// Chdir changes the current working directory to the named directory.
-// If there is an error, it will be of type *PathError.
-func Chdir(dir string) error {
-	if e := syscall.Chdir(dir); e != nil {
-		return &PathError{"chdir", dir, e}
-	}
-	return nil
-}
-
-// Chdir changes the current working directory to the file,
-// which must be a directory.
-// If there is an error, it will be of type *PathError.
-func (f *File) Chdir() error {
-	if f == nil {
-		return ErrInvalid
-	}
-	if e := syscall.Fchdir(f.fd); e != nil {
-		return &PathError{"chdir", f.name, e}
-	}
-	return nil
-}
-
-// Open opens the named file for reading.  If successful, methods on
-// the returned file can be used for reading; the associated file
-// descriptor has mode O_RDONLY.
-// If there is an error, it will be of type *PathError.
-func Open(name string) (file *File, err error) {
-	return OpenFile(name, O_RDONLY, 0)
-}
-
-// Create creates the named file mode 0666 (before umask), truncating
-// it if it already exists.  If successful, methods on the returned
-// File can be used for I/O; the associated file descriptor has mode
-// O_RDWR.
-// If there is an error, it will be of type *PathError.
-func Create(name string) (file *File, err error) {
-	return OpenFile(name, O_RDWR|O_CREATE|O_TRUNC, 0666)
-}
-
-// lstat is overridden in tests.
-var lstat = Lstat
-
-// Rename renames (moves) a file. OS-specific restrictions might apply.
-func Rename(oldpath, newpath string) error {
-	return rename(oldpath, newpath)
-}
diff --git a/src/pkg/os/file_plan9.go b/src/pkg/os/file_plan9.go
deleted file mode 100644
index a804b81..0000000
--- a/src/pkg/os/file_plan9.go
+++ /dev/null
@@ -1,468 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package os
-
-import (
-	"runtime"
-	"syscall"
-	"time"
-)
-
-// File represents an open file descriptor.
-type File struct {
-	*file
-}
-
-// file is the real representation of *File.
-// The extra level of indirection ensures that no clients of os
-// can overwrite this data, which could cause the finalizer
-// to close the wrong file descriptor.
-type file struct {
-	fd      int
-	name    string
-	dirinfo *dirInfo // nil unless directory being read
-}
-
-// Fd returns the integer Unix file descriptor referencing the open file.
-func (f *File) Fd() uintptr {
-	if f == nil {
-		return ^(uintptr(0))
-	}
-	return uintptr(f.fd)
-}
-
-// NewFile returns a new File with the given file descriptor and name.
-func NewFile(fd uintptr, name string) *File {
-	fdi := int(fd)
-	if fdi < 0 {
-		return nil
-	}
-	f := &File{&file{fd: fdi, name: name}}
-	runtime.SetFinalizer(f.file, (*file).close)
-	return f
-}
-
-// Auxiliary information if the File describes a directory
-type dirInfo struct {
-	buf  [syscall.STATMAX]byte // buffer for directory I/O
-	nbuf int                   // length of buf; return value from Read
-	bufp int                   // location of next record in buf.
-}
-
-func epipecheck(file *File, e error) {
-}
-
-// DevNull is the name of the operating system's ``null device.''
-// On Unix-like systems, it is "/dev/null"; on Windows, "NUL".
-const DevNull = "/dev/null"
-
-// syscallMode returns the syscall-specific mode bits from Go's portable mode bits.
-func syscallMode(i FileMode) (o uint32) {
-	o |= uint32(i.Perm())
-	if i&ModeAppend != 0 {
-		o |= syscall.DMAPPEND
-	}
-	if i&ModeExclusive != 0 {
-		o |= syscall.DMEXCL
-	}
-	if i&ModeTemporary != 0 {
-		o |= syscall.DMTMP
-	}
-	return
-}
-
-// OpenFile is the generalized open call; most users will use Open
-// or Create instead.  It opens the named file with specified flag
-// (O_RDONLY etc.) and perm, (0666 etc.) if applicable.  If successful,
-// methods on the returned File can be used for I/O.
-// If there is an error, it will be of type *PathError.
-func OpenFile(name string, flag int, perm FileMode) (file *File, err error) {
-	var (
-		fd     int
-		e      error
-		create bool
-		excl   bool
-		trunc  bool
-		append bool
-	)
-
-	if flag&O_CREATE == O_CREATE {
-		flag = flag & ^O_CREATE
-		create = true
-	}
-	if flag&O_EXCL == O_EXCL {
-		excl = true
-	}
-	if flag&O_TRUNC == O_TRUNC {
-		trunc = true
-	}
-	// O_APPEND is emulated on Plan 9
-	if flag&O_APPEND == O_APPEND {
-		flag = flag &^ O_APPEND
-		append = true
-	}
-
-	if (create && trunc) || excl {
-		fd, e = syscall.Create(name, flag, syscallMode(perm))
-	} else {
-		fd, e = syscall.Open(name, flag)
-		if e != nil && create {
-			var e1 error
-			fd, e1 = syscall.Create(name, flag, syscallMode(perm))
-			if e1 == nil {
-				e = nil
-			}
-		}
-	}
-
-	if e != nil {
-		return nil, &PathError{"open", name, e}
-	}
-
-	if append {
-		if _, e = syscall.Seek(fd, 0, SEEK_END); e != nil {
-			return nil, &PathError{"seek", name, e}
-		}
-	}
-
-	return NewFile(uintptr(fd), name), nil
-}
-
-// Close closes the File, rendering it unusable for I/O.
-// It returns an error, if any.
-func (f *File) Close() error {
-	if f == nil {
-		return ErrInvalid
-	}
-	return f.file.close()
-}
-
-func (file *file) close() error {
-	if file == nil || file.fd < 0 {
-		return ErrInvalid
-	}
-	var err error
-	syscall.ForkLock.RLock()
-	if e := syscall.Close(file.fd); e != nil {
-		err = &PathError{"close", file.name, e}
-	}
-	syscall.ForkLock.RUnlock()
-	file.fd = -1 // so it can't be closed again
-
-	// no need for a finalizer anymore
-	runtime.SetFinalizer(file, nil)
-	return err
-}
-
-// Stat returns the FileInfo structure describing file.
-// If there is an error, it will be of type *PathError.
-func (f *File) Stat() (fi FileInfo, err error) {
-	if f == nil {
-		return nil, ErrInvalid
-	}
-	d, err := dirstat(f)
-	if err != nil {
-		return nil, err
-	}
-	return fileInfoFromStat(d), nil
-}
-
-// Truncate changes the size of the file.
-// It does not change the I/O offset.
-// If there is an error, it will be of type *PathError.
-func (f *File) Truncate(size int64) error {
-	if f == nil {
-		return ErrInvalid
-	}
-
-	var d syscall.Dir
-	d.Null()
-	d.Length = size
-
-	var buf [syscall.STATFIXLEN]byte
-	n, err := d.Marshal(buf[:])
-	if err != nil {
-		return &PathError{"truncate", f.name, err}
-	}
-	if err = syscall.Fwstat(f.fd, buf[:n]); err != nil {
-		return &PathError{"truncate", f.name, err}
-	}
-	return nil
-}
-
-const chmodMask = uint32(syscall.DMAPPEND | syscall.DMEXCL | syscall.DMTMP | ModePerm)
-
-// Chmod changes the mode of the file to mode.
-// If there is an error, it will be of type *PathError.
-func (f *File) Chmod(mode FileMode) error {
-	if f == nil {
-		return ErrInvalid
-	}
-	var d syscall.Dir
-
-	odir, e := dirstat(f)
-	if e != nil {
-		return &PathError{"chmod", f.name, e}
-	}
-	d.Null()
-	d.Mode = odir.Mode&^chmodMask | syscallMode(mode)&chmodMask
-
-	var buf [syscall.STATFIXLEN]byte
-	n, err := d.Marshal(buf[:])
-	if err != nil {
-		return &PathError{"chmod", f.name, err}
-	}
-	if err = syscall.Fwstat(f.fd, buf[:n]); err != nil {
-		return &PathError{"chmod", f.name, err}
-	}
-	return nil
-}
-
-// Sync commits the current contents of the file to stable storage.
-// Typically, this means flushing the file system's in-memory copy
-// of recently written data to disk.
-func (f *File) Sync() (err error) {
-	if f == nil {
-		return ErrInvalid
-	}
-	var d syscall.Dir
-	d.Null()
-
-	var buf [syscall.STATFIXLEN]byte
-	n, err := d.Marshal(buf[:])
-	if err != nil {
-		return NewSyscallError("fsync", err)
-	}
-	if err = syscall.Fwstat(f.fd, buf[:n]); err != nil {
-		return NewSyscallError("fsync", err)
-	}
-	return nil
-}
-
-// read reads up to len(b) bytes from the File.
-// It returns the number of bytes read and an error, if any.
-func (f *File) read(b []byte) (n int, err error) {
-	return syscall.Read(f.fd, b)
-}
-
-// pread reads len(b) bytes from the File starting at byte offset off.
-// It returns the number of bytes read and the error, if any.
-// EOF is signaled by a zero count with err set to nil.
-func (f *File) pread(b []byte, off int64) (n int, err error) {
-	return syscall.Pread(f.fd, b, off)
-}
-
-// write writes len(b) bytes to the File.
-// It returns the number of bytes written and an error, if any.
-// Since Plan 9 preserves message boundaries, never allow
-// a zero-byte write.
-func (f *File) write(b []byte) (n int, err error) {
-	if len(b) == 0 {
-		return 0, nil
-	}
-	return syscall.Write(f.fd, b)
-}
-
-// pwrite writes len(b) bytes to the File starting at byte offset off.
-// It returns the number of bytes written and an error, if any.
-// Since Plan 9 preserves message boundaries, never allow
-// a zero-byte write.
-func (f *File) pwrite(b []byte, off int64) (n int, err error) {
-	if len(b) == 0 {
-		return 0, nil
-	}
-	return syscall.Pwrite(f.fd, b, off)
-}
-
-// seek sets the offset for the next Read or Write on file to offset, interpreted
-// according to whence: 0 means relative to the origin of the file, 1 means
-// relative to the current offset, and 2 means relative to the end.
-// It returns the new offset and an error, if any.
-func (f *File) seek(offset int64, whence int) (ret int64, err error) {
-	return syscall.Seek(f.fd, offset, whence)
-}
-
-// Truncate changes the size of the named file.
-// If the file is a symbolic link, it changes the size of the link's target.
-// If there is an error, it will be of type *PathError.
-func Truncate(name string, size int64) error {
-	var d syscall.Dir
-
-	d.Null()
-	d.Length = size
-
-	var buf [syscall.STATFIXLEN]byte
-	n, err := d.Marshal(buf[:])
-	if err != nil {
-		return &PathError{"truncate", name, err}
-	}
-	if err = syscall.Wstat(name, buf[:n]); err != nil {
-		return &PathError{"truncate", name, err}
-	}
-	return nil
-}
-
-// Remove removes the named file or directory.
-// If there is an error, it will be of type *PathError.
-func Remove(name string) error {
-	if e := syscall.Remove(name); e != nil {
-		return &PathError{"remove", name, e}
-	}
-	return nil
-}
-
-// HasPrefix from the strings package.
-func hasPrefix(s, prefix string) bool {
-	return len(s) >= len(prefix) && s[0:len(prefix)] == prefix
-}
-
-// Variant of LastIndex from the strings package.
-func lastIndex(s string, sep byte) int {
-	for i := len(s) - 1; i >= 0; i-- {
-		if s[i] == sep {
-			return i
-		}
-	}
-	return -1
-}
-
-func rename(oldname, newname string) error {
-	dirname := oldname[:lastIndex(oldname, '/')+1]
-	if hasPrefix(newname, dirname) {
-		newname = newname[len(dirname):]
-	} else {
-		return &LinkError{"rename", oldname, newname, ErrInvalid}
-	}
-
-	// If newname still contains slashes after removing the oldname
-	// prefix, the rename is cross-directory and must be rejected.
-	// This case is caught by d.Marshal below.
-
-	var d syscall.Dir
-
-	d.Null()
-	d.Name = newname
-
-	buf := make([]byte, syscall.STATFIXLEN+len(d.Name))
-	n, err := d.Marshal(buf[:])
-	if err != nil {
-		return &LinkError{"rename", oldname, newname, err}
-	}
-	if err = syscall.Wstat(oldname, buf[:n]); err != nil {
-		return &LinkError{"rename", oldname, newname, err}
-	}
-	return nil
-}
-
-// Chmod changes the mode of the named file to mode.
-// If the file is a symbolic link, it changes the mode of the link's target.
-// If there is an error, it will be of type *PathError.
-func Chmod(name string, mode FileMode) error {
-	var d syscall.Dir
-
-	odir, e := dirstat(name)
-	if e != nil {
-		return &PathError{"chmod", name, e}
-	}
-	d.Null()
-	d.Mode = odir.Mode&^chmodMask | syscallMode(mode)&chmodMask
-
-	var buf [syscall.STATFIXLEN]byte
-	n, err := d.Marshal(buf[:])
-	if err != nil {
-		return &PathError{"chmod", name, err}
-	}
-	if err = syscall.Wstat(name, buf[:n]); err != nil {
-		return &PathError{"chmod", name, err}
-	}
-	return nil
-}
-
-// Chtimes changes the access and modification times of the named
-// file, similar to the Unix utime() or utimes() functions.
-//
-// The underlying filesystem may truncate or round the values to a
-// less precise time unit.
-// If there is an error, it will be of type *PathError.
-func Chtimes(name string, atime time.Time, mtime time.Time) error {
-	var d syscall.Dir
-
-	d.Null()
-	d.Atime = uint32(atime.Unix())
-	d.Mtime = uint32(mtime.Unix())
-
-	var buf [syscall.STATFIXLEN]byte
-	n, err := d.Marshal(buf[:])
-	if err != nil {
-		return &PathError{"chtimes", name, err}
-	}
-	if err = syscall.Wstat(name, buf[:n]); err != nil {
-		return &PathError{"chtimes", name, err}
-	}
-	return nil
-}
-
-// Pipe returns a connected pair of Files; reads from r return bytes
-// written to w. It returns the files and an error, if any.
-func Pipe() (r *File, w *File, err error) {
-	var p [2]int
-
-	syscall.ForkLock.RLock()
-	if e := syscall.Pipe(p[0:]); e != nil {
-		syscall.ForkLock.RUnlock()
-		return nil, nil, NewSyscallError("pipe", e)
-	}
-	syscall.ForkLock.RUnlock()
-
-	return NewFile(uintptr(p[0]), "|0"), NewFile(uintptr(p[1]), "|1"), nil
-}
-
-// not supported on Plan 9
-
-// Link creates newname as a hard link to the oldname file.
-// If there is an error, it will be of type *LinkError.
-func Link(oldname, newname string) error {
-	return &LinkError{"link", oldname, newname, syscall.EPLAN9}
-}
-
-// Symlink creates newname as a symbolic link to oldname.
-// If there is an error, it will be of type *LinkError.
-func Symlink(oldname, newname string) error {
-	return &LinkError{"symlink", oldname, newname, syscall.EPLAN9}
-}
-
-// Readlink returns the destination of the named symbolic link.
-// If there is an error, it will be of type *PathError.
-func Readlink(name string) (string, error) {
-	return "", &PathError{"readlink", name, syscall.EPLAN9}
-}
-
-// Chown changes the numeric uid and gid of the named file.
-// If the file is a symbolic link, it changes the uid and gid of the link's target.
-// If there is an error, it will be of type *PathError.
-func Chown(name string, uid, gid int) error {
-	return &PathError{"chown", name, syscall.EPLAN9}
-}
-
-// Lchown changes the numeric uid and gid of the named file.
-// If the file is a symbolic link, it changes the uid and gid of the link itself.
-// If there is an error, it will be of type *PathError.
-func Lchown(name string, uid, gid int) error {
-	return &PathError{"lchown", name, syscall.EPLAN9}
-}
-
-// Chown changes the numeric uid and gid of the named file.
-// If there is an error, it will be of type *PathError.
-func (f *File) Chown(uid, gid int) error {
-	if f == nil {
-		return ErrInvalid
-	}
-	return &PathError{"chown", f.name, syscall.EPLAN9}
-}
-
-// TempDir returns the default directory to use for temporary files.
-func TempDir() string {
-	return "/tmp"
-}
diff --git a/src/pkg/os/file_posix.go b/src/pkg/os/file_posix.go
deleted file mode 100644
index b3466b1..0000000
--- a/src/pkg/os/file_posix.go
+++ /dev/null
@@ -1,169 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris windows
-
-package os
-
-import (
-	"syscall"
-	"time"
-)
-
-func sigpipe() // implemented in package runtime
-
-// Link creates newname as a hard link to the oldname file.
-// If there is an error, it will be of type *LinkError.
-func Link(oldname, newname string) error {
-	e := syscall.Link(oldname, newname)
-	if e != nil {
-		return &LinkError{"link", oldname, newname, e}
-	}
-	return nil
-}
-
-// Symlink creates newname as a symbolic link to oldname.
-// If there is an error, it will be of type *LinkError.
-func Symlink(oldname, newname string) error {
-	e := syscall.Symlink(oldname, newname)
-	if e != nil {
-		return &LinkError{"symlink", oldname, newname, e}
-	}
-	return nil
-}
-
-// Readlink returns the destination of the named symbolic link.
-// If there is an error, it will be of type *PathError.
-func Readlink(name string) (string, error) {
-	for len := 128; ; len *= 2 {
-		b := make([]byte, len)
-		n, e := syscall.Readlink(name, b)
-		if e != nil {
-			return "", &PathError{"readlink", name, e}
-		}
-		if n < len {
-			return string(b[0:n]), nil
-		}
-	}
-}
-
-func rename(oldname, newname string) error {
-	e := syscall.Rename(oldname, newname)
-	if e != nil {
-		return &LinkError{"rename", oldname, newname, e}
-	}
-	return nil
-}
-
-// syscallMode returns the syscall-specific mode bits from Go's portable mode bits.
-func syscallMode(i FileMode) (o uint32) {
-	o |= uint32(i.Perm())
-	if i&ModeSetuid != 0 {
-		o |= syscall.S_ISUID
-	}
-	if i&ModeSetgid != 0 {
-		o |= syscall.S_ISGID
-	}
-	if i&ModeSticky != 0 {
-		o |= syscall.S_ISVTX
-	}
-	// No mapping for Go's ModeTemporary (plan9 only).
-	return
-}
-
-// Chmod changes the mode of the named file to mode.
-// If the file is a symbolic link, it changes the mode of the link's target.
-// If there is an error, it will be of type *PathError.
-func Chmod(name string, mode FileMode) error {
-	if e := syscall.Chmod(name, syscallMode(mode)); e != nil {
-		return &PathError{"chmod", name, e}
-	}
-	return nil
-}
-
-// Chmod changes the mode of the file to mode.
-// If there is an error, it will be of type *PathError.
-func (f *File) Chmod(mode FileMode) error {
-	if f == nil {
-		return ErrInvalid
-	}
-	if e := syscall.Fchmod(f.fd, syscallMode(mode)); e != nil {
-		return &PathError{"chmod", f.name, e}
-	}
-	return nil
-}
-
-// Chown changes the numeric uid and gid of the named file.
-// If the file is a symbolic link, it changes the uid and gid of the link's target.
-// If there is an error, it will be of type *PathError.
-func Chown(name string, uid, gid int) error {
-	if e := syscall.Chown(name, uid, gid); e != nil {
-		return &PathError{"chown", name, e}
-	}
-	return nil
-}
-
-// Lchown changes the numeric uid and gid of the named file.
-// If the file is a symbolic link, it changes the uid and gid of the link itself.
-// If there is an error, it will be of type *PathError.
-func Lchown(name string, uid, gid int) error {
-	if e := syscall.Lchown(name, uid, gid); e != nil {
-		return &PathError{"lchown", name, e}
-	}
-	return nil
-}
-
-// Chown changes the numeric uid and gid of the named file.
-// If there is an error, it will be of type *PathError.
-func (f *File) Chown(uid, gid int) error {
-	if f == nil {
-		return ErrInvalid
-	}
-	if e := syscall.Fchown(f.fd, uid, gid); e != nil {
-		return &PathError{"chown", f.name, e}
-	}
-	return nil
-}
-
-// Truncate changes the size of the file.
-// It does not change the I/O offset.
-// If there is an error, it will be of type *PathError.
-func (f *File) Truncate(size int64) error {
-	if f == nil {
-		return ErrInvalid
-	}
-	if e := syscall.Ftruncate(f.fd, size); e != nil {
-		return &PathError{"truncate", f.name, e}
-	}
-	return nil
-}
-
-// Sync commits the current contents of the file to stable storage.
-// Typically, this means flushing the file system's in-memory copy
-// of recently written data to disk.
-func (f *File) Sync() (err error) {
-	if f == nil {
-		return ErrInvalid
-	}
-	if e := syscall.Fsync(f.fd); e != nil {
-		return NewSyscallError("fsync", e)
-	}
-	return nil
-}
-
-// Chtimes changes the access and modification times of the named
-// file, similar to the Unix utime() or utimes() functions.
-//
-// The underlying filesystem may truncate or round the values to a
-// less precise time unit.
-// If there is an error, it will be of type *PathError.
-func Chtimes(name string, atime time.Time, mtime time.Time) error {
-	var utimes [2]syscall.Timespec
-	utimes[0] = syscall.NsecToTimespec(atime.UnixNano())
-	utimes[1] = syscall.NsecToTimespec(mtime.UnixNano())
-	if e := syscall.UtimesNano(name, utimes[0:]); e != nil {
-		return &PathError{"chtimes", name, e}
-	}
-	return nil
-}
diff --git a/src/pkg/os/file_unix.go b/src/pkg/os/file_unix.go
deleted file mode 100644
index 7616833..0000000
--- a/src/pkg/os/file_unix.go
+++ /dev/null
@@ -1,314 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris
-
-package os
-
-import (
-	"runtime"
-	"sync/atomic"
-	"syscall"
-)
-
-// File represents an open file descriptor.
-type File struct {
-	*file
-}
-
-// file is the real representation of *File.
-// The extra level of indirection ensures that no clients of os
-// can overwrite this data, which could cause the finalizer
-// to close the wrong file descriptor.
-type file struct {
-	fd      int
-	name    string
-	dirinfo *dirInfo // nil unless directory being read
-	nepipe  int32    // number of consecutive EPIPE in Write
-}
-
-// Fd returns the integer Unix file descriptor referencing the open file.
-func (f *File) Fd() uintptr {
-	if f == nil {
-		return ^(uintptr(0))
-	}
-	return uintptr(f.fd)
-}
-
-// NewFile returns a new File with the given file descriptor and name.
-func NewFile(fd uintptr, name string) *File {
-	fdi := int(fd)
-	if fdi < 0 {
-		return nil
-	}
-	f := &File{&file{fd: fdi, name: name}}
-	runtime.SetFinalizer(f.file, (*file).close)
-	return f
-}
-
-// Auxiliary information if the File describes a directory
-type dirInfo struct {
-	buf  []byte // buffer for directory I/O
-	nbuf int    // length of buf; return value from Getdirentries
-	bufp int    // location of next record in buf.
-}
-
-func epipecheck(file *File, e error) {
-	if e == syscall.EPIPE {
-		if atomic.AddInt32(&file.nepipe, 1) >= 10 {
-			sigpipe()
-		}
-	} else {
-		atomic.StoreInt32(&file.nepipe, 0)
-	}
-}
-
-// DevNull is the name of the operating system's ``null device.''
-// On Unix-like systems, it is "/dev/null"; on Windows, "NUL".
-const DevNull = "/dev/null"
-
-// OpenFile is the generalized open call; most users will use Open
-// or Create instead.  It opens the named file with specified flag
-// (O_RDONLY etc.) and perm, (0666 etc.) if applicable.  If successful,
-// methods on the returned File can be used for I/O.
-// If there is an error, it will be of type *PathError.
-func OpenFile(name string, flag int, perm FileMode) (file *File, err error) {
-	r, e := syscall.Open(name, flag|syscall.O_CLOEXEC, syscallMode(perm))
-	if e != nil {
-		return nil, &PathError{"open", name, e}
-	}
-
-	// There's a race here with fork/exec, which we are
-	// content to live with.  See ../syscall/exec_unix.go.
-	if !supportsCloseOnExec {
-		syscall.CloseOnExec(r)
-	}
-
-	return NewFile(uintptr(r), name), nil
-}
-
-// Close closes the File, rendering it unusable for I/O.
-// It returns an error, if any.
-func (f *File) Close() error {
-	if f == nil {
-		return ErrInvalid
-	}
-	return f.file.close()
-}
-
-func (file *file) close() error {
-	if file == nil || file.fd < 0 {
-		return syscall.EINVAL
-	}
-	var err error
-	if e := syscall.Close(file.fd); e != nil {
-		err = &PathError{"close", file.name, e}
-	}
-	file.fd = -1 // so it can't be closed again
-
-	// no need for a finalizer anymore
-	runtime.SetFinalizer(file, nil)
-	return err
-}
-
-// Stat returns the FileInfo structure describing file.
-// If there is an error, it will be of type *PathError.
-func (f *File) Stat() (fi FileInfo, err error) {
-	if f == nil {
-		return nil, ErrInvalid
-	}
-	var stat syscall.Stat_t
-	err = syscall.Fstat(f.fd, &stat)
-	if err != nil {
-		return nil, &PathError{"stat", f.name, err}
-	}
-	return fileInfoFromStat(&stat, f.name), nil
-}
-
-// Stat returns a FileInfo describing the named file.
-// If there is an error, it will be of type *PathError.
-func Stat(name string) (fi FileInfo, err error) {
-	var stat syscall.Stat_t
-	err = syscall.Stat(name, &stat)
-	if err != nil {
-		return nil, &PathError{"stat", name, err}
-	}
-	return fileInfoFromStat(&stat, name), nil
-}
-
-// Lstat returns a FileInfo describing the named file.
-// If the file is a symbolic link, the returned FileInfo
-// describes the symbolic link.  Lstat makes no attempt to follow the link.
-// If there is an error, it will be of type *PathError.
-func Lstat(name string) (fi FileInfo, err error) {
-	var stat syscall.Stat_t
-	err = syscall.Lstat(name, &stat)
-	if err != nil {
-		return nil, &PathError{"lstat", name, err}
-	}
-	return fileInfoFromStat(&stat, name), nil
-}
-
-func (f *File) readdir(n int) (fi []FileInfo, err error) {
-	dirname := f.name
-	if dirname == "" {
-		dirname = "."
-	}
-	names, err := f.Readdirnames(n)
-	fi = make([]FileInfo, 0, len(names))
-	for _, filename := range names {
-		fip, lerr := lstat(dirname + "/" + filename)
-		if IsNotExist(lerr) {
-			// File disappeared between readdir + stat.
-			// Just treat it as if it didn't exist.
-			continue
-		}
-		if lerr != nil {
-			return fi, lerr
-		}
-		fi = append(fi, fip)
-	}
-	return fi, err
-}
-
-// Darwin and FreeBSD can't read or write 2GB+ at a time,
-// even on 64-bit systems. See golang.org/issue/7812.
-// Use 1GB instead of, say, 2GB-1, to keep subsequent
-// reads aligned.
-const (
-	needsMaxRW = runtime.GOOS == "darwin" || runtime.GOOS == "freebsd"
-	maxRW      = 1 << 30
-)
-
-// read reads up to len(b) bytes from the File.
-// It returns the number of bytes read and an error, if any.
-func (f *File) read(b []byte) (n int, err error) {
-	if needsMaxRW && len(b) > maxRW {
-		b = b[:maxRW]
-	}
-	return syscall.Read(f.fd, b)
-}
-
-// pread reads len(b) bytes from the File starting at byte offset off.
-// It returns the number of bytes read and the error, if any.
-// EOF is signaled by a zero count with err set to nil.
-func (f *File) pread(b []byte, off int64) (n int, err error) {
-	if needsMaxRW && len(b) > maxRW {
-		b = b[:maxRW]
-	}
-	return syscall.Pread(f.fd, b, off)
-}
-
-// write writes len(b) bytes to the File.
-// It returns the number of bytes written and an error, if any.
-func (f *File) write(b []byte) (n int, err error) {
-	for {
-		bcap := b
-		if needsMaxRW && len(bcap) > maxRW {
-			bcap = bcap[:maxRW]
-		}
-		m, err := syscall.Write(f.fd, bcap)
-		n += m
-
-		// If the syscall wrote some data but not all (short write)
-		// or it returned EINTR, then assume it stopped early for
-		// reasons that are uninteresting to the caller, and try again.
-		if 0 < m && m < len(bcap) || err == syscall.EINTR {
-			b = b[m:]
-			continue
-		}
-
-		if needsMaxRW && len(bcap) != len(b) && err == nil {
-			b = b[m:]
-			continue
-		}
-
-		return n, err
-	}
-}
-
-// pwrite writes len(b) bytes to the File starting at byte offset off.
-// It returns the number of bytes written and an error, if any.
-func (f *File) pwrite(b []byte, off int64) (n int, err error) {
-	if needsMaxRW && len(b) > maxRW {
-		b = b[:maxRW]
-	}
-	return syscall.Pwrite(f.fd, b, off)
-}
-
-// seek sets the offset for the next Read or Write on file to offset, interpreted
-// according to whence: 0 means relative to the origin of the file, 1 means
-// relative to the current offset, and 2 means relative to the end.
-// It returns the new offset and an error, if any.
-func (f *File) seek(offset int64, whence int) (ret int64, err error) {
-	return syscall.Seek(f.fd, offset, whence)
-}
-
-// Truncate changes the size of the named file.
-// If the file is a symbolic link, it changes the size of the link's target.
-// If there is an error, it will be of type *PathError.
-func Truncate(name string, size int64) error {
-	if e := syscall.Truncate(name, size); e != nil {
-		return &PathError{"truncate", name, e}
-	}
-	return nil
-}
-
-// Remove removes the named file or directory.
-// If there is an error, it will be of type *PathError.
-func Remove(name string) error {
-	// System call interface forces us to know
-	// whether name is a file or directory.
-	// Try both: it is cheaper on average than
-	// doing a Stat plus the right one.
-	e := syscall.Unlink(name)
-	if e == nil {
-		return nil
-	}
-	e1 := syscall.Rmdir(name)
-	if e1 == nil {
-		return nil
-	}
-
-	// Both failed: figure out which error to return.
-	// OS X and Linux differ on whether unlink(dir)
-	// returns EISDIR, so can't use that.  However,
-	// both agree that rmdir(file) returns ENOTDIR,
-	// so we can use that to decide which error is real.
-	// Rmdir might also return ENOTDIR if given a bad
-	// file path, like /etc/passwd/foo, but in that case,
-	// both errors will be ENOTDIR, so it's okay to
-	// use the error from unlink.
-	if e1 != syscall.ENOTDIR {
-		e = e1
-	}
-	return &PathError{"remove", name, e}
-}
-
-// basename removes trailing slashes and the leading directory name from path name
-func basename(name string) string {
-	i := len(name) - 1
-	// Remove trailing slashes
-	for ; i > 0 && name[i] == '/'; i-- {
-		name = name[:i]
-	}
-	// Remove leading directory name
-	for i--; i >= 0; i-- {
-		if name[i] == '/' {
-			name = name[i+1:]
-			break
-		}
-	}
-
-	return name
-}
-
-// TempDir returns the default directory to use for temporary files.
-func TempDir() string {
-	dir := Getenv("TMPDIR")
-	if dir == "" {
-		dir = "/tmp"
-	}
-	return dir
-}
diff --git a/src/pkg/os/file_windows.go b/src/pkg/os/file_windows.go
deleted file mode 100644
index efe8bc0..0000000
--- a/src/pkg/os/file_windows.go
+++ /dev/null
@@ -1,495 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package os
-
-import (
-	"io"
-	"runtime"
-	"sync"
-	"syscall"
-	"unicode/utf16"
-	"unicode/utf8"
-	"unsafe"
-)
-
-// File represents an open file descriptor.
-type File struct {
-	*file
-}
-
-// file is the real representation of *File.
-// The extra level of indirection ensures that no clients of os
-// can overwrite this data, which could cause the finalizer
-// to close the wrong file descriptor.
-type file struct {
-	fd      syscall.Handle
-	name    string
-	dirinfo *dirInfo   // nil unless directory being read
-	l       sync.Mutex // used to implement windows pread/pwrite
-
-	// only for console io
-	isConsole bool
-	lastbits  []byte // first few bytes of the last incomplete rune in last write
-	readbuf   []rune // input console buffer
-}
-
-// Fd returns the Windows handle referencing the open file.
-func (file *File) Fd() uintptr {
-	if file == nil {
-		return uintptr(syscall.InvalidHandle)
-	}
-	return uintptr(file.fd)
-}
-
-// newFile returns a new File with the given file handle and name.
-// Unlike NewFile, it does not check that h is syscall.InvalidHandle.
-func newFile(h syscall.Handle, name string) *File {
-	f := &File{&file{fd: h, name: name}}
-	var m uint32
-	if syscall.GetConsoleMode(f.fd, &m) == nil {
-		f.isConsole = true
-	}
-	runtime.SetFinalizer(f.file, (*file).close)
-	return f
-}
-
-// NewFile returns a new File with the given file descriptor and name.
-func NewFile(fd uintptr, name string) *File {
-	h := syscall.Handle(fd)
-	if h == syscall.InvalidHandle {
-		return nil
-	}
-	return newFile(h, name)
-}
-
-// Auxiliary information if the File describes a directory
-type dirInfo struct {
-	data     syscall.Win32finddata
-	needdata bool
-	path     string
-	isempty  bool // set if FindFirstFile returns ERROR_FILE_NOT_FOUND
-}
-
-func epipecheck(file *File, e error) {
-}
-
-const DevNull = "NUL"
-
-func (f *file) isdir() bool { return f != nil && f.dirinfo != nil }
-
-func openFile(name string, flag int, perm FileMode) (file *File, err error) {
-	r, e := syscall.Open(name, flag|syscall.O_CLOEXEC, syscallMode(perm))
-	if e != nil {
-		return nil, e
-	}
-	return NewFile(uintptr(r), name), nil
-}
-
-func openDir(name string) (file *File, err error) {
-	maskp, e := syscall.UTF16PtrFromString(name + `\*`)
-	if e != nil {
-		return nil, e
-	}
-	d := new(dirInfo)
-	r, e := syscall.FindFirstFile(maskp, &d.data)
-	if e != nil {
-		// FindFirstFile returns ERROR_FILE_NOT_FOUND when
-		// no matching files can be found. Then, if directory
-		// exists, we should proceed.
-		if e != syscall.ERROR_FILE_NOT_FOUND {
-			return nil, e
-		}
-		var fa syscall.Win32FileAttributeData
-		namep, e := syscall.UTF16PtrFromString(name)
-		if e != nil {
-			return nil, e
-		}
-		e = syscall.GetFileAttributesEx(namep, syscall.GetFileExInfoStandard, (*byte)(unsafe.Pointer(&fa)))
-		if e != nil {
-			return nil, e
-		}
-		if fa.FileAttributes&syscall.FILE_ATTRIBUTE_DIRECTORY == 0 {
-			return nil, e
-		}
-		d.isempty = true
-	}
-	d.path = name
-	if !isAbs(d.path) {
-		cwd, _ := Getwd()
-		d.path = cwd + `\` + d.path
-	}
-	f := newFile(r, name)
-	f.dirinfo = d
-	return f, nil
-}
-
-// OpenFile is the generalized open call; most users will use Open
-// or Create instead.  It opens the named file with specified flag
-// (O_RDONLY etc.) and perm, (0666 etc.) if applicable.  If successful,
-// methods on the returned File can be used for I/O.
-// If there is an error, it will be of type *PathError.
-func OpenFile(name string, flag int, perm FileMode) (file *File, err error) {
-	if name == "" {
-		return nil, &PathError{"open", name, syscall.ENOENT}
-	}
-	r, errf := openFile(name, flag, perm)
-	if errf == nil {
-		return r, nil
-	}
-	r, errd := openDir(name)
-	if errd == nil {
-		if flag&O_WRONLY != 0 || flag&O_RDWR != 0 {
-			r.Close()
-			return nil, &PathError{"open", name, syscall.EISDIR}
-		}
-		return r, nil
-	}
-	return nil, &PathError{"open", name, errf}
-}
-
-// Close closes the File, rendering it unusable for I/O.
-// It returns an error, if any.
-func (file *File) Close() error {
-	if file == nil {
-		return ErrInvalid
-	}
-	return file.file.close()
-}
-
-func (file *file) close() error {
-	if file == nil {
-		return syscall.EINVAL
-	}
-	if file.isdir() && file.dirinfo.isempty {
-		// "special" empty directories
-		return nil
-	}
-	if file.fd == syscall.InvalidHandle {
-		return syscall.EINVAL
-	}
-	var e error
-	if file.isdir() {
-		e = syscall.FindClose(syscall.Handle(file.fd))
-	} else {
-		e = syscall.CloseHandle(syscall.Handle(file.fd))
-	}
-	var err error
-	if e != nil {
-		err = &PathError{"close", file.name, e}
-	}
-	file.fd = syscall.InvalidHandle // so it can't be closed again
-
-	// no need for a finalizer anymore
-	runtime.SetFinalizer(file, nil)
-	return err
-}
-
-func (file *File) readdir(n int) (fi []FileInfo, err error) {
-	if file == nil {
-		return nil, syscall.EINVAL
-	}
-	if !file.isdir() {
-		return nil, &PathError{"Readdir", file.name, syscall.ENOTDIR}
-	}
-	if !file.dirinfo.isempty && file.fd == syscall.InvalidHandle {
-		return nil, syscall.EINVAL
-	}
-	wantAll := n <= 0
-	size := n
-	if wantAll {
-		n = -1
-		size = 100
-	}
-	fi = make([]FileInfo, 0, size) // Empty with room to grow.
-	d := &file.dirinfo.data
-	for n != 0 && !file.dirinfo.isempty {
-		if file.dirinfo.needdata {
-			e := syscall.FindNextFile(syscall.Handle(file.fd), d)
-			if e != nil {
-				if e == syscall.ERROR_NO_MORE_FILES {
-					break
-				} else {
-					err = &PathError{"FindNextFile", file.name, e}
-					if !wantAll {
-						fi = nil
-					}
-					return
-				}
-			}
-		}
-		file.dirinfo.needdata = true
-		name := string(syscall.UTF16ToString(d.FileName[0:]))
-		if name == "." || name == ".." { // Useless names
-			continue
-		}
-		f := &fileStat{
-			name: name,
-			sys: syscall.Win32FileAttributeData{
-				FileAttributes: d.FileAttributes,
-				CreationTime:   d.CreationTime,
-				LastAccessTime: d.LastAccessTime,
-				LastWriteTime:  d.LastWriteTime,
-				FileSizeHigh:   d.FileSizeHigh,
-				FileSizeLow:    d.FileSizeLow,
-			},
-			path: file.dirinfo.path + `\` + name,
-		}
-		n--
-		fi = append(fi, f)
-	}
-	if !wantAll && len(fi) == 0 {
-		return fi, io.EOF
-	}
-	return fi, nil
-}
-
-// readConsole reads utf16 characters from console File,
-// encodes them into utf8 and stores them in buffer b.
-// It returns the number of utf8 bytes read and an error, if any.
-func (f *File) readConsole(b []byte) (n int, err error) {
-	if len(b) == 0 {
-		return 0, nil
-	}
-	if len(f.readbuf) == 0 {
-		// syscall.ReadConsole seems to fail, if given large buffer.
-		// So limit the buffer to 16000 characters.
-		numBytes := len(b)
-		if numBytes > 16000 {
-			numBytes = 16000
-		}
-		// get more input data from os
-		wchars := make([]uint16, numBytes)
-		var p *uint16
-		if len(b) > 0 {
-			p = &wchars[0]
-		}
-		var nw uint32
-		err := syscall.ReadConsole(f.fd, p, uint32(len(wchars)), &nw, nil)
-		if err != nil {
-			return 0, err
-		}
-		f.readbuf = utf16.Decode(wchars[:nw])
-	}
-	for i, r := range f.readbuf {
-		if utf8.RuneLen(r) > len(b) {
-			f.readbuf = f.readbuf[i:]
-			return n, nil
-		}
-		nr := utf8.EncodeRune(b, r)
-		b = b[nr:]
-		n += nr
-	}
-	f.readbuf = nil
-	return n, nil
-}
-
-// read reads up to len(b) bytes from the File.
-// It returns the number of bytes read and an error, if any.
-func (f *File) read(b []byte) (n int, err error) {
-	f.l.Lock()
-	defer f.l.Unlock()
-	if f.isConsole {
-		return f.readConsole(b)
-	}
-	return syscall.Read(f.fd, b)
-}
-
-// pread reads len(b) bytes from the File starting at byte offset off.
-// It returns the number of bytes read and the error, if any.
-// EOF is signaled by a zero count with err set to 0.
-func (f *File) pread(b []byte, off int64) (n int, err error) {
-	f.l.Lock()
-	defer f.l.Unlock()
-	curoffset, e := syscall.Seek(f.fd, 0, 1)
-	if e != nil {
-		return 0, e
-	}
-	defer syscall.Seek(f.fd, curoffset, 0)
-	o := syscall.Overlapped{
-		OffsetHigh: uint32(off >> 32),
-		Offset:     uint32(off),
-	}
-	var done uint32
-	e = syscall.ReadFile(syscall.Handle(f.fd), b, &done, &o)
-	if e != nil {
-		if e == syscall.ERROR_HANDLE_EOF {
-			// end of file
-			return 0, nil
-		}
-		return 0, e
-	}
-	return int(done), nil
-}
-
-// writeConsole writes len(b) bytes to the console File.
-// It returns the number of bytes written and an error, if any.
-func (f *File) writeConsole(b []byte) (n int, err error) {
-	n = len(b)
-	runes := make([]rune, 0, 256)
-	if len(f.lastbits) > 0 {
-		b = append(f.lastbits, b...)
-		f.lastbits = nil
-
-	}
-	for len(b) >= utf8.UTFMax || utf8.FullRune(b) {
-		r, l := utf8.DecodeRune(b)
-		runes = append(runes, r)
-		b = b[l:]
-	}
-	if len(b) > 0 {
-		f.lastbits = make([]byte, len(b))
-		copy(f.lastbits, b)
-	}
-	// syscall.WriteConsole seems to fail, if given large buffer.
-	// So limit the buffer to 16000 characters. This number was
-	// discovered by experimenting with syscall.WriteConsole.
-	const maxWrite = 16000
-	for len(runes) > 0 {
-		m := len(runes)
-		if m > maxWrite {
-			m = maxWrite
-		}
-		chunk := runes[:m]
-		runes = runes[m:]
-		uint16s := utf16.Encode(chunk)
-		for len(uint16s) > 0 {
-			var written uint32
-			err = syscall.WriteConsole(f.fd, &uint16s[0], uint32(len(uint16s)), &written, nil)
-			if err != nil {
-				return 0, nil
-			}
-			uint16s = uint16s[written:]
-		}
-	}
-	return n, nil
-}
-
-// write writes len(b) bytes to the File.
-// It returns the number of bytes written and an error, if any.
-func (f *File) write(b []byte) (n int, err error) {
-	f.l.Lock()
-	defer f.l.Unlock()
-	if f.isConsole {
-		return f.writeConsole(b)
-	}
-	return syscall.Write(f.fd, b)
-}
-
-// pwrite writes len(b) bytes to the File starting at byte offset off.
-// It returns the number of bytes written and an error, if any.
-func (f *File) pwrite(b []byte, off int64) (n int, err error) {
-	f.l.Lock()
-	defer f.l.Unlock()
-	curoffset, e := syscall.Seek(f.fd, 0, 1)
-	if e != nil {
-		return 0, e
-	}
-	defer syscall.Seek(f.fd, curoffset, 0)
-	o := syscall.Overlapped{
-		OffsetHigh: uint32(off >> 32),
-		Offset:     uint32(off),
-	}
-	var done uint32
-	e = syscall.WriteFile(syscall.Handle(f.fd), b, &done, &o)
-	if e != nil {
-		return 0, e
-	}
-	return int(done), nil
-}
-
-// seek sets the offset for the next Read or Write on file to offset, interpreted
-// according to whence: 0 means relative to the origin of the file, 1 means
-// relative to the current offset, and 2 means relative to the end.
-// It returns the new offset and an error, if any.
-func (f *File) seek(offset int64, whence int) (ret int64, err error) {
-	f.l.Lock()
-	defer f.l.Unlock()
-	return syscall.Seek(f.fd, offset, whence)
-}
-
-// Truncate changes the size of the named file.
-// If the file is a symbolic link, it changes the size of the link's target.
-func Truncate(name string, size int64) error {
-	f, e := OpenFile(name, O_WRONLY|O_CREATE, 0666)
-	if e != nil {
-		return e
-	}
-	defer f.Close()
-	e1 := f.Truncate(size)
-	if e1 != nil {
-		return e1
-	}
-	return nil
-}
-
-// Remove removes the named file or directory.
-// If there is an error, it will be of type *PathError.
-func Remove(name string) error {
-	p, e := syscall.UTF16PtrFromString(name)
-	if e != nil {
-		return &PathError{"remove", name, e}
-	}
-
-	// Go file interface forces us to know whether
-	// name is a file or directory. Try both.
-	e = syscall.DeleteFile(p)
-	if e == nil {
-		return nil
-	}
-	e1 := syscall.RemoveDirectory(p)
-	if e1 == nil {
-		return nil
-	}
-
-	// Both failed: figure out which error to return.
-	if e1 != e {
-		a, e2 := syscall.GetFileAttributes(p)
-		if e2 != nil {
-			e = e2
-		} else {
-			if a&syscall.FILE_ATTRIBUTE_DIRECTORY != 0 {
-				e = e1
-			}
-		}
-	}
-	return &PathError{"remove", name, e}
-}
-
-// Pipe returns a connected pair of Files; reads from r return bytes written to w.
-// It returns the files and an error, if any.
-func Pipe() (r *File, w *File, err error) {
-	var p [2]syscall.Handle
-
-	// See ../syscall/exec.go for description of lock.
-	syscall.ForkLock.RLock()
-	e := syscall.Pipe(p[0:])
-	if e != nil {
-		syscall.ForkLock.RUnlock()
-		return nil, nil, NewSyscallError("pipe", e)
-	}
-	syscall.CloseOnExec(p[0])
-	syscall.CloseOnExec(p[1])
-	syscall.ForkLock.RUnlock()
-
-	return NewFile(uintptr(p[0]), "|0"), NewFile(uintptr(p[1]), "|1"), nil
-}
-
-// TempDir returns the default directory to use for temporary files.
-func TempDir() string {
-	const pathSep = '\\'
-	dirw := make([]uint16, syscall.MAX_PATH)
-	n, _ := syscall.GetTempPath(uint32(len(dirw)), &dirw[0])
-	if n > uint32(len(dirw)) {
-		dirw = make([]uint16, n)
-		n, _ = syscall.GetTempPath(uint32(len(dirw)), &dirw[0])
-		if n > uint32(len(dirw)) {
-			n = 0
-		}
-	}
-	if n > 0 && dirw[n-1] == pathSep {
-		n--
-	}
-	return string(utf16.Decode(dirw[0:n]))
-}
diff --git a/src/pkg/os/getwd.go b/src/pkg/os/getwd.go
deleted file mode 100644
index a72edea..0000000
--- a/src/pkg/os/getwd.go
+++ /dev/null
@@ -1,119 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package os
-
-import (
-	"sync"
-	"syscall"
-)
-
-var getwdCache struct {
-	sync.Mutex
-	dir string
-}
-
-// useSyscallwd determines whether to use the return value of
-// syscall.Getwd based on its error.
-var useSyscallwd = func(error) bool { return true }
-
-// Getwd returns a rooted path name corresponding to the
-// current directory.  If the current directory can be
-// reached via multiple paths (due to symbolic links),
-// Getwd may return any one of them.
-func Getwd() (dir string, err error) {
-	// If the operating system provides a Getwd call, use it.
-	if syscall.ImplementsGetwd {
-		s, e := syscall.Getwd()
-		if useSyscallwd(e) {
-			return s, NewSyscallError("getwd", e)
-		}
-	}
-
-	// Otherwise, we're trying to find our way back to ".".
-	dot, err := Stat(".")
-	if err != nil {
-		return "", err
-	}
-
-	// Clumsy but widespread kludge:
-	// if $PWD is set and matches ".", use it.
-	dir = Getenv("PWD")
-	if len(dir) > 0 && dir[0] == '/' {
-		d, err := Stat(dir)
-		if err == nil && SameFile(dot, d) {
-			return dir, nil
-		}
-	}
-
-	// Apply same kludge but to cached dir instead of $PWD.
-	getwdCache.Lock()
-	dir = getwdCache.dir
-	getwdCache.Unlock()
-	if len(dir) > 0 {
-		d, err := Stat(dir)
-		if err == nil && SameFile(dot, d) {
-			return dir, nil
-		}
-	}
-
-	// Root is a special case because it has no parent
-	// and ends in a slash.
-	root, err := Stat("/")
-	if err != nil {
-		// Can't stat root - no hope.
-		return "", err
-	}
-	if SameFile(root, dot) {
-		return "/", nil
-	}
-
-	// General algorithm: find name in parent
-	// and then find name of parent.  Each iteration
-	// adds /name to the beginning of dir.
-	dir = ""
-	for parent := ".."; ; parent = "../" + parent {
-		if len(parent) >= 1024 { // Sanity check
-			return "", syscall.ENAMETOOLONG
-		}
-		fd, err := Open(parent)
-		if err != nil {
-			return "", err
-		}
-
-		for {
-			names, err := fd.Readdirnames(100)
-			if err != nil {
-				fd.Close()
-				return "", err
-			}
-			for _, name := range names {
-				d, _ := Lstat(parent + "/" + name)
-				if SameFile(d, dot) {
-					dir = "/" + name + dir
-					goto Found
-				}
-			}
-		}
-
-	Found:
-		pd, err := fd.Stat()
-		if err != nil {
-			return "", err
-		}
-		fd.Close()
-		if SameFile(pd, root) {
-			break
-		}
-		// Set up for next round.
-		dot = pd
-	}
-
-	// Save answer as hint to avoid the expensive path next time.
-	getwdCache.Lock()
-	getwdCache.dir = dir
-	getwdCache.Unlock()
-
-	return dir, nil
-}
diff --git a/src/pkg/os/os_test.go b/src/pkg/os/os_test.go
deleted file mode 100644
index 16d5984..0000000
--- a/src/pkg/os/os_test.go
+++ /dev/null
@@ -1,1339 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package os_test
-
-import (
-	"bytes"
-	"errors"
-	"flag"
-	"fmt"
-	"io"
-	"io/ioutil"
-	. "os"
-	osexec "os/exec"
-	"path/filepath"
-	"reflect"
-	"runtime"
-	"sort"
-	"strings"
-	"syscall"
-	"testing"
-	"text/template"
-	"time"
-)
-
-var dot = []string{
-	"dir_unix.go",
-	"env.go",
-	"error.go",
-	"file.go",
-	"os_test.go",
-	"types.go",
-	"stat_darwin.go",
-	"stat_linux.go",
-}
-
-type sysDir struct {
-	name  string
-	files []string
-}
-
-var sysdir = func() (sd *sysDir) {
-	switch runtime.GOOS {
-	case "windows":
-		sd = &sysDir{
-			Getenv("SystemRoot") + "\\system32\\drivers\\etc",
-			[]string{
-				"networks",
-				"protocol",
-				"services",
-			},
-		}
-	case "plan9":
-		sd = &sysDir{
-			"/lib/ndb",
-			[]string{
-				"common",
-				"local",
-			},
-		}
-	default:
-		sd = &sysDir{
-			"/etc",
-			[]string{
-				"group",
-				"hosts",
-				"passwd",
-			},
-		}
-	}
-	return
-}()
-
-func size(name string, t *testing.T) int64 {
-	file, err := Open(name)
-	if err != nil {
-		t.Fatal("open failed:", err)
-	}
-	defer file.Close()
-	var buf [100]byte
-	len := 0
-	for {
-		n, e := file.Read(buf[0:])
-		len += n
-		if e == io.EOF {
-			break
-		}
-		if e != nil {
-			t.Fatal("read failed:", err)
-		}
-	}
-	return int64(len)
-}
-
-func equal(name1, name2 string) (r bool) {
-	switch runtime.GOOS {
-	case "windows":
-		r = strings.ToLower(name1) == strings.ToLower(name2)
-	default:
-		r = name1 == name2
-	}
-	return
-}
-
-func newFile(testName string, t *testing.T) (f *File) {
-	// Use a local file system, not NFS.
-	// On Unix, override $TMPDIR in case the user
-	// has it set to an NFS-mounted directory.
-	dir := ""
-	if runtime.GOOS != "windows" {
-		dir = "/tmp"
-	}
-	f, err := ioutil.TempFile(dir, "_Go_"+testName)
-	if err != nil {
-		t.Fatalf("open %s: %s", testName, err)
-	}
-	return
-}
-
-var sfdir = sysdir.name
-var sfname = sysdir.files[0]
-
-func TestStat(t *testing.T) {
-	path := sfdir + "/" + sfname
-	dir, err := Stat(path)
-	if err != nil {
-		t.Fatal("stat failed:", err)
-	}
-	if !equal(sfname, dir.Name()) {
-		t.Error("name should be ", sfname, "; is", dir.Name())
-	}
-	filesize := size(path, t)
-	if dir.Size() != filesize {
-		t.Error("size should be", filesize, "; is", dir.Size())
-	}
-}
-
-func TestFstat(t *testing.T) {
-	path := sfdir + "/" + sfname
-	file, err1 := Open(path)
-	if err1 != nil {
-		t.Fatal("open failed:", err1)
-	}
-	defer file.Close()
-	dir, err2 := file.Stat()
-	if err2 != nil {
-		t.Fatal("fstat failed:", err2)
-	}
-	if !equal(sfname, dir.Name()) {
-		t.Error("name should be ", sfname, "; is", dir.Name())
-	}
-	filesize := size(path, t)
-	if dir.Size() != filesize {
-		t.Error("size should be", filesize, "; is", dir.Size())
-	}
-}
-
-func TestLstat(t *testing.T) {
-	path := sfdir + "/" + sfname
-	dir, err := Lstat(path)
-	if err != nil {
-		t.Fatal("lstat failed:", err)
-	}
-	if !equal(sfname, dir.Name()) {
-		t.Error("name should be ", sfname, "; is", dir.Name())
-	}
-	filesize := size(path, t)
-	if dir.Size() != filesize {
-		t.Error("size should be", filesize, "; is", dir.Size())
-	}
-}
-
-// Read with length 0 should not return EOF.
-func TestRead0(t *testing.T) {
-	path := sfdir + "/" + sfname
-	f, err := Open(path)
-	if err != nil {
-		t.Fatal("open failed:", err)
-	}
-	defer f.Close()
-
-	b := make([]byte, 0)
-	n, err := f.Read(b)
-	if n != 0 || err != nil {
-		t.Errorf("Read(0) = %d, %v, want 0, nil", n, err)
-	}
-	b = make([]byte, 100)
-	n, err = f.Read(b)
-	if n <= 0 || err != nil {
-		t.Errorf("Read(100) = %d, %v, want >0, nil", n, err)
-	}
-}
-
-func testReaddirnames(dir string, contents []string, t *testing.T) {
-	file, err := Open(dir)
-	if err != nil {
-		t.Fatalf("open %q failed: %v", dir, err)
-	}
-	defer file.Close()
-	s, err2 := file.Readdirnames(-1)
-	if err2 != nil {
-		t.Fatalf("readdirnames %q failed: %v", dir, err2)
-	}
-	for _, m := range contents {
-		found := false
-		for _, n := range s {
-			if n == "." || n == ".." {
-				t.Errorf("got %s in directory", n)
-			}
-			if equal(m, n) {
-				if found {
-					t.Error("present twice:", m)
-				}
-				found = true
-			}
-		}
-		if !found {
-			t.Error("could not find", m)
-		}
-	}
-}
-
-func testReaddir(dir string, contents []string, t *testing.T) {
-	file, err := Open(dir)
-	if err != nil {
-		t.Fatalf("open %q failed: %v", dir, err)
-	}
-	defer file.Close()
-	s, err2 := file.Readdir(-1)
-	if err2 != nil {
-		t.Fatalf("readdir %q failed: %v", dir, err2)
-	}
-	for _, m := range contents {
-		found := false
-		for _, n := range s {
-			if equal(m, n.Name()) {
-				if found {
-					t.Error("present twice:", m)
-				}
-				found = true
-			}
-		}
-		if !found {
-			t.Error("could not find", m)
-		}
-	}
-}
-
-func TestReaddirnames(t *testing.T) {
-	testReaddirnames(".", dot, t)
-	testReaddirnames(sysdir.name, sysdir.files, t)
-}
-
-func TestReaddir(t *testing.T) {
-	testReaddir(".", dot, t)
-	testReaddir(sysdir.name, sysdir.files, t)
-}
-
-// Read the directory one entry at a time.
-func smallReaddirnames(file *File, length int, t *testing.T) []string {
-	names := make([]string, length)
-	count := 0
-	for {
-		d, err := file.Readdirnames(1)
-		if err == io.EOF {
-			break
-		}
-		if err != nil {
-			t.Fatalf("readdirnames %q failed: %v", file.Name(), err)
-		}
-		if len(d) == 0 {
-			t.Fatalf("readdirnames %q returned empty slice and no error", file.Name())
-		}
-		names[count] = d[0]
-		count++
-	}
-	return names[0:count]
-}
-
-// Check that reading a directory one entry at a time gives the same result
-// as reading it all at once.
-func TestReaddirnamesOneAtATime(t *testing.T) {
-	// big directory that doesn't change often.
-	dir := "/usr/bin"
-	switch runtime.GOOS {
-	case "windows":
-		dir = Getenv("SystemRoot") + "\\system32"
-	case "plan9":
-		dir = "/bin"
-	}
-	file, err := Open(dir)
-	if err != nil {
-		t.Fatalf("open %q failed: %v", dir, err)
-	}
-	defer file.Close()
-	all, err1 := file.Readdirnames(-1)
-	if err1 != nil {
-		t.Fatalf("readdirnames %q failed: %v", dir, err1)
-	}
-	file1, err2 := Open(dir)
-	if err2 != nil {
-		t.Fatalf("open %q failed: %v", dir, err2)
-	}
-	defer file1.Close()
-	small := smallReaddirnames(file1, len(all)+100, t) // +100 in case we screw up
-	if len(small) < len(all) {
-		t.Fatalf("len(small) is %d, less than %d", len(small), len(all))
-	}
-	for i, n := range all {
-		if small[i] != n {
-			t.Errorf("small read %q mismatch: %v", small[i], n)
-		}
-	}
-}
-
-func TestReaddirNValues(t *testing.T) {
-	if testing.Short() {
-		t.Skip("test.short; skipping")
-	}
-	dir, err := ioutil.TempDir("", "")
-	if err != nil {
-		t.Fatalf("TempDir: %v", err)
-	}
-	defer RemoveAll(dir)
-	for i := 1; i <= 105; i++ {
-		f, err := Create(filepath.Join(dir, fmt.Sprintf("%d", i)))
-		if err != nil {
-			t.Fatalf("Create: %v", err)
-		}
-		f.Write([]byte(strings.Repeat("X", i)))
-		f.Close()
-	}
-
-	var d *File
-	openDir := func() {
-		var err error
-		d, err = Open(dir)
-		if err != nil {
-			t.Fatalf("Open directory: %v", err)
-		}
-	}
-
-	readDirExpect := func(n, want int, wantErr error) {
-		fi, err := d.Readdir(n)
-		if err != wantErr {
-			t.Fatalf("Readdir of %d got error %v, want %v", n, err, wantErr)
-		}
-		if g, e := len(fi), want; g != e {
-			t.Errorf("Readdir of %d got %d files, want %d", n, g, e)
-		}
-	}
-
-	readDirNamesExpect := func(n, want int, wantErr error) {
-		fi, err := d.Readdirnames(n)
-		if err != wantErr {
-			t.Fatalf("Readdirnames of %d got error %v, want %v", n, err, wantErr)
-		}
-		if g, e := len(fi), want; g != e {
-			t.Errorf("Readdirnames of %d got %d files, want %d", n, g, e)
-		}
-	}
-
-	for _, fn := range []func(int, int, error){readDirExpect, readDirNamesExpect} {
-		// Test the slurp case
-		openDir()
-		fn(0, 105, nil)
-		fn(0, 0, nil)
-		d.Close()
-
-		// Slurp with -1 instead
-		openDir()
-		fn(-1, 105, nil)
-		fn(-2, 0, nil)
-		fn(0, 0, nil)
-		d.Close()
-
-		// Test the bounded case
-		openDir()
-		fn(1, 1, nil)
-		fn(2, 2, nil)
-		fn(105, 102, nil) // and tests buffer >100 case
-		fn(3, 0, io.EOF)
-		d.Close()
-	}
-}
-
-func touch(t *testing.T, name string) {
-	f, err := Create(name)
-	if err != nil {
-		t.Fatal(err)
-	}
-	if err := f.Close(); err != nil {
-		t.Fatal(err)
-	}
-}
-
-func TestReaddirStatFailures(t *testing.T) {
-	switch runtime.GOOS {
-	case "windows", "plan9":
-		// Windows and Plan 9 already do this correctly,
-		// but are structured with different syscalls such
-		// that they don't use Lstat, so the hook below for
-		// testing it wouldn't work.
-		t.Skipf("skipping test on %v", runtime.GOOS)
-	}
-	dir, err := ioutil.TempDir("", "")
-	if err != nil {
-		t.Fatalf("TempDir: %v", err)
-	}
-	defer RemoveAll(dir)
-	touch(t, filepath.Join(dir, "good1"))
-	touch(t, filepath.Join(dir, "x")) // will disappear or have an error
-	touch(t, filepath.Join(dir, "good2"))
-	defer func() {
-		*LstatP = Lstat
-	}()
-	var xerr error // error to return for x
-	*LstatP = func(path string) (FileInfo, error) {
-		if xerr != nil && strings.HasSuffix(path, "x") {
-			return nil, xerr
-		}
-		return Lstat(path)
-	}
-	readDir := func() ([]FileInfo, error) {
-		d, err := Open(dir)
-		if err != nil {
-			t.Fatal(err)
-		}
-		defer d.Close()
-		return d.Readdir(-1)
-	}
-	mustReadDir := func(testName string) []FileInfo {
-		fis, err := readDir()
-		if err != nil {
-			t.Fatalf("%s: Readdir: %v", testName, err)
-		}
-		return fis
-	}
-	names := func(fis []FileInfo) []string {
-		s := make([]string, len(fis))
-		for i, fi := range fis {
-			s[i] = fi.Name()
-		}
-		sort.Strings(s)
-		return s
-	}
-
-	if got, want := names(mustReadDir("inital readdir")),
-		[]string{"good1", "good2", "x"}; !reflect.DeepEqual(got, want) {
-		t.Errorf("initial readdir got %q; want %q", got, want)
-	}
-
-	xerr = ErrNotExist
-	if got, want := names(mustReadDir("with x disappearing")),
-		[]string{"good1", "good2"}; !reflect.DeepEqual(got, want) {
-		t.Errorf("with x disappearing, got %q; want %q", got, want)
-	}
-
-	xerr = errors.New("some real error")
-	if _, err := readDir(); err != xerr {
-		t.Errorf("with a non-ErrNotExist error, got error %v; want %v", err, xerr)
-	}
-}
-
-func TestHardLink(t *testing.T) {
-	// Hardlinks are not supported under windows or Plan 9.
-	if runtime.GOOS == "windows" || runtime.GOOS == "plan9" {
-		return
-	}
-	from, to := "hardlinktestfrom", "hardlinktestto"
-	Remove(from) // Just in case.
-	file, err := Create(to)
-	if err != nil {
-		t.Fatalf("open %q failed: %v", to, err)
-	}
-	defer Remove(to)
-	if err = file.Close(); err != nil {
-		t.Errorf("close %q failed: %v", to, err)
-	}
-	err = Link(to, from)
-	if err != nil {
-		t.Fatalf("link %q, %q failed: %v", to, from, err)
-	}
-	defer Remove(from)
-	tostat, err := Stat(to)
-	if err != nil {
-		t.Fatalf("stat %q failed: %v", to, err)
-	}
-	fromstat, err := Stat(from)
-	if err != nil {
-		t.Fatalf("stat %q failed: %v", from, err)
-	}
-	if !SameFile(tostat, fromstat) {
-		t.Errorf("link %q, %q did not create hard link", to, from)
-	}
-}
-
-func TestSymlink(t *testing.T) {
-	switch runtime.GOOS {
-	case "windows", "plan9", "nacl":
-		t.Skipf("skipping on %s", runtime.GOOS)
-	}
-	from, to := "symlinktestfrom", "symlinktestto"
-	Remove(from) // Just in case.
-	file, err := Create(to)
-	if err != nil {
-		t.Fatalf("open %q failed: %v", to, err)
-	}
-	defer Remove(to)
-	if err = file.Close(); err != nil {
-		t.Errorf("close %q failed: %v", to, err)
-	}
-	err = Symlink(to, from)
-	if err != nil {
-		t.Fatalf("symlink %q, %q failed: %v", to, from, err)
-	}
-	defer Remove(from)
-	tostat, err := Lstat(to)
-	if err != nil {
-		t.Fatalf("stat %q failed: %v", to, err)
-	}
-	if tostat.Mode()&ModeSymlink != 0 {
-		t.Fatalf("stat %q claims to have found a symlink", to)
-	}
-	fromstat, err := Stat(from)
-	if err != nil {
-		t.Fatalf("stat %q failed: %v", from, err)
-	}
-	if !SameFile(tostat, fromstat) {
-		t.Errorf("symlink %q, %q did not create symlink", to, from)
-	}
-	fromstat, err = Lstat(from)
-	if err != nil {
-		t.Fatalf("lstat %q failed: %v", from, err)
-	}
-	if fromstat.Mode()&ModeSymlink == 0 {
-		t.Fatalf("symlink %q, %q did not create symlink", to, from)
-	}
-	fromstat, err = Stat(from)
-	if err != nil {
-		t.Fatalf("stat %q failed: %v", from, err)
-	}
-	if fromstat.Mode()&ModeSymlink != 0 {
-		t.Fatalf("stat %q did not follow symlink", from)
-	}
-	s, err := Readlink(from)
-	if err != nil {
-		t.Fatalf("readlink %q failed: %v", from, err)
-	}
-	if s != to {
-		t.Fatalf("after symlink %q != %q", s, to)
-	}
-	file, err = Open(from)
-	if err != nil {
-		t.Fatalf("open %q failed: %v", from, err)
-	}
-	file.Close()
-}
-
-func TestLongSymlink(t *testing.T) {
-	switch runtime.GOOS {
-	case "windows", "plan9", "nacl":
-		t.Skipf("skipping on %s", runtime.GOOS)
-	}
-	s := "0123456789abcdef"
-	// Long, but not too long: a common limit is 255.
-	s = s + s + s + s + s + s + s + s + s + s + s + s + s + s + s
-	from := "longsymlinktestfrom"
-	Remove(from) // Just in case.
-	err := Symlink(s, from)
-	if err != nil {
-		t.Fatalf("symlink %q, %q failed: %v", s, from, err)
-	}
-	defer Remove(from)
-	r, err := Readlink(from)
-	if err != nil {
-		t.Fatalf("readlink %q failed: %v", from, err)
-	}
-	if r != s {
-		t.Fatalf("after symlink %q != %q", r, s)
-	}
-}
-
-func TestRename(t *testing.T) {
-	from, to := "renamefrom", "renameto"
-	Remove(to) // Just in case.
-	file, err := Create(from)
-	if err != nil {
-		t.Fatalf("open %q failed: %v", to, err)
-	}
-	if err = file.Close(); err != nil {
-		t.Errorf("close %q failed: %v", to, err)
-	}
-	err = Rename(from, to)
-	if err != nil {
-		t.Fatalf("rename %q, %q failed: %v", to, from, err)
-	}
-	defer Remove(to)
-	_, err = Stat(to)
-	if err != nil {
-		t.Errorf("stat %q failed: %v", to, err)
-	}
-}
-
-func exec(t *testing.T, dir, cmd string, args []string, expect string) {
-	r, w, err := Pipe()
-	if err != nil {
-		t.Fatalf("Pipe: %v", err)
-	}
-	defer r.Close()
-	attr := &ProcAttr{Dir: dir, Files: []*File{nil, w, Stderr}}
-	p, err := StartProcess(cmd, args, attr)
-	if err != nil {
-		t.Fatalf("StartProcess: %v", err)
-	}
-	w.Close()
-
-	var b bytes.Buffer
-	io.Copy(&b, r)
-	output := b.String()
-
-	fi1, _ := Stat(strings.TrimSpace(output))
-	fi2, _ := Stat(expect)
-	if !SameFile(fi1, fi2) {
-		t.Errorf("exec %q returned %q wanted %q",
-			strings.Join(append([]string{cmd}, args...), " "), output, expect)
-	}
-	p.Wait()
-}
-
-func TestStartProcess(t *testing.T) {
-	if runtime.GOOS == "nacl" {
-		t.Skip("skipping on nacl")
-	}
-
-	var dir, cmd string
-	var args []string
-	if runtime.GOOS == "windows" {
-		cmd = Getenv("COMSPEC")
-		dir = Getenv("SystemRoot")
-		args = []string{"/c", "cd"}
-	} else {
-		cmd = "/bin/pwd"
-		dir = "/"
-		args = []string{}
-	}
-	cmddir, cmdbase := filepath.Split(cmd)
-	args = append([]string{cmdbase}, args...)
-	// Test absolute executable path.
-	exec(t, dir, cmd, args, dir)
-	// Test relative executable path.
-	exec(t, cmddir, cmdbase, args, cmddir)
-}
-
-func checkMode(t *testing.T, path string, mode FileMode) {
-	dir, err := Stat(path)
-	if err != nil {
-		t.Fatalf("Stat %q (looking for mode %#o): %s", path, mode, err)
-	}
-	if dir.Mode()&0777 != mode {
-		t.Errorf("Stat %q: mode %#o want %#o", path, dir.Mode(), mode)
-	}
-}
-
-func TestChmod(t *testing.T) {
-	// Chmod is not supported under windows.
-	if runtime.GOOS == "windows" {
-		return
-	}
-	f := newFile("TestChmod", t)
-	defer Remove(f.Name())
-	defer f.Close()
-
-	if err := Chmod(f.Name(), 0456); err != nil {
-		t.Fatalf("chmod %s 0456: %s", f.Name(), err)
-	}
-	checkMode(t, f.Name(), 0456)
-
-	if err := f.Chmod(0123); err != nil {
-		t.Fatalf("chmod %s 0123: %s", f.Name(), err)
-	}
-	checkMode(t, f.Name(), 0123)
-}
-
-func checkSize(t *testing.T, f *File, size int64) {
-	dir, err := f.Stat()
-	if err != nil {
-		t.Fatalf("Stat %q (looking for size %d): %s", f.Name(), size, err)
-	}
-	if dir.Size() != size {
-		t.Errorf("Stat %q: size %d want %d", f.Name(), dir.Size(), size)
-	}
-}
-
-func TestFTruncate(t *testing.T) {
-	f := newFile("TestFTruncate", t)
-	defer Remove(f.Name())
-	defer f.Close()
-
-	checkSize(t, f, 0)
-	f.Write([]byte("hello, world\n"))
-	checkSize(t, f, 13)
-	f.Truncate(10)
-	checkSize(t, f, 10)
-	f.Truncate(1024)
-	checkSize(t, f, 1024)
-	f.Truncate(0)
-	checkSize(t, f, 0)
-	_, err := f.Write([]byte("surprise!"))
-	if err == nil {
-		checkSize(t, f, 13+9) // wrote at offset past where hello, world was.
-	}
-}
-
-func TestTruncate(t *testing.T) {
-	f := newFile("TestTruncate", t)
-	defer Remove(f.Name())
-	defer f.Close()
-
-	checkSize(t, f, 0)
-	f.Write([]byte("hello, world\n"))
-	checkSize(t, f, 13)
-	Truncate(f.Name(), 10)
-	checkSize(t, f, 10)
-	Truncate(f.Name(), 1024)
-	checkSize(t, f, 1024)
-	Truncate(f.Name(), 0)
-	checkSize(t, f, 0)
-	_, err := f.Write([]byte("surprise!"))
-	if err == nil {
-		checkSize(t, f, 13+9) // wrote at offset past where hello, world was.
-	}
-}
-
-// Use TempDir() to make sure we're on a local file system,
-// so that timings are not distorted by latency and caching.
-// On NFS, timings can be off due to caching of meta-data on
-// NFS servers (Issue 848).
-func TestChtimes(t *testing.T) {
-	f := newFile("TestChtimes", t)
-	defer Remove(f.Name())
-	defer f.Close()
-
-	f.Write([]byte("hello, world\n"))
-	f.Close()
-
-	st, err := Stat(f.Name())
-	if err != nil {
-		t.Fatalf("Stat %s: %s", f.Name(), err)
-	}
-	preStat := st
-
-	// Move access and modification time back a second
-	at := Atime(preStat)
-	mt := preStat.ModTime()
-	err = Chtimes(f.Name(), at.Add(-time.Second), mt.Add(-time.Second))
-	if err != nil {
-		t.Fatalf("Chtimes %s: %s", f.Name(), err)
-	}
-
-	st, err = Stat(f.Name())
-	if err != nil {
-		t.Fatalf("second Stat %s: %s", f.Name(), err)
-	}
-	postStat := st
-
-	/* Plan 9, NaCl:
-		Mtime is the time of the last change of content.  Similarly, atime is set whenever the
-	    contents are accessed; also, it is set whenever mtime is set.
-	*/
-	pat := Atime(postStat)
-	pmt := postStat.ModTime()
-	if !pat.Before(at) && runtime.GOOS != "plan9" && runtime.GOOS != "nacl" {
-		t.Errorf("AccessTime didn't go backwards; was=%d, after=%d", at, pat)
-	}
-
-	if !pmt.Before(mt) {
-		t.Errorf("ModTime didn't go backwards; was=%d, after=%d", mt, pmt)
-	}
-}
-
-func TestChdirAndGetwd(t *testing.T) {
-	// TODO(brainman): file.Chdir() is not implemented on windows.
-	if runtime.GOOS == "windows" {
-		return
-	}
-	fd, err := Open(".")
-	if err != nil {
-		t.Fatalf("Open .: %s", err)
-	}
-	// These are chosen carefully not to be symlinks on a Mac
-	// (unlike, say, /var, /etc, and /tmp).
-	dirs := []string{"/", "/usr/bin"}
-	// /usr/bin does not usually exist on Plan 9.
-	if runtime.GOOS == "plan9" {
-		dirs = []string{"/", "/usr"}
-	}
-	for mode := 0; mode < 2; mode++ {
-		for _, d := range dirs {
-			if mode == 0 {
-				err = Chdir(d)
-			} else {
-				fd1, err := Open(d)
-				if err != nil {
-					t.Errorf("Open %s: %s", d, err)
-					continue
-				}
-				err = fd1.Chdir()
-				fd1.Close()
-			}
-			pwd, err1 := Getwd()
-			err2 := fd.Chdir()
-			if err2 != nil {
-				// We changed the current directory and cannot go back.
-				// Don't let the tests continue; they'll scribble
-				// all over some other directory.
-				fmt.Fprintf(Stderr, "fchdir back to dot failed: %s\n", err2)
-				Exit(1)
-			}
-			if err != nil {
-				fd.Close()
-				t.Fatalf("Chdir %s: %s", d, err)
-			}
-			if err1 != nil {
-				fd.Close()
-				t.Fatalf("Getwd in %s: %s", d, err1)
-			}
-			if pwd != d {
-				fd.Close()
-				t.Fatalf("Getwd returned %q want %q", pwd, d)
-			}
-		}
-	}
-	fd.Close()
-}
-
-func TestSeek(t *testing.T) {
-	f := newFile("TestSeek", t)
-	defer Remove(f.Name())
-	defer f.Close()
-
-	const data = "hello, world\n"
-	io.WriteString(f, data)
-
-	type test struct {
-		in     int64
-		whence int
-		out    int64
-	}
-	var tests = []test{
-		{0, 1, int64(len(data))},
-		{0, 0, 0},
-		{5, 0, 5},
-		{0, 2, int64(len(data))},
-		{0, 0, 0},
-		{-1, 2, int64(len(data)) - 1},
-		{1 << 33, 0, 1 << 33},
-		{1 << 33, 2, 1<<33 + int64(len(data))},
-	}
-	for i, tt := range tests {
-		off, err := f.Seek(tt.in, tt.whence)
-		if off != tt.out || err != nil {
-			if e, ok := err.(*PathError); ok && e.Err == syscall.EINVAL && tt.out > 1<<32 {
-				// Reiserfs rejects the big seeks.
-				// http://code.google.com/p/go/issues/detail?id=91
-				break
-			}
-			t.Errorf("#%d: Seek(%v, %v) = %v, %v want %v, nil", i, tt.in, tt.whence, off, err, tt.out)
-		}
-	}
-}
-
-type openErrorTest struct {
-	path  string
-	mode  int
-	error error
-}
-
-var openErrorTests = []openErrorTest{
-	{
-		sfdir + "/no-such-file",
-		O_RDONLY,
-		syscall.ENOENT,
-	},
-	{
-		sfdir,
-		O_WRONLY,
-		syscall.EISDIR,
-	},
-	{
-		sfdir + "/" + sfname + "/no-such-file",
-		O_WRONLY,
-		syscall.ENOTDIR,
-	},
-}
-
-func TestOpenError(t *testing.T) {
-	for _, tt := range openErrorTests {
-		f, err := OpenFile(tt.path, tt.mode, 0)
-		if err == nil {
-			t.Errorf("Open(%q, %d) succeeded", tt.path, tt.mode)
-			f.Close()
-			continue
-		}
-		perr, ok := err.(*PathError)
-		if !ok {
-			t.Errorf("Open(%q, %d) returns error of %T type; want *PathError", tt.path, tt.mode, err)
-		}
-		if perr.Err != tt.error {
-			if runtime.GOOS == "plan9" {
-				syscallErrStr := perr.Err.Error()
-				expectedErrStr := strings.Replace(tt.error.Error(), "file ", "", 1)
-				if !strings.HasSuffix(syscallErrStr, expectedErrStr) {
-					t.Errorf("Open(%q, %d) = _, %q; want suffix %q", tt.path, tt.mode, syscallErrStr, expectedErrStr)
-				}
-				continue
-			}
-			if runtime.GOOS == "dragonfly" {
-				// DragonFly incorrectly returns EACCES rather
-				// EISDIR when a directory is opened for write.
-				if tt.error == syscall.EISDIR && perr.Err == syscall.EACCES {
-					continue
-				}
-			}
-			t.Errorf("Open(%q, %d) = _, %q; want %q", tt.path, tt.mode, perr.Err.Error(), tt.error.Error())
-		}
-	}
-}
-
-func TestOpenNoName(t *testing.T) {
-	f, err := Open("")
-	if err == nil {
-		t.Fatal(`Open("") succeeded`)
-		f.Close()
-	}
-}
-
-func run(t *testing.T, cmd []string) string {
-	// Run /bin/hostname and collect output.
-	r, w, err := Pipe()
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer r.Close()
-	p, err := StartProcess("/bin/hostname", []string{"hostname"}, &ProcAttr{Files: []*File{nil, w, Stderr}})
-	if err != nil {
-		t.Fatal(err)
-	}
-	w.Close()
-
-	var b bytes.Buffer
-	io.Copy(&b, r)
-	_, err = p.Wait()
-	if err != nil {
-		t.Fatalf("run hostname Wait: %v", err)
-	}
-	err = p.Kill()
-	if err == nil {
-		t.Errorf("expected an error from Kill running 'hostname'")
-	}
-	output := b.String()
-	if n := len(output); n > 0 && output[n-1] == '\n' {
-		output = output[0 : n-1]
-	}
-	if output == "" {
-		t.Fatalf("%v produced no output", cmd)
-	}
-
-	return output
-}
-
-func TestHostname(t *testing.T) {
-	// There is no other way to fetch hostname on windows, but via winapi.
-	// On Plan 9 it is can be taken from #c/sysname as Hostname() does.
-	switch runtime.GOOS {
-	case "windows", "plan9", "nacl":
-		t.Skipf("skipping on %s", runtime.GOOS)
-	}
-
-	// Check internal Hostname() against the output of /bin/hostname.
-	// Allow that the internal Hostname returns a Fully Qualified Domain Name
-	// and the /bin/hostname only returns the first component
-	hostname, err := Hostname()
-	if err != nil {
-		t.Fatalf("%v", err)
-	}
-	want := run(t, []string{"/bin/hostname"})
-	if hostname != want {
-		i := strings.Index(hostname, ".")
-		if i < 0 || hostname[0:i] != want {
-			t.Errorf("Hostname() = %q, want %q", hostname, want)
-		}
-	}
-}
-
-func TestReadAt(t *testing.T) {
-	f := newFile("TestReadAt", t)
-	defer Remove(f.Name())
-	defer f.Close()
-
-	const data = "hello, world\n"
-	io.WriteString(f, data)
-
-	b := make([]byte, 5)
-	n, err := f.ReadAt(b, 7)
-	if err != nil || n != len(b) {
-		t.Fatalf("ReadAt 7: %d, %v", n, err)
-	}
-	if string(b) != "world" {
-		t.Fatalf("ReadAt 7: have %q want %q", string(b), "world")
-	}
-}
-
-func TestWriteAt(t *testing.T) {
-	f := newFile("TestWriteAt", t)
-	defer Remove(f.Name())
-	defer f.Close()
-
-	const data = "hello, world\n"
-	io.WriteString(f, data)
-
-	n, err := f.WriteAt([]byte("WORLD"), 7)
-	if err != nil || n != 5 {
-		t.Fatalf("WriteAt 7: %d, %v", n, err)
-	}
-
-	b, err := ioutil.ReadFile(f.Name())
-	if err != nil {
-		t.Fatalf("ReadFile %s: %v", f.Name(), err)
-	}
-	if string(b) != "hello, WORLD\n" {
-		t.Fatalf("after write: have %q want %q", string(b), "hello, WORLD\n")
-	}
-}
-
-func writeFile(t *testing.T, fname string, flag int, text string) string {
-	f, err := OpenFile(fname, flag, 0666)
-	if err != nil {
-		t.Fatalf("Open: %v", err)
-	}
-	n, err := io.WriteString(f, text)
-	if err != nil {
-		t.Fatalf("WriteString: %d, %v", n, err)
-	}
-	f.Close()
-	data, err := ioutil.ReadFile(fname)
-	if err != nil {
-		t.Fatalf("ReadFile: %v", err)
-	}
-	return string(data)
-}
-
-func TestAppend(t *testing.T) {
-	const f = "append.txt"
-	defer Remove(f)
-	s := writeFile(t, f, O_CREATE|O_TRUNC|O_RDWR, "new")
-	if s != "new" {
-		t.Fatalf("writeFile: have %q want %q", s, "new")
-	}
-	s = writeFile(t, f, O_APPEND|O_RDWR, "|append")
-	if s != "new|append" {
-		t.Fatalf("writeFile: have %q want %q", s, "new|append")
-	}
-	s = writeFile(t, f, O_CREATE|O_APPEND|O_RDWR, "|append")
-	if s != "new|append|append" {
-		t.Fatalf("writeFile: have %q want %q", s, "new|append|append")
-	}
-	err := Remove(f)
-	if err != nil {
-		t.Fatalf("Remove: %v", err)
-	}
-	s = writeFile(t, f, O_CREATE|O_APPEND|O_RDWR, "new&append")
-	if s != "new&append" {
-		t.Fatalf("writeFile: after append have %q want %q", s, "new&append")
-	}
-	s = writeFile(t, f, O_CREATE|O_RDWR, "old")
-	if s != "old&append" {
-		t.Fatalf("writeFile: after create have %q want %q", s, "old&append")
-	}
-	s = writeFile(t, f, O_CREATE|O_TRUNC|O_RDWR, "new")
-	if s != "new" {
-		t.Fatalf("writeFile: after truncate have %q want %q", s, "new")
-	}
-}
-
-func TestStatDirWithTrailingSlash(t *testing.T) {
-	// Create new temporary directory and arrange to clean it up.
-	path, err := ioutil.TempDir("", "/_TestStatDirWithSlash_")
-	if err != nil {
-		t.Fatalf("TempDir: %s", err)
-	}
-	defer RemoveAll(path)
-
-	// Stat of path should succeed.
-	_, err = Stat(path)
-	if err != nil {
-		t.Fatalf("stat %s failed: %s", path, err)
-	}
-
-	// Stat of path+"/" should succeed too.
-	path += "/"
-	_, err = Stat(path)
-	if err != nil {
-		t.Fatalf("stat %s failed: %s", path, err)
-	}
-}
-
-func TestNilProcessStateString(t *testing.T) {
-	var ps *ProcessState
-	s := ps.String()
-	if s != "<nil>" {
-		t.Errorf("(*ProcessState)(nil).String() = %q, want %q", s, "<nil>")
-	}
-}
-
-func TestSameFile(t *testing.T) {
-	fa, err := Create("a")
-	if err != nil {
-		t.Fatalf("Create(a): %v", err)
-	}
-	defer Remove(fa.Name())
-	fa.Close()
-	fb, err := Create("b")
-	if err != nil {
-		t.Fatalf("Create(b): %v", err)
-	}
-	defer Remove(fb.Name())
-	fb.Close()
-
-	ia1, err := Stat("a")
-	if err != nil {
-		t.Fatalf("Stat(a): %v", err)
-	}
-	ia2, err := Stat("a")
-	if err != nil {
-		t.Fatalf("Stat(a): %v", err)
-	}
-	if !SameFile(ia1, ia2) {
-		t.Errorf("files should be same")
-	}
-
-	ib, err := Stat("b")
-	if err != nil {
-		t.Fatalf("Stat(b): %v", err)
-	}
-	if SameFile(ia1, ib) {
-		t.Errorf("files should be different")
-	}
-}
-
-func TestDevNullFile(t *testing.T) {
-	f, err := Open(DevNull)
-	if err != nil {
-		t.Fatalf("Open(%s): %v", DevNull, err)
-	}
-	defer f.Close()
-	fi, err := f.Stat()
-	if err != nil {
-		t.Fatalf("Stat(%s): %v", DevNull, err)
-	}
-	name := filepath.Base(DevNull)
-	if fi.Name() != name {
-		t.Fatalf("wrong file name have %v want %v", fi.Name(), name)
-	}
-	if fi.Size() != 0 {
-		t.Fatalf("wrong file size have %d want 0", fi.Size())
-	}
-}
-
-var testLargeWrite = flag.Bool("large_write", false, "run TestLargeWriteToConsole test that floods console with output")
-
-func TestLargeWriteToConsole(t *testing.T) {
-	if !*testLargeWrite {
-		t.Skip("skipping console-flooding test; enable with -large_write")
-	}
-	b := make([]byte, 32000)
-	for i := range b {
-		b[i] = '.'
-	}
-	b[len(b)-1] = '\n'
-	n, err := Stdout.Write(b)
-	if err != nil {
-		t.Fatalf("Write to os.Stdout failed: %v", err)
-	}
-	if n != len(b) {
-		t.Errorf("Write to os.Stdout should return %d; got %d", len(b), n)
-	}
-	n, err = Stderr.Write(b)
-	if err != nil {
-		t.Fatalf("Write to os.Stderr failed: %v", err)
-	}
-	if n != len(b) {
-		t.Errorf("Write to os.Stderr should return %d; got %d", len(b), n)
-	}
-}
-
-func TestStatDirModeExec(t *testing.T) {
-	const mode = 0111
-
-	path, err := ioutil.TempDir("", "go-build")
-	if err != nil {
-		t.Fatalf("Failed to create temp directory: %v", err)
-	}
-	defer RemoveAll(path)
-
-	if err := Chmod(path, 0777); err != nil {
-		t.Fatalf("Chmod %q 0777: %v", path, err)
-	}
-
-	dir, err := Stat(path)
-	if err != nil {
-		t.Fatalf("Stat %q (looking for mode %#o): %s", path, mode, err)
-	}
-	if dir.Mode()&mode != mode {
-		t.Errorf("Stat %q: mode %#o want %#o", path, dir.Mode()&mode, mode)
-	}
-}
-
-func TestReadAtEOF(t *testing.T) {
-	f := newFile("TestReadAtEOF", t)
-	defer Remove(f.Name())
-	defer f.Close()
-
-	_, err := f.ReadAt(make([]byte, 10), 0)
-	switch err {
-	case io.EOF:
-		// all good
-	case nil:
-		t.Fatalf("ReadAt succeeded")
-	default:
-		t.Fatalf("ReadAt failed: %s", err)
-	}
-}
-
-func testKillProcess(t *testing.T, processKiller func(p *Process)) {
-	if runtime.GOOS == "nacl" {
-		t.Skip("skipping on nacl")
-	}
-
-	dir, err := ioutil.TempDir("", "go-build")
-	if err != nil {
-		t.Fatalf("Failed to create temp directory: %v", err)
-	}
-	defer RemoveAll(dir)
-
-	src := filepath.Join(dir, "main.go")
-	f, err := Create(src)
-	if err != nil {
-		t.Fatalf("Failed to create %v: %v", src, err)
-	}
-	st := template.Must(template.New("source").Parse(`
-package main
-import "time"
-func main() {
-	time.Sleep(time.Second)
-}
-`))
-	err = st.Execute(f, nil)
-	if err != nil {
-		f.Close()
-		t.Fatalf("Failed to execute template: %v", err)
-	}
-	f.Close()
-
-	exe := filepath.Join(dir, "main.exe")
-	output, err := osexec.Command("go", "build", "-o", exe, src).CombinedOutput()
-	if err != nil {
-		t.Fatalf("Failed to build exe %v: %v %v", exe, err, string(output))
-	}
-
-	cmd := osexec.Command(exe)
-	err = cmd.Start()
-	if err != nil {
-		t.Fatalf("Failed to start test process: %v", err)
-	}
-	go func() {
-		time.Sleep(100 * time.Millisecond)
-		processKiller(cmd.Process)
-	}()
-	err = cmd.Wait()
-	if err == nil {
-		t.Errorf("Test process succeeded, but expected to fail")
-	}
-}
-
-func TestKillStartProcess(t *testing.T) {
-	testKillProcess(t, func(p *Process) {
-		err := p.Kill()
-		if err != nil {
-			t.Fatalf("Failed to kill test process: %v", err)
-		}
-	})
-}
-
-func TestKillFindProcess(t *testing.T) {
-	testKillProcess(t, func(p *Process) {
-		p2, err := FindProcess(p.Pid)
-		if err != nil {
-			t.Fatalf("Failed to find test process: %v", err)
-		}
-		err = p2.Kill()
-		if err != nil {
-			t.Fatalf("Failed to kill test process: %v", err)
-		}
-	})
-}
-
-var nilFileMethodTests = []struct {
-	name string
-	f    func(*File) error
-}{
-	{"Chdir", func(f *File) error { return f.Chdir() }},
-	{"Close", func(f *File) error { return f.Close() }},
-	{"Chmod", func(f *File) error { return f.Chmod(0) }},
-	{"Chown", func(f *File) error { return f.Chown(0, 0) }},
-	{"Read", func(f *File) error { _, err := f.Read(make([]byte, 0)); return err }},
-	{"ReadAt", func(f *File) error { _, err := f.ReadAt(make([]byte, 0), 0); return err }},
-	{"Readdir", func(f *File) error { _, err := f.Readdir(1); return err }},
-	{"Readdirnames", func(f *File) error { _, err := f.Readdirnames(1); return err }},
-	{"Seek", func(f *File) error { _, err := f.Seek(0, 0); return err }},
-	{"Stat", func(f *File) error { _, err := f.Stat(); return err }},
-	{"Sync", func(f *File) error { return f.Sync() }},
-	{"Truncate", func(f *File) error { return f.Truncate(0) }},
-	{"Write", func(f *File) error { _, err := f.Write(make([]byte, 0)); return err }},
-	{"WriteAt", func(f *File) error { _, err := f.WriteAt(make([]byte, 0), 0); return err }},
-	{"WriteString", func(f *File) error { _, err := f.WriteString(""); return err }},
-}
-
-// Test that all File methods give ErrInvalid if the receiver is nil.
-func TestNilFileMethods(t *testing.T) {
-	for _, tt := range nilFileMethodTests {
-		var file *File
-		got := tt.f(file)
-		if got != ErrInvalid {
-			t.Errorf("%v should fail when f is nil; got %v", tt.name, got)
-		}
-	}
-}
diff --git a/src/pkg/os/path.go b/src/pkg/os/path.go
deleted file mode 100644
index 02a77ec..0000000
--- a/src/pkg/os/path.go
+++ /dev/null
@@ -1,123 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package os
-
-import (
-	"io"
-	"syscall"
-)
-
-// MkdirAll creates a directory named path,
-// along with any necessary parents, and returns nil,
-// or else returns an error.
-// The permission bits perm are used for all
-// directories that MkdirAll creates.
-// If path is already a directory, MkdirAll does nothing
-// and returns nil.
-func MkdirAll(path string, perm FileMode) error {
-	// If path exists, stop with success or error.
-	dir, err := Stat(path)
-	if err == nil {
-		if dir.IsDir() {
-			return nil
-		}
-		return &PathError{"mkdir", path, syscall.ENOTDIR}
-	}
-
-	// Doesn't already exist; make sure parent does.
-	i := len(path)
-	for i > 0 && IsPathSeparator(path[i-1]) { // Skip trailing path separator.
-		i--
-	}
-
-	j := i
-	for j > 0 && !IsPathSeparator(path[j-1]) { // Scan backward over element.
-		j--
-	}
-
-	if j > 1 {
-		// Create parent
-		err = MkdirAll(path[0:j-1], perm)
-		if err != nil {
-			return err
-		}
-	}
-
-	// Now parent exists, try to create.
-	err = Mkdir(path, perm)
-	if err != nil {
-		// Handle arguments like "foo/." by
-		// double-checking that directory doesn't exist.
-		dir, err1 := Lstat(path)
-		if err1 == nil && dir.IsDir() {
-			return nil
-		}
-		return err
-	}
-	return nil
-}
-
-// RemoveAll removes path and any children it contains.
-// It removes everything it can but returns the first error
-// it encounters.  If the path does not exist, RemoveAll
-// returns nil (no error).
-func RemoveAll(path string) error {
-	// Simple case: if Remove works, we're done.
-	err := Remove(path)
-	if err == nil {
-		return nil
-	}
-
-	// Otherwise, is this a directory we need to recurse into?
-	dir, serr := Lstat(path)
-	if serr != nil {
-		if serr, ok := serr.(*PathError); ok && (IsNotExist(serr.Err) || serr.Err == syscall.ENOTDIR) {
-			return nil
-		}
-		return serr
-	}
-	if !dir.IsDir() {
-		// Not a directory; return the error from Remove.
-		return err
-	}
-
-	// Directory.
-	fd, err := Open(path)
-	if err != nil {
-		return err
-	}
-
-	// Remove contents & return first error.
-	err = nil
-	for {
-		names, err1 := fd.Readdirnames(100)
-		for _, name := range names {
-			err1 := RemoveAll(path + string(PathSeparator) + name)
-			if err == nil {
-				err = err1
-			}
-		}
-		if err1 == io.EOF {
-			break
-		}
-		// If Readdirnames returned an error, use it.
-		if err == nil {
-			err = err1
-		}
-		if len(names) == 0 {
-			break
-		}
-	}
-
-	// Close directory, because windows won't remove opened directory.
-	fd.Close()
-
-	// Remove directory.
-	err1 := Remove(path)
-	if err == nil {
-		err = err1
-	}
-	return err
-}
diff --git a/src/pkg/os/path_test.go b/src/pkg/os/path_test.go
deleted file mode 100644
index 3af21cd..0000000
--- a/src/pkg/os/path_test.go
+++ /dev/null
@@ -1,215 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package os_test
-
-import (
-	"io/ioutil"
-	. "os"
-	"path/filepath"
-	"runtime"
-	"syscall"
-	"testing"
-)
-
-func TestMkdirAll(t *testing.T) {
-	tmpDir := TempDir()
-	path := tmpDir + "/_TestMkdirAll_/dir/./dir2"
-	err := MkdirAll(path, 0777)
-	if err != nil {
-		t.Fatalf("MkdirAll %q: %s", path, err)
-	}
-	defer RemoveAll(tmpDir + "/_TestMkdirAll_")
-
-	// Already exists, should succeed.
-	err = MkdirAll(path, 0777)
-	if err != nil {
-		t.Fatalf("MkdirAll %q (second time): %s", path, err)
-	}
-
-	// Make file.
-	fpath := path + "/file"
-	f, err := Create(fpath)
-	if err != nil {
-		t.Fatalf("create %q: %s", fpath, err)
-	}
-	defer f.Close()
-
-	// Can't make directory named after file.
-	err = MkdirAll(fpath, 0777)
-	if err == nil {
-		t.Fatalf("MkdirAll %q: no error", fpath)
-	}
-	perr, ok := err.(*PathError)
-	if !ok {
-		t.Fatalf("MkdirAll %q returned %T, not *PathError", fpath, err)
-	}
-	if filepath.Clean(perr.Path) != filepath.Clean(fpath) {
-		t.Fatalf("MkdirAll %q returned wrong error path: %q not %q", fpath, filepath.Clean(perr.Path), filepath.Clean(fpath))
-	}
-
-	// Can't make subdirectory of file.
-	ffpath := fpath + "/subdir"
-	err = MkdirAll(ffpath, 0777)
-	if err == nil {
-		t.Fatalf("MkdirAll %q: no error", ffpath)
-	}
-	perr, ok = err.(*PathError)
-	if !ok {
-		t.Fatalf("MkdirAll %q returned %T, not *PathError", ffpath, err)
-	}
-	if filepath.Clean(perr.Path) != filepath.Clean(fpath) {
-		t.Fatalf("MkdirAll %q returned wrong error path: %q not %q", ffpath, filepath.Clean(perr.Path), filepath.Clean(fpath))
-	}
-
-	if runtime.GOOS == "windows" {
-		path := tmpDir + `\_TestMkdirAll_\dir\.\dir2\`
-		err := MkdirAll(path, 0777)
-		if err != nil {
-			t.Fatalf("MkdirAll %q: %s", path, err)
-		}
-	}
-}
-
-func TestRemoveAll(t *testing.T) {
-	tmpDir := TempDir()
-	// Work directory.
-	path := tmpDir + "/_TestRemoveAll_"
-	fpath := path + "/file"
-	dpath := path + "/dir"
-
-	// Make directory with 1 file and remove.
-	if err := MkdirAll(path, 0777); err != nil {
-		t.Fatalf("MkdirAll %q: %s", path, err)
-	}
-	fd, err := Create(fpath)
-	if err != nil {
-		t.Fatalf("create %q: %s", fpath, err)
-	}
-	fd.Close()
-	if err = RemoveAll(path); err != nil {
-		t.Fatalf("RemoveAll %q (first): %s", path, err)
-	}
-	if _, err = Lstat(path); err == nil {
-		t.Fatalf("Lstat %q succeeded after RemoveAll (first)", path)
-	}
-
-	// Make directory with file and subdirectory and remove.
-	if err = MkdirAll(dpath, 0777); err != nil {
-		t.Fatalf("MkdirAll %q: %s", dpath, err)
-	}
-	fd, err = Create(fpath)
-	if err != nil {
-		t.Fatalf("create %q: %s", fpath, err)
-	}
-	fd.Close()
-	fd, err = Create(dpath + "/file")
-	if err != nil {
-		t.Fatalf("create %q: %s", fpath, err)
-	}
-	fd.Close()
-	if err = RemoveAll(path); err != nil {
-		t.Fatalf("RemoveAll %q (second): %s", path, err)
-	}
-	if _, err := Lstat(path); err == nil {
-		t.Fatalf("Lstat %q succeeded after RemoveAll (second)", path)
-	}
-
-	// Determine if we should run the following test.
-	testit := true
-	if runtime.GOOS == "windows" {
-		// Chmod is not supported under windows.
-		testit = false
-	} else {
-		// Test fails as root.
-		testit = Getuid() != 0
-	}
-	if testit {
-		// Make directory with file and subdirectory and trigger error.
-		if err = MkdirAll(dpath, 0777); err != nil {
-			t.Fatalf("MkdirAll %q: %s", dpath, err)
-		}
-
-		for _, s := range []string{fpath, dpath + "/file1", path + "/zzz"} {
-			fd, err = Create(s)
-			if err != nil {
-				t.Fatalf("create %q: %s", s, err)
-			}
-			fd.Close()
-		}
-		if err = Chmod(dpath, 0); err != nil {
-			t.Fatalf("Chmod %q 0: %s", dpath, err)
-		}
-
-		// No error checking here: either RemoveAll
-		// will or won't be able to remove dpath;
-		// either way we want to see if it removes fpath
-		// and path/zzz.  Reasons why RemoveAll might
-		// succeed in removing dpath as well include:
-		//	* running as root
-		//	* running on a file system without permissions (FAT)
-		RemoveAll(path)
-		Chmod(dpath, 0777)
-
-		for _, s := range []string{fpath, path + "/zzz"} {
-			if _, err = Lstat(s); err == nil {
-				t.Fatalf("Lstat %q succeeded after partial RemoveAll", s)
-			}
-		}
-	}
-	if err = RemoveAll(path); err != nil {
-		t.Fatalf("RemoveAll %q after partial RemoveAll: %s", path, err)
-	}
-	if _, err = Lstat(path); err == nil {
-		t.Fatalf("Lstat %q succeeded after RemoveAll (final)", path)
-	}
-}
-
-func TestMkdirAllWithSymlink(t *testing.T) {
-	switch runtime.GOOS {
-	case "nacl", "plan9", "windows":
-		t.Skipf("skipping on %s", runtime.GOOS)
-	}
-
-	tmpDir, err := ioutil.TempDir("", "TestMkdirAllWithSymlink-")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer RemoveAll(tmpDir)
-
-	dir := tmpDir + "/dir"
-	err = Mkdir(dir, 0755)
-	if err != nil {
-		t.Fatalf("Mkdir %s: %s", dir, err)
-	}
-
-	link := tmpDir + "/link"
-	err = Symlink("dir", link)
-	if err != nil {
-		t.Fatalf("Symlink %s: %s", link, err)
-	}
-
-	path := link + "/foo"
-	err = MkdirAll(path, 0755)
-	if err != nil {
-		t.Errorf("MkdirAll %q: %s", path, err)
-	}
-}
-
-func TestMkdirAllAtSlash(t *testing.T) {
-	if runtime.GOOS == "windows" || runtime.GOOS == "plan9" {
-		return
-	}
-	RemoveAll("/_go_os_test")
-	err := MkdirAll("/_go_os_test/dir", 0777)
-	if err != nil {
-		pathErr, ok := err.(*PathError)
-		// common for users not to be able to write to /
-		if ok && pathErr.Err == syscall.EACCES {
-			return
-		}
-		t.Fatalf(`MkdirAll "/_go_os_test/dir": %v`, err)
-	}
-	RemoveAll("/_go_os_test")
-}
diff --git a/src/pkg/os/proc.go b/src/pkg/os/proc.go
deleted file mode 100644
index 38c436e..0000000
--- a/src/pkg/os/proc.go
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Process etc.
-
-package os
-
-import "syscall"
-
-// Args hold the command-line arguments, starting with the program name.
-var Args []string
-
-// Getuid returns the numeric user id of the caller.
-func Getuid() int { return syscall.Getuid() }
-
-// Geteuid returns the numeric effective user id of the caller.
-func Geteuid() int { return syscall.Geteuid() }
-
-// Getgid returns the numeric group id of the caller.
-func Getgid() int { return syscall.Getgid() }
-
-// Getegid returns the numeric effective group id of the caller.
-func Getegid() int { return syscall.Getegid() }
-
-// Getgroups returns a list of the numeric ids of groups that the caller belongs to.
-func Getgroups() ([]int, error) {
-	gids, e := syscall.Getgroups()
-	return gids, NewSyscallError("getgroups", e)
-}
-
-// Exit causes the current program to exit with the given status code.
-// Conventionally, code zero indicates success, non-zero an error.
-// The program terminates immediately; deferred functions are
-// not run.
-func Exit(code int) { syscall.Exit(code) }
diff --git a/src/pkg/os/signal/sig.s b/src/pkg/os/signal/sig.s
deleted file mode 100644
index f860924..0000000
--- a/src/pkg/os/signal/sig.s
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2012 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Assembly to get into package runtime without using exported symbols.
-
-// +build amd64 amd64p32 arm 386
-
-#include "../../../cmd/ld/textflag.h"
-
-#ifdef GOARCH_arm
-#define JMP B
-#endif
-
-TEXT ·signal_disable(SB),NOSPLIT,$0
-	JMP runtime·signal_disable(SB)
-
-TEXT ·signal_enable(SB),NOSPLIT,$0
-	JMP runtime·signal_enable(SB)
-
-TEXT ·signal_recv(SB),NOSPLIT,$0
-	JMP runtime·signal_recv(SB)
-
diff --git a/src/pkg/os/signal/signal_test.go b/src/pkg/os/signal/signal_test.go
deleted file mode 100644
index 076fe3f..0000000
--- a/src/pkg/os/signal/signal_test.go
+++ /dev/null
@@ -1,208 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build darwin dragonfly freebsd linux netbsd openbsd solaris
-
-package signal
-
-import (
-	"flag"
-	"io/ioutil"
-	"os"
-	"os/exec"
-	"runtime"
-	"strconv"
-	"syscall"
-	"testing"
-	"time"
-)
-
-func waitSig(t *testing.T, c <-chan os.Signal, sig os.Signal) {
-	select {
-	case s := <-c:
-		if s != sig {
-			t.Fatalf("signal was %v, want %v", s, sig)
-		}
-	case <-time.After(1 * time.Second):
-		t.Fatalf("timeout waiting for %v", sig)
-	}
-}
-
-// Test that basic signal handling works.
-func TestSignal(t *testing.T) {
-	// Ask for SIGHUP
-	c := make(chan os.Signal, 1)
-	Notify(c, syscall.SIGHUP)
-	defer Stop(c)
-
-	// Send this process a SIGHUP
-	t.Logf("sighup...")
-	syscall.Kill(syscall.Getpid(), syscall.SIGHUP)
-	waitSig(t, c, syscall.SIGHUP)
-
-	// Ask for everything we can get.
-	c1 := make(chan os.Signal, 1)
-	Notify(c1)
-
-	// Send this process a SIGWINCH
-	t.Logf("sigwinch...")
-	syscall.Kill(syscall.Getpid(), syscall.SIGWINCH)
-	waitSig(t, c1, syscall.SIGWINCH)
-
-	// Send two more SIGHUPs, to make sure that
-	// they get delivered on c1 and that not reading
-	// from c does not block everything.
-	t.Logf("sighup...")
-	syscall.Kill(syscall.Getpid(), syscall.SIGHUP)
-	waitSig(t, c1, syscall.SIGHUP)
-	t.Logf("sighup...")
-	syscall.Kill(syscall.Getpid(), syscall.SIGHUP)
-	waitSig(t, c1, syscall.SIGHUP)
-
-	// The first SIGHUP should be waiting for us on c.
-	waitSig(t, c, syscall.SIGHUP)
-}
-
-func TestStress(t *testing.T) {
-	dur := 3 * time.Second
-	if testing.Short() {
-		dur = 100 * time.Millisecond
-	}
-	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4))
-	done := make(chan bool)
-	finished := make(chan bool)
-	go func() {
-		sig := make(chan os.Signal, 1)
-		Notify(sig, syscall.SIGUSR1)
-		defer Stop(sig)
-	Loop:
-		for {
-			select {
-			case <-sig:
-			case <-done:
-				break Loop
-			}
-		}
-		finished <- true
-	}()
-	go func() {
-	Loop:
-		for {
-			select {
-			case <-done:
-				break Loop
-			default:
-				syscall.Kill(syscall.Getpid(), syscall.SIGUSR1)
-				runtime.Gosched()
-			}
-		}
-		finished <- true
-	}()
-	time.Sleep(dur)
-	close(done)
-	<-finished
-	<-finished
-	// When run with 'go test -cpu=1,2,4' SIGUSR1 from this test can slip
-	// into subsequent TestSignal() causing failure.
-	// Sleep for a while to reduce the possibility of the failure.
-	time.Sleep(10 * time.Millisecond)
-}
-
-var sendUncaughtSighup = flag.Int("send_uncaught_sighup", 0, "send uncaught SIGHUP during TestStop")
-
-// Test that Stop cancels the channel's registrations.
-func TestStop(t *testing.T) {
-	sigs := []syscall.Signal{
-		syscall.SIGWINCH,
-		syscall.SIGHUP,
-	}
-
-	for _, sig := range sigs {
-		// Send the signal.
-		// If it's SIGWINCH, we should not see it.
-		// If it's SIGHUP, maybe we'll die. Let the flag tell us what to do.
-		if sig != syscall.SIGHUP || *sendUncaughtSighup == 1 {
-			syscall.Kill(syscall.Getpid(), sig)
-		}
-		time.Sleep(10 * time.Millisecond)
-
-		// Ask for signal
-		c := make(chan os.Signal, 1)
-		Notify(c, sig)
-		defer Stop(c)
-
-		// Send this process that signal
-		syscall.Kill(syscall.Getpid(), sig)
-		waitSig(t, c, sig)
-
-		Stop(c)
-		select {
-		case s := <-c:
-			t.Fatalf("unexpected signal %v", s)
-		case <-time.After(10 * time.Millisecond):
-			// nothing to read - good
-		}
-
-		// Send the signal.
-		// If it's SIGWINCH, we should not see it.
-		// If it's SIGHUP, maybe we'll die. Let the flag tell us what to do.
-		if sig != syscall.SIGHUP || *sendUncaughtSighup == 2 {
-			syscall.Kill(syscall.Getpid(), sig)
-		}
-
-		select {
-		case s := <-c:
-			t.Fatalf("unexpected signal %v", s)
-		case <-time.After(10 * time.Millisecond):
-			// nothing to read - good
-		}
-	}
-}
-
-// Test that when run under nohup, an uncaught SIGHUP does not kill the program,
-// but a
-func TestNohup(t *testing.T) {
-	// Ugly: ask for SIGHUP so that child will not have no-hup set
-	// even if test is running under nohup environment.
-	// We have no intention of reading from c.
-	c := make(chan os.Signal, 1)
-	Notify(c, syscall.SIGHUP)
-
-	// When run without nohup, the test should crash on an uncaught SIGHUP.
-	// When run under nohup, the test should ignore uncaught SIGHUPs,
-	// because the runtime is not supposed to be listening for them.
-	// Either way, TestStop should still be able to catch them when it wants them
-	// and then when it stops wanting them, the original behavior should resume.
-	//
-	// send_uncaught_sighup=1 sends the SIGHUP before starting to listen for SIGHUPs.
-	// send_uncaught_sighup=2 sends the SIGHUP after no longer listening for SIGHUPs.
-	//
-	// Both should fail without nohup and succeed with nohup.
-
-	for i := 1; i <= 2; i++ {
-		out, err := exec.Command(os.Args[0], "-test.run=TestStop", "-send_uncaught_sighup="+strconv.Itoa(i)).CombinedOutput()
-		if err == nil {
-			t.Fatalf("ran test with -send_uncaught_sighup=%d and it succeeded: expected failure.\nOutput:\n%s", i, out)
-		}
-	}
-
-	Stop(c)
-
-	// Again, this time with nohup, assuming we can find it.
-	_, err := os.Stat("/usr/bin/nohup")
-	if err != nil {
-		t.Skip("cannot find nohup; skipping second half of test")
-	}
-
-	for i := 1; i <= 2; i++ {
-		os.Remove("nohup.out")
-		out, err := exec.Command("/usr/bin/nohup", os.Args[0], "-test.run=TestStop", "-send_uncaught_sighup="+strconv.Itoa(i)).CombinedOutput()
-
-		data, _ := ioutil.ReadFile("nohup.out")
-		os.Remove("nohup.out")
-		if err != nil {
-			t.Fatalf("ran test with -send_uncaught_sighup=%d under nohup and it failed: expected success.\nError: %v\nOutput:\n%s%s", i, err, out, data)
-		}
-	}
-}
diff --git a/src/pkg/os/stat_windows.go b/src/pkg/os/stat_windows.go
deleted file mode 100644
index 6dc3866..0000000
--- a/src/pkg/os/stat_windows.go
+++ /dev/null
@@ -1,160 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package os
-
-import (
-	"syscall"
-	"unsafe"
-)
-
-// Stat returns the FileInfo structure describing file.
-// If there is an error, it will be of type *PathError.
-func (file *File) Stat() (fi FileInfo, err error) {
-	if file == nil {
-		return nil, ErrInvalid
-	}
-	if file == nil || file.fd < 0 {
-		return nil, syscall.EINVAL
-	}
-	if file.isdir() {
-		// I don't know any better way to do that for directory
-		return Stat(file.name)
-	}
-	if file.name == DevNull {
-		return &devNullStat, nil
-	}
-	var d syscall.ByHandleFileInformation
-	e := syscall.GetFileInformationByHandle(syscall.Handle(file.fd), &d)
-	if e != nil {
-		return nil, &PathError{"GetFileInformationByHandle", file.name, e}
-	}
-	return &fileStat{
-		name: basename(file.name),
-		sys: syscall.Win32FileAttributeData{
-			FileAttributes: d.FileAttributes,
-			CreationTime:   d.CreationTime,
-			LastAccessTime: d.LastAccessTime,
-			LastWriteTime:  d.LastWriteTime,
-			FileSizeHigh:   d.FileSizeHigh,
-			FileSizeLow:    d.FileSizeLow,
-		},
-		vol:   d.VolumeSerialNumber,
-		idxhi: d.FileIndexHigh,
-		idxlo: d.FileIndexLow,
-	}, nil
-}
-
-// Stat returns a FileInfo structure describing the named file.
-// If there is an error, it will be of type *PathError.
-func Stat(name string) (fi FileInfo, err error) {
-	if len(name) == 0 {
-		return nil, &PathError{"Stat", name, syscall.Errno(syscall.ERROR_PATH_NOT_FOUND)}
-	}
-	if name == DevNull {
-		return &devNullStat, nil
-	}
-	fs := &fileStat{name: basename(name)}
-	namep, e := syscall.UTF16PtrFromString(name)
-	if e != nil {
-		return nil, &PathError{"Stat", name, e}
-	}
-	e = syscall.GetFileAttributesEx(namep, syscall.GetFileExInfoStandard, (*byte)(unsafe.Pointer(&fs.sys)))
-	if e != nil {
-		return nil, &PathError{"GetFileAttributesEx", name, e}
-	}
-	fs.path = name
-	if !isAbs(fs.path) {
-		cwd, _ := Getwd()
-		fs.path = cwd + `\` + fs.path
-	}
-	return fs, nil
-}
-
-// Lstat returns the FileInfo structure describing the named file.
-// If the file is a symbolic link, the returned FileInfo
-// describes the symbolic link.  Lstat makes no attempt to follow the link.
-// If there is an error, it will be of type *PathError.
-func Lstat(name string) (fi FileInfo, err error) {
-	// No links on Windows
-	return Stat(name)
-}
-
-// basename removes trailing slashes and the leading
-// directory name and drive letter from path name.
-func basename(name string) string {
-	// Remove drive letter
-	if len(name) == 2 && name[1] == ':' {
-		name = "."
-	} else if len(name) > 2 && name[1] == ':' {
-		name = name[2:]
-	}
-	i := len(name) - 1
-	// Remove trailing slashes
-	for ; i > 0 && (name[i] == '/' || name[i] == '\\'); i-- {
-		name = name[:i]
-	}
-	// Remove leading directory name
-	for i--; i >= 0; i-- {
-		if name[i] == '/' || name[i] == '\\' {
-			name = name[i+1:]
-			break
-		}
-	}
-	return name
-}
-
-func isSlash(c uint8) bool {
-	return c == '\\' || c == '/'
-}
-
-func isAbs(path string) (b bool) {
-	v := volumeName(path)
-	if v == "" {
-		return false
-	}
-	path = path[len(v):]
-	if path == "" {
-		return false
-	}
-	return isSlash(path[0])
-}
-
-func volumeName(path string) (v string) {
-	if len(path) < 2 {
-		return ""
-	}
-	// with drive letter
-	c := path[0]
-	if path[1] == ':' &&
-		('0' <= c && c <= '9' || 'a' <= c && c <= 'z' ||
-			'A' <= c && c <= 'Z') {
-		return path[:2]
-	}
-	// is it UNC
-	if l := len(path); l >= 5 && isSlash(path[0]) && isSlash(path[1]) &&
-		!isSlash(path[2]) && path[2] != '.' {
-		// first, leading `\\` and next shouldn't be `\`. its server name.
-		for n := 3; n < l-1; n++ {
-			// second, next '\' shouldn't be repeated.
-			if isSlash(path[n]) {
-				n++
-				// third, following something characters. its share name.
-				if !isSlash(path[n]) {
-					if path[n] == '.' {
-						break
-					}
-					for ; n < l; n++ {
-						if isSlash(path[n]) {
-							break
-						}
-					}
-					return path[:n]
-				}
-				break
-			}
-		}
-	}
-	return ""
-}
diff --git a/src/pkg/os/types_windows.go b/src/pkg/os/types_windows.go
deleted file mode 100644
index 3890168..0000000
--- a/src/pkg/os/types_windows.go
+++ /dev/null
@@ -1,104 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package os
-
-import (
-	"sync"
-	"syscall"
-	"time"
-)
-
-// A fileStat is the implementation of FileInfo returned by Stat and Lstat.
-type fileStat struct {
-	name string
-	sys  syscall.Win32FileAttributeData
-
-	// used to implement SameFile
-	sync.Mutex
-	path  string
-	vol   uint32
-	idxhi uint32
-	idxlo uint32
-}
-
-func (fs *fileStat) Size() int64 {
-	return int64(fs.sys.FileSizeHigh)<<32 + int64(fs.sys.FileSizeLow)
-}
-
-func (fs *fileStat) Mode() (m FileMode) {
-	if fs == &devNullStat {
-		return ModeDevice | ModeCharDevice | 0666
-	}
-	if fs.sys.FileAttributes&syscall.FILE_ATTRIBUTE_DIRECTORY != 0 {
-		m |= ModeDir | 0111
-	}
-	if fs.sys.FileAttributes&syscall.FILE_ATTRIBUTE_READONLY != 0 {
-		m |= 0444
-	} else {
-		m |= 0666
-	}
-	return m
-}
-
-func (fs *fileStat) ModTime() time.Time {
-	return time.Unix(0, fs.sys.LastWriteTime.Nanoseconds())
-}
-
-// Sys returns syscall.Win32FileAttributeData for file fs.
-func (fs *fileStat) Sys() interface{} { return &fs.sys }
-
-func (fs *fileStat) loadFileId() error {
-	fs.Lock()
-	defer fs.Unlock()
-	if fs.path == "" {
-		// already done
-		return nil
-	}
-	pathp, err := syscall.UTF16PtrFromString(fs.path)
-	if err != nil {
-		return err
-	}
-	h, err := syscall.CreateFile(pathp, 0, 0, nil, syscall.OPEN_EXISTING, syscall.FILE_FLAG_BACKUP_SEMANTICS, 0)
-	if err != nil {
-		return err
-	}
-	defer syscall.CloseHandle(h)
-	var i syscall.ByHandleFileInformation
-	err = syscall.GetFileInformationByHandle(syscall.Handle(h), &i)
-	if err != nil {
-		return err
-	}
-	fs.path = ""
-	fs.vol = i.VolumeSerialNumber
-	fs.idxhi = i.FileIndexHigh
-	fs.idxlo = i.FileIndexLow
-	return nil
-}
-
-// devNullStat is fileStat structure describing DevNull file ("NUL").
-var devNullStat = fileStat{
-	name: DevNull,
-	// hopefully this will work for SameFile
-	vol:   0,
-	idxhi: 0,
-	idxlo: 0,
-}
-
-func sameFile(fs1, fs2 *fileStat) bool {
-	e := fs1.loadFileId()
-	if e != nil {
-		return false
-	}
-	e = fs2.loadFileId()
-	if e != nil {
-		return false
-	}
-	return fs1.vol == fs2.vol && fs1.idxhi == fs2.idxhi && fs1.idxlo == fs2.idxlo
-}
-
-// For testing.
-func atime(fi FileInfo) time.Time {
-	return time.Unix(0, fi.Sys().(*syscall.Win32FileAttributeData).LastAccessTime.Nanoseconds())
-}
diff --git a/src/pkg/os/user/lookup_stubs.go b/src/pkg/os/user/lookup_stubs.go
deleted file mode 100644
index 86f0e6e..0000000
--- a/src/pkg/os/user/lookup_stubs.go
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build !cgo,!windows,!plan9
-
-package user
-
-import (
-	"fmt"
-	"runtime"
-)
-
-func init() {
-	implemented = false
-}
-
-func current() (*User, error) {
-	return nil, fmt.Errorf("user: Current not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
-}
-
-func lookup(username string) (*User, error) {
-	return nil, fmt.Errorf("user: Lookup not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
-}
-
-func lookupId(uid string) (*User, error) {
-	return nil, fmt.Errorf("user: LookupId not implemented on %s/%s", runtime.GOOS, runtime.GOARCH)
-}
diff --git a/src/pkg/os/user/lookup_unix.go b/src/pkg/os/user/lookup_unix.go
deleted file mode 100644
index f2baf05..0000000
--- a/src/pkg/os/user/lookup_unix.go
+++ /dev/null
@@ -1,112 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build darwin dragonfly freebsd linux netbsd openbsd solaris
-// +build cgo
-
-package user
-
-import (
-	"fmt"
-	"runtime"
-	"strconv"
-	"strings"
-	"syscall"
-	"unsafe"
-)
-
-/*
-#include <unistd.h>
-#include <sys/types.h>
-#include <pwd.h>
-#include <stdlib.h>
-
-static int mygetpwuid_r(int uid, struct passwd *pwd,
-	char *buf, size_t buflen, struct passwd **result) {
- return getpwuid_r(uid, pwd, buf, buflen, result);
-}
-*/
-import "C"
-
-func current() (*User, error) {
-	return lookupUnix(syscall.Getuid(), "", false)
-}
-
-func lookup(username string) (*User, error) {
-	return lookupUnix(-1, username, true)
-}
-
-func lookupId(uid string) (*User, error) {
-	i, e := strconv.Atoi(uid)
-	if e != nil {
-		return nil, e
-	}
-	return lookupUnix(i, "", false)
-}
-
-func lookupUnix(uid int, username string, lookupByName bool) (*User, error) {
-	var pwd C.struct_passwd
-	var result *C.struct_passwd
-
-	var bufSize C.long
-	if runtime.GOOS == "dragonfly" || runtime.GOOS == "freebsd" {
-		// DragonFly and FreeBSD do not have _SC_GETPW_R_SIZE_MAX
-		// and just return -1.  So just use the same
-		// size that Linux returns.
-		bufSize = 1024
-	} else {
-		bufSize = C.sysconf(C._SC_GETPW_R_SIZE_MAX)
-		if bufSize <= 0 || bufSize > 1<<20 {
-			return nil, fmt.Errorf("user: unreasonable _SC_GETPW_R_SIZE_MAX of %d", bufSize)
-		}
-	}
-	buf := C.malloc(C.size_t(bufSize))
-	defer C.free(buf)
-	var rv C.int
-	if lookupByName {
-		nameC := C.CString(username)
-		defer C.free(unsafe.Pointer(nameC))
-		rv = C.getpwnam_r(nameC,
-			&pwd,
-			(*C.char)(buf),
-			C.size_t(bufSize),
-			&result)
-		if rv != 0 {
-			return nil, fmt.Errorf("user: lookup username %s: %s", username, syscall.Errno(rv))
-		}
-		if result == nil {
-			return nil, UnknownUserError(username)
-		}
-	} else {
-		// mygetpwuid_r is a wrapper around getpwuid_r to
-		// to avoid using uid_t because C.uid_t(uid) for
-		// unknown reasons doesn't work on linux.
-		rv = C.mygetpwuid_r(C.int(uid),
-			&pwd,
-			(*C.char)(buf),
-			C.size_t(bufSize),
-			&result)
-		if rv != 0 {
-			return nil, fmt.Errorf("user: lookup userid %d: %s", uid, syscall.Errno(rv))
-		}
-		if result == nil {
-			return nil, UnknownUserIdError(uid)
-		}
-	}
-	u := &User{
-		Uid:      strconv.Itoa(int(pwd.pw_uid)),
-		Gid:      strconv.Itoa(int(pwd.pw_gid)),
-		Username: C.GoString(pwd.pw_name),
-		Name:     C.GoString(pwd.pw_gecos),
-		HomeDir:  C.GoString(pwd.pw_dir),
-	}
-	// The pw_gecos field isn't quite standardized.  Some docs
-	// say: "It is expected to be a comma separated list of
-	// personal data where the first item is the full name of the
-	// user."
-	if i := strings.Index(u.Name, ","); i >= 0 {
-		u.Name = u.Name[:i]
-	}
-	return u, nil
-}
diff --git a/src/pkg/path/filepath/match.go b/src/pkg/path/filepath/match.go
deleted file mode 100644
index a9bcc10..0000000
--- a/src/pkg/path/filepath/match.go
+++ /dev/null
@@ -1,309 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package filepath
-
-import (
-	"errors"
-	"os"
-	"runtime"
-	"sort"
-	"strings"
-	"unicode/utf8"
-)
-
-// ErrBadPattern indicates a globbing pattern was malformed.
-var ErrBadPattern = errors.New("syntax error in pattern")
-
-// Match returns true if name matches the shell file name pattern.
-// The pattern syntax is:
-//
-//	pattern:
-//		{ term }
-//	term:
-//		'*'         matches any sequence of non-Separator characters
-//		'?'         matches any single non-Separator character
-//		'[' [ '^' ] { character-range } ']'
-//		            character class (must be non-empty)
-//		c           matches character c (c != '*', '?', '\\', '[')
-//		'\\' c      matches character c
-//
-//	character-range:
-//		c           matches character c (c != '\\', '-', ']')
-//		'\\' c      matches character c
-//		lo '-' hi   matches character c for lo <= c <= hi
-//
-// Match requires pattern to match all of name, not just a substring.
-// The only possible returned error is ErrBadPattern, when pattern
-// is malformed.
-//
-// On Windows, escaping is disabled. Instead, '\\' is treated as
-// path separator.
-//
-func Match(pattern, name string) (matched bool, err error) {
-Pattern:
-	for len(pattern) > 0 {
-		var star bool
-		var chunk string
-		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
-		}
-		// Look for match at current position.
-		t, ok, err := matchChunk(chunk, name)
-		// if we're the last chunk, make sure we've exhausted the name
-		// otherwise we'll give a false result even if we could still match
-		// using the star
-		if ok && (len(t) == 0 || len(pattern) > 0) {
-			name = t
-			continue
-		}
-		if err != nil {
-			return false, err
-		}
-		if star {
-			// Look for match skipping i+1 bytes.
-			// Cannot skip /.
-			for i := 0; i < len(name) && name[i] != Separator; i++ {
-				t, ok, err := matchChunk(chunk, name[i+1:])
-				if ok {
-					// if we're the last chunk, make sure we exhausted the name
-					if len(pattern) == 0 && len(t) > 0 {
-						continue
-					}
-					name = t
-					continue Pattern
-				}
-				if err != nil {
-					return false, err
-				}
-			}
-		}
-		return false, nil
-	}
-	return len(name) == 0, nil
-}
-
-// scanChunk gets the next segment of pattern, which is a non-star string
-// possibly preceded by a star.
-func scanChunk(pattern string) (star bool, chunk, rest string) {
-	for len(pattern) > 0 && pattern[0] == '*' {
-		pattern = pattern[1:]
-		star = true
-	}
-	inrange := false
-	var i int
-Scan:
-	for i = 0; i < len(pattern); i++ {
-		switch pattern[i] {
-		case '\\':
-			if runtime.GOOS != "windows" {
-				// error check handled in matchChunk: bad pattern.
-				if i+1 < len(pattern) {
-					i++
-				}
-			}
-		case '[':
-			inrange = true
-		case ']':
-			inrange = false
-		case '*':
-			if !inrange {
-				break Scan
-			}
-		}
-	}
-	return star, pattern[0:i], pattern[i:]
-}
-
-// matchChunk checks whether chunk matches the beginning of s.
-// If so, it returns the remainder of s (after the match).
-// Chunk is all single-character operators: literals, char classes, and ?.
-func matchChunk(chunk, s string) (rest string, ok bool, err error) {
-	for len(chunk) > 0 {
-		if len(s) == 0 {
-			return
-		}
-		switch chunk[0] {
-		case '[':
-			// character class
-			r, n := utf8.DecodeRuneInString(s)
-			s = s[n:]
-			chunk = chunk[1:]
-			// We can't end right after '[', we're expecting at least
-			// a closing bracket and possibly a caret.
-			if len(chunk) == 0 {
-				err = ErrBadPattern
-				return
-			}
-			// possibly negated
-			negated := chunk[0] == '^'
-			if negated {
-				chunk = chunk[1:]
-			}
-			// parse all ranges
-			match := false
-			nrange := 0
-			for {
-				if len(chunk) > 0 && chunk[0] == ']' && nrange > 0 {
-					chunk = chunk[1:]
-					break
-				}
-				var lo, hi rune
-				if lo, chunk, err = getEsc(chunk); err != nil {
-					return
-				}
-				hi = lo
-				if chunk[0] == '-' {
-					if hi, chunk, err = getEsc(chunk[1:]); err != nil {
-						return
-					}
-				}
-				if lo <= r && r <= hi {
-					match = true
-				}
-				nrange++
-			}
-			if match == negated {
-				return
-			}
-
-		case '?':
-			if s[0] == Separator {
-				return
-			}
-			_, n := utf8.DecodeRuneInString(s)
-			s = s[n:]
-			chunk = chunk[1:]
-
-		case '\\':
-			if runtime.GOOS != "windows" {
-				chunk = chunk[1:]
-				if len(chunk) == 0 {
-					err = ErrBadPattern
-					return
-				}
-			}
-			fallthrough
-
-		default:
-			if chunk[0] != s[0] {
-				return
-			}
-			s = s[1:]
-			chunk = chunk[1:]
-		}
-	}
-	return s, true, nil
-}
-
-// getEsc gets a possibly-escaped character from chunk, for a character class.
-func getEsc(chunk string) (r rune, nchunk string, err error) {
-	if len(chunk) == 0 || chunk[0] == '-' || chunk[0] == ']' {
-		err = ErrBadPattern
-		return
-	}
-	if chunk[0] == '\\' && runtime.GOOS != "windows" {
-		chunk = chunk[1:]
-		if len(chunk) == 0 {
-			err = ErrBadPattern
-			return
-		}
-	}
-	r, n := utf8.DecodeRuneInString(chunk)
-	if r == utf8.RuneError && n == 1 {
-		err = ErrBadPattern
-	}
-	nchunk = chunk[n:]
-	if len(nchunk) == 0 {
-		err = ErrBadPattern
-	}
-	return
-}
-
-// Glob returns the names of all files matching pattern or nil
-// if there is no matching file. The syntax of patterns is the same
-// as in Match. The pattern may describe hierarchical names such as
-// /usr/*/bin/ed (assuming the Separator is '/').
-//
-func Glob(pattern string) (matches []string, err error) {
-	if !hasMeta(pattern) {
-		if _, err = os.Lstat(pattern); err != nil {
-			return nil, nil
-		}
-		return []string{pattern}, nil
-	}
-
-	dir, file := Split(pattern)
-	switch dir {
-	case "":
-		dir = "."
-	case string(Separator):
-		// nothing
-	default:
-		dir = dir[0 : len(dir)-1] // chop off trailing separator
-	}
-
-	if !hasMeta(dir) {
-		return glob(dir, file, nil)
-	}
-
-	var m []string
-	m, err = Glob(dir)
-	if err != nil {
-		return
-	}
-	for _, d := range m {
-		matches, err = glob(d, file, matches)
-		if err != nil {
-			return
-		}
-	}
-	return
-}
-
-// glob searches for files matching pattern in the directory dir
-// and appends them to matches. If the directory cannot be
-// opened, it returns the existing matches. New matches are
-// added in lexicographical order.
-func glob(dir, pattern string, matches []string) (m []string, e error) {
-	m = matches
-	fi, err := os.Stat(dir)
-	if err != nil {
-		return
-	}
-	if !fi.IsDir() {
-		return
-	}
-	d, err := os.Open(dir)
-	if err != nil {
-		return
-	}
-	defer d.Close()
-
-	names, err := d.Readdirnames(-1)
-	if err != nil {
-		return
-	}
-	sort.Strings(names)
-
-	for _, n := range names {
-		matched, err := Match(pattern, n)
-		if err != nil {
-			return m, err
-		}
-		if matched {
-			m = append(m, Join(dir, n))
-		}
-	}
-	return
-}
-
-// hasMeta returns true if path contains any of the magic characters
-// recognized by Match.
-func hasMeta(path string) bool {
-	// TODO(niemeyer): Should other magic characters be added here?
-	return strings.IndexAny(path, "*?[") >= 0
-}
diff --git a/src/pkg/path/filepath/match_test.go b/src/pkg/path/filepath/match_test.go
deleted file mode 100644
index 382692e..0000000
--- a/src/pkg/path/filepath/match_test.go
+++ /dev/null
@@ -1,206 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package filepath_test
-
-import (
-	"io/ioutil"
-	"os"
-	. "path/filepath"
-	"runtime"
-	"strings"
-	"testing"
-)
-
-type MatchTest struct {
-	pattern, s string
-	match      bool
-	err        error
-}
-
-var matchTests = []MatchTest{
-	{"abc", "abc", true, nil},
-	{"*", "abc", true, nil},
-	{"*c", "abc", true, nil},
-	{"a*", "a", true, nil},
-	{"a*", "abc", true, nil},
-	{"a*", "ab/c", false, nil},
-	{"a*/b", "abc/b", true, nil},
-	{"a*/b", "a/c/b", false, nil},
-	{"a*b*c*d*e*/f", "axbxcxdxe/f", true, nil},
-	{"a*b*c*d*e*/f", "axbxcxdxexxx/f", true, nil},
-	{"a*b*c*d*e*/f", "axbxcxdxe/xxx/f", false, nil},
-	{"a*b*c*d*e*/f", "axbxcxdxexxx/fff", false, nil},
-	{"a*b?c*x", "abxbbxdbxebxczzx", true, nil},
-	{"a*b?c*x", "abxbbxdbxebxczzy", false, nil},
-	{"ab[c]", "abc", true, nil},
-	{"ab[b-d]", "abc", true, nil},
-	{"ab[e-g]", "abc", false, nil},
-	{"ab[^c]", "abc", false, nil},
-	{"ab[^b-d]", "abc", false, nil},
-	{"ab[^e-g]", "abc", true, nil},
-	{"a\\*b", "a*b", true, nil},
-	{"a\\*b", "ab", false, nil},
-	{"a?b", "a☺b", true, nil},
-	{"a[^a]b", "a☺b", true, nil},
-	{"a???b", "a☺b", false, nil},
-	{"a[^a][^a][^a]b", "a☺b", false, nil},
-	{"[a-ζ]*", "α", true, nil},
-	{"*[a-ζ]", "A", false, nil},
-	{"a?b", "a/b", false, nil},
-	{"a*b", "a/b", false, nil},
-	{"[\\]a]", "]", true, nil},
-	{"[\\-]", "-", true, nil},
-	{"[x\\-]", "x", true, nil},
-	{"[x\\-]", "-", true, nil},
-	{"[x\\-]", "z", false, nil},
-	{"[\\-x]", "x", true, nil},
-	{"[\\-x]", "-", true, nil},
-	{"[\\-x]", "a", false, nil},
-	{"[]a]", "]", false, ErrBadPattern},
-	{"[-]", "-", false, ErrBadPattern},
-	{"[x-]", "x", false, ErrBadPattern},
-	{"[x-]", "-", false, ErrBadPattern},
-	{"[x-]", "z", false, ErrBadPattern},
-	{"[-x]", "x", false, ErrBadPattern},
-	{"[-x]", "-", false, ErrBadPattern},
-	{"[-x]", "a", false, ErrBadPattern},
-	{"\\", "a", false, ErrBadPattern},
-	{"[a-b-c]", "a", false, ErrBadPattern},
-	{"[", "a", false, ErrBadPattern},
-	{"[^", "a", false, ErrBadPattern},
-	{"[^bc", "a", false, ErrBadPattern},
-	{"a[", "a", false, nil},
-	{"a[", "ab", false, ErrBadPattern},
-	{"*x", "xxx", true, nil},
-}
-
-func errp(e error) string {
-	if e == nil {
-		return "<nil>"
-	}
-	return e.Error()
-}
-
-func TestMatch(t *testing.T) {
-	for _, tt := range matchTests {
-		pattern := tt.pattern
-		s := tt.s
-		if runtime.GOOS == "windows" {
-			if strings.Index(pattern, "\\") >= 0 {
-				// no escape allowed on windows.
-				continue
-			}
-			pattern = Clean(pattern)
-			s = Clean(s)
-		}
-		ok, err := Match(pattern, s)
-		if ok != tt.match || err != tt.err {
-			t.Errorf("Match(%#q, %#q) = %v, %q want %v, %q", pattern, s, ok, errp(err), tt.match, errp(tt.err))
-		}
-	}
-}
-
-// contains returns true if vector contains the string s.
-func contains(vector []string, s string) bool {
-	for _, elem := range vector {
-		if elem == s {
-			return true
-		}
-	}
-	return false
-}
-
-var globTests = []struct {
-	pattern, result string
-}{
-	{"match.go", "match.go"},
-	{"mat?h.go", "match.go"},
-	{"*", "match.go"},
-	{"../*/match.go", "../filepath/match.go"},
-}
-
-func TestGlob(t *testing.T) {
-	for _, tt := range globTests {
-		pattern := tt.pattern
-		result := tt.result
-		if runtime.GOOS == "windows" {
-			pattern = Clean(pattern)
-			result = Clean(result)
-		}
-		matches, err := Glob(pattern)
-		if err != nil {
-			t.Errorf("Glob error for %q: %s", pattern, err)
-			continue
-		}
-		if !contains(matches, result) {
-			t.Errorf("Glob(%#q) = %#v want %v", pattern, matches, result)
-		}
-	}
-	for _, pattern := range []string{"no_match", "../*/no_match"} {
-		matches, err := Glob(pattern)
-		if err != nil {
-			t.Errorf("Glob error for %q: %s", pattern, err)
-			continue
-		}
-		if len(matches) != 0 {
-			t.Errorf("Glob(%#q) = %#v want []", pattern, matches)
-		}
-	}
-}
-
-func TestGlobError(t *testing.T) {
-	_, err := Glob("[7]")
-	if err != nil {
-		t.Error("expected error for bad pattern; got none")
-	}
-}
-
-var globSymlinkTests = []struct {
-	path, dest string
-	brokenLink bool
-}{
-	{"test1", "link1", false},
-	{"test2", "link2", true},
-}
-
-func TestGlobSymlink(t *testing.T) {
-	switch runtime.GOOS {
-	case "nacl", "plan9", "windows":
-		t.Skipf("skipping on %s", runtime.GOOS)
-	}
-
-	tmpDir, err := ioutil.TempDir("", "globsymlink")
-	if err != nil {
-		t.Fatal("creating temp dir:", err)
-	}
-	defer os.RemoveAll(tmpDir)
-
-	for _, tt := range globSymlinkTests {
-		path := Join(tmpDir, tt.path)
-		dest := Join(tmpDir, tt.dest)
-		f, err := os.Create(path)
-		if err != nil {
-			t.Fatal(err)
-		}
-		if err := f.Close(); err != nil {
-			t.Fatal(err)
-		}
-		err = os.Symlink(path, dest)
-		if err != nil {
-			t.Fatal(err)
-		}
-		if tt.brokenLink {
-			// Break the symlink.
-			os.Remove(path)
-		}
-		matches, err := Glob(dest)
-		if err != nil {
-			t.Errorf("GlobSymlink error for %q: %s", dest, err)
-		}
-		if !contains(matches, dest) {
-			t.Errorf("Glob(%#q) = %#v want %v", dest, matches, dest)
-		}
-	}
-}
diff --git a/src/pkg/path/filepath/path.go b/src/pkg/path/filepath/path.go
deleted file mode 100644
index 71603cc..0000000
--- a/src/pkg/path/filepath/path.go
+++ /dev/null
@@ -1,467 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package filepath implements utility routines for manipulating filename paths
-// in a way compatible with the target operating system-defined file paths.
-package filepath
-
-import (
-	"errors"
-	"os"
-	"sort"
-	"strings"
-)
-
-// A lazybuf is a lazily constructed path buffer.
-// It supports append, reading previously appended bytes,
-// and retrieving the final string. It does not allocate a buffer
-// to hold the output until that output diverges from s.
-type lazybuf struct {
-	path       string
-	buf        []byte
-	w          int
-	volAndPath string
-	volLen     int
-}
-
-func (b *lazybuf) index(i int) byte {
-	if b.buf != nil {
-		return b.buf[i]
-	}
-	return b.path[i]
-}
-
-func (b *lazybuf) append(c byte) {
-	if b.buf == nil {
-		if b.w < len(b.path) && b.path[b.w] == c {
-			b.w++
-			return
-		}
-		b.buf = make([]byte, len(b.path))
-		copy(b.buf, b.path[:b.w])
-	}
-	b.buf[b.w] = c
-	b.w++
-}
-
-func (b *lazybuf) string() string {
-	if b.buf == nil {
-		return b.volAndPath[:b.volLen+b.w]
-	}
-	return b.volAndPath[:b.volLen] + string(b.buf[:b.w])
-}
-
-const (
-	Separator     = os.PathSeparator
-	ListSeparator = os.PathListSeparator
-)
-
-// Clean returns the shortest path name equivalent to path
-// by purely lexical processing.  It applies the following rules
-// iteratively until no further processing can be done:
-//
-//	1. Replace multiple Separator elements with a single one.
-//	2. Eliminate each . path name element (the current directory).
-//	3. Eliminate each inner .. path name element (the parent directory)
-//	   along with the non-.. element that precedes it.
-//	4. Eliminate .. elements that begin a rooted path:
-//	   that is, replace "/.." by "/" at the beginning of a path,
-//	   assuming Separator is '/'.
-//
-// The returned path ends in a slash only if it represents a root directory,
-// such as "/" on Unix or `C:\` on Windows.
-//
-// If the result of this process is an empty string, Clean
-// returns the string ".".
-//
-// See also Rob Pike, ``Lexical File Names in Plan 9 or
-// Getting Dot-Dot Right,''
-// http://plan9.bell-labs.com/sys/doc/lexnames.html
-func Clean(path string) string {
-	originalPath := path
-	volLen := volumeNameLen(path)
-	path = path[volLen:]
-	if path == "" {
-		if volLen > 1 && originalPath[1] != ':' {
-			// should be UNC
-			return FromSlash(originalPath)
-		}
-		return originalPath + "."
-	}
-	rooted := os.IsPathSeparator(path[0])
-
-	// Invariants:
-	//	reading from path; r is index of next byte to process.
-	//	writing to buf; w is index of next byte to write.
-	//	dotdot is index in buf where .. must stop, either because
-	//		it is the leading slash or it is a leading ../../.. prefix.
-	n := len(path)
-	out := lazybuf{path: path, volAndPath: originalPath, volLen: volLen}
-	r, dotdot := 0, 0
-	if rooted {
-		out.append(Separator)
-		r, dotdot = 1, 1
-	}
-
-	for r < n {
-		switch {
-		case os.IsPathSeparator(path[r]):
-			// empty path element
-			r++
-		case path[r] == '.' && (r+1 == n || os.IsPathSeparator(path[r+1])):
-			// . element
-			r++
-		case path[r] == '.' && path[r+1] == '.' && (r+2 == n || os.IsPathSeparator(path[r+2])):
-			// .. element: remove to last separator
-			r += 2
-			switch {
-			case out.w > dotdot:
-				// can backtrack
-				out.w--
-				for out.w > dotdot && !os.IsPathSeparator(out.index(out.w)) {
-					out.w--
-				}
-			case !rooted:
-				// cannot backtrack, but not rooted, so append .. element.
-				if out.w > 0 {
-					out.append(Separator)
-				}
-				out.append('.')
-				out.append('.')
-				dotdot = out.w
-			}
-		default:
-			// real path element.
-			// add slash if needed
-			if rooted && out.w != 1 || !rooted && out.w != 0 {
-				out.append(Separator)
-			}
-			// copy element
-			for ; r < n && !os.IsPathSeparator(path[r]); r++ {
-				out.append(path[r])
-			}
-		}
-	}
-
-	// Turn empty string into "."
-	if out.w == 0 {
-		out.append('.')
-	}
-
-	return FromSlash(out.string())
-}
-
-// ToSlash returns the result of replacing each separator character
-// in path with a slash ('/') character. Multiple separators are
-// replaced by multiple slashes.
-func ToSlash(path string) string {
-	if Separator == '/' {
-		return path
-	}
-	return strings.Replace(path, string(Separator), "/", -1)
-}
-
-// FromSlash returns the result of replacing each slash ('/') character
-// in path with a separator character. Multiple slashes are replaced
-// by multiple separators.
-func FromSlash(path string) string {
-	if Separator == '/' {
-		return path
-	}
-	return strings.Replace(path, "/", string(Separator), -1)
-}
-
-// SplitList splits a list of paths joined by the OS-specific ListSeparator,
-// usually found in PATH or GOPATH environment variables.
-// Unlike strings.Split, SplitList returns an empty slice when passed an empty string.
-func SplitList(path string) []string {
-	return splitList(path)
-}
-
-// Split splits path immediately following the final Separator,
-// separating it into a directory and file name component.
-// If there is no Separator in path, Split returns an empty dir
-// and file set to path.
-// The returned values have the property that path = dir+file.
-func Split(path string) (dir, file string) {
-	vol := VolumeName(path)
-	i := len(path) - 1
-	for i >= len(vol) && !os.IsPathSeparator(path[i]) {
-		i--
-	}
-	return path[:i+1], path[i+1:]
-}
-
-// Join joins any number of path elements into a single path, adding
-// a Separator if necessary. The result is Cleaned, in particular
-// all empty strings are ignored.
-func Join(elem ...string) string {
-	for i, e := range elem {
-		if e != "" {
-			return Clean(strings.Join(elem[i:], string(Separator)))
-		}
-	}
-	return ""
-}
-
-// Ext returns the file name extension used by path.
-// The extension is the suffix beginning at the final dot
-// in the final element of path; it is empty if there is
-// no dot.
-func Ext(path string) string {
-	for i := len(path) - 1; i >= 0 && !os.IsPathSeparator(path[i]); i-- {
-		if path[i] == '.' {
-			return path[i:]
-		}
-	}
-	return ""
-}
-
-// EvalSymlinks returns the path name after the evaluation of any symbolic
-// links.
-// If path is relative the result will be relative to the current directory,
-// unless one of the components is an absolute symbolic link.
-func EvalSymlinks(path string) (string, error) {
-	return evalSymlinks(path)
-}
-
-// Abs returns an absolute representation of path.
-// If the path is not absolute it will be joined with the current
-// working directory to turn it into an absolute path.  The absolute
-// path name for a given file is not guaranteed to be unique.
-func Abs(path string) (string, error) {
-	if IsAbs(path) {
-		return Clean(path), nil
-	}
-	wd, err := os.Getwd()
-	if err != nil {
-		return "", err
-	}
-	return Join(wd, path), nil
-}
-
-// Rel returns a relative path that is lexically equivalent to targpath when
-// joined to basepath with an intervening separator. That is,
-// Join(basepath, Rel(basepath, targpath)) is equivalent to targpath itself.
-// On success, the returned path will always be relative to basepath,
-// even if basepath and targpath share no elements.
-// An error is returned if targpath can't be made relative to basepath or if
-// knowing the current working directory would be necessary to compute it.
-func Rel(basepath, targpath string) (string, error) {
-	baseVol := VolumeName(basepath)
-	targVol := VolumeName(targpath)
-	base := Clean(basepath)
-	targ := Clean(targpath)
-	if targ == base {
-		return ".", nil
-	}
-	base = base[len(baseVol):]
-	targ = targ[len(targVol):]
-	if base == "." {
-		base = ""
-	}
-	// Can't use IsAbs - `\a` and `a` are both relative in Windows.
-	baseSlashed := len(base) > 0 && base[0] == Separator
-	targSlashed := len(targ) > 0 && targ[0] == Separator
-	if baseSlashed != targSlashed || baseVol != targVol {
-		return "", errors.New("Rel: can't make " + targ + " relative to " + base)
-	}
-	// Position base[b0:bi] and targ[t0:ti] at the first differing elements.
-	bl := len(base)
-	tl := len(targ)
-	var b0, bi, t0, ti int
-	for {
-		for bi < bl && base[bi] != Separator {
-			bi++
-		}
-		for ti < tl && targ[ti] != Separator {
-			ti++
-		}
-		if targ[t0:ti] != base[b0:bi] {
-			break
-		}
-		if bi < bl {
-			bi++
-		}
-		if ti < tl {
-			ti++
-		}
-		b0 = bi
-		t0 = ti
-	}
-	if base[b0:bi] == ".." {
-		return "", errors.New("Rel: can't make " + targ + " relative to " + base)
-	}
-	if b0 != bl {
-		// Base elements left. Must go up before going down.
-		seps := strings.Count(base[b0:bl], string(Separator))
-		size := 2 + seps*3
-		if tl != t0 {
-			size += 1 + tl - t0
-		}
-		buf := make([]byte, size)
-		n := copy(buf, "..")
-		for i := 0; i < seps; i++ {
-			buf[n] = Separator
-			copy(buf[n+1:], "..")
-			n += 3
-		}
-		if t0 != tl {
-			buf[n] = Separator
-			copy(buf[n+1:], targ[t0:])
-		}
-		return string(buf), nil
-	}
-	return targ[t0:], nil
-}
-
-// SkipDir is used as a return value from WalkFuncs to indicate that
-// the directory named in the call is to be skipped. It is not returned
-// as an error by any function.
-var SkipDir = errors.New("skip this directory")
-
-// WalkFunc is the type of the function called for each file or directory
-// visited by Walk. The path argument contains the argument to Walk as a
-// prefix; that is, if Walk is called with "dir", which is a directory
-// containing the file "a", the walk function will be called with argument
-// "dir/a". The info argument is the os.FileInfo for the named path.
-//
-// If there was a problem walking to the file or directory named by path, the
-// incoming error will describe the problem and the function can decide how
-// to handle that error (and Walk will not descend into that directory). If
-// an error is returned, processing stops. The sole exception is that if path
-// is a directory and the function returns the special value SkipDir, the
-// contents of the directory are skipped and processing continues as usual on
-// the next file.
-type WalkFunc func(path string, info os.FileInfo, err error) error
-
-var lstat = os.Lstat // for testing
-
-// walk recursively descends path, calling w.
-func walk(path string, info os.FileInfo, walkFn WalkFunc) error {
-	err := walkFn(path, info, nil)
-	if err != nil {
-		if info.IsDir() && err == SkipDir {
-			return nil
-		}
-		return err
-	}
-
-	if !info.IsDir() {
-		return nil
-	}
-
-	names, err := readDirNames(path)
-	if err != nil {
-		return walkFn(path, info, err)
-	}
-
-	for _, name := range names {
-		filename := Join(path, name)
-		fileInfo, err := lstat(filename)
-		if err != nil {
-			if err := walkFn(filename, fileInfo, err); err != nil && err != SkipDir {
-				return err
-			}
-		} else {
-			err = walk(filename, fileInfo, walkFn)
-			if err != nil {
-				if !fileInfo.IsDir() || err != SkipDir {
-					return err
-				}
-			}
-		}
-	}
-	return nil
-}
-
-// Walk walks the file tree rooted at root, calling walkFn for each file or
-// directory in the tree, including root. All errors that arise visiting files
-// and directories are filtered by walkFn. The files are walked in lexical
-// order, which makes the output deterministic but means that for very
-// large directories Walk can be inefficient.
-// Walk does not follow symbolic links.
-func Walk(root string, walkFn WalkFunc) error {
-	info, err := os.Lstat(root)
-	if err != nil {
-		return walkFn(root, nil, err)
-	}
-	return walk(root, info, walkFn)
-}
-
-// readDirNames reads the directory named by dirname and returns
-// a sorted list of directory entries.
-func readDirNames(dirname string) ([]string, error) {
-	f, err := os.Open(dirname)
-	if err != nil {
-		return nil, err
-	}
-	names, err := f.Readdirnames(-1)
-	f.Close()
-	if err != nil {
-		return nil, err
-	}
-	sort.Strings(names)
-	return names, nil
-}
-
-// Base returns the last element of path.
-// Trailing path separators are removed before extracting the last element.
-// If the path is empty, Base returns ".".
-// If the path consists entirely of separators, Base returns a single separator.
-func Base(path string) string {
-	if path == "" {
-		return "."
-	}
-	// Strip trailing slashes.
-	for len(path) > 0 && os.IsPathSeparator(path[len(path)-1]) {
-		path = path[0 : len(path)-1]
-	}
-	// Throw away volume name
-	path = path[len(VolumeName(path)):]
-	// Find the last element
-	i := len(path) - 1
-	for i >= 0 && !os.IsPathSeparator(path[i]) {
-		i--
-	}
-	if i >= 0 {
-		path = path[i+1:]
-	}
-	// If empty now, it had only slashes.
-	if path == "" {
-		return string(Separator)
-	}
-	return path
-}
-
-// Dir returns all but the last element of path, typically the path's directory.
-// After dropping the final element, the path is Cleaned and trailing
-// slashes are removed.
-// If the path is empty, Dir returns ".".
-// If the path consists entirely of separators, Dir returns a single separator.
-// The returned path does not end in a separator unless it is the root directory.
-func Dir(path string) string {
-	vol := VolumeName(path)
-	i := len(path) - 1
-	for i >= len(vol) && !os.IsPathSeparator(path[i]) {
-		i--
-	}
-	dir := Clean(path[len(vol) : i+1])
-	last := len(dir) - 1
-	if last > 0 && os.IsPathSeparator(dir[last]) {
-		dir = dir[:last]
-	}
-	if dir == "" {
-		dir = "."
-	}
-	return vol + dir
-}
-
-// VolumeName returns leading volume name.
-// Given "C:\foo\bar" it returns "C:" under windows.
-// Given "\\host\share\foo" it returns "\\host\share".
-// On other platforms it returns "".
-func VolumeName(path string) (v string) {
-	return path[:volumeNameLen(path)]
-}
diff --git a/src/pkg/path/filepath/path_plan9.go b/src/pkg/path/filepath/path_plan9.go
deleted file mode 100644
index 12e85aa..0000000
--- a/src/pkg/path/filepath/path_plan9.go
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package filepath
-
-import "strings"
-
-// IsAbs returns true if the path is absolute.
-func IsAbs(path string) bool {
-	return strings.HasPrefix(path, "/") || strings.HasPrefix(path, "#")
-}
-
-// volumeNameLen returns length of the leading volume name on Windows.
-// It returns 0 elsewhere.
-func volumeNameLen(path string) int {
-	return 0
-}
-
-// HasPrefix exists for historical compatibility and should not be used.
-func HasPrefix(p, prefix string) bool {
-	return strings.HasPrefix(p, prefix)
-}
-
-func splitList(path string) []string {
-	if path == "" {
-		return []string{}
-	}
-	return strings.Split(path, string(ListSeparator))
-}
diff --git a/src/pkg/path/filepath/path_test.go b/src/pkg/path/filepath/path_test.go
deleted file mode 100644
index 819bd21..0000000
--- a/src/pkg/path/filepath/path_test.go
+++ /dev/null
@@ -1,1017 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package filepath_test
-
-import (
-	"errors"
-	"io/ioutil"
-	"os"
-	"path/filepath"
-	"reflect"
-	"runtime"
-	"strings"
-	"testing"
-)
-
-type PathTest struct {
-	path, result string
-}
-
-var cleantests = []PathTest{
-	// Already clean
-	{"abc", "abc"},
-	{"abc/def", "abc/def"},
-	{"a/b/c", "a/b/c"},
-	{".", "."},
-	{"..", ".."},
-	{"../..", "../.."},
-	{"../../abc", "../../abc"},
-	{"/abc", "/abc"},
-	{"/", "/"},
-
-	// Empty is current dir
-	{"", "."},
-
-	// Remove trailing slash
-	{"abc/", "abc"},
-	{"abc/def/", "abc/def"},
-	{"a/b/c/", "a/b/c"},
-	{"./", "."},
-	{"../", ".."},
-	{"../../", "../.."},
-	{"/abc/", "/abc"},
-
-	// Remove doubled slash
-	{"abc//def//ghi", "abc/def/ghi"},
-	{"//abc", "/abc"},
-	{"///abc", "/abc"},
-	{"//abc//", "/abc"},
-	{"abc//", "abc"},
-
-	// Remove . elements
-	{"abc/./def", "abc/def"},
-	{"/./abc/def", "/abc/def"},
-	{"abc/.", "abc"},
-
-	// Remove .. elements
-	{"abc/def/ghi/../jkl", "abc/def/jkl"},
-	{"abc/def/../ghi/../jkl", "abc/jkl"},
-	{"abc/def/..", "abc"},
-	{"abc/def/../..", "."},
-	{"/abc/def/../..", "/"},
-	{"abc/def/../../..", ".."},
-	{"/abc/def/../../..", "/"},
-	{"abc/def/../../../ghi/jkl/../../../mno", "../../mno"},
-	{"/../abc", "/abc"},
-
-	// Combinations
-	{"abc/./../def", "def"},
-	{"abc//./../def", "def"},
-	{"abc/../../././../def", "../../def"},
-}
-
-var wincleantests = []PathTest{
-	{`c:`, `c:.`},
-	{`c:\`, `c:\`},
-	{`c:\abc`, `c:\abc`},
-	{`c:abc\..\..\.\.\..\def`, `c:..\..\def`},
-	{`c:\abc\def\..\..`, `c:\`},
-	{`c:\..\abc`, `c:\abc`},
-	{`c:..\abc`, `c:..\abc`},
-	{`\`, `\`},
-	{`/`, `\`},
-	{`\\i\..\c$`, `\c$`},
-	{`\\i\..\i\c$`, `\i\c$`},
-	{`\\i\..\I\c$`, `\I\c$`},
-	{`\\host\share\foo\..\bar`, `\\host\share\bar`},
-	{`//host/share/foo/../baz`, `\\host\share\baz`},
-	{`\\a\b\..\c`, `\\a\b\c`},
-	{`\\a\b`, `\\a\b`},
-}
-
-func TestClean(t *testing.T) {
-	tests := cleantests
-	if runtime.GOOS == "windows" {
-		for i := range tests {
-			tests[i].result = filepath.FromSlash(tests[i].result)
-		}
-		tests = append(tests, wincleantests...)
-	}
-	for _, test := range tests {
-		if s := filepath.Clean(test.path); s != test.result {
-			t.Errorf("Clean(%q) = %q, want %q", test.path, s, test.result)
-		}
-		if s := filepath.Clean(test.result); s != test.result {
-			t.Errorf("Clean(%q) = %q, want %q", test.result, s, test.result)
-		}
-	}
-
-	if testing.Short() {
-		t.Skip("skipping malloc count in short mode")
-	}
-	if runtime.GOMAXPROCS(0) > 1 {
-		t.Log("skipping AllocsPerRun checks; GOMAXPROCS>1")
-		return
-	}
-
-	for _, test := range tests {
-		allocs := testing.AllocsPerRun(100, func() { filepath.Clean(test.result) })
-		if allocs > 0 {
-			t.Errorf("Clean(%q): %v allocs, want zero", test.result, allocs)
-		}
-	}
-}
-
-const sep = filepath.Separator
-
-var slashtests = []PathTest{
-	{"", ""},
-	{"/", string(sep)},
-	{"/a/b", string([]byte{sep, 'a', sep, 'b'})},
-	{"a//b", string([]byte{'a', sep, sep, 'b'})},
-}
-
-func TestFromAndToSlash(t *testing.T) {
-	for _, test := range slashtests {
-		if s := filepath.FromSlash(test.path); s != test.result {
-			t.Errorf("FromSlash(%q) = %q, want %q", test.path, s, test.result)
-		}
-		if s := filepath.ToSlash(test.result); s != test.path {
-			t.Errorf("ToSlash(%q) = %q, want %q", test.result, s, test.path)
-		}
-	}
-}
-
-type SplitListTest struct {
-	list   string
-	result []string
-}
-
-const lsep = filepath.ListSeparator
-
-var splitlisttests = []SplitListTest{
-	{"", []string{}},
-	{string([]byte{'a', lsep, 'b'}), []string{"a", "b"}},
-	{string([]byte{lsep, 'a', lsep, 'b'}), []string{"", "a", "b"}},
-}
-
-var winsplitlisttests = []SplitListTest{
-	// quoted
-	{`"a"`, []string{`a`}},
-
-	// semicolon
-	{`";"`, []string{`;`}},
-	{`"a;b"`, []string{`a;b`}},
-	{`";";`, []string{`;`, ``}},
-	{`;";"`, []string{``, `;`}},
-
-	// partially quoted
-	{`a";"b`, []string{`a;b`}},
-	{`a; ""b`, []string{`a`, ` b`}},
-	{`"a;b`, []string{`a;b`}},
-	{`""a;b`, []string{`a`, `b`}},
-	{`"""a;b`, []string{`a;b`}},
-	{`""""a;b`, []string{`a`, `b`}},
-	{`a";b`, []string{`a;b`}},
-	{`a;b";c`, []string{`a`, `b;c`}},
-	{`"a";b";c`, []string{`a`, `b;c`}},
-}
-
-func TestSplitList(t *testing.T) {
-	tests := splitlisttests
-	if runtime.GOOS == "windows" {
-		tests = append(tests, winsplitlisttests...)
-	}
-	for _, test := range tests {
-		if l := filepath.SplitList(test.list); !reflect.DeepEqual(l, test.result) {
-			t.Errorf("SplitList(%#q) = %#q, want %#q", test.list, l, test.result)
-		}
-	}
-}
-
-type SplitTest struct {
-	path, dir, file string
-}
-
-var unixsplittests = []SplitTest{
-	{"a/b", "a/", "b"},
-	{"a/b/", "a/b/", ""},
-	{"a/", "a/", ""},
-	{"a", "", "a"},
-	{"/", "/", ""},
-}
-
-var winsplittests = []SplitTest{
-	{`c:`, `c:`, ``},
-	{`c:/`, `c:/`, ``},
-	{`c:/foo`, `c:/`, `foo`},
-	{`c:/foo/bar`, `c:/foo/`, `bar`},
-	{`//host/share`, `//host/share`, ``},
-	{`//host/share/`, `//host/share/`, ``},
-	{`//host/share/foo`, `//host/share/`, `foo`},
-	{`\\host\share`, `\\host\share`, ``},
-	{`\\host\share\`, `\\host\share\`, ``},
-	{`\\host\share\foo`, `\\host\share\`, `foo`},
-}
-
-func TestSplit(t *testing.T) {
-	var splittests []SplitTest
-	splittests = unixsplittests
-	if runtime.GOOS == "windows" {
-		splittests = append(splittests, winsplittests...)
-	}
-	for _, test := range splittests {
-		if d, f := filepath.Split(test.path); d != test.dir || f != test.file {
-			t.Errorf("Split(%q) = %q, %q, want %q, %q", test.path, d, f, test.dir, test.file)
-		}
-	}
-}
-
-type JoinTest struct {
-	elem []string
-	path string
-}
-
-var jointests = []JoinTest{
-	// zero parameters
-	{[]string{}, ""},
-
-	// one parameter
-	{[]string{""}, ""},
-	{[]string{"a"}, "a"},
-
-	// two parameters
-	{[]string{"a", "b"}, "a/b"},
-	{[]string{"a", ""}, "a"},
-	{[]string{"", "b"}, "b"},
-	{[]string{"/", "a"}, "/a"},
-	{[]string{"/", ""}, "/"},
-	{[]string{"a/", "b"}, "a/b"},
-	{[]string{"a/", ""}, "a"},
-	{[]string{"", ""}, ""},
-}
-
-var winjointests = []JoinTest{
-	{[]string{`directory`, `file`}, `directory\file`},
-	{[]string{`C:\Windows\`, `System32`}, `C:\Windows\System32`},
-	{[]string{`C:\Windows\`, ``}, `C:\Windows`},
-	{[]string{`C:\`, `Windows`}, `C:\Windows`},
-	{[]string{`C:`, `Windows`}, `C:\Windows`},
-	{[]string{`\\host\share`, `foo`}, `\\host\share\foo`},
-	{[]string{`//host/share`, `foo/bar`}, `\\host\share\foo\bar`},
-}
-
-// join takes a []string and passes it to Join.
-func join(elem []string, args ...string) string {
-	args = elem
-	return filepath.Join(args...)
-}
-
-func TestJoin(t *testing.T) {
-	if runtime.GOOS == "windows" {
-		jointests = append(jointests, winjointests...)
-	}
-	for _, test := range jointests {
-		if p := join(test.elem); p != filepath.FromSlash(test.path) {
-			t.Errorf("join(%q) = %q, want %q", test.elem, p, test.path)
-		}
-	}
-}
-
-type ExtTest struct {
-	path, ext string
-}
-
-var exttests = []ExtTest{
-	{"path.go", ".go"},
-	{"path.pb.go", ".go"},
-	{"a.dir/b", ""},
-	{"a.dir/b.go", ".go"},
-	{"a.dir/", ""},
-}
-
-func TestExt(t *testing.T) {
-	for _, test := range exttests {
-		if x := filepath.Ext(test.path); x != test.ext {
-			t.Errorf("Ext(%q) = %q, want %q", test.path, x, test.ext)
-		}
-	}
-}
-
-type Node struct {
-	name    string
-	entries []*Node // nil if the entry is a file
-	mark    int
-}
-
-var tree = &Node{
-	"testdata",
-	[]*Node{
-		{"a", nil, 0},
-		{"b", []*Node{}, 0},
-		{"c", nil, 0},
-		{
-			"d",
-			[]*Node{
-				{"x", nil, 0},
-				{"y", []*Node{}, 0},
-				{
-					"z",
-					[]*Node{
-						{"u", nil, 0},
-						{"v", nil, 0},
-					},
-					0,
-				},
-			},
-			0,
-		},
-	},
-	0,
-}
-
-func walkTree(n *Node, path string, f func(path string, n *Node)) {
-	f(path, n)
-	for _, e := range n.entries {
-		walkTree(e, filepath.Join(path, e.name), f)
-	}
-}
-
-func makeTree(t *testing.T) {
-	walkTree(tree, tree.name, func(path string, n *Node) {
-		if n.entries == nil {
-			fd, err := os.Create(path)
-			if err != nil {
-				t.Errorf("makeTree: %v", err)
-				return
-			}
-			fd.Close()
-		} else {
-			os.Mkdir(path, 0770)
-		}
-	})
-}
-
-func markTree(n *Node) { walkTree(n, "", func(path string, n *Node) { n.mark++ }) }
-
-func checkMarks(t *testing.T, report bool) {
-	walkTree(tree, tree.name, func(path string, n *Node) {
-		if n.mark != 1 && report {
-			t.Errorf("node %s mark = %d; expected 1", path, n.mark)
-		}
-		n.mark = 0
-	})
-}
-
-// Assumes that each node name is unique. Good enough for a test.
-// If clear is true, any incoming error is cleared before return. The errors
-// are always accumulated, though.
-func mark(path string, info os.FileInfo, err error, errors *[]error, clear bool) error {
-	if err != nil {
-		*errors = append(*errors, err)
-		if clear {
-			return nil
-		}
-		return err
-	}
-	name := info.Name()
-	walkTree(tree, tree.name, func(path string, n *Node) {
-		if n.name == name {
-			n.mark++
-		}
-	})
-	return nil
-}
-
-func TestWalk(t *testing.T) {
-	makeTree(t)
-	errors := make([]error, 0, 10)
-	clear := true
-	markFn := func(path string, info os.FileInfo, err error) error {
-		return mark(path, info, err, &errors, clear)
-	}
-	// Expect no errors.
-	err := filepath.Walk(tree.name, markFn)
-	if err != nil {
-		t.Fatalf("no error expected, found: %s", err)
-	}
-	if len(errors) != 0 {
-		t.Fatalf("unexpected errors: %s", errors)
-	}
-	checkMarks(t, true)
-	errors = errors[0:0]
-
-	// Test permission errors.  Only possible if we're not root
-	// and only on some file systems (AFS, FAT).  To avoid errors during
-	// all.bash on those file systems, skip during go test -short.
-	if os.Getuid() > 0 && !testing.Short() {
-		// introduce 2 errors: chmod top-level directories to 0
-		os.Chmod(filepath.Join(tree.name, tree.entries[1].name), 0)
-		os.Chmod(filepath.Join(tree.name, tree.entries[3].name), 0)
-
-		// 3) capture errors, expect two.
-		// mark respective subtrees manually
-		markTree(tree.entries[1])
-		markTree(tree.entries[3])
-		// correct double-marking of directory itself
-		tree.entries[1].mark--
-		tree.entries[3].mark--
-		err := filepath.Walk(tree.name, markFn)
-		if err != nil {
-			t.Fatalf("expected no error return from Walk, got %s", err)
-		}
-		if len(errors) != 2 {
-			t.Errorf("expected 2 errors, got %d: %s", len(errors), errors)
-		}
-		// the inaccessible subtrees were marked manually
-		checkMarks(t, true)
-		errors = errors[0:0]
-
-		// 4) capture errors, stop after first error.
-		// mark respective subtrees manually
-		markTree(tree.entries[1])
-		markTree(tree.entries[3])
-		// correct double-marking of directory itself
-		tree.entries[1].mark--
-		tree.entries[3].mark--
-		clear = false // error will stop processing
-		err = filepath.Walk(tree.name, markFn)
-		if err == nil {
-			t.Fatalf("expected error return from Walk")
-		}
-		if len(errors) != 1 {
-			t.Errorf("expected 1 error, got %d: %s", len(errors), errors)
-		}
-		// the inaccessible subtrees were marked manually
-		checkMarks(t, false)
-		errors = errors[0:0]
-
-		// restore permissions
-		os.Chmod(filepath.Join(tree.name, tree.entries[1].name), 0770)
-		os.Chmod(filepath.Join(tree.name, tree.entries[3].name), 0770)
-	}
-
-	// cleanup
-	if err := os.RemoveAll(tree.name); err != nil {
-		t.Errorf("removeTree: %v", err)
-	}
-}
-
-func touch(t *testing.T, name string) {
-	f, err := os.Create(name)
-	if err != nil {
-		t.Fatal(err)
-	}
-	if err := f.Close(); err != nil {
-		t.Fatal(err)
-	}
-}
-
-func TestWalkFileError(t *testing.T) {
-	td, err := ioutil.TempDir("", "walktest")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(td)
-
-	touch(t, filepath.Join(td, "foo"))
-	touch(t, filepath.Join(td, "bar"))
-	dir := filepath.Join(td, "dir")
-	if err := os.MkdirAll(filepath.Join(td, "dir"), 0755); err != nil {
-		t.Fatal(err)
-	}
-	touch(t, filepath.Join(dir, "baz"))
-	touch(t, filepath.Join(dir, "stat-error"))
-	defer func() {
-		*filepath.LstatP = os.Lstat
-	}()
-	statErr := errors.New("some stat error")
-	*filepath.LstatP = func(path string) (os.FileInfo, error) {
-		if strings.HasSuffix(path, "stat-error") {
-			return nil, statErr
-		}
-		return os.Lstat(path)
-	}
-	got := map[string]error{}
-	err = filepath.Walk(td, func(path string, fi os.FileInfo, err error) error {
-		rel, _ := filepath.Rel(td, path)
-		got[filepath.ToSlash(rel)] = err
-		return nil
-	})
-	if err != nil {
-		t.Errorf("Walk error: %v", err)
-	}
-	want := map[string]error{
-		".":              nil,
-		"foo":            nil,
-		"bar":            nil,
-		"dir":            nil,
-		"dir/baz":        nil,
-		"dir/stat-error": statErr,
-	}
-	if !reflect.DeepEqual(got, want) {
-		t.Errorf("Walked %#v; want %#v", got, want)
-	}
-}
-
-var basetests = []PathTest{
-	{"", "."},
-	{".", "."},
-	{"/.", "."},
-	{"/", "/"},
-	{"////", "/"},
-	{"x/", "x"},
-	{"abc", "abc"},
-	{"abc/def", "def"},
-	{"a/b/.x", ".x"},
-	{"a/b/c.", "c."},
-	{"a/b/c.x", "c.x"},
-}
-
-var winbasetests = []PathTest{
-	{`c:\`, `\`},
-	{`c:.`, `.`},
-	{`c:\a\b`, `b`},
-	{`c:a\b`, `b`},
-	{`c:a\b\c`, `c`},
-	{`\\host\share\`, `\`},
-	{`\\host\share\a`, `a`},
-	{`\\host\share\a\b`, `b`},
-}
-
-func TestBase(t *testing.T) {
-	tests := basetests
-	if runtime.GOOS == "windows" {
-		// make unix tests work on windows
-		for i := range tests {
-			tests[i].result = filepath.Clean(tests[i].result)
-		}
-		// add windows specific tests
-		tests = append(tests, winbasetests...)
-	}
-	for _, test := range tests {
-		if s := filepath.Base(test.path); s != test.result {
-			t.Errorf("Base(%q) = %q, want %q", test.path, s, test.result)
-		}
-	}
-}
-
-var dirtests = []PathTest{
-	{"", "."},
-	{".", "."},
-	{"/.", "/"},
-	{"/", "/"},
-	{"////", "/"},
-	{"/foo", "/"},
-	{"x/", "x"},
-	{"abc", "."},
-	{"abc/def", "abc"},
-	{"a/b/.x", "a/b"},
-	{"a/b/c.", "a/b"},
-	{"a/b/c.x", "a/b"},
-}
-
-var windirtests = []PathTest{
-	{`c:\`, `c:\`},
-	{`c:.`, `c:.`},
-	{`c:\a\b`, `c:\a`},
-	{`c:a\b`, `c:a`},
-	{`c:a\b\c`, `c:a\b`},
-	{`\\host\share\`, `\\host\share\`},
-	{`\\host\share\a`, `\\host\share\`},
-	{`\\host\share\a\b`, `\\host\share\a`},
-}
-
-func TestDir(t *testing.T) {
-	tests := dirtests
-	if runtime.GOOS == "windows" {
-		// make unix tests work on windows
-		for i := range tests {
-			tests[i].result = filepath.Clean(tests[i].result)
-		}
-		// add windows specific tests
-		tests = append(tests, windirtests...)
-	}
-	for _, test := range tests {
-		if s := filepath.Dir(test.path); s != test.result {
-			t.Errorf("Dir(%q) = %q, want %q", test.path, s, test.result)
-		}
-	}
-}
-
-type IsAbsTest struct {
-	path  string
-	isAbs bool
-}
-
-var isabstests = []IsAbsTest{
-	{"", false},
-	{"/", true},
-	{"/usr/bin/gcc", true},
-	{"..", false},
-	{"/a/../bb", true},
-	{".", false},
-	{"./", false},
-	{"lala", false},
-}
-
-var winisabstests = []IsAbsTest{
-	{`C:\`, true},
-	{`c\`, false},
-	{`c::`, false},
-	{`c:`, false},
-	{`/`, false},
-	{`\`, false},
-	{`\Windows`, false},
-	{`c:a\b`, false},
-	{`\\host\share\foo`, true},
-	{`//host/share/foo/bar`, true},
-}
-
-func TestIsAbs(t *testing.T) {
-	var tests []IsAbsTest
-	if runtime.GOOS == "windows" {
-		tests = append(tests, winisabstests...)
-		// All non-windows tests should fail, because they have no volume letter.
-		for _, test := range isabstests {
-			tests = append(tests, IsAbsTest{test.path, false})
-		}
-		// All non-windows test should work as intended if prefixed with volume letter.
-		for _, test := range isabstests {
-			tests = append(tests, IsAbsTest{"c:" + test.path, test.isAbs})
-		}
-	} else {
-		tests = isabstests
-	}
-
-	for _, test := range tests {
-		if r := filepath.IsAbs(test.path); r != test.isAbs {
-			t.Errorf("IsAbs(%q) = %v, want %v", test.path, r, test.isAbs)
-		}
-	}
-}
-
-type EvalSymlinksTest struct {
-	// If dest is empty, the path is created; otherwise the dest is symlinked to the path.
-	path, dest string
-}
-
-var EvalSymlinksTestDirs = []EvalSymlinksTest{
-	{"test", ""},
-	{"test/dir", ""},
-	{"test/dir/link3", "../../"},
-	{"test/link1", "../test"},
-	{"test/link2", "dir"},
-	{"test/linkabs", "/"},
-}
-
-var EvalSymlinksTests = []EvalSymlinksTest{
-	{"test", "test"},
-	{"test/dir", "test/dir"},
-	{"test/dir/../..", "."},
-	{"test/link1", "test"},
-	{"test/link2", "test/dir"},
-	{"test/link1/dir", "test/dir"},
-	{"test/link2/..", "test"},
-	{"test/dir/link3", "."},
-	{"test/link2/link3/test", "test"},
-	{"test/linkabs", "/"},
-}
-
-var EvalSymlinksAbsWindowsTests = []EvalSymlinksTest{
-	{`c:\`, `c:\`},
-}
-
-// simpleJoin builds a file name from the directory and path.
-// It does not use Join because we don't want ".." to be evaluated.
-func simpleJoin(dir, path string) string {
-	return dir + string(filepath.Separator) + path
-}
-
-func TestEvalSymlinks(t *testing.T) {
-	switch runtime.GOOS {
-	case "nacl", "plan9":
-		t.Skipf("skipping on %s", runtime.GOOS)
-	}
-
-	tmpDir, err := ioutil.TempDir("", "evalsymlink")
-	if err != nil {
-		t.Fatal("creating temp dir:", err)
-	}
-	defer os.RemoveAll(tmpDir)
-
-	// /tmp may itself be a symlink! Avoid the confusion, although
-	// it means trusting the thing we're testing.
-	tmpDir, err = filepath.EvalSymlinks(tmpDir)
-	if err != nil {
-		t.Fatal("eval symlink for tmp dir:", err)
-	}
-
-	// Create the symlink farm using relative paths.
-	for _, d := range EvalSymlinksTestDirs {
-		var err error
-		path := simpleJoin(tmpDir, d.path)
-		if d.dest == "" {
-			err = os.Mkdir(path, 0755)
-		} else {
-			if runtime.GOOS != "windows" {
-				err = os.Symlink(d.dest, path)
-			}
-		}
-		if err != nil {
-			t.Fatal(err)
-		}
-	}
-
-	var tests []EvalSymlinksTest
-	if runtime.GOOS == "windows" {
-		for _, d := range EvalSymlinksTests {
-			if d.path == d.dest {
-				// will test only real files and directories
-				tests = append(tests, d)
-				// test "canonical" names
-				d2 := EvalSymlinksTest{
-					path: strings.ToUpper(d.path),
-					dest: d.dest,
-				}
-				tests = append(tests, d2)
-			}
-		}
-	} else {
-		tests = EvalSymlinksTests
-	}
-
-	// Evaluate the symlink farm.
-	for _, d := range tests {
-		path := simpleJoin(tmpDir, d.path)
-		dest := simpleJoin(tmpDir, d.dest)
-		if filepath.IsAbs(d.dest) {
-			dest = d.dest
-		}
-		if p, err := filepath.EvalSymlinks(path); err != nil {
-			t.Errorf("EvalSymlinks(%q) error: %v", d.path, err)
-		} else if filepath.Clean(p) != filepath.Clean(dest) {
-			t.Errorf("Clean(%q)=%q, want %q", path, p, dest)
-		}
-	}
-}
-
-// Test directories relative to temporary directory.
-// The tests are run in absTestDirs[0].
-var absTestDirs = []string{
-	"a",
-	"a/b",
-	"a/b/c",
-}
-
-// Test paths relative to temporary directory. $ expands to the directory.
-// The tests are run in absTestDirs[0].
-// We create absTestDirs first.
-var absTests = []string{
-	".",
-	"b",
-	"../a",
-	"../a/b",
-	"../a/b/./c/../../.././a",
-	"$",
-	"$/.",
-	"$/a/../a/b",
-	"$/a/b/c/../../.././a",
-}
-
-func TestAbs(t *testing.T) {
-	oldwd, err := os.Getwd()
-	if err != nil {
-		t.Fatal("Getwd failed: ", err)
-	}
-	defer os.Chdir(oldwd)
-
-	root, err := ioutil.TempDir("", "TestAbs")
-	if err != nil {
-		t.Fatal("TempDir failed: ", err)
-	}
-	defer os.RemoveAll(root)
-
-	wd, err := os.Getwd()
-	if err != nil {
-		t.Fatal("getwd failed: ", err)
-	}
-	err = os.Chdir(root)
-	if err != nil {
-		t.Fatal("chdir failed: ", err)
-	}
-	defer os.Chdir(wd)
-
-	for _, dir := range absTestDirs {
-		err = os.Mkdir(dir, 0777)
-		if err != nil {
-			t.Fatal("Mkdir failed: ", err)
-		}
-	}
-
-	err = os.Chdir(absTestDirs[0])
-	if err != nil {
-		t.Fatal("chdir failed: ", err)
-	}
-
-	for _, path := range absTests {
-		path = strings.Replace(path, "$", root, -1)
-		info, err := os.Stat(path)
-		if err != nil {
-			t.Errorf("%s: %s", path, err)
-			continue
-		}
-
-		abspath, err := filepath.Abs(path)
-		if err != nil {
-			t.Errorf("Abs(%q) error: %v", path, err)
-			continue
-		}
-		absinfo, err := os.Stat(abspath)
-		if err != nil || !os.SameFile(absinfo, info) {
-			t.Errorf("Abs(%q)=%q, not the same file", path, abspath)
-		}
-		if !filepath.IsAbs(abspath) {
-			t.Errorf("Abs(%q)=%q, not an absolute path", path, abspath)
-		}
-		if filepath.IsAbs(path) && abspath != filepath.Clean(path) {
-			t.Errorf("Abs(%q)=%q, isn't clean", path, abspath)
-		}
-	}
-}
-
-type RelTests struct {
-	root, path, want string
-}
-
-var reltests = []RelTests{
-	{"a/b", "a/b", "."},
-	{"a/b/.", "a/b", "."},
-	{"a/b", "a/b/.", "."},
-	{"./a/b", "a/b", "."},
-	{"a/b", "./a/b", "."},
-	{"ab/cd", "ab/cde", "../cde"},
-	{"ab/cd", "ab/c", "../c"},
-	{"a/b", "a/b/c/d", "c/d"},
-	{"a/b", "a/b/../c", "../c"},
-	{"a/b/../c", "a/b", "../b"},
-	{"a/b/c", "a/c/d", "../../c/d"},
-	{"a/b", "c/d", "../../c/d"},
-	{"a/b/c/d", "a/b", "../.."},
-	{"a/b/c/d", "a/b/", "../.."},
-	{"a/b/c/d/", "a/b", "../.."},
-	{"a/b/c/d/", "a/b/", "../.."},
-	{"../../a/b", "../../a/b/c/d", "c/d"},
-	{"/a/b", "/a/b", "."},
-	{"/a/b/.", "/a/b", "."},
-	{"/a/b", "/a/b/.", "."},
-	{"/ab/cd", "/ab/cde", "../cde"},
-	{"/ab/cd", "/ab/c", "../c"},
-	{"/a/b", "/a/b/c/d", "c/d"},
-	{"/a/b", "/a/b/../c", "../c"},
-	{"/a/b/../c", "/a/b", "../b"},
-	{"/a/b/c", "/a/c/d", "../../c/d"},
-	{"/a/b", "/c/d", "../../c/d"},
-	{"/a/b/c/d", "/a/b", "../.."},
-	{"/a/b/c/d", "/a/b/", "../.."},
-	{"/a/b/c/d/", "/a/b", "../.."},
-	{"/a/b/c/d/", "/a/b/", "../.."},
-	{"/../../a/b", "/../../a/b/c/d", "c/d"},
-	{".", "a/b", "a/b"},
-	{".", "..", ".."},
-
-	// can't do purely lexically
-	{"..", ".", "err"},
-	{"..", "a", "err"},
-	{"../..", "..", "err"},
-	{"a", "/a", "err"},
-	{"/a", "a", "err"},
-}
-
-var winreltests = []RelTests{
-	{`C:a\b\c`, `C:a/b/d`, `..\d`},
-	{`C:\`, `D:\`, `err`},
-	{`C:`, `D:`, `err`},
-}
-
-func TestRel(t *testing.T) {
-	tests := append([]RelTests{}, reltests...)
-	if runtime.GOOS == "windows" {
-		for i := range tests {
-			tests[i].want = filepath.FromSlash(tests[i].want)
-		}
-		tests = append(tests, winreltests...)
-	}
-	for _, test := range tests {
-		got, err := filepath.Rel(test.root, test.path)
-		if test.want == "err" {
-			if err == nil {
-				t.Errorf("Rel(%q, %q)=%q, want error", test.root, test.path, got)
-			}
-			continue
-		}
-		if err != nil {
-			t.Errorf("Rel(%q, %q): want %q, got error: %s", test.root, test.path, test.want, err)
-		}
-		if got != test.want {
-			t.Errorf("Rel(%q, %q)=%q, want %q", test.root, test.path, got, test.want)
-		}
-	}
-}
-
-type VolumeNameTest struct {
-	path string
-	vol  string
-}
-
-var volumenametests = []VolumeNameTest{
-	{`c:/foo/bar`, `c:`},
-	{`c:`, `c:`},
-	{`2:`, ``},
-	{``, ``},
-	{`\\\host`, ``},
-	{`\\\host\`, ``},
-	{`\\\host\share`, ``},
-	{`\\\host\\share`, ``},
-	{`\\host`, ``},
-	{`//host`, ``},
-	{`\\host\`, ``},
-	{`//host/`, ``},
-	{`\\host\share`, `\\host\share`},
-	{`//host/share`, `//host/share`},
-	{`\\host\share\`, `\\host\share`},
-	{`//host/share/`, `//host/share`},
-	{`\\host\share\foo`, `\\host\share`},
-	{`//host/share/foo`, `//host/share`},
-	{`\\host\share\\foo\\\bar\\\\baz`, `\\host\share`},
-	{`//host/share//foo///bar////baz`, `//host/share`},
-	{`\\host\share\foo\..\bar`, `\\host\share`},
-	{`//host/share/foo/../bar`, `//host/share`},
-}
-
-func TestVolumeName(t *testing.T) {
-	if runtime.GOOS != "windows" {
-		return
-	}
-	for _, v := range volumenametests {
-		if vol := filepath.VolumeName(v.path); vol != v.vol {
-			t.Errorf("VolumeName(%q)=%q, want %q", v.path, vol, v.vol)
-		}
-	}
-}
-
-func TestDriveLetterInEvalSymlinks(t *testing.T) {
-	if runtime.GOOS != "windows" {
-		return
-	}
-	wd, _ := os.Getwd()
-	if len(wd) < 3 {
-		t.Errorf("Current directory path %q is too short", wd)
-	}
-	lp := strings.ToLower(wd)
-	up := strings.ToUpper(wd)
-	flp, err := filepath.EvalSymlinks(lp)
-	if err != nil {
-		t.Fatalf("EvalSymlinks(%q) failed: %q", lp, err)
-	}
-	fup, err := filepath.EvalSymlinks(up)
-	if err != nil {
-		t.Fatalf("EvalSymlinks(%q) failed: %q", up, err)
-	}
-	if flp != fup {
-		t.Errorf("Results of EvalSymlinks do not match: %q and %q", flp, fup)
-	}
-}
-
-func TestBug3486(t *testing.T) { // http://code.google.com/p/go/issues/detail?id=3486
-	root, err := filepath.EvalSymlinks(runtime.GOROOT() + "/test")
-	if err != nil {
-		t.Fatal(err)
-	}
-	bugs := filepath.Join(root, "bugs")
-	ken := filepath.Join(root, "ken")
-	seenBugs := false
-	seenKen := false
-	filepath.Walk(root, func(pth string, info os.FileInfo, err error) error {
-		if err != nil {
-			t.Fatal(err)
-		}
-
-		switch pth {
-		case bugs:
-			seenBugs = true
-			return filepath.SkipDir
-		case ken:
-			if !seenBugs {
-				t.Fatal("filepath.Walk out of order - ken before bugs")
-			}
-			seenKen = true
-		}
-		return nil
-	})
-	if !seenKen {
-		t.Fatalf("%q not seen", ken)
-	}
-}
diff --git a/src/pkg/path/filepath/path_unix.go b/src/pkg/path/filepath/path_unix.go
deleted file mode 100644
index 7aba0ab..0000000
--- a/src/pkg/path/filepath/path_unix.go
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris
-
-package filepath
-
-import "strings"
-
-// IsAbs returns true if the path is absolute.
-func IsAbs(path string) bool {
-	return strings.HasPrefix(path, "/")
-}
-
-// volumeNameLen returns length of the leading volume name on Windows.
-// It returns 0 elsewhere.
-func volumeNameLen(path string) int {
-	return 0
-}
-
-// HasPrefix exists for historical compatibility and should not be used.
-func HasPrefix(p, prefix string) bool {
-	return strings.HasPrefix(p, prefix)
-}
-
-func splitList(path string) []string {
-	if path == "" {
-		return []string{}
-	}
-	return strings.Split(path, string(ListSeparator))
-}
diff --git a/src/pkg/path/filepath/path_windows.go b/src/pkg/path/filepath/path_windows.go
deleted file mode 100644
index e999972..0000000
--- a/src/pkg/path/filepath/path_windows.go
+++ /dev/null
@@ -1,105 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package filepath
-
-import (
-	"strings"
-)
-
-func isSlash(c uint8) bool {
-	return c == '\\' || c == '/'
-}
-
-// IsAbs returns true if the path is absolute.
-func IsAbs(path string) (b bool) {
-	l := volumeNameLen(path)
-	if l == 0 {
-		return false
-	}
-	path = path[l:]
-	if path == "" {
-		return false
-	}
-	return isSlash(path[0])
-}
-
-// volumeNameLen returns length of the leading volume name on Windows.
-// It returns 0 elsewhere.
-func volumeNameLen(path string) int {
-	if len(path) < 2 {
-		return 0
-	}
-	// with drive letter
-	c := path[0]
-	if path[1] == ':' && ('a' <= c && c <= 'z' || 'A' <= c && c <= 'Z') {
-		return 2
-	}
-	// is it UNC
-	if l := len(path); l >= 5 && isSlash(path[0]) && isSlash(path[1]) &&
-		!isSlash(path[2]) && path[2] != '.' {
-		// first, leading `\\` and next shouldn't be `\`. its server name.
-		for n := 3; n < l-1; n++ {
-			// second, next '\' shouldn't be repeated.
-			if isSlash(path[n]) {
-				n++
-				// third, following something characters. its share name.
-				if !isSlash(path[n]) {
-					if path[n] == '.' {
-						break
-					}
-					for ; n < l; n++ {
-						if isSlash(path[n]) {
-							break
-						}
-					}
-					return n
-				}
-				break
-			}
-		}
-	}
-	return 0
-}
-
-// HasPrefix exists for historical compatibility and should not be used.
-func HasPrefix(p, prefix string) bool {
-	if strings.HasPrefix(p, prefix) {
-		return true
-	}
-	return strings.HasPrefix(strings.ToLower(p), strings.ToLower(prefix))
-}
-
-func splitList(path string) []string {
-	// The same implementation is used in LookPath in os/exec;
-	// consider changing os/exec when changing this.
-
-	if path == "" {
-		return []string{}
-	}
-
-	// Split path, respecting but preserving quotes.
-	list := []string{}
-	start := 0
-	quo := false
-	for i := 0; i < len(path); i++ {
-		switch c := path[i]; {
-		case c == '"':
-			quo = !quo
-		case c == ListSeparator && !quo:
-			list = append(list, path[start:i])
-			start = i + 1
-		}
-	}
-	list = append(list, path[start:])
-
-	// Remove quotes.
-	for i, s := range list {
-		if strings.Contains(s, `"`) {
-			list[i] = strings.Replace(s, `"`, ``, -1)
-		}
-	}
-
-	return list
-}
diff --git a/src/pkg/path/filepath/path_windows_test.go b/src/pkg/path/filepath/path_windows_test.go
deleted file mode 100644
index 8a9be8e..0000000
--- a/src/pkg/path/filepath/path_windows_test.go
+++ /dev/null
@@ -1,93 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package filepath_test
-
-import (
-	"io/ioutil"
-	"os"
-	"os/exec"
-	"path/filepath"
-	"reflect"
-	"testing"
-)
-
-func TestWinSplitListTestsAreValid(t *testing.T) {
-	comspec := os.Getenv("ComSpec")
-	if comspec == "" {
-		t.Fatal("%ComSpec% must be set")
-	}
-
-	for ti, tt := range winsplitlisttests {
-		testWinSplitListTestIsValid(t, ti, tt, comspec)
-	}
-}
-
-func testWinSplitListTestIsValid(t *testing.T, ti int, tt SplitListTest,
-	comspec string) {
-
-	const (
-		cmdfile             = `printdir.cmd`
-		perm    os.FileMode = 0700
-	)
-
-	tmp, err := ioutil.TempDir("", "testWinSplitListTestIsValid")
-	if err != nil {
-		t.Fatalf("TempDir failed: %v", err)
-	}
-	defer os.RemoveAll(tmp)
-
-	for i, d := range tt.result {
-		if d == "" {
-			continue
-		}
-		if cd := filepath.Clean(d); filepath.VolumeName(cd) != "" ||
-			cd[0] == '\\' || cd == ".." || (len(cd) >= 3 && cd[0:3] == `..\`) {
-			t.Errorf("%d,%d: %#q refers outside working directory", ti, i, d)
-			return
-		}
-		dd := filepath.Join(tmp, d)
-		if _, err := os.Stat(dd); err == nil {
-			t.Errorf("%d,%d: %#q already exists", ti, i, d)
-			return
-		}
-		if err = os.MkdirAll(dd, perm); err != nil {
-			t.Errorf("%d,%d: MkdirAll(%#q) failed: %v", ti, i, dd, err)
-			return
-		}
-		fn, data := filepath.Join(dd, cmdfile), []byte("@echo "+d+"\r\n")
-		if err = ioutil.WriteFile(fn, data, perm); err != nil {
-			t.Errorf("%d,%d: WriteFile(%#q) failed: %v", ti, i, fn, err)
-			return
-		}
-	}
-
-	for i, d := range tt.result {
-		if d == "" {
-			continue
-		}
-		exp := []byte(d + "\r\n")
-		cmd := &exec.Cmd{
-			Path: comspec,
-			Args: []string{`/c`, cmdfile},
-			Env:  []string{`Path=` + tt.list},
-			Dir:  tmp,
-		}
-		out, err := cmd.CombinedOutput()
-		switch {
-		case err != nil:
-			t.Errorf("%d,%d: execution error %v\n%q", ti, i, err, out)
-			return
-		case !reflect.DeepEqual(out, exp):
-			t.Errorf("%d,%d: expected %#q, got %#q", ti, i, exp, out)
-			return
-		default:
-			// unshadow cmdfile in next directory
-			err = os.Remove(filepath.Join(tmp, d, cmdfile))
-			if err != nil {
-				t.Fatalf("Remove test command failed: %v", err)
-			}
-		}
-	}
-}
diff --git a/src/pkg/path/filepath/symlink.go b/src/pkg/path/filepath/symlink.go
deleted file mode 100644
index 307dd0f..0000000
--- a/src/pkg/path/filepath/symlink.go
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build !windows
-
-package filepath
-
-import (
-	"bytes"
-	"errors"
-	"os"
-	"strings"
-)
-
-func evalSymlinks(path string) (string, error) {
-	const maxIter = 255
-	originalPath := path
-	// consume path by taking each frontmost path element,
-	// expanding it if it's a symlink, and appending it to b
-	var b bytes.Buffer
-	for n := 0; path != ""; n++ {
-		if n > maxIter {
-			return "", errors.New("EvalSymlinks: too many links in " + originalPath)
-		}
-
-		// find next path component, p
-		i := strings.IndexRune(path, Separator)
-		var p string
-		if i == -1 {
-			p, path = path, ""
-		} else {
-			p, path = path[:i], path[i+1:]
-		}
-
-		if p == "" {
-			if b.Len() == 0 {
-				// must be absolute path
-				b.WriteRune(Separator)
-			}
-			continue
-		}
-
-		fi, err := os.Lstat(b.String() + p)
-		if err != nil {
-			return "", err
-		}
-		if fi.Mode()&os.ModeSymlink == 0 {
-			b.WriteString(p)
-			if path != "" {
-				b.WriteRune(Separator)
-			}
-			continue
-		}
-
-		// it's a symlink, put it at the front of path
-		dest, err := os.Readlink(b.String() + p)
-		if err != nil {
-			return "", err
-		}
-		if IsAbs(dest) {
-			b.Reset()
-		}
-		path = dest + string(Separator) + path
-	}
-	return Clean(b.String()), nil
-}
diff --git a/src/pkg/path/filepath/symlink_windows.go b/src/pkg/path/filepath/symlink_windows.go
deleted file mode 100644
index 9adc8a4..0000000
--- a/src/pkg/path/filepath/symlink_windows.go
+++ /dev/null
@@ -1,69 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package filepath
-
-import (
-	"syscall"
-)
-
-func toShort(path string) (string, error) {
-	p, err := syscall.UTF16FromString(path)
-	if err != nil {
-		return "", err
-	}
-	b := p // GetShortPathName says we can reuse buffer
-	n, err := syscall.GetShortPathName(&p[0], &b[0], uint32(len(b)))
-	if err != nil {
-		return "", err
-	}
-	if n > uint32(len(b)) {
-		b = make([]uint16, n)
-		n, err = syscall.GetShortPathName(&p[0], &b[0], uint32(len(b)))
-		if err != nil {
-			return "", err
-		}
-	}
-	return syscall.UTF16ToString(b), nil
-}
-
-func toLong(path string) (string, error) {
-	p, err := syscall.UTF16FromString(path)
-	if err != nil {
-		return "", err
-	}
-	b := p // GetLongPathName says we can reuse buffer
-	n, err := syscall.GetLongPathName(&p[0], &b[0], uint32(len(b)))
-	if err != nil {
-		return "", err
-	}
-	if n > uint32(len(b)) {
-		b = make([]uint16, n)
-		n, err = syscall.GetLongPathName(&p[0], &b[0], uint32(len(b)))
-		if err != nil {
-			return "", err
-		}
-	}
-	b = b[:n]
-	return syscall.UTF16ToString(b), nil
-}
-
-func evalSymlinks(path string) (string, error) {
-	p, err := toShort(path)
-	if err != nil {
-		return "", err
-	}
-	p, err = toLong(p)
-	if err != nil {
-		return "", err
-	}
-	// syscall.GetLongPathName does not change the case of the drive letter,
-	// but the result of EvalSymlinks must be unique, so we have
-	// EvalSymlinks(`c:\a`) == EvalSymlinks(`C:\a`).
-	// Make drive letter upper case.
-	if len(p) >= 2 && p[1] == ':' && 'a' <= p[0] && p[0] <= 'z' {
-		p = string(p[0]+'A'-'a') + p[1:]
-	}
-	return Clean(p), nil
-}
diff --git a/src/pkg/path/path.go b/src/pkg/path/path.go
deleted file mode 100644
index bdb85c6..0000000
--- a/src/pkg/path/path.go
+++ /dev/null
@@ -1,218 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package path implements utility routines for manipulating slash-separated
-// paths.
-package path
-
-import (
-	"strings"
-)
-
-// A lazybuf is a lazily constructed path buffer.
-// It supports append, reading previously appended bytes,
-// and retrieving the final string. It does not allocate a buffer
-// to hold the output until that output diverges from s.
-type lazybuf struct {
-	s   string
-	buf []byte
-	w   int
-}
-
-func (b *lazybuf) index(i int) byte {
-	if b.buf != nil {
-		return b.buf[i]
-	}
-	return b.s[i]
-}
-
-func (b *lazybuf) append(c byte) {
-	if b.buf == nil {
-		if b.w < len(b.s) && b.s[b.w] == c {
-			b.w++
-			return
-		}
-		b.buf = make([]byte, len(b.s))
-		copy(b.buf, b.s[:b.w])
-	}
-	b.buf[b.w] = c
-	b.w++
-}
-
-func (b *lazybuf) string() string {
-	if b.buf == nil {
-		return b.s[:b.w]
-	}
-	return string(b.buf[:b.w])
-}
-
-// Clean returns the shortest path name equivalent to path
-// by purely lexical processing.  It applies the following rules
-// iteratively until no further processing can be done:
-//
-//	1. Replace multiple slashes with a single slash.
-//	2. Eliminate each . path name element (the current directory).
-//	3. Eliminate each inner .. path name element (the parent directory)
-//	   along with the non-.. element that precedes it.
-//	4. Eliminate .. elements that begin a rooted path:
-//	   that is, replace "/.." by "/" at the beginning of a path.
-//
-// The returned path ends in a slash only if it is the root "/".
-//
-// If the result of this process is an empty string, Clean
-// returns the string ".".
-//
-// See also Rob Pike, ``Lexical File Names in Plan 9 or
-// Getting Dot-Dot Right,''
-// http://plan9.bell-labs.com/sys/doc/lexnames.html
-func Clean(path string) string {
-	if path == "" {
-		return "."
-	}
-
-	rooted := path[0] == '/'
-	n := len(path)
-
-	// Invariants:
-	//	reading from path; r is index of next byte to process.
-	//	writing to buf; w is index of next byte to write.
-	//	dotdot is index in buf where .. must stop, either because
-	//		it is the leading slash or it is a leading ../../.. prefix.
-	out := lazybuf{s: path}
-	r, dotdot := 0, 0
-	if rooted {
-		out.append('/')
-		r, dotdot = 1, 1
-	}
-
-	for r < n {
-		switch {
-		case path[r] == '/':
-			// empty path element
-			r++
-		case path[r] == '.' && (r+1 == n || path[r+1] == '/'):
-			// . element
-			r++
-		case path[r] == '.' && path[r+1] == '.' && (r+2 == n || path[r+2] == '/'):
-			// .. element: remove to last /
-			r += 2
-			switch {
-			case out.w > dotdot:
-				// can backtrack
-				out.w--
-				for out.w > dotdot && out.index(out.w) != '/' {
-					out.w--
-				}
-			case !rooted:
-				// cannot backtrack, but not rooted, so append .. element.
-				if out.w > 0 {
-					out.append('/')
-				}
-				out.append('.')
-				out.append('.')
-				dotdot = out.w
-			}
-		default:
-			// real path element.
-			// add slash if needed
-			if rooted && out.w != 1 || !rooted && out.w != 0 {
-				out.append('/')
-			}
-			// copy element
-			for ; r < n && path[r] != '/'; r++ {
-				out.append(path[r])
-			}
-		}
-	}
-
-	// Turn empty string into "."
-	if out.w == 0 {
-		return "."
-	}
-
-	return out.string()
-}
-
-// Split splits path immediately following the final slash.
-// separating it into a directory and file name component.
-// If there is no slash path, Split returns an empty dir and
-// file set to path.
-// The returned values have the property that path = dir+file.
-func Split(path string) (dir, file string) {
-	i := strings.LastIndex(path, "/")
-	return path[:i+1], path[i+1:]
-}
-
-// Join joins any number of path elements into a single path, adding a
-// separating slash if necessary. The result is Cleaned; in particular,
-// all empty strings are ignored.
-func Join(elem ...string) string {
-	for i, e := range elem {
-		if e != "" {
-			return Clean(strings.Join(elem[i:], "/"))
-		}
-	}
-	return ""
-}
-
-// Ext returns the file name extension used by path.
-// The extension is the suffix beginning at the final dot
-// in the final slash-separated element of path;
-// it is empty if there is no dot.
-func Ext(path string) string {
-	for i := len(path) - 1; i >= 0 && path[i] != '/'; i-- {
-		if path[i] == '.' {
-			return path[i:]
-		}
-	}
-	return ""
-}
-
-// Base returns the last element of path.
-// Trailing slashes are removed before extracting the last element.
-// If the path is empty, Base returns ".".
-// If the path consists entirely of slashes, Base returns "/".
-func Base(path string) string {
-	if path == "" {
-		return "."
-	}
-	// Strip trailing slashes.
-	for len(path) > 0 && path[len(path)-1] == '/' {
-		path = path[0 : len(path)-1]
-	}
-	// Find the last element
-	if i := strings.LastIndex(path, "/"); i >= 0 {
-		path = path[i+1:]
-	}
-	// If empty now, it had only slashes.
-	if path == "" {
-		return "/"
-	}
-	return path
-}
-
-// IsAbs returns true if the path is absolute.
-func IsAbs(path string) bool {
-	return len(path) > 0 && path[0] == '/'
-}
-
-// Dir returns all but the last element of path, typically the path's directory.
-// After dropping the final element using Split, the path is Cleaned and trailing
-// slashes are removed.
-// If the path is empty, Dir returns ".".
-// If the path consists entirely of slashes followed by non-slash bytes, Dir
-// returns a single slash. In any other case, the returned path does not end in a
-// slash.
-func Dir(path string) string {
-	dir, _ := Split(path)
-	dir = Clean(dir)
-	last := len(dir) - 1
-	if last > 0 && dir[last] == '/' {
-		dir = dir[:last]
-	}
-	if dir == "" {
-		dir = "."
-	}
-	return dir
-}
diff --git a/src/pkg/reflect/all_test.go b/src/pkg/reflect/all_test.go
deleted file mode 100644
index e994901..0000000
--- a/src/pkg/reflect/all_test.go
+++ /dev/null
@@ -1,3841 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package reflect_test
-
-import (
-	"bytes"
-	"encoding/base64"
-	"flag"
-	"fmt"
-	"io"
-	"math/rand"
-	"os"
-	. "reflect"
-	"runtime"
-	"sort"
-	"strings"
-	"sync"
-	"testing"
-	"time"
-	"unsafe"
-)
-
-func TestBool(t *testing.T) {
-	v := ValueOf(true)
-	if v.Bool() != true {
-		t.Fatal("ValueOf(true).Bool() = false")
-	}
-}
-
-type integer int
-type T struct {
-	a int
-	b float64
-	c string
-	d *int
-}
-
-type pair struct {
-	i interface{}
-	s string
-}
-
-func isDigit(c uint8) bool { return '0' <= c && c <= '9' }
-
-func assert(t *testing.T, s, want string) {
-	if s != want {
-		t.Errorf("have %#q want %#q", s, want)
-	}
-}
-
-func typestring(i interface{}) string { return TypeOf(i).String() }
-
-var typeTests = []pair{
-	{struct{ x int }{}, "int"},
-	{struct{ x int8 }{}, "int8"},
-	{struct{ x int16 }{}, "int16"},
-	{struct{ x int32 }{}, "int32"},
-	{struct{ x int64 }{}, "int64"},
-	{struct{ x uint }{}, "uint"},
-	{struct{ x uint8 }{}, "uint8"},
-	{struct{ x uint16 }{}, "uint16"},
-	{struct{ x uint32 }{}, "uint32"},
-	{struct{ x uint64 }{}, "uint64"},
-	{struct{ x float32 }{}, "float32"},
-	{struct{ x float64 }{}, "float64"},
-	{struct{ x int8 }{}, "int8"},
-	{struct{ x (**int8) }{}, "**int8"},
-	{struct{ x (**integer) }{}, "**reflect_test.integer"},
-	{struct{ x ([32]int32) }{}, "[32]int32"},
-	{struct{ x ([]int8) }{}, "[]int8"},
-	{struct{ x (map[string]int32) }{}, "map[string]int32"},
-	{struct{ x (chan<- string) }{}, "chan<- string"},
-	{struct {
-		x struct {
-			c chan *int32
-			d float32
-		}
-	}{},
-		"struct { c chan *int32; d float32 }",
-	},
-	{struct{ x (func(a int8, b int32)) }{}, "func(int8, int32)"},
-	{struct {
-		x struct {
-			c func(chan *integer, *int8)
-		}
-	}{},
-		"struct { c func(chan *reflect_test.integer, *int8) }",
-	},
-	{struct {
-		x struct {
-			a int8
-			b int32
-		}
-	}{},
-		"struct { a int8; b int32 }",
-	},
-	{struct {
-		x struct {
-			a int8
-			b int8
-			c int32
-		}
-	}{},
-		"struct { a int8; b int8; c int32 }",
-	},
-	{struct {
-		x struct {
-			a int8
-			b int8
-			c int8
-			d int32
-		}
-	}{},
-		"struct { a int8; b int8; c int8; d int32 }",
-	},
-	{struct {
-		x struct {
-			a int8
-			b int8
-			c int8
-			d int8
-			e int32
-		}
-	}{},
-		"struct { a int8; b int8; c int8; d int8; e int32 }",
-	},
-	{struct {
-		x struct {
-			a int8
-			b int8
-			c int8
-			d int8
-			e int8
-			f int32
-		}
-	}{},
-		"struct { a int8; b int8; c int8; d int8; e int8; f int32 }",
-	},
-	{struct {
-		x struct {
-			a int8 `reflect:"hi there"`
-		}
-	}{},
-		`struct { a int8 "reflect:\"hi there\"" }`,
-	},
-	{struct {
-		x struct {
-			a int8 `reflect:"hi \x00there\t\n\"\\"`
-		}
-	}{},
-		`struct { a int8 "reflect:\"hi \\x00there\\t\\n\\\"\\\\\"" }`,
-	},
-	{struct {
-		x struct {
-			f func(args ...int)
-		}
-	}{},
-		"struct { f func(...int) }",
-	},
-	{struct {
-		x (interface {
-			a(func(func(int) int) func(func(int)) int)
-			b()
-		})
-	}{},
-		"interface { reflect_test.a(func(func(int) int) func(func(int)) int); reflect_test.b() }",
-	},
-}
-
-var valueTests = []pair{
-	{new(int), "132"},
-	{new(int8), "8"},
-	{new(int16), "16"},
-	{new(int32), "32"},
-	{new(int64), "64"},
-	{new(uint), "132"},
-	{new(uint8), "8"},
-	{new(uint16), "16"},
-	{new(uint32), "32"},
-	{new(uint64), "64"},
-	{new(float32), "256.25"},
-	{new(float64), "512.125"},
-	{new(complex64), "532.125+10i"},
-	{new(complex128), "564.25+1i"},
-	{new(string), "stringy cheese"},
-	{new(bool), "true"},
-	{new(*int8), "*int8(0)"},
-	{new(**int8), "**int8(0)"},
-	{new([5]int32), "[5]int32{0, 0, 0, 0, 0}"},
-	{new(**integer), "**reflect_test.integer(0)"},
-	{new(map[string]int32), "map[string]int32{<can't iterate on maps>}"},
-	{new(chan<- string), "chan<- string"},
-	{new(func(a int8, b int32)), "func(int8, int32)(0)"},
-	{new(struct {
-		c chan *int32
-		d float32
-	}),
-		"struct { c chan *int32; d float32 }{chan *int32, 0}",
-	},
-	{new(struct{ c func(chan *integer, *int8) }),
-		"struct { c func(chan *reflect_test.integer, *int8) }{func(chan *reflect_test.integer, *int8)(0)}",
-	},
-	{new(struct {
-		a int8
-		b int32
-	}),
-		"struct { a int8; b int32 }{0, 0}",
-	},
-	{new(struct {
-		a int8
-		b int8
-		c int32
-	}),
-		"struct { a int8; b int8; c int32 }{0, 0, 0}",
-	},
-}
-
-func testType(t *testing.T, i int, typ Type, want string) {
-	s := typ.String()
-	if s != want {
-		t.Errorf("#%d: have %#q, want %#q", i, s, want)
-	}
-}
-
-func TestTypes(t *testing.T) {
-	for i, tt := range typeTests {
-		testType(t, i, ValueOf(tt.i).Field(0).Type(), tt.s)
-	}
-}
-
-func TestSet(t *testing.T) {
-	for i, tt := range valueTests {
-		v := ValueOf(tt.i)
-		v = v.Elem()
-		switch v.Kind() {
-		case Int:
-			v.SetInt(132)
-		case Int8:
-			v.SetInt(8)
-		case Int16:
-			v.SetInt(16)
-		case Int32:
-			v.SetInt(32)
-		case Int64:
-			v.SetInt(64)
-		case Uint:
-			v.SetUint(132)
-		case Uint8:
-			v.SetUint(8)
-		case Uint16:
-			v.SetUint(16)
-		case Uint32:
-			v.SetUint(32)
-		case Uint64:
-			v.SetUint(64)
-		case Float32:
-			v.SetFloat(256.25)
-		case Float64:
-			v.SetFloat(512.125)
-		case Complex64:
-			v.SetComplex(532.125 + 10i)
-		case Complex128:
-			v.SetComplex(564.25 + 1i)
-		case String:
-			v.SetString("stringy cheese")
-		case Bool:
-			v.SetBool(true)
-		}
-		s := valueToString(v)
-		if s != tt.s {
-			t.Errorf("#%d: have %#q, want %#q", i, s, tt.s)
-		}
-	}
-}
-
-func TestSetValue(t *testing.T) {
-	for i, tt := range valueTests {
-		v := ValueOf(tt.i).Elem()
-		switch v.Kind() {
-		case Int:
-			v.Set(ValueOf(int(132)))
-		case Int8:
-			v.Set(ValueOf(int8(8)))
-		case Int16:
-			v.Set(ValueOf(int16(16)))
-		case Int32:
-			v.Set(ValueOf(int32(32)))
-		case Int64:
-			v.Set(ValueOf(int64(64)))
-		case Uint:
-			v.Set(ValueOf(uint(132)))
-		case Uint8:
-			v.Set(ValueOf(uint8(8)))
-		case Uint16:
-			v.Set(ValueOf(uint16(16)))
-		case Uint32:
-			v.Set(ValueOf(uint32(32)))
-		case Uint64:
-			v.Set(ValueOf(uint64(64)))
-		case Float32:
-			v.Set(ValueOf(float32(256.25)))
-		case Float64:
-			v.Set(ValueOf(512.125))
-		case Complex64:
-			v.Set(ValueOf(complex64(532.125 + 10i)))
-		case Complex128:
-			v.Set(ValueOf(complex128(564.25 + 1i)))
-		case String:
-			v.Set(ValueOf("stringy cheese"))
-		case Bool:
-			v.Set(ValueOf(true))
-		}
-		s := valueToString(v)
-		if s != tt.s {
-			t.Errorf("#%d: have %#q, want %#q", i, s, tt.s)
-		}
-	}
-}
-
-var _i = 7
-
-var valueToStringTests = []pair{
-	{123, "123"},
-	{123.5, "123.5"},
-	{byte(123), "123"},
-	{"abc", "abc"},
-	{T{123, 456.75, "hello", &_i}, "reflect_test.T{123, 456.75, hello, *int(&7)}"},
-	{new(chan *T), "*chan *reflect_test.T(&chan *reflect_test.T)"},
-	{[10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, "[10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}"},
-	{&[10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, "*[10]int(&[10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10})"},
-	{[]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, "[]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}"},
-	{&[]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, "*[]int(&[]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10})"},
-}
-
-func TestValueToString(t *testing.T) {
-	for i, test := range valueToStringTests {
-		s := valueToString(ValueOf(test.i))
-		if s != test.s {
-			t.Errorf("#%d: have %#q, want %#q", i, s, test.s)
-		}
-	}
-}
-
-func TestArrayElemSet(t *testing.T) {
-	v := ValueOf(&[10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}).Elem()
-	v.Index(4).SetInt(123)
-	s := valueToString(v)
-	const want = "[10]int{1, 2, 3, 4, 123, 6, 7, 8, 9, 10}"
-	if s != want {
-		t.Errorf("[10]int: have %#q want %#q", s, want)
-	}
-
-	v = ValueOf([]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10})
-	v.Index(4).SetInt(123)
-	s = valueToString(v)
-	const want1 = "[]int{1, 2, 3, 4, 123, 6, 7, 8, 9, 10}"
-	if s != want1 {
-		t.Errorf("[]int: have %#q want %#q", s, want1)
-	}
-}
-
-func TestPtrPointTo(t *testing.T) {
-	var ip *int32
-	var i int32 = 1234
-	vip := ValueOf(&ip)
-	vi := ValueOf(&i).Elem()
-	vip.Elem().Set(vi.Addr())
-	if *ip != 1234 {
-		t.Errorf("got %d, want 1234", *ip)
-	}
-
-	ip = nil
-	vp := ValueOf(&ip).Elem()
-	vp.Set(Zero(vp.Type()))
-	if ip != nil {
-		t.Errorf("got non-nil (%p), want nil", ip)
-	}
-}
-
-func TestPtrSetNil(t *testing.T) {
-	var i int32 = 1234
-	ip := &i
-	vip := ValueOf(&ip)
-	vip.Elem().Set(Zero(vip.Elem().Type()))
-	if ip != nil {
-		t.Errorf("got non-nil (%d), want nil", *ip)
-	}
-}
-
-func TestMapSetNil(t *testing.T) {
-	m := make(map[string]int)
-	vm := ValueOf(&m)
-	vm.Elem().Set(Zero(vm.Elem().Type()))
-	if m != nil {
-		t.Errorf("got non-nil (%p), want nil", m)
-	}
-}
-
-func TestAll(t *testing.T) {
-	testType(t, 1, TypeOf((int8)(0)), "int8")
-	testType(t, 2, TypeOf((*int8)(nil)).Elem(), "int8")
-
-	typ := TypeOf((*struct {
-		c chan *int32
-		d float32
-	})(nil))
-	testType(t, 3, typ, "*struct { c chan *int32; d float32 }")
-	etyp := typ.Elem()
-	testType(t, 4, etyp, "struct { c chan *int32; d float32 }")
-	styp := etyp
-	f := styp.Field(0)
-	testType(t, 5, f.Type, "chan *int32")
-
-	f, present := styp.FieldByName("d")
-	if !present {
-		t.Errorf("FieldByName says present field is absent")
-	}
-	testType(t, 6, f.Type, "float32")
-
-	f, present = styp.FieldByName("absent")
-	if present {
-		t.Errorf("FieldByName says absent field is present")
-	}
-
-	typ = TypeOf([32]int32{})
-	testType(t, 7, typ, "[32]int32")
-	testType(t, 8, typ.Elem(), "int32")
-
-	typ = TypeOf((map[string]*int32)(nil))
-	testType(t, 9, typ, "map[string]*int32")
-	mtyp := typ
-	testType(t, 10, mtyp.Key(), "string")
-	testType(t, 11, mtyp.Elem(), "*int32")
-
-	typ = TypeOf((chan<- string)(nil))
-	testType(t, 12, typ, "chan<- string")
-	testType(t, 13, typ.Elem(), "string")
-
-	// make sure tag strings are not part of element type
-	typ = TypeOf(struct {
-		d []uint32 `reflect:"TAG"`
-	}{}).Field(0).Type
-	testType(t, 14, typ, "[]uint32")
-}
-
-func TestInterfaceGet(t *testing.T) {
-	var inter struct {
-		E interface{}
-	}
-	inter.E = 123.456
-	v1 := ValueOf(&inter)
-	v2 := v1.Elem().Field(0)
-	assert(t, v2.Type().String(), "interface {}")
-	i2 := v2.Interface()
-	v3 := ValueOf(i2)
-	assert(t, v3.Type().String(), "float64")
-}
-
-func TestInterfaceValue(t *testing.T) {
-	var inter struct {
-		E interface{}
-	}
-	inter.E = 123.456
-	v1 := ValueOf(&inter)
-	v2 := v1.Elem().Field(0)
-	assert(t, v2.Type().String(), "interface {}")
-	v3 := v2.Elem()
-	assert(t, v3.Type().String(), "float64")
-
-	i3 := v2.Interface()
-	if _, ok := i3.(float64); !ok {
-		t.Error("v2.Interface() did not return float64, got ", TypeOf(i3))
-	}
-}
-
-func TestFunctionValue(t *testing.T) {
-	var x interface{} = func() {}
-	v := ValueOf(x)
-	if fmt.Sprint(v.Interface()) != fmt.Sprint(x) {
-		t.Fatalf("TestFunction returned wrong pointer")
-	}
-	assert(t, v.Type().String(), "func()")
-}
-
-var appendTests = []struct {
-	orig, extra []int
-}{
-	{make([]int, 2, 4), []int{22}},
-	{make([]int, 2, 4), []int{22, 33, 44}},
-}
-
-func sameInts(x, y []int) bool {
-	if len(x) != len(y) {
-		return false
-	}
-	for i, xx := range x {
-		if xx != y[i] {
-			return false
-		}
-	}
-	return true
-}
-
-func TestAppend(t *testing.T) {
-	for i, test := range appendTests {
-		origLen, extraLen := len(test.orig), len(test.extra)
-		want := append(test.orig, test.extra...)
-		// Convert extra from []int to []Value.
-		e0 := make([]Value, len(test.extra))
-		for j, e := range test.extra {
-			e0[j] = ValueOf(e)
-		}
-		// Convert extra from []int to *SliceValue.
-		e1 := ValueOf(test.extra)
-		// Test Append.
-		a0 := ValueOf(test.orig)
-		have0 := Append(a0, e0...).Interface().([]int)
-		if !sameInts(have0, want) {
-			t.Errorf("Append #%d: have %v, want %v (%p %p)", i, have0, want, test.orig, have0)
-		}
-		// Check that the orig and extra slices were not modified.
-		if len(test.orig) != origLen {
-			t.Errorf("Append #%d origLen: have %v, want %v", i, len(test.orig), origLen)
-		}
-		if len(test.extra) != extraLen {
-			t.Errorf("Append #%d extraLen: have %v, want %v", i, len(test.extra), extraLen)
-		}
-		// Test AppendSlice.
-		a1 := ValueOf(test.orig)
-		have1 := AppendSlice(a1, e1).Interface().([]int)
-		if !sameInts(have1, want) {
-			t.Errorf("AppendSlice #%d: have %v, want %v", i, have1, want)
-		}
-		// Check that the orig and extra slices were not modified.
-		if len(test.orig) != origLen {
-			t.Errorf("AppendSlice #%d origLen: have %v, want %v", i, len(test.orig), origLen)
-		}
-		if len(test.extra) != extraLen {
-			t.Errorf("AppendSlice #%d extraLen: have %v, want %v", i, len(test.extra), extraLen)
-		}
-	}
-}
-
-func TestCopy(t *testing.T) {
-	a := []int{1, 2, 3, 4, 10, 9, 8, 7}
-	b := []int{11, 22, 33, 44, 1010, 99, 88, 77, 66, 55, 44}
-	c := []int{11, 22, 33, 44, 1010, 99, 88, 77, 66, 55, 44}
-	for i := 0; i < len(b); i++ {
-		if b[i] != c[i] {
-			t.Fatalf("b != c before test")
-		}
-	}
-	a1 := a
-	b1 := b
-	aa := ValueOf(&a1).Elem()
-	ab := ValueOf(&b1).Elem()
-	for tocopy := 1; tocopy <= 7; tocopy++ {
-		aa.SetLen(tocopy)
-		Copy(ab, aa)
-		aa.SetLen(8)
-		for i := 0; i < tocopy; i++ {
-			if a[i] != b[i] {
-				t.Errorf("(i) tocopy=%d a[%d]=%d, b[%d]=%d",
-					tocopy, i, a[i], i, b[i])
-			}
-		}
-		for i := tocopy; i < len(b); i++ {
-			if b[i] != c[i] {
-				if i < len(a) {
-					t.Errorf("(ii) tocopy=%d a[%d]=%d, b[%d]=%d, c[%d]=%d",
-						tocopy, i, a[i], i, b[i], i, c[i])
-				} else {
-					t.Errorf("(iii) tocopy=%d b[%d]=%d, c[%d]=%d",
-						tocopy, i, b[i], i, c[i])
-				}
-			} else {
-				t.Logf("tocopy=%d elem %d is okay\n", tocopy, i)
-			}
-		}
-	}
-}
-
-func TestCopyArray(t *testing.T) {
-	a := [8]int{1, 2, 3, 4, 10, 9, 8, 7}
-	b := [11]int{11, 22, 33, 44, 1010, 99, 88, 77, 66, 55, 44}
-	c := b
-	aa := ValueOf(&a).Elem()
-	ab := ValueOf(&b).Elem()
-	Copy(ab, aa)
-	for i := 0; i < len(a); i++ {
-		if a[i] != b[i] {
-			t.Errorf("(i) a[%d]=%d, b[%d]=%d", i, a[i], i, b[i])
-		}
-	}
-	for i := len(a); i < len(b); i++ {
-		if b[i] != c[i] {
-			t.Errorf("(ii) b[%d]=%d, c[%d]=%d", i, b[i], i, c[i])
-		} else {
-			t.Logf("elem %d is okay\n", i)
-		}
-	}
-}
-
-func TestBigUnnamedStruct(t *testing.T) {
-	b := struct{ a, b, c, d int64 }{1, 2, 3, 4}
-	v := ValueOf(b)
-	b1 := v.Interface().(struct {
-		a, b, c, d int64
-	})
-	if b1.a != b.a || b1.b != b.b || b1.c != b.c || b1.d != b.d {
-		t.Errorf("ValueOf(%v).Interface().(*Big) = %v", b, b1)
-	}
-}
-
-type big struct {
-	a, b, c, d, e int64
-}
-
-func TestBigStruct(t *testing.T) {
-	b := big{1, 2, 3, 4, 5}
-	v := ValueOf(b)
-	b1 := v.Interface().(big)
-	if b1.a != b.a || b1.b != b.b || b1.c != b.c || b1.d != b.d || b1.e != b.e {
-		t.Errorf("ValueOf(%v).Interface().(big) = %v", b, b1)
-	}
-}
-
-type Basic struct {
-	x int
-	y float32
-}
-
-type NotBasic Basic
-
-type DeepEqualTest struct {
-	a, b interface{}
-	eq   bool
-}
-
-// Simple functions for DeepEqual tests.
-var (
-	fn1 func()             // nil.
-	fn2 func()             // nil.
-	fn3 = func() { fn1() } // Not nil.
-)
-
-var deepEqualTests = []DeepEqualTest{
-	// Equalities
-	{nil, nil, true},
-	{1, 1, true},
-	{int32(1), int32(1), true},
-	{0.5, 0.5, true},
-	{float32(0.5), float32(0.5), true},
-	{"hello", "hello", true},
-	{make([]int, 10), make([]int, 10), true},
-	{&[3]int{1, 2, 3}, &[3]int{1, 2, 3}, true},
-	{Basic{1, 0.5}, Basic{1, 0.5}, true},
-	{error(nil), error(nil), true},
-	{map[int]string{1: "one", 2: "two"}, map[int]string{2: "two", 1: "one"}, true},
-	{fn1, fn2, true},
-
-	// Inequalities
-	{1, 2, false},
-	{int32(1), int32(2), false},
-	{0.5, 0.6, false},
-	{float32(0.5), float32(0.6), false},
-	{"hello", "hey", false},
-	{make([]int, 10), make([]int, 11), false},
-	{&[3]int{1, 2, 3}, &[3]int{1, 2, 4}, false},
-	{Basic{1, 0.5}, Basic{1, 0.6}, false},
-	{Basic{1, 0}, Basic{2, 0}, false},
-	{map[int]string{1: "one", 3: "two"}, map[int]string{2: "two", 1: "one"}, false},
-	{map[int]string{1: "one", 2: "txo"}, map[int]string{2: "two", 1: "one"}, false},
-	{map[int]string{1: "one"}, map[int]string{2: "two", 1: "one"}, false},
-	{map[int]string{2: "two", 1: "one"}, map[int]string{1: "one"}, false},
-	{nil, 1, false},
-	{1, nil, false},
-	{fn1, fn3, false},
-	{fn3, fn3, false},
-	{[][]int{[]int{1}}, [][]int{[]int{2}}, false},
-
-	// Nil vs empty: not the same.
-	{[]int{}, []int(nil), false},
-	{[]int{}, []int{}, true},
-	{[]int(nil), []int(nil), true},
-	{map[int]int{}, map[int]int(nil), false},
-	{map[int]int{}, map[int]int{}, true},
-	{map[int]int(nil), map[int]int(nil), true},
-
-	// Mismatched types
-	{1, 1.0, false},
-	{int32(1), int64(1), false},
-	{0.5, "hello", false},
-	{[]int{1, 2, 3}, [3]int{1, 2, 3}, false},
-	{&[3]interface{}{1, 2, 4}, &[3]interface{}{1, 2, "s"}, false},
-	{Basic{1, 0.5}, NotBasic{1, 0.5}, false},
-	{map[uint]string{1: "one", 2: "two"}, map[int]string{2: "two", 1: "one"}, false},
-}
-
-func TestDeepEqual(t *testing.T) {
-	for _, test := range deepEqualTests {
-		if r := DeepEqual(test.a, test.b); r != test.eq {
-			t.Errorf("DeepEqual(%v, %v) = %v, want %v", test.a, test.b, r, test.eq)
-		}
-	}
-}
-
-func TestTypeOf(t *testing.T) {
-	// Special case for nil
-	if typ := TypeOf(nil); typ != nil {
-		t.Errorf("expected nil type for nil value; got %v", typ)
-	}
-	for _, test := range deepEqualTests {
-		v := ValueOf(test.a)
-		if !v.IsValid() {
-			continue
-		}
-		typ := TypeOf(test.a)
-		if typ != v.Type() {
-			t.Errorf("TypeOf(%v) = %v, but ValueOf(%v).Type() = %v", test.a, typ, test.a, v.Type())
-		}
-	}
-}
-
-type Recursive struct {
-	x int
-	r *Recursive
-}
-
-func TestDeepEqualRecursiveStruct(t *testing.T) {
-	a, b := new(Recursive), new(Recursive)
-	*a = Recursive{12, a}
-	*b = Recursive{12, b}
-	if !DeepEqual(a, b) {
-		t.Error("DeepEqual(recursive same) = false, want true")
-	}
-}
-
-type _Complex struct {
-	a int
-	b [3]*_Complex
-	c *string
-	d map[float64]float64
-}
-
-func TestDeepEqualComplexStruct(t *testing.T) {
-	m := make(map[float64]float64)
-	stra, strb := "hello", "hello"
-	a, b := new(_Complex), new(_Complex)
-	*a = _Complex{5, [3]*_Complex{a, b, a}, &stra, m}
-	*b = _Complex{5, [3]*_Complex{b, a, a}, &strb, m}
-	if !DeepEqual(a, b) {
-		t.Error("DeepEqual(complex same) = false, want true")
-	}
-}
-
-func TestDeepEqualComplexStructInequality(t *testing.T) {
-	m := make(map[float64]float64)
-	stra, strb := "hello", "helloo" // Difference is here
-	a, b := new(_Complex), new(_Complex)
-	*a = _Complex{5, [3]*_Complex{a, b, a}, &stra, m}
-	*b = _Complex{5, [3]*_Complex{b, a, a}, &strb, m}
-	if DeepEqual(a, b) {
-		t.Error("DeepEqual(complex different) = true, want false")
-	}
-}
-
-type UnexpT struct {
-	m map[int]int
-}
-
-func TestDeepEqualUnexportedMap(t *testing.T) {
-	// Check that DeepEqual can look at unexported fields.
-	x1 := UnexpT{map[int]int{1: 2}}
-	x2 := UnexpT{map[int]int{1: 2}}
-	if !DeepEqual(&x1, &x2) {
-		t.Error("DeepEqual(x1, x2) = false, want true")
-	}
-
-	y1 := UnexpT{map[int]int{2: 3}}
-	if DeepEqual(&x1, &y1) {
-		t.Error("DeepEqual(x1, y1) = true, want false")
-	}
-}
-
-func check2ndField(x interface{}, offs uintptr, t *testing.T) {
-	s := ValueOf(x)
-	f := s.Type().Field(1)
-	if f.Offset != offs {
-		t.Error("mismatched offsets in structure alignment:", f.Offset, offs)
-	}
-}
-
-// Check that structure alignment & offsets viewed through reflect agree with those
-// from the compiler itself.
-func TestAlignment(t *testing.T) {
-	type T1inner struct {
-		a int
-	}
-	type T1 struct {
-		T1inner
-		f int
-	}
-	type T2inner struct {
-		a, b int
-	}
-	type T2 struct {
-		T2inner
-		f int
-	}
-
-	x := T1{T1inner{2}, 17}
-	check2ndField(x, uintptr(unsafe.Pointer(&x.f))-uintptr(unsafe.Pointer(&x)), t)
-
-	x1 := T2{T2inner{2, 3}, 17}
-	check2ndField(x1, uintptr(unsafe.Pointer(&x1.f))-uintptr(unsafe.Pointer(&x1)), t)
-}
-
-func Nil(a interface{}, t *testing.T) {
-	n := ValueOf(a).Field(0)
-	if !n.IsNil() {
-		t.Errorf("%v should be nil", a)
-	}
-}
-
-func NotNil(a interface{}, t *testing.T) {
-	n := ValueOf(a).Field(0)
-	if n.IsNil() {
-		t.Errorf("value of type %v should not be nil", ValueOf(a).Type().String())
-	}
-}
-
-func TestIsNil(t *testing.T) {
-	// These implement IsNil.
-	// Wrap in extra struct to hide interface type.
-	doNil := []interface{}{
-		struct{ x *int }{},
-		struct{ x interface{} }{},
-		struct{ x map[string]int }{},
-		struct{ x func() bool }{},
-		struct{ x chan int }{},
-		struct{ x []string }{},
-	}
-	for _, ts := range doNil {
-		ty := TypeOf(ts).Field(0).Type
-		v := Zero(ty)
-		v.IsNil() // panics if not okay to call
-	}
-
-	// Check the implementations
-	var pi struct {
-		x *int
-	}
-	Nil(pi, t)
-	pi.x = new(int)
-	NotNil(pi, t)
-
-	var si struct {
-		x []int
-	}
-	Nil(si, t)
-	si.x = make([]int, 10)
-	NotNil(si, t)
-
-	var ci struct {
-		x chan int
-	}
-	Nil(ci, t)
-	ci.x = make(chan int)
-	NotNil(ci, t)
-
-	var mi struct {
-		x map[int]int
-	}
-	Nil(mi, t)
-	mi.x = make(map[int]int)
-	NotNil(mi, t)
-
-	var ii struct {
-		x interface{}
-	}
-	Nil(ii, t)
-	ii.x = 2
-	NotNil(ii, t)
-
-	var fi struct {
-		x func(t *testing.T)
-	}
-	Nil(fi, t)
-	fi.x = TestIsNil
-	NotNil(fi, t)
-}
-
-func TestInterfaceExtraction(t *testing.T) {
-	var s struct {
-		W io.Writer
-	}
-
-	s.W = os.Stdout
-	v := Indirect(ValueOf(&s)).Field(0).Interface()
-	if v != s.W.(interface{}) {
-		t.Error("Interface() on interface: ", v, s.W)
-	}
-}
-
-func TestNilPtrValueSub(t *testing.T) {
-	var pi *int
-	if pv := ValueOf(pi); pv.Elem().IsValid() {
-		t.Error("ValueOf((*int)(nil)).Elem().IsValid()")
-	}
-}
-
-func TestMap(t *testing.T) {
-	m := map[string]int{"a": 1, "b": 2}
-	mv := ValueOf(m)
-	if n := mv.Len(); n != len(m) {
-		t.Errorf("Len = %d, want %d", n, len(m))
-	}
-	keys := mv.MapKeys()
-	newmap := MakeMap(mv.Type())
-	for k, v := range m {
-		// Check that returned Keys match keys in range.
-		// These aren't required to be in the same order.
-		seen := false
-		for _, kv := range keys {
-			if kv.String() == k {
-				seen = true
-				break
-			}
-		}
-		if !seen {
-			t.Errorf("Missing key %q", k)
-		}
-
-		// Check that value lookup is correct.
-		vv := mv.MapIndex(ValueOf(k))
-		if vi := vv.Int(); vi != int64(v) {
-			t.Errorf("Key %q: have value %d, want %d", k, vi, v)
-		}
-
-		// Copy into new map.
-		newmap.SetMapIndex(ValueOf(k), ValueOf(v))
-	}
-	vv := mv.MapIndex(ValueOf("not-present"))
-	if vv.IsValid() {
-		t.Errorf("Invalid key: got non-nil value %s", valueToString(vv))
-	}
-
-	newm := newmap.Interface().(map[string]int)
-	if len(newm) != len(m) {
-		t.Errorf("length after copy: newm=%d, m=%d", len(newm), len(m))
-	}
-
-	for k, v := range newm {
-		mv, ok := m[k]
-		if mv != v {
-			t.Errorf("newm[%q] = %d, but m[%q] = %d, %v", k, v, k, mv, ok)
-		}
-	}
-
-	newmap.SetMapIndex(ValueOf("a"), Value{})
-	v, ok := newm["a"]
-	if ok {
-		t.Errorf("newm[\"a\"] = %d after delete", v)
-	}
-
-	mv = ValueOf(&m).Elem()
-	mv.Set(Zero(mv.Type()))
-	if m != nil {
-		t.Errorf("mv.Set(nil) failed")
-	}
-}
-
-func TestNilMap(t *testing.T) {
-	var m map[string]int
-	mv := ValueOf(m)
-	keys := mv.MapKeys()
-	if len(keys) != 0 {
-		t.Errorf(">0 keys for nil map: %v", keys)
-	}
-
-	// Check that value for missing key is zero.
-	x := mv.MapIndex(ValueOf("hello"))
-	if x.Kind() != Invalid {
-		t.Errorf("m.MapIndex(\"hello\") for nil map = %v, want Invalid Value", x)
-	}
-
-	// Check big value too.
-	var mbig map[string][10 << 20]byte
-	x = ValueOf(mbig).MapIndex(ValueOf("hello"))
-	if x.Kind() != Invalid {
-		t.Errorf("mbig.MapIndex(\"hello\") for nil map = %v, want Invalid Value", x)
-	}
-
-	// Test that deletes from a nil map succeed.
-	mv.SetMapIndex(ValueOf("hi"), Value{})
-}
-
-func TestChan(t *testing.T) {
-	for loop := 0; loop < 2; loop++ {
-		var c chan int
-		var cv Value
-
-		// check both ways to allocate channels
-		switch loop {
-		case 1:
-			c = make(chan int, 1)
-			cv = ValueOf(c)
-		case 0:
-			cv = MakeChan(TypeOf(c), 1)
-			c = cv.Interface().(chan int)
-		}
-
-		// Send
-		cv.Send(ValueOf(2))
-		if i := <-c; i != 2 {
-			t.Errorf("reflect Send 2, native recv %d", i)
-		}
-
-		// Recv
-		c <- 3
-		if i, ok := cv.Recv(); i.Int() != 3 || !ok {
-			t.Errorf("native send 3, reflect Recv %d, %t", i.Int(), ok)
-		}
-
-		// TryRecv fail
-		val, ok := cv.TryRecv()
-		if val.IsValid() || ok {
-			t.Errorf("TryRecv on empty chan: %s, %t", valueToString(val), ok)
-		}
-
-		// TryRecv success
-		c <- 4
-		val, ok = cv.TryRecv()
-		if !val.IsValid() {
-			t.Errorf("TryRecv on ready chan got nil")
-		} else if i := val.Int(); i != 4 || !ok {
-			t.Errorf("native send 4, TryRecv %d, %t", i, ok)
-		}
-
-		// TrySend fail
-		c <- 100
-		ok = cv.TrySend(ValueOf(5))
-		i := <-c
-		if ok {
-			t.Errorf("TrySend on full chan succeeded: value %d", i)
-		}
-
-		// TrySend success
-		ok = cv.TrySend(ValueOf(6))
-		if !ok {
-			t.Errorf("TrySend on empty chan failed")
-		} else {
-			if i = <-c; i != 6 {
-				t.Errorf("TrySend 6, recv %d", i)
-			}
-		}
-
-		// Close
-		c <- 123
-		cv.Close()
-		if i, ok := cv.Recv(); i.Int() != 123 || !ok {
-			t.Errorf("send 123 then close; Recv %d, %t", i.Int(), ok)
-		}
-		if i, ok := cv.Recv(); i.Int() != 0 || ok {
-			t.Errorf("after close Recv %d, %t", i.Int(), ok)
-		}
-	}
-
-	// check creation of unbuffered channel
-	var c chan int
-	cv := MakeChan(TypeOf(c), 0)
-	c = cv.Interface().(chan int)
-	if cv.TrySend(ValueOf(7)) {
-		t.Errorf("TrySend on sync chan succeeded")
-	}
-	if v, ok := cv.TryRecv(); v.IsValid() || ok {
-		t.Errorf("TryRecv on sync chan succeeded: isvalid=%v ok=%v", v.IsValid(), ok)
-	}
-
-	// len/cap
-	cv = MakeChan(TypeOf(c), 10)
-	c = cv.Interface().(chan int)
-	for i := 0; i < 3; i++ {
-		c <- i
-	}
-	if l, m := cv.Len(), cv.Cap(); l != len(c) || m != cap(c) {
-		t.Errorf("Len/Cap = %d/%d want %d/%d", l, m, len(c), cap(c))
-	}
-}
-
-// caseInfo describes a single case in a select test.
-type caseInfo struct {
-	desc      string
-	canSelect bool
-	recv      Value
-	closed    bool
-	helper    func()
-	panic     bool
-}
-
-var allselect = flag.Bool("allselect", false, "exhaustive select test")
-
-func TestSelect(t *testing.T) {
-	selectWatch.once.Do(func() { go selectWatcher() })
-
-	var x exhaustive
-	nch := 0
-	newop := func(n int, cap int) (ch, val Value) {
-		nch++
-		if nch%101%2 == 1 {
-			c := make(chan int, cap)
-			ch = ValueOf(c)
-			val = ValueOf(n)
-		} else {
-			c := make(chan string, cap)
-			ch = ValueOf(c)
-			val = ValueOf(fmt.Sprint(n))
-		}
-		return
-	}
-
-	for n := 0; x.Next(); n++ {
-		if testing.Short() && n >= 1000 {
-			break
-		}
-		if n >= 100000 && !*allselect {
-			break
-		}
-		if n%100000 == 0 && testing.Verbose() {
-			println("TestSelect", n)
-		}
-		var cases []SelectCase
-		var info []caseInfo
-
-		// Ready send.
-		if x.Maybe() {
-			ch, val := newop(len(cases), 1)
-			cases = append(cases, SelectCase{
-				Dir:  SelectSend,
-				Chan: ch,
-				Send: val,
-			})
-			info = append(info, caseInfo{desc: "ready send", canSelect: true})
-		}
-
-		// Ready recv.
-		if x.Maybe() {
-			ch, val := newop(len(cases), 1)
-			ch.Send(val)
-			cases = append(cases, SelectCase{
-				Dir:  SelectRecv,
-				Chan: ch,
-			})
-			info = append(info, caseInfo{desc: "ready recv", canSelect: true, recv: val})
-		}
-
-		// Blocking send.
-		if x.Maybe() {
-			ch, val := newop(len(cases), 0)
-			cases = append(cases, SelectCase{
-				Dir:  SelectSend,
-				Chan: ch,
-				Send: val,
-			})
-			// Let it execute?
-			if x.Maybe() {
-				f := func() { ch.Recv() }
-				info = append(info, caseInfo{desc: "blocking send", helper: f})
-			} else {
-				info = append(info, caseInfo{desc: "blocking send"})
-			}
-		}
-
-		// Blocking recv.
-		if x.Maybe() {
-			ch, val := newop(len(cases), 0)
-			cases = append(cases, SelectCase{
-				Dir:  SelectRecv,
-				Chan: ch,
-			})
-			// Let it execute?
-			if x.Maybe() {
-				f := func() { ch.Send(val) }
-				info = append(info, caseInfo{desc: "blocking recv", recv: val, helper: f})
-			} else {
-				info = append(info, caseInfo{desc: "blocking recv"})
-			}
-		}
-
-		// Zero Chan send.
-		if x.Maybe() {
-			// Maybe include value to send.
-			var val Value
-			if x.Maybe() {
-				val = ValueOf(100)
-			}
-			cases = append(cases, SelectCase{
-				Dir:  SelectSend,
-				Send: val,
-			})
-			info = append(info, caseInfo{desc: "zero Chan send"})
-		}
-
-		// Zero Chan receive.
-		if x.Maybe() {
-			cases = append(cases, SelectCase{
-				Dir: SelectRecv,
-			})
-			info = append(info, caseInfo{desc: "zero Chan recv"})
-		}
-
-		// nil Chan send.
-		if x.Maybe() {
-			cases = append(cases, SelectCase{
-				Dir:  SelectSend,
-				Chan: ValueOf((chan int)(nil)),
-				Send: ValueOf(101),
-			})
-			info = append(info, caseInfo{desc: "nil Chan send"})
-		}
-
-		// nil Chan recv.
-		if x.Maybe() {
-			cases = append(cases, SelectCase{
-				Dir:  SelectRecv,
-				Chan: ValueOf((chan int)(nil)),
-			})
-			info = append(info, caseInfo{desc: "nil Chan recv"})
-		}
-
-		// closed Chan send.
-		if x.Maybe() {
-			ch := make(chan int)
-			close(ch)
-			cases = append(cases, SelectCase{
-				Dir:  SelectSend,
-				Chan: ValueOf(ch),
-				Send: ValueOf(101),
-			})
-			info = append(info, caseInfo{desc: "closed Chan send", canSelect: true, panic: true})
-		}
-
-		// closed Chan recv.
-		if x.Maybe() {
-			ch, val := newop(len(cases), 0)
-			ch.Close()
-			val = Zero(val.Type())
-			cases = append(cases, SelectCase{
-				Dir:  SelectRecv,
-				Chan: ch,
-			})
-			info = append(info, caseInfo{desc: "closed Chan recv", canSelect: true, closed: true, recv: val})
-		}
-
-		var helper func() // goroutine to help the select complete
-
-		// Add default? Must be last case here, but will permute.
-		// Add the default if the select would otherwise
-		// block forever, and maybe add it anyway.
-		numCanSelect := 0
-		canProceed := false
-		canBlock := true
-		canPanic := false
-		helpers := []int{}
-		for i, c := range info {
-			if c.canSelect {
-				canProceed = true
-				canBlock = false
-				numCanSelect++
-				if c.panic {
-					canPanic = true
-				}
-			} else if c.helper != nil {
-				canProceed = true
-				helpers = append(helpers, i)
-			}
-		}
-		if !canProceed || x.Maybe() {
-			cases = append(cases, SelectCase{
-				Dir: SelectDefault,
-			})
-			info = append(info, caseInfo{desc: "default", canSelect: canBlock})
-			numCanSelect++
-		} else if canBlock {
-			// Select needs to communicate with another goroutine.
-			cas := &info[helpers[x.Choose(len(helpers))]]
-			helper = cas.helper
-			cas.canSelect = true
-			numCanSelect++
-		}
-
-		// Permute cases and case info.
-		// Doing too much here makes the exhaustive loop
-		// too exhausting, so just do two swaps.
-		for loop := 0; loop < 2; loop++ {
-			i := x.Choose(len(cases))
-			j := x.Choose(len(cases))
-			cases[i], cases[j] = cases[j], cases[i]
-			info[i], info[j] = info[j], info[i]
-		}
-
-		if helper != nil {
-			// We wait before kicking off a goroutine to satisfy a blocked select.
-			// The pause needs to be big enough to let the select block before
-			// we run the helper, but if we lose that race once in a while it's okay: the
-			// select will just proceed immediately. Not a big deal.
-			// For short tests we can grow [sic] the timeout a bit without fear of taking too long
-			pause := 10 * time.Microsecond
-			if testing.Short() {
-				pause = 100 * time.Microsecond
-			}
-			time.AfterFunc(pause, helper)
-		}
-
-		// Run select.
-		i, recv, recvOK, panicErr := runSelect(cases, info)
-		if panicErr != nil && !canPanic {
-			t.Fatalf("%s\npanicked unexpectedly: %v", fmtSelect(info), panicErr)
-		}
-		if panicErr == nil && canPanic && numCanSelect == 1 {
-			t.Fatalf("%s\nselected #%d incorrectly (should panic)", fmtSelect(info), i)
-		}
-		if panicErr != nil {
-			continue
-		}
-
-		cas := info[i]
-		if !cas.canSelect {
-			recvStr := ""
-			if recv.IsValid() {
-				recvStr = fmt.Sprintf(", received %v, %v", recv.Interface(), recvOK)
-			}
-			t.Fatalf("%s\nselected #%d incorrectly%s", fmtSelect(info), i, recvStr)
-			continue
-		}
-		if cas.panic {
-			t.Fatalf("%s\nselected #%d incorrectly (case should panic)", fmtSelect(info), i)
-			continue
-		}
-
-		if cases[i].Dir == SelectRecv {
-			if !recv.IsValid() {
-				t.Fatalf("%s\nselected #%d but got %v, %v, want %v, %v", fmtSelect(info), i, recv, recvOK, cas.recv.Interface(), !cas.closed)
-			}
-			if !cas.recv.IsValid() {
-				t.Fatalf("%s\nselected #%d but internal error: missing recv value", fmtSelect(info), i)
-			}
-			if recv.Interface() != cas.recv.Interface() || recvOK != !cas.closed {
-				if recv.Interface() == cas.recv.Interface() && recvOK == !cas.closed {
-					t.Fatalf("%s\nselected #%d, got %#v, %v, and DeepEqual is broken on %T", fmtSelect(info), i, recv.Interface(), recvOK, recv.Interface())
-				}
-				t.Fatalf("%s\nselected #%d but got %#v, %v, want %#v, %v", fmtSelect(info), i, recv.Interface(), recvOK, cas.recv.Interface(), !cas.closed)
-			}
-		} else {
-			if recv.IsValid() || recvOK {
-				t.Fatalf("%s\nselected #%d but got %v, %v, want %v, %v", fmtSelect(info), i, recv, recvOK, Value{}, false)
-			}
-		}
-	}
-}
-
-// selectWatch and the selectWatcher are a watchdog mechanism for running Select.
-// If the selectWatcher notices that the select has been blocked for >1 second, it prints
-// an error describing the select and panics the entire test binary.
-var selectWatch struct {
-	sync.Mutex
-	once sync.Once
-	now  time.Time
-	info []caseInfo
-}
-
-func selectWatcher() {
-	for {
-		time.Sleep(1 * time.Second)
-		selectWatch.Lock()
-		if selectWatch.info != nil && time.Since(selectWatch.now) > 1*time.Second {
-			fmt.Fprintf(os.Stderr, "TestSelect:\n%s blocked indefinitely\n", fmtSelect(selectWatch.info))
-			panic("select stuck")
-		}
-		selectWatch.Unlock()
-	}
-}
-
-// runSelect runs a single select test.
-// It returns the values returned by Select but also returns
-// a panic value if the Select panics.
-func runSelect(cases []SelectCase, info []caseInfo) (chosen int, recv Value, recvOK bool, panicErr interface{}) {
-	defer func() {
-		panicErr = recover()
-
-		selectWatch.Lock()
-		selectWatch.info = nil
-		selectWatch.Unlock()
-	}()
-
-	selectWatch.Lock()
-	selectWatch.now = time.Now()
-	selectWatch.info = info
-	selectWatch.Unlock()
-
-	chosen, recv, recvOK = Select(cases)
-	return
-}
-
-// fmtSelect formats the information about a single select test.
-func fmtSelect(info []caseInfo) string {
-	var buf bytes.Buffer
-	fmt.Fprintf(&buf, "\nselect {\n")
-	for i, cas := range info {
-		fmt.Fprintf(&buf, "%d: %s", i, cas.desc)
-		if cas.recv.IsValid() {
-			fmt.Fprintf(&buf, " val=%#v", cas.recv.Interface())
-		}
-		if cas.canSelect {
-			fmt.Fprintf(&buf, " canselect")
-		}
-		if cas.panic {
-			fmt.Fprintf(&buf, " panic")
-		}
-		fmt.Fprintf(&buf, "\n")
-	}
-	fmt.Fprintf(&buf, "}")
-	return buf.String()
-}
-
-type two [2]uintptr
-
-// Difficult test for function call because of
-// implicit padding between arguments.
-func dummy(b byte, c int, d byte, e two, f byte, g float32, h byte) (i byte, j int, k byte, l two, m byte, n float32, o byte) {
-	return b, c, d, e, f, g, h
-}
-
-func TestFunc(t *testing.T) {
-	ret := ValueOf(dummy).Call([]Value{
-		ValueOf(byte(10)),
-		ValueOf(20),
-		ValueOf(byte(30)),
-		ValueOf(two{40, 50}),
-		ValueOf(byte(60)),
-		ValueOf(float32(70)),
-		ValueOf(byte(80)),
-	})
-	if len(ret) != 7 {
-		t.Fatalf("Call returned %d values, want 7", len(ret))
-	}
-
-	i := byte(ret[0].Uint())
-	j := int(ret[1].Int())
-	k := byte(ret[2].Uint())
-	l := ret[3].Interface().(two)
-	m := byte(ret[4].Uint())
-	n := float32(ret[5].Float())
-	o := byte(ret[6].Uint())
-
-	if i != 10 || j != 20 || k != 30 || l != (two{40, 50}) || m != 60 || n != 70 || o != 80 {
-		t.Errorf("Call returned %d, %d, %d, %v, %d, %g, %d; want 10, 20, 30, [40, 50], 60, 70, 80", i, j, k, l, m, n, o)
-	}
-}
-
-type emptyStruct struct{}
-
-type nonEmptyStruct struct {
-	member int
-}
-
-func returnEmpty() emptyStruct {
-	return emptyStruct{}
-}
-
-func takesEmpty(e emptyStruct) {
-}
-
-func returnNonEmpty(i int) nonEmptyStruct {
-	return nonEmptyStruct{member: i}
-}
-
-func takesNonEmpty(n nonEmptyStruct) int {
-	return n.member
-}
-
-func TestCallWithStruct(t *testing.T) {
-	r := ValueOf(returnEmpty).Call(nil)
-	if len(r) != 1 || r[0].Type() != TypeOf(emptyStruct{}) {
-		t.Errorf("returning empty struct returned %#v instead", r)
-	}
-	r = ValueOf(takesEmpty).Call([]Value{ValueOf(emptyStruct{})})
-	if len(r) != 0 {
-		t.Errorf("takesEmpty returned values: %#v", r)
-	}
-	r = ValueOf(returnNonEmpty).Call([]Value{ValueOf(42)})
-	if len(r) != 1 || r[0].Type() != TypeOf(nonEmptyStruct{}) || r[0].Field(0).Int() != 42 {
-		t.Errorf("returnNonEmpty returned %#v", r)
-	}
-	r = ValueOf(takesNonEmpty).Call([]Value{ValueOf(nonEmptyStruct{member: 42})})
-	if len(r) != 1 || r[0].Type() != TypeOf(1) || r[0].Int() != 42 {
-		t.Errorf("takesNonEmpty returned %#v", r)
-	}
-}
-
-func TestMakeFunc(t *testing.T) {
-	f := dummy
-	fv := MakeFunc(TypeOf(f), func(in []Value) []Value { return in })
-	ValueOf(&f).Elem().Set(fv)
-
-	// Call g with small arguments so that there is
-	// something predictable (and different from the
-	// correct results) in those positions on the stack.
-	g := dummy
-	g(1, 2, 3, two{4, 5}, 6, 7, 8)
-
-	// Call constructed function f.
-	i, j, k, l, m, n, o := f(10, 20, 30, two{40, 50}, 60, 70, 80)
-	if i != 10 || j != 20 || k != 30 || l != (two{40, 50}) || m != 60 || n != 70 || o != 80 {
-		t.Errorf("Call returned %d, %d, %d, %v, %d, %g, %d; want 10, 20, 30, [40, 50], 60, 70, 80", i, j, k, l, m, n, o)
-	}
-}
-
-func TestMakeFuncInterface(t *testing.T) {
-	fn := func(i int) int { return i }
-	incr := func(in []Value) []Value {
-		return []Value{ValueOf(int(in[0].Int() + 1))}
-	}
-	fv := MakeFunc(TypeOf(fn), incr)
-	ValueOf(&fn).Elem().Set(fv)
-	if r := fn(2); r != 3 {
-		t.Errorf("Call returned %d, want 3", r)
-	}
-	if r := fv.Call([]Value{ValueOf(14)})[0].Int(); r != 15 {
-		t.Errorf("Call returned %d, want 15", r)
-	}
-	if r := fv.Interface().(func(int) int)(26); r != 27 {
-		t.Errorf("Call returned %d, want 27", r)
-	}
-}
-
-func TestMakeFuncVariadic(t *testing.T) {
-	// Test that variadic arguments are packed into a slice and passed as last arg
-	fn := func(_ int, is ...int) []int { return nil }
-	fv := MakeFunc(TypeOf(fn), func(in []Value) []Value { return in[1:2] })
-	ValueOf(&fn).Elem().Set(fv)
-
-	r := fv.Call([]Value{ValueOf(1), ValueOf(2), ValueOf(3)})[0].Interface().([]int)
-	if r[0] != 2 || r[1] != 3 {
-		t.Errorf("Call returned [%v, %v]; want 2, 3", r[0], r[1])
-	}
-
-	r = fv.CallSlice([]Value{ValueOf(1), ValueOf([]int{2, 3})})[0].Interface().([]int)
-	if r[0] != 2 || r[1] != 3 {
-		t.Errorf("Call returned [%v, %v]; want 2, 3", r[0], r[1])
-	}
-}
-
-type Point struct {
-	x, y int
-}
-
-// This will be index 0.
-func (p Point) AnotherMethod(scale int) int {
-	return -1
-}
-
-// This will be index 1.
-func (p Point) Dist(scale int) int {
-	//println("Point.Dist", p.x, p.y, scale)
-	return p.x*p.x*scale + p.y*p.y*scale
-}
-
-func TestMethod(t *testing.T) {
-	// Non-curried method of type.
-	p := Point{3, 4}
-	i := TypeOf(p).Method(1).Func.Call([]Value{ValueOf(p), ValueOf(10)})[0].Int()
-	if i != 250 {
-		t.Errorf("Type Method returned %d; want 250", i)
-	}
-
-	m, ok := TypeOf(p).MethodByName("Dist")
-	if !ok {
-		t.Fatalf("method by name failed")
-	}
-	i = m.Func.Call([]Value{ValueOf(p), ValueOf(11)})[0].Int()
-	if i != 275 {
-		t.Errorf("Type MethodByName returned %d; want 275", i)
-	}
-
-	i = TypeOf(&p).Method(1).Func.Call([]Value{ValueOf(&p), ValueOf(12)})[0].Int()
-	if i != 300 {
-		t.Errorf("Pointer Type Method returned %d; want 300", i)
-	}
-
-	m, ok = TypeOf(&p).MethodByName("Dist")
-	if !ok {
-		t.Fatalf("ptr method by name failed")
-	}
-	i = m.Func.Call([]Value{ValueOf(&p), ValueOf(13)})[0].Int()
-	if i != 325 {
-		t.Errorf("Pointer Type MethodByName returned %d; want 325", i)
-	}
-
-	// Curried method of value.
-	tfunc := TypeOf((func(int) int)(nil))
-	v := ValueOf(p).Method(1)
-	if tt := v.Type(); tt != tfunc {
-		t.Errorf("Value Method Type is %s; want %s", tt, tfunc)
-	}
-	i = v.Call([]Value{ValueOf(14)})[0].Int()
-	if i != 350 {
-		t.Errorf("Value Method returned %d; want 350", i)
-	}
-	v = ValueOf(p).MethodByName("Dist")
-	if tt := v.Type(); tt != tfunc {
-		t.Errorf("Value MethodByName Type is %s; want %s", tt, tfunc)
-	}
-	i = v.Call([]Value{ValueOf(15)})[0].Int()
-	if i != 375 {
-		t.Errorf("Value MethodByName returned %d; want 375", i)
-	}
-
-	// Curried method of pointer.
-	v = ValueOf(&p).Method(1)
-	if tt := v.Type(); tt != tfunc {
-		t.Errorf("Pointer Value Method Type is %s; want %s", tt, tfunc)
-	}
-	i = v.Call([]Value{ValueOf(16)})[0].Int()
-	if i != 400 {
-		t.Errorf("Pointer Value Method returned %d; want 400", i)
-	}
-	v = ValueOf(&p).MethodByName("Dist")
-	if tt := v.Type(); tt != tfunc {
-		t.Errorf("Pointer Value MethodByName Type is %s; want %s", tt, tfunc)
-	}
-	i = v.Call([]Value{ValueOf(17)})[0].Int()
-	if i != 425 {
-		t.Errorf("Pointer Value MethodByName returned %d; want 425", i)
-	}
-
-	// Curried method of interface value.
-	// Have to wrap interface value in a struct to get at it.
-	// Passing it to ValueOf directly would
-	// access the underlying Point, not the interface.
-	var x interface {
-		Dist(int) int
-	} = p
-	pv := ValueOf(&x).Elem()
-	v = pv.Method(0)
-	if tt := v.Type(); tt != tfunc {
-		t.Errorf("Interface Method Type is %s; want %s", tt, tfunc)
-	}
-	i = v.Call([]Value{ValueOf(18)})[0].Int()
-	if i != 450 {
-		t.Errorf("Interface Method returned %d; want 450", i)
-	}
-	v = pv.MethodByName("Dist")
-	if tt := v.Type(); tt != tfunc {
-		t.Errorf("Interface MethodByName Type is %s; want %s", tt, tfunc)
-	}
-	i = v.Call([]Value{ValueOf(19)})[0].Int()
-	if i != 475 {
-		t.Errorf("Interface MethodByName returned %d; want 475", i)
-	}
-}
-
-func TestMethodValue(t *testing.T) {
-	p := Point{3, 4}
-	var i int64
-
-	// Curried method of value.
-	tfunc := TypeOf((func(int) int)(nil))
-	v := ValueOf(p).Method(1)
-	if tt := v.Type(); tt != tfunc {
-		t.Errorf("Value Method Type is %s; want %s", tt, tfunc)
-	}
-	i = ValueOf(v.Interface()).Call([]Value{ValueOf(10)})[0].Int()
-	if i != 250 {
-		t.Errorf("Value Method returned %d; want 250", i)
-	}
-	v = ValueOf(p).MethodByName("Dist")
-	if tt := v.Type(); tt != tfunc {
-		t.Errorf("Value MethodByName Type is %s; want %s", tt, tfunc)
-	}
-	i = ValueOf(v.Interface()).Call([]Value{ValueOf(11)})[0].Int()
-	if i != 275 {
-		t.Errorf("Value MethodByName returned %d; want 275", i)
-	}
-
-	// Curried method of pointer.
-	v = ValueOf(&p).Method(1)
-	if tt := v.Type(); tt != tfunc {
-		t.Errorf("Pointer Value Method Type is %s; want %s", tt, tfunc)
-	}
-	i = ValueOf(v.Interface()).Call([]Value{ValueOf(12)})[0].Int()
-	if i != 300 {
-		t.Errorf("Pointer Value Method returned %d; want 300", i)
-	}
-	v = ValueOf(&p).MethodByName("Dist")
-	if tt := v.Type(); tt != tfunc {
-		t.Errorf("Pointer Value MethodByName Type is %s; want %s", tt, tfunc)
-	}
-	i = ValueOf(v.Interface()).Call([]Value{ValueOf(13)})[0].Int()
-	if i != 325 {
-		t.Errorf("Pointer Value MethodByName returned %d; want 325", i)
-	}
-
-	// Curried method of pointer to pointer.
-	pp := &p
-	v = ValueOf(&pp).Elem().Method(1)
-	if tt := v.Type(); tt != tfunc {
-		t.Errorf("Pointer Pointer Value Method Type is %s; want %s", tt, tfunc)
-	}
-	i = ValueOf(v.Interface()).Call([]Value{ValueOf(14)})[0].Int()
-	if i != 350 {
-		t.Errorf("Pointer Pointer Value Method returned %d; want 350", i)
-	}
-	v = ValueOf(&pp).Elem().MethodByName("Dist")
-	if tt := v.Type(); tt != tfunc {
-		t.Errorf("Pointer Pointer Value MethodByName Type is %s; want %s", tt, tfunc)
-	}
-	i = ValueOf(v.Interface()).Call([]Value{ValueOf(15)})[0].Int()
-	if i != 375 {
-		t.Errorf("Pointer Pointer Value MethodByName returned %d; want 375", i)
-	}
-
-	// Curried method of interface value.
-	// Have to wrap interface value in a struct to get at it.
-	// Passing it to ValueOf directly would
-	// access the underlying Point, not the interface.
-	var s = struct {
-		X interface {
-			Dist(int) int
-		}
-	}{p}
-	pv := ValueOf(s).Field(0)
-	v = pv.Method(0)
-	if tt := v.Type(); tt != tfunc {
-		t.Errorf("Interface Method Type is %s; want %s", tt, tfunc)
-	}
-	i = ValueOf(v.Interface()).Call([]Value{ValueOf(16)})[0].Int()
-	if i != 400 {
-		t.Errorf("Interface Method returned %d; want 400", i)
-	}
-	v = pv.MethodByName("Dist")
-	if tt := v.Type(); tt != tfunc {
-		t.Errorf("Interface MethodByName Type is %s; want %s", tt, tfunc)
-	}
-	i = ValueOf(v.Interface()).Call([]Value{ValueOf(17)})[0].Int()
-	if i != 425 {
-		t.Errorf("Interface MethodByName returned %d; want 425", i)
-	}
-}
-
-// Reflect version of $GOROOT/test/method5.go
-
-// Concrete types implementing M method.
-// Smaller than a word, word-sized, larger than a word.
-// Value and pointer receivers.
-
-type Tinter interface {
-	M(int, byte) (byte, int)
-}
-
-type Tsmallv byte
-
-func (v Tsmallv) M(x int, b byte) (byte, int) { return b, x + int(v) }
-
-type Tsmallp byte
-
-func (p *Tsmallp) M(x int, b byte) (byte, int) { return b, x + int(*p) }
-
-type Twordv uintptr
-
-func (v Twordv) M(x int, b byte) (byte, int) { return b, x + int(v) }
-
-type Twordp uintptr
-
-func (p *Twordp) M(x int, b byte) (byte, int) { return b, x + int(*p) }
-
-type Tbigv [2]uintptr
-
-func (v Tbigv) M(x int, b byte) (byte, int) { return b, x + int(v[0]) + int(v[1]) }
-
-type Tbigp [2]uintptr
-
-func (p *Tbigp) M(x int, b byte) (byte, int) { return b, x + int(p[0]) + int(p[1]) }
-
-// Again, with an unexported method.
-
-type tsmallv byte
-
-func (v tsmallv) m(x int, b byte) (byte, int) { return b, x + int(v) }
-
-type tsmallp byte
-
-func (p *tsmallp) m(x int, b byte) (byte, int) { return b, x + int(*p) }
-
-type twordv uintptr
-
-func (v twordv) m(x int, b byte) (byte, int) { return b, x + int(v) }
-
-type twordp uintptr
-
-func (p *twordp) m(x int, b byte) (byte, int) { return b, x + int(*p) }
-
-type tbigv [2]uintptr
-
-func (v tbigv) m(x int, b byte) (byte, int) { return b, x + int(v[0]) + int(v[1]) }
-
-type tbigp [2]uintptr
-
-func (p *tbigp) m(x int, b byte) (byte, int) { return b, x + int(p[0]) + int(p[1]) }
-
-type tinter interface {
-	m(int, byte) (byte, int)
-}
-
-// Embedding via pointer.
-
-type Tm1 struct {
-	Tm2
-}
-
-type Tm2 struct {
-	*Tm3
-}
-
-type Tm3 struct {
-	*Tm4
-}
-
-type Tm4 struct {
-}
-
-func (t4 Tm4) M(x int, b byte) (byte, int) { return b, x + 40 }
-
-func TestMethod5(t *testing.T) {
-	CheckF := func(name string, f func(int, byte) (byte, int), inc int) {
-		b, x := f(1000, 99)
-		if b != 99 || x != 1000+inc {
-			t.Errorf("%s(1000, 99) = %v, %v, want 99, %v", name, b, x, 1000+inc)
-		}
-	}
-
-	CheckV := func(name string, i Value, inc int) {
-		bx := i.Method(0).Call([]Value{ValueOf(1000), ValueOf(byte(99))})
-		b := bx[0].Interface()
-		x := bx[1].Interface()
-		if b != byte(99) || x != 1000+inc {
-			t.Errorf("direct %s.M(1000, 99) = %v, %v, want 99, %v", name, b, x, 1000+inc)
-		}
-
-		CheckF(name+".M", i.Method(0).Interface().(func(int, byte) (byte, int)), inc)
-	}
-
-	var TinterType = TypeOf(new(Tinter)).Elem()
-	var tinterType = TypeOf(new(tinter)).Elem()
-
-	CheckI := func(name string, i interface{}, inc int) {
-		v := ValueOf(i)
-		CheckV(name, v, inc)
-		CheckV("(i="+name+")", v.Convert(TinterType), inc)
-	}
-
-	sv := Tsmallv(1)
-	CheckI("sv", sv, 1)
-	CheckI("&sv", &sv, 1)
-
-	sp := Tsmallp(2)
-	CheckI("&sp", &sp, 2)
-
-	wv := Twordv(3)
-	CheckI("wv", wv, 3)
-	CheckI("&wv", &wv, 3)
-
-	wp := Twordp(4)
-	CheckI("&wp", &wp, 4)
-
-	bv := Tbigv([2]uintptr{5, 6})
-	CheckI("bv", bv, 11)
-	CheckI("&bv", &bv, 11)
-
-	bp := Tbigp([2]uintptr{7, 8})
-	CheckI("&bp", &bp, 15)
-
-	t4 := Tm4{}
-	t3 := Tm3{&t4}
-	t2 := Tm2{&t3}
-	t1 := Tm1{t2}
-	CheckI("t4", t4, 40)
-	CheckI("&t4", &t4, 40)
-	CheckI("t3", t3, 40)
-	CheckI("&t3", &t3, 40)
-	CheckI("t2", t2, 40)
-	CheckI("&t2", &t2, 40)
-	CheckI("t1", t1, 40)
-	CheckI("&t1", &t1, 40)
-
-	methodShouldPanic := func(name string, i interface{}) {
-		v := ValueOf(i)
-		m := v.Method(0)
-		shouldPanic(func() { m.Call([]Value{ValueOf(1000), ValueOf(byte(99))}) })
-		shouldPanic(func() { m.Interface() })
-
-		v = v.Convert(tinterType)
-		m = v.Method(0)
-		shouldPanic(func() { m.Call([]Value{ValueOf(1000), ValueOf(byte(99))}) })
-		shouldPanic(func() { m.Interface() })
-	}
-
-	_sv := tsmallv(1)
-	methodShouldPanic("_sv", _sv)
-	methodShouldPanic("&_sv", &_sv)
-
-	_sp := tsmallp(2)
-	methodShouldPanic("&_sp", &_sp)
-
-	_wv := twordv(3)
-	methodShouldPanic("_wv", _wv)
-	methodShouldPanic("&_wv", &_wv)
-
-	_wp := twordp(4)
-	methodShouldPanic("&_wp", &_wp)
-
-	_bv := tbigv([2]uintptr{5, 6})
-	methodShouldPanic("_bv", _bv)
-	methodShouldPanic("&_bv", &_bv)
-
-	_bp := tbigp([2]uintptr{7, 8})
-	methodShouldPanic("&_bp", &_bp)
-
-	var tnil Tinter
-	vnil := ValueOf(&tnil).Elem()
-	shouldPanic(func() { vnil.Method(0) })
-}
-
-func TestInterfaceSet(t *testing.T) {
-	p := &Point{3, 4}
-
-	var s struct {
-		I interface{}
-		P interface {
-			Dist(int) int
-		}
-	}
-	sv := ValueOf(&s).Elem()
-	sv.Field(0).Set(ValueOf(p))
-	if q := s.I.(*Point); q != p {
-		t.Errorf("i: have %p want %p", q, p)
-	}
-
-	pv := sv.Field(1)
-	pv.Set(ValueOf(p))
-	if q := s.P.(*Point); q != p {
-		t.Errorf("i: have %p want %p", q, p)
-	}
-
-	i := pv.Method(0).Call([]Value{ValueOf(10)})[0].Int()
-	if i != 250 {
-		t.Errorf("Interface Method returned %d; want 250", i)
-	}
-}
-
-type T1 struct {
-	a string
-	int
-}
-
-func TestAnonymousFields(t *testing.T) {
-	var field StructField
-	var ok bool
-	var t1 T1
-	type1 := TypeOf(t1)
-	if field, ok = type1.FieldByName("int"); !ok {
-		t.Fatal("no field 'int'")
-	}
-	if field.Index[0] != 1 {
-		t.Error("field index should be 1; is", field.Index)
-	}
-}
-
-type FTest struct {
-	s     interface{}
-	name  string
-	index []int
-	value int
-}
-
-type D1 struct {
-	d int
-}
-type D2 struct {
-	d int
-}
-
-type S0 struct {
-	A, B, C int
-	D1
-	D2
-}
-
-type S1 struct {
-	B int
-	S0
-}
-
-type S2 struct {
-	A int
-	*S1
-}
-
-type S1x struct {
-	S1
-}
-
-type S1y struct {
-	S1
-}
-
-type S3 struct {
-	S1x
-	S2
-	D, E int
-	*S1y
-}
-
-type S4 struct {
-	*S4
-	A int
-}
-
-// The X in S6 and S7 annihilate, but they also block the X in S8.S9.
-type S5 struct {
-	S6
-	S7
-	S8
-}
-
-type S6 struct {
-	X int
-}
-
-type S7 S6
-
-type S8 struct {
-	S9
-}
-
-type S9 struct {
-	X int
-	Y int
-}
-
-// The X in S11.S6 and S12.S6 annihilate, but they also block the X in S13.S8.S9.
-type S10 struct {
-	S11
-	S12
-	S13
-}
-
-type S11 struct {
-	S6
-}
-
-type S12 struct {
-	S6
-}
-
-type S13 struct {
-	S8
-}
-
-// The X in S15.S11.S1 and S16.S11.S1 annihilate.
-type S14 struct {
-	S15
-	S16
-}
-
-type S15 struct {
-	S11
-}
-
-type S16 struct {
-	S11
-}
-
-var fieldTests = []FTest{
-	{struct{}{}, "", nil, 0},
-	{struct{}{}, "Foo", nil, 0},
-	{S0{A: 'a'}, "A", []int{0}, 'a'},
-	{S0{}, "D", nil, 0},
-	{S1{S0: S0{A: 'a'}}, "A", []int{1, 0}, 'a'},
-	{S1{B: 'b'}, "B", []int{0}, 'b'},
-	{S1{}, "S0", []int{1}, 0},
-	{S1{S0: S0{C: 'c'}}, "C", []int{1, 2}, 'c'},
-	{S2{A: 'a'}, "A", []int{0}, 'a'},
-	{S2{}, "S1", []int{1}, 0},
-	{S2{S1: &S1{B: 'b'}}, "B", []int{1, 0}, 'b'},
-	{S2{S1: &S1{S0: S0{C: 'c'}}}, "C", []int{1, 1, 2}, 'c'},
-	{S2{}, "D", nil, 0},
-	{S3{}, "S1", nil, 0},
-	{S3{S2: S2{A: 'a'}}, "A", []int{1, 0}, 'a'},
-	{S3{}, "B", nil, 0},
-	{S3{D: 'd'}, "D", []int{2}, 0},
-	{S3{E: 'e'}, "E", []int{3}, 'e'},
-	{S4{A: 'a'}, "A", []int{1}, 'a'},
-	{S4{}, "B", nil, 0},
-	{S5{}, "X", nil, 0},
-	{S5{}, "Y", []int{2, 0, 1}, 0},
-	{S10{}, "X", nil, 0},
-	{S10{}, "Y", []int{2, 0, 0, 1}, 0},
-	{S14{}, "X", nil, 0},
-}
-
-func TestFieldByIndex(t *testing.T) {
-	for _, test := range fieldTests {
-		s := TypeOf(test.s)
-		f := s.FieldByIndex(test.index)
-		if f.Name != "" {
-			if test.index != nil {
-				if f.Name != test.name {
-					t.Errorf("%s.%s found; want %s", s.Name(), f.Name, test.name)
-				}
-			} else {
-				t.Errorf("%s.%s found", s.Name(), f.Name)
-			}
-		} else if len(test.index) > 0 {
-			t.Errorf("%s.%s not found", s.Name(), test.name)
-		}
-
-		if test.value != 0 {
-			v := ValueOf(test.s).FieldByIndex(test.index)
-			if v.IsValid() {
-				if x, ok := v.Interface().(int); ok {
-					if x != test.value {
-						t.Errorf("%s%v is %d; want %d", s.Name(), test.index, x, test.value)
-					}
-				} else {
-					t.Errorf("%s%v value not an int", s.Name(), test.index)
-				}
-			} else {
-				t.Errorf("%s%v value not found", s.Name(), test.index)
-			}
-		}
-	}
-}
-
-func TestFieldByName(t *testing.T) {
-	for _, test := range fieldTests {
-		s := TypeOf(test.s)
-		f, found := s.FieldByName(test.name)
-		if found {
-			if test.index != nil {
-				// Verify field depth and index.
-				if len(f.Index) != len(test.index) {
-					t.Errorf("%s.%s depth %d; want %d: %v vs %v", s.Name(), test.name, len(f.Index), len(test.index), f.Index, test.index)
-				} else {
-					for i, x := range f.Index {
-						if x != test.index[i] {
-							t.Errorf("%s.%s.Index[%d] is %d; want %d", s.Name(), test.name, i, x, test.index[i])
-						}
-					}
-				}
-			} else {
-				t.Errorf("%s.%s found", s.Name(), f.Name)
-			}
-		} else if len(test.index) > 0 {
-			t.Errorf("%s.%s not found", s.Name(), test.name)
-		}
-
-		if test.value != 0 {
-			v := ValueOf(test.s).FieldByName(test.name)
-			if v.IsValid() {
-				if x, ok := v.Interface().(int); ok {
-					if x != test.value {
-						t.Errorf("%s.%s is %d; want %d", s.Name(), test.name, x, test.value)
-					}
-				} else {
-					t.Errorf("%s.%s value not an int", s.Name(), test.name)
-				}
-			} else {
-				t.Errorf("%s.%s value not found", s.Name(), test.name)
-			}
-		}
-	}
-}
-
-func TestImportPath(t *testing.T) {
-	tests := []struct {
-		t    Type
-		path string
-	}{
-		{TypeOf(&base64.Encoding{}).Elem(), "encoding/base64"},
-		{TypeOf(int(0)), ""},
-		{TypeOf(int8(0)), ""},
-		{TypeOf(int16(0)), ""},
-		{TypeOf(int32(0)), ""},
-		{TypeOf(int64(0)), ""},
-		{TypeOf(uint(0)), ""},
-		{TypeOf(uint8(0)), ""},
-		{TypeOf(uint16(0)), ""},
-		{TypeOf(uint32(0)), ""},
-		{TypeOf(uint64(0)), ""},
-		{TypeOf(uintptr(0)), ""},
-		{TypeOf(float32(0)), ""},
-		{TypeOf(float64(0)), ""},
-		{TypeOf(complex64(0)), ""},
-		{TypeOf(complex128(0)), ""},
-		{TypeOf(byte(0)), ""},
-		{TypeOf(rune(0)), ""},
-		{TypeOf([]byte(nil)), ""},
-		{TypeOf([]rune(nil)), ""},
-		{TypeOf(string("")), ""},
-		{TypeOf((*interface{})(nil)).Elem(), ""},
-		{TypeOf((*byte)(nil)), ""},
-		{TypeOf((*rune)(nil)), ""},
-		{TypeOf((*int64)(nil)), ""},
-		{TypeOf(map[string]int{}), ""},
-		{TypeOf((*error)(nil)).Elem(), ""},
-	}
-	for _, test := range tests {
-		if path := test.t.PkgPath(); path != test.path {
-			t.Errorf("%v.PkgPath() = %q, want %q", test.t, path, test.path)
-		}
-	}
-}
-
-func TestVariadicType(t *testing.T) {
-	// Test example from Type documentation.
-	var f func(x int, y ...float64)
-	typ := TypeOf(f)
-	if typ.NumIn() == 2 && typ.In(0) == TypeOf(int(0)) {
-		sl := typ.In(1)
-		if sl.Kind() == Slice {
-			if sl.Elem() == TypeOf(0.0) {
-				// ok
-				return
-			}
-		}
-	}
-
-	// Failed
-	t.Errorf("want NumIn() = 2, In(0) = int, In(1) = []float64")
-	s := fmt.Sprintf("have NumIn() = %d", typ.NumIn())
-	for i := 0; i < typ.NumIn(); i++ {
-		s += fmt.Sprintf(", In(%d) = %s", i, typ.In(i))
-	}
-	t.Error(s)
-}
-
-type inner struct {
-	x int
-}
-
-type outer struct {
-	y int
-	inner
-}
-
-func (*inner) m() {}
-func (*outer) m() {}
-
-func TestNestedMethods(t *testing.T) {
-	typ := TypeOf((*outer)(nil))
-	if typ.NumMethod() != 1 || typ.Method(0).Func.Pointer() != ValueOf((*outer).m).Pointer() {
-		t.Errorf("Wrong method table for outer: (m=%p)", (*outer).m)
-		for i := 0; i < typ.NumMethod(); i++ {
-			m := typ.Method(i)
-			t.Errorf("\t%d: %s %#x\n", i, m.Name, m.Func.Pointer())
-		}
-	}
-}
-
-type InnerInt struct {
-	X int
-}
-
-type OuterInt struct {
-	Y int
-	InnerInt
-}
-
-func (i *InnerInt) M() int {
-	return i.X
-}
-
-func TestEmbeddedMethods(t *testing.T) {
-	typ := TypeOf((*OuterInt)(nil))
-	if typ.NumMethod() != 1 || typ.Method(0).Func.Pointer() != ValueOf((*OuterInt).M).Pointer() {
-		t.Errorf("Wrong method table for OuterInt: (m=%p)", (*OuterInt).M)
-		for i := 0; i < typ.NumMethod(); i++ {
-			m := typ.Method(i)
-			t.Errorf("\t%d: %s %#x\n", i, m.Name, m.Func.Pointer())
-		}
-	}
-
-	i := &InnerInt{3}
-	if v := ValueOf(i).Method(0).Call(nil)[0].Int(); v != 3 {
-		t.Errorf("i.M() = %d, want 3", v)
-	}
-
-	o := &OuterInt{1, InnerInt{2}}
-	if v := ValueOf(o).Method(0).Call(nil)[0].Int(); v != 2 {
-		t.Errorf("i.M() = %d, want 2", v)
-	}
-
-	f := (*OuterInt).M
-	if v := f(o); v != 2 {
-		t.Errorf("f(o) = %d, want 2", v)
-	}
-}
-
-func TestPtrTo(t *testing.T) {
-	var i int
-
-	typ := TypeOf(i)
-	for i = 0; i < 100; i++ {
-		typ = PtrTo(typ)
-	}
-	for i = 0; i < 100; i++ {
-		typ = typ.Elem()
-	}
-	if typ != TypeOf(i) {
-		t.Errorf("after 100 PtrTo and Elem, have %s, want %s", typ, TypeOf(i))
-	}
-}
-
-func TestPtrToGC(t *testing.T) {
-	type T *uintptr
-	tt := TypeOf(T(nil))
-	pt := PtrTo(tt)
-	const n = 100
-	var x []interface{}
-	for i := 0; i < n; i++ {
-		v := New(pt)
-		p := new(*uintptr)
-		*p = new(uintptr)
-		**p = uintptr(i)
-		v.Elem().Set(ValueOf(p).Convert(pt))
-		x = append(x, v.Interface())
-	}
-	runtime.GC()
-
-	for i, xi := range x {
-		k := ValueOf(xi).Elem().Elem().Elem().Interface().(uintptr)
-		if k != uintptr(i) {
-			t.Errorf("lost x[%d] = %d, want %d", i, k, i)
-		}
-	}
-}
-
-func TestAddr(t *testing.T) {
-	var p struct {
-		X, Y int
-	}
-
-	v := ValueOf(&p)
-	v = v.Elem()
-	v = v.Addr()
-	v = v.Elem()
-	v = v.Field(0)
-	v.SetInt(2)
-	if p.X != 2 {
-		t.Errorf("Addr.Elem.Set failed to set value")
-	}
-
-	// Again but take address of the ValueOf value.
-	// Exercises generation of PtrTypes not present in the binary.
-	q := &p
-	v = ValueOf(&q).Elem()
-	v = v.Addr()
-	v = v.Elem()
-	v = v.Elem()
-	v = v.Addr()
-	v = v.Elem()
-	v = v.Field(0)
-	v.SetInt(3)
-	if p.X != 3 {
-		t.Errorf("Addr.Elem.Set failed to set value")
-	}
-
-	// Starting without pointer we should get changed value
-	// in interface.
-	qq := p
-	v = ValueOf(&qq).Elem()
-	v0 := v
-	v = v.Addr()
-	v = v.Elem()
-	v = v.Field(0)
-	v.SetInt(4)
-	if p.X != 3 { // should be unchanged from last time
-		t.Errorf("somehow value Set changed original p")
-	}
-	p = v0.Interface().(struct {
-		X, Y int
-	})
-	if p.X != 4 {
-		t.Errorf("Addr.Elem.Set valued to set value in top value")
-	}
-
-	// Verify that taking the address of a type gives us a pointer
-	// which we can convert back using the usual interface
-	// notation.
-	var s struct {
-		B *bool
-	}
-	ps := ValueOf(&s).Elem().Field(0).Addr().Interface()
-	*(ps.(**bool)) = new(bool)
-	if s.B == nil {
-		t.Errorf("Addr.Interface direct assignment failed")
-	}
-}
-
-func noAlloc(t *testing.T, n int, f func(int)) {
-	if testing.Short() {
-		t.Skip("skipping malloc count in short mode")
-	}
-	if runtime.GOMAXPROCS(0) > 1 {
-		t.Skip("skipping; GOMAXPROCS>1")
-	}
-	i := -1
-	allocs := testing.AllocsPerRun(n, func() {
-		f(i)
-		i++
-	})
-	if allocs > 0 {
-		t.Errorf("%d iterations: got %v mallocs, want 0", n, allocs)
-	}
-}
-
-func TestAllocations(t *testing.T) {
-	noAlloc(t, 100, func(j int) {
-		var i interface{}
-		var v Value
-		i = 42 + j
-		v = ValueOf(i)
-		if int(v.Int()) != 42+j {
-			panic("wrong int")
-		}
-	})
-}
-
-func TestSmallNegativeInt(t *testing.T) {
-	i := int16(-1)
-	v := ValueOf(i)
-	if v.Int() != -1 {
-		t.Errorf("int16(-1).Int() returned %v", v.Int())
-	}
-}
-
-func TestIndex(t *testing.T) {
-	xs := []byte{1, 2, 3, 4, 5, 6, 7, 8}
-	v := ValueOf(xs).Index(3).Interface().(byte)
-	if v != xs[3] {
-		t.Errorf("xs.Index(3) = %v; expected %v", v, xs[3])
-	}
-	xa := [8]byte{10, 20, 30, 40, 50, 60, 70, 80}
-	v = ValueOf(xa).Index(2).Interface().(byte)
-	if v != xa[2] {
-		t.Errorf("xa.Index(2) = %v; expected %v", v, xa[2])
-	}
-	s := "0123456789"
-	v = ValueOf(s).Index(3).Interface().(byte)
-	if v != s[3] {
-		t.Errorf("s.Index(3) = %v; expected %v", v, s[3])
-	}
-}
-
-func TestSlice(t *testing.T) {
-	xs := []int{1, 2, 3, 4, 5, 6, 7, 8}
-	v := ValueOf(xs).Slice(3, 5).Interface().([]int)
-	if len(v) != 2 {
-		t.Errorf("len(xs.Slice(3, 5)) = %d", len(v))
-	}
-	if cap(v) != 5 {
-		t.Errorf("cap(xs.Slice(3, 5)) = %d", cap(v))
-	}
-	if !DeepEqual(v[0:5], xs[3:]) {
-		t.Errorf("xs.Slice(3, 5)[0:5] = %v", v[0:5])
-	}
-	xa := [8]int{10, 20, 30, 40, 50, 60, 70, 80}
-	v = ValueOf(&xa).Elem().Slice(2, 5).Interface().([]int)
-	if len(v) != 3 {
-		t.Errorf("len(xa.Slice(2, 5)) = %d", len(v))
-	}
-	if cap(v) != 6 {
-		t.Errorf("cap(xa.Slice(2, 5)) = %d", cap(v))
-	}
-	if !DeepEqual(v[0:6], xa[2:]) {
-		t.Errorf("xs.Slice(2, 5)[0:6] = %v", v[0:6])
-	}
-	s := "0123456789"
-	vs := ValueOf(s).Slice(3, 5).Interface().(string)
-	if vs != s[3:5] {
-		t.Errorf("s.Slice(3, 5) = %q; expected %q", vs, s[3:5])
-	}
-}
-
-func TestSlice3(t *testing.T) {
-	xs := []int{1, 2, 3, 4, 5, 6, 7, 8}
-	v := ValueOf(xs).Slice3(3, 5, 7).Interface().([]int)
-	if len(v) != 2 {
-		t.Errorf("len(xs.Slice3(3, 5, 7)) = %d", len(v))
-	}
-	if cap(v) != 4 {
-		t.Errorf("cap(xs.Slice3(3, 5, 7)) = %d", cap(v))
-	}
-	if !DeepEqual(v[0:4], xs[3:7:7]) {
-		t.Errorf("xs.Slice3(3, 5, 7)[0:4] = %v", v[0:4])
-	}
-	rv := ValueOf(&xs).Elem()
-	shouldPanic(func() { rv.Slice3(1, 2, 1) })
-	shouldPanic(func() { rv.Slice3(1, 1, 11) })
-	shouldPanic(func() { rv.Slice3(2, 2, 1) })
-
-	xa := [8]int{10, 20, 30, 40, 50, 60, 70, 80}
-	v = ValueOf(&xa).Elem().Slice3(2, 5, 6).Interface().([]int)
-	if len(v) != 3 {
-		t.Errorf("len(xa.Slice(2, 5, 6)) = %d", len(v))
-	}
-	if cap(v) != 4 {
-		t.Errorf("cap(xa.Slice(2, 5, 6)) = %d", cap(v))
-	}
-	if !DeepEqual(v[0:4], xa[2:6:6]) {
-		t.Errorf("xs.Slice(2, 5, 6)[0:4] = %v", v[0:4])
-	}
-	rv = ValueOf(&xa).Elem()
-	shouldPanic(func() { rv.Slice3(1, 2, 1) })
-	shouldPanic(func() { rv.Slice3(1, 1, 11) })
-	shouldPanic(func() { rv.Slice3(2, 2, 1) })
-
-	s := "hello world"
-	rv = ValueOf(&s).Elem()
-	shouldPanic(func() { rv.Slice3(1, 2, 3) })
-}
-
-func TestSetLenCap(t *testing.T) {
-	xs := []int{1, 2, 3, 4, 5, 6, 7, 8}
-	xa := [8]int{10, 20, 30, 40, 50, 60, 70, 80}
-
-	vs := ValueOf(&xs).Elem()
-	shouldPanic(func() { vs.SetLen(10) })
-	shouldPanic(func() { vs.SetCap(10) })
-	shouldPanic(func() { vs.SetLen(-1) })
-	shouldPanic(func() { vs.SetCap(-1) })
-	shouldPanic(func() { vs.SetCap(6) }) // smaller than len
-	vs.SetLen(5)
-	if len(xs) != 5 || cap(xs) != 8 {
-		t.Errorf("after SetLen(5), len, cap = %d, %d, want 5, 8", len(xs), cap(xs))
-	}
-	vs.SetCap(6)
-	if len(xs) != 5 || cap(xs) != 6 {
-		t.Errorf("after SetCap(6), len, cap = %d, %d, want 5, 6", len(xs), cap(xs))
-	}
-	vs.SetCap(5)
-	if len(xs) != 5 || cap(xs) != 5 {
-		t.Errorf("after SetCap(5), len, cap = %d, %d, want 5, 5", len(xs), cap(xs))
-	}
-	shouldPanic(func() { vs.SetCap(4) }) // smaller than len
-	shouldPanic(func() { vs.SetLen(6) }) // bigger than cap
-
-	va := ValueOf(&xa).Elem()
-	shouldPanic(func() { va.SetLen(8) })
-	shouldPanic(func() { va.SetCap(8) })
-}
-
-func TestVariadic(t *testing.T) {
-	var b bytes.Buffer
-	V := ValueOf
-
-	b.Reset()
-	V(fmt.Fprintf).Call([]Value{V(&b), V("%s, %d world"), V("hello"), V(42)})
-	if b.String() != "hello, 42 world" {
-		t.Errorf("after Fprintf Call: %q != %q", b.String(), "hello 42 world")
-	}
-
-	b.Reset()
-	V(fmt.Fprintf).CallSlice([]Value{V(&b), V("%s, %d world"), V([]interface{}{"hello", 42})})
-	if b.String() != "hello, 42 world" {
-		t.Errorf("after Fprintf CallSlice: %q != %q", b.String(), "hello 42 world")
-	}
-}
-
-func TestFuncArg(t *testing.T) {
-	f1 := func(i int, f func(int) int) int { return f(i) }
-	f2 := func(i int) int { return i + 1 }
-	r := ValueOf(f1).Call([]Value{ValueOf(100), ValueOf(f2)})
-	if r[0].Int() != 101 {
-		t.Errorf("function returned %d, want 101", r[0].Int())
-	}
-}
-
-var tagGetTests = []struct {
-	Tag   StructTag
-	Key   string
-	Value string
-}{
-	{`protobuf:"PB(1,2)"`, `protobuf`, `PB(1,2)`},
-	{`protobuf:"PB(1,2)"`, `foo`, ``},
-	{`protobuf:"PB(1,2)"`, `rotobuf`, ``},
-	{`protobuf:"PB(1,2)" json:"name"`, `json`, `name`},
-	{`protobuf:"PB(1,2)" json:"name"`, `protobuf`, `PB(1,2)`},
-}
-
-func TestTagGet(t *testing.T) {
-	for _, tt := range tagGetTests {
-		if v := tt.Tag.Get(tt.Key); v != tt.Value {
-			t.Errorf("StructTag(%#q).Get(%#q) = %#q, want %#q", tt.Tag, tt.Key, v, tt.Value)
-		}
-	}
-}
-
-func TestBytes(t *testing.T) {
-	type B []byte
-	x := B{1, 2, 3, 4}
-	y := ValueOf(x).Bytes()
-	if !bytes.Equal(x, y) {
-		t.Fatalf("ValueOf(%v).Bytes() = %v", x, y)
-	}
-	if &x[0] != &y[0] {
-		t.Errorf("ValueOf(%p).Bytes() = %p", &x[0], &y[0])
-	}
-}
-
-func TestSetBytes(t *testing.T) {
-	type B []byte
-	var x B
-	y := []byte{1, 2, 3, 4}
-	ValueOf(&x).Elem().SetBytes(y)
-	if !bytes.Equal(x, y) {
-		t.Fatalf("ValueOf(%v).Bytes() = %v", x, y)
-	}
-	if &x[0] != &y[0] {
-		t.Errorf("ValueOf(%p).Bytes() = %p", &x[0], &y[0])
-	}
-}
-
-type Private struct {
-	x int
-	y **int
-}
-
-func (p *Private) m() {
-}
-
-type Public struct {
-	X int
-	Y **int
-}
-
-func (p *Public) M() {
-}
-
-func TestUnexported(t *testing.T) {
-	var pub Public
-	v := ValueOf(&pub)
-	isValid(v.Elem().Field(0))
-	isValid(v.Elem().Field(1))
-	isValid(v.Elem().FieldByName("X"))
-	isValid(v.Elem().FieldByName("Y"))
-	isValid(v.Type().Method(0).Func)
-	isNonNil(v.Elem().Field(0).Interface())
-	isNonNil(v.Elem().Field(1).Interface())
-	isNonNil(v.Elem().FieldByName("X").Interface())
-	isNonNil(v.Elem().FieldByName("Y").Interface())
-	isNonNil(v.Type().Method(0).Func.Interface())
-
-	var priv Private
-	v = ValueOf(&priv)
-	isValid(v.Elem().Field(0))
-	isValid(v.Elem().Field(1))
-	isValid(v.Elem().FieldByName("x"))
-	isValid(v.Elem().FieldByName("y"))
-	isValid(v.Type().Method(0).Func)
-	shouldPanic(func() { v.Elem().Field(0).Interface() })
-	shouldPanic(func() { v.Elem().Field(1).Interface() })
-	shouldPanic(func() { v.Elem().FieldByName("x").Interface() })
-	shouldPanic(func() { v.Elem().FieldByName("y").Interface() })
-	shouldPanic(func() { v.Type().Method(0).Func.Interface() })
-}
-
-func shouldPanic(f func()) {
-	defer func() {
-		if recover() == nil {
-			panic("did not panic")
-		}
-	}()
-	f()
-}
-
-func isNonNil(x interface{}) {
-	if x == nil {
-		panic("nil interface")
-	}
-}
-
-func isValid(v Value) {
-	if !v.IsValid() {
-		panic("zero Value")
-	}
-}
-
-func TestAlias(t *testing.T) {
-	x := string("hello")
-	v := ValueOf(&x).Elem()
-	oldvalue := v.Interface()
-	v.SetString("world")
-	newvalue := v.Interface()
-
-	if oldvalue != "hello" || newvalue != "world" {
-		t.Errorf("aliasing: old=%q new=%q, want hello, world", oldvalue, newvalue)
-	}
-}
-
-var V = ValueOf
-
-func EmptyInterfaceV(x interface{}) Value {
-	return ValueOf(&x).Elem()
-}
-
-func ReaderV(x io.Reader) Value {
-	return ValueOf(&x).Elem()
-}
-
-func ReadWriterV(x io.ReadWriter) Value {
-	return ValueOf(&x).Elem()
-}
-
-type Empty struct{}
-type MyString string
-type MyBytes []byte
-type MyRunes []int32
-type MyFunc func()
-type MyByte byte
-
-var convertTests = []struct {
-	in  Value
-	out Value
-}{
-	// numbers
-	/*
-		Edit .+1,/\*\//-1>cat >/tmp/x.go && go run /tmp/x.go
-
-		package main
-
-		import "fmt"
-
-		var numbers = []string{
-			"int8", "uint8", "int16", "uint16",
-			"int32", "uint32", "int64", "uint64",
-			"int", "uint", "uintptr",
-			"float32", "float64",
-		}
-
-		func main() {
-			// all pairs but in an unusual order,
-			// to emit all the int8, uint8 cases
-			// before n grows too big.
-			n := 1
-			for i, f := range numbers {
-				for _, g := range numbers[i:] {
-					fmt.Printf("\t{V(%s(%d)), V(%s(%d))},\n", f, n, g, n)
-					n++
-					if f != g {
-						fmt.Printf("\t{V(%s(%d)), V(%s(%d))},\n", g, n, f, n)
-						n++
-					}
-				}
-			}
-		}
-	*/
-	{V(int8(1)), V(int8(1))},
-	{V(int8(2)), V(uint8(2))},
-	{V(uint8(3)), V(int8(3))},
-	{V(int8(4)), V(int16(4))},
-	{V(int16(5)), V(int8(5))},
-	{V(int8(6)), V(uint16(6))},
-	{V(uint16(7)), V(int8(7))},
-	{V(int8(8)), V(int32(8))},
-	{V(int32(9)), V(int8(9))},
-	{V(int8(10)), V(uint32(10))},
-	{V(uint32(11)), V(int8(11))},
-	{V(int8(12)), V(int64(12))},
-	{V(int64(13)), V(int8(13))},
-	{V(int8(14)), V(uint64(14))},
-	{V(uint64(15)), V(int8(15))},
-	{V(int8(16)), V(int(16))},
-	{V(int(17)), V(int8(17))},
-	{V(int8(18)), V(uint(18))},
-	{V(uint(19)), V(int8(19))},
-	{V(int8(20)), V(uintptr(20))},
-	{V(uintptr(21)), V(int8(21))},
-	{V(int8(22)), V(float32(22))},
-	{V(float32(23)), V(int8(23))},
-	{V(int8(24)), V(float64(24))},
-	{V(float64(25)), V(int8(25))},
-	{V(uint8(26)), V(uint8(26))},
-	{V(uint8(27)), V(int16(27))},
-	{V(int16(28)), V(uint8(28))},
-	{V(uint8(29)), V(uint16(29))},
-	{V(uint16(30)), V(uint8(30))},
-	{V(uint8(31)), V(int32(31))},
-	{V(int32(32)), V(uint8(32))},
-	{V(uint8(33)), V(uint32(33))},
-	{V(uint32(34)), V(uint8(34))},
-	{V(uint8(35)), V(int64(35))},
-	{V(int64(36)), V(uint8(36))},
-	{V(uint8(37)), V(uint64(37))},
-	{V(uint64(38)), V(uint8(38))},
-	{V(uint8(39)), V(int(39))},
-	{V(int(40)), V(uint8(40))},
-	{V(uint8(41)), V(uint(41))},
-	{V(uint(42)), V(uint8(42))},
-	{V(uint8(43)), V(uintptr(43))},
-	{V(uintptr(44)), V(uint8(44))},
-	{V(uint8(45)), V(float32(45))},
-	{V(float32(46)), V(uint8(46))},
-	{V(uint8(47)), V(float64(47))},
-	{V(float64(48)), V(uint8(48))},
-	{V(int16(49)), V(int16(49))},
-	{V(int16(50)), V(uint16(50))},
-	{V(uint16(51)), V(int16(51))},
-	{V(int16(52)), V(int32(52))},
-	{V(int32(53)), V(int16(53))},
-	{V(int16(54)), V(uint32(54))},
-	{V(uint32(55)), V(int16(55))},
-	{V(int16(56)), V(int64(56))},
-	{V(int64(57)), V(int16(57))},
-	{V(int16(58)), V(uint64(58))},
-	{V(uint64(59)), V(int16(59))},
-	{V(int16(60)), V(int(60))},
-	{V(int(61)), V(int16(61))},
-	{V(int16(62)), V(uint(62))},
-	{V(uint(63)), V(int16(63))},
-	{V(int16(64)), V(uintptr(64))},
-	{V(uintptr(65)), V(int16(65))},
-	{V(int16(66)), V(float32(66))},
-	{V(float32(67)), V(int16(67))},
-	{V(int16(68)), V(float64(68))},
-	{V(float64(69)), V(int16(69))},
-	{V(uint16(70)), V(uint16(70))},
-	{V(uint16(71)), V(int32(71))},
-	{V(int32(72)), V(uint16(72))},
-	{V(uint16(73)), V(uint32(73))},
-	{V(uint32(74)), V(uint16(74))},
-	{V(uint16(75)), V(int64(75))},
-	{V(int64(76)), V(uint16(76))},
-	{V(uint16(77)), V(uint64(77))},
-	{V(uint64(78)), V(uint16(78))},
-	{V(uint16(79)), V(int(79))},
-	{V(int(80)), V(uint16(80))},
-	{V(uint16(81)), V(uint(81))},
-	{V(uint(82)), V(uint16(82))},
-	{V(uint16(83)), V(uintptr(83))},
-	{V(uintptr(84)), V(uint16(84))},
-	{V(uint16(85)), V(float32(85))},
-	{V(float32(86)), V(uint16(86))},
-	{V(uint16(87)), V(float64(87))},
-	{V(float64(88)), V(uint16(88))},
-	{V(int32(89)), V(int32(89))},
-	{V(int32(90)), V(uint32(90))},
-	{V(uint32(91)), V(int32(91))},
-	{V(int32(92)), V(int64(92))},
-	{V(int64(93)), V(int32(93))},
-	{V(int32(94)), V(uint64(94))},
-	{V(uint64(95)), V(int32(95))},
-	{V(int32(96)), V(int(96))},
-	{V(int(97)), V(int32(97))},
-	{V(int32(98)), V(uint(98))},
-	{V(uint(99)), V(int32(99))},
-	{V(int32(100)), V(uintptr(100))},
-	{V(uintptr(101)), V(int32(101))},
-	{V(int32(102)), V(float32(102))},
-	{V(float32(103)), V(int32(103))},
-	{V(int32(104)), V(float64(104))},
-	{V(float64(105)), V(int32(105))},
-	{V(uint32(106)), V(uint32(106))},
-	{V(uint32(107)), V(int64(107))},
-	{V(int64(108)), V(uint32(108))},
-	{V(uint32(109)), V(uint64(109))},
-	{V(uint64(110)), V(uint32(110))},
-	{V(uint32(111)), V(int(111))},
-	{V(int(112)), V(uint32(112))},
-	{V(uint32(113)), V(uint(113))},
-	{V(uint(114)), V(uint32(114))},
-	{V(uint32(115)), V(uintptr(115))},
-	{V(uintptr(116)), V(uint32(116))},
-	{V(uint32(117)), V(float32(117))},
-	{V(float32(118)), V(uint32(118))},
-	{V(uint32(119)), V(float64(119))},
-	{V(float64(120)), V(uint32(120))},
-	{V(int64(121)), V(int64(121))},
-	{V(int64(122)), V(uint64(122))},
-	{V(uint64(123)), V(int64(123))},
-	{V(int64(124)), V(int(124))},
-	{V(int(125)), V(int64(125))},
-	{V(int64(126)), V(uint(126))},
-	{V(uint(127)), V(int64(127))},
-	{V(int64(128)), V(uintptr(128))},
-	{V(uintptr(129)), V(int64(129))},
-	{V(int64(130)), V(float32(130))},
-	{V(float32(131)), V(int64(131))},
-	{V(int64(132)), V(float64(132))},
-	{V(float64(133)), V(int64(133))},
-	{V(uint64(134)), V(uint64(134))},
-	{V(uint64(135)), V(int(135))},
-	{V(int(136)), V(uint64(136))},
-	{V(uint64(137)), V(uint(137))},
-	{V(uint(138)), V(uint64(138))},
-	{V(uint64(139)), V(uintptr(139))},
-	{V(uintptr(140)), V(uint64(140))},
-	{V(uint64(141)), V(float32(141))},
-	{V(float32(142)), V(uint64(142))},
-	{V(uint64(143)), V(float64(143))},
-	{V(float64(144)), V(uint64(144))},
-	{V(int(145)), V(int(145))},
-	{V(int(146)), V(uint(146))},
-	{V(uint(147)), V(int(147))},
-	{V(int(148)), V(uintptr(148))},
-	{V(uintptr(149)), V(int(149))},
-	{V(int(150)), V(float32(150))},
-	{V(float32(151)), V(int(151))},
-	{V(int(152)), V(float64(152))},
-	{V(float64(153)), V(int(153))},
-	{V(uint(154)), V(uint(154))},
-	{V(uint(155)), V(uintptr(155))},
-	{V(uintptr(156)), V(uint(156))},
-	{V(uint(157)), V(float32(157))},
-	{V(float32(158)), V(uint(158))},
-	{V(uint(159)), V(float64(159))},
-	{V(float64(160)), V(uint(160))},
-	{V(uintptr(161)), V(uintptr(161))},
-	{V(uintptr(162)), V(float32(162))},
-	{V(float32(163)), V(uintptr(163))},
-	{V(uintptr(164)), V(float64(164))},
-	{V(float64(165)), V(uintptr(165))},
-	{V(float32(166)), V(float32(166))},
-	{V(float32(167)), V(float64(167))},
-	{V(float64(168)), V(float32(168))},
-	{V(float64(169)), V(float64(169))},
-
-	// truncation
-	{V(float64(1.5)), V(int(1))},
-
-	// complex
-	{V(complex64(1i)), V(complex64(1i))},
-	{V(complex64(2i)), V(complex128(2i))},
-	{V(complex128(3i)), V(complex64(3i))},
-	{V(complex128(4i)), V(complex128(4i))},
-
-	// string
-	{V(string("hello")), V(string("hello"))},
-	{V(string("bytes1")), V([]byte("bytes1"))},
-	{V([]byte("bytes2")), V(string("bytes2"))},
-	{V([]byte("bytes3")), V([]byte("bytes3"))},
-	{V(string("runes♝")), V([]rune("runes♝"))},
-	{V([]rune("runes♕")), V(string("runes♕"))},
-	{V([]rune("runes🙈🙉🙊")), V([]rune("runes🙈🙉🙊"))},
-	{V(int('a')), V(string("a"))},
-	{V(int8('a')), V(string("a"))},
-	{V(int16('a')), V(string("a"))},
-	{V(int32('a')), V(string("a"))},
-	{V(int64('a')), V(string("a"))},
-	{V(uint('a')), V(string("a"))},
-	{V(uint8('a')), V(string("a"))},
-	{V(uint16('a')), V(string("a"))},
-	{V(uint32('a')), V(string("a"))},
-	{V(uint64('a')), V(string("a"))},
-	{V(uintptr('a')), V(string("a"))},
-	{V(int(-1)), V(string("\uFFFD"))},
-	{V(int8(-2)), V(string("\uFFFD"))},
-	{V(int16(-3)), V(string("\uFFFD"))},
-	{V(int32(-4)), V(string("\uFFFD"))},
-	{V(int64(-5)), V(string("\uFFFD"))},
-	{V(uint(0x110001)), V(string("\uFFFD"))},
-	{V(uint32(0x110002)), V(string("\uFFFD"))},
-	{V(uint64(0x110003)), V(string("\uFFFD"))},
-	{V(uintptr(0x110004)), V(string("\uFFFD"))},
-
-	// named string
-	{V(MyString("hello")), V(string("hello"))},
-	{V(string("hello")), V(MyString("hello"))},
-	{V(string("hello")), V(string("hello"))},
-	{V(MyString("hello")), V(MyString("hello"))},
-	{V(MyString("bytes1")), V([]byte("bytes1"))},
-	{V([]byte("bytes2")), V(MyString("bytes2"))},
-	{V([]byte("bytes3")), V([]byte("bytes3"))},
-	{V(MyString("runes♝")), V([]rune("runes♝"))},
-	{V([]rune("runes♕")), V(MyString("runes♕"))},
-	{V([]rune("runes🙈🙉🙊")), V([]rune("runes🙈🙉🙊"))},
-	{V([]rune("runes🙈🙉🙊")), V(MyRunes("runes🙈🙉🙊"))},
-	{V(MyRunes("runes🙈🙉🙊")), V([]rune("runes🙈🙉🙊"))},
-	{V(int('a')), V(MyString("a"))},
-	{V(int8('a')), V(MyString("a"))},
-	{V(int16('a')), V(MyString("a"))},
-	{V(int32('a')), V(MyString("a"))},
-	{V(int64('a')), V(MyString("a"))},
-	{V(uint('a')), V(MyString("a"))},
-	{V(uint8('a')), V(MyString("a"))},
-	{V(uint16('a')), V(MyString("a"))},
-	{V(uint32('a')), V(MyString("a"))},
-	{V(uint64('a')), V(MyString("a"))},
-	{V(uintptr('a')), V(MyString("a"))},
-	{V(int(-1)), V(MyString("\uFFFD"))},
-	{V(int8(-2)), V(MyString("\uFFFD"))},
-	{V(int16(-3)), V(MyString("\uFFFD"))},
-	{V(int32(-4)), V(MyString("\uFFFD"))},
-	{V(int64(-5)), V(MyString("\uFFFD"))},
-	{V(uint(0x110001)), V(MyString("\uFFFD"))},
-	{V(uint32(0x110002)), V(MyString("\uFFFD"))},
-	{V(uint64(0x110003)), V(MyString("\uFFFD"))},
-	{V(uintptr(0x110004)), V(MyString("\uFFFD"))},
-
-	// named []byte
-	{V(string("bytes1")), V(MyBytes("bytes1"))},
-	{V(MyBytes("bytes2")), V(string("bytes2"))},
-	{V(MyBytes("bytes3")), V(MyBytes("bytes3"))},
-	{V(MyString("bytes1")), V(MyBytes("bytes1"))},
-	{V(MyBytes("bytes2")), V(MyString("bytes2"))},
-
-	// named []rune
-	{V(string("runes♝")), V(MyRunes("runes♝"))},
-	{V(MyRunes("runes♕")), V(string("runes♕"))},
-	{V(MyRunes("runes🙈🙉🙊")), V(MyRunes("runes🙈🙉🙊"))},
-	{V(MyString("runes♝")), V(MyRunes("runes♝"))},
-	{V(MyRunes("runes♕")), V(MyString("runes♕"))},
-
-	// named types and equal underlying types
-	{V(new(int)), V(new(integer))},
-	{V(new(integer)), V(new(int))},
-	{V(Empty{}), V(struct{}{})},
-	{V(new(Empty)), V(new(struct{}))},
-	{V(struct{}{}), V(Empty{})},
-	{V(new(struct{})), V(new(Empty))},
-	{V(Empty{}), V(Empty{})},
-	{V(MyBytes{}), V([]byte{})},
-	{V([]byte{}), V(MyBytes{})},
-	{V((func())(nil)), V(MyFunc(nil))},
-	{V((MyFunc)(nil)), V((func())(nil))},
-
-	// can convert *byte and *MyByte
-	{V((*byte)(nil)), V((*MyByte)(nil))},
-	{V((*MyByte)(nil)), V((*byte)(nil))},
-
-	// cannot convert mismatched array sizes
-	{V([2]byte{}), V([2]byte{})},
-	{V([3]byte{}), V([3]byte{})},
-
-	// cannot convert other instances
-	{V((**byte)(nil)), V((**byte)(nil))},
-	{V((**MyByte)(nil)), V((**MyByte)(nil))},
-	{V((chan byte)(nil)), V((chan byte)(nil))},
-	{V((chan MyByte)(nil)), V((chan MyByte)(nil))},
-	{V(([]byte)(nil)), V(([]byte)(nil))},
-	{V(([]MyByte)(nil)), V(([]MyByte)(nil))},
-	{V((map[int]byte)(nil)), V((map[int]byte)(nil))},
-	{V((map[int]MyByte)(nil)), V((map[int]MyByte)(nil))},
-	{V((map[byte]int)(nil)), V((map[byte]int)(nil))},
-	{V((map[MyByte]int)(nil)), V((map[MyByte]int)(nil))},
-	{V([2]byte{}), V([2]byte{})},
-	{V([2]MyByte{}), V([2]MyByte{})},
-
-	// other
-	{V((***int)(nil)), V((***int)(nil))},
-	{V((***byte)(nil)), V((***byte)(nil))},
-	{V((***int32)(nil)), V((***int32)(nil))},
-	{V((***int64)(nil)), V((***int64)(nil))},
-	{V((chan int)(nil)), V((<-chan int)(nil))},
-	{V((chan int)(nil)), V((chan<- int)(nil))},
-	{V((chan string)(nil)), V((<-chan string)(nil))},
-	{V((chan string)(nil)), V((chan<- string)(nil))},
-	{V((chan byte)(nil)), V((chan byte)(nil))},
-	{V((chan MyByte)(nil)), V((chan MyByte)(nil))},
-	{V((map[int]bool)(nil)), V((map[int]bool)(nil))},
-	{V((map[int]byte)(nil)), V((map[int]byte)(nil))},
-	{V((map[uint]bool)(nil)), V((map[uint]bool)(nil))},
-	{V([]uint(nil)), V([]uint(nil))},
-	{V([]int(nil)), V([]int(nil))},
-	{V(new(interface{})), V(new(interface{}))},
-	{V(new(io.Reader)), V(new(io.Reader))},
-	{V(new(io.Writer)), V(new(io.Writer))},
-
-	// interfaces
-	{V(int(1)), EmptyInterfaceV(int(1))},
-	{V(string("hello")), EmptyInterfaceV(string("hello"))},
-	{V(new(bytes.Buffer)), ReaderV(new(bytes.Buffer))},
-	{ReadWriterV(new(bytes.Buffer)), ReaderV(new(bytes.Buffer))},
-	{V(new(bytes.Buffer)), ReadWriterV(new(bytes.Buffer))},
-}
-
-func TestConvert(t *testing.T) {
-	canConvert := map[[2]Type]bool{}
-	all := map[Type]bool{}
-
-	for _, tt := range convertTests {
-		t1 := tt.in.Type()
-		if !t1.ConvertibleTo(t1) {
-			t.Errorf("(%s).ConvertibleTo(%s) = false, want true", t1, t1)
-			continue
-		}
-
-		t2 := tt.out.Type()
-		if !t1.ConvertibleTo(t2) {
-			t.Errorf("(%s).ConvertibleTo(%s) = false, want true", t1, t2)
-			continue
-		}
-
-		all[t1] = true
-		all[t2] = true
-		canConvert[[2]Type{t1, t2}] = true
-
-		// vout1 represents the in value converted to the in type.
-		v1 := tt.in
-		vout1 := v1.Convert(t1)
-		out1 := vout1.Interface()
-		if vout1.Type() != tt.in.Type() || !DeepEqual(out1, tt.in.Interface()) {
-			t.Errorf("ValueOf(%T(%[1]v)).Convert(%s) = %T(%[3]v), want %T(%[4]v)", tt.in.Interface(), t1, out1, tt.in.Interface())
-		}
-
-		// vout2 represents the in value converted to the out type.
-		vout2 := v1.Convert(t2)
-		out2 := vout2.Interface()
-		if vout2.Type() != tt.out.Type() || !DeepEqual(out2, tt.out.Interface()) {
-			t.Errorf("ValueOf(%T(%[1]v)).Convert(%s) = %T(%[3]v), want %T(%[4]v)", tt.in.Interface(), t2, out2, tt.out.Interface())
-		}
-
-		// vout3 represents a new value of the out type, set to vout2.  This makes
-		// sure the converted value vout2 is really usable as a regular value.
-		vout3 := New(t2).Elem()
-		vout3.Set(vout2)
-		out3 := vout3.Interface()
-		if vout3.Type() != tt.out.Type() || !DeepEqual(out3, tt.out.Interface()) {
-			t.Errorf("Set(ValueOf(%T(%[1]v)).Convert(%s)) = %T(%[3]v), want %T(%[4]v)", tt.in.Interface(), t2, out3, tt.out.Interface())
-		}
-
-		if IsRO(v1) {
-			t.Errorf("table entry %v is RO, should not be", v1)
-		}
-		if IsRO(vout1) {
-			t.Errorf("self-conversion output %v is RO, should not be", vout1)
-		}
-		if IsRO(vout2) {
-			t.Errorf("conversion output %v is RO, should not be", vout2)
-		}
-		if IsRO(vout3) {
-			t.Errorf("set(conversion output) %v is RO, should not be", vout3)
-		}
-		if !IsRO(MakeRO(v1).Convert(t1)) {
-			t.Errorf("RO self-conversion output %v is not RO, should be", v1)
-		}
-		if !IsRO(MakeRO(v1).Convert(t2)) {
-			t.Errorf("RO conversion output %v is not RO, should be", v1)
-		}
-	}
-
-	// Assume that of all the types we saw during the tests,
-	// if there wasn't an explicit entry for a conversion between
-	// a pair of types, then it's not to be allowed. This checks for
-	// things like 'int64' converting to '*int'.
-	for t1 := range all {
-		for t2 := range all {
-			expectOK := t1 == t2 || canConvert[[2]Type{t1, t2}] || t2.Kind() == Interface && t2.NumMethod() == 0
-			if ok := t1.ConvertibleTo(t2); ok != expectOK {
-				t.Errorf("(%s).ConvertibleTo(%s) = %v, want %v", t1, t2, ok, expectOK)
-			}
-		}
-	}
-}
-
-func TestOverflow(t *testing.T) {
-	if ovf := V(float64(0)).OverflowFloat(1e300); ovf {
-		t.Errorf("%v wrongly overflows float64", 1e300)
-	}
-
-	maxFloat32 := float64((1<<24 - 1) << (127 - 23))
-	if ovf := V(float32(0)).OverflowFloat(maxFloat32); ovf {
-		t.Errorf("%v wrongly overflows float32", maxFloat32)
-	}
-	ovfFloat32 := float64((1<<24-1)<<(127-23) + 1<<(127-52))
-	if ovf := V(float32(0)).OverflowFloat(ovfFloat32); !ovf {
-		t.Errorf("%v should overflow float32", ovfFloat32)
-	}
-	if ovf := V(float32(0)).OverflowFloat(-ovfFloat32); !ovf {
-		t.Errorf("%v should overflow float32", -ovfFloat32)
-	}
-
-	maxInt32 := int64(0x7fffffff)
-	if ovf := V(int32(0)).OverflowInt(maxInt32); ovf {
-		t.Errorf("%v wrongly overflows int32", maxInt32)
-	}
-	if ovf := V(int32(0)).OverflowInt(-1 << 31); ovf {
-		t.Errorf("%v wrongly overflows int32", -int64(1)<<31)
-	}
-	ovfInt32 := int64(1 << 31)
-	if ovf := V(int32(0)).OverflowInt(ovfInt32); !ovf {
-		t.Errorf("%v should overflow int32", ovfInt32)
-	}
-
-	maxUint32 := uint64(0xffffffff)
-	if ovf := V(uint32(0)).OverflowUint(maxUint32); ovf {
-		t.Errorf("%v wrongly overflows uint32", maxUint32)
-	}
-	ovfUint32 := uint64(1 << 32)
-	if ovf := V(uint32(0)).OverflowUint(ovfUint32); !ovf {
-		t.Errorf("%v should overflow uint32", ovfUint32)
-	}
-}
-
-func checkSameType(t *testing.T, x, y interface{}) {
-	if TypeOf(x) != TypeOf(y) {
-		t.Errorf("did not find preexisting type for %s (vs %s)", TypeOf(x), TypeOf(y))
-	}
-}
-
-func TestArrayOf(t *testing.T) {
-	// check construction and use of type not in binary
-	type T int
-	at := ArrayOf(10, TypeOf(T(1)))
-	v := New(at).Elem()
-	for i := 0; i < v.Len(); i++ {
-		v.Index(i).Set(ValueOf(T(i)))
-	}
-	s := fmt.Sprint(v.Interface())
-	want := "[0 1 2 3 4 5 6 7 8 9]"
-	if s != want {
-		t.Errorf("constructed array = %s, want %s", s, want)
-	}
-
-	// check that type already in binary is found
-	checkSameType(t, Zero(ArrayOf(5, TypeOf(T(1)))).Interface(), [5]T{})
-}
-
-func TestSliceOf(t *testing.T) {
-	// check construction and use of type not in binary
-	type T int
-	st := SliceOf(TypeOf(T(1)))
-	v := MakeSlice(st, 10, 10)
-	runtime.GC()
-	for i := 0; i < v.Len(); i++ {
-		v.Index(i).Set(ValueOf(T(i)))
-		runtime.GC()
-	}
-	s := fmt.Sprint(v.Interface())
-	want := "[0 1 2 3 4 5 6 7 8 9]"
-	if s != want {
-		t.Errorf("constructed slice = %s, want %s", s, want)
-	}
-
-	// check that type already in binary is found
-	type T1 int
-	checkSameType(t, Zero(SliceOf(TypeOf(T1(1)))).Interface(), []T1{})
-}
-
-func TestSliceOverflow(t *testing.T) {
-	// check that MakeSlice panics when size of slice overflows uint
-	const S = 1e6
-	s := uint(S)
-	l := (1<<(unsafe.Sizeof((*byte)(nil))*8)-1)/s + 1
-	if l*s >= s {
-		t.Fatal("slice size does not overflow")
-	}
-	var x [S]byte
-	st := SliceOf(TypeOf(x))
-	defer func() {
-		err := recover()
-		if err == nil {
-			t.Fatal("slice overflow does not panic")
-		}
-	}()
-	MakeSlice(st, int(l), int(l))
-}
-
-func TestSliceOfGC(t *testing.T) {
-	type T *uintptr
-	tt := TypeOf(T(nil))
-	st := SliceOf(tt)
-	const n = 100
-	var x []interface{}
-	for i := 0; i < n; i++ {
-		v := MakeSlice(st, n, n)
-		for j := 0; j < v.Len(); j++ {
-			p := new(uintptr)
-			*p = uintptr(i*n + j)
-			v.Index(j).Set(ValueOf(p).Convert(tt))
-		}
-		x = append(x, v.Interface())
-	}
-	runtime.GC()
-
-	for i, xi := range x {
-		v := ValueOf(xi)
-		for j := 0; j < v.Len(); j++ {
-			k := v.Index(j).Elem().Interface()
-			if k != uintptr(i*n+j) {
-				t.Errorf("lost x[%d][%d] = %d, want %d", i, j, k, i*n+j)
-			}
-		}
-	}
-}
-
-func TestChanOf(t *testing.T) {
-	// check construction and use of type not in binary
-	type T string
-	ct := ChanOf(BothDir, TypeOf(T("")))
-	v := MakeChan(ct, 2)
-	runtime.GC()
-	v.Send(ValueOf(T("hello")))
-	runtime.GC()
-	v.Send(ValueOf(T("world")))
-	runtime.GC()
-
-	sv1, _ := v.Recv()
-	sv2, _ := v.Recv()
-	s1 := sv1.String()
-	s2 := sv2.String()
-	if s1 != "hello" || s2 != "world" {
-		t.Errorf("constructed chan: have %q, %q, want %q, %q", s1, s2, "hello", "world")
-	}
-
-	// check that type already in binary is found
-	type T1 int
-	checkSameType(t, Zero(ChanOf(BothDir, TypeOf(T1(1)))).Interface(), (chan T1)(nil))
-}
-
-func TestChanOfGC(t *testing.T) {
-	done := make(chan bool, 1)
-	go func() {
-		select {
-		case <-done:
-		case <-time.After(5 * time.Second):
-			panic("deadlock in TestChanOfGC")
-		}
-	}()
-
-	defer func() {
-		done <- true
-	}()
-
-	type T *uintptr
-	tt := TypeOf(T(nil))
-	ct := ChanOf(BothDir, tt)
-
-	// NOTE: The garbage collector handles allocated channels specially,
-	// so we have to save pointers to channels in x; the pointer code will
-	// use the gc info in the newly constructed chan type.
-	const n = 100
-	var x []interface{}
-	for i := 0; i < n; i++ {
-		v := MakeChan(ct, n)
-		for j := 0; j < n; j++ {
-			p := new(uintptr)
-			*p = uintptr(i*n + j)
-			v.Send(ValueOf(p).Convert(tt))
-		}
-		pv := New(ct)
-		pv.Elem().Set(v)
-		x = append(x, pv.Interface())
-	}
-	runtime.GC()
-
-	for i, xi := range x {
-		v := ValueOf(xi).Elem()
-		for j := 0; j < n; j++ {
-			pv, _ := v.Recv()
-			k := pv.Elem().Interface()
-			if k != uintptr(i*n+j) {
-				t.Errorf("lost x[%d][%d] = %d, want %d", i, j, k, i*n+j)
-			}
-		}
-	}
-}
-
-func TestMapOf(t *testing.T) {
-	// check construction and use of type not in binary
-	type K string
-	type V float64
-
-	v := MakeMap(MapOf(TypeOf(K("")), TypeOf(V(0))))
-	runtime.GC()
-	v.SetMapIndex(ValueOf(K("a")), ValueOf(V(1)))
-	runtime.GC()
-
-	s := fmt.Sprint(v.Interface())
-	want := "map[a:1]"
-	if s != want {
-		t.Errorf("constructed map = %s, want %s", s, want)
-	}
-
-	// check that type already in binary is found
-	checkSameType(t, Zero(MapOf(TypeOf(V(0)), TypeOf(K("")))).Interface(), map[V]K(nil))
-
-	// check that invalid key type panics
-	shouldPanic(func() { MapOf(TypeOf((func())(nil)), TypeOf(false)) })
-}
-
-func TestMapOfGCKeys(t *testing.T) {
-	type T *uintptr
-	tt := TypeOf(T(nil))
-	mt := MapOf(tt, TypeOf(false))
-
-	// NOTE: The garbage collector handles allocated maps specially,
-	// so we have to save pointers to maps in x; the pointer code will
-	// use the gc info in the newly constructed map type.
-	const n = 100
-	var x []interface{}
-	for i := 0; i < n; i++ {
-		v := MakeMap(mt)
-		for j := 0; j < n; j++ {
-			p := new(uintptr)
-			*p = uintptr(i*n + j)
-			v.SetMapIndex(ValueOf(p).Convert(tt), ValueOf(true))
-		}
-		pv := New(mt)
-		pv.Elem().Set(v)
-		x = append(x, pv.Interface())
-	}
-	runtime.GC()
-
-	for i, xi := range x {
-		v := ValueOf(xi).Elem()
-		var out []int
-		for _, kv := range v.MapKeys() {
-			out = append(out, int(kv.Elem().Interface().(uintptr)))
-		}
-		sort.Ints(out)
-		for j, k := range out {
-			if k != i*n+j {
-				t.Errorf("lost x[%d][%d] = %d, want %d", i, j, k, i*n+j)
-			}
-		}
-	}
-}
-
-func TestMapOfGCValues(t *testing.T) {
-	type T *uintptr
-	tt := TypeOf(T(nil))
-	mt := MapOf(TypeOf(1), tt)
-
-	// NOTE: The garbage collector handles allocated maps specially,
-	// so we have to save pointers to maps in x; the pointer code will
-	// use the gc info in the newly constructed map type.
-	const n = 100
-	var x []interface{}
-	for i := 0; i < n; i++ {
-		v := MakeMap(mt)
-		for j := 0; j < n; j++ {
-			p := new(uintptr)
-			*p = uintptr(i*n + j)
-			v.SetMapIndex(ValueOf(j), ValueOf(p).Convert(tt))
-		}
-		pv := New(mt)
-		pv.Elem().Set(v)
-		x = append(x, pv.Interface())
-	}
-	runtime.GC()
-
-	for i, xi := range x {
-		v := ValueOf(xi).Elem()
-		for j := 0; j < n; j++ {
-			k := v.MapIndex(ValueOf(j)).Elem().Interface().(uintptr)
-			if k != uintptr(i*n+j) {
-				t.Errorf("lost x[%d][%d] = %d, want %d", i, j, k, i*n+j)
-			}
-		}
-	}
-}
-
-type B1 struct {
-	X int
-	Y int
-	Z int
-}
-
-func BenchmarkFieldByName1(b *testing.B) {
-	t := TypeOf(B1{})
-	for i := 0; i < b.N; i++ {
-		t.FieldByName("Z")
-	}
-}
-
-func BenchmarkFieldByName2(b *testing.B) {
-	t := TypeOf(S3{})
-	for i := 0; i < b.N; i++ {
-		t.FieldByName("B")
-	}
-}
-
-type R0 struct {
-	*R1
-	*R2
-	*R3
-	*R4
-}
-
-type R1 struct {
-	*R5
-	*R6
-	*R7
-	*R8
-}
-
-type R2 R1
-type R3 R1
-type R4 R1
-
-type R5 struct {
-	*R9
-	*R10
-	*R11
-	*R12
-}
-
-type R6 R5
-type R7 R5
-type R8 R5
-
-type R9 struct {
-	*R13
-	*R14
-	*R15
-	*R16
-}
-
-type R10 R9
-type R11 R9
-type R12 R9
-
-type R13 struct {
-	*R17
-	*R18
-	*R19
-	*R20
-}
-
-type R14 R13
-type R15 R13
-type R16 R13
-
-type R17 struct {
-	*R21
-	*R22
-	*R23
-	*R24
-}
-
-type R18 R17
-type R19 R17
-type R20 R17
-
-type R21 struct {
-	X int
-}
-
-type R22 R21
-type R23 R21
-type R24 R21
-
-func TestEmbed(t *testing.T) {
-	typ := TypeOf(R0{})
-	f, ok := typ.FieldByName("X")
-	if ok {
-		t.Fatalf(`FieldByName("X") should fail, returned %v`, f.Index)
-	}
-}
-
-func BenchmarkFieldByName3(b *testing.B) {
-	t := TypeOf(R0{})
-	for i := 0; i < b.N; i++ {
-		t.FieldByName("X")
-	}
-}
-
-type S struct {
-	i1 int64
-	i2 int64
-}
-
-func BenchmarkInterfaceBig(b *testing.B) {
-	v := ValueOf(S{})
-	for i := 0; i < b.N; i++ {
-		v.Interface()
-	}
-	b.StopTimer()
-}
-
-func TestAllocsInterfaceBig(t *testing.T) {
-	if testing.Short() {
-		t.Skip("skipping malloc count in short mode")
-	}
-	v := ValueOf(S{})
-	if allocs := testing.AllocsPerRun(100, func() { v.Interface() }); allocs > 0 {
-		t.Error("allocs:", allocs)
-	}
-}
-
-func BenchmarkInterfaceSmall(b *testing.B) {
-	v := ValueOf(int64(0))
-	for i := 0; i < b.N; i++ {
-		v.Interface()
-	}
-}
-
-func TestAllocsInterfaceSmall(t *testing.T) {
-	if testing.Short() {
-		t.Skip("skipping malloc count in short mode")
-	}
-	v := ValueOf(int64(0))
-	if allocs := testing.AllocsPerRun(100, func() { v.Interface() }); allocs > 0 {
-		t.Error("allocs:", allocs)
-	}
-}
-
-// An exhaustive is a mechanism for writing exhaustive or stochastic tests.
-// The basic usage is:
-//
-//	for x.Next() {
-//		... code using x.Maybe() or x.Choice(n) to create test cases ...
-//	}
-//
-// Each iteration of the loop returns a different set of results, until all
-// possible result sets have been explored. It is okay for different code paths
-// to make different method call sequences on x, but there must be no
-// other source of non-determinism in the call sequences.
-//
-// When faced with a new decision, x chooses randomly. Future explorations
-// of that path will choose successive values for the result. Thus, stopping
-// the loop after a fixed number of iterations gives somewhat stochastic
-// testing.
-//
-// Example:
-//
-//	for x.Next() {
-//		v := make([]bool, x.Choose(4))
-//		for i := range v {
-//			v[i] = x.Maybe()
-//		}
-//		fmt.Println(v)
-//	}
-//
-// prints (in some order):
-//
-//	[]
-//	[false]
-//	[true]
-//	[false false]
-//	[false true]
-//	...
-//	[true true]
-//	[false false false]
-//	...
-//	[true true true]
-//	[false false false false]
-//	...
-//	[true true true true]
-//
-type exhaustive struct {
-	r    *rand.Rand
-	pos  int
-	last []choice
-}
-
-type choice struct {
-	off int
-	n   int
-	max int
-}
-
-func (x *exhaustive) Next() bool {
-	if x.r == nil {
-		x.r = rand.New(rand.NewSource(time.Now().UnixNano()))
-	}
-	x.pos = 0
-	if x.last == nil {
-		x.last = []choice{}
-		return true
-	}
-	for i := len(x.last) - 1; i >= 0; i-- {
-		c := &x.last[i]
-		if c.n+1 < c.max {
-			c.n++
-			x.last = x.last[:i+1]
-			return true
-		}
-	}
-	return false
-}
-
-func (x *exhaustive) Choose(max int) int {
-	if x.pos >= len(x.last) {
-		x.last = append(x.last, choice{x.r.Intn(max), 0, max})
-	}
-	c := &x.last[x.pos]
-	x.pos++
-	if c.max != max {
-		panic("inconsistent use of exhaustive tester")
-	}
-	return (c.n + c.off) % max
-}
-
-func (x *exhaustive) Maybe() bool {
-	return x.Choose(2) == 1
-}
-
-func GCFunc(args []Value) []Value {
-	runtime.GC()
-	return []Value{}
-}
-
-func TestReflectFuncTraceback(t *testing.T) {
-	f := MakeFunc(TypeOf(func() {}), GCFunc)
-	f.Call([]Value{})
-}
-
-func (p Point) GCMethod(k int) int {
-	runtime.GC()
-	return k + p.x
-}
-
-func TestReflectMethodTraceback(t *testing.T) {
-	p := Point{3, 4}
-	m := ValueOf(p).MethodByName("GCMethod")
-	i := ValueOf(m.Interface()).Call([]Value{ValueOf(5)})[0].Int()
-	if i != 8 {
-		t.Errorf("Call returned %d; want 8", i)
-	}
-}
-
-func TestBigZero(t *testing.T) {
-	const size = 1 << 10
-	var v [size]byte
-	z := Zero(ValueOf(v).Type()).Interface().([size]byte)
-	for i := 0; i < size; i++ {
-		if z[i] != 0 {
-			t.Fatalf("Zero object not all zero, index %d", i)
-		}
-	}
-}
-
-func TestFieldByIndexNil(t *testing.T) {
-	type P struct {
-		F int
-	}
-	type T struct {
-		*P
-	}
-	v := ValueOf(T{})
-
-	v.FieldByName("P") // should be fine
-
-	defer func() {
-		if err := recover(); err == nil {
-			t.Fatalf("no error")
-		} else if !strings.Contains(fmt.Sprint(err), "nil pointer to embedded struct") {
-			t.Fatalf(`err=%q, wanted error containing "nil pointer to embedded struct"`, err)
-		}
-	}()
-	v.FieldByName("F") // should panic
-
-	t.Fatalf("did not panic")
-}
-
-// Given
-//	type Outer struct {
-//		*Inner
-//		...
-//	}
-// the compiler generates the implementation of (*Outer).M dispatching to the embedded Inner.
-// The implementation is logically:
-//	func (p *Outer) M() {
-//		(p.Inner).M()
-//	}
-// but since the only change here is the replacement of one pointer receiver with another,
-// the actual generated code overwrites the original receiver with the p.Inner pointer and
-// then jumps to the M method expecting the *Inner receiver.
-//
-// During reflect.Value.Call, we create an argument frame and the associated data structures
-// to describe it to the garbage collector, populate the frame, call reflect.call to
-// run a function call using that frame, and then copy the results back out of the frame.
-// The reflect.call function does a memmove of the frame structure onto the
-// stack (to set up the inputs), runs the call, and the memmoves the stack back to
-// the frame structure (to preserve the outputs).
-//
-// Originally reflect.call did not distinguish inputs from outputs: both memmoves
-// were for the full stack frame. However, in the case where the called function was
-// one of these wrappers, the rewritten receiver is almost certainly a different type
-// than the original receiver. This is not a problem on the stack, where we use the
-// program counter to determine the type information and understand that
-// during (*Outer).M the receiver is an *Outer while during (*Inner).M the receiver in the same
-// memory word is now an *Inner. But in the statically typed argument frame created
-// by reflect, the receiver is always an *Outer. Copying the modified receiver pointer
-// off the stack into the frame will store an *Inner there, and then if a garbage collection
-// happens to scan that argument frame before it is discarded, it will scan the *Inner
-// memory as if it were an *Outer. If the two have different memory layouts, the
-// collection will intepret the memory incorrectly.
-//
-// One such possible incorrect interpretation is to treat two arbitrary memory words
-// (Inner.P1 and Inner.P2 below) as an interface (Outer.R below). Because interpreting
-// an interface requires dereferencing the itab word, the misinterpretation will try to
-// deference Inner.P1, causing a crash during garbage collection.
-//
-// This came up in a real program in issue 7725.
-
-type Outer struct {
-	*Inner
-	R io.Reader
-}
-
-type Inner struct {
-	X  *Outer
-	P1 uintptr
-	P2 uintptr
-}
-
-func (pi *Inner) M() {
-	// Clear references to pi so that the only way the
-	// garbage collection will find the pointer is in the
-	// argument frame, typed as a *Outer.
-	pi.X.Inner = nil
-
-	// Set up an interface value that will cause a crash.
-	// P1 = 1 is a non-zero, so the interface looks non-nil.
-	// P2 = pi ensures that the data word points into the
-	// allocated heap; if not the collection skips the interface
-	// value as irrelevant, without dereferencing P1.
-	pi.P1 = 1
-	pi.P2 = uintptr(unsafe.Pointer(pi))
-}
-
-func TestCallMethodJump(t *testing.T) {
-	// In reflect.Value.Call, trigger a garbage collection after reflect.call
-	// returns but before the args frame has been discarded.
-	// This is a little clumsy but makes the failure repeatable.
-	*CallGC = true
-
-	p := &Outer{Inner: new(Inner)}
-	p.Inner.X = p
-	ValueOf(p).Method(0).Call(nil)
-
-	// Stop garbage collecting during reflect.call.
-	*CallGC = false
-}
diff --git a/src/pkg/reflect/asm_386.s b/src/pkg/reflect/asm_386.s
deleted file mode 100644
index 75413c7..0000000
--- a/src/pkg/reflect/asm_386.s
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2012 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../cmd/ld/textflag.h"
-
-// makeFuncStub is the code half of the function returned by MakeFunc.
-// See the comment on the declaration of makeFuncStub in makefunc.go
-// for more details.
-// No argsize here, gc generates argsize info at call site.
-TEXT ·makeFuncStub(SB),(NOSPLIT|WRAPPER),$8
-	MOVL	DX, 0(SP)
-	LEAL	argframe+0(FP), CX
-	MOVL	CX, 4(SP)
-	CALL	·callReflect(SB)
-	RET
-
-// methodValueCall is the code half of the function returned by makeMethodValue.
-// See the comment on the declaration of methodValueCall in makefunc.go
-// for more details.
-// No argsize here, gc generates argsize info at call site.
-TEXT ·methodValueCall(SB),(NOSPLIT|WRAPPER),$8
-	MOVL	DX, 0(SP)
-	LEAL	argframe+0(FP), CX
-	MOVL	CX, 4(SP)
-	CALL	·callMethod(SB)
-	RET
diff --git a/src/pkg/reflect/asm_amd64.s b/src/pkg/reflect/asm_amd64.s
deleted file mode 100644
index 7129598..0000000
--- a/src/pkg/reflect/asm_amd64.s
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2012 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../cmd/ld/textflag.h"
-
-// makeFuncStub is the code half of the function returned by MakeFunc.
-// See the comment on the declaration of makeFuncStub in makefunc.go
-// for more details.
-// No argsize here, gc generates argsize info at call site.
-TEXT ·makeFuncStub(SB),(NOSPLIT|WRAPPER),$16
-	MOVQ	DX, 0(SP)
-	LEAQ	argframe+0(FP), CX
-	MOVQ	CX, 8(SP)
-	CALL	·callReflect(SB)
-	RET
-
-// methodValueCall is the code half of the function returned by makeMethodValue.
-// See the comment on the declaration of methodValueCall in makefunc.go
-// for more details.
-// No argsize here, gc generates argsize info at call site.
-TEXT ·methodValueCall(SB),(NOSPLIT|WRAPPER),$16
-	MOVQ	DX, 0(SP)
-	LEAQ	argframe+0(FP), CX
-	MOVQ	CX, 8(SP)
-	CALL	·callMethod(SB)
-	RET
diff --git a/src/pkg/reflect/asm_amd64p32.s b/src/pkg/reflect/asm_amd64p32.s
deleted file mode 100644
index 75413c7..0000000
--- a/src/pkg/reflect/asm_amd64p32.s
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2012 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../cmd/ld/textflag.h"
-
-// makeFuncStub is the code half of the function returned by MakeFunc.
-// See the comment on the declaration of makeFuncStub in makefunc.go
-// for more details.
-// No argsize here, gc generates argsize info at call site.
-TEXT ·makeFuncStub(SB),(NOSPLIT|WRAPPER),$8
-	MOVL	DX, 0(SP)
-	LEAL	argframe+0(FP), CX
-	MOVL	CX, 4(SP)
-	CALL	·callReflect(SB)
-	RET
-
-// methodValueCall is the code half of the function returned by makeMethodValue.
-// See the comment on the declaration of methodValueCall in makefunc.go
-// for more details.
-// No argsize here, gc generates argsize info at call site.
-TEXT ·methodValueCall(SB),(NOSPLIT|WRAPPER),$8
-	MOVL	DX, 0(SP)
-	LEAL	argframe+0(FP), CX
-	MOVL	CX, 4(SP)
-	CALL	·callMethod(SB)
-	RET
diff --git a/src/pkg/reflect/asm_arm.s b/src/pkg/reflect/asm_arm.s
deleted file mode 100644
index 68ded4a..0000000
--- a/src/pkg/reflect/asm_arm.s
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2012 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../cmd/ld/textflag.h"
-
-// makeFuncStub is jumped to by the code generated by MakeFunc.
-// See the comment on the declaration of makeFuncStub in makefunc.go
-// for more details.
-// No argsize here, gc generates argsize info at call site.
-TEXT ·makeFuncStub(SB),(NOSPLIT|WRAPPER),$8
-	MOVW	R7, 4(R13)
-	MOVW	$argframe+0(FP), R1
-	MOVW	R1, 8(R13)
-	BL	·callReflect(SB)
-	RET
-
-// methodValueCall is the code half of the function returned by makeMethodValue.
-// See the comment on the declaration of methodValueCall in makefunc.go
-// for more details.
-// No argsize here, gc generates argsize info at call site.
-TEXT ·methodValueCall(SB),(NOSPLIT|WRAPPER),$8
-	MOVW	R7, 4(R13)
-	MOVW	$argframe+0(FP), R1
-	MOVW	R1, 8(R13)
-	BL	·callMethod(SB)
-	RET
diff --git a/src/pkg/reflect/export_test.go b/src/pkg/reflect/export_test.go
deleted file mode 100644
index 0778ad3..0000000
--- a/src/pkg/reflect/export_test.go
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2012 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package reflect
-
-// MakeRO returns a copy of v with the read-only flag set.
-func MakeRO(v Value) Value {
-	v.flag |= flagRO
-	return v
-}
-
-// IsRO reports whether v's read-only flag is set.
-func IsRO(v Value) bool {
-	return v.flag&flagRO != 0
-}
-
-var ArrayOf = arrayOf
-var CallGC = &callGC
diff --git a/src/pkg/reflect/makefunc.go b/src/pkg/reflect/makefunc.go
deleted file mode 100644
index 0e61fde..0000000
--- a/src/pkg/reflect/makefunc.go
+++ /dev/null
@@ -1,120 +0,0 @@
-// Copyright 2012 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// MakeFunc implementation.
-
-package reflect
-
-import (
-	"unsafe"
-)
-
-// makeFuncImpl is the closure value implementing the function
-// returned by MakeFunc.
-type makeFuncImpl struct {
-	code uintptr
-	typ  *funcType
-	fn   func([]Value) []Value
-}
-
-// MakeFunc returns a new function of the given Type
-// that wraps the function fn. When called, that new function
-// does the following:
-//
-//	- converts its arguments to a slice of Values.
-//	- runs results := fn(args).
-//	- returns the results as a slice of Values, one per formal result.
-//
-// The implementation fn can assume that the argument Value slice
-// has the number and type of arguments given by typ.
-// If typ describes a variadic function, the final Value is itself
-// a slice representing the variadic arguments, as in the
-// body of a variadic function. The result Value slice returned by fn
-// must have the number and type of results given by typ.
-//
-// The Value.Call method allows the caller to invoke a typed function
-// in terms of Values; in contrast, MakeFunc allows the caller to implement
-// a typed function in terms of Values.
-//
-// The Examples section of the documentation includes an illustration
-// of how to use MakeFunc to build a swap function for different types.
-//
-func MakeFunc(typ Type, fn func(args []Value) (results []Value)) Value {
-	if typ.Kind() != Func {
-		panic("reflect: call of MakeFunc with non-Func type")
-	}
-
-	t := typ.common()
-	ftyp := (*funcType)(unsafe.Pointer(t))
-
-	// Indirect Go func value (dummy) to obtain
-	// actual code address. (A Go func value is a pointer
-	// to a C function pointer. http://golang.org/s/go11func.)
-	dummy := makeFuncStub
-	code := **(**uintptr)(unsafe.Pointer(&dummy))
-
-	impl := &makeFuncImpl{code: code, typ: ftyp, fn: fn}
-
-	return Value{t, unsafe.Pointer(impl), 0, flag(Func) << flagKindShift}
-}
-
-// makeFuncStub is an assembly function that is the code half of
-// the function returned from MakeFunc. It expects a *callReflectFunc
-// as its context register, and its job is to invoke callReflect(ctxt, frame)
-// where ctxt is the context register and frame is a pointer to the first
-// word in the passed-in argument frame.
-func makeFuncStub()
-
-type methodValue struct {
-	fn     uintptr
-	method int
-	rcvr   Value
-}
-
-// makeMethodValue converts v from the rcvr+method index representation
-// of a method value to an actual method func value, which is
-// basically the receiver value with a special bit set, into a true
-// func value - a value holding an actual func. The output is
-// semantically equivalent to the input as far as the user of package
-// reflect can tell, but the true func representation can be handled
-// by code like Convert and Interface and Assign.
-func makeMethodValue(op string, v Value) Value {
-	if v.flag&flagMethod == 0 {
-		panic("reflect: internal error: invalid use of makeMethodValue")
-	}
-
-	// Ignoring the flagMethod bit, v describes the receiver, not the method type.
-	fl := v.flag & (flagRO | flagAddr | flagIndir)
-	fl |= flag(v.typ.Kind()) << flagKindShift
-	rcvr := Value{v.typ, v.ptr, v.scalar, fl}
-
-	// v.Type returns the actual type of the method value.
-	funcType := v.Type().(*rtype)
-
-	// Indirect Go func value (dummy) to obtain
-	// actual code address. (A Go func value is a pointer
-	// to a C function pointer. http://golang.org/s/go11func.)
-	dummy := methodValueCall
-	code := **(**uintptr)(unsafe.Pointer(&dummy))
-
-	fv := &methodValue{
-		fn:     code,
-		method: int(v.flag) >> flagMethodShift,
-		rcvr:   rcvr,
-	}
-
-	// Cause panic if method is not appropriate.
-	// The panic would still happen during the call if we omit this,
-	// but we want Interface() and other operations to fail early.
-	methodReceiver(op, fv.rcvr, fv.method)
-
-	return Value{funcType, unsafe.Pointer(fv), 0, v.flag&flagRO | flag(Func)<<flagKindShift}
-}
-
-// methodValueCall is an assembly function that is the code half of
-// the function returned from makeMethodValue. It expects a *methodValue
-// as its context register, and its job is to invoke callMethod(ctxt, frame)
-// where ctxt is the context register and frame is a pointer to the first
-// word in the passed-in argument frame.
-func methodValueCall()
diff --git a/src/pkg/reflect/type.go b/src/pkg/reflect/type.go
deleted file mode 100644
index 40d76f9..0000000
--- a/src/pkg/reflect/type.go
+++ /dev/null
@@ -1,1926 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package reflect implements run-time reflection, allowing a program to
-// manipulate objects with arbitrary types.  The typical use is to take a value
-// with static type interface{} and extract its dynamic type information by
-// calling TypeOf, which returns a Type.
-//
-// A call to ValueOf returns a Value representing the run-time data.
-// Zero takes a Type and returns a Value representing a zero value
-// for that type.
-//
-// See "The Laws of Reflection" for an introduction to reflection in Go:
-// http://golang.org/doc/articles/laws_of_reflection.html
-package reflect
-
-import (
-	"runtime"
-	"strconv"
-	"sync"
-	"unsafe"
-)
-
-// Type is the representation of a Go type.
-//
-// Not all methods apply to all kinds of types.  Restrictions,
-// if any, are noted in the documentation for each method.
-// Use the Kind method to find out the kind of type before
-// calling kind-specific methods.  Calling a method
-// inappropriate to the kind of type causes a run-time panic.
-type Type interface {
-	// Methods applicable to all types.
-
-	// Align returns the alignment in bytes of a value of
-	// this type when allocated in memory.
-	Align() int
-
-	// FieldAlign returns the alignment in bytes of a value of
-	// this type when used as a field in a struct.
-	FieldAlign() int
-
-	// Method returns the i'th method in the type's method set.
-	// It panics if i is not in the range [0, NumMethod()).
-	//
-	// For a non-interface type T or *T, the returned Method's Type and Func
-	// fields describe a function whose first argument is the receiver.
-	//
-	// For an interface type, the returned Method's Type field gives the
-	// method signature, without a receiver, and the Func field is nil.
-	Method(int) Method
-
-	// MethodByName returns the method with that name in the type's
-	// method set and a boolean indicating if the method was found.
-	//
-	// For a non-interface type T or *T, the returned Method's Type and Func
-	// fields describe a function whose first argument is the receiver.
-	//
-	// For an interface type, the returned Method's Type field gives the
-	// method signature, without a receiver, and the Func field is nil.
-	MethodByName(string) (Method, bool)
-
-	// NumMethod returns the number of methods in the type's method set.
-	NumMethod() int
-
-	// Name returns the type's name within its package.
-	// It returns an empty string for unnamed types.
-	Name() string
-
-	// PkgPath returns a named type's package path, that is, the import path
-	// that uniquely identifies the package, such as "encoding/base64".
-	// If the type was predeclared (string, error) or unnamed (*T, struct{}, []int),
-	// the package path will be the empty string.
-	PkgPath() string
-
-	// Size returns the number of bytes needed to store
-	// a value of the given type; it is analogous to unsafe.Sizeof.
-	Size() uintptr
-
-	// String returns a string representation of the type.
-	// The string representation may use shortened package names
-	// (e.g., base64 instead of "encoding/base64") and is not
-	// guaranteed to be unique among types.  To test for equality,
-	// compare the Types directly.
-	String() string
-
-	// Kind returns the specific kind of this type.
-	Kind() Kind
-
-	// Implements returns true if the type implements the interface type u.
-	Implements(u Type) bool
-
-	// AssignableTo returns true if a value of the type is assignable to type u.
-	AssignableTo(u Type) bool
-
-	// ConvertibleTo returns true if a value of the type is convertible to type u.
-	ConvertibleTo(u Type) bool
-
-	// Methods applicable only to some types, depending on Kind.
-	// The methods allowed for each kind are:
-	//
-	//	Int*, Uint*, Float*, Complex*: Bits
-	//	Array: Elem, Len
-	//	Chan: ChanDir, Elem
-	//	Func: In, NumIn, Out, NumOut, IsVariadic.
-	//	Map: Key, Elem
-	//	Ptr: Elem
-	//	Slice: Elem
-	//	Struct: Field, FieldByIndex, FieldByName, FieldByNameFunc, NumField
-
-	// Bits returns the size of the type in bits.
-	// It panics if the type's Kind is not one of the
-	// sized or unsized Int, Uint, Float, or Complex kinds.
-	Bits() int
-
-	// ChanDir returns a channel type's direction.
-	// It panics if the type's Kind is not Chan.
-	ChanDir() ChanDir
-
-	// IsVariadic returns true if a function type's final input parameter
-	// is a "..." parameter.  If so, t.In(t.NumIn() - 1) returns the parameter's
-	// implicit actual type []T.
-	//
-	// For concreteness, if t represents func(x int, y ... float64), then
-	//
-	//	t.NumIn() == 2
-	//	t.In(0) is the reflect.Type for "int"
-	//	t.In(1) is the reflect.Type for "[]float64"
-	//	t.IsVariadic() == true
-	//
-	// IsVariadic panics if the type's Kind is not Func.
-	IsVariadic() bool
-
-	// Elem returns a type's element type.
-	// It panics if the type's Kind is not Array, Chan, Map, Ptr, or Slice.
-	Elem() Type
-
-	// Field returns a struct type's i'th field.
-	// It panics if the type's Kind is not Struct.
-	// It panics if i is not in the range [0, NumField()).
-	Field(i int) StructField
-
-	// FieldByIndex returns the nested field corresponding
-	// to the index sequence.  It is equivalent to calling Field
-	// successively for each index i.
-	// It panics if the type's Kind is not Struct.
-	FieldByIndex(index []int) StructField
-
-	// FieldByName returns the struct field with the given name
-	// and a boolean indicating if the field was found.
-	FieldByName(name string) (StructField, bool)
-
-	// FieldByNameFunc returns the first struct field with a name
-	// that satisfies the match function and a boolean indicating if
-	// the field was found.
-	FieldByNameFunc(match func(string) bool) (StructField, bool)
-
-	// In returns the type of a function type's i'th input parameter.
-	// It panics if the type's Kind is not Func.
-	// It panics if i is not in the range [0, NumIn()).
-	In(i int) Type
-
-	// Key returns a map type's key type.
-	// It panics if the type's Kind is not Map.
-	Key() Type
-
-	// Len returns an array type's length.
-	// It panics if the type's Kind is not Array.
-	Len() int
-
-	// NumField returns a struct type's field count.
-	// It panics if the type's Kind is not Struct.
-	NumField() int
-
-	// NumIn returns a function type's input parameter count.
-	// It panics if the type's Kind is not Func.
-	NumIn() int
-
-	// NumOut returns a function type's output parameter count.
-	// It panics if the type's Kind is not Func.
-	NumOut() int
-
-	// Out returns the type of a function type's i'th output parameter.
-	// It panics if the type's Kind is not Func.
-	// It panics if i is not in the range [0, NumOut()).
-	Out(i int) Type
-
-	common() *rtype
-	uncommon() *uncommonType
-}
-
-// BUG(rsc): FieldByName and related functions consider struct field names to be equal
-// if the names are equal, even if they are unexported names originating
-// in different packages. The practical effect of this is that the result of
-// t.FieldByName("x") is not well defined if the struct type t contains
-// multiple fields named x (embedded from different packages).
-// FieldByName may return one of the fields named x or may report that there are none.
-// See golang.org/issue/4876 for more details.
-
-/*
- * These data structures are known to the compiler (../../cmd/gc/reflect.c).
- * A few are known to ../runtime/type.go to convey to debuggers.
- * They are also known to ../runtime/type.h.
- */
-
-// A Kind represents the specific kind of type that a Type represents.
-// The zero Kind is not a valid kind.
-type Kind uint
-
-const (
-	Invalid Kind = iota
-	Bool
-	Int
-	Int8
-	Int16
-	Int32
-	Int64
-	Uint
-	Uint8
-	Uint16
-	Uint32
-	Uint64
-	Uintptr
-	Float32
-	Float64
-	Complex64
-	Complex128
-	Array
-	Chan
-	Func
-	Interface
-	Map
-	Ptr
-	Slice
-	String
-	Struct
-	UnsafePointer
-)
-
-// rtype is the common implementation of most values.
-// It is embedded in other, public struct types, but always
-// with a unique tag like `reflect:"array"` or `reflect:"ptr"`
-// so that code cannot convert from, say, *arrayType to *ptrType.
-type rtype struct {
-	size          uintptr        // size in bytes
-	hash          uint32         // hash of type; avoids computation in hash tables
-	_             uint8          // unused/padding
-	align         uint8          // alignment of variable with this type
-	fieldAlign    uint8          // alignment of struct field with this type
-	kind          uint8          // enumeration for C
-	alg           *uintptr       // algorithm table (../runtime/runtime.h:/Alg)
-	gc            unsafe.Pointer // garbage collection data
-	string        *string        // string form; unnecessary but undeniably useful
-	*uncommonType                // (relatively) uncommon fields
-	ptrToThis     *rtype         // type for pointer to this type, if used in binary or has methods
-	zero          unsafe.Pointer // pointer to zero value
-}
-
-// Method on non-interface type
-type method struct {
-	name    *string        // name of method
-	pkgPath *string        // nil for exported Names; otherwise import path
-	mtyp    *rtype         // method type (without receiver)
-	typ     *rtype         // .(*FuncType) underneath (with receiver)
-	ifn     unsafe.Pointer // fn used in interface call (one-word receiver)
-	tfn     unsafe.Pointer // fn used for normal method call
-}
-
-// uncommonType is present only for types with names or methods
-// (if T is a named type, the uncommonTypes for T and *T have methods).
-// Using a pointer to this struct reduces the overall size required
-// to describe an unnamed type with no methods.
-type uncommonType struct {
-	name    *string  // name of type
-	pkgPath *string  // import path; nil for built-in types like int, string
-	methods []method // methods associated with type
-}
-
-// ChanDir represents a channel type's direction.
-type ChanDir int
-
-const (
-	RecvDir ChanDir             = 1 << iota // <-chan
-	SendDir                                 // chan<-
-	BothDir = RecvDir | SendDir             // chan
-)
-
-// arrayType represents a fixed array type.
-type arrayType struct {
-	rtype `reflect:"array"`
-	elem  *rtype // array element type
-	slice *rtype // slice type
-	len   uintptr
-}
-
-// chanType represents a channel type.
-type chanType struct {
-	rtype `reflect:"chan"`
-	elem  *rtype  // channel element type
-	dir   uintptr // channel direction (ChanDir)
-}
-
-// funcType represents a function type.
-type funcType struct {
-	rtype     `reflect:"func"`
-	dotdotdot bool     // last input parameter is ...
-	in        []*rtype // input parameter types
-	out       []*rtype // output parameter types
-}
-
-// imethod represents a method on an interface type
-type imethod struct {
-	name    *string // name of method
-	pkgPath *string // nil for exported Names; otherwise import path
-	typ     *rtype  // .(*FuncType) underneath
-}
-
-// interfaceType represents an interface type.
-type interfaceType struct {
-	rtype   `reflect:"interface"`
-	methods []imethod // sorted by hash
-}
-
-// mapType represents a map type.
-type mapType struct {
-	rtype  `reflect:"map"`
-	key    *rtype // map key type
-	elem   *rtype // map element (value) type
-	bucket *rtype // internal bucket structure
-	hmap   *rtype // internal map header
-}
-
-// ptrType represents a pointer type.
-type ptrType struct {
-	rtype `reflect:"ptr"`
-	elem  *rtype // pointer element (pointed at) type
-}
-
-// sliceType represents a slice type.
-type sliceType struct {
-	rtype `reflect:"slice"`
-	elem  *rtype // slice element type
-}
-
-// Struct field
-type structField struct {
-	name    *string // nil for embedded fields
-	pkgPath *string // nil for exported Names; otherwise import path
-	typ     *rtype  // type of field
-	tag     *string // nil if no tag
-	offset  uintptr // byte offset of field within struct
-}
-
-// structType represents a struct type.
-type structType struct {
-	rtype  `reflect:"struct"`
-	fields []structField // sorted by offset
-}
-
-// NOTE: These are copied from ../runtime/mgc0.h.
-// They must be kept in sync.
-const (
-	_GC_END = iota
-	_GC_PTR
-	_GC_APTR
-	_GC_ARRAY_START
-	_GC_ARRAY_NEXT
-	_GC_CALL
-	_GC_CHAN_PTR
-	_GC_STRING
-	_GC_EFACE
-	_GC_IFACE
-	_GC_SLICE
-	_GC_REGION
-	_GC_NUM_INSTR
-)
-
-/*
- * The compiler knows the exact layout of all the data structures above.
- * The compiler does not know about the data structures and methods below.
- */
-
-// Method represents a single method.
-type Method struct {
-	// Name is the method name.
-	// PkgPath is the package path that qualifies a lower case (unexported)
-	// method name.  It is empty for upper case (exported) method names.
-	// The combination of PkgPath and Name uniquely identifies a method
-	// in a method set.
-	// See http://golang.org/ref/spec#Uniqueness_of_identifiers
-	Name    string
-	PkgPath string
-
-	Type  Type  // method type
-	Func  Value // func with receiver as first argument
-	Index int   // index for Type.Method
-}
-
-// High bit says whether type has
-// embedded pointers,to help garbage collector.
-const (
-	kindMask       = 0x7f
-	kindNoPointers = 0x80
-)
-
-func (k Kind) String() string {
-	if int(k) < len(kindNames) {
-		return kindNames[k]
-	}
-	return "kind" + strconv.Itoa(int(k))
-}
-
-var kindNames = []string{
-	Invalid:       "invalid",
-	Bool:          "bool",
-	Int:           "int",
-	Int8:          "int8",
-	Int16:         "int16",
-	Int32:         "int32",
-	Int64:         "int64",
-	Uint:          "uint",
-	Uint8:         "uint8",
-	Uint16:        "uint16",
-	Uint32:        "uint32",
-	Uint64:        "uint64",
-	Uintptr:       "uintptr",
-	Float32:       "float32",
-	Float64:       "float64",
-	Complex64:     "complex64",
-	Complex128:    "complex128",
-	Array:         "array",
-	Chan:          "chan",
-	Func:          "func",
-	Interface:     "interface",
-	Map:           "map",
-	Ptr:           "ptr",
-	Slice:         "slice",
-	String:        "string",
-	Struct:        "struct",
-	UnsafePointer: "unsafe.Pointer",
-}
-
-func (t *uncommonType) uncommon() *uncommonType {
-	return t
-}
-
-func (t *uncommonType) PkgPath() string {
-	if t == nil || t.pkgPath == nil {
-		return ""
-	}
-	return *t.pkgPath
-}
-
-func (t *uncommonType) Name() string {
-	if t == nil || t.name == nil {
-		return ""
-	}
-	return *t.name
-}
-
-func (t *rtype) String() string { return *t.string }
-
-func (t *rtype) Size() uintptr { return t.size }
-
-func (t *rtype) Bits() int {
-	if t == nil {
-		panic("reflect: Bits of nil Type")
-	}
-	k := t.Kind()
-	if k < Int || k > Complex128 {
-		panic("reflect: Bits of non-arithmetic Type " + t.String())
-	}
-	return int(t.size) * 8
-}
-
-func (t *rtype) Align() int { return int(t.align) }
-
-func (t *rtype) FieldAlign() int { return int(t.fieldAlign) }
-
-func (t *rtype) Kind() Kind { return Kind(t.kind & kindMask) }
-
-func (t *rtype) pointers() bool { return t.kind&kindNoPointers == 0 }
-
-func (t *rtype) common() *rtype { return t }
-
-func (t *uncommonType) Method(i int) (m Method) {
-	if t == nil || i < 0 || i >= len(t.methods) {
-		panic("reflect: Method index out of range")
-	}
-	p := &t.methods[i]
-	if p.name != nil {
-		m.Name = *p.name
-	}
-	fl := flag(Func) << flagKindShift
-	if p.pkgPath != nil {
-		m.PkgPath = *p.pkgPath
-		fl |= flagRO
-	}
-	mt := p.typ
-	m.Type = mt
-	fn := unsafe.Pointer(&p.tfn)
-	m.Func = Value{mt, fn, 0, fl}
-	m.Index = i
-	return
-}
-
-func (t *uncommonType) NumMethod() int {
-	if t == nil {
-		return 0
-	}
-	return len(t.methods)
-}
-
-func (t *uncommonType) MethodByName(name string) (m Method, ok bool) {
-	if t == nil {
-		return
-	}
-	var p *method
-	for i := range t.methods {
-		p = &t.methods[i]
-		if p.name != nil && *p.name == name {
-			return t.Method(i), true
-		}
-	}
-	return
-}
-
-// TODO(rsc): 6g supplies these, but they are not
-// as efficient as they could be: they have commonType
-// as the receiver instead of *rtype.
-func (t *rtype) NumMethod() int {
-	if t.Kind() == Interface {
-		tt := (*interfaceType)(unsafe.Pointer(t))
-		return tt.NumMethod()
-	}
-	return t.uncommonType.NumMethod()
-}
-
-func (t *rtype) Method(i int) (m Method) {
-	if t.Kind() == Interface {
-		tt := (*interfaceType)(unsafe.Pointer(t))
-		return tt.Method(i)
-	}
-	return t.uncommonType.Method(i)
-}
-
-func (t *rtype) MethodByName(name string) (m Method, ok bool) {
-	if t.Kind() == Interface {
-		tt := (*interfaceType)(unsafe.Pointer(t))
-		return tt.MethodByName(name)
-	}
-	return t.uncommonType.MethodByName(name)
-}
-
-func (t *rtype) PkgPath() string {
-	return t.uncommonType.PkgPath()
-}
-
-func (t *rtype) Name() string {
-	return t.uncommonType.Name()
-}
-
-func (t *rtype) ChanDir() ChanDir {
-	if t.Kind() != Chan {
-		panic("reflect: ChanDir of non-chan type")
-	}
-	tt := (*chanType)(unsafe.Pointer(t))
-	return ChanDir(tt.dir)
-}
-
-func (t *rtype) IsVariadic() bool {
-	if t.Kind() != Func {
-		panic("reflect: IsVariadic of non-func type")
-	}
-	tt := (*funcType)(unsafe.Pointer(t))
-	return tt.dotdotdot
-}
-
-func (t *rtype) Elem() Type {
-	switch t.Kind() {
-	case Array:
-		tt := (*arrayType)(unsafe.Pointer(t))
-		return toType(tt.elem)
-	case Chan:
-		tt := (*chanType)(unsafe.Pointer(t))
-		return toType(tt.elem)
-	case Map:
-		tt := (*mapType)(unsafe.Pointer(t))
-		return toType(tt.elem)
-	case Ptr:
-		tt := (*ptrType)(unsafe.Pointer(t))
-		return toType(tt.elem)
-	case Slice:
-		tt := (*sliceType)(unsafe.Pointer(t))
-		return toType(tt.elem)
-	}
-	panic("reflect: Elem of invalid type")
-}
-
-func (t *rtype) Field(i int) StructField {
-	if t.Kind() != Struct {
-		panic("reflect: Field of non-struct type")
-	}
-	tt := (*structType)(unsafe.Pointer(t))
-	return tt.Field(i)
-}
-
-func (t *rtype) FieldByIndex(index []int) StructField {
-	if t.Kind() != Struct {
-		panic("reflect: FieldByIndex of non-struct type")
-	}
-	tt := (*structType)(unsafe.Pointer(t))
-	return tt.FieldByIndex(index)
-}
-
-func (t *rtype) FieldByName(name string) (StructField, bool) {
-	if t.Kind() != Struct {
-		panic("reflect: FieldByName of non-struct type")
-	}
-	tt := (*structType)(unsafe.Pointer(t))
-	return tt.FieldByName(name)
-}
-
-func (t *rtype) FieldByNameFunc(match func(string) bool) (StructField, bool) {
-	if t.Kind() != Struct {
-		panic("reflect: FieldByNameFunc of non-struct type")
-	}
-	tt := (*structType)(unsafe.Pointer(t))
-	return tt.FieldByNameFunc(match)
-}
-
-func (t *rtype) In(i int) Type {
-	if t.Kind() != Func {
-		panic("reflect: In of non-func type")
-	}
-	tt := (*funcType)(unsafe.Pointer(t))
-	return toType(tt.in[i])
-}
-
-func (t *rtype) Key() Type {
-	if t.Kind() != Map {
-		panic("reflect: Key of non-map type")
-	}
-	tt := (*mapType)(unsafe.Pointer(t))
-	return toType(tt.key)
-}
-
-func (t *rtype) Len() int {
-	if t.Kind() != Array {
-		panic("reflect: Len of non-array type")
-	}
-	tt := (*arrayType)(unsafe.Pointer(t))
-	return int(tt.len)
-}
-
-func (t *rtype) NumField() int {
-	if t.Kind() != Struct {
-		panic("reflect: NumField of non-struct type")
-	}
-	tt := (*structType)(unsafe.Pointer(t))
-	return len(tt.fields)
-}
-
-func (t *rtype) NumIn() int {
-	if t.Kind() != Func {
-		panic("reflect: NumIn of non-func type")
-	}
-	tt := (*funcType)(unsafe.Pointer(t))
-	return len(tt.in)
-}
-
-func (t *rtype) NumOut() int {
-	if t.Kind() != Func {
-		panic("reflect: NumOut of non-func type")
-	}
-	tt := (*funcType)(unsafe.Pointer(t))
-	return len(tt.out)
-}
-
-func (t *rtype) Out(i int) Type {
-	if t.Kind() != Func {
-		panic("reflect: Out of non-func type")
-	}
-	tt := (*funcType)(unsafe.Pointer(t))
-	return toType(tt.out[i])
-}
-
-func (d ChanDir) String() string {
-	switch d {
-	case SendDir:
-		return "chan<-"
-	case RecvDir:
-		return "<-chan"
-	case BothDir:
-		return "chan"
-	}
-	return "ChanDir" + strconv.Itoa(int(d))
-}
-
-// Method returns the i'th method in the type's method set.
-func (t *interfaceType) Method(i int) (m Method) {
-	if i < 0 || i >= len(t.methods) {
-		return
-	}
-	p := &t.methods[i]
-	m.Name = *p.name
-	if p.pkgPath != nil {
-		m.PkgPath = *p.pkgPath
-	}
-	m.Type = toType(p.typ)
-	m.Index = i
-	return
-}
-
-// NumMethod returns the number of interface methods in the type's method set.
-func (t *interfaceType) NumMethod() int { return len(t.methods) }
-
-// MethodByName method with the given name in the type's method set.
-func (t *interfaceType) MethodByName(name string) (m Method, ok bool) {
-	if t == nil {
-		return
-	}
-	var p *imethod
-	for i := range t.methods {
-		p = &t.methods[i]
-		if *p.name == name {
-			return t.Method(i), true
-		}
-	}
-	return
-}
-
-// A StructField describes a single field in a struct.
-type StructField struct {
-	// Name is the field name.
-	// PkgPath is the package path that qualifies a lower case (unexported)
-	// field name.  It is empty for upper case (exported) field names.
-	// See http://golang.org/ref/spec#Uniqueness_of_identifiers
-	Name    string
-	PkgPath string
-
-	Type      Type      // field type
-	Tag       StructTag // field tag string
-	Offset    uintptr   // offset within struct, in bytes
-	Index     []int     // index sequence for Type.FieldByIndex
-	Anonymous bool      // is an embedded field
-}
-
-// A StructTag is the tag string in a struct field.
-//
-// By convention, tag strings are a concatenation of
-// optionally space-separated key:"value" pairs.
-// Each key is a non-empty string consisting of non-control
-// characters other than space (U+0020 ' '), quote (U+0022 '"'),
-// and colon (U+003A ':').  Each value is quoted using U+0022 '"'
-// characters and Go string literal syntax.
-type StructTag string
-
-// Get returns the value associated with key in the tag string.
-// If there is no such key in the tag, Get returns the empty string.
-// If the tag does not have the conventional format, the value
-// returned by Get is unspecified.
-func (tag StructTag) Get(key string) string {
-	for tag != "" {
-		// skip leading space
-		i := 0
-		for i < len(tag) && tag[i] == ' ' {
-			i++
-		}
-		tag = tag[i:]
-		if tag == "" {
-			break
-		}
-
-		// scan to colon.
-		// a space or a quote is a syntax error
-		i = 0
-		for i < len(tag) && tag[i] != ' ' && tag[i] != ':' && tag[i] != '"' {
-			i++
-		}
-		if i+1 >= len(tag) || tag[i] != ':' || tag[i+1] != '"' {
-			break
-		}
-		name := string(tag[:i])
-		tag = tag[i+1:]
-
-		// scan quoted string to find value
-		i = 1
-		for i < len(tag) && tag[i] != '"' {
-			if tag[i] == '\\' {
-				i++
-			}
-			i++
-		}
-		if i >= len(tag) {
-			break
-		}
-		qvalue := string(tag[:i+1])
-		tag = tag[i+1:]
-
-		if key == name {
-			value, _ := strconv.Unquote(qvalue)
-			return value
-		}
-	}
-	return ""
-}
-
-// Field returns the i'th struct field.
-func (t *structType) Field(i int) (f StructField) {
-	if i < 0 || i >= len(t.fields) {
-		return
-	}
-	p := &t.fields[i]
-	f.Type = toType(p.typ)
-	if p.name != nil {
-		f.Name = *p.name
-	} else {
-		t := f.Type
-		if t.Kind() == Ptr {
-			t = t.Elem()
-		}
-		f.Name = t.Name()
-		f.Anonymous = true
-	}
-	if p.pkgPath != nil {
-		f.PkgPath = *p.pkgPath
-	}
-	if p.tag != nil {
-		f.Tag = StructTag(*p.tag)
-	}
-	f.Offset = p.offset
-
-	// NOTE(rsc): This is the only allocation in the interface
-	// presented by a reflect.Type.  It would be nice to avoid,
-	// at least in the common cases, but we need to make sure
-	// that misbehaving clients of reflect cannot affect other
-	// uses of reflect.  One possibility is CL 5371098, but we
-	// postponed that ugliness until there is a demonstrated
-	// need for the performance.  This is issue 2320.
-	f.Index = []int{i}
-	return
-}
-
-// TODO(gri): Should there be an error/bool indicator if the index
-//            is wrong for FieldByIndex?
-
-// FieldByIndex returns the nested field corresponding to index.
-func (t *structType) FieldByIndex(index []int) (f StructField) {
-	f.Type = toType(&t.rtype)
-	for i, x := range index {
-		if i > 0 {
-			ft := f.Type
-			if ft.Kind() == Ptr && ft.Elem().Kind() == Struct {
-				ft = ft.Elem()
-			}
-			f.Type = ft
-		}
-		f = f.Type.Field(x)
-	}
-	return
-}
-
-// A fieldScan represents an item on the fieldByNameFunc scan work list.
-type fieldScan struct {
-	typ   *structType
-	index []int
-}
-
-// FieldByNameFunc returns the struct field with a name that satisfies the
-// match function and a boolean to indicate if the field was found.
-func (t *structType) FieldByNameFunc(match func(string) bool) (result StructField, ok bool) {
-	// This uses the same condition that the Go language does: there must be a unique instance
-	// of the match at a given depth level. If there are multiple instances of a match at the
-	// same depth, they annihilate each other and inhibit any possible match at a lower level.
-	// The algorithm is breadth first search, one depth level at a time.
-
-	// The current and next slices are work queues:
-	// current lists the fields to visit on this depth level,
-	// and next lists the fields on the next lower level.
-	current := []fieldScan{}
-	next := []fieldScan{{typ: t}}
-
-	// nextCount records the number of times an embedded type has been
-	// encountered and considered for queueing in the 'next' slice.
-	// We only queue the first one, but we increment the count on each.
-	// If a struct type T can be reached more than once at a given depth level,
-	// then it annihilates itself and need not be considered at all when we
-	// process that next depth level.
-	var nextCount map[*structType]int
-
-	// visited records the structs that have been considered already.
-	// Embedded pointer fields can create cycles in the graph of
-	// reachable embedded types; visited avoids following those cycles.
-	// It also avoids duplicated effort: if we didn't find the field in an
-	// embedded type T at level 2, we won't find it in one at level 4 either.
-	visited := map[*structType]bool{}
-
-	for len(next) > 0 {
-		current, next = next, current[:0]
-		count := nextCount
-		nextCount = nil
-
-		// Process all the fields at this depth, now listed in 'current'.
-		// The loop queues embedded fields found in 'next', for processing during the next
-		// iteration. The multiplicity of the 'current' field counts is recorded
-		// in 'count'; the multiplicity of the 'next' field counts is recorded in 'nextCount'.
-		for _, scan := range current {
-			t := scan.typ
-			if visited[t] {
-				// We've looked through this type before, at a higher level.
-				// That higher level would shadow the lower level we're now at,
-				// so this one can't be useful to us. Ignore it.
-				continue
-			}
-			visited[t] = true
-			for i := range t.fields {
-				f := &t.fields[i]
-				// Find name and type for field f.
-				var fname string
-				var ntyp *rtype
-				if f.name != nil {
-					fname = *f.name
-				} else {
-					// Anonymous field of type T or *T.
-					// Name taken from type.
-					ntyp = f.typ
-					if ntyp.Kind() == Ptr {
-						ntyp = ntyp.Elem().common()
-					}
-					fname = ntyp.Name()
-				}
-
-				// Does it match?
-				if match(fname) {
-					// Potential match
-					if count[t] > 1 || ok {
-						// Name appeared multiple times at this level: annihilate.
-						return StructField{}, false
-					}
-					result = t.Field(i)
-					result.Index = nil
-					result.Index = append(result.Index, scan.index...)
-					result.Index = append(result.Index, i)
-					ok = true
-					continue
-				}
-
-				// Queue embedded struct fields for processing with next level,
-				// but only if we haven't seen a match yet at this level and only
-				// if the embedded types haven't already been queued.
-				if ok || ntyp == nil || ntyp.Kind() != Struct {
-					continue
-				}
-				styp := (*structType)(unsafe.Pointer(ntyp))
-				if nextCount[styp] > 0 {
-					nextCount[styp] = 2 // exact multiple doesn't matter
-					continue
-				}
-				if nextCount == nil {
-					nextCount = map[*structType]int{}
-				}
-				nextCount[styp] = 1
-				if count[t] > 1 {
-					nextCount[styp] = 2 // exact multiple doesn't matter
-				}
-				var index []int
-				index = append(index, scan.index...)
-				index = append(index, i)
-				next = append(next, fieldScan{styp, index})
-			}
-		}
-		if ok {
-			break
-		}
-	}
-	return
-}
-
-// FieldByName returns the struct field with the given name
-// and a boolean to indicate if the field was found.
-func (t *structType) FieldByName(name string) (f StructField, present bool) {
-	// Quick check for top-level name, or struct without anonymous fields.
-	hasAnon := false
-	if name != "" {
-		for i := range t.fields {
-			tf := &t.fields[i]
-			if tf.name == nil {
-				hasAnon = true
-				continue
-			}
-			if *tf.name == name {
-				return t.Field(i), true
-			}
-		}
-	}
-	if !hasAnon {
-		return
-	}
-	return t.FieldByNameFunc(func(s string) bool { return s == name })
-}
-
-// TypeOf returns the reflection Type of the value in the interface{}.
-// TypeOf(nil) returns nil.
-func TypeOf(i interface{}) Type {
-	eface := *(*emptyInterface)(unsafe.Pointer(&i))
-	return toType(eface.typ)
-}
-
-// ptrMap is the cache for PtrTo.
-var ptrMap struct {
-	sync.RWMutex
-	m map[*rtype]*ptrType
-}
-
-// garbage collection bytecode program for pointer to memory without pointers.
-// See ../../cmd/gc/reflect.c:/^dgcsym1 and :/^dgcsym.
-type ptrDataGC struct {
-	width uintptr // sizeof(ptr)
-	op    uintptr // _GC_APTR
-	off   uintptr // 0
-	end   uintptr // _GC_END
-}
-
-var ptrDataGCProg = ptrDataGC{
-	width: unsafe.Sizeof((*byte)(nil)),
-	op:    _GC_APTR,
-	off:   0,
-	end:   _GC_END,
-}
-
-// garbage collection bytecode program for pointer to memory with pointers.
-// See ../../cmd/gc/reflect.c:/^dgcsym1 and :/^dgcsym.
-type ptrGC struct {
-	width  uintptr        // sizeof(ptr)
-	op     uintptr        // _GC_PTR
-	off    uintptr        // 0
-	elemgc unsafe.Pointer // element gc type
-	end    uintptr        // _GC_END
-}
-
-// PtrTo returns the pointer type with element t.
-// For example, if t represents type Foo, PtrTo(t) represents *Foo.
-func PtrTo(t Type) Type {
-	return t.(*rtype).ptrTo()
-}
-
-func (t *rtype) ptrTo() *rtype {
-	if p := t.ptrToThis; p != nil {
-		return p
-	}
-
-	// Otherwise, synthesize one.
-	// This only happens for pointers with no methods.
-	// We keep the mapping in a map on the side, because
-	// this operation is rare and a separate map lets us keep
-	// the type structures in read-only memory.
-	ptrMap.RLock()
-	if m := ptrMap.m; m != nil {
-		if p := m[t]; p != nil {
-			ptrMap.RUnlock()
-			return &p.rtype
-		}
-	}
-	ptrMap.RUnlock()
-	ptrMap.Lock()
-	if ptrMap.m == nil {
-		ptrMap.m = make(map[*rtype]*ptrType)
-	}
-	p := ptrMap.m[t]
-	if p != nil {
-		// some other goroutine won the race and created it
-		ptrMap.Unlock()
-		return &p.rtype
-	}
-
-	// Create a new ptrType starting with the description
-	// of an *unsafe.Pointer.
-	p = new(ptrType)
-	var iptr interface{} = (*unsafe.Pointer)(nil)
-	prototype := *(**ptrType)(unsafe.Pointer(&iptr))
-	*p = *prototype
-
-	s := "*" + *t.string
-	p.string = &s
-
-	// For the type structures linked into the binary, the
-	// compiler provides a good hash of the string.
-	// Create a good hash for the new string by using
-	// the FNV-1 hash's mixing function to combine the
-	// old hash and the new "*".
-	p.hash = fnv1(t.hash, '*')
-
-	p.uncommonType = nil
-	p.ptrToThis = nil
-	p.zero = unsafe.Pointer(&make([]byte, p.size)[0])
-	p.elem = t
-
-	if t.kind&kindNoPointers != 0 {
-		p.gc = unsafe.Pointer(&ptrDataGCProg)
-	} else {
-		p.gc = unsafe.Pointer(&ptrGC{
-			width:  p.size,
-			op:     _GC_PTR,
-			off:    0,
-			elemgc: t.gc,
-			end:    _GC_END,
-		})
-	}
-	// INCORRECT. Uncomment to check that TestPtrToGC fails when p.gc is wrong.
-	//p.gc = unsafe.Pointer(&badGC{width: p.size, end: _GC_END})
-
-	ptrMap.m[t] = p
-	ptrMap.Unlock()
-	return &p.rtype
-}
-
-// fnv1 incorporates the list of bytes into the hash x using the FNV-1 hash function.
-func fnv1(x uint32, list ...byte) uint32 {
-	for _, b := range list {
-		x = x*16777619 ^ uint32(b)
-	}
-	return x
-}
-
-func (t *rtype) Implements(u Type) bool {
-	if u == nil {
-		panic("reflect: nil type passed to Type.Implements")
-	}
-	if u.Kind() != Interface {
-		panic("reflect: non-interface type passed to Type.Implements")
-	}
-	return implements(u.(*rtype), t)
-}
-
-func (t *rtype) AssignableTo(u Type) bool {
-	if u == nil {
-		panic("reflect: nil type passed to Type.AssignableTo")
-	}
-	uu := u.(*rtype)
-	return directlyAssignable(uu, t) || implements(uu, t)
-}
-
-func (t *rtype) ConvertibleTo(u Type) bool {
-	if u == nil {
-		panic("reflect: nil type passed to Type.ConvertibleTo")
-	}
-	uu := u.(*rtype)
-	return convertOp(uu, t) != nil
-}
-
-// implements returns true if the type V implements the interface type T.
-func implements(T, V *rtype) bool {
-	if T.Kind() != Interface {
-		return false
-	}
-	t := (*interfaceType)(unsafe.Pointer(T))
-	if len(t.methods) == 0 {
-		return true
-	}
-
-	// The same algorithm applies in both cases, but the
-	// method tables for an interface type and a concrete type
-	// are different, so the code is duplicated.
-	// In both cases the algorithm is a linear scan over the two
-	// lists - T's methods and V's methods - simultaneously.
-	// Since method tables are stored in a unique sorted order
-	// (alphabetical, with no duplicate method names), the scan
-	// through V's methods must hit a match for each of T's
-	// methods along the way, or else V does not implement T.
-	// This lets us run the scan in overall linear time instead of
-	// the quadratic time  a naive search would require.
-	// See also ../runtime/iface.c.
-	if V.Kind() == Interface {
-		v := (*interfaceType)(unsafe.Pointer(V))
-		i := 0
-		for j := 0; j < len(v.methods); j++ {
-			tm := &t.methods[i]
-			vm := &v.methods[j]
-			if vm.name == tm.name && vm.pkgPath == tm.pkgPath && vm.typ == tm.typ {
-				if i++; i >= len(t.methods) {
-					return true
-				}
-			}
-		}
-		return false
-	}
-
-	v := V.uncommon()
-	if v == nil {
-		return false
-	}
-	i := 0
-	for j := 0; j < len(v.methods); j++ {
-		tm := &t.methods[i]
-		vm := &v.methods[j]
-		if vm.name == tm.name && vm.pkgPath == tm.pkgPath && vm.mtyp == tm.typ {
-			if i++; i >= len(t.methods) {
-				return true
-			}
-		}
-	}
-	return false
-}
-
-// directlyAssignable returns true if a value x of type V can be directly
-// assigned (using memmove) to a value of type T.
-// http://golang.org/doc/go_spec.html#Assignability
-// Ignoring the interface rules (implemented elsewhere)
-// and the ideal constant rules (no ideal constants at run time).
-func directlyAssignable(T, V *rtype) bool {
-	// x's type V is identical to T?
-	if T == V {
-		return true
-	}
-
-	// Otherwise at least one of T and V must be unnamed
-	// and they must have the same kind.
-	if T.Name() != "" && V.Name() != "" || T.Kind() != V.Kind() {
-		return false
-	}
-
-	// x's type T and V must  have identical underlying types.
-	return haveIdenticalUnderlyingType(T, V)
-}
-
-func haveIdenticalUnderlyingType(T, V *rtype) bool {
-	if T == V {
-		return true
-	}
-
-	kind := T.Kind()
-	if kind != V.Kind() {
-		return false
-	}
-
-	// Non-composite types of equal kind have same underlying type
-	// (the predefined instance of the type).
-	if Bool <= kind && kind <= Complex128 || kind == String || kind == UnsafePointer {
-		return true
-	}
-
-	// Composite types.
-	switch kind {
-	case Array:
-		return T.Elem() == V.Elem() && T.Len() == V.Len()
-
-	case Chan:
-		// Special case:
-		// x is a bidirectional channel value, T is a channel type,
-		// and x's type V and T have identical element types.
-		if V.ChanDir() == BothDir && T.Elem() == V.Elem() {
-			return true
-		}
-
-		// Otherwise continue test for identical underlying type.
-		return V.ChanDir() == T.ChanDir() && T.Elem() == V.Elem()
-
-	case Func:
-		t := (*funcType)(unsafe.Pointer(T))
-		v := (*funcType)(unsafe.Pointer(V))
-		if t.dotdotdot != v.dotdotdot || len(t.in) != len(v.in) || len(t.out) != len(v.out) {
-			return false
-		}
-		for i, typ := range t.in {
-			if typ != v.in[i] {
-				return false
-			}
-		}
-		for i, typ := range t.out {
-			if typ != v.out[i] {
-				return false
-			}
-		}
-		return true
-
-	case Interface:
-		t := (*interfaceType)(unsafe.Pointer(T))
-		v := (*interfaceType)(unsafe.Pointer(V))
-		if len(t.methods) == 0 && len(v.methods) == 0 {
-			return true
-		}
-		// Might have the same methods but still
-		// need a run time conversion.
-		return false
-
-	case Map:
-		return T.Key() == V.Key() && T.Elem() == V.Elem()
-
-	case Ptr, Slice:
-		return T.Elem() == V.Elem()
-
-	case Struct:
-		t := (*structType)(unsafe.Pointer(T))
-		v := (*structType)(unsafe.Pointer(V))
-		if len(t.fields) != len(v.fields) {
-			return false
-		}
-		for i := range t.fields {
-			tf := &t.fields[i]
-			vf := &v.fields[i]
-			if tf.name != vf.name && (tf.name == nil || vf.name == nil || *tf.name != *vf.name) {
-				return false
-			}
-			if tf.pkgPath != vf.pkgPath && (tf.pkgPath == nil || vf.pkgPath == nil || *tf.pkgPath != *vf.pkgPath) {
-				return false
-			}
-			if tf.typ != vf.typ {
-				return false
-			}
-			if tf.tag != vf.tag && (tf.tag == nil || vf.tag == nil || *tf.tag != *vf.tag) {
-				return false
-			}
-			if tf.offset != vf.offset {
-				return false
-			}
-		}
-		return true
-	}
-
-	return false
-}
-
-// typelinks is implemented in package runtime.
-// It returns a slice of all the 'typelink' information in the binary,
-// which is to say a slice of known types, sorted by string.
-// Note that strings are not unique identifiers for types:
-// there can be more than one with a given string.
-// Only types we might want to look up are included:
-// channels, maps, slices, and arrays.
-func typelinks() []*rtype
-
-// typesByString returns the subslice of typelinks() whose elements have
-// the given string representation.
-// It may be empty (no known types with that string) or may have
-// multiple elements (multiple types with that string).
-func typesByString(s string) []*rtype {
-	typ := typelinks()
-
-	// We are looking for the first index i where the string becomes >= s.
-	// This is a copy of sort.Search, with f(h) replaced by (*typ[h].string >= s).
-	i, j := 0, len(typ)
-	for i < j {
-		h := i + (j-i)/2 // avoid overflow when computing h
-		// i ≤ h < j
-		if !(*typ[h].string >= s) {
-			i = h + 1 // preserves f(i-1) == false
-		} else {
-			j = h // preserves f(j) == true
-		}
-	}
-	// i == j, f(i-1) == false, and f(j) (= f(i)) == true  =>  answer is i.
-
-	// Having found the first, linear scan forward to find the last.
-	// We could do a second binary search, but the caller is going
-	// to do a linear scan anyway.
-	j = i
-	for j < len(typ) && *typ[j].string == s {
-		j++
-	}
-
-	// This slice will be empty if the string is not found.
-	return typ[i:j]
-}
-
-// The lookupCache caches ChanOf, MapOf, and SliceOf lookups.
-var lookupCache struct {
-	sync.RWMutex
-	m map[cacheKey]*rtype
-}
-
-// A cacheKey is the key for use in the lookupCache.
-// Four values describe any of the types we are looking for:
-// type kind, one or two subtypes, and an extra integer.
-type cacheKey struct {
-	kind  Kind
-	t1    *rtype
-	t2    *rtype
-	extra uintptr
-}
-
-// cacheGet looks for a type under the key k in the lookupCache.
-// If it finds one, it returns that type.
-// If not, it returns nil with the cache locked.
-// The caller is expected to use cachePut to unlock the cache.
-func cacheGet(k cacheKey) Type {
-	lookupCache.RLock()
-	t := lookupCache.m[k]
-	lookupCache.RUnlock()
-	if t != nil {
-		return t
-	}
-
-	lookupCache.Lock()
-	t = lookupCache.m[k]
-	if t != nil {
-		lookupCache.Unlock()
-		return t
-	}
-
-	if lookupCache.m == nil {
-		lookupCache.m = make(map[cacheKey]*rtype)
-	}
-
-	return nil
-}
-
-// cachePut stores the given type in the cache, unlocks the cache,
-// and returns the type. It is expected that the cache is locked
-// because cacheGet returned nil.
-func cachePut(k cacheKey, t *rtype) Type {
-	lookupCache.m[k] = t
-	lookupCache.Unlock()
-	return t
-}
-
-// garbage collection bytecode program for chan.
-// See ../../cmd/gc/reflect.c:/^dgcsym1 and :/^dgcsym.
-type chanGC struct {
-	width uintptr // sizeof(map)
-	op    uintptr // _GC_CHAN_PTR
-	off   uintptr // 0
-	typ   *rtype  // map type
-	end   uintptr // _GC_END
-}
-
-type badGC struct {
-	width uintptr
-	end   uintptr
-}
-
-// ChanOf returns the channel type with the given direction and element type.
-// For example, if t represents int, ChanOf(RecvDir, t) represents <-chan int.
-//
-// The gc runtime imposes a limit of 64 kB on channel element types.
-// If t's size is equal to or exceeds this limit, ChanOf panics.
-func ChanOf(dir ChanDir, t Type) Type {
-	typ := t.(*rtype)
-
-	// Look in cache.
-	ckey := cacheKey{Chan, typ, nil, uintptr(dir)}
-	if ch := cacheGet(ckey); ch != nil {
-		return ch
-	}
-
-	// This restriction is imposed by the gc compiler and the runtime.
-	if typ.size >= 1<<16 {
-		lookupCache.Unlock()
-		panic("reflect.ChanOf: element size too large")
-	}
-
-	// Look in known types.
-	// TODO: Precedence when constructing string.
-	var s string
-	switch dir {
-	default:
-		lookupCache.Unlock()
-		panic("reflect.ChanOf: invalid dir")
-	case SendDir:
-		s = "chan<- " + *typ.string
-	case RecvDir:
-		s = "<-chan " + *typ.string
-	case BothDir:
-		s = "chan " + *typ.string
-	}
-	for _, tt := range typesByString(s) {
-		ch := (*chanType)(unsafe.Pointer(tt))
-		if ch.elem == typ && ch.dir == uintptr(dir) {
-			return cachePut(ckey, tt)
-		}
-	}
-
-	// Make a channel type.
-	var ichan interface{} = (chan unsafe.Pointer)(nil)
-	prototype := *(**chanType)(unsafe.Pointer(&ichan))
-	ch := new(chanType)
-	*ch = *prototype
-	ch.string = &s
-	ch.hash = fnv1(typ.hash, 'c', byte(dir))
-	ch.elem = typ
-	ch.uncommonType = nil
-	ch.ptrToThis = nil
-	ch.zero = unsafe.Pointer(&make([]byte, ch.size)[0])
-
-	ch.gc = unsafe.Pointer(&chanGC{
-		width: ch.size,
-		op:    _GC_CHAN_PTR,
-		off:   0,
-		typ:   &ch.rtype,
-		end:   _GC_END,
-	})
-
-	// INCORRECT. Uncomment to check that TestChanOfGC fails when ch.gc is wrong.
-	//ch.gc = unsafe.Pointer(&badGC{width: ch.size, end: _GC_END})
-
-	return cachePut(ckey, &ch.rtype)
-}
-
-func ismapkey(*rtype) bool // implemented in runtime
-
-// MapOf returns the map type with the given key and element types.
-// For example, if k represents int and e represents string,
-// MapOf(k, e) represents map[int]string.
-//
-// If the key type is not a valid map key type (that is, if it does
-// not implement Go's == operator), MapOf panics.
-func MapOf(key, elem Type) Type {
-	ktyp := key.(*rtype)
-	etyp := elem.(*rtype)
-
-	if !ismapkey(ktyp) {
-		panic("reflect.MapOf: invalid key type " + ktyp.String())
-	}
-
-	// Look in cache.
-	ckey := cacheKey{Map, ktyp, etyp, 0}
-	if mt := cacheGet(ckey); mt != nil {
-		return mt
-	}
-
-	// Look in known types.
-	s := "map[" + *ktyp.string + "]" + *etyp.string
-	for _, tt := range typesByString(s) {
-		mt := (*mapType)(unsafe.Pointer(tt))
-		if mt.key == ktyp && mt.elem == etyp {
-			return cachePut(ckey, tt)
-		}
-	}
-
-	// Make a map type.
-	var imap interface{} = (map[unsafe.Pointer]unsafe.Pointer)(nil)
-	prototype := *(**mapType)(unsafe.Pointer(&imap))
-	mt := new(mapType)
-	*mt = *prototype
-	mt.string = &s
-	mt.hash = fnv1(etyp.hash, 'm', byte(ktyp.hash>>24), byte(ktyp.hash>>16), byte(ktyp.hash>>8), byte(ktyp.hash))
-	mt.key = ktyp
-	mt.elem = etyp
-	mt.bucket = bucketOf(ktyp, etyp)
-	mt.hmap = hMapOf(mt.bucket)
-	mt.uncommonType = nil
-	mt.ptrToThis = nil
-	mt.zero = unsafe.Pointer(&make([]byte, mt.size)[0])
-	mt.gc = unsafe.Pointer(&ptrGC{
-		width:  unsafe.Sizeof(uintptr(0)),
-		op:     _GC_PTR,
-		off:    0,
-		elemgc: mt.hmap.gc,
-		end:    _GC_END,
-	})
-
-	// INCORRECT. Uncomment to check that TestMapOfGC and TestMapOfGCValues
-	// fail when mt.gc is wrong.
-	//mt.gc = unsafe.Pointer(&badGC{width: mt.size, end: _GC_END})
-
-	return cachePut(ckey, &mt.rtype)
-}
-
-// Make sure these routines stay in sync with ../../pkg/runtime/hashmap.c!
-// These types exist only for GC, so we only fill out GC relevant info.
-// Currently, that's just size and the GC program.  We also fill in string
-// for possible debugging use.
-const (
-	_BUCKETSIZE = 8
-	_MAXKEYSIZE = 128
-	_MAXVALSIZE = 128
-)
-
-func bucketOf(ktyp, etyp *rtype) *rtype {
-	if ktyp.size > _MAXKEYSIZE {
-		ktyp = PtrTo(ktyp).(*rtype)
-	}
-	if etyp.size > _MAXVALSIZE {
-		etyp = PtrTo(etyp).(*rtype)
-	}
-	ptrsize := unsafe.Sizeof(uintptr(0))
-
-	gc := make([]uintptr, 1)                                       // first entry is size, filled in at the end
-	offset := _BUCKETSIZE * unsafe.Sizeof(uint8(0))                // topbits
-	gc = append(gc, _GC_PTR, offset, 0 /*self pointer set below*/) // overflow
-	offset += ptrsize
-
-	if runtime.GOARCH == "amd64p32" {
-		offset += 4
-	}
-
-	// keys
-	if ktyp.kind&kindNoPointers == 0 {
-		gc = append(gc, _GC_ARRAY_START, offset, _BUCKETSIZE, ktyp.size)
-		gc = appendGCProgram(gc, ktyp)
-		gc = append(gc, _GC_ARRAY_NEXT)
-	}
-	offset += _BUCKETSIZE * ktyp.size
-
-	// values
-	if etyp.kind&kindNoPointers == 0 {
-		gc = append(gc, _GC_ARRAY_START, offset, _BUCKETSIZE, etyp.size)
-		gc = appendGCProgram(gc, etyp)
-		gc = append(gc, _GC_ARRAY_NEXT)
-	}
-	offset += _BUCKETSIZE * etyp.size
-
-	gc = append(gc, _GC_END)
-	gc[0] = offset
-	gc[3] = uintptr(unsafe.Pointer(&gc[0])) // set self pointer
-
-	b := new(rtype)
-	b.size = offset
-	b.gc = unsafe.Pointer(&gc[0])
-	s := "bucket(" + *ktyp.string + "," + *etyp.string + ")"
-	b.string = &s
-	return b
-}
-
-// Take the GC program for "t" and append it to the GC program "gc".
-func appendGCProgram(gc []uintptr, t *rtype) []uintptr {
-	p := t.gc
-	p = unsafe.Pointer(uintptr(p) + unsafe.Sizeof(uintptr(0))) // skip size
-loop:
-	for {
-		var argcnt int
-		switch *(*uintptr)(p) {
-		case _GC_END:
-			// Note: _GC_END not included in append
-			break loop
-		case _GC_ARRAY_NEXT:
-			argcnt = 0
-		case _GC_APTR, _GC_STRING, _GC_EFACE, _GC_IFACE:
-			argcnt = 1
-		case _GC_PTR, _GC_CALL, _GC_CHAN_PTR, _GC_SLICE:
-			argcnt = 2
-		case _GC_ARRAY_START, _GC_REGION:
-			argcnt = 3
-		default:
-			panic("unknown GC program op for " + *t.string + ": " + strconv.FormatUint(*(*uint64)(p), 10))
-		}
-		for i := 0; i < argcnt+1; i++ {
-			gc = append(gc, *(*uintptr)(p))
-			p = unsafe.Pointer(uintptr(p) + unsafe.Sizeof(uintptr(0)))
-		}
-	}
-	return gc
-}
-func hMapOf(bucket *rtype) *rtype {
-	ptrsize := unsafe.Sizeof(uintptr(0))
-
-	// make gc program & compute hmap size
-	gc := make([]uintptr, 1)           // first entry is size, filled in at the end
-	offset := unsafe.Sizeof(uint(0))   // count
-	offset += unsafe.Sizeof(uint32(0)) // flags
-	offset += unsafe.Sizeof(uint32(0)) // hash0
-	offset += unsafe.Sizeof(uint8(0))  // B
-	offset += unsafe.Sizeof(uint8(0))  // keysize
-	offset += unsafe.Sizeof(uint8(0))  // valuesize
-	offset = (offset + 1) / 2 * 2
-	offset += unsafe.Sizeof(uint16(0)) // bucketsize
-	offset = (offset + ptrsize - 1) / ptrsize * ptrsize
-	gc = append(gc, _GC_PTR, offset, uintptr(bucket.gc)) // buckets
-	offset += ptrsize
-	gc = append(gc, _GC_PTR, offset, uintptr(bucket.gc)) // oldbuckets
-	offset += ptrsize
-	offset += ptrsize // nevacuate
-	gc = append(gc, _GC_END)
-	gc[0] = offset
-
-	h := new(rtype)
-	h.size = offset
-	h.gc = unsafe.Pointer(&gc[0])
-	s := "hmap(" + *bucket.string + ")"
-	h.string = &s
-	return h
-}
-
-// garbage collection bytecode program for slice of non-zero-length values.
-// See ../../cmd/gc/reflect.c:/^dgcsym1 and :/^dgcsym.
-type sliceGC struct {
-	width  uintptr        // sizeof(slice)
-	op     uintptr        // _GC_SLICE
-	off    uintptr        // 0
-	elemgc unsafe.Pointer // element gc program
-	end    uintptr        // _GC_END
-}
-
-// garbage collection bytecode program for slice of zero-length values.
-// See ../../cmd/gc/reflect.c:/^dgcsym1 and :/^dgcsym.
-type sliceEmptyGC struct {
-	width uintptr // sizeof(slice)
-	op    uintptr // _GC_APTR
-	off   uintptr // 0
-	end   uintptr // _GC_END
-}
-
-var sliceEmptyGCProg = sliceEmptyGC{
-	width: unsafe.Sizeof([]byte(nil)),
-	op:    _GC_APTR,
-	off:   0,
-	end:   _GC_END,
-}
-
-// SliceOf returns the slice type with element type t.
-// For example, if t represents int, SliceOf(t) represents []int.
-func SliceOf(t Type) Type {
-	typ := t.(*rtype)
-
-	// Look in cache.
-	ckey := cacheKey{Slice, typ, nil, 0}
-	if slice := cacheGet(ckey); slice != nil {
-		return slice
-	}
-
-	// Look in known types.
-	s := "[]" + *typ.string
-	for _, tt := range typesByString(s) {
-		slice := (*sliceType)(unsafe.Pointer(tt))
-		if slice.elem == typ {
-			return cachePut(ckey, tt)
-		}
-	}
-
-	// Make a slice type.
-	var islice interface{} = ([]unsafe.Pointer)(nil)
-	prototype := *(**sliceType)(unsafe.Pointer(&islice))
-	slice := new(sliceType)
-	*slice = *prototype
-	slice.string = &s
-	slice.hash = fnv1(typ.hash, '[')
-	slice.elem = typ
-	slice.uncommonType = nil
-	slice.ptrToThis = nil
-	slice.zero = unsafe.Pointer(&make([]byte, slice.size)[0])
-
-	if typ.size == 0 {
-		slice.gc = unsafe.Pointer(&sliceEmptyGCProg)
-	} else {
-		slice.gc = unsafe.Pointer(&sliceGC{
-			width:  slice.size,
-			op:     _GC_SLICE,
-			off:    0,
-			elemgc: typ.gc,
-			end:    _GC_END,
-		})
-	}
-
-	// INCORRECT. Uncomment to check that TestSliceOfOfGC fails when slice.gc is wrong.
-	//slice.gc = unsafe.Pointer(&badGC{width: slice.size, end: _GC_END})
-
-	return cachePut(ckey, &slice.rtype)
-}
-
-// ArrayOf returns the array type with the given count and element type.
-// For example, if t represents int, ArrayOf(5, t) represents [5]int.
-//
-// If the resulting type would be larger than the available address space,
-// ArrayOf panics.
-//
-// TODO(rsc): Unexported for now. Export once the alg field is set correctly
-// for the type. This may require significant work.
-func arrayOf(count int, elem Type) Type {
-	typ := elem.(*rtype)
-	slice := SliceOf(elem)
-
-	// Look in cache.
-	ckey := cacheKey{Array, typ, nil, uintptr(count)}
-	if slice := cacheGet(ckey); slice != nil {
-		return slice
-	}
-
-	// Look in known types.
-	s := "[" + strconv.Itoa(count) + "]" + *typ.string
-	for _, tt := range typesByString(s) {
-		slice := (*sliceType)(unsafe.Pointer(tt))
-		if slice.elem == typ {
-			return cachePut(ckey, tt)
-		}
-	}
-
-	// Make an array type.
-	var iarray interface{} = [1]unsafe.Pointer{}
-	prototype := *(**arrayType)(unsafe.Pointer(&iarray))
-	array := new(arrayType)
-	*array = *prototype
-	array.string = &s
-	array.hash = fnv1(typ.hash, '[')
-	for n := uint32(count); n > 0; n >>= 8 {
-		array.hash = fnv1(array.hash, byte(n))
-	}
-	array.hash = fnv1(array.hash, ']')
-	array.elem = typ
-	max := ^uintptr(0) / typ.size
-	if uintptr(count) > max {
-		panic("reflect.ArrayOf: array size would exceed virtual address space")
-	}
-	array.size = typ.size * uintptr(count)
-	array.align = typ.align
-	array.fieldAlign = typ.fieldAlign
-	// TODO: array.alg
-	// TODO: array.gc
-	array.uncommonType = nil
-	array.ptrToThis = nil
-	array.zero = unsafe.Pointer(&make([]byte, array.size)[0])
-	array.len = uintptr(count)
-	array.slice = slice.(*rtype)
-
-	return cachePut(ckey, &array.rtype)
-}
-
-// toType converts from a *rtype to a Type that can be returned
-// to the client of package reflect. In gc, the only concern is that
-// a nil *rtype must be replaced by a nil Type, but in gccgo this
-// function takes care of ensuring that multiple *rtype for the same
-// type are coalesced into a single Type.
-func toType(t *rtype) Type {
-	if t == nil {
-		return nil
-	}
-	return t
-}
-
-type layoutKey struct {
-	t    *rtype // function signature
-	rcvr *rtype // receiver type, or nil if none
-}
-
-type layoutType struct {
-	t         *rtype
-	argSize   uintptr // size of arguments
-	retOffset uintptr // offset of return values.
-}
-
-var layoutCache struct {
-	sync.RWMutex
-	m map[layoutKey]layoutType
-}
-
-// funcLayout computes a struct type representing the layout of the
-// function arguments and return values for the function type t.
-// If rcvr != nil, rcvr specifies the type of the receiver.
-// The returned type exists only for GC, so we only fill out GC relevant info.
-// Currently, that's just size and the GC program.  We also fill in
-// the name for possible debugging use.
-func funcLayout(t *rtype, rcvr *rtype) (frametype *rtype, argSize, retOffset uintptr) {
-	if t.Kind() != Func {
-		panic("reflect: funcLayout of non-func type")
-	}
-	if rcvr != nil && rcvr.Kind() == Interface {
-		panic("reflect: funcLayout with interface receiver " + rcvr.String())
-	}
-	k := layoutKey{t, rcvr}
-	layoutCache.RLock()
-	if x := layoutCache.m[k]; x.t != nil {
-		layoutCache.RUnlock()
-		return x.t, x.argSize, x.retOffset
-	}
-	layoutCache.RUnlock()
-	layoutCache.Lock()
-	if x := layoutCache.m[k]; x.t != nil {
-		layoutCache.Unlock()
-		return x.t, x.argSize, x.retOffset
-	}
-
-	tt := (*funcType)(unsafe.Pointer(t))
-
-	// compute gc program for arguments
-	gc := make([]uintptr, 1) // first entry is size, filled in at the end
-	offset := uintptr(0)
-	if rcvr != nil {
-		// Reflect uses the "interface" calling convention for
-		// methods, where receivers take one word of argument
-		// space no matter how big they actually are.
-		if rcvr.size > ptrSize {
-			// we pass a pointer to the receiver.
-			gc = append(gc, _GC_PTR, offset, uintptr(rcvr.gc))
-		} else if rcvr.pointers() {
-			// rcvr is a one-word pointer object.  Its gc program
-			// is just what we need here.
-			gc = appendGCProgram(gc, rcvr)
-		}
-		offset += ptrSize
-	}
-	for _, arg := range tt.in {
-		offset = align(offset, uintptr(arg.align))
-		if arg.pointers() {
-			gc = append(gc, _GC_REGION, offset, arg.size, uintptr(arg.gc))
-		}
-		offset += arg.size
-	}
-	argSize = offset
-	if runtime.GOARCH == "amd64p32" {
-		offset = align(offset, 8)
-	}
-	offset = align(offset, ptrSize)
-	retOffset = offset
-	for _, res := range tt.out {
-		offset = align(offset, uintptr(res.align))
-		if res.pointers() {
-			gc = append(gc, _GC_REGION, offset, res.size, uintptr(res.gc))
-		}
-		offset += res.size
-	}
-	gc = append(gc, _GC_END)
-	gc[0] = offset
-
-	// build dummy rtype holding gc program
-	x := new(rtype)
-	x.size = offset
-	x.gc = unsafe.Pointer(&gc[0])
-	var s string
-	if rcvr != nil {
-		s = "methodargs(" + *rcvr.string + ")(" + *t.string + ")"
-	} else {
-		s = "funcargs(" + *t.string + ")"
-	}
-	x.string = &s
-
-	// cache result for future callers
-	if layoutCache.m == nil {
-		layoutCache.m = make(map[layoutKey]layoutType)
-	}
-	layoutCache.m[k] = layoutType{
-		t:         x,
-		argSize:   argSize,
-		retOffset: retOffset,
-	}
-	layoutCache.Unlock()
-	return x, argSize, retOffset
-}
diff --git a/src/pkg/reflect/value.go b/src/pkg/reflect/value.go
deleted file mode 100644
index 576cbc3..0000000
--- a/src/pkg/reflect/value.go
+++ /dev/null
@@ -1,2684 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package reflect
-
-import (
-	"math"
-	"runtime"
-	"strconv"
-	"unsafe"
-)
-
-const bigEndian = false // can be smarter if we find a big-endian machine
-const ptrSize = unsafe.Sizeof((*byte)(nil))
-const cannotSet = "cannot set value obtained from unexported struct field"
-
-// TODO: This will have to go away when
-// the new gc goes in.
-func memmove(adst, asrc unsafe.Pointer, n uintptr) {
-	dst := uintptr(adst)
-	src := uintptr(asrc)
-	switch {
-	case src < dst && src+n > dst:
-		// byte copy backward
-		// careful: i is unsigned
-		for i := n; i > 0; {
-			i--
-			*(*byte)(unsafe.Pointer(dst + i)) = *(*byte)(unsafe.Pointer(src + i))
-		}
-	case (n|src|dst)&(ptrSize-1) != 0:
-		// byte copy forward
-		for i := uintptr(0); i < n; i++ {
-			*(*byte)(unsafe.Pointer(dst + i)) = *(*byte)(unsafe.Pointer(src + i))
-		}
-	default:
-		// word copy forward
-		for i := uintptr(0); i < n; i += ptrSize {
-			*(*uintptr)(unsafe.Pointer(dst + i)) = *(*uintptr)(unsafe.Pointer(src + i))
-		}
-	}
-}
-
-// Value is the reflection interface to a Go value.
-//
-// Not all methods apply to all kinds of values.  Restrictions,
-// if any, are noted in the documentation for each method.
-// Use the Kind method to find out the kind of value before
-// calling kind-specific methods.  Calling a method
-// inappropriate to the kind of type causes a run time panic.
-//
-// The zero Value represents no value.
-// Its IsValid method returns false, its Kind method returns Invalid,
-// its String method returns "<invalid Value>", and all other methods panic.
-// Most functions and methods never return an invalid value.
-// If one does, its documentation states the conditions explicitly.
-//
-// A Value can be used concurrently by multiple goroutines provided that
-// the underlying Go value can be used concurrently for the equivalent
-// direct operations.
-type Value struct {
-	// typ holds the type of the value represented by a Value.
-	typ *rtype
-
-	// Pointer-valued data or, if flagIndir is set, pointer to data.
-	// Valid when either flagIndir is set or typ.pointers() is true.
-	ptr unsafe.Pointer
-
-	// Non-pointer-valued data.  When the data is smaller
-	// than a word, it begins at the first byte (in the memory
-	// address sense) of this field.
-	// Valid when flagIndir is not set and typ.pointers() is false.
-	scalar uintptr
-
-	// flag holds metadata about the value.
-	// The lowest bits are flag bits:
-	//	- flagRO: obtained via unexported field, so read-only
-	//	- flagIndir: val holds a pointer to the data
-	//	- flagAddr: v.CanAddr is true (implies flagIndir)
-	//	- flagMethod: v is a method value.
-	// The next five bits give the Kind of the value.
-	// This repeats typ.Kind() except for method values.
-	// The remaining 23+ bits give a method number for method values.
-	// If flag.kind() != Func, code can assume that flagMethod is unset.
-	// If typ.size > ptrSize, code can assume that flagIndir is set.
-	flag
-
-	// A method value represents a curried method invocation
-	// like r.Read for some receiver r.  The typ+val+flag bits describe
-	// the receiver r, but the flag's Kind bits say Func (methods are
-	// functions), and the top bits of the flag give the method number
-	// in r's type's method table.
-}
-
-type flag uintptr
-
-const (
-	flagRO flag = 1 << iota
-	flagIndir
-	flagAddr
-	flagMethod
-	flagKindShift        = iota
-	flagKindWidth        = 5 // there are 27 kinds
-	flagKindMask    flag = 1<<flagKindWidth - 1
-	flagMethodShift      = flagKindShift + flagKindWidth
-)
-
-func (f flag) kind() Kind {
-	return Kind((f >> flagKindShift) & flagKindMask)
-}
-
-// pointer returns the underlying pointer represented by v.
-// v.Kind() must be Ptr, Map, Chan, Func, or UnsafePointer
-func (v Value) pointer() unsafe.Pointer {
-	if v.typ.size != ptrSize || !v.typ.pointers() {
-		panic("can't call pointer on a non-pointer Value")
-	}
-	if v.flag&flagIndir != 0 {
-		return *(*unsafe.Pointer)(v.ptr)
-	}
-	return v.ptr
-}
-
-// packEface converts v to the empty interface.
-func packEface(v Value) interface{} {
-	t := v.typ
-	var i interface{}
-	e := (*emptyInterface)(unsafe.Pointer(&i))
-	// First, fill in the data portion of the interface.
-	switch {
-	case t.size > ptrSize:
-		// Value is indirect, and so is the interface we're making.
-		ptr := v.ptr
-		if v.flag&flagAddr != 0 {
-			// TODO: pass safe boolean from valueInterface so
-			// we don't need to copy if safe==true?
-			c := unsafe_New(t)
-			memmove(c, ptr, t.size)
-			ptr = c
-		}
-		e.word = iword(ptr)
-	case v.flag&flagIndir != 0:
-		// Value is indirect, but interface is direct.  We need
-		// to load the data at v.ptr into the interface data word.
-		if t.pointers() {
-			e.word = iword(*(*unsafe.Pointer)(v.ptr))
-		} else {
-			e.word = iword(loadScalar(v.ptr, t.size))
-		}
-	default:
-		// Value is direct, and so is the interface.
-		if t.pointers() {
-			e.word = iword(v.ptr)
-		} else {
-			e.word = iword(v.scalar)
-		}
-	}
-	// Now, fill in the type portion.  We're very careful here not
-	// to have any operation between the e.word and e.typ assignments
-	// that would let the garbage collector observe the partially-built
-	// interface value.
-	e.typ = t
-	return i
-}
-
-// unpackEface converts the empty interface i to a Value.
-func unpackEface(i interface{}) Value {
-	e := (*emptyInterface)(unsafe.Pointer(&i))
-	// NOTE: don't read e.word until we know whether it is really a pointer or not.
-	t := e.typ
-	if t == nil {
-		return Value{}
-	}
-	f := flag(t.Kind()) << flagKindShift
-	if t.size > ptrSize {
-		return Value{t, unsafe.Pointer(e.word), 0, f | flagIndir}
-	}
-	if t.pointers() {
-		return Value{t, unsafe.Pointer(e.word), 0, f}
-	}
-	return Value{t, nil, uintptr(e.word), f}
-}
-
-// A ValueError occurs when a Value method is invoked on
-// a Value that does not support it.  Such cases are documented
-// in the description of each method.
-type ValueError struct {
-	Method string
-	Kind   Kind
-}
-
-func (e *ValueError) Error() string {
-	if e.Kind == 0 {
-		return "reflect: call of " + e.Method + " on zero Value"
-	}
-	return "reflect: call of " + e.Method + " on " + e.Kind.String() + " Value"
-}
-
-// methodName returns the name of the calling method,
-// assumed to be two stack frames above.
-func methodName() string {
-	pc, _, _, _ := runtime.Caller(2)
-	f := runtime.FuncForPC(pc)
-	if f == nil {
-		return "unknown method"
-	}
-	return f.Name()
-}
-
-// An iword is the word that would be stored in an
-// interface to represent a given value v.  Specifically, if v is
-// bigger than a pointer, its word is a pointer to v's data.
-// Otherwise, its word holds the data stored
-// in its leading bytes (so is not a pointer).
-// This type is very dangerous for the garbage collector because
-// it must be treated conservatively.  We try to never expose it
-// to the GC here so that GC remains precise.
-type iword unsafe.Pointer
-
-// loadScalar loads n bytes at p from memory into a uintptr
-// that forms the second word of an interface.  The data
-// must be non-pointer in nature.
-func loadScalar(p unsafe.Pointer, n uintptr) uintptr {
-	// Run the copy ourselves instead of calling memmove
-	// to avoid moving w to the heap.
-	var w uintptr
-	switch n {
-	default:
-		panic("reflect: internal error: loadScalar of " + strconv.Itoa(int(n)) + "-byte value")
-	case 0:
-	case 1:
-		*(*uint8)(unsafe.Pointer(&w)) = *(*uint8)(p)
-	case 2:
-		*(*uint16)(unsafe.Pointer(&w)) = *(*uint16)(p)
-	case 3:
-		*(*[3]byte)(unsafe.Pointer(&w)) = *(*[3]byte)(p)
-	case 4:
-		*(*uint32)(unsafe.Pointer(&w)) = *(*uint32)(p)
-	case 5:
-		*(*[5]byte)(unsafe.Pointer(&w)) = *(*[5]byte)(p)
-	case 6:
-		*(*[6]byte)(unsafe.Pointer(&w)) = *(*[6]byte)(p)
-	case 7:
-		*(*[7]byte)(unsafe.Pointer(&w)) = *(*[7]byte)(p)
-	case 8:
-		*(*uint64)(unsafe.Pointer(&w)) = *(*uint64)(p)
-	}
-	return w
-}
-
-// storeScalar stores n bytes from w into p.
-func storeScalar(p unsafe.Pointer, w uintptr, n uintptr) {
-	// Run the copy ourselves instead of calling memmove
-	// to avoid moving w to the heap.
-	switch n {
-	default:
-		panic("reflect: internal error: storeScalar of " + strconv.Itoa(int(n)) + "-byte value")
-	case 0:
-	case 1:
-		*(*uint8)(p) = *(*uint8)(unsafe.Pointer(&w))
-	case 2:
-		*(*uint16)(p) = *(*uint16)(unsafe.Pointer(&w))
-	case 3:
-		*(*[3]byte)(p) = *(*[3]byte)(unsafe.Pointer(&w))
-	case 4:
-		*(*uint32)(p) = *(*uint32)(unsafe.Pointer(&w))
-	case 5:
-		*(*[5]byte)(p) = *(*[5]byte)(unsafe.Pointer(&w))
-	case 6:
-		*(*[6]byte)(p) = *(*[6]byte)(unsafe.Pointer(&w))
-	case 7:
-		*(*[7]byte)(p) = *(*[7]byte)(unsafe.Pointer(&w))
-	case 8:
-		*(*uint64)(p) = *(*uint64)(unsafe.Pointer(&w))
-	}
-}
-
-// emptyInterface is the header for an interface{} value.
-type emptyInterface struct {
-	typ  *rtype
-	word iword
-}
-
-// nonEmptyInterface is the header for a interface value with methods.
-type nonEmptyInterface struct {
-	// see ../runtime/iface.c:/Itab
-	itab *struct {
-		ityp   *rtype // static interface type
-		typ    *rtype // dynamic concrete type
-		link   unsafe.Pointer
-		bad    int32
-		unused int32
-		fun    [100000]unsafe.Pointer // method table
-	}
-	word iword
-}
-
-// mustBe panics if f's kind is not expected.
-// Making this a method on flag instead of on Value
-// (and embedding flag in Value) means that we can write
-// the very clear v.mustBe(Bool) and have it compile into
-// v.flag.mustBe(Bool), which will only bother to copy the
-// single important word for the receiver.
-func (f flag) mustBe(expected Kind) {
-	k := f.kind()
-	if k != expected {
-		panic(&ValueError{methodName(), k})
-	}
-}
-
-// mustBeExported panics if f records that the value was obtained using
-// an unexported field.
-func (f flag) mustBeExported() {
-	if f == 0 {
-		panic(&ValueError{methodName(), 0})
-	}
-	if f&flagRO != 0 {
-		panic("reflect: " + methodName() + " using value obtained using unexported field")
-	}
-}
-
-// mustBeAssignable panics if f records that the value is not assignable,
-// which is to say that either it was obtained using an unexported field
-// or it is not addressable.
-func (f flag) mustBeAssignable() {
-	if f == 0 {
-		panic(&ValueError{methodName(), Invalid})
-	}
-	// Assignable if addressable and not read-only.
-	if f&flagRO != 0 {
-		panic("reflect: " + methodName() + " using value obtained using unexported field")
-	}
-	if f&flagAddr == 0 {
-		panic("reflect: " + methodName() + " using unaddressable value")
-	}
-}
-
-// Addr returns a pointer value representing the address of v.
-// It panics if CanAddr() returns false.
-// Addr is typically used to obtain a pointer to a struct field
-// or slice element in order to call a method that requires a
-// pointer receiver.
-func (v Value) Addr() Value {
-	if v.flag&flagAddr == 0 {
-		panic("reflect.Value.Addr of unaddressable value")
-	}
-	return Value{v.typ.ptrTo(), v.ptr, 0, (v.flag & flagRO) | flag(Ptr)<<flagKindShift}
-}
-
-// Bool returns v's underlying value.
-// It panics if v's kind is not Bool.
-func (v Value) Bool() bool {
-	v.mustBe(Bool)
-	if v.flag&flagIndir != 0 {
-		return *(*bool)(v.ptr)
-	}
-	return *(*bool)(unsafe.Pointer(&v.scalar))
-}
-
-// Bytes returns v's underlying value.
-// It panics if v's underlying value is not a slice of bytes.
-func (v Value) Bytes() []byte {
-	v.mustBe(Slice)
-	if v.typ.Elem().Kind() != Uint8 {
-		panic("reflect.Value.Bytes of non-byte slice")
-	}
-	// Slice is always bigger than a word; assume flagIndir.
-	return *(*[]byte)(v.ptr)
-}
-
-// runes returns v's underlying value.
-// It panics if v's underlying value is not a slice of runes (int32s).
-func (v Value) runes() []rune {
-	v.mustBe(Slice)
-	if v.typ.Elem().Kind() != Int32 {
-		panic("reflect.Value.Bytes of non-rune slice")
-	}
-	// Slice is always bigger than a word; assume flagIndir.
-	return *(*[]rune)(v.ptr)
-}
-
-// CanAddr returns true if the value's address can be obtained with Addr.
-// Such values are called addressable.  A value is addressable if it is
-// an element of a slice, an element of an addressable array,
-// a field of an addressable struct, or the result of dereferencing a pointer.
-// If CanAddr returns false, calling Addr will panic.
-func (v Value) CanAddr() bool {
-	return v.flag&flagAddr != 0
-}
-
-// CanSet returns true if the value of v can be changed.
-// A Value can be changed only if it is addressable and was not
-// obtained by the use of unexported struct fields.
-// If CanSet returns false, calling Set or any type-specific
-// setter (e.g., SetBool, SetInt64) will panic.
-func (v Value) CanSet() bool {
-	return v.flag&(flagAddr|flagRO) == flagAddr
-}
-
-// Call calls the function v with the input arguments in.
-// For example, if len(in) == 3, v.Call(in) represents the Go call v(in[0], in[1], in[2]).
-// Call panics if v's Kind is not Func.
-// It returns the output results as Values.
-// As in Go, each input argument must be assignable to the
-// type of the function's corresponding input parameter.
-// If v is a variadic function, Call creates the variadic slice parameter
-// itself, copying in the corresponding values.
-func (v Value) Call(in []Value) []Value {
-	v.mustBe(Func)
-	v.mustBeExported()
-	return v.call("Call", in)
-}
-
-// CallSlice calls the variadic function v with the input arguments in,
-// assigning the slice in[len(in)-1] to v's final variadic argument.
-// For example, if len(in) == 3, v.Call(in) represents the Go call v(in[0], in[1], in[2]...).
-// Call panics if v's Kind is not Func or if v is not variadic.
-// It returns the output results as Values.
-// As in Go, each input argument must be assignable to the
-// type of the function's corresponding input parameter.
-func (v Value) CallSlice(in []Value) []Value {
-	v.mustBe(Func)
-	v.mustBeExported()
-	return v.call("CallSlice", in)
-}
-
-var callGC bool // for testing; see TestCallMethodJump
-
-var makeFuncStubFn = makeFuncStub
-var makeFuncStubCode = **(**uintptr)(unsafe.Pointer(&makeFuncStubFn))
-var methodValueCallFn = methodValueCall
-var methodValueCallCode = **(**uintptr)(unsafe.Pointer(&methodValueCallFn))
-
-func (v Value) call(op string, in []Value) []Value {
-	// Get function pointer, type.
-	t := v.typ
-	var (
-		fn       unsafe.Pointer
-		rcvr     Value
-		rcvrtype *rtype
-	)
-	if v.flag&flagMethod != 0 {
-		rcvr = v
-		rcvrtype, t, fn = methodReceiver(op, v, int(v.flag)>>flagMethodShift)
-	} else if v.flag&flagIndir != 0 {
-		fn = *(*unsafe.Pointer)(v.ptr)
-	} else {
-		fn = v.ptr
-	}
-
-	if fn == nil {
-		panic("reflect.Value.Call: call of nil function")
-	}
-
-	isSlice := op == "CallSlice"
-	n := t.NumIn()
-	if isSlice {
-		if !t.IsVariadic() {
-			panic("reflect: CallSlice of non-variadic function")
-		}
-		if len(in) < n {
-			panic("reflect: CallSlice with too few input arguments")
-		}
-		if len(in) > n {
-			panic("reflect: CallSlice with too many input arguments")
-		}
-	} else {
-		if t.IsVariadic() {
-			n--
-		}
-		if len(in) < n {
-			panic("reflect: Call with too few input arguments")
-		}
-		if !t.IsVariadic() && len(in) > n {
-			panic("reflect: Call with too many input arguments")
-		}
-	}
-	for _, x := range in {
-		if x.Kind() == Invalid {
-			panic("reflect: " + op + " using zero Value argument")
-		}
-	}
-	for i := 0; i < n; i++ {
-		if xt, targ := in[i].Type(), t.In(i); !xt.AssignableTo(targ) {
-			panic("reflect: " + op + " using " + xt.String() + " as type " + targ.String())
-		}
-	}
-	if !isSlice && t.IsVariadic() {
-		// prepare slice for remaining values
-		m := len(in) - n
-		slice := MakeSlice(t.In(n), m, m)
-		elem := t.In(n).Elem()
-		for i := 0; i < m; i++ {
-			x := in[n+i]
-			if xt := x.Type(); !xt.AssignableTo(elem) {
-				panic("reflect: cannot use " + xt.String() + " as type " + elem.String() + " in " + op)
-			}
-			slice.Index(i).Set(x)
-		}
-		origIn := in
-		in = make([]Value, n+1)
-		copy(in[:n], origIn)
-		in[n] = slice
-	}
-
-	nin := len(in)
-	if nin != t.NumIn() {
-		panic("reflect.Value.Call: wrong argument count")
-	}
-	nout := t.NumOut()
-
-	// If target is makeFuncStub, short circuit the unpack onto stack /
-	// pack back into []Value for the args and return values.  Just do the
-	// call directly.
-	// We need to do this here because otherwise we have a situation where
-	// reflect.callXX calls makeFuncStub, neither of which knows the
-	// layout of the args.  That's bad for precise gc & stack copying.
-	x := (*makeFuncImpl)(fn)
-	if x.code == makeFuncStubCode {
-		return x.fn(in)
-	}
-
-	// If the target is methodValueCall, do its work here: add the receiver
-	// argument and call the real target directly.
-	// We need to do this here because otherwise we have a situation where
-	// reflect.callXX calls methodValueCall, neither of which knows the
-	// layout of the args.  That's bad for precise gc & stack copying.
-	y := (*methodValue)(fn)
-	if y.fn == methodValueCallCode {
-		rcvr = y.rcvr
-		rcvrtype, t, fn = methodReceiver("call", rcvr, y.method)
-	}
-
-	// Compute frame type, allocate a chunk of memory for frame
-	frametype, _, retOffset := funcLayout(t, rcvrtype)
-	args := unsafe_New(frametype)
-	off := uintptr(0)
-
-	// Copy inputs into args.
-	if rcvrtype != nil {
-		storeRcvr(rcvr, args)
-		off = ptrSize
-	}
-	for i, v := range in {
-		v.mustBeExported()
-		targ := t.In(i).(*rtype)
-		a := uintptr(targ.align)
-		off = (off + a - 1) &^ (a - 1)
-		n := targ.size
-		addr := unsafe.Pointer(uintptr(args) + off)
-		v = v.assignTo("reflect.Value.Call", targ, (*interface{})(addr))
-		if v.flag&flagIndir != 0 {
-			memmove(addr, v.ptr, n)
-		} else if targ.pointers() {
-			*(*unsafe.Pointer)(addr) = v.ptr
-		} else {
-			storeScalar(addr, v.scalar, n)
-		}
-		off += n
-	}
-
-	// Call.
-	call(fn, args, uint32(frametype.size), uint32(retOffset))
-
-	// For testing; see TestCallMethodJump.
-	if callGC {
-		runtime.GC()
-	}
-
-	// Copy return values out of args.
-	ret := make([]Value, nout)
-	off = retOffset
-	for i := 0; i < nout; i++ {
-		tv := t.Out(i)
-		a := uintptr(tv.Align())
-		off = (off + a - 1) &^ (a - 1)
-		fl := flagIndir | flag(tv.Kind())<<flagKindShift
-		ret[i] = Value{tv.common(), unsafe.Pointer(uintptr(args) + off), 0, fl}
-		off += tv.Size()
-	}
-
-	return ret
-}
-
-// callReflect is the call implementation used by a function
-// returned by MakeFunc. In many ways it is the opposite of the
-// method Value.call above. The method above converts a call using Values
-// into a call of a function with a concrete argument frame, while
-// callReflect converts a call of a function with a concrete argument
-// frame into a call using Values.
-// It is in this file so that it can be next to the call method above.
-// The remainder of the MakeFunc implementation is in makefunc.go.
-//
-// NOTE: This function must be marked as a "wrapper" in the generated code,
-// so that the linker can make it work correctly for panic and recover.
-// The gc compilers know to do that for the name "reflect.callReflect".
-func callReflect(ctxt *makeFuncImpl, frame unsafe.Pointer) {
-	ftyp := ctxt.typ
-	f := ctxt.fn
-
-	// Copy argument frame into Values.
-	ptr := frame
-	off := uintptr(0)
-	in := make([]Value, 0, len(ftyp.in))
-	for _, arg := range ftyp.in {
-		typ := arg
-		off += -off & uintptr(typ.align-1)
-		addr := unsafe.Pointer(uintptr(ptr) + off)
-		v := Value{typ, nil, 0, flag(typ.Kind()) << flagKindShift}
-		if typ.size > ptrSize {
-			// value does not fit in word.
-			// Must make a copy, because f might keep a reference to it,
-			// and we cannot let f keep a reference to the stack frame
-			// after this function returns, not even a read-only reference.
-			v.ptr = unsafe_New(typ)
-			memmove(v.ptr, addr, typ.size)
-			v.flag |= flagIndir
-		} else if typ.pointers() {
-			v.ptr = *(*unsafe.Pointer)(addr)
-		} else {
-			v.scalar = loadScalar(addr, typ.size)
-		}
-		in = append(in, v)
-		off += typ.size
-	}
-
-	// Call underlying function.
-	out := f(in)
-	if len(out) != len(ftyp.out) {
-		panic("reflect: wrong return count from function created by MakeFunc")
-	}
-
-	// Copy results back into argument frame.
-	if len(ftyp.out) > 0 {
-		off += -off & (ptrSize - 1)
-		if runtime.GOARCH == "amd64p32" {
-			off = align(off, 8)
-		}
-		for i, arg := range ftyp.out {
-			typ := arg
-			v := out[i]
-			if v.typ != typ {
-				panic("reflect: function created by MakeFunc using " + funcName(f) +
-					" returned wrong type: have " +
-					out[i].typ.String() + " for " + typ.String())
-			}
-			if v.flag&flagRO != 0 {
-				panic("reflect: function created by MakeFunc using " + funcName(f) +
-					" returned value obtained from unexported field")
-			}
-			off += -off & uintptr(typ.align-1)
-			addr := unsafe.Pointer(uintptr(ptr) + off)
-			if v.flag&flagIndir != 0 {
-				memmove(addr, v.ptr, typ.size)
-			} else if typ.pointers() {
-				*(*unsafe.Pointer)(addr) = v.ptr
-			} else {
-				storeScalar(addr, v.scalar, typ.size)
-			}
-			off += typ.size
-		}
-	}
-}
-
-// methodReceiver returns information about the receiver
-// described by v. The Value v may or may not have the
-// flagMethod bit set, so the kind cached in v.flag should
-// not be used.
-// The return value rcvrtype gives the method's actual receiver type.
-// The return value t gives the method type signature (without the receiver).
-// The return value fn is a pointer to the method code.
-func methodReceiver(op string, v Value, methodIndex int) (rcvrtype, t *rtype, fn unsafe.Pointer) {
-	i := methodIndex
-	if v.typ.Kind() == Interface {
-		tt := (*interfaceType)(unsafe.Pointer(v.typ))
-		if i < 0 || i >= len(tt.methods) {
-			panic("reflect: internal error: invalid method index")
-		}
-		m := &tt.methods[i]
-		if m.pkgPath != nil {
-			panic("reflect: " + op + " of unexported method")
-		}
-		iface := (*nonEmptyInterface)(v.ptr)
-		if iface.itab == nil {
-			panic("reflect: " + op + " of method on nil interface value")
-		}
-		rcvrtype = iface.itab.typ
-		fn = unsafe.Pointer(&iface.itab.fun[i])
-		t = m.typ
-	} else {
-		rcvrtype = v.typ
-		ut := v.typ.uncommon()
-		if ut == nil || i < 0 || i >= len(ut.methods) {
-			panic("reflect: internal error: invalid method index")
-		}
-		m := &ut.methods[i]
-		if m.pkgPath != nil {
-			panic("reflect: " + op + " of unexported method")
-		}
-		fn = unsafe.Pointer(&m.ifn)
-		t = m.mtyp
-	}
-	return
-}
-
-// v is a method receiver.  Store at p the word which is used to
-// encode that receiver at the start of the argument list.
-// Reflect uses the "interface" calling convention for
-// methods, which always uses one word to record the receiver.
-func storeRcvr(v Value, p unsafe.Pointer) {
-	t := v.typ
-	if t.Kind() == Interface {
-		// the interface data word becomes the receiver word
-		iface := (*nonEmptyInterface)(v.ptr)
-		*(*unsafe.Pointer)(p) = unsafe.Pointer(iface.word)
-	} else if v.flag&flagIndir != 0 {
-		if t.size > ptrSize {
-			*(*unsafe.Pointer)(p) = v.ptr
-		} else if t.pointers() {
-			*(*unsafe.Pointer)(p) = *(*unsafe.Pointer)(v.ptr)
-		} else {
-			*(*uintptr)(p) = loadScalar(v.ptr, t.size)
-		}
-	} else if t.pointers() {
-		*(*unsafe.Pointer)(p) = v.ptr
-	} else {
-		*(*uintptr)(p) = v.scalar
-	}
-}
-
-// align returns the result of rounding x up to a multiple of n.
-// n must be a power of two.
-func align(x, n uintptr) uintptr {
-	return (x + n - 1) &^ (n - 1)
-}
-
-// callMethod is the call implementation used by a function returned
-// by makeMethodValue (used by v.Method(i).Interface()).
-// It is a streamlined version of the usual reflect call: the caller has
-// already laid out the argument frame for us, so we don't have
-// to deal with individual Values for each argument.
-// It is in this file so that it can be next to the two similar functions above.
-// The remainder of the makeMethodValue implementation is in makefunc.go.
-//
-// NOTE: This function must be marked as a "wrapper" in the generated code,
-// so that the linker can make it work correctly for panic and recover.
-// The gc compilers know to do that for the name "reflect.callMethod".
-func callMethod(ctxt *methodValue, frame unsafe.Pointer) {
-	rcvr := ctxt.rcvr
-	rcvrtype, t, fn := methodReceiver("call", rcvr, ctxt.method)
-	frametype, argSize, retOffset := funcLayout(t, rcvrtype)
-
-	// Make a new frame that is one word bigger so we can store the receiver.
-	args := unsafe_New(frametype)
-
-	// Copy in receiver and rest of args.
-	storeRcvr(rcvr, args)
-	memmove(unsafe.Pointer(uintptr(args)+ptrSize), frame, argSize-ptrSize)
-
-	// Call.
-	call(fn, args, uint32(frametype.size), uint32(retOffset))
-
-	// Copy return values. On amd64p32, the beginning of return values
-	// is 64-bit aligned, so the caller's frame layout (which doesn't have
-	// a receiver) is different from the layout of the fn call, which has
-	// a receiver.
-	// Ignore any changes to args and just copy return values.
-	callerRetOffset := retOffset - ptrSize
-	if runtime.GOARCH == "amd64p32" {
-		callerRetOffset = align(argSize-ptrSize, 8)
-	}
-	memmove(unsafe.Pointer(uintptr(frame)+callerRetOffset),
-		unsafe.Pointer(uintptr(args)+retOffset), frametype.size-retOffset)
-}
-
-// funcName returns the name of f, for use in error messages.
-func funcName(f func([]Value) []Value) string {
-	pc := *(*uintptr)(unsafe.Pointer(&f))
-	rf := runtime.FuncForPC(pc)
-	if rf != nil {
-		return rf.Name()
-	}
-	return "closure"
-}
-
-// Cap returns v's capacity.
-// It panics if v's Kind is not Array, Chan, or Slice.
-func (v Value) Cap() int {
-	k := v.kind()
-	switch k {
-	case Array:
-		return v.typ.Len()
-	case Chan:
-		return int(chancap(v.pointer()))
-	case Slice:
-		// Slice is always bigger than a word; assume flagIndir.
-		return (*sliceHeader)(v.ptr).Cap
-	}
-	panic(&ValueError{"reflect.Value.Cap", k})
-}
-
-// Close closes the channel v.
-// It panics if v's Kind is not Chan.
-func (v Value) Close() {
-	v.mustBe(Chan)
-	v.mustBeExported()
-	chanclose(v.pointer())
-}
-
-// Complex returns v's underlying value, as a complex128.
-// It panics if v's Kind is not Complex64 or Complex128
-func (v Value) Complex() complex128 {
-	k := v.kind()
-	switch k {
-	case Complex64:
-		if v.flag&flagIndir != 0 {
-			return complex128(*(*complex64)(v.ptr))
-		}
-		return complex128(*(*complex64)(unsafe.Pointer(&v.scalar)))
-	case Complex128:
-		// complex128 is always bigger than a word; assume flagIndir.
-		return *(*complex128)(v.ptr)
-	}
-	panic(&ValueError{"reflect.Value.Complex", k})
-}
-
-// Elem returns the value that the interface v contains
-// or that the pointer v points to.
-// It panics if v's Kind is not Interface or Ptr.
-// It returns the zero Value if v is nil.
-func (v Value) Elem() Value {
-	k := v.kind()
-	switch k {
-	case Interface:
-		var eface interface{}
-		if v.typ.NumMethod() == 0 {
-			eface = *(*interface{})(v.ptr)
-		} else {
-			eface = (interface{})(*(*interface {
-				M()
-			})(v.ptr))
-		}
-		x := unpackEface(eface)
-		x.flag |= v.flag & flagRO
-		return x
-	case Ptr:
-		ptr := v.ptr
-		if v.flag&flagIndir != 0 {
-			ptr = *(*unsafe.Pointer)(ptr)
-		}
-		// The returned value's address is v's value.
-		if ptr == nil {
-			return Value{}
-		}
-		tt := (*ptrType)(unsafe.Pointer(v.typ))
-		typ := tt.elem
-		fl := v.flag&flagRO | flagIndir | flagAddr
-		fl |= flag(typ.Kind() << flagKindShift)
-		return Value{typ, ptr, 0, fl}
-	}
-	panic(&ValueError{"reflect.Value.Elem", k})
-}
-
-// Field returns the i'th field of the struct v.
-// It panics if v's Kind is not Struct or i is out of range.
-func (v Value) Field(i int) Value {
-	v.mustBe(Struct)
-	tt := (*structType)(unsafe.Pointer(v.typ))
-	if i < 0 || i >= len(tt.fields) {
-		panic("reflect: Field index out of range")
-	}
-	field := &tt.fields[i]
-	typ := field.typ
-
-	// Inherit permission bits from v.
-	fl := v.flag & (flagRO | flagIndir | flagAddr)
-	// Using an unexported field forces flagRO.
-	if field.pkgPath != nil {
-		fl |= flagRO
-	}
-	fl |= flag(typ.Kind()) << flagKindShift
-
-	var ptr unsafe.Pointer
-	var scalar uintptr
-	switch {
-	case fl&flagIndir != 0:
-		// Indirect.  Just bump pointer.
-		ptr = unsafe.Pointer(uintptr(v.ptr) + field.offset)
-	case typ.pointers():
-		if field.offset != 0 {
-			panic("field access of ptr value isn't at offset 0")
-		}
-		ptr = v.ptr
-	case bigEndian:
-		// Must be scalar.  Discard leading bytes.
-		scalar = v.scalar << (field.offset * 8)
-	default:
-		// Must be scalar.  Discard leading bytes.
-		scalar = v.scalar >> (field.offset * 8)
-	}
-
-	return Value{typ, ptr, scalar, fl}
-}
-
-// FieldByIndex returns the nested field corresponding to index.
-// It panics if v's Kind is not struct.
-func (v Value) FieldByIndex(index []int) Value {
-	v.mustBe(Struct)
-	for i, x := range index {
-		if i > 0 {
-			if v.Kind() == Ptr && v.typ.Elem().Kind() == Struct {
-				if v.IsNil() {
-					panic("reflect: indirection through nil pointer to embedded struct")
-				}
-				v = v.Elem()
-			}
-		}
-		v = v.Field(x)
-	}
-	return v
-}
-
-// FieldByName returns the struct field with the given name.
-// It returns the zero Value if no field was found.
-// It panics if v's Kind is not struct.
-func (v Value) FieldByName(name string) Value {
-	v.mustBe(Struct)
-	if f, ok := v.typ.FieldByName(name); ok {
-		return v.FieldByIndex(f.Index)
-	}
-	return Value{}
-}
-
-// FieldByNameFunc returns the struct field with a name
-// that satisfies the match function.
-// It panics if v's Kind is not struct.
-// It returns the zero Value if no field was found.
-func (v Value) FieldByNameFunc(match func(string) bool) Value {
-	v.mustBe(Struct)
-	if f, ok := v.typ.FieldByNameFunc(match); ok {
-		return v.FieldByIndex(f.Index)
-	}
-	return Value{}
-}
-
-// Float returns v's underlying value, as a float64.
-// It panics if v's Kind is not Float32 or Float64
-func (v Value) Float() float64 {
-	k := v.kind()
-	switch k {
-	case Float32:
-		if v.flag&flagIndir != 0 {
-			return float64(*(*float32)(v.ptr))
-		}
-		return float64(*(*float32)(unsafe.Pointer(&v.scalar)))
-	case Float64:
-		if v.flag&flagIndir != 0 {
-			return *(*float64)(v.ptr)
-		}
-		return *(*float64)(unsafe.Pointer(&v.scalar))
-	}
-	panic(&ValueError{"reflect.Value.Float", k})
-}
-
-var uint8Type = TypeOf(uint8(0)).(*rtype)
-
-// Index returns v's i'th element.
-// It panics if v's Kind is not Array, Slice, or String or i is out of range.
-func (v Value) Index(i int) Value {
-	k := v.kind()
-	switch k {
-	case Array:
-		tt := (*arrayType)(unsafe.Pointer(v.typ))
-		if i < 0 || i > int(tt.len) {
-			panic("reflect: array index out of range")
-		}
-		typ := tt.elem
-		fl := v.flag & (flagRO | flagIndir | flagAddr) // bits same as overall array
-		fl |= flag(typ.Kind()) << flagKindShift
-		offset := uintptr(i) * typ.size
-
-		var val unsafe.Pointer
-		var scalar uintptr
-		switch {
-		case fl&flagIndir != 0:
-			// Indirect.  Just bump pointer.
-			val = unsafe.Pointer(uintptr(v.ptr) + offset)
-		case typ.pointers():
-			if offset != 0 {
-				panic("can't Index(i) with i!=0 on ptrLike value")
-			}
-			val = v.ptr
-		case bigEndian:
-			// Direct.  Discard leading bytes.
-			scalar = v.scalar << (offset * 8)
-		default:
-			// Direct.  Discard leading bytes.
-			scalar = v.scalar >> (offset * 8)
-		}
-		return Value{typ, val, scalar, fl}
-
-	case Slice:
-		// Element flag same as Elem of Ptr.
-		// Addressable, indirect, possibly read-only.
-		fl := flagAddr | flagIndir | v.flag&flagRO
-		s := (*sliceHeader)(v.ptr)
-		if i < 0 || i >= s.Len {
-			panic("reflect: slice index out of range")
-		}
-		tt := (*sliceType)(unsafe.Pointer(v.typ))
-		typ := tt.elem
-		fl |= flag(typ.Kind()) << flagKindShift
-		val := unsafe.Pointer(uintptr(s.Data) + uintptr(i)*typ.size)
-		return Value{typ, val, 0, fl}
-
-	case String:
-		fl := v.flag&flagRO | flag(Uint8<<flagKindShift)
-		s := (*stringHeader)(v.ptr)
-		if i < 0 || i >= s.Len {
-			panic("reflect: string index out of range")
-		}
-		b := uintptr(0)
-		*(*byte)(unsafe.Pointer(&b)) = *(*byte)(unsafe.Pointer(uintptr(s.Data) + uintptr(i)))
-		return Value{uint8Type, nil, b, fl}
-	}
-	panic(&ValueError{"reflect.Value.Index", k})
-}
-
-// Int returns v's underlying value, as an int64.
-// It panics if v's Kind is not Int, Int8, Int16, Int32, or Int64.
-func (v Value) Int() int64 {
-	k := v.kind()
-	var p unsafe.Pointer
-	if v.flag&flagIndir != 0 {
-		p = v.ptr
-	} else {
-		// The escape analysis is good enough that &v.scalar
-		// does not trigger a heap allocation.
-		p = unsafe.Pointer(&v.scalar)
-	}
-	switch k {
-	case Int:
-		return int64(*(*int)(p))
-	case Int8:
-		return int64(*(*int8)(p))
-	case Int16:
-		return int64(*(*int16)(p))
-	case Int32:
-		return int64(*(*int32)(p))
-	case Int64:
-		return int64(*(*int64)(p))
-	}
-	panic(&ValueError{"reflect.Value.Int", k})
-}
-
-// CanInterface returns true if Interface can be used without panicking.
-func (v Value) CanInterface() bool {
-	if v.flag == 0 {
-		panic(&ValueError{"reflect.Value.CanInterface", Invalid})
-	}
-	return v.flag&flagRO == 0
-}
-
-// Interface returns v's current value as an interface{}.
-// It is equivalent to:
-//	var i interface{} = (v's underlying value)
-// It panics if the Value was obtained by accessing
-// unexported struct fields.
-func (v Value) Interface() (i interface{}) {
-	return valueInterface(v, true)
-}
-
-func valueInterface(v Value, safe bool) interface{} {
-	if v.flag == 0 {
-		panic(&ValueError{"reflect.Value.Interface", 0})
-	}
-	if safe && v.flag&flagRO != 0 {
-		// Do not allow access to unexported values via Interface,
-		// because they might be pointers that should not be
-		// writable or methods or function that should not be callable.
-		panic("reflect.Value.Interface: cannot return value obtained from unexported field or method")
-	}
-	if v.flag&flagMethod != 0 {
-		v = makeMethodValue("Interface", v)
-	}
-
-	if v.kind() == Interface {
-		// Special case: return the element inside the interface.
-		// Empty interface has one layout, all interfaces with
-		// methods have a second layout.
-		if v.NumMethod() == 0 {
-			return *(*interface{})(v.ptr)
-		}
-		return *(*interface {
-			M()
-		})(v.ptr)
-	}
-
-	// TODO: pass safe to packEface so we don't need to copy if safe==true?
-	return packEface(v)
-}
-
-// InterfaceData returns the interface v's value as a uintptr pair.
-// It panics if v's Kind is not Interface.
-func (v Value) InterfaceData() [2]uintptr {
-	// TODO: deprecate this
-	v.mustBe(Interface)
-	// We treat this as a read operation, so we allow
-	// it even for unexported data, because the caller
-	// has to import "unsafe" to turn it into something
-	// that can be abused.
-	// Interface value is always bigger than a word; assume flagIndir.
-	return *(*[2]uintptr)(v.ptr)
-}
-
-// IsNil reports whether its argument v is nil. The argument must be
-// a chan, func, interface, map, pointer, or slice value; if it is
-// not, IsNil panics. Note that IsNil is not always equivalent to a
-// regular comparison with nil in Go. For example, if v was created
-// by calling ValueOf with an uninitialized interface variable i,
-// i==nil will be true but v.IsNil will panic as v will be the zero
-// Value.
-func (v Value) IsNil() bool {
-	k := v.kind()
-	switch k {
-	case Chan, Func, Map, Ptr:
-		if v.flag&flagMethod != 0 {
-			return false
-		}
-		ptr := v.ptr
-		if v.flag&flagIndir != 0 {
-			ptr = *(*unsafe.Pointer)(ptr)
-		}
-		return ptr == nil
-	case Interface, Slice:
-		// Both interface and slice are nil if first word is 0.
-		// Both are always bigger than a word; assume flagIndir.
-		return *(*unsafe.Pointer)(v.ptr) == nil
-	}
-	panic(&ValueError{"reflect.Value.IsNil", k})
-}
-
-// IsValid returns true if v represents a value.
-// It returns false if v is the zero Value.
-// If IsValid returns false, all other methods except String panic.
-// Most functions and methods never return an invalid value.
-// If one does, its documentation states the conditions explicitly.
-func (v Value) IsValid() bool {
-	return v.flag != 0
-}
-
-// Kind returns v's Kind.
-// If v is the zero Value (IsValid returns false), Kind returns Invalid.
-func (v Value) Kind() Kind {
-	return v.kind()
-}
-
-// Len returns v's length.
-// It panics if v's Kind is not Array, Chan, Map, Slice, or String.
-func (v Value) Len() int {
-	k := v.kind()
-	switch k {
-	case Array:
-		tt := (*arrayType)(unsafe.Pointer(v.typ))
-		return int(tt.len)
-	case Chan:
-		return chanlen(v.pointer())
-	case Map:
-		return maplen(v.pointer())
-	case Slice:
-		// Slice is bigger than a word; assume flagIndir.
-		return (*sliceHeader)(v.ptr).Len
-	case String:
-		// String is bigger than a word; assume flagIndir.
-		return (*stringHeader)(v.ptr).Len
-	}
-	panic(&ValueError{"reflect.Value.Len", k})
-}
-
-// MapIndex returns the value associated with key in the map v.
-// It panics if v's Kind is not Map.
-// It returns the zero Value if key is not found in the map or if v represents a nil map.
-// As in Go, the key's value must be assignable to the map's key type.
-func (v Value) MapIndex(key Value) Value {
-	v.mustBe(Map)
-	tt := (*mapType)(unsafe.Pointer(v.typ))
-
-	// Do not require key to be exported, so that DeepEqual
-	// and other programs can use all the keys returned by
-	// MapKeys as arguments to MapIndex.  If either the map
-	// or the key is unexported, though, the result will be
-	// considered unexported.  This is consistent with the
-	// behavior for structs, which allow read but not write
-	// of unexported fields.
-	key = key.assignTo("reflect.Value.MapIndex", tt.key, nil)
-
-	var k unsafe.Pointer
-	if key.flag&flagIndir != 0 {
-		k = key.ptr
-	} else if key.typ.pointers() {
-		k = unsafe.Pointer(&key.ptr)
-	} else {
-		k = unsafe.Pointer(&key.scalar)
-	}
-	e := mapaccess(v.typ, v.pointer(), k)
-	if e == nil {
-		return Value{}
-	}
-	typ := tt.elem
-	fl := (v.flag | key.flag) & flagRO
-	fl |= flag(typ.Kind()) << flagKindShift
-	if typ.size > ptrSize {
-		// Copy result so future changes to the map
-		// won't change the underlying value.
-		c := unsafe_New(typ)
-		memmove(c, e, typ.size)
-		return Value{typ, c, 0, fl | flagIndir}
-	} else if typ.pointers() {
-		return Value{typ, *(*unsafe.Pointer)(e), 0, fl}
-	} else {
-		return Value{typ, nil, loadScalar(e, typ.size), fl}
-	}
-}
-
-// MapKeys returns a slice containing all the keys present in the map,
-// in unspecified order.
-// It panics if v's Kind is not Map.
-// It returns an empty slice if v represents a nil map.
-func (v Value) MapKeys() []Value {
-	v.mustBe(Map)
-	tt := (*mapType)(unsafe.Pointer(v.typ))
-	keyType := tt.key
-
-	fl := v.flag&flagRO | flag(keyType.Kind())<<flagKindShift
-
-	m := v.pointer()
-	mlen := int(0)
-	if m != nil {
-		mlen = maplen(m)
-	}
-	it := mapiterinit(v.typ, m)
-	a := make([]Value, mlen)
-	var i int
-	for i = 0; i < len(a); i++ {
-		key := mapiterkey(it)
-		if key == nil {
-			// Someone deleted an entry from the map since we
-			// called maplen above.  It's a data race, but nothing
-			// we can do about it.
-			break
-		}
-		if keyType.size > ptrSize {
-			// Copy result so future changes to the map
-			// won't change the underlying value.
-			c := unsafe_New(keyType)
-			memmove(c, key, keyType.size)
-			a[i] = Value{keyType, c, 0, fl | flagIndir}
-		} else if keyType.pointers() {
-			a[i] = Value{keyType, *(*unsafe.Pointer)(key), 0, fl}
-		} else {
-			a[i] = Value{keyType, nil, loadScalar(key, keyType.size), fl}
-		}
-		mapiternext(it)
-	}
-	return a[:i]
-}
-
-// Method returns a function value corresponding to v's i'th method.
-// The arguments to a Call on the returned function should not include
-// a receiver; the returned function will always use v as the receiver.
-// Method panics if i is out of range or if v is a nil interface value.
-func (v Value) Method(i int) Value {
-	if v.typ == nil {
-		panic(&ValueError{"reflect.Value.Method", Invalid})
-	}
-	if v.flag&flagMethod != 0 || i < 0 || i >= v.typ.NumMethod() {
-		panic("reflect: Method index out of range")
-	}
-	if v.typ.Kind() == Interface && v.IsNil() {
-		panic("reflect: Method on nil interface value")
-	}
-	fl := v.flag & (flagRO | flagIndir)
-	fl |= flag(Func) << flagKindShift
-	fl |= flag(i)<<flagMethodShift | flagMethod
-	return Value{v.typ, v.ptr, v.scalar, fl}
-}
-
-// NumMethod returns the number of methods in the value's method set.
-func (v Value) NumMethod() int {
-	if v.typ == nil {
-		panic(&ValueError{"reflect.Value.NumMethod", Invalid})
-	}
-	if v.flag&flagMethod != 0 {
-		return 0
-	}
-	return v.typ.NumMethod()
-}
-
-// MethodByName returns a function value corresponding to the method
-// of v with the given name.
-// The arguments to a Call on the returned function should not include
-// a receiver; the returned function will always use v as the receiver.
-// It returns the zero Value if no method was found.
-func (v Value) MethodByName(name string) Value {
-	if v.typ == nil {
-		panic(&ValueError{"reflect.Value.MethodByName", Invalid})
-	}
-	if v.flag&flagMethod != 0 {
-		return Value{}
-	}
-	m, ok := v.typ.MethodByName(name)
-	if !ok {
-		return Value{}
-	}
-	return v.Method(m.Index)
-}
-
-// NumField returns the number of fields in the struct v.
-// It panics if v's Kind is not Struct.
-func (v Value) NumField() int {
-	v.mustBe(Struct)
-	tt := (*structType)(unsafe.Pointer(v.typ))
-	return len(tt.fields)
-}
-
-// OverflowComplex returns true if the complex128 x cannot be represented by v's type.
-// It panics if v's Kind is not Complex64 or Complex128.
-func (v Value) OverflowComplex(x complex128) bool {
-	k := v.kind()
-	switch k {
-	case Complex64:
-		return overflowFloat32(real(x)) || overflowFloat32(imag(x))
-	case Complex128:
-		return false
-	}
-	panic(&ValueError{"reflect.Value.OverflowComplex", k})
-}
-
-// OverflowFloat returns true if the float64 x cannot be represented by v's type.
-// It panics if v's Kind is not Float32 or Float64.
-func (v Value) OverflowFloat(x float64) bool {
-	k := v.kind()
-	switch k {
-	case Float32:
-		return overflowFloat32(x)
-	case Float64:
-		return false
-	}
-	panic(&ValueError{"reflect.Value.OverflowFloat", k})
-}
-
-func overflowFloat32(x float64) bool {
-	if x < 0 {
-		x = -x
-	}
-	return math.MaxFloat32 < x && x <= math.MaxFloat64
-}
-
-// OverflowInt returns true if the int64 x cannot be represented by v's type.
-// It panics if v's Kind is not Int, Int8, int16, Int32, or Int64.
-func (v Value) OverflowInt(x int64) bool {
-	k := v.kind()
-	switch k {
-	case Int, Int8, Int16, Int32, Int64:
-		bitSize := v.typ.size * 8
-		trunc := (x << (64 - bitSize)) >> (64 - bitSize)
-		return x != trunc
-	}
-	panic(&ValueError{"reflect.Value.OverflowInt", k})
-}
-
-// OverflowUint returns true if the uint64 x cannot be represented by v's type.
-// It panics if v's Kind is not Uint, Uintptr, Uint8, Uint16, Uint32, or Uint64.
-func (v Value) OverflowUint(x uint64) bool {
-	k := v.kind()
-	switch k {
-	case Uint, Uintptr, Uint8, Uint16, Uint32, Uint64:
-		bitSize := v.typ.size * 8
-		trunc := (x << (64 - bitSize)) >> (64 - bitSize)
-		return x != trunc
-	}
-	panic(&ValueError{"reflect.Value.OverflowUint", k})
-}
-
-// Pointer returns v's value as a uintptr.
-// It returns uintptr instead of unsafe.Pointer so that
-// code using reflect cannot obtain unsafe.Pointers
-// without importing the unsafe package explicitly.
-// It panics if v's Kind is not Chan, Func, Map, Ptr, Slice, or UnsafePointer.
-//
-// If v's Kind is Func, the returned pointer is an underlying
-// code pointer, but not necessarily enough to identify a
-// single function uniquely. The only guarantee is that the
-// result is zero if and only if v is a nil func Value.
-//
-// If v's Kind is Slice, the returned pointer is to the first
-// element of the slice.  If the slice is nil the returned value
-// is 0.  If the slice is empty but non-nil the return value is non-zero.
-func (v Value) Pointer() uintptr {
-	// TODO: deprecate
-	k := v.kind()
-	switch k {
-	case Chan, Map, Ptr, UnsafePointer:
-		return uintptr(v.pointer())
-	case Func:
-		if v.flag&flagMethod != 0 {
-			// As the doc comment says, the returned pointer is an
-			// underlying code pointer but not necessarily enough to
-			// identify a single function uniquely. All method expressions
-			// created via reflect have the same underlying code pointer,
-			// so their Pointers are equal. The function used here must
-			// match the one used in makeMethodValue.
-			f := methodValueCall
-			return **(**uintptr)(unsafe.Pointer(&f))
-		}
-		p := v.pointer()
-		// Non-nil func value points at data block.
-		// First word of data block is actual code.
-		if p != nil {
-			p = *(*unsafe.Pointer)(p)
-		}
-		return uintptr(p)
-
-	case Slice:
-		return (*SliceHeader)(v.ptr).Data
-	}
-	panic(&ValueError{"reflect.Value.Pointer", k})
-}
-
-// Recv receives and returns a value from the channel v.
-// It panics if v's Kind is not Chan.
-// The receive blocks until a value is ready.
-// The boolean value ok is true if the value x corresponds to a send
-// on the channel, false if it is a zero value received because the channel is closed.
-func (v Value) Recv() (x Value, ok bool) {
-	v.mustBe(Chan)
-	v.mustBeExported()
-	return v.recv(false)
-}
-
-// internal recv, possibly non-blocking (nb).
-// v is known to be a channel.
-func (v Value) recv(nb bool) (val Value, ok bool) {
-	tt := (*chanType)(unsafe.Pointer(v.typ))
-	if ChanDir(tt.dir)&RecvDir == 0 {
-		panic("reflect: recv on send-only channel")
-	}
-	t := tt.elem
-	val = Value{t, nil, 0, flag(t.Kind()) << flagKindShift}
-	var p unsafe.Pointer
-	if t.size > ptrSize {
-		p = unsafe_New(t)
-		val.ptr = p
-		val.flag |= flagIndir
-	} else if t.pointers() {
-		p = unsafe.Pointer(&val.ptr)
-	} else {
-		p = unsafe.Pointer(&val.scalar)
-	}
-	selected, ok := chanrecv(v.typ, v.pointer(), nb, p)
-	if !selected {
-		val = Value{}
-	}
-	return
-}
-
-// Send sends x on the channel v.
-// It panics if v's kind is not Chan or if x's type is not the same type as v's element type.
-// As in Go, x's value must be assignable to the channel's element type.
-func (v Value) Send(x Value) {
-	v.mustBe(Chan)
-	v.mustBeExported()
-	v.send(x, false)
-}
-
-// internal send, possibly non-blocking.
-// v is known to be a channel.
-func (v Value) send(x Value, nb bool) (selected bool) {
-	tt := (*chanType)(unsafe.Pointer(v.typ))
-	if ChanDir(tt.dir)&SendDir == 0 {
-		panic("reflect: send on recv-only channel")
-	}
-	x.mustBeExported()
-	x = x.assignTo("reflect.Value.Send", tt.elem, nil)
-	var p unsafe.Pointer
-	if x.flag&flagIndir != 0 {
-		p = x.ptr
-	} else if x.typ.pointers() {
-		p = unsafe.Pointer(&x.ptr)
-	} else {
-		p = unsafe.Pointer(&x.scalar)
-	}
-	return chansend(v.typ, v.pointer(), p, nb)
-}
-
-// Set assigns x to the value v.
-// It panics if CanSet returns false.
-// As in Go, x's value must be assignable to v's type.
-func (v Value) Set(x Value) {
-	v.mustBeAssignable()
-	x.mustBeExported() // do not let unexported x leak
-	var target *interface{}
-	if v.kind() == Interface {
-		target = (*interface{})(v.ptr)
-	}
-	x = x.assignTo("reflect.Set", v.typ, target)
-	if x.flag&flagIndir != 0 {
-		memmove(v.ptr, x.ptr, v.typ.size)
-	} else if x.typ.pointers() {
-		*(*unsafe.Pointer)(v.ptr) = x.ptr
-	} else {
-		memmove(v.ptr, unsafe.Pointer(&x.scalar), v.typ.size)
-	}
-}
-
-// SetBool sets v's underlying value.
-// It panics if v's Kind is not Bool or if CanSet() is false.
-func (v Value) SetBool(x bool) {
-	v.mustBeAssignable()
-	v.mustBe(Bool)
-	*(*bool)(v.ptr) = x
-}
-
-// SetBytes sets v's underlying value.
-// It panics if v's underlying value is not a slice of bytes.
-func (v Value) SetBytes(x []byte) {
-	v.mustBeAssignable()
-	v.mustBe(Slice)
-	if v.typ.Elem().Kind() != Uint8 {
-		panic("reflect.Value.SetBytes of non-byte slice")
-	}
-	*(*[]byte)(v.ptr) = x
-}
-
-// setRunes sets v's underlying value.
-// It panics if v's underlying value is not a slice of runes (int32s).
-func (v Value) setRunes(x []rune) {
-	v.mustBeAssignable()
-	v.mustBe(Slice)
-	if v.typ.Elem().Kind() != Int32 {
-		panic("reflect.Value.setRunes of non-rune slice")
-	}
-	*(*[]rune)(v.ptr) = x
-}
-
-// SetComplex sets v's underlying value to x.
-// It panics if v's Kind is not Complex64 or Complex128, or if CanSet() is false.
-func (v Value) SetComplex(x complex128) {
-	v.mustBeAssignable()
-	switch k := v.kind(); k {
-	default:
-		panic(&ValueError{"reflect.Value.SetComplex", k})
-	case Complex64:
-		*(*complex64)(v.ptr) = complex64(x)
-	case Complex128:
-		*(*complex128)(v.ptr) = x
-	}
-}
-
-// SetFloat sets v's underlying value to x.
-// It panics if v's Kind is not Float32 or Float64, or if CanSet() is false.
-func (v Value) SetFloat(x float64) {
-	v.mustBeAssignable()
-	switch k := v.kind(); k {
-	default:
-		panic(&ValueError{"reflect.Value.SetFloat", k})
-	case Float32:
-		*(*float32)(v.ptr) = float32(x)
-	case Float64:
-		*(*float64)(v.ptr) = x
-	}
-}
-
-// SetInt sets v's underlying value to x.
-// It panics if v's Kind is not Int, Int8, Int16, Int32, or Int64, or if CanSet() is false.
-func (v Value) SetInt(x int64) {
-	v.mustBeAssignable()
-	switch k := v.kind(); k {
-	default:
-		panic(&ValueError{"reflect.Value.SetInt", k})
-	case Int:
-		*(*int)(v.ptr) = int(x)
-	case Int8:
-		*(*int8)(v.ptr) = int8(x)
-	case Int16:
-		*(*int16)(v.ptr) = int16(x)
-	case Int32:
-		*(*int32)(v.ptr) = int32(x)
-	case Int64:
-		*(*int64)(v.ptr) = x
-	}
-}
-
-// SetLen sets v's length to n.
-// It panics if v's Kind is not Slice or if n is negative or
-// greater than the capacity of the slice.
-func (v Value) SetLen(n int) {
-	v.mustBeAssignable()
-	v.mustBe(Slice)
-	s := (*sliceHeader)(v.ptr)
-	if n < 0 || n > int(s.Cap) {
-		panic("reflect: slice length out of range in SetLen")
-	}
-	s.Len = n
-}
-
-// SetCap sets v's capacity to n.
-// It panics if v's Kind is not Slice or if n is smaller than the length or
-// greater than the capacity of the slice.
-func (v Value) SetCap(n int) {
-	v.mustBeAssignable()
-	v.mustBe(Slice)
-	s := (*sliceHeader)(v.ptr)
-	if n < int(s.Len) || n > int(s.Cap) {
-		panic("reflect: slice capacity out of range in SetCap")
-	}
-	s.Cap = n
-}
-
-// SetMapIndex sets the value associated with key in the map v to val.
-// It panics if v's Kind is not Map.
-// If val is the zero Value, SetMapIndex deletes the key from the map.
-// Otherwise if v holds a nil map, SetMapIndex will panic.
-// As in Go, key's value must be assignable to the map's key type,
-// and val's value must be assignable to the map's value type.
-func (v Value) SetMapIndex(key, val Value) {
-	v.mustBe(Map)
-	v.mustBeExported()
-	key.mustBeExported()
-	tt := (*mapType)(unsafe.Pointer(v.typ))
-	key = key.assignTo("reflect.Value.SetMapIndex", tt.key, nil)
-	var k unsafe.Pointer
-	if key.flag&flagIndir != 0 {
-		k = key.ptr
-	} else if key.typ.pointers() {
-		k = unsafe.Pointer(&key.ptr)
-	} else {
-		k = unsafe.Pointer(&key.scalar)
-	}
-	if val.typ == nil {
-		mapdelete(v.typ, v.pointer(), k)
-		return
-	}
-	val.mustBeExported()
-	val = val.assignTo("reflect.Value.SetMapIndex", tt.elem, nil)
-	var e unsafe.Pointer
-	if val.flag&flagIndir != 0 {
-		e = val.ptr
-	} else if val.typ.pointers() {
-		e = unsafe.Pointer(&val.ptr)
-	} else {
-		e = unsafe.Pointer(&val.scalar)
-	}
-	mapassign(v.typ, v.pointer(), k, e)
-}
-
-// SetUint sets v's underlying value to x.
-// It panics if v's Kind is not Uint, Uintptr, Uint8, Uint16, Uint32, or Uint64, or if CanSet() is false.
-func (v Value) SetUint(x uint64) {
-	v.mustBeAssignable()
-	switch k := v.kind(); k {
-	default:
-		panic(&ValueError{"reflect.Value.SetUint", k})
-	case Uint:
-		*(*uint)(v.ptr) = uint(x)
-	case Uint8:
-		*(*uint8)(v.ptr) = uint8(x)
-	case Uint16:
-		*(*uint16)(v.ptr) = uint16(x)
-	case Uint32:
-		*(*uint32)(v.ptr) = uint32(x)
-	case Uint64:
-		*(*uint64)(v.ptr) = x
-	case Uintptr:
-		*(*uintptr)(v.ptr) = uintptr(x)
-	}
-}
-
-// SetPointer sets the unsafe.Pointer value v to x.
-// It panics if v's Kind is not UnsafePointer.
-func (v Value) SetPointer(x unsafe.Pointer) {
-	v.mustBeAssignable()
-	v.mustBe(UnsafePointer)
-	*(*unsafe.Pointer)(v.ptr) = x
-}
-
-// SetString sets v's underlying value to x.
-// It panics if v's Kind is not String or if CanSet() is false.
-func (v Value) SetString(x string) {
-	v.mustBeAssignable()
-	v.mustBe(String)
-	*(*string)(v.ptr) = x
-}
-
-// Slice returns v[i:j].
-// It panics if v's Kind is not Array, Slice or String, or if v is an unaddressable array,
-// or if the indexes are out of bounds.
-func (v Value) Slice(i, j int) Value {
-	var (
-		cap  int
-		typ  *sliceType
-		base unsafe.Pointer
-	)
-	switch kind := v.kind(); kind {
-	default:
-		panic(&ValueError{"reflect.Value.Slice", kind})
-
-	case Array:
-		if v.flag&flagAddr == 0 {
-			panic("reflect.Value.Slice: slice of unaddressable array")
-		}
-		tt := (*arrayType)(unsafe.Pointer(v.typ))
-		cap = int(tt.len)
-		typ = (*sliceType)(unsafe.Pointer(tt.slice))
-		base = v.ptr
-
-	case Slice:
-		typ = (*sliceType)(unsafe.Pointer(v.typ))
-		s := (*sliceHeader)(v.ptr)
-		base = unsafe.Pointer(s.Data)
-		cap = s.Cap
-
-	case String:
-		s := (*stringHeader)(v.ptr)
-		if i < 0 || j < i || j > s.Len {
-			panic("reflect.Value.Slice: string slice index out of bounds")
-		}
-		t := stringHeader{unsafe.Pointer(uintptr(s.Data) + uintptr(i)), j - i}
-		return Value{v.typ, unsafe.Pointer(&t), 0, v.flag}
-	}
-
-	if i < 0 || j < i || j > cap {
-		panic("reflect.Value.Slice: slice index out of bounds")
-	}
-
-	// Declare slice so that gc can see the base pointer in it.
-	var x []unsafe.Pointer
-
-	// Reinterpret as *sliceHeader to edit.
-	s := (*sliceHeader)(unsafe.Pointer(&x))
-	s.Data = unsafe.Pointer(uintptr(base) + uintptr(i)*typ.elem.Size())
-	s.Len = j - i
-	s.Cap = cap - i
-
-	fl := v.flag&flagRO | flagIndir | flag(Slice)<<flagKindShift
-	return Value{typ.common(), unsafe.Pointer(&x), 0, fl}
-}
-
-// Slice3 is the 3-index form of the slice operation: it returns v[i:j:k].
-// It panics if v's Kind is not Array or Slice, or if v is an unaddressable array,
-// or if the indexes are out of bounds.
-func (v Value) Slice3(i, j, k int) Value {
-	var (
-		cap  int
-		typ  *sliceType
-		base unsafe.Pointer
-	)
-	switch kind := v.kind(); kind {
-	default:
-		panic(&ValueError{"reflect.Value.Slice3", kind})
-
-	case Array:
-		if v.flag&flagAddr == 0 {
-			panic("reflect.Value.Slice3: slice of unaddressable array")
-		}
-		tt := (*arrayType)(unsafe.Pointer(v.typ))
-		cap = int(tt.len)
-		typ = (*sliceType)(unsafe.Pointer(tt.slice))
-		base = v.ptr
-
-	case Slice:
-		typ = (*sliceType)(unsafe.Pointer(v.typ))
-		s := (*sliceHeader)(v.ptr)
-		base = s.Data
-		cap = s.Cap
-	}
-
-	if i < 0 || j < i || k < j || k > cap {
-		panic("reflect.Value.Slice3: slice index out of bounds")
-	}
-
-	// Declare slice so that the garbage collector
-	// can see the base pointer in it.
-	var x []unsafe.Pointer
-
-	// Reinterpret as *sliceHeader to edit.
-	s := (*sliceHeader)(unsafe.Pointer(&x))
-	s.Data = unsafe.Pointer(uintptr(base) + uintptr(i)*typ.elem.Size())
-	s.Len = j - i
-	s.Cap = k - i
-
-	fl := v.flag&flagRO | flagIndir | flag(Slice)<<flagKindShift
-	return Value{typ.common(), unsafe.Pointer(&x), 0, fl}
-}
-
-// String returns the string v's underlying value, as a string.
-// String is a special case because of Go's String method convention.
-// Unlike the other getters, it does not panic if v's Kind is not String.
-// Instead, it returns a string of the form "<T value>" where T is v's type.
-func (v Value) String() string {
-	switch k := v.kind(); k {
-	case Invalid:
-		return "<invalid Value>"
-	case String:
-		return *(*string)(v.ptr)
-	}
-	// If you call String on a reflect.Value of other type, it's better to
-	// print something than to panic. Useful in debugging.
-	return "<" + v.typ.String() + " Value>"
-}
-
-// TryRecv attempts to receive a value from the channel v but will not block.
-// It panics if v's Kind is not Chan.
-// If the receive delivers a value, x is the transferred value and ok is true.
-// If the receive cannot finish without blocking, x is the zero Value and ok is false.
-// If the channel is closed, x is the zero value for the channel's element type and ok is false.
-func (v Value) TryRecv() (x Value, ok bool) {
-	v.mustBe(Chan)
-	v.mustBeExported()
-	return v.recv(true)
-}
-
-// TrySend attempts to send x on the channel v but will not block.
-// It panics if v's Kind is not Chan.
-// It returns true if the value was sent, false otherwise.
-// As in Go, x's value must be assignable to the channel's element type.
-func (v Value) TrySend(x Value) bool {
-	v.mustBe(Chan)
-	v.mustBeExported()
-	return v.send(x, true)
-}
-
-// Type returns v's type.
-func (v Value) Type() Type {
-	f := v.flag
-	if f == 0 {
-		panic(&ValueError{"reflect.Value.Type", Invalid})
-	}
-	if f&flagMethod == 0 {
-		// Easy case
-		return v.typ
-	}
-
-	// Method value.
-	// v.typ describes the receiver, not the method type.
-	i := int(v.flag) >> flagMethodShift
-	if v.typ.Kind() == Interface {
-		// Method on interface.
-		tt := (*interfaceType)(unsafe.Pointer(v.typ))
-		if i < 0 || i >= len(tt.methods) {
-			panic("reflect: internal error: invalid method index")
-		}
-		m := &tt.methods[i]
-		return m.typ
-	}
-	// Method on concrete type.
-	ut := v.typ.uncommon()
-	if ut == nil || i < 0 || i >= len(ut.methods) {
-		panic("reflect: internal error: invalid method index")
-	}
-	m := &ut.methods[i]
-	return m.mtyp
-}
-
-// Uint returns v's underlying value, as a uint64.
-// It panics if v's Kind is not Uint, Uintptr, Uint8, Uint16, Uint32, or Uint64.
-func (v Value) Uint() uint64 {
-	k := v.kind()
-	var p unsafe.Pointer
-	if v.flag&flagIndir != 0 {
-		p = v.ptr
-	} else {
-		// The escape analysis is good enough that &v.scalar
-		// does not trigger a heap allocation.
-		p = unsafe.Pointer(&v.scalar)
-	}
-	switch k {
-	case Uint:
-		return uint64(*(*uint)(p))
-	case Uint8:
-		return uint64(*(*uint8)(p))
-	case Uint16:
-		return uint64(*(*uint16)(p))
-	case Uint32:
-		return uint64(*(*uint32)(p))
-	case Uint64:
-		return uint64(*(*uint64)(p))
-	case Uintptr:
-		return uint64(*(*uintptr)(p))
-	}
-	panic(&ValueError{"reflect.Value.Uint", k})
-}
-
-// UnsafeAddr returns a pointer to v's data.
-// It is for advanced clients that also import the "unsafe" package.
-// It panics if v is not addressable.
-func (v Value) UnsafeAddr() uintptr {
-	// TODO: deprecate
-	if v.typ == nil {
-		panic(&ValueError{"reflect.Value.UnsafeAddr", Invalid})
-	}
-	if v.flag&flagAddr == 0 {
-		panic("reflect.Value.UnsafeAddr of unaddressable value")
-	}
-	return uintptr(v.ptr)
-}
-
-// StringHeader is the runtime representation of a string.
-// It cannot be used safely or portably and its representation may
-// change in a later release.
-// Moreover, the Data field is not sufficient to guarantee the data
-// it references will not be garbage collected, so programs must keep
-// a separate, correctly typed pointer to the underlying data.
-type StringHeader struct {
-	Data uintptr
-	Len  int
-}
-
-// stringHeader is a safe version of StringHeader used within this package.
-type stringHeader struct {
-	Data unsafe.Pointer
-	Len  int
-}
-
-// SliceHeader is the runtime representation of a slice.
-// It cannot be used safely or portably and its representation may
-// change in a later release.
-// Moreover, the Data field is not sufficient to guarantee the data
-// it references will not be garbage collected, so programs must keep
-// a separate, correctly typed pointer to the underlying data.
-type SliceHeader struct {
-	Data uintptr
-	Len  int
-	Cap  int
-}
-
-// sliceHeader is a safe version of SliceHeader used within this package.
-type sliceHeader struct {
-	Data unsafe.Pointer
-	Len  int
-	Cap  int
-}
-
-func typesMustMatch(what string, t1, t2 Type) {
-	if t1 != t2 {
-		panic(what + ": " + t1.String() + " != " + t2.String())
-	}
-}
-
-// grow grows the slice s so that it can hold extra more values, allocating
-// more capacity if needed. It also returns the old and new slice lengths.
-func grow(s Value, extra int) (Value, int, int) {
-	i0 := s.Len()
-	i1 := i0 + extra
-	if i1 < i0 {
-		panic("reflect.Append: slice overflow")
-	}
-	m := s.Cap()
-	if i1 <= m {
-		return s.Slice(0, i1), i0, i1
-	}
-	if m == 0 {
-		m = extra
-	} else {
-		for m < i1 {
-			if i0 < 1024 {
-				m += m
-			} else {
-				m += m / 4
-			}
-		}
-	}
-	t := MakeSlice(s.Type(), i1, m)
-	Copy(t, s)
-	return t, i0, i1
-}
-
-// Append appends the values x to a slice s and returns the resulting slice.
-// As in Go, each x's value must be assignable to the slice's element type.
-func Append(s Value, x ...Value) Value {
-	s.mustBe(Slice)
-	s, i0, i1 := grow(s, len(x))
-	for i, j := i0, 0; i < i1; i, j = i+1, j+1 {
-		s.Index(i).Set(x[j])
-	}
-	return s
-}
-
-// AppendSlice appends a slice t to a slice s and returns the resulting slice.
-// The slices s and t must have the same element type.
-func AppendSlice(s, t Value) Value {
-	s.mustBe(Slice)
-	t.mustBe(Slice)
-	typesMustMatch("reflect.AppendSlice", s.Type().Elem(), t.Type().Elem())
-	s, i0, i1 := grow(s, t.Len())
-	Copy(s.Slice(i0, i1), t)
-	return s
-}
-
-// Copy copies the contents of src into dst until either
-// dst has been filled or src has been exhausted.
-// It returns the number of elements copied.
-// Dst and src each must have kind Slice or Array, and
-// dst and src must have the same element type.
-func Copy(dst, src Value) int {
-	dk := dst.kind()
-	if dk != Array && dk != Slice {
-		panic(&ValueError{"reflect.Copy", dk})
-	}
-	if dk == Array {
-		dst.mustBeAssignable()
-	}
-	dst.mustBeExported()
-
-	sk := src.kind()
-	if sk != Array && sk != Slice {
-		panic(&ValueError{"reflect.Copy", sk})
-	}
-	src.mustBeExported()
-
-	de := dst.typ.Elem()
-	se := src.typ.Elem()
-	typesMustMatch("reflect.Copy", de, se)
-
-	n := dst.Len()
-	if sn := src.Len(); n > sn {
-		n = sn
-	}
-
-	// If sk is an in-line array, cannot take its address.
-	// Instead, copy element by element.
-	// TODO: memmove would be ok for this (sa = unsafe.Pointer(&v.scalar))
-	// if we teach the compiler that ptrs don't escape from memmove.
-	if src.flag&flagIndir == 0 {
-		for i := 0; i < n; i++ {
-			dst.Index(i).Set(src.Index(i))
-		}
-		return n
-	}
-
-	// Copy via memmove.
-	var da, sa unsafe.Pointer
-	if dk == Array {
-		da = dst.ptr
-	} else {
-		da = (*sliceHeader)(dst.ptr).Data
-	}
-	if sk == Array {
-		sa = src.ptr
-	} else {
-		sa = (*sliceHeader)(src.ptr).Data
-	}
-	memmove(da, sa, uintptr(n)*de.Size())
-	return n
-}
-
-// A runtimeSelect is a single case passed to rselect.
-// This must match ../runtime/chan.c:/runtimeSelect
-type runtimeSelect struct {
-	dir uintptr        // 0, SendDir, or RecvDir
-	typ *rtype         // channel type
-	ch  unsafe.Pointer // channel
-	val unsafe.Pointer // ptr to data (SendDir) or ptr to receive buffer (RecvDir)
-}
-
-// rselect runs a select.  It returns the index of the chosen case.
-// If the case was a receive, val is filled in with the received value.
-// The conventional OK bool indicates whether the receive corresponds
-// to a sent value.
-//go:noescape
-func rselect([]runtimeSelect) (chosen int, recvOK bool)
-
-// A SelectDir describes the communication direction of a select case.
-type SelectDir int
-
-// NOTE: These values must match ../runtime/chan.c:/SelectDir.
-
-const (
-	_             SelectDir = iota
-	SelectSend              // case Chan <- Send
-	SelectRecv              // case <-Chan:
-	SelectDefault           // default
-)
-
-// A SelectCase describes a single case in a select operation.
-// The kind of case depends on Dir, the communication direction.
-//
-// If Dir is SelectDefault, the case represents a default case.
-// Chan and Send must be zero Values.
-//
-// If Dir is SelectSend, the case represents a send operation.
-// Normally Chan's underlying value must be a channel, and Send's underlying value must be
-// assignable to the channel's element type. As a special case, if Chan is a zero Value,
-// then the case is ignored, and the field Send will also be ignored and may be either zero
-// or non-zero.
-//
-// If Dir is SelectRecv, the case represents a receive operation.
-// Normally Chan's underlying value must be a channel and Send must be a zero Value.
-// If Chan is a zero Value, then the case is ignored, but Send must still be a zero Value.
-// When a receive operation is selected, the received Value is returned by Select.
-//
-type SelectCase struct {
-	Dir  SelectDir // direction of case
-	Chan Value     // channel to use (for send or receive)
-	Send Value     // value to send (for send)
-}
-
-// Select executes a select operation described by the list of cases.
-// Like the Go select statement, it blocks until at least one of the cases
-// can proceed, makes a uniform pseudo-random choice,
-// and then executes that case. It returns the index of the chosen case
-// and, if that case was a receive operation, the value received and a
-// boolean indicating whether the value corresponds to a send on the channel
-// (as opposed to a zero value received because the channel is closed).
-func Select(cases []SelectCase) (chosen int, recv Value, recvOK bool) {
-	// NOTE: Do not trust that caller is not modifying cases data underfoot.
-	// The range is safe because the caller cannot modify our copy of the len
-	// and each iteration makes its own copy of the value c.
-	runcases := make([]runtimeSelect, len(cases))
-	haveDefault := false
-	for i, c := range cases {
-		rc := &runcases[i]
-		rc.dir = uintptr(c.Dir)
-		switch c.Dir {
-		default:
-			panic("reflect.Select: invalid Dir")
-
-		case SelectDefault: // default
-			if haveDefault {
-				panic("reflect.Select: multiple default cases")
-			}
-			haveDefault = true
-			if c.Chan.IsValid() {
-				panic("reflect.Select: default case has Chan value")
-			}
-			if c.Send.IsValid() {
-				panic("reflect.Select: default case has Send value")
-			}
-
-		case SelectSend:
-			ch := c.Chan
-			if !ch.IsValid() {
-				break
-			}
-			ch.mustBe(Chan)
-			ch.mustBeExported()
-			tt := (*chanType)(unsafe.Pointer(ch.typ))
-			if ChanDir(tt.dir)&SendDir == 0 {
-				panic("reflect.Select: SendDir case using recv-only channel")
-			}
-			rc.ch = ch.pointer()
-			rc.typ = &tt.rtype
-			v := c.Send
-			if !v.IsValid() {
-				panic("reflect.Select: SendDir case missing Send value")
-			}
-			v.mustBeExported()
-			v = v.assignTo("reflect.Select", tt.elem, nil)
-			if v.flag&flagIndir != 0 {
-				rc.val = v.ptr
-			} else if v.typ.pointers() {
-				rc.val = unsafe.Pointer(&v.ptr)
-			} else {
-				rc.val = unsafe.Pointer(&v.scalar)
-			}
-
-		case SelectRecv:
-			if c.Send.IsValid() {
-				panic("reflect.Select: RecvDir case has Send value")
-			}
-			ch := c.Chan
-			if !ch.IsValid() {
-				break
-			}
-			ch.mustBe(Chan)
-			ch.mustBeExported()
-			tt := (*chanType)(unsafe.Pointer(ch.typ))
-			if ChanDir(tt.dir)&RecvDir == 0 {
-				panic("reflect.Select: RecvDir case using send-only channel")
-			}
-			rc.ch = ch.pointer()
-			rc.typ = &tt.rtype
-			rc.val = unsafe_New(tt.elem)
-		}
-	}
-
-	chosen, recvOK = rselect(runcases)
-	if runcases[chosen].dir == uintptr(SelectRecv) {
-		tt := (*chanType)(unsafe.Pointer(runcases[chosen].typ))
-		t := tt.elem
-		p := runcases[chosen].val
-		fl := flag(t.Kind()) << flagKindShift
-		if t.size > ptrSize {
-			recv = Value{t, p, 0, fl | flagIndir}
-		} else if t.pointers() {
-			recv = Value{t, *(*unsafe.Pointer)(p), 0, fl}
-		} else {
-			recv = Value{t, nil, loadScalar(p, t.size), fl}
-		}
-	}
-	return chosen, recv, recvOK
-}
-
-/*
- * constructors
- */
-
-// implemented in package runtime
-func unsafe_New(*rtype) unsafe.Pointer
-func unsafe_NewArray(*rtype, int) unsafe.Pointer
-
-// MakeSlice creates a new zero-initialized slice value
-// for the specified slice type, length, and capacity.
-func MakeSlice(typ Type, len, cap int) Value {
-	if typ.Kind() != Slice {
-		panic("reflect.MakeSlice of non-slice type")
-	}
-	if len < 0 {
-		panic("reflect.MakeSlice: negative len")
-	}
-	if cap < 0 {
-		panic("reflect.MakeSlice: negative cap")
-	}
-	if len > cap {
-		panic("reflect.MakeSlice: len > cap")
-	}
-
-	s := sliceHeader{unsafe_NewArray(typ.Elem().(*rtype), cap), len, cap}
-	return Value{typ.common(), unsafe.Pointer(&s), 0, flagIndir | flag(Slice)<<flagKindShift}
-}
-
-// MakeChan creates a new channel with the specified type and buffer size.
-func MakeChan(typ Type, buffer int) Value {
-	if typ.Kind() != Chan {
-		panic("reflect.MakeChan of non-chan type")
-	}
-	if buffer < 0 {
-		panic("reflect.MakeChan: negative buffer size")
-	}
-	if typ.ChanDir() != BothDir {
-		panic("reflect.MakeChan: unidirectional channel type")
-	}
-	ch := makechan(typ.(*rtype), uint64(buffer))
-	return Value{typ.common(), ch, 0, flag(Chan) << flagKindShift}
-}
-
-// MakeMap creates a new map of the specified type.
-func MakeMap(typ Type) Value {
-	if typ.Kind() != Map {
-		panic("reflect.MakeMap of non-map type")
-	}
-	m := makemap(typ.(*rtype))
-	return Value{typ.common(), m, 0, flag(Map) << flagKindShift}
-}
-
-// Indirect returns the value that v points to.
-// If v is a nil pointer, Indirect returns a zero Value.
-// If v is not a pointer, Indirect returns v.
-func Indirect(v Value) Value {
-	if v.Kind() != Ptr {
-		return v
-	}
-	return v.Elem()
-}
-
-// ValueOf returns a new Value initialized to the concrete value
-// stored in the interface i.  ValueOf(nil) returns the zero Value.
-func ValueOf(i interface{}) Value {
-	if i == nil {
-		return Value{}
-	}
-
-	// TODO(rsc): Eliminate this terrible hack.
-	// In the call to unpackEface, i.typ doesn't escape,
-	// and i.word is an integer.  So it looks like
-	// i doesn't escape.  But really it does,
-	// because i.word is actually a pointer.
-	escapes(i)
-
-	return unpackEface(i)
-}
-
-// Zero returns a Value representing the zero value for the specified type.
-// The result is different from the zero value of the Value struct,
-// which represents no value at all.
-// For example, Zero(TypeOf(42)) returns a Value with Kind Int and value 0.
-// The returned value is neither addressable nor settable.
-func Zero(typ Type) Value {
-	if typ == nil {
-		panic("reflect: Zero(nil)")
-	}
-	t := typ.common()
-	fl := flag(t.Kind()) << flagKindShift
-	if t.size <= ptrSize {
-		return Value{t, nil, 0, fl}
-	}
-	return Value{t, unsafe_New(typ.(*rtype)), 0, fl | flagIndir}
-}
-
-// New returns a Value representing a pointer to a new zero value
-// for the specified type.  That is, the returned Value's Type is PtrTo(typ).
-func New(typ Type) Value {
-	if typ == nil {
-		panic("reflect: New(nil)")
-	}
-	ptr := unsafe_New(typ.(*rtype))
-	fl := flag(Ptr) << flagKindShift
-	return Value{typ.common().ptrTo(), ptr, 0, fl}
-}
-
-// NewAt returns a Value representing a pointer to a value of the
-// specified type, using p as that pointer.
-func NewAt(typ Type, p unsafe.Pointer) Value {
-	fl := flag(Ptr) << flagKindShift
-	return Value{typ.common().ptrTo(), p, 0, fl}
-}
-
-// assignTo returns a value v that can be assigned directly to typ.
-// It panics if v is not assignable to typ.
-// For a conversion to an interface type, target is a suggested scratch space to use.
-func (v Value) assignTo(context string, dst *rtype, target *interface{}) Value {
-	if v.flag&flagMethod != 0 {
-		v = makeMethodValue(context, v)
-	}
-
-	switch {
-	case directlyAssignable(dst, v.typ):
-		// Overwrite type so that they match.
-		// Same memory layout, so no harm done.
-		v.typ = dst
-		fl := v.flag & (flagRO | flagAddr | flagIndir)
-		fl |= flag(dst.Kind()) << flagKindShift
-		return Value{dst, v.ptr, v.scalar, fl}
-
-	case implements(dst, v.typ):
-		if target == nil {
-			target = new(interface{})
-		}
-		x := valueInterface(v, false)
-		if dst.NumMethod() == 0 {
-			*target = x
-		} else {
-			ifaceE2I(dst, x, unsafe.Pointer(target))
-		}
-		return Value{dst, unsafe.Pointer(target), 0, flagIndir | flag(Interface)<<flagKindShift}
-	}
-
-	// Failed.
-	panic(context + ": value of type " + v.typ.String() + " is not assignable to type " + dst.String())
-}
-
-// Convert returns the value v converted to type t.
-// If the usual Go conversion rules do not allow conversion
-// of the value v to type t, Convert panics.
-func (v Value) Convert(t Type) Value {
-	if v.flag&flagMethod != 0 {
-		v = makeMethodValue("Convert", v)
-	}
-	op := convertOp(t.common(), v.typ)
-	if op == nil {
-		panic("reflect.Value.Convert: value of type " + v.typ.String() + " cannot be converted to type " + t.String())
-	}
-	return op(v, t)
-}
-
-// convertOp returns the function to convert a value of type src
-// to a value of type dst. If the conversion is illegal, convertOp returns nil.
-func convertOp(dst, src *rtype) func(Value, Type) Value {
-	switch src.Kind() {
-	case Int, Int8, Int16, Int32, Int64:
-		switch dst.Kind() {
-		case Int, Int8, Int16, Int32, Int64, Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
-			return cvtInt
-		case Float32, Float64:
-			return cvtIntFloat
-		case String:
-			return cvtIntString
-		}
-
-	case Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
-		switch dst.Kind() {
-		case Int, Int8, Int16, Int32, Int64, Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
-			return cvtUint
-		case Float32, Float64:
-			return cvtUintFloat
-		case String:
-			return cvtUintString
-		}
-
-	case Float32, Float64:
-		switch dst.Kind() {
-		case Int, Int8, Int16, Int32, Int64:
-			return cvtFloatInt
-		case Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
-			return cvtFloatUint
-		case Float32, Float64:
-			return cvtFloat
-		}
-
-	case Complex64, Complex128:
-		switch dst.Kind() {
-		case Complex64, Complex128:
-			return cvtComplex
-		}
-
-	case String:
-		if dst.Kind() == Slice && dst.Elem().PkgPath() == "" {
-			switch dst.Elem().Kind() {
-			case Uint8:
-				return cvtStringBytes
-			case Int32:
-				return cvtStringRunes
-			}
-		}
-
-	case Slice:
-		if dst.Kind() == String && src.Elem().PkgPath() == "" {
-			switch src.Elem().Kind() {
-			case Uint8:
-				return cvtBytesString
-			case Int32:
-				return cvtRunesString
-			}
-		}
-	}
-
-	// dst and src have same underlying type.
-	if haveIdenticalUnderlyingType(dst, src) {
-		return cvtDirect
-	}
-
-	// dst and src are unnamed pointer types with same underlying base type.
-	if dst.Kind() == Ptr && dst.Name() == "" &&
-		src.Kind() == Ptr && src.Name() == "" &&
-		haveIdenticalUnderlyingType(dst.Elem().common(), src.Elem().common()) {
-		return cvtDirect
-	}
-
-	if implements(dst, src) {
-		if src.Kind() == Interface {
-			return cvtI2I
-		}
-		return cvtT2I
-	}
-
-	return nil
-}
-
-// makeInt returns a Value of type t equal to bits (possibly truncated),
-// where t is a signed or unsigned int type.
-func makeInt(f flag, bits uint64, t Type) Value {
-	typ := t.common()
-	if typ.size > ptrSize {
-		// Assume ptrSize >= 4, so this must be uint64.
-		ptr := unsafe_New(typ)
-		*(*uint64)(unsafe.Pointer(ptr)) = bits
-		return Value{typ, ptr, 0, f | flagIndir | flag(typ.Kind())<<flagKindShift}
-	}
-	var s uintptr
-	switch typ.size {
-	case 1:
-		*(*uint8)(unsafe.Pointer(&s)) = uint8(bits)
-	case 2:
-		*(*uint16)(unsafe.Pointer(&s)) = uint16(bits)
-	case 4:
-		*(*uint32)(unsafe.Pointer(&s)) = uint32(bits)
-	case 8:
-		*(*uint64)(unsafe.Pointer(&s)) = uint64(bits)
-	}
-	return Value{typ, nil, s, f | flag(typ.Kind())<<flagKindShift}
-}
-
-// makeFloat returns a Value of type t equal to v (possibly truncated to float32),
-// where t is a float32 or float64 type.
-func makeFloat(f flag, v float64, t Type) Value {
-	typ := t.common()
-	if typ.size > ptrSize {
-		// Assume ptrSize >= 4, so this must be float64.
-		ptr := unsafe_New(typ)
-		*(*float64)(unsafe.Pointer(ptr)) = v
-		return Value{typ, ptr, 0, f | flagIndir | flag(typ.Kind())<<flagKindShift}
-	}
-
-	var s uintptr
-	switch typ.size {
-	case 4:
-		*(*float32)(unsafe.Pointer(&s)) = float32(v)
-	case 8:
-		*(*float64)(unsafe.Pointer(&s)) = v
-	}
-	return Value{typ, nil, s, f | flag(typ.Kind())<<flagKindShift}
-}
-
-// makeComplex returns a Value of type t equal to v (possibly truncated to complex64),
-// where t is a complex64 or complex128 type.
-func makeComplex(f flag, v complex128, t Type) Value {
-	typ := t.common()
-	if typ.size > ptrSize {
-		ptr := unsafe_New(typ)
-		switch typ.size {
-		case 8:
-			*(*complex64)(unsafe.Pointer(ptr)) = complex64(v)
-		case 16:
-			*(*complex128)(unsafe.Pointer(ptr)) = v
-		}
-		return Value{typ, ptr, 0, f | flagIndir | flag(typ.Kind())<<flagKindShift}
-	}
-
-	// Assume ptrSize <= 8 so this must be complex64.
-	var s uintptr
-	*(*complex64)(unsafe.Pointer(&s)) = complex64(v)
-	return Value{typ, nil, s, f | flag(typ.Kind())<<flagKindShift}
-}
-
-func makeString(f flag, v string, t Type) Value {
-	ret := New(t).Elem()
-	ret.SetString(v)
-	ret.flag = ret.flag&^flagAddr | f
-	return ret
-}
-
-func makeBytes(f flag, v []byte, t Type) Value {
-	ret := New(t).Elem()
-	ret.SetBytes(v)
-	ret.flag = ret.flag&^flagAddr | f
-	return ret
-}
-
-func makeRunes(f flag, v []rune, t Type) Value {
-	ret := New(t).Elem()
-	ret.setRunes(v)
-	ret.flag = ret.flag&^flagAddr | f
-	return ret
-}
-
-// These conversion functions are returned by convertOp
-// for classes of conversions. For example, the first function, cvtInt,
-// takes any value v of signed int type and returns the value converted
-// to type t, where t is any signed or unsigned int type.
-
-// convertOp: intXX -> [u]intXX
-func cvtInt(v Value, t Type) Value {
-	return makeInt(v.flag&flagRO, uint64(v.Int()), t)
-}
-
-// convertOp: uintXX -> [u]intXX
-func cvtUint(v Value, t Type) Value {
-	return makeInt(v.flag&flagRO, v.Uint(), t)
-}
-
-// convertOp: floatXX -> intXX
-func cvtFloatInt(v Value, t Type) Value {
-	return makeInt(v.flag&flagRO, uint64(int64(v.Float())), t)
-}
-
-// convertOp: floatXX -> uintXX
-func cvtFloatUint(v Value, t Type) Value {
-	return makeInt(v.flag&flagRO, uint64(v.Float()), t)
-}
-
-// convertOp: intXX -> floatXX
-func cvtIntFloat(v Value, t Type) Value {
-	return makeFloat(v.flag&flagRO, float64(v.Int()), t)
-}
-
-// convertOp: uintXX -> floatXX
-func cvtUintFloat(v Value, t Type) Value {
-	return makeFloat(v.flag&flagRO, float64(v.Uint()), t)
-}
-
-// convertOp: floatXX -> floatXX
-func cvtFloat(v Value, t Type) Value {
-	return makeFloat(v.flag&flagRO, v.Float(), t)
-}
-
-// convertOp: complexXX -> complexXX
-func cvtComplex(v Value, t Type) Value {
-	return makeComplex(v.flag&flagRO, v.Complex(), t)
-}
-
-// convertOp: intXX -> string
-func cvtIntString(v Value, t Type) Value {
-	return makeString(v.flag&flagRO, string(v.Int()), t)
-}
-
-// convertOp: uintXX -> string
-func cvtUintString(v Value, t Type) Value {
-	return makeString(v.flag&flagRO, string(v.Uint()), t)
-}
-
-// convertOp: []byte -> string
-func cvtBytesString(v Value, t Type) Value {
-	return makeString(v.flag&flagRO, string(v.Bytes()), t)
-}
-
-// convertOp: string -> []byte
-func cvtStringBytes(v Value, t Type) Value {
-	return makeBytes(v.flag&flagRO, []byte(v.String()), t)
-}
-
-// convertOp: []rune -> string
-func cvtRunesString(v Value, t Type) Value {
-	return makeString(v.flag&flagRO, string(v.runes()), t)
-}
-
-// convertOp: string -> []rune
-func cvtStringRunes(v Value, t Type) Value {
-	return makeRunes(v.flag&flagRO, []rune(v.String()), t)
-}
-
-// convertOp: direct copy
-func cvtDirect(v Value, typ Type) Value {
-	f := v.flag
-	t := typ.common()
-	ptr := v.ptr
-	if f&flagAddr != 0 {
-		// indirect, mutable word - make a copy
-		c := unsafe_New(t)
-		memmove(c, ptr, t.size)
-		ptr = c
-		f &^= flagAddr
-	}
-	return Value{t, ptr, v.scalar, v.flag&flagRO | f} // v.flag&flagRO|f == f?
-}
-
-// convertOp: concrete -> interface
-func cvtT2I(v Value, typ Type) Value {
-	target := new(interface{})
-	x := valueInterface(v, false)
-	if typ.NumMethod() == 0 {
-		*target = x
-	} else {
-		ifaceE2I(typ.(*rtype), x, unsafe.Pointer(target))
-	}
-	return Value{typ.common(), unsafe.Pointer(target), 0, v.flag&flagRO | flagIndir | flag(Interface)<<flagKindShift}
-}
-
-// convertOp: interface -> interface
-func cvtI2I(v Value, typ Type) Value {
-	if v.IsNil() {
-		ret := Zero(typ)
-		ret.flag |= v.flag & flagRO
-		return ret
-	}
-	return cvtT2I(v.Elem(), typ)
-}
-
-// implemented in ../pkg/runtime
-func chancap(ch unsafe.Pointer) int
-func chanclose(ch unsafe.Pointer)
-func chanlen(ch unsafe.Pointer) int
-
-//go:noescape
-func chanrecv(t *rtype, ch unsafe.Pointer, nb bool, val unsafe.Pointer) (selected, received bool)
-
-//go:noescape
-func chansend(t *rtype, ch unsafe.Pointer, val unsafe.Pointer, nb bool) bool
-
-func makechan(typ *rtype, size uint64) (ch unsafe.Pointer)
-func makemap(t *rtype) (m unsafe.Pointer)
-func mapaccess(t *rtype, m unsafe.Pointer, key unsafe.Pointer) (val unsafe.Pointer)
-func mapassign(t *rtype, m unsafe.Pointer, key, val unsafe.Pointer)
-func mapdelete(t *rtype, m unsafe.Pointer, key unsafe.Pointer)
-func mapiterinit(t *rtype, m unsafe.Pointer) unsafe.Pointer
-func mapiterkey(it unsafe.Pointer) (key unsafe.Pointer)
-func mapiternext(it unsafe.Pointer)
-func maplen(m unsafe.Pointer) int
-
-func call(fn, arg unsafe.Pointer, n uint32, retoffset uint32)
-func ifaceE2I(t *rtype, src interface{}, dst unsafe.Pointer)
-
-// Dummy annotation marking that the value x escapes,
-// for use in cases where the reflect code is so clever that
-// the compiler cannot follow.
-func escapes(x interface{}) {
-	if dummy.b {
-		dummy.x = x
-	}
-}
-
-var dummy struct {
-	b bool
-	x interface{}
-}
diff --git a/src/pkg/regexp/all_test.go b/src/pkg/regexp/all_test.go
deleted file mode 100644
index 301a1df..0000000
--- a/src/pkg/regexp/all_test.go
+++ /dev/null
@@ -1,645 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package regexp
-
-import (
-	"reflect"
-	"strings"
-	"testing"
-)
-
-var good_re = []string{
-	``,
-	`.`,
-	`^.$`,
-	`a`,
-	`a*`,
-	`a+`,
-	`a?`,
-	`a|b`,
-	`a*|b*`,
-	`(a*|b)(c*|d)`,
-	`[a-z]`,
-	`[a-abc-c\-\]\[]`,
-	`[a-z]+`,
-	`[abc]`,
-	`[^1234]`,
-	`[^\n]`,
-	`\!\\`,
-}
-
-type stringError struct {
-	re  string
-	err string
-}
-
-var bad_re = []stringError{
-	{`*`, "missing argument to repetition operator: `*`"},
-	{`+`, "missing argument to repetition operator: `+`"},
-	{`?`, "missing argument to repetition operator: `?`"},
-	{`(abc`, "missing closing ): `(abc`"},
-	{`abc)`, "unexpected ): `abc)`"},
-	{`x[a-z`, "missing closing ]: `[a-z`"},
-	{`[z-a]`, "invalid character class range: `z-a`"},
-	{`abc\`, "trailing backslash at end of expression"},
-	{`a**`, "invalid nested repetition operator: `**`"},
-	{`a*+`, "invalid nested repetition operator: `*+`"},
-	{`\x`, "invalid escape sequence: `\\x`"},
-}
-
-func compileTest(t *testing.T, expr string, error string) *Regexp {
-	re, err := Compile(expr)
-	if error == "" && err != nil {
-		t.Error("compiling `", expr, "`; unexpected error: ", err.Error())
-	}
-	if error != "" && err == nil {
-		t.Error("compiling `", expr, "`; missing error")
-	} else if error != "" && !strings.Contains(err.Error(), error) {
-		t.Error("compiling `", expr, "`; wrong error: ", err.Error(), "; want ", error)
-	}
-	return re
-}
-
-func TestGoodCompile(t *testing.T) {
-	for i := 0; i < len(good_re); i++ {
-		compileTest(t, good_re[i], "")
-	}
-}
-
-func TestBadCompile(t *testing.T) {
-	for i := 0; i < len(bad_re); i++ {
-		compileTest(t, bad_re[i].re, bad_re[i].err)
-	}
-}
-
-func matchTest(t *testing.T, test *FindTest) {
-	re := compileTest(t, test.pat, "")
-	if re == nil {
-		return
-	}
-	m := re.MatchString(test.text)
-	if m != (len(test.matches) > 0) {
-		t.Errorf("MatchString failure on %s: %t should be %t", test, m, len(test.matches) > 0)
-	}
-	// now try bytes
-	m = re.Match([]byte(test.text))
-	if m != (len(test.matches) > 0) {
-		t.Errorf("Match failure on %s: %t should be %t", test, m, len(test.matches) > 0)
-	}
-}
-
-func TestMatch(t *testing.T) {
-	for _, test := range findTests {
-		matchTest(t, &test)
-	}
-}
-
-func matchFunctionTest(t *testing.T, test *FindTest) {
-	m, err := MatchString(test.pat, test.text)
-	if err == nil {
-		return
-	}
-	if m != (len(test.matches) > 0) {
-		t.Errorf("Match failure on %s: %t should be %t", test, m, len(test.matches) > 0)
-	}
-}
-
-func TestMatchFunction(t *testing.T) {
-	for _, test := range findTests {
-		matchFunctionTest(t, &test)
-	}
-}
-
-type ReplaceTest struct {
-	pattern, replacement, input, output string
-}
-
-var replaceTests = []ReplaceTest{
-	// Test empty input and/or replacement, with pattern that matches the empty string.
-	{"", "", "", ""},
-	{"", "x", "", "x"},
-	{"", "", "abc", "abc"},
-	{"", "x", "abc", "xaxbxcx"},
-
-	// Test empty input and/or replacement, with pattern that does not match the empty string.
-	{"b", "", "", ""},
-	{"b", "x", "", ""},
-	{"b", "", "abc", "ac"},
-	{"b", "x", "abc", "axc"},
-	{"y", "", "", ""},
-	{"y", "x", "", ""},
-	{"y", "", "abc", "abc"},
-	{"y", "x", "abc", "abc"},
-
-	// Multibyte characters -- verify that we don't try to match in the middle
-	// of a character.
-	{"[a-c]*", "x", "\u65e5", "x\u65e5x"},
-	{"[^\u65e5]", "x", "abc\u65e5def", "xxx\u65e5xxx"},
-
-	// Start and end of a string.
-	{"^[a-c]*", "x", "abcdabc", "xdabc"},
-	{"[a-c]*$", "x", "abcdabc", "abcdx"},
-	{"^[a-c]*$", "x", "abcdabc", "abcdabc"},
-	{"^[a-c]*", "x", "abc", "x"},
-	{"[a-c]*$", "x", "abc", "x"},
-	{"^[a-c]*$", "x", "abc", "x"},
-	{"^[a-c]*", "x", "dabce", "xdabce"},
-	{"[a-c]*$", "x", "dabce", "dabcex"},
-	{"^[a-c]*$", "x", "dabce", "dabce"},
-	{"^[a-c]*", "x", "", "x"},
-	{"[a-c]*$", "x", "", "x"},
-	{"^[a-c]*$", "x", "", "x"},
-
-	{"^[a-c]+", "x", "abcdabc", "xdabc"},
-	{"[a-c]+$", "x", "abcdabc", "abcdx"},
-	{"^[a-c]+$", "x", "abcdabc", "abcdabc"},
-	{"^[a-c]+", "x", "abc", "x"},
-	{"[a-c]+$", "x", "abc", "x"},
-	{"^[a-c]+$", "x", "abc", "x"},
-	{"^[a-c]+", "x", "dabce", "dabce"},
-	{"[a-c]+$", "x", "dabce", "dabce"},
-	{"^[a-c]+$", "x", "dabce", "dabce"},
-	{"^[a-c]+", "x", "", ""},
-	{"[a-c]+$", "x", "", ""},
-	{"^[a-c]+$", "x", "", ""},
-
-	// Other cases.
-	{"abc", "def", "abcdefg", "defdefg"},
-	{"bc", "BC", "abcbcdcdedef", "aBCBCdcdedef"},
-	{"abc", "", "abcdabc", "d"},
-	{"x", "xXx", "xxxXxxx", "xXxxXxxXxXxXxxXxxXx"},
-	{"abc", "d", "", ""},
-	{"abc", "d", "abc", "d"},
-	{".+", "x", "abc", "x"},
-	{"[a-c]*", "x", "def", "xdxexfx"},
-	{"[a-c]+", "x", "abcbcdcdedef", "xdxdedef"},
-	{"[a-c]*", "x", "abcbcdcdedef", "xdxdxexdxexfx"},
-
-	// Substitutions
-	{"a+", "($0)", "banana", "b(a)n(a)n(a)"},
-	{"a+", "(${0})", "banana", "b(a)n(a)n(a)"},
-	{"a+", "(${0})$0", "banana", "b(a)an(a)an(a)a"},
-	{"a+", "(${0})$0", "banana", "b(a)an(a)an(a)a"},
-	{"hello, (.+)", "goodbye, ${1}", "hello, world", "goodbye, world"},
-	{"hello, (.+)", "goodbye, $1x", "hello, world", "goodbye, "},
-	{"hello, (.+)", "goodbye, ${1}x", "hello, world", "goodbye, worldx"},
-	{"hello, (.+)", "<$0><$1><$2><$3>", "hello, world", "<hello, world><world><><>"},
-	{"hello, (?P<noun>.+)", "goodbye, $noun!", "hello, world", "goodbye, world!"},
-	{"hello, (?P<noun>.+)", "goodbye, ${noun}", "hello, world", "goodbye, world"},
-	{"(?P<x>hi)|(?P<x>bye)", "$x$x$x", "hi", "hihihi"},
-	{"(?P<x>hi)|(?P<x>bye)", "$x$x$x", "bye", "byebyebye"},
-	{"(?P<x>hi)|(?P<x>bye)", "$xyz", "hi", ""},
-	{"(?P<x>hi)|(?P<x>bye)", "${x}yz", "hi", "hiyz"},
-	{"(?P<x>hi)|(?P<x>bye)", "hello $$x", "hi", "hello $x"},
-	{"a+", "${oops", "aaa", "${oops"},
-	{"a+", "$$", "aaa", "$"},
-	{"a+", "$", "aaa", "$"},
-
-	// Substitution when subexpression isn't found
-	{"(x)?", "$1", "123", "123"},
-	{"abc", "$1", "123", "123"},
-}
-
-var replaceLiteralTests = []ReplaceTest{
-	// Substitutions
-	{"a+", "($0)", "banana", "b($0)n($0)n($0)"},
-	{"a+", "(${0})", "banana", "b(${0})n(${0})n(${0})"},
-	{"a+", "(${0})$0", "banana", "b(${0})$0n(${0})$0n(${0})$0"},
-	{"a+", "(${0})$0", "banana", "b(${0})$0n(${0})$0n(${0})$0"},
-	{"hello, (.+)", "goodbye, ${1}", "hello, world", "goodbye, ${1}"},
-	{"hello, (?P<noun>.+)", "goodbye, $noun!", "hello, world", "goodbye, $noun!"},
-	{"hello, (?P<noun>.+)", "goodbye, ${noun}", "hello, world", "goodbye, ${noun}"},
-	{"(?P<x>hi)|(?P<x>bye)", "$x$x$x", "hi", "$x$x$x"},
-	{"(?P<x>hi)|(?P<x>bye)", "$x$x$x", "bye", "$x$x$x"},
-	{"(?P<x>hi)|(?P<x>bye)", "$xyz", "hi", "$xyz"},
-	{"(?P<x>hi)|(?P<x>bye)", "${x}yz", "hi", "${x}yz"},
-	{"(?P<x>hi)|(?P<x>bye)", "hello $$x", "hi", "hello $$x"},
-	{"a+", "${oops", "aaa", "${oops"},
-	{"a+", "$$", "aaa", "$$"},
-	{"a+", "$", "aaa", "$"},
-}
-
-type ReplaceFuncTest struct {
-	pattern       string
-	replacement   func(string) string
-	input, output string
-}
-
-var replaceFuncTests = []ReplaceFuncTest{
-	{"[a-c]", func(s string) string { return "x" + s + "y" }, "defabcdef", "defxayxbyxcydef"},
-	{"[a-c]+", func(s string) string { return "x" + s + "y" }, "defabcdef", "defxabcydef"},
-	{"[a-c]*", func(s string) string { return "x" + s + "y" }, "defabcdef", "xydxyexyfxabcydxyexyfxy"},
-}
-
-func TestReplaceAll(t *testing.T) {
-	for _, tc := range replaceTests {
-		re, err := Compile(tc.pattern)
-		if err != nil {
-			t.Errorf("Unexpected error compiling %q: %v", tc.pattern, err)
-			continue
-		}
-		actual := re.ReplaceAllString(tc.input, tc.replacement)
-		if actual != tc.output {
-			t.Errorf("%q.ReplaceAllString(%q,%q) = %q; want %q",
-				tc.pattern, tc.input, tc.replacement, actual, tc.output)
-		}
-		// now try bytes
-		actual = string(re.ReplaceAll([]byte(tc.input), []byte(tc.replacement)))
-		if actual != tc.output {
-			t.Errorf("%q.ReplaceAll(%q,%q) = %q; want %q",
-				tc.pattern, tc.input, tc.replacement, actual, tc.output)
-		}
-	}
-}
-
-func TestReplaceAllLiteral(t *testing.T) {
-	// Run ReplaceAll tests that do not have $ expansions.
-	for _, tc := range replaceTests {
-		if strings.Contains(tc.replacement, "$") {
-			continue
-		}
-		re, err := Compile(tc.pattern)
-		if err != nil {
-			t.Errorf("Unexpected error compiling %q: %v", tc.pattern, err)
-			continue
-		}
-		actual := re.ReplaceAllLiteralString(tc.input, tc.replacement)
-		if actual != tc.output {
-			t.Errorf("%q.ReplaceAllLiteralString(%q,%q) = %q; want %q",
-				tc.pattern, tc.input, tc.replacement, actual, tc.output)
-		}
-		// now try bytes
-		actual = string(re.ReplaceAllLiteral([]byte(tc.input), []byte(tc.replacement)))
-		if actual != tc.output {
-			t.Errorf("%q.ReplaceAllLiteral(%q,%q) = %q; want %q",
-				tc.pattern, tc.input, tc.replacement, actual, tc.output)
-		}
-	}
-
-	// Run literal-specific tests.
-	for _, tc := range replaceLiteralTests {
-		re, err := Compile(tc.pattern)
-		if err != nil {
-			t.Errorf("Unexpected error compiling %q: %v", tc.pattern, err)
-			continue
-		}
-		actual := re.ReplaceAllLiteralString(tc.input, tc.replacement)
-		if actual != tc.output {
-			t.Errorf("%q.ReplaceAllLiteralString(%q,%q) = %q; want %q",
-				tc.pattern, tc.input, tc.replacement, actual, tc.output)
-		}
-		// now try bytes
-		actual = string(re.ReplaceAllLiteral([]byte(tc.input), []byte(tc.replacement)))
-		if actual != tc.output {
-			t.Errorf("%q.ReplaceAllLiteral(%q,%q) = %q; want %q",
-				tc.pattern, tc.input, tc.replacement, actual, tc.output)
-		}
-	}
-}
-
-func TestReplaceAllFunc(t *testing.T) {
-	for _, tc := range replaceFuncTests {
-		re, err := Compile(tc.pattern)
-		if err != nil {
-			t.Errorf("Unexpected error compiling %q: %v", tc.pattern, err)
-			continue
-		}
-		actual := re.ReplaceAllStringFunc(tc.input, tc.replacement)
-		if actual != tc.output {
-			t.Errorf("%q.ReplaceFunc(%q,fn) = %q; want %q",
-				tc.pattern, tc.input, actual, tc.output)
-		}
-		// now try bytes
-		actual = string(re.ReplaceAllFunc([]byte(tc.input), func(s []byte) []byte { return []byte(tc.replacement(string(s))) }))
-		if actual != tc.output {
-			t.Errorf("%q.ReplaceFunc(%q,fn) = %q; want %q",
-				tc.pattern, tc.input, actual, tc.output)
-		}
-	}
-}
-
-type MetaTest struct {
-	pattern, output, literal string
-	isLiteral                bool
-}
-
-var metaTests = []MetaTest{
-	{``, ``, ``, true},
-	{`foo`, `foo`, `foo`, true},
-	{`foo\.\$`, `foo\\\.\\\$`, `foo.$`, true}, // has meta but no operator
-	{`foo.\$`, `foo\.\\\$`, `foo`, false},     // has escaped operators and real operators
-	{`!@#$%^&*()_+-=[{]}\|,<.>/?~`, `!@#\$%\^&\*\(\)_\+-=\[\{\]\}\\\|,<\.>/\?~`, `!@#`, false},
-}
-
-func TestQuoteMeta(t *testing.T) {
-	for _, tc := range metaTests {
-		// Verify that QuoteMeta returns the expected string.
-		quoted := QuoteMeta(tc.pattern)
-		if quoted != tc.output {
-			t.Errorf("QuoteMeta(`%s`) = `%s`; want `%s`",
-				tc.pattern, quoted, tc.output)
-			continue
-		}
-
-		// Verify that the quoted string is in fact treated as expected
-		// by Compile -- i.e. that it matches the original, unquoted string.
-		if tc.pattern != "" {
-			re, err := Compile(quoted)
-			if err != nil {
-				t.Errorf("Unexpected error compiling QuoteMeta(`%s`): %v", tc.pattern, err)
-				continue
-			}
-			src := "abc" + tc.pattern + "def"
-			repl := "xyz"
-			replaced := re.ReplaceAllString(src, repl)
-			expected := "abcxyzdef"
-			if replaced != expected {
-				t.Errorf("QuoteMeta(`%s`).Replace(`%s`,`%s`) = `%s`; want `%s`",
-					tc.pattern, src, repl, replaced, expected)
-			}
-		}
-	}
-}
-
-func TestLiteralPrefix(t *testing.T) {
-	for _, tc := range metaTests {
-		// Literal method needs to scan the pattern.
-		re := MustCompile(tc.pattern)
-		str, complete := re.LiteralPrefix()
-		if complete != tc.isLiteral {
-			t.Errorf("LiteralPrefix(`%s`) = %t; want %t", tc.pattern, complete, tc.isLiteral)
-		}
-		if str != tc.literal {
-			t.Errorf("LiteralPrefix(`%s`) = `%s`; want `%s`", tc.pattern, str, tc.literal)
-		}
-	}
-}
-
-type subexpCase struct {
-	input string
-	num   int
-	names []string
-}
-
-var subexpCases = []subexpCase{
-	{``, 0, nil},
-	{`.*`, 0, nil},
-	{`abba`, 0, nil},
-	{`ab(b)a`, 1, []string{"", ""}},
-	{`ab(.*)a`, 1, []string{"", ""}},
-	{`(.*)ab(.*)a`, 2, []string{"", "", ""}},
-	{`(.*)(ab)(.*)a`, 3, []string{"", "", "", ""}},
-	{`(.*)((a)b)(.*)a`, 4, []string{"", "", "", "", ""}},
-	{`(.*)(\(ab)(.*)a`, 3, []string{"", "", "", ""}},
-	{`(.*)(\(a\)b)(.*)a`, 3, []string{"", "", "", ""}},
-	{`(?P<foo>.*)(?P<bar>(a)b)(?P<foo>.*)a`, 4, []string{"", "foo", "bar", "", "foo"}},
-}
-
-func TestSubexp(t *testing.T) {
-	for _, c := range subexpCases {
-		re := MustCompile(c.input)
-		n := re.NumSubexp()
-		if n != c.num {
-			t.Errorf("%q: NumSubexp = %d, want %d", c.input, n, c.num)
-			continue
-		}
-		names := re.SubexpNames()
-		if len(names) != 1+n {
-			t.Errorf("%q: len(SubexpNames) = %d, want %d", c.input, len(names), n)
-			continue
-		}
-		if c.names != nil {
-			for i := 0; i < 1+n; i++ {
-				if names[i] != c.names[i] {
-					t.Errorf("%q: SubexpNames[%d] = %q, want %q", c.input, i, names[i], c.names[i])
-				}
-			}
-		}
-	}
-}
-
-var splitTests = []struct {
-	s   string
-	r   string
-	n   int
-	out []string
-}{
-	{"foo:and:bar", ":", -1, []string{"foo", "and", "bar"}},
-	{"foo:and:bar", ":", 1, []string{"foo:and:bar"}},
-	{"foo:and:bar", ":", 2, []string{"foo", "and:bar"}},
-	{"foo:and:bar", "foo", -1, []string{"", ":and:bar"}},
-	{"foo:and:bar", "bar", -1, []string{"foo:and:", ""}},
-	{"foo:and:bar", "baz", -1, []string{"foo:and:bar"}},
-	{"baabaab", "a", -1, []string{"b", "", "b", "", "b"}},
-	{"baabaab", "a*", -1, []string{"b", "b", "b"}},
-	{"baabaab", "ba*", -1, []string{"", "", "", ""}},
-	{"foobar", "f*b*", -1, []string{"", "o", "o", "a", "r"}},
-	{"foobar", "f+.*b+", -1, []string{"", "ar"}},
-	{"foobooboar", "o{2}", -1, []string{"f", "b", "boar"}},
-	{"a,b,c,d,e,f", ",", 3, []string{"a", "b", "c,d,e,f"}},
-	{"a,b,c,d,e,f", ",", 0, nil},
-	{",", ",", -1, []string{"", ""}},
-	{",,,", ",", -1, []string{"", "", "", ""}},
-	{"", ",", -1, []string{""}},
-	{"", ".*", -1, []string{""}},
-	{"", ".+", -1, []string{""}},
-	{"", "", -1, []string{}},
-	{"foobar", "", -1, []string{"f", "o", "o", "b", "a", "r"}},
-	{"abaabaccadaaae", "a*", 5, []string{"", "b", "b", "c", "cadaaae"}},
-	{":x:y:z:", ":", -1, []string{"", "x", "y", "z", ""}},
-}
-
-func TestSplit(t *testing.T) {
-	for i, test := range splitTests {
-		re, err := Compile(test.r)
-		if err != nil {
-			t.Errorf("#%d: %q: compile error: %s", i, test.r, err.Error())
-			continue
-		}
-
-		split := re.Split(test.s, test.n)
-		if !reflect.DeepEqual(split, test.out) {
-			t.Errorf("#%d: %q: got %q; want %q", i, test.r, split, test.out)
-		}
-
-		if QuoteMeta(test.r) == test.r {
-			strsplit := strings.SplitN(test.s, test.r, test.n)
-			if !reflect.DeepEqual(split, strsplit) {
-				t.Errorf("#%d: Split(%q, %q, %d): regexp vs strings mismatch\nregexp=%q\nstrings=%q", i, test.s, test.r, test.n, split, strsplit)
-			}
-		}
-	}
-}
-
-// This ran out of stack before issue 7608 was fixed.
-func TestOnePassCutoff(t *testing.T) {
-	MustCompile(`^(?:x{1,1000}){1,1000}$`)
-}
-
-func BenchmarkLiteral(b *testing.B) {
-	x := strings.Repeat("x", 50) + "y"
-	b.StopTimer()
-	re := MustCompile("y")
-	b.StartTimer()
-	for i := 0; i < b.N; i++ {
-		if !re.MatchString(x) {
-			b.Fatalf("no match!")
-		}
-	}
-}
-
-func BenchmarkNotLiteral(b *testing.B) {
-	x := strings.Repeat("x", 50) + "y"
-	b.StopTimer()
-	re := MustCompile(".y")
-	b.StartTimer()
-	for i := 0; i < b.N; i++ {
-		if !re.MatchString(x) {
-			b.Fatalf("no match!")
-		}
-	}
-}
-
-func BenchmarkMatchClass(b *testing.B) {
-	b.StopTimer()
-	x := strings.Repeat("xxxx", 20) + "w"
-	re := MustCompile("[abcdw]")
-	b.StartTimer()
-	for i := 0; i < b.N; i++ {
-		if !re.MatchString(x) {
-			b.Fatalf("no match!")
-		}
-	}
-}
-
-func BenchmarkMatchClass_InRange(b *testing.B) {
-	b.StopTimer()
-	// 'b' is between 'a' and 'c', so the charclass
-	// range checking is no help here.
-	x := strings.Repeat("bbbb", 20) + "c"
-	re := MustCompile("[ac]")
-	b.StartTimer()
-	for i := 0; i < b.N; i++ {
-		if !re.MatchString(x) {
-			b.Fatalf("no match!")
-		}
-	}
-}
-
-func BenchmarkReplaceAll(b *testing.B) {
-	x := "abcdefghijklmnopqrstuvwxyz"
-	b.StopTimer()
-	re := MustCompile("[cjrw]")
-	b.StartTimer()
-	for i := 0; i < b.N; i++ {
-		re.ReplaceAllString(x, "")
-	}
-}
-
-func BenchmarkAnchoredLiteralShortNonMatch(b *testing.B) {
-	b.StopTimer()
-	x := []byte("abcdefghijklmnopqrstuvwxyz")
-	re := MustCompile("^zbc(d|e)")
-	b.StartTimer()
-	for i := 0; i < b.N; i++ {
-		re.Match(x)
-	}
-}
-
-func BenchmarkAnchoredLiteralLongNonMatch(b *testing.B) {
-	b.StopTimer()
-	x := []byte("abcdefghijklmnopqrstuvwxyz")
-	for i := 0; i < 15; i++ {
-		x = append(x, x...)
-	}
-	re := MustCompile("^zbc(d|e)")
-	b.StartTimer()
-	for i := 0; i < b.N; i++ {
-		re.Match(x)
-	}
-}
-
-func BenchmarkAnchoredShortMatch(b *testing.B) {
-	b.StopTimer()
-	x := []byte("abcdefghijklmnopqrstuvwxyz")
-	re := MustCompile("^.bc(d|e)")
-	b.StartTimer()
-	for i := 0; i < b.N; i++ {
-		re.Match(x)
-	}
-}
-
-func BenchmarkAnchoredLongMatch(b *testing.B) {
-	b.StopTimer()
-	x := []byte("abcdefghijklmnopqrstuvwxyz")
-	for i := 0; i < 15; i++ {
-		x = append(x, x...)
-	}
-	re := MustCompile("^.bc(d|e)")
-	b.StartTimer()
-	for i := 0; i < b.N; i++ {
-		re.Match(x)
-	}
-}
-
-func BenchmarkOnePassShortA(b *testing.B) {
-	b.StopTimer()
-	x := []byte("abcddddddeeeededd")
-	re := MustCompile("^.bc(d|e)*$")
-	b.StartTimer()
-	for i := 0; i < b.N; i++ {
-		re.Match(x)
-	}
-}
-
-func BenchmarkNotOnePassShortA(b *testing.B) {
-	b.StopTimer()
-	x := []byte("abcddddddeeeededd")
-	re := MustCompile(".bc(d|e)*$")
-	b.StartTimer()
-	for i := 0; i < b.N; i++ {
-		re.Match(x)
-	}
-}
-
-func BenchmarkOnePassShortB(b *testing.B) {
-	b.StopTimer()
-	x := []byte("abcddddddeeeededd")
-	re := MustCompile("^.bc(?:d|e)*$")
-	b.StartTimer()
-	for i := 0; i < b.N; i++ {
-		re.Match(x)
-	}
-}
-
-func BenchmarkNotOnePassShortB(b *testing.B) {
-	b.StopTimer()
-	x := []byte("abcddddddeeeededd")
-	re := MustCompile(".bc(?:d|e)*$")
-	b.StartTimer()
-	for i := 0; i < b.N; i++ {
-		re.Match(x)
-	}
-}
-
-func BenchmarkOnePassLongPrefix(b *testing.B) {
-	b.StopTimer()
-	x := []byte("abcdefghijklmnopqrstuvwxyz")
-	re := MustCompile("^abcdefghijklmnopqrstuvwxyz.*$")
-	b.StartTimer()
-	for i := 0; i < b.N; i++ {
-		re.Match(x)
-	}
-}
-
-func BenchmarkOnePassLongNotPrefix(b *testing.B) {
-	b.StopTimer()
-	x := []byte("abcdefghijklmnopqrstuvwxyz")
-	re := MustCompile("^.bcdefghijklmnopqrstuvwxyz.*$")
-	b.StartTimer()
-	for i := 0; i < b.N; i++ {
-		re.Match(x)
-	}
-}
diff --git a/src/pkg/regexp/onepass.go b/src/pkg/regexp/onepass.go
deleted file mode 100644
index 501fb28..0000000
--- a/src/pkg/regexp/onepass.go
+++ /dev/null
@@ -1,582 +0,0 @@
-// Copyright 2014 The Go Authors.  All rights reserved.
-
-package regexp
-
-import (
-	"bytes"
-	"regexp/syntax"
-	"sort"
-	"unicode"
-)
-
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// "One-pass" regexp execution.
-// Some regexps can be analyzed to determine that they never need
-// backtracking: they are guaranteed to run in one pass over the string
-// without bothering to save all the usual NFA state.
-// Detect those and execute them more quickly.
-
-// A onePassProg is a compiled one-pass regular expression program.
-// It is the same as syntax.Prog except for the use of onePassInst.
-type onePassProg struct {
-	Inst   []onePassInst
-	Start  int // index of start instruction
-	NumCap int // number of InstCapture insts in re
-}
-
-// A onePassInst is a single instruction in a one-pass regular expression program.
-// It is the same as syntax.Inst except for the new 'Next' field.
-type onePassInst struct {
-	syntax.Inst
-	Next []uint32
-}
-
-// OnePassPrefix returns a literal string that all matches for the
-// regexp must start with.  Complete is true if the prefix
-// is the entire match. Pc is the index of the last rune instruction
-// in the string. The OnePassPrefix skips over the mandatory
-// EmptyBeginText
-func onePassPrefix(p *syntax.Prog) (prefix string, complete bool, pc uint32) {
-	i := &p.Inst[p.Start]
-	if i.Op != syntax.InstEmptyWidth || (syntax.EmptyOp(i.Arg))&syntax.EmptyBeginText == 0 {
-		return "", i.Op == syntax.InstMatch, uint32(p.Start)
-	}
-	pc = i.Out
-	i = &p.Inst[pc]
-	for i.Op == syntax.InstNop {
-		pc = i.Out
-		i = &p.Inst[pc]
-	}
-	// Avoid allocation of buffer if prefix is empty.
-	if iop(i) != syntax.InstRune || len(i.Rune) != 1 {
-		return "", i.Op == syntax.InstMatch, uint32(p.Start)
-	}
-
-	// Have prefix; gather characters.
-	var buf bytes.Buffer
-	for iop(i) == syntax.InstRune && len(i.Rune) == 1 && syntax.Flags(i.Arg)&syntax.FoldCase == 0 {
-		buf.WriteRune(i.Rune[0])
-		pc, i = i.Out, &p.Inst[i.Out]
-	}
-	return buf.String(), i.Op == syntax.InstEmptyWidth && (syntax.EmptyOp(i.Arg))&syntax.EmptyBeginText != 0, pc
-}
-
-// OnePassNext selects the next actionable state of the prog, based on the input character.
-// It should only be called when i.Op == InstAlt or InstAltMatch, and from the one-pass machine.
-// One of the alternates may ultimately lead without input to end of line. If the instruction
-// is InstAltMatch the path to the InstMatch is in i.Out, the normal node in i.Next.
-func onePassNext(i *onePassInst, r rune) uint32 {
-	next := i.MatchRunePos(r)
-	if next >= 0 {
-		return i.Next[next]
-	}
-	if i.Op == syntax.InstAltMatch {
-		return i.Out
-	}
-	return 0
-}
-
-func iop(i *syntax.Inst) syntax.InstOp {
-	op := i.Op
-	switch op {
-	case syntax.InstRune1, syntax.InstRuneAny, syntax.InstRuneAnyNotNL:
-		op = syntax.InstRune
-	}
-	return op
-}
-
-// Sparse Array implementation is used as a queueOnePass.
-type queueOnePass struct {
-	sparse          []uint32
-	dense           []uint32
-	size, nextIndex uint32
-}
-
-func (q *queueOnePass) empty() bool {
-	return q.nextIndex >= q.size
-}
-
-func (q *queueOnePass) next() (n uint32) {
-	n = q.dense[q.nextIndex]
-	q.nextIndex++
-	return
-}
-
-func (q *queueOnePass) clear() {
-	q.size = 0
-	q.nextIndex = 0
-}
-
-func (q *queueOnePass) reset() {
-	q.nextIndex = 0
-}
-
-func (q *queueOnePass) contains(u uint32) bool {
-	if u >= uint32(len(q.sparse)) {
-		return false
-	}
-	return q.sparse[u] < q.size && q.dense[q.sparse[u]] == u
-}
-
-func (q *queueOnePass) insert(u uint32) {
-	if !q.contains(u) {
-		q.insertNew(u)
-	}
-}
-
-func (q *queueOnePass) insertNew(u uint32) {
-	if u >= uint32(len(q.sparse)) {
-		return
-	}
-	q.sparse[u] = q.size
-	q.dense[q.size] = u
-	q.size++
-}
-
-func newQueue(size int) (q *queueOnePass) {
-	return &queueOnePass{
-		sparse: make([]uint32, size),
-		dense:  make([]uint32, size),
-	}
-}
-
-// mergeRuneSets merges two non-intersecting runesets, and returns the merged result,
-// and a NextIp array. The idea is that if a rune matches the OnePassRunes at index
-// i, NextIp[i/2] is the target. If the input sets intersect, an empty runeset and a
-// NextIp array with the single element mergeFailed is returned.
-// The code assumes that both inputs contain ordered and non-intersecting rune pairs.
-const mergeFailed = uint32(0xffffffff)
-
-var (
-	noRune = []rune{}
-	noNext = []uint32{mergeFailed}
-)
-
-func mergeRuneSets(leftRunes, rightRunes *[]rune, leftPC, rightPC uint32) ([]rune, []uint32) {
-	leftLen := len(*leftRunes)
-	rightLen := len(*rightRunes)
-	if leftLen&0x1 != 0 || rightLen&0x1 != 0 {
-		panic("mergeRuneSets odd length []rune")
-	}
-	var (
-		lx, rx int
-	)
-	merged := make([]rune, 0)
-	next := make([]uint32, 0)
-	ok := true
-	defer func() {
-		if !ok {
-			merged = nil
-			next = nil
-		}
-	}()
-
-	ix := -1
-	extend := func(newLow *int, newArray *[]rune, pc uint32) bool {
-		if ix > 0 && (*newArray)[*newLow] <= merged[ix] {
-			return false
-		}
-		merged = append(merged, (*newArray)[*newLow], (*newArray)[*newLow+1])
-		*newLow += 2
-		ix += 2
-		next = append(next, pc)
-		return true
-	}
-
-	for lx < leftLen || rx < rightLen {
-		switch {
-		case rx >= rightLen:
-			ok = extend(&lx, leftRunes, leftPC)
-		case lx >= leftLen:
-			ok = extend(&rx, rightRunes, rightPC)
-		case (*rightRunes)[rx] < (*leftRunes)[lx]:
-			ok = extend(&rx, rightRunes, rightPC)
-		default:
-			ok = extend(&lx, leftRunes, leftPC)
-		}
-		if !ok {
-			return noRune, noNext
-		}
-	}
-	return merged, next
-}
-
-// cleanupOnePass drops working memory, and restores certain shortcut instructions.
-func cleanupOnePass(prog *onePassProg, original *syntax.Prog) {
-	for ix, instOriginal := range original.Inst {
-		switch instOriginal.Op {
-		case syntax.InstAlt, syntax.InstAltMatch, syntax.InstRune:
-		case syntax.InstCapture, syntax.InstEmptyWidth, syntax.InstNop, syntax.InstMatch, syntax.InstFail:
-			prog.Inst[ix].Next = nil
-		case syntax.InstRune1, syntax.InstRuneAny, syntax.InstRuneAnyNotNL:
-			prog.Inst[ix].Next = nil
-			prog.Inst[ix] = onePassInst{Inst: instOriginal}
-		}
-	}
-}
-
-// onePassCopy creates a copy of the original Prog, as we'll be modifying it
-func onePassCopy(prog *syntax.Prog) *onePassProg {
-	p := &onePassProg{
-		Start:  prog.Start,
-		NumCap: prog.NumCap,
-	}
-	for _, inst := range prog.Inst {
-		p.Inst = append(p.Inst, onePassInst{Inst: inst})
-	}
-
-	// rewrites one or more common Prog constructs that enable some otherwise
-	// non-onepass Progs to be onepass. A:BD (for example) means an InstAlt at
-	// ip A, that points to ips B & C.
-	// A:BC + B:DA => A:BC + B:CD
-	// A:BC + B:DC => A:DC + B:DC
-	for pc := range p.Inst {
-		switch p.Inst[pc].Op {
-		default:
-			continue
-		case syntax.InstAlt, syntax.InstAltMatch:
-			// A:Bx + B:Ay
-			p_A_Other := &p.Inst[pc].Out
-			p_A_Alt := &p.Inst[pc].Arg
-			// make sure a target is another Alt
-			instAlt := p.Inst[*p_A_Alt]
-			if !(instAlt.Op == syntax.InstAlt || instAlt.Op == syntax.InstAltMatch) {
-				p_A_Alt, p_A_Other = p_A_Other, p_A_Alt
-				instAlt = p.Inst[*p_A_Alt]
-				if !(instAlt.Op == syntax.InstAlt || instAlt.Op == syntax.InstAltMatch) {
-					continue
-				}
-			}
-			instOther := p.Inst[*p_A_Other]
-			// Analyzing both legs pointing to Alts is for another day
-			if instOther.Op == syntax.InstAlt || instOther.Op == syntax.InstAltMatch {
-				// too complicated
-				continue
-			}
-			// simple empty transition loop
-			// A:BC + B:DA => A:BC + B:DC
-			p_B_Alt := &p.Inst[*p_A_Alt].Out
-			p_B_Other := &p.Inst[*p_A_Alt].Arg
-			patch := false
-			if instAlt.Out == uint32(pc) {
-				patch = true
-			} else if instAlt.Arg == uint32(pc) {
-				patch = true
-				p_B_Alt, p_B_Other = p_B_Other, p_B_Alt
-			}
-			if patch {
-				*p_B_Alt = *p_A_Other
-			}
-
-			// empty transition to common target
-			// A:BC + B:DC => A:DC + B:DC
-			if *p_A_Other == *p_B_Alt {
-				*p_A_Alt = *p_B_Other
-			}
-		}
-	}
-	return p
-}
-
-// runeSlice exists to permit sorting the case-folded rune sets.
-type runeSlice []rune
-
-func (p runeSlice) Len() int           { return len(p) }
-func (p runeSlice) Less(i, j int) bool { return p[i] < p[j] }
-func (p runeSlice) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
-
-// Sort is a convenience method.
-func (p runeSlice) Sort() {
-	sort.Sort(p)
-}
-
-var anyRuneNotNL = []rune{0, '\n' - 1, '\n' + 1, unicode.MaxRune}
-var anyRune = []rune{0, unicode.MaxRune}
-
-// makeOnePass creates a onepass Prog, if possible. It is possible if at any alt,
-// the match engine can always tell which branch to take. The routine may modify
-// p if it is turned into a onepass Prog. If it isn't possible for this to be a
-// onepass Prog, the Prog notOnePass is returned. makeOnePass is recursive
-// to the size of the Prog.
-func makeOnePass(p *onePassProg) *onePassProg {
-	// If the machine is very long, it's not worth the time to check if we can use one pass.
-	if len(p.Inst) >= 1000 {
-		return notOnePass
-	}
-
-	var (
-		instQueue    = newQueue(len(p.Inst))
-		visitQueue   = newQueue(len(p.Inst))
-		build        func(uint32, *queueOnePass)
-		check        func(uint32, map[uint32]bool) bool
-		onePassRunes = make([][]rune, len(p.Inst))
-	)
-	build = func(pc uint32, q *queueOnePass) {
-		if q.contains(pc) {
-			return
-		}
-		inst := p.Inst[pc]
-		switch inst.Op {
-		case syntax.InstAlt, syntax.InstAltMatch:
-			q.insert(inst.Out)
-			build(inst.Out, q)
-			q.insert(inst.Arg)
-		case syntax.InstMatch, syntax.InstFail:
-		default:
-			q.insert(inst.Out)
-		}
-	}
-
-	// check that paths from Alt instructions are unambiguous, and rebuild the new
-	// program as a onepass program
-	check = func(pc uint32, m map[uint32]bool) (ok bool) {
-		ok = true
-		inst := &p.Inst[pc]
-		if visitQueue.contains(pc) {
-			return
-		}
-		visitQueue.insert(pc)
-		switch inst.Op {
-		case syntax.InstAlt, syntax.InstAltMatch:
-			ok = check(inst.Out, m) && check(inst.Arg, m)
-			// check no-input paths to InstMatch
-			matchOut := m[inst.Out]
-			matchArg := m[inst.Arg]
-			if matchOut && matchArg {
-				ok = false
-				break
-			}
-			// Match on empty goes in inst.Out
-			if matchArg {
-				inst.Out, inst.Arg = inst.Arg, inst.Out
-				matchOut, matchArg = matchArg, matchOut
-			}
-			if matchOut {
-				m[pc] = true
-				inst.Op = syntax.InstAltMatch
-			}
-
-			// build a dispatch operator from the two legs of the alt.
-			onePassRunes[pc], inst.Next = mergeRuneSets(
-				&onePassRunes[inst.Out], &onePassRunes[inst.Arg], inst.Out, inst.Arg)
-			if len(inst.Next) > 0 && inst.Next[0] == mergeFailed {
-				ok = false
-				break
-			}
-		case syntax.InstCapture, syntax.InstNop:
-			ok = check(inst.Out, m)
-			m[pc] = m[inst.Out]
-			// pass matching runes back through these no-ops.
-			onePassRunes[pc] = append([]rune{}, onePassRunes[inst.Out]...)
-			inst.Next = []uint32{}
-			for i := len(onePassRunes[pc]) / 2; i >= 0; i-- {
-				inst.Next = append(inst.Next, inst.Out)
-			}
-		case syntax.InstEmptyWidth:
-			ok = check(inst.Out, m)
-			m[pc] = m[inst.Out]
-			onePassRunes[pc] = append([]rune{}, onePassRunes[inst.Out]...)
-			inst.Next = []uint32{}
-			for i := len(onePassRunes[pc]) / 2; i >= 0; i-- {
-				inst.Next = append(inst.Next, inst.Out)
-			}
-		case syntax.InstMatch, syntax.InstFail:
-			m[pc] = inst.Op == syntax.InstMatch
-			break
-		case syntax.InstRune:
-			ok = check(inst.Out, m)
-			m[pc] = false
-			if len(inst.Next) > 0 {
-				break
-			}
-			if len(inst.Rune) == 0 {
-				onePassRunes[pc] = []rune{}
-				inst.Next = []uint32{inst.Out}
-				break
-			}
-			runes := make([]rune, 0)
-			if len(inst.Rune) == 1 && syntax.Flags(inst.Arg)&syntax.FoldCase != 0 {
-				r0 := inst.Rune[0]
-				runes = append(runes, r0, r0)
-				for r1 := unicode.SimpleFold(r0); r1 != r0; r1 = unicode.SimpleFold(r1) {
-					runes = append(runes, r1, r1)
-				}
-				sort.Sort(runeSlice(runes))
-			} else {
-				runes = append(runes, inst.Rune...)
-			}
-			onePassRunes[pc] = runes
-			inst.Next = []uint32{}
-			for i := len(onePassRunes[pc]) / 2; i >= 0; i-- {
-				inst.Next = append(inst.Next, inst.Out)
-			}
-			inst.Op = syntax.InstRune
-		case syntax.InstRune1:
-			ok = check(inst.Out, m)
-			m[pc] = false
-			if len(inst.Next) > 0 {
-				break
-			}
-			runes := []rune{}
-			// expand case-folded runes
-			if syntax.Flags(inst.Arg)&syntax.FoldCase != 0 {
-				r0 := inst.Rune[0]
-				runes = append(runes, r0, r0)
-				for r1 := unicode.SimpleFold(r0); r1 != r0; r1 = unicode.SimpleFold(r1) {
-					runes = append(runes, r1, r1)
-				}
-				sort.Sort(runeSlice(runes))
-			} else {
-				runes = append(runes, inst.Rune[0], inst.Rune[0])
-			}
-			onePassRunes[pc] = runes
-			inst.Next = []uint32{}
-			for i := len(onePassRunes[pc]) / 2; i >= 0; i-- {
-				inst.Next = append(inst.Next, inst.Out)
-			}
-			inst.Op = syntax.InstRune
-		case syntax.InstRuneAny:
-			ok = check(inst.Out, m)
-			m[pc] = false
-			if len(inst.Next) > 0 {
-				break
-			}
-			onePassRunes[pc] = append([]rune{}, anyRune...)
-			inst.Next = []uint32{inst.Out}
-		case syntax.InstRuneAnyNotNL:
-			ok = check(inst.Out, m)
-			m[pc] = false
-			if len(inst.Next) > 0 {
-				break
-			}
-			onePassRunes[pc] = append([]rune{}, anyRuneNotNL...)
-			inst.Next = []uint32{}
-			for i := len(onePassRunes[pc]) / 2; i >= 0; i-- {
-				inst.Next = append(inst.Next, inst.Out)
-			}
-		}
-		return
-	}
-
-	instQueue.clear()
-	instQueue.insert(uint32(p.Start))
-	m := make(map[uint32]bool, len(p.Inst))
-	for !instQueue.empty() {
-		pc := instQueue.next()
-		inst := p.Inst[pc]
-		visitQueue.clear()
-		if !check(uint32(pc), m) {
-			p = notOnePass
-			break
-		}
-		switch inst.Op {
-		case syntax.InstAlt, syntax.InstAltMatch:
-			instQueue.insert(inst.Out)
-			instQueue.insert(inst.Arg)
-		case syntax.InstCapture, syntax.InstEmptyWidth, syntax.InstNop:
-			instQueue.insert(inst.Out)
-		case syntax.InstMatch:
-		case syntax.InstFail:
-		case syntax.InstRune, syntax.InstRune1, syntax.InstRuneAny, syntax.InstRuneAnyNotNL:
-		default:
-		}
-	}
-	if p != notOnePass {
-		for i, _ := range p.Inst {
-			p.Inst[i].Rune = onePassRunes[i]
-		}
-	}
-	return p
-}
-
-// walk visits each Inst in the prog once, and applies the argument
-// function(ip, next), in pre-order.
-func walk(prog *syntax.Prog, funcs ...func(ip, next uint32)) {
-	var walk1 func(uint32)
-	progQueue := newQueue(len(prog.Inst))
-	walk1 = func(ip uint32) {
-		if progQueue.contains(ip) {
-			return
-		}
-		progQueue.insert(ip)
-		inst := prog.Inst[ip]
-		switch inst.Op {
-		case syntax.InstAlt, syntax.InstAltMatch:
-			for _, f := range funcs {
-				f(ip, inst.Out)
-				f(ip, inst.Arg)
-			}
-			walk1(inst.Out)
-			walk1(inst.Arg)
-		default:
-			for _, f := range funcs {
-				f(ip, inst.Out)
-			}
-			walk1(inst.Out)
-		}
-	}
-	walk1(uint32(prog.Start))
-}
-
-// find returns the Insts that match the argument predicate function
-func find(prog *syntax.Prog, f func(*syntax.Prog, int) bool) (matches []uint32) {
-	matches = []uint32{}
-
-	for ip := range prog.Inst {
-		if f(prog, ip) {
-			matches = append(matches, uint32(ip))
-		}
-	}
-	return
-}
-
-var notOnePass *onePassProg = nil
-
-// compileOnePass returns a new *syntax.Prog suitable for onePass execution if the original Prog
-// can be recharacterized as a one-pass regexp program, or syntax.notOnePass if the
-// Prog cannot be converted. For a one pass prog, the fundamental condition that must
-// be true is: at any InstAlt, there must be no ambiguity about what branch to  take.
-func compileOnePass(prog *syntax.Prog) (p *onePassProg) {
-	if prog.Start == 0 {
-		return notOnePass
-	}
-	// onepass regexp is anchored
-	if prog.Inst[prog.Start].Op != syntax.InstEmptyWidth ||
-		syntax.EmptyOp(prog.Inst[prog.Start].Arg)&syntax.EmptyBeginText != syntax.EmptyBeginText {
-		return notOnePass
-	}
-	// every instruction leading to InstMatch must be EmptyEndText
-	for _, inst := range prog.Inst {
-		opOut := prog.Inst[inst.Out].Op
-		switch inst.Op {
-		default:
-			if opOut == syntax.InstMatch {
-				return notOnePass
-			}
-		case syntax.InstAlt, syntax.InstAltMatch:
-			if opOut == syntax.InstMatch || prog.Inst[inst.Arg].Op == syntax.InstMatch {
-				return notOnePass
-			}
-		case syntax.InstEmptyWidth:
-			if opOut == syntax.InstMatch {
-				if syntax.EmptyOp(inst.Arg)&syntax.EmptyEndText == syntax.EmptyEndText {
-					continue
-				}
-				return notOnePass
-			}
-		}
-	}
-	// Creates a slightly optimized copy of the original Prog
-	// that cleans up some Prog idioms that block valid onepass programs
-	p = onePassCopy(prog)
-
-	// checkAmbiguity on InstAlts, build onepass Prog if possible
-	p = makeOnePass(p)
-
-	if p != notOnePass {
-		cleanupOnePass(p, prog)
-	}
-	return p
-}
diff --git a/src/pkg/regexp/regexp.go b/src/pkg/regexp/regexp.go
deleted file mode 100644
index 0b8336a..0000000
--- a/src/pkg/regexp/regexp.go
+++ /dev/null
@@ -1,1120 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package regexp implements regular expression search.
-//
-// The syntax of the regular expressions accepted is the same
-// general syntax used by Perl, Python, and other languages.
-// More precisely, it is the syntax accepted by RE2 and described at
-// http://code.google.com/p/re2/wiki/Syntax, except for \C.
-// For an overview of the syntax, run
-//   godoc regexp/syntax
-//
-// The regexp implementation provided by this package is
-// guaranteed to run in time linear in the size of the input.
-// (This is a property not guaranteed by most open source
-// implementations of regular expressions.) For more information
-// about this property, see
-//	http://swtch.com/~rsc/regexp/regexp1.html
-// or any book about automata theory.
-//
-// All characters are UTF-8-encoded code points.
-//
-// There are 16 methods of Regexp that match a regular expression and identify
-// the matched text.  Their names are matched by this regular expression:
-//
-//	Find(All)?(String)?(Submatch)?(Index)?
-//
-// If 'All' is present, the routine matches successive non-overlapping
-// matches of the entire expression.  Empty matches abutting a preceding
-// match are ignored.  The return value is a slice containing the successive
-// return values of the corresponding non-'All' routine.  These routines take
-// an extra integer argument, n; if n >= 0, the function returns at most n
-// matches/submatches.
-//
-// If 'String' is present, the argument is a string; otherwise it is a slice
-// of bytes; return values are adjusted as appropriate.
-//
-// If 'Submatch' is present, the return value is a slice identifying the
-// successive submatches of the expression. Submatches are matches of
-// parenthesized subexpressions (also known as capturing groups) within the
-// regular expression, numbered from left to right in order of opening
-// parenthesis. Submatch 0 is the match of the entire expression, submatch 1
-// the match of the first parenthesized subexpression, and so on.
-//
-// If 'Index' is present, matches and submatches are identified by byte index
-// pairs within the input string: result[2*n:2*n+1] identifies the indexes of
-// the nth submatch.  The pair for n==0 identifies the match of the entire
-// expression.  If 'Index' is not present, the match is identified by the
-// text of the match/submatch.  If an index is negative, it means that
-// subexpression did not match any string in the input.
-//
-// There is also a subset of the methods that can be applied to text read
-// from a RuneReader:
-//
-//	MatchReader, FindReaderIndex, FindReaderSubmatchIndex
-//
-// This set may grow.  Note that regular expression matches may need to
-// examine text beyond the text returned by a match, so the methods that
-// match text from a RuneReader may read arbitrarily far into the input
-// before returning.
-//
-// (There are a few other methods that do not match this pattern.)
-//
-package regexp
-
-import (
-	"bytes"
-	"io"
-	"regexp/syntax"
-	"strconv"
-	"strings"
-	"sync"
-	"unicode"
-	"unicode/utf8"
-)
-
-var debug = false
-
-// Regexp is the representation of a compiled regular expression.
-// A Regexp is safe for concurrent use by multiple goroutines.
-type Regexp struct {
-	// read-only after Compile
-	expr           string         // as passed to Compile
-	prog           *syntax.Prog   // compiled program
-	onepass        *onePassProg   // onpass program or nil
-	prefix         string         // required prefix in unanchored matches
-	prefixBytes    []byte         // prefix, as a []byte
-	prefixComplete bool           // prefix is the entire regexp
-	prefixRune     rune           // first rune in prefix
-	prefixEnd      uint32         // pc for last rune in prefix
-	cond           syntax.EmptyOp // empty-width conditions required at start of match
-	numSubexp      int
-	subexpNames    []string
-	longest        bool
-
-	// cache of machines for running regexp
-	mu      sync.Mutex
-	machine []*machine
-}
-
-// String returns the source text used to compile the regular expression.
-func (re *Regexp) String() string {
-	return re.expr
-}
-
-// Compile parses a regular expression and returns, if successful,
-// a Regexp object that can be used to match against text.
-//
-// When matching against text, the regexp returns a match that
-// begins as early as possible in the input (leftmost), and among those
-// it chooses the one that a backtracking search would have found first.
-// This so-called leftmost-first matching is the same semantics
-// that Perl, Python, and other implementations use, although this
-// package implements it without the expense of backtracking.
-// For POSIX leftmost-longest matching, see CompilePOSIX.
-func Compile(expr string) (*Regexp, error) {
-	return compile(expr, syntax.Perl, false)
-}
-
-// CompilePOSIX is like Compile but restricts the regular expression
-// to POSIX ERE (egrep) syntax and changes the match semantics to
-// leftmost-longest.
-//
-// That is, when matching against text, the regexp returns a match that
-// begins as early as possible in the input (leftmost), and among those
-// it chooses a match that is as long as possible.
-// This so-called leftmost-longest matching is the same semantics
-// that early regular expression implementations used and that POSIX
-// specifies.
-//
-// However, there can be multiple leftmost-longest matches, with different
-// submatch choices, and here this package diverges from POSIX.
-// Among the possible leftmost-longest matches, this package chooses
-// the one that a backtracking search would have found first, while POSIX
-// specifies that the match be chosen to maximize the length of the first
-// subexpression, then the second, and so on from left to right.
-// The POSIX rule is computationally prohibitive and not even well-defined.
-// See http://swtch.com/~rsc/regexp/regexp2.html#posix for details.
-func CompilePOSIX(expr string) (*Regexp, error) {
-	return compile(expr, syntax.POSIX, true)
-}
-
-// Longest makes future searches prefer the leftmost-longest match.
-// That is, when matching against text, the regexp returns a match that
-// begins as early as possible in the input (leftmost), and among those
-// it chooses a match that is as long as possible.
-func (re *Regexp) Longest() {
-	re.longest = true
-}
-
-func compile(expr string, mode syntax.Flags, longest bool) (*Regexp, error) {
-	re, err := syntax.Parse(expr, mode)
-	if err != nil {
-		return nil, err
-	}
-	maxCap := re.MaxCap()
-	capNames := re.CapNames()
-
-	re = re.Simplify()
-	prog, err := syntax.Compile(re)
-	if err != nil {
-		return nil, err
-	}
-	regexp := &Regexp{
-		expr:        expr,
-		prog:        prog,
-		onepass:     compileOnePass(prog),
-		numSubexp:   maxCap,
-		subexpNames: capNames,
-		cond:        prog.StartCond(),
-		longest:     longest,
-	}
-	if regexp.onepass == notOnePass {
-		regexp.prefix, regexp.prefixComplete = prog.Prefix()
-	} else {
-		regexp.prefix, regexp.prefixComplete, regexp.prefixEnd = onePassPrefix(prog)
-	}
-	if regexp.prefix != "" {
-		// TODO(rsc): Remove this allocation by adding
-		// IndexString to package bytes.
-		regexp.prefixBytes = []byte(regexp.prefix)
-		regexp.prefixRune, _ = utf8.DecodeRuneInString(regexp.prefix)
-	}
-	return regexp, nil
-}
-
-// get returns a machine to use for matching re.
-// It uses the re's machine cache if possible, to avoid
-// unnecessary allocation.
-func (re *Regexp) get() *machine {
-	re.mu.Lock()
-	if n := len(re.machine); n > 0 {
-		z := re.machine[n-1]
-		re.machine = re.machine[:n-1]
-		re.mu.Unlock()
-		return z
-	}
-	re.mu.Unlock()
-	z := progMachine(re.prog, re.onepass)
-	z.re = re
-	return z
-}
-
-// put returns a machine to the re's machine cache.
-// There is no attempt to limit the size of the cache, so it will
-// grow to the maximum number of simultaneous matches
-// run using re.  (The cache empties when re gets garbage collected.)
-func (re *Regexp) put(z *machine) {
-	re.mu.Lock()
-	re.machine = append(re.machine, z)
-	re.mu.Unlock()
-}
-
-// MustCompile is like Compile but panics if the expression cannot be parsed.
-// It simplifies safe initialization of global variables holding compiled regular
-// expressions.
-func MustCompile(str string) *Regexp {
-	regexp, error := Compile(str)
-	if error != nil {
-		panic(`regexp: Compile(` + quote(str) + `): ` + error.Error())
-	}
-	return regexp
-}
-
-// MustCompilePOSIX is like CompilePOSIX but panics if the expression cannot be parsed.
-// It simplifies safe initialization of global variables holding compiled regular
-// expressions.
-func MustCompilePOSIX(str string) *Regexp {
-	regexp, error := CompilePOSIX(str)
-	if error != nil {
-		panic(`regexp: CompilePOSIX(` + quote(str) + `): ` + error.Error())
-	}
-	return regexp
-}
-
-func quote(s string) string {
-	if strconv.CanBackquote(s) {
-		return "`" + s + "`"
-	}
-	return strconv.Quote(s)
-}
-
-// NumSubexp returns the number of parenthesized subexpressions in this Regexp.
-func (re *Regexp) NumSubexp() int {
-	return re.numSubexp
-}
-
-// SubexpNames returns the names of the parenthesized subexpressions
-// in this Regexp.  The name for the first sub-expression is names[1],
-// so that if m is a match slice, the name for m[i] is SubexpNames()[i].
-// Since the Regexp as a whole cannot be named, names[0] is always
-// the empty string.  The slice should not be modified.
-func (re *Regexp) SubexpNames() []string {
-	return re.subexpNames
-}
-
-const endOfText rune = -1
-
-// input abstracts different representations of the input text. It provides
-// one-character lookahead.
-type input interface {
-	step(pos int) (r rune, width int) // advance one rune
-	canCheckPrefix() bool             // can we look ahead without losing info?
-	hasPrefix(re *Regexp) bool
-	index(re *Regexp, pos int) int
-	context(pos int) syntax.EmptyOp
-}
-
-// inputString scans a string.
-type inputString struct {
-	str string
-}
-
-func (i *inputString) step(pos int) (rune, int) {
-	if pos < len(i.str) {
-		c := i.str[pos]
-		if c < utf8.RuneSelf {
-			return rune(c), 1
-		}
-		return utf8.DecodeRuneInString(i.str[pos:])
-	}
-	return endOfText, 0
-}
-
-func (i *inputString) canCheckPrefix() bool {
-	return true
-}
-
-func (i *inputString) hasPrefix(re *Regexp) bool {
-	return strings.HasPrefix(i.str, re.prefix)
-}
-
-func (i *inputString) index(re *Regexp, pos int) int {
-	return strings.Index(i.str[pos:], re.prefix)
-}
-
-func (i *inputString) context(pos int) syntax.EmptyOp {
-	r1, r2 := endOfText, endOfText
-	if pos > 0 && pos <= len(i.str) {
-		r1, _ = utf8.DecodeLastRuneInString(i.str[:pos])
-	}
-	if pos < len(i.str) {
-		r2, _ = utf8.DecodeRuneInString(i.str[pos:])
-	}
-	return syntax.EmptyOpContext(r1, r2)
-}
-
-// inputBytes scans a byte slice.
-type inputBytes struct {
-	str []byte
-}
-
-func (i *inputBytes) step(pos int) (rune, int) {
-	if pos < len(i.str) {
-		c := i.str[pos]
-		if c < utf8.RuneSelf {
-			return rune(c), 1
-		}
-		return utf8.DecodeRune(i.str[pos:])
-	}
-	return endOfText, 0
-}
-
-func (i *inputBytes) canCheckPrefix() bool {
-	return true
-}
-
-func (i *inputBytes) hasPrefix(re *Regexp) bool {
-	return bytes.HasPrefix(i.str, re.prefixBytes)
-}
-
-func (i *inputBytes) index(re *Regexp, pos int) int {
-	return bytes.Index(i.str[pos:], re.prefixBytes)
-}
-
-func (i *inputBytes) context(pos int) syntax.EmptyOp {
-	r1, r2 := endOfText, endOfText
-	if pos > 0 && pos <= len(i.str) {
-		r1, _ = utf8.DecodeLastRune(i.str[:pos])
-	}
-	if pos < len(i.str) {
-		r2, _ = utf8.DecodeRune(i.str[pos:])
-	}
-	return syntax.EmptyOpContext(r1, r2)
-}
-
-// inputReader scans a RuneReader.
-type inputReader struct {
-	r     io.RuneReader
-	atEOT bool
-	pos   int
-}
-
-func (i *inputReader) step(pos int) (rune, int) {
-	if !i.atEOT && pos != i.pos {
-		return endOfText, 0
-
-	}
-	r, w, err := i.r.ReadRune()
-	if err != nil {
-		i.atEOT = true
-		return endOfText, 0
-	}
-	i.pos += w
-	return r, w
-}
-
-func (i *inputReader) canCheckPrefix() bool {
-	return false
-}
-
-func (i *inputReader) hasPrefix(re *Regexp) bool {
-	return false
-}
-
-func (i *inputReader) index(re *Regexp, pos int) int {
-	return -1
-}
-
-func (i *inputReader) context(pos int) syntax.EmptyOp {
-	return 0
-}
-
-// LiteralPrefix returns a literal string that must begin any match
-// of the regular expression re.  It returns the boolean true if the
-// literal string comprises the entire regular expression.
-func (re *Regexp) LiteralPrefix() (prefix string, complete bool) {
-	return re.prefix, re.prefixComplete
-}
-
-// MatchReader reports whether the Regexp matches the text read by the
-// RuneReader.
-func (re *Regexp) MatchReader(r io.RuneReader) bool {
-	return re.doExecute(r, nil, "", 0, 0) != nil
-}
-
-// MatchString reports whether the Regexp matches the string s.
-func (re *Regexp) MatchString(s string) bool {
-	return re.doExecute(nil, nil, s, 0, 0) != nil
-}
-
-// Match reports whether the Regexp matches the byte slice b.
-func (re *Regexp) Match(b []byte) bool {
-	return re.doExecute(nil, b, "", 0, 0) != nil
-}
-
-// MatchReader checks whether a textual regular expression matches the text
-// read by the RuneReader.  More complicated queries need to use Compile and
-// the full Regexp interface.
-func MatchReader(pattern string, r io.RuneReader) (matched bool, err error) {
-	re, err := Compile(pattern)
-	if err != nil {
-		return false, err
-	}
-	return re.MatchReader(r), nil
-}
-
-// MatchString checks whether a textual regular expression
-// matches a string.  More complicated queries need
-// to use Compile and the full Regexp interface.
-func MatchString(pattern string, s string) (matched bool, err error) {
-	re, err := Compile(pattern)
-	if err != nil {
-		return false, err
-	}
-	return re.MatchString(s), nil
-}
-
-// Match checks whether a textual regular expression
-// matches a byte slice.  More complicated queries need
-// to use Compile and the full Regexp interface.
-func Match(pattern string, b []byte) (matched bool, err error) {
-	re, err := Compile(pattern)
-	if err != nil {
-		return false, err
-	}
-	return re.Match(b), nil
-}
-
-// ReplaceAllString returns a copy of src, replacing matches of the Regexp
-// with the replacement string repl.  Inside repl, $ signs are interpreted as
-// 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 {
-		n = 2 * (re.numSubexp + 1)
-	}
-	b := re.replaceAll(nil, src, n, func(dst []byte, match []int) []byte {
-		return re.expand(dst, repl, nil, src, match)
-	})
-	return string(b)
-}
-
-// ReplaceAllStringLiteral returns a copy of src, replacing matches of the Regexp
-// with the replacement string repl.  The replacement repl is substituted directly,
-// without using Expand.
-func (re *Regexp) ReplaceAllLiteralString(src, repl string) string {
-	return string(re.replaceAll(nil, src, 2, func(dst []byte, match []int) []byte {
-		return append(dst, repl...)
-	}))
-}
-
-// ReplaceAllStringFunc returns a copy of src in which all matches of the
-// Regexp have been replaced by the return value of function repl applied
-// to the matched substring.  The replacement returned by repl is substituted
-// directly, without using Expand.
-func (re *Regexp) ReplaceAllStringFunc(src string, repl func(string) string) string {
-	b := re.replaceAll(nil, src, 2, func(dst []byte, match []int) []byte {
-		return append(dst, repl(src[match[0]:match[1]])...)
-	})
-	return string(b)
-}
-
-func (re *Regexp) replaceAll(bsrc []byte, src string, nmatch int, repl func(dst []byte, m []int) []byte) []byte {
-	lastMatchEnd := 0 // end position of the most recent match
-	searchPos := 0    // position where we next look for a match
-	var buf []byte
-	var endPos int
-	if bsrc != nil {
-		endPos = len(bsrc)
-	} else {
-		endPos = len(src)
-	}
-	for searchPos <= endPos {
-		a := re.doExecute(nil, bsrc, src, searchPos, nmatch)
-		if len(a) == 0 {
-			break // no more matches
-		}
-
-		// Copy the unmatched characters before this match.
-		if bsrc != nil {
-			buf = append(buf, bsrc[lastMatchEnd:a[0]]...)
-		} else {
-			buf = append(buf, src[lastMatchEnd:a[0]]...)
-		}
-
-		// Now insert a copy of the replacement string, but not for a
-		// match of the empty string immediately after another match.
-		// (Otherwise, we get double replacement for patterns that
-		// match both empty and nonempty strings.)
-		if a[1] > lastMatchEnd || a[0] == 0 {
-			buf = repl(buf, a)
-		}
-		lastMatchEnd = a[1]
-
-		// Advance past this match; always advance at least one character.
-		var width int
-		if bsrc != nil {
-			_, width = utf8.DecodeRune(bsrc[searchPos:])
-		} else {
-			_, width = utf8.DecodeRuneInString(src[searchPos:])
-		}
-		if searchPos+width > a[1] {
-			searchPos += width
-		} else if searchPos+1 > a[1] {
-			// This clause is only needed at the end of the input
-			// string.  In that case, DecodeRuneInString returns width=0.
-			searchPos++
-		} else {
-			searchPos = a[1]
-		}
-	}
-
-	// Copy the unmatched characters after the last match.
-	if bsrc != nil {
-		buf = append(buf, bsrc[lastMatchEnd:]...)
-	} else {
-		buf = append(buf, src[lastMatchEnd:]...)
-	}
-
-	return buf
-}
-
-// ReplaceAll returns a copy of src, replacing matches of the Regexp
-// with the replacement text repl.  Inside repl, $ signs are interpreted as
-// in Expand, so for instance $1 represents the text of the first submatch.
-func (re *Regexp) ReplaceAll(src, repl []byte) []byte {
-	n := 2
-	if bytes.IndexByte(repl, '$') >= 0 {
-		n = 2 * (re.numSubexp + 1)
-	}
-	srepl := ""
-	b := re.replaceAll(src, "", n, func(dst []byte, match []int) []byte {
-		if len(srepl) != len(repl) {
-			srepl = string(repl)
-		}
-		return re.expand(dst, srepl, src, "", match)
-	})
-	return b
-}
-
-// ReplaceAllLiteral returns a copy of src, replacing matches of the Regexp
-// with the replacement bytes repl.  The replacement repl is substituted directly,
-// without using Expand.
-func (re *Regexp) ReplaceAllLiteral(src, repl []byte) []byte {
-	return re.replaceAll(src, "", 2, func(dst []byte, match []int) []byte {
-		return append(dst, repl...)
-	})
-}
-
-// ReplaceAllFunc returns a copy of src in which all matches of the
-// Regexp have been replaced by the return value of function repl applied
-// to the matched byte slice.  The replacement returned by repl is substituted
-// directly, without using Expand.
-func (re *Regexp) ReplaceAllFunc(src []byte, repl func([]byte) []byte) []byte {
-	return re.replaceAll(src, "", 2, func(dst []byte, match []int) []byte {
-		return append(dst, repl(src[match[0]:match[1]])...)
-	})
-}
-
-var specialBytes = []byte(`\.+*?()|[]{}^$`)
-
-func special(b byte) bool {
-	return bytes.IndexByte(specialBytes, b) >= 0
-}
-
-// QuoteMeta returns a string that quotes all regular expression metacharacters
-// inside the argument text; the returned string is a regular expression matching
-// the literal text.  For example, QuoteMeta(`[foo]`) returns `\[foo\]`.
-func QuoteMeta(s string) string {
-	b := make([]byte, 2*len(s))
-
-	// A byte loop is correct because all metacharacters are ASCII.
-	j := 0
-	for i := 0; i < len(s); i++ {
-		if special(s[i]) {
-			b[j] = '\\'
-			j++
-		}
-		b[j] = s[i]
-		j++
-	}
-	return string(b[0:j])
-}
-
-// The number of capture values in the program may correspond
-// to fewer capturing expressions than are in the regexp.
-// For example, "(a){0}" turns into an empty program, so the
-// maximum capture in the program is 0 but we need to return
-// an expression for \1.  Pad appends -1s to the slice a as needed.
-func (re *Regexp) pad(a []int) []int {
-	if a == nil {
-		// No match.
-		return nil
-	}
-	n := (1 + re.numSubexp) * 2
-	for len(a) < n {
-		a = append(a, -1)
-	}
-	return a
-}
-
-// Find matches in slice b if b is non-nil, otherwise find matches in string s.
-func (re *Regexp) allMatches(s string, b []byte, n int, deliver func([]int)) {
-	var end int
-	if b == nil {
-		end = len(s)
-	} else {
-		end = len(b)
-	}
-
-	for pos, i, prevMatchEnd := 0, 0, -1; i < n && pos <= end; {
-		matches := re.doExecute(nil, b, s, pos, re.prog.NumCap)
-		if len(matches) == 0 {
-			break
-		}
-
-		accept := true
-		if matches[1] == pos {
-			// We've found an empty match.
-			if matches[0] == prevMatchEnd {
-				// We don't allow an empty match right
-				// after a previous match, so ignore it.
-				accept = false
-			}
-			var width int
-			// TODO: use step()
-			if b == nil {
-				_, width = utf8.DecodeRuneInString(s[pos:end])
-			} else {
-				_, width = utf8.DecodeRune(b[pos:end])
-			}
-			if width > 0 {
-				pos += width
-			} else {
-				pos = end + 1
-			}
-		} else {
-			pos = matches[1]
-		}
-		prevMatchEnd = matches[1]
-
-		if accept {
-			deliver(re.pad(matches))
-			i++
-		}
-	}
-}
-
-// Find returns a slice holding the text of the leftmost match in b of the regular expression.
-// A return value of nil indicates no match.
-func (re *Regexp) Find(b []byte) []byte {
-	a := re.doExecute(nil, b, "", 0, 2)
-	if a == nil {
-		return nil
-	}
-	return b[a[0]:a[1]]
-}
-
-// FindIndex returns a two-element slice of integers defining the location of
-// the leftmost match in b of the regular expression.  The match itself is at
-// b[loc[0]:loc[1]].
-// A return value of nil indicates no match.
-func (re *Regexp) FindIndex(b []byte) (loc []int) {
-	a := re.doExecute(nil, b, "", 0, 2)
-	if a == nil {
-		return nil
-	}
-	return a[0:2]
-}
-
-// FindString returns a string holding the text of the leftmost match in s of the regular
-// expression.  If there is no match, the return value is an empty string,
-// but it will also be empty if the regular expression successfully matches
-// an empty string.  Use FindStringIndex or FindStringSubmatch if it is
-// necessary to distinguish these cases.
-func (re *Regexp) FindString(s string) string {
-	a := re.doExecute(nil, nil, s, 0, 2)
-	if a == nil {
-		return ""
-	}
-	return s[a[0]:a[1]]
-}
-
-// FindStringIndex returns a two-element slice of integers defining the
-// location of the leftmost match in s of the regular expression.  The match
-// itself is at s[loc[0]:loc[1]].
-// A return value of nil indicates no match.
-func (re *Regexp) FindStringIndex(s string) (loc []int) {
-	a := re.doExecute(nil, nil, s, 0, 2)
-	if a == nil {
-		return nil
-	}
-	return a[0:2]
-}
-
-// FindReaderIndex returns a two-element slice of integers defining the
-// location of the leftmost match of the regular expression in text read from
-// the RuneReader.  The match text was found in the input stream at
-// byte offset loc[0] through loc[1]-1.
-// A return value of nil indicates no match.
-func (re *Regexp) FindReaderIndex(r io.RuneReader) (loc []int) {
-	a := re.doExecute(r, nil, "", 0, 2)
-	if a == nil {
-		return nil
-	}
-	return a[0:2]
-}
-
-// FindSubmatch returns a slice of slices holding the text of the leftmost
-// match of the regular expression in b and the matches, if any, of its
-// subexpressions, as defined by the 'Submatch' descriptions in the package
-// comment.
-// A return value of nil indicates no match.
-func (re *Regexp) FindSubmatch(b []byte) [][]byte {
-	a := re.doExecute(nil, b, "", 0, re.prog.NumCap)
-	if a == nil {
-		return nil
-	}
-	ret := make([][]byte, 1+re.numSubexp)
-	for i := range ret {
-		if 2*i < len(a) && a[2*i] >= 0 {
-			ret[i] = b[a[2*i]:a[2*i+1]]
-		}
-	}
-	return ret
-}
-
-// Expand appends template to dst and returns the result; during the
-// append, Expand replaces variables in the template with corresponding
-// matches drawn from src.  The match slice should have been returned by
-// FindSubmatchIndex.
-//
-// In the template, a variable is denoted by a substring of the form
-// $name or ${name}, where name is a non-empty sequence of letters,
-// digits, and underscores.  A purely numeric name like $1 refers to
-// the submatch with the corresponding index; other names refer to
-// capturing parentheses named with the (?P<name>...) syntax.  A
-// reference to an out of range or unmatched index or a name that is not
-// present in the regular expression is replaced with an empty slice.
-//
-// In the $name form, name is taken to be as long as possible: $1x is
-// equivalent to ${1x}, not ${1}x, and, $10 is equivalent to ${10}, not ${1}0.
-//
-// To insert a literal $ in the output, use $$ in the template.
-func (re *Regexp) Expand(dst []byte, template []byte, src []byte, match []int) []byte {
-	return re.expand(dst, string(template), src, "", match)
-}
-
-// ExpandString is like Expand but the template and source are strings.
-// It appends to and returns a byte slice in order to give the calling
-// code control over allocation.
-func (re *Regexp) ExpandString(dst []byte, template string, src string, match []int) []byte {
-	return re.expand(dst, template, nil, src, match)
-}
-
-func (re *Regexp) expand(dst []byte, template string, bsrc []byte, src string, match []int) []byte {
-	for len(template) > 0 {
-		i := strings.Index(template, "$")
-		if i < 0 {
-			break
-		}
-		dst = append(dst, template[:i]...)
-		template = template[i:]
-		if len(template) > 1 && template[1] == '$' {
-			// Treat $$ as $.
-			dst = append(dst, '$')
-			template = template[2:]
-			continue
-		}
-		name, num, rest, ok := extract(template)
-		if !ok {
-			// Malformed; treat $ as raw text.
-			dst = append(dst, '$')
-			template = template[1:]
-			continue
-		}
-		template = rest
-		if num >= 0 {
-			if 2*num+1 < len(match) && match[2*num] >= 0 {
-				if bsrc != nil {
-					dst = append(dst, bsrc[match[2*num]:match[2*num+1]]...)
-				} else {
-					dst = append(dst, src[match[2*num]:match[2*num+1]]...)
-				}
-			}
-		} else {
-			for i, namei := range re.subexpNames {
-				if name == namei && 2*i+1 < len(match) && match[2*i] >= 0 {
-					if bsrc != nil {
-						dst = append(dst, bsrc[match[2*i]:match[2*i+1]]...)
-					} else {
-						dst = append(dst, src[match[2*i]:match[2*i+1]]...)
-					}
-					break
-				}
-			}
-		}
-	}
-	dst = append(dst, template...)
-	return dst
-}
-
-// extract returns the name from a leading "$name" or "${name}" in str.
-// If it is a number, extract returns num set to that number; otherwise num = -1.
-func extract(str string) (name string, num int, rest string, ok bool) {
-	if len(str) < 2 || str[0] != '$' {
-		return
-	}
-	brace := false
-	if str[1] == '{' {
-		brace = true
-		str = str[2:]
-	} else {
-		str = str[1:]
-	}
-	i := 0
-	for i < len(str) {
-		rune, size := utf8.DecodeRuneInString(str[i:])
-		if !unicode.IsLetter(rune) && !unicode.IsDigit(rune) && rune != '_' {
-			break
-		}
-		i += size
-	}
-	if i == 0 {
-		// empty name is not okay
-		return
-	}
-	name = str[:i]
-	if brace {
-		if i >= len(str) || str[i] != '}' {
-			// missing closing brace
-			return
-		}
-		i++
-	}
-
-	// Parse number.
-	num = 0
-	for i := 0; i < len(name); i++ {
-		if name[i] < '0' || '9' < name[i] || num >= 1e8 {
-			num = -1
-			break
-		}
-		num = num*10 + int(name[i]) - '0'
-	}
-	// Disallow leading zeros.
-	if name[0] == '0' && len(name) > 1 {
-		num = -1
-	}
-
-	rest = str[i:]
-	ok = true
-	return
-}
-
-// FindSubmatchIndex returns a slice holding the index pairs identifying the
-// leftmost match of the regular expression in b and the matches, if any, of
-// its subexpressions, as defined by the 'Submatch' and 'Index' descriptions
-// in the package comment.
-// A return value of nil indicates no match.
-func (re *Regexp) FindSubmatchIndex(b []byte) []int {
-	return re.pad(re.doExecute(nil, b, "", 0, re.prog.NumCap))
-}
-
-// FindStringSubmatch returns a slice of strings holding the text of the
-// leftmost match of the regular expression in s and the matches, if any, of
-// its subexpressions, as defined by the 'Submatch' description in the
-// package comment.
-// A return value of nil indicates no match.
-func (re *Regexp) FindStringSubmatch(s string) []string {
-	a := re.doExecute(nil, nil, s, 0, re.prog.NumCap)
-	if a == nil {
-		return nil
-	}
-	ret := make([]string, 1+re.numSubexp)
-	for i := range ret {
-		if 2*i < len(a) && a[2*i] >= 0 {
-			ret[i] = s[a[2*i]:a[2*i+1]]
-		}
-	}
-	return ret
-}
-
-// FindStringSubmatchIndex returns a slice holding the index pairs
-// identifying the leftmost match of the regular expression in s and the
-// matches, if any, of its subexpressions, as defined by the 'Submatch' and
-// 'Index' descriptions in the package comment.
-// A return value of nil indicates no match.
-func (re *Regexp) FindStringSubmatchIndex(s string) []int {
-	return re.pad(re.doExecute(nil, nil, s, 0, re.prog.NumCap))
-}
-
-// FindReaderSubmatchIndex returns a slice holding the index pairs
-// identifying the leftmost match of the regular expression of text read by
-// the RuneReader, and the matches, if any, of its subexpressions, as defined
-// by the 'Submatch' and 'Index' descriptions in the package comment.  A
-// return value of nil indicates no match.
-func (re *Regexp) FindReaderSubmatchIndex(r io.RuneReader) []int {
-	return re.pad(re.doExecute(r, nil, "", 0, re.prog.NumCap))
-}
-
-const startSize = 10 // The size at which to start a slice in the 'All' routines.
-
-// FindAll is the 'All' version of Find; it returns a slice of all successive
-// matches of the expression, as defined by the 'All' description in the
-// package comment.
-// A return value of nil indicates no match.
-func (re *Regexp) FindAll(b []byte, n int) [][]byte {
-	if n < 0 {
-		n = len(b) + 1
-	}
-	result := make([][]byte, 0, startSize)
-	re.allMatches("", b, n, func(match []int) {
-		result = append(result, b[match[0]:match[1]])
-	})
-	if len(result) == 0 {
-		return nil
-	}
-	return result
-}
-
-// FindAllIndex is the 'All' version of FindIndex; it returns a slice of all
-// successive matches of the expression, as defined by the 'All' description
-// in the package comment.
-// A return value of nil indicates no match.
-func (re *Regexp) FindAllIndex(b []byte, n int) [][]int {
-	if n < 0 {
-		n = len(b) + 1
-	}
-	result := make([][]int, 0, startSize)
-	re.allMatches("", b, n, func(match []int) {
-		result = append(result, match[0:2])
-	})
-	if len(result) == 0 {
-		return nil
-	}
-	return result
-}
-
-// FindAllString is the 'All' version of FindString; it returns a slice of all
-// successive matches of the expression, as defined by the 'All' description
-// in the package comment.
-// A return value of nil indicates no match.
-func (re *Regexp) FindAllString(s string, n int) []string {
-	if n < 0 {
-		n = len(s) + 1
-	}
-	result := make([]string, 0, startSize)
-	re.allMatches(s, nil, n, func(match []int) {
-		result = append(result, s[match[0]:match[1]])
-	})
-	if len(result) == 0 {
-		return nil
-	}
-	return result
-}
-
-// FindAllStringIndex is the 'All' version of FindStringIndex; it returns a
-// slice of all successive matches of the expression, as defined by the 'All'
-// description in the package comment.
-// A return value of nil indicates no match.
-func (re *Regexp) FindAllStringIndex(s string, n int) [][]int {
-	if n < 0 {
-		n = len(s) + 1
-	}
-	result := make([][]int, 0, startSize)
-	re.allMatches(s, nil, n, func(match []int) {
-		result = append(result, match[0:2])
-	})
-	if len(result) == 0 {
-		return nil
-	}
-	return result
-}
-
-// FindAllSubmatch is the 'All' version of FindSubmatch; it returns a slice
-// of all successive matches of the expression, as defined by the 'All'
-// description in the package comment.
-// A return value of nil indicates no match.
-func (re *Regexp) FindAllSubmatch(b []byte, n int) [][][]byte {
-	if n < 0 {
-		n = len(b) + 1
-	}
-	result := make([][][]byte, 0, startSize)
-	re.allMatches("", b, n, func(match []int) {
-		slice := make([][]byte, len(match)/2)
-		for j := range slice {
-			if match[2*j] >= 0 {
-				slice[j] = b[match[2*j]:match[2*j+1]]
-			}
-		}
-		result = append(result, slice)
-	})
-	if len(result) == 0 {
-		return nil
-	}
-	return result
-}
-
-// FindAllSubmatchIndex is the 'All' version of FindSubmatchIndex; it returns
-// a slice of all successive matches of the expression, as defined by the
-// 'All' description in the package comment.
-// A return value of nil indicates no match.
-func (re *Regexp) FindAllSubmatchIndex(b []byte, n int) [][]int {
-	if n < 0 {
-		n = len(b) + 1
-	}
-	result := make([][]int, 0, startSize)
-	re.allMatches("", b, n, func(match []int) {
-		result = append(result, match)
-	})
-	if len(result) == 0 {
-		return nil
-	}
-	return result
-}
-
-// FindAllStringSubmatch is the 'All' version of FindStringSubmatch; it
-// returns a slice of all successive matches of the expression, as defined by
-// the 'All' description in the package comment.
-// A return value of nil indicates no match.
-func (re *Regexp) FindAllStringSubmatch(s string, n int) [][]string {
-	if n < 0 {
-		n = len(s) + 1
-	}
-	result := make([][]string, 0, startSize)
-	re.allMatches(s, nil, n, func(match []int) {
-		slice := make([]string, len(match)/2)
-		for j := range slice {
-			if match[2*j] >= 0 {
-				slice[j] = s[match[2*j]:match[2*j+1]]
-			}
-		}
-		result = append(result, slice)
-	})
-	if len(result) == 0 {
-		return nil
-	}
-	return result
-}
-
-// FindAllStringSubmatchIndex is the 'All' version of
-// FindStringSubmatchIndex; it returns a slice of all successive matches of
-// the expression, as defined by the 'All' description in the package
-// comment.
-// A return value of nil indicates no match.
-func (re *Regexp) FindAllStringSubmatchIndex(s string, n int) [][]int {
-	if n < 0 {
-		n = len(s) + 1
-	}
-	result := make([][]int, 0, startSize)
-	re.allMatches(s, nil, n, func(match []int) {
-		result = append(result, match)
-	})
-	if len(result) == 0 {
-		return nil
-	}
-	return result
-}
-
-// Split slices s into substrings separated by the expression and returns a slice of
-// the substrings between those expression matches.
-//
-// The slice returned by this method consists of all the substrings of s
-// not contained in the slice returned by FindAllString. When called on an expression
-// that contains no metacharacters, it is equivalent to strings.SplitN.
-//
-// Example:
-//   s := regexp.MustCompile("a*").Split("abaabaccadaaae", 5)
-//   // s: ["", "b", "b", "c", "cadaaae"]
-//
-// The count determines the number of substrings to return:
-//   n > 0: at most n substrings; the last substring will be the unsplit remainder.
-//   n == 0: the result is nil (zero substrings)
-//   n < 0: all substrings
-func (re *Regexp) Split(s string, n int) []string {
-
-	if n == 0 {
-		return nil
-	}
-
-	if len(re.expr) > 0 && len(s) == 0 {
-		return []string{""}
-	}
-
-	matches := re.FindAllStringIndex(s, n)
-	strings := make([]string, 0, len(matches))
-
-	beg := 0
-	end := 0
-	for _, match := range matches {
-		if n > 0 && len(strings) >= n-1 {
-			break
-		}
-
-		end = match[0]
-		if match[1] != 0 {
-			strings = append(strings, s[beg:end])
-		}
-		beg = match[1]
-	}
-
-	if end != len(s) {
-		strings = append(strings, s[beg:])
-	}
-
-	return strings
-}
diff --git a/src/pkg/regexp/syntax/doc.go b/src/pkg/regexp/syntax/doc.go
deleted file mode 100644
index 8e72c90..0000000
--- a/src/pkg/regexp/syntax/doc.go
+++ /dev/null
@@ -1,131 +0,0 @@
-// Copyright 2012 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// DO NOT EDIT. This file is generated by mksyntaxgo from the RE2 distribution.
-
-/*
-Package syntax parses regular expressions into parse trees and compiles
-parse trees into programs. Most clients of regular expressions will use the
-facilities of package regexp (such as Compile and Match) instead of this package.
-
-Syntax
-
-The regular expression syntax understood by this package when parsing with the Perl flag is as follows.
-Parts of the syntax can be disabled by passing alternate flags to Parse.
-
-
-Single characters:
-  .              any character, possibly including newline (flag s=true)
-  [xyz]          character class
-  [^xyz]         negated character class
-  \d             Perl character class
-  \D             negated Perl character class
-  [:alpha:]      ASCII character class
-  [:^alpha:]     negated ASCII character class
-  \pN            Unicode character class (one-letter name)
-  \p{Greek}      Unicode character class
-  \PN            negated Unicode character class (one-letter name)
-  \P{Greek}      negated Unicode character class
-
-Composites:
-  xy             x followed by y
-  x|y            x or y (prefer x)
-
-Repetitions:
-  x*             zero or more x, prefer more
-  x+             one or more x, prefer more
-  x?             zero or one x, prefer one
-  x{n,m}         n or n+1 or ... or m x, prefer more
-  x{n,}          n or more x, prefer more
-  x{n}           exactly n x
-  x*?            zero or more x, prefer fewer
-  x+?            one or more x, prefer fewer
-  x??            zero or one x, prefer zero
-  x{n,m}?        n or n+1 or ... or m x, prefer fewer
-  x{n,}?         n or more x, prefer fewer
-  x{n}?          exactly n x
-
-Implementation restriction: The counting forms x{n} etc. (but not the other
-forms x* etc.) have an upper limit of n=1000. Negative or higher explicit
-counts yield the parse error ErrInvalidRepeatSize.
-
-Grouping:
-  (re)           numbered capturing group (submatch)
-  (?P<name>re)   named & numbered capturing group (submatch)
-  (?:re)         non-capturing group (submatch)
-  (?flags)       set flags within current group; non-capturing
-  (?flags:re)    set flags during re; non-capturing
-
-  Flag syntax is xyz (set) or -xyz (clear) or xy-z (set xy, clear z). The flags are:
-
-  i              case-insensitive (default false)
-  m              multi-line mode: ^ and $ match begin/end line in addition to begin/end text (default false)
-  s              let . match \n (default false)
-  U              ungreedy: swap meaning of x* and x*?, x+ and x+?, etc (default false)
-
-Empty strings:
-  ^              at beginning of text or line (flag m=true)
-  $              at end of text (like \z not \Z) or line (flag m=true)
-  \A             at beginning of text
-  \b             at ASCII word boundary (\w on one side and \W, \A, or \z on the other)
-  \B             not an ASCII word boundary
-  \z             at end of text
-
-Escape sequences:
-  \a             bell (== \007)
-  \f             form feed (== \014)
-  \t             horizontal tab (== \011)
-  \n             newline (== \012)
-  \r             carriage return (== \015)
-  \v             vertical tab character (== \013)
-  \*             literal *, for any punctuation character *
-  \123           octal character code (up to three digits)
-  \x7F           hex character code (exactly two digits)
-  \x{10FFFF}     hex character code
-  \Q...\E        literal text ... even if ... has punctuation
-
-Character class elements:
-  x              single character
-  A-Z            character range (inclusive)
-  \d             Perl character class
-  [:foo:]        ASCII character class foo
-  \p{Foo}        Unicode character class Foo
-  \pF            Unicode character class F (one-letter name)
-
-Named character classes as character class elements:
-  [\d]           digits (== \d)
-  [^\d]          not digits (== \D)
-  [\D]           not digits (== \D)
-  [^\D]          not not digits (== \d)
-  [[:name:]]     named ASCII class inside character class (== [:name:])
-  [^[:name:]]    named ASCII class inside negated character class (== [:^name:])
-  [\p{Name}]     named Unicode property inside character class (== \p{Name})
-  [^\p{Name}]    named Unicode property inside negated character class (== \P{Name})
-
-Perl character classes:
-  \d             digits (== [0-9])
-  \D             not digits (== [^0-9])
-  \s             whitespace (== [\t\n\f\r ])
-  \S             not whitespace (== [^\t\n\f\r ])
-  \w             ASCII word characters (== [0-9A-Za-z_])
-  \W             not ASCII word characters (== [^0-9A-Za-z_])
-
-ASCII character classes:
-  [:alnum:]      alphanumeric (== [0-9A-Za-z])
-  [:alpha:]      alphabetic (== [A-Za-z])
-  [:ascii:]      ASCII (== [\x00-\x7F])
-  [:blank:]      blank (== [\t ])
-  [:cntrl:]      control (== [\x00-\x1F\x7F])
-  [:digit:]      digits (== [0-9])
-  [:graph:]      graphical (== [!-~] == [A-Za-z0-9!"#$%&'()*+,\-./:;<=>?@[\\\]^_`{|}~])
-  [:lower:]      lower case (== [a-z])
-  [:print:]      printable (== [ -~] == [ [:graph:]])
-  [:punct:]      punctuation (== [!-/:-@[-`{-~])
-  [:space:]      whitespace (== [\t\n\v\f\r ])
-  [:upper:]      upper case (== [A-Z])
-  [:word:]       word characters (== [0-9A-Za-z_])
-  [:xdigit:]     hex digit (== [0-9A-Fa-f])
-
-*/
-package syntax
diff --git a/src/pkg/regexp/syntax/parse.go b/src/pkg/regexp/syntax/parse.go
deleted file mode 100644
index cb25dca..0000000
--- a/src/pkg/regexp/syntax/parse.go
+++ /dev/null
@@ -1,1863 +0,0 @@
-// Copyright 2011 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package syntax
-
-import (
-	"sort"
-	"strings"
-	"unicode"
-	"unicode/utf8"
-)
-
-// An Error describes a failure to parse a regular expression
-// and gives the offending expression.
-type Error struct {
-	Code ErrorCode
-	Expr string
-}
-
-func (e *Error) Error() string {
-	return "error parsing regexp: " + e.Code.String() + ": `" + e.Expr + "`"
-}
-
-// An ErrorCode describes a failure to parse a regular expression.
-type ErrorCode string
-
-const (
-	// Unexpected error
-	ErrInternalError ErrorCode = "regexp/syntax: internal error"
-
-	// Parse errors
-	ErrInvalidCharClass      ErrorCode = "invalid character class"
-	ErrInvalidCharRange      ErrorCode = "invalid character class range"
-	ErrInvalidEscape         ErrorCode = "invalid escape sequence"
-	ErrInvalidNamedCapture   ErrorCode = "invalid named capture"
-	ErrInvalidPerlOp         ErrorCode = "invalid or unsupported Perl syntax"
-	ErrInvalidRepeatOp       ErrorCode = "invalid nested repetition operator"
-	ErrInvalidRepeatSize     ErrorCode = "invalid repeat count"
-	ErrInvalidUTF8           ErrorCode = "invalid UTF-8"
-	ErrMissingBracket        ErrorCode = "missing closing ]"
-	ErrMissingParen          ErrorCode = "missing closing )"
-	ErrMissingRepeatArgument ErrorCode = "missing argument to repetition operator"
-	ErrTrailingBackslash     ErrorCode = "trailing backslash at end of expression"
-	ErrUnexpectedParen       ErrorCode = "unexpected )"
-)
-
-func (e ErrorCode) String() string {
-	return string(e)
-}
-
-// Flags control the behavior of the parser and record information about regexp context.
-type Flags uint16
-
-const (
-	FoldCase      Flags = 1 << iota // case-insensitive match
-	Literal                         // treat pattern as literal string
-	ClassNL                         // allow character classes like [^a-z] and [[:space:]] to match newline
-	DotNL                           // allow . to match newline
-	OneLine                         // treat ^ and $ as only matching at beginning and end of text
-	NonGreedy                       // make repetition operators default to non-greedy
-	PerlX                           // allow Perl extensions
-	UnicodeGroups                   // allow \p{Han}, \P{Han} for Unicode group and negation
-	WasDollar                       // regexp OpEndText was $, not \z
-	Simple                          // regexp contains no counted repetition
-
-	MatchNL = ClassNL | DotNL
-
-	Perl        = ClassNL | OneLine | PerlX | UnicodeGroups // as close to Perl as possible
-	POSIX Flags = 0                                         // POSIX syntax
-)
-
-// Pseudo-ops for parsing stack.
-const (
-	opLeftParen = opPseudo + iota
-	opVerticalBar
-)
-
-type parser struct {
-	flags       Flags     // parse mode flags
-	stack       []*Regexp // stack of parsed expressions
-	free        *Regexp
-	numCap      int // number of capturing groups seen
-	wholeRegexp string
-	tmpClass    []rune // temporary char class work space
-}
-
-func (p *parser) newRegexp(op Op) *Regexp {
-	re := p.free
-	if re != nil {
-		p.free = re.Sub0[0]
-		*re = Regexp{}
-	} else {
-		re = new(Regexp)
-	}
-	re.Op = op
-	return re
-}
-
-func (p *parser) reuse(re *Regexp) {
-	re.Sub0[0] = p.free
-	p.free = re
-}
-
-// Parse stack manipulation.
-
-// push pushes the regexp re onto the parse stack and returns the regexp.
-func (p *parser) push(re *Regexp) *Regexp {
-	if re.Op == OpCharClass && len(re.Rune) == 2 && re.Rune[0] == re.Rune[1] {
-		// Single rune.
-		if p.maybeConcat(re.Rune[0], p.flags&^FoldCase) {
-			return nil
-		}
-		re.Op = OpLiteral
-		re.Rune = re.Rune[:1]
-		re.Flags = p.flags &^ FoldCase
-	} else if re.Op == OpCharClass && len(re.Rune) == 4 &&
-		re.Rune[0] == re.Rune[1] && re.Rune[2] == re.Rune[3] &&
-		unicode.SimpleFold(re.Rune[0]) == re.Rune[2] &&
-		unicode.SimpleFold(re.Rune[2]) == re.Rune[0] ||
-		re.Op == OpCharClass && len(re.Rune) == 2 &&
-			re.Rune[0]+1 == re.Rune[1] &&
-			unicode.SimpleFold(re.Rune[0]) == re.Rune[1] &&
-			unicode.SimpleFold(re.Rune[1]) == re.Rune[0] {
-		// Case-insensitive rune like [Aa] or [Δδ].
-		if p.maybeConcat(re.Rune[0], p.flags|FoldCase) {
-			return nil
-		}
-
-		// Rewrite as (case-insensitive) literal.
-		re.Op = OpLiteral
-		re.Rune = re.Rune[:1]
-		re.Flags = p.flags | FoldCase
-	} else {
-		// Incremental concatenation.
-		p.maybeConcat(-1, 0)
-	}
-
-	p.stack = append(p.stack, re)
-	return re
-}
-
-// maybeConcat implements incremental concatenation
-// of literal runes into string nodes.  The parser calls this
-// before each push, so only the top fragment of the stack
-// might need processing.  Since this is called before a push,
-// the topmost literal is no longer subject to operators like *
-// (Otherwise ab* would turn into (ab)*.)
-// If r >= 0 and there's a node left over, maybeConcat uses it
-// to push r with the given flags.
-// maybeConcat reports whether r was pushed.
-func (p *parser) maybeConcat(r rune, flags Flags) bool {
-	n := len(p.stack)
-	if n < 2 {
-		return false
-	}
-
-	re1 := p.stack[n-1]
-	re2 := p.stack[n-2]
-	if re1.Op != OpLiteral || re2.Op != OpLiteral || re1.Flags&FoldCase != re2.Flags&FoldCase {
-		return false
-	}
-
-	// Push re1 into re2.
-	re2.Rune = append(re2.Rune, re1.Rune...)
-
-	// Reuse re1 if possible.
-	if r >= 0 {
-		re1.Rune = re1.Rune0[:1]
-		re1.Rune[0] = r
-		re1.Flags = flags
-		return true
-	}
-
-	p.stack = p.stack[:n-1]
-	p.reuse(re1)
-	return false // did not push r
-}
-
-// newLiteral returns a new OpLiteral Regexp with the given flags
-func (p *parser) newLiteral(r rune, flags Flags) *Regexp {
-	re := p.newRegexp(OpLiteral)
-	re.Flags = flags
-	if flags&FoldCase != 0 {
-		r = minFoldRune(r)
-	}
-	re.Rune0[0] = r
-	re.Rune = re.Rune0[:1]
-	return re
-}
-
-// minFoldRune returns the minimum rune fold-equivalent to r.
-func minFoldRune(r rune) rune {
-	if r < minFold || r > maxFold {
-		return r
-	}
-	min := r
-	r0 := r
-	for r = unicode.SimpleFold(r); r != r0; r = unicode.SimpleFold(r) {
-		if min > r {
-			min = r
-		}
-	}
-	return min
-}
-
-// literal pushes a literal regexp for the rune r on the stack
-// and returns that regexp.
-func (p *parser) literal(r rune) {
-	p.push(p.newLiteral(r, p.flags))
-}
-
-// op pushes a regexp with the given op onto the stack
-// and returns that regexp.
-func (p *parser) op(op Op) *Regexp {
-	re := p.newRegexp(op)
-	re.Flags = p.flags
-	return p.push(re)
-}
-
-// repeat replaces the top stack element with itself repeated according to op, min, max.
-// before is the regexp suffix starting at the repetition operator.
-// after is the regexp suffix following after the repetition operator.
-// repeat returns an updated 'after' and an error, if any.
-func (p *parser) repeat(op Op, min, max int, before, after, lastRepeat string) (string, error) {
-	flags := p.flags
-	if p.flags&PerlX != 0 {
-		if len(after) > 0 && after[0] == '?' {
-			after = after[1:]
-			flags ^= NonGreedy
-		}
-		if lastRepeat != "" {
-			// In Perl it is not allowed to stack repetition operators:
-			// a** is a syntax error, not a doubled star, and a++ means
-			// something else entirely, which we don't support!
-			return "", &Error{ErrInvalidRepeatOp, lastRepeat[:len(lastRepeat)-len(after)]}
-		}
-	}
-	n := len(p.stack)
-	if n == 0 {
-		return "", &Error{ErrMissingRepeatArgument, before[:len(before)-len(after)]}
-	}
-	sub := p.stack[n-1]
-	if sub.Op >= opPseudo {
-		return "", &Error{ErrMissingRepeatArgument, before[:len(before)-len(after)]}
-	}
-	re := p.newRegexp(op)
-	re.Min = min
-	re.Max = max
-	re.Flags = flags
-	re.Sub = re.Sub0[:1]
-	re.Sub[0] = sub
-	p.stack[n-1] = re
-	return after, nil
-}
-
-// concat replaces the top of the stack (above the topmost '|' or '(') with its concatenation.
-func (p *parser) concat() *Regexp {
-	p.maybeConcat(-1, 0)
-
-	// Scan down to find pseudo-operator | or (.
-	i := len(p.stack)
-	for i > 0 && p.stack[i-1].Op < opPseudo {
-		i--
-	}
-	subs := p.stack[i:]
-	p.stack = p.stack[:i]
-
-	// Empty concatenation is special case.
-	if len(subs) == 0 {
-		return p.push(p.newRegexp(OpEmptyMatch))
-	}
-
-	return p.push(p.collapse(subs, OpConcat))
-}
-
-// alternate replaces the top of the stack (above the topmost '(') with its alternation.
-func (p *parser) alternate() *Regexp {
-	// Scan down to find pseudo-operator (.
-	// There are no | above (.
-	i := len(p.stack)
-	for i > 0 && p.stack[i-1].Op < opPseudo {
-		i--
-	}
-	subs := p.stack[i:]
-	p.stack = p.stack[:i]
-
-	// Make sure top class is clean.
-	// All the others already are (see swapVerticalBar).
-	if len(subs) > 0 {
-		cleanAlt(subs[len(subs)-1])
-	}
-
-	// Empty alternate is special case
-	// (shouldn't happen but easy to handle).
-	if len(subs) == 0 {
-		return p.push(p.newRegexp(OpNoMatch))
-	}
-
-	return p.push(p.collapse(subs, OpAlternate))
-}
-
-// cleanAlt cleans re for eventual inclusion in an alternation.
-func cleanAlt(re *Regexp) {
-	switch re.Op {
-	case OpCharClass:
-		re.Rune = cleanClass(&re.Rune)
-		if len(re.Rune) == 2 && re.Rune[0] == 0 && re.Rune[1] == unicode.MaxRune {
-			re.Rune = nil
-			re.Op = OpAnyChar
-			return
-		}
-		if len(re.Rune) == 4 && re.Rune[0] == 0 && re.Rune[1] == '\n'-1 && re.Rune[2] == '\n'+1 && re.Rune[3] == unicode.MaxRune {
-			re.Rune = nil
-			re.Op = OpAnyCharNotNL
-			return
-		}
-		if cap(re.Rune)-len(re.Rune) > 100 {
-			// re.Rune will not grow any more.
-			// Make a copy or inline to reclaim storage.
-			re.Rune = append(re.Rune0[:0], re.Rune...)
-		}
-	}
-}
-
-// collapse returns the result of applying op to sub.
-// If sub contains op nodes, they all get hoisted up
-// so that there is never a concat of a concat or an
-// alternate of an alternate.
-func (p *parser) collapse(subs []*Regexp, op Op) *Regexp {
-	if len(subs) == 1 {
-		return subs[0]
-	}
-	re := p.newRegexp(op)
-	re.Sub = re.Sub0[:0]
-	for _, sub := range subs {
-		if sub.Op == op {
-			re.Sub = append(re.Sub, sub.Sub...)
-			p.reuse(sub)
-		} else {
-			re.Sub = append(re.Sub, sub)
-		}
-	}
-	if op == OpAlternate {
-		re.Sub = p.factor(re.Sub, re.Flags)
-		if len(re.Sub) == 1 {
-			old := re
-			re = re.Sub[0]
-			p.reuse(old)
-		}
-	}
-	return re
-}
-
-// factor factors common prefixes from the alternation list sub.
-// It returns a replacement list that reuses the same storage and
-// frees (passes to p.reuse) any removed *Regexps.
-//
-// For example,
-//     ABC|ABD|AEF|BCX|BCY
-// simplifies by literal prefix extraction to
-//     A(B(C|D)|EF)|BC(X|Y)
-// which simplifies by character class introduction to
-//     A(B[CD]|EF)|BC[XY]
-//
-func (p *parser) factor(sub []*Regexp, flags Flags) []*Regexp {
-	if len(sub) < 2 {
-		return sub
-	}
-
-	// Round 1: Factor out common literal prefixes.
-	var str []rune
-	var strflags Flags
-	start := 0
-	out := sub[:0]
-	for i := 0; i <= len(sub); i++ {
-		// Invariant: the Regexps that were in sub[0:start] have been
-		// used or marked for reuse, and the slice space has been reused
-		// for out (len(out) <= start).
-		//
-		// Invariant: sub[start:i] consists of regexps that all begin
-		// with str as modified by strflags.
-		var istr []rune
-		var iflags Flags
-		if i < len(sub) {
-			istr, iflags = p.leadingString(sub[i])
-			if iflags == strflags {
-				same := 0
-				for same < len(str) && same < len(istr) && str[same] == istr[same] {
-					same++
-				}
-				if same > 0 {
-					// Matches at least one rune in current range.
-					// Keep going around.
-					str = str[:same]
-					continue
-				}
-			}
-		}
-
-		// Found end of a run with common leading literal string:
-		// sub[start:i] all begin with str[0:len(str)], but sub[i]
-		// does not even begin with str[0].
-		//
-		// Factor out common string and append factored expression to out.
-		if i == start {
-			// Nothing to do - run of length 0.
-		} else if i == start+1 {
-			// Just one: don't bother factoring.
-			out = append(out, sub[start])
-		} else {
-			// Construct factored form: prefix(suffix1|suffix2|...)
-			prefix := p.newRegexp(OpLiteral)
-			prefix.Flags = strflags
-			prefix.Rune = append(prefix.Rune[:0], str...)
-
-			for j := start; j < i; j++ {
-				sub[j] = p.removeLeadingString(sub[j], len(str))
-			}
-			suffix := p.collapse(sub[start:i], OpAlternate) // recurse
-
-			re := p.newRegexp(OpConcat)
-			re.Sub = append(re.Sub[:0], prefix, suffix)
-			out = append(out, re)
-		}
-
-		// Prepare for next iteration.
-		start = i
-		str = istr
-		strflags = iflags
-	}
-	sub = out
-
-	// Round 2: Factor out common complex prefixes,
-	// just the first piece of each concatenation,
-	// whatever it is.  This is good enough a lot of the time.
-	start = 0
-	out = sub[:0]
-	var first *Regexp
-	for i := 0; i <= len(sub); i++ {
-		// Invariant: the Regexps that were in sub[0:start] have been
-		// used or marked for reuse, and the slice space has been reused
-		// for out (len(out) <= start).
-		//
-		// Invariant: sub[start:i] consists of regexps that all begin with ifirst.
-		var ifirst *Regexp
-		if i < len(sub) {
-			ifirst = p.leadingRegexp(sub[i])
-			if first != nil && first.Equal(ifirst) {
-				continue
-			}
-		}
-
-		// Found end of a run with common leading regexp:
-		// sub[start:i] all begin with first but sub[i] does not.
-		//
-		// Factor out common regexp and append factored expression to out.
-		if i == start {
-			// Nothing to do - run of length 0.
-		} else if i == start+1 {
-			// Just one: don't bother factoring.
-			out = append(out, sub[start])
-		} else {
-			// Construct factored form: prefix(suffix1|suffix2|...)
-			prefix := first
-			for j := start; j < i; j++ {
-				reuse := j != start // prefix came from sub[start]
-				sub[j] = p.removeLeadingRegexp(sub[j], reuse)
-			}
-			suffix := p.collapse(sub[start:i], OpAlternate) // recurse
-
-			re := p.newRegexp(OpConcat)
-			re.Sub = append(re.Sub[:0], prefix, suffix)
-			out = append(out, re)
-		}
-
-		// Prepare for next iteration.
-		start = i
-		first = ifirst
-	}
-	sub = out
-
-	// Round 3: Collapse runs of single literals into character classes.
-	start = 0
-	out = sub[:0]
-	for i := 0; i <= len(sub); i++ {
-		// Invariant: the Regexps that were in sub[0:start] have been
-		// used or marked for reuse, and the slice space has been reused
-		// for out (len(out) <= start).
-		//
-		// Invariant: sub[start:i] consists of regexps that are either
-		// literal runes or character classes.
-		if i < len(sub) && isCharClass(sub[i]) {
-			continue
-		}
-
-		// sub[i] is not a char or char class;
-		// emit char class for sub[start:i]...
-		if i == start {
-			// Nothing to do - run of length 0.
-		} else if i == start+1 {
-			out = append(out, sub[start])
-		} else {
-			// Make new char class.
-			// Start with most complex regexp in sub[start].
-			max := start
-			for j := start + 1; j < i; j++ {
-				if sub[max].Op < sub[j].Op || sub[max].Op == sub[j].Op && len(sub[max].Rune) < len(sub[j].Rune) {
-					max = j
-				}
-			}
-			sub[start], sub[max] = sub[max], sub[start]
-
-			for j := start + 1; j < i; j++ {
-				mergeCharClass(sub[start], sub[j])
-				p.reuse(sub[j])
-			}
-			cleanAlt(sub[start])
-			out = append(out, sub[start])
-		}
-
-		// ... and then emit sub[i].
-		if i < len(sub) {
-			out = append(out, sub[i])
-		}
-		start = i + 1
-	}
-	sub = out
-
-	// Round 4: Collapse runs of empty matches into a single empty match.
-	start = 0
-	out = sub[:0]
-	for i := range sub {
-		if i+1 < len(sub) && sub[i].Op == OpEmptyMatch && sub[i+1].Op == OpEmptyMatch {
-			continue
-		}
-		out = append(out, sub[i])
-	}
-	sub = out
-
-	return sub
-}
-
-// leadingString returns the leading literal string that re begins with.
-// The string refers to storage in re or its children.
-func (p *parser) leadingString(re *Regexp) ([]rune, Flags) {
-	if re.Op == OpConcat && len(re.Sub) > 0 {
-		re = re.Sub[0]
-	}
-	if re.Op != OpLiteral {
-		return nil, 0
-	}
-	return re.Rune, re.Flags & FoldCase
-}
-
-// removeLeadingString removes the first n leading runes
-// from the beginning of re.  It returns the replacement for re.
-func (p *parser) removeLeadingString(re *Regexp, n int) *Regexp {
-	if re.Op == OpConcat && len(re.Sub) > 0 {
-		// Removing a leading string in a concatenation
-		// might simplify the concatenation.
-		sub := re.Sub[0]
-		sub = p.removeLeadingString(sub, n)
-		re.Sub[0] = sub
-		if sub.Op == OpEmptyMatch {
-			p.reuse(sub)
-			switch len(re.Sub) {
-			case 0, 1:
-				// Impossible but handle.
-				re.Op = OpEmptyMatch
-				re.Sub = nil
-			case 2:
-				old := re
-				re = re.Sub[1]
-				p.reuse(old)
-			default:
-				copy(re.Sub, re.Sub[1:])
-				re.Sub = re.Sub[:len(re.Sub)-1]
-			}
-		}
-		return re
-	}
-
-	if re.Op == OpLiteral {
-		re.Rune = re.Rune[:copy(re.Rune, re.Rune[n:])]
-		if len(re.Rune) == 0 {
-			re.Op = OpEmptyMatch
-		}
-	}
-	return re
-}
-
-// leadingRegexp returns the leading regexp that re begins with.
-// The regexp refers to storage in re or its children.
-func (p *parser) leadingRegexp(re *Regexp) *Regexp {
-	if re.Op == OpEmptyMatch {
-		return nil
-	}
-	if re.Op == OpConcat && len(re.Sub) > 0 {
-		sub := re.Sub[0]
-		if sub.Op == OpEmptyMatch {
-			return nil
-		}
-		return sub
-	}
-	return re
-}
-
-// removeLeadingRegexp removes the leading regexp in re.
-// It returns the replacement for re.
-// If reuse is true, it passes the removed regexp (if no longer needed) to p.reuse.
-func (p *parser) removeLeadingRegexp(re *Regexp, reuse bool) *Regexp {
-	if re.Op == OpConcat && len(re.Sub) > 0 {
-		if reuse {
-			p.reuse(re.Sub[0])
-		}
-		re.Sub = re.Sub[:copy(re.Sub, re.Sub[1:])]
-		switch len(re.Sub) {
-		case 0:
-			re.Op = OpEmptyMatch
-			re.Sub = nil
-		case 1:
-			old := re
-			re = re.Sub[0]
-			p.reuse(old)
-		}
-		return re
-	}
-	if reuse {
-		p.reuse(re)
-	}
-	return p.newRegexp(OpEmptyMatch)
-}
-
-func literalRegexp(s string, flags Flags) *Regexp {
-	re := &Regexp{Op: OpLiteral}
-	re.Flags = flags
-	re.Rune = re.Rune0[:0] // use local storage for small strings
-	for _, c := range s {
-		if len(re.Rune) >= cap(re.Rune) {
-			// string is too long to fit in Rune0.  let Go handle it
-			re.Rune = []rune(s)
-			break
-		}
-		re.Rune = append(re.Rune, c)
-	}
-	return re
-}
-
-// Parsing.
-
-// Parse parses a regular expression string s, controlled by the specified
-// Flags, and returns a regular expression parse tree. The syntax is
-// described in the top-level comment.
-func Parse(s string, flags Flags) (*Regexp, error) {
-	if flags&Literal != 0 {
-		// Trivial parser for literal string.
-		if err := checkUTF8(s); err != nil {
-			return nil, err
-		}
-		return literalRegexp(s, flags), nil
-	}
-
-	// Otherwise, must do real work.
-	var (
-		p          parser
-		err        error
-		c          rune
-		op         Op
-		lastRepeat string
-	)
-	p.flags = flags
-	p.wholeRegexp = s
-	t := s
-	for t != "" {
-		repeat := ""
-	BigSwitch:
-		switch t[0] {
-		default:
-			if c, t, err = nextRune(t); err != nil {
-				return nil, err
-			}
-			p.literal(c)
-
-		case '(':
-			if p.flags&PerlX != 0 && len(t) >= 2 && t[1] == '?' {
-				// Flag changes and non-capturing groups.
-				if t, err = p.parsePerlFlags(t); err != nil {
-					return nil, err
-				}
-				break
-			}
-			p.numCap++
-			p.op(opLeftParen).Cap = p.numCap
-			t = t[1:]
-		case '|':
-			if err = p.parseVerticalBar(); err != nil {
-				return nil, err
-			}
-			t = t[1:]
-		case ')':
-			if err = p.parseRightParen(); err != nil {
-				return nil, err
-			}
-			t = t[1:]
-		case '^':
-			if p.flags&OneLine != 0 {
-				p.op(OpBeginText)
-			} else {
-				p.op(OpBeginLine)
-			}
-			t = t[1:]
-		case '$':
-			if p.flags&OneLine != 0 {
-				p.op(OpEndText).Flags |= WasDollar
-			} else {
-				p.op(OpEndLine)
-			}
-			t = t[1:]
-		case '.':
-			if p.flags&DotNL != 0 {
-				p.op(OpAnyChar)
-			} else {
-				p.op(OpAnyCharNotNL)
-			}
-			t = t[1:]
-		case '[':
-			if t, err = p.parseClass(t); err != nil {
-				return nil, err
-			}
-		case '*', '+', '?':
-			before := t
-			switch t[0] {
-			case '*':
-				op = OpStar
-			case '+':
-				op = OpPlus
-			case '?':
-				op = OpQuest
-			}
-			after := t[1:]
-			if after, err = p.repeat(op, 0, 0, before, after, lastRepeat); err != nil {
-				return nil, err
-			}
-			repeat = before
-			t = after
-		case '{':
-			op = OpRepeat
-			before := t
-			min, max, after, ok := p.parseRepeat(t)
-			if !ok {
-				// If the repeat cannot be parsed, { is a literal.
-				p.literal('{')
-				t = t[1:]
-				break
-			}
-			if min < 0 || min > 1000 || max > 1000 || max >= 0 && min > max {
-				// Numbers were too big, or max is present and min > max.
-				return nil, &Error{ErrInvalidRepeatSize, before[:len(before)-len(after)]}
-			}
-			if after, err = p.repeat(op, min, max, before, after, lastRepeat); err != nil {
-				return nil, err
-			}
-			repeat = before
-			t = after
-		case '\\':
-			if p.flags&PerlX != 0 && len(t) >= 2 {
-				switch t[1] {
-				case 'A':
-					p.op(OpBeginText)
-					t = t[2:]
-					break BigSwitch
-				case 'b':
-					p.op(OpWordBoundary)
-					t = t[2:]
-					break BigSwitch
-				case 'B':
-					p.op(OpNoWordBoundary)
-					t = t[2:]
-					break BigSwitch
-				case 'C':
-					// any byte; not supported
-					return nil, &Error{ErrInvalidEscape, t[:2]}
-				case 'Q':
-					// \Q ... \E: the ... is always literals
-					var lit string
-					if i := strings.Index(t, `\E`); i < 0 {
-						lit = t[2:]
-						t = ""
-					} else {
-						lit = t[2:i]
-						t = t[i+2:]
-					}
-					p.push(literalRegexp(lit, p.flags))
-					break BigSwitch
-				case 'z':
-					p.op(OpEndText)
-					t = t[2:]
-					break BigSwitch
-				}
-			}
-
-			re := p.newRegexp(OpCharClass)
-			re.Flags = p.flags
-
-			// Look for Unicode character group like \p{Han}
-			if len(t) >= 2 && (t[1] == 'p' || t[1] == 'P') {
-				r, rest, err := p.parseUnicodeClass(t, re.Rune0[:0])
-				if err != nil {
-					return nil, err
-				}
-				if r != nil {
-					re.Rune = r
-					t = rest
-					p.push(re)
-					break BigSwitch
-				}
-			}
-
-			// Perl character class escape.
-			if r, rest := p.parsePerlClassEscape(t, re.Rune0[:0]); r != nil {
-				re.Rune = r
-				t = rest
-				p.push(re)
-				break BigSwitch
-			}
-			p.reuse(re)
-
-			// Ordinary single-character escape.
-			if c, t, err = p.parseEscape(t); err != nil {
-				return nil, err
-			}
-			p.literal(c)
-		}
-		lastRepeat = repeat
-	}
-
-	p.concat()
-	if p.swapVerticalBar() {
-		// pop vertical bar
-		p.stack = p.stack[:len(p.stack)-1]
-	}
-	p.alternate()
-
-	n := len(p.stack)
-	if n != 1 {
-		return nil, &Error{ErrMissingParen, s}
-	}
-	return p.stack[0], nil
-}
-
-// parseRepeat parses {min} (max=min) or {min,} (max=-1) or {min,max}.
-// If s is not of that form, it returns ok == false.
-// If s has the right form but the values are too big, it returns min == -1, ok == true.
-func (p *parser) parseRepeat(s string) (min, max int, rest string, ok bool) {
-	if s == "" || s[0] != '{' {
-		return
-	}
-	s = s[1:]
-	var ok1 bool
-	if min, s, ok1 = p.parseInt(s); !ok1 {
-		return
-	}
-	if s == "" {
-		return
-	}
-	if s[0] != ',' {
-		max = min
-	} else {
-		s = s[1:]
-		if s == "" {
-			return
-		}
-		if s[0] == '}' {
-			max = -1
-		} else if max, s, ok1 = p.parseInt(s); !ok1 {
-			return
-		} else if max < 0 {
-			// parseInt found too big a number
-			min = -1
-		}
-	}
-	if s == "" || s[0] != '}' {
-		return
-	}
-	rest = s[1:]
-	ok = true
-	return
-}
-
-// parsePerlFlags parses a Perl flag setting or non-capturing group or both,
-// like (?i) or (?: or (?i:.  It removes the prefix from s and updates the parse state.
-// The caller must have ensured that s begins with "(?".
-func (p *parser) parsePerlFlags(s string) (rest string, err error) {
-	t := s
-
-	// Check for named captures, first introduced in Python's regexp library.
-	// As usual, there are three slightly different syntaxes:
-	//
-	//   (?P<name>expr)   the original, introduced by Python
-	//   (?<name>expr)    the .NET alteration, adopted by Perl 5.10
-	//   (?'name'expr)    another .NET alteration, adopted by Perl 5.10
-	//
-	// Perl 5.10 gave in and implemented the Python version too,
-	// but they claim that the last two are the preferred forms.
-	// PCRE and languages based on it (specifically, PHP and Ruby)
-	// support all three as well.  EcmaScript 4 uses only the Python form.
-	//
-	// In both the open source world (via Code Search) and the
-	// Google source tree, (?P<expr>name) is the dominant form,
-	// so that's the one we implement.  One is enough.
-	if len(t) > 4 && t[2] == 'P' && t[3] == '<' {
-		// Pull out name.
-		end := strings.IndexRune(t, '>')
-		if end < 0 {
-			if err = checkUTF8(t); err != nil {
-				return "", err
-			}
-			return "", &Error{ErrInvalidNamedCapture, s}
-		}
-
-		capture := t[:end+1] // "(?P<name>"
-		name := t[4:end]     // "name"
-		if err = checkUTF8(name); err != nil {
-			return "", err
-		}
-		if !isValidCaptureName(name) {
-			return "", &Error{ErrInvalidNamedCapture, capture}
-		}
-
-		// Like ordinary capture, but named.
-		p.numCap++
-		re := p.op(opLeftParen)
-		re.Cap = p.numCap
-		re.Name = name
-		return t[end+1:], nil
-	}
-
-	// Non-capturing group.  Might also twiddle Perl flags.
-	var c rune
-	t = t[2:] // skip (?
-	flags := p.flags
-	sign := +1
-	sawFlag := false
-Loop:
-	for t != "" {
-		if c, t, err = nextRune(t); err != nil {
-			return "", err
-		}
-		switch c {
-		default:
-			break Loop
-
-		// Flags.
-		case 'i':
-			flags |= FoldCase
-			sawFlag = true
-		case 'm':
-			flags &^= OneLine
-			sawFlag = true
-		case 's':
-			flags |= DotNL
-			sawFlag = true
-		case 'U':
-			flags |= NonGreedy
-			sawFlag = true
-
-		// Switch to negation.
-		case '-':
-			if sign < 0 {
-				break Loop
-			}
-			sign = -1
-			// Invert flags so that | above turn into &^ and vice versa.
-			// We'll invert flags again before using it below.
-			flags = ^flags
-			sawFlag = false
-
-		// End of flags, starting group or not.
-		case ':', ')':
-			if sign < 0 {
-				if !sawFlag {
-					break Loop
-				}
-				flags = ^flags
-			}
-			if c == ':' {
-				// Open new group
-				p.op(opLeftParen)
-			}
-			p.flags = flags
-			return t, nil
-		}
-	}
-
-	return "", &Error{ErrInvalidPerlOp, s[:len(s)-len(t)]}
-}
-
-// isValidCaptureName reports whether name
-// is a valid capture name: [A-Za-z0-9_]+.
-// PCRE limits names to 32 bytes.
-// Python rejects names starting with digits.
-// We don't enforce either of those.
-func isValidCaptureName(name string) bool {
-	if name == "" {
-		return false
-	}
-	for _, c := range name {
-		if c != '_' && !isalnum(c) {
-			return false
-		}
-	}
-	return true
-}
-
-// parseInt parses a decimal integer.
-func (p *parser) parseInt(s string) (n int, rest string, ok bool) {
-	if s == "" || s[0] < '0' || '9' < s[0] {
-		return
-	}
-	// Disallow leading zeros.
-	if len(s) >= 2 && s[0] == '0' && '0' <= s[1] && s[1] <= '9' {
-		return
-	}
-	t := s
-	for s != "" && '0' <= s[0] && s[0] <= '9' {
-		s = s[1:]
-	}
-	rest = s
-	ok = true
-	// Have digits, compute value.
-	t = t[:len(t)-len(s)]
-	for i := 0; i < len(t); i++ {
-		// Avoid overflow.
-		if n >= 1e8 {
-			n = -1
-			break
-		}
-		n = n*10 + int(t[i]) - '0'
-	}
-	return
-}
-
-// can this be represented as a character class?
-// single-rune literal string, char class, ., and .|\n.
-func isCharClass(re *Regexp) bool {
-	return re.Op == OpLiteral && len(re.Rune) == 1 ||
-		re.Op == OpCharClass ||
-		re.Op == OpAnyCharNotNL ||
-		re.Op == OpAnyChar
-}
-
-// does re match r?
-func matchRune(re *Regexp, r rune) bool {
-	switch re.Op {
-	case OpLiteral:
-		return len(re.Rune) == 1 && re.Rune[0] == r
-	case OpCharClass:
-		for i := 0; i < len(re.Rune); i += 2 {
-			if re.Rune[i] <= r && r <= re.Rune[i+1] {
-				return true
-			}
-		}
-		return false
-	case OpAnyCharNotNL:
-		return r != '\n'
-	case OpAnyChar:
-		return true
-	}
-	return false
-}
-
-// parseVerticalBar handles a | in the input.
-func (p *parser) parseVerticalBar() error {
-	p.concat()
-
-	// The concatenation we just parsed is on top of the stack.
-	// If it sits above an opVerticalBar, swap it below
-	// (things below an opVerticalBar become an alternation).
-	// Otherwise, push a new vertical bar.
-	if !p.swapVerticalBar() {
-		p.op(opVerticalBar)
-	}
-
-	return nil
-}
-
-// mergeCharClass makes dst = dst|src.
-// The caller must ensure that dst.Op >= src.Op,
-// to reduce the amount of copying.
-func mergeCharClass(dst, src *Regexp) {
-	switch dst.Op {
-	case OpAnyChar:
-		// src doesn't add anything.
-	case OpAnyCharNotNL:
-		// src might add \n
-		if matchRune(src, '\n') {
-			dst.Op = OpAnyChar
-		}
-	case OpCharClass:
-		// src is simpler, so either literal or char class
-		if src.Op == OpLiteral {
-			dst.Rune = appendLiteral(dst.Rune, src.Rune[0], src.Flags)
-		} else {
-			dst.Rune = appendClass(dst.Rune, src.Rune)
-		}
-	case OpLiteral:
-		// both literal
-		if src.Rune[0] == dst.Rune[0] && src.Flags == dst.Flags {
-			break
-		}
-		dst.Op = OpCharClass
-		dst.Rune = appendLiteral(dst.Rune[:0], dst.Rune[0], dst.Flags)
-		dst.Rune = appendLiteral(dst.Rune, src.Rune[0], src.Flags)
-	}
-}
-
-// If the top of the stack is an element followed by an opVerticalBar
-// swapVerticalBar swaps the two and returns true.
-// Otherwise it returns false.
-func (p *parser) swapVerticalBar() bool {
-	// If above and below vertical bar are literal or char class,
-	// can merge into a single char class.
-	n := len(p.stack)
-	if n >= 3 && p.stack[n-2].Op == opVerticalBar && isCharClass(p.stack[n-1]) && isCharClass(p.stack[n-3]) {
-		re1 := p.stack[n-1]
-		re3 := p.stack[n-3]
-		// Make re3 the more complex of the two.
-		if re1.Op > re3.Op {
-			re1, re3 = re3, re1
-			p.stack[n-3] = re3
-		}
-		mergeCharClass(re3, re1)
-		p.reuse(re1)
-		p.stack = p.stack[:n-1]
-		return true
-	}
-
-	if n >= 2 {
-		re1 := p.stack[n-1]
-		re2 := p.stack[n-2]
-		if re2.Op == opVerticalBar {
-			if n >= 3 {
-				// Now out of reach.
-				// Clean opportunistically.
-				cleanAlt(p.stack[n-3])
-			}
-			p.stack[n-2] = re1
-			p.stack[n-1] = re2
-			return true
-		}
-	}
-	return false
-}
-
-// parseRightParen handles a ) in the input.
-func (p *parser) parseRightParen() error {
-	p.concat()
-	if p.swapVerticalBar() {
-		// pop vertical bar
-		p.stack = p.stack[:len(p.stack)-1]
-	}
-	p.alternate()
-
-	n := len(p.stack)
-	if n < 2 {
-		return &Error{ErrUnexpectedParen, p.wholeRegexp}
-	}
-	re1 := p.stack[n-1]
-	re2 := p.stack[n-2]
-	p.stack = p.stack[:n-2]
-	if re2.Op != opLeftParen {
-		return &Error{ErrUnexpectedParen, p.wholeRegexp}
-	}
-	// Restore flags at time of paren.
-	p.flags = re2.Flags
-	if re2.Cap == 0 {
-		// Just for grouping.
-		p.push(re1)
-	} else {
-		re2.Op = OpCapture
-		re2.Sub = re2.Sub0[:1]
-		re2.Sub[0] = re1
-		p.push(re2)
-	}
-	return nil
-}
-
-// parseEscape parses an escape sequence at the beginning of s
-// and returns the rune.
-func (p *parser) parseEscape(s string) (r rune, rest string, err error) {
-	t := s[1:]
-	if t == "" {
-		return 0, "", &Error{ErrTrailingBackslash, ""}
-	}
-	c, t, err := nextRune(t)
-	if err != nil {
-		return 0, "", err
-	}
-
-Switch:
-	switch c {
-	default:
-		if c < utf8.RuneSelf && !isalnum(c) {
-			// Escaped non-word characters are always themselves.
-			// PCRE is not quite so rigorous: it accepts things like
-			// \q, but we don't.  We once rejected \_, but too many
-			// programs and people insist on using it, so allow \_.
-			return c, t, nil
-		}
-
-	// Octal escapes.
-	case '1', '2', '3', '4', '5', '6', '7':
-		// Single non-zero digit is a backreference; not supported
-		if t == "" || t[0] < '0' || t[0] > '7' {
-			break
-		}
-		fallthrough
-	case '0':
-		// Consume up to three octal digits; already have one.
-		r = c - '0'
-		for i := 1; i < 3; i++ {
-			if t == "" || t[0] < '0' || t[0] > '7' {
-				break
-			}
-			r = r*8 + rune(t[0]) - '0'
-			t = t[1:]
-		}
-		return r, t, nil
-
-	// Hexadecimal escapes.
-	case 'x':
-		if t == "" {
-			break
-		}
-		if c, t, err = nextRune(t); err != nil {
-			return 0, "", err
-		}
-		if c == '{' {
-			// Any number of digits in braces.
-			// Perl accepts any text at all; it ignores all text
-			// after the first non-hex digit.  We require only hex digits,
-			// and at least one.
-			nhex := 0
-			r = 0
-			for {
-				if t == "" {
-					break Switch
-				}
-				if c, t, err = nextRune(t); err != nil {
-					return 0, "", err
-				}
-				if c == '}' {
-					break
-				}
-				v := unhex(c)
-				if v < 0 {
-					break Switch
-				}
-				r = r*16 + v
-				if r > unicode.MaxRune {
-					break Switch
-				}
-				nhex++
-			}
-			if nhex == 0 {
-				break Switch
-			}
-			return r, t, nil
-		}
-
-		// Easy case: two hex digits.
-		x := unhex(c)
-		if c, t, err = nextRune(t); err != nil {
-			return 0, "", err
-		}
-		y := unhex(c)
-		if x < 0 || y < 0 {
-			break
-		}
-		return x*16 + y, t, nil
-
-	// C escapes.  There is no case 'b', to avoid misparsing
-	// the Perl word-boundary \b as the C backspace \b
-	// when in POSIX mode.  In Perl, /\b/ means word-boundary
-	// but /[\b]/ means backspace.  We don't support that.
-	// If you want a backspace, embed a literal backspace
-	// character or use \x08.
-	case 'a':
-		return '\a', t, err
-	case 'f':
-		return '\f', t, err
-	case 'n':
-		return '\n', t, err
-	case 'r':
-		return '\r', t, err
-	case 't':
-		return '\t', t, err
-	case 'v':
-		return '\v', t, err
-	}
-	return 0, "", &Error{ErrInvalidEscape, s[:len(s)-len(t)]}
-}
-
-// parseClassChar parses a character class character at the beginning of s
-// and returns it.
-func (p *parser) parseClassChar(s, wholeClass string) (r rune, rest string, err error) {
-	if s == "" {
-		return 0, "", &Error{Code: ErrMissingBracket, Expr: wholeClass}
-	}
-
-	// Allow regular escape sequences even though
-	// many need not be escaped in this context.
-	if s[0] == '\\' {
-		return p.parseEscape(s)
-	}
-
-	return nextRune(s)
-}
-
-type charGroup struct {
-	sign  int
-	class []rune
-}
-
-// parsePerlClassEscape parses a leading Perl character class escape like \d
-// from the beginning of s.  If one is present, it appends the characters to r
-// and returns the new slice r and the remainder of the string.
-func (p *parser) parsePerlClassEscape(s string, r []rune) (out []rune, rest string) {
-	if p.flags&PerlX == 0 || len(s) < 2 || s[0] != '\\' {
-		return
-	}
-	g := perlGroup[s[0:2]]
-	if g.sign == 0 {
-		return
-	}
-	return p.appendGroup(r, g), s[2:]
-}
-
-// parseNamedClass parses a leading POSIX named character class like [:alnum:]
-// from the beginning of s.  If one is present, it appends the characters to r
-// and returns the new slice r and the remainder of the string.
-func (p *parser) parseNamedClass(s string, r []rune) (out []rune, rest string, err error) {
-	if len(s) < 2 || s[0] != '[' || s[1] != ':' {
-		return
-	}
-
-	i := strings.Index(s[2:], ":]")
-	if i < 0 {
-		return
-	}
-	i += 2
-	name, s := s[0:i+2], s[i+2:]
-	g := posixGroup[name]
-	if g.sign == 0 {
-		return nil, "", &Error{ErrInvalidCharRange, name}
-	}
-	return p.appendGroup(r, g), s, nil
-}
-
-func (p *parser) appendGroup(r []rune, g charGroup) []rune {
-	if p.flags&FoldCase == 0 {
-		if g.sign < 0 {
-			r = appendNegatedClass(r, g.class)
-		} else {
-			r = appendClass(r, g.class)
-		}
-	} else {
-		tmp := p.tmpClass[:0]
-		tmp = appendFoldedClass(tmp, g.class)
-		p.tmpClass = tmp
-		tmp = cleanClass(&p.tmpClass)
-		if g.sign < 0 {
-			r = appendNegatedClass(r, tmp)
-		} else {
-			r = appendClass(r, tmp)
-		}
-	}
-	return r
-}
-
-var anyTable = &unicode.RangeTable{
-	R16: []unicode.Range16{{Lo: 0, Hi: 1<<16 - 1, Stride: 1}},
-	R32: []unicode.Range32{{Lo: 1 << 16, Hi: unicode.MaxRune, Stride: 1}},
-}
-
-// unicodeTable returns the unicode.RangeTable identified by name
-// and the table of additional fold-equivalent code points.
-func unicodeTable(name string) (*unicode.RangeTable, *unicode.RangeTable) {
-	// Special case: "Any" means any.
-	if name == "Any" {
-		return anyTable, anyTable
-	}
-	if t := unicode.Categories[name]; t != nil {
-		return t, unicode.FoldCategory[name]
-	}
-	if t := unicode.Scripts[name]; t != nil {
-		return t, unicode.FoldScript[name]
-	}
-	return nil, nil
-}
-
-// parseUnicodeClass parses a leading Unicode character class like \p{Han}
-// from the beginning of s.  If one is present, it appends the characters to r
-// and returns the new slice r and the remainder of the string.
-func (p *parser) parseUnicodeClass(s string, r []rune) (out []rune, rest string, err error) {
-	if p.flags&UnicodeGroups == 0 || len(s) < 2 || s[0] != '\\' || s[1] != 'p' && s[1] != 'P' {
-		return
-	}
-
-	// Committed to parse or return error.
-	sign := +1
-	if s[1] == 'P' {
-		sign = -1
-	}
-	t := s[2:]
-	c, t, err := nextRune(t)
-	if err != nil {
-		return
-	}
-	var seq, name string
-	if c != '{' {
-		// Single-letter name.
-		seq = s[:len(s)-len(t)]
-		name = seq[2:]
-	} else {
-		// Name is in braces.
-		end := strings.IndexRune(s, '}')
-		if end < 0 {
-			if err = checkUTF8(s); err != nil {
-				return
-			}
-			return nil, "", &Error{ErrInvalidCharRange, s}
-		}
-		seq, t = s[:end+1], s[end+1:]
-		name = s[3:end]
-		if err = checkUTF8(name); err != nil {
-			return
-		}
-	}
-
-	// Group can have leading negation too.  \p{^Han} == \P{Han}, \P{^Han} == \p{Han}.
-	if name != "" && name[0] == '^' {
-		sign = -sign
-		name = name[1:]
-	}
-
-	tab, fold := unicodeTable(name)
-	if tab == nil {
-		return nil, "", &Error{ErrInvalidCharRange, seq}
-	}
-
-	if p.flags&FoldCase == 0 || fold == nil {
-		if sign > 0 {
-			r = appendTable(r, tab)
-		} else {
-			r = appendNegatedTable(r, tab)
-		}
-	} else {
-		// Merge and clean tab and fold in a temporary buffer.
-		// This is necessary for the negative case and just tidy
-		// for the positive case.
-		tmp := p.tmpClass[:0]
-		tmp = appendTable(tmp, tab)
-		tmp = appendTable(tmp, fold)
-		p.tmpClass = tmp
-		tmp = cleanClass(&p.tmpClass)
-		if sign > 0 {
-			r = appendClass(r, tmp)
-		} else {
-			r = appendNegatedClass(r, tmp)
-		}
-	}
-	return r, t, nil
-}
-
-// parseClass parses a character class at the beginning of s
-// and pushes it onto the parse stack.
-func (p *parser) parseClass(s string) (rest string, err error) {
-	t := s[1:] // chop [
-	re := p.newRegexp(OpCharClass)
-	re.Flags = p.flags
-	re.Rune = re.Rune0[:0]
-
-	sign := +1
-	if t != "" && t[0] == '^' {
-		sign = -1
-		t = t[1:]
-
-		// If character class does not match \n, add it here,
-		// so that negation later will do the right thing.
-		if p.flags&ClassNL == 0 {
-			re.Rune = append(re.Rune, '\n', '\n')
-		}
-	}
-
-	class := re.Rune
-	first := true // ] and - are okay as first char in class
-	for t == "" || t[0] != ']' || first {
-		// POSIX: - is only okay unescaped as first or last in class.
-		// Perl: - is okay anywhere.
-		if t != "" && t[0] == '-' && p.flags&PerlX == 0 && !first && (len(t) == 1 || t[1] != ']') {
-			_, size := utf8.DecodeRuneInString(t[1:])
-			return "", &Error{Code: ErrInvalidCharRange, Expr: t[:1+size]}
-		}
-		first = false
-
-		// Look for POSIX [:alnum:] etc.
-		if len(t) > 2 && t[0] == '[' && t[1] == ':' {
-			nclass, nt, err := p.parseNamedClass(t, class)
-			if err != nil {
-				return "", err
-			}
-			if nclass != nil {
-				class, t = nclass, nt
-				continue
-			}
-		}
-
-		// Look for Unicode character group like \p{Han}.
-		nclass, nt, err := p.parseUnicodeClass(t, class)
-		if err != nil {
-			return "", err
-		}
-		if nclass != nil {
-			class, t = nclass, nt
-			continue
-		}
-
-		// Look for Perl character class symbols (extension).
-		if nclass, nt := p.parsePerlClassEscape(t, class); nclass != nil {
-			class, t = nclass, nt
-			continue
-		}
-
-		// Single character or simple range.
-		rng := t
-		var lo, hi rune
-		if lo, t, err = p.parseClassChar(t, s); err != nil {
-			return "", err
-		}
-		hi = lo
-		// [a-] means (a|-) so check for final ].
-		if len(t) >= 2 && t[0] == '-' && t[1] != ']' {
-			t = t[1:]
-			if hi, t, err = p.parseClassChar(t, s); err != nil {
-				return "", err
-			}
-			if hi < lo {
-				rng = rng[:len(rng)-len(t)]
-				return "", &Error{Code: ErrInvalidCharRange, Expr: rng}
-			}
-		}
-		if p.flags&FoldCase == 0 {
-			class = appendRange(class, lo, hi)
-		} else {
-			class = appendFoldedRange(class, lo, hi)
-		}
-	}
-	t = t[1:] // chop ]
-
-	// Use &re.Rune instead of &class to avoid allocation.
-	re.Rune = class
-	class = cleanClass(&re.Rune)
-	if sign < 0 {
-		class = negateClass(class)
-	}
-	re.Rune = class
-	p.push(re)
-	return t, nil
-}
-
-// cleanClass sorts the ranges (pairs of elements of r),
-// merges them, and eliminates duplicates.
-func cleanClass(rp *[]rune) []rune {
-
-	// Sort by lo increasing, hi decreasing to break ties.
-	sort.Sort(ranges{rp})
-
-	r := *rp
-	if len(r) < 2 {
-		return r
-	}
-
-	// Merge abutting, overlapping.
-	w := 2 // write index
-	for i := 2; i < len(r); i += 2 {
-		lo, hi := r[i], r[i+1]
-		if lo <= r[w-1]+1 {
-			// merge with previous range
-			if hi > r[w-1] {
-				r[w-1] = hi
-			}
-			continue
-		}
-		// new disjoint range
-		r[w] = lo
-		r[w+1] = hi
-		w += 2
-	}
-
-	return r[:w]
-}
-
-// appendLiteral returns the result of appending the literal x to the class r.
-func appendLiteral(r []rune, x rune, flags Flags) []rune {
-	if flags&FoldCase != 0 {
-		return appendFoldedRange(r, x, x)
-	}
-	return appendRange(r, x, x)
-}
-
-// appendRange returns the result of appending the range lo-hi to the class r.
-func appendRange(r []rune, lo, hi rune) []rune {
-	// Expand last range or next to last range if it overlaps or abuts.
-	// Checking two ranges helps when appending case-folded
-	// alphabets, so that one range can be expanding A-Z and the
-	// other expanding a-z.
-	n := len(r)
-	for i := 2; i <= 4; i += 2 { // twice, using i=2, i=4
-		if n >= i {
-			rlo, rhi := r[n-i], r[n-i+1]
-			if lo <= rhi+1 && rlo <= hi+1 {
-				if lo < rlo {
-					r[n-i] = lo
-				}
-				if hi > rhi {
-					r[n-i+1] = hi
-				}
-				return r
-			}
-		}
-	}
-
-	return append(r, lo, hi)
-}
-
-const (
-	// minimum and maximum runes involved in folding.
-	// checked during test.
-	minFold = 0x0041
-	maxFold = 0x1044f
-)
-
-// appendFoldedRange returns the result of appending the range lo-hi
-// and its case folding-equivalent runes to the class r.
-func appendFoldedRange(r []rune, lo, hi rune) []rune {
-	// Optimizations.
-	if lo <= minFold && hi >= maxFold {
-		// Range is full: folding can't add more.
-		return appendRange(r, lo, hi)
-	}
-	if hi < minFold || lo > maxFold {
-		// Range is outside folding possibilities.
-		return appendRange(r, lo, hi)
-	}
-	if lo < minFold {
-		// [lo, minFold-1] needs no folding.
-		r = appendRange(r, lo, minFold-1)
-		lo = minFold
-	}
-	if hi > maxFold {
-		// [maxFold+1, hi] needs no folding.
-		r = appendRange(r, maxFold+1, hi)
-		hi = maxFold
-	}
-
-	// Brute force.  Depend on appendRange to coalesce ranges on the fly.
-	for c := lo; c <= hi; c++ {
-		r = appendRange(r, c, c)
-		f := unicode.SimpleFold(c)
-		for f != c {
-			r = appendRange(r, f, f)
-			f = unicode.SimpleFold(f)
-		}
-	}
-	return r
-}
-
-// appendClass returns the result of appending the class x to the class r.
-// It assume x is clean.
-func appendClass(r []rune, x []rune) []rune {
-	for i := 0; i < len(x); i += 2 {
-		r = appendRange(r, x[i], x[i+1])
-	}
-	return r
-}
-
-// appendFolded returns the result of appending the case folding of the class x to the class r.
-func appendFoldedClass(r []rune, x []rune) []rune {
-	for i := 0; i < len(x); i += 2 {
-		r = appendFoldedRange(r, x[i], x[i+1])
-	}
-	return r
-}
-
-// appendNegatedClass returns the result of appending the negation of the class x to the class r.
-// It assumes x is clean.
-func appendNegatedClass(r []rune, x []rune) []rune {
-	nextLo := '\u0000'
-	for i := 0; i < len(x); i += 2 {
-		lo, hi := x[i], x[i+1]
-		if nextLo <= lo-1 {
-			r = appendRange(r, nextLo, lo-1)
-		}
-		nextLo = hi + 1
-	}
-	if nextLo <= unicode.MaxRune {
-		r = appendRange(r, nextLo, unicode.MaxRune)
-	}
-	return r
-}
-
-// appendTable returns the result of appending x to the class r.
-func appendTable(r []rune, x *unicode.RangeTable) []rune {
-	for _, xr := range x.R16 {
-		lo, hi, stride := rune(xr.Lo), rune(xr.Hi), rune(xr.Stride)
-		if stride == 1 {
-			r = appendRange(r, lo, hi)
-			continue
-		}
-		for c := lo; c <= hi; c += stride {
-			r = appendRange(r, c, c)
-		}
-	}
-	for _, xr := range x.R32 {
-		lo, hi, stride := rune(xr.Lo), rune(xr.Hi), rune(xr.Stride)
-		if stride == 1 {
-			r = appendRange(r, lo, hi)
-			continue
-		}
-		for c := lo; c <= hi; c += stride {
-			r = appendRange(r, c, c)
-		}
-	}
-	return r
-}
-
-// appendNegatedTable returns the result of appending the negation of x to the class r.
-func appendNegatedTable(r []rune, x *unicode.RangeTable) []rune {
-	nextLo := '\u0000' // lo end of next class to add
-	for _, xr := range x.R16 {
-		lo, hi, stride := rune(xr.Lo), rune(xr.Hi), rune(xr.Stride)
-		if stride == 1 {
-			if nextLo <= lo-1 {
-				r = appendRange(r, nextLo, lo-1)
-			}
-			nextLo = hi + 1
-			continue
-		}
-		for c := lo; c <= hi; c += stride {
-			if nextLo <= c-1 {
-				r = appendRange(r, nextLo, c-1)
-			}
-			nextLo = c + 1
-		}
-	}
-	for _, xr := range x.R32 {
-		lo, hi, stride := rune(xr.Lo), rune(xr.Hi), rune(xr.Stride)
-		if stride == 1 {
-			if nextLo <= lo-1 {
-				r = appendRange(r, nextLo, lo-1)
-			}
-			nextLo = hi + 1
-			continue
-		}
-		for c := lo; c <= hi; c += stride {
-			if nextLo <= c-1 {
-				r = appendRange(r, nextLo, c-1)
-			}
-			nextLo = c + 1
-		}
-	}
-	if nextLo <= unicode.MaxRune {
-		r = appendRange(r, nextLo, unicode.MaxRune)
-	}
-	return r
-}
-
-// negateClass overwrites r and returns r's negation.
-// It assumes the class r is already clean.
-func negateClass(r []rune) []rune {
-	nextLo := '\u0000' // lo end of next class to add
-	w := 0             // write index
-	for i := 0; i < len(r); i += 2 {
-		lo, hi := r[i], r[i+1]
-		if nextLo <= lo-1 {
-			r[w] = nextLo
-			r[w+1] = lo - 1
-			w += 2
-		}
-		nextLo = hi + 1
-	}
-	r = r[:w]
-	if nextLo <= unicode.MaxRune {
-		// It's possible for the negation to have one more
-		// range - this one - than the original class, so use append.
-		r = append(r, nextLo, unicode.MaxRune)
-	}
-	return r
-}
-
-// ranges implements sort.Interface on a []rune.
-// The choice of receiver type definition is strange
-// but avoids an allocation since we already have
-// a *[]rune.
-type ranges struct {
-	p *[]rune
-}
-
-func (ra ranges) Less(i, j int) bool {
-	p := *ra.p
-	i *= 2
-	j *= 2
-	return p[i] < p[j] || p[i] == p[j] && p[i+1] > p[j+1]
-}
-
-func (ra ranges) Len() int {
-	return len(*ra.p) / 2
-}
-
-func (ra ranges) Swap(i, j int) {
-	p := *ra.p
-	i *= 2
-	j *= 2
-	p[i], p[i+1], p[j], p[j+1] = p[j], p[j+1], p[i], p[i+1]
-}
-
-func checkUTF8(s string) error {
-	for s != "" {
-		rune, size := utf8.DecodeRuneInString(s)
-		if rune == utf8.RuneError && size == 1 {
-			return &Error{Code: ErrInvalidUTF8, Expr: s}
-		}
-		s = s[size:]
-	}
-	return nil
-}
-
-func nextRune(s string) (c rune, t string, err error) {
-	c, size := utf8.DecodeRuneInString(s)
-	if c == utf8.RuneError && size == 1 {
-		return 0, "", &Error{Code: ErrInvalidUTF8, Expr: s}
-	}
-	return c, s[size:], nil
-}
-
-func isalnum(c rune) bool {
-	return '0' <= c && c <= '9' || 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z'
-}
-
-func unhex(c rune) rune {
-	if '0' <= c && c <= '9' {
-		return c - '0'
-	}
-	if 'a' <= c && c <= 'f' {
-		return c - 'a' + 10
-	}
-	if 'A' <= c && c <= 'F' {
-		return c - 'A' + 10
-	}
-	return -1
-}
diff --git a/src/pkg/regexp/syntax/parse_test.go b/src/pkg/regexp/syntax/parse_test.go
deleted file mode 100644
index f308929..0000000
--- a/src/pkg/regexp/syntax/parse_test.go
+++ /dev/null
@@ -1,559 +0,0 @@
-// Copyright 2011 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package syntax
-
-import (
-	"bytes"
-	"fmt"
-	"testing"
-	"unicode"
-)
-
-type parseTest struct {
-	Regexp string
-	Dump   string
-}
-
-var parseTests = []parseTest{
-	// Base cases
-	{`a`, `lit{a}`},
-	{`a.`, `cat{lit{a}dot{}}`},
-	{`a.b`, `cat{lit{a}dot{}lit{b}}`},
-	{`ab`, `str{ab}`},
-	{`a.b.c`, `cat{lit{a}dot{}lit{b}dot{}lit{c}}`},
-	{`abc`, `str{abc}`},
-	{`a|^`, `alt{lit{a}bol{}}`},
-	{`a|b`, `cc{0x61-0x62}`},
-	{`(a)`, `cap{lit{a}}`},
-	{`(a)|b`, `alt{cap{lit{a}}lit{b}}`},
-	{`a*`, `star{lit{a}}`},
-	{`a+`, `plus{lit{a}}`},
-	{`a?`, `que{lit{a}}`},
-	{`a{2}`, `rep{2,2 lit{a}}`},
-	{`a{2,3}`, `rep{2,3 lit{a}}`},
-	{`a{2,}`, `rep{2,-1 lit{a}}`},
-	{`a*?`, `nstar{lit{a}}`},
-	{`a+?`, `nplus{lit{a}}`},
-	{`a??`, `nque{lit{a}}`},
-	{`a{2}?`, `nrep{2,2 lit{a}}`},
-	{`a{2,3}?`, `nrep{2,3 lit{a}}`},
-	{`a{2,}?`, `nrep{2,-1 lit{a}}`},
-	// Malformed { } are treated as literals.
-	{`x{1001`, `str{x{1001}`},
-	{`x{9876543210`, `str{x{9876543210}`},
-	{`x{9876543210,`, `str{x{9876543210,}`},
-	{`x{2,1`, `str{x{2,1}`},
-	{`x{1,9876543210`, `str{x{1,9876543210}`},
-	{``, `emp{}`},
-	{`|`, `emp{}`}, // alt{emp{}emp{}} but got factored
-	{`|x|`, `alt{emp{}lit{x}emp{}}`},
-	{`.`, `dot{}`},
-	{`^`, `bol{}`},
-	{`$`, `eol{}`},
-	{`\|`, `lit{|}`},
-	{`\(`, `lit{(}`},
-	{`\)`, `lit{)}`},
-	{`\*`, `lit{*}`},
-	{`\+`, `lit{+}`},
-	{`\?`, `lit{?}`},
-	{`{`, `lit{{}`},
-	{`}`, `lit{}}`},
-	{`\.`, `lit{.}`},
-	{`\^`, `lit{^}`},
-	{`\$`, `lit{$}`},
-	{`\\`, `lit{\}`},
-	{`[ace]`, `cc{0x61 0x63 0x65}`},
-	{`[abc]`, `cc{0x61-0x63}`},
-	{`[a-z]`, `cc{0x61-0x7a}`},
-	{`[a]`, `lit{a}`},
-	{`\-`, `lit{-}`},
-	{`-`, `lit{-}`},
-	{`\_`, `lit{_}`},
-	{`abc`, `str{abc}`},
-	{`abc|def`, `alt{str{abc}str{def}}`},
-	{`abc|def|ghi`, `alt{str{abc}str{def}str{ghi}}`},
-
-	// Posix and Perl extensions
-	{`[[:lower:]]`, `cc{0x61-0x7a}`},
-	{`[a-z]`, `cc{0x61-0x7a}`},
-	{`[^[:lower:]]`, `cc{0x0-0x60 0x7b-0x10ffff}`},
-	{`[[:^lower:]]`, `cc{0x0-0x60 0x7b-0x10ffff}`},
-	{`(?i)[[:lower:]]`, `cc{0x41-0x5a 0x61-0x7a 0x17f 0x212a}`},
-	{`(?i)[a-z]`, `cc{0x41-0x5a 0x61-0x7a 0x17f 0x212a}`},
-	{`(?i)[^[:lower:]]`, `cc{0x0-0x40 0x5b-0x60 0x7b-0x17e 0x180-0x2129 0x212b-0x10ffff}`},
-	{`(?i)[[:^lower:]]`, `cc{0x0-0x40 0x5b-0x60 0x7b-0x17e 0x180-0x2129 0x212b-0x10ffff}`},
-	{`\d`, `cc{0x30-0x39}`},
-	{`\D`, `cc{0x0-0x2f 0x3a-0x10ffff}`},
-	{`\s`, `cc{0x9-0xa 0xc-0xd 0x20}`},
-	{`\S`, `cc{0x0-0x8 0xb 0xe-0x1f 0x21-0x10ffff}`},
-	{`\w`, `cc{0x30-0x39 0x41-0x5a 0x5f 0x61-0x7a}`},
-	{`\W`, `cc{0x0-0x2f 0x3a-0x40 0x5b-0x5e 0x60 0x7b-0x10ffff}`},
-	{`(?i)\w`, `cc{0x30-0x39 0x41-0x5a 0x5f 0x61-0x7a 0x17f 0x212a}`},
-	{`(?i)\W`, `cc{0x0-0x2f 0x3a-0x40 0x5b-0x5e 0x60 0x7b-0x17e 0x180-0x2129 0x212b-0x10ffff}`},
-	{`[^\\]`, `cc{0x0-0x5b 0x5d-0x10ffff}`},
-	//	{ `\C`, `byte{}` },  // probably never
-
-	// Unicode, negatives, and a double negative.
-	{`\p{Braille}`, `cc{0x2800-0x28ff}`},
-	{`\P{Braille}`, `cc{0x0-0x27ff 0x2900-0x10ffff}`},
-	{`\p{^Braille}`, `cc{0x0-0x27ff 0x2900-0x10ffff}`},
-	{`\P{^Braille}`, `cc{0x2800-0x28ff}`},
-	{`\pZ`, `cc{0x20 0xa0 0x1680 0x2000-0x200a 0x2028-0x2029 0x202f 0x205f 0x3000}`},
-	{`[\p{Braille}]`, `cc{0x2800-0x28ff}`},
-	{`[\P{Braille}]`, `cc{0x0-0x27ff 0x2900-0x10ffff}`},
-	{`[\p{^Braille}]`, `cc{0x0-0x27ff 0x2900-0x10ffff}`},
-	{`[\P{^Braille}]`, `cc{0x2800-0x28ff}`},
-	{`[\pZ]`, `cc{0x20 0xa0 0x1680 0x2000-0x200a 0x2028-0x2029 0x202f 0x205f 0x3000}`},
-	{`\p{Lu}`, mkCharClass(unicode.IsUpper)},
-	{`[\p{Lu}]`, mkCharClass(unicode.IsUpper)},
-	{`(?i)[\p{Lu}]`, mkCharClass(isUpperFold)},
-	{`\p{Any}`, `dot{}`},
-	{`\p{^Any}`, `cc{}`},
-
-	// Hex, octal.
-	{`[\012-\234]\141`, `cat{cc{0xa-0x9c}lit{a}}`},
-	{`[\x{41}-\x7a]\x61`, `cat{cc{0x41-0x7a}lit{a}}`},
-
-	// More interesting regular expressions.
-	{`a{,2}`, `str{a{,2}}`},
-	{`\.\^\$\\`, `str{.^$\}`},
-	{`[a-zABC]`, `cc{0x41-0x43 0x61-0x7a}`},
-	{`[^a]`, `cc{0x0-0x60 0x62-0x10ffff}`},
-	{`[α-ε☺]`, `cc{0x3b1-0x3b5 0x263a}`}, // utf-8
-	{`a*{`, `cat{star{lit{a}}lit{{}}`},
-
-	// Test precedences
-	{`(?:ab)*`, `star{str{ab}}`},
-	{`(ab)*`, `star{cap{str{ab}}}`},
-	{`ab|cd`, `alt{str{ab}str{cd}}`},
-	{`a(b|c)d`, `cat{lit{a}cap{cc{0x62-0x63}}lit{d}}`},
-
-	// Test flattening.
-	{`(?:a)`, `lit{a}`},
-	{`(?:ab)(?:cd)`, `str{abcd}`},
-	{`(?:a+b+)(?:c+d+)`, `cat{plus{lit{a}}plus{lit{b}}plus{lit{c}}plus{lit{d}}}`},
-	{`(?:a+|b+)|(?:c+|d+)`, `alt{plus{lit{a}}plus{lit{b}}plus{lit{c}}plus{lit{d}}}`},
-	{`(?:a|b)|(?:c|d)`, `cc{0x61-0x64}`},
-	{`a|.`, `dot{}`},
-	{`.|a`, `dot{}`},
-	{`(?:[abc]|A|Z|hello|world)`, `alt{cc{0x41 0x5a 0x61-0x63}str{hello}str{world}}`},
-	{`(?:[abc]|A|Z)`, `cc{0x41 0x5a 0x61-0x63}`},
-
-	// Test Perl quoted literals
-	{`\Q+|*?{[\E`, `str{+|*?{[}`},
-	{`\Q+\E+`, `plus{lit{+}}`},
-	{`\Q\\E`, `lit{\}`},
-	{`\Q\\\E`, `str{\\}`},
-
-	// Test Perl \A and \z
-	{`(?m)^`, `bol{}`},
-	{`(?m)$`, `eol{}`},
-	{`(?-m)^`, `bot{}`},
-	{`(?-m)$`, `eot{}`},
-	{`(?m)\A`, `bot{}`},
-	{`(?m)\z`, `eot{\z}`},
-	{`(?-m)\A`, `bot{}`},
-	{`(?-m)\z`, `eot{\z}`},
-
-	// Test named captures
-	{`(?P<name>a)`, `cap{name:lit{a}}`},
-
-	// Case-folded literals
-	{`[Aa]`, `litfold{A}`},
-	{`[\x{100}\x{101}]`, `litfold{Ā}`},
-	{`[Δδ]`, `litfold{Δ}`},
-
-	// Strings
-	{`abcde`, `str{abcde}`},
-	{`[Aa][Bb]cd`, `cat{strfold{AB}str{cd}}`},
-
-	// Factoring.
-	{`abc|abd|aef|bcx|bcy`, `alt{cat{lit{a}alt{cat{lit{b}cc{0x63-0x64}}str{ef}}}cat{str{bc}cc{0x78-0x79}}}`},
-	{`ax+y|ax+z|ay+w`, `cat{lit{a}alt{cat{plus{lit{x}}cc{0x79-0x7a}}cat{plus{lit{y}}lit{w}}}}`},
-
-	// Bug fixes.
-	{`(?:.)`, `dot{}`},
-	{`(?:x|(?:xa))`, `cat{lit{x}alt{emp{}lit{a}}}`},
-	{`(?:.|(?:.a))`, `cat{dot{}alt{emp{}lit{a}}}`},
-	{`(?:A(?:A|a))`, `cat{lit{A}litfold{A}}`},
-	{`(?:A|a)`, `litfold{A}`},
-	{`A|(?:A|a)`, `litfold{A}`},
-	{`(?s).`, `dot{}`},
-	{`(?-s).`, `dnl{}`},
-	{`(?:(?:^).)`, `cat{bol{}dot{}}`},
-	{`(?-s)(?:(?:^).)`, `cat{bol{}dnl{}}`},
-
-	// RE2 prefix_tests
-	{`abc|abd`, `cat{str{ab}cc{0x63-0x64}}`},
-	{`a(?:b)c|abd`, `cat{str{ab}cc{0x63-0x64}}`},
-	{`abc|abd|aef|bcx|bcy`,
-		`alt{cat{lit{a}alt{cat{lit{b}cc{0x63-0x64}}str{ef}}}` +
-			`cat{str{bc}cc{0x78-0x79}}}`},
-	{`abc|x|abd`, `alt{str{abc}lit{x}str{abd}}`},
-	{`(?i)abc|ABD`, `cat{strfold{AB}cc{0x43-0x44 0x63-0x64}}`},
-	{`[ab]c|[ab]d`, `cat{cc{0x61-0x62}cc{0x63-0x64}}`},
-	{`(?:xx|yy)c|(?:xx|yy)d`,
-		`cat{alt{str{xx}str{yy}}cc{0x63-0x64}}`},
-	{`x{2}|x{2}[0-9]`,
-		`cat{rep{2,2 lit{x}}alt{emp{}cc{0x30-0x39}}}`},
-	{`x{2}y|x{2}[0-9]y`,
-		`cat{rep{2,2 lit{x}}alt{lit{y}cat{cc{0x30-0x39}lit{y}}}}`},
-}
-
-const testFlags = MatchNL | PerlX | UnicodeGroups
-
-func TestParseSimple(t *testing.T) {
-	testParseDump(t, parseTests, testFlags)
-}
-
-var foldcaseTests = []parseTest{
-	{`AbCdE`, `strfold{ABCDE}`},
-	{`[Aa]`, `litfold{A}`},
-	{`a`, `litfold{A}`},
-
-	// 0x17F is an old English long s (looks like an f) and folds to s.
-	// 0x212A is the Kelvin symbol and folds to k.
-	{`A[F-g]`, `cat{litfold{A}cc{0x41-0x7a 0x17f 0x212a}}`}, // [Aa][A-z...]
-	{`[[:upper:]]`, `cc{0x41-0x5a 0x61-0x7a 0x17f 0x212a}`},
-	{`[[:lower:]]`, `cc{0x41-0x5a 0x61-0x7a 0x17f 0x212a}`},
-}
-
-func TestParseFoldCase(t *testing.T) {
-	testParseDump(t, foldcaseTests, FoldCase)
-}
-
-var literalTests = []parseTest{
-	{"(|)^$.[*+?]{5,10},\\", "str{(|)^$.[*+?]{5,10},\\}"},
-}
-
-func TestParseLiteral(t *testing.T) {
-	testParseDump(t, literalTests, Literal)
-}
-
-var matchnlTests = []parseTest{
-	{`.`, `dot{}`},
-	{"\n", "lit{\n}"},
-	{`[^a]`, `cc{0x0-0x60 0x62-0x10ffff}`},
-	{`[a\n]`, `cc{0xa 0x61}`},
-}
-
-func TestParseMatchNL(t *testing.T) {
-	testParseDump(t, matchnlTests, MatchNL)
-}
-
-var nomatchnlTests = []parseTest{
-	{`.`, `dnl{}`},
-	{"\n", "lit{\n}"},
-	{`[^a]`, `cc{0x0-0x9 0xb-0x60 0x62-0x10ffff}`},
-	{`[a\n]`, `cc{0xa 0x61}`},
-}
-
-func TestParseNoMatchNL(t *testing.T) {
-	testParseDump(t, nomatchnlTests, 0)
-}
-
-// Test Parse -> Dump.
-func testParseDump(t *testing.T, tests []parseTest, flags Flags) {
-	for _, tt := range tests {
-		re, err := Parse(tt.Regexp, flags)
-		if err != nil {
-			t.Errorf("Parse(%#q): %v", tt.Regexp, err)
-			continue
-		}
-		d := dump(re)
-		if d != tt.Dump {
-			t.Errorf("Parse(%#q).Dump() = %#q want %#q", tt.Regexp, d, tt.Dump)
-		}
-	}
-}
-
-// dump prints a string representation of the regexp showing
-// the structure explicitly.
-func dump(re *Regexp) string {
-	var b bytes.Buffer
-	dumpRegexp(&b, re)
-	return b.String()
-}
-
-var opNames = []string{
-	OpNoMatch:        "no",
-	OpEmptyMatch:     "emp",
-	OpLiteral:        "lit",
-	OpCharClass:      "cc",
-	OpAnyCharNotNL:   "dnl",
-	OpAnyChar:        "dot",
-	OpBeginLine:      "bol",
-	OpEndLine:        "eol",
-	OpBeginText:      "bot",
-	OpEndText:        "eot",
-	OpWordBoundary:   "wb",
-	OpNoWordBoundary: "nwb",
-	OpCapture:        "cap",
-	OpStar:           "star",
-	OpPlus:           "plus",
-	OpQuest:          "que",
-	OpRepeat:         "rep",
-	OpConcat:         "cat",
-	OpAlternate:      "alt",
-}
-
-// dumpRegexp writes an encoding of the syntax tree for the regexp re to b.
-// It is used during testing to distinguish between parses that might print
-// the same using re's String method.
-func dumpRegexp(b *bytes.Buffer, re *Regexp) {
-	if int(re.Op) >= len(opNames) || opNames[re.Op] == "" {
-		fmt.Fprintf(b, "op%d", re.Op)
-	} else {
-		switch re.Op {
-		default:
-			b.WriteString(opNames[re.Op])
-		case OpStar, OpPlus, OpQuest, OpRepeat:
-			if re.Flags&NonGreedy != 0 {
-				b.WriteByte('n')
-			}
-			b.WriteString(opNames[re.Op])
-		case OpLiteral:
-			if len(re.Rune) > 1 {
-				b.WriteString("str")
-			} else {
-				b.WriteString("lit")
-			}
-			if re.Flags&FoldCase != 0 {
-				for _, r := range re.Rune {
-					if unicode.SimpleFold(r) != r {
-						b.WriteString("fold")
-						break
-					}
-				}
-			}
-		}
-	}
-	b.WriteByte('{')
-	switch re.Op {
-	case OpEndText:
-		if re.Flags&WasDollar == 0 {
-			b.WriteString(`\z`)
-		}
-	case OpLiteral:
-		for _, r := range re.Rune {
-			b.WriteRune(r)
-		}
-	case OpConcat, OpAlternate:
-		for _, sub := range re.Sub {
-			dumpRegexp(b, sub)
-		}
-	case OpStar, OpPlus, OpQuest:
-		dumpRegexp(b, re.Sub[0])
-	case OpRepeat:
-		fmt.Fprintf(b, "%d,%d ", re.Min, re.Max)
-		dumpRegexp(b, re.Sub[0])
-	case OpCapture:
-		if re.Name != "" {
-			b.WriteString(re.Name)
-			b.WriteByte(':')
-		}
-		dumpRegexp(b, re.Sub[0])
-	case OpCharClass:
-		sep := ""
-		for i := 0; i < len(re.Rune); i += 2 {
-			b.WriteString(sep)
-			sep = " "
-			lo, hi := re.Rune[i], re.Rune[i+1]
-			if lo == hi {
-				fmt.Fprintf(b, "%#x", lo)
-			} else {
-				fmt.Fprintf(b, "%#x-%#x", lo, hi)
-			}
-		}
-	}
-	b.WriteByte('}')
-}
-
-func mkCharClass(f func(rune) bool) string {
-	re := &Regexp{Op: OpCharClass}
-	lo := rune(-1)
-	for i := rune(0); i <= unicode.MaxRune; i++ {
-		if f(i) {
-			if lo < 0 {
-				lo = i
-			}
-		} else {
-			if lo >= 0 {
-				re.Rune = append(re.Rune, lo, i-1)
-				lo = -1
-			}
-		}
-	}
-	if lo >= 0 {
-		re.Rune = append(re.Rune, lo, unicode.MaxRune)
-	}
-	return dump(re)
-}
-
-func isUpperFold(r rune) bool {
-	if unicode.IsUpper(r) {
-		return true
-	}
-	c := unicode.SimpleFold(r)
-	for c != r {
-		if unicode.IsUpper(c) {
-			return true
-		}
-		c = unicode.SimpleFold(c)
-	}
-	return false
-}
-
-func TestFoldConstants(t *testing.T) {
-	last := rune(-1)
-	for i := rune(0); i <= unicode.MaxRune; i++ {
-		if unicode.SimpleFold(i) == i {
-			continue
-		}
-		if last == -1 && minFold != i {
-			t.Errorf("minFold=%#U should be %#U", minFold, i)
-		}
-		last = i
-	}
-	if maxFold != last {
-		t.Errorf("maxFold=%#U should be %#U", maxFold, last)
-	}
-}
-
-func TestAppendRangeCollapse(t *testing.T) {
-	// AppendRange should collapse each of the new ranges
-	// into the earlier ones (it looks back two ranges), so that
-	// the slice never grows very large.
-	// Note that we are not calling cleanClass.
-	var r []rune
-	for i := rune('A'); i <= 'Z'; i++ {
-		r = appendRange(r, i, i)
-		r = appendRange(r, i+'a'-'A', i+'a'-'A')
-	}
-	if string(r) != "AZaz" {
-		t.Errorf("appendRange interlaced A-Z a-z = %s, want AZaz", string(r))
-	}
-}
-
-var invalidRegexps = []string{
-	`(`,
-	`)`,
-	`(a`,
-	`a)`,
-	`(a))`,
-	`(a|b|`,
-	`a|b|)`,
-	`(a|b|))`,
-	`(a|b`,
-	`a|b)`,
-	`(a|b))`,
-	`[a-z`,
-	`([a-z)`,
-	`[a-z)`,
-	`([a-z]))`,
-	`x{1001}`,
-	`x{9876543210}`,
-	`x{2,1}`,
-	`x{1,9876543210}`,
-	"\xff", // Invalid UTF-8
-	"[\xff]",
-	"[\\\xff]",
-	"\\\xff",
-	`(?P<name>a`,
-	`(?P<name>`,
-	`(?P<name`,
-	`(?P<x y>a)`,
-	`(?P<>a)`,
-	`[a-Z]`,
-	`(?i)[a-Z]`,
-	`a{100000}`,
-	`a{100000,}`,
-}
-
-var onlyPerl = []string{
-	`[a-b-c]`,
-	`\Qabc\E`,
-	`\Q*+?{[\E`,
-	`\Q\\E`,
-	`\Q\\\E`,
-	`\Q\\\\E`,
-	`\Q\\\\\E`,
-	`(?:a)`,
-	`(?P<name>a)`,
-}
-
-var onlyPOSIX = []string{
-	"a++",
-	"a**",
-	"a?*",
-	"a+*",
-	"a{1}*",
-	".{1}{2}.{3}",
-}
-
-func TestParseInvalidRegexps(t *testing.T) {
-	for _, regexp := range invalidRegexps {
-		if re, err := Parse(regexp, Perl); err == nil {
-			t.Errorf("Parse(%#q, Perl) = %s, should have failed", regexp, dump(re))
-		}
-		if re, err := Parse(regexp, POSIX); err == nil {
-			t.Errorf("Parse(%#q, POSIX) = %s, should have failed", regexp, dump(re))
-		}
-	}
-	for _, regexp := range onlyPerl {
-		if _, err := Parse(regexp, Perl); err != nil {
-			t.Errorf("Parse(%#q, Perl): %v", regexp, err)
-		}
-		if re, err := Parse(regexp, POSIX); err == nil {
-			t.Errorf("Parse(%#q, POSIX) = %s, should have failed", regexp, dump(re))
-		}
-	}
-	for _, regexp := range onlyPOSIX {
-		if re, err := Parse(regexp, Perl); err == nil {
-			t.Errorf("Parse(%#q, Perl) = %s, should have failed", regexp, dump(re))
-		}
-		if _, err := Parse(regexp, POSIX); err != nil {
-			t.Errorf("Parse(%#q, POSIX): %v", regexp, err)
-		}
-	}
-}
-
-func TestToStringEquivalentParse(t *testing.T) {
-	for _, tt := range parseTests {
-		re, err := Parse(tt.Regexp, testFlags)
-		if err != nil {
-			t.Errorf("Parse(%#q): %v", tt.Regexp, err)
-			continue
-		}
-		d := dump(re)
-		if d != tt.Dump {
-			t.Errorf("Parse(%#q).Dump() = %#q want %#q", tt.Regexp, d, tt.Dump)
-			continue
-		}
-
-		s := re.String()
-		if s != tt.Regexp {
-			// If ToString didn't return the original regexp,
-			// it must have found one with fewer parens.
-			// Unfortunately we can't check the length here, because
-			// ToString produces "\\{" for a literal brace,
-			// but "{" is a shorter equivalent in some contexts.
-			nre, err := Parse(s, testFlags)
-			if err != nil {
-				t.Errorf("Parse(%#q.String() = %#q): %v", tt.Regexp, s, err)
-				continue
-			}
-			nd := dump(nre)
-			if d != nd {
-				t.Errorf("Parse(%#q) -> %#q; %#q vs %#q", tt.Regexp, s, d, nd)
-			}
-
-			ns := nre.String()
-			if s != ns {
-				t.Errorf("Parse(%#q) -> %#q -> %#q", tt.Regexp, s, ns)
-			}
-		}
-	}
-}
diff --git a/src/pkg/regexp/syntax/regexp.go b/src/pkg/regexp/syntax/regexp.go
deleted file mode 100644
index 329a90e..0000000
--- a/src/pkg/regexp/syntax/regexp.go
+++ /dev/null
@@ -1,319 +0,0 @@
-// Copyright 2011 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package syntax
-
-// Note to implementers:
-// In this package, re is always a *Regexp and r is always a rune.
-
-import (
-	"bytes"
-	"strconv"
-	"strings"
-	"unicode"
-)
-
-// A Regexp is a node in a regular expression syntax tree.
-type Regexp struct {
-	Op       Op // operator
-	Flags    Flags
-	Sub      []*Regexp  // subexpressions, if any
-	Sub0     [1]*Regexp // storage for short Sub
-	Rune     []rune     // matched runes, for OpLiteral, OpCharClass
-	Rune0    [2]rune    // storage for short Rune
-	Min, Max int        // min, max for OpRepeat
-	Cap      int        // capturing index, for OpCapture
-	Name     string     // capturing name, for OpCapture
-}
-
-// An Op is a single regular expression operator.
-type Op uint8
-
-// Operators are listed in precedence order, tightest binding to weakest.
-// Character class operators are listed simplest to most complex
-// (OpLiteral, OpCharClass, OpAnyCharNotNL, OpAnyChar).
-
-const (
-	OpNoMatch        Op = 1 + iota // matches no strings
-	OpEmptyMatch                   // matches empty string
-	OpLiteral                      // matches Runes sequence
-	OpCharClass                    // matches Runes interpreted as range pair list
-	OpAnyCharNotNL                 // matches any character
-	OpAnyChar                      // matches any character
-	OpBeginLine                    // matches empty string at beginning of line
-	OpEndLine                      // matches empty string at end of line
-	OpBeginText                    // matches empty string at beginning of text
-	OpEndText                      // matches empty string at end of text
-	OpWordBoundary                 // matches word boundary `\b`
-	OpNoWordBoundary               // matches word non-boundary `\B`
-	OpCapture                      // capturing subexpression with index Cap, optional name Name
-	OpStar                         // matches Sub[0] zero or more times
-	OpPlus                         // matches Sub[0] one or more times
-	OpQuest                        // matches Sub[0] zero or one times
-	OpRepeat                       // matches Sub[0] at least Min times, at most Max (Max == -1 is no limit)
-	OpConcat                       // matches concatenation of Subs
-	OpAlternate                    // matches alternation of Subs
-)
-
-const opPseudo Op = 128 // where pseudo-ops start
-
-// Equal returns true if x and y have identical structure.
-func (x *Regexp) Equal(y *Regexp) bool {
-	if x == nil || y == nil {
-		return x == y
-	}
-	if x.Op != y.Op {
-		return false
-	}
-	switch x.Op {
-	case OpEndText:
-		// The parse flags remember whether this is \z or \Z.
-		if x.Flags&WasDollar != y.Flags&WasDollar {
-			return false
-		}
-
-	case OpLiteral, OpCharClass:
-		if len(x.Rune) != len(y.Rune) {
-			return false
-		}
-		for i, r := range x.Rune {
-			if r != y.Rune[i] {
-				return false
-			}
-		}
-
-	case OpAlternate, OpConcat:
-		if len(x.Sub) != len(y.Sub) {
-			return false
-		}
-		for i, sub := range x.Sub {
-			if !sub.Equal(y.Sub[i]) {
-				return false
-			}
-		}
-
-	case OpStar, OpPlus, OpQuest:
-		if x.Flags&NonGreedy != y.Flags&NonGreedy || !x.Sub[0].Equal(y.Sub[0]) {
-			return false
-		}
-
-	case OpRepeat:
-		if x.Flags&NonGreedy != y.Flags&NonGreedy || x.Min != y.Min || x.Max != y.Max || !x.Sub[0].Equal(y.Sub[0]) {
-			return false
-		}
-
-	case OpCapture:
-		if x.Cap != y.Cap || x.Name != y.Name || !x.Sub[0].Equal(y.Sub[0]) {
-			return false
-		}
-	}
-	return true
-}
-
-// writeRegexp writes the Perl syntax for the regular expression re to b.
-func writeRegexp(b *bytes.Buffer, re *Regexp) {
-	switch re.Op {
-	default:
-		b.WriteString("<invalid op" + strconv.Itoa(int(re.Op)) + ">")
-	case OpNoMatch:
-		b.WriteString(`[^\x00-\x{10FFFF}]`)
-	case OpEmptyMatch:
-		b.WriteString(`(?:)`)
-	case OpLiteral:
-		if re.Flags&FoldCase != 0 {
-			b.WriteString(`(?i:`)
-		}
-		for _, r := range re.Rune {
-			escape(b, r, false)
-		}
-		if re.Flags&FoldCase != 0 {
-			b.WriteString(`)`)
-		}
-	case OpCharClass:
-		if len(re.Rune)%2 != 0 {
-			b.WriteString(`[invalid char class]`)
-			break
-		}
-		b.WriteRune('[')
-		if len(re.Rune) == 0 {
-			b.WriteString(`^\x00-\x{10FFFF}`)
-		} else if re.Rune[0] == 0 && re.Rune[len(re.Rune)-1] == unicode.MaxRune {
-			// Contains 0 and MaxRune.  Probably a negated class.
-			// Print the gaps.
-			b.WriteRune('^')
-			for i := 1; i < len(re.Rune)-1; i += 2 {
-				lo, hi := re.Rune[i]+1, re.Rune[i+1]-1
-				escape(b, lo, lo == '-')
-				if lo != hi {
-					b.WriteRune('-')
-					escape(b, hi, hi == '-')
-				}
-			}
-		} else {
-			for i := 0; i < len(re.Rune); i += 2 {
-				lo, hi := re.Rune[i], re.Rune[i+1]
-				escape(b, lo, lo == '-')
-				if lo != hi {
-					b.WriteRune('-')
-					escape(b, hi, hi == '-')
-				}
-			}
-		}
-		b.WriteRune(']')
-	case OpAnyCharNotNL:
-		b.WriteString(`(?-s:.)`)
-	case OpAnyChar:
-		b.WriteString(`(?s:.)`)
-	case OpBeginLine:
-		b.WriteRune('^')
-	case OpEndLine:
-		b.WriteRune('$')
-	case OpBeginText:
-		b.WriteString(`\A`)
-	case OpEndText:
-		if re.Flags&WasDollar != 0 {
-			b.WriteString(`(?-m:$)`)
-		} else {
-			b.WriteString(`\z`)
-		}
-	case OpWordBoundary:
-		b.WriteString(`\b`)
-	case OpNoWordBoundary:
-		b.WriteString(`\B`)
-	case OpCapture:
-		if re.Name != "" {
-			b.WriteString(`(?P<`)
-			b.WriteString(re.Name)
-			b.WriteRune('>')
-		} else {
-			b.WriteRune('(')
-		}
-		if re.Sub[0].Op != OpEmptyMatch {
-			writeRegexp(b, re.Sub[0])
-		}
-		b.WriteRune(')')
-	case OpStar, OpPlus, OpQuest, OpRepeat:
-		if sub := re.Sub[0]; sub.Op > OpCapture || sub.Op == OpLiteral && len(sub.Rune) > 1 {
-			b.WriteString(`(?:`)
-			writeRegexp(b, sub)
-			b.WriteString(`)`)
-		} else {
-			writeRegexp(b, sub)
-		}
-		switch re.Op {
-		case OpStar:
-			b.WriteRune('*')
-		case OpPlus:
-			b.WriteRune('+')
-		case OpQuest:
-			b.WriteRune('?')
-		case OpRepeat:
-			b.WriteRune('{')
-			b.WriteString(strconv.Itoa(re.Min))
-			if re.Max != re.Min {
-				b.WriteRune(',')
-				if re.Max >= 0 {
-					b.WriteString(strconv.Itoa(re.Max))
-				}
-			}
-			b.WriteRune('}')
-		}
-		if re.Flags&NonGreedy != 0 {
-			b.WriteRune('?')
-		}
-	case OpConcat:
-		for _, sub := range re.Sub {
-			if sub.Op == OpAlternate {
-				b.WriteString(`(?:`)
-				writeRegexp(b, sub)
-				b.WriteString(`)`)
-			} else {
-				writeRegexp(b, sub)
-			}
-		}
-	case OpAlternate:
-		for i, sub := range re.Sub {
-			if i > 0 {
-				b.WriteRune('|')
-			}
-			writeRegexp(b, sub)
-		}
-	}
-}
-
-func (re *Regexp) String() string {
-	var b bytes.Buffer
-	writeRegexp(&b, re)
-	return b.String()
-}
-
-const meta = `\.+*?()|[]{}^$`
-
-func escape(b *bytes.Buffer, r rune, force bool) {
-	if unicode.IsPrint(r) {
-		if strings.IndexRune(meta, r) >= 0 || force {
-			b.WriteRune('\\')
-		}
-		b.WriteRune(r)
-		return
-	}
-
-	switch r {
-	case '\a':
-		b.WriteString(`\a`)
-	case '\f':
-		b.WriteString(`\f`)
-	case '\n':
-		b.WriteString(`\n`)
-	case '\r':
-		b.WriteString(`\r`)
-	case '\t':
-		b.WriteString(`\t`)
-	case '\v':
-		b.WriteString(`\v`)
-	default:
-		if r < 0x100 {
-			b.WriteString(`\x`)
-			s := strconv.FormatInt(int64(r), 16)
-			if len(s) == 1 {
-				b.WriteRune('0')
-			}
-			b.WriteString(s)
-			break
-		}
-		b.WriteString(`\x{`)
-		b.WriteString(strconv.FormatInt(int64(r), 16))
-		b.WriteString(`}`)
-	}
-}
-
-// MaxCap walks the regexp to find the maximum capture index.
-func (re *Regexp) MaxCap() int {
-	m := 0
-	if re.Op == OpCapture {
-		m = re.Cap
-	}
-	for _, sub := range re.Sub {
-		if n := sub.MaxCap(); m < n {
-			m = n
-		}
-	}
-	return m
-}
-
-// CapNames walks the regexp to find the names of capturing groups.
-func (re *Regexp) CapNames() []string {
-	names := make([]string, re.MaxCap()+1)
-	re.capNames(names)
-	return names
-}
-
-func (re *Regexp) capNames(names []string) {
-	if re.Op == OpCapture {
-		names[re.Cap] = re.Name
-	}
-	for _, sub := range re.Sub {
-		sub.capNames(names)
-	}
-}
diff --git a/src/pkg/runtime/Makefile b/src/pkg/runtime/Makefile
deleted file mode 100644
index 5827ce1..0000000
--- a/src/pkg/runtime/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
-# Copyright 2009 The Go Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style
-# license that can be found in the LICENSE file.
-
-include ../../Make.dist
diff --git a/src/pkg/runtime/alg.goc b/src/pkg/runtime/alg.goc
deleted file mode 100644
index f1b8d59..0000000
--- a/src/pkg/runtime/alg.goc
+++ /dev/null
@@ -1,549 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package runtime
-#include "runtime.h"
-#include "type.h"
-#include "../../cmd/ld/textflag.h"
-
-#define M0 (sizeof(uintptr)==4 ? 2860486313UL : 33054211828000289ULL)
-#define M1 (sizeof(uintptr)==4 ? 3267000013UL : 23344194077549503ULL)
-
-static bool use_aeshash;
-
-/*
- * map and chan helpers for
- * dealing with unknown types
- */
-void
-runtime·memhash(uintptr *h, uintptr s, void *a)
-{
-	byte *b;
-	uintptr hash;
-	if(!NaCl && use_aeshash) {
-		runtime·aeshash(h, s, a);
-		return;
-	}
-
-	b = a;
-	hash = M0 ^ *h;
-	while(s > 0) {
-		hash = (hash ^ *b) * M1;
-		b++;
-		s--;
-	}
-	*h = hash;
-}
-
-void
-runtime·memequal(bool *eq, uintptr s, void *a, void *b)
-{
-	if(a == b) {
-		*eq = 1;
-		return;
-	}
-	*eq = runtime·memeq(a, b, s);
-}
-
-void
-runtime·memprint(uintptr s, void *a)
-{
-	uint64 v;
-
-	v = 0xbadb00b;
-	switch(s) {
-	case 1:
-		v = *(uint8*)a;
-		break;
-	case 2:
-		v = *(uint16*)a;
-		break;
-	case 4:
-		v = *(uint32*)a;
-		break;
-	case 8:
-		v = *(uint64*)a;
-		break;
-	}
-	runtime·printint(v);
-}
-
-void
-runtime·memcopy(uintptr s, void *a, void *b)
-{
-	if(b == nil) {
-		runtime·memclr(a, s);
-		return;
-	}
-	runtime·memmove(a, b, s);
-}
-
-void
-runtime·memequal0(bool *eq, uintptr s, void *a, void *b)
-{
-	USED(s);
-	USED(a);
-	USED(b);
-	*eq = true;
-}
-
-void
-runtime·memcopy0(uintptr s, void *a, void *b)
-{
-	USED(s);
-	USED(a);
-	USED(b);
-}
-
-void
-runtime·memequal8(bool *eq, uintptr s, void *a, void *b)
-{
-	USED(s);
-	*eq = *(uint8*)a == *(uint8*)b;
-}
-
-void
-runtime·memcopy8(uintptr s, void *a, void *b)
-{
-	USED(s);
-	if(b == nil) {
-		*(uint8*)a = 0;
-		return;
-	}
-	*(uint8*)a = *(uint8*)b;
-}
-
-void
-runtime·memequal16(bool *eq, uintptr s, void *a, void *b)
-{
-	USED(s);
-	*eq = *(uint16*)a == *(uint16*)b;
-}
-
-void
-runtime·memcopy16(uintptr s, void *a, void *b)
-{
-	USED(s);
-	if(b == nil) {
-		*(uint16*)a = 0;
-		return;
-	}
-	*(uint16*)a = *(uint16*)b;
-}
-
-void
-runtime·memequal32(bool *eq, uintptr s, void *a, void *b)
-{
-	USED(s);
-	*eq = *(uint32*)a == *(uint32*)b;
-}
-
-void
-runtime·memcopy32(uintptr s, void *a, void *b)
-{
-	USED(s);
-	if(b == nil) {
-		*(uint32*)a = 0;
-		return;
-	}
-	*(uint32*)a = *(uint32*)b;
-}
-
-void
-runtime·memequal64(bool *eq, uintptr s, void *a, void *b)
-{
-	USED(s);
-	*eq = *(uint64*)a == *(uint64*)b;
-}
-
-void
-runtime·memcopy64(uintptr s, void *a, void *b)
-{
-	USED(s);
-	if(b == nil) {
-		*(uint64*)a = 0;
-		return;
-	}
-	*(uint64*)a = *(uint64*)b;
-}
-
-void
-runtime·memequal128(bool *eq, uintptr s, void *a, void *b)
-{
-	USED(s);
-	*eq = ((uint64*)a)[0] == ((uint64*)b)[0] && ((uint64*)a)[1] == ((uint64*)b)[1];
-}
-
-void
-runtime·memcopy128(uintptr s, void *a, void *b)
-{
-	USED(s);
-	if(b == nil) {
-		((uint64*)a)[0] = 0;
-		((uint64*)a)[1] = 0;
-		return;
-	}
-	((uint64*)a)[0] = ((uint64*)b)[0];
-	((uint64*)a)[1] = ((uint64*)b)[1];
-}
-
-void
-runtime·f32equal(bool *eq, uintptr s, void *a, void *b)
-{
-	USED(s);
-	*eq = *(float32*)a == *(float32*)b;
-}
-
-void
-runtime·f64equal(bool *eq, uintptr s, void *a, void *b)
-{
-	USED(s);
-	*eq = *(float64*)a == *(float64*)b;
-}
-
-void
-runtime·c64equal(bool *eq, uintptr s, void *a, void *b)
-{	
-	Complex64 *ca, *cb;
-	
-	USED(s);
-	ca = a;
-	cb = b;
-	*eq = ca->real == cb->real && ca->imag == cb->imag;
-}
-
-void
-runtime·c128equal(bool *eq, uintptr s, void *a, void *b)
-{	
-	Complex128 *ca, *cb;
-	
-	USED(s);
-	ca = a;
-	cb = b;
-	*eq = ca->real == cb->real && ca->imag == cb->imag;
-}
-
-// NOTE: Because NaN != NaN, a map can contain any
-// number of (mostly useless) entries keyed with NaNs.
-// To avoid long hash chains, we assign a random number
-// as the hash value for a NaN.
-
-void
-runtime·f32hash(uintptr *h, uintptr s, void *a)
-{
-	uintptr hash;
-	float32 f;
-
-	USED(s);
-	f = *(float32*)a;
-	if(f == 0)
-		hash = 0;  // +0, -0
-	else if(f != f)
-		hash = runtime·fastrand1();  // any kind of NaN
-	else
-		hash = *(uint32*)a;
-	*h = (*h ^ hash ^ M0) * M1;
-}
-
-void
-runtime·f64hash(uintptr *h, uintptr s, void *a)
-{
-	uintptr hash;
-	float64 f;
-	uint64 u;
-
-	USED(s);
-	f = *(float64*)a;
-	if(f == 0)
-		hash = 0;	// +0, -0
-	else if(f != f)
-		hash = runtime·fastrand1();  // any kind of NaN
-	else {
-		u = *(uint64*)a;
-		if(sizeof(uintptr) == 4)
-			hash = ((uint32)(u>>32) * M1) ^ (uint32)u;
-		else
-			hash = u;
-	}
-	*h = (*h ^ hash ^ M0) * M1;
-}
-
-void
-runtime·c64hash(uintptr *h, uintptr s, void *a)
-{
-	USED(s);
-	runtime·f32hash(h, 0, a);
-	runtime·f32hash(h, 0, (float32*)a+1);
-}
-
-void
-runtime·c128hash(uintptr *h, uintptr s, void *a)
-{
-	USED(s);
-	runtime·f64hash(h, 0, a);
-	runtime·f64hash(h, 0, (float64*)a+1);
-}
-
-void
-runtime·slicecopy(uintptr s, void *a, void *b)
-{
-	USED(s);
-	if(b == nil) {
-		((Slice*)a)->array = 0;
-		((Slice*)a)->len = 0;
-		((Slice*)a)->cap = 0;
-		return;
-	}
-	((Slice*)a)->array = ((Slice*)b)->array;
-	((Slice*)a)->len = ((Slice*)b)->len;
-	((Slice*)a)->cap = ((Slice*)b)->cap;
-}
-
-void
-runtime·strhash(uintptr *h, uintptr s, void *a)
-{
-	USED(s);
-	runtime·memhash(h, ((String*)a)->len, ((String*)a)->str);
-}
-
-void
-runtime·strequal(bool *eq, uintptr s, void *a, void *b)
-{
-	intgo alen;
-	byte *s1, *s2;
-
-	USED(s);
-	alen = ((String*)a)->len;
-	if(alen != ((String*)b)->len) {
-		*eq = false;
-		return;
-	}
-	s1 = ((String*)a)->str;
-	s2 = ((String*)b)->str;
-	if(s1 == s2) {
-		*eq = true;
-		return;
-	}
-	*eq = runtime·memeq(s1, s2, alen);
-}
-
-void
-runtime·strprint(uintptr s, void *a)
-{
-	USED(s);
-	runtime·printstring(*(String*)a);
-}
-
-void
-runtime·strcopy(uintptr s, void *a, void *b)
-{
-	USED(s);
-	if(b == nil) {
-		((String*)a)->str = 0;
-		((String*)a)->len = 0;
-		return;
-	}
-	((String*)a)->str = ((String*)b)->str;
-	((String*)a)->len = ((String*)b)->len;
-}
-
-void
-runtime·interhash(uintptr *h, uintptr s, void *a)
-{
-	USED(s);
-	*h = runtime·ifacehash(*(Iface*)a, *h ^ M0) * M1;
-}
-
-void
-runtime·interprint(uintptr s, void *a)
-{
-	USED(s);
-	runtime·printiface(*(Iface*)a);
-}
-
-void
-runtime·interequal(bool *eq, uintptr s, void *a, void *b)
-{
-	USED(s);
-	*eq = runtime·ifaceeq_c(*(Iface*)a, *(Iface*)b);
-}
-
-void
-runtime·intercopy(uintptr s, void *a, void *b)
-{
-	USED(s);
-	if(b == nil) {
-		((Iface*)a)->tab = 0;
-		((Iface*)a)->data = 0;
-		return;
-	}
-	((Iface*)a)->tab = ((Iface*)b)->tab;
-	((Iface*)a)->data = ((Iface*)b)->data;
-}
-
-void
-runtime·nilinterhash(uintptr *h, uintptr s, void *a)
-{
-	USED(s);
-	*h = runtime·efacehash(*(Eface*)a, *h ^ M0) * M1;
-}
-
-void
-runtime·nilinterprint(uintptr s, void *a)
-{
-	USED(s);
-	runtime·printeface(*(Eface*)a);
-}
-
-void
-runtime·nilinterequal(bool *eq, uintptr s, void *a, void *b)
-{
-	USED(s);
-	*eq = runtime·efaceeq_c(*(Eface*)a, *(Eface*)b);
-}
-
-void
-runtime·nilintercopy(uintptr s, void *a, void *b)
-{
-	USED(s);
-	if(b == nil) {
-		((Eface*)a)->type = 0;
-		((Eface*)a)->data = 0;
-		return;
-	}
-	((Eface*)a)->type = ((Eface*)b)->type;
-	((Eface*)a)->data = ((Eface*)b)->data;
-}
-
-void
-runtime·nohash(uintptr *h, uintptr s, void *a)
-{
-	USED(s);
-	USED(a);
-	USED(h);
-	runtime·panicstring("hash of unhashable type");
-}
-
-void
-runtime·noequal(bool *eq, uintptr s, void *a, void *b)
-{
-	USED(s);
-	USED(a);
-	USED(b);
-	USED(eq);
-	runtime·panicstring("comparing uncomparable types");
-}
-
-Alg
-runtime·algarray[] =
-{
-[AMEM]		{ runtime·memhash, runtime·memequal, runtime·memprint, runtime·memcopy },
-[ANOEQ]		{ runtime·nohash, runtime·noequal, runtime·memprint, runtime·memcopy },
-[ASTRING]	{ runtime·strhash, runtime·strequal, runtime·strprint, runtime·strcopy },
-[AINTER]	{ runtime·interhash, runtime·interequal, runtime·interprint, runtime·intercopy },
-[ANILINTER]	{ runtime·nilinterhash, runtime·nilinterequal, runtime·nilinterprint, runtime·nilintercopy },
-[ASLICE]	{ runtime·nohash, runtime·noequal, runtime·memprint, runtime·slicecopy },
-[AFLOAT32]	{ runtime·f32hash, runtime·f32equal, runtime·memprint, runtime·memcopy },
-[AFLOAT64]	{ runtime·f64hash, runtime·f64equal, runtime·memprint, runtime·memcopy },
-[ACPLX64]	{ runtime·c64hash, runtime·c64equal, runtime·memprint, runtime·memcopy },
-[ACPLX128]	{ runtime·c128hash, runtime·c128equal, runtime·memprint, runtime·memcopy },
-[AMEM0]		{ runtime·memhash, runtime·memequal0, runtime·memprint, runtime·memcopy0 },
-[AMEM8]		{ runtime·memhash, runtime·memequal8, runtime·memprint, runtime·memcopy8 },
-[AMEM16]	{ runtime·memhash, runtime·memequal16, runtime·memprint, runtime·memcopy16 },
-[AMEM32]	{ runtime·memhash, runtime·memequal32, runtime·memprint, runtime·memcopy32 },
-[AMEM64]	{ runtime·memhash, runtime·memequal64, runtime·memprint, runtime·memcopy64 },
-[AMEM128]	{ runtime·memhash, runtime·memequal128, runtime·memprint, runtime·memcopy128 },
-[ANOEQ0]	{ runtime·nohash, runtime·noequal, runtime·memprint, runtime·memcopy0 },
-[ANOEQ8]	{ runtime·nohash, runtime·noequal, runtime·memprint, runtime·memcopy8 },
-[ANOEQ16]	{ runtime·nohash, runtime·noequal, runtime·memprint, runtime·memcopy16 },
-[ANOEQ32]	{ runtime·nohash, runtime·noequal, runtime·memprint, runtime·memcopy32 },
-[ANOEQ64]	{ runtime·nohash, runtime·noequal, runtime·memprint, runtime·memcopy64 },
-[ANOEQ128]	{ runtime·nohash, runtime·noequal, runtime·memprint, runtime·memcopy128 },
-};
-
-// Runtime helpers.
-
-// used in asm_{386,amd64}.s
-#pragma dataflag NOPTR
-byte runtime·aeskeysched[HashRandomBytes];
-
-void
-runtime·hashinit(void)
-{
-        if(NaCl)
-                return;
-
-	// Install aes hash algorithm if we have the instructions we need
-	if((runtime·cpuid_ecx & (1 << 25)) != 0 &&  // aes (aesenc)
-	   (runtime·cpuid_ecx & (1 << 9)) != 0 &&   // sse3 (pshufb)
-	   (runtime·cpuid_ecx & (1 << 19)) != 0) {  // sse4.1 (pinsr{d,q})
-		byte *rnd;
-		int32 n;
-		use_aeshash = true;
-		runtime·algarray[AMEM].hash = runtime·aeshash;
-		runtime·algarray[AMEM8].hash = runtime·aeshash;
-		runtime·algarray[AMEM16].hash = runtime·aeshash;
-		runtime·algarray[AMEM32].hash = runtime·aeshash32;
-		runtime·algarray[AMEM64].hash = runtime·aeshash64;
-		runtime·algarray[AMEM128].hash = runtime·aeshash;
-		runtime·algarray[ASTRING].hash = runtime·aeshashstr;
-
-		// Initialize with random data so hash collisions will be hard to engineer.
-		runtime·get_random_data(&rnd, &n);
-		if(n > HashRandomBytes)
-			n = HashRandomBytes;
-		runtime·memmove(runtime·aeskeysched, rnd, n);
-		if(n < HashRandomBytes) {
-			// Not very random, but better than nothing.
-			int64 t = runtime·nanotime();
-			while (n < HashRandomBytes) {
-				runtime·aeskeysched[n++] = (int8)(t >> (8 * (n % 8)));
-			}
-		}
-	}
-}
-
-// func equal(t *Type, x T, y T) (ret bool)
-#pragma textflag NOSPLIT
-void
-runtime·equal(Type *t, ...)
-{
-	byte *x, *y;
-	bool *ret;
-	
-	x = (byte*)ROUND((uintptr)(&t+1), t->align);
-	y = x + t->size;
-	ret = (bool*)ROUND((uintptr)(y+t->size), Structrnd);
-	t->alg->equal(ret, t->size, x, y);
-}
-
-// Testing adapter for memclr
-func memclrBytes(s Slice) {
-	runtime·memclr(s.array, s.len);
-}
-
-// Testing adapters for hash quality tests (see hash_test.go)
-func haveGoodHash() (res bool) {
-	res = use_aeshash;
-}
-
-func stringHash(s String, seed uintptr) (res uintptr) {
-	runtime·algarray[ASTRING].hash(&seed, sizeof(String), &s);
-	res = seed;
-}
-
-func bytesHash(s Slice, seed uintptr) (res uintptr) {
-	runtime·algarray[AMEM].hash(&seed, s.len, s.array);
-	res = seed;
-}
-
-func int32Hash(i uint32, seed uintptr) (res uintptr) {
-	runtime·algarray[AMEM32].hash(&seed, sizeof(uint32), &i);
-	res = seed;
-}
-
-func int64Hash(i uint64, seed uintptr) (res uintptr) {
-	runtime·algarray[AMEM64].hash(&seed, sizeof(uint64), &i);
-	res = seed;
-}
diff --git a/src/pkg/runtime/arch_386.h b/src/pkg/runtime/arch_386.h
deleted file mode 100644
index 5c0a54f..0000000
--- a/src/pkg/runtime/arch_386.h
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-enum {
-	thechar = '8',
-	BigEndian = 0,
-	CacheLineSize = 64,
-	RuntimeGogoBytes = 64,
-#ifdef GOOS_nacl
-	PhysPageSize = 65536,
-#else
-	PhysPageSize = 4096,
-#endif
-	PCQuantum = 1
-};
diff --git a/src/pkg/runtime/arch_amd64.h b/src/pkg/runtime/arch_amd64.h
deleted file mode 100644
index c8a2184..0000000
--- a/src/pkg/runtime/arch_amd64.h
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-enum {
-	thechar = '6',
-	BigEndian = 0,
-	CacheLineSize = 64,
-#ifdef GOOS_solaris
-	RuntimeGogoBytes = 80,
-#else
-#ifdef GOOS_windows
-	RuntimeGogoBytes = 80,
-#else
-	RuntimeGogoBytes = 64,
-#endif	// Windows
-#endif	// Solaris
-	PhysPageSize = 4096,
-	PCQuantum = 1
-};
diff --git a/src/pkg/runtime/arch_amd64p32.h b/src/pkg/runtime/arch_amd64p32.h
deleted file mode 100644
index 073a9e3..0000000
--- a/src/pkg/runtime/arch_amd64p32.h
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-enum {
-	thechar = '6',
-	BigEndian = 0,
-	CacheLineSize = 64,
-	RuntimeGogoBytes = 64,
-#ifdef GOOS_nacl
-	PhysPageSize = 65536,
-#else
-	PhysPageSize = 4096,
-#endif
-	PCQuantum = 1
-};
diff --git a/src/pkg/runtime/arch_arm.h b/src/pkg/runtime/arch_arm.h
deleted file mode 100644
index b971128..0000000
--- a/src/pkg/runtime/arch_arm.h
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-enum {
-	thechar = '5',
-	BigEndian = 0,
-	CacheLineSize = 32,
-	RuntimeGogoBytes = 80,
-	PhysPageSize = 4096,
-	PCQuantum = 4
-};
diff --git a/src/pkg/runtime/asm_386.s b/src/pkg/runtime/asm_386.s
deleted file mode 100644
index 9531208..0000000
--- a/src/pkg/runtime/asm_386.s
+++ /dev/null
@@ -1,2166 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "zasm_GOOS_GOARCH.h"
-#include "funcdata.h"
-#include "../../cmd/ld/textflag.h"
-
-TEXT _rt0_go(SB),NOSPLIT,$0
-	// copy arguments forward on an even stack
-	MOVL	argc+0(FP), AX
-	MOVL	argv+4(FP), BX
-	SUBL	$128, SP		// plenty of scratch
-	ANDL	$~15, SP
-	MOVL	AX, 120(SP)		// save argc, argv away
-	MOVL	BX, 124(SP)
-
-	// set default stack bounds.
-	// _cgo_init may update stackguard.
-	MOVL	$runtime·g0(SB), BP
-	LEAL	(-64*1024+104)(SP), BX
-	MOVL	BX, g_stackguard(BP)
-	MOVL	BX, g_stackguard0(BP)
-	MOVL	SP, g_stackbase(BP)
-	
-	// find out information about the processor we're on
-	MOVL	$0, AX
-	CPUID
-	CMPL	AX, $0
-	JE	nocpuinfo
-	MOVL	$1, AX
-	CPUID
-	MOVL	CX, runtime·cpuid_ecx(SB)
-	MOVL	DX, runtime·cpuid_edx(SB)
-nocpuinfo:	
-
-	// if there is an _cgo_init, call it to let it
-	// initialize and to set up GS.  if not,
-	// we set up GS ourselves.
-	MOVL	_cgo_init(SB), AX
-	TESTL	AX, AX
-	JZ	needtls
-	MOVL	$setmg_gcc<>(SB), BX
-	MOVL	BX, 4(SP)
-	MOVL	BP, 0(SP)
-	CALL	AX
-	// update stackguard after _cgo_init
-	MOVL	$runtime·g0(SB), CX
-	MOVL	g_stackguard0(CX), AX
-	MOVL	AX, g_stackguard(CX)
-	// skip runtime·ldt0setup(SB) and tls test after _cgo_init for non-windows
-	CMPL runtime·iswindows(SB), $0
-	JEQ ok
-needtls:
-	// skip runtime·ldt0setup(SB) and tls test on Plan 9 in all cases
-	CMPL	runtime·isplan9(SB), $1
-	JEQ	ok
-
-	// set up %gs
-	CALL	runtime·ldt0setup(SB)
-
-	// store through it, to make sure it works
-	get_tls(BX)
-	MOVL	$0x123, g(BX)
-	MOVL	runtime·tls0(SB), AX
-	CMPL	AX, $0x123
-	JEQ	ok
-	MOVL	AX, 0	// abort
-ok:
-	// set up m and g "registers"
-	get_tls(BX)
-	LEAL	runtime·g0(SB), CX
-	MOVL	CX, g(BX)
-	LEAL	runtime·m0(SB), AX
-	MOVL	AX, m(BX)
-
-	// save m->g0 = g0
-	MOVL	CX, m_g0(AX)
-
-	CALL	runtime·emptyfunc(SB)	// fault if stack check is wrong
-
-	// convention is D is always cleared
-	CLD
-
-	CALL	runtime·check(SB)
-
-	// saved argc, argv
-	MOVL	120(SP), AX
-	MOVL	AX, 0(SP)
-	MOVL	124(SP), AX
-	MOVL	AX, 4(SP)
-	CALL	runtime·args(SB)
-	CALL	runtime·osinit(SB)
-	CALL	runtime·hashinit(SB)
-	CALL	runtime·schedinit(SB)
-
-	// create a new goroutine to start program
-	PUSHL	$runtime·main·f(SB)	// entry
-	PUSHL	$0	// arg size
-	ARGSIZE(8)
-	CALL	runtime·newproc(SB)
-	ARGSIZE(-1)
-	POPL	AX
-	POPL	AX
-
-	// start this M
-	CALL	runtime·mstart(SB)
-
-	INT $3
-	RET
-
-DATA	runtime·main·f+0(SB)/4,$runtime·main(SB)
-GLOBL	runtime·main·f(SB),RODATA,$4
-
-TEXT runtime·breakpoint(SB),NOSPLIT,$0-0
-	INT $3
-	RET
-
-TEXT runtime·asminit(SB),NOSPLIT,$0-0
-	// Linux and MinGW start the FPU in extended double precision.
-	// Other operating systems use double precision.
-	// Change to double precision to match them,
-	// and to match other hardware that only has double.
-	PUSHL $0x27F
-	FLDCW	0(SP)
-	POPL AX
-	RET
-
-/*
- *  go-routine
- */
-
-// void gosave(Gobuf*)
-// save state in Gobuf; setjmp
-TEXT runtime·gosave(SB), NOSPLIT, $0-4
-	MOVL	4(SP), AX		// gobuf
-	LEAL	4(SP), BX		// caller's SP
-	MOVL	BX, gobuf_sp(AX)
-	MOVL	0(SP), BX		// caller's PC
-	MOVL	BX, gobuf_pc(AX)
-	MOVL	$0, gobuf_ret(AX)
-	MOVL	$0, gobuf_ctxt(AX)
-	get_tls(CX)
-	MOVL	g(CX), BX
-	MOVL	BX, gobuf_g(AX)
-	RET
-
-// void gogo(Gobuf*)
-// restore state from Gobuf; longjmp
-TEXT runtime·gogo(SB), NOSPLIT, $0-4
-	MOVL	4(SP), BX		// gobuf
-	MOVL	gobuf_g(BX), DX
-	MOVL	0(DX), CX		// make sure g != nil
-	get_tls(CX)
-	MOVL	DX, g(CX)
-	MOVL	gobuf_sp(BX), SP	// restore SP
-	MOVL	gobuf_ret(BX), AX
-	MOVL	gobuf_ctxt(BX), DX
-	MOVL	$0, gobuf_sp(BX)	// clear to help garbage collector
-	MOVL	$0, gobuf_ret(BX)
-	MOVL	$0, gobuf_ctxt(BX)
-	MOVL	gobuf_pc(BX), BX
-	JMP	BX
-
-// void mcall(void (*fn)(G*))
-// Switch to m->g0's stack, call fn(g).
-// Fn must never return.  It should gogo(&g->sched)
-// to keep running g.
-TEXT runtime·mcall(SB), NOSPLIT, $0-4
-	MOVL	fn+0(FP), DI
-	
-	get_tls(CX)
-	MOVL	g(CX), AX	// save state in g->sched
-	MOVL	0(SP), BX	// caller's PC
-	MOVL	BX, (g_sched+gobuf_pc)(AX)
-	LEAL	4(SP), BX	// caller's SP
-	MOVL	BX, (g_sched+gobuf_sp)(AX)
-	MOVL	AX, (g_sched+gobuf_g)(AX)
-
-	// switch to m->g0 & its stack, call fn
-	MOVL	m(CX), BX
-	MOVL	m_g0(BX), SI
-	CMPL	SI, AX	// if g == m->g0 call badmcall
-	JNE	3(PC)
-	MOVL	$runtime·badmcall(SB), AX
-	JMP	AX
-	MOVL	SI, g(CX)	// g = m->g0
-	MOVL	(g_sched+gobuf_sp)(SI), SP	// sp = m->g0->sched.sp
-	PUSHL	AX
-	CALL	DI
-	POPL	AX
-	MOVL	$runtime·badmcall2(SB), AX
-	JMP	AX
-	RET
-
-/*
- * support for morestack
- */
-
-// Called during function prolog when more stack is needed.
-//
-// The traceback routines see morestack on a g0 as being
-// the top of a stack (for example, morestack calling newstack
-// calling the scheduler calling newm calling gc), so we must
-// record an argument size. For that purpose, it has no arguments.
-TEXT runtime·morestack(SB),NOSPLIT,$0-0
-	// Cannot grow scheduler stack (m->g0).
-	get_tls(CX)
-	MOVL	m(CX), BX
-	MOVL	m_g0(BX), SI
-	CMPL	g(CX), SI
-	JNE	2(PC)
-	INT	$3
-
-	// frame size in DI
-	// arg size in AX
-	// Save in m.
-	MOVL	DI, m_moreframesize(BX)
-	MOVL	AX, m_moreargsize(BX)
-
-	// Called from f.
-	// Set m->morebuf to f's caller.
-	MOVL	4(SP), DI	// f's caller's PC
-	MOVL	DI, (m_morebuf+gobuf_pc)(BX)
-	LEAL	8(SP), CX	// f's caller's SP
-	MOVL	CX, (m_morebuf+gobuf_sp)(BX)
-	MOVL	CX, m_moreargp(BX)
-	get_tls(CX)
-	MOVL	g(CX), SI
-	MOVL	SI, (m_morebuf+gobuf_g)(BX)
-
-	// Set g->sched to context in f.
-	MOVL	0(SP), AX	// f's PC
-	MOVL	AX, (g_sched+gobuf_pc)(SI)
-	MOVL	SI, (g_sched+gobuf_g)(SI)
-	LEAL	4(SP), AX	// f's SP
-	MOVL	AX, (g_sched+gobuf_sp)(SI)
-	MOVL	DX, (g_sched+gobuf_ctxt)(SI)
-
-	// Call newstack on m->g0's stack.
-	MOVL	m_g0(BX), BP
-	MOVL	BP, g(CX)
-	MOVL	(g_sched+gobuf_sp)(BP), AX
-	MOVL	-4(AX), BX	// fault if CALL would, before smashing SP
-	MOVL	AX, SP
-	CALL	runtime·newstack(SB)
-	MOVL	$0, 0x1003	// crash if newstack returns
-	RET
-
-TEXT runtime·morestack_noctxt(SB),NOSPLIT,$0-0
-	MOVL	$0, DX
-	JMP runtime·morestack(SB)
-
-// Called from panic.  Mimics morestack,
-// reuses stack growth code to create a frame
-// with the desired args running the desired function.
-//
-// func call(fn *byte, arg *byte, argsize uint32).
-TEXT runtime·newstackcall(SB), NOSPLIT, $0-12
-	get_tls(CX)
-	MOVL	m(CX), BX
-
-	// Save our caller's state as the PC and SP to
-	// restore when returning from f.
-	MOVL	0(SP), AX	// our caller's PC
-	MOVL	AX, (m_morebuf+gobuf_pc)(BX)
-	LEAL	4(SP), AX	// our caller's SP
-	MOVL	AX, (m_morebuf+gobuf_sp)(BX)
-	MOVL	g(CX), AX
-	MOVL	AX, (m_morebuf+gobuf_g)(BX)
-
-	// Save our own state as the PC and SP to restore
-	// if this goroutine needs to be restarted.
-	MOVL	$runtime·newstackcall(SB), (g_sched+gobuf_pc)(AX)
-	MOVL	SP, (g_sched+gobuf_sp)(AX)
-
-	// Set up morestack arguments to call f on a new stack.
-	// We set f's frame size to 1, as a hint to newstack
-	// that this is a call from runtime·newstackcall.
-	// If it turns out that f needs a larger frame than
-	// the default stack, f's usual stack growth prolog will
-	// allocate a new segment (and recopy the arguments).
-	MOVL	4(SP), AX	// fn
-	MOVL	8(SP), DX	// arg frame
-	MOVL	12(SP), CX	// arg size
-
-	MOVL	AX, m_cret(BX)	// f's PC
-	MOVL	DX, m_moreargp(BX)	// f's argument pointer
-	MOVL	CX, m_moreargsize(BX)	// f's argument size
-	MOVL	$1, m_moreframesize(BX)	// f's frame size
-
-	// Call newstack on m->g0's stack.
-	MOVL	m_g0(BX), BP
-	get_tls(CX)
-	MOVL	BP, g(CX)
-	MOVL	(g_sched+gobuf_sp)(BP), SP
-	CALL	runtime·newstack(SB)
-	MOVL	$0, 0x1103	// crash if newstack returns
-	RET
-
-// reflect·call: call a function with the given argument list
-// func call(f *FuncVal, arg *byte, argsize uint32).
-// we don't have variable-sized frames, so we use a small number
-// of constant-sized-frame functions to encode a few bits of size in the pc.
-// Caution: ugly multiline assembly macros in your future!
-
-#define DISPATCH(NAME,MAXSIZE)		\
-	CMPL	CX, $MAXSIZE;		\
-	JA	3(PC);			\
-	MOVL	$runtime·NAME(SB), AX;	\
-	JMP	AX
-// Note: can't just "JMP runtime·NAME(SB)" - bad inlining results.
-
-TEXT reflect·call(SB), NOSPLIT, $0-16
-	MOVL	argsize+8(FP), CX
-	DISPATCH(call16, 16)
-	DISPATCH(call32, 32)
-	DISPATCH(call64, 64)
-	DISPATCH(call128, 128)
-	DISPATCH(call256, 256)
-	DISPATCH(call512, 512)
-	DISPATCH(call1024, 1024)
-	DISPATCH(call2048, 2048)
-	DISPATCH(call4096, 4096)
-	DISPATCH(call8192, 8192)
-	DISPATCH(call16384, 16384)
-	DISPATCH(call32768, 32768)
-	DISPATCH(call65536, 65536)
-	DISPATCH(call131072, 131072)
-	DISPATCH(call262144, 262144)
-	DISPATCH(call524288, 524288)
-	DISPATCH(call1048576, 1048576)
-	DISPATCH(call2097152, 2097152)
-	DISPATCH(call4194304, 4194304)
-	DISPATCH(call8388608, 8388608)
-	DISPATCH(call16777216, 16777216)
-	DISPATCH(call33554432, 33554432)
-	DISPATCH(call67108864, 67108864)
-	DISPATCH(call134217728, 134217728)
-	DISPATCH(call268435456, 268435456)
-	DISPATCH(call536870912, 536870912)
-	DISPATCH(call1073741824, 1073741824)
-	MOVL	$runtime·badreflectcall(SB), AX
-	JMP	AX
-
-// Argument map for the callXX frames.  Each has one
-// stack map (for the single call) with 3 arguments.
-DATA gcargs_reflectcall<>+0x00(SB)/4, $1  // 1 stackmap
-DATA gcargs_reflectcall<>+0x04(SB)/4, $6  // 3 args
-DATA gcargs_reflectcall<>+0x08(SB)/4, $(const_BitsPointer+(const_BitsPointer<<2)+(const_BitsScalar<<4))
-GLOBL gcargs_reflectcall<>(SB),RODATA,$12
-
-// callXX frames have no locals
-DATA gclocals_reflectcall<>+0x00(SB)/4, $1  // 1 stackmap
-DATA gclocals_reflectcall<>+0x04(SB)/4, $0  // 0 locals
-GLOBL gclocals_reflectcall<>(SB),RODATA,$8
-
-#define CALLFN(NAME,MAXSIZE)			\
-TEXT runtime·NAME(SB), WRAPPER, $MAXSIZE-16;	\
-	FUNCDATA $FUNCDATA_ArgsPointerMaps,gcargs_reflectcall<>(SB);	\
-	FUNCDATA $FUNCDATA_LocalsPointerMaps,gclocals_reflectcall<>(SB);\
-	/* copy arguments to stack */		\
-	MOVL	argptr+4(FP), SI;		\
-	MOVL	argsize+8(FP), CX;		\
-	MOVL	SP, DI;				\
-	REP;MOVSB;				\
-	/* call function */			\
-	MOVL	f+0(FP), DX;			\
-	MOVL	(DX), AX; 			\
-	PCDATA  $PCDATA_StackMapIndex, $0;	\
-	CALL	AX;				\
-	/* copy return values back */		\
-	MOVL	argptr+4(FP), DI;		\
-	MOVL	argsize+8(FP), CX;		\
-	MOVL	retoffset+12(FP), BX;		\
-	MOVL	SP, SI;				\
-	ADDL	BX, DI;				\
-	ADDL	BX, SI;				\
-	SUBL	BX, CX;				\
-	REP;MOVSB;				\
-	RET
-
-CALLFN(call16, 16)
-CALLFN(call32, 32)
-CALLFN(call64, 64)
-CALLFN(call128, 128)
-CALLFN(call256, 256)
-CALLFN(call512, 512)
-CALLFN(call1024, 1024)
-CALLFN(call2048, 2048)
-CALLFN(call4096, 4096)
-CALLFN(call8192, 8192)
-CALLFN(call16384, 16384)
-CALLFN(call32768, 32768)
-CALLFN(call65536, 65536)
-CALLFN(call131072, 131072)
-CALLFN(call262144, 262144)
-CALLFN(call524288, 524288)
-CALLFN(call1048576, 1048576)
-CALLFN(call2097152, 2097152)
-CALLFN(call4194304, 4194304)
-CALLFN(call8388608, 8388608)
-CALLFN(call16777216, 16777216)
-CALLFN(call33554432, 33554432)
-CALLFN(call67108864, 67108864)
-CALLFN(call134217728, 134217728)
-CALLFN(call268435456, 268435456)
-CALLFN(call536870912, 536870912)
-CALLFN(call1073741824, 1073741824)
-
-// Return point when leaving stack.
-//
-// Lessstack can appear in stack traces for the same reason
-// as morestack; in that context, it has 0 arguments.
-TEXT runtime·lessstack(SB), NOSPLIT, $0-0
-	// Save return value in m->cret
-	get_tls(CX)
-	MOVL	m(CX), BX
-	MOVL	AX, m_cret(BX)
-
-	// Call oldstack on m->g0's stack.
-	MOVL	m_g0(BX), BP
-	MOVL	BP, g(CX)
-	MOVL	(g_sched+gobuf_sp)(BP), SP
-	CALL	runtime·oldstack(SB)
-	MOVL	$0, 0x1004	// crash if oldstack returns
-	RET
-
-
-// bool cas(int32 *val, int32 old, int32 new)
-// Atomically:
-//	if(*val == old){
-//		*val = new;
-//		return 1;
-//	}else
-//		return 0;
-TEXT runtime·cas(SB), NOSPLIT, $0-12
-	MOVL	4(SP), BX
-	MOVL	8(SP), AX
-	MOVL	12(SP), CX
-	LOCK
-	CMPXCHGL	CX, 0(BX)
-	JZ 3(PC)
-	MOVL	$0, AX
-	RET
-	MOVL	$1, AX
-	RET
-
-// bool runtime·cas64(uint64 *val, uint64 old, uint64 new)
-// Atomically:
-//	if(*val == *old){
-//		*val = new;
-//		return 1;
-//	} else {
-//		return 0;
-//	}
-TEXT runtime·cas64(SB), NOSPLIT, $0-20
-	MOVL	4(SP), BP
-	MOVL	8(SP), AX
-	MOVL	12(SP), DX
-	MOVL	16(SP), BX
-	MOVL	20(SP), CX
-	LOCK
-	CMPXCHG8B	0(BP)
-	JNZ	cas64_fail
-	MOVL	$1, AX
-	RET
-cas64_fail:
-	MOVL	$0, AX
-	RET
-
-// bool casp(void **p, void *old, void *new)
-// Atomically:
-//	if(*p == old){
-//		*p = new;
-//		return 1;
-//	}else
-//		return 0;
-TEXT runtime·casp(SB), NOSPLIT, $0-12
-	MOVL	4(SP), BX
-	MOVL	8(SP), AX
-	MOVL	12(SP), CX
-	LOCK
-	CMPXCHGL	CX, 0(BX)
-	JZ 3(PC)
-	MOVL	$0, AX
-	RET
-	MOVL	$1, AX
-	RET
-
-// uint32 xadd(uint32 volatile *val, int32 delta)
-// Atomically:
-//	*val += delta;
-//	return *val;
-TEXT runtime·xadd(SB), NOSPLIT, $0-8
-	MOVL	4(SP), BX
-	MOVL	8(SP), AX
-	MOVL	AX, CX
-	LOCK
-	XADDL	AX, 0(BX)
-	ADDL	CX, AX
-	RET
-
-TEXT runtime·xchg(SB), NOSPLIT, $0-8
-	MOVL	4(SP), BX
-	MOVL	8(SP), AX
-	XCHGL	AX, 0(BX)
-	RET
-
-TEXT runtime·xchgp(SB), NOSPLIT, $0-8
-	MOVL	4(SP), BX
-	MOVL	8(SP), AX
-	XCHGL	AX, 0(BX)
-	RET
-
-TEXT runtime·procyield(SB),NOSPLIT,$0-0
-	MOVL	4(SP), AX
-again:
-	PAUSE
-	SUBL	$1, AX
-	JNZ	again
-	RET
-
-TEXT runtime·atomicstorep(SB), NOSPLIT, $0-8
-	MOVL	4(SP), BX
-	MOVL	8(SP), AX
-	XCHGL	AX, 0(BX)
-	RET
-
-TEXT runtime·atomicstore(SB), NOSPLIT, $0-8
-	MOVL	4(SP), BX
-	MOVL	8(SP), AX
-	XCHGL	AX, 0(BX)
-	RET
-
-// uint64 atomicload64(uint64 volatile* addr);
-// so actually
-// void atomicload64(uint64 *res, uint64 volatile *addr);
-TEXT runtime·atomicload64(SB), NOSPLIT, $0-8
-	MOVL	4(SP), BX
-	MOVL	8(SP), AX
-	// MOVQ (%EAX), %MM0
-	BYTE $0x0f; BYTE $0x6f; BYTE $0x00
-	// MOVQ %MM0, 0(%EBX)
-	BYTE $0x0f; BYTE $0x7f; BYTE $0x03
-	// EMMS
-	BYTE $0x0F; BYTE $0x77
-	RET
-
-// void runtime·atomicstore64(uint64 volatile* addr, uint64 v);
-TEXT runtime·atomicstore64(SB), NOSPLIT, $0-12
-	MOVL	4(SP), AX
-	// MOVQ and EMMS were introduced on the Pentium MMX.
-	// MOVQ 0x8(%ESP), %MM0
-	BYTE $0x0f; BYTE $0x6f; BYTE $0x44; BYTE $0x24; BYTE $0x08
-	// MOVQ %MM0, (%EAX)
-	BYTE $0x0f; BYTE $0x7f; BYTE $0x00 
-	// EMMS
-	BYTE $0x0F; BYTE $0x77
-	// This is essentially a no-op, but it provides required memory fencing.
-	// It can be replaced with MFENCE, but MFENCE was introduced only on the Pentium4 (SSE2).
-	MOVL	$0, AX
-	LOCK
-	XADDL	AX, (SP)
-	RET
-
-// void jmpdefer(fn, sp);
-// called from deferreturn.
-// 1. pop the caller
-// 2. sub 5 bytes from the callers return
-// 3. jmp to the argument
-TEXT runtime·jmpdefer(SB), NOSPLIT, $0-8
-	MOVL	4(SP), DX	// fn
-	MOVL	8(SP), BX	// caller sp
-	LEAL	-4(BX), SP	// caller sp after CALL
-	SUBL	$5, (SP)	// return to CALL again
-	MOVL	0(DX), BX
-	JMP	BX	// but first run the deferred function
-
-// Save state of caller into g->sched.
-TEXT gosave<>(SB),NOSPLIT,$0
-	PUSHL	AX
-	PUSHL	BX
-	get_tls(BX)
-	MOVL	g(BX), BX
-	LEAL	arg+0(FP), AX
-	MOVL	AX, (g_sched+gobuf_sp)(BX)
-	MOVL	-4(AX), AX
-	MOVL	AX, (g_sched+gobuf_pc)(BX)
-	MOVL	$0, (g_sched+gobuf_ret)(BX)
-	MOVL	$0, (g_sched+gobuf_ctxt)(BX)
-	POPL	BX
-	POPL	AX
-	RET
-
-// asmcgocall(void(*fn)(void*), void *arg)
-// Call fn(arg) on the scheduler stack,
-// aligned appropriately for the gcc ABI.
-// See cgocall.c for more details.
-TEXT runtime·asmcgocall(SB),NOSPLIT,$0-8
-	MOVL	fn+0(FP), AX
-	MOVL	arg+4(FP), BX
-	MOVL	SP, DX
-
-	// Figure out if we need to switch to m->g0 stack.
-	// We get called to create new OS threads too, and those
-	// come in on the m->g0 stack already.
-	get_tls(CX)
-	MOVL	m(CX), BP
-	MOVL	m_g0(BP), SI
-	MOVL	g(CX), DI
-	CMPL	SI, DI
-	JEQ	4(PC)
-	CALL	gosave<>(SB)
-	MOVL	SI, g(CX)
-	MOVL	(g_sched+gobuf_sp)(SI), SP
-
-	// Now on a scheduling stack (a pthread-created stack).
-	SUBL	$32, SP
-	ANDL	$~15, SP	// alignment, perhaps unnecessary
-	MOVL	DI, 8(SP)	// save g
-	MOVL	DX, 4(SP)	// save SP
-	MOVL	BX, 0(SP)	// first argument in x86-32 ABI
-	CALL	AX
-
-	// Restore registers, g, stack pointer.
-	get_tls(CX)
-	MOVL	8(SP), DI
-	MOVL	DI, g(CX)
-	MOVL	4(SP), SP
-	RET
-
-// cgocallback(void (*fn)(void*), void *frame, uintptr framesize)
-// Turn the fn into a Go func (by taking its address) and call
-// cgocallback_gofunc.
-TEXT runtime·cgocallback(SB),NOSPLIT,$12-12
-	LEAL	fn+0(FP), AX
-	MOVL	AX, 0(SP)
-	MOVL	frame+4(FP), AX
-	MOVL	AX, 4(SP)
-	MOVL	framesize+8(FP), AX
-	MOVL	AX, 8(SP)
-	MOVL	$runtime·cgocallback_gofunc(SB), AX
-	CALL	AX
-	RET
-
-// cgocallback_gofunc(FuncVal*, void *frame, uintptr framesize)
-// See cgocall.c for more details.
-TEXT runtime·cgocallback_gofunc(SB),NOSPLIT,$12-12
-	// If m is nil, Go did not create the current thread.
-	// Call needm to obtain one for temporary use.
-	// In this case, we're running on the thread stack, so there's
-	// lots of space, but the linker doesn't know. Hide the call from
-	// the linker analysis by using an indirect call through AX.
-	get_tls(CX)
-#ifdef GOOS_windows
-	MOVL	$0, BP
-	CMPL	CX, $0
-	JEQ	2(PC)
-#endif
-	MOVL	m(CX), BP
-	MOVL	BP, DX // saved copy of oldm
-	CMPL	BP, $0
-	JNE	havem
-needm:
-	MOVL	DX, 0(SP)
-	MOVL	$runtime·needm(SB), AX
-	CALL	AX
-	MOVL	0(SP), DX
-	get_tls(CX)
-	MOVL	m(CX), BP
-
-havem:
-	// Now there's a valid m, and we're running on its m->g0.
-	// Save current m->g0->sched.sp on stack and then set it to SP.
-	// Save current sp in m->g0->sched.sp in preparation for
-	// switch back to m->curg stack.
-	// NOTE: unwindm knows that the saved g->sched.sp is at 0(SP).
-	MOVL	m_g0(BP), SI
-	MOVL	(g_sched+gobuf_sp)(SI), AX
-	MOVL	AX, 0(SP)
-	MOVL	SP, (g_sched+gobuf_sp)(SI)
-
-	// Switch to m->curg stack and call runtime.cgocallbackg.
-	// Because we are taking over the execution of m->curg
-	// but *not* resuming what had been running, we need to
-	// save that information (m->curg->sched) so we can restore it.
-	// We can restore m->curg->sched.sp easily, because calling
-	// runtime.cgocallbackg leaves SP unchanged upon return.
-	// To save m->curg->sched.pc, we push it onto the stack.
-	// This has the added benefit that it looks to the traceback
-	// routine like cgocallbackg is going to return to that
-	// PC (because the frame we allocate below has the same
-	// size as cgocallback_gofunc's frame declared above)
-	// so that the traceback will seamlessly trace back into
-	// the earlier calls.
-	//
-	// In the new goroutine, 0(SP) holds the saved oldm (DX) register.
-	// 4(SP) and 8(SP) are unused.
-	MOVL	m_curg(BP), SI
-	MOVL	SI, g(CX)
-	MOVL	(g_sched+gobuf_sp)(SI), DI // prepare stack as DI
-	MOVL	(g_sched+gobuf_pc)(SI), BP
-	MOVL	BP, -4(DI)
-	LEAL	-(4+12)(DI), SP
-	MOVL	DX, 0(SP)
-	CALL	runtime·cgocallbackg(SB)
-	MOVL	0(SP), DX
-
-	// Restore g->sched (== m->curg->sched) from saved values.
-	get_tls(CX)
-	MOVL	g(CX), SI
-	MOVL	12(SP), BP
-	MOVL	BP, (g_sched+gobuf_pc)(SI)
-	LEAL	(12+4)(SP), DI
-	MOVL	DI, (g_sched+gobuf_sp)(SI)
-
-	// Switch back to m->g0's stack and restore m->g0->sched.sp.
-	// (Unlike m->curg, the g0 goroutine never uses sched.pc,
-	// so we do not have to restore it.)
-	MOVL	m(CX), BP
-	MOVL	m_g0(BP), SI
-	MOVL	SI, g(CX)
-	MOVL	(g_sched+gobuf_sp)(SI), SP
-	MOVL	0(SP), AX
-	MOVL	AX, (g_sched+gobuf_sp)(SI)
-	
-	// If the m on entry was nil, we called needm above to borrow an m
-	// for the duration of the call. Since the call is over, return it with dropm.
-	CMPL	DX, $0
-	JNE 3(PC)
-	MOVL	$runtime·dropm(SB), AX
-	CALL	AX
-
-	// Done!
-	RET
-
-// void setmg(M*, G*); set m and g. for use by needm.
-TEXT runtime·setmg(SB), NOSPLIT, $0-8
-#ifdef GOOS_windows
-	MOVL	mm+0(FP), AX
-	CMPL	AX, $0
-	JNE	settls
-	MOVL	$0, 0x14(FS)
-	RET
-settls:
-	LEAL	m_tls(AX), AX
-	MOVL	AX, 0x14(FS)
-#endif
-	MOVL	mm+0(FP), AX
-	get_tls(CX)
-	MOVL	mm+0(FP), AX
-	MOVL	AX, m(CX)
-	MOVL	gg+4(FP), BX
-	MOVL	BX, g(CX)
-	RET
-
-// void setmg_gcc(M*, G*); set m and g. for use by gcc
-TEXT setmg_gcc<>(SB), NOSPLIT, $0
-	get_tls(AX)
-	MOVL	mm+0(FP), DX
-	MOVL	DX, m(AX)
-	MOVL	gg+4(FP), DX
-	MOVL	DX,g (AX)
-	RET
-
-// check that SP is in range [g->stackbase, g->stackguard)
-TEXT runtime·stackcheck(SB), NOSPLIT, $0-0
-	get_tls(CX)
-	MOVL	g(CX), AX
-	CMPL	g_stackbase(AX), SP
-	JHI	2(PC)
-	INT	$3
-	CMPL	SP, g_stackguard(AX)
-	JHI	2(PC)
-	INT	$3
-	RET
-
-TEXT runtime·getcallerpc(SB),NOSPLIT,$0-4
-	MOVL	x+0(FP),AX		// addr of first arg
-	MOVL	-4(AX),AX		// get calling pc
-	RET
-
-TEXT runtime·setcallerpc(SB),NOSPLIT,$0-8
-	MOVL	x+0(FP),AX		// addr of first arg
-	MOVL	x+4(FP), BX
-	MOVL	BX, -4(AX)		// set calling pc
-	RET
-
-TEXT runtime·getcallersp(SB), NOSPLIT, $0-4
-	MOVL	sp+0(FP), AX
-	RET
-
-// int64 runtime·cputicks(void), so really
-// void runtime·cputicks(int64 *ticks)
-TEXT runtime·cputicks(SB),NOSPLIT,$0-4
-	RDTSC
-	MOVL	ret+0(FP), DI
-	MOVL	AX, 0(DI)
-	MOVL	DX, 4(DI)
-	RET
-
-TEXT runtime·ldt0setup(SB),NOSPLIT,$16-0
-	// set up ldt 7 to point at tls0
-	// ldt 1 would be fine on Linux, but on OS X, 7 is as low as we can go.
-	// the entry number is just a hint.  setldt will set up GS with what it used.
-	MOVL	$7, 0(SP)
-	LEAL	runtime·tls0(SB), AX
-	MOVL	AX, 4(SP)
-	MOVL	$32, 8(SP)	// sizeof(tls array)
-	CALL	runtime·setldt(SB)
-	RET
-
-TEXT runtime·emptyfunc(SB),0,$0-0
-	RET
-
-TEXT runtime·abort(SB),NOSPLIT,$0-0
-	INT $0x3
-
-TEXT runtime·stackguard(SB),NOSPLIT,$0-8
-	MOVL	SP, DX
-	MOVL	DX, sp+0(FP)
-	get_tls(CX)
-	MOVL	g(CX), BX
-	MOVL	g_stackguard(BX), DX
-	MOVL	DX, limit+4(FP)
-	RET
-
-GLOBL runtime·tls0(SB), $32
-
-// hash function using AES hardware instructions
-TEXT runtime·aeshash(SB),NOSPLIT,$0-12
-	MOVL	4(SP), DX	// ptr to hash value
-	MOVL	8(SP), CX	// size
-	MOVL	12(SP), AX	// ptr to data
-	JMP	runtime·aeshashbody(SB)
-
-TEXT runtime·aeshashstr(SB),NOSPLIT,$0-12
-	MOVL	4(SP), DX	// ptr to hash value
-	MOVL	12(SP), AX	// ptr to string struct
-	MOVL	4(AX), CX	// length of string
-	MOVL	(AX), AX	// string data
-	JMP	runtime·aeshashbody(SB)
-
-// AX: data
-// CX: length
-// DX: ptr to seed input / hash output
-TEXT runtime·aeshashbody(SB),NOSPLIT,$0-12
-	MOVL	(DX), X0	// seed to low 32 bits of xmm0
-	PINSRD	$1, CX, X0	// size to next 32 bits of xmm0
-	MOVO	runtime·aeskeysched+0(SB), X2
-	MOVO	runtime·aeskeysched+16(SB), X3
-	CMPL	CX, $16
-	JB	aessmall
-aesloop:
-	CMPL	CX, $16
-	JBE	aesloopend
-	MOVOU	(AX), X1
-	AESENC	X2, X0
-	AESENC	X1, X0
-	SUBL	$16, CX
-	ADDL	$16, AX
-	JMP	aesloop
-// 1-16 bytes remaining
-aesloopend:
-	// This load may overlap with the previous load above.
-	// We'll hash some bytes twice, but that's ok.
-	MOVOU	-16(AX)(CX*1), X1
-	JMP	partial
-// 0-15 bytes
-aessmall:
-	TESTL	CX, CX
-	JE	finalize	// 0 bytes
-
-	CMPB	AX, $0xf0
-	JA	highpartial
-
-	// 16 bytes loaded at this address won't cross
-	// a page boundary, so we can load it directly.
-	MOVOU	(AX), X1
-	ADDL	CX, CX
-	PAND	masks<>(SB)(CX*8), X1
-	JMP	partial
-highpartial:
-	// address ends in 1111xxxx.  Might be up against
-	// a page boundary, so load ending at last byte.
-	// Then shift bytes down using pshufb.
-	MOVOU	-16(AX)(CX*1), X1
-	ADDL	CX, CX
-	PSHUFB	shifts<>(SB)(CX*8), X1
-partial:
-	// incorporate partial block into hash
-	AESENC	X3, X0
-	AESENC	X1, X0
-finalize:	
-	// finalize hash
-	AESENC	X2, X0
-	AESENC	X3, X0
-	AESENC	X2, X0
-	MOVL	X0, (DX)
-	RET
-
-TEXT runtime·aeshash32(SB),NOSPLIT,$0-12
-	MOVL	4(SP), DX	// ptr to hash value
-	MOVL	12(SP), AX	// ptr to data
-	MOVL	(DX), X0	// seed
-	PINSRD	$1, (AX), X0	// data
-	AESENC	runtime·aeskeysched+0(SB), X0
-	AESENC	runtime·aeskeysched+16(SB), X0
-	AESENC	runtime·aeskeysched+0(SB), X0
-	MOVL	X0, (DX)
-	RET
-
-TEXT runtime·aeshash64(SB),NOSPLIT,$0-12
-	MOVL	4(SP), DX	// ptr to hash value
-	MOVL	12(SP), AX	// ptr to data
-	MOVQ	(AX), X0	// data
-	PINSRD	$2, (DX), X0	// seed
-	AESENC	runtime·aeskeysched+0(SB), X0
-	AESENC	runtime·aeskeysched+16(SB), X0
-	AESENC	runtime·aeskeysched+0(SB), X0
-	MOVL	X0, (DX)
-	RET
-
-// simple mask to get rid of data in the high part of the register.
-DATA masks<>+0x00(SB)/4, $0x00000000
-DATA masks<>+0x04(SB)/4, $0x00000000
-DATA masks<>+0x08(SB)/4, $0x00000000
-DATA masks<>+0x0c(SB)/4, $0x00000000
-	
-DATA masks<>+0x10(SB)/4, $0x000000ff
-DATA masks<>+0x14(SB)/4, $0x00000000
-DATA masks<>+0x18(SB)/4, $0x00000000
-DATA masks<>+0x1c(SB)/4, $0x00000000
-	
-DATA masks<>+0x20(SB)/4, $0x0000ffff
-DATA masks<>+0x24(SB)/4, $0x00000000
-DATA masks<>+0x28(SB)/4, $0x00000000
-DATA masks<>+0x2c(SB)/4, $0x00000000
-	
-DATA masks<>+0x30(SB)/4, $0x00ffffff
-DATA masks<>+0x34(SB)/4, $0x00000000
-DATA masks<>+0x38(SB)/4, $0x00000000
-DATA masks<>+0x3c(SB)/4, $0x00000000
-	
-DATA masks<>+0x40(SB)/4, $0xffffffff
-DATA masks<>+0x44(SB)/4, $0x00000000
-DATA masks<>+0x48(SB)/4, $0x00000000
-DATA masks<>+0x4c(SB)/4, $0x00000000
-	
-DATA masks<>+0x50(SB)/4, $0xffffffff
-DATA masks<>+0x54(SB)/4, $0x000000ff
-DATA masks<>+0x58(SB)/4, $0x00000000
-DATA masks<>+0x5c(SB)/4, $0x00000000
-	
-DATA masks<>+0x60(SB)/4, $0xffffffff
-DATA masks<>+0x64(SB)/4, $0x0000ffff
-DATA masks<>+0x68(SB)/4, $0x00000000
-DATA masks<>+0x6c(SB)/4, $0x00000000
-	
-DATA masks<>+0x70(SB)/4, $0xffffffff
-DATA masks<>+0x74(SB)/4, $0x00ffffff
-DATA masks<>+0x78(SB)/4, $0x00000000
-DATA masks<>+0x7c(SB)/4, $0x00000000
-	
-DATA masks<>+0x80(SB)/4, $0xffffffff
-DATA masks<>+0x84(SB)/4, $0xffffffff
-DATA masks<>+0x88(SB)/4, $0x00000000
-DATA masks<>+0x8c(SB)/4, $0x00000000
-	
-DATA masks<>+0x90(SB)/4, $0xffffffff
-DATA masks<>+0x94(SB)/4, $0xffffffff
-DATA masks<>+0x98(SB)/4, $0x000000ff
-DATA masks<>+0x9c(SB)/4, $0x00000000
-	
-DATA masks<>+0xa0(SB)/4, $0xffffffff
-DATA masks<>+0xa4(SB)/4, $0xffffffff
-DATA masks<>+0xa8(SB)/4, $0x0000ffff
-DATA masks<>+0xac(SB)/4, $0x00000000
-	
-DATA masks<>+0xb0(SB)/4, $0xffffffff
-DATA masks<>+0xb4(SB)/4, $0xffffffff
-DATA masks<>+0xb8(SB)/4, $0x00ffffff
-DATA masks<>+0xbc(SB)/4, $0x00000000
-	
-DATA masks<>+0xc0(SB)/4, $0xffffffff
-DATA masks<>+0xc4(SB)/4, $0xffffffff
-DATA masks<>+0xc8(SB)/4, $0xffffffff
-DATA masks<>+0xcc(SB)/4, $0x00000000
-	
-DATA masks<>+0xd0(SB)/4, $0xffffffff
-DATA masks<>+0xd4(SB)/4, $0xffffffff
-DATA masks<>+0xd8(SB)/4, $0xffffffff
-DATA masks<>+0xdc(SB)/4, $0x000000ff
-	
-DATA masks<>+0xe0(SB)/4, $0xffffffff
-DATA masks<>+0xe4(SB)/4, $0xffffffff
-DATA masks<>+0xe8(SB)/4, $0xffffffff
-DATA masks<>+0xec(SB)/4, $0x0000ffff
-	
-DATA masks<>+0xf0(SB)/4, $0xffffffff
-DATA masks<>+0xf4(SB)/4, $0xffffffff
-DATA masks<>+0xf8(SB)/4, $0xffffffff
-DATA masks<>+0xfc(SB)/4, $0x00ffffff
-
-GLOBL masks<>(SB),RODATA,$256
-
-// these are arguments to pshufb.  They move data down from
-// the high bytes of the register to the low bytes of the register.
-// index is how many bytes to move.
-DATA shifts<>+0x00(SB)/4, $0x00000000
-DATA shifts<>+0x04(SB)/4, $0x00000000
-DATA shifts<>+0x08(SB)/4, $0x00000000
-DATA shifts<>+0x0c(SB)/4, $0x00000000
-	
-DATA shifts<>+0x10(SB)/4, $0xffffff0f
-DATA shifts<>+0x14(SB)/4, $0xffffffff
-DATA shifts<>+0x18(SB)/4, $0xffffffff
-DATA shifts<>+0x1c(SB)/4, $0xffffffff
-	
-DATA shifts<>+0x20(SB)/4, $0xffff0f0e
-DATA shifts<>+0x24(SB)/4, $0xffffffff
-DATA shifts<>+0x28(SB)/4, $0xffffffff
-DATA shifts<>+0x2c(SB)/4, $0xffffffff
-	
-DATA shifts<>+0x30(SB)/4, $0xff0f0e0d
-DATA shifts<>+0x34(SB)/4, $0xffffffff
-DATA shifts<>+0x38(SB)/4, $0xffffffff
-DATA shifts<>+0x3c(SB)/4, $0xffffffff
-	
-DATA shifts<>+0x40(SB)/4, $0x0f0e0d0c
-DATA shifts<>+0x44(SB)/4, $0xffffffff
-DATA shifts<>+0x48(SB)/4, $0xffffffff
-DATA shifts<>+0x4c(SB)/4, $0xffffffff
-	
-DATA shifts<>+0x50(SB)/4, $0x0e0d0c0b
-DATA shifts<>+0x54(SB)/4, $0xffffff0f
-DATA shifts<>+0x58(SB)/4, $0xffffffff
-DATA shifts<>+0x5c(SB)/4, $0xffffffff
-	
-DATA shifts<>+0x60(SB)/4, $0x0d0c0b0a
-DATA shifts<>+0x64(SB)/4, $0xffff0f0e
-DATA shifts<>+0x68(SB)/4, $0xffffffff
-DATA shifts<>+0x6c(SB)/4, $0xffffffff
-	
-DATA shifts<>+0x70(SB)/4, $0x0c0b0a09
-DATA shifts<>+0x74(SB)/4, $0xff0f0e0d
-DATA shifts<>+0x78(SB)/4, $0xffffffff
-DATA shifts<>+0x7c(SB)/4, $0xffffffff
-	
-DATA shifts<>+0x80(SB)/4, $0x0b0a0908
-DATA shifts<>+0x84(SB)/4, $0x0f0e0d0c
-DATA shifts<>+0x88(SB)/4, $0xffffffff
-DATA shifts<>+0x8c(SB)/4, $0xffffffff
-	
-DATA shifts<>+0x90(SB)/4, $0x0a090807
-DATA shifts<>+0x94(SB)/4, $0x0e0d0c0b
-DATA shifts<>+0x98(SB)/4, $0xffffff0f
-DATA shifts<>+0x9c(SB)/4, $0xffffffff
-	
-DATA shifts<>+0xa0(SB)/4, $0x09080706
-DATA shifts<>+0xa4(SB)/4, $0x0d0c0b0a
-DATA shifts<>+0xa8(SB)/4, $0xffff0f0e
-DATA shifts<>+0xac(SB)/4, $0xffffffff
-	
-DATA shifts<>+0xb0(SB)/4, $0x08070605
-DATA shifts<>+0xb4(SB)/4, $0x0c0b0a09
-DATA shifts<>+0xb8(SB)/4, $0xff0f0e0d
-DATA shifts<>+0xbc(SB)/4, $0xffffffff
-	
-DATA shifts<>+0xc0(SB)/4, $0x07060504
-DATA shifts<>+0xc4(SB)/4, $0x0b0a0908
-DATA shifts<>+0xc8(SB)/4, $0x0f0e0d0c
-DATA shifts<>+0xcc(SB)/4, $0xffffffff
-	
-DATA shifts<>+0xd0(SB)/4, $0x06050403
-DATA shifts<>+0xd4(SB)/4, $0x0a090807
-DATA shifts<>+0xd8(SB)/4, $0x0e0d0c0b
-DATA shifts<>+0xdc(SB)/4, $0xffffff0f
-	
-DATA shifts<>+0xe0(SB)/4, $0x05040302
-DATA shifts<>+0xe4(SB)/4, $0x09080706
-DATA shifts<>+0xe8(SB)/4, $0x0d0c0b0a
-DATA shifts<>+0xec(SB)/4, $0xffff0f0e
-	
-DATA shifts<>+0xf0(SB)/4, $0x04030201
-DATA shifts<>+0xf4(SB)/4, $0x08070605
-DATA shifts<>+0xf8(SB)/4, $0x0c0b0a09
-DATA shifts<>+0xfc(SB)/4, $0xff0f0e0d
-
-GLOBL shifts<>(SB),RODATA,$256
-
-TEXT runtime·memeq(SB),NOSPLIT,$0-12
-	MOVL	a+0(FP), SI
-	MOVL	b+4(FP), DI
-	MOVL	count+8(FP), BX
-	JMP	runtime·memeqbody(SB)
-
-TEXT bytes·Equal(SB),NOSPLIT,$0-25
-	MOVL	a_len+4(FP), BX
-	MOVL	b_len+16(FP), CX
-	XORL	AX, AX
-	CMPL	BX, CX
-	JNE	eqret
-	MOVL	a+0(FP), SI
-	MOVL	b+12(FP), DI
-	CALL	runtime·memeqbody(SB)
-eqret:
-	MOVB	AX, ret+24(FP)
-	RET
-
-// a in SI
-// b in DI
-// count in BX
-TEXT runtime·memeqbody(SB),NOSPLIT,$0-0
-	XORL	AX, AX
-
-	CMPL	BX, $4
-	JB	small
-
-	// 64 bytes at a time using xmm registers
-hugeloop:
-	CMPL	BX, $64
-	JB	bigloop
-	TESTL	$0x4000000, runtime·cpuid_edx(SB) // check for sse2
-	JE	bigloop
-	MOVOU	(SI), X0
-	MOVOU	(DI), X1
-	MOVOU	16(SI), X2
-	MOVOU	16(DI), X3
-	MOVOU	32(SI), X4
-	MOVOU	32(DI), X5
-	MOVOU	48(SI), X6
-	MOVOU	48(DI), X7
-	PCMPEQB	X1, X0
-	PCMPEQB	X3, X2
-	PCMPEQB	X5, X4
-	PCMPEQB	X7, X6
-	PAND	X2, X0
-	PAND	X6, X4
-	PAND	X4, X0
-	PMOVMSKB X0, DX
-	ADDL	$64, SI
-	ADDL	$64, DI
-	SUBL	$64, BX
-	CMPL	DX, $0xffff
-	JEQ	hugeloop
-	RET
-
-	// 4 bytes at a time using 32-bit register
-bigloop:
-	CMPL	BX, $4
-	JBE	leftover
-	MOVL	(SI), CX
-	MOVL	(DI), DX
-	ADDL	$4, SI
-	ADDL	$4, DI
-	SUBL	$4, BX
-	CMPL	CX, DX
-	JEQ	bigloop
-	RET
-
-	// remaining 0-4 bytes
-leftover:
-	MOVL	-4(SI)(BX*1), CX
-	MOVL	-4(DI)(BX*1), DX
-	CMPL	CX, DX
-	SETEQ	AX
-	RET
-
-small:
-	CMPL	BX, $0
-	JEQ	equal
-
-	LEAL	0(BX*8), CX
-	NEGL	CX
-
-	MOVL	SI, DX
-	CMPB	DX, $0xfc
-	JA	si_high
-
-	// load at SI won't cross a page boundary.
-	MOVL	(SI), SI
-	JMP	si_finish
-si_high:
-	// address ends in 111111xx.  Load up to bytes we want, move to correct position.
-	MOVL	-4(SI)(BX*1), SI
-	SHRL	CX, SI
-si_finish:
-
-	// same for DI.
-	MOVL	DI, DX
-	CMPB	DX, $0xfc
-	JA	di_high
-	MOVL	(DI), DI
-	JMP	di_finish
-di_high:
-	MOVL	-4(DI)(BX*1), DI
-	SHRL	CX, DI
-di_finish:
-
-	SUBL	SI, DI
-	SHLL	CX, DI
-equal:
-	SETEQ	AX
-	RET
-
-TEXT runtime·cmpstring(SB),NOSPLIT,$0-20
-	MOVL	s1+0(FP), SI
-	MOVL	s1+4(FP), BX
-	MOVL	s2+8(FP), DI
-	MOVL	s2+12(FP), DX
-	CALL	runtime·cmpbody(SB)
-	MOVL	AX, res+16(FP)
-	RET
-
-TEXT bytes·Compare(SB),NOSPLIT,$0-28
-	MOVL	s1+0(FP), SI
-	MOVL	s1+4(FP), BX
-	MOVL	s2+12(FP), DI
-	MOVL	s2+16(FP), DX
-	CALL	runtime·cmpbody(SB)
-	MOVL	AX, res+24(FP)
-	RET
-
-TEXT bytes·IndexByte(SB),NOSPLIT,$0
-	MOVL	s+0(FP), SI
-	MOVL	s_len+4(FP), CX
-	MOVB	c+12(FP), AL
-	MOVL	SI, DI
-	CLD; REPN; SCASB
-	JZ 3(PC)
-	MOVL	$-1, ret+16(FP)
-	RET
-	SUBL	SI, DI
-	SUBL	$1, DI
-	MOVL	DI, ret+16(FP)
-	RET
-
-TEXT strings·IndexByte(SB),NOSPLIT,$0
-	MOVL	s+0(FP), SI
-	MOVL	s_len+4(FP), CX
-	MOVB	c+8(FP), AL
-	MOVL	SI, DI
-	CLD; REPN; SCASB
-	JZ 3(PC)
-	MOVL	$-1, ret+12(FP)
-	RET
-	SUBL	SI, DI
-	SUBL	$1, DI
-	MOVL	DI, ret+12(FP)
-	RET
-
-// input:
-//   SI = a
-//   DI = b
-//   BX = alen
-//   DX = blen
-// output:
-//   AX = 1/0/-1
-TEXT runtime·cmpbody(SB),NOSPLIT,$0-0
-	CMPL	SI, DI
-	JEQ	cmp_allsame
-	CMPL	BX, DX
-	MOVL	DX, BP
-	CMOVLLT	BX, BP // BP = min(alen, blen)
-	CMPL	BP, $4
-	JB	cmp_small
-	TESTL	$0x4000000, runtime·cpuid_edx(SB) // check for sse2
-	JE	cmp_mediumloop
-cmp_largeloop:
-	CMPL	BP, $16
-	JB	cmp_mediumloop
-	MOVOU	(SI), X0
-	MOVOU	(DI), X1
-	PCMPEQB X0, X1
-	PMOVMSKB X1, AX
-	XORL	$0xffff, AX	// convert EQ to NE
-	JNE	cmp_diff16	// branch if at least one byte is not equal
-	ADDL	$16, SI
-	ADDL	$16, DI
-	SUBL	$16, BP
-	JMP	cmp_largeloop
-
-cmp_diff16:
-	BSFL	AX, BX	// index of first byte that differs
-	XORL	AX, AX
-	MOVB	(SI)(BX*1), CX
-	CMPB	CX, (DI)(BX*1)
-	SETHI	AX
-	LEAL	-1(AX*2), AX	// convert 1/0 to +1/-1
-	RET
-
-cmp_mediumloop:
-	CMPL	BP, $4
-	JBE	cmp_0through4
-	MOVL	(SI), AX
-	MOVL	(DI), CX
-	CMPL	AX, CX
-	JNE	cmp_diff4
-	ADDL	$4, SI
-	ADDL	$4, DI
-	SUBL	$4, BP
-	JMP	cmp_mediumloop
-
-cmp_0through4:
-	MOVL	-4(SI)(BP*1), AX
-	MOVL	-4(DI)(BP*1), CX
-	CMPL	AX, CX
-	JEQ	cmp_allsame
-
-cmp_diff4:
-	BSWAPL	AX	// reverse order of bytes
-	BSWAPL	CX
-	XORL	AX, CX	// find bit differences
-	BSRL	CX, CX	// index of highest bit difference
-	SHRL	CX, AX	// move a's bit to bottom
-	ANDL	$1, AX	// mask bit
-	LEAL	-1(AX*2), AX // 1/0 => +1/-1
-	RET
-
-	// 0-3 bytes in common
-cmp_small:
-	LEAL	(BP*8), CX
-	NEGL	CX
-	JEQ	cmp_allsame
-
-	// load si
-	CMPB	SI, $0xfc
-	JA	cmp_si_high
-	MOVL	(SI), SI
-	JMP	cmp_si_finish
-cmp_si_high:
-	MOVL	-4(SI)(BP*1), SI
-	SHRL	CX, SI
-cmp_si_finish:
-	SHLL	CX, SI
-
-	// same for di
-	CMPB	DI, $0xfc
-	JA	cmp_di_high
-	MOVL	(DI), DI
-	JMP	cmp_di_finish
-cmp_di_high:
-	MOVL	-4(DI)(BP*1), DI
-	SHRL	CX, DI
-cmp_di_finish:
-	SHLL	CX, DI
-
-	BSWAPL	SI	// reverse order of bytes
-	BSWAPL	DI
-	XORL	SI, DI	// find bit differences
-	JEQ	cmp_allsame
-	BSRL	DI, CX	// index of highest bit difference
-	SHRL	CX, SI	// move a's bit to bottom
-	ANDL	$1, SI	// mask bit
-	LEAL	-1(SI*2), AX // 1/0 => +1/-1
-	RET
-
-	// all the bytes in common are the same, so we just need
-	// to compare the lengths.
-cmp_allsame:
-	XORL	AX, AX
-	XORL	CX, CX
-	CMPL	BX, DX
-	SETGT	AX	// 1 if alen > blen
-	SETEQ	CX	// 1 if alen == blen
-	LEAL	-1(CX)(AX*2), AX	// 1,0,-1 result
-	RET
-
-// A Duff's device for zeroing memory.
-// The compiler jumps to computed addresses within
-// this routine to zero chunks of memory.  Do not
-// change this code without also changing the code
-// in ../../cmd/8g/ggen.c:clearfat.
-// AX: zero
-// DI: ptr to memory to be zeroed
-// DI is updated as a side effect.
-TEXT runtime·duffzero(SB), NOSPLIT, $0-0
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	STOSL
-	RET
-
-// A Duff's device for copying memory.
-// The compiler jumps to computed addresses within
-// this routine to copy chunks of memory.  Source
-// and destination must not overlap.  Do not
-// change this code without also changing the code
-// in ../../cmd/6g/cgen.c:sgen.
-// SI: ptr to source memory
-// DI: ptr to destination memory
-// SI and DI are updated as a side effect.
-
-// NOTE: this is equivalent to a sequence of MOVSL but
-// for some reason MOVSL is really slow.
-TEXT runtime·duffcopy(SB), NOSPLIT, $0-0
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	MOVL	(SI),CX
-	ADDL	$4,SI
-	MOVL	CX,(DI)
-	ADDL	$4,DI
-	
-	RET
-
-TEXT runtime·timenow(SB), NOSPLIT, $0-0
-	JMP	time·now(SB)
diff --git a/src/pkg/runtime/asm_amd64.s b/src/pkg/runtime/asm_amd64.s
deleted file mode 100644
index 2e28866..0000000
--- a/src/pkg/runtime/asm_amd64.s
+++ /dev/null
@@ -1,2200 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "zasm_GOOS_GOARCH.h"
-#include "funcdata.h"
-#include "../../cmd/ld/textflag.h"
-
-TEXT _rt0_go(SB),NOSPLIT,$0
-	// copy arguments forward on an even stack
-	MOVQ	DI, AX		// argc
-	MOVQ	SI, BX		// argv
-	SUBQ	$(4*8+7), SP		// 2args 2auto
-	ANDQ	$~15, SP
-	MOVQ	AX, 16(SP)
-	MOVQ	BX, 24(SP)
-	
-	// create istack out of the given (operating system) stack.
-	// _cgo_init may update stackguard.
-	MOVQ	$runtime·g0(SB), DI
-	LEAQ	(-64*1024+104)(SP), BX
-	MOVQ	BX, g_stackguard(DI)
-	MOVQ	BX, g_stackguard0(DI)
-	MOVQ	SP, g_stackbase(DI)
-
-	// find out information about the processor we're on
-	MOVQ	$0, AX
-	CPUID
-	CMPQ	AX, $0
-	JE	nocpuinfo
-	MOVQ	$1, AX
-	CPUID
-	MOVL	CX, runtime·cpuid_ecx(SB)
-	MOVL	DX, runtime·cpuid_edx(SB)
-nocpuinfo:	
-	
-	// if there is an _cgo_init, call it.
-	MOVQ	_cgo_init(SB), AX
-	TESTQ	AX, AX
-	JZ	needtls
-	// g0 already in DI
-	MOVQ	DI, CX	// Win64 uses CX for first parameter
-	MOVQ	$setmg_gcc<>(SB), SI
-	CALL	AX
-	// update stackguard after _cgo_init
-	MOVQ	$runtime·g0(SB), CX
-	MOVQ	g_stackguard0(CX), AX
-	MOVQ	AX, g_stackguard(CX)
-	CMPL	runtime·iswindows(SB), $0
-	JEQ ok
-
-needtls:
-	// skip TLS setup on Plan 9
-	CMPL	runtime·isplan9(SB), $1
-	JEQ ok
-	// skip TLS setup on Solaris
-	CMPL	runtime·issolaris(SB), $1
-	JEQ ok
-
-	LEAQ	runtime·tls0(SB), DI
-	CALL	runtime·settls(SB)
-
-	// store through it, to make sure it works
-	get_tls(BX)
-	MOVQ	$0x123, g(BX)
-	MOVQ	runtime·tls0(SB), AX
-	CMPQ	AX, $0x123
-	JEQ 2(PC)
-	MOVL	AX, 0	// abort
-ok:
-	// set the per-goroutine and per-mach "registers"
-	get_tls(BX)
-	LEAQ	runtime·g0(SB), CX
-	MOVQ	CX, g(BX)
-	LEAQ	runtime·m0(SB), AX
-	MOVQ	AX, m(BX)
-
-	// save m->g0 = g0
-	MOVQ	CX, m_g0(AX)
-
-	CLD				// convention is D is always left cleared
-	CALL	runtime·check(SB)
-
-	MOVL	16(SP), AX		// copy argc
-	MOVL	AX, 0(SP)
-	MOVQ	24(SP), AX		// copy argv
-	MOVQ	AX, 8(SP)
-	CALL	runtime·args(SB)
-	CALL	runtime·osinit(SB)
-	CALL	runtime·hashinit(SB)
-	CALL	runtime·schedinit(SB)
-
-	// create a new goroutine to start program
-	PUSHQ	$runtime·main·f(SB)		// entry
-	PUSHQ	$0			// arg size
-	ARGSIZE(16)
-	CALL	runtime·newproc(SB)
-	ARGSIZE(-1)
-	POPQ	AX
-	POPQ	AX
-
-	// start this M
-	CALL	runtime·mstart(SB)
-
-	MOVL	$0xf1, 0xf1  // crash
-	RET
-
-DATA	runtime·main·f+0(SB)/8,$runtime·main(SB)
-GLOBL	runtime·main·f(SB),RODATA,$8
-
-TEXT runtime·breakpoint(SB),NOSPLIT,$0-0
-	BYTE	$0xcc
-	RET
-
-TEXT runtime·asminit(SB),NOSPLIT,$0-0
-	// No per-thread init.
-	RET
-
-/*
- *  go-routine
- */
-
-// void gosave(Gobuf*)
-// save state in Gobuf; setjmp
-TEXT runtime·gosave(SB), NOSPLIT, $0-8
-	MOVQ	8(SP), AX		// gobuf
-	LEAQ	8(SP), BX		// caller's SP
-	MOVQ	BX, gobuf_sp(AX)
-	MOVQ	0(SP), BX		// caller's PC
-	MOVQ	BX, gobuf_pc(AX)
-	MOVQ	$0, gobuf_ret(AX)
-	MOVQ	$0, gobuf_ctxt(AX)
-	get_tls(CX)
-	MOVQ	g(CX), BX
-	MOVQ	BX, gobuf_g(AX)
-	RET
-
-// void gogo(Gobuf*)
-// restore state from Gobuf; longjmp
-TEXT runtime·gogo(SB), NOSPLIT, $0-8
-	MOVQ	8(SP), BX		// gobuf
-	MOVQ	gobuf_g(BX), DX
-	MOVQ	0(DX), CX		// make sure g != nil
-	get_tls(CX)
-	MOVQ	DX, g(CX)
-	MOVQ	gobuf_sp(BX), SP	// restore SP
-	MOVQ	gobuf_ret(BX), AX
-	MOVQ	gobuf_ctxt(BX), DX
-	MOVQ	$0, gobuf_sp(BX)	// clear to help garbage collector
-	MOVQ	$0, gobuf_ret(BX)
-	MOVQ	$0, gobuf_ctxt(BX)
-	MOVQ	gobuf_pc(BX), BX
-	JMP	BX
-
-// void mcall(void (*fn)(G*))
-// Switch to m->g0's stack, call fn(g).
-// Fn must never return.  It should gogo(&g->sched)
-// to keep running g.
-TEXT runtime·mcall(SB), NOSPLIT, $0-8
-	MOVQ	fn+0(FP), DI
-	
-	get_tls(CX)
-	MOVQ	g(CX), AX	// save state in g->sched
-	MOVQ	0(SP), BX	// caller's PC
-	MOVQ	BX, (g_sched+gobuf_pc)(AX)
-	LEAQ	8(SP), BX	// caller's SP
-	MOVQ	BX, (g_sched+gobuf_sp)(AX)
-	MOVQ	AX, (g_sched+gobuf_g)(AX)
-
-	// switch to m->g0 & its stack, call fn
-	MOVQ	m(CX), BX
-	MOVQ	m_g0(BX), SI
-	CMPQ	SI, AX	// if g == m->g0 call badmcall
-	JNE	3(PC)
-	MOVQ	$runtime·badmcall(SB), AX
-	JMP	AX
-	MOVQ	SI, g(CX)	// g = m->g0
-	MOVQ	(g_sched+gobuf_sp)(SI), SP	// sp = m->g0->sched.sp
-	PUSHQ	AX
-	ARGSIZE(8)
-	CALL	DI
-	POPQ	AX
-	MOVQ	$runtime·badmcall2(SB), AX
-	JMP	AX
-	RET
-
-/*
- * support for morestack
- */
-
-// Called during function prolog when more stack is needed.
-// Caller has already done get_tls(CX); MOVQ m(CX), BX.
-//
-// The traceback routines see morestack on a g0 as being
-// the top of a stack (for example, morestack calling newstack
-// calling the scheduler calling newm calling gc), so we must
-// record an argument size. For that purpose, it has no arguments.
-TEXT runtime·morestack(SB),NOSPLIT,$0-0
-	// Cannot grow scheduler stack (m->g0).
-	MOVQ	m_g0(BX), SI
-	CMPQ	g(CX), SI
-	JNE	2(PC)
-	INT	$3
-
-	// Called from f.
-	// Set m->morebuf to f's caller.
-	MOVQ	8(SP), AX	// f's caller's PC
-	MOVQ	AX, (m_morebuf+gobuf_pc)(BX)
-	LEAQ	16(SP), AX	// f's caller's SP
-	MOVQ	AX, (m_morebuf+gobuf_sp)(BX)
-	MOVQ	AX, m_moreargp(BX)
-	get_tls(CX)
-	MOVQ	g(CX), SI
-	MOVQ	SI, (m_morebuf+gobuf_g)(BX)
-
-	// Set g->sched to context in f.
-	MOVQ	0(SP), AX // f's PC
-	MOVQ	AX, (g_sched+gobuf_pc)(SI)
-	MOVQ	SI, (g_sched+gobuf_g)(SI)
-	LEAQ	8(SP), AX // f's SP
-	MOVQ	AX, (g_sched+gobuf_sp)(SI)
-	MOVQ	DX, (g_sched+gobuf_ctxt)(SI)
-
-	// Call newstack on m->g0's stack.
-	MOVQ	m_g0(BX), BP
-	MOVQ	BP, g(CX)
-	MOVQ	(g_sched+gobuf_sp)(BP), SP
-	CALL	runtime·newstack(SB)
-	MOVQ	$0, 0x1003	// crash if newstack returns
-	RET
-
-// Called from panic.  Mimics morestack,
-// reuses stack growth code to create a frame
-// with the desired args running the desired function.
-//
-// func call(fn *byte, arg *byte, argsize uint32).
-TEXT runtime·newstackcall(SB), NOSPLIT, $0-20
-	get_tls(CX)
-	MOVQ	m(CX), BX
-
-	// Save our caller's state as the PC and SP to
-	// restore when returning from f.
-	MOVQ	0(SP), AX	// our caller's PC
-	MOVQ	AX, (m_morebuf+gobuf_pc)(BX)
-	LEAQ	8(SP), AX	// our caller's SP
-	MOVQ	AX, (m_morebuf+gobuf_sp)(BX)
-	MOVQ	g(CX), AX
-	MOVQ	AX, (m_morebuf+gobuf_g)(BX)
-	
-	// Save our own state as the PC and SP to restore
-	// if this goroutine needs to be restarted.
-	MOVQ	$runtime·newstackcall(SB), (g_sched+gobuf_pc)(AX)
-	MOVQ	SP, (g_sched+gobuf_sp)(AX)
-
-	// Set up morestack arguments to call f on a new stack.
-	// We set f's frame size to 1, as a hint to newstack
-	// that this is a call from runtime·newstackcall.
-	// If it turns out that f needs a larger frame than
-	// the default stack, f's usual stack growth prolog will
-	// allocate a new segment (and recopy the arguments).
-	MOVQ	8(SP), AX	// fn
-	MOVQ	16(SP), DX	// arg frame
-	MOVL	24(SP), CX	// arg size
-
-	MOVQ	AX, m_cret(BX)	// f's PC
-	MOVQ	DX, m_moreargp(BX)	// argument frame pointer
-	MOVL	CX, m_moreargsize(BX)	// f's argument size
-	MOVL	$1, m_moreframesize(BX)	// f's frame size
-
-	// Call newstack on m->g0's stack.
-	MOVQ	m_g0(BX), BP
-	get_tls(CX)
-	MOVQ	BP, g(CX)
-	MOVQ	(g_sched+gobuf_sp)(BP), SP
-	CALL	runtime·newstack(SB)
-	MOVQ	$0, 0x1103	// crash if newstack returns
-	RET
-
-// reflect·call: call a function with the given argument list
-// func call(f *FuncVal, arg *byte, argsize uint32).
-// we don't have variable-sized frames, so we use a small number
-// of constant-sized-frame functions to encode a few bits of size in the pc.
-// Caution: ugly multiline assembly macros in your future!
-
-#define DISPATCH(NAME,MAXSIZE)		\
-	CMPQ	CX, $MAXSIZE;		\
-	JA	3(PC);			\
-	MOVQ	$runtime·NAME(SB), AX;	\
-	JMP	AX
-// Note: can't just "JMP runtime·NAME(SB)" - bad inlining results.
-
-TEXT reflect·call(SB), NOSPLIT, $0-24
-	MOVLQZX argsize+16(FP), CX
-	DISPATCH(call16, 16)
-	DISPATCH(call32, 32)
-	DISPATCH(call64, 64)
-	DISPATCH(call128, 128)
-	DISPATCH(call256, 256)
-	DISPATCH(call512, 512)
-	DISPATCH(call1024, 1024)
-	DISPATCH(call2048, 2048)
-	DISPATCH(call4096, 4096)
-	DISPATCH(call8192, 8192)
-	DISPATCH(call16384, 16384)
-	DISPATCH(call32768, 32768)
-	DISPATCH(call65536, 65536)
-	DISPATCH(call131072, 131072)
-	DISPATCH(call262144, 262144)
-	DISPATCH(call524288, 524288)
-	DISPATCH(call1048576, 1048576)
-	DISPATCH(call2097152, 2097152)
-	DISPATCH(call4194304, 4194304)
-	DISPATCH(call8388608, 8388608)
-	DISPATCH(call16777216, 16777216)
-	DISPATCH(call33554432, 33554432)
-	DISPATCH(call67108864, 67108864)
-	DISPATCH(call134217728, 134217728)
-	DISPATCH(call268435456, 268435456)
-	DISPATCH(call536870912, 536870912)
-	DISPATCH(call1073741824, 1073741824)
-	MOVQ	$runtime·badreflectcall(SB), AX
-	JMP	AX
-
-// Argument map for the callXX frames.  Each has one
-// stack map (for the single call) with 3 arguments.
-DATA gcargs_reflectcall<>+0x00(SB)/4, $1  // 1 stackmap
-DATA gcargs_reflectcall<>+0x04(SB)/4, $6  // 3 args
-DATA gcargs_reflectcall<>+0x08(SB)/4, $(const_BitsPointer+(const_BitsPointer<<2)+(const_BitsScalar<<4))
-GLOBL gcargs_reflectcall<>(SB),RODATA,$12
-
-// callXX frames have no locals
-DATA gclocals_reflectcall<>+0x00(SB)/4, $1  // 1 stackmap
-DATA gclocals_reflectcall<>+0x04(SB)/4, $0  // 0 locals
-GLOBL gclocals_reflectcall<>(SB),RODATA,$8
-
-#define CALLFN(NAME,MAXSIZE)			\
-TEXT runtime·NAME(SB), WRAPPER, $MAXSIZE-24;	\
-	FUNCDATA $FUNCDATA_ArgsPointerMaps,gcargs_reflectcall<>(SB);	\
-	FUNCDATA $FUNCDATA_LocalsPointerMaps,gclocals_reflectcall<>(SB);\
-	/* copy arguments to stack */		\
-	MOVQ	argptr+8(FP), SI;		\
-	MOVLQZX argsize+16(FP), CX;		\
-	MOVQ	SP, DI;				\
-	REP;MOVSB;				\
-	/* call function */			\
-	MOVQ	f+0(FP), DX;			\
-	PCDATA  $PCDATA_StackMapIndex, $0;	\
-	CALL	(DX);				\
-	/* copy return values back */		\
-	MOVQ	argptr+8(FP), DI;		\
-	MOVLQZX	argsize+16(FP), CX;		\
-	MOVLQZX retoffset+20(FP), BX;		\
-	MOVQ	SP, SI;				\
-	ADDQ	BX, DI;				\
-	ADDQ	BX, SI;				\
-	SUBQ	BX, CX;				\
-	REP;MOVSB;				\
-	RET
-
-CALLFN(call16, 16)
-CALLFN(call32, 32)
-CALLFN(call64, 64)
-CALLFN(call128, 128)
-CALLFN(call256, 256)
-CALLFN(call512, 512)
-CALLFN(call1024, 1024)
-CALLFN(call2048, 2048)
-CALLFN(call4096, 4096)
-CALLFN(call8192, 8192)
-CALLFN(call16384, 16384)
-CALLFN(call32768, 32768)
-CALLFN(call65536, 65536)
-CALLFN(call131072, 131072)
-CALLFN(call262144, 262144)
-CALLFN(call524288, 524288)
-CALLFN(call1048576, 1048576)
-CALLFN(call2097152, 2097152)
-CALLFN(call4194304, 4194304)
-CALLFN(call8388608, 8388608)
-CALLFN(call16777216, 16777216)
-CALLFN(call33554432, 33554432)
-CALLFN(call67108864, 67108864)
-CALLFN(call134217728, 134217728)
-CALLFN(call268435456, 268435456)
-CALLFN(call536870912, 536870912)
-CALLFN(call1073741824, 1073741824)
-
-// Return point when leaving stack.
-//
-// Lessstack can appear in stack traces for the same reason
-// as morestack; in that context, it has 0 arguments.
-TEXT runtime·lessstack(SB), NOSPLIT, $0-0
-	// Save return value in m->cret
-	get_tls(CX)
-	MOVQ	m(CX), BX
-	MOVQ	AX, m_cret(BX)
-
-	// Call oldstack on m->g0's stack.
-	MOVQ	m_g0(BX), BP
-	MOVQ	BP, g(CX)
-	MOVQ	(g_sched+gobuf_sp)(BP), SP
-	CALL	runtime·oldstack(SB)
-	MOVQ	$0, 0x1004	// crash if oldstack returns
-	RET
-
-// morestack trampolines
-TEXT runtime·morestack00(SB),NOSPLIT,$0
-	get_tls(CX)
-	MOVQ	m(CX), BX
-	MOVQ	$0, AX
-	MOVQ	AX, m_moreframesize(BX)
-	MOVQ	$runtime·morestack(SB), AX
-	JMP	AX
-
-TEXT runtime·morestack01(SB),NOSPLIT,$0
-	get_tls(CX)
-	MOVQ	m(CX), BX
-	SHLQ	$32, AX
-	MOVQ	AX, m_moreframesize(BX)
-	MOVQ	$runtime·morestack(SB), AX
-	JMP	AX
-
-TEXT runtime·morestack10(SB),NOSPLIT,$0
-	get_tls(CX)
-	MOVQ	m(CX), BX
-	MOVLQZX	AX, AX
-	MOVQ	AX, m_moreframesize(BX)
-	MOVQ	$runtime·morestack(SB), AX
-	JMP	AX
-
-TEXT runtime·morestack11(SB),NOSPLIT,$0
-	get_tls(CX)
-	MOVQ	m(CX), BX
-	MOVQ	AX, m_moreframesize(BX)
-	MOVQ	$runtime·morestack(SB), AX
-	JMP	AX
-
-// subcases of morestack01
-// with const of 8,16,...48
-TEXT runtime·morestack8(SB),NOSPLIT,$0
-	MOVQ	$1, R8
-	MOVQ	$morestack<>(SB), AX
-	JMP	AX
-
-TEXT runtime·morestack16(SB),NOSPLIT,$0
-	MOVQ	$2, R8
-	MOVQ	$morestack<>(SB), AX
-	JMP	AX
-
-TEXT runtime·morestack24(SB),NOSPLIT,$0
-	MOVQ	$3, R8
-	MOVQ	$morestack<>(SB), AX
-	JMP	AX
-
-TEXT runtime·morestack32(SB),NOSPLIT,$0
-	MOVQ	$4, R8
-	MOVQ	$morestack<>(SB), AX
-	JMP	AX
-
-TEXT runtime·morestack40(SB),NOSPLIT,$0
-	MOVQ	$5, R8
-	MOVQ	$morestack<>(SB), AX
-	JMP	AX
-
-TEXT runtime·morestack48(SB),NOSPLIT,$0
-	MOVQ	$6, R8
-	MOVQ	$morestack<>(SB), AX
-	JMP	AX
-
-TEXT morestack<>(SB),NOSPLIT,$0
-	get_tls(CX)
-	MOVQ	m(CX), BX
-	SHLQ	$35, R8
-	MOVQ	R8, m_moreframesize(BX)
-	MOVQ	$runtime·morestack(SB), AX
-	JMP	AX
-
-TEXT runtime·morestack00_noctxt(SB),NOSPLIT,$0
-	MOVL	$0, DX
-	JMP	runtime·morestack00(SB)
-
-TEXT runtime·morestack01_noctxt(SB),NOSPLIT,$0
-	MOVL	$0, DX
-	JMP	runtime·morestack01(SB)
-
-TEXT runtime·morestack10_noctxt(SB),NOSPLIT,$0
-	MOVL	$0, DX
-	JMP	runtime·morestack10(SB)
-
-TEXT runtime·morestack11_noctxt(SB),NOSPLIT,$0
-	MOVL	$0, DX
-	JMP	runtime·morestack11(SB)
-
-TEXT runtime·morestack8_noctxt(SB),NOSPLIT,$0
-	MOVL	$0, DX
-	JMP	runtime·morestack8(SB)
-
-TEXT runtime·morestack16_noctxt(SB),NOSPLIT,$0
-	MOVL	$0, DX
-	JMP	runtime·morestack16(SB)
-
-TEXT runtime·morestack24_noctxt(SB),NOSPLIT,$0
-	MOVL	$0, DX
-	JMP	runtime·morestack24(SB)
-
-TEXT runtime·morestack32_noctxt(SB),NOSPLIT,$0
-	MOVL	$0, DX
-	JMP	runtime·morestack32(SB)
-
-TEXT runtime·morestack40_noctxt(SB),NOSPLIT,$0
-	MOVL	$0, DX
-	JMP	runtime·morestack40(SB)
-
-TEXT runtime·morestack48_noctxt(SB),NOSPLIT,$0
-	MOVL	$0, DX
-	JMP	runtime·morestack48(SB)
-
-// bool cas(int32 *val, int32 old, int32 new)
-// Atomically:
-//	if(*val == old){
-//		*val = new;
-//		return 1;
-//	} else
-//		return 0;
-TEXT runtime·cas(SB), NOSPLIT, $0-16
-	MOVQ	8(SP), BX
-	MOVL	16(SP), AX
-	MOVL	20(SP), CX
-	LOCK
-	CMPXCHGL	CX, 0(BX)
-	JZ 3(PC)
-	MOVL	$0, AX
-	RET
-	MOVL	$1, AX
-	RET
-
-// bool	runtime·cas64(uint64 *val, uint64 old, uint64 new)
-// Atomically:
-//	if(*val == *old){
-//		*val = new;
-//		return 1;
-//	} else {
-//		return 0;
-//	}
-TEXT runtime·cas64(SB), NOSPLIT, $0-24
-	MOVQ	8(SP), BX
-	MOVQ	16(SP), AX
-	MOVQ	24(SP), CX
-	LOCK
-	CMPXCHGQ	CX, 0(BX)
-	JNZ	cas64_fail
-	MOVL	$1, AX
-	RET
-cas64_fail:
-	MOVL	$0, AX
-	RET
-
-// bool casp(void **val, void *old, void *new)
-// Atomically:
-//	if(*val == old){
-//		*val = new;
-//		return 1;
-//	} else
-//		return 0;
-TEXT runtime·casp(SB), NOSPLIT, $0-24
-	MOVQ	8(SP), BX
-	MOVQ	16(SP), AX
-	MOVQ	24(SP), CX
-	LOCK
-	CMPXCHGQ	CX, 0(BX)
-	JZ 3(PC)
-	MOVL	$0, AX
-	RET
-	MOVL	$1, AX
-	RET
-
-// uint32 xadd(uint32 volatile *val, int32 delta)
-// Atomically:
-//	*val += delta;
-//	return *val;
-TEXT runtime·xadd(SB), NOSPLIT, $0-12
-	MOVQ	8(SP), BX
-	MOVL	16(SP), AX
-	MOVL	AX, CX
-	LOCK
-	XADDL	AX, 0(BX)
-	ADDL	CX, AX
-	RET
-
-TEXT runtime·xadd64(SB), NOSPLIT, $0-16
-	MOVQ	8(SP), BX
-	MOVQ	16(SP), AX
-	MOVQ	AX, CX
-	LOCK
-	XADDQ	AX, 0(BX)
-	ADDQ	CX, AX
-	RET
-
-TEXT runtime·xchg(SB), NOSPLIT, $0-12
-	MOVQ	8(SP), BX
-	MOVL	16(SP), AX
-	XCHGL	AX, 0(BX)
-	RET
-
-TEXT runtime·xchg64(SB), NOSPLIT, $0-16
-	MOVQ	8(SP), BX
-	MOVQ	16(SP), AX
-	XCHGQ	AX, 0(BX)
-	RET
-
-TEXT runtime·xchgp(SB), NOSPLIT, $0-16
-	MOVQ	8(SP), BX
-	MOVQ	16(SP), AX
-	XCHGQ	AX, 0(BX)
-	RET
-
-TEXT runtime·procyield(SB),NOSPLIT,$0-0
-	MOVL	8(SP), AX
-again:
-	PAUSE
-	SUBL	$1, AX
-	JNZ	again
-	RET
-
-TEXT runtime·atomicstorep(SB), NOSPLIT, $0-16
-	MOVQ	8(SP), BX
-	MOVQ	16(SP), AX
-	XCHGQ	AX, 0(BX)
-	RET
-
-TEXT runtime·atomicstore(SB), NOSPLIT, $0-12
-	MOVQ	8(SP), BX
-	MOVL	16(SP), AX
-	XCHGL	AX, 0(BX)
-	RET
-
-TEXT runtime·atomicstore64(SB), NOSPLIT, $0-16
-	MOVQ	8(SP), BX
-	MOVQ	16(SP), AX
-	XCHGQ	AX, 0(BX)
-	RET
-
-// void jmpdefer(fn, sp);
-// called from deferreturn.
-// 1. pop the caller
-// 2. sub 5 bytes from the callers return
-// 3. jmp to the argument
-TEXT runtime·jmpdefer(SB), NOSPLIT, $0-16
-	MOVQ	8(SP), DX	// fn
-	MOVQ	16(SP), BX	// caller sp
-	LEAQ	-8(BX), SP	// caller sp after CALL
-	SUBQ	$5, (SP)	// return to CALL again
-	MOVQ	0(DX), BX
-	JMP	BX	// but first run the deferred function
-
-// Save state of caller into g->sched. Smashes R8, R9.
-TEXT gosave<>(SB),NOSPLIT,$0
-	get_tls(R8)
-	MOVQ	g(R8), R8
-	MOVQ	0(SP), R9
-	MOVQ	R9, (g_sched+gobuf_pc)(R8)
-	LEAQ	8(SP), R9
-	MOVQ	R9, (g_sched+gobuf_sp)(R8)
-	MOVQ	$0, (g_sched+gobuf_ret)(R8)
-	MOVQ	$0, (g_sched+gobuf_ctxt)(R8)
-	RET
-
-// asmcgocall(void(*fn)(void*), void *arg)
-// Call fn(arg) on the scheduler stack,
-// aligned appropriately for the gcc ABI.
-// See cgocall.c for more details.
-TEXT runtime·asmcgocall(SB),NOSPLIT,$0-16
-	MOVQ	fn+0(FP), AX
-	MOVQ	arg+8(FP), BX
-	MOVQ	SP, DX
-
-	// Figure out if we need to switch to m->g0 stack.
-	// We get called to create new OS threads too, and those
-	// come in on the m->g0 stack already.
-	get_tls(CX)
-	MOVQ	m(CX), BP
-	MOVQ	m_g0(BP), SI
-	MOVQ	g(CX), DI
-	CMPQ	SI, DI
-	JEQ	nosave
-	MOVQ	m_gsignal(BP), SI
-	CMPQ	SI, DI
-	JEQ	nosave
-	
-	MOVQ	m_g0(BP), SI
-	CALL	gosave<>(SB)
-	MOVQ	SI, g(CX)
-	MOVQ	(g_sched+gobuf_sp)(SI), SP
-nosave:
-
-	// Now on a scheduling stack (a pthread-created stack).
-	// Make sure we have enough room for 4 stack-backed fast-call
-	// registers as per windows amd64 calling convention.
-	SUBQ	$64, SP
-	ANDQ	$~15, SP	// alignment for gcc ABI
-	MOVQ	DI, 48(SP)	// save g
-	MOVQ	DX, 40(SP)	// save SP
-	MOVQ	BX, DI		// DI = first argument in AMD64 ABI
-	MOVQ	BX, CX		// CX = first argument in Win64
-	CALL	AX
-
-	// Restore registers, g, stack pointer.
-	get_tls(CX)
-	MOVQ	48(SP), DI
-	MOVQ	DI, g(CX)
-	MOVQ	40(SP), SP
-	RET
-
-// cgocallback(void (*fn)(void*), void *frame, uintptr framesize)
-// Turn the fn into a Go func (by taking its address) and call
-// cgocallback_gofunc.
-TEXT runtime·cgocallback(SB),NOSPLIT,$24-24
-	LEAQ	fn+0(FP), AX
-	MOVQ	AX, 0(SP)
-	MOVQ	frame+8(FP), AX
-	MOVQ	AX, 8(SP)
-	MOVQ	framesize+16(FP), AX
-	MOVQ	AX, 16(SP)
-	MOVQ	$runtime·cgocallback_gofunc(SB), AX
-	CALL	AX
-	RET
-
-// cgocallback_gofunc(FuncVal*, void *frame, uintptr framesize)
-// See cgocall.c for more details.
-TEXT runtime·cgocallback_gofunc(SB),NOSPLIT,$8-24
-	// If m is nil, Go did not create the current thread.
-	// Call needm to obtain one for temporary use.
-	// In this case, we're running on the thread stack, so there's
-	// lots of space, but the linker doesn't know. Hide the call from
-	// the linker analysis by using an indirect call through AX.
-	get_tls(CX)
-#ifdef GOOS_windows
-	MOVL	$0, BP
-	CMPQ	CX, $0
-	JEQ	2(PC)
-#endif
-	MOVQ	m(CX), BP
-	MOVQ	BP, R8 // holds oldm until end of function
-	CMPQ	BP, $0
-	JNE	havem
-needm:
-	MOVQ	R8, 0(SP)
-	MOVQ	$runtime·needm(SB), AX
-	CALL	AX
-	MOVQ	0(SP), R8
-	get_tls(CX)
-	MOVQ	m(CX), BP
-
-havem:
-	// Now there's a valid m, and we're running on its m->g0.
-	// Save current m->g0->sched.sp on stack and then set it to SP.
-	// Save current sp in m->g0->sched.sp in preparation for
-	// switch back to m->curg stack.
-	// NOTE: unwindm knows that the saved g->sched.sp is at 0(SP).
-	MOVQ	m_g0(BP), SI
-	MOVQ	(g_sched+gobuf_sp)(SI), AX
-	MOVQ	AX, 0(SP)
-	MOVQ	SP, (g_sched+gobuf_sp)(SI)
-
-	// Switch to m->curg stack and call runtime.cgocallbackg.
-	// Because we are taking over the execution of m->curg
-	// but *not* resuming what had been running, we need to
-	// save that information (m->curg->sched) so we can restore it.
-	// We can restore m->curg->sched.sp easily, because calling
-	// runtime.cgocallbackg leaves SP unchanged upon return.
-	// To save m->curg->sched.pc, we push it onto the stack.
-	// This has the added benefit that it looks to the traceback
-	// routine like cgocallbackg is going to return to that
-	// PC (because the frame we allocate below has the same
-	// size as cgocallback_gofunc's frame declared above)
-	// so that the traceback will seamlessly trace back into
-	// the earlier calls.
-	//
-	// In the new goroutine, 0(SP) holds the saved R8.
-	MOVQ	m_curg(BP), SI
-	MOVQ	SI, g(CX)
-	MOVQ	(g_sched+gobuf_sp)(SI), DI  // prepare stack as DI
-	MOVQ	(g_sched+gobuf_pc)(SI), BP
-	MOVQ	BP, -8(DI)
-	LEAQ	-(8+8)(DI), SP
-	MOVQ	R8, 0(SP)
-	MOVQ	$runtime·cgocallbackg(SB), AX // hide function call from linker
-	CALL	AX
-	MOVQ	0(SP), R8
-
-	// Restore g->sched (== m->curg->sched) from saved values.
-	get_tls(CX)
-	MOVQ	g(CX), SI
-	MOVQ	8(SP), BP
-	MOVQ	BP, (g_sched+gobuf_pc)(SI)
-	LEAQ	(8+8)(SP), DI
-	MOVQ	DI, (g_sched+gobuf_sp)(SI)
-
-	// Switch back to m->g0's stack and restore m->g0->sched.sp.
-	// (Unlike m->curg, the g0 goroutine never uses sched.pc,
-	// so we do not have to restore it.)
-	MOVQ	m(CX), BP
-	MOVQ	m_g0(BP), SI
-	MOVQ	SI, g(CX)
-	MOVQ	(g_sched+gobuf_sp)(SI), SP
-	MOVQ	0(SP), AX
-	MOVQ	AX, (g_sched+gobuf_sp)(SI)
-	
-	// If the m on entry was nil, we called needm above to borrow an m
-	// for the duration of the call. Since the call is over, return it with dropm.
-	CMPQ	R8, $0
-	JNE 3(PC)
-	MOVQ	$runtime·dropm(SB), AX
-	CALL	AX
-
-	// Done!
-	RET
-
-// void setmg(M*, G*); set m and g. for use by needm.
-TEXT runtime·setmg(SB), NOSPLIT, $0-16
-	MOVQ	mm+0(FP), AX
-#ifdef GOOS_windows
-	CMPQ	AX, $0
-	JNE	settls
-	MOVQ	$0, 0x28(GS)
-	RET
-settls:
-	LEAQ	m_tls(AX), AX
-	MOVQ	AX, 0x28(GS)
-#endif
-	get_tls(CX)
-	MOVQ	mm+0(FP), AX
-	MOVQ	AX, m(CX)
-	MOVQ	gg+8(FP), BX
-	MOVQ	BX, g(CX)
-	RET
-
-// void setmg_gcc(M*, G*); set m and g called from gcc.
-TEXT setmg_gcc<>(SB),NOSPLIT,$0
-	get_tls(AX)
-	MOVQ	DI, m(AX)
-	MOVQ	SI, g(AX)
-	RET
-
-// check that SP is in range [g->stackbase, g->stackguard)
-TEXT runtime·stackcheck(SB), NOSPLIT, $0-0
-	get_tls(CX)
-	MOVQ	g(CX), AX
-	CMPQ	g_stackbase(AX), SP
-	JHI	2(PC)
-	INT	$3
-	CMPQ	SP, g_stackguard(AX)
-	JHI	2(PC)
-	INT	$3
-	RET
-
-TEXT runtime·getcallerpc(SB),NOSPLIT,$0-8
-	MOVQ	x+0(FP),AX		// addr of first arg
-	MOVQ	-8(AX),AX		// get calling pc
-	RET
-
-TEXT runtime·setcallerpc(SB),NOSPLIT,$0-16
-	MOVQ	x+0(FP),AX		// addr of first arg
-	MOVQ	x+8(FP), BX
-	MOVQ	BX, -8(AX)		// set calling pc
-	RET
-
-TEXT runtime·getcallersp(SB),NOSPLIT,$0-8
-	MOVQ	sp+0(FP), AX
-	RET
-
-// int64 runtime·cputicks(void)
-TEXT runtime·cputicks(SB),NOSPLIT,$0-0
-	RDTSC
-	SHLQ	$32, DX
-	ADDQ	DX, AX
-	RET
-
-TEXT runtime·stackguard(SB),NOSPLIT,$0-16
-	MOVQ	SP, DX
-	MOVQ	DX, sp+0(FP)
-	get_tls(CX)
-	MOVQ	g(CX), BX
-	MOVQ	g_stackguard(BX), DX
-	MOVQ	DX, limit+8(FP)
-	RET
-
-GLOBL runtime·tls0(SB), $64
-
-// hash function using AES hardware instructions
-TEXT runtime·aeshash(SB),NOSPLIT,$0-24
-	MOVQ	8(SP), DX	// ptr to hash value
-	MOVQ	16(SP), CX	// size
-	MOVQ	24(SP), AX	// ptr to data
-	JMP	runtime·aeshashbody(SB)
-
-TEXT runtime·aeshashstr(SB),NOSPLIT,$0-24
-	MOVQ	8(SP), DX	// ptr to hash value
-	MOVQ	24(SP), AX	// ptr to string struct
-	MOVQ	8(AX), CX	// length of string
-	MOVQ	(AX), AX	// string data
-	JMP	runtime·aeshashbody(SB)
-
-// AX: data
-// CX: length
-// DX: ptr to seed input / hash output
-TEXT runtime·aeshashbody(SB),NOSPLIT,$0-24
-	MOVQ	(DX), X0	// seed to low 64 bits of xmm0
-	PINSRQ	$1, CX, X0	// size to high 64 bits of xmm0
-	MOVO	runtime·aeskeysched+0(SB), X2
-	MOVO	runtime·aeskeysched+16(SB), X3
-	CMPQ	CX, $16
-	JB	aessmall
-aesloop:
-	CMPQ	CX, $16
-	JBE	aesloopend
-	MOVOU	(AX), X1
-	AESENC	X2, X0
-	AESENC	X1, X0
-	SUBQ	$16, CX
-	ADDQ	$16, AX
-	JMP	aesloop
-// 1-16 bytes remaining
-aesloopend:
-	// This load may overlap with the previous load above.
-	// We'll hash some bytes twice, but that's ok.
-	MOVOU	-16(AX)(CX*1), X1
-	JMP	partial
-// 0-15 bytes
-aessmall:
-	TESTQ	CX, CX
-	JE	finalize	// 0 bytes
-
-	CMPB	AX, $0xf0
-	JA	highpartial
-
-	// 16 bytes loaded at this address won't cross
-	// a page boundary, so we can load it directly.
-	MOVOU	(AX), X1
-	ADDQ	CX, CX
-	PAND	masks<>(SB)(CX*8), X1
-	JMP	partial
-highpartial:
-	// address ends in 1111xxxx.  Might be up against
-	// a page boundary, so load ending at last byte.
-	// Then shift bytes down using pshufb.
-	MOVOU	-16(AX)(CX*1), X1
-	ADDQ	CX, CX
-	PSHUFB	shifts<>(SB)(CX*8), X1
-partial:
-	// incorporate partial block into hash
-	AESENC	X3, X0
-	AESENC	X1, X0
-finalize:	
-	// finalize hash
-	AESENC	X2, X0
-	AESENC	X3, X0
-	AESENC	X2, X0
-	MOVQ	X0, (DX)
-	RET
-
-TEXT runtime·aeshash32(SB),NOSPLIT,$0-24
-	MOVQ	8(SP), DX	// ptr to hash value
-	MOVQ	24(SP), AX	// ptr to data
-	MOVQ	(DX), X0	// seed
-	PINSRD	$2, (AX), X0	// data
-	AESENC	runtime·aeskeysched+0(SB), X0
-	AESENC	runtime·aeskeysched+16(SB), X0
-	AESENC	runtime·aeskeysched+0(SB), X0
-	MOVQ	X0, (DX)
-	RET
-
-TEXT runtime·aeshash64(SB),NOSPLIT,$0-24
-	MOVQ	8(SP), DX	// ptr to hash value
-	MOVQ	24(SP), AX	// ptr to data
-	MOVQ	(DX), X0	// seed
-	PINSRQ	$1, (AX), X0	// data
-	AESENC	runtime·aeskeysched+0(SB), X0
-	AESENC	runtime·aeskeysched+16(SB), X0
-	AESENC	runtime·aeskeysched+0(SB), X0
-	MOVQ	X0, (DX)
-	RET
-
-// simple mask to get rid of data in the high part of the register.
-DATA masks<>+0x00(SB)/8, $0x0000000000000000
-DATA masks<>+0x08(SB)/8, $0x0000000000000000
-DATA masks<>+0x10(SB)/8, $0x00000000000000ff
-DATA masks<>+0x18(SB)/8, $0x0000000000000000
-DATA masks<>+0x20(SB)/8, $0x000000000000ffff
-DATA masks<>+0x28(SB)/8, $0x0000000000000000
-DATA masks<>+0x30(SB)/8, $0x0000000000ffffff
-DATA masks<>+0x38(SB)/8, $0x0000000000000000
-DATA masks<>+0x40(SB)/8, $0x00000000ffffffff
-DATA masks<>+0x48(SB)/8, $0x0000000000000000
-DATA masks<>+0x50(SB)/8, $0x000000ffffffffff
-DATA masks<>+0x58(SB)/8, $0x0000000000000000
-DATA masks<>+0x60(SB)/8, $0x0000ffffffffffff
-DATA masks<>+0x68(SB)/8, $0x0000000000000000
-DATA masks<>+0x70(SB)/8, $0x00ffffffffffffff
-DATA masks<>+0x78(SB)/8, $0x0000000000000000
-DATA masks<>+0x80(SB)/8, $0xffffffffffffffff
-DATA masks<>+0x88(SB)/8, $0x0000000000000000
-DATA masks<>+0x90(SB)/8, $0xffffffffffffffff
-DATA masks<>+0x98(SB)/8, $0x00000000000000ff
-DATA masks<>+0xa0(SB)/8, $0xffffffffffffffff
-DATA masks<>+0xa8(SB)/8, $0x000000000000ffff
-DATA masks<>+0xb0(SB)/8, $0xffffffffffffffff
-DATA masks<>+0xb8(SB)/8, $0x0000000000ffffff
-DATA masks<>+0xc0(SB)/8, $0xffffffffffffffff
-DATA masks<>+0xc8(SB)/8, $0x00000000ffffffff
-DATA masks<>+0xd0(SB)/8, $0xffffffffffffffff
-DATA masks<>+0xd8(SB)/8, $0x000000ffffffffff
-DATA masks<>+0xe0(SB)/8, $0xffffffffffffffff
-DATA masks<>+0xe8(SB)/8, $0x0000ffffffffffff
-DATA masks<>+0xf0(SB)/8, $0xffffffffffffffff
-DATA masks<>+0xf8(SB)/8, $0x00ffffffffffffff
-GLOBL masks<>(SB),RODATA,$256
-
-// these are arguments to pshufb.  They move data down from
-// the high bytes of the register to the low bytes of the register.
-// index is how many bytes to move.
-DATA shifts<>+0x00(SB)/8, $0x0000000000000000
-DATA shifts<>+0x08(SB)/8, $0x0000000000000000
-DATA shifts<>+0x10(SB)/8, $0xffffffffffffff0f
-DATA shifts<>+0x18(SB)/8, $0xffffffffffffffff
-DATA shifts<>+0x20(SB)/8, $0xffffffffffff0f0e
-DATA shifts<>+0x28(SB)/8, $0xffffffffffffffff
-DATA shifts<>+0x30(SB)/8, $0xffffffffff0f0e0d
-DATA shifts<>+0x38(SB)/8, $0xffffffffffffffff
-DATA shifts<>+0x40(SB)/8, $0xffffffff0f0e0d0c
-DATA shifts<>+0x48(SB)/8, $0xffffffffffffffff
-DATA shifts<>+0x50(SB)/8, $0xffffff0f0e0d0c0b
-DATA shifts<>+0x58(SB)/8, $0xffffffffffffffff
-DATA shifts<>+0x60(SB)/8, $0xffff0f0e0d0c0b0a
-DATA shifts<>+0x68(SB)/8, $0xffffffffffffffff
-DATA shifts<>+0x70(SB)/8, $0xff0f0e0d0c0b0a09
-DATA shifts<>+0x78(SB)/8, $0xffffffffffffffff
-DATA shifts<>+0x80(SB)/8, $0x0f0e0d0c0b0a0908
-DATA shifts<>+0x88(SB)/8, $0xffffffffffffffff
-DATA shifts<>+0x90(SB)/8, $0x0e0d0c0b0a090807
-DATA shifts<>+0x98(SB)/8, $0xffffffffffffff0f
-DATA shifts<>+0xa0(SB)/8, $0x0d0c0b0a09080706
-DATA shifts<>+0xa8(SB)/8, $0xffffffffffff0f0e
-DATA shifts<>+0xb0(SB)/8, $0x0c0b0a0908070605
-DATA shifts<>+0xb8(SB)/8, $0xffffffffff0f0e0d
-DATA shifts<>+0xc0(SB)/8, $0x0b0a090807060504
-DATA shifts<>+0xc8(SB)/8, $0xffffffff0f0e0d0c
-DATA shifts<>+0xd0(SB)/8, $0x0a09080706050403
-DATA shifts<>+0xd8(SB)/8, $0xffffff0f0e0d0c0b
-DATA shifts<>+0xe0(SB)/8, $0x0908070605040302
-DATA shifts<>+0xe8(SB)/8, $0xffff0f0e0d0c0b0a
-DATA shifts<>+0xf0(SB)/8, $0x0807060504030201
-DATA shifts<>+0xf8(SB)/8, $0xff0f0e0d0c0b0a09
-GLOBL shifts<>(SB),RODATA,$256
-
-TEXT runtime·memeq(SB),NOSPLIT,$0-24
-	MOVQ	a+0(FP), SI
-	MOVQ	b+8(FP), DI
-	MOVQ	count+16(FP), BX
-	JMP	runtime·memeqbody(SB)
-
-// a in SI
-// b in DI
-// count in BX
-TEXT runtime·memeqbody(SB),NOSPLIT,$0-0
-	XORQ	AX, AX
-
-	CMPQ	BX, $8
-	JB	small
-	
-	// 64 bytes at a time using xmm registers
-hugeloop:
-	CMPQ	BX, $64
-	JB	bigloop
-	MOVOU	(SI), X0
-	MOVOU	(DI), X1
-	MOVOU	16(SI), X2
-	MOVOU	16(DI), X3
-	MOVOU	32(SI), X4
-	MOVOU	32(DI), X5
-	MOVOU	48(SI), X6
-	MOVOU	48(DI), X7
-	PCMPEQB	X1, X0
-	PCMPEQB	X3, X2
-	PCMPEQB	X5, X4
-	PCMPEQB	X7, X6
-	PAND	X2, X0
-	PAND	X6, X4
-	PAND	X4, X0
-	PMOVMSKB X0, DX
-	ADDQ	$64, SI
-	ADDQ	$64, DI
-	SUBQ	$64, BX
-	CMPL	DX, $0xffff
-	JEQ	hugeloop
-	RET
-
-	// 8 bytes at a time using 64-bit register
-bigloop:
-	CMPQ	BX, $8
-	JBE	leftover
-	MOVQ	(SI), CX
-	MOVQ	(DI), DX
-	ADDQ	$8, SI
-	ADDQ	$8, DI
-	SUBQ	$8, BX
-	CMPQ	CX, DX
-	JEQ	bigloop
-	RET
-
-	// remaining 0-8 bytes
-leftover:
-	MOVQ	-8(SI)(BX*1), CX
-	MOVQ	-8(DI)(BX*1), DX
-	CMPQ	CX, DX
-	SETEQ	AX
-	RET
-
-small:
-	CMPQ	BX, $0
-	JEQ	equal
-
-	LEAQ	0(BX*8), CX
-	NEGQ	CX
-
-	CMPB	SI, $0xf8
-	JA	si_high
-
-	// load at SI won't cross a page boundary.
-	MOVQ	(SI), SI
-	JMP	si_finish
-si_high:
-	// address ends in 11111xxx.  Load up to bytes we want, move to correct position.
-	MOVQ	-8(SI)(BX*1), SI
-	SHRQ	CX, SI
-si_finish:
-
-	// same for DI.
-	CMPB	DI, $0xf8
-	JA	di_high
-	MOVQ	(DI), DI
-	JMP	di_finish
-di_high:
-	MOVQ	-8(DI)(BX*1), DI
-	SHRQ	CX, DI
-di_finish:
-
-	SUBQ	SI, DI
-	SHLQ	CX, DI
-equal:
-	SETEQ	AX
-	RET
-
-TEXT runtime·cmpstring(SB),NOSPLIT,$0-40
-	MOVQ	s1+0(FP), SI
-	MOVQ	s1+8(FP), BX
-	MOVQ	s2+16(FP), DI
-	MOVQ	s2+24(FP), DX
-	CALL	runtime·cmpbody(SB)
-	MOVQ	AX, res+32(FP)
-	RET
-
-TEXT bytes·Compare(SB),NOSPLIT,$0-56
-	MOVQ	s1+0(FP), SI
-	MOVQ	s1+8(FP), BX
-	MOVQ	s2+24(FP), DI
-	MOVQ	s2+32(FP), DX
-	CALL	runtime·cmpbody(SB)
-	MOVQ	AX, res+48(FP)
-	RET
-
-// input:
-//   SI = a
-//   DI = b
-//   BX = alen
-//   DX = blen
-// output:
-//   AX = 1/0/-1
-TEXT runtime·cmpbody(SB),NOSPLIT,$0-0
-	CMPQ	SI, DI
-	JEQ	cmp_allsame
-	CMPQ	BX, DX
-	MOVQ	DX, BP
-	CMOVQLT	BX, BP // BP = min(alen, blen) = # of bytes to compare
-	CMPQ	BP, $8
-	JB	cmp_small
-
-cmp_loop:
-	CMPQ	BP, $16
-	JBE	cmp_0through16
-	MOVOU	(SI), X0
-	MOVOU	(DI), X1
-	PCMPEQB X0, X1
-	PMOVMSKB X1, AX
-	XORQ	$0xffff, AX	// convert EQ to NE
-	JNE	cmp_diff16	// branch if at least one byte is not equal
-	ADDQ	$16, SI
-	ADDQ	$16, DI
-	SUBQ	$16, BP
-	JMP	cmp_loop
-	
-	// AX = bit mask of differences
-cmp_diff16:
-	BSFQ	AX, BX	// index of first byte that differs
-	XORQ	AX, AX
-	MOVB	(SI)(BX*1), CX
-	CMPB	CX, (DI)(BX*1)
-	SETHI	AX
-	LEAQ	-1(AX*2), AX	// convert 1/0 to +1/-1
-	RET
-
-	// 0 through 16 bytes left, alen>=8, blen>=8
-cmp_0through16:
-	CMPQ	BP, $8
-	JBE	cmp_0through8
-	MOVQ	(SI), AX
-	MOVQ	(DI), CX
-	CMPQ	AX, CX
-	JNE	cmp_diff8
-cmp_0through8:
-	MOVQ	-8(SI)(BP*1), AX
-	MOVQ	-8(DI)(BP*1), CX
-	CMPQ	AX, CX
-	JEQ	cmp_allsame
-
-	// AX and CX contain parts of a and b that differ.
-cmp_diff8:
-	BSWAPQ	AX	// reverse order of bytes
-	BSWAPQ	CX
-	XORQ	AX, CX
-	BSRQ	CX, CX	// index of highest bit difference
-	SHRQ	CX, AX	// move a's bit to bottom
-	ANDQ	$1, AX	// mask bit
-	LEAQ	-1(AX*2), AX // 1/0 => +1/-1
-	RET
-
-	// 0-7 bytes in common
-cmp_small:
-	LEAQ	(BP*8), CX	// bytes left -> bits left
-	NEGQ	CX		//  - bits lift (== 64 - bits left mod 64)
-	JEQ	cmp_allsame
-
-	// load bytes of a into high bytes of AX
-	CMPB	SI, $0xf8
-	JA	cmp_si_high
-	MOVQ	(SI), SI
-	JMP	cmp_si_finish
-cmp_si_high:
-	MOVQ	-8(SI)(BP*1), SI
-	SHRQ	CX, SI
-cmp_si_finish:
-	SHLQ	CX, SI
-
-	// load bytes of b in to high bytes of BX
-	CMPB	DI, $0xf8
-	JA	cmp_di_high
-	MOVQ	(DI), DI
-	JMP	cmp_di_finish
-cmp_di_high:
-	MOVQ	-8(DI)(BP*1), DI
-	SHRQ	CX, DI
-cmp_di_finish:
-	SHLQ	CX, DI
-
-	BSWAPQ	SI	// reverse order of bytes
-	BSWAPQ	DI
-	XORQ	SI, DI	// find bit differences
-	JEQ	cmp_allsame
-	BSRQ	DI, CX	// index of highest bit difference
-	SHRQ	CX, SI	// move a's bit to bottom
-	ANDQ	$1, SI	// mask bit
-	LEAQ	-1(SI*2), AX // 1/0 => +1/-1
-	RET
-
-cmp_allsame:
-	XORQ	AX, AX
-	XORQ	CX, CX
-	CMPQ	BX, DX
-	SETGT	AX	// 1 if alen > blen
-	SETEQ	CX	// 1 if alen == blen
-	LEAQ	-1(CX)(AX*2), AX	// 1,0,-1 result
-	RET
-
-TEXT bytes·IndexByte(SB),NOSPLIT,$0
-	MOVQ s+0(FP), SI
-	MOVQ s_len+8(FP), BX
-	MOVB c+24(FP), AL
-	CALL runtime·indexbytebody(SB)
-	MOVQ AX, ret+32(FP)
-	RET
-
-TEXT strings·IndexByte(SB),NOSPLIT,$0
-	MOVQ s+0(FP), SI
-	MOVQ s_len+8(FP), BX
-	MOVB c+16(FP), AL
-	CALL runtime·indexbytebody(SB)
-	MOVQ AX, ret+24(FP)
-	RET
-
-// input:
-//   SI: data
-//   BX: data len
-//   AL: byte sought
-// output:
-//   AX
-TEXT runtime·indexbytebody(SB),NOSPLIT,$0
-	MOVQ SI, DI
-
-	CMPQ BX, $16
-	JLT indexbyte_small
-
-	// round up to first 16-byte boundary
-	TESTQ $15, SI
-	JZ aligned
-	MOVQ SI, CX
-	ANDQ $~15, CX
-	ADDQ $16, CX
-
-	// search the beginning
-	SUBQ SI, CX
-	REPN; SCASB
-	JZ success
-
-// DI is 16-byte aligned; get ready to search using SSE instructions
-aligned:
-	// round down to last 16-byte boundary
-	MOVQ BX, R11
-	ADDQ SI, R11
-	ANDQ $~15, R11
-
-	// shuffle X0 around so that each byte contains c
-	MOVD AX, X0
-	PUNPCKLBW X0, X0
-	PUNPCKLBW X0, X0
-	PSHUFL $0, X0, X0
-	JMP condition
-
-sse:
-	// move the next 16-byte chunk of the buffer into X1
-	MOVO (DI), X1
-	// compare bytes in X0 to X1
-	PCMPEQB X0, X1
-	// take the top bit of each byte in X1 and put the result in DX
-	PMOVMSKB X1, DX
-	TESTL DX, DX
-	JNZ ssesuccess
-	ADDQ $16, DI
-
-condition:
-	CMPQ DI, R11
-	JLT sse
-
-	// search the end
-	MOVQ SI, CX
-	ADDQ BX, CX
-	SUBQ R11, CX
-	// if CX == 0, the zero flag will be set and we'll end up
-	// returning a false success
-	JZ failure
-	REPN; SCASB
-	JZ success
-
-failure:
-	MOVQ $-1, AX
-	RET
-
-// handle for lengths < 16
-indexbyte_small:
-	MOVQ BX, CX
-	REPN; SCASB
-	JZ success
-	MOVQ $-1, AX
-	RET
-
-// we've found the chunk containing the byte
-// now just figure out which specific byte it is
-ssesuccess:
-	// get the index of the least significant set bit
-	BSFW DX, DX
-	SUBQ SI, DI
-	ADDQ DI, DX
-	MOVQ DX, AX
-	RET
-
-success:
-	SUBQ SI, DI
-	SUBL $1, DI
-	MOVQ DI, AX
-	RET
-
-TEXT bytes·Equal(SB),NOSPLIT,$0-49
-	MOVQ	a_len+8(FP), BX
-	MOVQ	b_len+32(FP), CX
-	XORQ	AX, AX
-	CMPQ	BX, CX
-	JNE	eqret
-	MOVQ	a+0(FP), SI
-	MOVQ	b+24(FP), DI
-	CALL	runtime·memeqbody(SB)
-eqret:
-	MOVB	AX, ret+48(FP)
-	RET
-
-// A Duff's device for zeroing memory.
-// The compiler jumps to computed addresses within
-// this routine to zero chunks of memory.  Do not
-// change this code without also changing the code
-// in ../../cmd/6g/ggen.c:clearfat.
-// AX: zero
-// DI: ptr to memory to be zeroed
-// DI is updated as a side effect.
-TEXT runtime·duffzero(SB), NOSPLIT, $0-0
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	STOSQ
-	RET
-
-// A Duff's device for copying memory.
-// The compiler jumps to computed addresses within
-// this routine to copy chunks of memory.  Source
-// and destination must not overlap.  Do not
-// change this code without also changing the code
-// in ../../cmd/6g/cgen.c:sgen.
-// SI: ptr to source memory
-// DI: ptr to destination memory
-// SI and DI are updated as a side effect.
-
-// NOTE: this is equivalent to a sequence of MOVSQ but
-// for some reason that is 3.5x slower than this code.
-// The STOSQ above seem fine, though.
-TEXT runtime·duffcopy(SB), NOSPLIT, $0-0
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	MOVQ	(SI),CX
-	ADDQ	$8,SI
-	MOVQ	CX,(DI)
-	ADDQ	$8,DI
-
-	RET
-
-TEXT runtime·timenow(SB), NOSPLIT, $0-0
-	JMP	time·now(SB)
diff --git a/src/pkg/runtime/asm_amd64p32.s b/src/pkg/runtime/asm_amd64p32.s
deleted file mode 100644
index d47f122..0000000
--- a/src/pkg/runtime/asm_amd64p32.s
+++ /dev/null
@@ -1,1073 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "zasm_GOOS_GOARCH.h"
-#include "funcdata.h"
-#include "../../cmd/ld/textflag.h"
-
-TEXT _rt0_go(SB),NOSPLIT,$0
-	// copy arguments forward on an even stack
-	MOVL	argc+0(FP), AX
-	MOVL	argv+4(FP), BX
-	MOVL	SP, CX
-	SUBL	$128, SP		// plenty of scratch
-	ANDL	$~15, CX
-	MOVL	CX, SP
-
-	MOVL	AX, 16(SP)
-	MOVL	BX, 24(SP)
-	
-	// create istack out of the given (operating system) stack.
-	MOVL	$runtime·g0(SB), DI
-	LEAL	(-64*1024+104)(SP), DI
-	MOVL	BX, g_stackguard(DI)
-	MOVL	BX, g_stackguard0(DI)
-	MOVL	SP, g_stackbase(DI)
-
-	// find out information about the processor we're on
-	MOVQ	$0, AX
-	CPUID
-	CMPQ	AX, $0
-	JE	nocpuinfo
-	MOVQ	$1, AX
-	CPUID
-	MOVL	CX, runtime·cpuid_ecx(SB)
-	MOVL	DX, runtime·cpuid_edx(SB)
-nocpuinfo:	
-	
-needtls:
-	LEAL	runtime·tls0(SB), DI
-	CALL	runtime·settls(SB)
-
-	// store through it, to make sure it works
-	get_tls(BX)
-	MOVQ	$0x123, g(BX)
-	MOVQ	runtime·tls0(SB), AX
-	CMPQ	AX, $0x123
-	JEQ 2(PC)
-	MOVL	AX, 0	// abort
-ok:
-	// set the per-goroutine and per-mach "registers"
-	get_tls(BX)
-	LEAL	runtime·g0(SB), CX
-	MOVL	CX, g(BX)
-	LEAL	runtime·m0(SB), AX
-	MOVL	AX, m(BX)
-
-	// save m->g0 = g0
-	MOVL	CX, m_g0(AX)
-
-	CLD				// convention is D is always left cleared
-	CALL	runtime·check(SB)
-
-	MOVL	16(SP), AX		// copy argc
-	MOVL	AX, 0(SP)
-	MOVL	24(SP), AX		// copy argv
-	MOVL	AX, 4(SP)
-	CALL	runtime·args(SB)
-	CALL	runtime·osinit(SB)
-	CALL	runtime·hashinit(SB)
-	CALL	runtime·schedinit(SB)
-
-	// create a new goroutine to start program
-	MOVL	$runtime·main·f(SB), AX	// entry
-	MOVL	$0, 0(SP)
-	MOVL	AX, 4(SP)
-	ARGSIZE(8)
-	CALL	runtime·newproc(SB)
-	ARGSIZE(-1)
-
-	// start this M
-	CALL	runtime·mstart(SB)
-
-	MOVL	$0xf1, 0xf1  // crash
-	RET
-
-DATA	runtime·main·f+0(SB)/4,$runtime·main(SB)
-GLOBL	runtime·main·f(SB),RODATA,$4
-
-TEXT runtime·breakpoint(SB),NOSPLIT,$0-0
-	INT $3
-	RET
-
-TEXT runtime·asminit(SB),NOSPLIT,$0-0
-	// No per-thread init.
-	RET
-
-/*
- *  go-routine
- */
-
-// void gosave(Gobuf*)
-// save state in Gobuf; setjmp
-TEXT runtime·gosave(SB), NOSPLIT, $0-4
-	MOVL	b+0(FP), AX	// gobuf
-	LEAL	b+0(FP), BX	// caller's SP
-	MOVL	BX, gobuf_sp(AX)
-	MOVL	0(SP), BX		// caller's PC
-	MOVL	BX, gobuf_pc(AX)
-	MOVL	$0, gobuf_ctxt(AX)
-	MOVQ	$0, gobuf_ret(AX)
-	get_tls(CX)
-	MOVL	g(CX), BX
-	MOVL	BX, gobuf_g(AX)
-	RET
-
-// void gogo(Gobuf*)
-// restore state from Gobuf; longjmp
-TEXT runtime·gogo(SB), NOSPLIT, $0-4
-	MOVL	b+0(FP), BX		// gobuf
-	MOVL	gobuf_g(BX), DX
-	MOVL	0(DX), CX		// make sure g != nil
-	get_tls(CX)
-	MOVL	DX, g(CX)
-	MOVL	gobuf_sp(BX), SP	// restore SP
-	MOVL	gobuf_ctxt(BX), DX
-	MOVQ	gobuf_ret(BX), AX
-	MOVL	$0, gobuf_sp(BX)	// clear to help garbage collector
-	MOVQ	$0, gobuf_ret(BX)
-	MOVL	$0, gobuf_ctxt(BX)
-	MOVL	gobuf_pc(BX), BX
-	JMP	BX
-
-// void mcall(void (*fn)(G*))
-// Switch to m->g0's stack, call fn(g).
-// Fn must never return.  It should gogo(&g->sched)
-// to keep running g.
-TEXT runtime·mcall(SB), NOSPLIT, $0-4
-	MOVL	fn+0(FP), DI
-	
-	get_tls(CX)
-	MOVL	g(CX), AX	// save state in g->sched
-	MOVL	0(SP), BX	// caller's PC
-	MOVL	BX, (g_sched+gobuf_pc)(AX)
-	LEAL	fn+0(FP), BX	// caller's SP
-	MOVL	BX, (g_sched+gobuf_sp)(AX)
-	MOVL	AX, (g_sched+gobuf_g)(AX)
-
-	// switch to m->g0 & its stack, call fn
-	MOVL	m(CX), BX
-	MOVL	m_g0(BX), SI
-	CMPL	SI, AX	// if g == m->g0 call badmcall
-	JNE	3(PC)
-	MOVL	$runtime·badmcall(SB), AX
-	JMP	AX
-	MOVL	SI, g(CX)	// g = m->g0
-	MOVL	(g_sched+gobuf_sp)(SI), SP	// sp = m->g0->sched.sp
-	PUSHQ	AX
-	ARGSIZE(8)
-	CALL	DI
-	POPQ	AX
-	MOVL	$runtime·badmcall2(SB), AX
-	JMP	AX
-	RET
-
-/*
- * support for morestack
- */
-
-// Called during function prolog when more stack is needed.
-// Caller has already done get_tls(CX); MOVQ m(CX), BX.
-//
-// The traceback routines see morestack on a g0 as being
-// the top of a stack (for example, morestack calling newstack
-// calling the scheduler calling newm calling gc), so we must
-// record an argument size. For that purpose, it has no arguments.
-TEXT runtime·morestack(SB),NOSPLIT,$0-0
-	// Cannot grow scheduler stack (m->g0).
-	MOVL	m_g0(BX), SI
-	CMPL	g(CX), SI
-	JNE	2(PC)
-	MOVL	0, AX
-
-	// Called from f.
-	// Set m->morebuf to f's caller.
-	MOVL	8(SP), AX	// f's caller's PC
-	MOVL	AX, (m_morebuf+gobuf_pc)(BX)
-	LEAL	16(SP), AX	// f's caller's SP
-	MOVL	AX, (m_morebuf+gobuf_sp)(BX)
-	MOVL	AX, m_moreargp(BX)
-	get_tls(CX)
-	MOVL	g(CX), SI
-	MOVL	SI, (m_morebuf+gobuf_g)(BX)
-
-	// Set g->sched to context in f.
-	MOVL	0(SP), AX // f's PC
-	MOVL	AX, (g_sched+gobuf_pc)(SI)
-	MOVL	SI, (g_sched+gobuf_g)(SI)
-	LEAL	8(SP), AX // f's SP
-	MOVL	AX, (g_sched+gobuf_sp)(SI)
-	MOVL	DX, (g_sched+gobuf_ctxt)(SI)
-
-	// Call newstack on m->g0's stack.
-	MOVL	m_g0(BX), BX
-	MOVL	BX, g(CX)
-	MOVL	(g_sched+gobuf_sp)(BX), SP
-	CALL	runtime·newstack(SB)
-	MOVL	$0, 0x1003	// crash if newstack returns
-	RET
-
-// Called from panic.  Mimics morestack,
-// reuses stack growth code to create a frame
-// with the desired args running the desired function.
-//
-// func call(fn *byte, arg *byte, argsize uint32).
-TEXT runtime·newstackcall(SB), NOSPLIT, $0-20
-	get_tls(CX)
-	MOVL	m(CX), BX
-
-	// Save our caller's state as the PC and SP to
-	// restore when returning from f.
-	MOVL	0(SP), AX	// our caller's PC
-	MOVL	AX, (m_morebuf+gobuf_pc)(BX)
-	LEAL	8(SP), AX	// our caller's SP
-	MOVL	AX, (m_morebuf+gobuf_sp)(BX)
-	MOVL	g(CX), AX
-	MOVL	AX, (m_morebuf+gobuf_g)(BX)
-	
-	// Save our own state as the PC and SP to restore
-	// if this goroutine needs to be restarted.
-	MOVL	$runtime·newstackcall(SB), DI
-	MOVL	DI, (g_sched+gobuf_pc)(AX)
-	MOVL	SP, (g_sched+gobuf_sp)(AX)
-
-	// Set up morestack arguments to call f on a new stack.
-	// We set f's frame size to 1, as a hint to newstack
-	// that this is a call from runtime·newstackcall.
-	// If it turns out that f needs a larger frame than
-	// the default stack, f's usual stack growth prolog will
-	// allocate a new segment (and recopy the arguments).
-	MOVL	8(SP), AX	// fn
-	MOVL	12(SP), DX	// arg frame
-	MOVL	16(SP), CX	// arg size
-
-	MOVQ	AX, m_cret(BX)	// f's PC
-	MOVL	DX, m_moreargp(BX)	// argument frame pointer
-	MOVL	CX, m_moreargsize(BX)	// f's argument size
-	MOVL	$1, m_moreframesize(BX)	// f's frame size
-
-	// Call newstack on m->g0's stack.
-	MOVL	m_g0(BX), BX
-	get_tls(CX)
-	MOVL	BX, g(CX)
-	MOVL	(g_sched+gobuf_sp)(BX), SP
-	CALL	runtime·newstack(SB)
-	MOVL	$0, 0x1103	// crash if newstack returns
-	RET
-
-// reflect·call: call a function with the given argument list
-// func call(f *FuncVal, arg *byte, argsize uint32).
-// we don't have variable-sized frames, so we use a small number
-// of constant-sized-frame functions to encode a few bits of size in the pc.
-// Caution: ugly multiline assembly macros in your future!
-
-#define DISPATCH(NAME,MAXSIZE)		\
-	CMPL	CX, $MAXSIZE;		\
-	JA	3(PC);			\
-	MOVL	$runtime·NAME(SB), AX;	\
-	JMP	AX
-// Note: can't just "JMP runtime·NAME(SB)" - bad inlining results.
-
-TEXT reflect·call(SB), NOSPLIT, $0-20
-	MOVLQZX argsize+8(FP), CX
-	DISPATCH(call16, 16)
-	DISPATCH(call32, 32)
-	DISPATCH(call64, 64)
-	DISPATCH(call128, 128)
-	DISPATCH(call256, 256)
-	DISPATCH(call512, 512)
-	DISPATCH(call1024, 1024)
-	DISPATCH(call2048, 2048)
-	DISPATCH(call4096, 4096)
-	DISPATCH(call8192, 8192)
-	DISPATCH(call16384, 16384)
-	DISPATCH(call32768, 32768)
-	DISPATCH(call65536, 65536)
-	DISPATCH(call131072, 131072)
-	DISPATCH(call262144, 262144)
-	DISPATCH(call524288, 524288)
-	DISPATCH(call1048576, 1048576)
-	DISPATCH(call2097152, 2097152)
-	DISPATCH(call4194304, 4194304)
-	DISPATCH(call8388608, 8388608)
-	DISPATCH(call16777216, 16777216)
-	DISPATCH(call33554432, 33554432)
-	DISPATCH(call67108864, 67108864)
-	DISPATCH(call134217728, 134217728)
-	DISPATCH(call268435456, 268435456)
-	DISPATCH(call536870912, 536870912)
-	DISPATCH(call1073741824, 1073741824)
-	MOVL	$runtime·badreflectcall(SB), AX
-	JMP	AX
-
-#define CALLFN(NAME,MAXSIZE)			\
-TEXT runtime·NAME(SB), WRAPPER, $MAXSIZE-16;		\
-	/* copy arguments to stack */		\
-	MOVL	argptr+4(FP), SI;		\
-	MOVL	argsize+8(FP), CX;		\
-	MOVL	SP, DI;				\
-	REP;MOVSB;				\
-	/* call function */			\
-	MOVL	f+0(FP), DX;			\
-	MOVL	(DX), AX;				\
-	CALL	AX; \
-	/* copy return values back */		\
-	MOVL	argptr+4(FP), DI;		\
-	MOVL	argsize+8(FP), CX;		\
-	MOVL	retoffset+12(FP), BX;		\
-	MOVL	SP, SI;				\
-	ADDL	BX, DI;				\
-	ADDL	BX, SI;				\
-	SUBL	BX, CX;				\
-	REP;MOVSB;				\
-	RET
-
-CALLFN(call16, 16)
-CALLFN(call32, 32)
-CALLFN(call64, 64)
-CALLFN(call128, 128)
-CALLFN(call256, 256)
-CALLFN(call512, 512)
-CALLFN(call1024, 1024)
-CALLFN(call2048, 2048)
-CALLFN(call4096, 4096)
-CALLFN(call8192, 8192)
-CALLFN(call16384, 16384)
-CALLFN(call32768, 32768)
-CALLFN(call65536, 65536)
-CALLFN(call131072, 131072)
-CALLFN(call262144, 262144)
-CALLFN(call524288, 524288)
-CALLFN(call1048576, 1048576)
-CALLFN(call2097152, 2097152)
-CALLFN(call4194304, 4194304)
-CALLFN(call8388608, 8388608)
-CALLFN(call16777216, 16777216)
-CALLFN(call33554432, 33554432)
-CALLFN(call67108864, 67108864)
-CALLFN(call134217728, 134217728)
-CALLFN(call268435456, 268435456)
-CALLFN(call536870912, 536870912)
-CALLFN(call1073741824, 1073741824)
-
-// Return point when leaving stack.
-//
-// Lessstack can appear in stack traces for the same reason
-// as morestack; in that context, it has 0 arguments.
-TEXT runtime·lessstack(SB), NOSPLIT, $0-0
-	// Save return value in m->cret
-	get_tls(CX)
-	MOVL	m(CX), BX
-	MOVQ	AX, m_cret(BX)	// MOVQ, to save all 64 bits
-
-	// Call oldstack on m->g0's stack.
-	MOVL	m_g0(BX), BX
-	MOVL	BX, g(CX)
-	MOVL	(g_sched+gobuf_sp)(BX), SP
-	CALL	runtime·oldstack(SB)
-	MOVL	$0, 0x1004	// crash if oldstack returns
-	RET
-
-// morestack trampolines
-TEXT runtime·morestack00(SB),NOSPLIT,$0
-	get_tls(CX)
-	MOVL	m(CX), BX
-	MOVQ	$0, AX
-	MOVQ	AX, m_moreframesize(BX)
-	MOVL	$runtime·morestack(SB), AX
-	JMP	AX
-
-TEXT runtime·morestack01(SB),NOSPLIT,$0
-	get_tls(CX)
-	MOVL	m(CX), BX
-	SHLQ	$32, AX
-	MOVQ	AX, m_moreframesize(BX)
-	MOVL	$runtime·morestack(SB), AX
-	JMP	AX
-
-TEXT runtime·morestack10(SB),NOSPLIT,$0
-	get_tls(CX)
-	MOVL	m(CX), BX
-	MOVLQZX	AX, AX
-	MOVQ	AX, m_moreframesize(BX)
-	MOVL	$runtime·morestack(SB), AX
-	JMP	AX
-
-TEXT runtime·morestack11(SB),NOSPLIT,$0
-	get_tls(CX)
-	MOVL	m(CX), BX
-	MOVQ	AX, m_moreframesize(BX)
-	MOVL	$runtime·morestack(SB), AX
-	JMP	AX
-
-// subcases of morestack01
-// with const of 8,16,...48
-TEXT runtime·morestack8(SB),NOSPLIT,$0
-	MOVQ	$1, R8
-	MOVL	$morestack<>(SB), AX
-	JMP	AX
-
-TEXT runtime·morestack16(SB),NOSPLIT,$0
-	MOVQ	$2, R8
-	MOVL	$morestack<>(SB), AX
-	JMP	AX
-
-TEXT runtime·morestack24(SB),NOSPLIT,$0
-	MOVQ	$3, R8
-	MOVL	$morestack<>(SB), AX
-	JMP	AX
-
-TEXT runtime·morestack32(SB),NOSPLIT,$0
-	MOVQ	$4, R8
-	MOVL	$morestack<>(SB), AX
-	JMP	AX
-
-TEXT runtime·morestack40(SB),NOSPLIT,$0
-	MOVQ	$5, R8
-	MOVL	$morestack<>(SB), AX
-	JMP	AX
-
-TEXT runtime·morestack48(SB),NOSPLIT,$0
-	MOVQ	$6, R8
-	MOVL	$morestack<>(SB), AX
-	JMP	AX
-
-TEXT morestack<>(SB),NOSPLIT,$0
-	get_tls(CX)
-	MOVL	m(CX), BX
-	SHLQ	$35, R8
-	MOVQ	R8, m_moreframesize(BX)
-	MOVL	$runtime·morestack(SB), AX
-	JMP	AX
-
-TEXT runtime·morestack00_noctxt(SB),NOSPLIT,$0
-	MOVL	$0, DX
-	JMP	runtime·morestack00(SB)
-
-TEXT runtime·morestack01_noctxt(SB),NOSPLIT,$0
-	MOVL	$0, DX
-	JMP	runtime·morestack01(SB)
-
-TEXT runtime·morestack10_noctxt(SB),NOSPLIT,$0
-	MOVL	$0, DX
-	JMP	runtime·morestack10(SB)
-
-TEXT runtime·morestack11_noctxt(SB),NOSPLIT,$0
-	MOVL	$0, DX
-	JMP	runtime·morestack11(SB)
-
-TEXT runtime·morestack8_noctxt(SB),NOSPLIT,$0
-	MOVL	$0, DX
-	JMP	runtime·morestack8(SB)
-
-TEXT runtime·morestack16_noctxt(SB),NOSPLIT,$0
-	MOVL	$0, DX
-	JMP	runtime·morestack16(SB)
-
-TEXT runtime·morestack24_noctxt(SB),NOSPLIT,$0
-	MOVL	$0, DX
-	JMP	runtime·morestack24(SB)
-
-TEXT runtime·morestack32_noctxt(SB),NOSPLIT,$0
-	MOVL	$0, DX
-	JMP	runtime·morestack32(SB)
-
-TEXT runtime·morestack40_noctxt(SB),NOSPLIT,$0
-	MOVL	$0, DX
-	JMP	runtime·morestack40(SB)
-
-TEXT runtime·morestack48_noctxt(SB),NOSPLIT,$0
-	MOVL	$0, DX
-	JMP	runtime·morestack48(SB)
-
-// bool cas(int32 *val, int32 old, int32 new)
-// Atomically:
-//	if(*val == old){
-//		*val = new;
-//		return 1;
-//	} else
-//		return 0;
-TEXT runtime·cas(SB), NOSPLIT, $0-12
-	MOVL	val+0(FP), BX
-	MOVL	old+4(FP), AX
-	MOVL	new+8(FP), CX
-	LOCK
-	CMPXCHGL	CX, 0(BX)
-	JZ 3(PC)
-	MOVL	$0, AX
-	RET
-	MOVL	$1, AX
-	RET
-
-// bool	runtime·cas64(uint64 *val, uint64 old, uint64 new)
-// Atomically:
-//	if(*val == *old){
-//		*val = new;
-//		return 1;
-//	} else {
-//		return 0;
-//	}
-TEXT runtime·cas64(SB), NOSPLIT, $0-24
-	MOVL	val+0(FP), BX
-	MOVQ	old+8(FP), AX
-	MOVQ	new+16(FP), CX
-	LOCK
-	CMPXCHGQ	CX, 0(BX)
-	JNZ	cas64_fail
-	MOVL	$1, AX
-	RET
-cas64_fail:
-	MOVL	$0, AX
-	RET
-
-// bool casp(void **val, void *old, void *new)
-// Atomically:
-//	if(*val == old){
-//		*val = new;
-//		return 1;
-//	} else
-//		return 0;
-TEXT runtime·casp(SB), NOSPLIT, $0-12
-	MOVL	val+0(FP), BX
-	MOVL	old+4(FP), AX
-	MOVL	new+8(FP), CX
-	LOCK
-	CMPXCHGL	CX, 0(BX)
-	JZ 3(PC)
-	MOVL	$0, AX
-	RET
-	MOVL	$1, AX
-	RET
-
-// uint32 xadd(uint32 volatile *val, int32 delta)
-// Atomically:
-//	*val += delta;
-//	return *val;
-TEXT runtime·xadd(SB), NOSPLIT, $0-8
-	MOVL	val+0(FP), BX
-	MOVL	delta+4(FP), AX
-	MOVL	AX, CX
-	LOCK
-	XADDL	AX, 0(BX)
-	ADDL	CX, AX
-	RET
-
-TEXT runtime·xadd64(SB), NOSPLIT, $0-16
-	MOVL	val+0(FP), BX
-	MOVQ	delta+8(FP), AX
-	MOVQ	AX, CX
-	LOCK
-	XADDQ	AX, 0(BX)
-	ADDQ	CX, AX
-	RET
-
-TEXT runtime·xchg(SB), NOSPLIT, $0-8
-	MOVL	val+0(FP), BX
-	MOVL	new+4(FP), AX
-	XCHGL	AX, 0(BX)
-	RET
-
-TEXT runtime·xchg64(SB), NOSPLIT, $0-16
-	MOVL	val+0(FP), BX
-	MOVQ	new+8(FP), AX
-	XCHGQ	AX, 0(BX)
-	RET
-
-TEXT runtime·procyield(SB),NOSPLIT,$0-0
-	MOVL	val+0(FP), AX
-again:
-	PAUSE
-	SUBL	$1, AX
-	JNZ	again
-	RET
-
-TEXT runtime·atomicstorep(SB), NOSPLIT, $0-8
-	MOVL	ptr+0(FP), BX
-	MOVL	val+4(FP), AX
-	XCHGL	AX, 0(BX)
-	RET
-
-TEXT runtime·atomicstore(SB), NOSPLIT, $0-8
-	MOVL	ptr+0(FP), BX
-	MOVL	val+4(FP), AX
-	XCHGL	AX, 0(BX)
-	RET
-
-TEXT runtime·atomicstore64(SB), NOSPLIT, $0-16
-	MOVL	ptr+0(FP), BX
-	MOVQ	val+8(FP), AX
-	XCHGQ	AX, 0(BX)
-	RET
-
-// void jmpdefer(fn, sp);
-// called from deferreturn.
-// 1. pop the caller
-// 2. sub 5 bytes from the callers return
-// 3. jmp to the argument
-TEXT runtime·jmpdefer(SB), NOSPLIT, $0-16
-	MOVL	fn+0(FP), DX
-	MOVL	callersp+4(FP), BX
-	LEAL	-8(BX), SP	// caller sp after CALL
-	SUBL	$5, (SP)	// return to CALL again
-	MOVL	0(DX), BX
-	JMP	BX	// but first run the deferred function
-
-// asmcgocall(void(*fn)(void*), void *arg)
-// Not implemented.
-TEXT runtime·asmcgocall(SB),NOSPLIT,$0-8
-	MOVL	0, AX
-	RET
-
-// cgocallback(void (*fn)(void*), void *frame, uintptr framesize)
-// Not implemented.
-TEXT runtime·cgocallback(SB),NOSPLIT,$0-12
-	MOVL	0, AX
-	RET
-
-// void setmg(M*, G*); set m and g. for use by needm.
-// Not implemented.
-TEXT runtime·setmg(SB), NOSPLIT, $0-8
-	MOVL	0, AX
-	RET
-
-// check that SP is in range [g->stackbase, g->stackguard)
-TEXT runtime·stackcheck(SB), NOSPLIT, $0-0
-	get_tls(CX)
-	MOVL	g(CX), AX
-	CMPL	g_stackbase(AX), SP
-	JHI	2(PC)
-	MOVL	0, AX
-	CMPL	SP, g_stackguard(AX)
-	JHI	2(PC)
-	MOVL	0, AX
-	RET
-
-TEXT runtime·memclr(SB),NOSPLIT,$0-8
-	MOVL	addr+0(FP), DI
-	MOVL	count+4(FP), CX
-	MOVQ	CX, BX
-	ANDQ	$7, BX
-	SHRQ	$3, CX
-	MOVQ	$0, AX
-	CLD
-	REP
-	STOSQ
-	MOVQ	BX, CX
-	REP
-	STOSB
-	RET
-
-TEXT runtime·getcallerpc(SB),NOSPLIT,$0-8
-	MOVL	x+0(FP),AX		// addr of first arg
-	MOVL	-8(AX),AX		// get calling pc
-	RET
-
-TEXT runtime·setcallerpc(SB),NOSPLIT,$0-16
-	MOVL	x+0(FP),AX		// addr of first arg
-	MOVL	pc+4(FP), BX		// pc to set
-	MOVQ	BX, -8(AX)		// set calling pc
-	RET
-
-TEXT runtime·getcallersp(SB),NOSPLIT,$0-8
-	MOVL	sp+0(FP), AX
-	RET
-
-// int64 runtime·cputicks(void)
-TEXT runtime·cputicks(SB),NOSPLIT,$0-0
-	RDTSC
-	SHLQ	$32, DX
-	ADDQ	DX, AX
-	RET
-
-TEXT runtime·stackguard(SB),NOSPLIT,$0-16
-	MOVL	SP, DX
-	MOVL	DX, sp+0(FP)
-	get_tls(CX)
-	MOVL	g(CX), BX
-	MOVL	g_stackguard(BX), DX
-	MOVL	DX, limit+4(FP)
-	RET
-
-GLOBL runtime·tls0(SB), $64
-
-// hash function using AES hardware instructions
-// For now, our one amd64p32 system (NaCl) does not
-// support using AES instructions, so have not bothered to
-// write the implementations. Can copy and adjust the ones
-// in asm_amd64.s when the time comes.
-
-TEXT runtime·aeshash(SB),NOSPLIT,$0-24
-	RET
-
-TEXT runtime·aeshashstr(SB),NOSPLIT,$0-24
-	RET
-
-TEXT runtime·aeshash32(SB),NOSPLIT,$0-24
-	RET
-
-TEXT runtime·aeshash64(SB),NOSPLIT,$0-24
-	RET
-
-TEXT runtime·memeq(SB),NOSPLIT,$0-12
-	MOVL	a+0(FP), SI
-	MOVL	b+4(FP), DI
-	MOVL	count+8(FP), BX
-	JMP	runtime·memeqbody(SB)
-
-// a in SI
-// b in DI
-// count in BX
-TEXT runtime·memeqbody(SB),NOSPLIT,$0-0
-	XORQ	AX, AX
-
-	CMPQ	BX, $8
-	JB	small
-	
-	// 64 bytes at a time using xmm registers
-hugeloop:
-	CMPQ	BX, $64
-	JB	bigloop
-	MOVOU	(SI), X0
-	MOVOU	(DI), X1
-	MOVOU	16(SI), X2
-	MOVOU	16(DI), X3
-	MOVOU	32(SI), X4
-	MOVOU	32(DI), X5
-	MOVOU	48(SI), X6
-	MOVOU	48(DI), X7
-	PCMPEQB	X1, X0
-	PCMPEQB	X3, X2
-	PCMPEQB	X5, X4
-	PCMPEQB	X7, X6
-	PAND	X2, X0
-	PAND	X6, X4
-	PAND	X4, X0
-	PMOVMSKB X0, DX
-	ADDQ	$64, SI
-	ADDQ	$64, DI
-	SUBQ	$64, BX
-	CMPL	DX, $0xffff
-	JEQ	hugeloop
-	RET
-
-	// 8 bytes at a time using 64-bit register
-bigloop:
-	CMPQ	BX, $8
-	JBE	leftover
-	MOVQ	(SI), CX
-	MOVQ	(DI), DX
-	ADDQ	$8, SI
-	ADDQ	$8, DI
-	SUBQ	$8, BX
-	CMPQ	CX, DX
-	JEQ	bigloop
-	RET
-
-	// remaining 0-8 bytes
-leftover:
-	ADDQ	BX, SI
-	ADDQ	BX, DI
-	MOVQ	-8(SI), CX
-	MOVQ	-8(DI), DX
-	CMPQ	CX, DX
-	SETEQ	AX
-	RET
-
-small:
-	CMPQ	BX, $0
-	JEQ	equal
-
-	LEAQ	0(BX*8), CX
-	NEGQ	CX
-
-	CMPB	SI, $0xf8
-	JA	si_high
-
-	// load at SI won't cross a page boundary.
-	MOVQ	(SI), SI
-	JMP	si_finish
-si_high:
-	// address ends in 11111xxx.  Load up to bytes we want, move to correct position.
-	MOVQ	BX, DX
-	ADDQ	SI, DX
-	MOVQ	-8(DX), SI
-	SHRQ	CX, SI
-si_finish:
-
-	// same for DI.
-	CMPB	DI, $0xf8
-	JA	di_high
-	MOVQ	(DI), DI
-	JMP	di_finish
-di_high:
-	MOVQ	BX, DX
-	ADDQ	DI, DX
-	MOVQ	-8(DX), DI
-	SHRQ	CX, DI
-di_finish:
-
-	SUBQ	SI, DI
-	SHLQ	CX, DI
-equal:
-	SETEQ	AX
-	RET
-
-TEXT runtime·cmpstring(SB),NOSPLIT,$0-20
-	MOVL	s1+0(FP), SI
-	MOVL	s1+4(FP), BX
-	MOVL	s2+8(FP), DI
-	MOVL	s2+12(FP), DX
-	CALL	runtime·cmpbody(SB)
-	MOVL	AX, res+16(FP)
-	RET
-
-TEXT bytes·Compare(SB),NOSPLIT,$0-28
-	MOVL	s1+0(FP), SI
-	MOVL	s1+4(FP), BX
-	MOVL	s2+12(FP), DI
-	MOVL	s2+16(FP), DX
-	CALL	runtime·cmpbody(SB)
-	MOVQ	AX, res+24(FP)
-	RET
-
-// input:
-//   SI = a
-//   DI = b
-//   BX = alen
-//   DX = blen
-// output:
-//   AX = 1/0/-1
-TEXT runtime·cmpbody(SB),NOSPLIT,$0-0
-	CMPQ	SI, DI
-	JEQ	cmp_allsame
-	CMPQ	BX, DX
-	MOVQ	DX, R8
-	CMOVQLT	BX, R8 // R8 = min(alen, blen) = # of bytes to compare
-	CMPQ	R8, $8
-	JB	cmp_small
-
-cmp_loop:
-	CMPQ	R8, $16
-	JBE	cmp_0through16
-	MOVOU	(SI), X0
-	MOVOU	(DI), X1
-	PCMPEQB X0, X1
-	PMOVMSKB X1, AX
-	XORQ	$0xffff, AX	// convert EQ to NE
-	JNE	cmp_diff16	// branch if at least one byte is not equal
-	ADDQ	$16, SI
-	ADDQ	$16, DI
-	SUBQ	$16, R8
-	JMP	cmp_loop
-	
-	// AX = bit mask of differences
-cmp_diff16:
-	BSFQ	AX, BX	// index of first byte that differs
-	XORQ	AX, AX
-	ADDQ	BX, SI
-	MOVB	(SI), CX
-	ADDQ	BX, DI
-	CMPB	CX, (DI)
-	SETHI	AX
-	LEAQ	-1(AX*2), AX	// convert 1/0 to +1/-1
-	RET
-
-	// 0 through 16 bytes left, alen>=8, blen>=8
-cmp_0through16:
-	CMPQ	R8, $8
-	JBE	cmp_0through8
-	MOVQ	(SI), AX
-	MOVQ	(DI), CX
-	CMPQ	AX, CX
-	JNE	cmp_diff8
-cmp_0through8:
-	ADDQ	R8, SI
-	ADDQ	R8, DI
-	MOVQ	-8(SI), AX
-	MOVQ	-8(DI), CX
-	CMPQ	AX, CX
-	JEQ	cmp_allsame
-
-	// AX and CX contain parts of a and b that differ.
-cmp_diff8:
-	BSWAPQ	AX	// reverse order of bytes
-	BSWAPQ	CX
-	XORQ	AX, CX
-	BSRQ	CX, CX	// index of highest bit difference
-	SHRQ	CX, AX	// move a's bit to bottom
-	ANDQ	$1, AX	// mask bit
-	LEAQ	-1(AX*2), AX // 1/0 => +1/-1
-	RET
-
-	// 0-7 bytes in common
-cmp_small:
-	LEAQ	(R8*8), CX	// bytes left -> bits left
-	NEGQ	CX		//  - bits lift (== 64 - bits left mod 64)
-	JEQ	cmp_allsame
-
-	// load bytes of a into high bytes of AX
-	CMPB	SI, $0xf8
-	JA	cmp_si_high
-	MOVQ	(SI), SI
-	JMP	cmp_si_finish
-cmp_si_high:
-	ADDQ	R8, SI
-	MOVQ	-8(SI), SI
-	SHRQ	CX, SI
-cmp_si_finish:
-	SHLQ	CX, SI
-
-	// load bytes of b in to high bytes of BX
-	CMPB	DI, $0xf8
-	JA	cmp_di_high
-	MOVQ	(DI), DI
-	JMP	cmp_di_finish
-cmp_di_high:
-	ADDQ	R8, DI
-	MOVQ	-8(DI), DI
-	SHRQ	CX, DI
-cmp_di_finish:
-	SHLQ	CX, DI
-
-	BSWAPQ	SI	// reverse order of bytes
-	BSWAPQ	DI
-	XORQ	SI, DI	// find bit differences
-	JEQ	cmp_allsame
-	BSRQ	DI, CX	// index of highest bit difference
-	SHRQ	CX, SI	// move a's bit to bottom
-	ANDQ	$1, SI	// mask bit
-	LEAQ	-1(SI*2), AX // 1/0 => +1/-1
-	RET
-
-cmp_allsame:
-	XORQ	AX, AX
-	XORQ	CX, CX
-	CMPQ	BX, DX
-	SETGT	AX	// 1 if alen > blen
-	SETEQ	CX	// 1 if alen == blen
-	LEAQ	-1(CX)(AX*2), AX	// 1,0,-1 result
-	RET
-
-TEXT bytes·IndexByte(SB),NOSPLIT,$0
-	MOVL s+0(FP), SI
-	MOVL s_len+4(FP), BX
-	MOVB c+12(FP), AL
-	CALL runtime·indexbytebody(SB)
-	MOVL AX, ret+16(FP)
-	RET
-
-TEXT strings·IndexByte(SB),NOSPLIT,$0
-	MOVL s+0(FP), SI
-	MOVL s_len+4(FP), BX
-	MOVB c+8(FP), AL
-	CALL runtime·indexbytebody(SB)
-	MOVL AX, ret+16(FP)
-	RET
-
-// input:
-//   SI: data
-//   BX: data len
-//   AL: byte sought
-// output:
-//   AX
-TEXT runtime·indexbytebody(SB),NOSPLIT,$0
-	MOVL SI, DI
-
-	CMPL BX, $16
-	JLT indexbyte_small
-
-	// round up to first 16-byte boundary
-	TESTL $15, SI
-	JZ aligned
-	MOVL SI, CX
-	ANDL $~15, CX
-	ADDL $16, CX
-
-	// search the beginning
-	SUBL SI, CX
-	REPN; SCASB
-	JZ success
-
-// DI is 16-byte aligned; get ready to search using SSE instructions
-aligned:
-	// round down to last 16-byte boundary
-	MOVL BX, R11
-	ADDL SI, R11
-	ANDL $~15, R11
-
-	// shuffle X0 around so that each byte contains c
-	MOVD AX, X0
-	PUNPCKLBW X0, X0
-	PUNPCKLBW X0, X0
-	PSHUFL $0, X0, X0
-	JMP condition
-
-sse:
-	// move the next 16-byte chunk of the buffer into X1
-	MOVO (DI), X1
-	// compare bytes in X0 to X1
-	PCMPEQB X0, X1
-	// take the top bit of each byte in X1 and put the result in DX
-	PMOVMSKB X1, DX
-	TESTL DX, DX
-	JNZ ssesuccess
-	ADDL $16, DI
-
-condition:
-	CMPL DI, R11
-	JLT sse
-
-	// search the end
-	MOVL SI, CX
-	ADDL BX, CX
-	SUBL R11, CX
-	// if CX == 0, the zero flag will be set and we'll end up
-	// returning a false success
-	JZ failure
-	REPN; SCASB
-	JZ success
-
-failure:
-	MOVL $-1, AX
-	RET
-
-// handle for lengths < 16
-indexbyte_small:
-	MOVL BX, CX
-	REPN; SCASB
-	JZ success
-	MOVL $-1, AX
-	RET
-
-// we've found the chunk containing the byte
-// now just figure out which specific byte it is
-ssesuccess:
-	// get the index of the least significant set bit
-	BSFW DX, DX
-	SUBL SI, DI
-	ADDL DI, DX
-	MOVL DX, AX
-	RET
-
-success:
-	SUBL SI, DI
-	SUBL $1, DI
-	MOVL DI, AX
-	RET
-
-TEXT bytes·Equal(SB),NOSPLIT,$0-25
-	MOVL	a_len+4(FP), BX
-	MOVL	b_len+16(FP), CX
-	XORL	AX, AX
-	CMPL	BX, CX
-	JNE	eqret
-	MOVL	a+0(FP), SI
-	MOVL	b+12(FP), DI
-	CALL	runtime·memeqbody(SB)
-eqret:
-	MOVB	AX, ret+24(FP)
-	RET
-
-TEXT runtime·timenow(SB), NOSPLIT, $0-0
-	JMP	time·now(SB)
diff --git a/src/pkg/runtime/asm_arm.s b/src/pkg/runtime/asm_arm.s
deleted file mode 100644
index 1aea903..0000000
--- a/src/pkg/runtime/asm_arm.s
+++ /dev/null
@@ -1,1179 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "zasm_GOOS_GOARCH.h"
-#include "funcdata.h"
-#include "../../cmd/ld/textflag.h"
-
-// using frame size $-4 means do not save LR on stack.
-TEXT _rt0_go(SB),NOSPLIT,$-4
-	MOVW	$0xcafebabe, R12
-
-	// copy arguments forward on an even stack
-	// use R13 instead of SP to avoid linker rewriting the offsets
-	MOVW	0(R13), R0		// argc
-	MOVW	4(R13), R1		// argv
-	SUB	$64, R13		// plenty of scratch
-	AND	$~7, R13
-	MOVW	R0, 60(R13)		// save argc, argv away
-	MOVW	R1, 64(R13)
-
-	// set up m and g registers
-	// g is R10, m is R9
-	MOVW	$runtime·g0(SB), g
-	MOVW	$runtime·m0(SB), m
-
-	// save m->g0 = g0
-	MOVW	g, m_g0(m)
-
-	// create istack out of the OS stack
-	MOVW	$(-8192+104)(R13), R0
-	MOVW	R0, g_stackguard(g)	// (w 104b guard)
-	MOVW	R0, g_stackguard0(g)
-	MOVW	R13, g_stackbase(g)
-	BL	runtime·emptyfunc(SB)	// fault if stack check is wrong
-
-	// if there is an _cgo_init, call it.
-	MOVW	_cgo_init(SB), R4
-	CMP	$0, R4
-	B.EQ	nocgo
-	BL		runtime·save_gm(SB);
-	MOVW	g, R0 // first argument of _cgo_init is g
-	MOVW	$setmg_gcc<>(SB), R1 // second argument is address of save_gm
-	BL		(R4) // will clobber R0-R3
-
-nocgo:
-	// update stackguard after _cgo_init
-	MOVW	g_stackguard0(g), R0
-	MOVW	R0, g_stackguard(g)
-
-	BL	runtime·checkgoarm(SB)
-	BL	runtime·check(SB)
-
-	// saved argc, argv
-	MOVW	60(R13), R0
-	MOVW	R0, 4(R13)
-	MOVW	64(R13), R1
-	MOVW	R1, 8(R13)
-	BL	runtime·args(SB)
-	BL	runtime·osinit(SB)
-	BL	runtime·hashinit(SB)
-	BL	runtime·schedinit(SB)
-
-	// create a new goroutine to start program
-	MOVW	$runtime·main·f(SB), R0
-	MOVW.W	R0, -4(R13)
-	MOVW	$8, R0
-	MOVW.W	R0, -4(R13)
-	MOVW	$0, R0
-	MOVW.W	R0, -4(R13)	// push $0 as guard
-	ARGSIZE(12)
-	BL	runtime·newproc(SB)
-	ARGSIZE(-1)
-	MOVW	$12(R13), R13	// pop args and LR
-
-	// start this M
-	BL	runtime·mstart(SB)
-
-	MOVW	$1234, R0
-	MOVW	$1000, R1
-	MOVW	R0, (R1)	// fail hard
-
-DATA	runtime·main·f+0(SB)/4,$runtime·main(SB)
-GLOBL	runtime·main·f(SB),RODATA,$4
-
-TEXT runtime·breakpoint(SB),NOSPLIT,$0-0
-	// gdb won't skip this breakpoint instruction automatically,
-	// so you must manually "set $pc+=4" to skip it and continue.
-	WORD	$0xe1200071	// BKPT 0x0001
-	RET
-
-TEXT runtime·asminit(SB),NOSPLIT,$0-0
-	// disable runfast (flush-to-zero) mode of vfp if runtime.goarm > 5
-	MOVB	runtime·goarm(SB), R11
-	CMP	$5, R11
-	BLE	4(PC)
-	WORD	$0xeef1ba10	// vmrs r11, fpscr
-	BIC	$(1<<24), R11
-	WORD	$0xeee1ba10	// vmsr fpscr, r11
-	RET
-
-/*
- *  go-routine
- */
-
-// void gosave(Gobuf*)
-// save state in Gobuf; setjmp
-TEXT runtime·gosave(SB), NOSPLIT, $-4-4
-	MOVW	0(FP), R0		// gobuf
-	MOVW	SP, gobuf_sp(R0)
-	MOVW	LR, gobuf_pc(R0)
-	MOVW	g, gobuf_g(R0)
-	MOVW	$0, R11
-	MOVW	R11, gobuf_lr(R0)
-	MOVW	R11, gobuf_ret(R0)
-	MOVW	R11, gobuf_ctxt(R0)
-	RET
-
-// void gogo(Gobuf*)
-// restore state from Gobuf; longjmp
-TEXT runtime·gogo(SB), NOSPLIT, $-4-4
-	MOVW	0(FP), R1		// gobuf
-	MOVW	gobuf_g(R1), g
-	MOVW	0(g), R2		// make sure g != nil
-	MOVB	runtime·iscgo(SB), R2
-	CMP 	$0, R2 // if in Cgo, we have to save g and m
-	BL.NE	runtime·save_gm(SB) // this call will clobber R0
-	MOVW	gobuf_sp(R1), SP	// restore SP
-	MOVW	gobuf_lr(R1), LR
-	MOVW	gobuf_ret(R1), R0
-	MOVW	gobuf_ctxt(R1), R7
-	MOVW	$0, R11
-	MOVW	R11, gobuf_sp(R1)	// clear to help garbage collector
-	MOVW	R11, gobuf_ret(R1)
-	MOVW	R11, gobuf_lr(R1)
-	MOVW	R11, gobuf_ctxt(R1)
-	CMP	R11, R11 // set condition codes for == test, needed by stack split
-	MOVW	gobuf_pc(R1), PC
-
-// void mcall(void (*fn)(G*))
-// Switch to m->g0's stack, call fn(g).
-// Fn must never return.  It should gogo(&g->sched)
-// to keep running g.
-TEXT runtime·mcall(SB), NOSPLIT, $-4-4
-	MOVW	fn+0(FP), R0
-
-	// Save caller state in g->sched.
-	MOVW	SP, (g_sched+gobuf_sp)(g)
-	MOVW	LR, (g_sched+gobuf_pc)(g)
-	MOVW	$0, R11
-	MOVW	R11, (g_sched+gobuf_lr)(g)
-	MOVW	g, (g_sched+gobuf_g)(g)
-
-	// Switch to m->g0 & its stack, call fn.
-	MOVW	g, R1
-	MOVW	m_g0(m), g
-	CMP	g, R1
-	B.NE	2(PC)
-	B	runtime·badmcall(SB)
-	MOVW	(g_sched+gobuf_sp)(g), SP
-	SUB	$8, SP
-	MOVW	R1, 4(SP)
-	BL	(R0)
-	B	runtime·badmcall2(SB)
-	RET
-
-/*
- * support for morestack
- */
-
-// Called during function prolog when more stack is needed.
-// R1 frame size
-// R2 arg size
-// R3 prolog's LR
-// NB. we do not save R0 because we've forced 5c to pass all arguments
-// on the stack.
-// using frame size $-4 means do not save LR on stack.
-//
-// The traceback routines see morestack on a g0 as being
-// the top of a stack (for example, morestack calling newstack
-// calling the scheduler calling newm calling gc), so we must
-// record an argument size. For that purpose, it has no arguments.
-TEXT runtime·morestack(SB),NOSPLIT,$-4-0
-	// Cannot grow scheduler stack (m->g0).
-	MOVW	m_g0(m), R4
-	CMP	g, R4
-	BL.EQ	runtime·abort(SB)
-
-	MOVW	R1, m_moreframesize(m)
-	MOVW	R2, m_moreargsize(m)
-
-	// Called from f.
-	// Set g->sched to context in f.
-	MOVW	R7, (g_sched+gobuf_ctxt)(g)
-	MOVW	SP, (g_sched+gobuf_sp)(g)
-	MOVW	LR, (g_sched+gobuf_pc)(g)
-	MOVW	R3, (g_sched+gobuf_lr)(g)
-
-	// Called from f.
-	// Set m->morebuf to f's caller.
-	MOVW	R3, (m_morebuf+gobuf_pc)(m)	// f's caller's PC
-	MOVW	SP, (m_morebuf+gobuf_sp)(m)	// f's caller's SP
-	MOVW	$4(SP), R3			// f's argument pointer
-	MOVW	R3, m_moreargp(m)	
-	MOVW	g, (m_morebuf+gobuf_g)(m)
-
-	// Call newstack on m->g0's stack.
-	MOVW	m_g0(m), g
-	MOVW	(g_sched+gobuf_sp)(g), SP
-	BL	runtime·newstack(SB)
-
-	// Not reached, but make sure the return PC from the call to newstack
-	// is still in this function, and not the beginning of the next.
-	RET
-
-TEXT runtime·morestack_noctxt(SB),NOSPLIT,$-4-0
-	MOVW	$0, R7
-	B runtime·morestack(SB)
-
-// Called from panic.  Mimics morestack,
-// reuses stack growth code to create a frame
-// with the desired args running the desired function.
-//
-// func call(fn *byte, arg *byte, argsize uint32).
-TEXT runtime·newstackcall(SB), NOSPLIT, $-4-12
-	// Save our caller's state as the PC and SP to
-	// restore when returning from f.
-	MOVW	LR, (m_morebuf+gobuf_pc)(m)	// our caller's PC
-	MOVW	SP, (m_morebuf+gobuf_sp)(m)	// our caller's SP
-	MOVW	g,  (m_morebuf+gobuf_g)(m)
-
-	// Save our own state as the PC and SP to restore
-	// if this goroutine needs to be restarted.
-	MOVW	$runtime·newstackcall(SB), R11
-	MOVW	R11, (g_sched+gobuf_pc)(g)
-	MOVW	LR, (g_sched+gobuf_lr)(g)
-	MOVW	SP, (g_sched+gobuf_sp)(g)
-
-	// Set up morestack arguments to call f on a new stack.
-	// We set f's frame size to 1, as a hint to newstack
-	// that this is a call from runtime·newstackcall.
-	// If it turns out that f needs a larger frame than
-	// the default stack, f's usual stack growth prolog will
-	// allocate a new segment (and recopy the arguments).
-	MOVW	4(SP), R0			// fn
-	MOVW	8(SP), R1			// arg frame
-	MOVW	12(SP), R2			// arg size
-
-	MOVW	R0, m_cret(m)			// f's PC
-	MOVW	R1, m_moreargp(m)		// f's argument pointer
-	MOVW	R2, m_moreargsize(m)		// f's argument size
-	MOVW	$1, R3
-	MOVW	R3, m_moreframesize(m)		// f's frame size
-
-	// Call newstack on m->g0's stack.
-	MOVW	m_g0(m), g
-	MOVW	(g_sched+gobuf_sp)(g), SP
-	B	runtime·newstack(SB)
-
-// reflect·call: call a function with the given argument list
-// func call(f *FuncVal, arg *byte, argsize uint32).
-// we don't have variable-sized frames, so we use a small number
-// of constant-sized-frame functions to encode a few bits of size in the pc.
-// Caution: ugly multiline assembly macros in your future!
-
-#define DISPATCH(NAME,MAXSIZE)		\
-	CMP	$MAXSIZE, R0;		\
-	B.HI	3(PC);			\
-	MOVW	$runtime·NAME(SB), R1;	\
-	B	(R1)
-
-TEXT reflect·call(SB), NOSPLIT, $-4-16
-	MOVW	argsize+8(FP), R0
-	DISPATCH(call16, 16)
-	DISPATCH(call32, 32)
-	DISPATCH(call64, 64)
-	DISPATCH(call128, 128)
-	DISPATCH(call256, 256)
-	DISPATCH(call512, 512)
-	DISPATCH(call1024, 1024)
-	DISPATCH(call2048, 2048)
-	DISPATCH(call4096, 4096)
-	DISPATCH(call8192, 8192)
-	DISPATCH(call16384, 16384)
-	DISPATCH(call32768, 32768)
-	DISPATCH(call65536, 65536)
-	DISPATCH(call131072, 131072)
-	DISPATCH(call262144, 262144)
-	DISPATCH(call524288, 524288)
-	DISPATCH(call1048576, 1048576)
-	DISPATCH(call2097152, 2097152)
-	DISPATCH(call4194304, 4194304)
-	DISPATCH(call8388608, 8388608)
-	DISPATCH(call16777216, 16777216)
-	DISPATCH(call33554432, 33554432)
-	DISPATCH(call67108864, 67108864)
-	DISPATCH(call134217728, 134217728)
-	DISPATCH(call268435456, 268435456)
-	DISPATCH(call536870912, 536870912)
-	DISPATCH(call1073741824, 1073741824)
-	MOVW	$runtime·badreflectcall(SB), R1
-	B	(R1)
-
-// Argument map for the callXX frames.  Each has one
-// stack map (for the single call) with 3 arguments.
-DATA gcargs_reflectcall<>+0x00(SB)/4, $1  // 1 stackmap
-DATA gcargs_reflectcall<>+0x04(SB)/4, $6  // 3 args
-DATA gcargs_reflectcall<>+0x08(SB)/4, $(const_BitsPointer+(const_BitsPointer<<2)+(const_BitsScalar<<4))
-GLOBL gcargs_reflectcall<>(SB),RODATA,$12
-
-// callXX frames have no locals
-DATA gclocals_reflectcall<>+0x00(SB)/4, $1  // 1 stackmap
-DATA gclocals_reflectcall<>+0x04(SB)/4, $0  // 0 locals
-GLOBL gclocals_reflectcall<>(SB),RODATA,$8
-
-#define CALLFN(NAME,MAXSIZE)			\
-TEXT runtime·NAME(SB), WRAPPER, $MAXSIZE-16;	\
-	FUNCDATA $FUNCDATA_ArgsPointerMaps,gcargs_reflectcall<>(SB);	\
-	FUNCDATA $FUNCDATA_LocalsPointerMaps,gclocals_reflectcall<>(SB);\
-	/* copy arguments to stack */		\
-	MOVW	argptr+4(FP), R0;		\
-	MOVW	argsize+8(FP), R2;		\
-	ADD	$4, SP, R1;			\
-	CMP	$0, R2;				\
-	B.EQ	5(PC);				\
-	MOVBU.P	1(R0), R5;			\
-	MOVBU.P R5, 1(R1);			\
-	SUB	$1, R2, R2;			\
-	B	-5(PC);				\
-	/* call function */			\
-	MOVW	f+0(FP), R7;			\
-	MOVW	(R7), R0;			\
-	PCDATA  $PCDATA_StackMapIndex, $0;	\
-	BL	(R0);				\
-	/* copy return values back */		\
-	MOVW	argptr+4(FP), R0;		\
-	MOVW	argsize+8(FP), R2;		\
-	MOVW	retoffset+12(FP), R3;		\
-	ADD	$4, SP, R1;			\
-	ADD	R3, R1;				\
-	ADD	R3, R0;				\
-	SUB	R3, R2;				\
-	CMP	$0, R2;				\
-	RET.EQ	;				\
-	MOVBU.P	1(R1), R5;			\
-	MOVBU.P R5, 1(R0);			\
-	SUB	$1, R2, R2;			\
-	B	-5(PC)				\
-
-CALLFN(call16, 16)
-CALLFN(call32, 32)
-CALLFN(call64, 64)
-CALLFN(call128, 128)
-CALLFN(call256, 256)
-CALLFN(call512, 512)
-CALLFN(call1024, 1024)
-CALLFN(call2048, 2048)
-CALLFN(call4096, 4096)
-CALLFN(call8192, 8192)
-CALLFN(call16384, 16384)
-CALLFN(call32768, 32768)
-CALLFN(call65536, 65536)
-CALLFN(call131072, 131072)
-CALLFN(call262144, 262144)
-CALLFN(call524288, 524288)
-CALLFN(call1048576, 1048576)
-CALLFN(call2097152, 2097152)
-CALLFN(call4194304, 4194304)
-CALLFN(call8388608, 8388608)
-CALLFN(call16777216, 16777216)
-CALLFN(call33554432, 33554432)
-CALLFN(call67108864, 67108864)
-CALLFN(call134217728, 134217728)
-CALLFN(call268435456, 268435456)
-CALLFN(call536870912, 536870912)
-CALLFN(call1073741824, 1073741824)
-
-// Return point when leaving stack.
-// using frame size $-4 means do not save LR on stack.
-//
-// Lessstack can appear in stack traces for the same reason
-// as morestack; in that context, it has 0 arguments.
-TEXT runtime·lessstack(SB), NOSPLIT, $-4-0
-	// Save return value in m->cret
-	MOVW	R0, m_cret(m)
-
-	// Call oldstack on m->g0's stack.
-	MOVW	m_g0(m), g
-	MOVW	(g_sched+gobuf_sp)(g), SP
-	BL	runtime·oldstack(SB)
-
-// void jmpdefer(fn, sp);
-// called from deferreturn.
-// 1. grab stored LR for caller
-// 2. sub 4 bytes to get back to BL deferreturn
-// 3. B to fn
-// TODO(rsc): Push things on stack and then use pop
-// to load all registers simultaneously, so that a profiling
-// interrupt can never see mismatched SP/LR/PC.
-// (And double-check that pop is atomic in that way.)
-TEXT runtime·jmpdefer(SB), NOSPLIT, $0-8
-	MOVW	0(SP), LR
-	MOVW	$-4(LR), LR	// BL deferreturn
-	MOVW	fn+0(FP), R7
-	MOVW	argp+4(FP), SP
-	MOVW	$-4(SP), SP	// SP is 4 below argp, due to saved LR
-	MOVW	0(R7), R1
-	B	(R1)
-
-// Save state of caller into g->sched. Smashes R11.
-TEXT gosave<>(SB),NOSPLIT,$0
-	MOVW	LR, (g_sched+gobuf_pc)(g)
-	MOVW	R13, (g_sched+gobuf_sp)(g)
-	MOVW	$0, R11
-	MOVW	R11, (g_sched+gobuf_lr)(g)
-	MOVW	R11, (g_sched+gobuf_ret)(g)
-	MOVW	R11, (g_sched+gobuf_ctxt)(g)
-	RET
-
-// asmcgocall(void(*fn)(void*), void *arg)
-// Call fn(arg) on the scheduler stack,
-// aligned appropriately for the gcc ABI.
-// See cgocall.c for more details.
-TEXT	runtime·asmcgocall(SB),NOSPLIT,$0-8
-	MOVW	fn+0(FP), R1
-	MOVW	arg+4(FP), R0
-	MOVW	R13, R2
-	MOVW	g, R5
-
-	// Figure out if we need to switch to m->g0 stack.
-	// We get called to create new OS threads too, and those
-	// come in on the m->g0 stack already.
-	MOVW	m_g0(m), R3
-	CMP	R3, g
-	BEQ	4(PC)
-	BL	gosave<>(SB)
-	MOVW	R3, g
-	MOVW	(g_sched+gobuf_sp)(g), R13
-
-	// Now on a scheduling stack (a pthread-created stack).
-	SUB	$24, R13
-	BIC	$0x7, R13	// alignment for gcc ABI
-	MOVW	R5, 20(R13) // save old g
-	MOVW	R2, 16(R13)	// save old SP
-	// R0 already contains the first argument
-	BL	(R1)
-
-	// Restore registers, g, stack pointer.
-	MOVW	20(R13), g
-	MOVW	16(R13), R13
-	RET
-
-// cgocallback(void (*fn)(void*), void *frame, uintptr framesize)
-// Turn the fn into a Go func (by taking its address) and call
-// cgocallback_gofunc.
-TEXT runtime·cgocallback(SB),NOSPLIT,$12-12
-	MOVW	$fn+0(FP), R0
-	MOVW	R0, 4(R13)
-	MOVW	frame+4(FP), R0
-	MOVW	R0, 8(R13)
-	MOVW	framesize+8(FP), R0
-	MOVW	R0, 12(R13)
-	MOVW	$runtime·cgocallback_gofunc(SB), R0
-	BL	(R0)
-	RET
-
-// cgocallback_gofunc(void (*fn)(void*), void *frame, uintptr framesize)
-// See cgocall.c for more details.
-TEXT	runtime·cgocallback_gofunc(SB),NOSPLIT,$8-12
-	// Load m and g from thread-local storage.
-	MOVB	runtime·iscgo(SB), R0
-	CMP	$0, R0
-	BL.NE	runtime·load_gm(SB)
-
-	// If m is nil, Go did not create the current thread.
-	// Call needm to obtain one for temporary use.
-	// In this case, we're running on the thread stack, so there's
-	// lots of space, but the linker doesn't know. Hide the call from
-	// the linker analysis by using an indirect call.
-	MOVW	m, savedm-4(SP)
-	CMP	$0, m
-	B.NE	havem
-	MOVW	$runtime·needm(SB), R0
-	BL	(R0)
-
-havem:
-	// Now there's a valid m, and we're running on its m->g0.
-	// Save current m->g0->sched.sp on stack and then set it to SP.
-	// Save current sp in m->g0->sched.sp in preparation for
-	// switch back to m->curg stack.
-	// NOTE: unwindm knows that the saved g->sched.sp is at 4(R13) aka savedsp-8(SP).
-	MOVW	m_g0(m), R3
-	MOVW	(g_sched+gobuf_sp)(R3), R4
-	MOVW	R4, savedsp-8(SP)
-	MOVW	R13, (g_sched+gobuf_sp)(R3)
-
-	// Switch to m->curg stack and call runtime.cgocallbackg.
-	// Because we are taking over the execution of m->curg
-	// but *not* resuming what had been running, we need to
-	// save that information (m->curg->sched) so we can restore it.
-	// We can restore m->curg->sched.sp easily, because calling
-	// runtime.cgocallbackg leaves SP unchanged upon return.
-	// To save m->curg->sched.pc, we push it onto the stack.
-	// This has the added benefit that it looks to the traceback
-	// routine like cgocallbackg is going to return to that
-	// PC (because the frame we allocate below has the same
-	// size as cgocallback_gofunc's frame declared above)
-	// so that the traceback will seamlessly trace back into
-	// the earlier calls.
-	//
-	// In the new goroutine, -8(SP) and -4(SP) are unused.
-	MOVW	fn+4(FP), R0
-	MOVW	frame+8(FP), R1
-	MOVW	framesize+12(FP), R2
-	MOVW	m_curg(m), g
-	MOVW	(g_sched+gobuf_sp)(g), R4 // prepare stack as R4
-	MOVW	(g_sched+gobuf_pc)(g), R5
-	MOVW	R5, -12(R4)
-	MOVW	$-12(R4), R13
-	BL	runtime·cgocallbackg(SB)
-
-	// Restore g->sched (== m->curg->sched) from saved values.
-	MOVW	0(R13), R5
-	MOVW	R5, (g_sched+gobuf_pc)(g)
-	MOVW	$12(R13), R4
-	MOVW	R4, (g_sched+gobuf_sp)(g)
-
-	// Switch back to m->g0's stack and restore m->g0->sched.sp.
-	// (Unlike m->curg, the g0 goroutine never uses sched.pc,
-	// so we do not have to restore it.)
-	MOVW	m_g0(m), g
-	MOVW	(g_sched+gobuf_sp)(g), R13
-	MOVW	savedsp-8(SP), R4
-	MOVW	R4, (g_sched+gobuf_sp)(g)
-
-	// If the m on entry was nil, we called needm above to borrow an m
-	// for the duration of the call. Since the call is over, return it with dropm.
-	MOVW	savedm-4(SP), R6
-	CMP	$0, R6
-	B.NE	3(PC)
-	MOVW	$runtime·dropm(SB), R0
-	BL	(R0)
-
-	// Done!
-	RET
-
-// void setmg(M*, G*); set m and g. for use by needm.
-TEXT runtime·setmg(SB), NOSPLIT, $0-8
-	MOVW	mm+0(FP), m
-	MOVW	gg+4(FP), g
-
-	// Save m and g to thread-local storage.
-	MOVB	runtime·iscgo(SB), R0
-	CMP	$0, R0
-	BL.NE	runtime·save_gm(SB)
-
-	RET
-
-TEXT runtime·getcallerpc(SB),NOSPLIT,$-4-4
-	MOVW	0(SP), R0
-	RET
-
-TEXT runtime·setcallerpc(SB),NOSPLIT,$-4-8
-	MOVW	x+4(FP), R0
-	MOVW	R0, 0(SP)
-	RET
-
-TEXT runtime·getcallersp(SB),NOSPLIT,$-4-4
-	MOVW	0(FP), R0
-	MOVW	$-4(R0), R0
-	RET
-
-TEXT runtime·emptyfunc(SB),0,$0-0
-	RET
-
-TEXT runtime·abort(SB),NOSPLIT,$-4-0
-	MOVW	$0, R0
-	MOVW	(R0), R1
-
-// bool armcas(int32 *val, int32 old, int32 new)
-// Atomically:
-//	if(*val == old){
-//		*val = new;
-//		return 1;
-//	}else
-//		return 0;
-//
-// To implement runtime·cas in sys_$GOOS_arm.s
-// using the native instructions, use:
-//
-//	TEXT runtime·cas(SB),NOSPLIT,$0
-//		B	runtime·armcas(SB)
-//
-TEXT runtime·armcas(SB),NOSPLIT,$0-12
-	MOVW	valptr+0(FP), R1
-	MOVW	old+4(FP), R2
-	MOVW	new+8(FP), R3
-casl:
-	LDREX	(R1), R0
-	CMP	R0, R2
-	BNE	casfail
-	STREX	R3, (R1), R0
-	CMP	$0, R0
-	BNE	casl
-	MOVW	$1, R0
-	RET
-casfail:
-	MOVW	$0, R0
-	RET
-
-TEXT runtime·stackguard(SB),NOSPLIT,$0-8
-	MOVW	R13, R1
-	MOVW	g_stackguard(g), R2
-	MOVW	R1, sp+0(FP)
-	MOVW	R2, limit+4(FP)
-	RET
-
-// AES hashing not implemented for ARM
-TEXT runtime·aeshash(SB),NOSPLIT,$-4-0
-	MOVW	$0, R0
-	MOVW	(R0), R1
-TEXT runtime·aeshash32(SB),NOSPLIT,$-4-0
-	MOVW	$0, R0
-	MOVW	(R0), R1
-TEXT runtime·aeshash64(SB),NOSPLIT,$-4-0
-	MOVW	$0, R0
-	MOVW	(R0), R1
-TEXT runtime·aeshashstr(SB),NOSPLIT,$-4-0
-	MOVW	$0, R0
-	MOVW	(R0), R1
-
-TEXT runtime·memeq(SB),NOSPLIT,$-4-12
-	MOVW	a+0(FP), R1
-	MOVW	b+4(FP), R2
-	MOVW	n+8(FP), R3
-	ADD	R1, R3, R6
-	MOVW	$1, R0
-_next:
-	CMP	R1, R6
-	RET.EQ
-	MOVBU.P	1(R1), R4
-	MOVBU.P	1(R2), R5
-	CMP	R4, R5
-	BEQ	_next
-
-	MOVW	$0, R0
-	RET
-
-// We have to resort to TLS variable to save g(R10) and
-// m(R9). One reason is that external code might trigger
-// SIGSEGV, and our runtime.sigtramp don't even know we
-// are in external code, and will continue to use R10/R9,
-// this might as well result in another SIGSEGV.
-// Note: all three functions will clobber R0, and the last
-// two can be called from 5c ABI code.
-
-// save_gm saves the g and m registers into pthread-provided
-// thread-local memory, so that we can call externally compiled
-// ARM code that will overwrite those registers.
-// NOTE: runtime.gogo assumes that R1 is preserved by this function.
-TEXT runtime·save_gm(SB),NOSPLIT,$0
-	MRC		15, 0, R0, C13, C0, 3 // fetch TLS base pointer
-	// $runtime.tlsgm(SB) is a special linker symbol.
-	// It is the offset from the TLS base pointer to our
-	// thread-local storage for g and m.
-	MOVW	$runtime·tlsgm(SB), R11
-	ADD	R11, R0
-	MOVW	g, 0(R0)
-	MOVW	m, 4(R0)
-	RET
-
-// load_gm loads the g and m registers from pthread-provided
-// thread-local memory, for use after calling externally compiled
-// ARM code that overwrote those registers.
-TEXT runtime·load_gm(SB),NOSPLIT,$0
-	MRC		15, 0, R0, C13, C0, 3 // fetch TLS base pointer
-	// $runtime.tlsgm(SB) is a special linker symbol.
-	// It is the offset from the TLS base pointer to our
-	// thread-local storage for g and m.
-	MOVW	$runtime·tlsgm(SB), R11
-	ADD	R11, R0
-	MOVW	0(R0), g
-	MOVW	4(R0), m
-	RET
-
-// void setmg_gcc(M*, G*); set m and g called from gcc.
-TEXT setmg_gcc<>(SB),NOSPLIT,$0
-	MOVW	R0, m
-	MOVW	R1, g
-	B		runtime·save_gm(SB)
-
-// TODO: share code with memeq?
-TEXT bytes·Equal(SB),NOSPLIT,$0
-	MOVW	a_len+4(FP), R1
-	MOVW	b_len+16(FP), R3
-	
-	CMP	R1, R3		// unequal lengths are not equal
-	B.NE	_notequal
-
-	MOVW	a+0(FP), R0
-	MOVW	b+12(FP), R2
-	ADD	R0, R1		// end
-
-_byteseq_next:
-	CMP	R0, R1
-	B.EQ	_equal		// reached the end
-	MOVBU.P	1(R0), R4
-	MOVBU.P	1(R2), R5
-	CMP	R4, R5
-	B.EQ	_byteseq_next
-
-_notequal:
-	MOVW	$0, R0
-	MOVBU	R0, ret+24(FP)
-	RET
-
-_equal:
-	MOVW	$1, R0
-	MOVBU	R0, ret+24(FP)
-	RET
-
-TEXT bytes·IndexByte(SB),NOSPLIT,$0
-	MOVW	s+0(FP), R0
-	MOVW	s_len+4(FP), R1
-	MOVBU	c+12(FP), R2	// byte to find
-	MOVW	R0, R4		// store base for later
-	ADD	R0, R1		// end 
-
-_loop:
-	CMP	R0, R1
-	B.EQ	_notfound
-	MOVBU.P	1(R0), R3
-	CMP	R2, R3
-	B.NE	_loop
-
-	SUB	$1, R0		// R0 will be one beyond the position we want
-	SUB	R4, R0		// remove base
-	MOVW    R0, ret+16(FP) 
-	RET
-
-_notfound:
-	MOVW	$-1, R0
-	MOVW	R0, ret+16(FP)
-	RET
-
-TEXT strings·IndexByte(SB),NOSPLIT,$0
-	MOVW	s+0(FP), R0
-	MOVW	s_len+4(FP), R1
-	MOVBU	c+8(FP), R2	// byte to find
-	MOVW	R0, R4		// store base for later
-	ADD	R0, R1		// end 
-
-_sib_loop:
-	CMP	R0, R1
-	B.EQ	_sib_notfound
-	MOVBU.P	1(R0), R3
-	CMP	R2, R3
-	B.NE	_sib_loop
-
-	SUB	$1, R0		// R0 will be one beyond the position we want
-	SUB	R4, R0		// remove base
-	MOVW	R0, ret+12(FP) 
-	RET
-
-_sib_notfound:
-	MOVW	$-1, R0
-	MOVW	R0, ret+12(FP)
-	RET
-
-TEXT runtime·timenow(SB), NOSPLIT, $0-0
-	B	time·now(SB)
-
-// A Duff's device for zeroing memory.
-// The compiler jumps to computed addresses within
-// this routine to zero chunks of memory.  Do not
-// change this code without also changing the code
-// in ../../cmd/5g/ggen.c:clearfat.
-// R0: zero
-// R1: ptr to memory to be zeroed
-// R1 is updated as a side effect.
-TEXT runtime·duffzero(SB), NOSPLIT, $0-0
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	MOVW.P	R0, 4(R1)
-	RET
-
-// A Duff's device for copying memory.
-// The compiler jumps to computed addresses within
-// this routine to copy chunks of memory.  Source
-// and destination must not overlap.  Do not
-// change this code without also changing the code
-// in ../../cmd/5g/cgen.c:sgen.
-// R0: scratch space
-// R1: ptr to source memory
-// R2: ptr to destination memory
-// R1 and R2 are updated as a side effect
-TEXT runtime·duffcopy(SB), NOSPLIT, $0-0
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	MOVW.P	4(R1), R0
-	MOVW.P	R0, 4(R2)
-	RET
diff --git a/src/pkg/runtime/atomic_386.c b/src/pkg/runtime/atomic_386.c
deleted file mode 100644
index d7162a1..0000000
--- a/src/pkg/runtime/atomic_386.c
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "runtime.h"
-#include "../../cmd/ld/textflag.h"
-
-#pragma textflag NOSPLIT
-uint32
-runtime·atomicload(uint32 volatile* addr)
-{
-	return *addr;
-}
-
-#pragma textflag NOSPLIT
-void*
-runtime·atomicloadp(void* volatile* addr)
-{
-	return *addr;
-}
-
-#pragma textflag NOSPLIT
-uint64
-runtime·xadd64(uint64 volatile* addr, int64 v)
-{
-	uint64 old;
-
-	do
-		old = *addr;
-	while(!runtime·cas64(addr, old, old+v));
-
-	return old+v;
-}
-
-#pragma textflag NOSPLIT
-uint64
-runtime·xchg64(uint64 volatile* addr, uint64 v)
-{
-	uint64 old;
-
-	do
-		old = *addr;
-	while(!runtime·cas64(addr, old, v));
-
-	return old;
-}
diff --git a/src/pkg/runtime/atomic_amd64x.c b/src/pkg/runtime/atomic_amd64x.c
deleted file mode 100644
index 11b5789..0000000
--- a/src/pkg/runtime/atomic_amd64x.c
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build amd64 amd64p32
-
-#include "runtime.h"
-#include "../../cmd/ld/textflag.h"
-
-#pragma textflag NOSPLIT
-uint32
-runtime·atomicload(uint32 volatile* addr)
-{
-	return *addr;
-}
-
-#pragma textflag NOSPLIT
-uint64
-runtime·atomicload64(uint64 volatile* addr)
-{
-	return *addr;
-}
-
-#pragma textflag NOSPLIT
-void*
-runtime·atomicloadp(void* volatile* addr)
-{
-	return *addr;
-}
diff --git a/src/pkg/runtime/atomic_arm.c b/src/pkg/runtime/atomic_arm.c
deleted file mode 100644
index d914475..0000000
--- a/src/pkg/runtime/atomic_arm.c
+++ /dev/null
@@ -1,169 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "runtime.h"
-#include "arch_GOARCH.h"
-#include "../../cmd/ld/textflag.h"
-
-static struct {
-	Lock l;
-	byte pad[CacheLineSize-sizeof(Lock)];
-} locktab[57];
-
-#define LOCK(addr) (&locktab[((uintptr)(addr)>>3)%nelem(locktab)].l)
-
-// Atomic add and return new value.
-#pragma textflag NOSPLIT
-uint32
-runtime·xadd(uint32 volatile *val, int32 delta)
-{
-	uint32 oval, nval;
-
-	for(;;){
-		oval = *val;
-		nval = oval + delta;
-		if(runtime·cas(val, oval, nval))
-			return nval;
-	}
-}
-
-#pragma textflag NOSPLIT
-uint32
-runtime·xchg(uint32 volatile* addr, uint32 v)
-{
-	uint32 old;
-
-	for(;;) {
-		old = *addr;
-		if(runtime·cas(addr, old, v))
-			return old;
-	}
-}
-
-#pragma textflag NOSPLIT
-void*
-runtime·xchgp(void* volatile* addr, void* v)
-{
-	void *old;
-
-	for(;;) {
-		old = *addr;
-		if(runtime·casp(addr, old, v))
-			return old;
-	}
-}
-
-#pragma textflag NOSPLIT
-void
-runtime·procyield(uint32 cnt)
-{
-	uint32 volatile i;
-
-	for(i = 0; i < cnt; i++) {
-	}
-}
-
-#pragma textflag NOSPLIT
-uint32
-runtime·atomicload(uint32 volatile* addr)
-{
-	return runtime·xadd(addr, 0);
-}
-
-#pragma textflag NOSPLIT
-void*
-runtime·atomicloadp(void* volatile* addr)
-{
-	return (void*)runtime·xadd((uint32 volatile*)addr, 0);
-}
-
-#pragma textflag NOSPLIT
-void
-runtime·atomicstorep(void* volatile* addr, void* v)
-{
-	void *old;
-
-	for(;;) {
-		old = *addr;
-		if(runtime·casp(addr, old, v))
-			return;
-	}
-}
-
-#pragma textflag NOSPLIT
-void
-runtime·atomicstore(uint32 volatile* addr, uint32 v)
-{
-	uint32 old;
-	
-	for(;;) {
-		old = *addr;
-		if(runtime·cas(addr, old, v))
-			return;
-	}
-}
-
-#pragma textflag NOSPLIT
-bool
-runtime·cas64(uint64 volatile *addr, uint64 old, uint64 new)
-{
-	bool res;
-	
-	runtime·lock(LOCK(addr));
-	if(*addr == old) {
-		*addr = new;
-		res = true;
-	} else {
-		res = false;
-	}
-	runtime·unlock(LOCK(addr));
-	return res;
-}
-
-#pragma textflag NOSPLIT
-uint64
-runtime·xadd64(uint64 volatile *addr, int64 delta)
-{
-	uint64 res;
-	
-	runtime·lock(LOCK(addr));
-	res = *addr + delta;
-	*addr = res;
-	runtime·unlock(LOCK(addr));
-	return res;
-}
-
-#pragma textflag NOSPLIT
-uint64
-runtime·xchg64(uint64 volatile *addr, uint64 v)
-{
-	uint64 res;
-
-	runtime·lock(LOCK(addr));
-	res = *addr;
-	*addr = v;
-	runtime·unlock(LOCK(addr));
-	return res;
-}
-
-#pragma textflag NOSPLIT
-uint64
-runtime·atomicload64(uint64 volatile *addr)
-{
-	uint64 res;
-	
-	runtime·lock(LOCK(addr));
-	res = *addr;
-	runtime·unlock(LOCK(addr));
-	return res;
-}
-
-#pragma textflag NOSPLIT
-void
-runtime·atomicstore64(uint64 volatile *addr, uint64 v)
-{
-	runtime·lock(LOCK(addr));
-	*addr = v;
-	runtime·unlock(LOCK(addr));
-}
diff --git a/src/pkg/runtime/callback_windows.c b/src/pkg/runtime/callback_windows.c
deleted file mode 100644
index 285678f..0000000
--- a/src/pkg/runtime/callback_windows.c
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "runtime.h"
-#include "type.h"
-#include "typekind.h"
-#include "defs_GOOS_GOARCH.h"
-#include "os_GOOS.h"
-#include "zasm_GOOS_GOARCH.h"
-
-typedef	struct	Callbacks	Callbacks;
-struct	Callbacks {
-	Lock;
-	WinCallbackContext*	ctxt[cb_max];
-	int32			n;
-};
-
-static	Callbacks	cbs;
-
-WinCallbackContext** runtime·cbctxts; // to simplify access to cbs.ctxt in sys_windows_*.s
-
-// Call back from windows dll into go.
-byte *
-runtime·compilecallback(Eface fn, bool cleanstack)
-{
-	FuncType *ft;
-	Type *t;
-	int32 argsize, i, n;
-	WinCallbackContext *c;
-
-	if(fn.type == nil || fn.type->kind != KindFunc)
-		runtime·panicstring("compilecallback: not a function");
-	ft = (FuncType*)fn.type;
-	if(ft->out.len != 1)
-		runtime·panicstring("compilecallback: function must have one output parameter");
-	if(((Type**)ft->out.array)[0]->size != sizeof(uintptr))
-		runtime·panicstring("compilecallback: output parameter size is wrong");
-	argsize = 0;
-	for(i=0; i<ft->in.len; i++) {
-		t = ((Type**)ft->in.array)[i];
-		if(t->size > sizeof(uintptr))
-			runtime·panicstring("compilecallback: input parameter size is wrong");
-		argsize += sizeof(uintptr);
-	}
-
-	runtime·lock(&cbs);
-	if(runtime·cbctxts == nil)
-		runtime·cbctxts = &(cbs.ctxt[0]);
-	n = cbs.n;
-	for(i=0; i<n; i++) {
-		if(cbs.ctxt[i]->gobody == fn.data && cbs.ctxt[i]->cleanstack == cleanstack) {
-			runtime·unlock(&cbs);
-			// runtime·callbackasm is just a series of CALL instructions
-			// (each is 5 bytes long), and we want callback to arrive at
-			// correspondent call instruction instead of start of
-			// runtime·callbackasm.
-			return (byte*)runtime·callbackasm + i * 5;
-		}
-	}
-	if(n >= cb_max)
-		runtime·throw("too many callback functions");
-	c = runtime·mal(sizeof *c);
-	c->gobody = fn.data;
-	c->argsize = argsize;
-	c->cleanstack = cleanstack;
-	if(cleanstack && argsize!=0)
-		c->restorestack = argsize;
-	else
-		c->restorestack = 0;
-	cbs.ctxt[n] = c;
-	cbs.n++;
-	runtime·unlock(&cbs);
-
-	// as before
-	return (byte*)runtime·callbackasm + n * 5;
-}
diff --git a/src/pkg/runtime/cgo/asm_386.s b/src/pkg/runtime/cgo/asm_386.s
deleted file mode 100644
index ab2f1d1..0000000
--- a/src/pkg/runtime/cgo/asm_386.s
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2009 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../../cmd/ld/textflag.h"
-
-/*
- * void crosscall2(void (*fn)(void*, int32), void*, int32)
- * Save registers and call fn with two arguments.
- */
-TEXT crosscall2(SB),NOSPLIT,$0
-	PUSHL	BP
-	MOVL	SP, BP
-	PUSHL	BX
-	PUSHL	SI
-	PUSHL	DI
-	
-	SUBL	$8, SP
-	MOVL	16(BP), AX
-	MOVL	AX, 4(SP)
-	MOVL	12(BP), AX
-	MOVL	AX, 0(SP)
-	MOVL	8(BP), AX
-	CALL	AX
-	ADDL	$8, SP
-	
-	POPL	DI
-	POPL	SI
-	POPL	BX
-	POPL	BP
-	RET
diff --git a/src/pkg/runtime/cgo/asm_amd64.s b/src/pkg/runtime/cgo/asm_amd64.s
deleted file mode 100644
index 64f719a..0000000
--- a/src/pkg/runtime/cgo/asm_amd64.s
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2009 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../../cmd/ld/textflag.h"
-
-/*
- * void crosscall2(void (*fn)(void*, int32), void*, int32)
- * Save registers and call fn with two arguments.
- */
-TEXT crosscall2(SB),NOSPLIT,$0
-	SUBQ	$0x58, SP	/* keeps stack pointer 32-byte aligned */
-	MOVQ	BX, 0x10(SP)
-	MOVQ	BP, 0x18(SP)
-	MOVQ	R12, 0x20(SP)
-	MOVQ	R13, 0x28(SP)
-	MOVQ	R14, 0x30(SP)
-	MOVQ	R15, 0x38(SP)
-
-#ifdef GOOS_windows
-	// Win64 save RBX, RBP, RDI, RSI, RSP, R12, R13, R14, and R15
-	MOVQ	DI, 0x40(SP)
-	MOVQ	SI, 0x48(SP)
-
-	MOVQ	DX, 0(SP)	/* arg */
-	MOVQ	R8, 8(SP)	/* argsize (includes padding) */
-	
-	CALL	CX	/* fn */
-	
-	MOVQ	0x40(SP), DI
-	MOVQ	0x48(SP), SI
-#else
-	MOVQ	SI, 0(SP)	/* arg */
-	MOVQ	DX, 8(SP)	/* argsize (includes padding) */
-
-	CALL	DI	/* fn */
-#endif
-
-	MOVQ	0x10(SP), BX
-	MOVQ	0x18(SP), BP
-	MOVQ	0x20(SP), R12
-	MOVQ	0x28(SP), R13
-	MOVQ	0x30(SP), R14
-	MOVQ	0x38(SP), R15
-	
-	ADDQ	$0x58, SP
-	RET
diff --git a/src/pkg/runtime/cgo/asm_arm.s b/src/pkg/runtime/cgo/asm_arm.s
deleted file mode 100644
index 850b1c6..0000000
--- a/src/pkg/runtime/cgo/asm_arm.s
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2012 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../../cmd/ld/textflag.h"
-
-/*
- * void crosscall2(void (*fn)(void*, int32), void*, int32)
- * Save registers and call fn with two arguments.
- */
-TEXT crosscall2(SB),NOSPLIT,$-4
-	/* 
-	 * We still need to save all callee save register as before, and then
-	 *  push 2 args for fn (R1 and R2).
-	 * Also note that at procedure entry in 5c/5g world, 4(R13) will be the
-	 *  first arg, so we must push another dummy reg (R0) for 0(R13).
-	 *  Additionally, runtime·load_gm will clobber R0, so we need to save R0
-	 *  nevertheless.
-	 */
-	MOVM.WP	[R0, R1, R2, R4, R5, R6, R7, R8, m, g, R11, R12, R14], (R13)
-	BL	runtime·load_gm(SB)
-	MOVW	PC, R14
-	MOVW	0(R13), PC
-	MOVM.IAW	(R13), [R0, R1, R2, R4, R5, R6, R7, R8, m, g, R11, R12, PC]
diff --git a/src/pkg/runtime/cgo/asm_nacl_amd64p32.s b/src/pkg/runtime/cgo/asm_nacl_amd64p32.s
deleted file mode 100644
index 377cf72..0000000
--- a/src/pkg/runtime/cgo/asm_nacl_amd64p32.s
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2013 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../../cmd/ld/textflag.h"
-
-/*
- * void crosscall2(void (*fn)(void*, int32), void*, int32)
- * Save registers and call fn with two arguments.
- */
-TEXT crosscall2(SB),NOSPLIT,$0
-	INT $3
-	RET
diff --git a/src/pkg/runtime/cgo/callbacks.c b/src/pkg/runtime/cgo/callbacks.c
deleted file mode 100644
index e91c8bf..0000000
--- a/src/pkg/runtime/cgo/callbacks.c
+++ /dev/null
@@ -1,102 +0,0 @@
-// Copyright 2011 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../runtime.h"
-#include "../cgocall.h"
-#include "../../../cmd/ld/textflag.h"
-
-// These utility functions are available to be called from code
-// compiled with gcc via crosscall2.
-
-// The declaration of crosscall2 is:
-//   void crosscall2(void (*fn)(void *, int), void *, int);
-// 
-// We need to export the symbol crosscall2 in order to support
-// callbacks from shared libraries. This applies regardless of
-// linking mode.
-#pragma cgo_export_static crosscall2
-#pragma cgo_export_dynamic crosscall2
-
-// Allocate memory.  This allocates the requested number of bytes in
-// memory controlled by the Go runtime.  The allocated memory will be
-// zeroed.  You are responsible for ensuring that the Go garbage
-// collector can see a pointer to the allocated memory for as long as
-// it is valid, e.g., by storing a pointer in a local variable in your
-// C function, or in memory allocated by the Go runtime.  If the only
-// pointers are in a C global variable or in memory allocated via
-// malloc, then the Go garbage collector may collect the memory.
-
-// Call like this in code compiled with gcc:
-//   struct { size_t len; void *ret; } a;
-//   a.len = /* number of bytes to allocate */;
-//   crosscall2(_cgo_allocate, &a, sizeof a);
-//   /* Here a.ret is a pointer to the allocated memory.  */
-
-static void
-_cgo_allocate_internal(uintptr len, byte *ret)
-{
-	CgoMal *c;
-
-	ret = runtime·mal(len);
-	c = runtime·mal(sizeof(*c));
-	c->next = m->cgomal;
-	c->alloc = ret;
-	m->cgomal = c;
-	FLUSH(&ret);
-}
-
-#pragma cgo_export_static _cgo_allocate
-#pragma cgo_export_dynamic _cgo_allocate
-#pragma textflag NOSPLIT
-void
-_cgo_allocate(void *a, int32 n)
-{
-	runtime·cgocallback((void(*)(void))_cgo_allocate_internal, a, n);
-}
-
-// Panic.  The argument is converted into a Go string.
-
-// Call like this in code compiled with gcc:
-//   struct { const char *p; } a;
-//   a.p = /* string to pass to panic */;
-//   crosscall2(_cgo_panic, &a, sizeof a);
-//   /* The function call will not return.  */
-
-extern void ·cgoStringToEface(String, Eface*);
-
-static void
-_cgo_panic_internal(byte *p)
-{
-	String s;
-	Eface err;
-
-	s = runtime·gostring(p);
-	·cgoStringToEface(s, &err);
-	runtime·panic(err);
-}
-
-#pragma cgo_export_static _cgo_panic
-#pragma cgo_export_dynamic _cgo_panic
-#pragma textflag NOSPLIT
-void
-_cgo_panic(void *a, int32 n)
-{
-	runtime·cgocallback((void(*)(void))_cgo_panic_internal, a, n);
-}
-
-#pragma cgo_import_static x_cgo_init
-extern void x_cgo_init(G*);
-void (*_cgo_init)(G*) = x_cgo_init;
-
-#pragma cgo_import_static x_cgo_malloc
-extern void x_cgo_malloc(void*);
-void (*_cgo_malloc)(void*) = x_cgo_malloc;
-
-#pragma cgo_import_static x_cgo_free
-extern void x_cgo_free(void*);
-void (*_cgo_free)(void*) = x_cgo_free;
-
-#pragma cgo_import_static x_cgo_thread_start
-extern void x_cgo_thread_start(void*);
-void (*_cgo_thread_start)(void*) = x_cgo_thread_start;
diff --git a/src/pkg/runtime/cgo/cgo.go b/src/pkg/runtime/cgo/cgo.go
deleted file mode 100644
index 258b6fb..0000000
--- a/src/pkg/runtime/cgo/cgo.go
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2010 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-/*
-Package cgo contains runtime support for code generated
-by the cgo tool.  See the documentation for the cgo command
-for details on using cgo.
-*/
-package cgo
-
-/*
-
-#cgo darwin LDFLAGS: -lpthread
-#cgo dragonfly LDFLAGS: -lpthread
-#cgo freebsd LDFLAGS: -lpthread
-#cgo linux LDFLAGS: -lpthread
-#cgo netbsd LDFLAGS: -lpthread
-#cgo openbsd LDFLAGS: -lpthread
-#cgo windows LDFLAGS: -lm -mthreads
-
-#cgo CFLAGS: -Wall -Werror
-
-*/
-import "C"
-
-// Supports _cgo_panic by converting a string constant to an empty
-// interface.
-
-func cgoStringToEface(s string, ret *interface{}) {
-	*ret = s
-}
diff --git a/src/pkg/runtime/cgo/dragonfly.c b/src/pkg/runtime/cgo/dragonfly.c
deleted file mode 100644
index acf53e2..0000000
--- a/src/pkg/runtime/cgo/dragonfly.c
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2010 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Supply environ and __progname, because we don't
-// link against the standard DragonFly crt0.o and the
-// libc dynamic library needs them.
-
-char *environ[1];
-char *__progname;
-
-#pragma dynexport environ environ
-#pragma dynexport __progname __progname
diff --git a/src/pkg/runtime/cgo/freebsd.c b/src/pkg/runtime/cgo/freebsd.c
deleted file mode 100644
index dfcfa3a..0000000
--- a/src/pkg/runtime/cgo/freebsd.c
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2010 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Supply environ and __progname, because we don't
-// link against the standard FreeBSD crt0.o and the
-// libc dynamic library needs them.
-
-char *environ[1];
-char *__progname;
-
-#pragma dynexport environ environ
-#pragma dynexport __progname __progname
diff --git a/src/pkg/runtime/cgo/gcc_arm.S b/src/pkg/runtime/cgo/gcc_arm.S
deleted file mode 100644
index 17e98d9..0000000
--- a/src/pkg/runtime/cgo/gcc_arm.S
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2012 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-/*
- * Apple still insists on underscore prefixes for C function names.
- */
-#if defined(__APPLE__)
-#define EXT(s) _##s
-#else
-#define EXT(s) s
-#endif
-
-/*
- * Because the assembler might target an earlier revision of the ISA
- * by default, we must explicitly specify the ISA revision to ensure
- * BLX is recognized as a valid instruction.
- */	
-.arch armv5t
-
-/*
- * void crosscall_arm2(void (*fn)(void), void (*setmg_gcc)(void *m, void *g), void *m, void *g)
- *
- * Calling into the 5c tool chain, where all registers are caller save.
- * Called from standard ARM EABI, where r4-r11 are callee-save, so they
- * must be saved explicitly.
- */
-.globl EXT(crosscall_arm2)
-EXT(crosscall_arm2):
-	push {r4, r5, r6, r7, r8, r9, r10, r11, ip, lr}
-	mov r4, r0
-	mov r5, r1
-	mov r0, r2
-	mov r1, r3
-	blx r5 // setmg(m, g) 
-	blx r4 // fn() 
-	pop {r4, r5, r6, r7, r8, r9, r10, r11, ip, pc}
-
-.globl EXT(__stack_chk_fail_local)
-EXT(__stack_chk_fail_local):
-1:
-	b 1b
-
-#ifdef __ELF__
-.section .note.GNU-stack,"",%progbits
-#endif
diff --git a/src/pkg/runtime/cgo/gcc_darwin_386.c b/src/pkg/runtime/cgo/gcc_darwin_386.c
deleted file mode 100644
index ad9fb5a..0000000
--- a/src/pkg/runtime/cgo/gcc_darwin_386.c
+++ /dev/null
@@ -1,165 +0,0 @@
-// Copyright 2009 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include <string.h> /* for strerror */
-#include <pthread.h>
-#include <signal.h>
-#include "libcgo.h"
-
-static void* threadentry(void*);
-static pthread_key_t k1, k2;
-
-#define magic1 (0x23581321U)
-
-static void
-inittls(void)
-{
-	uint32 x, y;
-	pthread_key_t tofree[128], k;
-	int i, ntofree;
-	int havek1, havek2;
-
-	/*
-	 * Allocate thread-local storage slots for m, g.
-	 * The key numbers start at 0x100, and we expect to be
-	 * one of the early calls to pthread_key_create, so we
-	 * should be able to get pretty low numbers.
-	 *
-	 * In Darwin/386 pthreads, %gs points at the thread
-	 * structure, and each key is an index into the thread-local
-	 * storage array that begins at offset 0x48 within in that structure.
-	 * It may happen that we are not quite the first function to try
-	 * to allocate thread-local storage keys, so instead of depending
-	 * on getting 0x100 and 0x101, we try for 0x108 and 0x109,
-	 * allocating keys until we get the ones we want and then freeing
-	 * the ones we didn't want.
-	 *
-	 * Thus the final offsets to use in %gs references are
-	 * 0x48+4*0x108 = 0x468 and 0x48+4*0x109 = 0x46c.
-	 *
-	 * The linker and runtime hard-code these constant offsets
-	 * from %gs where we expect to find m and g.
-	 * Known to ../../../cmd/8l/obj.c:/468
-	 * and to ../sys_darwin_386.s:/468
-	 *
-	 * This is truly disgusting and a bit fragile, but taking care
-	 * of it here protects the rest of the system from damage.
-	 * The alternative would be to use a global variable that
-	 * held the offset and refer to that variable each time we
-	 * need a %gs variable (m or g).  That approach would
-	 * require an extra instruction and memory reference in
-	 * every stack growth prolog and would also require
-	 * rewriting the code that 8c generates for extern registers.
-	 *
-	 * Things get more disgusting on OS X 10.7 Lion.
-	 * The 0x48 base mentioned above is the offset of the tsd
-	 * array within the per-thread structure on Leopard and Snow Leopard.
-	 * On Lion, the base moved a little, so while the math above
-	 * still applies, the base is different.  Thus, we cannot
-	 * look for specific key values if we want to build binaries
-	 * that run on both systems.  Instead, forget about the
-	 * specific key values and just allocate and initialize per-thread
-	 * storage until we find a key that writes to the memory location
-	 * we want.  Then keep that key.
-	 */
-	havek1 = 0;
-	havek2 = 0;
-	ntofree = 0;
-	while(!havek1 || !havek2) {
-		if(pthread_key_create(&k, nil) < 0) {
-			fprintf(stderr, "runtime/cgo: pthread_key_create failed\n");
-			abort();
-		}
-		pthread_setspecific(k, (void*)magic1);
-		asm volatile("movl %%gs:0x468, %0" : "=r"(x));
-		asm volatile("movl %%gs:0x46c, %0" : "=r"(y));
-		if(x == magic1) {
-			havek1 = 1;
-			k1 = k;
-		} else if(y == magic1) {
-			havek2 = 1;
-			k2 = k;
-		} else {
-			if(ntofree >= nelem(tofree)) {
-				fprintf(stderr, "runtime/cgo: could not obtain pthread_keys\n");
-				fprintf(stderr, "\ttried");
-				for(i=0; i<ntofree; i++)
-					fprintf(stderr, " %#x", (unsigned)tofree[i]);
-				fprintf(stderr, "\n");
-				abort();
-			}
-			tofree[ntofree++] = k;
-		}
-		pthread_setspecific(k, 0);
-	}
-
-	/*
-	 * We got the keys we wanted.  Free the others.
-	 */
-	for(i=0; i<ntofree; i++)
-		pthread_key_delete(tofree[i]);
-}
-
-void
-x_cgo_init(G *g)
-{
-	pthread_attr_t attr;
-	size_t size;
-
-	pthread_attr_init(&attr);
-	pthread_attr_getstacksize(&attr, &size);
-	g->stackguard = (uintptr)&attr - size + 4096;
-	pthread_attr_destroy(&attr);
-
-	inittls();
-}
-
-
-void
-_cgo_sys_thread_start(ThreadStart *ts)
-{
-	pthread_attr_t attr;
-	sigset_t ign, oset;
-	pthread_t p;
-	size_t size;
-	int err;
-
-	sigfillset(&ign);
-	pthread_sigmask(SIG_SETMASK, &ign, &oset);
-
-	pthread_attr_init(&attr);
-	pthread_attr_getstacksize(&attr, &size);
-	ts->g->stackguard = size;
-	err = pthread_create(&p, &attr, threadentry, ts);
-
-	pthread_sigmask(SIG_SETMASK, &oset, nil);
-
-	if (err != 0) {
-		fprintf(stderr, "runtime/cgo: pthread_create failed: %s\n", strerror(err));
-		abort();
-	}
-}
-
-static void*
-threadentry(void *v)
-{
-	ThreadStart ts;
-
-	ts = *(ThreadStart*)v;
-	free(v);
-
-	ts.g->stackbase = (uintptr)&ts;
-
-	/*
-	 * _cgo_sys_thread_start set stackguard to stack size;
-	 * change to actual guard pointer.
-	 */
-	ts.g->stackguard = (uintptr)&ts - ts.g->stackguard + 4096;
-
-	pthread_setspecific(k1, (void*)ts.g);
-	pthread_setspecific(k2, (void*)ts.m);
-
-	crosscall_386(ts.fn);
-	return nil;
-}
diff --git a/src/pkg/runtime/cgo/gcc_darwin_amd64.c b/src/pkg/runtime/cgo/gcc_darwin_amd64.c
deleted file mode 100644
index 65d3816..0000000
--- a/src/pkg/runtime/cgo/gcc_darwin_amd64.c
+++ /dev/null
@@ -1,135 +0,0 @@
-// Copyright 2009 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include <string.h> /* for strerror */
-#include <pthread.h>
-#include <signal.h>
-#include "libcgo.h"
-
-static void* threadentry(void*);
-static pthread_key_t k1, k2;
-
-#define magic1 (0x23581321345589ULL)
-
-static void
-inittls(void)
-{
-	uint64 x, y;
-	pthread_key_t tofree[128], k;
-	int i, ntofree;
-	int havek1, havek2;
-
-	/*
-	 * Same logic, code as darwin_386.c:/inittls, except that words
-	 * are 8 bytes long now, and the thread-local storage starts
-	 * at 0x60 on Leopard / Snow Leopard. So the offsets are
-	 * 0x60+8*0x108 = 0x8a0 and 0x60+8*0x109 = 0x8a8.
-	 *
-	 * The linker and runtime hard-code these constant offsets
-	 * from %gs where we expect to find m and g.
-	 * Known to ../../../cmd/6l/obj.c:/8a0
-	 * and to ../sys_darwin_amd64.s:/8a0
-	 *
-	 * As disgusting as on the 386; same justification.
-	 */
-	havek1 = 0;
-	havek2 = 0;
-	ntofree = 0;
-	while(!havek1 || !havek2) {
-		if(pthread_key_create(&k, nil) < 0) {
-			fprintf(stderr, "runtime/cgo: pthread_key_create failed\n");
-			abort();
-		}
-		pthread_setspecific(k, (void*)magic1);
-		asm volatile("movq %%gs:0x8a0, %0" : "=r"(x));
-		asm volatile("movq %%gs:0x8a8, %0" : "=r"(y));
-		if(x == magic1) {
-			havek1 = 1;
-			k1 = k;
-		} else if(y == magic1) {
-			havek2 = 1;
-			k2 = k;
-		} else {
-			if(ntofree >= nelem(tofree)) {
-				fprintf(stderr, "runtime/cgo: could not obtain pthread_keys\n");
-				fprintf(stderr, "\ttried");
-				for(i=0; i<ntofree; i++)
-					fprintf(stderr, " %#x", (unsigned)tofree[i]);
-				fprintf(stderr, "\n");
-				abort();
-			}
-			tofree[ntofree++] = k;
-		}
-		pthread_setspecific(k, 0);
-	}
-
-	/*
-	 * We got the keys we wanted.  Free the others.
-	 */
-	for(i=0; i<ntofree; i++)
-		pthread_key_delete(tofree[i]);
-}
-
-void
-x_cgo_init(G *g)
-{
-	pthread_attr_t attr;
-	size_t size;
-
-	pthread_attr_init(&attr);
-	pthread_attr_getstacksize(&attr, &size);
-	g->stackguard = (uintptr)&attr - size + 4096;
-	pthread_attr_destroy(&attr);
-
-	inittls();
-}
-
-
-void
-_cgo_sys_thread_start(ThreadStart *ts)
-{
-	pthread_attr_t attr;
-	sigset_t ign, oset;
-	pthread_t p;
-	size_t size;
-	int err;
-
-	sigfillset(&ign);
-	pthread_sigmask(SIG_SETMASK, &ign, &oset);
-
-	pthread_attr_init(&attr);
-	pthread_attr_getstacksize(&attr, &size);
-	ts->g->stackguard = size;
-	err = pthread_create(&p, &attr, threadentry, ts);
-
-	pthread_sigmask(SIG_SETMASK, &oset, nil);
-
-	if (err != 0) {
-		fprintf(stderr, "runtime/cgo: pthread_create failed: %s\n", strerror(err));
-		abort();
-	}
-}
-
-static void*
-threadentry(void *v)
-{
-	ThreadStart ts;
-
-	ts = *(ThreadStart*)v;
-	free(v);
-
-	ts.g->stackbase = (uintptr)&ts;
-
-	/*
-	 * _cgo_sys_thread_start set stackguard to stack size;
-	 * change to actual guard pointer.
-	 */
-	ts.g->stackguard = (uintptr)&ts - ts.g->stackguard + 4096;
-
-	pthread_setspecific(k1, (void*)ts.g);
-	pthread_setspecific(k2, (void*)ts.m);
-
-	crosscall_amd64(ts.fn);
-	return nil;
-}
diff --git a/src/pkg/runtime/cgo/gcc_dragonfly_386.c b/src/pkg/runtime/cgo/gcc_dragonfly_386.c
deleted file mode 100644
index 695c166..0000000
--- a/src/pkg/runtime/cgo/gcc_dragonfly_386.c
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright 2009 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include <sys/types.h>
-#include <sys/signalvar.h>
-#include <pthread.h>
-#include <signal.h>
-#include <string.h>
-#include "libcgo.h"
-
-static void* threadentry(void*);
-static void (*setmg_gcc)(void*, void*);
-
-void
-x_cgo_init(G *g, void (*setmg)(void*, void*))
-{
-	pthread_attr_t attr;
-	size_t size;
-
-	setmg_gcc = setmg;
-	pthread_attr_init(&attr);
-	pthread_attr_getstacksize(&attr, &size);
-	g->stackguard = (uintptr)&attr - size + 4096;
-	pthread_attr_destroy(&attr);
-}
-
-
-void
-_cgo_sys_thread_start(ThreadStart *ts)
-{
-	pthread_attr_t attr;
-	sigset_t ign, oset;
-	pthread_t p;
-	size_t size;
-	int err;
-
-	SIGFILLSET(ign);
-	pthread_sigmask(SIG_SETMASK, &ign, &oset);
-
-	pthread_attr_init(&attr);
-	pthread_attr_getstacksize(&attr, &size);
-	ts->g->stackguard = size;
-	err = pthread_create(&p, &attr, threadentry, ts);
-
-	pthread_sigmask(SIG_SETMASK, &oset, nil);
-
-	if (err != 0) {
-		fprintf(stderr, "runtime/cgo: pthread_create failed: %s\n", strerror(err));
-		abort();
-	}
-}
-
-static void*
-threadentry(void *v)
-{
-	ThreadStart ts;
-
-	ts = *(ThreadStart*)v;
-	free(v);
-
-	ts.g->stackbase = (uintptr)&ts;
-
-	/*
-	 * _cgo_sys_thread_start set stackguard to stack size;
-	 * change to actual guard pointer.
-	 */
-	ts.g->stackguard = (uintptr)&ts - ts.g->stackguard + 4096;
-
-	/*
-	 * Set specific keys.
-	 */
-	setmg_gcc((void*)ts.m, (void*)ts.g);
-
-	crosscall_386(ts.fn);
-	return nil;
-}
diff --git a/src/pkg/runtime/cgo/gcc_dragonfly_amd64.c b/src/pkg/runtime/cgo/gcc_dragonfly_amd64.c
deleted file mode 100644
index a46c121..0000000
--- a/src/pkg/runtime/cgo/gcc_dragonfly_amd64.c
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright 2009 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include <sys/types.h>
-#include <sys/signalvar.h>
-#include <pthread.h>
-#include <signal.h>
-#include <string.h>
-#include "libcgo.h"
-
-static void* threadentry(void*);
-static void (*setmg_gcc)(void*, void*);
-
-void
-x_cgo_init(G *g, void (*setmg)(void*, void*))
-{
-	pthread_attr_t attr;
-	size_t size;
-
-	setmg_gcc = setmg;
-	pthread_attr_init(&attr);
-	pthread_attr_getstacksize(&attr, &size);
-	g->stackguard = (uintptr)&attr - size + 4096;
-	pthread_attr_destroy(&attr);
-}
-
-void
-_cgo_sys_thread_start(ThreadStart *ts)
-{
-	pthread_attr_t attr;
-	sigset_t ign, oset;
-	pthread_t p;
-	size_t size;
-	int err;
-
-	SIGFILLSET(ign);
-	pthread_sigmask(SIG_SETMASK, &ign, &oset);
-
-	pthread_attr_init(&attr);
-	pthread_attr_getstacksize(&attr, &size);
-
-	ts->g->stackguard = size;
-	err = pthread_create(&p, &attr, threadentry, ts);
-
-	pthread_sigmask(SIG_SETMASK, &oset, nil);
-
-	if (err != 0) {
-		fprintf(stderr, "runtime/cgo: pthread_create failed: %s\n", strerror(err));
-		abort();
-	}
-}
-
-static void*
-threadentry(void *v)
-{
-	ThreadStart ts;
-
-	ts = *(ThreadStart*)v;
-	free(v);
-
-	ts.g->stackbase = (uintptr)&ts;
-
-	/*
-	 * _cgo_sys_thread_start set stackguard to stack size;
-	 * change to actual guard pointer.
-	 */
-	ts.g->stackguard = (uintptr)&ts - ts.g->stackguard + 4096;
-
-	/*
-	 * Set specific keys.
-	 */
-	setmg_gcc((void*)ts.m, (void*)ts.g);
-
-	crosscall_amd64(ts.fn);
-	return nil;
-}
diff --git a/src/pkg/runtime/cgo/gcc_freebsd_386.c b/src/pkg/runtime/cgo/gcc_freebsd_386.c
deleted file mode 100644
index 695c166..0000000
--- a/src/pkg/runtime/cgo/gcc_freebsd_386.c
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright 2009 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include <sys/types.h>
-#include <sys/signalvar.h>
-#include <pthread.h>
-#include <signal.h>
-#include <string.h>
-#include "libcgo.h"
-
-static void* threadentry(void*);
-static void (*setmg_gcc)(void*, void*);
-
-void
-x_cgo_init(G *g, void (*setmg)(void*, void*))
-{
-	pthread_attr_t attr;
-	size_t size;
-
-	setmg_gcc = setmg;
-	pthread_attr_init(&attr);
-	pthread_attr_getstacksize(&attr, &size);
-	g->stackguard = (uintptr)&attr - size + 4096;
-	pthread_attr_destroy(&attr);
-}
-
-
-void
-_cgo_sys_thread_start(ThreadStart *ts)
-{
-	pthread_attr_t attr;
-	sigset_t ign, oset;
-	pthread_t p;
-	size_t size;
-	int err;
-
-	SIGFILLSET(ign);
-	pthread_sigmask(SIG_SETMASK, &ign, &oset);
-
-	pthread_attr_init(&attr);
-	pthread_attr_getstacksize(&attr, &size);
-	ts->g->stackguard = size;
-	err = pthread_create(&p, &attr, threadentry, ts);
-
-	pthread_sigmask(SIG_SETMASK, &oset, nil);
-
-	if (err != 0) {
-		fprintf(stderr, "runtime/cgo: pthread_create failed: %s\n", strerror(err));
-		abort();
-	}
-}
-
-static void*
-threadentry(void *v)
-{
-	ThreadStart ts;
-
-	ts = *(ThreadStart*)v;
-	free(v);
-
-	ts.g->stackbase = (uintptr)&ts;
-
-	/*
-	 * _cgo_sys_thread_start set stackguard to stack size;
-	 * change to actual guard pointer.
-	 */
-	ts.g->stackguard = (uintptr)&ts - ts.g->stackguard + 4096;
-
-	/*
-	 * Set specific keys.
-	 */
-	setmg_gcc((void*)ts.m, (void*)ts.g);
-
-	crosscall_386(ts.fn);
-	return nil;
-}
diff --git a/src/pkg/runtime/cgo/gcc_freebsd_amd64.c b/src/pkg/runtime/cgo/gcc_freebsd_amd64.c
deleted file mode 100644
index a46c121..0000000
--- a/src/pkg/runtime/cgo/gcc_freebsd_amd64.c
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright 2009 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include <sys/types.h>
-#include <sys/signalvar.h>
-#include <pthread.h>
-#include <signal.h>
-#include <string.h>
-#include "libcgo.h"
-
-static void* threadentry(void*);
-static void (*setmg_gcc)(void*, void*);
-
-void
-x_cgo_init(G *g, void (*setmg)(void*, void*))
-{
-	pthread_attr_t attr;
-	size_t size;
-
-	setmg_gcc = setmg;
-	pthread_attr_init(&attr);
-	pthread_attr_getstacksize(&attr, &size);
-	g->stackguard = (uintptr)&attr - size + 4096;
-	pthread_attr_destroy(&attr);
-}
-
-void
-_cgo_sys_thread_start(ThreadStart *ts)
-{
-	pthread_attr_t attr;
-	sigset_t ign, oset;
-	pthread_t p;
-	size_t size;
-	int err;
-
-	SIGFILLSET(ign);
-	pthread_sigmask(SIG_SETMASK, &ign, &oset);
-
-	pthread_attr_init(&attr);
-	pthread_attr_getstacksize(&attr, &size);
-
-	ts->g->stackguard = size;
-	err = pthread_create(&p, &attr, threadentry, ts);
-
-	pthread_sigmask(SIG_SETMASK, &oset, nil);
-
-	if (err != 0) {
-		fprintf(stderr, "runtime/cgo: pthread_create failed: %s\n", strerror(err));
-		abort();
-	}
-}
-
-static void*
-threadentry(void *v)
-{
-	ThreadStart ts;
-
-	ts = *(ThreadStart*)v;
-	free(v);
-
-	ts.g->stackbase = (uintptr)&ts;
-
-	/*
-	 * _cgo_sys_thread_start set stackguard to stack size;
-	 * change to actual guard pointer.
-	 */
-	ts.g->stackguard = (uintptr)&ts - ts.g->stackguard + 4096;
-
-	/*
-	 * Set specific keys.
-	 */
-	setmg_gcc((void*)ts.m, (void*)ts.g);
-
-	crosscall_amd64(ts.fn);
-	return nil;
-}
diff --git a/src/pkg/runtime/cgo/gcc_freebsd_arm.c b/src/pkg/runtime/cgo/gcc_freebsd_arm.c
deleted file mode 100644
index 6175e1d..0000000
--- a/src/pkg/runtime/cgo/gcc_freebsd_arm.c
+++ /dev/null
@@ -1,89 +0,0 @@
-// Copyright 2012 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include <sys/types.h>
-#include <machine/sysarch.h>
-#include <sys/signalvar.h>
-#include <pthread.h>
-#include <signal.h>
-#include <string.h>
-#include "libcgo.h"
-
-#ifdef ARM_TP_ADDRESS
-// ARM_TP_ADDRESS is (ARM_VECTORS_HIGH + 0x1000) or 0xffff1000
-// and is known to runtime.read_tls_fallback. Verify it with
-// cpp.
-#if ARM_TP_ADDRESS != 0xffff1000
-#error Wrong ARM_TP_ADDRESS!
-#endif
-#endif
-
-static void *threadentry(void*);
-
-static void (*setmg_gcc)(void*, void*);
-
-void
-x_cgo_init(G *g, void (*setmg)(void*, void*))
-{
-	pthread_attr_t attr;
-	size_t size;
-
-	setmg_gcc = setmg;
-	pthread_attr_init(&attr);
-	pthread_attr_getstacksize(&attr, &size);
-	g->stackguard = (uintptr)&attr - size + 4096;
-	pthread_attr_destroy(&attr);
-}
-
-
-void
-_cgo_sys_thread_start(ThreadStart *ts)
-{
-	pthread_attr_t attr;
-	sigset_t ign, oset;
-	pthread_t p;
-	size_t size;
-	int err;
-
-	SIGFILLSET(ign);
-	pthread_sigmask(SIG_SETMASK, &ign, &oset);
-
-	// Not sure why the memset is necessary here,
-	// but without it, we get a bogus stack size
-	// out of pthread_attr_getstacksize.  C'est la Linux.
-	memset(&attr, 0, sizeof attr);
-	pthread_attr_init(&attr);
-	size = 0;
-	pthread_attr_getstacksize(&attr, &size);
-	ts->g->stackguard = size;
-	err = pthread_create(&p, &attr, threadentry, ts);
-
-	pthread_sigmask(SIG_SETMASK, &oset, nil);
-
-	if (err != 0) {
-		fprintf(stderr, "runtime/cgo: pthread_create failed: %s\n", strerror(err));
-		abort();
-	}
-}
-
-extern void crosscall_arm2(void (*fn)(void), void (*setmg_gcc)(void*, void*), void *g, void *m);
-static void*
-threadentry(void *v)
-{
-	ThreadStart ts;
-
-	ts = *(ThreadStart*)v;
-	free(v);
-
-	ts.g->stackbase = (uintptr)&ts;
-
-	/*
-	 * _cgo_sys_thread_start set stackguard to stack size;
-	 * change to actual guard pointer.
-	 */
-	ts.g->stackguard = (uintptr)&ts - ts.g->stackguard + 4096 * 2;
-
-	crosscall_arm2(ts.fn, setmg_gcc, (void*)ts.m, (void*)ts.g);
-	return nil;
-}
diff --git a/src/pkg/runtime/cgo/gcc_linux_386.c b/src/pkg/runtime/cgo/gcc_linux_386.c
deleted file mode 100644
index 0a46c9b..0000000
--- a/src/pkg/runtime/cgo/gcc_linux_386.c
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright 2009 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include <pthread.h>
-#include <string.h>
-#include <signal.h>
-#include "libcgo.h"
-
-static void *threadentry(void*);
-static void (*setmg_gcc)(void*, void*);
-
-void
-x_cgo_init(G *g, void (*setmg)(void*, void*))
-{
-	pthread_attr_t attr;
-	size_t size;
-
-	setmg_gcc = setmg;
-	pthread_attr_init(&attr);
-	pthread_attr_getstacksize(&attr, &size);
-	g->stackguard = (uintptr)&attr - size + 4096;
-	pthread_attr_destroy(&attr);
-}
-
-
-void
-_cgo_sys_thread_start(ThreadStart *ts)
-{
-	pthread_attr_t attr;
-	sigset_t ign, oset;
-	pthread_t p;
-	size_t size;
-	int err;
-
-	sigfillset(&ign);
-	pthread_sigmask(SIG_SETMASK, &ign, &oset);
-
-	// Not sure why the memset is necessary here,
-	// but without it, we get a bogus stack size
-	// out of pthread_attr_getstacksize.  C'est la Linux.
-	memset(&attr, 0, sizeof attr);
-	pthread_attr_init(&attr);
-	size = 0;
-	pthread_attr_getstacksize(&attr, &size);
-	ts->g->stackguard = size;
-	err = pthread_create(&p, &attr, threadentry, ts);
-
-	pthread_sigmask(SIG_SETMASK, &oset, nil);
-
-	if (err != 0) {
-		fprintf(stderr, "runtime/cgo: pthread_create failed: %s\n", strerror(err));
-		abort();
-	}
-}
-
-static void*
-threadentry(void *v)
-{
-	ThreadStart ts;
-
-	ts = *(ThreadStart*)v;
-	free(v);
-
-	ts.g->stackbase = (uintptr)&ts;
-
-	/*
-	 * _cgo_sys_thread_start set stackguard to stack size;
-	 * change to actual guard pointer.
-	 */
-	ts.g->stackguard = (uintptr)&ts - ts.g->stackguard + 4096;
-
-	/*
-	 * Set specific keys.
-	 */
-	setmg_gcc((void*)ts.m, (void*)ts.g);
-
-	crosscall_386(ts.fn);
-	return nil;
-}
diff --git a/src/pkg/runtime/cgo/gcc_linux_amd64.c b/src/pkg/runtime/cgo/gcc_linux_amd64.c
deleted file mode 100644
index c530183..0000000
--- a/src/pkg/runtime/cgo/gcc_linux_amd64.c
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright 2009 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include <pthread.h>
-#include <string.h> // strerror
-#include <signal.h>
-#include "libcgo.h"
-
-static void* threadentry(void*);
-static void (*setmg_gcc)(void*, void*);
-
-void
-x_cgo_init(G* g, void (*setmg)(void*, void*))
-{
-	pthread_attr_t attr;
-	size_t size;
-
-	setmg_gcc = setmg;
-	pthread_attr_init(&attr);
-	pthread_attr_getstacksize(&attr, &size);
-	g->stackguard = (uintptr)&attr - size + 4096;
-	pthread_attr_destroy(&attr);
-}
-
-
-void
-_cgo_sys_thread_start(ThreadStart *ts)
-{
-	pthread_attr_t attr;
-	sigset_t ign, oset;
-	pthread_t p;
-	size_t size;
-	int err;
-
-	sigfillset(&ign);
-	pthread_sigmask(SIG_SETMASK, &ign, &oset);
-
-	pthread_attr_init(&attr);
-	pthread_attr_getstacksize(&attr, &size);
-	ts->g->stackguard = size;
-	err = pthread_create(&p, &attr, threadentry, ts);
-
-	pthread_sigmask(SIG_SETMASK, &oset, nil);
-
-	if (err != 0) {
-		fprintf(stderr, "runtime/cgo: pthread_create failed: %s\n", strerror(err));
-		abort();
-	}
-}
-
-static void*
-threadentry(void *v)
-{
-	ThreadStart ts;
-
-	ts = *(ThreadStart*)v;
-	free(v);
-
-	ts.g->stackbase = (uintptr)&ts;
-
-	/*
-	 * _cgo_sys_thread_start set stackguard to stack size;
-	 * change to actual guard pointer.
-	 */
-	ts.g->stackguard = (uintptr)&ts - ts.g->stackguard + 4096;
-
-	/*
-	 * Set specific keys.
-	 */
-	setmg_gcc((void*)ts.m, (void*)ts.g);
-
-	crosscall_amd64(ts.fn);
-	return nil;
-}
diff --git a/src/pkg/runtime/cgo/gcc_linux_arm.c b/src/pkg/runtime/cgo/gcc_linux_arm.c
deleted file mode 100644
index 0325681..0000000
--- a/src/pkg/runtime/cgo/gcc_linux_arm.c
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright 2010 The Go 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 <pthread.h>
-#include <string.h>
-#include <signal.h>
-#include "libcgo.h"
-
-static void *threadentry(void*);
-
-static void (*setmg_gcc)(void*, void*);
-
-void
-x_cgo_init(G *g, void (*setmg)(void*, void*))
-{
-	pthread_attr_t attr;
-	size_t size;
-
-	setmg_gcc = setmg;
-	pthread_attr_init(&attr);
-	pthread_attr_getstacksize(&attr, &size);
-	g->stackguard = (uintptr)&attr - size + 4096;
-	pthread_attr_destroy(&attr);
-}
-
-
-void
-_cgo_sys_thread_start(ThreadStart *ts)
-{
-	pthread_attr_t attr;
-	sigset_t ign, oset;
-	pthread_t p;
-	size_t size;
-	int err;
-
-	sigfillset(&ign);
-	pthread_sigmask(SIG_SETMASK, &ign, &oset);
-
-	// Not sure why the memset is necessary here,
-	// but without it, we get a bogus stack size
-	// out of pthread_attr_getstacksize.  C'est la Linux.
-	memset(&attr, 0, sizeof attr);
-	pthread_attr_init(&attr);
-	size = 0;
-	pthread_attr_getstacksize(&attr, &size);
-	ts->g->stackguard = size;
-	err = pthread_create(&p, &attr, threadentry, ts);
-
-	pthread_sigmask(SIG_SETMASK, &oset, nil);
-
-	if (err != 0) {
-		fprintf(stderr, "runtime/cgo: pthread_create failed: %s\n", strerror(err));
-		abort();
-	}
-}
-
-extern void crosscall_arm2(void (*fn)(void), void (*setmg_gcc)(void*, void*), void*, void*);
-static void*
-threadentry(void *v)
-{
-	ThreadStart ts;
-
-	ts = *(ThreadStart*)v;
-	free(v);
-
-	ts.g->stackbase = (uintptr)&ts;
-
-	/*
-	 * _cgo_sys_thread_start set stackguard to stack size;
-	 * change to actual guard pointer.
-	 */
-	ts.g->stackguard = (uintptr)&ts - ts.g->stackguard + 4096 * 2;
-
-	crosscall_arm2(ts.fn, setmg_gcc, (void*)ts.m, (void*)ts.g);
-	return nil;
-}
diff --git a/src/pkg/runtime/cgo/gcc_netbsd_386.c b/src/pkg/runtime/cgo/gcc_netbsd_386.c
deleted file mode 100644
index 28690cc..0000000
--- a/src/pkg/runtime/cgo/gcc_netbsd_386.c
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright 2009 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include <sys/types.h>
-#include <pthread.h>
-#include <signal.h>
-#include <string.h>
-#include "libcgo.h"
-
-static void* threadentry(void*);
-static void (*setmg_gcc)(void*, void*);
-
-void
-x_cgo_init(G *g, void (*setmg)(void*, void*))
-{
-	pthread_attr_t attr;
-	size_t size;
-
-	setmg_gcc = setmg;
-	pthread_attr_init(&attr);
-	pthread_attr_getstacksize(&attr, &size);
-	g->stackguard = (uintptr)&attr - size + 4096;
-	pthread_attr_destroy(&attr);
-}
-
-
-void
-_cgo_sys_thread_start(ThreadStart *ts)
-{
-	pthread_attr_t attr;
-	sigset_t ign, oset;
-	pthread_t p;
-	size_t size;
-	int err;
-
-	sigfillset(&ign);
-	pthread_sigmask(SIG_SETMASK, &ign, &oset);
-
-	pthread_attr_init(&attr);
-	pthread_attr_getstacksize(&attr, &size);
-	ts->g->stackguard = size;
-	err = pthread_create(&p, &attr, threadentry, ts);
-
-	pthread_sigmask(SIG_SETMASK, &oset, nil);
-
-	if (err != 0) {
-		fprintf(stderr, "runtime/cgo: pthread_create failed: %s\n", strerror(err));
-		abort();
-	}
-}
-
-static void*
-threadentry(void *v)
-{
-	ThreadStart ts;
-
-	ts = *(ThreadStart*)v;
-	free(v);
-
-	ts.g->stackbase = (uintptr)&ts;
-
-	/*
-	 * _cgo_sys_thread_start set stackguard to stack size;
-	 * change to actual guard pointer.
-	 */
-	ts.g->stackguard = (uintptr)&ts - ts.g->stackguard + 4096;
-
-	/*
-	 * Set specific keys.
-	 */
-	setmg_gcc((void*)ts.m, (void*)ts.g);
-
-	crosscall_386(ts.fn);
-	return nil;
-}
diff --git a/src/pkg/runtime/cgo/gcc_netbsd_amd64.c b/src/pkg/runtime/cgo/gcc_netbsd_amd64.c
deleted file mode 100644
index 6e0482d..0000000
--- a/src/pkg/runtime/cgo/gcc_netbsd_amd64.c
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright 2009 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include <sys/types.h>
-#include <pthread.h>
-#include <signal.h>
-#include <string.h>
-#include "libcgo.h"
-
-static void* threadentry(void*);
-static void (*setmg_gcc)(void*, void*);
-
-void
-x_cgo_init(G *g, void (*setmg)(void*, void*))
-{
-	pthread_attr_t attr;
-	size_t size;
-
-	setmg_gcc = setmg;
-	pthread_attr_init(&attr);
-	pthread_attr_getstacksize(&attr, &size);
-	g->stackguard = (uintptr)&attr - size + 4096;
-	pthread_attr_destroy(&attr);
-}
-
-
-void
-_cgo_sys_thread_start(ThreadStart *ts)
-{
-	pthread_attr_t attr;
-	sigset_t ign, oset;
-	pthread_t p;
-	size_t size;
-	int err;
-
-	sigfillset(&ign);
-	pthread_sigmask(SIG_SETMASK, &ign, &oset);
-
-	pthread_attr_init(&attr);
-	pthread_attr_getstacksize(&attr, &size);
-
-	ts->g->stackguard = size;
-	err = pthread_create(&p, &attr, threadentry, ts);
-
-	pthread_sigmask(SIG_SETMASK, &oset, nil);
-
-	if (err != 0) {
-		fprintf(stderr, "runtime/cgo: pthread_create failed: %s\n", strerror(err));
-		abort();
-	}
-}
-
-static void*
-threadentry(void *v)
-{
-	ThreadStart ts;
-
-	ts = *(ThreadStart*)v;
-	free(v);
-
-	ts.g->stackbase = (uintptr)&ts;
-
-	/*
-	 * _cgo_sys_thread_start set stackguard to stack size;
-	 * change to actual guard pointer.
-	 */
-	ts.g->stackguard = (uintptr)&ts - ts.g->stackguard + 4096;
-
-	/*
-	 * Set specific keys.
-	 */
-	setmg_gcc((void*)ts.m, (void*)ts.g);
-
-	crosscall_amd64(ts.fn);
-	return nil;
-}
diff --git a/src/pkg/runtime/cgo/gcc_netbsd_arm.c b/src/pkg/runtime/cgo/gcc_netbsd_arm.c
deleted file mode 100644
index ba2ae25..0000000
--- a/src/pkg/runtime/cgo/gcc_netbsd_arm.c
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright 2013 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include <sys/types.h>
-#include <pthread.h>
-#include <signal.h>
-#include <string.h>
-#include "libcgo.h"
-
-static void *threadentry(void*);
-
-static void (*setmg_gcc)(void*, void*);
-
-void
-x_cgo_init(G *g, void (*setmg)(void*, void*))
-{
-	pthread_attr_t attr;
-	size_t size;
-
-	setmg_gcc = setmg;
-	pthread_attr_init(&attr);
-	pthread_attr_getstacksize(&attr, &size);
-	g->stackguard = (uintptr)&attr - size + 4096;
-	pthread_attr_destroy(&attr);
-}
-
-
-void
-_cgo_sys_thread_start(ThreadStart *ts)
-{
-	pthread_attr_t attr;
-	sigset_t ign, oset;
-	pthread_t p;
-	size_t size;
-	int err;
-
-	sigfillset(&ign);
-	pthread_sigmask(SIG_SETMASK, &ign, &oset);
-
-	pthread_attr_init(&attr);
-	pthread_attr_getstacksize(&attr, &size);
-	ts->g->stackguard = size;
-	err = pthread_create(&p, &attr, threadentry, ts);
-
-	pthread_sigmask(SIG_SETMASK, &oset, nil);
-
-	if (err != 0) {
-		fprintf(stderr, "runtime/cgo: pthread_create failed: %s\n", strerror(err));
-		abort();
-	}
-}
-
-extern void crosscall_arm2(void (*fn)(void), void (*setmg_gcc)(void*, void*), void *g, void *m);
-static void*
-threadentry(void *v)
-{
-	ThreadStart ts;
-
-	ts = *(ThreadStart*)v;
-	free(v);
-
-	ts.g->stackbase = (uintptr)&ts;
-
-	/*
-	 * _cgo_sys_thread_start set stackguard to stack size;
-	 * change to actual guard pointer.
-	 */
-	ts.g->stackguard = (uintptr)&ts - ts.g->stackguard + 4096 * 2;
-
-	crosscall_arm2(ts.fn, setmg_gcc, (void*)ts.m, (void*)ts.g);
-	return nil;
-}
diff --git a/src/pkg/runtime/cgo/gcc_openbsd_386.c b/src/pkg/runtime/cgo/gcc_openbsd_386.c
deleted file mode 100644
index e682c37..0000000
--- a/src/pkg/runtime/cgo/gcc_openbsd_386.c
+++ /dev/null
@@ -1,165 +0,0 @@
-// Copyright 2009 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include <sys/types.h>
-#include <dlfcn.h>
-#include <errno.h>
-#include <pthread.h>
-#include <signal.h>
-#include <string.h>
-#include "libcgo.h"
-
-static void* threadentry(void*);
-static void (*setmg_gcc)(void*, void*);
-
-// TCB_SIZE is sizeof(struct thread_control_block),
-// as defined in /usr/src/lib/librthread/tcb.h
-#define TCB_SIZE (4 * sizeof(void *))
-#define TLS_SIZE (2 * sizeof(void *))
-
-void *__get_tcb(void);
-void __set_tcb(void *);
-
-static int (*sys_pthread_create)(pthread_t *thread, const pthread_attr_t *attr,
-	void *(*start_routine)(void *), void *arg);
-
-struct thread_args {
-	void *(*func)(void *);
-	void *arg;
-};
-
-static void
-tcb_fixup(int mainthread)
-{
-	void *newtcb, *oldtcb;
-
-	// The OpenBSD ld.so(1) does not currently support PT_TLS. As a result,
-	// we need to allocate our own TLS space while preserving the existing
-	// TCB that has been setup via librthread.
-
-	newtcb = malloc(TCB_SIZE + TLS_SIZE);
-	if(newtcb == NULL)
-		abort();
-
-	// The signal trampoline expects the TLS slots to be zeroed.
-	bzero(newtcb, TLS_SIZE);
-
-	oldtcb = __get_tcb();
-	bcopy(oldtcb, newtcb + TLS_SIZE, TCB_SIZE);
-	__set_tcb(newtcb + TLS_SIZE);
-
-	// NOTE(jsing, minux): we can't free oldtcb without causing double-free
-	// problem. so newtcb will be memory leaks. Get rid of this when OpenBSD
-	// has proper support for PT_TLS.
-}
-
-static void *
-thread_start_wrapper(void *arg)
-{
-	struct thread_args args = *(struct thread_args *)arg;
-
-	free(arg);
-	tcb_fixup(0);
-
-	return args.func(args.arg);
-}
-
-int
-pthread_create(pthread_t *thread, const pthread_attr_t *attr,
-	void *(*start_routine)(void *), void *arg)
-{
-	struct thread_args *p;
-
-	p = malloc(sizeof(*p));
-	if(p == NULL) {
-		errno = ENOMEM;
-		return -1;
-	}
-	p->func = start_routine;
-	p->arg = arg;
-
-	return sys_pthread_create(thread, attr, thread_start_wrapper, p);
-}
-
-void
-x_cgo_init(G *g, void (*setmg)(void*, void*))
-{
-	pthread_attr_t attr;
-	size_t size;
-	void *handle;
-
-	setmg_gcc = setmg;
-	pthread_attr_init(&attr);
-	pthread_attr_getstacksize(&attr, &size);
-	g->stackguard = (uintptr)&attr - size + 4096;
-	pthread_attr_destroy(&attr);
-
-	// Locate symbol for the system pthread_create function.
-	handle = dlopen("libpthread.so", RTLD_LAZY);
-	if(handle == NULL) {
-		fprintf(stderr, "dlopen: failed to load libpthread: %s\n", dlerror());
-		abort();
-	}
-	sys_pthread_create = dlsym(handle, "pthread_create");
-	if(sys_pthread_create == NULL) {
-		fprintf(stderr, "dlsym: failed to find pthread_create: %s\n", dlerror());
-		abort();
-	}
-	dlclose(handle);
-
-	tcb_fixup(1);
-}
-
-
-void
-_cgo_sys_thread_start(ThreadStart *ts)
-{
-	pthread_attr_t attr;
-	sigset_t ign, oset;
-	pthread_t p;
-	size_t size;
-	int err;
-
-	sigfillset(&ign);
-	pthread_sigmask(SIG_SETMASK, &ign, &oset);
-
-	pthread_attr_init(&attr);
-	pthread_attr_getstacksize(&attr, &size);
-	ts->g->stackguard = size;
-	err = sys_pthread_create(&p, &attr, threadentry, ts);
-
-	pthread_sigmask(SIG_SETMASK, &oset, nil);
-
-	if (err != 0) {
-		fprintf(stderr, "runtime/cgo: pthread_create failed: %s\n", strerror(err));
-		abort();
-	}
-}
-
-static void*
-threadentry(void *v)
-{
-	ThreadStart ts;
-
-	tcb_fixup(0);
-
-	ts = *(ThreadStart*)v;
-	free(v);
-
-	ts.g->stackbase = (uintptr)&ts;
-
-	/*
-	 * _cgo_sys_thread_start set stackguard to stack size;
-	 * change to actual guard pointer.
-	 */
-	ts.g->stackguard = (uintptr)&ts - ts.g->stackguard + 4096;
-
-	/*
-	 * Set specific keys.
-	 */
-	setmg_gcc((void*)ts.m, (void*)ts.g);
-
-	crosscall_386(ts.fn);
-	return nil;
-}
diff --git a/src/pkg/runtime/cgo/gcc_openbsd_amd64.c b/src/pkg/runtime/cgo/gcc_openbsd_amd64.c
deleted file mode 100644
index 64d29a9..0000000
--- a/src/pkg/runtime/cgo/gcc_openbsd_amd64.c
+++ /dev/null
@@ -1,166 +0,0 @@
-// Copyright 2009 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include <sys/types.h>
-#include <dlfcn.h>
-#include <errno.h>
-#include <pthread.h>
-#include <signal.h>
-#include <string.h>
-#include "libcgo.h"
-
-static void* threadentry(void*);
-static void (*setmg_gcc)(void*, void*);
-
-// TCB_SIZE is sizeof(struct thread_control_block),
-// as defined in /usr/src/lib/librthread/tcb.h
-#define TCB_SIZE (4 * sizeof(void *))
-#define TLS_SIZE (2 * sizeof(void *))
-
-void *__get_tcb(void);
-void __set_tcb(void *);
-
-static int (*sys_pthread_create)(pthread_t *thread, const pthread_attr_t *attr,
-	void *(*start_routine)(void *), void *arg);
-
-struct thread_args {
-	void *(*func)(void *);
-	void *arg;
-};
-
-static void
-tcb_fixup(int mainthread)
-{
-	void *newtcb, *oldtcb;
-
-	// The OpenBSD ld.so(1) does not currently support PT_TLS. As a result,
-	// we need to allocate our own TLS space while preserving the existing
-	// TCB that has been setup via librthread.
-
-	newtcb = malloc(TCB_SIZE + TLS_SIZE);
-	if(newtcb == NULL)
-		abort();
-
-	// The signal trampoline expects the TLS slots to be zeroed.
-	bzero(newtcb, TLS_SIZE);
-
-	oldtcb = __get_tcb();
-	bcopy(oldtcb, newtcb + TLS_SIZE, TCB_SIZE);
-	__set_tcb(newtcb + TLS_SIZE);
-
-	// NOTE(jsing, minux): we can't free oldtcb without causing double-free
-	// problem. so newtcb will be memory leaks. Get rid of this when OpenBSD
-	// has proper support for PT_TLS.
-}
-
-static void *
-thread_start_wrapper(void *arg)
-{
-	struct thread_args args = *(struct thread_args *)arg;
-
-	free(arg);
-	tcb_fixup(0);
-
-	return args.func(args.arg);
-}
-
-int
-pthread_create(pthread_t *thread, const pthread_attr_t *attr,
-	void *(*start_routine)(void *), void *arg)
-{
-	struct thread_args *p;
-
-	p = malloc(sizeof(*p));
-	if(p == NULL) {
-		errno = ENOMEM;
-		return -1;
-	}
-	p->func = start_routine;
-	p->arg = arg;
-
-	return sys_pthread_create(thread, attr, thread_start_wrapper, p);
-}
-
-void
-x_cgo_init(G *g, void (*setmg)(void*, void*))
-{
-	pthread_attr_t attr;
-	size_t size;
-	void *handle;
-
-	setmg_gcc = setmg;
-	pthread_attr_init(&attr);
-	pthread_attr_getstacksize(&attr, &size);
-	g->stackguard = (uintptr)&attr - size + 4096;
-	pthread_attr_destroy(&attr);
-
-	// Locate symbol for the system pthread_create function.
-	handle = dlopen("libpthread.so", RTLD_LAZY);
-	if(handle == NULL) {
-		fprintf(stderr, "dlopen: failed to load libpthread: %s\n", dlerror());
-		abort();
-	}
-	sys_pthread_create = dlsym(handle, "pthread_create");
-	if(sys_pthread_create == NULL) {
-		fprintf(stderr, "dlsym: failed to find pthread_create: %s\n", dlerror());
-		abort();
-	}
-	dlclose(handle);
-
-	tcb_fixup(1);
-}
-
-
-void
-_cgo_sys_thread_start(ThreadStart *ts)
-{
-	pthread_attr_t attr;
-	sigset_t ign, oset;
-	pthread_t p;
-	size_t size;
-	int err;
-
-	sigfillset(&ign);
-	pthread_sigmask(SIG_SETMASK, &ign, &oset);
-
-	pthread_attr_init(&attr);
-	pthread_attr_getstacksize(&attr, &size);
-
-	ts->g->stackguard = size;
-	err = sys_pthread_create(&p, &attr, threadentry, ts);
-
-	pthread_sigmask(SIG_SETMASK, &oset, nil);
-
-	if (err != 0) {
-		fprintf(stderr, "runtime/cgo: pthread_create failed: %s\n", strerror(err));
-		abort();
-	}
-}
-
-static void*
-threadentry(void *v)
-{
-	ThreadStart ts;
-
-	tcb_fixup(0);
-
-	ts = *(ThreadStart*)v;
-	free(v);
-
-	ts.g->stackbase = (uintptr)&ts;
-
-	/*
-	 * _cgo_sys_thread_start set stackguard to stack size;
-	 * change to actual guard pointer.
-	 */
-	ts.g->stackguard = (uintptr)&ts - ts.g->stackguard + 4096;
-
-	/*
-	 * Set specific keys.
-	 */
-	setmg_gcc((void*)ts.m, (void*)ts.g);
-
-	crosscall_amd64(ts.fn);
-	return nil;
-}
diff --git a/src/pkg/runtime/cgo/gcc_setenv.c b/src/pkg/runtime/cgo/gcc_setenv.c
deleted file mode 100644
index 8b128b9..0000000
--- a/src/pkg/runtime/cgo/gcc_setenv.c
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2011 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build darwin dragonfly freebsd linux netbsd openbsd
-
-#include "libcgo.h"
-
-#include <stdlib.h>
-
-/* Stub for calling setenv */
-void
-x_cgo_setenv(char **arg)
-{
-	setenv(arg[0], arg[1], 1);
-}
diff --git a/src/pkg/runtime/cgo/gcc_windows_386.c b/src/pkg/runtime/cgo/gcc_windows_386.c
deleted file mode 100644
index cdc8664..0000000
--- a/src/pkg/runtime/cgo/gcc_windows_386.c
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2009 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#include <process.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include "libcgo.h"
-
-static void threadentry(void*);
-
-/* 1MB is default stack size for 32-bit Windows.
-   Allocation granularity on Windows is typically 64 KB.
-   The constant is also hardcoded in cmd/ld/pe.c (keep synchronized). */
-#define STACKSIZE (1*1024*1024)
-
-void
-x_cgo_init(G *g)
-{
-	int tmp;
-	g->stackguard = (uintptr)&tmp - STACKSIZE + 8*1024;
-}
-
-
-void
-_cgo_sys_thread_start(ThreadStart *ts)
-{
-	uintptr_t thandle;
-
-	thandle = _beginthread(threadentry, 0, ts);
-	if(thandle == -1) {
-		fprintf(stderr, "runtime: failed to create new OS thread (%d)\n", errno);
-		abort();
-	}
-}
-
-static void
-threadentry(void *v)
-{
-	ThreadStart ts;
-
-	ts = *(ThreadStart*)v;
-	free(v);
-
-	ts.g->stackbase = (uintptr)&ts;
-	ts.g->stackguard = (uintptr)&ts - STACKSIZE + 8*1024;
-
-	/*
-	 * Set specific keys in thread local storage.
-	 */
-	asm volatile (
-		"movl %0, %%fs:0x14\n"	// MOVL tls0, 0x14(FS)
-		"movl %%fs:0x14, %%eax\n"	// MOVL 0x14(FS), tmp
-		"movl %1, 0(%%eax)\n"	// MOVL g, 0(FS)
-		"movl %2, 4(%%eax)\n"	// MOVL m, 4(FS)
-		:: "r"(ts.tls), "r"(ts.g), "r"(ts.m) : "%eax"
-	);
-	
-	crosscall_386(ts.fn);
-}
diff --git a/src/pkg/runtime/cgo/gcc_windows_amd64.c b/src/pkg/runtime/cgo/gcc_windows_amd64.c
deleted file mode 100644
index d8dd69b..0000000
--- a/src/pkg/runtime/cgo/gcc_windows_amd64.c
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2009 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#define WIN64_LEAN_AND_MEAN
-#include <windows.h>
-#include <process.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include "libcgo.h"
-
-static void threadentry(void*);
-
-/* 2MB is default stack size for 64-bit Windows.
-   Allocation granularity on Windows is typically 64 KB.
-   The constant is also hardcoded in cmd/ld/pe.c (keep synchronized). */
-#define STACKSIZE (2*1024*1024)
-
-void
-x_cgo_init(G *g)
-{
-	int tmp;
-	g->stackguard = (uintptr)&tmp - STACKSIZE + 8*1024;
-}
-
-
-void
-_cgo_sys_thread_start(ThreadStart *ts)
-{
-	uintptr_t thandle;
-
-	thandle = _beginthread(threadentry, 0, ts);
-	if(thandle == -1) {
-		fprintf(stderr, "runtime: failed to create new OS thread (%d)\n", errno);
-		abort();
-	}
-}
-
-static void
-threadentry(void *v)
-{
-	ThreadStart ts;
-
-	ts = *(ThreadStart*)v;
-	free(v);
-
-	ts.g->stackbase = (uintptr)&ts;
-	ts.g->stackguard = (uintptr)&ts - STACKSIZE + 8*1024;
-
-	/*
-	 * Set specific keys in thread local storage.
-	 */
-	asm volatile (
-	  "movq %0, %%gs:0x28\n"	// MOVL tls0, 0x28(GS)
-	  "movq %%gs:0x28, %%rax\n" // MOVQ 0x28(GS), tmp
-	  "movq %1, 0(%%rax)\n" // MOVQ g, 0(GS)
-	  "movq %2, 8(%%rax)\n" // MOVQ m, 8(GS)
-	  :: "r"(ts.tls), "r"(ts.g), "r"(ts.m) : "%rax"
-	);
-
-	crosscall_amd64(ts.fn);
-}
diff --git a/src/pkg/runtime/cgo/libcgo.h b/src/pkg/runtime/cgo/libcgo.h
deleted file mode 100644
index 65ea3f3..0000000
--- a/src/pkg/runtime/cgo/libcgo.h
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2009 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include <stdint.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#define nil ((void*)0)
-#define nelem(x) (sizeof(x)/sizeof((x)[0]))
-
-typedef uint32_t uint32;
-typedef uint64_t uint64;
-typedef uintptr_t uintptr;
-
-/*
- * The beginning of the per-goroutine structure,
- * as defined in ../pkg/runtime/runtime.h.
- * Just enough to edit these two fields.
- */
-typedef struct G G;
-struct G
-{
-	uintptr stackguard;
-	uintptr stackbase;
-};
-
-/*
- * Arguments to the _cgo_thread_start call.
- * Also known to ../pkg/runtime/runtime.h.
- */
-typedef struct ThreadStart ThreadStart;
-struct ThreadStart
-{
-	uintptr m;
-	G *g;
-	uintptr *tls;
-	void (*fn)(void);
-};
-
-/*
- * Called by 5c/6c/8c world.
- * Makes a local copy of the ThreadStart and
- * calls _cgo_sys_thread_start(ts).
- */
-extern void (*_cgo_thread_start)(ThreadStart *ts);
-
-/*
- * Creates the new operating system thread (OS, arch dependent).
- */
-void _cgo_sys_thread_start(ThreadStart *ts);
-
-/*
- * Call fn in the 6c world.
- */
-void crosscall_amd64(void (*fn)(void));
-
-/*
- * Call fn in the 8c world.
- */
-void crosscall_386(void (*fn)(void));
diff --git a/src/pkg/runtime/cgo/netbsd.c b/src/pkg/runtime/cgo/netbsd.c
deleted file mode 100644
index b6403f6..0000000
--- a/src/pkg/runtime/cgo/netbsd.c
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2010 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Supply environ and __progname, because we don't
-// link against the standard NetBSD crt0.o and the
-// libc dynamic library needs them.
-
-char *environ[1];
-char *__progname;
-
-#pragma dynexport environ environ
-#pragma dynexport __progname __progname
diff --git a/src/pkg/runtime/cgo/openbsd.c b/src/pkg/runtime/cgo/openbsd.c
deleted file mode 100644
index 84e9f9e..0000000
--- a/src/pkg/runtime/cgo/openbsd.c
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2010 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Supply environ, __progname and __guard_local, because
-// we don't link against the standard OpenBSD crt0.o and
-// the libc dynamic library needs them.
-
-char *environ[1];
-char *__progname;
-long __guard_local;
-
-#pragma dynexport environ environ
-#pragma dynexport __progname __progname
-
-// This is normally marked as hidden and placed in the
-// .openbsd.randomdata section.
-#pragma dynexport __guard_local __guard_local
-
-// We override pthread_create to support PT_TLS.
-#pragma dynexport pthread_create pthread_create
diff --git a/src/pkg/runtime/cgo/setenv.c b/src/pkg/runtime/cgo/setenv.c
deleted file mode 100644
index 2d03db0..0000000
--- a/src/pkg/runtime/cgo/setenv.c
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright 2011 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build darwin dragonfly freebsd linux netbsd openbsd
-
-#pragma cgo_import_static x_cgo_setenv
-
-void x_cgo_setenv(char**);
-void (*_cgo_setenv)(char**) = x_cgo_setenv;
diff --git a/src/pkg/runtime/cgocall.c b/src/pkg/runtime/cgocall.c
deleted file mode 100644
index 75d3850..0000000
--- a/src/pkg/runtime/cgocall.c
+++ /dev/null
@@ -1,322 +0,0 @@
-// Copyright 2009 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "runtime.h"
-#include "arch_GOARCH.h"
-#include "stack.h"
-#include "cgocall.h"
-#include "race.h"
-#include "../../cmd/ld/textflag.h"
-
-// Cgo call and callback support.
-//
-// To call into the C function f from Go, the cgo-generated code calls
-// runtime.cgocall(_cgo_Cfunc_f, frame), where _cgo_Cfunc_f is a
-// gcc-compiled function written by cgo.
-//
-// runtime.cgocall (below) locks g to m, calls entersyscall
-// so as not to block other goroutines or the garbage collector,
-// and then calls runtime.asmcgocall(_cgo_Cfunc_f, frame). 
-//
-// runtime.asmcgocall (in asm_$GOARCH.s) switches to the m->g0 stack
-// (assumed to be an operating system-allocated stack, so safe to run
-// gcc-compiled code on) and calls _cgo_Cfunc_f(frame).
-//
-// _cgo_Cfunc_f invokes the actual C function f with arguments
-// taken from the frame structure, records the results in the frame,
-// and returns to runtime.asmcgocall.
-//
-// After it regains control, runtime.asmcgocall switches back to the
-// original g (m->curg)'s stack and returns to runtime.cgocall.
-//
-// After it regains control, runtime.cgocall calls exitsyscall, which blocks
-// until this m can run Go code without violating the $GOMAXPROCS limit,
-// and then unlocks g from m.
-//
-// The above description skipped over the possibility of the gcc-compiled
-// function f calling back into Go.  If that happens, we continue down
-// the rabbit hole during the execution of f.
-//
-// To make it possible for gcc-compiled C code to call a Go function p.GoF,
-// cgo writes a gcc-compiled function named GoF (not p.GoF, since gcc doesn't
-// know about packages).  The gcc-compiled C function f calls GoF.
-//
-// GoF calls crosscall2(_cgoexp_GoF, frame, framesize).  Crosscall2
-// (in cgo/gcc_$GOARCH.S, a gcc-compiled assembly file) is a two-argument
-// adapter from the gcc function call ABI to the 6c function call ABI.
-// It is called from gcc to call 6c functions.  In this case it calls
-// _cgoexp_GoF(frame, framesize), still running on m->g0's stack
-// and outside the $GOMAXPROCS limit.  Thus, this code cannot yet
-// call arbitrary Go code directly and must be careful not to allocate
-// memory or use up m->g0's stack.
-//
-// _cgoexp_GoF calls runtime.cgocallback(p.GoF, frame, framesize).
-// (The reason for having _cgoexp_GoF instead of writing a crosscall3
-// to make this call directly is that _cgoexp_GoF, because it is compiled
-// with 6c instead of gcc, can refer to dotted names like
-// runtime.cgocallback and p.GoF.)
-//
-// runtime.cgocallback (in asm_$GOARCH.s) switches from m->g0's
-// stack to the original g (m->curg)'s stack, on which it calls
-// runtime.cgocallbackg(p.GoF, frame, framesize).
-// As part of the stack switch, runtime.cgocallback saves the current
-// SP as m->g0->sched.sp, so that any use of m->g0's stack during the
-// execution of the callback will be done below the existing stack frames.
-// Before overwriting m->g0->sched.sp, it pushes the old value on the
-// m->g0 stack, so that it can be restored later.
-//
-// runtime.cgocallbackg (below) is now running on a real goroutine
-// stack (not an m->g0 stack).  First it calls runtime.exitsyscall, which will
-// block until the $GOMAXPROCS limit allows running this goroutine.
-// Once exitsyscall has returned, it is safe to do things like call the memory
-// allocator or invoke the Go callback function p.GoF.  runtime.cgocallbackg
-// first defers a function to unwind m->g0.sched.sp, so that if p.GoF
-// panics, m->g0.sched.sp will be restored to its old value: the m->g0 stack
-// and the m->curg stack will be unwound in lock step.
-// Then it calls p.GoF.  Finally it pops but does not execute the deferred
-// function, calls runtime.entersyscall, and returns to runtime.cgocallback.
-//
-// After it regains control, runtime.cgocallback switches back to
-// m->g0's stack (the pointer is still in m->g0.sched.sp), restores the old
-// m->g0.sched.sp value from the stack, and returns to _cgoexp_GoF.
-//
-// _cgoexp_GoF immediately returns to crosscall2, which restores the
-// callee-save registers for gcc and returns to GoF, which returns to f.
-
-void *_cgo_init;	/* filled in by dynamic linker when Cgo is available */
-static int64 cgosync;  /* represents possible synchronization in C code */
-
-static void unwindm(void);
-
-// Call from Go to C.
-
-static void endcgo(void);
-static FuncVal endcgoV = { endcgo };
-
-void
-runtime·cgocall(void (*fn)(void*), void *arg)
-{
-	Defer d;
-
-	if(!runtime·iscgo && !Solaris && !Windows)
-		runtime·throw("cgocall unavailable");
-
-	if(fn == 0)
-		runtime·throw("cgocall nil");
-
-	if(raceenabled)
-		runtime·racereleasemerge(&cgosync);
-
-	// Create an extra M for callbacks on threads not created by Go on first cgo call.
-	if(runtime·needextram && runtime·cas(&runtime·needextram, 1, 0))
-		runtime·newextram();
-
-	m->ncgocall++;
-
-	/*
-	 * Lock g to m to ensure we stay on the same stack if we do a
-	 * cgo callback. Add entry to defer stack in case of panic.
-	 */
-	runtime·lockOSThread();
-	d.fn = &endcgoV;
-	d.siz = 0;
-	d.link = g->defer;
-	d.argp = NoArgs;
-	d.special = true;
-	g->defer = &d;
-	
-	m->ncgo++;
-
-	/*
-	 * Announce we are entering a system call
-	 * so that the scheduler knows to create another
-	 * M to run goroutines while we are in the
-	 * foreign code.
-	 *
-	 * The call to asmcgocall is guaranteed not to
-	 * split the stack and does not allocate memory,
-	 * so it is safe to call while "in a system call", outside
-	 * the $GOMAXPROCS accounting.
-	 */
-	runtime·entersyscall();
-	runtime·asmcgocall(fn, arg);
-	runtime·exitsyscall();
-
-	if(g->defer != &d || d.fn != &endcgoV)
-		runtime·throw("runtime: bad defer entry in cgocallback");
-	g->defer = d.link;
-	endcgo();
-}
-
-static void
-endcgo(void)
-{
-	runtime·unlockOSThread();
-	m->ncgo--;
-	if(m->ncgo == 0) {
-		// We are going back to Go and are not in a recursive
-		// call.  Let the GC collect any memory allocated via
-		// _cgo_allocate that is no longer referenced.
-		m->cgomal = nil;
-	}
-
-	if(raceenabled)
-		runtime·raceacquire(&cgosync);
-}
-
-// Helper functions for cgo code.
-
-void (*_cgo_malloc)(void*);
-void (*_cgo_free)(void*);
-
-void*
-runtime·cmalloc(uintptr n)
-{
-	struct {
-		uint64 n;
-		void *ret;
-	} a;
-
-	a.n = n;
-	a.ret = nil;
-	runtime·cgocall(_cgo_malloc, &a);
-	if(a.ret == nil)
-		runtime·throw("runtime: C malloc failed");
-	return a.ret;
-}
-
-void
-runtime·cfree(void *p)
-{
-	runtime·cgocall(_cgo_free, p);
-}
-
-// Call from C back to Go.
-
-static FuncVal unwindmf = {unwindm};
-
-typedef struct CallbackArgs CallbackArgs;
-struct CallbackArgs
-{
-	FuncVal *fn;
-	void *arg;
-	uintptr argsize;
-};
-
-// Location of callback arguments depends on stack frame layout
-// and size of stack frame of cgocallback_gofunc.
-
-// On arm, stack frame is two words and there's a saved LR between
-// SP and the stack frame and between the stack frame and the arguments.
-#ifdef GOARCH_arm
-#define CBARGS (CallbackArgs*)((byte*)m->g0->sched.sp+4*sizeof(void*))
-#endif
-
-// On amd64, stack frame is one word, plus caller PC.
-#ifdef GOARCH_amd64
-#define CBARGS (CallbackArgs*)((byte*)m->g0->sched.sp+2*sizeof(void*))
-#endif
-
-// Unimplemented on amd64p32
-#ifdef GOARCH_amd64p32
-#define CBARGS (CallbackArgs*)(nil)
-#endif
-
-// On 386, stack frame is three words, plus caller PC.
-#ifdef GOARCH_386
-#define CBARGS (CallbackArgs*)((byte*)m->g0->sched.sp+4*sizeof(void*))
-#endif
-
-void runtime·cgocallbackg1(void);
-
-#pragma textflag NOSPLIT
-void
-runtime·cgocallbackg(void)
-{
-	uintptr pc, sp;
-
-	if(g != m->curg) {
-		runtime·prints("runtime: bad g in cgocallback");
-		runtime·exit(2);
-	}
-
-	pc = g->syscallpc;
-	sp = g->syscallsp;
-	runtime·exitsyscall();	// coming out of cgo call
-	runtime·cgocallbackg1();
-	runtime·reentersyscall((void*)pc, sp);	// going back to cgo call
-}
-
-void
-runtime·cgocallbackg1(void)
-{
-	CallbackArgs *cb;
-	Defer d;
-
-	if(m->needextram) {
-		m->needextram = 0;
-		runtime·newextram();
-	}
-
-	// Add entry to defer stack in case of panic.
-	d.fn = &unwindmf;
-	d.siz = 0;
-	d.link = g->defer;
-	d.argp = NoArgs;
-	d.special = true;
-	g->defer = &d;
-
-	if(raceenabled)
-		runtime·raceacquire(&cgosync);
-
-	// Invoke callback.
-	cb = CBARGS;
-	runtime·newstackcall(cb->fn, cb->arg, cb->argsize);
-
-	if(raceenabled)
-		runtime·racereleasemerge(&cgosync);
-
-	// Pop defer.
-	// Do not unwind m->g0->sched.sp.
-	// Our caller, cgocallback, will do that.
-	if(g->defer != &d || d.fn != &unwindmf)
-		runtime·throw("runtime: bad defer entry in cgocallback");
-	g->defer = d.link;
-}
-
-static void
-unwindm(void)
-{
-	// Restore sp saved by cgocallback during
-	// unwind of g's stack (see comment at top of file).
-	switch(thechar){
-	default:
-		runtime·throw("runtime: unwindm not implemented");
-	case '8':
-	case '6':
-		m->g0->sched.sp = *(uintptr*)m->g0->sched.sp;
-		break;
-	case '5':
-		m->g0->sched.sp = *(uintptr*)((byte*)m->g0->sched.sp + 4);
-		break;
-	}
-}
-
-void
-runtime·badcgocallback(void)	// called from assembly
-{
-	runtime·throw("runtime: misaligned stack in cgocallback");
-}
-
-void
-runtime·cgounimpl(void)	// called from (incomplete) assembly
-{
-	runtime·throw("runtime: cgo not implemented");
-}
-
-// For cgo-using programs with external linking,
-// export "main" (defined in assembly) so that libc can handle basic
-// C runtime startup and call the Go program as if it were
-// the C main function.
-#pragma cgo_export_static main
diff --git a/src/pkg/runtime/cgocall.h b/src/pkg/runtime/cgocall.h
deleted file mode 100644
index 253661a..0000000
--- a/src/pkg/runtime/cgocall.h
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright 2009 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-/*
- * Cgo interface.
- */
-
-void runtime·cgocall(void (*fn)(void*), void*);
-void runtime·cgocallback(void (*fn)(void), void*, uintptr);
-void *runtime·cmalloc(uintptr);
-void runtime·cfree(void*);
diff --git a/src/pkg/runtime/chan.goc b/src/pkg/runtime/chan.goc
deleted file mode 100644
index 7a58471..0000000
--- a/src/pkg/runtime/chan.goc
+++ /dev/null
@@ -1,1155 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package runtime
-#include "runtime.h"
-#include "arch_GOARCH.h"
-#include "type.h"
-#include "race.h"
-#include "malloc.h"
-#include "chan.h"
-#include "../../cmd/ld/textflag.h"
-
-uint32 runtime·Hchansize = sizeof(Hchan);
-
-static	void	dequeueg(WaitQ*);
-static	SudoG*	dequeue(WaitQ*);
-static	void	enqueue(WaitQ*, SudoG*);
-static	void	destroychan(Hchan*);
-static	void	racesync(Hchan*, SudoG*);
-
-static Hchan*
-makechan(ChanType *t, int64 hint)
-{
-	Hchan *c;
-	Type *elem;
-
-	elem = t->elem;
-
-	// compiler checks this but be safe.
-	if(elem->size >= (1<<16))
-		runtime·throw("makechan: invalid channel element type");
-	if((sizeof(*c)%MAXALIGN) != 0 || elem->align > MAXALIGN)
-		runtime·throw("makechan: bad alignment");
-
-	if(hint < 0 || (intgo)hint != hint || (elem->size > 0 && hint > (MaxMem - sizeof(*c)) / elem->size))
-		runtime·panicstring("makechan: size out of range");
-
-	// allocate memory in one call
-	c = (Hchan*)runtime·mallocgc(sizeof(*c) + hint*elem->size, (uintptr)t | TypeInfo_Chan, 0);
-	c->elemsize = elem->size;
-	c->elemtype = elem;
-	c->dataqsiz = hint;
-
-	if(debug)
-		runtime·printf("makechan: chan=%p; elemsize=%D; elemalg=%p; dataqsiz=%D\n",
-			c, (int64)elem->size, elem->alg, (int64)c->dataqsiz);
-
-	return c;
-}
-
-func reflect·makechan(t *ChanType, size uint64) (c *Hchan) {
-	c = makechan(t, size);
-}
-
-func makechan(t *ChanType, size int64) (c *Hchan) {
-	c = makechan(t, size);
-}
-
-/*
- * generic single channel send/recv
- * if the bool pointer is nil,
- * then the full exchange will
- * occur. if pres is not nil,
- * then the protocol will not
- * sleep but return if it could
- * not complete.
- *
- * sleep can wake up with g->param == nil
- * when a channel involved in the sleep has
- * been closed.  it is easiest to loop and re-run
- * the operation; we'll see that it's now closed.
- */
-static bool
-chansend(ChanType *t, Hchan *c, byte *ep, bool block, void *pc)
-{
-	SudoG *sg;
-	SudoG mysg;
-	G* gp;
-	int64 t0;
-
-	if(raceenabled)
-		runtime·racereadobjectpc(ep, t->elem, runtime·getcallerpc(&t), chansend);
-
-	if(c == nil) {
-		USED(t);
-		if(!block)
-			return false;
-		runtime·park(nil, nil, "chan send (nil chan)");
-		return false;  // not reached
-	}
-
-	if(debug) {
-		runtime·printf("chansend: chan=%p; elem=", c);
-		c->elemtype->alg->print(c->elemsize, ep);
-		runtime·prints("\n");
-	}
-
-	t0 = 0;
-	mysg.releasetime = 0;
-	if(runtime·blockprofilerate > 0) {
-		t0 = runtime·cputicks();
-		mysg.releasetime = -1;
-	}
-
-	runtime·lock(c);
-	if(raceenabled)
-		runtime·racereadpc(c, pc, chansend);
-	if(c->closed)
-		goto closed;
-
-	if(c->dataqsiz > 0)
-		goto asynch;
-
-	sg = dequeue(&c->recvq);
-	if(sg != nil) {
-		if(raceenabled)
-			racesync(c, sg);
-		runtime·unlock(c);
-
-		gp = sg->g;
-		gp->param = sg;
-		if(sg->elem != nil)
-			c->elemtype->alg->copy(c->elemsize, sg->elem, ep);
-		if(sg->releasetime)
-			sg->releasetime = runtime·cputicks();
-		runtime·ready(gp);
-		return true;
-	}
-
-	if(!block) {
-		runtime·unlock(c);
-		return false;
-	}
-
-	mysg.elem = ep;
-	mysg.g = g;
-	mysg.selectdone = nil;
-	g->param = nil;
-	enqueue(&c->sendq, &mysg);
-	runtime·parkunlock(c, "chan send");
-
-	if(g->param == nil) {
-		runtime·lock(c);
-		if(!c->closed)
-			runtime·throw("chansend: spurious wakeup");
-		goto closed;
-	}
-
-	if(mysg.releasetime > 0)
-		runtime·blockevent(mysg.releasetime - t0, 2);
-
-	return true;
-
-asynch:
-	if(c->closed)
-		goto closed;
-
-	if(c->qcount >= c->dataqsiz) {
-		if(!block) {
-			runtime·unlock(c);
-			return false;
-		}
-		mysg.g = g;
-		mysg.elem = nil;
-		mysg.selectdone = nil;
-		enqueue(&c->sendq, &mysg);
-		runtime·parkunlock(c, "chan send");
-
-		runtime·lock(c);
-		goto asynch;
-	}
-
-	if(raceenabled) {
-		runtime·raceacquire(chanbuf(c, c->sendx));
-		runtime·racerelease(chanbuf(c, c->sendx));
-	}
-
-	c->elemtype->alg->copy(c->elemsize, chanbuf(c, c->sendx), ep);
-	if(++c->sendx == c->dataqsiz)
-		c->sendx = 0;
-	c->qcount++;
-
-	sg = dequeue(&c->recvq);
-	if(sg != nil) {
-		gp = sg->g;
-		runtime·unlock(c);
-		if(sg->releasetime)
-			sg->releasetime = runtime·cputicks();
-		runtime·ready(gp);
-	} else
-		runtime·unlock(c);
-	if(mysg.releasetime > 0)
-		runtime·blockevent(mysg.releasetime - t0, 2);
-	return true;
-
-closed:
-	runtime·unlock(c);
-	runtime·panicstring("send on closed channel");
-	return false;  // not reached
-}
-
-
-static bool
-chanrecv(ChanType *t, Hchan* c, byte *ep, bool block, bool *received)
-{
-	SudoG *sg;
-	SudoG mysg;
-	G *gp;
-	int64 t0;
-
-	// raceenabled: don't need to check ep, as it is always on the stack.
-
-	if(debug)
-		runtime·printf("chanrecv: chan=%p\n", c);
-
-	if(c == nil) {
-		USED(t);
-		if(!block)
-			return false;
-		runtime·park(nil, nil, "chan receive (nil chan)");
-		return false;  // not reached
-	}
-
-	t0 = 0;
-	mysg.releasetime = 0;
-	if(runtime·blockprofilerate > 0) {
-		t0 = runtime·cputicks();
-		mysg.releasetime = -1;
-	}
-
-	runtime·lock(c);
-	if(c->dataqsiz > 0)
-		goto asynch;
-
-	if(c->closed)
-		goto closed;
-
-	sg = dequeue(&c->sendq);
-	if(sg != nil) {
-		if(raceenabled)
-			racesync(c, sg);
-		runtime·unlock(c);
-
-		if(ep != nil)
-			c->elemtype->alg->copy(c->elemsize, ep, sg->elem);
-		gp = sg->g;
-		gp->param = sg;
-		if(sg->releasetime)
-			sg->releasetime = runtime·cputicks();
-		runtime·ready(gp);
-
-		if(received != nil)
-			*received = true;
-		return true;
-	}
-
-	if(!block) {
-		runtime·unlock(c);
-		return false;
-	}
-
-	mysg.elem = ep;
-	mysg.g = g;
-	mysg.selectdone = nil;
-	g->param = nil;
-	enqueue(&c->recvq, &mysg);
-	runtime·parkunlock(c, "chan receive");
-
-	if(g->param == nil) {
-		runtime·lock(c);
-		if(!c->closed)
-			runtime·throw("chanrecv: spurious wakeup");
-		goto closed;
-	}
-
-	if(received != nil)
-		*received = true;
-	if(mysg.releasetime > 0)
-		runtime·blockevent(mysg.releasetime - t0, 2);
-	return true;
-
-asynch:
-	if(c->qcount <= 0) {
-		if(c->closed)
-			goto closed;
-
-		if(!block) {
-			runtime·unlock(c);
-			if(received != nil)
-				*received = false;
-			return false;
-		}
-		mysg.g = g;
-		mysg.elem = nil;
-		mysg.selectdone = nil;
-		enqueue(&c->recvq, &mysg);
-		runtime·parkunlock(c, "chan receive");
-
-		runtime·lock(c);
-		goto asynch;
-	}
-
-	if(raceenabled) {
-		runtime·raceacquire(chanbuf(c, c->recvx));
-		runtime·racerelease(chanbuf(c, c->recvx));
-	}
-
-	if(ep != nil)
-		c->elemtype->alg->copy(c->elemsize, ep, chanbuf(c, c->recvx));
-	c->elemtype->alg->copy(c->elemsize, chanbuf(c, c->recvx), nil);
-	if(++c->recvx == c->dataqsiz)
-		c->recvx = 0;
-	c->qcount--;
-
-	sg = dequeue(&c->sendq);
-	if(sg != nil) {
-		gp = sg->g;
-		runtime·unlock(c);
-		if(sg->releasetime)
-			sg->releasetime = runtime·cputicks();
-		runtime·ready(gp);
-	} else
-		runtime·unlock(c);
-
-	if(received != nil)
-		*received = true;
-	if(mysg.releasetime > 0)
-		runtime·blockevent(mysg.releasetime - t0, 2);
-	return true;
-
-closed:
-	if(ep != nil)
-		c->elemtype->alg->copy(c->elemsize, ep, nil);
-	if(received != nil)
-		*received = false;
-	if(raceenabled)
-		runtime·raceacquire(c);
-	runtime·unlock(c);
-	if(mysg.releasetime > 0)
-		runtime·blockevent(mysg.releasetime - t0, 2);
-	return true;
-}
-
-#pragma textflag NOSPLIT
-func chansend1(t *ChanType, c *Hchan, elem *byte) {
-	chansend(t, c, elem, true, runtime·getcallerpc(&t));
-}
-
-#pragma textflag NOSPLIT
-func chanrecv1(t *ChanType, c *Hchan, elem *byte) {
-	chanrecv(t, c, elem, true, nil);
-}
-
-// chanrecv2(hchan *chan any, elem *any) (received bool);
-#pragma textflag NOSPLIT
-func chanrecv2(t *ChanType, c *Hchan, elem *byte) (received bool) {
-	chanrecv(t, c, elem, true, &received);
-}
-
-// compiler implements
-//
-//	select {
-//	case c <- v:
-//		... foo
-//	default:
-//		... bar
-//	}
-//
-// as
-//
-//	if selectnbsend(c, v) {
-//		... foo
-//	} else {
-//		... bar
-//	}
-//
-#pragma textflag NOSPLIT
-func selectnbsend(t *ChanType, c *Hchan, elem *byte) (selected bool) {
-	selected = chansend(t, c, elem, false, runtime·getcallerpc(&t));
-}
-
-// compiler implements
-//
-//	select {
-//	case v = <-c:
-//		... foo
-//	default:
-//		... bar
-//	}
-//
-// as
-//
-//	if selectnbrecv(&v, c) {
-//		... foo
-//	} else {
-//		... bar
-//	}
-//
-#pragma textflag NOSPLIT
-func selectnbrecv(t *ChanType, elem *byte, c *Hchan) (selected bool) {
-	selected = chanrecv(t, c, elem, false, nil);
-}
-
-// compiler implements
-//
-//	select {
-//	case v, ok = <-c:
-//		... foo
-//	default:
-//		... bar
-//	}
-//
-// as
-//
-//	if c != nil && selectnbrecv2(&v, &ok, c) {
-//		... foo
-//	} else {
-//		... bar
-//	}
-//
-#pragma textflag NOSPLIT
-func selectnbrecv2(t *ChanType, elem *byte, received *bool, c *Hchan) (selected bool) {
-	selected = chanrecv(t, c, elem, false, received);
-}
-
-#pragma textflag NOSPLIT
-func reflect·chansend(t *ChanType, c *Hchan, elem *byte, nb bool) (selected bool) {
-	selected = chansend(t, c, elem, !nb, runtime·getcallerpc(&t));
-}
-
-func reflect·chanrecv(t *ChanType, c *Hchan, nb bool, elem *byte) (selected bool, received bool) {
-	received = false;
-	selected = chanrecv(t, c, elem, !nb, &received);
-}
-
-static Select* newselect(int32);
-
-#pragma textflag NOSPLIT
-func newselect(size int32) (sel *byte) {
-	sel = (byte*)newselect(size);
-}
-
-static Select*
-newselect(int32 size)
-{
-	int32 n;
-	Select *sel;
-
-	n = 0;
-	if(size > 1)
-		n = size-1;
-
-	// allocate all the memory we need in a single allocation
-	// start with Select with size cases
-	// then lockorder with size entries
-	// then pollorder with size entries
-	sel = runtime·mal(sizeof(*sel) +
-		n*sizeof(sel->scase[0]) +
-		size*sizeof(sel->lockorder[0]) +
-		size*sizeof(sel->pollorder[0]));
-
-	sel->tcase = size;
-	sel->ncase = 0;
-	sel->lockorder = (void*)(sel->scase + size);
-	sel->pollorder = (void*)(sel->lockorder + size);
-
-	if(debug)
-		runtime·printf("newselect s=%p size=%d\n", sel, size);
-	return sel;
-}
-
-// cut in half to give stack a chance to split
-static void selectsend(Select *sel, Hchan *c, void *pc, void *elem, int32 so);
-
-#pragma textflag NOSPLIT
-func selectsend(sel *Select, c *Hchan, elem *byte) (selected bool) {
-	selected = false;
-
-	// nil cases do not compete
-	if(c != nil)
-		selectsend(sel, c, runtime·getcallerpc(&sel), elem, (byte*)&selected - (byte*)&sel);
-}
-
-static void
-selectsend(Select *sel, Hchan *c, void *pc, void *elem, int32 so)
-{
-	int32 i;
-	Scase *cas;
-
-	i = sel->ncase;
-	if(i >= sel->tcase)
-		runtime·throw("selectsend: too many cases");
-	sel->ncase = i+1;
-	cas = &sel->scase[i];
-
-	cas->pc = pc;
-	cas->chan = c;
-	cas->so = so;
-	cas->kind = CaseSend;
-	cas->sg.elem = elem;
-
-	if(debug)
-		runtime·printf("selectsend s=%p pc=%p chan=%p so=%d\n",
-			sel, cas->pc, cas->chan, cas->so);
-}
-
-// cut in half to give stack a chance to split
-static void selectrecv(Select *sel, Hchan *c, void *pc, void *elem, bool*, int32 so);
-
-#pragma textflag NOSPLIT
-func selectrecv(sel *Select, c *Hchan, elem *byte) (selected bool) {
-	selected = false;
-
-	// nil cases do not compete
-	if(c != nil)
-		selectrecv(sel, c, runtime·getcallerpc(&sel), elem, nil, (byte*)&selected - (byte*)&sel);
-}
-
-#pragma textflag NOSPLIT
-func selectrecv2(sel *Select, c *Hchan, elem *byte, received *bool) (selected bool) {
-	selected = false;
-
-	// nil cases do not compete
-	if(c != nil)
-		selectrecv(sel, c, runtime·getcallerpc(&sel), elem, received, (byte*)&selected - (byte*)&sel);
-}
-
-static void
-selectrecv(Select *sel, Hchan *c, void *pc, void *elem, bool *received, int32 so)
-{
-	int32 i;
-	Scase *cas;
-
-	i = sel->ncase;
-	if(i >= sel->tcase)
-		runtime·throw("selectrecv: too many cases");
-	sel->ncase = i+1;
-	cas = &sel->scase[i];
-	cas->pc = pc;
-	cas->chan = c;
-
-	cas->so = so;
-	cas->kind = CaseRecv;
-	cas->sg.elem = elem;
-	cas->receivedp = received;
-
-	if(debug)
-		runtime·printf("selectrecv s=%p pc=%p chan=%p so=%d\n",
-			sel, cas->pc, cas->chan, cas->so);
-}
-
-// cut in half to give stack a chance to split
-static void selectdefault(Select*, void*, int32);
-
-#pragma textflag NOSPLIT
-func selectdefault(sel *Select) (selected bool) {
-	selected = false;
-	selectdefault(sel, runtime·getcallerpc(&sel), (byte*)&selected - (byte*)&sel);
-}
-
-static void
-selectdefault(Select *sel, void *callerpc, int32 so)
-{
-	int32 i;
-	Scase *cas;
-
-	i = sel->ncase;
-	if(i >= sel->tcase)
-		runtime·throw("selectdefault: too many cases");
-	sel->ncase = i+1;
-	cas = &sel->scase[i];
-	cas->pc = callerpc;
-	cas->chan = nil;
-
-	cas->so = so;
-	cas->kind = CaseDefault;
-
-	if(debug)
-		runtime·printf("selectdefault s=%p pc=%p so=%d\n",
-			sel, cas->pc, cas->so);
-}
-
-static void
-sellock(Select *sel)
-{
-	uint32 i;
-	Hchan *c, *c0;
-
-	c = nil;
-	for(i=0; i<sel->ncase; i++) {
-		c0 = sel->lockorder[i];
-		if(c0 && c0 != c) {
-			c = sel->lockorder[i];
-			runtime·lock(c);
-		}
-	}
-}
-
-static void
-selunlock(Select *sel)
-{
-	int32 i, n, r;
-	Hchan *c;
-
-	// We must be very careful here to not touch sel after we have unlocked
-	// the last lock, because sel can be freed right after the last unlock.
-	// Consider the following situation.
-	// First M calls runtime·park() in runtime·selectgo() passing the sel.
-	// Once runtime·park() has unlocked the last lock, another M makes
-	// the G that calls select runnable again and schedules it for execution.
-	// When the G runs on another M, it locks all the locks and frees sel.
-	// Now if the first M touches sel, it will access freed memory.
-	n = (int32)sel->ncase;
-	r = 0;
-	// skip the default case
-	if(n>0 && sel->lockorder[0] == nil)
-		r = 1;
-	for(i = n-1; i >= r; i--) {
-		c = sel->lockorder[i];
-		if(i>0 && sel->lockorder[i-1] == c)
-			continue;  // will unlock it on the next iteration
-		runtime·unlock(c);
-	}
-}
-
-static bool
-selparkcommit(G *gp, void *sel)
-{
-	USED(gp);
-	selunlock(sel);
-	return true;
-}
-
-func block() {
-	runtime·park(nil, nil, "select (no cases)");	// forever
-}
-
-static void* selectgo(Select**);
-
-// selectgo(sel *byte);
-//
-// overwrites return pc on stack to signal which case of the select
-// to run, so cannot appear at the top of a split stack.
-#pragma textflag NOSPLIT
-func selectgo(sel *Select) {
-	runtime·setcallerpc(&sel, selectgo(&sel));
-}
-
-static void*
-selectgo(Select **selp)
-{
-	Select *sel;
-	uint32 o, i, j, k, done;
-	int64 t0;
-	Scase *cas, *dfl;
-	Hchan *c;
-	SudoG *sg;
-	G *gp;
-	byte *as;
-	void *pc;
-
-	sel = *selp;
-
-	if(debug)
-		runtime·printf("select: sel=%p\n", sel);
-
-	t0 = 0;
-	if(runtime·blockprofilerate > 0) {
-		t0 = runtime·cputicks();
-		for(i=0; i<sel->ncase; i++)
-			sel->scase[i].sg.releasetime = -1;
-	}
-
-	// The compiler rewrites selects that statically have
-	// only 0 or 1 cases plus default into simpler constructs.
-	// The only way we can end up with such small sel->ncase
-	// values here is for a larger select in which most channels
-	// have been nilled out.  The general code handles those
-	// cases correctly, and they are rare enough not to bother
-	// optimizing (and needing to test).
-
-	// generate permuted order
-	for(i=0; i<sel->ncase; i++)
-		sel->pollorder[i] = i;
-	for(i=1; i<sel->ncase; i++) {
-		o = sel->pollorder[i];
-		j = runtime·fastrand1()%(i+1);
-		sel->pollorder[i] = sel->pollorder[j];
-		sel->pollorder[j] = o;
-	}
-
-	// sort the cases by Hchan address to get the locking order.
-	// simple heap sort, to guarantee n log n time and constant stack footprint.
-	for(i=0; i<sel->ncase; i++) {
-		j = i;
-		c = sel->scase[j].chan;
-		while(j > 0 && sel->lockorder[k=(j-1)/2] < c) {
-			sel->lockorder[j] = sel->lockorder[k];
-			j = k;
-		}
-		sel->lockorder[j] = c;
-	}
-	for(i=sel->ncase; i-->0; ) {
-		c = sel->lockorder[i];
-		sel->lockorder[i] = sel->lockorder[0];
-		j = 0;
-		for(;;) {
-			k = j*2+1;
-			if(k >= i)
-				break;
-			if(k+1 < i && sel->lockorder[k] < sel->lockorder[k+1])
-				k++;
-			if(c < sel->lockorder[k]) {
-				sel->lockorder[j] = sel->lockorder[k];
-				j = k;
-				continue;
-			}
-			break;
-		}
-		sel->lockorder[j] = c;
-	}
-	/*
-	for(i=0; i+1<sel->ncase; i++)
-		if(sel->lockorder[i] > sel->lockorder[i+1]) {
-			runtime·printf("i=%d %p %p\n", i, sel->lockorder[i], sel->lockorder[i+1]);
-			runtime·throw("select: broken sort");
-		}
-	*/
-	sellock(sel);
-
-loop:
-	// pass 1 - look for something already waiting
-	dfl = nil;
-	for(i=0; i<sel->ncase; i++) {
-		o = sel->pollorder[i];
-		cas = &sel->scase[o];
-		c = cas->chan;
-
-		switch(cas->kind) {
-		case CaseRecv:
-			if(c->dataqsiz > 0) {
-				if(c->qcount > 0)
-					goto asyncrecv;
-			} else {
-				sg = dequeue(&c->sendq);
-				if(sg != nil)
-					goto syncrecv;
-			}
-			if(c->closed)
-				goto rclose;
-			break;
-
-		case CaseSend:
-			if(raceenabled)
-				runtime·racereadpc(c, cas->pc, chansend);
-			if(c->closed)
-				goto sclose;
-			if(c->dataqsiz > 0) {
-				if(c->qcount < c->dataqsiz)
-					goto asyncsend;
-			} else {
-				sg = dequeue(&c->recvq);
-				if(sg != nil)
-					goto syncsend;
-			}
-			break;
-
-		case CaseDefault:
-			dfl = cas;
-			break;
-		}
-	}
-
-	if(dfl != nil) {
-		selunlock(sel);
-		cas = dfl;
-		goto retc;
-	}
-
-
-	// pass 2 - enqueue on all chans
-	done = 0;
-	for(i=0; i<sel->ncase; i++) {
-		o = sel->pollorder[i];
-		cas = &sel->scase[o];
-		c = cas->chan;
-		sg = &cas->sg;
-		sg->g = g;
-		sg->selectdone = &done;
-
-		switch(cas->kind) {
-		case CaseRecv:
-			enqueue(&c->recvq, sg);
-			break;
-
-		case CaseSend:
-			enqueue(&c->sendq, sg);
-			break;
-		}
-	}
-
-	g->param = nil;
-	runtime·park(selparkcommit, sel, "select");
-
-	sellock(sel);
-	sg = g->param;
-
-	// pass 3 - dequeue from unsuccessful chans
-	// otherwise they stack up on quiet channels
-	for(i=0; i<sel->ncase; i++) {
-		cas = &sel->scase[i];
-		if(cas != (Scase*)sg) {
-			c = cas->chan;
-			if(cas->kind == CaseSend)
-				dequeueg(&c->sendq);
-			else
-				dequeueg(&c->recvq);
-		}
-	}
-
-	if(sg == nil)
-		goto loop;
-
-	cas = (Scase*)sg;
-	c = cas->chan;
-
-	if(c->dataqsiz > 0)
-		runtime·throw("selectgo: shouldn't happen");
-
-	if(debug)
-		runtime·printf("wait-return: sel=%p c=%p cas=%p kind=%d\n",
-			sel, c, cas, cas->kind);
-
-	if(cas->kind == CaseRecv) {
-		if(cas->receivedp != nil)
-			*cas->receivedp = true;
-	}
-
-	if(raceenabled) {
-		if(cas->kind == CaseRecv && cas->sg.elem != nil)
-			runtime·racewriteobjectpc(cas->sg.elem, c->elemtype, cas->pc, chanrecv);
-		else if(cas->kind == CaseSend)
-			runtime·racereadobjectpc(cas->sg.elem, c->elemtype, cas->pc, chansend);
-	}
-
-	selunlock(sel);
-	goto retc;
-
-asyncrecv:
-	// can receive from buffer
-	if(raceenabled) {
-		if(cas->sg.elem != nil)
-			runtime·racewriteobjectpc(cas->sg.elem, c->elemtype, cas->pc, chanrecv);
-		runtime·raceacquire(chanbuf(c, c->recvx));
-		runtime·racerelease(chanbuf(c, c->recvx));
-	}
-	if(cas->receivedp != nil)
-		*cas->receivedp = true;
-	if(cas->sg.elem != nil)
-		c->elemtype->alg->copy(c->elemsize, cas->sg.elem, chanbuf(c, c->recvx));
-	c->elemtype->alg->copy(c->elemsize, chanbuf(c, c->recvx), nil);
-	if(++c->recvx == c->dataqsiz)
-		c->recvx = 0;
-	c->qcount--;
-	sg = dequeue(&c->sendq);
-	if(sg != nil) {
-		gp = sg->g;
-		selunlock(sel);
-		if(sg->releasetime)
-			sg->releasetime = runtime·cputicks();
-		runtime·ready(gp);
-	} else {
-		selunlock(sel);
-	}
-	goto retc;
-
-asyncsend:
-	// can send to buffer
-	if(raceenabled) {
-		runtime·raceacquire(chanbuf(c, c->sendx));
-		runtime·racerelease(chanbuf(c, c->sendx));
-		runtime·racereadobjectpc(cas->sg.elem, c->elemtype, cas->pc, chansend);
-	}
-	c->elemtype->alg->copy(c->elemsize, chanbuf(c, c->sendx), cas->sg.elem);
-	if(++c->sendx == c->dataqsiz)
-		c->sendx = 0;
-	c->qcount++;
-	sg = dequeue(&c->recvq);
-	if(sg != nil) {
-		gp = sg->g;
-		selunlock(sel);
-		if(sg->releasetime)
-			sg->releasetime = runtime·cputicks();
-		runtime·ready(gp);
-	} else {
-		selunlock(sel);
-	}
-	goto retc;
-
-syncrecv:
-	// can receive from sleeping sender (sg)
-	if(raceenabled) {
-		if(cas->sg.elem != nil)
-			runtime·racewriteobjectpc(cas->sg.elem, c->elemtype, cas->pc, chanrecv);
-		racesync(c, sg);
-	}
-	selunlock(sel);
-	if(debug)
-		runtime·printf("syncrecv: sel=%p c=%p o=%d\n", sel, c, o);
-	if(cas->receivedp != nil)
-		*cas->receivedp = true;
-	if(cas->sg.elem != nil)
-		c->elemtype->alg->copy(c->elemsize, cas->sg.elem, sg->elem);
-	gp = sg->g;
-	gp->param = sg;
-	if(sg->releasetime)
-		sg->releasetime = runtime·cputicks();
-	runtime·ready(gp);
-	goto retc;
-
-rclose:
-	// read at end of closed channel
-	selunlock(sel);
-	if(cas->receivedp != nil)
-		*cas->receivedp = false;
-	if(cas->sg.elem != nil)
-		c->elemtype->alg->copy(c->elemsize, cas->sg.elem, nil);
-	if(raceenabled)
-		runtime·raceacquire(c);
-	goto retc;
-
-syncsend:
-	// can send to sleeping receiver (sg)
-	if(raceenabled) {
-		runtime·racereadobjectpc(cas->sg.elem, c->elemtype, cas->pc, chansend);
-		racesync(c, sg);
-	}
-	selunlock(sel);
-	if(debug)
-		runtime·printf("syncsend: sel=%p c=%p o=%d\n", sel, c, o);
-	if(sg->elem != nil)
-		c->elemtype->alg->copy(c->elemsize, sg->elem, cas->sg.elem);
-	gp = sg->g;
-	gp->param = sg;
-	if(sg->releasetime)
-		sg->releasetime = runtime·cputicks();
-	runtime·ready(gp);
-
-retc:
-	// return pc corresponding to chosen case.
-	// Set boolean passed during select creation
-	// (at offset selp + cas->so) to true.
-	// If cas->so == 0, this is a reflect-driven select and we
-	// don't need to update the boolean.
-	pc = cas->pc;
-	if(cas->so > 0) {
-		as = (byte*)selp + cas->so;
-		*as = true;
-	}
-	if(cas->sg.releasetime > 0)
-		runtime·blockevent(cas->sg.releasetime - t0, 2);
-	runtime·free(sel);
-	return pc;
-
-sclose:
-	// send on closed channel
-	selunlock(sel);
-	runtime·panicstring("send on closed channel");
-	return nil;  // not reached
-}
-
-// This struct must match ../reflect/value.go:/runtimeSelect.
-typedef struct runtimeSelect runtimeSelect;
-struct runtimeSelect
-{
-	uintptr dir;
-	ChanType *typ;
-	Hchan *ch;
-	byte *val;
-};
-
-// This enum must match ../reflect/value.go:/SelectDir.
-enum SelectDir {
-	SelectSend = 1,
-	SelectRecv,
-	SelectDefault,
-};
-
-func reflect·rselect(cases Slice) (chosen int, recvOK bool) {
-	int32 i;
-	Select *sel;
-	runtimeSelect* rcase, *rc;
-
-	chosen = -1;
-	recvOK = false;
-
-	rcase = (runtimeSelect*)cases.array;
-
-	sel = newselect(cases.len);
-	for(i=0; i<cases.len; i++) {
-		rc = &rcase[i];
-		switch(rc->dir) {
-		case SelectDefault:
-			selectdefault(sel, (void*)i, 0);
-			break;
-		case SelectSend:
-			if(rc->ch == nil)
-				break;
-			selectsend(sel, rc->ch, (void*)i, rc->val, 0);
-			break;
-		case SelectRecv:
-			if(rc->ch == nil)
-				break;
-			selectrecv(sel, rc->ch, (void*)i, rc->val, &recvOK, 0);
-			break;
-		}
-	}
-
-	chosen = (intgo)(uintptr)selectgo(&sel);
-}
-
-static void closechan(Hchan *c, void *pc);
-
-#pragma textflag NOSPLIT
-func closechan(c *Hchan) {
-	closechan(c, runtime·getcallerpc(&c));
-}
-
-#pragma textflag NOSPLIT
-func reflect·chanclose(c *Hchan) {
-	closechan(c, runtime·getcallerpc(&c));
-}
-
-static void
-closechan(Hchan *c, void *pc)
-{
-	SudoG *sg;
-	G* gp;
-
-	if(c == nil)
-		runtime·panicstring("close of nil channel");
-
-	runtime·lock(c);
-	if(c->closed) {
-		runtime·unlock(c);
-		runtime·panicstring("close of closed channel");
-	}
-
-	if(raceenabled) {
-		runtime·racewritepc(c, pc, runtime·closechan);
-		runtime·racerelease(c);
-	}
-
-	c->closed = true;
-
-	// release all readers
-	for(;;) {
-		sg = dequeue(&c->recvq);
-		if(sg == nil)
-			break;
-		gp = sg->g;
-		gp->param = nil;
-		if(sg->releasetime)
-			sg->releasetime = runtime·cputicks();
-		runtime·ready(gp);
-	}
-
-	// release all writers
-	for(;;) {
-		sg = dequeue(&c->sendq);
-		if(sg == nil)
-			break;
-		gp = sg->g;
-		gp->param = nil;
-		if(sg->releasetime)
-			sg->releasetime = runtime·cputicks();
-		runtime·ready(gp);
-	}
-
-	runtime·unlock(c);
-}
-
-func reflect·chanlen(c *Hchan) (len int) {
-	if(c == nil)
-		len = 0;
-	else
-		len = c->qcount;
-}
-
-func reflect·chancap(c *Hchan) (cap int) {
-	if(c == nil)
-		cap = 0;
-	else
-		cap = c->dataqsiz;
-}
-
-static SudoG*
-dequeue(WaitQ *q)
-{
-	SudoG *sgp;
-
-loop:
-	sgp = q->first;
-	if(sgp == nil)
-		return nil;
-	q->first = sgp->link;
-
-	// if sgp participates in a select and is already signaled, ignore it
-	if(sgp->selectdone != nil) {
-		// claim the right to signal
-		if(*sgp->selectdone != 0 || !runtime·cas(sgp->selectdone, 0, 1))
-			goto loop;
-	}
-
-	return sgp;
-}
-
-static void
-dequeueg(WaitQ *q)
-{
-	SudoG **l, *sgp, *prevsgp;
-
-	prevsgp = nil;
-	for(l=&q->first; (sgp=*l) != nil; l=&sgp->link, prevsgp=sgp) {
-		if(sgp->g == g) {
-			*l = sgp->link;
-			if(q->last == sgp)
-				q->last = prevsgp;
-			break;
-		}
-	}
-}
-
-static void
-enqueue(WaitQ *q, SudoG *sgp)
-{
-	sgp->link = nil;
-	if(q->first == nil) {
-		q->first = sgp;
-		q->last = sgp;
-		return;
-	}
-	q->last->link = sgp;
-	q->last = sgp;
-}
-
-static void
-racesync(Hchan *c, SudoG *sg)
-{
-	runtime·racerelease(chanbuf(c, 0));
-	runtime·raceacquireg(sg->g, chanbuf(c, 0));
-	runtime·racereleaseg(sg->g, chanbuf(c, 0));
-	runtime·raceacquire(chanbuf(c, 0));
-}
diff --git a/src/pkg/runtime/chan.h b/src/pkg/runtime/chan.h
deleted file mode 100644
index ce2eb9f..0000000
--- a/src/pkg/runtime/chan.h
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#define	MAXALIGN	8
-
-typedef	struct	WaitQ	WaitQ;
-typedef	struct	SudoG	SudoG;
-typedef	struct	Select	Select;
-typedef	struct	Scase	Scase;
-
-struct	SudoG
-{
-	G*	g;
-	uint32*	selectdone;
-	SudoG*	link;
-	int64	releasetime;
-	byte*	elem;		// data element
-};
-
-struct	WaitQ
-{
-	SudoG*	first;
-	SudoG*	last;
-};
-
-// The garbage collector is assuming that Hchan can only contain pointers into the stack
-// and cannot contain pointers into the heap.
-struct	Hchan
-{
-	uintgo	qcount;			// total data in the q
-	uintgo	dataqsiz;		// size of the circular q
-	uint16	elemsize;
-	uint16	pad;			// ensures proper alignment of the buffer that follows Hchan in memory
-	bool	closed;
-	Type*	elemtype;		// element type
-	uintgo	sendx;			// send index
-	uintgo	recvx;			// receive index
-	WaitQ	recvq;			// list of recv waiters
-	WaitQ	sendq;			// list of send waiters
-	Lock;
-};
-
-// Buffer follows Hchan immediately in memory.
-// chanbuf(c, i) is pointer to the i'th slot in the buffer.
-#define chanbuf(c, i) ((byte*)((c)+1)+(uintptr)(c)->elemsize*(i))
-
-enum
-{
-	debug = 0,
-
-	// Scase.kind
-	CaseRecv,
-	CaseSend,
-	CaseDefault,
-};
-
-struct	Scase
-{
-	SudoG	sg;			// must be first member (cast to Scase)
-	Hchan*	chan;			// chan
-	byte*	pc;			// return pc
-	uint16	kind;
-	uint16	so;			// vararg of selected bool
-	bool*	receivedp;		// pointer to received bool (recv2)
-};
-
-struct	Select
-{
-	uint16	tcase;			// total count of scase[]
-	uint16	ncase;			// currently filled scase[]
-	uint16*	pollorder;		// case poll order
-	Hchan**	lockorder;		// channel lock order
-	Scase	scase[1];		// one per case (in order of appearance)
-};
diff --git a/src/pkg/runtime/chan_test.go b/src/pkg/runtime/chan_test.go
deleted file mode 100644
index ce4b396..0000000
--- a/src/pkg/runtime/chan_test.go
+++ /dev/null
@@ -1,711 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package runtime_test
-
-import (
-	"runtime"
-	"sync"
-	"sync/atomic"
-	"testing"
-	"time"
-)
-
-func TestChan(t *testing.T) {
-	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4))
-	N := 200
-	if testing.Short() {
-		N = 20
-	}
-	for chanCap := 0; chanCap < N; chanCap++ {
-		{
-			// Ensure that receive from empty chan blocks.
-			c := make(chan int, chanCap)
-			recv1 := false
-			go func() {
-				_ = <-c
-				recv1 = true
-			}()
-			recv2 := false
-			go func() {
-				_, _ = <-c
-				recv2 = true
-			}()
-			time.Sleep(time.Millisecond)
-			if recv1 || recv2 {
-				t.Fatalf("chan[%d]: receive from empty chan", chanCap)
-			}
-			// Ensure that non-blocking receive does not block.
-			select {
-			case _ = <-c:
-				t.Fatalf("chan[%d]: receive from empty chan", chanCap)
-			default:
-			}
-			select {
-			case _, _ = <-c:
-				t.Fatalf("chan[%d]: receive from empty chan", chanCap)
-			default:
-			}
-			c <- 0
-			c <- 0
-		}
-
-		{
-			// Ensure that send to full chan blocks.
-			c := make(chan int, chanCap)
-			for i := 0; i < chanCap; i++ {
-				c <- i
-			}
-			sent := uint32(0)
-			go func() {
-				c <- 0
-				atomic.StoreUint32(&sent, 1)
-			}()
-			time.Sleep(time.Millisecond)
-			if atomic.LoadUint32(&sent) != 0 {
-				t.Fatalf("chan[%d]: send to full chan", chanCap)
-			}
-			// Ensure that non-blocking send does not block.
-			select {
-			case c <- 0:
-				t.Fatalf("chan[%d]: send to full chan", chanCap)
-			default:
-			}
-			<-c
-		}
-
-		{
-			// Ensure that we receive 0 from closed chan.
-			c := make(chan int, chanCap)
-			for i := 0; i < chanCap; i++ {
-				c <- i
-			}
-			close(c)
-			for i := 0; i < chanCap; i++ {
-				v := <-c
-				if v != i {
-					t.Fatalf("chan[%d]: received %v, expected %v", chanCap, v, i)
-				}
-			}
-			if v := <-c; v != 0 {
-				t.Fatalf("chan[%d]: received %v, expected %v", chanCap, v, 0)
-			}
-			if v, ok := <-c; v != 0 || ok {
-				t.Fatalf("chan[%d]: received %v/%v, expected %v/%v", chanCap, v, ok, 0, false)
-			}
-		}
-
-		{
-			// Ensure that close unblocks receive.
-			c := make(chan int, chanCap)
-			done := make(chan bool)
-			go func() {
-				v, ok := <-c
-				done <- v == 0 && ok == false
-			}()
-			time.Sleep(time.Millisecond)
-			close(c)
-			if !<-done {
-				t.Fatalf("chan[%d]: received non zero from closed chan", chanCap)
-			}
-		}
-
-		{
-			// Send 100 integers,
-			// ensure that we receive them non-corrupted in FIFO order.
-			c := make(chan int, chanCap)
-			go func() {
-				for i := 0; i < 100; i++ {
-					c <- i
-				}
-			}()
-			for i := 0; i < 100; i++ {
-				v := <-c
-				if v != i {
-					t.Fatalf("chan[%d]: received %v, expected %v", chanCap, v, i)
-				}
-			}
-
-			// Same, but using recv2.
-			go func() {
-				for i := 0; i < 100; i++ {
-					c <- i
-				}
-			}()
-			for i := 0; i < 100; i++ {
-				v, ok := <-c
-				if !ok {
-					t.Fatalf("chan[%d]: receive failed, expected %v", chanCap, i)
-				}
-				if v != i {
-					t.Fatalf("chan[%d]: received %v, expected %v", chanCap, v, i)
-				}
-			}
-
-			// Send 1000 integers in 4 goroutines,
-			// ensure that we receive what we send.
-			const P = 4
-			const L = 1000
-			for p := 0; p < P; p++ {
-				go func() {
-					for i := 0; i < L; i++ {
-						c <- i
-					}
-				}()
-			}
-			done := make(chan map[int]int)
-			for p := 0; p < P; p++ {
-				go func() {
-					recv := make(map[int]int)
-					for i := 0; i < L; i++ {
-						v := <-c
-						recv[v] = recv[v] + 1
-					}
-					done <- recv
-				}()
-			}
-			recv := make(map[int]int)
-			for p := 0; p < P; p++ {
-				for k, v := range <-done {
-					recv[k] = recv[k] + v
-				}
-			}
-			if len(recv) != L {
-				t.Fatalf("chan[%d]: received %v values, expected %v", chanCap, len(recv), L)
-			}
-			for _, v := range recv {
-				if v != P {
-					t.Fatalf("chan[%d]: received %v values, expected %v", chanCap, v, P)
-				}
-			}
-		}
-
-		{
-			// Test len/cap.
-			c := make(chan int, chanCap)
-			if len(c) != 0 || cap(c) != chanCap {
-				t.Fatalf("chan[%d]: bad len/cap, expect %v/%v, got %v/%v", chanCap, 0, chanCap, len(c), cap(c))
-			}
-			for i := 0; i < chanCap; i++ {
-				c <- i
-			}
-			if len(c) != chanCap || cap(c) != chanCap {
-				t.Fatalf("chan[%d]: bad len/cap, expect %v/%v, got %v/%v", chanCap, chanCap, chanCap, len(c), cap(c))
-			}
-		}
-
-	}
-}
-
-func TestSelfSelect(t *testing.T) {
-	// Ensure that send/recv on the same chan in select
-	// does not crash nor deadlock.
-	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(2))
-	for _, chanCap := range []int{0, 10} {
-		var wg sync.WaitGroup
-		wg.Add(2)
-		c := make(chan int, chanCap)
-		for p := 0; p < 2; p++ {
-			p := p
-			go func() {
-				defer wg.Done()
-				for i := 0; i < 1000; i++ {
-					if p == 0 || i%2 == 0 {
-						select {
-						case c <- p:
-						case v := <-c:
-							if chanCap == 0 && v == p {
-								t.Fatalf("self receive")
-							}
-						}
-					} else {
-						select {
-						case v := <-c:
-							if chanCap == 0 && v == p {
-								t.Fatalf("self receive")
-							}
-						case c <- p:
-						}
-					}
-				}
-			}()
-		}
-		wg.Wait()
-	}
-}
-
-func TestSelectStress(t *testing.T) {
-	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(10))
-	var c [4]chan int
-	c[0] = make(chan int)
-	c[1] = make(chan int)
-	c[2] = make(chan int, 2)
-	c[3] = make(chan int, 3)
-	N := int(1e5)
-	if testing.Short() {
-		N /= 10
-	}
-	// There are 4 goroutines that send N values on each of the chans,
-	// + 4 goroutines that receive N values on each of the chans,
-	// + 1 goroutine that sends N values on each of the chans in a single select,
-	// + 1 goroutine that receives N values on each of the chans in a single select.
-	// All these sends, receives and selects interact chaotically at runtime,
-	// but we are careful that this whole construct does not deadlock.
-	var wg sync.WaitGroup
-	wg.Add(10)
-	for k := 0; k < 4; k++ {
-		k := k
-		go func() {
-			for i := 0; i < N; i++ {
-				c[k] <- 0
-			}
-			wg.Done()
-		}()
-		go func() {
-			for i := 0; i < N; i++ {
-				<-c[k]
-			}
-			wg.Done()
-		}()
-	}
-	go func() {
-		var n [4]int
-		c1 := c
-		for i := 0; i < 4*N; i++ {
-			select {
-			case c1[3] <- 0:
-				n[3]++
-				if n[3] == N {
-					c1[3] = nil
-				}
-			case c1[2] <- 0:
-				n[2]++
-				if n[2] == N {
-					c1[2] = nil
-				}
-			case c1[0] <- 0:
-				n[0]++
-				if n[0] == N {
-					c1[0] = nil
-				}
-			case c1[1] <- 0:
-				n[1]++
-				if n[1] == N {
-					c1[1] = nil
-				}
-			}
-		}
-		wg.Done()
-	}()
-	go func() {
-		var n [4]int
-		c1 := c
-		for i := 0; i < 4*N; i++ {
-			select {
-			case <-c1[0]:
-				n[0]++
-				if n[0] == N {
-					c1[0] = nil
-				}
-			case <-c1[1]:
-				n[1]++
-				if n[1] == N {
-					c1[1] = nil
-				}
-			case <-c1[2]:
-				n[2]++
-				if n[2] == N {
-					c1[2] = nil
-				}
-			case <-c1[3]:
-				n[3]++
-				if n[3] == N {
-					c1[3] = nil
-				}
-			}
-		}
-		wg.Done()
-	}()
-	wg.Wait()
-}
-
-func TestChanSendInterface(t *testing.T) {
-	type mt struct{}
-	m := &mt{}
-	c := make(chan interface{}, 1)
-	c <- m
-	select {
-	case c <- m:
-	default:
-	}
-	select {
-	case c <- m:
-	case c <- &mt{}:
-	default:
-	}
-}
-
-func TestPseudoRandomSend(t *testing.T) {
-	n := 100
-	for _, chanCap := range []int{0, n} {
-		c := make(chan int, chanCap)
-		l := make([]int, n)
-		var m sync.Mutex
-		m.Lock()
-		go func() {
-			for i := 0; i < n; i++ {
-				runtime.Gosched()
-				l[i] = <-c
-			}
-			m.Unlock()
-		}()
-		for i := 0; i < n; i++ {
-			select {
-			case c <- 1:
-			case c <- 0:
-			}
-		}
-		m.Lock() // wait
-		n0 := 0
-		n1 := 0
-		for _, i := range l {
-			n0 += (i + 1) % 2
-			n1 += i
-		}
-		if n0 <= n/10 || n1 <= n/10 {
-			t.Errorf("Want pseudorandom, got %d zeros and %d ones (chan cap %d)", n0, n1, chanCap)
-		}
-	}
-}
-
-func TestMultiConsumer(t *testing.T) {
-	const nwork = 23
-	const niter = 271828
-
-	pn := []int{2, 3, 7, 11, 13, 17, 19, 23, 27, 31}
-
-	q := make(chan int, nwork*3)
-	r := make(chan int, nwork*3)
-
-	// workers
-	var wg sync.WaitGroup
-	for i := 0; i < nwork; i++ {
-		wg.Add(1)
-		go func(w int) {
-			for v := range q {
-				// mess with the fifo-ish nature of range
-				if pn[w%len(pn)] == v {
-					runtime.Gosched()
-				}
-				r <- v
-			}
-			wg.Done()
-		}(i)
-	}
-
-	// feeder & closer
-	expect := 0
-	go func() {
-		for i := 0; i < niter; i++ {
-			v := pn[i%len(pn)]
-			expect += v
-			q <- v
-		}
-		close(q)  // no more work
-		wg.Wait() // workers done
-		close(r)  // ... so there can be no more results
-	}()
-
-	// consume & check
-	n := 0
-	s := 0
-	for v := range r {
-		n++
-		s += v
-	}
-	if n != niter || s != expect {
-		t.Errorf("Expected sum %d (got %d) from %d iter (saw %d)",
-			expect, s, niter, n)
-	}
-}
-
-func BenchmarkChanNonblocking(b *testing.B) {
-	myc := make(chan int)
-	b.RunParallel(func(pb *testing.PB) {
-		for pb.Next() {
-			select {
-			case <-myc:
-			default:
-			}
-		}
-	})
-}
-
-func BenchmarkSelectUncontended(b *testing.B) {
-	b.RunParallel(func(pb *testing.PB) {
-		myc1 := make(chan int, 1)
-		myc2 := make(chan int, 1)
-		myc1 <- 0
-		for pb.Next() {
-			select {
-			case <-myc1:
-				myc2 <- 0
-			case <-myc2:
-				myc1 <- 0
-			}
-		}
-	})
-}
-
-func BenchmarkSelectContended(b *testing.B) {
-	procs := runtime.GOMAXPROCS(0)
-	myc1 := make(chan int, procs)
-	myc2 := make(chan int, procs)
-	b.RunParallel(func(pb *testing.PB) {
-		myc1 <- 0
-		for pb.Next() {
-			select {
-			case <-myc1:
-				myc2 <- 0
-			case <-myc2:
-				myc1 <- 0
-			}
-		}
-	})
-}
-
-func BenchmarkSelectNonblock(b *testing.B) {
-	b.RunParallel(func(pb *testing.PB) {
-		myc1 := make(chan int)
-		myc2 := make(chan int)
-		myc3 := make(chan int, 1)
-		myc4 := make(chan int, 1)
-		for pb.Next() {
-			select {
-			case <-myc1:
-			default:
-			}
-			select {
-			case myc2 <- 0:
-			default:
-			}
-			select {
-			case <-myc3:
-			default:
-			}
-			select {
-			case myc4 <- 0:
-			default:
-			}
-		}
-	})
-}
-
-func BenchmarkChanUncontended(b *testing.B) {
-	const C = 100
-	b.RunParallel(func(pb *testing.PB) {
-		myc := make(chan int, C)
-		for pb.Next() {
-			for i := 0; i < C; i++ {
-				myc <- 0
-			}
-			for i := 0; i < C; i++ {
-				<-myc
-			}
-		}
-	})
-}
-
-func BenchmarkChanContended(b *testing.B) {
-	const C = 100
-	myc := make(chan int, C*runtime.GOMAXPROCS(0))
-	b.RunParallel(func(pb *testing.PB) {
-		for pb.Next() {
-			for i := 0; i < C; i++ {
-				myc <- 0
-			}
-			for i := 0; i < C; i++ {
-				<-myc
-			}
-		}
-	})
-}
-
-func BenchmarkChanSync(b *testing.B) {
-	const CallsPerSched = 1000
-	procs := 2
-	N := int32(b.N / CallsPerSched / procs * procs)
-	c := make(chan bool, procs)
-	myc := make(chan int)
-	for p := 0; p < procs; p++ {
-		go func() {
-			for {
-				i := atomic.AddInt32(&N, -1)
-				if i < 0 {
-					break
-				}
-				for g := 0; g < CallsPerSched; g++ {
-					if i%2 == 0 {
-						<-myc
-						myc <- 0
-					} else {
-						myc <- 0
-						<-myc
-					}
-				}
-			}
-			c <- true
-		}()
-	}
-	for p := 0; p < procs; p++ {
-		<-c
-	}
-}
-
-func benchmarkChanProdCons(b *testing.B, chanSize, localWork int) {
-	const CallsPerSched = 1000
-	procs := runtime.GOMAXPROCS(-1)
-	N := int32(b.N / CallsPerSched)
-	c := make(chan bool, 2*procs)
-	myc := make(chan int, chanSize)
-	for p := 0; p < procs; p++ {
-		go func() {
-			foo := 0
-			for atomic.AddInt32(&N, -1) >= 0 {
-				for g := 0; g < CallsPerSched; g++ {
-					for i := 0; i < localWork; i++ {
-						foo *= 2
-						foo /= 2
-					}
-					myc <- 1
-				}
-			}
-			myc <- 0
-			c <- foo == 42
-		}()
-		go func() {
-			foo := 0
-			for {
-				v := <-myc
-				if v == 0 {
-					break
-				}
-				for i := 0; i < localWork; i++ {
-					foo *= 2
-					foo /= 2
-				}
-			}
-			c <- foo == 42
-		}()
-	}
-	for p := 0; p < procs; p++ {
-		<-c
-		<-c
-	}
-}
-
-func BenchmarkChanProdCons0(b *testing.B) {
-	benchmarkChanProdCons(b, 0, 0)
-}
-
-func BenchmarkChanProdCons10(b *testing.B) {
-	benchmarkChanProdCons(b, 10, 0)
-}
-
-func BenchmarkChanProdCons100(b *testing.B) {
-	benchmarkChanProdCons(b, 100, 0)
-}
-
-func BenchmarkChanProdConsWork0(b *testing.B) {
-	benchmarkChanProdCons(b, 0, 100)
-}
-
-func BenchmarkChanProdConsWork10(b *testing.B) {
-	benchmarkChanProdCons(b, 10, 100)
-}
-
-func BenchmarkChanProdConsWork100(b *testing.B) {
-	benchmarkChanProdCons(b, 100, 100)
-}
-
-func BenchmarkSelectProdCons(b *testing.B) {
-	const CallsPerSched = 1000
-	procs := runtime.GOMAXPROCS(-1)
-	N := int32(b.N / CallsPerSched)
-	c := make(chan bool, 2*procs)
-	myc := make(chan int, 128)
-	myclose := make(chan bool)
-	for p := 0; p < procs; p++ {
-		go func() {
-			// Producer: sends to myc.
-			foo := 0
-			// Intended to not fire during benchmarking.
-			mytimer := time.After(time.Hour)
-			for atomic.AddInt32(&N, -1) >= 0 {
-				for g := 0; g < CallsPerSched; g++ {
-					// Model some local work.
-					for i := 0; i < 100; i++ {
-						foo *= 2
-						foo /= 2
-					}
-					select {
-					case myc <- 1:
-					case <-mytimer:
-					case <-myclose:
-					}
-				}
-			}
-			myc <- 0
-			c <- foo == 42
-		}()
-		go func() {
-			// Consumer: receives from myc.
-			foo := 0
-			// Intended to not fire during benchmarking.
-			mytimer := time.After(time.Hour)
-		loop:
-			for {
-				select {
-				case v := <-myc:
-					if v == 0 {
-						break loop
-					}
-				case <-mytimer:
-				case <-myclose:
-				}
-				// Model some local work.
-				for i := 0; i < 100; i++ {
-					foo *= 2
-					foo /= 2
-				}
-			}
-			c <- foo == 42
-		}()
-	}
-	for p := 0; p < procs; p++ {
-		<-c
-		<-c
-	}
-}
-
-func BenchmarkChanCreation(b *testing.B) {
-	b.RunParallel(func(pb *testing.PB) {
-		for pb.Next() {
-			myc := make(chan int, 1)
-			myc <- 0
-			<-myc
-		}
-	})
-}
-
-func BenchmarkChanSem(b *testing.B) {
-	type Empty struct{}
-	myc := make(chan Empty, runtime.GOMAXPROCS(0))
-	b.RunParallel(func(pb *testing.PB) {
-		for pb.Next() {
-			myc <- Empty{}
-			<-myc
-		}
-	})
-}
diff --git a/src/pkg/runtime/complex.goc b/src/pkg/runtime/complex.goc
deleted file mode 100644
index 40935cf..0000000
--- a/src/pkg/runtime/complex.goc
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package runtime
-#include "runtime.h"
-
-func complex128div(n Complex128, d Complex128) (q Complex128) {
-	int32 ninf, dinf, nnan, dnan;
-	float64 a, b, ratio, denom;
-
-	// Special cases as in C99.
-	ninf = n.real == runtime·posinf || n.real == runtime·neginf ||
-	       n.imag == runtime·posinf || n.imag == runtime·neginf;
-	dinf = d.real == runtime·posinf || d.real == runtime·neginf ||
-	       d.imag == runtime·posinf || d.imag == runtime·neginf;
-
-	nnan = !ninf && (ISNAN(n.real) || ISNAN(n.imag));
-	dnan = !dinf && (ISNAN(d.real) || ISNAN(d.imag));
-
-	if(nnan || dnan) {
-		q.real = runtime·nan;
-		q.imag = runtime·nan;
-	} else if(ninf && !dinf) {
-		q.real = runtime·posinf;
-		q.imag = runtime·posinf;
-	} else if(!ninf && dinf) {
-		q.real = 0;
-		q.imag = 0;
-	} else if(d.real == 0 && d.imag == 0) {
-		if(n.real == 0 && n.imag == 0) {
-			q.real = runtime·nan;
-			q.imag = runtime·nan;
-		} else {
-			q.real = runtime·posinf;
-			q.imag = runtime·posinf;
-		}
-	} else {
-		// Standard complex arithmetic, factored to avoid unnecessary overflow.
-		a = d.real;
-		if(a < 0)
-			a = -a;
-		b = d.imag;
-		if(b < 0)
-			b = -b;
-		if(a <= b) {
-			ratio = d.real/d.imag;
-			denom = d.real*ratio + d.imag;
-			q.real = (n.real*ratio + n.imag) / denom;
-			q.imag = (n.imag*ratio - n.real) / denom;
-		} else {
-			ratio = d.imag/d.real;
-			denom = d.imag*ratio + d.real;
-			q.real = (n.imag*ratio + n.real) / denom;
-			q.imag = (n.imag - n.real*ratio) / denom;
-		}
-	}
-}
diff --git a/src/pkg/runtime/cpuprof.goc b/src/pkg/runtime/cpuprof.goc
deleted file mode 100644
index faaea29..0000000
--- a/src/pkg/runtime/cpuprof.goc
+++ /dev/null
@@ -1,433 +0,0 @@
-// Copyright 2011 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// CPU profiling.
-// Based on algorithms and data structures used in
-// http://code.google.com/p/google-perftools/.
-//
-// The main difference between this code and the google-perftools
-// code is that this code is written to allow copying the profile data
-// to an arbitrary io.Writer, while the google-perftools code always
-// writes to an operating system file.
-//
-// The signal handler for the profiling clock tick adds a new stack trace
-// to a hash table tracking counts for recent traces.  Most clock ticks
-// hit in the cache.  In the event of a cache miss, an entry must be 
-// evicted from the hash table, copied to a log that will eventually be
-// written as profile data.  The google-perftools code flushed the
-// log itself during the signal handler.  This code cannot do that, because
-// the io.Writer might block or need system calls or locks that are not
-// safe to use from within the signal handler.  Instead, we split the log
-// into two halves and let the signal handler fill one half while a goroutine
-// is writing out the other half.  When the signal handler fills its half, it
-// offers to swap with the goroutine.  If the writer is not done with its half,
-// we lose the stack trace for this clock tick (and record that loss).
-// The goroutine interacts with the signal handler by calling getprofile() to
-// get the next log piece to write, implicitly handing back the last log
-// piece it obtained.
-//
-// The state of this dance between the signal handler and the goroutine
-// is encoded in the Profile.handoff field.  If handoff == 0, then the goroutine
-// is not using either log half and is waiting (or will soon be waiting) for
-// a new piece by calling notesleep(&p->wait).  If the signal handler
-// changes handoff from 0 to non-zero, it must call notewakeup(&p->wait)
-// to wake the goroutine.  The value indicates the number of entries in the
-// log half being handed off.  The goroutine leaves the non-zero value in
-// place until it has finished processing the log half and then flips the number
-// back to zero.  Setting the high bit in handoff means that the profiling is over, 
-// and the goroutine is now in charge of flushing the data left in the hash table
-// to the log and returning that data.  
-//
-// The handoff field is manipulated using atomic operations.
-// For the most part, the manipulation of handoff is orderly: if handoff == 0
-// then the signal handler owns it and can change it to non-zero.  
-// If handoff != 0 then the goroutine owns it and can change it to zero.
-// If that were the end of the story then we would not need to manipulate
-// handoff using atomic operations.  The operations are needed, however,
-// in order to let the log closer set the high bit to indicate "EOF" safely
-// in the situation when normally the goroutine "owns" handoff.
-
-package runtime
-#include "runtime.h"
-#include "arch_GOARCH.h"
-#include "malloc.h"
-
-enum
-{
-	HashSize = 1<<10,
-	LogSize = 1<<17,
-	Assoc = 4,
-	MaxStack = 64,
-};
-
-typedef struct Profile Profile;
-typedef struct Bucket Bucket;
-typedef struct Entry Entry;
-
-struct Entry {
-	uintptr count;
-	uintptr depth;
-	uintptr stack[MaxStack];
-};
-
-struct Bucket {
-	Entry entry[Assoc];
-};
-
-struct Profile {
-	bool on;		// profiling is on
-	Note wait;		// goroutine waits here
-	uintptr count;		// tick count
-	uintptr evicts;		// eviction count
-	uintptr lost;		// lost ticks that need to be logged
-
-	// Active recent stack traces.
-	Bucket hash[HashSize];
-
-	// Log of traces evicted from hash.
-	// Signal handler has filled log[toggle][:nlog].
-	// Goroutine is writing log[1-toggle][:handoff].
-	uintptr log[2][LogSize/2];
-	uintptr nlog;
-	int32 toggle;
-	uint32 handoff;
-	
-	// Writer state.
-	// Writer maintains its own toggle to avoid races
-	// looking at signal handler's toggle.
-	uint32 wtoggle;
-	bool wholding;	// holding & need to release a log half
-	bool flushing;	// flushing hash table - profile is over
-	bool eod_sent;  // special end-of-data record sent; => flushing
-};
-
-static Lock lk;
-static Profile *prof;
-
-static void tick(uintptr*, int32);
-static void add(Profile*, uintptr*, int32);
-static bool evict(Profile*, Entry*);
-static bool flushlog(Profile*);
-
-static uintptr eod[3] = {0, 1, 0};
-
-// LostProfileData is a no-op function used in profiles
-// to mark the number of profiling stack traces that were
-// discarded due to slow data writers.
-static void
-LostProfileData(void)
-{
-}
-
-// SetCPUProfileRate sets the CPU profiling rate.
-// The user documentation is in debug.go.
-void
-runtime·SetCPUProfileRate(intgo hz)
-{
-	uintptr *p;
-	uintptr n;
-
-	// Clamp hz to something reasonable.
-	if(hz < 0)
-		hz = 0;
-	if(hz > 1000000)
-		hz = 1000000;
-
-	runtime·lock(&lk);
-	if(hz > 0) {
-		if(prof == nil) {
-			prof = runtime·SysAlloc(sizeof *prof, &mstats.other_sys);
-			if(prof == nil) {
-				runtime·printf("runtime: cpu profiling cannot allocate memory\n");
-				runtime·unlock(&lk);
-				return;
-			}
-		}
-		if(prof->on || prof->handoff != 0) {
-			runtime·printf("runtime: cannot set cpu profile rate until previous profile has finished.\n");
-			runtime·unlock(&lk);
-			return;
-		}
-
-		prof->on = true;
-		p = prof->log[0];
-		// pprof binary header format.
-		// http://code.google.com/p/google-perftools/source/browse/trunk/src/profiledata.cc#117
-		*p++ = 0;  // count for header
-		*p++ = 3;  // depth for header
-		*p++ = 0;  // version number
-		*p++ = 1000000 / hz;  // period (microseconds)
-		*p++ = 0;
-		prof->nlog = p - prof->log[0];
-		prof->toggle = 0;
-		prof->wholding = false;
-		prof->wtoggle = 0;
-		prof->flushing = false;
-		prof->eod_sent = false;
-		runtime·noteclear(&prof->wait);
-
-		runtime·setcpuprofilerate(tick, hz);
-	} else if(prof != nil && prof->on) {
-		runtime·setcpuprofilerate(nil, 0);
-		prof->on = false;
-
-		// Now add is not running anymore, and getprofile owns the entire log.
-		// Set the high bit in prof->handoff to tell getprofile.
-		for(;;) {
-			n = prof->handoff;
-			if(n&0x80000000)
-				runtime·printf("runtime: setcpuprofile(off) twice");
-			if(runtime·cas(&prof->handoff, n, n|0x80000000))
-				break;
-		}
-		if(n == 0) {
-			// we did the transition from 0 -> nonzero so we wake getprofile
-			runtime·notewakeup(&prof->wait);
-		}
-	}
-	runtime·unlock(&lk);
-}
-
-static void
-tick(uintptr *pc, int32 n)
-{
-	add(prof, pc, n);
-}
-
-// add adds the stack trace to the profile.
-// It is called from signal handlers and other limited environments
-// and cannot allocate memory or acquire locks that might be
-// held at the time of the signal, nor can it use substantial amounts
-// of stack.  It is allowed to call evict.
-static void
-add(Profile *p, uintptr *pc, int32 n)
-{
-	int32 i, j;
-	uintptr h, x;
-	Bucket *b;
-	Entry *e;
-
-	if(n > MaxStack)
-		n = MaxStack;
-	
-	// Compute hash.
-	h = 0;
-	for(i=0; i<n; i++) {
-		h = h<<8 | (h>>(8*(sizeof(h)-1)));
-		x = pc[i];
-		h += x*31 + x*7 + x*3;
-	}
-	p->count++;
-
-	// Add to entry count if already present in table.
-	b = &p->hash[h%HashSize];
-	for(i=0; i<Assoc; i++) {
-		e = &b->entry[i];
-		if(e->depth != n)	
-			continue;
-		for(j=0; j<n; j++)
-			if(e->stack[j] != pc[j])
-				goto ContinueAssoc;
-		e->count++;
-		return;
-	ContinueAssoc:;
-	}
-
-	// Evict entry with smallest count.
-	e = &b->entry[0];
-	for(i=1; i<Assoc; i++)
-		if(b->entry[i].count < e->count)
-			e = &b->entry[i];
-	if(e->count > 0) {
-		if(!evict(p, e)) {
-			// Could not evict entry.  Record lost stack.
-			p->lost++;
-			return;
-		}
-		p->evicts++;
-	}
-	
-	// Reuse the newly evicted entry.
-	e->depth = n;
-	e->count = 1;
-	for(i=0; i<n; i++)
-		e->stack[i] = pc[i];
-}
-
-// evict copies the given entry's data into the log, so that
-// the entry can be reused.  evict is called from add, which
-// is called from the profiling signal handler, so it must not
-// allocate memory or block.  It is safe to call flushLog.
-// evict returns true if the entry was copied to the log,
-// false if there was no room available.
-static bool
-evict(Profile *p, Entry *e)
-{
-	int32 i, d, nslot;
-	uintptr *log, *q;
-	
-	d = e->depth;
-	nslot = d+2;
-	log = p->log[p->toggle];
-	if(p->nlog+nslot > nelem(p->log[0])) {
-		if(!flushlog(p))
-			return false;
-		log = p->log[p->toggle];
-	}
-	
-	q = log+p->nlog;
-	*q++ = e->count;
-	*q++ = d;
-	for(i=0; i<d; i++)
-		*q++ = e->stack[i];
-	p->nlog = q - log;
-	e->count = 0;
-	return true;
-}
-
-// flushlog tries to flush the current log and switch to the other one.
-// flushlog is called from evict, called from add, called from the signal handler,
-// so it cannot allocate memory or block.  It can try to swap logs with
-// the writing goroutine, as explained in the comment at the top of this file.
-static bool
-flushlog(Profile *p)
-{
-	uintptr *log, *q;
-
-	if(!runtime·cas(&p->handoff, 0, p->nlog))
-		return false;
-	runtime·notewakeup(&p->wait);
-
-	p->toggle = 1 - p->toggle;
-	log = p->log[p->toggle];
-	q = log;
-	if(p->lost > 0) {
-		*q++ = p->lost;
-		*q++ = 1;
-		*q++ = (uintptr)LostProfileData;
-		p->lost = 0;
-	}
-	p->nlog = q - log;
-	return true;
-}
-
-// getprofile blocks until the next block of profiling data is available
-// and returns it as a []byte.  It is called from the writing goroutine.
-Slice
-getprofile(Profile *p)
-{
-	uint32 i, j, n;
-	Slice ret;
-	Bucket *b;
-	Entry *e;
-
-	ret.array = nil;
-	ret.len = 0;
-	ret.cap = 0;
-	
-	if(p == nil)	
-		return ret;
-
-	if(p->wholding) {
-		// Release previous log to signal handling side.
-		// Loop because we are racing against SetCPUProfileRate(0).
-		for(;;) {
-			n = p->handoff;
-			if(n == 0) {
-				runtime·printf("runtime: phase error during cpu profile handoff\n");
-				return ret;
-			}
-			if(n & 0x80000000) {
-				p->wtoggle = 1 - p->wtoggle;
-				p->wholding = false;
-				p->flushing = true;
-				goto flush;
-			}
-			if(runtime·cas(&p->handoff, n, 0))
-				break;
-		}
-		p->wtoggle = 1 - p->wtoggle;
-		p->wholding = false;
-	}
-	
-	if(p->flushing)
-		goto flush;
-	
-	if(!p->on && p->handoff == 0)
-		return ret;
-
-	// Wait for new log.
-	runtime·notetsleepg(&p->wait, -1);
-	runtime·noteclear(&p->wait);
-
-	n = p->handoff;
-	if(n == 0) {
-		runtime·printf("runtime: phase error during cpu profile wait\n");
-		return ret;
-	}
-	if(n == 0x80000000) {
-		p->flushing = true;
-		goto flush;
-	}
-	n &= ~0x80000000;
-
-	// Return new log to caller.
-	p->wholding = true;
-
-	ret.array = (byte*)p->log[p->wtoggle];
-	ret.len = n*sizeof(uintptr);
-	ret.cap = ret.len;
-	return ret;
-
-flush:
-	// In flush mode.
-	// Add is no longer being called.  We own the log.
-	// Also, p->handoff is non-zero, so flushlog will return false.
-	// Evict the hash table into the log and return it.
-	for(i=0; i<HashSize; i++) {
-		b = &p->hash[i];
-		for(j=0; j<Assoc; j++) {
-			e = &b->entry[j];
-			if(e->count > 0 && !evict(p, e)) {
-				// Filled the log.  Stop the loop and return what we've got.
-				goto breakflush;
-			}
-		}
-	}
-breakflush:
-
-	// Return pending log data.
-	if(p->nlog > 0) {
-		// Note that we're using toggle now, not wtoggle,
-		// because we're working on the log directly.
-		ret.array = (byte*)p->log[p->toggle];
-		ret.len = p->nlog*sizeof(uintptr);
-		ret.cap = ret.len;
-		p->nlog = 0;
-		return ret;
-	}
-
-	// Made it through the table without finding anything to log.
-	if(!p->eod_sent) {
-		// We may not have space to append this to the partial log buf,
-		// so we always return a new slice for the end-of-data marker.
-		p->eod_sent = true;
-		ret.array = (byte*)eod;
-		ret.len = sizeof eod;
-		ret.cap = ret.len;
-		return ret;
-	}
-
-	// Finally done.  Clean up and return nil.
-	p->flushing = false;
-	if(!runtime·cas(&p->handoff, p->handoff, 0))
-		runtime·printf("runtime: profile flush racing with something\n");
-	return ret;  // set to nil at top of function
-}
-
-// CPUProfile returns the next cpu profile block as a []byte.
-// The user documentation is in debug.go.
-func CPUProfile() (ret Slice) {
-	ret = getprofile(prof);
-}
diff --git a/src/pkg/runtime/crash_cgo_test.go b/src/pkg/runtime/crash_cgo_test.go
deleted file mode 100644
index 4ff0084..0000000
--- a/src/pkg/runtime/crash_cgo_test.go
+++ /dev/null
@@ -1,119 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build cgo
-
-package runtime_test
-
-import (
-	"runtime"
-	"testing"
-)
-
-func TestCgoCrashHandler(t *testing.T) {
-	testCrashHandler(t, true)
-}
-
-func TestCgoSignalDeadlock(t *testing.T) {
-	if testing.Short() && runtime.GOOS == "windows" {
-		t.Skip("Skipping in short mode") // takes up to 64 seconds
-	}
-	got := executeTest(t, cgoSignalDeadlockSource, nil)
-	want := "OK\n"
-	if got != want {
-		t.Fatalf("expected %q, but got %q", want, got)
-	}
-}
-
-func TestCgoTraceback(t *testing.T) {
-	got := executeTest(t, cgoTracebackSource, nil)
-	want := "OK\n"
-	if got != want {
-		t.Fatalf("expected %q, but got %q", want, got)
-	}
-}
-
-const cgoSignalDeadlockSource = `
-package main
-
-import "C"
-
-import (
-	"fmt"
-	"runtime"
-	"time"
-)
-
-func main() {
-	runtime.GOMAXPROCS(100)
-	ping := make(chan bool)
-	go func() {
-		for i := 0; ; i++ {
-			runtime.Gosched()
-			select {
-			case done := <-ping:
-				if done {
-					ping <- true
-					return
-				}
-				ping <- true
-			default:
-			}
-			func() {
-				defer func() {
-					recover()
-				}()
-				var s *string
-				*s = ""
-			}()
-		}
-	}()
-	time.Sleep(time.Millisecond)
-	for i := 0; i < 64; i++ {
-		go func() {
-			runtime.LockOSThread()
-			select {}
-		}()
-		go func() {
-			runtime.LockOSThread()
-			select {}
-		}()
-		time.Sleep(time.Millisecond)
-		ping <- false
-		select {
-		case <-ping:
-		case <-time.After(time.Second):
-			fmt.Printf("HANG\n")
-			return
-		}
-	}
-	ping <- true
-	select {
-	case <-ping:
-	case <-time.After(time.Second):
-		fmt.Printf("HANG\n")
-		return
-	}
-	fmt.Printf("OK\n")
-}
-`
-
-const cgoTracebackSource = `
-package main
-
-/* void foo(void) {} */
-import "C"
-
-import (
-	"fmt"
-	"runtime"
-)
-
-func main() {
-	C.foo()
-	buf := make([]byte, 1)
-	runtime.Stack(buf, true)
-	fmt.Printf("OK\n")
-}
-`
diff --git a/src/pkg/runtime/crash_test.go b/src/pkg/runtime/crash_test.go
deleted file mode 100644
index b0277f2..0000000
--- a/src/pkg/runtime/crash_test.go
+++ /dev/null
@@ -1,366 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package runtime_test
-
-import (
-	"io/ioutil"
-	"os"
-	"os/exec"
-	"path/filepath"
-	"runtime"
-	"strings"
-	"testing"
-	"text/template"
-)
-
-// testEnv excludes GODEBUG from the environment
-// to prevent its output from breaking tests that
-// are trying to parse other command output.
-func testEnv(cmd *exec.Cmd) *exec.Cmd {
-	if cmd.Env != nil {
-		panic("environment already set")
-	}
-	for _, env := range os.Environ() {
-		if strings.HasPrefix(env, "GODEBUG=") {
-			continue
-		}
-		cmd.Env = append(cmd.Env, env)
-	}
-	return cmd
-}
-
-func executeTest(t *testing.T, templ string, data interface{}) string {
-	if runtime.GOOS == "nacl" {
-		t.Skip("skipping on nacl")
-	}
-
-	checkStaleRuntime(t)
-
-	st := template.Must(template.New("crashSource").Parse(templ))
-
-	dir, err := ioutil.TempDir("", "go-build")
-	if err != nil {
-		t.Fatalf("failed to create temp directory: %v", err)
-	}
-	defer os.RemoveAll(dir)
-
-	src := filepath.Join(dir, "main.go")
-	f, err := os.Create(src)
-	if err != nil {
-		t.Fatalf("failed to create file: %v", err)
-	}
-	err = st.Execute(f, data)
-	if err != nil {
-		f.Close()
-		t.Fatalf("failed to execute template: %v", err)
-	}
-	if err := f.Close(); err != nil {
-		t.Fatalf("failed to close file: %v", err)
-	}
-
-	got, _ := testEnv(exec.Command("go", "run", src)).CombinedOutput()
-	return string(got)
-}
-
-func checkStaleRuntime(t *testing.T) {
-	// 'go run' uses the installed copy of runtime.a, which may be out of date.
-	out, err := testEnv(exec.Command("go", "list", "-f", "{{.Stale}}", "runtime")).CombinedOutput()
-	if err != nil {
-		t.Fatalf("failed to execute 'go list': %v\n%v", err, string(out))
-	}
-	if string(out) != "false\n" {
-		t.Fatalf("Stale runtime.a. Run 'go install runtime'.")
-	}
-}
-
-func testCrashHandler(t *testing.T, cgo bool) {
-	type crashTest struct {
-		Cgo bool
-	}
-	output := executeTest(t, crashSource, &crashTest{Cgo: cgo})
-	want := "main: recovered done\nnew-thread: recovered done\nsecond-new-thread: recovered done\nmain-again: recovered done\n"
-	if output != want {
-		t.Fatalf("output:\n%s\n\nwanted:\n%s", output, want)
-	}
-}
-
-func TestCrashHandler(t *testing.T) {
-	testCrashHandler(t, false)
-}
-
-func testDeadlock(t *testing.T, source string) {
-	output := executeTest(t, source, nil)
-	want := "fatal error: all goroutines are asleep - deadlock!\n"
-	if !strings.HasPrefix(output, want) {
-		t.Fatalf("output does not start with %q:\n%s", want, output)
-	}
-}
-
-func TestSimpleDeadlock(t *testing.T) {
-	testDeadlock(t, simpleDeadlockSource)
-}
-
-func TestInitDeadlock(t *testing.T) {
-	testDeadlock(t, initDeadlockSource)
-}
-
-func TestLockedDeadlock(t *testing.T) {
-	testDeadlock(t, lockedDeadlockSource)
-}
-
-func TestLockedDeadlock2(t *testing.T) {
-	testDeadlock(t, lockedDeadlockSource2)
-}
-
-func TestGoexitDeadlock(t *testing.T) {
-	output := executeTest(t, goexitDeadlockSource, nil)
-	want := "no goroutines (main called runtime.Goexit) - deadlock!"
-	if !strings.Contains(output, want) {
-		t.Fatalf("output:\n%s\n\nwant output containing: %s", output, want)
-	}
-}
-
-func TestStackOverflow(t *testing.T) {
-	output := executeTest(t, stackOverflowSource, nil)
-	want := "runtime: goroutine stack exceeds 4194304-byte limit\nfatal error: stack overflow"
-	if !strings.HasPrefix(output, want) {
-		t.Fatalf("output does not start with %q:\n%s", want, output)
-	}
-}
-
-func TestThreadExhaustion(t *testing.T) {
-	output := executeTest(t, threadExhaustionSource, nil)
-	want := "runtime: program exceeds 10-thread limit\nfatal error: thread exhaustion"
-	if !strings.HasPrefix(output, want) {
-		t.Fatalf("output does not start with %q:\n%s", want, output)
-	}
-}
-
-func TestRecursivePanic(t *testing.T) {
-	output := executeTest(t, recursivePanicSource, nil)
-	want := `wrap: bad
-panic: again
-
-`
-	if !strings.HasPrefix(output, want) {
-		t.Fatalf("output does not start with %q:\n%s", want, output)
-	}
-
-}
-
-func TestGoexitCrash(t *testing.T) {
-	output := executeTest(t, goexitExitSource, nil)
-	want := "no goroutines (main called runtime.Goexit) - deadlock!"
-	if !strings.Contains(output, want) {
-		t.Fatalf("output:\n%s\n\nwant output containing: %s", output, want)
-	}
-}
-
-func TestGoNil(t *testing.T) {
-	output := executeTest(t, goNilSource, nil)
-	want := "go of nil func value"
-	if !strings.Contains(output, want) {
-		t.Fatalf("output:\n%s\n\nwant output containing: %s", output, want)
-	}
-}
-
-const crashSource = `
-package main
-
-import (
-	"fmt"
-	"runtime"
-)
-
-{{if .Cgo}}
-import "C"
-{{end}}
-
-func test(name string) {
-	defer func() {
-		if x := recover(); x != nil {
-			fmt.Printf(" recovered")
-		}
-		fmt.Printf(" done\n")
-	}()
-	fmt.Printf("%s:", name)
-	var s *string
-	_ = *s
-	fmt.Print("SHOULD NOT BE HERE")
-}
-
-func testInNewThread(name string) {
-	c := make(chan bool)
-	go func() {
-		runtime.LockOSThread()
-		test(name)
-		c <- true
-	}()
-	<-c
-}
-
-func main() {
-	runtime.LockOSThread()
-	test("main")
-	testInNewThread("new-thread")
-	testInNewThread("second-new-thread")
-	test("main-again")
-}
-`
-
-const simpleDeadlockSource = `
-package main
-func main() {
-	select {}
-}
-`
-
-const initDeadlockSource = `
-package main
-func init() {
-	select {}
-}
-func main() {
-}
-`
-
-const lockedDeadlockSource = `
-package main
-import "runtime"
-func main() {
-	runtime.LockOSThread()
-	select {}
-}
-`
-
-const lockedDeadlockSource2 = `
-package main
-import (
-	"runtime"
-	"time"
-)
-func main() {
-	go func() {
-		runtime.LockOSThread()
-		select {}
-	}()
-	time.Sleep(time.Millisecond)
-	select {}
-}
-`
-
-const goexitDeadlockSource = `
-package main
-import (
-      "runtime"
-)
-
-func F() {
-      for i := 0; i < 10; i++ {
-      }
-}
-
-func main() {
-      go F()
-      go F()
-      runtime.Goexit()
-}
-`
-
-const stackOverflowSource = `
-package main
-
-import "runtime/debug"
-
-func main() {
-	debug.SetMaxStack(4<<20)
-	f(make([]byte, 10))
-}
-
-func f(x []byte) byte {
-	var buf [64<<10]byte
-	return x[0] + f(buf[:])
-}
-`
-
-const threadExhaustionSource = `
-package main
-
-import (
-	"runtime"
-	"runtime/debug"
-)
-
-func main() {
-	debug.SetMaxThreads(10)
-	c := make(chan int)
-	for i := 0; i < 100; i++ {
-		go func() {
-			runtime.LockOSThread()
-			c <- 0
-			select{}
-		}()
-		<-c
-	}
-}
-`
-
-const recursivePanicSource = `
-package main
-
-import (
-	"fmt"
-)
-
-func main() {
-	func() {
-		defer func() {
-			fmt.Println(recover())
-		}()
-		var x [8192]byte
-		func(x [8192]byte) {
-			defer func() {
-				if err := recover(); err != nil {
-					panic("wrap: " + err.(string))
-				}
-			}()
-			panic("bad")
-		}(x)
-	}()
-	panic("again")
-}
-`
-
-const goexitExitSource = `
-package main
-
-import (
-	"runtime"
-	"time"
-)
-
-func main() {
-	go func() {
-		time.Sleep(time.Millisecond)
-	}()
-	i := 0
-	runtime.SetFinalizer(&i, func(p *int) {})
-	runtime.GC()
-	runtime.Goexit()
-}
-`
-
-const goNilSource = `
-package main
-
-func main() {
-	defer func() {
-		recover()
-	}()
-	var f func()
-	go f()
-	select{}
-}
-`
diff --git a/src/pkg/runtime/debug.go b/src/pkg/runtime/debug.go
deleted file mode 100644
index d82afb0..0000000
--- a/src/pkg/runtime/debug.go
+++ /dev/null
@@ -1,172 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package runtime
-
-// Breakpoint executes a breakpoint trap.
-func Breakpoint()
-
-// LockOSThread wires the calling goroutine to its current operating system thread.
-// Until the calling goroutine exits or calls UnlockOSThread, it will always
-// execute in that thread, and no other goroutine can.
-func LockOSThread()
-
-// UnlockOSThread unwires the calling goroutine from its fixed operating system thread.
-// If the calling goroutine has not called LockOSThread, UnlockOSThread is a no-op.
-func UnlockOSThread()
-
-// GOMAXPROCS sets the maximum number of CPUs that can be executing
-// simultaneously and returns the previous setting.  If n < 1, it does not
-// change the current setting.
-// The number of logical CPUs on the local machine can be queried with NumCPU.
-// This call will go away when the scheduler improves.
-func GOMAXPROCS(n int) int
-
-// NumCPU returns the number of logical CPUs on the local machine.
-func NumCPU() int
-
-// NumCgoCall returns the number of cgo calls made by the current process.
-func NumCgoCall() int64
-
-// NumGoroutine returns the number of goroutines that currently exist.
-func NumGoroutine() int
-
-// MemProfileRate controls the fraction of memory allocations
-// that are recorded and reported in the memory profile.
-// The profiler aims to sample an average of
-// one allocation per MemProfileRate bytes allocated.
-//
-// To include every allocated block in the profile, set MemProfileRate to 1.
-// To turn off profiling entirely, set MemProfileRate to 0.
-//
-// The tools that process the memory profiles assume that the
-// profile rate is constant across the lifetime of the program
-// and equal to the current value.  Programs that change the
-// memory profiling rate should do so just once, as early as
-// possible in the execution of the program (for example,
-// at the beginning of main).
-var MemProfileRate int = 512 * 1024
-
-// A MemProfileRecord describes the live objects allocated
-// by a particular call sequence (stack trace).
-type MemProfileRecord struct {
-	AllocBytes, FreeBytes     int64       // number of bytes allocated, freed
-	AllocObjects, FreeObjects int64       // number of objects allocated, freed
-	Stack0                    [32]uintptr // stack trace for this record; ends at first 0 entry
-}
-
-// InUseBytes returns the number of bytes in use (AllocBytes - FreeBytes).
-func (r *MemProfileRecord) InUseBytes() int64 { return r.AllocBytes - r.FreeBytes }
-
-// InUseObjects returns the number of objects in use (AllocObjects - FreeObjects).
-func (r *MemProfileRecord) InUseObjects() int64 {
-	return r.AllocObjects - r.FreeObjects
-}
-
-// Stack returns the stack trace associated with the record,
-// a prefix of r.Stack0.
-func (r *MemProfileRecord) Stack() []uintptr {
-	for i, v := range r.Stack0 {
-		if v == 0 {
-			return r.Stack0[0:i]
-		}
-	}
-	return r.Stack0[0:]
-}
-
-// MemProfile returns n, the number of records in the current memory profile.
-// If len(p) >= n, MemProfile copies the profile into p and returns n, true.
-// If len(p) < n, MemProfile does not change p and returns n, false.
-//
-// If inuseZero is true, the profile includes allocation records
-// where r.AllocBytes > 0 but r.AllocBytes == r.FreeBytes.
-// These are sites where memory was allocated, but it has all
-// been released back to the runtime.
-//
-// Most clients should use the runtime/pprof package or
-// the testing package's -test.memprofile flag instead
-// of calling MemProfile directly.
-func MemProfile(p []MemProfileRecord, inuseZero bool) (n int, ok bool)
-
-// A StackRecord describes a single execution stack.
-type StackRecord struct {
-	Stack0 [32]uintptr // stack trace for this record; ends at first 0 entry
-}
-
-// Stack returns the stack trace associated with the record,
-// a prefix of r.Stack0.
-func (r *StackRecord) Stack() []uintptr {
-	for i, v := range r.Stack0 {
-		if v == 0 {
-			return r.Stack0[0:i]
-		}
-	}
-	return r.Stack0[0:]
-}
-
-// ThreadCreateProfile returns n, the number of records in the thread creation profile.
-// If len(p) >= n, ThreadCreateProfile copies the profile into p and returns n, true.
-// If len(p) < n, ThreadCreateProfile does not change p and returns n, false.
-//
-// Most clients should use the runtime/pprof package instead
-// of calling ThreadCreateProfile directly.
-func ThreadCreateProfile(p []StackRecord) (n int, ok bool)
-
-// GoroutineProfile returns n, the number of records in the active goroutine stack profile.
-// If len(p) >= n, GoroutineProfile copies the profile into p and returns n, true.
-// If len(p) < n, GoroutineProfile does not change p and returns n, false.
-//
-// Most clients should use the runtime/pprof package instead
-// of calling GoroutineProfile directly.
-func GoroutineProfile(p []StackRecord) (n int, ok bool)
-
-// CPUProfile returns the next chunk of binary CPU profiling stack trace data,
-// blocking until data is available.  If profiling is turned off and all the profile
-// data accumulated while it was on has been returned, CPUProfile returns nil.
-// The caller must save the returned data before calling CPUProfile again.
-//
-// Most clients should use the runtime/pprof package or
-// the testing package's -test.cpuprofile flag instead of calling
-// CPUProfile directly.
-func CPUProfile() []byte
-
-// SetCPUProfileRate sets the CPU profiling rate to hz samples per second.
-// If hz <= 0, SetCPUProfileRate turns off profiling.
-// If the profiler is on, the rate cannot be changed without first turning it off.
-//
-// Most clients should use the runtime/pprof package or
-// the testing package's -test.cpuprofile flag instead of calling
-// SetCPUProfileRate directly.
-func SetCPUProfileRate(hz int)
-
-// SetBlockProfileRate controls the fraction of goroutine blocking events
-// that are reported in the blocking profile.  The profiler aims to sample
-// an average of one blocking event per rate nanoseconds spent blocked.
-//
-// To include every blocking event in the profile, pass rate = 1.
-// To turn off profiling entirely, pass rate <= 0.
-func SetBlockProfileRate(rate int)
-
-// BlockProfileRecord describes blocking events originated
-// at a particular call sequence (stack trace).
-type BlockProfileRecord struct {
-	Count  int64
-	Cycles int64
-	StackRecord
-}
-
-// BlockProfile returns n, the number of records in the current blocking profile.
-// If len(p) >= n, BlockProfile copies the profile into p and returns n, true.
-// If len(p) < n, BlockProfile does not change p and returns n, false.
-//
-// Most clients should use the runtime/pprof package or
-// the testing package's -test.blockprofile flag instead
-// of calling BlockProfile directly.
-func BlockProfile(p []BlockProfileRecord) (n int, ok bool)
-
-// Stack formats a stack trace of the calling goroutine into buf
-// and returns the number of bytes written to buf.
-// If all is true, Stack formats stack traces of all other goroutines
-// into buf after the trace for the current goroutine.
-func Stack(buf []byte, all bool) int
diff --git a/src/pkg/runtime/debug/garbage.go b/src/pkg/runtime/debug/garbage.go
deleted file mode 100644
index edb3643..0000000
--- a/src/pkg/runtime/debug/garbage.go
+++ /dev/null
@@ -1,153 +0,0 @@
-// Copyright 2013 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package debug
-
-import (
-	"runtime"
-	"sort"
-	"time"
-)
-
-// GCStats collect information about recent garbage collections.
-type GCStats struct {
-	LastGC         time.Time       // time of last collection
-	NumGC          int64           // number of garbage collections
-	PauseTotal     time.Duration   // total pause for all collections
-	Pause          []time.Duration // pause history, most recent first
-	PauseQuantiles []time.Duration
-}
-
-// Implemented in package runtime.
-func readGCStats(*[]time.Duration)
-func enableGC(bool) bool
-func setGCPercent(int) int
-func freeOSMemory()
-func setMaxStack(int) int
-func setMaxThreads(int) int
-
-// ReadGCStats reads statistics about garbage collection into stats.
-// The number of entries in the pause history is system-dependent;
-// stats.Pause slice will be reused if large enough, reallocated otherwise.
-// ReadGCStats may use the full capacity of the stats.Pause slice.
-// If stats.PauseQuantiles is non-empty, ReadGCStats fills it with quantiles
-// summarizing the distribution of pause time. For example, if
-// len(stats.PauseQuantiles) is 5, it will be filled with the minimum,
-// 25%, 50%, 75%, and maximum pause times.
-func ReadGCStats(stats *GCStats) {
-	// Create a buffer with space for at least two copies of the
-	// pause history tracked by the runtime. One will be returned
-	// to the caller and the other will be used as a temporary buffer
-	// for computing quantiles.
-	const maxPause = len(((*runtime.MemStats)(nil)).PauseNs)
-	if cap(stats.Pause) < 2*maxPause {
-		stats.Pause = make([]time.Duration, 2*maxPause)
-	}
-
-	// readGCStats fills in the pause history (up to maxPause entries)
-	// and then three more: Unix ns time of last GC, number of GC,
-	// and total pause time in nanoseconds. Here we depend on the
-	// fact that time.Duration's native unit is nanoseconds, so the
-	// pauses and the total pause time do not need any conversion.
-	readGCStats(&stats.Pause)
-	n := len(stats.Pause) - 3
-	stats.LastGC = time.Unix(0, int64(stats.Pause[n]))
-	stats.NumGC = int64(stats.Pause[n+1])
-	stats.PauseTotal = stats.Pause[n+2]
-	stats.Pause = stats.Pause[:n]
-
-	if len(stats.PauseQuantiles) > 0 {
-		if n == 0 {
-			for i := range stats.PauseQuantiles {
-				stats.PauseQuantiles[i] = 0
-			}
-		} else {
-			// There's room for a second copy of the data in stats.Pause.
-			// See the allocation at the top of the function.
-			sorted := stats.Pause[n : n+n]
-			copy(sorted, stats.Pause)
-			sort.Sort(byDuration(sorted))
-			nq := len(stats.PauseQuantiles) - 1
-			for i := 0; i < nq; i++ {
-				stats.PauseQuantiles[i] = sorted[len(sorted)*i/nq]
-			}
-			stats.PauseQuantiles[nq] = sorted[len(sorted)-1]
-		}
-	}
-}
-
-type byDuration []time.Duration
-
-func (x byDuration) Len() int           { return len(x) }
-func (x byDuration) Swap(i, j int)      { x[i], x[j] = x[j], x[i] }
-func (x byDuration) Less(i, j int) bool { return x[i] < x[j] }
-
-// SetGCPercent sets the garbage collection target percentage:
-// a collection is triggered when the ratio of freshly allocated data
-// to live data remaining after the previous collection reaches this percentage.
-// SetGCPercent returns the previous setting.
-// The initial setting is the value of the GOGC environment variable
-// at startup, or 100 if the variable is not set.
-// A negative percentage disables garbage collection.
-func SetGCPercent(percent int) int {
-	old := setGCPercent(percent)
-	runtime.GC()
-	return old
-}
-
-// FreeOSMemory forces a garbage collection followed by an
-// attempt to return as much memory to the operating system
-// as possible. (Even if this is not called, the runtime gradually
-// returns memory to the operating system in a background task.)
-func FreeOSMemory() {
-	freeOSMemory()
-}
-
-// SetMaxStack sets the maximum amount of memory that
-// can be used by a single goroutine stack.
-// If any goroutine exceeds this limit while growing its stack,
-// the program crashes.
-// SetMaxStack returns the previous setting.
-// The initial setting is 1 GB on 64-bit systems, 250 MB on 32-bit systems.
-//
-// SetMaxStack is useful mainly for limiting the damage done by
-// goroutines that enter an infinite recursion. It only limits future
-// stack growth.
-func SetMaxStack(bytes int) int {
-	return setMaxStack(bytes)
-}
-
-// SetMaxThreads sets the maximum number of operating system
-// threads that the Go program can use. If it attempts to use more than
-// this many, the program crashes.
-// SetMaxThreads returns the previous setting.
-// The initial setting is 10,000 threads.
-//
-// The limit controls the number of operating system threads, not the number
-// of goroutines. A Go program creates a new thread only when a goroutine
-// is ready to run but all the existing threads are blocked in system calls, cgo calls,
-// or are locked to other goroutines due to use of runtime.LockOSThread.
-//
-// SetMaxThreads is useful mainly for limiting the damage done by
-// programs that create an unbounded number of threads. The idea is
-// to take down the program before it takes down the operating system.
-func SetMaxThreads(threads int) int {
-	return setMaxThreads(threads)
-}
-
-// SetPanicOnFault controls the runtime's behavior when a program faults
-// at an unexpected (non-nil) address. Such faults are typically caused by
-// bugs such as runtime memory corruption, so the default response is to crash
-// the program. Programs working with memory-mapped files or unsafe
-// manipulation of memory may cause faults at non-nil addresses in less
-// dramatic situations; SetPanicOnFault allows such programs to request
-// that the runtime trigger only a panic, not a crash.
-// SetPanicOnFault applies only to the current goroutine.
-// It returns the previous setting.
-func SetPanicOnFault(enabled bool) bool
-
-// WriteHeapDump writes a description of the heap and the objects in
-// it to the given file descriptor.
-// The heap dump format is defined at http://golang.org/s/go13heapdump.
-func WriteHeapDump(fd uintptr)
diff --git a/src/pkg/runtime/debug/garbage_test.go b/src/pkg/runtime/debug/garbage_test.go
deleted file mode 100644
index 149bafc..0000000
--- a/src/pkg/runtime/debug/garbage_test.go
+++ /dev/null
@@ -1,102 +0,0 @@
-// Copyright 2013 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package debug
-
-import (
-	"runtime"
-	"testing"
-	"time"
-)
-
-func TestReadGCStats(t *testing.T) {
-	defer SetGCPercent(SetGCPercent(-1))
-
-	var stats GCStats
-	var mstats runtime.MemStats
-	var min, max time.Duration
-
-	// First ReadGCStats will allocate, second should not,
-	// especially if we follow up with an explicit garbage collection.
-	stats.PauseQuantiles = make([]time.Duration, 10)
-	ReadGCStats(&stats)
-	runtime.GC()
-
-	// Assume these will return same data: no GC during ReadGCStats.
-	ReadGCStats(&stats)
-	runtime.ReadMemStats(&mstats)
-
-	if stats.NumGC != int64(mstats.NumGC) {
-		t.Errorf("stats.NumGC = %d, but mstats.NumGC = %d", stats.NumGC, mstats.NumGC)
-	}
-	if stats.PauseTotal != time.Duration(mstats.PauseTotalNs) {
-		t.Errorf("stats.PauseTotal = %d, but mstats.PauseTotalNs = %d", stats.PauseTotal, mstats.PauseTotalNs)
-	}
-	if stats.LastGC.UnixNano() != int64(mstats.LastGC) {
-		t.Errorf("stats.LastGC.UnixNano = %d, but mstats.LastGC = %d", stats.LastGC.UnixNano(), mstats.LastGC)
-	}
-	n := int(mstats.NumGC)
-	if n > len(mstats.PauseNs) {
-		n = len(mstats.PauseNs)
-	}
-	if len(stats.Pause) != n {
-		t.Errorf("len(stats.Pause) = %d, want %d", len(stats.Pause), n)
-	} else {
-		off := (int(mstats.NumGC) + len(mstats.PauseNs) - 1) % len(mstats.PauseNs)
-		for i := 0; i < n; i++ {
-			dt := stats.Pause[i]
-			if dt != time.Duration(mstats.PauseNs[off]) {
-				t.Errorf("stats.Pause[%d] = %d, want %d", i, dt, mstats.PauseNs[off])
-			}
-			if max < dt {
-				max = dt
-			}
-			if min > dt || i == 0 {
-				min = dt
-			}
-			off = (off + len(mstats.PauseNs) - 1) % len(mstats.PauseNs)
-		}
-	}
-
-	q := stats.PauseQuantiles
-	nq := len(q)
-	if q[0] != min || q[nq-1] != max {
-		t.Errorf("stats.PauseQuantiles = [%d, ..., %d], want [%d, ..., %d]", q[0], q[nq-1], min, max)
-	}
-
-	for i := 0; i < nq-1; i++ {
-		if q[i] > q[i+1] {
-			t.Errorf("stats.PauseQuantiles[%d]=%d > stats.PauseQuantiles[%d]=%d", i, q[i], i+1, q[i+1])
-		}
-	}
-}
-
-var big = make([]byte, 1<<20)
-
-func TestFreeOSMemory(t *testing.T) {
-	var ms1, ms2 runtime.MemStats
-
-	if big == nil {
-		t.Skip("test is not reliable when run multiple times")
-	}
-	big = nil
-	runtime.GC()
-	runtime.ReadMemStats(&ms1)
-	FreeOSMemory()
-	runtime.ReadMemStats(&ms2)
-	if ms1.HeapReleased >= ms2.HeapReleased {
-		t.Errorf("released before=%d; released after=%d; did not go up", ms1.HeapReleased, ms2.HeapReleased)
-	}
-}
-
-func TestSetGCPercent(t *testing.T) {
-	// Test that the variable is being set and returned correctly.
-	// Assume the percentage itself is implemented fine during GC,
-	// which is harder to test.
-	old := SetGCPercent(123)
-	new := SetGCPercent(old)
-	if new != 123 {
-		t.Errorf("SetGCPercent(123); SetGCPercent(x) = %d, want 123", new)
-	}
-}
diff --git a/src/pkg/runtime/debug/stack_test.go b/src/pkg/runtime/debug/stack_test.go
deleted file mode 100644
index bbd6626..0000000
--- a/src/pkg/runtime/debug/stack_test.go
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package debug
-
-import (
-	"strings"
-	"testing"
-)
-
-type T int
-
-func (t *T) ptrmethod() []byte {
-	return Stack()
-}
-func (t T) method() []byte {
-	return t.ptrmethod()
-}
-
-/*
-	The traceback should look something like this, modulo line numbers and hex constants.
-	Don't worry much about the base levels, but check the ones in our own package.
-
-		/Users/r/go/src/pkg/runtime/debug/stack_test.go:15 (0x13878)
-			(*T).ptrmethod: return Stack()
-		/Users/r/go/src/pkg/runtime/debug/stack_test.go:18 (0x138dd)
-			T.method: return t.ptrmethod()
-		/Users/r/go/src/pkg/runtime/debug/stack_test.go:23 (0x13920)
-			TestStack: b := T(0).method()
-		/Users/r/go/src/pkg/testing/testing.go:132 (0x14a7a)
-			tRunner: test.F(t)
-		/Users/r/go/src/pkg/runtime/proc.c:145 (0xc970)
-			???: runtime·unlock(&runtime·sched);
-*/
-func TestStack(t *testing.T) {
-	b := T(0).method()
-	lines := strings.Split(string(b), "\n")
-	if len(lines) < 6 {
-		t.Fatal("too few lines")
-	}
-	n := 0
-	frame := func(line, code string) {
-		check(t, lines[n], line)
-		n++
-		// The source might not be available while running the test.
-		if strings.HasPrefix(lines[n], "\t") {
-			check(t, lines[n], code)
-			n++
-		}
-	}
-	frame("src/pkg/runtime/debug/stack_test.go", "\t(*T).ptrmethod: return Stack()")
-	frame("src/pkg/runtime/debug/stack_test.go", "\tT.method: return t.ptrmethod()")
-	frame("src/pkg/runtime/debug/stack_test.go", "\tTestStack: b := T(0).method()")
-	frame("src/pkg/testing/testing.go", "")
-}
-
-func check(t *testing.T, line, has string) {
-	if strings.Index(line, has) < 0 {
-		t.Errorf("expected %q in %q", has, line)
-	}
-}
diff --git a/src/pkg/runtime/defs.c b/src/pkg/runtime/defs.c
deleted file mode 100644
index 1c76198..0000000
--- a/src/pkg/runtime/defs.c
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2013 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// This file is compiled by cmd/dist to obtain debug information
-// about the given header files.
-
-#include "runtime.h"
-#include "arch_GOARCH.h"
-#include "malloc.h"
-#include "type.h"
-#include "race.h"
-#include "hashmap.h"
-#include "chan.h"
diff --git a/src/pkg/runtime/defs1_linux.go b/src/pkg/runtime/defs1_linux.go
deleted file mode 100644
index 451817a..0000000
--- a/src/pkg/runtime/defs1_linux.go
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build ignore
-
-/*
-Input to cgo -cdefs
-
-GOARCH=amd64 cgo -cdefs defs.go defs1.go >amd64/defs.h
-*/
-
-package runtime
-
-/*
-#include <ucontext.h>
-#include <fcntl.h>
-*/
-import "C"
-
-const (
-	O_RDONLY  = C.O_RDONLY
-	O_CLOEXEC = C.O_CLOEXEC
-)
-
-type Usigset C.__sigset_t
-type Fpxreg C.struct__libc_fpxreg
-type Xmmreg C.struct__libc_xmmreg
-type Fpstate C.struct__libc_fpstate
-type Fpxreg1 C.struct__fpxreg
-type Xmmreg1 C.struct__xmmreg
-type Fpstate1 C.struct__fpstate
-type Fpreg1 C.struct__fpreg
-type Sigaltstack C.struct_sigaltstack
-type Mcontext C.mcontext_t
-type Ucontext C.ucontext_t
-type Sigcontext C.struct_sigcontext
diff --git a/src/pkg/runtime/defs2_linux.go b/src/pkg/runtime/defs2_linux.go
deleted file mode 100644
index 60ecc69..0000000
--- a/src/pkg/runtime/defs2_linux.go
+++ /dev/null
@@ -1,146 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build ignore
-
-/*
- * Input to cgo -cdefs
-
-GOARCH=386 go tool cgo -cdefs defs2_linux.go >defs_linux_386.h
-
-The asm header tricks we have to use for Linux on amd64
-(see defs.c and defs1.c) don't work here, so this is yet another
-file.  Sigh.
-*/
-
-package runtime
-
-/*
-#cgo CFLAGS: -I/tmp/linux/arch/x86/include -I/tmp/linux/include -D_LOOSE_KERNEL_NAMES -D__ARCH_SI_UID_T=__kernel_uid32_t
-
-#define size_t __kernel_size_t
-#define pid_t int
-#include <asm/signal.h>
-#include <asm/mman.h>
-#include <asm/sigcontext.h>
-#include <asm/ucontext.h>
-#include <asm/siginfo.h>
-#include <asm-generic/errno.h>
-#include <asm-generic/fcntl.h>
-#include <asm-generic/poll.h>
-#include <linux/eventpoll.h>
-
-// This is the sigaction structure from the Linux 2.1.68 kernel which
-//   is used with the rt_sigaction system call.  For 386 this is not
-//   defined in any public header file.
-
-struct kernel_sigaction {
-	__sighandler_t k_sa_handler;
-	unsigned long sa_flags;
-	void (*sa_restorer) (void);
-	unsigned long long sa_mask;
-};
-*/
-import "C"
-
-const (
-	EINTR  = C.EINTR
-	EAGAIN = C.EAGAIN
-	ENOMEM = C.ENOMEM
-
-	PROT_NONE  = C.PROT_NONE
-	PROT_READ  = C.PROT_READ
-	PROT_WRITE = C.PROT_WRITE
-	PROT_EXEC  = C.PROT_EXEC
-
-	MAP_ANON    = C.MAP_ANONYMOUS
-	MAP_PRIVATE = C.MAP_PRIVATE
-	MAP_FIXED   = C.MAP_FIXED
-
-	MADV_DONTNEED = C.MADV_DONTNEED
-
-	SA_RESTART  = C.SA_RESTART
-	SA_ONSTACK  = C.SA_ONSTACK
-	SA_RESTORER = C.SA_RESTORER
-	SA_SIGINFO  = C.SA_SIGINFO
-
-	SIGHUP    = C.SIGHUP
-	SIGINT    = C.SIGINT
-	SIGQUIT   = C.SIGQUIT
-	SIGILL    = C.SIGILL
-	SIGTRAP   = C.SIGTRAP
-	SIGABRT   = C.SIGABRT
-	SIGBUS    = C.SIGBUS
-	SIGFPE    = C.SIGFPE
-	SIGKILL   = C.SIGKILL
-	SIGUSR1   = C.SIGUSR1
-	SIGSEGV   = C.SIGSEGV
-	SIGUSR2   = C.SIGUSR2
-	SIGPIPE   = C.SIGPIPE
-	SIGALRM   = C.SIGALRM
-	SIGSTKFLT = C.SIGSTKFLT
-	SIGCHLD   = C.SIGCHLD
-	SIGCONT   = C.SIGCONT
-	SIGSTOP   = C.SIGSTOP
-	SIGTSTP   = C.SIGTSTP
-	SIGTTIN   = C.SIGTTIN
-	SIGTTOU   = C.SIGTTOU
-	SIGURG    = C.SIGURG
-	SIGXCPU   = C.SIGXCPU
-	SIGXFSZ   = C.SIGXFSZ
-	SIGVTALRM = C.SIGVTALRM
-	SIGPROF   = C.SIGPROF
-	SIGWINCH  = C.SIGWINCH
-	SIGIO     = C.SIGIO
-	SIGPWR    = C.SIGPWR
-	SIGSYS    = C.SIGSYS
-
-	FPE_INTDIV = C.FPE_INTDIV
-	FPE_INTOVF = C.FPE_INTOVF
-	FPE_FLTDIV = C.FPE_FLTDIV
-	FPE_FLTOVF = C.FPE_FLTOVF
-	FPE_FLTUND = C.FPE_FLTUND
-	FPE_FLTRES = C.FPE_FLTRES
-	FPE_FLTINV = C.FPE_FLTINV
-	FPE_FLTSUB = C.FPE_FLTSUB
-
-	BUS_ADRALN = C.BUS_ADRALN
-	BUS_ADRERR = C.BUS_ADRERR
-	BUS_OBJERR = C.BUS_OBJERR
-
-	SEGV_MAPERR = C.SEGV_MAPERR
-	SEGV_ACCERR = C.SEGV_ACCERR
-
-	ITIMER_REAL    = C.ITIMER_REAL
-	ITIMER_VIRTUAL = C.ITIMER_VIRTUAL
-	ITIMER_PROF    = C.ITIMER_PROF
-
-	O_RDONLY  = C.O_RDONLY
-	O_CLOEXEC = C.O_CLOEXEC
-
-	EPOLLIN       = C.POLLIN
-	EPOLLOUT      = C.POLLOUT
-	EPOLLERR      = C.POLLERR
-	EPOLLHUP      = C.POLLHUP
-	EPOLLRDHUP    = C.POLLRDHUP
-	EPOLLET       = C.EPOLLET
-	EPOLL_CLOEXEC = C.EPOLL_CLOEXEC
-	EPOLL_CTL_ADD = C.EPOLL_CTL_ADD
-	EPOLL_CTL_DEL = C.EPOLL_CTL_DEL
-	EPOLL_CTL_MOD = C.EPOLL_CTL_MOD
-)
-
-type Fpreg C.struct__fpreg
-type Fpxreg C.struct__fpxreg
-type Xmmreg C.struct__xmmreg
-type Fpstate C.struct__fpstate
-type Timespec C.struct_timespec
-type Timeval C.struct_timeval
-type Sigaction C.struct_kernel_sigaction
-type Siginfo C.siginfo_t
-type Sigaltstack C.struct_sigaltstack
-type Sigcontext C.struct_sigcontext
-type Ucontext C.struct_ucontext
-type Itimerval C.struct_itimerval
-type EpollEvent C.struct_epoll_event
diff --git a/src/pkg/runtime/defs_arm_linux.go b/src/pkg/runtime/defs_arm_linux.go
deleted file mode 100644
index db0a191..0000000
--- a/src/pkg/runtime/defs_arm_linux.go
+++ /dev/null
@@ -1,124 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build ignore
-
-/*
-Input to cgo.
-On a Debian Lenny arm linux distribution:
-
-cgo -cdefs defs_arm.c >arm/defs.h
-*/
-
-package runtime
-
-/*
-#cgo CFLAGS: -I/usr/src/linux-headers-2.6.26-2-versatile/include
-
-#define __ARCH_SI_UID_T int
-#include <asm/signal.h>
-#include <asm/mman.h>
-#include <asm/sigcontext.h>
-#include <asm/ucontext.h>
-#include <asm/siginfo.h>
-#include <linux/time.h>
-
-struct xsiginfo {
-	int si_signo;
-	int si_errno;
-	int si_code;
-	char _sifields[4];
-};
-
-#undef sa_handler
-#undef sa_flags
-#undef sa_restorer
-#undef sa_mask
-
-struct xsigaction {
-	void (*sa_handler)(void);
-	unsigned long sa_flags;
-	void (*sa_restorer)(void);
-	unsigned int sa_mask;		// mask last for extensibility
-};
-*/
-import "C"
-
-const (
-	PROT_NONE  = C.PROT_NONE
-	PROT_READ  = C.PROT_READ
-	PROT_WRITE = C.PROT_WRITE
-	PROT_EXEC  = C.PROT_EXEC
-
-	MAP_ANON    = C.MAP_ANONYMOUS
-	MAP_PRIVATE = C.MAP_PRIVATE
-	MAP_FIXED   = C.MAP_FIXED
-
-	MADV_DONTNEED = C.MADV_DONTNEED
-
-	SA_RESTART  = C.SA_RESTART
-	SA_ONSTACK  = C.SA_ONSTACK
-	SA_RESTORER = C.SA_RESTORER
-	SA_SIGINFO  = C.SA_SIGINFO
-
-	SIGHUP    = C.SIGHUP
-	SIGINT    = C.SIGINT
-	SIGQUIT   = C.SIGQUIT
-	SIGILL    = C.SIGILL
-	SIGTRAP   = C.SIGTRAP
-	SIGABRT   = C.SIGABRT
-	SIGBUS    = C.SIGBUS
-	SIGFPE    = C.SIGFPE
-	SIGKILL   = C.SIGKILL
-	SIGUSR1   = C.SIGUSR1
-	SIGSEGV   = C.SIGSEGV
-	SIGUSR2   = C.SIGUSR2
-	SIGPIPE   = C.SIGPIPE
-	SIGALRM   = C.SIGALRM
-	SIGSTKFLT = C.SIGSTKFLT
-	SIGCHLD   = C.SIGCHLD
-	SIGCONT   = C.SIGCONT
-	SIGSTOP   = C.SIGSTOP
-	SIGTSTP   = C.SIGTSTP
-	SIGTTIN   = C.SIGTTIN
-	SIGTTOU   = C.SIGTTOU
-	SIGURG    = C.SIGURG
-	SIGXCPU   = C.SIGXCPU
-	SIGXFSZ   = C.SIGXFSZ
-	SIGVTALRM = C.SIGVTALRM
-	SIGPROF   = C.SIGPROF
-	SIGWINCH  = C.SIGWINCH
-	SIGIO     = C.SIGIO
-	SIGPWR    = C.SIGPWR
-	SIGSYS    = C.SIGSYS
-
-	FPE_INTDIV = C.FPE_INTDIV & 0xFFFF
-	FPE_INTOVF = C.FPE_INTOVF & 0xFFFF
-	FPE_FLTDIV = C.FPE_FLTDIV & 0xFFFF
-	FPE_FLTOVF = C.FPE_FLTOVF & 0xFFFF
-	FPE_FLTUND = C.FPE_FLTUND & 0xFFFF
-	FPE_FLTRES = C.FPE_FLTRES & 0xFFFF
-	FPE_FLTINV = C.FPE_FLTINV & 0xFFFF
-	FPE_FLTSUB = C.FPE_FLTSUB & 0xFFFF
-
-	BUS_ADRALN = C.BUS_ADRALN & 0xFFFF
-	BUS_ADRERR = C.BUS_ADRERR & 0xFFFF
-	BUS_OBJERR = C.BUS_OBJERR & 0xFFFF
-
-	SEGV_MAPERR = C.SEGV_MAPERR & 0xFFFF
-	SEGV_ACCERR = C.SEGV_ACCERR & 0xFFFF
-
-	ITIMER_REAL    = C.ITIMER_REAL
-	ITIMER_PROF    = C.ITIMER_PROF
-	ITIMER_VIRTUAL = C.ITIMER_VIRTUAL
-)
-
-type Timespec C.struct_timespec
-type Sigaltstack C.struct_sigaltstack
-type Sigcontext C.struct_sigcontext
-type Ucontext C.struct_ucontext
-type Timeval C.struct_timeval
-type Itimerval C.struct_itimerval
-type Siginfo C.struct_xsiginfo
-type Sigaction C.struct_xsigaction
diff --git a/src/pkg/runtime/defs_darwin_386.h b/src/pkg/runtime/defs_darwin_386.h
deleted file mode 100644
index 7b210ee..0000000
--- a/src/pkg/runtime/defs_darwin_386.h
+++ /dev/null
@@ -1,392 +0,0 @@
-// Created by cgo -cdefs - DO NOT EDIT
-// cgo -cdefs defs_darwin.go
-
-
-enum {
-	EINTR	= 0x4,
-	EFAULT	= 0xe,
-
-	PROT_NONE	= 0x0,
-	PROT_READ	= 0x1,
-	PROT_WRITE	= 0x2,
-	PROT_EXEC	= 0x4,
-
-	MAP_ANON	= 0x1000,
-	MAP_PRIVATE	= 0x2,
-	MAP_FIXED	= 0x10,
-
-	MADV_DONTNEED	= 0x4,
-	MADV_FREE	= 0x5,
-
-	MACH_MSG_TYPE_MOVE_RECEIVE	= 0x10,
-	MACH_MSG_TYPE_MOVE_SEND		= 0x11,
-	MACH_MSG_TYPE_MOVE_SEND_ONCE	= 0x12,
-	MACH_MSG_TYPE_COPY_SEND		= 0x13,
-	MACH_MSG_TYPE_MAKE_SEND		= 0x14,
-	MACH_MSG_TYPE_MAKE_SEND_ONCE	= 0x15,
-	MACH_MSG_TYPE_COPY_RECEIVE	= 0x16,
-
-	MACH_MSG_PORT_DESCRIPTOR		= 0x0,
-	MACH_MSG_OOL_DESCRIPTOR			= 0x1,
-	MACH_MSG_OOL_PORTS_DESCRIPTOR		= 0x2,
-	MACH_MSG_OOL_VOLATILE_DESCRIPTOR	= 0x3,
-
-	MACH_MSGH_BITS_COMPLEX	= 0x80000000,
-
-	MACH_SEND_MSG	= 0x1,
-	MACH_RCV_MSG	= 0x2,
-	MACH_RCV_LARGE	= 0x4,
-
-	MACH_SEND_TIMEOUT	= 0x10,
-	MACH_SEND_INTERRUPT	= 0x40,
-	MACH_SEND_ALWAYS	= 0x10000,
-	MACH_SEND_TRAILER	= 0x20000,
-	MACH_RCV_TIMEOUT	= 0x100,
-	MACH_RCV_NOTIFY		= 0x200,
-	MACH_RCV_INTERRUPT	= 0x400,
-	MACH_RCV_OVERWRITE	= 0x1000,
-
-	NDR_PROTOCOL_2_0	= 0x0,
-	NDR_INT_BIG_ENDIAN	= 0x0,
-	NDR_INT_LITTLE_ENDIAN	= 0x1,
-	NDR_FLOAT_IEEE		= 0x0,
-	NDR_CHAR_ASCII		= 0x0,
-
-	SA_SIGINFO	= 0x40,
-	SA_RESTART	= 0x2,
-	SA_ONSTACK	= 0x1,
-	SA_USERTRAMP	= 0x100,
-	SA_64REGSET	= 0x200,
-
-	SIGHUP		= 0x1,
-	SIGINT		= 0x2,
-	SIGQUIT		= 0x3,
-	SIGILL		= 0x4,
-	SIGTRAP		= 0x5,
-	SIGABRT		= 0x6,
-	SIGEMT		= 0x7,
-	SIGFPE		= 0x8,
-	SIGKILL		= 0x9,
-	SIGBUS		= 0xa,
-	SIGSEGV		= 0xb,
-	SIGSYS		= 0xc,
-	SIGPIPE		= 0xd,
-	SIGALRM		= 0xe,
-	SIGTERM		= 0xf,
-	SIGURG		= 0x10,
-	SIGSTOP		= 0x11,
-	SIGTSTP		= 0x12,
-	SIGCONT		= 0x13,
-	SIGCHLD		= 0x14,
-	SIGTTIN		= 0x15,
-	SIGTTOU		= 0x16,
-	SIGIO		= 0x17,
-	SIGXCPU		= 0x18,
-	SIGXFSZ		= 0x19,
-	SIGVTALRM	= 0x1a,
-	SIGPROF		= 0x1b,
-	SIGWINCH	= 0x1c,
-	SIGINFO		= 0x1d,
-	SIGUSR1		= 0x1e,
-	SIGUSR2		= 0x1f,
-
-	FPE_INTDIV	= 0x7,
-	FPE_INTOVF	= 0x8,
-	FPE_FLTDIV	= 0x1,
-	FPE_FLTOVF	= 0x2,
-	FPE_FLTUND	= 0x3,
-	FPE_FLTRES	= 0x4,
-	FPE_FLTINV	= 0x5,
-	FPE_FLTSUB	= 0x6,
-
-	BUS_ADRALN	= 0x1,
-	BUS_ADRERR	= 0x2,
-	BUS_OBJERR	= 0x3,
-
-	SEGV_MAPERR	= 0x1,
-	SEGV_ACCERR	= 0x2,
-
-	ITIMER_REAL	= 0x0,
-	ITIMER_VIRTUAL	= 0x1,
-	ITIMER_PROF	= 0x2,
-
-	EV_ADD		= 0x1,
-	EV_DELETE	= 0x2,
-	EV_CLEAR	= 0x20,
-	EV_RECEIPT	= 0x40,
-	EV_ERROR	= 0x4000,
-	EVFILT_READ	= -0x1,
-	EVFILT_WRITE	= -0x2,
-};
-
-typedef struct MachBody MachBody;
-typedef struct MachHeader MachHeader;
-typedef struct MachNDR MachNDR;
-typedef struct MachPort MachPort;
-typedef struct StackT StackT;
-typedef struct Sigaction Sigaction;
-typedef struct Siginfo Siginfo;
-typedef struct Timeval Timeval;
-typedef struct Itimerval Itimerval;
-typedef struct Timespec Timespec;
-typedef struct FPControl FPControl;
-typedef struct FPStatus FPStatus;
-typedef struct RegMMST RegMMST;
-typedef struct RegXMM RegXMM;
-typedef struct Regs64 Regs64;
-typedef struct FloatState64 FloatState64;
-typedef struct ExceptionState64 ExceptionState64;
-typedef struct Mcontext64 Mcontext64;
-typedef struct Regs32 Regs32;
-typedef struct FloatState32 FloatState32;
-typedef struct ExceptionState32 ExceptionState32;
-typedef struct Mcontext32 Mcontext32;
-typedef struct Ucontext Ucontext;
-typedef struct Kevent Kevent;
-
-#pragma pack on
-
-struct MachBody {
-	uint32	msgh_descriptor_count;
-};
-struct MachHeader {
-	uint32	msgh_bits;
-	uint32	msgh_size;
-	uint32	msgh_remote_port;
-	uint32	msgh_local_port;
-	uint32	msgh_reserved;
-	int32	msgh_id;
-};
-struct MachNDR {
-	uint8	mig_vers;
-	uint8	if_vers;
-	uint8	reserved1;
-	uint8	mig_encoding;
-	uint8	int_rep;
-	uint8	char_rep;
-	uint8	float_rep;
-	uint8	reserved2;
-};
-struct MachPort {
-	uint32	name;
-	uint32	pad1;
-	uint16	pad2;
-	uint8	disposition;
-	uint8	type;
-};
-
-struct StackT {
-	byte	*ss_sp;
-	uint32	ss_size;
-	int32	ss_flags;
-};
-typedef	byte	Sighandler[4];
-
-struct Sigaction {
-	byte	__sigaction_u[4];
-	void	*sa_tramp;
-	uint32	sa_mask;
-	int32	sa_flags;
-};
-
-typedef	byte	Sigval[4];
-struct Siginfo {
-	int32	si_signo;
-	int32	si_errno;
-	int32	si_code;
-	int32	si_pid;
-	uint32	si_uid;
-	int32	si_status;
-	byte	*si_addr;
-	byte	si_value[4];
-	int32	si_band;
-	uint32	__pad[7];
-};
-struct Timeval {
-	int32	tv_sec;
-	int32	tv_usec;
-};
-struct Itimerval {
-	Timeval	it_interval;
-	Timeval	it_value;
-};
-struct Timespec {
-	int32	tv_sec;
-	int32	tv_nsec;
-};
-
-struct FPControl {
-	byte	Pad_cgo_0[2];
-};
-struct FPStatus {
-	byte	Pad_cgo_0[2];
-};
-struct RegMMST {
-	int8	mmst_reg[10];
-	int8	mmst_rsrv[6];
-};
-struct RegXMM {
-	int8	xmm_reg[16];
-};
-
-struct Regs64 {
-	uint64	rax;
-	uint64	rbx;
-	uint64	rcx;
-	uint64	rdx;
-	uint64	rdi;
-	uint64	rsi;
-	uint64	rbp;
-	uint64	rsp;
-	uint64	r8;
-	uint64	r9;
-	uint64	r10;
-	uint64	r11;
-	uint64	r12;
-	uint64	r13;
-	uint64	r14;
-	uint64	r15;
-	uint64	rip;
-	uint64	rflags;
-	uint64	cs;
-	uint64	fs;
-	uint64	gs;
-};
-struct FloatState64 {
-	int32	fpu_reserved[2];
-	FPControl	fpu_fcw;
-	FPStatus	fpu_fsw;
-	uint8	fpu_ftw;
-	uint8	fpu_rsrv1;
-	uint16	fpu_fop;
-	uint32	fpu_ip;
-	uint16	fpu_cs;
-	uint16	fpu_rsrv2;
-	uint32	fpu_dp;
-	uint16	fpu_ds;
-	uint16	fpu_rsrv3;
-	uint32	fpu_mxcsr;
-	uint32	fpu_mxcsrmask;
-	RegMMST	fpu_stmm0;
-	RegMMST	fpu_stmm1;
-	RegMMST	fpu_stmm2;
-	RegMMST	fpu_stmm3;
-	RegMMST	fpu_stmm4;
-	RegMMST	fpu_stmm5;
-	RegMMST	fpu_stmm6;
-	RegMMST	fpu_stmm7;
-	RegXMM	fpu_xmm0;
-	RegXMM	fpu_xmm1;
-	RegXMM	fpu_xmm2;
-	RegXMM	fpu_xmm3;
-	RegXMM	fpu_xmm4;
-	RegXMM	fpu_xmm5;
-	RegXMM	fpu_xmm6;
-	RegXMM	fpu_xmm7;
-	RegXMM	fpu_xmm8;
-	RegXMM	fpu_xmm9;
-	RegXMM	fpu_xmm10;
-	RegXMM	fpu_xmm11;
-	RegXMM	fpu_xmm12;
-	RegXMM	fpu_xmm13;
-	RegXMM	fpu_xmm14;
-	RegXMM	fpu_xmm15;
-	int8	fpu_rsrv4[96];
-	int32	fpu_reserved1;
-};
-struct ExceptionState64 {
-	uint16	trapno;
-	uint16	cpu;
-	uint32	err;
-	uint64	faultvaddr;
-};
-struct Mcontext64 {
-	ExceptionState64	es;
-	Regs64	ss;
-	FloatState64	fs;
-};
-
-struct Regs32 {
-	uint32	eax;
-	uint32	ebx;
-	uint32	ecx;
-	uint32	edx;
-	uint32	edi;
-	uint32	esi;
-	uint32	ebp;
-	uint32	esp;
-	uint32	ss;
-	uint32	eflags;
-	uint32	eip;
-	uint32	cs;
-	uint32	ds;
-	uint32	es;
-	uint32	fs;
-	uint32	gs;
-};
-struct FloatState32 {
-	int32	fpu_reserved[2];
-	FPControl	fpu_fcw;
-	FPStatus	fpu_fsw;
-	uint8	fpu_ftw;
-	uint8	fpu_rsrv1;
-	uint16	fpu_fop;
-	uint32	fpu_ip;
-	uint16	fpu_cs;
-	uint16	fpu_rsrv2;
-	uint32	fpu_dp;
-	uint16	fpu_ds;
-	uint16	fpu_rsrv3;
-	uint32	fpu_mxcsr;
-	uint32	fpu_mxcsrmask;
-	RegMMST	fpu_stmm0;
-	RegMMST	fpu_stmm1;
-	RegMMST	fpu_stmm2;
-	RegMMST	fpu_stmm3;
-	RegMMST	fpu_stmm4;
-	RegMMST	fpu_stmm5;
-	RegMMST	fpu_stmm6;
-	RegMMST	fpu_stmm7;
-	RegXMM	fpu_xmm0;
-	RegXMM	fpu_xmm1;
-	RegXMM	fpu_xmm2;
-	RegXMM	fpu_xmm3;
-	RegXMM	fpu_xmm4;
-	RegXMM	fpu_xmm5;
-	RegXMM	fpu_xmm6;
-	RegXMM	fpu_xmm7;
-	int8	fpu_rsrv4[224];
-	int32	fpu_reserved1;
-};
-struct ExceptionState32 {
-	uint16	trapno;
-	uint16	cpu;
-	uint32	err;
-	uint32	faultvaddr;
-};
-struct Mcontext32 {
-	ExceptionState32	es;
-	Regs32	ss;
-	FloatState32	fs;
-};
-
-struct Ucontext {
-	int32	uc_onstack;
-	uint32	uc_sigmask;
-	StackT	uc_stack;
-	Ucontext	*uc_link;
-	uint32	uc_mcsize;
-	Mcontext32	*uc_mcontext;
-};
-
-struct Kevent {
-	uint32	ident;
-	int16	filter;
-	uint16	flags;
-	uint32	fflags;
-	int32	data;
-	byte	*udata;
-};
-
-
-#pragma pack off
diff --git a/src/pkg/runtime/defs_darwin_amd64.h b/src/pkg/runtime/defs_darwin_amd64.h
deleted file mode 100644
index 2d464a9..0000000
--- a/src/pkg/runtime/defs_darwin_amd64.h
+++ /dev/null
@@ -1,395 +0,0 @@
-// Created by cgo -cdefs - DO NOT EDIT
-// cgo -cdefs defs_darwin.go
-
-
-enum {
-	EINTR	= 0x4,
-	EFAULT	= 0xe,
-
-	PROT_NONE	= 0x0,
-	PROT_READ	= 0x1,
-	PROT_WRITE	= 0x2,
-	PROT_EXEC	= 0x4,
-
-	MAP_ANON	= 0x1000,
-	MAP_PRIVATE	= 0x2,
-	MAP_FIXED	= 0x10,
-
-	MADV_DONTNEED	= 0x4,
-	MADV_FREE	= 0x5,
-
-	MACH_MSG_TYPE_MOVE_RECEIVE	= 0x10,
-	MACH_MSG_TYPE_MOVE_SEND		= 0x11,
-	MACH_MSG_TYPE_MOVE_SEND_ONCE	= 0x12,
-	MACH_MSG_TYPE_COPY_SEND		= 0x13,
-	MACH_MSG_TYPE_MAKE_SEND		= 0x14,
-	MACH_MSG_TYPE_MAKE_SEND_ONCE	= 0x15,
-	MACH_MSG_TYPE_COPY_RECEIVE	= 0x16,
-
-	MACH_MSG_PORT_DESCRIPTOR		= 0x0,
-	MACH_MSG_OOL_DESCRIPTOR			= 0x1,
-	MACH_MSG_OOL_PORTS_DESCRIPTOR		= 0x2,
-	MACH_MSG_OOL_VOLATILE_DESCRIPTOR	= 0x3,
-
-	MACH_MSGH_BITS_COMPLEX	= 0x80000000,
-
-	MACH_SEND_MSG	= 0x1,
-	MACH_RCV_MSG	= 0x2,
-	MACH_RCV_LARGE	= 0x4,
-
-	MACH_SEND_TIMEOUT	= 0x10,
-	MACH_SEND_INTERRUPT	= 0x40,
-	MACH_SEND_ALWAYS	= 0x10000,
-	MACH_SEND_TRAILER	= 0x20000,
-	MACH_RCV_TIMEOUT	= 0x100,
-	MACH_RCV_NOTIFY		= 0x200,
-	MACH_RCV_INTERRUPT	= 0x400,
-	MACH_RCV_OVERWRITE	= 0x1000,
-
-	NDR_PROTOCOL_2_0	= 0x0,
-	NDR_INT_BIG_ENDIAN	= 0x0,
-	NDR_INT_LITTLE_ENDIAN	= 0x1,
-	NDR_FLOAT_IEEE		= 0x0,
-	NDR_CHAR_ASCII		= 0x0,
-
-	SA_SIGINFO	= 0x40,
-	SA_RESTART	= 0x2,
-	SA_ONSTACK	= 0x1,
-	SA_USERTRAMP	= 0x100,
-	SA_64REGSET	= 0x200,
-
-	SIGHUP		= 0x1,
-	SIGINT		= 0x2,
-	SIGQUIT		= 0x3,
-	SIGILL		= 0x4,
-	SIGTRAP		= 0x5,
-	SIGABRT		= 0x6,
-	SIGEMT		= 0x7,
-	SIGFPE		= 0x8,
-	SIGKILL		= 0x9,
-	SIGBUS		= 0xa,
-	SIGSEGV		= 0xb,
-	SIGSYS		= 0xc,
-	SIGPIPE		= 0xd,
-	SIGALRM		= 0xe,
-	SIGTERM		= 0xf,
-	SIGURG		= 0x10,
-	SIGSTOP		= 0x11,
-	SIGTSTP		= 0x12,
-	SIGCONT		= 0x13,
-	SIGCHLD		= 0x14,
-	SIGTTIN		= 0x15,
-	SIGTTOU		= 0x16,
-	SIGIO		= 0x17,
-	SIGXCPU		= 0x18,
-	SIGXFSZ		= 0x19,
-	SIGVTALRM	= 0x1a,
-	SIGPROF		= 0x1b,
-	SIGWINCH	= 0x1c,
-	SIGINFO		= 0x1d,
-	SIGUSR1		= 0x1e,
-	SIGUSR2		= 0x1f,
-
-	FPE_INTDIV	= 0x7,
-	FPE_INTOVF	= 0x8,
-	FPE_FLTDIV	= 0x1,
-	FPE_FLTOVF	= 0x2,
-	FPE_FLTUND	= 0x3,
-	FPE_FLTRES	= 0x4,
-	FPE_FLTINV	= 0x5,
-	FPE_FLTSUB	= 0x6,
-
-	BUS_ADRALN	= 0x1,
-	BUS_ADRERR	= 0x2,
-	BUS_OBJERR	= 0x3,
-
-	SEGV_MAPERR	= 0x1,
-	SEGV_ACCERR	= 0x2,
-
-	ITIMER_REAL	= 0x0,
-	ITIMER_VIRTUAL	= 0x1,
-	ITIMER_PROF	= 0x2,
-
-	EV_ADD		= 0x1,
-	EV_DELETE	= 0x2,
-	EV_CLEAR	= 0x20,
-	EV_RECEIPT	= 0x40,
-	EV_ERROR	= 0x4000,
-	EVFILT_READ	= -0x1,
-	EVFILT_WRITE	= -0x2,
-};
-
-typedef struct MachBody MachBody;
-typedef struct MachHeader MachHeader;
-typedef struct MachNDR MachNDR;
-typedef struct MachPort MachPort;
-typedef struct StackT StackT;
-typedef struct Sigaction Sigaction;
-typedef struct Siginfo Siginfo;
-typedef struct Timeval Timeval;
-typedef struct Itimerval Itimerval;
-typedef struct Timespec Timespec;
-typedef struct FPControl FPControl;
-typedef struct FPStatus FPStatus;
-typedef struct RegMMST RegMMST;
-typedef struct RegXMM RegXMM;
-typedef struct Regs64 Regs64;
-typedef struct FloatState64 FloatState64;
-typedef struct ExceptionState64 ExceptionState64;
-typedef struct Mcontext64 Mcontext64;
-typedef struct Regs32 Regs32;
-typedef struct FloatState32 FloatState32;
-typedef struct ExceptionState32 ExceptionState32;
-typedef struct Mcontext32 Mcontext32;
-typedef struct Ucontext Ucontext;
-typedef struct Kevent Kevent;
-
-#pragma pack on
-
-struct MachBody {
-	uint32	msgh_descriptor_count;
-};
-struct MachHeader {
-	uint32	msgh_bits;
-	uint32	msgh_size;
-	uint32	msgh_remote_port;
-	uint32	msgh_local_port;
-	uint32	msgh_reserved;
-	int32	msgh_id;
-};
-struct MachNDR {
-	uint8	mig_vers;
-	uint8	if_vers;
-	uint8	reserved1;
-	uint8	mig_encoding;
-	uint8	int_rep;
-	uint8	char_rep;
-	uint8	float_rep;
-	uint8	reserved2;
-};
-struct MachPort {
-	uint32	name;
-	uint32	pad1;
-	uint16	pad2;
-	uint8	disposition;
-	uint8	type;
-};
-
-struct StackT {
-	byte	*ss_sp;
-	uint64	ss_size;
-	int32	ss_flags;
-	byte	Pad_cgo_0[4];
-};
-typedef	byte	Sighandler[8];
-
-struct Sigaction {
-	byte	__sigaction_u[8];
-	void	*sa_tramp;
-	uint32	sa_mask;
-	int32	sa_flags;
-};
-
-typedef	byte	Sigval[8];
-struct Siginfo {
-	int32	si_signo;
-	int32	si_errno;
-	int32	si_code;
-	int32	si_pid;
-	uint32	si_uid;
-	int32	si_status;
-	byte	*si_addr;
-	byte	si_value[8];
-	int64	si_band;
-	uint64	__pad[7];
-};
-struct Timeval {
-	int64	tv_sec;
-	int32	tv_usec;
-	byte	Pad_cgo_0[4];
-};
-struct Itimerval {
-	Timeval	it_interval;
-	Timeval	it_value;
-};
-struct Timespec {
-	int64	tv_sec;
-	int64	tv_nsec;
-};
-
-struct FPControl {
-	byte	Pad_cgo_0[2];
-};
-struct FPStatus {
-	byte	Pad_cgo_0[2];
-};
-struct RegMMST {
-	int8	mmst_reg[10];
-	int8	mmst_rsrv[6];
-};
-struct RegXMM {
-	int8	xmm_reg[16];
-};
-
-struct Regs64 {
-	uint64	rax;
-	uint64	rbx;
-	uint64	rcx;
-	uint64	rdx;
-	uint64	rdi;
-	uint64	rsi;
-	uint64	rbp;
-	uint64	rsp;
-	uint64	r8;
-	uint64	r9;
-	uint64	r10;
-	uint64	r11;
-	uint64	r12;
-	uint64	r13;
-	uint64	r14;
-	uint64	r15;
-	uint64	rip;
-	uint64	rflags;
-	uint64	cs;
-	uint64	fs;
-	uint64	gs;
-};
-struct FloatState64 {
-	int32	fpu_reserved[2];
-	FPControl	fpu_fcw;
-	FPStatus	fpu_fsw;
-	uint8	fpu_ftw;
-	uint8	fpu_rsrv1;
-	uint16	fpu_fop;
-	uint32	fpu_ip;
-	uint16	fpu_cs;
-	uint16	fpu_rsrv2;
-	uint32	fpu_dp;
-	uint16	fpu_ds;
-	uint16	fpu_rsrv3;
-	uint32	fpu_mxcsr;
-	uint32	fpu_mxcsrmask;
-	RegMMST	fpu_stmm0;
-	RegMMST	fpu_stmm1;
-	RegMMST	fpu_stmm2;
-	RegMMST	fpu_stmm3;
-	RegMMST	fpu_stmm4;
-	RegMMST	fpu_stmm5;
-	RegMMST	fpu_stmm6;
-	RegMMST	fpu_stmm7;
-	RegXMM	fpu_xmm0;
-	RegXMM	fpu_xmm1;
-	RegXMM	fpu_xmm2;
-	RegXMM	fpu_xmm3;
-	RegXMM	fpu_xmm4;
-	RegXMM	fpu_xmm5;
-	RegXMM	fpu_xmm6;
-	RegXMM	fpu_xmm7;
-	RegXMM	fpu_xmm8;
-	RegXMM	fpu_xmm9;
-	RegXMM	fpu_xmm10;
-	RegXMM	fpu_xmm11;
-	RegXMM	fpu_xmm12;
-	RegXMM	fpu_xmm13;
-	RegXMM	fpu_xmm14;
-	RegXMM	fpu_xmm15;
-	int8	fpu_rsrv4[96];
-	int32	fpu_reserved1;
-};
-struct ExceptionState64 {
-	uint16	trapno;
-	uint16	cpu;
-	uint32	err;
-	uint64	faultvaddr;
-};
-struct Mcontext64 {
-	ExceptionState64	es;
-	Regs64	ss;
-	FloatState64	fs;
-	byte	Pad_cgo_0[4];
-};
-
-struct Regs32 {
-	uint32	eax;
-	uint32	ebx;
-	uint32	ecx;
-	uint32	edx;
-	uint32	edi;
-	uint32	esi;
-	uint32	ebp;
-	uint32	esp;
-	uint32	ss;
-	uint32	eflags;
-	uint32	eip;
-	uint32	cs;
-	uint32	ds;
-	uint32	es;
-	uint32	fs;
-	uint32	gs;
-};
-struct FloatState32 {
-	int32	fpu_reserved[2];
-	FPControl	fpu_fcw;
-	FPStatus	fpu_fsw;
-	uint8	fpu_ftw;
-	uint8	fpu_rsrv1;
-	uint16	fpu_fop;
-	uint32	fpu_ip;
-	uint16	fpu_cs;
-	uint16	fpu_rsrv2;
-	uint32	fpu_dp;
-	uint16	fpu_ds;
-	uint16	fpu_rsrv3;
-	uint32	fpu_mxcsr;
-	uint32	fpu_mxcsrmask;
-	RegMMST	fpu_stmm0;
-	RegMMST	fpu_stmm1;
-	RegMMST	fpu_stmm2;
-	RegMMST	fpu_stmm3;
-	RegMMST	fpu_stmm4;
-	RegMMST	fpu_stmm5;
-	RegMMST	fpu_stmm6;
-	RegMMST	fpu_stmm7;
-	RegXMM	fpu_xmm0;
-	RegXMM	fpu_xmm1;
-	RegXMM	fpu_xmm2;
-	RegXMM	fpu_xmm3;
-	RegXMM	fpu_xmm4;
-	RegXMM	fpu_xmm5;
-	RegXMM	fpu_xmm6;
-	RegXMM	fpu_xmm7;
-	int8	fpu_rsrv4[224];
-	int32	fpu_reserved1;
-};
-struct ExceptionState32 {
-	uint16	trapno;
-	uint16	cpu;
-	uint32	err;
-	uint32	faultvaddr;
-};
-struct Mcontext32 {
-	ExceptionState32	es;
-	Regs32	ss;
-	FloatState32	fs;
-};
-
-struct Ucontext {
-	int32	uc_onstack;
-	uint32	uc_sigmask;
-	StackT	uc_stack;
-	Ucontext	*uc_link;
-	uint64	uc_mcsize;
-	Mcontext64	*uc_mcontext;
-};
-
-struct Kevent {
-	uint64	ident;
-	int16	filter;
-	uint16	flags;
-	uint32	fflags;
-	int64	data;
-	byte	*udata;
-};
-
-
-#pragma pack off
diff --git a/src/pkg/runtime/defs_dragonfly.go b/src/pkg/runtime/defs_dragonfly.go
deleted file mode 100644
index 8ebc3a9..0000000
--- a/src/pkg/runtime/defs_dragonfly.go
+++ /dev/null
@@ -1,126 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build ignore
-
-/*
-Input to cgo.
-
-GOARCH=amd64 go tool cgo -cdefs defs_dragonfly.go >defs_dragonfly_amd64.h
-GOARCH=386 go tool cgo -cdefs defs_dragonfly.go >defs_dragonfly_386.h
-*/
-
-package runtime
-
-/*
-#include <sys/user.h>
-#include <sys/time.h>
-#include <sys/event.h>
-#include <sys/mman.h>
-#include <sys/ucontext.h>
-#include <sys/rtprio.h>
-#include <sys/signal.h>
-#include <sys/unistd.h>
-#include <errno.h>
-#include <signal.h>
-*/
-import "C"
-
-const (
-	EINTR  = C.EINTR
-	EFAULT = C.EFAULT
-	EBUSY  = C.EBUSY
-	EAGAIN = C.EAGAIN
-
-	PROT_NONE  = C.PROT_NONE
-	PROT_READ  = C.PROT_READ
-	PROT_WRITE = C.PROT_WRITE
-	PROT_EXEC  = C.PROT_EXEC
-
-	MAP_ANON    = C.MAP_ANON
-	MAP_PRIVATE = C.MAP_PRIVATE
-	MAP_FIXED   = C.MAP_FIXED
-
-	MADV_FREE = C.MADV_FREE
-
-	SA_SIGINFO = C.SA_SIGINFO
-	SA_RESTART = C.SA_RESTART
-	SA_ONSTACK = C.SA_ONSTACK
-
-	SIGHUP    = C.SIGHUP
-	SIGINT    = C.SIGINT
-	SIGQUIT   = C.SIGQUIT
-	SIGILL    = C.SIGILL
-	SIGTRAP   = C.SIGTRAP
-	SIGABRT   = C.SIGABRT
-	SIGEMT    = C.SIGEMT
-	SIGFPE    = C.SIGFPE
-	SIGKILL   = C.SIGKILL
-	SIGBUS    = C.SIGBUS
-	SIGSEGV   = C.SIGSEGV
-	SIGSYS    = C.SIGSYS
-	SIGPIPE   = C.SIGPIPE
-	SIGALRM   = C.SIGALRM
-	SIGTERM   = C.SIGTERM
-	SIGURG    = C.SIGURG
-	SIGSTOP   = C.SIGSTOP
-	SIGTSTP   = C.SIGTSTP
-	SIGCONT   = C.SIGCONT
-	SIGCHLD   = C.SIGCHLD
-	SIGTTIN   = C.SIGTTIN
-	SIGTTOU   = C.SIGTTOU
-	SIGIO     = C.SIGIO
-	SIGXCPU   = C.SIGXCPU
-	SIGXFSZ   = C.SIGXFSZ
-	SIGVTALRM = C.SIGVTALRM
-	SIGPROF   = C.SIGPROF
-	SIGWINCH  = C.SIGWINCH
-	SIGINFO   = C.SIGINFO
-	SIGUSR1   = C.SIGUSR1
-	SIGUSR2   = C.SIGUSR2
-
-	FPE_INTDIV = C.FPE_INTDIV
-	FPE_INTOVF = C.FPE_INTOVF
-	FPE_FLTDIV = C.FPE_FLTDIV
-	FPE_FLTOVF = C.FPE_FLTOVF
-	FPE_FLTUND = C.FPE_FLTUND
-	FPE_FLTRES = C.FPE_FLTRES
-	FPE_FLTINV = C.FPE_FLTINV
-	FPE_FLTSUB = C.FPE_FLTSUB
-
-	BUS_ADRALN = C.BUS_ADRALN
-	BUS_ADRERR = C.BUS_ADRERR
-	BUS_OBJERR = C.BUS_OBJERR
-
-	SEGV_MAPERR = C.SEGV_MAPERR
-	SEGV_ACCERR = C.SEGV_ACCERR
-
-	ITIMER_REAL    = C.ITIMER_REAL
-	ITIMER_VIRTUAL = C.ITIMER_VIRTUAL
-	ITIMER_PROF    = C.ITIMER_PROF
-
-	EV_ADD       = C.EV_ADD
-	EV_DELETE    = C.EV_DELETE
-	EV_CLEAR     = C.EV_CLEAR
-	EV_ERROR     = C.EV_ERROR
-	EVFILT_READ  = C.EVFILT_READ
-	EVFILT_WRITE = C.EVFILT_WRITE
-)
-
-type Rtprio C.struct_rtprio
-type Lwpparams C.struct_lwp_params
-type Sigaltstack C.struct_sigaltstack
-type Sigset C.struct___sigset
-type StackT C.stack_t
-
-type Siginfo C.siginfo_t
-
-type Mcontext C.mcontext_t
-type Ucontext C.ucontext_t
-
-type Timespec C.struct_timespec
-type Timeval C.struct_timeval
-type Itimerval C.struct_itimerval
-
-type Kevent C.struct_kevent
diff --git a/src/pkg/runtime/defs_dragonfly_386.h b/src/pkg/runtime/defs_dragonfly_386.h
deleted file mode 100644
index 696dcd8..0000000
--- a/src/pkg/runtime/defs_dragonfly_386.h
+++ /dev/null
@@ -1,198 +0,0 @@
-// Created by cgo -cdefs - DO NOT EDIT
-// cgo -cdefs defs_dragonfly.go
-
-
-enum {
-	EINTR	= 0x4,
-	EFAULT	= 0xe,
-	EBUSY	= 0x10,
-	EAGAIN	= 0x23,
-
-	PROT_NONE	= 0x0,
-	PROT_READ	= 0x1,
-	PROT_WRITE	= 0x2,
-	PROT_EXEC	= 0x4,
-
-	MAP_ANON	= 0x1000,
-	MAP_PRIVATE	= 0x2,
-	MAP_FIXED	= 0x10,
-
-	MADV_FREE	= 0x5,
-
-	SA_SIGINFO	= 0x40,
-	SA_RESTART	= 0x2,
-	SA_ONSTACK	= 0x1,
-
-	SIGHUP		= 0x1,
-	SIGINT		= 0x2,
-	SIGQUIT		= 0x3,
-	SIGILL		= 0x4,
-	SIGTRAP		= 0x5,
-	SIGABRT		= 0x6,
-	SIGEMT		= 0x7,
-	SIGFPE		= 0x8,
-	SIGKILL		= 0x9,
-	SIGBUS		= 0xa,
-	SIGSEGV		= 0xb,
-	SIGSYS		= 0xc,
-	SIGPIPE		= 0xd,
-	SIGALRM		= 0xe,
-	SIGTERM		= 0xf,
-	SIGURG		= 0x10,
-	SIGSTOP		= 0x11,
-	SIGTSTP		= 0x12,
-	SIGCONT		= 0x13,
-	SIGCHLD		= 0x14,
-	SIGTTIN		= 0x15,
-	SIGTTOU		= 0x16,
-	SIGIO		= 0x17,
-	SIGXCPU		= 0x18,
-	SIGXFSZ		= 0x19,
-	SIGVTALRM	= 0x1a,
-	SIGPROF		= 0x1b,
-	SIGWINCH	= 0x1c,
-	SIGINFO		= 0x1d,
-	SIGUSR1		= 0x1e,
-	SIGUSR2		= 0x1f,
-
-	FPE_INTDIV	= 0x2,
-	FPE_INTOVF	= 0x1,
-	FPE_FLTDIV	= 0x3,
-	FPE_FLTOVF	= 0x4,
-	FPE_FLTUND	= 0x5,
-	FPE_FLTRES	= 0x6,
-	FPE_FLTINV	= 0x7,
-	FPE_FLTSUB	= 0x8,
-
-	BUS_ADRALN	= 0x1,
-	BUS_ADRERR	= 0x2,
-	BUS_OBJERR	= 0x3,
-
-	SEGV_MAPERR	= 0x1,
-	SEGV_ACCERR	= 0x2,
-
-	ITIMER_REAL	= 0x0,
-	ITIMER_VIRTUAL	= 0x1,
-	ITIMER_PROF	= 0x2,
-
-	EV_ADD		= 0x1,
-	EV_DELETE	= 0x2,
-	EV_CLEAR	= 0x20,
-	EV_ERROR	= 0x4000,
-	EVFILT_READ	= -0x1,
-	EVFILT_WRITE	= -0x2,
-};
-
-typedef struct Rtprio Rtprio;
-typedef struct Lwpparams Lwpparams;
-typedef struct Sigaltstack Sigaltstack;
-typedef struct Sigset Sigset;
-typedef struct StackT StackT;
-typedef struct Siginfo Siginfo;
-typedef struct Mcontext Mcontext;
-typedef struct Ucontext Ucontext;
-typedef struct Timespec Timespec;
-typedef struct Timeval Timeval;
-typedef struct Itimerval Itimerval;
-typedef struct Kevent Kevent;
-
-#pragma pack on
-
-struct Rtprio {
-	uint16	type;
-	uint16	prio;
-};
-struct Lwpparams {
-	void	*func;
-	byte	*arg;
-	byte	*stack;
-	int32	*tid1;
-	int32	*tid2;
-};
-struct Sigaltstack {
-	int8	*ss_sp;
-	uint32	ss_size;
-	int32	ss_flags;
-};
-struct Sigset {
-	uint32	__bits[4];
-};
-struct StackT {
-	int8	*ss_sp;
-	uint32	ss_size;
-	int32	ss_flags;
-};
-
-struct Siginfo {
-	int32	si_signo;
-	int32	si_errno;
-	int32	si_code;
-	int32	si_pid;
-	uint32	si_uid;
-	int32	si_status;
-	byte	*si_addr;
-	byte	si_value[4];
-	int32	si_band;
-	int32	__spare__[7];
-};
-
-struct Mcontext {
-	int32	mc_onstack;
-	int32	mc_gs;
-	int32	mc_fs;
-	int32	mc_es;
-	int32	mc_ds;
-	int32	mc_edi;
-	int32	mc_esi;
-	int32	mc_ebp;
-	int32	mc_isp;
-	int32	mc_ebx;
-	int32	mc_edx;
-	int32	mc_ecx;
-	int32	mc_eax;
-	int32	mc_xflags;
-	int32	mc_trapno;
-	int32	mc_err;
-	int32	mc_eip;
-	int32	mc_cs;
-	int32	mc_eflags;
-	int32	mc_esp;
-	int32	mc_ss;
-	int32	mc_len;
-	int32	mc_fpformat;
-	int32	mc_ownedfp;
-	int32	mc_fpregs[128];
-	int32	__spare__[16];
-};
-struct Ucontext {
-	Sigset	uc_sigmask;
-	Mcontext	uc_mcontext;
-	Ucontext	*uc_link;
-	StackT	uc_stack;
-	int32	__spare__[8];
-};
-
-struct Timespec {
-	int32	tv_sec;
-	int32	tv_nsec;
-};
-struct Timeval {
-	int32	tv_sec;
-	int32	tv_usec;
-};
-struct Itimerval {
-	Timeval	it_interval;
-	Timeval	it_value;
-};
-
-struct Kevent {
-	uint32	ident;
-	int16	filter;
-	uint16	flags;
-	uint32	fflags;
-	int32	data;
-	byte	*udata;
-};
-
-
-#pragma pack off
diff --git a/src/pkg/runtime/defs_dragonfly_amd64.h b/src/pkg/runtime/defs_dragonfly_amd64.h
deleted file mode 100644
index 74581cc..0000000
--- a/src/pkg/runtime/defs_dragonfly_amd64.h
+++ /dev/null
@@ -1,208 +0,0 @@
-// Created by cgo -cdefs - DO NOT EDIT
-// cgo -cdefs defs_dragonfly.go
-
-
-enum {
-	EINTR	= 0x4,
-	EFAULT	= 0xe,
-	EBUSY	= 0x10,
-	EAGAIN	= 0x23,
-
-	PROT_NONE	= 0x0,
-	PROT_READ	= 0x1,
-	PROT_WRITE	= 0x2,
-	PROT_EXEC	= 0x4,
-
-	MAP_ANON	= 0x1000,
-	MAP_PRIVATE	= 0x2,
-	MAP_FIXED	= 0x10,
-
-	MADV_FREE	= 0x5,
-
-	SA_SIGINFO	= 0x40,
-	SA_RESTART	= 0x2,
-	SA_ONSTACK	= 0x1,
-
-	SIGHUP		= 0x1,
-	SIGINT		= 0x2,
-	SIGQUIT		= 0x3,
-	SIGILL		= 0x4,
-	SIGTRAP		= 0x5,
-	SIGABRT		= 0x6,
-	SIGEMT		= 0x7,
-	SIGFPE		= 0x8,
-	SIGKILL		= 0x9,
-	SIGBUS		= 0xa,
-	SIGSEGV		= 0xb,
-	SIGSYS		= 0xc,
-	SIGPIPE		= 0xd,
-	SIGALRM		= 0xe,
-	SIGTERM		= 0xf,
-	SIGURG		= 0x10,
-	SIGSTOP		= 0x11,
-	SIGTSTP		= 0x12,
-	SIGCONT		= 0x13,
-	SIGCHLD		= 0x14,
-	SIGTTIN		= 0x15,
-	SIGTTOU		= 0x16,
-	SIGIO		= 0x17,
-	SIGXCPU		= 0x18,
-	SIGXFSZ		= 0x19,
-	SIGVTALRM	= 0x1a,
-	SIGPROF		= 0x1b,
-	SIGWINCH	= 0x1c,
-	SIGINFO		= 0x1d,
-	SIGUSR1		= 0x1e,
-	SIGUSR2		= 0x1f,
-
-	FPE_INTDIV	= 0x2,
-	FPE_INTOVF	= 0x1,
-	FPE_FLTDIV	= 0x3,
-	FPE_FLTOVF	= 0x4,
-	FPE_FLTUND	= 0x5,
-	FPE_FLTRES	= 0x6,
-	FPE_FLTINV	= 0x7,
-	FPE_FLTSUB	= 0x8,
-
-	BUS_ADRALN	= 0x1,
-	BUS_ADRERR	= 0x2,
-	BUS_OBJERR	= 0x3,
-
-	SEGV_MAPERR	= 0x1,
-	SEGV_ACCERR	= 0x2,
-
-	ITIMER_REAL	= 0x0,
-	ITIMER_VIRTUAL	= 0x1,
-	ITIMER_PROF	= 0x2,
-
-	EV_ADD		= 0x1,
-	EV_DELETE	= 0x2,
-	EV_CLEAR	= 0x20,
-	EV_ERROR	= 0x4000,
-	EVFILT_READ	= -0x1,
-	EVFILT_WRITE	= -0x2,
-};
-
-typedef struct Rtprio Rtprio;
-typedef struct Lwpparams Lwpparams;
-typedef struct Sigaltstack Sigaltstack;
-typedef struct Sigset Sigset;
-typedef struct StackT StackT;
-typedef struct Siginfo Siginfo;
-typedef struct Mcontext Mcontext;
-typedef struct Ucontext Ucontext;
-typedef struct Timespec Timespec;
-typedef struct Timeval Timeval;
-typedef struct Itimerval Itimerval;
-typedef struct Kevent Kevent;
-
-#pragma pack on
-
-struct Rtprio {
-	uint16	type;
-	uint16	prio;
-};
-struct Lwpparams {
-	void	*func;
-	byte	*arg;
-	byte	*stack;
-	int32	*tid1;
-	int32	*tid2;
-};
-struct Sigaltstack {
-	int8	*ss_sp;
-	uint64	ss_size;
-	int32	ss_flags;
-	byte	Pad_cgo_0[4];
-};
-struct Sigset {
-	uint32	__bits[4];
-};
-struct StackT {
-	int8	*ss_sp;
-	uint64	ss_size;
-	int32	ss_flags;
-	byte	Pad_cgo_0[4];
-};
-
-struct Siginfo {
-	int32	si_signo;
-	int32	si_errno;
-	int32	si_code;
-	int32	si_pid;
-	uint32	si_uid;
-	int32	si_status;
-	byte	*si_addr;
-	byte	si_value[8];
-	int64	si_band;
-	int32	__spare__[7];
-	byte	Pad_cgo_0[4];
-};
-
-struct Mcontext {
-	int64	mc_onstack;
-	int64	mc_rdi;
-	int64	mc_rsi;
-	int64	mc_rdx;
-	int64	mc_rcx;
-	int64	mc_r8;
-	int64	mc_r9;
-	int64	mc_rax;
-	int64	mc_rbx;
-	int64	mc_rbp;
-	int64	mc_r10;
-	int64	mc_r11;
-	int64	mc_r12;
-	int64	mc_r13;
-	int64	mc_r14;
-	int64	mc_r15;
-	int64	mc_xflags;
-	int64	mc_trapno;
-	int64	mc_addr;
-	int64	mc_flags;
-	int64	mc_err;
-	int64	mc_rip;
-	int64	mc_cs;
-	int64	mc_rflags;
-	int64	mc_rsp;
-	int64	mc_ss;
-	uint32	mc_len;
-	uint32	mc_fpformat;
-	uint32	mc_ownedfp;
-	uint32	mc_reserved;
-	uint32	mc_unused[8];
-	int32	mc_fpregs[256];
-};
-struct Ucontext {
-	Sigset	uc_sigmask;
-	byte	Pad_cgo_0[48];
-	Mcontext	uc_mcontext;
-	Ucontext	*uc_link;
-	StackT	uc_stack;
-	int32	__spare__[8];
-};
-
-struct Timespec {
-	int64	tv_sec;
-	int64	tv_nsec;
-};
-struct Timeval {
-	int64	tv_sec;
-	int64	tv_usec;
-};
-struct Itimerval {
-	Timeval	it_interval;
-	Timeval	it_value;
-};
-
-struct Kevent {
-	uint64	ident;
-	int16	filter;
-	uint16	flags;
-	uint32	fflags;
-	int64	data;
-	byte	*udata;
-};
-
-
-#pragma pack off
diff --git a/src/pkg/runtime/defs_freebsd.go b/src/pkg/runtime/defs_freebsd.go
deleted file mode 100644
index 2832583..0000000
--- a/src/pkg/runtime/defs_freebsd.go
+++ /dev/null
@@ -1,133 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build ignore
-
-/*
-Input to cgo.
-
-GOARCH=amd64 go tool cgo -cdefs defs_freebsd.go >defs_freebsd_amd64.h
-GOARCH=386 go tool cgo -cdefs defs_freebsd.go >defs_freebsd_386.h
-GOARCH=arm go tool cgo -cdefs defs_freebsd.go >defs_freebsd_arm.h
-*/
-
-package runtime
-
-/*
-#include <sys/types.h>
-#include <sys/time.h>
-#include <signal.h>
-#include <errno.h>
-#include <sys/event.h>
-#include <sys/mman.h>
-#include <sys/ucontext.h>
-#include <sys/umtx.h>
-#include <sys/rtprio.h>
-#include <sys/thr.h>
-#include <sys/_sigset.h>
-#include <sys/unistd.h>
-*/
-import "C"
-
-const (
-	EINTR  = C.EINTR
-	EFAULT = C.EFAULT
-
-	PROT_NONE  = C.PROT_NONE
-	PROT_READ  = C.PROT_READ
-	PROT_WRITE = C.PROT_WRITE
-	PROT_EXEC  = C.PROT_EXEC
-
-	MAP_ANON    = C.MAP_ANON
-	MAP_PRIVATE = C.MAP_PRIVATE
-	MAP_FIXED   = C.MAP_FIXED
-
-	MADV_FREE = C.MADV_FREE
-
-	SA_SIGINFO = C.SA_SIGINFO
-	SA_RESTART = C.SA_RESTART
-	SA_ONSTACK = C.SA_ONSTACK
-
-	UMTX_OP_WAIT_UINT         = C.UMTX_OP_WAIT_UINT
-	UMTX_OP_WAIT_UINT_PRIVATE = C.UMTX_OP_WAIT_UINT_PRIVATE
-	UMTX_OP_WAKE              = C.UMTX_OP_WAKE
-	UMTX_OP_WAKE_PRIVATE      = C.UMTX_OP_WAKE_PRIVATE
-
-	SIGHUP    = C.SIGHUP
-	SIGINT    = C.SIGINT
-	SIGQUIT   = C.SIGQUIT
-	SIGILL    = C.SIGILL
-	SIGTRAP   = C.SIGTRAP
-	SIGABRT   = C.SIGABRT
-	SIGEMT    = C.SIGEMT
-	SIGFPE    = C.SIGFPE
-	SIGKILL   = C.SIGKILL
-	SIGBUS    = C.SIGBUS
-	SIGSEGV   = C.SIGSEGV
-	SIGSYS    = C.SIGSYS
-	SIGPIPE   = C.SIGPIPE
-	SIGALRM   = C.SIGALRM
-	SIGTERM   = C.SIGTERM
-	SIGURG    = C.SIGURG
-	SIGSTOP   = C.SIGSTOP
-	SIGTSTP   = C.SIGTSTP
-	SIGCONT   = C.SIGCONT
-	SIGCHLD   = C.SIGCHLD
-	SIGTTIN   = C.SIGTTIN
-	SIGTTOU   = C.SIGTTOU
-	SIGIO     = C.SIGIO
-	SIGXCPU   = C.SIGXCPU
-	SIGXFSZ   = C.SIGXFSZ
-	SIGVTALRM = C.SIGVTALRM
-	SIGPROF   = C.SIGPROF
-	SIGWINCH  = C.SIGWINCH
-	SIGINFO   = C.SIGINFO
-	SIGUSR1   = C.SIGUSR1
-	SIGUSR2   = C.SIGUSR2
-
-	FPE_INTDIV = C.FPE_INTDIV
-	FPE_INTOVF = C.FPE_INTOVF
-	FPE_FLTDIV = C.FPE_FLTDIV
-	FPE_FLTOVF = C.FPE_FLTOVF
-	FPE_FLTUND = C.FPE_FLTUND
-	FPE_FLTRES = C.FPE_FLTRES
-	FPE_FLTINV = C.FPE_FLTINV
-	FPE_FLTSUB = C.FPE_FLTSUB
-
-	BUS_ADRALN = C.BUS_ADRALN
-	BUS_ADRERR = C.BUS_ADRERR
-	BUS_OBJERR = C.BUS_OBJERR
-
-	SEGV_MAPERR = C.SEGV_MAPERR
-	SEGV_ACCERR = C.SEGV_ACCERR
-
-	ITIMER_REAL    = C.ITIMER_REAL
-	ITIMER_VIRTUAL = C.ITIMER_VIRTUAL
-	ITIMER_PROF    = C.ITIMER_PROF
-
-	EV_ADD       = C.EV_ADD
-	EV_DELETE    = C.EV_DELETE
-	EV_CLEAR     = C.EV_CLEAR
-	EV_RECEIPT   = C.EV_RECEIPT
-	EV_ERROR     = C.EV_ERROR
-	EVFILT_READ  = C.EVFILT_READ
-	EVFILT_WRITE = C.EVFILT_WRITE
-)
-
-type Rtprio C.struct_rtprio
-type ThrParam C.struct_thr_param
-type Sigaltstack C.struct_sigaltstack
-type Sigset C.struct___sigset
-type StackT C.stack_t
-
-type Siginfo C.siginfo_t
-
-type Mcontext C.mcontext_t
-type Ucontext C.ucontext_t
-
-type Timespec C.struct_timespec
-type Timeval C.struct_timeval
-type Itimerval C.struct_itimerval
-
-type Kevent C.struct_kevent
diff --git a/src/pkg/runtime/defs_freebsd_386.h b/src/pkg/runtime/defs_freebsd_386.h
deleted file mode 100644
index fab9385..0000000
--- a/src/pkg/runtime/defs_freebsd_386.h
+++ /dev/null
@@ -1,213 +0,0 @@
-// Created by cgo -cdefs - DO NOT EDIT
-// cgo -cdefs defs_freebsd.go
-
-
-enum {
-	EINTR	= 0x4,
-	EFAULT	= 0xe,
-
-	PROT_NONE	= 0x0,
-	PROT_READ	= 0x1,
-	PROT_WRITE	= 0x2,
-	PROT_EXEC	= 0x4,
-
-	MAP_ANON	= 0x1000,
-	MAP_PRIVATE	= 0x2,
-	MAP_FIXED	= 0x10,
-
-	MADV_FREE	= 0x5,
-
-	SA_SIGINFO	= 0x40,
-	SA_RESTART	= 0x2,
-	SA_ONSTACK	= 0x1,
-
-	UMTX_OP_WAIT_UINT		= 0xb,
-	UMTX_OP_WAIT_UINT_PRIVATE	= 0xf,
-	UMTX_OP_WAKE			= 0x3,
-	UMTX_OP_WAKE_PRIVATE		= 0x10,
-
-	SIGHUP		= 0x1,
-	SIGINT		= 0x2,
-	SIGQUIT		= 0x3,
-	SIGILL		= 0x4,
-	SIGTRAP		= 0x5,
-	SIGABRT		= 0x6,
-	SIGEMT		= 0x7,
-	SIGFPE		= 0x8,
-	SIGKILL		= 0x9,
-	SIGBUS		= 0xa,
-	SIGSEGV		= 0xb,
-	SIGSYS		= 0xc,
-	SIGPIPE		= 0xd,
-	SIGALRM		= 0xe,
-	SIGTERM		= 0xf,
-	SIGURG		= 0x10,
-	SIGSTOP		= 0x11,
-	SIGTSTP		= 0x12,
-	SIGCONT		= 0x13,
-	SIGCHLD		= 0x14,
-	SIGTTIN		= 0x15,
-	SIGTTOU		= 0x16,
-	SIGIO		= 0x17,
-	SIGXCPU		= 0x18,
-	SIGXFSZ		= 0x19,
-	SIGVTALRM	= 0x1a,
-	SIGPROF		= 0x1b,
-	SIGWINCH	= 0x1c,
-	SIGINFO		= 0x1d,
-	SIGUSR1		= 0x1e,
-	SIGUSR2		= 0x1f,
-
-	FPE_INTDIV	= 0x2,
-	FPE_INTOVF	= 0x1,
-	FPE_FLTDIV	= 0x3,
-	FPE_FLTOVF	= 0x4,
-	FPE_FLTUND	= 0x5,
-	FPE_FLTRES	= 0x6,
-	FPE_FLTINV	= 0x7,
-	FPE_FLTSUB	= 0x8,
-
-	BUS_ADRALN	= 0x1,
-	BUS_ADRERR	= 0x2,
-	BUS_OBJERR	= 0x3,
-
-	SEGV_MAPERR	= 0x1,
-	SEGV_ACCERR	= 0x2,
-
-	ITIMER_REAL	= 0x0,
-	ITIMER_VIRTUAL	= 0x1,
-	ITIMER_PROF	= 0x2,
-
-	EV_ADD		= 0x1,
-	EV_DELETE	= 0x2,
-	EV_CLEAR	= 0x20,
-	EV_RECEIPT	= 0x40,
-	EV_ERROR	= 0x4000,
-	EVFILT_READ	= -0x1,
-	EVFILT_WRITE	= -0x2,
-};
-
-typedef struct Rtprio Rtprio;
-typedef struct ThrParam ThrParam;
-typedef struct Sigaltstack Sigaltstack;
-typedef struct Sigset Sigset;
-typedef struct StackT StackT;
-typedef struct Siginfo Siginfo;
-typedef struct Mcontext Mcontext;
-typedef struct Ucontext Ucontext;
-typedef struct Timespec Timespec;
-typedef struct Timeval Timeval;
-typedef struct Itimerval Itimerval;
-typedef struct Kevent Kevent;
-
-#pragma pack on
-
-struct Rtprio {
-	uint16	type;
-	uint16	prio;
-};
-struct ThrParam {
-	void	*start_func;
-	byte	*arg;
-	int8	*stack_base;
-	uint32	stack_size;
-	int8	*tls_base;
-	uint32	tls_size;
-	int32	*child_tid;
-	int32	*parent_tid;
-	int32	flags;
-	Rtprio	*rtp;
-	void	*spare[3];
-};
-struct Sigaltstack {
-	int8	*ss_sp;
-	uint32	ss_size;
-	int32	ss_flags;
-};
-struct Sigset {
-	uint32	__bits[4];
-};
-struct StackT {
-	int8	*ss_sp;
-	uint32	ss_size;
-	int32	ss_flags;
-};
-
-struct Siginfo {
-	int32	si_signo;
-	int32	si_errno;
-	int32	si_code;
-	int32	si_pid;
-	uint32	si_uid;
-	int32	si_status;
-	byte	*si_addr;
-	byte	si_value[4];
-	byte	_reason[32];
-};
-
-struct Mcontext {
-	int32	mc_onstack;
-	int32	mc_gs;
-	int32	mc_fs;
-	int32	mc_es;
-	int32	mc_ds;
-	int32	mc_edi;
-	int32	mc_esi;
-	int32	mc_ebp;
-	int32	mc_isp;
-	int32	mc_ebx;
-	int32	mc_edx;
-	int32	mc_ecx;
-	int32	mc_eax;
-	int32	mc_trapno;
-	int32	mc_err;
-	int32	mc_eip;
-	int32	mc_cs;
-	int32	mc_eflags;
-	int32	mc_esp;
-	int32	mc_ss;
-	int32	mc_len;
-	int32	mc_fpformat;
-	int32	mc_ownedfp;
-	int32	mc_flags;
-	int32	mc_fpstate[128];
-	int32	mc_fsbase;
-	int32	mc_gsbase;
-	int32	mc_xfpustate;
-	int32	mc_xfpustate_len;
-	int32	mc_spare2[4];
-};
-struct Ucontext {
-	Sigset	uc_sigmask;
-	Mcontext	uc_mcontext;
-	Ucontext	*uc_link;
-	StackT	uc_stack;
-	int32	uc_flags;
-	int32	__spare__[4];
-	byte	Pad_cgo_0[12];
-};
-
-struct Timespec {
-	int32	tv_sec;
-	int32	tv_nsec;
-};
-struct Timeval {
-	int32	tv_sec;
-	int32	tv_usec;
-};
-struct Itimerval {
-	Timeval	it_interval;
-	Timeval	it_value;
-};
-
-struct Kevent {
-	uint32	ident;
-	int16	filter;
-	uint16	flags;
-	uint32	fflags;
-	int32	data;
-	byte	*udata;
-};
-
-
-#pragma pack off
diff --git a/src/pkg/runtime/defs_freebsd_amd64.h b/src/pkg/runtime/defs_freebsd_amd64.h
deleted file mode 100644
index c1db918..0000000
--- a/src/pkg/runtime/defs_freebsd_amd64.h
+++ /dev/null
@@ -1,224 +0,0 @@
-// Created by cgo -cdefs - DO NOT EDIT
-// cgo -cdefs defs_freebsd.go
-
-
-enum {
-	EINTR	= 0x4,
-	EFAULT	= 0xe,
-
-	PROT_NONE	= 0x0,
-	PROT_READ	= 0x1,
-	PROT_WRITE	= 0x2,
-	PROT_EXEC	= 0x4,
-
-	MAP_ANON	= 0x1000,
-	MAP_PRIVATE	= 0x2,
-	MAP_FIXED	= 0x10,
-
-	MADV_FREE	= 0x5,
-
-	SA_SIGINFO	= 0x40,
-	SA_RESTART	= 0x2,
-	SA_ONSTACK	= 0x1,
-
-	UMTX_OP_WAIT_UINT		= 0xb,
-	UMTX_OP_WAIT_UINT_PRIVATE	= 0xf,
-	UMTX_OP_WAKE			= 0x3,
-	UMTX_OP_WAKE_PRIVATE		= 0x10,
-
-	SIGHUP		= 0x1,
-	SIGINT		= 0x2,
-	SIGQUIT		= 0x3,
-	SIGILL		= 0x4,
-	SIGTRAP		= 0x5,
-	SIGABRT		= 0x6,
-	SIGEMT		= 0x7,
-	SIGFPE		= 0x8,
-	SIGKILL		= 0x9,
-	SIGBUS		= 0xa,
-	SIGSEGV		= 0xb,
-	SIGSYS		= 0xc,
-	SIGPIPE		= 0xd,
-	SIGALRM		= 0xe,
-	SIGTERM		= 0xf,
-	SIGURG		= 0x10,
-	SIGSTOP		= 0x11,
-	SIGTSTP		= 0x12,
-	SIGCONT		= 0x13,
-	SIGCHLD		= 0x14,
-	SIGTTIN		= 0x15,
-	SIGTTOU		= 0x16,
-	SIGIO		= 0x17,
-	SIGXCPU		= 0x18,
-	SIGXFSZ		= 0x19,
-	SIGVTALRM	= 0x1a,
-	SIGPROF		= 0x1b,
-	SIGWINCH	= 0x1c,
-	SIGINFO		= 0x1d,
-	SIGUSR1		= 0x1e,
-	SIGUSR2		= 0x1f,
-
-	FPE_INTDIV	= 0x2,
-	FPE_INTOVF	= 0x1,
-	FPE_FLTDIV	= 0x3,
-	FPE_FLTOVF	= 0x4,
-	FPE_FLTUND	= 0x5,
-	FPE_FLTRES	= 0x6,
-	FPE_FLTINV	= 0x7,
-	FPE_FLTSUB	= 0x8,
-
-	BUS_ADRALN	= 0x1,
-	BUS_ADRERR	= 0x2,
-	BUS_OBJERR	= 0x3,
-
-	SEGV_MAPERR	= 0x1,
-	SEGV_ACCERR	= 0x2,
-
-	ITIMER_REAL	= 0x0,
-	ITIMER_VIRTUAL	= 0x1,
-	ITIMER_PROF	= 0x2,
-
-	EV_ADD		= 0x1,
-	EV_DELETE	= 0x2,
-	EV_CLEAR	= 0x20,
-	EV_RECEIPT	= 0x40,
-	EV_ERROR	= 0x4000,
-	EVFILT_READ	= -0x1,
-	EVFILT_WRITE	= -0x2,
-};
-
-typedef struct Rtprio Rtprio;
-typedef struct ThrParam ThrParam;
-typedef struct Sigaltstack Sigaltstack;
-typedef struct Sigset Sigset;
-typedef struct StackT StackT;
-typedef struct Siginfo Siginfo;
-typedef struct Mcontext Mcontext;
-typedef struct Ucontext Ucontext;
-typedef struct Timespec Timespec;
-typedef struct Timeval Timeval;
-typedef struct Itimerval Itimerval;
-typedef struct Kevent Kevent;
-
-#pragma pack on
-
-struct Rtprio {
-	uint16	type;
-	uint16	prio;
-};
-struct ThrParam {
-	void	*start_func;
-	byte	*arg;
-	int8	*stack_base;
-	uint64	stack_size;
-	int8	*tls_base;
-	uint64	tls_size;
-	int64	*child_tid;
-	int64	*parent_tid;
-	int32	flags;
-	byte	Pad_cgo_0[4];
-	Rtprio	*rtp;
-	void	*spare[3];
-};
-struct Sigaltstack {
-	int8	*ss_sp;
-	uint64	ss_size;
-	int32	ss_flags;
-	byte	Pad_cgo_0[4];
-};
-struct Sigset {
-	uint32	__bits[4];
-};
-struct StackT {
-	int8	*ss_sp;
-	uint64	ss_size;
-	int32	ss_flags;
-	byte	Pad_cgo_0[4];
-};
-
-struct Siginfo {
-	int32	si_signo;
-	int32	si_errno;
-	int32	si_code;
-	int32	si_pid;
-	uint32	si_uid;
-	int32	si_status;
-	byte	*si_addr;
-	byte	si_value[8];
-	byte	_reason[40];
-};
-
-struct Mcontext {
-	int64	mc_onstack;
-	int64	mc_rdi;
-	int64	mc_rsi;
-	int64	mc_rdx;
-	int64	mc_rcx;
-	int64	mc_r8;
-	int64	mc_r9;
-	int64	mc_rax;
-	int64	mc_rbx;
-	int64	mc_rbp;
-	int64	mc_r10;
-	int64	mc_r11;
-	int64	mc_r12;
-	int64	mc_r13;
-	int64	mc_r14;
-	int64	mc_r15;
-	uint32	mc_trapno;
-	uint16	mc_fs;
-	uint16	mc_gs;
-	int64	mc_addr;
-	uint32	mc_flags;
-	uint16	mc_es;
-	uint16	mc_ds;
-	int64	mc_err;
-	int64	mc_rip;
-	int64	mc_cs;
-	int64	mc_rflags;
-	int64	mc_rsp;
-	int64	mc_ss;
-	int64	mc_len;
-	int64	mc_fpformat;
-	int64	mc_ownedfp;
-	int64	mc_fpstate[64];
-	int64	mc_fsbase;
-	int64	mc_gsbase;
-	int64	mc_xfpustate;
-	int64	mc_xfpustate_len;
-	int64	mc_spare[4];
-};
-struct Ucontext {
-	Sigset	uc_sigmask;
-	Mcontext	uc_mcontext;
-	Ucontext	*uc_link;
-	StackT	uc_stack;
-	int32	uc_flags;
-	int32	__spare__[4];
-	byte	Pad_cgo_0[12];
-};
-
-struct Timespec {
-	int64	tv_sec;
-	int64	tv_nsec;
-};
-struct Timeval {
-	int64	tv_sec;
-	int64	tv_usec;
-};
-struct Itimerval {
-	Timeval	it_interval;
-	Timeval	it_value;
-};
-
-struct Kevent {
-	uint64	ident;
-	int16	filter;
-	uint16	flags;
-	uint32	fflags;
-	int64	data;
-	byte	*udata;
-};
-
-
-#pragma pack off
diff --git a/src/pkg/runtime/defs_freebsd_arm.h b/src/pkg/runtime/defs_freebsd_arm.h
deleted file mode 100644
index 4fc452e..0000000
--- a/src/pkg/runtime/defs_freebsd_arm.h
+++ /dev/null
@@ -1,186 +0,0 @@
-// Created by cgo -cdefs - DO NOT EDIT
-// cgo -cdefs defs_freebsd.go
-
-
-enum {
-	EINTR	= 0x4,
-	EFAULT	= 0xe,
-
-	PROT_NONE	= 0x0,
-	PROT_READ	= 0x1,
-	PROT_WRITE	= 0x2,
-	PROT_EXEC	= 0x4,
-
-	MAP_ANON	= 0x1000,
-	MAP_PRIVATE	= 0x2,
-	MAP_FIXED	= 0x10,
-
-	MADV_FREE	= 0x5,
-
-	SA_SIGINFO	= 0x40,
-	SA_RESTART	= 0x2,
-	SA_ONSTACK	= 0x1,
-
-	UMTX_OP_WAIT_UINT		= 0xb,
-	UMTX_OP_WAIT_UINT_PRIVATE	= 0xf,
-	UMTX_OP_WAKE			= 0x3,
-	UMTX_OP_WAKE_PRIVATE		= 0x10,
-
-	SIGHUP		= 0x1,
-	SIGINT		= 0x2,
-	SIGQUIT		= 0x3,
-	SIGILL		= 0x4,
-	SIGTRAP		= 0x5,
-	SIGABRT		= 0x6,
-	SIGEMT		= 0x7,
-	SIGFPE		= 0x8,
-	SIGKILL		= 0x9,
-	SIGBUS		= 0xa,
-	SIGSEGV		= 0xb,
-	SIGSYS		= 0xc,
-	SIGPIPE		= 0xd,
-	SIGALRM		= 0xe,
-	SIGTERM		= 0xf,
-	SIGURG		= 0x10,
-	SIGSTOP		= 0x11,
-	SIGTSTP		= 0x12,
-	SIGCONT		= 0x13,
-	SIGCHLD		= 0x14,
-	SIGTTIN		= 0x15,
-	SIGTTOU		= 0x16,
-	SIGIO		= 0x17,
-	SIGXCPU		= 0x18,
-	SIGXFSZ		= 0x19,
-	SIGVTALRM	= 0x1a,
-	SIGPROF		= 0x1b,
-	SIGWINCH	= 0x1c,
-	SIGINFO		= 0x1d,
-	SIGUSR1		= 0x1e,
-	SIGUSR2		= 0x1f,
-
-	FPE_INTDIV	= 0x2,
-	FPE_INTOVF	= 0x1,
-	FPE_FLTDIV	= 0x3,
-	FPE_FLTOVF	= 0x4,
-	FPE_FLTUND	= 0x5,
-	FPE_FLTRES	= 0x6,
-	FPE_FLTINV	= 0x7,
-	FPE_FLTSUB	= 0x8,
-
-	BUS_ADRALN	= 0x1,
-	BUS_ADRERR	= 0x2,
-	BUS_OBJERR	= 0x3,
-
-	SEGV_MAPERR	= 0x1,
-	SEGV_ACCERR	= 0x2,
-
-	ITIMER_REAL	= 0x0,
-	ITIMER_VIRTUAL	= 0x1,
-	ITIMER_PROF	= 0x2,
-
-	EV_ADD		= 0x1,
-	EV_DELETE	= 0x2,
-	EV_CLEAR	= 0x20,
-	EV_RECEIPT	= 0x40,
-	EV_ERROR	= 0x4000,
-	EVFILT_READ	= -0x1,
-	EVFILT_WRITE	= -0x2,
-};
-
-typedef struct Rtprio Rtprio;
-typedef struct ThrParam ThrParam;
-typedef struct Sigaltstack Sigaltstack;
-typedef struct Sigset Sigset;
-typedef struct StackT StackT;
-typedef struct Siginfo Siginfo;
-typedef struct Mcontext Mcontext;
-typedef struct Ucontext Ucontext;
-typedef struct Timespec Timespec;
-typedef struct Timeval Timeval;
-typedef struct Itimerval Itimerval;
-typedef struct Kevent Kevent;
-
-#pragma pack on
-
-struct Rtprio {
-	uint16	type;
-	uint16	prio;
-};
-struct ThrParam {
-	void	*start_func;
-	byte	*arg;
-	uint8	*stack_base;
-	uint32	stack_size;
-	uint8	*tls_base;
-	uint32	tls_size;
-	int32	*child_tid;
-	int32	*parent_tid;
-	int32	flags;
-	Rtprio	*rtp;
-	void	*spare[3];
-};
-struct Sigaltstack {
-	uint8	*ss_sp;
-	uint32	ss_size;
-	int32	ss_flags;
-};
-struct Sigset {
-	uint32	__bits[4];
-};
-struct StackT {
-	uint8	*ss_sp;
-	uint32	ss_size;
-	int32	ss_flags;
-};
-
-struct Siginfo {
-	int32	si_signo;
-	int32	si_errno;
-	int32	si_code;
-	int32	si_pid;
-	uint32	si_uid;
-	int32	si_status;
-	byte	*si_addr;
-	byte	si_value[4];
-	byte	_reason[32];
-};
-
-struct Mcontext {
-	uint32	__gregs[17];
-	byte	__fpu[140];
-};
-struct Ucontext {
-	Sigset	uc_sigmask;
-	Mcontext	uc_mcontext;
-	Ucontext	*uc_link;
-	StackT	uc_stack;
-	int32	uc_flags;
-	int32	__spare__[4];
-};
-
-struct Timespec {
-	int64	tv_sec;
-	int32	tv_nsec;
-	byte	Pad_cgo_0[4];
-};
-struct Timeval {
-	int64	tv_sec;
-	int32	tv_usec;
-	byte	Pad_cgo_0[4];
-};
-struct Itimerval {
-	Timeval	it_interval;
-	Timeval	it_value;
-};
-
-struct Kevent {
-	uint32	ident;
-	int16	filter;
-	uint16	flags;
-	uint32	fflags;
-	int32	data;
-	byte	*udata;
-};
-
-
-#pragma pack off
diff --git a/src/pkg/runtime/defs_linux.go b/src/pkg/runtime/defs_linux.go
deleted file mode 100644
index 2f4e03a..0000000
--- a/src/pkg/runtime/defs_linux.go
+++ /dev/null
@@ -1,123 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build ignore
-
-/*
-Input to cgo -cdefs
-
-GOARCH=amd64 go tool cgo -cdefs defs_linux.go defs1_linux.go >defs_linux_amd64.h
-*/
-
-package runtime
-
-/*
-// Linux glibc and Linux kernel define different and conflicting
-// definitions for struct sigaction, struct timespec, etc.
-// We want the kernel ones, which are in the asm/* headers.
-// But then we'd get conflicts when we include the system
-// headers for things like ucontext_t, so that happens in
-// a separate file, defs1.go.
-
-#include <asm/posix_types.h>
-#define size_t __kernel_size_t
-#include <asm/signal.h>
-#include <asm/siginfo.h>
-#include <asm/mman.h>
-#include <asm-generic/errno.h>
-#include <asm-generic/poll.h>
-#include <linux/eventpoll.h>
-*/
-import "C"
-
-const (
-	EINTR  = C.EINTR
-	EAGAIN = C.EAGAIN
-	ENOMEM = C.ENOMEM
-
-	PROT_NONE  = C.PROT_NONE
-	PROT_READ  = C.PROT_READ
-	PROT_WRITE = C.PROT_WRITE
-	PROT_EXEC  = C.PROT_EXEC
-
-	MAP_ANON    = C.MAP_ANONYMOUS
-	MAP_PRIVATE = C.MAP_PRIVATE
-	MAP_FIXED   = C.MAP_FIXED
-
-	MADV_DONTNEED = C.MADV_DONTNEED
-
-	SA_RESTART  = C.SA_RESTART
-	SA_ONSTACK  = C.SA_ONSTACK
-	SA_RESTORER = C.SA_RESTORER
-	SA_SIGINFO  = C.SA_SIGINFO
-
-	SIGHUP    = C.SIGHUP
-	SIGINT    = C.SIGINT
-	SIGQUIT   = C.SIGQUIT
-	SIGILL    = C.SIGILL
-	SIGTRAP   = C.SIGTRAP
-	SIGABRT   = C.SIGABRT
-	SIGBUS    = C.SIGBUS
-	SIGFPE    = C.SIGFPE
-	SIGKILL   = C.SIGKILL
-	SIGUSR1   = C.SIGUSR1
-	SIGSEGV   = C.SIGSEGV
-	SIGUSR2   = C.SIGUSR2
-	SIGPIPE   = C.SIGPIPE
-	SIGALRM   = C.SIGALRM
-	SIGSTKFLT = C.SIGSTKFLT
-	SIGCHLD   = C.SIGCHLD
-	SIGCONT   = C.SIGCONT
-	SIGSTOP   = C.SIGSTOP
-	SIGTSTP   = C.SIGTSTP
-	SIGTTIN   = C.SIGTTIN
-	SIGTTOU   = C.SIGTTOU
-	SIGURG    = C.SIGURG
-	SIGXCPU   = C.SIGXCPU
-	SIGXFSZ   = C.SIGXFSZ
-	SIGVTALRM = C.SIGVTALRM
-	SIGPROF   = C.SIGPROF
-	SIGWINCH  = C.SIGWINCH
-	SIGIO     = C.SIGIO
-	SIGPWR    = C.SIGPWR
-	SIGSYS    = C.SIGSYS
-
-	FPE_INTDIV = C.FPE_INTDIV
-	FPE_INTOVF = C.FPE_INTOVF
-	FPE_FLTDIV = C.FPE_FLTDIV
-	FPE_FLTOVF = C.FPE_FLTOVF
-	FPE_FLTUND = C.FPE_FLTUND
-	FPE_FLTRES = C.FPE_FLTRES
-	FPE_FLTINV = C.FPE_FLTINV
-	FPE_FLTSUB = C.FPE_FLTSUB
-
-	BUS_ADRALN = C.BUS_ADRALN
-	BUS_ADRERR = C.BUS_ADRERR
-	BUS_OBJERR = C.BUS_OBJERR
-
-	SEGV_MAPERR = C.SEGV_MAPERR
-	SEGV_ACCERR = C.SEGV_ACCERR
-
-	ITIMER_REAL    = C.ITIMER_REAL
-	ITIMER_VIRTUAL = C.ITIMER_VIRTUAL
-	ITIMER_PROF    = C.ITIMER_PROF
-
-	EPOLLIN       = C.POLLIN
-	EPOLLOUT      = C.POLLOUT
-	EPOLLERR      = C.POLLERR
-	EPOLLHUP      = C.POLLHUP
-	EPOLLRDHUP    = C.POLLRDHUP
-	EPOLLET       = C.EPOLLET
-	EPOLL_CLOEXEC = C.EPOLL_CLOEXEC
-	EPOLL_CTL_ADD = C.EPOLL_CTL_ADD
-	EPOLL_CTL_DEL = C.EPOLL_CTL_DEL
-	EPOLL_CTL_MOD = C.EPOLL_CTL_MOD
-)
-
-type Timespec C.struct_timespec
-type Timeval C.struct_timeval
-type Sigaction C.struct_sigaction
-type Siginfo C.siginfo_t
-type Itimerval C.struct_itimerval
-type EpollEvent C.struct_epoll_event
diff --git a/src/pkg/runtime/defs_linux_386.h b/src/pkg/runtime/defs_linux_386.h
deleted file mode 100644
index 27dae9e..0000000
--- a/src/pkg/runtime/defs_linux_386.h
+++ /dev/null
@@ -1,211 +0,0 @@
-// Created by cgo -cdefs - DO NOT EDIT
-// cgo -cdefs defs2_linux.go
-
-
-enum {
-	EINTR	= 0x4,
-	EAGAIN	= 0xb,
-	ENOMEM	= 0xc,
-
-	PROT_NONE	= 0x0,
-	PROT_READ	= 0x1,
-	PROT_WRITE	= 0x2,
-	PROT_EXEC	= 0x4,
-
-	MAP_ANON	= 0x20,
-	MAP_PRIVATE	= 0x2,
-	MAP_FIXED	= 0x10,
-
-	MADV_DONTNEED	= 0x4,
-
-	SA_RESTART	= 0x10000000,
-	SA_ONSTACK	= 0x8000000,
-	SA_RESTORER	= 0x4000000,
-	SA_SIGINFO	= 0x4,
-
-	SIGHUP		= 0x1,
-	SIGINT		= 0x2,
-	SIGQUIT		= 0x3,
-	SIGILL		= 0x4,
-	SIGTRAP		= 0x5,
-	SIGABRT		= 0x6,
-	SIGBUS		= 0x7,
-	SIGFPE		= 0x8,
-	SIGKILL		= 0x9,
-	SIGUSR1		= 0xa,
-	SIGSEGV		= 0xb,
-	SIGUSR2		= 0xc,
-	SIGPIPE		= 0xd,
-	SIGALRM		= 0xe,
-	SIGSTKFLT	= 0x10,
-	SIGCHLD		= 0x11,
-	SIGCONT		= 0x12,
-	SIGSTOP		= 0x13,
-	SIGTSTP		= 0x14,
-	SIGTTIN		= 0x15,
-	SIGTTOU		= 0x16,
-	SIGURG		= 0x17,
-	SIGXCPU		= 0x18,
-	SIGXFSZ		= 0x19,
-	SIGVTALRM	= 0x1a,
-	SIGPROF		= 0x1b,
-	SIGWINCH	= 0x1c,
-	SIGIO		= 0x1d,
-	SIGPWR		= 0x1e,
-	SIGSYS		= 0x1f,
-
-	FPE_INTDIV	= 0x1,
-	FPE_INTOVF	= 0x2,
-	FPE_FLTDIV	= 0x3,
-	FPE_FLTOVF	= 0x4,
-	FPE_FLTUND	= 0x5,
-	FPE_FLTRES	= 0x6,
-	FPE_FLTINV	= 0x7,
-	FPE_FLTSUB	= 0x8,
-
-	BUS_ADRALN	= 0x1,
-	BUS_ADRERR	= 0x2,
-	BUS_OBJERR	= 0x3,
-
-	SEGV_MAPERR	= 0x1,
-	SEGV_ACCERR	= 0x2,
-
-	ITIMER_REAL	= 0x0,
-	ITIMER_VIRTUAL	= 0x1,
-	ITIMER_PROF	= 0x2,
-
-	O_RDONLY	= 0x0,
-	O_CLOEXEC	= 0x80000,
-
-	EPOLLIN		= 0x1,
-	EPOLLOUT	= 0x4,
-	EPOLLERR	= 0x8,
-	EPOLLHUP	= 0x10,
-	EPOLLRDHUP	= 0x2000,
-	EPOLLET		= -0x80000000,
-	EPOLL_CLOEXEC	= 0x80000,
-	EPOLL_CTL_ADD	= 0x1,
-	EPOLL_CTL_DEL	= 0x2,
-	EPOLL_CTL_MOD	= 0x3,
-};
-
-typedef struct Fpreg Fpreg;
-typedef struct Fpxreg Fpxreg;
-typedef struct Xmmreg Xmmreg;
-typedef struct Fpstate Fpstate;
-typedef struct Timespec Timespec;
-typedef struct Timeval Timeval;
-typedef struct Sigaction Sigaction;
-typedef struct Siginfo Siginfo;
-typedef struct Sigaltstack Sigaltstack;
-typedef struct Sigcontext Sigcontext;
-typedef struct Ucontext Ucontext;
-typedef struct Itimerval Itimerval;
-typedef struct EpollEvent EpollEvent;
-
-#pragma pack on
-
-struct Fpreg {
-	uint16	significand[4];
-	uint16	exponent;
-};
-struct Fpxreg {
-	uint16	significand[4];
-	uint16	exponent;
-	uint16	padding[3];
-};
-struct Xmmreg {
-	uint32	element[4];
-};
-struct Fpstate {
-	uint32	cw;
-	uint32	sw;
-	uint32	tag;
-	uint32	ipoff;
-	uint32	cssel;
-	uint32	dataoff;
-	uint32	datasel;
-	Fpreg	_st[8];
-	uint16	status;
-	uint16	magic;
-	uint32	_fxsr_env[6];
-	uint32	mxcsr;
-	uint32	reserved;
-	Fpxreg	_fxsr_st[8];
-	Xmmreg	_xmm[8];
-	uint32	padding1[44];
-	byte	anon0[48];
-};
-struct Timespec {
-	int32	tv_sec;
-	int32	tv_nsec;
-};
-struct Timeval {
-	int32	tv_sec;
-	int32	tv_usec;
-};
-struct Sigaction {
-	void	*k_sa_handler;
-	uint32	sa_flags;
-	void	*sa_restorer;
-	uint64	sa_mask;
-};
-struct Siginfo {
-	int32	si_signo;
-	int32	si_errno;
-	int32	si_code;
-	byte	_sifields[116];
-};
-struct Sigaltstack {
-	byte	*ss_sp;
-	int32	ss_flags;
-	uint32	ss_size;
-};
-struct Sigcontext {
-	uint16	gs;
-	uint16	__gsh;
-	uint16	fs;
-	uint16	__fsh;
-	uint16	es;
-	uint16	__esh;
-	uint16	ds;
-	uint16	__dsh;
-	uint32	edi;
-	uint32	esi;
-	uint32	ebp;
-	uint32	esp;
-	uint32	ebx;
-	uint32	edx;
-	uint32	ecx;
-	uint32	eax;
-	uint32	trapno;
-	uint32	err;
-	uint32	eip;
-	uint16	cs;
-	uint16	__csh;
-	uint32	eflags;
-	uint32	esp_at_signal;
-	uint16	ss;
-	uint16	__ssh;
-	Fpstate	*fpstate;
-	uint32	oldmask;
-	uint32	cr2;
-};
-struct Ucontext {
-	uint32	uc_flags;
-	Ucontext	*uc_link;
-	Sigaltstack	uc_stack;
-	Sigcontext	uc_mcontext;
-	uint32	uc_sigmask;
-};
-struct Itimerval {
-	Timeval	it_interval;
-	Timeval	it_value;
-};
-struct EpollEvent {
-	uint32	events;
-	uint64	data;
-};
-
-
-#pragma pack off
diff --git a/src/pkg/runtime/defs_linux_amd64.h b/src/pkg/runtime/defs_linux_amd64.h
deleted file mode 100644
index 3e87df6..0000000
--- a/src/pkg/runtime/defs_linux_amd64.h
+++ /dev/null
@@ -1,254 +0,0 @@
-// Created by cgo -cdefs - DO NOT EDIT
-// cgo -cdefs defs_linux.go defs1_linux.go
-
-
-enum {
-	EINTR	= 0x4,
-	EAGAIN	= 0xb,
-	ENOMEM	= 0xc,
-
-	PROT_NONE	= 0x0,
-	PROT_READ	= 0x1,
-	PROT_WRITE	= 0x2,
-	PROT_EXEC	= 0x4,
-
-	MAP_ANON	= 0x20,
-	MAP_PRIVATE	= 0x2,
-	MAP_FIXED	= 0x10,
-
-	MADV_DONTNEED	= 0x4,
-
-	SA_RESTART	= 0x10000000,
-	SA_ONSTACK	= 0x8000000,
-	SA_RESTORER	= 0x4000000,
-	SA_SIGINFO	= 0x4,
-
-	SIGHUP		= 0x1,
-	SIGINT		= 0x2,
-	SIGQUIT		= 0x3,
-	SIGILL		= 0x4,
-	SIGTRAP		= 0x5,
-	SIGABRT		= 0x6,
-	SIGBUS		= 0x7,
-	SIGFPE		= 0x8,
-	SIGKILL		= 0x9,
-	SIGUSR1		= 0xa,
-	SIGSEGV		= 0xb,
-	SIGUSR2		= 0xc,
-	SIGPIPE		= 0xd,
-	SIGALRM		= 0xe,
-	SIGSTKFLT	= 0x10,
-	SIGCHLD		= 0x11,
-	SIGCONT		= 0x12,
-	SIGSTOP		= 0x13,
-	SIGTSTP		= 0x14,
-	SIGTTIN		= 0x15,
-	SIGTTOU		= 0x16,
-	SIGURG		= 0x17,
-	SIGXCPU		= 0x18,
-	SIGXFSZ		= 0x19,
-	SIGVTALRM	= 0x1a,
-	SIGPROF		= 0x1b,
-	SIGWINCH	= 0x1c,
-	SIGIO		= 0x1d,
-	SIGPWR		= 0x1e,
-	SIGSYS		= 0x1f,
-
-	FPE_INTDIV	= 0x1,
-	FPE_INTOVF	= 0x2,
-	FPE_FLTDIV	= 0x3,
-	FPE_FLTOVF	= 0x4,
-	FPE_FLTUND	= 0x5,
-	FPE_FLTRES	= 0x6,
-	FPE_FLTINV	= 0x7,
-	FPE_FLTSUB	= 0x8,
-
-	BUS_ADRALN	= 0x1,
-	BUS_ADRERR	= 0x2,
-	BUS_OBJERR	= 0x3,
-
-	SEGV_MAPERR	= 0x1,
-	SEGV_ACCERR	= 0x2,
-
-	ITIMER_REAL	= 0x0,
-	ITIMER_VIRTUAL	= 0x1,
-	ITIMER_PROF	= 0x2,
-
-	EPOLLIN		= 0x1,
-	EPOLLOUT	= 0x4,
-	EPOLLERR	= 0x8,
-	EPOLLHUP	= 0x10,
-	EPOLLRDHUP	= 0x2000,
-	EPOLLET		= -0x80000000,
-	EPOLL_CLOEXEC	= 0x80000,
-	EPOLL_CTL_ADD	= 0x1,
-	EPOLL_CTL_DEL	= 0x2,
-	EPOLL_CTL_MOD	= 0x3,
-};
-
-typedef struct Timespec Timespec;
-typedef struct Timeval Timeval;
-typedef struct Sigaction Sigaction;
-typedef struct Siginfo Siginfo;
-typedef struct Itimerval Itimerval;
-typedef struct EpollEvent EpollEvent;
-
-#pragma pack on
-
-struct Timespec {
-	int64	tv_sec;
-	int64	tv_nsec;
-};
-struct Timeval {
-	int64	tv_sec;
-	int64	tv_usec;
-};
-struct Sigaction {
-	void	*sa_handler;
-	uint64	sa_flags;
-	void	*sa_restorer;
-	uint64	sa_mask;
-};
-struct Siginfo {
-	int32	si_signo;
-	int32	si_errno;
-	int32	si_code;
-	byte	Pad_cgo_0[4];
-	byte	_sifields[112];
-};
-struct Itimerval {
-	Timeval	it_interval;
-	Timeval	it_value;
-};
-struct EpollEvent {
-	uint32	events;
-	uint64	data;
-};
-
-
-#pragma pack off
-// Created by cgo -cdefs - DO NOT EDIT
-// cgo -cdefs defs_linux.go defs1_linux.go
-
-
-enum {
-	O_RDONLY	= 0x0,
-	O_CLOEXEC	= 0x80000,
-};
-
-typedef struct Usigset Usigset;
-typedef struct Fpxreg Fpxreg;
-typedef struct Xmmreg Xmmreg;
-typedef struct Fpstate Fpstate;
-typedef struct Fpxreg1 Fpxreg1;
-typedef struct Xmmreg1 Xmmreg1;
-typedef struct Fpstate1 Fpstate1;
-typedef struct Fpreg1 Fpreg1;
-typedef struct Sigaltstack Sigaltstack;
-typedef struct Mcontext Mcontext;
-typedef struct Ucontext Ucontext;
-typedef struct Sigcontext Sigcontext;
-
-#pragma pack on
-
-struct Usigset {
-	uint64	__val[16];
-};
-struct Fpxreg {
-	uint16	significand[4];
-	uint16	exponent;
-	uint16	padding[3];
-};
-struct Xmmreg {
-	uint32	element[4];
-};
-struct Fpstate {
-	uint16	cwd;
-	uint16	swd;
-	uint16	ftw;
-	uint16	fop;
-	uint64	rip;
-	uint64	rdp;
-	uint32	mxcsr;
-	uint32	mxcr_mask;
-	Fpxreg	_st[8];
-	Xmmreg	_xmm[16];
-	uint32	padding[24];
-};
-struct Fpxreg1 {
-	uint16	significand[4];
-	uint16	exponent;
-	uint16	padding[3];
-};
-struct Xmmreg1 {
-	uint32	element[4];
-};
-struct Fpstate1 {
-	uint16	cwd;
-	uint16	swd;
-	uint16	ftw;
-	uint16	fop;
-	uint64	rip;
-	uint64	rdp;
-	uint32	mxcsr;
-	uint32	mxcr_mask;
-	Fpxreg1	_st[8];
-	Xmmreg1	_xmm[16];
-	uint32	padding[24];
-};
-struct Fpreg1 {
-	uint16	significand[4];
-	uint16	exponent;
-};
-struct Sigaltstack {
-	byte	*ss_sp;
-	int32	ss_flags;
-	byte	Pad_cgo_0[4];
-	uint64	ss_size;
-};
-struct Mcontext {
-	int64	gregs[23];
-	Fpstate	*fpregs;
-	uint64	__reserved1[8];
-};
-struct Ucontext {
-	uint64	uc_flags;
-	Ucontext	*uc_link;
-	Sigaltstack	uc_stack;
-	Mcontext	uc_mcontext;
-	Usigset	uc_sigmask;
-	Fpstate	__fpregs_mem;
-};
-struct Sigcontext {
-	uint64	r8;
-	uint64	r9;
-	uint64	r10;
-	uint64	r11;
-	uint64	r12;
-	uint64	r13;
-	uint64	r14;
-	uint64	r15;
-	uint64	rdi;
-	uint64	rsi;
-	uint64	rbp;
-	uint64	rbx;
-	uint64	rdx;
-	uint64	rax;
-	uint64	rcx;
-	uint64	rsp;
-	uint64	rip;
-	uint64	eflags;
-	uint16	cs;
-	uint16	gs;
-	uint16	fs;
-	uint16	__pad0;
-	uint64	err;
-	uint64	trapno;
-	uint64	oldmask;
-	uint64	cr2;
-	Fpstate1	*fpstate;
-	uint64	__reserved1[8];
-};
-
-
-#pragma pack off
diff --git a/src/pkg/runtime/defs_linux_arm.h b/src/pkg/runtime/defs_linux_arm.h
deleted file mode 100644
index 9216096..0000000
--- a/src/pkg/runtime/defs_linux_arm.h
+++ /dev/null
@@ -1,168 +0,0 @@
-// TODO: Generate using cgo like defs_linux_{386,amd64}.h
-
-// Constants
-enum {
-	EINTR  = 0x4,
-	ENOMEM = 0xc,
-	EAGAIN = 0xb,
-
-	PROT_NONE = 0,
-	PROT_READ = 0x1,
-	PROT_WRITE = 0x2,
-	PROT_EXEC = 0x4,
-	MAP_ANON = 0x20,
-	MAP_PRIVATE = 0x2,
-	MAP_FIXED = 0x10,
-	MADV_DONTNEED = 0x4,
-	SA_RESTART = 0x10000000,
-	SA_ONSTACK = 0x8000000,
-	SA_RESTORER = 0x4000000,
-	SA_SIGINFO = 0x4,
-	SIGHUP = 0x1,
-	SIGINT = 0x2,
-	SIGQUIT = 0x3,
-	SIGILL = 0x4,
-	SIGTRAP = 0x5,
-	SIGABRT = 0x6,
-	SIGBUS = 0x7,
-	SIGFPE = 0x8,
-	SIGKILL = 0x9,
-	SIGUSR1 = 0xa,
-	SIGSEGV = 0xb,
-	SIGUSR2 = 0xc,
-	SIGPIPE = 0xd,
-	SIGALRM = 0xe,
-	SIGSTKFLT = 0x10,
-	SIGCHLD = 0x11,
-	SIGCONT = 0x12,
-	SIGSTOP = 0x13,
-	SIGTSTP = 0x14,
-	SIGTTIN = 0x15,
-	SIGTTOU = 0x16,
-	SIGURG = 0x17,
-	SIGXCPU = 0x18,
-	SIGXFSZ = 0x19,
-	SIGVTALRM = 0x1a,
-	SIGPROF = 0x1b,
-	SIGWINCH = 0x1c,
-	SIGIO = 0x1d,
-	SIGPWR = 0x1e,
-	SIGSYS = 0x1f,
-	FPE_INTDIV = 0x1,
-	FPE_INTOVF = 0x2,
-	FPE_FLTDIV = 0x3,
-	FPE_FLTOVF = 0x4,
-	FPE_FLTUND = 0x5,
-	FPE_FLTRES = 0x6,
-	FPE_FLTINV = 0x7,
-	FPE_FLTSUB = 0x8,
-	BUS_ADRALN = 0x1,
-	BUS_ADRERR = 0x2,
-	BUS_OBJERR = 0x3,
-	SEGV_MAPERR = 0x1,
-	SEGV_ACCERR = 0x2,
-	ITIMER_REAL = 0,
-	ITIMER_PROF = 0x2,
-	ITIMER_VIRTUAL = 0x1,
-	O_RDONLY = 0,
-	O_CLOEXEC = 02000000,
-
-	EPOLLIN		= 0x1,
-	EPOLLOUT	= 0x4,
-	EPOLLERR	= 0x8,
-	EPOLLHUP	= 0x10,
-	EPOLLRDHUP	= 0x2000,
-	EPOLLET		= -0x80000000,
-	EPOLL_CLOEXEC	= 0x80000,
-	EPOLL_CTL_ADD	= 0x1,
-	EPOLL_CTL_DEL	= 0x2,
-	EPOLL_CTL_MOD	= 0x3,
-};
-
-// Types
-#pragma pack on
-
-typedef struct Timespec Timespec;
-struct Timespec {
-	int32 tv_sec;
-	int32 tv_nsec;
-};
-
-typedef struct Sigaltstack Sigaltstack;
-struct Sigaltstack {
-	void *ss_sp;
-	int32 ss_flags;
-	uint32 ss_size;
-};
-
-typedef struct Sigcontext Sigcontext;
-struct Sigcontext {
-	uint32 trap_no;
-	uint32 error_code;
-	uint32 oldmask;
-	uint32 arm_r0;
-	uint32 arm_r1;
-	uint32 arm_r2;
-	uint32 arm_r3;
-	uint32 arm_r4;
-	uint32 arm_r5;
-	uint32 arm_r6;
-	uint32 arm_r7;
-	uint32 arm_r8;
-	uint32 arm_r9;
-	uint32 arm_r10;
-	uint32 arm_fp;
-	uint32 arm_ip;
-	uint32 arm_sp;
-	uint32 arm_lr;
-	uint32 arm_pc;
-	uint32 arm_cpsr;
-	uint32 fault_address;
-};
-
-typedef struct Ucontext Ucontext;
-struct Ucontext {
-	uint32 uc_flags;
-	Ucontext *uc_link;
-	Sigaltstack uc_stack;
-	Sigcontext uc_mcontext;
-	uint32 uc_sigmask;
-	int32 __unused[31];
-	uint32 uc_regspace[128];
-};
-
-typedef struct Timeval Timeval;
-struct Timeval {
-	int32 tv_sec;
-	int32 tv_usec;
-};
-
-typedef struct Itimerval Itimerval;
-struct Itimerval {
-	Timeval it_interval;
-	Timeval it_value;
-};
-
-typedef struct Siginfo Siginfo;
-struct Siginfo {
-	int32 si_signo;
-	int32 si_errno;
-	int32 si_code;
-	uint8 _sifields[4];
-};
-
-typedef struct Sigaction Sigaction;
-struct Sigaction {
-	void *sa_handler;
-	uint32 sa_flags;
-	void *sa_restorer;
-	uint64 sa_mask;
-};
-
-typedef struct EpollEvent EpollEvent;
-struct EpollEvent {
-	uint32	events;
-	uint32	_pad;
-	uint64	data;
-};
-#pragma pack off
diff --git a/src/pkg/runtime/defs_nacl_amd64p32.h b/src/pkg/runtime/defs_nacl_amd64p32.h
deleted file mode 100644
index 8d3068b..0000000
--- a/src/pkg/runtime/defs_nacl_amd64p32.h
+++ /dev/null
@@ -1,90 +0,0 @@
-// Copyright 2013 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Created by hand, not machine generated.
-
-enum
-{
-	// These values are referred to in the source code
-	// but really don't matter. Even so, use the standard numbers.
-	SIGSEGV = 11,
-	SIGPROF = 27,
-};
-
-typedef struct Siginfo Siginfo;
-
-
-// native_client/src/trusted/service_runtime/include/machine/_types.h
-typedef struct Timespec Timespec;
-
-struct Timespec
-{
-	int64 tv_sec;
-	int32 tv_nsec;
-};
-
-// native_client/src/trusted/service_runtime/nacl_exception.h
-// native_client/src/include/nacl/nacl_exception.h
-
-typedef struct ExcContext ExcContext;
-typedef struct ExcPortable ExcPortable;
-typedef struct ExcRegs386 ExcRegs386;
-typedef struct ExcRegsAmd64 ExcRegsAmd64;
-
-struct ExcRegs386
-{
-	uint32	eax;
-	uint32	ecx;
-	uint32	edx;
-	uint32	ebx;
-	uint32	esp;
-	uint32	ebp;
-	uint32	esi;
-	uint32	edi;
-	uint32	eip;
-	uint32	eflags;
-};
-
-struct ExcRegsAmd64
-{
-	uint64	rax;
-	uint64	rcx;
-	uint64	rdx;
-	uint64	rbx;
-	uint64	rsp;
-	uint64	rbp;
-	uint64	rsi;
-	uint64	rdi;
-	uint64	r8;
-	uint64	r9;
-	uint64	r10;
-	uint64	r11;
-	uint64	r12;
-	uint64	r13;
-	uint64	r14;
-	uint64	r15;
-	uint64	rip;
-	uint32	rflags;
-};
-
-struct ExcContext
-{
-	uint32	size;
-	uint32	portable_context_offset;
-	uint32	portable_context_size;
-	uint32	arch;
-	uint32	regs_size;
-	uint32	reserved[11];
-	union {
-		ExcRegs386	regs;
-		ExcRegsAmd64	regs64;
-	};
-};
-
-struct ExcPortableContext
-{
-	uint32	pc;
-	uint32	sp;
-	uint32	fp;
-};
diff --git a/src/pkg/runtime/defs_netbsd.go b/src/pkg/runtime/defs_netbsd.go
deleted file mode 100644
index d1c4cbe..0000000
--- a/src/pkg/runtime/defs_netbsd.go
+++ /dev/null
@@ -1,125 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build ignore
-
-/*
-Input to cgo.
-
-GOARCH=amd64 go tool cgo -cdefs defs_netbsd.go defs_netbsd_amd64.go >defs_netbsd_amd64.h
-GOARCH=386 go tool cgo -cdefs defs_netbsd.go defs_netbsd_386.go >defs_netbsd_386.h
-GOARCH=arm go tool cgo -cdefs defs_netbsd.go defs_netbsd_arm.go >defs_netbsd_arm.h
-*/
-
-// +godefs map __fpregset_t [644]byte
-
-package runtime
-
-/*
-#include <sys/types.h>
-#include <sys/mman.h>
-#include <sys/signal.h>
-#include <sys/event.h>
-#include <sys/time.h>
-#include <sys/ucontext.h>
-#include <sys/unistd.h>
-#include <errno.h>
-#include <signal.h>
-*/
-import "C"
-
-const (
-	EINTR  = C.EINTR
-	EFAULT = C.EFAULT
-
-	PROT_NONE  = C.PROT_NONE
-	PROT_READ  = C.PROT_READ
-	PROT_WRITE = C.PROT_WRITE
-	PROT_EXEC  = C.PROT_EXEC
-
-	MAP_ANON    = C.MAP_ANON
-	MAP_PRIVATE = C.MAP_PRIVATE
-	MAP_FIXED   = C.MAP_FIXED
-
-	MADV_FREE = C.MADV_FREE
-
-	SA_SIGINFO = C.SA_SIGINFO
-	SA_RESTART = C.SA_RESTART
-	SA_ONSTACK = C.SA_ONSTACK
-
-	SIGHUP    = C.SIGHUP
-	SIGINT    = C.SIGINT
-	SIGQUIT   = C.SIGQUIT
-	SIGILL    = C.SIGILL
-	SIGTRAP   = C.SIGTRAP
-	SIGABRT   = C.SIGABRT
-	SIGEMT    = C.SIGEMT
-	SIGFPE    = C.SIGFPE
-	SIGKILL   = C.SIGKILL
-	SIGBUS    = C.SIGBUS
-	SIGSEGV   = C.SIGSEGV
-	SIGSYS    = C.SIGSYS
-	SIGPIPE   = C.SIGPIPE
-	SIGALRM   = C.SIGALRM
-	SIGTERM   = C.SIGTERM
-	SIGURG    = C.SIGURG
-	SIGSTOP   = C.SIGSTOP
-	SIGTSTP   = C.SIGTSTP
-	SIGCONT   = C.SIGCONT
-	SIGCHLD   = C.SIGCHLD
-	SIGTTIN   = C.SIGTTIN
-	SIGTTOU   = C.SIGTTOU
-	SIGIO     = C.SIGIO
-	SIGXCPU   = C.SIGXCPU
-	SIGXFSZ   = C.SIGXFSZ
-	SIGVTALRM = C.SIGVTALRM
-	SIGPROF   = C.SIGPROF
-	SIGWINCH  = C.SIGWINCH
-	SIGINFO   = C.SIGINFO
-	SIGUSR1   = C.SIGUSR1
-	SIGUSR2   = C.SIGUSR2
-
-	FPE_INTDIV = C.FPE_INTDIV
-	FPE_INTOVF = C.FPE_INTOVF
-	FPE_FLTDIV = C.FPE_FLTDIV
-	FPE_FLTOVF = C.FPE_FLTOVF
-	FPE_FLTUND = C.FPE_FLTUND
-	FPE_FLTRES = C.FPE_FLTRES
-	FPE_FLTINV = C.FPE_FLTINV
-	FPE_FLTSUB = C.FPE_FLTSUB
-
-	BUS_ADRALN = C.BUS_ADRALN
-	BUS_ADRERR = C.BUS_ADRERR
-	BUS_OBJERR = C.BUS_OBJERR
-
-	SEGV_MAPERR = C.SEGV_MAPERR
-	SEGV_ACCERR = C.SEGV_ACCERR
-
-	ITIMER_REAL    = C.ITIMER_REAL
-	ITIMER_VIRTUAL = C.ITIMER_VIRTUAL
-	ITIMER_PROF    = C.ITIMER_PROF
-
-	EV_ADD       = C.EV_ADD
-	EV_DELETE    = C.EV_DELETE
-	EV_CLEAR     = C.EV_CLEAR
-	EV_RECEIPT   = 0
-	EV_ERROR     = C.EV_ERROR
-	EVFILT_READ  = C.EVFILT_READ
-	EVFILT_WRITE = C.EVFILT_WRITE
-)
-
-type Sigaltstack C.struct_sigaltstack
-type Sigset C.sigset_t
-type Siginfo C.struct__ksiginfo
-
-type StackT C.stack_t
-
-type Timespec C.struct_timespec
-type Timeval C.struct_timeval
-type Itimerval C.struct_itimerval
-
-type McontextT C.mcontext_t
-type UcontextT C.ucontext_t
-
-type Kevent C.struct_kevent
diff --git a/src/pkg/runtime/defs_netbsd_386.h b/src/pkg/runtime/defs_netbsd_386.h
deleted file mode 100644
index 7fd6695..0000000
--- a/src/pkg/runtime/defs_netbsd_386.h
+++ /dev/null
@@ -1,182 +0,0 @@
-// Created by cgo -cdefs - DO NOT EDIT
-// cgo -cdefs defs_netbsd.go defs_netbsd_386.go
-
-
-enum {
-	EINTR	= 0x4,
-	EFAULT	= 0xe,
-
-	PROT_NONE	= 0x0,
-	PROT_READ	= 0x1,
-	PROT_WRITE	= 0x2,
-	PROT_EXEC	= 0x4,
-
-	MAP_ANON	= 0x1000,
-	MAP_PRIVATE	= 0x2,
-	MAP_FIXED	= 0x10,
-
-	MADV_FREE	= 0x6,
-
-	SA_SIGINFO	= 0x40,
-	SA_RESTART	= 0x2,
-	SA_ONSTACK	= 0x1,
-
-	SIGHUP		= 0x1,
-	SIGINT		= 0x2,
-	SIGQUIT		= 0x3,
-	SIGILL		= 0x4,
-	SIGTRAP		= 0x5,
-	SIGABRT		= 0x6,
-	SIGEMT		= 0x7,
-	SIGFPE		= 0x8,
-	SIGKILL		= 0x9,
-	SIGBUS		= 0xa,
-	SIGSEGV		= 0xb,
-	SIGSYS		= 0xc,
-	SIGPIPE		= 0xd,
-	SIGALRM		= 0xe,
-	SIGTERM		= 0xf,
-	SIGURG		= 0x10,
-	SIGSTOP		= 0x11,
-	SIGTSTP		= 0x12,
-	SIGCONT		= 0x13,
-	SIGCHLD		= 0x14,
-	SIGTTIN		= 0x15,
-	SIGTTOU		= 0x16,
-	SIGIO		= 0x17,
-	SIGXCPU		= 0x18,
-	SIGXFSZ		= 0x19,
-	SIGVTALRM	= 0x1a,
-	SIGPROF		= 0x1b,
-	SIGWINCH	= 0x1c,
-	SIGINFO		= 0x1d,
-	SIGUSR1		= 0x1e,
-	SIGUSR2		= 0x1f,
-
-	FPE_INTDIV	= 0x1,
-	FPE_INTOVF	= 0x2,
-	FPE_FLTDIV	= 0x3,
-	FPE_FLTOVF	= 0x4,
-	FPE_FLTUND	= 0x5,
-	FPE_FLTRES	= 0x6,
-	FPE_FLTINV	= 0x7,
-	FPE_FLTSUB	= 0x8,
-
-	BUS_ADRALN	= 0x1,
-	BUS_ADRERR	= 0x2,
-	BUS_OBJERR	= 0x3,
-
-	SEGV_MAPERR	= 0x1,
-	SEGV_ACCERR	= 0x2,
-
-	ITIMER_REAL	= 0x0,
-	ITIMER_VIRTUAL	= 0x1,
-	ITIMER_PROF	= 0x2,
-
-	EV_ADD		= 0x1,
-	EV_DELETE	= 0x2,
-	EV_CLEAR	= 0x20,
-	EV_RECEIPT	= 0,
-	EV_ERROR	= 0x4000,
-	EVFILT_READ	= 0x0,
-	EVFILT_WRITE	= 0x1,
-};
-
-typedef struct Sigaltstack Sigaltstack;
-typedef struct Sigset Sigset;
-typedef struct Siginfo Siginfo;
-typedef struct StackT StackT;
-typedef struct Timespec Timespec;
-typedef struct Timeval Timeval;
-typedef struct Itimerval Itimerval;
-typedef struct McontextT McontextT;
-typedef struct UcontextT UcontextT;
-typedef struct Kevent Kevent;
-
-#pragma pack on
-
-struct Sigaltstack {
-	byte	*ss_sp;
-	uint32	ss_size;
-	int32	ss_flags;
-};
-struct Sigset {
-	uint32	__bits[4];
-};
-struct Siginfo {
-	int32	_signo;
-	int32	_code;
-	int32	_errno;
-	byte	_reason[20];
-};
-
-struct StackT {
-	byte	*ss_sp;
-	uint32	ss_size;
-	int32	ss_flags;
-};
-
-struct Timespec {
-	int64	tv_sec;
-	int32	tv_nsec;
-};
-struct Timeval {
-	int64	tv_sec;
-	int32	tv_usec;
-};
-struct Itimerval {
-	Timeval	it_interval;
-	Timeval	it_value;
-};
-
-struct McontextT {
-	int32	__gregs[19];
-	byte	__fpregs[644];
-	int32	_mc_tlsbase;
-};
-struct UcontextT {
-	uint32	uc_flags;
-	UcontextT	*uc_link;
-	Sigset	uc_sigmask;
-	StackT	uc_stack;
-	McontextT	uc_mcontext;
-	int32	__uc_pad[4];
-};
-
-struct Kevent {
-	uint32	ident;
-	uint32	filter;
-	uint32	flags;
-	uint32	fflags;
-	int64	data;
-	int32	udata;
-};
-
-
-#pragma pack off
-// Created by cgo -cdefs - DO NOT EDIT
-// cgo -cdefs defs_netbsd.go defs_netbsd_386.go
-
-
-enum {
-	REG_GS		= 0x0,
-	REG_FS		= 0x1,
-	REG_ES		= 0x2,
-	REG_DS		= 0x3,
-	REG_EDI		= 0x4,
-	REG_ESI		= 0x5,
-	REG_EBP		= 0x6,
-	REG_ESP		= 0x7,
-	REG_EBX		= 0x8,
-	REG_EDX		= 0x9,
-	REG_ECX		= 0xa,
-	REG_EAX		= 0xb,
-	REG_TRAPNO	= 0xc,
-	REG_ERR		= 0xd,
-	REG_EIP		= 0xe,
-	REG_CS		= 0xf,
-	REG_EFL		= 0x10,
-	REG_UESP	= 0x11,
-	REG_SS		= 0x12,
-};
-
diff --git a/src/pkg/runtime/defs_netbsd_amd64.h b/src/pkg/runtime/defs_netbsd_amd64.h
deleted file mode 100644
index 972af16..0000000
--- a/src/pkg/runtime/defs_netbsd_amd64.h
+++ /dev/null
@@ -1,194 +0,0 @@
-// Created by cgo -cdefs - DO NOT EDIT
-// cgo -cdefs defs_netbsd.go defs_netbsd_amd64.go
-
-
-enum {
-	EINTR	= 0x4,
-	EFAULT	= 0xe,
-
-	PROT_NONE	= 0x0,
-	PROT_READ	= 0x1,
-	PROT_WRITE	= 0x2,
-	PROT_EXEC	= 0x4,
-
-	MAP_ANON	= 0x1000,
-	MAP_PRIVATE	= 0x2,
-	MAP_FIXED	= 0x10,
-
-	MADV_FREE	= 0x6,
-
-	SA_SIGINFO	= 0x40,
-	SA_RESTART	= 0x2,
-	SA_ONSTACK	= 0x1,
-
-	SIGHUP		= 0x1,
-	SIGINT		= 0x2,
-	SIGQUIT		= 0x3,
-	SIGILL		= 0x4,
-	SIGTRAP		= 0x5,
-	SIGABRT		= 0x6,
-	SIGEMT		= 0x7,
-	SIGFPE		= 0x8,
-	SIGKILL		= 0x9,
-	SIGBUS		= 0xa,
-	SIGSEGV		= 0xb,
-	SIGSYS		= 0xc,
-	SIGPIPE		= 0xd,
-	SIGALRM		= 0xe,
-	SIGTERM		= 0xf,
-	SIGURG		= 0x10,
-	SIGSTOP		= 0x11,
-	SIGTSTP		= 0x12,
-	SIGCONT		= 0x13,
-	SIGCHLD		= 0x14,
-	SIGTTIN		= 0x15,
-	SIGTTOU		= 0x16,
-	SIGIO		= 0x17,
-	SIGXCPU		= 0x18,
-	SIGXFSZ		= 0x19,
-	SIGVTALRM	= 0x1a,
-	SIGPROF		= 0x1b,
-	SIGWINCH	= 0x1c,
-	SIGINFO		= 0x1d,
-	SIGUSR1		= 0x1e,
-	SIGUSR2		= 0x1f,
-
-	FPE_INTDIV	= 0x1,
-	FPE_INTOVF	= 0x2,
-	FPE_FLTDIV	= 0x3,
-	FPE_FLTOVF	= 0x4,
-	FPE_FLTUND	= 0x5,
-	FPE_FLTRES	= 0x6,
-	FPE_FLTINV	= 0x7,
-	FPE_FLTSUB	= 0x8,
-
-	BUS_ADRALN	= 0x1,
-	BUS_ADRERR	= 0x2,
-	BUS_OBJERR	= 0x3,
-
-	SEGV_MAPERR	= 0x1,
-	SEGV_ACCERR	= 0x2,
-
-	ITIMER_REAL	= 0x0,
-	ITIMER_VIRTUAL	= 0x1,
-	ITIMER_PROF	= 0x2,
-
-	EV_ADD		= 0x1,
-	EV_DELETE	= 0x2,
-	EV_CLEAR	= 0x20,
-	EV_RECEIPT	= 0,
-	EV_ERROR	= 0x4000,
-	EVFILT_READ	= 0x0,
-	EVFILT_WRITE	= 0x1,
-};
-
-typedef struct Sigaltstack Sigaltstack;
-typedef struct Sigset Sigset;
-typedef struct Siginfo Siginfo;
-typedef struct StackT StackT;
-typedef struct Timespec Timespec;
-typedef struct Timeval Timeval;
-typedef struct Itimerval Itimerval;
-typedef struct McontextT McontextT;
-typedef struct UcontextT UcontextT;
-typedef struct Kevent Kevent;
-
-#pragma pack on
-
-struct Sigaltstack {
-	byte	*ss_sp;
-	uint64	ss_size;
-	int32	ss_flags;
-	byte	Pad_cgo_0[4];
-};
-struct Sigset {
-	uint32	__bits[4];
-};
-struct Siginfo {
-	int32	_signo;
-	int32	_code;
-	int32	_errno;
-	int32	_pad;
-	byte	_reason[24];
-};
-
-struct StackT {
-	byte	*ss_sp;
-	uint64	ss_size;
-	int32	ss_flags;
-	byte	Pad_cgo_0[4];
-};
-
-struct Timespec {
-	int64	tv_sec;
-	int64	tv_nsec;
-};
-struct Timeval {
-	int64	tv_sec;
-	int32	tv_usec;
-	byte	Pad_cgo_0[4];
-};
-struct Itimerval {
-	Timeval	it_interval;
-	Timeval	it_value;
-};
-
-struct McontextT {
-	uint64	__gregs[26];
-	uint64	_mc_tlsbase;
-	int8	__fpregs[512];
-};
-struct UcontextT {
-	uint32	uc_flags;
-	byte	Pad_cgo_0[4];
-	UcontextT	*uc_link;
-	Sigset	uc_sigmask;
-	StackT	uc_stack;
-	McontextT	uc_mcontext;
-};
-
-struct Kevent {
-	uint64	ident;
-	uint32	filter;
-	uint32	flags;
-	uint32	fflags;
-	byte	Pad_cgo_0[4];
-	int64	data;
-	int64	udata;
-};
-
-
-#pragma pack off
-// Created by cgo -cdefs - DO NOT EDIT
-// cgo -cdefs defs_netbsd.go defs_netbsd_amd64.go
-
-
-enum {
-	REG_RDI		= 0x0,
-	REG_RSI		= 0x1,
-	REG_RDX		= 0x2,
-	REG_RCX		= 0x3,
-	REG_R8		= 0x4,
-	REG_R9		= 0x5,
-	REG_R10		= 0x6,
-	REG_R11		= 0x7,
-	REG_R12		= 0x8,
-	REG_R13		= 0x9,
-	REG_R14		= 0xa,
-	REG_R15		= 0xb,
-	REG_RBP		= 0xc,
-	REG_RBX		= 0xd,
-	REG_RAX		= 0xe,
-	REG_GS		= 0xf,
-	REG_FS		= 0x10,
-	REG_ES		= 0x11,
-	REG_DS		= 0x12,
-	REG_TRAPNO	= 0x13,
-	REG_ERR		= 0x14,
-	REG_RIP		= 0x15,
-	REG_CS		= 0x16,
-	REG_RFLAGS	= 0x17,
-	REG_RSP		= 0x18,
-	REG_SS		= 0x19,
-};
-
diff --git a/src/pkg/runtime/defs_netbsd_arm.h b/src/pkg/runtime/defs_netbsd_arm.h
deleted file mode 100644
index c6f5b1c..0000000
--- a/src/pkg/runtime/defs_netbsd_arm.h
+++ /dev/null
@@ -1,184 +0,0 @@
-// Created by cgo -cdefs - DO NOT EDIT
-// cgo -cdefs defs_netbsd.go defs_netbsd_arm.go
-
-
-enum {
-	EINTR	= 0x4,
-	EFAULT	= 0xe,
-
-	PROT_NONE	= 0x0,
-	PROT_READ	= 0x1,
-	PROT_WRITE	= 0x2,
-	PROT_EXEC	= 0x4,
-
-	MAP_ANON	= 0x1000,
-	MAP_PRIVATE	= 0x2,
-	MAP_FIXED	= 0x10,
-
-	MADV_FREE	= 0x6,
-
-	SA_SIGINFO	= 0x40,
-	SA_RESTART	= 0x2,
-	SA_ONSTACK	= 0x1,
-
-	SIGHUP		= 0x1,
-	SIGINT		= 0x2,
-	SIGQUIT		= 0x3,
-	SIGILL		= 0x4,
-	SIGTRAP		= 0x5,
-	SIGABRT		= 0x6,
-	SIGEMT		= 0x7,
-	SIGFPE		= 0x8,
-	SIGKILL		= 0x9,
-	SIGBUS		= 0xa,
-	SIGSEGV		= 0xb,
-	SIGSYS		= 0xc,
-	SIGPIPE		= 0xd,
-	SIGALRM		= 0xe,
-	SIGTERM		= 0xf,
-	SIGURG		= 0x10,
-	SIGSTOP		= 0x11,
-	SIGTSTP		= 0x12,
-	SIGCONT		= 0x13,
-	SIGCHLD		= 0x14,
-	SIGTTIN		= 0x15,
-	SIGTTOU		= 0x16,
-	SIGIO		= 0x17,
-	SIGXCPU		= 0x18,
-	SIGXFSZ		= 0x19,
-	SIGVTALRM	= 0x1a,
-	SIGPROF		= 0x1b,
-	SIGWINCH	= 0x1c,
-	SIGINFO		= 0x1d,
-	SIGUSR1		= 0x1e,
-	SIGUSR2		= 0x1f,
-
-	FPE_INTDIV	= 0x1,
-	FPE_INTOVF	= 0x2,
-	FPE_FLTDIV	= 0x3,
-	FPE_FLTOVF	= 0x4,
-	FPE_FLTUND	= 0x5,
-	FPE_FLTRES	= 0x6,
-	FPE_FLTINV	= 0x7,
-	FPE_FLTSUB	= 0x8,
-
-	BUS_ADRALN	= 0x1,
-	BUS_ADRERR	= 0x2,
-	BUS_OBJERR	= 0x3,
-
-	SEGV_MAPERR	= 0x1,
-	SEGV_ACCERR	= 0x2,
-
-	ITIMER_REAL	= 0x0,
-	ITIMER_VIRTUAL	= 0x1,
-	ITIMER_PROF	= 0x2,
-
-	EV_ADD		= 0x1,
-	EV_DELETE	= 0x2,
-	EV_CLEAR	= 0x20,
-	EV_RECEIPT	= 0,
-	EV_ERROR	= 0x4000,
-	EVFILT_READ	= 0x0,
-	EVFILT_WRITE	= 0x1,
-};
-
-typedef struct Sigaltstack Sigaltstack;
-typedef struct Sigset Sigset;
-typedef struct Siginfo Siginfo;
-typedef struct StackT StackT;
-typedef struct Timespec Timespec;
-typedef struct Timeval Timeval;
-typedef struct Itimerval Itimerval;
-typedef struct McontextT McontextT;
-typedef struct UcontextT UcontextT;
-typedef struct Kevent Kevent;
-
-#pragma pack on
-
-struct Sigaltstack {
-	byte	*ss_sp;
-	uint32	ss_size;
-	int32	ss_flags;
-};
-struct Sigset {
-	uint32	__bits[4];
-};
-struct Siginfo {
-	int32	_signo;
-	int32	_code;
-	int32	_errno;
-	byte	_reason[20];
-};
-
-struct StackT {
-	byte	*ss_sp;
-	uint32	ss_size;
-	int32	ss_flags;
-};
-
-struct Timespec {
-	int64	tv_sec;
-	int32	tv_nsec;
-};
-struct Timeval {
-	int64	tv_sec;
-	int32	tv_usec;
-};
-struct Itimerval {
-	Timeval	it_interval;
-	Timeval	it_value;
-};
-
-struct McontextT {
-	uint32	__gregs[17];
-#ifdef __ARM_EABI__
-	byte	__fpu[4+8*32+4];
-#else
-	byte	__fpu[4+4*33+4];
-#endif
-	uint32	_mc_tlsbase;
-};
-struct UcontextT {
-	uint32	uc_flags;
-	UcontextT	*uc_link;
-	Sigset	uc_sigmask;
-	StackT	uc_stack;
-	McontextT	uc_mcontext;
-	int32	__uc_pad[2];
-};
-
-struct Kevent {
-	uint32	ident;
-	uint32	filter;
-	uint32	flags;
-	uint32	fflags;
-	int64	data;
-	int32	udata;
-};
-
-
-#pragma pack off
-// Created by cgo -cdefs - DO NOT EDIT
-// cgo -cdefs defs_netbsd.go defs_netbsd_arm.go
-
-
-enum {
-	REG_R0		= 0x0,
-	REG_R1		= 0x1,
-	REG_R2		= 0x2,
-	REG_R3		= 0x3,
-	REG_R4		= 0x4,
-	REG_R5		= 0x5,
-	REG_R6		= 0x6,
-	REG_R7		= 0x7,
-	REG_R8		= 0x8,
-	REG_R9		= 0x9,
-	REG_R10		= 0xa,
-	REG_R11		= 0xb,
-	REG_R12		= 0xc,
-	REG_R13		= 0xd,
-	REG_R14		= 0xe,
-	REG_R15		= 0xf,
-	REG_CPSR	= 0x10,
-};
-
diff --git a/src/pkg/runtime/defs_openbsd.go b/src/pkg/runtime/defs_openbsd.go
deleted file mode 100644
index 4a70579..0000000
--- a/src/pkg/runtime/defs_openbsd.go
+++ /dev/null
@@ -1,121 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build ignore
-
-/*
-Input to cgo.
-
-GOARCH=amd64 go tool cgo -cdefs defs_openbsd.go >defs_openbsd_amd64.h
-GOARCH=386 go tool cgo -cdefs defs_openbsd.go >defs_openbsd_386.h
-*/
-
-package runtime
-
-/*
-#include <sys/types.h>
-#include <sys/event.h>
-#include <sys/mman.h>
-#include <sys/time.h>
-#include <sys/unistd.h>
-#include <sys/signal.h>
-#include <errno.h>
-#include <signal.h>
-*/
-import "C"
-
-const (
-	EINTR  = C.EINTR
-	EFAULT = C.EFAULT
-
-	PROT_NONE  = C.PROT_NONE
-	PROT_READ  = C.PROT_READ
-	PROT_WRITE = C.PROT_WRITE
-	PROT_EXEC  = C.PROT_EXEC
-
-	MAP_ANON    = C.MAP_ANON
-	MAP_PRIVATE = C.MAP_PRIVATE
-	MAP_FIXED   = C.MAP_FIXED
-
-	MADV_FREE = C.MADV_FREE
-
-	SA_SIGINFO = C.SA_SIGINFO
-	SA_RESTART = C.SA_RESTART
-	SA_ONSTACK = C.SA_ONSTACK
-
-	SIGHUP    = C.SIGHUP
-	SIGINT    = C.SIGINT
-	SIGQUIT   = C.SIGQUIT
-	SIGILL    = C.SIGILL
-	SIGTRAP   = C.SIGTRAP
-	SIGABRT   = C.SIGABRT
-	SIGEMT    = C.SIGEMT
-	SIGFPE    = C.SIGFPE
-	SIGKILL   = C.SIGKILL
-	SIGBUS    = C.SIGBUS
-	SIGSEGV   = C.SIGSEGV
-	SIGSYS    = C.SIGSYS
-	SIGPIPE   = C.SIGPIPE
-	SIGALRM   = C.SIGALRM
-	SIGTERM   = C.SIGTERM
-	SIGURG    = C.SIGURG
-	SIGSTOP   = C.SIGSTOP
-	SIGTSTP   = C.SIGTSTP
-	SIGCONT   = C.SIGCONT
-	SIGCHLD   = C.SIGCHLD
-	SIGTTIN   = C.SIGTTIN
-	SIGTTOU   = C.SIGTTOU
-	SIGIO     = C.SIGIO
-	SIGXCPU   = C.SIGXCPU
-	SIGXFSZ   = C.SIGXFSZ
-	SIGVTALRM = C.SIGVTALRM
-	SIGPROF   = C.SIGPROF
-	SIGWINCH  = C.SIGWINCH
-	SIGINFO   = C.SIGINFO
-	SIGUSR1   = C.SIGUSR1
-	SIGUSR2   = C.SIGUSR2
-
-	FPE_INTDIV = C.FPE_INTDIV
-	FPE_INTOVF = C.FPE_INTOVF
-	FPE_FLTDIV = C.FPE_FLTDIV
-	FPE_FLTOVF = C.FPE_FLTOVF
-	FPE_FLTUND = C.FPE_FLTUND
-	FPE_FLTRES = C.FPE_FLTRES
-	FPE_FLTINV = C.FPE_FLTINV
-	FPE_FLTSUB = C.FPE_FLTSUB
-
-	BUS_ADRALN = C.BUS_ADRALN
-	BUS_ADRERR = C.BUS_ADRERR
-	BUS_OBJERR = C.BUS_OBJERR
-
-	SEGV_MAPERR = C.SEGV_MAPERR
-	SEGV_ACCERR = C.SEGV_ACCERR
-
-	ITIMER_REAL    = C.ITIMER_REAL
-	ITIMER_VIRTUAL = C.ITIMER_VIRTUAL
-	ITIMER_PROF    = C.ITIMER_PROF
-
-	EV_ADD       = C.EV_ADD
-	EV_DELETE    = C.EV_DELETE
-	EV_CLEAR     = C.EV_CLEAR
-	EV_ERROR     = C.EV_ERROR
-	EVFILT_READ  = C.EVFILT_READ
-	EVFILT_WRITE = C.EVFILT_WRITE
-)
-
-type Tfork C.struct___tfork
-
-type Sigaltstack C.struct_sigaltstack
-type Sigcontext C.struct_sigcontext
-type Siginfo C.siginfo_t
-type Sigset C.sigset_t
-type Sigval C.union_sigval
-
-type StackT C.stack_t
-
-type Timespec C.struct_timespec
-type Timeval C.struct_timeval
-type Itimerval C.struct_itimerval
-
-type Kevent C.struct_kevent
diff --git a/src/pkg/runtime/defs_openbsd_386.h b/src/pkg/runtime/defs_openbsd_386.h
deleted file mode 100644
index b8f993e..0000000
--- a/src/pkg/runtime/defs_openbsd_386.h
+++ /dev/null
@@ -1,168 +0,0 @@
-// Created by cgo -cdefs - DO NOT EDIT
-// cgo -cdefs defs_openbsd.go
-
-
-enum {
-	EINTR	= 0x4,
-	EFAULT	= 0xe,
-
-	PROT_NONE	= 0x0,
-	PROT_READ	= 0x1,
-	PROT_WRITE	= 0x2,
-	PROT_EXEC	= 0x4,
-
-	MAP_ANON	= 0x1000,
-	MAP_PRIVATE	= 0x2,
-	MAP_FIXED	= 0x10,
-
-	MADV_FREE	= 0x6,
-
-	SA_SIGINFO	= 0x40,
-	SA_RESTART	= 0x2,
-	SA_ONSTACK	= 0x1,
-
-	SIGHUP		= 0x1,
-	SIGINT		= 0x2,
-	SIGQUIT		= 0x3,
-	SIGILL		= 0x4,
-	SIGTRAP		= 0x5,
-	SIGABRT		= 0x6,
-	SIGEMT		= 0x7,
-	SIGFPE		= 0x8,
-	SIGKILL		= 0x9,
-	SIGBUS		= 0xa,
-	SIGSEGV		= 0xb,
-	SIGSYS		= 0xc,
-	SIGPIPE		= 0xd,
-	SIGALRM		= 0xe,
-	SIGTERM		= 0xf,
-	SIGURG		= 0x10,
-	SIGSTOP		= 0x11,
-	SIGTSTP		= 0x12,
-	SIGCONT		= 0x13,
-	SIGCHLD		= 0x14,
-	SIGTTIN		= 0x15,
-	SIGTTOU		= 0x16,
-	SIGIO		= 0x17,
-	SIGXCPU		= 0x18,
-	SIGXFSZ		= 0x19,
-	SIGVTALRM	= 0x1a,
-	SIGPROF		= 0x1b,
-	SIGWINCH	= 0x1c,
-	SIGINFO		= 0x1d,
-	SIGUSR1		= 0x1e,
-	SIGUSR2		= 0x1f,
-
-	FPE_INTDIV	= 0x1,
-	FPE_INTOVF	= 0x2,
-	FPE_FLTDIV	= 0x3,
-	FPE_FLTOVF	= 0x4,
-	FPE_FLTUND	= 0x5,
-	FPE_FLTRES	= 0x6,
-	FPE_FLTINV	= 0x7,
-	FPE_FLTSUB	= 0x8,
-
-	BUS_ADRALN	= 0x1,
-	BUS_ADRERR	= 0x2,
-	BUS_OBJERR	= 0x3,
-
-	SEGV_MAPERR	= 0x1,
-	SEGV_ACCERR	= 0x2,
-
-	ITIMER_REAL	= 0x0,
-	ITIMER_VIRTUAL	= 0x1,
-	ITIMER_PROF	= 0x2,
-
-	EV_ADD		= 0x1,
-	EV_DELETE	= 0x2,
-	EV_CLEAR	= 0x20,
-	EV_ERROR	= 0x4000,
-	EVFILT_READ	= -0x1,
-	EVFILT_WRITE	= -0x2,
-};
-
-typedef struct Tfork Tfork;
-typedef struct Sigaltstack Sigaltstack;
-typedef struct Sigcontext Sigcontext;
-typedef struct Siginfo Siginfo;
-typedef struct StackT StackT;
-typedef struct Timespec Timespec;
-typedef struct Timeval Timeval;
-typedef struct Itimerval Itimerval;
-typedef struct Kevent Kevent;
-
-#pragma pack on
-
-struct Tfork {
-	byte	*tf_tcb;
-	int32	*tf_tid;
-	byte	*tf_stack;
-};
-
-struct Sigaltstack {
-	byte	*ss_sp;
-	uint32	ss_size;
-	int32	ss_flags;
-};
-struct Sigcontext {
-	int32	sc_gs;
-	int32	sc_fs;
-	int32	sc_es;
-	int32	sc_ds;
-	int32	sc_edi;
-	int32	sc_esi;
-	int32	sc_ebp;
-	int32	sc_ebx;
-	int32	sc_edx;
-	int32	sc_ecx;
-	int32	sc_eax;
-	int32	sc_eip;
-	int32	sc_cs;
-	int32	sc_eflags;
-	int32	sc_esp;
-	int32	sc_ss;
-	int32	__sc_unused;
-	int32	sc_mask;
-	int32	sc_trapno;
-	int32	sc_err;
-	void	*sc_fpstate;
-};
-struct Siginfo {
-	int32	si_signo;
-	int32	si_code;
-	int32	si_errno;
-	byte	_data[116];
-};
-typedef	uint32	Sigset;
-typedef	byte	Sigval[4];
-
-struct StackT {
-	byte	*ss_sp;
-	uint32	ss_size;
-	int32	ss_flags;
-};
-
-struct Timespec {
-	int64	tv_sec;
-	int32	tv_nsec;
-};
-struct Timeval {
-	int64	tv_sec;
-	int32	tv_usec;
-};
-struct Itimerval {
-	Timeval	it_interval;
-	Timeval	it_value;
-};
-
-struct Kevent {
-	uint32	ident;
-	int16	filter;
-	uint16	flags;
-	uint32	fflags;
-	int64	data;
-	byte	*udata;
-};
-
-
-#pragma pack off
diff --git a/src/pkg/runtime/defs_openbsd_amd64.h b/src/pkg/runtime/defs_openbsd_amd64.h
deleted file mode 100644
index a1ae2ef..0000000
--- a/src/pkg/runtime/defs_openbsd_amd64.h
+++ /dev/null
@@ -1,179 +0,0 @@
-// Created by cgo -cdefs - DO NOT EDIT
-// cgo -cdefs defs_openbsd.go
-
-
-enum {
-	EINTR	= 0x4,
-	EFAULT	= 0xe,
-
-	PROT_NONE	= 0x0,
-	PROT_READ	= 0x1,
-	PROT_WRITE	= 0x2,
-	PROT_EXEC	= 0x4,
-
-	MAP_ANON	= 0x1000,
-	MAP_PRIVATE	= 0x2,
-	MAP_FIXED	= 0x10,
-
-	MADV_FREE	= 0x6,
-
-	SA_SIGINFO	= 0x40,
-	SA_RESTART	= 0x2,
-	SA_ONSTACK	= 0x1,
-
-	SIGHUP		= 0x1,
-	SIGINT		= 0x2,
-	SIGQUIT		= 0x3,
-	SIGILL		= 0x4,
-	SIGTRAP		= 0x5,
-	SIGABRT		= 0x6,
-	SIGEMT		= 0x7,
-	SIGFPE		= 0x8,
-	SIGKILL		= 0x9,
-	SIGBUS		= 0xa,
-	SIGSEGV		= 0xb,
-	SIGSYS		= 0xc,
-	SIGPIPE		= 0xd,
-	SIGALRM		= 0xe,
-	SIGTERM		= 0xf,
-	SIGURG		= 0x10,
-	SIGSTOP		= 0x11,
-	SIGTSTP		= 0x12,
-	SIGCONT		= 0x13,
-	SIGCHLD		= 0x14,
-	SIGTTIN		= 0x15,
-	SIGTTOU		= 0x16,
-	SIGIO		= 0x17,
-	SIGXCPU		= 0x18,
-	SIGXFSZ		= 0x19,
-	SIGVTALRM	= 0x1a,
-	SIGPROF		= 0x1b,
-	SIGWINCH	= 0x1c,
-	SIGINFO		= 0x1d,
-	SIGUSR1		= 0x1e,
-	SIGUSR2		= 0x1f,
-
-	FPE_INTDIV	= 0x1,
-	FPE_INTOVF	= 0x2,
-	FPE_FLTDIV	= 0x3,
-	FPE_FLTOVF	= 0x4,
-	FPE_FLTUND	= 0x5,
-	FPE_FLTRES	= 0x6,
-	FPE_FLTINV	= 0x7,
-	FPE_FLTSUB	= 0x8,
-
-	BUS_ADRALN	= 0x1,
-	BUS_ADRERR	= 0x2,
-	BUS_OBJERR	= 0x3,
-
-	SEGV_MAPERR	= 0x1,
-	SEGV_ACCERR	= 0x2,
-
-	ITIMER_REAL	= 0x0,
-	ITIMER_VIRTUAL	= 0x1,
-	ITIMER_PROF	= 0x2,
-
-	EV_ADD		= 0x1,
-	EV_DELETE	= 0x2,
-	EV_CLEAR	= 0x20,
-	EV_ERROR	= 0x4000,
-	EVFILT_READ	= -0x1,
-	EVFILT_WRITE	= -0x2,
-};
-
-typedef struct Tfork Tfork;
-typedef struct Sigaltstack Sigaltstack;
-typedef struct Sigcontext Sigcontext;
-typedef struct Siginfo Siginfo;
-typedef struct StackT StackT;
-typedef struct Timespec Timespec;
-typedef struct Timeval Timeval;
-typedef struct Itimerval Itimerval;
-typedef struct Kevent Kevent;
-
-#pragma pack on
-
-struct Tfork {
-	byte	*tf_tcb;
-	int32	*tf_tid;
-	byte	*tf_stack;
-};
-
-struct Sigaltstack {
-	byte	*ss_sp;
-	uint64	ss_size;
-	int32	ss_flags;
-	byte	Pad_cgo_0[4];
-};
-struct Sigcontext {
-	int64	sc_rdi;
-	int64	sc_rsi;
-	int64	sc_rdx;
-	int64	sc_rcx;
-	int64	sc_r8;
-	int64	sc_r9;
-	int64	sc_r10;
-	int64	sc_r11;
-	int64	sc_r12;
-	int64	sc_r13;
-	int64	sc_r14;
-	int64	sc_r15;
-	int64	sc_rbp;
-	int64	sc_rbx;
-	int64	sc_rax;
-	int64	sc_gs;
-	int64	sc_fs;
-	int64	sc_es;
-	int64	sc_ds;
-	int64	sc_trapno;
-	int64	sc_err;
-	int64	sc_rip;
-	int64	sc_cs;
-	int64	sc_rflags;
-	int64	sc_rsp;
-	int64	sc_ss;
-	void	*sc_fpstate;
-	int32	__sc_unused;
-	int32	sc_mask;
-};
-struct Siginfo {
-	int32	si_signo;
-	int32	si_code;
-	int32	si_errno;
-	byte	Pad_cgo_0[4];
-	byte	_data[120];
-};
-typedef	uint32	Sigset;
-typedef	byte	Sigval[8];
-
-struct StackT {
-	byte	*ss_sp;
-	uint64	ss_size;
-	int32	ss_flags;
-	byte	Pad_cgo_0[4];
-};
-
-struct Timespec {
-	int64	tv_sec;
-	int64	tv_nsec;
-};
-struct Timeval {
-	int64	tv_sec;
-	int64	tv_usec;
-};
-struct Itimerval {
-	Timeval	it_interval;
-	Timeval	it_value;
-};
-
-struct Kevent {
-	uint64	ident;
-	int16	filter;
-	uint16	flags;
-	uint32	fflags;
-	int64	data;
-	byte	*udata;
-};
-
-
-#pragma pack off
diff --git a/src/pkg/runtime/defs_plan9_386.h b/src/pkg/runtime/defs_plan9_386.h
deleted file mode 100644
index bde299d..0000000
--- a/src/pkg/runtime/defs_plan9_386.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#define PAGESIZE 0x1000
-
-typedef struct Ureg Ureg;
-
-struct Ureg
-{
-	uint32	di;		/* general registers */
-	uint32	si;		/* ... */
-	uint32	bp;		/* ... */
-	uint32	nsp;
-	uint32	bx;		/* ... */
-	uint32	dx;		/* ... */
-	uint32	cx;		/* ... */
-	uint32	ax;		/* ... */
-	uint32	gs;		/* data segments */
-	uint32	fs;		/* ... */
-	uint32	es;		/* ... */
-	uint32	ds;		/* ... */
-	uint32	trap;		/* trap type */
-	uint32	ecode;		/* error code (or zero) */
-	uint32	pc;		/* pc */
-	uint32	cs;		/* old context */
-	uint32	flags;		/* old flags */
-	union {
-		uint32	usp;
-		uint32	sp;
-	};
-	uint32	ss;		/* old stack segment */
-};
diff --git a/src/pkg/runtime/defs_plan9_amd64.h b/src/pkg/runtime/defs_plan9_amd64.h
deleted file mode 100644
index d8fec67..0000000
--- a/src/pkg/runtime/defs_plan9_amd64.h
+++ /dev/null
@@ -1,34 +0,0 @@
-#define PAGESIZE 0x200000ULL
-
-typedef struct Ureg Ureg;
-
-struct Ureg {
-	uint64	ax;
-	uint64	bx;
-	uint64	cx;
-	uint64	dx;
-	uint64	si;
-	uint64	di;
-	uint64	bp;
-	uint64	r8;
-	uint64	r9;
-	uint64	r10;
-	uint64	r11;
-	uint64	r12;
-	uint64	r13;
-	uint64	r14;
-	uint64	r15;
-
-	uint16	ds;
-	uint16	es;
-	uint16	fs;
-	uint16	gs;
-
-	uint64	type;
-	uint64	error;				/* error code (or zero) */
-	uint64	ip;				/* pc */
-	uint64	cs;				/* old context */
-	uint64	flags;				/* old flags */
-	uint64	sp;				/* sp */
-	uint64	ss;				/* old stack segment */
-};
diff --git a/src/pkg/runtime/defs_solaris.go b/src/pkg/runtime/defs_solaris.go
deleted file mode 100644
index 8dcbb08..0000000
--- a/src/pkg/runtime/defs_solaris.go
+++ /dev/null
@@ -1,156 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build ignore
-
-/*
-Input to cgo.
-
-GOARCH=amd64 go tool cgo -cdefs defs_solaris.go >defs_solaris_amd64.h
-*/
-
-package runtime
-
-/*
-#include <sys/types.h>
-#include <sys/mman.h>
-#include <sys/select.h>
-#include <sys/siginfo.h>
-#include <sys/signal.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <sys/ucontext.h>
-#include <sys/regset.h>
-#include <sys/unistd.h>
-#include <sys/fork.h>
-#include <sys/port.h>
-#include <semaphore.h>
-#include <errno.h>
-#include <signal.h>
-#include <pthread.h>
-#include <netdb.h>
-*/
-import "C"
-
-const (
-	EINTR       = C.EINTR
-	EBADF       = C.EBADF
-	EFAULT      = C.EFAULT
-	EAGAIN      = C.EAGAIN
-	ETIMEDOUT   = C.ETIMEDOUT
-	EWOULDBLOCK = C.EWOULDBLOCK
-	EINPROGRESS = C.EINPROGRESS
-
-	PROT_NONE  = C.PROT_NONE
-	PROT_READ  = C.PROT_READ
-	PROT_WRITE = C.PROT_WRITE
-	PROT_EXEC  = C.PROT_EXEC
-
-	MAP_ANON    = C.MAP_ANON
-	MAP_PRIVATE = C.MAP_PRIVATE
-	MAP_FIXED   = C.MAP_FIXED
-
-	MADV_FREE = C.MADV_FREE
-
-	SA_SIGINFO = C.SA_SIGINFO
-	SA_RESTART = C.SA_RESTART
-	SA_ONSTACK = C.SA_ONSTACK
-
-	SIGHUP    = C.SIGHUP
-	SIGINT    = C.SIGINT
-	SIGQUIT   = C.SIGQUIT
-	SIGILL    = C.SIGILL
-	SIGTRAP   = C.SIGTRAP
-	SIGABRT   = C.SIGABRT
-	SIGEMT    = C.SIGEMT
-	SIGFPE    = C.SIGFPE
-	SIGKILL   = C.SIGKILL
-	SIGBUS    = C.SIGBUS
-	SIGSEGV   = C.SIGSEGV
-	SIGSYS    = C.SIGSYS
-	SIGPIPE   = C.SIGPIPE
-	SIGALRM   = C.SIGALRM
-	SIGTERM   = C.SIGTERM
-	SIGURG    = C.SIGURG
-	SIGSTOP   = C.SIGSTOP
-	SIGTSTP   = C.SIGTSTP
-	SIGCONT   = C.SIGCONT
-	SIGCHLD   = C.SIGCHLD
-	SIGTTIN   = C.SIGTTIN
-	SIGTTOU   = C.SIGTTOU
-	SIGIO     = C.SIGIO
-	SIGXCPU   = C.SIGXCPU
-	SIGXFSZ   = C.SIGXFSZ
-	SIGVTALRM = C.SIGVTALRM
-	SIGPROF   = C.SIGPROF
-	SIGWINCH  = C.SIGWINCH
-	SIGUSR1   = C.SIGUSR1
-	SIGUSR2   = C.SIGUSR2
-
-	FPE_INTDIV = C.FPE_INTDIV
-	FPE_INTOVF = C.FPE_INTOVF
-	FPE_FLTDIV = C.FPE_FLTDIV
-	FPE_FLTOVF = C.FPE_FLTOVF
-	FPE_FLTUND = C.FPE_FLTUND
-	FPE_FLTRES = C.FPE_FLTRES
-	FPE_FLTINV = C.FPE_FLTINV
-	FPE_FLTSUB = C.FPE_FLTSUB
-
-	BUS_ADRALN = C.BUS_ADRALN
-	BUS_ADRERR = C.BUS_ADRERR
-	BUS_OBJERR = C.BUS_OBJERR
-
-	SEGV_MAPERR = C.SEGV_MAPERR
-	SEGV_ACCERR = C.SEGV_ACCERR
-
-	ITIMER_REAL    = C.ITIMER_REAL
-	ITIMER_VIRTUAL = C.ITIMER_VIRTUAL
-	ITIMER_PROF    = C.ITIMER_PROF
-
-	_SC_NPROCESSORS_ONLN = C._SC_NPROCESSORS_ONLN
-
-	PTHREAD_CREATE_DETACHED = C.PTHREAD_CREATE_DETACHED
-
-	FORK_NOSIGCHLD = C.FORK_NOSIGCHLD
-	FORK_WAITPID   = C.FORK_WAITPID
-
-	MAXHOSTNAMELEN = C.MAXHOSTNAMELEN
-
-	O_NONBLOCK = C.O_NONBLOCK
-	FD_CLOEXEC = C.FD_CLOEXEC
-	F_GETFL    = C.F_GETFL
-	F_SETFL    = C.F_SETFL
-	F_SETFD    = C.F_SETFD
-
-	POLLIN  = C.POLLIN
-	POLLOUT = C.POLLOUT
-	POLLHUP = C.POLLHUP
-	POLLERR = C.POLLERR
-
-	PORT_SOURCE_FD = C.PORT_SOURCE_FD
-)
-
-type SemT C.sem_t
-
-type Sigaltstack C.struct_sigaltstack
-type Sigset C.sigset_t
-type StackT C.stack_t
-
-type Siginfo C.siginfo_t
-type Sigaction C.struct_sigaction
-
-type Fpregset C.fpregset_t
-type Mcontext C.mcontext_t
-type Ucontext C.ucontext_t
-
-type Timespec C.struct_timespec
-type Timeval C.struct_timeval
-type Itimerval C.struct_itimerval
-
-type PortEvent C.port_event_t
-type Pthread C.pthread_t
-type PthreadAttr C.pthread_attr_t
-
-// depends on Timespec, must appear below
-type Stat C.struct_stat
diff --git a/src/pkg/runtime/defs_solaris_amd64.h b/src/pkg/runtime/defs_solaris_amd64.h
deleted file mode 100644
index 799724f..0000000
--- a/src/pkg/runtime/defs_solaris_amd64.h
+++ /dev/null
@@ -1,254 +0,0 @@
-// Created by cgo -cdefs - DO NOT EDIT
-// cgo -cdefs defs_solaris.go defs_solaris_amd64.go
-
-
-enum {
-	EINTR		= 0x4,
-	EBADF		= 0x9,
-	EFAULT		= 0xe,
-	EAGAIN		= 0xb,
-	ETIMEDOUT	= 0x91,
-	EWOULDBLOCK	= 0xb,
-	EINPROGRESS	= 0x96,
-
-	PROT_NONE	= 0x0,
-	PROT_READ	= 0x1,
-	PROT_WRITE	= 0x2,
-	PROT_EXEC	= 0x4,
-
-	MAP_ANON	= 0x100,
-	MAP_PRIVATE	= 0x2,
-	MAP_FIXED	= 0x10,
-
-	MADV_FREE	= 0x5,
-
-	SA_SIGINFO	= 0x8,
-	SA_RESTART	= 0x4,
-	SA_ONSTACK	= 0x1,
-
-	SIGHUP		= 0x1,
-	SIGINT		= 0x2,
-	SIGQUIT		= 0x3,
-	SIGILL		= 0x4,
-	SIGTRAP		= 0x5,
-	SIGABRT		= 0x6,
-	SIGEMT		= 0x7,
-	SIGFPE		= 0x8,
-	SIGKILL		= 0x9,
-	SIGBUS		= 0xa,
-	SIGSEGV		= 0xb,
-	SIGSYS		= 0xc,
-	SIGPIPE		= 0xd,
-	SIGALRM		= 0xe,
-	SIGTERM		= 0xf,
-	SIGURG		= 0x15,
-	SIGSTOP		= 0x17,
-	SIGTSTP		= 0x18,
-	SIGCONT		= 0x19,
-	SIGCHLD		= 0x12,
-	SIGTTIN		= 0x1a,
-	SIGTTOU		= 0x1b,
-	SIGIO		= 0x16,
-	SIGXCPU		= 0x1e,
-	SIGXFSZ		= 0x1f,
-	SIGVTALRM	= 0x1c,
-	SIGPROF		= 0x1d,
-	SIGWINCH	= 0x14,
-	SIGUSR1		= 0x10,
-	SIGUSR2		= 0x11,
-
-	FPE_INTDIV	= 0x1,
-	FPE_INTOVF	= 0x2,
-	FPE_FLTDIV	= 0x3,
-	FPE_FLTOVF	= 0x4,
-	FPE_FLTUND	= 0x5,
-	FPE_FLTRES	= 0x6,
-	FPE_FLTINV	= 0x7,
-	FPE_FLTSUB	= 0x8,
-
-	BUS_ADRALN	= 0x1,
-	BUS_ADRERR	= 0x2,
-	BUS_OBJERR	= 0x3,
-
-	SEGV_MAPERR	= 0x1,
-	SEGV_ACCERR	= 0x2,
-
-	ITIMER_REAL	= 0x0,
-	ITIMER_VIRTUAL	= 0x1,
-	ITIMER_PROF	= 0x2,
-
-	_SC_NPROCESSORS_ONLN	= 0xf,
-
-	PTHREAD_CREATE_DETACHED	= 0x40,
-
-	FORK_NOSIGCHLD	= 0x1,
-	FORK_WAITPID	= 0x2,
-
-	MAXHOSTNAMELEN	= 0x100,
-
-	O_NONBLOCK	= 0x80,
-	FD_CLOEXEC	= 0x1,
-	F_GETFL		= 0x3,
-	F_SETFL		= 0x4,
-	F_SETFD		= 0x2,
-
-	POLLIN	= 0x1,
-	POLLOUT	= 0x4,
-	POLLHUP	= 0x10,
-	POLLERR	= 0x8,
-
-	PORT_SOURCE_FD	= 0x4,
-};
-
-typedef struct SemT SemT;
-typedef struct Sigaltstack Sigaltstack;
-typedef struct Sigset Sigset;
-typedef struct StackT StackT;
-typedef struct Siginfo Siginfo;
-typedef struct Sigaction Sigaction;
-typedef struct Fpregset Fpregset;
-typedef struct Mcontext Mcontext;
-typedef struct Ucontext Ucontext;
-typedef struct Timespec Timespec;
-typedef struct Timeval Timeval;
-typedef struct Itimerval Itimerval;
-typedef struct PortEvent PortEvent;
-typedef struct PthreadAttr PthreadAttr;
-typedef struct Stat Stat;
-
-#pragma pack on
-
-struct SemT {
-	uint32	sem_count;
-	uint16	sem_type;
-	uint16	sem_magic;
-	uint64	sem_pad1[3];
-	uint64	sem_pad2[2];
-};
-
-struct Sigaltstack {
-	byte	*ss_sp;
-	uint64	ss_size;
-	int32	ss_flags;
-	byte	Pad_cgo_0[4];
-};
-struct Sigset {
-	uint32	__sigbits[4];
-};
-struct StackT {
-	byte	*ss_sp;
-	uint64	ss_size;
-	int32	ss_flags;
-	byte	Pad_cgo_0[4];
-};
-
-struct Siginfo {
-	int32	si_signo;
-	int32	si_code;
-	int32	si_errno;
-	int32	si_pad;
-	byte	__data[240];
-};
-struct Sigaction {
-	int32	sa_flags;
-	byte	Pad_cgo_0[4];
-	byte	_funcptr[8];
-	Sigset	sa_mask;
-};
-
-struct Fpregset {
-	byte	fp_reg_set[528];
-};
-struct Mcontext {
-	int64	gregs[28];
-	Fpregset	fpregs;
-};
-struct Ucontext {
-	uint64	uc_flags;
-	Ucontext	*uc_link;
-	Sigset	uc_sigmask;
-	StackT	uc_stack;
-	byte	Pad_cgo_0[8];
-	Mcontext	uc_mcontext;
-	int64	uc_filler[5];
-	byte	Pad_cgo_1[8];
-};
-
-struct Timespec {
-	int64	tv_sec;
-	int64	tv_nsec;
-};
-struct Timeval {
-	int64	tv_sec;
-	int64	tv_usec;
-};
-struct Itimerval {
-	Timeval	it_interval;
-	Timeval	it_value;
-};
-
-struct PortEvent {
-	int32	portev_events;
-	uint16	portev_source;
-	uint16	portev_pad;
-	uint64	portev_object;
-	byte	*portev_user;
-};
-typedef	uint32	Pthread;
-struct PthreadAttr {
-	byte	*__pthread_attrp;
-};
-
-struct Stat {
-	uint64	st_dev;
-	uint64	st_ino;
-	uint32	st_mode;
-	uint32	st_nlink;
-	uint32	st_uid;
-	uint32	st_gid;
-	uint64	st_rdev;
-	int64	st_size;
-	Timespec	st_atim;
-	Timespec	st_mtim;
-	Timespec	st_ctim;
-	int32	st_blksize;
-	byte	Pad_cgo_0[4];
-	int64	st_blocks;
-	int8	st_fstype[16];
-};
-
-
-#pragma pack off
-// Created by cgo -cdefs - DO NOT EDIT
-// cgo -cdefs defs_solaris.go defs_solaris_amd64.go
-
-
-enum {
-	REG_RDI		= 0x8,
-	REG_RSI		= 0x9,
-	REG_RDX		= 0xc,
-	REG_RCX		= 0xd,
-	REG_R8		= 0x7,
-	REG_R9		= 0x6,
-	REG_R10		= 0x5,
-	REG_R11		= 0x4,
-	REG_R12		= 0x3,
-	REG_R13		= 0x2,
-	REG_R14		= 0x1,
-	REG_R15		= 0x0,
-	REG_RBP		= 0xa,
-	REG_RBX		= 0xb,
-	REG_RAX		= 0xe,
-	REG_GS		= 0x17,
-	REG_FS		= 0x16,
-	REG_ES		= 0x18,
-	REG_DS		= 0x19,
-	REG_TRAPNO	= 0xf,
-	REG_ERR		= 0x10,
-	REG_RIP		= 0x11,
-	REG_CS		= 0x12,
-	REG_RFLAGS	= 0x13,
-	REG_RSP		= 0x14,
-	REG_SS		= 0x15,
-};
-
diff --git a/src/pkg/runtime/defs_windows.go b/src/pkg/runtime/defs_windows.go
deleted file mode 100644
index 01aea92..0000000
--- a/src/pkg/runtime/defs_windows.go
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build ignore
-
-/*
-Input to cgo.
-
-GOARCH=amd64 go tool cgo -cdefs defs_windows.go > defs_windows_amd64.h
-GOARCH=386 go tool cgo -cdefs defs_windows.go > defs_windows_386.h
-*/
-
-package runtime
-
-/*
-#include <signal.h>
-#include <stdarg.h>
-#include <windef.h>
-#include <winbase.h>
-#include <wincon.h>
-
-#ifndef _X86_
-typedef struct {} FLOATING_SAVE_AREA;
-#endif
-#ifndef _AMD64_
-typedef struct {} M128A;
-#endif
-*/
-import "C"
-
-const (
-	PROT_NONE  = 0
-	PROT_READ  = 1
-	PROT_WRITE = 2
-	PROT_EXEC  = 4
-
-	MAP_ANON    = 1
-	MAP_PRIVATE = 2
-
-	DUPLICATE_SAME_ACCESS   = C.DUPLICATE_SAME_ACCESS
-	THREAD_PRIORITY_HIGHEST = C.THREAD_PRIORITY_HIGHEST
-
-	SIGINT           = C.SIGINT
-	CTRL_C_EVENT     = C.CTRL_C_EVENT
-	CTRL_BREAK_EVENT = C.CTRL_BREAK_EVENT
-
-	CONTEXT_CONTROL = C.CONTEXT_CONTROL
-	CONTEXT_FULL    = C.CONTEXT_FULL
-
-	EXCEPTION_ACCESS_VIOLATION     = C.STATUS_ACCESS_VIOLATION
-	EXCEPTION_BREAKPOINT           = C.STATUS_BREAKPOINT
-	EXCEPTION_FLT_DENORMAL_OPERAND = C.STATUS_FLOAT_DENORMAL_OPERAND
-	EXCEPTION_FLT_DIVIDE_BY_ZERO   = C.STATUS_FLOAT_DIVIDE_BY_ZERO
-	EXCEPTION_FLT_INEXACT_RESULT   = C.STATUS_FLOAT_INEXACT_RESULT
-	EXCEPTION_FLT_OVERFLOW         = C.STATUS_FLOAT_OVERFLOW
-	EXCEPTION_FLT_UNDERFLOW        = C.STATUS_FLOAT_UNDERFLOW
-	EXCEPTION_INT_DIVIDE_BY_ZERO   = C.STATUS_INTEGER_DIVIDE_BY_ZERO
-	EXCEPTION_INT_OVERFLOW         = C.STATUS_INTEGER_OVERFLOW
-
-	INFINITE     = C.INFINITE
-	WAIT_TIMEOUT = C.WAIT_TIMEOUT
-)
-
-type SystemInfo C.SYSTEM_INFO
-type ExceptionRecord C.EXCEPTION_RECORD
-type FloatingSaveArea C.FLOATING_SAVE_AREA
-type M128a C.M128A
-type Context C.CONTEXT
-type Overlapped C.OVERLAPPED
diff --git a/src/pkg/runtime/defs_windows_386.h b/src/pkg/runtime/defs_windows_386.h
deleted file mode 100644
index db3629a..0000000
--- a/src/pkg/runtime/defs_windows_386.h
+++ /dev/null
@@ -1,113 +0,0 @@
-// Created by cgo -cdefs - DO NOT EDIT
-// cgo -cdefs defs_windows.go
-
-
-enum {
-	PROT_NONE	= 0,
-	PROT_READ	= 1,
-	PROT_WRITE	= 2,
-	PROT_EXEC	= 4,
-
-	MAP_ANON	= 1,
-	MAP_PRIVATE	= 2,
-
-	DUPLICATE_SAME_ACCESS	= 0x2,
-	THREAD_PRIORITY_HIGHEST	= 0x2,
-
-	SIGINT			= 0x2,
-	CTRL_C_EVENT		= 0x0,
-	CTRL_BREAK_EVENT	= 0x1,
-
-	CONTEXT_CONTROL	= 0x10001,
-	CONTEXT_FULL	= 0x10007,
-
-	EXCEPTION_ACCESS_VIOLATION	= 0xc0000005,
-	EXCEPTION_BREAKPOINT		= 0x80000003,
-	EXCEPTION_FLT_DENORMAL_OPERAND	= 0xc000008d,
-	EXCEPTION_FLT_DIVIDE_BY_ZERO	= 0xc000008e,
-	EXCEPTION_FLT_INEXACT_RESULT	= 0xc000008f,
-	EXCEPTION_FLT_OVERFLOW		= 0xc0000091,
-	EXCEPTION_FLT_UNDERFLOW		= 0xc0000093,
-	EXCEPTION_INT_DIVIDE_BY_ZERO	= 0xc0000094,
-	EXCEPTION_INT_OVERFLOW		= 0xc0000095,
-
-	INFINITE	= 0xffffffff,
-	WAIT_TIMEOUT	= 0x102,
-};
-
-typedef struct SystemInfo SystemInfo;
-typedef struct ExceptionRecord ExceptionRecord;
-typedef struct FloatingSaveArea FloatingSaveArea;
-typedef struct M128a M128a;
-typedef struct Context Context;
-typedef struct Overlapped Overlapped;
-
-#pragma pack on
-
-struct SystemInfo {
-	byte	anon0[4];
-	uint32	dwPageSize;
-	byte	*lpMinimumApplicationAddress;
-	byte	*lpMaximumApplicationAddress;
-	uint32	dwActiveProcessorMask;
-	uint32	dwNumberOfProcessors;
-	uint32	dwProcessorType;
-	uint32	dwAllocationGranularity;
-	uint16	wProcessorLevel;
-	uint16	wProcessorRevision;
-};
-struct ExceptionRecord {
-	uint32	ExceptionCode;
-	uint32	ExceptionFlags;
-	ExceptionRecord	*ExceptionRecord;
-	byte	*ExceptionAddress;
-	uint32	NumberParameters;
-	uint32	ExceptionInformation[15];
-};
-struct FloatingSaveArea {
-	uint32	ControlWord;
-	uint32	StatusWord;
-	uint32	TagWord;
-	uint32	ErrorOffset;
-	uint32	ErrorSelector;
-	uint32	DataOffset;
-	uint32	DataSelector;
-	uint8	RegisterArea[80];
-	uint32	Cr0NpxState;
-};
-struct Context {
-	uint32	ContextFlags;
-	uint32	Dr0;
-	uint32	Dr1;
-	uint32	Dr2;
-	uint32	Dr3;
-	uint32	Dr6;
-	uint32	Dr7;
-	FloatingSaveArea	FloatSave;
-	uint32	SegGs;
-	uint32	SegFs;
-	uint32	SegEs;
-	uint32	SegDs;
-	uint32	Edi;
-	uint32	Esi;
-	uint32	Ebx;
-	uint32	Edx;
-	uint32	Ecx;
-	uint32	Eax;
-	uint32	Ebp;
-	uint32	Eip;
-	uint32	SegCs;
-	uint32	EFlags;
-	uint32	Esp;
-	uint32	SegSs;
-	uint8	ExtendedRegisters[512];
-};
-struct Overlapped {
-	uint32	Internal;
-	uint32	InternalHigh;
-	byte	anon0[8];
-	byte	*hEvent;
-};
-
-
-#pragma pack off
diff --git a/src/pkg/runtime/defs_windows_amd64.h b/src/pkg/runtime/defs_windows_amd64.h
deleted file mode 100644
index fe26f5a..0000000
--- a/src/pkg/runtime/defs_windows_amd64.h
+++ /dev/null
@@ -1,128 +0,0 @@
-// Created by cgo -cdefs - DO NOT EDIT
-// cgo -cdefs defs_windows.go
-
-
-enum {
-	PROT_NONE	= 0,
-	PROT_READ	= 1,
-	PROT_WRITE	= 2,
-	PROT_EXEC	= 4,
-
-	MAP_ANON	= 1,
-	MAP_PRIVATE	= 2,
-
-	DUPLICATE_SAME_ACCESS	= 0x2,
-	THREAD_PRIORITY_HIGHEST	= 0x2,
-
-	SIGINT			= 0x2,
-	CTRL_C_EVENT		= 0x0,
-	CTRL_BREAK_EVENT	= 0x1,
-
-	CONTEXT_CONTROL	= 0x100001,
-	CONTEXT_FULL	= 0x10000b,
-
-	EXCEPTION_ACCESS_VIOLATION	= 0xc0000005,
-	EXCEPTION_BREAKPOINT		= 0x80000003,
-	EXCEPTION_FLT_DENORMAL_OPERAND	= 0xc000008d,
-	EXCEPTION_FLT_DIVIDE_BY_ZERO	= 0xc000008e,
-	EXCEPTION_FLT_INEXACT_RESULT	= 0xc000008f,
-	EXCEPTION_FLT_OVERFLOW		= 0xc0000091,
-	EXCEPTION_FLT_UNDERFLOW		= 0xc0000093,
-	EXCEPTION_INT_DIVIDE_BY_ZERO	= 0xc0000094,
-	EXCEPTION_INT_OVERFLOW		= 0xc0000095,
-
-	INFINITE	= 0xffffffff,
-	WAIT_TIMEOUT	= 0x102,
-};
-
-typedef struct SystemInfo SystemInfo;
-typedef struct ExceptionRecord ExceptionRecord;
-typedef struct FloatingSaveArea FloatingSaveArea;
-typedef struct M128a M128a;
-typedef struct Context Context;
-typedef struct Overlapped Overlapped;
-
-#pragma pack on
-
-struct SystemInfo {
-	byte	anon0[4];
-	uint32	dwPageSize;
-	byte	*lpMinimumApplicationAddress;
-	byte	*lpMaximumApplicationAddress;
-	uint64	dwActiveProcessorMask;
-	uint32	dwNumberOfProcessors;
-	uint32	dwProcessorType;
-	uint32	dwAllocationGranularity;
-	uint16	wProcessorLevel;
-	uint16	wProcessorRevision;
-};
-struct ExceptionRecord {
-	uint32	ExceptionCode;
-	uint32	ExceptionFlags;
-	ExceptionRecord	*ExceptionRecord;
-	byte	*ExceptionAddress;
-	uint32	NumberParameters;
-	byte	Pad_cgo_0[4];
-	uint64	ExceptionInformation[15];
-};
-struct M128a {
-	uint64	Low;
-	int64	High;
-};
-struct Context {
-	uint64	P1Home;
-	uint64	P2Home;
-	uint64	P3Home;
-	uint64	P4Home;
-	uint64	P5Home;
-	uint64	P6Home;
-	uint32	ContextFlags;
-	uint32	MxCsr;
-	uint16	SegCs;
-	uint16	SegDs;
-	uint16	SegEs;
-	uint16	SegFs;
-	uint16	SegGs;
-	uint16	SegSs;
-	uint32	EFlags;
-	uint64	Dr0;
-	uint64	Dr1;
-	uint64	Dr2;
-	uint64	Dr3;
-	uint64	Dr6;
-	uint64	Dr7;
-	uint64	Rax;
-	uint64	Rcx;
-	uint64	Rdx;
-	uint64	Rbx;
-	uint64	Rsp;
-	uint64	Rbp;
-	uint64	Rsi;
-	uint64	Rdi;
-	uint64	R8;
-	uint64	R9;
-	uint64	R10;
-	uint64	R11;
-	uint64	R12;
-	uint64	R13;
-	uint64	R14;
-	uint64	R15;
-	uint64	Rip;
-	byte	anon0[512];
-	M128a	VectorRegister[26];
-	uint64	VectorControl;
-	uint64	DebugControl;
-	uint64	LastBranchToRip;
-	uint64	LastBranchFromRip;
-	uint64	LastExceptionToRip;
-	uint64	LastExceptionFromRip;
-};
-struct Overlapped {
-	uint64	Internal;
-	uint64	InternalHigh;
-	byte	anon0[8];
-	byte	*hEvent;
-};
-
-
-#pragma pack off
diff --git a/src/pkg/runtime/env_plan9.c b/src/pkg/runtime/env_plan9.c
deleted file mode 100644
index f732c9f..0000000
--- a/src/pkg/runtime/env_plan9.c
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2012 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "runtime.h"
-#include "os_GOOS.h"
-
-byte*
-runtime·getenv(int8 *s)
-{
-	int32 fd, n, r;
-	intgo len;
-	byte file[128];
-	byte *p;
-	static byte b[128];
-
-	len = runtime·findnull((byte*)s);
-	if(len > sizeof file-6)
-		return nil;
-
-	runtime·memclr(file, sizeof file);
-	runtime·memmove((void*)file, (void*)"/env/", 5);
-	runtime·memmove((void*)(file+5), (void*)s, len);
-
-	fd = runtime·open((int8*)file, OREAD, 0);
-	if(fd < 0)
-		return nil;
-	n = runtime·seek(fd, 0, 2);
-	if(runtime·strcmp((byte*)s, (byte*)"GOTRACEBACK") == 0){
-		// should not call malloc
-		if(n >= sizeof b)
-			return nil;
-		runtime·memclr(b, sizeof b);
-		p = b;
-	}else
-		p = runtime·malloc(n+1);
-	r = runtime·pread(fd, p, n, 0);
-	runtime·close(fd);
-	if(r < 0)
-		return nil;
-	return p;
-}
diff --git a/src/pkg/runtime/env_posix.c b/src/pkg/runtime/env_posix.c
deleted file mode 100644
index 4c8288f..0000000
--- a/src/pkg/runtime/env_posix.c
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris windows
-
-#include "runtime.h"
-#include "arch_GOARCH.h"
-#include "malloc.h"
-
-Slice syscall·envs;
-
-byte*
-runtime·getenv(int8 *s)
-{
-	int32 i, j;
-	intgo len;
-	byte *v, *bs;
-	String* envv;
-	int32 envc;
-
-	bs = (byte*)s;
-	len = runtime·findnull(bs);
-	envv = (String*)syscall·envs.array;
-	envc = syscall·envs.len;
-	for(i=0; i<envc; i++){
-		if(envv[i].len <= len)
-			continue;
-		v = envv[i].str;
-		for(j=0; j<len; j++)
-			if(bs[j] != v[j])
-				goto nomatch;
-		if(v[len] != '=')
-			goto nomatch;
-		return v+len+1;
-	nomatch:;
-	}
-	return nil;
-}
-
-void (*_cgo_setenv)(byte**);
-
-// Update the C environment if cgo is loaded.
-// Called from syscall.Setenv.
-void
-syscall·setenv_c(String k, String v)
-{
-	byte *arg[2];
-	uintptr len;
-
-	if(_cgo_setenv == nil)
-		return;
-
-	// Objects that are explicitly freed must be at least 16 bytes in size,
-	// so that they are not allocated using tiny alloc.
-	len = k.len + 1;
-	if(len < TinySize)
-		len = TinySize;
-	arg[0] = runtime·malloc(len);
-	runtime·memmove(arg[0], k.str, k.len);
-	arg[0][k.len] = 0;
-
-	len = v.len + 1;
-	if(len < TinySize)
-		len = TinySize;
-	arg[1] = runtime·malloc(len);
-	runtime·memmove(arg[1], v.str, v.len);
-	arg[1][v.len] = 0;
-
-	runtime·asmcgocall((void*)_cgo_setenv, arg);
-	runtime·free(arg[0]);
-	runtime·free(arg[1]);
-}
diff --git a/src/pkg/runtime/error.go b/src/pkg/runtime/error.go
deleted file mode 100644
index e704ff8..0000000
--- a/src/pkg/runtime/error.go
+++ /dev/null
@@ -1,124 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package runtime
-
-// The Error interface identifies a run time error.
-type Error interface {
-	error
-
-	// RuntimeError is a no-op function but
-	// serves to distinguish types that are runtime
-	// errors from ordinary errors: a type is a
-	// runtime error if it has a RuntimeError method.
-	RuntimeError()
-}
-
-// A TypeAssertionError explains a failed type assertion.
-type TypeAssertionError struct {
-	interfaceString string
-	concreteString  string
-	assertedString  string
-	missingMethod   string // one method needed by Interface, missing from Concrete
-}
-
-func (*TypeAssertionError) RuntimeError() {}
-
-func (e *TypeAssertionError) Error() string {
-	inter := e.interfaceString
-	if inter == "" {
-		inter = "interface"
-	}
-	if e.concreteString == "" {
-		return "interface conversion: " + inter + " is nil, not " + e.assertedString
-	}
-	if e.missingMethod == "" {
-		return "interface conversion: " + inter + " is " + e.concreteString +
-			", not " + e.assertedString
-	}
-	return "interface conversion: " + e.concreteString + " is not " + e.assertedString +
-		": missing method " + e.missingMethod
-}
-
-// For calling from C.
-func newTypeAssertionError(ps1, ps2, ps3 *string, pmeth *string, ret *interface{}) {
-	var s1, s2, s3, meth string
-
-	if ps1 != nil {
-		s1 = *ps1
-	}
-	if ps2 != nil {
-		s2 = *ps2
-	}
-	if ps3 != nil {
-		s3 = *ps3
-	}
-	if pmeth != nil {
-		meth = *pmeth
-	}
-	*ret = &TypeAssertionError{s1, s2, s3, meth}
-}
-
-// An errorString represents a runtime error described by a single string.
-type errorString string
-
-func (e errorString) RuntimeError() {}
-
-func (e errorString) Error() string {
-	return "runtime error: " + string(e)
-}
-
-// For calling from C.
-func newErrorString(s string, ret *interface{}) {
-	*ret = errorString(s)
-}
-
-// An errorCString represents a runtime error described by a single C string.
-// Not "type errorCString uintptr" because of http://golang.org/issue/7084.
-type errorCString struct{ cstr uintptr }
-
-func (e errorCString) RuntimeError() {}
-
-func cstringToGo(uintptr) string
-
-func (e errorCString) Error() string {
-	return "runtime error: " + cstringToGo(e.cstr)
-}
-
-// For calling from C.
-func newErrorCString(s uintptr, ret *interface{}) {
-	*ret = errorCString{s}
-}
-
-type stringer interface {
-	String() string
-}
-
-func typestring(interface{}) string
-
-// For calling from C.
-// Prints an argument passed to panic.
-// There's room for arbitrary complexity here, but we keep it
-// simple and handle just a few important cases: int, string, and Stringer.
-func printany(i interface{}) {
-	switch v := i.(type) {
-	case nil:
-		print("nil")
-	case stringer:
-		print(v.String())
-	case error:
-		print(v.Error())
-	case int:
-		print(v)
-	case string:
-		print(v)
-	default:
-		print("(", typestring(i), ") ", i)
-	}
-}
-
-// called from generated code
-func panicwrap(pkg, typ, meth string) {
-	panic("value method " + pkg + "." + typ + "." + meth + " called using nil *" + typ + " pointer")
-}
diff --git a/src/pkg/runtime/export_futex_test.go b/src/pkg/runtime/export_futex_test.go
deleted file mode 100644
index 1477828..0000000
--- a/src/pkg/runtime/export_futex_test.go
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2013 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build dragonfly freebsd linux
-
-package runtime
-
-func futexsleep(addr *uint32, val uint32, ns int64)
-func futexwakeup(addr *uint32, val uint32)
-
-var Futexsleep = futexsleep
-var Futexwakeup = futexwakeup
diff --git a/src/pkg/runtime/export_test.go b/src/pkg/runtime/export_test.go
deleted file mode 100644
index 7a31b63..0000000
--- a/src/pkg/runtime/export_test.go
+++ /dev/null
@@ -1,92 +0,0 @@
-// Copyright 2010 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Export guts for testing.
-
-package runtime
-
-var Fadd64 = fadd64
-var Fsub64 = fsub64
-var Fmul64 = fmul64
-var Fdiv64 = fdiv64
-var F64to32 = f64to32
-var F32to64 = f32to64
-var Fcmp64 = fcmp64
-var Fintto64 = fintto64
-var F64toint = f64toint
-
-func entersyscall()
-func exitsyscall()
-func golockedOSThread() bool
-func stackguard() (sp, limit uintptr)
-
-var Entersyscall = entersyscall
-var Exitsyscall = exitsyscall
-var LockedOSThread = golockedOSThread
-var Stackguard = stackguard
-
-type LFNode struct {
-	Next    *LFNode
-	Pushcnt uintptr
-}
-
-func lfstackpush_go(head *uint64, node *LFNode)
-func lfstackpop_go(head *uint64) *LFNode
-
-var LFStackPush = lfstackpush_go
-var LFStackPop = lfstackpop_go
-
-type ParFor struct {
-	body    *byte
-	done    uint32
-	Nthr    uint32
-	nthrmax uint32
-	thrseq  uint32
-	Cnt     uint32
-	Ctx     *byte
-	wait    bool
-}
-
-func newParFor(nthrmax uint32) *ParFor
-func parForSetup(desc *ParFor, nthr, n uint32, ctx *byte, wait bool, body func(*ParFor, uint32))
-func parForDo(desc *ParFor)
-func parForIters(desc *ParFor, tid uintptr) (uintptr, uintptr)
-
-var NewParFor = newParFor
-var ParForSetup = parForSetup
-var ParForDo = parForDo
-
-func ParForIters(desc *ParFor, tid uint32) (uint32, uint32) {
-	begin, end := parForIters(desc, uintptr(tid))
-	return uint32(begin), uint32(end)
-}
-
-func testSchedLocalQueue()
-func testSchedLocalQueueSteal()
-
-var TestSchedLocalQueue1 = testSchedLocalQueue
-var TestSchedLocalQueueSteal1 = testSchedLocalQueueSteal
-
-func haveGoodHash() bool
-func stringHash(s string, seed uintptr) uintptr
-func bytesHash(b []byte, seed uintptr) uintptr
-func int32Hash(i uint32, seed uintptr) uintptr
-func int64Hash(i uint64, seed uintptr) uintptr
-
-var HaveGoodHash = haveGoodHash
-var StringHash = stringHash
-var BytesHash = bytesHash
-var Int32Hash = int32Hash
-var Int64Hash = int64Hash
-
-var hashLoad float64 // declared in hashmap.c
-var HashLoad = &hashLoad
-
-func memclrBytes(b []byte)
-
-var MemclrBytes = memclrBytes
-
-func gogoBytes() int32
-
-var GogoBytes = gogoBytes
diff --git a/src/pkg/runtime/extern.go b/src/pkg/runtime/extern.go
deleted file mode 100644
index 053dc10..0000000
--- a/src/pkg/runtime/extern.go
+++ /dev/null
@@ -1,205 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-/*
-Package runtime contains operations that interact with Go's runtime system,
-such as functions to control goroutines. It also includes the low-level type information
-used by the reflect package; see reflect's documentation for the programmable
-interface to the run-time type system.
-
-Environment Variables
-
-The following environment variables ($name or %name%, depending on the host
-operating system) control the run-time behavior of Go programs. The meanings
-and use may change from release to release.
-
-The GOGC variable sets the initial garbage collection target percentage.
-A collection is triggered when the ratio of freshly allocated data to live data
-remaining after the previous collection reaches this percentage. The default
-is GOGC=100. Setting GOGC=off disables the garbage collector entirely.
-The runtime/debug package's SetGCPercent function allows changing this
-percentage at run time. See http://golang.org/pkg/runtime/debug/#SetGCPercent.
-
-The GODEBUG variable controls debug output from the runtime. GODEBUG value is
-a comma-separated list of name=val pairs. Supported names are:
-
-	allocfreetrace: setting allocfreetrace=1 causes every allocation to be
-	profiled and a stack trace printed on each object's allocation and free.
-
-	efence: setting efence=1 causes the allocator to run in a mode
-	where each object is allocated on a unique page and addresses are
-	never recycled.
-
-	gctrace: setting gctrace=1 causes the garbage collector to emit a single line to standard
-	error at each collection, summarizing the amount of memory collected and the
-	length of the pause. Setting gctrace=2 emits the same summary but also
-	repeats each collection.
-
-	gcdead: setting gcdead=1 causes the garbage collector to clobber all stack slots
-	that it thinks are dead.
-
-	scheddetail: setting schedtrace=X and scheddetail=1 causes the scheduler to emit
-	detailed multiline info every X milliseconds, describing state of the scheduler,
-	processors, threads and goroutines.
-
-	schedtrace: setting schedtrace=X causes the scheduler to emit a single line to standard
-	error every X milliseconds, summarizing the scheduler state.
-
-The GOMAXPROCS variable limits the number of operating system threads that
-can execute user-level Go code simultaneously. There is no limit to the number of threads
-that can be blocked in system calls on behalf of Go code; those do not count against
-the GOMAXPROCS limit. This package's GOMAXPROCS function queries and changes
-the limit.
-
-The GOTRACEBACK variable controls the amount of output generated when a Go
-program fails due to an unrecovered panic or an unexpected runtime condition.
-By default, a failure prints a stack trace for every extant goroutine, eliding functions
-internal to the run-time system, and then exits with exit code 2.
-If GOTRACEBACK=0, the per-goroutine stack traces are omitted entirely.
-If GOTRACEBACK=1, the default behavior is used.
-If GOTRACEBACK=2, the per-goroutine stack traces include run-time functions.
-If GOTRACEBACK=crash, the per-goroutine stack traces include run-time functions,
-and if possible the program crashes in an operating-specific manner instead of
-exiting. For example, on Unix systems, the program raises SIGABRT to trigger a
-core dump.
-
-The GOARCH, GOOS, GOPATH, and GOROOT environment variables complete
-the set of Go environment variables. They influence the building of Go programs
-(see http://golang.org/cmd/go and http://golang.org/pkg/go/build).
-GOARCH, GOOS, and GOROOT are recorded at compile time and made available by
-constants or functions in this package, but they do not influence the execution
-of the run-time system.
-*/
-package runtime
-
-// Gosched yields the processor, allowing other goroutines to run.  It does not
-// suspend the current goroutine, so execution resumes automatically.
-func Gosched()
-
-// Goexit terminates the goroutine that calls it.  No other goroutine is affected.
-// Goexit runs all deferred calls before terminating the goroutine.
-//
-// Calling Goexit from the main goroutine terminates that goroutine
-// without func main returning. Since func main has not returned,
-// the program continues execution of other goroutines.
-// If all other goroutines exit, the program crashes.
-func Goexit()
-
-// Caller reports file and line number information about function invocations on
-// the calling goroutine's stack.  The argument skip is the number of stack frames
-// to ascend, with 0 identifying the caller of Caller.  (For historical reasons the
-// meaning of skip differs between Caller and Callers.) The return values report the
-// program counter, file name, and line number within the file of the corresponding
-// call.  The boolean ok is false if it was not possible to recover the information.
-func Caller(skip int) (pc uintptr, file string, line int, ok bool)
-
-// Callers fills the slice pc with the program counters of function invocations
-// on the calling goroutine's stack.  The argument skip is the number of stack frames
-// to skip before recording in pc, with 0 identifying the frame for Callers itself and
-// 1 identifying the caller of Callers.
-// It returns the number of entries written to pc.
-func Callers(skip int, pc []uintptr) int
-
-type Func struct {
-	opaque struct{} // unexported field to disallow conversions
-}
-
-// FuncForPC returns a *Func describing the function that contains the
-// given program counter address, or else nil.
-func FuncForPC(pc uintptr) *Func
-
-// Name returns the name of the function.
-func (f *Func) Name() string {
-	return funcname_go(f)
-}
-
-// Entry returns the entry address of the function.
-func (f *Func) Entry() uintptr {
-	return funcentry_go(f)
-}
-
-// FileLine returns the file name and line number of the
-// source code corresponding to the program counter pc.
-// The result will not be accurate if pc is not a program
-// counter within f.
-func (f *Func) FileLine(pc uintptr) (file string, line int) {
-	return funcline_go(f, pc)
-}
-
-// implemented in symtab.c
-func funcline_go(*Func, uintptr) (string, int)
-func funcname_go(*Func) string
-func funcentry_go(*Func) uintptr
-
-// SetFinalizer sets the finalizer associated with x to f.
-// When the garbage collector finds an unreachable block
-// with an associated finalizer, it clears the association and runs
-// f(x) in a separate goroutine.  This makes x reachable again, but
-// now without an associated finalizer.  Assuming that SetFinalizer
-// is not called again, the next time the garbage collector sees
-// that x is unreachable, it will free x.
-//
-// SetFinalizer(x, nil) clears any finalizer associated with x.
-//
-// The argument x must be a pointer to an object allocated by
-// calling new or by taking the address of a composite literal.
-// The argument f must be a function that takes a single argument
-// to which x's type can be assigned, and can have arbitrary ignored return
-// values. If either of these is not true, SetFinalizer aborts the
-// program.
-//
-// Finalizers are run in dependency order: if A points at B, both have
-// finalizers, and they are otherwise unreachable, only the finalizer
-// for A runs; once A is freed, the finalizer for B can run.
-// If a cyclic structure includes a block with a finalizer, that
-// cycle is not guaranteed to be garbage collected and the finalizer
-// is not guaranteed to run, because there is no ordering that
-// respects the dependencies.
-//
-// The finalizer for x is scheduled to run at some arbitrary time after
-// x becomes unreachable.
-// There is no guarantee that finalizers will run before a program exits,
-// so typically they are useful only for releasing non-memory resources
-// associated with an object during a long-running program.
-// For example, an os.File object could use a finalizer to close the
-// associated operating system file descriptor when a program discards
-// an os.File without calling Close, but it would be a mistake
-// to depend on a finalizer to flush an in-memory I/O buffer such as a
-// bufio.Writer, because the buffer would not be flushed at program exit.
-//
-// It is not guaranteed that a finalizer will run if the size of *x is
-// zero bytes.
-//
-// A single goroutine runs all finalizers for a program, sequentially.
-// If a finalizer must run for a long time, it should do so by starting
-// a new goroutine.
-func SetFinalizer(x, f interface{})
-
-func getgoroot() string
-
-// GOROOT returns the root of the Go tree.
-// It uses the GOROOT environment variable, if set,
-// or else the root used during the Go build.
-func GOROOT() string {
-	s := getgoroot()
-	if s != "" {
-		return s
-	}
-	return defaultGoroot
-}
-
-// Version returns the Go tree's version string.
-// It is either the commit hash and date at the time of the build or,
-// when possible, a release tag like "go1.3".
-func Version() string {
-	return theVersion
-}
-
-// GOOS is the running program's operating system target:
-// one of darwin, freebsd, linux, and so on.
-const GOOS string = theGoos
-
-// GOARCH is the running program's architecture target:
-// 386, amd64, or arm.
-const GOARCH string = theGoarch
diff --git a/src/pkg/runtime/funcdata.h b/src/pkg/runtime/funcdata.h
deleted file mode 100644
index e20b6ae..0000000
--- a/src/pkg/runtime/funcdata.h
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2013 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// This file defines the IDs for PCDATA and FUNCDATA instructions
-// in Go binaries. It is included by both C and assembly, so it must
-// be written using #defines. It is included by the runtime package
-// as well as the compilers.
-
-#define PCDATA_ArgSize 0 /* argument size at CALL instruction */
-#define PCDATA_StackMapIndex 1
-
-#define FUNCDATA_ArgsPointerMaps 2 /* garbage collector blocks */
-#define FUNCDATA_LocalsPointerMaps 3
-#define FUNCDATA_DeadValueMaps 4
-
-// To be used in assembly.
-#define ARGSIZE(n) PCDATA $PCDATA_ArgSize, $n
-
-// ArgsSizeUnknown is set in Func.argsize to mark all functions
-// whose argument size is unknown (C vararg functions, and
-// assembly code without an explicit specification).
-// This value is generated by the compiler, assembler, or linker.
-#define ArgsSizeUnknown 0x80000000
diff --git a/src/pkg/runtime/gc_test.go b/src/pkg/runtime/gc_test.go
deleted file mode 100644
index 58717ec..0000000
--- a/src/pkg/runtime/gc_test.go
+++ /dev/null
@@ -1,236 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package runtime_test
-
-import (
-	"os"
-	"runtime"
-	"runtime/debug"
-	"testing"
-	"time"
-)
-
-func TestGcSys(t *testing.T) {
-	if os.Getenv("GOGC") == "off" {
-		t.Skip("skipping test; GOGC=off in environment")
-	}
-	data := struct{ Short bool }{testing.Short()}
-	got := executeTest(t, testGCSysSource, &data)
-	want := "OK\n"
-	if got != want {
-		t.Fatalf("expected %q, but got %q", want, got)
-	}
-}
-
-const testGCSysSource = `
-package main
-
-import (
-	"fmt"
-	"runtime"
-)
-
-func main() {
-	runtime.GOMAXPROCS(1)
-	memstats := new(runtime.MemStats)
-	runtime.GC()
-	runtime.ReadMemStats(memstats)
-	sys := memstats.Sys
-
-	runtime.MemProfileRate = 0 // disable profiler
-
-	itercount := 1000000
-{{if .Short}}
-	itercount = 100000
-{{end}}
-	for i := 0; i < itercount; i++ {
-		workthegc()
-	}
-
-	// Should only be using a few MB.
-	// We allocated 100 MB or (if not short) 1 GB.
-	runtime.ReadMemStats(memstats)
-	if sys > memstats.Sys {
-		sys = 0
-	} else {
-		sys = memstats.Sys - sys
-	}
-	if sys > 16<<20 {
-		fmt.Printf("using too much memory: %d bytes\n", sys)
-		return
-	}
-	fmt.Printf("OK\n")
-}
-
-func workthegc() []byte {
-	return make([]byte, 1029)
-}
-`
-
-func TestGcDeepNesting(t *testing.T) {
-	type T [2][2][2][2][2][2][2][2][2][2]*int
-	a := new(T)
-
-	// Prevent the compiler from applying escape analysis.
-	// This makes sure new(T) is allocated on heap, not on the stack.
-	t.Logf("%p", a)
-
-	a[0][0][0][0][0][0][0][0][0][0] = new(int)
-	*a[0][0][0][0][0][0][0][0][0][0] = 13
-	runtime.GC()
-	if *a[0][0][0][0][0][0][0][0][0][0] != 13 {
-		t.Fail()
-	}
-}
-
-func TestGcHashmapIndirection(t *testing.T) {
-	defer debug.SetGCPercent(debug.SetGCPercent(1))
-	runtime.GC()
-	type T struct {
-		a [256]int
-	}
-	m := make(map[T]T)
-	for i := 0; i < 2000; i++ {
-		var a T
-		a.a[0] = i
-		m[a] = T{}
-	}
-}
-
-func TestGcArraySlice(t *testing.T) {
-	type X struct {
-		buf     [1]byte
-		nextbuf []byte
-		next    *X
-	}
-	var head *X
-	for i := 0; i < 10; i++ {
-		p := &X{}
-		p.buf[0] = 42
-		p.next = head
-		if head != nil {
-			p.nextbuf = head.buf[:]
-		}
-		head = p
-		runtime.GC()
-	}
-	for p := head; p != nil; p = p.next {
-		if p.buf[0] != 42 {
-			t.Fatal("corrupted heap")
-		}
-	}
-}
-
-func TestGcRescan(t *testing.T) {
-	type X struct {
-		c     chan error
-		nextx *X
-	}
-	type Y struct {
-		X
-		nexty *Y
-		p     *int
-	}
-	var head *Y
-	for i := 0; i < 10; i++ {
-		p := &Y{}
-		p.c = make(chan error)
-		if head != nil {
-			p.nextx = &head.X
-		}
-		p.nexty = head
-		p.p = new(int)
-		*p.p = 42
-		head = p
-		runtime.GC()
-	}
-	for p := head; p != nil; p = p.nexty {
-		if *p.p != 42 {
-			t.Fatal("corrupted heap")
-		}
-	}
-}
-
-func TestGcLastTime(t *testing.T) {
-	ms := new(runtime.MemStats)
-	t0 := time.Now().UnixNano()
-	runtime.GC()
-	t1 := time.Now().UnixNano()
-	runtime.ReadMemStats(ms)
-	last := int64(ms.LastGC)
-	if t0 > last || last > t1 {
-		t.Fatalf("bad last GC time: got %v, want [%v, %v]", last, t0, t1)
-	}
-}
-
-func BenchmarkSetTypeNoPtr1(b *testing.B) {
-	type NoPtr1 struct {
-		p uintptr
-	}
-	var p *NoPtr1
-	for i := 0; i < b.N; i++ {
-		p = &NoPtr1{}
-	}
-	_ = p
-}
-func BenchmarkSetTypeNoPtr2(b *testing.B) {
-	type NoPtr2 struct {
-		p, q uintptr
-	}
-	var p *NoPtr2
-	for i := 0; i < b.N; i++ {
-		p = &NoPtr2{}
-	}
-	_ = p
-}
-func BenchmarkSetTypePtr1(b *testing.B) {
-	type Ptr1 struct {
-		p *byte
-	}
-	var p *Ptr1
-	for i := 0; i < b.N; i++ {
-		p = &Ptr1{}
-	}
-	_ = p
-}
-func BenchmarkSetTypePtr2(b *testing.B) {
-	type Ptr2 struct {
-		p, q *byte
-	}
-	var p *Ptr2
-	for i := 0; i < b.N; i++ {
-		p = &Ptr2{}
-	}
-	_ = p
-}
-
-func BenchmarkAllocation(b *testing.B) {
-	type T struct {
-		x, y *byte
-	}
-	ngo := runtime.GOMAXPROCS(0)
-	work := make(chan bool, b.N+ngo)
-	result := make(chan *T)
-	for i := 0; i < b.N; i++ {
-		work <- true
-	}
-	for i := 0; i < ngo; i++ {
-		work <- false
-	}
-	for i := 0; i < ngo; i++ {
-		go func() {
-			var x *T
-			for <-work {
-				for i := 0; i < 1000; i++ {
-					x = &T{}
-				}
-			}
-			result <- x
-		}()
-	}
-	for i := 0; i < ngo; i++ {
-		<-result
-	}
-}
diff --git a/src/pkg/runtime/hash_test.go b/src/pkg/runtime/hash_test.go
deleted file mode 100644
index 1c11e05..0000000
--- a/src/pkg/runtime/hash_test.go
+++ /dev/null
@@ -1,512 +0,0 @@
-// Copyright 2013 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package runtime_test
-
-import (
-	"fmt"
-	"math"
-	"math/rand"
-	. "runtime"
-	"strings"
-	"testing"
-)
-
-// Smhasher is a torture test for hash functions.
-// https://code.google.com/p/smhasher/
-// This code is a port of some of the Smhasher tests to Go.
-//
-// The current AES hash function passes Smhasher.  Our fallback
-// hash functions don't, so we only enable the difficult tests when
-// we know the AES implementation is available.
-
-// Sanity checks.
-// hash should not depend on values outside key.
-// hash should not depend on alignment.
-func TestSmhasherSanity(t *testing.T) {
-	r := rand.New(rand.NewSource(1234))
-	const REP = 10
-	const KEYMAX = 128
-	const PAD = 16
-	const OFFMAX = 16
-	for k := 0; k < REP; k++ {
-		for n := 0; n < KEYMAX; n++ {
-			for i := 0; i < OFFMAX; i++ {
-				var b [KEYMAX + OFFMAX + 2*PAD]byte
-				var c [KEYMAX + OFFMAX + 2*PAD]byte
-				randBytes(r, b[:])
-				randBytes(r, c[:])
-				copy(c[PAD+i:PAD+i+n], b[PAD:PAD+n])
-				if BytesHash(b[PAD:PAD+n], 0) != BytesHash(c[PAD+i:PAD+i+n], 0) {
-					t.Errorf("hash depends on bytes outside key")
-				}
-			}
-		}
-	}
-}
-
-type HashSet struct {
-	m map[uintptr]struct{} // set of hashes added
-	n int                  // number of hashes added
-}
-
-func newHashSet() *HashSet {
-	return &HashSet{make(map[uintptr]struct{}), 0}
-}
-func (s *HashSet) add(h uintptr) {
-	s.m[h] = struct{}{}
-	s.n++
-}
-func (s *HashSet) addS(x string) {
-	s.add(StringHash(x, 0))
-}
-func (s *HashSet) addB(x []byte) {
-	s.add(BytesHash(x, 0))
-}
-func (s *HashSet) addS_seed(x string, seed uintptr) {
-	s.add(StringHash(x, seed))
-}
-func (s *HashSet) check(t *testing.T) {
-	const SLOP = 10.0
-	collisions := s.n - len(s.m)
-	//fmt.Printf("%d/%d\n", len(s.m), s.n)
-	pairs := int64(s.n) * int64(s.n-1) / 2
-	expected := float64(pairs) / math.Pow(2.0, float64(hashSize))
-	stddev := math.Sqrt(expected)
-	if float64(collisions) > expected+SLOP*3*stddev {
-		t.Errorf("unexpected number of collisions: got=%d mean=%f stddev=%f", collisions, expected, stddev)
-	}
-}
-
-// a string plus adding zeros must make distinct hashes
-func TestSmhasherAppendedZeros(t *testing.T) {
-	s := "hello" + strings.Repeat("\x00", 256)
-	h := newHashSet()
-	for i := 0; i <= len(s); i++ {
-		h.addS(s[:i])
-	}
-	h.check(t)
-}
-
-// All 0-3 byte strings have distinct hashes.
-func TestSmhasherSmallKeys(t *testing.T) {
-	h := newHashSet()
-	var b [3]byte
-	for i := 0; i < 256; i++ {
-		b[0] = byte(i)
-		h.addB(b[:1])
-		for j := 0; j < 256; j++ {
-			b[1] = byte(j)
-			h.addB(b[:2])
-			if !testing.Short() {
-				for k := 0; k < 256; k++ {
-					b[2] = byte(k)
-					h.addB(b[:3])
-				}
-			}
-		}
-	}
-	h.check(t)
-}
-
-// Different length strings of all zeros have distinct hashes.
-func TestSmhasherZeros(t *testing.T) {
-	N := 256 * 1024
-	if testing.Short() {
-		N = 1024
-	}
-	h := newHashSet()
-	b := make([]byte, N)
-	for i := 0; i <= N; i++ {
-		h.addB(b[:i])
-	}
-	h.check(t)
-}
-
-// Strings with up to two nonzero bytes all have distinct hashes.
-func TestSmhasherTwoNonzero(t *testing.T) {
-	if testing.Short() {
-		t.Skip("Skipping in short mode")
-	}
-	h := newHashSet()
-	for n := 2; n <= 16; n++ {
-		twoNonZero(h, n)
-	}
-	h.check(t)
-}
-func twoNonZero(h *HashSet, n int) {
-	b := make([]byte, n)
-
-	// all zero
-	h.addB(b[:])
-
-	// one non-zero byte
-	for i := 0; i < n; i++ {
-		for x := 1; x < 256; x++ {
-			b[i] = byte(x)
-			h.addB(b[:])
-			b[i] = 0
-		}
-	}
-
-	// two non-zero bytes
-	for i := 0; i < n; i++ {
-		for x := 1; x < 256; x++ {
-			b[i] = byte(x)
-			for j := i + 1; j < n; j++ {
-				for y := 1; y < 256; y++ {
-					b[j] = byte(y)
-					h.addB(b[:])
-					b[j] = 0
-				}
-			}
-			b[i] = 0
-		}
-	}
-}
-
-// Test strings with repeats, like "abcdabcdabcdabcd..."
-func TestSmhasherCyclic(t *testing.T) {
-	if testing.Short() {
-		t.Skip("Skipping in short mode")
-	}
-	if !HaveGoodHash() {
-		t.Skip("fallback hash not good enough for this test")
-	}
-	r := rand.New(rand.NewSource(1234))
-	const REPEAT = 8
-	const N = 1000000
-	for n := 4; n <= 12; n++ {
-		h := newHashSet()
-		b := make([]byte, REPEAT*n)
-		for i := 0; i < N; i++ {
-			b[0] = byte(i * 79 % 97)
-			b[1] = byte(i * 43 % 137)
-			b[2] = byte(i * 151 % 197)
-			b[3] = byte(i * 199 % 251)
-			randBytes(r, b[4:n])
-			for j := n; j < n*REPEAT; j++ {
-				b[j] = b[j-n]
-			}
-			h.addB(b)
-		}
-		h.check(t)
-	}
-}
-
-// Test strings with only a few bits set
-func TestSmhasherSparse(t *testing.T) {
-	if testing.Short() {
-		t.Skip("Skipping in short mode")
-	}
-	sparse(t, 32, 6)
-	sparse(t, 40, 6)
-	sparse(t, 48, 5)
-	sparse(t, 56, 5)
-	sparse(t, 64, 5)
-	sparse(t, 96, 4)
-	sparse(t, 256, 3)
-	sparse(t, 2048, 2)
-}
-func sparse(t *testing.T, n int, k int) {
-	b := make([]byte, n/8)
-	h := newHashSet()
-	setbits(h, b, 0, k)
-	h.check(t)
-}
-
-// set up to k bits at index i and greater
-func setbits(h *HashSet, b []byte, i int, k int) {
-	h.addB(b)
-	if k == 0 {
-		return
-	}
-	for j := i; j < len(b)*8; j++ {
-		b[j/8] |= byte(1 << uint(j&7))
-		setbits(h, b, j+1, k-1)
-		b[j/8] &= byte(^(1 << uint(j&7)))
-	}
-}
-
-// Test all possible combinations of n blocks from the set s.
-// "permutation" is a bad name here, but it is what Smhasher uses.
-func TestSmhasherPermutation(t *testing.T) {
-	if testing.Short() {
-		t.Skip("Skipping in short mode")
-	}
-	if !HaveGoodHash() {
-		t.Skip("fallback hash not good enough for this test")
-	}
-	permutation(t, []uint32{0, 1, 2, 3, 4, 5, 6, 7}, 8)
-	permutation(t, []uint32{0, 1 << 29, 2 << 29, 3 << 29, 4 << 29, 5 << 29, 6 << 29, 7 << 29}, 8)
-	permutation(t, []uint32{0, 1}, 20)
-	permutation(t, []uint32{0, 1 << 31}, 20)
-	permutation(t, []uint32{0, 1, 2, 3, 4, 5, 6, 7, 1 << 29, 2 << 29, 3 << 29, 4 << 29, 5 << 29, 6 << 29, 7 << 29}, 6)
-}
-func permutation(t *testing.T, s []uint32, n int) {
-	b := make([]byte, n*4)
-	h := newHashSet()
-	genPerm(h, b, s, 0)
-	h.check(t)
-}
-func genPerm(h *HashSet, b []byte, s []uint32, n int) {
-	h.addB(b[:n])
-	if n == len(b) {
-		return
-	}
-	for _, v := range s {
-		b[n] = byte(v)
-		b[n+1] = byte(v >> 8)
-		b[n+2] = byte(v >> 16)
-		b[n+3] = byte(v >> 24)
-		genPerm(h, b, s, n+4)
-	}
-}
-
-type Key interface {
-	clear()              // set bits all to 0
-	random(r *rand.Rand) // set key to something random
-	bits() int           // how many bits key has
-	flipBit(i int)       // flip bit i of the key
-	hash() uintptr       // hash the key
-	name() string        // for error reporting
-}
-
-type BytesKey struct {
-	b []byte
-}
-
-func (k *BytesKey) clear() {
-	for i := range k.b {
-		k.b[i] = 0
-	}
-}
-func (k *BytesKey) random(r *rand.Rand) {
-	randBytes(r, k.b)
-}
-func (k *BytesKey) bits() int {
-	return len(k.b) * 8
-}
-func (k *BytesKey) flipBit(i int) {
-	k.b[i>>3] ^= byte(1 << uint(i&7))
-}
-func (k *BytesKey) hash() uintptr {
-	return BytesHash(k.b, 0)
-}
-func (k *BytesKey) name() string {
-	return fmt.Sprintf("bytes%d", len(k.b))
-}
-
-type Int32Key struct {
-	i uint32
-}
-
-func (k *Int32Key) clear() {
-	k.i = 0
-}
-func (k *Int32Key) random(r *rand.Rand) {
-	k.i = r.Uint32()
-}
-func (k *Int32Key) bits() int {
-	return 32
-}
-func (k *Int32Key) flipBit(i int) {
-	k.i ^= 1 << uint(i)
-}
-func (k *Int32Key) hash() uintptr {
-	return Int32Hash(k.i, 0)
-}
-func (k *Int32Key) name() string {
-	return "int32"
-}
-
-type Int64Key struct {
-	i uint64
-}
-
-func (k *Int64Key) clear() {
-	k.i = 0
-}
-func (k *Int64Key) random(r *rand.Rand) {
-	k.i = uint64(r.Uint32()) + uint64(r.Uint32())<<32
-}
-func (k *Int64Key) bits() int {
-	return 64
-}
-func (k *Int64Key) flipBit(i int) {
-	k.i ^= 1 << uint(i)
-}
-func (k *Int64Key) hash() uintptr {
-	return Int64Hash(k.i, 0)
-}
-func (k *Int64Key) name() string {
-	return "int64"
-}
-
-// Flipping a single bit of a key should flip each output bit with 50% probability.
-func TestSmhasherAvalanche(t *testing.T) {
-	if !HaveGoodHash() {
-		t.Skip("fallback hash not good enough for this test")
-	}
-	if testing.Short() {
-		t.Skip("Skipping in short mode")
-	}
-	avalancheTest1(t, &BytesKey{make([]byte, 2)})
-	avalancheTest1(t, &BytesKey{make([]byte, 4)})
-	avalancheTest1(t, &BytesKey{make([]byte, 8)})
-	avalancheTest1(t, &BytesKey{make([]byte, 16)})
-	avalancheTest1(t, &BytesKey{make([]byte, 32)})
-	avalancheTest1(t, &BytesKey{make([]byte, 200)})
-	avalancheTest1(t, &Int32Key{})
-	avalancheTest1(t, &Int64Key{})
-}
-func avalancheTest1(t *testing.T, k Key) {
-	const REP = 100000
-	r := rand.New(rand.NewSource(1234))
-	n := k.bits()
-
-	// grid[i][j] is a count of whether flipping
-	// input bit i affects output bit j.
-	grid := make([][hashSize]int, n)
-
-	for z := 0; z < REP; z++ {
-		// pick a random key, hash it
-		k.random(r)
-		h := k.hash()
-
-		// flip each bit, hash & compare the results
-		for i := 0; i < n; i++ {
-			k.flipBit(i)
-			d := h ^ k.hash()
-			k.flipBit(i)
-
-			// record the effects of that bit flip
-			g := &grid[i]
-			for j := 0; j < hashSize; j++ {
-				g[j] += int(d & 1)
-				d >>= 1
-			}
-		}
-	}
-
-	// Each entry in the grid should be about REP/2.
-	// More precisely, we did N = k.bits() * hashSize experiments where
-	// each is the sum of REP coin flips.  We want to find bounds on the
-	// sum of coin flips such that a truly random experiment would have
-	// all sums inside those bounds with 99% probability.
-	N := n * hashSize
-	var c float64
-	// find c such that Prob(mean-c*stddev < x < mean+c*stddev)^N > .9999
-	for c = 0.0; math.Pow(math.Erf(c/math.Sqrt(2)), float64(N)) < .9999; c += .1 {
-	}
-	c *= 4.0 // allowed slack - we don't need to be perfectly random
-	mean := .5 * REP
-	stddev := .5 * math.Sqrt(REP)
-	low := int(mean - c*stddev)
-	high := int(mean + c*stddev)
-	for i := 0; i < n; i++ {
-		for j := 0; j < hashSize; j++ {
-			x := grid[i][j]
-			if x < low || x > high {
-				t.Errorf("bad bias for %s bit %d -> bit %d: %d/%d\n", k.name(), i, j, x, REP)
-			}
-		}
-	}
-}
-
-// All bit rotations of a set of distinct keys
-func TestSmhasherWindowed(t *testing.T) {
-	windowed(t, &Int32Key{})
-	windowed(t, &Int64Key{})
-	windowed(t, &BytesKey{make([]byte, 128)})
-}
-func windowed(t *testing.T, k Key) {
-	if testing.Short() {
-		t.Skip("Skipping in short mode")
-	}
-	const BITS = 16
-
-	for r := 0; r < k.bits(); r++ {
-		h := newHashSet()
-		for i := 0; i < 1<<BITS; i++ {
-			k.clear()
-			for j := 0; j < BITS; j++ {
-				if i>>uint(j)&1 != 0 {
-					k.flipBit((j + r) % k.bits())
-				}
-			}
-			h.add(k.hash())
-		}
-		h.check(t)
-	}
-}
-
-// All keys of the form prefix + [A-Za-z0-9]*N + suffix.
-func TestSmhasherText(t *testing.T) {
-	if testing.Short() {
-		t.Skip("Skipping in short mode")
-	}
-	text(t, "Foo", "Bar")
-	text(t, "FooBar", "")
-	text(t, "", "FooBar")
-}
-func text(t *testing.T, prefix, suffix string) {
-	const N = 4
-	const S = "ABCDEFGHIJKLMNOPQRSTabcdefghijklmnopqrst0123456789"
-	const L = len(S)
-	b := make([]byte, len(prefix)+N+len(suffix))
-	copy(b, prefix)
-	copy(b[len(prefix)+N:], suffix)
-	h := newHashSet()
-	c := b[len(prefix):]
-	for i := 0; i < L; i++ {
-		c[0] = S[i]
-		for j := 0; j < L; j++ {
-			c[1] = S[j]
-			for k := 0; k < L; k++ {
-				c[2] = S[k]
-				for x := 0; x < L; x++ {
-					c[3] = S[x]
-					h.addB(b)
-				}
-			}
-		}
-	}
-	h.check(t)
-}
-
-// Make sure different seed values generate different hashes.
-func TestSmhasherSeed(t *testing.T) {
-	h := newHashSet()
-	const N = 100000
-	s := "hello"
-	for i := 0; i < N; i++ {
-		h.addS_seed(s, uintptr(i))
-	}
-	h.check(t)
-}
-
-// size of the hash output (32 or 64 bits)
-const hashSize = 32 + int(^uintptr(0)>>63<<5)
-
-func randBytes(r *rand.Rand, b []byte) {
-	for i := range b {
-		b[i] = byte(r.Uint32())
-	}
-}
-
-func benchmarkHash(b *testing.B, n int) {
-	s := strings.Repeat("A", n)
-
-	for i := 0; i < b.N; i++ {
-		StringHash(s, 0)
-	}
-	b.SetBytes(int64(n))
-}
-
-func BenchmarkHash5(b *testing.B)     { benchmarkHash(b, 5) }
-func BenchmarkHash16(b *testing.B)    { benchmarkHash(b, 16) }
-func BenchmarkHash64(b *testing.B)    { benchmarkHash(b, 64) }
-func BenchmarkHash1024(b *testing.B)  { benchmarkHash(b, 1024) }
-func BenchmarkHash65536(b *testing.B) { benchmarkHash(b, 65536) }
diff --git a/src/pkg/runtime/hashmap.goc b/src/pkg/runtime/hashmap.goc
deleted file mode 100644
index 3327bed..0000000
--- a/src/pkg/runtime/hashmap.goc
+++ /dev/null
@@ -1,1078 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package runtime
-#include "runtime.h"
-#include "arch_GOARCH.h"
-#include "malloc.h"
-#include "type.h"
-#include "race.h"
-#include "hashmap.h"
-#include "typekind.h"
-#include "../../cmd/ld/textflag.h"
-
-enum
-{
-	docheck = 0,  // check invariants before and after every op.  Slow!!!
-	debug = 0,    // print every operation
-	checkgc = 0 || docheck,  // check interaction of mallocgc() with the garbage collector
-};
-static void
-check(MapType *t, Hmap *h)
-{
-	uintptr bucket, oldbucket;
-	Bucket *b;
-	uintptr i;
-	uintptr hash;
-	uintgo cnt;
-	uint8 top;
-	bool eq;
-	byte *k, *v;
-
-	cnt = 0;
-
-	// check buckets
-	for(bucket = 0; bucket < (uintptr)1 << h->B; bucket++) {
-		for(b = (Bucket*)(h->buckets + bucket * h->bucketsize); b != nil; b = b->overflow) {
-			for(i = 0, k = (byte*)b->data, v = k + h->keysize * BUCKETSIZE; i < BUCKETSIZE; i++, k += h->keysize, v += h->valuesize) {
-				if(b->tophash[i] == Empty)
-					continue;
-				if(b->tophash[i] > Empty && b->tophash[i] < MinTopHash)
-					runtime·throw("evacuated cell in buckets");
-				cnt++;
-				t->key->alg->equal(&eq, t->key->size, IK(h, k), IK(h, k));
-				if(!eq)
-					continue; // NaN!
-				hash = h->hash0;
-				t->key->alg->hash(&hash, t->key->size, IK(h, k));
-				top = hash >> (8*sizeof(uintptr) - 8);
-				if(top < MinTopHash)
-					top += MinTopHash;
-				if(top != b->tophash[i])
-					runtime·throw("bad hash");
-			}
-		}
-	}
-
-	// check oldbuckets
-	if(h->oldbuckets != nil) {
-		for(oldbucket = 0; oldbucket < (uintptr)1 << (h->B - 1); oldbucket++) {
-			b = (Bucket*)(h->oldbuckets + oldbucket * h->bucketsize);
-			for(; b != nil; b = b->overflow) {
-				for(i = 0, k = (byte*)b->data, v = k + h->keysize * BUCKETSIZE; i < BUCKETSIZE; i++, k += h->keysize, v += h->valuesize) {
-					if(b->tophash[i] < MinTopHash)
-						continue;
-					if(oldbucket < h->nevacuate)
-						runtime·throw("unevacuated entry in an evacuated bucket");
-					cnt++;
-					t->key->alg->equal(&eq, t->key->size, IK(h, k), IK(h, k));
-					if(!eq)
-						continue; // NaN!
-					hash = h->hash0;
-					t->key->alg->hash(&hash, t->key->size, IK(h, k));
-					top = hash >> (8*sizeof(uintptr) - 8);
-					if(top < MinTopHash)
-						top += MinTopHash;
-					if(top != b->tophash[i])
-						runtime·throw("bad hash (old)");
-				}
-			}
-		}
-	}
-
-	if(cnt != h->count) {
-		runtime·printf("%D %D\n", (uint64)cnt, (uint64)h->count);
-		runtime·throw("entries missing");
-	}
-}
-
-static void
-hash_init(MapType *t, Hmap *h, uint32 hint)
-{
-	uint8 B;
-	byte *buckets;
-	uintptr keysize, valuesize, bucketsize;
-	uint8 flags;
-
-	flags = 0;
-
-	// figure out how big we have to make everything
-	keysize = t->key->size;
-	if(keysize > MAXKEYSIZE) {
-		flags |= IndirectKey;
-		keysize = sizeof(byte*);
-	}
-	valuesize = t->elem->size;
-	if(valuesize > MAXVALUESIZE) {
-		flags |= IndirectValue;
-		valuesize = sizeof(byte*);
-	}
-	bucketsize = offsetof(Bucket, data[0]) + (keysize + valuesize) * BUCKETSIZE;
-	if(bucketsize != t->bucket->size) {
-		runtime·printf("runtime: bucketsize=%p but t->bucket->size=%p; t=%S\n", bucketsize, t->bucket->size, *t->string);
-		runtime·throw("bucketsize wrong");
-	}
-
-	// invariants we depend on.  We should probably check these at compile time
-	// somewhere, but for now we'll do it here.
-	if(t->key->align > BUCKETSIZE)
-		runtime·throw("key align too big");
-	if(t->elem->align > BUCKETSIZE)
-		runtime·throw("value align too big");
-	if(t->key->size % t->key->align != 0)
-		runtime·throw("key size not a multiple of key align");
-	if(t->elem->size % t->elem->align != 0)
-		runtime·throw("value size not a multiple of value align");
-	if(BUCKETSIZE < 8)
-		runtime·throw("bucketsize too small for proper alignment");
-	if((offsetof(Bucket, data[0]) & (t->key->align-1)) != 0)
-		runtime·throw("need padding in bucket (key)");
-	if((offsetof(Bucket, data[0]) & (t->elem->align-1)) != 0)
-		runtime·throw("need padding in bucket (value)");
-
-	// find size parameter which will hold the requested # of elements
-	B = 0;
-	while(hint > BUCKETSIZE && hint > LOAD * ((uintptr)1 << B))
-		B++;
-
-	// allocate initial hash table
-	// If hint is large zeroing this memory could take a while.
-	if(checkgc) mstats.next_gc = mstats.heap_alloc;
-	if(B == 0) {
-		// done lazily later.
-		buckets = nil;
-	} else {
-		buckets = runtime·cnewarray(t->bucket, (uintptr)1 << B);
-	}
-
-	// initialize Hmap
-	h->count = 0;
-	h->B = B;
-	h->flags = flags;
-	h->keysize = keysize;
-	h->valuesize = valuesize;
-	h->bucketsize = bucketsize;
-	h->hash0 = runtime·fastrand1();
-	h->buckets = buckets;
-	h->oldbuckets = nil;
-	h->nevacuate = 0;
-	if(docheck)
-		check(t, h);
-}
-
-// Moves entries in oldbuckets[i] to buckets[i] and buckets[i+2^k].
-// We leave the original bucket intact, except for marking the topbits
-// entries as evacuated, so that iterators can still iterate through the old buckets.
-static void
-evacuate(MapType *t, Hmap *h, uintptr oldbucket)
-{
-	Bucket *b;
-	Bucket *x, *y;
-	Bucket *newx, *newy;
-	uintptr xi, yi;
-	uintptr newbit;
-	uintptr hash;
-	uintptr i;
-	byte *k, *v;
-	byte *xk, *yk, *xv, *yv;
-	uint8 top;
-	bool eq;
-
-	b = (Bucket*)(h->oldbuckets + oldbucket * h->bucketsize);
-	newbit = (uintptr)1 << (h->B - 1);
-
-	if(!evacuated(b)) {
-		// TODO: reuse overflow buckets instead of using new ones, if there
-		// is no iterator using the old buckets.  (If !OldIterator.)
-
-		x = (Bucket*)(h->buckets + oldbucket * h->bucketsize);
-		y = (Bucket*)(h->buckets + (oldbucket + newbit) * h->bucketsize);
-		xi = 0;
-		yi = 0;
-		xk = (byte*)x->data;
-		yk = (byte*)y->data;
-		xv = xk + h->keysize * BUCKETSIZE;
-		yv = yk + h->keysize * BUCKETSIZE;
-		for(; b != nil; b = b->overflow) {
-			for(i = 0, k = (byte*)b->data, v = k + h->keysize * BUCKETSIZE; i < BUCKETSIZE; i++, k += h->keysize, v += h->valuesize) {
-				top = b->tophash[i];
-				if(top == Empty) {
-					b->tophash[i] = EvacuatedEmpty;
-					continue;
-				}
-				if(top < MinTopHash)
-					runtime·throw("bad state");
-
-				// Compute hash to make our evacuation decision (whether we need
-				// to send this key/value to bucket x or bucket y).
-				hash = h->hash0;
-				t->key->alg->hash(&hash, t->key->size, IK(h, k));
-				if((h->flags & Iterator) != 0) {
-					t->key->alg->equal(&eq, t->key->size, IK(h, k), IK(h, k));
-					if(!eq) {
-						// If key != key (NaNs), then the hash could be (and probably
-						// will be) entirely different from the old hash.  Moreover,
-						// it isn't reproducible.  Reproducibility is required in the
-						// presence of iterators, as our evacuation decision must
-						// match whatever decision the iterator made.
-						// Fortunately, we have the freedom to send these keys either
-						// way.  Also, tophash is meaningless for these kinds of keys.
-						// We let the low bit of tophash drive the evacuation decision.
-						// We recompute a new random tophash for the next level so
-						// these keys will get evenly distributed across all buckets
-						// after multiple grows.
-						if((top & 1) != 0)
-							hash |= newbit;
-						else
-							hash &= ~newbit;
-						top = hash >> (8*sizeof(uintptr)-8);
-						if(top < MinTopHash)
-							top += MinTopHash;
-					}
-				}
-
-				if((hash & newbit) == 0) {
-					b->tophash[i] = EvacuatedX;
-					if(xi == BUCKETSIZE) {
-						if(checkgc) mstats.next_gc = mstats.heap_alloc;
-						newx = runtime·cnew(t->bucket);
-						x->overflow = newx;
-						x = newx;
-						xi = 0;
-						xk = (byte*)x->data;
-						xv = xk + h->keysize * BUCKETSIZE;
-					}
-					x->tophash[xi] = top;
-					if((h->flags & IndirectKey) != 0) {
-						*(byte**)xk = *(byte**)k;               // copy pointer
-					} else {
-						t->key->alg->copy(t->key->size, xk, k); // copy value
-					}
-					if((h->flags & IndirectValue) != 0) {
-						*(byte**)xv = *(byte**)v;
-					} else {
-						t->elem->alg->copy(t->elem->size, xv, v);
-					}
-					xi++;
-					xk += h->keysize;
-					xv += h->valuesize;
-				} else {
-					b->tophash[i] = EvacuatedY;
-					if(yi == BUCKETSIZE) {
-						if(checkgc) mstats.next_gc = mstats.heap_alloc;
-						newy = runtime·cnew(t->bucket);
-						y->overflow = newy;
-						y = newy;
-						yi = 0;
-						yk = (byte*)y->data;
-						yv = yk + h->keysize * BUCKETSIZE;
-					}
-					y->tophash[yi] = top;
-					if((h->flags & IndirectKey) != 0) {
-						*(byte**)yk = *(byte**)k;
-					} else {
-						t->key->alg->copy(t->key->size, yk, k);
-					}
-					if((h->flags & IndirectValue) != 0) {
-						*(byte**)yv = *(byte**)v;
-					} else {
-						t->elem->alg->copy(t->elem->size, yv, v);
-					}
-					yi++;
-					yk += h->keysize;
-					yv += h->valuesize;
-				}
-			}
-		}
-
-		// Unlink the overflow buckets & clear key/value to help GC.
-		if((h->flags & OldIterator) == 0) {
-			b = (Bucket*)(h->oldbuckets + oldbucket * h->bucketsize);
-			b->overflow = nil;
-			runtime·memclr((byte*)b->data, h->bucketsize - offsetof(Bucket, data[0]));
-		}
-	}
-
-	// Advance evacuation mark
-	if(oldbucket == h->nevacuate) {
-		h->nevacuate = oldbucket + 1;
-		if(oldbucket + 1 == newbit) // newbit == # of oldbuckets
-			// Growing is all done.  Free old main bucket array.
-			h->oldbuckets = nil;
-	}
-	if(docheck)
-		check(t, h);
-}
-
-static void
-grow_work(MapType *t, Hmap *h, uintptr bucket)
-{
-	uintptr noldbuckets;
-
-	noldbuckets = (uintptr)1 << (h->B - 1);
-
-	// make sure we evacuate the oldbucket corresponding
-	// to the bucket we're about to use
-	evacuate(t, h, bucket & (noldbuckets - 1));
-
-	// evacuate one more oldbucket to make progress on growing
-	if(h->oldbuckets != nil)
-		evacuate(t, h, h->nevacuate);
-}
-
-static void
-hash_grow(MapType *t, Hmap *h)
-{
-	byte *old_buckets;
-	byte *new_buckets;
-	uint8 flags;
-
-	// allocate a bigger hash table
-	if(h->oldbuckets != nil)
-		runtime·throw("evacuation not done in time");
-	old_buckets = h->buckets;
-	if(checkgc) mstats.next_gc = mstats.heap_alloc;
-	new_buckets = runtime·cnewarray(t->bucket, (uintptr)1 << (h->B + 1));
-	flags = (h->flags & ~(Iterator | OldIterator));
-	if((h->flags & Iterator) != 0)
-		flags |= OldIterator;
-
-	// commit the grow (atomic wrt gc)
-	h->B++;
-	h->flags = flags;
-	h->oldbuckets = old_buckets;
-	h->buckets = new_buckets;
-	h->nevacuate = 0;
-
-	// the actual copying of the hash table data is done incrementally
-	// by grow_work() and evacuate().
-	if(docheck)
-		check(t, h);
-}
-
-// returns ptr to value associated with key *keyp, or nil if none.
-// if it returns non-nil, updates *keyp to point to the currently stored key.
-static byte*
-hash_lookup(MapType *t, Hmap *h, byte **keyp)
-{
-	void *key;
-	uintptr hash;
-	uintptr bucket, oldbucket;
-	Bucket *b;
-	uint8 top;
-	uintptr i;
-	bool eq;
-	byte *k, *k2, *v;
-
-	key = *keyp;
-	if(docheck)
-		check(t, h);
-	if(h->count == 0)
-		return nil;
-	hash = h->hash0;
-	t->key->alg->hash(&hash, t->key->size, key);
-	bucket = hash & (((uintptr)1 << h->B) - 1);
-	if(h->oldbuckets != nil) {
-		oldbucket = bucket & (((uintptr)1 << (h->B - 1)) - 1);
-		b = (Bucket*)(h->oldbuckets + oldbucket * h->bucketsize);
-		if(evacuated(b)) {
-			b = (Bucket*)(h->buckets + bucket * h->bucketsize);
-		}
-	} else {
-		b = (Bucket*)(h->buckets + bucket * h->bucketsize);
-	}
-	top = hash >> (sizeof(uintptr)*8 - 8);
-	if(top < MinTopHash)
-		top += MinTopHash;
-	do {
-		for(i = 0, k = (byte*)b->data, v = k + h->keysize * BUCKETSIZE; i < BUCKETSIZE; i++, k += h->keysize, v += h->valuesize) {
-			if(b->tophash[i] == top) {
-				k2 = IK(h, k);
-				t->key->alg->equal(&eq, t->key->size, key, k2);
-				if(eq) {
-					*keyp = k2;
-					return IV(h, v);
-				}
-			}
-		}
-		b = b->overflow;
-	} while(b != nil);
-	return nil;
-}
-
-// Specialized versions of mapaccess1 for specific types.
-// See ./hashmap_fast.c and ../../cmd/gc/walk.c.
-#define HASH_LOOKUP1 runtime·mapaccess1_fast32
-#define HASH_LOOKUP2 runtime·mapaccess2_fast32
-#define KEYTYPE uint32
-#define HASHFUNC runtime·algarray[AMEM32].hash
-#define FASTKEY(x) true
-#define QUICK_NE(x,y) ((x) != (y))
-#define QUICK_EQ(x,y) true
-#define SLOW_EQ(x,y) true
-#define MAYBE_EQ(x,y) true
-#include "hashmap_fast.c"
-
-#undef HASH_LOOKUP1
-#undef HASH_LOOKUP2
-#undef KEYTYPE
-#undef HASHFUNC
-#undef FASTKEY
-#undef QUICK_NE
-#undef QUICK_EQ
-#undef SLOW_EQ
-#undef MAYBE_EQ
-
-#define HASH_LOOKUP1 runtime·mapaccess1_fast64
-#define HASH_LOOKUP2 runtime·mapaccess2_fast64
-#define KEYTYPE uint64
-#define HASHFUNC runtime·algarray[AMEM64].hash
-#define FASTKEY(x) true
-#define QUICK_NE(x,y) ((x) != (y))
-#define QUICK_EQ(x,y) true
-#define SLOW_EQ(x,y) true
-#define MAYBE_EQ(x,y) true
-#include "hashmap_fast.c"
-
-#undef HASH_LOOKUP1
-#undef HASH_LOOKUP2
-#undef KEYTYPE
-#undef HASHFUNC
-#undef FASTKEY
-#undef QUICK_NE
-#undef QUICK_EQ
-#undef SLOW_EQ
-#undef MAYBE_EQ
-
-#ifdef GOARCH_amd64
-#define CHECKTYPE uint64
-#endif
-#ifdef GOARCH_amd64p32
-#define CHECKTYPE uint32
-#endif
-#ifdef GOARCH_386
-#define CHECKTYPE uint32
-#endif
-#ifdef GOARCH_arm
-// can't use uint32 on arm because our loads aren't aligned.
-// TODO: use uint32 for arm v6+?
-#define CHECKTYPE uint8
-#endif
-
-#define HASH_LOOKUP1 runtime·mapaccess1_faststr
-#define HASH_LOOKUP2 runtime·mapaccess2_faststr
-#define KEYTYPE String
-#define HASHFUNC runtime·algarray[ASTRING].hash
-#define FASTKEY(x) ((x).len < 32)
-#define QUICK_NE(x,y) ((x).len != (y).len)
-#define QUICK_EQ(x,y) ((x).str == (y).str)
-#define SLOW_EQ(x,y) runtime·memeq((x).str, (y).str, (x).len)
-#define MAYBE_EQ(x,y) (*(CHECKTYPE*)(x).str == *(CHECKTYPE*)(y).str && *(CHECKTYPE*)((x).str + (x).len - sizeof(CHECKTYPE)) == *(CHECKTYPE*)((y).str + (x).len - sizeof(CHECKTYPE)))
-#include "hashmap_fast.c"
-
-static void
-hash_insert(MapType *t, Hmap *h, void *key, void *value)
-{
-	uintptr hash;
-	uintptr bucket;
-	uintptr i;
-	bool eq;
-	Bucket *b;
-	Bucket *newb;
-	uint8 *inserti;
-	byte *insertk, *insertv;
-	uint8 top;
-	byte *k, *v;
-	byte *kmem, *vmem;
-
-	if(docheck)
-		check(t, h);
-	hash = h->hash0;
-	t->key->alg->hash(&hash, t->key->size, key);
-	if(h->buckets == nil)
-		h->buckets = runtime·cnewarray(t->bucket, 1);
-
- again:
-	bucket = hash & (((uintptr)1 << h->B) - 1);
-	if(h->oldbuckets != nil)
-		grow_work(t, h, bucket);
-	b = (Bucket*)(h->buckets + bucket * h->bucketsize);
-	top = hash >> (sizeof(uintptr)*8 - 8);
-	if(top < MinTopHash)
-		top += MinTopHash;
-	inserti = nil;
-	insertk = nil;
-	insertv = nil;
-	while(true) {
-		for(i = 0, k = (byte*)b->data, v = k + h->keysize * BUCKETSIZE; i < BUCKETSIZE; i++, k += h->keysize, v += h->valuesize) {
-			if(b->tophash[i] != top) {
-				if(b->tophash[i] == Empty && inserti == nil) {
-					inserti = &b->tophash[i];
-					insertk = k;
-					insertv = v;
-				}
-				continue;
-			}
-			t->key->alg->equal(&eq, t->key->size, key, IK(h, k));
-			if(!eq)
-				continue;
-			// already have a mapping for key.  Update it.
-			t->key->alg->copy(t->key->size, IK(h, k), key); // Need to update key for keys which are distinct but equal (e.g. +0.0 and -0.0)
-			t->elem->alg->copy(t->elem->size, IV(h, v), value);
-			if(docheck)
-				check(t, h);
-			return;
-		}
-		if(b->overflow == nil)
-			break;
-		b = b->overflow;
-	}
-
-	// did not find mapping for key.  Allocate new cell & add entry.
-	if(h->count >= LOAD * ((uintptr)1 << h->B) && h->count >= BUCKETSIZE) {
-		hash_grow(t, h);
-		goto again; // Growing the table invalidates everything, so try again
-	}
-
-	if(inserti == nil) {
-		// all current buckets are full, allocate a new one.
-		if(checkgc) mstats.next_gc = mstats.heap_alloc;
-		newb = runtime·cnew(t->bucket);
-		b->overflow = newb;
-		inserti = newb->tophash;
-		insertk = (byte*)newb->data;
-		insertv = insertk + h->keysize * BUCKETSIZE;
-	}
-
-	// store new key/value at insert position
-	if((h->flags & IndirectKey) != 0) {
-		if(checkgc) mstats.next_gc = mstats.heap_alloc;
-		kmem = runtime·cnew(t->key);
-		*(byte**)insertk = kmem;
-		insertk = kmem;
-	}
-	if((h->flags & IndirectValue) != 0) {
-		if(checkgc) mstats.next_gc = mstats.heap_alloc;
-		vmem = runtime·cnew(t->elem);
-		*(byte**)insertv = vmem;
-		insertv = vmem;
-	}
-	t->key->alg->copy(t->key->size, insertk, key);
-	t->elem->alg->copy(t->elem->size, insertv, value);
-	*inserti = top;
-	h->count++;
-	if(docheck)
-		check(t, h);
-}
-
-static void
-hash_remove(MapType *t, Hmap *h, void *key)
-{
-	uintptr hash;
-	uintptr bucket;
-	Bucket *b;
-	uint8 top;
-	uintptr i;
-	byte *k, *v;
-	bool eq;
-	
-	if(docheck)
-		check(t, h);
-	if(h->count == 0)
-		return;
-	hash = h->hash0;
-	t->key->alg->hash(&hash, t->key->size, key);
-	bucket = hash & (((uintptr)1 << h->B) - 1);
-	if(h->oldbuckets != nil)
-		grow_work(t, h, bucket);
-	b = (Bucket*)(h->buckets + bucket * h->bucketsize);
-	top = hash >> (sizeof(uintptr)*8 - 8);
-	if(top < MinTopHash)
-		top += MinTopHash;
-	do {
-		for(i = 0, k = (byte*)b->data, v = k + h->keysize * BUCKETSIZE; i < BUCKETSIZE; i++, k += h->keysize, v += h->valuesize) {
-			if(b->tophash[i] != top)
-				continue;
-			t->key->alg->equal(&eq, t->key->size, key, IK(h, k));
-			if(!eq)
-				continue;
-
-			if((h->flags & IndirectKey) != 0) {
-				*(byte**)k = nil;
-			} else {
-				t->key->alg->copy(t->key->size, k, nil);
-			}
-			if((h->flags & IndirectValue) != 0) {
-				*(byte**)v = nil;
-			} else {
-				t->elem->alg->copy(t->elem->size, v, nil);
-			}
-
-			b->tophash[i] = Empty;
-			h->count--;
-			
-			// TODO: consolidate buckets if they are mostly empty
-			// can only consolidate if there are no live iterators at this size.
-			if(docheck)
-				check(t, h);
-			return;
-		}
-		b = b->overflow;
-	} while(b != nil);
-}
-
-// TODO: shrink the map, the same way we grow it.
-
-// iterator state:
-// bucket: the current bucket ID
-// b: the current Bucket in the chain
-// i: the next offset to check in the current bucket
-static void
-hash_iter_init(MapType *t, Hmap *h, Hiter *it)
-{
-	uint32 old;
-
-	if(sizeof(Hiter) / sizeof(uintptr) != 10) {
-		runtime·throw("hash_iter size incorrect"); // see ../../cmd/gc/reflect.c
-	}
-	it->t = t;
-	it->h = h;
-
-	// grab snapshot of bucket state
-	it->B = h->B;
-	it->buckets = h->buckets;
-
-	// iterator state
-	it->bucket = 0;
-	it->offset = runtime·fastrand1() & (BUCKETSIZE - 1);
-	it->done = false;
-	it->bptr = nil;
-
-	// Remember we have an iterator.
-	// Can run concurrently with another hash_iter_init().
-	for(;;) {
-		old = h->flags;
-		if((old&(Iterator|OldIterator)) == (Iterator|OldIterator))
-			break;
-		if(runtime·cas(&h->flags, old, old|Iterator|OldIterator))
-			break;
-	}
-
-	if(h->buckets == nil) {
-		// Empty map. Force next hash_next to exit without
-		// evaluating h->bucket.
-		it->done = true;
-	}
-}
-
-// initializes it->key and it->value to the next key/value pair
-// in the iteration, or nil if we've reached the end.
-static void
-hash_next(Hiter *it)
-{
-	Hmap *h;
-	MapType *t;
-	uintptr bucket, oldbucket;
-	uintptr hash;
-	Bucket *b;
-	uintptr i, offi;
-	intptr check_bucket;
-	bool eq;
-	byte *k, *v;
-	byte *rk, *rv;
-
-	h = it->h;
-	t = it->t;
-	bucket = it->bucket;
-	b = it->bptr;
-	i = it->i;
-	check_bucket = it->check_bucket;
-
-next:
-	if(b == nil) {
-		if(it->done) {
-			// end of iteration
-			it->key = nil;
-			it->value = nil;
-			return;
-		}
-		if(h->oldbuckets != nil && it->B == h->B) {
-			// Iterator was started in the middle of a grow, and the grow isn't done yet.
-			// If the bucket we're looking at hasn't been filled in yet (i.e. the old
-			// bucket hasn't been evacuated) then we need to iterate through the old
-			// bucket and only return the ones that will be migrated to this bucket.
-			oldbucket = bucket & (((uintptr)1 << (it->B - 1)) - 1);
-			b = (Bucket*)(h->oldbuckets + oldbucket * h->bucketsize);
-			if(!evacuated(b)) {
-				check_bucket = bucket;
-			} else {
-				b = (Bucket*)(it->buckets + bucket * h->bucketsize);
-				check_bucket = -1;
-			}
-		} else {
-			b = (Bucket*)(it->buckets + bucket * h->bucketsize);
-			check_bucket = -1;
-		}
-		bucket++;
-		if(bucket == ((uintptr)1 << it->B)) {
-			bucket = 0;
-			it->done = true;
-		}
-		i = 0;
-	}
-	for(; i < BUCKETSIZE; i++) {
-		offi = (i + it->offset) & (BUCKETSIZE - 1);
-		k = (byte*)b->data + h->keysize * offi;
-		v = (byte*)b->data + h->keysize * BUCKETSIZE + h->valuesize * offi;
-		if(b->tophash[offi] != Empty && b->tophash[offi] != EvacuatedEmpty) {
-			if(check_bucket >= 0) {
-				// Special case: iterator was started during a grow and the
-				// grow is not done yet.  We're working on a bucket whose
-				// oldbucket has not been evacuated yet.  Or at least, it wasn't
-				// evacuated when we started the bucket.  So we're iterating
-				// through the oldbucket, skipping any keys that will go
-				// to the other new bucket (each oldbucket expands to two
-				// buckets during a grow).
-				t->key->alg->equal(&eq, t->key->size, IK(h, k), IK(h, k));
-				if(eq) {
-					// If the item in the oldbucket is not destined for
-					// the current new bucket in the iteration, skip it.
-					hash = h->hash0;
-					t->key->alg->hash(&hash, t->key->size, IK(h, k));
-					if((hash & (((uintptr)1 << it->B) - 1)) != check_bucket) {
-						continue;
-					}
-				} else {
-					// Hash isn't repeatable if k != k (NaNs).  We need a
-					// repeatable and randomish choice of which direction
-					// to send NaNs during evacuation.  We'll use the low
-					// bit of tophash to decide which way NaNs go.
-					// NOTE: this case is why we need two evacuate tophash
-					// values, evacuatedX and evacuatedY, that differ in
-					// their low bit.
-					if(check_bucket >> (it->B - 1) != (b->tophash[offi] & 1)) {
-						continue;
-					}
-				}
-			}
-			if(b->tophash[offi] != EvacuatedX && b->tophash[offi] != EvacuatedY) {
-				// this is the golden data, we can return it.
-				it->key = IK(h, k);
-				it->value = IV(h, v);
-			} else {
-				// The hash table has grown since the iterator was started.
-				// The golden data for this key is now somewhere else.
-				t->key->alg->equal(&eq, t->key->size, IK(h, k), IK(h, k));
-				if(eq) {
-					// Check the current hash table for the data.
-					// This code handles the case where the key
-					// has been deleted, updated, or deleted and reinserted.
-					// NOTE: we need to regrab the key as it has potentially been
-					// updated to an equal() but not identical key (e.g. +0.0 vs -0.0).
-					rk = IK(h, k);
-					rv = hash_lookup(t, it->h, &rk);
-					if(rv == nil)
-						continue; // key has been deleted
-					it->key = rk;
-					it->value = rv;
-				} else {
-					// if key!=key then the entry can't be deleted or
-					// updated, so we can just return it.  That's lucky for
-					// us because when key!=key we can't look it up
-					// successfully in the current table.
-					it->key = IK(h, k);
-					it->value = IV(h, v);
-				}
-			}
-			it->bucket = bucket;
-			it->bptr = b;
-			it->i = i + 1;
-			it->check_bucket = check_bucket;
-			return;
-		}
-	}
-	b = b->overflow;
-	i = 0;
-	goto next;
-}
-
-//
-/// interfaces to go runtime
-//
-
-func reflect·ismapkey(typ *Type) (ret bool) {
-	ret = typ != nil && typ->alg->hash != runtime·nohash;
-}
-
-static Hmap*
-makemap_c(MapType *typ, int64 hint)
-{
-	Hmap *h;
-	Type *key;
-
-	key = typ->key;
-	
-	if(sizeof(Hmap) > 48)
-		runtime·panicstring("hmap too large");
-
-	if(hint < 0 || (int32)hint != hint)
-		runtime·panicstring("makemap: size out of range");
-
-	if(key->alg->hash == runtime·nohash)
-		runtime·throw("runtime.makemap: unsupported map key type");
-
-	h = runtime·cnew(typ->hmap);
-	hash_init(typ, h, hint);
-
-	// these calculations are compiler dependent.
-	// figure out offsets of map call arguments.
-
-	if(debug) {
-		runtime·printf("makemap: map=%p; keysize=%p; valsize=%p; keyalg=%p; valalg=%p\n",
-			       h, key->size, typ->elem->size, key->alg, typ->elem->alg);
-	}
-
-	return h;
-}
-
-func makemap(typ *MapType, hint int64) (ret *Hmap) {
-	ret = makemap_c(typ, hint);
-}
-
-func reflect·makemap(t *MapType) (ret *Hmap) {
-	ret = makemap_c(t, 0);
-}
-
-// NOTE: The returned pointer may keep the whole map live, so don't
-// hold onto it for very long.
-#pragma textflag NOSPLIT
-func mapaccess1(t *MapType, h *Hmap, key *byte) (val *byte) {
-	if(raceenabled && h != nil) {
-		runtime·racereadpc(h, runtime·getcallerpc(&t), runtime·mapaccess1);
-		runtime·racereadobjectpc(key, t->key, runtime·getcallerpc(&t), runtime·mapaccess1);
-	}
-	if(h == nil || h->count == 0) {
-		val = t->elem->zero;
-	} else {
-		val = hash_lookup(t, h, &key);
-		if(val == nil)
-			val = t->elem->zero;
-	}
-
-	if(debug) {
-		runtime·prints("runtime.mapaccess1: map=");
-		runtime·printpointer(h);
-		runtime·prints("; key=");
-		t->key->alg->print(t->key->size, key);
-		runtime·prints("; val=");
-		t->elem->alg->print(t->elem->size, val);
-		runtime·prints("\n");
-	}
-}
-
-// NOTE: The returned pointer keeps the whole map live, so don't
-// hold onto it for very long.
-#pragma textflag NOSPLIT
-func mapaccess2(t *MapType, h *Hmap, key *byte) (val *byte, pres bool) {
-	if(raceenabled && h != nil) {
-		runtime·racereadpc(h, runtime·getcallerpc(&t), runtime·mapaccess2);
-		runtime·racereadobjectpc(key, t->key, runtime·getcallerpc(&t), runtime·mapaccess2);
-	}
-
-	if(h == nil || h->count == 0) {
-		val = t->elem->zero;
-		pres = false;
-	} else {
-		val = hash_lookup(t, h, &key);
-		if(val == nil) {
-			val = t->elem->zero;
-			pres = false;
-		} else {
-			pres = true;
-		}
-	}
-
-	if(debug) {
-		runtime·prints("runtime.mapaccess2: map=");
-		runtime·printpointer(h);
-		runtime·prints("; key=");
-		t->key->alg->print(t->key->size, key);
-		runtime·prints("; val=");
-		t->elem->alg->print(t->elem->size, val);
-		runtime·prints("; pres=");
-		runtime·printbool(pres);
-		runtime·prints("\n");
-	}
-}
-
-#pragma textflag NOSPLIT
-func reflect·mapaccess(t *MapType, h *Hmap, key *byte) (val *byte) {
-	if(h == nil)
-		val = nil;
-	else {
-		if(raceenabled) {
-			runtime·racereadpc(h, runtime·getcallerpc(&t), reflect·mapaccess);
-			runtime·racereadobjectpc(key, t->key, runtime·getcallerpc(&t), reflect·mapaccess);
-		}
-		val = hash_lookup(t, h, &key);
-	}
-}
-
-#pragma textflag NOSPLIT
-func mapassign1(t *MapType, h *Hmap, key *byte, val *byte) {
-	if(h == nil)
-		runtime·panicstring("assignment to entry in nil map");
-
-	if(raceenabled) {
-		runtime·racewritepc(h, runtime·getcallerpc(&t), runtime·mapassign1);
-		runtime·racereadobjectpc(key, t->key, runtime·getcallerpc(&t), runtime·mapassign1);
-		runtime·racereadobjectpc(val, t->elem, runtime·getcallerpc(&t), runtime·mapassign1);
-	}
-
-	hash_insert(t, h, key, val);
-
-	if(debug) {
-		runtime·prints("mapassign1: map=");
-		runtime·printpointer(h);
-		runtime·prints("; key=");
-		t->key->alg->print(t->key->size, key);
-		runtime·prints("; val=");
-		t->elem->alg->print(t->elem->size, val);
-		runtime·prints("\n");
-	}
-}
-
-#pragma textflag NOSPLIT
-func mapdelete(t *MapType, h *Hmap, key *byte) {
-	if(h == nil)
-		return;
-
-	if(raceenabled) {
-		runtime·racewritepc(h, runtime·getcallerpc(&t), runtime·mapdelete);
-		runtime·racereadobjectpc(key, t->key, runtime·getcallerpc(&t), runtime·mapdelete);
-	}
-
-	hash_remove(t, h, key);
-
-	if(debug) {
-		runtime·prints("mapdelete: map=");
-		runtime·printpointer(h);
-		runtime·prints("; key=");
-		t->key->alg->print(t->key->size, key);
-		runtime·prints("\n");
-	}
-}
-
-#pragma textflag NOSPLIT
-func reflect·mapassign(t *MapType, h *Hmap, key *byte, val *byte) {
-	if(h == nil)
-		runtime·panicstring("assignment to entry in nil map");
-	if(raceenabled) {
-		runtime·racewritepc(h, runtime·getcallerpc(&t), reflect·mapassign);
-		runtime·racereadobjectpc(key, t->key, runtime·getcallerpc(&t), reflect·mapassign);
-		runtime·racereadobjectpc(val, t->elem, runtime·getcallerpc(&t), reflect·mapassign);
-	}
-
-	hash_insert(t, h, key, val);
-
-	if(debug) {
-		runtime·prints("mapassign: map=");
-		runtime·printpointer(h);
-		runtime·prints("; key=");
-		t->key->alg->print(t->key->size, key);
-		runtime·prints("; val=");
-		t->elem->alg->print(t->elem->size, val);
-		runtime·prints("\n");
-	}
-}
-
-#pragma textflag NOSPLIT
-func reflect·mapdelete(t *MapType, h *Hmap, key *byte) {
-	if(h == nil)
-		return; // see bug 8051
-	if(raceenabled) {
-		runtime·racewritepc(h, runtime·getcallerpc(&t), reflect·mapdelete);
-		runtime·racereadobjectpc(key, t->key, runtime·getcallerpc(&t), reflect·mapdelete);
-	}
-	hash_remove(t, h, key);
-
-	if(debug) {
-		runtime·prints("mapdelete: map=");
-		runtime·printpointer(h);
-		runtime·prints("; key=");
-		t->key->alg->print(t->key->size, key);
-		runtime·prints("\n");
-	}
-}
-
-#pragma textflag NOSPLIT
-func mapiterinit(t *MapType, h *Hmap, it *Hiter) {
-	// Clear pointer fields so garbage collector does not complain.
-	it->key = nil;
-	it->value = nil;
-	it->t = nil;
-	it->h = nil;
-	it->buckets = nil;
-	it->bptr = nil;
-
-	if(h == nil || h->count == 0) {
-		it->key = nil;
-		return;
-	}
-	if(raceenabled)
-		runtime·racereadpc(h, runtime·getcallerpc(&t), runtime·mapiterinit);
-	hash_iter_init(t, h, it);
-	hash_next(it);
-	if(debug) {
-		runtime·prints("runtime.mapiterinit: map=");
-		runtime·printpointer(h);
-		runtime·prints("; iter=");
-		runtime·printpointer(it);
-		runtime·prints("; key=");
-		runtime·printpointer(it->key);
-		runtime·prints("\n");
-	}
-}
-
-func reflect·mapiterinit(t *MapType, h *Hmap) (it *Hiter) {
-	it = runtime·mal(sizeof *it);
-	runtime·mapiterinit(t, h, it);
-}
-
-#pragma textflag NOSPLIT
-func mapiternext(it *Hiter) {
-	if(raceenabled)
-		runtime·racereadpc(it->h, runtime·getcallerpc(&it), runtime·mapiternext);
-
-	hash_next(it);
-	if(debug) {
-		runtime·prints("runtime.mapiternext: iter=");
-		runtime·printpointer(it);
-		runtime·prints("; key=");
-		runtime·printpointer(it->key);
-		runtime·prints("\n");
-	}
-}
-
-func reflect·mapiternext(it *Hiter) {
-	runtime·mapiternext(it);
-}
-
-func reflect·mapiterkey(it *Hiter) (key *byte) {
-	key = it->key;
-}
-
-#pragma textflag NOSPLIT
-func reflect·maplen(h *Hmap) (len int) {
-	if(h == nil)
-		len = 0;
-	else {
-		len = h->count;
-		if(raceenabled)
-			runtime·racereadpc(h, runtime·getcallerpc(&h), reflect·maplen);
-	}
-}
-
-// exported value for testing
-float64 runtime·hashLoad = LOAD;
diff --git a/src/pkg/runtime/hashmap.h b/src/pkg/runtime/hashmap.h
deleted file mode 100644
index 522d1ad..0000000
--- a/src/pkg/runtime/hashmap.h
+++ /dev/null
@@ -1,147 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// This file contains the implementation of Go's map type.
-//
-// The map is just a hash table.  The data is arranged
-// into an array of buckets.  Each bucket contains up to
-// 8 key/value pairs.  The low-order bits of the hash are
-// used to select a bucket.  Each bucket contains a few
-// high-order bits of each hash to distinguish the entries
-// within a single bucket.
-//
-// If more than 8 keys hash to a bucket, we chain on
-// extra buckets.
-//
-// When the hashtable grows, we allocate a new array
-// of buckets twice as big.  Buckets are incrementally
-// copied from the old bucket array to the new bucket array.
-//
-// Map iterators walk through the array of buckets and
-// return the keys in walk order (bucket #, then overflow
-// chain order, then bucket index).  To maintain iteration
-// semantics, we never move keys within their bucket (if
-// we did, keys might be returned 0 or 2 times).  When
-// growing the table, iterators remain iterating through the
-// old table and must check the new table if the bucket
-// they are iterating through has been moved ("evacuated")
-// to the new table.
-
-// Maximum number of key/value pairs a bucket can hold.
-#define BUCKETSIZE 8
-
-// Maximum average load of a bucket that triggers growth.
-#define LOAD 6.5
-
-// Picking LOAD: too large and we have lots of overflow
-// buckets, too small and we waste a lot of space.  I wrote
-// a simple program to check some stats for different loads:
-// (64-bit, 8 byte keys and values)
-//        LOAD    %overflow  bytes/entry     hitprobe    missprobe
-//        4.00         2.13        20.77         3.00         4.00
-//        4.50         4.05        17.30         3.25         4.50
-//        5.00         6.85        14.77         3.50         5.00
-//        5.50        10.55        12.94         3.75         5.50
-//        6.00        15.27        11.67         4.00         6.00
-//        6.50        20.90        10.79         4.25         6.50
-//        7.00        27.14        10.15         4.50         7.00
-//        7.50        34.03         9.73         4.75         7.50
-//        8.00        41.10         9.40         5.00         8.00
-//
-// %overflow   = percentage of buckets which have an overflow bucket
-// bytes/entry = overhead bytes used per key/value pair
-// hitprobe    = # of entries to check when looking up a present key
-// missprobe   = # of entries to check when looking up an absent key
-//
-// Keep in mind this data is for maximally loaded tables, i.e. just
-// before the table grows.  Typical tables will be somewhat less loaded.
-
-// Maximum key or value size to keep inline (instead of mallocing per element).
-// Must fit in a uint8.
-// Fast versions cannot handle big values - the cutoff size for
-// fast versions in ../../cmd/gc/walk.c must be at most this value.
-#define MAXKEYSIZE 128
-#define MAXVALUESIZE 128
-
-typedef struct Bucket Bucket;
-struct Bucket
-{
-	// Note: the format of the Bucket is encoded in ../../cmd/gc/reflect.c and
-	// ../reflect/type.go.  Don't change this structure without also changing that code!
-	uint8  tophash[BUCKETSIZE]; // top 8 bits of hash of each entry (or special mark below)
-	Bucket *overflow;           // overflow bucket, if any
-	uint64 data[1];             // BUCKETSIZE keys followed by BUCKETSIZE values
-};
-// NOTE: packing all the keys together and then all the values together makes the
-// code a bit more complicated than alternating key/value/key/value/... but it allows
-// us to eliminate padding which would be needed for, e.g., map[int64]int8.
-
-// tophash values.  We reserve a few possibilities for special marks.
-// Each bucket (including its overflow buckets, if any) will have either all or none of its
-// entries in the Evacuated* states (except during the evacuate() method, which only happens
-// during map writes and thus no one else can observe the map during that time).
-enum
-{
-	Empty = 0,		// cell is empty
-	EvacuatedEmpty = 1,	// cell is empty, bucket is evacuated.
-	EvacuatedX = 2,		// key/value is valid.  Entry has been evacuated to first half of larger table.
-	EvacuatedY = 3,		// same as above, but evacuated to second half of larger table.
-	MinTopHash = 4, 	// minimum tophash for a normal filled cell.
-};
-#define evacuated(b) ((b)->tophash[0] > Empty && (b)->tophash[0] < MinTopHash)
-
-struct Hmap
-{
-	// Note: the format of the Hmap is encoded in ../../cmd/gc/reflect.c and
-	// ../reflect/type.go.  Don't change this structure without also changing that code!
-	uintgo  count;        // # live cells == size of map.  Must be first (used by len() builtin)
-	uint32  flags;
-	uint32  hash0;        // hash seed
-	uint8   B;            // log_2 of # of buckets (can hold up to LOAD * 2^B items)
-	uint8   keysize;      // key size in bytes
-	uint8   valuesize;    // value size in bytes
-	uint16  bucketsize;   // bucket size in bytes
-
-	byte    *buckets;     // array of 2^B Buckets. may be nil if count==0.
-	byte    *oldbuckets;  // previous bucket array of half the size, non-nil only when growing
-	uintptr nevacuate;    // progress counter for evacuation (buckets less than this have been evacuated)
-};
-
-// possible flags
-enum
-{
-	IndirectKey = 1,    // storing pointers to keys
-	IndirectValue = 2,  // storing pointers to values
-	Iterator = 4,       // there may be an iterator using buckets
-	OldIterator = 8,    // there may be an iterator using oldbuckets
-};
-
-// Macros for dereferencing indirect keys
-#define IK(h, p) (((h)->flags & IndirectKey) != 0 ? *(byte**)(p) : (p))
-#define IV(h, p) (((h)->flags & IndirectValue) != 0 ? *(byte**)(p) : (p))
-
-// If you modify Hiter, also change cmd/gc/reflect.c to indicate
-// the layout of this structure.
-struct Hiter
-{
-	uint8* key; // Must be in first position.  Write nil to indicate iteration end (see cmd/gc/range.c).
-	uint8* value; // Must be in second position (see cmd/gc/range.c).
-
-	MapType *t;
-	Hmap *h;
-	byte *buckets; // bucket ptr at hash_iter initialization time
-	struct Bucket *bptr; // current bucket
-
-	uint8 offset; // intra-bucket offset to start from during iteration (should be big enough to hold BUCKETSIZE-1)
-	bool done;
-
-	// state of table at time iterator is initialized
-	uint8 B;
-
-	// iter state
-	uintptr bucket;
-	uintptr i;
-	intptr check_bucket;
-};
-
diff --git a/src/pkg/runtime/hashmap_fast.c b/src/pkg/runtime/hashmap_fast.c
deleted file mode 100644
index 83bf6fe..0000000
--- a/src/pkg/runtime/hashmap_fast.c
+++ /dev/null
@@ -1,233 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Fast hashmap lookup specialized to a specific key type.
-// Included by hashmap.c once for each specialized type.
-
-// +build ignore
-
-// Because this file is #included, it cannot be processed by goc2c,
-// so we have to handle the Go resuts ourselves.
-
-#pragma textflag NOSPLIT
-void
-HASH_LOOKUP1(MapType *t, Hmap *h, KEYTYPE key, GoOutput base, ...)
-{
-	uintptr bucket, i;
-	Bucket *b;
-	KEYTYPE *k;
-	byte *v, **valueptr;
-	uint8 top;
-	int8 keymaybe;
-
-	valueptr = (byte**)&base;
-	if(debug) {
-		runtime·prints("runtime.mapaccess1_fastXXX: map=");
-		runtime·printpointer(h);
-		runtime·prints("; key=");
-		t->key->alg->print(t->key->size, &key);
-		runtime·prints("\n");
-	}
-	if(h == nil || h->count == 0) {
-		*valueptr = t->elem->zero;
-		return;
-	}
-	if(raceenabled)
-		runtime·racereadpc(h, runtime·getcallerpc(&t), HASH_LOOKUP1);
-	if(docheck)
-		check(t, h);
-
-	if(h->B == 0) {
-		// One-bucket table. Don't hash, just check each bucket entry.
-		b = (Bucket*)h->buckets;
-		if(FASTKEY(key)) {
-			for(i = 0, k = (KEYTYPE*)b->data, v = (byte*)(k + BUCKETSIZE); i < BUCKETSIZE; i++, k++, v += h->valuesize) {
-				if(b->tophash[i] == Empty)
-					continue;
-				if(QUICK_NE(key, *k))
-					continue;
-				if(QUICK_EQ(key, *k) || SLOW_EQ(key, *k)) {
-					*valueptr = v;
-					return;
-				}
-			}
-		} else {
-			keymaybe = -1;
-			for(i = 0, k = (KEYTYPE*)b->data, v = (byte*)(k + BUCKETSIZE); i < BUCKETSIZE; i++, k++, v += h->valuesize) {
-				if(b->tophash[i] == Empty)
-					continue;
-				if(QUICK_NE(key, *k))
-					continue;
-				if(QUICK_EQ(key, *k)) {
-					*valueptr = v;
-					return;
-				}
-				if(MAYBE_EQ(key, *k)) {
-					if(keymaybe >= 0) {
-						// Two same-length strings in this bucket.
-						// use slow path.
-						// TODO: keep track of more than just 1.  We could
-						// afford about 3 equals calls before it would be more
-						// expensive than 1 hash + 1 equals.
-						goto dohash;
-					}
-					keymaybe = i;
-				}
-			}
-			if(keymaybe >= 0) {
-				k = (KEYTYPE*)b->data + keymaybe;
-				if(SLOW_EQ(key, *k)) {
-					*valueptr = (byte*)((KEYTYPE*)b->data + BUCKETSIZE) + keymaybe * h->valuesize;
-					return;
-				}
-			}
-		}
-	} else {
-dohash:
-		bucket = h->hash0;
-		HASHFUNC(&bucket, sizeof(KEYTYPE), &key);
-		top = bucket >> (sizeof(uintptr)*8 - 8);
-		if(top < MinTopHash)
-			top += MinTopHash;
-		bucket &= (((uintptr)1 << h->B) - 1);
-		if(h->oldbuckets != nil) {
-			i = bucket & (((uintptr)1 << (h->B - 1)) - 1);
-			b = (Bucket*)(h->oldbuckets + i * h->bucketsize);
-			if(evacuated(b)) {
-				b = (Bucket*)(h->buckets + bucket * h->bucketsize);
-			}
-		} else {
-			b = (Bucket*)(h->buckets + bucket * h->bucketsize);
-		}
-		do {
-			for(i = 0, k = (KEYTYPE*)b->data, v = (byte*)(k + BUCKETSIZE); i < BUCKETSIZE; i++, k++, v += h->valuesize) {
-				if(b->tophash[i] != top)
-					continue;
-				if(QUICK_NE(key, *k))
-					continue;
-				if(QUICK_EQ(key, *k) || SLOW_EQ(key, *k)) {
-					*valueptr = v;
-					return;
-				}
-			}
-			b = b->overflow;
-		} while(b != nil);
-	}
-	*valueptr = t->elem->zero;
-}
-
-#pragma textflag NOSPLIT
-void
-HASH_LOOKUP2(MapType *t, Hmap *h, KEYTYPE key, GoOutput base, ...)
-{
-	uintptr bucket, i;
-	Bucket *b;
-	KEYTYPE *k;
-	byte *v, **valueptr;
-	uint8 top;
-	int8 keymaybe;
-	bool *okptr;
-
-	valueptr = (byte**)&base;
-	okptr = (bool*)(valueptr+1);
-	if(debug) {
-		runtime·prints("runtime.mapaccess2_fastXXX: map=");
-		runtime·printpointer(h);
-		runtime·prints("; key=");
-		t->key->alg->print(t->key->size, &key);
-		runtime·prints("\n");
-	}
-	if(h == nil || h->count == 0) {
-		*valueptr = t->elem->zero;
-		*okptr = false;
-		return;
-	}
-	if(raceenabled)
-		runtime·racereadpc(h, runtime·getcallerpc(&t), HASH_LOOKUP2);
-	if(docheck)
-		check(t, h);
-
-	if(h->B == 0) {
-		// One-bucket table. Don't hash, just check each bucket entry.
-		b = (Bucket*)h->buckets;
-		if(FASTKEY(key)) {
-			for(i = 0, k = (KEYTYPE*)b->data, v = (byte*)(k + BUCKETSIZE); i < BUCKETSIZE; i++, k++, v += h->valuesize) {
-				if(b->tophash[i] == Empty)
-					continue;
-				if(QUICK_NE(key, *k))
-					continue;
-				if(QUICK_EQ(key, *k) || SLOW_EQ(key, *k)) {
-					*valueptr = v;
-					*okptr = true;
-					return;
-				}
-			}
-		} else {
-			keymaybe = -1;
-			for(i = 0, k = (KEYTYPE*)b->data, v = (byte*)(k + BUCKETSIZE); i < BUCKETSIZE; i++, k++, v += h->valuesize) {
-				if(b->tophash[i] == Empty)
-					continue;
-				if(QUICK_NE(key, *k))
-					continue;
-				if(QUICK_EQ(key, *k)) {
-					*valueptr = v;
-					*okptr = true;
-					return;
-				}
-				if(MAYBE_EQ(key, *k)) {
-					if(keymaybe >= 0) {
-						// Two same-length strings in this bucket.
-						// use slow path.
-						// TODO: keep track of more than just 1.  We could
-						// afford about 3 equals calls before it would be more
-						// expensive than 1 hash + 1 equals.
-						goto dohash;
-					}
-					keymaybe = i;
-				}
-			}
-			if(keymaybe >= 0) {
-				k = (KEYTYPE*)b->data + keymaybe;
-				if(SLOW_EQ(key, *k)) {
-					*valueptr = (byte*)((KEYTYPE*)b->data + BUCKETSIZE) + keymaybe * h->valuesize;
-					*okptr = true;
-					return;
-				}
-			}
-		}
-	} else {
-dohash:
-		bucket = h->hash0;
-		HASHFUNC(&bucket, sizeof(KEYTYPE), &key);
-		top = bucket >> (sizeof(uintptr)*8 - 8);
-		if(top < MinTopHash)
-			top += MinTopHash;
-		bucket &= (((uintptr)1 << h->B) - 1);
-		if(h->oldbuckets != nil) {
-			i = bucket & (((uintptr)1 << (h->B - 1)) - 1);
-			b = (Bucket*)(h->oldbuckets + i * h->bucketsize);
-			if(evacuated(b)) {
-				b = (Bucket*)(h->buckets + bucket * h->bucketsize);
-			}
-		} else {
-			b = (Bucket*)(h->buckets + bucket * h->bucketsize);
-		}
-		do {
-			for(i = 0, k = (KEYTYPE*)b->data, v = (byte*)(k + BUCKETSIZE); i < BUCKETSIZE; i++, k++, v += h->valuesize) {
-				if(b->tophash[i] != top)
-					continue;
-				if(QUICK_NE(key, *k))
-					continue;
-				if(QUICK_EQ(key, *k) || SLOW_EQ(key, *k)) {
-					*valueptr = v;
-					*okptr = true;
-					return;
-				}
-			}
-			b = b->overflow;
-		} while(b != nil);
-	}
-	*valueptr = t->elem->zero;
-	*okptr = false;
-}
diff --git a/src/pkg/runtime/heapdump.c b/src/pkg/runtime/heapdump.c
deleted file mode 100644
index 744c59f..0000000
--- a/src/pkg/runtime/heapdump.c
+++ /dev/null
@@ -1,981 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Implementation of runtime/debug.WriteHeapDump.  Writes all
-// objects in the heap plus additional info (roots, threads,
-// finalizers, etc.) to a file.
-
-// The format of the dumped file is described at
-// http://code.google.com/p/go-wiki/wiki/heapdump13
-
-#include "runtime.h"
-#include "arch_GOARCH.h"
-#include "malloc.h"
-#include "mgc0.h"
-#include "type.h"
-#include "typekind.h"
-#include "funcdata.h"
-#include "zaexperiment.h"
-#include "../../cmd/ld/textflag.h"
-
-extern byte data[];
-extern byte edata[];
-extern byte bss[];
-extern byte ebss[];
-extern byte gcdata[];
-extern byte gcbss[];
-
-enum {
-	FieldKindEol = 0,
-	FieldKindPtr = 1,
-	FieldKindString = 2,
-	FieldKindSlice = 3,
-	FieldKindIface = 4,
-	FieldKindEface = 5,
-
-	TagEOF = 0,
-	TagObject = 1,
-	TagOtherRoot = 2,
-	TagType = 3,
-	TagGoRoutine = 4,
-	TagStackFrame = 5,
-	TagParams = 6,
-	TagFinalizer = 7,
-	TagItab = 8,
-	TagOSThread = 9,
-	TagMemStats = 10,
-	TagQueuedFinalizer = 11,
-	TagData = 12,
-	TagBss = 13,
-	TagDefer = 14,
-	TagPanic = 15,
-	TagMemProf = 16,
-	TagAllocSample = 17,
-
-	TypeInfo_Conservative = 127,
-};
-
-static uintptr* playgcprog(uintptr offset, uintptr *prog, void (*callback)(void*,uintptr,uintptr), void *arg);
-static void dumpfields(uintptr *prog);
-static void dumpefacetypes(void *obj, uintptr size, Type *type, uintptr kind);
-static void dumpbvtypes(BitVector *bv, byte *base);
-
-// fd to write the dump to.
-static uintptr dumpfd;
-
-// buffer of pending write data
-enum {
-	BufSize = 4096,
-};
-#pragma dataflag NOPTR
-static byte buf[BufSize];
-static uintptr nbuf;
-
-static void
-write(byte *data, uintptr len)
-{
-	if(len + nbuf <= BufSize) {
-		runtime·memmove(buf + nbuf, data, len);
-		nbuf += len;
-		return;
-	}
-	runtime·write(dumpfd, buf, nbuf);
-	if(len >= BufSize) {
-		runtime·write(dumpfd, data, len);
-		nbuf = 0;
-	} else {
-		runtime·memmove(buf, data, len);
-		nbuf = len;
-	}
-}
-
-static void
-flush(void)
-{
-	runtime·write(dumpfd, buf, nbuf);
-	nbuf = 0;
-}
-
-// Cache of types that have been serialized already.
-// We use a type's hash field to pick a bucket.
-// Inside a bucket, we keep a list of types that
-// have been serialized so far, most recently used first.
-// Note: when a bucket overflows we may end up
-// serializing a type more than once.  That's ok.
-enum {
-	TypeCacheBuckets = 256, // must be a power of 2
-	TypeCacheAssoc = 4,
-};
-typedef struct TypeCacheBucket TypeCacheBucket;
-struct TypeCacheBucket {
-	Type *t[TypeCacheAssoc];
-};
-static TypeCacheBucket typecache[TypeCacheBuckets];
-
-// dump a uint64 in a varint format parseable by encoding/binary
-static void
-dumpint(uint64 v)
-{
-	byte buf[10];
-	int32 n;
-	n = 0;
-	while(v >= 0x80) {
-		buf[n++] = v | 0x80;
-		v >>= 7;
-	}
-	buf[n++] = v;
-	write(buf, n);
-}
-
-static void
-dumpbool(bool b)
-{
-	dumpint(b ? 1 : 0);
-}
-
-// dump varint uint64 length followed by memory contents
-static void
-dumpmemrange(byte *data, uintptr len)
-{
-	dumpint(len);
-	write(data, len);
-}
-
-static void
-dumpstr(String s)
-{
-	dumpmemrange(s.str, s.len);
-}
-
-static void
-dumpcstr(int8 *c)
-{
-	dumpmemrange((byte*)c, runtime·findnull((byte*)c));
-}
-
-// dump information for a type
-static void
-dumptype(Type *t)
-{
-	TypeCacheBucket *b;
-	int32 i, j;
-
-	if(t == nil) {
-		return;
-	}
-
-	// If we've definitely serialized the type before,
-	// no need to do it again.
-	b = &typecache[t->hash & (TypeCacheBuckets-1)];
-	if(t == b->t[0]) return;
-	for(i = 1; i < TypeCacheAssoc; i++) {
-		if(t == b->t[i]) {
-			// Move-to-front
-			for(j = i; j > 0; j--) {
-				b->t[j] = b->t[j-1];
-			}
-			b->t[0] = t;
-			return;
-		}
-	}
-	// Might not have been dumped yet.  Dump it and
-	// remember we did so.
-	for(j = TypeCacheAssoc-1; j > 0; j--) {
-		b->t[j] = b->t[j-1];
-	}
-	b->t[0] = t;
-	
-	// dump the type
-	dumpint(TagType);
-	dumpint((uintptr)t);
-	dumpint(t->size);
-	if(t->x == nil || t->x->pkgPath == nil || t->x->name == nil) {
-		dumpstr(*t->string);
-	} else {
-		dumpint(t->x->pkgPath->len + 1 + t->x->name->len);
-		write(t->x->pkgPath->str, t->x->pkgPath->len);
-		write((byte*)".", 1);
-		write(t->x->name->str, t->x->name->len);
-	}
-	dumpbool(t->size > PtrSize || (t->kind & KindNoPointers) == 0);
-	dumpfields((uintptr*)t->gc + 1);
-}
-
-// returns true if object is scannable
-static bool
-scannable(byte *obj)
-{
-	uintptr *b, off, shift;
-
-	off = (uintptr*)obj - (uintptr*)runtime·mheap.arena_start;  // word offset
-	b = (uintptr*)runtime·mheap.arena_start - off/wordsPerBitmapWord - 1;
-	shift = off % wordsPerBitmapWord;
-	return ((*b >> shift) & bitScan) != 0;
-}
-
-// dump an object
-static void
-dumpobj(byte *obj, uintptr size, Type *type, uintptr kind)
-{
-	if(type != nil) {
-		dumptype(type);
-		dumpefacetypes(obj, size, type, kind);
-	}
-
-	dumpint(TagObject);
-	dumpint((uintptr)obj);
-	dumpint((uintptr)type);
-	dumpint(kind);
-	dumpmemrange(obj, size);
-}
-
-static void
-dumpotherroot(int8 *description, byte *to)
-{
-	dumpint(TagOtherRoot);
-	dumpcstr(description);
-	dumpint((uintptr)to);
-}
-
-static void
-dumpfinalizer(byte *obj, FuncVal *fn, Type* fint, PtrType *ot)
-{
-	dumpint(TagFinalizer);
-	dumpint((uintptr)obj);
-	dumpint((uintptr)fn);
-	dumpint((uintptr)fn->fn);
-	dumpint((uintptr)fint);
-	dumpint((uintptr)ot);
-}
-
-typedef struct ChildInfo ChildInfo;
-struct ChildInfo {
-	// Information passed up from the callee frame about
-	// the layout of the outargs region.
-	uintptr argoff;     // where the arguments start in the frame
-	uintptr arglen;     // size of args region
-	BitVector args;    // if args.n >= 0, pointer map of args region
-
-	byte *sp;           // callee sp
-	uintptr depth;      // depth in call stack (0 == most recent)
-};
-
-// dump kinds & offsets of interesting fields in bv
-static void
-dumpbv(BitVector *bv, uintptr offset)
-{
-	uintptr i;
-
-	for(i = 0; i < bv->n; i += BitsPerPointer) {
-		switch(bv->data[i/32] >> i%32 & 3) {
-		case BitsDead:
-		case BitsScalar:
-			break;
-		case BitsPointer:
-			dumpint(FieldKindPtr);
-			dumpint(offset + i / BitsPerPointer * PtrSize);
-			break;
-		case BitsMultiWord:
-			switch(bv->data[(i+BitsPerPointer)/32] >> (i+BitsPerPointer)%32 & 3) {
-			case BitsString:
-				dumpint(FieldKindString);
-				dumpint(offset + i / BitsPerPointer * PtrSize);
-				i += BitsPerPointer;
-				break;
-			case BitsSlice:
-				dumpint(FieldKindSlice);
-				dumpint(offset + i / BitsPerPointer * PtrSize);
-				i += 2 * BitsPerPointer;
-				break;
-			case BitsIface:
-				dumpint(FieldKindIface);
-				dumpint(offset + i / BitsPerPointer * PtrSize);
-				i += BitsPerPointer;
-				break;
-			case BitsEface:
-				dumpint(FieldKindEface);
-				dumpint(offset + i / BitsPerPointer * PtrSize);
-				i += BitsPerPointer;
-				break;
-			}
-		}
-	}
-}
-
-static bool
-dumpframe(Stkframe *s, void *arg)
-{
-	Func *f;
-	ChildInfo *child;
-	uintptr pc, off, size;
-	int32 pcdata;
-	StackMap *stackmap;
-	int8 *name;
-	BitVector bv;
-
-	child = (ChildInfo*)arg;
-	f = s->fn;
-
-	// Figure out what we can about our stack map
-	pc = s->pc;
-	if(pc != f->entry)
-		pc--;
-	pcdata = runtime·pcdatavalue(f, PCDATA_StackMapIndex, pc);
-	if(pcdata == -1) {
-		// We do not have a valid pcdata value but there might be a
-		// stackmap for this function.  It is likely that we are looking
-		// at the function prologue, assume so and hope for the best.
-		pcdata = 0;
-	}
-	stackmap = runtime·funcdata(f, FUNCDATA_LocalsPointerMaps);
-
-	// Dump any types we will need to resolve Efaces.
-	if(child->args.n >= 0)
-		dumpbvtypes(&child->args, (byte*)s->sp + child->argoff);
-	if(stackmap != nil && stackmap->n > 0) {
-		bv = runtime·stackmapdata(stackmap, pcdata);
-		dumpbvtypes(&bv, s->varp - bv.n / BitsPerPointer * PtrSize);
-	} else {
-		bv.n = -1;
-	}
-
-	// Dump main body of stack frame.
-	dumpint(TagStackFrame);
-	dumpint(s->sp); // lowest address in frame
-	dumpint(child->depth); // # of frames deep on the stack
-	dumpint((uintptr)child->sp); // sp of child, or 0 if bottom of stack
-	dumpmemrange((byte*)s->sp, s->fp - s->sp);  // frame contents
-	dumpint(f->entry);
-	dumpint(s->pc);
-	dumpint(s->continpc);
-	name = runtime·funcname(f);
-	if(name == nil)
-		name = "unknown function";
-	dumpcstr(name);
-
-	// Dump fields in the outargs section
-	if(child->args.n >= 0) {
-		dumpbv(&child->args, child->argoff);
-	} else {
-		// conservative - everything might be a pointer
-		for(off = child->argoff; off < child->argoff + child->arglen; off += PtrSize) {
-			dumpint(FieldKindPtr);
-			dumpint(off);
-		}
-	}
-
-	// Dump fields in the local vars section
-	if(stackmap == nil) {
-		// No locals information, dump everything.
-		for(off = child->arglen; off < s->varp - (byte*)s->sp; off += PtrSize) {
-			dumpint(FieldKindPtr);
-			dumpint(off);
-		}
-	} else if(stackmap->n < 0) {
-		// Locals size information, dump just the locals.
-		size = -stackmap->n;
-		for(off = s->varp - size - (byte*)s->sp; off < s->varp - (byte*)s->sp; off += PtrSize) {
-			dumpint(FieldKindPtr);
-			dumpint(off);
-		}
-	} else if(stackmap->n > 0) {
-		// Locals bitmap information, scan just the pointers in
-		// locals.
-		dumpbv(&bv, s->varp - bv.n / BitsPerPointer * PtrSize - (byte*)s->sp);
-	}
-	dumpint(FieldKindEol);
-
-	// Record arg info for parent.
-	child->argoff = s->argp - (byte*)s->fp;
-	child->arglen = s->arglen;
-	child->sp = (byte*)s->sp;
-	child->depth++;
-	stackmap = runtime·funcdata(f, FUNCDATA_ArgsPointerMaps);
-	if(stackmap != nil)
-		child->args = runtime·stackmapdata(stackmap, pcdata);
-	else
-		child->args.n = -1;
-	return true;
-}
-
-static void
-dumpgoroutine(G *gp)
-{
-	uintptr sp, pc, lr;
-	ChildInfo child;
-	Defer *d;
-	Panic *p;
-
-	if(gp->syscallstack != (uintptr)nil) {
-		sp = gp->syscallsp;
-		pc = gp->syscallpc;
-		lr = 0;
-	} else {
-		sp = gp->sched.sp;
-		pc = gp->sched.pc;
-		lr = gp->sched.lr;
-	}
-
-	dumpint(TagGoRoutine);
-	dumpint((uintptr)gp);
-	dumpint((uintptr)sp);
-	dumpint(gp->goid);
-	dumpint(gp->gopc);
-	dumpint(gp->status);
-	dumpbool(gp->issystem);
-	dumpbool(gp->isbackground);
-	dumpint(gp->waitsince);
-	dumpcstr(gp->waitreason);
-	dumpint((uintptr)gp->sched.ctxt);
-	dumpint((uintptr)gp->m);
-	dumpint((uintptr)gp->defer);
-	dumpint((uintptr)gp->panic);
-
-	// dump stack
-	child.args.n = -1;
-	child.arglen = 0;
-	child.sp = nil;
-	child.depth = 0;
-	if(!ScanStackByFrames)
-		runtime·throw("need frame info to dump stacks");
-	runtime·gentraceback(pc, sp, lr, gp, 0, nil, 0x7fffffff, dumpframe, &child, false);
-
-	// dump defer & panic records
-	for(d = gp->defer; d != nil; d = d->link) {
-		dumpint(TagDefer);
-		dumpint((uintptr)d);
-		dumpint((uintptr)gp);
-		dumpint((uintptr)d->argp);
-		dumpint((uintptr)d->pc);
-		dumpint((uintptr)d->fn);
-		dumpint((uintptr)d->fn->fn);
-		dumpint((uintptr)d->link);
-	}
-	for (p = gp->panic; p != nil; p = p->link) {
-		dumpint(TagPanic);
-		dumpint((uintptr)p);
-		dumpint((uintptr)gp);
-		dumpint((uintptr)p->arg.type);
-		dumpint((uintptr)p->arg.data);
-		dumpint((uintptr)p->defer);
-		dumpint((uintptr)p->link);
-	}
-}
-
-static void
-dumpgs(void)
-{
-	G *gp;
-	uint32 i;
-
-	// goroutines & stacks
-	for(i = 0; i < runtime·allglen; i++) {
-		gp = runtime·allg[i];
-		switch(gp->status){
-		default:
-			runtime·printf("unexpected G.status %d\n", gp->status);
-			runtime·throw("mark - bad status");
-		case Gdead:
-			break;
-		case Grunnable:
-		case Gsyscall:
-		case Gwaiting:
-			dumpgoroutine(gp);
-			break;
-		}
-	}
-}
-
-static void
-finq_callback(FuncVal *fn, byte *obj, uintptr nret, Type *fint, PtrType *ot)
-{
-	dumpint(TagQueuedFinalizer);
-	dumpint((uintptr)obj);
-	dumpint((uintptr)fn);
-	dumpint((uintptr)fn->fn);
-	dumpint((uintptr)fint);
-	dumpint((uintptr)ot);
-	USED(&nret);
-}
-
-
-static void
-dumproots(void)
-{
-	MSpan *s, **allspans;
-	uint32 spanidx;
-	Special *sp;
-	SpecialFinalizer *spf;
-	byte *p;
-
-	// data segment
-	dumpint(TagData);
-	dumpint((uintptr)data);
-	dumpmemrange(data, edata - data);
-	dumpfields((uintptr*)gcdata + 1);
-
-	// bss segment
-	dumpint(TagBss);
-	dumpint((uintptr)bss);
-	dumpmemrange(bss, ebss - bss);
-	dumpfields((uintptr*)gcbss + 1);
-	
-	// MSpan.types
-	allspans = runtime·mheap.allspans;
-	for(spanidx=0; spanidx<runtime·mheap.nspan; spanidx++) {
-		s = allspans[spanidx];
-		if(s->state == MSpanInUse) {
-			// The garbage collector ignores type pointers stored in MSpan.types:
-			//  - Compiler-generated types are stored outside of heap.
-			//  - The reflect package has runtime-generated types cached in its data structures.
-			//    The garbage collector relies on finding the references via that cache.
-			switch(s->types.compression) {
-			case MTypes_Empty:
-			case MTypes_Single:
-				break;
-			case MTypes_Words:
-			case MTypes_Bytes:
-				dumpotherroot("runtime type info", (byte*)s->types.data);
-				break;
-			}
-
-			// Finalizers
-			for(sp = s->specials; sp != nil; sp = sp->next) {
-				if(sp->kind != KindSpecialFinalizer)
-					continue;
-				spf = (SpecialFinalizer*)sp;
-				p = (byte*)((s->start << PageShift) + spf->offset);
-				dumpfinalizer(p, spf->fn, spf->fint, spf->ot);
-			}
-		}
-	}
-
-	// Finalizer queue
-	runtime·iterate_finq(finq_callback);
-}
-
-// Bit vector of free marks.
-// Needs to be as big as the largest number of objects per span.
-static byte free[PageSize/8];
-
-static void
-dumpobjs(void)
-{
-	uintptr i, j, size, n, off, shift, *bitp, bits, ti, kind;
-	MSpan *s;
-	MLink *l;
-	byte *p;
-	Type *t;
-
-	for(i = 0; i < runtime·mheap.nspan; i++) {
-		s = runtime·mheap.allspans[i];
-		if(s->state != MSpanInUse)
-			continue;
-		p = (byte*)(s->start << PageShift);
-		size = s->elemsize;
-		n = (s->npages << PageShift) / size;
-		if(n > PageSize/8)
-			runtime·throw("free array doesn't have enough entries");
-		for(l = s->freelist; l != nil; l = l->next) {
-			free[((byte*)l - p) / size] = true;
-		}
-		for(j = 0; j < n; j++, p += size) {
-			if(free[j]) {
-				free[j] = false;
-				continue;
-			}
-			off = (uintptr*)p - (uintptr*)runtime·mheap.arena_start;
-			bitp = (uintptr*)runtime·mheap.arena_start - off/wordsPerBitmapWord - 1;
-			shift = off % wordsPerBitmapWord;
-			bits = *bitp >> shift;
-
-			// Skip FlagNoGC allocations (stacks)
-			if((bits & bitAllocated) == 0)
-				continue;
-
-			// extract type and kind
-			ti = runtime·gettype(p);
-			t = (Type*)(ti & ~(uintptr)(PtrSize-1));
-			kind = ti & (PtrSize-1);
-			
-			// dump it
-			if(kind == TypeInfo_Chan)
-				t = ((ChanType*)t)->elem; // use element type for chan encoding
-			if(t == nil && scannable(p))
-				kind = TypeInfo_Conservative; // special kind for conservatively scanned objects
-			dumpobj(p, size, t, kind);
-		}
-	}
-}
-
-static void
-dumpparams(void)
-{
-	byte *x;
-
-	dumpint(TagParams);
-	x = (byte*)1;
-	if(*(byte*)&x == 1)
-		dumpbool(false); // little-endian ptrs
-	else
-		dumpbool(true); // big-endian ptrs
-	dumpint(PtrSize);
-	dumpint(runtime·Hchansize);
-	dumpint((uintptr)runtime·mheap.arena_start);
-	dumpint((uintptr)runtime·mheap.arena_used);
-	dumpint(thechar);
-	dumpcstr(GOEXPERIMENT);
-	dumpint(runtime·ncpu);
-}
-
-static void
-itab_callback(Itab *tab)
-{
-	Type *t;
-
-	dumpint(TagItab);
-	dumpint((uintptr)tab);
-	t = tab->type;
-	dumpbool(t->size > PtrSize || (t->kind & KindNoPointers) == 0);
-}
-
-static void
-dumpitabs(void)
-{
-	runtime·iterate_itabs(itab_callback);
-}
-
-static void
-dumpms(void)
-{
-	M *mp;
-
-	for(mp = runtime·allm; mp != nil; mp = mp->alllink) {
-		dumpint(TagOSThread);
-		dumpint((uintptr)mp);
-		dumpint(mp->id);
-		dumpint(mp->procid);
-	}
-}
-
-static void
-dumpmemstats(void)
-{
-	int32 i;
-
-	dumpint(TagMemStats);
-	dumpint(mstats.alloc);
-	dumpint(mstats.total_alloc);
-	dumpint(mstats.sys);
-	dumpint(mstats.nlookup);
-	dumpint(mstats.nmalloc);
-	dumpint(mstats.nfree);
-	dumpint(mstats.heap_alloc);
-	dumpint(mstats.heap_sys);
-	dumpint(mstats.heap_idle);
-	dumpint(mstats.heap_inuse);
-	dumpint(mstats.heap_released);
-	dumpint(mstats.heap_objects);
-	dumpint(mstats.stacks_inuse);
-	dumpint(mstats.stacks_sys);
-	dumpint(mstats.mspan_inuse);
-	dumpint(mstats.mspan_sys);
-	dumpint(mstats.mcache_inuse);
-	dumpint(mstats.mcache_sys);
-	dumpint(mstats.buckhash_sys);
-	dumpint(mstats.gc_sys);
-	dumpint(mstats.other_sys);
-	dumpint(mstats.next_gc);
-	dumpint(mstats.last_gc);
-	dumpint(mstats.pause_total_ns);
-	for(i = 0; i < 256; i++)
-		dumpint(mstats.pause_ns[i]);
-	dumpint(mstats.numgc);
-}
-
-static void
-dumpmemprof_callback(Bucket *b, uintptr nstk, uintptr *stk, uintptr size, uintptr allocs, uintptr frees)
-{
-	uintptr i, pc;
-	Func *f;
-	byte buf[20];
-	String file;
-	int32 line;
-
-	dumpint(TagMemProf);
-	dumpint((uintptr)b);
-	dumpint(size);
-	dumpint(nstk);
-	for(i = 0; i < nstk; i++) {
-		pc = stk[i];
-		f = runtime·findfunc(pc);
-		if(f == nil) {
-			runtime·snprintf(buf, sizeof(buf), "%X", (uint64)pc);
-			dumpcstr((int8*)buf);
-			dumpcstr("?");
-			dumpint(0);
-		} else {
-			dumpcstr(runtime·funcname(f));
-			// TODO: Why do we need to back up to a call instruction here?
-			// Maybe profiler should do this.
-			if(i > 0 && pc > f->entry) {
-				if(thechar == '6' || thechar == '8')
-					pc--;
-				else
-					pc -= 4; // arm, etc
-			}
-			line = runtime·funcline(f, pc, &file);
-			dumpstr(file);
-			dumpint(line);
-		}
-	}
-	dumpint(allocs);
-	dumpint(frees);
-}
-
-static void
-dumpmemprof(void)
-{
-	MSpan *s, **allspans;
-	uint32 spanidx;
-	Special *sp;
-	SpecialProfile *spp;
-	byte *p;
-
-	runtime·iterate_memprof(dumpmemprof_callback);
-
-	allspans = runtime·mheap.allspans;
-	for(spanidx=0; spanidx<runtime·mheap.nspan; spanidx++) {
-		s = allspans[spanidx];
-		if(s->state != MSpanInUse)
-			continue;
-		for(sp = s->specials; sp != nil; sp = sp->next) {
-			if(sp->kind != KindSpecialProfile)
-				continue;
-			spp = (SpecialProfile*)sp;
-			p = (byte*)((s->start << PageShift) + spp->offset);
-			dumpint(TagAllocSample);
-			dumpint((uintptr)p);
-			dumpint((uintptr)spp->b);
-		}
-	}
-}
-
-static void
-mdump(G *gp)
-{
-	byte *hdr;
-	uintptr i;
-	MSpan *s;
-
-	// make sure we're done sweeping
-	for(i = 0; i < runtime·mheap.nspan; i++) {
-		s = runtime·mheap.allspans[i];
-		if(s->state == MSpanInUse)
-			runtime·MSpan_EnsureSwept(s);
-	}
-
-	runtime·memclr((byte*)&typecache[0], sizeof(typecache));
-	hdr = (byte*)"go1.3 heap dump\n";
-	write(hdr, runtime·findnull(hdr));
-	dumpparams();
-	dumpitabs();
-	dumpobjs();
-	dumpgs();
-	dumpms();
-	dumproots();
-	dumpmemstats();
-	dumpmemprof();
-	dumpint(TagEOF);
-	flush();
-
-	gp->param = nil;
-	gp->status = Grunning;
-	runtime·gogo(&gp->sched);
-}
-
-void
-runtime∕debug·WriteHeapDump(uintptr fd)
-{
-	// Stop the world.
-	runtime·semacquire(&runtime·worldsema, false);
-	m->gcing = 1;
-	m->locks++;
-	runtime·stoptheworld();
-
-	// Update stats so we can dump them.
-	// As a side effect, flushes all the MCaches so the MSpan.freelist
-	// lists contain all the free objects.
-	runtime·updatememstats(nil);
-
-	// Set dump file.
-	dumpfd = fd;
-
-	// Call dump routine on M stack.
-	g->status = Gwaiting;
-	g->waitreason = "dumping heap";
-	runtime·mcall(mdump);
-
-	// Reset dump file.
-	dumpfd = 0;
-
-	// Start up the world again.
-	m->gcing = 0;
-	runtime·semrelease(&runtime·worldsema);
-	runtime·starttheworld();
-	m->locks--;
-}
-
-// Runs the specified gc program.  Calls the callback for every
-// pointer-like field specified by the program and passes to the
-// callback the kind and offset of that field within the object.
-// offset is the offset in the object of the start of the program.
-// Returns a pointer to the opcode that ended the gc program (either
-// GC_END or GC_ARRAY_NEXT).
-static uintptr*
-playgcprog(uintptr offset, uintptr *prog, void (*callback)(void*,uintptr,uintptr), void *arg)
-{
-	uintptr len, elemsize, i, *end;
-
-	for(;;) {
-		switch(prog[0]) {
-		case GC_END:
-			return prog;
-		case GC_PTR:
-			callback(arg, FieldKindPtr, offset + prog[1]);
-			prog += 3;
-			break;
-		case GC_APTR:
-			callback(arg, FieldKindPtr, offset + prog[1]);
-			prog += 2;
-			break;
-		case GC_ARRAY_START:
-			len = prog[2];
-			elemsize = prog[3];
-			end = nil;
-			for(i = 0; i < len; i++) {
-				end = playgcprog(offset + prog[1] + i * elemsize, prog + 4, callback, arg);
-				if(end[0] != GC_ARRAY_NEXT)
-					runtime·throw("GC_ARRAY_START did not have matching GC_ARRAY_NEXT");
-			}
-			prog = end + 1;
-			break;
-		case GC_ARRAY_NEXT:
-			return prog;
-		case GC_CALL:
-			playgcprog(offset + prog[1], (uintptr*)((byte*)prog + *(int32*)&prog[2]), callback, arg);
-			prog += 3;
-			break;
-		case GC_CHAN_PTR:
-			callback(arg, FieldKindPtr, offset + prog[1]);
-			prog += 3;
-			break;
-		case GC_STRING:
-			callback(arg, FieldKindString, offset + prog[1]);
-			prog += 2;
-			break;
-		case GC_EFACE:
-			callback(arg, FieldKindEface, offset + prog[1]);
-			prog += 2;
-			break;
-		case GC_IFACE:
-			callback(arg, FieldKindIface, offset + prog[1]);
-			prog += 2;
-			break;
-		case GC_SLICE:
-			callback(arg, FieldKindSlice, offset + prog[1]);
-			prog += 3;
-			break;
-		case GC_REGION:
-			playgcprog(offset + prog[1], (uintptr*)prog[3] + 1, callback, arg);
-			prog += 4;
-			break;
-		default:
-			runtime·printf("%D\n", (uint64)prog[0]);
-			runtime·throw("bad gc op");
-		}
-	}
-}
-
-static void
-dump_callback(void *p, uintptr kind, uintptr offset)
-{
-	USED(&p);
-	dumpint(kind);
-	dumpint(offset);
-}
-
-// dumpint() the kind & offset of each field in an object.
-static void
-dumpfields(uintptr *prog)
-{
-	playgcprog(0, prog, dump_callback, nil);
-	dumpint(FieldKindEol);
-}
-
-static void
-dumpeface_callback(void *p, uintptr kind, uintptr offset)
-{
-	Eface *e;
-
-	if(kind != FieldKindEface)
-		return;
-	e = (Eface*)((byte*)p + offset);
-	dumptype(e->type);
-}
-
-// The heap dump reader needs to be able to disambiguate
-// Eface entries.  So it needs to know every type that might
-// appear in such an entry.  The following two routines accomplish
-// that.
-
-// Dump all the types that appear in the type field of
-// any Eface contained in obj.
-static void
-dumpefacetypes(void *obj, uintptr size, Type *type, uintptr kind)
-{
-	uintptr i;
-
-	switch(kind) {
-	case TypeInfo_SingleObject:
-		playgcprog(0, (uintptr*)type->gc + 1, dumpeface_callback, obj);
-		break;
-	case TypeInfo_Array:
-		for(i = 0; i <= size - type->size; i += type->size)
-			playgcprog(i, (uintptr*)type->gc + 1, dumpeface_callback, obj);
-		break;
-	case TypeInfo_Chan:
-		if(type->size == 0) // channels may have zero-sized objects in them
-			break;
-		for(i = runtime·Hchansize; i <= size - type->size; i += type->size)
-			playgcprog(i, (uintptr*)type->gc + 1, dumpeface_callback, obj);
-		break;
-	}
-}
-
-// Dump all the types that appear in the type field of
-// any Eface described by this bit vector.
-static void
-dumpbvtypes(BitVector *bv, byte *base)
-{
-	uintptr i;
-
-	for(i = 0; i < bv->n; i += BitsPerPointer) {
-		if((bv->data[i/32] >> i%32 & 3) != BitsMultiWord)
-			continue;
-		switch(bv->data[(i+BitsPerPointer)/32] >> (i+BitsPerPointer)%32 & 3) {
-		case BitsString:
-		case BitsIface:
-			i += BitsPerPointer;
-			break;
-		case BitsSlice:
-			i += 2 * BitsPerPointer;
-			break;
-		case BitsEface:
-			dumptype(*(Type**)(base + i / BitsPerPointer * PtrSize));
-			i += BitsPerPointer;
-			break;
-		}
-	}
-}
diff --git a/src/pkg/runtime/iface.goc b/src/pkg/runtime/iface.goc
deleted file mode 100644
index c0a17e3..0000000
--- a/src/pkg/runtime/iface.goc
+++ /dev/null
@@ -1,620 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package runtime
-#include "runtime.h"
-#include "arch_GOARCH.h"
-#include "type.h"
-#include "typekind.h"
-#include "malloc.h"
-#include "../../cmd/ld/textflag.h"
-
-func printiface(i Iface) {
-	runtime·printf("(%p,%p)", i.tab, i.data);
-}
-
-func printeface(e Eface) {
-	runtime·printf("(%p,%p)", e.type, e.data);
-}
-
-static	Itab*	hash[1009];
-static	Lock	ifacelock;
-
-static Itab*
-itab(InterfaceType *inter, Type *type, int32 canfail)
-{
-	int32 locked;
-	int32 ni;
-	Method *t, *et;
-	IMethod *i, *ei;
-	uint32 h;
-	String *iname, *ipkgPath;
-	Itab *m;
-	UncommonType *x;
-	Type *itype;
-	Eface err;
-
-	if(inter->mhdr.len == 0)
-		runtime·throw("internal error - misuse of itab");
-
-	locked = 0;
-
-	// easy case
-	x = type->x;
-	if(x == nil) {
-		if(canfail)
-			return nil;
-		iname = inter->m[0].name;
-		goto throw;
-	}
-
-	// compiler has provided some good hash codes for us.
-	h = inter->hash;
-	h += 17 * type->hash;
-	// TODO(rsc): h += 23 * x->mhash ?
-	h %= nelem(hash);
-
-	// look twice - once without lock, once with.
-	// common case will be no lock contention.
-	for(locked=0; locked<2; locked++) {
-		if(locked)
-			runtime·lock(&ifacelock);
-		for(m=runtime·atomicloadp(&hash[h]); m!=nil; m=m->link) {
-			if(m->inter == inter && m->type == type) {
-				if(m->bad) {
-					m = nil;
-					if(!canfail) {
-						// this can only happen if the conversion
-						// was already done once using the , ok form
-						// and we have a cached negative result.
-						// the cached result doesn't record which
-						// interface function was missing, so jump
-						// down to the interface check, which will
-						// do more work but give a better error.
-						goto search;
-					}
-				}
-				if(locked)
-					runtime·unlock(&ifacelock);
-				return m;
-			}
-		}
-	}
-
-	ni = inter->mhdr.len;
-	m = runtime·persistentalloc(sizeof(*m) + ni*sizeof m->fun[0], 0, &mstats.other_sys);
-	m->inter = inter;
-	m->type = type;
-
-search:
-	// both inter and type have method sorted by name,
-	// and interface names are unique,
-	// so can iterate over both in lock step;
-	// the loop is O(ni+nt) not O(ni*nt).
-	i = inter->m;
-	ei = i + inter->mhdr.len;
-	t = x->m;
-	et = t + x->mhdr.len;
-	for(; i < ei; i++) {
-		itype = i->type;
-		iname = i->name;
-		ipkgPath = i->pkgPath;
-		for(;; t++) {
-			if(t >= et) {
-				if(!canfail) {
-				throw:
-					// didn't find method
-					runtime·newTypeAssertionError(
-						nil, type->string, inter->string,
-						iname, &err);
-					if(locked)
-						runtime·unlock(&ifacelock);
-					runtime·panic(err);
-					return nil;	// not reached
-				}
-				m->bad = 1;
-				goto out;
-			}
-			if(t->mtyp == itype && t->name == iname && t->pkgPath == ipkgPath)
-				break;
-		}
-		if(m)
-			m->fun[i - inter->m] = t->ifn;
-	}
-
-out:
-	if(!locked)
-		runtime·panicstring("invalid itab locking");
-	m->link = hash[h];
-	runtime·atomicstorep(&hash[h], m);
-	runtime·unlock(&ifacelock);
-	if(m->bad)
-		return nil;
-	return m;
-}
-
-// call the callback for every itab that is currently allocated.
-void
-runtime·iterate_itabs(void (*callback)(Itab*))
-{
-	int32 i;
-	Itab *tab;
-
-	for(i = 0; i < nelem(hash); i++) {
-		for(tab = hash[i]; tab != nil; tab = tab->link) {
-			callback(tab);
-		}
-	}
-}
-
-static void
-copyin(Type *t, void *src, void **dst)
-{
-	uintptr size;
-	void *p;
-	Alg *alg;
-
-	size = t->size;
-	alg = t->alg;
-
-	if(size <= sizeof(*dst))
-		alg->copy(size, dst, src);
-	else {
-		p = runtime·cnew(t);
-		alg->copy(size, p, src);
-		*dst = p;
-	}
-}
-
-static void
-copyout(Type *t, void **src, void *dst)
-{
-	uintptr size;
-	Alg *alg;
-
-	size = t->size;
-	alg = t->alg;
-
-	if(size <= sizeof(*src))
-		alg->copy(size, dst, src);
-	else
-		alg->copy(size, dst, *src);
-}
-
-#pragma textflag NOSPLIT
-func typ2Itab(t *Type, inter *InterfaceType, cache **Itab) (tab *Itab) {
-	tab = itab(inter, t, 0);
-	runtime·atomicstorep(cache, tab);
-}
-
-#pragma textflag NOSPLIT
-func convT2I(t *Type, inter *InterfaceType, cache **Itab, elem *byte) (ret Iface) {
-	Itab *tab;
-
-	tab = runtime·atomicloadp(cache);
-	if(!tab) {
-		tab = itab(inter, t, 0);
-		runtime·atomicstorep(cache, tab);
-	}
-	ret.tab = tab;
-	copyin(t, elem, &ret.data);
-}
-
-#pragma textflag NOSPLIT
-func convT2E(t *Type, elem *byte) (ret Eface) {
-	ret.type = t;
-	copyin(t, elem, &ret.data);
-}
-
-static void assertI2Tret(Type *t, Iface i, byte *ret);
-
-/*
- * NOTE: Cannot use 'func' here, because we have to declare
- * a return value, the only types we have are at least 1 byte large,
- * goc2c will zero the return value, and the actual return value
- * might have size 0 bytes, in which case the zeroing of the
- * 1 or more bytes would be wrong.
- * Using C lets us control (avoid) the initial zeroing.
- */
-#pragma textflag NOSPLIT
-void
-runtime·assertI2T(Type *t, Iface i, GoOutput retbase)
-{
-	assertI2Tret(t, i, (byte*)&retbase);
-}
-
-static void
-assertI2Tret(Type *t, Iface i, byte *ret)
-{
-	Itab *tab;
-	Eface err;
-
-	tab = i.tab;
-	if(tab == nil) {
-		runtime·newTypeAssertionError(
-			nil, nil, t->string,
-			nil, &err);
-		runtime·panic(err);
-	}
-	if(tab->type != t) {
-		runtime·newTypeAssertionError(
-			tab->inter->string, tab->type->string, t->string,
-			nil, &err);
-		runtime·panic(err);
-	}
-	copyout(t, &i.data, ret);
-}
-
-#pragma textflag NOSPLIT
-func assertI2T2(t *Type, i Iface) (ret byte, ...) {
-	bool *ok;
-	int32 wid;
-
-	wid = t->size;
-	ok = (bool*)(&ret + wid);
-
-	if(i.tab == nil || i.tab->type != t) {
-		*ok = false;
-		runtime·memclr(&ret, wid);
-		return;
-	}
-
-	*ok = true;
-	copyout(t, &i.data, &ret);
-}
-
-func assertI2TOK(t *Type, i Iface) (ok bool) {
-	ok = i.tab!=nil && i.tab->type==t;
-}
-
-static void assertE2Tret(Type *t, Eface e, byte *ret);
-
-/*
- * NOTE: Cannot use 'func' here. See assertI2T above.
- */
-#pragma textflag NOSPLIT
-void
-runtime·assertE2T(Type *t, Eface e, GoOutput retbase)
-{
-	assertE2Tret(t, e, (byte*)&retbase);
-}
-
-static void
-assertE2Tret(Type *t, Eface e, byte *ret)
-{
-	Eface err;
-
-	if(e.type == nil) {
-		runtime·newTypeAssertionError(
-			nil, nil, t->string,
-			nil, &err);
-		runtime·panic(err);
-	}
-	if(e.type != t) {
-		runtime·newTypeAssertionError(
-			nil, e.type->string, t->string,
-			nil, &err);
-		runtime·panic(err);
-	}
-	copyout(t, &e.data, ret);
-}
-
-#pragma textflag NOSPLIT
-func assertE2T2(t *Type, e Eface) (ret byte, ...) {
-	bool *ok;
-	int32 wid;
-
-	wid = t->size;
-	ok = (bool*)(&ret + wid);
-
-	if(t != e.type) {
-		*ok = false;
-		runtime·memclr(&ret, wid);
-		return;
-	}
-
-	*ok = true;
-	copyout(t, &e.data, &ret);
-}
-
-func assertE2TOK(t *Type, e Eface) (ok bool) {
-	ok = t==e.type;
-}
-
-func convI2E(i Iface) (ret Eface) {
-	Itab *tab;
-
-	ret.data = i.data;
-	if((tab = i.tab) == nil)
-		ret.type = nil;
-	else
-		ret.type = tab->type;
-}
-
-func assertI2E(inter *InterfaceType, i Iface) (ret Eface) {
-	Itab *tab;
-	Eface err;
-
-	tab = i.tab;
-	if(tab == nil) {
-		// explicit conversions require non-nil interface value.
-		runtime·newTypeAssertionError(
-			nil, nil, inter->string,
-			nil, &err);
-		runtime·panic(err);
-	}
-	ret.data = i.data;
-	ret.type = tab->type;
-}
-
-func assertI2E2(inter *InterfaceType, i Iface) (ret Eface, ok bool) {
-	Itab *tab;
-
-	USED(inter);
-	tab = i.tab;
-	if(tab == nil) {
-		ret.type = nil;
-		ok = 0;
-	} else {
-		ret.type = tab->type;
-		ok = 1;
-	}
-	ret.data = i.data;
-}
-
-func convI2I(inter *InterfaceType, i Iface) (ret Iface) {
-	Itab *tab;
-
-	ret.data = i.data;
-	if((tab = i.tab) == nil)
-		ret.tab = nil;
-	else if(tab->inter == inter)
-		ret.tab = tab;
-	else
-		ret.tab = itab(inter, tab->type, 0);
-}
-
-void
-runtime·ifaceI2I(InterfaceType *inter, Iface i, Iface *ret)
-{
-	Itab *tab;
-	Eface err;
-
-	tab = i.tab;
-	if(tab == nil) {
-		// explicit conversions require non-nil interface value.
-		runtime·newTypeAssertionError(
-			nil, nil, inter->string,
-			nil, &err);
-		runtime·panic(err);
-	}
-	ret->data = i.data;
-	ret->tab = itab(inter, tab->type, 0);
-}
-
-func assertI2I(inter *InterfaceType, i Iface) (ret Iface) {
-	runtime·ifaceI2I(inter, i, &ret);
-}
-
-func assertI2I2(inter *InterfaceType, i Iface) (ret Iface, ok bool) {
-	Itab *tab;
-
-	tab = i.tab;
-	if(tab != nil && (tab->inter == inter || (tab = itab(inter, tab->type, 1)) != nil)) {
-		ret.data = i.data;
-		ret.tab = tab;
-		ok = 1;
-	} else {
-		ret.data = 0;
-		ret.tab = 0;
-		ok = 0;
-	}
-}
-
-void
-runtime·ifaceE2I(InterfaceType *inter, Eface e, Iface *ret)
-{
-	Type *t;
-	Eface err;
-
-	t = e.type;
-	if(t == nil) {
-		// explicit conversions require non-nil interface value.
-		runtime·newTypeAssertionError(
-			nil, nil, inter->string,
-			nil, &err);
-		runtime·panic(err);
-	}
-	ret->data = e.data;
-	ret->tab = itab(inter, t, 0);
-}
-
-bool
-runtime·ifaceE2I2(InterfaceType *inter, Eface e, Iface *ret)
-{
-	ret->tab = itab(inter, e.type, 1);
-	if(ret->tab == nil)
-		return false;
-	ret->data = e.data;
-	return true;
-}
-
-func reflect·ifaceE2I(inter *InterfaceType, e Eface, dst *Iface) {
-	runtime·ifaceE2I(inter, e, dst);
-}
-
-func assertE2I(inter *InterfaceType, e Eface) (ret Iface) {
-	runtime·ifaceE2I(inter, e, &ret);
-}
-
-func assertE2I2(inter *InterfaceType, e Eface) (ret Iface, ok bool) {
-	if(e.type == nil) {
-		ok = 0;
-		ret.data = nil;
-		ret.tab = nil;
-	} else if((ret.tab = itab(inter, e.type, 1)) == nil) {
-		ok = 0;
-		ret.data = nil;
-	} else {
-		ok = 1;
-		ret.data = e.data;
-	}
-}
-
-func assertE2E(inter *InterfaceType, e Eface) (ret Eface) {
-	Type *t;
-	Eface err;
-
-	t = e.type;
-	if(t == nil) {
-		// explicit conversions require non-nil interface value.
-		runtime·newTypeAssertionError(
-			nil, nil, inter->string,
-			nil, &err);
-		runtime·panic(err);
-	}
-	ret = e;
-}
-
-func assertE2E2(inter *InterfaceType, e Eface) (ret Eface, ok bool) {
-	USED(inter);
-	ret = e;
-	ok = e.type != nil;
-}
-
-static uintptr
-ifacehash1(void *data, Type *t, uintptr h)
-{
-	Alg *alg;
-	uintptr size;
-	Eface err;
-
-	if(t == nil)
-		return 0;
-
-	alg = t->alg;
-	size = t->size;
-	if(alg->hash == runtime·nohash) {
-		// calling nohash will panic too,
-		// but we can print a better error.
-		runtime·newErrorString(runtime·catstring(runtime·gostringnocopy((byte*)"hash of unhashable type "), *t->string), &err);
-		runtime·panic(err);
-	}
-	if(size <= sizeof(data))
-		alg->hash(&h, size, &data);
-	else
-		alg->hash(&h, size, data);
-	return h;
-}
-
-uintptr
-runtime·ifacehash(Iface a, uintptr h)
-{
-	if(a.tab == nil)
-		return h;
-	return ifacehash1(a.data, a.tab->type, h);
-}
-
-uintptr
-runtime·efacehash(Eface a, uintptr h)
-{
-	return ifacehash1(a.data, a.type, h);
-}
-
-static bool
-ifaceeq1(void *data1, void *data2, Type *t)
-{
-	uintptr size;
-	Alg *alg;
-	Eface err;
-	bool eq;
-
-	alg = t->alg;
-	size = t->size;
-
-	if(alg->equal == runtime·noequal) {
-		// calling noequal will panic too,
-		// but we can print a better error.
-		runtime·newErrorString(runtime·catstring(runtime·gostringnocopy((byte*)"comparing uncomparable type "), *t->string), &err);
-		runtime·panic(err);
-	}
-
-	eq = 0;
-	if(size <= sizeof(data1))
-		alg->equal(&eq, size, &data1, &data2);
-	else
-		alg->equal(&eq, size, data1, data2);
-	return eq;
-}
-
-bool
-runtime·ifaceeq_c(Iface i1, Iface i2)
-{
-	if(i1.tab != i2.tab)
-		return false;
-	if(i1.tab == nil)
-		return true;
-	return ifaceeq1(i1.data, i2.data, i1.tab->type);
-}
-
-bool
-runtime·efaceeq_c(Eface e1, Eface e2)
-{
-	if(e1.type != e2.type)
-		return false;
-	if(e1.type == nil)
-		return true;
-	return ifaceeq1(e1.data, e2.data, e1.type);
-}
-
-func ifaceeq(i1 Iface, i2 Iface) (ret bool) {
-	ret = runtime·ifaceeq_c(i1, i2);
-}
-
-func efaceeq(e1 Eface, e2 Eface) (ret bool) {
-	ret = runtime·efaceeq_c(e1, e2);
-}
-
-func ifacethash(i1 Iface) (ret uint32) {
-	Itab *tab;
-
-	ret = 0;
-	tab = i1.tab;
-	if(tab != nil)
-		ret = tab->type->hash;
-}
-
-func efacethash(e1 Eface) (ret uint32) {
-	Type *t;
-
-	ret = 0;
-	t = e1.type;
-	if(t != nil)
-		ret = t->hash;
-}
-
-func reflect·unsafe_Typeof(e Eface) (ret Eface) {
-	if(e.type == nil) {
-		ret.type = nil;
-		ret.data = nil;
-	} else {
-		ret = *(Eface*)(e.type);
-	}
-}
-
-func reflect·unsafe_New(t *Type) (ret *byte) {
-	ret = runtime·cnew(t);
-}
-
-func reflect·unsafe_NewArray(t *Type, n int) (ret *byte) {
-	ret = runtime·cnewarray(t, n);
-}
-
-func reflect·typelinks() (ret Slice) {
-	extern Type *typelink[], *etypelink[];
-	static int32 first = 1;
-	ret.array = (byte*)typelink;
-	ret.len = etypelink - typelink;
-	ret.cap = ret.len;
-}
diff --git a/src/pkg/runtime/lfstack.goc b/src/pkg/runtime/lfstack.goc
deleted file mode 100644
index f7b8eff..0000000
--- a/src/pkg/runtime/lfstack.goc
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Lock-free stack.
-
-package runtime
-#include "runtime.h"
-#include "arch_GOARCH.h"
-
-#ifdef _64BIT
-// Amd64 uses 48-bit virtual addresses, 47-th bit is used as kernel/user flag.
-// So we use 17msb of pointers as ABA counter.
-# define PTR_BITS 47
-#else
-# define PTR_BITS 32
-#endif
-#define PTR_MASK ((1ull<<PTR_BITS)-1)
-#define CNT_MASK (0ull-1)
-
-#ifdef _64BIT
-#ifdef GOOS_solaris
-// SPARC64 and Solaris on AMD64 uses all 64 bits of virtual addresses.
-// Use low-order three bits as ABA counter.
-// http://docs.oracle.com/cd/E19120-01/open.solaris/816-5138/6mba6ua5p/index.html
-#undef PTR_BITS
-#undef CNT_MASK
-#undef PTR_MASK
-#define PTR_BITS 0
-#define CNT_MASK 7
-#define PTR_MASK ((0ull-1)<<3)
-#endif
-#endif
-
-void
-runtime·lfstackpush(uint64 *head, LFNode *node)
-{
-	uint64 old, new;
-
-	if((uintptr)node != ((uintptr)node&PTR_MASK)) {
-		runtime·printf("p=%p\n", node);
-		runtime·throw("runtime·lfstackpush: invalid pointer");
-	}
-
-	node->pushcnt++;
-	new = (uint64)(uintptr)node|(((uint64)node->pushcnt&CNT_MASK)<<PTR_BITS);
-	for(;;) {
-		old = runtime·atomicload64(head);
-		node->next = (LFNode*)(uintptr)(old&PTR_MASK);
-		if(runtime·cas64(head, old, new))
-			break;
-	}
-}
-
-LFNode*
-runtime·lfstackpop(uint64 *head)
-{
-	LFNode *node, *node2;
-	uint64 old, new;
-
-	for(;;) {
-		old = runtime·atomicload64(head);
-		if(old == 0)
-			return nil;
-		node = (LFNode*)(uintptr)(old&PTR_MASK);
-		node2 = runtime·atomicloadp(&node->next);
-		new = 0;
-		if(node2 != nil)
-			new = (uint64)(uintptr)node2|(((uint64)node2->pushcnt&CNT_MASK)<<PTR_BITS);
-		if(runtime·cas64(head, old, new))
-			return node;
-	}
-}
-
-func lfstackpush_go(head *uint64, node *LFNode) {
-	runtime·lfstackpush(head, node);
-}
-
-func lfstackpop_go(head *uint64) (node *LFNode) {
-	node = runtime·lfstackpop(head);
-}
diff --git a/src/pkg/runtime/lock_futex.c b/src/pkg/runtime/lock_futex.c
deleted file mode 100644
index c16ac90..0000000
--- a/src/pkg/runtime/lock_futex.c
+++ /dev/null
@@ -1,201 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build dragonfly freebsd linux
-
-#include "runtime.h"
-#include "stack.h"
-#include "../../cmd/ld/textflag.h"
-
-// This implementation depends on OS-specific implementations of
-//
-//	runtime·futexsleep(uint32 *addr, uint32 val, int64 ns)
-//		Atomically,
-//			if(*addr == val) sleep
-//		Might be woken up spuriously; that's allowed.
-//		Don't sleep longer than ns; ns < 0 means forever.
-//
-//	runtime·futexwakeup(uint32 *addr, uint32 cnt)
-//		If any procs are sleeping on addr, wake up at most cnt.
-
-enum
-{
-	MUTEX_UNLOCKED = 0,
-	MUTEX_LOCKED = 1,
-	MUTEX_SLEEPING = 2,
-
-	ACTIVE_SPIN = 4,
-	ACTIVE_SPIN_CNT = 30,
-	PASSIVE_SPIN = 1,
-};
-
-// Possible lock states are MUTEX_UNLOCKED, MUTEX_LOCKED and MUTEX_SLEEPING.
-// MUTEX_SLEEPING means that there is presumably at least one sleeping thread.
-// Note that there can be spinning threads during all states - they do not
-// affect mutex's state.
-void
-runtime·lock(Lock *l)
-{
-	uint32 i, v, wait, spin;
-
-	if(m->locks++ < 0)
-		runtime·throw("runtime·lock: lock count");
-
-	// Speculative grab for lock.
-	v = runtime·xchg((uint32*)&l->key, MUTEX_LOCKED);
-	if(v == MUTEX_UNLOCKED)
-		return;
-
-	// wait is either MUTEX_LOCKED or MUTEX_SLEEPING
-	// depending on whether there is a thread sleeping
-	// on this mutex.  If we ever change l->key from
-	// MUTEX_SLEEPING to some other value, we must be
-	// careful to change it back to MUTEX_SLEEPING before
-	// returning, to ensure that the sleeping thread gets
-	// its wakeup call.
-	wait = v;
-
-	// On uniprocessor's, no point spinning.
-	// On multiprocessors, spin for ACTIVE_SPIN attempts.
-	spin = 0;
-	if(runtime·ncpu > 1)
-		spin = ACTIVE_SPIN;
-
-	for(;;) {
-		// Try for lock, spinning.
-		for(i = 0; i < spin; i++) {
-			while(l->key == MUTEX_UNLOCKED)
-				if(runtime·cas((uint32*)&l->key, MUTEX_UNLOCKED, wait))
-					return;
-			runtime·procyield(ACTIVE_SPIN_CNT);
-		}
-
-		// Try for lock, rescheduling.
-		for(i=0; i < PASSIVE_SPIN; i++) {
-			while(l->key == MUTEX_UNLOCKED)
-				if(runtime·cas((uint32*)&l->key, MUTEX_UNLOCKED, wait))
-					return;
-			runtime·osyield();
-		}
-
-		// Sleep.
-		v = runtime·xchg((uint32*)&l->key, MUTEX_SLEEPING);
-		if(v == MUTEX_UNLOCKED)
-			return;
-		wait = MUTEX_SLEEPING;
-		runtime·futexsleep((uint32*)&l->key, MUTEX_SLEEPING, -1);
-	}
-}
-
-void
-runtime·unlock(Lock *l)
-{
-	uint32 v;
-
-	v = runtime·xchg((uint32*)&l->key, MUTEX_UNLOCKED);
-	if(v == MUTEX_UNLOCKED)
-		runtime·throw("unlock of unlocked lock");
-	if(v == MUTEX_SLEEPING)
-		runtime·futexwakeup((uint32*)&l->key, 1);
-
-	if(--m->locks < 0)
-		runtime·throw("runtime·unlock: lock count");
-	if(m->locks == 0 && g->preempt)  // restore the preemption request in case we've cleared it in newstack
-		g->stackguard0 = StackPreempt;
-}
-
-// One-time notifications.
-void
-runtime·noteclear(Note *n)
-{
-	n->key = 0;
-}
-
-void
-runtime·notewakeup(Note *n)
-{
-	uint32 old;
-
-	old = runtime·xchg((uint32*)&n->key, 1);
-	if(old != 0) {
-		runtime·printf("notewakeup - double wakeup (%d)\n", old);
-		runtime·throw("notewakeup - double wakeup");
-	}
-	runtime·futexwakeup((uint32*)&n->key, 1);
-}
-
-void
-runtime·notesleep(Note *n)
-{
-	if(g != m->g0)
-		runtime·throw("notesleep not on g0");
-	while(runtime·atomicload((uint32*)&n->key) == 0) {
-		m->blocked = true;
-		runtime·futexsleep((uint32*)&n->key, 0, -1);
-		m->blocked = false;
-	}
-}
-
-#pragma textflag NOSPLIT
-static bool
-notetsleep(Note *n, int64 ns, int64 deadline, int64 now)
-{
-	// Conceptually, deadline and now are local variables.
-	// They are passed as arguments so that the space for them
-	// does not count against our nosplit stack sequence.
-
-	if(ns < 0) {
-		while(runtime·atomicload((uint32*)&n->key) == 0) {
-			m->blocked = true;
-			runtime·futexsleep((uint32*)&n->key, 0, -1);
-			m->blocked = false;
-		}
-		return true;
-	}
-
-	if(runtime·atomicload((uint32*)&n->key) != 0)
-		return true;
-
-	deadline = runtime·nanotime() + ns;
-	for(;;) {
-		m->blocked = true;
-		runtime·futexsleep((uint32*)&n->key, 0, ns);
-		m->blocked = false;
-		if(runtime·atomicload((uint32*)&n->key) != 0)
-			break;
-		now = runtime·nanotime();
-		if(now >= deadline)
-			break;
-		ns = deadline - now;
-	}
-	return runtime·atomicload((uint32*)&n->key) != 0;
-}
-
-bool
-runtime·notetsleep(Note *n, int64 ns)
-{
-	bool res;
-
-	if(g != m->g0 && !m->gcing)
-		runtime·throw("notetsleep not on g0");
-
-	res = notetsleep(n, ns, 0, 0);
-	return res;
-}
-
-// same as runtime·notetsleep, but called on user g (not g0)
-// calls only nosplit functions between entersyscallblock/exitsyscall
-bool
-runtime·notetsleepg(Note *n, int64 ns)
-{
-	bool res;
-
-	if(g == m->g0)
-		runtime·throw("notetsleepg on g0");
-
-	runtime·entersyscallblock();
-	res = notetsleep(n, ns, 0, 0);
-	runtime·exitsyscall();
-	return res;
-}
diff --git a/src/pkg/runtime/lock_sema.c b/src/pkg/runtime/lock_sema.c
deleted file mode 100644
index ff8fdfd..0000000
--- a/src/pkg/runtime/lock_sema.c
+++ /dev/null
@@ -1,266 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build darwin nacl netbsd openbsd plan9 solaris windows
-
-#include "runtime.h"
-#include "stack.h"
-#include "../../cmd/ld/textflag.h"
-
-// This implementation depends on OS-specific implementations of
-//
-//	uintptr runtime·semacreate(void)
-//		Create a semaphore, which will be assigned to m->waitsema.
-//		The zero value is treated as absence of any semaphore,
-//		so be sure to return a non-zero value.
-//
-//	int32 runtime·semasleep(int64 ns)
-//		If ns < 0, acquire m->waitsema and return 0.
-//		If ns >= 0, try to acquire m->waitsema for at most ns nanoseconds.
-//		Return 0 if the semaphore was acquired, -1 if interrupted or timed out.
-//
-//	int32 runtime·semawakeup(M *mp)
-//		Wake up mp, which is or will soon be sleeping on mp->waitsema.
-//
-
-enum
-{
-	LOCKED = 1,
-
-	ACTIVE_SPIN = 4,
-	ACTIVE_SPIN_CNT = 30,
-	PASSIVE_SPIN = 1,
-};
-
-void
-runtime·lock(Lock *l)
-{
-	uintptr v;
-	uint32 i, spin;
-
-	if(m->locks++ < 0)
-		runtime·throw("runtime·lock: lock count");
-
-	// Speculative grab for lock.
-	if(runtime·casp((void**)&l->key, nil, (void*)LOCKED))
-		return;
-
-	if(m->waitsema == 0)
-		m->waitsema = runtime·semacreate();
-
-	// On uniprocessor's, no point spinning.
-	// On multiprocessors, spin for ACTIVE_SPIN attempts.
-	spin = 0;
-	if(runtime·ncpu > 1)
-		spin = ACTIVE_SPIN;
-
-	for(i=0;; i++) {
-		v = (uintptr)runtime·atomicloadp((void**)&l->key);
-		if((v&LOCKED) == 0) {
-unlocked:
-			if(runtime·casp((void**)&l->key, (void*)v, (void*)(v|LOCKED)))
-				return;
-			i = 0;
-		}
-		if(i<spin)
-			runtime·procyield(ACTIVE_SPIN_CNT);
-		else if(i<spin+PASSIVE_SPIN)
-			runtime·osyield();
-		else {
-			// Someone else has it.
-			// l->waitm points to a linked list of M's waiting
-			// for this lock, chained through m->nextwaitm.
-			// Queue this M.
-			for(;;) {
-				m->nextwaitm = (void*)(v&~LOCKED);
-				if(runtime·casp((void**)&l->key, (void*)v, (void*)((uintptr)m|LOCKED)))
-					break;
-				v = (uintptr)runtime·atomicloadp((void**)&l->key);
-				if((v&LOCKED) == 0)
-					goto unlocked;
-			}
-			if(v&LOCKED) {
-				// Queued.  Wait.
-				runtime·semasleep(-1);
-				i = 0;
-			}
-		}
-	}
-}
-
-void
-runtime·unlock(Lock *l)
-{
-	uintptr v;
-	M *mp;
-
-	for(;;) {
-		v = (uintptr)runtime·atomicloadp((void**)&l->key);
-		if(v == LOCKED) {
-			if(runtime·casp((void**)&l->key, (void*)LOCKED, nil))
-				break;
-		} else {
-			// Other M's are waiting for the lock.
-			// Dequeue an M.
-			mp = (void*)(v&~LOCKED);
-			if(runtime·casp((void**)&l->key, (void*)v, mp->nextwaitm)) {
-				// Dequeued an M.  Wake it.
-				runtime·semawakeup(mp);
-				break;
-			}
-		}
-	}
-
-	if(--m->locks < 0)
-		runtime·throw("runtime·unlock: lock count");
-	if(m->locks == 0 && g->preempt)  // restore the preemption request in case we've cleared it in newstack
-		g->stackguard0 = StackPreempt;
-}
-
-// One-time notifications.
-void
-runtime·noteclear(Note *n)
-{
-	n->key = 0;
-}
-
-void
-runtime·notewakeup(Note *n)
-{
-	M *mp;
-
-	do
-		mp = runtime·atomicloadp((void**)&n->key);
-	while(!runtime·casp((void**)&n->key, mp, (void*)LOCKED));
-
-	// Successfully set waitm to LOCKED.
-	// What was it before?
-	if(mp == nil) {
-		// Nothing was waiting.  Done.
-	} else if(mp == (M*)LOCKED) {
-		// Two notewakeups!  Not allowed.
-		runtime·throw("notewakeup - double wakeup");
-	} else {
-		// Must be the waiting m.  Wake it up.
-		runtime·semawakeup(mp);
-	}
-}
-
-void
-runtime·notesleep(Note *n)
-{
-	if(g != m->g0)
-		runtime·throw("notesleep not on g0");
-
-	if(m->waitsema == 0)
-		m->waitsema = runtime·semacreate();
-	if(!runtime·casp((void**)&n->key, nil, m)) {  // must be LOCKED (got wakeup)
-		if(n->key != LOCKED)
-			runtime·throw("notesleep - waitm out of sync");
-		return;
-	}
-	// Queued.  Sleep.
-	m->blocked = true;
-	runtime·semasleep(-1);
-	m->blocked = false;
-}
-
-#pragma textflag NOSPLIT
-static bool
-notetsleep(Note *n, int64 ns, int64 deadline, M *mp)
-{
-	// Conceptually, deadline and mp are local variables.
-	// They are passed as arguments so that the space for them
-	// does not count against our nosplit stack sequence.
-
-	// Register for wakeup on n->waitm.
-	if(!runtime·casp((void**)&n->key, nil, m)) {  // must be LOCKED (got wakeup already)
-		if(n->key != LOCKED)
-			runtime·throw("notetsleep - waitm out of sync");
-		return true;
-	}
-
-	if(ns < 0) {
-		// Queued.  Sleep.
-		m->blocked = true;
-		runtime·semasleep(-1);
-		m->blocked = false;
-		return true;
-	}
-
-	deadline = runtime·nanotime() + ns;
-	for(;;) {
-		// Registered.  Sleep.
-		m->blocked = true;
-		if(runtime·semasleep(ns) >= 0) {
-			m->blocked = false;
-			// Acquired semaphore, semawakeup unregistered us.
-			// Done.
-			return true;
-		}
-		m->blocked = false;
-
-		// Interrupted or timed out.  Still registered.  Semaphore not acquired.
-		ns = deadline - runtime·nanotime();
-		if(ns <= 0)
-			break;
-		// Deadline hasn't arrived.  Keep sleeping.
-	}
-
-	// Deadline arrived.  Still registered.  Semaphore not acquired.
-	// Want to give up and return, but have to unregister first,
-	// so that any notewakeup racing with the return does not
-	// try to grant us the semaphore when we don't expect it.
-	for(;;) {
-		mp = runtime·atomicloadp((void**)&n->key);
-		if(mp == m) {
-			// No wakeup yet; unregister if possible.
-			if(runtime·casp((void**)&n->key, mp, nil))
-				return false;
-		} else if(mp == (M*)LOCKED) {
-			// Wakeup happened so semaphore is available.
-			// Grab it to avoid getting out of sync.
-			m->blocked = true;
-			if(runtime·semasleep(-1) < 0)
-				runtime·throw("runtime: unable to acquire - semaphore out of sync");
-			m->blocked = false;
-			return true;
-		} else
-			runtime·throw("runtime: unexpected waitm - semaphore out of sync");
-	}
-}
-
-bool
-runtime·notetsleep(Note *n, int64 ns)
-{
-	bool res;
-
-	if(g != m->g0 && !m->gcing)
-		runtime·throw("notetsleep not on g0");
-
-	if(m->waitsema == 0)
-		m->waitsema = runtime·semacreate();
-
-	res = notetsleep(n, ns, 0, nil);
-	return res;
-}
-
-// same as runtime·notetsleep, but called on user g (not g0)
-// calls only nosplit functions between entersyscallblock/exitsyscall
-bool
-runtime·notetsleepg(Note *n, int64 ns)
-{
-	bool res;
-
-	if(g == m->g0)
-		runtime·throw("notetsleepg on g0");
-
-	if(m->waitsema == 0)
-		m->waitsema = runtime·semacreate();
-
-	runtime·entersyscallblock();
-	res = notetsleep(n, ns, 0, nil);
-	runtime·exitsyscall();
-	return res;
-}
diff --git a/src/pkg/runtime/malloc.goc b/src/pkg/runtime/malloc.goc
deleted file mode 100644
index 7b7e350..0000000
--- a/src/pkg/runtime/malloc.goc
+++ /dev/null
@@ -1,939 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// See malloc.h for overview.
-//
-// TODO(rsc): double-check stats.
-
-package runtime
-#include "runtime.h"
-#include "arch_GOARCH.h"
-#include "malloc.h"
-#include "type.h"
-#include "typekind.h"
-#include "race.h"
-#include "stack.h"
-#include "../../cmd/ld/textflag.h"
-
-// Mark mheap as 'no pointers', it does not contain interesting pointers but occupies ~45K.
-#pragma dataflag NOPTR
-MHeap runtime·mheap;
-#pragma dataflag NOPTR
-MStats mstats;
-
-int32	runtime·checking;
-
-extern MStats mstats;	// defined in zruntime_def_$GOOS_$GOARCH.go
-
-extern volatile intgo runtime·MemProfileRate;
-
-static MSpan* largealloc(uint32, uintptr*);
-static void profilealloc(void *v, uintptr size);
-static void settype(MSpan *s, void *v, uintptr typ);
-
-// Allocate an object of at least size bytes.
-// Small objects are allocated from the per-thread cache's free lists.
-// Large objects (> 32 kB) are allocated straight from the heap.
-// If the block will be freed with runtime·free(), typ must be 0.
-void*
-runtime·mallocgc(uintptr size, uintptr typ, uint32 flag)
-{
-	int32 sizeclass;
-	uintptr tinysize, size1;
-	intgo rate;
-	MCache *c;
-	MSpan *s;
-	MLink *v, *next;
-	byte *tiny;
-
-	if(size == 0) {
-		// All 0-length allocations use this pointer.
-		// The language does not require the allocations to
-		// have distinct values.
-		return &runtime·zerobase;
-	}
-	if(m->mallocing)
-		runtime·throw("malloc/free - deadlock");
-	// Disable preemption during settype.
-	// We can not use m->mallocing for this, because settype calls mallocgc.
-	m->locks++;
-	m->mallocing = 1;
-
-	if(DebugTypeAtBlockEnd)
-		size += sizeof(uintptr);
-
-	c = m->mcache;
-	if(!runtime·debug.efence && size <= MaxSmallSize) {
-		if((flag&(FlagNoScan|FlagNoGC)) == FlagNoScan && size < TinySize) {
-			// Tiny allocator.
-			//
-			// Tiny allocator combines several tiny allocation requests
-			// into a single memory block. The resulting memory block
-			// is freed when all subobjects are unreachable. The subobjects
-			// must be FlagNoScan (don't have pointers), this ensures that
-			// the amount of potentially wasted memory is bounded.
-			//
-			// Size of the memory block used for combining (TinySize) is tunable.
-			// Current setting is 16 bytes, which relates to 2x worst case memory
-			// wastage (when all but one subobjects are unreachable).
-			// 8 bytes would result in no wastage at all, but provides less
-			// opportunities for combining.
-			// 32 bytes provides more opportunities for combining,
-			// but can lead to 4x worst case wastage.
-			// The best case winning is 8x regardless of block size.
-			//
-			// Objects obtained from tiny allocator must not be freed explicitly.
-			// So when an object will be freed explicitly, we ensure that
-			// its size >= TinySize.
-			//
-			// SetFinalizer has a special case for objects potentially coming
-			// from tiny allocator, it such case it allows to set finalizers
-			// for an inner byte of a memory block.
-			//
-			// The main targets of tiny allocator are small strings and
-			// standalone escaping variables. On a json benchmark
-			// the allocator reduces number of allocations by ~12% and
-			// reduces heap size by ~20%.
-
-			tinysize = c->tinysize;
-			if(size <= tinysize) {
-				tiny = c->tiny;
-				// Align tiny pointer for required (conservative) alignment.
-				if((size&7) == 0)
-					tiny = (byte*)ROUND((uintptr)tiny, 8);
-				else if((size&3) == 0)
-					tiny = (byte*)ROUND((uintptr)tiny, 4);
-				else if((size&1) == 0)
-					tiny = (byte*)ROUND((uintptr)tiny, 2);
-				size1 = size + (tiny - c->tiny);
-				if(size1 <= tinysize) {
-					// The object fits into existing tiny block.
-					v = (MLink*)tiny;
-					c->tiny += size1;
-					c->tinysize -= size1;
-					m->mallocing = 0;
-					m->locks--;
-					if(m->locks == 0 && g->preempt)  // restore the preemption request in case we've cleared it in newstack
-						g->stackguard0 = StackPreempt;
-					return v;
-				}
-			}
-			// Allocate a new TinySize block.
-			s = c->alloc[TinySizeClass];
-			if(s->freelist == nil)
-				s = runtime·MCache_Refill(c, TinySizeClass);
-			v = s->freelist;
-			next = v->next;
-			s->freelist = next;
-			s->ref++;
-			if(next != nil)  // prefetching nil leads to a DTLB miss
-				PREFETCH(next);
-			((uint64*)v)[0] = 0;
-			((uint64*)v)[1] = 0;
-			// See if we need to replace the existing tiny block with the new one
-			// based on amount of remaining free space.
-			if(TinySize-size > tinysize) {
-				c->tiny = (byte*)v + size;
-				c->tinysize = TinySize - size;
-			}
-			size = TinySize;
-			goto done;
-		}
-		// Allocate from mcache free lists.
-		// Inlined version of SizeToClass().
-		if(size <= 1024-8)
-			sizeclass = runtime·size_to_class8[(size+7)>>3];
-		else
-			sizeclass = runtime·size_to_class128[(size-1024+127) >> 7];
-		size = runtime·class_to_size[sizeclass];
-		s = c->alloc[sizeclass];
-		if(s->freelist == nil)
-			s = runtime·MCache_Refill(c, sizeclass);
-		v = s->freelist;
-		next = v->next;
-		s->freelist = next;
-		s->ref++;
-		if(next != nil)  // prefetching nil leads to a DTLB miss
-			PREFETCH(next);
-		if(!(flag & FlagNoZero)) {
-			v->next = nil;
-			// block is zeroed iff second word is zero ...
-			if(size > 2*sizeof(uintptr) && ((uintptr*)v)[1] != 0)
-				runtime·memclr((byte*)v, size);
-		}
-	done:
-		c->local_cachealloc += size;
-	} else {
-		// Allocate directly from heap.
-		s = largealloc(flag, &size);
-		v = (void*)(s->start << PageShift);
-	}
-
-	if(flag & FlagNoGC)
-		runtime·marknogc(v);
-	else if(!(flag & FlagNoScan))
-		runtime·markscan(v);
-
-	if(DebugTypeAtBlockEnd)
-		*(uintptr*)((uintptr)v+size-sizeof(uintptr)) = typ;
-
-	m->mallocing = 0;
-	// TODO: save type even if FlagNoScan?  Potentially expensive but might help
-	// heap profiling/tracing.
-	if(UseSpanType && !(flag & FlagNoScan) && typ != 0)
-		settype(s, v, typ);
-
-	if(raceenabled)
-		runtime·racemalloc(v, size);
-
-	if(runtime·debug.allocfreetrace)
-		runtime·tracealloc(v, size, typ);
-
-	if(!(flag & FlagNoProfiling) && (rate = runtime·MemProfileRate) > 0) {
-		if(size < rate && size < c->next_sample)
-			c->next_sample -= size;
-		else
-			profilealloc(v, size);
-	}
-
-	m->locks--;
-	if(m->locks == 0 && g->preempt)  // restore the preemption request in case we've cleared it in newstack
-		g->stackguard0 = StackPreempt;
-
-	if(!(flag & FlagNoInvokeGC) && mstats.heap_alloc >= mstats.next_gc)
-		runtime·gc(0);
-
-	return v;
-}
-
-static MSpan*
-largealloc(uint32 flag, uintptr *sizep)
-{
-	uintptr npages, size;
-	MSpan *s;
-	void *v;
-
-	// Allocate directly from heap.
-	size = *sizep;
-	if(size + PageSize < size)
-		runtime·throw("out of memory");
-	npages = size >> PageShift;
-	if((size & PageMask) != 0)
-		npages++;
-	s = runtime·MHeap_Alloc(&runtime·mheap, npages, 0, 1, !(flag & FlagNoZero));
-	if(s == nil)
-		runtime·throw("out of memory");
-	s->limit = (byte*)(s->start<<PageShift) + size;
-	*sizep = npages<<PageShift;
-	v = (void*)(s->start << PageShift);
-	// setup for mark sweep
-	runtime·markspan(v, 0, 0, true);
-	return s;
-}
-
-static void
-profilealloc(void *v, uintptr size)
-{
-	uintptr rate;
-	int32 next;
-	MCache *c;
-
-	c = m->mcache;
-	rate = runtime·MemProfileRate;
-	if(size < rate) {
-		// pick next profile time
-		// If you change this, also change allocmcache.
-		if(rate > 0x3fffffff)	// make 2*rate not overflow
-			rate = 0x3fffffff;
-		next = runtime·fastrand1() % (2*rate);
-		// Subtract the "remainder" of the current allocation.
-		// Otherwise objects that are close in size to sampling rate
-		// will be under-sampled, because we consistently discard this remainder.
-		next -= (size - c->next_sample);
-		if(next < 0)
-			next = 0;
-		c->next_sample = next;
-	}
-	runtime·MProf_Malloc(v, size);
-}
-
-void*
-runtime·malloc(uintptr size)
-{
-	return runtime·mallocgc(size, 0, FlagNoInvokeGC);
-}
-
-// Free the object whose base pointer is v.
-void
-runtime·free(void *v)
-{
-	int32 sizeclass;
-	MSpan *s;
-	MCache *c;
-	uintptr size;
-
-	if(v == nil)
-		return;
-	
-	// If you change this also change mgc0.c:/^sweep,
-	// which has a copy of the guts of free.
-
-	if(m->mallocing)
-		runtime·throw("malloc/free - deadlock");
-	m->mallocing = 1;
-
-	if(!runtime·mlookup(v, nil, nil, &s)) {
-		runtime·printf("free %p: not an allocated block\n", v);
-		runtime·throw("free runtime·mlookup");
-	}
-	size = s->elemsize;
-	sizeclass = s->sizeclass;
-	// Objects that are smaller than TinySize can be allocated using tiny alloc,
-	// if then such object is combined with an object with finalizer, we will crash.
-	if(size < TinySize)
-		runtime·throw("freeing too small block");
-
-	if(runtime·debug.allocfreetrace)
-		runtime·tracefree(v, size);
-
-	// Ensure that the span is swept.
-	// If we free into an unswept span, we will corrupt GC bitmaps.
-	runtime·MSpan_EnsureSwept(s);
-
-	if(s->specials != nil)
-		runtime·freeallspecials(s, v, size);
-
-	c = m->mcache;
-	if(sizeclass == 0) {
-		// Large object.
-		s->needzero = 1;
-		// Must mark v freed before calling unmarkspan and MHeap_Free:
-		// they might coalesce v into other spans and change the bitmap further.
-		runtime·markfreed(v);
-		runtime·unmarkspan(v, 1<<PageShift);
-		// NOTE(rsc,dvyukov): The original implementation of efence
-		// in CL 22060046 used SysFree instead of SysFault, so that
-		// the operating system would eventually give the memory
-		// back to us again, so that an efence program could run
-		// longer without running out of memory. Unfortunately,
-		// calling SysFree here without any kind of adjustment of the
-		// heap data structures means that when the memory does
-		// come back to us, we have the wrong metadata for it, either in
-		// the MSpan structures or in the garbage collection bitmap.
-		// Using SysFault here means that the program will run out of
-		// memory fairly quickly in efence mode, but at least it won't
-		// have mysterious crashes due to confused memory reuse.
-		// It should be possible to switch back to SysFree if we also 
-		// implement and then call some kind of MHeap_DeleteSpan.
-		if(runtime·debug.efence)
-			runtime·SysFault((void*)(s->start<<PageShift), size);
-		else
-			runtime·MHeap_Free(&runtime·mheap, s, 1);
-		c->local_nlargefree++;
-		c->local_largefree += size;
-	} else {
-		// Small object.
-		if(size > 2*sizeof(uintptr))
-			((uintptr*)v)[1] = (uintptr)0xfeedfeedfeedfeedll;	// mark as "needs to be zeroed"
-		else if(size > sizeof(uintptr))
-			((uintptr*)v)[1] = 0;
-		// Must mark v freed before calling MCache_Free:
-		// it might coalesce v and other blocks into a bigger span
-		// and change the bitmap further.
-		c->local_nsmallfree[sizeclass]++;
-		c->local_cachealloc -= size;
-		if(c->alloc[sizeclass] == s) {
-			// We own the span, so we can just add v to the freelist
-			runtime·markfreed(v);
-			((MLink*)v)->next = s->freelist;
-			s->freelist = v;
-			s->ref--;
-		} else {
-			// Someone else owns this span.  Add to free queue.
-			runtime·MCache_Free(c, v, sizeclass, size);
-		}
-	}
-	m->mallocing = 0;
-}
-
-int32
-runtime·mlookup(void *v, byte **base, uintptr *size, MSpan **sp)
-{
-	uintptr n, i;
-	byte *p;
-	MSpan *s;
-
-	m->mcache->local_nlookup++;
-	if (sizeof(void*) == 4 && m->mcache->local_nlookup >= (1<<30)) {
-		// purge cache stats to prevent overflow
-		runtime·lock(&runtime·mheap);
-		runtime·purgecachedstats(m->mcache);
-		runtime·unlock(&runtime·mheap);
-	}
-
-	s = runtime·MHeap_LookupMaybe(&runtime·mheap, v);
-	if(sp)
-		*sp = s;
-	if(s == nil) {
-		runtime·checkfreed(v, 1);
-		if(base)
-			*base = nil;
-		if(size)
-			*size = 0;
-		return 0;
-	}
-
-	p = (byte*)((uintptr)s->start<<PageShift);
-	if(s->sizeclass == 0) {
-		// Large object.
-		if(base)
-			*base = p;
-		if(size)
-			*size = s->npages<<PageShift;
-		return 1;
-	}
-
-	n = s->elemsize;
-	if(base) {
-		i = ((byte*)v - p)/n;
-		*base = p + i*n;
-	}
-	if(size)
-		*size = n;
-
-	return 1;
-}
-
-void
-runtime·purgecachedstats(MCache *c)
-{
-	MHeap *h;
-	int32 i;
-
-	// Protected by either heap or GC lock.
-	h = &runtime·mheap;
-	mstats.heap_alloc += c->local_cachealloc;
-	c->local_cachealloc = 0;
-	mstats.nlookup += c->local_nlookup;
-	c->local_nlookup = 0;
-	h->largefree += c->local_largefree;
-	c->local_largefree = 0;
-	h->nlargefree += c->local_nlargefree;
-	c->local_nlargefree = 0;
-	for(i=0; i<nelem(c->local_nsmallfree); i++) {
-		h->nsmallfree[i] += c->local_nsmallfree[i];
-		c->local_nsmallfree[i] = 0;
-	}
-}
-
-// Size of the trailing by_size array differs between Go and C,
-// NumSizeClasses was changed, but we can not change Go struct because of backward compatibility.
-// sizeof_C_MStats is what C thinks about size of Go struct.
-uintptr runtime·sizeof_C_MStats = sizeof(MStats) - (NumSizeClasses - 61) * sizeof(mstats.by_size[0]);
-
-#define MaxArena32 (2U<<30)
-
-void
-runtime·mallocinit(void)
-{
-	byte *p, *p1;
-	uintptr arena_size, bitmap_size, spans_size, p_size;
-	extern byte end[];
-	uintptr limit;
-	uint64 i;
-	bool reserved;
-
-	p = nil;
-	p_size = 0;
-	arena_size = 0;
-	bitmap_size = 0;
-	spans_size = 0;
-	reserved = false;
-
-	// for 64-bit build
-	USED(p);
-	USED(p_size);
-	USED(arena_size);
-	USED(bitmap_size);
-	USED(spans_size);
-
-	runtime·InitSizes();
-
-	if(runtime·class_to_size[TinySizeClass] != TinySize)
-		runtime·throw("bad TinySizeClass");
-
-	// limit = runtime·memlimit();
-	// See https://code.google.com/p/go/issues/detail?id=5049
-	// TODO(rsc): Fix after 1.1.
-	limit = 0;
-
-	// Set up the allocation arena, a contiguous area of memory where
-	// allocated data will be found.  The arena begins with a bitmap large
-	// enough to hold 4 bits per allocated word.
-	if(sizeof(void*) == 8 && (limit == 0 || limit > (1<<30))) {
-		// On a 64-bit machine, allocate from a single contiguous reservation.
-		// 128 GB (MaxMem) should be big enough for now.
-		//
-		// The code will work with the reservation at any address, but ask
-		// SysReserve to use 0x0000XXc000000000 if possible (XX=00...7f).
-		// Allocating a 128 GB region takes away 37 bits, and the amd64
-		// doesn't let us choose the top 17 bits, so that leaves the 11 bits
-		// in the middle of 0x00c0 for us to choose.  Choosing 0x00c0 means
-		// that the valid memory addresses will begin 0x00c0, 0x00c1, ..., 0x00df.
-		// In little-endian, that's c0 00, c1 00, ..., df 00. None of those are valid
-		// UTF-8 sequences, and they are otherwise as far away from 
-		// ff (likely a common byte) as possible.  If that fails, we try other 0xXXc0
-		// addresses.  An earlier attempt to use 0x11f8 caused out of memory errors
-		// on OS X during thread allocations.  0x00c0 causes conflicts with
-		// AddressSanitizer which reserves all memory up to 0x0100.
-		// These choices are both for debuggability and to reduce the
-		// odds of the conservative garbage collector not collecting memory
-		// because some non-pointer block of memory had a bit pattern
-		// that matched a memory address.
-		//
-		// Actually we reserve 136 GB (because the bitmap ends up being 8 GB)
-		// but it hardly matters: e0 00 is not valid UTF-8 either.
-		//
-		// If this fails we fall back to the 32 bit memory mechanism
-		arena_size = MaxMem;
-		bitmap_size = arena_size / (sizeof(void*)*8/4);
-		spans_size = arena_size / PageSize * sizeof(runtime·mheap.spans[0]);
-		spans_size = ROUND(spans_size, PageSize);
-		for(i = 0; i <= 0x7f; i++) {
-			p = (void*)(i<<40 | 0x00c0ULL<<32);
-			p_size = bitmap_size + spans_size + arena_size + PageSize;
-			p = runtime·SysReserve(p, p_size, &reserved);
-			if(p != nil)
-				break;
-		}
-	}
-	if (p == nil) {
-		// On a 32-bit machine, we can't typically get away
-		// with a giant virtual address space reservation.
-		// Instead we map the memory information bitmap
-		// immediately after the data segment, large enough
-		// to handle another 2GB of mappings (256 MB),
-		// along with a reservation for another 512 MB of memory.
-		// When that gets used up, we'll start asking the kernel
-		// for any memory anywhere and hope it's in the 2GB
-		// following the bitmap (presumably the executable begins
-		// near the bottom of memory, so we'll have to use up
-		// most of memory before the kernel resorts to giving out
-		// memory before the beginning of the text segment).
-		//
-		// Alternatively we could reserve 512 MB bitmap, enough
-		// for 4GB of mappings, and then accept any memory the
-		// kernel threw at us, but normally that's a waste of 512 MB
-		// of address space, which is probably too much in a 32-bit world.
-		bitmap_size = MaxArena32 / (sizeof(void*)*8/4);
-		arena_size = 512<<20;
-		spans_size = MaxArena32 / PageSize * sizeof(runtime·mheap.spans[0]);
-		if(limit > 0 && arena_size+bitmap_size+spans_size > limit) {
-			bitmap_size = (limit / 9) & ~((1<<PageShift) - 1);
-			arena_size = bitmap_size * 8;
-			spans_size = arena_size / PageSize * sizeof(runtime·mheap.spans[0]);
-		}
-		spans_size = ROUND(spans_size, PageSize);
-
-		// SysReserve treats the address we ask for, end, as a hint,
-		// not as an absolute requirement.  If we ask for the end
-		// of the data segment but the operating system requires
-		// a little more space before we can start allocating, it will
-		// give out a slightly higher pointer.  Except QEMU, which
-		// is buggy, as usual: it won't adjust the pointer upward.
-		// So adjust it upward a little bit ourselves: 1/4 MB to get
-		// away from the running binary image and then round up
-		// to a MB boundary.
-		p = (byte*)ROUND((uintptr)end + (1<<18), 1<<20);
-		p_size = bitmap_size + spans_size + arena_size + PageSize;
-		p = runtime·SysReserve(p, p_size, &reserved);
-		if(p == nil)
-			runtime·throw("runtime: cannot reserve arena virtual address space");
-	}
-
-	// PageSize can be larger than OS definition of page size,
-	// so SysReserve can give us a PageSize-unaligned pointer.
-	// To overcome this we ask for PageSize more and round up the pointer.
-	p1 = (byte*)ROUND((uintptr)p, PageSize);
-
-	runtime·mheap.spans = (MSpan**)p1;
-	runtime·mheap.bitmap = p1 + spans_size;
-	runtime·mheap.arena_start = p1 + spans_size + bitmap_size;
-	runtime·mheap.arena_used = runtime·mheap.arena_start;
-	runtime·mheap.arena_end = p + p_size;
-	runtime·mheap.arena_reserved = reserved;
-
-	if(((uintptr)runtime·mheap.arena_start & (PageSize-1)) != 0)
-		runtime·throw("misrounded allocation in mallocinit");
-
-	// Initialize the rest of the allocator.	
-	runtime·MHeap_Init(&runtime·mheap);
-	m->mcache = runtime·allocmcache();
-
-	// See if it works.
-	runtime·free(runtime·malloc(TinySize));
-}
-
-void*
-runtime·MHeap_SysAlloc(MHeap *h, uintptr n)
-{
-	byte *p, *p_end;
-	uintptr p_size;
-	bool reserved;
-
-	if(n > h->arena_end - h->arena_used) {
-		// We are in 32-bit mode, maybe we didn't use all possible address space yet.
-		// Reserve some more space.
-		byte *new_end;
-
-		p_size = ROUND(n + PageSize, 256<<20);
-		new_end = h->arena_end + p_size;
-		if(new_end <= h->arena_start + MaxArena32) {
-			// TODO: It would be bad if part of the arena
-			// is reserved and part is not.
-			p = runtime·SysReserve(h->arena_end, p_size, &reserved);
-			if(p == h->arena_end) {
-				h->arena_end = new_end;
-				h->arena_reserved = reserved;
-			}
-			else if(p+p_size <= h->arena_start + MaxArena32) {
-				// Keep everything page-aligned.
-				// Our pages are bigger than hardware pages.
-				h->arena_end = p+p_size;
-				h->arena_used = p + (-(uintptr)p&(PageSize-1));
-				h->arena_reserved = reserved;
-			} else {
-				uint64 stat;
-				stat = 0;
-				runtime·SysFree(p, p_size, &stat);
-			}
-		}
-	}
-	if(n <= h->arena_end - h->arena_used) {
-		// Keep taking from our reservation.
-		p = h->arena_used;
-		runtime·SysMap(p, n, h->arena_reserved, &mstats.heap_sys);
-		h->arena_used += n;
-		runtime·MHeap_MapBits(h);
-		runtime·MHeap_MapSpans(h);
-		if(raceenabled)
-			runtime·racemapshadow(p, n);
-		
-		if(((uintptr)p & (PageSize-1)) != 0)
-			runtime·throw("misrounded allocation in MHeap_SysAlloc");
-		return p;
-	}
-	
-	// If using 64-bit, our reservation is all we have.
-	if(h->arena_end - h->arena_start >= MaxArena32)
-		return nil;
-
-	// On 32-bit, once the reservation is gone we can
-	// try to get memory at a location chosen by the OS
-	// and hope that it is in the range we allocated bitmap for.
-	p_size = ROUND(n, PageSize) + PageSize;
-	p = runtime·SysAlloc(p_size, &mstats.heap_sys);
-	if(p == nil)
-		return nil;
-
-	if(p < h->arena_start || p+p_size - h->arena_start >= MaxArena32) {
-		runtime·printf("runtime: memory allocated by OS (%p) not in usable range [%p,%p)\n",
-			p, h->arena_start, h->arena_start+MaxArena32);
-		runtime·SysFree(p, p_size, &mstats.heap_sys);
-		return nil;
-	}
-	
-	p_end = p + p_size;
-	p += -(uintptr)p & (PageSize-1);
-	if(p+n > h->arena_used) {
-		h->arena_used = p+n;
-		if(p_end > h->arena_end)
-			h->arena_end = p_end;
-		runtime·MHeap_MapBits(h);
-		runtime·MHeap_MapSpans(h);
-		if(raceenabled)
-			runtime·racemapshadow(p, n);
-	}
-	
-	if(((uintptr)p & (PageSize-1)) != 0)
-		runtime·throw("misrounded allocation in MHeap_SysAlloc");
-	return p;
-}
-
-static struct
-{
-	Lock;
-	byte*	pos;
-	byte*	end;
-} persistent;
-
-enum
-{
-	PersistentAllocChunk	= 256<<10,
-	PersistentAllocMaxBlock	= 64<<10,  // VM reservation granularity is 64K on windows
-};
-
-// Wrapper around SysAlloc that can allocate small chunks.
-// There is no associated free operation.
-// Intended for things like function/type/debug-related persistent data.
-// If align is 0, uses default align (currently 8).
-void*
-runtime·persistentalloc(uintptr size, uintptr align, uint64 *stat)
-{
-	byte *p;
-
-	if(align != 0) {
-		if(align&(align-1))
-			runtime·throw("persistentalloc: align is not a power of 2");
-		if(align > PageSize)
-			runtime·throw("persistentalloc: align is too large");
-	} else
-		align = 8;
-	if(size >= PersistentAllocMaxBlock)
-		return runtime·SysAlloc(size, stat);
-	runtime·lock(&persistent);
-	persistent.pos = (byte*)ROUND((uintptr)persistent.pos, align);
-	if(persistent.pos + size > persistent.end) {
-		persistent.pos = runtime·SysAlloc(PersistentAllocChunk, &mstats.other_sys);
-		if(persistent.pos == nil) {
-			runtime·unlock(&persistent);
-			runtime·throw("runtime: cannot allocate memory");
-		}
-		persistent.end = persistent.pos + PersistentAllocChunk;
-	}
-	p = persistent.pos;
-	persistent.pos += size;
-	runtime·unlock(&persistent);
-	if(stat != &mstats.other_sys) {
-		// reaccount the allocation against provided stat
-		runtime·xadd64(stat, size);
-		runtime·xadd64(&mstats.other_sys, -(uint64)size);
-	}
-	return p;
-}
-
-static void
-settype(MSpan *s, void *v, uintptr typ)
-{
-	uintptr size, ofs, j, t;
-	uintptr ntypes, nbytes2, nbytes3;
-	uintptr *data2;
-	byte *data3;
-
-	if(s->sizeclass == 0) {
-		s->types.compression = MTypes_Single;
-		s->types.data = typ;
-		return;
-	}
-	size = s->elemsize;
-	ofs = ((uintptr)v - (s->start<<PageShift)) / size;
-
-	switch(s->types.compression) {
-	case MTypes_Empty:
-		ntypes = (s->npages << PageShift) / size;
-		nbytes3 = 8*sizeof(uintptr) + 1*ntypes;
-		data3 = runtime·mallocgc(nbytes3, 0, FlagNoProfiling|FlagNoScan|FlagNoInvokeGC);
-		s->types.compression = MTypes_Bytes;
-		s->types.data = (uintptr)data3;
-		((uintptr*)data3)[1] = typ;
-		data3[8*sizeof(uintptr) + ofs] = 1;
-		break;
-		
-	case MTypes_Words:
-		((uintptr*)s->types.data)[ofs] = typ;
-		break;
-		
-	case MTypes_Bytes:
-		data3 = (byte*)s->types.data;
-		for(j=1; j<8; j++) {
-			if(((uintptr*)data3)[j] == typ) {
-				break;
-			}
-			if(((uintptr*)data3)[j] == 0) {
-				((uintptr*)data3)[j] = typ;
-				break;
-			}
-		}
-		if(j < 8) {
-			data3[8*sizeof(uintptr) + ofs] = j;
-		} else {
-			ntypes = (s->npages << PageShift) / size;
-			nbytes2 = ntypes * sizeof(uintptr);
-			data2 = runtime·mallocgc(nbytes2, 0, FlagNoProfiling|FlagNoScan|FlagNoInvokeGC);
-			s->types.compression = MTypes_Words;
-			s->types.data = (uintptr)data2;
-			
-			// Move the contents of data3 to data2. Then deallocate data3.
-			for(j=0; j<ntypes; j++) {
-				t = data3[8*sizeof(uintptr) + j];
-				t = ((uintptr*)data3)[t];
-				data2[j] = t;
-			}
-			data2[ofs] = typ;
-		}
-		break;
-	}
-}
-
-uintptr
-runtime·gettype(void *v)
-{
-	MSpan *s;
-	uintptr t, ofs;
-	byte *data;
-
-	s = runtime·MHeap_LookupMaybe(&runtime·mheap, v);
-	if(s != nil) {
-		t = 0;
-		switch(s->types.compression) {
-		case MTypes_Empty:
-			break;
-		case MTypes_Single:
-			t = s->types.data;
-			break;
-		case MTypes_Words:
-			ofs = (uintptr)v - (s->start<<PageShift);
-			t = ((uintptr*)s->types.data)[ofs/s->elemsize];
-			break;
-		case MTypes_Bytes:
-			ofs = (uintptr)v - (s->start<<PageShift);
-			data = (byte*)s->types.data;
-			t = data[8*sizeof(uintptr) + ofs/s->elemsize];
-			t = ((uintptr*)data)[t];
-			break;
-		default:
-			runtime·throw("runtime·gettype: invalid compression kind");
-		}
-		if(0) {
-			runtime·printf("%p -> %d,%X\n", v, (int32)s->types.compression, (int64)t);
-		}
-		return t;
-	}
-	return 0;
-}
-
-// Runtime stubs.
-
-void*
-runtime·mal(uintptr n)
-{
-	return runtime·mallocgc(n, 0, 0);
-}
-
-#pragma textflag NOSPLIT
-func new(typ *Type) (ret *uint8) {
-	ret = runtime·mallocgc(typ->size, (uintptr)typ | TypeInfo_SingleObject, typ->kind&KindNoPointers ? FlagNoScan : 0);
-}
-
-static void*
-cnew(Type *typ, intgo n, int32 objtyp)
-{
-	if((objtyp&(PtrSize-1)) != objtyp)
-		runtime·throw("runtime: invalid objtyp");
-	if(n < 0 || (typ->size > 0 && n > MaxMem/typ->size))
-		runtime·panicstring("runtime: allocation size out of range");
-	return runtime·mallocgc(typ->size*n, (uintptr)typ | objtyp, typ->kind&KindNoPointers ? FlagNoScan : 0);
-}
-
-// same as runtime·new, but callable from C
-void*
-runtime·cnew(Type *typ)
-{
-	return cnew(typ, 1, TypeInfo_SingleObject);
-}
-
-void*
-runtime·cnewarray(Type *typ, intgo n)
-{
-	return cnew(typ, n, TypeInfo_Array);
-}
-
-func GC() {
-	runtime·gc(2);  // force GC and do eager sweep
-}
-
-func SetFinalizer(obj Eface, finalizer Eface) {
-	byte *base;
-	uintptr size;
-	FuncType *ft;
-	int32 i;
-	uintptr nret;
-	Type *t;
-	Type *fint;
-	PtrType *ot;
-	Iface iface;
-
-	if(obj.type == nil) {
-		runtime·printf("runtime.SetFinalizer: first argument is nil interface\n");
-		goto throw;
-	}
-	if(obj.type->kind != KindPtr) {
-		runtime·printf("runtime.SetFinalizer: first argument is %S, not pointer\n", *obj.type->string);
-		goto throw;
-	}
-	ot = (PtrType*)obj.type;
-	// As an implementation detail we do not run finalizers for zero-sized objects,
-	// because we use &runtime·zerobase for all such allocations.
-	if(ot->elem != nil && ot->elem->size == 0)
-		return;
-	// The following check is required for cases when a user passes a pointer to composite literal,
-	// but compiler makes it a pointer to global. For example:
-	//	var Foo = &Object{}
-	//	func main() {
-	//		runtime.SetFinalizer(Foo, nil)
-	//	}
-	// See issue 7656.
-	if((byte*)obj.data < runtime·mheap.arena_start || runtime·mheap.arena_used <= (byte*)obj.data)
-		return;
-	if(!runtime·mlookup(obj.data, &base, &size, nil) || obj.data != base) {
-		// As an implementation detail we allow to set finalizers for an inner byte
-		// of an object if it could come from tiny alloc (see mallocgc for details).
-		if(ot->elem == nil || (ot->elem->kind&KindNoPointers) == 0 || ot->elem->size >= TinySize) {
-			runtime·printf("runtime.SetFinalizer: pointer not at beginning of allocated block (%p)\n", obj.data);
-			goto throw;
-		}
-	}
-	if(finalizer.type != nil) {
-		runtime·createfing();
-		if(finalizer.type->kind != KindFunc)
-			goto badfunc;
-		ft = (FuncType*)finalizer.type;
-		if(ft->dotdotdot || ft->in.len != 1)
-			goto badfunc;
-		fint = *(Type**)ft->in.array;
-		if(fint == obj.type) {
-			// ok - same type
-		} else if(fint->kind == KindPtr && (fint->x == nil || fint->x->name == nil || obj.type->x == nil || obj.type->x->name == nil) && ((PtrType*)fint)->elem == ((PtrType*)obj.type)->elem) {
-			// ok - not same type, but both pointers,
-			// one or the other is unnamed, and same element type, so assignable.
-		} else if(fint->kind == KindInterface && ((InterfaceType*)fint)->mhdr.len == 0) {
-			// ok - satisfies empty interface
-		} else if(fint->kind == KindInterface && runtime·ifaceE2I2((InterfaceType*)fint, obj, &iface)) {
-			// ok - satisfies non-empty interface
-		} else
-			goto badfunc;
-
-		// compute size needed for return parameters
-		nret = 0;
-		for(i=0; i<ft->out.len; i++) {
-			t = ((Type**)ft->out.array)[i];
-			nret = ROUND(nret, t->align) + t->size;
-		}
-		nret = ROUND(nret, sizeof(void*));
-		ot = (PtrType*)obj.type;
-		if(!runtime·addfinalizer(obj.data, finalizer.data, nret, fint, ot)) {
-			runtime·printf("runtime.SetFinalizer: finalizer already set\n");
-			goto throw;
-		}
-	} else {
-		// NOTE: asking to remove a finalizer when there currently isn't one set is OK.
-		runtime·removefinalizer(obj.data);
-	}
-	return;
-
-badfunc:
-	runtime·printf("runtime.SetFinalizer: cannot pass %S to finalizer %S\n", *obj.type->string, *finalizer.type->string);
-throw:
-	runtime·throw("runtime.SetFinalizer");
-}
diff --git a/src/pkg/runtime/malloc.h b/src/pkg/runtime/malloc.h
deleted file mode 100644
index 798c130..0000000
--- a/src/pkg/runtime/malloc.h
+++ /dev/null
@@ -1,643 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Memory allocator, based on tcmalloc.
-// http://goog-perftools.sourceforge.net/doc/tcmalloc.html
-
-// The main allocator works in runs of pages.
-// Small allocation sizes (up to and including 32 kB) are
-// rounded to one of about 100 size classes, each of which
-// has its own free list of objects of exactly that size.
-// Any free page of memory can be split into a set of objects
-// of one size class, which are then managed using free list
-// allocators.
-//
-// The allocator's data structures are:
-//
-//	FixAlloc: a free-list allocator for fixed-size objects,
-//		used to manage storage used by the allocator.
-//	MHeap: the malloc heap, managed at page (4096-byte) granularity.
-//	MSpan: a run of pages managed by the MHeap.
-//	MCentral: a shared free list for a given size class.
-//	MCache: a per-thread (in Go, per-P) cache for small objects.
-//	MStats: allocation statistics.
-//
-// Allocating a small object proceeds up a hierarchy of caches:
-//
-//	1. Round the size up to one of the small size classes
-//	   and look in the corresponding MCache free list.
-//	   If the list is not empty, allocate an object from it.
-//	   This can all be done without acquiring a lock.
-//
-//	2. If the MCache free list is empty, replenish it by
-//	   taking a bunch of objects from the MCentral free list.
-//	   Moving a bunch amortizes the cost of acquiring the MCentral lock.
-//
-//	3. If the MCentral free list is empty, replenish it by
-//	   allocating a run of pages from the MHeap and then
-//	   chopping that memory into a objects of the given size.
-//	   Allocating many objects amortizes the cost of locking
-//	   the heap.
-//
-//	4. If the MHeap is empty or has no page runs large enough,
-//	   allocate a new group of pages (at least 1MB) from the
-//	   operating system.  Allocating a large run of pages
-//	   amortizes the cost of talking to the operating system.
-//
-// Freeing a small object proceeds up the same hierarchy:
-//
-//	1. Look up the size class for the object and add it to
-//	   the MCache free list.
-//
-//	2. If the MCache free list is too long or the MCache has
-//	   too much memory, return some to the MCentral free lists.
-//
-//	3. If all the objects in a given span have returned to
-//	   the MCentral list, return that span to the page heap.
-//
-//	4. If the heap has too much memory, return some to the
-//	   operating system.
-//
-//	TODO(rsc): Step 4 is not implemented.
-//
-// Allocating and freeing a large object uses the page heap
-// directly, bypassing the MCache and MCentral free lists.
-//
-// The small objects on the MCache and MCentral free lists
-// may or may not be zeroed.  They are zeroed if and only if
-// the second word of the object is zero.  A span in the
-// page heap is zeroed unless s->needzero is set. When a span
-// is allocated to break into small objects, it is zeroed if needed
-// and s->needzero is set. There are two main benefits to delaying the
-// zeroing this way:
-//
-//	1. stack frames allocated from the small object lists
-//	   or the page heap can avoid zeroing altogether.
-//	2. the cost of zeroing when reusing a small object is
-//	   charged to the mutator, not the garbage collector.
-//
-// This C code was written with an eye toward translating to Go
-// in the future.  Methods have the form Type_Method(Type *t, ...).
-
-typedef struct MCentral	MCentral;
-typedef struct MHeap	MHeap;
-typedef struct MSpan	MSpan;
-typedef struct MStats	MStats;
-typedef struct MLink	MLink;
-typedef struct MTypes	MTypes;
-typedef struct GCStats	GCStats;
-
-enum
-{
-	PageShift	= 13,
-	PageSize	= 1<<PageShift,
-	PageMask	= PageSize - 1,
-};
-typedef	uintptr	PageID;		// address >> PageShift
-
-enum
-{
-	// Computed constant.  The definition of MaxSmallSize and the
-	// algorithm in msize.c produce some number of different allocation
-	// size classes.  NumSizeClasses is that number.  It's needed here
-	// because there are static arrays of this length; when msize runs its
-	// size choosing algorithm it double-checks that NumSizeClasses agrees.
-	NumSizeClasses = 67,
-
-	// Tunable constants.
-	MaxSmallSize = 32<<10,
-
-	// Tiny allocator parameters, see "Tiny allocator" comment in malloc.goc.
-	TinySize = 16,
-	TinySizeClass = 2,
-
-	FixAllocChunk = 16<<10,		// Chunk size for FixAlloc
-	MaxMHeapList = 1<<(20 - PageShift),	// Maximum page length for fixed-size list in MHeap.
-	HeapAllocChunk = 1<<20,		// Chunk size for heap growth
-
-	// Number of bits in page to span calculations (4k pages).
-	// On Windows 64-bit we limit the arena to 32GB or 35 bits (see below for reason).
-	// On other 64-bit platforms, we limit the arena to 128GB, or 37 bits.
-	// On 32-bit, we don't bother limiting anything, so we use the full 32-bit address.
-#ifdef _64BIT
-#ifdef GOOS_windows
-	// Windows counts memory used by page table into committed memory
-	// of the process, so we can't reserve too much memory.
-	// See http://golang.org/issue/5402 and http://golang.org/issue/5236.
-	MHeapMap_Bits = 35 - PageShift,
-#else
-	MHeapMap_Bits = 37 - PageShift,
-#endif
-#else
-	MHeapMap_Bits = 32 - PageShift,
-#endif
-
-	// Max number of threads to run garbage collection.
-	// 2, 3, and 4 are all plausible maximums depending
-	// on the hardware details of the machine.  The garbage
-	// collector scales well to 8 cpus.
-	MaxGcproc = 8,
-};
-
-// Maximum memory allocation size, a hint for callers.
-// This must be a #define instead of an enum because it
-// is so large.
-#ifdef _64BIT
-#define	MaxMem	(1ULL<<(MHeapMap_Bits+PageShift))	/* 128 GB or 32 GB */
-#else
-#define	MaxMem	((uintptr)-1)
-#endif
-
-// A generic linked list of blocks.  (Typically the block is bigger than sizeof(MLink).)
-struct MLink
-{
-	MLink *next;
-};
-
-// SysAlloc obtains a large chunk of zeroed memory from the
-// operating system, typically on the order of a hundred kilobytes
-// or a megabyte.
-// NOTE: SysAlloc returns OS-aligned memory, but the heap allocator
-// may use larger alignment, so the caller must be careful to realign the
-// memory obtained by SysAlloc.
-//
-// SysUnused notifies the operating system that the contents
-// of the memory region are no longer needed and can be reused
-// for other purposes.
-// SysUsed notifies the operating system that the contents
-// of the memory region are needed again.
-//
-// SysFree returns it unconditionally; this is only used if
-// an out-of-memory error has been detected midway through
-// an allocation.  It is okay if SysFree is a no-op.
-//
-// SysReserve reserves address space without allocating memory.
-// If the pointer passed to it is non-nil, the caller wants the
-// reservation there, but SysReserve can still choose another
-// location if that one is unavailable.  On some systems and in some
-// cases SysReserve will simply check that the address space is
-// available and not actually reserve it.  If SysReserve returns
-// non-nil, it sets *reserved to true if the address space is
-// reserved, false if it has merely been checked.
-// NOTE: SysReserve returns OS-aligned memory, but the heap allocator
-// may use larger alignment, so the caller must be careful to realign the
-// memory obtained by SysAlloc.
-//
-// SysMap maps previously reserved address space for use.
-// The reserved argument is true if the address space was really
-// reserved, not merely checked.
-//
-// SysFault marks a (already SysAlloc'd) region to fault
-// if accessed.  Used only for debugging the runtime.
-
-void*	runtime·SysAlloc(uintptr nbytes, uint64 *stat);
-void	runtime·SysFree(void *v, uintptr nbytes, uint64 *stat);
-void	runtime·SysUnused(void *v, uintptr nbytes);
-void	runtime·SysUsed(void *v, uintptr nbytes);
-void	runtime·SysMap(void *v, uintptr nbytes, bool reserved, uint64 *stat);
-void*	runtime·SysReserve(void *v, uintptr nbytes, bool *reserved);
-void	runtime·SysFault(void *v, uintptr nbytes);
-
-// FixAlloc is a simple free-list allocator for fixed size objects.
-// Malloc uses a FixAlloc wrapped around SysAlloc to manages its
-// MCache and MSpan objects.
-//
-// Memory returned by FixAlloc_Alloc is not zeroed.
-// The caller is responsible for locking around FixAlloc calls.
-// Callers can keep state in the object but the first word is
-// smashed by freeing and reallocating.
-struct FixAlloc
-{
-	uintptr	size;
-	void	(*first)(void *arg, byte *p);	// called first time p is returned
-	void*	arg;
-	MLink*	list;
-	byte*	chunk;
-	uint32	nchunk;
-	uintptr	inuse;	// in-use bytes now
-	uint64*	stat;
-};
-
-void	runtime·FixAlloc_Init(FixAlloc *f, uintptr size, void (*first)(void*, byte*), void *arg, uint64 *stat);
-void*	runtime·FixAlloc_Alloc(FixAlloc *f);
-void	runtime·FixAlloc_Free(FixAlloc *f, void *p);
-
-
-// Statistics.
-// Shared with Go: if you edit this structure, also edit type MemStats in mem.go.
-struct MStats
-{
-	// General statistics.
-	uint64	alloc;		// bytes allocated and still in use
-	uint64	total_alloc;	// bytes allocated (even if freed)
-	uint64	sys;		// bytes obtained from system (should be sum of xxx_sys below, no locking, approximate)
-	uint64	nlookup;	// number of pointer lookups
-	uint64	nmalloc;	// number of mallocs
-	uint64	nfree;  // number of frees
-
-	// Statistics about malloc heap.
-	// protected by mheap.Lock
-	uint64	heap_alloc;	// bytes allocated and still in use
-	uint64	heap_sys;	// bytes obtained from system
-	uint64	heap_idle;	// bytes in idle spans
-	uint64	heap_inuse;	// bytes in non-idle spans
-	uint64	heap_released;	// bytes released to the OS
-	uint64	heap_objects;	// total number of allocated objects
-
-	// Statistics about allocation of low-level fixed-size structures.
-	// Protected by FixAlloc locks.
-	uint64	stacks_inuse;	// bootstrap stacks
-	uint64	stacks_sys;
-	uint64	mspan_inuse;	// MSpan structures
-	uint64	mspan_sys;
-	uint64	mcache_inuse;	// MCache structures
-	uint64	mcache_sys;
-	uint64	buckhash_sys;	// profiling bucket hash table
-	uint64	gc_sys;
-	uint64	other_sys;
-
-	// Statistics about garbage collector.
-	// Protected by mheap or stopping the world during GC.
-	uint64	next_gc;	// next GC (in heap_alloc time)
-	uint64  last_gc;	// last GC (in absolute time)
-	uint64	pause_total_ns;
-	uint64	pause_ns[256];
-	uint32	numgc;
-	bool	enablegc;
-	bool	debuggc;
-
-	// Statistics about allocation size classes.
-	struct {
-		uint32 size;
-		uint64 nmalloc;
-		uint64 nfree;
-	} by_size[NumSizeClasses];
-};
-
-#define mstats runtime·memStats
-extern MStats mstats;
-void	runtime·updatememstats(GCStats *stats);
-
-// Size classes.  Computed and initialized by InitSizes.
-//
-// SizeToClass(0 <= n <= MaxSmallSize) returns the size class,
-//	1 <= sizeclass < NumSizeClasses, for n.
-//	Size class 0 is reserved to mean "not small".
-//
-// class_to_size[i] = largest size in class i
-// class_to_allocnpages[i] = number of pages to allocate when
-//	making new objects in class i
-
-int32	runtime·SizeToClass(int32);
-uintptr	runtime·roundupsize(uintptr);
-extern	int32	runtime·class_to_size[NumSizeClasses];
-extern	int32	runtime·class_to_allocnpages[NumSizeClasses];
-extern	int8	runtime·size_to_class8[1024/8 + 1];
-extern	int8	runtime·size_to_class128[(MaxSmallSize-1024)/128 + 1];
-extern	void	runtime·InitSizes(void);
-
-
-typedef struct MCacheList MCacheList;
-struct MCacheList
-{
-	MLink *list;
-	uint32 nlist;
-};
-
-// Per-thread (in Go, per-P) cache for small objects.
-// No locking needed because it is per-thread (per-P).
-struct MCache
-{
-	// The following members are accessed on every malloc,
-	// so they are grouped here for better caching.
-	int32 next_sample;		// trigger heap sample after allocating this many bytes
-	intptr local_cachealloc;	// bytes allocated (or freed) from cache since last lock of heap
-	// Allocator cache for tiny objects w/o pointers.
-	// See "Tiny allocator" comment in malloc.goc.
-	byte*	tiny;
-	uintptr	tinysize;
-	// The rest is not accessed on every malloc.
-	MSpan*	alloc[NumSizeClasses];	// spans to allocate from
-	MCacheList free[NumSizeClasses];// lists of explicitly freed objects
-	// Local allocator stats, flushed during GC.
-	uintptr local_nlookup;		// number of pointer lookups
-	uintptr local_largefree;	// bytes freed for large objects (>MaxSmallSize)
-	uintptr local_nlargefree;	// number of frees for large objects (>MaxSmallSize)
-	uintptr local_nsmallfree[NumSizeClasses];	// number of frees for small objects (<=MaxSmallSize)
-};
-
-MSpan*	runtime·MCache_Refill(MCache *c, int32 sizeclass);
-void	runtime·MCache_Free(MCache *c, MLink *p, int32 sizeclass, uintptr size);
-void	runtime·MCache_ReleaseAll(MCache *c);
-
-// MTypes describes the types of blocks allocated within a span.
-// The compression field describes the layout of the data.
-//
-// MTypes_Empty:
-//     All blocks are free, or no type information is available for
-//     allocated blocks.
-//     The data field has no meaning.
-// MTypes_Single:
-//     The span contains just one block.
-//     The data field holds the type information.
-//     The sysalloc field has no meaning.
-// MTypes_Words:
-//     The span contains multiple blocks.
-//     The data field points to an array of type [NumBlocks]uintptr,
-//     and each element of the array holds the type of the corresponding
-//     block.
-// MTypes_Bytes:
-//     The span contains at most seven different types of blocks.
-//     The data field points to the following structure:
-//         struct {
-//             type  [8]uintptr       // type[0] is always 0
-//             index [NumBlocks]byte
-//         }
-//     The type of the i-th block is: data.type[data.index[i]]
-enum
-{
-	MTypes_Empty = 0,
-	MTypes_Single = 1,
-	MTypes_Words = 2,
-	MTypes_Bytes = 3,
-};
-struct MTypes
-{
-	byte	compression;	// one of MTypes_*
-	uintptr	data;
-};
-
-enum
-{
-	KindSpecialFinalizer = 1,
-	KindSpecialProfile = 2,
-	// Note: The finalizer special must be first because if we're freeing
-	// an object, a finalizer special will cause the freeing operation
-	// to abort, and we want to keep the other special records around
-	// if that happens.
-};
-
-typedef struct Special Special;
-struct Special
-{
-	Special*	next;	// linked list in span
-	uint16		offset;	// span offset of object
-	byte		kind;	// kind of Special
-};
-
-// The described object has a finalizer set for it.
-typedef struct SpecialFinalizer SpecialFinalizer;
-struct SpecialFinalizer
-{
-	Special;
-	FuncVal*	fn;
-	uintptr		nret;
-	Type*		fint;
-	PtrType*	ot;
-};
-
-// The described object is being heap profiled.
-typedef struct Bucket Bucket; // from mprof.goc
-typedef struct SpecialProfile SpecialProfile;
-struct SpecialProfile
-{
-	Special;
-	Bucket*	b;
-};
-
-// An MSpan is a run of pages.
-enum
-{
-	MSpanInUse = 0,
-	MSpanFree,
-	MSpanListHead,
-	MSpanDead,
-};
-struct MSpan
-{
-	MSpan	*next;		// in a span linked list
-	MSpan	*prev;		// in a span linked list
-	PageID	start;		// starting page number
-	uintptr	npages;		// number of pages in span
-	MLink	*freelist;	// list of free objects
-	// sweep generation:
-	// if sweepgen == h->sweepgen - 2, the span needs sweeping
-	// if sweepgen == h->sweepgen - 1, the span is currently being swept
-	// if sweepgen == h->sweepgen, the span is swept and ready to use
-	// h->sweepgen is incremented by 2 after every GC
-	uint32	sweepgen;
-	uint16	ref;		// capacity - number of objects in freelist
-	uint8	sizeclass;	// size class
-	bool	incache;	// being used by an MCache
-	uint8	state;		// MSpanInUse etc
-	uint8	needzero;	// needs to be zeroed before allocation
-	uintptr	elemsize;	// computed from sizeclass or from npages
-	int64   unusedsince;	// First time spotted by GC in MSpanFree state
-	uintptr npreleased;	// number of pages released to the OS
-	byte	*limit;		// end of data in span
-	MTypes	types;		// types of allocated objects in this span
-	Lock	specialLock;	// guards specials list
-	Special	*specials;	// linked list of special records sorted by offset.
-	MLink	*freebuf;	// objects freed explicitly, not incorporated into freelist yet
-};
-
-void	runtime·MSpan_Init(MSpan *span, PageID start, uintptr npages);
-void	runtime·MSpan_EnsureSwept(MSpan *span);
-bool	runtime·MSpan_Sweep(MSpan *span);
-
-// Every MSpan is in one doubly-linked list,
-// either one of the MHeap's free lists or one of the
-// MCentral's span lists.  We use empty MSpan structures as list heads.
-void	runtime·MSpanList_Init(MSpan *list);
-bool	runtime·MSpanList_IsEmpty(MSpan *list);
-void	runtime·MSpanList_Insert(MSpan *list, MSpan *span);
-void	runtime·MSpanList_InsertBack(MSpan *list, MSpan *span);
-void	runtime·MSpanList_Remove(MSpan *span);	// from whatever list it is in
-
-
-// Central list of free objects of a given size.
-struct MCentral
-{
-	Lock;
-	int32 sizeclass;
-	MSpan nonempty;	// list of spans with a free object
-	MSpan empty;	// list of spans with no free objects (or cached in an MCache)
-	int32 nfree;	// # of objects available in nonempty spans
-};
-
-void	runtime·MCentral_Init(MCentral *c, int32 sizeclass);
-MSpan*	runtime·MCentral_CacheSpan(MCentral *c);
-void	runtime·MCentral_UncacheSpan(MCentral *c, MSpan *s);
-bool	runtime·MCentral_FreeSpan(MCentral *c, MSpan *s, int32 n, MLink *start, MLink *end);
-void	runtime·MCentral_FreeList(MCentral *c, MLink *start); // TODO: need this?
-
-// Main malloc heap.
-// The heap itself is the "free[]" and "large" arrays,
-// but all the other global data is here too.
-struct MHeap
-{
-	Lock;
-	MSpan free[MaxMHeapList];	// free lists of given length
-	MSpan freelarge;		// free lists length >= MaxMHeapList
-	MSpan busy[MaxMHeapList];	// busy lists of large objects of given length
-	MSpan busylarge;		// busy lists of large objects length >= MaxMHeapList
-	MSpan **allspans;		// all spans out there
-	MSpan **sweepspans;		// copy of allspans referenced by sweeper
-	uint32	nspan;
-	uint32	nspancap;
-	uint32	sweepgen;		// sweep generation, see comment in MSpan
-	uint32	sweepdone;		// all spans are swept
-
-	// span lookup
-	MSpan**	spans;
-	uintptr	spans_mapped;
-
-	// range of addresses we might see in the heap
-	byte *bitmap;
-	uintptr bitmap_mapped;
-	byte *arena_start;
-	byte *arena_used;
-	byte *arena_end;
-	bool arena_reserved;
-
-	// central free lists for small size classes.
-	// the padding makes sure that the MCentrals are
-	// spaced CacheLineSize bytes apart, so that each MCentral.Lock
-	// gets its own cache line.
-	struct {
-		MCentral;
-		byte pad[CacheLineSize];
-	} central[NumSizeClasses];
-
-	FixAlloc spanalloc;	// allocator for Span*
-	FixAlloc cachealloc;	// allocator for MCache*
-	FixAlloc specialfinalizeralloc;	// allocator for SpecialFinalizer*
-	FixAlloc specialprofilealloc;	// allocator for SpecialProfile*
-	Lock speciallock; // lock for sepcial record allocators.
-
-	// Malloc stats.
-	uint64 largefree;	// bytes freed for large objects (>MaxSmallSize)
-	uint64 nlargefree;	// number of frees for large objects (>MaxSmallSize)
-	uint64 nsmallfree[NumSizeClasses];	// number of frees for small objects (<=MaxSmallSize)
-};
-extern MHeap runtime·mheap;
-
-void	runtime·MHeap_Init(MHeap *h);
-MSpan*	runtime·MHeap_Alloc(MHeap *h, uintptr npage, int32 sizeclass, bool large, bool needzero);
-void	runtime·MHeap_Free(MHeap *h, MSpan *s, int32 acct);
-MSpan*	runtime·MHeap_Lookup(MHeap *h, void *v);
-MSpan*	runtime·MHeap_LookupMaybe(MHeap *h, void *v);
-void	runtime·MGetSizeClassInfo(int32 sizeclass, uintptr *size, int32 *npages, int32 *nobj);
-void*	runtime·MHeap_SysAlloc(MHeap *h, uintptr n);
-void	runtime·MHeap_MapBits(MHeap *h);
-void	runtime·MHeap_MapSpans(MHeap *h);
-void	runtime·MHeap_Scavenger(void);
-void	runtime·MHeap_SplitSpan(MHeap *h, MSpan *s);
-
-void*	runtime·mallocgc(uintptr size, uintptr typ, uint32 flag);
-void*	runtime·persistentalloc(uintptr size, uintptr align, uint64 *stat);
-int32	runtime·mlookup(void *v, byte **base, uintptr *size, MSpan **s);
-void	runtime·gc(int32 force);
-uintptr	runtime·sweepone(void);
-void	runtime·markscan(void *v);
-void	runtime·marknogc(void *v);
-void	runtime·checkallocated(void *v, uintptr n);
-void	runtime·markfreed(void *v);
-void	runtime·checkfreed(void *v, uintptr n);
-extern	int32	runtime·checking;
-void	runtime·markspan(void *v, uintptr size, uintptr n, bool leftover);
-void	runtime·unmarkspan(void *v, uintptr size);
-void	runtime·purgecachedstats(MCache*);
-void*	runtime·cnew(Type*);
-void*	runtime·cnewarray(Type*, intgo);
-void	runtime·tracealloc(void*, uintptr, uintptr);
-void	runtime·tracefree(void*, uintptr);
-void	runtime·tracegc(void);
-
-uintptr	runtime·gettype(void*);
-
-enum
-{
-	// flags to malloc
-	FlagNoScan	= 1<<0,	// GC doesn't have to scan object
-	FlagNoProfiling	= 1<<1,	// must not profile
-	FlagNoGC	= 1<<2,	// must not free or scan for pointers
-	FlagNoZero	= 1<<3, // don't zero memory
-	FlagNoInvokeGC	= 1<<4, // don't invoke GC
-};
-
-void	runtime·MProf_Malloc(void*, uintptr);
-void	runtime·MProf_Free(Bucket*, uintptr, bool);
-void	runtime·MProf_GC(void);
-void	runtime·iterate_memprof(void (*callback)(Bucket*, uintptr, uintptr*, uintptr, uintptr, uintptr));
-int32	runtime·gcprocs(void);
-void	runtime·helpgc(int32 nproc);
-void	runtime·gchelper(void);
-void	runtime·createfing(void);
-G*	runtime·wakefing(void);
-extern bool	runtime·fingwait;
-extern bool	runtime·fingwake;
-
-void	runtime·setprofilebucket(void *p, Bucket *b);
-
-bool	runtime·addfinalizer(void*, FuncVal *fn, uintptr, Type*, PtrType*);
-void	runtime·removefinalizer(void*);
-void	runtime·queuefinalizer(byte *p, FuncVal *fn, uintptr nret, Type *fint, PtrType *ot);
-
-void	runtime·freeallspecials(MSpan *span, void *p, uintptr size);
-bool	runtime·freespecial(Special *s, void *p, uintptr size, bool freed);
-
-enum
-{
-	TypeInfo_SingleObject = 0,
-	TypeInfo_Array = 1,
-	TypeInfo_Chan = 2,
-
-	// Enables type information at the end of blocks allocated from heap	
-	DebugTypeAtBlockEnd = 0,
-};
-
-// Information from the compiler about the layout of stack frames.
-typedef struct BitVector BitVector;
-struct BitVector
-{
-	int32 n; // # of bits
-	uint32 *data;
-};
-typedef struct StackMap StackMap;
-struct StackMap
-{
-	int32 n; // number of bitmaps
-	int32 nbit; // number of bits in each bitmap
-	uint32 data[];
-};
-enum {
-	// Pointer map
-	BitsPerPointer = 2,
-	BitsDead = 0,
-	BitsScalar = 1,
-	BitsPointer = 2,
-	BitsMultiWord = 3,
-	// BitsMultiWord will be set for the first word of a multi-word item.
-	// When it is set, one of the following will be set for the second word.
-	BitsString = 0,
-	BitsSlice = 1,
-	BitsIface = 2,
-	BitsEface = 3,
-};
-// Returns pointer map data for the given stackmap index
-// (the index is encoded in PCDATA_StackMapIndex).
-BitVector	runtime·stackmapdata(StackMap *stackmap, int32 n);
-
-// defined in mgc0.go
-void	runtime·gc_m_ptr(Eface*);
-void	runtime·gc_g_ptr(Eface*);
-void	runtime·gc_itab_ptr(Eface*);
-
-void	runtime·memorydump(void);
-int32	runtime·setgcpercent(int32);
-
-// Value we use to mark dead pointers when GODEBUG=gcdead=1.
-#define PoisonGC ((uintptr)0xf969696969696969ULL)
-#define PoisonStack ((uintptr)0x6868686868686868ULL)
diff --git a/src/pkg/runtime/malloc1.go b/src/pkg/runtime/malloc1.go
deleted file mode 100644
index da92f4c..0000000
--- a/src/pkg/runtime/malloc1.go
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build ignore
-
-// trivial malloc test
-
-package main
-
-import (
-	"flag"
-	"fmt"
-	"runtime"
-)
-
-var chatty = flag.Bool("v", false, "chatty")
-
-func main() {
-	memstats := new(runtime.MemStats)
-	runtime.Free(runtime.Alloc(1))
-	runtime.ReadMemStats(memstats)
-	if *chatty {
-		fmt.Printf("%+v %v\n", memstats, uint64(0))
-	}
-}
diff --git a/src/pkg/runtime/malloc_test.go b/src/pkg/runtime/malloc_test.go
deleted file mode 100644
index 128ec09..0000000
--- a/src/pkg/runtime/malloc_test.go
+++ /dev/null
@@ -1,156 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package runtime_test
-
-import (
-	"flag"
-	. "runtime"
-	"testing"
-	"time"
-	"unsafe"
-)
-
-func TestMemStats(t *testing.T) {
-	// Test that MemStats has sane values.
-	st := new(MemStats)
-	ReadMemStats(st)
-	if st.HeapSys == 0 || st.StackSys == 0 || st.MSpanSys == 0 || st.MCacheSys == 0 ||
-		st.BuckHashSys == 0 || st.GCSys == 0 || st.OtherSys == 0 {
-		t.Fatalf("Zero sys value: %+v", *st)
-	}
-	if st.Sys != st.HeapSys+st.StackSys+st.MSpanSys+st.MCacheSys+
-		st.BuckHashSys+st.GCSys+st.OtherSys {
-		t.Fatalf("Bad sys value: %+v", *st)
-	}
-}
-
-var mallocSink uintptr
-
-func BenchmarkMalloc8(b *testing.B) {
-	var x uintptr
-	for i := 0; i < b.N; i++ {
-		p := new(int64)
-		x ^= uintptr(unsafe.Pointer(p))
-	}
-	mallocSink = x
-}
-
-func BenchmarkMalloc16(b *testing.B) {
-	var x uintptr
-	for i := 0; i < b.N; i++ {
-		p := new([2]int64)
-		x ^= uintptr(unsafe.Pointer(p))
-	}
-	mallocSink = x
-}
-
-func BenchmarkMallocTypeInfo8(b *testing.B) {
-	var x uintptr
-	for i := 0; i < b.N; i++ {
-		p := new(struct {
-			p [8 / unsafe.Sizeof(uintptr(0))]*int
-		})
-		x ^= uintptr(unsafe.Pointer(p))
-	}
-	mallocSink = x
-}
-
-func BenchmarkMallocTypeInfo16(b *testing.B) {
-	var x uintptr
-	for i := 0; i < b.N; i++ {
-		p := new(struct {
-			p [16 / unsafe.Sizeof(uintptr(0))]*int
-		})
-		x ^= uintptr(unsafe.Pointer(p))
-	}
-	mallocSink = x
-}
-
-var n = flag.Int("n", 1000, "number of goroutines")
-
-func BenchmarkGoroutineSelect(b *testing.B) {
-	quit := make(chan struct{})
-	read := func(ch chan struct{}) {
-		for {
-			select {
-			case _, ok := <-ch:
-				if !ok {
-					return
-				}
-			case <-quit:
-				return
-			}
-		}
-	}
-	benchHelper(b, *n, read)
-}
-
-func BenchmarkGoroutineBlocking(b *testing.B) {
-	read := func(ch chan struct{}) {
-		for {
-			if _, ok := <-ch; !ok {
-				return
-			}
-		}
-	}
-	benchHelper(b, *n, read)
-}
-
-func BenchmarkGoroutineForRange(b *testing.B) {
-	read := func(ch chan struct{}) {
-		for _ = range ch {
-		}
-	}
-	benchHelper(b, *n, read)
-}
-
-func benchHelper(b *testing.B, n int, read func(chan struct{})) {
-	m := make([]chan struct{}, n)
-	for i := range m {
-		m[i] = make(chan struct{}, 1)
-		go read(m[i])
-	}
-	b.StopTimer()
-	b.ResetTimer()
-	GC()
-
-	for i := 0; i < b.N; i++ {
-		for _, ch := range m {
-			if ch != nil {
-				ch <- struct{}{}
-			}
-		}
-		time.Sleep(10 * time.Millisecond)
-		b.StartTimer()
-		GC()
-		b.StopTimer()
-	}
-
-	for _, ch := range m {
-		close(ch)
-	}
-	time.Sleep(10 * time.Millisecond)
-}
-
-func BenchmarkGoroutineIdle(b *testing.B) {
-	quit := make(chan struct{})
-	fn := func() {
-		<-quit
-	}
-	for i := 0; i < *n; i++ {
-		go fn()
-	}
-
-	GC()
-	b.ResetTimer()
-
-	for i := 0; i < b.N; i++ {
-		GC()
-	}
-
-	b.StopTimer()
-	close(quit)
-	time.Sleep(10 * time.Millisecond)
-}
diff --git a/src/pkg/runtime/mallocrand.go b/src/pkg/runtime/mallocrand.go
deleted file mode 100644
index f1bcb89..0000000
--- a/src/pkg/runtime/mallocrand.go
+++ /dev/null
@@ -1,93 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build ignore
-
-// Random malloc test.
-
-package main
-
-import (
-	"flag"
-	"math/rand"
-	"runtime"
-	"unsafe"
-)
-
-var chatty = flag.Bool("v", false, "chatty")
-
-var footprint uint64
-var allocated uint64
-
-func bigger() {
-	memstats := new(runtime.MemStats)
-	runtime.ReadMemStats(memstats)
-	if f := memstats.Sys; footprint < f {
-		footprint = f
-		if *chatty {
-			println("Footprint", footprint, " for ", allocated)
-		}
-		if footprint > 1e9 {
-			println("too big")
-			panic("fail")
-		}
-	}
-}
-
-// Prime the data structures by allocating one of
-// each block in order.  After this, there should be
-// little reason to ask for more memory from the OS.
-func prime() {
-	for i := 0; i < 16; i++ {
-		b := runtime.Alloc(1 << uint(i))
-		runtime.Free(b)
-	}
-	for i := uintptr(0); i < 256; i++ {
-		b := runtime.Alloc(i << 12)
-		runtime.Free(b)
-	}
-}
-
-func memset(b *byte, c byte, n uintptr) {
-	np := uintptr(n)
-	for i := uintptr(0); i < np; i++ {
-		*(*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(b)) + i)) = c
-	}
-}
-
-func main() {
-	flag.Parse()
-	//	prime()
-	var blocks [1]struct {
-		base *byte
-		siz  uintptr
-	}
-	for i := 0; i < 1<<10; i++ {
-		if i%(1<<10) == 0 && *chatty {
-			println(i)
-		}
-		b := rand.Int() % len(blocks)
-		if blocks[b].base != nil {
-			//	println("Free", blocks[b].siz, blocks[b].base)
-			runtime.Free(blocks[b].base)
-			blocks[b].base = nil
-			allocated -= uint64(blocks[b].siz)
-			continue
-		}
-		siz := uintptr(rand.Int() >> (11 + rand.Uint32()%20))
-		base := runtime.Alloc(siz)
-		//	ptr := uintptr(syscall.BytePtr(base))+uintptr(siz/2)
-		//	obj, size, ref, ok := allocator.find(ptr)
-		//	if obj != base || *ref != 0 || !ok {
-		//		println("find", siz, obj, ref, ok)
-		//		panic("fail")
-		//	}
-		blocks[b].base = base
-		blocks[b].siz = siz
-		allocated += uint64(siz)
-		//	println("Alloc", siz, base)
-		memset(base, 0xbb, siz)
-		bigger()
-	}
-}
diff --git a/src/pkg/runtime/mallocrep.go b/src/pkg/runtime/mallocrep.go
deleted file mode 100644
index 03ee71e..0000000
--- a/src/pkg/runtime/mallocrep.go
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Repeated malloc test.
-
-// +build ignore
-
-package main
-
-import (
-	"flag"
-	"runtime"
-)
-
-var chatty = flag.Bool("v", false, "chatty")
-
-var oldsys uint64
-var memstats runtime.MemStats
-
-func bigger() {
-	st := &memstats
-	runtime.ReadMemStats(st)
-	if oldsys < st.Sys {
-		oldsys = st.Sys
-		if *chatty {
-			println(st.Sys, " system bytes for ", st.Alloc, " Go bytes")
-		}
-		if st.Sys > 1e9 {
-			println("too big")
-			panic("fail")
-		}
-	}
-}
-
-func main() {
-	runtime.GC()                    // clean up garbage from init
-	runtime.ReadMemStats(&memstats) // first call can do some allocations
-	runtime.MemProfileRate = 0      // disable profiler
-	stacks := memstats.Alloc        // ignore stacks
-	flag.Parse()
-	for i := 0; i < 1<<7; i++ {
-		for j := 1; j <= 1<<22; j <<= 1 {
-			if i == 0 && *chatty {
-				println("First alloc:", j)
-			}
-			if a := memstats.Alloc - stacks; a != 0 {
-				println("no allocations but stats report", a, "bytes allocated")
-				panic("fail")
-			}
-			b := runtime.Alloc(uintptr(j))
-			runtime.ReadMemStats(&memstats)
-			during := memstats.Alloc - stacks
-			runtime.Free(b)
-			runtime.ReadMemStats(&memstats)
-			if a := memstats.Alloc - stacks; a != 0 {
-				println("allocated ", j, ": wrong stats: during=", during, " after=", a, " (want 0)")
-				panic("fail")
-			}
-			bigger()
-		}
-		if i%(1<<10) == 0 && *chatty {
-			println(i)
-		}
-		if i == 0 {
-			if *chatty {
-				println("Primed", i)
-			}
-			//	runtime.frozen = true
-		}
-	}
-}
diff --git a/src/pkg/runtime/mallocrep1.go b/src/pkg/runtime/mallocrep1.go
deleted file mode 100644
index bc33e3a..0000000
--- a/src/pkg/runtime/mallocrep1.go
+++ /dev/null
@@ -1,144 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build ignore
-
-// Repeated malloc test.
-
-package main
-
-import (
-	"flag"
-	"fmt"
-	"runtime"
-	"strconv"
-)
-
-var chatty = flag.Bool("v", false, "chatty")
-var reverse = flag.Bool("r", false, "reverse")
-var longtest = flag.Bool("l", false, "long test")
-
-var b []*byte
-var stats = new(runtime.MemStats)
-
-func OkAmount(size, n uintptr) bool {
-	if n < size {
-		return false
-	}
-	if size < 16*8 {
-		if n > size+16 {
-			return false
-		}
-	} else {
-		if n > size*9/8 {
-			return false
-		}
-	}
-	return true
-}
-
-func AllocAndFree(size, count int) {
-	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(1))
-	if *chatty {
-		fmt.Printf("size=%d count=%d ...\n", size, count)
-	}
-	runtime.ReadMemStats(stats)
-	n1 := stats.Alloc
-	for i := 0; i < count; i++ {
-		b[i] = runtime.Alloc(uintptr(size))
-		base, n := runtime.Lookup(b[i])
-		if base != b[i] || !OkAmount(uintptr(size), n) {
-			println("lookup failed: got", base, n, "for", b[i])
-			panic("fail")
-		}
-		runtime.ReadMemStats(stats)
-		if stats.Sys > 1e9 {
-			println("too much memory allocated")
-			panic("fail")
-		}
-	}
-	runtime.ReadMemStats(stats)
-	n2 := stats.Alloc
-	if *chatty {
-		fmt.Printf("size=%d count=%d stats=%+v\n", size, count, *stats)
-	}
-	n3 := stats.Alloc
-	for j := 0; j < count; j++ {
-		i := j
-		if *reverse {
-			i = count - 1 - j
-		}
-		alloc := uintptr(stats.Alloc)
-		base, n := runtime.Lookup(b[i])
-		if base != b[i] || !OkAmount(uintptr(size), n) {
-			println("lookup failed: got", base, n, "for", b[i])
-			panic("fail")
-		}
-		runtime.Free(b[i])
-		runtime.ReadMemStats(stats)
-		if stats.Alloc != uint64(alloc-n) {
-			println("free alloc got", stats.Alloc, "expected", alloc-n, "after free of", n)
-			panic("fail")
-		}
-		if stats.Sys > 1e9 {
-			println("too much memory allocated")
-			panic("fail")
-		}
-	}
-	runtime.ReadMemStats(stats)
-	n4 := stats.Alloc
-
-	if *chatty {
-		fmt.Printf("size=%d count=%d stats=%+v\n", size, count, *stats)
-	}
-	if n2-n1 != n3-n4 {
-		println("wrong alloc count: ", n2-n1, n3-n4)
-		panic("fail")
-	}
-}
-
-func atoi(s string) int {
-	i, _ := strconv.Atoi(s)
-	return i
-}
-
-func main() {
-	runtime.MemProfileRate = 0 // disable profiler
-	flag.Parse()
-	b = make([]*byte, 10000)
-	if flag.NArg() > 0 {
-		AllocAndFree(atoi(flag.Arg(0)), atoi(flag.Arg(1)))
-		return
-	}
-	maxb := 1 << 22
-	if !*longtest {
-		maxb = 1 << 19
-	}
-	for j := 1; j <= maxb; j <<= 1 {
-		n := len(b)
-		max := uintptr(1 << 28)
-		if !*longtest {
-			max = uintptr(maxb)
-		}
-		if uintptr(j)*uintptr(n) > max {
-			n = int(max / uintptr(j))
-		}
-		if n < 10 {
-			n = 10
-		}
-		for m := 1; m <= n; {
-			AllocAndFree(j, m)
-			if m == n {
-				break
-			}
-			m = 5 * m / 4
-			if m < 4 {
-				m++
-			}
-			if m > n {
-				m = n
-			}
-		}
-	}
-}
diff --git a/src/pkg/runtime/map_test.go b/src/pkg/runtime/map_test.go
deleted file mode 100644
index e4e8383..0000000
--- a/src/pkg/runtime/map_test.go
+++ /dev/null
@@ -1,477 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package runtime_test
-
-import (
-	"fmt"
-	"math"
-	"reflect"
-	"runtime"
-	"sort"
-	"strings"
-	"sync"
-	"testing"
-)
-
-// negative zero is a good test because:
-//  1) 0 and -0 are equal, yet have distinct representations.
-//  2) 0 is represented as all zeros, -0 isn't.
-// I'm not sure the language spec actually requires this behavior,
-// but it's what the current map implementation does.
-func TestNegativeZero(t *testing.T) {
-	m := make(map[float64]bool, 0)
-
-	m[+0.0] = true
-	m[math.Copysign(0.0, -1.0)] = true // should overwrite +0 entry
-
-	if len(m) != 1 {
-		t.Error("length wrong")
-	}
-
-	for k := range m {
-		if math.Copysign(1.0, k) > 0 {
-			t.Error("wrong sign")
-		}
-	}
-
-	m = make(map[float64]bool, 0)
-	m[math.Copysign(0.0, -1.0)] = true
-	m[+0.0] = true // should overwrite -0.0 entry
-
-	if len(m) != 1 {
-		t.Error("length wrong")
-	}
-
-	for k := range m {
-		if math.Copysign(1.0, k) < 0 {
-			t.Error("wrong sign")
-		}
-	}
-}
-
-// nan is a good test because nan != nan, and nan has
-// a randomized hash value.
-func TestNan(t *testing.T) {
-	m := make(map[float64]int, 0)
-	nan := math.NaN()
-	m[nan] = 1
-	m[nan] = 2
-	m[nan] = 4
-	if len(m) != 3 {
-		t.Error("length wrong")
-	}
-	s := 0
-	for k, v := range m {
-		if k == k {
-			t.Error("nan disappeared")
-		}
-		if (v & (v - 1)) != 0 {
-			t.Error("value wrong")
-		}
-		s |= v
-	}
-	if s != 7 {
-		t.Error("values wrong")
-	}
-}
-
-// Maps aren't actually copied on assignment.
-func TestAlias(t *testing.T) {
-	m := make(map[int]int, 0)
-	m[0] = 5
-	n := m
-	n[0] = 6
-	if m[0] != 6 {
-		t.Error("alias didn't work")
-	}
-}
-
-func TestGrowWithNaN(t *testing.T) {
-	m := make(map[float64]int, 4)
-	nan := math.NaN()
-	m[nan] = 1
-	m[nan] = 2
-	m[nan] = 4
-	cnt := 0
-	s := 0
-	growflag := true
-	for k, v := range m {
-		if growflag {
-			// force a hashtable resize
-			for i := 0; i < 100; i++ {
-				m[float64(i)] = i
-			}
-			growflag = false
-		}
-		if k != k {
-			cnt++
-			s |= v
-		}
-	}
-	if cnt != 3 {
-		t.Error("NaN keys lost during grow")
-	}
-	if s != 7 {
-		t.Error("NaN values lost during grow")
-	}
-}
-
-type FloatInt struct {
-	x float64
-	y int
-}
-
-func TestGrowWithNegativeZero(t *testing.T) {
-	negzero := math.Copysign(0.0, -1.0)
-	m := make(map[FloatInt]int, 4)
-	m[FloatInt{0.0, 0}] = 1
-	m[FloatInt{0.0, 1}] = 2
-	m[FloatInt{0.0, 2}] = 4
-	m[FloatInt{0.0, 3}] = 8
-	growflag := true
-	s := 0
-	cnt := 0
-	negcnt := 0
-	// The first iteration should return the +0 key.
-	// The subsequent iterations should return the -0 key.
-	// I'm not really sure this is required by the spec,
-	// but it makes sense.
-	// TODO: are we allowed to get the first entry returned again???
-	for k, v := range m {
-		if v == 0 {
-			continue
-		} // ignore entries added to grow table
-		cnt++
-		if math.Copysign(1.0, k.x) < 0 {
-			if v&16 == 0 {
-				t.Error("key/value not updated together 1")
-			}
-			negcnt++
-			s |= v & 15
-		} else {
-			if v&16 == 16 {
-				t.Error("key/value not updated together 2", k, v)
-			}
-			s |= v
-		}
-		if growflag {
-			// force a hashtable resize
-			for i := 0; i < 100; i++ {
-				m[FloatInt{3.0, i}] = 0
-			}
-			// then change all the entries
-			// to negative zero
-			m[FloatInt{negzero, 0}] = 1 | 16
-			m[FloatInt{negzero, 1}] = 2 | 16
-			m[FloatInt{negzero, 2}] = 4 | 16
-			m[FloatInt{negzero, 3}] = 8 | 16
-			growflag = false
-		}
-	}
-	if s != 15 {
-		t.Error("entry missing", s)
-	}
-	if cnt != 4 {
-		t.Error("wrong number of entries returned by iterator", cnt)
-	}
-	if negcnt != 3 {
-		t.Error("update to negzero missed by iteration", negcnt)
-	}
-}
-
-func TestIterGrowAndDelete(t *testing.T) {
-	m := make(map[int]int, 4)
-	for i := 0; i < 100; i++ {
-		m[i] = i
-	}
-	growflag := true
-	for k := range m {
-		if growflag {
-			// grow the table
-			for i := 100; i < 1000; i++ {
-				m[i] = i
-			}
-			// delete all odd keys
-			for i := 1; i < 1000; i += 2 {
-				delete(m, i)
-			}
-			growflag = false
-		} else {
-			if k&1 == 1 {
-				t.Error("odd value returned")
-			}
-		}
-	}
-}
-
-// make sure old bucket arrays don't get GCd while
-// an iterator is still using them.
-func TestIterGrowWithGC(t *testing.T) {
-	m := make(map[int]int, 4)
-	for i := 0; i < 16; i++ {
-		m[i] = i
-	}
-	growflag := true
-	bitmask := 0
-	for k := range m {
-		if k < 16 {
-			bitmask |= 1 << uint(k)
-		}
-		if growflag {
-			// grow the table
-			for i := 100; i < 1000; i++ {
-				m[i] = i
-			}
-			// trigger a gc
-			runtime.GC()
-			growflag = false
-		}
-	}
-	if bitmask != 1<<16-1 {
-		t.Error("missing key", bitmask)
-	}
-}
-
-func testConcurrentReadsAfterGrowth(t *testing.T, useReflect bool) {
-	if runtime.GOMAXPROCS(-1) == 1 {
-		defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(16))
-	}
-	numLoop := 10
-	numGrowStep := 250
-	numReader := 16
-	if testing.Short() {
-		numLoop, numGrowStep = 2, 500
-	}
-	for i := 0; i < numLoop; i++ {
-		m := make(map[int]int, 0)
-		for gs := 0; gs < numGrowStep; gs++ {
-			m[gs] = gs
-			var wg sync.WaitGroup
-			wg.Add(numReader * 2)
-			for nr := 0; nr < numReader; nr++ {
-				go func() {
-					defer wg.Done()
-					for _ = range m {
-					}
-				}()
-				go func() {
-					defer wg.Done()
-					for key := 0; key < gs; key++ {
-						_ = m[key]
-					}
-				}()
-				if useReflect {
-					wg.Add(1)
-					go func() {
-						defer wg.Done()
-						mv := reflect.ValueOf(m)
-						keys := mv.MapKeys()
-						for _, k := range keys {
-							mv.MapIndex(k)
-						}
-					}()
-				}
-			}
-			wg.Wait()
-		}
-	}
-}
-
-func TestConcurrentReadsAfterGrowth(t *testing.T) {
-	testConcurrentReadsAfterGrowth(t, false)
-}
-
-func TestConcurrentReadsAfterGrowthReflect(t *testing.T) {
-	testConcurrentReadsAfterGrowth(t, true)
-}
-
-func TestBigItems(t *testing.T) {
-	var key [256]string
-	for i := 0; i < 256; i++ {
-		key[i] = "foo"
-	}
-	m := make(map[[256]string][256]string, 4)
-	for i := 0; i < 100; i++ {
-		key[37] = fmt.Sprintf("string%02d", i)
-		m[key] = key
-	}
-	var keys [100]string
-	var values [100]string
-	i := 0
-	for k, v := range m {
-		keys[i] = k[37]
-		values[i] = v[37]
-		i++
-	}
-	sort.Strings(keys[:])
-	sort.Strings(values[:])
-	for i := 0; i < 100; i++ {
-		if keys[i] != fmt.Sprintf("string%02d", i) {
-			t.Errorf("#%d: missing key: %v", i, keys[i])
-		}
-		if values[i] != fmt.Sprintf("string%02d", i) {
-			t.Errorf("#%d: missing value: %v", i, values[i])
-		}
-	}
-}
-
-type empty struct {
-}
-
-func TestEmptyKeyAndValue(t *testing.T) {
-	a := make(map[int]empty, 4)
-	b := make(map[empty]int, 4)
-	c := make(map[empty]empty, 4)
-	a[0] = empty{}
-	b[empty{}] = 0
-	b[empty{}] = 1
-	c[empty{}] = empty{}
-
-	if len(a) != 1 {
-		t.Errorf("empty value insert problem")
-	}
-	if b[empty{}] != 1 {
-		t.Errorf("empty key returned wrong value")
-	}
-}
-
-// Tests a map with a single bucket, with same-lengthed short keys
-// ("quick keys") as well as long keys.
-func TestSingleBucketMapStringKeys_DupLen(t *testing.T) {
-	testMapLookups(t, map[string]string{
-		"x":    "x1val",
-		"xx":   "x2val",
-		"foo":  "fooval",
-		"bar":  "barval", // same key length as "foo"
-		"xxxx": "x4val",
-		strings.Repeat("x", 128): "longval1",
-		strings.Repeat("y", 128): "longval2",
-	})
-}
-
-// Tests a map with a single bucket, with all keys having different lengths.
-func TestSingleBucketMapStringKeys_NoDupLen(t *testing.T) {
-	testMapLookups(t, map[string]string{
-		"x":                      "x1val",
-		"xx":                     "x2val",
-		"foo":                    "fooval",
-		"xxxx":                   "x4val",
-		"xxxxx":                  "x5val",
-		"xxxxxx":                 "x6val",
-		strings.Repeat("x", 128): "longval",
-	})
-}
-
-func testMapLookups(t *testing.T, m map[string]string) {
-	for k, v := range m {
-		if m[k] != v {
-			t.Fatalf("m[%q] = %q; want %q", k, m[k], v)
-		}
-	}
-}
-
-// Tests whether the iterator returns the right elements when
-// started in the middle of a grow, when the keys are NaNs.
-func TestMapNanGrowIterator(t *testing.T) {
-	m := make(map[float64]int)
-	nan := math.NaN()
-	const nBuckets = 16
-	// To fill nBuckets buckets takes LOAD * nBuckets keys.
-	nKeys := int(nBuckets * *runtime.HashLoad)
-
-	// Get map to full point with nan keys.
-	for i := 0; i < nKeys; i++ {
-		m[nan] = i
-	}
-	// Trigger grow
-	m[1.0] = 1
-	delete(m, 1.0)
-
-	// Run iterator
-	found := make(map[int]struct{})
-	for _, v := range m {
-		if v != -1 {
-			if _, repeat := found[v]; repeat {
-				t.Fatalf("repeat of value %d", v)
-			}
-			found[v] = struct{}{}
-		}
-		if len(found) == nKeys/2 {
-			// Halfway through iteration, finish grow.
-			for i := 0; i < nBuckets; i++ {
-				delete(m, 1.0)
-			}
-		}
-	}
-	if len(found) != nKeys {
-		t.Fatalf("missing value")
-	}
-}
-
-func TestMapIterOrder(t *testing.T) {
-	for _, n := range [...]int{3, 7, 9, 15} {
-		// Make m be {0: true, 1: true, ..., n-1: true}.
-		m := make(map[int]bool)
-		for i := 0; i < n; i++ {
-			m[i] = true
-		}
-		// Check that iterating over the map produces at least two different orderings.
-		ord := func() []int {
-			var s []int
-			for key := range m {
-				s = append(s, key)
-			}
-			return s
-		}
-		first := ord()
-		ok := false
-		for try := 0; try < 100; try++ {
-			if !reflect.DeepEqual(first, ord()) {
-				ok = true
-				break
-			}
-		}
-		if !ok {
-			t.Errorf("Map with n=%d elements had consistent iteration order: %v", n, first)
-		}
-	}
-}
-
-func TestMapStringBytesLookup(t *testing.T) {
-	// Use large string keys to avoid small-allocation coalescing,
-	// which can cause AllocsPerRun to report lower counts than it should.
-	m := map[string]int{
-		"1000000000000000000000000000000000000000000000000": 1,
-		"2000000000000000000000000000000000000000000000000": 2,
-	}
-	buf := []byte("1000000000000000000000000000000000000000000000000")
-	if x := m[string(buf)]; x != 1 {
-		t.Errorf(`m[string([]byte("1"))] = %d, want 1`, x)
-	}
-	buf[0] = '2'
-	if x := m[string(buf)]; x != 2 {
-		t.Errorf(`m[string([]byte("2"))] = %d, want 2`, x)
-	}
-
-	var x int
-	n := testing.AllocsPerRun(100, func() {
-		x += m[string(buf)]
-	})
-	if n != 0 {
-		t.Errorf("AllocsPerRun for m[string(buf)] = %v, want 0", n)
-	}
-
-	x = 0
-	n = testing.AllocsPerRun(100, func() {
-		y, ok := m[string(buf)]
-		if !ok {
-			panic("!ok")
-		}
-		x += y
-	})
-	if n != 0 {
-		t.Errorf("AllocsPerRun for x,ok = m[string(buf)] = %v, want 0", n)
-	}
-}
diff --git a/src/pkg/runtime/mapspeed_test.go b/src/pkg/runtime/mapspeed_test.go
deleted file mode 100644
index da45ea1..0000000
--- a/src/pkg/runtime/mapspeed_test.go
+++ /dev/null
@@ -1,300 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-package runtime_test
-
-import (
-	"fmt"
-	"strings"
-	"testing"
-)
-
-const size = 10
-
-func BenchmarkHashStringSpeed(b *testing.B) {
-	strings := make([]string, size)
-	for i := 0; i < size; i++ {
-		strings[i] = fmt.Sprintf("string#%d", i)
-	}
-	sum := 0
-	m := make(map[string]int, size)
-	for i := 0; i < size; i++ {
-		m[strings[i]] = 0
-	}
-	idx := 0
-	b.ResetTimer()
-	for i := 0; i < b.N; i++ {
-		sum += m[strings[idx]]
-		idx++
-		if idx == size {
-			idx = 0
-		}
-	}
-}
-
-type chunk [17]byte
-
-func BenchmarkHashBytesSpeed(b *testing.B) {
-	// a bunch of chunks, each with a different alignment mod 16
-	var chunks [size]chunk
-	// initialize each to a different value
-	for i := 0; i < size; i++ {
-		chunks[i][0] = byte(i)
-	}
-	// put into a map
-	m := make(map[chunk]int, size)
-	for i, c := range chunks {
-		m[c] = i
-	}
-	idx := 0
-	b.ResetTimer()
-	for i := 0; i < b.N; i++ {
-		if m[chunks[idx]] != idx {
-			b.Error("bad map entry for chunk")
-		}
-		idx++
-		if idx == size {
-			idx = 0
-		}
-	}
-}
-
-func BenchmarkHashInt32Speed(b *testing.B) {
-	ints := make([]int32, size)
-	for i := 0; i < size; i++ {
-		ints[i] = int32(i)
-	}
-	sum := 0
-	m := make(map[int32]int, size)
-	for i := 0; i < size; i++ {
-		m[ints[i]] = 0
-	}
-	idx := 0
-	b.ResetTimer()
-	for i := 0; i < b.N; i++ {
-		sum += m[ints[idx]]
-		idx++
-		if idx == size {
-			idx = 0
-		}
-	}
-}
-
-func BenchmarkHashInt64Speed(b *testing.B) {
-	ints := make([]int64, size)
-	for i := 0; i < size; i++ {
-		ints[i] = int64(i)
-	}
-	sum := 0
-	m := make(map[int64]int, size)
-	for i := 0; i < size; i++ {
-		m[ints[i]] = 0
-	}
-	idx := 0
-	b.ResetTimer()
-	for i := 0; i < b.N; i++ {
-		sum += m[ints[idx]]
-		idx++
-		if idx == size {
-			idx = 0
-		}
-	}
-}
-func BenchmarkHashStringArraySpeed(b *testing.B) {
-	stringpairs := make([][2]string, size)
-	for i := 0; i < size; i++ {
-		for j := 0; j < 2; j++ {
-			stringpairs[i][j] = fmt.Sprintf("string#%d/%d", i, j)
-		}
-	}
-	sum := 0
-	m := make(map[[2]string]int, size)
-	for i := 0; i < size; i++ {
-		m[stringpairs[i]] = 0
-	}
-	idx := 0
-	b.ResetTimer()
-	for i := 0; i < b.N; i++ {
-		sum += m[stringpairs[idx]]
-		idx++
-		if idx == size {
-			idx = 0
-		}
-	}
-}
-
-func BenchmarkMegMap(b *testing.B) {
-	m := make(map[string]bool)
-	for suffix := 'A'; suffix <= 'G'; suffix++ {
-		m[strings.Repeat("X", 1<<20-1)+fmt.Sprint(suffix)] = true
-	}
-	key := strings.Repeat("X", 1<<20-1) + "k"
-	b.ResetTimer()
-	for i := 0; i < b.N; i++ {
-		_, _ = m[key]
-	}
-}
-
-func BenchmarkMegOneMap(b *testing.B) {
-	m := make(map[string]bool)
-	m[strings.Repeat("X", 1<<20)] = true
-	key := strings.Repeat("Y", 1<<20)
-	b.ResetTimer()
-	for i := 0; i < b.N; i++ {
-		_, _ = m[key]
-	}
-}
-
-func BenchmarkMegEqMap(b *testing.B) {
-	m := make(map[string]bool)
-	key1 := strings.Repeat("X", 1<<20)
-	key2 := strings.Repeat("X", 1<<20) // equal but different instance
-	m[key1] = true
-	b.ResetTimer()
-	for i := 0; i < b.N; i++ {
-		_, _ = m[key2]
-	}
-}
-
-func BenchmarkMegEmptyMap(b *testing.B) {
-	m := make(map[string]bool)
-	key := strings.Repeat("X", 1<<20)
-	b.ResetTimer()
-	for i := 0; i < b.N; i++ {
-		_, _ = m[key]
-	}
-}
-
-func BenchmarkSmallStrMap(b *testing.B) {
-	m := make(map[string]bool)
-	for suffix := 'A'; suffix <= 'G'; suffix++ {
-		m[fmt.Sprint(suffix)] = true
-	}
-	key := "k"
-	b.ResetTimer()
-	for i := 0; i < b.N; i++ {
-		_, _ = m[key]
-	}
-}
-
-func BenchmarkMapStringKeysEight_16(b *testing.B) { benchmarkMapStringKeysEight(b, 16) }
-func BenchmarkMapStringKeysEight_32(b *testing.B) { benchmarkMapStringKeysEight(b, 32) }
-func BenchmarkMapStringKeysEight_64(b *testing.B) { benchmarkMapStringKeysEight(b, 64) }
-func BenchmarkMapStringKeysEight_1M(b *testing.B) { benchmarkMapStringKeysEight(b, 1<<20) }
-
-func benchmarkMapStringKeysEight(b *testing.B, keySize int) {
-	m := make(map[string]bool)
-	for i := 0; i < 8; i++ {
-		m[strings.Repeat("K", i+1)] = true
-	}
-	key := strings.Repeat("K", keySize)
-	b.ResetTimer()
-	for i := 0; i < b.N; i++ {
-		_ = m[key]
-	}
-}
-
-func BenchmarkIntMap(b *testing.B) {
-	m := make(map[int]bool)
-	for i := 0; i < 8; i++ {
-		m[i] = true
-	}
-	b.ResetTimer()
-	for i := 0; i < b.N; i++ {
-		_, _ = m[7]
-	}
-}
-
-// Accessing the same keys in a row.
-func benchmarkRepeatedLookup(b *testing.B, lookupKeySize int) {
-	m := make(map[string]bool)
-	// At least bigger than a single bucket:
-	for i := 0; i < 64; i++ {
-		m[fmt.Sprintf("some key %d", i)] = true
-	}
-	base := strings.Repeat("x", lookupKeySize-1)
-	key1 := base + "1"
-	key2 := base + "2"
-	b.ResetTimer()
-	for i := 0; i < b.N/4; i++ {
-		_ = m[key1]
-		_ = m[key1]
-		_ = m[key2]
-		_ = m[key2]
-	}
-}
-
-func BenchmarkRepeatedLookupStrMapKey32(b *testing.B) { benchmarkRepeatedLookup(b, 32) }
-func BenchmarkRepeatedLookupStrMapKey1M(b *testing.B) { benchmarkRepeatedLookup(b, 1<<20) }
-
-func BenchmarkNewEmptyMap(b *testing.B) {
-	b.ReportAllocs()
-	for i := 0; i < b.N; i++ {
-		_ = make(map[int]int)
-	}
-}
-
-func BenchmarkMapIter(b *testing.B) {
-	m := make(map[int]bool)
-	for i := 0; i < 8; i++ {
-		m[i] = true
-	}
-	b.ResetTimer()
-	for i := 0; i < b.N; i++ {
-		for _, _ = range m {
-		}
-	}
-}
-
-func BenchmarkMapIterEmpty(b *testing.B) {
-	m := make(map[int]bool)
-	b.ResetTimer()
-	for i := 0; i < b.N; i++ {
-		for _, _ = range m {
-		}
-	}
-}
-
-func BenchmarkSameLengthMap(b *testing.B) {
-	// long strings, same length, differ in first few
-	// and last few bytes.
-	m := make(map[string]bool)
-	s1 := "foo" + strings.Repeat("-", 100) + "bar"
-	s2 := "goo" + strings.Repeat("-", 100) + "ber"
-	m[s1] = true
-	m[s2] = true
-	b.ResetTimer()
-	for i := 0; i < b.N; i++ {
-		_ = m[s1]
-	}
-}
-
-type BigKey [3]int64
-
-func BenchmarkBigKeyMap(b *testing.B) {
-	m := make(map[BigKey]bool)
-	k := BigKey{3, 4, 5}
-	m[k] = true
-	for i := 0; i < b.N; i++ {
-		_ = m[k]
-	}
-}
-
-type BigVal [3]int64
-
-func BenchmarkBigValMap(b *testing.B) {
-	m := make(map[BigKey]BigVal)
-	k := BigKey{3, 4, 5}
-	m[k] = BigVal{6, 7, 8}
-	for i := 0; i < b.N; i++ {
-		_ = m[k]
-	}
-}
-
-func BenchmarkSmallKeyMap(b *testing.B) {
-	m := make(map[int16]bool)
-	m[5] = true
-	for i := 0; i < b.N; i++ {
-		_ = m[5]
-	}
-}
diff --git a/src/pkg/runtime/mcache.c b/src/pkg/runtime/mcache.c
deleted file mode 100644
index 26e3db2..0000000
--- a/src/pkg/runtime/mcache.c
+++ /dev/null
@@ -1,130 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Per-P malloc cache for small objects.
-//
-// See malloc.h for an overview.
-
-#include "runtime.h"
-#include "arch_GOARCH.h"
-#include "malloc.h"
-
-extern volatile intgo runtime·MemProfileRate;
-
-// dummy MSpan that contains no free objects.
-static MSpan emptymspan;
-
-MCache*
-runtime·allocmcache(void)
-{
-	intgo rate;
-	MCache *c;
-	int32 i;
-
-	runtime·lock(&runtime·mheap);
-	c = runtime·FixAlloc_Alloc(&runtime·mheap.cachealloc);
-	runtime·unlock(&runtime·mheap);
-	runtime·memclr((byte*)c, sizeof(*c));
-	for(i = 0; i < NumSizeClasses; i++)
-		c->alloc[i] = &emptymspan;
-
-	// Set first allocation sample size.
-	rate = runtime·MemProfileRate;
-	if(rate > 0x3fffffff)	// make 2*rate not overflow
-		rate = 0x3fffffff;
-	if(rate != 0)
-		c->next_sample = runtime·fastrand1() % (2*rate);
-
-	return c;
-}
-
-void
-runtime·freemcache(MCache *c)
-{
-	runtime·MCache_ReleaseAll(c);
-	runtime·lock(&runtime·mheap);
-	runtime·purgecachedstats(c);
-	runtime·FixAlloc_Free(&runtime·mheap.cachealloc, c);
-	runtime·unlock(&runtime·mheap);
-}
-
-// Gets a span that has a free object in it and assigns it
-// to be the cached span for the given sizeclass.  Returns this span.
-MSpan*
-runtime·MCache_Refill(MCache *c, int32 sizeclass)
-{
-	MCacheList *l;
-	MSpan *s;
-
-	m->locks++;
-	// Return the current cached span to the central lists.
-	s = c->alloc[sizeclass];
-	if(s->freelist != nil)
-		runtime·throw("refill on a nonempty span");
-	if(s != &emptymspan)
-		runtime·MCentral_UncacheSpan(&runtime·mheap.central[sizeclass], s);
-
-	// Push any explicitly freed objects to the central lists.
-	// Not required, but it seems like a good time to do it.
-	l = &c->free[sizeclass];
-	if(l->nlist > 0) {
-		runtime·MCentral_FreeList(&runtime·mheap.central[sizeclass], l->list);
-		l->list = nil;
-		l->nlist = 0;
-	}
-
-	// Get a new cached span from the central lists.
-	s = runtime·MCentral_CacheSpan(&runtime·mheap.central[sizeclass]);
-	if(s == nil)
-		runtime·throw("out of memory");
-	if(s->freelist == nil) {
-		runtime·printf("%d %d\n", s->ref, (int32)((s->npages << PageShift) / s->elemsize));
-		runtime·throw("empty span");
-	}
-	c->alloc[sizeclass] = s;
-	m->locks--;
-	return s;
-}
-
-void
-runtime·MCache_Free(MCache *c, MLink *p, int32 sizeclass, uintptr size)
-{
-	MCacheList *l;
-
-	// Put on free list.
-	l = &c->free[sizeclass];
-	p->next = l->list;
-	l->list = p;
-	l->nlist++;
-
-	// We transfer a span at a time from MCentral to MCache,
-	// so we'll do the same in the other direction.
-	if(l->nlist >= (runtime·class_to_allocnpages[sizeclass]<<PageShift)/size) {
-		runtime·MCentral_FreeList(&runtime·mheap.central[sizeclass], l->list);
-		l->list = nil;
-		l->nlist = 0;
-	}
-}
-
-void
-runtime·MCache_ReleaseAll(MCache *c)
-{
-	int32 i;
-	MSpan *s;
-	MCacheList *l;
-
-	for(i=0; i<NumSizeClasses; i++) {
-		s = c->alloc[i];
-		if(s != &emptymspan) {
-			runtime·MCentral_UncacheSpan(&runtime·mheap.central[i], s);
-			c->alloc[i] = &emptymspan;
-		}
-		l = &c->free[i];
-		if(l->nlist > 0) {
-			runtime·MCentral_FreeList(&runtime·mheap.central[i], l->list);
-			l->list = nil;
-			l->nlist = 0;
-		}
-	}
-}
diff --git a/src/pkg/runtime/mcentral.c b/src/pkg/runtime/mcentral.c
deleted file mode 100644
index 203558f..0000000
--- a/src/pkg/runtime/mcentral.c
+++ /dev/null
@@ -1,307 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Central free lists.
-//
-// See malloc.h for an overview.
-//
-// The MCentral doesn't actually contain the list of free objects; the MSpan does.
-// Each MCentral is two lists of MSpans: those with free objects (c->nonempty)
-// and those that are completely allocated (c->empty).
-//
-// TODO(rsc): tcmalloc uses a "transfer cache" to split the list
-// into sections of class_to_transfercount[sizeclass] objects
-// so that it is faster to move those lists between MCaches and MCentrals.
-
-#include "runtime.h"
-#include "arch_GOARCH.h"
-#include "malloc.h"
-
-static bool MCentral_Grow(MCentral *c);
-static void MCentral_Free(MCentral *c, MLink *v);
-static void MCentral_ReturnToHeap(MCentral *c, MSpan *s);
-
-// Initialize a single central free list.
-void
-runtime·MCentral_Init(MCentral *c, int32 sizeclass)
-{
-	c->sizeclass = sizeclass;
-	runtime·MSpanList_Init(&c->nonempty);
-	runtime·MSpanList_Init(&c->empty);
-}
-
-// Allocate a span to use in an MCache.
-MSpan*
-runtime·MCentral_CacheSpan(MCentral *c)
-{
-	MSpan *s;
-	int32 cap, n;
-	uint32 sg;
-
-	runtime·lock(c);
-	sg = runtime·mheap.sweepgen;
-retry:
-	for(s = c->nonempty.next; s != &c->nonempty; s = s->next) {
-		if(s->sweepgen == sg-2 && runtime·cas(&s->sweepgen, sg-2, sg-1)) {
-			runtime·unlock(c);
-			runtime·MSpan_Sweep(s);
-			runtime·lock(c);
-			// the span could have been moved to heap, retry
-			goto retry;
-		}
-		if(s->sweepgen == sg-1) {
-			// the span is being swept by background sweeper, skip
-			continue;
-		}
-		// we have a nonempty span that does not require sweeping, allocate from it
-		goto havespan;
-	}
-
-	for(s = c->empty.next; s != &c->empty; s = s->next) {
-		if(s->sweepgen == sg-2 && runtime·cas(&s->sweepgen, sg-2, sg-1)) {
-			// we have an empty span that requires sweeping,
-			// sweep it and see if we can free some space in it
-			runtime·MSpanList_Remove(s);
-			// swept spans are at the end of the list
-			runtime·MSpanList_InsertBack(&c->empty, s);
-			runtime·unlock(c);
-			runtime·MSpan_Sweep(s);
-			runtime·lock(c);
-			// the span could be moved to nonempty or heap, retry
-			goto retry;
-		}
-		if(s->sweepgen == sg-1) {
-			// the span is being swept by background sweeper, skip
-			continue;
-		}
-		// already swept empty span,
-		// all subsequent ones must also be either swept or in process of sweeping
-		break;
-	}
-
-	// Replenish central list if empty.
-	if(!MCentral_Grow(c)) {
-		runtime·unlock(c);
-		return nil;
-	}
-	goto retry;
-
-havespan:
-	cap = (s->npages << PageShift) / s->elemsize;
-	n = cap - s->ref;
-	if(n == 0)
-		runtime·throw("empty span");
-	if(s->freelist == nil)
-		runtime·throw("freelist empty");
-	c->nfree -= n;
-	runtime·MSpanList_Remove(s);
-	runtime·MSpanList_InsertBack(&c->empty, s);
-	s->incache = true;
-	runtime·unlock(c);
-	return s;
-}
-
-// Return span from an MCache.
-void
-runtime·MCentral_UncacheSpan(MCentral *c, MSpan *s)
-{
-	MLink *v;
-	int32 cap, n;
-
-	runtime·lock(c);
-
-	s->incache = false;
-
-	// Move any explicitly freed items from the freebuf to the freelist.
-	while((v = s->freebuf) != nil) {
-		s->freebuf = v->next;
-		runtime·markfreed(v);
-		v->next = s->freelist;
-		s->freelist = v;
-		s->ref--;
-	}
-
-	if(s->ref == 0) {
-		// Free back to heap.  Unlikely, but possible.
-		MCentral_ReturnToHeap(c, s); // unlocks c
-		return;
-	}
-	
-	cap = (s->npages << PageShift) / s->elemsize;
-	n = cap - s->ref;
-	if(n > 0) {
-		c->nfree += n;
-		runtime·MSpanList_Remove(s);
-		runtime·MSpanList_Insert(&c->nonempty, s);
-	}
-	runtime·unlock(c);
-}
-
-// Free the list of objects back into the central free list c.
-// Called from runtime·free.
-void
-runtime·MCentral_FreeList(MCentral *c, MLink *start)
-{
-	MLink *next;
-
-	runtime·lock(c);
-	for(; start != nil; start = next) {
-		next = start->next;
-		MCentral_Free(c, start);
-	}
-	runtime·unlock(c);
-}
-
-// Helper: free one object back into the central free list.
-// Caller must hold lock on c on entry.  Holds lock on exit.
-static void
-MCentral_Free(MCentral *c, MLink *v)
-{
-	MSpan *s;
-
-	// Find span for v.
-	s = runtime·MHeap_Lookup(&runtime·mheap, v);
-	if(s == nil || s->ref == 0)
-		runtime·throw("invalid free");
-	if(s->sweepgen != runtime·mheap.sweepgen)
-		runtime·throw("free into unswept span");
-	
-	// If the span is currently being used unsynchronized by an MCache,
-	// we can't modify the freelist.  Add to the freebuf instead.  The
-	// items will get moved to the freelist when the span is returned
-	// by the MCache.
-	if(s->incache) {
-		v->next = s->freebuf;
-		s->freebuf = v;
-		return;
-	}
-
-	// Move span to nonempty if necessary.
-	if(s->freelist == nil) {
-		runtime·MSpanList_Remove(s);
-		runtime·MSpanList_Insert(&c->nonempty, s);
-	}
-
-	// Add the object to span's free list.
-	runtime·markfreed(v);
-	v->next = s->freelist;
-	s->freelist = v;
-	s->ref--;
-	c->nfree++;
-
-	// If s is completely freed, return it to the heap.
-	if(s->ref == 0) {
-		MCentral_ReturnToHeap(c, s); // unlocks c
-		runtime·lock(c);
-	}
-}
-
-// Free n objects from a span s back into the central free list c.
-// Called during sweep.
-// Returns true if the span was returned to heap.  Sets sweepgen to
-// the latest generation.
-bool
-runtime·MCentral_FreeSpan(MCentral *c, MSpan *s, int32 n, MLink *start, MLink *end)
-{
-	if(s->incache)
-		runtime·throw("freespan into cached span");
-	runtime·lock(c);
-
-	// Move to nonempty if necessary.
-	if(s->freelist == nil) {
-		runtime·MSpanList_Remove(s);
-		runtime·MSpanList_Insert(&c->nonempty, s);
-	}
-
-	// Add the objects back to s's free list.
-	end->next = s->freelist;
-	s->freelist = start;
-	s->ref -= n;
-	c->nfree += n;
-	
-	// delay updating sweepgen until here.  This is the signal that
-	// the span may be used in an MCache, so it must come after the
-	// linked list operations above (actually, just after the
-	// lock of c above.)
-	runtime·atomicstore(&s->sweepgen, runtime·mheap.sweepgen);
-
-	if(s->ref != 0) {
-		runtime·unlock(c);
-		return false;
-	}
-
-	// s is completely freed, return it to the heap.
-	MCentral_ReturnToHeap(c, s); // unlocks c
-	return true;
-}
-
-void
-runtime·MGetSizeClassInfo(int32 sizeclass, uintptr *sizep, int32 *npagesp, int32 *nobj)
-{
-	int32 size;
-	int32 npages;
-
-	npages = runtime·class_to_allocnpages[sizeclass];
-	size = runtime·class_to_size[sizeclass];
-	*npagesp = npages;
-	*sizep = size;
-	*nobj = (npages << PageShift) / size;
-}
-
-// Fetch a new span from the heap and
-// carve into objects for the free list.
-static bool
-MCentral_Grow(MCentral *c)
-{
-	int32 i, n, npages;
-	uintptr size;
-	MLink **tailp, *v;
-	byte *p;
-	MSpan *s;
-
-	runtime·unlock(c);
-	runtime·MGetSizeClassInfo(c->sizeclass, &size, &npages, &n);
-	s = runtime·MHeap_Alloc(&runtime·mheap, npages, c->sizeclass, 0, 1);
-	if(s == nil) {
-		// TODO(rsc): Log out of memory
-		runtime·lock(c);
-		return false;
-	}
-
-	// Carve span into sequence of blocks.
-	tailp = &s->freelist;
-	p = (byte*)(s->start << PageShift);
-	s->limit = p + size*n;
-	for(i=0; i<n; i++) {
-		v = (MLink*)p;
-		*tailp = v;
-		tailp = &v->next;
-		p += size;
-	}
-	*tailp = nil;
-	runtime·markspan((byte*)(s->start<<PageShift), size, n, size*n < (s->npages<<PageShift));
-
-	runtime·lock(c);
-	c->nfree += n;
-	runtime·MSpanList_Insert(&c->nonempty, s);
-	return true;
-}
-
-// Return s to the heap.  s must be unused (s->ref == 0).  Unlocks c.
-static void
-MCentral_ReturnToHeap(MCentral *c, MSpan *s)
-{
-	int32 size;
-
-	size = runtime·class_to_size[c->sizeclass];
-	runtime·MSpanList_Remove(s);
-	s->needzero = 1;
-	s->freelist = nil;
-	if(s->ref != 0)
-		runtime·throw("ref wrong");
-	c->nfree -= (s->npages << PageShift) / size;
-	runtime·unlock(c);
-	runtime·unmarkspan((byte*)(s->start<<PageShift), s->npages<<PageShift);
-	runtime·MHeap_Free(&runtime·mheap, s, 0);
-}
diff --git a/src/pkg/runtime/mem.go b/src/pkg/runtime/mem.go
deleted file mode 100644
index fa308b5..0000000
--- a/src/pkg/runtime/mem.go
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package runtime
-
-import "unsafe"
-
-// Note: the MemStats struct should be kept in sync with
-// struct MStats in malloc.h
-
-// A MemStats records statistics about the memory allocator.
-type MemStats struct {
-	// General statistics.
-	Alloc      uint64 // bytes allocated and still in use
-	TotalAlloc uint64 // bytes allocated (even if freed)
-	Sys        uint64 // bytes obtained from system (sum of XxxSys below)
-	Lookups    uint64 // number of pointer lookups
-	Mallocs    uint64 // number of mallocs
-	Frees      uint64 // number of frees
-
-	// Main allocation heap statistics.
-	HeapAlloc    uint64 // bytes allocated and still in use
-	HeapSys      uint64 // bytes obtained from system
-	HeapIdle     uint64 // bytes in idle spans
-	HeapInuse    uint64 // bytes in non-idle span
-	HeapReleased uint64 // bytes released to the OS
-	HeapObjects  uint64 // total number of allocated objects
-
-	// Low-level fixed-size structure allocator statistics.
-	//	Inuse is bytes used now.
-	//	Sys is bytes obtained from system.
-	StackInuse  uint64 // bootstrap stacks
-	StackSys    uint64
-	MSpanInuse  uint64 // mspan structures
-	MSpanSys    uint64
-	MCacheInuse uint64 // mcache structures
-	MCacheSys   uint64
-	BuckHashSys uint64 // profiling bucket hash table
-	GCSys       uint64 // GC metadata
-	OtherSys    uint64 // other system allocations
-
-	// Garbage collector statistics.
-	NextGC       uint64 // next run in HeapAlloc time (bytes)
-	LastGC       uint64 // last run in absolute time (ns)
-	PauseTotalNs uint64
-	PauseNs      [256]uint64 // circular buffer of recent GC pause times, most recent at [(NumGC+255)%256]
-	NumGC        uint32
-	EnableGC     bool
-	DebugGC      bool
-
-	// Per-size allocation statistics.
-	// 61 is NumSizeClasses in the C code.
-	BySize [61]struct {
-		Size    uint32
-		Mallocs uint64
-		Frees   uint64
-	}
-}
-
-var sizeof_C_MStats uintptr // filled in by malloc.goc
-
-func init() {
-	var memStats MemStats
-	if sizeof_C_MStats != unsafe.Sizeof(memStats) {
-		println(sizeof_C_MStats, unsafe.Sizeof(memStats))
-		panic("MStats vs MemStatsType size mismatch")
-	}
-}
-
-// ReadMemStats populates m with memory allocator statistics.
-func ReadMemStats(m *MemStats)
-
-// GC runs a garbage collection.
-func GC()
diff --git a/src/pkg/runtime/mem_darwin.c b/src/pkg/runtime/mem_darwin.c
deleted file mode 100644
index 878c4e1..0000000
--- a/src/pkg/runtime/mem_darwin.c
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright 2010 The Go 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 "runtime.h"
-#include "arch_GOARCH.h"
-#include "defs_GOOS_GOARCH.h"
-#include "os_GOOS.h"
-#include "malloc.h"
-
-void*
-runtime·SysAlloc(uintptr n, uint64 *stat)
-{
-	void *v;
-
-	v = runtime·mmap(nil, n, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0);
-	if(v < (void*)4096)
-		return nil;
-	runtime·xadd64(stat, n);
-	return v;
-}
-
-void
-runtime·SysUnused(void *v, uintptr n)
-{
-	// Linux's MADV_DONTNEED is like BSD's MADV_FREE.
-	runtime·madvise(v, n, MADV_FREE);
-}
-
-void
-runtime·SysUsed(void *v, uintptr n)
-{
-	USED(v);
-	USED(n);
-}
-
-void
-runtime·SysFree(void *v, uintptr n, uint64 *stat)
-{
-	runtime·xadd64(stat, -(uint64)n);
-	runtime·munmap(v, n);
-}
-
-void
-runtime·SysFault(void *v, uintptr n)
-{
-	runtime·mmap(v, n, PROT_NONE, MAP_ANON|MAP_PRIVATE|MAP_FIXED, -1, 0);
-}
-
-void*
-runtime·SysReserve(void *v, uintptr n, bool *reserved)
-{
-	void *p;
-
-	*reserved = true;
-	p = runtime·mmap(v, n, PROT_NONE, MAP_ANON|MAP_PRIVATE, -1, 0);
-	if(p < (void*)4096)
-		return nil;
-	return p;
-}
-
-enum
-{
-	ENOMEM = 12,
-};
-
-void
-runtime·SysMap(void *v, uintptr n, bool reserved, uint64 *stat)
-{
-	void *p;
-	
-	USED(reserved);
-
-	runtime·xadd64(stat, n);
-	p = runtime·mmap(v, n, PROT_READ|PROT_WRITE, MAP_ANON|MAP_FIXED|MAP_PRIVATE, -1, 0);
-	if(p == (void*)ENOMEM)
-		runtime·throw("runtime: out of memory");
-	if(p != v)
-		runtime·throw("runtime: cannot map pages in arena address space");
-}
diff --git a/src/pkg/runtime/mem_dragonfly.c b/src/pkg/runtime/mem_dragonfly.c
deleted file mode 100644
index c270332..0000000
--- a/src/pkg/runtime/mem_dragonfly.c
+++ /dev/null
@@ -1,103 +0,0 @@
-// Copyright 2010 The Go 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 "runtime.h"
-#include "arch_GOARCH.h"
-#include "defs_GOOS_GOARCH.h"
-#include "os_GOOS.h"
-#include "malloc.h"
-
-enum
-{
-	ENOMEM = 12,
-};
-
-void*
-runtime·SysAlloc(uintptr n, uint64 *stat)
-{
-	void *v;
-
-	v = runtime·mmap(nil, n, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0);
-	if(v < (void*)4096)
-		return nil;
-	runtime·xadd64(stat, n);
-	return v;
-}
-
-void
-runtime·SysUnused(void *v, uintptr n)
-{
-	runtime·madvise(v, n, MADV_FREE);
-}
-
-void
-runtime·SysUsed(void *v, uintptr n)
-{
-	USED(v);
-	USED(n);
-}
-
-void
-runtime·SysFree(void *v, uintptr n, uint64 *stat)
-{
-	runtime·xadd64(stat, -(uint64)n);
-	runtime·munmap(v, n);
-}
-
-void
-runtime·SysFault(void *v, uintptr n)
-{
-	runtime·mmap(v, n, PROT_NONE, MAP_ANON|MAP_PRIVATE|MAP_FIXED, -1, 0);
-}
-
-void*
-runtime·SysReserve(void *v, uintptr n, bool *reserved)
-{
-	void *p;
-
-	// On 64-bit, people with ulimit -v set complain if we reserve too
-	// much address space.  Instead, assume that the reservation is okay
-	// and check the assumption in SysMap.
-	if(sizeof(void*) == 8 && n > 1LL<<32) {
-		*reserved = false;
-		return v;
-	}
-
-	*reserved = true;
-	p = runtime·mmap(v, n, PROT_NONE, MAP_ANON|MAP_PRIVATE, -1, 0);
-	if(p < (void*)4096)
-		return nil;
-	return p;
-}
-
-void
-runtime·SysMap(void *v, uintptr n, bool reserved, uint64 *stat)
-{
-	void *p;
-	
-	runtime·xadd64(stat, n);
-
-	// On 64-bit, we don't actually have v reserved, so tread carefully.
-	if(!reserved) {
-		// TODO(jsing): For some reason DragonFly seems to return
-		// memory at a different address than we requested, even when
-		// there should be no reason for it to do so. This can be
-		// avoided by using MAP_FIXED, but I'm not sure we should need
-		// to do this - we do not on other platforms.
-		p = runtime·mmap(v, n, PROT_READ|PROT_WRITE, MAP_ANON|MAP_FIXED|MAP_PRIVATE, -1, 0);
-		if(p == (void*)ENOMEM)
-			runtime·throw("runtime: out of memory");
-		if(p != v) {
-			runtime·printf("runtime: address space conflict: map(%p) = %p\n", v, p);
-			runtime·throw("runtime: address space conflict");
-		}
-		return;
-	}
-
-	p = runtime·mmap(v, n, PROT_READ|PROT_WRITE, MAP_ANON|MAP_FIXED|MAP_PRIVATE, -1, 0);
-	if(p == (void*)ENOMEM)
-		runtime·throw("runtime: out of memory");
-	if(p != v)
-		runtime·throw("runtime: cannot map pages in arena address space");
-}
diff --git a/src/pkg/runtime/mem_freebsd.c b/src/pkg/runtime/mem_freebsd.c
deleted file mode 100644
index 586947a..0000000
--- a/src/pkg/runtime/mem_freebsd.c
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright 2010 The Go 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 "runtime.h"
-#include "arch_GOARCH.h"
-#include "defs_GOOS_GOARCH.h"
-#include "os_GOOS.h"
-#include "malloc.h"
-
-enum
-{
-	ENOMEM = 12,
-};
-
-void*
-runtime·SysAlloc(uintptr n, uint64 *stat)
-{
-	void *v;
-
-	v = runtime·mmap(nil, n, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0);
-	if(v < (void*)4096)
-		return nil;
-	runtime·xadd64(stat, n);
-	return v;
-}
-
-void
-runtime·SysUnused(void *v, uintptr n)
-{
-	runtime·madvise(v, n, MADV_FREE);
-}
-
-void
-runtime·SysUsed(void *v, uintptr n)
-{
-	USED(v);
-	USED(n);
-}
-
-void
-runtime·SysFree(void *v, uintptr n, uint64 *stat)
-{
-	runtime·xadd64(stat, -(uint64)n);
-	runtime·munmap(v, n);
-}
-
-void
-runtime·SysFault(void *v, uintptr n)
-{
-	runtime·mmap(v, n, PROT_NONE, MAP_ANON|MAP_PRIVATE|MAP_FIXED, -1, 0);
-}
-
-void*
-runtime·SysReserve(void *v, uintptr n, bool *reserved)
-{
-	void *p;
-
-	// On 64-bit, people with ulimit -v set complain if we reserve too
-	// much address space.  Instead, assume that the reservation is okay
-	// and check the assumption in SysMap.
-	if(sizeof(void*) == 8 && n > 1LL<<32) {
-		*reserved = false;
-		return v;
-	}
-
-	*reserved = true;
-	p = runtime·mmap(v, n, PROT_NONE, MAP_ANON|MAP_PRIVATE, -1, 0);
-	if(p < (void*)4096)
-		return nil;
-	return p;
-}
-
-void
-runtime·SysMap(void *v, uintptr n, bool reserved, uint64 *stat)
-{
-	void *p;
-	
-	runtime·xadd64(stat, n);
-
-	// On 64-bit, we don't actually have v reserved, so tread carefully.
-	if(!reserved) {
-		p = runtime·mmap(v, n, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0);
-		if(p == (void*)ENOMEM)
-			runtime·throw("runtime: out of memory");
-		if(p != v) {
-			runtime·printf("runtime: address space conflict: map(%p) = %p\n", v, p);
-			runtime·throw("runtime: address space conflict");
-		}
-		return;
-	}
-
-	p = runtime·mmap(v, n, PROT_READ|PROT_WRITE, MAP_ANON|MAP_FIXED|MAP_PRIVATE, -1, 0);
-	if(p == (void*)ENOMEM)
-		runtime·throw("runtime: out of memory");
-	if(p != v)
-		runtime·throw("runtime: cannot map pages in arena address space");
-}
diff --git a/src/pkg/runtime/mem_linux.c b/src/pkg/runtime/mem_linux.c
deleted file mode 100644
index 635594c..0000000
--- a/src/pkg/runtime/mem_linux.c
+++ /dev/null
@@ -1,160 +0,0 @@
-// Copyright 2010 The Go 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 "runtime.h"
-#include "arch_GOARCH.h"
-#include "defs_GOOS_GOARCH.h"
-#include "os_GOOS.h"
-#include "malloc.h"
-
-enum
-{
-	_PAGE_SIZE = 4096,
-	EACCES = 13,
-};
-
-static int32
-addrspace_free(void *v, uintptr n)
-{
-	int32 errval;
-	uintptr chunk;
-	uintptr off;
-	
-	// NOTE: vec must be just 1 byte long here.
-	// Mincore returns ENOMEM if any of the pages are unmapped,
-	// but we want to know that all of the pages are unmapped.
-	// To make these the same, we can only ask about one page
-	// at a time. See golang.org/issue/7476.
-	static byte vec[1];
-
-	for(off = 0; off < n; off += chunk) {
-		chunk = _PAGE_SIZE * sizeof vec;
-		if(chunk > (n - off))
-			chunk = n - off;
-		errval = runtime·mincore((int8*)v + off, chunk, vec);
-		// ENOMEM means unmapped, which is what we want.
-		// Anything else we assume means the pages are mapped.
-		if (errval != -ENOMEM)
-			return 0;
-	}
-	return 1;
-}
-
-static void *
-mmap_fixed(byte *v, uintptr n, int32 prot, int32 flags, int32 fd, uint32 offset)
-{
-	void *p;
-
-	p = runtime·mmap(v, n, prot, flags, fd, offset);
-	if(p != v && addrspace_free(v, n)) {
-		// On some systems, mmap ignores v without
-		// MAP_FIXED, so retry if the address space is free.
-		if(p > (void*)4096)
-			runtime·munmap(p, n);
-		p = runtime·mmap(v, n, prot, flags|MAP_FIXED, fd, offset);
-	}
-	return p;
-}
-
-void*
-runtime·SysAlloc(uintptr n, uint64 *stat)
-{
-	void *p;
-
-	p = runtime·mmap(nil, n, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0);
-	if(p < (void*)4096) {
-		if(p == (void*)EACCES) {
-			runtime·printf("runtime: mmap: access denied\n");
-			runtime·printf("if you're running SELinux, enable execmem for this process.\n");
-			runtime·exit(2);
-		}
-		if(p == (void*)EAGAIN) {
-			runtime·printf("runtime: mmap: too much locked memory (check 'ulimit -l').\n");
-			runtime·exit(2);
-		}
-		return nil;
-	}
-	runtime·xadd64(stat, n);
-	return p;
-}
-
-void
-runtime·SysUnused(void *v, uintptr n)
-{
-	runtime·madvise(v, n, MADV_DONTNEED);
-}
-
-void
-runtime·SysUsed(void *v, uintptr n)
-{
-	USED(v);
-	USED(n);
-}
-
-void
-runtime·SysFree(void *v, uintptr n, uint64 *stat)
-{
-	runtime·xadd64(stat, -(uint64)n);
-	runtime·munmap(v, n);
-}
-
-void
-runtime·SysFault(void *v, uintptr n)
-{
-	runtime·mmap(v, n, PROT_NONE, MAP_ANON|MAP_PRIVATE|MAP_FIXED, -1, 0);
-}
-
-void*
-runtime·SysReserve(void *v, uintptr n, bool *reserved)
-{
-	void *p;
-
-	// On 64-bit, people with ulimit -v set complain if we reserve too
-	// much address space.  Instead, assume that the reservation is okay
-	// if we can reserve at least 64K and check the assumption in SysMap.
-	// Only user-mode Linux (UML) rejects these requests.
-	if(sizeof(void*) == 8 && n > 1LL<<32) {
-		p = mmap_fixed(v, 64<<10, PROT_NONE, MAP_ANON|MAP_PRIVATE, -1, 0);
-		if (p != v) {
-			if(p >= (void*)4096)
-				runtime·munmap(p, 64<<10);
-			return nil;
-		}
-		runtime·munmap(p, 64<<10);
-		*reserved = false;
-		return v;
-	}
-
-	p = runtime·mmap(v, n, PROT_NONE, MAP_ANON|MAP_PRIVATE, -1, 0);
-	if((uintptr)p < 4096)
-		return nil;
-	*reserved = true;
-	return p;
-}
-
-void
-runtime·SysMap(void *v, uintptr n, bool reserved, uint64 *stat)
-{
-	void *p;
-	
-	runtime·xadd64(stat, n);
-
-	// On 64-bit, we don't actually have v reserved, so tread carefully.
-	if(!reserved) {
-		p = mmap_fixed(v, n, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0);
-		if(p == (void*)ENOMEM)
-			runtime·throw("runtime: out of memory");
-		if(p != v) {
-			runtime·printf("runtime: address space conflict: map(%p) = %p\n", v, p);
-			runtime·throw("runtime: address space conflict");
-		}
-		return;
-	}
-
-	p = runtime·mmap(v, n, PROT_READ|PROT_WRITE, MAP_ANON|MAP_FIXED|MAP_PRIVATE, -1, 0);
-	if(p == (void*)ENOMEM)
-		runtime·throw("runtime: out of memory");
-	if(p != v)
-		runtime·throw("runtime: cannot map pages in arena address space");
-}
diff --git a/src/pkg/runtime/mem_nacl.c b/src/pkg/runtime/mem_nacl.c
deleted file mode 100644
index e2bca40..0000000
--- a/src/pkg/runtime/mem_nacl.c
+++ /dev/null
@@ -1,118 +0,0 @@
-// Copyright 2010 The Go 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 "runtime.h"
-#include "arch_GOARCH.h"
-#include "defs_GOOS_GOARCH.h"
-#include "os_GOOS.h"
-#include "malloc.h"
-
-enum
-{
-	Debug = 0,
-};
-
-void*
-runtime·SysAlloc(uintptr n, uint64 *stat)
-{
-	void *v;
-
-	v = runtime·mmap(nil, n, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0);
-	if(v < (void*)4096) {
-		if(Debug)
-			runtime·printf("SysAlloc(%p): %p\n", n, v);
-		return nil;
-	}
-	runtime·xadd64(stat, n);
-	if(Debug)
-		runtime·printf("SysAlloc(%p) = %p\n", n, v);
-	return v;
-}
-
-void
-runtime·SysUnused(void *v, uintptr n)
-{
-	if(Debug)
-		runtime·printf("SysUnused(%p, %p)\n", v, n);
-}
-
-void
-runtime·SysUsed(void *v, uintptr n)
-{
-	USED(v);
-	USED(n);
-}
-
-void
-runtime·SysFree(void *v, uintptr n, uint64 *stat)
-{
-	if(Debug)
-		runtime·printf("SysFree(%p, %p)\n", v, n);
-	runtime·xadd64(stat, -(uint64)n);
-	runtime·munmap(v, n);
-}
-
-void
-runtime·SysFault(void *v, uintptr n)
-{
-	runtime·mmap(v, n, PROT_NONE, MAP_ANON|MAP_PRIVATE|MAP_FIXED, -1, 0);
-}
-
-void*
-runtime·SysReserve(void *v, uintptr n, bool *reserved)
-{
-	void *p;
-
-	// On 64-bit, people with ulimit -v set complain if we reserve too
-	// much address space.  Instead, assume that the reservation is okay
-	// and check the assumption in SysMap.
-	if(NaCl || sizeof(void*) == 8) {
-		*reserved = false;
-		return v;
-	}
-	
-	p = runtime·mmap(v, n, PROT_NONE, MAP_ANON|MAP_PRIVATE, -1, 0);
-	if(p < (void*)4096)
-		return nil;
-	*reserved = true;
-	return p;
-}
-
-void
-runtime·SysMap(void *v, uintptr n, bool reserved, uint64 *stat)
-{
-	void *p;
-	
-	runtime·xadd64(stat, n);
-
-	// On 64-bit, we don't actually have v reserved, so tread carefully.
-	if(!reserved) {
-		p = runtime·mmap(v, n, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0);
-		if(p == (void*)ENOMEM) {
-			runtime·printf("SysMap(%p, %p): %p\n", v, n, p);
-			runtime·throw("runtime: out of memory");
-		}
-		if(p != v) {
-			runtime·printf("SysMap(%p, %p): %p\n", v, n, p);
-			runtime·printf("runtime: address space conflict: map(%p) = %p\n", v, p);
-			runtime·throw("runtime: address space conflict");
-		}
-		if(Debug)
-			runtime·printf("SysMap(%p, %p) = %p\n", v, n, p);
-		return;
-	}
-
-	p = runtime·mmap(v, n, PROT_READ|PROT_WRITE, MAP_ANON|MAP_FIXED|MAP_PRIVATE, -1, 0);
-	if(p == (void*)ENOMEM) {
-		runtime·printf("SysMap(%p, %p): %p\n", v, n, p);
-		runtime·throw("runtime: out of memory");
-	}
-	if(p != v) {
-		runtime·printf("SysMap(%p, %p): %p\n", v, n, p);
-		runtime·printf("mmap MAP_FIXED %p returned %p\n", v, p);
-		runtime·throw("runtime: cannot map pages in arena address space");
-	}
-	if(Debug)
-		runtime·printf("SysMap(%p, %p) = %p\n", v, n, p);
-}
diff --git a/src/pkg/runtime/mem_netbsd.c b/src/pkg/runtime/mem_netbsd.c
deleted file mode 100644
index 861ae90..0000000
--- a/src/pkg/runtime/mem_netbsd.c
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright 2010 The Go 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 "runtime.h"
-#include "arch_GOARCH.h"
-#include "defs_GOOS_GOARCH.h"
-#include "os_GOOS.h"
-#include "malloc.h"
-
-enum
-{
-	ENOMEM = 12,
-};
-
-void*
-runtime·SysAlloc(uintptr n, uint64 *stat)
-{
-	void *v;
-
-	v = runtime·mmap(nil, n, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0);
-	if(v < (void*)4096)
-		return nil;
-	runtime·xadd64(stat, n);
-	return v;
-}
-
-void
-runtime·SysUnused(void *v, uintptr n)
-{
-	runtime·madvise(v, n, MADV_FREE);
-}
-
-void
-runtime·SysUsed(void *v, uintptr n)
-{
-	USED(v);
-	USED(n);
-}
-
-void
-runtime·SysFree(void *v, uintptr n, uint64 *stat)
-{
-	runtime·xadd64(stat, -(uint64)n);
-	runtime·munmap(v, n);
-}
-
-void
-runtime·SysFault(void *v, uintptr n)
-{
-	runtime·mmap(v, n, PROT_NONE, MAP_ANON|MAP_PRIVATE|MAP_FIXED, -1, 0);
-}
-
-void*
-runtime·SysReserve(void *v, uintptr n, bool *reserved)
-{
-	void *p;
-
-	// On 64-bit, people with ulimit -v set complain if we reserve too
-	// much address space.  Instead, assume that the reservation is okay
-	// and check the assumption in SysMap.
-	if(sizeof(void*) == 8 && n > 1LL<<32) {
-		*reserved = false;
-		return v;
-	}
-
-	p = runtime·mmap(v, n, PROT_NONE, MAP_ANON|MAP_PRIVATE, -1, 0);
-	if(p < (void*)4096)
-		return nil;
-	*reserved = true;
-	return p;
-}
-
-void
-runtime·SysMap(void *v, uintptr n, bool reserved, uint64 *stat)
-{
-	void *p;
-	
-	runtime·xadd64(stat, n);
-
-	// On 64-bit, we don't actually have v reserved, so tread carefully.
-	if(!reserved) {
-		p = runtime·mmap(v, n, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0);
-		if(p == (void*)ENOMEM)
-			runtime·throw("runtime: out of memory");
-		if(p != v) {
-			runtime·printf("runtime: address space conflict: map(%p) = %p\n", v, p);
-			runtime·throw("runtime: address space conflict");
-		}
-		return;
-	}
-
-	p = runtime·mmap(v, n, PROT_READ|PROT_WRITE, MAP_ANON|MAP_FIXED|MAP_PRIVATE, -1, 0);
-	if(p == (void*)ENOMEM)
-		runtime·throw("runtime: out of memory");
-	if(p != v)
-		runtime·throw("runtime: cannot map pages in arena address space");
-}
diff --git a/src/pkg/runtime/mem_openbsd.c b/src/pkg/runtime/mem_openbsd.c
deleted file mode 100644
index 861ae90..0000000
--- a/src/pkg/runtime/mem_openbsd.c
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright 2010 The Go 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 "runtime.h"
-#include "arch_GOARCH.h"
-#include "defs_GOOS_GOARCH.h"
-#include "os_GOOS.h"
-#include "malloc.h"
-
-enum
-{
-	ENOMEM = 12,
-};
-
-void*
-runtime·SysAlloc(uintptr n, uint64 *stat)
-{
-	void *v;
-
-	v = runtime·mmap(nil, n, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0);
-	if(v < (void*)4096)
-		return nil;
-	runtime·xadd64(stat, n);
-	return v;
-}
-
-void
-runtime·SysUnused(void *v, uintptr n)
-{
-	runtime·madvise(v, n, MADV_FREE);
-}
-
-void
-runtime·SysUsed(void *v, uintptr n)
-{
-	USED(v);
-	USED(n);
-}
-
-void
-runtime·SysFree(void *v, uintptr n, uint64 *stat)
-{
-	runtime·xadd64(stat, -(uint64)n);
-	runtime·munmap(v, n);
-}
-
-void
-runtime·SysFault(void *v, uintptr n)
-{
-	runtime·mmap(v, n, PROT_NONE, MAP_ANON|MAP_PRIVATE|MAP_FIXED, -1, 0);
-}
-
-void*
-runtime·SysReserve(void *v, uintptr n, bool *reserved)
-{
-	void *p;
-
-	// On 64-bit, people with ulimit -v set complain if we reserve too
-	// much address space.  Instead, assume that the reservation is okay
-	// and check the assumption in SysMap.
-	if(sizeof(void*) == 8 && n > 1LL<<32) {
-		*reserved = false;
-		return v;
-	}
-
-	p = runtime·mmap(v, n, PROT_NONE, MAP_ANON|MAP_PRIVATE, -1, 0);
-	if(p < (void*)4096)
-		return nil;
-	*reserved = true;
-	return p;
-}
-
-void
-runtime·SysMap(void *v, uintptr n, bool reserved, uint64 *stat)
-{
-	void *p;
-	
-	runtime·xadd64(stat, n);
-
-	// On 64-bit, we don't actually have v reserved, so tread carefully.
-	if(!reserved) {
-		p = runtime·mmap(v, n, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0);
-		if(p == (void*)ENOMEM)
-			runtime·throw("runtime: out of memory");
-		if(p != v) {
-			runtime·printf("runtime: address space conflict: map(%p) = %p\n", v, p);
-			runtime·throw("runtime: address space conflict");
-		}
-		return;
-	}
-
-	p = runtime·mmap(v, n, PROT_READ|PROT_WRITE, MAP_ANON|MAP_FIXED|MAP_PRIVATE, -1, 0);
-	if(p == (void*)ENOMEM)
-		runtime·throw("runtime: out of memory");
-	if(p != v)
-		runtime·throw("runtime: cannot map pages in arena address space");
-}
diff --git a/src/pkg/runtime/mem_plan9.c b/src/pkg/runtime/mem_plan9.c
deleted file mode 100644
index bbf04c7..0000000
--- a/src/pkg/runtime/mem_plan9.c
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright 2010 The Go 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 "runtime.h"
-#include "defs_GOOS_GOARCH.h"
-#include "arch_GOARCH.h"
-#include "malloc.h"
-#include "os_GOOS.h"
-
-extern byte end[];
-static byte *bloc = { end };
-static Lock memlock;
-
-enum
-{
-	Round = PAGESIZE-1
-};
-
-void*
-runtime·SysAlloc(uintptr nbytes, uint64 *stat)
-{
-	uintptr bl;
-
-	runtime·lock(&memlock);
-	// Plan 9 sbrk from /sys/src/libc/9sys/sbrk.c
-	bl = ((uintptr)bloc + Round) & ~Round;
-	if(runtime·brk_((void*)(bl + nbytes)) < 0) {
-		runtime·unlock(&memlock);
-		return nil;
-	}
-	bloc = (byte*)bl + nbytes;
-	runtime·unlock(&memlock);
-	runtime·xadd64(stat, nbytes);
-	return (void*)bl;
-}
-
-void
-runtime·SysFree(void *v, uintptr nbytes, uint64 *stat)
-{
-	runtime·xadd64(stat, -(uint64)nbytes);
-	runtime·lock(&memlock);
-	// from tiny/mem.c
-	// Push pointer back if this is a free
-	// of the most recent SysAlloc.
-	nbytes += (nbytes + Round) & ~Round;
-	if(bloc == (byte*)v+nbytes)
-		bloc -= nbytes;
-	runtime·unlock(&memlock);
-}
-
-void
-runtime·SysUnused(void *v, uintptr nbytes)
-{
-	USED(v, nbytes);
-}
-
-void
-runtime·SysUsed(void *v, uintptr nbytes)
-{
-	USED(v, nbytes);
-}
-
-void
-runtime·SysMap(void *v, uintptr nbytes, bool reserved, uint64 *stat)
-{
-	USED(v, nbytes, reserved, stat);
-}
-
-void
-runtime·SysFault(void *v, uintptr nbytes)
-{
-	USED(v, nbytes);
-}
-
-void*
-runtime·SysReserve(void *v, uintptr nbytes, bool *reserved)
-{
-	USED(v);
-	*reserved = true;
-	return runtime·SysAlloc(nbytes, &mstats.heap_sys);
-}
diff --git a/src/pkg/runtime/mem_solaris.c b/src/pkg/runtime/mem_solaris.c
deleted file mode 100644
index 0342228..0000000
--- a/src/pkg/runtime/mem_solaris.c
+++ /dev/null
@@ -1,99 +0,0 @@
-// Copyright 2010 The Go 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 "runtime.h"
-#include "arch_GOARCH.h"
-#include "defs_GOOS_GOARCH.h"
-#include "os_GOOS.h"
-#include "malloc.h"
-
-enum
-{
-	ENOMEM = 12,
-};
-
-void*
-runtime·SysAlloc(uintptr n, uint64 *stat)
-{
-	void *v;
-
-	v = runtime·mmap(nil, n, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0);
-	if(v < (void*)4096)
-		return nil;
-	runtime·xadd64(stat, n);
-	return v;
-}
-
-void
-runtime·SysUnused(void *v, uintptr n)
-{
-	USED(v);
-	USED(n);
-}
-
-void
-runtime·SysUsed(void *v, uintptr n)
-{
-	USED(v);
-	USED(n);
-}
-
-void
-runtime·SysFree(void *v, uintptr n, uint64 *stat)
-{
-	runtime·xadd64(stat, -(uint64)n);
-	runtime·munmap(v, n);
-}
-
-void
-runtime·SysFault(void *v, uintptr n)
-{
-	runtime·mmap(v, n, PROT_NONE, MAP_ANON|MAP_PRIVATE|MAP_FIXED, -1, 0);
-}
-
-void*
-runtime·SysReserve(void *v, uintptr n, bool *reserved)
-{
-	void *p;
-
-	// On 64-bit, people with ulimit -v set complain if we reserve too
-	// much address space.  Instead, assume that the reservation is okay
-	// and check the assumption in SysMap.
-	if(sizeof(void*) == 8 && n > 1LL<<32) {
-		*reserved = false;
-		return v;
-	}
-	
-	p = runtime·mmap(v, n, PROT_NONE, MAP_ANON|MAP_PRIVATE, -1, 0);
-	if(p < (void*)4096)
-		return nil;
-	*reserved = true;
-	return p;
-}
-
-void
-runtime·SysMap(void *v, uintptr n, bool reserved, uint64 *stat)
-{
-	void *p;
-	
-	runtime·xadd64(stat, n);
-
-	// On 64-bit, we don't actually have v reserved, so tread carefully.
-	if(!reserved) {
-		p = runtime·mmap(v, n, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0);
-		if(p == (void*)ENOMEM)
-			runtime·throw("runtime: out of memory");
-		if(p != v) {
-			runtime·printf("runtime: address space conflict: map(%p) = %p\n", v, p);
-			runtime·throw("runtime: address space conflict");
-		}
-		return;
-	}
-
-	p = runtime·mmap(v, n, PROT_READ|PROT_WRITE, MAP_ANON|MAP_FIXED|MAP_PRIVATE, -1, 0);
-	if(p == (void*)ENOMEM)
-		runtime·throw("runtime: out of memory");
-	if(p != v)
-		runtime·throw("runtime: cannot map pages in arena address space");
-}
diff --git a/src/pkg/runtime/mem_windows.c b/src/pkg/runtime/mem_windows.c
deleted file mode 100644
index 77ec6e9..0000000
--- a/src/pkg/runtime/mem_windows.c
+++ /dev/null
@@ -1,118 +0,0 @@
-// Copyright 2010 The Go 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 "runtime.h"
-#include "arch_GOARCH.h"
-#include "os_GOOS.h"
-#include "defs_GOOS_GOARCH.h"
-#include "malloc.h"
-
-enum {
-	MEM_COMMIT = 0x1000,
-	MEM_RESERVE = 0x2000,
-	MEM_DECOMMIT = 0x4000,
-	MEM_RELEASE = 0x8000,
-	
-	PAGE_READWRITE = 0x0004,
-	PAGE_NOACCESS = 0x0001,
-};
-
-#pragma dynimport runtime·VirtualAlloc VirtualAlloc "kernel32.dll"
-#pragma dynimport runtime·VirtualFree VirtualFree "kernel32.dll"
-#pragma dynimport runtime·VirtualProtect VirtualProtect "kernel32.dll"
-extern void *runtime·VirtualAlloc;
-extern void *runtime·VirtualFree;
-extern void *runtime·VirtualProtect;
-
-void*
-runtime·SysAlloc(uintptr n, uint64 *stat)
-{
-	runtime·xadd64(stat, n);
-	return runtime·stdcall(runtime·VirtualAlloc, 4, nil, n, (uintptr)(MEM_COMMIT|MEM_RESERVE), (uintptr)PAGE_READWRITE);
-}
-
-void
-runtime·SysUnused(void *v, uintptr n)
-{
-	void *r;
-	uintptr small;
-
-	r = runtime·stdcall(runtime·VirtualFree, 3, v, n, (uintptr)MEM_DECOMMIT);
-	if(r != nil)
-		return;
-
-	// Decommit failed. Usual reason is that we've merged memory from two different
-	// VirtualAlloc calls, and Windows will only let each VirtualFree handle pages from
-	// a single VirtualAlloc. It is okay to specify a subset of the pages from a single alloc,
-	// just not pages from multiple allocs. This is a rare case, arising only when we're
-	// trying to give memory back to the operating system, which happens on a time
-	// scale of minutes. It doesn't have to be terribly fast. Instead of extra bookkeeping
-	// on all our VirtualAlloc calls, try freeing successively smaller pieces until
-	// we manage to free something, and then repeat. This ends up being O(n log n)
-	// in the worst case, but that's fast enough.
-	while(n > 0) {
-		small = n;
-		while(small >= 4096 && runtime·stdcall(runtime·VirtualFree, 3, v, small, (uintptr)MEM_DECOMMIT) == nil)
-			small = (small / 2) & ~(4096-1);
-		if(small < 4096)
-			runtime·throw("runtime: failed to decommit pages");
-		v = (byte*)v + small;
-		n -= small;
-	}
-}
-
-void
-runtime·SysUsed(void *v, uintptr n)
-{
-	void *r;
-
-	r = runtime·stdcall(runtime·VirtualAlloc, 4, v, n, (uintptr)MEM_COMMIT, (uintptr)PAGE_READWRITE);
-	if(r != v)
-		runtime·throw("runtime: failed to commit pages");
-}
-
-void
-runtime·SysFree(void *v, uintptr n, uint64 *stat)
-{
-	uintptr r;
-
-	runtime·xadd64(stat, -(uint64)n);
-	r = (uintptr)runtime·stdcall(runtime·VirtualFree, 3, v, (uintptr)0, (uintptr)MEM_RELEASE);
-	if(r == 0)
-		runtime·throw("runtime: failed to release pages");
-}
-
-void
-runtime·SysFault(void *v, uintptr n)
-{
-	// SysUnused makes the memory inaccessible and prevents its reuse
-	runtime·SysUnused(v, n);
-}
-
-void*
-runtime·SysReserve(void *v, uintptr n, bool *reserved)
-{
-	*reserved = true;
-	// v is just a hint.
-	// First try at v.
-	v = runtime·stdcall(runtime·VirtualAlloc, 4, v, n, (uintptr)MEM_RESERVE, (uintptr)PAGE_READWRITE);
-	if(v != nil)
-		return v;
-	
-	// Next let the kernel choose the address.
-	return runtime·stdcall(runtime·VirtualAlloc, 4, nil, n, (uintptr)MEM_RESERVE, (uintptr)PAGE_READWRITE);
-}
-
-void
-runtime·SysMap(void *v, uintptr n, bool reserved, uint64 *stat)
-{
-	void *p;
-
-	USED(reserved);
-
-	runtime·xadd64(stat, n);
-	p = runtime·stdcall(runtime·VirtualAlloc, 4, v, n, (uintptr)MEM_COMMIT, (uintptr)PAGE_READWRITE);
-	if(p != v)
-		runtime·throw("runtime: cannot map pages in arena address space");
-}
diff --git a/src/pkg/runtime/memclr_386.s b/src/pkg/runtime/memclr_386.s
deleted file mode 100644
index 4b7580c..0000000
--- a/src/pkg/runtime/memclr_386.s
+++ /dev/null
@@ -1,127 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build !plan9
-
-#include "../../cmd/ld/textflag.h"
-
-// void runtime·memclr(void*, uintptr)
-TEXT runtime·memclr(SB), NOSPLIT, $0-8
-	MOVL	ptr+0(FP), DI
-	MOVL	n+4(FP), BX
-	XORL	AX, AX
-
-	// MOVOU seems always faster than REP STOSL.
-clr_tail:
-	TESTL	BX, BX
-	JEQ	clr_0
-	CMPL	BX, $2
-	JBE	clr_1or2
-	CMPL	BX, $4
-	JBE	clr_3or4
-	CMPL	BX, $8
-	JBE	clr_5through8
-	CMPL	BX, $16
-	JBE	clr_9through16
-	TESTL	$0x4000000, runtime·cpuid_edx(SB) // check for sse2
-	JEQ	nosse2
-	PXOR	X0, X0
-	CMPL	BX, $32
-	JBE	clr_17through32
-	CMPL	BX, $64
-	JBE	clr_33through64
-	CMPL	BX, $128
-	JBE	clr_65through128
-	CMPL	BX, $256
-	JBE	clr_129through256
-	// TODO: use branch table and BSR to make this just a single dispatch
-
-clr_loop:
-	MOVOU	X0, 0(DI)
-	MOVOU	X0, 16(DI)
-	MOVOU	X0, 32(DI)
-	MOVOU	X0, 48(DI)
-	MOVOU	X0, 64(DI)
-	MOVOU	X0, 80(DI)
-	MOVOU	X0, 96(DI)
-	MOVOU	X0, 112(DI)
-	MOVOU	X0, 128(DI)
-	MOVOU	X0, 144(DI)
-	MOVOU	X0, 160(DI)
-	MOVOU	X0, 176(DI)
-	MOVOU	X0, 192(DI)
-	MOVOU	X0, 208(DI)
-	MOVOU	X0, 224(DI)
-	MOVOU	X0, 240(DI)
-	SUBL	$256, BX
-	ADDL	$256, DI
-	CMPL	BX, $256
-	JAE	clr_loop
-	JMP	clr_tail
-
-clr_1or2:
-	MOVB	AX, (DI)
-	MOVB	AX, -1(DI)(BX*1)
-clr_0:
-	RET
-clr_3or4:
-	MOVW	AX, (DI)
-	MOVW	AX, -2(DI)(BX*1)
-	RET
-clr_5through8:
-	MOVL	AX, (DI)
-	MOVL	AX, -4(DI)(BX*1)
-	RET
-clr_9through16:
-	MOVL	AX, (DI)
-	MOVL	AX, 4(DI)
-	MOVL	AX, -8(DI)(BX*1)
-	MOVL	AX, -4(DI)(BX*1)
-	RET
-clr_17through32:
-	MOVOU	X0, (DI)
-	MOVOU	X0, -16(DI)(BX*1)
-	RET
-clr_33through64:
-	MOVOU	X0, (DI)
-	MOVOU	X0, 16(DI)
-	MOVOU	X0, -32(DI)(BX*1)
-	MOVOU	X0, -16(DI)(BX*1)
-	RET
-clr_65through128:
-	MOVOU	X0, (DI)
-	MOVOU	X0, 16(DI)
-	MOVOU	X0, 32(DI)
-	MOVOU	X0, 48(DI)
-	MOVOU	X0, -64(DI)(BX*1)
-	MOVOU	X0, -48(DI)(BX*1)
-	MOVOU	X0, -32(DI)(BX*1)
-	MOVOU	X0, -16(DI)(BX*1)
-	RET
-clr_129through256:
-	MOVOU	X0, (DI)
-	MOVOU	X0, 16(DI)
-	MOVOU	X0, 32(DI)
-	MOVOU	X0, 48(DI)
-	MOVOU	X0, 64(DI)
-	MOVOU	X0, 80(DI)
-	MOVOU	X0, 96(DI)
-	MOVOU	X0, 112(DI)
-	MOVOU	X0, -128(DI)(BX*1)
-	MOVOU	X0, -112(DI)(BX*1)
-	MOVOU	X0, -96(DI)(BX*1)
-	MOVOU	X0, -80(DI)(BX*1)
-	MOVOU	X0, -64(DI)(BX*1)
-	MOVOU	X0, -48(DI)(BX*1)
-	MOVOU	X0, -32(DI)(BX*1)
-	MOVOU	X0, -16(DI)(BX*1)
-	RET
-nosse2:
-	MOVL	BX, CX
-	SHRL	$2, CX
-	REP
-	STOSL
-	ANDL	$3, BX
-	JNE	clr_tail
-	RET
diff --git a/src/pkg/runtime/memclr_amd64.s b/src/pkg/runtime/memclr_amd64.s
deleted file mode 100644
index 6b79363..0000000
--- a/src/pkg/runtime/memclr_amd64.s
+++ /dev/null
@@ -1,116 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build !plan9
-
-#include "../../cmd/ld/textflag.h"
-
-// void runtime·memclr(void*, uintptr)
-TEXT runtime·memclr(SB), NOSPLIT, $0-16
-	MOVQ	ptr+0(FP), DI
-	MOVQ	n+8(FP), BX
-	XORQ	AX, AX
-
-	// MOVOU seems always faster than REP STOSQ.
-clr_tail:
-	TESTQ	BX, BX
-	JEQ	clr_0
-	CMPQ	BX, $2
-	JBE	clr_1or2
-	CMPQ	BX, $4
-	JBE	clr_3or4
-	CMPQ	BX, $8
-	JBE	clr_5through8
-	CMPQ	BX, $16
-	JBE	clr_9through16
-	PXOR	X0, X0
-	CMPQ	BX, $32
-	JBE	clr_17through32
-	CMPQ	BX, $64
-	JBE	clr_33through64
-	CMPQ	BX, $128
-	JBE	clr_65through128
-	CMPQ	BX, $256
-	JBE	clr_129through256
-	// TODO: use branch table and BSR to make this just a single dispatch
-	// TODO: for really big clears, use MOVNTDQ.
-
-clr_loop:
-	MOVOU	X0, 0(DI)
-	MOVOU	X0, 16(DI)
-	MOVOU	X0, 32(DI)
-	MOVOU	X0, 48(DI)
-	MOVOU	X0, 64(DI)
-	MOVOU	X0, 80(DI)
-	MOVOU	X0, 96(DI)
-	MOVOU	X0, 112(DI)
-	MOVOU	X0, 128(DI)
-	MOVOU	X0, 144(DI)
-	MOVOU	X0, 160(DI)
-	MOVOU	X0, 176(DI)
-	MOVOU	X0, 192(DI)
-	MOVOU	X0, 208(DI)
-	MOVOU	X0, 224(DI)
-	MOVOU	X0, 240(DI)
-	SUBQ	$256, BX
-	ADDQ	$256, DI
-	CMPQ	BX, $256
-	JAE	clr_loop
-	JMP	clr_tail
-
-clr_1or2:
-	MOVB	AX, (DI)
-	MOVB	AX, -1(DI)(BX*1)
-clr_0:
-	RET
-clr_3or4:
-	MOVW	AX, (DI)
-	MOVW	AX, -2(DI)(BX*1)
-	RET
-clr_5through8:
-	MOVL	AX, (DI)
-	MOVL	AX, -4(DI)(BX*1)
-	RET
-clr_9through16:
-	MOVQ	AX, (DI)
-	MOVQ	AX, -8(DI)(BX*1)
-	RET
-clr_17through32:
-	MOVOU	X0, (DI)
-	MOVOU	X0, -16(DI)(BX*1)
-	RET
-clr_33through64:
-	MOVOU	X0, (DI)
-	MOVOU	X0, 16(DI)
-	MOVOU	X0, -32(DI)(BX*1)
-	MOVOU	X0, -16(DI)(BX*1)
-	RET
-clr_65through128:
-	MOVOU	X0, (DI)
-	MOVOU	X0, 16(DI)
-	MOVOU	X0, 32(DI)
-	MOVOU	X0, 48(DI)
-	MOVOU	X0, -64(DI)(BX*1)
-	MOVOU	X0, -48(DI)(BX*1)
-	MOVOU	X0, -32(DI)(BX*1)
-	MOVOU	X0, -16(DI)(BX*1)
-	RET
-clr_129through256:
-	MOVOU	X0, (DI)
-	MOVOU	X0, 16(DI)
-	MOVOU	X0, 32(DI)
-	MOVOU	X0, 48(DI)
-	MOVOU	X0, 64(DI)
-	MOVOU	X0, 80(DI)
-	MOVOU	X0, 96(DI)
-	MOVOU	X0, 112(DI)
-	MOVOU	X0, -128(DI)(BX*1)
-	MOVOU	X0, -112(DI)(BX*1)
-	MOVOU	X0, -96(DI)(BX*1)
-	MOVOU	X0, -80(DI)(BX*1)
-	MOVOU	X0, -64(DI)(BX*1)
-	MOVOU	X0, -48(DI)(BX*1)
-	MOVOU	X0, -32(DI)(BX*1)
-	MOVOU	X0, -16(DI)(BX*1)
-	RET
diff --git a/src/pkg/runtime/memclr_arm.s b/src/pkg/runtime/memclr_arm.s
deleted file mode 100644
index b19ea72..0000000
--- a/src/pkg/runtime/memclr_arm.s
+++ /dev/null
@@ -1,87 +0,0 @@
-// Inferno's libkern/memset-arm.s
-// http://code.google.com/p/inferno-os/source/browse/libkern/memset-arm.s
-//
-//         Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//         Revisions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com).  All rights reserved.
-//         Portions Copyright 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-#include "../../cmd/ld/textflag.h"
-
-TO = 8
-TOE = 11
-N = 12
-TMP = 12				/* N and TMP don't overlap */
-
-TEXT runtime·memclr(SB),NOSPLIT,$0-8
-	MOVW	ptr+0(FP), R(TO)
-	MOVW	n+4(FP), R(N)
-	MOVW	$0, R(0)
-
-	ADD	R(N), R(TO), R(TOE)	/* to end pointer */
-
-	CMP	$4, R(N)		/* need at least 4 bytes to copy */
-	BLT	_1tail
-
-_4align:				/* align on 4 */
-	AND.S	$3, R(TO), R(TMP)
-	BEQ	_4aligned
-
-	MOVBU.P	R(0), 1(R(TO))		/* implicit write back */
-	B	_4align
-
-_4aligned:
-	SUB	$31, R(TOE), R(TMP)	/* do 32-byte chunks if possible */
-	CMP	R(TMP), R(TO)
-	BHS	_4tail
-
-	MOVW	R0, R1			/* replicate */
-	MOVW	R0, R2
-	MOVW	R0, R3
-	MOVW	R0, R4
-	MOVW	R0, R5
-	MOVW	R0, R6
-	MOVW	R0, R7
-
-_f32loop:
-	CMP	R(TMP), R(TO)
-	BHS	_4tail
-
-	MOVM.IA.W [R0-R7], (R(TO))
-	B	_f32loop
-
-_4tail:
-	SUB	$3, R(TOE), R(TMP)	/* do remaining words if possible */
-_4loop:
-	CMP	R(TMP), R(TO)
-	BHS	_1tail
-
-	MOVW.P	R(0), 4(R(TO))		/* implicit write back */
-	B	_4loop
-
-_1tail:
-	CMP	R(TO), R(TOE)
-	BEQ	_return
-
-	MOVBU.P	R(0), 1(R(TO))		/* implicit write back */
-	B	_1tail
-
-_return:
-	RET
diff --git a/src/pkg/runtime/memclr_plan9_386.s b/src/pkg/runtime/memclr_plan9_386.s
deleted file mode 100644
index 9b49678..0000000
--- a/src/pkg/runtime/memclr_plan9_386.s
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../cmd/ld/textflag.h"
-
-// void runtime·memclr(void*, uintptr)
-TEXT runtime·memclr(SB), NOSPLIT, $0-8
-	MOVL	ptr+0(FP), DI
-	MOVL	n+4(FP), BX
-	XORL	AX, AX
-
-clr_tail:
-	TESTL	BX, BX
-	JEQ	clr_0
-	CMPL	BX, $2
-	JBE	clr_1or2
-	CMPL	BX, $4
-	JBE	clr_3or4
-	CMPL	BX, $8
-	JBE	clr_5through8
-	CMPL	BX, $16
-	JBE	clr_9through16
-	MOVL	BX, CX
-	SHRL	$2, CX
-	REP
-	STOSL
-	ANDL	$3, BX
-	JNE	clr_tail
-	RET
-
-clr_1or2:
-	MOVB	AX, (DI)
-	MOVB	AX, -1(DI)(BX*1)
-clr_0:
-	RET
-clr_3or4:
-	MOVW	AX, (DI)
-	MOVW	AX, -2(DI)(BX*1)
-	RET
-clr_5through8:
-	MOVL	AX, (DI)
-	MOVL	AX, -4(DI)(BX*1)
-	RET
-clr_9through16:
-	MOVL	AX, (DI)
-	MOVL	AX, 4(DI)
-	MOVL	AX, -8(DI)(BX*1)
-	MOVL	AX, -4(DI)(BX*1)
-	RET
diff --git a/src/pkg/runtime/memclr_plan9_amd64.s b/src/pkg/runtime/memclr_plan9_amd64.s
deleted file mode 100644
index 6b33054..0000000
--- a/src/pkg/runtime/memclr_plan9_amd64.s
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../cmd/ld/textflag.h"
-
-// void runtime·memclr(void*, uintptr)
-TEXT runtime·memclr(SB), NOSPLIT, $0-16
-	MOVQ	ptr+0(FP), DI
-	MOVQ	n+8(FP), BX
-	XORQ	AX, AX
-
-clr_tail:
-	TESTQ	BX, BX
-	JEQ	clr_0
-	CMPQ	BX, $2
-	JBE	clr_1or2
-	CMPQ	BX, $4
-	JBE	clr_3or4
-	CMPQ	BX, $8
-	JBE	clr_5through8
-	CMPQ	BX, $16
-	JBE	clr_9through16
-	MOVQ	BX, CX
-	SHRQ	$2, CX
-	REP
-	STOSQ
-	ANDQ	$3, BX
-	JNE	clr_tail
-	RET
-
-clr_1or2:
-	MOVB	AX, (DI)
-	MOVB	AX, -1(DI)(BX*1)
-clr_0:
-	RET
-clr_3or4:
-	MOVW	AX, (DI)
-	MOVW	AX, -2(DI)(BX*1)
-	RET
-clr_5through8:
-	MOVL	AX, (DI)
-	MOVL	AX, -4(DI)(BX*1)
-	RET
-clr_9through16:
-	MOVQ	AX, (DI)
-	MOVQ	AX, -8(DI)(BX*1)
-	RET
diff --git a/src/pkg/runtime/memmove_386.s b/src/pkg/runtime/memmove_386.s
deleted file mode 100644
index 3aed8ad..0000000
--- a/src/pkg/runtime/memmove_386.s
+++ /dev/null
@@ -1,175 +0,0 @@
-// Inferno's libkern/memmove-386.s
-// http://code.google.com/p/inferno-os/source/browse/libkern/memmove-386.s
-//
-//         Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//         Revisions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com).  All rights reserved.
-//         Portions Copyright 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-// +build !plan9
-
-#include "../../cmd/ld/textflag.h"
-
-TEXT runtime·memmove(SB), NOSPLIT, $0-12
-	MOVL	to+0(FP), DI
-	MOVL	fr+4(FP), SI
-	MOVL	n+8(FP), BX
-
-	// REP instructions have a high startup cost, so we handle small sizes
-	// with some straightline code.  The REP MOVSL instruction is really fast
-	// for large sizes.  The cutover is approximately 1K.  We implement up to
-	// 128 because that is the maximum SSE register load (loading all data
-	// into registers lets us ignore copy direction).
-tail:
-	TESTL	BX, BX
-	JEQ	move_0
-	CMPL	BX, $2
-	JBE	move_1or2
-	CMPL	BX, $4
-	JBE	move_3or4
-	CMPL	BX, $8
-	JBE	move_5through8
-	CMPL	BX, $16
-	JBE	move_9through16
-	TESTL	$0x4000000, runtime·cpuid_edx(SB) // check for sse2
-	JEQ	nosse2
-	CMPL	BX, $32
-	JBE	move_17through32
-	CMPL	BX, $64
-	JBE	move_33through64
-	CMPL	BX, $128
-	JBE	move_65through128
-	// TODO: use branch table and BSR to make this just a single dispatch
-
-nosse2:
-/*
- * check and set for backwards
- */
-	CMPL	SI, DI
-	JLS	back
-
-/*
- * forward copy loop
- */
-forward:	
-	MOVL	BX, CX
-	SHRL	$2, CX
-	ANDL	$3, BX
-
-	REP;	MOVSL
-	JMP	tail
-/*
- * check overlap
- */
-back:
-	MOVL	SI, CX
-	ADDL	BX, CX
-	CMPL	CX, DI
-	JLS	forward
-/*
- * whole thing backwards has
- * adjusted addresses
- */
-
-	ADDL	BX, DI
-	ADDL	BX, SI
-	STD
-
-/*
- * copy
- */
-	MOVL	BX, CX
-	SHRL	$2, CX
-	ANDL	$3, BX
-
-	SUBL	$4, DI
-	SUBL	$4, SI
-	REP;	MOVSL
-
-	CLD
-	ADDL	$4, DI
-	ADDL	$4, SI
-	SUBL	BX, DI
-	SUBL	BX, SI
-	JMP	tail
-
-move_1or2:
-	MOVB	(SI), AX
-	MOVB	-1(SI)(BX*1), CX
-	MOVB	AX, (DI)
-	MOVB	CX, -1(DI)(BX*1)
-move_0:
-	RET
-move_3or4:
-	MOVW	(SI), AX
-	MOVW	-2(SI)(BX*1), CX
-	MOVW	AX, (DI)
-	MOVW	CX, -2(DI)(BX*1)
-	RET
-move_5through8:
-	MOVL	(SI), AX
-	MOVL	-4(SI)(BX*1), CX
-	MOVL	AX, (DI)
-	MOVL	CX, -4(DI)(BX*1)
-	RET
-move_9through16:
-	MOVL	(SI), AX
-	MOVL	4(SI), CX
-	MOVL	-8(SI)(BX*1), DX
-	MOVL	-4(SI)(BX*1), BP
-	MOVL	AX, (DI)
-	MOVL	CX, 4(DI)
-	MOVL	DX, -8(DI)(BX*1)
-	MOVL	BP, -4(DI)(BX*1)
-	RET
-move_17through32:
-	MOVOU	(SI), X0
-	MOVOU	-16(SI)(BX*1), X1
-	MOVOU	X0, (DI)
-	MOVOU	X1, -16(DI)(BX*1)
-	RET
-move_33through64:
-	MOVOU	(SI), X0
-	MOVOU	16(SI), X1
-	MOVOU	-32(SI)(BX*1), X2
-	MOVOU	-16(SI)(BX*1), X3
-	MOVOU	X0, (DI)
-	MOVOU	X1, 16(DI)
-	MOVOU	X2, -32(DI)(BX*1)
-	MOVOU	X3, -16(DI)(BX*1)
-	RET
-move_65through128:
-	MOVOU	(SI), X0
-	MOVOU	16(SI), X1
-	MOVOU	32(SI), X2
-	MOVOU	48(SI), X3
-	MOVOU	-64(SI)(BX*1), X4
-	MOVOU	-48(SI)(BX*1), X5
-	MOVOU	-32(SI)(BX*1), X6
-	MOVOU	-16(SI)(BX*1), X7
-	MOVOU	X0, (DI)
-	MOVOU	X1, 16(DI)
-	MOVOU	X2, 32(DI)
-	MOVOU	X3, 48(DI)
-	MOVOU	X4, -64(DI)(BX*1)
-	MOVOU	X5, -48(DI)(BX*1)
-	MOVOU	X6, -32(DI)(BX*1)
-	MOVOU	X7, -16(DI)(BX*1)
-	RET
diff --git a/src/pkg/runtime/memmove_amd64.s b/src/pkg/runtime/memmove_amd64.s
deleted file mode 100644
index 5895846..0000000
--- a/src/pkg/runtime/memmove_amd64.s
+++ /dev/null
@@ -1,207 +0,0 @@
-// Derived from Inferno's libkern/memmove-386.s (adapted for amd64)
-// http://code.google.com/p/inferno-os/source/browse/libkern/memmove-386.s
-//
-//         Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//         Revisions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com).  All rights reserved.
-//         Portions Copyright 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-// +build !plan9
-
-#include "../../cmd/ld/textflag.h"
-
-// void runtime·memmove(void*, void*, uintptr)
-TEXT runtime·memmove(SB), NOSPLIT, $0-24
-
-	MOVQ	to+0(FP), DI
-	MOVQ	fr+8(FP), SI
-	MOVQ	n+16(FP), BX
-
-	// REP instructions have a high startup cost, so we handle small sizes
-	// with some straightline code.  The REP MOVSQ instruction is really fast
-	// for large sizes.  The cutover is approximately 1K.  We implement up to
-	// 256 because that is the maximum SSE register load (loading all data
-	// into registers lets us ignore copy direction).
-tail:
-	TESTQ	BX, BX
-	JEQ	move_0
-	CMPQ	BX, $2
-	JBE	move_1or2
-	CMPQ	BX, $4
-	JBE	move_3or4
-	CMPQ	BX, $8
-	JBE	move_5through8
-	CMPQ	BX, $16
-	JBE	move_9through16
-	CMPQ	BX, $32
-	JBE	move_17through32
-	CMPQ	BX, $64
-	JBE	move_33through64
-	CMPQ	BX, $128
-	JBE	move_65through128
-	CMPQ	BX, $256
-	JBE	move_129through256
-	// TODO: use branch table and BSR to make this just a single dispatch
-
-/*
- * check and set for backwards
- */
-	CMPQ	SI, DI
-	JLS	back
-
-/*
- * forward copy loop
- */
-forward:
-	MOVQ	BX, CX
-	SHRQ	$3, CX
-	ANDQ	$7, BX
-
-	REP;	MOVSQ
-	JMP	tail
-
-back:
-/*
- * check overlap
- */
-	MOVQ	SI, CX
-	ADDQ	BX, CX
-	CMPQ	CX, DI
-	JLS	forward
-	
-/*
- * whole thing backwards has
- * adjusted addresses
- */
-	ADDQ	BX, DI
-	ADDQ	BX, SI
-	STD
-
-/*
- * copy
- */
-	MOVQ	BX, CX
-	SHRQ	$3, CX
-	ANDQ	$7, BX
-
-	SUBQ	$8, DI
-	SUBQ	$8, SI
-	REP;	MOVSQ
-
-	CLD
-	ADDQ	$8, DI
-	ADDQ	$8, SI
-	SUBQ	BX, DI
-	SUBQ	BX, SI
-	JMP	tail
-
-move_1or2:
-	MOVB	(SI), AX
-	MOVB	-1(SI)(BX*1), CX
-	MOVB	AX, (DI)
-	MOVB	CX, -1(DI)(BX*1)
-move_0:
-	RET
-move_3or4:
-	MOVW	(SI), AX
-	MOVW	-2(SI)(BX*1), CX
-	MOVW	AX, (DI)
-	MOVW	CX, -2(DI)(BX*1)
-	RET
-move_5through8:
-	MOVL	(SI), AX
-	MOVL	-4(SI)(BX*1), CX
-	MOVL	AX, (DI)
-	MOVL	CX, -4(DI)(BX*1)
-	RET
-move_9through16:
-	MOVQ	(SI), AX
-	MOVQ	-8(SI)(BX*1), CX
-	MOVQ	AX, (DI)
-	MOVQ	CX, -8(DI)(BX*1)
-	RET
-move_17through32:
-	MOVOU	(SI), X0
-	MOVOU	-16(SI)(BX*1), X1
-	MOVOU	X0, (DI)
-	MOVOU	X1, -16(DI)(BX*1)
-	RET
-move_33through64:
-	MOVOU	(SI), X0
-	MOVOU	16(SI), X1
-	MOVOU	-32(SI)(BX*1), X2
-	MOVOU	-16(SI)(BX*1), X3
-	MOVOU	X0, (DI)
-	MOVOU	X1, 16(DI)
-	MOVOU	X2, -32(DI)(BX*1)
-	MOVOU	X3, -16(DI)(BX*1)
-	RET
-move_65through128:
-	MOVOU	(SI), X0
-	MOVOU	16(SI), X1
-	MOVOU	32(SI), X2
-	MOVOU	48(SI), X3
-	MOVOU	-64(SI)(BX*1), X4
-	MOVOU	-48(SI)(BX*1), X5
-	MOVOU	-32(SI)(BX*1), X6
-	MOVOU	-16(SI)(BX*1), X7
-	MOVOU	X0, (DI)
-	MOVOU	X1, 16(DI)
-	MOVOU	X2, 32(DI)
-	MOVOU	X3, 48(DI)
-	MOVOU	X4, -64(DI)(BX*1)
-	MOVOU	X5, -48(DI)(BX*1)
-	MOVOU	X6, -32(DI)(BX*1)
-	MOVOU	X7, -16(DI)(BX*1)
-	RET
-move_129through256:
-	MOVOU	(SI), X0
-	MOVOU	16(SI), X1
-	MOVOU	32(SI), X2
-	MOVOU	48(SI), X3
-	MOVOU	64(SI), X4
-	MOVOU	80(SI), X5
-	MOVOU	96(SI), X6
-	MOVOU	112(SI), X7
-	MOVOU	-128(SI)(BX*1), X8
-	MOVOU	-112(SI)(BX*1), X9
-	MOVOU	-96(SI)(BX*1), X10
-	MOVOU	-80(SI)(BX*1), X11
-	MOVOU	-64(SI)(BX*1), X12
-	MOVOU	-48(SI)(BX*1), X13
-	MOVOU	-32(SI)(BX*1), X14
-	MOVOU	-16(SI)(BX*1), X15
-	MOVOU	X0, (DI)
-	MOVOU	X1, 16(DI)
-	MOVOU	X2, 32(DI)
-	MOVOU	X3, 48(DI)
-	MOVOU	X4, 64(DI)
-	MOVOU	X5, 80(DI)
-	MOVOU	X6, 96(DI)
-	MOVOU	X7, 112(DI)
-	MOVOU	X8, -128(DI)(BX*1)
-	MOVOU	X9, -112(DI)(BX*1)
-	MOVOU	X10, -96(DI)(BX*1)
-	MOVOU	X11, -80(DI)(BX*1)
-	MOVOU	X12, -64(DI)(BX*1)
-	MOVOU	X13, -48(DI)(BX*1)
-	MOVOU	X14, -32(DI)(BX*1)
-	MOVOU	X15, -16(DI)(BX*1)
-	RET
diff --git a/src/pkg/runtime/memmove_arm.s b/src/pkg/runtime/memmove_arm.s
deleted file mode 100644
index 9701dc9..0000000
--- a/src/pkg/runtime/memmove_arm.s
+++ /dev/null
@@ -1,261 +0,0 @@
-// Inferno's libkern/memmove-arm.s
-// http://code.google.com/p/inferno-os/source/browse/libkern/memmove-arm.s
-//
-//         Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//         Revisions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com).  All rights reserved.
-//         Portions Copyright 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-#include "../../cmd/ld/textflag.h"
-
-// TE or TS are spilled to the stack during bulk register moves.
-TS = 0
-TE = 8
-
-// Warning: the linker will use R11 to synthesize certain instructions. Please
-// take care and double check with objdump.
-FROM = 11
-N = 12
-TMP = 12				/* N and TMP don't overlap */
-TMP1 = 5
-
-RSHIFT = 5
-LSHIFT = 6
-OFFSET = 7
-
-BR0 = 0					/* shared with TS */
-BW0 = 1
-BR1 = 1
-BW1 = 2
-BR2 = 2
-BW2 = 3
-BR3 = 3
-BW3 = 4
-
-FW0 = 1
-FR0 = 2
-FW1 = 2
-FR1 = 3
-FW2 = 3
-FR2 = 4
-FW3 = 4
-FR3 = 8					/* shared with TE */
-
-TEXT runtime·memmove(SB), NOSPLIT, $4-12
-_memmove:
-	MOVW	to+0(FP), R(TS)
-	MOVW	from+4(FP), R(FROM)
-	MOVW	n+8(FP), R(N)
-
-	ADD	R(N), R(TS), R(TE)	/* to end pointer */
-
-	CMP	R(FROM), R(TS)
-	BLS	_forward
-
-_back:
-	ADD	R(N), R(FROM)		/* from end pointer */
-	CMP	$4, R(N)		/* need at least 4 bytes to copy */
-	BLT	_b1tail
-
-_b4align:				/* align destination on 4 */
-	AND.S	$3, R(TE), R(TMP)
-	BEQ	_b4aligned
-
-	MOVBU.W	-1(R(FROM)), R(TMP)	/* pre-indexed */
-	MOVBU.W	R(TMP), -1(R(TE))	/* pre-indexed */
-	B	_b4align
-
-_b4aligned:				/* is source now aligned? */
-	AND.S	$3, R(FROM), R(TMP)
-	BNE	_bunaligned
-
-	ADD	$31, R(TS), R(TMP)	/* do 32-byte chunks if possible */
-	MOVW	R(TS), savedts-4(SP)
-_b32loop:
-	CMP	R(TMP), R(TE)
-	BLS	_b4tail
-
-	MOVM.DB.W (R(FROM)), [R0-R7]
-	MOVM.DB.W [R0-R7], (R(TE))
-	B	_b32loop
-
-_b4tail:				/* do remaining words if possible */
-	MOVW	savedts-4(SP), R(TS)
-	ADD	$3, R(TS), R(TMP)
-_b4loop:
-	CMP	R(TMP), R(TE)
-	BLS	_b1tail
-
-	MOVW.W	-4(R(FROM)), R(TMP1)	/* pre-indexed */
-	MOVW.W	R(TMP1), -4(R(TE))	/* pre-indexed */
-	B	_b4loop
-
-_b1tail:				/* remaining bytes */
-	CMP	R(TE), R(TS)
-	BEQ	_return
-
-	MOVBU.W	-1(R(FROM)), R(TMP)	/* pre-indexed */
-	MOVBU.W	R(TMP), -1(R(TE))	/* pre-indexed */
-	B	_b1tail
-
-_forward:
-	CMP	$4, R(N)		/* need at least 4 bytes to copy */
-	BLT	_f1tail
-
-_f4align:				/* align destination on 4 */
-	AND.S	$3, R(TS), R(TMP)
-	BEQ	_f4aligned
-
-	MOVBU.P	1(R(FROM)), R(TMP)	/* implicit write back */
-	MOVBU.P	R(TMP), 1(R(TS))	/* implicit write back */
-	B	_f4align
-
-_f4aligned:				/* is source now aligned? */
-	AND.S	$3, R(FROM), R(TMP)
-	BNE	_funaligned
-
-	SUB	$31, R(TE), R(TMP)	/* do 32-byte chunks if possible */
-	MOVW	R(TE), savedte-4(SP)
-_f32loop:
-	CMP	R(TMP), R(TS)
-	BHS	_f4tail
-
-	MOVM.IA.W (R(FROM)), [R1-R8] 
-	MOVM.IA.W [R1-R8], (R(TS))
-	B	_f32loop
-
-_f4tail:
-	MOVW	savedte-4(SP), R(TE)
-	SUB	$3, R(TE), R(TMP)	/* do remaining words if possible */
-_f4loop:
-	CMP	R(TMP), R(TS)
-	BHS	_f1tail
-
-	MOVW.P	4(R(FROM)), R(TMP1)	/* implicit write back */
-	MOVW.P	R(TMP1), 4(R(TS))	/* implicit write back */
-	B	_f4loop
-
-_f1tail:
-	CMP	R(TS), R(TE)
-	BEQ	_return
-
-	MOVBU.P	1(R(FROM)), R(TMP)	/* implicit write back */
-	MOVBU.P	R(TMP), 1(R(TS))	/* implicit write back */
-	B	_f1tail
-
-_return:
-	MOVW	to+0(FP), R0
-	RET
-
-_bunaligned:
-	CMP	$2, R(TMP)		/* is R(TMP) < 2 ? */
-
-	MOVW.LT	$8, R(RSHIFT)		/* (R(n)<<24)|(R(n-1)>>8) */
-	MOVW.LT	$24, R(LSHIFT)
-	MOVW.LT	$1, R(OFFSET)
-
-	MOVW.EQ	$16, R(RSHIFT)		/* (R(n)<<16)|(R(n-1)>>16) */
-	MOVW.EQ	$16, R(LSHIFT)
-	MOVW.EQ	$2, R(OFFSET)
-
-	MOVW.GT	$24, R(RSHIFT)		/* (R(n)<<8)|(R(n-1)>>24) */
-	MOVW.GT	$8, R(LSHIFT)
-	MOVW.GT	$3, R(OFFSET)
-
-	ADD	$16, R(TS), R(TMP)	/* do 16-byte chunks if possible */
-	CMP	R(TMP), R(TE)
-	BLS	_b1tail
-
-	BIC	$3, R(FROM)		/* align source */
-	MOVW	R(TS), savedts-4(SP)
-	MOVW	(R(FROM)), R(BR0)	/* prime first block register */
-
-_bu16loop:
-	CMP	R(TMP), R(TE)
-	BLS	_bu1tail
-
-	MOVW	R(BR0)<<R(LSHIFT), R(BW3)
-	MOVM.DB.W (R(FROM)), [R(BR0)-R(BR3)]
-	ORR	R(BR3)>>R(RSHIFT), R(BW3)
-
-	MOVW	R(BR3)<<R(LSHIFT), R(BW2)
-	ORR	R(BR2)>>R(RSHIFT), R(BW2)
-
-	MOVW	R(BR2)<<R(LSHIFT), R(BW1)
-	ORR	R(BR1)>>R(RSHIFT), R(BW1)
-
-	MOVW	R(BR1)<<R(LSHIFT), R(BW0)
-	ORR	R(BR0)>>R(RSHIFT), R(BW0)
-
-	MOVM.DB.W [R(BW0)-R(BW3)], (R(TE))
-	B	_bu16loop
-
-_bu1tail:
-	MOVW	savedts-4(SP), R(TS)
-	ADD	R(OFFSET), R(FROM)
-	B	_b1tail
-
-_funaligned:
-	CMP	$2, R(TMP)
-
-	MOVW.LT	$8, R(RSHIFT)		/* (R(n+1)<<24)|(R(n)>>8) */
-	MOVW.LT	$24, R(LSHIFT)
-	MOVW.LT	$3, R(OFFSET)
-
-	MOVW.EQ	$16, R(RSHIFT)		/* (R(n+1)<<16)|(R(n)>>16) */
-	MOVW.EQ	$16, R(LSHIFT)
-	MOVW.EQ	$2, R(OFFSET)
-
-	MOVW.GT	$24, R(RSHIFT)		/* (R(n+1)<<8)|(R(n)>>24) */
-	MOVW.GT	$8, R(LSHIFT)
-	MOVW.GT	$1, R(OFFSET)
-
-	SUB	$16, R(TE), R(TMP)	/* do 16-byte chunks if possible */
-	CMP	R(TMP), R(TS)
-	BHS	_f1tail
-
-	BIC	$3, R(FROM)		/* align source */
-	MOVW	R(TE), savedte-4(SP)
-	MOVW.P	4(R(FROM)), R(FR3)	/* prime last block register, implicit write back */
-
-_fu16loop:
-	CMP	R(TMP), R(TS)
-	BHS	_fu1tail
-
-	MOVW	R(FR3)>>R(RSHIFT), R(FW0)
-	MOVM.IA.W (R(FROM)), [R(FR0),R(FR1),R(FR2),R(FR3)]
-	ORR	R(FR0)<<R(LSHIFT), R(FW0)
-
-	MOVW	R(FR0)>>R(RSHIFT), R(FW1)
-	ORR	R(FR1)<<R(LSHIFT), R(FW1)
-
-	MOVW	R(FR1)>>R(RSHIFT), R(FW2)
-	ORR	R(FR2)<<R(LSHIFT), R(FW2)
-
-	MOVW	R(FR2)>>R(RSHIFT), R(FW3)
-	ORR	R(FR3)<<R(LSHIFT), R(FW3)
-
-	MOVM.IA.W [R(FW0),R(FW1),R(FW2),R(FW3)], (R(TS))
-	B	_fu16loop
-
-_fu1tail:
-	MOVW	savedte-4(SP), R(TE)
-	SUB	R(OFFSET), R(FROM)
-	B	_f1tail
diff --git a/src/pkg/runtime/memmove_nacl_amd64p32.s b/src/pkg/runtime/memmove_nacl_amd64p32.s
deleted file mode 100644
index 1b57331..0000000
--- a/src/pkg/runtime/memmove_nacl_amd64p32.s
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2013 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../cmd/ld/textflag.h"
-
-TEXT runtime·memmove(SB), NOSPLIT, $0-12
-	MOVL	to+0(FP), DI
-	MOVL	fr+4(FP), SI
-	MOVL	n+8(FP), BX
-
-	CMPL	SI, DI
-	JLS back
-
-forward:
-	MOVL	BX, CX
-	SHRL	$3, CX
-	ANDL	$7, BX
-	REP; MOVSQ
-	MOVL	BX, CX
-	REP; MOVSB
-	RET
-
-back:
-	MOVL	SI, CX
-	ADDL	BX, CX
-	CMPL	CX, DI
-	JLS forward
-
-	ADDL	BX, DI
-	ADDL	BX, SI
-	STD
-	
-	MOVL	BX, CX
-	SHRL	$3, CX
-	ANDL	$7, BX
-	SUBL	$8, DI
-	SUBL	$8, SI
-	REP; MOVSQ
-	ADDL	$7, DI
-	ADDL	$7, SI
-	MOVL	BX, CX
-	REP; MOVSB
-	CLD
-
-	RET
diff --git a/src/pkg/runtime/memmove_plan9_386.s b/src/pkg/runtime/memmove_plan9_386.s
deleted file mode 100644
index 187616c..0000000
--- a/src/pkg/runtime/memmove_plan9_386.s
+++ /dev/null
@@ -1,127 +0,0 @@
-// Inferno's libkern/memmove-386.s
-// http://code.google.com/p/inferno-os/source/browse/libkern/memmove-386.s
-//
-//         Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//         Revisions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com).  All rights reserved.
-//         Portions Copyright 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-#include "../../cmd/ld/textflag.h"
-
-TEXT runtime·memmove(SB), NOSPLIT, $0-12
-	MOVL	to+0(FP), DI
-	MOVL	fr+4(FP), SI
-	MOVL	n+8(FP), BX
-
-	// REP instructions have a high startup cost, so we handle small sizes
-	// with some straightline code.  The REP MOVSL instruction is really fast
-	// for large sizes.  The cutover is approximately 1K.
-tail:
-	TESTL	BX, BX
-	JEQ	move_0
-	CMPL	BX, $2
-	JBE	move_1or2
-	CMPL	BX, $4
-	JBE	move_3or4
-	CMPL	BX, $8
-	JBE	move_5through8
-	CMPL	BX, $16
-	JBE	move_9through16
-
-/*
- * check and set for backwards
- */
-	CMPL	SI, DI
-	JLS	back
-
-/*
- * forward copy loop
- */
-forward:	
-	MOVL	BX, CX
-	SHRL	$2, CX
-	ANDL	$3, BX
-
-	REP;	MOVSL
-	JMP	tail
-/*
- * check overlap
- */
-back:
-	MOVL	SI, CX
-	ADDL	BX, CX
-	CMPL	CX, DI
-	JLS	forward
-/*
- * whole thing backwards has
- * adjusted addresses
- */
-
-	ADDL	BX, DI
-	ADDL	BX, SI
-	STD
-
-/*
- * copy
- */
-	MOVL	BX, CX
-	SHRL	$2, CX
-	ANDL	$3, BX
-
-	SUBL	$4, DI
-	SUBL	$4, SI
-	REP;	MOVSL
-
-	CLD
-	ADDL	$4, DI
-	ADDL	$4, SI
-	SUBL	BX, DI
-	SUBL	BX, SI
-	JMP	tail
-
-move_1or2:
-	MOVB	(SI), AX
-	MOVB	-1(SI)(BX*1), CX
-	MOVB	AX, (DI)
-	MOVB	CX, -1(DI)(BX*1)
-move_0:
-	RET
-move_3or4:
-	MOVW	(SI), AX
-	MOVW	-2(SI)(BX*1), CX
-	MOVW	AX, (DI)
-	MOVW	CX, -2(DI)(BX*1)
-	RET
-move_5through8:
-	MOVL	(SI), AX
-	MOVL	-4(SI)(BX*1), CX
-	MOVL	AX, (DI)
-	MOVL	CX, -4(DI)(BX*1)
-	RET
-move_9through16:
-	MOVL	(SI), AX
-	MOVL	4(SI), CX
-	MOVL	-8(SI)(BX*1), DX
-	MOVL	-4(SI)(BX*1), BP
-	MOVL	AX, (DI)
-	MOVL	CX, 4(DI)
-	MOVL	DX, -8(DI)(BX*1)
-	MOVL	BP, -4(DI)(BX*1)
-	RET
diff --git a/src/pkg/runtime/memmove_plan9_amd64.s b/src/pkg/runtime/memmove_plan9_amd64.s
deleted file mode 100644
index 6010827..0000000
--- a/src/pkg/runtime/memmove_plan9_amd64.s
+++ /dev/null
@@ -1,126 +0,0 @@
-// Derived from Inferno's libkern/memmove-386.s (adapted for amd64)
-// http://code.google.com/p/inferno-os/source/browse/libkern/memmove-386.s
-//
-//         Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//         Revisions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com).  All rights reserved.
-//         Portions Copyright 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-#include "../../cmd/ld/textflag.h"
-
-// void runtime·memmove(void*, void*, uintptr)
-TEXT runtime·memmove(SB), NOSPLIT, $0-24
-
-	MOVQ	to+0(FP), DI
-	MOVQ	fr+8(FP), SI
-	MOVQ	n+16(FP), BX
-
-	// REP instructions have a high startup cost, so we handle small sizes
-	// with some straightline code.  The REP MOVSQ instruction is really fast
-	// for large sizes.  The cutover is approximately 1K.
-tail:
-	TESTQ	BX, BX
-	JEQ	move_0
-	CMPQ	BX, $2
-	JBE	move_1or2
-	CMPQ	BX, $4
-	JBE	move_3or4
-	CMPQ	BX, $8
-	JBE	move_5through8
-	CMPQ	BX, $16
-	JBE	move_9through16
-
-/*
- * check and set for backwards
- */
-	CMPQ	SI, DI
-	JLS	back
-
-/*
- * forward copy loop
- */
-forward:
-	MOVQ	BX, CX
-	SHRQ	$3, CX
-	ANDQ	$7, BX
-
-	REP;	MOVSQ
-	JMP	tail
-
-back:
-/*
- * check overlap
- */
-	MOVQ	SI, CX
-	ADDQ	BX, CX
-	CMPQ	CX, DI
-	JLS	forward
-	
-/*
- * whole thing backwards has
- * adjusted addresses
- */
-	ADDQ	BX, DI
-	ADDQ	BX, SI
-	STD
-
-/*
- * copy
- */
-	MOVQ	BX, CX
-	SHRQ	$3, CX
-	ANDQ	$7, BX
-
-	SUBQ	$8, DI
-	SUBQ	$8, SI
-	REP;	MOVSQ
-
-	CLD
-	ADDQ	$8, DI
-	ADDQ	$8, SI
-	SUBQ	BX, DI
-	SUBQ	BX, SI
-	JMP	tail
-
-move_1or2:
-	MOVB	(SI), AX
-	MOVB	-1(SI)(BX*1), CX
-	MOVB	AX, (DI)
-	MOVB	CX, -1(DI)(BX*1)
-move_0:
-	RET
-move_3or4:
-	MOVW	(SI), AX
-	MOVW	-2(SI)(BX*1), CX
-	MOVW	AX, (DI)
-	MOVW	CX, -2(DI)(BX*1)
-	RET
-move_5through8:
-	MOVL	(SI), AX
-	MOVL	-4(SI)(BX*1), CX
-	MOVL	AX, (DI)
-	MOVL	CX, -4(DI)(BX*1)
-	RET
-move_9through16:
-	MOVQ	(SI), AX
-	MOVQ	-8(SI)(BX*1), CX
-	MOVQ	AX, (DI)
-	MOVQ	CX, -8(DI)(BX*1)
-	RET
diff --git a/src/pkg/runtime/memmove_test.go b/src/pkg/runtime/memmove_test.go
deleted file mode 100644
index 540f0fe..0000000
--- a/src/pkg/runtime/memmove_test.go
+++ /dev/null
@@ -1,243 +0,0 @@
-// Copyright 2013 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package runtime_test
-
-import (
-	. "runtime"
-	"testing"
-)
-
-func TestMemmove(t *testing.T) {
-	size := 256
-	if testing.Short() {
-		size = 128 + 16
-	}
-	src := make([]byte, size)
-	dst := make([]byte, size)
-	for i := 0; i < size; i++ {
-		src[i] = byte(128 + (i & 127))
-	}
-	for i := 0; i < size; i++ {
-		dst[i] = byte(i & 127)
-	}
-	for n := 0; n <= size; n++ {
-		for x := 0; x <= size-n; x++ { // offset in src
-			for y := 0; y <= size-n; y++ { // offset in dst
-				copy(dst[y:y+n], src[x:x+n])
-				for i := 0; i < y; i++ {
-					if dst[i] != byte(i&127) {
-						t.Fatalf("prefix dst[%d] = %d", i, dst[i])
-					}
-				}
-				for i := y; i < y+n; i++ {
-					if dst[i] != byte(128+((i-y+x)&127)) {
-						t.Fatalf("copied dst[%d] = %d", i, dst[i])
-					}
-					dst[i] = byte(i & 127) // reset dst
-				}
-				for i := y + n; i < size; i++ {
-					if dst[i] != byte(i&127) {
-						t.Fatalf("suffix dst[%d] = %d", i, dst[i])
-					}
-				}
-			}
-		}
-	}
-}
-
-func TestMemmoveAlias(t *testing.T) {
-	size := 256
-	if testing.Short() {
-		size = 128 + 16
-	}
-	buf := make([]byte, size)
-	for i := 0; i < size; i++ {
-		buf[i] = byte(i)
-	}
-	for n := 0; n <= size; n++ {
-		for x := 0; x <= size-n; x++ { // src offset
-			for y := 0; y <= size-n; y++ { // dst offset
-				copy(buf[y:y+n], buf[x:x+n])
-				for i := 0; i < y; i++ {
-					if buf[i] != byte(i) {
-						t.Fatalf("prefix buf[%d] = %d", i, buf[i])
-					}
-				}
-				for i := y; i < y+n; i++ {
-					if buf[i] != byte(i-y+x) {
-						t.Fatalf("copied buf[%d] = %d", i, buf[i])
-					}
-					buf[i] = byte(i) // reset buf
-				}
-				for i := y + n; i < size; i++ {
-					if buf[i] != byte(i) {
-						t.Fatalf("suffix buf[%d] = %d", i, buf[i])
-					}
-				}
-			}
-		}
-	}
-}
-
-func bmMemmove(b *testing.B, n int) {
-	x := make([]byte, n)
-	y := make([]byte, n)
-	b.SetBytes(int64(n))
-	for i := 0; i < b.N; i++ {
-		copy(x, y)
-	}
-}
-
-func BenchmarkMemmove0(b *testing.B)    { bmMemmove(b, 0) }
-func BenchmarkMemmove1(b *testing.B)    { bmMemmove(b, 1) }
-func BenchmarkMemmove2(b *testing.B)    { bmMemmove(b, 2) }
-func BenchmarkMemmove3(b *testing.B)    { bmMemmove(b, 3) }
-func BenchmarkMemmove4(b *testing.B)    { bmMemmove(b, 4) }
-func BenchmarkMemmove5(b *testing.B)    { bmMemmove(b, 5) }
-func BenchmarkMemmove6(b *testing.B)    { bmMemmove(b, 6) }
-func BenchmarkMemmove7(b *testing.B)    { bmMemmove(b, 7) }
-func BenchmarkMemmove8(b *testing.B)    { bmMemmove(b, 8) }
-func BenchmarkMemmove9(b *testing.B)    { bmMemmove(b, 9) }
-func BenchmarkMemmove10(b *testing.B)   { bmMemmove(b, 10) }
-func BenchmarkMemmove11(b *testing.B)   { bmMemmove(b, 11) }
-func BenchmarkMemmove12(b *testing.B)   { bmMemmove(b, 12) }
-func BenchmarkMemmove13(b *testing.B)   { bmMemmove(b, 13) }
-func BenchmarkMemmove14(b *testing.B)   { bmMemmove(b, 14) }
-func BenchmarkMemmove15(b *testing.B)   { bmMemmove(b, 15) }
-func BenchmarkMemmove16(b *testing.B)   { bmMemmove(b, 16) }
-func BenchmarkMemmove32(b *testing.B)   { bmMemmove(b, 32) }
-func BenchmarkMemmove64(b *testing.B)   { bmMemmove(b, 64) }
-func BenchmarkMemmove128(b *testing.B)  { bmMemmove(b, 128) }
-func BenchmarkMemmove256(b *testing.B)  { bmMemmove(b, 256) }
-func BenchmarkMemmove512(b *testing.B)  { bmMemmove(b, 512) }
-func BenchmarkMemmove1024(b *testing.B) { bmMemmove(b, 1024) }
-func BenchmarkMemmove2048(b *testing.B) { bmMemmove(b, 2048) }
-func BenchmarkMemmove4096(b *testing.B) { bmMemmove(b, 4096) }
-
-func TestMemclr(t *testing.T) {
-	size := 512
-	if testing.Short() {
-		size = 128 + 16
-	}
-	mem := make([]byte, size)
-	for i := 0; i < size; i++ {
-		mem[i] = 0xee
-	}
-	for n := 0; n < size; n++ {
-		for x := 0; x <= size-n; x++ { // offset in mem
-			MemclrBytes(mem[x : x+n])
-			for i := 0; i < x; i++ {
-				if mem[i] != 0xee {
-					t.Fatalf("overwrite prefix mem[%d] = %d", i, mem[i])
-				}
-			}
-			for i := x; i < x+n; i++ {
-				if mem[i] != 0 {
-					t.Fatalf("failed clear mem[%d] = %d", i, mem[i])
-				}
-				mem[i] = 0xee
-			}
-			for i := x + n; i < size; i++ {
-				if mem[i] != 0xee {
-					t.Fatalf("overwrite suffix mem[%d] = %d", i, mem[i])
-				}
-			}
-		}
-	}
-}
-
-func bmMemclr(b *testing.B, n int) {
-	x := make([]byte, n)
-	b.SetBytes(int64(n))
-	for i := 0; i < b.N; i++ {
-		MemclrBytes(x)
-	}
-}
-func BenchmarkMemclr5(b *testing.B)     { bmMemclr(b, 5) }
-func BenchmarkMemclr16(b *testing.B)    { bmMemclr(b, 16) }
-func BenchmarkMemclr64(b *testing.B)    { bmMemclr(b, 64) }
-func BenchmarkMemclr256(b *testing.B)   { bmMemclr(b, 256) }
-func BenchmarkMemclr4096(b *testing.B)  { bmMemclr(b, 4096) }
-func BenchmarkMemclr65536(b *testing.B) { bmMemclr(b, 65536) }
-
-func BenchmarkClearFat32(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		var x [32]byte
-		_ = x
-	}
-}
-func BenchmarkClearFat64(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		var x [64]byte
-		_ = x
-	}
-}
-func BenchmarkClearFat128(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		var x [128]byte
-		_ = x
-	}
-}
-func BenchmarkClearFat256(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		var x [256]byte
-		_ = x
-	}
-}
-func BenchmarkClearFat512(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		var x [512]byte
-		_ = x
-	}
-}
-func BenchmarkClearFat1024(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		var x [1024]byte
-		_ = x
-	}
-}
-
-func BenchmarkCopyFat32(b *testing.B) {
-	var x [32 / 4]uint32
-	for i := 0; i < b.N; i++ {
-		y := x
-		_ = y
-	}
-}
-func BenchmarkCopyFat64(b *testing.B) {
-	var x [64 / 4]uint32
-	for i := 0; i < b.N; i++ {
-		y := x
-		_ = y
-	}
-}
-func BenchmarkCopyFat128(b *testing.B) {
-	var x [128 / 4]uint32
-	for i := 0; i < b.N; i++ {
-		y := x
-		_ = y
-	}
-}
-func BenchmarkCopyFat256(b *testing.B) {
-	var x [256 / 4]uint32
-	for i := 0; i < b.N; i++ {
-		y := x
-		_ = y
-	}
-}
-func BenchmarkCopyFat512(b *testing.B) {
-	var x [512 / 4]uint32
-	for i := 0; i < b.N; i++ {
-		y := x
-		_ = y
-	}
-}
-func BenchmarkCopyFat1024(b *testing.B) {
-	var x [1024 / 4]uint32
-	for i := 0; i < b.N; i++ {
-		y := x
-		_ = y
-	}
-}
diff --git a/src/pkg/runtime/mfinal_test.go b/src/pkg/runtime/mfinal_test.go
deleted file mode 100644
index 6b53888..0000000
--- a/src/pkg/runtime/mfinal_test.go
+++ /dev/null
@@ -1,239 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package runtime_test
-
-import (
-	"runtime"
-	"testing"
-	"time"
-	"unsafe"
-)
-
-type Tintptr *int // assignable to *int
-type Tint int     // *Tint implements Tinter, interface{}
-
-func (t *Tint) m() {}
-
-type Tinter interface {
-	m()
-}
-
-func TestFinalizerType(t *testing.T) {
-	if runtime.GOARCH != "amd64" {
-		t.Skipf("Skipping on non-amd64 machine")
-	}
-
-	ch := make(chan bool, 10)
-	finalize := func(x *int) {
-		if *x != 97531 {
-			t.Errorf("finalizer %d, want %d", *x, 97531)
-		}
-		ch <- true
-	}
-
-	var finalizerTests = []struct {
-		convert   func(*int) interface{}
-		finalizer interface{}
-	}{
-		{func(x *int) interface{} { return x }, func(v *int) { finalize(v) }},
-		{func(x *int) interface{} { return Tintptr(x) }, func(v Tintptr) { finalize(v) }},
-		{func(x *int) interface{} { return Tintptr(x) }, func(v *int) { finalize(v) }},
-		{func(x *int) interface{} { return (*Tint)(x) }, func(v *Tint) { finalize((*int)(v)) }},
-		{func(x *int) interface{} { return (*Tint)(x) }, func(v Tinter) { finalize((*int)(v.(*Tint))) }},
-	}
-
-	for _, tt := range finalizerTests {
-		done := make(chan bool, 1)
-		go func() {
-			v := new(int)
-			*v = 97531
-			runtime.SetFinalizer(tt.convert(v), tt.finalizer)
-			v = nil
-			done <- true
-		}()
-		<-done
-		runtime.GC()
-		select {
-		case <-ch:
-		case <-time.After(time.Second * 4):
-			t.Errorf("finalizer for type %T didn't run", tt.finalizer)
-		}
-	}
-}
-
-type bigValue struct {
-	fill uint64
-	it   bool
-	up   string
-}
-
-func TestFinalizerInterfaceBig(t *testing.T) {
-	if runtime.GOARCH != "amd64" {
-		t.Skipf("Skipping on non-amd64 machine")
-	}
-	ch := make(chan bool)
-	done := make(chan bool, 1)
-	go func() {
-		v := &bigValue{0xDEADBEEFDEADBEEF, true, "It matters not how strait the gate"}
-		old := *v
-		runtime.SetFinalizer(v, func(v interface{}) {
-			i, ok := v.(*bigValue)
-			if !ok {
-				t.Errorf("finalizer called with type %T, want *bigValue", v)
-			}
-			if *i != old {
-				t.Errorf("finalizer called with %+v, want %+v", *i, old)
-			}
-			close(ch)
-		})
-		v = nil
-		done <- true
-	}()
-	<-done
-	runtime.GC()
-	select {
-	case <-ch:
-	case <-time.After(4 * time.Second):
-		t.Errorf("finalizer for type *bigValue didn't run")
-	}
-}
-
-func fin(v *int) {
-}
-
-// Verify we don't crash at least. golang.org/issue/6857
-func TestFinalizerZeroSizedStruct(t *testing.T) {
-	type Z struct{}
-	z := new(Z)
-	runtime.SetFinalizer(z, func(*Z) {})
-}
-
-func BenchmarkFinalizer(b *testing.B) {
-	const Batch = 1000
-	b.RunParallel(func(pb *testing.PB) {
-		var data [Batch]*int
-		for i := 0; i < Batch; i++ {
-			data[i] = new(int)
-		}
-		for pb.Next() {
-			for i := 0; i < Batch; i++ {
-				runtime.SetFinalizer(data[i], fin)
-			}
-			for i := 0; i < Batch; i++ {
-				runtime.SetFinalizer(data[i], nil)
-			}
-		}
-	})
-}
-
-func BenchmarkFinalizerRun(b *testing.B) {
-	b.RunParallel(func(pb *testing.PB) {
-		for pb.Next() {
-			v := new(int)
-			runtime.SetFinalizer(v, fin)
-		}
-	})
-}
-
-// One chunk must be exactly one sizeclass in size.
-// It should be a sizeclass not used much by others, so we
-// have a greater chance of finding adjacent ones.
-// size class 19: 320 byte objects, 25 per page, 1 page alloc at a time
-const objsize = 320
-
-type objtype [objsize]byte
-
-func adjChunks() (*objtype, *objtype) {
-	var s []*objtype
-
-	for {
-		c := new(objtype)
-		for _, d := range s {
-			if uintptr(unsafe.Pointer(c))+unsafe.Sizeof(*c) == uintptr(unsafe.Pointer(d)) {
-				return c, d
-			}
-			if uintptr(unsafe.Pointer(d))+unsafe.Sizeof(*c) == uintptr(unsafe.Pointer(c)) {
-				return d, c
-			}
-		}
-		s = append(s, c)
-	}
-}
-
-// Make sure an empty slice on the stack doesn't pin the next object in memory.
-func TestEmptySlice(t *testing.T) {
-	if true { // disable until bug 7564 is fixed.
-		return
-	}
-	x, y := adjChunks()
-
-	// the pointer inside xs points to y.
-	xs := x[objsize:] // change objsize to objsize-1 and the test passes
-
-	fin := make(chan bool, 1)
-	runtime.SetFinalizer(y, func(z *objtype) { fin <- true })
-	runtime.GC()
-	select {
-	case <-fin:
-	case <-time.After(4 * time.Second):
-		t.Errorf("finalizer of next object in memory didn't run")
-	}
-	xsglobal = xs // keep empty slice alive until here
-}
-
-var xsglobal []byte
-
-func adjStringChunk() (string, *objtype) {
-	b := make([]byte, objsize)
-	for {
-		s := string(b)
-		t := new(objtype)
-		p := *(*uintptr)(unsafe.Pointer(&s))
-		q := uintptr(unsafe.Pointer(t))
-		if p+objsize == q {
-			return s, t
-		}
-	}
-}
-
-// Make sure an empty string on the stack doesn't pin the next object in memory.
-func TestEmptyString(t *testing.T) {
-	x, y := adjStringChunk()
-
-	ss := x[objsize:] // change objsize to objsize-1 and the test passes
-	fin := make(chan bool, 1)
-	// set finalizer on string contents of y
-	runtime.SetFinalizer(y, func(z *objtype) { fin <- true })
-	runtime.GC()
-	select {
-	case <-fin:
-	case <-time.After(4 * time.Second):
-		t.Errorf("finalizer of next string in memory didn't run")
-	}
-	ssglobal = ss // keep 0-length string live until here
-}
-
-var ssglobal string
-
-// Test for issue 7656.
-func TestFinalizerOnGlobal(t *testing.T) {
-	runtime.SetFinalizer(Foo1, func(p *Object1) {})
-	runtime.SetFinalizer(Foo2, func(p *Object2) {})
-	runtime.SetFinalizer(Foo1, nil)
-	runtime.SetFinalizer(Foo2, nil)
-}
-
-type Object1 struct {
-	Something []byte
-}
-
-type Object2 struct {
-	Something byte
-}
-
-var (
-	Foo2 = &Object2{}
-	Foo1 = &Object1{}
-)
diff --git a/src/pkg/runtime/mgc0.c b/src/pkg/runtime/mgc0.c
deleted file mode 100644
index 392da53..0000000
--- a/src/pkg/runtime/mgc0.c
+++ /dev/null
@@ -1,2892 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Garbage collector (GC).
-//
-// GC is:
-// - mark&sweep
-// - mostly precise (with the exception of some C-allocated objects, assembly frames/arguments, etc)
-// - parallel (up to MaxGcproc threads)
-// - partially concurrent (mark is stop-the-world, while sweep is concurrent)
-// - non-moving/non-compacting
-// - full (non-partial)
-//
-// GC rate.
-// Next GC is after we've allocated an extra amount of memory proportional to
-// the amount already in use. The proportion is controlled by GOGC environment variable
-// (100 by default). If GOGC=100 and we're using 4M, we'll GC again when we get to 8M
-// (this mark is tracked in next_gc variable). This keeps the GC cost in linear
-// proportion to the allocation cost. Adjusting GOGC just changes the linear constant
-// (and also the amount of extra memory used).
-//
-// Concurrent sweep.
-// The sweep phase proceeds concurrently with normal program execution.
-// The heap is swept span-by-span both lazily (when a goroutine needs another span)
-// and concurrently in a background goroutine (this helps programs that are not CPU bound).
-// However, at the end of the stop-the-world GC phase we don't know the size of the live heap,
-// and so next_gc calculation is tricky and happens as follows.
-// At the end of the stop-the-world phase next_gc is conservatively set based on total
-// heap size; all spans are marked as "needs sweeping".
-// Whenever a span is swept, next_gc is decremented by GOGC*newly_freed_memory.
-// The background sweeper goroutine simply sweeps spans one-by-one bringing next_gc
-// closer to the target value. However, this is not enough to avoid over-allocating memory.
-// Consider that a goroutine wants to allocate a new span for a large object and
-// there are no free swept spans, but there are small-object unswept spans.
-// If the goroutine naively allocates a new span, it can surpass the yet-unknown
-// target next_gc value. In order to prevent such cases (1) when a goroutine needs
-// to allocate a new small-object span, it sweeps small-object spans for the same
-// object size until it frees at least one object; (2) when a goroutine needs to
-// allocate large-object span from heap, it sweeps spans until it frees at least
-// that many pages into heap. Together these two measures ensure that we don't surpass
-// target next_gc value by a large margin. There is an exception: if a goroutine sweeps
-// and frees two nonadjacent one-page spans to the heap, it will allocate a new two-page span,
-// but there can still be other one-page unswept spans which could be combined into a two-page span.
-// It's critical to ensure that no operations proceed on unswept spans (that would corrupt
-// mark bits in GC bitmap). During GC all mcaches are flushed into the central cache,
-// so they are empty. When a goroutine grabs a new span into mcache, it sweeps it.
-// When a goroutine explicitly frees an object or sets a finalizer, it ensures that
-// the span is swept (either by sweeping it, or by waiting for the concurrent sweep to finish).
-// The finalizer goroutine is kicked off only when all spans are swept.
-// When the next GC starts, it sweeps all not-yet-swept spans (if any).
-
-#include "runtime.h"
-#include "arch_GOARCH.h"
-#include "malloc.h"
-#include "stack.h"
-#include "mgc0.h"
-#include "chan.h"
-#include "race.h"
-#include "type.h"
-#include "typekind.h"
-#include "funcdata.h"
-#include "../../cmd/ld/textflag.h"
-
-enum {
-	Debug = 0,
-	CollectStats = 0,
-	ConcurrentSweep = 1,
-
-	WorkbufSize	= 16*1024,
-	FinBlockSize	= 4*1024,
-
-	handoffThreshold = 4,
-	IntermediateBufferCapacity = 64,
-
-	// Bits in type information
-	PRECISE = 1,
-	LOOP = 2,
-	PC_BITS = PRECISE | LOOP,
-
-	RootData	= 0,
-	RootBss		= 1,
-	RootFinalizers	= 2,
-	RootSpanTypes	= 3,
-	RootFlushCaches = 4,
-	RootCount	= 5,
-};
-
-#define GcpercentUnknown (-2)
-
-// Initialized from $GOGC.  GOGC=off means no gc.
-static int32 gcpercent = GcpercentUnknown;
-
-static FuncVal* poolcleanup;
-
-void
-sync·runtime_registerPoolCleanup(FuncVal *f)
-{
-	poolcleanup = f;
-}
-
-static void
-clearpools(void)
-{
-	P *p, **pp;
-	MCache *c;
-	int32 i;
-
-	// clear sync.Pool's
-	if(poolcleanup != nil)
-		reflect·call(poolcleanup, nil, 0, 0);
-
-	for(pp=runtime·allp; p=*pp; pp++) {
-		// clear tinyalloc pool
-		c = p->mcache;
-		if(c != nil) {
-			c->tiny = nil;
-			c->tinysize = 0;
-		}
-		// clear defer pools
-		for(i=0; i<nelem(p->deferpool); i++)
-			p->deferpool[i] = nil;
-	}
-}
-
-// Holding worldsema grants an M the right to try to stop the world.
-// The procedure is:
-//
-//	runtime·semacquire(&runtime·worldsema);
-//	m->gcing = 1;
-//	runtime·stoptheworld();
-//
-//	... do stuff ...
-//
-//	m->gcing = 0;
-//	runtime·semrelease(&runtime·worldsema);
-//	runtime·starttheworld();
-//
-uint32 runtime·worldsema = 1;
-
-typedef struct Obj Obj;
-struct Obj
-{
-	byte	*p;	// data pointer
-	uintptr	n;	// size of data in bytes
-	uintptr	ti;	// type info
-};
-
-typedef struct Workbuf Workbuf;
-struct Workbuf
-{
-#define SIZE (WorkbufSize-sizeof(LFNode)-sizeof(uintptr))
-	LFNode  node; // must be first
-	uintptr nobj;
-	Obj     obj[SIZE/sizeof(Obj) - 1];
-	uint8   _padding[SIZE%sizeof(Obj) + sizeof(Obj)];
-#undef SIZE
-};
-
-typedef struct Finalizer Finalizer;
-struct Finalizer
-{
-	FuncVal *fn;
-	void *arg;
-	uintptr nret;
-	Type *fint;
-	PtrType *ot;
-};
-
-typedef struct FinBlock FinBlock;
-struct FinBlock
-{
-	FinBlock *alllink;
-	FinBlock *next;
-	int32 cnt;
-	int32 cap;
-	Finalizer fin[1];
-};
-
-extern byte data[];
-extern byte edata[];
-extern byte bss[];
-extern byte ebss[];
-
-extern byte gcdata[];
-extern byte gcbss[];
-
-static Lock	finlock;	// protects the following variables
-static FinBlock	*finq;		// list of finalizers that are to be executed
-static FinBlock	*finc;		// cache of free blocks
-static FinBlock	*allfin;	// list of all blocks
-bool	runtime·fingwait;
-bool	runtime·fingwake;
-
-static Lock	gclock;
-static G*	fing;
-
-static void	runfinq(void);
-static void	bgsweep(void);
-static Workbuf* getempty(Workbuf*);
-static Workbuf* getfull(Workbuf*);
-static void	putempty(Workbuf*);
-static Workbuf* handoff(Workbuf*);
-static void	gchelperstart(void);
-static void	flushallmcaches(void);
-static bool	scanframe(Stkframe *frame, void *wbufp);
-static void	addstackroots(G *gp, Workbuf **wbufp);
-
-static FuncVal runfinqv = {runfinq};
-static FuncVal bgsweepv = {bgsweep};
-
-static struct {
-	uint64	full;  // lock-free list of full blocks
-	uint64	empty; // lock-free list of empty blocks
-	byte	pad0[CacheLineSize]; // prevents false-sharing between full/empty and nproc/nwait
-	uint32	nproc;
-	int64	tstart;
-	volatile uint32	nwait;
-	volatile uint32	ndone;
-	Note	alldone;
-	ParFor	*markfor;
-
-	Lock;
-	byte	*chunk;
-	uintptr	nchunk;
-} work;
-
-enum {
-	GC_DEFAULT_PTR = GC_NUM_INSTR,
-	GC_CHAN,
-
-	GC_NUM_INSTR2
-};
-
-static struct {
-	struct {
-		uint64 sum;
-		uint64 cnt;
-	} ptr;
-	uint64 nbytes;
-	struct {
-		uint64 sum;
-		uint64 cnt;
-		uint64 notype;
-		uint64 typelookup;
-	} obj;
-	uint64 rescan;
-	uint64 rescanbytes;
-	uint64 instr[GC_NUM_INSTR2];
-	uint64 putempty;
-	uint64 getfull;
-	struct {
-		uint64 foundbit;
-		uint64 foundword;
-		uint64 foundspan;
-	} flushptrbuf;
-	struct {
-		uint64 foundbit;
-		uint64 foundword;
-		uint64 foundspan;
-	} markonly;
-	uint32 nbgsweep;
-	uint32 npausesweep;
-} gcstats;
-
-// markonly marks an object. It returns true if the object
-// has been marked by this function, false otherwise.
-// This function doesn't append the object to any buffer.
-static bool
-markonly(void *obj)
-{
-	byte *p;
-	uintptr *bitp, bits, shift, x, xbits, off, j;
-	MSpan *s;
-	PageID k;
-
-	// Words outside the arena cannot be pointers.
-	if(obj < runtime·mheap.arena_start || obj >= runtime·mheap.arena_used)
-		return false;
-
-	// obj may be a pointer to a live object.
-	// Try to find the beginning of the object.
-
-	// Round down to word boundary.
-	obj = (void*)((uintptr)obj & ~((uintptr)PtrSize-1));
-
-	// Find bits for this word.
-	off = (uintptr*)obj - (uintptr*)runtime·mheap.arena_start;
-	bitp = (uintptr*)runtime·mheap.arena_start - off/wordsPerBitmapWord - 1;
-	shift = off % wordsPerBitmapWord;
-	xbits = *bitp;
-	bits = xbits >> shift;
-
-	// Pointing at the beginning of a block?
-	if((bits & (bitAllocated|bitBlockBoundary)) != 0) {
-		if(CollectStats)
-			runtime·xadd64(&gcstats.markonly.foundbit, 1);
-		goto found;
-	}
-
-	// Pointing just past the beginning?
-	// Scan backward a little to find a block boundary.
-	for(j=shift; j-->0; ) {
-		if(((xbits>>j) & (bitAllocated|bitBlockBoundary)) != 0) {
-			shift = j;
-			bits = xbits>>shift;
-			if(CollectStats)
-				runtime·xadd64(&gcstats.markonly.foundword, 1);
-			goto found;
-		}
-	}
-
-	// Otherwise consult span table to find beginning.
-	// (Manually inlined copy of MHeap_LookupMaybe.)
-	k = (uintptr)obj>>PageShift;
-	x = k;
-	x -= (uintptr)runtime·mheap.arena_start>>PageShift;
-	s = runtime·mheap.spans[x];
-	if(s == nil || k < s->start || obj >= s->limit || s->state != MSpanInUse)
-		return false;
-	p = (byte*)((uintptr)s->start<<PageShift);
-	if(s->sizeclass == 0) {
-		obj = p;
-	} else {
-		uintptr size = s->elemsize;
-		int32 i = ((byte*)obj - p)/size;
-		obj = p+i*size;
-	}
-
-	// Now that we know the object header, reload bits.
-	off = (uintptr*)obj - (uintptr*)runtime·mheap.arena_start;
-	bitp = (uintptr*)runtime·mheap.arena_start - off/wordsPerBitmapWord - 1;
-	shift = off % wordsPerBitmapWord;
-	xbits = *bitp;
-	bits = xbits >> shift;
-	if(CollectStats)
-		runtime·xadd64(&gcstats.markonly.foundspan, 1);
-
-found:
-	// Now we have bits, bitp, and shift correct for
-	// obj pointing at the base of the object.
-	// Only care about allocated and not marked.
-	if((bits & (bitAllocated|bitMarked)) != bitAllocated)
-		return false;
-	if(work.nproc == 1)
-		*bitp |= bitMarked<<shift;
-	else {
-		for(;;) {
-			x = *bitp;
-			if(x & (bitMarked<<shift))
-				return false;
-			if(runtime·casp((void**)bitp, (void*)x, (void*)(x|(bitMarked<<shift))))
-				break;
-		}
-	}
-
-	// The object is now marked
-	return true;
-}
-
-// PtrTarget is a structure used by intermediate buffers.
-// The intermediate buffers hold GC data before it
-// is moved/flushed to the work buffer (Workbuf).
-// The size of an intermediate buffer is very small,
-// such as 32 or 64 elements.
-typedef struct PtrTarget PtrTarget;
-struct PtrTarget
-{
-	void *p;
-	uintptr ti;
-};
-
-typedef	struct Scanbuf Scanbuf;
-struct	Scanbuf
-{
-	struct {
-		PtrTarget *begin;
-		PtrTarget *end;
-		PtrTarget *pos;
-	} ptr;
-	struct {
-		Obj *begin;
-		Obj *end;
-		Obj *pos;
-	} obj;
-	Workbuf *wbuf;
-	Obj *wp;
-	uintptr nobj;
-};
-
-typedef struct BufferList BufferList;
-struct BufferList
-{
-	PtrTarget ptrtarget[IntermediateBufferCapacity];
-	Obj obj[IntermediateBufferCapacity];
-	uint32 busy;
-	byte pad[CacheLineSize];
-};
-#pragma dataflag NOPTR
-static BufferList bufferList[MaxGcproc];
-
-static Type *itabtype;
-
-static void enqueue(Obj obj, Workbuf **_wbuf, Obj **_wp, uintptr *_nobj);
-
-// flushptrbuf moves data from the PtrTarget buffer to the work buffer.
-// The PtrTarget buffer contains blocks irrespective of whether the blocks have been marked or scanned,
-// while the work buffer contains blocks which have been marked
-// and are prepared to be scanned by the garbage collector.
-//
-// _wp, _wbuf, _nobj are input/output parameters and are specifying the work buffer.
-//
-// A simplified drawing explaining how the todo-list moves from a structure to another:
-//
-//     scanblock
-//  (find pointers)
-//    Obj ------> PtrTarget (pointer targets)
-//     ↑          |
-//     |          |
-//     `----------'
-//     flushptrbuf
-//  (find block start, mark and enqueue)
-static void
-flushptrbuf(Scanbuf *sbuf)
-{
-	byte *p, *arena_start, *obj;
-	uintptr size, *bitp, bits, shift, j, x, xbits, off, nobj, ti, n;
-	MSpan *s;
-	PageID k;
-	Obj *wp;
-	Workbuf *wbuf;
-	PtrTarget *ptrbuf;
-	PtrTarget *ptrbuf_end;
-
-	arena_start = runtime·mheap.arena_start;
-
-	wp = sbuf->wp;
-	wbuf = sbuf->wbuf;
-	nobj = sbuf->nobj;
-
-	ptrbuf = sbuf->ptr.begin;
-	ptrbuf_end = sbuf->ptr.pos;
-	n = ptrbuf_end - sbuf->ptr.begin;
-	sbuf->ptr.pos = sbuf->ptr.begin;
-
-	if(CollectStats) {
-		runtime·xadd64(&gcstats.ptr.sum, n);
-		runtime·xadd64(&gcstats.ptr.cnt, 1);
-	}
-
-	// If buffer is nearly full, get a new one.
-	if(wbuf == nil || nobj+n >= nelem(wbuf->obj)) {
-		if(wbuf != nil)
-			wbuf->nobj = nobj;
-		wbuf = getempty(wbuf);
-		wp = wbuf->obj;
-		nobj = 0;
-
-		if(n >= nelem(wbuf->obj))
-			runtime·throw("ptrbuf has to be smaller than WorkBuf");
-	}
-
-	while(ptrbuf < ptrbuf_end) {
-		obj = ptrbuf->p;
-		ti = ptrbuf->ti;
-		ptrbuf++;
-
-		// obj belongs to interval [mheap.arena_start, mheap.arena_used).
-		if(Debug > 1) {
-			if(obj < runtime·mheap.arena_start || obj >= runtime·mheap.arena_used)
-				runtime·throw("object is outside of mheap");
-		}
-
-		// obj may be a pointer to a live object.
-		// Try to find the beginning of the object.
-
-		// Round down to word boundary.
-		if(((uintptr)obj & ((uintptr)PtrSize-1)) != 0) {
-			obj = (void*)((uintptr)obj & ~((uintptr)PtrSize-1));
-			ti = 0;
-		}
-
-		// Find bits for this word.
-		off = (uintptr*)obj - (uintptr*)arena_start;
-		bitp = (uintptr*)arena_start - off/wordsPerBitmapWord - 1;
-		shift = off % wordsPerBitmapWord;
-		xbits = *bitp;
-		bits = xbits >> shift;
-
-		// Pointing at the beginning of a block?
-		if((bits & (bitAllocated|bitBlockBoundary)) != 0) {
-			if(CollectStats)
-				runtime·xadd64(&gcstats.flushptrbuf.foundbit, 1);
-			goto found;
-		}
-
-		ti = 0;
-
-		// Pointing just past the beginning?
-		// Scan backward a little to find a block boundary.
-		for(j=shift; j-->0; ) {
-			if(((xbits>>j) & (bitAllocated|bitBlockBoundary)) != 0) {
-				obj = (byte*)obj - (shift-j)*PtrSize;
-				shift = j;
-				bits = xbits>>shift;
-				if(CollectStats)
-					runtime·xadd64(&gcstats.flushptrbuf.foundword, 1);
-				goto found;
-			}
-		}
-
-		// Otherwise consult span table to find beginning.
-		// (Manually inlined copy of MHeap_LookupMaybe.)
-		k = (uintptr)obj>>PageShift;
-		x = k;
-		x -= (uintptr)arena_start>>PageShift;
-		s = runtime·mheap.spans[x];
-		if(s == nil || k < s->start || obj >= s->limit || s->state != MSpanInUse)
-			continue;
-		p = (byte*)((uintptr)s->start<<PageShift);
-		if(s->sizeclass == 0) {
-			obj = p;
-		} else {
-			size = s->elemsize;
-			int32 i = ((byte*)obj - p)/size;
-			obj = p+i*size;
-		}
-
-		// Now that we know the object header, reload bits.
-		off = (uintptr*)obj - (uintptr*)arena_start;
-		bitp = (uintptr*)arena_start - off/wordsPerBitmapWord - 1;
-		shift = off % wordsPerBitmapWord;
-		xbits = *bitp;
-		bits = xbits >> shift;
-		if(CollectStats)
-			runtime·xadd64(&gcstats.flushptrbuf.foundspan, 1);
-
-	found:
-		// Now we have bits, bitp, and shift correct for
-		// obj pointing at the base of the object.
-		// Only care about allocated and not marked.
-		if((bits & (bitAllocated|bitMarked)) != bitAllocated)
-			continue;
-		if(work.nproc == 1)
-			*bitp |= bitMarked<<shift;
-		else {
-			for(;;) {
-				x = *bitp;
-				if(x & (bitMarked<<shift))
-					goto continue_obj;
-				if(runtime·casp((void**)bitp, (void*)x, (void*)(x|(bitMarked<<shift))))
-					break;
-			}
-		}
-
-		// If object has no pointers, don't need to scan further.
-		if((bits & bitScan) == 0)
-			continue;
-
-		// Ask span about size class.
-		// (Manually inlined copy of MHeap_Lookup.)
-		x = (uintptr)obj >> PageShift;
-		x -= (uintptr)arena_start>>PageShift;
-		s = runtime·mheap.spans[x];
-
-		PREFETCH(obj);
-
-		*wp = (Obj){obj, s->elemsize, ti};
-		wp++;
-		nobj++;
-	continue_obj:;
-	}
-
-	// If another proc wants a pointer, give it some.
-	if(work.nwait > 0 && nobj > handoffThreshold && work.full == 0) {
-		wbuf->nobj = nobj;
-		wbuf = handoff(wbuf);
-		nobj = wbuf->nobj;
-		wp = wbuf->obj + nobj;
-	}
-
-	sbuf->wp = wp;
-	sbuf->wbuf = wbuf;
-	sbuf->nobj = nobj;
-}
-
-static void
-flushobjbuf(Scanbuf *sbuf)
-{
-	uintptr nobj, off;
-	Obj *wp, obj;
-	Workbuf *wbuf;
-	Obj *objbuf;
-	Obj *objbuf_end;
-
-	wp = sbuf->wp;
-	wbuf = sbuf->wbuf;
-	nobj = sbuf->nobj;
-
-	objbuf = sbuf->obj.begin;
-	objbuf_end = sbuf->obj.pos;
-	sbuf->obj.pos = sbuf->obj.begin;
-
-	while(objbuf < objbuf_end) {
-		obj = *objbuf++;
-
-		// Align obj.b to a word boundary.
-		off = (uintptr)obj.p & (PtrSize-1);
-		if(off != 0) {
-			obj.p += PtrSize - off;
-			obj.n -= PtrSize - off;
-			obj.ti = 0;
-		}
-
-		if(obj.p == nil || obj.n == 0)
-			continue;
-
-		// If buffer is full, get a new one.
-		if(wbuf == nil || nobj >= nelem(wbuf->obj)) {
-			if(wbuf != nil)
-				wbuf->nobj = nobj;
-			wbuf = getempty(wbuf);
-			wp = wbuf->obj;
-			nobj = 0;
-		}
-
-		*wp = obj;
-		wp++;
-		nobj++;
-	}
-
-	// If another proc wants a pointer, give it some.
-	if(work.nwait > 0 && nobj > handoffThreshold && work.full == 0) {
-		wbuf->nobj = nobj;
-		wbuf = handoff(wbuf);
-		nobj = wbuf->nobj;
-		wp = wbuf->obj + nobj;
-	}
-
-	sbuf->wp = wp;
-	sbuf->wbuf = wbuf;
-	sbuf->nobj = nobj;
-}
-
-// Program that scans the whole block and treats every block element as a potential pointer
-static uintptr defaultProg[2] = {PtrSize, GC_DEFAULT_PTR};
-
-// Hchan program
-static uintptr chanProg[2] = {0, GC_CHAN};
-
-// Local variables of a program fragment or loop
-typedef struct Frame Frame;
-struct Frame {
-	uintptr count, elemsize, b;
-	uintptr *loop_or_ret;
-};
-
-// Sanity check for the derived type info objti.
-static void
-checkptr(void *obj, uintptr objti)
-{
-	uintptr *pc1, *pc2, type, tisize, i, j, x;
-	byte *objstart;
-	Type *t;
-	MSpan *s;
-
-	if(!Debug)
-		runtime·throw("checkptr is debug only");
-
-	if(obj < runtime·mheap.arena_start || obj >= runtime·mheap.arena_used)
-		return;
-	type = runtime·gettype(obj);
-	t = (Type*)(type & ~(uintptr)(PtrSize-1));
-	if(t == nil)
-		return;
-	x = (uintptr)obj >> PageShift;
-	x -= (uintptr)(runtime·mheap.arena_start)>>PageShift;
-	s = runtime·mheap.spans[x];
-	objstart = (byte*)((uintptr)s->start<<PageShift);
-	if(s->sizeclass != 0) {
-		i = ((byte*)obj - objstart)/s->elemsize;
-		objstart += i*s->elemsize;
-	}
-	tisize = *(uintptr*)objti;
-	// Sanity check for object size: it should fit into the memory block.
-	if((byte*)obj + tisize > objstart + s->elemsize) {
-		runtime·printf("object of type '%S' at %p/%p does not fit in block %p/%p\n",
-			       *t->string, obj, tisize, objstart, s->elemsize);
-		runtime·throw("invalid gc type info");
-	}
-	if(obj != objstart)
-		return;
-	// If obj points to the beginning of the memory block,
-	// check type info as well.
-	if(t->string == nil ||
-		// Gob allocates unsafe pointers for indirection.
-		(runtime·strcmp(t->string->str, (byte*)"unsafe.Pointer") &&
-		// Runtime and gc think differently about closures.
-		runtime·strstr(t->string->str, (byte*)"struct { F uintptr") != t->string->str)) {
-		pc1 = (uintptr*)objti;
-		pc2 = (uintptr*)t->gc;
-		// A simple best-effort check until first GC_END.
-		for(j = 1; pc1[j] != GC_END && pc2[j] != GC_END; j++) {
-			if(pc1[j] != pc2[j]) {
-				runtime·printf("invalid gc type info for '%s', type info %p [%d]=%p, block info %p [%d]=%p\n",
-					       t->string ? (int8*)t->string->str : (int8*)"?", pc1, (int32)j, pc1[j], pc2, (int32)j, pc2[j]);
-				runtime·throw("invalid gc type info");
-			}
-		}
-	}
-}					
-
-// scanblock scans a block of n bytes starting at pointer b for references
-// to other objects, scanning any it finds recursively until there are no
-// unscanned objects left.  Instead of using an explicit recursion, it keeps
-// a work list in the Workbuf* structures and loops in the main function
-// body.  Keeping an explicit work list is easier on the stack allocator and
-// more efficient.
-static void
-scanblock(Workbuf *wbuf, bool keepworking)
-{
-	byte *b, *arena_start, *arena_used;
-	uintptr n, i, end_b, elemsize, size, ti, objti, count, type, nobj;
-	uintptr *pc, precise_type, nominal_size;
-	uintptr *chan_ret, chancap;
-	void *obj;
-	Type *t, *et;
-	Slice *sliceptr;
-	String *stringptr;
-	Frame *stack_ptr, stack_top, stack[GC_STACK_CAPACITY+4];
-	BufferList *scanbuffers;
-	Scanbuf sbuf;
-	Eface *eface;
-	Iface *iface;
-	Hchan *chan;
-	ChanType *chantype;
-	Obj *wp;
-
-	if(sizeof(Workbuf) % WorkbufSize != 0)
-		runtime·throw("scanblock: size of Workbuf is suboptimal");
-
-	// Memory arena parameters.
-	arena_start = runtime·mheap.arena_start;
-	arena_used = runtime·mheap.arena_used;
-
-	stack_ptr = stack+nelem(stack)-1;
-
-	precise_type = false;
-	nominal_size = 0;
-
-	if(wbuf) {
-		nobj = wbuf->nobj;
-		wp = &wbuf->obj[nobj];
-	} else {
-		nobj = 0;
-		wp = nil;
-	}
-
-	// Initialize sbuf
-	scanbuffers = &bufferList[m->helpgc];
-
-	sbuf.ptr.begin = sbuf.ptr.pos = &scanbuffers->ptrtarget[0];
-	sbuf.ptr.end = sbuf.ptr.begin + nelem(scanbuffers->ptrtarget);
-
-	sbuf.obj.begin = sbuf.obj.pos = &scanbuffers->obj[0];
-	sbuf.obj.end = sbuf.obj.begin + nelem(scanbuffers->obj);
-
-	sbuf.wbuf = wbuf;
-	sbuf.wp = wp;
-	sbuf.nobj = nobj;
-
-	// (Silence the compiler)
-	chan = nil;
-	chantype = nil;
-	chan_ret = nil;
-
-	goto next_block;
-
-	for(;;) {
-		// Each iteration scans the block b of length n, queueing pointers in
-		// the work buffer.
-
-		if(CollectStats) {
-			runtime·xadd64(&gcstats.nbytes, n);
-			runtime·xadd64(&gcstats.obj.sum, sbuf.nobj);
-			runtime·xadd64(&gcstats.obj.cnt, 1);
-		}
-
-		if(ti != 0) {
-			if(Debug > 1) {
-				runtime·printf("scanblock %p %D ti %p\n", b, (int64)n, ti);
-			}
-			pc = (uintptr*)(ti & ~(uintptr)PC_BITS);
-			precise_type = (ti & PRECISE);
-			stack_top.elemsize = pc[0];
-			if(!precise_type)
-				nominal_size = pc[0];
-			if(ti & LOOP) {
-				stack_top.count = 0;	// 0 means an infinite number of iterations
-				stack_top.loop_or_ret = pc+1;
-			} else {
-				stack_top.count = 1;
-			}
-			if(Debug) {
-				// Simple sanity check for provided type info ti:
-				// The declared size of the object must be not larger than the actual size
-				// (it can be smaller due to inferior pointers).
-				// It's difficult to make a comprehensive check due to inferior pointers,
-				// reflection, gob, etc.
-				if(pc[0] > n) {
-					runtime·printf("invalid gc type info: type info size %p, block size %p\n", pc[0], n);
-					runtime·throw("invalid gc type info");
-				}
-			}
-		} else if(UseSpanType) {
-			if(CollectStats)
-				runtime·xadd64(&gcstats.obj.notype, 1);
-
-			type = runtime·gettype(b);
-			if(type != 0) {
-				if(CollectStats)
-					runtime·xadd64(&gcstats.obj.typelookup, 1);
-
-				t = (Type*)(type & ~(uintptr)(PtrSize-1));
-				switch(type & (PtrSize-1)) {
-				case TypeInfo_SingleObject:
-					pc = (uintptr*)t->gc;
-					precise_type = true;  // type information about 'b' is precise
-					stack_top.count = 1;
-					stack_top.elemsize = pc[0];
-					break;
-				case TypeInfo_Array:
-					pc = (uintptr*)t->gc;
-					if(pc[0] == 0)
-						goto next_block;
-					precise_type = true;  // type information about 'b' is precise
-					stack_top.count = 0;  // 0 means an infinite number of iterations
-					stack_top.elemsize = pc[0];
-					stack_top.loop_or_ret = pc+1;
-					break;
-				case TypeInfo_Chan:
-					chan = (Hchan*)b;
-					chantype = (ChanType*)t;
-					chan_ret = nil;
-					pc = chanProg;
-					break;
-				default:
-					if(Debug > 1)
-						runtime·printf("scanblock %p %D type %p %S\n", b, (int64)n, type, *t->string);
-					runtime·throw("scanblock: invalid type");
-					return;
-				}
-				if(Debug > 1)
-					runtime·printf("scanblock %p %D type %p %S pc=%p\n", b, (int64)n, type, *t->string, pc);
-			} else {
-				pc = defaultProg;
-				if(Debug > 1)
-					runtime·printf("scanblock %p %D unknown type\n", b, (int64)n);
-			}
-		} else {
-			pc = defaultProg;
-			if(Debug > 1)
-				runtime·printf("scanblock %p %D no span types\n", b, (int64)n);
-		}
-
-		if(IgnorePreciseGC)
-			pc = defaultProg;
-
-		pc++;
-		stack_top.b = (uintptr)b;
-		end_b = (uintptr)b + n - PtrSize;
-
-	for(;;) {
-		if(CollectStats)
-			runtime·xadd64(&gcstats.instr[pc[0]], 1);
-
-		obj = nil;
-		objti = 0;
-		switch(pc[0]) {
-		case GC_PTR:
-			obj = *(void**)(stack_top.b + pc[1]);
-			objti = pc[2];
-			if(Debug > 2)
-				runtime·printf("gc_ptr @%p: %p ti=%p\n", stack_top.b+pc[1], obj, objti);
-			pc += 3;
-			if(Debug)
-				checkptr(obj, objti);
-			break;
-
-		case GC_SLICE:
-			sliceptr = (Slice*)(stack_top.b + pc[1]);
-			if(Debug > 2)
-				runtime·printf("gc_slice @%p: %p/%D/%D\n", sliceptr, sliceptr->array, (int64)sliceptr->len, (int64)sliceptr->cap);
-			if(sliceptr->cap != 0) {
-				obj = sliceptr->array;
-				// Can't use slice element type for scanning,
-				// because if it points to an array embedded
-				// in the beginning of a struct,
-				// we will scan the whole struct as the slice.
-				// So just obtain type info from heap.
-			}
-			pc += 3;
-			break;
-
-		case GC_APTR:
-			obj = *(void**)(stack_top.b + pc[1]);
-			if(Debug > 2)
-				runtime·printf("gc_aptr @%p: %p\n", stack_top.b+pc[1], obj);
-			pc += 2;
-			break;
-
-		case GC_STRING:
-			stringptr = (String*)(stack_top.b + pc[1]);
-			if(Debug > 2)
-				runtime·printf("gc_string @%p: %p/%D\n", stack_top.b+pc[1], stringptr->str, (int64)stringptr->len);
-			if(stringptr->len != 0)
-				markonly(stringptr->str);
-			pc += 2;
-			continue;
-
-		case GC_EFACE:
-			eface = (Eface*)(stack_top.b + pc[1]);
-			pc += 2;
-			if(Debug > 2)
-				runtime·printf("gc_eface @%p: %p %p\n", stack_top.b+pc[1], eface->type, eface->data);
-			if(eface->type == nil)
-				continue;
-
-			// eface->type
-			t = eface->type;
-			if((void*)t >= arena_start && (void*)t < arena_used) {
-				*sbuf.ptr.pos++ = (PtrTarget){t, 0};
-				if(sbuf.ptr.pos == sbuf.ptr.end)
-					flushptrbuf(&sbuf);
-			}
-
-			// eface->data
-			if(eface->data >= arena_start && eface->data < arena_used) {
-				if(t->size <= sizeof(void*)) {
-					if((t->kind & KindNoPointers))
-						continue;
-
-					obj = eface->data;
-					if((t->kind & ~KindNoPointers) == KindPtr) {
-						// Only use type information if it is a pointer-containing type.
-						// This matches the GC programs written by cmd/gc/reflect.c's
-						// dgcsym1 in case TPTR32/case TPTR64. See rationale there.
-						et = ((PtrType*)t)->elem;
-						if(!(et->kind & KindNoPointers))
-							objti = (uintptr)((PtrType*)t)->elem->gc;
-					}
-				} else {
-					obj = eface->data;
-					objti = (uintptr)t->gc;
-				}
-			}
-			break;
-
-		case GC_IFACE:
-			iface = (Iface*)(stack_top.b + pc[1]);
-			pc += 2;
-			if(Debug > 2)
-				runtime·printf("gc_iface @%p: %p/%p %p\n", stack_top.b+pc[1], iface->tab, nil, iface->data);
-			if(iface->tab == nil)
-				continue;
-			
-			// iface->tab
-			if((void*)iface->tab >= arena_start && (void*)iface->tab < arena_used) {
-				*sbuf.ptr.pos++ = (PtrTarget){iface->tab, (uintptr)itabtype->gc};
-				if(sbuf.ptr.pos == sbuf.ptr.end)
-					flushptrbuf(&sbuf);
-			}
-
-			// iface->data
-			if(iface->data >= arena_start && iface->data < arena_used) {
-				t = iface->tab->type;
-				if(t->size <= sizeof(void*)) {
-					if((t->kind & KindNoPointers))
-						continue;
-
-					obj = iface->data;
-					if((t->kind & ~KindNoPointers) == KindPtr) {
-						// Only use type information if it is a pointer-containing type.
-						// This matches the GC programs written by cmd/gc/reflect.c's
-						// dgcsym1 in case TPTR32/case TPTR64. See rationale there.
-						et = ((PtrType*)t)->elem;
-						if(!(et->kind & KindNoPointers))
-							objti = (uintptr)((PtrType*)t)->elem->gc;
-					}
-				} else {
-					obj = iface->data;
-					objti = (uintptr)t->gc;
-				}
-			}
-			break;
-
-		case GC_DEFAULT_PTR:
-			while(stack_top.b <= end_b) {
-				obj = *(byte**)stack_top.b;
-				if(Debug > 2)
-					runtime·printf("gc_default_ptr @%p: %p\n", stack_top.b, obj);
-				stack_top.b += PtrSize;
-				if(obj >= arena_start && obj < arena_used) {
-					*sbuf.ptr.pos++ = (PtrTarget){obj, 0};
-					if(sbuf.ptr.pos == sbuf.ptr.end)
-						flushptrbuf(&sbuf);
-				}
-			}
-			goto next_block;
-
-		case GC_END:
-			if(--stack_top.count != 0) {
-				// Next iteration of a loop if possible.
-				stack_top.b += stack_top.elemsize;
-				if(stack_top.b + stack_top.elemsize <= end_b+PtrSize) {
-					pc = stack_top.loop_or_ret;
-					continue;
-				}
-				i = stack_top.b;
-			} else {
-				// Stack pop if possible.
-				if(stack_ptr+1 < stack+nelem(stack)) {
-					pc = stack_top.loop_or_ret;
-					stack_top = *(++stack_ptr);
-					continue;
-				}
-				i = (uintptr)b + nominal_size;
-			}
-			if(!precise_type) {
-				// Quickly scan [b+i,b+n) for possible pointers.
-				for(; i<=end_b; i+=PtrSize) {
-					if(*(byte**)i != nil) {
-						// Found a value that may be a pointer.
-						// Do a rescan of the entire block.
-						enqueue((Obj){b, n, 0}, &sbuf.wbuf, &sbuf.wp, &sbuf.nobj);
-						if(CollectStats) {
-							runtime·xadd64(&gcstats.rescan, 1);
-							runtime·xadd64(&gcstats.rescanbytes, n);
-						}
-						break;
-					}
-				}
-			}
-			goto next_block;
-
-		case GC_ARRAY_START:
-			i = stack_top.b + pc[1];
-			count = pc[2];
-			elemsize = pc[3];
-			pc += 4;
-
-			// Stack push.
-			*stack_ptr-- = stack_top;
-			stack_top = (Frame){count, elemsize, i, pc};
-			continue;
-
-		case GC_ARRAY_NEXT:
-			if(--stack_top.count != 0) {
-				stack_top.b += stack_top.elemsize;
-				pc = stack_top.loop_or_ret;
-			} else {
-				// Stack pop.
-				stack_top = *(++stack_ptr);
-				pc += 1;
-			}
-			continue;
-
-		case GC_CALL:
-			// Stack push.
-			*stack_ptr-- = stack_top;
-			stack_top = (Frame){1, 0, stack_top.b + pc[1], pc+3 /*return address*/};
-			pc = (uintptr*)((byte*)pc + *(int32*)(pc+2));  // target of the CALL instruction
-			continue;
-
-		case GC_REGION:
-			obj = (void*)(stack_top.b + pc[1]);
-			size = pc[2];
-			objti = pc[3];
-			pc += 4;
-
-			if(Debug > 2)
-				runtime·printf("gc_region @%p: %D %p\n", stack_top.b+pc[1], (int64)size, objti);
-			*sbuf.obj.pos++ = (Obj){obj, size, objti};
-			if(sbuf.obj.pos == sbuf.obj.end)
-				flushobjbuf(&sbuf);
-			continue;
-
-		case GC_CHAN_PTR:
-			chan = *(Hchan**)(stack_top.b + pc[1]);
-			if(Debug > 2 && chan != nil)
-				runtime·printf("gc_chan_ptr @%p: %p/%D/%D %p\n", stack_top.b+pc[1], chan, (int64)chan->qcount, (int64)chan->dataqsiz, pc[2]);
-			if(chan == nil) {
-				pc += 3;
-				continue;
-			}
-			if(markonly(chan)) {
-				chantype = (ChanType*)pc[2];
-				if(!(chantype->elem->kind & KindNoPointers)) {
-					// Start chanProg.
-					chan_ret = pc+3;
-					pc = chanProg+1;
-					continue;
-				}
-			}
-			pc += 3;
-			continue;
-
-		case GC_CHAN:
-			// There are no heap pointers in struct Hchan,
-			// so we can ignore the leading sizeof(Hchan) bytes.
-			if(!(chantype->elem->kind & KindNoPointers)) {
-				// Channel's buffer follows Hchan immediately in memory.
-				// Size of buffer (cap(c)) is second int in the chan struct.
-				chancap = ((uintgo*)chan)[1];
-				if(chancap > 0) {
-					// TODO(atom): split into two chunks so that only the
-					// in-use part of the circular buffer is scanned.
-					// (Channel routines zero the unused part, so the current
-					// code does not lead to leaks, it's just a little inefficient.)
-					*sbuf.obj.pos++ = (Obj){(byte*)chan+runtime·Hchansize, chancap*chantype->elem->size,
-						(uintptr)chantype->elem->gc | PRECISE | LOOP};
-					if(sbuf.obj.pos == sbuf.obj.end)
-						flushobjbuf(&sbuf);
-				}
-			}
-			if(chan_ret == nil)
-				goto next_block;
-			pc = chan_ret;
-			continue;
-
-		default:
-			runtime·printf("runtime: invalid GC instruction %p at %p\n", pc[0], pc);
-			runtime·throw("scanblock: invalid GC instruction");
-			return;
-		}
-
-		if(obj >= arena_start && obj < arena_used) {
-			*sbuf.ptr.pos++ = (PtrTarget){obj, objti};
-			if(sbuf.ptr.pos == sbuf.ptr.end)
-				flushptrbuf(&sbuf);
-		}
-	}
-
-	next_block:
-		// Done scanning [b, b+n).  Prepare for the next iteration of
-		// the loop by setting b, n, ti to the parameters for the next block.
-
-		if(sbuf.nobj == 0) {
-			flushptrbuf(&sbuf);
-			flushobjbuf(&sbuf);
-
-			if(sbuf.nobj == 0) {
-				if(!keepworking) {
-					if(sbuf.wbuf)
-						putempty(sbuf.wbuf);
-					return;
-				}
-				// Emptied our buffer: refill.
-				sbuf.wbuf = getfull(sbuf.wbuf);
-				if(sbuf.wbuf == nil)
-					return;
-				sbuf.nobj = sbuf.wbuf->nobj;
-				sbuf.wp = sbuf.wbuf->obj + sbuf.wbuf->nobj;
-			}
-		}
-
-		// Fetch b from the work buffer.
-		--sbuf.wp;
-		b = sbuf.wp->p;
-		n = sbuf.wp->n;
-		ti = sbuf.wp->ti;
-		sbuf.nobj--;
-	}
-}
-
-// Append obj to the work buffer.
-// _wbuf, _wp, _nobj are input/output parameters and are specifying the work buffer.
-static void
-enqueue(Obj obj, Workbuf **_wbuf, Obj **_wp, uintptr *_nobj)
-{
-	uintptr nobj, off;
-	Obj *wp;
-	Workbuf *wbuf;
-
-	if(Debug > 1)
-		runtime·printf("append obj(%p %D %p)\n", obj.p, (int64)obj.n, obj.ti);
-
-	// Align obj.b to a word boundary.
-	off = (uintptr)obj.p & (PtrSize-1);
-	if(off != 0) {
-		obj.p += PtrSize - off;
-		obj.n -= PtrSize - off;
-		obj.ti = 0;
-	}
-
-	if(obj.p == nil || obj.n == 0)
-		return;
-
-	// Load work buffer state
-	wp = *_wp;
-	wbuf = *_wbuf;
-	nobj = *_nobj;
-
-	// If another proc wants a pointer, give it some.
-	if(work.nwait > 0 && nobj > handoffThreshold && work.full == 0) {
-		wbuf->nobj = nobj;
-		wbuf = handoff(wbuf);
-		nobj = wbuf->nobj;
-		wp = wbuf->obj + nobj;
-	}
-
-	// If buffer is full, get a new one.
-	if(wbuf == nil || nobj >= nelem(wbuf->obj)) {
-		if(wbuf != nil)
-			wbuf->nobj = nobj;
-		wbuf = getempty(wbuf);
-		wp = wbuf->obj;
-		nobj = 0;
-	}
-
-	*wp = obj;
-	wp++;
-	nobj++;
-
-	// Save work buffer state
-	*_wp = wp;
-	*_wbuf = wbuf;
-	*_nobj = nobj;
-}
-
-static void
-enqueue1(Workbuf **wbufp, Obj obj)
-{
-	Workbuf *wbuf;
-
-	wbuf = *wbufp;
-	if(wbuf->nobj >= nelem(wbuf->obj))
-		*wbufp = wbuf = getempty(wbuf);
-	wbuf->obj[wbuf->nobj++] = obj;
-}
-
-static void
-markroot(ParFor *desc, uint32 i)
-{
-	Workbuf *wbuf;
-	FinBlock *fb;
-	MHeap *h;
-	MSpan **allspans, *s;
-	uint32 spanidx, sg;
-	G *gp;
-	void *p;
-
-	USED(&desc);
-	wbuf = getempty(nil);
-	// Note: if you add a case here, please also update heapdump.c:dumproots.
-	switch(i) {
-	case RootData:
-		enqueue1(&wbuf, (Obj){data, edata - data, (uintptr)gcdata});
-		break;
-
-	case RootBss:
-		enqueue1(&wbuf, (Obj){bss, ebss - bss, (uintptr)gcbss});
-		break;
-
-	case RootFinalizers:
-		for(fb=allfin; fb; fb=fb->alllink)
-			enqueue1(&wbuf, (Obj){(byte*)fb->fin, fb->cnt*sizeof(fb->fin[0]), 0});
-		break;
-
-	case RootSpanTypes:
-		// mark span types and MSpan.specials (to walk spans only once)
-		h = &runtime·mheap;
-		sg = h->sweepgen;
-		allspans = h->allspans;
-		for(spanidx=0; spanidx<runtime·mheap.nspan; spanidx++) {
-			Special *sp;
-			SpecialFinalizer *spf;
-
-			s = allspans[spanidx];
-			if(s->sweepgen != sg) {
-				runtime·printf("sweep %d %d\n", s->sweepgen, sg);
-				runtime·throw("gc: unswept span");
-			}
-			if(s->state != MSpanInUse)
-				continue;
-			// The garbage collector ignores type pointers stored in MSpan.types:
-			//  - Compiler-generated types are stored outside of heap.
-			//  - The reflect package has runtime-generated types cached in its data structures.
-			//    The garbage collector relies on finding the references via that cache.
-			if(s->types.compression == MTypes_Words || s->types.compression == MTypes_Bytes)
-				markonly((byte*)s->types.data);
-			for(sp = s->specials; sp != nil; sp = sp->next) {
-				if(sp->kind != KindSpecialFinalizer)
-					continue;
-				// don't mark finalized object, but scan it so we
-				// retain everything it points to.
-				spf = (SpecialFinalizer*)sp;
-				// A finalizer can be set for an inner byte of an object, find object beginning.
-				p = (void*)((s->start << PageShift) + spf->offset/s->elemsize*s->elemsize);
-				enqueue1(&wbuf, (Obj){p, s->elemsize, 0});
-				enqueue1(&wbuf, (Obj){(void*)&spf->fn, PtrSize, 0});
-				enqueue1(&wbuf, (Obj){(void*)&spf->fint, PtrSize, 0});
-				enqueue1(&wbuf, (Obj){(void*)&spf->ot, PtrSize, 0});
-			}
-		}
-		break;
-
-	case RootFlushCaches:
-		flushallmcaches();
-		break;
-
-	default:
-		// the rest is scanning goroutine stacks
-		if(i - RootCount >= runtime·allglen)
-			runtime·throw("markroot: bad index");
-		gp = runtime·allg[i - RootCount];
-		// remember when we've first observed the G blocked
-		// needed only to output in traceback
-		if((gp->status == Gwaiting || gp->status == Gsyscall) && gp->waitsince == 0)
-			gp->waitsince = work.tstart;
-		addstackroots(gp, &wbuf);
-		break;
-		
-	}
-
-	if(wbuf)
-		scanblock(wbuf, false);
-}
-
-// Get an empty work buffer off the work.empty list,
-// allocating new buffers as needed.
-static Workbuf*
-getempty(Workbuf *b)
-{
-	if(b != nil)
-		runtime·lfstackpush(&work.full, &b->node);
-	b = (Workbuf*)runtime·lfstackpop(&work.empty);
-	if(b == nil) {
-		// Need to allocate.
-		runtime·lock(&work);
-		if(work.nchunk < sizeof *b) {
-			work.nchunk = 1<<20;
-			work.chunk = runtime·SysAlloc(work.nchunk, &mstats.gc_sys);
-			if(work.chunk == nil)
-				runtime·throw("runtime: cannot allocate memory");
-		}
-		b = (Workbuf*)work.chunk;
-		work.chunk += sizeof *b;
-		work.nchunk -= sizeof *b;
-		runtime·unlock(&work);
-	}
-	b->nobj = 0;
-	return b;
-}
-
-static void
-putempty(Workbuf *b)
-{
-	if(CollectStats)
-		runtime·xadd64(&gcstats.putempty, 1);
-
-	runtime·lfstackpush(&work.empty, &b->node);
-}
-
-// Get a full work buffer off the work.full list, or return nil.
-static Workbuf*
-getfull(Workbuf *b)
-{
-	int32 i;
-
-	if(CollectStats)
-		runtime·xadd64(&gcstats.getfull, 1);
-
-	if(b != nil)
-		runtime·lfstackpush(&work.empty, &b->node);
-	b = (Workbuf*)runtime·lfstackpop(&work.full);
-	if(b != nil || work.nproc == 1)
-		return b;
-
-	runtime·xadd(&work.nwait, +1);
-	for(i=0;; i++) {
-		if(work.full != 0) {
-			runtime·xadd(&work.nwait, -1);
-			b = (Workbuf*)runtime·lfstackpop(&work.full);
-			if(b != nil)
-				return b;
-			runtime·xadd(&work.nwait, +1);
-		}
-		if(work.nwait == work.nproc)
-			return nil;
-		if(i < 10) {
-			m->gcstats.nprocyield++;
-			runtime·procyield(20);
-		} else if(i < 20) {
-			m->gcstats.nosyield++;
-			runtime·osyield();
-		} else {
-			m->gcstats.nsleep++;
-			runtime·usleep(100);
-		}
-	}
-}
-
-static Workbuf*
-handoff(Workbuf *b)
-{
-	int32 n;
-	Workbuf *b1;
-
-	// Make new buffer with half of b's pointers.
-	b1 = getempty(nil);
-	n = b->nobj/2;
-	b->nobj -= n;
-	b1->nobj = n;
-	runtime·memmove(b1->obj, b->obj+b->nobj, n*sizeof b1->obj[0]);
-	m->gcstats.nhandoff++;
-	m->gcstats.nhandoffcnt += n;
-
-	// Put b on full list - let first half of b get stolen.
-	runtime·lfstackpush(&work.full, &b->node);
-	return b1;
-}
-
-extern byte pclntab[]; // base for f->ptrsoff
-
-BitVector
-runtime·stackmapdata(StackMap *stackmap, int32 n)
-{
-	if(n < 0 || n >= stackmap->n)
-		runtime·throw("stackmapdata: index out of range");
-	return (BitVector){stackmap->nbit, stackmap->data + n*((stackmap->nbit+31)/32)};
-}
-
-// Scans an interface data value when the interface type indicates
-// that it is a pointer.
-static void
-scaninterfacedata(uintptr bits, byte *scanp, bool afterprologue, void *wbufp)
-{
-	Itab *tab;
-	Type *type;
-
-	if(runtime·precisestack && afterprologue) {
-		if(bits == BitsIface) {
-			tab = *(Itab**)scanp;
-			if(tab->type->size <= sizeof(void*) && (tab->type->kind & KindNoPointers))
-				return;
-		} else { // bits == BitsEface
-			type = *(Type**)scanp;
-			if(type->size <= sizeof(void*) && (type->kind & KindNoPointers))
-				return;
-		}
-	}
-	enqueue1(wbufp, (Obj){scanp+PtrSize, PtrSize, 0});
-}
-
-// Starting from scanp, scans words corresponding to set bits.
-static void
-scanbitvector(Func *f, bool precise, byte *scanp, BitVector *bv, bool afterprologue, void *wbufp)
-{
-	uintptr word, bits;
-	uint32 *wordp;
-	int32 i, remptrs;
-	byte *p;
-
-	wordp = bv->data;
-	for(remptrs = bv->n; remptrs > 0; remptrs -= 32) {
-		word = *wordp++;
-		if(remptrs < 32)
-			i = remptrs;
-		else
-			i = 32;
-		i /= BitsPerPointer;
-		for(; i > 0; i--) {
-			bits = word & 3;
-			switch(bits) {
-			case BitsDead:
-				if(runtime·debug.gcdead)
-					*(uintptr*)scanp = PoisonGC;
-				break;
-			case BitsScalar:
-				break;
-			case BitsPointer:
-				p = *(byte**)scanp;
-				if(p != nil) {
-					if(Debug > 2)
-						runtime·printf("frame %s @%p: ptr %p\n", runtime·funcname(f), scanp, p);
-					if(precise && (p < (byte*)PageSize || (uintptr)p == PoisonGC || (uintptr)p == PoisonStack)) {
-						// Looks like a junk value in a pointer slot.
-						// Liveness analysis wrong?
-						m->traceback = 2;
-						runtime·printf("bad pointer in frame %s at %p: %p\n", runtime·funcname(f), scanp, p);
-						runtime·throw("bad pointer in scanbitvector");
-					}
-					enqueue1(wbufp, (Obj){scanp, PtrSize, 0});
-				}
-				break;
-			case BitsMultiWord:
-				p = scanp;
-				word >>= BitsPerPointer;
-				scanp += PtrSize;
-				i--;
-				if(i == 0) {
-					// Get next chunk of bits
-					remptrs -= 32;
-					word = *wordp++;
-					if(remptrs < 32)
-						i = remptrs;
-					else
-						i = 32;
-					i /= BitsPerPointer;
-				}
-				switch(word & 3) {
-				case BitsString:
-					if(Debug > 2)
-						runtime·printf("frame %s @%p: string %p/%D\n", runtime·funcname(f), p, ((String*)p)->str, (int64)((String*)p)->len);
-					if(((String*)p)->len != 0)
-						markonly(((String*)p)->str);
-					break;
-				case BitsSlice:
-					word >>= BitsPerPointer;
-					scanp += PtrSize;
-					i--;
-					if(i == 0) {
-						// Get next chunk of bits
-						remptrs -= 32;
-						word = *wordp++;
-						if(remptrs < 32)
-							i = remptrs;
-						else
-							i = 32;
-						i /= BitsPerPointer;
-					}
-					if(Debug > 2)
-						runtime·printf("frame %s @%p: slice %p/%D/%D\n", runtime·funcname(f), p, ((Slice*)p)->array, (int64)((Slice*)p)->len, (int64)((Slice*)p)->cap);
-					if(((Slice*)p)->cap < ((Slice*)p)->len) {
-						m->traceback = 2;
-						runtime·printf("bad slice in frame %s at %p: %p/%p/%p\n", runtime·funcname(f), p, ((byte**)p)[0], ((byte**)p)[1], ((byte**)p)[2]);
-						runtime·throw("slice capacity smaller than length");
-					}
-					if(((Slice*)p)->cap != 0)
-						enqueue1(wbufp, (Obj){p, PtrSize, 0});
-					break;
-				case BitsIface:
-				case BitsEface:
-					if(*(byte**)p != nil) {
-						if(Debug > 2) {
-							if((word&3) == BitsEface)
-								runtime·printf("frame %s @%p: eface %p %p\n", runtime·funcname(f), p, ((uintptr*)p)[0], ((uintptr*)p)[1]);
-							else
-								runtime·printf("frame %s @%p: iface %p %p\n", runtime·funcname(f), p, ((uintptr*)p)[0], ((uintptr*)p)[1]);
-						}
-						scaninterfacedata(word & 3, p, afterprologue, wbufp);
-					}
-					break;
-				}
-			}
-			word >>= BitsPerPointer;
-			scanp += PtrSize;
-		}
-	}
-}
-
-// Scan a stack frame: local variables and function arguments/results.
-static bool
-scanframe(Stkframe *frame, void *wbufp)
-{
-	Func *f;
-	StackMap *stackmap;
-	BitVector bv;
-	uintptr size;
-	uintptr targetpc;
-	int32 pcdata;
-	bool afterprologue;
-	bool precise;
-
-	f = frame->fn;
-	targetpc = frame->continpc;
-	if(targetpc == 0) {
-		// Frame is dead.
-		return true;
-	}
-	if(targetpc != f->entry)
-		targetpc--;
-	pcdata = runtime·pcdatavalue(f, PCDATA_StackMapIndex, targetpc);
-	if(pcdata == -1) {
-		// We do not have a valid pcdata value but there might be a
-		// stackmap for this function.  It is likely that we are looking
-		// at the function prologue, assume so and hope for the best.
-		pcdata = 0;
-	}
-
-	// Scan local variables if stack frame has been allocated.
-	// Use pointer information if known.
-	afterprologue = (frame->varp > (byte*)frame->sp);
-	precise = false;
-	if(afterprologue) {
-		stackmap = runtime·funcdata(f, FUNCDATA_LocalsPointerMaps);
-		if(stackmap == nil) {
-			// No locals information, scan everything.
-			size = frame->varp - (byte*)frame->sp;
-			if(Debug > 2)
-				runtime·printf("frame %s unsized locals %p+%p\n", runtime·funcname(f), frame->varp-size, size);
-			enqueue1(wbufp, (Obj){frame->varp - size, size, 0});
-		} else if(stackmap->n < 0) {
-			// Locals size information, scan just the locals.
-			size = -stackmap->n;
-			if(Debug > 2)
-				runtime·printf("frame %s conservative locals %p+%p\n", runtime·funcname(f), frame->varp-size, size);
-			enqueue1(wbufp, (Obj){frame->varp - size, size, 0});
-		} else if(stackmap->n > 0) {
-			// Locals bitmap information, scan just the pointers in
-			// locals.
-			if(pcdata < 0 || pcdata >= stackmap->n) {
-				// don't know where we are
-				runtime·printf("pcdata is %d and %d stack map entries for %s (targetpc=%p)\n",
-					pcdata, stackmap->n, runtime·funcname(f), targetpc);
-				runtime·throw("scanframe: bad symbol table");
-			}
-			bv = runtime·stackmapdata(stackmap, pcdata);
-			size = (bv.n * PtrSize) / BitsPerPointer;
-			precise = true;
-			scanbitvector(f, true, frame->varp - size, &bv, afterprologue, wbufp);
-		}
-	}
-
-	// Scan arguments.
-	// Use pointer information if known.
-	stackmap = runtime·funcdata(f, FUNCDATA_ArgsPointerMaps);
-	if(stackmap != nil) {
-		bv = runtime·stackmapdata(stackmap, pcdata);
-		scanbitvector(f, precise, frame->argp, &bv, true, wbufp);
-	} else {
-		if(Debug > 2)
-			runtime·printf("frame %s conservative args %p+%p\n", runtime·funcname(f), frame->argp, (uintptr)frame->arglen);
-		enqueue1(wbufp, (Obj){frame->argp, frame->arglen, 0});
-	}
-	return true;
-}
-
-static void
-addstackroots(G *gp, Workbuf **wbufp)
-{
-	M *mp;
-	int32 n;
-	Stktop *stk;
-	uintptr sp, guard;
-	void *base;
-	uintptr size;
-
-	switch(gp->status){
-	default:
-		runtime·printf("unexpected G.status %d (goroutine %p %D)\n", gp->status, gp, gp->goid);
-		runtime·throw("mark - bad status");
-	case Gdead:
-		return;
-	case Grunning:
-		runtime·throw("mark - world not stopped");
-	case Grunnable:
-	case Gsyscall:
-	case Gwaiting:
-		break;
-	}
-
-	if(gp == g)
-		runtime·throw("can't scan our own stack");
-	if((mp = gp->m) != nil && mp->helpgc)
-		runtime·throw("can't scan gchelper stack");
-
-	if(gp->syscallstack != (uintptr)nil) {
-		// Scanning another goroutine that is about to enter or might
-		// have just exited a system call. It may be executing code such
-		// as schedlock and may have needed to start a new stack segment.
-		// Use the stack segment and stack pointer at the time of
-		// the system call instead, since that won't change underfoot.
-		sp = gp->syscallsp;
-		stk = (Stktop*)gp->syscallstack;
-		guard = gp->syscallguard;
-	} else {
-		// Scanning another goroutine's stack.
-		// The goroutine is usually asleep (the world is stopped).
-		sp = gp->sched.sp;
-		stk = (Stktop*)gp->stackbase;
-		guard = gp->stackguard;
-		// For function about to start, context argument is a root too.
-		if(gp->sched.ctxt != 0 && runtime·mlookup(gp->sched.ctxt, &base, &size, nil))
-			enqueue1(wbufp, (Obj){base, size, 0});
-	}
-	if(ScanStackByFrames) {
-		USED(sp);
-		USED(stk);
-		USED(guard);
-		runtime·gentraceback(~(uintptr)0, ~(uintptr)0, 0, gp, 0, nil, 0x7fffffff, scanframe, wbufp, false);
-	} else {
-		n = 0;
-		while(stk) {
-			if(sp < guard-StackGuard || (uintptr)stk < sp) {
-				runtime·printf("scanstack inconsistent: g%D#%d sp=%p not in [%p,%p]\n", gp->goid, n, sp, guard-StackGuard, stk);
-				runtime·throw("scanstack");
-			}
-			if(Debug > 2)
-				runtime·printf("conservative stack %p+%p\n", (byte*)sp, (uintptr)stk-sp);
-			enqueue1(wbufp, (Obj){(byte*)sp, (uintptr)stk - sp, (uintptr)defaultProg | PRECISE | LOOP});
-			sp = stk->gobuf.sp;
-			guard = stk->stackguard;
-			stk = (Stktop*)stk->stackbase;
-			n++;
-		}
-	}
-}
-
-void
-runtime·queuefinalizer(byte *p, FuncVal *fn, uintptr nret, Type *fint, PtrType *ot)
-{
-	FinBlock *block;
-	Finalizer *f;
-
-	runtime·lock(&finlock);
-	if(finq == nil || finq->cnt == finq->cap) {
-		if(finc == nil) {
-			finc = runtime·persistentalloc(FinBlockSize, 0, &mstats.gc_sys);
-			finc->cap = (FinBlockSize - sizeof(FinBlock)) / sizeof(Finalizer) + 1;
-			finc->alllink = allfin;
-			allfin = finc;
-		}
-		block = finc;
-		finc = block->next;
-		block->next = finq;
-		finq = block;
-	}
-	f = &finq->fin[finq->cnt];
-	finq->cnt++;
-	f->fn = fn;
-	f->nret = nret;
-	f->fint = fint;
-	f->ot = ot;
-	f->arg = p;
-	runtime·fingwake = true;
-	runtime·unlock(&finlock);
-}
-
-void
-runtime·iterate_finq(void (*callback)(FuncVal*, byte*, uintptr, Type*, PtrType*))
-{
-	FinBlock *fb;
-	Finalizer *f;
-	uintptr i;
-
-	for(fb = allfin; fb; fb = fb->alllink) {
-		for(i = 0; i < fb->cnt; i++) {
-			f = &fb->fin[i];
-			callback(f->fn, f->arg, f->nret, f->fint, f->ot);
-		}
-	}
-}
-
-void
-runtime·MSpan_EnsureSwept(MSpan *s)
-{
-	uint32 sg;
-
-	// Caller must disable preemption.
-	// Otherwise when this function returns the span can become unswept again
-	// (if GC is triggered on another goroutine).
-	if(m->locks == 0 && m->mallocing == 0 && g != m->g0)
-		runtime·throw("MSpan_EnsureSwept: m is not locked");
-
-	sg = runtime·mheap.sweepgen;
-	if(runtime·atomicload(&s->sweepgen) == sg)
-		return;
-	if(runtime·cas(&s->sweepgen, sg-2, sg-1)) {
-		runtime·MSpan_Sweep(s);
-		return;
-	}
-	// unfortunate condition, and we don't have efficient means to wait
-	while(runtime·atomicload(&s->sweepgen) != sg)
-		runtime·osyield();  
-}
-
-// Sweep frees or collects finalizers for blocks not marked in the mark phase.
-// It clears the mark bits in preparation for the next GC round.
-// Returns true if the span was returned to heap.
-bool
-runtime·MSpan_Sweep(MSpan *s)
-{
-	int32 cl, n, npages, nfree;
-	uintptr size, off, *bitp, shift, bits;
-	uint32 sweepgen;
-	byte *p;
-	MCache *c;
-	byte *arena_start;
-	MLink head, *end;
-	byte *type_data;
-	byte compression;
-	uintptr type_data_inc;
-	MLink *x;
-	Special *special, **specialp, *y;
-	bool res, sweepgenset;
-
-	// It's critical that we enter this function with preemption disabled,
-	// GC must not start while we are in the middle of this function.
-	if(m->locks == 0 && m->mallocing == 0 && g != m->g0)
-		runtime·throw("MSpan_Sweep: m is not locked");
-	sweepgen = runtime·mheap.sweepgen;
-	if(s->state != MSpanInUse || s->sweepgen != sweepgen-1) {
-		runtime·printf("MSpan_Sweep: state=%d sweepgen=%d mheap.sweepgen=%d\n",
-			s->state, s->sweepgen, sweepgen);
-		runtime·throw("MSpan_Sweep: bad span state");
-	}
-	arena_start = runtime·mheap.arena_start;
-	cl = s->sizeclass;
-	size = s->elemsize;
-	if(cl == 0) {
-		n = 1;
-	} else {
-		// Chunk full of small blocks.
-		npages = runtime·class_to_allocnpages[cl];
-		n = (npages << PageShift) / size;
-	}
-	res = false;
-	nfree = 0;
-	end = &head;
-	c = m->mcache;
-	sweepgenset = false;
-
-	// mark any free objects in this span so we don't collect them
-	for(x = s->freelist; x != nil; x = x->next) {
-		// This is markonly(x) but faster because we don't need
-		// atomic access and we're guaranteed to be pointing at
-		// the head of a valid object.
-		off = (uintptr*)x - (uintptr*)runtime·mheap.arena_start;
-		bitp = (uintptr*)runtime·mheap.arena_start - off/wordsPerBitmapWord - 1;
-		shift = off % wordsPerBitmapWord;
-		*bitp |= bitMarked<<shift;
-	}
-
-	// Unlink & free special records for any objects we're about to free.
-	specialp = &s->specials;
-	special = *specialp;
-	while(special != nil) {
-		// A finalizer can be set for an inner byte of an object, find object beginning.
-		p = (byte*)(s->start << PageShift) + special->offset/size*size;
-		off = (uintptr*)p - (uintptr*)arena_start;
-		bitp = (uintptr*)arena_start - off/wordsPerBitmapWord - 1;
-		shift = off % wordsPerBitmapWord;
-		bits = *bitp>>shift;
-		if((bits & (bitAllocated|bitMarked)) == bitAllocated) {
-			// Find the exact byte for which the special was setup
-			// (as opposed to object beginning).
-			p = (byte*)(s->start << PageShift) + special->offset;
-			// about to free object: splice out special record
-			y = special;
-			special = special->next;
-			*specialp = special;
-			if(!runtime·freespecial(y, p, size, false)) {
-				// stop freeing of object if it has a finalizer
-				*bitp |= bitMarked << shift;
-			}
-		} else {
-			// object is still live: keep special record
-			specialp = &special->next;
-			special = *specialp;
-		}
-	}
-
-	type_data = (byte*)s->types.data;
-	type_data_inc = sizeof(uintptr);
-	compression = s->types.compression;
-	switch(compression) {
-	case MTypes_Bytes:
-		type_data += 8*sizeof(uintptr);
-		type_data_inc = 1;
-		break;
-	}
-
-	// Sweep through n objects of given size starting at p.
-	// This thread owns the span now, so it can manipulate
-	// the block bitmap without atomic operations.
-	p = (byte*)(s->start << PageShift);
-	for(; n > 0; n--, p += size, type_data+=type_data_inc) {
-		off = (uintptr*)p - (uintptr*)arena_start;
-		bitp = (uintptr*)arena_start - off/wordsPerBitmapWord - 1;
-		shift = off % wordsPerBitmapWord;
-		bits = *bitp>>shift;
-
-		if((bits & bitAllocated) == 0)
-			continue;
-
-		if((bits & bitMarked) != 0) {
-			*bitp &= ~(bitMarked<<shift);
-			continue;
-		}
-
-		if(runtime·debug.allocfreetrace)
-			runtime·tracefree(p, size);
-
-		// Clear mark and scan bits.
-		*bitp &= ~((bitScan|bitMarked)<<shift);
-
-		if(cl == 0) {
-			// Free large span.
-			runtime·unmarkspan(p, 1<<PageShift);
-			s->needzero = 1;
-			// important to set sweepgen before returning it to heap
-			runtime·atomicstore(&s->sweepgen, sweepgen);
-			sweepgenset = true;
-			// See note about SysFault vs SysFree in malloc.goc.
-			if(runtime·debug.efence)
-				runtime·SysFault(p, size);
-			else
-				runtime·MHeap_Free(&runtime·mheap, s, 1);
-			c->local_nlargefree++;
-			c->local_largefree += size;
-			runtime·xadd64(&mstats.next_gc, -(uint64)(size * (gcpercent + 100)/100));
-			res = true;
-		} else {
-			// Free small object.
-			switch(compression) {
-			case MTypes_Words:
-				*(uintptr*)type_data = 0;
-				break;
-			case MTypes_Bytes:
-				*(byte*)type_data = 0;
-				break;
-			}
-			if(size > 2*sizeof(uintptr))
-				((uintptr*)p)[1] = (uintptr)0xdeaddeaddeaddeadll;	// mark as "needs to be zeroed"
-			else if(size > sizeof(uintptr))
-				((uintptr*)p)[1] = 0;
-
-			end->next = (MLink*)p;
-			end = (MLink*)p;
-			nfree++;
-		}
-	}
-
-	// We need to set s->sweepgen = h->sweepgen only when all blocks are swept,
-	// because of the potential for a concurrent free/SetFinalizer.
-	// But we need to set it before we make the span available for allocation
-	// (return it to heap or mcentral), because allocation code assumes that a
-	// span is already swept if available for allocation.
-
-	if(!sweepgenset && nfree == 0) {
-		// The span must be in our exclusive ownership until we update sweepgen,
-		// check for potential races.
-		if(s->state != MSpanInUse || s->sweepgen != sweepgen-1) {
-			runtime·printf("MSpan_Sweep: state=%d sweepgen=%d mheap.sweepgen=%d\n",
-				s->state, s->sweepgen, sweepgen);
-			runtime·throw("MSpan_Sweep: bad span state after sweep");
-		}
-		runtime·atomicstore(&s->sweepgen, sweepgen);
-	}
-	if(nfree > 0) {
-		c->local_nsmallfree[cl] += nfree;
-		c->local_cachealloc -= nfree * size;
-		runtime·xadd64(&mstats.next_gc, -(uint64)(nfree * size * (gcpercent + 100)/100));
-		res = runtime·MCentral_FreeSpan(&runtime·mheap.central[cl], s, nfree, head.next, end);
-		//MCentral_FreeSpan updates sweepgen
-	}
-	return res;
-}
-
-// State of background sweep.
-// Pretected by gclock.
-static struct
-{
-	G*	g;
-	bool	parked;
-
-	MSpan**	spans;
-	uint32	nspan;
-	uint32	spanidx;
-} sweep;
-
-// background sweeping goroutine
-static void
-bgsweep(void)
-{
-	g->issystem = 1;
-	for(;;) {
-		while(runtime·sweepone() != -1) {
-			gcstats.nbgsweep++;
-			runtime·gosched();
-		}
-		runtime·lock(&gclock);
-		if(!runtime·mheap.sweepdone) {
-			// It's possible if GC has happened between sweepone has
-			// returned -1 and gclock lock.
-			runtime·unlock(&gclock);
-			continue;
-		}
-		sweep.parked = true;
-		g->isbackground = true;
-		runtime·parkunlock(&gclock, "GC sweep wait");
-		g->isbackground = false;
-	}
-}
-
-// sweeps one span
-// returns number of pages returned to heap, or -1 if there is nothing to sweep
-uintptr
-runtime·sweepone(void)
-{
-	MSpan *s;
-	uint32 idx, sg;
-	uintptr npages;
-
-	// increment locks to ensure that the goroutine is not preempted
-	// in the middle of sweep thus leaving the span in an inconsistent state for next GC
-	m->locks++;
-	sg = runtime·mheap.sweepgen;
-	for(;;) {
-		idx = runtime·xadd(&sweep.spanidx, 1) - 1;
-		if(idx >= sweep.nspan) {
-			runtime·mheap.sweepdone = true;
-			m->locks--;
-			return -1;
-		}
-		s = sweep.spans[idx];
-		if(s->state != MSpanInUse) {
-			s->sweepgen = sg;
-			continue;
-		}
-		if(s->sweepgen != sg-2 || !runtime·cas(&s->sweepgen, sg-2, sg-1))
-			continue;
-		if(s->incache)
-			runtime·throw("sweep of incache span");
-		npages = s->npages;
-		if(!runtime·MSpan_Sweep(s))
-			npages = 0;
-		m->locks--;
-		return npages;
-	}
-}
-
-static void
-dumpspan(uint32 idx)
-{
-	int32 sizeclass, n, npages, i, column;
-	uintptr size;
-	byte *p;
-	byte *arena_start;
-	MSpan *s;
-	bool allocated;
-
-	s = runtime·mheap.allspans[idx];
-	if(s->state != MSpanInUse)
-		return;
-	arena_start = runtime·mheap.arena_start;
-	p = (byte*)(s->start << PageShift);
-	sizeclass = s->sizeclass;
-	size = s->elemsize;
-	if(sizeclass == 0) {
-		n = 1;
-	} else {
-		npages = runtime·class_to_allocnpages[sizeclass];
-		n = (npages << PageShift) / size;
-	}
-	
-	runtime·printf("%p .. %p:\n", p, p+n*size);
-	column = 0;
-	for(; n>0; n--, p+=size) {
-		uintptr off, *bitp, shift, bits;
-
-		off = (uintptr*)p - (uintptr*)arena_start;
-		bitp = (uintptr*)arena_start - off/wordsPerBitmapWord - 1;
-		shift = off % wordsPerBitmapWord;
-		bits = *bitp>>shift;
-
-		allocated = ((bits & bitAllocated) != 0);
-
-		for(i=0; i<size; i+=sizeof(void*)) {
-			if(column == 0) {
-				runtime·printf("\t");
-			}
-			if(i == 0) {
-				runtime·printf(allocated ? "(" : "[");
-				runtime·printf("%p: ", p+i);
-			} else {
-				runtime·printf(" ");
-			}
-
-			runtime·printf("%p", *(void**)(p+i));
-
-			if(i+sizeof(void*) >= size) {
-				runtime·printf(allocated ? ") " : "] ");
-			}
-
-			column++;
-			if(column == 8) {
-				runtime·printf("\n");
-				column = 0;
-			}
-		}
-	}
-	runtime·printf("\n");
-}
-
-// A debugging function to dump the contents of memory
-void
-runtime·memorydump(void)
-{
-	uint32 spanidx;
-
-	for(spanidx=0; spanidx<runtime·mheap.nspan; spanidx++) {
-		dumpspan(spanidx);
-	}
-}
-
-void
-runtime·gchelper(void)
-{
-	uint32 nproc;
-
-	m->traceback = 2;
-	gchelperstart();
-
-	// parallel mark for over gc roots
-	runtime·parfordo(work.markfor);
-
-	// help other threads scan secondary blocks
-	scanblock(nil, true);
-
-	bufferList[m->helpgc].busy = 0;
-	nproc = work.nproc;  // work.nproc can change right after we increment work.ndone
-	if(runtime·xadd(&work.ndone, +1) == nproc-1)
-		runtime·notewakeup(&work.alldone);
-	m->traceback = 0;
-}
-
-static void
-cachestats(void)
-{
-	MCache *c;
-	P *p, **pp;
-
-	for(pp=runtime·allp; p=*pp; pp++) {
-		c = p->mcache;
-		if(c==nil)
-			continue;
-		runtime·purgecachedstats(c);
-	}
-}
-
-static void
-flushallmcaches(void)
-{
-	P *p, **pp;
-	MCache *c;
-
-	// Flush MCache's to MCentral.
-	for(pp=runtime·allp; p=*pp; pp++) {
-		c = p->mcache;
-		if(c==nil)
-			continue;
-		runtime·MCache_ReleaseAll(c);
-	}
-}
-
-void
-runtime·updatememstats(GCStats *stats)
-{
-	M *mp;
-	MSpan *s;
-	int32 i;
-	uint64 stacks_inuse, smallfree;
-	uint64 *src, *dst;
-
-	if(stats)
-		runtime·memclr((byte*)stats, sizeof(*stats));
-	stacks_inuse = 0;
-	for(mp=runtime·allm; mp; mp=mp->alllink) {
-		stacks_inuse += mp->stackinuse*FixedStack;
-		if(stats) {
-			src = (uint64*)&mp->gcstats;
-			dst = (uint64*)stats;
-			for(i=0; i<sizeof(*stats)/sizeof(uint64); i++)
-				dst[i] += src[i];
-			runtime·memclr((byte*)&mp->gcstats, sizeof(mp->gcstats));
-		}
-	}
-	mstats.stacks_inuse = stacks_inuse;
-	mstats.mcache_inuse = runtime·mheap.cachealloc.inuse;
-	mstats.mspan_inuse = runtime·mheap.spanalloc.inuse;
-	mstats.sys = mstats.heap_sys + mstats.stacks_sys + mstats.mspan_sys +
-		mstats.mcache_sys + mstats.buckhash_sys + mstats.gc_sys + mstats.other_sys;
-	
-	// Calculate memory allocator stats.
-	// During program execution we only count number of frees and amount of freed memory.
-	// Current number of alive object in the heap and amount of alive heap memory
-	// are calculated by scanning all spans.
-	// Total number of mallocs is calculated as number of frees plus number of alive objects.
-	// Similarly, total amount of allocated memory is calculated as amount of freed memory
-	// plus amount of alive heap memory.
-	mstats.alloc = 0;
-	mstats.total_alloc = 0;
-	mstats.nmalloc = 0;
-	mstats.nfree = 0;
-	for(i = 0; i < nelem(mstats.by_size); i++) {
-		mstats.by_size[i].nmalloc = 0;
-		mstats.by_size[i].nfree = 0;
-	}
-
-	// Flush MCache's to MCentral.
-	flushallmcaches();
-
-	// Aggregate local stats.
-	cachestats();
-
-	// Scan all spans and count number of alive objects.
-	for(i = 0; i < runtime·mheap.nspan; i++) {
-		s = runtime·mheap.allspans[i];
-		if(s->state != MSpanInUse)
-			continue;
-		if(s->sizeclass == 0) {
-			mstats.nmalloc++;
-			mstats.alloc += s->elemsize;
-		} else {
-			mstats.nmalloc += s->ref;
-			mstats.by_size[s->sizeclass].nmalloc += s->ref;
-			mstats.alloc += s->ref*s->elemsize;
-		}
-	}
-
-	// Aggregate by size class.
-	smallfree = 0;
-	mstats.nfree = runtime·mheap.nlargefree;
-	for(i = 0; i < nelem(mstats.by_size); i++) {
-		mstats.nfree += runtime·mheap.nsmallfree[i];
-		mstats.by_size[i].nfree = runtime·mheap.nsmallfree[i];
-		mstats.by_size[i].nmalloc += runtime·mheap.nsmallfree[i];
-		smallfree += runtime·mheap.nsmallfree[i] * runtime·class_to_size[i];
-	}
-	mstats.nmalloc += mstats.nfree;
-
-	// Calculate derived stats.
-	mstats.total_alloc = mstats.alloc + runtime·mheap.largefree + smallfree;
-	mstats.heap_alloc = mstats.alloc;
-	mstats.heap_objects = mstats.nmalloc - mstats.nfree;
-}
-
-// Structure of arguments passed to function gc().
-// This allows the arguments to be passed via runtime·mcall.
-struct gc_args
-{
-	int64 start_time; // start time of GC in ns (just before stoptheworld)
-	bool  eagersweep;
-};
-
-static void gc(struct gc_args *args);
-static void mgc(G *gp);
-
-static int32
-readgogc(void)
-{
-	byte *p;
-
-	p = runtime·getenv("GOGC");
-	if(p == nil || p[0] == '\0')
-		return 100;
-	if(runtime·strcmp(p, (byte*)"off") == 0)
-		return -1;
-	return runtime·atoi(p);
-}
-
-// force = 1 - do GC regardless of current heap usage
-// force = 2 - go GC and eager sweep
-void
-runtime·gc(int32 force)
-{
-	struct gc_args a;
-	int32 i;
-
-	// The atomic operations are not atomic if the uint64s
-	// are not aligned on uint64 boundaries. This has been
-	// a problem in the past.
-	if((((uintptr)&work.empty) & 7) != 0)
-		runtime·throw("runtime: gc work buffer is misaligned");
-	if((((uintptr)&work.full) & 7) != 0)
-		runtime·throw("runtime: gc work buffer is misaligned");
-
-	// The gc is turned off (via enablegc) until
-	// the bootstrap has completed.
-	// Also, malloc gets called in the guts
-	// of a number of libraries that might be
-	// holding locks.  To avoid priority inversion
-	// problems, don't bother trying to run gc
-	// while holding a lock.  The next mallocgc
-	// without a lock will do the gc instead.
-	if(!mstats.enablegc || g == m->g0 || m->locks > 0 || runtime·panicking)
-		return;
-
-	if(gcpercent == GcpercentUnknown) {	// first time through
-		runtime·lock(&runtime·mheap);
-		if(gcpercent == GcpercentUnknown)
-			gcpercent = readgogc();
-		runtime·unlock(&runtime·mheap);
-	}
-	if(gcpercent < 0)
-		return;
-
-	runtime·semacquire(&runtime·worldsema, false);
-	if(force==0 && mstats.heap_alloc < mstats.next_gc) {
-		// typically threads which lost the race to grab
-		// worldsema exit here when gc is done.
-		runtime·semrelease(&runtime·worldsema);
-		return;
-	}
-
-	// Ok, we're doing it!  Stop everybody else
-	a.start_time = runtime·nanotime();
-	a.eagersweep = force >= 2;
-	m->gcing = 1;
-	runtime·stoptheworld();
-	
-	clearpools();
-
-	// Run gc on the g0 stack.  We do this so that the g stack
-	// we're currently running on will no longer change.  Cuts
-	// the root set down a bit (g0 stacks are not scanned, and
-	// we don't need to scan gc's internal state).  Also an
-	// enabler for copyable stacks.
-	for(i = 0; i < (runtime·debug.gctrace > 1 ? 2 : 1); i++) {
-		if(i > 0)
-			a.start_time = runtime·nanotime();
-		// switch to g0, call gc(&a), then switch back
-		g->param = &a;
-		g->status = Gwaiting;
-		g->waitreason = "garbage collection";
-		runtime·mcall(mgc);
-	}
-
-	// all done
-	m->gcing = 0;
-	m->locks++;
-	runtime·semrelease(&runtime·worldsema);
-	runtime·starttheworld();
-	m->locks--;
-
-	// now that gc is done, kick off finalizer thread if needed
-	if(!ConcurrentSweep) {
-		// give the queued finalizers, if any, a chance to run
-		runtime·gosched();
-	}
-}
-
-static void
-mgc(G *gp)
-{
-	gc(gp->param);
-	gp->param = nil;
-	gp->status = Grunning;
-	runtime·gogo(&gp->sched);
-}
-
-static void
-gc(struct gc_args *args)
-{
-	int64 t0, t1, t2, t3, t4;
-	uint64 heap0, heap1, obj, ninstr;
-	GCStats stats;
-	uint32 i;
-	Eface eface;
-
-	if(runtime·debug.allocfreetrace)
-		runtime·tracegc();
-
-	m->traceback = 2;
-	t0 = args->start_time;
-	work.tstart = args->start_time; 
-
-	if(CollectStats)
-		runtime·memclr((byte*)&gcstats, sizeof(gcstats));
-
-	m->locks++;	// disable gc during mallocs in parforalloc
-	if(work.markfor == nil)
-		work.markfor = runtime·parforalloc(MaxGcproc);
-	m->locks--;
-
-	if(itabtype == nil) {
-		// get C pointer to the Go type "itab"
-		runtime·gc_itab_ptr(&eface);
-		itabtype = ((PtrType*)eface.type)->elem;
-	}
-
-	t1 = 0;
-	if(runtime·debug.gctrace)
-		t1 = runtime·nanotime();
-
-	// Sweep what is not sweeped by bgsweep.
-	while(runtime·sweepone() != -1)
-		gcstats.npausesweep++;
-
-	work.nwait = 0;
-	work.ndone = 0;
-	work.nproc = runtime·gcprocs();
-	runtime·parforsetup(work.markfor, work.nproc, RootCount + runtime·allglen, nil, false, markroot);
-	if(work.nproc > 1) {
-		runtime·noteclear(&work.alldone);
-		runtime·helpgc(work.nproc);
-	}
-
-	t2 = 0;
-	if(runtime·debug.gctrace)
-		t2 = runtime·nanotime();
-
-	gchelperstart();
-	runtime·parfordo(work.markfor);
-	scanblock(nil, true);
-
-	t3 = 0;
-	if(runtime·debug.gctrace)
-		t3 = runtime·nanotime();
-
-	bufferList[m->helpgc].busy = 0;
-	if(work.nproc > 1)
-		runtime·notesleep(&work.alldone);
-
-	cachestats();
-	// next_gc calculation is tricky with concurrent sweep since we don't know size of live heap
-	// estimate what was live heap size after previous GC (for tracing only)
-	heap0 = mstats.next_gc*100/(gcpercent+100);
-	// conservatively set next_gc to high value assuming that everything is live
-	// concurrent/lazy sweep will reduce this number while discovering new garbage
-	mstats.next_gc = mstats.heap_alloc+mstats.heap_alloc*gcpercent/100;
-
-	t4 = runtime·nanotime();
-	mstats.last_gc = runtime·unixnanotime();  // must be Unix time to make sense to user
-	mstats.pause_ns[mstats.numgc%nelem(mstats.pause_ns)] = t4 - t0;
-	mstats.pause_total_ns += t4 - t0;
-	mstats.numgc++;
-	if(mstats.debuggc)
-		runtime·printf("pause %D\n", t4-t0);
-
-	if(runtime·debug.gctrace) {
-		heap1 = mstats.heap_alloc;
-		runtime·updatememstats(&stats);
-		if(heap1 != mstats.heap_alloc) {
-			runtime·printf("runtime: mstats skew: heap=%D/%D\n", heap1, mstats.heap_alloc);
-			runtime·throw("mstats skew");
-		}
-		obj = mstats.nmalloc - mstats.nfree;
-
-		stats.nprocyield += work.markfor->nprocyield;
-		stats.nosyield += work.markfor->nosyield;
-		stats.nsleep += work.markfor->nsleep;
-
-		runtime·printf("gc%d(%d): %D+%D+%D+%D us, %D -> %D MB, %D (%D-%D) objects,"
-				" %d/%d/%d sweeps,"
-				" %D(%D) handoff, %D(%D) steal, %D/%D/%D yields\n",
-			mstats.numgc, work.nproc, (t1-t0)/1000, (t2-t1)/1000, (t3-t2)/1000, (t4-t3)/1000,
-			heap0>>20, heap1>>20, obj,
-			mstats.nmalloc, mstats.nfree,
-			sweep.nspan, gcstats.nbgsweep, gcstats.npausesweep,
-			stats.nhandoff, stats.nhandoffcnt,
-			work.markfor->nsteal, work.markfor->nstealcnt,
-			stats.nprocyield, stats.nosyield, stats.nsleep);
-		gcstats.nbgsweep = gcstats.npausesweep = 0;
-		if(CollectStats) {
-			runtime·printf("scan: %D bytes, %D objects, %D untyped, %D types from MSpan\n",
-				gcstats.nbytes, gcstats.obj.cnt, gcstats.obj.notype, gcstats.obj.typelookup);
-			if(gcstats.ptr.cnt != 0)
-				runtime·printf("avg ptrbufsize: %D (%D/%D)\n",
-					gcstats.ptr.sum/gcstats.ptr.cnt, gcstats.ptr.sum, gcstats.ptr.cnt);
-			if(gcstats.obj.cnt != 0)
-				runtime·printf("avg nobj: %D (%D/%D)\n",
-					gcstats.obj.sum/gcstats.obj.cnt, gcstats.obj.sum, gcstats.obj.cnt);
-			runtime·printf("rescans: %D, %D bytes\n", gcstats.rescan, gcstats.rescanbytes);
-
-			runtime·printf("instruction counts:\n");
-			ninstr = 0;
-			for(i=0; i<nelem(gcstats.instr); i++) {
-				runtime·printf("\t%d:\t%D\n", i, gcstats.instr[i]);
-				ninstr += gcstats.instr[i];
-			}
-			runtime·printf("\ttotal:\t%D\n", ninstr);
-
-			runtime·printf("putempty: %D, getfull: %D\n", gcstats.putempty, gcstats.getfull);
-
-			runtime·printf("markonly base lookup: bit %D word %D span %D\n", gcstats.markonly.foundbit, gcstats.markonly.foundword, gcstats.markonly.foundspan);
-			runtime·printf("flushptrbuf base lookup: bit %D word %D span %D\n", gcstats.flushptrbuf.foundbit, gcstats.flushptrbuf.foundword, gcstats.flushptrbuf.foundspan);
-		}
-	}
-
-	// We cache current runtime·mheap.allspans array in sweep.spans,
-	// because the former can be resized and freed.
-	// Otherwise we would need to take heap lock every time
-	// we want to convert span index to span pointer.
-
-	// Free the old cached array if necessary.
-	if(sweep.spans && sweep.spans != runtime·mheap.allspans)
-		runtime·SysFree(sweep.spans, sweep.nspan*sizeof(sweep.spans[0]), &mstats.other_sys);
-	// Cache the current array.
-	runtime·mheap.sweepspans = runtime·mheap.allspans;
-	runtime·mheap.sweepgen += 2;
-	runtime·mheap.sweepdone = false;
-	sweep.spans = runtime·mheap.allspans;
-	sweep.nspan = runtime·mheap.nspan;
-	sweep.spanidx = 0;
-
-	// Temporary disable concurrent sweep, because we see failures on builders.
-	if(ConcurrentSweep && !args->eagersweep) {
-		runtime·lock(&gclock);
-		if(sweep.g == nil)
-			sweep.g = runtime·newproc1(&bgsweepv, nil, 0, 0, runtime·gc);
-		else if(sweep.parked) {
-			sweep.parked = false;
-			runtime·ready(sweep.g);
-		}
-		runtime·unlock(&gclock);
-	} else {
-		// Sweep all spans eagerly.
-		while(runtime·sweepone() != -1)
-			gcstats.npausesweep++;
-	}
-
-	// Shrink a stack if not much of it is being used.
-	// TODO: do in a parfor
-	for(i = 0; i < runtime·allglen; i++)
-		runtime·shrinkstack(runtime·allg[i]);
-
-	runtime·MProf_GC();
-	m->traceback = 0;
-}
-
-extern uintptr runtime·sizeof_C_MStats;
-
-void
-runtime·ReadMemStats(MStats *stats)
-{
-	// Have to acquire worldsema to stop the world,
-	// because stoptheworld can only be used by
-	// one goroutine at a time, and there might be
-	// a pending garbage collection already calling it.
-	runtime·semacquire(&runtime·worldsema, false);
-	m->gcing = 1;
-	runtime·stoptheworld();
-	runtime·updatememstats(nil);
-	// Size of the trailing by_size array differs between Go and C,
-	// NumSizeClasses was changed, but we can not change Go struct because of backward compatibility.
-	runtime·memcopy(runtime·sizeof_C_MStats, stats, &mstats);
-	m->gcing = 0;
-	m->locks++;
-	runtime·semrelease(&runtime·worldsema);
-	runtime·starttheworld();
-	m->locks--;
-}
-
-void
-runtime∕debug·readGCStats(Slice *pauses)
-{
-	uint64 *p;
-	uint32 i, n;
-
-	// Calling code in runtime/debug should make the slice large enough.
-	if(pauses->cap < nelem(mstats.pause_ns)+3)
-		runtime·throw("runtime: short slice passed to readGCStats");
-
-	// Pass back: pauses, last gc (absolute time), number of gc, total pause ns.
-	p = (uint64*)pauses->array;
-	runtime·lock(&runtime·mheap);
-	n = mstats.numgc;
-	if(n > nelem(mstats.pause_ns))
-		n = nelem(mstats.pause_ns);
-	
-	// The pause buffer is circular. The most recent pause is at
-	// pause_ns[(numgc-1)%nelem(pause_ns)], and then backward
-	// from there to go back farther in time. We deliver the times
-	// most recent first (in p[0]).
-	for(i=0; i<n; i++)
-		p[i] = mstats.pause_ns[(mstats.numgc-1-i)%nelem(mstats.pause_ns)];
-
-	p[n] = mstats.last_gc;
-	p[n+1] = mstats.numgc;
-	p[n+2] = mstats.pause_total_ns;	
-	runtime·unlock(&runtime·mheap);
-	pauses->len = n+3;
-}
-
-int32
-runtime·setgcpercent(int32 in) {
-	int32 out;
-
-	runtime·lock(&runtime·mheap);
-	if(gcpercent == GcpercentUnknown)
-		gcpercent = readgogc();
-	out = gcpercent;
-	if(in < 0)
-		in = -1;
-	gcpercent = in;
-	runtime·unlock(&runtime·mheap);
-	return out;
-}
-
-static void
-gchelperstart(void)
-{
-	if(m->helpgc < 0 || m->helpgc >= MaxGcproc)
-		runtime·throw("gchelperstart: bad m->helpgc");
-	if(runtime·xchg(&bufferList[m->helpgc].busy, 1))
-		runtime·throw("gchelperstart: already busy");
-	if(g != m->g0)
-		runtime·throw("gchelper not running on g0 stack");
-}
-
-static void
-runfinq(void)
-{
-	Finalizer *f;
-	FinBlock *fb, *next;
-	byte *frame;
-	uint32 framesz, framecap, i;
-	Eface *ef, ef1;
-
-	// This function blocks for long periods of time, and because it is written in C
-	// we have no liveness information. Zero everything so that uninitialized pointers
-	// do not cause memory leaks.
-	f = nil;
-	fb = nil;
-	next = nil;
-	frame = nil;
-	framecap = 0;
-	framesz = 0;
-	i = 0;
-	ef = nil;
-	ef1.type = nil;
-	ef1.data = nil;
-	
-	// force flush to memory
-	USED(&f);
-	USED(&fb);
-	USED(&next);
-	USED(&framesz);
-	USED(&i);
-	USED(&ef);
-	USED(&ef1);
-
-	for(;;) {
-		runtime·lock(&finlock);
-		fb = finq;
-		finq = nil;
-		if(fb == nil) {
-			runtime·fingwait = true;
-			g->isbackground = true;
-			runtime·parkunlock(&finlock, "finalizer wait");
-			g->isbackground = false;
-			continue;
-		}
-		runtime·unlock(&finlock);
-		if(raceenabled)
-			runtime·racefingo();
-		for(; fb; fb=next) {
-			next = fb->next;
-			for(i=0; i<fb->cnt; i++) {
-				f = &fb->fin[i];
-				framesz = sizeof(Eface) + f->nret;
-				if(framecap < framesz) {
-					runtime·free(frame);
-					// The frame does not contain pointers interesting for GC,
-					// all not yet finalized objects are stored in finq.
-					// If we do not mark it as FlagNoScan,
-					// the last finalized object is not collected.
-					frame = runtime·mallocgc(framesz, 0, FlagNoScan|FlagNoInvokeGC);
-					framecap = framesz;
-				}
-				if(f->fint == nil)
-					runtime·throw("missing type in runfinq");
-				if(f->fint->kind == KindPtr) {
-					// direct use of pointer
-					*(void**)frame = f->arg;
-				} else if(((InterfaceType*)f->fint)->mhdr.len == 0) {
-					// convert to empty interface
-					ef = (Eface*)frame;
-					ef->type = f->ot;
-					ef->data = f->arg;
-				} else {
-					// convert to interface with methods, via empty interface.
-					ef1.type = f->ot;
-					ef1.data = f->arg;
-					if(!runtime·ifaceE2I2((InterfaceType*)f->fint, ef1, (Iface*)frame))
-						runtime·throw("invalid type conversion in runfinq");
-				}
-				reflect·call(f->fn, frame, framesz, framesz);
-				f->fn = nil;
-				f->arg = nil;
-				f->ot = nil;
-			}
-			fb->cnt = 0;
-			runtime·lock(&finlock);
-			fb->next = finc;
-			finc = fb;
-			runtime·unlock(&finlock);
-		}
-
-		// Zero everything that's dead, to avoid memory leaks.
-		// See comment at top of function.
-		f = nil;
-		fb = nil;
-		next = nil;
-		i = 0;
-		ef = nil;
-		ef1.type = nil;
-		ef1.data = nil;
-		runtime·gc(1);	// trigger another gc to clean up the finalized objects, if possible
-	}
-}
-
-void
-runtime·createfing(void)
-{
-	if(fing != nil)
-		return;
-	// Here we use gclock instead of finlock,
-	// because newproc1 can allocate, which can cause on-demand span sweep,
-	// which can queue finalizers, which would deadlock.
-	runtime·lock(&gclock);
-	if(fing == nil)
-		fing = runtime·newproc1(&runfinqv, nil, 0, 0, runtime·gc);
-	runtime·unlock(&gclock);
-}
-
-G*
-runtime·wakefing(void)
-{
-	G *res;
-
-	res = nil;
-	runtime·lock(&finlock);
-	if(runtime·fingwait && runtime·fingwake) {
-		runtime·fingwait = false;
-		runtime·fingwake = false;
-		res = fing;
-	}
-	runtime·unlock(&finlock);
-	return res;
-}
-
-void
-runtime·marknogc(void *v)
-{
-	uintptr *b, off, shift;
-
-	off = (uintptr*)v - (uintptr*)runtime·mheap.arena_start;  // word offset
-	b = (uintptr*)runtime·mheap.arena_start - off/wordsPerBitmapWord - 1;
-	shift = off % wordsPerBitmapWord;
-	*b = (*b & ~(bitAllocated<<shift)) | bitBlockBoundary<<shift;
-}
-
-void
-runtime·markscan(void *v)
-{
-	uintptr *b, off, shift;
-
-	off = (uintptr*)v - (uintptr*)runtime·mheap.arena_start;  // word offset
-	b = (uintptr*)runtime·mheap.arena_start - off/wordsPerBitmapWord - 1;
-	shift = off % wordsPerBitmapWord;
-	*b |= bitScan<<shift;
-}
-
-// mark the block at v as freed.
-void
-runtime·markfreed(void *v)
-{
-	uintptr *b, off, shift;
-
-	if(0)
-		runtime·printf("markfreed %p\n", v);
-
-	if((byte*)v > (byte*)runtime·mheap.arena_used || (byte*)v < runtime·mheap.arena_start)
-		runtime·throw("markfreed: bad pointer");
-
-	off = (uintptr*)v - (uintptr*)runtime·mheap.arena_start;  // word offset
-	b = (uintptr*)runtime·mheap.arena_start - off/wordsPerBitmapWord - 1;
-	shift = off % wordsPerBitmapWord;
-	*b = (*b & ~(bitMask<<shift)) | (bitAllocated<<shift);
-}
-
-// check that the block at v of size n is marked freed.
-void
-runtime·checkfreed(void *v, uintptr n)
-{
-	uintptr *b, bits, off, shift;
-
-	if(!runtime·checking)
-		return;
-
-	if((byte*)v+n > (byte*)runtime·mheap.arena_used || (byte*)v < runtime·mheap.arena_start)
-		return;	// not allocated, so okay
-
-	off = (uintptr*)v - (uintptr*)runtime·mheap.arena_start;  // word offset
-	b = (uintptr*)runtime·mheap.arena_start - off/wordsPerBitmapWord - 1;
-	shift = off % wordsPerBitmapWord;
-
-	bits = *b>>shift;
-	if((bits & bitAllocated) != 0) {
-		runtime·printf("checkfreed %p+%p: off=%p have=%p\n",
-			v, n, off, bits & bitMask);
-		runtime·throw("checkfreed: not freed");
-	}
-}
-
-// mark the span of memory at v as having n blocks of the given size.
-// if leftover is true, there is left over space at the end of the span.
-void
-runtime·markspan(void *v, uintptr size, uintptr n, bool leftover)
-{
-	uintptr *b, *b0, off, shift, i, x;
-	byte *p;
-
-	if((byte*)v+size*n > (byte*)runtime·mheap.arena_used || (byte*)v < runtime·mheap.arena_start)
-		runtime·throw("markspan: bad pointer");
-
-	if(runtime·checking) {
-		// bits should be all zero at the start
-		off = (byte*)v + size - runtime·mheap.arena_start;
-		b = (uintptr*)(runtime·mheap.arena_start - off/wordsPerBitmapWord);
-		for(i = 0; i < size/PtrSize/wordsPerBitmapWord; i++) {
-			if(b[i] != 0)
-				runtime·throw("markspan: span bits not zero");
-		}
-	}
-
-	p = v;
-	if(leftover)	// mark a boundary just past end of last block too
-		n++;
-
-	b0 = nil;
-	x = 0;
-	for(; n-- > 0; p += size) {
-		// Okay to use non-atomic ops here, because we control
-		// the entire span, and each bitmap word has bits for only
-		// one span, so no other goroutines are changing these
-		// bitmap words.
-		off = (uintptr*)p - (uintptr*)runtime·mheap.arena_start;  // word offset
-		b = (uintptr*)runtime·mheap.arena_start - off/wordsPerBitmapWord - 1;
-		shift = off % wordsPerBitmapWord;
-		if(b0 != b) {
-			if(b0 != nil)
-				*b0 = x;
-			b0 = b;
-			x = 0;
-		}
-		x |= bitAllocated<<shift;
-	}
-	*b0 = x;
-}
-
-// unmark the span of memory at v of length n bytes.
-void
-runtime·unmarkspan(void *v, uintptr n)
-{
-	uintptr *p, *b, off;
-
-	if((byte*)v+n > (byte*)runtime·mheap.arena_used || (byte*)v < runtime·mheap.arena_start)
-		runtime·throw("markspan: bad pointer");
-
-	p = v;
-	off = p - (uintptr*)runtime·mheap.arena_start;  // word offset
-	if(off % wordsPerBitmapWord != 0)
-		runtime·throw("markspan: unaligned pointer");
-	b = (uintptr*)runtime·mheap.arena_start - off/wordsPerBitmapWord - 1;
-	n /= PtrSize;
-	if(n%wordsPerBitmapWord != 0)
-		runtime·throw("unmarkspan: unaligned length");
-	// Okay to use non-atomic ops here, because we control
-	// the entire span, and each bitmap word has bits for only
-	// one span, so no other goroutines are changing these
-	// bitmap words.
-	n /= wordsPerBitmapWord;
-	while(n-- > 0)
-		*b-- = 0;
-}
-
-void
-runtime·MHeap_MapBits(MHeap *h)
-{
-	// Caller has added extra mappings to the arena.
-	// Add extra mappings of bitmap words as needed.
-	// We allocate extra bitmap pieces in chunks of bitmapChunk.
-	enum {
-		bitmapChunk = 8192
-	};
-	uintptr n;
-
-	n = (h->arena_used - h->arena_start) / wordsPerBitmapWord;
-	n = ROUND(n, bitmapChunk);
-	n = ROUND(n, PhysPageSize);
-	if(h->bitmap_mapped >= n)
-		return;
-
-	runtime·SysMap(h->arena_start - n, n - h->bitmap_mapped, h->arena_reserved, &mstats.gc_sys);
-	h->bitmap_mapped = n;
-}
diff --git a/src/pkg/runtime/mgc0.go b/src/pkg/runtime/mgc0.go
deleted file mode 100644
index 624485d..0000000
--- a/src/pkg/runtime/mgc0.go
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package runtime
-
-// Called from C. Returns the Go type *m.
-func gc_m_ptr(ret *interface{}) {
-	*ret = (*m)(nil)
-}
-
-// Called from C. Returns the Go type *g.
-func gc_g_ptr(ret *interface{}) {
-	*ret = (*g)(nil)
-}
-
-// Called from C. Returns the Go type *itab.
-func gc_itab_ptr(ret *interface{}) {
-	*ret = (*itab)(nil)
-}
-
-func timenow() (sec int64, nsec int32)
-
-func gc_unixnanotime(now *int64) {
-	sec, nsec := timenow()
-	*now = sec*1e9 + int64(nsec)
-}
diff --git a/src/pkg/runtime/mgc0.h b/src/pkg/runtime/mgc0.h
deleted file mode 100644
index 16000d1..0000000
--- a/src/pkg/runtime/mgc0.h
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Garbage collector (GC)
-
-// GC instruction opcodes.
-//
-// The opcode of an instruction is followed by zero or more
-// arguments to the instruction.
-//
-// Meaning of arguments:
-//   off      Offset (in bytes) from the start of the current object
-//   objgc    Pointer to GC info of an object
-//   objgcrel Offset to GC info of an object
-//   len      Length of an array
-//   elemsize Size (in bytes) of an element
-//   size     Size (in bytes)
-//
-// NOTE: There is a copy of these in ../reflect/type.go.
-// They must be kept in sync.
-enum {
-	GC_END,         // End of object, loop or subroutine. Args: none
-	GC_PTR,         // A typed pointer. Args: (off, objgc)
-	GC_APTR,        // Pointer to an arbitrary object. Args: (off)
-	GC_ARRAY_START, // Start an array with a fixed length. Args: (off, len, elemsize)
-	GC_ARRAY_NEXT,  // The next element of an array. Args: none
-	GC_CALL,        // Call a subroutine. Args: (off, objgcrel)
-	GC_CHAN_PTR,    // Go channel. Args: (off, ChanType*)
-	GC_STRING,      // Go string. Args: (off)
-	GC_EFACE,       // interface{}. Args: (off)
-	GC_IFACE,       // interface{...}. Args: (off)
-	GC_SLICE,       // Go slice. Args: (off, objgc)
-	GC_REGION,      // A region/part of the current object. Args: (off, size, objgc)
-
-	GC_NUM_INSTR,   // Number of instruction opcodes
-};
-
-enum {
-	// Size of GC's fixed stack.
-	//
-	// The current GC implementation permits:
-	//  - at most 1 stack allocation because of GC_CALL
-	//  - at most GC_STACK_CAPACITY allocations because of GC_ARRAY_START
-	GC_STACK_CAPACITY = 8,	
-};
-
-enum {
-	ScanStackByFrames = 1,
-	IgnorePreciseGC = 0,
-
-	// Four bits per word (see #defines below).
-	wordsPerBitmapWord = sizeof(void*)*8/4,
-	bitShift = sizeof(void*)*8/4,
-};
-
-// Bits in per-word bitmap.
-// #defines because enum might not be able to hold the values.
-//
-// Each word in the bitmap describes wordsPerBitmapWord words
-// of heap memory.  There are 4 bitmap bits dedicated to each heap word,
-// so on a 64-bit system there is one bitmap word per 16 heap words.
-// The bits in the word are packed together by type first, then by
-// heap location, so each 64-bit bitmap word consists of, from top to bottom,
-// the 16 bitMarked bits for the corresponding heap words,
-// then the 16 bitScan/bitBlockBoundary bits, then the 16 bitAllocated bits.
-// This layout makes it easier to iterate over the bits of a given type.
-//
-// The bitmap starts at mheap.arena_start and extends *backward* from
-// there.  On a 64-bit system the off'th word in the arena is tracked by
-// the off/16+1'th word before mheap.arena_start.  (On a 32-bit system,
-// the only difference is that the divisor is 8.)
-//
-// To pull out the bits corresponding to a given pointer p, we use:
-//
-//	off = p - (uintptr*)mheap.arena_start;  // word offset
-//	b = (uintptr*)mheap.arena_start - off/wordsPerBitmapWord - 1;
-//	shift = off % wordsPerBitmapWord
-//	bits = *b >> shift;
-//	/* then test bits & bitAllocated, bits & bitMarked, etc. */
-//
-#define bitAllocated		((uintptr)1<<(bitShift*0))	/* block start; eligible for garbage collection */
-#define bitScan			((uintptr)1<<(bitShift*1))	/* when bitAllocated is set */
-#define bitMarked		((uintptr)1<<(bitShift*2))	/* when bitAllocated is set */
-#define bitBlockBoundary	((uintptr)1<<(bitShift*1))	/* when bitAllocated is NOT set - mark for FlagNoGC objects */
-
-#define bitMask (bitAllocated | bitScan | bitMarked)
diff --git a/src/pkg/runtime/mheap.c b/src/pkg/runtime/mheap.c
deleted file mode 100644
index 7e83eb2..0000000
--- a/src/pkg/runtime/mheap.c
+++ /dev/null
@@ -1,932 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Page heap.
-//
-// See malloc.h for overview.
-//
-// When a MSpan is in the heap free list, state == MSpanFree
-// and heapmap(s->start) == span, heapmap(s->start+s->npages-1) == span.
-//
-// When a MSpan is allocated, state == MSpanInUse
-// and heapmap(i) == span for all s->start <= i < s->start+s->npages.
-
-#include "runtime.h"
-#include "arch_GOARCH.h"
-#include "malloc.h"
-
-static MSpan *MHeap_AllocLocked(MHeap*, uintptr, int32);
-static bool MHeap_Grow(MHeap*, uintptr);
-static void MHeap_FreeLocked(MHeap*, MSpan*);
-static MSpan *MHeap_AllocLarge(MHeap*, uintptr);
-static MSpan *BestFit(MSpan*, uintptr, MSpan*);
-
-static void
-RecordSpan(void *vh, byte *p)
-{
-	MHeap *h;
-	MSpan *s;
-	MSpan **all;
-	uint32 cap;
-
-	h = vh;
-	s = (MSpan*)p;
-	if(h->nspan >= h->nspancap) {
-		cap = 64*1024/sizeof(all[0]);
-		if(cap < h->nspancap*3/2)
-			cap = h->nspancap*3/2;
-		all = (MSpan**)runtime·SysAlloc(cap*sizeof(all[0]), &mstats.other_sys);
-		if(all == nil)
-			runtime·throw("runtime: cannot allocate memory");
-		if(h->allspans) {
-			runtime·memmove(all, h->allspans, h->nspancap*sizeof(all[0]));
-			// Don't free the old array if it's referenced by sweep.
-			// See the comment in mgc0.c.
-			if(h->allspans != runtime·mheap.sweepspans)
-				runtime·SysFree(h->allspans, h->nspancap*sizeof(all[0]), &mstats.other_sys);
-		}
-		h->allspans = all;
-		h->nspancap = cap;
-	}
-	h->allspans[h->nspan++] = s;
-}
-
-// Initialize the heap; fetch memory using alloc.
-void
-runtime·MHeap_Init(MHeap *h)
-{
-	uint32 i;
-
-	runtime·FixAlloc_Init(&h->spanalloc, sizeof(MSpan), RecordSpan, h, &mstats.mspan_sys);
-	runtime·FixAlloc_Init(&h->cachealloc, sizeof(MCache), nil, nil, &mstats.mcache_sys);
-	runtime·FixAlloc_Init(&h->specialfinalizeralloc, sizeof(SpecialFinalizer), nil, nil, &mstats.other_sys);
-	runtime·FixAlloc_Init(&h->specialprofilealloc, sizeof(SpecialProfile), nil, nil, &mstats.other_sys);
-	// h->mapcache needs no init
-	for(i=0; i<nelem(h->free); i++) {
-		runtime·MSpanList_Init(&h->free[i]);
-		runtime·MSpanList_Init(&h->busy[i]);
-	}
-	runtime·MSpanList_Init(&h->freelarge);
-	runtime·MSpanList_Init(&h->busylarge);
-	for(i=0; i<nelem(h->central); i++)
-		runtime·MCentral_Init(&h->central[i], i);
-}
-
-void
-runtime·MHeap_MapSpans(MHeap *h)
-{
-	uintptr n;
-
-	// Map spans array, PageSize at a time.
-	n = (uintptr)h->arena_used;
-	n -= (uintptr)h->arena_start;
-	n = n / PageSize * sizeof(h->spans[0]);
-	n = ROUND(n, PhysPageSize);
-	if(h->spans_mapped >= n)
-		return;
-	runtime·SysMap((byte*)h->spans + h->spans_mapped, n - h->spans_mapped, h->arena_reserved, &mstats.other_sys);
-	h->spans_mapped = n;
-}
-
-// Sweeps spans in list until reclaims at least npages into heap.
-// Returns the actual number of pages reclaimed.
-static uintptr
-MHeap_ReclaimList(MHeap *h, MSpan *list, uintptr npages)
-{
-	MSpan *s;
-	uintptr n;
-	uint32 sg;
-
-	n = 0;
-	sg = runtime·mheap.sweepgen;
-retry:
-	for(s = list->next; s != list; s = s->next) {
-		if(s->sweepgen == sg-2 && runtime·cas(&s->sweepgen, sg-2, sg-1)) {
-			runtime·MSpanList_Remove(s);
-			// swept spans are at the end of the list
-			runtime·MSpanList_InsertBack(list, s);
-			runtime·unlock(h);
-			n += runtime·MSpan_Sweep(s);
-			runtime·lock(h);
-			if(n >= npages)
-				return n;
-			// the span could have been moved elsewhere
-			goto retry;
-		}
-		if(s->sweepgen == sg-1) {
-			// the span is being sweept by background sweeper, skip
-			continue;
-		}
-		// already swept empty span,
-		// all subsequent ones must also be either swept or in process of sweeping
-		break;
-	}
-	return n;
-}
-
-// Sweeps and reclaims at least npage pages into heap.
-// Called before allocating npage pages.
-static void
-MHeap_Reclaim(MHeap *h, uintptr npage)
-{
-	uintptr reclaimed, n;
-
-	// First try to sweep busy spans with large objects of size >= npage,
-	// this has good chances of reclaiming the necessary space.
-	for(n=npage; n < nelem(h->busy); n++) {
-		if(MHeap_ReclaimList(h, &h->busy[n], npage))
-			return;  // Bingo!
-	}
-
-	// Then -- even larger objects.
-	if(MHeap_ReclaimList(h, &h->busylarge, npage))
-		return;  // Bingo!
-
-	// Now try smaller objects.
-	// One such object is not enough, so we need to reclaim several of them.
-	reclaimed = 0;
-	for(n=0; n < npage && n < nelem(h->busy); n++) {
-		reclaimed += MHeap_ReclaimList(h, &h->busy[n], npage-reclaimed);
-		if(reclaimed >= npage)
-			return;
-	}
-
-	// Now sweep everything that is not yet swept.
-	runtime·unlock(h);
-	for(;;) {
-		n = runtime·sweepone();
-		if(n == -1)  // all spans are swept
-			break;
-		reclaimed += n;
-		if(reclaimed >= npage)
-			break;
-	}
-	runtime·lock(h);
-}
-
-// Allocate a new span of npage pages from the heap
-// and record its size class in the HeapMap and HeapMapCache.
-MSpan*
-runtime·MHeap_Alloc(MHeap *h, uintptr npage, int32 sizeclass, bool large, bool needzero)
-{
-	MSpan *s;
-
-	runtime·lock(h);
-	mstats.heap_alloc += m->mcache->local_cachealloc;
-	m->mcache->local_cachealloc = 0;
-	s = MHeap_AllocLocked(h, npage, sizeclass);
-	if(s != nil) {
-		mstats.heap_inuse += npage<<PageShift;
-		if(large) {
-			mstats.heap_objects++;
-			mstats.heap_alloc += npage<<PageShift;
-			// Swept spans are at the end of lists.
-			if(s->npages < nelem(h->free))
-				runtime·MSpanList_InsertBack(&h->busy[s->npages], s);
-			else
-				runtime·MSpanList_InsertBack(&h->busylarge, s);
-		}
-	}
-	runtime·unlock(h);
-	if(s != nil) {
-		if(needzero && s->needzero)
-			runtime·memclr((byte*)(s->start<<PageShift), s->npages<<PageShift);
-		s->needzero = 0;
-	}
-	return s;
-}
-
-static MSpan*
-MHeap_AllocLocked(MHeap *h, uintptr npage, int32 sizeclass)
-{
-	uintptr n;
-	MSpan *s, *t;
-	PageID p;
-
-	// To prevent excessive heap growth, before allocating n pages
-	// we need to sweep and reclaim at least n pages.
-	if(!h->sweepdone)
-		MHeap_Reclaim(h, npage);
-
-	// Try in fixed-size lists up to max.
-	for(n=npage; n < nelem(h->free); n++) {
-		if(!runtime·MSpanList_IsEmpty(&h->free[n])) {
-			s = h->free[n].next;
-			goto HaveSpan;
-		}
-	}
-
-	// Best fit in list of large spans.
-	if((s = MHeap_AllocLarge(h, npage)) == nil) {
-		if(!MHeap_Grow(h, npage))
-			return nil;
-		if((s = MHeap_AllocLarge(h, npage)) == nil)
-			return nil;
-	}
-
-HaveSpan:
-	// Mark span in use.
-	if(s->state != MSpanFree)
-		runtime·throw("MHeap_AllocLocked - MSpan not free");
-	if(s->npages < npage)
-		runtime·throw("MHeap_AllocLocked - bad npages");
-	runtime·MSpanList_Remove(s);
-	runtime·atomicstore(&s->sweepgen, h->sweepgen);
-	s->state = MSpanInUse;
-	mstats.heap_idle -= s->npages<<PageShift;
-	mstats.heap_released -= s->npreleased<<PageShift;
-	if(s->npreleased > 0)
-		runtime·SysUsed((void*)(s->start<<PageShift), s->npages<<PageShift);
-	s->npreleased = 0;
-
-	if(s->npages > npage) {
-		// Trim extra and put it back in the heap.
-		t = runtime·FixAlloc_Alloc(&h->spanalloc);
-		runtime·MSpan_Init(t, s->start + npage, s->npages - npage);
-		s->npages = npage;
-		p = t->start;
-		p -= ((uintptr)h->arena_start>>PageShift);
-		if(p > 0)
-			h->spans[p-1] = s;
-		h->spans[p] = t;
-		h->spans[p+t->npages-1] = t;
-		t->needzero = s->needzero;
-		runtime·atomicstore(&t->sweepgen, h->sweepgen);
-		t->state = MSpanInUse;
-		MHeap_FreeLocked(h, t);
-		t->unusedsince = s->unusedsince; // preserve age
-	}
-	s->unusedsince = 0;
-
-	// Record span info, because gc needs to be
-	// able to map interior pointer to containing span.
-	s->sizeclass = sizeclass;
-	s->elemsize = (sizeclass==0 ? s->npages<<PageShift : runtime·class_to_size[sizeclass]);
-	s->types.compression = MTypes_Empty;
-	p = s->start;
-	p -= ((uintptr)h->arena_start>>PageShift);
-	for(n=0; n<npage; n++)
-		h->spans[p+n] = s;
-	return s;
-}
-
-// Allocate a span of exactly npage pages from the list of large spans.
-static MSpan*
-MHeap_AllocLarge(MHeap *h, uintptr npage)
-{
-	return BestFit(&h->freelarge, npage, nil);
-}
-
-// Search list for smallest span with >= npage pages.
-// If there are multiple smallest spans, take the one
-// with the earliest starting address.
-static MSpan*
-BestFit(MSpan *list, uintptr npage, MSpan *best)
-{
-	MSpan *s;
-
-	for(s=list->next; s != list; s=s->next) {
-		if(s->npages < npage)
-			continue;
-		if(best == nil
-		|| s->npages < best->npages
-		|| (s->npages == best->npages && s->start < best->start))
-			best = s;
-	}
-	return best;
-}
-
-// Try to add at least npage pages of memory to the heap,
-// returning whether it worked.
-static bool
-MHeap_Grow(MHeap *h, uintptr npage)
-{
-	uintptr ask;
-	void *v;
-	MSpan *s;
-	PageID p;
-
-	// Ask for a big chunk, to reduce the number of mappings
-	// the operating system needs to track; also amortizes
-	// the overhead of an operating system mapping.
-	// Allocate a multiple of 64kB (16 pages).
-	npage = (npage+15)&~15;
-	ask = npage<<PageShift;
-	if(ask < HeapAllocChunk)
-		ask = HeapAllocChunk;
-
-	v = runtime·MHeap_SysAlloc(h, ask);
-	if(v == nil) {
-		if(ask > (npage<<PageShift)) {
-			ask = npage<<PageShift;
-			v = runtime·MHeap_SysAlloc(h, ask);
-		}
-		if(v == nil) {
-			runtime·printf("runtime: out of memory: cannot allocate %D-byte block (%D in use)\n", (uint64)ask, mstats.heap_sys);
-			return false;
-		}
-	}
-
-	// Create a fake "in use" span and free it, so that the
-	// right coalescing happens.
-	s = runtime·FixAlloc_Alloc(&h->spanalloc);
-	runtime·MSpan_Init(s, (uintptr)v>>PageShift, ask>>PageShift);
-	p = s->start;
-	p -= ((uintptr)h->arena_start>>PageShift);
-	h->spans[p] = s;
-	h->spans[p + s->npages - 1] = s;
-	runtime·atomicstore(&s->sweepgen, h->sweepgen);
-	s->state = MSpanInUse;
-	MHeap_FreeLocked(h, s);
-	return true;
-}
-
-// Look up the span at the given address.
-// Address is guaranteed to be in map
-// and is guaranteed to be start or end of span.
-MSpan*
-runtime·MHeap_Lookup(MHeap *h, void *v)
-{
-	uintptr p;
-	
-	p = (uintptr)v;
-	p -= (uintptr)h->arena_start;
-	return h->spans[p >> PageShift];
-}
-
-// Look up the span at the given address.
-// Address is *not* guaranteed to be in map
-// and may be anywhere in the span.
-// Map entries for the middle of a span are only
-// valid for allocated spans.  Free spans may have
-// other garbage in their middles, so we have to
-// check for that.
-MSpan*
-runtime·MHeap_LookupMaybe(MHeap *h, void *v)
-{
-	MSpan *s;
-	PageID p, q;
-
-	if((byte*)v < h->arena_start || (byte*)v >= h->arena_used)
-		return nil;
-	p = (uintptr)v>>PageShift;
-	q = p;
-	q -= (uintptr)h->arena_start >> PageShift;
-	s = h->spans[q];
-	if(s == nil || p < s->start || v >= s->limit || s->state != MSpanInUse)
-		return nil;
-	return s;
-}
-
-// Free the span back into the heap.
-void
-runtime·MHeap_Free(MHeap *h, MSpan *s, int32 acct)
-{
-	runtime·lock(h);
-	mstats.heap_alloc += m->mcache->local_cachealloc;
-	m->mcache->local_cachealloc = 0;
-	mstats.heap_inuse -= s->npages<<PageShift;
-	if(acct) {
-		mstats.heap_alloc -= s->npages<<PageShift;
-		mstats.heap_objects--;
-	}
-	MHeap_FreeLocked(h, s);
-	runtime·unlock(h);
-}
-
-static void
-MHeap_FreeLocked(MHeap *h, MSpan *s)
-{
-	MSpan *t;
-	PageID p;
-
-	s->types.compression = MTypes_Empty;
-
-	if(s->state != MSpanInUse || s->ref != 0 || s->sweepgen != h->sweepgen) {
-		runtime·printf("MHeap_FreeLocked - span %p ptr %p state %d ref %d sweepgen %d/%d\n",
-			s, s->start<<PageShift, s->state, s->ref, s->sweepgen, h->sweepgen);
-		runtime·throw("MHeap_FreeLocked - invalid free");
-	}
-	mstats.heap_idle += s->npages<<PageShift;
-	s->state = MSpanFree;
-	runtime·MSpanList_Remove(s);
-	// Stamp newly unused spans. The scavenger will use that
-	// info to potentially give back some pages to the OS.
-	s->unusedsince = runtime·nanotime();
-	s->npreleased = 0;
-
-	// Coalesce with earlier, later spans.
-	p = s->start;
-	p -= (uintptr)h->arena_start >> PageShift;
-	if(p > 0 && (t = h->spans[p-1]) != nil && t->state != MSpanInUse) {
-		s->start = t->start;
-		s->npages += t->npages;
-		s->npreleased = t->npreleased; // absorb released pages
-		s->needzero |= t->needzero;
-		p -= t->npages;
-		h->spans[p] = s;
-		runtime·MSpanList_Remove(t);
-		t->state = MSpanDead;
-		runtime·FixAlloc_Free(&h->spanalloc, t);
-	}
-	if((p+s->npages)*sizeof(h->spans[0]) < h->spans_mapped && (t = h->spans[p+s->npages]) != nil && t->state != MSpanInUse) {
-		s->npages += t->npages;
-		s->npreleased += t->npreleased;
-		s->needzero |= t->needzero;
-		h->spans[p + s->npages - 1] = s;
-		runtime·MSpanList_Remove(t);
-		t->state = MSpanDead;
-		runtime·FixAlloc_Free(&h->spanalloc, t);
-	}
-
-	// Insert s into appropriate list.
-	if(s->npages < nelem(h->free))
-		runtime·MSpanList_Insert(&h->free[s->npages], s);
-	else
-		runtime·MSpanList_Insert(&h->freelarge, s);
-}
-
-static void
-forcegchelper(Note *note)
-{
-	runtime·gc(1);
-	runtime·notewakeup(note);
-}
-
-static uintptr
-scavengelist(MSpan *list, uint64 now, uint64 limit)
-{
-	uintptr released, sumreleased;
-	MSpan *s;
-
-	if(runtime·MSpanList_IsEmpty(list))
-		return 0;
-
-	sumreleased = 0;
-	for(s=list->next; s != list; s=s->next) {
-		if((now - s->unusedsince) > limit && s->npreleased != s->npages) {
-			released = (s->npages - s->npreleased) << PageShift;
-			mstats.heap_released += released;
-			sumreleased += released;
-			s->npreleased = s->npages;
-			runtime·SysUnused((void*)(s->start << PageShift), s->npages << PageShift);
-		}
-	}
-	return sumreleased;
-}
-
-static void
-scavenge(int32 k, uint64 now, uint64 limit)
-{
-	uint32 i;
-	uintptr sumreleased;
-	MHeap *h;
-	
-	h = &runtime·mheap;
-	sumreleased = 0;
-	for(i=0; i < nelem(h->free); i++)
-		sumreleased += scavengelist(&h->free[i], now, limit);
-	sumreleased += scavengelist(&h->freelarge, now, limit);
-
-	if(runtime·debug.gctrace > 0) {
-		if(sumreleased > 0)
-			runtime·printf("scvg%d: %D MB released\n", k, (uint64)sumreleased>>20);
-		runtime·printf("scvg%d: inuse: %D, idle: %D, sys: %D, released: %D, consumed: %D (MB)\n",
-			k, mstats.heap_inuse>>20, mstats.heap_idle>>20, mstats.heap_sys>>20,
-			mstats.heap_released>>20, (mstats.heap_sys - mstats.heap_released)>>20);
-	}
-}
-
-static FuncVal forcegchelperv = {(void(*)(void))forcegchelper};
-
-// Release (part of) unused memory to OS.
-// Goroutine created at startup.
-// Loop forever.
-void
-runtime·MHeap_Scavenger(void)
-{
-	MHeap *h;
-	uint64 tick, now, forcegc, limit;
-	int64 unixnow;
-	int32 k;
-	Note note, *notep;
-
-	g->issystem = true;
-	g->isbackground = true;
-
-	// If we go two minutes without a garbage collection, force one to run.
-	forcegc = 2*60*1e9;
-	// If a span goes unused for 5 minutes after a garbage collection,
-	// we hand it back to the operating system.
-	limit = 5*60*1e9;
-	// Make wake-up period small enough for the sampling to be correct.
-	if(forcegc < limit)
-		tick = forcegc/2;
-	else
-		tick = limit/2;
-
-	h = &runtime·mheap;
-	for(k=0;; k++) {
-		runtime·noteclear(&note);
-		runtime·notetsleepg(&note, tick);
-
-		runtime·lock(h);
-		unixnow = runtime·unixnanotime();
-		if(unixnow - mstats.last_gc > forcegc) {
-			runtime·unlock(h);
-			// The scavenger can not block other goroutines,
-			// otherwise deadlock detector can fire spuriously.
-			// GC blocks other goroutines via the runtime·worldsema.
-			runtime·noteclear(&note);
-			notep = ¬e;
-			runtime·newproc1(&forcegchelperv, (byte*)&notep, sizeof(notep), 0, runtime·MHeap_Scavenger);
-			runtime·notetsleepg(&note, -1);
-			if(runtime·debug.gctrace > 0)
-				runtime·printf("scvg%d: GC forced\n", k);
-			runtime·lock(h);
-		}
-		now = runtime·nanotime();
-		scavenge(k, now, limit);
-		runtime·unlock(h);
-	}
-}
-
-void
-runtime∕debug·freeOSMemory(void)
-{
-	runtime·gc(2);  // force GC and do eager sweep
-	runtime·lock(&runtime·mheap);
-	scavenge(-1, ~(uintptr)0, 0);
-	runtime·unlock(&runtime·mheap);
-}
-
-// Initialize a new span with the given start and npages.
-void
-runtime·MSpan_Init(MSpan *span, PageID start, uintptr npages)
-{
-	span->next = nil;
-	span->prev = nil;
-	span->start = start;
-	span->npages = npages;
-	span->freelist = nil;
-	span->ref = 0;
-	span->sizeclass = 0;
-	span->incache = false;
-	span->elemsize = 0;
-	span->state = MSpanDead;
-	span->unusedsince = 0;
-	span->npreleased = 0;
-	span->types.compression = MTypes_Empty;
-	span->specialLock.key = 0;
-	span->specials = nil;
-	span->needzero = 0;
-	span->freebuf = nil;
-}
-
-// Initialize an empty doubly-linked list.
-void
-runtime·MSpanList_Init(MSpan *list)
-{
-	list->state = MSpanListHead;
-	list->next = list;
-	list->prev = list;
-}
-
-void
-runtime·MSpanList_Remove(MSpan *span)
-{
-	if(span->prev == nil && span->next == nil)
-		return;
-	span->prev->next = span->next;
-	span->next->prev = span->prev;
-	span->prev = nil;
-	span->next = nil;
-}
-
-bool
-runtime·MSpanList_IsEmpty(MSpan *list)
-{
-	return list->next == list;
-}
-
-void
-runtime·MSpanList_Insert(MSpan *list, MSpan *span)
-{
-	if(span->next != nil || span->prev != nil) {
-		runtime·printf("failed MSpanList_Insert %p %p %p\n", span, span->next, span->prev);
-		runtime·throw("MSpanList_Insert");
-	}
-	span->next = list->next;
-	span->prev = list;
-	span->next->prev = span;
-	span->prev->next = span;
-}
-
-void
-runtime·MSpanList_InsertBack(MSpan *list, MSpan *span)
-{
-	if(span->next != nil || span->prev != nil) {
-		runtime·printf("failed MSpanList_Insert %p %p %p\n", span, span->next, span->prev);
-		runtime·throw("MSpanList_Insert");
-	}
-	span->next = list;
-	span->prev = list->prev;
-	span->next->prev = span;
-	span->prev->next = span;
-}
-
-// Adds the special record s to the list of special records for
-// the object p.  All fields of s should be filled in except for
-// offset & next, which this routine will fill in.
-// Returns true if the special was successfully added, false otherwise.
-// (The add will fail only if a record with the same p and s->kind
-//  already exists.)
-static bool
-addspecial(void *p, Special *s)
-{
-	MSpan *span;
-	Special **t, *x;
-	uintptr offset;
-	byte kind;
-
-	span = runtime·MHeap_LookupMaybe(&runtime·mheap, p);
-	if(span == nil)
-		runtime·throw("addspecial on invalid pointer");
-
-	// Ensure that the span is swept.
-	// GC accesses specials list w/o locks. And it's just much safer.
-	m->locks++;
-	runtime·MSpan_EnsureSwept(span);
-
-	offset = (uintptr)p - (span->start << PageShift);
-	kind = s->kind;
-
-	runtime·lock(&span->specialLock);
-
-	// Find splice point, check for existing record.
-	t = &span->specials;
-	while((x = *t) != nil) {
-		if(offset == x->offset && kind == x->kind) {
-			runtime·unlock(&span->specialLock);
-			m->locks--;
-			return false; // already exists
-		}
-		if(offset < x->offset || (offset == x->offset && kind < x->kind))
-			break;
-		t = &x->next;
-	}
-	// Splice in record, fill in offset.
-	s->offset = offset;
-	s->next = x;
-	*t = s;
-	runtime·unlock(&span->specialLock);
-	m->locks--;
-	return true;
-}
-
-// Removes the Special record of the given kind for the object p.
-// Returns the record if the record existed, nil otherwise.
-// The caller must FixAlloc_Free the result.
-static Special*
-removespecial(void *p, byte kind)
-{
-	MSpan *span;
-	Special *s, **t;
-	uintptr offset;
-
-	span = runtime·MHeap_LookupMaybe(&runtime·mheap, p);
-	if(span == nil)
-		runtime·throw("removespecial on invalid pointer");
-
-	// Ensure that the span is swept.
-	// GC accesses specials list w/o locks. And it's just much safer.
-	m->locks++;
-	runtime·MSpan_EnsureSwept(span);
-
-	offset = (uintptr)p - (span->start << PageShift);
-
-	runtime·lock(&span->specialLock);
-	t = &span->specials;
-	while((s = *t) != nil) {
-		// This function is used for finalizers only, so we don't check for
-		// "interior" specials (p must be exactly equal to s->offset).
-		if(offset == s->offset && kind == s->kind) {
-			*t = s->next;
-			runtime·unlock(&span->specialLock);
-			m->locks--;
-			return s;
-		}
-		t = &s->next;
-	}
-	runtime·unlock(&span->specialLock);
-	m->locks--;
-	return nil;
-}
-
-// Adds a finalizer to the object p.  Returns true if it succeeded.
-bool
-runtime·addfinalizer(void *p, FuncVal *f, uintptr nret, Type *fint, PtrType *ot)
-{
-	SpecialFinalizer *s;
-
-	runtime·lock(&runtime·mheap.speciallock);
-	s = runtime·FixAlloc_Alloc(&runtime·mheap.specialfinalizeralloc);
-	runtime·unlock(&runtime·mheap.speciallock);
-	s->kind = KindSpecialFinalizer;
-	s->fn = f;
-	s->nret = nret;
-	s->fint = fint;
-	s->ot = ot;
-	if(addspecial(p, s))
-		return true;
-
-	// There was an old finalizer
-	runtime·lock(&runtime·mheap.speciallock);
-	runtime·FixAlloc_Free(&runtime·mheap.specialfinalizeralloc, s);
-	runtime·unlock(&runtime·mheap.speciallock);
-	return false;
-}
-
-// Removes the finalizer (if any) from the object p.
-void
-runtime·removefinalizer(void *p)
-{
-	SpecialFinalizer *s;
-
-	s = (SpecialFinalizer*)removespecial(p, KindSpecialFinalizer);
-	if(s == nil)
-		return; // there wasn't a finalizer to remove
-	runtime·lock(&runtime·mheap.speciallock);
-	runtime·FixAlloc_Free(&runtime·mheap.specialfinalizeralloc, s);
-	runtime·unlock(&runtime·mheap.speciallock);
-}
-
-// Set the heap profile bucket associated with addr to b.
-void
-runtime·setprofilebucket(void *p, Bucket *b)
-{
-	SpecialProfile *s;
-
-	runtime·lock(&runtime·mheap.speciallock);
-	s = runtime·FixAlloc_Alloc(&runtime·mheap.specialprofilealloc);
-	runtime·unlock(&runtime·mheap.speciallock);
-	s->kind = KindSpecialProfile;
-	s->b = b;
-	if(!addspecial(p, s))
-		runtime·throw("setprofilebucket: profile already set");
-}
-
-// Do whatever cleanup needs to be done to deallocate s.  It has
-// already been unlinked from the MSpan specials list.
-// Returns true if we should keep working on deallocating p.
-bool
-runtime·freespecial(Special *s, void *p, uintptr size, bool freed)
-{
-	SpecialFinalizer *sf;
-	SpecialProfile *sp;
-
-	switch(s->kind) {
-	case KindSpecialFinalizer:
-		sf = (SpecialFinalizer*)s;
-		runtime·queuefinalizer(p, sf->fn, sf->nret, sf->fint, sf->ot);
-		runtime·lock(&runtime·mheap.speciallock);
-		runtime·FixAlloc_Free(&runtime·mheap.specialfinalizeralloc, sf);
-		runtime·unlock(&runtime·mheap.speciallock);
-		return false; // don't free p until finalizer is done
-	case KindSpecialProfile:
-		sp = (SpecialProfile*)s;
-		runtime·MProf_Free(sp->b, size, freed);
-		runtime·lock(&runtime·mheap.speciallock);
-		runtime·FixAlloc_Free(&runtime·mheap.specialprofilealloc, sp);
-		runtime·unlock(&runtime·mheap.speciallock);
-		return true;
-	default:
-		runtime·throw("bad special kind");
-		return true;
-	}
-}
-
-// Free all special records for p.
-void
-runtime·freeallspecials(MSpan *span, void *p, uintptr size)
-{
-	Special *s, **t, *list;
-	uintptr offset;
-
-	if(span->sweepgen != runtime·mheap.sweepgen)
-		runtime·throw("runtime: freeallspecials: unswept span");
-	// first, collect all specials into the list; then, free them
-	// this is required to not cause deadlock between span->specialLock and proflock
-	list = nil;
-	offset = (uintptr)p - (span->start << PageShift);
-	runtime·lock(&span->specialLock);
-	t = &span->specials;
-	while((s = *t) != nil) {
-		if(offset + size <= s->offset)
-			break;
-		if(offset <= s->offset) {
-			*t = s->next;
-			s->next = list;
-			list = s;
-		} else
-			t = &s->next;
-	}
-	runtime·unlock(&span->specialLock);
-
-	while(list != nil) {
-		s = list;
-		list = s->next;
-		if(!runtime·freespecial(s, p, size, true))
-			runtime·throw("can't explicitly free an object with a finalizer");
-	}
-}
-
-// Split an allocated span into two equal parts.
-void
-runtime·MHeap_SplitSpan(MHeap *h, MSpan *s)
-{
-	MSpan *t;
-	MCentral *c;
-	uintptr i;
-	uintptr npages;
-	PageID p;
-
-	if(s->state != MSpanInUse)
-		runtime·throw("MHeap_SplitSpan on a free span");
-	if(s->sizeclass != 0 && s->ref != 1)
-		runtime·throw("MHeap_SplitSpan doesn't have an allocated object");
-	npages = s->npages;
-
-	// remove the span from whatever list it is in now
-	if(s->sizeclass > 0) {
-		// must be in h->central[x].empty
-		c = &h->central[s->sizeclass];
-		runtime·lock(c);
-		runtime·MSpanList_Remove(s);
-		runtime·unlock(c);
-		runtime·lock(h);
-	} else {
-		// must be in h->busy/busylarge
-		runtime·lock(h);
-		runtime·MSpanList_Remove(s);
-	}
-	// heap is locked now
-
-	if(npages == 1) {
-		// convert span of 1 PageSize object to a span of 2 PageSize/2 objects.
-		s->ref = 2;
-		s->sizeclass = runtime·SizeToClass(PageSize/2);
-		s->elemsize = PageSize/2;
-	} else {
-		// convert span of n>1 pages into two spans of n/2 pages each.
-		if((s->npages & 1) != 0)
-			runtime·throw("MHeap_SplitSpan on an odd size span");
-
-		// compute position in h->spans
-		p = s->start;
-		p -= (uintptr)h->arena_start >> PageShift;
-
-		// Allocate a new span for the first half.
-		t = runtime·FixAlloc_Alloc(&h->spanalloc);
-		runtime·MSpan_Init(t, s->start, npages/2);
-		t->limit = (byte*)((t->start + npages/2) << PageShift);
-		t->state = MSpanInUse;
-		t->elemsize = npages << (PageShift - 1);
-		t->sweepgen = s->sweepgen;
-		if(t->elemsize <= MaxSmallSize) {
-			t->sizeclass = runtime·SizeToClass(t->elemsize);
-			t->ref = 1;
-		}
-
-		// the old span holds the second half.
-		s->start += npages/2;
-		s->npages = npages/2;
-		s->elemsize = npages << (PageShift - 1);
-		if(s->elemsize <= MaxSmallSize) {
-			s->sizeclass = runtime·SizeToClass(s->elemsize);
-			s->ref = 1;
-		}
-
-		// update span lookup table
-		for(i = p; i < p + npages/2; i++)
-			h->spans[i] = t;
-	}
-
-	// place the span into a new list
-	if(s->sizeclass > 0) {
-		runtime·unlock(h);
-		c = &h->central[s->sizeclass];
-		runtime·lock(c);
-		// swept spans are at the end of the list
-		runtime·MSpanList_InsertBack(&c->empty, s);
-		runtime·unlock(c);
-	} else {
-		// Swept spans are at the end of lists.
-		if(s->npages < nelem(h->free))
-			runtime·MSpanList_InsertBack(&h->busy[s->npages], s);
-		else
-			runtime·MSpanList_InsertBack(&h->busylarge, s);
-		runtime·unlock(h);
-	}
-}
diff --git a/src/pkg/runtime/mprof.goc b/src/pkg/runtime/mprof.goc
deleted file mode 100644
index 9c23a16..0000000
--- a/src/pkg/runtime/mprof.goc
+++ /dev/null
@@ -1,527 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Malloc profiling.
-// Patterned after tcmalloc's algorithms; shorter code.
-
-package runtime
-#include "runtime.h"
-#include "arch_GOARCH.h"
-#include "malloc.h"
-#include "defs_GOOS_GOARCH.h"
-#include "type.h"
-
-// NOTE(rsc): Everything here could use cas if contention became an issue.
-static Lock proflock;
-
-// All memory allocations are local and do not escape outside of the profiler.
-// The profiler is forbidden from referring to garbage-collected memory.
-
-enum { MProf, BProf };  // profile types
-
-// Per-call-stack profiling information.
-// Lookup by hashing call stack into a linked-list hash table.
-struct Bucket
-{
-	Bucket	*next;	// next in hash list
-	Bucket	*allnext;	// next in list of all mbuckets/bbuckets
-	int32	typ;
-	// Generally unions can break precise GC,
-	// this one is fine because it does not contain pointers.
-	union
-	{
-		struct  // typ == MProf
-		{
-			// The following complex 3-stage scheme of stats accumulation
-			// is required to obtain a consistent picture of mallocs and frees
-			// for some point in time.
-			// The problem is that mallocs come in real time, while frees
-			// come only after a GC during concurrent sweeping. So if we would
-			// naively count them, we would get a skew toward mallocs.
-			//
-			// Mallocs are accounted in recent stats.
-			// Explicit frees are accounted in recent stats.
-			// GC frees are accounted in prev stats.
-			// After GC prev stats are added to final stats and
-			// recent stats are moved into prev stats.
-			uintptr	allocs;
-			uintptr	frees;
-			uintptr	alloc_bytes;
-			uintptr	free_bytes;
-
-			uintptr	prev_allocs;  // since last but one till last gc
-			uintptr	prev_frees;
-			uintptr	prev_alloc_bytes;
-			uintptr	prev_free_bytes;
-
-			uintptr	recent_allocs;  // since last gc till now
-			uintptr	recent_frees;
-			uintptr	recent_alloc_bytes;
-			uintptr	recent_free_bytes;
-
-		};
-		struct  // typ == BProf
-		{
-			int64	count;
-			int64	cycles;
-		};
-	};
-	uintptr	hash;	// hash of size + stk
-	uintptr	size;
-	uintptr	nstk;
-	uintptr	stk[1];
-};
-enum {
-	BuckHashSize = 179999,
-};
-static Bucket **buckhash;
-static Bucket *mbuckets;  // memory profile buckets
-static Bucket *bbuckets;  // blocking profile buckets
-static uintptr bucketmem;
-
-// Return the bucket for stk[0:nstk], allocating new bucket if needed.
-static Bucket*
-stkbucket(int32 typ, uintptr size, uintptr *stk, int32 nstk, bool alloc)
-{
-	int32 i;
-	uintptr h;
-	Bucket *b;
-
-	if(buckhash == nil) {
-		buckhash = runtime·SysAlloc(BuckHashSize*sizeof buckhash[0], &mstats.buckhash_sys);
-		if(buckhash == nil)
-			runtime·throw("runtime: cannot allocate memory");
-	}
-
-	// Hash stack.
-	h = 0;
-	for(i=0; i<nstk; i++) {
-		h += stk[i];
-		h += h<<10;
-		h ^= h>>6;
-	}
-	// hash in size
-	h += size;
-	h += h<<10;
-	h ^= h>>6;
-	// finalize
-	h += h<<3;
-	h ^= h>>11;
-
-	i = h%BuckHashSize;
-	for(b = buckhash[i]; b; b=b->next)
-		if(b->typ == typ && b->hash == h && b->size == size && b->nstk == nstk &&
-		   runtime·mcmp((byte*)b->stk, (byte*)stk, nstk*sizeof stk[0]) == 0)
-			return b;
-
-	if(!alloc)
-		return nil;
-
-	b = runtime·persistentalloc(sizeof *b + nstk*sizeof stk[0], 0, &mstats.buckhash_sys);
-	bucketmem += sizeof *b + nstk*sizeof stk[0];
-	runtime·memmove(b->stk, stk, nstk*sizeof stk[0]);
-	b->typ = typ;
-	b->hash = h;
-	b->size = size;
-	b->nstk = nstk;
-	b->next = buckhash[i];
-	buckhash[i] = b;
-	if(typ == MProf) {
-		b->allnext = mbuckets;
-		mbuckets = b;
-	} else {
-		b->allnext = bbuckets;
-		bbuckets = b;
-	}
-	return b;
-}
-
-static void
-MProf_GC(void)
-{
-	Bucket *b;
-
-	for(b=mbuckets; b; b=b->allnext) {
-		b->allocs += b->prev_allocs;
-		b->frees += b->prev_frees;
-		b->alloc_bytes += b->prev_alloc_bytes;
-		b->free_bytes += b->prev_free_bytes;
-
-		b->prev_allocs = b->recent_allocs;
-		b->prev_frees = b->recent_frees;
-		b->prev_alloc_bytes = b->recent_alloc_bytes;
-		b->prev_free_bytes = b->recent_free_bytes;
-
-		b->recent_allocs = 0;
-		b->recent_frees = 0;
-		b->recent_alloc_bytes = 0;
-		b->recent_free_bytes = 0;
-	}
-}
-
-// Record that a gc just happened: all the 'recent' statistics are now real.
-void
-runtime·MProf_GC(void)
-{
-	runtime·lock(&proflock);
-	MProf_GC();
-	runtime·unlock(&proflock);
-}
-
-// Called by malloc to record a profiled block.
-void
-runtime·MProf_Malloc(void *p, uintptr size)
-{
-	uintptr stk[32];
-	Bucket *b;
-	int32 nstk;
-
-	nstk = runtime·callers(1, stk, nelem(stk));
-	runtime·lock(&proflock);
-	b = stkbucket(MProf, size, stk, nstk, true);
-	b->recent_allocs++;
-	b->recent_alloc_bytes += size;
-	runtime·unlock(&proflock);
-
-	// Setprofilebucket locks a bunch of other mutexes, so we call it outside of proflock.
-	// This reduces potential contention and chances of deadlocks.
-	// Since the object must be alive during call to MProf_Malloc,
-	// it's fine to do this non-atomically.
-	runtime·setprofilebucket(p, b);
-}
-
-// Called when freeing a profiled block.
-void
-runtime·MProf_Free(Bucket *b, uintptr size, bool freed)
-{
-	runtime·lock(&proflock);
-	if(freed) {
-		b->recent_frees++;
-		b->recent_free_bytes += size;
-	} else {
-		b->prev_frees++;
-		b->prev_free_bytes += size;
-	}
-	runtime·unlock(&proflock);
-}
-
-int64 runtime·blockprofilerate;  // in CPU ticks
-
-void
-runtime·SetBlockProfileRate(intgo rate)
-{
-	int64 r;
-
-	if(rate <= 0)
-		r = 0;  // disable profiling
-	else {
-		// convert ns to cycles, use float64 to prevent overflow during multiplication
-		r = (float64)rate*runtime·tickspersecond()/(1000*1000*1000);
-		if(r == 0)
-			r = 1;
-	}
-	runtime·atomicstore64((uint64*)&runtime·blockprofilerate, r);
-}
-
-void
-runtime·blockevent(int64 cycles, int32 skip)
-{
-	int32 nstk;
-	int64 rate;
-	uintptr stk[32];
-	Bucket *b;
-
-	if(cycles <= 0)
-		return;
-	rate = runtime·atomicload64((uint64*)&runtime·blockprofilerate);
-	if(rate <= 0 || (rate > cycles && runtime·fastrand1()%rate > cycles))
-		return;
-
-	nstk = runtime·callers(skip, stk, nelem(stk));
-	runtime·lock(&proflock);
-	b = stkbucket(BProf, 0, stk, nstk, true);
-	b->count++;
-	b->cycles += cycles;
-	runtime·unlock(&proflock);
-}
-
-// Go interface to profile data.  (Declared in debug.go)
-
-// Must match MemProfileRecord in debug.go.
-typedef struct Record Record;
-struct Record {
-	int64 alloc_bytes, free_bytes;
-	int64 alloc_objects, free_objects;
-	uintptr stk[32];
-};
-
-// Write b's data to r.
-static void
-record(Record *r, Bucket *b)
-{
-	int32 i;
-
-	r->alloc_bytes = b->alloc_bytes;
-	r->free_bytes = b->free_bytes;
-	r->alloc_objects = b->allocs;
-	r->free_objects = b->frees;
-	for(i=0; i<b->nstk && i<nelem(r->stk); i++)
-		r->stk[i] = b->stk[i];
-	for(; i<nelem(r->stk); i++)
-		r->stk[i] = 0;
-}
-
-func MemProfile(p Slice, include_inuse_zero bool) (n int, ok bool) {
-	Bucket *b;
-	Record *r;
-	bool clear;
-
-	runtime·lock(&proflock);
-	n = 0;
-	clear = true;
-	for(b=mbuckets; b; b=b->allnext) {
-		if(include_inuse_zero || b->alloc_bytes != b->free_bytes)
-			n++;
-		if(b->allocs != 0 || b->frees != 0)
-			clear = false;
-	}
-	if(clear) {
-		// Absolutely no data, suggesting that a garbage collection
-		// has not yet happened. In order to allow profiling when
-		// garbage collection is disabled from the beginning of execution,
-		// accumulate stats as if a GC just happened, and recount buckets.
-		MProf_GC();
-		MProf_GC();
-		n = 0;
-		for(b=mbuckets; b; b=b->allnext)
-			if(include_inuse_zero || b->alloc_bytes != b->free_bytes)
-				n++;
-	}
-	ok = false;
-	if(n <= p.len) {
-		ok = true;
-		r = (Record*)p.array;
-		for(b=mbuckets; b; b=b->allnext)
-			if(include_inuse_zero || b->alloc_bytes != b->free_bytes)
-				record(r++, b);
-	}
-	runtime·unlock(&proflock);
-}
-
-void
-runtime·iterate_memprof(void (*callback)(Bucket*, uintptr, uintptr*, uintptr, uintptr, uintptr))
-{
-	Bucket *b;
-
-	runtime·lock(&proflock);
-	for(b=mbuckets; b; b=b->allnext) {
-		callback(b, b->nstk, b->stk, b->size, b->allocs, b->frees);
-	}
-	runtime·unlock(&proflock);
-}
-
-// Must match BlockProfileRecord in debug.go.
-typedef struct BRecord BRecord;
-struct BRecord {
-	int64 count;
-	int64 cycles;
-	uintptr stk[32];
-};
-
-func BlockProfile(p Slice) (n int, ok bool) {
-	Bucket *b;
-	BRecord *r;
-	int32 i;
-
-	runtime·lock(&proflock);
-	n = 0;
-	for(b=bbuckets; b; b=b->allnext)
-		n++;
-	ok = false;
-	if(n <= p.len) {
-		ok = true;
-		r = (BRecord*)p.array;
-		for(b=bbuckets; b; b=b->allnext, r++) {
-			r->count = b->count;
-			r->cycles = b->cycles;
-			for(i=0; i<b->nstk && i<nelem(r->stk); i++)
-				r->stk[i] = b->stk[i];
-			for(; i<nelem(r->stk); i++)
-				r->stk[i] = 0;			
-		}
-	}
-	runtime·unlock(&proflock);
-}
-
-// Must match StackRecord in debug.go.
-typedef struct TRecord TRecord;
-struct TRecord {
-	uintptr stk[32];
-};
-
-func ThreadCreateProfile(p Slice) (n int, ok bool) {
-	TRecord *r;
-	M *first, *mp;
-	
-	first = runtime·atomicloadp(&runtime·allm);
-	n = 0;
-	for(mp=first; mp; mp=mp->alllink)
-		n++;
-	ok = false;
-	if(n <= p.len) {
-		ok = true;
-		r = (TRecord*)p.array;
-		for(mp=first; mp; mp=mp->alllink) {
-			runtime·memmove(r->stk, mp->createstack, sizeof r->stk);
-			r++;
-		}
-	}
-}
-
-func Stack(b Slice, all bool) (n int) {
-	uintptr pc, sp;
-	
-	sp = runtime·getcallersp(&b);
-	pc = (uintptr)runtime·getcallerpc(&b);
-
-	if(all) {
-		runtime·semacquire(&runtime·worldsema, false);
-		m->gcing = 1;
-		runtime·stoptheworld();
-	}
-
-	if(b.len == 0)
-		n = 0;
-	else{
-		g->writebuf = (byte*)b.array;
-		g->writenbuf = b.len;
-		runtime·goroutineheader(g);
-		runtime·traceback(pc, sp, 0, g);
-		if(all)
-			runtime·tracebackothers(g);
-		n = b.len - g->writenbuf;
-		g->writebuf = nil;
-		g->writenbuf = 0;
-	}
-	
-	if(all) {
-		m->gcing = 0;
-		runtime·semrelease(&runtime·worldsema);
-		runtime·starttheworld();
-	}
-}
-
-static void
-saveg(uintptr pc, uintptr sp, G *gp, TRecord *r)
-{
-	int32 n;
-	
-	n = runtime·gentraceback(pc, sp, 0, gp, 0, r->stk, nelem(r->stk), nil, nil, false);
-	if(n < nelem(r->stk))
-		r->stk[n] = 0;
-}
-
-func GoroutineProfile(b Slice) (n int, ok bool) {
-	uintptr pc, sp, i;
-	TRecord *r;
-	G *gp;
-	
-	sp = runtime·getcallersp(&b);
-	pc = (uintptr)runtime·getcallerpc(&b);
-	
-	ok = false;
-	n = runtime·gcount();
-	if(n <= b.len) {
-		runtime·semacquire(&runtime·worldsema, false);
-		m->gcing = 1;
-		runtime·stoptheworld();
-
-		n = runtime·gcount();
-		if(n <= b.len) {
-			ok = true;
-			r = (TRecord*)b.array;
-			saveg(pc, sp, g, r++);
-			for(i = 0; i < runtime·allglen; i++) {
-				gp = runtime·allg[i];
-				if(gp == g || gp->status == Gdead)
-					continue;
-				saveg(~(uintptr)0, ~(uintptr)0, gp, r++);
-			}
-		}
-	
-		m->gcing = 0;
-		runtime·semrelease(&runtime·worldsema);
-		runtime·starttheworld();
-	}
-}
-
-// Tracing of alloc/free/gc.
-
-static Lock tracelock;
-
-static int8*
-typeinfoname(int32 typeinfo)
-{
-	if(typeinfo == TypeInfo_SingleObject)
-		return "single object";
-	else if(typeinfo == TypeInfo_Array)
-		return "array";
-	else if(typeinfo == TypeInfo_Chan)
-		return "channel";
-	runtime·throw("typinfoname: unknown type info");
-	return nil;
-}
-
-void
-runtime·tracealloc(void *p, uintptr size, uintptr typ)
-{
-	int8 *name;
-	Type *type;
-
-	runtime·lock(&tracelock);
-	m->traceback = 2;
-	type = (Type*)(typ & ~3);
-	name = typeinfoname(typ & 3);
-	if(type == nil)
-		runtime·printf("tracealloc(%p, %p, %s)\n", p, size, name);
-	else	
-		runtime·printf("tracealloc(%p, %p, %s of %S)\n", p, size, name, *type->string);
-	if(m->curg == nil || g == m->curg) {
-		runtime·goroutineheader(g);
-		runtime·traceback((uintptr)runtime·getcallerpc(&p), (uintptr)runtime·getcallersp(&p), 0, g);
-	} else {
-		runtime·goroutineheader(m->curg);
-		runtime·traceback(~(uintptr)0, ~(uintptr)0, 0, m->curg);
-	}
-	runtime·printf("\n");
-	m->traceback = 0;
-	runtime·unlock(&tracelock);
-}
-
-void
-runtime·tracefree(void *p, uintptr size)
-{
-	runtime·lock(&tracelock);
-	m->traceback = 2;
-	runtime·printf("tracefree(%p, %p)\n", p, size);
-	runtime·goroutineheader(g);
-	runtime·traceback((uintptr)runtime·getcallerpc(&p), (uintptr)runtime·getcallersp(&p), 0, g);
-	runtime·printf("\n");
-	m->traceback = 0;
-	runtime·unlock(&tracelock);
-}
-
-void
-runtime·tracegc(void)
-{
-	runtime·lock(&tracelock);
-	m->traceback = 2;
-	runtime·printf("tracegc()\n");
-	// running on m->g0 stack; show all non-g0 goroutines
-	runtime·tracebackothers(g);
-	runtime·printf("end tracegc\n");
-	runtime·printf("\n");
-	m->traceback = 0;
-	runtime·unlock(&tracelock);
-}
diff --git a/src/pkg/runtime/msize.c b/src/pkg/runtime/msize.c
deleted file mode 100644
index 2fbd5e1..0000000
--- a/src/pkg/runtime/msize.c
+++ /dev/null
@@ -1,184 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Malloc small size classes.
-//
-// See malloc.h for overview.
-//
-// The size classes are chosen so that rounding an allocation
-// request up to the next size class wastes at most 12.5% (1.125x).
-//
-// Each size class has its own page count that gets allocated
-// and chopped up when new objects of the size class are needed.
-// That page count is chosen so that chopping up the run of
-// pages into objects of the given size wastes at most 12.5% (1.125x)
-// of the memory.  It is not necessary that the cutoff here be
-// the same as above.
-//
-// The two sources of waste multiply, so the worst possible case
-// for the above constraints would be that allocations of some
-// size might have a 26.6% (1.266x) overhead.
-// In practice, only one of the wastes comes into play for a
-// given size (sizes < 512 waste mainly on the round-up,
-// sizes > 512 waste mainly on the page chopping).
-//
-// TODO(rsc): Compute max waste for any given size.
-
-#include "runtime.h"
-#include "arch_GOARCH.h"
-#include "malloc.h"
-#include "../../cmd/ld/textflag.h"
-
-#pragma dataflag NOPTR
-int32 runtime·class_to_size[NumSizeClasses];
-#pragma dataflag NOPTR
-int32 runtime·class_to_allocnpages[NumSizeClasses];
-
-// The SizeToClass lookup is implemented using two arrays,
-// one mapping sizes <= 1024 to their class and one mapping
-// sizes >= 1024 and <= MaxSmallSize to their class.
-// All objects are 8-aligned, so the first array is indexed by
-// the size divided by 8 (rounded up).  Objects >= 1024 bytes
-// are 128-aligned, so the second array is indexed by the
-// size divided by 128 (rounded up).  The arrays are filled in
-// by InitSizes.
-
-#pragma dataflag NOPTR
-int8 runtime·size_to_class8[1024/8 + 1];
-#pragma dataflag NOPTR
-int8 runtime·size_to_class128[(MaxSmallSize-1024)/128 + 1];
-
-void runtime·testdefersizes(void);
-
-int32
-runtime·SizeToClass(int32 size)
-{
-	if(size > MaxSmallSize)
-		runtime·throw("SizeToClass - invalid size");
-	if(size > 1024-8)
-		return runtime·size_to_class128[(size-1024+127) >> 7];
-	return runtime·size_to_class8[(size+7)>>3];
-}
-
-void
-runtime·InitSizes(void)
-{
-	int32 align, sizeclass, size, nextsize, n;
-	uint32 i;
-	uintptr allocsize, npages;
-
-	// Initialize the runtime·class_to_size table (and choose class sizes in the process).
-	runtime·class_to_size[0] = 0;
-	sizeclass = 1;	// 0 means no class
-	align = 8;
-	for(size = align; size <= MaxSmallSize; size += align) {
-		if((size&(size-1)) == 0) {	// bump alignment once in a while
-			if(size >= 2048)
-				align = 256;
-			else if(size >= 128)
-				align = size / 8;
-			else if(size >= 16)
-				align = 16;	// required for x86 SSE instructions, if we want to use them
-		}
-		if((align&(align-1)) != 0)
-			runtime·throw("InitSizes - bug");
-
-		// Make the allocnpages big enough that
-		// the leftover is less than 1/8 of the total,
-		// so wasted space is at most 12.5%.
-		allocsize = PageSize;
-		while(allocsize%size > allocsize/8)
-			allocsize += PageSize;
-		npages = allocsize >> PageShift;
-
-		// If the previous sizeclass chose the same
-		// allocation size and fit the same number of
-		// objects into the page, we might as well
-		// use just this size instead of having two
-		// different sizes.
-		if(sizeclass > 1 &&
-			npages == runtime·class_to_allocnpages[sizeclass-1] &&
-			allocsize/size == allocsize/runtime·class_to_size[sizeclass-1]) {
-			runtime·class_to_size[sizeclass-1] = size;
-			continue;
-		}
-
-		runtime·class_to_allocnpages[sizeclass] = npages;
-		runtime·class_to_size[sizeclass] = size;
-		sizeclass++;
-	}
-	if(sizeclass != NumSizeClasses) {
-		runtime·printf("sizeclass=%d NumSizeClasses=%d\n", sizeclass, NumSizeClasses);
-		runtime·throw("InitSizes - bad NumSizeClasses");
-	}
-
-	// Initialize the size_to_class tables.
-	nextsize = 0;
-	for (sizeclass = 1; sizeclass < NumSizeClasses; sizeclass++) {
-		for(; nextsize < 1024 && nextsize <= runtime·class_to_size[sizeclass]; nextsize+=8)
-			runtime·size_to_class8[nextsize/8] = sizeclass;
-		if(nextsize >= 1024)
-			for(; nextsize <= runtime·class_to_size[sizeclass]; nextsize += 128)
-				runtime·size_to_class128[(nextsize-1024)/128] = sizeclass;
-	}
-
-	// Double-check SizeToClass.
-	if(0) {
-		for(n=0; n < MaxSmallSize; n++) {
-			sizeclass = runtime·SizeToClass(n);
-			if(sizeclass < 1 || sizeclass >= NumSizeClasses || runtime·class_to_size[sizeclass] < n) {
-				runtime·printf("size=%d sizeclass=%d runtime·class_to_size=%d\n", n, sizeclass, runtime·class_to_size[sizeclass]);
-				runtime·printf("incorrect SizeToClass");
-				goto dump;
-			}
-			if(sizeclass > 1 && runtime·class_to_size[sizeclass-1] >= n) {
-				runtime·printf("size=%d sizeclass=%d runtime·class_to_size=%d\n", n, sizeclass, runtime·class_to_size[sizeclass]);
-				runtime·printf("SizeToClass too big");
-				goto dump;
-			}
-		}
-	}
-
-	runtime·testdefersizes();
-
-	// Copy out for statistics table.
-	for(i=0; i<nelem(runtime·class_to_size); i++)
-		mstats.by_size[i].size = runtime·class_to_size[i];
-	return;
-
-dump:
-	if(1){
-		runtime·printf("NumSizeClasses=%d\n", NumSizeClasses);
-		runtime·printf("runtime·class_to_size:");
-		for(sizeclass=0; sizeclass<NumSizeClasses; sizeclass++)
-			runtime·printf(" %d", runtime·class_to_size[sizeclass]);
-		runtime·printf("\n\n");
-		runtime·printf("size_to_class8:");
-		for(i=0; i<nelem(runtime·size_to_class8); i++)
-			runtime·printf(" %d=>%d(%d)\n", i*8, runtime·size_to_class8[i],
-				runtime·class_to_size[runtime·size_to_class8[i]]);
-		runtime·printf("\n");
-		runtime·printf("size_to_class128:");
-		for(i=0; i<nelem(runtime·size_to_class128); i++)
-			runtime·printf(" %d=>%d(%d)\n", i*128, runtime·size_to_class128[i],
-				runtime·class_to_size[runtime·size_to_class128[i]]);
-		runtime·printf("\n");
-	}
-	runtime·throw("InitSizes failed");
-}
-
-// Returns size of the memory block that mallocgc will allocate if you ask for the size.
-uintptr
-runtime·roundupsize(uintptr size)
-{
-	if(size < MaxSmallSize) {
-		if(size <= 1024-8)
-			return runtime·class_to_size[runtime·size_to_class8[(size+7)>>3]];
-		else
-			return runtime·class_to_size[runtime·size_to_class128[(size-1024+127) >> 7]];
-	}
-	if(size + PageSize < size)
-		return size;
-	return ROUND(size, PageSize);
-}
diff --git a/src/pkg/runtime/netpoll.goc b/src/pkg/runtime/netpoll.goc
deleted file mode 100644
index 7b3d16d..0000000
--- a/src/pkg/runtime/netpoll.goc
+++ /dev/null
@@ -1,467 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris windows
-
-package net
-
-#include "runtime.h"
-#include "defs_GOOS_GOARCH.h"
-#include "arch_GOARCH.h"
-#include "malloc.h"
-
-// Integrated network poller (platform-independent part).
-// A particular implementation (epoll/kqueue) must define the following functions:
-// void runtime·netpollinit(void);			// to initialize the poller
-// int32 runtime·netpollopen(uintptr fd, PollDesc *pd);	// to arm edge-triggered notifications
-							// and associate fd with pd.
-// An implementation must call the following function to denote that the pd is ready.
-// void runtime·netpollready(G **gpp, PollDesc *pd, int32 mode);
-
-// PollDesc contains 2 binary semaphores, rg and wg, to park reader and writer
-// goroutines respectively. The semaphore can be in the following states:
-// READY - io readiness notification is pending;
-//         a goroutine consumes the notification by changing the state to nil.
-// WAIT - a goroutine prepares to park on the semaphore, but not yet parked;
-//        the goroutine commits to park by changing the state to G pointer,
-//        or, alternatively, concurrent io notification changes the state to READY,
-//        or, alternatively, concurrent timeout/close changes the state to nil.
-// G pointer - the goroutine is blocked on the semaphore;
-//             io notification or timeout/close changes the state to READY or nil respectively
-//             and unparks the goroutine.
-// nil - nothing of the above.
-#define READY ((G*)1)
-#define WAIT  ((G*)2)
-
-enum
-{
-	PollBlockSize	= 4*1024,
-};
-
-struct PollDesc
-{
-	PollDesc* link;	// in pollcache, protected by pollcache.Lock
-
-	// The lock protects pollOpen, pollSetDeadline, pollUnblock and deadlineimpl operations.
-	// This fully covers seq, rt and wt variables. fd is constant throughout the PollDesc lifetime.
-	// pollReset, pollWait, pollWaitCanceled and runtime·netpollready (IO rediness notification)
-	// proceed w/o taking the lock. So closing, rg, rd, wg and wd are manipulated
-	// in a lock-free way by all operations.
-	Lock;		// protectes the following fields
-	uintptr	fd;
-	bool	closing;
-	uintptr	seq;	// protects from stale timers and ready notifications
-	G*	rg;	// READY, WAIT, G waiting for read or nil
-	Timer	rt;	// read deadline timer (set if rt.fv != nil)
-	int64	rd;	// read deadline
-	G*	wg;	// READY, WAIT, G waiting for write or nil
-	Timer	wt;	// write deadline timer
-	int64	wd;	// write deadline
-	void*	user;	// user settable cookie
-};
-
-static struct
-{
-	Lock;
-	PollDesc*	first;
-	// PollDesc objects must be type-stable,
-	// because we can get ready notification from epoll/kqueue
-	// after the descriptor is closed/reused.
-	// Stale notifications are detected using seq variable,
-	// seq is incremented when deadlines are changed or descriptor is reused.
-} pollcache;
-
-static bool	netpollblock(PollDesc*, int32, bool);
-static G*	netpollunblock(PollDesc*, int32, bool);
-static void	deadline(int64, Eface);
-static void	readDeadline(int64, Eface);
-static void	writeDeadline(int64, Eface);
-static PollDesc*	allocPollDesc(void);
-static intgo	checkerr(PollDesc *pd, int32 mode);
-
-static FuncVal deadlineFn	= {(void(*)(void))deadline};
-static FuncVal readDeadlineFn	= {(void(*)(void))readDeadline};
-static FuncVal writeDeadlineFn	= {(void(*)(void))writeDeadline};
-
-// runtimeNano returns the current value of the runtime clock in nanoseconds.
-func runtimeNano() (ns int64) {
-	ns = runtime·nanotime();
-}
-
-func runtime_pollServerInit() {
-	runtime·netpollinit();
-}
-
-func runtime_pollOpen(fd uintptr) (pd *PollDesc, errno int) {
-	pd = allocPollDesc();
-	runtime·lock(pd);
-	if(pd->wg != nil && pd->wg != READY)
-		runtime·throw("runtime_pollOpen: blocked write on free descriptor");
-	if(pd->rg != nil && pd->rg != READY)
-		runtime·throw("runtime_pollOpen: blocked read on free descriptor");
-	pd->fd = fd;
-	pd->closing = false;
-	pd->seq++;
-	pd->rg = nil;
-	pd->rd = 0;
-	pd->wg = nil;
-	pd->wd = 0;
-	runtime·unlock(pd);
-
-	errno = runtime·netpollopen(fd, pd);
-}
-
-func runtime_pollClose(pd *PollDesc) {
-	if(!pd->closing)
-		runtime·throw("runtime_pollClose: close w/o unblock");
-	if(pd->wg != nil && pd->wg != READY)
-		runtime·throw("runtime_pollClose: blocked write on closing descriptor");
-	if(pd->rg != nil && pd->rg != READY)
-		runtime·throw("runtime_pollClose: blocked read on closing descriptor");
-	runtime·netpollclose(pd->fd);
-	runtime·lock(&pollcache);
-	pd->link = pollcache.first;
-	pollcache.first = pd;
-	runtime·unlock(&pollcache);
-}
-
-func runtime_pollReset(pd *PollDesc, mode int) (err int) {
-	err = checkerr(pd, mode);
-	if(err)
-		goto ret;
-	if(mode == 'r')
-		pd->rg = nil;
-	else if(mode == 'w')
-		pd->wg = nil;
-ret:
-}
-
-func runtime_pollWait(pd *PollDesc, mode int) (err int) {
-	err = checkerr(pd, mode);
-	if(err == 0) {
-		// As for now only Solaris uses level-triggered IO.
-		if(Solaris)
-			runtime·netpollarm(pd, mode);
-		while(!netpollblock(pd, mode, false)) {
-			err = checkerr(pd, mode);
-			if(err != 0)
-				break;
-			// Can happen if timeout has fired and unblocked us,
-			// but before we had a chance to run, timeout has been reset.
-			// Pretend it has not happened and retry.
-		}
-	}
-}
-
-func runtime_pollWaitCanceled(pd *PollDesc, mode int) {
-	// This function is used only on windows after a failed attempt to cancel
-	// a pending async IO operation. Wait for ioready, ignore closing or timeouts.
-	while(!netpollblock(pd, mode, true))
-		;
-}
-
-func runtime_pollSetDeadline(pd *PollDesc, d int64, mode int) {
-	G *rg, *wg;
-
-	runtime·lock(pd);
-	if(pd->closing) {
-		runtime·unlock(pd);
-		return;
-	}
-	pd->seq++;  // invalidate current timers
-	// Reset current timers.
-	if(pd->rt.fv) {
-		runtime·deltimer(&pd->rt);
-		pd->rt.fv = nil;
-	}
-	if(pd->wt.fv) {
-		runtime·deltimer(&pd->wt);
-		pd->wt.fv = nil;
-	}
-	// Setup new timers.
-	if(d != 0 && d <= runtime·nanotime())
-		d = -1;
-	if(mode == 'r' || mode == 'r'+'w')
-		pd->rd = d;
-	if(mode == 'w' || mode == 'r'+'w')
-		pd->wd = d;
-	if(pd->rd > 0 && pd->rd == pd->wd) {
-		pd->rt.fv = &deadlineFn;
-		pd->rt.when = pd->rd;
-		// Copy current seq into the timer arg.
-		// Timer func will check the seq against current descriptor seq,
-		// if they differ the descriptor was reused or timers were reset.
-		pd->rt.arg.type = (Type*)pd->seq;
-		pd->rt.arg.data = pd;
-		runtime·addtimer(&pd->rt);
-	} else {
-		if(pd->rd > 0) {
-			pd->rt.fv = &readDeadlineFn;
-			pd->rt.when = pd->rd;
-			pd->rt.arg.type = (Type*)pd->seq;
-			pd->rt.arg.data = pd;
-			runtime·addtimer(&pd->rt);
-		}
-		if(pd->wd > 0) {
-			pd->wt.fv = &writeDeadlineFn;
-			pd->wt.when = pd->wd;
-			pd->wt.arg.type = (Type*)pd->seq;
-			pd->wt.arg.data = pd;
-			runtime·addtimer(&pd->wt);
-		}
-	}
-	// If we set the new deadline in the past, unblock currently pending IO if any.
-	rg = nil;
-	runtime·atomicstorep(&wg, nil);  // full memory barrier between stores to rd/wd and load of rg/wg in netpollunblock
-	if(pd->rd < 0)
-		rg = netpollunblock(pd, 'r', false);
-	if(pd->wd < 0)
-		wg = netpollunblock(pd, 'w', false);
-	runtime·unlock(pd);
-	if(rg)
-		runtime·ready(rg);
-	if(wg)
-		runtime·ready(wg);
-}
-
-func runtime_pollUnblock(pd *PollDesc) {
-	G *rg, *wg;
-
-	runtime·lock(pd);
-	if(pd->closing)
-		runtime·throw("runtime_pollUnblock: already closing");
-	pd->closing = true;
-	pd->seq++;
-	runtime·atomicstorep(&rg, nil);  // full memory barrier between store to closing and read of rg/wg in netpollunblock
-	rg = netpollunblock(pd, 'r', false);
-	wg = netpollunblock(pd, 'w', false);
-	if(pd->rt.fv) {
-		runtime·deltimer(&pd->rt);
-		pd->rt.fv = nil;
-	}
-	if(pd->wt.fv) {
-		runtime·deltimer(&pd->wt);
-		pd->wt.fv = nil;
-	}
-	runtime·unlock(pd);
-	if(rg)
-		runtime·ready(rg);
-	if(wg)
-		runtime·ready(wg);
-}
-
-uintptr
-runtime·netpollfd(PollDesc *pd)
-{
-	return pd->fd;
-}
-
-void**
-runtime·netpolluser(PollDesc *pd)
-{
-	return &pd->user;
-}
-
-bool
-runtime·netpollclosing(PollDesc *pd)
-{
-	return pd->closing;
-}
-
-void
-runtime·netpolllock(PollDesc *pd)
-{
-	runtime·lock(pd);
-}
-
-void
-runtime·netpollunlock(PollDesc *pd)
-{
-	runtime·unlock(pd);
-}
-
-// make pd ready, newly runnable goroutines (if any) are enqueued info gpp list
-void
-runtime·netpollready(G **gpp, PollDesc *pd, int32 mode)
-{
-	G *rg, *wg;
-
-	rg = wg = nil;
-	if(mode == 'r' || mode == 'r'+'w')
-		rg = netpollunblock(pd, 'r', true);
-	if(mode == 'w' || mode == 'r'+'w')
-		wg = netpollunblock(pd, 'w', true);
-	if(rg) {
-		rg->schedlink = *gpp;
-		*gpp = rg;
-	}
-	if(wg) {
-		wg->schedlink = *gpp;
-		*gpp = wg;
-	}
-}
-
-static intgo
-checkerr(PollDesc *pd, int32 mode)
-{
-	if(pd->closing)
-		return 1;  // errClosing
-	if((mode == 'r' && pd->rd < 0) || (mode == 'w' && pd->wd < 0))
-		return 2;  // errTimeout
-	return 0;
-}
-
-static bool
-blockcommit(G *gp, G **gpp)
-{
-	return runtime·casp(gpp, WAIT, gp);
-}
-
-// returns true if IO is ready, or false if timedout or closed
-// waitio - wait only for completed IO, ignore errors
-static bool
-netpollblock(PollDesc *pd, int32 mode, bool waitio)
-{
-	G **gpp, *old;
-
-	gpp = &pd->rg;
-	if(mode == 'w')
-		gpp = &pd->wg;
-
-	// set the gpp semaphore to WAIT
-	for(;;) {
-		old = *gpp;
-		if(old == READY) {
-			*gpp = nil;
-			return true;
-		}
-		if(old != nil)
-			runtime·throw("netpollblock: double wait");
-		if(runtime·casp(gpp, nil, WAIT))
-			break;
-	}
-
-	// need to recheck error states after setting gpp to WAIT
-	// this is necessary because runtime_pollUnblock/runtime_pollSetDeadline/deadlineimpl
-	// do the opposite: store to closing/rd/wd, membarrier, load of rg/wg
-	if(waitio || checkerr(pd, mode) == 0)
-		runtime·park((bool(*)(G*, void*))blockcommit, gpp, "IO wait");
-	// be careful to not lose concurrent READY notification
-	old = runtime·xchgp(gpp, nil);
-	if(old > WAIT)
-		runtime·throw("netpollblock: corrupted state");
-	return old == READY;
-}
-
-static G*
-netpollunblock(PollDesc *pd, int32 mode, bool ioready)
-{
-	G **gpp, *old, *new;
-
-	gpp = &pd->rg;
-	if(mode == 'w')
-		gpp = &pd->wg;
-
-	for(;;) {
-		old = *gpp;
-		if(old == READY)
-			return nil;
-		if(old == nil && !ioready) {
-			// Only set READY for ioready. runtime_pollWait
-			// will check for timeout/cancel before waiting.
-			return nil;
-		}
-		new = nil;
-		if(ioready)
-			new = READY;
-		if(runtime·casp(gpp, old, new))
-			break;
-	}
-	if(old > WAIT)
-		return old;  // must be G*
-	return nil;
-}
-
-static void
-deadlineimpl(int64 now, Eface arg, bool read, bool write)
-{
-	PollDesc *pd;
-	uint32 seq;
-	G *rg, *wg;
-
-	USED(now);
-	pd = (PollDesc*)arg.data;
-	// This is the seq when the timer was set.
-	// If it's stale, ignore the timer event.
-	seq = (uintptr)arg.type;
-	rg = wg = nil;
-	runtime·lock(pd);
-	if(seq != pd->seq) {
-		// The descriptor was reused or timers were reset.
-		runtime·unlock(pd);
-		return;
-	}
-	if(read) {
-		if(pd->rd <= 0 || pd->rt.fv == nil)
-			runtime·throw("deadlineimpl: inconsistent read deadline");
-		pd->rd = -1;
-		runtime·atomicstorep(&pd->rt.fv, nil);  // full memory barrier between store to rd and load of rg in netpollunblock
-		rg = netpollunblock(pd, 'r', false);
-	}
-	if(write) {
-		if(pd->wd <= 0 || (pd->wt.fv == nil && !read))
-			runtime·throw("deadlineimpl: inconsistent write deadline");
-		pd->wd = -1;
-		runtime·atomicstorep(&pd->wt.fv, nil);  // full memory barrier between store to wd and load of wg in netpollunblock
-		wg = netpollunblock(pd, 'w', false);
-	}
-	runtime·unlock(pd);
-	if(rg)
-		runtime·ready(rg);
-	if(wg)
-		runtime·ready(wg);
-}
-
-static void
-deadline(int64 now, Eface arg)
-{
-	deadlineimpl(now, arg, true, true);
-}
-
-static void
-readDeadline(int64 now, Eface arg)
-{
-	deadlineimpl(now, arg, true, false);
-}
-
-static void
-writeDeadline(int64 now, Eface arg)
-{
-	deadlineimpl(now, arg, false, true);
-}
-
-static PollDesc*
-allocPollDesc(void)
-{
-	PollDesc *pd;
-	uint32 i, n;
-
-	runtime·lock(&pollcache);
-	if(pollcache.first == nil) {
-		n = PollBlockSize/sizeof(*pd);
-		if(n == 0)
-			n = 1;
-		// Must be in non-GC memory because can be referenced
-		// only from epoll/kqueue internals.
-		pd = runtime·persistentalloc(n*sizeof(*pd), 0, &mstats.other_sys);
-		for(i = 0; i < n; i++) {
-			pd[i].link = pollcache.first;
-			pollcache.first = &pd[i];
-		}
-	}
-	pd = pollcache.first;
-	pollcache.first = pd->link;
-	runtime·unlock(&pollcache);
-	return pd;
-}
diff --git a/src/pkg/runtime/netpoll_epoll.c b/src/pkg/runtime/netpoll_epoll.c
deleted file mode 100644
index 9ea5e1a..0000000
--- a/src/pkg/runtime/netpoll_epoll.c
+++ /dev/null
@@ -1,102 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build linux
-
-#include "runtime.h"
-#include "defs_GOOS_GOARCH.h"
-
-int32	runtime·epollcreate(int32 size);
-int32	runtime·epollcreate1(int32 flags);
-int32	runtime·epollctl(int32 epfd, int32 op, int32 fd, EpollEvent *ev);
-int32	runtime·epollwait(int32 epfd, EpollEvent *ev, int32 nev, int32 timeout);
-void	runtime·closeonexec(int32 fd);
-
-static int32 epfd = -1;  // epoll descriptor
-
-void
-runtime·netpollinit(void)
-{
-	epfd = runtime·epollcreate1(EPOLL_CLOEXEC);
-	if(epfd >= 0)
-		return;
-	epfd = runtime·epollcreate(1024);
-	if(epfd >= 0) {
-		runtime·closeonexec(epfd);
-		return;
-	}
-	runtime·printf("netpollinit: failed to create descriptor (%d)\n", -epfd);
-	runtime·throw("netpollinit: failed to create descriptor");
-}
-
-int32
-runtime·netpollopen(uintptr fd, PollDesc *pd)
-{
-	EpollEvent ev;
-	int32 res;
-
-	ev.events = EPOLLIN|EPOLLOUT|EPOLLRDHUP|EPOLLET;
-	ev.data = (uint64)pd;
-	res = runtime·epollctl(epfd, EPOLL_CTL_ADD, (int32)fd, &ev);
-	return -res;
-}
-
-int32
-runtime·netpollclose(uintptr fd)
-{
-	EpollEvent ev;
-	int32 res;
-
-	res = runtime·epollctl(epfd, EPOLL_CTL_DEL, (int32)fd, &ev);
-	return -res;
-}
-
-void
-runtime·netpollarm(PollDesc* pd, int32 mode)
-{
-	USED(pd, mode);
-	runtime·throw("unused");
-}
-
-// polls for ready network connections
-// returns list of goroutines that become runnable
-G*
-runtime·netpoll(bool block)
-{
-	static int32 lasterr;
-	EpollEvent events[128], *ev;
-	int32 n, i, waitms, mode;
-	G *gp;
-
-	if(epfd == -1)
-		return nil;
-	waitms = -1;
-	if(!block)
-		waitms = 0;
-retry:
-	n = runtime·epollwait(epfd, events, nelem(events), waitms);
-	if(n < 0) {
-		if(n != -EINTR && n != lasterr) {
-			lasterr = n;
-			runtime·printf("runtime: epollwait on fd %d failed with %d\n", epfd, -n);
-		}
-		goto retry;
-	}
-	gp = nil;
-	for(i = 0; i < n; i++) {
-		ev = &events[i];
-		if(ev->events == 0)
-			continue;
-		mode = 0;
-		if(ev->events & (EPOLLIN|EPOLLRDHUP|EPOLLHUP|EPOLLERR))
-			mode += 'r';
-		if(ev->events & (EPOLLOUT|EPOLLHUP|EPOLLERR))
-			mode += 'w';
-		if(mode)
-			runtime·netpollready(&gp, (void*)ev->data, mode);
-	}
-	if(block && gp == nil)
-		goto retry;
-	return gp;
-}
diff --git a/src/pkg/runtime/netpoll_kqueue.c b/src/pkg/runtime/netpoll_kqueue.c
deleted file mode 100644
index 171346c..0000000
--- a/src/pkg/runtime/netpoll_kqueue.c
+++ /dev/null
@@ -1,111 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build darwin dragonfly freebsd netbsd openbsd
-
-#include "runtime.h"
-#include "defs_GOOS_GOARCH.h"
-#include "os_GOOS.h"
-
-// Integrated network poller (kqueue-based implementation).
-
-int32	runtime·kqueue(void);
-int32	runtime·kevent(int32, Kevent*, int32, Kevent*, int32, Timespec*);
-void	runtime·closeonexec(int32);
-
-static int32 kq = -1;
-
-void
-runtime·netpollinit(void)
-{
-	kq = runtime·kqueue();
-	if(kq < 0) {
-		runtime·printf("netpollinit: kqueue failed with %d\n", -kq);
-		runtime·throw("netpollinit: kqueue failed");
-	}
-	runtime·closeonexec(kq);
-}
-
-int32
-runtime·netpollopen(uintptr fd, PollDesc *pd)
-{
-	Kevent ev[2];
-	int32 n;
-
-	// Arm both EVFILT_READ and EVFILT_WRITE in edge-triggered mode (EV_CLEAR)
-	// for the whole fd lifetime.  The notifications are automatically unregistered
-	// when fd is closed.
-	ev[0].ident = (uint32)fd;
-	ev[0].filter = EVFILT_READ;
-	ev[0].flags = EV_ADD|EV_CLEAR;
-	ev[0].fflags = 0;
-	ev[0].data = 0;
-	ev[0].udata = (kevent_udata)pd;
-	ev[1] = ev[0];
-	ev[1].filter = EVFILT_WRITE;
-	n = runtime·kevent(kq, ev, 2, nil, 0, nil);
-	if(n < 0)
-		return -n;
-	return 0;
-}
-
-int32
-runtime·netpollclose(uintptr fd)
-{
-	// Don't need to unregister because calling close()
-	// on fd will remove any kevents that reference the descriptor.
-	USED(fd);
-	return 0;
-}
-
-void
-runtime·netpollarm(PollDesc* pd, int32 mode)
-{
-	USED(pd, mode);
-	runtime·throw("unused");
-}
-
-// Polls for ready network connections.
-// Returns list of goroutines that become runnable.
-G*
-runtime·netpoll(bool block)
-{
-	static int32 lasterr;
-	Kevent events[64], *ev;
-	Timespec ts, *tp;
-	int32 n, i, mode;
-	G *gp;
-
-	if(kq == -1)
-		return nil;
-	tp = nil;
-	if(!block) {
-		ts.tv_sec = 0;
-		ts.tv_nsec = 0;
-		tp = &ts;
-	}
-	gp = nil;
-retry:
-	n = runtime·kevent(kq, nil, 0, events, nelem(events), tp);
-	if(n < 0) {
-		if(n != -EINTR && n != lasterr) {
-			lasterr = n;
-			runtime·printf("runtime: kevent on fd %d failed with %d\n", kq, -n);
-		}
-		goto retry;
-	}
-	for(i = 0; i < n; i++) {
-		ev = &events[i];
-		mode = 0;
-		if(ev->filter == EVFILT_READ)
-			mode += 'r';
-		if(ev->filter == EVFILT_WRITE)
-			mode += 'w';
-		if(mode)
-			runtime·netpollready(&gp, (PollDesc*)ev->udata, mode);
-	}
-	if(block && gp == nil)
-		goto retry;
-	return gp;
-}
diff --git a/src/pkg/runtime/netpoll_nacl.c b/src/pkg/runtime/netpoll_nacl.c
deleted file mode 100644
index b75753a..0000000
--- a/src/pkg/runtime/netpoll_nacl.c
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "runtime.h"
-#include "defs_GOOS_GOARCH.h"
-#include "os_GOOS.h"
-
-// Fake network poller for NaCl.
-// Should never be used, because NaCl network connections do not honor "SetNonblock".
-
-void
-runtime·netpollinit(void)
-{
-}
-
-int32
-runtime·netpollopen(uintptr fd, PollDesc *pd)
-{
-	USED(fd);
-	USED(pd);
-	return 0;
-}
-
-int32
-runtime·netpollclose(uintptr fd)
-{
-	USED(fd);
-	return 0;
-}
-
-G*
-runtime·netpoll(bool block)
-{
-	USED(block);
-	return nil;
-}
diff --git a/src/pkg/runtime/netpoll_solaris.c b/src/pkg/runtime/netpoll_solaris.c
deleted file mode 100644
index a2631a8..0000000
--- a/src/pkg/runtime/netpoll_solaris.c
+++ /dev/null
@@ -1,268 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "runtime.h"
-#include "arch_GOARCH.h"
-#include "defs_GOOS_GOARCH.h"
-#include "os_GOOS.h"
-
-// Solaris runtime-integrated network poller.
-// 
-// Solaris uses event ports for scalable network I/O. Event
-// ports are level-triggered, unlike epoll and kqueue which
-// can be configured in both level-triggered and edge-triggered
-// mode. Level triggering means we have to keep track of a few things
-// ourselves. After we receive an event for a file descriptor,
-// it's our responsibility to ask again to be notified for future
-// events for that descriptor. When doing this we must keep track of
-// what kind of events the goroutines are currently interested in,
-// for example a fd may be open both for reading and writing.
-// 
-// A description of the high level operation of this code
-// follows. Networking code will get a file descriptor by some means
-// and will register it with the netpolling mechanism by a code path
-// that eventually calls runtime·netpollopen. runtime·netpollopen
-// calls port_associate with an empty event set. That means that we
-// will not receive any events at this point. The association needs
-// to be done at this early point because we need to process the I/O
-// readiness notification at some point in the future. If I/O becomes
-// ready when nobody is listening, when we finally care about it,
-// nobody will tell us anymore.
-// 
-// Beside calling runtime·netpollopen, the networking code paths
-// will call runtime·netpollarm each time goroutines are interested
-// in doing network I/O. Because now we know what kind of I/O we
-// are interested in (reading/writting), we can call port_associate
-// passing the correct type of event set (POLLIN/POLLOUT). As we made
-// sure to have already associated the file descriptor with the port,
-// when we now call port_associate, we will unblock the main poller
-// loop (in runtime·netpoll) right away if the socket is actually
-// ready for I/O.
-// 
-// The main poller loop runs in its own thread waiting for events
-// using port_getn. When an event happens, it will tell the scheduler
-// about it using runtime·netpollready. Besides doing this, it must
-// also re-associate the events that were not part of this current
-// notification with the file descriptor. Failing to do this would
-// mean each notification will prevent concurrent code using the
-// same file descriptor in parallel.
-// 
-// The logic dealing with re-associations is encapsulated in
-// runtime·netpollupdate. This function takes care to associate the
-// descriptor only with the subset of events that were previously
-// part of the association, except the one that just happened. We
-// can't re-associate with that right away, because event ports
-// are level triggered so it would cause a busy loop. Instead, that
-// association is effected only by the runtime·netpollarm code path,
-// when Go code actually asks for I/O.
-// 
-// The open and arming mechanisms are serialized using the lock
-// inside PollDesc. This is required because the netpoll loop runs
-// asynchonously in respect to other Go code and by the time we get
-// to call port_associate to update the association in the loop, the
-// file descriptor might have been closed and reopened already. The
-// lock allows runtime·netpollupdate to be called synchronously from
-// the loop thread while preventing other threads operating to the
-// same PollDesc, so once we unblock in the main loop, until we loop
-// again we know for sure we are always talking about the same file
-// descriptor and can safely access the data we want (the event set).
-
-#pragma dynimport libc·fcntl fcntl "libc.so"
-#pragma dynimport libc·port_create port_create "libc.so"
-#pragma dynimport libc·port_associate port_associate "libc.so"
-#pragma dynimport libc·port_dissociate port_dissociate "libc.so"
-#pragma dynimport libc·port_getn port_getn "libc.so"
-extern uintptr libc·fcntl;
-extern uintptr libc·port_create;
-extern uintptr libc·port_associate;
-extern uintptr libc·port_dissociate;
-extern uintptr libc·port_getn;
-
-#define errno (*m->perrno)
-
-int32
-runtime·fcntl(int32 fd, int32 cmd, uintptr arg)
-{
-	return runtime·sysvicall6(libc·fcntl, 3,
-	    (uintptr)fd, (uintptr)cmd, (uintptr)arg);
-}
-
-int32
-runtime·port_create(void)
-{
-	return runtime·sysvicall6(libc·port_create, 0);
-}
-
-int32
-runtime·port_associate(int32 port, int32 source, uintptr object, int32 events, uintptr user)
-{
-	return runtime·sysvicall6(libc·port_associate,
-	    5, (uintptr)port, (uintptr)source, object, (uintptr)events, user);
-}
-
-int32
-runtime·port_dissociate(int32 port, int32 source, uintptr object)
-{
-	return runtime·sysvicall6(libc·port_dissociate,
-	    3, (uintptr)port, (uintptr)source, object);
-}
-
-int32
-runtime·port_getn(int32 port, PortEvent *evs, uint32 max, uint32 *nget, Timespec *timeout)
-{
-	return runtime·sysvicall6(libc·port_getn, 5, (uintptr)port,
-	    (uintptr)evs, (uintptr)max, (uintptr)nget, (uintptr)timeout);
-}
-
-static int32 portfd = -1;
-
-void
-runtime·netpollinit(void)
-{
-	if((portfd = runtime·port_create()) >= 0) {
-		runtime·fcntl(portfd, F_SETFD, FD_CLOEXEC);
-		return;
-	}
-
-	runtime·printf("netpollinit: failed to create port (%d)\n", errno);
-	runtime·throw("netpollinit: failed to create port");
-}
-
-int32
-runtime·netpollopen(uintptr fd, PollDesc *pd)
-{
-	int32 r;
-
-	runtime·netpolllock(pd);
-	// We don't register for any specific type of events yet, that's
-	// netpollarm's job. We merely ensure we call port_associate before
-	// asynchonous connect/accept completes, so when we actually want
-	// to do any I/O, the call to port_associate (from netpollarm,
-	// with the interested event set) will unblock port_getn right away
-	// because of the I/O readiness notification.
-	*runtime·netpolluser(pd) = 0;
-	r = runtime·port_associate(portfd, PORT_SOURCE_FD, fd, 0, (uintptr)pd);
-	runtime·netpollunlock(pd);
-	return r;
-}
-
-int32
-runtime·netpollclose(uintptr fd)
-{
-	return runtime·port_dissociate(portfd, PORT_SOURCE_FD, fd);
-}
-
-// Updates the association with a new set of interested events. After
-// this call, port_getn will return one and only one event for that
-// particular descriptor, so this function needs to be called again.
-void
-runtime·netpollupdate(PollDesc* pd, uint32 set, uint32 clear)
-{
-	uint32 *ep, old, events;
-	uintptr fd = runtime·netpollfd(pd);
-	ep = (uint32*)runtime·netpolluser(pd);
-
-	if(runtime·netpollclosing(pd))
-		return;
-
-	old = *ep;
-	events = (old & ~clear) | set;
-	if(old == events)
-		return;
-
-	if(events && runtime·port_associate(portfd, PORT_SOURCE_FD, fd, events, (uintptr)pd) != 0) {
-		runtime·printf("netpollupdate: failed to associate (%d)\n", errno);
-		runtime·throw("netpollupdate: failed to associate");
-	} 
-	*ep = events;
-}
-
-// subscribe the fd to the port such that port_getn will return one event.
-void
-runtime·netpollarm(PollDesc* pd, int32 mode)
-{
-	runtime·netpolllock(pd);
-	switch(mode) {
-	case 'r':
-		runtime·netpollupdate(pd, POLLIN, 0);
-		break;
-	case 'w':
-		runtime·netpollupdate(pd, POLLOUT, 0);
-		break;
-	default:
-		runtime·throw("netpollarm: bad mode");
-	}
-	runtime·netpollunlock(pd);
-}
-
-// polls for ready network connections
-// returns list of goroutines that become runnable
-G*
-runtime·netpoll(bool block)
-{
-	static int32 lasterr;
-	PortEvent events[128], *ev;
-	PollDesc *pd;
-	int32 i, mode, clear;
-	uint32 n;
-	Timespec *wait = nil, zero;
-	G *gp;
-
-	if(portfd == -1)
-		return (nil);
-
-	if(!block) {
-		zero.tv_sec = 0;
-		zero.tv_nsec = 0;
-		wait = &zero;
-	}
-
-retry:
-	n = 1;
-	if(runtime·port_getn(portfd, events, nelem(events), &n, wait) < 0) {
-		if(errno != EINTR && errno != lasterr) {
-			lasterr = errno;
-			runtime·printf("runtime: port_getn on fd %d failed with %d\n", portfd, errno);
-		}
-		goto retry;
-	}
-
-	gp = nil;
-	for(i = 0; i < n; i++) {
-		ev = &events[i];
-
-		if(ev->portev_events == 0)
-			continue;
-		pd = (PollDesc *)ev->portev_user;
-
-		mode = 0;
-		clear = 0;
-		if(ev->portev_events & (POLLIN|POLLHUP|POLLERR)) {
-			mode += 'r';
-			clear |= POLLIN;
-		}
-		if(ev->portev_events & (POLLOUT|POLLHUP|POLLERR)) {
-			mode += 'w';
-			clear |= POLLOUT;
-		}
-		// To effect edge-triggered events, we need to be sure to
-		// update our association with whatever events were not
-		// set with the event. For example if we are registered
-		// for POLLIN|POLLOUT, and we get POLLIN, besides waking
-		// the goroutine interested in POLLIN we have to not forget
-		// about the one interested in POLLOUT.
-		if(clear != 0) {
-			runtime·netpolllock(pd);
-			runtime·netpollupdate(pd, 0, clear);
-			runtime·netpollunlock(pd);
-		}
-
-		if(mode)
-			runtime·netpollready(&gp, pd, mode);
-	}
-
-	if(block && gp == nil)
-		goto retry;
-	return gp;
-}
diff --git a/src/pkg/runtime/netpoll_windows.c b/src/pkg/runtime/netpoll_windows.c
deleted file mode 100644
index f3cd15c..0000000
--- a/src/pkg/runtime/netpoll_windows.c
+++ /dev/null
@@ -1,163 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "runtime.h"
-#include "defs_GOOS_GOARCH.h"
-#include "os_GOOS.h"
-
-#define DWORD_MAX 0xffffffff
-
-#pragma dynimport runtime·CreateIoCompletionPort CreateIoCompletionPort "kernel32.dll"
-#pragma dynimport runtime·GetQueuedCompletionStatus GetQueuedCompletionStatus "kernel32.dll"
-#pragma dynimport runtime·WSAGetOverlappedResult WSAGetOverlappedResult "ws2_32.dll"
-
-extern void *runtime·CreateIoCompletionPort;
-extern void *runtime·GetQueuedCompletionStatus;
-extern void *runtime·WSAGetOverlappedResult;
-
-#define INVALID_HANDLE_VALUE ((uintptr)-1)
-
-// net_op must be the same as beginning of net.operation. Keep these in sync.
-typedef struct net_op net_op;
-struct net_op
-{
-	// used by windows
-	Overlapped	o;
-	// used by netpoll
-	PollDesc*	pd;
-	int32	mode;
-	int32	errno;
-	uint32	qty;
-};
-
-typedef struct OverlappedEntry OverlappedEntry;
-struct OverlappedEntry
-{
-	uintptr	key;
-	net_op*	op;  // In reality it's Overlapped*, but we cast it to net_op* anyway.
-	uintptr	internal;
-	uint32	qty;
-};
-
-static void handlecompletion(G **gpp, net_op *o, int32 errno, uint32 qty);
-
-static uintptr iocphandle = INVALID_HANDLE_VALUE;  // completion port io handle
-
-void
-runtime·netpollinit(void)
-{
-	iocphandle = (uintptr)runtime·stdcall(runtime·CreateIoCompletionPort, 4, INVALID_HANDLE_VALUE, (uintptr)0, (uintptr)0, (uintptr)DWORD_MAX);
-	if(iocphandle == 0) {
-		runtime·printf("netpoll: failed to create iocp handle (errno=%d)\n", runtime·getlasterror());
-		runtime·throw("netpoll: failed to create iocp handle");
-	}
-	return;
-}
-
-int32
-runtime·netpollopen(uintptr fd, PollDesc *pd)
-{
-	USED(pd);
-	if(runtime·stdcall(runtime·CreateIoCompletionPort, 4, fd, iocphandle, (uintptr)0, (uintptr)0) == 0)
-		return -runtime·getlasterror();
-	return 0;
-}
-
-int32
-runtime·netpollclose(uintptr fd)
-{
-	// nothing to do
-	USED(fd);
-	return 0;
-}
-
-void
-runtime·netpollarm(PollDesc* pd, int32 mode)
-{
-	USED(pd, mode);
-	runtime·throw("unused");
-}
-
-// Polls for completed network IO.
-// Returns list of goroutines that become runnable.
-G*
-runtime·netpoll(bool block)
-{
-	OverlappedEntry entries[64];
-	uint32 wait, qty, key, flags, n, i;
-	int32 errno;
-	net_op *op;
-	G *gp;
-
-	if(iocphandle == INVALID_HANDLE_VALUE)
-		return nil;
-	gp = nil;
-	wait = 0;
-	if(block)
-		wait = INFINITE;
-retry:
-	if(runtime·GetQueuedCompletionStatusEx != nil) {
-		n = nelem(entries) / runtime·gomaxprocs;
-		if(n < 8)
-			n = 8;
-		if(block)
-			m->blocked = true;
-		if(runtime·stdcall(runtime·GetQueuedCompletionStatusEx, 6, iocphandle, entries, (uintptr)n, &n, (uintptr)wait, (uintptr)0) == 0) {
-			m->blocked = false;
-			errno = runtime·getlasterror();
-			if(!block && errno == WAIT_TIMEOUT)
-				return nil;
-			runtime·printf("netpoll: GetQueuedCompletionStatusEx failed (errno=%d)\n", errno);
-			runtime·throw("netpoll: GetQueuedCompletionStatusEx failed");
-		}
-		m->blocked = false;
-		for(i = 0; i < n; i++) {
-			op = entries[i].op;
-			errno = 0;
-			qty = 0;
-			if(runtime·stdcall(runtime·WSAGetOverlappedResult, 5, runtime·netpollfd(op->pd), op, &qty, (uintptr)0, (uintptr)&flags) == 0)
-				errno = runtime·getlasterror();
-			handlecompletion(&gp, op, errno, qty);
-		}
-	} else {
-		op = nil;
-		errno = 0;
-		qty = 0;
-		if(block)
-			m->blocked = true;
-		if(runtime·stdcall(runtime·GetQueuedCompletionStatus, 5, iocphandle, &qty, &key, &op, (uintptr)wait) == 0) {
-			m->blocked = false;
-			errno = runtime·getlasterror();
-			if(!block && errno == WAIT_TIMEOUT)
-				return nil;
-			if(op == nil) {
-				runtime·printf("netpoll: GetQueuedCompletionStatus failed (errno=%d)\n", errno);
-				runtime·throw("netpoll: GetQueuedCompletionStatus failed");
-			}
-			// dequeued failed IO packet, so report that
-		}
-		m->blocked = false;
-		handlecompletion(&gp, op, errno, qty);
-	}
-	if(block && gp == nil)
-		goto retry;
-	return gp;
-}
-
-static void
-handlecompletion(G **gpp, net_op *op, int32 errno, uint32 qty)
-{
-	int32 mode;
-
-	if(op == nil)
-		runtime·throw("netpoll: GetQueuedCompletionStatus returned op == nil");
-	mode = op->mode;
-	if(mode != 'r' && mode != 'w') {
-		runtime·printf("netpoll: GetQueuedCompletionStatus returned invalid mode=%d\n", mode);
-		runtime·throw("netpoll: GetQueuedCompletionStatus returned invalid mode");
-	}
-	op->errno = errno;
-	op->qty = qty;
-	runtime·netpollready(gpp, op->pd, mode);
-}
diff --git a/src/pkg/runtime/noasm_arm.goc b/src/pkg/runtime/noasm_arm.goc
deleted file mode 100644
index fe3591e..0000000
--- a/src/pkg/runtime/noasm_arm.goc
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Routines that are implemented in assembly in asm_{amd64,386}.s
-// but are implemented in C for arm.
-
-package runtime
-#include "runtime.h"
-#include "../../cmd/ld/textflag.h"
-
-#pragma textflag NOSPLIT
-func cmpstring(s1 String, s2 String) (v int) {
-	uintgo i, l;
-	byte c1, c2;
-	
-	l = s1.len;
-        if(s2.len < l)
-		l = s2.len;
-        for(i=0; i<l; i++) {
-		c1 = s1.str[i];
-		c2 = s2.str[i];
-		if(c1 < c2) {
-			v = -1;
-			goto done;
-		}
-		if(c1 > c2) {
-			v = +1;
-			goto done;
-		}
-	}
-        if(s1.len < s2.len) {
-		v = -1;
-		goto done;
-	}
-        if(s1.len > s2.len) {
-		v = +1;
-		goto done;
-	}
-        v = 0;
- done:;
-}
-
-#pragma textflag NOSPLIT
-func bytes·Compare(s1 Slice, s2 Slice) (v int) {
-	uintgo i, l;
-	byte c1, c2;
-	
-	l = s1.len;
-        if(s2.len < l)
-		l = s2.len;
-        for(i=0; i<l; i++) {
-		c1 = s1.array[i];
-		c2 = s2.array[i];
-		if(c1 < c2) {
-			v = -1;
-			goto done;
-		}
-		if(c1 > c2) {
-			v = +1;
-			goto done;
-		}
-	}
-        if(s1.len < s2.len) {
-		v = -1;
-		goto done;
-	}
-	if(s1.len > s2.len) {
-		v = +1;
-		goto done;
-	}
-	v = 0;
- done:;
-}
diff --git a/src/pkg/runtime/os_darwin.c b/src/pkg/runtime/os_darwin.c
deleted file mode 100644
index 33a2df9..0000000
--- a/src/pkg/runtime/os_darwin.c
+++ /dev/null
@@ -1,529 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "runtime.h"
-#include "defs_GOOS_GOARCH.h"
-#include "os_GOOS.h"
-#include "signal_unix.h"
-#include "stack.h"
-#include "../../cmd/ld/textflag.h"
-
-extern SigTab runtime·sigtab[];
-
-static Sigset sigset_none;
-static Sigset sigset_all = ~(Sigset)0;
-
-static void
-unimplemented(int8 *name)
-{
-	runtime·prints(name);
-	runtime·prints(" not implemented\n");
-	*(int32*)1231 = 1231;
-}
-
-void
-runtime·semawakeup(M *mp)
-{
-	runtime·mach_semrelease(mp->waitsema);
-}
-
-uintptr
-runtime·semacreate(void)
-{
-	return runtime·mach_semcreate();
-}
-
-// BSD interface for threading.
-void
-runtime·osinit(void)
-{
-	// bsdthread_register delayed until end of goenvs so that we
-	// can look at the environment first.
-
-	// Use sysctl to fetch hw.ncpu.
-	uint32 mib[2];
-	uint32 out;
-	int32 ret;
-	uintptr nout;
-
-	mib[0] = 6;
-	mib[1] = 3;
-	nout = sizeof out;
-	out = 0;
-	ret = runtime·sysctl(mib, 2, (byte*)&out, &nout, nil, 0);
-	if(ret >= 0)
-		runtime·ncpu = out;
-}
-
-void
-runtime·get_random_data(byte **rnd, int32 *rnd_len)
-{
-	#pragma dataflag NOPTR
-	static byte urandom_data[HashRandomBytes];
-	int32 fd;
-	fd = runtime·open("/dev/urandom", 0 /* O_RDONLY */, 0);
-	if(runtime·read(fd, urandom_data, HashRandomBytes) == HashRandomBytes) {
-		*rnd = urandom_data;
-		*rnd_len = HashRandomBytes;
-	} else {
-		*rnd = nil;
-		*rnd_len = 0;
-	}
-	runtime·close(fd);
-}
-
-void
-runtime·goenvs(void)
-{
-	runtime·goenvs_unix();
-
-	// Register our thread-creation callback (see sys_darwin_{amd64,386}.s)
-	// but only if we're not using cgo.  If we are using cgo we need
-	// to let the C pthread library install its own thread-creation callback.
-	if(!runtime·iscgo) {
-		if(runtime·bsdthread_register() != 0) {
-			if(runtime·getenv("DYLD_INSERT_LIBRARIES"))
-				runtime·throw("runtime: bsdthread_register error (unset DYLD_INSERT_LIBRARIES)");
-			runtime·throw("runtime: bsdthread_register error");
-		}
-	}
-
-}
-
-void
-runtime·newosproc(M *mp, void *stk)
-{
-	int32 errno;
-	Sigset oset;
-
-	mp->tls[0] = mp->id;	// so 386 asm can find it
-	if(0){
-		runtime·printf("newosproc stk=%p m=%p g=%p id=%d/%d ostk=%p\n",
-			stk, mp, mp->g0, mp->id, (int32)mp->tls[0], &mp);
-	}
-
-	runtime·sigprocmask(SIG_SETMASK, &sigset_all, &oset);
-	errno = runtime·bsdthread_create(stk, mp, mp->g0, runtime·mstart);
-	runtime·sigprocmask(SIG_SETMASK, &oset, nil);
-
-	if(errno < 0) {
-		runtime·printf("runtime: failed to create new OS thread (have %d already; errno=%d)\n", runtime·mcount(), -errno);
-		runtime·throw("runtime.newosproc");
-	}
-}
-
-// Called to initialize a new m (including the bootstrap m).
-// Called on the parent thread (main thread in case of bootstrap), can allocate memory.
-void
-runtime·mpreinit(M *mp)
-{
-	mp->gsignal = runtime·malg(32*1024);	// OS X wants >=8K, Linux >=2K
-}
-
-// Called to initialize a new m (including the bootstrap m).
-// Called on the new thread, can not allocate memory.
-void
-runtime·minit(void)
-{
-	// Initialize signal handling.
-	runtime·signalstack((byte*)m->gsignal->stackguard - StackGuard, 32*1024);
-
-	runtime·sigprocmask(SIG_SETMASK, &sigset_none, nil);
-}
-
-// Called from dropm to undo the effect of an minit.
-void
-runtime·unminit(void)
-{
-	runtime·signalstack(nil, 0);
-}
-
-// Mach IPC, to get at semaphores
-// Definitions are in /usr/include/mach on a Mac.
-
-#pragma textflag NOSPLIT
-static void
-macherror(int32 r, int8 *fn)
-{
-	runtime·prints("mach error ");
-	runtime·prints(fn);
-	runtime·prints(": ");
-	runtime·printint(r);
-	runtime·prints("\n");
-	runtime·throw("mach error");
-}
-
-enum
-{
-	DebugMach = 0
-};
-
-static MachNDR zerondr;
-
-#define MACH_MSGH_BITS(a, b) ((a) | ((b)<<8))
-
-static int32
-mach_msg(MachHeader *h,
-	int32 op,
-	uint32 send_size,
-	uint32 rcv_size,
-	uint32 rcv_name,
-	uint32 timeout,
-	uint32 notify)
-{
-	// TODO: Loop on interrupt.
-	return runtime·mach_msg_trap(h, op, send_size, rcv_size, rcv_name, timeout, notify);
-}
-
-// Mach RPC (MIG)
-
-enum
-{
-	MinMachMsg = 48,
-	Reply = 100,
-};
-
-#pragma pack on
-typedef struct CodeMsg CodeMsg;
-struct CodeMsg
-{
-	MachHeader h;
-	MachNDR NDR;
-	int32 code;
-};
-#pragma pack off
-
-static int32
-machcall(MachHeader *h, int32 maxsize, int32 rxsize)
-{
-	uint32 *p;
-	int32 i, ret, id;
-	uint32 port;
-	CodeMsg *c;
-
-	if((port = m->machport) == 0){
-		port = runtime·mach_reply_port();
-		m->machport = port;
-	}
-
-	h->msgh_bits |= MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, MACH_MSG_TYPE_MAKE_SEND_ONCE);
-	h->msgh_local_port = port;
-	h->msgh_reserved = 0;
-	id = h->msgh_id;
-
-	if(DebugMach){
-		p = (uint32*)h;
-		runtime·prints("send:\t");
-		for(i=0; i<h->msgh_size/sizeof(p[0]); i++){
-			runtime·prints(" ");
-			runtime·printpointer((void*)p[i]);
-			if(i%8 == 7)
-				runtime·prints("\n\t");
-		}
-		if(i%8)
-			runtime·prints("\n");
-	}
-
-	ret = mach_msg(h, MACH_SEND_MSG|MACH_RCV_MSG,
-		h->msgh_size, maxsize, port, 0, 0);
-	if(ret != 0){
-		if(DebugMach){
-			runtime·prints("mach_msg error ");
-			runtime·printint(ret);
-			runtime·prints("\n");
-		}
-		return ret;
-	}
-
-	if(DebugMach){
-		p = (uint32*)h;
-		runtime·prints("recv:\t");
-		for(i=0; i<h->msgh_size/sizeof(p[0]); i++){
-			runtime·prints(" ");
-			runtime·printpointer((void*)p[i]);
-			if(i%8 == 7)
-				runtime·prints("\n\t");
-		}
-		if(i%8)
-			runtime·prints("\n");
-	}
-
-	if(h->msgh_id != id+Reply){
-		if(DebugMach){
-			runtime·prints("mach_msg reply id mismatch ");
-			runtime·printint(h->msgh_id);
-			runtime·prints(" != ");
-			runtime·printint(id+Reply);
-			runtime·prints("\n");
-		}
-		return -303;	// MIG_REPLY_MISMATCH
-	}
-
-	// Look for a response giving the return value.
-	// Any call can send this back with an error,
-	// and some calls only have return values so they
-	// send it back on success too.  I don't quite see how
-	// you know it's one of these and not the full response
-	// format, so just look if the message is right.
-	c = (CodeMsg*)h;
-	if(h->msgh_size == sizeof(CodeMsg)
-	&& !(h->msgh_bits & MACH_MSGH_BITS_COMPLEX)){
-		if(DebugMach){
-			runtime·prints("mig result ");
-			runtime·printint(c->code);
-			runtime·prints("\n");
-		}
-		return c->code;
-	}
-
-	if(h->msgh_size != rxsize){
-		if(DebugMach){
-			runtime·prints("mach_msg reply size mismatch ");
-			runtime·printint(h->msgh_size);
-			runtime·prints(" != ");
-			runtime·printint(rxsize);
-			runtime·prints("\n");
-		}
-		return -307;	// MIG_ARRAY_TOO_LARGE
-	}
-
-	return 0;
-}
-
-
-// Semaphores!
-
-enum
-{
-	Tmach_semcreate = 3418,
-	Rmach_semcreate = Tmach_semcreate + Reply,
-
-	Tmach_semdestroy = 3419,
-	Rmach_semdestroy = Tmach_semdestroy + Reply,
-
-	// Mach calls that get interrupted by Unix signals
-	// return this error code.  We retry them.
-	KERN_ABORTED = 14,
-	KERN_OPERATION_TIMED_OUT = 49,
-};
-
-typedef struct Tmach_semcreateMsg Tmach_semcreateMsg;
-typedef struct Rmach_semcreateMsg Rmach_semcreateMsg;
-typedef struct Tmach_semdestroyMsg Tmach_semdestroyMsg;
-// Rmach_semdestroyMsg = CodeMsg
-
-#pragma pack on
-struct Tmach_semcreateMsg
-{
-	MachHeader h;
-	MachNDR ndr;
-	int32 policy;
-	int32 value;
-};
-
-struct Rmach_semcreateMsg
-{
-	MachHeader h;
-	MachBody body;
-	MachPort semaphore;
-};
-
-struct Tmach_semdestroyMsg
-{
-	MachHeader h;
-	MachBody body;
-	MachPort semaphore;
-};
-#pragma pack off
-
-uint32
-runtime·mach_semcreate(void)
-{
-	union {
-		Tmach_semcreateMsg tx;
-		Rmach_semcreateMsg rx;
-		uint8 pad[MinMachMsg];
-	} m;
-	int32 r;
-
-	m.tx.h.msgh_bits = 0;
-	m.tx.h.msgh_size = sizeof(m.tx);
-	m.tx.h.msgh_remote_port = runtime·mach_task_self();
-	m.tx.h.msgh_id = Tmach_semcreate;
-	m.tx.ndr = zerondr;
-
-	m.tx.policy = 0;	// 0 = SYNC_POLICY_FIFO
-	m.tx.value = 0;
-
-	while((r = machcall(&m.tx.h, sizeof m, sizeof(m.rx))) != 0){
-		if(r == KERN_ABORTED)	// interrupted
-			continue;
-		macherror(r, "semaphore_create");
-	}
-	if(m.rx.body.msgh_descriptor_count != 1)
-		unimplemented("mach_semcreate desc count");
-	return m.rx.semaphore.name;
-}
-
-void
-runtime·mach_semdestroy(uint32 sem)
-{
-	union {
-		Tmach_semdestroyMsg tx;
-		uint8 pad[MinMachMsg];
-	} m;
-	int32 r;
-
-	m.tx.h.msgh_bits = MACH_MSGH_BITS_COMPLEX;
-	m.tx.h.msgh_size = sizeof(m.tx);
-	m.tx.h.msgh_remote_port = runtime·mach_task_self();
-	m.tx.h.msgh_id = Tmach_semdestroy;
-	m.tx.body.msgh_descriptor_count = 1;
-	m.tx.semaphore.name = sem;
-	m.tx.semaphore.disposition = MACH_MSG_TYPE_MOVE_SEND;
-	m.tx.semaphore.type = 0;
-
-	while((r = machcall(&m.tx.h, sizeof m, 0)) != 0){
-		if(r == KERN_ABORTED)	// interrupted
-			continue;
-		macherror(r, "semaphore_destroy");
-	}
-}
-
-// The other calls have simple system call traps in sys_darwin_{amd64,386}.s
-int32 runtime·mach_semaphore_wait(uint32 sema);
-int32 runtime·mach_semaphore_timedwait(uint32 sema, uint32 sec, uint32 nsec);
-int32 runtime·mach_semaphore_signal(uint32 sema);
-int32 runtime·mach_semaphore_signal_all(uint32 sema);
-
-#pragma textflag NOSPLIT
-int32
-runtime·semasleep(int64 ns)
-{
-	int32 r, secs, nsecs;
-
-	if(ns >= 0) {
-		secs = runtime·timediv(ns, 1000000000, &nsecs);
-		r = runtime·mach_semaphore_timedwait(m->waitsema, secs, nsecs);
-		if(r == KERN_ABORTED || r == KERN_OPERATION_TIMED_OUT)
-			return -1;
-		if(r != 0)
-			macherror(r, "semaphore_wait");
-		return 0;
-	}
-	while((r = runtime·mach_semaphore_wait(m->waitsema)) != 0) {
-		if(r == KERN_ABORTED)	// interrupted
-			continue;
-		macherror(r, "semaphore_wait");
-	}
-	return 0;
-}
-
-void
-runtime·mach_semrelease(uint32 sem)
-{
-	int32 r;
-
-	while((r = runtime·mach_semaphore_signal(sem)) != 0) {
-		if(r == KERN_ABORTED)	// interrupted
-			continue;
-		macherror(r, "semaphore_signal");
-	}
-}
-
-void
-runtime·sigpanic(void)
-{
-	if(!runtime·canpanic(g))
-		runtime·throw("unexpected signal during runtime execution");
-
-	switch(g->sig) {
-	case SIGBUS:
-		if(g->sigcode0 == BUS_ADRERR && g->sigcode1 < 0x1000 || g->paniconfault) {
-			if(g->sigpc == 0)
-				runtime·panicstring("call of nil func value");
-			runtime·panicstring("invalid memory address or nil pointer dereference");
-		}
-		runtime·printf("unexpected fault address %p\n", g->sigcode1);
-		runtime·throw("fault");
-	case SIGSEGV:
-		if((g->sigcode0 == 0 || g->sigcode0 == SEGV_MAPERR || g->sigcode0 == SEGV_ACCERR) && g->sigcode1 < 0x1000 || g->paniconfault) {
-			if(g->sigpc == 0)
-				runtime·panicstring("call of nil func value");
-			runtime·panicstring("invalid memory address or nil pointer dereference");
-		}
-		runtime·printf("unexpected fault address %p\n", g->sigcode1);
-		runtime·throw("fault");
-	case SIGFPE:
-		switch(g->sigcode0) {
-		case FPE_INTDIV:
-			runtime·panicstring("integer divide by zero");
-		case FPE_INTOVF:
-			runtime·panicstring("integer overflow");
-		}
-		runtime·panicstring("floating point error");
-	}
-	runtime·panicstring(runtime·sigtab[g->sig].name);
-}
-
-#pragma textflag NOSPLIT
-void
-runtime·osyield(void)
-{
-	runtime·usleep(1);
-}
-
-uintptr
-runtime·memlimit(void)
-{
-	// NOTE(rsc): Could use getrlimit here,
-	// like on FreeBSD or Linux, but Darwin doesn't enforce
-	// ulimit -v, so it's unclear why we'd try to stay within
-	// the limit.
-	return 0;
-}
-
-void
-runtime·setsig(int32 i, GoSighandler *fn, bool restart)
-{
-	Sigaction sa;
-		
-	runtime·memclr((byte*)&sa, sizeof sa);
-	sa.sa_flags = SA_SIGINFO|SA_ONSTACK;
-	if(restart)
-		sa.sa_flags |= SA_RESTART;
-	sa.sa_mask = ~(uintptr)0;
-	sa.sa_tramp = (void*)runtime·sigtramp;	// runtime·sigtramp's job is to call into real handler
-	*(uintptr*)sa.__sigaction_u = (uintptr)fn;
-	runtime·sigaction(i, &sa, nil);
-}
-
-GoSighandler*
-runtime·getsig(int32 i)
-{
-	Sigaction sa;
-
-	runtime·memclr((byte*)&sa, sizeof sa);
-	runtime·sigaction(i, nil, &sa);
-	return *(void**)sa.__sigaction_u;
-}
-
-void
-runtime·signalstack(byte *p, int32 n)
-{
-	StackT st;
-
-	st.ss_sp = (void*)p;
-	st.ss_size = n;
-	st.ss_flags = 0;
-	if(p == nil)
-		st.ss_flags = SS_DISABLE;
-	runtime·sigaltstack(&st, nil);
-}
-
-void
-runtime·unblocksignals(void)
-{
-	runtime·sigprocmask(SIG_SETMASK, &sigset_none, nil);
-}
diff --git a/src/pkg/runtime/os_darwin.h b/src/pkg/runtime/os_darwin.h
deleted file mode 100644
index 91a405f..0000000
--- a/src/pkg/runtime/os_darwin.h
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#define SS_DISABLE 4
-
-typedef byte* kevent_udata;
-
-int32	runtime·bsdthread_create(void*, M*, G*, void(*)(void));
-int32	runtime·bsdthread_register(void);
-int32	runtime·mach_msg_trap(MachHeader*, int32, uint32, uint32, uint32, uint32, uint32);
-uint32	runtime·mach_reply_port(void);
-int32	runtime·mach_semacquire(uint32, int64);
-uint32	runtime·mach_semcreate(void);
-void	runtime·mach_semdestroy(uint32);
-void	runtime·mach_semrelease(uint32);
-void	runtime·mach_semreset(uint32);
-uint32	runtime·mach_task_self(void);
-uint32	runtime·mach_task_self(void);
-uint32	runtime·mach_thread_self(void);
-uint32	runtime·mach_thread_self(void);
-int32	runtime·sysctl(uint32*, uint32, byte*, uintptr*, byte*, uintptr);
-
-typedef uint32 Sigset;
-void	runtime·sigprocmask(int32, Sigset*, Sigset*);
-void	runtime·unblocksignals(void);
-
-struct Sigaction;
-void	runtime·sigaction(uintptr, struct Sigaction*, struct Sigaction*);
-
-struct StackT;
-void	runtime·sigaltstack(struct StackT*, struct StackT*);
-void	runtime·sigtramp(void);
-void	runtime·sigpanic(void);
-void	runtime·setitimer(int32, Itimerval*, Itimerval*);
-
-
-#define	NSIG 32
-#define	SI_USER	0  /* empirically true, but not what headers say */
-#define	SIG_BLOCK 1
-#define	SIG_UNBLOCK 2
-#define	SIG_SETMASK 3
diff --git a/src/pkg/runtime/os_dragonfly.c b/src/pkg/runtime/os_dragonfly.c
deleted file mode 100644
index e7fd2cc..0000000
--- a/src/pkg/runtime/os_dragonfly.c
+++ /dev/null
@@ -1,292 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "runtime.h"
-#include "defs_GOOS_GOARCH.h"
-#include "os_GOOS.h"
-#include "signal_unix.h"
-#include "stack.h"
-#include "../../cmd/ld/textflag.h"
-
-extern SigTab runtime·sigtab[];
-extern int32 runtime·sys_umtx_sleep(uint32*, int32, int32);
-extern int32 runtime·sys_umtx_wakeup(uint32*, int32);
-
-// From DragonFly's <sys/sysctl.h>
-#define	CTL_HW	6
-#define	HW_NCPU	3
-
-static Sigset sigset_none;
-static Sigset sigset_all = { ~(uint32)0, ~(uint32)0, ~(uint32)0, ~(uint32)0, };
-
-static int32
-getncpu(void)
-{
-	uint32 mib[2];
-	uint32 out;
-	int32 ret;
-	uintptr nout;
-
-	// Fetch hw.ncpu via sysctl.
-	mib[0] = CTL_HW;
-	mib[1] = HW_NCPU;
-	nout = sizeof out;
-	out = 0;
-	ret = runtime·sysctl(mib, 2, (byte*)&out, &nout, nil, 0);
-	if(ret >= 0)
-		return out;
-	else
-		return 1;
-}
-
-#pragma textflag NOSPLIT
-void
-runtime·futexsleep(uint32 *addr, uint32 val, int64 ns)
-{
-	int32 timeout = 0;
-	int32 ret;
-
-	if(ns >= 0) {
-		// The timeout is specified in microseconds - ensure that we
-		// do not end up dividing to zero, which would put us to sleep
-		// indefinitely...
-		timeout = runtime·timediv(ns, 1000, nil);
-		if(timeout == 0)
-			timeout = 1;
-	}
-
-	// sys_umtx_sleep will return EWOULDBLOCK (EAGAIN) when the timeout
-	// expires or EBUSY if the mutex value does not match. 
-	ret = runtime·sys_umtx_sleep(addr, val, timeout);
-	if(ret >= 0 || ret == -EINTR || ret == -EAGAIN || ret == -EBUSY)
-		return;
-
-	runtime·prints("umtx_wait addr=");
-	runtime·printpointer(addr);
-	runtime·prints(" val=");
-	runtime·printint(val);
-	runtime·prints(" ret=");
-	runtime·printint(ret);
-	runtime·prints("\n");
-	*(int32*)0x1005 = 0x1005;
-}
-
-void
-runtime·futexwakeup(uint32 *addr, uint32 cnt)
-{
-	int32 ret;
-
-	ret = runtime·sys_umtx_wakeup(addr, cnt);
-	if(ret >= 0)
-		return;
-
-	runtime·printf("umtx_wake addr=%p ret=%d\n", addr, ret);
-	*(int32*)0x1006 = 0x1006;
-}
-
-void runtime·lwp_start(void*);
-
-void
-runtime·newosproc(M *mp, void *stk)
-{
-	Lwpparams params;
-	Sigset oset;
-
-	if(0){
-		runtime·printf("newosproc stk=%p m=%p g=%p id=%d/%d ostk=%p\n",
-			stk, mp, mp->g0, mp->id, (int32)mp->tls[0], &mp);
-	}
-
-	runtime·sigprocmask(&sigset_all, &oset);
-	runtime·memclr((byte*)&params, sizeof params);
-
-	params.func = runtime·lwp_start;
-	params.arg = (byte*)mp;
-	params.stack = (byte*)stk;
-	params.tid1 = (int32*)&mp->procid;
-	params.tid2 = nil;
-
-	mp->tls[0] = mp->id;	// so 386 asm can find it
-
-	runtime·lwp_create(&params);
-	runtime·sigprocmask(&oset, nil);
-}
-
-void
-runtime·osinit(void)
-{
-	runtime·ncpu = getncpu();
-}
-
-void
-runtime·get_random_data(byte **rnd, int32 *rnd_len)
-{
-	#pragma dataflag NOPTR
-	static byte urandom_data[HashRandomBytes];
-	int32 fd;
-	fd = runtime·open("/dev/urandom", 0 /* O_RDONLY */, 0);
-	if(runtime·read(fd, urandom_data, HashRandomBytes) == HashRandomBytes) {
-		*rnd = urandom_data;
-		*rnd_len = HashRandomBytes;
-	} else {
-		*rnd = nil;
-		*rnd_len = 0;
-	}
-	runtime·close(fd);
-}
-
-void
-runtime·goenvs(void)
-{
-	runtime·goenvs_unix();
-}
-
-// Called to initialize a new m (including the bootstrap m).
-// Called on the parent thread (main thread in case of bootstrap), can allocate memory.
-void
-runtime·mpreinit(M *mp)
-{
-	mp->gsignal = runtime·malg(32*1024);
-}
-
-// Called to initialize a new m (including the bootstrap m).
-// Called on the new thread, can not allocate memory.
-void
-runtime·minit(void)
-{
-	// Initialize signal handling
-	runtime·signalstack((byte*)m->gsignal->stackguard - StackGuard, 32*1024);
-	runtime·sigprocmask(&sigset_none, nil);
-}
-
-// Called from dropm to undo the effect of an minit.
-void
-runtime·unminit(void)
-{
-	runtime·signalstack(nil, 0);
-}
-
-void
-runtime·sigpanic(void)
-{
-	if(!runtime·canpanic(g))
-		runtime·throw("unexpected signal during runtime execution");
-
-	switch(g->sig) {
-	case SIGBUS:
-		if(g->sigcode0 == BUS_ADRERR && g->sigcode1 < 0x1000 || g->paniconfault) {
-			if(g->sigpc == 0)
-				runtime·panicstring("call of nil func value");
-			runtime·panicstring("invalid memory address or nil pointer dereference");
-		}
-		runtime·printf("unexpected fault address %p\n", g->sigcode1);
-		runtime·throw("fault");
-	case SIGSEGV:
-		if((g->sigcode0 == 0 || g->sigcode0 == SEGV_MAPERR || g->sigcode0 == SEGV_ACCERR) && g->sigcode1 < 0x1000 || g->paniconfault) {
-			if(g->sigpc == 0)
-				runtime·panicstring("call of nil func value");
-			runtime·panicstring("invalid memory address or nil pointer dereference");
-		}
-		runtime·printf("unexpected fault address %p\n", g->sigcode1);
-		runtime·throw("fault");
-	case SIGFPE:
-		switch(g->sigcode0) {
-		case FPE_INTDIV:
-			runtime·panicstring("integer divide by zero");
-		case FPE_INTOVF:
-			runtime·panicstring("integer overflow");
-		}
-		runtime·panicstring("floating point error");
-	}
-	runtime·panicstring(runtime·sigtab[g->sig].name);
-}
-
-uintptr
-runtime·memlimit(void)
-{
-	Rlimit rl;
-	extern byte text[], end[];
-	uintptr used;
-	
-	if(runtime·getrlimit(RLIMIT_AS, &rl) != 0)
-		return 0;
-	if(rl.rlim_cur >= 0x7fffffff)
-		return 0;
-
-	// Estimate our VM footprint excluding the heap.
-	// Not an exact science: use size of binary plus
-	// some room for thread stacks.
-	used = end - text + (64<<20);
-	if(used >= rl.rlim_cur)
-		return 0;
-
-	// If there's not at least 16 MB left, we're probably
-	// not going to be able to do much.  Treat as no limit.
-	rl.rlim_cur -= used;
-	if(rl.rlim_cur < (16<<20))
-		return 0;
-
-	return rl.rlim_cur - used;
-}
-
-extern void runtime·sigtramp(void);
-
-typedef struct sigaction {
-	union {
-		void    (*__sa_handler)(int32);
-		void    (*__sa_sigaction)(int32, Siginfo*, void *);
-	} __sigaction_u;		/* signal handler */
-	int32	sa_flags;		/* see signal options below */
-	Sigset	sa_mask;		/* signal mask to apply */
-} Sigaction;
-
-void
-runtime·setsig(int32 i, GoSighandler *fn, bool restart)
-{
-	Sigaction sa;
-
-	runtime·memclr((byte*)&sa, sizeof sa);
-	sa.sa_flags = SA_SIGINFO|SA_ONSTACK;
-	if(restart)
-		sa.sa_flags |= SA_RESTART;
-	sa.sa_mask.__bits[0] = ~(uint32)0;
-	sa.sa_mask.__bits[1] = ~(uint32)0;
-	sa.sa_mask.__bits[2] = ~(uint32)0;
-	sa.sa_mask.__bits[3] = ~(uint32)0;
-	if(fn == runtime·sighandler)
-		fn = (void*)runtime·sigtramp;
-	sa.__sigaction_u.__sa_sigaction = (void*)fn;
-	runtime·sigaction(i, &sa, nil);
-}
-
-GoSighandler*
-runtime·getsig(int32 i)
-{
-	Sigaction sa;
-
-	runtime·memclr((byte*)&sa, sizeof sa);
-	runtime·sigaction(i, nil, &sa);
-	if((void*)sa.__sigaction_u.__sa_sigaction == runtime·sigtramp)
-		return runtime·sighandler;
-	return (void*)sa.__sigaction_u.__sa_sigaction;
-}
-
-void
-runtime·signalstack(byte *p, int32 n)
-{
-	StackT st;
-
-	st.ss_sp = (void*)p;
-	st.ss_size = n;
-	st.ss_flags = 0;
-	if(p == nil)
-		st.ss_flags = SS_DISABLE;
-	runtime·sigaltstack(&st, nil);
-}
-
-void
-runtime·unblocksignals(void)
-{
-	runtime·sigprocmask(&sigset_none, nil);
-}
diff --git a/src/pkg/runtime/os_dragonfly.h b/src/pkg/runtime/os_dragonfly.h
deleted file mode 100644
index fddeede..0000000
--- a/src/pkg/runtime/os_dragonfly.h
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#define SS_DISABLE 4
-
-typedef byte* kevent_udata;
-
-int32	runtime·lwp_create(Lwpparams*);
-void	runtime·sigpanic(void);
-void	runtime·sigaltstack(Sigaltstack*, Sigaltstack*);
-struct	sigaction;
-void	runtime·sigaction(int32, struct sigaction*, struct sigaction*);
-void	runtime·sigprocmask(Sigset *, Sigset *);
-void	runtime·unblocksignals(void);
-void	runtime·setitimer(int32, Itimerval*, Itimerval*);
-int32	runtime·sysctl(uint32*, uint32, byte*, uintptr*, byte*, uintptr);
-
-
-#define	NSIG 33
-#define	SI_USER	0x10001
-
-#define RLIMIT_AS 10
-typedef struct Rlimit Rlimit;
-struct Rlimit {
-	int64	rlim_cur;
-	int64	rlim_max;
-};
-int32	runtime·getrlimit(int32, Rlimit*);
diff --git a/src/pkg/runtime/os_freebsd.c b/src/pkg/runtime/os_freebsd.c
deleted file mode 100644
index 02b1347..0000000
--- a/src/pkg/runtime/os_freebsd.c
+++ /dev/null
@@ -1,300 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "runtime.h"
-#include "defs_GOOS_GOARCH.h"
-#include "os_GOOS.h"
-#include "signal_unix.h"
-#include "stack.h"
-#include "../../cmd/ld/textflag.h"
-
-extern SigTab runtime·sigtab[];
-extern int32 runtime·sys_umtx_op(uint32*, int32, uint32, void*, void*);
-
-// From FreeBSD's <sys/sysctl.h>
-#define	CTL_HW	6
-#define	HW_NCPU	3
-
-static Sigset sigset_none;
-static Sigset sigset_all = { ~(uint32)0, ~(uint32)0, ~(uint32)0, ~(uint32)0, };
-
-static int32
-getncpu(void)
-{
-	uint32 mib[2];
-	uint32 out;
-	int32 ret;
-	uintptr nout;
-
-	// Fetch hw.ncpu via sysctl.
-	mib[0] = CTL_HW;
-	mib[1] = HW_NCPU;
-	nout = sizeof out;
-	out = 0;
-	ret = runtime·sysctl(mib, 2, (byte*)&out, &nout, nil, 0);
-	if(ret >= 0)
-		return out;
-	else
-		return 1;
-}
-
-// FreeBSD's umtx_op syscall is effectively the same as Linux's futex, and
-// thus the code is largely similar. See linux/thread.c and lock_futex.c for comments.
-
-#pragma textflag NOSPLIT
-void
-runtime·futexsleep(uint32 *addr, uint32 val, int64 ns)
-{
-	int32 ret;
-	Timespec ts;
-
-	if(ns < 0) {
-		ret = runtime·sys_umtx_op(addr, UMTX_OP_WAIT_UINT_PRIVATE, val, nil, nil);
-		if(ret >= 0 || ret == -EINTR)
-			return;
-		goto fail;
-	}
-	// NOTE: tv_nsec is int64 on amd64, so this assumes a little-endian system.
-	ts.tv_nsec = 0;
-	ts.tv_sec = runtime·timediv(ns, 1000000000, (int32*)&ts.tv_nsec);
-	ret = runtime·sys_umtx_op(addr, UMTX_OP_WAIT_UINT_PRIVATE, val, nil, &ts);
-	if(ret >= 0 || ret == -EINTR)
-		return;
-
-fail:
-	runtime·prints("umtx_wait addr=");
-	runtime·printpointer(addr);
-	runtime·prints(" val=");
-	runtime·printint(val);
-	runtime·prints(" ret=");
-	runtime·printint(ret);
-	runtime·prints("\n");
-	*(int32*)0x1005 = 0x1005;
-}
-
-void
-runtime·futexwakeup(uint32 *addr, uint32 cnt)
-{
-	int32 ret;
-
-	ret = runtime·sys_umtx_op(addr, UMTX_OP_WAKE_PRIVATE, cnt, nil, nil);
-	if(ret >= 0)
-		return;
-
-	runtime·printf("umtx_wake addr=%p ret=%d\n", addr, ret);
-	*(int32*)0x1006 = 0x1006;
-}
-
-void runtime·thr_start(void*);
-
-void
-runtime·newosproc(M *mp, void *stk)
-{
-	ThrParam param;
-	Sigset oset;
-
-	if(0){
-		runtime·printf("newosproc stk=%p m=%p g=%p id=%d/%d ostk=%p\n",
-			stk, mp, mp->g0, mp->id, (int32)mp->tls[0], &mp);
-	}
-
-	runtime·sigprocmask(&sigset_all, &oset);
-	runtime·memclr((byte*)&param, sizeof param);
-
-	param.start_func = runtime·thr_start;
-	param.arg = (byte*)mp;
-	
-	// NOTE(rsc): This code is confused. stackbase is the top of the stack
-	// and is equal to stk. However, it's working, so I'm not changing it.
-	param.stack_base = (void*)mp->g0->stackbase;
-	param.stack_size = (byte*)stk - (byte*)mp->g0->stackbase;
-
-	param.child_tid = (intptr*)&mp->procid;
-	param.parent_tid = nil;
-	param.tls_base = (void*)&mp->tls[0];
-	param.tls_size = sizeof mp->tls;
-
-	mp->tls[0] = mp->id;	// so 386 asm can find it
-
-	runtime·thr_new(&param, sizeof param);
-	runtime·sigprocmask(&oset, nil);
-}
-
-void
-runtime·osinit(void)
-{
-	runtime·ncpu = getncpu();
-}
-
-void
-runtime·get_random_data(byte **rnd, int32 *rnd_len)
-{
-	#pragma dataflag NOPTR
-	static byte urandom_data[HashRandomBytes];
-	int32 fd;
-	fd = runtime·open("/dev/urandom", 0 /* O_RDONLY */, 0);
-	if(runtime·read(fd, urandom_data, HashRandomBytes) == HashRandomBytes) {
-		*rnd = urandom_data;
-		*rnd_len = HashRandomBytes;
-	} else {
-		*rnd = nil;
-		*rnd_len = 0;
-	}
-	runtime·close(fd);
-}
-
-void
-runtime·goenvs(void)
-{
-	runtime·goenvs_unix();
-}
-
-// Called to initialize a new m (including the bootstrap m).
-// Called on the parent thread (main thread in case of bootstrap), can allocate memory.
-void
-runtime·mpreinit(M *mp)
-{
-	mp->gsignal = runtime·malg(32*1024);
-}
-
-// Called to initialize a new m (including the bootstrap m).
-// Called on the new thread, can not allocate memory.
-void
-runtime·minit(void)
-{
-	// Initialize signal handling
-	runtime·signalstack((byte*)m->gsignal->stackguard - StackGuard, 32*1024);
-	runtime·sigprocmask(&sigset_none, nil);
-}
-
-// Called from dropm to undo the effect of an minit.
-void
-runtime·unminit(void)
-{
-	runtime·signalstack(nil, 0);
-}
-
-void
-runtime·sigpanic(void)
-{
-	if(!runtime·canpanic(g))
-		runtime·throw("unexpected signal during runtime execution");
-
-	switch(g->sig) {
-	case SIGBUS:
-		if(g->sigcode0 == BUS_ADRERR && g->sigcode1 < 0x1000 || g->paniconfault) {
-			if(g->sigpc == 0)
-				runtime·panicstring("call of nil func value");
-			runtime·panicstring("invalid memory address or nil pointer dereference");
-		}
-		runtime·printf("unexpected fault address %p\n", g->sigcode1);
-		runtime·throw("fault");
-	case SIGSEGV:
-		if((g->sigcode0 == 0 || g->sigcode0 == SEGV_MAPERR || g->sigcode0 == SEGV_ACCERR) && g->sigcode1 < 0x1000 || g->paniconfault) {
-			if(g->sigpc == 0)
-				runtime·panicstring("call of nil func value");
-			runtime·panicstring("invalid memory address or nil pointer dereference");
-		}
-		runtime·printf("unexpected fault address %p\n", g->sigcode1);
-		runtime·throw("fault");
-	case SIGFPE:
-		switch(g->sigcode0) {
-		case FPE_INTDIV:
-			runtime·panicstring("integer divide by zero");
-		case FPE_INTOVF:
-			runtime·panicstring("integer overflow");
-		}
-		runtime·panicstring("floating point error");
-	}
-	runtime·panicstring(runtime·sigtab[g->sig].name);
-}
-
-uintptr
-runtime·memlimit(void)
-{
-	Rlimit rl;
-	extern byte text[], end[];
-	uintptr used;
-	
-	if(runtime·getrlimit(RLIMIT_AS, &rl) != 0)
-		return 0;
-	if(rl.rlim_cur >= 0x7fffffff)
-		return 0;
-
-	// Estimate our VM footprint excluding the heap.
-	// Not an exact science: use size of binary plus
-	// some room for thread stacks.
-	used = end - text + (64<<20);
-	if(used >= rl.rlim_cur)
-		return 0;
-
-	// If there's not at least 16 MB left, we're probably
-	// not going to be able to do much.  Treat as no limit.
-	rl.rlim_cur -= used;
-	if(rl.rlim_cur < (16<<20))
-		return 0;
-
-	return rl.rlim_cur - used;
-}
-
-extern void runtime·sigtramp(void);
-
-typedef struct sigaction {
-	union {
-		void    (*__sa_handler)(int32);
-		void    (*__sa_sigaction)(int32, Siginfo*, void *);
-	} __sigaction_u;		/* signal handler */
-	int32	sa_flags;		/* see signal options below */
-	Sigset	sa_mask;		/* signal mask to apply */
-} Sigaction;
-
-void
-runtime·setsig(int32 i, GoSighandler *fn, bool restart)
-{
-	Sigaction sa;
-
-	runtime·memclr((byte*)&sa, sizeof sa);
-	sa.sa_flags = SA_SIGINFO|SA_ONSTACK;
-	if(restart)
-		sa.sa_flags |= SA_RESTART;
-	sa.sa_mask.__bits[0] = ~(uint32)0;
-	sa.sa_mask.__bits[1] = ~(uint32)0;
-	sa.sa_mask.__bits[2] = ~(uint32)0;
-	sa.sa_mask.__bits[3] = ~(uint32)0;
-	if(fn == runtime·sighandler)
-		fn = (void*)runtime·sigtramp;
-	sa.__sigaction_u.__sa_sigaction = (void*)fn;
-	runtime·sigaction(i, &sa, nil);
-}
-
-GoSighandler*
-runtime·getsig(int32 i)
-{
-	Sigaction sa;
-
-	runtime·memclr((byte*)&sa, sizeof sa);
-	runtime·sigaction(i, nil, &sa);
-	if((void*)sa.__sigaction_u.__sa_sigaction == runtime·sigtramp)
-		return runtime·sighandler;
-	return (void*)sa.__sigaction_u.__sa_sigaction;
-}
-
-void
-runtime·signalstack(byte *p, int32 n)
-{
-	StackT st;
-
-	st.ss_sp = (void*)p;
-	st.ss_size = n;
-	st.ss_flags = 0;
-	if(p == nil)
-		st.ss_flags = SS_DISABLE;
-	runtime·sigaltstack(&st, nil);
-}
-
-void
-runtime·unblocksignals(void)
-{
-	runtime·sigprocmask(&sigset_none, nil);
-}
diff --git a/src/pkg/runtime/os_freebsd.h b/src/pkg/runtime/os_freebsd.h
deleted file mode 100644
index 4b2c253..0000000
--- a/src/pkg/runtime/os_freebsd.h
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#define SS_DISABLE 4
-
-typedef byte* kevent_udata;
-
-int32	runtime·thr_new(ThrParam*, int32);
-void	runtime·sigpanic(void);
-void	runtime·sigaltstack(Sigaltstack*, Sigaltstack*);
-struct	sigaction;
-void	runtime·sigaction(int32, struct sigaction*, struct sigaction*);
-void	runtime·sigprocmask(Sigset *, Sigset *);
-void	runtime·unblocksignals(void);
-void	runtime·setitimer(int32, Itimerval*, Itimerval*);
-int32	runtime·sysctl(uint32*, uint32, byte*, uintptr*, byte*, uintptr);
-
-
-#define	NSIG 33
-#define	SI_USER	0x10001
-
-#define RLIMIT_AS 10
-typedef struct Rlimit Rlimit;
-struct Rlimit {
-	int64	rlim_cur;
-	int64	rlim_max;
-};
-int32	runtime·getrlimit(int32, Rlimit*);
diff --git a/src/pkg/runtime/os_freebsd_arm.c b/src/pkg/runtime/os_freebsd_arm.c
deleted file mode 100644
index 1fa235b..0000000
--- a/src/pkg/runtime/os_freebsd_arm.c
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "runtime.h"
-#include "defs_GOOS_GOARCH.h"
-#include "os_GOOS.h"
-#include "../../cmd/ld/textflag.h"
-
-void
-runtime·checkgoarm(void)
-{
-	// TODO(minux)
-}
-
-#pragma textflag NOSPLIT
-int64
-runtime·cputicks(void)
-{
-	// Currently cputicks() is used in blocking profiler and to seed runtime·fastrand1().
-	// runtime·nanotime() is a poor approximation of CPU ticks that is enough for the profiler.
-	// TODO: need more entropy to better seed fastrand1.
-	return runtime·nanotime();
-}
diff --git a/src/pkg/runtime/os_linux.c b/src/pkg/runtime/os_linux.c
deleted file mode 100644
index 8a94524..0000000
--- a/src/pkg/runtime/os_linux.c
+++ /dev/null
@@ -1,342 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "runtime.h"
-#include "defs_GOOS_GOARCH.h"
-#include "os_GOOS.h"
-#include "signal_unix.h"
-#include "stack.h"
-#include "../../cmd/ld/textflag.h"
-
-extern SigTab runtime·sigtab[];
-
-static Sigset sigset_none;
-static Sigset sigset_all = { ~(uint32)0, ~(uint32)0 };
-
-// Linux futex.
-//
-//	futexsleep(uint32 *addr, uint32 val)
-//	futexwakeup(uint32 *addr)
-//
-// Futexsleep atomically checks if *addr == val and if so, sleeps on addr.
-// Futexwakeup wakes up threads sleeping on addr.
-// Futexsleep is allowed to wake up spuriously.
-
-enum
-{
-	FUTEX_WAIT = 0,
-	FUTEX_WAKE = 1,
-};
-
-// Atomically,
-//	if(*addr == val) sleep
-// Might be woken up spuriously; that's allowed.
-// Don't sleep longer than ns; ns < 0 means forever.
-#pragma textflag NOSPLIT
-void
-runtime·futexsleep(uint32 *addr, uint32 val, int64 ns)
-{
-	Timespec ts;
-
-	// Some Linux kernels have a bug where futex of
-	// FUTEX_WAIT returns an internal error code
-	// as an errno.  Libpthread ignores the return value
-	// here, and so can we: as it says a few lines up,
-	// spurious wakeups are allowed.
-
-	if(ns < 0) {
-		runtime·futex(addr, FUTEX_WAIT, val, nil, nil, 0);
-		return;
-	}
-	// NOTE: tv_nsec is int64 on amd64, so this assumes a little-endian system.
-	ts.tv_nsec = 0;
-	ts.tv_sec = runtime·timediv(ns, 1000000000LL, (int32*)&ts.tv_nsec);
-	runtime·futex(addr, FUTEX_WAIT, val, &ts, nil, 0);
-}
-
-// If any procs are sleeping on addr, wake up at most cnt.
-void
-runtime·futexwakeup(uint32 *addr, uint32 cnt)
-{
-	int64 ret;
-
-	ret = runtime·futex(addr, FUTEX_WAKE, cnt, nil, nil, 0);
-
-	if(ret >= 0)
-		return;
-
-	// I don't know that futex wakeup can return
-	// EAGAIN or EINTR, but if it does, it would be
-	// safe to loop and call futex again.
-	runtime·printf("futexwakeup addr=%p returned %D\n", addr, ret);
-	*(int32*)0x1006 = 0x1006;
-}
-
-extern runtime·sched_getaffinity(uintptr pid, uintptr len, uintptr *buf);
-static int32
-getproccount(void)
-{
-	uintptr buf[16], t;
-	int32 r, cnt, i;
-
-	cnt = 0;
-	r = runtime·sched_getaffinity(0, sizeof(buf), buf);
-	if(r > 0)
-	for(i = 0; i < r/sizeof(buf[0]); i++) {
-		t = buf[i];
-		t = t - ((t >> 1) & 0x5555555555555555ULL);
-		t = (t & 0x3333333333333333ULL) + ((t >> 2) & 0x3333333333333333ULL);
-		cnt += (int32)((((t + (t >> 4)) & 0xF0F0F0F0F0F0F0FULL) * 0x101010101010101ULL) >> 56);
-	}
-
-	return cnt ? cnt : 1;
-}
-
-// Clone, the Linux rfork.
-enum
-{
-	CLONE_VM = 0x100,
-	CLONE_FS = 0x200,
-	CLONE_FILES = 0x400,
-	CLONE_SIGHAND = 0x800,
-	CLONE_PTRACE = 0x2000,
-	CLONE_VFORK = 0x4000,
-	CLONE_PARENT = 0x8000,
-	CLONE_THREAD = 0x10000,
-	CLONE_NEWNS = 0x20000,
-	CLONE_SYSVSEM = 0x40000,
-	CLONE_SETTLS = 0x80000,
-	CLONE_PARENT_SETTID = 0x100000,
-	CLONE_CHILD_CLEARTID = 0x200000,
-	CLONE_UNTRACED = 0x800000,
-	CLONE_CHILD_SETTID = 0x1000000,
-	CLONE_STOPPED = 0x2000000,
-	CLONE_NEWUTS = 0x4000000,
-	CLONE_NEWIPC = 0x8000000,
-};
-
-void
-runtime·newosproc(M *mp, void *stk)
-{
-	int32 ret;
-	int32 flags;
-	Sigset oset;
-
-	/*
-	 * note: strace gets confused if we use CLONE_PTRACE here.
-	 */
-	flags = CLONE_VM	/* share memory */
-		| CLONE_FS	/* share cwd, etc */
-		| CLONE_FILES	/* share fd table */
-		| CLONE_SIGHAND	/* share sig handler table */
-		| CLONE_THREAD	/* revisit - okay for now */
-		;
-
-	mp->tls[0] = mp->id;	// so 386 asm can find it
-	if(0){
-		runtime·printf("newosproc stk=%p m=%p g=%p clone=%p id=%d/%d ostk=%p\n",
-			stk, mp, mp->g0, runtime·clone, mp->id, (int32)mp->tls[0], &mp);
-	}
-
-	// Disable signals during clone, so that the new thread starts
-	// with signals disabled.  It will enable them in minit.
-	runtime·rtsigprocmask(SIG_SETMASK, &sigset_all, &oset, sizeof oset);
-	ret = runtime·clone(flags, stk, mp, mp->g0, runtime·mstart);
-	runtime·rtsigprocmask(SIG_SETMASK, &oset, nil, sizeof oset);
-
-	if(ret < 0) {
-		runtime·printf("runtime: failed to create new OS thread (have %d already; errno=%d)\n", runtime·mcount(), -ret);
-		runtime·throw("runtime.newosproc");
-	}
-}
-
-void
-runtime·osinit(void)
-{
-	runtime·ncpu = getproccount();
-}
-
-// Random bytes initialized at startup.  These come
-// from the ELF AT_RANDOM auxiliary vector (vdso_linux_amd64.c).
-byte*	runtime·startup_random_data;
-uint32	runtime·startup_random_data_len;
-
-void
-runtime·get_random_data(byte **rnd, int32 *rnd_len)
-{
-	if(runtime·startup_random_data != nil) {
-		*rnd = runtime·startup_random_data;
-		*rnd_len = runtime·startup_random_data_len;
-	} else {
-		#pragma dataflag NOPTR
-		static byte urandom_data[HashRandomBytes];
-		int32 fd;
-		fd = runtime·open("/dev/urandom", 0 /* O_RDONLY */, 0);
-		if(runtime·read(fd, urandom_data, HashRandomBytes) == HashRandomBytes) {
-			*rnd = urandom_data;
-			*rnd_len = HashRandomBytes;
-		} else {
-			*rnd = nil;
-			*rnd_len = 0;
-		}
-		runtime·close(fd);
-	}
-}
-
-void
-runtime·goenvs(void)
-{
-	runtime·goenvs_unix();
-}
-
-// Called to initialize a new m (including the bootstrap m).
-// Called on the parent thread (main thread in case of bootstrap), can allocate memory.
-void
-runtime·mpreinit(M *mp)
-{
-	mp->gsignal = runtime·malg(32*1024);	// OS X wants >=8K, Linux >=2K
-}
-
-// Called to initialize a new m (including the bootstrap m).
-// Called on the new thread, can not allocate memory.
-void
-runtime·minit(void)
-{
-	// Initialize signal handling.
-	runtime·signalstack((byte*)m->gsignal->stackguard - StackGuard, 32*1024);
-	runtime·rtsigprocmask(SIG_SETMASK, &sigset_none, nil, sizeof(Sigset));
-}
-
-// Called from dropm to undo the effect of an minit.
-void
-runtime·unminit(void)
-{
-	runtime·signalstack(nil, 0);
-}
-
-void
-runtime·sigpanic(void)
-{
-	if(!runtime·canpanic(g))
-		runtime·throw("unexpected signal during runtime execution");
-
-	switch(g->sig) {
-	case SIGBUS:
-		if(g->sigcode0 == BUS_ADRERR && g->sigcode1 < 0x1000 || g->paniconfault) {
-			if(g->sigpc == 0)
-				runtime·panicstring("call of nil func value");
-			runtime·panicstring("invalid memory address or nil pointer dereference");
-		}
-		runtime·printf("unexpected fault address %p\n", g->sigcode1);
-		runtime·throw("fault");
-	case SIGSEGV:
-		if((g->sigcode0 == 0 || g->sigcode0 == SEGV_MAPERR || g->sigcode0 == SEGV_ACCERR) && g->sigcode1 < 0x1000 || g->paniconfault) {
-			if(g->sigpc == 0)
-				runtime·panicstring("call of nil func value");
-			runtime·panicstring("invalid memory address or nil pointer dereference");
-		}
-		runtime·printf("unexpected fault address %p\n", g->sigcode1);
-		runtime·throw("fault");
-	case SIGFPE:
-		switch(g->sigcode0) {
-		case FPE_INTDIV:
-			runtime·panicstring("integer divide by zero");
-		case FPE_INTOVF:
-			runtime·panicstring("integer overflow");
-		}
-		runtime·panicstring("floating point error");
-	}
-	runtime·panicstring(runtime·sigtab[g->sig].name);
-}
-
-uintptr
-runtime·memlimit(void)
-{
-	Rlimit rl;
-	extern byte text[], end[];
-	uintptr used;
-
-	if(runtime·getrlimit(RLIMIT_AS, &rl) != 0)
-		return 0;
-	if(rl.rlim_cur >= 0x7fffffff)
-		return 0;
-
-	// Estimate our VM footprint excluding the heap.
-	// Not an exact science: use size of binary plus
-	// some room for thread stacks.
-	used = end - text + (64<<20);
-	if(used >= rl.rlim_cur)
-		return 0;
-
-	// If there's not at least 16 MB left, we're probably
-	// not going to be able to do much.  Treat as no limit.
-	rl.rlim_cur -= used;
-	if(rl.rlim_cur < (16<<20))
-		return 0;
-
-	return rl.rlim_cur - used;
-}
-
-#ifdef GOARCH_386
-#define sa_handler k_sa_handler
-#endif
-
-/*
- * This assembler routine takes the args from registers, puts them on the stack,
- * and calls sighandler().
- */
-extern void runtime·sigtramp(void);
-extern void runtime·sigreturn(void);	// calls runtime·sigreturn
-
-void
-runtime·setsig(int32 i, GoSighandler *fn, bool restart)
-{
-	Sigaction sa;
-
-	runtime·memclr((byte*)&sa, sizeof sa);
-	sa.sa_flags = SA_ONSTACK | SA_SIGINFO | SA_RESTORER;
-	if(restart)
-		sa.sa_flags |= SA_RESTART;
-	sa.sa_mask = ~0ULL;
-	// TODO(adonovan): Linux manpage says "sa_restorer element is
-	// obsolete and should not be used".  Avoid it here, and test.
-	sa.sa_restorer = (void*)runtime·sigreturn;
-	if(fn == runtime·sighandler)
-		fn = (void*)runtime·sigtramp;
-	sa.sa_handler = fn;
-	if(runtime·rt_sigaction(i, &sa, nil, sizeof(sa.sa_mask)) != 0)
-		runtime·throw("rt_sigaction failure");
-}
-
-GoSighandler*
-runtime·getsig(int32 i)
-{
-	Sigaction sa;
-
-	runtime·memclr((byte*)&sa, sizeof sa);
-	if(runtime·rt_sigaction(i, nil, &sa, sizeof(sa.sa_mask)) != 0)
-		runtime·throw("rt_sigaction read failure");
-	if((void*)sa.sa_handler == runtime·sigtramp)
-		return runtime·sighandler;
-	return (void*)sa.sa_handler;
-}
-
-void
-runtime·signalstack(byte *p, int32 n)
-{
-	Sigaltstack st;
-
-	st.ss_sp = p;
-	st.ss_size = n;
-	st.ss_flags = 0;
-	if(p == nil)
-		st.ss_flags = SS_DISABLE;
-	runtime·sigaltstack(&st, nil);
-}
-
-void
-runtime·unblocksignals(void)
-{
-	runtime·rtsigprocmask(SIG_SETMASK, &sigset_none, nil, sizeof sigset_none);
-}
diff --git a/src/pkg/runtime/os_linux.h b/src/pkg/runtime/os_linux.h
deleted file mode 100644
index d4b1902..0000000
--- a/src/pkg/runtime/os_linux.h
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#define SS_DISABLE 2
-
-// Linux-specific system calls
-int32	runtime·futex(uint32*, int32, uint32, Timespec*, uint32*, uint32);
-int32	runtime·clone(int32, void*, M*, G*, void(*)(void));
-
-struct Sigaction;
-int32	runtime·rt_sigaction(uintptr, struct Sigaction*, void*, uintptr);
-
-void	runtime·sigaltstack(Sigaltstack*, Sigaltstack*);
-void	runtime·sigpanic(void);
-void runtime·setitimer(int32, Itimerval*, Itimerval*);
-
-
-#define	NSIG	65
-#define	SI_USER 0
-
-// It's hard to tease out exactly how big a Sigset is, but
-// rt_sigprocmask crashes if we get it wrong, so if binaries
-// are running, this is right.
-typedef struct Sigset Sigset;
-struct Sigset
-{
-	uint32 mask[2];
-};
-void	runtime·rtsigprocmask(int32, Sigset*, Sigset*, int32);
-void	runtime·unblocksignals(void);
-#define SIG_SETMASK 2
-
-#define RLIMIT_AS 9
-typedef struct Rlimit Rlimit;
-struct Rlimit {
-	uintptr	rlim_cur;
-	uintptr	rlim_max;
-};
-int32	runtime·getrlimit(int32, Rlimit*);
diff --git a/src/pkg/runtime/os_linux_386.c b/src/pkg/runtime/os_linux_386.c
deleted file mode 100644
index ad72814..0000000
--- a/src/pkg/runtime/os_linux_386.c
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "runtime.h"
-#include "defs_GOOS_GOARCH.h"
-#include "os_GOOS.h"
-#include "../../cmd/ld/textflag.h"
-
-#define AT_NULL		0
-#define AT_RANDOM	25
-#define AT_SYSINFO	32
-extern uint32 runtime·_vdso;
-
-#pragma textflag NOSPLIT
-void
-runtime·linux_setup_vdso(int32 argc, byte **argv)
-{
-	byte **envp;
-	uint32 *auxv;
-
-	// skip envp to get to ELF auxiliary vector.
-	for(envp = &argv[argc+1]; *envp != nil; envp++)
-		;
-	envp++;
-	
-	for(auxv=(uint32*)envp; auxv[0] != AT_NULL; auxv += 2) {
-		if(auxv[0] == AT_SYSINFO) {
-			runtime·_vdso = auxv[1];
-			continue;
-		}
-		if(auxv[0] == AT_RANDOM) {
-			runtime·startup_random_data = (byte*)auxv[1];
-			runtime·startup_random_data_len = 16;
-			continue;
-		}
-	}
-}
diff --git a/src/pkg/runtime/os_linux_arm.c b/src/pkg/runtime/os_linux_arm.c
deleted file mode 100644
index aad08b9..0000000
--- a/src/pkg/runtime/os_linux_arm.c
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "runtime.h"
-#include "defs_GOOS_GOARCH.h"
-#include "os_GOOS.h"
-#include "../../cmd/ld/textflag.h"
-
-#define AT_NULL		0
-#define AT_PLATFORM	15 // introduced in at least 2.6.11
-#define AT_HWCAP	16 // introduced in at least 2.6.11
-#define AT_RANDOM	25 // introduced in 2.6.29
-#define HWCAP_VFP	(1 << 6) // introduced in at least 2.6.11
-#define HWCAP_VFPv3	(1 << 13) // introduced in 2.6.30
-static uint32 runtime·randomNumber;
-uint8  runtime·armArch = 6;	// we default to ARMv6
-uint32 runtime·hwcap;	// set by setup_auxv
-extern uint8  runtime·goarm;	// set by 5l
-
-void
-runtime·checkgoarm(void)
-{
-	if(runtime·goarm > 5 && !(runtime·hwcap & HWCAP_VFP)) {
-		runtime·printf("runtime: this CPU has no floating point hardware, so it cannot run\n");
-		runtime·printf("this GOARM=%d binary. Recompile using GOARM=5.\n", runtime·goarm);
-		runtime·exit(1);
-	}
-	if(runtime·goarm > 6 && !(runtime·hwcap & HWCAP_VFPv3)) {
-		runtime·printf("runtime: this CPU has no VFPv3 floating point hardware, so it cannot run\n");
-		runtime·printf("this GOARM=%d binary. Recompile using GOARM=6.\n", runtime·goarm);
-		runtime·exit(1);
-	}
-}
-
-#pragma textflag NOSPLIT
-void
-runtime·setup_auxv(int32 argc, byte **argv)
-{
-	byte **envp;
-	byte *rnd;
-	uint32 *auxv;
-	uint32 t;
-
-	// skip envp to get to ELF auxiliary vector.
-	for(envp = &argv[argc+1]; *envp != nil; envp++)
-		;
-	envp++;
-	
-	for(auxv=(uint32*)envp; auxv[0] != AT_NULL; auxv += 2) {
-		switch(auxv[0]) {
-		case AT_RANDOM: // kernel provided 16-byte worth of random data
-			if(auxv[1]) {
-				rnd = (byte*)auxv[1];
-				runtime·randomNumber = rnd[4] | rnd[5]<<8 | rnd[6]<<16 | rnd[7]<<24;
-			}
-			break;
-		case AT_PLATFORM: // v5l, v6l, v7l
-			if(auxv[1]) {
-				t = *(uint8*)(auxv[1]+1);
-				if(t >= '5' && t <= '7')
-					runtime·armArch = t - '0';
-			}
-			break;
-		case AT_HWCAP: // CPU capability bit flags
-			runtime·hwcap = auxv[1];
-			break;
-		}
-	}
-}
-
-#pragma textflag NOSPLIT
-int64
-runtime·cputicks(void)
-{
-	// Currently cputicks() is used in blocking profiler and to seed runtime·fastrand1().
-	// runtime·nanotime() is a poor approximation of CPU ticks that is enough for the profiler.
-	// runtime·randomNumber provides better seeding of fastrand1.
-	return runtime·nanotime() + runtime·randomNumber;
-}
diff --git a/src/pkg/runtime/os_nacl.c b/src/pkg/runtime/os_nacl.c
deleted file mode 100644
index 3196e2c..0000000
--- a/src/pkg/runtime/os_nacl.c
+++ /dev/null
@@ -1,278 +0,0 @@
-// Copyright 2010 The Go 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 "runtime.h"
-#include "defs_GOOS_GOARCH.h"
-#include "os_GOOS.h"
-#include "arch_GOARCH.h"
-#include "../../cmd/ld/textflag.h"
-#include "stack.h"
-
-int8 *goos = "nacl";
-extern SigTab runtime·sigtab[];
-
-void runtime·sigtramp(void);
-
-// Called to initialize a new m (including the bootstrap m).
-// Called on the parent thread (main thread in case of bootstrap), can allocate memory.
-void
-runtime·mpreinit(M *mp)
-{
-	mp->gsignal = runtime·malg(32*1024);	// OS X wants >=8K, Linux >=2K
-}
-
-// Called to initialize a new m (including the bootstrap m).
-// Called on the new thread, can not allocate memory.
-void
-runtime·minit(void)
-{
-	int32 ret;
-
-	// Initialize signal handling
-	ret = runtime·nacl_exception_stack((byte*)m->gsignal->stackguard - StackGuard, 32*1024);
-	if(ret < 0)
-		runtime·printf("runtime: nacl_exception_stack: error %d\n", -ret);
-
-	ret = runtime·nacl_exception_handler(runtime·sigtramp, nil);
-	if(ret < 0)
-		runtime·printf("runtime: nacl_exception_handler: error %d\n", -ret);
-}
-
-// Called from dropm to undo the effect of an minit.
-void
-runtime·unminit(void)
-{
-}
-
-int8 runtime·sigtrampf[] = "runtime: signal at PC=%X AX=%X CX=%X DX=%X BX=%X DI=%X R15=%X *SP=%X\n";
-int8 runtime·sigtrampp[] = "runtime: sigtramp";
-
-extern byte runtime·tls0[];
-
-void
-runtime·osinit(void)
-{
-	runtime·ncpu = 1;
-	m->procid = 2;
-//runtime·nacl_exception_handler(runtime·sigtramp, nil);
-}
-
-void
-runtime·crash(void)
-{
-	*(int32*)0 = 0;
-}
-
-void
-runtime·get_random_data(byte **rnd, int32 *rnd_len)
-{
-	*rnd = nil;
-	*rnd_len = 0;
-}
-
-void
-runtime·goenvs(void)
-{
-	runtime·goenvs_unix();
-}
-
-void
-runtime·initsig(void)
-{
-}
-
-#pragma textflag NOSPLIT
-void
-runtime·usleep(uint32 us)
-{
-	Timespec ts;
-	
-	ts.tv_sec = us/1000000;
-	ts.tv_nsec = (us%1000000)*1000;
-	runtime·nacl_nanosleep(&ts, nil);
-}
-
-void runtime·mstart_nacl(void);
-
-void
-runtime·newosproc(M *mp, void *stk)
-{
-	int32 ret;
-	void **tls;
-
-	tls = (void**)mp->tls;
-	tls[0] = mp->g0;
-	tls[1] = mp;
-	ret = runtime·nacl_thread_create(runtime·mstart_nacl, stk, tls+2, 0);
-	if(ret < 0) {
-		runtime·printf("nacl_thread_create: error %d\n", -ret);
-		runtime·throw("newosproc");
-	}
-}
-
-uintptr
-runtime·semacreate(void)
-{
-	int32 mu, cond;
-	
-	mu = runtime·nacl_mutex_create(0);
-	if(mu < 0) {
-		runtime·printf("nacl_mutex_create: error %d\n", -mu);
-		runtime·throw("semacreate");
-	}
-	cond = runtime·nacl_cond_create(0);
-	if(cond < 0) {
-		runtime·printf("nacl_cond_create: error %d\n", -cond);
-		runtime·throw("semacreate");
-	}
-	m->waitsemalock = mu;
-	return cond; // assigned to m->waitsema
-}
-
-#pragma textflag NOSPLIT
-int32
-runtime·semasleep(int64 ns)
-{
-	int32 ret;
-	
-	ret = runtime·nacl_mutex_lock(m->waitsemalock);
-	if(ret < 0) {
-		//runtime·printf("nacl_mutex_lock: error %d\n", -ret);
-		runtime·throw("semasleep");
-	}
-	if(m->waitsemacount > 0) {
-		m->waitsemacount = 0;
-		runtime·nacl_mutex_unlock(m->waitsemalock);
-		return 0;
-	}
-
-	while(m->waitsemacount == 0) {
-		if(ns < 0) {
-			ret = runtime·nacl_cond_wait(m->waitsema, m->waitsemalock);
-			if(ret < 0) {
-				//runtime·printf("nacl_cond_wait: error %d\n", -ret);
-				runtime·throw("semasleep");
-			}
-		} else {
-			Timespec ts;
-			
-			ns += runtime·nanotime();
-			ts.tv_sec = runtime·timediv(ns, 1000000000, (int32*)&ts.tv_nsec);
-			ret = runtime·nacl_cond_timed_wait_abs(m->waitsema, m->waitsemalock, &ts);
-			if(ret == -ETIMEDOUT) {
-				runtime·nacl_mutex_unlock(m->waitsemalock);
-				return -1;
-			}
-			if(ret < 0) {
-				//runtime·printf("nacl_cond_timed_wait_abs: error %d\n", -ret);
-				runtime·throw("semasleep");
-			}
-		}
-	}
-			
-	m->waitsemacount = 0;
-	runtime·nacl_mutex_unlock(m->waitsemalock);
-	return 0;
-}
-
-void
-runtime·semawakeup(M *mp)
-{
-	int32 ret;
-	
-	ret = runtime·nacl_mutex_lock(mp->waitsemalock);
-	if(ret < 0) {
-		//runtime·printf("nacl_mutex_lock: error %d\n", -ret);
-		runtime·throw("semawakeup");
-	}
-	if(mp->waitsemacount != 0) {
-		//runtime·printf("semawakeup: double wakeup\n");
-		runtime·throw("semawakeup");
-	}
-	mp->waitsemacount = 1;
-	runtime·nacl_cond_signal(mp->waitsema);
-	runtime·nacl_mutex_unlock(mp->waitsemalock);
-}
-
-void
-os·sigpipe(void)
-{
-	runtime·throw("too many writes on closed pipe");
-}
-
-uintptr
-runtime·memlimit(void)
-{
-	runtime·printf("memlimit\n");
-	return 0;
-}
-
-#pragma dataflag NOPTR
-static int8 badsignal[] = "runtime: signal received on thread not created by Go.\n";
-
-// This runs on a foreign stack, without an m or a g.  No stack split.
-#pragma textflag NOSPLIT
-void
-runtime·badsignal2(void)
-{
-	runtime·write(2, badsignal, sizeof badsignal - 1);
-	runtime·exit(2);
-}
-
-void	runtime·madvise(byte*, uintptr, int32) { }
-void runtime·munmap(byte*, uintptr) {}
-
-void
-runtime·resetcpuprofiler(int32 hz)
-{
-	USED(hz);
-}
-
-void
-runtime·sigdisable(uint32)
-{
-}
-
-void
-runtime·sigenable(uint32)
-{
-}
-
-void
-runtime·closeonexec(int32)
-{
-}
-
-void
-runtime·sigpanic(void)
-{
-	if(!runtime·canpanic(g))
-		runtime·throw("unexpected signal during runtime execution");
-
-	// Native Client only invokes the exception handler for memory faults.
-	g->sig = SIGSEGV;
-	if(g->sigpc == 0)
-		runtime·panicstring("call of nil func value");
-	runtime·panicstring("invalid memory address or nil pointer dereference");
-}
-
-uint32 runtime·writelock; // test-and-set spin lock for runtime.write
-
-/*
-An attempt at IRT. Doesn't work. See end of sys_nacl_amd64.s.
-
-void (*runtime·nacl_irt_query)(void);
-
-int8 runtime·nacl_irt_basic_v0_1_str[] = "nacl-irt-basic-0.1";
-void *runtime·nacl_irt_basic_v0_1[6]; // exit, gettod, clock, nanosleep, sched_yield, sysconf
-int32 runtime·nacl_irt_basic_v0_1_size = sizeof(runtime·nacl_irt_basic_v0_1);
-
-int8 runtime·nacl_irt_memory_v0_3_str[] = "nacl-irt-memory-0.3";
-void *runtime·nacl_irt_memory_v0_3[3]; // mmap, munmap, mprotect
-int32 runtime·nacl_irt_memory_v0_3_size = sizeof(runtime·nacl_irt_memory_v0_3);
-
-int8 runtime·nacl_irt_thread_v0_1_str[] = "nacl-irt-thread-0.1";
-void *runtime·nacl_irt_thread_v0_1[3]; // thread_create, thread_exit, thread_nice
-int32 runtime·nacl_irt_thread_v0_1_size = sizeof(runtime·nacl_irt_thread_v0_1);
-*/
\ No newline at end of file
diff --git a/src/pkg/runtime/os_netbsd.c b/src/pkg/runtime/os_netbsd.c
deleted file mode 100644
index 93229bf..0000000
--- a/src/pkg/runtime/os_netbsd.c
+++ /dev/null
@@ -1,338 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "runtime.h"
-#include "defs_GOOS_GOARCH.h"
-#include "os_GOOS.h"
-#include "signal_unix.h"
-#include "stack.h"
-#include "../../cmd/ld/textflag.h"
-
-enum
-{
-	ESRCH = 3,
-	ENOTSUP = 91,
-
-	// From NetBSD's <sys/time.h>
-	CLOCK_REALTIME = 0,
-	CLOCK_VIRTUAL = 1,
-	CLOCK_PROF = 2,
-	CLOCK_MONOTONIC = 3
-};
-
-extern SigTab runtime·sigtab[];
-
-static Sigset sigset_none;
-static Sigset sigset_all = { ~(uint32)0, ~(uint32)0, ~(uint32)0, ~(uint32)0, };
-
-extern void runtime·getcontext(UcontextT *context);
-extern int32 runtime·lwp_create(UcontextT *context, uintptr flags, void *lwpid);
-extern void runtime·lwp_mcontext_init(void *mc, void *stack, M *mp, G *gp, void (*fn)(void));
-extern int32 runtime·lwp_park(Timespec *abstime, int32 unpark, void *hint, void *unparkhint);
-extern int32 runtime·lwp_unpark(int32 lwp, void *hint);
-extern int32 runtime·lwp_self(void);
-
-// From NetBSD's <sys/sysctl.h>
-#define	CTL_HW	6
-#define	HW_NCPU	3
-
-static int32
-getncpu(void)
-{
-	uint32 mib[2];
-	uint32 out;
-	int32 ret;
-	uintptr nout;
-
-	// Fetch hw.ncpu via sysctl.
-	mib[0] = CTL_HW;
-	mib[1] = HW_NCPU;
-	nout = sizeof out;
-	out = 0;
-	ret = runtime·sysctl(mib, 2, (byte*)&out, &nout, nil, 0);
-	if(ret >= 0)
-		return out;
-	else
-		return 1;
-}
-
-uintptr
-runtime·semacreate(void)
-{
-	return 1;
-}
-
-#pragma textflag NOSPLIT
-int32
-runtime·semasleep(int64 ns)
-{
-	Timespec ts;
-
-	// spin-mutex lock
-	while(runtime·xchg(&m->waitsemalock, 1))
-		runtime·osyield();
-
-	for(;;) {
-		// lock held
-		if(m->waitsemacount == 0) {
-			// sleep until semaphore != 0 or timeout.
-			// thrsleep unlocks m->waitsemalock.
-			if(ns < 0) {
-				// TODO(jsing) - potential deadlock!
-				//
-				// There is a potential deadlock here since we
-				// have to release the waitsemalock mutex
-				// before we call lwp_park() to suspend the
-				// thread. This allows another thread to
-				// release the lock and call lwp_unpark()
-				// before the thread is actually suspended.
-				// If this occurs the current thread will end
-				// up sleeping indefinitely. Unfortunately
-				// the NetBSD kernel does not appear to provide
-				// a mechanism for unlocking the userspace
-				// mutex once the thread is actually parked.
-				runtime·atomicstore(&m->waitsemalock, 0);
-				runtime·lwp_park(nil, 0, &m->waitsemacount, nil);
-			} else {
-				ns = ns + runtime·nanotime();
-				// NOTE: tv_nsec is int64 on amd64, so this assumes a little-endian system.
-				ts.tv_nsec = 0;
-				ts.tv_sec = runtime·timediv(ns, 1000000000, (int32*)&ts.tv_nsec);
-				// TODO(jsing) - potential deadlock!
-				// See above for details.
-				runtime·atomicstore(&m->waitsemalock, 0);
-				runtime·lwp_park(&ts, 0, &m->waitsemacount, nil);
-			}
-			// reacquire lock
-			while(runtime·xchg(&m->waitsemalock, 1))
-				runtime·osyield();
-		}
-
-		// lock held (again)
-		if(m->waitsemacount != 0) {
-			// semaphore is available.
-			m->waitsemacount--;
-			// spin-mutex unlock
-			runtime·atomicstore(&m->waitsemalock, 0);
-			return 0;  // semaphore acquired
-		}
-
-		// semaphore not available.
-		// if there is a timeout, stop now.
-		// otherwise keep trying.
-		if(ns >= 0)
-			break;
-	}
-
-	// lock held but giving up
-	// spin-mutex unlock
-	runtime·atomicstore(&m->waitsemalock, 0);
-	return -1;
-}
-
-void
-runtime·semawakeup(M *mp)
-{
-	uint32 ret;
-
-	// spin-mutex lock
-	while(runtime·xchg(&mp->waitsemalock, 1))
-		runtime·osyield();
-	mp->waitsemacount++;
-	// TODO(jsing) - potential deadlock, see semasleep() for details.
-	// Confirm that LWP is parked before unparking...
-	ret = runtime·lwp_unpark(mp->procid, &mp->waitsemacount);
-	if(ret != 0 && ret != ESRCH)
-		runtime·printf("thrwakeup addr=%p sem=%d ret=%d\n", &mp->waitsemacount, mp->waitsemacount, ret);
-	// spin-mutex unlock
-	runtime·atomicstore(&mp->waitsemalock, 0);
-}
-
-void
-runtime·newosproc(M *mp, void *stk)
-{
-	UcontextT uc;
-	int32 ret;
-
-	if(0) {
-		runtime·printf(
-			"newosproc stk=%p m=%p g=%p id=%d/%d ostk=%p\n",
-			stk, mp, mp->g0, mp->id, (int32)mp->tls[0], &mp);
-	}
-
-	mp->tls[0] = mp->id;	// so 386 asm can find it
-
-	runtime·getcontext(&uc);
-	
-	uc.uc_flags = _UC_SIGMASK | _UC_CPU;
-	uc.uc_link = nil;
-	uc.uc_sigmask = sigset_all;
-
-	runtime·lwp_mcontext_init(&uc.uc_mcontext, stk, mp, mp->g0, runtime·mstart);
-
-	ret = runtime·lwp_create(&uc, 0, &mp->procid);
-
-	if(ret < 0) {
-		runtime·printf("runtime: failed to create new OS thread (have %d already; errno=%d)\n", runtime·mcount() - 1, -ret);
-		runtime·throw("runtime.newosproc");
-	}
-}
-
-void
-runtime·osinit(void)
-{
-	runtime·ncpu = getncpu();
-}
-
-void
-runtime·get_random_data(byte **rnd, int32 *rnd_len)
-{
-	#pragma dataflag NOPTR
-	static byte urandom_data[HashRandomBytes];
-	int32 fd;
-	fd = runtime·open("/dev/urandom", 0 /* O_RDONLY */, 0);
-	if(runtime·read(fd, urandom_data, HashRandomBytes) == HashRandomBytes) {
-		*rnd = urandom_data;
-		*rnd_len = HashRandomBytes;
-	} else {
-		*rnd = nil;
-		*rnd_len = 0;
-	}
-	runtime·close(fd);
-}
-
-void
-runtime·goenvs(void)
-{
-	runtime·goenvs_unix();
-}
-
-// Called to initialize a new m (including the bootstrap m).
-// Called on the parent thread (main thread in case of bootstrap), can allocate memory.
-void
-runtime·mpreinit(M *mp)
-{
-	mp->gsignal = runtime·malg(32*1024);
-}
-
-// Called to initialize a new m (including the bootstrap m).
-// Called on the new thread, can not allocate memory.
-void
-runtime·minit(void)
-{
-	m->procid = runtime·lwp_self();
-
-	// Initialize signal handling
-	runtime·signalstack((byte*)m->gsignal->stackguard - StackGuard, 32*1024);
-	runtime·sigprocmask(SIG_SETMASK, &sigset_none, nil);
-}
-
-// Called from dropm to undo the effect of an minit.
-void
-runtime·unminit(void)
-{
-	runtime·signalstack(nil, 0);
-}
-
-void
-runtime·sigpanic(void)
-{
-	if(!runtime·canpanic(g))
-		runtime·throw("unexpected signal during runtime execution");
-
-	switch(g->sig) {
-	case SIGBUS:
-		if(g->sigcode0 == BUS_ADRERR && g->sigcode1 < 0x1000 || g->paniconfault) {
-			if(g->sigpc == 0)
-				runtime·panicstring("call of nil func value");
-			runtime·panicstring("invalid memory address or nil pointer dereference");
-		}
-		runtime·printf("unexpected fault address %p\n", g->sigcode1);
-		runtime·throw("fault");
-	case SIGSEGV:
-		if((g->sigcode0 == 0 || g->sigcode0 == SEGV_MAPERR || g->sigcode0 == SEGV_ACCERR) && g->sigcode1 < 0x1000 || g->paniconfault) {
-			if(g->sigpc == 0)
-				runtime·panicstring("call of nil func value");
-			runtime·panicstring("invalid memory address or nil pointer dereference");
-		}
-		runtime·printf("unexpected fault address %p\n", g->sigcode1);
-		runtime·throw("fault");
-	case SIGFPE:
-		switch(g->sigcode0) {
-		case FPE_INTDIV:
-			runtime·panicstring("integer divide by zero");
-		case FPE_INTOVF:
-			runtime·panicstring("integer overflow");
-		}
-		runtime·panicstring("floating point error");
-	}
-	runtime·panicstring(runtime·sigtab[g->sig].name);
-}
-
-uintptr
-runtime·memlimit(void)
-{
-	return 0;
-}
-
-extern void runtime·sigtramp(void);
-
-typedef struct sigaction {
-	union {
-		void    (*_sa_handler)(int32);
-		void    (*_sa_sigaction)(int32, Siginfo*, void *);
-	} _sa_u;			/* signal handler */
-	uint32	sa_mask[4];		/* signal mask to apply */
-	int32	sa_flags;		/* see signal options below */
-} Sigaction;
-
-void
-runtime·setsig(int32 i, GoSighandler *fn, bool restart)
-{
-	Sigaction sa;
-
-	runtime·memclr((byte*)&sa, sizeof sa);
-	sa.sa_flags = SA_SIGINFO|SA_ONSTACK;
-	if(restart)
-		sa.sa_flags |= SA_RESTART;
-	sa.sa_mask[0] = ~0U;
-	sa.sa_mask[1] = ~0U;
-	sa.sa_mask[2] = ~0U;
-	sa.sa_mask[3] = ~0U;
-	if (fn == runtime·sighandler)
-		fn = (void*)runtime·sigtramp;
-	sa._sa_u._sa_sigaction = (void*)fn;
-	runtime·sigaction(i, &sa, nil);
-}
-
-GoSighandler*
-runtime·getsig(int32 i)
-{
-	Sigaction sa;
-
-	runtime·memclr((byte*)&sa, sizeof sa);
-	runtime·sigaction(i, nil, &sa);
-	if((void*)sa._sa_u._sa_sigaction == runtime·sigtramp)
-		return runtime·sighandler;
-	return (void*)sa._sa_u._sa_sigaction;
-}
-
-void
-runtime·signalstack(byte *p, int32 n)
-{
-	StackT st;
-
-	st.ss_sp = (void*)p;
-	st.ss_size = n;
-	st.ss_flags = 0;
-	if(p == nil)
-		st.ss_flags = SS_DISABLE;
-	runtime·sigaltstack(&st, nil);
-}
-
-void
-runtime·unblocksignals(void)
-{
-	runtime·sigprocmask(SIG_SETMASK, &sigset_none, nil);
-}
diff --git a/src/pkg/runtime/os_netbsd.h b/src/pkg/runtime/os_netbsd.h
deleted file mode 100644
index 16e9833..0000000
--- a/src/pkg/runtime/os_netbsd.h
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2010 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#define SS_DISABLE 4
-
-#define SIG_BLOCK 1
-#define SIG_UNBLOCK 2
-#define SIG_SETMASK 3
-
-typedef uintptr kevent_udata;
-
-struct sigaction;
-
-void	runtime·sigpanic(void);
-
-void	runtime·setitimer(int32, Itimerval*, Itimerval*);
-void	runtime·sigaction(int32, struct sigaction*, struct sigaction*);
-void	runtime·sigaltstack(Sigaltstack*, Sigaltstack*);
-void	runtime·sigprocmask(int32, Sigset*, Sigset*);
-void	runtime·unblocksignals(void);
-int32	runtime·sysctl(uint32*, uint32, byte*, uintptr*, byte*, uintptr);
-extern void runtime·lwp_tramp(void);
-
-#define	NSIG 33
-#define	SI_USER	0
-
-// From NetBSD's <sys/ucontext.h>
-#define _UC_SIGMASK	0x01
-#define _UC_CPU		0x04
diff --git a/src/pkg/runtime/os_netbsd_arm.c b/src/pkg/runtime/os_netbsd_arm.c
deleted file mode 100644
index e440e7d..0000000
--- a/src/pkg/runtime/os_netbsd_arm.c
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "runtime.h"
-#include "defs_GOOS_GOARCH.h"
-#include "os_GOOS.h"
-#include "signal_GOOS_GOARCH.h"
-#include "../../cmd/ld/textflag.h"
-
-void
-runtime·lwp_mcontext_init(McontextT *mc, void *stack, M *mp, G *gp, void (*fn)(void))
-{
-	mc->__gregs[REG_R15] = (uint32)runtime·lwp_tramp;
-	mc->__gregs[REG_R13] = (uint32)stack;
-	mc->__gregs[REG_R0] = (uint32)mp;
-	mc->__gregs[REG_R1] = (uint32)gp;
-	mc->__gregs[REG_R2] = (uint32)fn;
-}
-
-void
-runtime·checkgoarm(void)
-{
-	// TODO(minux)
-}
-
-#pragma textflag NOSPLIT
-int64
-runtime·cputicks() {
-	// Currently cputicks() is used in blocking profiler and to seed runtime·fastrand1().
-	// runtime·nanotime() is a poor approximation of CPU ticks that is enough for the profiler.
-	// TODO: need more entropy to better seed fastrand1.
-	return runtime·nanotime();
-}
diff --git a/src/pkg/runtime/os_openbsd.c b/src/pkg/runtime/os_openbsd.c
deleted file mode 100644
index 08a290a..0000000
--- a/src/pkg/runtime/os_openbsd.c
+++ /dev/null
@@ -1,312 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "runtime.h"
-#include "defs_GOOS_GOARCH.h"
-#include "os_GOOS.h"
-#include "signal_unix.h"
-#include "stack.h"
-#include "../../cmd/ld/textflag.h"
-
-enum
-{
-	ESRCH = 3,
-	ENOTSUP = 91,
-
-	// From OpenBSD's sys/time.h
-	CLOCK_REALTIME = 0,
-	CLOCK_VIRTUAL = 1,
-	CLOCK_PROF = 2,
-	CLOCK_MONOTONIC = 3
-};
-
-extern SigTab runtime·sigtab[];
-
-static Sigset sigset_none;
-static Sigset sigset_all = ~(Sigset)0;
-
-extern int64 runtime·tfork(void *param, uintptr psize, M *mp, G *gp, void (*fn)(void));
-extern int32 runtime·thrsleep(void *ident, int32 clock_id, void *tsp, void *lock, const int32 *abort);
-extern int32 runtime·thrwakeup(void *ident, int32 n);
-
-// From OpenBSD's <sys/sysctl.h>
-#define	CTL_HW	6
-#define	HW_NCPU	3
-
-static int32
-getncpu(void)
-{
-	uint32 mib[2];
-	uint32 out;
-	int32 ret;
-	uintptr nout;
-
-	// Fetch hw.ncpu via sysctl.
-	mib[0] = CTL_HW;
-	mib[1] = HW_NCPU;
-	nout = sizeof out;
-	out = 0;
-	ret = runtime·sysctl(mib, 2, (byte*)&out, &nout, nil, 0);
-	if(ret >= 0)
-		return out;
-	else
-		return 1;
-}
-
-uintptr
-runtime·semacreate(void)
-{
-	return 1;
-}
-
-#pragma textflag NOSPLIT
-int32
-runtime·semasleep(int64 ns)
-{
-	Timespec ts;
-
-	// spin-mutex lock
-	while(runtime·xchg(&m->waitsemalock, 1))
-		runtime·osyield();
-
-	for(;;) {
-		// lock held
-		if(m->waitsemacount == 0) {
-			// sleep until semaphore != 0 or timeout.
-			// thrsleep unlocks m->waitsemalock.
-			if(ns < 0)
-				runtime·thrsleep(&m->waitsemacount, 0, nil, &m->waitsemalock, nil);
-			else {
-				ns += runtime·nanotime();
-				// NOTE: tv_nsec is int64 on amd64, so this assumes a little-endian system.
-				ts.tv_nsec = 0;
-				ts.tv_sec = runtime·timediv(ns, 1000000000, (int32*)&ts.tv_nsec);
-				runtime·thrsleep(&m->waitsemacount, CLOCK_MONOTONIC, &ts, &m->waitsemalock, nil);
-			}
-			// reacquire lock
-			while(runtime·xchg(&m->waitsemalock, 1))
-				runtime·osyield();
-		}
-
-		// lock held (again)
-		if(m->waitsemacount != 0) {
-			// semaphore is available.
-			m->waitsemacount--;
-			// spin-mutex unlock
-			runtime·atomicstore(&m->waitsemalock, 0);
-			return 0;  // semaphore acquired
-		}
-
-		// semaphore not available.
-		// if there is a timeout, stop now.
-		// otherwise keep trying.
-		if(ns >= 0)
-			break;
-	}
-
-	// lock held but giving up
-	// spin-mutex unlock
-	runtime·atomicstore(&m->waitsemalock, 0);
-	return -1;
-}
-
-void
-runtime·semawakeup(M *mp)
-{
-	uint32 ret;
-
-	// spin-mutex lock
-	while(runtime·xchg(&mp->waitsemalock, 1))
-		runtime·osyield();
-	mp->waitsemacount++;
-	ret = runtime·thrwakeup(&mp->waitsemacount, 1);
-	if(ret != 0 && ret != ESRCH)
-		runtime·printf("thrwakeup addr=%p sem=%d ret=%d\n", &mp->waitsemacount, mp->waitsemacount, ret);
-	// spin-mutex unlock
-	runtime·atomicstore(&mp->waitsemalock, 0);
-}
-
-void
-runtime·newosproc(M *mp, void *stk)
-{
-	Tfork param;
-	Sigset oset;
-	int32 ret;
-
-	if(0) {
-		runtime·printf(
-			"newosproc stk=%p m=%p g=%p id=%d/%d ostk=%p\n",
-			stk, mp, mp->g0, mp->id, (int32)mp->tls[0], &mp);
-	}
-
-	mp->tls[0] = mp->id;	// so 386 asm can find it
-
-	param.tf_tcb = (byte*)&mp->tls[0];
-	param.tf_tid = (int32*)&mp->procid;
-	param.tf_stack = stk;
-
-	oset = runtime·sigprocmask(SIG_SETMASK, sigset_all);
-	ret = runtime·tfork((byte*)&param, sizeof(param), mp, mp->g0, runtime·mstart);
-	runtime·sigprocmask(SIG_SETMASK, oset);
-
-	if(ret < 0) {
-		runtime·printf("runtime: failed to create new OS thread (have %d already; errno=%d)\n", runtime·mcount() - 1, -ret);
-		if (ret == -ENOTSUP)
-			runtime·printf("runtime: is kern.rthreads disabled?\n");
-		runtime·throw("runtime.newosproc");
-	}
-}
-
-void
-runtime·osinit(void)
-{
-	runtime·ncpu = getncpu();
-}
-
-void
-runtime·get_random_data(byte **rnd, int32 *rnd_len)
-{
-	#pragma dataflag NOPTR
-	static byte urandom_data[HashRandomBytes];
-	int32 fd;
-	fd = runtime·open("/dev/urandom", 0 /* O_RDONLY */, 0);
-	if(runtime·read(fd, urandom_data, HashRandomBytes) == HashRandomBytes) {
-		*rnd = urandom_data;
-		*rnd_len = HashRandomBytes;
-	} else {
-		*rnd = nil;
-		*rnd_len = 0;
-	}
-	runtime·close(fd);
-}
-
-void
-runtime·goenvs(void)
-{
-	runtime·goenvs_unix();
-}
-
-// Called to initialize a new m (including the bootstrap m).
-// Called on the parent thread (main thread in case of bootstrap), can allocate memory.
-void
-runtime·mpreinit(M *mp)
-{
-	mp->gsignal = runtime·malg(32*1024);
-}
-
-// Called to initialize a new m (including the bootstrap m).
-// Called on the new thread, can not allocate memory.
-void
-runtime·minit(void)
-{
-	// Initialize signal handling
-	runtime·signalstack((byte*)m->gsignal->stackguard - StackGuard, 32*1024);
-	runtime·sigprocmask(SIG_SETMASK, sigset_none);
-}
-
-// Called from dropm to undo the effect of an minit.
-void
-runtime·unminit(void)
-{
-	runtime·signalstack(nil, 0);
-}
-
-void
-runtime·sigpanic(void)
-{
-	if(!runtime·canpanic(g))
-		runtime·throw("unexpected signal during runtime execution");
-
-	switch(g->sig) {
-	case SIGBUS:
-		if(g->sigcode0 == BUS_ADRERR && g->sigcode1 < 0x1000 || g->paniconfault) {
-			if(g->sigpc == 0)
-				runtime·panicstring("call of nil func value");
-			runtime·panicstring("invalid memory address or nil pointer dereference");
-		}
-		runtime·printf("unexpected fault address %p\n", g->sigcode1);
-		runtime·throw("fault");
-	case SIGSEGV:
-		if((g->sigcode0 == 0 || g->sigcode0 == SEGV_MAPERR || g->sigcode0 == SEGV_ACCERR) && g->sigcode1 < 0x1000 || g->paniconfault) {
-			if(g->sigpc == 0)
-				runtime·panicstring("call of nil func value");
-			runtime·panicstring("invalid memory address or nil pointer dereference");
-		}
-		runtime·printf("unexpected fault address %p\n", g->sigcode1);
-		runtime·throw("fault");
-	case SIGFPE:
-		switch(g->sigcode0) {
-		case FPE_INTDIV:
-			runtime·panicstring("integer divide by zero");
-		case FPE_INTOVF:
-			runtime·panicstring("integer overflow");
-		}
-		runtime·panicstring("floating point error");
-	}
-	runtime·panicstring(runtime·sigtab[g->sig].name);
-}
-
-uintptr
-runtime·memlimit(void)
-{
-	return 0;
-}
-
-extern void runtime·sigtramp(void);
-
-typedef struct sigaction {
-	union {
-		void    (*__sa_handler)(int32);
-		void    (*__sa_sigaction)(int32, Siginfo*, void *);
-	} __sigaction_u;		/* signal handler */
-	uint32	sa_mask;		/* signal mask to apply */
-	int32	sa_flags;		/* see signal options below */
-} Sigaction;
-
-void
-runtime·setsig(int32 i, GoSighandler *fn, bool restart)
-{
-	Sigaction sa;
-
-	runtime·memclr((byte*)&sa, sizeof sa);
-	sa.sa_flags = SA_SIGINFO|SA_ONSTACK;
-	if(restart)
-		sa.sa_flags |= SA_RESTART;
-	sa.sa_mask = ~0U;
-	if(fn == runtime·sighandler)
-		fn = (void*)runtime·sigtramp;
-	sa.__sigaction_u.__sa_sigaction = (void*)fn;
-	runtime·sigaction(i, &sa, nil);
-}
-
-GoSighandler*
-runtime·getsig(int32 i)
-{
-	Sigaction sa;
-
-	runtime·memclr((byte*)&sa, sizeof sa);
-	runtime·sigaction(i, nil, &sa);
-	if((void*)sa.__sigaction_u.__sa_sigaction == runtime·sigtramp)
-		return runtime·sighandler;
-	return (void*)sa.__sigaction_u.__sa_sigaction;
-}
-
-void
-runtime·signalstack(byte *p, int32 n)
-{
-	StackT st;
-
-	st.ss_sp = (void*)p;
-	st.ss_size = n;
-	st.ss_flags = 0;
-	if(p == nil)
-		st.ss_flags = SS_DISABLE;
-	runtime·sigaltstack(&st, nil);
-}
-
-void
-runtime·unblocksignals(void)
-{
-	runtime·sigprocmask(SIG_SETMASK, sigset_none);
-}
diff --git a/src/pkg/runtime/os_openbsd.h b/src/pkg/runtime/os_openbsd.h
deleted file mode 100644
index bbfde39..0000000
--- a/src/pkg/runtime/os_openbsd.h
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2010 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#define SS_DISABLE 4
-
-#define SIG_BLOCK 1
-#define SIG_UNBLOCK 2
-#define SIG_SETMASK 3
-
-typedef byte* kevent_udata;
-
-struct sigaction;
-
-void	runtime·sigpanic(void);
-
-void	runtime·setitimer(int32, Itimerval*, Itimerval*);
-void	runtime·sigaction(int32, struct sigaction*, struct sigaction*);
-void	runtime·sigaltstack(Sigaltstack*, Sigaltstack*);
-Sigset	runtime·sigprocmask(int32, Sigset);
-void	runtime·unblocksignals(void);
-int32	runtime·sysctl(uint32*, uint32, byte*, uintptr*, byte*, uintptr);
-
-#define	NSIG 33
-#define	SI_USER	0
diff --git a/src/pkg/runtime/os_plan9.c b/src/pkg/runtime/os_plan9.c
deleted file mode 100644
index 14d4fae..0000000
--- a/src/pkg/runtime/os_plan9.c
+++ /dev/null
@@ -1,418 +0,0 @@
-// Copyright 2010 The Go 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 "runtime.h"
-#include "os_GOOS.h"
-#include "arch_GOARCH.h"
-#include "../../cmd/ld/textflag.h"
-
-int8 *goos = "plan9";
-extern SigTab runtime·sigtab[];
-
-int32 runtime·postnote(int32, int8*);
-
-// Called to initialize a new m (including the bootstrap m).
-// Called on the parent thread (main thread in case of bootstrap), can allocate memory.
-void
-runtime·mpreinit(M *mp)
-{
-	// Initialize stack and goroutine for note handling.
-	mp->gsignal = runtime·malg(32*1024);
-	mp->notesig = (int8*)runtime·malloc(ERRMAX*sizeof(int8));
-
-	// Initialize stack for handling strings from the
-	// errstr system call, as used in package syscall.
-	mp->errstr = (byte*)runtime·malloc(ERRMAX*sizeof(byte));
-}
-
-// Called to initialize a new m (including the bootstrap m).
-// Called on the new thread, can not allocate memory.
-void
-runtime·minit(void)
-{
-	// Mask all SSE floating-point exceptions
-	// when running on the 64-bit kernel.
-	runtime·setfpmasks();
-}
-
-// Called from dropm to undo the effect of an minit.
-void
-runtime·unminit(void)
-{
-}
-
-
-static int32
-getproccount(void)
-{
-	int32 fd, i, n, ncpu;
-	byte buf[2048];
-
-	fd = runtime·open("/dev/sysstat", OREAD, 0);
-	if(fd < 0)
-		return 1;
-	ncpu = 0;
-	for(;;) {
-		n = runtime·read(fd, buf, sizeof buf);
-		if(n <= 0)
-			break;
-		for(i = 0; i < n; i++) {
-			if(buf[i] == '\n')
-				ncpu++;
-		}
-	}
-	runtime·close(fd);
-	return ncpu > 0 ? ncpu : 1;
-}
-
-static int32
-getpid(void)
-{
-	byte b[20], *c;
-	int32 fd;
-
-	runtime·memclr(b, sizeof(b));
-	fd = runtime·open("#c/pid", 0, 0);
-	if(fd >= 0) {
-		runtime·read(fd, b, sizeof(b));
-		runtime·close(fd);
-	}
-	c = b;
-	while(*c == ' ' || *c == '\t')
-		c++;
-	return runtime·atoi(c);
-}
-
-void
-runtime·osinit(void)
-{
-	runtime·ncpu = getproccount();
-	m->procid = getpid();
-	runtime·notify(runtime·sigtramp);
-}
-
-void
-runtime·crash(void)
-{
-	runtime·notify(nil);
-	*(int32*)0 = 0;
-}
-
-void
-runtime·get_random_data(byte **rnd, int32 *rnd_len)
-{
-	static byte random_data[HashRandomBytes];
-	int32 fd;
-
-	fd = runtime·open("/dev/random", 0 /* O_RDONLY */, 0);
-	if(runtime·read(fd, random_data, HashRandomBytes) == HashRandomBytes) {
-		*rnd = random_data;
-		*rnd_len = HashRandomBytes;
-	} else {
-		*rnd = nil;
-		*rnd_len = 0;
-	}
-	runtime·close(fd);
-}
-
-void
-runtime·goenvs(void)
-{
-}
-
-void
-runtime·initsig(void)
-{
-}
-
-#pragma textflag NOSPLIT
-void
-runtime·osyield(void)
-{
-	runtime·sleep(0);
-}
-
-#pragma textflag NOSPLIT
-void
-runtime·usleep(uint32 µs)
-{
-	uint32 ms;
-
-	ms = µs/1000;
-	if(ms == 0)
-		ms = 1;
-	runtime·sleep(ms);
-}
-
-void
-time·now(int64 sec, int32 nsec)
-{
-	int64 ns;
-
-	ns = runtime·nanotime();
-	sec = ns / 1000000000LL;
-	nsec = ns - sec * 1000000000LL;
-	FLUSH(&sec);
-	FLUSH(&nsec);
-}
-
-void
-runtime·itoa(int32 n, byte *p, uint32 len)
-{
-	byte *q, c;
-	uint32 i;
-
-	if(len <= 1)
-		return;
-
-	runtime·memclr(p, len);
-	q = p;
-
-	if(n==0) {
-		*q++ = '0';
-		USED(q);
-		return;
-	}
-	if(n < 0) {
-		*q++ = '-';
-		p++;
-		n = -n;
-	}
-	for(i=0; n > 0 && i < len; i++) {
-		*q++ = '0' + (n%10);
-		n = n/10;
-	}
-	for(q--; q >= p; ) {
-		c = *p;
-		*p++ = *q;
-		*q-- = c;
-	}
-}
-
-void
-runtime·goexitsall(int8 *status)
-{
-	int8 buf[ERRMAX];
-	M *mp;
-	int32 pid;
-
-	runtime·snprintf((byte*)buf, sizeof buf, "go: exit %s", status);
-	pid = getpid();
-	for(mp=runtime·atomicloadp(&runtime·allm); mp; mp=mp->alllink)
-		if(mp->procid != pid)
-			runtime·postnote(mp->procid, buf);
-}
-
-int32
-runtime·postnote(int32 pid, int8* msg)
-{
-	int32 fd;
-	intgo len;
-	uint8 buf[128];
-	uint8 tmp[16];
-	uint8 *p, *q;
-
-	runtime·memclr(buf, sizeof buf);
-
-	/* build path string /proc/pid/note */
-	q = tmp;
-	p = buf;
-	runtime·itoa(pid, tmp, sizeof tmp);
-	runtime·memmove((void*)p, (void*)"/proc/", 6);
-	for(p += 6; *p++ = *q++; );
-	p--;
-	runtime·memmove((void*)p, (void*)"/note", 5);
-
-	fd = runtime·open((int8*)buf, OWRITE, 0);
-	if(fd < 0)
-		return -1;
-
-	len = runtime·findnull((byte*)msg);
-	if(runtime·write(fd, msg, len) != len) {
-		runtime·close(fd);
-		return -1;
-	}
-	runtime·close(fd);
-	return 0;
-}
-
-void
-runtime·exit(int32 e)
-{
-	byte tmp[16];
-	int8 *status;
- 
-	if(e == 0)
-		status = "";
-	else {
-		/* build error string */
-		runtime·itoa(e, tmp, sizeof tmp);
-		status = (int8*)tmp;
-	}
-
-	runtime·goexitsall(status);
-	runtime·exits(status);
-}
-
-void
-runtime·newosproc(M *mp, void *stk)
-{
-	mp->tls[0] = mp->id;	// so 386 asm can find it
-	if(0){
-		runtime·printf("newosproc stk=%p m=%p g=%p rfork=%p id=%d/%d ostk=%p\n",
-			stk, mp, mp->g0, runtime·rfork, mp->id, (int32)mp->tls[0], &mp);
-	}
-
-	if(runtime·rfork(RFPROC|RFMEM|RFNOWAIT, stk, mp, mp->g0, runtime·mstart) < 0)
-		runtime·throw("newosproc: rfork failed");
-}
-
-uintptr
-runtime·semacreate(void)
-{
-	return 1;
-}
-
-#pragma textflag NOSPLIT
-int32
-runtime·semasleep(int64 ns)
-{
-	int32 ret;
-	int32 ms;
-
-	if(ns >= 0) {
-		ms = runtime·timediv(ns, 1000000, nil);
-		if(ms == 0)
-			ms = 1;
-		ret = runtime·plan9_tsemacquire(&m->waitsemacount, ms);
-		if(ret == 1)
-			return 0;  // success
-		return -1;  // timeout or interrupted
-	}
-
-	while(runtime·plan9_semacquire(&m->waitsemacount, 1) < 0) {
-		/* interrupted; try again (c.f. lock_sema.c) */
-	}
-	return 0;  // success
-}
-
-void
-runtime·semawakeup(M *mp)
-{
-	runtime·plan9_semrelease(&mp->waitsemacount, 1);
-}
-
-void
-os·sigpipe(void)
-{
-	runtime·throw("too many writes on closed pipe");
-}
-
-static int64
-atolwhex(byte *p)
-{
-	int64 n;
-	int32 f;
-
-	n = 0;
-	f = 0;
-	while(*p == ' ' || *p == '\t')
-		p++;
-	if(*p == '-' || *p == '+') {
-		if(*p++ == '-')
-			f = 1;
-		while(*p == ' ' || *p == '\t')
-			p++;
-	}
-	if(p[0] == '0' && p[1]) {
-		if(p[1] == 'x' || p[1] == 'X') {
-			p += 2;
-			for(;;) {
-				if('0' <= *p && *p <= '9')
-					n = n*16 + *p++ - '0';
-				else if('a' <= *p && *p <= 'f')
-					n = n*16 + *p++ - 'a' + 10;
-				else if('A' <= *p && *p <= 'F')
-					n = n*16 + *p++ - 'A' + 10;
-				else
-					break;
-			}
-		} else
-			while('0' <= *p && *p <= '7')
-				n = n*8 + *p++ - '0';
-	} else
-		while('0' <= *p && *p <= '9')
-			n = n*10 + *p++ - '0';
-	if(f)
-		n = -n;
-	return n;
-}
-
-void
-runtime·sigpanic(void)
-{
-	byte *p;
-
-	if(!runtime·canpanic(g))
-		runtime·throw("unexpected signal during runtime execution");
-
-	switch(g->sig) {
-	case SIGRFAULT:
-	case SIGWFAULT:
-		p = runtime·strstr((byte*)m->notesig, (byte*)"addr=")+5;
-		g->sigcode1 = atolwhex(p);
-		if(g->sigcode1 < 0x1000 || g->paniconfault) {
-			if(g->sigpc == 0)
-				runtime·panicstring("call of nil func value");
-			runtime·panicstring("invalid memory address or nil pointer dereference");
-		}
-		runtime·printf("unexpected fault address %p\n", g->sigcode1);
-		runtime·throw("fault");
-		break;
-	case SIGTRAP:
-		if(g->paniconfault)
-			runtime·panicstring("invalid memory address or nil pointer dereference");
-		runtime·throw(m->notesig);
-		break;
-	case SIGINTDIV:
-		runtime·panicstring("integer divide by zero");
-		break;
-	case SIGFLOAT:
-		runtime·panicstring("floating point error");
-		break;
-	default:
-		runtime·panicstring(m->notesig);
-		break;
-	}
-}
-
-int32
-runtime·read(int32 fd, void *buf, int32 nbytes)
-{
-	return runtime·pread(fd, buf, nbytes, -1LL);
-}
-
-int32
-runtime·write(uintptr fd, void *buf, int32 nbytes)
-{
-	return runtime·pwrite((int32)fd, buf, nbytes, -1LL);
-}
-
-uintptr
-runtime·memlimit(void)
-{
-	return 0;
-}
-
-#pragma dataflag NOPTR
-static int8 badsignal[] = "runtime: signal received on thread not created by Go.\n";
-
-// This runs on a foreign stack, without an m or a g.  No stack split.
-#pragma textflag NOSPLIT
-void
-runtime·badsignal2(void)
-{
-	runtime·pwrite(2, badsignal, sizeof badsignal - 1, -1LL);
-	runtime·exits(badsignal);
-}
diff --git a/src/pkg/runtime/os_plan9.h b/src/pkg/runtime/os_plan9.h
deleted file mode 100644
index 00ea836..0000000
--- a/src/pkg/runtime/os_plan9.h
+++ /dev/null
@@ -1,89 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Plan 9-specific system calls
-int32	runtime·pread(int32 fd, void *buf, int32 nbytes, int64 offset);
-int32	runtime·pwrite(int32 fd, void *buf, int32 nbytes, int64 offset);
-int64	runtime·seek(int32 fd, int64 offset, int32 whence);
-void	runtime·exits(int8* msg);
-intptr	runtime·brk_(void*);
-int32	runtime·sleep(int32 ms);
-int32	runtime·rfork(int32 flags, void *stk, M *mp, G *gp, void (*fn)(void));
-int32	runtime·plan9_semacquire(uint32 *addr, int32 block);
-int32	runtime·plan9_tsemacquire(uint32 *addr, int32 ms);
-int32 	runtime·plan9_semrelease(uint32 *addr, int32 count);
-int32	runtime·notify(void (*fn)(void*, int8*));
-int32	runtime·noted(int32);
-void	runtime·sigtramp(void*, int8*);
-void	runtime·sigpanic(void);
-void	runtime·goexitsall(int8*);
-void	runtime·setfpmasks(void);
-
-/* open */
-enum
-{
-	OREAD	= 0,
-	OWRITE	= 1,
-	ORDWR	= 2,
-	OEXEC	= 3,
-	OTRUNC	= 16,
-	OCEXEC	= 32,
-	ORCLOSE	= 64,
-	OEXCL	= 0x1000
-};
-
-/* rfork */
-enum
-{
-	RFNAMEG         = (1<<0),
-	RFENVG          = (1<<1),
-	RFFDG           = (1<<2),
-	RFNOTEG         = (1<<3),
-	RFPROC          = (1<<4),
-	RFMEM           = (1<<5),
-	RFNOWAIT        = (1<<6),
-	RFCNAMEG        = (1<<10),
-	RFCENVG         = (1<<11),
-	RFCFDG          = (1<<12),
-	RFREND          = (1<<13),
-	RFNOMNT         = (1<<14)
-};
-
-/* notify */
-enum
-{
-	NCONT	= 0,
-	NDFLT	= 1
-};
-
-typedef struct Tos Tos;
-typedef intptr Plink;
-
-struct Tos {
-	struct			/* Per process profiling */
-	{
-		Plink	*pp;	/* known to be 0(ptr) */
-		Plink	*next;	/* known to be 4(ptr) */
-		Plink	*last;
-		Plink	*first;
-		uint32	pid;
-		uint32	what;
-	} prof;
-	uint64	cyclefreq;	/* cycle clock frequency if there is one, 0 otherwise */
-	int64	kcycles;	/* cycles spent in kernel */
-	int64	pcycles;	/* cycles spent in process (kernel + user) */
-	uint32	pid;		/* might as well put the pid here */
-	uint32	clock;
-	/* top of stack is here */
-};
-
-#define	NSIG	14	/* number of signals in runtime·SigTab array */
-#define	ERRMAX	128	/* max length of note string */
-
-/* Notes in runtime·sigtab that are handled by runtime·sigpanic. */
-#define	SIGRFAULT	2
-#define	SIGWFAULT	3
-#define	SIGINTDIV	4
-#define	SIGFLOAT	5
-#define	SIGTRAP		6
diff --git a/src/pkg/runtime/os_plan9_386.c b/src/pkg/runtime/os_plan9_386.c
deleted file mode 100644
index 80d711f..0000000
--- a/src/pkg/runtime/os_plan9_386.c
+++ /dev/null
@@ -1,150 +0,0 @@
-// Copyright 2010 The Go 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 "runtime.h"
-#include "defs_GOOS_GOARCH.h"
-#include "os_GOOS.h"
-#include "signals_GOOS.h"
-
-void
-runtime·dumpregs(Ureg *u)
-{
-	runtime·printf("ax	%x\n", u->ax);
-	runtime·printf("bx	%x\n", u->bx);
-	runtime·printf("cx	%x\n", u->cx);
-	runtime·printf("dx	%x\n", u->dx);
-	runtime·printf("di	%x\n", u->di);
-	runtime·printf("si	%x\n", u->si);
-	runtime·printf("bp	%x\n", u->bp);
-	runtime·printf("sp	%x\n", u->sp);
-	runtime·printf("pc	%x\n", u->pc);
-	runtime·printf("flags	%x\n", u->flags);
-	runtime·printf("cs	%x\n", u->cs);
-	runtime·printf("fs	%x\n", u->fs);
-	runtime·printf("gs	%x\n", u->gs);
-}
-
-int32
-runtime·sighandler(void *v, int8 *note, G *gp)
-{
-	uintptr *sp;
-	SigTab *t;
-	bool crash;
-	Ureg *ureg;
-	intgo len, n;
-	int32 sig, flags;
-
-	ureg = (Ureg*)v;
-
-	// The kernel will never pass us a nil note or ureg so we probably
-	// made a mistake somewhere in runtime·sigtramp.
-	if(ureg == nil || note == nil) {
-		runtime·printf("sighandler: ureg %p note %p\n", ureg, note);
-		goto Throw;
-	}
-
-	// Check that the note is no more than ERRMAX bytes (including
-	// the trailing NUL). We should never receive a longer note.
-	len = runtime·findnull((byte*)note);
-	if(len > ERRMAX-1) {
-		runtime·printf("sighandler: note is longer than ERRMAX\n");
-		goto Throw;
-	}
-
-	// See if the note matches one of the patterns in runtime·sigtab.
-	// Notes that do not match any pattern can be handled at a higher
-	// level by the program but will otherwise be ignored.
-	flags = SigNotify;
-	for(sig = 0; sig < nelem(runtime·sigtab); sig++) {
-		t = &runtime·sigtab[sig];
-		n = runtime·findnull((byte*)t->name);
-		if(len < n)
-			continue;
-		if(runtime·strncmp((byte*)note, (byte*)t->name, n) == 0) {
-			flags = t->flags;
-			break;
-		}
-	}
-
-	if(flags & SigGoExit)
-		runtime·exits(note+9); // Strip "go: exit " prefix.
-
-	if(flags & SigPanic) {
-		// Copy the error string from sigtramp's stack into m->notesig so
-		// we can reliably access it from the panic routines.
-		runtime·memmove(m->notesig, note, len+1);
-
-		gp->sig = sig;
-		gp->sigpc = ureg->pc;
-
-		// Only push runtime·sigpanic if PC != 0.
-		//
-		// If PC == 0, probably panicked because of a call to a nil func.
-		// Not pushing that onto SP will make the trace look like a call
-		// to runtime·sigpanic instead. (Otherwise the trace will end at
-		// runtime·sigpanic and we won't get to see who faulted).
-		if(ureg->pc != 0) {
-			sp = (uintptr*)ureg->sp;
-			*--sp = ureg->pc;
-			ureg->sp = (uint32)sp;
-		}
-		ureg->pc = (uintptr)runtime·sigpanic;
-		return NCONT;
-	}
-
-	if(flags & SigNotify) {
-		// TODO(ality): See if os/signal wants it.
-		//if(runtime·sigsend(...))
-		//	return NCONT;
-	}
-	if(flags & SigKill)
-		goto Exit;
-	if(!(flags & SigThrow))
-		return NCONT;
-
-Throw:
-	m->throwing = 1;
-	m->caughtsig = gp;
-	runtime·startpanic();
-
-	runtime·printf("%s\n", note);
-	runtime·printf("PC=%x\n", ureg->pc);
-	runtime·printf("\n");
-
-	if(runtime·gotraceback(&crash)) {
-		runtime·goroutineheader(gp);
-		runtime·traceback(ureg->pc, ureg->sp, 0, gp);
-		runtime·tracebackothers(gp);
-		runtime·printf("\n");
-		runtime·dumpregs(ureg);
-	}
-	
-	if(crash)
-		runtime·crash();
-
-Exit:
-	runtime·goexitsall(note);
-	runtime·exits(note);
-	return NDFLT; // not reached
-}
-
-void
-runtime·sigenable(uint32 sig)
-{
-	USED(sig);
-}
-
-void
-runtime·sigdisable(uint32 sig)
-{
-	USED(sig);
-}
-
-void
-runtime·resetcpuprofiler(int32 hz)
-{
-	// TODO: Enable profiling interrupts.
-	
-	m->profilehz = hz;
-}
diff --git a/src/pkg/runtime/os_plan9_amd64.c b/src/pkg/runtime/os_plan9_amd64.c
deleted file mode 100644
index a4e5ba8..0000000
--- a/src/pkg/runtime/os_plan9_amd64.c
+++ /dev/null
@@ -1,158 +0,0 @@
-// Copyright 2010 The Go 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 "runtime.h"
-#include "defs_GOOS_GOARCH.h"
-#include "os_GOOS.h"
-#include "signals_GOOS.h"
-
-void
-runtime·dumpregs(Ureg *u)
-{
-	runtime·printf("ax	%X\n", u->ax);
-	runtime·printf("bx	%X\n", u->bx);
-	runtime·printf("cx	%X\n", u->cx);
-	runtime·printf("dx	%X\n", u->dx);
-	runtime·printf("di	%X\n", u->di);
-	runtime·printf("si	%X\n", u->si);
-	runtime·printf("bp	%X\n", u->bp);
-	runtime·printf("sp	%X\n", u->sp);
-	runtime·printf("r8	%X\n", u->r8);
-	runtime·printf("r9	%X\n", u->r9);
-	runtime·printf("r10	%X\n", u->r10);
-	runtime·printf("r11	%X\n", u->r11);
-	runtime·printf("r12	%X\n", u->r12);
-	runtime·printf("r13	%X\n", u->r13);
-	runtime·printf("r14	%X\n", u->r14);
-	runtime·printf("r15	%X\n", u->r15);
-	runtime·printf("ip	%X\n", u->ip);
-	runtime·printf("flags	%X\n", u->flags);
-	runtime·printf("cs	%X\n", (uint64)u->cs);
-	runtime·printf("fs	%X\n", (uint64)u->fs);
-	runtime·printf("gs	%X\n", (uint64)u->gs);
-}
-
-int32
-runtime·sighandler(void *v, int8 *note, G *gp)
-{
-	uintptr *sp;
-	SigTab *t;
-	bool crash;
-	Ureg *ureg;
-	intgo len, n;
-	int32 sig, flags;
-
-	ureg = (Ureg*)v;
-
-	// The kernel will never pass us a nil note or ureg so we probably
-	// made a mistake somewhere in runtime·sigtramp.
-	if(ureg == nil || note == nil) {
-		runtime·printf("sighandler: ureg %p note %p\n", ureg, note);
-		goto Throw;
-	}
-
-	// Check that the note is no more than ERRMAX bytes (including
-	// the trailing NUL). We should never receive a longer note.
-	len = runtime·findnull((byte*)note);
-	if(len > ERRMAX-1) {
-		runtime·printf("sighandler: note is longer than ERRMAX\n");
-		goto Throw;
-	}
-
-	// See if the note matches one of the patterns in runtime·sigtab.
-	// Notes that do not match any pattern can be handled at a higher
-	// level by the program but will otherwise be ignored.
-	flags = SigNotify;
-	for(sig = 0; sig < nelem(runtime·sigtab); sig++) {
-		t = &runtime·sigtab[sig];
-		n = runtime·findnull((byte*)t->name);
-		if(len < n)
-			continue;
-		if(runtime·strncmp((byte*)note, (byte*)t->name, n) == 0) {
-			flags = t->flags;
-			break;
-		}
-	}
-
-	if(flags & SigGoExit)
-		runtime·exits(note+9); // Strip "go: exit " prefix.
-
-	if(flags & SigPanic) {
-		// Copy the error string from sigtramp's stack into m->notesig so
-		// we can reliably access it from the panic routines.
-		runtime·memmove(m->notesig, note, len+1);
-
-		gp->sig = sig;
-		gp->sigpc = ureg->ip;
-
-		// Only push runtime·sigpanic if PC != 0.
-		//
-		// If PC == 0, probably panicked because of a call to a nil func.
-		// Not pushing that onto SP will make the trace look like a call
-		// to runtime·sigpanic instead. (Otherwise the trace will end at
-		// runtime·sigpanic and we won't get to see who faulted).
-		if(ureg->ip != 0) {
-			sp = (uintptr*)ureg->sp;
-			*--sp = ureg->ip;
-			ureg->sp = (uint64)sp;
-		}
-		ureg->ip = (uintptr)runtime·sigpanic;
-		return NCONT;
-	}
-
-	if(flags & SigNotify) {
-		// TODO(ality): See if os/signal wants it.
-		//if(runtime·sigsend(...))
-		//	return NCONT;
-	}
-	if(flags & SigKill)
-		goto Exit;
-	if(!(flags & SigThrow))
-		return NCONT;
-
-Throw:
-	m->throwing = 1;
-	m->caughtsig = gp;
-	runtime·startpanic();
-
-	runtime·printf("%s\n", note);
-	runtime·printf("PC=%X\n", ureg->ip);
-	runtime·printf("\n");
-
-	if(runtime·gotraceback(&crash)) {
-		runtime·goroutineheader(gp);
-		runtime·traceback(ureg->ip, ureg->sp, 0, gp);
-		runtime·tracebackothers(gp);
-		runtime·printf("\n");
-		runtime·dumpregs(ureg);
-	}
-	
-	if(crash)
-		runtime·crash();
-
-Exit:
-	runtime·goexitsall(note);
-	runtime·exits(note);
-	return NDFLT; // not reached
-}
-
-void
-runtime·sigenable(uint32 sig)
-{
-	USED(sig);
-}
-
-void
-runtime·sigdisable(uint32 sig)
-{
-	USED(sig);
-}
-
-void
-runtime·resetcpuprofiler(int32 hz)
-{
-	// TODO: Enable profiling interrupts.
-	
-	m->profilehz = hz;
-}
diff --git a/src/pkg/runtime/os_solaris.c b/src/pkg/runtime/os_solaris.c
deleted file mode 100644
index c6bbea3..0000000
--- a/src/pkg/runtime/os_solaris.c
+++ /dev/null
@@ -1,583 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "runtime.h"
-#include "defs_GOOS_GOARCH.h"
-#include "os_GOOS.h"
-#include "signal_unix.h"
-#include "stack.h"
-#include "../../cmd/ld/textflag.h"
-
-#pragma dynexport end _end
-#pragma dynexport etext _etext
-#pragma dynexport edata _edata
-
-#pragma dynimport libc·___errno ___errno "libc.so"
-#pragma dynimport libc·clock_gettime clock_gettime "libc.so"
-#pragma dynimport libc·close close "libc.so"
-#pragma dynimport libc·exit exit "libc.so"
-#pragma dynimport libc·fstat fstat "libc.so"
-#pragma dynimport libc·getcontext getcontext "libc.so"
-#pragma dynimport libc·getrlimit getrlimit "libc.so"
-#pragma dynimport libc·malloc malloc "libc.so"
-#pragma dynimport libc·mmap mmap "libc.so"
-#pragma dynimport libc·munmap munmap "libc.so"
-#pragma dynimport libc·open open "libc.so"
-#pragma dynimport libc·pthread_attr_destroy pthread_attr_destroy "libc.so"
-#pragma dynimport libc·pthread_attr_getstack pthread_attr_getstack "libc.so"
-#pragma dynimport libc·pthread_attr_init pthread_attr_init "libc.so"
-#pragma dynimport libc·pthread_attr_setdetachstate pthread_attr_setdetachstate "libc.so"
-#pragma dynimport libc·pthread_attr_setstack pthread_attr_setstack "libc.so"
-#pragma dynimport libc·pthread_create pthread_create "libc.so"
-#pragma dynimport libc·raise raise "libc.so"
-#pragma dynimport libc·read read "libc.so"
-#pragma dynimport libc·select select "libc.so"
-#pragma dynimport libc·sched_yield sched_yield "libc.so"
-#pragma dynimport libc·sem_init sem_init "libc.so"
-#pragma dynimport libc·sem_post sem_post "libc.so"
-#pragma dynimport libc·sem_reltimedwait_np sem_reltimedwait_np "libc.so"
-#pragma dynimport libc·sem_wait sem_wait "libc.so"
-#pragma dynimport libc·setitimer setitimer "libc.so"
-#pragma dynimport libc·sigaction sigaction "libc.so"
-#pragma dynimport libc·sigaltstack sigaltstack "libc.so"
-#pragma dynimport libc·sigprocmask sigprocmask "libc.so"
-#pragma dynimport libc·sysconf sysconf "libc.so"
-#pragma dynimport libc·usleep usleep "libc.so"
-#pragma dynimport libc·write write "libc.so"
-
-extern uintptr libc·___errno;
-extern uintptr libc·clock_gettime;
-extern uintptr libc·close;
-extern uintptr libc·exit;
-extern uintptr libc·fstat;
-extern uintptr libc·getcontext;
-extern uintptr libc·getrlimit;
-extern uintptr libc·malloc;
-extern uintptr libc·mmap;
-extern uintptr libc·munmap;
-extern uintptr libc·open;
-extern uintptr libc·pthread_attr_destroy;
-extern uintptr libc·pthread_attr_getstack;
-extern uintptr libc·pthread_attr_init;
-extern uintptr libc·pthread_attr_setdetachstate;
-extern uintptr libc·pthread_attr_setstack;
-extern uintptr libc·pthread_create;
-extern uintptr libc·raise;
-extern uintptr libc·read;
-extern uintptr libc·sched_yield;
-extern uintptr libc·select;
-extern uintptr libc·sem_init;
-extern uintptr libc·sem_post;
-extern uintptr libc·sem_reltimedwait_np;
-extern uintptr libc·sem_wait;
-extern uintptr libc·setitimer;
-extern uintptr libc·sigaction;
-extern uintptr libc·sigaltstack;
-extern uintptr libc·sigprocmask;
-extern uintptr libc·sysconf;
-extern uintptr libc·usleep;
-extern uintptr libc·write;
-
-void	runtime·getcontext(Ucontext *context);
-int32	runtime·pthread_attr_destroy(PthreadAttr* attr);
-int32	runtime·pthread_attr_init(PthreadAttr* attr);
-int32	runtime·pthread_attr_getstack(PthreadAttr* attr, void** addr, uint64* size);
-int32	runtime·pthread_attr_setdetachstate(PthreadAttr* attr, int32 state);
-int32	runtime·pthread_attr_setstack(PthreadAttr* attr, void* addr, uint64 size);
-int32	runtime·pthread_create(Pthread* thread, PthreadAttr* attr, void(*fn)(void), void *arg);
-uint32	runtime·tstart_sysvicall(M *newm);
-int32	runtime·sem_init(SemT* sem, int32 pshared, uint32 value);
-int32	runtime·sem_post(SemT* sem);
-int32	runtime·sem_reltimedwait_np(SemT* sem, Timespec* timeout);
-int32	runtime·sem_wait(SemT* sem);
-int64	runtime·sysconf(int32 name);
-
-extern SigTab runtime·sigtab[];
-static Sigset sigset_none;
-static Sigset sigset_all = { ~(uint32)0, ~(uint32)0, ~(uint32)0, ~(uint32)0, };
-
-// Calling sysvcall on os stack.
-#pragma textflag NOSPLIT
-uintptr
-runtime·sysvicall6(uintptr fn, int32 count, ...)
-{
-	runtime·memclr((byte*)&m->scratch, sizeof(m->scratch));
-	m->libcall.fn = (void*)fn;
-	m->libcall.n = (uintptr)count;
-	for(;count; count--)
-		m->scratch.v[count - 1] = *((uintptr*)&count + count);
-	m->libcall.args = (uintptr*)&m->scratch.v[0];
-	runtime·asmcgocall(runtime·asmsysvicall6, &m->libcall);
-	return m->libcall.r1;
-}
-
-static int32
-getncpu(void) 
-{
-	int32 n;
-	
-	n = (int32)runtime·sysconf(_SC_NPROCESSORS_ONLN);
-	if(n < 1)
-		return 1;
-	return n;
-}
-
-void
-runtime·osinit(void)
-{
-	runtime·ncpu = getncpu(); 
-}
-
-void
-runtime·newosproc(M *mp, void *stk)
-{
-	PthreadAttr attr;
-	Sigset oset;
-	Pthread tid;
-	int32 ret;
-
-	USED(stk);
-	if(runtime·pthread_attr_init(&attr) != 0)
-		runtime·throw("pthread_attr_init");
-	if(runtime·pthread_attr_setstack(&attr, 0, 0x200000) != 0)
-		runtime·throw("pthread_attr_setstack");
-	if(runtime·pthread_attr_getstack(&attr, (void**)&mp->g0->stackbase, &mp->g0->stacksize) != 0)
-		runtime·throw("pthread_attr_getstack");	
-	if(runtime·pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) != 0)
-		runtime·throw("pthread_attr_setdetachstate");
-
-	// Disable signals during create, so that the new thread starts
-	// with signals disabled.  It will enable them in minit.
-	runtime·sigprocmask(SIG_SETMASK, &sigset_all, &oset);
-	ret = runtime·pthread_create(&tid, &attr, (void (*)(void))runtime·tstart_sysvicall, mp);
-	runtime·sigprocmask(SIG_SETMASK, &oset, nil);
-	if(ret != 0) {
-		runtime·printf("runtime: failed to create new OS thread (have %d already; errno=%d)\n", runtime·mcount(), ret);
-		runtime·throw("runtime.newosproc");
-	}
-}
-
-void
-runtime·get_random_data(byte **rnd, int32 *rnd_len)
-{
-	#pragma dataflag NOPTR
-	static byte urandom_data[HashRandomBytes];
-	int32 fd;
-	fd = runtime·open("/dev/urandom", 0 /* O_RDONLY */, 0);
-	if(runtime·read(fd, urandom_data, HashRandomBytes) == HashRandomBytes) {
-		*rnd = urandom_data;
-		*rnd_len = HashRandomBytes;
-	} else {
-		*rnd = nil;
-		*rnd_len = 0;
-	}
-	runtime·close(fd);
-}
-
-void
-runtime·goenvs(void)
-{
-	runtime·goenvs_unix();
-}
-
-// Called to initialize a new m (including the bootstrap m).
-// Called on the parent thread (main thread in case of bootstrap), can allocate memory.
-void
-runtime·mpreinit(M *mp)
-{
-	mp->gsignal = runtime·malg(32*1024);
-}
-
-// Called to initialize a new m (including the bootstrap m).
-// Called on the new thread, can not allocate memory.
-void
-runtime·minit(void)
-{
-	runtime·asmcgocall(runtime·miniterrno, (void *)libc·___errno);
-	// Initialize signal handling
-	runtime·signalstack((byte*)m->gsignal->stackguard - StackGuard, 32*1024);
-	runtime·sigprocmask(SIG_SETMASK, &sigset_none, nil);
-}
-
-// Called from dropm to undo the effect of an minit.
-void
-runtime·unminit(void)
-{
-	runtime·signalstack(nil, 0);
-}
-
-void
-runtime·sigpanic(void)
-{
-	if(!runtime·canpanic(g))
-		runtime·throw("unexpected signal during runtime execution");
-
-	switch(g->sig) {
-	case SIGBUS:
-		if(g->sigcode0 == BUS_ADRERR && g->sigcode1 < 0x1000 || g->paniconfault) {
-			if(g->sigpc == 0)
-				runtime·panicstring("call of nil func value");
-			runtime·panicstring("invalid memory address or nil pointer dereference");
-		}
-		runtime·printf("unexpected fault address %p\n", g->sigcode1);
-		runtime·throw("fault");
-	case SIGSEGV:
-		if((g->sigcode0 == 0 || g->sigcode0 == SEGV_MAPERR || g->sigcode0 == SEGV_ACCERR) && g->sigcode1 < 0x1000 || g->paniconfault) {
-			if(g->sigpc == 0)
-				runtime·panicstring("call of nil func value");
-			runtime·panicstring("invalid memory address or nil pointer dereference");
-		}
-		runtime·printf("unexpected fault address %p\n", g->sigcode1);
-		runtime·throw("fault");
-	case SIGFPE:
-		switch(g->sigcode0) {
-		case FPE_INTDIV:
-			runtime·panicstring("integer divide by zero");
-		case FPE_INTOVF:
-			runtime·panicstring("integer overflow");
-		}
-		runtime·panicstring("floating point error");
-	}
-	runtime·panicstring(runtime·sigtab[g->sig].name);
-}
-
-uintptr
-runtime·memlimit(void)
-{
-	Rlimit rl;
-	extern byte text[], end[];
-	uintptr used;
-	
-	if(runtime·getrlimit(RLIMIT_AS, &rl) != 0)
-		return 0;
-	if(rl.rlim_cur >= 0x7fffffff)
-		return 0;
-
-	// Estimate our VM footprint excluding the heap.
-	// Not an exact science: use size of binary plus
-	// some room for thread stacks.
-	used = end - text + (64<<20);
-	if(used >= rl.rlim_cur)
-		return 0;
-
-	// If there's not at least 16 MB left, we're probably
-	// not going to be able to do much.  Treat as no limit.
-	rl.rlim_cur -= used;
-	if(rl.rlim_cur < (16<<20))
-		return 0;
-
-	return rl.rlim_cur - used;
-}
-
-void
-runtime·setprof(bool on)
-{
-	USED(on);
-}
-
-extern void runtime·sigtramp(void);
-
-void
-runtime·setsig(int32 i, GoSighandler *fn, bool restart)
-{
-	Sigaction sa;
-
-	runtime·memclr((byte*)&sa, sizeof sa);
-	sa.sa_flags = SA_SIGINFO|SA_ONSTACK;
-	if(restart)
-		sa.sa_flags |= SA_RESTART;
-	sa.sa_mask.__sigbits[0] = ~(uint32)0;
-	sa.sa_mask.__sigbits[1] = ~(uint32)0;
-	sa.sa_mask.__sigbits[2] = ~(uint32)0;
-	sa.sa_mask.__sigbits[3] = ~(uint32)0;
-	if(fn == runtime·sighandler)
-		fn = (void*)runtime·sigtramp;
-	*((void**)&sa._funcptr[0]) = (void*)fn;
-	runtime·sigaction(i, &sa, nil);
-}
-
-GoSighandler*
-runtime·getsig(int32 i)
-{
-	Sigaction sa;
-
-	runtime·memclr((byte*)&sa, sizeof sa);
-	runtime·sigaction(i, nil, &sa);
-	if(*((void**)&sa._funcptr[0]) == runtime·sigtramp)
-		return runtime·sighandler;
-	return *((void**)&sa._funcptr[0]);
-}
-
-void
-runtime·signalstack(byte *p, int32 n)
-{
-	StackT st;
-
-	st.ss_sp = (void*)p;
-	st.ss_size = n;
-	st.ss_flags = 0;
-	if(p == nil)
-		st.ss_flags = SS_DISABLE;
-	runtime·sigaltstack(&st, nil);
-}
-
-void
-runtime·unblocksignals(void)
-{
-	runtime·sigprocmask(SIG_SETMASK, &sigset_none, nil);
-}
-
-#pragma textflag NOSPLIT
-uintptr
-runtime·semacreate(void)
-{
-	SemT* sem;
-
-	// Call libc's malloc rather than runtime·malloc.  This will
-	// allocate space on the C heap.  We can't call runtime·malloc
-	// here because it could cause a deadlock.
-	m->libcall.fn = (void*)libc·malloc;
-	m->libcall.n = 1;
-	runtime·memclr((byte*)&m->scratch, sizeof(m->scratch));
-	m->scratch.v[0] = (uintptr)sizeof(*sem);
-	m->libcall.args = (uintptr*)&m->scratch;
-	runtime·asmcgocall(runtime·asmsysvicall6, &m->libcall);
-	sem = (void*)m->libcall.r1;
-	if(runtime·sem_init(sem, 0, 0) != 0)
-		runtime·throw("sem_init");
-	return (uintptr)sem;
-}
-
-#pragma textflag NOSPLIT
-int32
-runtime·semasleep(int64 ns)
-{
-	if(ns >= 0) {
-		m->ts.tv_sec = ns / 1000000000LL;
-		m->ts.tv_nsec = ns % 1000000000LL;
-
-		m->libcall.fn = (void*)libc·sem_reltimedwait_np;
-		m->libcall.n = 2;
-		runtime·memclr((byte*)&m->scratch, sizeof(m->scratch));
-		m->scratch.v[0] = m->waitsema;
-		m->scratch.v[1] = (uintptr)&m->ts;
-		m->libcall.args = (uintptr*)&m->scratch;
-		runtime·asmcgocall(runtime·asmsysvicall6, &m->libcall);
-		if(*m->perrno != 0) {
-			if(*m->perrno == ETIMEDOUT || *m->perrno == EAGAIN || *m->perrno == EINTR)
-				return -1;
-			runtime·throw("sem_reltimedwait_np");
-		}
-		return 0;
-	}
-	for(;;) {
-		m->libcall.fn = (void*)libc·sem_wait;
-		m->libcall.n = 1;
-		runtime·memclr((byte*)&m->scratch, sizeof(m->scratch));
-		m->scratch.v[0] = m->waitsema;
-		m->libcall.args = (uintptr*)&m->scratch;
-		runtime·asmcgocall(runtime·asmsysvicall6, &m->libcall);
-		if(m->libcall.r1 == 0)
-			break;
-		if(*m->perrno == EINTR) 
-			continue;
-		runtime·throw("sem_wait");
-	}
-	return 0;
-}
-
-#pragma textflag NOSPLIT
-void
-runtime·semawakeup(M *mp)
-{
-	SemT* sem = (SemT*)mp->waitsema;
-	if(runtime·sem_post(sem) != 0)
-		runtime·throw("sem_post");
-}
-
-int32
-runtime·close(int32 fd)
-{
-	return runtime·sysvicall6(libc·close, 1, (uintptr)fd);
-}
-
-void
-runtime·exit(int32 r)
-{
-	runtime·sysvicall6(libc·exit, 1, (uintptr)r);
-}
-
-/* int32 */ void
-runtime·getcontext(Ucontext* context)
-{
-	runtime·sysvicall6(libc·getcontext, 1, (uintptr)context);
-}
-
-int32
-runtime·getrlimit(int32 res, Rlimit* rlp)
-{
-	return runtime·sysvicall6(libc·getrlimit, 2, (uintptr)res, (uintptr)rlp);
-}
-
-uint8*
-runtime·mmap(byte* addr, uintptr len, int32 prot, int32 flags, int32 fildes, uint32 off)
-{
-	return (uint8*)runtime·sysvicall6(libc·mmap, 6, (uintptr)addr, (uintptr)len, (uintptr)prot, (uintptr)flags, (uintptr)fildes, (uintptr)off);
-}
-
-void
-runtime·munmap(byte* addr, uintptr len)
-{
-	runtime·sysvicall6(libc·munmap, 2, (uintptr)addr, (uintptr)len);
-}
-
-extern int64 runtime·nanotime1(void);
-#pragma textflag NOSPLIT
-int64
-runtime·nanotime(void)
-{
-	return runtime·sysvicall6((uintptr)runtime·nanotime1, 0);
-}
-
-void
-time·now(int64 sec, int32 usec)
-{
-	int64 ns;
-
-	ns = runtime·nanotime();
-	sec = ns / 1000000000LL;
-	usec = ns - sec * 1000000000LL;
-	FLUSH(&sec);
-	FLUSH(&usec);
-}
-
-int32
-runtime·open(int8* path, int32 oflag, int32 mode)
-{
-	return runtime·sysvicall6(libc·open, 3, (uintptr)path, (uintptr)oflag, (uintptr)mode);
-}
-
-int32
-runtime·pthread_attr_destroy(PthreadAttr* attr)
-{
-	return runtime·sysvicall6(libc·pthread_attr_destroy, 1, (uintptr)attr);
-}
-
-int32
-runtime·pthread_attr_getstack(PthreadAttr* attr, void** addr, uint64* size)
-{
-	return runtime·sysvicall6(libc·pthread_attr_getstack, 3, (uintptr)attr, (uintptr)addr, (uintptr)size);
-}
-
-int32
-runtime·pthread_attr_init(PthreadAttr* attr)
-{
-	return runtime·sysvicall6(libc·pthread_attr_init, 1, (uintptr)attr);
-}
-
-int32
-runtime·pthread_attr_setdetachstate(PthreadAttr* attr, int32 state)
-{
-	return runtime·sysvicall6(libc·pthread_attr_setdetachstate, 2, (uintptr)attr, (uintptr)state);
-}
-
-int32
-runtime·pthread_attr_setstack(PthreadAttr* attr, void* addr, uint64 size)
-{
-	return runtime·sysvicall6(libc·pthread_attr_setstack, 3, (uintptr)attr, (uintptr)addr, (uintptr)size);
-}
-
-int32
-runtime·pthread_create(Pthread* thread, PthreadAttr* attr, void(*fn)(void), void *arg)
-{
-	return runtime·sysvicall6(libc·pthread_create, 4, (uintptr)thread, (uintptr)attr, (uintptr)fn, (uintptr)arg);
-}
-
-/* int32 */ void
-runtime·raise(int32 sig)
-{
-	runtime·sysvicall6(libc·raise, 1, (uintptr)sig);
-}
-
-int32
-runtime·read(int32 fd, void* buf, int32 nbyte)
-{
-	return runtime·sysvicall6(libc·read, 3, (uintptr)fd, (uintptr)buf, (uintptr)nbyte);
-}
-
-#pragma textflag NOSPLIT
-int32
-runtime·sem_init(SemT* sem, int32 pshared, uint32 value)
-{
-	return runtime·sysvicall6(libc·sem_init, 3, (uintptr)sem, (uintptr)pshared, (uintptr)value);
-}
-
-#pragma textflag NOSPLIT
-int32
-runtime·sem_post(SemT* sem)
-{
-	return runtime·sysvicall6(libc·sem_post, 1, (uintptr)sem);
-}
-
-#pragma textflag NOSPLIT
-int32
-runtime·sem_reltimedwait_np(SemT* sem, Timespec* timeout)
-{
-	return runtime·sysvicall6(libc·sem_reltimedwait_np, 2, (uintptr)sem, (uintptr)timeout);
-}
-
-#pragma textflag NOSPLIT
-int32
-runtime·sem_wait(SemT* sem)
-{
-	return runtime·sysvicall6(libc·sem_wait, 1, (uintptr)sem);
-}
-
-/* int32 */ void
-runtime·setitimer(int32 which, Itimerval* value, Itimerval* ovalue)
-{
-	runtime·sysvicall6(libc·setitimer, 3, (uintptr)which, (uintptr)value, (uintptr)ovalue);
-}
-
-/* int32 */ void
-runtime·sigaction(int32 sig, struct Sigaction* act, struct Sigaction* oact)
-{
-	runtime·sysvicall6(libc·sigaction, 3, (uintptr)sig, (uintptr)act, (uintptr)oact);
-}
-
-/* int32 */ void
-runtime·sigaltstack(Sigaltstack* ss, Sigaltstack* oss)
-{
-	runtime·sysvicall6(libc·sigaltstack, 2, (uintptr)ss, (uintptr)oss);
-}
-
-/* int32 */ void
-runtime·sigprocmask(int32 how, Sigset* set, Sigset* oset)
-{
-	runtime·sysvicall6(libc·sigprocmask, 3, (uintptr)how, (uintptr)set, (uintptr)oset);
-}
-
-int64
-runtime·sysconf(int32 name)
-{
-	return runtime·sysvicall6(libc·sysconf, 1, (uintptr)name);
-}
-
-void
-runtime·usleep(uint32 us)
-{
-	runtime·sysvicall6(libc·usleep, 1, (uintptr)us);
-}
-
-int32
-runtime·write(uintptr fd, void* buf, int32 nbyte)
-{
-	return runtime·sysvicall6(libc·write, 3, (uintptr)fd, (uintptr)buf, (uintptr)nbyte);
-}
-
-void
-runtime·osyield(void)
-{
-	runtime·sysvicall6(libc·sched_yield, 0);
-}
diff --git a/src/pkg/runtime/os_solaris.h b/src/pkg/runtime/os_solaris.h
deleted file mode 100644
index f3fae5d..0000000
--- a/src/pkg/runtime/os_solaris.h
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#define SS_DISABLE 2
-
-#define SIG_BLOCK 1
-#define SIG_UNBLOCK 2
-#define SIG_SETMASK 3
-
-typedef uintptr kevent_udata;
-
-struct sigaction;
-
-void	runtime·sigpanic(void);
-
-void	runtime·setitimer(int32, Itimerval*, Itimerval*);
-void	runtime·sigaction(int32, struct Sigaction*, struct Sigaction*);
-void	runtime·sigaltstack(Sigaltstack*, Sigaltstack*);
-void	runtime·sigprocmask(int32, Sigset*, Sigset*);
-void	runtime·unblocksignals(void);
-int32	runtime·sysctl(uint32*, uint32, byte*, uintptr*, byte*, uintptr);
-
-#define	NSIG 73 /* number of signals in runtime·SigTab array */
-#define	SI_USER	0
-
-void	runtime·raisesigpipe(void);
-void	runtime·setsig(int32, void(*)(int32, Siginfo*, void*, G*), bool);
-void	runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp);
-void	runtime·sigpanic(void);
-
-#define _UC_SIGMASK	0x01
-#define _UC_CPU		0x04
-
-#define RLIMIT_AS 10
-typedef struct Rlimit Rlimit;
-struct Rlimit {
-	int64   rlim_cur;
-	int64   rlim_max;
-};
-int32   runtime·getrlimit(int32, Rlimit*);
-
-// Call a library function with SysV conventions,
-// and switch to os stack during the call.
-#pragma	varargck	countpos	runtime·sysvicall6	2
-#pragma	varargck	type		runtime·sysvicall6	uintptr
-#pragma	varargck	type		runtime·sysvicall6	int32
-void	runtime·asmsysvicall6(void *c);
-uintptr	runtime·sysvicall6(uintptr fn, int32 count, ...);
-
-void	runtime·miniterrno(void *fn);
diff --git a/src/pkg/runtime/os_windows.c b/src/pkg/runtime/os_windows.c
deleted file mode 100644
index 0dd44ed..0000000
--- a/src/pkg/runtime/os_windows.c
+++ /dev/null
@@ -1,517 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "runtime.h"
-#include "type.h"
-#include "defs_GOOS_GOARCH.h"
-#include "os_GOOS.h"
-#include "../../cmd/ld/textflag.h"
-
-#pragma dynimport runtime·AddVectoredExceptionHandler AddVectoredExceptionHandler "kernel32.dll"
-#pragma dynimport runtime·CloseHandle CloseHandle "kernel32.dll"
-#pragma dynimport runtime·CreateEvent CreateEventA "kernel32.dll"
-#pragma dynimport runtime·CreateThread CreateThread "kernel32.dll"
-#pragma dynimport runtime·CreateWaitableTimer CreateWaitableTimerA "kernel32.dll"
-#pragma dynimport runtime·CryptAcquireContextW CryptAcquireContextW "advapi32.dll"
-#pragma dynimport runtime·CryptGenRandom CryptGenRandom "advapi32.dll"
-#pragma dynimport runtime·CryptReleaseContext CryptReleaseContext "advapi32.dll"
-#pragma dynimport runtime·DuplicateHandle DuplicateHandle "kernel32.dll"
-#pragma dynimport runtime·ExitProcess ExitProcess "kernel32.dll"
-#pragma dynimport runtime·FreeEnvironmentStringsW FreeEnvironmentStringsW "kernel32.dll"
-#pragma dynimport runtime·GetEnvironmentStringsW GetEnvironmentStringsW "kernel32.dll"
-#pragma dynimport runtime·GetProcAddress GetProcAddress "kernel32.dll"
-#pragma dynimport runtime·GetStdHandle GetStdHandle "kernel32.dll"
-#pragma dynimport runtime·GetSystemInfo GetSystemInfo "kernel32.dll"
-#pragma dynimport runtime·GetSystemTimeAsFileTime GetSystemTimeAsFileTime "kernel32.dll"
-#pragma dynimport runtime·GetThreadContext GetThreadContext "kernel32.dll"
-#pragma dynimport runtime·LoadLibrary LoadLibraryW "kernel32.dll"
-#pragma dynimport runtime·LoadLibraryA LoadLibraryA "kernel32.dll"
-#pragma dynimport runtime·NtWaitForSingleObject NtWaitForSingleObject "ntdll.dll"
-#pragma dynimport runtime·ResumeThread ResumeThread "kernel32.dll"
-#pragma dynimport runtime·SetConsoleCtrlHandler SetConsoleCtrlHandler "kernel32.dll"
-#pragma dynimport runtime·SetEvent SetEvent "kernel32.dll"
-#pragma dynimport runtime·SetProcessPriorityBoost SetProcessPriorityBoost "kernel32.dll"
-#pragma dynimport runtime·SetThreadPriority SetThreadPriority "kernel32.dll"
-#pragma dynimport runtime·SetWaitableTimer SetWaitableTimer "kernel32.dll"
-#pragma dynimport runtime·Sleep Sleep "kernel32.dll"
-#pragma dynimport runtime·SuspendThread SuspendThread "kernel32.dll"
-#pragma dynimport runtime·WaitForSingleObject WaitForSingleObject "kernel32.dll"
-#pragma dynimport runtime·WriteFile WriteFile "kernel32.dll"
-#pragma dynimport runtime·timeBeginPeriod timeBeginPeriod "winmm.dll"
-
-extern void *runtime·AddVectoredExceptionHandler;
-extern void *runtime·CloseHandle;
-extern void *runtime·CreateEvent;
-extern void *runtime·CreateThread;
-extern void *runtime·CreateWaitableTimer;
-extern void *runtime·CryptAcquireContextW;
-extern void *runtime·CryptGenRandom;
-extern void *runtime·CryptReleaseContext;
-extern void *runtime·DuplicateHandle;
-extern void *runtime·ExitProcess;
-extern void *runtime·FreeEnvironmentStringsW;
-extern void *runtime·GetEnvironmentStringsW;
-extern void *runtime·GetProcAddress;
-extern void *runtime·GetStdHandle;
-extern void *runtime·GetSystemInfo;
-extern void *runtime·GetSystemTimeAsFileTime;
-extern void *runtime·GetThreadContext;
-extern void *runtime·LoadLibrary;
-extern void *runtime·LoadLibraryA;
-extern void *runtime·NtWaitForSingleObject;
-extern void *runtime·ResumeThread;
-extern void *runtime·SetConsoleCtrlHandler;
-extern void *runtime·SetEvent;
-extern void *runtime·SetProcessPriorityBoost;
-extern void *runtime·SetThreadPriority;
-extern void *runtime·SetWaitableTimer;
-extern void *runtime·Sleep;
-extern void *runtime·SuspendThread;
-extern void *runtime·WaitForSingleObject;
-extern void *runtime·WriteFile;
-extern void *runtime·timeBeginPeriod;
-
-void *runtime·GetQueuedCompletionStatusEx;
-
-extern uintptr runtime·externalthreadhandlerp;
-void runtime·externalthreadhandler(void);
-void runtime·sigtramp(void);
-
-static int32
-getproccount(void)
-{
-	SystemInfo info;
-
-	runtime·stdcall(runtime·GetSystemInfo, 1, &info);
-	return info.dwNumberOfProcessors;
-}
-
-void
-runtime·osinit(void)
-{
-	void *kernel32;
-
-	runtime·externalthreadhandlerp = (uintptr)runtime·externalthreadhandler;
-
-	runtime·stdcall(runtime·AddVectoredExceptionHandler, 2, (uintptr)1, (uintptr)runtime·sigtramp);
-	runtime·stdcall(runtime·SetConsoleCtrlHandler, 2, runtime·ctrlhandler, (uintptr)1);
-	runtime·stdcall(runtime·timeBeginPeriod, 1, (uintptr)1);
-	runtime·ncpu = getproccount();
-	
-	// Windows dynamic priority boosting assumes that a process has different types
-	// of dedicated threads -- GUI, IO, computational, etc. Go processes use
-	// equivalent threads that all do a mix of GUI, IO, computations, etc.
-	// In such context dynamic priority boosting does nothing but harm, so we turn it off.
-	runtime·stdcall(runtime·SetProcessPriorityBoost, 2, (uintptr)-1, (uintptr)1);
-
-	kernel32 = runtime·stdcall(runtime·LoadLibraryA, 1, "kernel32.dll");
-	if(kernel32 != nil) {
-		runtime·GetQueuedCompletionStatusEx = runtime·stdcall(runtime·GetProcAddress, 2, kernel32, "GetQueuedCompletionStatusEx");
-	}
-}
-
-void
-runtime·get_random_data(byte **rnd, int32 *rnd_len)
-{
-	uintptr handle;
-	*rnd = nil;
-	*rnd_len = 0;
-	if(runtime·stdcall(runtime·CryptAcquireContextW, 5, &handle, nil, nil,
-			   (uintptr)1 /* PROV_RSA_FULL */,
-			   (uintptr)0xf0000000U /* CRYPT_VERIFYCONTEXT */) != 0) {
-		static byte random_data[HashRandomBytes];
-		if(runtime·stdcall(runtime·CryptGenRandom, 3, handle, (uintptr)HashRandomBytes, random_data)) {
-			*rnd = random_data;
-			*rnd_len = HashRandomBytes;
-		}
-		runtime·stdcall(runtime·CryptReleaseContext, 2, handle, (uintptr)0);
-	}
-}
-
-void
-runtime·goenvs(void)
-{
-	extern Slice syscall·envs;
-
-	uint16 *env;
-	String *s;
-	int32 i, n;
-	uint16 *p;
-
-	env = runtime·stdcall(runtime·GetEnvironmentStringsW, 0);
-
-	n = 0;
-	for(p=env; *p; n++)
-		p += runtime·findnullw(p)+1;
-
-	s = runtime·malloc(n*sizeof s[0]);
-
-	p = env;
-	for(i=0; i<n; i++) {
-		s[i] = runtime·gostringw(p);
-		p += runtime·findnullw(p)+1;
-	}
-	syscall·envs.array = (byte*)s;
-	syscall·envs.len = n;
-	syscall·envs.cap = n;
-
-	runtime·stdcall(runtime·FreeEnvironmentStringsW, 1, env);
-}
-
-void
-runtime·exit(int32 code)
-{
-	runtime·stdcall(runtime·ExitProcess, 1, (uintptr)code);
-}
-
-int32
-runtime·write(uintptr fd, void *buf, int32 n)
-{
-	void *handle;
-	uint32 written;
-
-	written = 0;
-	switch(fd) {
-	case 1:
-		handle = runtime·stdcall(runtime·GetStdHandle, 1, (uintptr)-11);
-		break;
-	case 2:
-		handle = runtime·stdcall(runtime·GetStdHandle, 1, (uintptr)-12);
-		break;
-	default:
-		// assume fd is real windows handle.
-		handle = (void*)fd;
-		break;
-	}
-	runtime·stdcall(runtime·WriteFile, 5, handle, buf, (uintptr)n, &written, (uintptr)0);
-	return written;
-}
-
-#define INFINITE ((uintptr)0xFFFFFFFF)
-
-#pragma textflag NOSPLIT
-int32
-runtime·semasleep(int64 ns)
-{
-	// store ms in ns to save stack space
-	if(ns < 0)
-		ns = INFINITE;
-	else {
-		ns = runtime·timediv(ns, 1000000, nil);
-		if(ns == 0)
-			ns = 1;
-	}
-	if(runtime·stdcall(runtime·WaitForSingleObject, 2, m->waitsema, (uintptr)ns) != 0)
-		return -1;  // timeout
-	return 0;
-}
-
-void
-runtime·semawakeup(M *mp)
-{
-	runtime·stdcall(runtime·SetEvent, 1, mp->waitsema);
-}
-
-uintptr
-runtime·semacreate(void)
-{
-	return (uintptr)runtime·stdcall(runtime·CreateEvent, 4, (uintptr)0, (uintptr)0, (uintptr)0, (uintptr)0);
-}
-
-#define STACK_SIZE_PARAM_IS_A_RESERVATION ((uintptr)0x00010000)
-
-void
-runtime·newosproc(M *mp, void *stk)
-{
-	void *thandle;
-
-	USED(stk);
-
-	thandle = runtime·stdcall(runtime·CreateThread, 6,
-		nil, (uintptr)0x20000, runtime·tstart_stdcall, mp,
-		STACK_SIZE_PARAM_IS_A_RESERVATION, nil);
-	if(thandle == nil) {
-		runtime·printf("runtime: failed to create new OS thread (have %d already; errno=%d)\n", runtime·mcount(), runtime·getlasterror());
-		runtime·throw("runtime.newosproc");
-	}
-}
-
-// Called to initialize a new m (including the bootstrap m).
-// Called on the parent thread (main thread in case of bootstrap), can allocate memory.
-void
-runtime·mpreinit(M *mp)
-{
-	USED(mp);
-}
-
-// Called to initialize a new m (including the bootstrap m).
-// Called on the new thread, can not allocate memory.
-void
-runtime·minit(void)
-{
-	void *thandle;
-
-	// -1 = current process, -2 = current thread
-	runtime·stdcall(runtime·DuplicateHandle, 7,
-		(uintptr)-1, (uintptr)-2, (uintptr)-1, &thandle,
-		(uintptr)0, (uintptr)0, (uintptr)DUPLICATE_SAME_ACCESS);
-	runtime·atomicstorep(&m->thread, thandle);
-}
-
-// Called from dropm to undo the effect of an minit.
-void
-runtime·unminit(void)
-{
-}
-
-#pragma textflag NOSPLIT
-int64
-runtime·nanotime(void)
-{
-	int64 filetime;
-
-	runtime·stdcall(runtime·GetSystemTimeAsFileTime, 1, &filetime);
-
-	// Filetime is 100s of nanoseconds since January 1, 1601.
-	// Convert to nanoseconds since January 1, 1970.
-	return (filetime - 116444736000000000LL) * 100LL;
-}
-
-void
-time·now(int64 sec, int32 usec)
-{
-	int64 ns;
-
-	ns = runtime·nanotime();
-	sec = ns / 1000000000LL;
-	usec = ns - sec * 1000000000LL;
-	FLUSH(&sec);
-	FLUSH(&usec);
-}
-
-// Calling stdcall on os stack.
-#pragma textflag NOSPLIT
-void *
-runtime·stdcall(void *fn, int32 count, ...)
-{
-	m->libcall.fn = fn;
-	m->libcall.n = count;
-	m->libcall.args = (uintptr*)&count + 1;
-	if(m->profilehz != 0) {
-		// leave pc/sp for cpu profiler
-		m->libcallg = g;
-		m->libcallpc = (uintptr)runtime·getcallerpc(&fn);
-		// sp must be the last, because once async cpu profiler finds
-		// all three values to be non-zero, it will use them
-		m->libcallsp = (uintptr)runtime·getcallersp(&fn);
-	}
-	runtime·asmcgocall(runtime·asmstdcall, &m->libcall);
-	m->libcallsp = 0;
-	return (void*)m->libcall.r1;
-}
-
-extern void runtime·usleep1(uint32);
-
-#pragma textflag NOSPLIT
-void
-runtime·osyield(void)
-{
-	runtime·usleep1(1);
-}
-
-#pragma textflag NOSPLIT
-void
-runtime·usleep(uint32 us)
-{
-	// Have 1us units; want 100ns units.
-	runtime·usleep1(10*us);
-}
-
-uint32
-runtime·issigpanic(uint32 code)
-{
-	switch(code) {
-	case EXCEPTION_ACCESS_VIOLATION:
-	case EXCEPTION_INT_DIVIDE_BY_ZERO:
-	case EXCEPTION_INT_OVERFLOW:
-	case EXCEPTION_FLT_DENORMAL_OPERAND:
-	case EXCEPTION_FLT_DIVIDE_BY_ZERO:
-	case EXCEPTION_FLT_INEXACT_RESULT:
-	case EXCEPTION_FLT_OVERFLOW:
-	case EXCEPTION_FLT_UNDERFLOW:
-		return 1;
-	}
-	return 0;
-}
-
-void
-runtime·sigpanic(void)
-{
-	if(!runtime·canpanic(g))
-		runtime·throw("unexpected signal during runtime execution");
-
-	switch(g->sig) {
-	case EXCEPTION_ACCESS_VIOLATION:
-		if(g->sigcode1 < 0x1000 || g->paniconfault) {
-			if(g->sigpc == 0)
-				runtime·panicstring("call of nil func value");
-			runtime·panicstring("invalid memory address or nil pointer dereference");
-		}
-		runtime·printf("unexpected fault address %p\n", g->sigcode1);
-		runtime·throw("fault");
-	case EXCEPTION_INT_DIVIDE_BY_ZERO:
-		runtime·panicstring("integer divide by zero");
-	case EXCEPTION_INT_OVERFLOW:
-		runtime·panicstring("integer overflow");
-	case EXCEPTION_FLT_DENORMAL_OPERAND:
-	case EXCEPTION_FLT_DIVIDE_BY_ZERO:
-	case EXCEPTION_FLT_INEXACT_RESULT:
-	case EXCEPTION_FLT_OVERFLOW:
-	case EXCEPTION_FLT_UNDERFLOW:
-		runtime·panicstring("floating point error");
-	}
-	runtime·throw("fault");
-}
-
-void
-runtime·initsig(void)
-{
-	// following line keeps sigtramp alive at link stage
-	// if there's a better way please write it here
-	void *p = runtime·sigtramp;
-	USED(p);
-}
-
-uint32
-runtime·ctrlhandler1(uint32 type)
-{
-	int32 s;
-
-	switch(type) {
-	case CTRL_C_EVENT:
-	case CTRL_BREAK_EVENT:
-		s = SIGINT;
-		break;
-	default:
-		return 0;
-	}
-
-	if(runtime·sigsend(s))
-		return 1;
-	runtime·exit(2);	// SIGINT, SIGTERM, etc
-	return 0;
-}
-
-extern void runtime·dosigprof(Context *r, G *gp, M *mp);
-extern void runtime·profileloop(void);
-static void *profiletimer;
-
-static void
-profilem(M *mp)
-{
-	extern M runtime·m0;
-	extern uint32 runtime·tls0[];
-	byte rbuf[sizeof(Context)+15];
-	Context *r;
-	void *tls;
-	G *gp;
-
-	tls = mp->tls;
-	if(mp == &runtime·m0)
-		tls = runtime·tls0;
-	gp = *(G**)tls;
-
-	// align Context to 16 bytes
-	r = (Context*)((uintptr)(&rbuf[15]) & ~15);
-	r->ContextFlags = CONTEXT_CONTROL;
-	runtime·stdcall(runtime·GetThreadContext, 2, mp->thread, r);
-	runtime·dosigprof(r, gp, mp);
-}
-
-void
-runtime·profileloop1(void)
-{
-	M *mp, *allm;
-	void *thread;
-
-	runtime·stdcall(runtime·SetThreadPriority, 2,
-		(uintptr)-2, (uintptr)THREAD_PRIORITY_HIGHEST);
-
-	for(;;) {
-		runtime·stdcall(runtime·WaitForSingleObject, 2, profiletimer, (uintptr)-1);
-		allm = runtime·atomicloadp(&runtime·allm);
-		for(mp = allm; mp != nil; mp = mp->alllink) {
-			thread = runtime·atomicloadp(&mp->thread);
-			// Do not profile threads blocked on Notes,
-			// this includes idle worker threads,
-			// idle timer thread, idle heap scavenger, etc.
-			if(thread == nil || mp->profilehz == 0 || mp->blocked)
-				continue;
-			runtime·stdcall(runtime·SuspendThread, 1, thread);
-			if(mp->profilehz != 0 && !mp->blocked)
-				profilem(mp);
-			runtime·stdcall(runtime·ResumeThread, 1, thread);
-		}
-	}
-}
-
-void
-runtime·resetcpuprofiler(int32 hz)
-{
-	static Lock lock;
-	void *timer, *thread;
-	int32 ms;
-	int64 due;
-
-	runtime·lock(&lock);
-	if(profiletimer == nil) {
-		timer = runtime·stdcall(runtime·CreateWaitableTimer, 3, nil, nil, nil);
-		runtime·atomicstorep(&profiletimer, timer);
-		thread = runtime·stdcall(runtime·CreateThread, 6,
-			nil, nil, runtime·profileloop, nil, nil, nil);
-		runtime·stdcall(runtime·CloseHandle, 1, thread);
-	}
-	runtime·unlock(&lock);
-
-	ms = 0;
-	due = 1LL<<63;
-	if(hz > 0) {
-		ms = 1000 / hz;
-		if(ms == 0)
-			ms = 1;
-		due = ms * -10000;
-	}
-	runtime·stdcall(runtime·SetWaitableTimer, 6,
-		profiletimer, &due, (uintptr)ms, nil, nil, nil);
-	runtime·atomicstore((uint32*)&m->profilehz, hz);
-}
-
-void
-os·sigpipe(void)
-{
-	runtime·throw("too many writes on closed pipe");
-}
-
-uintptr
-runtime·memlimit(void)
-{
-	return 0;
-}
-
-#pragma dataflag NOPTR
-int8 runtime·badsignalmsg[] = "runtime: signal received on thread not created by Go.\n";
-int32 runtime·badsignallen = sizeof runtime·badsignalmsg - 1;
-
-void
-runtime·crash(void)
-{
-	// TODO: This routine should do whatever is needed
-	// to make the Windows program abort/crash as it
-	// would if Go was not intercepting signals.
-	// On Unix the routine would remove the custom signal
-	// handler and then raise a signal (like SIGABRT).
-	// Something like that should happen here.
-	// It's okay to leave this empty for now: if crash returns
-	// the ordinary exit-after-panic happens.
-}
diff --git a/src/pkg/runtime/os_windows.h b/src/pkg/runtime/os_windows.h
deleted file mode 100644
index b64fa88..0000000
--- a/src/pkg/runtime/os_windows.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-extern void *runtime·LoadLibrary;
-extern void *runtime·GetProcAddress;
-extern void *runtime·GetQueuedCompletionStatusEx;
-
-// Call a Windows function with stdcall conventions,
-// and switch to os stack during the call.
-#pragma	varargck	countpos	runtime·stdcall	2
-#pragma	varargck	type		runtime·stdcall	void*
-#pragma	varargck	type		runtime·stdcall	uintptr
-void runtime·asmstdcall(void *c);
-void *runtime·stdcall(void *fn, int32 count, ...);
-
-uint32 runtime·getlasterror(void);
-void runtime·setlasterror(uint32 err);
-
-// Function to be called by windows CreateThread
-// to start new os thread.
-uint32 runtime·tstart_stdcall(M *newm);
-
-uint32 runtime·issigpanic(uint32);
-void runtime·sigpanic(void);
-uint32 runtime·ctrlhandler(uint32 type);
-
-// Windows dll function to go callback entry.
-byte *runtime·compilecallback(Eface fn, bool cleanstack);
-void *runtime·callbackasm(void);
-
-void runtime·install_exception_handler(void);
-void runtime·remove_exception_handler(void);
-
-// TODO(brainman): should not need those
-#define	NSIG	65
diff --git a/src/pkg/runtime/os_windows_386.c b/src/pkg/runtime/os_windows_386.c
deleted file mode 100644
index c36a001..0000000
--- a/src/pkg/runtime/os_windows_386.c
+++ /dev/null
@@ -1,138 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "runtime.h"
-#include "defs_GOOS_GOARCH.h"
-#include "os_GOOS.h"
-
-void
-runtime·dumpregs(Context *r)
-{
-	runtime·printf("eax     %x\n", r->Eax);
-	runtime·printf("ebx     %x\n", r->Ebx);
-	runtime·printf("ecx     %x\n", r->Ecx);
-	runtime·printf("edx     %x\n", r->Edx);
-	runtime·printf("edi     %x\n", r->Edi);
-	runtime·printf("esi     %x\n", r->Esi);
-	runtime·printf("ebp     %x\n", r->Ebp);
-	runtime·printf("esp     %x\n", r->Esp);
-	runtime·printf("eip     %x\n", r->Eip);
-	runtime·printf("eflags  %x\n", r->EFlags);
-	runtime·printf("cs      %x\n", r->SegCs);
-	runtime·printf("fs      %x\n", r->SegFs);
-	runtime·printf("gs      %x\n", r->SegGs);
-}
-
-#define DBG_PRINTEXCEPTION_C 0x40010006
-
-// Called by sigtramp from Windows VEH handler.
-// Return value signals whether the exception has been handled (-1)
-// or should be made available to other handlers in the chain (0).
-uint32
-runtime·sighandler(ExceptionRecord *info, Context *r, G *gp)
-{
-	bool crash;
-	uintptr *sp;
-	extern byte text[], etext[];
-
-	if(info->ExceptionCode == DBG_PRINTEXCEPTION_C) {
-		// This exception is intended to be caught by debuggers.
-		// There is a not-very-informational message like
-		// "Invalid parameter passed to C runtime function"
-		// sitting at info->ExceptionInformation[0] (a wchar_t*),
-		// with length info->ExceptionInformation[1].
-		// The default behavior is to ignore this exception,
-		// but somehow returning 0 here (meaning keep going)
-		// makes the program crash instead. Maybe Windows has no
-		// other handler registered? In any event, ignore it.
-		return -1;
-	}
-
-	// Only handle exception if executing instructions in Go binary
-	// (not Windows library code). 
-	if(r->Eip < (uint32)text || (uint32)etext < r->Eip)
-		return 0;
-
-	switch(info->ExceptionCode) {
-	case EXCEPTION_BREAKPOINT:
-		// It is unclear whether this is needed, unclear whether it
-		// would work, and unclear how to test it. Leave out for now.
-		// This only handles breakpoint instructions written in the
-		// assembly sources, not breakpoints set by a debugger, and
-		// there are very few of the former.
-		//
-		// r->Eip--;	// because 8l generates 2 bytes for INT3
-		// return 0;
-		break;
-	}
-
-	if(gp != nil && runtime·issigpanic(info->ExceptionCode)) {
-		// Make it look like a call to the signal func.
-		// Have to pass arguments out of band since
-		// augmenting the stack frame would break
-		// the unwinding code.
-		gp->sig = info->ExceptionCode;
-		gp->sigcode0 = info->ExceptionInformation[0];
-		gp->sigcode1 = info->ExceptionInformation[1];
-		gp->sigpc = r->Eip;
-
-		// Only push runtime·sigpanic if r->eip != 0.
-		// If r->eip == 0, probably panicked because of a
-		// call to a nil func.  Not pushing that onto sp will
-		// make the trace look like a call to runtime·sigpanic instead.
-		// (Otherwise the trace will end at runtime·sigpanic and we
-		// won't get to see who faulted.)
-		if(r->Eip != 0) {
-			sp = (uintptr*)r->Esp;
-			*--sp = r->Eip;
-			r->Esp = (uintptr)sp;
-		}
-		r->Eip = (uintptr)runtime·sigpanic;
-		return -1;
-	}
-
-	if(runtime·panicking)	// traceback already printed
-		runtime·exit(2);
-	runtime·panicking = 1;
-
-	runtime·printf("Exception %x %p %p %p\n", info->ExceptionCode,
-		info->ExceptionInformation[0], info->ExceptionInformation[1], r->Eip);
-
-	runtime·printf("PC=%x\n", r->Eip);
-	if(m->lockedg != nil && m->ncgo > 0 && gp == m->g0) {
-		runtime·printf("signal arrived during cgo execution\n");
-		gp = m->lockedg;
-	}
-	runtime·printf("\n");
-
-	if(runtime·gotraceback(&crash)){
-		runtime·traceback(r->Eip, r->Esp, 0, gp);
-		runtime·tracebackothers(gp);
-		runtime·dumpregs(r);
-	}
-	
-	if(crash)
-		runtime·crash();
-
-	runtime·exit(2);
-	return -1; // not reached
-}
-
-void
-runtime·sigenable(uint32 sig)
-{
-	USED(sig);
-}
-
-void
-runtime·sigdisable(uint32 sig)
-{
-	USED(sig);
-}
-
-void
-runtime·dosigprof(Context *r, G *gp, M *mp)
-{
-	runtime·sigprof((uint8*)r->Eip, (uint8*)r->Esp, nil, gp, mp);
-}
diff --git a/src/pkg/runtime/os_windows_amd64.c b/src/pkg/runtime/os_windows_amd64.c
deleted file mode 100644
index 7fb973c..0000000
--- a/src/pkg/runtime/os_windows_amd64.c
+++ /dev/null
@@ -1,144 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "runtime.h"
-#include "defs_GOOS_GOARCH.h"
-#include "os_GOOS.h"
-
-void
-runtime·dumpregs(Context *r)
-{
-	runtime·printf("rax     %X\n", r->Rax);
-	runtime·printf("rbx     %X\n", r->Rbx);
-	runtime·printf("rcx     %X\n", r->Rcx);
-	runtime·printf("rdx     %X\n", r->Rdx);
-	runtime·printf("rdi     %X\n", r->Rdi);
-	runtime·printf("rsi     %X\n", r->Rsi);
-	runtime·printf("rbp     %X\n", r->Rbp);
-	runtime·printf("rsp     %X\n", r->Rsp);
-	runtime·printf("r8      %X\n", r->R8 );
-	runtime·printf("r9      %X\n", r->R9 );
-	runtime·printf("r10     %X\n", r->R10);
-	runtime·printf("r11     %X\n", r->R11);
-	runtime·printf("r12     %X\n", r->R12);
-	runtime·printf("r13     %X\n", r->R13);
-	runtime·printf("r14     %X\n", r->R14);
-	runtime·printf("r15     %X\n", r->R15);
-	runtime·printf("rip     %X\n", r->Rip);
-	runtime·printf("rflags  %X\n", r->EFlags);
-	runtime·printf("cs      %X\n", (uint64)r->SegCs);
-	runtime·printf("fs      %X\n", (uint64)r->SegFs);
-	runtime·printf("gs      %X\n", (uint64)r->SegGs);
-}
-
-#define DBG_PRINTEXCEPTION_C 0x40010006
-
-// Called by sigtramp from Windows VEH handler.
-// Return value signals whether the exception has been handled (-1)
-// or should be made available to other handlers in the chain (0).
-uint32
-runtime·sighandler(ExceptionRecord *info, Context *r, G *gp)
-{
-	bool crash;
-	uintptr *sp;
-	extern byte text[], etext[];
-
-	if(info->ExceptionCode == DBG_PRINTEXCEPTION_C) {
-		// This exception is intended to be caught by debuggers.
-		// There is a not-very-informational message like
-		// "Invalid parameter passed to C runtime function"
-		// sitting at info->ExceptionInformation[0] (a wchar_t*),
-		// with length info->ExceptionInformation[1].
-		// The default behavior is to ignore this exception,
-		// but somehow returning 0 here (meaning keep going)
-		// makes the program crash instead. Maybe Windows has no
-		// other handler registered? In any event, ignore it.
-		return -1;
-	}
-
-	// Only handle exception if executing instructions in Go binary
-	// (not Windows library code). 
-	if(r->Rip < (uint64)text || (uint64)etext < r->Rip)
-		return 0;
-
-	switch(info->ExceptionCode) {
-	case EXCEPTION_BREAKPOINT:
-		// It is unclear whether this is needed, unclear whether it
-		// would work, and unclear how to test it. Leave out for now.
-		// This only handles breakpoint instructions written in the
-		// assembly sources, not breakpoints set by a debugger, and
-		// there are very few of the former.
-		break;
-	}
-
-	if(gp != nil && runtime·issigpanic(info->ExceptionCode)) {
-		// Make it look like a call to the signal func.
-		// Have to pass arguments out of band since
-		// augmenting the stack frame would break
-		// the unwinding code.
-		gp->sig = info->ExceptionCode;
-		gp->sigcode0 = info->ExceptionInformation[0];
-		gp->sigcode1 = info->ExceptionInformation[1];
-		gp->sigpc = r->Rip;
-
-		// Only push runtime·sigpanic if r->rip != 0.
-		// If r->rip == 0, probably panicked because of a
-		// call to a nil func.  Not pushing that onto sp will
-		// make the trace look like a call to runtime·sigpanic instead.
-		// (Otherwise the trace will end at runtime·sigpanic and we
-		// won't get to see who faulted.)
-		if(r->Rip != 0) {
-			sp = (uintptr*)r->Rsp;
-			*--sp = r->Rip;
-			r->Rsp = (uintptr)sp;
-		}
-		r->Rip = (uintptr)runtime·sigpanic;
-		return -1;
-	}
-
-	if(runtime·panicking)	// traceback already printed
-		runtime·exit(2);
-	runtime·panicking = 1;
-
-	runtime·printf("Exception %x %p %p %p\n", info->ExceptionCode,
-		info->ExceptionInformation[0], info->ExceptionInformation[1], r->Rip);
-
-
-	runtime·printf("PC=%X\n", r->Rip);
-	if(m->lockedg != nil && m->ncgo > 0 && gp == m->g0) {
-		runtime·printf("signal arrived during cgo execution\n");
-		gp = m->lockedg;
-	}
-	runtime·printf("\n");
-
-	if(runtime·gotraceback(&crash)){
-		runtime·traceback(r->Rip, r->Rsp, 0, gp);
-		runtime·tracebackothers(gp);
-		runtime·dumpregs(r);
-	}
-	
-	if(crash)
-		runtime·crash();
-
-	runtime·exit(2);
-	return -1; // not reached
-}
-
-void
-runtime·sigenable(uint32 sig)
-{
-	USED(sig);
-}
-
-void
-runtime·sigdisable(uint32 sig)
-{
-	USED(sig);
-}
-
-void
-runtime·dosigprof(Context *r, G *gp, M *mp)
-{
-	runtime·sigprof((uint8*)r->Rip, (uint8*)r->Rsp, nil, gp, mp);
-}
diff --git a/src/pkg/runtime/panic.c b/src/pkg/runtime/panic.c
deleted file mode 100644
index f577b37..0000000
--- a/src/pkg/runtime/panic.c
+++ /dev/null
@@ -1,566 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "runtime.h"
-#include "arch_GOARCH.h"
-#include "stack.h"
-#include "malloc.h"
-#include "../../cmd/ld/textflag.h"
-
-// Code related to defer, panic and recover.
-
-uint32 runtime·panicking;
-static Lock paniclk;
-
-// Each P holds pool for defers with arg sizes 8, 24, 40, 56 and 72 bytes.
-// Memory block is 40 (24 for 32 bits) bytes larger due to Defer header.
-// This maps exactly to malloc size classes.
-
-// defer size class for arg size sz
-#define DEFERCLASS(sz) (((sz)+7)>>4)
-// total size of memory block for defer with arg size sz
-#define TOTALSIZE(sz) (sizeof(Defer) - sizeof(((Defer*)nil)->args) + ROUND(sz, sizeof(uintptr)))
-
-// Allocate a Defer, usually using per-P pool.
-// Each defer must be released with freedefer.
-static Defer*
-newdefer(int32 siz)
-{
-	int32 total, sc;
-	Defer *d;
-	P *p;
-
-	d = nil;
-	sc = DEFERCLASS(siz);
-	if(sc < nelem(p->deferpool)) {
-		p = m->p;
-		d = p->deferpool[sc];
-		if(d)
-			p->deferpool[sc] = d->link;
-	}
-	if(d == nil) {
-		// deferpool is empty or just a big defer
-		total = TOTALSIZE(siz);
-		d = runtime·malloc(total);
-	}
-	d->siz = siz;
-	d->special = 0;
-	d->link = g->defer;
-	g->defer = d;
-	return d;
-}
-
-// Free the given defer.
-// The defer cannot be used after this call.
-static void
-freedefer(Defer *d)
-{
-	int32 sc;
-	P *p;
-
-	if(d->special)
-		return;
-	sc = DEFERCLASS(d->siz);
-	if(sc < nelem(p->deferpool)) {
-		p = m->p;
-		d->link = p->deferpool[sc];
-		p->deferpool[sc] = d;
-		// No need to wipe out pointers in argp/pc/fn/args,
-		// because we empty the pool before GC.
-	} else
-		runtime·free(d);
-}
-
-// Create a new deferred function fn with siz bytes of arguments.
-// The compiler turns a defer statement into a call to this.
-// Cannot split the stack because it assumes that the arguments
-// are available sequentially after &fn; they would not be
-// copied if a stack split occurred.  It's OK for this to call
-// functions that split the stack.
-#pragma textflag NOSPLIT
-uintptr
-runtime·deferproc(int32 siz, FuncVal *fn, ...)
-{
-	Defer *d;
-
-	d = newdefer(siz);
-	d->fn = fn;
-	d->pc = runtime·getcallerpc(&siz);
-	if(thechar == '5')
-		d->argp = (byte*)(&fn+2);  // skip caller's saved link register
-	else
-		d->argp = (byte*)(&fn+1);
-	runtime·memmove(d->args, d->argp, d->siz);
-
-	// deferproc returns 0 normally.
-	// a deferred func that stops a panic
-	// makes the deferproc return 1.
-	// the code the compiler generates always
-	// checks the return value and jumps to the
-	// end of the function if deferproc returns != 0.
-	return 0;
-}
-
-// Run a deferred function if there is one.
-// The compiler inserts a call to this at the end of any
-// function which calls defer.
-// If there is a deferred function, this will call runtime·jmpdefer,
-// which will jump to the deferred function such that it appears
-// to have been called by the caller of deferreturn at the point
-// just before deferreturn was called.  The effect is that deferreturn
-// is called again and again until there are no more deferred functions.
-// Cannot split the stack because we reuse the caller's frame to
-// call the deferred function.
-
-// The single argument isn't actually used - it just has its address
-// taken so it can be matched against pending defers.
-#pragma textflag NOSPLIT
-void
-runtime·deferreturn(uintptr arg0)
-{
-	Defer *d;
-	byte *argp;
-	FuncVal *fn;
-
-	d = g->defer;
-	if(d == nil)
-		return;
-	argp = (byte*)&arg0;
-	if(d->argp != argp)
-		return;
-
-	// Moving arguments around.
-	// Do not allow preemption here, because the garbage collector
-	// won't know the form of the arguments until the jmpdefer can
-	// flip the PC over to fn.
-	m->locks++;
-	runtime·memmove(argp, d->args, d->siz);
-	fn = d->fn;
-	g->defer = d->link;
-	freedefer(d);
-	m->locks--;
-	if(m->locks == 0 && g->preempt)
-		g->stackguard0 = StackPreempt;
-	runtime·jmpdefer(fn, argp);
-}
-
-// Ensure that defer arg sizes that map to the same defer size class
-// also map to the same malloc size class.
-void
-runtime·testdefersizes(void)
-{
-	P *p;
-	int32 i, siz, defersc, mallocsc;
-	int32 map[nelem(p->deferpool)];
-
-	for(i=0; i<nelem(p->deferpool); i++)
-		map[i] = -1;
-	for(i=0;; i++) {
-		defersc = DEFERCLASS(i);
-		if(defersc >= nelem(p->deferpool))
-			break;
-		siz = TOTALSIZE(i);
-		mallocsc = runtime·SizeToClass(siz);
-		siz = runtime·class_to_size[mallocsc];
-		// runtime·printf("defer class %d: arg size %d, block size %d(%d)\n", defersc, i, siz, mallocsc);
-		if(map[defersc] < 0) {
-			map[defersc] = mallocsc;
-			continue;
-		}
-		if(map[defersc] != mallocsc) {
-			runtime·printf("bad defer size class: i=%d siz=%d mallocsc=%d/%d\n",
-				i, siz, map[defersc], mallocsc);
-			runtime·throw("bad defer size class");
-		}
-	}
-}
-
-// Run all deferred functions for the current goroutine.
-static void
-rundefer(void)
-{
-	Defer *d;
-
-	while((d = g->defer) != nil) {
-		g->defer = d->link;
-		reflect·call(d->fn, (byte*)d->args, d->siz, d->siz);
-		freedefer(d);
-	}
-}
-
-// Print all currently active panics.  Used when crashing.
-static void
-printpanics(Panic *p)
-{
-	if(p->link) {
-		printpanics(p->link);
-		runtime·printf("\t");
-	}
-	runtime·printf("panic: ");
-	runtime·printany(p->arg);
-	if(p->recovered)
-		runtime·printf(" [recovered]");
-	runtime·printf("\n");
-}
-
-static void recovery(G*);
-static void abortpanic(Panic*);
-static FuncVal abortpanicV = { (void(*)(void))abortpanic };
-
-// The implementation of the predeclared function panic.
-void
-runtime·panic(Eface e)
-{
-	Defer *d, dabort;
-	Panic p;
-	void *pc, *argp;
-
-	runtime·memclr((byte*)&p, sizeof p);
-	p.arg = e;
-	p.link = g->panic;
-	p.stackbase = g->stackbase;
-	g->panic = &p;
-
-	dabort.fn = &abortpanicV;
-	dabort.siz = sizeof(&p);
-	dabort.args[0] = &p;
-	dabort.argp = NoArgs;
-	dabort.special = true;
-
-	for(;;) {
-		d = g->defer;
-		if(d == nil)
-			break;
-		// take defer off list in case of recursive panic
-		g->defer = d->link;
-		g->ispanic = true;	// rock for runtime·newstack, where runtime·newstackcall ends up
-		argp = d->argp;
-		pc = d->pc;
-
-		// The deferred function may cause another panic,
-		// so newstackcall may not return. Set up a defer
-		// to mark this panic aborted if that happens.
-		dabort.link = g->defer;
-		g->defer = &dabort;
-		p.defer = d;
-
-		runtime·newstackcall(d->fn, (byte*)d->args, d->siz);
-
-		// Newstackcall did not panic. Remove dabort.
-		if(g->defer != &dabort)
-			runtime·throw("bad defer entry in panic");
-		g->defer = dabort.link;
-
-		freedefer(d);
-		if(p.recovered) {
-			g->panic = p.link;
-			// Aborted panics are marked but remain on the g->panic list.
-			// Recovery will unwind the stack frames containing their Panic structs.
-			// Remove them from the list and free the associated defers.
-			while(g->panic && g->panic->aborted) {
-				freedefer(g->panic->defer);
-				g->panic = g->panic->link;
-			}
-			if(g->panic == nil)	// must be done with signal
-				g->sig = 0;
-			// Pass information about recovering frame to recovery.
-			g->sigcode0 = (uintptr)argp;
-			g->sigcode1 = (uintptr)pc;
-			runtime·mcall(recovery);
-			runtime·throw("recovery failed"); // mcall should not return
-		}
-	}
-
-	// ran out of deferred calls - old-school panic now
-	runtime·startpanic();
-	printpanics(g->panic);
-	runtime·dopanic(0);	// should not return
-	runtime·exit(1);	// not reached
-}
-
-static void
-abortpanic(Panic *p)
-{
-	p->aborted = true;
-}
-
-// Unwind the stack after a deferred function calls recover
-// after a panic.  Then arrange to continue running as though
-// the caller of the deferred function returned normally.
-static void
-recovery(G *gp)
-{
-	void *argp;
-	uintptr pc;
-	
-	// Info about defer passed in G struct.
-	argp = (void*)gp->sigcode0;
-	pc = (uintptr)gp->sigcode1;
-
-	// Unwind to the stack frame with d's arguments in it.
-	runtime·unwindstack(gp, argp);
-
-	// Make the deferproc for this d return again,
-	// this time returning 1.  The calling function will
-	// jump to the standard return epilogue.
-	// The -2*sizeof(uintptr) makes up for the
-	// two extra words that are on the stack at
-	// each call to deferproc.
-	// (The pc we're returning to does pop pop
-	// before it tests the return value.)
-	// On the arm there are 2 saved LRs mixed in too.
-	if(thechar == '5')
-		gp->sched.sp = (uintptr)argp - 4*sizeof(uintptr);
-	else
-		gp->sched.sp = (uintptr)argp - 2*sizeof(uintptr);
-	gp->sched.pc = pc;
-	gp->sched.lr = 0;
-	gp->sched.ret = 1;
-	runtime·gogo(&gp->sched);
-}
-
-// Free stack frames until we hit the last one
-// or until we find the one that contains the sp.
-void
-runtime·unwindstack(G *gp, byte *sp)
-{
-	Stktop *top;
-	byte *stk;
-
-	// Must be called from a different goroutine, usually m->g0.
-	if(g == gp)
-		runtime·throw("unwindstack on self");
-
-	while((top = (Stktop*)gp->stackbase) != 0 && top->stackbase != 0) {
-		stk = (byte*)gp->stackguard - StackGuard;
-		if(stk <= sp && sp < (byte*)gp->stackbase)
-			break;
-		gp->stackbase = top->stackbase;
-		gp->stackguard = top->stackguard;
-		gp->stackguard0 = gp->stackguard;
-		runtime·stackfree(gp, stk, top);
-	}
-
-	if(sp != nil && (sp < (byte*)gp->stackguard - StackGuard || (byte*)gp->stackbase < sp)) {
-		runtime·printf("recover: %p not in [%p, %p]\n", sp, gp->stackguard - StackGuard, gp->stackbase);
-		runtime·throw("bad unwindstack");
-	}
-}
-
-// The implementation of the predeclared function recover.
-// Cannot split the stack because it needs to reliably
-// find the stack segment of its caller.
-#pragma textflag NOSPLIT
-void
-runtime·recover(byte *argp, GoOutput retbase, ...)
-{
-	Panic *p;
-	Stktop *top;
-	Eface *ret;
-
-	// Must be an unrecovered panic in progress.
-	// Must be on a stack segment created for a deferred call during a panic.
-	// Must be at the top of that segment, meaning the deferred call itself
-	// and not something it called. The top frame in the segment will have
-	// argument pointer argp == top - top->argsize.
-	// The subtraction of g->panicwrap allows wrapper functions that
-	// do not count as official calls to adjust what we consider the top frame
-	// while they are active on the stack. The linker emits adjustments of
-	// g->panicwrap in the prologue and epilogue of functions marked as wrappers.
-	ret = (Eface*)&retbase;
-	top = (Stktop*)g->stackbase;
-	p = g->panic;
-	if(p != nil && !p->recovered && top->panic && argp == (byte*)top - top->argsize - g->panicwrap) {
-		p->recovered = 1;
-		*ret = p->arg;
-	} else {
-		ret->type = nil;
-		ret->data = nil;
-	}
-}
-
-void
-runtime·startpanic(void)
-{
-	if(runtime·mheap.cachealloc.size == 0) { // very early
-		runtime·printf("runtime: panic before malloc heap initialized\n");
-		m->mallocing = 1; // tell rest of panic not to try to malloc
-	} else if(m->mcache == nil) // can happen if called from signal handler or throw
-		m->mcache = runtime·allocmcache();
-	switch(m->dying) {
-	case 0:
-		m->dying = 1;
-		if(g != nil)
-			g->writebuf = nil;
-		runtime·xadd(&runtime·panicking, 1);
-		runtime·lock(&paniclk);
-		if(runtime·debug.schedtrace > 0 || runtime·debug.scheddetail > 0)
-			runtime·schedtrace(true);
-		runtime·freezetheworld();
-		return;
-	case 1:
-		// Something failed while panicing, probably the print of the
-		// argument to panic().  Just print a stack trace and exit.
-		m->dying = 2;
-		runtime·printf("panic during panic\n");
-		runtime·dopanic(0);
-		runtime·exit(3);
-	case 2:
-		// This is a genuine bug in the runtime, we couldn't even
-		// print the stack trace successfully.
-		m->dying = 3;
-		runtime·printf("stack trace unavailable\n");
-		runtime·exit(4);
-	default:
-		// Can't even print!  Just exit.
-		runtime·exit(5);
-	}
-}
-
-void
-runtime·dopanic(int32 unused)
-{
-	static bool didothers;
-	bool crash;
-	int32 t;
-
-	if(g->sig != 0)
-		runtime·printf("[signal %x code=%p addr=%p pc=%p]\n",
-			g->sig, g->sigcode0, g->sigcode1, g->sigpc);
-
-	if((t = runtime·gotraceback(&crash)) > 0){
-		if(g != m->g0) {
-			runtime·printf("\n");
-			runtime·goroutineheader(g);
-			runtime·traceback((uintptr)runtime·getcallerpc(&unused), (uintptr)runtime·getcallersp(&unused), 0, g);
-		} else if(t >= 2 || m->throwing > 0) {
-			runtime·printf("\nruntime stack:\n");
-			runtime·traceback((uintptr)runtime·getcallerpc(&unused), (uintptr)runtime·getcallersp(&unused), 0, g);
-		}
-		if(!didothers) {
-			didothers = true;
-			runtime·tracebackothers(g);
-		}
-	}
-	runtime·unlock(&paniclk);
-	if(runtime·xadd(&runtime·panicking, -1) != 0) {
-		// Some other m is panicking too.
-		// Let it print what it needs to print.
-		// Wait forever without chewing up cpu.
-		// It will exit when it's done.
-		static Lock deadlock;
-		runtime·lock(&deadlock);
-		runtime·lock(&deadlock);
-	}
-	
-	if(crash)
-		runtime·crash();
-
-	runtime·exit(2);
-}
-
-void
-runtime·panicindex(void)
-{
-	runtime·panicstring("index out of range");
-}
-
-void
-runtime·panicslice(void)
-{
-	runtime·panicstring("slice bounds out of range");
-}
-
-void
-runtime·throwreturn(void)
-{
-	// can only happen if compiler is broken
-	runtime·throw("no return at end of a typed function - compiler is broken");
-}
-
-void
-runtime·throwinit(void)
-{
-	// can only happen with linker skew
-	runtime·throw("recursive call during initialization - linker skew");
-}
-
-bool
-runtime·canpanic(G *gp)
-{
-	byte g;
-
-	USED(&g);  // don't use global g, it points to gsignal
-
-	// Is it okay for gp to panic instead of crashing the program?
-	// Yes, as long as it is running Go code, not runtime code,
-	// and not stuck in a system call.
-	if(gp == nil || gp != m->curg)
-		return false;
-	if(m->locks-m->softfloat != 0 || m->mallocing != 0 || m->throwing != 0 || m->gcing != 0 || m->dying != 0)
-		return false;
-	if(gp->status != Grunning || gp->syscallsp != 0)
-		return false;
-#ifdef GOOS_windows
-	if(m->libcallsp != 0)
-		return false;
-#endif
-	return true;
-}
-
-void
-runtime·throw(int8 *s)
-{
-	if(m->throwing == 0)
-		m->throwing = 1;
-	runtime·startpanic();
-	runtime·printf("fatal error: %s\n", s);
-	runtime·dopanic(0);
-	*(int32*)0 = 0;	// not reached
-	runtime·exit(1);	// even more not reached
-}
-
-void
-runtime·panicstring(int8 *s)
-{
-	Eface err;
-
-	// m->softfloat is set during software floating point,
-	// which might cause a fault during a memory load.
-	// It increments m->locks to avoid preemption.
-	// If we're panicking, the software floating point frames
-	// will be unwound, so decrement m->locks as they would.
-	if(m->softfloat) {
-		m->locks--;
-		m->softfloat = 0;
-	}
-
-	if(m->mallocing) {
-		runtime·printf("panic: %s\n", s);
-		runtime·throw("panic during malloc");
-	}
-	if(m->gcing) {
-		runtime·printf("panic: %s\n", s);
-		runtime·throw("panic during gc");
-	}
-	if(m->locks) {
-		runtime·printf("panic: %s\n", s);
-		runtime·throw("panic holding locks");
-	}
-	runtime·newErrorCString(s, &err);
-	runtime·panic(err);
-}
-
-void
-runtime·Goexit(void)
-{
-	rundefer();
-	runtime·goexit();
-}
-
-void
-runtime·panicdivide(void)
-{
-	runtime·panicstring("integer divide by zero");
-}
diff --git a/src/pkg/runtime/parfor.c b/src/pkg/runtime/parfor.c
deleted file mode 100644
index 4706e0a..0000000
--- a/src/pkg/runtime/parfor.c
+++ /dev/null
@@ -1,199 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Parallel for algorithm.
-
-#include "runtime.h"
-#include "arch_GOARCH.h"
-
-struct ParForThread
-{
-	// the thread's iteration space [32lsb, 32msb)
-	uint64 pos;
-	// stats
-	uint64 nsteal;
-	uint64 nstealcnt;
-	uint64 nprocyield;
-	uint64 nosyield;
-	uint64 nsleep;
-	byte pad[CacheLineSize];
-};
-
-ParFor*
-runtime·parforalloc(uint32 nthrmax)
-{
-	ParFor *desc;
-
-	// The ParFor object is followed by CacheLineSize padding
-	// and then nthrmax ParForThread.
-	desc = (ParFor*)runtime·malloc(sizeof(ParFor) + CacheLineSize + nthrmax * sizeof(ParForThread));
-	desc->thr = (ParForThread*)((byte*)(desc+1) + CacheLineSize);
-	desc->nthrmax = nthrmax;
-	return desc;
-}
-
-void
-runtime·parforsetup(ParFor *desc, uint32 nthr, uint32 n, void *ctx, bool wait, void (*body)(ParFor*, uint32))
-{
-	uint32 i, begin, end;
-	uint64 *pos;
-
-	if(desc == nil || nthr == 0 || nthr > desc->nthrmax || body == nil) {
-		runtime·printf("desc=%p nthr=%d count=%d body=%p\n", desc, nthr, n, body);
-		runtime·throw("parfor: invalid args");
-	}
-
-	desc->body = body;
-	desc->done = 0;
-	desc->nthr = nthr;
-	desc->thrseq = 0;
-	desc->cnt = n;
-	desc->ctx = ctx;
-	desc->wait = wait;
-	desc->nsteal = 0;
-	desc->nstealcnt = 0;
-	desc->nprocyield = 0;
-	desc->nosyield = 0;
-	desc->nsleep = 0;
-	for(i=0; i<nthr; i++) {
-		begin = (uint64)n*i / nthr;
-		end = (uint64)n*(i+1) / nthr;
-		pos = &desc->thr[i].pos;
-		if(((uintptr)pos & 7) != 0)
-			runtime·throw("parforsetup: pos is not aligned");
-		*pos = (uint64)begin | (((uint64)end)<<32);
-	}
-}
-
-void
-runtime·parfordo(ParFor *desc)
-{
-	ParForThread *me;
-	uint32 tid, begin, end, begin2, try, victim, i;
-	uint64 *mypos, *victimpos, pos, newpos;
-	void (*body)(ParFor*, uint32);
-	bool idle;
-
-	// Obtain 0-based thread index.
-	tid = runtime·xadd(&desc->thrseq, 1) - 1;
-	if(tid >= desc->nthr) {
-		runtime·printf("tid=%d nthr=%d\n", tid, desc->nthr);
-		runtime·throw("parfor: invalid tid");
-	}
-
-	// If single-threaded, just execute the for serially.
-	if(desc->nthr==1) {
-		for(i=0; i<desc->cnt; i++)
-			desc->body(desc, i);
-		return;
-	}
-
-	body = desc->body;
-	me = &desc->thr[tid];
-	mypos = &me->pos;
-	for(;;) {
-		for(;;) {
-			// While there is local work,
-			// bump low index and execute the iteration.
-			pos = runtime·xadd64(mypos, 1);
-			begin = (uint32)pos-1;
-			end = (uint32)(pos>>32);
-			if(begin < end) {
-				body(desc, begin);
-				continue;
-			}
-			break;
-		}
-
-		// Out of work, need to steal something.
-		idle = false;
-		for(try=0;; try++) {
-			// If we don't see any work for long enough,
-			// increment the done counter...
-			if(try > desc->nthr*4 && !idle) {
-				idle = true;
-				runtime·xadd(&desc->done, 1);
-			}
-			// ...if all threads have incremented the counter,
-			// we are done.
-			if(desc->done + !idle == desc->nthr) {
-				if(!idle)
-					runtime·xadd(&desc->done, 1);
-				goto exit;
-			}
-			// Choose a random victim for stealing.
-			victim = runtime·fastrand1() % (desc->nthr-1);
-			if(victim >= tid)
-				victim++;
-			victimpos = &desc->thr[victim].pos;
-			for(;;) {
-				// See if it has any work.
-				pos = runtime·atomicload64(victimpos);
-				begin = (uint32)pos;
-				end = (uint32)(pos>>32);
-				if(begin+1 >= end) {
-					begin = end = 0;
-					break;
-				}
-				if(idle) {
-					runtime·xadd(&desc->done, -1);
-					idle = false;
-				}
-				begin2 = begin + (end-begin)/2;
-				newpos = (uint64)begin | (uint64)begin2<<32;
-				if(runtime·cas64(victimpos, pos, newpos)) {
-					begin = begin2;
-					break;
-				}
-			}
-			if(begin < end) {
-				// Has successfully stolen some work.
-				if(idle)
-					runtime·throw("parfor: should not be idle");
-				runtime·atomicstore64(mypos, (uint64)begin | (uint64)end<<32);
-				me->nsteal++;
-				me->nstealcnt += end-begin;
-				break;
-			}
-			// Backoff.
-			if(try < desc->nthr) {
-				// nothing
-			} else if (try < 4*desc->nthr) {
-				me->nprocyield++;
-				runtime·procyield(20);
-			// If a caller asked not to wait for the others, exit now
-			// (assume that most work is already done at this point).
-			} else if (!desc->wait) {
-				if(!idle)
-					runtime·xadd(&desc->done, 1);
-				goto exit;
-			} else if (try < 6*desc->nthr) {
-				me->nosyield++;
-				runtime·osyield();
-			} else {
-				me->nsleep++;
-				runtime·usleep(1);
-			}
-		}
-	}
-exit:
-	runtime·xadd64(&desc->nsteal, me->nsteal);
-	runtime·xadd64(&desc->nstealcnt, me->nstealcnt);
-	runtime·xadd64(&desc->nprocyield, me->nprocyield);
-	runtime·xadd64(&desc->nosyield, me->nosyield);
-	runtime·xadd64(&desc->nsleep, me->nsleep);
-	me->nsteal = 0;
-	me->nstealcnt = 0;
-	me->nprocyield = 0;
-	me->nosyield = 0;
-	me->nsleep = 0;
-}
-
-// For testing from Go.
-void
-runtime·parforiters(ParFor *desc, uintptr tid, uintptr *start, uintptr *end)
-{
-	*start = (uint32)desc->thr[tid].pos;
-	*end = (uint32)(desc->thr[tid].pos>>32);
-}
diff --git a/src/pkg/runtime/pprof/pprof.go b/src/pkg/runtime/pprof/pprof.go
deleted file mode 100644
index 26aa0b8..0000000
--- a/src/pkg/runtime/pprof/pprof.go
+++ /dev/null
@@ -1,679 +0,0 @@
-// Copyright 2010 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package pprof writes runtime profiling data in the format expected
-// by the pprof visualization tool.
-// For more information about pprof, see
-// http://code.google.com/p/google-perftools/.
-package pprof
-
-import (
-	"bufio"
-	"bytes"
-	"fmt"
-	"io"
-	"runtime"
-	"sort"
-	"strings"
-	"sync"
-	"text/tabwriter"
-)
-
-// BUG(rsc): Profiles are incomplete and inaccurate on NetBSD and OS X.
-// See http://golang.org/issue/6047 for details.
-
-// A Profile is a collection of stack traces showing the call sequences
-// that led to instances of a particular event, such as allocation.
-// Packages can create and maintain their own profiles; the most common
-// use is for tracking resources that must be explicitly closed, such as files
-// or network connections.
-//
-// A Profile's methods can be called from multiple goroutines simultaneously.
-//
-// Each Profile has a unique name.  A few profiles are predefined:
-//
-//	goroutine    - stack traces of all current goroutines
-//	heap         - a sampling of all heap allocations
-//	threadcreate - stack traces that led to the creation of new OS threads
-//	block        - stack traces that led to blocking on synchronization primitives
-//
-// These predefined profiles maintain themselves and panic on an explicit
-// Add or Remove method call.
-//
-// The CPU profile is not available as a Profile.  It has a special API,
-// the StartCPUProfile and StopCPUProfile functions, because it streams
-// output to a writer during profiling.
-//
-type Profile struct {
-	name  string
-	mu    sync.Mutex
-	m     map[interface{}][]uintptr
-	count func() int
-	write func(io.Writer, int) error
-}
-
-// profiles records all registered profiles.
-var profiles struct {
-	mu sync.Mutex
-	m  map[string]*Profile
-}
-
-var goroutineProfile = &Profile{
-	name:  "goroutine",
-	count: countGoroutine,
-	write: writeGoroutine,
-}
-
-var threadcreateProfile = &Profile{
-	name:  "threadcreate",
-	count: countThreadCreate,
-	write: writeThreadCreate,
-}
-
-var heapProfile = &Profile{
-	name:  "heap",
-	count: countHeap,
-	write: writeHeap,
-}
-
-var blockProfile = &Profile{
-	name:  "block",
-	count: countBlock,
-	write: writeBlock,
-}
-
-func lockProfiles() {
-	profiles.mu.Lock()
-	if profiles.m == nil {
-		// Initial built-in profiles.
-		profiles.m = map[string]*Profile{
-			"goroutine":    goroutineProfile,
-			"threadcreate": threadcreateProfile,
-			"heap":         heapProfile,
-			"block":        blockProfile,
-		}
-	}
-}
-
-func unlockProfiles() {
-	profiles.mu.Unlock()
-}
-
-// NewProfile creates a new profile with the given name.
-// If a profile with that name already exists, NewProfile panics.
-// The convention is to use a 'import/path.' prefix to create
-// separate name spaces for each package.
-func NewProfile(name string) *Profile {
-	lockProfiles()
-	defer unlockProfiles()
-	if name == "" {
-		panic("pprof: NewProfile with empty name")
-	}
-	if profiles.m[name] != nil {
-		panic("pprof: NewProfile name already in use: " + name)
-	}
-	p := &Profile{
-		name: name,
-		m:    map[interface{}][]uintptr{},
-	}
-	profiles.m[name] = p
-	return p
-}
-
-// Lookup returns the profile with the given name, or nil if no such profile exists.
-func Lookup(name string) *Profile {
-	lockProfiles()
-	defer unlockProfiles()
-	return profiles.m[name]
-}
-
-// Profiles returns a slice of all the known profiles, sorted by name.
-func Profiles() []*Profile {
-	lockProfiles()
-	defer unlockProfiles()
-
-	var all []*Profile
-	for _, p := range profiles.m {
-		all = append(all, p)
-	}
-
-	sort.Sort(byName(all))
-	return all
-}
-
-type byName []*Profile
-
-func (x byName) Len() int           { return len(x) }
-func (x byName) Swap(i, j int)      { x[i], x[j] = x[j], x[i] }
-func (x byName) Less(i, j int) bool { return x[i].name < x[j].name }
-
-// Name returns this profile's name, which can be passed to Lookup to reobtain the profile.
-func (p *Profile) Name() string {
-	return p.name
-}
-
-// Count returns the number of execution stacks currently in the profile.
-func (p *Profile) Count() int {
-	p.mu.Lock()
-	defer p.mu.Unlock()
-	if p.count != nil {
-		return p.count()
-	}
-	return len(p.m)
-}
-
-// Add adds the current execution stack to the profile, associated with value.
-// Add stores value in an internal map, so value must be suitable for use as
-// a map key and will not be garbage collected until the corresponding
-// call to Remove.  Add panics if the profile already contains a stack for value.
-//
-// The skip parameter has the same meaning as runtime.Caller's skip
-// and controls where the stack trace begins.  Passing skip=0 begins the
-// trace in the function calling Add.  For example, given this
-// execution stack:
-//
-//	Add
-//	called from rpc.NewClient
-//	called from mypkg.Run
-//	called from main.main
-//
-// Passing skip=0 begins the stack trace at the call to Add inside rpc.NewClient.
-// Passing skip=1 begins the stack trace at the call to NewClient inside mypkg.Run.
-//
-func (p *Profile) Add(value interface{}, skip int) {
-	if p.name == "" {
-		panic("pprof: use of uninitialized Profile")
-	}
-	if p.write != nil {
-		panic("pprof: Add called on built-in Profile " + p.name)
-	}
-
-	stk := make([]uintptr, 32)
-	n := runtime.Callers(skip+1, stk[:])
-
-	p.mu.Lock()
-	defer p.mu.Unlock()
-	if p.m[value] != nil {
-		panic("pprof: Profile.Add of duplicate value")
-	}
-	p.m[value] = stk[:n]
-}
-
-// Remove removes the execution stack associated with value from the profile.
-// It is a no-op if the value is not in the profile.
-func (p *Profile) Remove(value interface{}) {
-	p.mu.Lock()
-	defer p.mu.Unlock()
-	delete(p.m, value)
-}
-
-// WriteTo writes a pprof-formatted snapshot of the profile to w.
-// If a write to w returns an error, WriteTo returns that error.
-// Otherwise, WriteTo returns nil.
-//
-// The debug parameter enables additional output.
-// Passing debug=0 prints only the hexadecimal addresses that pprof needs.
-// Passing debug=1 adds comments translating addresses to function names
-// and line numbers, so that a programmer can read the profile without tools.
-//
-// The predefined profiles may assign meaning to other debug values;
-// for example, when printing the "goroutine" profile, debug=2 means to
-// print the goroutine stacks in the same form that a Go program uses
-// when dying due to an unrecovered panic.
-func (p *Profile) WriteTo(w io.Writer, debug int) error {
-	if p.name == "" {
-		panic("pprof: use of zero Profile")
-	}
-	if p.write != nil {
-		return p.write(w, debug)
-	}
-
-	// Obtain consistent snapshot under lock; then process without lock.
-	var all [][]uintptr
-	p.mu.Lock()
-	for _, stk := range p.m {
-		all = append(all, stk)
-	}
-	p.mu.Unlock()
-
-	// Map order is non-deterministic; make output deterministic.
-	sort.Sort(stackProfile(all))
-
-	return printCountProfile(w, debug, p.name, stackProfile(all))
-}
-
-type stackProfile [][]uintptr
-
-func (x stackProfile) Len() int              { return len(x) }
-func (x stackProfile) Stack(i int) []uintptr { return x[i] }
-func (x stackProfile) Swap(i, j int)         { x[i], x[j] = x[j], x[i] }
-func (x stackProfile) Less(i, j int) bool {
-	t, u := x[i], x[j]
-	for k := 0; k < len(t) && k < len(u); k++ {
-		if t[k] != u[k] {
-			return t[k] < u[k]
-		}
-	}
-	return len(t) < len(u)
-}
-
-// A countProfile is a set of stack traces to be printed as counts
-// grouped by stack trace.  There are multiple implementations:
-// all that matters is that we can find out how many traces there are
-// and obtain each trace in turn.
-type countProfile interface {
-	Len() int
-	Stack(i int) []uintptr
-}
-
-// printCountProfile prints a countProfile at the specified debug level.
-func printCountProfile(w io.Writer, debug int, name string, p countProfile) error {
-	b := bufio.NewWriter(w)
-	var tw *tabwriter.Writer
-	w = b
-	if debug > 0 {
-		tw = tabwriter.NewWriter(w, 1, 8, 1, '\t', 0)
-		w = tw
-	}
-
-	fmt.Fprintf(w, "%s profile: total %d\n", name, p.Len())
-
-	// Build count of each stack.
-	var buf bytes.Buffer
-	key := func(stk []uintptr) string {
-		buf.Reset()
-		fmt.Fprintf(&buf, "@")
-		for _, pc := range stk {
-			fmt.Fprintf(&buf, " %#x", pc)
-		}
-		return buf.String()
-	}
-	m := map[string]int{}
-	n := p.Len()
-	for i := 0; i < n; i++ {
-		m[key(p.Stack(i))]++
-	}
-
-	// Print stacks, listing count on first occurrence of a unique stack.
-	for i := 0; i < n; i++ {
-		stk := p.Stack(i)
-		s := key(stk)
-		if count := m[s]; count != 0 {
-			fmt.Fprintf(w, "%d %s\n", count, s)
-			if debug > 0 {
-				printStackRecord(w, stk, false)
-			}
-			delete(m, s)
-		}
-	}
-
-	if tw != nil {
-		tw.Flush()
-	}
-	return b.Flush()
-}
-
-// printStackRecord prints the function + source line information
-// for a single stack trace.
-func printStackRecord(w io.Writer, stk []uintptr, allFrames bool) {
-	show := allFrames
-	wasPanic := false
-	for i, pc := range stk {
-		f := runtime.FuncForPC(pc)
-		if f == nil {
-			show = true
-			fmt.Fprintf(w, "#\t%#x\n", pc)
-			wasPanic = false
-		} else {
-			tracepc := pc
-			// Back up to call instruction.
-			if i > 0 && pc > f.Entry() && !wasPanic {
-				if runtime.GOARCH == "386" || runtime.GOARCH == "amd64" {
-					tracepc--
-				} else {
-					tracepc -= 4 // arm, etc
-				}
-			}
-			file, line := f.FileLine(tracepc)
-			name := f.Name()
-			// Hide runtime.goexit and any runtime functions at the beginning.
-			// This is useful mainly for allocation traces.
-			wasPanic = name == "runtime.panic"
-			if name == "runtime.goexit" || !show && strings.HasPrefix(name, "runtime.") {
-				continue
-			}
-			show = true
-			fmt.Fprintf(w, "#\t%#x\t%s+%#x\t%s:%d\n", pc, name, pc-f.Entry(), file, line)
-		}
-	}
-	if !show {
-		// We didn't print anything; do it again,
-		// and this time include runtime functions.
-		printStackRecord(w, stk, true)
-		return
-	}
-	fmt.Fprintf(w, "\n")
-}
-
-// Interface to system profiles.
-
-type byInUseBytes []runtime.MemProfileRecord
-
-func (x byInUseBytes) Len() int           { return len(x) }
-func (x byInUseBytes) Swap(i, j int)      { x[i], x[j] = x[j], x[i] }
-func (x byInUseBytes) Less(i, j int) bool { return x[i].InUseBytes() > x[j].InUseBytes() }
-
-// WriteHeapProfile is shorthand for Lookup("heap").WriteTo(w, 0).
-// It is preserved for backwards compatibility.
-func WriteHeapProfile(w io.Writer) error {
-	return writeHeap(w, 0)
-}
-
-// countHeap returns the number of records in the heap profile.
-func countHeap() int {
-	n, _ := runtime.MemProfile(nil, true)
-	return n
-}
-
-// writeHeap writes the current runtime heap profile to w.
-func writeHeap(w io.Writer, debug int) error {
-	// Find out how many records there are (MemProfile(nil, true)),
-	// allocate that many records, and get the data.
-	// There's a race—more records might be added between
-	// the two calls—so allocate a few extra records for safety
-	// and also try again if we're very unlucky.
-	// The loop should only execute one iteration in the common case.
-	var p []runtime.MemProfileRecord
-	n, ok := runtime.MemProfile(nil, true)
-	for {
-		// Allocate room for a slightly bigger profile,
-		// in case a few more entries have been added
-		// since the call to MemProfile.
-		p = make([]runtime.MemProfileRecord, n+50)
-		n, ok = runtime.MemProfile(p, true)
-		if ok {
-			p = p[0:n]
-			break
-		}
-		// Profile grew; try again.
-	}
-
-	sort.Sort(byInUseBytes(p))
-
-	b := bufio.NewWriter(w)
-	var tw *tabwriter.Writer
-	w = b
-	if debug > 0 {
-		tw = tabwriter.NewWriter(w, 1, 8, 1, '\t', 0)
-		w = tw
-	}
-
-	var total runtime.MemProfileRecord
-	for i := range p {
-		r := &p[i]
-		total.AllocBytes += r.AllocBytes
-		total.AllocObjects += r.AllocObjects
-		total.FreeBytes += r.FreeBytes
-		total.FreeObjects += r.FreeObjects
-	}
-
-	// Technically the rate is MemProfileRate not 2*MemProfileRate,
-	// but early versions of the C++ heap profiler reported 2*MemProfileRate,
-	// so that's what pprof has come to expect.
-	fmt.Fprintf(w, "heap profile: %d: %d [%d: %d] @ heap/%d\n",
-		total.InUseObjects(), total.InUseBytes(),
-		total.AllocObjects, total.AllocBytes,
-		2*runtime.MemProfileRate)
-
-	for i := range p {
-		r := &p[i]
-		fmt.Fprintf(w, "%d: %d [%d: %d] @",
-			r.InUseObjects(), r.InUseBytes(),
-			r.AllocObjects, r.AllocBytes)
-		for _, pc := range r.Stack() {
-			fmt.Fprintf(w, " %#x", pc)
-		}
-		fmt.Fprintf(w, "\n")
-		if debug > 0 {
-			printStackRecord(w, r.Stack(), false)
-		}
-	}
-
-	// Print memstats information too.
-	// Pprof will ignore, but useful for people
-	if debug > 0 {
-		s := new(runtime.MemStats)
-		runtime.ReadMemStats(s)
-		fmt.Fprintf(w, "\n# runtime.MemStats\n")
-		fmt.Fprintf(w, "# Alloc = %d\n", s.Alloc)
-		fmt.Fprintf(w, "# TotalAlloc = %d\n", s.TotalAlloc)
-		fmt.Fprintf(w, "# Sys = %d\n", s.Sys)
-		fmt.Fprintf(w, "# Lookups = %d\n", s.Lookups)
-		fmt.Fprintf(w, "# Mallocs = %d\n", s.Mallocs)
-		fmt.Fprintf(w, "# Frees = %d\n", s.Frees)
-
-		fmt.Fprintf(w, "# HeapAlloc = %d\n", s.HeapAlloc)
-		fmt.Fprintf(w, "# HeapSys = %d\n", s.HeapSys)
-		fmt.Fprintf(w, "# HeapIdle = %d\n", s.HeapIdle)
-		fmt.Fprintf(w, "# HeapInuse = %d\n", s.HeapInuse)
-		fmt.Fprintf(w, "# HeapReleased = %d\n", s.HeapReleased)
-		fmt.Fprintf(w, "# HeapObjects = %d\n", s.HeapObjects)
-
-		fmt.Fprintf(w, "# Stack = %d / %d\n", s.StackInuse, s.StackSys)
-		fmt.Fprintf(w, "# MSpan = %d / %d\n", s.MSpanInuse, s.MSpanSys)
-		fmt.Fprintf(w, "# MCache = %d / %d\n", s.MCacheInuse, s.MCacheSys)
-		fmt.Fprintf(w, "# BuckHashSys = %d\n", s.BuckHashSys)
-
-		fmt.Fprintf(w, "# NextGC = %d\n", s.NextGC)
-		fmt.Fprintf(w, "# PauseNs = %d\n", s.PauseNs)
-		fmt.Fprintf(w, "# NumGC = %d\n", s.NumGC)
-		fmt.Fprintf(w, "# EnableGC = %v\n", s.EnableGC)
-		fmt.Fprintf(w, "# DebugGC = %v\n", s.DebugGC)
-	}
-
-	if tw != nil {
-		tw.Flush()
-	}
-	return b.Flush()
-}
-
-// countThreadCreate returns the size of the current ThreadCreateProfile.
-func countThreadCreate() int {
-	n, _ := runtime.ThreadCreateProfile(nil)
-	return n
-}
-
-// writeThreadCreate writes the current runtime ThreadCreateProfile to w.
-func writeThreadCreate(w io.Writer, debug int) error {
-	return writeRuntimeProfile(w, debug, "threadcreate", runtime.ThreadCreateProfile)
-}
-
-// countGoroutine returns the number of goroutines.
-func countGoroutine() int {
-	return runtime.NumGoroutine()
-}
-
-// writeGoroutine writes the current runtime GoroutineProfile to w.
-func writeGoroutine(w io.Writer, debug int) error {
-	if debug >= 2 {
-		return writeGoroutineStacks(w)
-	}
-	return writeRuntimeProfile(w, debug, "goroutine", runtime.GoroutineProfile)
-}
-
-func writeGoroutineStacks(w io.Writer) error {
-	// We don't know how big the buffer needs to be to collect
-	// all the goroutines.  Start with 1 MB and try a few times, doubling each time.
-	// Give up and use a truncated trace if 64 MB is not enough.
-	buf := make([]byte, 1<<20)
-	for i := 0; ; i++ {
-		n := runtime.Stack(buf, true)
-		if n < len(buf) {
-			buf = buf[:n]
-			break
-		}
-		if len(buf) >= 64<<20 {
-			// Filled 64 MB - stop there.
-			break
-		}
-		buf = make([]byte, 2*len(buf))
-	}
-	_, err := w.Write(buf)
-	return err
-}
-
-func writeRuntimeProfile(w io.Writer, debug int, name string, fetch func([]runtime.StackRecord) (int, bool)) error {
-	// Find out how many records there are (fetch(nil)),
-	// allocate that many records, and get the data.
-	// There's a race—more records might be added between
-	// the two calls—so allocate a few extra records for safety
-	// and also try again if we're very unlucky.
-	// The loop should only execute one iteration in the common case.
-	var p []runtime.StackRecord
-	n, ok := fetch(nil)
-	for {
-		// Allocate room for a slightly bigger profile,
-		// in case a few more entries have been added
-		// since the call to ThreadProfile.
-		p = make([]runtime.StackRecord, n+10)
-		n, ok = fetch(p)
-		if ok {
-			p = p[0:n]
-			break
-		}
-		// Profile grew; try again.
-	}
-
-	return printCountProfile(w, debug, name, runtimeProfile(p))
-}
-
-type runtimeProfile []runtime.StackRecord
-
-func (p runtimeProfile) Len() int              { return len(p) }
-func (p runtimeProfile) Stack(i int) []uintptr { return p[i].Stack() }
-
-var cpu struct {
-	sync.Mutex
-	profiling bool
-	done      chan bool
-}
-
-// StartCPUProfile enables CPU profiling for the current process.
-// While profiling, the profile will be buffered and written to w.
-// StartCPUProfile returns an error if profiling is already enabled.
-func StartCPUProfile(w io.Writer) error {
-	// The runtime routines allow a variable profiling rate,
-	// but in practice operating systems cannot trigger signals
-	// at more than about 500 Hz, and our processing of the
-	// signal is not cheap (mostly getting the stack trace).
-	// 100 Hz is a reasonable choice: it is frequent enough to
-	// produce useful data, rare enough not to bog down the
-	// system, and a nice round number to make it easy to
-	// convert sample counts to seconds.  Instead of requiring
-	// each client to specify the frequency, we hard code it.
-	const hz = 100
-
-	// Avoid queueing behind StopCPUProfile.
-	// Could use TryLock instead if we had it.
-	if cpu.profiling {
-		return fmt.Errorf("cpu profiling already in use")
-	}
-
-	cpu.Lock()
-	defer cpu.Unlock()
-	if cpu.done == nil {
-		cpu.done = make(chan bool)
-	}
-	// Double-check.
-	if cpu.profiling {
-		return fmt.Errorf("cpu profiling already in use")
-	}
-	cpu.profiling = true
-	runtime.SetCPUProfileRate(hz)
-	go profileWriter(w)
-	return nil
-}
-
-func profileWriter(w io.Writer) {
-	for {
-		data := runtime.CPUProfile()
-		if data == nil {
-			break
-		}
-		w.Write(data)
-	}
-	cpu.done <- true
-}
-
-// StopCPUProfile stops the current CPU profile, if any.
-// StopCPUProfile only returns after all the writes for the
-// profile have completed.
-func StopCPUProfile() {
-	cpu.Lock()
-	defer cpu.Unlock()
-
-	if !cpu.profiling {
-		return
-	}
-	cpu.profiling = false
-	runtime.SetCPUProfileRate(0)
-	<-cpu.done
-}
-
-type byCycles []runtime.BlockProfileRecord
-
-func (x byCycles) Len() int           { return len(x) }
-func (x byCycles) Swap(i, j int)      { x[i], x[j] = x[j], x[i] }
-func (x byCycles) Less(i, j int) bool { return x[i].Cycles > x[j].Cycles }
-
-// countBlock returns the number of records in the blocking profile.
-func countBlock() int {
-	n, _ := runtime.BlockProfile(nil)
-	return n
-}
-
-// writeBlock writes the current blocking profile to w.
-func writeBlock(w io.Writer, debug int) error {
-	var p []runtime.BlockProfileRecord
-	n, ok := runtime.BlockProfile(nil)
-	for {
-		p = make([]runtime.BlockProfileRecord, n+50)
-		n, ok = runtime.BlockProfile(p)
-		if ok {
-			p = p[:n]
-			break
-		}
-	}
-
-	sort.Sort(byCycles(p))
-
-	b := bufio.NewWriter(w)
-	var tw *tabwriter.Writer
-	w = b
-	if debug > 0 {
-		tw = tabwriter.NewWriter(w, 1, 8, 1, '\t', 0)
-		w = tw
-	}
-
-	fmt.Fprintf(w, "--- contention:\n")
-	fmt.Fprintf(w, "cycles/second=%v\n", runtime_cyclesPerSecond())
-	for i := range p {
-		r := &p[i]
-		fmt.Fprintf(w, "%v %v @", r.Cycles, r.Count)
-		for _, pc := range r.Stack() {
-			fmt.Fprintf(w, " %#x", pc)
-		}
-		fmt.Fprint(w, "\n")
-		if debug > 0 {
-			printStackRecord(w, r.Stack(), true)
-		}
-	}
-
-	if tw != nil {
-		tw.Flush()
-	}
-	return b.Flush()
-}
-
-func runtime_cyclesPerSecond() int64
diff --git a/src/pkg/runtime/pprof/pprof_test.go b/src/pkg/runtime/pprof/pprof_test.go
deleted file mode 100644
index aba538e..0000000
--- a/src/pkg/runtime/pprof/pprof_test.go
+++ /dev/null
@@ -1,403 +0,0 @@
-// Copyright 2011 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build !nacl
-
-package pprof_test
-
-import (
-	"bytes"
-	"fmt"
-	"hash/crc32"
-	"math/big"
-	"os/exec"
-	"regexp"
-	"runtime"
-	. "runtime/pprof"
-	"strings"
-	"sync"
-	"testing"
-	"time"
-	"unsafe"
-)
-
-func TestCPUProfile(t *testing.T) {
-	buf := make([]byte, 100000)
-	testCPUProfile(t, []string{"crc32.ChecksumIEEE"}, func() {
-		// This loop takes about a quarter second on a 2 GHz laptop.
-		// We only need to get one 100 Hz clock tick, so we've got
-		// a 25x safety buffer.
-		for i := 0; i < 1000; i++ {
-			crc32.ChecksumIEEE(buf)
-		}
-	})
-}
-
-func TestCPUProfileMultithreaded(t *testing.T) {
-	buf := make([]byte, 100000)
-	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(2))
-	testCPUProfile(t, []string{"crc32.ChecksumIEEE", "crc32.Update"}, func() {
-		c := make(chan int)
-		go func() {
-			for i := 0; i < 2000; i++ {
-				crc32.Update(0, crc32.IEEETable, buf)
-			}
-			c <- 1
-		}()
-		// This loop takes about a quarter second on a 2 GHz laptop.
-		// We only need to get one 100 Hz clock tick, so we've got
-		// a 25x safety buffer.
-		for i := 0; i < 2000; i++ {
-			crc32.ChecksumIEEE(buf)
-		}
-		<-c
-	})
-}
-
-func parseProfile(t *testing.T, bytes []byte, f func(uintptr, []uintptr)) {
-	// Convert []byte to []uintptr.
-	l := len(bytes) / int(unsafe.Sizeof(uintptr(0)))
-	val := *(*[]uintptr)(unsafe.Pointer(&bytes))
-	val = val[:l]
-
-	// 5 for the header, 2 for the per-sample header on at least one sample, 3 for the trailer.
-	if l < 5+2+3 {
-		t.Logf("profile too short: %#x", val)
-		if badOS[runtime.GOOS] {
-			t.Skipf("ignoring failure on %s; see golang.org/issue/6047", runtime.GOOS)
-			return
-		}
-		t.FailNow()
-	}
-
-	hd, val, tl := val[:5], val[5:l-3], val[l-3:]
-	if hd[0] != 0 || hd[1] != 3 || hd[2] != 0 || hd[3] != 1e6/100 || hd[4] != 0 {
-		t.Fatalf("unexpected header %#x", hd)
-	}
-
-	if tl[0] != 0 || tl[1] != 1 || tl[2] != 0 {
-		t.Fatalf("malformed end-of-data marker %#x", tl)
-	}
-
-	for len(val) > 0 {
-		if len(val) < 2 || val[0] < 1 || val[1] < 1 || uintptr(len(val)) < 2+val[1] {
-			t.Fatalf("malformed profile.  leftover: %#x", val)
-		}
-		f(val[0], val[2:2+val[1]])
-		val = val[2+val[1]:]
-	}
-}
-
-func testCPUProfile(t *testing.T, need []string, f func()) {
-	switch runtime.GOOS {
-	case "darwin":
-		out, err := exec.Command("uname", "-a").CombinedOutput()
-		if err != nil {
-			t.Fatal(err)
-		}
-		vers := string(out)
-		t.Logf("uname -a: %v", vers)
-	case "plan9":
-		// unimplemented
-		return
-	}
-
-	var prof bytes.Buffer
-	if err := StartCPUProfile(&prof); err != nil {
-		t.Fatal(err)
-	}
-	f()
-	StopCPUProfile()
-
-	// Check that profile is well formed and contains ChecksumIEEE.
-	have := make([]uintptr, len(need))
-	parseProfile(t, prof.Bytes(), func(count uintptr, stk []uintptr) {
-		for _, pc := range stk {
-			f := runtime.FuncForPC(pc)
-			if f == nil {
-				continue
-			}
-			for i, name := range need {
-				if strings.Contains(f.Name(), name) {
-					have[i] += count
-				}
-			}
-		}
-	})
-
-	if len(need) == 0 {
-		return
-	}
-
-	var total uintptr
-	for i, name := range need {
-		total += have[i]
-		t.Logf("%s: %d\n", name, have[i])
-	}
-	ok := true
-	if total == 0 {
-		t.Logf("no CPU profile samples collected")
-		ok = false
-	}
-	// We'd like to check a reasonable minimum, like
-	// total / len(have) / smallconstant, but this test is
-	// pretty flaky (see bug 7095).  So we'll just test to
-	// make sure we got at least one sample.
-	min := uintptr(1)
-	for i, name := range need {
-		if have[i] < min {
-			t.Logf("%s has %d samples out of %d, want at least %d, ideally %d", name, have[i], total, min, total/uintptr(len(have)))
-			ok = false
-		}
-	}
-
-	if !ok {
-		if badOS[runtime.GOOS] {
-			t.Skipf("ignoring failure on %s; see golang.org/issue/6047", runtime.GOOS)
-			return
-		}
-		t.FailNow()
-	}
-}
-
-func TestCPUProfileWithFork(t *testing.T) {
-	// Fork can hang if preempted with signals frequently enough (see issue 5517).
-	// Ensure that we do not do this.
-	heap := 1 << 30
-	if testing.Short() {
-		heap = 100 << 20
-	}
-	// This makes fork slower.
-	garbage := make([]byte, heap)
-	// Need to touch the slice, otherwise it won't be paged in.
-	done := make(chan bool)
-	go func() {
-		for i := range garbage {
-			garbage[i] = 42
-		}
-		done <- true
-	}()
-	<-done
-
-	var prof bytes.Buffer
-	if err := StartCPUProfile(&prof); err != nil {
-		t.Fatal(err)
-	}
-	defer StopCPUProfile()
-
-	for i := 0; i < 10; i++ {
-		exec.Command("go").CombinedOutput()
-	}
-}
-
-// Test that profiler does not observe runtime.gogo as "user" goroutine execution.
-// If it did, it would see inconsistent state and would either record an incorrect stack
-// or crash because the stack was malformed.
-func TestGoroutineSwitch(t *testing.T) {
-	// How much to try. These defaults take about 1 seconds
-	// on a 2012 MacBook Pro. The ones in short mode take
-	// about 0.1 seconds.
-	tries := 10
-	count := 1000000
-	if testing.Short() {
-		tries = 1
-	}
-	for try := 0; try < tries; try++ {
-		var prof bytes.Buffer
-		if err := StartCPUProfile(&prof); err != nil {
-			t.Fatal(err)
-		}
-		for i := 0; i < count; i++ {
-			runtime.Gosched()
-		}
-		StopCPUProfile()
-
-		// Read profile to look for entries for runtime.gogo with an attempt at a traceback.
-		// The special entry
-		parseProfile(t, prof.Bytes(), func(count uintptr, stk []uintptr) {
-			// An entry with two frames with 'System' in its top frame
-			// exists to record a PC without a traceback. Those are okay.
-			if len(stk) == 2 {
-				f := runtime.FuncForPC(stk[1])
-				if f != nil && (f.Name() == "System" || f.Name() == "ExternalCode") {
-					return
-				}
-			}
-
-			// Otherwise, should not see runtime.gogo.
-			// The place we'd see it would be the inner most frame.
-			f := runtime.FuncForPC(stk[0])
-			if f != nil && f.Name() == "runtime.gogo" {
-				var buf bytes.Buffer
-				for _, pc := range stk {
-					f := runtime.FuncForPC(pc)
-					if f == nil {
-						fmt.Fprintf(&buf, "%#x ?:0\n", pc)
-					} else {
-						file, line := f.FileLine(pc)
-						fmt.Fprintf(&buf, "%#x %s:%d\n", pc, file, line)
-					}
-				}
-				t.Fatalf("found profile entry for runtime.gogo:\n%s", buf.String())
-			}
-		})
-	}
-}
-
-// Test that profiling of division operations is okay, especially on ARM. See issue 6681.
-func TestMathBigDivide(t *testing.T) {
-	testCPUProfile(t, nil, func() {
-		t := time.After(5 * time.Second)
-		pi := new(big.Int)
-		for {
-			for i := 0; i < 100; i++ {
-				n := big.NewInt(2646693125139304345)
-				d := big.NewInt(842468587426513207)
-				pi.Div(n, d)
-			}
-			select {
-			case <-t:
-				return
-			default:
-			}
-		}
-	})
-}
-
-// Operating systems that are expected to fail the tests. See issue 6047.
-var badOS = map[string]bool{
-	"darwin": true,
-	"netbsd": true,
-	"plan9":  true,
-}
-
-func TestBlockProfile(t *testing.T) {
-	type TestCase struct {
-		name string
-		f    func()
-		re   string
-	}
-	tests := [...]TestCase{
-		{"chan recv", blockChanRecv, `
-[0-9]+ [0-9]+ @ 0x[0-9,a-f]+ 0x[0-9,a-f]+ 0x[0-9,a-f]+ 0x[0-9,a-f]+ 0x[0-9,a-f]+
-#	0x[0-9,a-f]+	runtime\.chanrecv1\+0x[0-9,a-f]+	.*/src/pkg/runtime/chan.goc:[0-9]+
-#	0x[0-9,a-f]+	runtime/pprof_test\.blockChanRecv\+0x[0-9,a-f]+	.*/src/pkg/runtime/pprof/pprof_test.go:[0-9]+
-#	0x[0-9,a-f]+	runtime/pprof_test\.TestBlockProfile\+0x[0-9,a-f]+	.*/src/pkg/runtime/pprof/pprof_test.go:[0-9]+
-`},
-		{"chan send", blockChanSend, `
-[0-9]+ [0-9]+ @ 0x[0-9,a-f]+ 0x[0-9,a-f]+ 0x[0-9,a-f]+ 0x[0-9,a-f]+ 0x[0-9,a-f]+
-#	0x[0-9,a-f]+	runtime\.chansend1\+0x[0-9,a-f]+	.*/src/pkg/runtime/chan.goc:[0-9]+
-#	0x[0-9,a-f]+	runtime/pprof_test\.blockChanSend\+0x[0-9,a-f]+	.*/src/pkg/runtime/pprof/pprof_test.go:[0-9]+
-#	0x[0-9,a-f]+	runtime/pprof_test\.TestBlockProfile\+0x[0-9,a-f]+	.*/src/pkg/runtime/pprof/pprof_test.go:[0-9]+
-`},
-		{"chan close", blockChanClose, `
-[0-9]+ [0-9]+ @ 0x[0-9,a-f]+ 0x[0-9,a-f]+ 0x[0-9,a-f]+ 0x[0-9,a-f]+ 0x[0-9,a-f]+
-#	0x[0-9,a-f]+	runtime\.chanrecv1\+0x[0-9,a-f]+	.*/src/pkg/runtime/chan.goc:[0-9]+
-#	0x[0-9,a-f]+	runtime/pprof_test\.blockChanClose\+0x[0-9,a-f]+	.*/src/pkg/runtime/pprof/pprof_test.go:[0-9]+
-#	0x[0-9,a-f]+	runtime/pprof_test\.TestBlockProfile\+0x[0-9,a-f]+	.*/src/pkg/runtime/pprof/pprof_test.go:[0-9]+
-`},
-		{"select recv async", blockSelectRecvAsync, `
-[0-9]+ [0-9]+ @ 0x[0-9,a-f]+ 0x[0-9,a-f]+ 0x[0-9,a-f]+ 0x[0-9,a-f]+ 0x[0-9,a-f]+
-#	0x[0-9,a-f]+	runtime\.selectgo\+0x[0-9,a-f]+	.*/src/pkg/runtime/chan.goc:[0-9]+
-#	0x[0-9,a-f]+	runtime/pprof_test\.blockSelectRecvAsync\+0x[0-9,a-f]+	.*/src/pkg/runtime/pprof/pprof_test.go:[0-9]+
-#	0x[0-9,a-f]+	runtime/pprof_test\.TestBlockProfile\+0x[0-9,a-f]+	.*/src/pkg/runtime/pprof/pprof_test.go:[0-9]+
-`},
-		{"select send sync", blockSelectSendSync, `
-[0-9]+ [0-9]+ @ 0x[0-9,a-f]+ 0x[0-9,a-f]+ 0x[0-9,a-f]+ 0x[0-9,a-f]+ 0x[0-9,a-f]+
-#	0x[0-9,a-f]+	runtime\.selectgo\+0x[0-9,a-f]+	.*/src/pkg/runtime/chan.goc:[0-9]+
-#	0x[0-9,a-f]+	runtime/pprof_test\.blockSelectSendSync\+0x[0-9,a-f]+	.*/src/pkg/runtime/pprof/pprof_test.go:[0-9]+
-#	0x[0-9,a-f]+	runtime/pprof_test\.TestBlockProfile\+0x[0-9,a-f]+	.*/src/pkg/runtime/pprof/pprof_test.go:[0-9]+
-`},
-		{"mutex", blockMutex, `
-[0-9]+ [0-9]+ @ 0x[0-9,a-f]+ 0x[0-9,a-f]+ 0x[0-9,a-f]+ 0x[0-9,a-f]+ 0x[0-9,a-f]+
-#	0x[0-9,a-f]+	sync\.\(\*Mutex\)\.Lock\+0x[0-9,a-f]+	.*/src/pkg/sync/mutex\.go:[0-9]+
-#	0x[0-9,a-f]+	runtime/pprof_test\.blockMutex\+0x[0-9,a-f]+	.*/src/pkg/runtime/pprof/pprof_test.go:[0-9]+
-#	0x[0-9,a-f]+	runtime/pprof_test\.TestBlockProfile\+0x[0-9,a-f]+	.*/src/pkg/runtime/pprof/pprof_test.go:[0-9]+
-`},
-	}
-
-	runtime.SetBlockProfileRate(1)
-	defer runtime.SetBlockProfileRate(0)
-	for _, test := range tests {
-		test.f()
-	}
-	var w bytes.Buffer
-	Lookup("block").WriteTo(&w, 1)
-	prof := w.String()
-
-	if !strings.HasPrefix(prof, "--- contention:\ncycles/second=") {
-		t.Fatalf("Bad profile header:\n%v", prof)
-	}
-
-	for _, test := range tests {
-		if !regexp.MustCompile(test.re).MatchString(prof) {
-			t.Fatalf("Bad %v entry, expect:\n%v\ngot:\n%v", test.name, test.re, prof)
-		}
-	}
-}
-
-const blockDelay = 10 * time.Millisecond
-
-func blockChanRecv() {
-	c := make(chan bool)
-	go func() {
-		time.Sleep(blockDelay)
-		c <- true
-	}()
-	<-c
-}
-
-func blockChanSend() {
-	c := make(chan bool)
-	go func() {
-		time.Sleep(blockDelay)
-		<-c
-	}()
-	c <- true
-}
-
-func blockChanClose() {
-	c := make(chan bool)
-	go func() {
-		time.Sleep(blockDelay)
-		close(c)
-	}()
-	<-c
-}
-
-func blockSelectRecvAsync() {
-	c := make(chan bool, 1)
-	c2 := make(chan bool, 1)
-	go func() {
-		time.Sleep(blockDelay)
-		c <- true
-	}()
-	select {
-	case <-c:
-	case <-c2:
-	}
-}
-
-func blockSelectSendSync() {
-	c := make(chan bool)
-	c2 := make(chan bool)
-	go func() {
-		time.Sleep(blockDelay)
-		<-c
-	}()
-	select {
-	case c <- true:
-	case c2 <- true:
-	}
-}
-
-func blockMutex() {
-	var mu sync.Mutex
-	mu.Lock()
-	go func() {
-		time.Sleep(blockDelay)
-		mu.Unlock()
-	}()
-	mu.Lock()
-}
diff --git a/src/pkg/runtime/print.c b/src/pkg/runtime/print.c
deleted file mode 100644
index a04708f..0000000
--- a/src/pkg/runtime/print.c
+++ /dev/null
@@ -1,393 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "runtime.h"
-#include "type.h"
-#include "../../cmd/ld/textflag.h"
-
-//static Lock debuglock;
-
-static void vprintf(int8*, byte*);
-
-// write to goroutine-local buffer if diverting output,
-// or else standard error.
-static void
-gwrite(void *v, intgo n)
-{
-	if(g == nil || g->writebuf == nil) {
-		runtime·write(2, v, n);
-		return;
-	}
-
-	if(g->writenbuf == 0)
-		return;
-
-	if(n > g->writenbuf)
-		n = g->writenbuf;
-	runtime·memmove(g->writebuf, v, n);
-	g->writebuf += n;
-	g->writenbuf -= n;
-}
-
-void
-runtime·dump(byte *p, int32 n)
-{
-	int32 i;
-
-	for(i=0; i<n; i++) {
-		runtime·printpointer((byte*)(p[i]>>4));
-		runtime·printpointer((byte*)(p[i]&0xf));
-		if((i&15) == 15)
-			runtime·prints("\n");
-		else
-			runtime·prints(" ");
-	}
-	if(n & 15)
-		runtime·prints("\n");
-}
-
-void
-runtime·prints(int8 *s)
-{
-	gwrite(s, runtime·findnull((byte*)s));
-}
-
-#pragma textflag NOSPLIT
-void
-runtime·printf(int8 *s, ...)
-{
-	byte *arg;
-
-	arg = (byte*)(&s+1);
-	vprintf(s, arg);
-}
-
-#pragma textflag NOSPLIT
-int32
-runtime·snprintf(byte *buf, int32 n, int8 *s, ...)
-{
-	byte *arg;
-	int32 m;
-
-	arg = (byte*)(&s+1);
-	g->writebuf = buf;
-	g->writenbuf = n-1;
-	vprintf(s, arg);
-	*g->writebuf = '\0';
-	m = g->writebuf - buf;
-	g->writenbuf = 0;
-	g->writebuf = nil;
-	return m;
-}
-
-// Very simple printf.  Only for debugging prints.
-// Do not add to this without checking with Rob.
-static void
-vprintf(int8 *s, byte *base)
-{
-	int8 *p, *lp;
-	uintptr arg, siz;
-	byte *v;
-
-	//runtime·lock(&debuglock);
-
-	lp = p = s;
-	arg = (uintptr)base;
-	for(; *p; p++) {
-		if(*p != '%')
-			continue;
-		if(p > lp)
-			gwrite(lp, p-lp);
-		p++;
-		siz = 0;
-		switch(*p) {
-		case 't':
-		case 'c':
-			siz = 1;
-			break;
-		case 'd':	// 32-bit
-		case 'x':
-			arg = ROUND(arg, 4);
-			siz = 4;
-			break;
-		case 'D':	// 64-bit
-		case 'U':
-		case 'X':
-		case 'f':
-			arg = ROUND(arg, sizeof(uintreg));
-			siz = 8;
-			break;
-		case 'C':
-			arg = ROUND(arg, sizeof(uintreg));
-			siz = 16;
-			break;
-		case 'p':	// pointer-sized
-		case 's':
-			arg = ROUND(arg, sizeof(uintptr));
-			siz = sizeof(uintptr);
-			break;
-		case 'S':	// pointer-aligned but bigger
-			arg = ROUND(arg, sizeof(uintptr));
-			siz = sizeof(String);
-			break;
-		case 'a':	// pointer-aligned but bigger
-			arg = ROUND(arg, sizeof(uintptr));
-			siz = sizeof(Slice);
-			break;
-		case 'i':	// pointer-aligned but bigger
-		case 'e':
-			arg = ROUND(arg, sizeof(uintptr));
-			siz = sizeof(Eface);
-			break;
-		}
-		v = (byte*)arg;
-		switch(*p) {
-		case 'a':
-			runtime·printslice(*(Slice*)v);
-			break;
-		case 'c':
-			runtime·printbyte(*(int8*)v);
-			break;
-		case 'd':
-			runtime·printint(*(int32*)v);
-			break;
-		case 'D':
-			runtime·printint(*(int64*)v);
-			break;
-		case 'e':
-			runtime·printeface(*(Eface*)v);
-			break;
-		case 'f':
-			runtime·printfloat(*(float64*)v);
-			break;
-		case 'C':
-			runtime·printcomplex(*(Complex128*)v);
-			break;
-		case 'i':
-			runtime·printiface(*(Iface*)v);
-			break;
-		case 'p':
-			runtime·printpointer(*(void**)v);
-			break;
-		case 's':
-			runtime·prints(*(int8**)v);
-			break;
-		case 'S':
-			runtime·printstring(*(String*)v);
-			break;
-		case 't':
-			runtime·printbool(*(bool*)v);
-			break;
-		case 'U':
-			runtime·printuint(*(uint64*)v);
-			break;
-		case 'x':
-			runtime·printhex(*(uint32*)v);
-			break;
-		case 'X':
-			runtime·printhex(*(uint64*)v);
-			break;
-		}
-		arg += siz;
-		lp = p+1;
-	}
-	if(p > lp)
-		gwrite(lp, p-lp);
-
-	//runtime·unlock(&debuglock);
-}
-
-#pragma textflag NOSPLIT
-void
-runtime·goprintf(String s, ...)
-{
-	// Can assume s has terminating NUL because only
-	// the Go compiler generates calls to runtime·goprintf, using
-	// string constants, and all the string constants have NULs.
-	vprintf((int8*)s.str, (byte*)(&s+1));
-}
-
-void
-runtime·printpc(void *p)
-{
-	runtime·prints("PC=");
-	runtime·printhex((uint64)runtime·getcallerpc(p));
-}
-
-void
-runtime·printbool(bool v)
-{
-	if(v) {
-		gwrite((byte*)"true", 4);
-		return;
-	}
-	gwrite((byte*)"false", 5);
-}
-
-void
-runtime·printbyte(int8 c)
-{
-	gwrite(&c, 1);
-}
-
-void
-runtime·printfloat(float64 v)
-{
-	byte buf[20];
-	int32 e, s, i, n;
-	float64 h;
-
-	if(ISNAN(v)) {
-		gwrite("NaN", 3);
-		return;
-	}
-	if(v == runtime·posinf) {
-		gwrite("+Inf", 4);
-		return;
-	}
-	if(v == runtime·neginf) {
-		gwrite("-Inf", 4);
-		return;
-	}
-
-	n = 7;	// digits printed
-	e = 0;	// exp
-	s = 0;	// sign
-	if(v == 0) {
-		if(1/v == runtime·neginf)
-			s = 1;
-	} else {
-		// sign
-		if(v < 0) {
-			v = -v;
-			s = 1;
-		}
-
-		// normalize
-		while(v >= 10) {
-			e++;
-			v /= 10;
-		}
-		while(v < 1) {
-			e--;
-			v *= 10;
-		}
-
-		// round
-		h = 5;
-		for(i=0; i<n; i++)
-			h /= 10;
-
-		v += h;
-		if(v >= 10) {
-			e++;
-			v /= 10;
-		}
-	}
-
-	// format +d.dddd+edd
-	buf[0] = '+';
-	if(s)
-		buf[0] = '-';
-	for(i=0; i<n; i++) {
-		s = v;
-		buf[i+2] = s+'0';
-		v -= s;
-		v *= 10.;
-	}
-	buf[1] = buf[2];
-	buf[2] = '.';
-
-	buf[n+2] = 'e';
-	buf[n+3] = '+';
-	if(e < 0) {
-		e = -e;
-		buf[n+3] = '-';
-	}
-
-	buf[n+4] = (e/100) + '0';
-	buf[n+5] = (e/10)%10 + '0';
-	buf[n+6] = (e%10) + '0';
-	gwrite(buf, n+7);
-}
-
-void
-runtime·printcomplex(Complex128 v)
-{
-	gwrite("(", 1);
-	runtime·printfloat(v.real);
-	runtime·printfloat(v.imag);
-	gwrite("i)", 2);
-}
-
-void
-runtime·printuint(uint64 v)
-{
-	byte buf[100];
-	int32 i;
-
-	for(i=nelem(buf)-1; i>0; i--) {
-		buf[i] = v%10 + '0';
-		if(v < 10)
-			break;
-		v = v/10;
-	}
-	gwrite(buf+i, nelem(buf)-i);
-}
-
-void
-runtime·printint(int64 v)
-{
-	if(v < 0) {
-		gwrite("-", 1);
-		v = -v;
-	}
-	runtime·printuint(v);
-}
-
-void
-runtime·printhex(uint64 v)
-{
-	static int8 *dig = "0123456789abcdef";
-	byte buf[100];
-	int32 i;
-
-	i=nelem(buf);
-	for(; v>0; v/=16)
-		buf[--i] = dig[v%16];
-	if(i == nelem(buf))
-		buf[--i] = '0';
-	buf[--i] = 'x';
-	buf[--i] = '0';
-	gwrite(buf+i, nelem(buf)-i);
-}
-
-void
-runtime·printpointer(void *p)
-{
-	runtime·printhex((uintptr)p);
-}
-
-void
-runtime·printstring(String v)
-{
-	if(v.len > runtime·maxstring) {
-		gwrite("[string too long]", 17);
-		return;
-	}
-	if(v.len > 0)
-		gwrite(v.str, v.len);
-}
-
-void
-runtime·printsp(void)
-{
-	gwrite(" ", 1);
-}
-
-void
-runtime·printnl(void)
-{
-	gwrite("\n", 1);
-}
diff --git a/src/pkg/runtime/proc.c b/src/pkg/runtime/proc.c
deleted file mode 100644
index de4f701..0000000
--- a/src/pkg/runtime/proc.c
+++ /dev/null
@@ -1,3153 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "runtime.h"
-#include "arch_GOARCH.h"
-#include "zaexperiment.h"
-#include "malloc.h"
-#include "stack.h"
-#include "race.h"
-#include "type.h"
-#include "../../cmd/ld/textflag.h"
-
-// Goroutine scheduler
-// The scheduler's job is to distribute ready-to-run goroutines over worker threads.
-//
-// The main concepts are:
-// G - goroutine.
-// M - worker thread, or machine.
-// P - processor, a resource that is required to execute Go code.
-//     M must have an associated P to execute Go code, however it can be
-//     blocked or in a syscall w/o an associated P.
-//
-// Design doc at http://golang.org/s/go11sched.
-
-typedef struct Sched Sched;
-struct Sched {
-	Lock;
-
-	uint64	goidgen;
-
-	M*	midle;	 // idle m's waiting for work
-	int32	nmidle;	 // number of idle m's waiting for work
-	int32	nmidlelocked; // number of locked m's waiting for work
-	int32	mcount;	 // number of m's that have been created
-	int32	maxmcount;	// maximum number of m's allowed (or die)
-
-	P*	pidle;  // idle P's
-	uint32	npidle;
-	uint32	nmspinning;
-
-	// Global runnable queue.
-	G*	runqhead;
-	G*	runqtail;
-	int32	runqsize;
-
-	// Global cache of dead G's.
-	Lock	gflock;
-	G*	gfree;
-
-	uint32	gcwaiting;	// gc is waiting to run
-	int32	stopwait;
-	Note	stopnote;
-	uint32	sysmonwait;
-	Note	sysmonnote;
-	uint64	lastpoll;
-
-	int32	profilehz;	// cpu profiling rate
-};
-
-enum
-{
-	// The max value of GOMAXPROCS.
-	// There are no fundamental restrictions on the value.
-	MaxGomaxprocs = 1<<8,
-
-	// Number of goroutine ids to grab from runtime·sched.goidgen to local per-P cache at once.
-	// 16 seems to provide enough amortization, but other than that it's mostly arbitrary number.
-	GoidCacheBatch = 16,
-};
-
-Sched	runtime·sched;
-int32	runtime·gomaxprocs;
-uint32	runtime·needextram;
-bool	runtime·iscgo;
-M	runtime·m0;
-G	runtime·g0;	// idle goroutine for m0
-G*	runtime·lastg;
-M*	runtime·allm;
-M*	runtime·extram;
-int8*	runtime·goos;
-int32	runtime·ncpu;
-static int32	newprocs;
-
-static	Lock allglock;	// the following vars are protected by this lock or by stoptheworld
-G**	runtime·allg;
-uintptr runtime·allglen;
-static	uintptr allgcap;
-
-void runtime·mstart(void);
-static void runqput(P*, G*);
-static G* runqget(P*);
-static bool runqputslow(P*, G*, uint32, uint32);
-static G* runqsteal(P*, P*);
-static void mput(M*);
-static M* mget(void);
-static void mcommoninit(M*);
-static void schedule(void);
-static void procresize(int32);
-static void acquirep(P*);
-static P* releasep(void);
-static void newm(void(*)(void), P*);
-static void stopm(void);
-static void startm(P*, bool);
-static void handoffp(P*);
-static void wakep(void);
-static void stoplockedm(void);
-static void startlockedm(G*);
-static void sysmon(void);
-static uint32 retake(int64);
-static void incidlelocked(int32);
-static void checkdead(void);
-static void exitsyscall0(G*);
-static void park0(G*);
-static void goexit0(G*);
-static void gfput(P*, G*);
-static G* gfget(P*);
-static void gfpurge(P*);
-static void globrunqput(G*);
-static void globrunqputbatch(G*, G*, int32);
-static G* globrunqget(P*, int32);
-static P* pidleget(void);
-static void pidleput(P*);
-static void injectglist(G*);
-static bool preemptall(void);
-static bool preemptone(P*);
-static bool exitsyscallfast(void);
-static bool haveexperiment(int8*);
-static void allgadd(G*);
-
-// The bootstrap sequence is:
-//
-//	call osinit
-//	call schedinit
-//	make & queue new G
-//	call runtime·mstart
-//
-// The new G calls runtime·main.
-void
-runtime·schedinit(void)
-{
-	int32 n, procs;
-	byte *p;
-	Eface i;
-
-	runtime·sched.maxmcount = 10000;
-	runtime·precisestack = true; // haveexperiment("precisestack");
-
-	runtime·symtabinit();
-	runtime·mallocinit();
-	mcommoninit(m);
-	
-	// Initialize the itable value for newErrorCString,
-	// so that the next time it gets called, possibly
-	// in a fault during a garbage collection, it will not
-	// need to allocated memory.
-	runtime·newErrorCString(0, &i);
-	
-	// Initialize the cached gotraceback value, since
-	// gotraceback calls getenv, which mallocs on Plan 9.
-	runtime·gotraceback(nil);
-
-	runtime·goargs();
-	runtime·goenvs();
-	runtime·parsedebugvars();
-
-	runtime·sched.lastpoll = runtime·nanotime();
-	procs = 1;
-	p = runtime·getenv("GOMAXPROCS");
-	if(p != nil && (n = runtime·atoi(p)) > 0) {
-		if(n > MaxGomaxprocs)
-			n = MaxGomaxprocs;
-		procs = n;
-	}
-	runtime·allp = runtime·malloc((MaxGomaxprocs+1)*sizeof(runtime·allp[0]));
-	procresize(procs);
-
-	runtime·copystack = runtime·precisestack;
-	p = runtime·getenv("GOCOPYSTACK");
-	if(p != nil && !runtime·strcmp(p, (byte*)"0"))
-		runtime·copystack = false;
-
-	mstats.enablegc = 1;
-
-	if(raceenabled)
-		g->racectx = runtime·raceinit();
-}
-
-extern void main·init(void);
-extern void main·main(void);
-
-static FuncVal scavenger = {runtime·MHeap_Scavenger};
-
-static FuncVal initDone = { runtime·unlockOSThread };
-
-// The main goroutine.
-// Note: C frames in general are not copyable during stack growth, for two reasons:
-//   1) We don't know where in a frame to find pointers to other stack locations.
-//   2) There's no guarantee that globals or heap values do not point into the frame.
-//
-// The C frame for runtime.main is copyable, because:
-//   1) There are no pointers to other stack locations in the frame
-//      (d.fn points at a global, d.link is nil, d.argp is -1).
-//   2) The only pointer into this frame is from the defer chain,
-//      which is explicitly handled during stack copying.
-void
-runtime·main(void)
-{
-	Defer d;
-	
-	// Max stack size is 1 GB on 64-bit, 250 MB on 32-bit.
-	// Using decimal instead of binary GB and MB because
-	// they look nicer in the stack overflow failure message.
-	if(sizeof(void*) == 8)
-		runtime·maxstacksize = 1000000000;
-	else
-		runtime·maxstacksize = 250000000;
-
-	newm(sysmon, nil);
-
-	// Lock the main goroutine onto this, the main OS thread,
-	// during initialization.  Most programs won't care, but a few
-	// do require certain calls to be made by the main thread.
-	// Those can arrange for main.main to run in the main thread
-	// by calling runtime.LockOSThread during initialization
-	// to preserve the lock.
-	runtime·lockOSThread();
-	
-	// Defer unlock so that runtime.Goexit during init does the unlock too.
-	d.fn = &initDone;
-	d.siz = 0;
-	d.link = g->defer;
-	d.argp = NoArgs;
-	d.special = true;
-	g->defer = &d;
-
-	if(m != &runtime·m0)
-		runtime·throw("runtime·main not on m0");
-	runtime·newproc1(&scavenger, nil, 0, 0, runtime·main);
-	main·init();
-
-	if(g->defer != &d || d.fn != &initDone)
-		runtime·throw("runtime: bad defer entry after init");
-	g->defer = d.link;
-	runtime·unlockOSThread();
-
-	main·main();
-	if(raceenabled)
-		runtime·racefini();
-
-	// Make racy client program work: if panicking on
-	// another goroutine at the same time as main returns,
-	// let the other goroutine finish printing the panic trace.
-	// Once it does, it will exit. See issue 3934.
-	if(runtime·panicking)
-		runtime·park(nil, nil, "panicwait");
-
-	runtime·exit(0);
-	for(;;)
-		*(int32*)runtime·main = 0;
-}
-
-void
-runtime·goroutineheader(G *gp)
-{
-	int8 *status;
-	int64 waitfor;
-
-	switch(gp->status) {
-	case Gidle:
-		status = "idle";
-		break;
-	case Grunnable:
-		status = "runnable";
-		break;
-	case Grunning:
-		status = "running";
-		break;
-	case Gsyscall:
-		status = "syscall";
-		break;
-	case Gwaiting:
-		if(gp->waitreason)
-			status = gp->waitreason;
-		else
-			status = "waiting";
-		break;
-	default:
-		status = "???";
-		break;
-	}
-
-	// approx time the G is blocked, in minutes
-	waitfor = 0;
-	if((gp->status == Gwaiting || gp->status == Gsyscall) && gp->waitsince != 0)
-		waitfor = (runtime·nanotime() - gp->waitsince) / (60LL*1000*1000*1000);
-
-	if(waitfor < 1)
-		runtime·printf("goroutine %D [%s]:\n", gp->goid, status);
-	else
-		runtime·printf("goroutine %D [%s, %D minutes]:\n", gp->goid, status, waitfor);
-}
-
-void
-runtime·tracebackothers(G *me)
-{
-	G *gp;
-	int32 traceback;
-	uintptr i;
-
-	traceback = runtime·gotraceback(nil);
-	
-	// Show the current goroutine first, if we haven't already.
-	if((gp = m->curg) != nil && gp != me) {
-		runtime·printf("\n");
-		runtime·goroutineheader(gp);
-		runtime·traceback(~(uintptr)0, ~(uintptr)0, 0, gp);
-	}
-
-	runtime·lock(&allglock);
-	for(i = 0; i < runtime·allglen; i++) {
-		gp = runtime·allg[i];
-		if(gp == me || gp == m->curg || gp->status == Gdead)
-			continue;
-		if(gp->issystem && traceback < 2)
-			continue;
-		runtime·printf("\n");
-		runtime·goroutineheader(gp);
-		if(gp->status == Grunning) {
-			runtime·printf("\tgoroutine running on other thread; stack unavailable\n");
-			runtime·printcreatedby(gp);
-		} else
-			runtime·traceback(~(uintptr)0, ~(uintptr)0, 0, gp);
-	}
-	runtime·unlock(&allglock);
-}
-
-static void
-checkmcount(void)
-{
-	// sched lock is held
-	if(runtime·sched.mcount > runtime·sched.maxmcount) {
-		runtime·printf("runtime: program exceeds %d-thread limit\n", runtime·sched.maxmcount);
-		runtime·throw("thread exhaustion");
-	}
-}
-
-static void
-mcommoninit(M *mp)
-{
-	// If there is no mcache runtime·callers() will crash,
-	// and we are most likely in sysmon thread so the stack is senseless anyway.
-	if(m->mcache)
-		runtime·callers(1, mp->createstack, nelem(mp->createstack));
-
-	mp->fastrand = 0x49f6428aUL + mp->id + runtime·cputicks();
-
-	runtime·lock(&runtime·sched);
-	mp->id = runtime·sched.mcount++;
-	checkmcount();
-	runtime·mpreinit(mp);
-
-	// Add to runtime·allm so garbage collector doesn't free m
-	// when it is just in a register or thread-local storage.
-	mp->alllink = runtime·allm;
-	// runtime·NumCgoCall() iterates over allm w/o schedlock,
-	// so we need to publish it safely.
-	runtime·atomicstorep(&runtime·allm, mp);
-	runtime·unlock(&runtime·sched);
-}
-
-// Mark gp ready to run.
-void
-runtime·ready(G *gp)
-{
-	// Mark runnable.
-	m->locks++;  // disable preemption because it can be holding p in a local var
-	if(gp->status != Gwaiting) {
-		runtime·printf("goroutine %D has status %d\n", gp->goid, gp->status);
-		runtime·throw("bad g->status in ready");
-	}
-	gp->status = Grunnable;
-	runqput(m->p, gp);
-	if(runtime·atomicload(&runtime·sched.npidle) != 0 && runtime·atomicload(&runtime·sched.nmspinning) == 0)  // TODO: fast atomic
-		wakep();
-	m->locks--;
-	if(m->locks == 0 && g->preempt)  // restore the preemption request in case we've cleared it in newstack
-		g->stackguard0 = StackPreempt;
-}
-
-int32
-runtime·gcprocs(void)
-{
-	int32 n;
-
-	// Figure out how many CPUs to use during GC.
-	// Limited by gomaxprocs, number of actual CPUs, and MaxGcproc.
-	runtime·lock(&runtime·sched);
-	n = runtime·gomaxprocs;
-	if(n > runtime·ncpu)
-		n = runtime·ncpu;
-	if(n > MaxGcproc)
-		n = MaxGcproc;
-	if(n > runtime·sched.nmidle+1) // one M is currently running
-		n = runtime·sched.nmidle+1;
-	runtime·unlock(&runtime·sched);
-	return n;
-}
-
-static bool
-needaddgcproc(void)
-{
-	int32 n;
-
-	runtime·lock(&runtime·sched);
-	n = runtime·gomaxprocs;
-	if(n > runtime·ncpu)
-		n = runtime·ncpu;
-	if(n > MaxGcproc)
-		n = MaxGcproc;
-	n -= runtime·sched.nmidle+1; // one M is currently running
-	runtime·unlock(&runtime·sched);
-	return n > 0;
-}
-
-void
-runtime·helpgc(int32 nproc)
-{
-	M *mp;
-	int32 n, pos;
-
-	runtime·lock(&runtime·sched);
-	pos = 0;
-	for(n = 1; n < nproc; n++) {  // one M is currently running
-		if(runtime·allp[pos]->mcache == m->mcache)
-			pos++;
-		mp = mget();
-		if(mp == nil)
-			runtime·throw("runtime·gcprocs inconsistency");
-		mp->helpgc = n;
-		mp->mcache = runtime·allp[pos]->mcache;
-		pos++;
-		runtime·notewakeup(&mp->park);
-	}
-	runtime·unlock(&runtime·sched);
-}
-
-// Similar to stoptheworld but best-effort and can be called several times.
-// There is no reverse operation, used during crashing.
-// This function must not lock any mutexes.
-void
-runtime·freezetheworld(void)
-{
-	int32 i;
-
-	if(runtime·gomaxprocs == 1)
-		return;
-	// stopwait and preemption requests can be lost
-	// due to races with concurrently executing threads,
-	// so try several times
-	for(i = 0; i < 5; i++) {
-		// this should tell the scheduler to not start any new goroutines
-		runtime·sched.stopwait = 0x7fffffff;
-		runtime·atomicstore((uint32*)&runtime·sched.gcwaiting, 1);
-		// this should stop running goroutines
-		if(!preemptall())
-			break;  // no running goroutines
-		runtime·usleep(1000);
-	}
-	// to be sure
-	runtime·usleep(1000);
-	preemptall();
-	runtime·usleep(1000);
-}
-
-void
-runtime·stoptheworld(void)
-{
-	int32 i;
-	uint32 s;
-	P *p;
-	bool wait;
-
-	runtime·lock(&runtime·sched);
-	runtime·sched.stopwait = runtime·gomaxprocs;
-	runtime·atomicstore((uint32*)&runtime·sched.gcwaiting, 1);
-	preemptall();
-	// stop current P
-	m->p->status = Pgcstop;
-	runtime·sched.stopwait--;
-	// try to retake all P's in Psyscall status
-	for(i = 0; i < runtime·gomaxprocs; i++) {
-		p = runtime·allp[i];
-		s = p->status;
-		if(s == Psyscall && runtime·cas(&p->status, s, Pgcstop))
-			runtime·sched.stopwait--;
-	}
-	// stop idle P's
-	while(p = pidleget()) {
-		p->status = Pgcstop;
-		runtime·sched.stopwait--;
-	}
-	wait = runtime·sched.stopwait > 0;
-	runtime·unlock(&runtime·sched);
-
-	// wait for remaining P's to stop voluntarily
-	if(wait) {
-		for(;;) {
-			// wait for 100us, then try to re-preempt in case of any races
-			if(runtime·notetsleep(&runtime·sched.stopnote, 100*1000)) {
-				runtime·noteclear(&runtime·sched.stopnote);
-				break;
-			}
-			preemptall();
-		}
-	}
-	if(runtime·sched.stopwait)
-		runtime·throw("stoptheworld: not stopped");
-	for(i = 0; i < runtime·gomaxprocs; i++) {
-		p = runtime·allp[i];
-		if(p->status != Pgcstop)
-			runtime·throw("stoptheworld: not stopped");
-	}
-}
-
-static void
-mhelpgc(void)
-{
-	m->helpgc = -1;
-}
-
-void
-runtime·starttheworld(void)
-{
-	P *p, *p1;
-	M *mp;
-	G *gp;
-	bool add;
-
-	m->locks++;  // disable preemption because it can be holding p in a local var
-	gp = runtime·netpoll(false);  // non-blocking
-	injectglist(gp);
-	add = needaddgcproc();
-	runtime·lock(&runtime·sched);
-	if(newprocs) {
-		procresize(newprocs);
-		newprocs = 0;
-	} else
-		procresize(runtime·gomaxprocs);
-	runtime·sched.gcwaiting = 0;
-
-	p1 = nil;
-	while(p = pidleget()) {
-		// procresize() puts p's with work at the beginning of the list.
-		// Once we reach a p without a run queue, the rest don't have one either.
-		if(p->runqhead == p->runqtail) {
-			pidleput(p);
-			break;
-		}
-		p->m = mget();
-		p->link = p1;
-		p1 = p;
-	}
-	if(runtime·sched.sysmonwait) {
-		runtime·sched.sysmonwait = false;
-		runtime·notewakeup(&runtime·sched.sysmonnote);
-	}
-	runtime·unlock(&runtime·sched);
-
-	while(p1) {
-		p = p1;
-		p1 = p1->link;
-		if(p->m) {
-			mp = p->m;
-			p->m = nil;
-			if(mp->nextp)
-				runtime·throw("starttheworld: inconsistent mp->nextp");
-			mp->nextp = p;
-			runtime·notewakeup(&mp->park);
-		} else {
-			// Start M to run P.  Do not start another M below.
-			newm(nil, p);
-			add = false;
-		}
-	}
-
-	if(add) {
-		// If GC could have used another helper proc, start one now,
-		// in the hope that it will be available next time.
-		// It would have been even better to start it before the collection,
-		// but doing so requires allocating memory, so it's tricky to
-		// coordinate.  This lazy approach works out in practice:
-		// we don't mind if the first couple gc rounds don't have quite
-		// the maximum number of procs.
-		newm(mhelpgc, nil);
-	}
-	m->locks--;
-	if(m->locks == 0 && g->preempt)  // restore the preemption request in case we've cleared it in newstack
-		g->stackguard0 = StackPreempt;
-}
-
-// Called to start an M.
-void
-runtime·mstart(void)
-{
-	if(g != m->g0)
-		runtime·throw("bad runtime·mstart");
-
-	// Record top of stack for use by mcall.
-	// Once we call schedule we're never coming back,
-	// so other calls can reuse this stack space.
-	runtime·gosave(&m->g0->sched);
-	m->g0->sched.pc = (uintptr)-1;  // make sure it is never used
-	m->g0->stackguard = m->g0->stackguard0;  // cgo sets only stackguard0, copy it to stackguard
-	runtime·asminit();
-	runtime·minit();
-
-	// Install signal handlers; after minit so that minit can
-	// prepare the thread to be able to handle the signals.
-	if(m == &runtime·m0)
-		runtime·initsig();
-	
-	if(m->mstartfn)
-		m->mstartfn();
-
-	if(m->helpgc) {
-		m->helpgc = 0;
-		stopm();
-	} else if(m != &runtime·m0) {
-		acquirep(m->nextp);
-		m->nextp = nil;
-	}
-	schedule();
-
-	// TODO(brainman): This point is never reached, because scheduler
-	// does not release os threads at the moment. But once this path
-	// is enabled, we must remove our seh here.
-}
-
-// When running with cgo, we call _cgo_thread_start
-// to start threads for us so that we can play nicely with
-// foreign code.
-void (*_cgo_thread_start)(void*);
-
-typedef struct CgoThreadStart CgoThreadStart;
-struct CgoThreadStart
-{
-	M *m;
-	G *g;
-	uintptr *tls;
-	void (*fn)(void);
-};
-
-// Allocate a new m unassociated with any thread.
-// Can use p for allocation context if needed.
-M*
-runtime·allocm(P *p)
-{
-	M *mp;
-	static Type *mtype;  // The Go type M
-
-	m->locks++;  // disable GC because it can be called from sysmon
-	if(m->p == nil)
-		acquirep(p);  // temporarily borrow p for mallocs in this function
-	if(mtype == nil) {
-		Eface e;
-		runtime·gc_m_ptr(&e);
-		mtype = ((PtrType*)e.type)->elem;
-	}
-
-	mp = runtime·cnew(mtype);
-	mcommoninit(mp);
-
-	// In case of cgo or Solaris, pthread_create will make us a stack.
-	// Windows will layout sched stack on OS stack.
-	if(runtime·iscgo || Solaris || Windows)
-		mp->g0 = runtime·malg(-1);
-	else
-		mp->g0 = runtime·malg(8192);
-
-	if(p == m->p)
-		releasep();
-	m->locks--;
-	if(m->locks == 0 && g->preempt)  // restore the preemption request in case we've cleared it in newstack
-		g->stackguard0 = StackPreempt;
-
-	return mp;
-}
-
-static G*
-allocg(void)
-{
-	G *gp;
-	static Type *gtype;
-	
-	if(gtype == nil) {
-		Eface e;
-		runtime·gc_g_ptr(&e);
-		gtype = ((PtrType*)e.type)->elem;
-	}
-	gp = runtime·cnew(gtype);
-	return gp;
-}
-
-static M* lockextra(bool nilokay);
-static void unlockextra(M*);
-
-// needm is called when a cgo callback happens on a
-// thread without an m (a thread not created by Go).
-// In this case, needm is expected to find an m to use
-// and return with m, g initialized correctly.
-// Since m and g are not set now (likely nil, but see below)
-// needm is limited in what routines it can call. In particular
-// it can only call nosplit functions (textflag 7) and cannot
-// do any scheduling that requires an m.
-//
-// In order to avoid needing heavy lifting here, we adopt
-// the following strategy: there is a stack of available m's
-// that can be stolen. Using compare-and-swap
-// to pop from the stack has ABA races, so we simulate
-// a lock by doing an exchange (via casp) to steal the stack
-// head and replace the top pointer with MLOCKED (1).
-// This serves as a simple spin lock that we can use even
-// without an m. The thread that locks the stack in this way
-// unlocks the stack by storing a valid stack head pointer.
-//
-// In order to make sure that there is always an m structure
-// available to be stolen, we maintain the invariant that there
-// is always one more than needed. At the beginning of the
-// program (if cgo is in use) the list is seeded with a single m.
-// If needm finds that it has taken the last m off the list, its job
-// is - once it has installed its own m so that it can do things like
-// allocate memory - to create a spare m and put it on the list.
-//
-// Each of these extra m's also has a g0 and a curg that are
-// pressed into service as the scheduling stack and current
-// goroutine for the duration of the cgo callback.
-//
-// When the callback is done with the m, it calls dropm to
-// put the m back on the list.
-#pragma textflag NOSPLIT
-void
-runtime·needm(byte x)
-{
-	M *mp;
-
-	if(runtime·needextram) {
-		// Can happen if C/C++ code calls Go from a global ctor.
-		// Can not throw, because scheduler is not initialized yet.
-		runtime·write(2, "fatal error: cgo callback before cgo call\n",
-			sizeof("fatal error: cgo callback before cgo call\n")-1);
-		runtime·exit(1);
-	}
-
-	// Lock extra list, take head, unlock popped list.
-	// nilokay=false is safe here because of the invariant above,
-	// that the extra list always contains or will soon contain
-	// at least one m.
-	mp = lockextra(false);
-
-	// Set needextram when we've just emptied the list,
-	// so that the eventual call into cgocallbackg will
-	// allocate a new m for the extra list. We delay the
-	// allocation until then so that it can be done
-	// after exitsyscall makes sure it is okay to be
-	// running at all (that is, there's no garbage collection
-	// running right now).
-	mp->needextram = mp->schedlink == nil;
-	unlockextra(mp->schedlink);
-
-	// Install m and g (= m->g0) and set the stack bounds
-	// to match the current stack. We don't actually know
-	// how big the stack is, like we don't know how big any
-	// scheduling stack is, but we assume there's at least 32 kB,
-	// which is more than enough for us.
-	runtime·setmg(mp, mp->g0);
-	g->stackbase = (uintptr)(&x + 1024);
-	g->stackguard = (uintptr)(&x - 32*1024);
-	g->stackguard0 = g->stackguard;
-
-	// Initialize this thread to use the m.
-	runtime·asminit();
-	runtime·minit();
-}
-
-// newextram allocates an m and puts it on the extra list.
-// It is called with a working local m, so that it can do things
-// like call schedlock and allocate.
-void
-runtime·newextram(void)
-{
-	M *mp, *mnext;
-	G *gp;
-
-	// Create extra goroutine locked to extra m.
-	// The goroutine is the context in which the cgo callback will run.
-	// The sched.pc will never be returned to, but setting it to
-	// runtime.goexit makes clear to the traceback routines where
-	// the goroutine stack ends.
-	mp = runtime·allocm(nil);
-	gp = runtime·malg(4096);
-	gp->sched.pc = (uintptr)runtime·goexit;
-	gp->sched.sp = gp->stackbase;
-	gp->sched.lr = 0;
-	gp->sched.g = gp;
-	gp->syscallpc = gp->sched.pc;
-	gp->syscallsp = gp->sched.sp;
-	gp->syscallstack = gp->stackbase;
-	gp->syscallguard = gp->stackguard;
-	gp->status = Gsyscall;
-	mp->curg = gp;
-	mp->locked = LockInternal;
-	mp->lockedg = gp;
-	gp->lockedm = mp;
-	gp->goid = runtime·xadd64(&runtime·sched.goidgen, 1);
-	if(raceenabled)
-		gp->racectx = runtime·racegostart(runtime·newextram);
-	// put on allg for garbage collector
-	allgadd(gp);
-
-	// Add m to the extra list.
-	mnext = lockextra(true);
-	mp->schedlink = mnext;
-	unlockextra(mp);
-}
-
-// dropm is called when a cgo callback has called needm but is now
-// done with the callback and returning back into the non-Go thread.
-// It puts the current m back onto the extra list.
-//
-// The main expense here is the call to signalstack to release the
-// m's signal stack, and then the call to needm on the next callback
-// from this thread. It is tempting to try to save the m for next time,
-// which would eliminate both these costs, but there might not be
-// a next time: the current thread (which Go does not control) might exit.
-// If we saved the m for that thread, there would be an m leak each time
-// such a thread exited. Instead, we acquire and release an m on each
-// call. These should typically not be scheduling operations, just a few
-// atomics, so the cost should be small.
-//
-// TODO(rsc): An alternative would be to allocate a dummy pthread per-thread
-// variable using pthread_key_create. Unlike the pthread keys we already use
-// on OS X, this dummy key would never be read by Go code. It would exist
-// only so that we could register at thread-exit-time destructor.
-// That destructor would put the m back onto the extra list.
-// This is purely a performance optimization. The current version,
-// in which dropm happens on each cgo call, is still correct too.
-// We may have to keep the current version on systems with cgo
-// but without pthreads, like Windows.
-void
-runtime·dropm(void)
-{
-	M *mp, *mnext;
-
-	// Undo whatever initialization minit did during needm.
-	runtime·unminit();
-
-	// Clear m and g, and return m to the extra list.
-	// After the call to setmg we can only call nosplit functions.
-	mp = m;
-	runtime·setmg(nil, nil);
-
-	mnext = lockextra(true);
-	mp->schedlink = mnext;
-	unlockextra(mp);
-}
-
-#define MLOCKED ((M*)1)
-
-// lockextra locks the extra list and returns the list head.
-// The caller must unlock the list by storing a new list head
-// to runtime.extram. If nilokay is true, then lockextra will
-// return a nil list head if that's what it finds. If nilokay is false,
-// lockextra will keep waiting until the list head is no longer nil.
-#pragma textflag NOSPLIT
-static M*
-lockextra(bool nilokay)
-{
-	M *mp;
-	void (*yield)(void);
-
-	for(;;) {
-		mp = runtime·atomicloadp(&runtime·extram);
-		if(mp == MLOCKED) {
-			yield = runtime·osyield;
-			yield();
-			continue;
-		}
-		if(mp == nil && !nilokay) {
-			runtime·usleep(1);
-			continue;
-		}
-		if(!runtime·casp(&runtime·extram, mp, MLOCKED)) {
-			yield = runtime·osyield;
-			yield();
-			continue;
-		}
-		break;
-	}
-	return mp;
-}
-
-#pragma textflag NOSPLIT
-static void
-unlockextra(M *mp)
-{
-	runtime·atomicstorep(&runtime·extram, mp);
-}
-
-
-// Create a new m.  It will start off with a call to fn, or else the scheduler.
-static void
-newm(void(*fn)(void), P *p)
-{
-	M *mp;
-
-	mp = runtime·allocm(p);
-	mp->nextp = p;
-	mp->mstartfn = fn;
-
-	if(runtime·iscgo) {
-		CgoThreadStart ts;
-
-		if(_cgo_thread_start == nil)
-			runtime·throw("_cgo_thread_start missing");
-		ts.m = mp;
-		ts.g = mp->g0;
-		ts.tls = mp->tls;
-		ts.fn = runtime·mstart;
-		runtime·asmcgocall(_cgo_thread_start, &ts);
-		return;
-	}
-	runtime·newosproc(mp, (byte*)mp->g0->stackbase);
-}
-
-// Stops execution of the current m until new work is available.
-// Returns with acquired P.
-static void
-stopm(void)
-{
-	if(m->locks)
-		runtime·throw("stopm holding locks");
-	if(m->p)
-		runtime·throw("stopm holding p");
-	if(m->spinning) {
-		m->spinning = false;
-		runtime·xadd(&runtime·sched.nmspinning, -1);
-	}
-
-retry:
-	runtime·lock(&runtime·sched);
-	mput(m);
-	runtime·unlock(&runtime·sched);
-	runtime·notesleep(&m->park);
-	runtime·noteclear(&m->park);
-	if(m->helpgc) {
-		runtime·gchelper();
-		m->helpgc = 0;
-		m->mcache = nil;
-		goto retry;
-	}
-	acquirep(m->nextp);
-	m->nextp = nil;
-}
-
-static void
-mspinning(void)
-{
-	m->spinning = true;
-}
-
-// Schedules some M to run the p (creates an M if necessary).
-// If p==nil, tries to get an idle P, if no idle P's does nothing.
-static void
-startm(P *p, bool spinning)
-{
-	M *mp;
-	void (*fn)(void);
-
-	runtime·lock(&runtime·sched);
-	if(p == nil) {
-		p = pidleget();
-		if(p == nil) {
-			runtime·unlock(&runtime·sched);
-			if(spinning)
-				runtime·xadd(&runtime·sched.nmspinning, -1);
-			return;
-		}
-	}
-	mp = mget();
-	runtime·unlock(&runtime·sched);
-	if(mp == nil) {
-		fn = nil;
-		if(spinning)
-			fn = mspinning;
-		newm(fn, p);
-		return;
-	}
-	if(mp->spinning)
-		runtime·throw("startm: m is spinning");
-	if(mp->nextp)
-		runtime·throw("startm: m has p");
-	mp->spinning = spinning;
-	mp->nextp = p;
-	runtime·notewakeup(&mp->park);
-}
-
-// Hands off P from syscall or locked M.
-static void
-handoffp(P *p)
-{
-	// if it has local work, start it straight away
-	if(p->runqhead != p->runqtail || runtime·sched.runqsize) {
-		startm(p, false);
-		return;
-	}
-	// no local work, check that there are no spinning/idle M's,
-	// otherwise our help is not required
-	if(runtime·atomicload(&runtime·sched.nmspinning) + runtime·atomicload(&runtime·sched.npidle) == 0 &&  // TODO: fast atomic
-		runtime·cas(&runtime·sched.nmspinning, 0, 1)) {
-		startm(p, true);
-		return;
-	}
-	runtime·lock(&runtime·sched);
-	if(runtime·sched.gcwaiting) {
-		p->status = Pgcstop;
-		if(--runtime·sched.stopwait == 0)
-			runtime·notewakeup(&runtime·sched.stopnote);
-		runtime·unlock(&runtime·sched);
-		return;
-	}
-	if(runtime·sched.runqsize) {
-		runtime·unlock(&runtime·sched);
-		startm(p, false);
-		return;
-	}
-	// If this is the last running P and nobody is polling network,
-	// need to wakeup another M to poll network.
-	if(runtime·sched.npidle == runtime·gomaxprocs-1 && runtime·atomicload64(&runtime·sched.lastpoll) != 0) {
-		runtime·unlock(&runtime·sched);
-		startm(p, false);
-		return;
-	}
-	pidleput(p);
-	runtime·unlock(&runtime·sched);
-}
-
-// Tries to add one more P to execute G's.
-// Called when a G is made runnable (newproc, ready).
-static void
-wakep(void)
-{
-	// be conservative about spinning threads
-	if(!runtime·cas(&runtime·sched.nmspinning, 0, 1))
-		return;
-	startm(nil, true);
-}
-
-// Stops execution of the current m that is locked to a g until the g is runnable again.
-// Returns with acquired P.
-static void
-stoplockedm(void)
-{
-	P *p;
-
-	if(m->lockedg == nil || m->lockedg->lockedm != m)
-		runtime·throw("stoplockedm: inconsistent locking");
-	if(m->p) {
-		// Schedule another M to run this p.
-		p = releasep();
-		handoffp(p);
-	}
-	incidlelocked(1);
-	// Wait until another thread schedules lockedg again.
-	runtime·notesleep(&m->park);
-	runtime·noteclear(&m->park);
-	if(m->lockedg->status != Grunnable)
-		runtime·throw("stoplockedm: not runnable");
-	acquirep(m->nextp);
-	m->nextp = nil;
-}
-
-// Schedules the locked m to run the locked gp.
-static void
-startlockedm(G *gp)
-{
-	M *mp;
-	P *p;
-
-	mp = gp->lockedm;
-	if(mp == m)
-		runtime·throw("startlockedm: locked to me");
-	if(mp->nextp)
-		runtime·throw("startlockedm: m has p");
-	// directly handoff current P to the locked m
-	incidlelocked(-1);
-	p = releasep();
-	mp->nextp = p;
-	runtime·notewakeup(&mp->park);
-	stopm();
-}
-
-// Stops the current m for stoptheworld.
-// Returns when the world is restarted.
-static void
-gcstopm(void)
-{
-	P *p;
-
-	if(!runtime·sched.gcwaiting)
-		runtime·throw("gcstopm: not waiting for gc");
-	if(m->spinning) {
-		m->spinning = false;
-		runtime·xadd(&runtime·sched.nmspinning, -1);
-	}
-	p = releasep();
-	runtime·lock(&runtime·sched);
-	p->status = Pgcstop;
-	if(--runtime·sched.stopwait == 0)
-		runtime·notewakeup(&runtime·sched.stopnote);
-	runtime·unlock(&runtime·sched);
-	stopm();
-}
-
-// Schedules gp to run on the current M.
-// Never returns.
-static void
-execute(G *gp)
-{
-	int32 hz;
-
-	if(gp->status != Grunnable) {
-		runtime·printf("execute: bad g status %d\n", gp->status);
-		runtime·throw("execute: bad g status");
-	}
-	gp->status = Grunning;
-	gp->waitsince = 0;
-	gp->preempt = false;
-	gp->stackguard0 = gp->stackguard;
-	m->p->schedtick++;
-	m->curg = gp;
-	gp->m = m;
-
-	// Check whether the profiler needs to be turned on or off.
-	hz = runtime·sched.profilehz;
-	if(m->profilehz != hz)
-		runtime·resetcpuprofiler(hz);
-
-	runtime·gogo(&gp->sched);
-}
-
-// Finds a runnable goroutine to execute.
-// Tries to steal from other P's, get g from global queue, poll network.
-static G*
-findrunnable(void)
-{
-	G *gp;
-	P *p;
-	int32 i;
-
-top:
-	if(runtime·sched.gcwaiting) {
-		gcstopm();
-		goto top;
-	}
-	if(runtime·fingwait && runtime·fingwake && (gp = runtime·wakefing()) != nil)
-		runtime·ready(gp);
-	// local runq
-	gp = runqget(m->p);
-	if(gp)
-		return gp;
-	// global runq
-	if(runtime·sched.runqsize) {
-		runtime·lock(&runtime·sched);
-		gp = globrunqget(m->p, 0);
-		runtime·unlock(&runtime·sched);
-		if(gp)
-			return gp;
-	}
-	// poll network
-	gp = runtime·netpoll(false);  // non-blocking
-	if(gp) {
-		injectglist(gp->schedlink);
-		gp->status = Grunnable;
-		return gp;
-	}
-	// If number of spinning M's >= number of busy P's, block.
-	// This is necessary to prevent excessive CPU consumption
-	// when GOMAXPROCS>>1 but the program parallelism is low.
-	if(!m->spinning && 2 * runtime·atomicload(&runtime·sched.nmspinning) >= runtime·gomaxprocs - runtime·atomicload(&runtime·sched.npidle))  // TODO: fast atomic
-		goto stop;
-	if(!m->spinning) {
-		m->spinning = true;
-		runtime·xadd(&runtime·sched.nmspinning, 1);
-	}
-	// random steal from other P's
-	for(i = 0; i < 2*runtime·gomaxprocs; i++) {
-		if(runtime·sched.gcwaiting)
-			goto top;
-		p = runtime·allp[runtime·fastrand1()%runtime·gomaxprocs];
-		if(p == m->p)
-			gp = runqget(p);
-		else
-			gp = runqsteal(m->p, p);
-		if(gp)
-			return gp;
-	}
-stop:
-	// return P and block
-	runtime·lock(&runtime·sched);
-	if(runtime·sched.gcwaiting) {
-		runtime·unlock(&runtime·sched);
-		goto top;
-	}
-	if(runtime·sched.runqsize) {
-		gp = globrunqget(m->p, 0);
-		runtime·unlock(&runtime·sched);
-		return gp;
-	}
-	p = releasep();
-	pidleput(p);
-	runtime·unlock(&runtime·sched);
-	if(m->spinning) {
-		m->spinning = false;
-		runtime·xadd(&runtime·sched.nmspinning, -1);
-	}
-	// check all runqueues once again
-	for(i = 0; i < runtime·gomaxprocs; i++) {
-		p = runtime·allp[i];
-		if(p && p->runqhead != p->runqtail) {
-			runtime·lock(&runtime·sched);
-			p = pidleget();
-			runtime·unlock(&runtime·sched);
-			if(p) {
-				acquirep(p);
-				goto top;
-			}
-			break;
-		}
-	}
-	// poll network
-	if(runtime·xchg64(&runtime·sched.lastpoll, 0) != 0) {
-		if(m->p)
-			runtime·throw("findrunnable: netpoll with p");
-		if(m->spinning)
-			runtime·throw("findrunnable: netpoll with spinning");
-		gp = runtime·netpoll(true);  // block until new work is available
-		runtime·atomicstore64(&runtime·sched.lastpoll, runtime·nanotime());
-		if(gp) {
-			runtime·lock(&runtime·sched);
-			p = pidleget();
-			runtime·unlock(&runtime·sched);
-			if(p) {
-				acquirep(p);
-				injectglist(gp->schedlink);
-				gp->status = Grunnable;
-				return gp;
-			}
-			injectglist(gp);
-		}
-	}
-	stopm();
-	goto top;
-}
-
-static void
-resetspinning(void)
-{
-	int32 nmspinning;
-
-	if(m->spinning) {
-		m->spinning = false;
-		nmspinning = runtime·xadd(&runtime·sched.nmspinning, -1);
-		if(nmspinning < 0)
-			runtime·throw("findrunnable: negative nmspinning");
-	} else
-		nmspinning = runtime·atomicload(&runtime·sched.nmspinning);
-
-	// M wakeup policy is deliberately somewhat conservative (see nmspinning handling),
-	// so see if we need to wakeup another P here.
-	if (nmspinning == 0 && runtime·atomicload(&runtime·sched.npidle) > 0)
-		wakep();
-}
-
-// Injects the list of runnable G's into the scheduler.
-// Can run concurrently with GC.
-static void
-injectglist(G *glist)
-{
-	int32 n;
-	G *gp;
-
-	if(glist == nil)
-		return;
-	runtime·lock(&runtime·sched);
-	for(n = 0; glist; n++) {
-		gp = glist;
-		glist = gp->schedlink;
-		gp->status = Grunnable;
-		globrunqput(gp);
-	}
-	runtime·unlock(&runtime·sched);
-
-	for(; n && runtime·sched.npidle; n--)
-		startm(nil, false);
-}
-
-// One round of scheduler: find a runnable goroutine and execute it.
-// Never returns.
-static void
-schedule(void)
-{
-	G *gp;
-	uint32 tick;
-
-	if(m->locks)
-		runtime·throw("schedule: holding locks");
-
-top:
-	if(runtime·sched.gcwaiting) {
-		gcstopm();
-		goto top;
-	}
-
-	gp = nil;
-	// Check the global runnable queue once in a while to ensure fairness.
-	// Otherwise two goroutines can completely occupy the local runqueue
-	// by constantly respawning each other.
-	tick = m->p->schedtick;
-	// This is a fancy way to say tick%61==0,
-	// it uses 2 MUL instructions instead of a single DIV and so is faster on modern processors.
-	if(tick - (((uint64)tick*0x4325c53fu)>>36)*61 == 0 && runtime·sched.runqsize > 0) {
-		runtime·lock(&runtime·sched);
-		gp = globrunqget(m->p, 1);
-		runtime·unlock(&runtime·sched);
-		if(gp)
-			resetspinning();
-	}
-	if(gp == nil) {
-		gp = runqget(m->p);
-		if(gp && m->spinning)
-			runtime·throw("schedule: spinning with local work");
-	}
-	if(gp == nil) {
-		gp = findrunnable();  // blocks until work is available
-		resetspinning();
-	}
-
-	if(gp->lockedm) {
-		// Hands off own p to the locked m,
-		// then blocks waiting for a new p.
-		startlockedm(gp);
-		goto top;
-	}
-
-	execute(gp);
-}
-
-// Puts the current goroutine into a waiting state and calls unlockf.
-// If unlockf returns false, the goroutine is resumed.
-void
-runtime·park(bool(*unlockf)(G*, void*), void *lock, int8 *reason)
-{
-	if(g->status != Grunning)
-		runtime·throw("bad g status");
-	m->waitlock = lock;
-	m->waitunlockf = unlockf;
-	g->waitreason = reason;
-	runtime·mcall(park0);
-}
-
-static bool
-parkunlock(G *gp, void *lock)
-{
-	USED(gp);
-	runtime·unlock(lock);
-	return true;
-}
-
-// Puts the current goroutine into a waiting state and unlocks the lock.
-// The goroutine can be made runnable again by calling runtime·ready(gp).
-void
-runtime·parkunlock(Lock *lock, int8 *reason)
-{
-	runtime·park(parkunlock, lock, reason);
-}
-
-// runtime·park continuation on g0.
-static void
-park0(G *gp)
-{
-	bool ok;
-
-	gp->status = Gwaiting;
-	gp->m = nil;
-	m->curg = nil;
-	if(m->waitunlockf) {
-		ok = m->waitunlockf(gp, m->waitlock);
-		m->waitunlockf = nil;
-		m->waitlock = nil;
-		if(!ok) {
-			gp->status = Grunnable;
-			execute(gp);  // Schedule it back, never returns.
-		}
-	}
-	if(m->lockedg) {
-		stoplockedm();
-		execute(gp);  // Never returns.
-	}
-	schedule();
-}
-
-// Scheduler yield.
-void
-runtime·gosched(void)
-{
-	if(g->status != Grunning)
-		runtime·throw("bad g status");
-	runtime·mcall(runtime·gosched0);
-}
-
-// runtime·gosched continuation on g0.
-void
-runtime·gosched0(G *gp)
-{
-	gp->status = Grunnable;
-	gp->m = nil;
-	m->curg = nil;
-	runtime·lock(&runtime·sched);
-	globrunqput(gp);
-	runtime·unlock(&runtime·sched);
-	if(m->lockedg) {
-		stoplockedm();
-		execute(gp);  // Never returns.
-	}
-	schedule();
-}
-
-// Finishes execution of the current goroutine.
-// Need to mark it as nosplit, because it runs with sp > stackbase (as runtime·lessstack).
-// Since it does not return it does not matter.  But if it is preempted
-// at the split stack check, GC will complain about inconsistent sp.
-#pragma textflag NOSPLIT
-void
-runtime·goexit(void)
-{
-	if(g->status != Grunning)
-		runtime·throw("bad g status");
-	if(raceenabled)
-		runtime·racegoend();
-	runtime·mcall(goexit0);
-}
-
-// runtime·goexit continuation on g0.
-static void
-goexit0(G *gp)
-{
-	gp->status = Gdead;
-	gp->m = nil;
-	gp->lockedm = nil;
-	gp->paniconfault = 0;
-	gp->defer = nil; // should be true already but just in case.
-	gp->panic = nil; // non-nil for Goexit during panic. points at stack-allocated data.
-	gp->writenbuf = 0;
-	gp->writebuf = nil;
-	gp->waitreason = nil;
-	gp->param = nil;
-	m->curg = nil;
-	m->lockedg = nil;
-	if(m->locked & ~LockExternal) {
-		runtime·printf("invalid m->locked = %d\n", m->locked);
-		runtime·throw("internal lockOSThread error");
-	}	
-	m->locked = 0;
-	runtime·unwindstack(gp, nil);
-	gfput(m->p, gp);
-	schedule();
-}
-
-#pragma textflag NOSPLIT
-static void
-save(void *pc, uintptr sp)
-{
-	g->sched.pc = (uintptr)pc;
-	g->sched.sp = sp;
-	g->sched.lr = 0;
-	g->sched.ret = 0;
-	g->sched.ctxt = 0;
-	g->sched.g = g;
-}
-
-// The goroutine g is about to enter a system call.
-// Record that it's not using the cpu anymore.
-// This is called only from the go syscall library and cgocall,
-// not from the low-level system calls used by the runtime.
-//
-// Entersyscall cannot split the stack: the runtime·gosave must
-// make g->sched refer to the caller's stack segment, because
-// entersyscall is going to return immediately after.
-#pragma textflag NOSPLIT
-void
-runtime·reentersyscall(void *pc, uintptr sp)
-{
-	// Disable preemption because during this function g is in Gsyscall status,
-	// but can have inconsistent g->sched, do not let GC observe it.
-	m->locks++;
-
-	// Leave SP around for GC and traceback.
-	save(pc, sp);
-	g->syscallsp = g->sched.sp;
-	g->syscallpc = g->sched.pc;
-	g->syscallstack = g->stackbase;
-	g->syscallguard = g->stackguard;
-	g->status = Gsyscall;
-	if(g->syscallsp < g->syscallguard-StackGuard || g->syscallstack < g->syscallsp) {
-		// runtime·printf("entersyscall inconsistent %p [%p,%p]\n",
-		//	g->syscallsp, g->syscallguard-StackGuard, g->syscallstack);
-		runtime·throw("entersyscall");
-	}
-
-	if(runtime·atomicload(&runtime·sched.sysmonwait)) {  // TODO: fast atomic
-		runtime·lock(&runtime·sched);
-		if(runtime·atomicload(&runtime·sched.sysmonwait)) {
-			runtime·atomicstore(&runtime·sched.sysmonwait, 0);
-			runtime·notewakeup(&runtime·sched.sysmonnote);
-		}
-		runtime·unlock(&runtime·sched);
-		save(pc, sp);
-	}
-
-	m->mcache = nil;
-	m->p->m = nil;
-	runtime·atomicstore(&m->p->status, Psyscall);
-	if(runtime·sched.gcwaiting) {
-		runtime·lock(&runtime·sched);
-		if (runtime·sched.stopwait > 0 && runtime·cas(&m->p->status, Psyscall, Pgcstop)) {
-			if(--runtime·sched.stopwait == 0)
-				runtime·notewakeup(&runtime·sched.stopnote);
-		}
-		runtime·unlock(&runtime·sched);
-		save(pc, sp);
-	}
-
-	// Goroutines must not split stacks in Gsyscall status (it would corrupt g->sched).
-	// We set stackguard to StackPreempt so that first split stack check calls morestack.
-	// Morestack detects this case and throws.
-	g->stackguard0 = StackPreempt;
-	m->locks--;
-}
-
-#pragma textflag NOSPLIT
-void
-·entersyscall(int32 dummy)
-{
-	runtime·reentersyscall(runtime·getcallerpc(&dummy), runtime·getcallersp(&dummy));
-}
-
-// The same as runtime·entersyscall(), but with a hint that the syscall is blocking.
-#pragma textflag NOSPLIT
-void
-·entersyscallblock(int32 dummy)
-{
-	P *p;
-
-	m->locks++;  // see comment in entersyscall
-
-	// Leave SP around for GC and traceback.
-	save(runtime·getcallerpc(&dummy), runtime·getcallersp(&dummy));
-	g->syscallsp = g->sched.sp;
-	g->syscallpc = g->sched.pc;
-	g->syscallstack = g->stackbase;
-	g->syscallguard = g->stackguard;
-	g->status = Gsyscall;
-	if(g->syscallsp < g->syscallguard-StackGuard || g->syscallstack < g->syscallsp) {
-		// runtime·printf("entersyscall inconsistent %p [%p,%p]\n",
-		//	g->syscallsp, g->syscallguard-StackGuard, g->syscallstack);
-		runtime·throw("entersyscallblock");
-	}
-
-	p = releasep();
-	handoffp(p);
-	if(g->isbackground)  // do not consider blocked scavenger for deadlock detection
-		incidlelocked(1);
-
-	// Resave for traceback during blocked call.
-	save(runtime·getcallerpc(&dummy), runtime·getcallersp(&dummy));
-
-	g->stackguard0 = StackPreempt;  // see comment in entersyscall
-	m->locks--;
-}
-
-// The goroutine g exited its system call.
-// Arrange for it to run on a cpu again.
-// This is called only from the go syscall library, not
-// from the low-level system calls used by the runtime.
-#pragma textflag NOSPLIT
-void
-·exitsyscall(int32 dummy)
-{
-	m->locks++;  // see comment in entersyscall
-
-	if(runtime·getcallersp(&dummy) > g->syscallsp)
-		runtime·throw("exitsyscall: syscall frame is no longer valid");
-
-	if(g->isbackground)  // do not consider blocked scavenger for deadlock detection
-		incidlelocked(-1);
-
-	g->waitsince = 0;
-	if(exitsyscallfast()) {
-		// There's a cpu for us, so we can run.
-		m->p->syscalltick++;
-		g->status = Grunning;
-		// Garbage collector isn't running (since we are),
-		// so okay to clear gcstack and gcsp.
-		g->syscallstack = (uintptr)nil;
-		g->syscallsp = (uintptr)nil;
-		m->locks--;
-		if(g->preempt) {
-			// restore the preemption request in case we've cleared it in newstack
-			g->stackguard0 = StackPreempt;
-		} else {
-			// otherwise restore the real stackguard, we've spoiled it in entersyscall/entersyscallblock
-			g->stackguard0 = g->stackguard;
-		}
-		return;
-	}
-
-	m->locks--;
-
-	// Call the scheduler.
-	runtime·mcall(exitsyscall0);
-
-	// Scheduler returned, so we're allowed to run now.
-	// Delete the gcstack information that we left for
-	// the garbage collector during the system call.
-	// Must wait until now because until gosched returns
-	// we don't know for sure that the garbage collector
-	// is not running.
-	g->syscallstack = (uintptr)nil;
-	g->syscallsp = (uintptr)nil;
-	m->p->syscalltick++;
-}
-
-#pragma textflag NOSPLIT
-static bool
-exitsyscallfast(void)
-{
-	P *p;
-
-	// Freezetheworld sets stopwait but does not retake P's.
-	if(runtime·sched.stopwait) {
-		m->p = nil;
-		return false;
-	}
-
-	// Try to re-acquire the last P.
-	if(m->p && m->p->status == Psyscall && runtime·cas(&m->p->status, Psyscall, Prunning)) {
-		// There's a cpu for us, so we can run.
-		m->mcache = m->p->mcache;
-		m->p->m = m;
-		return true;
-	}
-	// Try to get any other idle P.
-	m->p = nil;
-	if(runtime·sched.pidle) {
-		runtime·lock(&runtime·sched);
-		p = pidleget();
-		if(p && runtime·atomicload(&runtime·sched.sysmonwait)) {
-			runtime·atomicstore(&runtime·sched.sysmonwait, 0);
-			runtime·notewakeup(&runtime·sched.sysmonnote);
-		}
-		runtime·unlock(&runtime·sched);
-		if(p) {
-			acquirep(p);
-			return true;
-		}
-	}
-	return false;
-}
-
-// runtime·exitsyscall slow path on g0.
-// Failed to acquire P, enqueue gp as runnable.
-static void
-exitsyscall0(G *gp)
-{
-	P *p;
-
-	gp->status = Grunnable;
-	gp->m = nil;
-	m->curg = nil;
-	runtime·lock(&runtime·sched);
-	p = pidleget();
-	if(p == nil)
-		globrunqput(gp);
-	else if(runtime·atomicload(&runtime·sched.sysmonwait)) {
-		runtime·atomicstore(&runtime·sched.sysmonwait, 0);
-		runtime·notewakeup(&runtime·sched.sysmonnote);
-	}
-	runtime·unlock(&runtime·sched);
-	if(p) {
-		acquirep(p);
-		execute(gp);  // Never returns.
-	}
-	if(m->lockedg) {
-		// Wait until another thread schedules gp and so m again.
-		stoplockedm();
-		execute(gp);  // Never returns.
-	}
-	stopm();
-	schedule();  // Never returns.
-}
-
-// Called from syscall package before fork.
-#pragma textflag NOSPLIT
-void
-syscall·runtime_BeforeFork(void)
-{
-	// Fork can hang if preempted with signals frequently enough (see issue 5517).
-	// Ensure that we stay on the same M where we disable profiling.
-	m->locks++;
-	if(m->profilehz != 0)
-		runtime·resetcpuprofiler(0);
-
-	// This function is called before fork in syscall package.
-	// Code between fork and exec must not allocate memory nor even try to grow stack.
-	// Here we spoil g->stackguard to reliably detect any attempts to grow stack.
-	// runtime_AfterFork will undo this in parent process, but not in child.
-	m->forkstackguard = g->stackguard;
-	g->stackguard0 = StackPreempt-1;
-	g->stackguard = StackPreempt-1;
-}
-
-// Called from syscall package after fork in parent.
-#pragma textflag NOSPLIT
-void
-syscall·runtime_AfterFork(void)
-{
-	int32 hz;
-
-	// See the comment in runtime_BeforeFork.
-	g->stackguard0 = m->forkstackguard;
-	g->stackguard = m->forkstackguard;
-	m->forkstackguard = 0;
-
-	hz = runtime·sched.profilehz;
-	if(hz != 0)
-		runtime·resetcpuprofiler(hz);
-	m->locks--;
-}
-
-// Hook used by runtime·malg to call runtime·stackalloc on the
-// scheduler stack.  This exists because runtime·stackalloc insists
-// on being called on the scheduler stack, to avoid trying to grow
-// the stack while allocating a new stack segment.
-static void
-mstackalloc(G *gp)
-{
-	G *newg;
-	uintptr size;
-
-	newg = (G*)gp->param;
-	size = newg->stacksize;
-	newg->stacksize = 0;
-	gp->param = runtime·stackalloc(newg, size);
-	runtime·gogo(&gp->sched);
-}
-
-// Allocate a new g, with a stack big enough for stacksize bytes.
-G*
-runtime·malg(int32 stacksize)
-{
-	G *newg;
-	byte *stk;
-
-	if(StackTop < sizeof(Stktop)) {
-		runtime·printf("runtime: SizeofStktop=%d, should be >=%d\n", (int32)StackTop, (int32)sizeof(Stktop));
-		runtime·throw("runtime: bad stack.h");
-	}
-
-	newg = allocg();
-	if(stacksize >= 0) {
-		stacksize = runtime·round2(StackSystem + stacksize);
-		if(g == m->g0) {
-			// running on scheduler stack already.
-			stk = runtime·stackalloc(newg, stacksize);
-		} else {
-			// have to call stackalloc on scheduler stack.
-			newg->stacksize = stacksize;
-			g->param = newg;
-			runtime·mcall(mstackalloc);
-			stk = g->param;
-			g->param = nil;
-		}
-		newg->stack0 = (uintptr)stk;
-		newg->stackguard = (uintptr)stk + StackGuard;
-		newg->stackguard0 = newg->stackguard;
-		newg->stackbase = (uintptr)stk + stacksize - sizeof(Stktop);
-	}
-	return newg;
-}
-
-// Create a new g running fn with siz bytes of arguments.
-// Put it on the queue of g's waiting to run.
-// The compiler turns a go statement into a call to this.
-// Cannot split the stack because it assumes that the arguments
-// are available sequentially after &fn; they would not be
-// copied if a stack split occurred.  It's OK for this to call
-// functions that split the stack.
-#pragma textflag NOSPLIT
-void
-runtime·newproc(int32 siz, FuncVal* fn, ...)
-{
-	byte *argp;
-
-	if(thechar == '5')
-		argp = (byte*)(&fn+2);  // skip caller's saved LR
-	else
-		argp = (byte*)(&fn+1);
-	runtime·newproc1(fn, argp, siz, 0, runtime·getcallerpc(&siz));
-}
-
-// Create a new g running fn with narg bytes of arguments starting
-// at argp and returning nret bytes of results.  callerpc is the
-// address of the go statement that created this.  The new g is put
-// on the queue of g's waiting to run.
-G*
-runtime·newproc1(FuncVal *fn, byte *argp, int32 narg, int32 nret, void *callerpc)
-{
-	byte *sp;
-	G *newg;
-	P *p;
-	int32 siz;
-
-//runtime·printf("newproc1 %p %p narg=%d nret=%d\n", fn->fn, argp, narg, nret);
-	if(fn == nil) {
-		m->throwing = -1;  // do not dump full stacks
-		runtime·throw("go of nil func value");
-	}
-	m->locks++;  // disable preemption because it can be holding p in a local var
-	siz = narg + nret;
-	siz = (siz+7) & ~7;
-
-	// We could instead create a secondary stack frame
-	// and make it look like goexit was on the original but
-	// the call to the actual goroutine function was split.
-	// Not worth it: this is almost always an error.
-	if(siz > StackMin - 1024)
-		runtime·throw("runtime.newproc: function arguments too large for new goroutine");
-
-	p = m->p;
-	if((newg = gfget(p)) != nil) {
-		if(newg->stackguard - StackGuard != newg->stack0)
-			runtime·throw("invalid stack in newg");
-	} else {
-		newg = runtime·malg(StackMin);
-		allgadd(newg);
-	}
-
-	sp = (byte*)newg->stackbase;
-	sp -= siz;
-	runtime·memmove(sp, argp, narg);
-	if(thechar == '5') {
-		// caller's LR
-		sp -= sizeof(void*);
-		*(void**)sp = nil;
-	}
-
-	runtime·memclr((byte*)&newg->sched, sizeof newg->sched);
-	newg->sched.sp = (uintptr)sp;
-	newg->sched.pc = (uintptr)runtime·goexit;
-	newg->sched.g = newg;
-	runtime·gostartcallfn(&newg->sched, fn);
-	newg->gopc = (uintptr)callerpc;
-	newg->status = Grunnable;
-	if(p->goidcache == p->goidcacheend) {
-		p->goidcache = runtime·xadd64(&runtime·sched.goidgen, GoidCacheBatch);
-		p->goidcacheend = p->goidcache + GoidCacheBatch;
-	}
-	newg->goid = p->goidcache++;
-	newg->panicwrap = 0;
-	if(raceenabled)
-		newg->racectx = runtime·racegostart((void*)callerpc);
-	runqput(p, newg);
-
-	if(runtime·atomicload(&runtime·sched.npidle) != 0 && runtime·atomicload(&runtime·sched.nmspinning) == 0 && fn->fn != runtime·main)  // TODO: fast atomic
-		wakep();
-	m->locks--;
-	if(m->locks == 0 && g->preempt)  // restore the preemption request in case we've cleared it in newstack
-		g->stackguard0 = StackPreempt;
-	return newg;
-}
-
-static void
-allgadd(G *gp)
-{
-	G **new;
-	uintptr cap;
-
-	runtime·lock(&allglock);
-	if(runtime·allglen >= allgcap) {
-		cap = 4096/sizeof(new[0]);
-		if(cap < 2*allgcap)
-			cap = 2*allgcap;
-		new = runtime·malloc(cap*sizeof(new[0]));
-		if(new == nil)
-			runtime·throw("runtime: cannot allocate memory");
-		if(runtime·allg != nil) {
-			runtime·memmove(new, runtime·allg, runtime·allglen*sizeof(new[0]));
-			runtime·free(runtime·allg);
-		}
-		runtime·allg = new;
-		allgcap = cap;
-	}
-	runtime·allg[runtime·allglen++] = gp;
-	runtime·unlock(&allglock);
-}
-
-// Put on gfree list.
-// If local list is too long, transfer a batch to the global list.
-static void
-gfput(P *p, G *gp)
-{
-	uintptr stksize;
-	Stktop *top;
-
-	if(gp->stackguard - StackGuard != gp->stack0)
-		runtime·throw("invalid stack in gfput");
-	stksize = gp->stackbase + sizeof(Stktop) - gp->stack0;
-	if(stksize != gp->stacksize) {
-		runtime·printf("runtime: bad stacksize, goroutine %D, remain=%d, last=%d\n",
-			gp->goid, (int32)gp->stacksize, (int32)stksize);
-		runtime·throw("gfput: bad stacksize");
-	}
-	top = (Stktop*)gp->stackbase;
-	if(top->malloced) {
-		// non-standard stack size - free it.
-		runtime·stackfree(gp, (void*)gp->stack0, top);
-		gp->stack0 = 0;
-		gp->stackguard = 0;
-		gp->stackguard0 = 0;
-		gp->stackbase = 0;
-	}
-	gp->schedlink = p->gfree;
-	p->gfree = gp;
-	p->gfreecnt++;
-	if(p->gfreecnt >= 64) {
-		runtime·lock(&runtime·sched.gflock);
-		while(p->gfreecnt >= 32) {
-			p->gfreecnt--;
-			gp = p->gfree;
-			p->gfree = gp->schedlink;
-			gp->schedlink = runtime·sched.gfree;
-			runtime·sched.gfree = gp;
-		}
-		runtime·unlock(&runtime·sched.gflock);
-	}
-}
-
-// Get from gfree list.
-// If local list is empty, grab a batch from global list.
-static G*
-gfget(P *p)
-{
-	G *gp;
-	byte *stk;
-
-retry:
-	gp = p->gfree;
-	if(gp == nil && runtime·sched.gfree) {
-		runtime·lock(&runtime·sched.gflock);
-		while(p->gfreecnt < 32 && runtime·sched.gfree) {
-			p->gfreecnt++;
-			gp = runtime·sched.gfree;
-			runtime·sched.gfree = gp->schedlink;
-			gp->schedlink = p->gfree;
-			p->gfree = gp;
-		}
-		runtime·unlock(&runtime·sched.gflock);
-		goto retry;
-	}
-	if(gp) {
-		p->gfree = gp->schedlink;
-		p->gfreecnt--;
-
-		if(gp->stack0 == 0) {
-			// Stack was deallocated in gfput.  Allocate a new one.
-			if(g == m->g0) {
-				stk = runtime·stackalloc(gp, FixedStack);
-			} else {
-				gp->stacksize = FixedStack;
-				g->param = gp;
-				runtime·mcall(mstackalloc);
-				stk = g->param;
-				g->param = nil;
-			}
-			gp->stack0 = (uintptr)stk;
-			gp->stackbase = (uintptr)stk + FixedStack - sizeof(Stktop);
-			gp->stackguard = (uintptr)stk + StackGuard;
-			gp->stackguard0 = gp->stackguard;
-		}
-	}
-	return gp;
-}
-
-// Purge all cached G's from gfree list to the global list.
-static void
-gfpurge(P *p)
-{
-	G *gp;
-
-	runtime·lock(&runtime·sched.gflock);
-	while(p->gfreecnt) {
-		p->gfreecnt--;
-		gp = p->gfree;
-		p->gfree = gp->schedlink;
-		gp->schedlink = runtime·sched.gfree;
-		runtime·sched.gfree = gp;
-	}
-	runtime·unlock(&runtime·sched.gflock);
-}
-
-void
-runtime·Breakpoint(void)
-{
-	runtime·breakpoint();
-}
-
-void
-runtime·Gosched(void)
-{
-	runtime·gosched();
-}
-
-// Implementation of runtime.GOMAXPROCS.
-// delete when scheduler is even stronger
-int32
-runtime·gomaxprocsfunc(int32 n)
-{
-	int32 ret;
-
-	if(n > MaxGomaxprocs)
-		n = MaxGomaxprocs;
-	runtime·lock(&runtime·sched);
-	ret = runtime·gomaxprocs;
-	if(n <= 0 || n == ret) {
-		runtime·unlock(&runtime·sched);
-		return ret;
-	}
-	runtime·unlock(&runtime·sched);
-
-	runtime·semacquire(&runtime·worldsema, false);
-	m->gcing = 1;
-	runtime·stoptheworld();
-	newprocs = n;
-	m->gcing = 0;
-	runtime·semrelease(&runtime·worldsema);
-	runtime·starttheworld();
-
-	return ret;
-}
-
-// lockOSThread is called by runtime.LockOSThread and runtime.lockOSThread below
-// after they modify m->locked. Do not allow preemption during this call,
-// or else the m might be different in this function than in the caller.
-#pragma textflag NOSPLIT
-static void
-lockOSThread(void)
-{
-	m->lockedg = g;
-	g->lockedm = m;
-}
-
-void
-runtime·LockOSThread(void)
-{
-	m->locked |= LockExternal;
-	lockOSThread();
-}
-
-void
-runtime·lockOSThread(void)
-{
-	m->locked += LockInternal;
-	lockOSThread();
-}
-
-
-// unlockOSThread is called by runtime.UnlockOSThread and runtime.unlockOSThread below
-// after they update m->locked. Do not allow preemption during this call,
-// or else the m might be in different in this function than in the caller.
-#pragma textflag NOSPLIT
-static void
-unlockOSThread(void)
-{
-	if(m->locked != 0)
-		return;
-	m->lockedg = nil;
-	g->lockedm = nil;
-}
-
-void
-runtime·UnlockOSThread(void)
-{
-	m->locked &= ~LockExternal;
-	unlockOSThread();
-}
-
-void
-runtime·unlockOSThread(void)
-{
-	if(m->locked < LockInternal)
-		runtime·throw("runtime: internal error: misuse of lockOSThread/unlockOSThread");
-	m->locked -= LockInternal;
-	unlockOSThread();
-}
-
-bool
-runtime·lockedOSThread(void)
-{
-	return g->lockedm != nil && m->lockedg != nil;
-}
-
-int32
-runtime·gcount(void)
-{
-	G *gp;
-	int32 n, s;
-	uintptr i;
-
-	n = 0;
-	runtime·lock(&allglock);
-	// TODO(dvyukov): runtime.NumGoroutine() is O(N).
-	// We do not want to increment/decrement centralized counter in newproc/goexit,
-	// just to make runtime.NumGoroutine() faster.
-	// Compromise solution is to introduce per-P counters of active goroutines.
-	for(i = 0; i < runtime·allglen; i++) {
-		gp = runtime·allg[i];
-		s = gp->status;
-		if(s == Grunnable || s == Grunning || s == Gsyscall || s == Gwaiting)
-			n++;
-	}
-	runtime·unlock(&allglock);
-	return n;
-}
-
-int32
-runtime·mcount(void)
-{
-	return runtime·sched.mcount;
-}
-
-void
-runtime·badmcall(void (*fn)(G*))  // called from assembly
-{
-	USED(fn); // TODO: print fn?
-	runtime·throw("runtime: mcall called on m->g0 stack");
-}
-
-void
-runtime·badmcall2(void (*fn)(G*))  // called from assembly
-{
-	USED(fn);
-	runtime·throw("runtime: mcall function returned");
-}
-
-void
-runtime·badreflectcall(void) // called from assembly
-{
-	runtime·panicstring("runtime: arg size to reflect.call more than 1GB");
-}
-
-static struct {
-	Lock;
-	void (*fn)(uintptr*, int32);
-	int32 hz;
-	uintptr pcbuf[100];
-} prof;
-
-static void System(void) {}
-static void ExternalCode(void) {}
-static void GC(void) {}
-extern byte etext[];
-
-// Called if we receive a SIGPROF signal.
-void
-runtime·sigprof(uint8 *pc, uint8 *sp, uint8 *lr, G *gp, M *mp)
-{
-	int32 n;
-	bool traceback;
-	// Do not use global m in this function, use mp instead.
-	// On windows one m is sending reports about all the g's, so m means a wrong thing.
-	byte m;
-
-	m = 0;
-	USED(m);
-
-	if(prof.fn == nil || prof.hz == 0)
-		return;
-
-	// Profiling runs concurrently with GC, so it must not allocate.
-	mp->mallocing++;
-
-	// Define that a "user g" is a user-created goroutine, and a "system g"
-	// is one that is m->g0 or m->gsignal. We've only made sure that we
-	// can unwind user g's, so exclude the system g's.
-	//
-	// It is not quite as easy as testing gp == m->curg (the current user g)
-	// because we might be interrupted for profiling halfway through a
-	// goroutine switch. The switch involves updating three (or four) values:
-	// g, PC, SP, and (on arm) LR. The PC must be the last to be updated,
-	// because once it gets updated the new g is running.
-	//
-	// When switching from a user g to a system g, LR is not considered live,
-	// so the update only affects g, SP, and PC. Since PC must be last, there
-	// the possible partial transitions in ordinary execution are (1) g alone is updated,
-	// (2) both g and SP are updated, and (3) SP alone is updated.
-	// If g is updated, we'll see a system g and not look closer.
-	// If SP alone is updated, we can detect the partial transition by checking
-	// whether the SP is within g's stack bounds. (We could also require that SP
-	// be changed only after g, but the stack bounds check is needed by other
-	// cases, so there is no need to impose an additional requirement.)
-	//
-	// There is one exceptional transition to a system g, not in ordinary execution.
-	// When a signal arrives, the operating system starts the signal handler running
-	// with an updated PC and SP. The g is updated last, at the beginning of the
-	// handler. There are two reasons this is okay. First, until g is updated the
-	// g and SP do not match, so the stack bounds check detects the partial transition.
-	// Second, signal handlers currently run with signals disabled, so a profiling
-	// signal cannot arrive during the handler.
-	//
-	// When switching from a system g to a user g, there are three possibilities.
-	//
-	// First, it may be that the g switch has no PC update, because the SP
-	// either corresponds to a user g throughout (as in runtime.asmcgocall)
-	// or because it has been arranged to look like a user g frame
-	// (as in runtime.cgocallback_gofunc). In this case, since the entire
-	// transition is a g+SP update, a partial transition updating just one of 
-	// those will be detected by the stack bounds check.
-	//
-	// Second, when returning from a signal handler, the PC and SP updates
-	// are performed by the operating system in an atomic update, so the g
-	// update must be done before them. The stack bounds check detects
-	// the partial transition here, and (again) signal handlers run with signals
-	// disabled, so a profiling signal cannot arrive then anyway.
-	//
-	// Third, the common case: it may be that the switch updates g, SP, and PC
-	// separately, as in runtime.gogo.
-	//
-	// Because runtime.gogo is the only instance, we check whether the PC lies
-	// within that function, and if so, not ask for a traceback. This approach
-	// requires knowing the size of the runtime.gogo function, which we
-	// record in arch_*.h and check in runtime_test.go.
-	//
-	// There is another apparently viable approach, recorded here in case
-	// the "PC within runtime.gogo" check turns out not to be usable.
-	// It would be possible to delay the update of either g or SP until immediately
-	// before the PC update instruction. Then, because of the stack bounds check,
-	// the only problematic interrupt point is just before that PC update instruction,
-	// and the sigprof handler can detect that instruction and simulate stepping past
-	// it in order to reach a consistent state. On ARM, the update of g must be made
-	// in two places (in R10 and also in a TLS slot), so the delayed update would
-	// need to be the SP update. The sigprof handler must read the instruction at
-	// the current PC and if it was the known instruction (for example, JMP BX or 
-	// MOV R2, PC), use that other register in place of the PC value.
-	// The biggest drawback to this solution is that it requires that we can tell
-	// whether it's safe to read from the memory pointed at by PC.
-	// In a correct program, we can test PC == nil and otherwise read,
-	// but if a profiling signal happens at the instant that a program executes
-	// a bad jump (before the program manages to handle the resulting fault)
-	// the profiling handler could fault trying to read nonexistent memory.
-	//
-	// To recap, there are no constraints on the assembly being used for the
-	// transition. We simply require that g and SP match and that the PC is not
-	// in runtime.gogo.
-	traceback = true;
-	if(gp == nil || gp != mp->curg ||
-	   (uintptr)sp < gp->stackguard - StackGuard || gp->stackbase < (uintptr)sp ||
-	   ((uint8*)runtime·gogo <= pc && pc < (uint8*)runtime·gogo + RuntimeGogoBytes))
-		traceback = false;
-
-	runtime·lock(&prof);
-	if(prof.fn == nil) {
-		runtime·unlock(&prof);
-		mp->mallocing--;
-		return;
-	}
-	n = 0;
-	if(traceback)
-		n = runtime·gentraceback((uintptr)pc, (uintptr)sp, (uintptr)lr, gp, 0, prof.pcbuf, nelem(prof.pcbuf), nil, nil, false);
-	if(!traceback || n <= 0) {
-		// Normal traceback is impossible or has failed.
-		// See if it falls into several common cases.
-		n = 0;
-		if(mp->ncgo > 0 && mp->curg != nil &&
-			mp->curg->syscallpc != 0 && mp->curg->syscallsp != 0) {
-			// Cgo, we can't unwind and symbolize arbitrary C code,
-			// so instead collect Go stack that leads to the cgo call.
-			// This is especially important on windows, since all syscalls are cgo calls.
-			n = runtime·gentraceback(mp->curg->syscallpc, mp->curg->syscallsp, 0, mp->curg, 0, prof.pcbuf, nelem(prof.pcbuf), nil, nil, false);
-		}
-#ifdef GOOS_windows
-		if(n == 0 && mp->libcallg != nil && mp->libcallpc != 0 && mp->libcallsp != 0) {
-			// Libcall, i.e. runtime syscall on windows.
-			// Collect Go stack that leads to the call.
-			n = runtime·gentraceback(mp->libcallpc, mp->libcallsp, 0, mp->libcallg, 0, prof.pcbuf, nelem(prof.pcbuf), nil, nil, false);
-		}
-#endif
-		if(n == 0) {
-			// If all of the above has failed, account it against abstract "System" or "GC".
-			n = 2;
-			// "ExternalCode" is better than "etext".
-			if((uintptr)pc > (uintptr)etext)
-				pc = (byte*)ExternalCode + PCQuantum;
-			prof.pcbuf[0] = (uintptr)pc;
-			if(mp->gcing || mp->helpgc)
-				prof.pcbuf[1] = (uintptr)GC + PCQuantum;
-			else
-				prof.pcbuf[1] = (uintptr)System + PCQuantum;
-		}
-	}
-	prof.fn(prof.pcbuf, n);
-	runtime·unlock(&prof);
-	mp->mallocing--;
-}
-
-// Arrange to call fn with a traceback hz times a second.
-void
-runtime·setcpuprofilerate(void (*fn)(uintptr*, int32), int32 hz)
-{
-	// Force sane arguments.
-	if(hz < 0)
-		hz = 0;
-	if(hz == 0)
-		fn = nil;
-	if(fn == nil)
-		hz = 0;
-
-	// Disable preemption, otherwise we can be rescheduled to another thread
-	// that has profiling enabled.
-	m->locks++;
-
-	// Stop profiler on this thread so that it is safe to lock prof.
-	// if a profiling signal came in while we had prof locked,
-	// it would deadlock.
-	runtime·resetcpuprofiler(0);
-
-	runtime·lock(&prof);
-	prof.fn = fn;
-	prof.hz = hz;
-	runtime·unlock(&prof);
-	runtime·lock(&runtime·sched);
-	runtime·sched.profilehz = hz;
-	runtime·unlock(&runtime·sched);
-
-	if(hz != 0)
-		runtime·resetcpuprofiler(hz);
-
-	m->locks--;
-}
-
-// Change number of processors.  The world is stopped, sched is locked.
-static void
-procresize(int32 new)
-{
-	int32 i, old;
-	bool empty;
-	G *gp;
-	P *p;
-
-	old = runtime·gomaxprocs;
-	if(old < 0 || old > MaxGomaxprocs || new <= 0 || new >MaxGomaxprocs)
-		runtime·throw("procresize: invalid arg");
-	// initialize new P's
-	for(i = 0; i < new; i++) {
-		p = runtime·allp[i];
-		if(p == nil) {
-			p = (P*)runtime·mallocgc(sizeof(*p), 0, FlagNoInvokeGC);
-			p->id = i;
-			p->status = Pgcstop;
-			runtime·atomicstorep(&runtime·allp[i], p);
-		}
-		if(p->mcache == nil) {
-			if(old==0 && i==0)
-				p->mcache = m->mcache;  // bootstrap
-			else
-				p->mcache = runtime·allocmcache();
-		}
-	}
-
-	// redistribute runnable G's evenly
-	// collect all runnable goroutines in global queue preserving FIFO order
-	// FIFO order is required to ensure fairness even during frequent GCs
-	// see http://golang.org/issue/7126
-	empty = false;
-	while(!empty) {
-		empty = true;
-		for(i = 0; i < old; i++) {
-			p = runtime·allp[i];
-			if(p->runqhead == p->runqtail)
-				continue;
-			empty = false;
-			// pop from tail of local queue
-			p->runqtail--;
-			gp = p->runq[p->runqtail%nelem(p->runq)];
-			// push onto head of global queue
-			gp->schedlink = runtime·sched.runqhead;
-			runtime·sched.runqhead = gp;
-			if(runtime·sched.runqtail == nil)
-				runtime·sched.runqtail = gp;
-			runtime·sched.runqsize++;
-		}
-	}
-	// fill local queues with at most nelem(p->runq)/2 goroutines
-	// start at 1 because current M already executes some G and will acquire allp[0] below,
-	// so if we have a spare G we want to put it into allp[1].
-	for(i = 1; i < new * nelem(p->runq)/2 && runtime·sched.runqsize > 0; i++) {
-		gp = runtime·sched.runqhead;
-		runtime·sched.runqhead = gp->schedlink;
-		if(runtime·sched.runqhead == nil)
-			runtime·sched.runqtail = nil;
-		runtime·sched.runqsize--;
-		runqput(runtime·allp[i%new], gp);
-	}
-
-	// free unused P's
-	for(i = new; i < old; i++) {
-		p = runtime·allp[i];
-		runtime·freemcache(p->mcache);
-		p->mcache = nil;
-		gfpurge(p);
-		p->status = Pdead;
-		// can't free P itself because it can be referenced by an M in syscall
-	}
-
-	if(m->p)
-		m->p->m = nil;
-	m->p = nil;
-	m->mcache = nil;
-	p = runtime·allp[0];
-	p->m = nil;
-	p->status = Pidle;
-	acquirep(p);
-	for(i = new-1; i > 0; i--) {
-		p = runtime·allp[i];
-		p->status = Pidle;
-		pidleput(p);
-	}
-	runtime·atomicstore((uint32*)&runtime·gomaxprocs, new);
-}
-
-// Associate p and the current m.
-static void
-acquirep(P *p)
-{
-	if(m->p || m->mcache)
-		runtime·throw("acquirep: already in go");
-	if(p->m || p->status != Pidle) {
-		runtime·printf("acquirep: p->m=%p(%d) p->status=%d\n", p->m, p->m ? p->m->id : 0, p->status);
-		runtime·throw("acquirep: invalid p state");
-	}
-	m->mcache = p->mcache;
-	m->p = p;
-	p->m = m;
-	p->status = Prunning;
-}
-
-// Disassociate p and the current m.
-static P*
-releasep(void)
-{
-	P *p;
-
-	if(m->p == nil || m->mcache == nil)
-		runtime·throw("releasep: invalid arg");
-	p = m->p;
-	if(p->m != m || p->mcache != m->mcache || p->status != Prunning) {
-		runtime·printf("releasep: m=%p m->p=%p p->m=%p m->mcache=%p p->mcache=%p p->status=%d\n",
-			m, m->p, p->m, m->mcache, p->mcache, p->status);
-		runtime·throw("releasep: invalid p state");
-	}
-	m->p = nil;
-	m->mcache = nil;
-	p->m = nil;
-	p->status = Pidle;
-	return p;
-}
-
-static void
-incidlelocked(int32 v)
-{
-	runtime·lock(&runtime·sched);
-	runtime·sched.nmidlelocked += v;
-	if(v > 0)
-		checkdead();
-	runtime·unlock(&runtime·sched);
-}
-
-// Check for deadlock situation.
-// The check is based on number of running M's, if 0 -> deadlock.
-static void
-checkdead(void)
-{
-	G *gp;
-	int32 run, grunning, s;
-	uintptr i;
-
-	// -1 for sysmon
-	run = runtime·sched.mcount - runtime·sched.nmidle - runtime·sched.nmidlelocked - 1;
-	if(run > 0)
-		return;
-	// If we are dying because of a signal caught on an already idle thread,
-	// freezetheworld will cause all running threads to block.
-	// And runtime will essentially enter into deadlock state,
-	// except that there is a thread that will call runtime·exit soon.
-	if(runtime·panicking > 0)
-		return;
-	if(run < 0) {
-		runtime·printf("runtime: checkdead: nmidle=%d nmidlelocked=%d mcount=%d\n",
-			runtime·sched.nmidle, runtime·sched.nmidlelocked, runtime·sched.mcount);
-		runtime·throw("checkdead: inconsistent counts");
-	}
-	grunning = 0;
-	runtime·lock(&allglock);
-	for(i = 0; i < runtime·allglen; i++) {
-		gp = runtime·allg[i];
-		if(gp->isbackground)
-			continue;
-		s = gp->status;
-		if(s == Gwaiting)
-			grunning++;
-		else if(s == Grunnable || s == Grunning || s == Gsyscall) {
-			runtime·unlock(&allglock);
-			runtime·printf("runtime: checkdead: find g %D in status %d\n", gp->goid, s);
-			runtime·throw("checkdead: runnable g");
-		}
-	}
-	runtime·unlock(&allglock);
-	if(grunning == 0)  // possible if main goroutine calls runtime·Goexit()
-		runtime·throw("no goroutines (main called runtime.Goexit) - deadlock!");
-	m->throwing = -1;  // do not dump full stacks
-	runtime·throw("all goroutines are asleep - deadlock!");
-}
-
-static void
-sysmon(void)
-{
-	uint32 idle, delay;
-	int64 now, lastpoll, lasttrace;
-	G *gp;
-
-	lasttrace = 0;
-	idle = 0;  // how many cycles in succession we had not wokeup somebody
-	delay = 0;
-	for(;;) {
-		if(idle == 0)  // start with 20us sleep...
-			delay = 20;
-		else if(idle > 50)  // start doubling the sleep after 1ms...
-			delay *= 2;
-		if(delay > 10*1000)  // up to 10ms
-			delay = 10*1000;
-		runtime·usleep(delay);
-		if(runtime·debug.schedtrace <= 0 &&
-			(runtime·sched.gcwaiting || runtime·atomicload(&runtime·sched.npidle) == runtime·gomaxprocs)) {  // TODO: fast atomic
-			runtime·lock(&runtime·sched);
-			if(runtime·atomicload(&runtime·sched.gcwaiting) || runtime·atomicload(&runtime·sched.npidle) == runtime·gomaxprocs) {
-				runtime·atomicstore(&runtime·sched.sysmonwait, 1);
-				runtime·unlock(&runtime·sched);
-				runtime·notesleep(&runtime·sched.sysmonnote);
-				runtime·noteclear(&runtime·sched.sysmonnote);
-				idle = 0;
-				delay = 20;
-			} else
-				runtime·unlock(&runtime·sched);
-		}
-		// poll network if not polled for more than 10ms
-		lastpoll = runtime·atomicload64(&runtime·sched.lastpoll);
-		now = runtime·nanotime();
-		if(lastpoll != 0 && lastpoll + 10*1000*1000 < now) {
-			runtime·cas64(&runtime·sched.lastpoll, lastpoll, now);
-			gp = runtime·netpoll(false);  // non-blocking
-			if(gp) {
-				// Need to decrement number of idle locked M's
-				// (pretending that one more is running) before injectglist.
-				// Otherwise it can lead to the following situation:
-				// injectglist grabs all P's but before it starts M's to run the P's,
-				// another M returns from syscall, finishes running its G,
-				// observes that there is no work to do and no other running M's
-				// and reports deadlock.
-				incidlelocked(-1);
-				injectglist(gp);
-				incidlelocked(1);
-			}
-		}
-		// retake P's blocked in syscalls
-		// and preempt long running G's
-		if(retake(now))
-			idle = 0;
-		else
-			idle++;
-
-		if(runtime·debug.schedtrace > 0 && lasttrace + runtime·debug.schedtrace*1000000ll <= now) {
-			lasttrace = now;
-			runtime·schedtrace(runtime·debug.scheddetail);
-		}
-	}
-}
-
-typedef struct Pdesc Pdesc;
-struct Pdesc
-{
-	uint32	schedtick;
-	int64	schedwhen;
-	uint32	syscalltick;
-	int64	syscallwhen;
-};
-#pragma dataflag NOPTR
-static Pdesc pdesc[MaxGomaxprocs];
-
-static uint32
-retake(int64 now)
-{
-	uint32 i, s, n;
-	int64 t;
-	P *p;
-	Pdesc *pd;
-
-	n = 0;
-	for(i = 0; i < runtime·gomaxprocs; i++) {
-		p = runtime·allp[i];
-		if(p==nil)
-			continue;
-		pd = &pdesc[i];
-		s = p->status;
-		if(s == Psyscall) {
-			// Retake P from syscall if it's there for more than 1 sysmon tick (at least 20us).
-			t = p->syscalltick;
-			if(pd->syscalltick != t) {
-				pd->syscalltick = t;
-				pd->syscallwhen = now;
-				continue;
-			}
-			// On the one hand we don't want to retake Ps if there is no other work to do,
-			// but on the other hand we want to retake them eventually
-			// because they can prevent the sysmon thread from deep sleep.
-			if(p->runqhead == p->runqtail &&
-				runtime·atomicload(&runtime·sched.nmspinning) + runtime·atomicload(&runtime·sched.npidle) > 0 &&
-				pd->syscallwhen + 10*1000*1000 > now)
-				continue;
-			// Need to decrement number of idle locked M's
-			// (pretending that one more is running) before the CAS.
-			// Otherwise the M from which we retake can exit the syscall,
-			// increment nmidle and report deadlock.
-			incidlelocked(-1);
-			if(runtime·cas(&p->status, s, Pidle)) {
-				n++;
-				handoffp(p);
-			}
-			incidlelocked(1);
-		} else if(s == Prunning) {
-			// Preempt G if it's running for more than 10ms.
-			t = p->schedtick;
-			if(pd->schedtick != t) {
-				pd->schedtick = t;
-				pd->schedwhen = now;
-				continue;
-			}
-			if(pd->schedwhen + 10*1000*1000 > now)
-				continue;
-			preemptone(p);
-		}
-	}
-	return n;
-}
-
-// Tell all goroutines that they have been preempted and they should stop.
-// This function is purely best-effort.  It can fail to inform a goroutine if a
-// processor just started running it.
-// No locks need to be held.
-// Returns true if preemption request was issued to at least one goroutine.
-static bool
-preemptall(void)
-{
-	P *p;
-	int32 i;
-	bool res;
-
-	res = false;
-	for(i = 0; i < runtime·gomaxprocs; i++) {
-		p = runtime·allp[i];
-		if(p == nil || p->status != Prunning)
-			continue;
-		res |= preemptone(p);
-	}
-	return res;
-}
-
-// Tell the goroutine running on processor P to stop.
-// This function is purely best-effort.  It can incorrectly fail to inform the
-// goroutine.  It can send inform the wrong goroutine.  Even if it informs the
-// correct goroutine, that goroutine might ignore the request if it is
-// simultaneously executing runtime·newstack.
-// No lock needs to be held.
-// Returns true if preemption request was issued.
-static bool
-preemptone(P *p)
-{
-	M *mp;
-	G *gp;
-
-	mp = p->m;
-	if(mp == nil || mp == m)
-		return false;
-	gp = mp->curg;
-	if(gp == nil || gp == mp->g0)
-		return false;
-	gp->preempt = true;
-	gp->stackguard0 = StackPreempt;
-	return true;
-}
-
-void
-runtime·schedtrace(bool detailed)
-{
-	static int64 starttime;
-	int64 now;
-	int64 id1, id2, id3;
-	int32 i, t, h;
-	uintptr gi;
-	int8 *fmt;
-	M *mp, *lockedm;
-	G *gp, *lockedg;
-	P *p;
-
-	now = runtime·nanotime();
-	if(starttime == 0)
-		starttime = now;
-
-	runtime·lock(&runtime·sched);
-	runtime·printf("SCHED %Dms: gomaxprocs=%d idleprocs=%d threads=%d idlethreads=%d runqueue=%d",
-		(now-starttime)/1000000, runtime·gomaxprocs, runtime·sched.npidle, runtime·sched.mcount,
-		runtime·sched.nmidle, runtime·sched.runqsize);
-	if(detailed) {
-		runtime·printf(" gcwaiting=%d nmidlelocked=%d nmspinning=%d stopwait=%d sysmonwait=%d\n",
-			runtime·sched.gcwaiting, runtime·sched.nmidlelocked, runtime·sched.nmspinning,
-			runtime·sched.stopwait, runtime·sched.sysmonwait);
-	}
-	// We must be careful while reading data from P's, M's and G's.
-	// Even if we hold schedlock, most data can be changed concurrently.
-	// E.g. (p->m ? p->m->id : -1) can crash if p->m changes from non-nil to nil.
-	for(i = 0; i < runtime·gomaxprocs; i++) {
-		p = runtime·allp[i];
-		if(p == nil)
-			continue;
-		mp = p->m;
-		h = runtime·atomicload(&p->runqhead);
-		t = runtime·atomicload(&p->runqtail);
-		if(detailed)
-			runtime·printf("  P%d: status=%d schedtick=%d syscalltick=%d m=%d runqsize=%d gfreecnt=%d\n",
-				i, p->status, p->schedtick, p->syscalltick, mp ? mp->id : -1, t-h, p->gfreecnt);
-		else {
-			// In non-detailed mode format lengths of per-P run queues as:
-			// [len1 len2 len3 len4]
-			fmt = " %d";
-			if(runtime·gomaxprocs == 1)
-				fmt = " [%d]\n";
-			else if(i == 0)
-				fmt = " [%d";
-			else if(i == runtime·gomaxprocs-1)
-				fmt = " %d]\n";
-			runtime·printf(fmt, t-h);
-		}
-	}
-	if(!detailed) {
-		runtime·unlock(&runtime·sched);
-		return;
-	}
-	for(mp = runtime·allm; mp; mp = mp->alllink) {
-		p = mp->p;
-		gp = mp->curg;
-		lockedg = mp->lockedg;
-		id1 = -1;
-		if(p)
-			id1 = p->id;
-		id2 = -1;
-		if(gp)
-			id2 = gp->goid;
-		id3 = -1;
-		if(lockedg)
-			id3 = lockedg->goid;
-		runtime·printf("  M%d: p=%D curg=%D mallocing=%d throwing=%d gcing=%d"
-			" locks=%d dying=%d helpgc=%d spinning=%d blocked=%d lockedg=%D\n",
-			mp->id, id1, id2,
-			mp->mallocing, mp->throwing, mp->gcing, mp->locks, mp->dying, mp->helpgc,
-			mp->spinning, m->blocked, id3);
-	}
-	runtime·lock(&allglock);
-	for(gi = 0; gi < runtime·allglen; gi++) {
-		gp = runtime·allg[gi];
-		mp = gp->m;
-		lockedm = gp->lockedm;
-		runtime·printf("  G%D: status=%d(%s) m=%d lockedm=%d\n",
-			gp->goid, gp->status, gp->waitreason, mp ? mp->id : -1,
-			lockedm ? lockedm->id : -1);
-	}
-	runtime·unlock(&allglock);
-	runtime·unlock(&runtime·sched);
-}
-
-// Put mp on midle list.
-// Sched must be locked.
-static void
-mput(M *mp)
-{
-	mp->schedlink = runtime·sched.midle;
-	runtime·sched.midle = mp;
-	runtime·sched.nmidle++;
-	checkdead();
-}
-
-// Try to get an m from midle list.
-// Sched must be locked.
-static M*
-mget(void)
-{
-	M *mp;
-
-	if((mp = runtime·sched.midle) != nil){
-		runtime·sched.midle = mp->schedlink;
-		runtime·sched.nmidle--;
-	}
-	return mp;
-}
-
-// Put gp on the global runnable queue.
-// Sched must be locked.
-static void
-globrunqput(G *gp)
-{
-	gp->schedlink = nil;
-	if(runtime·sched.runqtail)
-		runtime·sched.runqtail->schedlink = gp;
-	else
-		runtime·sched.runqhead = gp;
-	runtime·sched.runqtail = gp;
-	runtime·sched.runqsize++;
-}
-
-// Put a batch of runnable goroutines on the global runnable queue.
-// Sched must be locked.
-static void
-globrunqputbatch(G *ghead, G *gtail, int32 n)
-{
-	gtail->schedlink = nil;
-	if(runtime·sched.runqtail)
-		runtime·sched.runqtail->schedlink = ghead;
-	else
-		runtime·sched.runqhead = ghead;
-	runtime·sched.runqtail = gtail;
-	runtime·sched.runqsize += n;
-}
-
-// Try get a batch of G's from the global runnable queue.
-// Sched must be locked.
-static G*
-globrunqget(P *p, int32 max)
-{
-	G *gp, *gp1;
-	int32 n;
-
-	if(runtime·sched.runqsize == 0)
-		return nil;
-	n = runtime·sched.runqsize/runtime·gomaxprocs+1;
-	if(n > runtime·sched.runqsize)
-		n = runtime·sched.runqsize;
-	if(max > 0 && n > max)
-		n = max;
-	if(n > nelem(p->runq)/2)
-		n = nelem(p->runq)/2;
-	runtime·sched.runqsize -= n;
-	if(runtime·sched.runqsize == 0)
-		runtime·sched.runqtail = nil;
-	gp = runtime·sched.runqhead;
-	runtime·sched.runqhead = gp->schedlink;
-	n--;
-	while(n--) {
-		gp1 = runtime·sched.runqhead;
-		runtime·sched.runqhead = gp1->schedlink;
-		runqput(p, gp1);
-	}
-	return gp;
-}
-
-// Put p to on pidle list.
-// Sched must be locked.
-static void
-pidleput(P *p)
-{
-	p->link = runtime·sched.pidle;
-	runtime·sched.pidle = p;
-	runtime·xadd(&runtime·sched.npidle, 1);  // TODO: fast atomic
-}
-
-// Try get a p from pidle list.
-// Sched must be locked.
-static P*
-pidleget(void)
-{
-	P *p;
-
-	p = runtime·sched.pidle;
-	if(p) {
-		runtime·sched.pidle = p->link;
-		runtime·xadd(&runtime·sched.npidle, -1);  // TODO: fast atomic
-	}
-	return p;
-}
-
-// Try to put g on local runnable queue.
-// If it's full, put onto global queue.
-// Executed only by the owner P.
-static void
-runqput(P *p, G *gp)
-{
-	uint32 h, t;
-
-retry:
-	h = runtime·atomicload(&p->runqhead);  // load-acquire, synchronize with consumers
-	t = p->runqtail;
-	if(t - h < nelem(p->runq)) {
-		p->runq[t%nelem(p->runq)] = gp;
-		runtime·atomicstore(&p->runqtail, t+1);  // store-release, makes the item available for consumption
-		return;
-	}
-	if(runqputslow(p, gp, h, t))
-		return;
-	// the queue is not full, now the put above must suceed
-	goto retry;
-}
-
-// Put g and a batch of work from local runnable queue on global queue.
-// Executed only by the owner P.
-static bool
-runqputslow(P *p, G *gp, uint32 h, uint32 t)
-{
-	G *batch[nelem(p->runq)/2+1];
-	uint32 n, i;
-
-	// First, grab a batch from local queue.
-	n = t-h;
-	n = n/2;
-	if(n != nelem(p->runq)/2)
-		runtime·throw("runqputslow: queue is not full");
-	for(i=0; i<n; i++)
-		batch[i] = p->runq[(h+i)%nelem(p->runq)];
-	if(!runtime·cas(&p->runqhead, h, h+n))  // cas-release, commits consume
-		return false;
-	batch[n] = gp;
-	// Link the goroutines.
-	for(i=0; i<n; i++)
-		batch[i]->schedlink = batch[i+1];
-	// Now put the batch on global queue.
-	runtime·lock(&runtime·sched);
-	globrunqputbatch(batch[0], batch[n], n+1);
-	runtime·unlock(&runtime·sched);
-	return true;
-}
-
-// Get g from local runnable queue.
-// Executed only by the owner P.
-static G*
-runqget(P *p)
-{
-	G *gp;
-	uint32 t, h;
-
-	for(;;) {
-		h = runtime·atomicload(&p->runqhead);  // load-acquire, synchronize with other consumers
-		t = p->runqtail;
-		if(t == h)
-			return nil;
-		gp = p->runq[h%nelem(p->runq)];
-		if(runtime·cas(&p->runqhead, h, h+1))  // cas-release, commits consume
-			return gp;
-	}
-}
-
-// Grabs a batch of goroutines from local runnable queue.
-// batch array must be of size nelem(p->runq)/2. Returns number of grabbed goroutines.
-// Can be executed by any P.
-static uint32
-runqgrab(P *p, G **batch)
-{
-	uint32 t, h, n, i;
-
-	for(;;) {
-		h = runtime·atomicload(&p->runqhead);  // load-acquire, synchronize with other consumers
-		t = runtime·atomicload(&p->runqtail);  // load-acquire, synchronize with the producer
-		n = t-h;
-		n = n - n/2;
-		if(n == 0)
-			break;
-		if(n > nelem(p->runq)/2)  // read inconsistent h and t
-			continue;
-		for(i=0; i<n; i++)
-			batch[i] = p->runq[(h+i)%nelem(p->runq)];
-		if(runtime·cas(&p->runqhead, h, h+n))  // cas-release, commits consume
-			break;
-	}
-	return n;
-}
-
-// Steal half of elements from local runnable queue of p2
-// and put onto local runnable queue of p.
-// Returns one of the stolen elements (or nil if failed).
-static G*
-runqsteal(P *p, P *p2)
-{
-	G *gp;
-	G *batch[nelem(p->runq)/2];
-	uint32 t, h, n, i;
-
-	n = runqgrab(p2, batch);
-	if(n == 0)
-		return nil;
-	n--;
-	gp = batch[n];
-	if(n == 0)
-		return gp;
-	h = runtime·atomicload(&p->runqhead);  // load-acquire, synchronize with consumers
-	t = p->runqtail;
-	if(t - h + n >= nelem(p->runq))
-		runtime·throw("runqsteal: runq overflow");
-	for(i=0; i<n; i++, t++)
-		p->runq[t%nelem(p->runq)] = batch[i];
-	runtime·atomicstore(&p->runqtail, t);  // store-release, makes the item available for consumption
-	return gp;
-}
-
-void
-runtime·testSchedLocalQueue(void)
-{
-	P p;
-	G gs[nelem(p.runq)];
-	int32 i, j;
-
-	runtime·memclr((byte*)&p, sizeof(p));
-
-	for(i = 0; i < nelem(gs); i++) {
-		if(runqget(&p) != nil)
-			runtime·throw("runq is not empty initially");
-		for(j = 0; j < i; j++)
-			runqput(&p, &gs[i]);
-		for(j = 0; j < i; j++) {
-			if(runqget(&p) != &gs[i]) {
-				runtime·printf("bad element at iter %d/%d\n", i, j);
-				runtime·throw("bad element");
-			}
-		}
-		if(runqget(&p) != nil)
-			runtime·throw("runq is not empty afterwards");
-	}
-}
-
-void
-runtime·testSchedLocalQueueSteal(void)
-{
-	P p1, p2;
-	G gs[nelem(p1.runq)], *gp;
-	int32 i, j, s;
-
-	runtime·memclr((byte*)&p1, sizeof(p1));
-	runtime·memclr((byte*)&p2, sizeof(p2));
-
-	for(i = 0; i < nelem(gs); i++) {
-		for(j = 0; j < i; j++) {
-			gs[j].sig = 0;
-			runqput(&p1, &gs[j]);
-		}
-		gp = runqsteal(&p2, &p1);
-		s = 0;
-		if(gp) {
-			s++;
-			gp->sig++;
-		}
-		while(gp = runqget(&p2)) {
-			s++;
-			gp->sig++;
-		}
-		while(gp = runqget(&p1))
-			gp->sig++;
-		for(j = 0; j < i; j++) {
-			if(gs[j].sig != 1) {
-				runtime·printf("bad element %d(%d) at iter %d\n", j, gs[j].sig, i);
-				runtime·throw("bad element");
-			}
-		}
-		if(s != i/2 && s != i/2+1) {
-			runtime·printf("bad steal %d, want %d or %d, iter %d\n",
-				s, i/2, i/2+1, i);
-			runtime·throw("bad steal");
-		}
-	}
-}
-
-extern void runtime·morestack(void);
-uintptr runtime·externalthreadhandlerp;
-
-// Does f mark the top of a goroutine stack?
-bool
-runtime·topofstack(Func *f)
-{
-	return f->entry == (uintptr)runtime·goexit ||
-		f->entry == (uintptr)runtime·mstart ||
-		f->entry == (uintptr)runtime·mcall ||
-		f->entry == (uintptr)runtime·morestack ||
-		f->entry == (uintptr)runtime·lessstack ||
-		f->entry == (uintptr)_rt0_go ||
-		(runtime·externalthreadhandlerp != 0 && f->entry == runtime·externalthreadhandlerp);
-}
-
-int32
-runtime·setmaxthreads(int32 in)
-{
-	int32 out;
-
-	runtime·lock(&runtime·sched);
-	out = runtime·sched.maxmcount;
-	runtime·sched.maxmcount = in;
-	checkmcount();
-	runtime·unlock(&runtime·sched);
-	return out;
-}
-
-static int8 experiment[] = GOEXPERIMENT; // defined in zaexperiment.h
-
-static bool
-haveexperiment(int8 *name)
-{
-	int32 i, j;
-	
-	for(i=0; i<sizeof(experiment); i++) {
-		if((i == 0 || experiment[i-1] == ',') && experiment[i] == name[0]) {
-			for(j=0; name[j]; j++)
-				if(experiment[i+j] != name[j])
-					goto nomatch;
-			if(experiment[i+j] != '\0' && experiment[i+j] != ',')
-				goto nomatch;
-			return 1;
-		}
-	nomatch:;
-	}
-	return 0;
-}
diff --git a/src/pkg/runtime/proc_test.go b/src/pkg/runtime/proc_test.go
deleted file mode 100644
index 5be3551..0000000
--- a/src/pkg/runtime/proc_test.go
+++ /dev/null
@@ -1,476 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package runtime_test
-
-import (
-	"math"
-	"runtime"
-	"sync/atomic"
-	"syscall"
-	"testing"
-	"time"
-)
-
-var stop = make(chan bool, 1)
-
-func perpetuumMobile() {
-	select {
-	case <-stop:
-	default:
-		go perpetuumMobile()
-	}
-}
-
-func TestStopTheWorldDeadlock(t *testing.T) {
-	if testing.Short() {
-		t.Skip("skipping during short test")
-	}
-	maxprocs := runtime.GOMAXPROCS(3)
-	compl := make(chan bool, 2)
-	go func() {
-		for i := 0; i != 1000; i += 1 {
-			runtime.GC()
-		}
-		compl <- true
-	}()
-	go func() {
-		for i := 0; i != 1000; i += 1 {
-			runtime.GOMAXPROCS(3)
-		}
-		compl <- true
-	}()
-	go perpetuumMobile()
-	<-compl
-	<-compl
-	stop <- true
-	runtime.GOMAXPROCS(maxprocs)
-}
-
-func TestYieldProgress(t *testing.T) {
-	testYieldProgress(t, false)
-}
-
-func TestYieldLockedProgress(t *testing.T) {
-	testYieldProgress(t, true)
-}
-
-func testYieldProgress(t *testing.T, locked bool) {
-	c := make(chan bool)
-	cack := make(chan bool)
-	go func() {
-		if locked {
-			runtime.LockOSThread()
-		}
-		for {
-			select {
-			case <-c:
-				cack <- true
-				return
-			default:
-				runtime.Gosched()
-			}
-		}
-	}()
-	time.Sleep(10 * time.Millisecond)
-	c <- true
-	<-cack
-}
-
-func TestYieldLocked(t *testing.T) {
-	const N = 10
-	c := make(chan bool)
-	go func() {
-		runtime.LockOSThread()
-		for i := 0; i < N; i++ {
-			runtime.Gosched()
-			time.Sleep(time.Millisecond)
-		}
-		c <- true
-		// runtime.UnlockOSThread() is deliberately omitted
-	}()
-	<-c
-}
-
-func TestGoroutineParallelism(t *testing.T) {
-	P := 4
-	N := 10
-	if testing.Short() {
-		P = 3
-		N = 3
-	}
-	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(P))
-	for try := 0; try < N; try++ {
-		done := make(chan bool)
-		x := uint32(0)
-		for p := 0; p < P; p++ {
-			// Test that all P goroutines are scheduled at the same time
-			go func(p int) {
-				for i := 0; i < 3; i++ {
-					expected := uint32(P*i + p)
-					for atomic.LoadUint32(&x) != expected {
-					}
-					atomic.StoreUint32(&x, expected+1)
-				}
-				done <- true
-			}(p)
-		}
-		for p := 0; p < P; p++ {
-			<-done
-		}
-	}
-}
-
-func TestBlockLocked(t *testing.T) {
-	const N = 10
-	c := make(chan bool)
-	go func() {
-		runtime.LockOSThread()
-		for i := 0; i < N; i++ {
-			c <- true
-		}
-		runtime.UnlockOSThread()
-	}()
-	for i := 0; i < N; i++ {
-		<-c
-	}
-}
-
-func TestTimerFairness(t *testing.T) {
-	done := make(chan bool)
-	c := make(chan bool)
-	for i := 0; i < 2; i++ {
-		go func() {
-			for {
-				select {
-				case c <- true:
-				case <-done:
-					return
-				}
-			}
-		}()
-	}
-
-	timer := time.After(20 * time.Millisecond)
-	for {
-		select {
-		case <-c:
-		case <-timer:
-			close(done)
-			return
-		}
-	}
-}
-
-func TestTimerFairness2(t *testing.T) {
-	done := make(chan bool)
-	c := make(chan bool)
-	for i := 0; i < 2; i++ {
-		go func() {
-			timer := time.After(20 * time.Millisecond)
-			var buf [1]byte
-			for {
-				syscall.Read(0, buf[0:0])
-				select {
-				case c <- true:
-				case <-c:
-				case <-timer:
-					done <- true
-					return
-				}
-			}
-		}()
-	}
-	<-done
-	<-done
-}
-
-// The function is used to test preemption at split stack checks.
-// Declaring a var avoids inlining at the call site.
-var preempt = func() int {
-	var a [128]int
-	sum := 0
-	for _, v := range a {
-		sum += v
-	}
-	return sum
-}
-
-func TestPreemption(t *testing.T) {
-	// Test that goroutines are preempted at function calls.
-	N := 5
-	if testing.Short() {
-		N = 2
-	}
-	c := make(chan bool)
-	var x uint32
-	for g := 0; g < 2; g++ {
-		go func(g int) {
-			for i := 0; i < N; i++ {
-				for atomic.LoadUint32(&x) != uint32(g) {
-					preempt()
-				}
-				atomic.StoreUint32(&x, uint32(1-g))
-			}
-			c <- true
-		}(g)
-	}
-	<-c
-	<-c
-}
-
-func TestPreemptionGC(t *testing.T) {
-	// Test that pending GC preempts running goroutines.
-	P := 5
-	N := 10
-	if testing.Short() {
-		P = 3
-		N = 2
-	}
-	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(P + 1))
-	var stop uint32
-	for i := 0; i < P; i++ {
-		go func() {
-			for atomic.LoadUint32(&stop) == 0 {
-				preempt()
-			}
-		}()
-	}
-	for i := 0; i < N; i++ {
-		runtime.Gosched()
-		runtime.GC()
-	}
-	atomic.StoreUint32(&stop, 1)
-}
-
-func TestGCFairness(t *testing.T) {
-	output := executeTest(t, testGCFairnessSource, nil)
-	want := "OK\n"
-	if output != want {
-		t.Fatalf("want %s, got %s\n", want, output)
-	}
-}
-
-const testGCFairnessSource = `
-package main
-
-import (
-	"fmt"
-	"os"
-	"runtime"
-	"time"
-)
-
-func main() {
-	runtime.GOMAXPROCS(1)
-	f, err := os.Open("/dev/null")
-	if os.IsNotExist(err) {
-		// This test tests what it is intended to test only if writes are fast.
-		// If there is no /dev/null, we just don't execute the test.
-		fmt.Println("OK")
-		return
-	}
-	if err != nil {
-		fmt.Println(err)
-		os.Exit(1)
-	}
-	for i := 0; i < 2; i++ {
-		go func() {
-			for {
-				f.Write([]byte("."))
-			}
-		}()
-	}
-	time.Sleep(10 * time.Millisecond)
-	fmt.Println("OK")
-}
-`
-
-func stackGrowthRecursive(i int) {
-	var pad [128]uint64
-	if i != 0 && pad[0] == 0 {
-		stackGrowthRecursive(i - 1)
-	}
-}
-
-func TestPreemptSplitBig(t *testing.T) {
-	if testing.Short() {
-		t.Skip("skipping in -short mode")
-	}
-	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(2))
-	stop := make(chan int)
-	go big(stop)
-	for i := 0; i < 3; i++ {
-		time.Sleep(10 * time.Microsecond) // let big start running
-		runtime.GC()
-	}
-	close(stop)
-}
-
-func big(stop chan int) int {
-	n := 0
-	for {
-		// delay so that gc is sure to have asked for a preemption
-		for i := 0; i < 1e9; i++ {
-			n++
-		}
-
-		// call bigframe, which used to miss the preemption in its prologue.
-		bigframe(stop)
-
-		// check if we've been asked to stop.
-		select {
-		case <-stop:
-			return n
-		}
-	}
-}
-
-func bigframe(stop chan int) int {
-	// not splitting the stack will overflow.
-	// small will notice that it needs a stack split and will
-	// catch the overflow.
-	var x [8192]byte
-	return small(stop, &x)
-}
-
-func small(stop chan int, x *[8192]byte) int {
-	for i := range x {
-		x[i] = byte(i)
-	}
-	sum := 0
-	for i := range x {
-		sum += int(x[i])
-	}
-
-	// keep small from being a leaf function, which might
-	// make it not do any stack check at all.
-	nonleaf(stop)
-
-	return sum
-}
-
-func nonleaf(stop chan int) bool {
-	// do something that won't be inlined:
-	select {
-	case <-stop:
-		return true
-	default:
-		return false
-	}
-}
-
-func TestSchedLocalQueue(t *testing.T) {
-	runtime.TestSchedLocalQueue1()
-}
-
-func TestSchedLocalQueueSteal(t *testing.T) {
-	runtime.TestSchedLocalQueueSteal1()
-}
-
-func benchmarkStackGrowth(b *testing.B, rec int) {
-	b.RunParallel(func(pb *testing.PB) {
-		for pb.Next() {
-			stackGrowthRecursive(rec)
-		}
-	})
-}
-
-func BenchmarkStackGrowth(b *testing.B) {
-	benchmarkStackGrowth(b, 10)
-}
-
-func BenchmarkStackGrowthDeep(b *testing.B) {
-	benchmarkStackGrowth(b, 1024)
-}
-
-func BenchmarkCreateGoroutines(b *testing.B) {
-	benchmarkCreateGoroutines(b, 1)
-}
-
-func BenchmarkCreateGoroutinesParallel(b *testing.B) {
-	benchmarkCreateGoroutines(b, runtime.GOMAXPROCS(-1))
-}
-
-func benchmarkCreateGoroutines(b *testing.B, procs int) {
-	c := make(chan bool)
-	var f func(n int)
-	f = func(n int) {
-		if n == 0 {
-			c <- true
-			return
-		}
-		go f(n - 1)
-	}
-	for i := 0; i < procs; i++ {
-		go f(b.N / procs)
-	}
-	for i := 0; i < procs; i++ {
-		<-c
-	}
-}
-
-type Matrix [][]float64
-
-func BenchmarkMatmult(b *testing.B) {
-	b.StopTimer()
-	// matmult is O(N**3) but testing expects O(b.N),
-	// so we need to take cube root of b.N
-	n := int(math.Cbrt(float64(b.N))) + 1
-	A := makeMatrix(n)
-	B := makeMatrix(n)
-	C := makeMatrix(n)
-	b.StartTimer()
-	matmult(nil, A, B, C, 0, n, 0, n, 0, n, 8)
-}
-
-func makeMatrix(n int) Matrix {
-	m := make(Matrix, n)
-	for i := 0; i < n; i++ {
-		m[i] = make([]float64, n)
-		for j := 0; j < n; j++ {
-			m[i][j] = float64(i*n + j)
-		}
-	}
-	return m
-}
-
-func matmult(done chan<- struct{}, A, B, C Matrix, i0, i1, j0, j1, k0, k1, threshold int) {
-	di := i1 - i0
-	dj := j1 - j0
-	dk := k1 - k0
-	if di >= dj && di >= dk && di >= threshold {
-		// divide in two by y axis
-		mi := i0 + di/2
-		done1 := make(chan struct{}, 1)
-		go matmult(done1, A, B, C, i0, mi, j0, j1, k0, k1, threshold)
-		matmult(nil, A, B, C, mi, i1, j0, j1, k0, k1, threshold)
-		<-done1
-	} else if dj >= dk && dj >= threshold {
-		// divide in two by x axis
-		mj := j0 + dj/2
-		done1 := make(chan struct{}, 1)
-		go matmult(done1, A, B, C, i0, i1, j0, mj, k0, k1, threshold)
-		matmult(nil, A, B, C, i0, i1, mj, j1, k0, k1, threshold)
-		<-done1
-	} else if dk >= threshold {
-		// divide in two by "k" axis
-		// deliberately not parallel because of data races
-		mk := k0 + dk/2
-		matmult(nil, A, B, C, i0, i1, j0, j1, k0, mk, threshold)
-		matmult(nil, A, B, C, i0, i1, j0, j1, mk, k1, threshold)
-	} else {
-		// the matrices are small enough, compute directly
-		for i := i0; i < i1; i++ {
-			for j := j0; j < j1; j++ {
-				for k := k0; k < k1; k++ {
-					C[i][j] += A[i][k] * B[k][j]
-				}
-			}
-		}
-	}
-	if done != nil {
-		done <- struct{}{}
-	}
-}
diff --git a/src/pkg/runtime/race.c b/src/pkg/runtime/race.c
deleted file mode 100644
index eb0be7f..0000000
--- a/src/pkg/runtime/race.c
+++ /dev/null
@@ -1,292 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Implementation of the race detector API.
-// +build race
-
-#include "runtime.h"
-#include "arch_GOARCH.h"
-#include "malloc.h"
-#include "race.h"
-#include "type.h"
-#include "typekind.h"
-
-// Race runtime functions called via runtime·racecall.
-void __tsan_init(void);
-void __tsan_fini(void);
-void __tsan_map_shadow(void);
-void __tsan_finalizer_goroutine(void);
-void __tsan_go_start(void);
-void __tsan_go_end(void);
-void __tsan_malloc(void);
-void __tsan_acquire(void);
-void __tsan_release(void);
-void __tsan_release_merge(void);
-
-// Mimic what cmd/cgo would do.
-#pragma cgo_import_static __tsan_init
-#pragma cgo_import_static __tsan_fini
-#pragma cgo_import_static __tsan_map_shadow
-#pragma cgo_import_static __tsan_finalizer_goroutine
-#pragma cgo_import_static __tsan_go_start
-#pragma cgo_import_static __tsan_go_end
-#pragma cgo_import_static __tsan_malloc
-#pragma cgo_import_static __tsan_acquire
-#pragma cgo_import_static __tsan_release
-#pragma cgo_import_static __tsan_release_merge
-
-// These are called from race_amd64.s.
-#pragma cgo_import_static __tsan_read
-#pragma cgo_import_static __tsan_read_pc
-#pragma cgo_import_static __tsan_read_range
-#pragma cgo_import_static __tsan_write
-#pragma cgo_import_static __tsan_write_pc
-#pragma cgo_import_static __tsan_write_range
-#pragma cgo_import_static __tsan_func_enter
-#pragma cgo_import_static __tsan_func_exit
-
-extern byte noptrdata[];
-extern byte enoptrbss[];
-  
-// start/end of heap for race_amd64.s
-uintptr runtime·racearenastart;
-uintptr runtime·racearenaend;
-
-void runtime·racefuncenter(void *callpc);
-void runtime·racefuncexit(void);
-void runtime·racereadrangepc1(void *addr, uintptr sz, void *pc);
-void runtime·racewriterangepc1(void *addr, uintptr sz, void *pc);
-void runtime·racesymbolizethunk(void*);
-
-// racecall allows calling an arbitrary function f from C race runtime
-// with up to 4 uintptr arguments.
-void runtime·racecall(void(*f)(void), ...);
-
-uintptr
-runtime·raceinit(void)
-{
-	uintptr racectx, start, size;
-
-	// cgo is required to initialize libc, which is used by race runtime
-	if(!runtime·iscgo)
-		runtime·throw("raceinit: race build must use cgo");
-	runtime·racecall(__tsan_init, &racectx, runtime·racesymbolizethunk);
-	// Round data segment to page boundaries, because it's used in mmap().
-	start = (uintptr)noptrdata & ~(PageSize-1);
-	size = ROUND((uintptr)enoptrbss - start, PageSize);
-	runtime·racecall(__tsan_map_shadow, start, size);
-	return racectx;
-}
-
-void
-runtime·racefini(void)
-{
-	runtime·racecall(__tsan_fini);
-}
-
-void
-runtime·racemapshadow(void *addr, uintptr size)
-{
-	if(runtime·racearenastart == 0)
-		runtime·racearenastart = (uintptr)addr;
-	if(runtime·racearenaend < (uintptr)addr+size)
-		runtime·racearenaend = (uintptr)addr+size;
-	runtime·racecall(__tsan_map_shadow, addr, size);
-}
-
-void
-runtime·racemalloc(void *p, uintptr sz)
-{
-	runtime·racecall(__tsan_malloc, p, sz);
-}
-
-uintptr
-runtime·racegostart(void *pc)
-{
-	uintptr racectx;
-
-	runtime·racecall(__tsan_go_start, g->racectx, &racectx, pc);
-	return racectx;
-}
-
-void
-runtime·racegoend(void)
-{
-	runtime·racecall(__tsan_go_end, g->racectx);
-}
-
-void
-runtime·racewriterangepc(void *addr, uintptr sz, void *callpc, void *pc)
-{
-	if(callpc != nil)
-		runtime·racefuncenter(callpc);
-	runtime·racewriterangepc1(addr, sz, pc);
-	if(callpc != nil)
-		runtime·racefuncexit();
-}
-
-void
-runtime·racereadrangepc(void *addr, uintptr sz, void *callpc, void *pc)
-{
-	if(callpc != nil)
-		runtime·racefuncenter(callpc);
-	runtime·racereadrangepc1(addr, sz, pc);
-	if(callpc != nil)
-		runtime·racefuncexit();
-}
-
-void
-runtime·racewriteobjectpc(void *addr, Type *t, void *callpc, void *pc)
-{
-	uint8 kind;
-
-	kind = t->kind & ~KindNoPointers;
-	if(kind == KindArray || kind == KindStruct)
-		runtime·racewriterangepc(addr, t->size, callpc, pc);
-	else
-		runtime·racewritepc(addr, callpc, pc);
-}
-
-void
-runtime·racereadobjectpc(void *addr, Type *t, void *callpc, void *pc)
-{
-	uint8 kind;
-
-	kind = t->kind & ~KindNoPointers;
-	if(kind == KindArray || kind == KindStruct)
-		runtime·racereadrangepc(addr, t->size, callpc, pc);
-	else
-		runtime·racereadpc(addr, callpc, pc);
-}
-
-void
-runtime·raceacquire(void *addr)
-{
-	runtime·raceacquireg(g, addr);
-}
-
-void
-runtime·raceacquireg(G *gp, void *addr)
-{
-	if(g->raceignore)
-		return;
-	runtime·racecall(__tsan_acquire, gp->racectx, addr);
-}
-
-void
-runtime·racerelease(void *addr)
-{
-	runtime·racereleaseg(g, addr);
-}
-
-void
-runtime·racereleaseg(G *gp, void *addr)
-{
-	if(g->raceignore)
-		return;
-	runtime·racecall(__tsan_release, gp->racectx, addr);
-}
-
-void
-runtime·racereleasemerge(void *addr)
-{
-	runtime·racereleasemergeg(g, addr);
-}
-
-void
-runtime·racereleasemergeg(G *gp, void *addr)
-{
-	if(g->raceignore)
-		return;
-	runtime·racecall(__tsan_release_merge, gp->racectx, addr);
-}
-
-void
-runtime·racefingo(void)
-{
-	runtime·racecall(__tsan_finalizer_goroutine, g->racectx);
-}
-
-// func RaceAcquire(addr unsafe.Pointer)
-void
-runtime·RaceAcquire(void *addr)
-{
-	runtime·raceacquire(addr);
-}
-
-// func RaceRelease(addr unsafe.Pointer)
-void
-runtime·RaceRelease(void *addr)
-{
-	runtime·racerelease(addr);
-}
-
-// func RaceReleaseMerge(addr unsafe.Pointer)
-void
-runtime·RaceReleaseMerge(void *addr)
-{
-	runtime·racereleasemerge(addr);
-}
-
-// func RaceSemacquire(s *uint32)
-void
-runtime·RaceSemacquire(uint32 *s)
-{
-	runtime·semacquire(s, false);
-}
-
-// func RaceSemrelease(s *uint32)
-void
-runtime·RaceSemrelease(uint32 *s)
-{
-	runtime·semrelease(s);
-}
-
-// func RaceDisable()
-void
-runtime·RaceDisable(void)
-{
-	g->raceignore++;
-}
-
-// func RaceEnable()
-void
-runtime·RaceEnable(void)
-{
-	g->raceignore--;
-}
-
-typedef struct SymbolizeContext SymbolizeContext;
-struct SymbolizeContext
-{
-	uintptr	pc;
-	int8*	func;
-	int8*	file;
-	uintptr	line;
-	uintptr	off;
-	uintptr	res;
-};
-
-// Callback from C into Go, runs on g0.
-void
-runtime·racesymbolize(SymbolizeContext *ctx)
-{
-	Func *f;
-	String file;
-
-	f = runtime·findfunc(ctx->pc);
-	if(f == nil) {
-		ctx->func = "??";
-		ctx->file = "-";
-		ctx->line = 0;
-		ctx->off = ctx->pc;
-		ctx->res = 1;
-		return;
-	}
-	ctx->func = runtime·funcname(f);
-	ctx->line = runtime·funcline(f, ctx->pc, &file);
-	ctx->file = (int8*)file.str;  // assume zero-terminated
-	ctx->off = ctx->pc - f->entry;
-	ctx->res = 1;
-}
diff --git a/src/pkg/runtime/race.go b/src/pkg/runtime/race.go
deleted file mode 100644
index 2a9124d..0000000
--- a/src/pkg/runtime/race.go
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2012 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build race
-
-// Public race detection API, present iff build with -race.
-
-package runtime
-
-import (
-	"unsafe"
-)
-
-// RaceDisable disables handling of race events in the current goroutine.
-func RaceDisable()
-
-// RaceEnable re-enables handling of race events in the current goroutine.
-func RaceEnable()
-
-func RaceAcquire(addr unsafe.Pointer)
-func RaceRelease(addr unsafe.Pointer)
-func RaceReleaseMerge(addr unsafe.Pointer)
-
-func RaceRead(addr unsafe.Pointer)
-func RaceWrite(addr unsafe.Pointer)
-func RaceReadRange(addr unsafe.Pointer, len int)
-func RaceWriteRange(addr unsafe.Pointer, len int)
-
-func RaceSemacquire(s *uint32)
-func RaceSemrelease(s *uint32)
diff --git a/src/pkg/runtime/race/README b/src/pkg/runtime/race/README
deleted file mode 100644
index 7856406..0000000
--- a/src/pkg/runtime/race/README
+++ /dev/null
@@ -1,12 +0,0 @@
-runtime/race package contains the data race detector runtime library.
-It is based on ThreadSanitizer race detector, that is currently a part of
-the LLVM project.
-
-To update the .syso files you need to:
-$ svn co http://llvm.org/svn/llvm-project/compiler-rt/trunk
-$ cd compiler-rt/lib/tsan/go
-$ ./buildgo.sh
-
-Tested with gcc 4.6.1 and 4.7.0.  On Windows it's built with 64-bit MinGW.
-
-Current runtime is built on rev 203116.
diff --git a/src/pkg/runtime/race/race.go b/src/pkg/runtime/race/race.go
deleted file mode 100644
index e53cacf..0000000
--- a/src/pkg/runtime/race/race.go
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build race,linux,amd64 race,darwin,amd64 race,windows,amd64
-
-package race
-
-// This file merely ensures that we link in runtime/cgo in race build,
-// this is turn ensures that runtime uses pthread_create to create threads.
-// The prebuilt race runtime lives in race_GOOS_GOARCH.syso.
-// Calls to the runtime are done directly from src/pkg/runtime/race.c.
-
-// void __race_unused_func(void);
-import "C"
diff --git a/src/pkg/runtime/race/race_darwin_amd64.syso b/src/pkg/runtime/race/race_darwin_amd64.syso
deleted file mode 100644
index 249a878..0000000
Binary files a/src/pkg/runtime/race/race_darwin_amd64.syso and /dev/null differ
diff --git a/src/pkg/runtime/race/race_linux_amd64.syso b/src/pkg/runtime/race/race_linux_amd64.syso
deleted file mode 100644
index 8120484..0000000
Binary files a/src/pkg/runtime/race/race_linux_amd64.syso and /dev/null differ
diff --git a/src/pkg/runtime/race/race_windows_amd64.syso b/src/pkg/runtime/race/race_windows_amd64.syso
deleted file mode 100644
index 67db40f..0000000
Binary files a/src/pkg/runtime/race/race_windows_amd64.syso and /dev/null differ
diff --git a/src/pkg/runtime/race/testdata/atomic_test.go b/src/pkg/runtime/race/testdata/atomic_test.go
deleted file mode 100644
index fc569b9..0000000
--- a/src/pkg/runtime/race/testdata/atomic_test.go
+++ /dev/null
@@ -1,290 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package race_test
-
-import (
-	"runtime"
-	"sync"
-	"sync/atomic"
-	"testing"
-	"unsafe"
-)
-
-func TestNoRaceAtomicAddInt64(t *testing.T) {
-	var x1, x2 int8
-	var s int64
-	ch := make(chan bool, 2)
-	go func() {
-		x1 = 1
-		if atomic.AddInt64(&s, 1) == 2 {
-			x2 = 1
-		}
-		ch <- true
-	}()
-	go func() {
-		x2 = 1
-		if atomic.AddInt64(&s, 1) == 2 {
-			x1 = 1
-		}
-		ch <- true
-	}()
-	<-ch
-	<-ch
-}
-
-func TestRaceAtomicAddInt64(t *testing.T) {
-	var x1, x2 int8
-	var s int64
-	ch := make(chan bool, 2)
-	go func() {
-		x1 = 1
-		if atomic.AddInt64(&s, 1) == 1 {
-			x2 = 1
-		}
-		ch <- true
-	}()
-	go func() {
-		x2 = 1
-		if atomic.AddInt64(&s, 1) == 1 {
-			x1 = 1
-		}
-		ch <- true
-	}()
-	<-ch
-	<-ch
-}
-
-func TestNoRaceAtomicAddInt32(t *testing.T) {
-	var x1, x2 int8
-	var s int32
-	ch := make(chan bool, 2)
-	go func() {
-		x1 = 1
-		if atomic.AddInt32(&s, 1) == 2 {
-			x2 = 1
-		}
-		ch <- true
-	}()
-	go func() {
-		x2 = 1
-		if atomic.AddInt32(&s, 1) == 2 {
-			x1 = 1
-		}
-		ch <- true
-	}()
-	<-ch
-	<-ch
-}
-
-func TestNoRaceAtomicLoadAddInt32(t *testing.T) {
-	var x int64
-	var s int32
-	go func() {
-		x = 2
-		atomic.AddInt32(&s, 1)
-	}()
-	for atomic.LoadInt32(&s) != 1 {
-		runtime.Gosched()
-	}
-	x = 1
-}
-
-func TestNoRaceAtomicLoadStoreInt32(t *testing.T) {
-	var x int64
-	var s int32
-	go func() {
-		x = 2
-		atomic.StoreInt32(&s, 1)
-	}()
-	for atomic.LoadInt32(&s) != 1 {
-		runtime.Gosched()
-	}
-	x = 1
-}
-
-func TestNoRaceAtomicStoreCASInt32(t *testing.T) {
-	var x int64
-	var s int32
-	go func() {
-		x = 2
-		atomic.StoreInt32(&s, 1)
-	}()
-	for !atomic.CompareAndSwapInt32(&s, 1, 0) {
-		runtime.Gosched()
-	}
-	x = 1
-}
-
-func TestNoRaceAtomicCASLoadInt32(t *testing.T) {
-	var x int64
-	var s int32
-	go func() {
-		x = 2
-		if !atomic.CompareAndSwapInt32(&s, 0, 1) {
-			panic("")
-		}
-	}()
-	for atomic.LoadInt32(&s) != 1 {
-		runtime.Gosched()
-	}
-	x = 1
-}
-
-func TestNoRaceAtomicCASCASInt32(t *testing.T) {
-	var x int64
-	var s int32
-	go func() {
-		x = 2
-		if !atomic.CompareAndSwapInt32(&s, 0, 1) {
-			panic("")
-		}
-	}()
-	for !atomic.CompareAndSwapInt32(&s, 1, 0) {
-		runtime.Gosched()
-	}
-	x = 1
-}
-
-func TestNoRaceAtomicCASCASInt32_2(t *testing.T) {
-	var x1, x2 int8
-	var s int32
-	ch := make(chan bool, 2)
-	go func() {
-		x1 = 1
-		if !atomic.CompareAndSwapInt32(&s, 0, 1) {
-			x2 = 1
-		}
-		ch <- true
-	}()
-	go func() {
-		x2 = 1
-		if !atomic.CompareAndSwapInt32(&s, 0, 1) {
-			x1 = 1
-		}
-		ch <- true
-	}()
-	<-ch
-	<-ch
-}
-
-func TestNoRaceAtomicLoadInt64(t *testing.T) {
-	var x int32
-	var s int64
-	go func() {
-		x = 2
-		atomic.AddInt64(&s, 1)
-	}()
-	for atomic.LoadInt64(&s) != 1 {
-		runtime.Gosched()
-	}
-	x = 1
-}
-
-func TestNoRaceAtomicCASCASUInt64(t *testing.T) {
-	var x int64
-	var s uint64
-	go func() {
-		x = 2
-		if !atomic.CompareAndSwapUint64(&s, 0, 1) {
-			panic("")
-		}
-	}()
-	for !atomic.CompareAndSwapUint64(&s, 1, 0) {
-		runtime.Gosched()
-	}
-	x = 1
-}
-
-func TestNoRaceAtomicLoadStorePointer(t *testing.T) {
-	var x int64
-	var s unsafe.Pointer
-	var y int = 2
-	var p unsafe.Pointer = unsafe.Pointer(&y)
-	go func() {
-		x = 2
-		atomic.StorePointer(&s, p)
-	}()
-	for atomic.LoadPointer(&s) != p {
-		runtime.Gosched()
-	}
-	x = 1
-}
-
-func TestNoRaceAtomicStoreCASUint64(t *testing.T) {
-	var x int64
-	var s uint64
-	go func() {
-		x = 2
-		atomic.StoreUint64(&s, 1)
-	}()
-	for !atomic.CompareAndSwapUint64(&s, 1, 0) {
-		runtime.Gosched()
-	}
-	x = 1
-}
-
-// Races with non-atomic loads are not detected.
-func TestRaceFailingAtomicStoreLoad(t *testing.T) {
-	c := make(chan bool)
-	var a uint64
-	go func() {
-		atomic.StoreUint64(&a, 1)
-		c <- true
-	}()
-	_ = a
-	<-c
-}
-
-func TestRaceAtomicLoadStore(t *testing.T) {
-	c := make(chan bool)
-	var a uint64
-	go func() {
-		_ = atomic.LoadUint64(&a)
-		c <- true
-	}()
-	a = 1
-	<-c
-}
-
-// Races with non-atomic loads are not detected.
-func TestRaceFailingAtomicAddLoad(t *testing.T) {
-	c := make(chan bool)
-	var a uint64
-	go func() {
-		atomic.AddUint64(&a, 1)
-		c <- true
-	}()
-	_ = a
-	<-c
-}
-
-func TestRaceAtomicAddStore(t *testing.T) {
-	c := make(chan bool)
-	var a uint64
-	go func() {
-		atomic.AddUint64(&a, 1)
-		c <- true
-	}()
-	a = 42
-	<-c
-}
-
-// A nil pointer in an atomic operation should not deadlock
-// the rest of the program. Used to hang indefinitely.
-func TestNoRaceAtomicCrash(t *testing.T) {
-	var mutex sync.Mutex
-	var nilptr *int32
-	panics := 0
-	defer func() {
-		if x := recover(); x != nil {
-			mutex.Lock()
-			panics++
-			mutex.Unlock()
-		} else {
-			panic("no panic")
-		}
-	}()
-	atomic.AddInt32(nilptr, 1)
-}
diff --git a/src/pkg/runtime/race/testdata/chan_test.go b/src/pkg/runtime/race/testdata/chan_test.go
deleted file mode 100644
index 4a3d529..0000000
--- a/src/pkg/runtime/race/testdata/chan_test.go
+++ /dev/null
@@ -1,659 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package race_test
-
-import (
-	"runtime"
-	"testing"
-	"time"
-)
-
-func TestNoRaceChanSync(t *testing.T) {
-	v := 0
-	c := make(chan int)
-	go func() {
-		v = 1
-		c <- 0
-	}()
-	<-c
-	v = 2
-}
-
-func TestNoRaceChanSyncRev(t *testing.T) {
-	v := 0
-	c := make(chan int)
-	go func() {
-		c <- 0
-		v = 2
-	}()
-	v = 1
-	<-c
-}
-
-func TestNoRaceChanAsync(t *testing.T) {
-	v := 0
-	c := make(chan int, 10)
-	go func() {
-		v = 1
-		c <- 0
-	}()
-	<-c
-	v = 2
-}
-
-func TestRaceChanAsyncRev(t *testing.T) {
-	v := 0
-	c := make(chan int, 10)
-	go func() {
-		c <- 0
-		v = 1
-	}()
-	v = 2
-	<-c
-}
-
-func TestNoRaceChanAsyncCloseRecv(t *testing.T) {
-	v := 0
-	c := make(chan int, 10)
-	go func() {
-		v = 1
-		close(c)
-	}()
-	func() {
-		defer func() {
-			recover()
-			v = 2
-		}()
-		<-c
-	}()
-}
-
-func TestNoRaceChanAsyncCloseRecv2(t *testing.T) {
-	v := 0
-	c := make(chan int, 10)
-	go func() {
-		v = 1
-		close(c)
-	}()
-	_, _ = <-c
-	v = 2
-}
-
-func TestNoRaceChanAsyncCloseRecv3(t *testing.T) {
-	v := 0
-	c := make(chan int, 10)
-	go func() {
-		v = 1
-		close(c)
-	}()
-	for _ = range c {
-	}
-	v = 2
-}
-
-func TestNoRaceChanSyncCloseRecv(t *testing.T) {
-	v := 0
-	c := make(chan int)
-	go func() {
-		v = 1
-		close(c)
-	}()
-	func() {
-		defer func() {
-			recover()
-			v = 2
-		}()
-		<-c
-	}()
-}
-
-func TestNoRaceChanSyncCloseRecv2(t *testing.T) {
-	v := 0
-	c := make(chan int)
-	go func() {
-		v = 1
-		close(c)
-	}()
-	_, _ = <-c
-	v = 2
-}
-
-func TestNoRaceChanSyncCloseRecv3(t *testing.T) {
-	v := 0
-	c := make(chan int)
-	go func() {
-		v = 1
-		close(c)
-	}()
-	for _ = range c {
-	}
-	v = 2
-}
-
-func TestRaceChanSyncCloseSend(t *testing.T) {
-	v := 0
-	c := make(chan int)
-	go func() {
-		v = 1
-		close(c)
-	}()
-	func() {
-		defer func() {
-			recover()
-		}()
-		c <- 0
-	}()
-	v = 2
-}
-
-func TestRaceChanAsyncCloseSend(t *testing.T) {
-	v := 0
-	c := make(chan int, 10)
-	go func() {
-		v = 1
-		close(c)
-	}()
-	func() {
-		defer func() {
-			recover()
-		}()
-		for {
-			c <- 0
-		}
-	}()
-	v = 2
-}
-
-func TestRaceChanCloseClose(t *testing.T) {
-	compl := make(chan bool, 2)
-	v1 := 0
-	v2 := 0
-	c := make(chan int)
-	go func() {
-		defer func() {
-			if recover() != nil {
-				v2 = 2
-			}
-			compl <- true
-		}()
-		v1 = 1
-		close(c)
-	}()
-	go func() {
-		defer func() {
-			if recover() != nil {
-				v1 = 2
-			}
-			compl <- true
-		}()
-		v2 = 1
-		close(c)
-	}()
-	<-compl
-	<-compl
-}
-
-func TestRaceChanSendLen(t *testing.T) {
-	v := 0
-	c := make(chan int, 10)
-	go func() {
-		v = 1
-		c <- 1
-	}()
-	for len(c) == 0 {
-		runtime.Gosched()
-	}
-	v = 2
-}
-
-func TestRaceChanRecvLen(t *testing.T) {
-	v := 0
-	c := make(chan int, 10)
-	c <- 1
-	go func() {
-		v = 1
-		<-c
-	}()
-	for len(c) != 0 {
-		runtime.Gosched()
-	}
-	v = 2
-}
-
-func TestRaceChanSendSend(t *testing.T) {
-	compl := make(chan bool, 2)
-	v1 := 0
-	v2 := 0
-	c := make(chan int, 1)
-	go func() {
-		v1 = 1
-		select {
-		case c <- 1:
-		default:
-			v2 = 2
-		}
-		compl <- true
-	}()
-	go func() {
-		v2 = 1
-		select {
-		case c <- 1:
-		default:
-			v1 = 2
-		}
-		compl <- true
-	}()
-	<-compl
-	<-compl
-}
-
-func TestNoRaceChanPtr(t *testing.T) {
-	type msg struct {
-		x int
-	}
-	c := make(chan *msg)
-	go func() {
-		c <- &msg{1}
-	}()
-	m := <-c
-	m.x = 2
-}
-
-func TestRaceChanWrongSend(t *testing.T) {
-	v1 := 0
-	v2 := 0
-	c := make(chan int, 2)
-	go func() {
-		v1 = 1
-		c <- 1
-	}()
-	go func() {
-		v2 = 2
-		c <- 2
-	}()
-	time.Sleep(1e7)
-	if <-c == 1 {
-		v2 = 3
-	} else {
-		v1 = 3
-	}
-}
-
-func TestRaceChanWrongClose(t *testing.T) {
-	v1 := 0
-	v2 := 0
-	c := make(chan int, 1)
-	go func() {
-		defer func() {
-			recover()
-		}()
-		v1 = 1
-		c <- 1
-	}()
-	go func() {
-		time.Sleep(1e7)
-		v2 = 2
-		close(c)
-	}()
-	time.Sleep(2e7)
-	if _, who := <-c; who {
-		v2 = 2
-	} else {
-		v1 = 2
-	}
-}
-
-func TestRaceChanSendClose(t *testing.T) {
-	compl := make(chan bool, 2)
-	c := make(chan int, 1)
-	go func() {
-		defer func() {
-			recover()
-			compl <- true
-		}()
-		c <- 1
-	}()
-	go func() {
-		time.Sleep(10 * time.Millisecond)
-		close(c)
-		compl <- true
-	}()
-	<-compl
-	<-compl
-}
-
-func TestRaceChanSendSelectClose(t *testing.T) {
-	compl := make(chan bool, 2)
-	c := make(chan int, 1)
-	c1 := make(chan int)
-	go func() {
-		defer func() {
-			recover()
-			compl <- true
-		}()
-		time.Sleep(10 * time.Millisecond)
-		select {
-		case c <- 1:
-		case <-c1:
-		}
-	}()
-	go func() {
-		close(c)
-		compl <- true
-	}()
-	<-compl
-	<-compl
-}
-
-func TestRaceSelectReadWriteAsync(t *testing.T) {
-	done := make(chan bool)
-	x := 0
-	c1 := make(chan int, 10)
-	c2 := make(chan int, 10)
-	c3 := make(chan int)
-	c2 <- 1
-	go func() {
-		select {
-		case c1 <- x: // read of x races with...
-		case c3 <- 1:
-		}
-		done <- true
-	}()
-	select {
-	case x = <-c2: // ... write to x here
-	case c3 <- 1:
-	}
-	<-done
-}
-
-func TestRaceSelectReadWriteSync(t *testing.T) {
-	done := make(chan bool)
-	x := 0
-	c1 := make(chan int)
-	c2 := make(chan int)
-	c3 := make(chan int)
-	// make c1 and c2 ready for communication
-	go func() {
-		<-c1
-	}()
-	go func() {
-		c2 <- 1
-	}()
-	go func() {
-		select {
-		case c1 <- x: // read of x races with...
-		case c3 <- 1:
-		}
-		done <- true
-	}()
-	select {
-	case x = <-c2: // ... write to x here
-	case c3 <- 1:
-	}
-	<-done
-}
-
-func TestNoRaceSelectReadWriteAsync(t *testing.T) {
-	done := make(chan bool)
-	x := 0
-	c1 := make(chan int)
-	c2 := make(chan int)
-	go func() {
-		select {
-		case c1 <- x: // read of x does not race with...
-		case c2 <- 1:
-		}
-		done <- true
-	}()
-	select {
-	case x = <-c1: // ... write to x here
-	case c2 <- 1:
-	}
-	<-done
-}
-
-func TestRaceChanReadWriteAsync(t *testing.T) {
-	done := make(chan bool)
-	c1 := make(chan int, 10)
-	c2 := make(chan int, 10)
-	c2 <- 10
-	x := 0
-	go func() {
-		c1 <- x // read of x races with...
-		done <- true
-	}()
-	x = <-c2 // ... write to x here
-	<-done
-}
-
-func TestRaceChanReadWriteSync(t *testing.T) {
-	done := make(chan bool)
-	c1 := make(chan int)
-	c2 := make(chan int)
-	// make c1 and c2 ready for communication
-	go func() {
-		<-c1
-	}()
-	go func() {
-		c2 <- 10
-	}()
-	x := 0
-	go func() {
-		c1 <- x // read of x races with...
-		done <- true
-	}()
-	x = <-c2 // ... write to x here
-	<-done
-}
-
-func TestNoRaceChanReadWriteAsync(t *testing.T) {
-	done := make(chan bool)
-	c1 := make(chan int, 10)
-	x := 0
-	go func() {
-		c1 <- x // read of x does not race with...
-		done <- true
-	}()
-	x = <-c1 // ... write to x here
-	<-done
-}
-
-func TestNoRaceProducerConsumerUnbuffered(t *testing.T) {
-	type Task struct {
-		f    func()
-		done chan bool
-	}
-
-	queue := make(chan Task)
-
-	go func() {
-		t := <-queue
-		t.f()
-		t.done <- true
-	}()
-
-	doit := func(f func()) {
-		done := make(chan bool, 1)
-		queue <- Task{f, done}
-		<-done
-	}
-
-	x := 0
-	doit(func() {
-		x = 1
-	})
-	_ = x
-}
-
-func TestRaceChanItselfSend(t *testing.T) {
-	compl := make(chan bool, 1)
-	c := make(chan int, 10)
-	go func() {
-		c <- 0
-		compl <- true
-	}()
-	c = make(chan int, 20)
-	<-compl
-}
-
-func TestRaceChanItselfRecv(t *testing.T) {
-	compl := make(chan bool, 1)
-	c := make(chan int, 10)
-	c <- 1
-	go func() {
-		<-c
-		compl <- true
-	}()
-	time.Sleep(1e7)
-	c = make(chan int, 20)
-	<-compl
-}
-
-func TestRaceChanItselfNil(t *testing.T) {
-	c := make(chan int, 10)
-	go func() {
-		c <- 0
-	}()
-	time.Sleep(1e7)
-	c = nil
-	_ = c
-}
-
-func TestRaceChanItselfClose(t *testing.T) {
-	compl := make(chan bool, 1)
-	c := make(chan int)
-	go func() {
-		close(c)
-		compl <- true
-	}()
-	c = make(chan int)
-	<-compl
-}
-
-func TestRaceChanItselfLen(t *testing.T) {
-	compl := make(chan bool, 1)
-	c := make(chan int)
-	go func() {
-		_ = len(c)
-		compl <- true
-	}()
-	c = make(chan int)
-	<-compl
-}
-
-func TestRaceChanItselfCap(t *testing.T) {
-	compl := make(chan bool, 1)
-	c := make(chan int)
-	go func() {
-		_ = cap(c)
-		compl <- true
-	}()
-	c = make(chan int)
-	<-compl
-}
-
-func TestRaceChanCloseLen(t *testing.T) {
-	v := 0
-	c := make(chan int, 10)
-	c <- 0
-	go func() {
-		v = 1
-		close(c)
-	}()
-	time.Sleep(1e7)
-	_ = len(c)
-	v = 2
-}
-
-func TestRaceChanCloseSend(t *testing.T) {
-	compl := make(chan bool, 1)
-	c := make(chan int, 10)
-	go func() {
-		close(c)
-		compl <- true
-	}()
-	c <- 0
-	<-compl
-}
-
-func TestNoRaceChanMutex(t *testing.T) {
-	done := make(chan struct{})
-	mtx := make(chan struct{}, 1)
-	data := 0
-	go func() {
-		mtx <- struct{}{}
-		data = 42
-		<-mtx
-		done <- struct{}{}
-	}()
-	mtx <- struct{}{}
-	data = 43
-	<-mtx
-	<-done
-}
-
-func TestNoRaceSelectMutex(t *testing.T) {
-	done := make(chan struct{})
-	mtx := make(chan struct{}, 1)
-	aux := make(chan bool)
-	data := 0
-	go func() {
-		select {
-		case mtx <- struct{}{}:
-		case <-aux:
-		}
-		data = 42
-		select {
-		case <-mtx:
-		case <-aux:
-		}
-		done <- struct{}{}
-	}()
-	select {
-	case mtx <- struct{}{}:
-	case <-aux:
-	}
-	data = 43
-	select {
-	case <-mtx:
-	case <-aux:
-	}
-	<-done
-}
-
-func TestRaceChanSem(t *testing.T) {
-	done := make(chan struct{})
-	mtx := make(chan bool, 2)
-	data := 0
-	go func() {
-		mtx <- true
-		data = 42
-		<-mtx
-		done <- struct{}{}
-	}()
-	mtx <- true
-	data = 43
-	<-mtx
-	<-done
-}
-
-func TestNoRaceChanWaitGroup(t *testing.T) {
-	const N = 10
-	chanWg := make(chan bool, N/2)
-	data := make([]int, N)
-	for i := 0; i < N; i++ {
-		chanWg <- true
-		go func(i int) {
-			data[i] = 42
-			<-chanWg
-		}(i)
-	}
-	for i := 0; i < cap(chanWg); i++ {
-		chanWg <- true
-	}
-	for i := 0; i < N; i++ {
-		_ = data[i]
-	}
-}
diff --git a/src/pkg/runtime/race/testdata/map_test.go b/src/pkg/runtime/race/testdata/map_test.go
deleted file mode 100644
index 98e2a5f..0000000
--- a/src/pkg/runtime/race/testdata/map_test.go
+++ /dev/null
@@ -1,240 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package race_test
-
-import (
-	"testing"
-)
-
-func TestRaceMapRW(t *testing.T) {
-	m := make(map[int]int)
-	ch := make(chan bool, 1)
-	go func() {
-		_ = m[1]
-		ch <- true
-	}()
-	m[1] = 1
-	<-ch
-}
-
-func TestRaceMapRW2(t *testing.T) {
-	m := make(map[int]int)
-	ch := make(chan bool, 1)
-	go func() {
-		_, _ = m[1]
-		ch <- true
-	}()
-	m[1] = 1
-	<-ch
-}
-
-func TestRaceMapRWArray(t *testing.T) {
-	// Check instrumentation of unaddressable arrays (issue 4578).
-	m := make(map[int][2]int)
-	ch := make(chan bool, 1)
-	go func() {
-		_ = m[1][1]
-		ch <- true
-	}()
-	m[2] = [2]int{1, 2}
-	<-ch
-}
-
-func TestNoRaceMapRR(t *testing.T) {
-	m := make(map[int]int)
-	ch := make(chan bool, 1)
-	go func() {
-		_, _ = m[1]
-		ch <- true
-	}()
-	_ = m[1]
-	<-ch
-}
-
-func TestRaceMapRange(t *testing.T) {
-	m := make(map[int]int)
-	ch := make(chan bool, 1)
-	go func() {
-		for _ = range m {
-		}
-		ch <- true
-	}()
-	m[1] = 1
-	<-ch
-}
-
-func TestRaceMapRange2(t *testing.T) {
-	m := make(map[int]int)
-	ch := make(chan bool, 1)
-	go func() {
-		for _ = range m {
-		}
-		ch <- true
-	}()
-	m[1] = 1
-	<-ch
-}
-
-func TestNoRaceMapRangeRange(t *testing.T) {
-	m := make(map[int]int)
-	// now the map is not empty and range triggers an event
-	// should work without this (as in other tests)
-	// so it is suspicious if this test passes and others don't
-	m[0] = 0
-	ch := make(chan bool, 1)
-	go func() {
-		for _ = range m {
-		}
-		ch <- true
-	}()
-	for _ = range m {
-	}
-	<-ch
-}
-
-func TestRaceMapLen(t *testing.T) {
-	m := make(map[string]bool)
-	ch := make(chan bool, 1)
-	go func() {
-		_ = len(m)
-		ch <- true
-	}()
-	m[""] = true
-	<-ch
-}
-
-func TestRaceMapDelete(t *testing.T) {
-	m := make(map[string]bool)
-	ch := make(chan bool, 1)
-	go func() {
-		delete(m, "")
-		ch <- true
-	}()
-	m[""] = true
-	<-ch
-}
-
-func TestRaceMapLenDelete(t *testing.T) {
-	m := make(map[string]bool)
-	ch := make(chan bool, 1)
-	go func() {
-		delete(m, "a")
-		ch <- true
-	}()
-	_ = len(m)
-	<-ch
-}
-
-func TestRaceMapVariable(t *testing.T) {
-	ch := make(chan bool, 1)
-	m := make(map[int]int)
-	go func() {
-		m = make(map[int]int)
-		ch <- true
-	}()
-	m = make(map[int]int)
-	<-ch
-}
-
-func TestRaceMapVariable2(t *testing.T) {
-	ch := make(chan bool, 1)
-	m := make(map[int]int)
-	go func() {
-		m[1] = 1
-		ch <- true
-	}()
-	m = make(map[int]int)
-	<-ch
-}
-
-func TestRaceMapVariable3(t *testing.T) {
-	ch := make(chan bool, 1)
-	m := make(map[int]int)
-	go func() {
-		_ = m[1]
-		ch <- true
-	}()
-	m = make(map[int]int)
-	<-ch
-}
-
-type Big struct {
-	x [17]int32
-}
-
-func TestRaceMapLookupPartKey(t *testing.T) {
-	k := &Big{}
-	m := make(map[Big]bool)
-	ch := make(chan bool, 1)
-	go func() {
-		k.x[8] = 1
-		ch <- true
-	}()
-	_ = m[*k]
-	<-ch
-}
-
-func TestRaceMapLookupPartKey2(t *testing.T) {
-	k := &Big{}
-	m := make(map[Big]bool)
-	ch := make(chan bool, 1)
-	go func() {
-		k.x[8] = 1
-		ch <- true
-	}()
-	_, _ = m[*k]
-	<-ch
-}
-func TestRaceMapDeletePartKey(t *testing.T) {
-	k := &Big{}
-	m := make(map[Big]bool)
-	ch := make(chan bool, 1)
-	go func() {
-		k.x[8] = 1
-		ch <- true
-	}()
-	delete(m, *k)
-	<-ch
-}
-
-func TestRaceMapInsertPartKey(t *testing.T) {
-	k := &Big{}
-	m := make(map[Big]bool)
-	ch := make(chan bool, 1)
-	go func() {
-		k.x[8] = 1
-		ch <- true
-	}()
-	m[*k] = true
-	<-ch
-}
-
-func TestRaceMapInsertPartVal(t *testing.T) {
-	v := &Big{}
-	m := make(map[int]Big)
-	ch := make(chan bool, 1)
-	go func() {
-		v.x[8] = 1
-		ch <- true
-	}()
-	m[1] = *v
-	<-ch
-}
-
-// Test for issue 7561.
-func TestRaceMapAssignMultipleReturn(t *testing.T) {
-	connect := func() (int, error) { return 42, nil }
-	conns := make(map[int][]int)
-	conns[1] = []int{0}
-	ch := make(chan bool, 1)
-	var err error
-	go func() {
-		conns[1][0], err = connect()
-		ch <- true
-	}()
-	x := conns[1][0]
-	_ = x
-	<-ch
-}
diff --git a/src/pkg/runtime/race/testdata/mop_test.go b/src/pkg/runtime/race/testdata/mop_test.go
deleted file mode 100644
index 14591b1..0000000
--- a/src/pkg/runtime/race/testdata/mop_test.go
+++ /dev/null
@@ -1,1957 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package race_test
-
-import (
-	"bytes"
-	"crypto/sha1"
-	"errors"
-	"fmt"
-	"io"
-	"os"
-	"runtime"
-	"sync"
-	"testing"
-	"time"
-	"unsafe"
-)
-
-type Point struct {
-	x, y int
-}
-
-type NamedPoint struct {
-	name string
-	p    Point
-}
-
-type DummyWriter struct {
-	state int
-}
-type Writer interface {
-	Write(p []byte) (n int)
-}
-
-func (d DummyWriter) Write(p []byte) (n int) {
-	return 0
-}
-
-var GlobalX, GlobalY int = 0, 0
-var GlobalCh chan int = make(chan int, 2)
-
-func GlobalFunc1() {
-	GlobalY = GlobalX
-	GlobalCh <- 1
-}
-
-func GlobalFunc2() {
-	GlobalX = 1
-	GlobalCh <- 1
-}
-
-func TestRaceIntRWGlobalFuncs(t *testing.T) {
-	go GlobalFunc1()
-	go GlobalFunc2()
-	<-GlobalCh
-	<-GlobalCh
-}
-
-func TestRaceIntRWClosures(t *testing.T) {
-	var x, y int
-	ch := make(chan int, 2)
-
-	go func() {
-		y = x
-		ch <- 1
-	}()
-	go func() {
-		x = 1
-		ch <- 1
-	}()
-	<-ch
-	<-ch
-}
-
-func TestNoRaceIntRWClosures(t *testing.T) {
-	var x, y int
-	ch := make(chan int, 1)
-
-	go func() {
-		y = x
-		ch <- 1
-	}()
-	<-ch
-	go func() {
-		x = 1
-		ch <- 1
-	}()
-	<-ch
-
-}
-
-func TestRaceInt32RWClosures(t *testing.T) {
-	var x, y int32
-	ch := make(chan bool, 2)
-
-	go func() {
-		y = x
-		ch <- true
-	}()
-	go func() {
-		x = 1
-		ch <- true
-	}()
-	<-ch
-	<-ch
-}
-
-func TestNoRaceCase(t *testing.T) {
-	var y int
-	for x := -1; x <= 1; x++ {
-		switch {
-		case x < 0:
-			y = -1
-		case x == 0:
-			y = 0
-		case x > 0:
-			y = 1
-		}
-	}
-	y++
-}
-
-func TestRaceCaseCondition(t *testing.T) {
-	var x int = 0
-	ch := make(chan int, 2)
-
-	go func() {
-		x = 2
-		ch <- 1
-	}()
-	go func() {
-		switch x < 2 {
-		case true:
-			x = 1
-			//case false:
-			//	x = 5
-		}
-		ch <- 1
-	}()
-	<-ch
-	<-ch
-}
-
-func TestRaceCaseCondition2(t *testing.T) {
-	// switch body is rearranged by the compiler so the tests
-	// passes even if we don't instrument '<'
-	var x int = 0
-	ch := make(chan int, 2)
-
-	go func() {
-		x = 2
-		ch <- 1
-	}()
-	go func() {
-		switch x < 2 {
-		case true:
-			x = 1
-		case false:
-			x = 5
-		}
-		ch <- 1
-	}()
-	<-ch
-	<-ch
-}
-
-func TestRaceCaseBody(t *testing.T) {
-	var x, y int
-	ch := make(chan int, 2)
-
-	go func() {
-		y = x
-		ch <- 1
-	}()
-	go func() {
-		switch {
-		default:
-			x = 1
-		case x == 100:
-			x = -x
-		}
-		ch <- 1
-	}()
-	<-ch
-	<-ch
-}
-
-func TestNoRaceCaseFallthrough(t *testing.T) {
-	var x, y, z int
-	ch := make(chan int, 2)
-	z = 1
-
-	go func() {
-		y = x
-		ch <- 1
-	}()
-	go func() {
-		switch {
-		case z == 1:
-		case z == 2:
-			x = 2
-		}
-		ch <- 1
-	}()
-	<-ch
-	<-ch
-}
-
-func TestRaceCaseFallthrough(t *testing.T) {
-	var x, y, z int
-	ch := make(chan int, 2)
-	z = 1
-
-	go func() {
-		y = x
-		ch <- 1
-	}()
-	go func() {
-		switch {
-		case z == 1:
-			fallthrough
-		case z == 2:
-			x = 2
-		}
-		ch <- 1
-	}()
-
-	<-ch
-	<-ch
-}
-
-func TestRaceCaseIssue6418(t *testing.T) {
-	m := map[string]map[string]string{
-		"a": map[string]string{
-			"b": "c",
-		},
-	}
-	ch := make(chan int)
-	go func() {
-		m["a"]["x"] = "y"
-		ch <- 1
-	}()
-	switch m["a"]["b"] {
-	}
-	<-ch
-}
-
-func TestRaceCaseType(t *testing.T) {
-	var x, y int
-	var i interface{} = x
-	c := make(chan int, 1)
-	go func() {
-		switch i.(type) {
-		case nil:
-		case int:
-		}
-		c <- 1
-	}()
-	i = y
-	<-c
-}
-
-func TestRaceCaseTypeBody(t *testing.T) {
-	var x, y int
-	var i interface{} = &x
-	c := make(chan int, 1)
-	go func() {
-		switch i := i.(type) {
-		case nil:
-		case *int:
-			*i = y
-		}
-		c <- 1
-	}()
-	x = y
-	<-c
-}
-
-func TestRaceCaseTypeIssue5890(t *testing.T) {
-	// spurious extra instrumentation of the initial interface
-	// value.
-	var x, y int
-	m := make(map[int]map[int]interface{})
-	m[0] = make(map[int]interface{})
-	c := make(chan int, 1)
-	go func() {
-		switch i := m[0][1].(type) {
-		case nil:
-		case *int:
-			*i = x
-		}
-		c <- 1
-	}()
-	m[0][1] = y
-	<-c
-}
-
-func TestNoRaceRange(t *testing.T) {
-	ch := make(chan int, 3)
-	a := [...]int{1, 2, 3}
-	for _, v := range a {
-		ch <- v
-	}
-	close(ch)
-}
-
-func TestNoRaceRangeIssue5446(t *testing.T) {
-	ch := make(chan int, 3)
-	a := []int{1, 2, 3}
-	b := []int{4}
-	// used to insert a spurious instrumentation of a[i]
-	// and crash.
-	i := 1
-	for i, a[i] = range b {
-		ch <- i
-	}
-	close(ch)
-}
-
-func TestRaceRange(t *testing.T) {
-	const N = 2
-	var a [N]int
-	var x, y int
-	done := make(chan bool, N)
-	for i, v := range a {
-		go func(i int) {
-			// we don't want a write-vs-write race
-			// so there is no array b here
-			if i == 0 {
-				x = v
-			} else {
-				y = v
-			}
-			done <- true
-		}(i)
-	}
-	for i := 0; i < N; i++ {
-		<-done
-	}
-}
-
-func TestRaceForInit(t *testing.T) {
-	c := make(chan int)
-	x := 0
-	go func() {
-		c <- x
-	}()
-	for x = 42; false; {
-	}
-	<-c
-}
-
-func TestNoRaceForInit(t *testing.T) {
-	done := make(chan bool)
-	c := make(chan bool)
-	x := 0
-	go func() {
-		for {
-			_, ok := <-c
-			if !ok {
-				done <- true
-				return
-			}
-			x++
-		}
-	}()
-	i := 0
-	for x = 42; i < 10; i++ {
-		c <- true
-	}
-	close(c)
-	<-done
-}
-
-func TestRaceForTest(t *testing.T) {
-	done := make(chan bool)
-	c := make(chan bool)
-	stop := false
-	go func() {
-		for {
-			_, ok := <-c
-			if !ok {
-				done <- true
-				return
-			}
-			stop = true
-		}
-	}()
-	for !stop {
-		c <- true
-	}
-	close(c)
-	<-done
-}
-
-func TestRaceForIncr(t *testing.T) {
-	done := make(chan bool)
-	c := make(chan bool)
-	x := 0
-	go func() {
-		for {
-			_, ok := <-c
-			if !ok {
-				done <- true
-				return
-			}
-			x++
-		}
-	}()
-	for i := 0; i < 10; x++ {
-		i++
-		c <- true
-	}
-	close(c)
-	<-done
-}
-
-func TestNoRaceForIncr(t *testing.T) {
-	done := make(chan bool)
-	x := 0
-	go func() {
-		x++
-		done <- true
-	}()
-	for i := 0; i < 0; x++ {
-	}
-	<-done
-}
-
-func TestRacePlus(t *testing.T) {
-	var x, y, z int
-	ch := make(chan int, 2)
-
-	go func() {
-		y = x + z
-		ch <- 1
-	}()
-	go func() {
-		y = x + z + z
-		ch <- 1
-	}()
-	<-ch
-	<-ch
-}
-
-func TestRacePlus2(t *testing.T) {
-	var x, y, z int
-	ch := make(chan int, 2)
-
-	go func() {
-		x = 1
-		ch <- 1
-	}()
-	go func() {
-		y = +x + z
-		ch <- 1
-	}()
-	<-ch
-	<-ch
-}
-
-func TestNoRacePlus(t *testing.T) {
-	var x, y, z, f int
-	ch := make(chan int, 2)
-
-	go func() {
-		y = x + z
-		ch <- 1
-	}()
-	go func() {
-		f = z + x
-		ch <- 1
-	}()
-	<-ch
-	<-ch
-}
-
-func TestRaceComplement(t *testing.T) {
-	var x, y, z int
-	ch := make(chan int, 2)
-
-	go func() {
-		x = ^y
-		ch <- 1
-	}()
-	go func() {
-		y = ^z
-		ch <- 1
-	}()
-	<-ch
-	<-ch
-}
-
-func TestRaceDiv(t *testing.T) {
-	var x, y, z int
-	ch := make(chan int, 2)
-
-	go func() {
-		x = y / (z + 1)
-		ch <- 1
-	}()
-	go func() {
-		y = z
-		ch <- 1
-	}()
-	<-ch
-	<-ch
-}
-
-func TestRaceDivConst(t *testing.T) {
-	var x, y, z uint32
-	ch := make(chan int, 2)
-
-	go func() {
-		x = y / 3 // involves only a HMUL node
-		ch <- 1
-	}()
-	go func() {
-		y = z
-		ch <- 1
-	}()
-	<-ch
-	<-ch
-}
-
-func TestRaceMod(t *testing.T) {
-	var x, y, z int
-	ch := make(chan int, 2)
-
-	go func() {
-		x = y % (z + 1)
-		ch <- 1
-	}()
-	go func() {
-		y = z
-		ch <- 1
-	}()
-	<-ch
-	<-ch
-}
-
-func TestRaceModConst(t *testing.T) {
-	var x, y, z int
-	ch := make(chan int, 2)
-
-	go func() {
-		x = y % 3
-		ch <- 1
-	}()
-	go func() {
-		y = z
-		ch <- 1
-	}()
-	<-ch
-	<-ch
-}
-
-func TestRaceRotate(t *testing.T) {
-	var x, y, z uint32
-	ch := make(chan int, 2)
-
-	go func() {
-		x = y<<12 | y>>20
-		ch <- 1
-	}()
-	go func() {
-		y = z
-		ch <- 1
-	}()
-	<-ch
-	<-ch
-}
-
-// May crash if the instrumentation is reckless.
-func TestNoRaceEnoughRegisters(t *testing.T) {
-	// from erf.go
-	const (
-		sa1 = 1
-		sa2 = 2
-		sa3 = 3
-		sa4 = 4
-		sa5 = 5
-		sa6 = 6
-		sa7 = 7
-		sa8 = 8
-	)
-	var s, S float64
-	s = 3.1415
-	S = 1 + s*(sa1+s*(sa2+s*(sa3+s*(sa4+s*(sa5+s*(sa6+s*(sa7+s*sa8)))))))
-	s = S
-}
-
-// emptyFunc should not be inlined.
-func emptyFunc(x int) {
-	if false {
-		fmt.Println(x)
-	}
-}
-
-func TestRaceFuncArgument(t *testing.T) {
-	var x int
-	ch := make(chan bool, 1)
-	go func() {
-		emptyFunc(x)
-		ch <- true
-	}()
-	x = 1
-	<-ch
-}
-
-func TestRaceFuncArgument2(t *testing.T) {
-	var x int
-	ch := make(chan bool, 2)
-	go func() {
-		x = 42
-		ch <- true
-	}()
-	go func(y int) {
-		ch <- true
-	}(x)
-	<-ch
-	<-ch
-}
-
-func TestRaceSprint(t *testing.T) {
-	var x int
-	ch := make(chan bool, 1)
-	go func() {
-		fmt.Sprint(x)
-		ch <- true
-	}()
-	x = 1
-	<-ch
-}
-
-func TestRaceArrayCopy(t *testing.T) {
-	ch := make(chan bool, 1)
-	var a [5]int
-	go func() {
-		a[3] = 1
-		ch <- true
-	}()
-	a = [5]int{1, 2, 3, 4, 5}
-	<-ch
-}
-
-// Blows up a naive compiler.
-func TestRaceNestedArrayCopy(t *testing.T) {
-	ch := make(chan bool, 1)
-	type (
-		Point32   [2][2][2][2][2]Point
-		Point1024 [2][2][2][2][2]Point32
-		Point32k  [2][2][2][2][2]Point1024
-		Point1M   [2][2][2][2][2]Point32k
-	)
-	var a, b Point1M
-	go func() {
-		a[0][1][0][1][0][1][0][1][0][1][0][1][0][1][0][1][0][1][0][1].y = 1
-		ch <- true
-	}()
-	a = b
-	<-ch
-}
-
-func TestRaceStructRW(t *testing.T) {
-	p := Point{0, 0}
-	ch := make(chan bool, 1)
-	go func() {
-		p = Point{1, 1}
-		ch <- true
-	}()
-	q := p
-	<-ch
-	p = q
-}
-
-func TestRaceStructFieldRW1(t *testing.T) {
-	p := Point{0, 0}
-	ch := make(chan bool, 1)
-	go func() {
-		p.x = 1
-		ch <- true
-	}()
-	_ = p.x
-	<-ch
-}
-
-func TestNoRaceStructFieldRW1(t *testing.T) {
-	// Same struct, different variables, no
-	// pointers. The layout is known (at compile time?) ->
-	// no read on p
-	// writes on x and y
-	p := Point{0, 0}
-	ch := make(chan bool, 1)
-	go func() {
-		p.x = 1
-		ch <- true
-	}()
-	p.y = 1
-	<-ch
-	_ = p
-}
-
-func TestNoRaceStructFieldRW2(t *testing.T) {
-	// Same as NoRaceStructFieldRW1
-	// but p is a pointer, so there is a read on p
-	p := Point{0, 0}
-	ch := make(chan bool, 1)
-	go func() {
-		p.x = 1
-		ch <- true
-	}()
-	p.y = 1
-	<-ch
-	_ = p
-}
-
-func TestRaceStructFieldRW2(t *testing.T) {
-	p := &Point{0, 0}
-	ch := make(chan bool, 1)
-	go func() {
-		p.x = 1
-		ch <- true
-	}()
-	_ = p.x
-	<-ch
-}
-
-func TestRaceStructFieldRW3(t *testing.T) {
-	p := NamedPoint{name: "a", p: Point{0, 0}}
-	ch := make(chan bool, 1)
-	go func() {
-		p.p.x = 1
-		ch <- true
-	}()
-	_ = p.p.x
-	<-ch
-}
-
-func TestRaceEfaceWW(t *testing.T) {
-	var a, b interface{}
-	ch := make(chan bool, 1)
-	go func() {
-		a = 1
-		ch <- true
-	}()
-	a = 2
-	<-ch
-	_, _ = a, b
-}
-
-func TestRaceIfaceWW(t *testing.T) {
-	var a, b Writer
-	ch := make(chan bool, 1)
-	go func() {
-		a = DummyWriter{1}
-		ch <- true
-	}()
-	a = DummyWriter{2}
-	<-ch
-	b = a
-	a = b
-}
-
-func TestRaceIfaceCmp(t *testing.T) {
-	var a, b Writer
-	a = DummyWriter{1}
-	ch := make(chan bool, 1)
-	go func() {
-		a = DummyWriter{1}
-		ch <- true
-	}()
-	_ = a == b
-	<-ch
-}
-
-func TestRaceIfaceCmpNil(t *testing.T) {
-	var a Writer
-	a = DummyWriter{1}
-	ch := make(chan bool, 1)
-	go func() {
-		a = DummyWriter{1}
-		ch <- true
-	}()
-	_ = a == nil
-	<-ch
-}
-
-func TestRaceEfaceConv(t *testing.T) {
-	c := make(chan bool)
-	v := 0
-	go func() {
-		go func(x interface{}) {
-		}(v)
-		c <- true
-	}()
-	v = 42
-	<-c
-}
-
-type OsFile struct{}
-
-func (*OsFile) Read() {
-}
-
-type IoReader interface {
-	Read()
-}
-
-func TestRaceIfaceConv(t *testing.T) {
-	c := make(chan bool)
-	f := &OsFile{}
-	go func() {
-		go func(x IoReader) {
-		}(f)
-		c <- true
-	}()
-	f = &OsFile{}
-	<-c
-}
-
-func TestRaceError(t *testing.T) {
-	ch := make(chan bool, 1)
-	var err error
-	go func() {
-		err = nil
-		ch <- true
-	}()
-	_ = err
-	<-ch
-}
-
-func TestRaceIntptrRW(t *testing.T) {
-	var x, y int
-	var p *int = &x
-	ch := make(chan bool, 1)
-	go func() {
-		*p = 5
-		ch <- true
-	}()
-	y = *p
-	x = y
-	<-ch
-}
-
-func TestRaceStringRW(t *testing.T) {
-	ch := make(chan bool, 1)
-	s := ""
-	go func() {
-		s = "abacaba"
-		ch <- true
-	}()
-	_ = s
-	<-ch
-}
-
-func TestRaceStringPtrRW(t *testing.T) {
-	ch := make(chan bool, 1)
-	var x string
-	p := &x
-	go func() {
-		*p = "a"
-		ch <- true
-	}()
-	_ = *p
-	<-ch
-}
-
-func TestRaceFloat64WW(t *testing.T) {
-	var x, y float64
-	ch := make(chan bool, 1)
-	go func() {
-		x = 1.0
-		ch <- true
-	}()
-	x = 2.0
-	<-ch
-
-	y = x
-	x = y
-}
-
-func TestRaceComplex128WW(t *testing.T) {
-	var x, y complex128
-	ch := make(chan bool, 1)
-	go func() {
-		x = 2 + 2i
-		ch <- true
-	}()
-	x = 4 + 4i
-	<-ch
-
-	y = x
-	x = y
-}
-
-func TestRaceUnsafePtrRW(t *testing.T) {
-	var x, y, z int
-	x, y, z = 1, 2, 3
-	var p unsafe.Pointer = unsafe.Pointer(&x)
-	ch := make(chan bool, 1)
-	go func() {
-		p = (unsafe.Pointer)(&z)
-		ch <- true
-	}()
-	y = *(*int)(p)
-	x = y
-	<-ch
-}
-
-func TestRaceFuncVariableRW(t *testing.T) {
-	var f func(x int) int
-	f = func(x int) int {
-		return x * x
-	}
-	ch := make(chan bool, 1)
-	go func() {
-		f = func(x int) int {
-			return x
-		}
-		ch <- true
-	}()
-	y := f(1)
-	<-ch
-	x := y
-	y = x
-}
-
-func TestRaceFuncVariableWW(t *testing.T) {
-	var f func(x int) int
-	ch := make(chan bool, 1)
-	go func() {
-		f = func(x int) int {
-			return x
-		}
-		ch <- true
-	}()
-	f = func(x int) int {
-		return x * x
-	}
-	<-ch
-}
-
-// This one should not belong to mop_test
-func TestRacePanic(t *testing.T) {
-	var x int
-	var zero int = 0
-	ch := make(chan bool, 2)
-	go func() {
-		defer func() {
-			err := recover()
-			if err == nil {
-				panic("should be panicking")
-			}
-			x = 1
-			ch <- true
-		}()
-		var y int = 1 / zero
-		zero = y
-	}()
-	go func() {
-		defer func() {
-			err := recover()
-			if err == nil {
-				panic("should be panicking")
-			}
-			x = 2
-			ch <- true
-		}()
-		var y int = 1 / zero
-		zero = y
-	}()
-
-	<-ch
-	<-ch
-	if zero != 0 {
-		panic("zero has changed")
-	}
-}
-
-func TestNoRaceBlank(t *testing.T) {
-	var a [5]int
-	ch := make(chan bool, 1)
-	go func() {
-		_, _ = a[0], a[1]
-		ch <- true
-	}()
-	_, _ = a[2], a[3]
-	<-ch
-	a[1] = a[0]
-}
-
-func TestRaceAppendRW(t *testing.T) {
-	a := make([]int, 10)
-	ch := make(chan bool)
-	go func() {
-		_ = append(a, 1)
-		ch <- true
-	}()
-	a[0] = 1
-	<-ch
-}
-
-func TestRaceAppendLenRW(t *testing.T) {
-	a := make([]int, 0)
-	ch := make(chan bool)
-	go func() {
-		a = append(a, 1)
-		ch <- true
-	}()
-	_ = len(a)
-	<-ch
-}
-
-func TestRaceAppendCapRW(t *testing.T) {
-	a := make([]int, 0)
-	ch := make(chan string)
-	go func() {
-		a = append(a, 1)
-		ch <- ""
-	}()
-	_ = cap(a)
-	<-ch
-}
-
-func TestNoRaceFuncArgsRW(t *testing.T) {
-	ch := make(chan byte, 1)
-	var x byte
-	go func(y byte) {
-		_ = y
-		ch <- 0
-	}(x)
-	x = 1
-	<-ch
-}
-
-func TestRaceFuncArgsRW(t *testing.T) {
-	ch := make(chan byte, 1)
-	var x byte
-	go func(y *byte) {
-		_ = *y
-		ch <- 0
-	}(&x)
-	x = 1
-	<-ch
-}
-
-// from the mailing list, slightly modified
-// unprotected concurrent access to seen[]
-func TestRaceCrawl(t *testing.T) {
-	url := "dummyurl"
-	depth := 3
-	seen := make(map[string]bool)
-	ch := make(chan int, 100)
-	var wg sync.WaitGroup
-	var crawl func(string, int)
-	crawl = func(u string, d int) {
-		nurl := 0
-		defer func() {
-			ch <- nurl
-		}()
-		seen[u] = true
-		if d <= 0 {
-			return
-		}
-		urls := [...]string{"a", "b", "c"}
-		for _, uu := range urls {
-			if _, ok := seen[uu]; !ok {
-				wg.Add(1)
-				go crawl(uu, d-1)
-				nurl++
-			}
-		}
-		wg.Done()
-	}
-	wg.Add(1)
-	go crawl(url, depth)
-	wg.Wait()
-}
-
-func TestRaceIndirection(t *testing.T) {
-	ch := make(chan struct{}, 1)
-	var y int
-	var x *int = &y
-	go func() {
-		*x = 1
-		ch <- struct{}{}
-	}()
-	*x = 2
-	<-ch
-	_ = *x
-}
-
-func TestRaceRune(t *testing.T) {
-	c := make(chan bool)
-	var x rune
-	go func() {
-		x = 1
-		c <- true
-	}()
-	_ = x
-	<-c
-}
-
-func TestRaceEmptyInterface1(t *testing.T) {
-	c := make(chan bool)
-	var x interface{}
-	go func() {
-		x = nil
-		c <- true
-	}()
-	_ = x
-	<-c
-}
-
-func TestRaceEmptyInterface2(t *testing.T) {
-	c := make(chan bool)
-	var x interface{}
-	go func() {
-		x = &Point{}
-		c <- true
-	}()
-	_ = x
-	<-c
-}
-
-func TestRaceTLS(t *testing.T) {
-	comm := make(chan *int)
-	done := make(chan bool, 2)
-	go func() {
-		var x int
-		comm <- &x
-		x = 1
-		x = *(<-comm)
-		done <- true
-	}()
-	go func() {
-		p := <-comm
-		*p = 2
-		comm <- p
-		done <- true
-	}()
-	<-done
-	<-done
-}
-
-func TestNoRaceHeapReallocation(t *testing.T) {
-	// It is possible that a future implementation
-	// of memory allocation will ruin this test.
-	// Increasing n might help in this case, so
-	// this test is a bit more generic than most of the
-	// others.
-	const n = 2
-	done := make(chan bool, n)
-	empty := func(p *int) {}
-	for i := 0; i < n; i++ {
-		ms := i
-		go func() {
-			<-time.After(time.Duration(ms) * time.Millisecond)
-			runtime.GC()
-			var x int
-			empty(&x) // x goes to the heap
-			done <- true
-		}()
-	}
-	for i := 0; i < n; i++ {
-		<-done
-	}
-}
-
-func TestRaceAnd(t *testing.T) {
-	c := make(chan bool)
-	x, y := 0, 0
-	go func() {
-		x = 1
-		c <- true
-	}()
-	if x == 1 && y == 1 {
-	}
-	<-c
-}
-
-func TestRaceAnd2(t *testing.T) {
-	c := make(chan bool)
-	x, y := 0, 0
-	go func() {
-		x = 1
-		c <- true
-	}()
-	if y == 0 && x == 1 {
-	}
-	<-c
-}
-
-func TestNoRaceAnd(t *testing.T) {
-	c := make(chan bool)
-	x, y := 0, 0
-	go func() {
-		x = 1
-		c <- true
-	}()
-	if y == 1 && x == 1 {
-	}
-	<-c
-}
-
-func TestRaceOr(t *testing.T) {
-	c := make(chan bool)
-	x, y := 0, 0
-	go func() {
-		x = 1
-		c <- true
-	}()
-	if x == 1 || y == 1 {
-	}
-	<-c
-}
-
-func TestRaceOr2(t *testing.T) {
-	c := make(chan bool)
-	x, y := 0, 0
-	go func() {
-		x = 1
-		c <- true
-	}()
-	if y == 1 || x == 1 {
-	}
-	<-c
-}
-
-func TestNoRaceOr(t *testing.T) {
-	c := make(chan bool)
-	x, y := 0, 0
-	go func() {
-		x = 1
-		c <- true
-	}()
-	if y == 0 || x == 1 {
-	}
-	<-c
-}
-
-func TestNoRaceShortCalc(t *testing.T) {
-	c := make(chan bool)
-	x, y := 0, 0
-	go func() {
-		y = 1
-		c <- true
-	}()
-	if x == 0 || y == 0 {
-	}
-	<-c
-}
-
-func TestNoRaceShortCalc2(t *testing.T) {
-	c := make(chan bool)
-	x, y := 0, 0
-	go func() {
-		y = 1
-		c <- true
-	}()
-	if x == 1 && y == 0 {
-	}
-	<-c
-}
-
-func TestRaceFuncItself(t *testing.T) {
-	c := make(chan bool)
-	f := func() {}
-	go func() {
-		f()
-		c <- true
-	}()
-	f = func() {}
-	<-c
-}
-
-func TestNoRaceFuncUnlock(t *testing.T) {
-	ch := make(chan bool, 1)
-	var mu sync.Mutex
-	x := 0
-	go func() {
-		mu.Lock()
-		x = 42
-		mu.Unlock()
-		ch <- true
-	}()
-	x = func(mu *sync.Mutex) int {
-		mu.Lock()
-		return 43
-	}(&mu)
-	mu.Unlock()
-	<-ch
-}
-
-func TestRaceStructInit(t *testing.T) {
-	type X struct {
-		x, y int
-	}
-	c := make(chan bool, 1)
-	y := 0
-	go func() {
-		y = 42
-		c <- true
-	}()
-	x := X{x: y}
-	_ = x
-	<-c
-}
-
-func TestRaceArrayInit(t *testing.T) {
-	c := make(chan bool, 1)
-	y := 0
-	go func() {
-		y = 42
-		c <- true
-	}()
-	x := []int{0, y, 42}
-	_ = x
-	<-c
-}
-
-func TestRaceMapInit(t *testing.T) {
-	c := make(chan bool, 1)
-	y := 0
-	go func() {
-		y = 42
-		c <- true
-	}()
-	x := map[int]int{0: 42, y: 42}
-	_ = x
-	<-c
-}
-
-func TestRaceMapInit2(t *testing.T) {
-	c := make(chan bool, 1)
-	y := 0
-	go func() {
-		y = 42
-		c <- true
-	}()
-	x := map[int]int{0: 42, 42: y}
-	_ = x
-	<-c
-}
-
-type Inter interface {
-	Foo(x int)
-}
-type InterImpl struct {
-	x, y int
-}
-
-func (p InterImpl) Foo(x int) {
-	// prevent inlining
-	z := 42
-	x = 85
-	y := x / z
-	z = y * z
-	x = z * y
-	_, _, _ = x, y, z
-}
-
-type InterImpl2 InterImpl
-
-func (p *InterImpl2) Foo(x int) {
-	if p == nil {
-		InterImpl{}.Foo(x)
-	}
-	InterImpl(*p).Foo(x)
-}
-
-func TestRaceInterCall(t *testing.T) {
-	c := make(chan bool, 1)
-	p := InterImpl{}
-	var x Inter = p
-	go func() {
-		p2 := InterImpl{}
-		x = p2
-		c <- true
-	}()
-	x.Foo(0)
-	<-c
-}
-
-func TestRaceInterCall2(t *testing.T) {
-	c := make(chan bool, 1)
-	p := InterImpl{}
-	var x Inter = p
-	z := 0
-	go func() {
-		z = 42
-		c <- true
-	}()
-	x.Foo(z)
-	<-c
-}
-
-func TestRaceFuncCall(t *testing.T) {
-	c := make(chan bool, 1)
-	f := func(x, y int) {}
-	x, y := 0, 0
-	go func() {
-		y = 42
-		c <- true
-	}()
-	f(x, y)
-	<-c
-}
-
-func TestRaceMethodCall(t *testing.T) {
-	c := make(chan bool, 1)
-	i := InterImpl{}
-	x := 0
-	go func() {
-		x = 42
-		c <- true
-	}()
-	i.Foo(x)
-	<-c
-}
-
-func TestRaceMethodCall2(t *testing.T) {
-	c := make(chan bool, 1)
-	i := &InterImpl{}
-	go func() {
-		i = &InterImpl{}
-		c <- true
-	}()
-	i.Foo(0)
-	<-c
-}
-
-// Method value with concrete value receiver.
-func TestRaceMethodValue(t *testing.T) {
-	c := make(chan bool, 1)
-	i := InterImpl{}
-	go func() {
-		i = InterImpl{}
-		c <- true
-	}()
-	_ = i.Foo
-	<-c
-}
-
-// Method value with interface receiver.
-func TestRaceMethodValue2(t *testing.T) {
-	c := make(chan bool, 1)
-	var i Inter = InterImpl{}
-	go func() {
-		i = InterImpl{}
-		c <- true
-	}()
-	_ = i.Foo
-	<-c
-}
-
-// Method value with implicit dereference.
-func TestRaceMethodValue3(t *testing.T) {
-	c := make(chan bool, 1)
-	i := &InterImpl{}
-	go func() {
-		*i = InterImpl{}
-		c <- true
-	}()
-	_ = i.Foo // dereferences i.
-	<-c
-}
-
-// Method value implicitly taking receiver address.
-func TestNoRaceMethodValue(t *testing.T) {
-	c := make(chan bool, 1)
-	i := InterImpl2{}
-	go func() {
-		i = InterImpl2{}
-		c <- true
-	}()
-	_ = i.Foo // takes the address of i only.
-	<-c
-}
-
-func TestRacePanicArg(t *testing.T) {
-	c := make(chan bool, 1)
-	err := errors.New("err")
-	go func() {
-		err = errors.New("err2")
-		c <- true
-	}()
-	defer func() {
-		recover()
-		<-c
-	}()
-	panic(err)
-}
-
-func TestRaceDeferArg(t *testing.T) {
-	c := make(chan bool, 1)
-	x := 0
-	go func() {
-		x = 42
-		c <- true
-	}()
-	func() {
-		defer func(x int) {
-		}(x)
-	}()
-	<-c
-}
-
-type DeferT int
-
-func (d DeferT) Foo() {
-}
-
-func TestRaceDeferArg2(t *testing.T) {
-	c := make(chan bool, 1)
-	var x DeferT
-	go func() {
-		var y DeferT
-		x = y
-		c <- true
-	}()
-	func() {
-		defer x.Foo()
-	}()
-	<-c
-}
-
-func TestNoRaceAddrExpr(t *testing.T) {
-	c := make(chan bool, 1)
-	x := 0
-	go func() {
-		x = 42
-		c <- true
-	}()
-	_ = &x
-	<-c
-}
-
-type AddrT struct {
-	_ [256]byte
-	x int
-}
-
-type AddrT2 struct {
-	_ [512]byte
-	p *AddrT
-}
-
-func TestRaceAddrExpr(t *testing.T) {
-	c := make(chan bool, 1)
-	a := AddrT2{p: &AddrT{x: 42}}
-	go func() {
-		a.p = &AddrT{x: 43}
-		c <- true
-	}()
-	_ = &a.p.x
-	<-c
-}
-
-func TestRaceTypeAssert(t *testing.T) {
-	c := make(chan bool, 1)
-	x := 0
-	var i interface{} = x
-	go func() {
-		y := 0
-		i = y
-		c <- true
-	}()
-	_ = i.(int)
-	<-c
-}
-
-func TestRaceBlockAs(t *testing.T) {
-	c := make(chan bool, 1)
-	var x, y int
-	go func() {
-		x = 42
-		c <- true
-	}()
-	x, y = y, x
-	<-c
-}
-
-func TestRaceSliceSlice(t *testing.T) {
-	c := make(chan bool, 1)
-	x := make([]int, 10)
-	go func() {
-		x = make([]int, 20)
-		c <- true
-	}()
-	_ = x[2:3]
-	<-c
-}
-
-func TestRaceSliceSlice2(t *testing.T) {
-	c := make(chan bool, 1)
-	x := make([]int, 10)
-	i := 2
-	go func() {
-		i = 3
-		c <- true
-	}()
-	_ = x[i:4]
-	<-c
-}
-
-func TestRaceSliceString(t *testing.T) {
-	c := make(chan bool, 1)
-	x := "hello"
-	go func() {
-		x = "world"
-		c <- true
-	}()
-	_ = x[2:3]
-	<-c
-}
-
-func TestRaceSliceStruct(t *testing.T) {
-	type X struct {
-		x, y int
-	}
-	c := make(chan bool, 1)
-	x := make([]X, 10)
-	go func() {
-		y := make([]X, 10)
-		copy(y, x)
-		c <- true
-	}()
-	x[1].y = 42
-	<-c
-}
-
-func TestRaceAppendSliceStruct(t *testing.T) {
-	type X struct {
-		x, y int
-	}
-	c := make(chan bool, 1)
-	x := make([]X, 10)
-	go func() {
-		y := make([]X, 0, 10)
-		y = append(y, x...)
-		c <- true
-	}()
-	x[1].y = 42
-	<-c
-}
-
-func TestRaceStructInd(t *testing.T) {
-	c := make(chan bool, 1)
-	type Item struct {
-		x, y int
-	}
-	i := Item{}
-	go func(p *Item) {
-		*p = Item{}
-		c <- true
-	}(&i)
-	i.y = 42
-	<-c
-}
-
-func TestRaceAsFunc1(t *testing.T) {
-	var s []byte
-	c := make(chan bool, 1)
-	go func() {
-		var err error
-		s, err = func() ([]byte, error) {
-			t := []byte("hello world")
-			return t, nil
-		}()
-		c <- true
-		_ = err
-	}()
-	_ = string(s)
-	<-c
-}
-
-func TestRaceAsFunc2(t *testing.T) {
-	c := make(chan bool, 1)
-	x := 0
-	go func() {
-		func(x int) {
-		}(x)
-		c <- true
-	}()
-	x = 42
-	<-c
-}
-
-func TestRaceAsFunc3(t *testing.T) {
-	c := make(chan bool, 1)
-	var mu sync.Mutex
-	x := 0
-	go func() {
-		func(x int) {
-			mu.Lock()
-		}(x) // Read of x must be outside of the mutex.
-		mu.Unlock()
-		c <- true
-	}()
-	mu.Lock()
-	x = 42
-	mu.Unlock()
-	<-c
-}
-
-func TestNoRaceAsFunc4(t *testing.T) {
-	c := make(chan bool, 1)
-	var mu sync.Mutex
-	x := 0
-	go func() {
-		x = func() int { // Write of x must be under the mutex.
-			mu.Lock()
-			return 42
-		}()
-		mu.Unlock()
-		c <- true
-	}()
-	mu.Lock()
-	x = 42
-	mu.Unlock()
-	<-c
-}
-
-func TestRaceHeapParam(t *testing.T) {
-	x := func() (x int) {
-		go func() {
-			x = 42
-		}()
-		return
-	}()
-	_ = x
-}
-
-func TestNoRaceEmptyStruct(t *testing.T) {
-	type Empty struct{}
-	type X struct {
-		y int64
-		Empty
-	}
-	type Y struct {
-		x X
-		y int64
-	}
-	c := make(chan X)
-	var y Y
-	go func() {
-		x := y.x
-		c <- x
-	}()
-	y.y = 42
-	<-c
-}
-
-func TestRaceNestedStruct(t *testing.T) {
-	type X struct {
-		x, y int
-	}
-	type Y struct {
-		x X
-	}
-	c := make(chan Y)
-	var y Y
-	go func() {
-		c <- y
-	}()
-	y.x.y = 42
-	<-c
-}
-
-func TestRaceIssue5567(t *testing.T) {
-	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4))
-	in := make(chan []byte)
-	res := make(chan error)
-	go func() {
-		var err error
-		defer func() {
-			close(in)
-			res <- err
-		}()
-		path := "mop_test.go"
-		f, err := os.Open(path)
-		if err != nil {
-			return
-		}
-		defer f.Close()
-		var n, total int
-		b := make([]byte, 17) // the race is on b buffer
-		for err == nil {
-			n, err = f.Read(b)
-			total += n
-			if n > 0 {
-				in <- b[:n]
-			}
-		}
-		if err == io.EOF {
-			err = nil
-		}
-	}()
-	h := sha1.New()
-	for b := range in {
-		h.Write(b)
-	}
-	_ = h.Sum(nil)
-	err := <-res
-	if err != nil {
-		t.Fatal(err)
-	}
-}
-
-func TestRaceIssue5654(t *testing.T) {
-	text := `Friends, Romans, countrymen, lend me your ears;
-I come to bury Caesar, not to praise him.
-The evil that men do lives after them;
-The good is oft interred with their bones;
-So let it be with Caesar. The noble Brutus
-Hath told you Caesar was ambitious:
-If it were so, it was a grievous fault,
-And grievously hath Caesar answer'd it.
-Here, under leave of Brutus and the rest -
-For Brutus is an honourable man;
-So are they all, all honourable men -
-Come I to speak in Caesar's funeral.
-He was my friend, faithful and just to me:
-But Brutus says he was ambitious;
-And Brutus is an honourable man.`
-
-	data := bytes.NewBufferString(text)
-	in := make(chan []byte)
-
-	go func() {
-		buf := make([]byte, 16)
-		var n int
-		var err error
-		for ; err == nil; n, err = data.Read(buf) {
-			in <- buf[:n]
-		}
-		close(in)
-	}()
-	res := ""
-	for s := range in {
-		res += string(s)
-	}
-	_ = res
-}
-
-type Base int
-
-func (b *Base) Foo() int {
-	return 42
-}
-
-func (b Base) Bar() int {
-	return int(b)
-}
-
-func TestNoRaceMethodThunk(t *testing.T) {
-	type Derived struct {
-		pad int
-		Base
-	}
-	var d Derived
-	done := make(chan bool)
-	go func() {
-		_ = d.Foo()
-		done <- true
-	}()
-	d = Derived{}
-	<-done
-}
-
-func TestRaceMethodThunk(t *testing.T) {
-	type Derived struct {
-		pad int
-		*Base
-	}
-	var d Derived
-	done := make(chan bool)
-	go func() {
-		_ = d.Foo()
-		done <- true
-	}()
-	d = Derived{}
-	<-done
-}
-
-func TestRaceMethodThunk2(t *testing.T) {
-	type Derived struct {
-		pad int
-		Base
-	}
-	var d Derived
-	done := make(chan bool)
-	go func() {
-		_ = d.Bar()
-		done <- true
-	}()
-	d = Derived{}
-	<-done
-}
-
-func TestRaceMethodThunk3(t *testing.T) {
-	type Derived struct {
-		pad int
-		*Base
-	}
-	var d Derived
-	d.Base = new(Base)
-	done := make(chan bool)
-	go func() {
-		_ = d.Bar()
-		done <- true
-	}()
-	d.Base = new(Base)
-	<-done
-}
-
-func TestRaceMethodThunk4(t *testing.T) {
-	type Derived struct {
-		pad int
-		*Base
-	}
-	var d Derived
-	d.Base = new(Base)
-	done := make(chan bool)
-	go func() {
-		_ = d.Bar()
-		done <- true
-	}()
-	*(*int)(d.Base) = 42
-	<-done
-}
-
-func TestNoRaceTinyAlloc(t *testing.T) {
-	const P = 4
-	const N = 1e6
-	var tinySink *byte
-	done := make(chan bool)
-	for p := 0; p < P; p++ {
-		go func() {
-			for i := 0; i < N; i++ {
-				var b byte
-				if b != 0 {
-					tinySink = &b // make it heap allocated
-				}
-				b = 42
-			}
-			done <- true
-		}()
-	}
-	for p := 0; p < P; p++ {
-		<-done
-	}
-}
diff --git a/src/pkg/runtime/race/testdata/slice_test.go b/src/pkg/runtime/race/testdata/slice_test.go
deleted file mode 100644
index c85df5e..0000000
--- a/src/pkg/runtime/race/testdata/slice_test.go
+++ /dev/null
@@ -1,485 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package race_test
-
-import (
-	"testing"
-)
-
-func TestRaceSliceRW(t *testing.T) {
-	ch := make(chan bool, 1)
-	a := make([]int, 2)
-	go func() {
-		a[1] = 1
-		ch <- true
-	}()
-	_ = a[1]
-	<-ch
-}
-
-func TestNoRaceSliceRW(t *testing.T) {
-	ch := make(chan bool, 1)
-	a := make([]int, 2)
-	go func() {
-		a[0] = 1
-		ch <- true
-	}()
-	_ = a[1]
-	<-ch
-}
-
-func TestRaceSliceWW(t *testing.T) {
-	a := make([]int, 10)
-	ch := make(chan bool, 1)
-	go func() {
-		a[1] = 1
-		ch <- true
-	}()
-	a[1] = 2
-	<-ch
-}
-
-func TestNoRaceArrayWW(t *testing.T) {
-	var a [5]int
-	ch := make(chan bool, 1)
-	go func() {
-		a[0] = 1
-		ch <- true
-	}()
-	a[1] = 2
-	<-ch
-}
-
-func TestRaceArrayWW(t *testing.T) {
-	var a [5]int
-	ch := make(chan bool, 1)
-	go func() {
-		a[1] = 1
-		ch <- true
-	}()
-	a[1] = 2
-	<-ch
-}
-
-func TestNoRaceSliceWriteLen(t *testing.T) {
-	ch := make(chan bool, 1)
-	a := make([]bool, 1)
-	go func() {
-		a[0] = true
-		ch <- true
-	}()
-	_ = len(a)
-	<-ch
-}
-
-func TestNoRaceSliceWriteCap(t *testing.T) {
-	ch := make(chan bool, 1)
-	a := make([]uint64, 100)
-	go func() {
-		a[50] = 123
-		ch <- true
-	}()
-	_ = cap(a)
-	<-ch
-}
-
-func TestRaceSliceCopyRead(t *testing.T) {
-	ch := make(chan bool, 1)
-	a := make([]int, 10)
-	b := make([]int, 10)
-	go func() {
-		_ = a[5]
-		ch <- true
-	}()
-	copy(a, b)
-	<-ch
-}
-
-func TestNoRaceSliceWriteCopy(t *testing.T) {
-	ch := make(chan bool, 1)
-	a := make([]int, 10)
-	b := make([]int, 10)
-	go func() {
-		a[5] = 1
-		ch <- true
-	}()
-	copy(a[:5], b[:5])
-	<-ch
-}
-
-func TestRaceSliceCopyWrite2(t *testing.T) {
-	ch := make(chan bool, 1)
-	a := make([]int, 10)
-	b := make([]int, 10)
-	go func() {
-		b[5] = 1
-		ch <- true
-	}()
-	copy(a, b)
-	<-ch
-}
-
-func TestRaceSliceCopyWrite3(t *testing.T) {
-	ch := make(chan bool, 1)
-	a := make([]byte, 10)
-	go func() {
-		a[7] = 1
-		ch <- true
-	}()
-	copy(a, "qwertyqwerty")
-	<-ch
-}
-
-func TestNoRaceSliceCopyRead(t *testing.T) {
-	ch := make(chan bool, 1)
-	a := make([]int, 10)
-	b := make([]int, 10)
-	go func() {
-		_ = b[5]
-		ch <- true
-	}()
-	copy(a, b)
-	<-ch
-}
-
-func TestNoRaceSliceWriteSlice2(t *testing.T) {
-	ch := make(chan bool, 1)
-	a := make([]float64, 10)
-	go func() {
-		a[2] = 1.0
-		ch <- true
-	}()
-	_ = a[0:5]
-	<-ch
-}
-
-func TestRaceSliceWriteSlice(t *testing.T) {
-	ch := make(chan bool, 1)
-	a := make([]float64, 10)
-	go func() {
-		a[2] = 1.0
-		ch <- true
-	}()
-	a = a[5:10]
-	<-ch
-}
-
-func TestNoRaceSliceWriteSlice(t *testing.T) {
-	ch := make(chan bool, 1)
-	a := make([]float64, 10)
-	go func() {
-		a[2] = 1.0
-		ch <- true
-	}()
-	_ = a[5:10]
-	<-ch
-}
-
-func TestNoRaceSliceLenCap(t *testing.T) {
-	ch := make(chan bool, 1)
-	a := make([]struct{}, 10)
-	go func() {
-		_ = len(a)
-		ch <- true
-	}()
-	_ = cap(a)
-	<-ch
-}
-
-func TestNoRaceStructSlicesRangeWrite(t *testing.T) {
-	type Str struct {
-		a []int
-		b []int
-	}
-	ch := make(chan bool, 1)
-	var s Str
-	s.a = make([]int, 10)
-	s.b = make([]int, 10)
-	go func() {
-		for _ = range s.a {
-		}
-		ch <- true
-	}()
-	s.b[5] = 5
-	<-ch
-}
-
-func TestRaceSliceDifferent(t *testing.T) {
-	c := make(chan bool, 1)
-	s := make([]int, 10)
-	s2 := s
-	go func() {
-		s[3] = 3
-		c <- true
-	}()
-	// false negative because s2 is PAUTO w/o PHEAP
-	// so we do not instrument it
-	s2[3] = 3
-	<-c
-}
-
-func TestRaceSliceRangeWrite(t *testing.T) {
-	c := make(chan bool, 1)
-	s := make([]int, 10)
-	go func() {
-		s[3] = 3
-		c <- true
-	}()
-	for _, v := range s {
-		_ = v
-	}
-	<-c
-}
-
-func TestNoRaceSliceRangeWrite(t *testing.T) {
-	c := make(chan bool, 1)
-	s := make([]int, 10)
-	go func() {
-		s[3] = 3
-		c <- true
-	}()
-	for _ = range s {
-	}
-	<-c
-}
-
-func TestRaceSliceRangeAppend(t *testing.T) {
-	c := make(chan bool, 1)
-	s := make([]int, 10)
-	go func() {
-		s = append(s, 3)
-		c <- true
-	}()
-	for _ = range s {
-	}
-	<-c
-}
-
-func TestNoRaceSliceRangeAppend(t *testing.T) {
-	c := make(chan bool, 1)
-	s := make([]int, 10)
-	go func() {
-		_ = append(s, 3)
-		c <- true
-	}()
-	for _ = range s {
-	}
-	<-c
-}
-
-func TestRaceSliceVarWrite(t *testing.T) {
-	c := make(chan bool, 1)
-	s := make([]int, 10)
-	go func() {
-		s[3] = 3
-		c <- true
-	}()
-	s = make([]int, 20)
-	<-c
-}
-
-func TestRaceSliceVarRead(t *testing.T) {
-	c := make(chan bool, 1)
-	s := make([]int, 10)
-	go func() {
-		_ = s[3]
-		c <- true
-	}()
-	s = make([]int, 20)
-	<-c
-}
-
-func TestRaceSliceVarRange(t *testing.T) {
-	c := make(chan bool, 1)
-	s := make([]int, 10)
-	go func() {
-		for _ = range s {
-		}
-		c <- true
-	}()
-	s = make([]int, 20)
-	<-c
-}
-
-func TestRaceSliceVarAppend(t *testing.T) {
-	c := make(chan bool, 1)
-	s := make([]int, 10)
-	go func() {
-		_ = append(s, 10)
-		c <- true
-	}()
-	s = make([]int, 20)
-	<-c
-}
-
-func TestRaceSliceVarCopy(t *testing.T) {
-	c := make(chan bool, 1)
-	s := make([]int, 10)
-	go func() {
-		s2 := make([]int, 10)
-		copy(s, s2)
-		c <- true
-	}()
-	s = make([]int, 20)
-	<-c
-}
-
-func TestRaceSliceVarCopy2(t *testing.T) {
-	c := make(chan bool, 1)
-	s := make([]int, 10)
-	go func() {
-		s2 := make([]int, 10)
-		copy(s2, s)
-		c <- true
-	}()
-	s = make([]int, 20)
-	<-c
-}
-
-func TestRaceSliceAppend(t *testing.T) {
-	c := make(chan bool, 1)
-	s := make([]int, 10, 20)
-	go func() {
-		_ = append(s, 1)
-		c <- true
-	}()
-	_ = append(s, 2)
-	<-c
-}
-
-func TestRaceSliceAppendWrite(t *testing.T) {
-	c := make(chan bool, 1)
-	s := make([]int, 10)
-	go func() {
-		_ = append(s, 1)
-		c <- true
-	}()
-	s[0] = 42
-	<-c
-}
-
-func TestRaceSliceAppendSlice(t *testing.T) {
-	c := make(chan bool, 1)
-	s := make([]int, 10)
-	go func() {
-		s2 := make([]int, 10)
-		_ = append(s, s2...)
-		c <- true
-	}()
-	s[0] = 42
-	<-c
-}
-
-func TestRaceSliceAppendSlice2(t *testing.T) {
-	c := make(chan bool, 1)
-	s := make([]int, 10)
-	s2foobar := make([]int, 10)
-	go func() {
-		_ = append(s, s2foobar...)
-		c <- true
-	}()
-	s2foobar[5] = 42
-	<-c
-}
-
-func TestRaceSliceAppendString(t *testing.T) {
-	c := make(chan bool, 1)
-	s := make([]byte, 10)
-	go func() {
-		_ = append(s, "qwerty"...)
-		c <- true
-	}()
-	s[0] = 42
-	<-c
-}
-
-func TestNoRaceSliceIndexAccess(t *testing.T) {
-	c := make(chan bool, 1)
-	s := make([]int, 10)
-	v := 0
-	go func() {
-		_ = v
-		c <- true
-	}()
-	s[v] = 1
-	<-c
-}
-
-func TestNoRaceSliceIndexAccess2(t *testing.T) {
-	c := make(chan bool, 1)
-	s := make([]int, 10)
-	v := 0
-	go func() {
-		_ = v
-		c <- true
-	}()
-	_ = s[v]
-	<-c
-}
-
-func TestRaceSliceIndexAccess(t *testing.T) {
-	c := make(chan bool, 1)
-	s := make([]int, 10)
-	v := 0
-	go func() {
-		v = 1
-		c <- true
-	}()
-	s[v] = 1
-	<-c
-}
-
-func TestRaceSliceIndexAccess2(t *testing.T) {
-	c := make(chan bool, 1)
-	s := make([]int, 10)
-	v := 0
-	go func() {
-		v = 1
-		c <- true
-	}()
-	_ = s[v]
-	<-c
-}
-
-func TestRaceSliceByteToString(t *testing.T) {
-	c := make(chan string)
-	s := make([]byte, 10)
-	go func() {
-		c <- string(s)
-	}()
-	s[0] = 42
-	<-c
-}
-
-func TestRaceSliceRuneToString(t *testing.T) {
-	c := make(chan string)
-	s := make([]rune, 10)
-	go func() {
-		c <- string(s)
-	}()
-	s[9] = 42
-	<-c
-}
-
-func TestRaceConcatString(t *testing.T) {
-	s := "hello"
-	c := make(chan string, 1)
-	go func() {
-		c <- s + " world"
-	}()
-	s = "world"
-	<-c
-}
-
-func TestRaceCompareString(t *testing.T) {
-	s1 := "hello"
-	s2 := "world"
-	c := make(chan bool, 1)
-	go func() {
-		c <- s1 == s2
-	}()
-	s1 = s2
-	<-c
-}
diff --git a/src/pkg/runtime/race0.c b/src/pkg/runtime/race0.c
deleted file mode 100644
index eddb0be..0000000
--- a/src/pkg/runtime/race0.c
+++ /dev/null
@@ -1,124 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Stub implementation of the race detector API.
-// +build !race
-
-#include "runtime.h"
-
-uintptr
-runtime·raceinit(void)
-{
-	return 0;
-}
-
-void
-runtime·racefini(void)
-{
-}
-
-
-void
-runtime·racemapshadow(void *addr, uintptr size)
-{
-	USED(addr);
-	USED(size);
-}
-
-void
-runtime·racewritepc(void *addr, void *callpc, void *pc)
-{
-	USED(addr);
-	USED(callpc);
-	USED(pc);
-}
-
-void
-runtime·racereadpc(void *addr, void *callpc, void *pc)
-{
-	USED(addr);
-	USED(callpc);
-	USED(pc);
-}
-
-void
-runtime·racewriterangepc(void *addr, uintptr sz, void *callpc, void *pc)
-{
-	USED(addr);
-	USED(sz);
-	USED(callpc);
-	USED(pc);
-}
-
-void
-runtime·racereadrangepc(void *addr, uintptr sz, void *callpc, void *pc)
-{
-	USED(addr);
-	USED(sz);
-	USED(callpc);
-	USED(pc);
-}
-
-void
-runtime·raceacquire(void *addr)
-{
-	USED(addr);
-}
-
-void
-runtime·raceacquireg(G *gp, void *addr)
-{
-	USED(gp);
-	USED(addr);
-}
-
-void
-runtime·racerelease(void *addr)
-{
-	USED(addr);
-}
-
-void
-runtime·racereleaseg(G *gp, void *addr)
-{
-	USED(gp);
-	USED(addr);
-}
-
-void
-runtime·racereleasemerge(void *addr)
-{
-	USED(addr);
-}
-
-void
-runtime·racereleasemergeg(G *gp, void *addr)
-{
-	USED(gp);
-	USED(addr);
-}
-
-void
-runtime·racefingo(void)
-{
-}
-
-void
-runtime·racemalloc(void *p, uintptr sz)
-{
-	USED(p);
-	USED(sz);
-}
-
-uintptr
-runtime·racegostart(void *pc)
-{
-	USED(pc);
-	return 0;
-}
-
-void
-runtime·racegoend(void)
-{
-}
diff --git a/src/pkg/runtime/race_amd64.s b/src/pkg/runtime/race_amd64.s
deleted file mode 100644
index d60cf89..0000000
--- a/src/pkg/runtime/race_amd64.s
+++ /dev/null
@@ -1,244 +0,0 @@
-// Copyright 2013 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build race
-
-#include "zasm_GOOS_GOARCH.h"
-#include "funcdata.h"
-#include "../../cmd/ld/textflag.h"
-
-// The following thunks allow calling the gcc-compiled race runtime directly
-// from Go code without going all the way through cgo.
-// First, it's much faster (up to 50% speedup for real Go programs).
-// Second, it eliminates race-related special cases from cgocall and scheduler.
-// Third, in long-term it will allow to remove cyclic runtime/race dependency on cmd/go.
-
-// A brief recap of the amd64 calling convention.
-// Arguments are passed in DI, SI, DX, CX, R8, R9, the rest is on stack.
-// Callee-saved registers are: BX, BP, R12-R15.
-// SP must be 16-byte aligned.
-// On Windows:
-// Arguments are passed in CX, DX, R8, R9, the rest is on stack.
-// Callee-saved registers are: BX, BP, DI, SI, R12-R15.
-// SP must be 16-byte aligned. Windows also requires "stack-backing" for the 4 register arguments:
-// http://msdn.microsoft.com/en-us/library/ms235286.aspx
-// We do not do this, because it seems to be intended for vararg/unprototyped functions.
-// Gcc-compiled race runtime does not try to use that space.
-
-#ifdef GOOS_windows
-#define RARG0 CX
-#define RARG1 DX
-#define RARG2 R8
-#define RARG3 R9
-#else
-#define RARG0 DI
-#define RARG1 SI
-#define RARG2 DX
-#define RARG3 CX
-#endif
-
-// func runtime·raceread(addr uintptr)
-// Called from instrumented code.
-TEXT	runtime·raceread(SB), NOSPLIT, $0-8
-	MOVQ	addr+0(FP), RARG1
-	MOVQ	(SP), RARG2
-	// void __tsan_read(ThreadState *thr, void *addr, void *pc);
-	MOVQ	$__tsan_read(SB), AX
-	JMP	racecalladdr<>(SB)
-
-// func runtime·RaceRead(addr uintptr)
-TEXT	runtime·RaceRead(SB), NOSPLIT, $0-8
-	// This needs to be a tail call, because raceread reads caller pc.
-	JMP	runtime·raceread(SB)
-
-// void runtime·racereadpc(void *addr, void *callpc, void *pc)
-TEXT	runtime·racereadpc(SB), NOSPLIT, $0-24
-	MOVQ	addr+0(FP), RARG1
-	MOVQ	callpc+8(FP), RARG2
-	MOVQ	pc+16(FP), RARG3
-	// void __tsan_read_pc(ThreadState *thr, void *addr, void *callpc, void *pc);
-	MOVQ	$__tsan_read_pc(SB), AX
-	JMP	racecalladdr<>(SB)
-
-// func runtime·racewrite(addr uintptr)
-// Called from instrumented code.
-TEXT	runtime·racewrite(SB), NOSPLIT, $0-8
-	MOVQ	addr+0(FP), RARG1
-	MOVQ	(SP), RARG2
-	// void __tsan_write(ThreadState *thr, void *addr, void *pc);
-	MOVQ	$__tsan_write(SB), AX
-	JMP	racecalladdr<>(SB)
-
-// func runtime·RaceWrite(addr uintptr)
-TEXT	runtime·RaceWrite(SB), NOSPLIT, $0-8
-	// This needs to be a tail call, because racewrite reads caller pc.
-	JMP	runtime·racewrite(SB)
-
-// void runtime·racewritepc(void *addr, void *callpc, void *pc)
-TEXT	runtime·racewritepc(SB), NOSPLIT, $0-24
-	MOVQ	addr+0(FP), RARG1
-	MOVQ	callpc+8(FP), RARG2
-	MOVQ	cp+16(FP), RARG3
-	// void __tsan_write_pc(ThreadState *thr, void *addr, void *callpc, void *pc);
-	MOVQ	$__tsan_write_pc(SB), AX
-	JMP	racecalladdr<>(SB)
-
-// func runtime·racereadrange(addr, size uintptr)
-// Called from instrumented code.
-TEXT	runtime·racereadrange(SB), NOSPLIT, $0-16
-	MOVQ	addr+0(FP), RARG1
-	MOVQ	size+8(FP), RARG2
-	MOVQ	(SP), RARG3
-	// void __tsan_read_range(ThreadState *thr, void *addr, uintptr size, void *pc);
-	MOVQ	$__tsan_read_range(SB), AX
-	JMP	racecalladdr<>(SB)
-
-// func runtime·RaceReadRange(addr, size uintptr)
-TEXT	runtime·RaceReadRange(SB), NOSPLIT, $0-16
-	// This needs to be a tail call, because racereadrange reads caller pc.
-	JMP	runtime·racereadrange(SB)
-
-// void runtime·racereadrangepc1(void *addr, uintptr sz, void *pc)
-TEXT	runtime·racereadrangepc1(SB), NOSPLIT, $0-24
-	MOVQ	addr+0(FP), RARG1
-	MOVQ	size+8(FP), RARG2
-	MOVQ	pc+16(FP), RARG3
-	// void __tsan_read_range(ThreadState *thr, void *addr, uintptr size, void *pc);
-	MOVQ	$__tsan_read_range(SB), AX
-	JMP	racecalladdr<>(SB)
-
-// func runtime·racewriterange(addr, size uintptr)
-// Called from instrumented code.
-TEXT	runtime·racewriterange(SB), NOSPLIT, $0-16
-	MOVQ	addr+0(FP), RARG1
-	MOVQ	size+8(FP), RARG2
-	MOVQ	(SP), RARG3
-	// void __tsan_write_range(ThreadState *thr, void *addr, uintptr size, void *pc);
-	MOVQ	$__tsan_write_range(SB), AX
-	JMP	racecalladdr<>(SB)
-
-// func runtime·RaceWriteRange(addr, size uintptr)
-TEXT	runtime·RaceWriteRange(SB), NOSPLIT, $0-16
-	// This needs to be a tail call, because racewriterange reads caller pc.
-	JMP	runtime·racewriterange(SB)
-
-// void runtime·racewriterangepc1(void *addr, uintptr sz, void *pc)
-TEXT	runtime·racewriterangepc1(SB), NOSPLIT, $0-24
-	MOVQ	addr+0(FP), RARG1
-	MOVQ	size+8(FP), RARG2
-	MOVQ	pc+16(FP), RARG3
-	// void __tsan_write_range(ThreadState *thr, void *addr, uintptr size, void *pc);
-	MOVQ	$__tsan_write_range(SB), AX
-	JMP	racecalladdr<>(SB)
-
-// If addr (RARG1) is out of range, do nothing.
-// Otherwise, setup goroutine context and invoke racecall. Other arguments already set.
-TEXT	racecalladdr<>(SB), NOSPLIT, $0-0
-	get_tls(R12)
-	MOVQ	g(R12), R14
-	MOVQ	g_racectx(R14), RARG0	// goroutine context
-	// Check that addr is within [arenastart, arenaend) or within [noptrdata, enoptrbss).
-	CMPQ	RARG1, runtime·racearenastart(SB)
-	JB	racecalladdr_data
-	CMPQ	RARG1, runtime·racearenaend(SB)
-	JB	racecalladdr_call
-racecalladdr_data:
-	CMPQ	RARG1, $noptrdata(SB)
-	JB	racecalladdr_ret
-	CMPQ	RARG1, $enoptrbss(SB)
-	JAE	racecalladdr_ret
-racecalladdr_call:
-	MOVQ	AX, AX		// w/o this 6a miscompiles this function
-	JMP	racecall<>(SB)
-racecalladdr_ret:
-	RET
-
-// func runtime·racefuncenter(pc uintptr)
-// Called from instrumented code.
-TEXT	runtime·racefuncenter(SB), NOSPLIT, $0-8
-	MOVQ	DX, R15		// save function entry context (for closures)
-	get_tls(R12)
-	MOVQ	g(R12), R14
-	MOVQ	g_racectx(R14), RARG0	// goroutine context
-	MOVQ	callpc+0(FP), RARG1
-	// void __tsan_func_enter(ThreadState *thr, void *pc);
-	MOVQ	$__tsan_func_enter(SB), AX
-	CALL	racecall<>(SB)
-	MOVQ	R15, DX	// restore function entry context
-	RET
-
-// func runtime·racefuncexit()
-// Called from instrumented code.
-TEXT	runtime·racefuncexit(SB), NOSPLIT, $0-0
-	get_tls(R12)
-	MOVQ	g(R12), R14
-	MOVQ	g_racectx(R14), RARG0	// goroutine context
-	// void __tsan_func_exit(ThreadState *thr);
-	MOVQ	$__tsan_func_exit(SB), AX
-	JMP	racecall<>(SB)
-
-// void runtime·racecall(void(*f)(...), ...)
-// Calls C function f from race runtime and passes up to 4 arguments to it.
-// The arguments are never heap-object-preserving pointers, so we pretend there are no arguments.
-TEXT	runtime·racecall(SB), NOSPLIT, $0-0
-	MOVQ	fn+0(FP), AX
-	MOVQ	arg0+8(FP), RARG0
-	MOVQ	arg1+16(FP), RARG1
-	MOVQ	arg2+24(FP), RARG2
-	MOVQ	arg3+32(FP), RARG3
-	JMP	racecall<>(SB)
-
-// Switches SP to g0 stack and calls (AX). Arguments already set.
-TEXT	racecall<>(SB), NOSPLIT, $0-0
-	get_tls(R12)
-	MOVQ	m(R12), R13
-	MOVQ	g(R12), R14
-	// Switch to g0 stack.
-	MOVQ	SP, R12		// callee-saved, preserved across the CALL
-	MOVQ	m_g0(R13), R10
-	CMPQ	R10, R14
-	JE	racecall_cont	// already on g0
-	MOVQ	(g_sched+gobuf_sp)(R10), SP
-racecall_cont:
-	ANDQ	$~15, SP	// alignment for gcc ABI
-	CALL	AX
-	MOVQ	R12, SP
-	RET
-
-// C->Go callback thunk that allows to call runtime·racesymbolize from C code.
-// Direct Go->C race call has only switched SP, finish g->g0 switch by setting correct g.
-// The overall effect of Go->C->Go call chain is similar to that of mcall.
-TEXT	runtime·racesymbolizethunk(SB), NOSPLIT, $56-8
-	// Save callee-saved registers (Go code won't respect that).
-	// This is superset of darwin/linux/windows registers.
-	PUSHQ	BX
-	PUSHQ	BP
-	PUSHQ	DI
-	PUSHQ	SI
-	PUSHQ	R12
-	PUSHQ	R13
-	PUSHQ	R14
-	PUSHQ	R15
-	// Set g = g0.
-	get_tls(R12)
-	MOVQ	m(R12), R13
-	MOVQ	m_g0(R13), R14
-	MOVQ	R14, g(R12)	// g = m->g0
-	MOVQ	RARG0, 0(SP)	// func arg
-	CALL	runtime·racesymbolize(SB)
-	// All registers are smashed after Go code, reload.
-	get_tls(R12)
-	MOVQ	m(R12), R13
-	MOVQ	m_curg(R13), R14
-	MOVQ	R14, g(R12)	// g = m->curg
-	// Restore callee-saved registers.
-	POPQ	R15
-	POPQ	R14
-	POPQ	R13
-	POPQ	R12
-	POPQ	SI
-	POPQ	DI
-	POPQ	BP
-	POPQ	BX
-	RET
diff --git a/src/pkg/runtime/rdebug.goc b/src/pkg/runtime/rdebug.goc
deleted file mode 100644
index 042b30a..0000000
--- a/src/pkg/runtime/rdebug.goc
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2013 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package runtime∕debug
-#include "runtime.h"
-#include "arch_GOARCH.h"
-#include "malloc.h"
-#include "stack.h"
-
-func setMaxStack(in int) (out int) {
-	out = runtime·maxstacksize;
-	runtime·maxstacksize = in;
-}
-
-func setGCPercent(in int) (out int) {
-	out = runtime·setgcpercent(in);
-}
-
-func setMaxThreads(in int) (out int) {
-	out = runtime·setmaxthreads(in);
-}
-
-func SetPanicOnFault(enabled bool) (old bool) {
-	old = g->paniconfault;
-	g->paniconfault = enabled;
-}
diff --git a/src/pkg/runtime/rt0_darwin_386.s b/src/pkg/runtime/rt0_darwin_386.s
deleted file mode 100644
index 4f85250..0000000
--- a/src/pkg/runtime/rt0_darwin_386.s
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../cmd/ld/textflag.h"
-
-TEXT _rt0_386_darwin(SB),NOSPLIT,$8
-	MOVL	8(SP), AX
-	LEAL	12(SP), BX
-	MOVL	AX, 0(SP)
-	MOVL	BX, 4(SP)
-	CALL	main(SB)
-	INT	$3
-
-TEXT main(SB),NOSPLIT,$0
-	JMP	_rt0_go(SB)
diff --git a/src/pkg/runtime/rt0_darwin_amd64.s b/src/pkg/runtime/rt0_darwin_amd64.s
deleted file mode 100644
index 8d2962b..0000000
--- a/src/pkg/runtime/rt0_darwin_amd64.s
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../cmd/ld/textflag.h"
-
-TEXT _rt0_amd64_darwin(SB),NOSPLIT,$-8
-	LEAQ	8(SP), SI // argv
-	MOVQ	0(SP), DI // argc
-	MOVQ	$main(SB), AX
-	JMP	AX
-
-TEXT main(SB),NOSPLIT,$-8
-	MOVQ	$_rt0_go(SB), AX
-	JMP	AX
diff --git a/src/pkg/runtime/rt0_dragonfly_386.s b/src/pkg/runtime/rt0_dragonfly_386.s
deleted file mode 100644
index b857f60..0000000
--- a/src/pkg/runtime/rt0_dragonfly_386.s
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../cmd/ld/textflag.h"
-
-TEXT _rt0_386_dragonfly(SB),NOSPLIT,$8
-	MOVL	8(SP), AX
-	LEAL	12(SP), BX
-	MOVL	AX, 0(SP)
-	MOVL	BX, 4(SP)
-	CALL	main(SB)
-	INT	$3
-
-TEXT main(SB),NOSPLIT,$0
-	JMP	_rt0_go(SB)
diff --git a/src/pkg/runtime/rt0_dragonfly_amd64.s b/src/pkg/runtime/rt0_dragonfly_amd64.s
deleted file mode 100644
index fc7e745..0000000
--- a/src/pkg/runtime/rt0_dragonfly_amd64.s
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../cmd/ld/textflag.h"
-
-TEXT _rt0_amd64_dragonfly(SB),NOSPLIT,$-8
-	LEAQ	8(DI), SI // argv
-	MOVQ	0(DI), DI // argc
-	MOVQ	$main(SB), AX
-	JMP	AX
-
-TEXT main(SB),NOSPLIT,$-8
-	MOVQ	$_rt0_go(SB), AX
-	JMP	AX
diff --git a/src/pkg/runtime/rt0_freebsd_386.s b/src/pkg/runtime/rt0_freebsd_386.s
deleted file mode 100644
index 758f7d2..0000000
--- a/src/pkg/runtime/rt0_freebsd_386.s
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../cmd/ld/textflag.h"
-
-TEXT _rt0_386_freebsd(SB),NOSPLIT,$8
-	MOVL	8(SP), AX
-	LEAL	12(SP), BX
-	MOVL	AX, 0(SP)
-	MOVL	BX, 4(SP)
-	CALL	main(SB)
-	INT	$3
-
-TEXT main(SB),NOSPLIT,$0
-	JMP	_rt0_go(SB)
diff --git a/src/pkg/runtime/rt0_freebsd_amd64.s b/src/pkg/runtime/rt0_freebsd_amd64.s
deleted file mode 100644
index 3cf7163..0000000
--- a/src/pkg/runtime/rt0_freebsd_amd64.s
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../cmd/ld/textflag.h"
-
-TEXT _rt0_amd64_freebsd(SB),NOSPLIT,$-8
-	LEAQ	8(DI), SI // argv
-	MOVQ	0(DI), DI // argc
-	MOVQ	$main(SB), AX
-	JMP	AX
-
-TEXT main(SB),NOSPLIT,$-8
-	MOVQ	$_rt0_go(SB), AX
-	JMP	AX
diff --git a/src/pkg/runtime/rt0_freebsd_arm.s b/src/pkg/runtime/rt0_freebsd_arm.s
deleted file mode 100644
index 56219f8..0000000
--- a/src/pkg/runtime/rt0_freebsd_arm.s
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../cmd/ld/textflag.h"
-
-// FreeBSD and Linux use the same linkage to main
-
-TEXT _rt0_arm_freebsd(SB),NOSPLIT,$-4
-	MOVW	(R13), R0	// argc
-	MOVW	$4(R13), R1		// argv
-	MOVM.DB.W [R0-R1], (R13)
-	B	_rt0_go(SB)
-
-TEXT main(SB),NOSPLIT,$-4
-	MOVM.DB.W [R0-R1], (R13)
-	MOVW	$_rt0_go(SB), R4
-	B		(R4)
diff --git a/src/pkg/runtime/rt0_linux_386.s b/src/pkg/runtime/rt0_linux_386.s
deleted file mode 100644
index c6f4159..0000000
--- a/src/pkg/runtime/rt0_linux_386.s
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../cmd/ld/textflag.h"
-
-TEXT _rt0_386_linux(SB),NOSPLIT,$8
-	MOVL	8(SP), AX
-	LEAL	12(SP), BX
-	MOVL	AX, 0(SP)
-	MOVL	BX, 4(SP)
-	CALL	runtime·linux_setup_vdso(SB)
-	CALL	main(SB)
-	INT	$3
-
-TEXT main(SB),NOSPLIT,$0
-	JMP	_rt0_go(SB)
-
-TEXT _fallback_vdso(SB),NOSPLIT,$0
-	INT	$0x80
-	RET
-
-DATA	runtime·_vdso(SB)/4, $_fallback_vdso(SB)
-GLOBL	runtime·_vdso(SB), $4
-
diff --git a/src/pkg/runtime/rt0_linux_amd64.s b/src/pkg/runtime/rt0_linux_amd64.s
deleted file mode 100644
index a887ced..0000000
--- a/src/pkg/runtime/rt0_linux_amd64.s
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../cmd/ld/textflag.h"
-
-TEXT _rt0_amd64_linux(SB),NOSPLIT,$-8
-	LEAQ	8(SP), SI // argv
-	MOVQ	0(SP), DI // argc
-	MOVQ	$main(SB), AX
-	JMP	AX
-
-TEXT main(SB),NOSPLIT,$-8
-	MOVQ	$_rt0_go(SB), AX
-	JMP	AX
diff --git a/src/pkg/runtime/rt0_linux_arm.s b/src/pkg/runtime/rt0_linux_arm.s
deleted file mode 100644
index 309fa2f..0000000
--- a/src/pkg/runtime/rt0_linux_arm.s
+++ /dev/null
@@ -1,91 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../cmd/ld/textflag.h"
-
-TEXT _rt0_arm_linux(SB),NOSPLIT,$-4
-	MOVW	(R13), R0	// argc
-	MOVW	$4(R13), R1		// argv
-	MOVW	$_rt0_arm_linux1(SB), R4
-	B		(R4)
-
-TEXT _rt0_arm_linux1(SB),NOSPLIT,$-4
-	// We first need to detect the kernel ABI, and warn the user
-	// if the system only supports OABI
-	// The strategy here is to call some EABI syscall to see if
-	// SIGILL is received.
-	// To catch SIGILL, we have to first setup sigaction, this is
-	// a chicken-and-egg problem, because we can't do syscall if
-	// we don't know the kernel ABI... Oh, not really, we can do
-	// syscall in Thumb mode.
-
-	// Save argc and argv
-	MOVM.DB.W [R0-R1], (R13)
-
-	// Thumb mode OABI check disabled because there are some
-	// EABI systems that do not support Thumb execution.
-	// We can run on them except for this check!
-
-	// // set up sa_handler
-	// MOVW	$bad_abi<>(SB), R0 // sa_handler
-	// MOVW	$0, R1 // sa_flags
-	// MOVW	$0, R2 // sa_restorer
-	// MOVW	$0, R3 // sa_mask
-	// MOVM.DB.W [R0-R3], (R13)
-	// MOVW	$4, R0 // SIGILL
-	// MOVW	R13, R1 // sa
-	// SUB	$16, R13
-	// MOVW	R13, R2 // old_sa
-	// MOVW	$8, R3 // c
-	// MOVW	$174, R7 // sys_sigaction
-	// BL	oabi_syscall<>(SB)
-
-	// do an EABI syscall
-	MOVW	$20, R7 // sys_getpid
-	SWI	$0 // this will trigger SIGILL on OABI systems
-	
-	// MOVW	$4, R0  // SIGILL
-	// MOVW	R13, R1 // sa
-	// MOVW	$0, R2 // old_sa
-	// MOVW	$8, R3 // c
-	// MOVW	$174, R7 // sys_sigaction
-	// SWI	$0 // restore signal handler
-	// ADD	$32, R13
-
-	SUB	$4, R13 // fake a stack frame for runtime·setup_auxv
-	BL	runtime·setup_auxv(SB)
-	ADD	$4, R13
-	B	_rt0_go(SB)
-
-TEXT bad_abi<>(SB),NOSPLIT,$-4
-	// give diagnosis and exit
-	MOVW	$2, R0 // stderr
-	MOVW	$bad_abi_msg(SB), R1 // data
-	MOVW	$45, R2 // len
-	MOVW	$4, R7 // sys_write
-	BL	oabi_syscall<>(SB)
-	MOVW	$1, R0
-	MOVW	$1, R7 // sys_exit
-	BL	oabi_syscall<>(SB)
-	B  	0(PC)
-
-DATA bad_abi_msg+0x00(SB)/8, $"This pro"
-DATA bad_abi_msg+0x08(SB)/8, $"gram can"
-DATA bad_abi_msg+0x10(SB)/8, $" only be"
-DATA bad_abi_msg+0x18(SB)/8, $" run on "
-DATA bad_abi_msg+0x20(SB)/8, $"EABI ker"
-DATA bad_abi_msg+0x28(SB)/4, $"nels"
-DATA bad_abi_msg+0x2c(SB)/1, $0xa
-GLOBL bad_abi_msg(SB), $45
-
-TEXT oabi_syscall<>(SB),NOSPLIT,$-4
-	ADD $1, PC, R4
-	WORD $0xe12fff14 //BX	(R4) // enter thumb mode
-	// TODO(minux): only supports little-endian CPUs
-	WORD $0x4770df01 // swi $1; bx lr
-
-TEXT main(SB),NOSPLIT,$-4
-	MOVW	$_rt0_arm_linux1(SB), R4
-	B		(R4)
-
diff --git a/src/pkg/runtime/rt0_nacl_386.s b/src/pkg/runtime/rt0_nacl_386.s
deleted file mode 100644
index 8b71354..0000000
--- a/src/pkg/runtime/rt0_nacl_386.s
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../cmd/ld/textflag.h"
-
-// NaCl entry has:
-//	0(FP) - arg block == SP+8
-//	4(FP) - cleanup function pointer, always 0
-//	8(FP) - envc
-//	12(FP) - argc
-//	16(FP) - argv, then 0, then envv, then 0, then auxv
-TEXT _rt0_386_nacl(SB),NOSPLIT,$8
-	MOVL	argc+12(FP), AX
-	LEAL	argv+16(FP), BX
-	MOVL	AX, 0(SP)
-	MOVL	BX, 4(SP)
-	CALL	main(SB)
-	INT	$3
-
-TEXT main(SB),NOSPLIT,$0
-	JMP	_rt0_go(SB)
diff --git a/src/pkg/runtime/rt0_nacl_amd64p32.s b/src/pkg/runtime/rt0_nacl_amd64p32.s
deleted file mode 100644
index 502d2e2..0000000
--- a/src/pkg/runtime/rt0_nacl_amd64p32.s
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../cmd/ld/textflag.h"
-
-// NaCl entry on 32-bit x86 has DI pointing at the arg block, which contains:
-//
-//	0(DI) - cleanup function pointer, always 0
-//	4(DI) - envc
-//	8(DI) - argc
-//	12(DI) - argv, then 0, then envv, then 0, then auxv
-// NaCl entry here is almost the same, except that there
-// is no saved caller PC, so 0(FP) is -8(FP) and so on. 
-TEXT _rt0_amd64p32_nacl(SB),NOSPLIT,$16
-	MOVL	DI, 0(SP)
-	CALL	runtime·nacl_sysinfo(SB)
-	MOVL	0(SP), DI
-	MOVL	8(DI), AX
-	LEAL	12(DI), BX
-	MOVL	AX, 0(SP)
-	MOVL	BX, 4(SP)
-	CALL	main(SB)
-	INT	$3
-
-TEXT main(SB),NOSPLIT,$0
-	// Uncomment for fake time like on Go Playground.
-	//MOVQ	$1257894000000000000, AX
-	//MOVQ	AX, runtime·timens(SB)
-	JMP	_rt0_go(SB)
diff --git a/src/pkg/runtime/rt0_netbsd_386.s b/src/pkg/runtime/rt0_netbsd_386.s
deleted file mode 100644
index eb348fc..0000000
--- a/src/pkg/runtime/rt0_netbsd_386.s
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../cmd/ld/textflag.h"
-
-TEXT _rt0_386_netbsd(SB),NOSPLIT,$8
-	MOVL	8(SP), AX
-	LEAL	12(SP), BX
-	MOVL	AX, 0(SP)
-	MOVL	BX, 4(SP)
-	CALL	main(SB)
-	INT	$3
-
-TEXT main(SB),NOSPLIT,$0
-	JMP	_rt0_go(SB)
diff --git a/src/pkg/runtime/rt0_netbsd_amd64.s b/src/pkg/runtime/rt0_netbsd_amd64.s
deleted file mode 100644
index c8e3fb1..0000000
--- a/src/pkg/runtime/rt0_netbsd_amd64.s
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../cmd/ld/textflag.h"
-
-TEXT _rt0_amd64_netbsd(SB),NOSPLIT,$-8
-	LEAQ	8(SP), SI // argv
-	MOVQ	0(SP), DI // argc
-	MOVQ	$main(SB), AX
-	JMP	AX
-
-TEXT main(SB),NOSPLIT,$-8
-	MOVQ	$_rt0_go(SB), AX
-	JMP	AX
diff --git a/src/pkg/runtime/rt0_netbsd_arm.s b/src/pkg/runtime/rt0_netbsd_arm.s
deleted file mode 100644
index 36effc3..0000000
--- a/src/pkg/runtime/rt0_netbsd_arm.s
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../cmd/ld/textflag.h"
-
-// FreeBSD/NetBSD and Linux use the same linkage to main
-
-TEXT _rt0_arm_netbsd(SB),NOSPLIT,$-4
-	MOVW	(R13), R0	// argc
-	MOVW	$4(R13), R1		// argv
-	MOVM.DB.W [R0-R1], (R13)
-	B _rt0_go(SB)
diff --git a/src/pkg/runtime/rt0_openbsd_386.s b/src/pkg/runtime/rt0_openbsd_386.s
deleted file mode 100644
index 9e80f69..0000000
--- a/src/pkg/runtime/rt0_openbsd_386.s
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../cmd/ld/textflag.h"
-
-TEXT _rt0_386_openbsd(SB),NOSPLIT,$8
-	MOVL	8(SP), AX
-	LEAL	12(SP), BX
-	MOVL	AX, 0(SP)
-	MOVL	BX, 4(SP)
-	CALL	main(SB)
-	INT	$3
-
-TEXT main(SB),NOSPLIT,$0
-	JMP	_rt0_go(SB)
diff --git a/src/pkg/runtime/rt0_openbsd_amd64.s b/src/pkg/runtime/rt0_openbsd_amd64.s
deleted file mode 100644
index b1ad403..0000000
--- a/src/pkg/runtime/rt0_openbsd_amd64.s
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../cmd/ld/textflag.h"
-
-TEXT _rt0_amd64_openbsd(SB),NOSPLIT,$-8
-	LEAQ	8(SP), SI // argv
-	MOVQ	0(SP), DI // argc
-	MOVQ	$main(SB), AX
-	JMP	AX
-
-TEXT main(SB),NOSPLIT,$-8
-	MOVQ	$_rt0_go(SB), AX
-	JMP	AX
diff --git a/src/pkg/runtime/rt0_plan9_386.s b/src/pkg/runtime/rt0_plan9_386.s
deleted file mode 100644
index dad75c8..0000000
--- a/src/pkg/runtime/rt0_plan9_386.s
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2010 The Go 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 "../../cmd/ld/textflag.h"
-
-TEXT _rt0_386_plan9(SB),NOSPLIT, $0
-	MOVL	AX, _tos(SB)
-	
-	// move arguments down to make room for
-	// m and g at top of stack, right before Tos.
-	MOVL	SP, SI
-	SUBL	$8, SP
-	MOVL	SP, DI
-		
-	MOVL	AX, CX
-	SUBL	SI, CX
-	CLD
-	REP; MOVSB
-	
-	// adjust argv
-	SUBL	SI, DI
-	MOVL	newargc+0(SP), CX
-	LEAL	newargv+4(SP), BP
-argv_fix:
-	ADDL	DI, 0(BP)
-	ADDL	$4, BP
-	LOOP	argv_fix
-	
-	CALL	runtime·asminit(SB)
-
-	MOVL	0(SP), AX
-	LEAL	4(SP), BX
-	PUSHL	BX
-	PUSHL	AX
-	PUSHL	$-1
-
-	JMP	_rt0_go(SB)
-
-DATA  runtime·isplan9(SB)/4, $1
-GLOBL runtime·isplan9(SB), $4
-GLOBL _tos(SB), $4
diff --git a/src/pkg/runtime/rt0_plan9_amd64.s b/src/pkg/runtime/rt0_plan9_amd64.s
deleted file mode 100644
index 79a7c92..0000000
--- a/src/pkg/runtime/rt0_plan9_amd64.s
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2010 The Go 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 "../../cmd/ld/textflag.h"
-
-TEXT _rt0_amd64_plan9(SB),NOSPLIT,$-8
-	LEAQ	8(SP), SI // argv
-	MOVQ	0(SP), DI // argc
-	MOVQ	$_rt0_go(SB), AX
-	JMP	AX
-
-DATA runtime·isplan9(SB)/4, $1
-GLOBL runtime·isplan9(SB), $4
diff --git a/src/pkg/runtime/rt0_solaris_amd64.s b/src/pkg/runtime/rt0_solaris_amd64.s
deleted file mode 100644
index 4aca991..0000000
--- a/src/pkg/runtime/rt0_solaris_amd64.s
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../cmd/ld/textflag.h"
-
-TEXT _rt0_amd64_solaris(SB),NOSPLIT,$-8
-	LEAQ	8(SP), SI // argv
-	MOVQ	0(SP), DI // argc
-	MOVQ	$main(SB), AX
-	JMP	AX
-
-TEXT main(SB),NOSPLIT,$-8
-	MOVQ	$_rt0_go(SB), AX
-	JMP	AX
-
-DATA runtime·issolaris(SB)/4, $1
-GLOBL runtime·issolaris(SB), $4
diff --git a/src/pkg/runtime/rt0_windows_386.s b/src/pkg/runtime/rt0_windows_386.s
deleted file mode 100644
index 594e2cd..0000000
--- a/src/pkg/runtime/rt0_windows_386.s
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../cmd/ld/textflag.h"
-
-TEXT _rt0_386_windows(SB),NOSPLIT,$12
-	MOVL	12(SP), AX
-	LEAL	16(SP), BX
-	MOVL	AX, 4(SP)
-	MOVL	BX, 8(SP)
-	MOVL	$-1, 0(SP) // return PC for main
-	JMP	main(SB)
-
-TEXT main(SB),NOSPLIT,$0
-	JMP	_rt0_go(SB)
-
-
-DATA  runtime·iswindows(SB)/4, $1
-GLOBL runtime·iswindows(SB), $4
diff --git a/src/pkg/runtime/rt0_windows_amd64.s b/src/pkg/runtime/rt0_windows_amd64.s
deleted file mode 100644
index 32e18b0..0000000
--- a/src/pkg/runtime/rt0_windows_amd64.s
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "zasm_GOOS_GOARCH.h"
-#include "../../cmd/ld/textflag.h"
-
-TEXT _rt0_amd64_windows(SB),NOSPLIT,$-8
-	LEAQ	8(SP), SI // argv
-	MOVQ	0(SP), DI // argc
-	MOVQ	$main(SB), AX
-	JMP	AX
-
-TEXT main(SB),NOSPLIT,$-8
-	MOVQ	$_rt0_go(SB), AX
-	JMP	AX
-
-DATA  runtime·iswindows(SB)/4, $1
-GLOBL runtime·iswindows(SB), $4
diff --git a/src/pkg/runtime/rune.c b/src/pkg/runtime/rune.c
deleted file mode 100644
index ed86726..0000000
--- a/src/pkg/runtime/rune.c
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- * The authors of this software are Rob Pike and Ken Thompson.
- *              Copyright (c) 2002 by Lucent Technologies.
- *              Portions Copyright 2009 The Go Authors. All rights reserved.
- * Permission to use, copy, modify, and distribute this software for any
- * purpose without fee is hereby granted, provided that this entire notice
- * is included in all copies of any software which is or includes a copy
- * or modification of this software and in all copies of the supporting
- * documentation for such software.
- * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
- * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
- * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
- */
-
-/*
- * This code is copied, with slight editing due to type differences,
- * from a subset of ../lib9/utf/rune.c
- */
-
-#include "runtime.h"
-
-enum
-{
-	Bit1	= 7,
-	Bitx	= 6,
-	Bit2	= 5,
-	Bit3	= 4,
-	Bit4	= 3,
-	Bit5	= 2,
-
-	T1	= ((1<<(Bit1+1))-1) ^ 0xFF,	/* 0000 0000 */
-	Tx	= ((1<<(Bitx+1))-1) ^ 0xFF,	/* 1000 0000 */
-	T2	= ((1<<(Bit2+1))-1) ^ 0xFF,	/* 1100 0000 */
-	T3	= ((1<<(Bit3+1))-1) ^ 0xFF,	/* 1110 0000 */
-	T4	= ((1<<(Bit4+1))-1) ^ 0xFF,	/* 1111 0000 */
-	T5	= ((1<<(Bit5+1))-1) ^ 0xFF,	/* 1111 1000 */
-
-	Rune1	= (1<<(Bit1+0*Bitx))-1,		/* 0000 0000 0111 1111 */
-	Rune2	= (1<<(Bit2+1*Bitx))-1,		/* 0000 0111 1111 1111 */
-	Rune3	= (1<<(Bit3+2*Bitx))-1,		/* 1111 1111 1111 1111 */
-	Rune4	= (1<<(Bit4+3*Bitx))-1,		/* 0001 1111 1111 1111 1111 1111 */
-
-	Maskx	= (1<<Bitx)-1,			/* 0011 1111 */
-	Testx	= Maskx ^ 0xFF,			/* 1100 0000 */
-
-	Runeerror	= 0xFFFD,
-	Runeself	= 0x80,
-
-	SurrogateMin = 0xD800,
-	SurrogateMax = 0xDFFF,
-
-	Bad	= Runeerror,
-
-	Runemax	= 0x10FFFF,	/* maximum rune value */
-};
-
-/*
- * Modified by Wei-Hwa Huang, Google Inc., on 2004-09-24
- * This is a slower but "safe" version of the old chartorune
- * that works on strings that are not necessarily null-terminated.
- *
- * If you know for sure that your string is null-terminated,
- * chartorune will be a bit faster.
- *
- * It is guaranteed not to attempt to access "length"
- * past the incoming pointer.  This is to avoid
- * possible access violations.  If the string appears to be
- * well-formed but incomplete (i.e., to get the whole Rune
- * we'd need to read past str+length) then we'll set the Rune
- * to Bad and return 0.
- *
- * Note that if we have decoding problems for other
- * reasons, we return 1 instead of 0.
- */
-int32
-runtime·charntorune(int32 *rune, uint8 *str, int32 length)
-{
-	int32 c, c1, c2, c3, l;
-
-	/* When we're not allowed to read anything */
-	if(length <= 0) {
-		goto badlen;
-	}
-
-	/*
-	 * one character sequence (7-bit value)
-	 *	00000-0007F => T1
-	 */
-	c = *(uint8*)str;
-	if(c < Tx) {
-		*rune = c;
-		return 1;
-	}
-
-	// If we can't read more than one character we must stop
-	if(length <= 1) {
-		goto badlen;
-	}
-
-	/*
-	 * two character sequence (11-bit value)
-	 *	0080-07FF => T2 Tx
-	 */
-	c1 = *(uint8*)(str+1) ^ Tx;
-	if(c1 & Testx)
-		goto bad;
-	if(c < T3) {
-		if(c < T2)
-			goto bad;
-		l = ((c << Bitx) | c1) & Rune2;
-		if(l <= Rune1)
-			goto bad;
-		*rune = l;
-		return 2;
-	}
-
-	// If we can't read more than two characters we must stop
-	if(length <= 2) {
-		goto badlen;
-	}
-
-	/*
-	 * three character sequence (16-bit value)
-	 *	0800-FFFF => T3 Tx Tx
-	 */
-	c2 = *(uint8*)(str+2) ^ Tx;
-	if(c2 & Testx)
-		goto bad;
-	if(c < T4) {
-		l = ((((c << Bitx) | c1) << Bitx) | c2) & Rune3;
-		if(l <= Rune2)
-			goto bad;
-		if (SurrogateMin <= l && l <= SurrogateMax)
-			goto bad;
-		*rune = l;
-		return 3;
-	}
-
-	if (length <= 3)
-		goto badlen;
-
-	/*
-	 * four character sequence (21-bit value)
-	 *	10000-1FFFFF => T4 Tx Tx Tx
-	 */
-	c3 = *(uint8*)(str+3) ^ Tx;
-	if (c3 & Testx)
-		goto bad;
-	if (c < T5) {
-		l = ((((((c << Bitx) | c1) << Bitx) | c2) << Bitx) | c3) & Rune4;
-		if (l <= Rune3 || l > Runemax)
-			goto bad;
-		*rune = l;
-		return 4;
-	}
-
-	// Support for 5-byte or longer UTF-8 would go here, but
-	// since we don't have that, we'll just fall through to bad.
-
-	/*
-	 * bad decoding
-	 */
-bad:
-	*rune = Bad;
-	return 1;
-badlen:
-	// was return 0, but return 1 is more convenient for the runtime.
-	*rune = Bad;
-	return 1;
-
-}
-
-int32
-runtime·runetochar(byte *str, int32 rune)  /* note: in original, arg2 was pointer */
-{
-	/* Runes are signed, so convert to unsigned for range check. */
-	uint32 c;
-
-	/*
-	 * one character sequence
-	 *	00000-0007F => 00-7F
-	 */
-	c = rune;
-	if(c <= Rune1) {
-		str[0] = c;
-		return 1;
-	}
-
-	/*
-	 * two character sequence
-	 *	0080-07FF => T2 Tx
-	 */
-	if(c <= Rune2) {
-		str[0] = T2 | (c >> 1*Bitx);
-		str[1] = Tx | (c & Maskx);
-		return 2;
-	}
-
-	/*
-	 * If the Rune is out of range or a surrogate half, convert it to the error rune.
-	 * Do this test here because the error rune encodes to three bytes.
-	 * Doing it earlier would duplicate work, since an out of range
-	 * Rune wouldn't have fit in one or two bytes.
-	 */
-	if (c > Runemax)
-		c = Runeerror;
-	if (SurrogateMin <= c && c <= SurrogateMax)
-		c = Runeerror;
-
-	/*
-	 * three character sequence
-	 *	0800-FFFF => T3 Tx Tx
-	 */
-	if (c <= Rune3) {
-		str[0] = T3 |  (c >> 2*Bitx);
-		str[1] = Tx | ((c >> 1*Bitx) & Maskx);
-		str[2] = Tx |  (c & Maskx);
-		return 3;
-	}
-
-	/*
-	 * four character sequence (21-bit value)
-	 *     10000-1FFFFF => T4 Tx Tx Tx
-	 */
-	str[0] = T4 | (c >> 3*Bitx);
-	str[1] = Tx | ((c >> 2*Bitx) & Maskx);
-	str[2] = Tx | ((c >> 1*Bitx) & Maskx);
-	str[3] = Tx | (c & Maskx);
-	return 4;
-}
diff --git a/src/pkg/runtime/runtime.c b/src/pkg/runtime/runtime.c
deleted file mode 100644
index 3b322e0..0000000
--- a/src/pkg/runtime/runtime.c
+++ /dev/null
@@ -1,396 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "runtime.h"
-#include "stack.h"
-#include "arch_GOARCH.h"
-#include "../../cmd/ld/textflag.h"
-
-enum {
-	maxround = sizeof(uintptr),
-};
-
-// Keep a cached value to make gotraceback fast,
-// since we call it on every call to gentraceback.
-// The cached value is a uint32 in which the low bit
-// is the "crash" setting and the top 31 bits are the
-// gotraceback value.
-static uint32 traceback_cache = ~(uint32)0;
-
-// The GOTRACEBACK environment variable controls the
-// behavior of a Go program that is crashing and exiting.
-//	GOTRACEBACK=0   suppress all tracebacks
-//	GOTRACEBACK=1   default behavior - show tracebacks but exclude runtime frames
-//	GOTRACEBACK=2   show tracebacks including runtime frames
-//	GOTRACEBACK=crash   show tracebacks including runtime frames, then crash (core dump etc)
-int32
-runtime·gotraceback(bool *crash)
-{
-	byte *p;
-	uint32 x;
-
-	if(crash != nil)
-		*crash = false;
-	if(m->traceback != 0)
-		return m->traceback;
-	x = runtime·atomicload(&traceback_cache);
-	if(x == ~(uint32)0) {
-		p = runtime·getenv("GOTRACEBACK");
-		if(p == nil)
-			p = (byte*)"";
-		if(p[0] == '\0')
-			x = 1<<1;
-		else if(runtime·strcmp(p, (byte*)"crash") == 0)
-			x = (2<<1) | 1;
-		else
-			x = runtime·atoi(p)<<1;	
-		runtime·atomicstore(&traceback_cache, x);
-	}
-	if(crash != nil)
-		*crash = x&1;
-	return x>>1;
-}
-
-int32
-runtime·mcmp(byte *s1, byte *s2, uintptr n)
-{
-	uintptr i;
-	byte c1, c2;
-
-	for(i=0; i<n; i++) {
-		c1 = s1[i];
-		c2 = s2[i];
-		if(c1 < c2)
-			return -1;
-		if(c1 > c2)
-			return +1;
-	}
-	return 0;
-}
-
-
-byte*
-runtime·mchr(byte *p, byte c, byte *ep)
-{
-	for(; p < ep; p++)
-		if(*p == c)
-			return p;
-	return nil;
-}
-
-static int32	argc;
-static uint8**	argv;
-
-Slice os·Args;
-Slice syscall·envs;
-
-void (*runtime·sysargs)(int32, uint8**);
-
-void
-runtime·args(int32 c, uint8 **v)
-{
-	argc = c;
-	argv = v;
-	if(runtime·sysargs != nil)
-		runtime·sysargs(c, v);
-}
-
-int32 runtime·isplan9;
-int32 runtime·issolaris;
-int32 runtime·iswindows;
-
-// Information about what cpu features are available.
-// Set on startup in asm_{x86/amd64}.s.
-uint32 runtime·cpuid_ecx;
-uint32 runtime·cpuid_edx;
-
-void
-runtime·goargs(void)
-{
-	String *s;
-	int32 i;
-
-	// for windows implementation see "os" package
-	if(Windows)
-		return;
-
-	s = runtime·malloc(argc*sizeof s[0]);
-	for(i=0; i<argc; i++)
-		s[i] = runtime·gostringnocopy(argv[i]);
-	os·Args.array = (byte*)s;
-	os·Args.len = argc;
-	os·Args.cap = argc;
-}
-
-void
-runtime·goenvs_unix(void)
-{
-	String *s;
-	int32 i, n;
-
-	for(n=0; argv[argc+1+n] != 0; n++)
-		;
-
-	s = runtime·malloc(n*sizeof s[0]);
-	for(i=0; i<n; i++)
-		s[i] = runtime·gostringnocopy(argv[argc+1+i]);
-	syscall·envs.array = (byte*)s;
-	syscall·envs.len = n;
-	syscall·envs.cap = n;
-}
-
-int32
-runtime·atoi(byte *p)
-{
-	int32 n;
-
-	n = 0;
-	while('0' <= *p && *p <= '9')
-		n = n*10 + *p++ - '0';
-	return n;
-}
-
-static void
-TestAtomic64(void)
-{
-	uint64 z64, x64;
-
-	z64 = 42;
-	x64 = 0;
-	PREFETCH(&z64);
-	if(runtime·cas64(&z64, x64, 1))
-		runtime·throw("cas64 failed");
-	if(x64 != 0)
-		runtime·throw("cas64 failed");
-	x64 = 42;
-	if(!runtime·cas64(&z64, x64, 1))
-		runtime·throw("cas64 failed");
-	if(x64 != 42 || z64 != 1)
-		runtime·throw("cas64 failed");
-	if(runtime·atomicload64(&z64) != 1)
-		runtime·throw("load64 failed");
-	runtime·atomicstore64(&z64, (1ull<<40)+1);
-	if(runtime·atomicload64(&z64) != (1ull<<40)+1)
-		runtime·throw("store64 failed");
-	if(runtime·xadd64(&z64, (1ull<<40)+1) != (2ull<<40)+2)
-		runtime·throw("xadd64 failed");
-	if(runtime·atomicload64(&z64) != (2ull<<40)+2)
-		runtime·throw("xadd64 failed");
-	if(runtime·xchg64(&z64, (3ull<<40)+3) != (2ull<<40)+2)
-		runtime·throw("xchg64 failed");
-	if(runtime·atomicload64(&z64) != (3ull<<40)+3)
-		runtime·throw("xchg64 failed");
-}
-
-void
-runtime·check(void)
-{
-	int8 a;
-	uint8 b;
-	int16 c;
-	uint16 d;
-	int32 e;
-	uint32 f;
-	int64 g;
-	uint64 h;
-	float32 i, i1;
-	float64 j, j1;
-	byte *k, *k1;
-	uint16* l;
-	struct x1 {
-		byte x;
-	};
-	struct y1 {
-		struct x1 x1;
-		byte y;
-	};
-
-	if(sizeof(a) != 1) runtime·throw("bad a");
-	if(sizeof(b) != 1) runtime·throw("bad b");
-	if(sizeof(c) != 2) runtime·throw("bad c");
-	if(sizeof(d) != 2) runtime·throw("bad d");
-	if(sizeof(e) != 4) runtime·throw("bad e");
-	if(sizeof(f) != 4) runtime·throw("bad f");
-	if(sizeof(g) != 8) runtime·throw("bad g");
-	if(sizeof(h) != 8) runtime·throw("bad h");
-	if(sizeof(i) != 4) runtime·throw("bad i");
-	if(sizeof(j) != 8) runtime·throw("bad j");
-	if(sizeof(k) != sizeof(uintptr)) runtime·throw("bad k");
-	if(sizeof(l) != sizeof(uintptr)) runtime·throw("bad l");
-	if(sizeof(struct x1) != 1) runtime·throw("bad sizeof x1");
-	if(offsetof(struct y1, y) != 1) runtime·throw("bad offsetof y1.y");
-	if(sizeof(struct y1) != 2) runtime·throw("bad sizeof y1");
-
-	if(runtime·timediv(12345LL*1000000000+54321, 1000000000, &e) != 12345 || e != 54321)
-		runtime·throw("bad timediv");
-
-	uint32 z;
-	z = 1;
-	if(!runtime·cas(&z, 1, 2))
-		runtime·throw("cas1");
-	if(z != 2)
-		runtime·throw("cas2");
-
-	z = 4;
-	if(runtime·cas(&z, 5, 6))
-		runtime·throw("cas3");
-	if(z != 4)
-		runtime·throw("cas4");
-
-	k = (byte*)0xfedcb123;
-	if(sizeof(void*) == 8)
-		k = (byte*)((uintptr)k<<10);
-	if(runtime·casp((void**)&k, nil, nil))
-		runtime·throw("casp1");
-	k1 = k+1;
-	if(!runtime·casp((void**)&k, k, k1))
-		runtime·throw("casp2");
-	if(k != k1)
-		runtime·throw("casp3");
-
-	*(uint64*)&j = ~0ULL;
-	if(j == j)
-		runtime·throw("float64nan");
-	if(!(j != j))
-		runtime·throw("float64nan1");
-
-	*(uint64*)&j1 = ~1ULL;
-	if(j == j1)
-		runtime·throw("float64nan2");
-	if(!(j != j1))
-		runtime·throw("float64nan3");
-
-	*(uint32*)&i = ~0UL;
-	if(i == i)
-		runtime·throw("float32nan");
-	if(!(i != i))
-		runtime·throw("float32nan1");
-
-	*(uint32*)&i1 = ~1UL;
-	if(i == i1)
-		runtime·throw("float32nan2");
-	if(!(i != i1))
-		runtime·throw("float32nan3");
-
-	TestAtomic64();
-
-	if(FixedStack != runtime·round2(FixedStack))
-		runtime·throw("FixedStack is not power-of-2");
-}
-
-uint32
-runtime·fastrand1(void)
-{
-	uint32 x;
-
-	x = m->fastrand;
-	x += x;
-	if(x & 0x80000000L)
-		x ^= 0x88888eefUL;
-	m->fastrand = x;
-	return x;
-}
-
-static Lock ticksLock;
-static int64 ticks;
-
-int64
-runtime·tickspersecond(void)
-{
-	int64 res, t0, t1, c0, c1;
-
-	res = (int64)runtime·atomicload64((uint64*)&ticks);
-	if(res != 0)
-		return ticks;
-	runtime·lock(&ticksLock);
-	res = ticks;
-	if(res == 0) {
-		t0 = runtime·nanotime();
-		c0 = runtime·cputicks();
-		runtime·usleep(100*1000);
-		t1 = runtime·nanotime();
-		c1 = runtime·cputicks();
-		if(t1 == t0)
-			t1++;
-		res = (c1-c0)*1000*1000*1000/(t1-t0);
-		if(res == 0)
-			res++;
-		runtime·atomicstore64((uint64*)&ticks, res);
-	}
-	runtime·unlock(&ticksLock);
-	return res;
-}
-
-DebugVars	runtime·debug;
-
-static struct {
-	int8*	name;
-	int32*	value;
-} dbgvar[] = {
-	{"allocfreetrace", &runtime·debug.allocfreetrace},
-	{"efence", &runtime·debug.efence},
-	{"gctrace", &runtime·debug.gctrace},
-	{"gcdead", &runtime·debug.gcdead},
-	{"scheddetail", &runtime·debug.scheddetail},
-	{"schedtrace", &runtime·debug.schedtrace},
-};
-
-void
-runtime·parsedebugvars(void)
-{
-	byte *p;
-	intgo i, n;
-	bool tmp;
-	
-	// gotraceback caches the GOTRACEBACK setting in traceback_cache.
-	// gotraceback can be called before the environment is available.
-	// traceback_cache must be reset after the environment is made
-	// available, in order for the environment variable to take effect.
-	// The code is fixed differently in Go 1.4.
-	// This is a limited fix for Go 1.3.3.
-	traceback_cache = ~(uint32)0;
-	runtime·gotraceback(&tmp);
-
-	p = runtime·getenv("GODEBUG");
-	if(p == nil)
-		return;
-	for(;;) {
-		for(i=0; i<nelem(dbgvar); i++) {
-			n = runtime·findnull((byte*)dbgvar[i].name);
-			if(runtime·mcmp(p, (byte*)dbgvar[i].name, n) == 0 && p[n] == '=')
-				*dbgvar[i].value = runtime·atoi(p+n+1);
-		}
-		p = runtime·strstr(p, (byte*)",");
-		if(p == nil)
-			break;
-		p++;
-	}
-}
-
-// Poor mans 64-bit division.
-// This is a very special function, do not use it if you are not sure what you are doing.
-// int64 division is lowered into _divv() call on 386, which does not fit into nosplit functions.
-// Handles overflow in a time-specific manner.
-#pragma textflag NOSPLIT
-int32
-runtime·timediv(int64 v, int32 div, int32 *rem)
-{
-	int32 res, bit;
-
-	if(v >= (int64)div*0x7fffffffLL) {
-		if(rem != nil)
-			*rem = 0;
-		return 0x7fffffff;
-	}
-	res = 0;
-	for(bit = 30; bit >= 0; bit--) {
-		if(v >= ((int64)div<<bit)) {
-			v = v - ((int64)div<<bit);
-			res += 1<<bit;
-		}
-	}
-	if(rem != nil)
-		*rem = v;
-	return res;
-}
diff --git a/src/pkg/runtime/runtime.h b/src/pkg/runtime/runtime.h
deleted file mode 100644
index 42fb3a4..0000000
--- a/src/pkg/runtime/runtime.h
+++ /dev/null
@@ -1,1151 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-/*
- * basic types
- */
-typedef	signed char		int8;
-typedef	unsigned char		uint8;
-typedef	signed short		int16;
-typedef	unsigned short		uint16;
-typedef	signed int		int32;
-typedef	unsigned int		uint32;
-typedef	signed long long int	int64;
-typedef	unsigned long long int	uint64;
-typedef	float			float32;
-typedef	double			float64;
-
-#ifdef _64BIT
-typedef	uint64		uintptr;
-typedef	int64		intptr;
-typedef	int64		intgo; // Go's int
-typedef	uint64		uintgo; // Go's uint
-#else
-typedef	uint32		uintptr;
-typedef	int32		intptr;
-typedef	int32		intgo; // Go's int
-typedef	uint32		uintgo; // Go's uint
-#endif
-
-#ifdef _64BITREG
-typedef	uint64		uintreg;
-#else
-typedef	uint32		uintreg;
-#endif
-
-/*
- * get rid of C types
- * the / / / forces a syntax error immediately,
- * which will show "last name: XXunsigned".
- */
-#define	unsigned		XXunsigned / / /
-#define	signed			XXsigned / / /
-#define	char			XXchar / / /
-#define	short			XXshort / / /
-#define	int			XXint / / /
-#define	long			XXlong / / /
-#define	float			XXfloat / / /
-#define	double			XXdouble / / /
-
-/*
- * defined types
- */
-typedef	uint8			bool;
-typedef	uint8			byte;
-typedef	struct	Func		Func;
-typedef	struct	G		G;
-typedef	struct	Gobuf		Gobuf;
-typedef	struct	Lock		Lock;
-typedef	struct	M		M;
-typedef	struct	P		P;
-typedef	struct	Note		Note;
-typedef	struct	Slice		Slice;
-typedef	struct	Stktop		Stktop;
-typedef	struct	String		String;
-typedef	struct	FuncVal		FuncVal;
-typedef	struct	SigTab		SigTab;
-typedef	struct	MCache		MCache;
-typedef	struct	FixAlloc	FixAlloc;
-typedef	struct	Iface		Iface;
-typedef	struct	Itab		Itab;
-typedef	struct	InterfaceType	InterfaceType;
-typedef	struct	Eface		Eface;
-typedef	struct	Type		Type;
-typedef	struct	PtrType		PtrType;
-typedef	struct	ChanType		ChanType;
-typedef	struct	MapType		MapType;
-typedef	struct	Defer		Defer;
-typedef	struct	Panic		Panic;
-typedef	struct	Hmap		Hmap;
-typedef	struct	Hiter			Hiter;
-typedef	struct	Hchan		Hchan;
-typedef	struct	Complex64	Complex64;
-typedef	struct	Complex128	Complex128;
-typedef	struct	LibCall		LibCall;
-typedef	struct	WinCallbackContext	WinCallbackContext;
-typedef	struct	Timers		Timers;
-typedef	struct	Timer		Timer;
-typedef	struct	GCStats		GCStats;
-typedef	struct	LFNode		LFNode;
-typedef	struct	ParFor		ParFor;
-typedef	struct	ParForThread	ParForThread;
-typedef	struct	CgoMal		CgoMal;
-typedef	struct	PollDesc	PollDesc;
-typedef	struct	DebugVars	DebugVars;
-
-/*
- * Per-CPU declaration.
- *
- * "extern register" is a special storage class implemented by 6c, 8c, etc.
- * On the ARM, it is an actual register; elsewhere it is a slot in thread-
- * local storage indexed by a pseudo-register TLS. See zasmhdr in
- * src/cmd/dist/buildruntime.c for details, and be aware that the linker may
- * make further OS-specific changes to the compiler's output. For example,
- * 6l/linux rewrites 0(TLS) as -16(FS).
- *
- * Every C file linked into a Go program must include runtime.h so that the
- * C compiler (6c, 8c, etc.) knows to avoid other uses of these dedicated
- * registers. The Go compiler (6g, 8g, etc.) knows to avoid them.
- */
-extern	register	G*	g;
-extern	register	M*	m;
-
-/*
- * defined constants
- */
-enum
-{
-	// G status
-	//
-	// If you add to this list, add to the list
-	// of "okay during garbage collection" status
-	// in mgc0.c too.
-	Gidle,
-	Grunnable,
-	Grunning,
-	Gsyscall,
-	Gwaiting,
-	Gmoribund_unused,  // currently unused, but hardcoded in gdb scripts
-	Gdead,
-};
-enum
-{
-	// P status
-	Pidle,
-	Prunning,
-	Psyscall,
-	Pgcstop,
-	Pdead,
-};
-enum
-{
-	true	= 1,
-	false	= 0,
-};
-enum
-{
-	PtrSize = sizeof(void*),
-};
-enum
-{
-	// Per-M stack segment cache size.
-	StackCacheSize = 32,
-	// Global <-> per-M stack segment cache transfer batch size.
-	StackCacheBatch = 16,
-};
-/*
- * structures
- */
-struct	Lock
-{
-	// Futex-based impl treats it as uint32 key,
-	// while sema-based impl as M* waitm.
-	// Used to be a union, but unions break precise GC.
-	uintptr	key;
-};
-struct	Note
-{
-	// Futex-based impl treats it as uint32 key,
-	// while sema-based impl as M* waitm.
-	// Used to be a union, but unions break precise GC.
-	uintptr	key;
-};
-struct String
-{
-	byte*	str;
-	intgo	len;
-};
-struct FuncVal
-{
-	void	(*fn)(void);
-	// variable-size, fn-specific data here
-};
-struct Iface
-{
-	Itab*	tab;
-	void*	data;
-};
-struct Eface
-{
-	Type*	type;
-	void*	data;
-};
-struct Complex64
-{
-	float32	real;
-	float32	imag;
-};
-struct Complex128
-{
-	float64	real;
-	float64	imag;
-};
-
-struct	Slice
-{				// must not move anything
-	byte*	array;		// actual data
-	uintgo	len;		// number of elements
-	uintgo	cap;		// allocated number of elements
-};
-struct	Gobuf
-{
-	// The offsets of sp, pc, and g are known to (hard-coded in) libmach.
-	uintptr	sp;
-	uintptr	pc;
-	G*	g;
-	void*	ctxt;
-	uintreg	ret;
-	uintptr	lr;
-};
-struct	GCStats
-{
-	// the struct must consist of only uint64's,
-	// because it is casted to uint64[].
-	uint64	nhandoff;
-	uint64	nhandoffcnt;
-	uint64	nprocyield;
-	uint64	nosyield;
-	uint64	nsleep;
-};
-
-struct	LibCall
-{
-	void	(*fn)(void*);
-	uintptr	n;	// number of parameters
-	void*	args;	// parameters
-	uintptr	r1;	// return values
-	uintptr	r2;
-	uintptr	err;	// error number
-};
-
-// describes how to handle callback
-struct	WinCallbackContext
-{
-	void*	gobody;		// Go function to call
-	uintptr	argsize;	// callback arguments size (in bytes)
-	uintptr	restorestack;	// adjust stack on return by (in bytes) (386 only)
-	bool	cleanstack;
-};
-
-struct	G
-{
-	// stackguard0 can be set to StackPreempt as opposed to stackguard
-	uintptr	stackguard0;	// cannot move - also known to linker, libmach, runtime/cgo
-	uintptr	stackbase;	// cannot move - also known to libmach, runtime/cgo
-	uint32	panicwrap;	// cannot move - also known to linker
-	Defer*	defer;
-	Panic*	panic;
-	Gobuf	sched;
-	uintptr	syscallstack;	// if status==Gsyscall, syscallstack = stackbase to use during gc
-	uintptr	syscallsp;	// if status==Gsyscall, syscallsp = sched.sp to use during gc
-	uintptr	syscallpc;	// if status==Gsyscall, syscallpc = sched.pc to use during gc
-	uintptr	syscallguard;	// if status==Gsyscall, syscallguard = stackguard to use during gc
-	uintptr	stackguard;	// same as stackguard0, but not set to StackPreempt
-	uintptr	stack0;
-	uintptr	stacksize;
-	void*	param;		// passed parameter on wakeup
-	int16	status;
-	int64	goid;
-	int64	waitsince;	// approx time when the G become blocked
-	int8*	waitreason;	// if status==Gwaiting
-	G*	schedlink;
-	bool	ispanic;
-	bool	issystem;	// do not output in stack dump
-	bool	isbackground;	// ignore in deadlock detector
-	bool	preempt;	// preemption signal, duplicates stackguard0 = StackPreempt
-	bool	paniconfault;	// panic (instead of crash) on unexpected fault address
-	int8	raceignore;	// ignore race detection events
-	M*	m;		// for debuggers, but offset not hard-coded
-	M*	lockedm;
-	int32	sig;
-	int32	writenbuf;
-	byte*	writebuf;
-	uintptr	sigcode0;
-	uintptr	sigcode1;
-	uintptr	sigpc;
-	uintptr	gopc;		// pc of go statement that created this goroutine
-	uintptr	racectx;
-	uintptr	end[];
-};
-
-struct	M
-{
-	G*	g0;		// goroutine with scheduling stack
-	void*	moreargp;	// argument pointer for more stack
-	Gobuf	morebuf;	// gobuf arg to morestack
-
-	// Fields not known to debuggers.
-	uint32	moreframesize;	// size arguments to morestack
-	uint32	moreargsize;	// known by amd64 asm to follow moreframesize
-	uintreg	cret;		// return value from C
-	uint64	procid;		// for debuggers, but offset not hard-coded
-	G*	gsignal;	// signal-handling G
-	uintptr	tls[4];		// thread-local storage (for x86 extern register)
-	void	(*mstartfn)(void);
-	G*	curg;		// current running goroutine
-	G*	caughtsig;	// goroutine running during fatal signal
-	P*	p;		// attached P for executing Go code (nil if not executing Go code)
-	P*	nextp;
-	int32	id;
-	int32	mallocing;
-	int32	throwing;
-	int32	gcing;
-	int32	locks;
-	int32	softfloat;
-	int32	dying;
-	int32	profilehz;
-	int32	helpgc;
-	bool	spinning;	// M is out of work and is actively looking for work
-	bool	blocked;	// M is blocked on a Note
-	uint32	fastrand;
-	uint64	ncgocall;	// number of cgo calls in total
-	int32	ncgo;		// number of cgo calls currently in progress
-	CgoMal*	cgomal;
-	Note	park;
-	M*	alllink;	// on allm
-	M*	schedlink;
-	uint32	machport;	// Return address for Mach IPC (OS X)
-	MCache*	mcache;
-	int32	stackinuse;
-	uint32	stackcachepos;
-	uint32	stackcachecnt;
-	void*	stackcache[StackCacheSize];
-	G*	lockedg;
-	uintptr	createstack[32];// Stack that created this thread.
-	uint32	freglo[16];	// D[i] lsb and F[i]
-	uint32	freghi[16];	// D[i] msb and F[i+16]
-	uint32	fflag;		// floating point compare flags
-	uint32	locked;		// tracking for LockOSThread
-	M*	nextwaitm;	// next M waiting for lock
-	uintptr	waitsema;	// semaphore for parking on locks
-	uint32	waitsemacount;
-	uint32	waitsemalock;
-	GCStats	gcstats;
-	bool	needextram;
-	uint8	traceback;
-	bool	(*waitunlockf)(G*, void*);
-	void*	waitlock;
-	uintptr	forkstackguard;
-#ifdef GOOS_windows
-	void*	thread;		// thread handle
-	// these are here because they are too large to be on the stack
-	// of low-level NOSPLIT functions.
-	LibCall	libcall;
-	uintptr	libcallpc;	// for cpu profiler
-	uintptr	libcallsp;
-	G*	libcallg;
-#endif
-#ifdef GOOS_solaris
-	int32*	perrno; 	// pointer to TLS errno
-	// these are here because they are too large to be on the stack
-	// of low-level NOSPLIT functions.
-	LibCall	libcall;
-	struct {
-		int64	tv_sec;
-		int64	tv_nsec;
-	} ts;
-	struct {
-		uintptr v[6];
-	} scratch;
-#endif
-#ifdef GOOS_plan9
-	int8*	notesig;
-	byte*	errstr;
-#endif
-	uintptr	end[];
-};
-
-struct P
-{
-	Lock;
-
-	int32	id;
-	uint32	status;		// one of Pidle/Prunning/...
-	P*	link;
-	uint32	schedtick;	// incremented on every scheduler call
-	uint32	syscalltick;	// incremented on every system call
-	M*	m;		// back-link to associated M (nil if idle)
-	MCache*	mcache;
-	Defer*	deferpool[5];	// pool of available Defer structs of different sizes (see panic.c)
-
-	// Cache of goroutine ids, amortizes accesses to runtime·sched.goidgen.
-	uint64	goidcache;
-	uint64	goidcacheend;
-
-	// Queue of runnable goroutines.
-	uint32	runqhead;
-	uint32	runqtail;
-	G*	runq[256];
-
-	// Available G's (status == Gdead)
-	G*	gfree;
-	int32	gfreecnt;
-
-	byte	pad[64];
-};
-
-// The m->locked word holds two pieces of state counting active calls to LockOSThread/lockOSThread.
-// The low bit (LockExternal) is a boolean reporting whether any LockOSThread call is active.
-// External locks are not recursive; a second lock is silently ignored.
-// The upper bits of m->lockedcount record the nesting depth of calls to lockOSThread
-// (counting up by LockInternal), popped by unlockOSThread (counting down by LockInternal).
-// Internal locks can be recursive. For instance, a lock for cgo can occur while the main
-// goroutine is holding the lock during the initialization phase.
-enum
-{
-	LockExternal = 1,
-	LockInternal = 2,
-};
-
-struct	Stktop
-{
-	// The offsets of these fields are known to (hard-coded in) libmach.
-	uintptr	stackguard;
-	uintptr	stackbase;
-	Gobuf	gobuf;
-	uint32	argsize;
-	uint32	panicwrap;
-
-	uint8*	argp;	// pointer to arguments in old frame
-	bool	panic;	// is this frame the top of a panic?
-	bool	malloced;
-};
-struct	SigTab
-{
-	int32	flags;
-	int8	*name;
-};
-enum
-{
-	SigNotify = 1<<0,	// let signal.Notify have signal, even if from kernel
-	SigKill = 1<<1,		// if signal.Notify doesn't take it, exit quietly
-	SigThrow = 1<<2,	// if signal.Notify doesn't take it, exit loudly
-	SigPanic = 1<<3,	// if the signal is from the kernel, panic
-	SigDefault = 1<<4,	// if the signal isn't explicitly requested, don't monitor it
-	SigHandling = 1<<5,	// our signal handler is registered
-	SigIgnored = 1<<6,	// the signal was ignored before we registered for it
-	SigGoExit = 1<<7,	// cause all runtime procs to exit (only used on Plan 9).
-};
-
-// Layout of in-memory per-function information prepared by linker
-// See http://golang.org/s/go12symtab.
-// Keep in sync with linker and with ../../libmach/sym.c
-// and with package debug/gosym.
-struct	Func
-{
-	uintptr	entry;	// start pc
-	int32	nameoff;// function name
-	
-	int32	args;	// in/out args size
-	int32	frame;	// legacy frame size; use pcsp if possible
-
-	int32	pcsp;
-	int32	pcfile;
-	int32	pcln;
-	int32	npcdata;
-	int32	nfuncdata;
-};
-
-// layout of Itab known to compilers
-// allocated in non-garbage-collected memory
-struct	Itab
-{
-	InterfaceType*	inter;
-	Type*	type;
-	Itab*	link;
-	int32	bad;
-	int32	unused;
-	void	(*fun[])(void);
-};
-
-#ifdef GOOS_nacl
-enum {
-   NaCl = 1,
-};
-#else
-enum {
-   NaCl = 0,
-};
-#endif
-
-#ifdef GOOS_windows
-enum {
-   Windows = 1
-};
-#else
-enum {
-   Windows = 0
-};
-#endif
-#ifdef GOOS_solaris
-enum {
-   Solaris = 1
-};
-#else
-enum {
-   Solaris = 0
-};
-#endif
-
-struct	Timers
-{
-	Lock;
-	G	*timerproc;
-	bool		sleeping;
-	bool		rescheduling;
-	Note	waitnote;
-	Timer	**t;
-	int32	len;
-	int32	cap;
-};
-
-// Package time knows the layout of this structure.
-// If this struct changes, adjust ../time/sleep.go:/runtimeTimer.
-// For GOOS=nacl, package syscall knows the layout of this structure.
-// If this struct changes, adjust ../syscall/net_nacl.go:/runtimeTimer.
-struct	Timer
-{
-	int32	i;	// heap index
-
-	// Timer wakes up at when, and then at when+period, ... (period > 0 only)
-	// each time calling f(now, arg) in the timer goroutine, so f must be
-	// a well-behaved function and not block.
-	int64	when;
-	int64	period;
-	FuncVal	*fv;
-	Eface	arg;
-};
-
-// Lock-free stack node.
-struct LFNode
-{
-	LFNode	*next;
-	uintptr	pushcnt;
-};
-
-// Parallel for descriptor.
-struct ParFor
-{
-	void (*body)(ParFor*, uint32);	// executed for each element
-	uint32 done;			// number of idle threads
-	uint32 nthr;			// total number of threads
-	uint32 nthrmax;			// maximum number of threads
-	uint32 thrseq;			// thread id sequencer
-	uint32 cnt;			// iteration space [0, cnt)
-	void *ctx;			// arbitrary user context
-	bool wait;			// if true, wait while all threads finish processing,
-					// otherwise parfor may return while other threads are still working
-	ParForThread *thr;		// array of thread descriptors
-	uint32 pad;			// to align ParForThread.pos for 64-bit atomic operations
-	// stats
-	uint64 nsteal;
-	uint64 nstealcnt;
-	uint64 nprocyield;
-	uint64 nosyield;
-	uint64 nsleep;
-};
-
-// Track memory allocated by code not written in Go during a cgo call,
-// so that the garbage collector can see them.
-struct CgoMal
-{
-	CgoMal	*next;
-	void	*alloc;
-};
-
-// Holds variables parsed from GODEBUG env var.
-struct DebugVars
-{
-	int32	allocfreetrace;
-	int32	efence;
-	int32	gctrace;
-	int32	gcdead;
-	int32	scheddetail;
-	int32	schedtrace;
-};
-
-extern bool runtime·precisestack;
-extern bool runtime·copystack;
-
-/*
- * defined macros
- *    you need super-gopher-guru privilege
- *    to add this list.
- */
-#define	nelem(x)	(sizeof(x)/sizeof((x)[0]))
-#define	nil		((void*)0)
-#define	offsetof(s,m)	(uint32)(&(((s*)0)->m))
-#define	ROUND(x, n)	(((x)+(n)-1)&~(uintptr)((n)-1)) /* all-caps to mark as macro: it evaluates n twice */
-
-/*
- * known to compiler
- */
-enum {
-	Structrnd = sizeof(uintreg),
-};
-
-/*
- * type algorithms - known to compiler
- */
-enum
-{
-	AMEM,
-	AMEM0,
-	AMEM8,
-	AMEM16,
-	AMEM32,
-	AMEM64,
-	AMEM128,
-	ANOEQ,
-	ANOEQ0,
-	ANOEQ8,
-	ANOEQ16,
-	ANOEQ32,
-	ANOEQ64,
-	ANOEQ128,
-	ASTRING,
-	AINTER,
-	ANILINTER,
-	ASLICE,
-	AFLOAT32,
-	AFLOAT64,
-	ACPLX64,
-	ACPLX128,
-	Amax
-};
-typedef	struct	Alg		Alg;
-struct	Alg
-{
-	void	(*hash)(uintptr*, uintptr, void*);
-	void	(*equal)(bool*, uintptr, void*, void*);
-	void	(*print)(uintptr, void*);
-	void	(*copy)(uintptr, void*, void*);
-};
-
-extern	Alg	runtime·algarray[Amax];
-
-byte*	runtime·startup_random_data;
-uint32	runtime·startup_random_data_len;
-void	runtime·get_random_data(byte**, int32*);
-
-enum {
-	// hashinit wants this many random bytes
-	HashRandomBytes = 32
-};
-void	runtime·hashinit(void);
-
-void	runtime·memhash(uintptr*, uintptr, void*);
-void	runtime·nohash(uintptr*, uintptr, void*);
-void	runtime·strhash(uintptr*, uintptr, void*);
-void	runtime·interhash(uintptr*, uintptr, void*);
-void	runtime·nilinterhash(uintptr*, uintptr, void*);
-void	runtime·aeshash(uintptr*, uintptr, void*);
-void	runtime·aeshash32(uintptr*, uintptr, void*);
-void	runtime·aeshash64(uintptr*, uintptr, void*);
-void	runtime·aeshashstr(uintptr*, uintptr, void*);
-
-void	runtime·memequal(bool*, uintptr, void*, void*);
-void	runtime·noequal(bool*, uintptr, void*, void*);
-void	runtime·strequal(bool*, uintptr, void*, void*);
-void	runtime·interequal(bool*, uintptr, void*, void*);
-void	runtime·nilinterequal(bool*, uintptr, void*, void*);
-
-bool	runtime·memeq(void*, void*, uintptr);
-
-void	runtime·memprint(uintptr, void*);
-void	runtime·strprint(uintptr, void*);
-void	runtime·interprint(uintptr, void*);
-void	runtime·nilinterprint(uintptr, void*);
-
-void	runtime·memcopy(uintptr, void*, void*);
-void	runtime·memcopy8(uintptr, void*, void*);
-void	runtime·memcopy16(uintptr, void*, void*);
-void	runtime·memcopy32(uintptr, void*, void*);
-void	runtime·memcopy64(uintptr, void*, void*);
-void	runtime·memcopy128(uintptr, void*, void*);
-void	runtime·strcopy(uintptr, void*, void*);
-void	runtime·algslicecopy(uintptr, void*, void*);
-void	runtime·intercopy(uintptr, void*, void*);
-void	runtime·nilintercopy(uintptr, void*, void*);
-
-/*
- * deferred subroutine calls
- */
-struct Defer
-{
-	int32	siz;
-	bool	special;	// not part of defer frame
-	byte*	argp;		// where args were copied from
-	byte*	pc;
-	FuncVal*	fn;
-	Defer*	link;
-	void*	args[1];	// padded to actual size
-};
-
-// argp used in Defer structs when there is no argp.
-// TODO(rsc): Maybe we could use nil instead, but we've always used -1
-// and I don't want to change this days before the Go 1.3 release.
-#define NoArgs ((byte*)-1)
-
-/*
- * panics
- */
-struct Panic
-{
-	Eface	arg;		// argument to panic
-	uintptr	stackbase;	// g->stackbase in panic
-	Panic*	link;		// link to earlier panic
-	Defer*	defer;		// current executing defer
-	bool	recovered;	// whether this panic is over
-	bool	aborted;	// the panic was aborted
-};
-
-/*
- * stack traces
- */
-typedef struct Stkframe Stkframe;
-struct Stkframe
-{
-	Func*	fn;	// function being run
-	uintptr	pc;	// program counter within fn
-	uintptr	continpc;	// program counter where execution can continue, or 0 if not
-	uintptr	lr;	// program counter at caller aka link register
-	uintptr	sp;	// stack pointer at pc
-	uintptr	fp;	// stack pointer at caller aka frame pointer
-	byte*	varp;	// top of local variables
-	byte*	argp;	// pointer to function arguments
-	uintptr	arglen;	// number of bytes at argp
-};
-
-int32	runtime·gentraceback(uintptr, uintptr, uintptr, G*, int32, uintptr*, int32, bool(*)(Stkframe*, void*), void*, bool);
-void	runtime·traceback(uintptr pc, uintptr sp, uintptr lr, G* gp);
-void	runtime·tracebackothers(G*);
-bool	runtime·haszeroargs(uintptr pc);
-bool	runtime·topofstack(Func*);
-enum
-{
-	// The maximum number of frames we print for a traceback
-	TracebackMaxFrames = 100,
-};
-
-/*
- * external data
- */
-extern	String	runtime·emptystring;
-extern	uintptr runtime·zerobase;
-extern	G**	runtime·allg;
-extern	uintptr runtime·allglen;
-extern	G*	runtime·lastg;
-extern	M*	runtime·allm;
-extern	P**	runtime·allp;
-extern	int32	runtime·gomaxprocs;
-extern	uint32	runtime·needextram;
-extern	uint32	runtime·panicking;
-extern	int8*	runtime·goos;
-extern	int32	runtime·ncpu;
-extern	bool	runtime·iscgo;
-extern 	void	(*runtime·sysargs)(int32, uint8**);
-extern	uintptr	runtime·maxstring;
-extern	uint32	runtime·Hchansize;
-extern	uint32	runtime·cpuid_ecx;
-extern	uint32	runtime·cpuid_edx;
-extern	DebugVars	runtime·debug;
-extern	uintptr	runtime·maxstacksize;
-
-/*
- * common functions and data
- */
-int32	runtime·strcmp(byte*, byte*);
-int32	runtime·strncmp(byte*, byte*, uintptr);
-byte*	runtime·strstr(byte*, byte*);
-intgo	runtime·findnull(byte*);
-intgo	runtime·findnullw(uint16*);
-void	runtime·dump(byte*, int32);
-int32	runtime·runetochar(byte*, int32);
-int32	runtime·charntorune(int32*, uint8*, int32);
-
-
-/*
- * This macro is used when writing C functions
- * called as if they were Go functions.
- * Passed the address of a result before a return statement,
- * it makes sure the result has been flushed to memory
- * before the return.
- *
- * It is difficult to write such functions portably, because
- * of the varying requirements on the alignment of the
- * first output value. Almost all code should write such
- * functions in .goc files, where goc2c (part of cmd/dist)
- * can arrange the correct alignment for the target system.
- * Goc2c also takes care of conveying to the garbage collector
- * which parts of the argument list are inputs vs outputs.
- *
- * Therefore, do NOT use this macro if at all possible.
- */ 
-#define FLUSH(x)	USED(x)
-
-/*
- * GoOutput is a type with the same alignment requirements as the
- * initial output argument from a Go function. Only for use in cases
- * where using goc2c is not possible. See comment on FLUSH above.
- */
-typedef uint64 GoOutput;
-
-void	runtime·gogo(Gobuf*);
-void	runtime·gostartcall(Gobuf*, void(*)(void), void*);
-void	runtime·gostartcallfn(Gobuf*, FuncVal*);
-void	runtime·gosave(Gobuf*);
-void	runtime·lessstack(void);
-void	runtime·goargs(void);
-void	runtime·goenvs(void);
-void	runtime·goenvs_unix(void);
-void*	runtime·getu(void);
-void	runtime·throw(int8*);
-void	runtime·panicstring(int8*);
-bool	runtime·canpanic(G*);
-void	runtime·prints(int8*);
-void	runtime·printf(int8*, ...);
-int32	runtime·snprintf(byte*, int32, int8*, ...);
-byte*	runtime·mchr(byte*, byte, byte*);
-int32	runtime·mcmp(byte*, byte*, uintptr);
-void	runtime·memmove(void*, void*, uintptr);
-void*	runtime·mal(uintptr);
-String	runtime·catstring(String, String);
-String	runtime·gostring(byte*);
-String  runtime·gostringn(byte*, intgo);
-Slice	runtime·gobytes(byte*, intgo);
-String	runtime·gostringnocopy(byte*);
-String	runtime·gostringw(uint16*);
-void	runtime·initsig(void);
-void	runtime·sigenable(uint32 sig);
-void	runtime·sigdisable(uint32 sig);
-int32	runtime·gotraceback(bool *crash);
-void	runtime·goroutineheader(G*);
-int32	runtime·open(int8*, int32, int32);
-int32	runtime·read(int32, void*, int32);
-int32	runtime·write(uintptr, void*, int32); // use uintptr to accommodate windows.
-int32	runtime·close(int32);
-int32	runtime·mincore(void*, uintptr, byte*);
-void	runtime·jmpdefer(FuncVal*, void*);
-void	runtime·exit1(int32);
-void	runtime·ready(G*);
-byte*	runtime·getenv(int8*);
-int32	runtime·atoi(byte*);
-void	runtime·newosproc(M *mp, void *stk);
-void	runtime·mstart(void);
-G*	runtime·malg(int32);
-void	runtime·asminit(void);
-void	runtime·mpreinit(M*);
-void	runtime·minit(void);
-void	runtime·unminit(void);
-void	runtime·signalstack(byte*, int32);
-void	runtime·symtabinit(void);
-Func*	runtime·findfunc(uintptr);
-int32	runtime·funcline(Func*, uintptr, String*);
-int32	runtime·funcarglen(Func*, uintptr);
-int32	runtime·funcspdelta(Func*, uintptr);
-int8*	runtime·funcname(Func*);
-int32	runtime·pcdatavalue(Func*, int32, uintptr);
-void*	runtime·stackalloc(G*, uint32);
-void	runtime·stackfree(G*, void*, Stktop*);
-void	runtime·shrinkstack(G*);
-MCache*	runtime·allocmcache(void);
-void	runtime·freemcache(MCache*);
-void	runtime·mallocinit(void);
-bool	runtime·ifaceeq_c(Iface, Iface);
-bool	runtime·efaceeq_c(Eface, Eface);
-uintptr	runtime·ifacehash(Iface, uintptr);
-uintptr	runtime·efacehash(Eface, uintptr);
-void*	runtime·malloc(uintptr size);
-void	runtime·free(void *v);
-void	runtime·runpanic(Panic*);
-uintptr	runtime·getcallersp(void*);
-int32	runtime·mcount(void);
-int32	runtime·gcount(void);
-void	runtime·mcall(void(*)(G*));
-uint32	runtime·fastrand1(void);
-void	runtime·rewindmorestack(Gobuf*);
-int32	runtime·timediv(int64, int32, int32*);
-int32	runtime·round2(int32 x); // round x up to a power of 2.
-
-// atomic operations
-bool	runtime·cas(uint32*, uint32, uint32);
-bool	runtime·cas64(uint64*, uint64, uint64);
-bool	runtime·casp(void**, void*, void*);
-// Don't confuse with XADD x86 instruction,
-// this one is actually 'addx', that is, add-and-fetch.
-uint32	runtime·xadd(uint32 volatile*, int32);
-uint64	runtime·xadd64(uint64 volatile*, int64);
-uint32	runtime·xchg(uint32 volatile*, uint32);
-uint64	runtime·xchg64(uint64 volatile*, uint64);
-void*	runtime·xchgp(void* volatile*, void*);
-uint32	runtime·atomicload(uint32 volatile*);
-void	runtime·atomicstore(uint32 volatile*, uint32);
-void	runtime·atomicstore64(uint64 volatile*, uint64);
-uint64	runtime·atomicload64(uint64 volatile*);
-void*	runtime·atomicloadp(void* volatile*);
-void	runtime·atomicstorep(void* volatile*, void*);
-
-void	runtime·setmg(M*, G*);
-void	runtime·newextram(void);
-void	runtime·exit(int32);
-void	runtime·breakpoint(void);
-void	runtime·gosched(void);
-void	runtime·gosched0(G*);
-void	runtime·schedtrace(bool);
-void	runtime·park(bool(*)(G*, void*), void*, int8*);
-void	runtime·parkunlock(Lock*, int8*);
-void	runtime·tsleep(int64, int8*);
-M*	runtime·newm(void);
-void	runtime·goexit(void);
-void	runtime·asmcgocall(void (*fn)(void*), void*);
-void	runtime·entersyscall(void);
-void	runtime·reentersyscall(void*, uintptr);
-void	runtime·entersyscallblock(void);
-void	runtime·exitsyscall(void);
-G*	runtime·newproc1(FuncVal*, byte*, int32, int32, void*);
-bool	runtime·sigsend(int32 sig);
-int32	runtime·callers(int32, uintptr*, int32);
-int64	runtime·nanotime(void);	// monotonic time
-int64	runtime·unixnanotime(void); // real time, can skip
-void	runtime·dopanic(int32);
-void	runtime·startpanic(void);
-void	runtime·freezetheworld(void);
-void	runtime·unwindstack(G*, byte*);
-void	runtime·sigprof(uint8 *pc, uint8 *sp, uint8 *lr, G *gp, M *mp);
-void	runtime·resetcpuprofiler(int32);
-void	runtime·setcpuprofilerate(void(*)(uintptr*, int32), int32);
-void	runtime·usleep(uint32);
-int64	runtime·cputicks(void);
-int64	runtime·tickspersecond(void);
-void	runtime·blockevent(int64, int32);
-extern int64 runtime·blockprofilerate;
-void	runtime·addtimer(Timer*);
-bool	runtime·deltimer(Timer*);
-G*	runtime·netpoll(bool);
-void	runtime·netpollinit(void);
-int32	runtime·netpollopen(uintptr, PollDesc*);
-int32   runtime·netpollclose(uintptr);
-void	runtime·netpollready(G**, PollDesc*, int32);
-uintptr	runtime·netpollfd(PollDesc*);
-void	runtime·netpollarm(PollDesc*, int32);
-void**	runtime·netpolluser(PollDesc*);
-bool	runtime·netpollclosing(PollDesc*);
-void	runtime·netpolllock(PollDesc*);
-void	runtime·netpollunlock(PollDesc*);
-void	runtime·crash(void);
-void	runtime·parsedebugvars(void);
-void	_rt0_go(void);
-void*	runtime·funcdata(Func*, int32);
-int32	runtime·setmaxthreads(int32);
-G*	runtime·timejump(void);
-void	runtime·iterate_itabs(void (*callback)(Itab*));
-void	runtime·iterate_finq(void (*callback)(FuncVal*, byte*, uintptr, Type*, PtrType*));
-
-#pragma	varargck	argpos	runtime·printf	1
-#pragma	varargck	type	"c"	int32
-#pragma	varargck	type	"d"	int32
-#pragma	varargck	type	"d"	uint32
-#pragma	varargck	type	"D"	int64
-#pragma	varargck	type	"D"	uint64
-#pragma	varargck	type	"x"	int32
-#pragma	varargck	type	"x"	uint32
-#pragma	varargck	type	"X"	int64
-#pragma	varargck	type	"X"	uint64
-#pragma	varargck	type	"p"	void*
-#pragma	varargck	type	"p"	uintptr
-#pragma	varargck	type	"s"	int8*
-#pragma	varargck	type	"s"	uint8*
-#pragma	varargck	type	"S"	String
-
-void	runtime·stoptheworld(void);
-void	runtime·starttheworld(void);
-extern uint32 runtime·worldsema;
-
-/*
- * mutual exclusion locks.  in the uncontended case,
- * as fast as spin locks (just a few user-level instructions),
- * but on the contention path they sleep in the kernel.
- * a zeroed Lock is unlocked (no need to initialize each lock).
- */
-void	runtime·lock(Lock*);
-void	runtime·unlock(Lock*);
-
-/*
- * sleep and wakeup on one-time events.
- * before any calls to notesleep or notewakeup,
- * must call noteclear to initialize the Note.
- * then, exactly one thread can call notesleep
- * and exactly one thread can call notewakeup (once).
- * once notewakeup has been called, the notesleep
- * will return.  future notesleep will return immediately.
- * subsequent noteclear must be called only after
- * previous notesleep has returned, e.g. it's disallowed
- * to call noteclear straight after notewakeup.
- *
- * notetsleep is like notesleep but wakes up after
- * a given number of nanoseconds even if the event
- * has not yet happened.  if a goroutine uses notetsleep to
- * wake up early, it must wait to call noteclear until it
- * can be sure that no other goroutine is calling
- * notewakeup.
- *
- * notesleep/notetsleep are generally called on g0,
- * notetsleepg is similar to notetsleep but is called on user g.
- */
-void	runtime·noteclear(Note*);
-void	runtime·notesleep(Note*);
-void	runtime·notewakeup(Note*);
-bool	runtime·notetsleep(Note*, int64);  // false - timeout
-bool	runtime·notetsleepg(Note*, int64);  // false - timeout
-
-/*
- * low-level synchronization for implementing the above
- */
-uintptr	runtime·semacreate(void);
-int32	runtime·semasleep(int64);
-void	runtime·semawakeup(M*);
-// or
-void	runtime·futexsleep(uint32*, uint32, int64);
-void	runtime·futexwakeup(uint32*, uint32);
-
-/*
- * Lock-free stack.
- * Initialize uint64 head to 0, compare with 0 to test for emptiness.
- * The stack does not keep pointers to nodes,
- * so they can be garbage collected if there are no other pointers to nodes.
- */
-void	runtime·lfstackpush(uint64 *head, LFNode *node);
-LFNode*	runtime·lfstackpop(uint64 *head);
-
-/*
- * Parallel for over [0, n).
- * body() is executed for each iteration.
- * nthr - total number of worker threads.
- * ctx - arbitrary user context.
- * if wait=true, threads return from parfor() when all work is done;
- * otherwise, threads can return while other threads are still finishing processing.
- */
-ParFor*	runtime·parforalloc(uint32 nthrmax);
-void	runtime·parforsetup(ParFor *desc, uint32 nthr, uint32 n, void *ctx, bool wait, void (*body)(ParFor*, uint32));
-void	runtime·parfordo(ParFor *desc);
-void	runtime·parforiters(ParFor*, uintptr, uintptr*, uintptr*);
-
-/*
- * low level C-called
- */
-// for mmap, we only pass the lower 32 bits of file offset to the 
-// assembly routine; the higher bits (if required), should be provided
-// by the assembly routine as 0.
-uint8*	runtime·mmap(byte*, uintptr, int32, int32, int32, uint32);
-void	runtime·munmap(byte*, uintptr);
-void	runtime·madvise(byte*, uintptr, int32);
-void	runtime·memclr(byte*, uintptr);
-void	runtime·setcallerpc(void*, void*);
-void*	runtime·getcallerpc(void*);
-
-/*
- * runtime go-called
- */
-void	runtime·printbool(bool);
-void	runtime·printbyte(int8);
-void	runtime·printfloat(float64);
-void	runtime·printint(int64);
-void	runtime·printiface(Iface);
-void	runtime·printeface(Eface);
-void	runtime·printstring(String);
-void	runtime·printpc(void*);
-void	runtime·printpointer(void*);
-void	runtime·printuint(uint64);
-void	runtime·printhex(uint64);
-void	runtime·printslice(Slice);
-void	runtime·printcomplex(Complex128);
-void	runtime·newstackcall(FuncVal*, byte*, uint32);
-void	reflect·call(FuncVal*, byte*, uint32, uint32);
-void	runtime·panic(Eface);
-void	runtime·panicindex(void);
-void	runtime·panicslice(void);
-void	runtime·panicdivide(void);
-
-/*
- * runtime c-called (but written in Go)
- */
-void	runtime·printany(Eface);
-void	runtime·newTypeAssertionError(String*, String*, String*, String*, Eface*);
-void	runtime·newErrorString(String, Eface*);
-void	runtime·newErrorCString(int8*, Eface*);
-void	runtime·fadd64c(uint64, uint64, uint64*);
-void	runtime·fsub64c(uint64, uint64, uint64*);
-void	runtime·fmul64c(uint64, uint64, uint64*);
-void	runtime·fdiv64c(uint64, uint64, uint64*);
-void	runtime·fneg64c(uint64, uint64*);
-void	runtime·f32to64c(uint32, uint64*);
-void	runtime·f64to32c(uint64, uint32*);
-void	runtime·fcmp64c(uint64, uint64, int32*, bool*);
-void	runtime·fintto64c(int64, uint64*);
-void	runtime·f64tointc(uint64, int64*, bool*);
-
-/*
- * wrapped for go users
- */
-float64	runtime·Inf(int32 sign);
-float64	runtime·NaN(void);
-float32	runtime·float32frombits(uint32 i);
-uint32	runtime·float32tobits(float32 f);
-float64	runtime·float64frombits(uint64 i);
-uint64	runtime·float64tobits(float64 f);
-float64	runtime·frexp(float64 d, int32 *ep);
-bool	runtime·isInf(float64 f, int32 sign);
-bool	runtime·isNaN(float64 f);
-float64	runtime·ldexp(float64 d, int32 e);
-float64	runtime·modf(float64 d, float64 *ip);
-void	runtime·semacquire(uint32*, bool);
-void	runtime·semrelease(uint32*);
-int32	runtime·gomaxprocsfunc(int32 n);
-void	runtime·procyield(uint32);
-void	runtime·osyield(void);
-void	runtime·lockOSThread(void);
-void	runtime·unlockOSThread(void);
-bool	runtime·lockedOSThread(void);
-
-bool	runtime·showframe(Func*, G*);
-void	runtime·printcreatedby(G*);
-
-void	runtime·ifaceE2I(InterfaceType*, Eface, Iface*);
-bool	runtime·ifaceE2I2(InterfaceType*, Eface, Iface*);
-uintptr	runtime·memlimit(void);
-
-// float.c
-extern float64 runtime·nan;
-extern float64 runtime·posinf;
-extern float64 runtime·neginf;
-extern uint64 ·nan;
-extern uint64 ·posinf;
-extern uint64 ·neginf;
-#define ISNAN(f) ((f) != (f))
-
-enum
-{
-	UseSpanType = 1,
-};
diff --git a/src/pkg/runtime/runtime1.goc b/src/pkg/runtime/runtime1.goc
deleted file mode 100644
index c6f6b62..0000000
--- a/src/pkg/runtime/runtime1.goc
+++ /dev/null
@@ -1,128 +0,0 @@
-// Copyright 2010 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package runtime
-#include "runtime.h"
-#include "arch_GOARCH.h"
-#include "type.h"
-
-func GOMAXPROCS(n int) (ret int) {
-	ret = runtime·gomaxprocsfunc(n);
-}
-
-func NumCPU() (ret int) {
-	ret = runtime·ncpu;
-}
-
-func NumCgoCall() (ret int64) {
-	M *mp;
-
-	ret = 0;
-	for(mp=runtime·atomicloadp(&runtime·allm); mp; mp=mp->alllink)
-		ret += mp->ncgocall;
-}
-
-func newParFor(nthrmax uint32) (desc *ParFor) {
-	desc = runtime·parforalloc(nthrmax);
-}
-
-func parForSetup(desc *ParFor, nthr uint32, n uint32, ctx *byte, wait bool, body *byte) {
-	runtime·parforsetup(desc, nthr, n, ctx, wait, *(void(**)(ParFor*, uint32))body);
-}
-
-func parForDo(desc *ParFor) {
-	runtime·parfordo(desc);
-}
-
-func parForIters(desc *ParFor, tid uintptr) (start uintptr, end uintptr) {
-	runtime·parforiters(desc, tid, &start, &end);
-}
-
-func gogoBytes() (x int32) {
-	x = RuntimeGogoBytes;
-}
-
-func typestring(e Eface) (s String) {
-	s = *e.type->string;
-}
-
-func golockedOSThread() (ret bool) {
-	ret = runtime·lockedOSThread();
-}
-
-func NumGoroutine() (ret int) {
-	ret = runtime·gcount();
-}
-
-func getgoroot() (out String) {
-	byte *p;
-
-	p = runtime·getenv("GOROOT");
-	out = runtime·gostringnocopy(p);
-}
-
-/*
- * We assume that all architectures turn faults and the like
- * into apparent calls to runtime.sigpanic.  If we see a "call"
- * to runtime.sigpanic, we do not back up the PC to find the
- * line number of the CALL instruction, because there is no CALL.
- */
-void	runtime·sigpanic(void);
-
-func Caller(skip int) (retpc uintptr, retfile String, retline int, retbool bool) {
-	Func *f, *g;
-	uintptr pc;
-	uintptr rpc[2];
-
-	/*
-	 * Ask for two PCs: the one we were asked for
-	 * and what it called, so that we can see if it
-	 * "called" sigpanic.
-	 */
-	retpc = 0;
-	if(runtime·callers(1+skip-1, rpc, 2) < 2) {
-		retfile = runtime·emptystring;
-		retline = 0;
-		retbool = false;
-	} else if((f = runtime·findfunc(rpc[1])) == nil) {
-		retfile = runtime·emptystring;
-		retline = 0;
-		retbool = true;  // have retpc at least
-	} else {
-		retpc = rpc[1];
-		pc = retpc;
-		g = runtime·findfunc(rpc[0]);
-		if(pc > f->entry && (g == nil || g->entry != (uintptr)runtime·sigpanic))
-			pc--;
-		retline = runtime·funcline(f, pc, &retfile);
-		retbool = true;
-	}
-}
-
-func Callers(skip int, pc Slice) (retn int) {
-	// runtime.callers uses pc.array==nil as a signal
-	// to print a stack trace.  Pick off 0-length pc here
-	// so that we don't let a nil pc slice get to it.
-	if(pc.len == 0)
-		retn = 0;
-	else
-		retn = runtime·callers(skip, (uintptr*)pc.array, pc.len);
-}
-
-func runtime∕pprof·runtime_cyclesPerSecond() (res int64) {
-	res = runtime·tickspersecond();
-}
-
-func sync·runtime_procPin() (p int) {
-	M *mp;
-
-	mp = m;
-	// Disable preemption.
-	mp->locks++;
-	p = mp->p->id;
-}
-
-func sync·runtime_procUnpin() {
-	m->locks--;
-}
diff --git a/src/pkg/runtime/runtime_test.go b/src/pkg/runtime/runtime_test.go
deleted file mode 100644
index 5a9f52f..0000000
--- a/src/pkg/runtime/runtime_test.go
+++ /dev/null
@@ -1,204 +0,0 @@
-// Copyright 2012 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package runtime_test
-
-import (
-	"io"
-	"io/ioutil"
-	"os"
-	"os/exec"
-	. "runtime"
-	"runtime/debug"
-	"strconv"
-	"strings"
-	"testing"
-	"unsafe"
-)
-
-var errf error
-
-func errfn() error {
-	return errf
-}
-
-func errfn1() error {
-	return io.EOF
-}
-
-func BenchmarkIfaceCmp100(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		for j := 0; j < 100; j++ {
-			if errfn() == io.EOF {
-				b.Fatal("bad comparison")
-			}
-		}
-	}
-}
-
-func BenchmarkIfaceCmpNil100(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		for j := 0; j < 100; j++ {
-			if errfn1() == nil {
-				b.Fatal("bad comparison")
-			}
-		}
-	}
-}
-
-func BenchmarkDefer(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		defer1()
-	}
-}
-
-func defer1() {
-	defer func(x, y, z int) {
-		if recover() != nil || x != 1 || y != 2 || z != 3 {
-			panic("bad recover")
-		}
-	}(1, 2, 3)
-	return
-}
-
-func BenchmarkDefer10(b *testing.B) {
-	for i := 0; i < b.N/10; i++ {
-		defer2()
-	}
-}
-
-func defer2() {
-	for i := 0; i < 10; i++ {
-		defer func(x, y, z int) {
-			if recover() != nil || x != 1 || y != 2 || z != 3 {
-				panic("bad recover")
-			}
-		}(1, 2, 3)
-	}
-}
-
-func BenchmarkDeferMany(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		defer func(x, y, z int) {
-			if recover() != nil || x != 1 || y != 2 || z != 3 {
-				panic("bad recover")
-			}
-		}(1, 2, 3)
-	}
-}
-
-// The profiling signal handler needs to know whether it is executing runtime.gogo.
-// The constant RuntimeGogoBytes in arch_*.h gives the size of the function;
-// we don't have a way to obtain it from the linker (perhaps someday).
-// Test that the constant matches the size determined by 'go tool nm -S'.
-// The value reported will include the padding between runtime.gogo and the
-// next function in memory. That's fine.
-func TestRuntimeGogoBytes(t *testing.T) {
-	if GOOS == "nacl" {
-		t.Skip("skipping on nacl")
-	}
-
-	dir, err := ioutil.TempDir("", "go-build")
-	if err != nil {
-		t.Fatalf("failed to create temp directory: %v", err)
-	}
-	defer os.RemoveAll(dir)
-
-	out, err := exec.Command("go", "build", "-o", dir+"/hello", "../../../test/helloworld.go").CombinedOutput()
-	if err != nil {
-		t.Fatalf("building hello world: %v\n%s", err, out)
-	}
-
-	out, err = exec.Command("go", "tool", "nm", "-size", dir+"/hello").CombinedOutput()
-	if err != nil {
-		t.Fatalf("go tool nm: %v\n%s", err, out)
-	}
-
-	for _, line := range strings.Split(string(out), "\n") {
-		f := strings.Fields(line)
-		if len(f) == 4 && f[3] == "runtime.gogo" {
-			size, _ := strconv.Atoi(f[1])
-			if GogoBytes() != int32(size) {
-				t.Fatalf("RuntimeGogoBytes = %d, should be %d", GogoBytes(), size)
-			}
-			return
-		}
-	}
-
-	t.Fatalf("go tool nm did not report size for runtime.gogo")
-}
-
-// golang.org/issue/7063
-func TestStopCPUProfilingWithProfilerOff(t *testing.T) {
-	SetCPUProfileRate(0)
-}
-
-// Addresses to test for faulting behavior.
-// This is less a test of SetPanicOnFault and more a check that
-// the operating system and the runtime can process these faults
-// correctly. That is, we're indirectly testing that without SetPanicOnFault
-// these would manage to turn into ordinary crashes.
-// Note that these are truncated on 32-bit systems, so the bottom 32 bits
-// of the larger addresses must themselves be invalid addresses.
-// We might get unlucky and the OS might have mapped one of these
-// addresses, but probably not: they're all in the first page, very high
-// adderesses that normally an OS would reserve for itself, or malformed
-// addresses. Even so, we might have to remove one or two on different
-// systems. We will see.
-
-var faultAddrs = []uint64{
-	// low addresses
-	0,
-	1,
-	0xfff,
-	// high (kernel) addresses
-	// or else malformed.
-	0xffffffffffffffff,
-	0xfffffffffffff001,
-	// no 0xffffffffffff0001; 0xffff0001 is mapped for 32-bit user space on OS X
-	// no 0xfffffffffff00001; 0xfff00001 is mapped for 32-bit user space sometimes on Linux
-	0xffffffffff000001,
-	0xfffffffff0000001,
-	0xffffffff00000001,
-	0xfffffff000000001,
-	0xffffff0000000001,
-	0xfffff00000000001,
-	0xffff000000000001,
-	0xfff0000000000001,
-	0xff00000000000001,
-	0xf000000000000001,
-	0x8000000000000001,
-}
-
-func TestSetPanicOnFault(t *testing.T) {
-	// This currently results in a fault in the signal trampoline on
-	// dragonfly/386 - see issue 7421.
-	if GOOS == "dragonfly" && GOARCH == "386" {
-		t.Skip("skipping test on dragonfly/386")
-	}
-
-	old := debug.SetPanicOnFault(true)
-	defer debug.SetPanicOnFault(old)
-
-	for _, addr := range faultAddrs {
-		testSetPanicOnFault(t, uintptr(addr))
-	}
-}
-
-func testSetPanicOnFault(t *testing.T, addr uintptr) {
-	if GOOS == "nacl" {
-		t.Skip("nacl doesn't seem to fault on high addresses")
-	}
-
-	defer func() {
-		if err := recover(); err == nil {
-			t.Fatalf("did not find error in recover")
-		}
-	}()
-
-	var p *int
-	p = (*int)(unsafe.Pointer(addr))
-	println(*p)
-	t.Fatalf("still here - should have faulted on address %#x", addr)
-}
diff --git a/src/pkg/runtime/sema.goc b/src/pkg/runtime/sema.goc
deleted file mode 100644
index c1e8e4e..0000000
--- a/src/pkg/runtime/sema.goc
+++ /dev/null
@@ -1,294 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Semaphore implementation exposed to Go.
-// Intended use is provide a sleep and wakeup
-// primitive that can be used in the contended case
-// of other synchronization primitives.
-// Thus it targets the same goal as Linux's futex,
-// but it has much simpler semantics.
-//
-// That is, don't think of these as semaphores.
-// Think of them as a way to implement sleep and wakeup
-// such that every sleep is paired with a single wakeup,
-// even if, due to races, the wakeup happens before the sleep.
-//
-// See Mullender and Cox, ``Semaphores in Plan 9,''
-// http://swtch.com/semaphore.pdf
-
-package sync
-#include "runtime.h"
-#include "arch_GOARCH.h"
-#include "../../cmd/ld/textflag.h"
-
-typedef struct SemaWaiter SemaWaiter;
-struct SemaWaiter
-{
-	uint32 volatile*	addr;
-	G*	g;
-	int64	releasetime;
-	int32	nrelease;	// -1 for acquire
-	SemaWaiter*	prev;
-	SemaWaiter*	next;
-};
-
-typedef struct SemaRoot SemaRoot;
-struct SemaRoot
-{
-	Lock;
-	SemaWaiter*	head;
-	SemaWaiter*	tail;
-	// Number of waiters. Read w/o the lock.
-	uint32 volatile	nwait;
-};
-
-// Prime to not correlate with any user patterns.
-#define SEMTABLESZ 251
-
-struct semtable
-{
-	SemaRoot;
-	uint8 pad[CacheLineSize-sizeof(SemaRoot)];
-};
-#pragma dataflag NOPTR /* mark semtable as 'no pointers', hiding from garbage collector */
-static struct semtable semtable[SEMTABLESZ];
-
-static SemaRoot*
-semroot(uint32 *addr)
-{
-	return &semtable[((uintptr)addr >> 3) % SEMTABLESZ];
-}
-
-static void
-semqueue(SemaRoot *root, uint32 volatile *addr, SemaWaiter *s)
-{
-	s->g = g;
-	s->addr = addr;
-	s->next = nil;
-	s->prev = root->tail;
-	if(root->tail)
-		root->tail->next = s;
-	else
-		root->head = s;
-	root->tail = s;
-}
-
-static void
-semdequeue(SemaRoot *root, SemaWaiter *s)
-{
-	if(s->next)
-		s->next->prev = s->prev;
-	else
-		root->tail = s->prev;
-	if(s->prev)
-		s->prev->next = s->next;
-	else
-		root->head = s->next;
-	s->prev = nil;
-	s->next = nil;
-}
-
-static int32
-cansemacquire(uint32 *addr)
-{
-	uint32 v;
-
-	while((v = runtime·atomicload(addr)) > 0)
-		if(runtime·cas(addr, v, v-1))
-			return 1;
-	return 0;
-}
-
-void
-runtime·semacquire(uint32 volatile *addr, bool profile)
-{
-	SemaWaiter s;	// Needs to be allocated on stack, otherwise garbage collector could deallocate it
-	SemaRoot *root;
-	int64 t0;
-	
-	// Easy case.
-	if(cansemacquire(addr))
-		return;
-
-	// Harder case:
-	//	increment waiter count
-	//	try cansemacquire one more time, return if succeeded
-	//	enqueue itself as a waiter
-	//	sleep
-	//	(waiter descriptor is dequeued by signaler)
-	root = semroot(addr);
-	t0 = 0;
-	s.releasetime = 0;
-	if(profile && runtime·blockprofilerate > 0) {
-		t0 = runtime·cputicks();
-		s.releasetime = -1;
-	}
-	for(;;) {
-		runtime·lock(root);
-		// Add ourselves to nwait to disable "easy case" in semrelease.
-		runtime·xadd(&root->nwait, 1);
-		// Check cansemacquire to avoid missed wakeup.
-		if(cansemacquire(addr)) {
-			runtime·xadd(&root->nwait, -1);
-			runtime·unlock(root);
-			return;
-		}
-		// Any semrelease after the cansemacquire knows we're waiting
-		// (we set nwait above), so go to sleep.
-		semqueue(root, addr, &s);
-		runtime·parkunlock(root, "semacquire");
-		if(cansemacquire(addr)) {
-			if(t0)
-				runtime·blockevent(s.releasetime - t0, 3);
-			return;
-		}
-	}
-}
-
-void
-runtime·semrelease(uint32 volatile *addr)
-{
-	SemaWaiter *s;
-	SemaRoot *root;
-
-	root = semroot(addr);
-	runtime·xadd(addr, 1);
-
-	// Easy case: no waiters?
-	// This check must happen after the xadd, to avoid a missed wakeup
-	// (see loop in semacquire).
-	if(runtime·atomicload(&root->nwait) == 0)
-		return;
-
-	// Harder case: search for a waiter and wake it.
-	runtime·lock(root);
-	if(runtime·atomicload(&root->nwait) == 0) {
-		// The count is already consumed by another goroutine,
-		// so no need to wake up another goroutine.
-		runtime·unlock(root);
-		return;
-	}
-	for(s = root->head; s; s = s->next) {
-		if(s->addr == addr) {
-			runtime·xadd(&root->nwait, -1);
-			semdequeue(root, s);
-			break;
-		}
-	}
-	runtime·unlock(root);
-	if(s) {
-		if(s->releasetime)
-			s->releasetime = runtime·cputicks();
-		runtime·ready(s->g);
-	}
-}
-
-// TODO(dvyukov): move to netpoll.goc once it's used by all OSes.
-void net·runtime_Semacquire(uint32 *addr)
-{
-	runtime·semacquire(addr, true);
-}
-
-void net·runtime_Semrelease(uint32 *addr)
-{
-	runtime·semrelease(addr);
-}
-
-func runtime_Semacquire(addr *uint32) {
-	runtime·semacquire(addr, true);
-}
-
-func runtime_Semrelease(addr *uint32) {
-	runtime·semrelease(addr);
-}
-
-typedef struct SyncSema SyncSema;
-struct SyncSema
-{
-	Lock;
-	SemaWaiter*	head;
-	SemaWaiter*	tail;
-};
-
-func runtime_Syncsemcheck(size uintptr) {
-	if(size != sizeof(SyncSema)) {
-		runtime·printf("bad SyncSema size: sync:%D runtime:%D\n", (int64)size, (int64)sizeof(SyncSema));
-		runtime·throw("bad SyncSema size");
-	}
-}
-
-// Syncsemacquire waits for a pairing Syncsemrelease on the same semaphore s.
-func runtime_Syncsemacquire(s *SyncSema) {
-	SemaWaiter w, *wake;
-	int64 t0;
-
-	w.g = g;
-	w.nrelease = -1;
-	w.next = nil;
-	w.releasetime = 0;
-	t0 = 0;
-	if(runtime·blockprofilerate > 0) {
-		t0 = runtime·cputicks();
-		w.releasetime = -1;
-	}
-
-	runtime·lock(s);
-	if(s->head && s->head->nrelease > 0) {
-		// have pending release, consume it
-		wake = nil;
-		s->head->nrelease--;
-		if(s->head->nrelease == 0) {
-			wake = s->head;
-			s->head = wake->next;
-			if(s->head == nil)
-				s->tail = nil;
-		}
-		runtime·unlock(s);
-		if(wake)
-			runtime·ready(wake->g);
-	} else {
-		// enqueue itself
-		if(s->tail == nil)
-			s->head = &w;
-		else
-			s->tail->next = &w;
-		s->tail = &w;
-		runtime·parkunlock(s, "semacquire");
-		if(t0)
-			runtime·blockevent(w.releasetime - t0, 2);
-	}
-}
-
-// Syncsemrelease waits for n pairing Syncsemacquire on the same semaphore s.
-func runtime_Syncsemrelease(s *SyncSema, n uint32) {
-	SemaWaiter w, *wake;
-
-	w.g = g;
-	w.nrelease = (int32)n;
-	w.next = nil;
-	w.releasetime = 0;
-
-	runtime·lock(s);
-	while(w.nrelease > 0 && s->head && s->head->nrelease < 0) {
-		// have pending acquire, satisfy it
-		wake = s->head;
-		s->head = wake->next;
-		if(s->head == nil)
-			s->tail = nil;
-		if(wake->releasetime)
-			wake->releasetime = runtime·cputicks();
-		runtime·ready(wake->g);
-		w.nrelease--;
-	}
-	if(w.nrelease > 0) {
-		// enqueue itself
-		if(s->tail == nil)
-			s->head = &w;
-		else
-			s->tail->next = &w;
-		s->tail = &w;
-		runtime·parkunlock(s, "semarelease");
-	} else
-		runtime·unlock(s);
-}
diff --git a/src/pkg/runtime/signal_386.c b/src/pkg/runtime/signal_386.c
deleted file mode 100644
index 70fcc6a..0000000
--- a/src/pkg/runtime/signal_386.c
+++ /dev/null
@@ -1,122 +0,0 @@
-// Copyright 2013 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build darwin dragonfly freebsd linux nacl netbsd openbsd
-
-#include "runtime.h"
-#include "defs_GOOS_GOARCH.h"
-#include "os_GOOS.h"
-#include "signal_GOOS_GOARCH.h"
-#include "signals_GOOS.h"
-
-void
-runtime·dumpregs(Siginfo *info, void *ctxt)
-{
-	USED(info);
-	USED(ctxt);
-	
-	runtime·printf("eax     %x\n", SIG_EAX(info, ctxt));
-	runtime·printf("ebx     %x\n", SIG_EBX(info, ctxt));
-	runtime·printf("ecx     %x\n", SIG_ECX(info, ctxt));
-	runtime·printf("edx     %x\n", SIG_EDX(info, ctxt));
-	runtime·printf("edi     %x\n", SIG_EDI(info, ctxt));
-	runtime·printf("esi     %x\n", SIG_ESI(info, ctxt));
-	runtime·printf("ebp     %x\n", SIG_EBP(info, ctxt));
-	runtime·printf("esp     %x\n", SIG_ESP(info, ctxt));
-	runtime·printf("eip     %x\n", SIG_EIP(info, ctxt));
-	runtime·printf("eflags  %x\n", SIG_EFLAGS(info, ctxt));
-	runtime·printf("cs      %x\n", SIG_CS(info, ctxt));
-	runtime·printf("fs      %x\n", SIG_FS(info, ctxt));
-	runtime·printf("gs      %x\n", SIG_GS(info, ctxt));
-}
-
-void
-runtime·sighandler(int32 sig, Siginfo *info, void *ctxt, G *gp)
-{
-	uintptr *sp;
-	SigTab *t;
-	bool crash;
-
-	if(sig == SIGPROF) {
-		runtime·sigprof((byte*)SIG_EIP(info, ctxt), (byte*)SIG_ESP(info, ctxt), nil, gp, m);
-		return;
-	}
-
-	t = &runtime·sigtab[sig];
-	if(SIG_CODE0(info, ctxt) != SI_USER && (t->flags & SigPanic)) {
-		// Make it look like a call to the signal func.
-		// Have to pass arguments out of band since
-		// augmenting the stack frame would break
-		// the unwinding code.
-		gp->sig = sig;
-		gp->sigcode0 = SIG_CODE0(info, ctxt);
-		gp->sigcode1 = SIG_CODE1(info, ctxt);
-		gp->sigpc = SIG_EIP(info, ctxt);
-
-#ifdef GOOS_darwin
-		// Work around Leopard bug that doesn't set FPE_INTDIV.
-		// Look at instruction to see if it is a divide.
-		// Not necessary in Snow Leopard (si_code will be != 0).
-		if(sig == SIGFPE && gp->sigcode0 == 0) {
-			byte *pc;
-			pc = (byte*)gp->sigpc;
-			if(pc[0] == 0x66)	// 16-bit instruction prefix
-				pc++;
-			if(pc[0] == 0xF6 || pc[0] == 0xF7)
-				gp->sigcode0 = FPE_INTDIV;
-		}
-#endif
-
-		// Only push runtime·sigpanic if eip != 0.
-		// If eip == 0, probably panicked because of a
-		// call to a nil func.  Not pushing that onto sp will
-		// make the trace look like a call to runtime·sigpanic instead.
-		// (Otherwise the trace will end at runtime·sigpanic and we
-		// won't get to see who faulted.)
-		if(SIG_EIP(info, ctxt) != 0) {
-			sp = (uintptr*)SIG_ESP(info, ctxt);
-			*--sp = SIG_EIP(info, ctxt);
-			SIG_ESP(info, ctxt) = (uintptr)sp;
-		}
-		SIG_EIP(info, ctxt) = (uintptr)runtime·sigpanic;
-		return;
-	}
-
-	if(SIG_CODE0(info, ctxt) == SI_USER || (t->flags & SigNotify))
-		if(runtime·sigsend(sig))
-			return;
-	if(t->flags & SigKill)
-		runtime·exit(2);
-	if(!(t->flags & SigThrow))
-		return;
-
-	m->throwing = 1;
-	m->caughtsig = gp;
-	runtime·startpanic();
-
-	if(sig < 0 || sig >= NSIG)
-		runtime·printf("Signal %d\n", sig);
-	else
-		runtime·printf("%s\n", runtime·sigtab[sig].name);
-
-	runtime·printf("PC=%x\n", SIG_EIP(info, ctxt));
-	if(m->lockedg != nil && m->ncgo > 0 && gp == m->g0) {
-		runtime·printf("signal arrived during cgo execution\n");
-		gp = m->lockedg;
-	}	
-	runtime·printf("\n");
-
-	if(runtime·gotraceback(&crash)){
-		runtime·goroutineheader(gp);
-		runtime·traceback(SIG_EIP(info, ctxt), SIG_ESP(info, ctxt), 0, gp);
-		runtime·tracebackothers(gp);
-		runtime·printf("\n");
-		runtime·dumpregs(info, ctxt);
-	}
-	
-	if(crash)
-		runtime·crash();
-
-	runtime·exit(2);
-}
diff --git a/src/pkg/runtime/signal_amd64x.c b/src/pkg/runtime/signal_amd64x.c
deleted file mode 100644
index 04026f3..0000000
--- a/src/pkg/runtime/signal_amd64x.c
+++ /dev/null
@@ -1,156 +0,0 @@
-// Copyright 2013 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build amd64 amd64p32
-// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris
-
-#include "runtime.h"
-#include "defs_GOOS_GOARCH.h"
-#include "os_GOOS.h"
-#include "signal_GOOS_GOARCH.h"
-#include "signals_GOOS.h"
-
-void
-runtime·dumpregs(Siginfo *info, void *ctxt)
-{
-	USED(info);
-	USED(ctxt);
-	
-	runtime·printf("rax     %X\n", SIG_RAX(info, ctxt));
-	runtime·printf("rbx     %X\n", SIG_RBX(info, ctxt));
-	runtime·printf("rcx     %X\n", SIG_RCX(info, ctxt));
-	runtime·printf("rdx     %X\n", SIG_RDX(info, ctxt));
-	runtime·printf("rdi     %X\n", SIG_RDI(info, ctxt));
-	runtime·printf("rsi     %X\n", SIG_RSI(info, ctxt));
-	runtime·printf("rbp     %X\n", SIG_RBP(info, ctxt));
-	runtime·printf("rsp     %X\n", SIG_RSP(info, ctxt));
-	runtime·printf("r8      %X\n", SIG_R8(info, ctxt) );
-	runtime·printf("r9      %X\n", SIG_R9(info, ctxt) );
-	runtime·printf("r10     %X\n", SIG_R10(info, ctxt));
-	runtime·printf("r11     %X\n", SIG_R11(info, ctxt));
-	runtime·printf("r12     %X\n", SIG_R12(info, ctxt));
-	runtime·printf("r13     %X\n", SIG_R13(info, ctxt));
-	runtime·printf("r14     %X\n", SIG_R14(info, ctxt));
-	runtime·printf("r15     %X\n", SIG_R15(info, ctxt));
-	runtime·printf("rip     %X\n", SIG_RIP(info, ctxt));
-	runtime·printf("rflags  %X\n", SIG_RFLAGS(info, ctxt));
-	runtime·printf("cs      %X\n", SIG_CS(info, ctxt));
-	runtime·printf("fs      %X\n", SIG_FS(info, ctxt));
-	runtime·printf("gs      %X\n", SIG_GS(info, ctxt));
-}
-
-void
-runtime·sighandler(int32 sig, Siginfo *info, void *ctxt, G *gp)
-{
-	uintptr *sp;
-	SigTab *t;
-	bool crash;
-
-	if(sig == SIGPROF) {
-		runtime·sigprof((byte*)SIG_RIP(info, ctxt), (byte*)SIG_RSP(info, ctxt), nil, gp, m);
-		return;
-	}
-
-#ifdef GOOS_darwin
-	// x86-64 has 48-bit virtual addresses. The top 16 bits must echo bit 47.
-	// The hardware delivers a different kind of fault for a malformed address
-	// than it does for an attempt to access a valid but unmapped address.
-	// OS X 10.9.2 mishandles the malformed address case, making it look like
-	// a user-generated signal (like someone ran kill -SEGV ourpid).
-	// We pass user-generated signals to os/signal, or else ignore them.
-	// Doing that here - and returning to the faulting code - results in an
-	// infinite loop. It appears the best we can do is rewrite what the kernel
-	// delivers into something more like the truth. The address used below
-	// has very little chance of being the one that caused the fault, but it is
-	// malformed, it is clearly not a real pointer, and if it does get printed
-	// in real life, people will probably search for it and find this code.
-	// There are no Google hits for b01dfacedebac1e or 0xb01dfacedebac1e
-	// as I type this comment.
-	if(sig == SIGSEGV && SIG_CODE0(info, ctxt) == SI_USER) {
-		SIG_CODE0(info, ctxt) = SI_USER+1;
-		info->si_addr = (void*)(uintptr)0xb01dfacedebac1eULL;
-	}
-#endif
-
-	t = &runtime·sigtab[sig];
-	if(SIG_CODE0(info, ctxt) != SI_USER && (t->flags & SigPanic)) {
-		// Make it look like a call to the signal func.
-		// Have to pass arguments out of band since
-		// augmenting the stack frame would break
-		// the unwinding code.
-		gp->sig = sig;
-		gp->sigcode0 = SIG_CODE0(info, ctxt);
-		gp->sigcode1 = SIG_CODE1(info, ctxt);
-		gp->sigpc = SIG_RIP(info, ctxt);
-
-#ifdef GOOS_darwin
-		// Work around Leopard bug that doesn't set FPE_INTDIV.
-		// Look at instruction to see if it is a divide.
-		// Not necessary in Snow Leopard (si_code will be != 0).
-		if(sig == SIGFPE && gp->sigcode0 == 0) {
-			byte *pc;
-			pc = (byte*)gp->sigpc;
-			if((pc[0]&0xF0) == 0x40)	// 64-bit REX prefix
-				pc++;
-			else if(pc[0] == 0x66)	// 16-bit instruction prefix
-				pc++;
-			if(pc[0] == 0xF6 || pc[0] == 0xF7)
-				gp->sigcode0 = FPE_INTDIV;
-		}
-#endif
-
-		// Only push runtime·sigpanic if rip != 0.
-		// If rip == 0, probably panicked because of a
-		// call to a nil func.  Not pushing that onto sp will
-		// make the trace look like a call to runtime·sigpanic instead.
-		// (Otherwise the trace will end at runtime·sigpanic and we
-		// won't get to see who faulted.)
-		if(SIG_RIP(info, ctxt) != 0) {
-			sp = (uintptr*)SIG_RSP(info, ctxt);
-			if(sizeof(uintreg) > sizeof(uintptr))
-				*--sp = 0;
-			*--sp = SIG_RIP(info, ctxt);
-			SIG_RSP(info, ctxt) = (uintptr)sp;
-		}
-		SIG_RIP(info, ctxt) = (uintptr)runtime·sigpanic;
-		return;
-	}
-
-	if(SIG_CODE0(info, ctxt) == SI_USER || (t->flags & SigNotify))
-		if(runtime·sigsend(sig))
-			return;
-	if(t->flags & SigKill)
-		runtime·exit(2);
-	if(!(t->flags & SigThrow))
-		return;
-
-	m->throwing = 1;
-	m->caughtsig = gp;
-	runtime·startpanic();
-
-	if(sig < 0 || sig >= NSIG)
-		runtime·printf("Signal %d\n", sig);
-	else
-		runtime·printf("%s\n", runtime·sigtab[sig].name);
-
-	runtime·printf("PC=%X\n", SIG_RIP(info, ctxt));
-	if(m->lockedg != nil && m->ncgo > 0 && gp == m->g0) {
-		runtime·printf("signal arrived during cgo execution\n");
-		gp = m->lockedg;
-	}
-	runtime·printf("\n");
-
-	if(runtime·gotraceback(&crash)){
-		runtime·goroutineheader(gp);
-		runtime·traceback(SIG_RIP(info, ctxt), SIG_RSP(info, ctxt), 0, gp);
-		runtime·tracebackothers(gp);
-		runtime·printf("\n");
-		runtime·dumpregs(info, ctxt);
-	}
-	
-	if(crash)
-		runtime·crash();
-
-	runtime·exit(2);
-}
diff --git a/src/pkg/runtime/signal_arm.c b/src/pkg/runtime/signal_arm.c
deleted file mode 100644
index 9b2a43d..0000000
--- a/src/pkg/runtime/signal_arm.c
+++ /dev/null
@@ -1,122 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build darwin dragonfly freebsd linux netbsd openbsd
-
-#include "runtime.h"
-#include "defs_GOOS_GOARCH.h"
-#include "os_GOOS.h"
-#include "signal_GOOS_GOARCH.h"
-#include "signals_GOOS.h"
-
-void
-runtime·dumpregs(Siginfo *info, void *ctxt)
-{
-	USED(info);
-	USED(ctxt);
-
-	runtime·printf("trap    %x\n", SIG_TRAP(info, ctxt));
-	runtime·printf("error   %x\n", SIG_ERROR(info, ctxt));
-	runtime·printf("oldmask %x\n", SIG_OLDMASK(info, ctxt));
-	runtime·printf("r0      %x\n", SIG_R0(info, ctxt));
-	runtime·printf("r1      %x\n", SIG_R1(info, ctxt));
-	runtime·printf("r2      %x\n", SIG_R2(info, ctxt));
-	runtime·printf("r3      %x\n", SIG_R3(info, ctxt));
-	runtime·printf("r4      %x\n", SIG_R4(info, ctxt));
-	runtime·printf("r5      %x\n", SIG_R5(info, ctxt));
-	runtime·printf("r6      %x\n", SIG_R6(info, ctxt));
-	runtime·printf("r7      %x\n", SIG_R7(info, ctxt));
-	runtime·printf("r8      %x\n", SIG_R8(info, ctxt));
-	runtime·printf("r9      %x\n", SIG_R9(info, ctxt));
-	runtime·printf("r10     %x\n", SIG_R10(info, ctxt));
-	runtime·printf("fp      %x\n", SIG_FP(info, ctxt));
-	runtime·printf("ip      %x\n", SIG_IP(info, ctxt));
-	runtime·printf("sp      %x\n", SIG_SP(info, ctxt));
-	runtime·printf("lr      %x\n", SIG_LR(info, ctxt));
-	runtime·printf("pc      %x\n", SIG_PC(info, ctxt));
-	runtime·printf("cpsr    %x\n", SIG_CPSR(info, ctxt));
-	runtime·printf("fault   %x\n", SIG_FAULT(info, ctxt));
-}
-
-void
-runtime·sighandler(int32 sig, Siginfo *info, void *ctxt, G *gp)
-{
-	SigTab *t;
-	bool crash;
-
-	if(sig == SIGPROF) {
-		runtime·sigprof((uint8*)SIG_PC(info, ctxt), (uint8*)SIG_SP(info, ctxt), (uint8*)SIG_LR(info, ctxt), gp, m);
-		return;
-	}
-
-	t = &runtime·sigtab[sig];
-	if(SIG_CODE0(info, ctxt) != SI_USER && (t->flags & SigPanic)) {
-		// Make it look like a call to the signal func.
-		// Have to pass arguments out of band since
-		// augmenting the stack frame would break
-		// the unwinding code.
-		gp->sig = sig;
-		gp->sigcode0 = SIG_CODE0(info, ctxt);
-		gp->sigcode1 = SIG_FAULT(info, ctxt);
-		gp->sigpc = SIG_PC(info, ctxt);
-
-		// We arrange lr, and pc to pretend the panicking
-		// function calls sigpanic directly.
-		// Always save LR to stack so that panics in leaf
-		// functions are correctly handled. This smashes
-		// the stack frame but we're not going back there
-		// anyway.
-		SIG_SP(info, ctxt) -= 4;
-		*(uint32*)SIG_SP(info, ctxt) = SIG_LR(info, ctxt);
-		// Don't bother saving PC if it's zero, which is
-		// probably a call to a nil func: the old link register
-		// is more useful in the stack trace.
-		if(gp->sigpc != 0)
-			SIG_LR(info, ctxt) = gp->sigpc;
-		// In case we are panicking from external C code
-		SIG_R10(info, ctxt) = (uintptr)gp;
-		SIG_R9(info, ctxt) = (uintptr)m;
-		SIG_PC(info, ctxt) = (uintptr)runtime·sigpanic;
-		return;
-	}
-
-	if(SIG_CODE0(info, ctxt) == SI_USER || (t->flags & SigNotify))
-		if(runtime·sigsend(sig))
-			return;
-	if(t->flags & SigKill)
-		runtime·exit(2);
-	if(!(t->flags & SigThrow))
-		return;
-
-	m->throwing = 1;
-	m->caughtsig = gp;
-	if(runtime·panicking)	// traceback already printed
-		runtime·exit(2);
-	runtime·panicking = 1;
-
-	if(sig < 0 || sig >= NSIG)
-		runtime·printf("Signal %d\n", sig);
-	else
-		runtime·printf("%s\n", runtime·sigtab[sig].name);
-
-	runtime·printf("PC=%x\n", SIG_PC(info, ctxt));
-	if(m->lockedg != nil && m->ncgo > 0 && gp == m->g0) {
-		runtime·printf("signal arrived during cgo execution\n");
-		gp = m->lockedg;
-	}
-	runtime·printf("\n");
-
-	if(runtime·gotraceback(&crash)){
-		runtime·goroutineheader(gp);
-		runtime·traceback(SIG_PC(info, ctxt), SIG_SP(info, ctxt), SIG_LR(info, ctxt), gp);
-		runtime·tracebackothers(gp);
-		runtime·printf("\n");
-		runtime·dumpregs(info, ctxt);
-	}
-	
-	if(crash)
-		runtime·crash();
-
-	runtime·exit(2);
-}
diff --git a/src/pkg/runtime/signal_nacl_amd64p32.h b/src/pkg/runtime/signal_nacl_amd64p32.h
deleted file mode 100644
index c58593a..0000000
--- a/src/pkg/runtime/signal_nacl_amd64p32.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2013 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#define SIG_REGS(ctxt) (((ExcContext*)(ctxt))->regs64)
-
-#define SIG_RAX(info, ctxt) (SIG_REGS(ctxt).rax)
-#define SIG_RBX(info, ctxt) (SIG_REGS(ctxt).rbx)
-#define SIG_RCX(info, ctxt) (SIG_REGS(ctxt).rcx)
-#define SIG_RDX(info, ctxt) (SIG_REGS(ctxt).rdx)
-#define SIG_RDI(info, ctxt) (SIG_REGS(ctxt).rdi)
-#define SIG_RSI(info, ctxt) (SIG_REGS(ctxt).rsi)
-#define SIG_RBP(info, ctxt) (SIG_REGS(ctxt).rbp)
-#define SIG_RSP(info, ctxt) (SIG_REGS(ctxt).rsp)
-#define SIG_R8(info, ctxt) (SIG_REGS(ctxt).r8)
-#define SIG_R9(info, ctxt) (SIG_REGS(ctxt).r9)
-#define SIG_R10(info, ctxt) (SIG_REGS(ctxt).r10)
-#define SIG_R11(info, ctxt) (SIG_REGS(ctxt).r11)
-#define SIG_R12(info, ctxt) (SIG_REGS(ctxt).r12)
-#define SIG_R13(info, ctxt) (SIG_REGS(ctxt).r13)
-#define SIG_R14(info, ctxt) (SIG_REGS(ctxt).r14)
-#define SIG_R15(info, ctxt) (SIG_REGS(ctxt).r15)
-#define SIG_RIP(info, ctxt) (SIG_REGS(ctxt).rip)
-#define SIG_RFLAGS(info, ctxt) (SIG_REGS(ctxt).rflags)
-
-#define SIG_CS(info, ctxt) (~0)
-#define SIG_FS(info, ctxt) (~0)
-#define SIG_GS(info, ctxt) (~0)
-
-#define SIG_CODE0(info, ctxt) (~0)
-#define SIG_CODE1(info, ctxt) (0)
diff --git a/src/pkg/runtime/signal_unix.c b/src/pkg/runtime/signal_unix.c
deleted file mode 100644
index 246a1eb..0000000
--- a/src/pkg/runtime/signal_unix.c
+++ /dev/null
@@ -1,119 +0,0 @@
-// Copyright 2012 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build darwin dragonfly freebsd linux netbsd openbsd solaris
-
-#include "runtime.h"
-#include "defs_GOOS_GOARCH.h"
-#include "os_GOOS.h"
-#include "signal_unix.h"
-
-extern SigTab runtime·sigtab[];
-
-void
-runtime·initsig(void)
-{
-	int32 i;
-	SigTab *t;
-
-	// First call: basic setup.
-	for(i = 0; i<NSIG; i++) {
-		t = &runtime·sigtab[i];
-		if((t->flags == 0) || (t->flags & SigDefault))
-			continue;
-
-		// For some signals, we respect an inherited SIG_IGN handler
-		// rather than insist on installing our own default handler.
-		// Even these signals can be fetched using the os/signal package.
-		switch(i) {
-		case SIGHUP:
-		case SIGINT:
-			if(runtime·getsig(i) == SIG_IGN) {
-				t->flags = SigNotify | SigIgnored;
-				continue;
-			}
-		}
-
-		t->flags |= SigHandling;
-		runtime·setsig(i, runtime·sighandler, true);
-	}
-}
-
-void
-runtime·sigenable(uint32 sig)
-{
-	SigTab *t;
-
-	if(sig >= NSIG)
-		return;
-
-	t = &runtime·sigtab[sig];
-	if((t->flags & SigNotify) && !(t->flags & SigHandling)) {
-		t->flags |= SigHandling;
-		if(runtime·getsig(sig) == SIG_IGN)
-			t->flags |= SigIgnored;
-		runtime·setsig(sig, runtime·sighandler, true);
-	}
-}
-
-void
-runtime·sigdisable(uint32 sig)
-{
-	SigTab *t;
-
-	if(sig >= NSIG)
-		return;
-
-	t = &runtime·sigtab[sig];
-	if((t->flags & SigNotify) && (t->flags & SigHandling)) {
-		t->flags &= ~SigHandling;
-		if(t->flags & SigIgnored)
-			runtime·setsig(sig, SIG_IGN, true);
-		else
-			runtime·setsig(sig, SIG_DFL, true);
-	}
-}
-
-void
-runtime·resetcpuprofiler(int32 hz)
-{
-	Itimerval it;
-
-	runtime·memclr((byte*)&it, sizeof it);
-	if(hz == 0) {
-		runtime·setitimer(ITIMER_PROF, &it, nil);
-	} else {
-		it.it_interval.tv_sec = 0;
-		it.it_interval.tv_usec = 1000000 / hz;
-		it.it_value = it.it_interval;
-		runtime·setitimer(ITIMER_PROF, &it, nil);
-	}
-	m->profilehz = hz;
-}
-
-void
-os·sigpipe(void)
-{
-	runtime·setsig(SIGPIPE, SIG_DFL, false);
-	runtime·raise(SIGPIPE);
-}
-
-void
-runtime·crash(void)
-{
-#ifdef GOOS_darwin
-	// OS X core dumps are linear dumps of the mapped memory,
-	// from the first virtual byte to the last, with zeros in the gaps.
-	// Because of the way we arrange the address space on 64-bit systems,
-	// this means the OS X core file will be >128 GB and even on a zippy
-	// workstation can take OS X well over an hour to write (uninterruptible).
-	// Save users from making that mistake.
-	if(sizeof(void*) == 8)
-		return;
-#endif
-
-	runtime·unblocksignals();
-	runtime·setsig(SIGABRT, SIG_DFL, false);
-	runtime·raise(SIGABRT);
-}
diff --git a/src/pkg/runtime/signals_darwin.h b/src/pkg/runtime/signals_darwin.h
deleted file mode 100644
index 229b585..0000000
--- a/src/pkg/runtime/signals_darwin.h
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#define N SigNotify
-#define K SigKill
-#define T SigThrow
-#define P SigPanic
-#define D SigDefault
-
-SigTab runtime·sigtab[] = {
-	/* 0 */	0, "SIGNONE: no trap",
-	/* 1 */	N+K, "SIGHUP: terminal line hangup",
-	/* 2 */	N+K, "SIGINT: interrupt",
-	/* 3 */	N+T, "SIGQUIT: quit",
-	/* 4 */	T, "SIGILL: illegal instruction",
-	/* 5 */	T, "SIGTRAP: trace trap",
-	/* 6 */	N+T, "SIGABRT: abort",
-	/* 7 */	T, "SIGEMT: emulate instruction executed",
-	/* 8 */	P, "SIGFPE: floating-point exception",
-	/* 9 */	0, "SIGKILL: kill",
-	/* 10 */	P, "SIGBUS: bus error",
-	/* 11 */	P, "SIGSEGV: segmentation violation",
-	/* 12 */	T, "SIGSYS: bad system call",
-	/* 13 */	N, "SIGPIPE: write to broken pipe",
-	/* 14 */	N, "SIGALRM: alarm clock",
-	/* 15 */	N+K, "SIGTERM: termination",
-	/* 16 */	N, "SIGURG: urgent condition on socket",
-	/* 17 */	0, "SIGSTOP: stop",
-	/* 18 */	N+D, "SIGTSTP: keyboard stop",
-	/* 19 */	0, "SIGCONT: continue after stop",
-	/* 20 */	N, "SIGCHLD: child status has changed",
-	/* 21 */	N+D, "SIGTTIN: background read from tty",
-	/* 22 */	N+D, "SIGTTOU: background write to tty",
-	/* 23 */	N, "SIGIO: i/o now possible",
-	/* 24 */	N, "SIGXCPU: cpu limit exceeded",
-	/* 25 */	N, "SIGXFSZ: file size limit exceeded",
-	/* 26 */	N, "SIGVTALRM: virtual alarm clock",
-	/* 27 */	N, "SIGPROF: profiling alarm clock",
-	/* 28 */	N, "SIGWINCH: window size change",
-	/* 29 */	N, "SIGINFO: status request from keyboard",
-	/* 30 */	N, "SIGUSR1: user-defined signal 1",
-	/* 31 */	N, "SIGUSR2: user-defined signal 2",
-};
-
-#undef N
-#undef K
-#undef T
-#undef P
-#undef D
diff --git a/src/pkg/runtime/signals_dragonfly.h b/src/pkg/runtime/signals_dragonfly.h
deleted file mode 100644
index 4d27e05..0000000
--- a/src/pkg/runtime/signals_dragonfly.h
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#define N SigNotify
-#define K SigKill
-#define T SigThrow
-#define P SigPanic
-#define D SigDefault
-
-SigTab runtime·sigtab[] = {
-	/* 0 */	0, "SIGNONE: no trap",
-	/* 1 */	N+K, "SIGHUP: terminal line hangup",
-	/* 2 */	N+K, "SIGINT: interrupt",
-	/* 3 */	N+T, "SIGQUIT: quit",
-	/* 4 */	T, "SIGILL: illegal instruction",
-	/* 5 */	T, "SIGTRAP: trace trap",
-	/* 6 */	N+T, "SIGABRT: abort",
-	/* 7 */	T, "SIGEMT: emulate instruction executed",
-	/* 8 */	P, "SIGFPE: floating-point exception",
-	/* 9 */	0, "SIGKILL: kill",
-	/* 10 */	P, "SIGBUS: bus error",
-	/* 11 */	P, "SIGSEGV: segmentation violation",
-	/* 12 */	T, "SIGSYS: bad system call",
-	/* 13 */	N, "SIGPIPE: write to broken pipe",
-	/* 14 */	N, "SIGALRM: alarm clock",
-	/* 15 */	N+K, "SIGTERM: termination",
-	/* 16 */	N, "SIGURG: urgent condition on socket",
-	/* 17 */	0, "SIGSTOP: stop",
-	/* 18 */	N+D, "SIGTSTP: keyboard stop",
-	/* 19 */	0, "SIGCONT: continue after stop",
-	/* 20 */	N, "SIGCHLD: child status has changed",
-	/* 21 */	N+D, "SIGTTIN: background read from tty",
-	/* 22 */	N+D, "SIGTTOU: background write to tty",
-	/* 23 */	N, "SIGIO: i/o now possible",
-	/* 24 */	N, "SIGXCPU: cpu limit exceeded",
-	/* 25 */	N, "SIGXFSZ: file size limit exceeded",
-	/* 26 */	N, "SIGVTALRM: virtual alarm clock",
-	/* 27 */	N, "SIGPROF: profiling alarm clock",
-	/* 28 */	N, "SIGWINCH: window size change",
-	/* 29 */	N, "SIGINFO: status request from keyboard",
-	/* 30 */	N, "SIGUSR1: user-defined signal 1",
-	/* 31 */	N, "SIGUSR2: user-defined signal 2",
-	/* 32 */	N, "SIGTHR: reserved",
-};
-
-#undef N
-#undef K
-#undef T
-#undef P
-#undef D
diff --git a/src/pkg/runtime/signals_freebsd.h b/src/pkg/runtime/signals_freebsd.h
deleted file mode 100644
index 8d45c50..0000000
--- a/src/pkg/runtime/signals_freebsd.h
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#define N SigNotify
-#define K SigKill
-#define T SigThrow
-#define P SigPanic
-#define D SigDefault
-
-SigTab runtime·sigtab[] = {
-	/* 0 */	0, "SIGNONE: no trap",
-	/* 1 */	N+K, "SIGHUP: terminal line hangup",
-	/* 2 */	N+K, "SIGINT: interrupt",
-	/* 3 */	N+T, "SIGQUIT: quit",
-	/* 4 */	T, "SIGILL: illegal instruction",
-	/* 5 */	T, "SIGTRAP: trace trap",
-	/* 6 */	N+T, "SIGABRT: abort",
-	/* 7 */	T, "SIGEMT: emulate instruction executed",
-	/* 8 */	P, "SIGFPE: floating-point exception",
-	/* 9 */	0, "SIGKILL: kill",
-	/* 10 */	P, "SIGBUS: bus error",
-	/* 11 */	P, "SIGSEGV: segmentation violation",
-	/* 12 */	N, "SIGSYS: bad system call",
-	/* 13 */	N, "SIGPIPE: write to broken pipe",
-	/* 14 */	N, "SIGALRM: alarm clock",
-	/* 15 */	N+K, "SIGTERM: termination",
-	/* 16 */	N, "SIGURG: urgent condition on socket",
-	/* 17 */	0, "SIGSTOP: stop",
-	/* 18 */	N+D, "SIGTSTP: keyboard stop",
-	/* 19 */	0, "SIGCONT: continue after stop",
-	/* 20 */	N, "SIGCHLD: child status has changed",
-	/* 21 */	N+D, "SIGTTIN: background read from tty",
-	/* 22 */	N+D, "SIGTTOU: background write to tty",
-	/* 23 */	N, "SIGIO: i/o now possible",
-	/* 24 */	N, "SIGXCPU: cpu limit exceeded",
-	/* 25 */	N, "SIGXFSZ: file size limit exceeded",
-	/* 26 */	N, "SIGVTALRM: virtual alarm clock",
-	/* 27 */	N, "SIGPROF: profiling alarm clock",
-	/* 28 */	N, "SIGWINCH: window size change",
-	/* 29 */	N, "SIGINFO: status request from keyboard",
-	/* 30 */	N, "SIGUSR1: user-defined signal 1",
-	/* 31 */	N, "SIGUSR2: user-defined signal 2",
-	/* 32 */	N, "SIGTHR: reserved",
-};
-
-#undef N
-#undef K
-#undef T
-#undef P
-#undef D
diff --git a/src/pkg/runtime/signals_linux.h b/src/pkg/runtime/signals_linux.h
deleted file mode 100644
index 368afc1..0000000
--- a/src/pkg/runtime/signals_linux.h
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#define N SigNotify
-#define K SigKill
-#define T SigThrow
-#define P SigPanic
-#define D SigDefault
-
-SigTab runtime·sigtab[] = {
-	/* 0 */	0, "SIGNONE: no trap",
-	/* 1 */	N+K, "SIGHUP: terminal line hangup",
-	/* 2 */	N+K, "SIGINT: interrupt",
-	/* 3 */	N+T, "SIGQUIT: quit",
-	/* 4 */	T, "SIGILL: illegal instruction",
-	/* 5 */	T, "SIGTRAP: trace trap",
-	/* 6 */	N+T, "SIGABRT: abort",
-	/* 7 */	P, "SIGBUS: bus error",
-	/* 8 */	P, "SIGFPE: floating-point exception",
-	/* 9 */	0, "SIGKILL: kill",
-	/* 10 */	N, "SIGUSR1: user-defined signal 1",
-	/* 11 */	P, "SIGSEGV: segmentation violation",
-	/* 12 */	N, "SIGUSR2: user-defined signal 2",
-	/* 13 */	N, "SIGPIPE: write to broken pipe",
-	/* 14 */	N, "SIGALRM: alarm clock",
-	/* 15 */	N+K, "SIGTERM: termination",
-	/* 16 */	T, "SIGSTKFLT: stack fault",
-	/* 17 */	N, "SIGCHLD: child status has changed",
-	/* 18 */	0, "SIGCONT: continue",
-	/* 19 */	0, "SIGSTOP: stop, unblockable",
-	/* 20 */	N+D, "SIGTSTP: keyboard stop",
-	/* 21 */	N+D, "SIGTTIN: background read from tty",
-	/* 22 */	N+D, "SIGTTOU: background write to tty",
-	/* 23 */	N, "SIGURG: urgent condition on socket",
-	/* 24 */	N, "SIGXCPU: cpu limit exceeded",
-	/* 25 */	N, "SIGXFSZ: file size limit exceeded",
-	/* 26 */	N, "SIGVTALRM: virtual alarm clock",
-	/* 27 */	N, "SIGPROF: profiling alarm clock",
-	/* 28 */	N, "SIGWINCH: window size change",
-	/* 29 */	N, "SIGIO: i/o now possible",
-	/* 30 */	N, "SIGPWR: power failure restart",
-	/* 31 */	N, "SIGSYS: bad system call",
-	/* 32 */	0, "signal 32", /* SIGCANCEL; see issue 6997 */
-	/* 33 */	0, "signal 33", /* SIGSETXID; see issue 3871 */
-	/* 34 */	N, "signal 34",
-	/* 35 */	N, "signal 35",
-	/* 36 */	N, "signal 36",
-	/* 37 */	N, "signal 37",
-	/* 38 */	N, "signal 38",
-	/* 39 */	N, "signal 39",
-	/* 40 */	N, "signal 40",
-	/* 41 */	N, "signal 41",
-	/* 42 */	N, "signal 42",
-	/* 43 */	N, "signal 43",
-	/* 44 */	N, "signal 44",
-	/* 45 */	N, "signal 45",
-	/* 46 */	N, "signal 46",
-	/* 47 */	N, "signal 47",
-	/* 48 */	N, "signal 48",
-	/* 49 */	N, "signal 49",
-	/* 50 */	N, "signal 50",
-	/* 51 */	N, "signal 51",
-	/* 52 */	N, "signal 52",
-	/* 53 */	N, "signal 53",
-	/* 54 */	N, "signal 54",
-	/* 55 */	N, "signal 55",
-	/* 56 */	N, "signal 56",
-	/* 57 */	N, "signal 57",
-	/* 58 */	N, "signal 58",
-	/* 59 */	N, "signal 59",
-	/* 60 */	N, "signal 60",
-	/* 61 */	N, "signal 61",
-	/* 62 */	N, "signal 62",
-	/* 63 */	N, "signal 63",
-	/* 64 */	N, "signal 64",
-};
-
-#undef N
-#undef K
-#undef T
-#undef P
-#undef D
diff --git a/src/pkg/runtime/signals_nacl.h b/src/pkg/runtime/signals_nacl.h
deleted file mode 100644
index 229b585..0000000
--- a/src/pkg/runtime/signals_nacl.h
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#define N SigNotify
-#define K SigKill
-#define T SigThrow
-#define P SigPanic
-#define D SigDefault
-
-SigTab runtime·sigtab[] = {
-	/* 0 */	0, "SIGNONE: no trap",
-	/* 1 */	N+K, "SIGHUP: terminal line hangup",
-	/* 2 */	N+K, "SIGINT: interrupt",
-	/* 3 */	N+T, "SIGQUIT: quit",
-	/* 4 */	T, "SIGILL: illegal instruction",
-	/* 5 */	T, "SIGTRAP: trace trap",
-	/* 6 */	N+T, "SIGABRT: abort",
-	/* 7 */	T, "SIGEMT: emulate instruction executed",
-	/* 8 */	P, "SIGFPE: floating-point exception",
-	/* 9 */	0, "SIGKILL: kill",
-	/* 10 */	P, "SIGBUS: bus error",
-	/* 11 */	P, "SIGSEGV: segmentation violation",
-	/* 12 */	T, "SIGSYS: bad system call",
-	/* 13 */	N, "SIGPIPE: write to broken pipe",
-	/* 14 */	N, "SIGALRM: alarm clock",
-	/* 15 */	N+K, "SIGTERM: termination",
-	/* 16 */	N, "SIGURG: urgent condition on socket",
-	/* 17 */	0, "SIGSTOP: stop",
-	/* 18 */	N+D, "SIGTSTP: keyboard stop",
-	/* 19 */	0, "SIGCONT: continue after stop",
-	/* 20 */	N, "SIGCHLD: child status has changed",
-	/* 21 */	N+D, "SIGTTIN: background read from tty",
-	/* 22 */	N+D, "SIGTTOU: background write to tty",
-	/* 23 */	N, "SIGIO: i/o now possible",
-	/* 24 */	N, "SIGXCPU: cpu limit exceeded",
-	/* 25 */	N, "SIGXFSZ: file size limit exceeded",
-	/* 26 */	N, "SIGVTALRM: virtual alarm clock",
-	/* 27 */	N, "SIGPROF: profiling alarm clock",
-	/* 28 */	N, "SIGWINCH: window size change",
-	/* 29 */	N, "SIGINFO: status request from keyboard",
-	/* 30 */	N, "SIGUSR1: user-defined signal 1",
-	/* 31 */	N, "SIGUSR2: user-defined signal 2",
-};
-
-#undef N
-#undef K
-#undef T
-#undef P
-#undef D
diff --git a/src/pkg/runtime/signals_netbsd.h b/src/pkg/runtime/signals_netbsd.h
deleted file mode 100644
index 7140de8..0000000
--- a/src/pkg/runtime/signals_netbsd.h
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#define N SigNotify
-#define K SigKill
-#define T SigThrow
-#define P SigPanic
-#define D SigDefault
-
-SigTab runtime·sigtab[] = {
-	/*  0 */	0, "SIGNONE: no trap",
-	/*  1 */	N+K, "SIGHUP: terminal line hangup",
-	/*  2 */	N+K, "SIGINT: interrupt",
-	/*  3 */	N+T, "SIGQUIT: quit",
-	/*  4 */	T, "SIGILL: illegal instruction",
-	/*  5 */	T, "SIGTRAP: trace trap",
-	/*  6 */	N+T, "SIGABRT: abort",
-	/*  7 */	T, "SIGEMT: emulate instruction executed",
-	/*  8 */	P, "SIGFPE: floating-point exception",
-	/*  9 */	0, "SIGKILL: kill",
-	/* 10 */	P, "SIGBUS: bus error",
-	/* 11 */	P, "SIGSEGV: segmentation violation",
-	/* 12 */	T, "SIGSYS: bad system call",
-	/* 13 */	N, "SIGPIPE: write to broken pipe",
-	/* 14 */	N, "SIGALRM: alarm clock",
-	/* 15 */	N+K, "SIGTERM: termination",
-	/* 16 */	N, "SIGURG: urgent condition on socket",
-	/* 17 */	0, "SIGSTOP: stop",
-	/* 18 */	N+D, "SIGTSTP: keyboard stop",
-	/* 19 */	0, "SIGCONT: continue after stop",
-	/* 20 */	N, "SIGCHLD: child status has changed",
-	/* 21 */	N+D, "SIGTTIN: background read from tty",
-	/* 22 */	N+D, "SIGTTOU: background write to tty",
-	/* 23 */	N, "SIGIO: i/o now possible",
-	/* 24 */	N, "SIGXCPU: cpu limit exceeded",
-	/* 25 */	N, "SIGXFSZ: file size limit exceeded",
-	/* 26 */	N, "SIGVTALRM: virtual alarm clock",
-	/* 27 */	N, "SIGPROF: profiling alarm clock",
-	/* 28 */	N, "SIGWINCH: window size change",
-	/* 29 */	N, "SIGINFO: status request from keyboard",
-	/* 30 */	N, "SIGUSR1: user-defined signal 1",
-	/* 31 */	N, "SIGUSR2: user-defined signal 2",
-	/* 32 */	N, "SIGTHR: reserved",
-};
-
-#undef N
-#undef K
-#undef T
-#undef P
-#undef D
diff --git a/src/pkg/runtime/signals_openbsd.h b/src/pkg/runtime/signals_openbsd.h
deleted file mode 100644
index 7140de8..0000000
--- a/src/pkg/runtime/signals_openbsd.h
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#define N SigNotify
-#define K SigKill
-#define T SigThrow
-#define P SigPanic
-#define D SigDefault
-
-SigTab runtime·sigtab[] = {
-	/*  0 */	0, "SIGNONE: no trap",
-	/*  1 */	N+K, "SIGHUP: terminal line hangup",
-	/*  2 */	N+K, "SIGINT: interrupt",
-	/*  3 */	N+T, "SIGQUIT: quit",
-	/*  4 */	T, "SIGILL: illegal instruction",
-	/*  5 */	T, "SIGTRAP: trace trap",
-	/*  6 */	N+T, "SIGABRT: abort",
-	/*  7 */	T, "SIGEMT: emulate instruction executed",
-	/*  8 */	P, "SIGFPE: floating-point exception",
-	/*  9 */	0, "SIGKILL: kill",
-	/* 10 */	P, "SIGBUS: bus error",
-	/* 11 */	P, "SIGSEGV: segmentation violation",
-	/* 12 */	T, "SIGSYS: bad system call",
-	/* 13 */	N, "SIGPIPE: write to broken pipe",
-	/* 14 */	N, "SIGALRM: alarm clock",
-	/* 15 */	N+K, "SIGTERM: termination",
-	/* 16 */	N, "SIGURG: urgent condition on socket",
-	/* 17 */	0, "SIGSTOP: stop",
-	/* 18 */	N+D, "SIGTSTP: keyboard stop",
-	/* 19 */	0, "SIGCONT: continue after stop",
-	/* 20 */	N, "SIGCHLD: child status has changed",
-	/* 21 */	N+D, "SIGTTIN: background read from tty",
-	/* 22 */	N+D, "SIGTTOU: background write to tty",
-	/* 23 */	N, "SIGIO: i/o now possible",
-	/* 24 */	N, "SIGXCPU: cpu limit exceeded",
-	/* 25 */	N, "SIGXFSZ: file size limit exceeded",
-	/* 26 */	N, "SIGVTALRM: virtual alarm clock",
-	/* 27 */	N, "SIGPROF: profiling alarm clock",
-	/* 28 */	N, "SIGWINCH: window size change",
-	/* 29 */	N, "SIGINFO: status request from keyboard",
-	/* 30 */	N, "SIGUSR1: user-defined signal 1",
-	/* 31 */	N, "SIGUSR2: user-defined signal 2",
-	/* 32 */	N, "SIGTHR: reserved",
-};
-
-#undef N
-#undef K
-#undef T
-#undef P
-#undef D
diff --git a/src/pkg/runtime/signals_plan9.h b/src/pkg/runtime/signals_plan9.h
deleted file mode 100644
index 818f508..0000000
--- a/src/pkg/runtime/signals_plan9.h
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#define N SigNotify
-#define K SigKill
-#define T SigThrow
-#define P SigPanic
-#define E SigGoExit
-
-// Incoming notes are compared against this table using strncmp, so the
-// order matters: longer patterns must appear before their prefixes.
-// There are #defined SIG constants in os_plan9.h for the table index of
-// some of these.
-//
-// If you add entries to this table, you must respect the prefix ordering
-// and also update the constant values is os_plan9.h.
-
-SigTab runtime·sigtab[] = {
-	// Traps that we cannot be recovered.
-	T,	"sys: trap: debug exception",
-	T,	"sys: trap: invalid opcode",
-
-	// We can recover from some memory errors in runtime·sigpanic.
-	P,	"sys: trap: fault read addr",	// SIGRFAULT
-	P,	"sys: trap: fault write addr",	// SIGWFAULT
-
-	// We can also recover from math errors.
-	P,	"sys: trap: divide error",	// SIGINTDIV
-	P,	"sys: fp:",	// SIGFLOAT
-
-	// All other traps are normally handled as if they were marked SigThrow.
-	// We mark them SigPanic here so that debug.SetPanicOnFault will work.
-	P,	"sys: trap:",	// SIGTRAP
-
-	// Writes to a closed pipe can be handled if desired, otherwise they're ignored.
-	N,	"sys: write on closed pipe",
-
-	// Other system notes are more serious and cannot be recovered.
-	T,	"sys:",
-
-	// Issued to all other procs when calling runtime·exit.
-	E,	"go: exit ",
-
-	// Kill is sent by external programs to cause an exit.
-	K,	"kill",
-
-	// Interrupts can be handled if desired, otherwise they cause an exit.
-	N+K,	"interrupt",
-	N+K,	"hangup",
-
-	// Alarms can be handled if desired, otherwise they're ignored.
-	N,	"alarm",
-};
-
-#undef N
-#undef K
-#undef T
-#undef P
-#undef E
diff --git a/src/pkg/runtime/signals_solaris.h b/src/pkg/runtime/signals_solaris.h
deleted file mode 100644
index c272cad..0000000
--- a/src/pkg/runtime/signals_solaris.h
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#define N SigNotify
-#define K SigKill
-#define T SigThrow
-#define P SigPanic
-#define D SigDefault
-
-SigTab runtime·sigtab[] = {
-	/* 0 */		0, "SIGNONE: no trap",
-	/* 1 */		N+K, "SIGHUP: hangup",
-	/* 2 */		N+K, "SIGINT: interrupt (rubout)",
-	/* 3 */		N+T, "SIGQUIT: quit (ASCII FS)",
-	/* 4 */		T, "SIGILL: illegal instruction (not reset when caught)",
-	/* 5 */		T, "SIGTRAP: trace trap (not reset when caught)",
-	/* 6 */		N+T, "SIGABRT: used by abort, replace SIGIOT in the future",
-	/* 7 */		T, "SIGEMT: EMT instruction",
-	/* 8 */		P, "SIGFPE: floating point exception",
-	/* 9 */		0, "SIGKILL: kill (cannot be caught or ignored)",
-	/* 10 */	P, "SIGBUS: bus error",
-	/* 11 */	P, "SIGSEGV: segmentation violation",
-	/* 12 */	T, "SIGSYS: bad argument to system call",
-	/* 13 */	N, "SIGPIPE: write on a pipe with no one to read it",
-	/* 14 */	N, "SIGALRM: alarm clock",
-	/* 15 */	N+K, "SIGTERM: software termination signal from kill",
-	/* 16 */	N, "SIGUSR1: user defined signal 1",
-	/* 17 */	N, "SIGUSR2: user defined signal 2",
-	/* 18 */	N, "SIGCLD: child status change",
-	/* 18 */	N, "SIGCHLD: child status change alias (POSIX)",
-	/* 19 */	N, "SIGPWR: power-fail restart",
-	/* 20 */	N, "SIGWINCH: window size change",
-	/* 21 */	N, "SIGURG: urgent socket condition",
-	/* 22 */	N, "SIGPOLL: pollable event occured",
-	/* 23 */	N+D, "SIGSTOP: stop (cannot be caught or ignored)",
-	/* 24 */	0, "SIGTSTP: user stop requested from tty",
-	/* 25 */	0, "SIGCONT: stopped process has been continued",
-	/* 26 */	N+D, "SIGTTIN: background tty read attempted",
-	/* 27 */	N+D, "SIGTTOU: background tty write attempted",
-	/* 28 */	N, "SIGVTALRM: virtual timer expired",
-	/* 29 */	N, "SIGPROF: profiling timer expired",
-	/* 30 */	N, "SIGXCPU: exceeded cpu limit",
-	/* 31 */	N, "SIGXFSZ: exceeded file size limit",
-	/* 32 */	N, "SIGWAITING: reserved signal no longer used by",
-	/* 33 */	N, "SIGLWP: reserved signal no longer used by",
-	/* 34 */	N, "SIGFREEZE: special signal used by CPR",
-	/* 35 */	N, "SIGTHAW: special signal used by CPR",
-	/* 36 */	0, "SIGCANCEL: reserved signal for thread cancellation",
-	/* 37 */	N, "SIGLOST: resource lost (eg, record-lock lost)",
-	/* 38 */	N, "SIGXRES: resource control exceeded",
-	/* 39 */	N, "SIGJVM1: reserved signal for Java Virtual Machine",
-	/* 40 */	N, "SIGJVM2: reserved signal for Java Virtual Machine",
-
-	/* TODO(aram): what should be do about these signals? D or N? is this set static? */
-	/* 41 */	N, "real time signal",
-	/* 42 */	N, "real time signal",
-	/* 43 */	N, "real time signal",
-	/* 44 */	N, "real time signal",
-	/* 45 */	N, "real time signal",
-	/* 46 */	N, "real time signal",
-	/* 47 */	N, "real time signal",
-	/* 48 */	N, "real time signal",
-	/* 49 */	N, "real time signal",
-	/* 50 */	N, "real time signal",
-	/* 51 */	N, "real time signal",
-	/* 52 */	N, "real time signal",
-	/* 53 */	N, "real time signal",
-	/* 54 */	N, "real time signal",
-	/* 55 */	N, "real time signal",
-	/* 56 */	N, "real time signal",
-	/* 57 */	N, "real time signal",
-	/* 58 */	N, "real time signal",
-	/* 59 */	N, "real time signal",
-	/* 60 */	N, "real time signal",
-	/* 61 */	N, "real time signal",
-	/* 62 */	N, "real time signal",
-	/* 63 */	N, "real time signal",
-	/* 64 */	N, "real time signal",
-	/* 65 */	N, "real time signal",
-	/* 66 */	N, "real time signal",
-	/* 67 */	N, "real time signal",
-	/* 68 */	N, "real time signal",
-	/* 69 */	N, "real time signal",
-	/* 70 */	N, "real time signal",
-	/* 71 */	N, "real time signal",
-	/* 72 */	N, "real time signal",
-};
-
-#undef N
-#undef K
-#undef T
-#undef P
-#undef D
diff --git a/src/pkg/runtime/sigqueue.goc b/src/pkg/runtime/sigqueue.goc
deleted file mode 100644
index e08bf98..0000000
--- a/src/pkg/runtime/sigqueue.goc
+++ /dev/null
@@ -1,165 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// This file implements runtime support for signal handling.
-//
-// Most synchronization primitives are not available from
-// the signal handler (it cannot block, allocate memory, or use locks)
-// so the handler communicates with a processing goroutine
-// via struct sig, below.
-//
-// sigsend() is called by the signal handler to queue a new signal.
-// signal_recv() is called by the Go program to receive a newly queued signal.
-// Synchronization between sigsend() and signal_recv() is based on the sig.state
-// variable.  It can be in 3 states: 0, HASWAITER and HASSIGNAL.
-// HASWAITER means that signal_recv() is blocked on sig.Note and there are no
-// new pending signals.
-// HASSIGNAL means that sig.mask *may* contain new pending signals,
-// signal_recv() can't be blocked in this state.
-// 0 means that there are no new pending signals and signal_recv() is not blocked.
-// Transitions between states are done atomically with CAS.
-// When signal_recv() is unblocked, it resets sig.Note and rechecks sig.mask.
-// If several sigsend()'s and signal_recv() execute concurrently, it can lead to
-// unnecessary rechecks of sig.mask, but must not lead to missed signals
-// nor deadlocks.
-
-package runtime
-#include "runtime.h"
-#include "defs_GOOS_GOARCH.h"
-#include "os_GOOS.h"
-#include "cgocall.h"
-#include "../../cmd/ld/textflag.h"
-
-static struct {
-	Note;
-	uint32 mask[(NSIG+31)/32];
-	uint32 wanted[(NSIG+31)/32];
-	uint32 state;
-	bool inuse;
-} sig;
-
-enum {
-	HASWAITER = 1,
-	HASSIGNAL = 2,
-};
-
-// Called from sighandler to send a signal back out of the signal handling thread.
-bool
-runtime·sigsend(int32 s)
-{
-	uint32 bit, mask, old, new;
-
-	if(!sig.inuse || s < 0 || s >= 32*nelem(sig.wanted) || !(sig.wanted[s/32]&(1U<<(s&31))))
-		return false;
-	bit = 1 << (s&31);
-	for(;;) {
-		mask = sig.mask[s/32];
-		if(mask & bit)
-			break;		// signal already in queue
-		if(runtime·cas(&sig.mask[s/32], mask, mask|bit)) {
-			// Added to queue.
-			// Only send a wakeup if the receiver needs a kick.
-			for(;;) {
-				old = runtime·atomicload(&sig.state);
-				if(old == HASSIGNAL)
-					break;
-				if(old == HASWAITER)
-					new = 0;
-				else  // if(old == 0)
-					new = HASSIGNAL;
-				if(runtime·cas(&sig.state, old, new)) {
-					if (old == HASWAITER)
-						runtime·notewakeup(&sig);
-					break;
-				}
-			}
-			break;
-		}
-	}
-	return true;
-}
-
-// Called to receive the next queued signal.
-// Must only be called from a single goroutine at a time.
-func signal_recv() (m uint32) {
-	static uint32 recv[nelem(sig.mask)];
-	uint32 i, old, new;
-	
-	for(;;) {
-		// Serve from local copy if there are bits left.
-		for(i=0; i<NSIG; i++) {
-			if(recv[i/32]&(1U<<(i&31))) {
-				recv[i/32] ^= 1U<<(i&31);
-				m = i;
-				goto done;
-			}
-		}
-
-		// Check and update sig.state.
-		for(;;) {
-			old = runtime·atomicload(&sig.state);
-			if(old == HASWAITER)
-				runtime·throw("inconsistent state in signal_recv");
-			if(old == HASSIGNAL)
-				new = 0;
-			else  // if(old == 0)
-				new = HASWAITER;
-			if(runtime·cas(&sig.state, old, new)) {
-				if (new == HASWAITER) {
-					runtime·notetsleepg(&sig, -1);
-					runtime·noteclear(&sig);
-				}
-				break;
-			}
-		}
-
-		// Get a new local copy.
-		for(i=0; i<nelem(sig.mask); i++) {
-			for(;;) {
-				m = sig.mask[i];
-				if(runtime·cas(&sig.mask[i], m, 0))
-					break;
-			}
-			recv[i] = m;
-		}
-	}
-
-done:;
-	// goc requires that we fall off the end of functions
-	// that return values instead of using our own return
-	// statements.
-}
-
-// Must only be called from a single goroutine at a time.
-func signal_enable(s uint32) {
-	if(!sig.inuse) {
-		// The first call to signal_enable is for us
-		// to use for initialization.  It does not pass
-		// signal information in m.
-		sig.inuse = true;	// enable reception of signals; cannot disable
-		runtime·noteclear(&sig);
-		return;
-	}
-	
-	if(s >= nelem(sig.wanted)*32)
-		return;
-	sig.wanted[s/32] |= 1U<<(s&31);
-	runtime·sigenable(s);
-}
-
-// Must only be called from a single goroutine at a time.
-func signal_disable(s uint32) {
-	if(s >= nelem(sig.wanted)*32)
-		return;
-	sig.wanted[s/32] &= ~(1U<<(s&31));
-	runtime·sigdisable(s);
-}
-
-// This runs on a foreign stack, without an m or a g.  No stack split.
-#pragma textflag NOSPLIT
-void
-runtime·badsignal(uintptr sig)
-{
-	runtime·cgocallback((void (*)(void))runtime·sigsend, &sig, sizeof(sig));
-}
diff --git a/src/pkg/runtime/slice.goc b/src/pkg/runtime/slice.goc
deleted file mode 100644
index 2a14daf..0000000
--- a/src/pkg/runtime/slice.goc
+++ /dev/null
@@ -1,204 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package runtime
-#include "runtime.h"
-#include "arch_GOARCH.h"
-#include "type.h"
-#include "typekind.h"
-#include "malloc.h"
-#include "race.h"
-#include "stack.h"
-#include "../../cmd/ld/textflag.h"
-
-enum
-{
-	debug = 0
-};
-
-static	void	makeslice1(SliceType*, intgo, intgo, Slice*);
-static	void	growslice1(SliceType*, Slice, intgo, Slice *);
-
-// see also unsafe·NewArray
-func makeslice(t *SliceType, len int64, cap int64) (ret Slice) {
-	// NOTE: The len > MaxMem/elemsize check here is not strictly necessary,
-	// but it produces a 'len out of range' error instead of a 'cap out of range' error
-	// when someone does make([]T, bignumber). 'cap out of range' is true too,
-	// but since the cap is only being supplied implicitly, saying len is clearer.
-	// See issue 4085.
-	if(len < 0 || (intgo)len != len || t->elem->size > 0 && len > MaxMem / t->elem->size)
-		runtime·panicstring("makeslice: len out of range");
-
-	if(cap < len || (intgo)cap != cap || t->elem->size > 0 && cap > MaxMem / t->elem->size)
-		runtime·panicstring("makeslice: cap out of range");
-
-	makeslice1(t, len, cap, &ret);
-
-	if(debug) {
-		runtime·printf("makeslice(%S, %D, %D); ret=",
-			*t->string, len, cap);
-		runtime·printslice(ret);
-	}
-}
-
-// Dummy word to use as base pointer for make([]T, 0).
-// Since you cannot take the address of such a slice,
-// you can't tell that they all have the same base pointer.
-uintptr runtime·zerobase;
-
-static void
-makeslice1(SliceType *t, intgo len, intgo cap, Slice *ret)
-{
-	ret->len = len;
-	ret->cap = cap;
-	ret->array = runtime·cnewarray(t->elem, cap);
-}
-
-// growslice(type *Type, x, []T, n int64) []T
-func growslice(t *SliceType, old Slice, n int64) (ret Slice) {
-	int64 cap;
-	void *pc;
-
-	if(n < 1)
-		runtime·panicstring("growslice: invalid n");
-
-	cap = old.cap + n;
-
-	if((intgo)cap != cap || cap < (int64)old.cap || (t->elem->size > 0 && cap > MaxMem/t->elem->size))
-		runtime·panicstring("growslice: cap out of range");
-
-	if(raceenabled) {
-		pc = runtime·getcallerpc(&t);
-		runtime·racereadrangepc(old.array, old.len*t->elem->size, pc, runtime·growslice);
-	}
-
-	growslice1(t, old, cap, &ret);
-
-	if(debug) {
-		runtime·printf("growslice(%S,", *t->string);
-		runtime·printslice(old);
-		runtime·printf(", new cap=%D) =", cap);
-		runtime·printslice(ret);
-	}
-}
-
-static void
-growslice1(SliceType *t, Slice x, intgo newcap, Slice *ret)
-{
-	intgo newcap1;
-	uintptr capmem, lenmem;
-	int32 flag;
-	Type *typ;
-
-	typ = t->elem;
-	if(typ->size == 0) {
-		*ret = x;
-		ret->cap = newcap;
-		return;
-	}
-
-	newcap1 = x.cap;
-	
-	// Using newcap directly for m+m < newcap handles
-	// both the case where m == 0 and also the case where
-	// m+m/4 wraps around, in which case the loop
-	// below might never terminate.
-	if(newcap1+newcap1 < newcap)
-		newcap1 = newcap;
-	else {
-		do {
-			if(x.len < 1024)
-				newcap1 += newcap1;
-			else
-				newcap1 += newcap1/4;
-		} while(newcap1 < newcap);
-	}
-
-	if(newcap1 > MaxMem/typ->size)
-		runtime·panicstring("growslice: cap out of range");
-	capmem = runtime·roundupsize(newcap1*typ->size);
-	flag = 0;
-	// Can't use FlagNoZero w/o FlagNoScan, because otherwise GC can scan unitialized memory.
-	if(typ->kind&KindNoPointers)
-		flag = FlagNoScan|FlagNoZero;
-	ret->array = runtime·mallocgc(capmem, (uintptr)typ|TypeInfo_Array, flag);
-	ret->len = x.len;
-	ret->cap = capmem/typ->size;
-	lenmem = x.len*typ->size;
-	runtime·memmove(ret->array, x.array, lenmem);
-	if(typ->kind&KindNoPointers)
-		runtime·memclr(ret->array+lenmem, capmem-lenmem);
-}
-
-#pragma textflag NOSPLIT
-func copy(to Slice, fm Slice, width uintptr) (ret int) {
-	void *pc;
-
-	if(fm.len == 0 || to.len == 0 || width == 0) {
-		ret = 0;
-		goto out;
-	}
-
-	ret = fm.len;
-	if(to.len < ret)
-		ret = to.len;
-
-	if(raceenabled) {
-		pc = runtime·getcallerpc(&to);
-		runtime·racewriterangepc(to.array, ret*width, pc, runtime·copy);
-		runtime·racereadrangepc(fm.array, ret*width, pc, runtime·copy);
-	}
-
-	if(ret == 1 && width == 1) {	// common case worth about 2x to do here
-		*to.array = *fm.array;	// known to be a byte pointer
-	} else {
-		runtime·memmove(to.array, fm.array, ret*width);
-	}
-
-out:
-
-	if(debug) {
-		runtime·prints("main·copy: to=");
-		runtime·printslice(to);
-		runtime·prints("; fm=");
-		runtime·printslice(fm);
-		runtime·prints("; width=");
-		runtime·printint(width);
-		runtime·prints("; ret=");
-		runtime·printint(ret);
-		runtime·prints("\n");
-	}
-}
-
-#pragma textflag NOSPLIT
-func slicestringcopy(to Slice, fm String) (ret int) {
-	void *pc;
-
-	if(fm.len == 0 || to.len == 0) {
-		ret = 0;
-		goto out;
-	}
-
-	ret = fm.len;
-	if(to.len < ret)
-		ret = to.len;
-
-	if(raceenabled) {
-		pc = runtime·getcallerpc(&to);
-		runtime·racewriterangepc(to.array, ret, pc, runtime·slicestringcopy);
-	}
-
-	runtime·memmove(to.array, fm.str, ret);
-
-out:;
-}
-
-func printslice(a Slice) {
-	runtime·prints("[");
-	runtime·printint(a.len);
-	runtime·prints("/");
-	runtime·printint(a.cap);
-	runtime·prints("]");
-	runtime·printpointer(a.array);
-}
diff --git a/src/pkg/runtime/softfloat_arm.c b/src/pkg/runtime/softfloat_arm.c
deleted file mode 100644
index 29a52bd..0000000
--- a/src/pkg/runtime/softfloat_arm.c
+++ /dev/null
@@ -1,620 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Software floating point interpretaton of ARM 7500 FP instructions.
-// The interpretation is not bit compatible with the 7500.
-// It uses true little-endian doubles, while the 7500 used mixed-endian.
-
-#include "runtime.h"
-#include "../../cmd/ld/textflag.h"
-
-#define CPSR 14
-#define FLAGS_N (1U << 31)
-#define FLAGS_Z (1U << 30)
-#define FLAGS_C (1U << 29)
-#define FLAGS_V (1U << 28)
-
-void	runtime·abort(void);
-void	runtime·sqrtC(uint64, uint64*);
-
-static	uint32	trace = 0;
-
-static void
-fabort(void)
-{
-	if (1) {
-		runtime·printf("Unsupported floating point instruction\n");
-		runtime·abort();
-	}
-}
-
-static void
-putf(uint32 reg, uint32 val)
-{
-	m->freglo[reg] = val;
-}
-
-static void
-putd(uint32 reg, uint64 val)
-{
-	m->freglo[reg] = (uint32)val;
-	m->freghi[reg] = (uint32)(val>>32);
-}
-
-static uint64
-getd(uint32 reg)
-{
-	return (uint64)m->freglo[reg] | ((uint64)m->freghi[reg]<<32);
-}
-
-static void
-fprint(void)
-{
-	uint32 i;
-	for (i = 0; i < 16; i++) {
-		runtime·printf("\tf%d:\t%X %X\n", i, m->freghi[i], m->freglo[i]);
-	}
-}
-
-static uint32
-d2f(uint64 d)
-{
-	uint32 x;
-
-	runtime·f64to32c(d, &x);
-	return x;
-}
-
-static uint64
-f2d(uint32 f)
-{
-	uint64 x;
-
-	runtime·f32to64c(f, &x);
-	return x;
-}
-
-static uint32
-fstatus(bool nan, int32 cmp)
-{
-	if(nan)
-		return FLAGS_C | FLAGS_V;
-	if(cmp == 0)
-		return FLAGS_Z | FLAGS_C;
-	if(cmp < 0)
-		return FLAGS_N;
-	return FLAGS_C;
-}
-
-// conditions array record the required CPSR cond field for the
-// first 5 pairs of conditional execution opcodes
-// higher 4 bits are must set, lower 4 bits are must clear
-static const uint8 conditions[10/2] = {
-	[0/2] = (FLAGS_Z >> 24) | 0, // 0: EQ (Z set), 1: NE (Z clear)
-	[2/2] = (FLAGS_C >> 24) | 0, // 2: CS/HS (C set), 3: CC/LO (C clear)
-	[4/2] = (FLAGS_N >> 24) | 0, // 4: MI (N set), 5: PL (N clear)
-	[6/2] = (FLAGS_V >> 24) | 0, // 6: VS (V set), 7: VC (V clear)
-	[8/2] = (FLAGS_C >> 24) | 
-	        (FLAGS_Z >> 28),     // 8: HI (C set and Z clear), 9: LS (C clear and Z set)
-};
-
-// returns number of words that the fp instruction
-// is occupying, 0 if next instruction isn't float.
-static uint32
-stepflt(uint32 *pc, uint32 *regs)
-{
-	uint32 i, opc, regd, regm, regn, cpsr;
-	int32 delta;
-	uint32 *addr;
-	uint64 uval;
-	int64 sval;
-	bool nan, ok;
-	int32 cmp;
-
-	i = *pc;
-
-	if(trace)
-		runtime·printf("stepflt %p %x (cpsr %x)\n", pc, i, regs[CPSR] >> 28);
-
-	opc = i >> 28;
-	if(opc == 14) // common case first
-		goto execute;
-	cpsr = regs[CPSR] >> 28;
-	switch(opc) {
-	case 0: case 1: case 2: case 3: case 4: 
-	case 5: case 6: case 7: case 8: case 9:
-		if(((cpsr & (conditions[opc/2] >> 4)) == (conditions[opc/2] >> 4)) &&
-		   ((cpsr & (conditions[opc/2] & 0xf)) == 0)) {
-			if(opc & 1) return 1;
-		} else {
-			if(!(opc & 1)) return 1;
-		}
-		break;
-	case 10: // GE (N == V)
-	case 11: // LT (N != V)
-		if((cpsr & (FLAGS_N >> 28)) == (cpsr & (FLAGS_V >> 28))) {
-			if(opc & 1) return 1;
-		} else {
-			if(!(opc & 1)) return 1;
-		}
-		break;
-	case 12: // GT (N == V and Z == 0)
-	case 13: // LE (N != V or Z == 1)
-		if((cpsr & (FLAGS_N >> 28)) == (cpsr & (FLAGS_V >> 28)) &&
-		   (cpsr & (FLAGS_Z >> 28)) == 0) {
-			if(opc & 1) return 1;
-		} else {
-			if(!(opc & 1)) return 1;
-		}
-		break;
-	case 14: // AL
-		break;
-	case 15: // shouldn't happen
-		return 0;
-	}
-	if(trace)
-		runtime·printf("conditional %x (cpsr %x) pass\n", opc, cpsr);
-	i = (0xeU << 28) | (i & 0xfffffff);
-
-execute:
-	// special cases
-	if((i&0xfffff000) == 0xe59fb000) {
-		// load r11 from pc-relative address.
-		// might be part of a floating point move
-		// (or might not, but no harm in simulating
-		// one instruction too many).
-		addr = (uint32*)((uint8*)pc + (i&0xfff) + 8);
-		regs[11] = addr[0];
-
-		if(trace)
-			runtime·printf("*** cpu R[%d] = *(%p) %x\n",
-				11, addr, regs[11]);
-		return 1;
-	}
-	if(i == 0xe08bb00d) {
-		// add sp to r11.
-		// might be part of a large stack offset address
-		// (or might not, but again no harm done).
-		regs[11] += regs[13];
-
-		if(trace)
-			runtime·printf("*** cpu R[%d] += R[%d] %x\n",
-				11, 13, regs[11]);
-		return 1;
-	}
-	if(i == 0xeef1fa10) {
-		regs[CPSR] = (regs[CPSR]&0x0fffffff) | m->fflag;
-
-		if(trace)
-			runtime·printf("*** fpsr R[CPSR] = F[CPSR] %x\n", regs[CPSR]);
-		return 1;
-	}
-	if((i&0xff000000) == 0xea000000) {
-		// unconditional branch
-		// can happen in the middle of floating point
-		// if the linker decides it is time to lay down
-		// a sequence of instruction stream constants.
-		delta = i&0xffffff;
-		delta = (delta<<8) >> 8;	// sign extend
-
-		if(trace)
-			runtime·printf("*** cpu PC += %x\n", (delta+2)*4);
-		return delta+2;
-	}
-
-	goto stage1;
-
-stage1:	// load/store regn is cpureg, regm is 8bit offset
-	regd = i>>12 & 0xf;
-	regn = i>>16 & 0xf;
-	regm = (i & 0xff) << 2;	// PLUS or MINUS ??
-
-	switch(i & 0xfff00f00) {
-	default:
-		goto stage2;
-
-	case 0xed900a00:	// single load
-		addr = (uint32*)(regs[regn] + regm);
-		m->freglo[regd] = addr[0];
-
-		if(trace)
-			runtime·printf("*** load F[%d] = %x\n",
-				regd, m->freglo[regd]);
-		break;
-
-	case 0xed900b00:	// double load
-		addr = (uint32*)(regs[regn] + regm);
-		m->freglo[regd] = addr[0];
-		m->freghi[regd] = addr[1];
-
-		if(trace)
-			runtime·printf("*** load D[%d] = %x-%x\n",
-				regd, m->freghi[regd], m->freglo[regd]);
-		break;
-
-	case 0xed800a00:	// single store
-		addr = (uint32*)(regs[regn] + regm);
-		addr[0] = m->freglo[regd];
-
-		if(trace)
-			runtime·printf("*** *(%p) = %x\n",
-				addr, addr[0]);
-		break;
-
-	case 0xed800b00:	// double store
-		addr = (uint32*)(regs[regn] + regm);
-		addr[0] = m->freglo[regd];
-		addr[1] = m->freghi[regd];
-
-		if(trace)
-			runtime·printf("*** *(%p) = %x-%x\n",
-				addr, addr[1], addr[0]);
-		break;
-	}
-	return 1;
-
-stage2:	// regd, regm, regn are 4bit variables
-	regm = i>>0 & 0xf;
-	switch(i & 0xfff00ff0) {
-	default:
-		goto stage3;
-
-	case 0xf3000110:	// veor
-		m->freglo[regd] = m->freglo[regm]^m->freglo[regn];
-		m->freghi[regd] = m->freghi[regm]^m->freghi[regn];
-
-		if(trace)
-			runtime·printf("*** veor D[%d] = %x-%x\n",
-				regd, m->freghi[regd], m->freglo[regd]);
-		break;
-
-	case 0xeeb00b00:	// D[regd] = const(regn,regm)
-		regn = (regn<<4) | regm;
-		regm = 0x40000000UL;
-		if(regn & 0x80)
-			regm |= 0x80000000UL;
-		if(regn & 0x40)
-			regm ^= 0x7fc00000UL;
-		regm |= (regn & 0x3f) << 16;
-		m->freglo[regd] = 0;
-		m->freghi[regd] = regm;
-
-		if(trace)
-			runtime·printf("*** immed D[%d] = %x-%x\n",
-				regd, m->freghi[regd], m->freglo[regd]);
-		break;
-
-	case 0xeeb00a00:	// F[regd] = const(regn,regm)
-		regn = (regn<<4) | regm;
-		regm = 0x40000000UL;
-		if(regn & 0x80)
-			regm |= 0x80000000UL;
-		if(regn & 0x40)
-			regm ^= 0x7e000000UL;
-		regm |= (regn & 0x3f) << 19;
-		m->freglo[regd] = regm;
-
-		if(trace)
-			runtime·printf("*** immed D[%d] = %x\n",
-				regd, m->freglo[regd]);
-		break;
-
-	case 0xee300b00:	// D[regd] = D[regn]+D[regm]
-		runtime·fadd64c(getd(regn), getd(regm), &uval);
-		putd(regd, uval);
-
-		if(trace)
-			runtime·printf("*** add D[%d] = D[%d]+D[%d] %x-%x\n",
-				regd, regn, regm, m->freghi[regd], m->freglo[regd]);
-		break;
-
-	case 0xee300a00:	// F[regd] = F[regn]+F[regm]
-		runtime·fadd64c(f2d(m->freglo[regn]), f2d(m->freglo[regm]), &uval);
-		m->freglo[regd] = d2f(uval);
-
-		if(trace)
-			runtime·printf("*** add F[%d] = F[%d]+F[%d] %x\n",
-				regd, regn, regm, m->freglo[regd]);
-		break;
-
-	case 0xee300b40:	// D[regd] = D[regn]-D[regm]
-		runtime·fsub64c(getd(regn), getd(regm), &uval);
-		putd(regd, uval);
-
-		if(trace)
-			runtime·printf("*** sub D[%d] = D[%d]-D[%d] %x-%x\n",
-				regd, regn, regm, m->freghi[regd], m->freglo[regd]);
-		break;
-
-	case 0xee300a40:	// F[regd] = F[regn]-F[regm]
-		runtime·fsub64c(f2d(m->freglo[regn]), f2d(m->freglo[regm]), &uval);
-		m->freglo[regd] = d2f(uval);
-
-		if(trace)
-			runtime·printf("*** sub F[%d] = F[%d]-F[%d] %x\n",
-				regd, regn, regm, m->freglo[regd]);
-		break;
-
-	case 0xee200b00:	// D[regd] = D[regn]*D[regm]
-		runtime·fmul64c(getd(regn), getd(regm), &uval);
-		putd(regd, uval);
-
-		if(trace)
-			runtime·printf("*** mul D[%d] = D[%d]*D[%d] %x-%x\n",
-				regd, regn, regm, m->freghi[regd], m->freglo[regd]);
-		break;
-
-	case 0xee200a00:	// F[regd] = F[regn]*F[regm]
-		runtime·fmul64c(f2d(m->freglo[regn]), f2d(m->freglo[regm]), &uval);
-		m->freglo[regd] = d2f(uval);
-
-		if(trace)
-			runtime·printf("*** mul F[%d] = F[%d]*F[%d] %x\n",
-				regd, regn, regm, m->freglo[regd]);
-		break;
-
-	case 0xee800b00:	// D[regd] = D[regn]/D[regm]
-		runtime·fdiv64c(getd(regn), getd(regm), &uval);
-		putd(regd, uval);
-
-		if(trace)
-			runtime·printf("*** div D[%d] = D[%d]/D[%d] %x-%x\n",
-				regd, regn, regm, m->freghi[regd], m->freglo[regd]);
-		break;
-
-	case 0xee800a00:	// F[regd] = F[regn]/F[regm]
-		runtime·fdiv64c(f2d(m->freglo[regn]), f2d(m->freglo[regm]), &uval);
-		m->freglo[regd] = d2f(uval);
-
-		if(trace)
-			runtime·printf("*** div F[%d] = F[%d]/F[%d] %x\n",
-				regd, regn, regm, m->freglo[regd]);
-		break;
-
-	case 0xee000b10:	// S[regn] = R[regd] (MOVW) (regm ignored)
-		m->freglo[regn] = regs[regd];
-
-		if(trace)
-			runtime·printf("*** cpy S[%d] = R[%d] %x\n",
-				regn, regd, m->freglo[regn]);
-		break;
-
-	case 0xee100b10:	// R[regd] = S[regn] (MOVW) (regm ignored)
-		regs[regd] = m->freglo[regn];
-
-		if(trace)
-			runtime·printf("*** cpy R[%d] = S[%d] %x\n",
-				regd, regn, regs[regd]);
-		break;
-	}
-	return 1;
-
-stage3:	// regd, regm are 4bit variables
-	switch(i & 0xffff0ff0) {
-	default:
-		goto done;
-
-	case 0xeeb00a40:	// F[regd] = F[regm] (MOVF)
-		m->freglo[regd] = m->freglo[regm];
-
-		if(trace)
-			runtime·printf("*** F[%d] = F[%d] %x\n",
-				regd, regm, m->freglo[regd]);
-		break;
-
-	case 0xeeb00b40:	// D[regd] = D[regm] (MOVD)
-		m->freglo[regd] = m->freglo[regm];
-		m->freghi[regd] = m->freghi[regm];
-
-		if(trace)
-			runtime·printf("*** D[%d] = D[%d] %x-%x\n",
-				regd, regm, m->freghi[regd], m->freglo[regd]);
-		break;
-
-	case 0xeeb10bc0:	// D[regd] = sqrt D[regm]
-		runtime·sqrtC(getd(regm), &uval);
-		putd(regd, uval);
-
-		if(trace)
-			runtime·printf("*** D[%d] = sqrt D[%d] %x-%x\n",
-				regd, regm, m->freghi[regd], m->freglo[regd]);
-		break;
-
-	case 0xeeb00bc0:	// D[regd] = abs D[regm]
-		m->freglo[regd] = m->freglo[regm];
-		m->freghi[regd] = m->freghi[regm] & ((1<<31)-1);
-
-		if(trace)
-			runtime·printf("*** D[%d] = abs D[%d] %x-%x\n",
-					regd, regm, m->freghi[regd], m->freglo[regd]);
-		break;
-
-	case 0xeeb00ac0:	// F[regd] = abs F[regm]
-		m->freglo[regd] = m->freglo[regm] & ((1<<31)-1);
-
-		if(trace)
-			runtime·printf("*** F[%d] = abs F[%d] %x\n",
-					regd, regm, m->freglo[regd]);
-		break;
-
-	case 0xeeb40bc0:	// D[regd] :: D[regm] (CMPD)
-		runtime·fcmp64c(getd(regd), getd(regm), &cmp, &nan);
-		m->fflag = fstatus(nan, cmp);
-
-		if(trace)
-			runtime·printf("*** cmp D[%d]::D[%d] %x\n",
-				regd, regm, m->fflag);
-		break;
-
-	case 0xeeb40ac0:	// F[regd] :: F[regm] (CMPF)
-		runtime·fcmp64c(f2d(m->freglo[regd]), f2d(m->freglo[regm]), &cmp, &nan);
-		m->fflag = fstatus(nan, cmp);
-
-		if(trace)
-			runtime·printf("*** cmp F[%d]::F[%d] %x\n",
-				regd, regm, m->fflag);
-		break;
-
-	case 0xeeb70ac0:	// D[regd] = F[regm] (MOVFD)
-		putd(regd, f2d(m->freglo[regm]));
-
-		if(trace)
-			runtime·printf("*** f2d D[%d]=F[%d] %x-%x\n",
-				regd, regm, m->freghi[regd], m->freglo[regd]);
-		break;
-
-	case 0xeeb70bc0:	// F[regd] = D[regm] (MOVDF)
-		m->freglo[regd] = d2f(getd(regm));
-
-		if(trace)
-			runtime·printf("*** d2f F[%d]=D[%d] %x-%x\n",
-				regd, regm, m->freghi[regd], m->freglo[regd]);
-		break;
-
-	case 0xeebd0ac0:	// S[regd] = F[regm] (MOVFW)
-		runtime·f64tointc(f2d(m->freglo[regm]), &sval, &ok);
-		if(!ok || (int32)sval != sval)
-			sval = 0;
-		m->freglo[regd] = sval;
-
-		if(trace)
-			runtime·printf("*** fix S[%d]=F[%d] %x\n",
-				regd, regm, m->freglo[regd]);
-		break;
-
-	case 0xeebc0ac0:	// S[regd] = F[regm] (MOVFW.U)
-		runtime·f64tointc(f2d(m->freglo[regm]), &sval, &ok);
-		if(!ok || (uint32)sval != sval)
-			sval = 0;
-		m->freglo[regd] = sval;
-
-		if(trace)
-			runtime·printf("*** fix unsigned S[%d]=F[%d] %x\n",
-				regd, regm, m->freglo[regd]);
-		break;
-
-	case 0xeebd0bc0:	// S[regd] = D[regm] (MOVDW)
-		runtime·f64tointc(getd(regm), &sval, &ok);
-		if(!ok || (int32)sval != sval)
-			sval = 0;
-		m->freglo[regd] = sval;
-
-		if(trace)
-			runtime·printf("*** fix S[%d]=D[%d] %x\n",
-				regd, regm, m->freglo[regd]);
-		break;
-
-	case 0xeebc0bc0:	// S[regd] = D[regm] (MOVDW.U)
-		runtime·f64tointc(getd(regm), &sval, &ok);
-		if(!ok || (uint32)sval != sval)
-			sval = 0;
-		m->freglo[regd] = sval;
-
-		if(trace)
-			runtime·printf("*** fix unsigned S[%d]=D[%d] %x\n",
-				regd, regm, m->freglo[regd]);
-		break;
-
-	case 0xeeb80ac0:	// D[regd] = S[regm] (MOVWF)
-		cmp = m->freglo[regm];
-		if(cmp < 0) {
-			runtime·fintto64c(-cmp, &uval);
-			putf(regd, d2f(uval));
-			m->freglo[regd] ^= 0x80000000;
-		} else {
-			runtime·fintto64c(cmp, &uval);
-			putf(regd, d2f(uval));
-		}
-
-		if(trace)
-			runtime·printf("*** float D[%d]=S[%d] %x-%x\n",
-				regd, regm, m->freghi[regd], m->freglo[regd]);
-		break;
-
-	case 0xeeb80a40:	// D[regd] = S[regm] (MOVWF.U)
-		runtime·fintto64c(m->freglo[regm], &uval);
-		putf(regd, d2f(uval));
-
-		if(trace)
-			runtime·printf("*** float unsigned D[%d]=S[%d] %x-%x\n",
-				regd, regm, m->freghi[regd], m->freglo[regd]);
-		break;
-
-	case 0xeeb80bc0:	// D[regd] = S[regm] (MOVWD)
-		cmp = m->freglo[regm];
-		if(cmp < 0) {
-			runtime·fintto64c(-cmp, &uval);
-			putd(regd, uval);
-			m->freghi[regd] ^= 0x80000000;
-		} else {
-			runtime·fintto64c(cmp, &uval);
-			putd(regd, uval);
-		}
-
-		if(trace)
-			runtime·printf("*** float D[%d]=S[%d] %x-%x\n",
-				regd, regm, m->freghi[regd], m->freglo[regd]);
-		break;
-
-	case 0xeeb80b40:	// D[regd] = S[regm] (MOVWD.U)
-		runtime·fintto64c(m->freglo[regm], &uval);
-		putd(regd, uval);
-
-		if(trace)
-			runtime·printf("*** float unsigned D[%d]=S[%d] %x-%x\n",
-				regd, regm, m->freghi[regd], m->freglo[regd]);
-		break;
-	}
-	return 1;
-
-done:
-	if((i&0xff000000) == 0xee000000 ||
-	   (i&0xff000000) == 0xed000000) {
-		runtime·printf("stepflt %p %x\n", pc, i);
-		fabort();
-	}
-	return 0;
-}
-
-typedef struct Sfregs Sfregs;
-
-// NOTE: These are all recorded as pointers because they are possibly live registers,
-// and we don't know what they contain. Recording them as pointers should be
-// safer than not.
-struct Sfregs
-{
-	uint32 *r0;
-	uint32 *r1;
-	uint32 *r2;
-	uint32 *r3;
-	uint32 *r4;
-	uint32 *r5;
-	uint32 *r6;
-	uint32 *r7;
-	uint32 *r8;
-	uint32 *r9;
-	uint32 *r10;
-	uint32 *r11;
-	uint32 *r12;
-	uint32 *r13;
-	uint32 cspr;
-};
-
-#pragma textflag NOSPLIT
-uint32*
-runtime·_sfloat2(uint32 *lr, Sfregs regs)
-{
-	uint32 skip;
-
-	skip = stepflt(lr, (uint32*)&regs.r0);
-	if(skip == 0) {
-		runtime·printf("sfloat2 %p %x\n", lr, *lr);
-		fabort(); // not ok to fail first instruction
-	}
-
-	lr += skip;
-	while(skip = stepflt(lr, (uint32*)&regs.r0))
-		lr += skip;
-	return lr;
-}
diff --git a/src/pkg/runtime/stack.c b/src/pkg/runtime/stack.c
deleted file mode 100644
index 1680f00..0000000
--- a/src/pkg/runtime/stack.c
+++ /dev/null
@@ -1,947 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "runtime.h"
-#include "arch_GOARCH.h"
-#include "malloc.h"
-#include "stack.h"
-#include "funcdata.h"
-#include "typekind.h"
-#include "type.h"
-#include "../../cmd/ld/textflag.h"
-
-enum
-{
-	// StackDebug == 0: no logging
-	//            == 1: logging of per-stack operations
-	//            == 2: logging of per-frame operations
-	//            == 3: logging of per-word updates
-	//            == 4: logging of per-word reads
-	StackDebug = 0,
-	StackFromSystem = 0,	// allocate stacks from system memory instead of the heap
-	StackFaultOnFree = 0,	// old stacks are mapped noaccess to detect use after free
-};
-
-typedef struct StackCacheNode StackCacheNode;
-struct StackCacheNode
-{
-	StackCacheNode *next;
-	void*	batch[StackCacheBatch-1];
-};
-
-static StackCacheNode *stackcache;
-static Lock stackcachemu;
-
-// stackcacherefill/stackcacherelease implement a global cache of stack segments.
-// The cache is required to prevent unlimited growth of per-thread caches.
-static void
-stackcacherefill(void)
-{
-	StackCacheNode *n;
-	int32 i, pos;
-
-	runtime·lock(&stackcachemu);
-	n = stackcache;
-	if(n)
-		stackcache = n->next;
-	runtime·unlock(&stackcachemu);
-	if(n == nil) {
-		n = (StackCacheNode*)runtime·SysAlloc(FixedStack*StackCacheBatch, &mstats.stacks_sys);
-		if(n == nil)
-			runtime·throw("out of memory (stackcacherefill)");
-		for(i = 0; i < StackCacheBatch-1; i++)
-			n->batch[i] = (byte*)n + (i+1)*FixedStack;
-	}
-	pos = m->stackcachepos;
-	for(i = 0; i < StackCacheBatch-1; i++) {
-		m->stackcache[pos] = n->batch[i];
-		pos = (pos + 1) % StackCacheSize;
-	}
-	m->stackcache[pos] = n;
-	pos = (pos + 1) % StackCacheSize;
-	m->stackcachepos = pos;
-	m->stackcachecnt += StackCacheBatch;
-}
-
-static void
-stackcacherelease(void)
-{
-	StackCacheNode *n;
-	uint32 i, pos;
-
-	pos = (m->stackcachepos - m->stackcachecnt) % StackCacheSize;
-	n = (StackCacheNode*)m->stackcache[pos];
-	pos = (pos + 1) % StackCacheSize;
-	for(i = 0; i < StackCacheBatch-1; i++) {
-		n->batch[i] = m->stackcache[pos];
-		pos = (pos + 1) % StackCacheSize;
-	}
-	m->stackcachecnt -= StackCacheBatch;
-	runtime·lock(&stackcachemu);
-	n->next = stackcache;
-	stackcache = n;
-	runtime·unlock(&stackcachemu);
-}
-
-void*
-runtime·stackalloc(G *gp, uint32 n)
-{
-	uint32 pos;
-	void *v;
-	bool malloced;
-	Stktop *top;
-
-	// Stackalloc must be called on scheduler stack, so that we
-	// never try to grow the stack during the code that stackalloc runs.
-	// Doing so would cause a deadlock (issue 1547).
-	if(g != m->g0)
-		runtime·throw("stackalloc not on scheduler stack");
-	if((n & (n-1)) != 0)
-		runtime·throw("stack size not a power of 2");
-	if(StackDebug >= 1)
-		runtime·printf("stackalloc %d\n", n);
-
-	gp->stacksize += n;
-	if(runtime·debug.efence || StackFromSystem) {
-		v = runtime·SysAlloc(ROUND(n, PageSize), &mstats.stacks_sys);
-		if(v == nil)
-			runtime·throw("out of memory (stackalloc)");
-		return v;
-	}
-
-	// Minimum-sized stacks are allocated with a fixed-size free-list allocator,
-	// but if we need a stack of a bigger size, we fall back on malloc
-	// (assuming that inside malloc all the stack frames are small,
-	// so that we do not deadlock).
-	malloced = true;
-	if(n == FixedStack || m->mallocing) {
-		if(n != FixedStack) {
-			runtime·printf("stackalloc: in malloc, size=%d want %d\n", FixedStack, n);
-			runtime·throw("stackalloc");
-		}
-		if(m->stackcachecnt == 0)
-			stackcacherefill();
-		pos = m->stackcachepos;
-		pos = (pos - 1) % StackCacheSize;
-		v = m->stackcache[pos];
-		m->stackcachepos = pos;
-		m->stackcachecnt--;
-		m->stackinuse++;
-		malloced = false;
-	} else
-		v = runtime·mallocgc(n, 0, FlagNoProfiling|FlagNoGC|FlagNoZero|FlagNoInvokeGC);
-
-	top = (Stktop*)((byte*)v+n-sizeof(Stktop));
-	runtime·memclr((byte*)top, sizeof(*top));
-	top->malloced = malloced;
-	return v;
-}
-
-void
-runtime·stackfree(G *gp, void *v, Stktop *top)
-{
-	uint32 pos;
-	uintptr n;
-
-	n = (uintptr)(top+1) - (uintptr)v;
-	if(StackDebug >= 1)
-		runtime·printf("stackfree %p %d\n", v, (int32)n);
-	gp->stacksize -= n;
-	if(runtime·debug.efence || StackFromSystem) {
-		if(runtime·debug.efence || StackFaultOnFree)
-			runtime·SysFault(v, n);
-		else
-			runtime·SysFree(v, n, &mstats.stacks_sys);
-		return;
-	}
-	if(top->malloced) {
-		runtime·free(v);
-		return;
-	}
-	if(n != FixedStack)
-		runtime·throw("stackfree: bad fixed size");
-	if(m->stackcachecnt == StackCacheSize)
-		stackcacherelease();
-	pos = m->stackcachepos;
-	m->stackcache[pos] = v;
-	m->stackcachepos = (pos + 1) % StackCacheSize;
-	m->stackcachecnt++;
-	m->stackinuse--;
-}
-
-// Called from runtime·lessstack when returning from a function which
-// allocated a new stack segment.  The function's return value is in
-// m->cret.
-void
-runtime·oldstack(void)
-{
-	Stktop *top;
-	uint32 argsize;
-	byte *sp, *old;
-	uintptr *src, *dst, *dstend;
-	G *gp;
-	int64 goid;
-	int32 oldstatus;
-
-	gp = m->curg;
-	top = (Stktop*)gp->stackbase;
-	old = (byte*)gp->stackguard - StackGuard;
-	sp = (byte*)top;
-	argsize = top->argsize;
-
-	if(StackDebug >= 1) {
-		runtime·printf("runtime: oldstack gobuf={pc:%p sp:%p lr:%p} cret=%p argsize=%p\n",
-			top->gobuf.pc, top->gobuf.sp, top->gobuf.lr, (uintptr)m->cret, (uintptr)argsize);
-	}
-
-	// gp->status is usually Grunning, but it could be Gsyscall if a stack overflow
-	// happens during a function call inside entersyscall.
-	oldstatus = gp->status;
-	
-	gp->sched = top->gobuf;
-	gp->sched.ret = m->cret;
-	m->cret = 0; // drop reference
-	gp->status = Gwaiting;
-	gp->waitreason = "stack unsplit";
-
-	if(argsize > 0) {
-		sp -= argsize;
-		dst = (uintptr*)top->argp;
-		dstend = dst + argsize/sizeof(*dst);
-		src = (uintptr*)sp;
-		while(dst < dstend)
-			*dst++ = *src++;
-	}
-	goid = top->gobuf.g->goid;	// fault if g is bad, before gogo
-	USED(goid);
-
-	gp->stackbase = top->stackbase;
-	gp->stackguard = top->stackguard;
-	gp->stackguard0 = gp->stackguard;
-	gp->panicwrap = top->panicwrap;
-	runtime·stackfree(gp, old, top);
-
-	gp->status = oldstatus;
-	runtime·gogo(&gp->sched);
-}
-
-uintptr runtime·maxstacksize = 1<<20; // enough until runtime.main sets it for real
-
-static uint8*
-mapnames[] = {
-	(uint8*)"---",
-	(uint8*)"scalar",
-	(uint8*)"ptr",
-	(uint8*)"multi",
-};
-
-// Stack frame layout
-//
-// (x86)
-// +------------------+
-// | args from caller |
-// +------------------+ <- frame->argp
-// |  return address  |
-// +------------------+ <- frame->varp
-// |     locals       |
-// +------------------+
-// |  args to callee  |
-// +------------------+ <- frame->sp
-//
-// (arm: TODO)
-
-typedef struct CopyableInfo CopyableInfo;
-struct CopyableInfo {
-	byte *stk;	// bottom address of segment
-	byte *base;	// top address of segment (including Stktop)
-	int32 frames;	// count of copyable frames (-1 = not copyable)
-};
-
-void runtime·main(void);
-
-static bool
-checkframecopy(Stkframe *frame, void *arg)
-{
-	CopyableInfo *cinfo;
-	Func *f;
-	StackMap *stackmap;
-
-	cinfo = arg;
-	f = frame->fn;
-	if(StackDebug >= 2)
-		runtime·printf("    checking %s frame=[%p,%p] stk=[%p,%p]\n", runtime·funcname(f), frame->sp, frame->fp, cinfo->stk, cinfo->base);
-	// if we're not in the segment any more, return immediately.
-	if(frame->varp < cinfo->stk || frame->varp >= cinfo->base) {
-		if(StackDebug >= 2)
-			runtime·printf("    <next segment>\n");
-		return false; // stop traceback
-	}
-	if(f->entry == (uintptr)runtime·main) {
-		// A special routine at the TOS of the main routine.
-		// We will allow it to be copied even though we don't
-		// have full GC info for it (because it is written in C).
-		cinfo->frames++;
-		return false; // stop traceback
-	}
-	if(frame->varp != (byte*)frame->sp) { // not in prologue (and has at least one local or outarg)
-		stackmap = runtime·funcdata(f, FUNCDATA_LocalsPointerMaps);
-		if(stackmap == nil) {
-			cinfo->frames = -1;
-			if(StackDebug >= 1)
-				runtime·printf("copystack: no locals info for %s\n", runtime·funcname(f));
-			return false;
-		}
-		if(stackmap->n <= 0) {
-			cinfo->frames = -1;
-			if(StackDebug >= 1)
-				runtime·printf("copystack: locals size info only for %s\n", runtime·funcname(f));
-			return false;
-		}
-	}
-	if(frame->arglen != 0) {
-		stackmap = runtime·funcdata(f, FUNCDATA_ArgsPointerMaps);
-		if(stackmap == nil) {
-			cinfo->frames = -1;
-			if(StackDebug >= 1)
-				runtime·printf("copystack: no arg info for %s\n", runtime·funcname(f));
-			return false;
-		}
-	}
-	cinfo->frames++;
-	return true; // this frame is ok; keep going
-}
-
-// If the top segment of the stack contains an uncopyable
-// frame, return -1.  Otherwise return the number of frames
-// in the top segment, all of which are copyable.
-static int32
-copyabletopsegment(G *gp)
-{
-	CopyableInfo cinfo;
-	Defer *d;
-	Func *f;
-	FuncVal *fn;
-	StackMap *stackmap;
-
-	cinfo.stk = (byte*)gp->stackguard - StackGuard;
-	cinfo.base = (byte*)gp->stackbase + sizeof(Stktop);
-	cinfo.frames = 0;
-
-	// Check that each frame is copyable.  As a side effect,
-	// count the frames.
-	runtime·gentraceback(~(uintptr)0, ~(uintptr)0, 0, gp, 0, nil, 0x7fffffff, checkframecopy, &cinfo, false);
-	if(StackDebug >= 1 && cinfo.frames != -1)
-		runtime·printf("copystack: %d copyable frames\n", cinfo.frames);
-
-	// Check to make sure all Defers are copyable
-	for(d = gp->defer; d != nil; d = d->link) {
-		if(cinfo.stk <= (byte*)d && (byte*)d < cinfo.base) {
-			// Defer is on the stack.  Its copyableness has
-			// been established during stack walking.
-			// For now, this only happens with the Defer in runtime.main.
-			continue;
-		}
-		if(d->argp < cinfo.stk || cinfo.base <= d->argp)
-			break; // a defer for the next segment
-		fn = d->fn;
-		if(fn == nil) // See issue 8047
-			continue;
-		f = runtime·findfunc((uintptr)fn->fn);
-		if(f == nil)
-			return -1;
-
-		// Check to make sure we have an args pointer map for the defer's args.
-		// We only need the args map, but we check
-		// for the locals map also, because when the locals map
-		// isn't provided it means the ptr map came from C and
-		// C (particularly, cgo) lies to us.  See issue 7695.
-		stackmap = runtime·funcdata(f, FUNCDATA_ArgsPointerMaps);
-		if(stackmap == nil || stackmap->n <= 0)
-			return -1;
-		stackmap = runtime·funcdata(f, FUNCDATA_LocalsPointerMaps);
-		if(stackmap == nil || stackmap->n <= 0)
-			return -1;
-
-		if(cinfo.stk <= (byte*)fn && (byte*)fn < cinfo.base) {
-			// FuncVal is on the stack.  Again, its copyableness
-			// was established during stack walking.
-			continue;
-		}
-		// The FuncVal may have pointers in it, but fortunately for us
-		// the compiler won't put pointers into the stack in a
-		// heap-allocated FuncVal.
-		// One day if we do need to check this, we'll need maps of the
-		// pointerness of the closure args.  The only place we have that map
-		// right now is in the gc program for the FuncVal.  Ugh.
-	}
-
-	return cinfo.frames;
-}
-
-typedef struct AdjustInfo AdjustInfo;
-struct AdjustInfo {
-	byte *oldstk;	// bottom address of segment
-	byte *oldbase;	// top address of segment (after Stktop)
-	uintptr delta;  // ptr distance from old to new stack (newbase - oldbase)
-};
-
-// bv describes the memory starting at address scanp.
-// Adjust any pointers contained therein.
-static void
-adjustpointers(byte **scanp, BitVector *bv, AdjustInfo *adjinfo, Func *f)
-{
-	uintptr delta;
-	int32 num, i;
-	byte *p, *minp, *maxp;
-	Type *t;
-	Itab *tab;
-	
-	minp = adjinfo->oldstk;
-	maxp = adjinfo->oldbase;
-	delta = adjinfo->delta;
-	num = bv->n / BitsPerPointer;
-	for(i = 0; i < num; i++) {
-		if(StackDebug >= 4)
-			runtime·printf("        %p:%s:%p\n", &scanp[i], mapnames[bv->data[i / (32 / BitsPerPointer)] >> (i * BitsPerPointer & 31) & 3], scanp[i]);
-		switch(bv->data[i / (32 / BitsPerPointer)] >> (i * BitsPerPointer & 31) & 3) {
-		case BitsDead:
-			if(runtime·debug.gcdead)
-				scanp[i] = (byte*)PoisonStack;
-			break;
-		case BitsScalar:
-			break;
-		case BitsPointer:
-			p = scanp[i];
-			if(f != nil && (byte*)0 < p && (p < (byte*)PageSize || (uintptr)p == PoisonGC || (uintptr)p == PoisonStack)) {
-				// Looks like a junk value in a pointer slot.
-				// Live analysis wrong?
-				m->traceback = 2;
-				runtime·printf("runtime: bad pointer in frame %s at %p: %p\n", runtime·funcname(f), &scanp[i], p);
-				runtime·throw("bad pointer!");
-			}
-			if(minp <= p && p < maxp) {
-				if(StackDebug >= 3)
-					runtime·printf("adjust ptr %p %s\n", p, runtime·funcname(f));
-				scanp[i] = p + delta;
-			}
-			break;
-		case BitsMultiWord:
-			switch(bv->data[(i+1) / (32 / BitsPerPointer)] >> ((i+1) * BitsPerPointer & 31) & 3) {
-			case BitsString:
-				// string referents are never on the stack, never need to be adjusted
-				i++; // skip len
-				break;
-			case BitsSlice:
-				p = scanp[i];
-				if(minp <= p && p < maxp) {
-					if(StackDebug >= 3)
-						runtime·printf("adjust slice %p\n", p);
-					scanp[i] = p + delta;
-				}
-				i += 2; // skip len, cap
-				break;
-			case BitsEface:
-				t = (Type*)scanp[i];
-				if(t != nil && (t->size > PtrSize || (t->kind & KindNoPointers) == 0)) {
-					p = scanp[i+1];
-					if(minp <= p && p < maxp) {
-						if(StackDebug >= 3)
-							runtime·printf("adjust eface %p\n", p);
-						if(t->size > PtrSize) // currently we always allocate such objects on the heap
-							runtime·throw("large interface value found on stack");
-						scanp[i+1] = p + delta;
-					}
-				}
-				i++;
-				break;
-			case BitsIface:
-				tab = (Itab*)scanp[i];
-				if(tab != nil) {
-					t = tab->type;
-					//runtime·printf("          type=%p\n", t);
-					if(t->size > PtrSize || (t->kind & KindNoPointers) == 0) {
-						p = scanp[i+1];
-						if(minp <= p && p < maxp) {
-							if(StackDebug >= 3)
-								runtime·printf("adjust iface %p\n", p);
-							if(t->size > PtrSize) // currently we always allocate such objects on the heap
-								runtime·throw("large interface value found on stack");
-							scanp[i+1] = p + delta;
-						}
-					}
-				}
-				i++;
-				break;
-			}
-			break;
-		}
-	}
-}
-
-// Note: the argument/return area is adjusted by the callee.
-static bool
-adjustframe(Stkframe *frame, void *arg)
-{
-	AdjustInfo *adjinfo;
-	Func *f;
-	StackMap *stackmap;
-	int32 pcdata;
-	BitVector bv;
-	uintptr targetpc;
-
-	adjinfo = arg;
-	f = frame->fn;
-	if(StackDebug >= 2)
-		runtime·printf("    adjusting %s frame=[%p,%p] pc=%p continpc=%p\n", runtime·funcname(f), frame->sp, frame->fp, frame->pc, frame->continpc);
-	if(f->entry == (uintptr)runtime·main)
-		return true;
-	targetpc = frame->continpc;
-	if(targetpc == 0) {
-		// Frame is dead.
-		return true;
-	}
-	if(targetpc != f->entry)
-		targetpc--;
-	pcdata = runtime·pcdatavalue(f, PCDATA_StackMapIndex, targetpc);
-	if(pcdata == -1)
-		pcdata = 0; // in prologue
-
-	// adjust local pointers
-	if(frame->varp != (byte*)frame->sp) {
-		stackmap = runtime·funcdata(f, FUNCDATA_LocalsPointerMaps);
-		if(stackmap == nil)
-			runtime·throw("no locals info");
-		if(stackmap->n <= 0)
-			runtime·throw("locals size info only");
-		bv = runtime·stackmapdata(stackmap, pcdata);
-		if(StackDebug >= 3)
-			runtime·printf("      locals\n");
-		adjustpointers((byte**)frame->varp - bv.n / BitsPerPointer, &bv, adjinfo, f);
-	}
-	// adjust inargs and outargs
-	if(frame->arglen != 0) {
-		stackmap = runtime·funcdata(f, FUNCDATA_ArgsPointerMaps);
-		if(stackmap == nil)
-			runtime·throw("no arg info");
-		bv = runtime·stackmapdata(stackmap, pcdata);
-		if(StackDebug >= 3)
-			runtime·printf("      args\n");
-		adjustpointers((byte**)frame->argp, &bv, adjinfo, nil);
-	}
-	return true;
-}
-
-static void
-adjustctxt(G *gp, AdjustInfo *adjinfo)
-{
-	if(adjinfo->oldstk <= (byte*)gp->sched.ctxt && (byte*)gp->sched.ctxt < adjinfo->oldbase)
-		gp->sched.ctxt = (byte*)gp->sched.ctxt + adjinfo->delta;
-}
-
-static void
-adjustdefers(G *gp, AdjustInfo *adjinfo)
-{
-	Defer *d, **dp;
-	Func *f;
-	FuncVal *fn;
-	StackMap *stackmap;
-	BitVector bv;
-
-	for(dp = &gp->defer, d = *dp; d != nil; dp = &d->link, d = *dp) {
-		if(adjinfo->oldstk <= (byte*)d && (byte*)d < adjinfo->oldbase) {
-			// The Defer record is on the stack.  Its fields will
-			// get adjusted appropriately.
-			// This only happens for runtime.main now, but a compiler
-			// optimization could do more of this.
-			*dp = (Defer*)((byte*)d + adjinfo->delta);
-			continue;
-		}
-		if(d->argp < adjinfo->oldstk || adjinfo->oldbase <= d->argp)
-			break; // a defer for the next segment
-		fn = d->fn;
-		if(fn == nil) {
-			// Defer of nil function.  It will panic when run, and there
-			// aren't any args to adjust.  See issue 8047.
-			d->argp += adjinfo->delta;
-			continue;
-		}
-		f = runtime·findfunc((uintptr)fn->fn);
-		if(f == nil)
-			runtime·throw("can't adjust unknown defer");
-		if(StackDebug >= 4)
-			runtime·printf("  checking defer %s\n", runtime·funcname(f));
-		// Defer's FuncVal might be on the stack
-		if(adjinfo->oldstk <= (byte*)fn && (byte*)fn < adjinfo->oldbase) {
-			if(StackDebug >= 3)
-				runtime·printf("    adjust defer fn %s\n", runtime·funcname(f));
-			d->fn = (FuncVal*)((byte*)fn + adjinfo->delta);
-		} else {
-			// deferred function's args might point into the stack.
-			if(StackDebug >= 3)
-				runtime·printf("    adjust deferred args for %s\n", runtime·funcname(f));
-			stackmap = runtime·funcdata(f, FUNCDATA_ArgsPointerMaps);
-			if(stackmap == nil)
-				runtime·throw("runtime: deferred function has no arg ptr map");
-			bv = runtime·stackmapdata(stackmap, 0);
-			adjustpointers(d->args, &bv, adjinfo, f);
-		}
-		d->argp += adjinfo->delta;
-	}
-}
-
-// Copies the top stack segment of gp to a new stack segment of a
-// different size.  The top segment must contain nframes frames.
-static void
-copystack(G *gp, uintptr nframes, uintptr newsize)
-{
-	byte *oldstk, *oldbase, *newstk, *newbase;
-	uintptr oldsize, used;
-	AdjustInfo adjinfo;
-	Stktop *oldtop, *newtop;
-	bool malloced;
-
-	if(gp->syscallstack != 0)
-		runtime·throw("can't handle stack copy in syscall yet");
-	oldstk = (byte*)gp->stackguard - StackGuard;
-	oldbase = (byte*)gp->stackbase + sizeof(Stktop);
-	oldsize = oldbase - oldstk;
-	used = oldbase - (byte*)gp->sched.sp;
-	oldtop = (Stktop*)gp->stackbase;
-
-	// allocate new stack
-	newstk = runtime·stackalloc(gp, newsize);
-	newbase = newstk + newsize;
-	newtop = (Stktop*)(newbase - sizeof(Stktop));
-	malloced = newtop->malloced;
-
-	if(StackDebug >= 1)
-		runtime·printf("copystack [%p %p]/%d -> [%p %p]/%d\n", oldstk, oldbase, (int32)oldsize, newstk, newbase, (int32)newsize);
-	USED(oldsize);
-	
-	// adjust pointers in the to-be-copied frames
-	adjinfo.oldstk = oldstk;
-	adjinfo.oldbase = oldbase;
-	adjinfo.delta = newbase - oldbase;
-	runtime·gentraceback(~(uintptr)0, ~(uintptr)0, 0, gp, 0, nil, nframes, adjustframe, &adjinfo, false);
-	
-	// adjust other miscellaneous things that have pointers into stacks.
-	adjustctxt(gp, &adjinfo);
-	adjustdefers(gp, &adjinfo);
-	
-	// copy the stack (including Stktop) to the new location
-	runtime·memmove(newbase - used, oldbase - used, used);
-	newtop->malloced = malloced;
-	
-	// Swap out old stack for new one
-	gp->stackbase = (uintptr)newtop;
-	gp->stackguard = (uintptr)newstk + StackGuard;
-	gp->stackguard0 = (uintptr)newstk + StackGuard; // NOTE: might clobber a preempt request
-	if(gp->stack0 == (uintptr)oldstk)
-		gp->stack0 = (uintptr)newstk;
-	gp->sched.sp = (uintptr)(newbase - used);
-
-	// free old stack
-	runtime·stackfree(gp, oldstk, oldtop);
-}
-
-// round x up to a power of 2.
-int32
-runtime·round2(int32 x)
-{
-	int32 s;
-
-	s = 0;
-	while((1 << s) < x)
-		s++;
-	return 1 << s;
-}
-
-// Called from runtime·newstackcall or from runtime·morestack when a new
-// stack segment is needed.  Allocate a new stack big enough for
-// m->moreframesize bytes, copy m->moreargsize bytes to the new frame,
-// and then act as though runtime·lessstack called the function at
-// m->morepc.
-void
-runtime·newstack(void)
-{
-	int32 framesize, argsize, oldstatus, oldsize, newsize, nframes;
-	Stktop *top, *oldtop;
-	byte *stk, *oldstk, *oldbase;
-	uintptr sp;
-	uintptr *src, *dst, *dstend;
-	G *gp;
-	Gobuf label, morebuf;
-	void *moreargp;
-	bool newstackcall;
-
-	if(m->forkstackguard)
-		runtime·throw("split stack after fork");
-	if(m->morebuf.g != m->curg) {
-		runtime·printf("runtime: newstack called from g=%p\n"
-			"\tm=%p m->curg=%p m->g0=%p m->gsignal=%p\n",
-			m->morebuf.g, m, m->curg, m->g0, m->gsignal);
-		runtime·throw("runtime: wrong goroutine in newstack");
-	}
-
-	// gp->status is usually Grunning, but it could be Gsyscall if a stack overflow
-	// happens during a function call inside entersyscall.
-	gp = m->curg;
-	oldstatus = gp->status;
-
-	framesize = m->moreframesize;
-	argsize = m->moreargsize;
-	moreargp = m->moreargp;
-	m->moreargp = nil;
-	morebuf = m->morebuf;
-	m->morebuf.pc = (uintptr)nil;
-	m->morebuf.lr = (uintptr)nil;
-	m->morebuf.sp = (uintptr)nil;
-	gp->status = Gwaiting;
-	gp->waitreason = "stack growth";
-	newstackcall = framesize==1;
-	if(newstackcall)
-		framesize = 0;
-
-	// For newstackcall the context already points to beginning of runtime·newstackcall.
-	if(!newstackcall)
-		runtime·rewindmorestack(&gp->sched);
-
-	sp = gp->sched.sp;
-	if(thechar == '6' || thechar == '8') {
-		// The call to morestack cost a word.
-		sp -= sizeof(uintptr);
-	}
-	if(StackDebug >= 1 || sp < gp->stackguard - StackGuard) {
-		runtime·printf("runtime: newstack framesize=%p argsize=%p sp=%p stack=[%p, %p]\n"
-			"\tmorebuf={pc:%p sp:%p lr:%p}\n"
-			"\tsched={pc:%p sp:%p lr:%p ctxt:%p}\n",
-			(uintptr)framesize, (uintptr)argsize, sp, gp->stackguard - StackGuard, gp->stackbase,
-			m->morebuf.pc, m->morebuf.sp, m->morebuf.lr,
-			gp->sched.pc, gp->sched.sp, gp->sched.lr, gp->sched.ctxt);
-	}
-	if(sp < gp->stackguard - StackGuard) {
-		runtime·printf("runtime: split stack overflow: %p < %p\n", sp, gp->stackguard - StackGuard);
-		runtime·throw("runtime: split stack overflow");
-	}
-
-	if(argsize % sizeof(uintptr) != 0) {
-		runtime·printf("runtime: stack growth with misaligned argsize %d\n", argsize);
-		runtime·throw("runtime: stack growth argsize");
-	}
-
-	if(gp->stackguard0 == (uintptr)StackPreempt) {
-		if(gp == m->g0)
-			runtime·throw("runtime: preempt g0");
-		if(oldstatus == Grunning && m->p == nil && m->locks == 0)
-			runtime·throw("runtime: g is running but p is not");
-		if(oldstatus == Gsyscall && m->locks == 0)
-			runtime·throw("runtime: stack growth during syscall");
-		// Be conservative about where we preempt.
-		// We are interested in preempting user Go code, not runtime code.
-		if(oldstatus != Grunning || m->locks || m->mallocing || m->gcing || m->p->status != Prunning) {
-			// Let the goroutine keep running for now.
-			// gp->preempt is set, so it will be preempted next time.
-			gp->stackguard0 = gp->stackguard;
-			gp->status = oldstatus;
-			runtime·gogo(&gp->sched);	// never return
-		}
-		// Act like goroutine called runtime.Gosched.
-		gp->status = oldstatus;
-		runtime·gosched0(gp);	// never return
-	}
-
-	// If every frame on the top segment is copyable, allocate a bigger segment
-	// and move the segment instead of allocating a new segment.
-	if(runtime·copystack) {
-		if(!runtime·precisestack)
-			runtime·throw("can't copy stacks without precise stacks");
-		nframes = copyabletopsegment(gp);
-		if(nframes != -1) {
-			oldstk = (byte*)gp->stackguard - StackGuard;
-			oldbase = (byte*)gp->stackbase + sizeof(Stktop);
-			oldsize = oldbase - oldstk;
-			newsize = oldsize * 2;
-			copystack(gp, nframes, newsize);
-			if(StackDebug >= 1)
-				runtime·printf("stack grow done\n");
-			if(gp->stacksize > runtime·maxstacksize) {
-				runtime·printf("runtime: goroutine stack exceeds %D-byte limit\n", (uint64)runtime·maxstacksize);
-				runtime·throw("stack overflow");
-			}
-			gp->status = oldstatus;
-			runtime·gogo(&gp->sched);
-		}
-		// TODO: if stack is uncopyable because we're in C code, patch return value at
-		// end of C code to trigger a copy as soon as C code exits.  That way, we'll
-		// have stack available if we get this deep again.
-	}
-
-	// allocate new segment.
-	framesize += argsize;
-	framesize += StackExtra;	// room for more functions, Stktop.
-	if(framesize < StackMin)
-		framesize = StackMin;
-	framesize += StackSystem;
-	framesize = runtime·round2(framesize);
-	stk = runtime·stackalloc(gp, framesize);
-	if(gp->stacksize > runtime·maxstacksize) {
-		runtime·printf("runtime: goroutine stack exceeds %D-byte limit\n", (uint64)runtime·maxstacksize);
-		runtime·throw("stack overflow");
-	}
-	top = (Stktop*)(stk+framesize-sizeof(*top));
-
-	if(StackDebug >= 1) {
-		runtime·printf("\t-> new stack [%p, %p]\n", stk, top);
-	}
-
-	top->stackbase = gp->stackbase;
-	top->stackguard = gp->stackguard;
-	top->gobuf = morebuf;
-	top->argp = moreargp;
-	top->argsize = argsize;
-
-	// copy flag from panic
-	top->panic = gp->ispanic;
-	gp->ispanic = false;
-	
-	// if this isn't a panic, maybe we're splitting the stack for a panic.
-	// if we're splitting in the top frame, propagate the panic flag
-	// forward so that recover will know we're in a panic.
-	oldtop = (Stktop*)top->stackbase;
-	if(oldtop != nil && oldtop->panic && top->argp == (byte*)oldtop - oldtop->argsize - gp->panicwrap)
-		top->panic = true;
-
-	top->panicwrap = gp->panicwrap;
-	gp->panicwrap = 0;
-
-	gp->stackbase = (uintptr)top;
-	gp->stackguard = (uintptr)stk + StackGuard;
-	gp->stackguard0 = gp->stackguard;
-
-	sp = (uintptr)top;
-	if(argsize > 0) {
-		sp -= argsize;
-		dst = (uintptr*)sp;
-		dstend = dst + argsize/sizeof(*dst);
-		src = (uintptr*)top->argp;
-		while(dst < dstend)
-			*dst++ = *src++;
-	}
-	if(thechar == '5') {
-		// caller would have saved its LR below args.
-		sp -= sizeof(void*);
-		*(void**)sp = nil;
-	}
-
-	// Continue as if lessstack had just called m->morepc
-	// (the PC that decided to grow the stack).
-	runtime·memclr((byte*)&label, sizeof label);
-	label.sp = sp;
-	label.pc = (uintptr)runtime·lessstack;
-	label.g = m->curg;
-	if(newstackcall)
-		runtime·gostartcallfn(&label, (FuncVal*)m->cret);
-	else {
-		runtime·gostartcall(&label, (void(*)(void))gp->sched.pc, gp->sched.ctxt);
-		gp->sched.ctxt = nil;
-	}
-	gp->status = oldstatus;
-	runtime·gogo(&label);
-
-	*(int32*)345 = 123;	// never return
-}
-
-#pragma textflag NOSPLIT
-void
-runtime·nilfunc(void)
-{
-	*(byte*)0 = 0;
-}
-
-// adjust Gobuf as if it executed a call to fn
-// and then did an immediate gosave.
-void
-runtime·gostartcallfn(Gobuf *gobuf, FuncVal *fv)
-{
-	void *fn;
-
-	if(fv != nil)
-		fn = fv->fn;
-	else
-		fn = runtime·nilfunc;
-	runtime·gostartcall(gobuf, fn, fv);
-}
-
-// Maybe shrink the stack being used by gp.
-// Called at garbage collection time.
-void
-runtime·shrinkstack(G *gp)
-{
-	int32 nframes;
-	byte *oldstk, *oldbase;
-	uintptr used, oldsize, newsize;
-	MSpan *span;
-
-	if(!runtime·copystack)
-		return;
-	oldstk = (byte*)gp->stackguard - StackGuard;
-	oldbase = (byte*)gp->stackbase + sizeof(Stktop);
-	oldsize = oldbase - oldstk;
-	newsize = oldsize / 2;
-	if(newsize < FixedStack)
-		return; // don't shrink below the minimum-sized stack
-	used = oldbase - (byte*)gp->sched.sp;
-	if(used >= oldsize / 4)
-		return; // still using at least 1/4 of the segment.
-
-	// To shrink to less than 1/2 a page, we need to copy.
-	if(newsize < PageSize/2) {
-		if(gp->syscallstack != (uintptr)nil) // TODO: can we handle this case?
-			return;
-#ifdef GOOS_windows
-		if(gp->m != nil && gp->m->libcallsp != 0)
-			return;
-#endif
-		nframes = copyabletopsegment(gp);
-		if(nframes == -1)
-			return;
-		copystack(gp, nframes, newsize);
-		return;
-	}
-
-	// To shrink a stack of one page size or more, we can shrink it
-	// without copying.  Just deallocate the lower half.
-	span = runtime·MHeap_LookupMaybe(&runtime·mheap, oldstk);
-	if(span == nil)
-		return; // stack allocated outside heap.  Can't shrink it.  Can happen if stack is allocated while inside malloc.  TODO: shrink by copying?
-	if(span->elemsize != oldsize)
-		runtime·throw("span element size doesn't match stack size");
-	if((uintptr)oldstk != span->start << PageShift)
-		runtime·throw("stack not at start of span");
-
-	if(StackDebug)
-		runtime·printf("shrinking stack in place %p %X->%X\n", oldstk, oldsize, newsize);
-
-	// new stack guard for smaller stack
-	gp->stackguard = (uintptr)oldstk + newsize + StackGuard;
-	gp->stackguard0 = (uintptr)oldstk + newsize + StackGuard;
-	if(gp->stack0 == (uintptr)oldstk)
-		gp->stack0 = (uintptr)oldstk + newsize;
-	gp->stacksize -= oldsize - newsize;
-
-	// Free bottom half of the stack.
-	if(runtime·debug.efence || StackFromSystem) {
-		if(runtime·debug.efence || StackFaultOnFree)
-			runtime·SysFault(oldstk, newsize);
-		else
-			runtime·SysFree(oldstk, newsize, &mstats.stacks_sys);
-		return;
-	}
-	// First, we trick malloc into thinking
-	// we allocated the stack as two separate half-size allocs.  Then the
-	// free() call does the rest of the work for us.
-	runtime·MSpan_EnsureSwept(span);
-	runtime·MHeap_SplitSpan(&runtime·mheap, span);
-	runtime·free(oldstk);
-}
diff --git a/src/pkg/runtime/stack.h b/src/pkg/runtime/stack.h
deleted file mode 100644
index 18ab30b..0000000
--- a/src/pkg/runtime/stack.h
+++ /dev/null
@@ -1,113 +0,0 @@
-// Copyright 2011 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-/*
-Stack layout parameters.
-Included both by runtime (compiled via 6c) and linkers (compiled via gcc).
-
-The per-goroutine g->stackguard is set to point StackGuard bytes
-above the bottom of the stack.  Each function compares its stack
-pointer against g->stackguard to check for overflow.  To cut one
-instruction from the check sequence for functions with tiny frames,
-the stack is allowed to protrude StackSmall bytes below the stack
-guard.  Functions with large frames don't bother with the check and
-always call morestack.  The sequences are (for amd64, others are
-similar):
- 
-	guard = g->stackguard
-	frame = function's stack frame size
-	argsize = size of function arguments (call + return)
-
-	stack frame size <= StackSmall:
-		CMPQ guard, SP
-		JHI 3(PC)
-		MOVQ m->morearg, $(argsize << 32)
-		CALL morestack(SB)
-
-	stack frame size > StackSmall but < StackBig
-		LEAQ (frame-StackSmall)(SP), R0
-		CMPQ guard, R0
-		JHI 3(PC)
-		MOVQ m->morearg, $(argsize << 32)
-		CALL morestack(SB)
-
-	stack frame size >= StackBig:
-		MOVQ m->morearg, $((argsize << 32) | frame)
-		CALL morestack(SB)
-
-The bottom StackGuard - StackSmall bytes are important: there has
-to be enough room to execute functions that refuse to check for
-stack overflow, either because they need to be adjacent to the
-actual caller's frame (deferproc) or because they handle the imminent
-stack overflow (morestack).
-
-For example, deferproc might call malloc, which does one of the
-above checks (without allocating a full frame), which might trigger
-a call to morestack.  This sequence needs to fit in the bottom
-section of the stack.  On amd64, morestack's frame is 40 bytes, and
-deferproc's frame is 56 bytes.  That fits well within the
-StackGuard - StackSmall = 128 bytes at the bottom.  
-The linkers explore all possible call traces involving non-splitting
-functions to make sure that this limit cannot be violated.
- */
-
-enum {
-	// StackSystem is a number of additional bytes to add
-	// to each stack below the usual guard area for OS-specific
-	// purposes like signal handling. Used on Windows and on
-	// Plan 9 because they do not use a separate stack.
-#ifdef GOOS_windows
-	StackSystem = 512 * sizeof(uintptr),
-#else
-#ifdef GOOS_plan9
-	// The size of the note handler frame varies among architectures,
-	// but 512 bytes should be enough for every implementation.
-	StackSystem = 512,
-#else
-	StackSystem = 0,
-#endif	// Plan 9
-#endif	// Windows
-
-	// The amount of extra stack to allocate beyond the size
-	// needed for the single frame that triggered the split.
-	StackExtra = 2048,
-
-	// The minimum stack segment size to allocate.
-	// If the amount needed for the splitting frame + StackExtra
-	// is less than this number, the stack will have this size instead.
-	StackMin = 8192,
-	StackSystemRounded = StackSystem + (-StackSystem & (StackMin-1)),
-	FixedStack = StackMin + StackSystemRounded,
-
-	// Functions that need frames bigger than this use an extra
-	// instruction to do the stack split check, to avoid overflow
-	// in case SP - framesize wraps below zero.
-	// This value can be no bigger than the size of the unmapped
-	// space at zero.
-	StackBig = 4096,
-
-	// The stack guard is a pointer this many bytes above the
-	// bottom of the stack.
-	StackGuard = 256 + StackSystem,
-
-	// After a stack split check the SP is allowed to be this
-	// many bytes below the stack guard.  This saves an instruction
-	// in the checking sequence for tiny frames.
-	StackSmall = 128,
-
-	// The maximum number of bytes that a chain of NOSPLIT
-	// functions can use.
-	StackLimit = StackGuard - StackSystem - StackSmall,
-	
-	// The assumed size of the top-of-stack data block.
-	// The actual size can be smaller than this but cannot be larger.
-	// Checked in proc.c's runtime.malg.
-	StackTop = 88,
-};
-
-// Goroutine preemption request.
-// Stored into g->stackguard0 to cause split stack check failure.
-// Must be greater than any real sp.
-// 0xfffffade in hex.
-#define StackPreempt ((uint64)-1314)
diff --git a/src/pkg/runtime/stack_gen_test.go b/src/pkg/runtime/stack_gen_test.go
deleted file mode 100644
index 2810106..0000000
--- a/src/pkg/runtime/stack_gen_test.go
+++ /dev/null
@@ -1,1473 +0,0 @@
-// Copyright 2014 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package runtime_test
-
-import (
-	. "runtime"
-)
-
-var splitTests = []func() (uintptr, uintptr){
-	// Edit .+1,/^}/-1|seq 4 4 5000 | sed 's/.*/	stack&,/' | fmt
-	stack4, stack8, stack12, stack16, stack20, stack24, stack28,
-	stack32, stack36, stack40, stack44, stack48, stack52, stack56,
-	stack60, stack64, stack68, stack72, stack76, stack80, stack84,
-	stack88, stack92, stack96, stack100, stack104, stack108, stack112,
-	stack116, stack120, stack124, stack128, stack132, stack136,
-	stack140, stack144, stack148, stack152, stack156, stack160,
-	stack164, stack168, stack172, stack176, stack180, stack184,
-	stack188, stack192, stack196, stack200, stack204, stack208,
-	stack212, stack216, stack220, stack224, stack228, stack232,
-	stack236, stack240, stack244, stack248, stack252, stack256,
-	stack260, stack264, stack268, stack272, stack276, stack280,
-	stack284, stack288, stack292, stack296, stack300, stack304,
-	stack308, stack312, stack316, stack320, stack324, stack328,
-	stack332, stack336, stack340, stack344, stack348, stack352,
-	stack356, stack360, stack364, stack368, stack372, stack376,
-	stack380, stack384, stack388, stack392, stack396, stack400,
-	stack404, stack408, stack412, stack416, stack420, stack424,
-	stack428, stack432, stack436, stack440, stack444, stack448,
-	stack452, stack456, stack460, stack464, stack468, stack472,
-	stack476, stack480, stack484, stack488, stack492, stack496,
-	stack500, stack504, stack508, stack512, stack516, stack520,
-	stack524, stack528, stack532, stack536, stack540, stack544,
-	stack548, stack552, stack556, stack560, stack564, stack568,
-	stack572, stack576, stack580, stack584, stack588, stack592,
-	stack596, stack600, stack604, stack608, stack612, stack616,
-	stack620, stack624, stack628, stack632, stack636, stack640,
-	stack644, stack648, stack652, stack656, stack660, stack664,
-	stack668, stack672, stack676, stack680, stack684, stack688,
-	stack692, stack696, stack700, stack704, stack708, stack712,
-	stack716, stack720, stack724, stack728, stack732, stack736,
-	stack740, stack744, stack748, stack752, stack756, stack760,
-	stack764, stack768, stack772, stack776, stack780, stack784,
-	stack788, stack792, stack796, stack800, stack804, stack808,
-	stack812, stack816, stack820, stack824, stack828, stack832,
-	stack836, stack840, stack844, stack848, stack852, stack856,
-	stack860, stack864, stack868, stack872, stack876, stack880,
-	stack884, stack888, stack892, stack896, stack900, stack904,
-	stack908, stack912, stack916, stack920, stack924, stack928,
-	stack932, stack936, stack940, stack944, stack948, stack952,
-	stack956, stack960, stack964, stack968, stack972, stack976,
-	stack980, stack984, stack988, stack992, stack996, stack1000,
-	stack1004, stack1008, stack1012, stack1016, stack1020, stack1024,
-	stack1028, stack1032, stack1036, stack1040, stack1044, stack1048,
-	stack1052, stack1056, stack1060, stack1064, stack1068, stack1072,
-	stack1076, stack1080, stack1084, stack1088, stack1092, stack1096,
-	stack1100, stack1104, stack1108, stack1112, stack1116, stack1120,
-	stack1124, stack1128, stack1132, stack1136, stack1140, stack1144,
-	stack1148, stack1152, stack1156, stack1160, stack1164, stack1168,
-	stack1172, stack1176, stack1180, stack1184, stack1188, stack1192,
-	stack1196, stack1200, stack1204, stack1208, stack1212, stack1216,
-	stack1220, stack1224, stack1228, stack1232, stack1236, stack1240,
-	stack1244, stack1248, stack1252, stack1256, stack1260, stack1264,
-	stack1268, stack1272, stack1276, stack1280, stack1284, stack1288,
-	stack1292, stack1296, stack1300, stack1304, stack1308, stack1312,
-	stack1316, stack1320, stack1324, stack1328, stack1332, stack1336,
-	stack1340, stack1344, stack1348, stack1352, stack1356, stack1360,
-	stack1364, stack1368, stack1372, stack1376, stack1380, stack1384,
-	stack1388, stack1392, stack1396, stack1400, stack1404, stack1408,
-	stack1412, stack1416, stack1420, stack1424, stack1428, stack1432,
-	stack1436, stack1440, stack1444, stack1448, stack1452, stack1456,
-	stack1460, stack1464, stack1468, stack1472, stack1476, stack1480,
-	stack1484, stack1488, stack1492, stack1496, stack1500, stack1504,
-	stack1508, stack1512, stack1516, stack1520, stack1524, stack1528,
-	stack1532, stack1536, stack1540, stack1544, stack1548, stack1552,
-	stack1556, stack1560, stack1564, stack1568, stack1572, stack1576,
-	stack1580, stack1584, stack1588, stack1592, stack1596, stack1600,
-	stack1604, stack1608, stack1612, stack1616, stack1620, stack1624,
-	stack1628, stack1632, stack1636, stack1640, stack1644, stack1648,
-	stack1652, stack1656, stack1660, stack1664, stack1668, stack1672,
-	stack1676, stack1680, stack1684, stack1688, stack1692, stack1696,
-	stack1700, stack1704, stack1708, stack1712, stack1716, stack1720,
-	stack1724, stack1728, stack1732, stack1736, stack1740, stack1744,
-	stack1748, stack1752, stack1756, stack1760, stack1764, stack1768,
-	stack1772, stack1776, stack1780, stack1784, stack1788, stack1792,
-	stack1796, stack1800, stack1804, stack1808, stack1812, stack1816,
-	stack1820, stack1824, stack1828, stack1832, stack1836, stack1840,
-	stack1844, stack1848, stack1852, stack1856, stack1860, stack1864,
-	stack1868, stack1872, stack1876, stack1880, stack1884, stack1888,
-	stack1892, stack1896, stack1900, stack1904, stack1908, stack1912,
-	stack1916, stack1920, stack1924, stack1928, stack1932, stack1936,
-	stack1940, stack1944, stack1948, stack1952, stack1956, stack1960,
-	stack1964, stack1968, stack1972, stack1976, stack1980, stack1984,
-	stack1988, stack1992, stack1996, stack2000, stack2004, stack2008,
-	stack2012, stack2016, stack2020, stack2024, stack2028, stack2032,
-	stack2036, stack2040, stack2044, stack2048, stack2052, stack2056,
-	stack2060, stack2064, stack2068, stack2072, stack2076, stack2080,
-	stack2084, stack2088, stack2092, stack2096, stack2100, stack2104,
-	stack2108, stack2112, stack2116, stack2120, stack2124, stack2128,
-	stack2132, stack2136, stack2140, stack2144, stack2148, stack2152,
-	stack2156, stack2160, stack2164, stack2168, stack2172, stack2176,
-	stack2180, stack2184, stack2188, stack2192, stack2196, stack2200,
-	stack2204, stack2208, stack2212, stack2216, stack2220, stack2224,
-	stack2228, stack2232, stack2236, stack2240, stack2244, stack2248,
-	stack2252, stack2256, stack2260, stack2264, stack2268, stack2272,
-	stack2276, stack2280, stack2284, stack2288, stack2292, stack2296,
-	stack2300, stack2304, stack2308, stack2312, stack2316, stack2320,
-	stack2324, stack2328, stack2332, stack2336, stack2340, stack2344,
-	stack2348, stack2352, stack2356, stack2360, stack2364, stack2368,
-	stack2372, stack2376, stack2380, stack2384, stack2388, stack2392,
-	stack2396, stack2400, stack2404, stack2408, stack2412, stack2416,
-	stack2420, stack2424, stack2428, stack2432, stack2436, stack2440,
-	stack2444, stack2448, stack2452, stack2456, stack2460, stack2464,
-	stack2468, stack2472, stack2476, stack2480, stack2484, stack2488,
-	stack2492, stack2496, stack2500, stack2504, stack2508, stack2512,
-	stack2516, stack2520, stack2524, stack2528, stack2532, stack2536,
-	stack2540, stack2544, stack2548, stack2552, stack2556, stack2560,
-	stack2564, stack2568, stack2572, stack2576, stack2580, stack2584,
-	stack2588, stack2592, stack2596, stack2600, stack2604, stack2608,
-	stack2612, stack2616, stack2620, stack2624, stack2628, stack2632,
-	stack2636, stack2640, stack2644, stack2648, stack2652, stack2656,
-	stack2660, stack2664, stack2668, stack2672, stack2676, stack2680,
-	stack2684, stack2688, stack2692, stack2696, stack2700, stack2704,
-	stack2708, stack2712, stack2716, stack2720, stack2724, stack2728,
-	stack2732, stack2736, stack2740, stack2744, stack2748, stack2752,
-	stack2756, stack2760, stack2764, stack2768, stack2772, stack2776,
-	stack2780, stack2784, stack2788, stack2792, stack2796, stack2800,
-	stack2804, stack2808, stack2812, stack2816, stack2820, stack2824,
-	stack2828, stack2832, stack2836, stack2840, stack2844, stack2848,
-	stack2852, stack2856, stack2860, stack2864, stack2868, stack2872,
-	stack2876, stack2880, stack2884, stack2888, stack2892, stack2896,
-	stack2900, stack2904, stack2908, stack2912, stack2916, stack2920,
-	stack2924, stack2928, stack2932, stack2936, stack2940, stack2944,
-	stack2948, stack2952, stack2956, stack2960, stack2964, stack2968,
-	stack2972, stack2976, stack2980, stack2984, stack2988, stack2992,
-	stack2996, stack3000, stack3004, stack3008, stack3012, stack3016,
-	stack3020, stack3024, stack3028, stack3032, stack3036, stack3040,
-	stack3044, stack3048, stack3052, stack3056, stack3060, stack3064,
-	stack3068, stack3072, stack3076, stack3080, stack3084, stack3088,
-	stack3092, stack3096, stack3100, stack3104, stack3108, stack3112,
-	stack3116, stack3120, stack3124, stack3128, stack3132, stack3136,
-	stack3140, stack3144, stack3148, stack3152, stack3156, stack3160,
-	stack3164, stack3168, stack3172, stack3176, stack3180, stack3184,
-	stack3188, stack3192, stack3196, stack3200, stack3204, stack3208,
-	stack3212, stack3216, stack3220, stack3224, stack3228, stack3232,
-	stack3236, stack3240, stack3244, stack3248, stack3252, stack3256,
-	stack3260, stack3264, stack3268, stack3272, stack3276, stack3280,
-	stack3284, stack3288, stack3292, stack3296, stack3300, stack3304,
-	stack3308, stack3312, stack3316, stack3320, stack3324, stack3328,
-	stack3332, stack3336, stack3340, stack3344, stack3348, stack3352,
-	stack3356, stack3360, stack3364, stack3368, stack3372, stack3376,
-	stack3380, stack3384, stack3388, stack3392, stack3396, stack3400,
-	stack3404, stack3408, stack3412, stack3416, stack3420, stack3424,
-	stack3428, stack3432, stack3436, stack3440, stack3444, stack3448,
-	stack3452, stack3456, stack3460, stack3464, stack3468, stack3472,
-	stack3476, stack3480, stack3484, stack3488, stack3492, stack3496,
-	stack3500, stack3504, stack3508, stack3512, stack3516, stack3520,
-	stack3524, stack3528, stack3532, stack3536, stack3540, stack3544,
-	stack3548, stack3552, stack3556, stack3560, stack3564, stack3568,
-	stack3572, stack3576, stack3580, stack3584, stack3588, stack3592,
-	stack3596, stack3600, stack3604, stack3608, stack3612, stack3616,
-	stack3620, stack3624, stack3628, stack3632, stack3636, stack3640,
-	stack3644, stack3648, stack3652, stack3656, stack3660, stack3664,
-	stack3668, stack3672, stack3676, stack3680, stack3684, stack3688,
-	stack3692, stack3696, stack3700, stack3704, stack3708, stack3712,
-	stack3716, stack3720, stack3724, stack3728, stack3732, stack3736,
-	stack3740, stack3744, stack3748, stack3752, stack3756, stack3760,
-	stack3764, stack3768, stack3772, stack3776, stack3780, stack3784,
-	stack3788, stack3792, stack3796, stack3800, stack3804, stack3808,
-	stack3812, stack3816, stack3820, stack3824, stack3828, stack3832,
-	stack3836, stack3840, stack3844, stack3848, stack3852, stack3856,
-	stack3860, stack3864, stack3868, stack3872, stack3876, stack3880,
-	stack3884, stack3888, stack3892, stack3896, stack3900, stack3904,
-	stack3908, stack3912, stack3916, stack3920, stack3924, stack3928,
-	stack3932, stack3936, stack3940, stack3944, stack3948, stack3952,
-	stack3956, stack3960, stack3964, stack3968, stack3972, stack3976,
-	stack3980, stack3984, stack3988, stack3992, stack3996, stack4000,
-	stack4004, stack4008, stack4012, stack4016, stack4020, stack4024,
-	stack4028, stack4032, stack4036, stack4040, stack4044, stack4048,
-	stack4052, stack4056, stack4060, stack4064, stack4068, stack4072,
-	stack4076, stack4080, stack4084, stack4088, stack4092, stack4096,
-	stack4100, stack4104, stack4108, stack4112, stack4116, stack4120,
-	stack4124, stack4128, stack4132, stack4136, stack4140, stack4144,
-	stack4148, stack4152, stack4156, stack4160, stack4164, stack4168,
-	stack4172, stack4176, stack4180, stack4184, stack4188, stack4192,
-	stack4196, stack4200, stack4204, stack4208, stack4212, stack4216,
-	stack4220, stack4224, stack4228, stack4232, stack4236, stack4240,
-	stack4244, stack4248, stack4252, stack4256, stack4260, stack4264,
-	stack4268, stack4272, stack4276, stack4280, stack4284, stack4288,
-	stack4292, stack4296, stack4300, stack4304, stack4308, stack4312,
-	stack4316, stack4320, stack4324, stack4328, stack4332, stack4336,
-	stack4340, stack4344, stack4348, stack4352, stack4356, stack4360,
-	stack4364, stack4368, stack4372, stack4376, stack4380, stack4384,
-	stack4388, stack4392, stack4396, stack4400, stack4404, stack4408,
-	stack4412, stack4416, stack4420, stack4424, stack4428, stack4432,
-	stack4436, stack4440, stack4444, stack4448, stack4452, stack4456,
-	stack4460, stack4464, stack4468, stack4472, stack4476, stack4480,
-	stack4484, stack4488, stack4492, stack4496, stack4500, stack4504,
-	stack4508, stack4512, stack4516, stack4520, stack4524, stack4528,
-	stack4532, stack4536, stack4540, stack4544, stack4548, stack4552,
-	stack4556, stack4560, stack4564, stack4568, stack4572, stack4576,
-	stack4580, stack4584, stack4588, stack4592, stack4596, stack4600,
-	stack4604, stack4608, stack4612, stack4616, stack4620, stack4624,
-	stack4628, stack4632, stack4636, stack4640, stack4644, stack4648,
-	stack4652, stack4656, stack4660, stack4664, stack4668, stack4672,
-	stack4676, stack4680, stack4684, stack4688, stack4692, stack4696,
-	stack4700, stack4704, stack4708, stack4712, stack4716, stack4720,
-	stack4724, stack4728, stack4732, stack4736, stack4740, stack4744,
-	stack4748, stack4752, stack4756, stack4760, stack4764, stack4768,
-	stack4772, stack4776, stack4780, stack4784, stack4788, stack4792,
-	stack4796, stack4800, stack4804, stack4808, stack4812, stack4816,
-	stack4820, stack4824, stack4828, stack4832, stack4836, stack4840,
-	stack4844, stack4848, stack4852, stack4856, stack4860, stack4864,
-	stack4868, stack4872, stack4876, stack4880, stack4884, stack4888,
-	stack4892, stack4896, stack4900, stack4904, stack4908, stack4912,
-	stack4916, stack4920, stack4924, stack4928, stack4932, stack4936,
-	stack4940, stack4944, stack4948, stack4952, stack4956, stack4960,
-	stack4964, stack4968, stack4972, stack4976, stack4980, stack4984,
-	stack4988, stack4992, stack4996, stack5000,
-}
-
-// Edit .+1,$ | seq 4 4 5000 | sed 's/.*/func stack&()(uintptr, uintptr) { var buf [&]byte; use(buf[:]); return Stackguard() }/'
-func stack4() (uintptr, uintptr)    { var buf [4]byte; use(buf[:]); return Stackguard() }
-func stack8() (uintptr, uintptr)    { var buf [8]byte; use(buf[:]); return Stackguard() }
-func stack12() (uintptr, uintptr)   { var buf [12]byte; use(buf[:]); return Stackguard() }
-func stack16() (uintptr, uintptr)   { var buf [16]byte; use(buf[:]); return Stackguard() }
-func stack20() (uintptr, uintptr)   { var buf [20]byte; use(buf[:]); return Stackguard() }
-func stack24() (uintptr, uintptr)   { var buf [24]byte; use(buf[:]); return Stackguard() }
-func stack28() (uintptr, uintptr)   { var buf [28]byte; use(buf[:]); return Stackguard() }
-func stack32() (uintptr, uintptr)   { var buf [32]byte; use(buf[:]); return Stackguard() }
-func stack36() (uintptr, uintptr)   { var buf [36]byte; use(buf[:]); return Stackguard() }
-func stack40() (uintptr, uintptr)   { var buf [40]byte; use(buf[:]); return Stackguard() }
-func stack44() (uintptr, uintptr)   { var buf [44]byte; use(buf[:]); return Stackguard() }
-func stack48() (uintptr, uintptr)   { var buf [48]byte; use(buf[:]); return Stackguard() }
-func stack52() (uintptr, uintptr)   { var buf [52]byte; use(buf[:]); return Stackguard() }
-func stack56() (uintptr, uintptr)   { var buf [56]byte; use(buf[:]); return Stackguard() }
-func stack60() (uintptr, uintptr)   { var buf [60]byte; use(buf[:]); return Stackguard() }
-func stack64() (uintptr, uintptr)   { var buf [64]byte; use(buf[:]); return Stackguard() }
-func stack68() (uintptr, uintptr)   { var buf [68]byte; use(buf[:]); return Stackguard() }
-func stack72() (uintptr, uintptr)   { var buf [72]byte; use(buf[:]); return Stackguard() }
-func stack76() (uintptr, uintptr)   { var buf [76]byte; use(buf[:]); return Stackguard() }
-func stack80() (uintptr, uintptr)   { var buf [80]byte; use(buf[:]); return Stackguard() }
-func stack84() (uintptr, uintptr)   { var buf [84]byte; use(buf[:]); return Stackguard() }
-func stack88() (uintptr, uintptr)   { var buf [88]byte; use(buf[:]); return Stackguard() }
-func stack92() (uintptr, uintptr)   { var buf [92]byte; use(buf[:]); return Stackguard() }
-func stack96() (uintptr, uintptr)   { var buf [96]byte; use(buf[:]); return Stackguard() }
-func stack100() (uintptr, uintptr)  { var buf [100]byte; use(buf[:]); return Stackguard() }
-func stack104() (uintptr, uintptr)  { var buf [104]byte; use(buf[:]); return Stackguard() }
-func stack108() (uintptr, uintptr)  { var buf [108]byte; use(buf[:]); return Stackguard() }
-func stack112() (uintptr, uintptr)  { var buf [112]byte; use(buf[:]); return Stackguard() }
-func stack116() (uintptr, uintptr)  { var buf [116]byte; use(buf[:]); return Stackguard() }
-func stack120() (uintptr, uintptr)  { var buf [120]byte; use(buf[:]); return Stackguard() }
-func stack124() (uintptr, uintptr)  { var buf [124]byte; use(buf[:]); return Stackguard() }
-func stack128() (uintptr, uintptr)  { var buf [128]byte; use(buf[:]); return Stackguard() }
-func stack132() (uintptr, uintptr)  { var buf [132]byte; use(buf[:]); return Stackguard() }
-func stack136() (uintptr, uintptr)  { var buf [136]byte; use(buf[:]); return Stackguard() }
-func stack140() (uintptr, uintptr)  { var buf [140]byte; use(buf[:]); return Stackguard() }
-func stack144() (uintptr, uintptr)  { var buf [144]byte; use(buf[:]); return Stackguard() }
-func stack148() (uintptr, uintptr)  { var buf [148]byte; use(buf[:]); return Stackguard() }
-func stack152() (uintptr, uintptr)  { var buf [152]byte; use(buf[:]); return Stackguard() }
-func stack156() (uintptr, uintptr)  { var buf [156]byte; use(buf[:]); return Stackguard() }
-func stack160() (uintptr, uintptr)  { var buf [160]byte; use(buf[:]); return Stackguard() }
-func stack164() (uintptr, uintptr)  { var buf [164]byte; use(buf[:]); return Stackguard() }
-func stack168() (uintptr, uintptr)  { var buf [168]byte; use(buf[:]); return Stackguard() }
-func stack172() (uintptr, uintptr)  { var buf [172]byte; use(buf[:]); return Stackguard() }
-func stack176() (uintptr, uintptr)  { var buf [176]byte; use(buf[:]); return Stackguard() }
-func stack180() (uintptr, uintptr)  { var buf [180]byte; use(buf[:]); return Stackguard() }
-func stack184() (uintptr, uintptr)  { var buf [184]byte; use(buf[:]); return Stackguard() }
-func stack188() (uintptr, uintptr)  { var buf [188]byte; use(buf[:]); return Stackguard() }
-func stack192() (uintptr, uintptr)  { var buf [192]byte; use(buf[:]); return Stackguard() }
-func stack196() (uintptr, uintptr)  { var buf [196]byte; use(buf[:]); return Stackguard() }
-func stack200() (uintptr, uintptr)  { var buf [200]byte; use(buf[:]); return Stackguard() }
-func stack204() (uintptr, uintptr)  { var buf [204]byte; use(buf[:]); return Stackguard() }
-func stack208() (uintptr, uintptr)  { var buf [208]byte; use(buf[:]); return Stackguard() }
-func stack212() (uintptr, uintptr)  { var buf [212]byte; use(buf[:]); return Stackguard() }
-func stack216() (uintptr, uintptr)  { var buf [216]byte; use(buf[:]); return Stackguard() }
-func stack220() (uintptr, uintptr)  { var buf [220]byte; use(buf[:]); return Stackguard() }
-func stack224() (uintptr, uintptr)  { var buf [224]byte; use(buf[:]); return Stackguard() }
-func stack228() (uintptr, uintptr)  { var buf [228]byte; use(buf[:]); return Stackguard() }
-func stack232() (uintptr, uintptr)  { var buf [232]byte; use(buf[:]); return Stackguard() }
-func stack236() (uintptr, uintptr)  { var buf [236]byte; use(buf[:]); return Stackguard() }
-func stack240() (uintptr, uintptr)  { var buf [240]byte; use(buf[:]); return Stackguard() }
-func stack244() (uintptr, uintptr)  { var buf [244]byte; use(buf[:]); return Stackguard() }
-func stack248() (uintptr, uintptr)  { var buf [248]byte; use(buf[:]); return Stackguard() }
-func stack252() (uintptr, uintptr)  { var buf [252]byte; use(buf[:]); return Stackguard() }
-func stack256() (uintptr, uintptr)  { var buf [256]byte; use(buf[:]); return Stackguard() }
-func stack260() (uintptr, uintptr)  { var buf [260]byte; use(buf[:]); return Stackguard() }
-func stack264() (uintptr, uintptr)  { var buf [264]byte; use(buf[:]); return Stackguard() }
-func stack268() (uintptr, uintptr)  { var buf [268]byte; use(buf[:]); return Stackguard() }
-func stack272() (uintptr, uintptr)  { var buf [272]byte; use(buf[:]); return Stackguard() }
-func stack276() (uintptr, uintptr)  { var buf [276]byte; use(buf[:]); return Stackguard() }
-func stack280() (uintptr, uintptr)  { var buf [280]byte; use(buf[:]); return Stackguard() }
-func stack284() (uintptr, uintptr)  { var buf [284]byte; use(buf[:]); return Stackguard() }
-func stack288() (uintptr, uintptr)  { var buf [288]byte; use(buf[:]); return Stackguard() }
-func stack292() (uintptr, uintptr)  { var buf [292]byte; use(buf[:]); return Stackguard() }
-func stack296() (uintptr, uintptr)  { var buf [296]byte; use(buf[:]); return Stackguard() }
-func stack300() (uintptr, uintptr)  { var buf [300]byte; use(buf[:]); return Stackguard() }
-func stack304() (uintptr, uintptr)  { var buf [304]byte; use(buf[:]); return Stackguard() }
-func stack308() (uintptr, uintptr)  { var buf [308]byte; use(buf[:]); return Stackguard() }
-func stack312() (uintptr, uintptr)  { var buf [312]byte; use(buf[:]); return Stackguard() }
-func stack316() (uintptr, uintptr)  { var buf [316]byte; use(buf[:]); return Stackguard() }
-func stack320() (uintptr, uintptr)  { var buf [320]byte; use(buf[:]); return Stackguard() }
-func stack324() (uintptr, uintptr)  { var buf [324]byte; use(buf[:]); return Stackguard() }
-func stack328() (uintptr, uintptr)  { var buf [328]byte; use(buf[:]); return Stackguard() }
-func stack332() (uintptr, uintptr)  { var buf [332]byte; use(buf[:]); return Stackguard() }
-func stack336() (uintptr, uintptr)  { var buf [336]byte; use(buf[:]); return Stackguard() }
-func stack340() (uintptr, uintptr)  { var buf [340]byte; use(buf[:]); return Stackguard() }
-func stack344() (uintptr, uintptr)  { var buf [344]byte; use(buf[:]); return Stackguard() }
-func stack348() (uintptr, uintptr)  { var buf [348]byte; use(buf[:]); return Stackguard() }
-func stack352() (uintptr, uintptr)  { var buf [352]byte; use(buf[:]); return Stackguard() }
-func stack356() (uintptr, uintptr)  { var buf [356]byte; use(buf[:]); return Stackguard() }
-func stack360() (uintptr, uintptr)  { var buf [360]byte; use(buf[:]); return Stackguard() }
-func stack364() (uintptr, uintptr)  { var buf [364]byte; use(buf[:]); return Stackguard() }
-func stack368() (uintptr, uintptr)  { var buf [368]byte; use(buf[:]); return Stackguard() }
-func stack372() (uintptr, uintptr)  { var buf [372]byte; use(buf[:]); return Stackguard() }
-func stack376() (uintptr, uintptr)  { var buf [376]byte; use(buf[:]); return Stackguard() }
-func stack380() (uintptr, uintptr)  { var buf [380]byte; use(buf[:]); return Stackguard() }
-func stack384() (uintptr, uintptr)  { var buf [384]byte; use(buf[:]); return Stackguard() }
-func stack388() (uintptr, uintptr)  { var buf [388]byte; use(buf[:]); return Stackguard() }
-func stack392() (uintptr, uintptr)  { var buf [392]byte; use(buf[:]); return Stackguard() }
-func stack396() (uintptr, uintptr)  { var buf [396]byte; use(buf[:]); return Stackguard() }
-func stack400() (uintptr, uintptr)  { var buf [400]byte; use(buf[:]); return Stackguard() }
-func stack404() (uintptr, uintptr)  { var buf [404]byte; use(buf[:]); return Stackguard() }
-func stack408() (uintptr, uintptr)  { var buf [408]byte; use(buf[:]); return Stackguard() }
-func stack412() (uintptr, uintptr)  { var buf [412]byte; use(buf[:]); return Stackguard() }
-func stack416() (uintptr, uintptr)  { var buf [416]byte; use(buf[:]); return Stackguard() }
-func stack420() (uintptr, uintptr)  { var buf [420]byte; use(buf[:]); return Stackguard() }
-func stack424() (uintptr, uintptr)  { var buf [424]byte; use(buf[:]); return Stackguard() }
-func stack428() (uintptr, uintptr)  { var buf [428]byte; use(buf[:]); return Stackguard() }
-func stack432() (uintptr, uintptr)  { var buf [432]byte; use(buf[:]); return Stackguard() }
-func stack436() (uintptr, uintptr)  { var buf [436]byte; use(buf[:]); return Stackguard() }
-func stack440() (uintptr, uintptr)  { var buf [440]byte; use(buf[:]); return Stackguard() }
-func stack444() (uintptr, uintptr)  { var buf [444]byte; use(buf[:]); return Stackguard() }
-func stack448() (uintptr, uintptr)  { var buf [448]byte; use(buf[:]); return Stackguard() }
-func stack452() (uintptr, uintptr)  { var buf [452]byte; use(buf[:]); return Stackguard() }
-func stack456() (uintptr, uintptr)  { var buf [456]byte; use(buf[:]); return Stackguard() }
-func stack460() (uintptr, uintptr)  { var buf [460]byte; use(buf[:]); return Stackguard() }
-func stack464() (uintptr, uintptr)  { var buf [464]byte; use(buf[:]); return Stackguard() }
-func stack468() (uintptr, uintptr)  { var buf [468]byte; use(buf[:]); return Stackguard() }
-func stack472() (uintptr, uintptr)  { var buf [472]byte; use(buf[:]); return Stackguard() }
-func stack476() (uintptr, uintptr)  { var buf [476]byte; use(buf[:]); return Stackguard() }
-func stack480() (uintptr, uintptr)  { var buf [480]byte; use(buf[:]); return Stackguard() }
-func stack484() (uintptr, uintptr)  { var buf [484]byte; use(buf[:]); return Stackguard() }
-func stack488() (uintptr, uintptr)  { var buf [488]byte; use(buf[:]); return Stackguard() }
-func stack492() (uintptr, uintptr)  { var buf [492]byte; use(buf[:]); return Stackguard() }
-func stack496() (uintptr, uintptr)  { var buf [496]byte; use(buf[:]); return Stackguard() }
-func stack500() (uintptr, uintptr)  { var buf [500]byte; use(buf[:]); return Stackguard() }
-func stack504() (uintptr, uintptr)  { var buf [504]byte; use(buf[:]); return Stackguard() }
-func stack508() (uintptr, uintptr)  { var buf [508]byte; use(buf[:]); return Stackguard() }
-func stack512() (uintptr, uintptr)  { var buf [512]byte; use(buf[:]); return Stackguard() }
-func stack516() (uintptr, uintptr)  { var buf [516]byte; use(buf[:]); return Stackguard() }
-func stack520() (uintptr, uintptr)  { var buf [520]byte; use(buf[:]); return Stackguard() }
-func stack524() (uintptr, uintptr)  { var buf [524]byte; use(buf[:]); return Stackguard() }
-func stack528() (uintptr, uintptr)  { var buf [528]byte; use(buf[:]); return Stackguard() }
-func stack532() (uintptr, uintptr)  { var buf [532]byte; use(buf[:]); return Stackguard() }
-func stack536() (uintptr, uintptr)  { var buf [536]byte; use(buf[:]); return Stackguard() }
-func stack540() (uintptr, uintptr)  { var buf [540]byte; use(buf[:]); return Stackguard() }
-func stack544() (uintptr, uintptr)  { var buf [544]byte; use(buf[:]); return Stackguard() }
-func stack548() (uintptr, uintptr)  { var buf [548]byte; use(buf[:]); return Stackguard() }
-func stack552() (uintptr, uintptr)  { var buf [552]byte; use(buf[:]); return Stackguard() }
-func stack556() (uintptr, uintptr)  { var buf [556]byte; use(buf[:]); return Stackguard() }
-func stack560() (uintptr, uintptr)  { var buf [560]byte; use(buf[:]); return Stackguard() }
-func stack564() (uintptr, uintptr)  { var buf [564]byte; use(buf[:]); return Stackguard() }
-func stack568() (uintptr, uintptr)  { var buf [568]byte; use(buf[:]); return Stackguard() }
-func stack572() (uintptr, uintptr)  { var buf [572]byte; use(buf[:]); return Stackguard() }
-func stack576() (uintptr, uintptr)  { var buf [576]byte; use(buf[:]); return Stackguard() }
-func stack580() (uintptr, uintptr)  { var buf [580]byte; use(buf[:]); return Stackguard() }
-func stack584() (uintptr, uintptr)  { var buf [584]byte; use(buf[:]); return Stackguard() }
-func stack588() (uintptr, uintptr)  { var buf [588]byte; use(buf[:]); return Stackguard() }
-func stack592() (uintptr, uintptr)  { var buf [592]byte; use(buf[:]); return Stackguard() }
-func stack596() (uintptr, uintptr)  { var buf [596]byte; use(buf[:]); return Stackguard() }
-func stack600() (uintptr, uintptr)  { var buf [600]byte; use(buf[:]); return Stackguard() }
-func stack604() (uintptr, uintptr)  { var buf [604]byte; use(buf[:]); return Stackguard() }
-func stack608() (uintptr, uintptr)  { var buf [608]byte; use(buf[:]); return Stackguard() }
-func stack612() (uintptr, uintptr)  { var buf [612]byte; use(buf[:]); return Stackguard() }
-func stack616() (uintptr, uintptr)  { var buf [616]byte; use(buf[:]); return Stackguard() }
-func stack620() (uintptr, uintptr)  { var buf [620]byte; use(buf[:]); return Stackguard() }
-func stack624() (uintptr, uintptr)  { var buf [624]byte; use(buf[:]); return Stackguard() }
-func stack628() (uintptr, uintptr)  { var buf [628]byte; use(buf[:]); return Stackguard() }
-func stack632() (uintptr, uintptr)  { var buf [632]byte; use(buf[:]); return Stackguard() }
-func stack636() (uintptr, uintptr)  { var buf [636]byte; use(buf[:]); return Stackguard() }
-func stack640() (uintptr, uintptr)  { var buf [640]byte; use(buf[:]); return Stackguard() }
-func stack644() (uintptr, uintptr)  { var buf [644]byte; use(buf[:]); return Stackguard() }
-func stack648() (uintptr, uintptr)  { var buf [648]byte; use(buf[:]); return Stackguard() }
-func stack652() (uintptr, uintptr)  { var buf [652]byte; use(buf[:]); return Stackguard() }
-func stack656() (uintptr, uintptr)  { var buf [656]byte; use(buf[:]); return Stackguard() }
-func stack660() (uintptr, uintptr)  { var buf [660]byte; use(buf[:]); return Stackguard() }
-func stack664() (uintptr, uintptr)  { var buf [664]byte; use(buf[:]); return Stackguard() }
-func stack668() (uintptr, uintptr)  { var buf [668]byte; use(buf[:]); return Stackguard() }
-func stack672() (uintptr, uintptr)  { var buf [672]byte; use(buf[:]); return Stackguard() }
-func stack676() (uintptr, uintptr)  { var buf [676]byte; use(buf[:]); return Stackguard() }
-func stack680() (uintptr, uintptr)  { var buf [680]byte; use(buf[:]); return Stackguard() }
-func stack684() (uintptr, uintptr)  { var buf [684]byte; use(buf[:]); return Stackguard() }
-func stack688() (uintptr, uintptr)  { var buf [688]byte; use(buf[:]); return Stackguard() }
-func stack692() (uintptr, uintptr)  { var buf [692]byte; use(buf[:]); return Stackguard() }
-func stack696() (uintptr, uintptr)  { var buf [696]byte; use(buf[:]); return Stackguard() }
-func stack700() (uintptr, uintptr)  { var buf [700]byte; use(buf[:]); return Stackguard() }
-func stack704() (uintptr, uintptr)  { var buf [704]byte; use(buf[:]); return Stackguard() }
-func stack708() (uintptr, uintptr)  { var buf [708]byte; use(buf[:]); return Stackguard() }
-func stack712() (uintptr, uintptr)  { var buf [712]byte; use(buf[:]); return Stackguard() }
-func stack716() (uintptr, uintptr)  { var buf [716]byte; use(buf[:]); return Stackguard() }
-func stack720() (uintptr, uintptr)  { var buf [720]byte; use(buf[:]); return Stackguard() }
-func stack724() (uintptr, uintptr)  { var buf [724]byte; use(buf[:]); return Stackguard() }
-func stack728() (uintptr, uintptr)  { var buf [728]byte; use(buf[:]); return Stackguard() }
-func stack732() (uintptr, uintptr)  { var buf [732]byte; use(buf[:]); return Stackguard() }
-func stack736() (uintptr, uintptr)  { var buf [736]byte; use(buf[:]); return Stackguard() }
-func stack740() (uintptr, uintptr)  { var buf [740]byte; use(buf[:]); return Stackguard() }
-func stack744() (uintptr, uintptr)  { var buf [744]byte; use(buf[:]); return Stackguard() }
-func stack748() (uintptr, uintptr)  { var buf [748]byte; use(buf[:]); return Stackguard() }
-func stack752() (uintptr, uintptr)  { var buf [752]byte; use(buf[:]); return Stackguard() }
-func stack756() (uintptr, uintptr)  { var buf [756]byte; use(buf[:]); return Stackguard() }
-func stack760() (uintptr, uintptr)  { var buf [760]byte; use(buf[:]); return Stackguard() }
-func stack764() (uintptr, uintptr)  { var buf [764]byte; use(buf[:]); return Stackguard() }
-func stack768() (uintptr, uintptr)  { var buf [768]byte; use(buf[:]); return Stackguard() }
-func stack772() (uintptr, uintptr)  { var buf [772]byte; use(buf[:]); return Stackguard() }
-func stack776() (uintptr, uintptr)  { var buf [776]byte; use(buf[:]); return Stackguard() }
-func stack780() (uintptr, uintptr)  { var buf [780]byte; use(buf[:]); return Stackguard() }
-func stack784() (uintptr, uintptr)  { var buf [784]byte; use(buf[:]); return Stackguard() }
-func stack788() (uintptr, uintptr)  { var buf [788]byte; use(buf[:]); return Stackguard() }
-func stack792() (uintptr, uintptr)  { var buf [792]byte; use(buf[:]); return Stackguard() }
-func stack796() (uintptr, uintptr)  { var buf [796]byte; use(buf[:]); return Stackguard() }
-func stack800() (uintptr, uintptr)  { var buf [800]byte; use(buf[:]); return Stackguard() }
-func stack804() (uintptr, uintptr)  { var buf [804]byte; use(buf[:]); return Stackguard() }
-func stack808() (uintptr, uintptr)  { var buf [808]byte; use(buf[:]); return Stackguard() }
-func stack812() (uintptr, uintptr)  { var buf [812]byte; use(buf[:]); return Stackguard() }
-func stack816() (uintptr, uintptr)  { var buf [816]byte; use(buf[:]); return Stackguard() }
-func stack820() (uintptr, uintptr)  { var buf [820]byte; use(buf[:]); return Stackguard() }
-func stack824() (uintptr, uintptr)  { var buf [824]byte; use(buf[:]); return Stackguard() }
-func stack828() (uintptr, uintptr)  { var buf [828]byte; use(buf[:]); return Stackguard() }
-func stack832() (uintptr, uintptr)  { var buf [832]byte; use(buf[:]); return Stackguard() }
-func stack836() (uintptr, uintptr)  { var buf [836]byte; use(buf[:]); return Stackguard() }
-func stack840() (uintptr, uintptr)  { var buf [840]byte; use(buf[:]); return Stackguard() }
-func stack844() (uintptr, uintptr)  { var buf [844]byte; use(buf[:]); return Stackguard() }
-func stack848() (uintptr, uintptr)  { var buf [848]byte; use(buf[:]); return Stackguard() }
-func stack852() (uintptr, uintptr)  { var buf [852]byte; use(buf[:]); return Stackguard() }
-func stack856() (uintptr, uintptr)  { var buf [856]byte; use(buf[:]); return Stackguard() }
-func stack860() (uintptr, uintptr)  { var buf [860]byte; use(buf[:]); return Stackguard() }
-func stack864() (uintptr, uintptr)  { var buf [864]byte; use(buf[:]); return Stackguard() }
-func stack868() (uintptr, uintptr)  { var buf [868]byte; use(buf[:]); return Stackguard() }
-func stack872() (uintptr, uintptr)  { var buf [872]byte; use(buf[:]); return Stackguard() }
-func stack876() (uintptr, uintptr)  { var buf [876]byte; use(buf[:]); return Stackguard() }
-func stack880() (uintptr, uintptr)  { var buf [880]byte; use(buf[:]); return Stackguard() }
-func stack884() (uintptr, uintptr)  { var buf [884]byte; use(buf[:]); return Stackguard() }
-func stack888() (uintptr, uintptr)  { var buf [888]byte; use(buf[:]); return Stackguard() }
-func stack892() (uintptr, uintptr)  { var buf [892]byte; use(buf[:]); return Stackguard() }
-func stack896() (uintptr, uintptr)  { var buf [896]byte; use(buf[:]); return Stackguard() }
-func stack900() (uintptr, uintptr)  { var buf [900]byte; use(buf[:]); return Stackguard() }
-func stack904() (uintptr, uintptr)  { var buf [904]byte; use(buf[:]); return Stackguard() }
-func stack908() (uintptr, uintptr)  { var buf [908]byte; use(buf[:]); return Stackguard() }
-func stack912() (uintptr, uintptr)  { var buf [912]byte; use(buf[:]); return Stackguard() }
-func stack916() (uintptr, uintptr)  { var buf [916]byte; use(buf[:]); return Stackguard() }
-func stack920() (uintptr, uintptr)  { var buf [920]byte; use(buf[:]); return Stackguard() }
-func stack924() (uintptr, uintptr)  { var buf [924]byte; use(buf[:]); return Stackguard() }
-func stack928() (uintptr, uintptr)  { var buf [928]byte; use(buf[:]); return Stackguard() }
-func stack932() (uintptr, uintptr)  { var buf [932]byte; use(buf[:]); return Stackguard() }
-func stack936() (uintptr, uintptr)  { var buf [936]byte; use(buf[:]); return Stackguard() }
-func stack940() (uintptr, uintptr)  { var buf [940]byte; use(buf[:]); return Stackguard() }
-func stack944() (uintptr, uintptr)  { var buf [944]byte; use(buf[:]); return Stackguard() }
-func stack948() (uintptr, uintptr)  { var buf [948]byte; use(buf[:]); return Stackguard() }
-func stack952() (uintptr, uintptr)  { var buf [952]byte; use(buf[:]); return Stackguard() }
-func stack956() (uintptr, uintptr)  { var buf [956]byte; use(buf[:]); return Stackguard() }
-func stack960() (uintptr, uintptr)  { var buf [960]byte; use(buf[:]); return Stackguard() }
-func stack964() (uintptr, uintptr)  { var buf [964]byte; use(buf[:]); return Stackguard() }
-func stack968() (uintptr, uintptr)  { var buf [968]byte; use(buf[:]); return Stackguard() }
-func stack972() (uintptr, uintptr)  { var buf [972]byte; use(buf[:]); return Stackguard() }
-func stack976() (uintptr, uintptr)  { var buf [976]byte; use(buf[:]); return Stackguard() }
-func stack980() (uintptr, uintptr)  { var buf [980]byte; use(buf[:]); return Stackguard() }
-func stack984() (uintptr, uintptr)  { var buf [984]byte; use(buf[:]); return Stackguard() }
-func stack988() (uintptr, uintptr)  { var buf [988]byte; use(buf[:]); return Stackguard() }
-func stack992() (uintptr, uintptr)  { var buf [992]byte; use(buf[:]); return Stackguard() }
-func stack996() (uintptr, uintptr)  { var buf [996]byte; use(buf[:]); return Stackguard() }
-func stack1000() (uintptr, uintptr) { var buf [1000]byte; use(buf[:]); return Stackguard() }
-func stack1004() (uintptr, uintptr) { var buf [1004]byte; use(buf[:]); return Stackguard() }
-func stack1008() (uintptr, uintptr) { var buf [1008]byte; use(buf[:]); return Stackguard() }
-func stack1012() (uintptr, uintptr) { var buf [1012]byte; use(buf[:]); return Stackguard() }
-func stack1016() (uintptr, uintptr) { var buf [1016]byte; use(buf[:]); return Stackguard() }
-func stack1020() (uintptr, uintptr) { var buf [1020]byte; use(buf[:]); return Stackguard() }
-func stack1024() (uintptr, uintptr) { var buf [1024]byte; use(buf[:]); return Stackguard() }
-func stack1028() (uintptr, uintptr) { var buf [1028]byte; use(buf[:]); return Stackguard() }
-func stack1032() (uintptr, uintptr) { var buf [1032]byte; use(buf[:]); return Stackguard() }
-func stack1036() (uintptr, uintptr) { var buf [1036]byte; use(buf[:]); return Stackguard() }
-func stack1040() (uintptr, uintptr) { var buf [1040]byte; use(buf[:]); return Stackguard() }
-func stack1044() (uintptr, uintptr) { var buf [1044]byte; use(buf[:]); return Stackguard() }
-func stack1048() (uintptr, uintptr) { var buf [1048]byte; use(buf[:]); return Stackguard() }
-func stack1052() (uintptr, uintptr) { var buf [1052]byte; use(buf[:]); return Stackguard() }
-func stack1056() (uintptr, uintptr) { var buf [1056]byte; use(buf[:]); return Stackguard() }
-func stack1060() (uintptr, uintptr) { var buf [1060]byte; use(buf[:]); return Stackguard() }
-func stack1064() (uintptr, uintptr) { var buf [1064]byte; use(buf[:]); return Stackguard() }
-func stack1068() (uintptr, uintptr) { var buf [1068]byte; use(buf[:]); return Stackguard() }
-func stack1072() (uintptr, uintptr) { var buf [1072]byte; use(buf[:]); return Stackguard() }
-func stack1076() (uintptr, uintptr) { var buf [1076]byte; use(buf[:]); return Stackguard() }
-func stack1080() (uintptr, uintptr) { var buf [1080]byte; use(buf[:]); return Stackguard() }
-func stack1084() (uintptr, uintptr) { var buf [1084]byte; use(buf[:]); return Stackguard() }
-func stack1088() (uintptr, uintptr) { var buf [1088]byte; use(buf[:]); return Stackguard() }
-func stack1092() (uintptr, uintptr) { var buf [1092]byte; use(buf[:]); return Stackguard() }
-func stack1096() (uintptr, uintptr) { var buf [1096]byte; use(buf[:]); return Stackguard() }
-func stack1100() (uintptr, uintptr) { var buf [1100]byte; use(buf[:]); return Stackguard() }
-func stack1104() (uintptr, uintptr) { var buf [1104]byte; use(buf[:]); return Stackguard() }
-func stack1108() (uintptr, uintptr) { var buf [1108]byte; use(buf[:]); return Stackguard() }
-func stack1112() (uintptr, uintptr) { var buf [1112]byte; use(buf[:]); return Stackguard() }
-func stack1116() (uintptr, uintptr) { var buf [1116]byte; use(buf[:]); return Stackguard() }
-func stack1120() (uintptr, uintptr) { var buf [1120]byte; use(buf[:]); return Stackguard() }
-func stack1124() (uintptr, uintptr) { var buf [1124]byte; use(buf[:]); return Stackguard() }
-func stack1128() (uintptr, uintptr) { var buf [1128]byte; use(buf[:]); return Stackguard() }
-func stack1132() (uintptr, uintptr) { var buf [1132]byte; use(buf[:]); return Stackguard() }
-func stack1136() (uintptr, uintptr) { var buf [1136]byte; use(buf[:]); return Stackguard() }
-func stack1140() (uintptr, uintptr) { var buf [1140]byte; use(buf[:]); return Stackguard() }
-func stack1144() (uintptr, uintptr) { var buf [1144]byte; use(buf[:]); return Stackguard() }
-func stack1148() (uintptr, uintptr) { var buf [1148]byte; use(buf[:]); return Stackguard() }
-func stack1152() (uintptr, uintptr) { var buf [1152]byte; use(buf[:]); return Stackguard() }
-func stack1156() (uintptr, uintptr) { var buf [1156]byte; use(buf[:]); return Stackguard() }
-func stack1160() (uintptr, uintptr) { var buf [1160]byte; use(buf[:]); return Stackguard() }
-func stack1164() (uintptr, uintptr) { var buf [1164]byte; use(buf[:]); return Stackguard() }
-func stack1168() (uintptr, uintptr) { var buf [1168]byte; use(buf[:]); return Stackguard() }
-func stack1172() (uintptr, uintptr) { var buf [1172]byte; use(buf[:]); return Stackguard() }
-func stack1176() (uintptr, uintptr) { var buf [1176]byte; use(buf[:]); return Stackguard() }
-func stack1180() (uintptr, uintptr) { var buf [1180]byte; use(buf[:]); return Stackguard() }
-func stack1184() (uintptr, uintptr) { var buf [1184]byte; use(buf[:]); return Stackguard() }
-func stack1188() (uintptr, uintptr) { var buf [1188]byte; use(buf[:]); return Stackguard() }
-func stack1192() (uintptr, uintptr) { var buf [1192]byte; use(buf[:]); return Stackguard() }
-func stack1196() (uintptr, uintptr) { var buf [1196]byte; use(buf[:]); return Stackguard() }
-func stack1200() (uintptr, uintptr) { var buf [1200]byte; use(buf[:]); return Stackguard() }
-func stack1204() (uintptr, uintptr) { var buf [1204]byte; use(buf[:]); return Stackguard() }
-func stack1208() (uintptr, uintptr) { var buf [1208]byte; use(buf[:]); return Stackguard() }
-func stack1212() (uintptr, uintptr) { var buf [1212]byte; use(buf[:]); return Stackguard() }
-func stack1216() (uintptr, uintptr) { var buf [1216]byte; use(buf[:]); return Stackguard() }
-func stack1220() (uintptr, uintptr) { var buf [1220]byte; use(buf[:]); return Stackguard() }
-func stack1224() (uintptr, uintptr) { var buf [1224]byte; use(buf[:]); return Stackguard() }
-func stack1228() (uintptr, uintptr) { var buf [1228]byte; use(buf[:]); return Stackguard() }
-func stack1232() (uintptr, uintptr) { var buf [1232]byte; use(buf[:]); return Stackguard() }
-func stack1236() (uintptr, uintptr) { var buf [1236]byte; use(buf[:]); return Stackguard() }
-func stack1240() (uintptr, uintptr) { var buf [1240]byte; use(buf[:]); return Stackguard() }
-func stack1244() (uintptr, uintptr) { var buf [1244]byte; use(buf[:]); return Stackguard() }
-func stack1248() (uintptr, uintptr) { var buf [1248]byte; use(buf[:]); return Stackguard() }
-func stack1252() (uintptr, uintptr) { var buf [1252]byte; use(buf[:]); return Stackguard() }
-func stack1256() (uintptr, uintptr) { var buf [1256]byte; use(buf[:]); return Stackguard() }
-func stack1260() (uintptr, uintptr) { var buf [1260]byte; use(buf[:]); return Stackguard() }
-func stack1264() (uintptr, uintptr) { var buf [1264]byte; use(buf[:]); return Stackguard() }
-func stack1268() (uintptr, uintptr) { var buf [1268]byte; use(buf[:]); return Stackguard() }
-func stack1272() (uintptr, uintptr) { var buf [1272]byte; use(buf[:]); return Stackguard() }
-func stack1276() (uintptr, uintptr) { var buf [1276]byte; use(buf[:]); return Stackguard() }
-func stack1280() (uintptr, uintptr) { var buf [1280]byte; use(buf[:]); return Stackguard() }
-func stack1284() (uintptr, uintptr) { var buf [1284]byte; use(buf[:]); return Stackguard() }
-func stack1288() (uintptr, uintptr) { var buf [1288]byte; use(buf[:]); return Stackguard() }
-func stack1292() (uintptr, uintptr) { var buf [1292]byte; use(buf[:]); return Stackguard() }
-func stack1296() (uintptr, uintptr) { var buf [1296]byte; use(buf[:]); return Stackguard() }
-func stack1300() (uintptr, uintptr) { var buf [1300]byte; use(buf[:]); return Stackguard() }
-func stack1304() (uintptr, uintptr) { var buf [1304]byte; use(buf[:]); return Stackguard() }
-func stack1308() (uintptr, uintptr) { var buf [1308]byte; use(buf[:]); return Stackguard() }
-func stack1312() (uintptr, uintptr) { var buf [1312]byte; use(buf[:]); return Stackguard() }
-func stack1316() (uintptr, uintptr) { var buf [1316]byte; use(buf[:]); return Stackguard() }
-func stack1320() (uintptr, uintptr) { var buf [1320]byte; use(buf[:]); return Stackguard() }
-func stack1324() (uintptr, uintptr) { var buf [1324]byte; use(buf[:]); return Stackguard() }
-func stack1328() (uintptr, uintptr) { var buf [1328]byte; use(buf[:]); return Stackguard() }
-func stack1332() (uintptr, uintptr) { var buf [1332]byte; use(buf[:]); return Stackguard() }
-func stack1336() (uintptr, uintptr) { var buf [1336]byte; use(buf[:]); return Stackguard() }
-func stack1340() (uintptr, uintptr) { var buf [1340]byte; use(buf[:]); return Stackguard() }
-func stack1344() (uintptr, uintptr) { var buf [1344]byte; use(buf[:]); return Stackguard() }
-func stack1348() (uintptr, uintptr) { var buf [1348]byte; use(buf[:]); return Stackguard() }
-func stack1352() (uintptr, uintptr) { var buf [1352]byte; use(buf[:]); return Stackguard() }
-func stack1356() (uintptr, uintptr) { var buf [1356]byte; use(buf[:]); return Stackguard() }
-func stack1360() (uintptr, uintptr) { var buf [1360]byte; use(buf[:]); return Stackguard() }
-func stack1364() (uintptr, uintptr) { var buf [1364]byte; use(buf[:]); return Stackguard() }
-func stack1368() (uintptr, uintptr) { var buf [1368]byte; use(buf[:]); return Stackguard() }
-func stack1372() (uintptr, uintptr) { var buf [1372]byte; use(buf[:]); return Stackguard() }
-func stack1376() (uintptr, uintptr) { var buf [1376]byte; use(buf[:]); return Stackguard() }
-func stack1380() (uintptr, uintptr) { var buf [1380]byte; use(buf[:]); return Stackguard() }
-func stack1384() (uintptr, uintptr) { var buf [1384]byte; use(buf[:]); return Stackguard() }
-func stack1388() (uintptr, uintptr) { var buf [1388]byte; use(buf[:]); return Stackguard() }
-func stack1392() (uintptr, uintptr) { var buf [1392]byte; use(buf[:]); return Stackguard() }
-func stack1396() (uintptr, uintptr) { var buf [1396]byte; use(buf[:]); return Stackguard() }
-func stack1400() (uintptr, uintptr) { var buf [1400]byte; use(buf[:]); return Stackguard() }
-func stack1404() (uintptr, uintptr) { var buf [1404]byte; use(buf[:]); return Stackguard() }
-func stack1408() (uintptr, uintptr) { var buf [1408]byte; use(buf[:]); return Stackguard() }
-func stack1412() (uintptr, uintptr) { var buf [1412]byte; use(buf[:]); return Stackguard() }
-func stack1416() (uintptr, uintptr) { var buf [1416]byte; use(buf[:]); return Stackguard() }
-func stack1420() (uintptr, uintptr) { var buf [1420]byte; use(buf[:]); return Stackguard() }
-func stack1424() (uintptr, uintptr) { var buf [1424]byte; use(buf[:]); return Stackguard() }
-func stack1428() (uintptr, uintptr) { var buf [1428]byte; use(buf[:]); return Stackguard() }
-func stack1432() (uintptr, uintptr) { var buf [1432]byte; use(buf[:]); return Stackguard() }
-func stack1436() (uintptr, uintptr) { var buf [1436]byte; use(buf[:]); return Stackguard() }
-func stack1440() (uintptr, uintptr) { var buf [1440]byte; use(buf[:]); return Stackguard() }
-func stack1444() (uintptr, uintptr) { var buf [1444]byte; use(buf[:]); return Stackguard() }
-func stack1448() (uintptr, uintptr) { var buf [1448]byte; use(buf[:]); return Stackguard() }
-func stack1452() (uintptr, uintptr) { var buf [1452]byte; use(buf[:]); return Stackguard() }
-func stack1456() (uintptr, uintptr) { var buf [1456]byte; use(buf[:]); return Stackguard() }
-func stack1460() (uintptr, uintptr) { var buf [1460]byte; use(buf[:]); return Stackguard() }
-func stack1464() (uintptr, uintptr) { var buf [1464]byte; use(buf[:]); return Stackguard() }
-func stack1468() (uintptr, uintptr) { var buf [1468]byte; use(buf[:]); return Stackguard() }
-func stack1472() (uintptr, uintptr) { var buf [1472]byte; use(buf[:]); return Stackguard() }
-func stack1476() (uintptr, uintptr) { var buf [1476]byte; use(buf[:]); return Stackguard() }
-func stack1480() (uintptr, uintptr) { var buf [1480]byte; use(buf[:]); return Stackguard() }
-func stack1484() (uintptr, uintptr) { var buf [1484]byte; use(buf[:]); return Stackguard() }
-func stack1488() (uintptr, uintptr) { var buf [1488]byte; use(buf[:]); return Stackguard() }
-func stack1492() (uintptr, uintptr) { var buf [1492]byte; use(buf[:]); return Stackguard() }
-func stack1496() (uintptr, uintptr) { var buf [1496]byte; use(buf[:]); return Stackguard() }
-func stack1500() (uintptr, uintptr) { var buf [1500]byte; use(buf[:]); return Stackguard() }
-func stack1504() (uintptr, uintptr) { var buf [1504]byte; use(buf[:]); return Stackguard() }
-func stack1508() (uintptr, uintptr) { var buf [1508]byte; use(buf[:]); return Stackguard() }
-func stack1512() (uintptr, uintptr) { var buf [1512]byte; use(buf[:]); return Stackguard() }
-func stack1516() (uintptr, uintptr) { var buf [1516]byte; use(buf[:]); return Stackguard() }
-func stack1520() (uintptr, uintptr) { var buf [1520]byte; use(buf[:]); return Stackguard() }
-func stack1524() (uintptr, uintptr) { var buf [1524]byte; use(buf[:]); return Stackguard() }
-func stack1528() (uintptr, uintptr) { var buf [1528]byte; use(buf[:]); return Stackguard() }
-func stack1532() (uintptr, uintptr) { var buf [1532]byte; use(buf[:]); return Stackguard() }
-func stack1536() (uintptr, uintptr) { var buf [1536]byte; use(buf[:]); return Stackguard() }
-func stack1540() (uintptr, uintptr) { var buf [1540]byte; use(buf[:]); return Stackguard() }
-func stack1544() (uintptr, uintptr) { var buf [1544]byte; use(buf[:]); return Stackguard() }
-func stack1548() (uintptr, uintptr) { var buf [1548]byte; use(buf[:]); return Stackguard() }
-func stack1552() (uintptr, uintptr) { var buf [1552]byte; use(buf[:]); return Stackguard() }
-func stack1556() (uintptr, uintptr) { var buf [1556]byte; use(buf[:]); return Stackguard() }
-func stack1560() (uintptr, uintptr) { var buf [1560]byte; use(buf[:]); return Stackguard() }
-func stack1564() (uintptr, uintptr) { var buf [1564]byte; use(buf[:]); return Stackguard() }
-func stack1568() (uintptr, uintptr) { var buf [1568]byte; use(buf[:]); return Stackguard() }
-func stack1572() (uintptr, uintptr) { var buf [1572]byte; use(buf[:]); return Stackguard() }
-func stack1576() (uintptr, uintptr) { var buf [1576]byte; use(buf[:]); return Stackguard() }
-func stack1580() (uintptr, uintptr) { var buf [1580]byte; use(buf[:]); return Stackguard() }
-func stack1584() (uintptr, uintptr) { var buf [1584]byte; use(buf[:]); return Stackguard() }
-func stack1588() (uintptr, uintptr) { var buf [1588]byte; use(buf[:]); return Stackguard() }
-func stack1592() (uintptr, uintptr) { var buf [1592]byte; use(buf[:]); return Stackguard() }
-func stack1596() (uintptr, uintptr) { var buf [1596]byte; use(buf[:]); return Stackguard() }
-func stack1600() (uintptr, uintptr) { var buf [1600]byte; use(buf[:]); return Stackguard() }
-func stack1604() (uintptr, uintptr) { var buf [1604]byte; use(buf[:]); return Stackguard() }
-func stack1608() (uintptr, uintptr) { var buf [1608]byte; use(buf[:]); return Stackguard() }
-func stack1612() (uintptr, uintptr) { var buf [1612]byte; use(buf[:]); return Stackguard() }
-func stack1616() (uintptr, uintptr) { var buf [1616]byte; use(buf[:]); return Stackguard() }
-func stack1620() (uintptr, uintptr) { var buf [1620]byte; use(buf[:]); return Stackguard() }
-func stack1624() (uintptr, uintptr) { var buf [1624]byte; use(buf[:]); return Stackguard() }
-func stack1628() (uintptr, uintptr) { var buf [1628]byte; use(buf[:]); return Stackguard() }
-func stack1632() (uintptr, uintptr) { var buf [1632]byte; use(buf[:]); return Stackguard() }
-func stack1636() (uintptr, uintptr) { var buf [1636]byte; use(buf[:]); return Stackguard() }
-func stack1640() (uintptr, uintptr) { var buf [1640]byte; use(buf[:]); return Stackguard() }
-func stack1644() (uintptr, uintptr) { var buf [1644]byte; use(buf[:]); return Stackguard() }
-func stack1648() (uintptr, uintptr) { var buf [1648]byte; use(buf[:]); return Stackguard() }
-func stack1652() (uintptr, uintptr) { var buf [1652]byte; use(buf[:]); return Stackguard() }
-func stack1656() (uintptr, uintptr) { var buf [1656]byte; use(buf[:]); return Stackguard() }
-func stack1660() (uintptr, uintptr) { var buf [1660]byte; use(buf[:]); return Stackguard() }
-func stack1664() (uintptr, uintptr) { var buf [1664]byte; use(buf[:]); return Stackguard() }
-func stack1668() (uintptr, uintptr) { var buf [1668]byte; use(buf[:]); return Stackguard() }
-func stack1672() (uintptr, uintptr) { var buf [1672]byte; use(buf[:]); return Stackguard() }
-func stack1676() (uintptr, uintptr) { var buf [1676]byte; use(buf[:]); return Stackguard() }
-func stack1680() (uintptr, uintptr) { var buf [1680]byte; use(buf[:]); return Stackguard() }
-func stack1684() (uintptr, uintptr) { var buf [1684]byte; use(buf[:]); return Stackguard() }
-func stack1688() (uintptr, uintptr) { var buf [1688]byte; use(buf[:]); return Stackguard() }
-func stack1692() (uintptr, uintptr) { var buf [1692]byte; use(buf[:]); return Stackguard() }
-func stack1696() (uintptr, uintptr) { var buf [1696]byte; use(buf[:]); return Stackguard() }
-func stack1700() (uintptr, uintptr) { var buf [1700]byte; use(buf[:]); return Stackguard() }
-func stack1704() (uintptr, uintptr) { var buf [1704]byte; use(buf[:]); return Stackguard() }
-func stack1708() (uintptr, uintptr) { var buf [1708]byte; use(buf[:]); return Stackguard() }
-func stack1712() (uintptr, uintptr) { var buf [1712]byte; use(buf[:]); return Stackguard() }
-func stack1716() (uintptr, uintptr) { var buf [1716]byte; use(buf[:]); return Stackguard() }
-func stack1720() (uintptr, uintptr) { var buf [1720]byte; use(buf[:]); return Stackguard() }
-func stack1724() (uintptr, uintptr) { var buf [1724]byte; use(buf[:]); return Stackguard() }
-func stack1728() (uintptr, uintptr) { var buf [1728]byte; use(buf[:]); return Stackguard() }
-func stack1732() (uintptr, uintptr) { var buf [1732]byte; use(buf[:]); return Stackguard() }
-func stack1736() (uintptr, uintptr) { var buf [1736]byte; use(buf[:]); return Stackguard() }
-func stack1740() (uintptr, uintptr) { var buf [1740]byte; use(buf[:]); return Stackguard() }
-func stack1744() (uintptr, uintptr) { var buf [1744]byte; use(buf[:]); return Stackguard() }
-func stack1748() (uintptr, uintptr) { var buf [1748]byte; use(buf[:]); return Stackguard() }
-func stack1752() (uintptr, uintptr) { var buf [1752]byte; use(buf[:]); return Stackguard() }
-func stack1756() (uintptr, uintptr) { var buf [1756]byte; use(buf[:]); return Stackguard() }
-func stack1760() (uintptr, uintptr) { var buf [1760]byte; use(buf[:]); return Stackguard() }
-func stack1764() (uintptr, uintptr) { var buf [1764]byte; use(buf[:]); return Stackguard() }
-func stack1768() (uintptr, uintptr) { var buf [1768]byte; use(buf[:]); return Stackguard() }
-func stack1772() (uintptr, uintptr) { var buf [1772]byte; use(buf[:]); return Stackguard() }
-func stack1776() (uintptr, uintptr) { var buf [1776]byte; use(buf[:]); return Stackguard() }
-func stack1780() (uintptr, uintptr) { var buf [1780]byte; use(buf[:]); return Stackguard() }
-func stack1784() (uintptr, uintptr) { var buf [1784]byte; use(buf[:]); return Stackguard() }
-func stack1788() (uintptr, uintptr) { var buf [1788]byte; use(buf[:]); return Stackguard() }
-func stack1792() (uintptr, uintptr) { var buf [1792]byte; use(buf[:]); return Stackguard() }
-func stack1796() (uintptr, uintptr) { var buf [1796]byte; use(buf[:]); return Stackguard() }
-func stack1800() (uintptr, uintptr) { var buf [1800]byte; use(buf[:]); return Stackguard() }
-func stack1804() (uintptr, uintptr) { var buf [1804]byte; use(buf[:]); return Stackguard() }
-func stack1808() (uintptr, uintptr) { var buf [1808]byte; use(buf[:]); return Stackguard() }
-func stack1812() (uintptr, uintptr) { var buf [1812]byte; use(buf[:]); return Stackguard() }
-func stack1816() (uintptr, uintptr) { var buf [1816]byte; use(buf[:]); return Stackguard() }
-func stack1820() (uintptr, uintptr) { var buf [1820]byte; use(buf[:]); return Stackguard() }
-func stack1824() (uintptr, uintptr) { var buf [1824]byte; use(buf[:]); return Stackguard() }
-func stack1828() (uintptr, uintptr) { var buf [1828]byte; use(buf[:]); return Stackguard() }
-func stack1832() (uintptr, uintptr) { var buf [1832]byte; use(buf[:]); return Stackguard() }
-func stack1836() (uintptr, uintptr) { var buf [1836]byte; use(buf[:]); return Stackguard() }
-func stack1840() (uintptr, uintptr) { var buf [1840]byte; use(buf[:]); return Stackguard() }
-func stack1844() (uintptr, uintptr) { var buf [1844]byte; use(buf[:]); return Stackguard() }
-func stack1848() (uintptr, uintptr) { var buf [1848]byte; use(buf[:]); return Stackguard() }
-func stack1852() (uintptr, uintptr) { var buf [1852]byte; use(buf[:]); return Stackguard() }
-func stack1856() (uintptr, uintptr) { var buf [1856]byte; use(buf[:]); return Stackguard() }
-func stack1860() (uintptr, uintptr) { var buf [1860]byte; use(buf[:]); return Stackguard() }
-func stack1864() (uintptr, uintptr) { var buf [1864]byte; use(buf[:]); return Stackguard() }
-func stack1868() (uintptr, uintptr) { var buf [1868]byte; use(buf[:]); return Stackguard() }
-func stack1872() (uintptr, uintptr) { var buf [1872]byte; use(buf[:]); return Stackguard() }
-func stack1876() (uintptr, uintptr) { var buf [1876]byte; use(buf[:]); return Stackguard() }
-func stack1880() (uintptr, uintptr) { var buf [1880]byte; use(buf[:]); return Stackguard() }
-func stack1884() (uintptr, uintptr) { var buf [1884]byte; use(buf[:]); return Stackguard() }
-func stack1888() (uintptr, uintptr) { var buf [1888]byte; use(buf[:]); return Stackguard() }
-func stack1892() (uintptr, uintptr) { var buf [1892]byte; use(buf[:]); return Stackguard() }
-func stack1896() (uintptr, uintptr) { var buf [1896]byte; use(buf[:]); return Stackguard() }
-func stack1900() (uintptr, uintptr) { var buf [1900]byte; use(buf[:]); return Stackguard() }
-func stack1904() (uintptr, uintptr) { var buf [1904]byte; use(buf[:]); return Stackguard() }
-func stack1908() (uintptr, uintptr) { var buf [1908]byte; use(buf[:]); return Stackguard() }
-func stack1912() (uintptr, uintptr) { var buf [1912]byte; use(buf[:]); return Stackguard() }
-func stack1916() (uintptr, uintptr) { var buf [1916]byte; use(buf[:]); return Stackguard() }
-func stack1920() (uintptr, uintptr) { var buf [1920]byte; use(buf[:]); return Stackguard() }
-func stack1924() (uintptr, uintptr) { var buf [1924]byte; use(buf[:]); return Stackguard() }
-func stack1928() (uintptr, uintptr) { var buf [1928]byte; use(buf[:]); return Stackguard() }
-func stack1932() (uintptr, uintptr) { var buf [1932]byte; use(buf[:]); return Stackguard() }
-func stack1936() (uintptr, uintptr) { var buf [1936]byte; use(buf[:]); return Stackguard() }
-func stack1940() (uintptr, uintptr) { var buf [1940]byte; use(buf[:]); return Stackguard() }
-func stack1944() (uintptr, uintptr) { var buf [1944]byte; use(buf[:]); return Stackguard() }
-func stack1948() (uintptr, uintptr) { var buf [1948]byte; use(buf[:]); return Stackguard() }
-func stack1952() (uintptr, uintptr) { var buf [1952]byte; use(buf[:]); return Stackguard() }
-func stack1956() (uintptr, uintptr) { var buf [1956]byte; use(buf[:]); return Stackguard() }
-func stack1960() (uintptr, uintptr) { var buf [1960]byte; use(buf[:]); return Stackguard() }
-func stack1964() (uintptr, uintptr) { var buf [1964]byte; use(buf[:]); return Stackguard() }
-func stack1968() (uintptr, uintptr) { var buf [1968]byte; use(buf[:]); return Stackguard() }
-func stack1972() (uintptr, uintptr) { var buf [1972]byte; use(buf[:]); return Stackguard() }
-func stack1976() (uintptr, uintptr) { var buf [1976]byte; use(buf[:]); return Stackguard() }
-func stack1980() (uintptr, uintptr) { var buf [1980]byte; use(buf[:]); return Stackguard() }
-func stack1984() (uintptr, uintptr) { var buf [1984]byte; use(buf[:]); return Stackguard() }
-func stack1988() (uintptr, uintptr) { var buf [1988]byte; use(buf[:]); return Stackguard() }
-func stack1992() (uintptr, uintptr) { var buf [1992]byte; use(buf[:]); return Stackguard() }
-func stack1996() (uintptr, uintptr) { var buf [1996]byte; use(buf[:]); return Stackguard() }
-func stack2000() (uintptr, uintptr) { var buf [2000]byte; use(buf[:]); return Stackguard() }
-func stack2004() (uintptr, uintptr) { var buf [2004]byte; use(buf[:]); return Stackguard() }
-func stack2008() (uintptr, uintptr) { var buf [2008]byte; use(buf[:]); return Stackguard() }
-func stack2012() (uintptr, uintptr) { var buf [2012]byte; use(buf[:]); return Stackguard() }
-func stack2016() (uintptr, uintptr) { var buf [2016]byte; use(buf[:]); return Stackguard() }
-func stack2020() (uintptr, uintptr) { var buf [2020]byte; use(buf[:]); return Stackguard() }
-func stack2024() (uintptr, uintptr) { var buf [2024]byte; use(buf[:]); return Stackguard() }
-func stack2028() (uintptr, uintptr) { var buf [2028]byte; use(buf[:]); return Stackguard() }
-func stack2032() (uintptr, uintptr) { var buf [2032]byte; use(buf[:]); return Stackguard() }
-func stack2036() (uintptr, uintptr) { var buf [2036]byte; use(buf[:]); return Stackguard() }
-func stack2040() (uintptr, uintptr) { var buf [2040]byte; use(buf[:]); return Stackguard() }
-func stack2044() (uintptr, uintptr) { var buf [2044]byte; use(buf[:]); return Stackguard() }
-func stack2048() (uintptr, uintptr) { var buf [2048]byte; use(buf[:]); return Stackguard() }
-func stack2052() (uintptr, uintptr) { var buf [2052]byte; use(buf[:]); return Stackguard() }
-func stack2056() (uintptr, uintptr) { var buf [2056]byte; use(buf[:]); return Stackguard() }
-func stack2060() (uintptr, uintptr) { var buf [2060]byte; use(buf[:]); return Stackguard() }
-func stack2064() (uintptr, uintptr) { var buf [2064]byte; use(buf[:]); return Stackguard() }
-func stack2068() (uintptr, uintptr) { var buf [2068]byte; use(buf[:]); return Stackguard() }
-func stack2072() (uintptr, uintptr) { var buf [2072]byte; use(buf[:]); return Stackguard() }
-func stack2076() (uintptr, uintptr) { var buf [2076]byte; use(buf[:]); return Stackguard() }
-func stack2080() (uintptr, uintptr) { var buf [2080]byte; use(buf[:]); return Stackguard() }
-func stack2084() (uintptr, uintptr) { var buf [2084]byte; use(buf[:]); return Stackguard() }
-func stack2088() (uintptr, uintptr) { var buf [2088]byte; use(buf[:]); return Stackguard() }
-func stack2092() (uintptr, uintptr) { var buf [2092]byte; use(buf[:]); return Stackguard() }
-func stack2096() (uintptr, uintptr) { var buf [2096]byte; use(buf[:]); return Stackguard() }
-func stack2100() (uintptr, uintptr) { var buf [2100]byte; use(buf[:]); return Stackguard() }
-func stack2104() (uintptr, uintptr) { var buf [2104]byte; use(buf[:]); return Stackguard() }
-func stack2108() (uintptr, uintptr) { var buf [2108]byte; use(buf[:]); return Stackguard() }
-func stack2112() (uintptr, uintptr) { var buf [2112]byte; use(buf[:]); return Stackguard() }
-func stack2116() (uintptr, uintptr) { var buf [2116]byte; use(buf[:]); return Stackguard() }
-func stack2120() (uintptr, uintptr) { var buf [2120]byte; use(buf[:]); return Stackguard() }
-func stack2124() (uintptr, uintptr) { var buf [2124]byte; use(buf[:]); return Stackguard() }
-func stack2128() (uintptr, uintptr) { var buf [2128]byte; use(buf[:]); return Stackguard() }
-func stack2132() (uintptr, uintptr) { var buf [2132]byte; use(buf[:]); return Stackguard() }
-func stack2136() (uintptr, uintptr) { var buf [2136]byte; use(buf[:]); return Stackguard() }
-func stack2140() (uintptr, uintptr) { var buf [2140]byte; use(buf[:]); return Stackguard() }
-func stack2144() (uintptr, uintptr) { var buf [2144]byte; use(buf[:]); return Stackguard() }
-func stack2148() (uintptr, uintptr) { var buf [2148]byte; use(buf[:]); return Stackguard() }
-func stack2152() (uintptr, uintptr) { var buf [2152]byte; use(buf[:]); return Stackguard() }
-func stack2156() (uintptr, uintptr) { var buf [2156]byte; use(buf[:]); return Stackguard() }
-func stack2160() (uintptr, uintptr) { var buf [2160]byte; use(buf[:]); return Stackguard() }
-func stack2164() (uintptr, uintptr) { var buf [2164]byte; use(buf[:]); return Stackguard() }
-func stack2168() (uintptr, uintptr) { var buf [2168]byte; use(buf[:]); return Stackguard() }
-func stack2172() (uintptr, uintptr) { var buf [2172]byte; use(buf[:]); return Stackguard() }
-func stack2176() (uintptr, uintptr) { var buf [2176]byte; use(buf[:]); return Stackguard() }
-func stack2180() (uintptr, uintptr) { var buf [2180]byte; use(buf[:]); return Stackguard() }
-func stack2184() (uintptr, uintptr) { var buf [2184]byte; use(buf[:]); return Stackguard() }
-func stack2188() (uintptr, uintptr) { var buf [2188]byte; use(buf[:]); return Stackguard() }
-func stack2192() (uintptr, uintptr) { var buf [2192]byte; use(buf[:]); return Stackguard() }
-func stack2196() (uintptr, uintptr) { var buf [2196]byte; use(buf[:]); return Stackguard() }
-func stack2200() (uintptr, uintptr) { var buf [2200]byte; use(buf[:]); return Stackguard() }
-func stack2204() (uintptr, uintptr) { var buf [2204]byte; use(buf[:]); return Stackguard() }
-func stack2208() (uintptr, uintptr) { var buf [2208]byte; use(buf[:]); return Stackguard() }
-func stack2212() (uintptr, uintptr) { var buf [2212]byte; use(buf[:]); return Stackguard() }
-func stack2216() (uintptr, uintptr) { var buf [2216]byte; use(buf[:]); return Stackguard() }
-func stack2220() (uintptr, uintptr) { var buf [2220]byte; use(buf[:]); return Stackguard() }
-func stack2224() (uintptr, uintptr) { var buf [2224]byte; use(buf[:]); return Stackguard() }
-func stack2228() (uintptr, uintptr) { var buf [2228]byte; use(buf[:]); return Stackguard() }
-func stack2232() (uintptr, uintptr) { var buf [2232]byte; use(buf[:]); return Stackguard() }
-func stack2236() (uintptr, uintptr) { var buf [2236]byte; use(buf[:]); return Stackguard() }
-func stack2240() (uintptr, uintptr) { var buf [2240]byte; use(buf[:]); return Stackguard() }
-func stack2244() (uintptr, uintptr) { var buf [2244]byte; use(buf[:]); return Stackguard() }
-func stack2248() (uintptr, uintptr) { var buf [2248]byte; use(buf[:]); return Stackguard() }
-func stack2252() (uintptr, uintptr) { var buf [2252]byte; use(buf[:]); return Stackguard() }
-func stack2256() (uintptr, uintptr) { var buf [2256]byte; use(buf[:]); return Stackguard() }
-func stack2260() (uintptr, uintptr) { var buf [2260]byte; use(buf[:]); return Stackguard() }
-func stack2264() (uintptr, uintptr) { var buf [2264]byte; use(buf[:]); return Stackguard() }
-func stack2268() (uintptr, uintptr) { var buf [2268]byte; use(buf[:]); return Stackguard() }
-func stack2272() (uintptr, uintptr) { var buf [2272]byte; use(buf[:]); return Stackguard() }
-func stack2276() (uintptr, uintptr) { var buf [2276]byte; use(buf[:]); return Stackguard() }
-func stack2280() (uintptr, uintptr) { var buf [2280]byte; use(buf[:]); return Stackguard() }
-func stack2284() (uintptr, uintptr) { var buf [2284]byte; use(buf[:]); return Stackguard() }
-func stack2288() (uintptr, uintptr) { var buf [2288]byte; use(buf[:]); return Stackguard() }
-func stack2292() (uintptr, uintptr) { var buf [2292]byte; use(buf[:]); return Stackguard() }
-func stack2296() (uintptr, uintptr) { var buf [2296]byte; use(buf[:]); return Stackguard() }
-func stack2300() (uintptr, uintptr) { var buf [2300]byte; use(buf[:]); return Stackguard() }
-func stack2304() (uintptr, uintptr) { var buf [2304]byte; use(buf[:]); return Stackguard() }
-func stack2308() (uintptr, uintptr) { var buf [2308]byte; use(buf[:]); return Stackguard() }
-func stack2312() (uintptr, uintptr) { var buf [2312]byte; use(buf[:]); return Stackguard() }
-func stack2316() (uintptr, uintptr) { var buf [2316]byte; use(buf[:]); return Stackguard() }
-func stack2320() (uintptr, uintptr) { var buf [2320]byte; use(buf[:]); return Stackguard() }
-func stack2324() (uintptr, uintptr) { var buf [2324]byte; use(buf[:]); return Stackguard() }
-func stack2328() (uintptr, uintptr) { var buf [2328]byte; use(buf[:]); return Stackguard() }
-func stack2332() (uintptr, uintptr) { var buf [2332]byte; use(buf[:]); return Stackguard() }
-func stack2336() (uintptr, uintptr) { var buf [2336]byte; use(buf[:]); return Stackguard() }
-func stack2340() (uintptr, uintptr) { var buf [2340]byte; use(buf[:]); return Stackguard() }
-func stack2344() (uintptr, uintptr) { var buf [2344]byte; use(buf[:]); return Stackguard() }
-func stack2348() (uintptr, uintptr) { var buf [2348]byte; use(buf[:]); return Stackguard() }
-func stack2352() (uintptr, uintptr) { var buf [2352]byte; use(buf[:]); return Stackguard() }
-func stack2356() (uintptr, uintptr) { var buf [2356]byte; use(buf[:]); return Stackguard() }
-func stack2360() (uintptr, uintptr) { var buf [2360]byte; use(buf[:]); return Stackguard() }
-func stack2364() (uintptr, uintptr) { var buf [2364]byte; use(buf[:]); return Stackguard() }
-func stack2368() (uintptr, uintptr) { var buf [2368]byte; use(buf[:]); return Stackguard() }
-func stack2372() (uintptr, uintptr) { var buf [2372]byte; use(buf[:]); return Stackguard() }
-func stack2376() (uintptr, uintptr) { var buf [2376]byte; use(buf[:]); return Stackguard() }
-func stack2380() (uintptr, uintptr) { var buf [2380]byte; use(buf[:]); return Stackguard() }
-func stack2384() (uintptr, uintptr) { var buf [2384]byte; use(buf[:]); return Stackguard() }
-func stack2388() (uintptr, uintptr) { var buf [2388]byte; use(buf[:]); return Stackguard() }
-func stack2392() (uintptr, uintptr) { var buf [2392]byte; use(buf[:]); return Stackguard() }
-func stack2396() (uintptr, uintptr) { var buf [2396]byte; use(buf[:]); return Stackguard() }
-func stack2400() (uintptr, uintptr) { var buf [2400]byte; use(buf[:]); return Stackguard() }
-func stack2404() (uintptr, uintptr) { var buf [2404]byte; use(buf[:]); return Stackguard() }
-func stack2408() (uintptr, uintptr) { var buf [2408]byte; use(buf[:]); return Stackguard() }
-func stack2412() (uintptr, uintptr) { var buf [2412]byte; use(buf[:]); return Stackguard() }
-func stack2416() (uintptr, uintptr) { var buf [2416]byte; use(buf[:]); return Stackguard() }
-func stack2420() (uintptr, uintptr) { var buf [2420]byte; use(buf[:]); return Stackguard() }
-func stack2424() (uintptr, uintptr) { var buf [2424]byte; use(buf[:]); return Stackguard() }
-func stack2428() (uintptr, uintptr) { var buf [2428]byte; use(buf[:]); return Stackguard() }
-func stack2432() (uintptr, uintptr) { var buf [2432]byte; use(buf[:]); return Stackguard() }
-func stack2436() (uintptr, uintptr) { var buf [2436]byte; use(buf[:]); return Stackguard() }
-func stack2440() (uintptr, uintptr) { var buf [2440]byte; use(buf[:]); return Stackguard() }
-func stack2444() (uintptr, uintptr) { var buf [2444]byte; use(buf[:]); return Stackguard() }
-func stack2448() (uintptr, uintptr) { var buf [2448]byte; use(buf[:]); return Stackguard() }
-func stack2452() (uintptr, uintptr) { var buf [2452]byte; use(buf[:]); return Stackguard() }
-func stack2456() (uintptr, uintptr) { var buf [2456]byte; use(buf[:]); return Stackguard() }
-func stack2460() (uintptr, uintptr) { var buf [2460]byte; use(buf[:]); return Stackguard() }
-func stack2464() (uintptr, uintptr) { var buf [2464]byte; use(buf[:]); return Stackguard() }
-func stack2468() (uintptr, uintptr) { var buf [2468]byte; use(buf[:]); return Stackguard() }
-func stack2472() (uintptr, uintptr) { var buf [2472]byte; use(buf[:]); return Stackguard() }
-func stack2476() (uintptr, uintptr) { var buf [2476]byte; use(buf[:]); return Stackguard() }
-func stack2480() (uintptr, uintptr) { var buf [2480]byte; use(buf[:]); return Stackguard() }
-func stack2484() (uintptr, uintptr) { var buf [2484]byte; use(buf[:]); return Stackguard() }
-func stack2488() (uintptr, uintptr) { var buf [2488]byte; use(buf[:]); return Stackguard() }
-func stack2492() (uintptr, uintptr) { var buf [2492]byte; use(buf[:]); return Stackguard() }
-func stack2496() (uintptr, uintptr) { var buf [2496]byte; use(buf[:]); return Stackguard() }
-func stack2500() (uintptr, uintptr) { var buf [2500]byte; use(buf[:]); return Stackguard() }
-func stack2504() (uintptr, uintptr) { var buf [2504]byte; use(buf[:]); return Stackguard() }
-func stack2508() (uintptr, uintptr) { var buf [2508]byte; use(buf[:]); return Stackguard() }
-func stack2512() (uintptr, uintptr) { var buf [2512]byte; use(buf[:]); return Stackguard() }
-func stack2516() (uintptr, uintptr) { var buf [2516]byte; use(buf[:]); return Stackguard() }
-func stack2520() (uintptr, uintptr) { var buf [2520]byte; use(buf[:]); return Stackguard() }
-func stack2524() (uintptr, uintptr) { var buf [2524]byte; use(buf[:]); return Stackguard() }
-func stack2528() (uintptr, uintptr) { var buf [2528]byte; use(buf[:]); return Stackguard() }
-func stack2532() (uintptr, uintptr) { var buf [2532]byte; use(buf[:]); return Stackguard() }
-func stack2536() (uintptr, uintptr) { var buf [2536]byte; use(buf[:]); return Stackguard() }
-func stack2540() (uintptr, uintptr) { var buf [2540]byte; use(buf[:]); return Stackguard() }
-func stack2544() (uintptr, uintptr) { var buf [2544]byte; use(buf[:]); return Stackguard() }
-func stack2548() (uintptr, uintptr) { var buf [2548]byte; use(buf[:]); return Stackguard() }
-func stack2552() (uintptr, uintptr) { var buf [2552]byte; use(buf[:]); return Stackguard() }
-func stack2556() (uintptr, uintptr) { var buf [2556]byte; use(buf[:]); return Stackguard() }
-func stack2560() (uintptr, uintptr) { var buf [2560]byte; use(buf[:]); return Stackguard() }
-func stack2564() (uintptr, uintptr) { var buf [2564]byte; use(buf[:]); return Stackguard() }
-func stack2568() (uintptr, uintptr) { var buf [2568]byte; use(buf[:]); return Stackguard() }
-func stack2572() (uintptr, uintptr) { var buf [2572]byte; use(buf[:]); return Stackguard() }
-func stack2576() (uintptr, uintptr) { var buf [2576]byte; use(buf[:]); return Stackguard() }
-func stack2580() (uintptr, uintptr) { var buf [2580]byte; use(buf[:]); return Stackguard() }
-func stack2584() (uintptr, uintptr) { var buf [2584]byte; use(buf[:]); return Stackguard() }
-func stack2588() (uintptr, uintptr) { var buf [2588]byte; use(buf[:]); return Stackguard() }
-func stack2592() (uintptr, uintptr) { var buf [2592]byte; use(buf[:]); return Stackguard() }
-func stack2596() (uintptr, uintptr) { var buf [2596]byte; use(buf[:]); return Stackguard() }
-func stack2600() (uintptr, uintptr) { var buf [2600]byte; use(buf[:]); return Stackguard() }
-func stack2604() (uintptr, uintptr) { var buf [2604]byte; use(buf[:]); return Stackguard() }
-func stack2608() (uintptr, uintptr) { var buf [2608]byte; use(buf[:]); return Stackguard() }
-func stack2612() (uintptr, uintptr) { var buf [2612]byte; use(buf[:]); return Stackguard() }
-func stack2616() (uintptr, uintptr) { var buf [2616]byte; use(buf[:]); return Stackguard() }
-func stack2620() (uintptr, uintptr) { var buf [2620]byte; use(buf[:]); return Stackguard() }
-func stack2624() (uintptr, uintptr) { var buf [2624]byte; use(buf[:]); return Stackguard() }
-func stack2628() (uintptr, uintptr) { var buf [2628]byte; use(buf[:]); return Stackguard() }
-func stack2632() (uintptr, uintptr) { var buf [2632]byte; use(buf[:]); return Stackguard() }
-func stack2636() (uintptr, uintptr) { var buf [2636]byte; use(buf[:]); return Stackguard() }
-func stack2640() (uintptr, uintptr) { var buf [2640]byte; use(buf[:]); return Stackguard() }
-func stack2644() (uintptr, uintptr) { var buf [2644]byte; use(buf[:]); return Stackguard() }
-func stack2648() (uintptr, uintptr) { var buf [2648]byte; use(buf[:]); return Stackguard() }
-func stack2652() (uintptr, uintptr) { var buf [2652]byte; use(buf[:]); return Stackguard() }
-func stack2656() (uintptr, uintptr) { var buf [2656]byte; use(buf[:]); return Stackguard() }
-func stack2660() (uintptr, uintptr) { var buf [2660]byte; use(buf[:]); return Stackguard() }
-func stack2664() (uintptr, uintptr) { var buf [2664]byte; use(buf[:]); return Stackguard() }
-func stack2668() (uintptr, uintptr) { var buf [2668]byte; use(buf[:]); return Stackguard() }
-func stack2672() (uintptr, uintptr) { var buf [2672]byte; use(buf[:]); return Stackguard() }
-func stack2676() (uintptr, uintptr) { var buf [2676]byte; use(buf[:]); return Stackguard() }
-func stack2680() (uintptr, uintptr) { var buf [2680]byte; use(buf[:]); return Stackguard() }
-func stack2684() (uintptr, uintptr) { var buf [2684]byte; use(buf[:]); return Stackguard() }
-func stack2688() (uintptr, uintptr) { var buf [2688]byte; use(buf[:]); return Stackguard() }
-func stack2692() (uintptr, uintptr) { var buf [2692]byte; use(buf[:]); return Stackguard() }
-func stack2696() (uintptr, uintptr) { var buf [2696]byte; use(buf[:]); return Stackguard() }
-func stack2700() (uintptr, uintptr) { var buf [2700]byte; use(buf[:]); return Stackguard() }
-func stack2704() (uintptr, uintptr) { var buf [2704]byte; use(buf[:]); return Stackguard() }
-func stack2708() (uintptr, uintptr) { var buf [2708]byte; use(buf[:]); return Stackguard() }
-func stack2712() (uintptr, uintptr) { var buf [2712]byte; use(buf[:]); return Stackguard() }
-func stack2716() (uintptr, uintptr) { var buf [2716]byte; use(buf[:]); return Stackguard() }
-func stack2720() (uintptr, uintptr) { var buf [2720]byte; use(buf[:]); return Stackguard() }
-func stack2724() (uintptr, uintptr) { var buf [2724]byte; use(buf[:]); return Stackguard() }
-func stack2728() (uintptr, uintptr) { var buf [2728]byte; use(buf[:]); return Stackguard() }
-func stack2732() (uintptr, uintptr) { var buf [2732]byte; use(buf[:]); return Stackguard() }
-func stack2736() (uintptr, uintptr) { var buf [2736]byte; use(buf[:]); return Stackguard() }
-func stack2740() (uintptr, uintptr) { var buf [2740]byte; use(buf[:]); return Stackguard() }
-func stack2744() (uintptr, uintptr) { var buf [2744]byte; use(buf[:]); return Stackguard() }
-func stack2748() (uintptr, uintptr) { var buf [2748]byte; use(buf[:]); return Stackguard() }
-func stack2752() (uintptr, uintptr) { var buf [2752]byte; use(buf[:]); return Stackguard() }
-func stack2756() (uintptr, uintptr) { var buf [2756]byte; use(buf[:]); return Stackguard() }
-func stack2760() (uintptr, uintptr) { var buf [2760]byte; use(buf[:]); return Stackguard() }
-func stack2764() (uintptr, uintptr) { var buf [2764]byte; use(buf[:]); return Stackguard() }
-func stack2768() (uintptr, uintptr) { var buf [2768]byte; use(buf[:]); return Stackguard() }
-func stack2772() (uintptr, uintptr) { var buf [2772]byte; use(buf[:]); return Stackguard() }
-func stack2776() (uintptr, uintptr) { var buf [2776]byte; use(buf[:]); return Stackguard() }
-func stack2780() (uintptr, uintptr) { var buf [2780]byte; use(buf[:]); return Stackguard() }
-func stack2784() (uintptr, uintptr) { var buf [2784]byte; use(buf[:]); return Stackguard() }
-func stack2788() (uintptr, uintptr) { var buf [2788]byte; use(buf[:]); return Stackguard() }
-func stack2792() (uintptr, uintptr) { var buf [2792]byte; use(buf[:]); return Stackguard() }
-func stack2796() (uintptr, uintptr) { var buf [2796]byte; use(buf[:]); return Stackguard() }
-func stack2800() (uintptr, uintptr) { var buf [2800]byte; use(buf[:]); return Stackguard() }
-func stack2804() (uintptr, uintptr) { var buf [2804]byte; use(buf[:]); return Stackguard() }
-func stack2808() (uintptr, uintptr) { var buf [2808]byte; use(buf[:]); return Stackguard() }
-func stack2812() (uintptr, uintptr) { var buf [2812]byte; use(buf[:]); return Stackguard() }
-func stack2816() (uintptr, uintptr) { var buf [2816]byte; use(buf[:]); return Stackguard() }
-func stack2820() (uintptr, uintptr) { var buf [2820]byte; use(buf[:]); return Stackguard() }
-func stack2824() (uintptr, uintptr) { var buf [2824]byte; use(buf[:]); return Stackguard() }
-func stack2828() (uintptr, uintptr) { var buf [2828]byte; use(buf[:]); return Stackguard() }
-func stack2832() (uintptr, uintptr) { var buf [2832]byte; use(buf[:]); return Stackguard() }
-func stack2836() (uintptr, uintptr) { var buf [2836]byte; use(buf[:]); return Stackguard() }
-func stack2840() (uintptr, uintptr) { var buf [2840]byte; use(buf[:]); return Stackguard() }
-func stack2844() (uintptr, uintptr) { var buf [2844]byte; use(buf[:]); return Stackguard() }
-func stack2848() (uintptr, uintptr) { var buf [2848]byte; use(buf[:]); return Stackguard() }
-func stack2852() (uintptr, uintptr) { var buf [2852]byte; use(buf[:]); return Stackguard() }
-func stack2856() (uintptr, uintptr) { var buf [2856]byte; use(buf[:]); return Stackguard() }
-func stack2860() (uintptr, uintptr) { var buf [2860]byte; use(buf[:]); return Stackguard() }
-func stack2864() (uintptr, uintptr) { var buf [2864]byte; use(buf[:]); return Stackguard() }
-func stack2868() (uintptr, uintptr) { var buf [2868]byte; use(buf[:]); return Stackguard() }
-func stack2872() (uintptr, uintptr) { var buf [2872]byte; use(buf[:]); return Stackguard() }
-func stack2876() (uintptr, uintptr) { var buf [2876]byte; use(buf[:]); return Stackguard() }
-func stack2880() (uintptr, uintptr) { var buf [2880]byte; use(buf[:]); return Stackguard() }
-func stack2884() (uintptr, uintptr) { var buf [2884]byte; use(buf[:]); return Stackguard() }
-func stack2888() (uintptr, uintptr) { var buf [2888]byte; use(buf[:]); return Stackguard() }
-func stack2892() (uintptr, uintptr) { var buf [2892]byte; use(buf[:]); return Stackguard() }
-func stack2896() (uintptr, uintptr) { var buf [2896]byte; use(buf[:]); return Stackguard() }
-func stack2900() (uintptr, uintptr) { var buf [2900]byte; use(buf[:]); return Stackguard() }
-func stack2904() (uintptr, uintptr) { var buf [2904]byte; use(buf[:]); return Stackguard() }
-func stack2908() (uintptr, uintptr) { var buf [2908]byte; use(buf[:]); return Stackguard() }
-func stack2912() (uintptr, uintptr) { var buf [2912]byte; use(buf[:]); return Stackguard() }
-func stack2916() (uintptr, uintptr) { var buf [2916]byte; use(buf[:]); return Stackguard() }
-func stack2920() (uintptr, uintptr) { var buf [2920]byte; use(buf[:]); return Stackguard() }
-func stack2924() (uintptr, uintptr) { var buf [2924]byte; use(buf[:]); return Stackguard() }
-func stack2928() (uintptr, uintptr) { var buf [2928]byte; use(buf[:]); return Stackguard() }
-func stack2932() (uintptr, uintptr) { var buf [2932]byte; use(buf[:]); return Stackguard() }
-func stack2936() (uintptr, uintptr) { var buf [2936]byte; use(buf[:]); return Stackguard() }
-func stack2940() (uintptr, uintptr) { var buf [2940]byte; use(buf[:]); return Stackguard() }
-func stack2944() (uintptr, uintptr) { var buf [2944]byte; use(buf[:]); return Stackguard() }
-func stack2948() (uintptr, uintptr) { var buf [2948]byte; use(buf[:]); return Stackguard() }
-func stack2952() (uintptr, uintptr) { var buf [2952]byte; use(buf[:]); return Stackguard() }
-func stack2956() (uintptr, uintptr) { var buf [2956]byte; use(buf[:]); return Stackguard() }
-func stack2960() (uintptr, uintptr) { var buf [2960]byte; use(buf[:]); return Stackguard() }
-func stack2964() (uintptr, uintptr) { var buf [2964]byte; use(buf[:]); return Stackguard() }
-func stack2968() (uintptr, uintptr) { var buf [2968]byte; use(buf[:]); return Stackguard() }
-func stack2972() (uintptr, uintptr) { var buf [2972]byte; use(buf[:]); return Stackguard() }
-func stack2976() (uintptr, uintptr) { var buf [2976]byte; use(buf[:]); return Stackguard() }
-func stack2980() (uintptr, uintptr) { var buf [2980]byte; use(buf[:]); return Stackguard() }
-func stack2984() (uintptr, uintptr) { var buf [2984]byte; use(buf[:]); return Stackguard() }
-func stack2988() (uintptr, uintptr) { var buf [2988]byte; use(buf[:]); return Stackguard() }
-func stack2992() (uintptr, uintptr) { var buf [2992]byte; use(buf[:]); return Stackguard() }
-func stack2996() (uintptr, uintptr) { var buf [2996]byte; use(buf[:]); return Stackguard() }
-func stack3000() (uintptr, uintptr) { var buf [3000]byte; use(buf[:]); return Stackguard() }
-func stack3004() (uintptr, uintptr) { var buf [3004]byte; use(buf[:]); return Stackguard() }
-func stack3008() (uintptr, uintptr) { var buf [3008]byte; use(buf[:]); return Stackguard() }
-func stack3012() (uintptr, uintptr) { var buf [3012]byte; use(buf[:]); return Stackguard() }
-func stack3016() (uintptr, uintptr) { var buf [3016]byte; use(buf[:]); return Stackguard() }
-func stack3020() (uintptr, uintptr) { var buf [3020]byte; use(buf[:]); return Stackguard() }
-func stack3024() (uintptr, uintptr) { var buf [3024]byte; use(buf[:]); return Stackguard() }
-func stack3028() (uintptr, uintptr) { var buf [3028]byte; use(buf[:]); return Stackguard() }
-func stack3032() (uintptr, uintptr) { var buf [3032]byte; use(buf[:]); return Stackguard() }
-func stack3036() (uintptr, uintptr) { var buf [3036]byte; use(buf[:]); return Stackguard() }
-func stack3040() (uintptr, uintptr) { var buf [3040]byte; use(buf[:]); return Stackguard() }
-func stack3044() (uintptr, uintptr) { var buf [3044]byte; use(buf[:]); return Stackguard() }
-func stack3048() (uintptr, uintptr) { var buf [3048]byte; use(buf[:]); return Stackguard() }
-func stack3052() (uintptr, uintptr) { var buf [3052]byte; use(buf[:]); return Stackguard() }
-func stack3056() (uintptr, uintptr) { var buf [3056]byte; use(buf[:]); return Stackguard() }
-func stack3060() (uintptr, uintptr) { var buf [3060]byte; use(buf[:]); return Stackguard() }
-func stack3064() (uintptr, uintptr) { var buf [3064]byte; use(buf[:]); return Stackguard() }
-func stack3068() (uintptr, uintptr) { var buf [3068]byte; use(buf[:]); return Stackguard() }
-func stack3072() (uintptr, uintptr) { var buf [3072]byte; use(buf[:]); return Stackguard() }
-func stack3076() (uintptr, uintptr) { var buf [3076]byte; use(buf[:]); return Stackguard() }
-func stack3080() (uintptr, uintptr) { var buf [3080]byte; use(buf[:]); return Stackguard() }
-func stack3084() (uintptr, uintptr) { var buf [3084]byte; use(buf[:]); return Stackguard() }
-func stack3088() (uintptr, uintptr) { var buf [3088]byte; use(buf[:]); return Stackguard() }
-func stack3092() (uintptr, uintptr) { var buf [3092]byte; use(buf[:]); return Stackguard() }
-func stack3096() (uintptr, uintptr) { var buf [3096]byte; use(buf[:]); return Stackguard() }
-func stack3100() (uintptr, uintptr) { var buf [3100]byte; use(buf[:]); return Stackguard() }
-func stack3104() (uintptr, uintptr) { var buf [3104]byte; use(buf[:]); return Stackguard() }
-func stack3108() (uintptr, uintptr) { var buf [3108]byte; use(buf[:]); return Stackguard() }
-func stack3112() (uintptr, uintptr) { var buf [3112]byte; use(buf[:]); return Stackguard() }
-func stack3116() (uintptr, uintptr) { var buf [3116]byte; use(buf[:]); return Stackguard() }
-func stack3120() (uintptr, uintptr) { var buf [3120]byte; use(buf[:]); return Stackguard() }
-func stack3124() (uintptr, uintptr) { var buf [3124]byte; use(buf[:]); return Stackguard() }
-func stack3128() (uintptr, uintptr) { var buf [3128]byte; use(buf[:]); return Stackguard() }
-func stack3132() (uintptr, uintptr) { var buf [3132]byte; use(buf[:]); return Stackguard() }
-func stack3136() (uintptr, uintptr) { var buf [3136]byte; use(buf[:]); return Stackguard() }
-func stack3140() (uintptr, uintptr) { var buf [3140]byte; use(buf[:]); return Stackguard() }
-func stack3144() (uintptr, uintptr) { var buf [3144]byte; use(buf[:]); return Stackguard() }
-func stack3148() (uintptr, uintptr) { var buf [3148]byte; use(buf[:]); return Stackguard() }
-func stack3152() (uintptr, uintptr) { var buf [3152]byte; use(buf[:]); return Stackguard() }
-func stack3156() (uintptr, uintptr) { var buf [3156]byte; use(buf[:]); return Stackguard() }
-func stack3160() (uintptr, uintptr) { var buf [3160]byte; use(buf[:]); return Stackguard() }
-func stack3164() (uintptr, uintptr) { var buf [3164]byte; use(buf[:]); return Stackguard() }
-func stack3168() (uintptr, uintptr) { var buf [3168]byte; use(buf[:]); return Stackguard() }
-func stack3172() (uintptr, uintptr) { var buf [3172]byte; use(buf[:]); return Stackguard() }
-func stack3176() (uintptr, uintptr) { var buf [3176]byte; use(buf[:]); return Stackguard() }
-func stack3180() (uintptr, uintptr) { var buf [3180]byte; use(buf[:]); return Stackguard() }
-func stack3184() (uintptr, uintptr) { var buf [3184]byte; use(buf[:]); return Stackguard() }
-func stack3188() (uintptr, uintptr) { var buf [3188]byte; use(buf[:]); return Stackguard() }
-func stack3192() (uintptr, uintptr) { var buf [3192]byte; use(buf[:]); return Stackguard() }
-func stack3196() (uintptr, uintptr) { var buf [3196]byte; use(buf[:]); return Stackguard() }
-func stack3200() (uintptr, uintptr) { var buf [3200]byte; use(buf[:]); return Stackguard() }
-func stack3204() (uintptr, uintptr) { var buf [3204]byte; use(buf[:]); return Stackguard() }
-func stack3208() (uintptr, uintptr) { var buf [3208]byte; use(buf[:]); return Stackguard() }
-func stack3212() (uintptr, uintptr) { var buf [3212]byte; use(buf[:]); return Stackguard() }
-func stack3216() (uintptr, uintptr) { var buf [3216]byte; use(buf[:]); return Stackguard() }
-func stack3220() (uintptr, uintptr) { var buf [3220]byte; use(buf[:]); return Stackguard() }
-func stack3224() (uintptr, uintptr) { var buf [3224]byte; use(buf[:]); return Stackguard() }
-func stack3228() (uintptr, uintptr) { var buf [3228]byte; use(buf[:]); return Stackguard() }
-func stack3232() (uintptr, uintptr) { var buf [3232]byte; use(buf[:]); return Stackguard() }
-func stack3236() (uintptr, uintptr) { var buf [3236]byte; use(buf[:]); return Stackguard() }
-func stack3240() (uintptr, uintptr) { var buf [3240]byte; use(buf[:]); return Stackguard() }
-func stack3244() (uintptr, uintptr) { var buf [3244]byte; use(buf[:]); return Stackguard() }
-func stack3248() (uintptr, uintptr) { var buf [3248]byte; use(buf[:]); return Stackguard() }
-func stack3252() (uintptr, uintptr) { var buf [3252]byte; use(buf[:]); return Stackguard() }
-func stack3256() (uintptr, uintptr) { var buf [3256]byte; use(buf[:]); return Stackguard() }
-func stack3260() (uintptr, uintptr) { var buf [3260]byte; use(buf[:]); return Stackguard() }
-func stack3264() (uintptr, uintptr) { var buf [3264]byte; use(buf[:]); return Stackguard() }
-func stack3268() (uintptr, uintptr) { var buf [3268]byte; use(buf[:]); return Stackguard() }
-func stack3272() (uintptr, uintptr) { var buf [3272]byte; use(buf[:]); return Stackguard() }
-func stack3276() (uintptr, uintptr) { var buf [3276]byte; use(buf[:]); return Stackguard() }
-func stack3280() (uintptr, uintptr) { var buf [3280]byte; use(buf[:]); return Stackguard() }
-func stack3284() (uintptr, uintptr) { var buf [3284]byte; use(buf[:]); return Stackguard() }
-func stack3288() (uintptr, uintptr) { var buf [3288]byte; use(buf[:]); return Stackguard() }
-func stack3292() (uintptr, uintptr) { var buf [3292]byte; use(buf[:]); return Stackguard() }
-func stack3296() (uintptr, uintptr) { var buf [3296]byte; use(buf[:]); return Stackguard() }
-func stack3300() (uintptr, uintptr) { var buf [3300]byte; use(buf[:]); return Stackguard() }
-func stack3304() (uintptr, uintptr) { var buf [3304]byte; use(buf[:]); return Stackguard() }
-func stack3308() (uintptr, uintptr) { var buf [3308]byte; use(buf[:]); return Stackguard() }
-func stack3312() (uintptr, uintptr) { var buf [3312]byte; use(buf[:]); return Stackguard() }
-func stack3316() (uintptr, uintptr) { var buf [3316]byte; use(buf[:]); return Stackguard() }
-func stack3320() (uintptr, uintptr) { var buf [3320]byte; use(buf[:]); return Stackguard() }
-func stack3324() (uintptr, uintptr) { var buf [3324]byte; use(buf[:]); return Stackguard() }
-func stack3328() (uintptr, uintptr) { var buf [3328]byte; use(buf[:]); return Stackguard() }
-func stack3332() (uintptr, uintptr) { var buf [3332]byte; use(buf[:]); return Stackguard() }
-func stack3336() (uintptr, uintptr) { var buf [3336]byte; use(buf[:]); return Stackguard() }
-func stack3340() (uintptr, uintptr) { var buf [3340]byte; use(buf[:]); return Stackguard() }
-func stack3344() (uintptr, uintptr) { var buf [3344]byte; use(buf[:]); return Stackguard() }
-func stack3348() (uintptr, uintptr) { var buf [3348]byte; use(buf[:]); return Stackguard() }
-func stack3352() (uintptr, uintptr) { var buf [3352]byte; use(buf[:]); return Stackguard() }
-func stack3356() (uintptr, uintptr) { var buf [3356]byte; use(buf[:]); return Stackguard() }
-func stack3360() (uintptr, uintptr) { var buf [3360]byte; use(buf[:]); return Stackguard() }
-func stack3364() (uintptr, uintptr) { var buf [3364]byte; use(buf[:]); return Stackguard() }
-func stack3368() (uintptr, uintptr) { var buf [3368]byte; use(buf[:]); return Stackguard() }
-func stack3372() (uintptr, uintptr) { var buf [3372]byte; use(buf[:]); return Stackguard() }
-func stack3376() (uintptr, uintptr) { var buf [3376]byte; use(buf[:]); return Stackguard() }
-func stack3380() (uintptr, uintptr) { var buf [3380]byte; use(buf[:]); return Stackguard() }
-func stack3384() (uintptr, uintptr) { var buf [3384]byte; use(buf[:]); return Stackguard() }
-func stack3388() (uintptr, uintptr) { var buf [3388]byte; use(buf[:]); return Stackguard() }
-func stack3392() (uintptr, uintptr) { var buf [3392]byte; use(buf[:]); return Stackguard() }
-func stack3396() (uintptr, uintptr) { var buf [3396]byte; use(buf[:]); return Stackguard() }
-func stack3400() (uintptr, uintptr) { var buf [3400]byte; use(buf[:]); return Stackguard() }
-func stack3404() (uintptr, uintptr) { var buf [3404]byte; use(buf[:]); return Stackguard() }
-func stack3408() (uintptr, uintptr) { var buf [3408]byte; use(buf[:]); return Stackguard() }
-func stack3412() (uintptr, uintptr) { var buf [3412]byte; use(buf[:]); return Stackguard() }
-func stack3416() (uintptr, uintptr) { var buf [3416]byte; use(buf[:]); return Stackguard() }
-func stack3420() (uintptr, uintptr) { var buf [3420]byte; use(buf[:]); return Stackguard() }
-func stack3424() (uintptr, uintptr) { var buf [3424]byte; use(buf[:]); return Stackguard() }
-func stack3428() (uintptr, uintptr) { var buf [3428]byte; use(buf[:]); return Stackguard() }
-func stack3432() (uintptr, uintptr) { var buf [3432]byte; use(buf[:]); return Stackguard() }
-func stack3436() (uintptr, uintptr) { var buf [3436]byte; use(buf[:]); return Stackguard() }
-func stack3440() (uintptr, uintptr) { var buf [3440]byte; use(buf[:]); return Stackguard() }
-func stack3444() (uintptr, uintptr) { var buf [3444]byte; use(buf[:]); return Stackguard() }
-func stack3448() (uintptr, uintptr) { var buf [3448]byte; use(buf[:]); return Stackguard() }
-func stack3452() (uintptr, uintptr) { var buf [3452]byte; use(buf[:]); return Stackguard() }
-func stack3456() (uintptr, uintptr) { var buf [3456]byte; use(buf[:]); return Stackguard() }
-func stack3460() (uintptr, uintptr) { var buf [3460]byte; use(buf[:]); return Stackguard() }
-func stack3464() (uintptr, uintptr) { var buf [3464]byte; use(buf[:]); return Stackguard() }
-func stack3468() (uintptr, uintptr) { var buf [3468]byte; use(buf[:]); return Stackguard() }
-func stack3472() (uintptr, uintptr) { var buf [3472]byte; use(buf[:]); return Stackguard() }
-func stack3476() (uintptr, uintptr) { var buf [3476]byte; use(buf[:]); return Stackguard() }
-func stack3480() (uintptr, uintptr) { var buf [3480]byte; use(buf[:]); return Stackguard() }
-func stack3484() (uintptr, uintptr) { var buf [3484]byte; use(buf[:]); return Stackguard() }
-func stack3488() (uintptr, uintptr) { var buf [3488]byte; use(buf[:]); return Stackguard() }
-func stack3492() (uintptr, uintptr) { var buf [3492]byte; use(buf[:]); return Stackguard() }
-func stack3496() (uintptr, uintptr) { var buf [3496]byte; use(buf[:]); return Stackguard() }
-func stack3500() (uintptr, uintptr) { var buf [3500]byte; use(buf[:]); return Stackguard() }
-func stack3504() (uintptr, uintptr) { var buf [3504]byte; use(buf[:]); return Stackguard() }
-func stack3508() (uintptr, uintptr) { var buf [3508]byte; use(buf[:]); return Stackguard() }
-func stack3512() (uintptr, uintptr) { var buf [3512]byte; use(buf[:]); return Stackguard() }
-func stack3516() (uintptr, uintptr) { var buf [3516]byte; use(buf[:]); return Stackguard() }
-func stack3520() (uintptr, uintptr) { var buf [3520]byte; use(buf[:]); return Stackguard() }
-func stack3524() (uintptr, uintptr) { var buf [3524]byte; use(buf[:]); return Stackguard() }
-func stack3528() (uintptr, uintptr) { var buf [3528]byte; use(buf[:]); return Stackguard() }
-func stack3532() (uintptr, uintptr) { var buf [3532]byte; use(buf[:]); return Stackguard() }
-func stack3536() (uintptr, uintptr) { var buf [3536]byte; use(buf[:]); return Stackguard() }
-func stack3540() (uintptr, uintptr) { var buf [3540]byte; use(buf[:]); return Stackguard() }
-func stack3544() (uintptr, uintptr) { var buf [3544]byte; use(buf[:]); return Stackguard() }
-func stack3548() (uintptr, uintptr) { var buf [3548]byte; use(buf[:]); return Stackguard() }
-func stack3552() (uintptr, uintptr) { var buf [3552]byte; use(buf[:]); return Stackguard() }
-func stack3556() (uintptr, uintptr) { var buf [3556]byte; use(buf[:]); return Stackguard() }
-func stack3560() (uintptr, uintptr) { var buf [3560]byte; use(buf[:]); return Stackguard() }
-func stack3564() (uintptr, uintptr) { var buf [3564]byte; use(buf[:]); return Stackguard() }
-func stack3568() (uintptr, uintptr) { var buf [3568]byte; use(buf[:]); return Stackguard() }
-func stack3572() (uintptr, uintptr) { var buf [3572]byte; use(buf[:]); return Stackguard() }
-func stack3576() (uintptr, uintptr) { var buf [3576]byte; use(buf[:]); return Stackguard() }
-func stack3580() (uintptr, uintptr) { var buf [3580]byte; use(buf[:]); return Stackguard() }
-func stack3584() (uintptr, uintptr) { var buf [3584]byte; use(buf[:]); return Stackguard() }
-func stack3588() (uintptr, uintptr) { var buf [3588]byte; use(buf[:]); return Stackguard() }
-func stack3592() (uintptr, uintptr) { var buf [3592]byte; use(buf[:]); return Stackguard() }
-func stack3596() (uintptr, uintptr) { var buf [3596]byte; use(buf[:]); return Stackguard() }
-func stack3600() (uintptr, uintptr) { var buf [3600]byte; use(buf[:]); return Stackguard() }
-func stack3604() (uintptr, uintptr) { var buf [3604]byte; use(buf[:]); return Stackguard() }
-func stack3608() (uintptr, uintptr) { var buf [3608]byte; use(buf[:]); return Stackguard() }
-func stack3612() (uintptr, uintptr) { var buf [3612]byte; use(buf[:]); return Stackguard() }
-func stack3616() (uintptr, uintptr) { var buf [3616]byte; use(buf[:]); return Stackguard() }
-func stack3620() (uintptr, uintptr) { var buf [3620]byte; use(buf[:]); return Stackguard() }
-func stack3624() (uintptr, uintptr) { var buf [3624]byte; use(buf[:]); return Stackguard() }
-func stack3628() (uintptr, uintptr) { var buf [3628]byte; use(buf[:]); return Stackguard() }
-func stack3632() (uintptr, uintptr) { var buf [3632]byte; use(buf[:]); return Stackguard() }
-func stack3636() (uintptr, uintptr) { var buf [3636]byte; use(buf[:]); return Stackguard() }
-func stack3640() (uintptr, uintptr) { var buf [3640]byte; use(buf[:]); return Stackguard() }
-func stack3644() (uintptr, uintptr) { var buf [3644]byte; use(buf[:]); return Stackguard() }
-func stack3648() (uintptr, uintptr) { var buf [3648]byte; use(buf[:]); return Stackguard() }
-func stack3652() (uintptr, uintptr) { var buf [3652]byte; use(buf[:]); return Stackguard() }
-func stack3656() (uintptr, uintptr) { var buf [3656]byte; use(buf[:]); return Stackguard() }
-func stack3660() (uintptr, uintptr) { var buf [3660]byte; use(buf[:]); return Stackguard() }
-func stack3664() (uintptr, uintptr) { var buf [3664]byte; use(buf[:]); return Stackguard() }
-func stack3668() (uintptr, uintptr) { var buf [3668]byte; use(buf[:]); return Stackguard() }
-func stack3672() (uintptr, uintptr) { var buf [3672]byte; use(buf[:]); return Stackguard() }
-func stack3676() (uintptr, uintptr) { var buf [3676]byte; use(buf[:]); return Stackguard() }
-func stack3680() (uintptr, uintptr) { var buf [3680]byte; use(buf[:]); return Stackguard() }
-func stack3684() (uintptr, uintptr) { var buf [3684]byte; use(buf[:]); return Stackguard() }
-func stack3688() (uintptr, uintptr) { var buf [3688]byte; use(buf[:]); return Stackguard() }
-func stack3692() (uintptr, uintptr) { var buf [3692]byte; use(buf[:]); return Stackguard() }
-func stack3696() (uintptr, uintptr) { var buf [3696]byte; use(buf[:]); return Stackguard() }
-func stack3700() (uintptr, uintptr) { var buf [3700]byte; use(buf[:]); return Stackguard() }
-func stack3704() (uintptr, uintptr) { var buf [3704]byte; use(buf[:]); return Stackguard() }
-func stack3708() (uintptr, uintptr) { var buf [3708]byte; use(buf[:]); return Stackguard() }
-func stack3712() (uintptr, uintptr) { var buf [3712]byte; use(buf[:]); return Stackguard() }
-func stack3716() (uintptr, uintptr) { var buf [3716]byte; use(buf[:]); return Stackguard() }
-func stack3720() (uintptr, uintptr) { var buf [3720]byte; use(buf[:]); return Stackguard() }
-func stack3724() (uintptr, uintptr) { var buf [3724]byte; use(buf[:]); return Stackguard() }
-func stack3728() (uintptr, uintptr) { var buf [3728]byte; use(buf[:]); return Stackguard() }
-func stack3732() (uintptr, uintptr) { var buf [3732]byte; use(buf[:]); return Stackguard() }
-func stack3736() (uintptr, uintptr) { var buf [3736]byte; use(buf[:]); return Stackguard() }
-func stack3740() (uintptr, uintptr) { var buf [3740]byte; use(buf[:]); return Stackguard() }
-func stack3744() (uintptr, uintptr) { var buf [3744]byte; use(buf[:]); return Stackguard() }
-func stack3748() (uintptr, uintptr) { var buf [3748]byte; use(buf[:]); return Stackguard() }
-func stack3752() (uintptr, uintptr) { var buf [3752]byte; use(buf[:]); return Stackguard() }
-func stack3756() (uintptr, uintptr) { var buf [3756]byte; use(buf[:]); return Stackguard() }
-func stack3760() (uintptr, uintptr) { var buf [3760]byte; use(buf[:]); return Stackguard() }
-func stack3764() (uintptr, uintptr) { var buf [3764]byte; use(buf[:]); return Stackguard() }
-func stack3768() (uintptr, uintptr) { var buf [3768]byte; use(buf[:]); return Stackguard() }
-func stack3772() (uintptr, uintptr) { var buf [3772]byte; use(buf[:]); return Stackguard() }
-func stack3776() (uintptr, uintptr) { var buf [3776]byte; use(buf[:]); return Stackguard() }
-func stack3780() (uintptr, uintptr) { var buf [3780]byte; use(buf[:]); return Stackguard() }
-func stack3784() (uintptr, uintptr) { var buf [3784]byte; use(buf[:]); return Stackguard() }
-func stack3788() (uintptr, uintptr) { var buf [3788]byte; use(buf[:]); return Stackguard() }
-func stack3792() (uintptr, uintptr) { var buf [3792]byte; use(buf[:]); return Stackguard() }
-func stack3796() (uintptr, uintptr) { var buf [3796]byte; use(buf[:]); return Stackguard() }
-func stack3800() (uintptr, uintptr) { var buf [3800]byte; use(buf[:]); return Stackguard() }
-func stack3804() (uintptr, uintptr) { var buf [3804]byte; use(buf[:]); return Stackguard() }
-func stack3808() (uintptr, uintptr) { var buf [3808]byte; use(buf[:]); return Stackguard() }
-func stack3812() (uintptr, uintptr) { var buf [3812]byte; use(buf[:]); return Stackguard() }
-func stack3816() (uintptr, uintptr) { var buf [3816]byte; use(buf[:]); return Stackguard() }
-func stack3820() (uintptr, uintptr) { var buf [3820]byte; use(buf[:]); return Stackguard() }
-func stack3824() (uintptr, uintptr) { var buf [3824]byte; use(buf[:]); return Stackguard() }
-func stack3828() (uintptr, uintptr) { var buf [3828]byte; use(buf[:]); return Stackguard() }
-func stack3832() (uintptr, uintptr) { var buf [3832]byte; use(buf[:]); return Stackguard() }
-func stack3836() (uintptr, uintptr) { var buf [3836]byte; use(buf[:]); return Stackguard() }
-func stack3840() (uintptr, uintptr) { var buf [3840]byte; use(buf[:]); return Stackguard() }
-func stack3844() (uintptr, uintptr) { var buf [3844]byte; use(buf[:]); return Stackguard() }
-func stack3848() (uintptr, uintptr) { var buf [3848]byte; use(buf[:]); return Stackguard() }
-func stack3852() (uintptr, uintptr) { var buf [3852]byte; use(buf[:]); return Stackguard() }
-func stack3856() (uintptr, uintptr) { var buf [3856]byte; use(buf[:]); return Stackguard() }
-func stack3860() (uintptr, uintptr) { var buf [3860]byte; use(buf[:]); return Stackguard() }
-func stack3864() (uintptr, uintptr) { var buf [3864]byte; use(buf[:]); return Stackguard() }
-func stack3868() (uintptr, uintptr) { var buf [3868]byte; use(buf[:]); return Stackguard() }
-func stack3872() (uintptr, uintptr) { var buf [3872]byte; use(buf[:]); return Stackguard() }
-func stack3876() (uintptr, uintptr) { var buf [3876]byte; use(buf[:]); return Stackguard() }
-func stack3880() (uintptr, uintptr) { var buf [3880]byte; use(buf[:]); return Stackguard() }
-func stack3884() (uintptr, uintptr) { var buf [3884]byte; use(buf[:]); return Stackguard() }
-func stack3888() (uintptr, uintptr) { var buf [3888]byte; use(buf[:]); return Stackguard() }
-func stack3892() (uintptr, uintptr) { var buf [3892]byte; use(buf[:]); return Stackguard() }
-func stack3896() (uintptr, uintptr) { var buf [3896]byte; use(buf[:]); return Stackguard() }
-func stack3900() (uintptr, uintptr) { var buf [3900]byte; use(buf[:]); return Stackguard() }
-func stack3904() (uintptr, uintptr) { var buf [3904]byte; use(buf[:]); return Stackguard() }
-func stack3908() (uintptr, uintptr) { var buf [3908]byte; use(buf[:]); return Stackguard() }
-func stack3912() (uintptr, uintptr) { var buf [3912]byte; use(buf[:]); return Stackguard() }
-func stack3916() (uintptr, uintptr) { var buf [3916]byte; use(buf[:]); return Stackguard() }
-func stack3920() (uintptr, uintptr) { var buf [3920]byte; use(buf[:]); return Stackguard() }
-func stack3924() (uintptr, uintptr) { var buf [3924]byte; use(buf[:]); return Stackguard() }
-func stack3928() (uintptr, uintptr) { var buf [3928]byte; use(buf[:]); return Stackguard() }
-func stack3932() (uintptr, uintptr) { var buf [3932]byte; use(buf[:]); return Stackguard() }
-func stack3936() (uintptr, uintptr) { var buf [3936]byte; use(buf[:]); return Stackguard() }
-func stack3940() (uintptr, uintptr) { var buf [3940]byte; use(buf[:]); return Stackguard() }
-func stack3944() (uintptr, uintptr) { var buf [3944]byte; use(buf[:]); return Stackguard() }
-func stack3948() (uintptr, uintptr) { var buf [3948]byte; use(buf[:]); return Stackguard() }
-func stack3952() (uintptr, uintptr) { var buf [3952]byte; use(buf[:]); return Stackguard() }
-func stack3956() (uintptr, uintptr) { var buf [3956]byte; use(buf[:]); return Stackguard() }
-func stack3960() (uintptr, uintptr) { var buf [3960]byte; use(buf[:]); return Stackguard() }
-func stack3964() (uintptr, uintptr) { var buf [3964]byte; use(buf[:]); return Stackguard() }
-func stack3968() (uintptr, uintptr) { var buf [3968]byte; use(buf[:]); return Stackguard() }
-func stack3972() (uintptr, uintptr) { var buf [3972]byte; use(buf[:]); return Stackguard() }
-func stack3976() (uintptr, uintptr) { var buf [3976]byte; use(buf[:]); return Stackguard() }
-func stack3980() (uintptr, uintptr) { var buf [3980]byte; use(buf[:]); return Stackguard() }
-func stack3984() (uintptr, uintptr) { var buf [3984]byte; use(buf[:]); return Stackguard() }
-func stack3988() (uintptr, uintptr) { var buf [3988]byte; use(buf[:]); return Stackguard() }
-func stack3992() (uintptr, uintptr) { var buf [3992]byte; use(buf[:]); return Stackguard() }
-func stack3996() (uintptr, uintptr) { var buf [3996]byte; use(buf[:]); return Stackguard() }
-func stack4000() (uintptr, uintptr) { var buf [4000]byte; use(buf[:]); return Stackguard() }
-func stack4004() (uintptr, uintptr) { var buf [4004]byte; use(buf[:]); return Stackguard() }
-func stack4008() (uintptr, uintptr) { var buf [4008]byte; use(buf[:]); return Stackguard() }
-func stack4012() (uintptr, uintptr) { var buf [4012]byte; use(buf[:]); return Stackguard() }
-func stack4016() (uintptr, uintptr) { var buf [4016]byte; use(buf[:]); return Stackguard() }
-func stack4020() (uintptr, uintptr) { var buf [4020]byte; use(buf[:]); return Stackguard() }
-func stack4024() (uintptr, uintptr) { var buf [4024]byte; use(buf[:]); return Stackguard() }
-func stack4028() (uintptr, uintptr) { var buf [4028]byte; use(buf[:]); return Stackguard() }
-func stack4032() (uintptr, uintptr) { var buf [4032]byte; use(buf[:]); return Stackguard() }
-func stack4036() (uintptr, uintptr) { var buf [4036]byte; use(buf[:]); return Stackguard() }
-func stack4040() (uintptr, uintptr) { var buf [4040]byte; use(buf[:]); return Stackguard() }
-func stack4044() (uintptr, uintptr) { var buf [4044]byte; use(buf[:]); return Stackguard() }
-func stack4048() (uintptr, uintptr) { var buf [4048]byte; use(buf[:]); return Stackguard() }
-func stack4052() (uintptr, uintptr) { var buf [4052]byte; use(buf[:]); return Stackguard() }
-func stack4056() (uintptr, uintptr) { var buf [4056]byte; use(buf[:]); return Stackguard() }
-func stack4060() (uintptr, uintptr) { var buf [4060]byte; use(buf[:]); return Stackguard() }
-func stack4064() (uintptr, uintptr) { var buf [4064]byte; use(buf[:]); return Stackguard() }
-func stack4068() (uintptr, uintptr) { var buf [4068]byte; use(buf[:]); return Stackguard() }
-func stack4072() (uintptr, uintptr) { var buf [4072]byte; use(buf[:]); return Stackguard() }
-func stack4076() (uintptr, uintptr) { var buf [4076]byte; use(buf[:]); return Stackguard() }
-func stack4080() (uintptr, uintptr) { var buf [4080]byte; use(buf[:]); return Stackguard() }
-func stack4084() (uintptr, uintptr) { var buf [4084]byte; use(buf[:]); return Stackguard() }
-func stack4088() (uintptr, uintptr) { var buf [4088]byte; use(buf[:]); return Stackguard() }
-func stack4092() (uintptr, uintptr) { var buf [4092]byte; use(buf[:]); return Stackguard() }
-func stack4096() (uintptr, uintptr) { var buf [4096]byte; use(buf[:]); return Stackguard() }
-func stack4100() (uintptr, uintptr) { var buf [4100]byte; use(buf[:]); return Stackguard() }
-func stack4104() (uintptr, uintptr) { var buf [4104]byte; use(buf[:]); return Stackguard() }
-func stack4108() (uintptr, uintptr) { var buf [4108]byte; use(buf[:]); return Stackguard() }
-func stack4112() (uintptr, uintptr) { var buf [4112]byte; use(buf[:]); return Stackguard() }
-func stack4116() (uintptr, uintptr) { var buf [4116]byte; use(buf[:]); return Stackguard() }
-func stack4120() (uintptr, uintptr) { var buf [4120]byte; use(buf[:]); return Stackguard() }
-func stack4124() (uintptr, uintptr) { var buf [4124]byte; use(buf[:]); return Stackguard() }
-func stack4128() (uintptr, uintptr) { var buf [4128]byte; use(buf[:]); return Stackguard() }
-func stack4132() (uintptr, uintptr) { var buf [4132]byte; use(buf[:]); return Stackguard() }
-func stack4136() (uintptr, uintptr) { var buf [4136]byte; use(buf[:]); return Stackguard() }
-func stack4140() (uintptr, uintptr) { var buf [4140]byte; use(buf[:]); return Stackguard() }
-func stack4144() (uintptr, uintptr) { var buf [4144]byte; use(buf[:]); return Stackguard() }
-func stack4148() (uintptr, uintptr) { var buf [4148]byte; use(buf[:]); return Stackguard() }
-func stack4152() (uintptr, uintptr) { var buf [4152]byte; use(buf[:]); return Stackguard() }
-func stack4156() (uintptr, uintptr) { var buf [4156]byte; use(buf[:]); return Stackguard() }
-func stack4160() (uintptr, uintptr) { var buf [4160]byte; use(buf[:]); return Stackguard() }
-func stack4164() (uintptr, uintptr) { var buf [4164]byte; use(buf[:]); return Stackguard() }
-func stack4168() (uintptr, uintptr) { var buf [4168]byte; use(buf[:]); return Stackguard() }
-func stack4172() (uintptr, uintptr) { var buf [4172]byte; use(buf[:]); return Stackguard() }
-func stack4176() (uintptr, uintptr) { var buf [4176]byte; use(buf[:]); return Stackguard() }
-func stack4180() (uintptr, uintptr) { var buf [4180]byte; use(buf[:]); return Stackguard() }
-func stack4184() (uintptr, uintptr) { var buf [4184]byte; use(buf[:]); return Stackguard() }
-func stack4188() (uintptr, uintptr) { var buf [4188]byte; use(buf[:]); return Stackguard() }
-func stack4192() (uintptr, uintptr) { var buf [4192]byte; use(buf[:]); return Stackguard() }
-func stack4196() (uintptr, uintptr) { var buf [4196]byte; use(buf[:]); return Stackguard() }
-func stack4200() (uintptr, uintptr) { var buf [4200]byte; use(buf[:]); return Stackguard() }
-func stack4204() (uintptr, uintptr) { var buf [4204]byte; use(buf[:]); return Stackguard() }
-func stack4208() (uintptr, uintptr) { var buf [4208]byte; use(buf[:]); return Stackguard() }
-func stack4212() (uintptr, uintptr) { var buf [4212]byte; use(buf[:]); return Stackguard() }
-func stack4216() (uintptr, uintptr) { var buf [4216]byte; use(buf[:]); return Stackguard() }
-func stack4220() (uintptr, uintptr) { var buf [4220]byte; use(buf[:]); return Stackguard() }
-func stack4224() (uintptr, uintptr) { var buf [4224]byte; use(buf[:]); return Stackguard() }
-func stack4228() (uintptr, uintptr) { var buf [4228]byte; use(buf[:]); return Stackguard() }
-func stack4232() (uintptr, uintptr) { var buf [4232]byte; use(buf[:]); return Stackguard() }
-func stack4236() (uintptr, uintptr) { var buf [4236]byte; use(buf[:]); return Stackguard() }
-func stack4240() (uintptr, uintptr) { var buf [4240]byte; use(buf[:]); return Stackguard() }
-func stack4244() (uintptr, uintptr) { var buf [4244]byte; use(buf[:]); return Stackguard() }
-func stack4248() (uintptr, uintptr) { var buf [4248]byte; use(buf[:]); return Stackguard() }
-func stack4252() (uintptr, uintptr) { var buf [4252]byte; use(buf[:]); return Stackguard() }
-func stack4256() (uintptr, uintptr) { var buf [4256]byte; use(buf[:]); return Stackguard() }
-func stack4260() (uintptr, uintptr) { var buf [4260]byte; use(buf[:]); return Stackguard() }
-func stack4264() (uintptr, uintptr) { var buf [4264]byte; use(buf[:]); return Stackguard() }
-func stack4268() (uintptr, uintptr) { var buf [4268]byte; use(buf[:]); return Stackguard() }
-func stack4272() (uintptr, uintptr) { var buf [4272]byte; use(buf[:]); return Stackguard() }
-func stack4276() (uintptr, uintptr) { var buf [4276]byte; use(buf[:]); return Stackguard() }
-func stack4280() (uintptr, uintptr) { var buf [4280]byte; use(buf[:]); return Stackguard() }
-func stack4284() (uintptr, uintptr) { var buf [4284]byte; use(buf[:]); return Stackguard() }
-func stack4288() (uintptr, uintptr) { var buf [4288]byte; use(buf[:]); return Stackguard() }
-func stack4292() (uintptr, uintptr) { var buf [4292]byte; use(buf[:]); return Stackguard() }
-func stack4296() (uintptr, uintptr) { var buf [4296]byte; use(buf[:]); return Stackguard() }
-func stack4300() (uintptr, uintptr) { var buf [4300]byte; use(buf[:]); return Stackguard() }
-func stack4304() (uintptr, uintptr) { var buf [4304]byte; use(buf[:]); return Stackguard() }
-func stack4308() (uintptr, uintptr) { var buf [4308]byte; use(buf[:]); return Stackguard() }
-func stack4312() (uintptr, uintptr) { var buf [4312]byte; use(buf[:]); return Stackguard() }
-func stack4316() (uintptr, uintptr) { var buf [4316]byte; use(buf[:]); return Stackguard() }
-func stack4320() (uintptr, uintptr) { var buf [4320]byte; use(buf[:]); return Stackguard() }
-func stack4324() (uintptr, uintptr) { var buf [4324]byte; use(buf[:]); return Stackguard() }
-func stack4328() (uintptr, uintptr) { var buf [4328]byte; use(buf[:]); return Stackguard() }
-func stack4332() (uintptr, uintptr) { var buf [4332]byte; use(buf[:]); return Stackguard() }
-func stack4336() (uintptr, uintptr) { var buf [4336]byte; use(buf[:]); return Stackguard() }
-func stack4340() (uintptr, uintptr) { var buf [4340]byte; use(buf[:]); return Stackguard() }
-func stack4344() (uintptr, uintptr) { var buf [4344]byte; use(buf[:]); return Stackguard() }
-func stack4348() (uintptr, uintptr) { var buf [4348]byte; use(buf[:]); return Stackguard() }
-func stack4352() (uintptr, uintptr) { var buf [4352]byte; use(buf[:]); return Stackguard() }
-func stack4356() (uintptr, uintptr) { var buf [4356]byte; use(buf[:]); return Stackguard() }
-func stack4360() (uintptr, uintptr) { var buf [4360]byte; use(buf[:]); return Stackguard() }
-func stack4364() (uintptr, uintptr) { var buf [4364]byte; use(buf[:]); return Stackguard() }
-func stack4368() (uintptr, uintptr) { var buf [4368]byte; use(buf[:]); return Stackguard() }
-func stack4372() (uintptr, uintptr) { var buf [4372]byte; use(buf[:]); return Stackguard() }
-func stack4376() (uintptr, uintptr) { var buf [4376]byte; use(buf[:]); return Stackguard() }
-func stack4380() (uintptr, uintptr) { var buf [4380]byte; use(buf[:]); return Stackguard() }
-func stack4384() (uintptr, uintptr) { var buf [4384]byte; use(buf[:]); return Stackguard() }
-func stack4388() (uintptr, uintptr) { var buf [4388]byte; use(buf[:]); return Stackguard() }
-func stack4392() (uintptr, uintptr) { var buf [4392]byte; use(buf[:]); return Stackguard() }
-func stack4396() (uintptr, uintptr) { var buf [4396]byte; use(buf[:]); return Stackguard() }
-func stack4400() (uintptr, uintptr) { var buf [4400]byte; use(buf[:]); return Stackguard() }
-func stack4404() (uintptr, uintptr) { var buf [4404]byte; use(buf[:]); return Stackguard() }
-func stack4408() (uintptr, uintptr) { var buf [4408]byte; use(buf[:]); return Stackguard() }
-func stack4412() (uintptr, uintptr) { var buf [4412]byte; use(buf[:]); return Stackguard() }
-func stack4416() (uintptr, uintptr) { var buf [4416]byte; use(buf[:]); return Stackguard() }
-func stack4420() (uintptr, uintptr) { var buf [4420]byte; use(buf[:]); return Stackguard() }
-func stack4424() (uintptr, uintptr) { var buf [4424]byte; use(buf[:]); return Stackguard() }
-func stack4428() (uintptr, uintptr) { var buf [4428]byte; use(buf[:]); return Stackguard() }
-func stack4432() (uintptr, uintptr) { var buf [4432]byte; use(buf[:]); return Stackguard() }
-func stack4436() (uintptr, uintptr) { var buf [4436]byte; use(buf[:]); return Stackguard() }
-func stack4440() (uintptr, uintptr) { var buf [4440]byte; use(buf[:]); return Stackguard() }
-func stack4444() (uintptr, uintptr) { var buf [4444]byte; use(buf[:]); return Stackguard() }
-func stack4448() (uintptr, uintptr) { var buf [4448]byte; use(buf[:]); return Stackguard() }
-func stack4452() (uintptr, uintptr) { var buf [4452]byte; use(buf[:]); return Stackguard() }
-func stack4456() (uintptr, uintptr) { var buf [4456]byte; use(buf[:]); return Stackguard() }
-func stack4460() (uintptr, uintptr) { var buf [4460]byte; use(buf[:]); return Stackguard() }
-func stack4464() (uintptr, uintptr) { var buf [4464]byte; use(buf[:]); return Stackguard() }
-func stack4468() (uintptr, uintptr) { var buf [4468]byte; use(buf[:]); return Stackguard() }
-func stack4472() (uintptr, uintptr) { var buf [4472]byte; use(buf[:]); return Stackguard() }
-func stack4476() (uintptr, uintptr) { var buf [4476]byte; use(buf[:]); return Stackguard() }
-func stack4480() (uintptr, uintptr) { var buf [4480]byte; use(buf[:]); return Stackguard() }
-func stack4484() (uintptr, uintptr) { var buf [4484]byte; use(buf[:]); return Stackguard() }
-func stack4488() (uintptr, uintptr) { var buf [4488]byte; use(buf[:]); return Stackguard() }
-func stack4492() (uintptr, uintptr) { var buf [4492]byte; use(buf[:]); return Stackguard() }
-func stack4496() (uintptr, uintptr) { var buf [4496]byte; use(buf[:]); return Stackguard() }
-func stack4500() (uintptr, uintptr) { var buf [4500]byte; use(buf[:]); return Stackguard() }
-func stack4504() (uintptr, uintptr) { var buf [4504]byte; use(buf[:]); return Stackguard() }
-func stack4508() (uintptr, uintptr) { var buf [4508]byte; use(buf[:]); return Stackguard() }
-func stack4512() (uintptr, uintptr) { var buf [4512]byte; use(buf[:]); return Stackguard() }
-func stack4516() (uintptr, uintptr) { var buf [4516]byte; use(buf[:]); return Stackguard() }
-func stack4520() (uintptr, uintptr) { var buf [4520]byte; use(buf[:]); return Stackguard() }
-func stack4524() (uintptr, uintptr) { var buf [4524]byte; use(buf[:]); return Stackguard() }
-func stack4528() (uintptr, uintptr) { var buf [4528]byte; use(buf[:]); return Stackguard() }
-func stack4532() (uintptr, uintptr) { var buf [4532]byte; use(buf[:]); return Stackguard() }
-func stack4536() (uintptr, uintptr) { var buf [4536]byte; use(buf[:]); return Stackguard() }
-func stack4540() (uintptr, uintptr) { var buf [4540]byte; use(buf[:]); return Stackguard() }
-func stack4544() (uintptr, uintptr) { var buf [4544]byte; use(buf[:]); return Stackguard() }
-func stack4548() (uintptr, uintptr) { var buf [4548]byte; use(buf[:]); return Stackguard() }
-func stack4552() (uintptr, uintptr) { var buf [4552]byte; use(buf[:]); return Stackguard() }
-func stack4556() (uintptr, uintptr) { var buf [4556]byte; use(buf[:]); return Stackguard() }
-func stack4560() (uintptr, uintptr) { var buf [4560]byte; use(buf[:]); return Stackguard() }
-func stack4564() (uintptr, uintptr) { var buf [4564]byte; use(buf[:]); return Stackguard() }
-func stack4568() (uintptr, uintptr) { var buf [4568]byte; use(buf[:]); return Stackguard() }
-func stack4572() (uintptr, uintptr) { var buf [4572]byte; use(buf[:]); return Stackguard() }
-func stack4576() (uintptr, uintptr) { var buf [4576]byte; use(buf[:]); return Stackguard() }
-func stack4580() (uintptr, uintptr) { var buf [4580]byte; use(buf[:]); return Stackguard() }
-func stack4584() (uintptr, uintptr) { var buf [4584]byte; use(buf[:]); return Stackguard() }
-func stack4588() (uintptr, uintptr) { var buf [4588]byte; use(buf[:]); return Stackguard() }
-func stack4592() (uintptr, uintptr) { var buf [4592]byte; use(buf[:]); return Stackguard() }
-func stack4596() (uintptr, uintptr) { var buf [4596]byte; use(buf[:]); return Stackguard() }
-func stack4600() (uintptr, uintptr) { var buf [4600]byte; use(buf[:]); return Stackguard() }
-func stack4604() (uintptr, uintptr) { var buf [4604]byte; use(buf[:]); return Stackguard() }
-func stack4608() (uintptr, uintptr) { var buf [4608]byte; use(buf[:]); return Stackguard() }
-func stack4612() (uintptr, uintptr) { var buf [4612]byte; use(buf[:]); return Stackguard() }
-func stack4616() (uintptr, uintptr) { var buf [4616]byte; use(buf[:]); return Stackguard() }
-func stack4620() (uintptr, uintptr) { var buf [4620]byte; use(buf[:]); return Stackguard() }
-func stack4624() (uintptr, uintptr) { var buf [4624]byte; use(buf[:]); return Stackguard() }
-func stack4628() (uintptr, uintptr) { var buf [4628]byte; use(buf[:]); return Stackguard() }
-func stack4632() (uintptr, uintptr) { var buf [4632]byte; use(buf[:]); return Stackguard() }
-func stack4636() (uintptr, uintptr) { var buf [4636]byte; use(buf[:]); return Stackguard() }
-func stack4640() (uintptr, uintptr) { var buf [4640]byte; use(buf[:]); return Stackguard() }
-func stack4644() (uintptr, uintptr) { var buf [4644]byte; use(buf[:]); return Stackguard() }
-func stack4648() (uintptr, uintptr) { var buf [4648]byte; use(buf[:]); return Stackguard() }
-func stack4652() (uintptr, uintptr) { var buf [4652]byte; use(buf[:]); return Stackguard() }
-func stack4656() (uintptr, uintptr) { var buf [4656]byte; use(buf[:]); return Stackguard() }
-func stack4660() (uintptr, uintptr) { var buf [4660]byte; use(buf[:]); return Stackguard() }
-func stack4664() (uintptr, uintptr) { var buf [4664]byte; use(buf[:]); return Stackguard() }
-func stack4668() (uintptr, uintptr) { var buf [4668]byte; use(buf[:]); return Stackguard() }
-func stack4672() (uintptr, uintptr) { var buf [4672]byte; use(buf[:]); return Stackguard() }
-func stack4676() (uintptr, uintptr) { var buf [4676]byte; use(buf[:]); return Stackguard() }
-func stack4680() (uintptr, uintptr) { var buf [4680]byte; use(buf[:]); return Stackguard() }
-func stack4684() (uintptr, uintptr) { var buf [4684]byte; use(buf[:]); return Stackguard() }
-func stack4688() (uintptr, uintptr) { var buf [4688]byte; use(buf[:]); return Stackguard() }
-func stack4692() (uintptr, uintptr) { var buf [4692]byte; use(buf[:]); return Stackguard() }
-func stack4696() (uintptr, uintptr) { var buf [4696]byte; use(buf[:]); return Stackguard() }
-func stack4700() (uintptr, uintptr) { var buf [4700]byte; use(buf[:]); return Stackguard() }
-func stack4704() (uintptr, uintptr) { var buf [4704]byte; use(buf[:]); return Stackguard() }
-func stack4708() (uintptr, uintptr) { var buf [4708]byte; use(buf[:]); return Stackguard() }
-func stack4712() (uintptr, uintptr) { var buf [4712]byte; use(buf[:]); return Stackguard() }
-func stack4716() (uintptr, uintptr) { var buf [4716]byte; use(buf[:]); return Stackguard() }
-func stack4720() (uintptr, uintptr) { var buf [4720]byte; use(buf[:]); return Stackguard() }
-func stack4724() (uintptr, uintptr) { var buf [4724]byte; use(buf[:]); return Stackguard() }
-func stack4728() (uintptr, uintptr) { var buf [4728]byte; use(buf[:]); return Stackguard() }
-func stack4732() (uintptr, uintptr) { var buf [4732]byte; use(buf[:]); return Stackguard() }
-func stack4736() (uintptr, uintptr) { var buf [4736]byte; use(buf[:]); return Stackguard() }
-func stack4740() (uintptr, uintptr) { var buf [4740]byte; use(buf[:]); return Stackguard() }
-func stack4744() (uintptr, uintptr) { var buf [4744]byte; use(buf[:]); return Stackguard() }
-func stack4748() (uintptr, uintptr) { var buf [4748]byte; use(buf[:]); return Stackguard() }
-func stack4752() (uintptr, uintptr) { var buf [4752]byte; use(buf[:]); return Stackguard() }
-func stack4756() (uintptr, uintptr) { var buf [4756]byte; use(buf[:]); return Stackguard() }
-func stack4760() (uintptr, uintptr) { var buf [4760]byte; use(buf[:]); return Stackguard() }
-func stack4764() (uintptr, uintptr) { var buf [4764]byte; use(buf[:]); return Stackguard() }
-func stack4768() (uintptr, uintptr) { var buf [4768]byte; use(buf[:]); return Stackguard() }
-func stack4772() (uintptr, uintptr) { var buf [4772]byte; use(buf[:]); return Stackguard() }
-func stack4776() (uintptr, uintptr) { var buf [4776]byte; use(buf[:]); return Stackguard() }
-func stack4780() (uintptr, uintptr) { var buf [4780]byte; use(buf[:]); return Stackguard() }
-func stack4784() (uintptr, uintptr) { var buf [4784]byte; use(buf[:]); return Stackguard() }
-func stack4788() (uintptr, uintptr) { var buf [4788]byte; use(buf[:]); return Stackguard() }
-func stack4792() (uintptr, uintptr) { var buf [4792]byte; use(buf[:]); return Stackguard() }
-func stack4796() (uintptr, uintptr) { var buf [4796]byte; use(buf[:]); return Stackguard() }
-func stack4800() (uintptr, uintptr) { var buf [4800]byte; use(buf[:]); return Stackguard() }
-func stack4804() (uintptr, uintptr) { var buf [4804]byte; use(buf[:]); return Stackguard() }
-func stack4808() (uintptr, uintptr) { var buf [4808]byte; use(buf[:]); return Stackguard() }
-func stack4812() (uintptr, uintptr) { var buf [4812]byte; use(buf[:]); return Stackguard() }
-func stack4816() (uintptr, uintptr) { var buf [4816]byte; use(buf[:]); return Stackguard() }
-func stack4820() (uintptr, uintptr) { var buf [4820]byte; use(buf[:]); return Stackguard() }
-func stack4824() (uintptr, uintptr) { var buf [4824]byte; use(buf[:]); return Stackguard() }
-func stack4828() (uintptr, uintptr) { var buf [4828]byte; use(buf[:]); return Stackguard() }
-func stack4832() (uintptr, uintptr) { var buf [4832]byte; use(buf[:]); return Stackguard() }
-func stack4836() (uintptr, uintptr) { var buf [4836]byte; use(buf[:]); return Stackguard() }
-func stack4840() (uintptr, uintptr) { var buf [4840]byte; use(buf[:]); return Stackguard() }
-func stack4844() (uintptr, uintptr) { var buf [4844]byte; use(buf[:]); return Stackguard() }
-func stack4848() (uintptr, uintptr) { var buf [4848]byte; use(buf[:]); return Stackguard() }
-func stack4852() (uintptr, uintptr) { var buf [4852]byte; use(buf[:]); return Stackguard() }
-func stack4856() (uintptr, uintptr) { var buf [4856]byte; use(buf[:]); return Stackguard() }
-func stack4860() (uintptr, uintptr) { var buf [4860]byte; use(buf[:]); return Stackguard() }
-func stack4864() (uintptr, uintptr) { var buf [4864]byte; use(buf[:]); return Stackguard() }
-func stack4868() (uintptr, uintptr) { var buf [4868]byte; use(buf[:]); return Stackguard() }
-func stack4872() (uintptr, uintptr) { var buf [4872]byte; use(buf[:]); return Stackguard() }
-func stack4876() (uintptr, uintptr) { var buf [4876]byte; use(buf[:]); return Stackguard() }
-func stack4880() (uintptr, uintptr) { var buf [4880]byte; use(buf[:]); return Stackguard() }
-func stack4884() (uintptr, uintptr) { var buf [4884]byte; use(buf[:]); return Stackguard() }
-func stack4888() (uintptr, uintptr) { var buf [4888]byte; use(buf[:]); return Stackguard() }
-func stack4892() (uintptr, uintptr) { var buf [4892]byte; use(buf[:]); return Stackguard() }
-func stack4896() (uintptr, uintptr) { var buf [4896]byte; use(buf[:]); return Stackguard() }
-func stack4900() (uintptr, uintptr) { var buf [4900]byte; use(buf[:]); return Stackguard() }
-func stack4904() (uintptr, uintptr) { var buf [4904]byte; use(buf[:]); return Stackguard() }
-func stack4908() (uintptr, uintptr) { var buf [4908]byte; use(buf[:]); return Stackguard() }
-func stack4912() (uintptr, uintptr) { var buf [4912]byte; use(buf[:]); return Stackguard() }
-func stack4916() (uintptr, uintptr) { var buf [4916]byte; use(buf[:]); return Stackguard() }
-func stack4920() (uintptr, uintptr) { var buf [4920]byte; use(buf[:]); return Stackguard() }
-func stack4924() (uintptr, uintptr) { var buf [4924]byte; use(buf[:]); return Stackguard() }
-func stack4928() (uintptr, uintptr) { var buf [4928]byte; use(buf[:]); return Stackguard() }
-func stack4932() (uintptr, uintptr) { var buf [4932]byte; use(buf[:]); return Stackguard() }
-func stack4936() (uintptr, uintptr) { var buf [4936]byte; use(buf[:]); return Stackguard() }
-func stack4940() (uintptr, uintptr) { var buf [4940]byte; use(buf[:]); return Stackguard() }
-func stack4944() (uintptr, uintptr) { var buf [4944]byte; use(buf[:]); return Stackguard() }
-func stack4948() (uintptr, uintptr) { var buf [4948]byte; use(buf[:]); return Stackguard() }
-func stack4952() (uintptr, uintptr) { var buf [4952]byte; use(buf[:]); return Stackguard() }
-func stack4956() (uintptr, uintptr) { var buf [4956]byte; use(buf[:]); return Stackguard() }
-func stack4960() (uintptr, uintptr) { var buf [4960]byte; use(buf[:]); return Stackguard() }
-func stack4964() (uintptr, uintptr) { var buf [4964]byte; use(buf[:]); return Stackguard() }
-func stack4968() (uintptr, uintptr) { var buf [4968]byte; use(buf[:]); return Stackguard() }
-func stack4972() (uintptr, uintptr) { var buf [4972]byte; use(buf[:]); return Stackguard() }
-func stack4976() (uintptr, uintptr) { var buf [4976]byte; use(buf[:]); return Stackguard() }
-func stack4980() (uintptr, uintptr) { var buf [4980]byte; use(buf[:]); return Stackguard() }
-func stack4984() (uintptr, uintptr) { var buf [4984]byte; use(buf[:]); return Stackguard() }
-func stack4988() (uintptr, uintptr) { var buf [4988]byte; use(buf[:]); return Stackguard() }
-func stack4992() (uintptr, uintptr) { var buf [4992]byte; use(buf[:]); return Stackguard() }
-func stack4996() (uintptr, uintptr) { var buf [4996]byte; use(buf[:]); return Stackguard() }
-func stack5000() (uintptr, uintptr) { var buf [5000]byte; use(buf[:]); return Stackguard() }
diff --git a/src/pkg/runtime/stack_test.go b/src/pkg/runtime/stack_test.go
deleted file mode 100644
index f0c599a..0000000
--- a/src/pkg/runtime/stack_test.go
+++ /dev/null
@@ -1,283 +0,0 @@
-// Copyright 2012 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package runtime_test
-
-import (
-	. "runtime"
-	"sync"
-	"testing"
-	"time"
-	"unsafe"
-)
-
-// See stack.h.
-const (
-	StackGuard = 256
-	StackLimit = 128
-)
-
-// Test stack split logic by calling functions of every frame size
-// from near 0 up to and beyond the default segment size (4k).
-// Each of those functions reports its SP + stack limit, and then
-// the test (the caller) checks that those make sense.  By not
-// doing the actual checking and reporting from the suspect functions,
-// we minimize the possibility of crashes during the test itself.
-//
-// Exhaustive test for http://golang.org/issue/3310.
-// The linker used to get a few sizes near the segment size wrong:
-//
-// --- FAIL: TestStackSplit (0.01 seconds)
-// 	stack_test.go:22: after runtime_test.stack3812: sp=0x7f7818d5d078 < limit=0x7f7818d5d080
-// 	stack_test.go:22: after runtime_test.stack3816: sp=0x7f7818d5d078 < limit=0x7f7818d5d080
-// 	stack_test.go:22: after runtime_test.stack3820: sp=0x7f7818d5d070 < limit=0x7f7818d5d080
-// 	stack_test.go:22: after runtime_test.stack3824: sp=0x7f7818d5d070 < limit=0x7f7818d5d080
-// 	stack_test.go:22: after runtime_test.stack3828: sp=0x7f7818d5d068 < limit=0x7f7818d5d080
-// 	stack_test.go:22: after runtime_test.stack3832: sp=0x7f7818d5d068 < limit=0x7f7818d5d080
-// 	stack_test.go:22: after runtime_test.stack3836: sp=0x7f7818d5d060 < limit=0x7f7818d5d080
-// 	stack_test.go:22: after runtime_test.stack3840: sp=0x7f7818d5d060 < limit=0x7f7818d5d080
-// 	stack_test.go:22: after runtime_test.stack3844: sp=0x7f7818d5d058 < limit=0x7f7818d5d080
-// 	stack_test.go:22: after runtime_test.stack3848: sp=0x7f7818d5d058 < limit=0x7f7818d5d080
-// 	stack_test.go:22: after runtime_test.stack3852: sp=0x7f7818d5d050 < limit=0x7f7818d5d080
-// 	stack_test.go:22: after runtime_test.stack3856: sp=0x7f7818d5d050 < limit=0x7f7818d5d080
-// 	stack_test.go:22: after runtime_test.stack3860: sp=0x7f7818d5d048 < limit=0x7f7818d5d080
-// 	stack_test.go:22: after runtime_test.stack3864: sp=0x7f7818d5d048 < limit=0x7f7818d5d080
-// FAIL
-func TestStackSplit(t *testing.T) {
-	for _, f := range splitTests {
-		sp, guard := f()
-		bottom := guard - StackGuard
-		if sp < bottom+StackLimit {
-			fun := FuncForPC(**(**uintptr)(unsafe.Pointer(&f)))
-			t.Errorf("after %s: sp=%#x < limit=%#x (guard=%#x, bottom=%#x)",
-				fun.Name(), sp, bottom+StackLimit, guard, bottom)
-		}
-	}
-}
-
-var Used byte
-
-func use(buf []byte) {
-	for _, c := range buf {
-		Used += c
-	}
-}
-
-// TestStackMem measures per-thread stack segment cache behavior.
-// The test consumed up to 500MB in the past.
-func TestStackMem(t *testing.T) {
-	const (
-		BatchSize      = 32
-		BatchCount     = 256
-		ArraySize      = 1024
-		RecursionDepth = 128
-	)
-	if testing.Short() {
-		return
-	}
-	defer GOMAXPROCS(GOMAXPROCS(BatchSize))
-	s0 := new(MemStats)
-	ReadMemStats(s0)
-	for b := 0; b < BatchCount; b++ {
-		c := make(chan bool, BatchSize)
-		for i := 0; i < BatchSize; i++ {
-			go func() {
-				var f func(k int, a [ArraySize]byte)
-				f = func(k int, a [ArraySize]byte) {
-					if k == 0 {
-						time.Sleep(time.Millisecond)
-						return
-					}
-					f(k-1, a)
-				}
-				f(RecursionDepth, [ArraySize]byte{})
-				c <- true
-			}()
-		}
-		for i := 0; i < BatchSize; i++ {
-			<-c
-		}
-
-		// The goroutines have signaled via c that they are ready to exit.
-		// Give them a chance to exit by sleeping. If we don't wait, we
-		// might not reuse them on the next batch.
-		time.Sleep(10 * time.Millisecond)
-	}
-	s1 := new(MemStats)
-	ReadMemStats(s1)
-	consumed := s1.StackSys - s0.StackSys
-	t.Logf("Consumed %vMB for stack mem", consumed>>20)
-	estimate := uint64(8 * BatchSize * ArraySize * RecursionDepth) // 8 is to reduce flakiness.
-	if consumed > estimate {
-		t.Fatalf("Stack mem: want %v, got %v", estimate, consumed)
-	}
-	// Due to broken stack memory accounting (http://golang.org/issue/7468),
-	// StackInuse can decrease during function execution, so we cast the values to int64.
-	inuse := int64(s1.StackInuse) - int64(s0.StackInuse)
-	t.Logf("Inuse %vMB for stack mem", inuse>>20)
-	if inuse > 4<<20 {
-		t.Fatalf("Stack inuse: want %v, got %v", 4<<20, inuse)
-	}
-}
-
-// Test stack growing in different contexts.
-func TestStackGrowth(t *testing.T) {
-	switch GOARCH {
-	case "386", "arm":
-		t.Skipf("skipping test on %q; see issue 8083", GOARCH)
-	}
-	t.Parallel()
-	var wg sync.WaitGroup
-
-	// in a normal goroutine
-	wg.Add(1)
-	go func() {
-		defer wg.Done()
-		growStack()
-	}()
-	wg.Wait()
-
-	// in locked goroutine
-	wg.Add(1)
-	go func() {
-		defer wg.Done()
-		LockOSThread()
-		growStack()
-		UnlockOSThread()
-	}()
-	wg.Wait()
-
-	// in finalizer
-	wg.Add(1)
-	go func() {
-		defer wg.Done()
-		done := make(chan bool)
-		go func() {
-			s := new(string)
-			SetFinalizer(s, func(ss *string) {
-				growStack()
-				done <- true
-			})
-			s = nil
-			done <- true
-		}()
-		<-done
-		GC()
-		select {
-		case <-done:
-		case <-time.After(20 * time.Second):
-			t.Fatal("finalizer did not run")
-		}
-	}()
-	wg.Wait()
-}
-
-// ... and in init
-//func init() {
-//	growStack()
-//}
-
-func growStack() {
-	n := 1 << 10
-	if testing.Short() {
-		n = 1 << 8
-	}
-	for i := 0; i < n; i++ {
-		x := 0
-		growStackIter(&x, i)
-		if x != i+1 {
-			panic("stack is corrupted")
-		}
-	}
-	GC()
-}
-
-// This function is not an anonimous func, so that the compiler can do escape
-// analysis and place x on stack (and subsequently stack growth update the pointer).
-func growStackIter(p *int, n int) {
-	if n == 0 {
-		*p = n + 1
-		GC()
-		return
-	}
-	*p = n + 1
-	x := 0
-	growStackIter(&x, n-1)
-	if x != n {
-		panic("stack is corrupted")
-	}
-}
-
-func TestStackGrowthCallback(t *testing.T) {
-	t.Parallel()
-	var wg sync.WaitGroup
-
-	// test stack growth at chan op
-	wg.Add(1)
-	go func() {
-		defer wg.Done()
-		c := make(chan int, 1)
-		growStackWithCallback(func() {
-			c <- 1
-			<-c
-		})
-	}()
-
-	// test stack growth at map op
-	wg.Add(1)
-	go func() {
-		defer wg.Done()
-		m := make(map[int]int)
-		growStackWithCallback(func() {
-			_, _ = m[1]
-			m[1] = 1
-		})
-	}()
-
-	// test stack growth at goroutine creation
-	wg.Add(1)
-	go func() {
-		defer wg.Done()
-		growStackWithCallback(func() {
-			done := make(chan bool)
-			go func() {
-				done <- true
-			}()
-			<-done
-		})
-	}()
-
-	wg.Wait()
-}
-
-func growStackWithCallback(cb func()) {
-	var f func(n int)
-	f = func(n int) {
-		if n == 0 {
-			cb()
-			return
-		}
-		f(n - 1)
-	}
-	for i := 0; i < 1<<10; i++ {
-		f(i)
-	}
-}
-
-// TestDeferPtrs tests the adjustment of Defer's argument pointers (p aka &y)
-// during a stack copy.
-func set(p *int, x int) {
-	*p = x
-}
-func TestDeferPtrs(t *testing.T) {
-	var y int
-
-	defer func() {
-		if y != 42 {
-			t.Errorf("defer's stack references were not adjusted appropriately")
-		}
-	}()
-	defer set(&y, 42)
-	growStack()
-}
diff --git a/src/pkg/runtime/string.goc b/src/pkg/runtime/string.goc
deleted file mode 100644
index 97a69d0..0000000
--- a/src/pkg/runtime/string.goc
+++ /dev/null
@@ -1,430 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package runtime
-#include "runtime.h"
-#include "arch_GOARCH.h"
-#include "malloc.h"
-#include "race.h"
-#include "../../cmd/ld/textflag.h"
-
-String	runtime·emptystring;
-
-#pragma textflag NOSPLIT
-intgo
-runtime·findnull(byte *s)
-{
-	intgo l;
-
-	if(s == nil)
-		return 0;
-	for(l=0; s[l]!=0; l++)
-		;
-	return l;
-}
-
-intgo
-runtime·findnullw(uint16 *s)
-{
-	intgo l;
-
-	if(s == nil)
-		return 0;
-	for(l=0; s[l]!=0; l++)
-		;
-	return l;
-}
-
-uintptr runtime·maxstring = 256; // a hint for print
-
-static String
-gostringsize(intgo l)
-{
-	String s;
-	uintptr ms;
-
-	if(l == 0)
-		return runtime·emptystring;
-	s.str = runtime·mallocgc(l, 0, FlagNoScan|FlagNoZero);
-	s.len = l;
-	for(;;) {
-		ms = runtime·maxstring;
-		if((uintptr)l <= ms || runtime·casp((void**)&runtime·maxstring, (void*)ms, (void*)l))
-			break;
-	}
-	return s;
-}
-
-String
-runtime·gostring(byte *str)
-{
-	intgo l;
-	String s;
-
-	l = runtime·findnull(str);
-	s = gostringsize(l);
-	runtime·memmove(s.str, str, l);
-	return s;
-}
-
-String
-runtime·gostringn(byte *str, intgo l)
-{
-	String s;
-
-	s = gostringsize(l);
-	runtime·memmove(s.str, str, l);
-	return s;
-}
-
-// used by cmd/cgo
-Slice
-runtime·gobytes(byte *p, intgo n)
-{
-	Slice sl;
-
-	sl.array = runtime·mallocgc(n, 0, FlagNoScan|FlagNoZero);
-	sl.len = n;
-	sl.cap = n;
-	runtime·memmove(sl.array, p, n);
-	return sl;
-}
-
-String
-runtime·gostringnocopy(byte *str)
-{
-	String s;
-	
-	s.str = str;
-	s.len = runtime·findnull(str);
-	return s;
-}
-
-func cstringToGo(str *byte) (s String) {
-	s = runtime·gostringnocopy(str);
-}
-
-String
-runtime·gostringw(uint16 *str)
-{
-	intgo n1, n2, i;
-	byte buf[8];
-	String s;
-
-	n1 = 0;
-	for(i=0; str[i]; i++)
-		n1 += runtime·runetochar(buf, str[i]);
-	s = gostringsize(n1+4);
-	n2 = 0;
-	for(i=0; str[i]; i++) {
-		// check for race
-		if(n2 >= n1)
-			break;
-		n2 += runtime·runetochar(s.str+n2, str[i]);
-	}
-	s.len = n2;
-	s.str[s.len] = 0;
-	return s;
-}
-
-String
-runtime·catstring(String s1, String s2)
-{
-	String s3;
-
-	if(s1.len == 0)
-		return s2;
-	if(s2.len == 0)
-		return s1;
-
-	s3 = gostringsize(s1.len + s2.len);
-	runtime·memmove(s3.str, s1.str, s1.len);
-	runtime·memmove(s3.str+s1.len, s2.str, s2.len);
-	return s3;
-}
-
-static String
-concatstring(intgo n, String *s)
-{
-	intgo i, l, count;
-	String out;
-
-	l = 0;
-	count = 0;
-	for(i=0; i<n; i++) {
-		if(l + s[i].len < l)
-			runtime·throw("string concatenation too long");
-		l += s[i].len;
-		if(s[i].len > 0) {
-			count++;
-			out = s[i];
-		}
-	}
-	if(count == 0)
-		return runtime·emptystring;
-	if(count == 1) // zero or one non-empty string in concatenation
-		return out;
-	
-	out = gostringsize(l);
-	l = 0;
-	for(i=0; i<n; i++) {
-		runtime·memmove(out.str+l, s[i].str, s[i].len);
-		l += s[i].len;
-	}
-	return out;
-}
-
-#pragma textflag NOSPLIT
-func concatstring2(s1 String, s2 String) (res String) {
-	USED(&s2);
-	res = concatstring(2, &s1);
-}
-#pragma textflag NOSPLIT
-func concatstring3(s1 String, s2 String, s3 String) (res String) {
-	USED(&s2);
-	USED(&s3);
-	res = concatstring(3, &s1);
-}
-#pragma textflag NOSPLIT
-func concatstring4(s1 String, s2 String, s3 String, s4 String) (res String) {
-	USED(&s2);
-	USED(&s3);
-	USED(&s4);
-	res = concatstring(4, &s1);
-}
-#pragma textflag NOSPLIT
-func concatstring5(s1 String, s2 String, s3 String, s4 String, s5 String) (res String) {
-	USED(&s2);
-	USED(&s3);
-	USED(&s4);
-	USED(&s5);
-	res = concatstring(5, &s1);
-}
-#pragma textflag NOSPLIT
-func concatstrings(s Slice) (res String) {
-	res = concatstring(s.len, (String*)s.array);
-}
-
-func eqstring(s1 String, s2 String) (v bool) {
-	if(s1.len != s2.len) {
-		v = false;
-		return;
-	}
-	if(s1.str == s2.str) {
-		v = true;
-		return;
-	}
-	v = runtime·memeq(s1.str, s2.str, s1.len);
-}
-
-int32
-runtime·strcmp(byte *s1, byte *s2)
-{
-	uintptr i;
-	byte c1, c2;
-
-	for(i=0;; i++) {
-		c1 = s1[i];
-		c2 = s2[i];
-		if(c1 < c2)
-			return -1;
-		if(c1 > c2)
-			return +1;
-		if(c1 == 0)
-			return 0;
-	}
-}
-
-int32
-runtime·strncmp(byte *s1, byte *s2, uintptr n)
-{
-	uintptr i;
-	byte c1, c2;
-
-	for(i=0; i<n; i++) {
-		c1 = s1[i];
-		c2 = s2[i];
-		if(c1 < c2)
-			return -1;
-		if(c1 > c2)
-			return +1;
-		if(c1 == 0)
-			break;
-	}
-	return 0;
-}
-
-byte*
-runtime·strstr(byte *s1, byte *s2)
-{
-	byte *sp1, *sp2;
-
-	if(*s2 == 0)
-		return s1;
-	for(; *s1; s1++) {
-		if(*s1 != *s2)
-			continue;
-		sp1 = s1;
-		sp2 = s2;
-		for(;;) {
-			if(*sp2 == 0)
-				return s1;
-			if(*sp1++ != *sp2++)
-				break;
-		}
-	}
-	return nil;
-}
-
-func intstring(v int64) (s String) {
-	s = gostringsize(8);
-	s.len = runtime·runetochar(s.str, v);
-	s.str[s.len] = 0;
-}
-
-func slicebytetostring(b Slice) (s String) {
-	void *pc;
-
-	if(raceenabled) {
-		pc = runtime·getcallerpc(&b);
-		runtime·racereadrangepc(b.array, b.len, pc, runtime·slicebytetostring);
-	}
-	s = gostringsize(b.len);
-	runtime·memmove(s.str, b.array, s.len);
-}
-
-func slicebytetostringtmp(b Slice) (s String) {
-	void *pc;
-
-	if(raceenabled) {
-		pc = runtime·getcallerpc(&b);
-		runtime·racereadrangepc(b.array, b.len, pc, runtime·slicebytetostringtmp);
-	}
-	
-	// Return a "string" referring to the actual []byte bytes.
-	// This is only for use by internal compiler optimizations
-	// that know that the string form will be discarded before
-	// the calling goroutine could possibly modify the original
-	// slice or synchronize with another goroutine.
-	// Today, the only such case is a m[string(k)] lookup where
-	// m is a string-keyed map and k is a []byte.
-	s.str = b.array;
-	s.len = b.len;
-}
-
-func stringtoslicebyte(s String) (b Slice) {
-	uintptr cap;
-
-	cap = runtime·roundupsize(s.len);
-	b.array = runtime·mallocgc(cap, 0, FlagNoScan|FlagNoZero);
-	b.len = s.len;
-	b.cap = cap;
-	runtime·memmove(b.array, s.str, s.len);
-	if(cap != b.len)
-		runtime·memclr(b.array+b.len, cap-b.len);
-}
-
-func slicerunetostring(b Slice) (s String) {
-	intgo siz1, siz2, i;
-	int32 *a;
-	byte dum[8];
-	void *pc;
-
-	if(raceenabled) {
-		pc = runtime·getcallerpc(&b);
-		runtime·racereadrangepc(b.array, b.len*sizeof(*a), pc, runtime·slicerunetostring);
-	}
-	a = (int32*)b.array;
-	siz1 = 0;
-	for(i=0; i<b.len; i++) {
-		siz1 += runtime·runetochar(dum, a[i]);
-	}
-
-	s = gostringsize(siz1+4);
-	siz2 = 0;
-	for(i=0; i<b.len; i++) {
-		// check for race
-		if(siz2 >= siz1)
-			break;
-		siz2 += runtime·runetochar(s.str+siz2, a[i]);
-	}
-	s.len = siz2;
-	s.str[s.len] = 0;
-}
-
-func stringtoslicerune(s String) (b Slice) {
-	intgo n;
-	int32 dum, *r;
-	uint8 *p, *ep;
-	uintptr mem;
-
-	// two passes.
-	// unlike slicerunetostring, no race because strings are immutable.
-	p = s.str;
-	ep = s.str+s.len;
-	n = 0;
-	while(p < ep) {
-		p += runtime·charntorune(&dum, p, ep-p);
-		n++;
-	}
-
-	if(n > MaxMem/sizeof(r[0]))
-		runtime·throw("out of memory");
-	mem = runtime·roundupsize(n*sizeof(r[0]));
-	b.array = runtime·mallocgc(mem, 0, FlagNoScan|FlagNoZero);
-	b.len = n;
-	b.cap = mem/sizeof(r[0]);
-	p = s.str;
-	r = (int32*)b.array;
-	while(p < ep)
-		p += runtime·charntorune(r++, p, ep-p);
-	if(b.cap > b.len)
-		runtime·memclr(b.array+b.len*sizeof(r[0]), (b.cap-b.len)*sizeof(r[0]));
-}
-
-enum
-{
-	Runeself	= 0x80,
-};
-
-func stringiter(s String, k int) (retk int) {
-	int32 l;
-
-	if(k >= s.len) {
-		// retk=0 is end of iteration
-		retk = 0;
-		goto out;
-	}
-
-	l = s.str[k];
-	if(l < Runeself) {
-		retk = k+1;
-		goto out;
-	}
-
-	// multi-char rune
-	retk = k + runtime·charntorune(&l, s.str+k, s.len-k);
-
-out:
-}
-
-func stringiter2(s String, k int) (retk int, retv int32) {
-	if(k >= s.len) {
-		// retk=0 is end of iteration
-		retk = 0;
-		retv = 0;
-		goto out;
-	}
-
-	retv = s.str[k];
-	if(retv < Runeself) {
-		retk = k+1;
-		goto out;
-	}
-
-	// multi-char rune
-	retk = k + runtime·charntorune(&retv, s.str+k, s.len-k);
-
-out:
-}
diff --git a/src/pkg/runtime/string_test.go b/src/pkg/runtime/string_test.go
deleted file mode 100644
index df3ff06..0000000
--- a/src/pkg/runtime/string_test.go
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package runtime_test
-
-import (
-	"testing"
-)
-
-func BenchmarkCompareStringEqual(b *testing.B) {
-	bytes := []byte("Hello Gophers!")
-	s1, s2 := string(bytes), string(bytes)
-	for i := 0; i < b.N; i++ {
-		if s1 != s2 {
-			b.Fatal("s1 != s2")
-		}
-	}
-}
-
-func BenchmarkCompareStringIdentical(b *testing.B) {
-	s1 := "Hello Gophers!"
-	s2 := s1
-	for i := 0; i < b.N; i++ {
-		if s1 != s2 {
-			b.Fatal("s1 != s2")
-		}
-	}
-}
-
-func BenchmarkCompareStringSameLength(b *testing.B) {
-	s1 := "Hello Gophers!"
-	s2 := "Hello, Gophers"
-	for i := 0; i < b.N; i++ {
-		if s1 == s2 {
-			b.Fatal("s1 == s2")
-		}
-	}
-}
-
-func BenchmarkCompareStringDifferentLength(b *testing.B) {
-	s1 := "Hello Gophers!"
-	s2 := "Hello, Gophers!"
-	for i := 0; i < b.N; i++ {
-		if s1 == s2 {
-			b.Fatal("s1 == s2")
-		}
-	}
-}
-
-func BenchmarkCompareStringBigUnaligned(b *testing.B) {
-	bytes := make([]byte, 0, 1<<20)
-	for len(bytes) < 1<<20 {
-		bytes = append(bytes, "Hello Gophers!"...)
-	}
-	s1, s2 := string(bytes), "hello"+string(bytes)
-	for i := 0; i < b.N; i++ {
-		if s1 != s2[len("hello"):] {
-			b.Fatal("s1 != s2")
-		}
-	}
-	b.SetBytes(int64(len(s1)))
-}
-
-func BenchmarkCompareStringBig(b *testing.B) {
-	bytes := make([]byte, 0, 1<<20)
-	for len(bytes) < 1<<20 {
-		bytes = append(bytes, "Hello Gophers!"...)
-	}
-	s1, s2 := string(bytes), string(bytes)
-	for i := 0; i < b.N; i++ {
-		if s1 != s2 {
-			b.Fatal("s1 != s2")
-		}
-	}
-	b.SetBytes(int64(len(s1)))
-}
diff --git a/src/pkg/runtime/symtab.goc b/src/pkg/runtime/symtab.goc
deleted file mode 100644
index 15e1d28..0000000
--- a/src/pkg/runtime/symtab.goc
+++ /dev/null
@@ -1,332 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Runtime symbol table parsing.
-// See http://golang.org/s/go12symtab for an overview.
-
-package runtime
-#include "runtime.h"
-#include "defs_GOOS_GOARCH.h"
-#include "os_GOOS.h"
-#include "arch_GOARCH.h"
-#include "malloc.h"
-#include "funcdata.h"
-
-typedef struct Ftab Ftab;
-struct Ftab
-{
-	uintptr	entry;
-	uintptr	funcoff;
-};
-
-extern byte pclntab[];
-
-static Ftab *ftab;
-static uintptr nftab;
-static uint32 *filetab;
-static uint32 nfiletab;
-
-static String end = { (uint8*)"end", 3 };
-
-void
-runtime·symtabinit(void)
-{
-	int32 i, j;
-	Func *f1, *f2;
-	
-	// See golang.org/s/go12symtab for header: 0xfffffffb,
-	// two zero bytes, a byte giving the PC quantum,
-	// and a byte giving the pointer width in bytes.
-	if(*(uint32*)pclntab != 0xfffffffb || pclntab[4] != 0 || pclntab[5] != 0 || pclntab[6] != PCQuantum || pclntab[7] != sizeof(void*)) {
-		runtime·printf("runtime: function symbol table header: %x %x\n", *(uint32*)pclntab, *(uint32*)(pclntab+4));
-		runtime·throw("invalid function symbol table\n");
-	}
-
-	nftab = *(uintptr*)(pclntab+8);
-	ftab = (Ftab*)(pclntab+8+sizeof(void*));
-	for(i=0; i<nftab; i++) {
-		// NOTE: ftab[nftab].entry is legal; it is the address beyond the final function.
-		if(ftab[i].entry > ftab[i+1].entry) {
-			f1 = (Func*)(pclntab + ftab[i].funcoff);
-			f2 = (Func*)(pclntab + ftab[i+1].funcoff);
-			runtime·printf("function symbol table not sorted by program counter: %p %s > %p %s", ftab[i].entry, runtime·funcname(f1), ftab[i+1].entry, i+1 == nftab ? "end" : runtime·funcname(f2));
-			for(j=0; j<=i; j++)
-				runtime·printf("\t%p %s\n", ftab[j].entry, runtime·funcname((Func*)(pclntab + ftab[j].funcoff)));
-			runtime·throw("invalid runtime symbol table");
-		}
-	}
-	
-	filetab = (uint32*)(pclntab + *(uint32*)&ftab[nftab].funcoff);
-	nfiletab = filetab[0];
-}
-
-static uint32
-readvarint(byte **pp)
-{
-	byte *p;
-	uint32 v;
-	int32 shift;
-	
-	v = 0;
-	p = *pp;
-	for(shift = 0;; shift += 7) {
-		v |= (*p & 0x7F) << shift;
-		if(!(*p++ & 0x80))
-			break;
-	}
-	*pp = p;
-	return v;
-}
-
-void*
-runtime·funcdata(Func *f, int32 i)
-{
-	byte *p;
-
-	if(i < 0 || i >= f->nfuncdata)
-		return nil;
-	p = (byte*)&f->nfuncdata + 4 + f->npcdata*4;
-	if(sizeof(void*) == 8 && ((uintptr)p & 4)) {
-		if(((uintptr)f & 4))
-			runtime·printf("misaligned func %p\n", f);
-		p += 4;
-	}
-	return ((void**)p)[i];
-}
-
-static bool
-step(byte **pp, uintptr *pc, int32 *value, bool first)
-{
-	uint32 uvdelta, pcdelta;
-	int32 vdelta;
-
-	uvdelta = readvarint(pp);
-	if(uvdelta == 0 && !first)
-		return 0;
-	if(uvdelta&1)
-		uvdelta = ~(uvdelta>>1);
-	else
-		uvdelta >>= 1;
-	vdelta = (int32)uvdelta;
-	pcdelta = readvarint(pp) * PCQuantum;
-	*value += vdelta;
-	*pc += pcdelta;
-	return 1;
-}
-
-// Return associated data value for targetpc in func f.
-// (Source file is f->src.)
-static int32
-pcvalue(Func *f, int32 off, uintptr targetpc, bool strict)
-{
-	byte *p;
-	uintptr pc;
-	int32 value;
-
-	enum {
-		debug = 0
-	};
-
-	// The table is a delta-encoded sequence of (value, pc) pairs.
-	// Each pair states the given value is in effect up to pc.
-	// The value deltas are signed, zig-zag encoded.
-	// The pc deltas are unsigned.
-	// The starting value is -1, the starting pc is the function entry.
-	// The table ends at a value delta of 0 except in the first pair.
-	if(off == 0)
-		return -1;
-	p = pclntab + off;
-	pc = f->entry;
-	value = -1;
-
-	if(debug && !runtime·panicking)
-		runtime·printf("pcvalue start f=%s [%p] pc=%p targetpc=%p value=%d tab=%p\n",
-			runtime·funcname(f), f, pc, targetpc, value, p);
-	
-	while(step(&p, &pc, &value, pc == f->entry)) {
-		if(debug)
-			runtime·printf("\tvalue=%d until pc=%p\n", value, pc);
-		if(targetpc < pc)
-			return value;
-	}
-	
-	// If there was a table, it should have covered all program counters.
-	// If not, something is wrong.
-	if(runtime·panicking || !strict)
-		return -1;
-	runtime·printf("runtime: invalid pc-encoded table f=%s pc=%p targetpc=%p tab=%p\n",
-		runtime·funcname(f), pc, targetpc, p);
-	p = (byte*)f + off;
-	pc = f->entry;
-	value = -1;
-	
-	while(step(&p, &pc, &value, pc == f->entry))
-		runtime·printf("\tvalue=%d until pc=%p\n", value, pc);
-	
-	runtime·throw("invalid runtime symbol table");
-	return -1;
-}
-
-static String unknown = { (uint8*)"?", 1 };
-
-int8*
-runtime·funcname(Func *f)
-{
-	if(f == nil || f->nameoff == 0)
-		return nil;
-	return (int8*)(pclntab + f->nameoff);
-}
-
-static int32
-funcline(Func *f, uintptr targetpc, String *file, bool strict)
-{
-	int32 line;
-	int32 fileno;
-
-	*file = unknown;
-	fileno = pcvalue(f, f->pcfile, targetpc, strict);
-	line = pcvalue(f, f->pcln, targetpc, strict);
-	if(fileno == -1 || line == -1 || fileno >= nfiletab) {
-		// runtime·printf("looking for %p in %S got file=%d line=%d\n", targetpc, *f->name, fileno, line);
-		return 0;
-	}
-	*file = runtime·gostringnocopy(pclntab + filetab[fileno]);
-	return line;
-}
-
-int32
-runtime·funcline(Func *f, uintptr targetpc, String *file)
-{
-	return funcline(f, targetpc, file, true);
-}
-
-int32
-runtime·funcspdelta(Func *f, uintptr targetpc)
-{
-	int32 x;
-	
-	x = pcvalue(f, f->pcsp, targetpc, true);
-	if(x&(sizeof(void*)-1))
-		runtime·printf("invalid spdelta %d %d\n", f->pcsp, x);
-	return x;
-}
-
-int32
-runtime·pcdatavalue(Func *f, int32 table, uintptr targetpc)
-{
-	if(table < 0 || table >= f->npcdata)
-		return -1;
-	return pcvalue(f, (&f->nfuncdata)[1+table], targetpc, true);
-}
-
-int32
-runtime·funcarglen(Func *f, uintptr targetpc)
-{
-	if(targetpc == f->entry)
-		return 0;
-	return runtime·pcdatavalue(f, PCDATA_ArgSize, targetpc-PCQuantum);
-}
-
-func funcline_go(f *Func, targetpc uintptr) (retfile String, retline int) {
-	// Pass strict=false here, because anyone can call this function,
-	// and they might just be wrong about targetpc belonging to f.
-	retline = funcline(f, targetpc, &retfile, false);
-}
-
-func funcname_go(f *Func) (ret String) {
-	ret = runtime·gostringnocopy((uint8*)runtime·funcname(f));
-}
-
-func funcentry_go(f *Func) (ret uintptr) {
-	ret = f->entry;
-}
-
-Func*
-runtime·findfunc(uintptr addr)
-{
-	Ftab *f;
-	int32 nf, n;
-
-	if(nftab == 0)
-		return nil;
-	if(addr < ftab[0].entry || addr >= ftab[nftab].entry)
-		return nil;
-
-	// binary search to find func with entry <= addr.
-	f = ftab;
-	nf = nftab;
-	while(nf > 0) {
-		n = nf/2;
-		if(f[n].entry <= addr && addr < f[n+1].entry)
-			return (Func*)(pclntab + f[n].funcoff);
-		else if(addr < f[n].entry)
-			nf = n;
-		else {
-			f += n+1;
-			nf -= n+1;
-		}
-	}
-
-	// can't get here -- we already checked above
-	// that the address was in the table bounds.
-	// this can only happen if the table isn't sorted
-	// by address or if the binary search above is buggy.
-	runtime·prints("findfunc unreachable\n");
-	return nil;
-}
-
-func FuncForPC(pc uintptr) (ret *Func) {
-	ret = runtime·findfunc(pc);
-}
-
-static bool
-hasprefix(String s, int8 *p)
-{
-	int32 i;
-
-	for(i=0; i<s.len; i++) {
-		if(p[i] == 0)
-			return 1;
-		if(p[i] != s.str[i])
-			return 0;
-	}
-	return p[i] == 0;
-}
-
-static bool
-contains(String s, int8 *p)
-{
-	int32 i;
-
-	if(p[0] == 0)
-		return 1;
-	for(i=0; i<s.len; i++) {
-		if(s.str[i] != p[0])
-			continue;
-		if(hasprefix((String){s.str + i, s.len - i}, p))
-			return 1;
-	}
-	return 0;
-}
-
-bool
-runtime·showframe(Func *f, G *gp)
-{
-	static int32 traceback = -1;
-	String name;
-
-	if(m->throwing > 0 && gp != nil && (gp == m->curg || gp == m->caughtsig))
-		return 1;
-	if(traceback < 0)
-		traceback = runtime·gotraceback(nil);
-	name = runtime·gostringnocopy((uint8*)runtime·funcname(f));
-
-	// Special case: always show runtime.panic frame, so that we can
-	// see where a panic started in the middle of a stack trace.
-	// See golang.org/issue/5832.
-	if(name.len == 7+1+5 && hasprefix(name, "runtime.panic"))
-		return 1;
-
-	return traceback > 1 || f != nil && contains(name, ".") && !hasprefix(name, "runtime.");
-}
diff --git a/src/pkg/runtime/sys_darwin_386.s b/src/pkg/runtime/sys_darwin_386.s
deleted file mode 100644
index bfaaa00..0000000
--- a/src/pkg/runtime/sys_darwin_386.s
+++ /dev/null
@@ -1,522 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// System calls and other sys.stuff for 386, Darwin
-// See http://fxr.watson.org/fxr/source/bsd/kern/syscalls.c?v=xnu-1228
-// or /usr/include/sys/syscall.h (on a Mac) for system call numbers.
-
-#include "zasm_GOOS_GOARCH.h"
-#include "../../cmd/ld/textflag.h"
-
-// Exit the entire program (like C exit)
-TEXT runtime·exit(SB),NOSPLIT,$0
-	MOVL	$1, AX
-	INT	$0x80
-	MOVL	$0xf1, 0xf1  // crash
-	RET
-
-// Exit this OS thread (like pthread_exit, which eventually
-// calls __bsdthread_terminate).
-TEXT runtime·exit1(SB),NOSPLIT,$0
-	MOVL	$361, AX
-	INT	$0x80
-	JAE 2(PC)
-	MOVL	$0xf1, 0xf1  // crash
-	RET
-
-TEXT runtime·open(SB),NOSPLIT,$0
-	MOVL	$5, AX
-	INT	$0x80
-	RET
-
-TEXT runtime·close(SB),NOSPLIT,$0
-	MOVL	$6, AX
-	INT	$0x80
-	RET
-
-TEXT runtime·read(SB),NOSPLIT,$0
-	MOVL	$3, AX
-	INT	$0x80
-	RET
-
-TEXT runtime·write(SB),NOSPLIT,$0
-	MOVL	$4, AX
-	INT	$0x80
-	RET
-
-TEXT runtime·raise(SB),NOSPLIT,$16
-	MOVL	$20, AX // getpid
-	INT	$0x80
-	MOVL	AX, 4(SP)	// pid
-	MOVL	sig+0(FP), AX
-	MOVL	AX, 8(SP)	// signal
-	MOVL	$1, 12(SP)	// posix
-	MOVL	$37, AX // kill
-	INT	$0x80
-	RET
-
-TEXT runtime·mmap(SB),NOSPLIT,$0
-	MOVL	$197, AX
-	INT	$0x80
-	RET
-
-TEXT runtime·madvise(SB),NOSPLIT,$0
-	MOVL	$75, AX
-	INT	$0x80
-	// ignore failure - maybe pages are locked
-	RET
-
-TEXT runtime·munmap(SB),NOSPLIT,$0
-	MOVL	$73, AX
-	INT	$0x80
-	JAE	2(PC)
-	MOVL	$0xf1, 0xf1  // crash
-	RET
-
-TEXT runtime·setitimer(SB),NOSPLIT,$0
-	MOVL	$83, AX
-	INT	$0x80
-	RET
-
-// OS X comm page time offsets
-// http://www.opensource.apple.com/source/xnu/xnu-1699.26.8/osfmk/i386/cpu_capabilities.h
-#define	cpu_capabilities	0x20
-#define	nt_tsc_base	0x50
-#define	nt_scale	0x58
-#define	nt_shift	0x5c
-#define	nt_ns_base	0x60
-#define	nt_generation	0x68
-#define	gtod_generation	0x6c
-#define	gtod_ns_base	0x70
-#define	gtod_sec_base	0x78
-
-// called from assembly
-// 64-bit unix nanoseconds returned in DX:AX.
-// I'd much rather write this in C but we need
-// assembly for the 96-bit multiply and RDTSC.
-TEXT runtime·now(SB),NOSPLIT,$40
-	MOVL	$0xffff0000, BP /* comm page base */
-	
-	// Test for slow CPU. If so, the math is completely
-	// different, and unimplemented here, so use the
-	// system call.
-	MOVL	cpu_capabilities(BP), AX
-	TESTL	$0x4000, AX
-	JNZ	systime
-
-	// Loop trying to take a consistent snapshot
-	// of the time parameters.
-timeloop:
-	MOVL	gtod_generation(BP), BX
-	TESTL	BX, BX
-	JZ	systime
-	MOVL	nt_generation(BP), CX
-	TESTL	CX, CX
-	JZ	timeloop
-	RDTSC
-	MOVL	nt_tsc_base(BP), SI
-	MOVL	(nt_tsc_base+4)(BP), DI
-	MOVL	SI, 0(SP)
-	MOVL	DI, 4(SP)
-	MOVL	nt_scale(BP), SI
-	MOVL	SI, 8(SP)
-	MOVL	nt_ns_base(BP), SI
-	MOVL	(nt_ns_base+4)(BP), DI
-	MOVL	SI, 12(SP)
-	MOVL	DI, 16(SP)
-	CMPL	nt_generation(BP), CX
-	JNE	timeloop
-	MOVL	gtod_ns_base(BP), SI
-	MOVL	(gtod_ns_base+4)(BP), DI
-	MOVL	SI, 20(SP)
-	MOVL	DI, 24(SP)
-	MOVL	gtod_sec_base(BP), SI
-	MOVL	(gtod_sec_base+4)(BP), DI
-	MOVL	SI, 28(SP)
-	MOVL	DI, 32(SP)
-	CMPL	gtod_generation(BP), BX
-	JNE	timeloop
-
-	// Gathered all the data we need. Compute time.
-	//	((tsc - nt_tsc_base) * nt_scale) >> 32 + nt_ns_base - gtod_ns_base + gtod_sec_base*1e9
-	// The multiply and shift extracts the top 64 bits of the 96-bit product.
-	SUBL	0(SP), AX // DX:AX = (tsc - nt_tsc_base)
-	SBBL	4(SP), DX
-
-	// We have x = tsc - nt_tsc_base - DX:AX to be
-	// multiplied by y = nt_scale = 8(SP), keeping the top 64 bits of the 96-bit product.
-	// x*y = (x&0xffffffff)*y + (x&0xffffffff00000000)*y
-	// (x*y)>>32 = ((x&0xffffffff)*y)>>32 + (x>>32)*y
-	MOVL	DX, CX // SI = (x&0xffffffff)*y >> 32
-	MOVL	$0, DX
-	MULL	8(SP)
-	MOVL	DX, SI
-
-	MOVL	CX, AX // DX:AX = (x>>32)*y
-	MOVL	$0, DX
-	MULL	8(SP)
-
-	ADDL	SI, AX	// DX:AX += (x&0xffffffff)*y >> 32
-	ADCL	$0, DX
-	
-	// DX:AX is now ((tsc - nt_tsc_base) * nt_scale) >> 32.
-	ADDL	12(SP), AX	// DX:AX += nt_ns_base
-	ADCL	16(SP), DX
-	SUBL	20(SP), AX	// DX:AX -= gtod_ns_base
-	SBBL	24(SP), DX
-	MOVL	AX, SI	// DI:SI = DX:AX
-	MOVL	DX, DI
-	MOVL	28(SP), AX	// DX:AX = gtod_sec_base*1e9
-	MOVL	32(SP), DX
-	MOVL	$1000000000, CX
-	MULL	CX
-	ADDL	SI, AX	// DX:AX += DI:SI
-	ADCL	DI, DX
-	RET
-
-systime:
-	// Fall back to system call (usually first call in this thread)
-	LEAL	12(SP), AX	// must be non-nil, unused
-	MOVL	AX, 4(SP)
-	MOVL	$0, 8(SP)	// time zone pointer
-	MOVL	$116, AX
-	INT	$0x80
-	// sec is in AX, usec in DX
-	// convert to DX:AX nsec
-	MOVL	DX, BX
-	MOVL	$1000000000, CX
-	MULL	CX
-	IMULL	$1000, BX
-	ADDL	BX, AX
-	ADCL	$0, DX
-	RET
-
-// func now() (sec int64, nsec int32)
-TEXT time·now(SB),NOSPLIT,$0
-	CALL	runtime·now(SB)
-	MOVL	$1000000000, CX
-	DIVL	CX
-	MOVL	AX, sec+0(FP)
-	MOVL	$0, sec+4(FP)
-	MOVL	DX, nsec+8(FP)
-	RET
-
-// int64 nanotime(void) so really
-// void nanotime(int64 *nsec)
-TEXT runtime·nanotime(SB),NOSPLIT,$0
-	CALL	runtime·now(SB)
-	MOVL	ret+0(FP), DI
-	MOVL	AX, 0(DI)
-	MOVL	DX, 4(DI)
-	RET
-
-TEXT runtime·sigprocmask(SB),NOSPLIT,$0
-	MOVL	$329, AX  // pthread_sigmask (on OS X, sigprocmask==entire process)
-	INT	$0x80
-	JAE	2(PC)
-	MOVL	$0xf1, 0xf1  // crash
-	RET
-
-TEXT runtime·sigaction(SB),NOSPLIT,$0
-	MOVL	$46, AX
-	INT	$0x80
-	JAE	2(PC)
-	MOVL	$0xf1, 0xf1  // crash
-	RET
-
-// Sigtramp's job is to call the actual signal handler.
-// It is called with the following arguments on the stack:
-//	0(FP)	"return address" - ignored
-//	4(FP)	actual handler
-//	8(FP)	signal number
-//	12(FP)	siginfo style
-//	16(FP)	siginfo
-//	20(FP)	context
-TEXT runtime·sigtramp(SB),NOSPLIT,$40
-	get_tls(CX)
-	
-	// check that m exists
-	MOVL	m(CX), BP
-	CMPL	BP, $0
-	JNE	6(PC)
-	MOVL	sig+8(FP), BX
-	MOVL	BX, 0(SP)
-	MOVL	$runtime·badsignal(SB), AX
-	CALL	AX
-	JMP 	sigtramp_ret
-
-	// save g
-	MOVL	g(CX), DI
-	MOVL	DI, 20(SP)
-
-	// g = m->gsignal
-	MOVL	m_gsignal(BP), BP
-	MOVL	BP, g(CX)
-
-	// copy arguments to sighandler
-	MOVL	sig+8(FP), BX
-	MOVL	BX, 0(SP)
-	MOVL	info+12(FP), BX
-	MOVL	BX, 4(SP)
-	MOVL	context+16(FP), BX
-	MOVL	BX, 8(SP)
-	MOVL	DI, 12(SP)
-
-	MOVL	handler+0(FP), BX
-	CALL	BX
-
-	// restore g
-	get_tls(CX)
-	MOVL	20(SP), DI
-	MOVL	DI, g(CX)
-
-sigtramp_ret:
-	// call sigreturn
-	MOVL	context+16(FP), CX
-	MOVL	style+4(FP), BX
-	MOVL	$0, 0(SP)	// "caller PC" - ignored
-	MOVL	CX, 4(SP)
-	MOVL	BX, 8(SP)
-	MOVL	$184, AX	// sigreturn(ucontext, infostyle)
-	INT	$0x80
-	MOVL	$0xf1, 0xf1  // crash
-	RET
-
-TEXT runtime·sigaltstack(SB),NOSPLIT,$0
-	MOVL	$53, AX
-	INT	$0x80
-	JAE	2(PC)
-	MOVL	$0xf1, 0xf1  // crash
-	RET
-
-TEXT runtime·usleep(SB),NOSPLIT,$32
-	MOVL	$0, DX
-	MOVL	usec+0(FP), AX
-	MOVL	$1000000, CX
-	DIVL	CX
-	MOVL	AX, 24(SP)  // sec
-	MOVL	DX, 28(SP)  // usec
-
-	// select(0, 0, 0, 0, &tv)
-	MOVL	$0, 0(SP)  // "return PC" - ignored
-	MOVL	$0, 4(SP)
-	MOVL	$0, 8(SP)
-	MOVL	$0, 12(SP)
-	MOVL	$0, 16(SP)
-	LEAL	24(SP), AX
-	MOVL	AX, 20(SP)
-	MOVL	$93, AX
-	INT	$0x80
-	RET
-
-// void bsdthread_create(void *stk, M *mp, G *gp, void (*fn)(void))
-// System call args are: func arg stack pthread flags.
-TEXT runtime·bsdthread_create(SB),NOSPLIT,$32
-	MOVL	$360, AX
-	// 0(SP) is where the caller PC would be; kernel skips it
-	MOVL	func+12(FP), BX
-	MOVL	BX, 4(SP)	// func
-	MOVL	mm+4(FP), BX
-	MOVL	BX, 8(SP)	// arg
-	MOVL	stk+0(FP), BX
-	MOVL	BX, 12(SP)	// stack
-	MOVL	gg+8(FP), BX
-	MOVL	BX, 16(SP)	// pthread
-	MOVL	$0x1000000, 20(SP)	// flags = PTHREAD_START_CUSTOM
-	INT	$0x80
-	JAE	3(PC)
-	NEGL	AX
-	RET
-	MOVL	$0, AX
-	RET
-
-// The thread that bsdthread_create creates starts executing here,
-// because we registered this function using bsdthread_register
-// at startup.
-//	AX = "pthread" (= g)
-//	BX = mach thread port
-//	CX = "func" (= fn)
-//	DX = "arg" (= m)
-//	DI = stack top
-//	SI = flags (= 0x1000000)
-//	SP = stack - C_32_STK_ALIGN
-TEXT runtime·bsdthread_start(SB),NOSPLIT,$0
-	// set up ldt 7+id to point at m->tls.
-	// m->tls is at m+40.  newosproc left
-	// the m->id in tls[0].
-	LEAL	m_tls(DX), BP
-	MOVL	0(BP), DI
-	ADDL	$7, DI	// m0 is LDT#7. count up.
-	// setldt(tls#, &tls, sizeof tls)
-	PUSHAL	// save registers
-	PUSHL	$32	// sizeof tls
-	PUSHL	BP	// &tls
-	PUSHL	DI	// tls #
-	CALL	runtime·setldt(SB)
-	POPL	AX
-	POPL	AX
-	POPL	AX
-	POPAL
-
-	// Now segment is established.  Initialize m, g.
-	get_tls(BP)
-	MOVL	AX, g(BP)
-	MOVL	DX, m(BP)
-	MOVL	BX, m_procid(DX)	// m->procid = thread port (for debuggers)
-	CALL	runtime·stackcheck(SB)		// smashes AX
-	CALL	CX	// fn()
-	CALL	runtime·exit1(SB)
-	RET
-
-// void bsdthread_register(void)
-// registers callbacks for threadstart (see bsdthread_create above
-// and wqthread and pthsize (not used).  returns 0 on success.
-TEXT runtime·bsdthread_register(SB),NOSPLIT,$40
-	MOVL	$366, AX
-	// 0(SP) is where kernel expects caller PC; ignored
-	MOVL	$runtime·bsdthread_start(SB), 4(SP)	// threadstart
-	MOVL	$0, 8(SP)	// wqthread, not used by us
-	MOVL	$0, 12(SP)	// pthsize, not used by us
-	MOVL	$0, 16(SP)	// dummy_value [sic]
-	MOVL	$0, 20(SP)	// targetconc_ptr
-	MOVL	$0, 24(SP)	// dispatchqueue_offset
-	INT	$0x80
-	JAE	3(PC)
-	NEGL	AX
-	RET
-	MOVL	$0, AX
-	RET
-
-// Invoke Mach system call.
-// Assumes system call number in AX,
-// caller PC on stack, caller's caller PC next,
-// and then the system call arguments.
-//
-// Can be used for BSD too, but we don't,
-// because if you use this interface the BSD
-// system call numbers need an extra field
-// in the high 16 bits that seems to be the
-// argument count in bytes but is not always.
-// INT $0x80 works fine for those.
-TEXT runtime·sysenter(SB),NOSPLIT,$0
-	POPL	DX
-	MOVL	SP, CX
-	BYTE $0x0F; BYTE $0x34;  // SYSENTER
-	// returns to DX with SP set to CX
-
-TEXT runtime·mach_msg_trap(SB),NOSPLIT,$0
-	MOVL	$-31, AX
-	CALL	runtime·sysenter(SB)
-	RET
-
-TEXT runtime·mach_reply_port(SB),NOSPLIT,$0
-	MOVL	$-26, AX
-	CALL	runtime·sysenter(SB)
-	RET
-
-TEXT runtime·mach_task_self(SB),NOSPLIT,$0
-	MOVL	$-28, AX
-	CALL	runtime·sysenter(SB)
-	RET
-
-// Mach provides trap versions of the semaphore ops,
-// instead of requiring the use of RPC.
-
-// uint32 mach_semaphore_wait(uint32)
-TEXT runtime·mach_semaphore_wait(SB),NOSPLIT,$0
-	MOVL	$-36, AX
-	CALL	runtime·sysenter(SB)
-	RET
-
-// uint32 mach_semaphore_timedwait(uint32, uint32, uint32)
-TEXT runtime·mach_semaphore_timedwait(SB),NOSPLIT,$0
-	MOVL	$-38, AX
-	CALL	runtime·sysenter(SB)
-	RET
-
-// uint32 mach_semaphore_signal(uint32)
-TEXT runtime·mach_semaphore_signal(SB),NOSPLIT,$0
-	MOVL	$-33, AX
-	CALL	runtime·sysenter(SB)
-	RET
-
-// uint32 mach_semaphore_signal_all(uint32)
-TEXT runtime·mach_semaphore_signal_all(SB),NOSPLIT,$0
-	MOVL	$-34, AX
-	CALL	runtime·sysenter(SB)
-	RET
-
-// setldt(int entry, int address, int limit)
-// entry and limit are ignored.
-TEXT runtime·setldt(SB),NOSPLIT,$32
-	MOVL	address+4(FP), BX	// aka base
-
-	/*
-	 * When linking against the system libraries,
-	 * we use its pthread_create and let it set up %gs
-	 * for us.  When we do that, the private storage
-	 * we get is not at 0(GS) but at 0x468(GS).
-	 * 8l rewrites 0(TLS) into 0x468(GS) for us.
-	 * To accommodate that rewrite, we translate the
-	 * address and limit here so that 0x468(GS) maps to 0(address).
-	 *
-	 * See cgo/gcc_darwin_386.c:/468 for the derivation
-	 * of the constant.
-	 */
-	SUBL	$0x468, BX
-
-	/*
-	 * Must set up as USER_CTHREAD segment because
-	 * Darwin forces that value into %gs for signal handlers,
-	 * and if we don't set one up, we'll get a recursive
-	 * fault trying to get into the signal handler.
-	 * Since we have to set one up anyway, it might as
-	 * well be the value we want.  So don't bother with
-	 * i386_set_ldt.
-	 */
-	MOVL	BX, 4(SP)
-	MOVL	$3, AX	// thread_fast_set_cthread_self - machdep call #3
-	INT	$0x82	// sic: 0x82, not 0x80, for machdep call
-
-	XORL	AX, AX
-	MOVW	GS, AX
-	RET
-
-TEXT runtime·sysctl(SB),NOSPLIT,$0
-	MOVL	$202, AX
-	INT	$0x80
-	JAE	3(PC)
-	NEGL	AX
-	RET
-	MOVL	$0, AX
-	RET
-
-// int32 runtime·kqueue(void);
-TEXT runtime·kqueue(SB),NOSPLIT,$0
-	MOVL	$362, AX
-	INT	$0x80
-	JAE	2(PC)
-	NEGL	AX
-	RET
-
-// int32 runtime·kevent(int kq, Kevent *changelist, int nchanges, Kevent *eventlist, int nevents, Timespec *timeout);
-TEXT runtime·kevent(SB),NOSPLIT,$0
-	MOVL	$363, AX
-	INT	$0x80
-	JAE	2(PC)
-	NEGL	AX
-	RET
-
-// int32 runtime·closeonexec(int32 fd);
-TEXT runtime·closeonexec(SB),NOSPLIT,$32
-	MOVL	$92, AX  // fcntl
-	// 0(SP) is where the caller PC would be; kernel skips it
-	MOVL	fd+0(FP), BX
-	MOVL	BX, 4(SP)  // fd
-	MOVL	$2, 8(SP)  // F_SETFD
-	MOVL	$1, 12(SP)  // FD_CLOEXEC
-	INT	$0x80
-	JAE	2(PC)
-	NEGL	AX
-	RET
diff --git a/src/pkg/runtime/sys_darwin_amd64.s b/src/pkg/runtime/sys_darwin_amd64.s
deleted file mode 100644
index a0c81b5..0000000
--- a/src/pkg/runtime/sys_darwin_amd64.s
+++ /dev/null
@@ -1,480 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//
-// System calls and other sys.stuff for AMD64, Darwin
-// See http://fxr.watson.org/fxr/source/bsd/kern/syscalls.c?v=xnu-1228
-// or /usr/include/sys/syscall.h (on a Mac) for system call numbers.
-//
-// The low 24 bits are the system call number.
-// The high 8 bits specify the kind of system call: 1=Mach, 2=BSD, 3=Machine-Dependent.
-//
-
-#include "zasm_GOOS_GOARCH.h"
-#include "../../cmd/ld/textflag.h"
-
-// Exit the entire program (like C exit)
-TEXT runtime·exit(SB),NOSPLIT,$0
-	MOVL	8(SP), DI		// arg 1 exit status
-	MOVL	$(0x2000000+1), AX	// syscall entry
-	SYSCALL
-	MOVL	$0xf1, 0xf1  // crash
-	RET
-
-// Exit this OS thread (like pthread_exit, which eventually
-// calls __bsdthread_terminate).
-TEXT runtime·exit1(SB),NOSPLIT,$0
-	MOVL	8(SP), DI		// arg 1 exit status
-	MOVL	$(0x2000000+361), AX	// syscall entry
-	SYSCALL
-	MOVL	$0xf1, 0xf1  // crash
-	RET
-
-TEXT runtime·open(SB),NOSPLIT,$0
-	MOVQ	8(SP), DI		// arg 1 pathname
-	MOVL	16(SP), SI		// arg 2 flags
-	MOVL	20(SP), DX		// arg 3 mode
-	MOVL	$(0x2000000+5), AX	// syscall entry
-	SYSCALL
-	RET
-
-TEXT runtime·close(SB),NOSPLIT,$0
-	MOVL	8(SP), DI		// arg 1 fd
-	MOVL	$(0x2000000+6), AX	// syscall entry
-	SYSCALL
-	RET
-
-TEXT runtime·read(SB),NOSPLIT,$0
-	MOVL	8(SP), DI		// arg 1 fd
-	MOVQ	16(SP), SI		// arg 2 buf
-	MOVL	24(SP), DX		// arg 3 count
-	MOVL	$(0x2000000+3), AX	// syscall entry
-	SYSCALL
-	RET
-
-TEXT runtime·write(SB),NOSPLIT,$0
-	MOVL	8(SP), DI		// arg 1 fd
-	MOVQ	16(SP), SI		// arg 2 buf
-	MOVL	24(SP), DX		// arg 3 count
-	MOVL	$(0x2000000+4), AX	// syscall entry
-	SYSCALL
-	RET
-
-TEXT runtime·raise(SB),NOSPLIT,$24
-	MOVL	$(0x2000000+20), AX // getpid
-	SYSCALL
-	MOVQ	AX, DI	// arg 1 - pid
-	MOVL	sig+0(FP), SI	// arg 2 - signal
-	MOVL	$1, DX	// arg 3 - posix
-	MOVL	$(0x2000000+37), AX // kill
-	SYSCALL
-	RET
-
-TEXT runtime·setitimer(SB), NOSPLIT, $0
-	MOVL	8(SP), DI
-	MOVQ	16(SP), SI
-	MOVQ	24(SP), DX
-	MOVL	$(0x2000000+83), AX	// syscall entry
-	SYSCALL
-	RET
-
-TEXT runtime·madvise(SB), NOSPLIT, $0
-	MOVQ	8(SP), DI		// arg 1 addr
-	MOVQ	16(SP), SI		// arg 2 len
-	MOVL	24(SP), DX		// arg 3 advice
-	MOVL	$(0x2000000+75), AX	// syscall entry madvise
-	SYSCALL
-	// ignore failure - maybe pages are locked
-	RET
-
-// OS X comm page time offsets
-// http://www.opensource.apple.com/source/xnu/xnu-1699.26.8/osfmk/i386/cpu_capabilities.h
-#define	nt_tsc_base	0x50
-#define	nt_scale	0x58
-#define	nt_shift	0x5c
-#define	nt_ns_base	0x60
-#define	nt_generation	0x68
-#define	gtod_generation	0x6c
-#define	gtod_ns_base	0x70
-#define	gtod_sec_base	0x78
-
-// int64 nanotime(void)
-TEXT runtime·nanotime(SB), NOSPLIT, $32
-	MOVQ	$0x7fffffe00000, BP	/* comm page base */
-	// Loop trying to take a consistent snapshot
-	// of the time parameters.
-timeloop:
-	MOVL	gtod_generation(BP), R8
-	TESTL	R8, R8
-	JZ	systime
-	MOVL	nt_generation(BP), R9
-	TESTL	R9, R9
-	JZ	timeloop
-	RDTSC
-	MOVQ	nt_tsc_base(BP), R10
-	MOVL	nt_scale(BP), R11
-	MOVQ	nt_ns_base(BP), R12
-	CMPL	nt_generation(BP), R9
-	JNE	timeloop
-	MOVQ	gtod_ns_base(BP), R13
-	MOVQ	gtod_sec_base(BP), R14
-	CMPL	gtod_generation(BP), R8
-	JNE	timeloop
-
-	// Gathered all the data we need. Compute time.
-	//	((tsc - nt_tsc_base) * nt_scale) >> 32 + nt_ns_base - gtod_ns_base + gtod_sec_base*1e9
-	// The multiply and shift extracts the top 64 bits of the 96-bit product.
-	SHLQ	$32, DX
-	ADDQ	DX, AX
-	SUBQ	R10, AX
-	MULQ	R11
-	SHRQ	$32, AX:DX
-	ADDQ	R12, AX
-	SUBQ	R13, AX
-	IMULQ	$1000000000, R14
-	ADDQ	R14, AX
-	RET
-
-systime:
-	// Fall back to system call (usually first call in this thread).
-	MOVQ	SP, DI	// must be non-nil, unused
-	MOVQ	$0, SI
-	MOVL	$(0x2000000+116), AX
-	SYSCALL
-	// sec is in AX, usec in DX
-	// return nsec in AX
-	IMULQ	$1000000000, AX
-	IMULQ	$1000, DX
-	ADDQ	DX, AX
-	RET
-
-// func now() (sec int64, nsec int32)
-TEXT time·now(SB),NOSPLIT,$0
-	CALL	runtime·nanotime(SB)
-
-	// generated code for
-	//	func f(x uint64) (uint64, uint64) { return x/1000000000, x%100000000 }
-	// adapted to reduce duplication
-	MOVQ	AX, CX
-	MOVQ	$1360296554856532783, AX
-	MULQ	CX
-	ADDQ	CX, DX
-	RCRQ	$1, DX
-	SHRQ	$29, DX
-	MOVQ	DX, sec+0(FP)
-	IMULQ	$1000000000, DX
-	SUBQ	DX, CX
-	MOVL	CX, nsec+8(FP)
-	RET
-
-TEXT runtime·sigprocmask(SB),NOSPLIT,$0
-	MOVL	8(SP), DI
-	MOVQ	16(SP), SI
-	MOVQ	24(SP), DX
-	MOVL	$(0x2000000+329), AX  // pthread_sigmask (on OS X, sigprocmask==entire process)
-	SYSCALL
-	JCC	2(PC)
-	MOVL	$0xf1, 0xf1  // crash
-	RET
-
-TEXT runtime·sigaction(SB),NOSPLIT,$0
-	MOVL	8(SP), DI		// arg 1 sig
-	MOVQ	16(SP), SI		// arg 2 act
-	MOVQ	24(SP), DX		// arg 3 oact
-	MOVQ	24(SP), CX		// arg 3 oact
-	MOVQ	24(SP), R10		// arg 3 oact
-	MOVL	$(0x2000000+46), AX	// syscall entry
-	SYSCALL
-	JCC	2(PC)
-	MOVL	$0xf1, 0xf1  // crash
-	RET
-
-TEXT runtime·sigtramp(SB),NOSPLIT,$64
-	get_tls(BX)
-
-	MOVQ	R8, 32(SP)	// save ucontext
-	MOVQ	SI, 40(SP)	// save infostyle
-
-	// check that m exists
-	MOVQ	m(BX), BP
-	CMPQ	BP, $0
-	JNE	5(PC)
-	MOVL	DX, 0(SP)
-	MOVQ	$runtime·badsignal(SB), AX
-	CALL	AX
-	JMP 	sigtramp_ret
-
-	// save g
-	MOVQ	g(BX), R10
-	MOVQ	R10, 48(SP)
-
-	// g = m->gsignal
-	MOVQ	m_gsignal(BP), BP
-	MOVQ	BP, g(BX)
-
-	MOVL	DX, 0(SP)
-	MOVQ	CX, 8(SP)
-	MOVQ	R8, 16(SP)
-	MOVQ	R10, 24(SP)
-
-	CALL	DI
-
-	// restore g
-	get_tls(BX)
-	MOVQ	48(SP), R10
-	MOVQ	R10, g(BX)
-
-sigtramp_ret:
-	// call sigreturn
-	MOVL	$(0x2000000+184), AX	// sigreturn(ucontext, infostyle)
-	MOVQ	32(SP), DI	// saved ucontext
-	MOVQ	40(SP), SI	// saved infostyle
-	SYSCALL
-	INT $3	// not reached
-
-TEXT runtime·mmap(SB),NOSPLIT,$0
-	MOVQ	8(SP), DI		// arg 1 addr
-	MOVQ	16(SP), SI		// arg 2 len
-	MOVL	24(SP), DX		// arg 3 prot
-	MOVL	28(SP), R10		// arg 4 flags
-	MOVL	32(SP), R8		// arg 5 fid
-	MOVL	36(SP), R9		// arg 6 offset
-	MOVL	$(0x2000000+197), AX	// syscall entry
-	SYSCALL
-	RET
-
-TEXT runtime·munmap(SB),NOSPLIT,$0
-	MOVQ	8(SP), DI		// arg 1 addr
-	MOVQ	16(SP), SI		// arg 2 len
-	MOVL	$(0x2000000+73), AX	// syscall entry
-	SYSCALL
-	JCC	2(PC)
-	MOVL	$0xf1, 0xf1  // crash
-	RET
-
-TEXT runtime·sigaltstack(SB),NOSPLIT,$0
-	MOVQ	new+8(SP), DI
-	MOVQ	old+16(SP), SI
-	MOVQ	$(0x2000000+53), AX
-	SYSCALL
-	JCC	2(PC)
-	MOVL	$0xf1, 0xf1  // crash
-	RET
-
-TEXT runtime·usleep(SB),NOSPLIT,$16
-	MOVL	$0, DX
-	MOVL	usec+0(FP), AX
-	MOVL	$1000000, CX
-	DIVL	CX
-	MOVQ	AX, 0(SP)  // sec
-	MOVL	DX, 8(SP)  // usec
-
-	// select(0, 0, 0, 0, &tv)
-	MOVL	$0, DI
-	MOVL	$0, SI
-	MOVL	$0, DX
-	MOVL	$0, R10
-	MOVQ	SP, R8
-	MOVL	$(0x2000000+93), AX
-	SYSCALL
-	RET
-
-// void bsdthread_create(void *stk, M *mp, G *gp, void (*fn)(void))
-TEXT runtime·bsdthread_create(SB),NOSPLIT,$0
-	// Set up arguments to bsdthread_create system call.
-	// The ones in quotes pass through to the thread callback
-	// uninterpreted, so we can put whatever we want there.
-	MOVQ	fn+32(SP), DI	// "func"
-	MOVQ	mm+16(SP), SI	// "arg"
-	MOVQ	stk+8(SP), DX	// stack
-	MOVQ	gg+24(SP), R10	// "pthread"
-	MOVQ	$0x01000000, R8	// flags = PTHREAD_START_CUSTOM
-	MOVQ	$0, R9	// paranoia
-	MOVQ	$(0x2000000+360), AX	// bsdthread_create
-	SYSCALL
-	JCC 3(PC)
-	NEGQ	AX
-	RET
-	MOVL	$0, AX
-	RET
-
-// The thread that bsdthread_create creates starts executing here,
-// because we registered this function using bsdthread_register
-// at startup.
-//	DI = "pthread"
-//	SI = mach thread port
-//	DX = "func" (= fn)
-//	CX = "arg" (= m)
-//	R8 = stack
-//	R9 = flags (= 0)
-//	SP = stack - C_64_REDZONE_LEN (= stack - 128)
-TEXT runtime·bsdthread_start(SB),NOSPLIT,$0
-	MOVQ	R8, SP		// empirically, SP is very wrong but R8 is right
-
-	PUSHQ	DX
-	PUSHQ	CX
-	PUSHQ	SI
-
-	// set up thread local storage pointing at m->tls.
-	LEAQ	m_tls(CX), DI
-	CALL	runtime·settls(SB)
-
-	POPQ	SI
-	POPQ	CX
-	POPQ	DX
-
-	get_tls(BX)
-	MOVQ	CX, m(BX)
-	MOVQ	SI, m_procid(CX)	// thread port is m->procid
-	MOVQ	m_g0(CX), AX
-	MOVQ	AX, g(BX)
-	CALL	runtime·stackcheck(SB)	// smashes AX, CX
-	CALL	DX	// fn
-	CALL	runtime·exit1(SB)
-	RET
-
-// void bsdthread_register(void)
-// registers callbacks for threadstart (see bsdthread_create above
-// and wqthread and pthsize (not used).  returns 0 on success.
-TEXT runtime·bsdthread_register(SB),NOSPLIT,$0
-	MOVQ	$runtime·bsdthread_start(SB), DI	// threadstart
-	MOVQ	$0, SI	// wqthread, not used by us
-	MOVQ	$0, DX	// pthsize, not used by us
-	MOVQ	$0, R10	// dummy_value [sic]
-	MOVQ	$0, R8	// targetconc_ptr
-	MOVQ	$0, R9	// dispatchqueue_offset
-	MOVQ	$(0x2000000+366), AX	// bsdthread_register
-	SYSCALL
-	JCC 3(PC)
-	NEGQ	AX
-	RET
-	MOVL	$0, AX
-	RET
-
-// Mach system calls use 0x1000000 instead of the BSD's 0x2000000.
-
-// uint32 mach_msg_trap(void*, uint32, uint32, uint32, uint32, uint32, uint32)
-TEXT runtime·mach_msg_trap(SB),NOSPLIT,$0
-	MOVQ	8(SP), DI
-	MOVL	16(SP), SI
-	MOVL	20(SP), DX
-	MOVL	24(SP), R10
-	MOVL	28(SP), R8
-	MOVL	32(SP), R9
-	MOVL	36(SP), R11
-	PUSHQ	R11	// seventh arg, on stack
-	MOVL	$(0x1000000+31), AX	// mach_msg_trap
-	SYSCALL
-	POPQ	R11
-	RET
-
-TEXT runtime·mach_task_self(SB),NOSPLIT,$0
-	MOVL	$(0x1000000+28), AX	// task_self_trap
-	SYSCALL
-	RET
-
-TEXT runtime·mach_thread_self(SB),NOSPLIT,$0
-	MOVL	$(0x1000000+27), AX	// thread_self_trap
-	SYSCALL
-	RET
-
-TEXT runtime·mach_reply_port(SB),NOSPLIT,$0
-	MOVL	$(0x1000000+26), AX	// mach_reply_port
-	SYSCALL
-	RET
-
-// Mach provides trap versions of the semaphore ops,
-// instead of requiring the use of RPC.
-
-// uint32 mach_semaphore_wait(uint32)
-TEXT runtime·mach_semaphore_wait(SB),NOSPLIT,$0
-	MOVL	8(SP), DI
-	MOVL	$(0x1000000+36), AX	// semaphore_wait_trap
-	SYSCALL
-	RET
-
-// uint32 mach_semaphore_timedwait(uint32, uint32, uint32)
-TEXT runtime·mach_semaphore_timedwait(SB),NOSPLIT,$0
-	MOVL	8(SP), DI
-	MOVL	12(SP), SI
-	MOVL	16(SP), DX
-	MOVL	$(0x1000000+38), AX	// semaphore_timedwait_trap
-	SYSCALL
-	RET
-
-// uint32 mach_semaphore_signal(uint32)
-TEXT runtime·mach_semaphore_signal(SB),NOSPLIT,$0
-	MOVL	8(SP), DI
-	MOVL	$(0x1000000+33), AX	// semaphore_signal_trap
-	SYSCALL
-	RET
-
-// uint32 mach_semaphore_signal_all(uint32)
-TEXT runtime·mach_semaphore_signal_all(SB),NOSPLIT,$0
-	MOVL	8(SP), DI
-	MOVL	$(0x1000000+34), AX	// semaphore_signal_all_trap
-	SYSCALL
-	RET
-
-// set tls base to DI
-TEXT runtime·settls(SB),NOSPLIT,$32
-	/*
-	* Same as in sys_darwin_386.s:/ugliness, different constant.
-	* See cgo/gcc_darwin_amd64.c for the derivation
-	* of the constant.
-	*/
-	SUBQ $0x8a0, DI
-
-	MOVL	$(0x3000000+3), AX	// thread_fast_set_cthread_self - machdep call #3
-	SYSCALL
-	RET
-
-TEXT runtime·sysctl(SB),NOSPLIT,$0
-	MOVQ	8(SP), DI
-	MOVL	16(SP), SI
-	MOVQ	24(SP), DX
-	MOVQ	32(SP), R10
-	MOVQ	40(SP), R8
-	MOVQ	48(SP), R9
-	MOVL	$(0x2000000+202), AX	// syscall entry
-	SYSCALL
-	JCC 3(PC)
-	NEGQ	AX
-	RET
-	MOVL	$0, AX
-	RET
-
-// int32 runtime·kqueue(void);
-TEXT runtime·kqueue(SB),NOSPLIT,$0
-	MOVQ    $0, DI
-	MOVQ    $0, SI
-	MOVQ    $0, DX
-	MOVL	$(0x2000000+362), AX
-	SYSCALL
-	JCC	2(PC)
-	NEGQ	AX
-	RET
-
-// int32 runtime·kevent(int kq, Kevent *changelist, int nchanges, Kevent *eventlist, int nevents, Timespec *timeout);
-TEXT runtime·kevent(SB),NOSPLIT,$0
-	MOVL    8(SP), DI
-	MOVQ    16(SP), SI
-	MOVL    24(SP), DX
-	MOVQ    32(SP), R10
-	MOVL    40(SP), R8
-	MOVQ    48(SP), R9
-	MOVL	$(0x2000000+363), AX
-	SYSCALL
-	JCC	2(PC)
-	NEGQ	AX
-	RET
-
-// void runtime·closeonexec(int32 fd);
-TEXT runtime·closeonexec(SB),NOSPLIT,$0
-	MOVL    8(SP), DI  // fd
-	MOVQ    $2, SI  // F_SETFD
-	MOVQ    $1, DX  // FD_CLOEXEC
-	MOVL	$(0x2000000+92), AX  // fcntl
-	SYSCALL
-	RET
diff --git a/src/pkg/runtime/sys_dragonfly_386.s b/src/pkg/runtime/sys_dragonfly_386.s
deleted file mode 100644
index 20e6999..0000000
--- a/src/pkg/runtime/sys_dragonfly_386.s
+++ /dev/null
@@ -1,369 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-//
-// System calls and other sys.stuff for 386, FreeBSD
-// /usr/src/sys/kern/syscalls.master for syscall numbers.
-//
-
-#include "zasm_GOOS_GOARCH.h"
-#include "../../cmd/ld/textflag.h"
-	
-TEXT runtime·sys_umtx_sleep(SB),NOSPLIT,$-4
-	MOVL	$469, AX		// umtx_sleep
-	INT	$0x80
-	JAE	2(PC)
-	NEGL	AX
-	RET
-
-TEXT runtime·sys_umtx_wakeup(SB),NOSPLIT,$-4
-	MOVL	$470, AX		// umtx_wakeup
-	INT	$0x80
-	JAE	2(PC)
-	NEGL	AX
-	RET
-
-TEXT runtime·lwp_create(SB),NOSPLIT,$-4
-	MOVL	$495, AX		// lwp_create
-	INT	$0x80
-	RET
-
-TEXT runtime·lwp_start(SB),NOSPLIT,$0
-
-	// Set GS to point at m->tls.
-	MOVL	mm+0(FP), BX
-	MOVL	m_g0(BX), DX
-	LEAL	m_tls(BX), BP
-	PUSHAL
-	PUSHL	BP
-	CALL	runtime·settls(SB)
-	POPL	AX
-	POPAL
-	
-	// Now segment is established.  Initialize m, g.
-	get_tls(CX)
-	MOVL	BX, m(CX)
-	MOVL	DX, g(CX)
-
-	CALL	runtime·stackcheck(SB)	// smashes AX, CX
-	MOVL	0(DX), DX		// paranoia; check they are not nil
-	MOVL	0(BX), BX
-
-	// More paranoia; check that stack splitting code works.
-	PUSHAL
-	CALL	runtime·emptyfunc(SB)
-	POPAL
-
-	CALL	runtime·mstart(SB)
-
-	CALL	runtime·exit1(SB)
-	MOVL	$0x1234, 0x1005
-	RET
-
-// Exit the entire program (like C exit)
-TEXT runtime·exit(SB),NOSPLIT,$-4
-	MOVL	$1, AX
-	INT	$0x80
-	MOVL	$0xf1, 0xf1  // crash
-	RET
-
-TEXT runtime·exit1(SB),NOSPLIT,$16
-	MOVL	$0, 0(SP)		// syscall gap
-	MOVL	$0x10000, 4(SP)		// arg 1 - how (EXTEXIT_LWP)
-	MOVL	$0, 8(SP)		// arg 2 - status
-	MOVL	$0, 12(SP)		// arg 3 - addr
-	MOVL	$494, AX
-	INT	$0x80
-	JAE	2(PC)
-	MOVL	$0xf1, 0xf1  // crash
-	RET
-
-TEXT runtime·open(SB),NOSPLIT,$-4
-	MOVL	$5, AX
-	INT	$0x80
-	RET
-
-TEXT runtime·close(SB),NOSPLIT,$-4
-	MOVL	$6, AX
-	INT	$0x80
-	RET
-
-TEXT runtime·read(SB),NOSPLIT,$-4
-	MOVL	$3, AX
-	INT	$0x80
-	RET
-
-TEXT runtime·write(SB),NOSPLIT,$-4
-	MOVL	$4, AX
-	INT	$0x80
-	RET
-
-TEXT runtime·getrlimit(SB),NOSPLIT,$-4
-	MOVL	$194, AX
-	INT	$0x80
-	RET
-
-TEXT runtime·raise(SB),NOSPLIT,$16
-	MOVL	$496, AX		// lwp_gettid
-	INT	$0x80
-	MOVL	$0, 0(SP)
-	MOVL	$-1, 4(SP)		// arg 1 - pid
-	MOVL	AX, 8(SP)		// arg 2 - tid
-	MOVL	sig+0(FP), AX
-	MOVL	AX, 8(SP)		// arg 3 - signum
-	MOVL	$497, AX		// lwp_kill
-	INT	$0x80
-	RET
-
-TEXT runtime·mmap(SB),NOSPLIT,$36
-	LEAL	arg0+0(FP), SI
-	LEAL	4(SP), DI
-	CLD
-	MOVSL				// arg 1 - addr
-	MOVSL				// arg 2 - len
-	MOVSL				// arg 3 - prot
-	MOVSL				// arg 4 - flags
-	MOVSL				// arg 5 - fd
-	MOVL	$0, AX
-	STOSL				// arg 6 - pad
-	MOVSL				// arg 7 - offset
-	MOVL	$0, AX			// top 32 bits of file offset
-	STOSL
-	MOVL	$197, AX		// sys_mmap
-	INT	$0x80
-	RET
-
-TEXT runtime·munmap(SB),NOSPLIT,$-4
-	MOVL	$73, AX
-	INT	$0x80
-	JAE	2(PC)
-	MOVL	$0xf1, 0xf1  // crash
-	RET
-
-TEXT runtime·madvise(SB),NOSPLIT,$-4
-	MOVL	$75, AX	// madvise
-	INT	$0x80
-	// ignore failure - maybe pages are locked
-	RET
-
-TEXT runtime·setitimer(SB), NOSPLIT, $-4
-	MOVL	$83, AX
-	INT	$0x80
-	RET
-
-// func now() (sec int64, nsec int32)
-TEXT time·now(SB), NOSPLIT, $32
-	MOVL	$232, AX
-	LEAL	12(SP), BX
-	MOVL	$0, 4(SP)	// CLOCK_REALTIME
-	MOVL	BX, 8(SP)
-	INT	$0x80
-	MOVL	12(SP), AX	// sec
-	MOVL	16(SP), BX	// nsec
-
-	// sec is in AX, nsec in BX
-	MOVL	AX, sec+0(FP)
-	MOVL	$0, sec+4(FP)
-	MOVL	BX, nsec+8(FP)
-	RET
-
-// int64 nanotime(void) so really
-// void nanotime(int64 *nsec)
-TEXT runtime·nanotime(SB), NOSPLIT, $32
-	MOVL	$232, AX
-	LEAL	12(SP), BX
-	MOVL	$4, 4(SP)	// CLOCK_MONOTONIC
-	MOVL	BX, 8(SP)
-	INT	$0x80
-	MOVL	12(SP), AX	// sec
-	MOVL	16(SP), BX	// nsec
-
-	// sec is in AX, nsec in BX
-	// convert to DX:AX nsec
-	MOVL	$1000000000, CX
-	MULL	CX
-	ADDL	BX, AX
-	ADCL	$0, DX
-
-	MOVL	ret+0(FP), DI
-	MOVL	AX, 0(DI)
-	MOVL	DX, 4(DI)
-	RET
-
-
-TEXT runtime·sigaction(SB),NOSPLIT,$-4
-	MOVL	$342, AX
-	INT	$0x80
-	JAE	2(PC)
-	MOVL	$0xf1, 0xf1  // crash
-	RET
-
-TEXT runtime·sigtramp(SB),NOSPLIT,$44
-	get_tls(CX)
-
-	// check that m exists
-	MOVL	m(CX), BX
-	CMPL	BX, $0
-	JNE	6(PC)
-	MOVL	signo+0(FP), BX
-	MOVL	BX, 0(SP)
-	MOVL	$runtime·badsignal(SB), AX
-	CALL	AX
-	JMP 	sigtramp_ret
-
-	// save g
-	MOVL	g(CX), DI
-	MOVL	DI, 20(SP)
-	
-	// g = m->gsignal
-	MOVL	m_gsignal(BX), BX
-	MOVL	BX, g(CX)
-
-	// copy arguments for call to sighandler
-	MOVL	signo+0(FP), BX
-	MOVL	BX, 0(SP)
-	MOVL	info+4(FP), BX
-	MOVL	BX, 4(SP)
-	MOVL	context+8(FP), BX
-	MOVL	BX, 8(SP)
-	MOVL	DI, 12(SP)
-
-	CALL	runtime·sighandler(SB)
-
-	// restore g
-	get_tls(CX)
-	MOVL	20(SP), BX
-	MOVL	BX, g(CX)
-
-sigtramp_ret:
-	// call sigreturn
-	MOVL	context+8(FP), AX
-	MOVL	$0, 0(SP)	// syscall gap
-	MOVL	AX, 4(SP)
-	MOVL	$344, AX	// sigreturn(ucontext)
-	INT	$0x80
-	MOVL	$0xf1, 0xf1  // crash
-	RET
-
-TEXT runtime·sigaltstack(SB),NOSPLIT,$0
-	MOVL	$53, AX
-	INT	$0x80
-	JAE	2(PC)
-	MOVL	$0xf1, 0xf1  // crash
-	RET
-
-TEXT runtime·usleep(SB),NOSPLIT,$20
-	MOVL	$0, DX
-	MOVL	usec+0(FP), AX
-	MOVL	$1000000, CX
-	DIVL	CX
-	MOVL	AX, 12(SP)		// tv_sec
-	MOVL	$1000, AX
-	MULL	DX
-	MOVL	AX, 16(SP)		// tv_nsec
-
-	MOVL	$0, 0(SP)
-	LEAL	12(SP), AX
-	MOVL	AX, 4(SP)		// arg 1 - rqtp
-	MOVL	$0, 8(SP)		// arg 2 - rmtp
-	MOVL	$240, AX		// sys_nanosleep
-	INT	$0x80
-	RET
-
-TEXT runtime·setldt(SB),NOSPLIT,$4
-	// Under DragonFly we set the GS base instead of messing with the LDT.
-	MOVL	tls0+4(FP), AX
-	MOVL	AX, 0(SP)
-	CALL	runtime·settls(SB)
-	RET
-
-TEXT runtime·settls(SB),NOSPLIT,$24
-	// adjust for ELF: wants to use -8(GS) and -4(GS) for g and m
-	MOVL	tlsbase+0(FP), CX
-	ADDL	$8, CX
-
-	// Set up a struct tls_info - a size of -1 maps the whole address
-	// space and is required for direct-tls access of variable data
-	// via negative offsets.
-	LEAL	16(SP), BX
-	MOVL	CX, 16(SP)		// base
-	MOVL	$-1, 20(SP)		// size
-
-	// set_tls_area returns the descriptor that needs to be loaded into GS.
-	MOVL	$0, 0(SP)		// syscall gap
-	MOVL	$0, 4(SP)		// arg 1 - which
-	MOVL	BX, 8(SP)		// arg 2 - tls_info
-	MOVL	$8, 12(SP)		// arg 3 - infosize
-	MOVL    $472, AX                // set_tls_area
-	INT     $0x80
-	JCC     2(PC)
-	MOVL    $0xf1, 0xf1             // crash
-	MOVW	AX, GS
-	RET
-
-TEXT runtime·sysctl(SB),NOSPLIT,$28
-	LEAL	arg0+0(FP), SI
-	LEAL	4(SP), DI
-	CLD
-	MOVSL				// arg 1 - name
-	MOVSL				// arg 2 - namelen
-	MOVSL				// arg 3 - oldp
-	MOVSL				// arg 4 - oldlenp
-	MOVSL				// arg 5 - newp
-	MOVSL				// arg 6 - newlen
-	MOVL	$202, AX		// sys___sysctl
-	INT	$0x80
-	JCC	3(PC)
-	NEGL	AX
-	RET
-	MOVL	$0, AX
-	RET
-
-TEXT runtime·osyield(SB),NOSPLIT,$-4
-	MOVL	$331, AX		// sys_sched_yield
-	INT	$0x80
-	RET
-
-TEXT runtime·sigprocmask(SB),NOSPLIT,$16
-	MOVL	$0, 0(SP)		// syscall gap
-	MOVL	$3, 4(SP)		// arg 1 - how (SIG_SETMASK)
-	MOVL	args+0(FP), AX
-	MOVL	AX, 8(SP)		// arg 2 - set
-	MOVL	args+4(FP), AX
-	MOVL	AX, 12(SP)		// arg 3 - oset
-	MOVL	$340, AX		// sys_sigprocmask
-	INT	$0x80
-	JAE	2(PC)
-	MOVL	$0xf1, 0xf1  // crash
-	RET
-
-// int32 runtime·kqueue(void);
-TEXT runtime·kqueue(SB),NOSPLIT,$0
-	MOVL	$362, AX
-	INT	$0x80
-	JAE	2(PC)
-	NEGL	AX
-	RET
-
-// int32 runtime·kevent(int kq, Kevent *changelist, int nchanges, Kevent *eventlist, int nevents, Timespec *timeout);
-TEXT runtime·kevent(SB),NOSPLIT,$0
-	MOVL	$363, AX
-	INT	$0x80
-	JAE	2(PC)
-	NEGL	AX
-	RET
-
-// int32 runtime·closeonexec(int32 fd);
-TEXT runtime·closeonexec(SB),NOSPLIT,$32
-	MOVL	$92, AX		// fcntl
-	// 0(SP) is where the caller PC would be; kernel skips it
-	MOVL	fd+0(FP), BX
-	MOVL	BX, 4(SP)	// fd
-	MOVL	$2, 8(SP)	// F_SETFD
-	MOVL	$1, 12(SP)	// FD_CLOEXEC
-	INT	$0x80
-	JAE	2(PC)
-	NEGL	AX
-	RET
-
-GLOBL runtime·tlsoffset(SB),$4
diff --git a/src/pkg/runtime/sys_dragonfly_amd64.s b/src/pkg/runtime/sys_dragonfly_amd64.s
deleted file mode 100644
index d70d2e8..0000000
--- a/src/pkg/runtime/sys_dragonfly_amd64.s
+++ /dev/null
@@ -1,330 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-//
-// System calls and other sys.stuff for AMD64, FreeBSD
-// /usr/src/sys/kern/syscalls.master for syscall numbers.
-//
-
-#include "zasm_GOOS_GOARCH.h"
-#include "../../cmd/ld/textflag.h"
-	
-TEXT runtime·sys_umtx_sleep(SB),NOSPLIT,$0
-	MOVQ 8(SP), DI		// arg 1 - ptr
-	MOVL 16(SP), SI		// arg 2 - value
-	MOVL 20(SP), DX		// arg 3 - timeout
-	MOVL $469, AX		// umtx_sleep
-	SYSCALL
-	JCC	2(PC)
-	NEGQ	AX
-	RET
-
-TEXT runtime·sys_umtx_wakeup(SB),NOSPLIT,$0
-	MOVQ 8(SP), DI		// arg 1 - ptr
-	MOVL 16(SP), SI		// arg 2 - count
-	MOVL $470, AX		// umtx_wakeup
-	SYSCALL
-	JCC	2(PC)
-	NEGQ	AX
-	RET
-
-TEXT runtime·lwp_create(SB),NOSPLIT,$0
-	MOVQ 8(SP), DI		// arg 1 - params
-	MOVL $495, AX		// lwp_create
-	SYSCALL
-	RET
-
-TEXT runtime·lwp_start(SB),NOSPLIT,$0
-	MOVQ	DI, R13 // m
-
-	// set up FS to point at m->tls
-	LEAQ	m_tls(R13), DI
-	CALL	runtime·settls(SB)	// smashes DI
-
-	// set up m, g
-	get_tls(CX)
-	MOVQ	R13, m(CX)
-	MOVQ	m_g0(R13), DI
-	MOVQ	DI, g(CX)
-
-	CALL	runtime·stackcheck(SB)
-	CALL	runtime·mstart(SB)
-
-	MOVQ 0, AX			// crash (not reached)
-
-// Exit the entire program (like C exit)
-TEXT runtime·exit(SB),NOSPLIT,$-8
-	MOVL	8(SP), DI		// arg 1 exit status
-	MOVL	$1, AX
-	SYSCALL
-	MOVL	$0xf1, 0xf1  // crash
-	RET
-
-TEXT runtime·exit1(SB),NOSPLIT,$-8
-	MOVQ	8(SP), DI		// arg 1 exit status
-	MOVL	$431, AX
-	SYSCALL
-	MOVL	$0xf1, 0xf1  // crash
-	RET
-
-TEXT runtime·open(SB),NOSPLIT,$-8
-	MOVQ	8(SP), DI		// arg 1 pathname
-	MOVL	16(SP), SI		// arg 2 flags
-	MOVL	20(SP), DX		// arg 3 mode
-	MOVL	$5, AX
-	SYSCALL
-	RET
-
-TEXT runtime·close(SB),NOSPLIT,$-8
-	MOVL	8(SP), DI		// arg 1 fd
-	MOVL	$6, AX
-	SYSCALL
-	RET
-
-TEXT runtime·read(SB),NOSPLIT,$-8
-	MOVL	8(SP), DI		// arg 1 fd
-	MOVQ	16(SP), SI		// arg 2 buf
-	MOVL	24(SP), DX		// arg 3 count
-	MOVL	$3, AX
-	SYSCALL
-	RET
-
-TEXT runtime·write(SB),NOSPLIT,$-8
-	MOVL	8(SP), DI		// arg 1 fd
-	MOVQ	16(SP), SI		// arg 2 buf
-	MOVL	24(SP), DX		// arg 3 count
-	MOVL	$4, AX
-	SYSCALL
-	RET
-
-TEXT runtime·getrlimit(SB),NOSPLIT,$-8
-	MOVL	8(SP), DI
-	MOVQ	16(SP), SI
-	MOVL	$194, AX
-	SYSCALL
-	RET
-
-TEXT runtime·raise(SB),NOSPLIT,$16
-	MOVL	$496, AX	// lwp_gettid
-	SYSCALL
-	MOVQ	$-1, DI		// arg 1 - pid
-	MOVQ	8(SP), DI	// arg 2 - tid
-	MOVL	sig+0(FP), SI	// arg 3 - signum
-	MOVL	$497, AX	// lwp_kill
-	SYSCALL
-	RET
-
-TEXT runtime·setitimer(SB), NOSPLIT, $-8
-	MOVL	8(SP), DI
-	MOVQ	16(SP), SI
-	MOVQ	24(SP), DX
-	MOVL	$83, AX
-	SYSCALL
-	RET
-
-// func now() (sec int64, nsec int32)
-TEXT time·now(SB), NOSPLIT, $32
-	MOVL	$232, AX
-	MOVQ	$0, DI  	// CLOCK_REALTIME
-	LEAQ	8(SP), SI
-	SYSCALL
-	MOVQ	8(SP), AX	// sec
-	MOVQ	16(SP), DX	// nsec
-
-	// sec is in AX, nsec in DX
-	MOVQ	AX, sec+0(FP)
-	MOVL	DX, nsec+8(FP)
-	RET
-
-TEXT runtime·nanotime(SB), NOSPLIT, $32
-	MOVL	$232, AX
-	MOVQ	$4, DI  	// CLOCK_MONOTONIC
-	LEAQ	8(SP), SI
-	SYSCALL
-	MOVQ	8(SP), AX	// sec
-	MOVQ	16(SP), DX	// nsec
-
-	// sec is in AX, nsec in DX
-	// return nsec in AX
-	IMULQ	$1000000000, AX
-	ADDQ	DX, AX
-	RET
-
-TEXT runtime·sigaction(SB),NOSPLIT,$-8
-	MOVL	8(SP), DI		// arg 1 sig
-	MOVQ	16(SP), SI		// arg 2 act
-	MOVQ	24(SP), DX		// arg 3 oact
-	MOVL	$342, AX
-	SYSCALL
-	JCC	2(PC)
-	MOVL	$0xf1, 0xf1  // crash
-	RET
-
-TEXT runtime·sigtramp(SB),NOSPLIT,$64
-	get_tls(BX)
-
-	// check that m exists
-	MOVQ	m(BX), BP
-	CMPQ	BP, $0
-	JNE	5(PC)
-	MOVQ	DI, 0(SP)
-	MOVQ	$runtime·badsignal(SB), AX
-	CALL	AX
-	RET
-
-	// save g
-	MOVQ	g(BX), R10
-	MOVQ	R10, 40(SP)
-	
-	// g = m->signal
-	MOVQ	m_gsignal(BP), BP
-	MOVQ	BP, g(BX)
-	
-	MOVQ	DI, 0(SP)
-	MOVQ	SI, 8(SP)
-	MOVQ	DX, 16(SP)
-	MOVQ	R10, 24(SP)
-
-	CALL	runtime·sighandler(SB)
-
-	// restore g
-	get_tls(BX)
-	MOVQ	40(SP), R10
-	MOVQ	R10, g(BX)
-	RET
-
-TEXT runtime·mmap(SB),NOSPLIT,$0
-	MOVQ	8(SP), DI		// arg 1 - addr
-	MOVQ	16(SP), SI		// arg 2 - len
-	MOVL	24(SP), DX		// arg 3 - prot
-	MOVL	28(SP), R10		// arg 4 - flags
-	MOVL	32(SP), R8		// arg 5 - fd
-	MOVL	36(SP), R9
-	SUBQ	$16, SP
-	MOVQ	R9, 8(SP)		// arg 7 - offset (passed on stack)
-	MOVQ	$0, R9			// arg 6 - pad
-	MOVL	$197, AX
-	SYSCALL
-	ADDQ	$16, SP
-	RET
-
-TEXT runtime·munmap(SB),NOSPLIT,$0
-	MOVQ	8(SP), DI		// arg 1 addr
-	MOVQ	16(SP), SI		// arg 2 len
-	MOVL	$73, AX
-	SYSCALL
-	JCC	2(PC)
-	MOVL	$0xf1, 0xf1  // crash
-	RET
-
-TEXT runtime·madvise(SB),NOSPLIT,$0
-	MOVQ	8(SP), DI
-	MOVQ	16(SP), SI
-	MOVQ	24(SP), DX
-	MOVQ	$75, AX	// madvise
-	SYSCALL
-	// ignore failure - maybe pages are locked
-	RET
-	
-TEXT runtime·sigaltstack(SB),NOSPLIT,$-8
-	MOVQ	new+8(SP), DI
-	MOVQ	old+16(SP), SI
-	MOVQ	$53, AX
-	SYSCALL
-	JCC	2(PC)
-	MOVL	$0xf1, 0xf1  // crash
-	RET
-
-TEXT runtime·usleep(SB),NOSPLIT,$16
-	MOVL	$0, DX
-	MOVL	usec+0(FP), AX
-	MOVL	$1000000, CX
-	DIVL	CX
-	MOVQ	AX, 0(SP)		// tv_sec
-	MOVL	$1000, AX
-	MULL	DX
-	MOVQ	AX, 8(SP)		// tv_nsec
-
-	MOVQ	SP, DI			// arg 1 - rqtp
-	MOVQ	$0, SI			// arg 2 - rmtp
-	MOVL	$240, AX		// sys_nanosleep
-	SYSCALL
-	RET
-
-// set tls base to DI
-TEXT runtime·settls(SB),NOSPLIT,$16
-	ADDQ	$16, DI	// adjust for ELF: wants to use -16(FS) and -8(FS) for g and m
-	MOVQ	DI, 0(SP)
-	MOVQ	$16, 8(SP)
-	MOVQ	$0, DI			// arg 1 - which
-	MOVQ	SP, SI			// arg 2 - tls_info
-	MOVQ	$16, DX			// arg 3 - infosize
-	MOVQ	$472, AX		// set_tls_area
-	SYSCALL
-	JCC	2(PC)
-	MOVL	$0xf1, 0xf1  // crash
-	RET
-
-TEXT runtime·sysctl(SB),NOSPLIT,$0
-	MOVQ	8(SP), DI		// arg 1 - name
-	MOVL	16(SP), SI		// arg 2 - namelen
-	MOVQ	24(SP), DX		// arg 3 - oldp
-	MOVQ	32(SP), R10		// arg 4 - oldlenp
-	MOVQ	40(SP), R8		// arg 5 - newp
-	MOVQ	48(SP), R9		// arg 6 - newlen
-	MOVQ	$202, AX		// sys___sysctl
-	SYSCALL
-	JCC 3(PC)
-	NEGQ	AX
-	RET
-	MOVL	$0, AX
-	RET
-
-TEXT runtime·osyield(SB),NOSPLIT,$-4
-	MOVL	$331, AX		// sys_sched_yield
-	SYSCALL
-	RET
-
-TEXT runtime·sigprocmask(SB),NOSPLIT,$0
-	MOVL	$3, DI			// arg 1 - how (SIG_SETMASK)
-	MOVQ	8(SP), SI		// arg 2 - set
-	MOVQ	16(SP), DX		// arg 3 - oset
-	MOVL	$340, AX		// sys_sigprocmask
-	SYSCALL
-	JAE	2(PC)
-	MOVL	$0xf1, 0xf1  // crash
-	RET
-
-// int32 runtime·kqueue(void);
-TEXT runtime·kqueue(SB),NOSPLIT,$0
-	MOVQ	$0, DI
-	MOVQ	$0, SI
-	MOVQ	$0, DX
-	MOVL	$362, AX
-	SYSCALL
-	JCC	2(PC)
-	NEGQ	AX
-	RET
-
-// int32 runtime·kevent(int kq, Kevent *changelist, int nchanges, Kevent *eventlist, int nevents, Timespec *timeout);
-TEXT runtime·kevent(SB),NOSPLIT,$0
-	MOVL	8(SP), DI
-	MOVQ	16(SP), SI
-	MOVL	24(SP), DX
-	MOVQ	32(SP), R10
-	MOVL	40(SP), R8
-	MOVQ	48(SP), R9
-	MOVL	$363, AX
-	SYSCALL
-	JCC	2(PC)
-	NEGQ	AX
-	RET
-
-// void runtime·closeonexec(int32 fd);
-TEXT runtime·closeonexec(SB),NOSPLIT,$0
-	MOVL	8(SP), DI	// fd
-	MOVQ	$2, SI		// F_SETFD
-	MOVQ	$1, DX		// FD_CLOEXEC
-	MOVL	$92, AX		// fcntl
-	SYSCALL
-	RET
diff --git a/src/pkg/runtime/sys_freebsd_386.s b/src/pkg/runtime/sys_freebsd_386.s
deleted file mode 100644
index 4c97eec..0000000
--- a/src/pkg/runtime/sys_freebsd_386.s
+++ /dev/null
@@ -1,381 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-//
-// System calls and other sys.stuff for 386, FreeBSD
-// /usr/src/sys/kern/syscalls.master for syscall numbers.
-//
-
-#include "zasm_GOOS_GOARCH.h"
-#include "../../cmd/ld/textflag.h"
-	
-TEXT runtime·sys_umtx_op(SB),NOSPLIT,$-4
-	MOVL	$454, AX
-	INT	$0x80
-	RET
-
-TEXT runtime·thr_new(SB),NOSPLIT,$-4
-	MOVL	$455, AX
-	INT	$0x80
-	RET
-
-TEXT runtime·thr_start(SB),NOSPLIT,$0
-	MOVL	mm+0(FP), AX
-	MOVL	m_g0(AX), BX
-	LEAL	m_tls(AX), BP
-	MOVL	0(BP), DI
-	ADDL	$7, DI
-	PUSHAL
-	PUSHL	$32
-	PUSHL	BP
-	PUSHL	DI
-	CALL	runtime·setldt(SB)
-	POPL	AX
-	POPL	AX
-	POPL	AX
-	POPAL
-	get_tls(CX)
-	MOVL	BX, g(CX)
-	
-	MOVL	AX, m(CX)
-	CALL	runtime·stackcheck(SB)		// smashes AX
-	CALL	runtime·mstart(SB)
-
-	MOVL	0, AX			// crash (not reached)
-
-// Exit the entire program (like C exit)
-TEXT runtime·exit(SB),NOSPLIT,$-4
-	MOVL	$1, AX
-	INT	$0x80
-	MOVL	$0xf1, 0xf1  // crash
-	RET
-
-TEXT runtime·exit1(SB),NOSPLIT,$-4
-	MOVL	$431, AX
-	INT	$0x80
-	JAE	2(PC)
-	MOVL	$0xf1, 0xf1  // crash
-	RET
-
-TEXT runtime·open(SB),NOSPLIT,$-4
-	MOVL	$5, AX
-	INT	$0x80
-	RET
-
-TEXT runtime·close(SB),NOSPLIT,$-4
-	MOVL	$6, AX
-	INT	$0x80
-	RET
-
-TEXT runtime·read(SB),NOSPLIT,$-4
-	MOVL	$3, AX
-	INT	$0x80
-	RET
-
-TEXT runtime·write(SB),NOSPLIT,$-4
-	MOVL	$4, AX
-	INT	$0x80
-	RET
-
-TEXT runtime·getrlimit(SB),NOSPLIT,$-4
-	MOVL	$194, AX
-	INT	$0x80
-	RET
-
-TEXT runtime·raise(SB),NOSPLIT,$16
-	// thr_self(&8(SP))
-	LEAL	8(SP), AX
-	MOVL	AX, 4(SP)
-	MOVL	$432, AX
-	INT	$0x80
-	// thr_kill(self, SIGPIPE)
-	MOVL	8(SP), AX
-	MOVL	AX, 4(SP)
-	MOVL	sig+0(FP), AX
-	MOVL	AX, 8(SP)
-	MOVL	$433, AX
-	INT	$0x80
-	RET
-
-TEXT runtime·mmap(SB),NOSPLIT,$32
-	LEAL arg0+0(FP), SI
-	LEAL	4(SP), DI
-	CLD
-	MOVSL
-	MOVSL
-	MOVSL
-	MOVSL
-	MOVSL
-	MOVSL
-	MOVL	$0, AX	// top 32 bits of file offset
-	STOSL
-	MOVL	$477, AX
-	INT	$0x80
-	RET
-
-TEXT runtime·munmap(SB),NOSPLIT,$-4
-	MOVL	$73, AX
-	INT	$0x80
-	JAE	2(PC)
-	MOVL	$0xf1, 0xf1  // crash
-	RET
-
-TEXT runtime·madvise(SB),NOSPLIT,$-4
-	MOVL	$75, AX	// madvise
-	INT	$0x80
-	// ignore failure - maybe pages are locked
-	RET
-
-TEXT runtime·setitimer(SB), NOSPLIT, $-4
-	MOVL	$83, AX
-	INT	$0x80
-	RET
-
-// func now() (sec int64, nsec int32)
-TEXT time·now(SB), NOSPLIT, $32
-	MOVL	$232, AX
-	LEAL	12(SP), BX
-	MOVL	$0, 4(SP)	// CLOCK_REALTIME
-	MOVL	BX, 8(SP)
-	INT	$0x80
-	MOVL	12(SP), AX	// sec
-	MOVL	16(SP), BX	// nsec
-
-	// sec is in AX, nsec in BX
-	MOVL	AX, sec+0(FP)
-	MOVL	$0, sec+4(FP)
-	MOVL	BX, nsec+8(FP)
-	RET
-
-// int64 nanotime(void) so really
-// void nanotime(int64 *nsec)
-TEXT runtime·nanotime(SB), NOSPLIT, $32
-	MOVL	$232, AX
-	LEAL	12(SP), BX
-	// We can use CLOCK_MONOTONIC_FAST here when we drop
-	// support for FreeBSD 8-STABLE.
-	MOVL	$4, 4(SP)	// CLOCK_MONOTONIC
-	MOVL	BX, 8(SP)
-	INT	$0x80
-	MOVL	12(SP), AX	// sec
-	MOVL	16(SP), BX	// nsec
-
-	// sec is in AX, nsec in BX
-	// convert to DX:AX nsec
-	MOVL	$1000000000, CX
-	MULL	CX
-	ADDL	BX, AX
-	ADCL	$0, DX
-
-	MOVL	ret+0(FP), DI
-	MOVL	AX, 0(DI)
-	MOVL	DX, 4(DI)
-	RET
-
-
-TEXT runtime·sigaction(SB),NOSPLIT,$-4
-	MOVL	$416, AX
-	INT	$0x80
-	JAE	2(PC)
-	MOVL	$0xf1, 0xf1  // crash
-	RET
-
-TEXT runtime·sigtramp(SB),NOSPLIT,$44
-	get_tls(CX)
-
-	// check that m exists
-	MOVL	m(CX), BX
-	CMPL	BX, $0
-	JNE	6(PC)
-	MOVL	signo+0(FP), BX
-	MOVL	BX, 0(SP)
-	MOVL	$runtime·badsignal(SB), AX
-	CALL	AX
-	JMP 	sigtramp_ret
-
-	// save g
-	MOVL	g(CX), DI
-	MOVL	DI, 20(SP)
-	
-	// g = m->gsignal
-	MOVL	m_gsignal(BX), BX
-	MOVL	BX, g(CX)
-
-	// copy arguments for call to sighandler
-	MOVL	signo+0(FP), BX
-	MOVL	BX, 0(SP)
-	MOVL	info+4(FP), BX
-	MOVL	BX, 4(SP)
-	MOVL	context+8(FP), BX
-	MOVL	BX, 8(SP)
-	MOVL	DI, 12(SP)
-
-	CALL	runtime·sighandler(SB)
-
-	// restore g
-	get_tls(CX)
-	MOVL	20(SP), BX
-	MOVL	BX, g(CX)
-
-sigtramp_ret:
-	// call sigreturn
-	MOVL	context+8(FP), AX
-	MOVL	$0, 0(SP)	// syscall gap
-	MOVL	AX, 4(SP)
-	MOVL	$417, AX	// sigreturn(ucontext)
-	INT	$0x80
-	MOVL	$0xf1, 0xf1  // crash
-	RET
-
-TEXT runtime·sigaltstack(SB),NOSPLIT,$0
-	MOVL	$53, AX
-	INT	$0x80
-	JAE	2(PC)
-	MOVL	$0xf1, 0xf1  // crash
-	RET
-
-TEXT runtime·usleep(SB),NOSPLIT,$20
-	MOVL	$0, DX
-	MOVL	usec+0(FP), AX
-	MOVL	$1000000, CX
-	DIVL	CX
-	MOVL	AX, 12(SP)		// tv_sec
-	MOVL	$1000, AX
-	MULL	DX
-	MOVL	AX, 16(SP)		// tv_nsec
-
-	MOVL	$0, 0(SP)
-	LEAL	12(SP), AX
-	MOVL	AX, 4(SP)		// arg 1 - rqtp
-	MOVL	$0, 8(SP)		// arg 2 - rmtp
-	MOVL	$240, AX		// sys_nanosleep
-	INT	$0x80
-	RET
-
-/*
-descriptor entry format for system call
-is the native machine format, ugly as it is:
-
-	2-byte limit
-	3-byte base
-	1-byte: 0x80=present, 0x60=dpl<<5, 0x1F=type
-	1-byte: 0x80=limit is *4k, 0x40=32-bit operand size,
-		0x0F=4 more bits of limit
-	1 byte: 8 more bits of base
-
-int i386_get_ldt(int, union ldt_entry *, int);
-int i386_set_ldt(int, const union ldt_entry *, int);
-
-*/
-
-// setldt(int entry, int address, int limit)
-TEXT runtime·setldt(SB),NOSPLIT,$32
-	MOVL	address+4(FP), BX	// aka base
-	// see comment in sys_linux_386.s; freebsd is similar
-	ADDL	$0x8, BX
-
-	// set up data_desc
-	LEAL	16(SP), AX	// struct data_desc
-	MOVL	$0, 0(AX)
-	MOVL	$0, 4(AX)
-
-	MOVW	BX, 2(AX)
-	SHRL	$16, BX
-	MOVB	BX, 4(AX)
-	SHRL	$8, BX
-	MOVB	BX, 7(AX)
-
-	MOVW	$0xffff, 0(AX)
-	MOVB	$0xCF, 6(AX)	// 32-bit operand, 4k limit unit, 4 more bits of limit
-
-	MOVB	$0xF2, 5(AX)	// r/w data descriptor, dpl=3, present
-
-	// call i386_set_ldt(entry, desc, 1)
-	MOVL	$0xffffffff, 0(SP)	// auto-allocate entry and return in AX
-	MOVL	AX, 4(SP)
-	MOVL	$1, 8(SP)
-	CALL	runtime·i386_set_ldt(SB)
-
-	// compute segment selector - (entry*8+7)
-	SHLL	$3, AX
-	ADDL	$7, AX
-	MOVW	AX, GS
-	RET
-
-TEXT runtime·i386_set_ldt(SB),NOSPLIT,$16
-	LEAL	args+0(FP), AX	// 0(FP) == 4(SP) before SP got moved
-	MOVL	$0, 0(SP)	// syscall gap
-	MOVL	$1, 4(SP)
-	MOVL	AX, 8(SP)
-	MOVL	$165, AX
-	INT	$0x80
-	JAE	2(PC)
-	INT	$3
-	RET
-
-TEXT runtime·sysctl(SB),NOSPLIT,$28
-	LEAL	arg0+0(FP), SI
-	LEAL	4(SP), DI
-	CLD
-	MOVSL				// arg 1 - name
-	MOVSL				// arg 2 - namelen
-	MOVSL				// arg 3 - oldp
-	MOVSL				// arg 4 - oldlenp
-	MOVSL				// arg 5 - newp
-	MOVSL				// arg 6 - newlen
-	MOVL	$202, AX		// sys___sysctl
-	INT	$0x80
-	JAE	3(PC)
-	NEGL	AX
-	RET
-	MOVL	$0, AX
-	RET
-
-TEXT runtime·osyield(SB),NOSPLIT,$-4
-	MOVL	$331, AX		// sys_sched_yield
-	INT	$0x80
-	RET
-
-TEXT runtime·sigprocmask(SB),NOSPLIT,$16
-	MOVL	$0, 0(SP)		// syscall gap
-	MOVL	$3, 4(SP)		// arg 1 - how (SIG_SETMASK)
-	MOVL	args+0(FP), AX
-	MOVL	AX, 8(SP)		// arg 2 - set
-	MOVL	args+4(FP), AX
-	MOVL	AX, 12(SP)		// arg 3 - oset
-	MOVL	$340, AX		// sys_sigprocmask
-	INT	$0x80
-	JAE	2(PC)
-	MOVL	$0xf1, 0xf1  // crash
-	RET
-
-// int32 runtime·kqueue(void);
-TEXT runtime·kqueue(SB),NOSPLIT,$0
-	MOVL	$362, AX
-	INT	$0x80
-	JAE	2(PC)
-	NEGL	AX
-	RET
-
-// int32 runtime·kevent(int kq, Kevent *changelist, int nchanges, Kevent *eventlist, int nevents, Timespec *timeout);
-TEXT runtime·kevent(SB),NOSPLIT,$0
-	MOVL	$363, AX
-	INT	$0x80
-	JAE	2(PC)
-	NEGL	AX
-	RET
-
-// int32 runtime·closeonexec(int32 fd);
-TEXT runtime·closeonexec(SB),NOSPLIT,$32
-	MOVL	$92, AX		// fcntl
-	// 0(SP) is where the caller PC would be; kernel skips it
-	MOVL	fd+0(FP), BX
-	MOVL	BX, 4(SP)	// fd
-	MOVL	$2, 8(SP)	// F_SETFD
-	MOVL	$1, 12(SP)	// FD_CLOEXEC
-	INT	$0x80
-	JAE	2(PC)
-	NEGL	AX
-	RET
-
-GLOBL runtime·tlsoffset(SB),$4
diff --git a/src/pkg/runtime/sys_freebsd_amd64.s b/src/pkg/runtime/sys_freebsd_amd64.s
deleted file mode 100644
index 4c5b325..0000000
--- a/src/pkg/runtime/sys_freebsd_amd64.s
+++ /dev/null
@@ -1,345 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-//
-// System calls and other sys.stuff for AMD64, FreeBSD
-// /usr/src/sys/kern/syscalls.master for syscall numbers.
-//
-
-#include "zasm_GOOS_GOARCH.h"
-#include "../../cmd/ld/textflag.h"
-
-// FreeBSD 8, FreeBSD 9, and older versions that I have checked
-// do not restore R10 on exit from a "restarted" system call
-// if you use the SYSCALL instruction. This means that, for example,
-// if a signal arrives while the wait4 system call is executing,
-// the wait4 internally returns ERESTART, which makes the kernel
-// back up the PC to execute the SYSCALL instruction a second time.
-// However, since the kernel does not restore R10, the fourth
-// argument to the system call has been lost. (FreeBSD 9 also fails
-// to restore the fifth and sixth arguments, R8 and R9, although
-// some earlier versions did restore those correctly.)
-// The broken code is in fast_syscall in FreeBSD's amd64/amd64/exception.S.
-// It restores only DI, SI, DX, AX, and RFLAGS on system call return.
-// http://fxr.watson.org/fxr/source/amd64/amd64/exception.S?v=FREEBSD91#L399
-//
-// The INT $0x80 system call path (int0x80_syscall in FreeBSD's 
-// amd64/ia32/ia32_exception.S) does not have this problem,
-// but it expects the third argument in R10. Instead of rewriting
-// all the assembly in this file, #define SYSCALL to a safe simulation
-// using INT $0x80.
-//
-// INT $0x80 is a little slower than SYSCALL, but correctness wins.
-//
-// See golang.org/issue/6372.
-#define SYSCALL MOVQ R10, CX; INT $0x80
-	
-TEXT runtime·sys_umtx_op(SB),NOSPLIT,$0
-	MOVQ 8(SP), DI
-	MOVL 16(SP), SI
-	MOVL 20(SP), DX
-	MOVQ 24(SP), R10
-	MOVQ 32(SP), R8
-	MOVL $454, AX
-	SYSCALL
-	RET
-
-TEXT runtime·thr_new(SB),NOSPLIT,$0
-	MOVQ 8(SP), DI
-	MOVQ 16(SP), SI
-	MOVL $455, AX
-	SYSCALL
-	RET
-
-TEXT runtime·thr_start(SB),NOSPLIT,$0
-	MOVQ	DI, R13 // m
-
-	// set up FS to point at m->tls
-	LEAQ	m_tls(R13), DI
-	CALL	runtime·settls(SB)	// smashes DI
-
-	// set up m, g
-	get_tls(CX)
-	MOVQ	R13, m(CX)
-	MOVQ	m_g0(R13), DI
-	MOVQ	DI, g(CX)
-
-	CALL	runtime·stackcheck(SB)
-	CALL	runtime·mstart(SB)
-
-	MOVQ 0, AX			// crash (not reached)
-
-// Exit the entire program (like C exit)
-TEXT runtime·exit(SB),NOSPLIT,$-8
-	MOVL	8(SP), DI		// arg 1 exit status
-	MOVL	$1, AX
-	SYSCALL
-	MOVL	$0xf1, 0xf1  // crash
-	RET
-
-TEXT runtime·exit1(SB),NOSPLIT,$-8
-	MOVQ	8(SP), DI		// arg 1 exit status
-	MOVL	$431, AX
-	SYSCALL
-	MOVL	$0xf1, 0xf1  // crash
-	RET
-
-TEXT runtime·open(SB),NOSPLIT,$-8
-	MOVQ	8(SP), DI		// arg 1 pathname
-	MOVL	16(SP), SI		// arg 2 flags
-	MOVL	20(SP), DX		// arg 3 mode
-	MOVL	$5, AX
-	SYSCALL
-	RET
-
-TEXT runtime·close(SB),NOSPLIT,$-8
-	MOVL	8(SP), DI		// arg 1 fd
-	MOVL	$6, AX
-	SYSCALL
-	RET
-
-TEXT runtime·read(SB),NOSPLIT,$-8
-	MOVL	8(SP), DI		// arg 1 fd
-	MOVQ	16(SP), SI		// arg 2 buf
-	MOVL	24(SP), DX		// arg 3 count
-	MOVL	$3, AX
-	SYSCALL
-	RET
-
-TEXT runtime·write(SB),NOSPLIT,$-8
-	MOVL	8(SP), DI		// arg 1 fd
-	MOVQ	16(SP), SI		// arg 2 buf
-	MOVL	24(SP), DX		// arg 3 count
-	MOVL	$4, AX
-	SYSCALL
-	RET
-
-TEXT runtime·getrlimit(SB),NOSPLIT,$-8
-	MOVL	8(SP), DI
-	MOVQ	16(SP), SI
-	MOVL	$194, AX
-	SYSCALL
-	RET
-
-TEXT runtime·raise(SB),NOSPLIT,$16
-	// thr_self(&8(SP))
-	LEAQ	8(SP), DI	// arg 1 &8(SP)
-	MOVL	$432, AX
-	SYSCALL
-	// thr_kill(self, SIGPIPE)
-	MOVQ	8(SP), DI	// arg 1 id
-	MOVL	sig+0(FP), SI	// arg 2
-	MOVL	$433, AX
-	SYSCALL
-	RET
-
-TEXT runtime·setitimer(SB), NOSPLIT, $-8
-	MOVL	8(SP), DI
-	MOVQ	16(SP), SI
-	MOVQ	24(SP), DX
-	MOVL	$83, AX
-	SYSCALL
-	RET
-
-// func now() (sec int64, nsec int32)
-TEXT time·now(SB), NOSPLIT, $32
-	MOVL	$232, AX
-	MOVQ	$0, DI		// CLOCK_REALTIME
-	LEAQ	8(SP), SI
-	SYSCALL
-	MOVQ	8(SP), AX	// sec
-	MOVQ	16(SP), DX	// nsec
-
-	// sec is in AX, nsec in DX
-	MOVQ	AX, sec+0(FP)
-	MOVL	DX, nsec+8(FP)
-	RET
-
-TEXT runtime·nanotime(SB), NOSPLIT, $32
-	MOVL	$232, AX
-	// We can use CLOCK_MONOTONIC_FAST here when we drop
-	// support for FreeBSD 8-STABLE.
-	MOVQ	$4, DI		// CLOCK_MONOTONIC
-	LEAQ	8(SP), SI
-	SYSCALL
-	MOVQ	8(SP), AX	// sec
-	MOVQ	16(SP), DX	// nsec
-
-	// sec is in AX, nsec in DX
-	// return nsec in AX
-	IMULQ	$1000000000, AX
-	ADDQ	DX, AX
-	RET
-
-TEXT runtime·sigaction(SB),NOSPLIT,$-8
-	MOVL	8(SP), DI		// arg 1 sig
-	MOVQ	16(SP), SI		// arg 2 act
-	MOVQ	24(SP), DX		// arg 3 oact
-	MOVL	$416, AX
-	SYSCALL
-	JCC	2(PC)
-	MOVL	$0xf1, 0xf1  // crash
-	RET
-
-TEXT runtime·sigtramp(SB),NOSPLIT,$64
-	get_tls(BX)
-
-	// check that m exists
-	MOVQ	m(BX), BP
-	CMPQ	BP, $0
-	JNE	5(PC)
-	MOVQ	DI, 0(SP)
-	MOVQ	$runtime·badsignal(SB), AX
-	CALL	AX
-	RET
-
-	// save g
-	MOVQ	g(BX), R10
-	MOVQ	R10, 40(SP)
-	
-	// g = m->signal
-	MOVQ	m_gsignal(BP), BP
-	MOVQ	BP, g(BX)
-	
-	MOVQ	DI, 0(SP)
-	MOVQ	SI, 8(SP)
-	MOVQ	DX, 16(SP)
-	MOVQ	R10, 24(SP)
-
-	CALL	runtime·sighandler(SB)
-
-	// restore g
-	get_tls(BX)
-	MOVQ	40(SP), R10
-	MOVQ	R10, g(BX)
-	RET
-
-TEXT runtime·mmap(SB),NOSPLIT,$0
-	MOVQ	8(SP), DI		// arg 1 addr
-	MOVQ	16(SP), SI		// arg 2 len
-	MOVL	24(SP), DX		// arg 3 prot
-	MOVL	28(SP), R10		// arg 4 flags
-	MOVL	32(SP), R8		// arg 5 fid
-	MOVL	36(SP), R9		// arg 6 offset
-	MOVL	$477, AX
-	SYSCALL
-	RET
-
-TEXT runtime·munmap(SB),NOSPLIT,$0
-	MOVQ	8(SP), DI		// arg 1 addr
-	MOVQ	16(SP), SI		// arg 2 len
-	MOVL	$73, AX
-	SYSCALL
-	JCC	2(PC)
-	MOVL	$0xf1, 0xf1  // crash
-	RET
-
-TEXT runtime·madvise(SB),NOSPLIT,$0
-	MOVQ	8(SP), DI
-	MOVQ	16(SP), SI
-	MOVQ	24(SP), DX
-	MOVQ	$75, AX	// madvise
-	SYSCALL
-	// ignore failure - maybe pages are locked
-	RET
-	
-TEXT runtime·sigaltstack(SB),NOSPLIT,$-8
-	MOVQ	new+8(SP), DI
-	MOVQ	old+16(SP), SI
-	MOVQ	$53, AX
-	SYSCALL
-	JCC	2(PC)
-	MOVL	$0xf1, 0xf1  // crash
-	RET
-
-TEXT runtime·usleep(SB),NOSPLIT,$16
-	MOVL	$0, DX
-	MOVL	usec+0(FP), AX
-	MOVL	$1000000, CX
-	DIVL	CX
-	MOVQ	AX, 0(SP)		// tv_sec
-	MOVL	$1000, AX
-	MULL	DX
-	MOVQ	AX, 8(SP)		// tv_nsec
-
-	MOVQ	SP, DI			// arg 1 - rqtp
-	MOVQ	$0, SI			// arg 2 - rmtp
-	MOVL	$240, AX		// sys_nanosleep
-	SYSCALL
-	RET
-
-// set tls base to DI
-TEXT runtime·settls(SB),NOSPLIT,$8
-	ADDQ	$16, DI	// adjust for ELF: wants to use -16(FS) and -8(FS) for g and m
-	MOVQ	DI, 0(SP)
-	MOVQ	SP, SI
-	MOVQ	$129, DI	// AMD64_SET_FSBASE
-	MOVQ	$165, AX	// sysarch
-	SYSCALL
-	JCC	2(PC)
-	MOVL	$0xf1, 0xf1  // crash
-	RET
-
-TEXT runtime·sysctl(SB),NOSPLIT,$0
-	MOVQ	8(SP), DI		// arg 1 - name
-	MOVL	16(SP), SI		// arg 2 - namelen
-	MOVQ	24(SP), DX		// arg 3 - oldp
-	MOVQ	32(SP), R10		// arg 4 - oldlenp
-	MOVQ	40(SP), R8		// arg 5 - newp
-	MOVQ	48(SP), R9		// arg 6 - newlen
-	MOVQ	$202, AX		// sys___sysctl
-	SYSCALL
-	JCC 3(PC)
-	NEGQ	AX
-	RET
-	MOVL	$0, AX
-	RET
-
-TEXT runtime·osyield(SB),NOSPLIT,$-4
-	MOVL	$331, AX		// sys_sched_yield
-	SYSCALL
-	RET
-
-TEXT runtime·sigprocmask(SB),NOSPLIT,$0
-	MOVL	$3, DI			// arg 1 - how (SIG_SETMASK)
-	MOVQ	8(SP), SI		// arg 2 - set
-	MOVQ	16(SP), DX		// arg 3 - oset
-	MOVL	$340, AX		// sys_sigprocmask
-	SYSCALL
-	JAE	2(PC)
-	MOVL	$0xf1, 0xf1  // crash
-	RET
-
-// int32 runtime·kqueue(void);
-TEXT runtime·kqueue(SB),NOSPLIT,$0
-	MOVQ	$0, DI
-	MOVQ	$0, SI
-	MOVQ	$0, DX
-	MOVL	$362, AX
-	SYSCALL
-	JCC	2(PC)
-	NEGQ	AX
-	RET
-
-// int32 runtime·kevent(int kq, Kevent *changelist, int nchanges, Kevent *eventlist, int nevents, Timespec *timeout);
-TEXT runtime·kevent(SB),NOSPLIT,$0
-	MOVL	8(SP), DI
-	MOVQ	16(SP), SI
-	MOVL	24(SP), DX
-	MOVQ	32(SP), R10
-	MOVL	40(SP), R8
-	MOVQ	48(SP), R9
-	MOVL	$363, AX
-	SYSCALL
-	JCC	2(PC)
-	NEGQ	AX
-	RET
-
-// void runtime·closeonexec(int32 fd);
-TEXT runtime·closeonexec(SB),NOSPLIT,$0
-	MOVL	8(SP), DI	// fd
-	MOVQ	$2, SI		// F_SETFD
-	MOVQ	$1, DX		// FD_CLOEXEC
-	MOVL	$92, AX		// fcntl
-	SYSCALL
-	RET
diff --git a/src/pkg/runtime/sys_freebsd_arm.s b/src/pkg/runtime/sys_freebsd_arm.s
deleted file mode 100644
index 3ec95a6..0000000
--- a/src/pkg/runtime/sys_freebsd_arm.s
+++ /dev/null
@@ -1,373 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-//
-// System calls and other sys.stuff for ARM, FreeBSD
-// /usr/src/sys/kern/syscalls.master for syscall numbers.
-//
-
-#include "zasm_GOOS_GOARCH.h"
-#include "../../cmd/ld/textflag.h"
-
-// for EABI, as we don't support OABI
-#define SYS_BASE 0x0
-
-#define SYS_exit (SYS_BASE + 1)
-#define SYS_read (SYS_BASE + 3)
-#define SYS_write (SYS_BASE + 4)
-#define SYS_open (SYS_BASE + 5)
-#define SYS_close (SYS_BASE + 6)
-#define SYS_sigaltstack (SYS_BASE + 53)
-#define SYS_munmap (SYS_BASE + 73)
-#define SYS_madvise (SYS_BASE + 75)
-#define SYS_setitimer (SYS_BASE + 83)
-#define SYS_fcntl (SYS_BASE + 92)
-#define SYS_getrlimit (SYS_BASE + 194)
-#define SYS___sysctl (SYS_BASE + 202)
-#define SYS_nanosleep (SYS_BASE + 240)
-#define SYS_clock_gettime (SYS_BASE + 232)
-#define SYS_sched_yield (SYS_BASE + 331)
-#define SYS_sigprocmask (SYS_BASE + 340)
-#define SYS_kqueue (SYS_BASE + 362)
-#define SYS_kevent (SYS_BASE + 363)
-#define SYS_sigaction (SYS_BASE + 416)
-#define SYS_thr_exit (SYS_BASE + 431)
-#define SYS_thr_self (SYS_BASE + 432)
-#define SYS_thr_kill (SYS_BASE + 433)
-#define SYS__umtx_op (SYS_BASE + 454)
-#define SYS_thr_new (SYS_BASE + 455)
-#define SYS_mmap (SYS_BASE + 477) 
-	
-TEXT runtime·sys_umtx_op(SB),NOSPLIT,$0
-	MOVW 0(FP), R0
-	MOVW 4(FP), R1
-	MOVW 8(FP), R2
-	MOVW 12(FP), R3
-	ADD $20, R13 // arg 5 is passed on stack
-	MOVW $SYS__umtx_op, R7
-	SWI $0
-	SUB $20, R13
-	// BCS error
-	RET
-
-TEXT runtime·thr_new(SB),NOSPLIT,$0
-	MOVW 0(FP), R0
-	MOVW 4(FP), R1
-	MOVW $SYS_thr_new, R7
-	SWI $0
-	RET
-
-TEXT runtime·thr_start(SB),NOSPLIT,$0
-	MOVW R0, m
-
-	// set up g
-	MOVW m_g0(m), g
-	BL runtime·emptyfunc(SB) // fault if stack check is wrong
-	BL runtime·mstart(SB)
-
-	MOVW $2, R8  // crash (not reached)
-	MOVW R8, (R8)
-	RET
-
-// Exit the entire program (like C exit)
-TEXT runtime·exit(SB),NOSPLIT,$-8
-	MOVW 0(FP), R0	// arg 1 exit status
-	MOVW $SYS_exit, R7
-	SWI $0
-	MOVW.CS $0, R8 // crash on syscall failure
-	MOVW.CS R8, (R8)
-	RET
-
-TEXT runtime·exit1(SB),NOSPLIT,$-8
-	MOVW 0(FP), R0	// arg 1 exit status
-	MOVW $SYS_thr_exit, R7	
-	SWI $0
-	MOVW.CS $0, R8 // crash on syscall failure
-	MOVW.CS R8, (R8)
-	RET
-
-TEXT runtime·open(SB),NOSPLIT,$-8
-	MOVW 0(FP), R0	// arg 1 name
-	MOVW 4(FP), R1	// arg 2 mode
-	MOVW 8(FP), R2	// arg 3 perm
-	MOVW $SYS_open, R7
-	SWI $0
-	RET
-
-TEXT runtime·read(SB),NOSPLIT,$-8
-	MOVW 0(FP), R0	// arg 1 fd
-	MOVW 4(FP), R1	// arg 2 buf
-	MOVW 8(FP), R2	// arg 3 count
-	MOVW $SYS_read, R7
-	SWI $0
-	RET
-
-TEXT runtime·write(SB),NOSPLIT,$-8
-	MOVW 0(FP), R0	// arg 1 fd
-	MOVW 4(FP), R1	// arg 2 buf
-	MOVW 8(FP), R2	// arg 3 count
-	MOVW $SYS_write, R7
-	SWI $0
-	RET
-
-TEXT runtime·close(SB),NOSPLIT,$-8
-	MOVW 0(FP), R0	// arg 1 fd
-	MOVW $SYS_close, R7
-	SWI $0
-	RET
-
-TEXT runtime·getrlimit(SB),NOSPLIT,$-8
-	MOVW 0(FP), R0
-	MOVW 4(FP), R1
-	MOVW $SYS_getrlimit, R7
-	SWI $0
-	RET
-
-TEXT runtime·raise(SB),NOSPLIT,$8
-	// thr_self(&4(R13))
-	MOVW $4(R13), R0 // arg 1 &4(R13)
-	MOVW $SYS_thr_self, R7
-	SWI $0
-	// thr_kill(self, SIGPIPE)
-	MOVW 4(R13), R0	// arg 1 id
-	MOVW sig+0(FP), R1	// arg 2 - signal
-	MOVW $SYS_thr_kill, R7
-	SWI $0
-	RET
-
-TEXT runtime·setitimer(SB), NOSPLIT, $-8
-	MOVW 0(FP), R0
-	MOVW 4(FP), R1
-	MOVW 8(FP), R2
-	MOVW $SYS_setitimer, R7
-	SWI $0
-	RET
-
-// func now() (sec int64, nsec int32)
-TEXT time·now(SB), NOSPLIT, $32
-	MOVW $0, R0 // CLOCK_REALTIME
-	MOVW $8(R13), R1
-	MOVW $SYS_clock_gettime, R7
-	SWI $0
-
-	MOVW 8(R13), R0 // sec.low
-	MOVW 12(R13), R1 // sec.high
-	MOVW 16(R13), R2 // nsec
-
-	MOVW R0, 0(FP)
-	MOVW R1, 4(FP)
-	MOVW R2, 8(FP)
-	RET
-
-// int64 nanotime(void) so really
-// void nanotime(int64 *nsec)
-TEXT runtime·nanotime(SB), NOSPLIT, $32
-	// We can use CLOCK_MONOTONIC_FAST here when we drop
-	// support for FreeBSD 8-STABLE.
-	MOVW $4, R0 // CLOCK_MONOTONIC
-	MOVW $8(R13), R1
-	MOVW $SYS_clock_gettime, R7
-	SWI $0
-
-	MOVW 8(R13), R0 // sec.low
-	MOVW 12(R13), R4 // sec.high
-	MOVW 16(R13), R2 // nsec
-
-	MOVW $1000000000, R3
-	MULLU R0, R3, (R1, R0)
-	MUL R3, R4
-	ADD.S R2, R0
-	ADC R4, R1
-
-	MOVW 0(FP), R3
-	MOVW R0, 0(R3)
-	MOVW R1, 4(R3)
-	RET
-
-TEXT runtime·sigaction(SB),NOSPLIT,$-8
-	MOVW 0(FP), R0		// arg 1 sig
-	MOVW 4(FP), R1		// arg 2 act
-	MOVW 8(FP), R2		// arg 3 oact
-	MOVW $SYS_sigaction, R7
-	SWI $0
-	MOVW.CS $0, R8 // crash on syscall failure
-	MOVW.CS R8, (R8)
-	RET
-
-TEXT runtime·sigtramp(SB),NOSPLIT,$24
-	// this might be called in external code context,
-	// where g and m are not set.
-	// first save R0, because runtime·load_gm will clobber it
-	MOVW	R0, 4(R13) // signum
-	MOVB	runtime·iscgo(SB), R0
-	CMP 	$0, R0
-	BL.NE	runtime·load_gm(SB)
-
-	CMP $0, m
-	BNE 4(PC)
-	// signal number is already prepared in 4(R13)
-	MOVW $runtime·badsignal(SB), R11
-	BL (R11)
-	RET
-
-	// save g
-	MOVW g, R4
-	MOVW g, 20(R13)
-
-	// g = m->signal
-	MOVW m_gsignal(m), g
-
-	// R0 is already saved
-	MOVW R1, 8(R13) // info
-	MOVW R2, 12(R13) // context
-	MOVW R4, 16(R13) // oldg
-
-	BL runtime·sighandler(SB)
-
-	// restore g
-	MOVW 20(R13), g
-	RET
-
-TEXT runtime·mmap(SB),NOSPLIT,$16
-	MOVW 0(FP), R0		// arg 1 addr
-	MOVW 4(FP), R1		// arg 2 len
-	MOVW 8(FP), R2		// arg 3 prot
-	MOVW 12(FP), R3		// arg 4 flags
-	// arg 5 (fid) and arg6 (offset_lo, offset_hi) are passed on stack
-	// note the C runtime only passes the 32-bit offset_lo to us
-	MOVW 16(FP), R4		// arg 5
-	MOVW R4, 4(R13)
-	MOVW 20(FP), R5		// arg 6 lower 32-bit
-	// the word at 8(R13) is skipped due to 64-bit argument alignment.
-	MOVW R5, 12(R13)
-	MOVW $0, R6 		// higher 32-bit for arg 6
-	MOVW R6, 16(R13)
-	ADD $4, R13
-	MOVW $SYS_mmap, R7
-	SWI $0
-	SUB $4, R13
-	// TODO(dfc) error checking ?
-	RET
-
-TEXT runtime·munmap(SB),NOSPLIT,$0
-	MOVW 0(FP), R0		// arg 1 addr
-	MOVW 4(FP), R1		// arg 2 len
-	MOVW $SYS_munmap, R7
-	SWI $0
-	MOVW.CS $0, R8 // crash on syscall failure
-	MOVW.CS R8, (R8)
-	RET
-
-TEXT runtime·madvise(SB),NOSPLIT,$0
-	MOVW 0(FP), R0		// arg 1 addr
-	MOVW 4(FP), R1		// arg 2 len
-	MOVW 8(FP), R2		// arg 3 flags
-	MOVW $SYS_madvise, R7
-	SWI $0
-	// ignore failure - maybe pages are locked
-	RET
-	
-TEXT runtime·sigaltstack(SB),NOSPLIT,$-8
-	MOVW new+0(FP), R0
-	MOVW old+4(FP), R1
-	MOVW $SYS_sigaltstack, R7
-	SWI $0
-	MOVW.CS $0, R8 // crash on syscall failure
-	MOVW.CS R8, (R8)
-	RET
-
-TEXT runtime·usleep(SB),NOSPLIT,$16
-	MOVW usec+0(FP), R0
-	MOVW R0, R2
-	MOVW $1000000, R1
-	DIV R1, R0
-	// 0(R13) is the saved LR, don't use it
-	MOVW R0, 4(R13) // tv_sec.low
-	MOVW $0, R0
-	MOVW R0, 8(R13) // tv_sec.high
-	MOD R1, R2
-	MOVW $1000, R1
-	MUL R1, R2
-	MOVW R2, 12(R13) // tv_nsec
-
-	MOVW $4(R13), R0 // arg 1 - rqtp
-	MOVW $0, R1      // arg 2 - rmtp
-	MOVW $SYS_nanosleep, R7
-	SWI $0
-	RET
-
-TEXT runtime·sysctl(SB),NOSPLIT,$0
-	MOVW 0(FP), R0	// arg 1 - name
-	MOVW 4(FP), R1	// arg 2 - namelen
-	MOVW 8(FP), R2	// arg 3 - old
-	MOVW 12(FP), R3	// arg 4 - oldlenp
-	// arg 5 (newp) and arg 6 (newlen) are passed on stack
-	ADD $20, R13
-	MOVW $SYS___sysctl, R7
-	SWI $0
-	SUB.CS $0, R0, R0
-	SUB $20, R13
-	RET
-
-TEXT runtime·osyield(SB),NOSPLIT,$-4
-	MOVW $SYS_sched_yield, R7
-	SWI $0
-	RET
-
-TEXT runtime·sigprocmask(SB),NOSPLIT,$0
-	MOVW $3, R0	// arg 1 - how (SIG_SETMASK)
-	MOVW 0(FP), R1	// arg 2 - set
-	MOVW 4(FP), R2	// arg 3 - oset
-	MOVW $SYS_sigprocmask, R7
-	SWI $0
-	MOVW.CS $0, R8 // crash on syscall failure
-	MOVW.CS R8, (R8)
-	RET
-
-// int32 runtime·kqueue(void)
-TEXT runtime·kqueue(SB),NOSPLIT,$0
-	MOVW $SYS_kqueue, R7
-	SWI $0
-	RSB.CS $0, R0
-	RET
-
-// int32 runtime·kevent(int kq, Kevent *changelist, int nchanges, Kevent *eventlist, int nevents, Timespec *timeout)
-TEXT runtime·kevent(SB),NOSPLIT,$0
-	MOVW 0(FP), R0	// kq
-	MOVW 4(FP), R1	// changelist
-	MOVW 8(FP), R2	// nchanges
-	MOVW 12(FP), R3	// eventlist
-	ADD $20, R13	// pass arg 5 and 6 on stack
-	MOVW $SYS_kevent, R7
-	SWI $0
-	RSB.CS $0, R0
-	SUB $20, R13
-	RET
-
-// void runtime·closeonexec(int32 fd)
-TEXT runtime·closeonexec(SB),NOSPLIT,$0
-	MOVW 0(FP), R0	// fd
-	MOVW $2, R1	// F_SETFD
-	MOVW $1, R2	// FD_CLOEXEC
-	MOVW $SYS_fcntl, R7
-	SWI $0
-	RET
-
-TEXT runtime·casp(SB),NOSPLIT,$0
-	B	runtime·cas(SB)
-
-// TODO(minux): this is only valid for ARMv6+
-// bool armcas(int32 *val, int32 old, int32 new)
-// Atomically:
-//	if(*val == old){
-//		*val = new;
-//		return 1;
-//	}else
-//		return 0;
-TEXT runtime·cas(SB),NOSPLIT,$0
-	B runtime·armcas(SB)
-
-// TODO(minux): this only supports ARMv6K+.
-TEXT runtime·read_tls_fallback(SB),NOSPLIT,$-4
-	WORD $0xee1d0f70 // mrc p15, 0, r0, c13, c0, 3
-	RET
diff --git a/src/pkg/runtime/sys_linux_386.s b/src/pkg/runtime/sys_linux_386.s
deleted file mode 100644
index b7896f1..0000000
--- a/src/pkg/runtime/sys_linux_386.s
+++ /dev/null
@@ -1,477 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//
-// System calls and other sys.stuff for 386, Linux
-//
-
-#include "zasm_GOOS_GOARCH.h"
-#include "../../cmd/ld/textflag.h"
-
-TEXT runtime·exit(SB),NOSPLIT,$0
-	MOVL	$252, AX	// syscall number
-	MOVL	4(SP), BX
-	CALL	*runtime·_vdso(SB)
-	INT $3	// not reached
-	RET
-
-TEXT runtime·exit1(SB),NOSPLIT,$0
-	MOVL	$1, AX	// exit - exit the current os thread
-	MOVL	4(SP), BX
-	CALL	*runtime·_vdso(SB)
-	INT $3	// not reached
-	RET
-
-TEXT runtime·open(SB),NOSPLIT,$0
-	MOVL	$5, AX		// syscall - open
-	MOVL	4(SP), BX
-	MOVL	8(SP), CX
-	MOVL	12(SP), DX
-	CALL	*runtime·_vdso(SB)
-	RET
-
-TEXT runtime·close(SB),NOSPLIT,$0
-	MOVL	$6, AX		// syscall - close
-	MOVL	4(SP), BX
-	CALL	*runtime·_vdso(SB)
-	RET
-
-TEXT runtime·write(SB),NOSPLIT,$0
-	MOVL	$4, AX		// syscall - write
-	MOVL	4(SP), BX
-	MOVL	8(SP), CX
-	MOVL	12(SP), DX
-	CALL	*runtime·_vdso(SB)
-	RET
-
-TEXT runtime·read(SB),NOSPLIT,$0
-	MOVL	$3, AX		// syscall - read
-	MOVL	4(SP), BX
-	MOVL	8(SP), CX
-	MOVL	12(SP), DX
-	CALL	*runtime·_vdso(SB)
-	RET
-
-TEXT runtime·getrlimit(SB),NOSPLIT,$0
-	MOVL	$191, AX		// syscall - ugetrlimit
-	MOVL	4(SP), BX
-	MOVL	8(SP), CX
-	CALL	*runtime·_vdso(SB)
-	RET
-
-TEXT runtime·usleep(SB),NOSPLIT,$8
-	MOVL	$0, DX
-	MOVL	usec+0(FP), AX
-	MOVL	$1000000, CX
-	DIVL	CX
-	MOVL	AX, 0(SP)
-	MOVL	DX, 4(SP)
-
-	// select(0, 0, 0, 0, &tv)
-	MOVL	$142, AX
-	MOVL	$0, BX
-	MOVL	$0, CX
-	MOVL	$0, DX
-	MOVL	$0, SI
-	LEAL	0(SP), DI
-	CALL	*runtime·_vdso(SB)
-	RET
-
-TEXT runtime·raise(SB),NOSPLIT,$12
-	MOVL	$224, AX	// syscall - gettid
-	CALL	*runtime·_vdso(SB)
-	MOVL	AX, BX	// arg 1 tid
-	MOVL	sig+0(FP), CX	// arg 2 signal
-	MOVL	$238, AX	// syscall - tkill
-	CALL	*runtime·_vdso(SB)
-	RET
-
-TEXT runtime·setitimer(SB),NOSPLIT,$0-24
-	MOVL	$104, AX			// syscall - setitimer
-	MOVL	4(SP), BX
-	MOVL	8(SP), CX
-	MOVL	12(SP), DX
-	CALL	*runtime·_vdso(SB)
-	RET
-
-TEXT runtime·mincore(SB),NOSPLIT,$0-24
-	MOVL	$218, AX			// syscall - mincore
-	MOVL	4(SP), BX
-	MOVL	8(SP), CX
-	MOVL	12(SP), DX
-	CALL	*runtime·_vdso(SB)
-	RET
-
-// func now() (sec int64, nsec int32)
-TEXT time·now(SB), NOSPLIT, $32
-	MOVL	$265, AX			// syscall - clock_gettime
-	MOVL	$0, BX		// CLOCK_REALTIME
-	LEAL	8(SP), CX
-	MOVL	$0, DX
-	CALL	*runtime·_vdso(SB)
-	MOVL	8(SP), AX	// sec
-	MOVL	12(SP), BX	// nsec
-
-	// sec is in AX, nsec in BX
-	MOVL	AX, sec+0(FP)
-	MOVL	$0, sec+4(FP)
-	MOVL	BX, nsec+8(FP)
-	RET
-
-// int64 nanotime(void) so really
-// void nanotime(int64 *nsec)
-TEXT runtime·nanotime(SB), NOSPLIT, $32
-	MOVL	$265, AX			// syscall - clock_gettime
-	MOVL	$1, BX		// CLOCK_MONOTONIC
-	LEAL	8(SP), CX
-	MOVL	$0, DX
-	CALL	*runtime·_vdso(SB)
-	MOVL	8(SP), AX	// sec
-	MOVL	12(SP), BX	// nsec
-
-	// sec is in AX, nsec in BX
-	// convert to DX:AX nsec
-	MOVL	$1000000000, CX
-	MULL	CX
-	ADDL	BX, AX
-	ADCL	$0, DX
-
-	MOVL	ret+0(FP), DI
-	MOVL	AX, 0(DI)
-	MOVL	DX, 4(DI)
-	RET
-
-TEXT runtime·rtsigprocmask(SB),NOSPLIT,$0
-	MOVL	$175, AX		// syscall entry
-	MOVL	4(SP), BX
-	MOVL	8(SP), CX
-	MOVL	12(SP), DX
-	MOVL	16(SP), SI
-	CALL	*runtime·_vdso(SB)
-	CMPL	AX, $0xfffff001
-	JLS	2(PC)
-	INT $3
-	RET
-
-TEXT runtime·rt_sigaction(SB),NOSPLIT,$0
-	MOVL	$174, AX		// syscall - rt_sigaction
-	MOVL	4(SP), BX
-	MOVL	8(SP), CX
-	MOVL	12(SP), DX
-	MOVL	16(SP), SI
-	CALL	*runtime·_vdso(SB)
-	RET
-
-TEXT runtime·sigtramp(SB),NOSPLIT,$44
-	get_tls(CX)
-
-	// check that m exists
-	MOVL	m(CX), BX
-	CMPL	BX, $0
-	JNE	6(PC)
-	MOVL	sig+0(FP), BX
-	MOVL	BX, 0(SP)
-	MOVL	$runtime·badsignal(SB), AX
-	CALL	AX
-	RET
-
-	// save g
-	MOVL	g(CX), DI
-	MOVL	DI, 20(SP)
-
-	// g = m->gsignal
-	MOVL	m(CX), BX
-	MOVL	m_gsignal(BX), BX
-	MOVL	BX, g(CX)
-
-	// copy arguments for call to sighandler
-	MOVL	sig+0(FP), BX
-	MOVL	BX, 0(SP)
-	MOVL	info+4(FP), BX
-	MOVL	BX, 4(SP)
-	MOVL	context+8(FP), BX
-	MOVL	BX, 8(SP)
-	MOVL	DI, 12(SP)
-
-	CALL	runtime·sighandler(SB)
-
-	// restore g
-	get_tls(CX)
-	MOVL	20(SP), BX
-	MOVL	BX, g(CX)
-
-	RET
-
-TEXT runtime·sigreturn(SB),NOSPLIT,$0
-	MOVL	$173, AX	// rt_sigreturn
-	// Sigreturn expects same SP as signal handler,
-	// so cannot CALL *runtime._vsdo(SB) here.
-	INT	$0x80
-	INT $3	// not reached
-	RET
-
-TEXT runtime·mmap(SB),NOSPLIT,$0
-	MOVL	$192, AX	// mmap2
-	MOVL	4(SP), BX
-	MOVL	8(SP), CX
-	MOVL	12(SP), DX
-	MOVL	16(SP), SI
-	MOVL	20(SP), DI
-	MOVL	24(SP), BP
-	SHRL	$12, BP
-	CALL	*runtime·_vdso(SB)
-	CMPL	AX, $0xfffff001
-	JLS	3(PC)
-	NOTL	AX
-	INCL	AX
-	RET
-
-TEXT runtime·munmap(SB),NOSPLIT,$0
-	MOVL	$91, AX	// munmap
-	MOVL	4(SP), BX
-	MOVL	8(SP), CX
-	CALL	*runtime·_vdso(SB)
-	CMPL	AX, $0xfffff001
-	JLS	2(PC)
-	INT $3
-	RET
-
-TEXT runtime·madvise(SB),NOSPLIT,$0
-	MOVL	$219, AX	// madvise
-	MOVL	4(SP), BX
-	MOVL	8(SP), CX
-	MOVL	12(SP), DX
-	CALL	*runtime·_vdso(SB)
-	// ignore failure - maybe pages are locked
-	RET
-
-// int32 futex(int32 *uaddr, int32 op, int32 val,
-//	struct timespec *timeout, int32 *uaddr2, int32 val2);
-TEXT runtime·futex(SB),NOSPLIT,$0
-	MOVL	$240, AX	// futex
-	MOVL	4(SP), BX
-	MOVL	8(SP), CX
-	MOVL	12(SP), DX
-	MOVL	16(SP), SI
-	MOVL	20(SP), DI
-	MOVL	24(SP), BP
-	CALL	*runtime·_vdso(SB)
-	RET
-
-// int32 clone(int32 flags, void *stack, M *mp, G *gp, void (*fn)(void));
-TEXT runtime·clone(SB),NOSPLIT,$0
-	MOVL	$120, AX	// clone
-	MOVL	flags+4(SP), BX
-	MOVL	stack+8(SP), CX
-	MOVL	$0, DX	// parent tid ptr
-	MOVL	$0, DI	// child tid ptr
-
-	// Copy mp, gp, fn off parent stack for use by child.
-	SUBL	$16, CX
-	MOVL	mm+12(SP), SI
-	MOVL	SI, 0(CX)
-	MOVL	gg+16(SP), SI
-	MOVL	SI, 4(CX)
-	MOVL	fn+20(SP), SI
-	MOVL	SI, 8(CX)
-	MOVL	$1234, 12(CX)
-
-	// cannot use CALL *runtime·_vdso(SB) here, because
-	// the stack changes during the system call (after
-	// CALL *runtime·_vdso(SB), the child is still using
-	// the parent's stack when executing its RET instruction).
-	INT	$0x80
-
-	// In parent, return.
-	CMPL	AX, $0
-	JEQ	2(PC)
-	RET
-
-	// Paranoia: check that SP is as we expect.
-	MOVL	12(SP), BP
-	CMPL	BP, $1234
-	JEQ	2(PC)
-	INT	$3
-
-	// Initialize AX to Linux tid
-	MOVL	$224, AX
-	CALL	*runtime·_vdso(SB)
-
-	// In child on new stack.  Reload registers (paranoia).
-	MOVL	0(SP), BX	// m
-	MOVL	4(SP), DX	// g
-	MOVL	8(SP), SI	// fn
-
-	MOVL	AX, m_procid(BX)	// save tid as m->procid
-
-	// set up ldt 7+id to point at m->tls.
-	// newosproc left the id in tls[0].
-	LEAL	m_tls(BX), BP
-	MOVL	0(BP), DI
-	ADDL	$7, DI	// m0 is LDT#7. count up.
-	// setldt(tls#, &tls, sizeof tls)
-	PUSHAL	// save registers
-	PUSHL	$32	// sizeof tls
-	PUSHL	BP	// &tls
-	PUSHL	DI	// tls #
-	CALL	runtime·setldt(SB)
-	POPL	AX
-	POPL	AX
-	POPL	AX
-	POPAL
-
-	// Now segment is established.  Initialize m, g.
-	get_tls(AX)
-	MOVL	DX, g(AX)
-	MOVL	BX, m(AX)
-
-	CALL	runtime·stackcheck(SB)	// smashes AX, CX
-	MOVL	0(DX), DX	// paranoia; check they are not nil
-	MOVL	0(BX), BX
-
-	// more paranoia; check that stack splitting code works
-	PUSHAL
-	CALL	runtime·emptyfunc(SB)
-	POPAL
-
-	CALL	SI	// fn()
-	CALL	runtime·exit1(SB)
-	MOVL	$0x1234, 0x1005
-	RET
-
-TEXT runtime·sigaltstack(SB),NOSPLIT,$-8
-	MOVL	$186, AX	// sigaltstack
-	MOVL	new+4(SP), BX
-	MOVL	old+8(SP), CX
-	CALL	*runtime·_vdso(SB)
-	CMPL	AX, $0xfffff001
-	JLS	2(PC)
-	INT	$3
-	RET
-
-// <asm-i386/ldt.h>
-// struct user_desc {
-//	unsigned int  entry_number;
-//	unsigned long base_addr;
-//	unsigned int  limit;
-//	unsigned int  seg_32bit:1;
-//	unsigned int  contents:2;
-//	unsigned int  read_exec_only:1;
-//	unsigned int  limit_in_pages:1;
-//	unsigned int  seg_not_present:1;
-//	unsigned int  useable:1;
-// };
-#define SEG_32BIT 0x01
-// contents are the 2 bits 0x02 and 0x04.
-#define CONTENTS_DATA 0x00
-#define CONTENTS_STACK 0x02
-#define CONTENTS_CODE 0x04
-#define READ_EXEC_ONLY 0x08
-#define LIMIT_IN_PAGES 0x10
-#define SEG_NOT_PRESENT 0x20
-#define USEABLE 0x40
-
-// setldt(int entry, int address, int limit)
-TEXT runtime·setldt(SB),NOSPLIT,$32
-	MOVL	entry+0(FP), BX	// entry
-	MOVL	address+4(FP), CX	// base address
-
-	/*
-	 * When linking against the system libraries,
-	 * we use its pthread_create and let it set up %gs
-	 * for us.  When we do that, the private storage
-	 * we get is not at 0(GS), 4(GS), but -8(GS), -4(GS).
-	 * To insulate the rest of the tool chain from this
-	 * ugliness, 8l rewrites 0(TLS) into -8(GS) for us.
-	 * To accommodate that rewrite, we translate
-	 * the address here and bump the limit to 0xffffffff (no limit)
-	 * so that -8(GS) maps to 0(address).
-	 * Also, the final 0(GS) (current 8(CX)) has to point
-	 * to itself, to mimic ELF.
-	 */
-	ADDL	$0x8, CX	// address
-	MOVL	CX, 0(CX)
-
-	// set up user_desc
-	LEAL	16(SP), AX	// struct user_desc
-	MOVL	BX, 0(AX)
-	MOVL	CX, 4(AX)
-	MOVL	$0xfffff, 8(AX)
-	MOVL	$(SEG_32BIT|LIMIT_IN_PAGES|USEABLE|CONTENTS_DATA), 12(AX)	// flag bits
-
-	// call modify_ldt
-	MOVL	$1, BX	// func = 1 (write)
-	MOVL	AX, CX	// user_desc
-	MOVL	$16, DX	// sizeof(user_desc)
-	MOVL	$123, AX	// syscall - modify_ldt
-	CALL	*runtime·_vdso(SB)
-
-	// breakpoint on error
-	CMPL AX, $0xfffff001
-	JLS 2(PC)
-	INT $3
-
-	// compute segment selector - (entry*8+7)
-	MOVL	entry+0(FP), AX
-	SHLL	$3, AX
-	ADDL	$7, AX
-	MOVW	AX, GS
-
-	RET
-
-TEXT runtime·osyield(SB),NOSPLIT,$0
-	MOVL	$158, AX
-	CALL	*runtime·_vdso(SB)
-	RET
-
-TEXT runtime·sched_getaffinity(SB),NOSPLIT,$0
-	MOVL	$242, AX		// syscall - sched_getaffinity
-	MOVL	4(SP), BX
-	MOVL	8(SP), CX
-	MOVL	12(SP), DX
-	CALL	*runtime·_vdso(SB)
-	RET
-
-// int32 runtime·epollcreate(int32 size);
-TEXT runtime·epollcreate(SB),NOSPLIT,$0
-	MOVL    $254, AX
-	MOVL	4(SP), BX
-	CALL	*runtime·_vdso(SB)
-	RET
-
-// int32 runtime·epollcreate1(int32 flags);
-TEXT runtime·epollcreate1(SB),NOSPLIT,$0
-	MOVL    $329, AX
-	MOVL	4(SP), BX
-	CALL	*runtime·_vdso(SB)
-	RET
-
-// int32 runtime·epollctl(int32 epfd, int32 op, int32 fd, EpollEvent *ev);
-TEXT runtime·epollctl(SB),NOSPLIT,$0
-	MOVL	$255, AX
-	MOVL	4(SP), BX
-	MOVL	8(SP), CX
-	MOVL	12(SP), DX
-	MOVL	16(SP), SI
-	CALL	*runtime·_vdso(SB)
-	RET
-
-// int32 runtime·epollwait(int32 epfd, EpollEvent *ev, int32 nev, int32 timeout);
-TEXT runtime·epollwait(SB),NOSPLIT,$0
-	MOVL	$256, AX
-	MOVL	4(SP), BX
-	MOVL	8(SP), CX
-	MOVL	12(SP), DX
-	MOVL	16(SP), SI
-	CALL	*runtime·_vdso(SB)
-	RET
-
-// void runtime·closeonexec(int32 fd);
-TEXT runtime·closeonexec(SB),NOSPLIT,$0
-	MOVL	$55, AX  // fcntl
-	MOVL	4(SP), BX  // fd
-	MOVL	$2, CX  // F_SETFD
-	MOVL	$1, DX  // FD_CLOEXEC
-	CALL	*runtime·_vdso(SB)
-	RET
diff --git a/src/pkg/runtime/sys_linux_amd64.s b/src/pkg/runtime/sys_linux_amd64.s
deleted file mode 100644
index b340c4f..0000000
--- a/src/pkg/runtime/sys_linux_amd64.s
+++ /dev/null
@@ -1,394 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//
-// System calls and other sys.stuff for AMD64, Linux
-//
-
-#include "zasm_GOOS_GOARCH.h"
-#include "../../cmd/ld/textflag.h"
-
-TEXT runtime·exit(SB),NOSPLIT,$0-8
-	MOVL	8(SP), DI
-	MOVL	$231, AX	// exitgroup - force all os threads to exit
-	SYSCALL
-	RET
-
-TEXT runtime·exit1(SB),NOSPLIT,$0-8
-	MOVL	8(SP), DI
-	MOVL	$60, AX	// exit - exit the current os thread
-	SYSCALL
-	RET
-
-TEXT runtime·open(SB),NOSPLIT,$0-16
-	MOVQ	8(SP), DI
-	MOVL	16(SP), SI
-	MOVL	20(SP), DX
-	MOVL	$2, AX			// syscall entry
-	SYSCALL
-	RET
-
-TEXT runtime·close(SB),NOSPLIT,$0-16
-	MOVL	8(SP), DI
-	MOVL	$3, AX			// syscall entry
-	SYSCALL
-	RET
-
-TEXT runtime·write(SB),NOSPLIT,$0-24
-	MOVL	8(SP), DI
-	MOVQ	16(SP), SI
-	MOVL	24(SP), DX
-	MOVL	$1, AX			// syscall entry
-	SYSCALL
-	RET
-
-TEXT runtime·read(SB),NOSPLIT,$0-24
-	MOVL	8(SP), DI
-	MOVQ	16(SP), SI
-	MOVL	24(SP), DX
-	MOVL	$0, AX			// syscall entry
-	SYSCALL
-	RET
-
-TEXT runtime·getrlimit(SB),NOSPLIT,$0-24
-	MOVL	8(SP), DI
-	MOVQ	16(SP), SI
-	MOVL	$97, AX			// syscall entry
-	SYSCALL
-	RET
-
-TEXT runtime·usleep(SB),NOSPLIT,$16
-	MOVL	$0, DX
-	MOVL	usec+0(FP), AX
-	MOVL	$1000000, CX
-	DIVL	CX
-	MOVQ	AX, 0(SP)
-	MOVQ	DX, 8(SP)
-
-	// select(0, 0, 0, 0, &tv)
-	MOVL	$0, DI
-	MOVL	$0, SI
-	MOVL	$0, DX
-	MOVL	$0, R10
-	MOVQ	SP, R8
-	MOVL	$23, AX
-	SYSCALL
-	RET
-
-TEXT runtime·raise(SB),NOSPLIT,$0
-	MOVL	$186, AX	// syscall - gettid
-	SYSCALL
-	MOVL	AX, DI	// arg 1 tid
-	MOVL	sig+0(FP), SI	// arg 2
-	MOVL	$200, AX	// syscall - tkill
-	SYSCALL
-	RET
-
-TEXT runtime·setitimer(SB),NOSPLIT,$0-24
-	MOVL	8(SP), DI
-	MOVQ	16(SP), SI
-	MOVQ	24(SP), DX
-	MOVL	$38, AX			// syscall entry
-	SYSCALL
-	RET
-
-TEXT runtime·mincore(SB),NOSPLIT,$0-24
-	MOVQ	8(SP), DI
-	MOVQ	16(SP), SI
-	MOVQ	24(SP), DX
-	MOVL	$27, AX			// syscall entry
-	SYSCALL
-	RET
-
-// func now() (sec int64, nsec int32)
-TEXT time·now(SB),NOSPLIT,$16
-	// Be careful. We're calling a function with gcc calling convention here.
-	// We're guaranteed 128 bytes on entry, and we've taken 16, and the
-	// call uses another 8.
-	// That leaves 104 for the gettime code to use. Hope that's enough!
-	MOVQ	runtime·__vdso_clock_gettime_sym(SB), AX
-	CMPQ	AX, $0
-	JEQ	fallback_gtod
-	MOVL	$0, DI // CLOCK_REALTIME
-	LEAQ	0(SP), SI
-	CALL	AX
-	MOVQ	0(SP), AX	// sec
-	MOVQ	8(SP), DX	// nsec
-	MOVQ	AX, sec+0(FP)
-	MOVL	DX, nsec+8(FP)
-	RET
-fallback_gtod:
-	LEAQ	0(SP), DI
-	MOVQ	$0, SI
-	MOVQ	runtime·__vdso_gettimeofday_sym(SB), AX
-	CALL	AX
-	MOVQ	0(SP), AX	// sec
-	MOVL	8(SP), DX	// usec
-	IMULQ	$1000, DX
-	MOVQ	AX, sec+0(FP)
-	MOVL	DX, nsec+8(FP)
-	RET
-
-TEXT runtime·nanotime(SB),NOSPLIT,$16
-	// Duplicate time.now here to avoid using up precious stack space.
-	// See comment above in time.now.
-	MOVQ	runtime·__vdso_clock_gettime_sym(SB), AX
-	CMPQ	AX, $0
-	JEQ	fallback_gtod_nt
-	MOVL	$1, DI // CLOCK_MONOTONIC
-	LEAQ	0(SP), SI
-	CALL	AX
-	MOVQ	0(SP), AX	// sec
-	MOVQ	8(SP), DX	// nsec
-	// sec is in AX, nsec in DX
-	// return nsec in AX
-	IMULQ	$1000000000, AX
-	ADDQ	DX, AX
-	RET
-fallback_gtod_nt:
-	LEAQ	0(SP), DI
-	MOVQ	$0, SI
-	MOVQ	runtime·__vdso_gettimeofday_sym(SB), AX
-	CALL	AX
-	MOVQ	0(SP), AX	// sec
-	MOVL	8(SP), DX	// usec
-	IMULQ	$1000, DX
-	// sec is in AX, nsec in DX
-	// return nsec in AX
-	IMULQ	$1000000000, AX
-	ADDQ	DX, AX
-	RET
-
-TEXT runtime·rtsigprocmask(SB),NOSPLIT,$0-32
-	MOVL	8(SP), DI
-	MOVQ	16(SP), SI
-	MOVQ	24(SP), DX
-	MOVL	32(SP), R10
-	MOVL	$14, AX			// syscall entry
-	SYSCALL
-	CMPQ	AX, $0xfffffffffffff001
-	JLS	2(PC)
-	MOVL	$0xf1, 0xf1  // crash
-	RET
-
-TEXT runtime·rt_sigaction(SB),NOSPLIT,$0-32
-	MOVL	8(SP), DI
-	MOVQ	16(SP), SI
-	MOVQ	24(SP), DX
-	MOVQ	32(SP), R10
-	MOVL	$13, AX			// syscall entry
-	SYSCALL
-	RET
-
-TEXT runtime·sigtramp(SB),NOSPLIT,$64
-	get_tls(BX)
-
-	// check that m exists
-	MOVQ	m(BX), BP
-	CMPQ	BP, $0
-	JNE	5(PC)
-	MOVQ	DI, 0(SP)
-	MOVQ	$runtime·badsignal(SB), AX
-	CALL	AX
-	RET
-
-	// save g
-	MOVQ	g(BX), R10
-	MOVQ	R10, 40(SP)
-
-	// g = m->gsignal
-	MOVQ	m_gsignal(BP), BP
-	MOVQ	BP, g(BX)
-
-	MOVQ	DI, 0(SP)
-	MOVQ	SI, 8(SP)
-	MOVQ	DX, 16(SP)
-	MOVQ	R10, 24(SP)
-
-	CALL	runtime·sighandler(SB)
-
-	// restore g
-	get_tls(BX)
-	MOVQ	40(SP), R10
-	MOVQ	R10, g(BX)
-	RET
-
-TEXT runtime·sigreturn(SB),NOSPLIT,$0
-	MOVL	$15, AX	// rt_sigreturn
-	SYSCALL
-	INT $3	// not reached
-
-TEXT runtime·mmap(SB),NOSPLIT,$0
-	MOVQ	8(SP), DI
-	MOVQ	$0, SI
-	MOVQ	16(SP), SI
-	MOVL	24(SP), DX
-	MOVL	28(SP), R10
-	MOVL	32(SP), R8
-	MOVL	36(SP), R9
-
-	MOVL	$9, AX			// mmap
-	SYSCALL
-	CMPQ	AX, $0xfffffffffffff001
-	JLS	3(PC)
-	NOTQ	AX
-	INCQ	AX
-	RET
-
-TEXT runtime·munmap(SB),NOSPLIT,$0
-	MOVQ	8(SP), DI
-	MOVQ	16(SP), SI
-	MOVQ	$11, AX	// munmap
-	SYSCALL
-	CMPQ	AX, $0xfffffffffffff001
-	JLS	2(PC)
-	MOVL	$0xf1, 0xf1  // crash
-	RET
-
-TEXT runtime·madvise(SB),NOSPLIT,$0
-	MOVQ	8(SP), DI
-	MOVQ	16(SP), SI
-	MOVQ	24(SP), DX
-	MOVQ	$28, AX	// madvise
-	SYSCALL
-	// ignore failure - maybe pages are locked
-	RET
-
-// int64 futex(int32 *uaddr, int32 op, int32 val,
-//	struct timespec *timeout, int32 *uaddr2, int32 val2);
-TEXT runtime·futex(SB),NOSPLIT,$0
-	MOVQ	8(SP), DI
-	MOVL	16(SP), SI
-	MOVL	20(SP), DX
-	MOVQ	24(SP), R10
-	MOVQ	32(SP), R8
-	MOVL	40(SP), R9
-	MOVL	$202, AX
-	SYSCALL
-	RET
-
-// int64 clone(int32 flags, void *stack, M *mp, G *gp, void (*fn)(void));
-TEXT runtime·clone(SB),NOSPLIT,$0
-	MOVL	flags+8(SP), DI
-	MOVQ	stack+16(SP), SI
-
-	// Copy mp, gp, fn off parent stack for use by child.
-	// Careful: Linux system call clobbers CX and R11.
-	MOVQ	mm+24(SP), R8
-	MOVQ	gg+32(SP), R9
-	MOVQ	fn+40(SP), R12
-
-	MOVL	$56, AX
-	SYSCALL
-
-	// In parent, return.
-	CMPQ	AX, $0
-	JEQ	2(PC)
-	RET
-
-	// In child, on new stack.
-	MOVQ	SI, SP
-
-	// Initialize m->procid to Linux tid
-	MOVL	$186, AX	// gettid
-	SYSCALL
-	MOVQ	AX, m_procid(R8)
-
-	// Set FS to point at m->tls.
-	LEAQ	m_tls(R8), DI
-	CALL	runtime·settls(SB)
-
-	// In child, set up new stack
-	get_tls(CX)
-	MOVQ	R8, m(CX)
-	MOVQ	R9, g(CX)
-	CALL	runtime·stackcheck(SB)
-
-	// Call fn
-	CALL	R12
-
-	// It shouldn't return.  If it does, exit
-	MOVL	$111, DI
-	MOVL	$60, AX
-	SYSCALL
-	JMP	-3(PC)	// keep exiting
-
-TEXT runtime·sigaltstack(SB),NOSPLIT,$-8
-	MOVQ	new+8(SP), DI
-	MOVQ	old+16(SP), SI
-	MOVQ	$131, AX
-	SYSCALL
-	CMPQ	AX, $0xfffffffffffff001
-	JLS	2(PC)
-	MOVL	$0xf1, 0xf1  // crash
-	RET
-
-// set tls base to DI
-TEXT runtime·settls(SB),NOSPLIT,$32
-	ADDQ	$16, DI	// ELF wants to use -16(FS), -8(FS)
-
-	MOVQ	DI, SI
-	MOVQ	$0x1002, DI	// ARCH_SET_FS
-	MOVQ	$158, AX	// arch_prctl
-	SYSCALL
-	CMPQ	AX, $0xfffffffffffff001
-	JLS	2(PC)
-	MOVL	$0xf1, 0xf1  // crash
-	RET
-
-TEXT runtime·osyield(SB),NOSPLIT,$0
-	MOVL	$24, AX
-	SYSCALL
-	RET
-
-TEXT runtime·sched_getaffinity(SB),NOSPLIT,$0
-	MOVQ	8(SP), DI
-	MOVL	16(SP), SI
-	MOVQ	24(SP), DX
-	MOVL	$204, AX			// syscall entry
-	SYSCALL
-	RET
-
-// int32 runtime·epollcreate(int32 size);
-TEXT runtime·epollcreate(SB),NOSPLIT,$0
-	MOVL    8(SP), DI
-	MOVL    $213, AX                        // syscall entry
-	SYSCALL
-	RET
-
-// int32 runtime·epollcreate1(int32 flags);
-TEXT runtime·epollcreate1(SB),NOSPLIT,$0
-	MOVL	8(SP), DI
-	MOVL	$291, AX			// syscall entry
-	SYSCALL
-	RET
-
-// int32 runtime·epollctl(int32 epfd, int32 op, int32 fd, EpollEvent *ev);
-TEXT runtime·epollctl(SB),NOSPLIT,$0
-	MOVL	8(SP), DI
-	MOVL	12(SP), SI
-	MOVL	16(SP), DX
-	MOVQ	24(SP), R10
-	MOVL	$233, AX			// syscall entry
-	SYSCALL
-	RET
-
-// int32 runtime·epollwait(int32 epfd, EpollEvent *ev, int32 nev, int32 timeout);
-TEXT runtime·epollwait(SB),NOSPLIT,$0
-	MOVL	8(SP), DI
-	MOVQ	16(SP), SI
-	MOVL	24(SP), DX
-	MOVL	28(SP), R10
-	MOVL	$232, AX			// syscall entry
-	SYSCALL
-	RET
-
-// void runtime·closeonexec(int32 fd);
-TEXT runtime·closeonexec(SB),NOSPLIT,$0
-	MOVL    8(SP), DI  // fd
-	MOVQ    $2, SI  // F_SETFD
-	MOVQ    $1, DX  // FD_CLOEXEC
-	MOVL	$72, AX  // fcntl
-	SYSCALL
-	RET
diff --git a/src/pkg/runtime/sys_linux_arm.s b/src/pkg/runtime/sys_linux_arm.s
deleted file mode 100644
index c537a87..0000000
--- a/src/pkg/runtime/sys_linux_arm.s
+++ /dev/null
@@ -1,448 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//
-// System calls and other sys.stuff for arm, Linux
-//
-
-#include "zasm_GOOS_GOARCH.h"
-#include "../../cmd/ld/textflag.h"
-
-// for EABI, as we don't support OABI
-#define SYS_BASE 0x0
-
-#define SYS_exit (SYS_BASE + 1)
-#define SYS_read (SYS_BASE + 3)
-#define SYS_write (SYS_BASE + 4)
-#define SYS_open (SYS_BASE + 5)
-#define SYS_close (SYS_BASE + 6)
-#define SYS_gettimeofday (SYS_BASE + 78)
-#define SYS_clone (SYS_BASE + 120)
-#define SYS_rt_sigreturn (SYS_BASE + 173)
-#define SYS_rt_sigaction (SYS_BASE + 174)
-#define SYS_rt_sigprocmask (SYS_BASE + 175)
-#define SYS_sigaltstack (SYS_BASE + 186)
-#define SYS_mmap2 (SYS_BASE + 192)
-#define SYS_futex (SYS_BASE + 240)
-#define SYS_exit_group (SYS_BASE + 248)
-#define SYS_munmap (SYS_BASE + 91)
-#define SYS_madvise (SYS_BASE + 220)
-#define SYS_setitimer (SYS_BASE + 104)
-#define SYS_mincore (SYS_BASE + 219)
-#define SYS_gettid (SYS_BASE + 224)
-#define SYS_tkill (SYS_BASE + 238)
-#define SYS_sched_yield (SYS_BASE + 158)
-#define SYS_select (SYS_BASE + 142) // newselect
-#define SYS_ugetrlimit (SYS_BASE + 191)
-#define SYS_sched_getaffinity (SYS_BASE + 242)
-#define SYS_clock_gettime (SYS_BASE + 263)
-#define SYS_epoll_create (SYS_BASE + 250)
-#define SYS_epoll_ctl (SYS_BASE + 251)
-#define SYS_epoll_wait (SYS_BASE + 252)
-#define SYS_epoll_create1 (SYS_BASE + 357)
-#define SYS_fcntl (SYS_BASE + 55)
-
-#define ARM_BASE (SYS_BASE + 0x0f0000)
-
-TEXT runtime·open(SB),NOSPLIT,$0
-	MOVW	0(FP), R0
-	MOVW	4(FP), R1
-	MOVW	8(FP), R2
-	MOVW	$SYS_open, R7
-	SWI	$0
-	RET
-
-TEXT runtime·close(SB),NOSPLIT,$0
-	MOVW	0(FP), R0
-	MOVW	$SYS_close, R7
-	SWI	$0
-	RET
-
-TEXT runtime·write(SB),NOSPLIT,$0
-	MOVW	0(FP), R0
-	MOVW	4(FP), R1
-	MOVW	8(FP), R2
-	MOVW	$SYS_write, R7
-	SWI	$0
-	RET
-
-TEXT runtime·read(SB),NOSPLIT,$0
-	MOVW	0(FP), R0
-	MOVW	4(FP), R1
-	MOVW	8(FP), R2
-	MOVW	$SYS_read, R7
-	SWI	$0
-	RET
-
-TEXT runtime·getrlimit(SB),NOSPLIT,$0
-	MOVW	0(FP), R0
-	MOVW	4(FP), R1
-	MOVW	$SYS_ugetrlimit, R7
-	SWI	$0
-	RET
-
-TEXT runtime·exit(SB),NOSPLIT,$-4
-	MOVW	0(FP), R0
-	MOVW	$SYS_exit_group, R7
-	SWI	$0
-	MOVW	$1234, R0
-	MOVW	$1002, R1
-	MOVW	R0, (R1)	// fail hard
-
-TEXT runtime·exit1(SB),NOSPLIT,$-4
-	MOVW	0(FP), R0
-	MOVW	$SYS_exit, R7
-	SWI	$0
-	MOVW	$1234, R0
-	MOVW	$1003, R1
-	MOVW	R0, (R1)	// fail hard
-
-TEXT	runtime·raise(SB),NOSPLIT,$-4
-	MOVW	$SYS_gettid, R7
-	SWI	$0
-	// arg 1 tid already in R0 from gettid
-	MOVW	sig+0(FP), R1	// arg 2 - signal
-	MOVW	$SYS_tkill, R7
-	SWI	$0
-	RET
-
-TEXT runtime·mmap(SB),NOSPLIT,$0
-	MOVW	0(FP), R0
-	MOVW	4(FP), R1
-	MOVW	8(FP), R2
-	MOVW	12(FP), R3
-	MOVW	16(FP), R4
-	MOVW	20(FP), R5
-	MOVW	$SYS_mmap2, R7
-	SWI	$0
-	MOVW	$0xfffff001, R6
-	CMP		R6, R0
-	RSB.HI	$0, R0
-	RET
-
-TEXT runtime·munmap(SB),NOSPLIT,$0
-	MOVW	0(FP), R0
-	MOVW	4(FP), R1
-	MOVW	$SYS_munmap, R7
-	SWI	$0
-	MOVW	$0xfffff001, R6
-	CMP 	R6, R0
-	MOVW.HI	$0, R8  // crash on syscall failure
-	MOVW.HI	R8, (R8)
-	RET
-
-TEXT runtime·madvise(SB),NOSPLIT,$0
-	MOVW	0(FP), R0
-	MOVW	4(FP), R1
-	MOVW	8(FP), R2
-	MOVW	$SYS_madvise, R7
-	SWI	$0
-	// ignore failure - maybe pages are locked
-	RET
-
-TEXT runtime·setitimer(SB),NOSPLIT,$0
-	MOVW	0(FP), R0
-	MOVW	4(FP), R1
-	MOVW	8(FP), R2
-	MOVW	$SYS_setitimer, R7
-	SWI	$0
-	RET
-
-TEXT runtime·mincore(SB),NOSPLIT,$0
-	MOVW	0(FP), R0
-	MOVW	4(FP), R1
-	MOVW	8(FP), R2
-	MOVW	$SYS_mincore, R7
-	SWI	$0
-	RET
-
-TEXT time·now(SB), NOSPLIT, $32
-	MOVW	$0, R0  // CLOCK_REALTIME
-	MOVW	$8(R13), R1  // timespec
-	MOVW	$SYS_clock_gettime, R7
-	SWI	$0
-	
-	MOVW	8(R13), R0  // sec
-	MOVW	12(R13), R2  // nsec
-	
-	MOVW	R0, 0(FP)
-	MOVW	$0, R1
-	MOVW	R1, 4(FP)
-	MOVW	R2, 8(FP)
-	RET	
-
-// int64 nanotime(void) so really
-// void nanotime(int64 *nsec)
-TEXT runtime·nanotime(SB),NOSPLIT,$32
-	MOVW	$1, R0  // CLOCK_MONOTONIC
-	MOVW	$8(R13), R1  // timespec
-	MOVW	$SYS_clock_gettime, R7
-	SWI	$0
-	
-	MOVW	8(R13), R0  // sec
-	MOVW	12(R13), R2  // nsec
-	
-	MOVW	$1000000000, R3
-	MULLU	R0, R3, (R1, R0)
-	MOVW	$0, R4
-	ADD.S	R2, R0
-	ADC	R4, R1
-
-	MOVW	0(FP), R3
-	MOVW	R0, 0(R3)
-	MOVW	R1, 4(R3)
-	RET
-
-// int32 futex(int32 *uaddr, int32 op, int32 val,
-//	struct timespec *timeout, int32 *uaddr2, int32 val2);
-TEXT runtime·futex(SB),NOSPLIT,$0
-	MOVW	4(SP), R0
-	MOVW	8(SP), R1
-	MOVW	12(SP), R2
-	MOVW	16(SP), R3
-	MOVW	20(SP), R4
-	MOVW	24(SP), R5
-	MOVW	$SYS_futex, R7
-	SWI	$0
-	RET
-
-
-// int32 clone(int32 flags, void *stack, M *mp, G *gp, void (*fn)(void));
-TEXT runtime·clone(SB),NOSPLIT,$0
-	MOVW	flags+0(FP), R0
-	MOVW	stack+4(FP), R1
-	MOVW	$0, R2	// parent tid ptr
-	MOVW	$0, R3	// tls_val
-	MOVW	$0, R4	// child tid ptr
-	MOVW	$0, R5
-
-	// Copy mp, gp, fn off parent stack for use by child.
-	// TODO(kaib): figure out which registers are clobbered by clone and avoid stack copying
-	MOVW	$-16(R1), R1
-	MOVW	mm+8(FP), R6
-	MOVW	R6, 0(R1)
-	MOVW	gg+12(FP), R6
-	MOVW	R6, 4(R1)
-	MOVW	fn+16(FP), R6
-	MOVW	R6, 8(R1)
-	MOVW	$1234, R6
-	MOVW	R6, 12(R1)
-
-	MOVW	$SYS_clone, R7
-	SWI	$0
-
-	// In parent, return.
-	CMP	$0, R0
-	BEQ	2(PC)
-	RET
-
-	// Paranoia: check that SP is as we expect. Use R13 to avoid linker 'fixup'
-	MOVW	12(R13), R0
-	MOVW	$1234, R1
-	CMP	R0, R1
-	BEQ	2(PC)
-	BL	runtime·abort(SB)
-
-	MOVW	0(R13), m
-	MOVW	4(R13), g
-
-	// paranoia; check they are not nil
-	MOVW	0(m), R0
-	MOVW	0(g), R0
-
-	BL	runtime·emptyfunc(SB)	// fault if stack check is wrong
-
-	// Initialize m->procid to Linux tid
-	MOVW	$SYS_gettid, R7
-	SWI	$0
-	MOVW	R0, m_procid(m)
-
-	// Call fn
-	MOVW	8(R13), R0
-	MOVW	$16(R13), R13
-	BL	(R0)
-
-	MOVW	$0, R0
-	MOVW	R0, 4(R13)
-	BL	runtime·exit1(SB)
-
-	// It shouldn't return
-	MOVW	$1234, R0
-	MOVW	$1005, R1
-	MOVW	R0, (R1)
-
-TEXT runtime·sigaltstack(SB),NOSPLIT,$0
-	MOVW	0(FP), R0
-	MOVW	4(FP), R1
-	MOVW	$SYS_sigaltstack, R7
-	SWI	$0
-	MOVW	$0xfffff001, R6
-	CMP 	R6, R0
-	MOVW.HI	$0, R8  // crash on syscall failure
-	MOVW.HI	R8, (R8)
-	RET
-
-TEXT runtime·sigtramp(SB),NOSPLIT,$24
-	// this might be called in external code context,
-	// where g and m are not set.
-	// first save R0, because runtime·load_gm will clobber it
-	MOVW	R0, 4(R13)
-	MOVB	runtime·iscgo(SB), R0
-	CMP 	$0, R0
-	BL.NE	runtime·load_gm(SB)
-
-	CMP 	$0, m
-	BNE 	4(PC)
-	// signal number is already prepared in 4(R13)
-	MOVW  	$runtime·badsignal(SB), R11
-	BL	(R11)
-	RET
-
-	// save g
-	MOVW	g, R3
-	MOVW	g, 20(R13)
-
-	// g = m->gsignal
-	MOVW	m_gsignal(m), g
-
-	// copy arguments for call to sighandler
-	// R0 is already saved above
-	MOVW	R1, 8(R13)
-	MOVW	R2, 12(R13)
-	MOVW	R3, 16(R13)
-
-	BL	runtime·sighandler(SB)
-
-	// restore g
-	MOVW	20(R13), g
-
-	RET
-
-TEXT runtime·rtsigprocmask(SB),NOSPLIT,$0
-	MOVW	0(FP), R0
-	MOVW	4(FP), R1
-	MOVW	8(FP), R2
-	MOVW	12(FP), R3
-	MOVW	$SYS_rt_sigprocmask, R7
-	SWI	$0
-	RET
-
-TEXT runtime·rt_sigaction(SB),NOSPLIT,$0
-	MOVW	0(FP), R0
-	MOVW	4(FP), R1
-	MOVW	8(FP), R2
-	MOVW	12(FP), R3
-	MOVW	$SYS_rt_sigaction, R7
-	SWI	$0
-	RET
-
-TEXT runtime·sigreturn(SB),NOSPLIT,$0
-	MOVW	$SYS_rt_sigreturn, R7
-	SWI	$0
-	RET
-
-TEXT runtime·usleep(SB),NOSPLIT,$12
-	MOVW	usec+0(FP), R0
-	MOVW	R0, R1
-	MOVW	$1000000, R2
-	DIV	R2, R0
-	MOD	R2, R1
-	MOVW	R0, 4(SP)
-	MOVW	R1, 8(SP)
-	MOVW	$0, R0
-	MOVW	$0, R1
-	MOVW	$0, R2
-	MOVW	$0, R3
-	MOVW	$4(SP), R4
-	MOVW	$SYS_select, R7
-	SWI	$0
-	RET
-
-// Use kernel version instead of native armcas in asm_arm.s.
-// See ../sync/atomic/asm_linux_arm.s for details.
-TEXT cas<>(SB),NOSPLIT,$0
-	MOVW	$0xffff0fc0, PC
-
-TEXT runtime·cas(SB),NOSPLIT,$0
-	MOVW	valptr+0(FP), R2
-	MOVW	old+4(FP), R0
-casagain:
-	MOVW	new+8(FP), R1
-	BL	cas<>(SB)
-	BCC	cascheck
-	MOVW	$1, R0
-	RET
-cascheck:
-	// Kernel lies; double-check.
-	MOVW	valptr+0(FP), R2
-	MOVW	old+4(FP), R0
-	MOVW	0(R2), R3
-	CMP	R0, R3
-	BEQ	casagain
-	MOVW	$0, R0
-	RET
-
-TEXT runtime·casp(SB),NOSPLIT,$0
-	B	runtime·cas(SB)
-
-TEXT runtime·osyield(SB),NOSPLIT,$0
-	MOVW	$SYS_sched_yield, R7
-	SWI	$0
-	RET
-
-TEXT runtime·sched_getaffinity(SB),NOSPLIT,$0
-	MOVW	0(FP), R0
-	MOVW	4(FP), R1
-	MOVW	8(FP), R2
-	MOVW	$SYS_sched_getaffinity, R7
-	SWI	$0
-	RET
-
-// int32 runtime·epollcreate(int32 size)
-TEXT runtime·epollcreate(SB),NOSPLIT,$0
-	MOVW	0(FP), R0
-	MOVW	$SYS_epoll_create, R7
-	SWI	$0
-	RET
-
-// int32 runtime·epollcreate1(int32 flags)
-TEXT runtime·epollcreate1(SB),NOSPLIT,$0
-	MOVW	0(FP), R0
-	MOVW	$SYS_epoll_create1, R7
-	SWI	$0
-	RET
-
-// int32 runtime·epollctl(int32 epfd, int32 op, int32 fd, EpollEvent *ev)
-TEXT runtime·epollctl(SB),NOSPLIT,$0
-	MOVW	0(FP), R0
-	MOVW	4(FP), R1
-	MOVW	8(FP), R2
-	MOVW	12(FP), R3
-	MOVW	$SYS_epoll_ctl, R7
-	SWI	$0
-	RET
-
-// int32 runtime·epollwait(int32 epfd, EpollEvent *ev, int32 nev, int32 timeout)
-TEXT runtime·epollwait(SB),NOSPLIT,$0
-	MOVW	0(FP), R0
-	MOVW	4(FP), R1
-	MOVW	8(FP), R2
-	MOVW	12(FP), R3
-	MOVW	$SYS_epoll_wait, R7
-	SWI	$0
-	RET
-
-// void runtime·closeonexec(int32 fd)
-TEXT runtime·closeonexec(SB),NOSPLIT,$0
-	MOVW	0(FP), R0	// fd
-	MOVW	$2, R1	// F_SETFD
-	MOVW	$1, R2	// FD_CLOEXEC
-	MOVW	$SYS_fcntl, R7
-	SWI	$0
-	RET
-
-// b __kuser_get_tls @ 0xffff0fe0
-TEXT runtime·read_tls_fallback(SB),NOSPLIT,$-4
-	MOVW	$0xffff0fe0, R0
-	B	(R0)
diff --git a/src/pkg/runtime/sys_nacl_386.s b/src/pkg/runtime/sys_nacl_386.s
deleted file mode 100644
index 42ba0e0..0000000
--- a/src/pkg/runtime/sys_nacl_386.s
+++ /dev/null
@@ -1,243 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "zasm_GOOS_GOARCH.h"
-#include "../../cmd/ld/textflag.h"
-#include "syscall_nacl.h"
-
-#define NACL_SYSCALL(code) \
-	MOVL $(0x10000 + ((code)<<5)), AX; CALL AX
-
-#define NACL_SYSJMP(code) \
-	MOVL $(0x10000 + ((code)<<5)), AX; JMP AX
-
-TEXT runtime·exit(SB),NOSPLIT,$0
-	NACL_SYSJMP(SYS_exit)
-
-TEXT runtime·exit1(SB),NOSPLIT,$0
-	NACL_SYSJMP(SYS_thread_exit)
-
-TEXT runtime·open(SB),NOSPLIT,$0
-	NACL_SYSJMP(SYS_open)
-
-TEXT runtime·close(SB),NOSPLIT,$0
-	NACL_SYSJMP(SYS_close)
-
-TEXT runtime·read(SB),NOSPLIT,$0
-	NACL_SYSJMP(SYS_read)
-
-TEXT syscall·naclWrite(SB), NOSPLIT, $12-16
-	MOVL arg1+0(FP), DI
-	MOVL arg2+4(FP), SI
-	MOVL arg3+8(FP), DX
-	MOVL DI, 0(SP)
-	MOVL SI, 4(SP)
-	MOVL DX, 8(SP)
-	CALL runtime·write(SB)
-	MOVL AX, ret+16(FP)
-	RET
-
-TEXT runtime·write(SB),NOSPLIT,$0
-	NACL_SYSJMP(SYS_write)
-
-TEXT runtime·nacl_exception_stack(SB),NOSPLIT,$0
-	NACL_SYSJMP(SYS_exception_stack)
-
-TEXT runtime·nacl_exception_handler(SB),NOSPLIT,$0
-	NACL_SYSJMP(SYS_exception_handler)
-
-TEXT runtime·nacl_sem_create(SB),NOSPLIT,$0
-	NACL_SYSJMP(SYS_sem_create)
-
-TEXT runtime·nacl_sem_wait(SB),NOSPLIT,$0
-	NACL_SYSJMP(SYS_sem_wait)
-
-TEXT runtime·nacl_sem_post(SB),NOSPLIT,$0
-	NACL_SYSJMP(SYS_sem_post)
-
-TEXT runtime·nacl_mutex_create(SB),NOSPLIT,$0
-	NACL_SYSJMP(SYS_mutex_create)
-
-TEXT runtime·nacl_mutex_lock(SB),NOSPLIT,$0
-	NACL_SYSJMP(SYS_mutex_lock)
-
-TEXT runtime·nacl_mutex_trylock(SB),NOSPLIT,$0
-	NACL_SYSJMP(SYS_mutex_trylock)
-
-TEXT runtime·nacl_mutex_unlock(SB),NOSPLIT,$0
-	NACL_SYSJMP(SYS_mutex_unlock)
-
-TEXT runtime·nacl_cond_create(SB),NOSPLIT,$0
-	NACL_SYSJMP(SYS_cond_create)
-
-TEXT runtime·nacl_cond_wait(SB),NOSPLIT,$0
-	NACL_SYSJMP(SYS_cond_wait)
-
-TEXT runtime·nacl_cond_signal(SB),NOSPLIT,$0
-	NACL_SYSJMP(SYS_cond_signal)
-
-TEXT runtime·nacl_cond_broadcast(SB),NOSPLIT,$0
-	NACL_SYSJMP(SYS_cond_broadcast)
-
-TEXT runtime·nacl_cond_timed_wait_abs(SB),NOSPLIT,$0
-	NACL_SYSJMP(SYS_cond_timed_wait_abs)
-
-TEXT runtime·nacl_thread_create(SB),NOSPLIT,$0
-	NACL_SYSJMP(SYS_thread_create)
-
-TEXT runtime·mstart_nacl(SB),NOSPLIT,$0
-	JMP runtime·mstart(SB)
-
-TEXT runtime·nacl_nanosleep(SB),NOSPLIT,$0
-	NACL_SYSJMP(SYS_nanosleep)
-
-TEXT runtime·osyield(SB),NOSPLIT,$0
-	NACL_SYSJMP(SYS_sched_yield)
-
-TEXT runtime·mmap(SB),NOSPLIT,$32
-	MOVL	arg1+0(FP), AX
-	MOVL	AX, 0(SP)
-	MOVL	arg2+4(FP), AX
-	MOVL	AX, 4(SP)
-	MOVL	arg3+8(FP), AX
-	MOVL	AX, 8(SP)
-	MOVL	arg4+12(FP), AX
-	MOVL	AX, 12(SP)
-	MOVL	arg5+16(FP), AX
-	MOVL	AX, 16(SP)
-	MOVL	arg6+20(FP), AX
-	MOVL	AX, 24(SP)
-	MOVL	$0, 28(SP)
-	LEAL	24(SP), AX
-	MOVL	AX, 20(SP)
-	NACL_SYSCALL(SYS_mmap)
-	RET
-
-TEXT time·now(SB),NOSPLIT,$20
-	MOVL $0, 0(SP) // real time clock
-	LEAL 8(SP), AX
-	MOVL AX, 4(SP) // timespec
-	NACL_SYSCALL(SYS_clock_gettime)
-	MOVL 8(SP), AX // low 32 sec
-	MOVL 12(SP), CX // high 32 sec
-	MOVL 16(SP), BX // nsec
-
-	// sec is in AX, nsec in BX
-	MOVL	AX, sec+0(FP)
-	MOVL	CX, sec+4(FP)
-	MOVL	BX, nsec+8(FP)
-	RET
-
-TEXT syscall·now(SB),NOSPLIT,$0
-	JMP time·now(SB)
-
-TEXT runtime·nacl_clock_gettime(SB),NOSPLIT,$0
-	NACL_SYSJMP(SYS_clock_gettime)
-	
-TEXT runtime·nanotime(SB),NOSPLIT,$20
-	MOVL $0, 0(SP) // real time clock
-	LEAL 8(SP), AX
-	MOVL AX, 4(SP) // timespec
-	NACL_SYSCALL(SYS_clock_gettime)
-	MOVL 8(SP), AX // low 32 sec
-	MOVL 16(SP), BX // nsec
-
-	// sec is in AX, nsec in BX
-	// convert to DX:AX nsec
-	MOVL	$1000000000, CX
-	MULL	CX
-	ADDL	BX, AX
-	ADCL	$0, DX
-
-	MOVL	ret+0(FP), DI
-	MOVL	AX, 0(DI)
-	MOVL	DX, 4(DI)
-	RET
-
-TEXT runtime·setldt(SB),NOSPLIT,$8
-	MOVL	addr+4(FP), BX // aka base
-	ADDL	$0x8, BX
-	MOVL	BX, 0(SP)
-	NACL_SYSCALL(SYS_tls_init)
-	RET
-
-TEXT runtime·sigtramp(SB),NOSPLIT,$0
-	get_tls(CX)
-
-	// check that m exists
-	MOVL	m(CX), BX
-	CMPL	BX, $0
-	JNE	6(PC)
-	MOVL	$11, BX
-	MOVL	BX, 0(SP)
-	MOVL	$runtime·badsignal(SB), AX
-	CALL	AX
-	JMP 	sigtramp_ret
-
-	// save g
-	MOVL	g(CX), DI
-	MOVL	DI, 20(SP)
-	
-	// g = m->gsignal
-	MOVL	m_gsignal(BX), BX
-	MOVL	BX, g(CX)
-	
-	// copy arguments for sighandler
-	MOVL	$11, 0(SP) // signal
-	MOVL	$0, 4(SP) // siginfo
-	LEAL	ctxt+4(FP), AX
-	MOVL	AX, 8(SP) // context
-	MOVL	DI, 12(SP) // g
-
-	CALL	runtime·sighandler(SB)
-
-	// restore g
-	get_tls(CX)
-	MOVL	20(SP), BX
-	MOVL	BX, g(CX)
-
-sigtramp_ret:
-	// Enable exceptions again.
-	NACL_SYSCALL(SYS_exception_clear_flag)
-
-	// NaCl has abidcated its traditional operating system responsibility
-	// and declined to implement 'sigreturn'. Instead the only way to return
-	// to the execution of our program is to restore the registers ourselves.
-	// Unfortunately, that is impossible to do with strict fidelity, because
-	// there is no way to do the final update of PC that ends the sequence
-	// without either (1) jumping to a register, in which case the register ends
-	// holding the PC value instead of its intended value or (2) storing the PC
-	// on the stack and using RET, which imposes the requirement that SP is
-	// valid and that is okay to smash the word below it. The second would
-	// normally be the lesser of the two evils, except that on NaCl, the linker
-	// must rewrite RET into "POP reg; AND $~31, reg; JMP reg", so either way
-	// we are going to lose a register as a result of the incoming signal.
-	// Similarly, there is no way to restore EFLAGS; the usual way is to use
-	// POPFL, but NaCl rejects that instruction. We could inspect the bits and
-	// execute a sequence of instructions designed to recreate those flag
-	// settings, but that's a lot of work.
-	//
-	// Thankfully, Go's signal handlers never try to return directly to the
-	// executing code, so all the registers and EFLAGS are dead and can be
-	// smashed. The only registers that matter are the ones that are setting
-	// up for the simulated call that the signal handler has created.
-	// Today those registers are just PC and SP, but in case additional registers
-	// are relevant in the future (for example DX is the Go func context register)
-	// we restore as many registers as possible.
-	// 
-	// We smash BP, because that's what the linker smashes during RET.
-	//
-	LEAL	ctxt+4(FP), BP
-	ADDL	$64, BP
-	MOVL	0(BP), AX
-	MOVL	4(BP), CX
-	MOVL	8(BP), DX
-	MOVL	12(BP), BX
-	MOVL	16(BP), SP
-	// 20(BP) is saved BP, never to be seen again
-	MOVL	24(BP), SI
-	MOVL	28(BP), DI
-	// 36(BP) is saved EFLAGS, never to be seen again
-	MOVL	32(BP), BP // saved PC
-	JMP	BP
diff --git a/src/pkg/runtime/sys_nacl_amd64p32.s b/src/pkg/runtime/sys_nacl_amd64p32.s
deleted file mode 100644
index 43c1723..0000000
--- a/src/pkg/runtime/sys_nacl_amd64p32.s
+++ /dev/null
@@ -1,413 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "zasm_GOOS_GOARCH.h"
-#include "../../cmd/ld/textflag.h"
-#include "syscall_nacl.h"
-
-#define NACL_SYSCALL(code) \
-	MOVL $(0x10000 + ((code)<<5)), AX; CALL AX
-
-#define NACL_SYSJMP(code) \
-	MOVL $(0x10000 + ((code)<<5)), AX; JMP AX
-
-TEXT runtime·settls(SB),NOSPLIT,$0
-	MOVL	DI, TLS // really BP
-	RET
-
-TEXT runtime·exit(SB),NOSPLIT,$0
-	MOVL arg1+0(FP), DI
-	NACL_SYSJMP(SYS_exit)
-
-TEXT runtime·exit1(SB),NOSPLIT,$0
-	MOVL arg1+0(FP), DI
-	NACL_SYSJMP(SYS_thread_exit)
-
-TEXT runtime·open(SB),NOSPLIT,$0
-	MOVL arg1+0(FP), DI
-	MOVL arg2+4(FP), SI
-	MOVL arg3+8(FP), DX
-	NACL_SYSJMP(SYS_open)
-
-TEXT runtime·close(SB),NOSPLIT,$0
-	MOVL arg1+0(FP), DI
-	NACL_SYSJMP(SYS_close)
-
-TEXT runtime·read(SB),NOSPLIT,$0
-	MOVL arg1+0(FP), DI
-	MOVL arg2+4(FP), SI
-	MOVL arg3+8(FP), DX
-	NACL_SYSJMP(SYS_read)
-
-TEXT syscall·naclWrite(SB), NOSPLIT, $16-20
-	MOVL arg1+0(FP), DI
-	MOVL arg2+4(FP), SI
-	MOVL arg3+8(FP), DX
-	MOVL DI, 0(SP)
-	MOVL SI, 4(SP)
-	MOVL DX, 8(SP)
-	CALL runtime·write(SB)
-	MOVL AX, ret+16(FP)
-	RET
-
-TEXT runtime·write(SB),NOSPLIT,$16-12
-	// If using fake time and writing to stdout or stderr,
-	// emit playback header before actual data.
-	MOVQ runtime·timens(SB), AX
-	CMPQ AX, $0
-	JEQ write
-	MOVL arg1+0(FP), DI
-	CMPL DI, $1
-	JEQ playback
-	CMPL DI, $2
-	JEQ playback
-
-write:
-	// Ordinary write.
-	MOVL arg1+0(FP), DI
-	MOVL arg2+4(FP), SI
-	MOVL arg3+8(FP), DX
-	NACL_SYSCALL(SYS_write)
-	RET
-
-	// Write with playback header.
-	// First, lock to avoid interleaving writes.
-playback:
-	MOVL $1, BX
-	XCHGL	runtime·writelock(SB), BX
-	CMPL BX, $0
-	JNE playback
-
-	// Playback header: 0 0 P B <8-byte time> <4-byte data length>
-	MOVL $(('B'<<24) | ('P'<<16)), 0(SP)
-	BSWAPQ AX
-	MOVQ AX, 4(SP)
-	MOVL arg3+8(FP), DX
-	BSWAPL DX
-	MOVL DX, 12(SP)
-	MOVL $1, DI // standard output
-	MOVL SP, SI
-	MOVL $16, DX
-	NACL_SYSCALL(SYS_write)
-
-	// Write actual data.
-	MOVL $1, DI // standard output
-	MOVL arg2+4(FP), SI
-	MOVL arg3+8(FP), DX
-	NACL_SYSCALL(SYS_write)
-
-	// Unlock.
-	MOVL	$0, runtime·writelock(SB)
-
-	RET
-
-TEXT runtime·nacl_exception_stack(SB),NOSPLIT,$0
-	MOVL arg1+0(FP), DI
-	MOVL arg2+4(FP), SI
-	NACL_SYSJMP(SYS_exception_stack)
-
-TEXT runtime·nacl_exception_handler(SB),NOSPLIT,$0
-	MOVL arg1+0(FP), DI
-	MOVL arg2+4(FP), SI
-	NACL_SYSJMP(SYS_exception_handler)
-
-TEXT runtime·nacl_sem_create(SB),NOSPLIT,$0
-	MOVL arg1+0(FP), DI
-	NACL_SYSJMP(SYS_sem_create)
-
-TEXT runtime·nacl_sem_wait(SB),NOSPLIT,$0
-	MOVL arg1+0(FP), DI
-	NACL_SYSJMP(SYS_sem_wait)
-
-TEXT runtime·nacl_sem_post(SB),NOSPLIT,$0
-	MOVL arg1+0(FP), DI
-	NACL_SYSJMP(SYS_sem_post)
-
-TEXT runtime·nacl_mutex_create(SB),NOSPLIT,$0
-	MOVL arg1+0(FP), DI
-	NACL_SYSJMP(SYS_mutex_create)
-
-TEXT runtime·nacl_mutex_lock(SB),NOSPLIT,$0
-	MOVL arg1+0(FP), DI
-	NACL_SYSJMP(SYS_mutex_lock)
-
-TEXT runtime·nacl_mutex_trylock(SB),NOSPLIT,$0
-	MOVL arg1+0(FP), DI
-	NACL_SYSJMP(SYS_mutex_trylock)
-
-TEXT runtime·nacl_mutex_unlock(SB),NOSPLIT,$0
-	MOVL arg1+0(FP), DI
-	NACL_SYSJMP(SYS_mutex_unlock)
-
-TEXT runtime·nacl_cond_create(SB),NOSPLIT,$0
-	MOVL arg1+0(FP), DI
-	NACL_SYSJMP(SYS_cond_create)
-
-TEXT runtime·nacl_cond_wait(SB),NOSPLIT,$0
-	MOVL arg1+0(FP), DI
-	MOVL arg2+4(FP), SI
-	NACL_SYSJMP(SYS_cond_wait)
-
-TEXT runtime·nacl_cond_signal(SB),NOSPLIT,$0
-	MOVL arg1+0(FP), DI
-	NACL_SYSJMP(SYS_cond_signal)
-
-TEXT runtime·nacl_cond_broadcast(SB),NOSPLIT,$0
-	MOVL arg1+0(FP), DI
-	NACL_SYSJMP(SYS_cond_broadcast)
-
-TEXT runtime·nacl_cond_timed_wait_abs(SB),NOSPLIT,$0
-	MOVL arg1+0(FP), DI
-	MOVL arg2+4(FP), SI
-	MOVL arg3+8(FP), DX
-	NACL_SYSJMP(SYS_cond_timed_wait_abs)
-
-TEXT runtime·nacl_thread_create(SB),NOSPLIT,$0
-	MOVL arg1+0(FP), DI
-	MOVL arg2+4(FP), SI
-	MOVL arg3+8(FP), DX
-	MOVL arg4+12(FP), CX
-	NACL_SYSJMP(SYS_thread_create)
-
-TEXT runtime·mstart_nacl(SB),NOSPLIT,$0
-	NACL_SYSCALL(SYS_tls_get)
-	SUBL	$8, AX
-	MOVL	AX, TLS
-	JMP runtime·mstart(SB)
-
-TEXT runtime·nacl_nanosleep(SB),NOSPLIT,$0
-	MOVL arg1+0(FP), DI
-	MOVL arg2+4(FP), SI
-	NACL_SYSJMP(SYS_nanosleep)
-
-TEXT runtime·osyield(SB),NOSPLIT,$0
-	NACL_SYSJMP(SYS_sched_yield)
-
-TEXT runtime·mmap(SB),NOSPLIT,$8
-	MOVL arg1+0(FP), DI
-	MOVL arg2+4(FP), SI
-	MOVL arg3+8(FP), DX
-	MOVL arg4+12(FP), CX
-	MOVL arg5+16(FP), R8
-	MOVL arg6+20(FP), AX
-	MOVQ AX, 0(SP)
-	MOVL SP, R9
-	NACL_SYSCALL(SYS_mmap)
-	CMPL AX, $-4095
-	JNA 2(PC)
-	NEGL AX
-	RET
-
-TEXT time·now(SB),NOSPLIT,$16
-	MOVQ runtime·timens(SB), AX
-	CMPQ AX, $0
-	JEQ realtime
-	MOVQ $0, DX
-	MOVQ $1000000000, CX
-	DIVQ CX
-	MOVQ AX, sec+0(FP)
-	MOVL DX, nsec+8(FP)
-	RET
-realtime:
-	MOVL $0, DI // real time clock
-	LEAL 0(SP), AX
-	MOVL AX, SI // timespec
-	NACL_SYSCALL(SYS_clock_gettime)
-	MOVL 0(SP), AX // low 32 sec
-	MOVL 4(SP), CX // high 32 sec
-	MOVL 8(SP), BX // nsec
-
-	// sec is in AX, nsec in BX
-	MOVL	AX, sec+0(FP)
-	MOVL	CX, sec+4(FP)
-	MOVL	BX, nsec+8(FP)
-	RET
-
-TEXT syscall·now(SB),NOSPLIT,$0
-	JMP time·now(SB)
-
-TEXT runtime·nacl_clock_gettime(SB),NOSPLIT,$0
-	MOVL arg1+0(FP), DI
-	MOVL arg2+4(FP), SI
-	NACL_SYSJMP(SYS_clock_gettime)
-
-TEXT runtime·nanotime(SB),NOSPLIT,$16
-	MOVQ runtime·timens(SB), AX
-	CMPQ AX, $0
-	JEQ 2(PC)
-	RET
-	MOVL $0, DI // real time clock
-	LEAL 0(SP), AX
-	MOVL AX, SI // timespec
-	NACL_SYSCALL(SYS_clock_gettime)
-	MOVQ 0(SP), AX // sec
-	MOVL 8(SP), DX // nsec
-
-	// sec is in AX, nsec in DX
-	// return nsec in AX
-	IMULQ	$1000000000, AX
-	ADDQ	DX, AX
-	RET
-
-TEXT runtime·sigtramp(SB),NOSPLIT,$80
-	// restore TLS register at time of execution,
-	// in case it's been smashed.
-	// the TLS register is really BP, but for consistency
-	// with non-NaCl systems it is referred to here as TLS.
-	// NOTE: Cannot use SYS_tls_get here (like we do in mstart_nacl),
-	// because the main thread never calls tls_set.
-	LEAL ctxt+0(FP), AX
-	MOVL (16*4+5*8)(AX), AX
-	MOVL	AX, TLS
-
-	// check that m exists
-	get_tls(CX)
-	MOVL	m(CX), BX
-	
-	CMPL	BX, $0
-	JEQ	nom
-
-	// save g
-	MOVL	g(CX), DI
-	MOVL	DI, 20(SP)
-	
-	// g = m->gsignal
-	MOVL	m_gsignal(BX), BX
-	MOVL	BX, g(CX)
-
-//JMP debughandler
-
-	// copy arguments for sighandler
-	MOVL	$11, 0(SP) // signal
-	MOVL	$0, 4(SP) // siginfo
-	LEAL	ctxt+0(FP), AX
-	MOVL	AX, 8(SP) // context
-	MOVL	DI, 12(SP) // g
-
-	CALL	runtime·sighandler(SB)
-
-	// restore g
-	get_tls(CX)
-	MOVL	20(SP), BX
-	MOVL	BX, g(CX)
-
-sigtramp_ret:
-	// Enable exceptions again.
-	NACL_SYSCALL(SYS_exception_clear_flag)
-
-	// Restore registers as best we can. Impossible to do perfectly.
-	// See comment in sys_nacl_386.s for extended rationale.
-	LEAL	ctxt+0(FP), SI
-	ADDL	$64, SI
-	MOVQ	0(SI), AX
-	MOVQ	8(SI), CX
-	MOVQ	16(SI), DX
-	MOVQ	24(SI), BX
-	MOVL	32(SI), SP	// MOVL for SP sandboxing
-	// 40(SI) is saved BP aka TLS, already restored above
-	// 48(SI) is saved SI, never to be seen again
-	MOVQ	56(SI), DI
-	MOVQ	64(SI), R8
-	MOVQ	72(SI), R9
-	MOVQ	80(SI), R10
-	MOVQ	88(SI), R11
-	MOVQ	96(SI), R12
-	MOVQ	104(SI), R13
-	MOVQ	112(SI), R14
-	// 120(SI) is R15, which is owned by Native Client and must not be modified
-	MOVQ	128(SI), SI // saved PC
-	// 136(SI) is saved EFLAGS, never to be seen again
-	JMP	SI
-
-debughandler:
-	// print basic information
-	LEAL	ctxt+0(FP), DI
-	MOVL	$runtime·sigtrampf(SB), AX
-	MOVL	AX, 0(SP)
-	MOVQ	(16*4+16*8)(DI), BX // rip
-	MOVQ	BX, 8(SP)
-	MOVQ	(16*4+0*8)(DI), BX // rax
-	MOVQ	BX, 16(SP)
-	MOVQ	(16*4+1*8)(DI), BX // rcx
-	MOVQ	BX, 24(SP)
-	MOVQ	(16*4+2*8)(DI), BX // rdx
-	MOVQ	BX, 32(SP)
-	MOVQ	(16*4+3*8)(DI), BX // rbx
-	MOVQ	BX, 40(SP)
-	MOVQ	(16*4+7*8)(DI), BX // rdi
-	MOVQ	BX, 48(SP)
-	MOVQ	(16*4+15*8)(DI), BX // r15
-	MOVQ	BX, 56(SP)
-	MOVQ	(16*4+4*8)(DI), BX // rsp
-	MOVQ	0(BX), BX
-	MOVQ	BX, 64(SP)
-	CALL	runtime·printf(SB)
-	
-	LEAL	ctxt+0(FP), DI
-	MOVQ	(16*4+16*8)(DI), BX // rip
-	MOVL	BX, 0(SP)
-	MOVQ	(16*4+4*8)(DI), BX // rsp
-	MOVL	BX, 4(SP)
-	MOVL	$0, 8(SP)	// lr
-	get_tls(CX)
-	MOVL	g(CX), BX
-	MOVL	BX, 12(SP)	// gp
-	CALL	runtime·traceback(SB)
-
-notls:
-	MOVL	0, AX
-	RET
-
-nom:
-	MOVL	0, AX
-	RET
-
-// cannot do real signal handling yet, because gsignal has not been allocated.
-MOVL $1, DI; NACL_SYSCALL(SYS_exit)
-
-TEXT runtime·nacl_sysinfo(SB),NOSPLIT,$16
-/*
-	MOVL	di+0(FP), DI
-	LEAL	12(DI), BX
-	MOVL	8(DI), AX
-	ADDL	4(DI), AX
-	ADDL	$2, AX
-	LEAL	(BX)(AX*4), BX
-	MOVL	BX, runtime·nacl_irt_query(SB)
-auxloop:
-	MOVL	0(BX), DX
-	CMPL	DX, $0
-	JNE	2(PC)
-	RET
-	CMPL	DX, $32
-	JEQ	auxfound
-	ADDL	$8, BX
-	JMP	auxloop
-auxfound:
-	MOVL	4(BX), BX
-	MOVL	BX, runtime·nacl_irt_query(SB)
-
-	LEAL	runtime·nacl_irt_basic_v0_1_str(SB), DI
-	LEAL	runtime·nacl_irt_basic_v0_1(SB), SI
-	MOVL	runtime·nacl_irt_basic_v0_1_size(SB), DX
-	MOVL	runtime·nacl_irt_query(SB), BX
-	CALL	BX
-
-	LEAL	runtime·nacl_irt_memory_v0_3_str(SB), DI
-	LEAL	runtime·nacl_irt_memory_v0_3(SB), SI
-	MOVL	runtime·nacl_irt_memory_v0_3_size(SB), DX
-	MOVL	runtime·nacl_irt_query(SB), BX
-	CALL	BX
-
-	LEAL	runtime·nacl_irt_thread_v0_1_str(SB), DI
-	LEAL	runtime·nacl_irt_thread_v0_1(SB), SI
-	MOVL	runtime·nacl_irt_thread_v0_1_size(SB), DX
-	MOVL	runtime·nacl_irt_query(SB), BX
-	CALL	BX
-
-	// TODO: Once we have a NaCl SDK with futex syscall support,
-	// try switching to futex syscalls and here load the
-	// nacl-irt-futex-0.1 table.
-*/
-	RET
diff --git a/src/pkg/runtime/sys_netbsd_386.s b/src/pkg/runtime/sys_netbsd_386.s
deleted file mode 100644
index 05de55e..0000000
--- a/src/pkg/runtime/sys_netbsd_386.s
+++ /dev/null
@@ -1,374 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-//
-// System calls and other sys.stuff for 386, NetBSD
-// /usr/src/sys/kern/syscalls.master for syscall numbers.
-//
-
-#include "zasm_GOOS_GOARCH.h"
-#include "../../cmd/ld/textflag.h"
-
-// Exit the entire program (like C exit)
-TEXT runtime·exit(SB),NOSPLIT,$-4
-	MOVL	$1, AX
-	INT	$0x80
-	MOVL	$0xf1, 0xf1		// crash
-	RET
-
-TEXT runtime·exit1(SB),NOSPLIT,$-4
-	MOVL	$310, AX		// sys__lwp_exit
-	INT	$0x80
-	JAE	2(PC)
-	MOVL	$0xf1, 0xf1		// crash
-	RET
-
-TEXT runtime·open(SB),NOSPLIT,$-4
-	MOVL	$5, AX
-	INT	$0x80
-	RET
-
-TEXT runtime·close(SB),NOSPLIT,$-4
-	MOVL	$6, AX
-	INT	$0x80
-	RET
-
-TEXT runtime·read(SB),NOSPLIT,$-4
-	MOVL	$3, AX
-	INT	$0x80
-	RET
-
-TEXT runtime·write(SB),NOSPLIT,$-4
-	MOVL	$4, AX			// sys_write
-	INT	$0x80
-	RET
-
-TEXT runtime·usleep(SB),NOSPLIT,$24
-	MOVL	$0, DX
-	MOVL	usec+0(FP), AX
-	MOVL	$1000000, CX
-	DIVL	CX
-	MOVL	AX, 12(SP)		// tv_sec - l32
-	MOVL	$0, 16(SP)		// tv_sec - h32
-	MOVL	$1000, AX
-	MULL	DX
-	MOVL	AX, 20(SP)		// tv_nsec
-
-	MOVL	$0, 0(SP)
-	LEAL	12(SP), AX
-	MOVL	AX, 4(SP)		// arg 1 - rqtp
-	MOVL	$0, 8(SP)		// arg 2 - rmtp
-	MOVL	$430, AX		// sys_nanosleep
-	INT	$0x80
-	RET
-
-TEXT runtime·raise(SB),NOSPLIT,$12
-	MOVL	$311, AX		// sys__lwp_self
-	INT	$0x80
-	MOVL	$0, 0(SP)
-	MOVL	AX, 4(SP)		// arg 1 - target
-	MOVL	sig+0(FP), AX
-	MOVL	AX, 8(SP)		// arg 2 - signo
-	MOVL	$318, AX		// sys__lwp_kill
-	INT	$0x80
-	RET
-
-TEXT runtime·mmap(SB),NOSPLIT,$36
-	LEAL	arg0+0(FP), SI
-	LEAL	4(SP), DI
-	CLD
-	MOVSL				// arg 1 - addr
-	MOVSL				// arg 2 - len
-	MOVSL				// arg 3 - prot
-	MOVSL				// arg 4 - flags
-	MOVSL				// arg 5 - fd
-	MOVL	$0, AX
-	STOSL				// arg 6 - pad
-	MOVSL				// arg 7 - offset
-	MOVL	$0, AX			// top 32 bits of file offset
-	STOSL
-	MOVL	$197, AX		// sys_mmap
-	INT	$0x80
-	RET
-
-TEXT runtime·munmap(SB),NOSPLIT,$-4
-	MOVL	$73, AX			// sys_munmap
-	INT	$0x80
-	JAE	2(PC)
-	MOVL	$0xf1, 0xf1		// crash
-	RET
-
-TEXT runtime·madvise(SB),NOSPLIT,$-4
-	MOVL	$75, AX			// sys_madvise
-	INT	$0x80
-	// ignore failure - maybe pages are locked
-	RET
-
-TEXT runtime·setitimer(SB),NOSPLIT,$-4
-	MOVL	$425, AX		// sys_setitimer
-	INT	$0x80
-	RET
-
-// func now() (sec int64, nsec int32)
-TEXT time·now(SB), NOSPLIT, $32
-	LEAL	12(SP), BX
-	MOVL	$0, 4(SP)		// arg 1 - clock_id
-	MOVL	BX, 8(SP)		// arg 2 - tp
-	MOVL	$427, AX		// sys_clock_gettime
-	INT	$0x80
-
-	MOVL	12(SP), AX		// sec - l32
-	MOVL	AX, sec+0(FP)
-	MOVL	16(SP), AX		// sec - h32
-	MOVL	AX, sec+4(FP)
-
-	MOVL	20(SP), BX		// nsec
-	MOVL	BX, nsec+8(FP)
-	RET
-
-// int64 nanotime(void) so really
-// void nanotime(int64 *nsec)
-TEXT runtime·nanotime(SB),NOSPLIT,$32
-	LEAL	12(SP), BX
-	MOVL	$0, 4(SP)		// arg 1 - clock_id
-	MOVL	BX, 8(SP)		// arg 2 - tp
-	MOVL	$427, AX		// sys_clock_gettime
-	INT	$0x80
-
-	MOVL	16(SP), CX		// sec - h32
-	IMULL	$1000000000, CX
-
-	MOVL	12(SP), AX		// sec - l32
-	MOVL	$1000000000, BX
-	MULL	BX			// result in dx:ax
-
-	MOVL	20(SP), BX		// nsec
-	ADDL	BX, AX
-	ADCL	CX, DX			// add high bits with carry
-
-	MOVL	ret+0(FP), DI
-	MOVL	AX, 0(DI)
-	MOVL	DX, 4(DI)
-	RET
-
-TEXT runtime·getcontext(SB),NOSPLIT,$-4
-	MOVL	$307, AX		// sys_getcontext
-	INT	$0x80
-	JAE	2(PC)
-	MOVL	$0xf1, 0xf1		// crash
-	RET
-
-TEXT runtime·sigprocmask(SB),NOSPLIT,$-4
-	MOVL	$293, AX		// sys_sigprocmask
-	INT	$0x80
-	JAE	2(PC)
-	MOVL	$0xf1, 0xf1		// crash
-	RET
-
-TEXT runtime·sigreturn_tramp(SB),NOSPLIT,$0
-	LEAL	140(SP), AX		// Load address of ucontext
-	MOVL	AX, 4(SP)
-	MOVL	$308, AX		// sys_setcontext
-	INT	$0x80
-	MOVL	$-1, 4(SP)		// Something failed...
-	MOVL	$1, AX			// sys_exit
-	INT	$0x80
-
-TEXT runtime·sigaction(SB),NOSPLIT,$24
-	LEAL	arg0+0(FP), SI
-	LEAL	4(SP), DI
-	CLD
-	MOVSL				// arg 1 - sig
-	MOVSL				// arg 2 - act
-	MOVSL				// arg 3 - oact
-	LEAL	runtime·sigreturn_tramp(SB), AX
-	STOSL				// arg 4 - tramp
-	MOVL	$2, AX
-	STOSL				// arg 5 - vers
-	MOVL	$340, AX		// sys___sigaction_sigtramp
-	INT	$0x80
-	JAE	2(PC)
-	MOVL	$0xf1, 0xf1		// crash
-	RET
-
-TEXT runtime·sigtramp(SB),NOSPLIT,$44
-	get_tls(CX)
-
-	// check that m exists
-	MOVL	m(CX), BX
-	CMPL	BX, $0
-	JNE	6(PC)
-	MOVL	signo+0(FP), BX
-	MOVL	BX, 0(SP)
-	MOVL	$runtime·badsignal(SB), AX
-	CALL	AX
-	RET
-
-	// save g
-	MOVL	g(CX), DI
-	MOVL	DI, 20(SP)
-
-	// g = m->gsignal
-	MOVL	m_gsignal(BX), BX
-	MOVL	BX, g(CX)
-
-	// copy arguments for call to sighandler
-	MOVL	signo+0(FP), BX
-	MOVL	BX, 0(SP)
-	MOVL	info+4(FP), BX
-	MOVL	BX, 4(SP)
-	MOVL	context+8(FP), BX
-	MOVL	BX, 8(SP)
-	MOVL	DI, 12(SP)
-
-	CALL	runtime·sighandler(SB)
-
-	// restore g
-	get_tls(CX)
-	MOVL	20(SP), BX
-	MOVL	BX, g(CX)
-	RET
-
-// int32 lwp_create(void *context, uintptr flags, void *lwpid);
-TEXT runtime·lwp_create(SB),NOSPLIT,$16
-	MOVL	$0, 0(SP)
-	MOVL	context+0(FP), AX
-	MOVL	AX, 4(SP)		// arg 1 - context
-	MOVL	flags+4(FP), AX
-	MOVL	AX, 8(SP)		// arg 2 - flags
-	MOVL	lwpid+8(FP), AX
-	MOVL	AX, 12(SP)		// arg 3 - lwpid
-	MOVL	$309, AX		// sys__lwp_create
-	INT	$0x80
-	JCC	2(PC)
-	NEGL	AX
-	RET
-
-TEXT runtime·lwp_tramp(SB),NOSPLIT,$0
-
-	// Set FS to point at m->tls
-	LEAL	m_tls(BX), BP
-	PUSHAL				// save registers
-	PUSHL	BP
-	CALL	runtime·settls(SB)
-	POPL	AX
-	POPAL
-
-	// Now segment is established.  Initialize m, g.
-	get_tls(AX)
-	MOVL	DX, g(AX)
-	MOVL	BX, m(AX)
-
-	CALL	runtime·stackcheck(SB)	// smashes AX, CX
-	MOVL	0(DX), DX		// paranoia; check they are not nil
-	MOVL	0(BX), BX
-
-	// more paranoia; check that stack splitting code works
-	PUSHAL
-	CALL	runtime·emptyfunc(SB)
-	POPAL
-
-	// Call fn
-	CALL	SI
-
-	CALL	runtime·exit1(SB)
-	MOVL	$0x1234, 0x1005
-	RET
-
-TEXT runtime·sigaltstack(SB),NOSPLIT,$-8
-	MOVL	$281, AX		// sys___sigaltstack14
-	MOVL	new+4(SP), BX
-	MOVL	old+8(SP), CX
-	INT	$0x80
-	CMPL	AX, $0xfffff001
-	JLS	2(PC)
-	INT	$3
-	RET
-
-TEXT runtime·setldt(SB),NOSPLIT,$8
-	// Under NetBSD we set the GS base instead of messing with the LDT.
-	MOVL	16(SP), AX		// tls0
-	MOVL	AX, 0(SP)
-	CALL	runtime·settls(SB)
-	RET
-
-TEXT runtime·settls(SB),NOSPLIT,$16
-	// adjust for ELF: wants to use -8(GS) and -4(GS) for g and m
-	MOVL	base+0(FP), CX
-	ADDL	$8, CX
-	MOVL	$0, 0(SP)		// syscall gap
-	MOVL	CX, 4(SP)		// arg 1 - ptr
-	MOVL	$317, AX		// sys__lwp_setprivate
-	INT	$0x80
-	JCC	2(PC)
-	MOVL	$0xf1, 0xf1		// crash
-	RET
-
-TEXT runtime·osyield(SB),NOSPLIT,$-4
-	MOVL	$350, AX		// sys_sched_yield
-	INT	$0x80
-	RET
-
-TEXT runtime·lwp_park(SB),NOSPLIT,$-4
-	MOVL	$434, AX		// sys__lwp_park
-	INT	$0x80
-	RET
-
-TEXT runtime·lwp_unpark(SB),NOSPLIT,$-4
-	MOVL	$321, AX		// sys__lwp_unpark
-	INT	$0x80
-	RET
-
-TEXT runtime·lwp_self(SB),NOSPLIT,$-4
-	MOVL	$311, AX		// sys__lwp_self
-	INT	$0x80
-	RET
-
-TEXT runtime·sysctl(SB),NOSPLIT,$28
-	LEAL	arg0+0(FP), SI
-	LEAL	4(SP), DI
-	CLD
-	MOVSL				// arg 1 - name
-	MOVSL				// arg 2 - namelen
-	MOVSL				// arg 3 - oldp
-	MOVSL				// arg 4 - oldlenp
-	MOVSL				// arg 5 - newp
-	MOVSL				// arg 6 - newlen
-	MOVL	$202, AX		// sys___sysctl
-	INT	$0x80
-	JCC	3(PC)
-	NEGL	AX
-	RET
-	MOVL	$0, AX
-	RET
-
-GLOBL runtime·tlsoffset(SB),$4
-
-// int32 runtime·kqueue(void)
-TEXT runtime·kqueue(SB),NOSPLIT,$0
-	MOVL	$344, AX
-	INT	$0x80
-	JAE	2(PC)
-	NEGL	AX
-	RET
-
-// int32 runtime·kevent(int kq, Kevent *changelist, int nchanges, Kevent *eventlist, int nevents, Timespec *timeout)
-TEXT runtime·kevent(SB),NOSPLIT,$0
-	MOVL	$435, AX
-	INT	$0x80
-	JAE	2(PC)
-	NEGL	AX
-	RET
-
-// int32 runtime·closeonexec(int32 fd)
-TEXT runtime·closeonexec(SB),NOSPLIT,$32
-	MOVL	$92, AX		// fcntl
-	// 0(SP) is where the caller PC would be; kernel skips it
-	MOVL	fd+0(FP), BX
-	MOVL	BX, 4(SP)	// fd
-	MOVL	$2, 8(SP)	// F_SETFD
-	MOVL	$1, 12(SP)	// FD_CLOEXEC
-	INT	$0x80
-	JAE	2(PC)
-	NEGL	AX
-	RET
diff --git a/src/pkg/runtime/sys_netbsd_amd64.s b/src/pkg/runtime/sys_netbsd_amd64.s
deleted file mode 100644
index fcbced5..0000000
--- a/src/pkg/runtime/sys_netbsd_amd64.s
+++ /dev/null
@@ -1,344 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-//
-// System calls and other sys.stuff for AMD64, NetBSD
-// /usr/src/sys/kern/syscalls.master for syscall numbers.
-//
-
-#include "zasm_GOOS_GOARCH.h"
-#include "../../cmd/ld/textflag.h"
-
-// int32 lwp_create(void *context, uintptr flags, void *lwpid)
-TEXT runtime·lwp_create(SB),NOSPLIT,$0
-	MOVQ	context+0(FP), DI
-	MOVQ	flags+8(FP), SI
-	MOVQ	lwpid+16(FP), DX
-	MOVL	$309, AX		// sys__lwp_create
-	SYSCALL
-	JCC	2(PC)
-	NEGQ	AX
-	RET
-
-TEXT runtime·lwp_tramp(SB),NOSPLIT,$0
-	
-	// Set FS to point at m->tls.
-	LEAQ	m_tls(R8), DI
-	CALL	runtime·settls(SB)
-
-	// Set up new stack.
-	get_tls(CX)
-	MOVQ	R8, m(CX)
-	MOVQ	R9, g(CX)
-	CALL	runtime·stackcheck(SB)
-
-	// Call fn
-	CALL	R12
-
-	// It shouldn't return.  If it does, exit.
-	MOVL	$310, AX		// sys__lwp_exit
-	SYSCALL
-	JMP	-3(PC)			// keep exiting
-
-TEXT runtime·osyield(SB),NOSPLIT,$0
-	MOVL	$350, AX		// sys_sched_yield
-	SYSCALL
-	RET
-
-TEXT runtime·lwp_park(SB),NOSPLIT,$0
-	MOVQ	8(SP), DI		// arg 1 - abstime
-	MOVL	16(SP), SI		// arg 2 - unpark
-	MOVQ	24(SP), DX		// arg 3 - hint
-	MOVQ	32(SP), R10		// arg 4 - unparkhint
-	MOVL	$434, AX		// sys__lwp_park
-	SYSCALL
-	RET
-
-TEXT runtime·lwp_unpark(SB),NOSPLIT,$0
-	MOVQ	8(SP), DI		// arg 1 - lwp
-	MOVL	16(SP), SI		// arg 2 - hint
-	MOVL	$321, AX		// sys__lwp_unpark
-	SYSCALL
-	RET
-
-TEXT runtime·lwp_self(SB),NOSPLIT,$0
-	MOVL	$311, AX		// sys__lwp_self
-	SYSCALL
-	RET
-
-// Exit the entire program (like C exit)
-TEXT runtime·exit(SB),NOSPLIT,$-8
-	MOVL	8(SP), DI		// arg 1 - exit status
-	MOVL	$1, AX			// sys_exit
-	SYSCALL
-	MOVL	$0xf1, 0xf1		// crash
-	RET
-
-TEXT runtime·exit1(SB),NOSPLIT,$-8
-	MOVL	$310, AX		// sys__lwp_exit
-	SYSCALL
-	MOVL	$0xf1, 0xf1		// crash
-	RET
-
-TEXT runtime·open(SB),NOSPLIT,$-8
-	MOVQ	8(SP), DI		// arg 1 pathname
-	MOVL	16(SP), SI		// arg 2 flags
-	MOVL	20(SP), DX		// arg 3 mode
-	MOVL	$5, AX
-	SYSCALL
-	RET
-
-TEXT runtime·close(SB),NOSPLIT,$-8
-	MOVL	8(SP), DI		// arg 1 fd
-	MOVL	$6, AX
-	SYSCALL
-	RET
-
-TEXT runtime·read(SB),NOSPLIT,$-8
-	MOVL	8(SP), DI		// arg 1 fd
-	MOVQ	16(SP), SI		// arg 2 buf
-	MOVL	24(SP), DX		// arg 3 count
-	MOVL	$3, AX
-	SYSCALL
-	RET
-
-TEXT runtime·write(SB),NOSPLIT,$-8
-	MOVL	8(SP), DI		// arg 1 - fd
-	MOVQ	16(SP), SI		// arg 2 - buf
-	MOVL	24(SP), DX		// arg 3 - nbyte
-	MOVL	$4, AX			// sys_write
-	SYSCALL
-	RET
-
-TEXT runtime·usleep(SB),NOSPLIT,$16
-	MOVL	$0, DX
-	MOVL	usec+0(FP), AX
-	MOVL	$1000000, CX
-	DIVL	CX
-	MOVQ	AX, 0(SP)		// tv_sec
-	MOVL	$1000, AX
-	MULL	DX
-	MOVQ	AX, 8(SP)		// tv_nsec
-
-	MOVQ	SP, DI			// arg 1 - rqtp
-	MOVQ	$0, SI			// arg 2 - rmtp
-	MOVL	$430, AX		// sys_nanosleep
-	SYSCALL
-	RET
-
-TEXT runtime·raise(SB),NOSPLIT,$16
-	MOVL	$311, AX		// sys__lwp_self
-	SYSCALL
-	MOVQ	AX, DI			// arg 1 - target
-	MOVL	sig+0(FP), SI		// arg 2 - signo
-	MOVL	$318, AX		// sys__lwp_kill
-	SYSCALL
-	RET
-
-TEXT runtime·setitimer(SB),NOSPLIT,$-8
-	MOVL	8(SP), DI		// arg 1 - which
-	MOVQ	16(SP), SI		// arg 2 - itv
-	MOVQ	24(SP), DX		// arg 3 - oitv
-	MOVL	$425, AX		// sys_setitimer
-	SYSCALL
-	RET
-
-// func now() (sec int64, nsec int32)
-TEXT time·now(SB), NOSPLIT, $32
-	MOVQ	$0, DI			// arg 1 - clock_id
-	LEAQ	8(SP), SI		// arg 2 - tp
-	MOVL	$427, AX		// sys_clock_gettime
-	SYSCALL
-	MOVQ	8(SP), AX		// sec
-	MOVL	16(SP), DX		// nsec
-
-	// sec is in AX, nsec in DX
-	MOVQ	AX, sec+0(FP)
-	MOVL	DX, nsec+8(FP)
-	RET
-
-TEXT runtime·nanotime(SB),NOSPLIT,$32
-	MOVQ	$0, DI			// arg 1 - clock_id
-	LEAQ	8(SP), SI		// arg 2 - tp
-	MOVL	$427, AX		// sys_clock_gettime
-	SYSCALL
-	MOVQ	8(SP), AX		// sec
-	MOVL	16(SP), DX		// nsec
-
-	// sec is in AX, nsec in DX
-	// return nsec in AX
-	IMULQ	$1000000000, AX
-	ADDQ	DX, AX
-	RET
-
-TEXT runtime·getcontext(SB),NOSPLIT,$-8
-	MOVQ	8(SP), DI		// arg 1 - context
-	MOVL	$307, AX		// sys_getcontext
-	SYSCALL
-	JCC	2(PC)
-	MOVL	$0xf1, 0xf1		// crash
-	RET
-
-TEXT runtime·sigprocmask(SB),NOSPLIT,$0
-	MOVL	8(SP), DI		// arg 1 - how
-	MOVQ	16(SP), SI		// arg 2 - set
-	MOVQ	24(SP), DX		// arg 3 - oset
-	MOVL	$293, AX		// sys_sigprocmask
-	SYSCALL
-	JCC	2(PC)
-	MOVL	$0xf1, 0xf1		// crash
-	RET
-
-TEXT runtime·sigreturn_tramp(SB),NOSPLIT,$-8
-	MOVQ	R15, DI			// Load address of ucontext
-	MOVQ	$308, AX		// sys_setcontext
-	SYSCALL
-	MOVQ	$-1, DI			// Something failed...
-	MOVL	$1, AX			// sys_exit
-	SYSCALL
-
-TEXT runtime·sigaction(SB),NOSPLIT,$-8
-	MOVL	8(SP), DI		// arg 1 - signum
-	MOVQ	16(SP), SI		// arg 2 - nsa
-	MOVQ	24(SP), DX		// arg 3 - osa
-					// arg 4 - tramp
-	LEAQ	runtime·sigreturn_tramp(SB), R10
-	MOVQ	$2, R8			// arg 5 - vers
-	MOVL	$340, AX		// sys___sigaction_sigtramp
-	SYSCALL
-	JCC	2(PC)
-	MOVL	$0xf1, 0xf1		// crash
-	RET
-
-TEXT runtime·sigtramp(SB),NOSPLIT,$64
-	get_tls(BX)
-
-	// check that m exists
-	MOVQ	m(BX), BP
-	CMPQ	BP, $0
-	JNE	5(PC)
-	MOVQ	DI, 0(SP)
-	MOVQ	$runtime·badsignal(SB), AX
-	CALL	AX
-	RET
-
-	// save g
-	MOVQ	g(BX), R10
-	MOVQ	R10, 40(SP)
-
-	// g = m->signal
-	MOVQ	m_gsignal(BP), BP
-	MOVQ	BP, g(BX)
-
-	MOVQ	DI, 0(SP)
-	MOVQ	SI, 8(SP)
-	MOVQ	DX, 16(SP)
-	MOVQ	R10, 24(SP)
-
-	CALL	runtime·sighandler(SB)
-
-	// restore g
-	get_tls(BX)
-	MOVQ	40(SP), R10
-	MOVQ	R10, g(BX)
-	RET
-
-TEXT runtime·mmap(SB),NOSPLIT,$0
-	MOVQ	8(SP), DI		// arg 1 - addr
-	MOVQ	16(SP), SI		// arg 2 - len
-	MOVL	24(SP), DX		// arg 3 - prot
-	MOVL	28(SP), R10		// arg 4 - flags
-	MOVL	32(SP), R8		// arg 5 - fd
-	MOVQ	36(SP), R9
-	SUBQ	$16, SP
-	MOVQ	R9, 8(SP)		// arg 7 - offset (passed on stack)
-	MOVQ	$0, R9			// arg 6 - pad
-	MOVL	$197, AX		// sys_mmap
-	SYSCALL
-	ADDQ	$16, SP
-	RET
-
-TEXT runtime·munmap(SB),NOSPLIT,$0
-	MOVQ	8(SP), DI		// arg 1 - addr
-	MOVQ	16(SP), SI		// arg 2 - len
-	MOVL	$73, AX			// sys_munmap
-	SYSCALL
-	JCC	2(PC)
-	MOVL	$0xf1, 0xf1		// crash
-	RET
-
-
-TEXT runtime·madvise(SB),NOSPLIT,$0
-	MOVQ	addr+0(FP), DI		// arg 1 - addr
-	MOVQ	len+8(FP), SI		// arg 2 - len
-	MOVQ	behav+16(FP), DX	// arg 3 - behav
-	MOVQ	$75, AX			// sys_madvise
-	SYSCALL
-	// ignore failure - maybe pages are locked
-	RET
-
-TEXT runtime·sigaltstack(SB),NOSPLIT,$-8
-	MOVQ	new+8(SP), DI		// arg 1 - nss
-	MOVQ	old+16(SP), SI		// arg 2 - oss
-	MOVQ	$281, AX		// sys___sigaltstack14
-	SYSCALL
-	JCC	2(PC)
-	MOVL	$0xf1, 0xf1		// crash
-	RET
-
-// set tls base to DI
-TEXT runtime·settls(SB),NOSPLIT,$8
-	// adjust for ELF: wants to use -16(FS) and -8(FS) for g and m
-	ADDQ	$16, DI			// arg 1 - ptr
-	MOVQ	$317, AX		// sys__lwp_setprivate
-	SYSCALL
-	JCC	2(PC)
-	MOVL	$0xf1, 0xf1		// crash
-	RET
-
-TEXT runtime·sysctl(SB),NOSPLIT,$0
-	MOVQ	8(SP), DI		// arg 1 - name
-	MOVL	16(SP), SI		// arg 2 - namelen
-	MOVQ	24(SP), DX		// arg 3 - oldp
-	MOVQ	32(SP), R10		// arg 4 - oldlenp
-	MOVQ	40(SP), R8		// arg 5 - newp
-	MOVQ	48(SP), R9		// arg 6 - newlen
-	MOVQ	$202, AX		// sys___sysctl
-	SYSCALL
-	JCC 3(PC)
-	NEGQ	AX
-	RET
-	MOVL	$0, AX
-	RET
-
-// int32 runtime·kqueue(void)
-TEXT runtime·kqueue(SB),NOSPLIT,$0
-	MOVQ	$0, DI
-	MOVL	$344, AX
-	SYSCALL
-	JCC	2(PC)
-	NEGQ	AX
-	RET
-
-// int32 runtime·kevent(int kq, Kevent *changelist, int nchanges, Kevent *eventlist, int nevents, Timespec *timeout)
-TEXT runtime·kevent(SB),NOSPLIT,$0
-	MOVL	8(SP), DI
-	MOVQ	16(SP), SI
-	MOVL	24(SP), DX
-	MOVQ	32(SP), R10
-	MOVL	40(SP), R8
-	MOVQ	48(SP), R9
-	MOVL	$435, AX
-	SYSCALL
-	JCC	2(PC)
-	NEGQ	AX
-	RET
-
-// void runtime·closeonexec(int32 fd)
-TEXT runtime·closeonexec(SB),NOSPLIT,$0
-	MOVL	8(SP), DI	// fd
-	MOVQ	$2, SI		// F_SETFD
-	MOVQ	$1, DX		// FD_CLOEXEC
-	MOVL	$92, AX		// fcntl
-	SYSCALL
-	RET
diff --git a/src/pkg/runtime/sys_netbsd_arm.s b/src/pkg/runtime/sys_netbsd_arm.s
deleted file mode 100644
index b2eb74e..0000000
--- a/src/pkg/runtime/sys_netbsd_arm.s
+++ /dev/null
@@ -1,339 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-//
-// System calls and other sys.stuff for ARM, NetBSD
-// /usr/src/sys/kern/syscalls.master for syscall numbers.
-//
-
-#include "zasm_GOOS_GOARCH.h"
-#include "../../cmd/ld/textflag.h"
-
-// Exit the entire program (like C exit)
-TEXT runtime·exit(SB),NOSPLIT,$-4
-	MOVW 0(FP), R0	// arg 1 exit status
-	SWI $0xa00001
-	MOVW.CS $0, R8	// crash on syscall failure
-	MOVW.CS R8, (R8)
-	RET
-
-TEXT runtime·exit1(SB),NOSPLIT,$-4
-	SWI $0xa00136	// sys__lwp_exit
-	MOVW $1, R8	// crash
-	MOVW R8, (R8)
-	RET
-	
-TEXT runtime·open(SB),NOSPLIT,$-8
-	MOVW 0(FP), R0
-	MOVW 4(FP), R1
-	MOVW 8(FP), R2
-	SWI $0xa00005
-	RET
-
-TEXT runtime·close(SB),NOSPLIT,$-8
-	MOVW 0(FP), R0
-	SWI $0xa00006
-	RET
-
-TEXT runtime·read(SB),NOSPLIT,$-8
-	MOVW 0(FP), R0
-	MOVW 4(FP), R1
-	MOVW 8(FP), R2
-	SWI $0xa00003
-	RET
-
-TEXT runtime·write(SB),NOSPLIT,$-4
-	MOVW	0(FP), R0	// arg 1 - fd
-	MOVW	4(FP), R1	// arg 2 - buf
-	MOVW	8(FP), R2	// arg 3 - nbyte
-	SWI $0xa00004	// sys_write
-	RET
-
-// int32 lwp_create(void *context, uintptr flags, void *lwpid)
-TEXT runtime·lwp_create(SB),NOSPLIT,$0
-	MOVW context+0(FP), R0
-	MOVW flags+4(FP), R1
-	MOVW lwpid+8(FP), R2
-	SWI $0xa00135	// sys__lwp_create
-	RET
-
-TEXT runtime·osyield(SB),NOSPLIT,$0
-	SWI $0xa0015e	// sys_sched_yield
-	RET
-
-TEXT runtime·lwp_park(SB),NOSPLIT,$0
-	MOVW 0(FP), R0	// arg 1 - abstime
-	MOVW 4(FP), R1	// arg 2 - unpark
-	MOVW 8(FP), R2	// arg 3 - hint
-	MOVW 12(FP), R3	// arg 4 - unparkhint
-	SWI $0xa001b2	// sys__lwp_park
-	RET
-
-TEXT runtime·lwp_unpark(SB),NOSPLIT,$0
-	MOVW	0(FP), R0	// arg 1 - lwp
-	MOVW	4(FP), R1	// arg 2 - hint
-	SWI $0xa00141 // sys__lwp_unpark
-	RET
-
-TEXT runtime·lwp_self(SB),NOSPLIT,$0
-	SWI $0xa00137	// sys__lwp_self
-	RET
-
-TEXT runtime·lwp_tramp(SB),NOSPLIT,$0
-	MOVW R0, m
-	MOVW R1, g
-
-	BL runtime·emptyfunc(SB) // fault if stack check is wrong
-	BL (R2)
-	MOVW $2, R8  // crash (not reached)
-	MOVW R8, (R8)
-	RET
-
-TEXT runtime·usleep(SB),NOSPLIT,$16
-	MOVW usec+0(FP), R0
-	MOVW R0, R2
-	MOVW $1000000, R1
-	DIV R1, R0
-	// 0(R13) is the saved LR, don't use it
-	MOVW R0, 4(R13) // tv_sec.low
-	MOVW $0, R0
-	MOVW R0, 8(R13) // tv_sec.high
-	MOD R1, R2
-	MOVW $1000, R1
-	MUL R1, R2
-	MOVW R2, 12(R13) // tv_nsec
-
-	MOVW $4(R13), R0 // arg 1 - rqtp
-	MOVW $0, R1      // arg 2 - rmtp
-	SWI $0xa001ae	// sys_nanosleep
-	RET
-
-TEXT runtime·raise(SB),NOSPLIT,$16
-	SWI $0xa00137	// sys__lwp_self, the returned R0 is arg 1
-	MOVW	sig+0(FP), R1	// arg 2 - signal
-	SWI $0xa0013e	// sys__lwp_kill
-	RET
-
-TEXT runtime·setitimer(SB),NOSPLIT,$-4
-	MOVW 0(FP), R0	// arg 1 - which
-	MOVW 4(FP), R1	// arg 2 - itv
-	MOVW 8(FP), R2	// arg 3 - oitv
-	SWI $0xa001a9	// sys_setitimer
-	RET
-
-// func now() (sec int64, nsec int32)
-TEXT time·now(SB), NOSPLIT, $32
-	MOVW $0, R0	// CLOCK_REALTIME
-	MOVW $8(R13), R1
-	SWI $0xa001ab	// clock_gettime
-
-	MOVW 8(R13), R0	// sec.low
-	MOVW 12(R13), R1 // sec.high
-	MOVW 16(R13), R2 // nsec
-
-	MOVW R0, 0(FP)
-	MOVW R1, 4(FP)
-	MOVW R2, 8(FP)
-	RET
-
-// int64 nanotime(void) so really
-// void nanotime(int64 *nsec)
-TEXT runtime·nanotime(SB), NOSPLIT, $32
-	MOVW $0, R0 // CLOCK_REALTIME
-	MOVW $8(R13), R1
-	SWI $0xa001ab	// clock_gettime
-
-	MOVW 8(R13), R0 // sec.low
-	MOVW 12(R13), R4 // sec.high
-	MOVW 16(R13), R2 // nsec
-
-	MOVW $1000000000, R3
-	MULLU R0, R3, (R1, R0)
-	MUL R3, R4
-	ADD.S R2, R0
-	ADC R4, R1
-
-	MOVW 0(FP), R3
-	MOVW R0, 0(R3)
-	MOVW R1, 4(R3)
-	RET
-
-TEXT runtime·getcontext(SB),NOSPLIT,$-4
-	MOVW 0(FP), R0	// arg 1 - context
-	SWI $0xa00133	// sys_getcontext
-	MOVW.CS $0, R8	// crash on syscall failure
-	MOVW.CS R8, (R8)
-	RET
-
-TEXT runtime·sigprocmask(SB),NOSPLIT,$0
-	MOVW 0(FP), R0	// arg 1 - how
-	MOVW 4(FP), R1	// arg 2 - set
-	MOVW 8(FP), R2	// arg 3 - oset
-	SWI $0xa00125	// sys_sigprocmask
-	MOVW.CS $0, R8	// crash on syscall failure
-	MOVW.CS R8, (R8)
-	RET
-
-TEXT runtime·sigreturn_tramp(SB),NOSPLIT,$-4
-	// on entry, SP points to siginfo, we add sizeof(ucontext)
-	// to SP to get a pointer to ucontext.
-	ADD $0x80, R13, R0 // 0x80 == sizeof(UcontextT)
-	SWI $0xa00134	// sys_setcontext
-	// something failed, we have to exit
-	MOVW $0x4242, R0 // magic return number
-	SWI $0xa00001	// sys_exit
-	B -2(PC)	// continue exit
-
-TEXT runtime·sigaction(SB),NOSPLIT,$4
-	MOVW 0(FP), R0	// arg 1 - signum
-	MOVW 4(FP), R1	// arg 2 - nsa
-	MOVW 8(FP), R2	// arg 3 - osa
-	MOVW $runtime·sigreturn_tramp(SB), R3	// arg 4 - tramp
-	MOVW $2, R4	// arg 5 - vers
-	MOVW R4, 4(R13)
-	ADD $4, R13	// pass arg 5 on stack
-	SWI $0xa00154	// sys___sigaction_sigtramp
-	SUB $4, R13
-	MOVW.CS $3, R8	// crash on syscall failure
-	MOVW.CS R8, (R8)
-	RET
-
-TEXT runtime·sigtramp(SB),NOSPLIT,$24
-	// this might be called in external code context,
-	// where g and m are not set.
-	// first save R0, because runtime·load_gm will clobber it
-	MOVW	R0, 4(R13) // signum
-	MOVB	runtime·iscgo(SB), R0
-	CMP 	$0, R0
-	BL.NE	runtime·load_gm(SB)
-
-	CMP $0, m
-	BNE 4(PC)
-	// signal number is already prepared in 4(R13)
-	MOVW $runtime·badsignal(SB), R11
-	BL (R11)
-	RET
-
-	// save g
-	MOVW g, R4
-	MOVW g, 20(R13)
-
-	// g = m->signal
-	MOVW m_gsignal(m), g
-
-	// R0 is already saved
-	MOVW R1, 8(R13) // info
-	MOVW R2, 12(R13) // context
-	MOVW R4, 16(R13) // gp
-
-	BL runtime·sighandler(SB)
-
-	// restore g
-	MOVW 20(R13), g
-	RET
-
-TEXT runtime·mmap(SB),NOSPLIT,$12
-	MOVW 0(FP), R0	// arg 1 - addr
-	MOVW 4(FP), R1	// arg 2 - len
-	MOVW 8(FP), R2	// arg 3 - prot
-	MOVW 12(FP), R3	// arg 4 - flags
-	// arg 5 (fid) and arg6 (offset_lo, offset_hi) are passed on stack
-	// note the C runtime only passes the 32-bit offset_lo to us
-	MOVW 16(FP), R4		// arg 5
-	MOVW R4, 4(R13)
-	MOVW 20(FP), R5		// arg 6 lower 32-bit
-	MOVW R5, 8(R13)
-	MOVW $0, R6 // higher 32-bit for arg 6
-	MOVW R6, 12(R13)
-	ADD $4, R13 // pass arg 5 and arg 6 on stack
-	SWI $0xa000c5	// sys_mmap
-	SUB $4, R13
-	RET
-
-TEXT runtime·munmap(SB),NOSPLIT,$0
-	MOVW 0(FP), R0	// arg 1 - addr
-	MOVW 4(FP), R1	// arg 2 - len
-	SWI $0xa00049	// sys_munmap
-	MOVW.CS $0, R8	// crash on syscall failure
-	MOVW.CS R8, (R8)
-	RET
-
-TEXT runtime·madvise(SB),NOSPLIT,$0
-	MOVW 0(FP), R0	// arg 1 - addr
-	MOVW 4(FP), R1	// arg 2 - len
-	MOVW 8(FP), R2	// arg 3 - behav
-	SWI $0xa0004b	// sys_madvise
-	// ignore failure - maybe pages are locked
-	RET
-
-TEXT runtime·sigaltstack(SB),NOSPLIT,$-4
-	MOVW 0(FP), R0	// arg 1 - nss
-	MOVW 4(FP), R1	// arg 2 - oss
-	SWI $0xa00119	// sys___sigaltstack14
-	MOVW.CS $0, R8	// crash on syscall failure
-	MOVW.CS R8, (R8)
-	RET
-
-TEXT runtime·sysctl(SB),NOSPLIT,$8
-	MOVW 0(FP), R0	// arg 1 - name
-	MOVW 4(FP), R1	// arg 2 - namelen
-	MOVW 8(FP), R2	// arg 3 - oldp
-	MOVW 12(FP), R3	// arg 4 - oldlenp
-	MOVW 16(FP), R4	// arg 5 - newp
-	MOVW R4, 4(R13)
-	MOVW 20(FP), R4	// arg 6 - newlen
-	MOVW R4, 8(R13)
-	ADD $4, R13	// pass arg 5 and 6 on stack
-	SWI $0xa000ca	// sys___sysctl
-	SUB $4, R13
-	RET
-
-// int32 runtime·kqueue(void)
-TEXT runtime·kqueue(SB),NOSPLIT,$0
-	SWI $0xa00158	// sys_kqueue
-	RSB.CS $0, R0
-	RET
-
-// int32 runtime·kevent(int kq, Kevent *changelist, int nchanges, Kevent *eventlist, int nevents, Timespec *timeout)
-TEXT runtime·kevent(SB),NOSPLIT,$8
-	MOVW 0(FP), R0	// kq
-	MOVW 4(FP), R1	// changelist
-	MOVW 8(FP), R2	// nchanges
-	MOVW 12(FP), R3	// eventlist
-	MOVW 16(FP), R4	// nevents
-	MOVW R4, 4(R13)
-	MOVW 20(FP), R4	// timeout
-	MOVW R4, 8(R13)
-	ADD $4, R13	// pass arg 5 and 6 on stack
-	SWI $0xa001b3	// sys___kevent50
-	RSB.CS $0, R0
-	SUB $4, R13
-	RET
-
-// void runtime·closeonexec(int32 fd)
-TEXT runtime·closeonexec(SB),NOSPLIT,$0
-	MOVW 0(FP), R0	// fd
-	MOVW $2, R1	// F_SETFD
-	MOVW $1, R2	// FD_CLOEXEC
-	SWI $0xa0005c	// sys_fcntl
-	RET
-
-TEXT runtime·casp(SB),NOSPLIT,$0
-	B	runtime·cas(SB)
-
-// TODO(minux): this is only valid for ARMv6+
-// bool armcas(int32 *val, int32 old, int32 new)
-// Atomically:
-//	if(*val == old){
-//		*val = new;
-//		return 1;
-//	}else
-//		return 0;
-TEXT runtime·cas(SB),NOSPLIT,$0
-	B runtime·armcas(SB)
-
-TEXT runtime·read_tls_fallback(SB),NOSPLIT,$-4
-	MOVM.WP [R1, R2, R3, R12], (R13)
-	SWI $0x00a0013c // _lwp_getprivate
-	MOVM.IAW    (R13), [R1, R2, R3, R12]
-	RET
diff --git a/src/pkg/runtime/sys_openbsd_386.s b/src/pkg/runtime/sys_openbsd_386.s
deleted file mode 100644
index 8f0da5c..0000000
--- a/src/pkg/runtime/sys_openbsd_386.s
+++ /dev/null
@@ -1,390 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-//
-// System calls and other sys.stuff for 386, OpenBSD
-// /usr/src/sys/kern/syscalls.master for syscall numbers.
-//
-
-#include "zasm_GOOS_GOARCH.h"
-#include "../../cmd/ld/textflag.h"
-
-#define	CLOCK_MONOTONIC	$3
-
-// Exit the entire program (like C exit)
-TEXT runtime·exit(SB),NOSPLIT,$-4
-	MOVL	$1, AX
-	INT	$0x80
-	MOVL	$0xf1, 0xf1		// crash
-	RET
-
-TEXT runtime·exit1(SB),NOSPLIT,$8
-	MOVL	$0, 0(SP)
-	MOVL	$0, 4(SP)		// arg 1 - notdead
-	MOVL	$302, AX		// sys___threxit
-	INT	$0x80
-	JAE	2(PC)
-	MOVL	$0xf1, 0xf1		// crash
-	RET
-
-TEXT runtime·open(SB),NOSPLIT,$-4
-	MOVL	$5, AX
-	INT	$0x80
-	RET
-
-TEXT runtime·close(SB),NOSPLIT,$-4
-	MOVL	$6, AX
-	INT	$0x80
-	RET
-
-TEXT runtime·read(SB),NOSPLIT,$-4
-	MOVL	$3, AX
-	INT	$0x80
-	RET
-
-TEXT runtime·write(SB),NOSPLIT,$-4
-	MOVL	$4, AX			// sys_write
-	INT	$0x80
-	RET
-
-TEXT runtime·usleep(SB),NOSPLIT,$24
-	MOVL	$0, DX
-	MOVL	usec+0(FP), AX
-	MOVL	$1000000, CX
-	DIVL	CX
-	MOVL	AX, 12(SP)		// tv_sec - l32
-	MOVL	$0, 16(SP)		// tv_sec - h32
-	MOVL	$1000, AX
-	MULL	DX
-	MOVL	AX, 20(SP)		// tv_nsec
-
-	MOVL	$0, 0(SP)
-	LEAL	12(SP), AX
-	MOVL	AX, 4(SP)		// arg 1 - rqtp
-	MOVL	$0, 8(SP)		// arg 2 - rmtp
-	MOVL	$91, AX			// sys_nanosleep
-	INT	$0x80
-	RET
-
-TEXT runtime·raise(SB),NOSPLIT,$12
-	MOVL	$299, AX		// sys_getthrid
-	INT	$0x80
-	MOVL	$0, 0(SP)
-	MOVL	AX, 4(SP)		// arg 1 - pid
-	MOVL	sig+0(FP), AX
-	MOVL	AX, 8(SP)		// arg 2 - signum
-	MOVL	$37, AX			// sys_kill
-	INT	$0x80
-	RET
-
-TEXT runtime·mmap(SB),NOSPLIT,$36
-	LEAL	arg0+0(FP), SI
-	LEAL	4(SP), DI
-	CLD
-	MOVSL				// arg 1 - addr
-	MOVSL				// arg 2 - len
-	MOVSL				// arg 3 - prot
-	MOVSL				// arg 4 - flags
-	MOVSL				// arg 5 - fd
-	MOVL	$0, AX
-	STOSL				// arg 6 - pad
-	MOVSL				// arg 7 - offset
-	MOVL	$0, AX			// top 32 bits of file offset
-	STOSL
-	MOVL	$197, AX		// sys_mmap
-	INT	$0x80
-	RET
-
-TEXT runtime·munmap(SB),NOSPLIT,$-4
-	MOVL	$73, AX			// sys_munmap
-	INT	$0x80
-	JAE	2(PC)
-	MOVL	$0xf1, 0xf1		// crash
-	RET
-
-TEXT runtime·madvise(SB),NOSPLIT,$-4
-	MOVL	$75, AX			// sys_madvise
-	INT	$0x80
-	JAE	2(PC)
-	MOVL	$0xf1, 0xf1		// crash
-	RET
-
-TEXT runtime·setitimer(SB),NOSPLIT,$-4
-	MOVL	$69, AX
-	INT	$0x80
-	RET
-
-// func now() (sec int64, nsec int32)
-TEXT time·now(SB), NOSPLIT, $32
-	LEAL	12(SP), BX
-	MOVL	$0, 4(SP)		// arg 1 - clock_id
-	MOVL	BX, 8(SP)		// arg 2 - tp
-	MOVL	$87, AX			// sys_clock_gettime
-	INT	$0x80
-
-	MOVL	12(SP), AX		// sec - l32
-	MOVL	AX, sec+0(FP)
-	MOVL	16(SP), AX		// sec - h32
-	MOVL	AX, sec+4(FP)
-
-	MOVL	20(SP), BX		// nsec
-	MOVL	BX, nsec+8(FP)
-	RET
-
-// int64 nanotime(void) so really
-// void nanotime(int64 *nsec)
-TEXT runtime·nanotime(SB),NOSPLIT,$32
-	LEAL	12(SP), BX
-	MOVL	CLOCK_MONOTONIC, 4(SP)	// arg 1 - clock_id
-	MOVL	BX, 8(SP)		// arg 2 - tp
-	MOVL	$87, AX			// sys_clock_gettime
-	INT	$0x80
-
-	MOVL    16(SP), CX		// sec - h32
-	IMULL   $1000000000, CX
-
-	MOVL    12(SP), AX		// sec - l32
-	MOVL    $1000000000, BX
-	MULL    BX			// result in dx:ax
-
-	MOVL	20(SP), BX		// nsec
-	ADDL	BX, AX
-	ADCL	CX, DX			// add high bits with carry
-
-	MOVL	ret+0(FP), DI
-	MOVL	AX, 0(DI)
-	MOVL	DX, 4(DI)
-	RET
-
-TEXT runtime·sigaction(SB),NOSPLIT,$-4
-	MOVL	$46, AX			// sys_sigaction
-	INT	$0x80
-	JAE	2(PC)
-	MOVL	$0xf1, 0xf1		// crash
-	RET
-
-TEXT runtime·sigprocmask(SB),NOSPLIT,$-4
-	MOVL	$48, AX			// sys_sigprocmask
-	INT	$0x80
-	JAE	2(PC)
-	MOVL	$0xf1, 0xf1		// crash
-	MOVL	AX, oset+0(FP)
-	RET
-
-TEXT runtime·sigtramp(SB),NOSPLIT,$44
-	get_tls(CX)
-
-	// check that m exists
-	MOVL	m(CX), BX
-	CMPL	BX, $0
-	JNE	6(PC)
-	MOVL	signo+0(FP), BX
-	MOVL	BX, 0(SP)
-	MOVL	$runtime·badsignal(SB), AX
-	CALL	AX
-	JMP 	sigtramp_ret
-
-	// save g
-	MOVL	g(CX), DI
-	MOVL	DI, 20(SP)
-	
-	// g = m->gsignal
-	MOVL	m_gsignal(BX), BX
-	MOVL	BX, g(CX)
-
-	// copy arguments for call to sighandler
-	MOVL	signo+0(FP), BX
-	MOVL	BX, 0(SP)
-	MOVL	info+4(FP), BX
-	MOVL	BX, 4(SP)
-	MOVL	context+8(FP), BX
-	MOVL	BX, 8(SP)
-	MOVL	DI, 12(SP)
-
-	CALL	runtime·sighandler(SB)
-
-	// restore g
-	get_tls(CX)
-	MOVL	20(SP), BX
-	MOVL	BX, g(CX)
-
-sigtramp_ret:
-	// call sigreturn
-	MOVL	context+8(FP), AX
-	MOVL	$0, 0(SP)		// syscall gap
-	MOVL	AX, 4(SP)		// arg 1 - sigcontext
-	MOVL	$103, AX		// sys_sigreturn
-	INT	$0x80
-	MOVL	$0xf1, 0xf1		// crash
-	RET
-
-// int32 tfork(void *param, uintptr psize, M *mp, G *gp, void (*fn)(void));
-TEXT runtime·tfork(SB),NOSPLIT,$12
-
-	// Copy mp, gp and fn from the parent stack onto the child stack.
-	MOVL	params+4(FP), AX
-	MOVL	8(AX), CX		// tf_stack
-	SUBL	$16, CX
-	MOVL	CX, 8(AX)
-	MOVL	mm+12(FP), SI
-	MOVL	SI, 0(CX)
-	MOVL	gg+16(FP), SI
-	MOVL	SI, 4(CX)
-	MOVL	fn+20(FP), SI
-	MOVL	SI, 8(CX)
-	MOVL	$1234, 12(CX)
-
-	MOVL	$0, 0(SP)		// syscall gap
-	MOVL	params+4(FP), AX
-	MOVL	AX, 4(SP)		// arg 1 - param
-	MOVL	psize+8(FP), AX
-	MOVL	AX, 8(SP)		// arg 2 - psize
-	MOVL	$8, AX			// sys___tfork
-	INT	$0x80
-
-	// Return if tfork syscall failed.
-	JCC	5(PC)
-	NEGL	AX
-	MOVL	ret+0(FP), DX
-	MOVL	AX, 0(DX)
-	RET
-
-	// In parent, return.
-	CMPL	AX, $0
-	JEQ	4(PC)
-	MOVL	ret+0(FP), DX
-	MOVL	AX, 0(DX)
-	RET
-
-	// Paranoia: check that SP is as we expect.
-	MOVL	12(SP), BP
-	CMPL	BP, $1234
-	JEQ	2(PC)
-	INT	$3
-
-	// Reload registers.
-	MOVL	0(SP), BX		// m
-	MOVL	4(SP), DX		// g
-	MOVL	8(SP), SI		// fn
-
-	// Set FS to point at m->tls.
-	LEAL	m_tls(BX), BP
-	PUSHAL				// save registers
-	PUSHL	BP
-	CALL	runtime·settls(SB)
-	POPL	AX
-	POPAL
-	
-	// Now segment is established.  Initialize m, g.
-	get_tls(AX)
-	MOVL	DX, g(AX)
-	MOVL	BX, m(AX)
-
-	CALL	runtime·stackcheck(SB)	// smashes AX, CX
-	MOVL	0(DX), DX		// paranoia; check they are not nil
-	MOVL	0(BX), BX
-
-	// More paranoia; check that stack splitting code works.
-	PUSHAL
-	CALL	runtime·emptyfunc(SB)
-	POPAL
-
-	// Call fn.
-	CALL	SI
-
-	CALL	runtime·exit1(SB)
-	MOVL	$0x1234, 0x1005
-	RET
-
-TEXT runtime·sigaltstack(SB),NOSPLIT,$-8
-	MOVL	$288, AX		// sys_sigaltstack
-	MOVL	new+4(SP), BX
-	MOVL	old+8(SP), CX
-	INT	$0x80
-	CMPL	AX, $0xfffff001
-	JLS	2(PC)
-	INT	$3
-	RET
-
-TEXT runtime·setldt(SB),NOSPLIT,$4
-	// Under OpenBSD we set the GS base instead of messing with the LDT.
-	MOVL	tls0+4(FP), AX
-	MOVL	AX, 0(SP)
-	CALL	runtime·settls(SB)
-	RET
-
-TEXT runtime·settls(SB),NOSPLIT,$8
-	// adjust for ELF: wants to use -8(GS) and -4(GS) for g and m
-	MOVL	tlsbase+0(FP), CX
-	ADDL	$8, CX
-	MOVL	$0, 0(SP)		// syscall gap
-	MOVL	CX, 4(SP)		// arg 1 - tcb
-	MOVL	$329, AX		// sys___set_tcb
-	INT	$0x80
-	JCC	2(PC)
-	MOVL	$0xf1, 0xf1		// crash
-	RET
-
-TEXT runtime·osyield(SB),NOSPLIT,$-4
-	MOVL	$298, AX		// sys_sched_yield
-	INT	$0x80
-	RET
-
-TEXT runtime·thrsleep(SB),NOSPLIT,$-4
-	MOVL	$94, AX			// sys___thrsleep
-	INT	$0x80
-	RET
-
-TEXT runtime·thrwakeup(SB),NOSPLIT,$-4
-	MOVL	$301, AX		// sys___thrwakeup
-	INT	$0x80
-	RET
-
-TEXT runtime·sysctl(SB),NOSPLIT,$28
-	LEAL	arg0+0(FP), SI
-	LEAL	4(SP), DI
-	CLD
-	MOVSL				// arg 1 - name
-	MOVSL				// arg 2 - namelen
-	MOVSL				// arg 3 - oldp
-	MOVSL				// arg 4 - oldlenp
-	MOVSL				// arg 5 - newp
-	MOVSL				// arg 6 - newlen
-	MOVL	$202, AX		// sys___sysctl
-	INT	$0x80
-	JCC	3(PC)
-	NEGL	AX
-	RET
-	MOVL	$0, AX
-	RET
-
-// int32 runtime·kqueue(void);
-TEXT runtime·kqueue(SB),NOSPLIT,$0
-	MOVL	$269, AX
-	INT	$0x80
-	JAE	2(PC)
-	NEGL	AX
-	RET
-
-// int32 runtime·kevent(int kq, Kevent *changelist, int nchanges, Kevent *eventlist, int nevents, Timespec *timeout);
-TEXT runtime·kevent(SB),NOSPLIT,$0
-	MOVL	$72, AX			// sys_kevent
-	INT	$0x80
-	JAE	2(PC)
-	NEGL	AX
-	RET
-
-// int32 runtime·closeonexec(int32 fd);
-TEXT runtime·closeonexec(SB),NOSPLIT,$32
-	MOVL	$92, AX			// sys_fcntl
-	// 0(SP) is where the caller PC would be; kernel skips it
-	MOVL	fd+0(FP), BX
-	MOVL	BX, 4(SP)	// fd
-	MOVL	$2, 8(SP)	// F_SETFD
-	MOVL	$1, 12(SP)	// FD_CLOEXEC
-	INT	$0x80
-	JAE	2(PC)
-	NEGL	AX
-	RET
-
-GLOBL runtime·tlsoffset(SB),$4
diff --git a/src/pkg/runtime/sys_openbsd_amd64.s b/src/pkg/runtime/sys_openbsd_amd64.s
deleted file mode 100644
index b2a6182..0000000
--- a/src/pkg/runtime/sys_openbsd_amd64.s
+++ /dev/null
@@ -1,336 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-//
-// System calls and other sys.stuff for AMD64, OpenBSD
-// /usr/src/sys/kern/syscalls.master for syscall numbers.
-//
-
-#include "zasm_GOOS_GOARCH.h"
-#include "../../cmd/ld/textflag.h"
-
-#define CLOCK_MONOTONIC	$3
-
-// int64 tfork(void *param, uintptr psize, M *mp, G *gp, void (*fn)(void));
-TEXT runtime·tfork(SB),NOSPLIT,$32
-
-	// Copy mp, gp and fn off parent stack for use by child.
-	MOVQ	mm+16(FP), R8
-	MOVQ	gg+24(FP), R9
-	MOVQ	fn+32(FP), R12
-
-	MOVQ	param+0(FP), DI
-	MOVQ	psize+8(FP), SI
-	MOVL	$8, AX			// sys___tfork
-	SYSCALL
-
-	// Return if tfork syscall failed.
-	JCC	3(PC)
-	NEGQ	AX
-	RET
-
-	// In parent, return.
-	CMPL	AX, $0
-	JEQ	2(PC)
-	RET
-
-	// Set FS to point at m->tls.
-	LEAQ	m_tls(R8), DI
-	CALL	runtime·settls(SB)
-
-	// In child, set up new stack.
-	get_tls(CX)
-	MOVQ	R8, m(CX)
-	MOVQ	R9, g(CX)
-	CALL	runtime·stackcheck(SB)
-
-	// Call fn
-	CALL	R12
-
-	// It shouldn't return.  If it does, exit
-	MOVQ	$0, DI			// arg 1 - notdead
-	MOVL	$302, AX		// sys___threxit
-	SYSCALL
-	JMP	-3(PC)			// keep exiting
-
-TEXT runtime·osyield(SB),NOSPLIT,$0
-	MOVL	$298, AX		// sys_sched_yield
-	SYSCALL
-	RET
-
-TEXT runtime·thrsleep(SB),NOSPLIT,$0
-	MOVQ	8(SP), DI		// arg 1 - ident
-	MOVL	16(SP), SI		// arg 2 - clock_id
-	MOVQ	24(SP), DX		// arg 3 - tp
-	MOVQ	32(SP), R10		// arg 4 - lock
-	MOVQ	40(SP), R8		// arg 5 - abort
-	MOVL	$94, AX			// sys___thrsleep
-	SYSCALL
-	RET
-
-TEXT runtime·thrwakeup(SB),NOSPLIT,$0
-	MOVQ	8(SP), DI		// arg 1 - ident
-	MOVL	16(SP), SI		// arg 2 - n
-	MOVL	$301, AX		// sys___thrwakeup
-	SYSCALL
-	RET
-
-// Exit the entire program (like C exit)
-TEXT runtime·exit(SB),NOSPLIT,$-8
-	MOVL	8(SP), DI		// arg 1 - exit status
-	MOVL	$1, AX			// sys_exit
-	SYSCALL
-	MOVL	$0xf1, 0xf1		// crash
-	RET
-
-TEXT runtime·exit1(SB),NOSPLIT,$-8
-	MOVQ	$0, DI			// arg 1 - notdead
-	MOVL	$302, AX		// sys___threxit
-	SYSCALL
-	MOVL	$0xf1, 0xf1		// crash
-	RET
-
-TEXT runtime·open(SB),NOSPLIT,$-8
-	MOVQ	8(SP), DI		// arg 1 pathname
-	MOVL	16(SP), SI		// arg 2 flags
-	MOVL	20(SP), DX		// arg 3 mode
-	MOVL	$5, AX
-	SYSCALL
-	RET
-
-TEXT runtime·close(SB),NOSPLIT,$-8
-	MOVL	8(SP), DI		// arg 1 fd
-	MOVL	$6, AX
-	SYSCALL
-	RET
-
-TEXT runtime·read(SB),NOSPLIT,$-8
-	MOVL	8(SP), DI		// arg 1 fd
-	MOVQ	16(SP), SI		// arg 2 buf
-	MOVL	24(SP), DX		// arg 3 count
-	MOVL	$3, AX
-	SYSCALL
-	RET
-
-TEXT runtime·write(SB),NOSPLIT,$-8
-	MOVL	8(SP), DI		// arg 1 - fd
-	MOVQ	16(SP), SI		// arg 2 - buf
-	MOVL	24(SP), DX		// arg 3 - nbyte
-	MOVL	$4, AX			// sys_write
-	SYSCALL
-	RET
-
-TEXT runtime·usleep(SB),NOSPLIT,$16
-	MOVL	$0, DX
-	MOVL	usec+0(FP), AX
-	MOVL	$1000000, CX
-	DIVL	CX
-	MOVQ	AX, 0(SP)		// tv_sec
-	MOVL	$1000, AX
-	MULL	DX
-	MOVQ	AX, 8(SP)		// tv_nsec
-
-	MOVQ	SP, DI			// arg 1 - rqtp
-	MOVQ	$0, SI			// arg 2 - rmtp
-	MOVL	$91, AX			// sys_nanosleep
-	SYSCALL
-	RET
-
-TEXT runtime·raise(SB),NOSPLIT,$16
-	MOVL	$299, AX		// sys_getthrid
-	SYSCALL
-	MOVQ	AX, DI			// arg 1 - pid
-	MOVL	sig+0(FP), SI		// arg 2 - signum
-	MOVL	$37, AX			// sys_kill
-	SYSCALL
-	RET
-
-TEXT runtime·setitimer(SB),NOSPLIT,$-8
-	MOVL	8(SP), DI		// arg 1 - which
-	MOVQ	16(SP), SI		// arg 2 - itv
-	MOVQ	24(SP), DX		// arg 3 - oitv
-	MOVL	$69, AX			// sys_setitimer
-	SYSCALL
-	RET
-
-// func now() (sec int64, nsec int32)
-TEXT time·now(SB), NOSPLIT, $32
-	MOVQ	$0, DI			// arg 1 - clock_id
-	LEAQ	8(SP), SI		// arg 2 - tp
-	MOVL	$87, AX			// sys_clock_gettime
-	SYSCALL
-	MOVQ	8(SP), AX		// sec
-	MOVQ	16(SP), DX		// nsec
-
-	// sec is in AX, nsec in DX
-	MOVQ	AX, sec+0(FP)
-	MOVL	DX, nsec+8(FP)
-	RET
-
-TEXT runtime·nanotime(SB),NOSPLIT,$24
-	MOVQ	CLOCK_MONOTONIC, DI	// arg 1 - clock_id
-	LEAQ	8(SP), SI		// arg 2 - tp
-	MOVL	$87, AX			// sys_clock_gettime
-	SYSCALL
-	MOVQ	8(SP), AX		// sec
-	MOVQ	16(SP), DX		// nsec
-
-	// sec is in AX, nsec in DX
-	// return nsec in AX
-	IMULQ	$1000000000, AX
-	ADDQ	DX, AX
-	RET
-
-TEXT runtime·sigaction(SB),NOSPLIT,$-8
-	MOVL	8(SP), DI		// arg 1 - signum
-	MOVQ	16(SP), SI		// arg 2 - nsa
-	MOVQ	24(SP), DX		// arg 3 - osa
-	MOVL	$46, AX
-	SYSCALL
-	JCC	2(PC)
-	MOVL	$0xf1, 0xf1		// crash
-	RET
-
-TEXT runtime·sigprocmask(SB),NOSPLIT,$0
-	MOVL	8(SP), DI		// arg 1 - how
-	MOVL	12(SP), SI		// arg 2 - set
-	MOVL	$48, AX			// sys_sigprocmask
-	SYSCALL
-	JCC	2(PC)
-	MOVL	$0xf1, 0xf1		// crash
-	MOVL	AX, oset+0(FP)		// Return oset
-	RET
-
-TEXT runtime·sigtramp(SB),NOSPLIT,$64
-	get_tls(BX)
-	
-	// check that m exists
-	MOVQ	m(BX), BP
-	CMPQ	BP, $0
-	JNE	5(PC)
-	MOVQ	DI, 0(SP)
-	MOVQ	$runtime·badsignal(SB), AX
-	CALL	AX
-	RET
-
-	// save g
-	MOVQ	g(BX), R10
-	MOVQ	R10, 40(SP)
-	
-	// g = m->signal
-	MOVQ	m_gsignal(BP), BP
-	MOVQ	BP, g(BX)
-	
-	MOVQ	DI, 0(SP)
-	MOVQ	SI, 8(SP)
-	MOVQ	DX, 16(SP)
-	MOVQ	R10, 24(SP)
-	
-	CALL	runtime·sighandler(SB)
-
-	// restore g
-	get_tls(BX)
-	MOVQ	40(SP), R10
-	MOVQ	R10, g(BX)
-	RET
-
-TEXT runtime·mmap(SB),NOSPLIT,$0
-	MOVQ	8(SP), DI		// arg 1 - addr
-	MOVQ	16(SP), SI		// arg 2 - len
-	MOVL	24(SP), DX		// arg 3 - prot
-	MOVL	28(SP), R10		// arg 4 - flags
-	MOVL	32(SP), R8		// arg 5 - fd
-	MOVQ	36(SP), R9
-	SUBQ	$16, SP
-	MOVQ	R9, 8(SP)		// arg 7 - offset (passed on stack)
-	MOVQ	$0, R9			// arg 6 - pad
-	MOVL	$197, AX
-	SYSCALL
-	ADDQ	$16, SP
-	RET
-
-TEXT runtime·munmap(SB),NOSPLIT,$0
-	MOVQ	8(SP), DI		// arg 1 - addr
-	MOVQ	16(SP), SI		// arg 2 - len
-	MOVL	$73, AX			// sys_munmap
-	SYSCALL
-	JCC	2(PC)
-	MOVL	$0xf1, 0xf1		// crash
-	RET
-
-TEXT runtime·madvise(SB),NOSPLIT,$0
-	MOVQ	addr+0(FP), DI		// arg 1 - addr
-	MOVQ	len+8(FP), SI		// arg 2 - len
-	MOVQ	behav+16(FP), DX	// arg 3 - behav
-	MOVQ	$75, AX			// sys_madvise
-	SYSCALL
-	// ignore failure - maybe pages are locked
-	RET
-
-TEXT runtime·sigaltstack(SB),NOSPLIT,$-8
-	MOVQ	new+8(SP), DI		// arg 1 - nss
-	MOVQ	old+16(SP), SI		// arg 2 - oss
-	MOVQ	$288, AX		// sys_sigaltstack
-	SYSCALL
-	JCC	2(PC)
-	MOVL	$0xf1, 0xf1		// crash
-	RET
-
-// set tls base to DI
-TEXT runtime·settls(SB),NOSPLIT,$0
-	// adjust for ELF: wants to use -16(FS) and -8(FS) for g and m
-	ADDQ	$16, DI
-	MOVQ	$329, AX		// sys___settcb
-	SYSCALL
-	JCC	2(PC)
-	MOVL	$0xf1, 0xf1		// crash
-	RET
-
-TEXT runtime·sysctl(SB),NOSPLIT,$0
-	MOVQ	8(SP), DI		// arg 1 - name
-	MOVL	16(SP), SI		// arg 2 - namelen
-	MOVQ	24(SP), DX		// arg 3 - oldp
-	MOVQ	32(SP), R10		// arg 4 - oldlenp
-	MOVQ	40(SP), R8		// arg 5 - newp
-	MOVQ	48(SP), R9		// arg 6 - newlen
-	MOVQ	$202, AX		// sys___sysctl
-	SYSCALL
-	JCC	3(PC)
-	NEGQ	AX
-	RET
-	MOVL	$0, AX
-	RET
-
-// int32 runtime·kqueue(void);
-TEXT runtime·kqueue(SB),NOSPLIT,$0
-	MOVQ	$0, DI
-	MOVQ	$0, SI
-	MOVQ	$0, DX
-	MOVL	$269, AX
-	SYSCALL
-	JCC	2(PC)
-	NEGQ	AX
-	RET
-
-// int32 runtime·kevent(int kq, Kevent *changelist, int nchanges, Kevent *eventlist, int nevents, Timespec *timeout);
-TEXT runtime·kevent(SB),NOSPLIT,$0
-	MOVL	8(SP), DI
-	MOVQ	16(SP), SI
-	MOVL	24(SP), DX
-	MOVQ	32(SP), R10
-	MOVL	40(SP), R8
-	MOVQ	48(SP), R9
-	MOVL	$72, AX
-	SYSCALL
-	JCC	2(PC)
-	NEGQ	AX
-	RET
-
-// void runtime·closeonexec(int32 fd);
-TEXT runtime·closeonexec(SB),NOSPLIT,$0
-	MOVL	8(SP), DI	// fd
-	MOVQ	$2, SI		// F_SETFD
-	MOVQ	$1, DX		// FD_CLOEXEC
-	MOVL	$92, AX		// fcntl
-	SYSCALL
-	RET
diff --git a/src/pkg/runtime/sys_plan9_386.s b/src/pkg/runtime/sys_plan9_386.s
deleted file mode 100644
index 143cd2e..0000000
--- a/src/pkg/runtime/sys_plan9_386.s
+++ /dev/null
@@ -1,199 +0,0 @@
-// Copyright 2010 The Go 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 "zasm_GOOS_GOARCH.h"
-#include "../../cmd/ld/textflag.h"
-
-// setldt(int entry, int address, int limit)
-TEXT runtime·setldt(SB),NOSPLIT,$0
-	RET
-
-TEXT runtime·open(SB),NOSPLIT,$0
-	MOVL    $14, AX
-	INT     $64
-	RET
-
-TEXT runtime·pread(SB),NOSPLIT,$0
-	MOVL    $50, AX
-	INT     $64
-	RET
-
-TEXT runtime·pwrite(SB),NOSPLIT,$0
-	MOVL    $51, AX
-	INT     $64
-	RET
-
-TEXT runtime·seek(SB),NOSPLIT,$0
-	MOVL	$39, AX
-	INT	$64
-	CMPL	AX, $-1
-	JNE	4(PC)
-	MOVL	a+0(FP), CX
-	MOVL	AX, 0(CX)
-	MOVL	AX, 4(CX)
-	RET
-
-TEXT runtime·close(SB),NOSPLIT,$0
-	MOVL	$4, AX
-	INT	$64
-	RET
-
-TEXT runtime·exits(SB),NOSPLIT,$0
-	MOVL    $8, AX
-	INT     $64
-	RET
-
-TEXT runtime·brk_(SB),NOSPLIT,$0
-	MOVL    $24, AX
-	INT     $64
-	RET
-
-TEXT runtime·sleep(SB),NOSPLIT,$0
-	MOVL    $17, AX
-	INT     $64
-	RET
-
-TEXT runtime·plan9_semacquire(SB),NOSPLIT,$0
-	MOVL	$37, AX
-	INT	$64
-	RET
-
-TEXT runtime·plan9_tsemacquire(SB),NOSPLIT,$0
-	MOVL	$52, AX
-	INT	$64
-	RET
-
-TEXT runtime·notify(SB),NOSPLIT,$0
-	MOVL	$28, AX
-	INT	$64
-	RET
-
-TEXT runtime·noted(SB),NOSPLIT,$0
-	MOVL	$29, AX
-	INT	$64
-	RET
-	
-TEXT runtime·plan9_semrelease(SB),NOSPLIT,$0
-	MOVL	$38, AX
-	INT	$64
-	RET
-	
-TEXT runtime·rfork(SB),NOSPLIT,$0
-	MOVL    $19, AX // rfork
-	MOVL	stack+8(SP), CX
-	MOVL	mm+12(SP), BX	// m
-	MOVL	gg+16(SP), DX	// g
-	MOVL	fn+20(SP), SI	// fn
-	INT     $64
-
-	// In parent, return.
-	CMPL	AX, $0
-	JEQ	2(PC)
-	RET
-
-	// set SP to be on the new child stack
-	MOVL	CX, SP
-
-	// Initialize m, g.
-	get_tls(AX)
-	MOVL	DX, g(AX)
-	MOVL	BX, m(AX)
-
-	// Initialize procid from TOS struct.
-	// TODO: Be explicit and insert a new MOVL _tos(SB), AX here.
-	MOVL	48(AX), AX // procid
-	MOVL	AX, m_procid(BX)	// save pid as m->procid
-	
-	CALL	runtime·stackcheck(SB)	// smashes AX, CX
-	
-	MOVL	0(DX), DX	// paranoia; check they are not nil
-	MOVL	0(BX), BX
-	
-	// more paranoia; check that stack splitting code works
-	PUSHL	SI
-	CALL	runtime·emptyfunc(SB)
-	POPL	SI
-	
-	CALL	SI	// fn()
-	CALL	runtime·exit(SB)
-	RET
-
-// void sigtramp(void *ureg, int8 *note)
-TEXT runtime·sigtramp(SB),NOSPLIT,$0
-	get_tls(AX)
-
-	// check that m exists
-	MOVL	m(AX), BX
-	CMPL	BX, $0
-	JNE	3(PC)
-	CALL	runtime·badsignal2(SB) // will exit
-	RET
-
-	// save args
-	MOVL	ureg+4(SP), CX
-	MOVL	note+8(SP), DX
-
-	// change stack
-	MOVL	m_gsignal(BX), BP
-	MOVL	g_stackbase(BP), BP
-	MOVL	BP, SP
-
-	// make room for args and g
-	SUBL	$16, SP
-
-	// save g
-	MOVL	g(AX), BP
-	MOVL	BP, 12(SP)
-
-	// g = m->gsignal
-	MOVL	m_gsignal(BX), DI
-	MOVL	DI, g(AX)
-
-	// load args and call sighandler
-	MOVL	CX, 0(SP)
-	MOVL	DX, 4(SP)
-	MOVL	BP, 8(SP)
-
-	CALL	runtime·sighandler(SB)
-
-	// restore g
-	get_tls(BX)
-	MOVL	12(SP), BP
-	MOVL	BP, g(BX)
-
-	// call noted(AX)
-	MOVL	AX, 0(SP)
-	CALL	runtime·noted(SB)
-	RET
-
-// Only used by the 64-bit runtime.
-TEXT runtime·setfpmasks(SB),NOSPLIT,$0
-	RET
-
-#define ERRMAX 128	/* from os_plan9.h */
-
-// func errstr() String
-// Only used by package syscall.
-// Grab error string due to a syscall made
-// in entersyscall mode, without going
-// through the allocator (issue 4994).
-// See ../syscall/asm_plan9_386.s:/·Syscall/
-TEXT runtime·errstr(SB),NOSPLIT,$0
-	get_tls(AX)
-	MOVL	m(AX), BX
-	MOVL	m_errstr(BX), CX
-	MOVL	CX, 4(SP)
-	MOVL	$ERRMAX, 8(SP)
-	MOVL	$41, AX
-	INT	$64
-
-	// syscall requires caller-save
-	MOVL	4(SP), CX
-
-	// push the argument
-	PUSHL	CX
-	CALL	runtime·findnull(SB)
-	POPL	CX
-	MOVL	AX, 8(SP)
-	RET
diff --git a/src/pkg/runtime/sys_plan9_amd64.s b/src/pkg/runtime/sys_plan9_amd64.s
deleted file mode 100644
index e60459c..0000000
--- a/src/pkg/runtime/sys_plan9_amd64.s
+++ /dev/null
@@ -1,237 +0,0 @@
-// Copyright 2010 The Go 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 "zasm_GOOS_GOARCH.h"
-#include "../../cmd/ld/textflag.h"
-
-// setldt(int entry, int address, int limit)
-TEXT runtime·setldt(SB),NOSPLIT,$0
-	RET
-
-TEXT runtime·open(SB),NOSPLIT,$0
-	MOVQ	$0x8000, AX
-	MOVQ	$14, BP
-	SYSCALL
-	RET
-
-TEXT runtime·pread(SB),NOSPLIT,$0
-	MOVQ	$0x8000, AX
-	MOVQ	$50, BP
-	SYSCALL
-	RET
-
-TEXT runtime·pwrite(SB),NOSPLIT,$0
-	MOVQ	$0x8000, AX
-	MOVQ	$51, BP
-	SYSCALL
-	RET
-
-// int32 _seek(int64*, int32, int64, int32)
-TEXT _seek<>(SB),NOSPLIT,$0
-	MOVQ	$0x8000, AX
-	MOVQ	$39, BP
-	SYSCALL
-	RET
-
-// int64 seek(int32, int64, int32)
-TEXT runtime·seek(SB),NOSPLIT,$56
-	LEAQ	new+48(SP), CX
-	MOVQ	CX, 0(SP)
-	MOVQ	fd+0(FP), CX
-	MOVQ	CX, 8(SP)
-	MOVQ	off+8(FP), CX
-	MOVQ	CX, 16(SP)
-	MOVQ	whence+16(FP), CX
-	MOVQ	CX, 24(SP)
-	CALL	_seek<>(SB)
-	CMPL	AX, $0
-	JGE	2(PC)
-	MOVQ	$-1, new+48(SP)
-	MOVQ	new+48(SP), AX
-	RET
-
-TEXT runtime·close(SB),NOSPLIT,$0
-	MOVQ	$0x8000, AX
-	MOVQ	$4, BP
-	SYSCALL
-	RET
-
-TEXT runtime·exits(SB),NOSPLIT,$0
-	MOVQ	$0x8000, AX
-	MOVQ	$8, BP
-	SYSCALL
-	RET
-
-TEXT runtime·brk_(SB),NOSPLIT,$0
-	MOVQ	$0x8000, AX
-	MOVQ	$24, BP
-	SYSCALL
-	RET
-
-TEXT runtime·sleep(SB),NOSPLIT,$0
-	MOVQ	$0x8000, AX
-	MOVQ	$17, BP
-	SYSCALL
-	RET
-
-TEXT runtime·plan9_semacquire(SB),NOSPLIT,$0
-	MOVQ	$0x8000, AX
-	MOVQ	$37, BP
-	SYSCALL
-	RET
-
-TEXT runtime·plan9_tsemacquire(SB),NOSPLIT,$0
-	MOVQ	$0x8000, AX
-	MOVQ	$52, BP
-	SYSCALL
-	RET
-
-TEXT runtime·notify(SB),NOSPLIT,$0
-	MOVQ	$0x8000, AX
-	MOVQ	$28, BP
-	SYSCALL
-	RET
-
-TEXT runtime·noted(SB),NOSPLIT,$0
-	MOVQ	$0x8000, AX
-	MOVQ	$29, BP
-	SYSCALL
-	RET
-	
-TEXT runtime·plan9_semrelease(SB),NOSPLIT,$0
-	MOVQ	$0x8000, AX
-	MOVQ	$38, BP
-	SYSCALL
-	RET
-
-TEXT runtime·nanotime(SB),NOSPLIT,$0
-	MOVQ	$0x8000, AX
-	MOVQ	$60, BP
-	SYSCALL
-	RET
-
-TEXT runtime·rfork(SB),NOSPLIT,$0
-	MOVQ	$0x8000, AX
-	MOVQ	$19, BP // rfork
-	SYSCALL
-
-	// In parent, return.
-	CMPQ	AX, $0
-	JEQ	2(PC)
-	RET
-
-	// In child on forked stack.
-	MOVQ	mm+24(SP), BX	// m
-	MOVQ	gg+32(SP), DX	// g
-	MOVQ	fn+40(SP), SI	// fn
-
-	// set SP to be on the new child stack
-	MOVQ	stack+16(SP), CX
-	MOVQ	CX, SP
-
-	// Initialize m, g.
-	get_tls(AX)
-	MOVQ	DX, g(AX)
-	MOVQ	BX, m(AX)
-
-	// Initialize AX from pid in TLS.
-	MOVQ	0(FS), AX
-	MOVQ	AX, m_procid(BX)	// save pid as m->procid
-	
-	CALL	runtime·stackcheck(SB)	// smashes AX, CX
-	
-	MOVQ	0(DX), DX	// paranoia; check they are not nil
-	MOVQ	0(BX), BX
-	
-	CALL	SI	// fn()
-	CALL	runtime·exit(SB)
-	RET
-
-// This is needed by asm_amd64.s
-TEXT runtime·settls(SB),NOSPLIT,$0
-	RET
-
-// void sigtramp(void *ureg, int8 *note)
-TEXT runtime·sigtramp(SB),NOSPLIT,$0
-	get_tls(AX)
-
-	// check that m exists
-	MOVQ	m(AX), BX
-	CMPQ	BX, $0
-	JNE	3(PC)
-	CALL	runtime·badsignal2(SB) // will exit
-	RET
-
-	// save args
-	MOVQ	ureg+8(SP), CX
-	MOVQ	note+16(SP), DX
-
-	// change stack
-	MOVQ	m_gsignal(BX), R10
-	MOVQ	g_stackbase(R10), BP
-	MOVQ	BP, SP
-
-	// make room for args and g
-	SUBQ	$32, SP
-
-	// save g
-	MOVQ	g(AX), BP
-	MOVQ	BP, 24(SP)
-
-	// g = m->gsignal
-	MOVQ	R10, g(AX)
-
-	// load args and call sighandler
-	MOVQ	CX, 0(SP)
-	MOVQ	DX, 8(SP)
-	MOVQ	BP, 16(SP)
-
-	CALL	runtime·sighandler(SB)
-
-	// restore g
-	get_tls(BX)
-	MOVQ	24(SP), R10
-	MOVQ	R10, g(BX)
-
-	// call noted(AX)
-	MOVQ	AX, 0(SP)
-	CALL	runtime·noted(SB)
-	RET
-
-TEXT runtime·setfpmasks(SB),NOSPLIT,$8
-	STMXCSR	0(SP)
-	MOVL	0(SP), AX
-	ANDL	$~0x3F, AX
-	ORL	$(0x3F<<7), AX
-	MOVL	AX, 0(SP)
-	LDMXCSR	0(SP)
-	RET
-
-#define ERRMAX 128	/* from os_plan9.h */
-
-// func errstr() String
-// Only used by package syscall.
-// Grab error string due to a syscall made
-// in entersyscall mode, without going
-// through the allocator (issue 4994).
-// See ../syscall/asm_plan9_386.s:/·Syscall/
-TEXT runtime·errstr(SB),NOSPLIT,$0
-	get_tls(AX)
-	MOVQ	m(AX), BX
-	MOVQ	m_errstr(BX), CX
-	MOVQ	CX, 8(SP)
-	MOVQ	$ERRMAX, 16(SP)
-	MOVQ	$0x8000, AX
-	MOVQ	$41, BP
-	SYSCALL
-
-	// syscall requires caller-save
-	MOVQ	8(SP), CX
-
-	// push the argument
-	PUSHQ	CX
-	CALL	runtime·findnull(SB)
-	POPQ	CX
-	MOVQ	AX, 16(SP)
-	RET
diff --git a/src/pkg/runtime/sys_solaris_amd64.s b/src/pkg/runtime/sys_solaris_amd64.s
deleted file mode 100644
index 2151769..0000000
--- a/src/pkg/runtime/sys_solaris_amd64.s
+++ /dev/null
@@ -1,267 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-//
-// System calls and other sys.stuff for AMD64, SunOS
-// /usr/include/sys/syscall.h for syscall numbers.
-//
-
-#include "zasm_GOOS_GOARCH.h"
-#include "../../cmd/ld/textflag.h"
-
-// This is needed by asm_amd64.s
-TEXT runtime·settls(SB),NOSPLIT,$8
-	RET
-
-// void libc·miniterrno(void *(*___errno)(void));
-//
-// Set the TLS errno pointer in M.
-//
-// Called using runtime·asmcgocall from os_solaris.c:/minit.
-TEXT runtime·miniterrno(SB),NOSPLIT,$0
-	// asmcgocall will put first argument into DI.
-	CALL	DI	// SysV ABI so returns in AX
-	get_tls(CX)
-	MOVQ	m(CX), BX
-	MOVQ	AX,	m_perrno(BX)
-	RET
-
-// int64 runtime·nanotime1(void);
-//
-// clock_gettime(3c) wrapper because Timespec is too large for
-// runtime·nanotime stack.
-//
-// Called using runtime·sysvicall6 from os_solaris.c:/nanotime.
-TEXT runtime·nanotime1(SB),NOSPLIT,$0
-	// need space for the timespec argument.
-	SUBQ	$64, SP	// 16 bytes will do, but who knows in the future?
-	MOVQ	$3, DI	// CLOCK_REALTIME from <sys/time_impl.h>
-	MOVQ	SP, SI
-	MOVQ	libc·clock_gettime(SB), AX
-	CALL	AX
-	MOVQ	(SP), AX	// tv_sec from struct timespec
-	IMULQ	$1000000000, AX	// multiply into nanoseconds
-	ADDQ	8(SP), AX	// tv_nsec, offset should be stable.
-	ADDQ	$64, SP
-	RET
-
-// pipe(3c) wrapper that returns fds in AX, DX.
-TEXT runtime·pipe1(SB),NOSPLIT,$0
-	SUBQ	$16, SP // 8 bytes will do, but stack has to be 16-byte alligned
-	MOVQ	SP, DI
-	MOVQ	libc·pipe(SB), AX
-	CALL	AX
-	MOVL	0(SP), AX
-	MOVL	4(SP), DX
-	ADDQ	$16, SP
-	RET
-
-// Call a library function with SysV calling conventions.
-// The called function can take a maximum of 6 INTEGER class arguments,
-// see 
-//   Michael Matz, Jan Hubicka, Andreas Jaeger, and Mark Mitchell
-//   System V Application Binary Interface 
-//   AMD64 Architecture Processor Supplement
-// section 3.2.3.
-//
-// Called by runtime·asmcgocall or runtime·cgocall.
-TEXT runtime·asmsysvicall6(SB),NOSPLIT,$0
-	// asmcgocall will put first argument into DI.
-	PUSHQ	DI			// save for later
-	MOVQ	libcall_fn(DI), AX
-	MOVQ	libcall_args(DI), R11
-	MOVQ	libcall_n(DI), R10
-
-	get_tls(CX)
-	MOVQ	m(CX), BX
-	MOVQ	m_perrno(BX), DX
-	CMPQ	DX, $0
-	JEQ	skiperrno1
-	MOVL	$0, 0(DX)
-
-skiperrno1:
-	CMPQ	R11, $0
-	JEQ	skipargs
-	// Load 6 args into correspondent registers.
-	MOVQ	0(R11), DI
-	MOVQ	8(R11), SI
-	MOVQ	16(R11), DX
-	MOVQ	24(R11), CX
-	MOVQ	32(R11), R8
-	MOVQ	40(R11), R9
-skipargs:
-
-	// Call SysV function
-	CALL	AX
-
-	// Return result
-	POPQ	DI
-	MOVQ	AX, libcall_r1(DI)
-	MOVQ	DX, libcall_r2(DI)
-
-	get_tls(CX)
-	MOVQ	m(CX), BX
-	MOVQ	m_perrno(BX), AX
-	CMPQ	AX, $0
-	JEQ	skiperrno2
-	MOVL	0(AX), AX
-	MOVQ	AX, libcall_err(DI)
-
-skiperrno2:	
-	RET
-
-// uint32 tstart_sysvicall(M *newm);
-TEXT runtime·tstart_sysvicall(SB),NOSPLIT,$0
-	// DI contains first arg newm
-	MOVQ	m_g0(DI), DX		// g
-
-	// Make TLS entries point at g and m.
-	get_tls(BX)
-	MOVQ	DX, g(BX)
-	MOVQ	DI, m(BX)
-
-	// Layout new m scheduler stack on os stack.
-	MOVQ	SP, AX
-	MOVQ	AX, g_stackbase(DX)
-	SUBQ	$(0x100000), AX		// stack size
-	MOVQ	AX, g_stackguard(DX)
-	MOVQ	AX, g_stackguard0(DX)
-
-	// Someday the convention will be D is always cleared.
-	CLD
-
-	CALL	runtime·stackcheck(SB)	// clobbers AX,CX
-	CALL	runtime·mstart(SB)
-
-	XORL	AX, AX			// return 0 == success
-	RET
-
-// Careful, this is called by __sighndlr, a libc function. We must preserve
-// registers as per AMD 64 ABI.
-TEXT runtime·sigtramp(SB),NOSPLIT,$0
-	// Note that we are executing on altsigstack here, so we have
-	// more stack available than NOSPLIT would have us believe.
-	// To defeat the linker, we make our own stack frame with
-	// more space:
-	SUBQ    $184, SP
-
-	// save registers
-	MOVQ    BX, 32(SP)
-	MOVQ    BP, 40(SP)
-	MOVQ	R12, 48(SP)
-	MOVQ	R13, 56(SP)
-	MOVQ	R14, 64(SP)
-	MOVQ	R15, 72(SP)
-
-	get_tls(BX)
-	// check that m exists
-	MOVQ	m(BX), BP
-	CMPQ	BP, $0
-	JNE	allgood
-	MOVQ	DI, 0(SP)
-	MOVQ	$runtime·badsignal(SB), AX
-	CALL	AX
-	RET
-
-allgood:
-	// save g
-	MOVQ	g(BX), R10
-	MOVQ	R10, 80(SP)
-
-	// Save m->libcall and m->scratch. We need to do this because we
-	// might get interrupted by a signal in runtime·asmcgocall.
-
-	// save m->libcall 
-	LEAQ	m_libcall(BP), R11
-	MOVQ	libcall_fn(R11), R10
-	MOVQ	R10, 88(SP)
-	MOVQ	libcall_args(R11), R10
-	MOVQ	R10, 96(SP)
-	MOVQ	libcall_n(R11), R10
-	MOVQ	R10, 104(SP)
-	MOVQ    libcall_r1(R11), R10
-	MOVQ    R10, 168(SP)
-	MOVQ    libcall_r2(R11), R10
-	MOVQ    R10, 176(SP)
-
-	// save m->scratch
-	LEAQ	m_scratch(BP), R11
-	MOVQ	0(R11), R10
-	MOVQ	R10, 112(SP)
-	MOVQ	8(R11), R10
-	MOVQ	R10, 120(SP)
-	MOVQ	16(R11), R10
-	MOVQ	R10, 128(SP)
-	MOVQ	24(R11), R10
-	MOVQ	R10, 136(SP)
-	MOVQ	32(R11), R10
-	MOVQ	R10, 144(SP)
-	MOVQ	40(R11), R10
-	MOVQ	R10, 152(SP)
-
-	// save errno, it might be EINTR; stuff we do here might reset it.
-	MOVQ	m_perrno(BP), R10
-	MOVL	0(R10), R10
-	MOVQ	R10, 160(SP)
-
-	MOVQ	g(BX), R10
-	// g = m->gsignal
-	MOVQ	m_gsignal(BP), BP
-	MOVQ	BP, g(BX)
-
-	// prepare call
-	MOVQ	DI, 0(SP)
-	MOVQ	SI, 8(SP)
-	MOVQ	DX, 16(SP)
-	MOVQ	R10, 24(SP)
-	CALL	runtime·sighandler(SB)
-
-	get_tls(BX)
-	MOVQ	m(BX), BP
-	// restore libcall
-	LEAQ	m_libcall(BP), R11
-	MOVQ	88(SP), R10
-	MOVQ	R10, libcall_fn(R11)
-	MOVQ	96(SP), R10
-	MOVQ	R10, libcall_args(R11)
-	MOVQ	104(SP), R10
-	MOVQ	R10, libcall_n(R11)
-	MOVQ    168(SP), R10
-	MOVQ    R10, libcall_r1(R11)
-	MOVQ    176(SP), R10
-	MOVQ    R10, libcall_r2(R11)
-
-	// restore scratch
-	LEAQ	m_scratch(BP), R11
-	MOVQ	112(SP), R10
-	MOVQ	R10, 0(R11)
-	MOVQ	120(SP), R10
-	MOVQ	R10, 8(R11)
-	MOVQ	128(SP), R10
-	MOVQ	R10, 16(R11)
-	MOVQ	136(SP), R10
-	MOVQ	R10, 24(R11)
-	MOVQ	144(SP), R10
-	MOVQ	R10, 32(R11)
-	MOVQ	152(SP), R10
-	MOVQ	R10, 40(R11)
-
-	// restore errno
-	MOVQ	m_perrno(BP), R11
-	MOVQ	160(SP), R10
-	MOVL	R10, 0(R11)
-
-	// restore g
-	MOVQ	80(SP), R10
-	MOVQ	R10, g(BX)
-
-	// restore registers
-	MOVQ	32(SP), BX
-	MOVQ	40(SP), BP
-	MOVQ	48(SP), R12
-	MOVQ	56(SP), R13
-	MOVQ	64(SP), R14
-	MOVQ	72(SP), R15
-
-	ADDQ    $184, SP
-	RET
diff --git a/src/pkg/runtime/sys_windows_386.s b/src/pkg/runtime/sys_windows_386.s
deleted file mode 100644
index 576831d..0000000
--- a/src/pkg/runtime/sys_windows_386.s
+++ /dev/null
@@ -1,363 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "zasm_GOOS_GOARCH.h"
-#include "../../cmd/ld/textflag.h"
-
-// void runtime·asmstdcall(void *c);
-TEXT runtime·asmstdcall(SB),NOSPLIT,$0
-	MOVL	c+0(FP), BX
-
-	// SetLastError(0).
-	MOVL	$0, 0x34(FS)
-
-	// Copy args to the stack.
-	MOVL	SP, BP
-	MOVL	libcall_n(BX), CX	// words
-	MOVL	CX, AX
-	SALL	$2, AX
-	SUBL	AX, SP			// room for args
-	MOVL	SP, DI
-	MOVL	libcall_args(BX), SI
-	CLD
-	REP; MOVSL
-
-	// Call stdcall or cdecl function.
-	// DI SI BP BX are preserved, SP is not
-	CALL	libcall_fn(BX)
-	MOVL	BP, SP
-
-	// Return result.
-	MOVL	c+0(FP), BX
-	MOVL	AX, libcall_r1(BX)
-	MOVL	DX, libcall_r2(BX)
-
-	// GetLastError().
-	MOVL	0x34(FS), AX
-	MOVL	AX, libcall_err(BX)
-
-	RET
-
-TEXT	runtime·badsignal2(SB),NOSPLIT,$24
-	// stderr
-	MOVL	$-12, 0(SP)
-	MOVL	SP, BP
-	CALL	*runtime·GetStdHandle(SB)
-	MOVL	BP, SP
-
-	MOVL	AX, 0(SP)	// handle
-	MOVL	$runtime·badsignalmsg(SB), DX // pointer
-	MOVL	DX, 4(SP)
-	MOVL	runtime·badsignallen(SB), DX // count
-	MOVL	DX, 8(SP)
-	LEAL	20(SP), DX  // written count
-	MOVL	$0, 0(DX)
-	MOVL	DX, 12(SP)
-	MOVL	$0, 16(SP) // overlapped
-	CALL	*runtime·WriteFile(SB)
-	MOVL	BP, SI
-	RET
-
-// faster get/set last error
-TEXT runtime·getlasterror(SB),NOSPLIT,$0
-	MOVL	0x34(FS), AX
-	RET
-
-TEXT runtime·setlasterror(SB),NOSPLIT,$0
-	MOVL	err+0(FP), AX
-	MOVL	AX, 0x34(FS)
-	RET
-
-// Called by Windows as a Vectored Exception Handler (VEH).
-// First argument is pointer to struct containing
-// exception record and context pointers.
-// Return 0 for 'not handled', -1 for handled.
-TEXT runtime·sigtramp(SB),NOSPLIT,$0-0
-	MOVL	ptrs+0(FP), CX
-	SUBL	$28, SP
-
-	// save callee-saved registers
-	MOVL	BX, 12(SP)
-	MOVL	BP, 16(SP)
-	MOVL	SI, 20(SP)
-	MOVL	DI, 24(SP)
-
-	MOVL	0(CX), BX // ExceptionRecord*
-	MOVL	4(CX), CX // Context*
-
-	// fetch g
-	get_tls(DX)
- 	CMPL	DX, $0
- 	JNE	3(PC)
- 	MOVL	$0, AX // continue
- 	JMP	done
-	MOVL	m(DX), AX
-	CMPL	AX, $0
-	JNE	2(PC)
-	CALL	runtime·badsignal2(SB)
-	MOVL	g(DX), DX
-	// call sighandler(ExceptionRecord*, Context*, G*)
-	MOVL	BX, 0(SP)
-	MOVL	CX, 4(SP)
-	MOVL	DX, 8(SP)
-	CALL	runtime·sighandler(SB)
-	// AX is set to report result back to Windows
-
-done:
-	// restore callee-saved registers
-	MOVL	24(SP), DI
-	MOVL	20(SP), SI
-	MOVL	16(SP), BP
-	MOVL	12(SP), BX
-
-	ADDL	$28, SP
-	// RET 4 (return and pop 4 bytes parameters)
-	BYTE $0xC2; WORD $4
-	RET // unreached; make assembler happy
-
-TEXT runtime·ctrlhandler(SB),NOSPLIT,$0
-	PUSHL	$runtime·ctrlhandler1(SB)
-	CALL	runtime·externalthreadhandler(SB)
-	MOVL	4(SP), CX
-	ADDL	$12, SP
-	JMP	CX
-
-TEXT runtime·profileloop(SB),NOSPLIT,$0
-	PUSHL	$runtime·profileloop1(SB)
-	CALL	runtime·externalthreadhandler(SB)
-	MOVL	4(SP), CX
-	ADDL	$12, SP
-	JMP	CX
-
-TEXT runtime·externalthreadhandler(SB),NOSPLIT,$0
-	PUSHL	BP
-	MOVL	SP, BP
-	PUSHL	BX
-	PUSHL	SI
-	PUSHL	DI
-	PUSHL	0x14(FS)
-	MOVL	SP, DX
-
-	// setup dummy m, g
-	SUBL	$m_end, SP		// space for M
-	MOVL	SP, 0(SP)
-	MOVL	$m_end, 4(SP)
-	CALL	runtime·memclr(SB)	// smashes AX,BX,CX
-
-	LEAL	m_tls(SP), CX
-	MOVL	CX, 0x14(FS)
-	MOVL	SP, m(CX)
-	MOVL	SP, BX
-	SUBL	$g_end, SP		// space for G
-	MOVL	SP, g(CX)
-	MOVL	SP, m_g0(BX)
-
-	MOVL	SP, 0(SP)
-	MOVL	$g_end, 4(SP)
-	CALL	runtime·memclr(SB)	// smashes AX,BX,CX
-	LEAL	-4096(SP), CX
-	MOVL	CX, g_stackguard(SP)
-	MOVL	DX, g_stackbase(SP)
-
-	PUSHL	16(BP)			// arg for handler
-	CALL	8(BP)
-	POPL	CX
-
-	get_tls(CX)
-	MOVL	g(CX), CX
-	MOVL	g_stackbase(CX), SP
-	POPL	0x14(FS)
-	POPL	DI
-	POPL	SI
-	POPL	BX
-	POPL	BP
-	RET
-
-GLOBL runtime·cbctxts(SB), $4
-
-TEXT runtime·callbackasm1+0(SB),NOSPLIT,$0
-  	MOVL	0(SP), AX	// will use to find our callback context
-
-	// remove return address from stack, we are not returning there
-	ADDL	$4, SP
-
-	// address to callback parameters into CX
-	LEAL	4(SP), CX
-
-	// save registers as required for windows callback
-	PUSHL	DI
-	PUSHL	SI
-	PUSHL	BP
-	PUSHL	BX
-
-	// determine index into runtime·cbctxts table
-	SUBL	$runtime·callbackasm(SB), AX
-	MOVL	$0, DX
-	MOVL	$5, BX	// divide by 5 because each call instruction in runtime·callbacks is 5 bytes long
-	DIVL	BX,
-
-	// find correspondent runtime·cbctxts table entry
-	MOVL	runtime·cbctxts(SB), BX
-	MOVL	-4(BX)(AX*4), BX
-
-	// extract callback context
-	MOVL	cbctxt_gobody(BX), AX
-	MOVL	cbctxt_argsize(BX), DX
-
-	// preserve whatever's at the memory location that
-	// the callback will use to store the return value
-	PUSHL	0(CX)(DX*1)
-
-	// extend argsize by size of return value
-	ADDL	$4, DX
-
-	// remember how to restore stack on return
-	MOVL	cbctxt_restorestack(BX), BX
-	PUSHL	BX
-
-	// call target Go function
-	PUSHL	DX			// argsize (including return value)
-	PUSHL	CX			// callback parameters
-	PUSHL	AX			// address of target Go function
-	CLD
-	CALL	runtime·cgocallback_gofunc(SB)
-	POPL	AX
-	POPL	CX
-	POPL	DX
-
-	// how to restore stack on return
-	POPL	BX
-
-	// return value into AX (as per Windows spec)
-	// and restore previously preserved value
-	MOVL	-4(CX)(DX*1), AX
-	POPL	-4(CX)(DX*1)
-
-	MOVL	BX, CX			// cannot use BX anymore
-
-	// restore registers as required for windows callback
-	POPL	BX
-	POPL	BP
-	POPL	SI
-	POPL	DI
-
-	// remove callback parameters before return (as per Windows spec)
-	POPL	DX
-	ADDL	CX, SP
-	PUSHL	DX
-
-	CLD
-
-	RET
-
-// void tstart(M *newm);
-TEXT runtime·tstart(SB),NOSPLIT,$0
-	MOVL	newm+4(SP), CX		// m
-	MOVL	m_g0(CX), DX		// g
-
-	// Layout new m scheduler stack on os stack.
-	MOVL	SP, AX
-	MOVL	AX, g_stackbase(DX)
-	SUBL	$(64*1024), AX		// stack size
-	MOVL	AX, g_stackguard(DX)
-
-	// Set up tls.
-	LEAL	m_tls(CX), SI
-	MOVL	SI, 0x14(FS)
-	MOVL	CX, m(SI)
-	MOVL	DX, g(SI)
-
-	// Someday the convention will be D is always cleared.
-	CLD
-
-	CALL	runtime·stackcheck(SB)	// clobbers AX,CX
-	CALL	runtime·mstart(SB)
-
-	RET
-
-// uint32 tstart_stdcall(M *newm);
-TEXT runtime·tstart_stdcall(SB),NOSPLIT,$0
-	MOVL	newm+4(SP), BX
-
-	PUSHL	BX
-	CALL	runtime·tstart(SB)
-	POPL	BX
-
-	// Adjust stack for stdcall to return properly.
-	MOVL	(SP), AX		// save return address
-	ADDL	$4, SP			// remove single parameter
-	MOVL	AX, (SP)		// restore return address
-
-	XORL	AX, AX			// return 0 == success
-
-	RET
-
-// setldt(int entry, int address, int limit)
-TEXT runtime·setldt(SB),NOSPLIT,$0
-	MOVL	address+4(FP), CX
-	MOVL	CX, 0x14(FS)
-	RET
-
-// Sleep duration is in 100ns units.
-TEXT runtime·usleep1(SB),NOSPLIT,$0
-	MOVL	duration+0(FP), BX
-	MOVL	$runtime·usleep2(SB), AX // to hide from 8l
-
-	// Execute call on m->g0 stack, in case we are not actually
-	// calling a system call wrapper, like when running under WINE.
-	get_tls(CX)
-	CMPL	CX, $0
-	JNE	3(PC)
-	// Not a Go-managed thread. Do not switch stack.
-	CALL	AX
-	RET
-
-	MOVL	m(CX), BP
-
-	// leave pc/sp for cpu profiler
-	MOVL	(SP), SI
-	MOVL	SI, m_libcallpc(BP)
-	MOVL	g(CX), SI
-	MOVL	SI, m_libcallg(BP)
-	// sp must be the last, because once async cpu profiler finds
-	// all three values to be non-zero, it will use them
-	LEAL	4(SP), SI
-	MOVL	SI, m_libcallsp(BP)
-
-	MOVL	m_g0(BP), SI
-	CMPL	g(CX), SI
-	JNE	usleep1_switch
-	// executing on m->g0 already
-	CALL	AX
-	JMP	usleep1_ret
-
-usleep1_switch:
-	// Switch to m->g0 stack and back.
-	MOVL	(g_sched+gobuf_sp)(SI), SI
-	MOVL	SP, -4(SI)
-	LEAL	-4(SI), SP
-	CALL	AX
-	MOVL	0(SP), SP
-
-usleep1_ret:
-	get_tls(CX)
-	MOVL	m(CX), BP
-	MOVL	$0, m_libcallsp(BP)
-	RET
-
-// Runs on OS stack. duration (in 100ns units) is in BX.
-TEXT runtime·usleep2(SB),NOSPLIT,$20
-	// Want negative 100ns units.
-	NEGL	BX
-	MOVL	$-1, hi-4(SP)
-	MOVL	BX, lo-8(SP)
-	LEAL	lo-8(SP), BX
-	MOVL	BX, ptime-12(SP)
-	MOVL	$0, alertable-16(SP)
-	MOVL	$-1, handle-20(SP)
-	MOVL	SP, BP
-	MOVL	runtime·NtWaitForSingleObject(SB), AX
-	CALL	AX
-	MOVL	BP, SP
-	RET
diff --git a/src/pkg/runtime/sys_windows_amd64.s b/src/pkg/runtime/sys_windows_amd64.s
deleted file mode 100644
index d161be6..0000000
--- a/src/pkg/runtime/sys_windows_amd64.s
+++ /dev/null
@@ -1,377 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "zasm_GOOS_GOARCH.h"
-#include "../../cmd/ld/textflag.h"
-
-// maxargs should be divisible by 2, as Windows stack
-// must be kept 16-byte aligned on syscall entry.
-#define maxargs 16
-
-// void runtime·asmstdcall(void *c);
-TEXT runtime·asmstdcall(SB),NOSPLIT,$0
-	// asmcgocall will put first argument into CX.
-	PUSHQ	CX			// save for later
-	MOVQ	libcall_fn(CX), AX
-	MOVQ	libcall_args(CX), SI
-	MOVQ	libcall_n(CX), CX
-
-	// SetLastError(0).
-	MOVQ	0x30(GS), DI
-	MOVL	$0, 0x68(DI)
-
-	SUBQ	$(maxargs*8), SP	// room for args
-
-	// Fast version, do not store args on the stack.
-	CMPL	CX, $4
-	JLE	loadregs
-
-	// Check we have enough room for args.
-	CMPL	CX, $maxargs
-	JLE	2(PC)
-	INT	$3			// not enough room -> crash
-
-	// Copy args to the stack.
-	MOVQ	SP, DI
-	CLD
-	REP; MOVSQ
-	MOVQ	SP, SI
-
-loadregs:
-	// Load first 4 args into correspondent registers.
-	MOVQ	0(SI), CX
-	MOVQ	8(SI), DX
-	MOVQ	16(SI), R8
-	MOVQ	24(SI), R9
-
-	// Call stdcall function.
-	CALL	AX
-
-	ADDQ	$(maxargs*8), SP
-
-	// Return result.
-	POPQ	CX
-	MOVQ	AX, libcall_r1(CX)
-
-	// GetLastError().
-	MOVQ	0x30(GS), DI
-	MOVL	0x68(DI), AX
-	MOVQ	AX, libcall_err(CX)
-
-	RET
-
-TEXT runtime·badsignal2(SB),NOSPLIT,$48
-	// stderr
-	MOVQ	$-12, CX // stderr
-	MOVQ	CX, 0(SP)
-	MOVQ	runtime·GetStdHandle(SB), AX
-	CALL	AX
-
-	MOVQ	AX, CX	// handle
-	MOVQ	CX, 0(SP)
-	MOVQ	$runtime·badsignalmsg(SB), DX // pointer
-	MOVQ	DX, 8(SP)
-	MOVL	$runtime·badsignallen(SB), R8 // count
-	MOVQ	R8, 16(SP)
-	LEAQ	40(SP), R9  // written count
-	MOVQ	$0, 0(R9)
-	MOVQ	R9, 24(SP)
-	MOVQ	$0, 32(SP)	// overlapped
-	MOVQ	runtime·WriteFile(SB), AX
-	CALL	AX
-	
-	RET
-
-// faster get/set last error
-TEXT runtime·getlasterror(SB),NOSPLIT,$0
-	MOVQ	0x30(GS), AX
-	MOVL	0x68(AX), AX
-	RET
-
-TEXT runtime·setlasterror(SB),NOSPLIT,$0
-	MOVL	err+0(FP), AX
-	MOVQ	0x30(GS),	CX
-	MOVL	AX, 0x68(CX)
-	RET
-
-// Called by Windows as a Vectored Exception Handler (VEH).
-// First argument is pointer to struct containing
-// exception record and context pointers.
-// Return 0 for 'not handled', -1 for handled.
-TEXT runtime·sigtramp(SB),NOSPLIT,$0-0
-	// CX: PEXCEPTION_POINTERS ExceptionInfo
-
-	// DI SI BP BX R12 R13 R14 R15 registers and DF flag are preserved
-	// as required by windows callback convention.
-	PUSHFQ
-	SUBQ	$88, SP
-	MOVQ	DI, 80(SP)
-	MOVQ	SI, 72(SP)
-	MOVQ	BP, 64(SP)
-	MOVQ	BX, 56(SP)
-	MOVQ	R12, 48(SP)
-	MOVQ	R13, 40(SP)
-	MOVQ	R14, 32(SP)
-	MOVQ	R15, 24(SP)
-
-	MOVQ	0(CX), BX // ExceptionRecord*
-	MOVQ	8(CX), CX // Context*
-
-	// fetch g
-	get_tls(DX)
- 	CMPQ	DX, $0
- 	JNE	3(PC)
- 	MOVQ	$0, AX // continue
- 	JMP	done
-	MOVQ	m(DX), AX
-	CMPQ	AX, $0
-	JNE	2(PC)
-	CALL	runtime·badsignal2(SB)
-	MOVQ	g(DX), DX
-	// call sighandler(ExceptionRecord*, Context*, G*)
-	MOVQ	BX, 0(SP)
-	MOVQ	CX, 8(SP)
-	MOVQ	DX, 16(SP)
-	CALL	runtime·sighandler(SB)
-	// AX is set to report result back to Windows
-
-done:
-	// restore registers as required for windows callback
-	MOVQ	24(SP), R15
-	MOVQ	32(SP), R14
-	MOVQ	40(SP), R13
-	MOVQ	48(SP), R12
-	MOVQ	56(SP), BX
-	MOVQ	64(SP), BP
-	MOVQ	72(SP), SI
-	MOVQ	80(SP), DI
-	ADDQ	$88, SP
-	POPFQ
-
-	RET
-
-TEXT runtime·ctrlhandler(SB),NOSPLIT,$8
-	MOVQ	CX, 16(SP)		// spill
-	MOVQ	$runtime·ctrlhandler1(SB), CX
-	MOVQ	CX, 0(SP)
-	CALL	runtime·externalthreadhandler(SB)
-	RET
-
-TEXT runtime·profileloop(SB),NOSPLIT,$8
-	MOVQ	$runtime·profileloop1(SB), CX
-	MOVQ	CX, 0(SP)
-	CALL	runtime·externalthreadhandler(SB)
-	RET
-
-TEXT runtime·externalthreadhandler(SB),NOSPLIT,$0
-	PUSHQ	BP
-	MOVQ	SP, BP
-	PUSHQ	BX
-	PUSHQ	SI
-	PUSHQ	DI
-	PUSHQ	0x28(GS)
-	MOVQ	SP, DX
-
-	// setup dummy m, g
-	SUBQ	$m_end, SP		// space for M
-	MOVQ	SP, 0(SP)
-	MOVQ	$m_end, 8(SP)
-	CALL	runtime·memclr(SB)	// smashes AX,BX,CX
-
-	LEAQ	m_tls(SP), CX
-	MOVQ	CX, 0x28(GS)
-	MOVQ	SP, m(CX)
-	MOVQ	SP, BX
-	SUBQ	$g_end, SP		// space for G
-	MOVQ	SP, g(CX)
-	MOVQ	SP, m_g0(BX)
-
-	MOVQ	SP, 0(SP)
-	MOVQ	$g_end, 8(SP)
-	CALL	runtime·memclr(SB)	// smashes AX,BX,CX
-	LEAQ	-8192(SP), CX
-	MOVQ	CX, g_stackguard(SP)
-	MOVQ	DX, g_stackbase(SP)
-
-	PUSHQ	32(BP)			// arg for handler
-	CALL	16(BP)
-	POPQ	CX
-
-	get_tls(CX)
-	MOVQ	g(CX), CX
-	MOVQ	g_stackbase(CX), SP
-	POPQ	0x28(GS)
-	POPQ	DI
-	POPQ	SI
-	POPQ	BX
-	POPQ	BP
-	RET
-
-GLOBL runtime·cbctxts(SB), $8
-
-TEXT runtime·callbackasm1(SB),NOSPLIT,$0
-	// Construct args vector for cgocallback().
-	// By windows/amd64 calling convention first 4 args are in CX, DX, R8, R9
-	// args from the 5th on are on the stack.
-	// In any case, even if function has 0,1,2,3,4 args, there is reserved
-	// but uninitialized "shadow space" for the first 4 args.
-	// The values are in registers.
-  	MOVQ	CX, (16+0)(SP)
-  	MOVQ	DX, (16+8)(SP)
-  	MOVQ	R8, (16+16)(SP)
-  	MOVQ	R9, (16+24)(SP)
-
-	// remove return address from stack, we are not returning there
-  	MOVQ	0(SP), AX
-	ADDQ	$8, SP
-
-	// determine index into runtime·cbctxts table
-	SUBQ	$runtime·callbackasm(SB), AX
-	MOVQ	$0, DX
-	MOVQ	$5, CX	// divide by 5 because each call instruction in runtime·callbacks is 5 bytes long
-	DIVL	CX,
-
-	// find correspondent runtime·cbctxts table entry
-	MOVQ	runtime·cbctxts(SB), CX
-	MOVQ	-8(CX)(AX*8), AX
-
-	// extract callback context
-	MOVQ	cbctxt_argsize(AX), DX
-	MOVQ	cbctxt_gobody(AX), AX
-
-	// preserve whatever's at the memory location that
-	// the callback will use to store the return value
-	LEAQ	8(SP), CX       // args vector, skip return address
-	PUSHQ	0(CX)(DX*1)     // store 8 bytes from just after the args array
-	ADDQ	$8, DX          // extend argsize by size of return value
-
-	// DI SI BP BX R12 R13 R14 R15 registers and DF flag are preserved
-	// as required by windows callback convention.
-	PUSHFQ
-	SUBQ	$64, SP
-	MOVQ	DI, 56(SP)
-	MOVQ	SI, 48(SP)
-	MOVQ	BP, 40(SP)
-	MOVQ	BX, 32(SP)
-	MOVQ	R12, 24(SP)
-	MOVQ	R13, 16(SP)
-	MOVQ	R14, 8(SP)
-	MOVQ	R15, 0(SP)
-
-	// prepare call stack.  use SUBQ to hide from stack frame checks
-	// cgocallback(Go func, void *frame, uintptr framesize)
-	SUBQ	$24, SP
-	MOVQ	DX, 16(SP)	// argsize (including return value)
-	MOVQ	CX, 8(SP)	// callback parameters
-	MOVQ	AX, 0(SP)	// address of target Go function
-	CLD
-	CALL	runtime·cgocallback_gofunc(SB)
-	MOVQ	0(SP), AX
-	MOVQ	8(SP), CX
-	MOVQ	16(SP), DX
-	ADDQ	$24, SP
-
-	// restore registers as required for windows callback
-	MOVQ	0(SP), R15
-	MOVQ	8(SP), R14
-	MOVQ	16(SP), R13
-	MOVQ	24(SP), R12
-	MOVQ	32(SP), BX
-	MOVQ	40(SP), BP
-	MOVQ	48(SP), SI
-	MOVQ	56(SP), DI
-	ADDQ	$64, SP
-	POPFQ
-
-	MOVL	-8(CX)(DX*1), AX  // return value
-	POPQ	-8(CX)(DX*1)      // restore bytes just after the args
-	RET
-
-// uint32 tstart_stdcall(M *newm);
-TEXT runtime·tstart_stdcall(SB),NOSPLIT,$0
-	// CX contains first arg newm
-	MOVQ	m_g0(CX), DX		// g
-
-	// Layout new m scheduler stack on os stack.
-	MOVQ	SP, AX
-	MOVQ	AX, g_stackbase(DX)
-	SUBQ	$(64*1024), AX		// stack size
-	MOVQ	AX, g_stackguard(DX)
-
-	// Set up tls.
-	LEAQ	m_tls(CX), SI
-	MOVQ	SI, 0x28(GS)
-	MOVQ	CX, m(SI)
-	MOVQ	DX, g(SI)
-
-	// Someday the convention will be D is always cleared.
-	CLD
-
-	CALL	runtime·stackcheck(SB)	// clobbers AX,CX
-	CALL	runtime·mstart(SB)
-
-	XORL	AX, AX			// return 0 == success
-	RET
-
-// set tls base to DI
-TEXT runtime·settls(SB),NOSPLIT,$0
-	MOVQ	DI, 0x28(GS)
-	RET
-
-// Sleep duration is in 100ns units.
-TEXT runtime·usleep1(SB),NOSPLIT,$0
-	MOVL	duration+0(FP), BX
-	MOVQ	$runtime·usleep2(SB), AX // to hide from 6l
-
-	// Execute call on m->g0 stack, in case we are not actually
-	// calling a system call wrapper, like when running under WINE.
-	get_tls(R15)
-	CMPQ	R15, $0
-	JNE	3(PC)
-	// Not a Go-managed thread. Do not switch stack.
-	CALL	AX
-	RET
-
-	MOVQ	m(R15), R13
-
-	// leave pc/sp for cpu profiler
-	MOVQ	(SP), R12
-	MOVQ	R12, m_libcallpc(R13)
-	MOVQ	g(R15), R12
-	MOVQ	R12, m_libcallg(R13)
-	// sp must be the last, because once async cpu profiler finds
-	// all three values to be non-zero, it will use them
-	LEAQ	8(SP), R12
-	MOVQ	R12, m_libcallsp(R13)
-
-	MOVQ	m_g0(R13), R14
-	CMPQ	g(R15), R14
-	JNE	usleep1_switch
-	// executing on m->g0 already
-	CALL	AX
-	JMP	usleep1_ret
-
-usleep1_switch:
-	// Switch to m->g0 stack and back.
-	MOVQ	(g_sched+gobuf_sp)(R14), R14
-	MOVQ	SP, -8(R14)
-	LEAQ	-8(R14), SP
-	CALL	AX
-	MOVQ	0(SP), SP
-
-usleep1_ret:
-	MOVQ	$0, m_libcallsp(R13)
-	RET
-
-// Runs on OS stack. duration (in 100ns units) is in BX.
-TEXT runtime·usleep2(SB),NOSPLIT,$8
-	// Want negative 100ns units.
-	NEGQ	BX
-	MOVQ	SP, R8 // ptime
-	MOVQ	BX, (R8)
-	MOVQ	$-1, CX // handle
-	MOVQ	$0, DX // alertable
-	MOVQ	runtime·NtWaitForSingleObject(SB), AX
-	CALL	AX
-	RET
diff --git a/src/pkg/runtime/syscall_solaris.goc b/src/pkg/runtime/syscall_solaris.goc
deleted file mode 100644
index 21bcce4..0000000
--- a/src/pkg/runtime/syscall_solaris.goc
+++ /dev/null
@@ -1,374 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package syscall
-#include "runtime.h"
-#include "defs_GOOS_GOARCH.h"
-#include "os_GOOS.h"
-#include "cgocall.h"
-#include "../../cmd/ld/textflag.h"
-
-#pragma dynimport libc·chdir chdir "libc.so"
-#pragma dynimport libc·chroot chroot "libc.so"
-#pragma dynimport libc·close close "libc.so"
-#pragma dynimport libc·dlclose dlclose "libc.so"
-#pragma dynimport libc·dlopen dlopen "libc.so"
-#pragma dynimport libc·dlsym dlsym "libc.so"
-#pragma dynimport libc·execve execve "libc.so"
-#pragma dynimport libc·fcntl fcntl "libc.so"
-#pragma dynimport libc·gethostname gethostname "libc.so"
-#pragma dynimport libc·ioctl ioctl "libc.so"
-#pragma dynimport libc·pipe pipe "libc.so"
-#pragma dynimport libc·setgid setgid "libc.so"
-#pragma dynimport libc·setgroups setgroups "libc.so"
-#pragma dynimport libc·setsid setsid "libc.so"
-#pragma dynimport libc·setuid setuid "libc.so"
-#pragma dynimport libc·setpgid setsid "libc.so"
-#pragma dynimport libc·syscall syscall "libc.so"
-#pragma dynimport libc·forkx forkx "libc.so"
-#pragma dynimport libc·wait4 wait4 "libc.so"
-extern uintptr libc·chdir;
-extern uintptr libc·chroot;
-extern uintptr libc·close;
-extern uintptr libc·dlclose;
-extern uintptr libc·dlopen;
-extern uintptr libc·dlsym;
-extern uintptr libc·execve;
-extern uintptr libc·exit;
-extern uintptr libc·fcntl;
-extern uintptr libc·gethostname;
-extern uintptr libc·ioctl;
-extern uintptr libc·pipe;
-extern uintptr libc·setgid;
-extern uintptr libc·setgroups;
-extern uintptr libc·setsid;
-extern uintptr libc·setuid;
-extern uintptr libc·setpgid;
-extern uintptr libc·syscall;
-extern uintptr libc·forkx;
-extern uintptr libc·wait4;
-extern uintptr libc·write;
-
-func sysvicall6(func uintptr, nargs uintptr, a1 uintptr, a2 uintptr, a3 uintptr, a4 uintptr, a5 uintptr, a6 uintptr) (r1 uintptr, r2 uintptr, err uintptr)
-{
-	LibCall c;
-
-	USED(a2);
-	USED(a3);
-	USED(a4);
-	USED(a5);
-	USED(a6);
-	c.fn = (void*)func;
-	c.n = nargs;
-	c.args = (void*)&a1;
-	runtime·cgocall(runtime·asmsysvicall6, &c);
-	err = c.err;
-	r1 = c.r1;
-	r2 = c.r2;
-}
-
-#pragma textflag NOSPLIT
-func rawSysvicall6(func uintptr, nargs uintptr, a1 uintptr, a2 uintptr, a3 uintptr, a4 uintptr, a5 uintptr, a6 uintptr) (r1 uintptr, r2 uintptr, err uintptr)
-{
-	LibCall c;
-
-	USED(a2);
-	USED(a3);
-	USED(a4);
-	USED(a5);
-	USED(a6);
-	c.fn = (void*)func;
-	c.n = nargs;
-	c.args = (void*)&a1;
-	runtime·asmcgocall(runtime·asmsysvicall6, &c);
-	err = c.err;
-	r1 = c.r1;
-	r2 = c.r2;
-}
-
-#pragma textflag NOSPLIT
-func chdir(path uintptr) (err uintptr) {
-	LibCall c;
-
-	c.fn = (void*)libc·chdir;
-	c.n = 1;
-	c.args = (void*)&path;
-	runtime·asmcgocall(runtime·asmsysvicall6, &c);
-	err = c.err;
-}
-
-#pragma textflag NOSPLIT
-func chroot1(path uintptr) (err uintptr) {
-	LibCall c;
-
-	c.fn = (void*)libc·chroot;
-	c.n = 1;
-	c.args = (void*)&path;
-	runtime·asmcgocall(runtime·asmsysvicall6, &c);
-	err = c.err;
-}
-
-#pragma textflag NOSPLIT
-func close(fd uintptr) (err uintptr) {
-	LibCall c;
-
-	c.fn = (void*)libc·close;
-	c.n = 1;
-	c.args = (void*)&fd;
-	runtime·asmcgocall(runtime·asmsysvicall6, &c);
-	err = c.err;
-}
-
-func dlclose(handle uintptr) (err uintptr) {
-	LibCall c;
-
-	USED(handle);
-	c.fn = (void*)libc·dlclose;
-	c.n = 1;
-	c.args = (void*)&handle;
-	runtime·cgocall(runtime·asmsysvicall6, &c);
-	err = c.r1;
-}
-
-func dlopen(name *uint8, mode uintptr) (handle uintptr, err uintptr) {
-	LibCall c;
-
-	USED(mode);
-	c.fn = (void*)libc·dlopen;
-	c.n = 2;
-	c.args = (void*)&name;
-	runtime·cgocall(runtime·asmsysvicall6, &c);
-	handle = c.r1;
-	if(handle == 0)
-		err = c.err;
-	else
-		err = 0;
-}
-
-func dlsym(handle uintptr, name *uint8) (proc uintptr, err uintptr) {
-	LibCall c;
-
-	USED(name);
-	c.fn = (void*)libc·dlsym;
-	c.n = 2;
-	c.args = &handle;
-	runtime·cgocall(runtime·asmsysvicall6, &c);
-	proc = c.r1;
-	if(proc == 0)
-		err = c.err;
-	else
-		err = 0;
-}
-
-#pragma textflag NOSPLIT
-func execve(path uintptr, argv uintptr, envp uintptr) (err uintptr) {
-	LibCall c;
-
-	USED(argv);
-	USED(envp);
-	c.fn = (void*)libc·execve;
-	c.n = 3;
-	c.args = (void*)&path;
-	runtime·asmcgocall(runtime·asmsysvicall6, &c);
-	err = c.err;
-}
-
-#pragma textflag NOSPLIT
-func exit(code uintptr) {
-	LibCall c;
-
-	c.fn = (void*)libc·exit;
-	c.n = 1;
-	c.args = (void*)&code;
-	runtime·asmcgocall(runtime·asmsysvicall6, &c);
-}
-
-#pragma textflag NOSPLIT
-func fcntl1(fd uintptr, cmd uintptr, arg uintptr) (val uintptr, err uintptr) {
-	LibCall c;
-
-	USED(cmd);
-	USED(arg);
-	c.fn = (void*)libc·fcntl;
-	c.n = 3;
-	c.args = (void*)&fd;
-	runtime·asmcgocall(runtime·asmsysvicall6, &c);
-	err = c.err;
-	val = c.r1;
-}
-
-func gethostname() (name String, err uintptr) {
-	struct { uintptr v[2]; } args;
-	uint8 cname[MAXHOSTNAMELEN];
-	LibCall c;
-
-	c.fn = (void*)libc·gethostname;
-	c.n = 2;
-	args.v[0] = (uintptr)&cname[0];
-	args.v[1] = MAXHOSTNAMELEN;
-	c.args = (void*)&args;
-	runtime·cgocall(runtime·asmsysvicall6, &c);
-	err = c.err;
-	if(c.r1) {
-		name = runtime·emptystring;
-		return;
-	}
-	cname[MAXHOSTNAMELEN - 1] = 0;
-	name = runtime·gostring(cname);
-}
-
-#pragma textflag NOSPLIT
-func ioctl(fd uintptr, req uintptr, arg uintptr) (err uintptr) {
-	LibCall c;
-
-	USED(req);
-	USED(arg);
-	c.fn = (void*)libc·ioctl;
-	c.n = 3;
-	c.args = (void*)&fd;
-	runtime·asmcgocall(runtime·asmsysvicall6, &c);
-	err = c.err;
-}
-
-func wait4(pid uintptr, wstatus *uint32, options uintptr, rusage *void) (wpid int, err uintptr) {
-	LibCall c;
-
-	USED(wstatus);
-	USED(options);
-	USED(rusage);
-	c.fn = (void*)libc·wait4;
-	c.n = 4;
-	c.args = (void*)&pid;
-	runtime·cgocall(runtime·asmsysvicall6, &c);
-	err = c.err;
-	wpid = c.r1;
-}
-
-#pragma textflag NOSPLIT
-func setgid(gid uintptr) (err uintptr) {
-	LibCall c;
-
-	c.fn = (void*)libc·setgid;
-	c.n = 1;
-	c.args = (void*)&gid;
-	runtime·asmcgocall(runtime·asmsysvicall6, &c);
-	err = c.err;
-}
-
-#pragma textflag NOSPLIT
-func setgroups1(ngid uintptr, gid uintptr) (err uintptr) {
-	LibCall c;
-
-	USED(gid);
-	c.fn = (void*)libc·setgroups;
-	c.n = 2;
-	c.args = (void*)&ngid;
-	runtime·asmcgocall(runtime·asmsysvicall6, &c);
-	err = c.err;
-}
-
-#pragma textflag NOSPLIT
-func setsid() (pid uintptr, err uintptr) {
-	LibCall c;
-
-	c.fn = (void*)libc·setsid;
-	c.n = 0;
-	c.args = (void*)0;
-	runtime·asmcgocall(runtime·asmsysvicall6, &c);
-	err = c.err;
-	pid = c.r1;
-}
-
-#pragma textflag NOSPLIT
-func setuid(uid uintptr) (err uintptr) {
-	LibCall c;
-
-	c.fn = (void*)libc·setuid;
-	c.n = 1;
-	c.args = (void*)&uid;
-	runtime·asmcgocall(runtime·asmsysvicall6, &c);
-	err = c.err;
-}
-
-#pragma textflag NOSPLIT
-func setpgid(pid uintptr, pgid uintptr) (err uintptr) {
-	LibCall c;
-
-	USED(pgid);
-	c.fn = (void*)libc·setpgid;
-	c.n = 2;
-	c.args = (void*)&pid;
-	runtime·asmcgocall(runtime·asmsysvicall6, &c);
-	err = c.err;
-}
-
-#pragma textflag NOSPLIT
-func forkx(flags uintptr) (pid uintptr, err uintptr) {
-	LibCall c;
-
-	c.fn = (void*)libc·forkx;
-	c.n = 1;
-	c.args = (void*)&flags;
-	runtime·asmcgocall(runtime·asmsysvicall6, &c);
-	err = c.err;
-	pid = c.r1;
-}
-
-void runtime·pipe1(void);
-
-func pipe() (r uintptr, w uintptr, err uintptr) {
-	LibCall c;
-
-	c.fn = (void*)runtime·pipe1;
-	c.n = 0;
-	c.args = (void*)0;
-	runtime·cgocall(runtime·asmsysvicall6, &c);
-	err = c.err;
-	r = c.r1;
-	w = c.r2;
-}
-
-#pragma textflag NOSPLIT
-func write1(fd uintptr, buf uintptr, nbyte uintptr) (n uintptr, err uintptr) {
-	LibCall c;
-
-	USED(buf);
-	USED(nbyte);
-	c.fn = (void*)libc·write;
-	c.n = 3;
-	c.args = (void*)fd;
-	runtime·asmcgocall(runtime·asmsysvicall6, &c);
-	err = c.err;
-	n = c.r1;
-}
-
-func Syscall(trap uintptr, a1 uintptr, a2 uintptr, a3 uintptr) (r1 uintptr, r2 uintptr, err uintptr) {
-	LibCall c;
-
-	USED(a1);
-	USED(a2);
-	USED(a3);
-	c.fn = (void*)libc·syscall;
-	c.n = 4;
-	c.args = &trap;
-	runtime·cgocall(runtime·asmsysvicall6, &c);
-	err = c.err;
-	r1 = c.r1;
-	r2 = c.r2;
-}
-
-func RawSyscall(trap uintptr, a1 uintptr, a2 uintptr, a3 uintptr) (r1 uintptr, r2 uintptr, err uintptr) {
-	LibCall c;
-
-	USED(a1);
-	USED(a2);
-	USED(a3);
-	c.fn = (void*)libc·syscall;
-	c.n = 4;
-	c.args = &trap;
-	runtime·asmcgocall(runtime·asmsysvicall6, &c);
-	err = c.err;
-	r1 = c.r1;
-	r2 = c.r2;
-}
diff --git a/src/pkg/runtime/syscall_windows.goc b/src/pkg/runtime/syscall_windows.goc
deleted file mode 100644
index 5282453..0000000
--- a/src/pkg/runtime/syscall_windows.goc
+++ /dev/null
@@ -1,145 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package syscall
-#include "runtime.h"
-#include "os_GOOS.h"
-#include "cgocall.h"
-
-func loadlibrary(filename *uint16) (handle uintptr, err uintptr) {
-	LibCall c;
-
-	c.fn = runtime·LoadLibrary;
-	c.n = 1;
-	c.args = &filename;
-	runtime·cgocall(runtime·asmstdcall, &c);
-	handle = c.r1;
-	if(handle == 0)
-		err = c.err;
-	else
-		err = 0;
-}
-
-func getprocaddress(handle uintptr, procname *uint8) (proc uintptr, err uintptr) {
-	LibCall c;
-
-	USED(procname);
-	c.fn = runtime·GetProcAddress;
-	c.n = 2;
-	c.args = &handle;
-	runtime·cgocall(runtime·asmstdcall, &c);
-	proc = c.r1;
-	if(proc == 0)
-		err = c.err;
-	else
-		err = 0;
-}
-
-func NewCallback(fn Eface) (code uintptr) {
-	code = (uintptr)runtime·compilecallback(fn, true);
-}
-
-func NewCallbackCDecl(fn Eface) (code uintptr) {
-	code = (uintptr)runtime·compilecallback(fn, false);
-}
-
-func Syscall(fn uintptr, nargs uintptr, a1 uintptr, a2 uintptr, a3 uintptr) (r1 uintptr, r2 uintptr, err uintptr) {
-	LibCall c;
-
-	USED(a2);
-	USED(a3);
-	c.fn = (void*)fn;
-	c.n = nargs;
-	c.args = &a1;
-	runtime·cgocall(runtime·asmstdcall, &c);
-	err = c.err;
-	r1 = c.r1;
-	r2 = c.r2;
-}
-
-func Syscall6(fn uintptr, nargs uintptr, a1 uintptr, a2 uintptr, a3 uintptr, a4 uintptr, a5 uintptr, a6 uintptr) (r1 uintptr, r2 uintptr, err uintptr) {
-	LibCall c;
-
-	USED(a2);
-	USED(a3);
-	USED(a4);
-	USED(a5);
-	USED(a6);
-	c.fn = (void*)fn;
-	c.n = nargs;
-	c.args = &a1;
-	runtime·cgocall(runtime·asmstdcall, &c);
-	err = c.err;
-	r1 = c.r1;
-	r2 = c.r2;
-}
-
-func Syscall9(fn uintptr, nargs uintptr, a1 uintptr, a2 uintptr, a3 uintptr, a4 uintptr, a5 uintptr, a6 uintptr, a7 uintptr, a8 uintptr, a9 uintptr) (r1 uintptr, r2 uintptr, err uintptr) {
-	LibCall c;
-
-	USED(a2);
-	USED(a3);
-	USED(a4);
-	USED(a5);
-	USED(a6);
-	USED(a7);
-	USED(a8);
-	USED(a9);
-	c.fn = (void*)fn;
-	c.n = nargs;
-	c.args = &a1;
-	runtime·cgocall(runtime·asmstdcall, &c);
-	err = c.err;
-	r1 = c.r1;
-	r2 = c.r2;
-}
-
-func Syscall12(fn uintptr, nargs uintptr, a1 uintptr, a2 uintptr, a3 uintptr, a4 uintptr, a5 uintptr, a6 uintptr, a7 uintptr, a8 uintptr, a9 uintptr, a10 uintptr, a11 uintptr, a12 uintptr) (r1 uintptr, r2 uintptr, err uintptr) {
-	LibCall c;
-
-	USED(a2);
-	USED(a3);
-	USED(a4);
-	USED(a5);
-	USED(a6);
-	USED(a7);
-	USED(a8);
-	USED(a9);
-	USED(a10);
-	USED(a11);
-	USED(a12);
-	c.fn = (void*)fn;
-	c.n = nargs;
-	c.args = &a1;
-	runtime·cgocall(runtime·asmstdcall, &c);
-	err = c.err;
-	r1 = c.r1;
-	r2 = c.r2;
-}
-
-func Syscall15(fn uintptr, nargs uintptr, a1 uintptr, a2 uintptr, a3 uintptr, a4 uintptr, a5 uintptr, a6 uintptr, a7 uintptr, a8 uintptr, a9 uintptr, a10 uintptr, a11 uintptr, a12 uintptr, a13 uintptr, a14 uintptr, a15 uintptr) (r1 uintptr, r2 uintptr, err uintptr) {
-	LibCall c;
-
-	USED(a2);
-	USED(a3);
-	USED(a4);
-	USED(a5);
-	USED(a6);
-	USED(a7);
-	USED(a8);
-	USED(a9);
-	USED(a10);
-	USED(a11);
-	USED(a12);
-	USED(a13);
-	USED(a14);
-	USED(a15);
-	c.fn = (void*)fn;
-	c.n = nargs;
-	c.args = &a1;
-	runtime·cgocall(runtime·asmstdcall, &c);
-	err = c.err;
-	r1 = c.r1;
-	r2 = c.r2;
-}
diff --git a/src/pkg/runtime/syscall_windows_test.go b/src/pkg/runtime/syscall_windows_test.go
deleted file mode 100644
index fabf935..0000000
--- a/src/pkg/runtime/syscall_windows_test.go
+++ /dev/null
@@ -1,451 +0,0 @@
-// Copyright 2010 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package runtime_test
-
-import (
-	"fmt"
-	"io/ioutil"
-	"os"
-	"os/exec"
-	"path/filepath"
-	"runtime"
-	"strings"
-	"syscall"
-	"testing"
-	"unsafe"
-)
-
-type DLL struct {
-	*syscall.DLL
-	t *testing.T
-}
-
-func GetDLL(t *testing.T, name string) *DLL {
-	d, e := syscall.LoadDLL(name)
-	if e != nil {
-		t.Fatal(e)
-	}
-	return &DLL{DLL: d, t: t}
-}
-
-func (d *DLL) Proc(name string) *syscall.Proc {
-	p, e := d.FindProc(name)
-	if e != nil {
-		d.t.Fatal(e)
-	}
-	return p
-}
-
-func TestStdCall(t *testing.T) {
-	type Rect struct {
-		left, top, right, bottom int32
-	}
-	res := Rect{}
-	expected := Rect{1, 1, 40, 60}
-	a, _, _ := GetDLL(t, "user32.dll").Proc("UnionRect").Call(
-		uintptr(unsafe.Pointer(&res)),
-		uintptr(unsafe.Pointer(&Rect{10, 1, 14, 60})),
-		uintptr(unsafe.Pointer(&Rect{1, 2, 40, 50})))
-	if a != 1 || res.left != expected.left ||
-		res.top != expected.top ||
-		res.right != expected.right ||
-		res.bottom != expected.bottom {
-		t.Error("stdcall USER32.UnionRect returns", a, "res=", res)
-	}
-}
-
-func Test64BitReturnStdCall(t *testing.T) {
-
-	const (
-		VER_BUILDNUMBER      = 0x0000004
-		VER_MAJORVERSION     = 0x0000002
-		VER_MINORVERSION     = 0x0000001
-		VER_PLATFORMID       = 0x0000008
-		VER_PRODUCT_TYPE     = 0x0000080
-		VER_SERVICEPACKMAJOR = 0x0000020
-		VER_SERVICEPACKMINOR = 0x0000010
-		VER_SUITENAME        = 0x0000040
-
-		VER_EQUAL         = 1
-		VER_GREATER       = 2
-		VER_GREATER_EQUAL = 3
-		VER_LESS          = 4
-		VER_LESS_EQUAL    = 5
-
-		ERROR_OLD_WIN_VERSION syscall.Errno = 1150
-	)
-
-	type OSVersionInfoEx struct {
-		OSVersionInfoSize uint32
-		MajorVersion      uint32
-		MinorVersion      uint32
-		BuildNumber       uint32
-		PlatformId        uint32
-		CSDVersion        [128]uint16
-		ServicePackMajor  uint16
-		ServicePackMinor  uint16
-		SuiteMask         uint16
-		ProductType       byte
-		Reserve           byte
-	}
-
-	d := GetDLL(t, "kernel32.dll")
-
-	var m1, m2 uintptr
-	VerSetConditionMask := d.Proc("VerSetConditionMask")
-	m1, m2, _ = VerSetConditionMask.Call(m1, m2, VER_MAJORVERSION, VER_GREATER_EQUAL)
-	m1, m2, _ = VerSetConditionMask.Call(m1, m2, VER_MINORVERSION, VER_GREATER_EQUAL)
-	m1, m2, _ = VerSetConditionMask.Call(m1, m2, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL)
-	m1, m2, _ = VerSetConditionMask.Call(m1, m2, VER_SERVICEPACKMINOR, VER_GREATER_EQUAL)
-
-	vi := OSVersionInfoEx{
-		MajorVersion:     5,
-		MinorVersion:     1,
-		ServicePackMajor: 2,
-		ServicePackMinor: 0,
-	}
-	vi.OSVersionInfoSize = uint32(unsafe.Sizeof(vi))
-	r, _, e2 := d.Proc("VerifyVersionInfoW").Call(
-		uintptr(unsafe.Pointer(&vi)),
-		VER_MAJORVERSION|VER_MINORVERSION|VER_SERVICEPACKMAJOR|VER_SERVICEPACKMINOR,
-		m1, m2)
-	if r == 0 && e2 != ERROR_OLD_WIN_VERSION {
-		t.Errorf("VerifyVersionInfo failed: %s", e2)
-	}
-}
-
-func TestCDecl(t *testing.T) {
-	var buf [50]byte
-	fmtp, _ := syscall.BytePtrFromString("%d %d %d")
-	a, _, _ := GetDLL(t, "user32.dll").Proc("wsprintfA").Call(
-		uintptr(unsafe.Pointer(&buf[0])),
-		uintptr(unsafe.Pointer(fmtp)),
-		1000, 2000, 3000)
-	if string(buf[:a]) != "1000 2000 3000" {
-		t.Error("cdecl USER32.wsprintfA returns", a, "buf=", buf[:a])
-	}
-}
-
-func TestEnumWindows(t *testing.T) {
-	d := GetDLL(t, "user32.dll")
-	isWindows := d.Proc("IsWindow")
-	counter := 0
-	cb := syscall.NewCallback(func(hwnd syscall.Handle, lparam uintptr) uintptr {
-		if lparam != 888 {
-			t.Error("lparam was not passed to callback")
-		}
-		b, _, _ := isWindows.Call(uintptr(hwnd))
-		if b == 0 {
-			t.Error("USER32.IsWindow returns FALSE")
-		}
-		counter++
-		return 1 // continue enumeration
-	})
-	a, _, _ := d.Proc("EnumWindows").Call(cb, 888)
-	if a == 0 {
-		t.Error("USER32.EnumWindows returns FALSE")
-	}
-	if counter == 0 {
-		t.Error("Callback has been never called or your have no windows")
-	}
-}
-
-func callback(hwnd syscall.Handle, lparam uintptr) uintptr {
-	(*(*func())(unsafe.Pointer(&lparam)))()
-	return 0 // stop enumeration
-}
-
-// nestedCall calls into Windows, back into Go, and finally to f.
-func nestedCall(t *testing.T, f func()) {
-	c := syscall.NewCallback(callback)
-	d := GetDLL(t, "user32.dll")
-	defer d.Release()
-	d.Proc("EnumWindows").Call(c, uintptr(*(*unsafe.Pointer)(unsafe.Pointer(&f))))
-}
-
-func TestCallback(t *testing.T) {
-	var x = false
-	nestedCall(t, func() { x = true })
-	if !x {
-		t.Fatal("nestedCall did not call func")
-	}
-}
-
-func TestCallbackGC(t *testing.T) {
-	nestedCall(t, runtime.GC)
-}
-
-func TestCallbackPanicLocked(t *testing.T) {
-	runtime.LockOSThread()
-	defer runtime.UnlockOSThread()
-
-	if !runtime.LockedOSThread() {
-		t.Fatal("runtime.LockOSThread didn't")
-	}
-	defer func() {
-		s := recover()
-		if s == nil {
-			t.Fatal("did not panic")
-		}
-		if s.(string) != "callback panic" {
-			t.Fatal("wrong panic:", s)
-		}
-		if !runtime.LockedOSThread() {
-			t.Fatal("lost lock on OS thread after panic")
-		}
-	}()
-	nestedCall(t, func() { panic("callback panic") })
-	panic("nestedCall returned")
-}
-
-func TestCallbackPanic(t *testing.T) {
-	// Make sure panic during callback unwinds properly.
-	if runtime.LockedOSThread() {
-		t.Fatal("locked OS thread on entry to TestCallbackPanic")
-	}
-	defer func() {
-		s := recover()
-		if s == nil {
-			t.Fatal("did not panic")
-		}
-		if s.(string) != "callback panic" {
-			t.Fatal("wrong panic:", s)
-		}
-		if runtime.LockedOSThread() {
-			t.Fatal("locked OS thread on exit from TestCallbackPanic")
-		}
-	}()
-	nestedCall(t, func() { panic("callback panic") })
-	panic("nestedCall returned")
-}
-
-func TestCallbackPanicLoop(t *testing.T) {
-	// Make sure we don't blow out m->g0 stack.
-	for i := 0; i < 100000; i++ {
-		TestCallbackPanic(t)
-	}
-}
-
-func TestBlockingCallback(t *testing.T) {
-	c := make(chan int)
-	go func() {
-		for i := 0; i < 10; i++ {
-			c <- <-c
-		}
-	}()
-	nestedCall(t, func() {
-		for i := 0; i < 10; i++ {
-			c <- i
-			if j := <-c; j != i {
-				t.Errorf("out of sync %d != %d", j, i)
-			}
-		}
-	})
-}
-
-func TestCallbackInAnotherThread(t *testing.T) {
-	// TODO: test a function which calls back in another thread: QueueUserAPC() or CreateThread()
-}
-
-type cbDLLFunc int // int determines number of callback parameters
-
-func (f cbDLLFunc) stdcallName() string {
-	return fmt.Sprintf("stdcall%d", f)
-}
-
-func (f cbDLLFunc) cdeclName() string {
-	return fmt.Sprintf("cdecl%d", f)
-}
-
-func (f cbDLLFunc) buildOne(stdcall bool) string {
-	var funcname, attr string
-	if stdcall {
-		funcname = f.stdcallName()
-		attr = "__stdcall"
-	} else {
-		funcname = f.cdeclName()
-		attr = "__cdecl"
-	}
-	typename := "t" + funcname
-	p := make([]string, f)
-	for i := range p {
-		p[i] = "void*"
-	}
-	params := strings.Join(p, ",")
-	for i := range p {
-		p[i] = fmt.Sprintf("%d", i+1)
-	}
-	args := strings.Join(p, ",")
-	return fmt.Sprintf(`
-typedef void %s (*%s)(%s);
-void %s(%s f, void *n) {
-	int i;
-	for(i=0;i<(int)n;i++){
-		f(%s);
-	}
-}
-	`, attr, typename, params, funcname, typename, args)
-}
-
-func (f cbDLLFunc) build() string {
-	return f.buildOne(false) + f.buildOne(true)
-}
-
-var cbFuncs = [...]interface{}{
-	2: func(i1, i2 uintptr) uintptr {
-		if i1+i2 != 3 {
-			panic("bad input")
-		}
-		return 0
-	},
-	3: func(i1, i2, i3 uintptr) uintptr {
-		if i1+i2+i3 != 6 {
-			panic("bad input")
-		}
-		return 0
-	},
-	4: func(i1, i2, i3, i4 uintptr) uintptr {
-		if i1+i2+i3+i4 != 10 {
-			panic("bad input")
-		}
-		return 0
-	},
-	5: func(i1, i2, i3, i4, i5 uintptr) uintptr {
-		if i1+i2+i3+i4+i5 != 15 {
-			panic("bad input")
-		}
-		return 0
-	},
-	6: func(i1, i2, i3, i4, i5, i6 uintptr) uintptr {
-		if i1+i2+i3+i4+i5+i6 != 21 {
-			panic("bad input")
-		}
-		return 0
-	},
-	7: func(i1, i2, i3, i4, i5, i6, i7 uintptr) uintptr {
-		if i1+i2+i3+i4+i5+i6+i7 != 28 {
-			panic("bad input")
-		}
-		return 0
-	},
-	8: func(i1, i2, i3, i4, i5, i6, i7, i8 uintptr) uintptr {
-		if i1+i2+i3+i4+i5+i6+i7+i8 != 36 {
-			panic("bad input")
-		}
-		return 0
-	},
-	9: func(i1, i2, i3, i4, i5, i6, i7, i8, i9 uintptr) uintptr {
-		if i1+i2+i3+i4+i5+i6+i7+i8+i9 != 45 {
-			panic("bad input")
-		}
-		return 0
-	},
-}
-
-type cbDLL struct {
-	name      string
-	buildArgs func(out, src string) []string
-}
-
-func (d *cbDLL) buildSrc(t *testing.T, path string) {
-	f, err := os.Create(path)
-	if err != nil {
-		t.Fatalf("failed to create source file: %v", err)
-	}
-	defer f.Close()
-
-	for i := 2; i < 10; i++ {
-		fmt.Fprint(f, cbDLLFunc(i).build())
-	}
-}
-
-func (d *cbDLL) build(t *testing.T, dir string) string {
-	srcname := d.name + ".c"
-	d.buildSrc(t, filepath.Join(dir, srcname))
-	outname := d.name + ".dll"
-	args := d.buildArgs(outname, srcname)
-	cmd := exec.Command(args[0], args[1:]...)
-	cmd.Dir = dir
-	out, err := cmd.CombinedOutput()
-	if err != nil {
-		t.Fatalf("failed to build dll: %v - %v", err, string(out))
-	}
-	return filepath.Join(dir, outname)
-}
-
-var cbDLLs = []cbDLL{
-	{
-		"test",
-		func(out, src string) []string {
-			return []string{"gcc", "-shared", "-s", "-o", out, src}
-		},
-	},
-	{
-		"testO2",
-		func(out, src string) []string {
-			return []string{"gcc", "-shared", "-s", "-o", out, "-O2", src}
-		},
-	},
-}
-
-type cbTest struct {
-	n     int     // number of callback parameters
-	param uintptr // dll function parameter
-}
-
-func (test *cbTest) run(t *testing.T, dllpath string) {
-	dll := syscall.MustLoadDLL(dllpath)
-	defer dll.Release()
-	cb := cbFuncs[test.n]
-	stdcall := syscall.NewCallback(cb)
-	f := cbDLLFunc(test.n)
-	test.runOne(t, dll, f.stdcallName(), stdcall)
-	cdecl := syscall.NewCallbackCDecl(cb)
-	test.runOne(t, dll, f.cdeclName(), cdecl)
-}
-
-func (test *cbTest) runOne(t *testing.T, dll *syscall.DLL, proc string, cb uintptr) {
-	defer func() {
-		if r := recover(); r != nil {
-			t.Errorf("dll call %v(..., %d) failed: %v", proc, test.param, r)
-		}
-	}()
-	dll.MustFindProc(proc).Call(cb, test.param)
-}
-
-var cbTests = []cbTest{
-	{2, 1},
-	{2, 10000},
-	{3, 3},
-	{4, 5},
-	{4, 6},
-	{5, 2},
-	{6, 7},
-	{6, 8},
-	{7, 6},
-	{8, 1},
-	{9, 8},
-	{9, 10000},
-	{3, 4},
-	{5, 3},
-	{7, 7},
-	{8, 2},
-	{9, 9},
-}
-
-func TestStdcallAndCDeclCallbacks(t *testing.T) {
-	tmp, err := ioutil.TempDir("", "TestCDeclCallback")
-	if err != nil {
-		t.Fatal("TempDir failed: ", err)
-	}
-	defer os.RemoveAll(tmp)
-
-	for _, dll := range cbDLLs {
-		dllPath := dll.build(t, tmp)
-		for _, test := range cbTests {
-			test.run(t, dllPath)
-		}
-	}
-}
diff --git a/src/pkg/runtime/time.goc b/src/pkg/runtime/time.goc
deleted file mode 100644
index 712e03e..0000000
--- a/src/pkg/runtime/time.goc
+++ /dev/null
@@ -1,344 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Time-related runtime and pieces of package time.
-
-package time
-
-#include "runtime.h"
-#include "defs_GOOS_GOARCH.h"
-#include "os_GOOS.h"
-#include "arch_GOARCH.h"
-#include "malloc.h"
-#include "race.h"
-
-enum {
-	debug = 0,
-};
-
-static Timers timers;
-static void addtimer(Timer*);
-static void dumptimers(int8*);
-
-// nacl fake time support. 
-int64 runtime·timens;
-
-// Package time APIs.
-// Godoc uses the comments in package time, not these.
-
-// time.now is implemented in assembly.
-
-// runtimeNano returns the current value of the runtime clock in nanoseconds.
-func runtimeNano() (ns int64) {
-	ns = runtime·nanotime();
-}
-
-// Sleep puts the current goroutine to sleep for at least ns nanoseconds.
-func Sleep(ns int64) {
-	runtime·tsleep(ns, "sleep");
-}
-
-// startTimer adds t to the timer heap.
-func startTimer(t *Timer) {
-	if(raceenabled)
-		runtime·racerelease(t);
-	runtime·addtimer(t);
-}
-
-// stopTimer removes t from the timer heap if it is there.
-// It returns true if t was removed, false if t wasn't even there.
-func stopTimer(t *Timer) (stopped bool) {
-	stopped = runtime·deltimer(t);
-}
-
-// C runtime.
-
-void runtime·gc_unixnanotime(int64 *now);
-
-int64 runtime·unixnanotime(void)
-{
-	int64 now;
-
-	runtime·gc_unixnanotime(&now);
-	return now;
-}
-
-static void timerproc(void);
-static void siftup(int32);
-static void siftdown(int32);
-
-// Ready the goroutine e.data.
-static void
-ready(int64 now, Eface e)
-{
-	USED(now);
-
-	runtime·ready(e.data);
-}
-
-static FuncVal readyv = {(void(*)(void))ready};
-
-// Put the current goroutine to sleep for ns nanoseconds.
-void
-runtime·tsleep(int64 ns, int8 *reason)
-{
-	Timer t;
-
-	if(ns <= 0)
-		return;
-
-	t.when = runtime·nanotime() + ns;
-	t.period = 0;
-	t.fv = &readyv;
-	t.arg.data = g;
-	runtime·lock(&timers);
-	addtimer(&t);
-	runtime·parkunlock(&timers, reason);
-}
-
-static FuncVal timerprocv = {timerproc};
-
-void
-runtime·addtimer(Timer *t)
-{
-	runtime·lock(&timers);
-	addtimer(t);
-	runtime·unlock(&timers);
-}
-
-// Add a timer to the heap and start or kick the timer proc
-// if the new timer is earlier than any of the others.
-static void
-addtimer(Timer *t)
-{
-	int32 n;
-	Timer **nt;
-
-	// when must never be negative; otherwise timerproc will overflow
-	// during its delta calculation and never expire other timers.
-	if(t->when < 0)
-		t->when = (1LL<<63)-1;
-
-	if(timers.len >= timers.cap) {
-		// Grow slice.
-		n = 16;
-		if(n <= timers.cap)
-			n = timers.cap*3 / 2;
-		nt = runtime·malloc(n*sizeof nt[0]);
-		runtime·memmove(nt, timers.t, timers.len*sizeof nt[0]);
-		runtime·free(timers.t);
-		timers.t = nt;
-		timers.cap = n;
-	}
-	t->i = timers.len++;
-	timers.t[t->i] = t;
-	siftup(t->i);
-	if(t->i == 0) {
-		// siftup moved to top: new earliest deadline.
-		if(timers.sleeping) {
-			timers.sleeping = false;
-			runtime·notewakeup(&timers.waitnote);
-		}
-		if(timers.rescheduling) {
-			timers.rescheduling = false;
-			runtime·ready(timers.timerproc);
-		}
-	}
-	if(timers.timerproc == nil) {
-		timers.timerproc = runtime·newproc1(&timerprocv, nil, 0, 0, addtimer);
-		timers.timerproc->issystem = true;
-	}
-	if(debug)
-		dumptimers("addtimer");
-}
-
-// Delete timer t from the heap.
-// Do not need to update the timerproc:
-// if it wakes up early, no big deal.
-bool
-runtime·deltimer(Timer *t)
-{
-	int32 i;
-
-	// Dereference t so that any panic happens before the lock is held.
-	// Discard result, because t might be moving in the heap.
-	i = t->i;
-	USED(i);
-
-	runtime·lock(&timers);
-
-	// t may not be registered anymore and may have
-	// a bogus i (typically 0, if generated by Go).
-	// Verify it before proceeding.
-	i = t->i;
-	if(i < 0 || i >= timers.len || timers.t[i] != t) {
-		runtime·unlock(&timers);
-		return false;
-	}
-
-	timers.len--;
-	if(i == timers.len) {
-		timers.t[i] = nil;
-	} else {
-		timers.t[i] = timers.t[timers.len];
-		timers.t[timers.len] = nil;
-		timers.t[i]->i = i;
-		siftup(i);
-		siftdown(i);
-	}
-	if(debug)
-		dumptimers("deltimer");
-	runtime·unlock(&timers);
-	return true;
-}
-
-// Timerproc runs the time-driven events.
-// It sleeps until the next event in the timers heap.
-// If addtimer inserts a new earlier event, addtimer
-// wakes timerproc early.
-static void
-timerproc(void)
-{
-	int64 delta, now;
-	Timer *t;
-	void (*f)(int64, Eface);
-	Eface arg;
-
-	for(;;) {
-		runtime·lock(&timers);
-		timers.sleeping = false;
-		now = runtime·nanotime();
-		for(;;) {
-			if(timers.len == 0) {
-				delta = -1;
-				break;
-			}
-			t = timers.t[0];
-			delta = t->when - now;
-			if(delta > 0)
-				break;
-			if(t->period > 0) {
-				// leave in heap but adjust next time to fire
-				t->when += t->period * (1 + -delta/t->period);
-				siftdown(0);
-			} else {
-				// remove from heap
-				timers.t[0] = timers.t[--timers.len];
-				timers.t[0]->i = 0;
-				siftdown(0);
-				t->i = -1;  // mark as removed
-			}
-			f = (void*)t->fv->fn;
-			arg = t->arg;
-			runtime·unlock(&timers);
-			if(raceenabled)
-				runtime·raceacquire(t);
-			f(now, arg);
-
-			// clear f and arg to avoid leak while sleeping for next timer
-			f = nil;
-			USED(f);
-			arg.type = nil;
-			arg.data = nil;
-			USED(&arg);
-
-			runtime·lock(&timers);
-		}
-		if(delta < 0) {
-			// No timers left - put goroutine to sleep.
-			timers.rescheduling = true;
-			g->isbackground = true;
-			runtime·parkunlock(&timers, "timer goroutine (idle)");
-			g->isbackground = false;
-			continue;
-		}
-		// At least one timer pending.  Sleep until then.
-		timers.sleeping = true;
-		runtime·noteclear(&timers.waitnote);
-		runtime·unlock(&timers);
-		runtime·notetsleepg(&timers.waitnote, delta);
-	}
-}
-
-// heap maintenance algorithms.
-
-static void
-siftup(int32 i)
-{
-	int32 p;
-	int64 when;
-	Timer **t, *tmp;
-
-	t = timers.t;
-	when = t[i]->when;
-	tmp = t[i];
-	while(i > 0) {
-		p = (i-1)/4;  // parent
-		if(when >= t[p]->when)
-			break;
-		t[i] = t[p];
-		t[i]->i = i;
-		t[p] = tmp;
-		tmp->i = p;
-		i = p;
-	}
-}
-
-static void
-siftdown(int32 i)
-{
-	int32 c, c3, len;
-	int64 when, w, w3;
-	Timer **t, *tmp;
-
-	t = timers.t;
-	len = timers.len;
-	when = t[i]->when;
-	tmp = t[i];
-	for(;;) {
-		c = i*4 + 1;  // left child
-		c3 = c + 2;  // mid child
-		if(c >= len) {
-			break;
-		}
-		w = t[c]->when;
-		if(c+1 < len && t[c+1]->when < w) {
-			w = t[c+1]->when;
-			c++;
-		}
-		if(c3 < len) {
-			w3 = t[c3]->when;
-			if(c3+1 < len && t[c3+1]->when < w3) {
-				w3 = t[c3+1]->when;
-				c3++;
-			}
-			if(w3 < w) {
-				w = w3;
-				c = c3;
-			}
-		}
-		if(w >= when)
-			break;
-		t[i] = t[c];
-		t[i]->i = i;
-		t[c] = tmp;
-		tmp->i = c;
-		i = c;
-	}
-}
-
-static void
-dumptimers(int8 *msg)
-{
-	Timer *t;
-	int32 i;
-
-	runtime·printf("timers: %s\n", msg);
-	for(i = 0; i < timers.len; i++) {
-		t = timers.t[i];
-		runtime·printf("\t%d\t%p:\ti %d when %D period %D fn %p\n",
-				i, t, t->i, t->when, t->period, t->fv->fn);
-	}
-	runtime·printf("\n");
-}
diff --git a/src/pkg/runtime/time_plan9_386.c b/src/pkg/runtime/time_plan9_386.c
deleted file mode 100644
index 71d54b7..0000000
--- a/src/pkg/runtime/time_plan9_386.c
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2010 The Go 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 "runtime.h"
-#include "os_GOOS.h"
-#include "../../cmd/ld/textflag.h"
-
-#pragma textflag NOSPLIT
-int64
-runtime·nanotime(void)
-{
-	static int32 fd = -1;
-	byte b[8];
-	uint32 hi, lo;
-
-	// As long as all goroutines share the same file
-	// descriptor table we can get away with using
-	// just a static fd.  Without a lock the file can
-	// be opened twice but that's okay.
-	//
-	// Using /dev/bintime gives us a latency on the
-	// order of ten microseconds between two calls.
-	//
-	// The naïve implementation (without the cached
-	// file descriptor) is roughly four times slower
-	// in 9vx on a 2.16 GHz Intel Core 2 Duo.
-
-	if(fd < 0 && (fd = runtime·open("/dev/bintime", OREAD|OCEXEC, 0)) < 0)
-		return 0;
-	if(runtime·pread(fd, b, sizeof b, 0) != sizeof b)
-		return 0;
-	hi = b[0]<<24 | b[1]<<16 | b[2]<<8 | b[3];
-	lo = b[4]<<24 | b[5]<<16 | b[6]<<8 | b[7];
-	return (int64)hi<<32 | (int64)lo;
-}
diff --git a/src/pkg/runtime/traceback_arm.c b/src/pkg/runtime/traceback_arm.c
deleted file mode 100644
index 30f43d5..0000000
--- a/src/pkg/runtime/traceback_arm.c
+++ /dev/null
@@ -1,357 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "runtime.h"
-#include "arch_GOARCH.h"
-#include "malloc.h"
-#include "funcdata.h"
-
-void runtime·sigpanic(void);
-void runtime·newproc(void);
-void runtime·deferproc(void);
-
-int32
-runtime·gentraceback(uintptr pc0, uintptr sp0, uintptr lr0, G *gp, int32 skip, uintptr *pcbuf, int32 max, bool (*callback)(Stkframe*, void*), void *v, bool printall)
-{
-	int32 i, n, nprint, line, gotraceback;
-	uintptr x, tracepc, sparg;
-	bool waspanic, wasnewproc, printing;
-	Func *f, *flr;
-	Stkframe frame;
-	Stktop *stk;
-	String file;
-	Panic *panic;
-	Defer *defer;
-
-	gotraceback = runtime·gotraceback(nil);
-
-	if(pc0 == ~(uintptr)0 && sp0 == ~(uintptr)0) { // Signal to fetch saved values from gp.
-		if(gp->syscallstack != (uintptr)nil) {
-			pc0 = gp->syscallpc;
-			sp0 = gp->syscallsp;
-			lr0 = 0;
-		} else {
-			pc0 = gp->sched.pc;
-			sp0 = gp->sched.sp;
-			lr0 = gp->sched.lr;
-		}
-	}
-
-	nprint = 0;
-	runtime·memclr((byte*)&frame, sizeof frame);
-	frame.pc = pc0;
-	frame.lr = lr0;
-	frame.sp = sp0;
-	waspanic = false;
-	wasnewproc = false;
-	printing = pcbuf==nil && callback==nil;
-
-	panic = gp->panic;
-	defer = gp->defer;
-
-	while(defer != nil && defer->argp == NoArgs)
-		defer = defer->link;	
-	while(panic != nil && panic->defer == nil)
-		panic = panic->link;
-
-	// If the PC is zero, it's likely a nil function call.
-	// Start in the caller's frame.
-	if(frame.pc == 0) {
-		frame.pc = frame.lr;
-		frame.lr = 0;
-	}
-	
-	f = runtime·findfunc(frame.pc);
-	if(f == nil) {
-		if(callback != nil) {
-			runtime·printf("runtime: unknown pc %p\n", frame.pc);
-			runtime·throw("unknown pc");
-		}
-		return 0;
-	}
-	frame.fn = f;
-
-	n = 0;
-	stk = (Stktop*)gp->stackbase;
-	while(n < max) {
-		// Typically:
-		//	pc is the PC of the running function.
-		//	sp is the stack pointer at that program counter.
-		//	fp is the frame pointer (caller's stack pointer) at that program counter, or nil if unknown.
-		//	stk is the stack containing sp.
-		//	The caller's program counter is lr, unless lr is zero, in which case it is *(uintptr*)sp.
-		
-		if(frame.pc == (uintptr)runtime·lessstack) {
-			// Hit top of stack segment.  Unwind to next segment.
-			frame.pc = stk->gobuf.pc;
-			frame.sp = stk->gobuf.sp;
-			frame.lr = 0;
-			frame.fp = 0;
-			if(printing && runtime·showframe(nil, gp))
-				runtime·printf("----- stack segment boundary -----\n");
-			stk = (Stktop*)stk->stackbase;
-			
-			f = runtime·findfunc(frame.pc);
-			if(f == nil) {
-				runtime·printf("runtime: unknown pc %p after stack split\n", frame.pc);
-				if(callback != nil)
-					runtime·throw("unknown pc");
-			}
-			frame.fn = f;
-			continue;
-		}
-		f = frame.fn;
-		
-		// Found an actual function.
-		// Derive frame pointer and link register.
-		if(frame.fp == 0)
-			frame.fp = frame.sp + runtime·funcspdelta(f, frame.pc);
-		if(runtime·topofstack(f)) {
-			frame.lr = 0;
-			flr = nil;
-		} else if(f->entry == (uintptr)runtime·jmpdefer) {
-			// jmpdefer modifies SP/LR/PC non-atomically.
-			// If a profiling interrupt arrives during jmpdefer,
-			// the stack unwind may see a mismatched register set
-			// and get confused. Stop if we see PC within jmpdefer
-			// to avoid that confusion.
-			// See golang.org/issue/8153.
-			// This check can be deleted if jmpdefer is changed
-			// to restore all three atomically using pop.
-			if(callback != nil)
-				runtime·throw("traceback_arm: found jmpdefer when tracing with callback");
-			frame.lr = 0;
-			flr = nil;
-		} else {
-			if((n == 0 && frame.sp < frame.fp) || frame.lr == 0)
-				frame.lr = *(uintptr*)frame.sp;
-			flr = runtime·findfunc(frame.lr);
-			if(flr == nil) {
-				// This happens if you get a profiling interrupt at just the wrong time.
-				// In that context it is okay to stop early.
-				// But if callback is set, we're doing a garbage collection and must
-				// get everything, so crash loudly.
-				if(callback != nil) {
-					runtime·printf("runtime: unexpected return pc for %s called from %p\n", runtime·funcname(f), frame.lr);
-					runtime·throw("unknown caller pc");
-				}
-			}
-		}
-
-		frame.varp = (byte*)frame.fp;
-
-		// Derive size of arguments.
-		// Most functions have a fixed-size argument block,
-		// so we can use metadata about the function f.
-		// Not all, though: there are some variadic functions
-		// in package runtime and reflect, and for those we use call-specific
-		// metadata recorded by f's caller.
-		if(callback != nil || printing) {
-			frame.argp = (byte*)frame.fp + sizeof(uintptr);
-			if(f->args != ArgsSizeUnknown)
-				frame.arglen = f->args;
-			else if(flr == nil)
-				frame.arglen = 0;
-			else if(frame.lr == (uintptr)runtime·lessstack)
-				frame.arglen = stk->argsize;
-			else if((i = runtime·funcarglen(flr, frame.lr)) >= 0)
-				frame.arglen = i;
-			else {
-				runtime·printf("runtime: unknown argument frame size for %s called from %p [%s]\n",
-					runtime·funcname(f), frame.lr, flr ? runtime·funcname(flr) : "?");
-				if(callback != nil)
-					runtime·throw("invalid stack");
-				frame.arglen = 0;
-			}
-		}
-
-		// Determine function SP where deferproc would find its arguments.
-		// On ARM that's just the standard bottom-of-stack plus 1 word for
-		// the saved LR. If the previous frame was a direct call to newproc/deferproc,
-		// however, the SP is three words lower than normal.
-		// If the function has no frame at all - perhaps it just started, or perhaps
-		// it is a leaf with no local variables - then we cannot possibly find its
-		// SP in a defer, and we might confuse its SP for its caller's SP, so
-		// set sparg=0 in that case.
-		sparg = 0;
-		if(frame.fp != frame.sp) {
-			sparg = frame.sp + sizeof(uintreg);
-			if(wasnewproc)
-				sparg += 3*sizeof(uintreg);
-		}
-
-		// Determine frame's 'continuation PC', where it can continue.
-		// Normally this is the return address on the stack, but if sigpanic
-		// is immediately below this function on the stack, then the frame
-		// stopped executing due to a trap, and frame.pc is probably not
-		// a safe point for looking up liveness information. In this panicking case,
-		// the function either doesn't return at all (if it has no defers or if the
-		// defers do not recover) or it returns from one of the calls to 
-		// deferproc a second time (if the corresponding deferred func recovers).
-		// It suffices to assume that the most recent deferproc is the one that
-		// returns; everything live at earlier deferprocs is still live at that one.
-		frame.continpc = frame.pc;
-		if(waspanic) {
-			if(panic != nil && panic->defer->argp == (byte*)sparg)
-				frame.continpc = (uintptr)panic->defer->pc;
-			else if(defer != nil && defer->argp == (byte*)sparg)
-				frame.continpc = (uintptr)defer->pc;
-			else
-				frame.continpc = 0;
-		}
-
-		// Unwind our local panic & defer stacks past this frame.
-		while(panic != nil && (panic->defer == nil || panic->defer->argp == (byte*)sparg || panic->defer->argp == NoArgs))
-			panic = panic->link;
-		while(defer != nil && (defer->argp == (byte*)sparg || defer->argp == NoArgs))
-			defer = defer->link;	
-
-		if(skip > 0) {
-			skip--;
-			goto skipped;
-		}
-
-		if(pcbuf != nil)
-			pcbuf[n] = frame.pc;
-		if(callback != nil) {
-			if(!callback(&frame, v))
-				return n;
-		}
-		if(printing) {
-			if(printall || runtime·showframe(f, gp)) {
-				// Print during crash.
-				//	main(0x1, 0x2, 0x3)
-				//		/home/rsc/go/src/runtime/x.go:23 +0xf
-				tracepc = frame.pc;	// back up to CALL instruction for funcline.
-				if(n > 0 && frame.pc > f->entry && !waspanic)
-					tracepc -= sizeof(uintptr);
-				runtime·printf("%s(", runtime·funcname(f));
-				for(i = 0; i < frame.arglen/sizeof(uintptr); i++) {
-					if(i >= 10) {
-						runtime·prints(", ...");
-						break;
-					}
-					if(i != 0)
-						runtime·prints(", ");
-					runtime·printhex(((uintptr*)frame.argp)[i]);
-				}
-				runtime·prints(")\n");
-				line = runtime·funcline(f, tracepc, &file);
-				runtime·printf("\t%S:%d", file, line);
-				if(frame.pc > f->entry)
-					runtime·printf(" +%p", (uintptr)(frame.pc - f->entry));
-				if(m->throwing > 0 && gp == m->curg || gotraceback >= 2)
-					runtime·printf(" fp=%p sp=%p", frame.fp, frame.sp);
-				runtime·printf("\n");
-				nprint++;
-			}
-		}
-		n++;
-		
-	skipped:
-		waspanic = f->entry == (uintptr)runtime·sigpanic;
-		wasnewproc = f->entry == (uintptr)runtime·newproc || f->entry == (uintptr)runtime·deferproc;
-
-		// Do not unwind past the bottom of the stack.
-		if(flr == nil)
-			break;
-
-		// Unwind to next frame.
-		frame.pc = frame.lr;
-		frame.fn = flr;
-		frame.lr = 0;
-		frame.sp = frame.fp;
-		frame.fp = 0;
-	
-		// sighandler saves the lr on stack before faking a call to sigpanic
-		if(waspanic) {
-			x = *(uintptr*)frame.sp;
-			frame.sp += 4;
-			frame.fn = f = runtime·findfunc(frame.pc);
-			if(f == nil)
-				frame.pc = x;
-			else if(f->frame == 0)
-				frame.lr = x;
-		}
-	}
-	
-	if(pcbuf == nil && callback == nil)
-		n = nprint;
-
-	// For rationale, see long comment in traceback_x86.c.
-	if(callback != nil && n < max && defer != nil) {
-		if(defer != nil)
-			runtime·printf("runtime: g%D: leftover defer argp=%p pc=%p\n", gp->goid, defer->argp, defer->pc);
-		if(panic != nil)
-			runtime·printf("runtime: g%D: leftover panic argp=%p pc=%p\n", gp->goid, panic->defer->argp, panic->defer->pc);
-		for(defer = gp->defer; defer != nil; defer = defer->link)
-			runtime·printf("\tdefer %p argp=%p pc=%p\n", defer, defer->argp, defer->pc);
-		for(panic = gp->panic; panic != nil; panic = panic->link) {
-			runtime·printf("\tpanic %p defer %p", panic, panic->defer);
-			if(panic->defer != nil)
-				runtime·printf(" argp=%p pc=%p", panic->defer->argp, panic->defer->pc);
-			runtime·printf("\n");
-		}
-		runtime·throw("traceback has leftover defers or panics");
-	}
-
-	return n;		
-}
-
-void
-runtime·printcreatedby(G *gp)
-{
-	int32 line;
-	uintptr pc, tracepc;
-	Func *f;
-	String file;
-
-	// Show what created goroutine, except main goroutine (goid 1).
-	if((pc = gp->gopc) != 0 && (f = runtime·findfunc(pc)) != nil &&
-		runtime·showframe(f, gp) && gp->goid != 1) {
-		runtime·printf("created by %s\n", runtime·funcname(f));
-		tracepc = pc;	// back up to CALL instruction for funcline.
-		if(pc > f->entry)
-			tracepc -= PCQuantum;
-		line = runtime·funcline(f, tracepc, &file);
-		runtime·printf("\t%S:%d", file, line);
-		if(pc > f->entry)
-			runtime·printf(" +%p", (uintptr)(pc - f->entry));
-		runtime·printf("\n");
-	}
-}
-
-void
-runtime·traceback(uintptr pc, uintptr sp, uintptr lr, G *gp)
-{
-	int32 n;
-
-	if(gp->status == Gsyscall) {
-		// Override signal registers if blocked in system call.
-		pc = gp->syscallpc;
-		sp = gp->syscallsp;
-		lr = 0;
-	}
-
-	// Print traceback. By default, omits runtime frames.
-	// If that means we print nothing at all, repeat forcing all frames printed.
-	n = runtime·gentraceback(pc, sp, lr, gp, 0, nil, TracebackMaxFrames, nil, nil, false);
-	if(n == 0)
-		runtime·gentraceback(pc, sp, lr, gp, 0, nil, TracebackMaxFrames, nil, nil, true);
-	if(n == TracebackMaxFrames)
-		runtime·printf("...additional frames elided...\n");
-	runtime·printcreatedby(gp);
-}
-
-// func caller(n int) (pc uintptr, file string, line int, ok bool)
-int32
-runtime·callers(int32 skip, uintptr *pcbuf, int32 m)
-{
-	uintptr pc, sp;
-	
-	sp = runtime·getcallersp(&skip);
-	pc = (uintptr)runtime·getcallerpc(&skip);
-
-	return runtime·gentraceback(pc, sp, 0, g, skip, pcbuf, m, nil, nil, false);
-}
diff --git a/src/pkg/runtime/traceback_x86.c b/src/pkg/runtime/traceback_x86.c
deleted file mode 100644
index 7359cfc..0000000
--- a/src/pkg/runtime/traceback_x86.c
+++ /dev/null
@@ -1,430 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build amd64 amd64p32 386
-
-#include "runtime.h"
-#include "arch_GOARCH.h"
-#include "malloc.h"
-#include "funcdata.h"
-#ifdef GOOS_windows
-#include "defs_GOOS_GOARCH.h"
-#endif
-
-void runtime·sigpanic(void);
-void runtime·newproc(void);
-void runtime·deferproc(void);
-
-#ifdef GOOS_windows
-void runtime·sigtramp(void);
-#endif
-
-// This code is also used for the 386 tracebacks.
-// Use uintptr for an appropriate word-sized integer.
-
-// Generic traceback.  Handles runtime stack prints (pcbuf == nil),
-// the runtime.Callers function (pcbuf != nil), as well as the garbage
-// collector (callback != nil).  A little clunky to merge these, but avoids
-// duplicating the code and all its subtlety.
-int32
-runtime·gentraceback(uintptr pc0, uintptr sp0, uintptr lr0, G *gp, int32 skip, uintptr *pcbuf, int32 max, bool (*callback)(Stkframe*, void*), void *v, bool printall)
-{
-	int32 i, n, nprint, line, gotraceback;
-	uintptr tracepc, sparg;
-	bool waspanic, wasnewproc, printing;
-	Func *f, *flr;
-	Stkframe frame;
-	Stktop *stk;
-	String file;
-	Panic *panic;
-	Defer *defer;
-
-	USED(lr0);
-	
-	gotraceback = runtime·gotraceback(nil);
-	
-	if(pc0 == ~(uintptr)0 && sp0 == ~(uintptr)0) { // Signal to fetch saved values from gp.
-		if(gp->syscallstack != (uintptr)nil) {
-			pc0 = gp->syscallpc;
-			sp0 = gp->syscallsp;
-		} else {
-			pc0 = gp->sched.pc;
-			sp0 = gp->sched.sp;
-		}
-	}
-
-	nprint = 0;
-	runtime·memclr((byte*)&frame, sizeof frame);
-	frame.pc = pc0;
-	frame.sp = sp0;
-	waspanic = false;
-	wasnewproc = false;
-	printing = pcbuf==nil && callback==nil;
-	panic = gp->panic;
-	defer = gp->defer;
-
-	while(defer != nil && defer->argp == NoArgs)
-		defer = defer->link;	
-	while(panic != nil && panic->defer == nil)
-		panic = panic->link;
-
-	// If the PC is zero, it's likely a nil function call.
-	// Start in the caller's frame.
-	if(frame.pc == 0) {
-		frame.pc = *(uintptr*)frame.sp;
-		frame.sp += sizeof(uintreg);
-	}
-	
-	f = runtime·findfunc(frame.pc);
-	if(f == nil) {
-		if(callback != nil) {
-			runtime·printf("runtime: unknown pc %p\n", frame.pc);
-			runtime·throw("unknown pc");
-		}
-		return 0;
-	}
-	frame.fn = f;
-
-	n = 0;
-	stk = (Stktop*)gp->stackbase;
-	while(n < max) {
-		// Typically:
-		//	pc is the PC of the running function.
-		//	sp is the stack pointer at that program counter.
-		//	fp is the frame pointer (caller's stack pointer) at that program counter, or nil if unknown.
-		//	stk is the stack containing sp.
-		//	The caller's program counter is lr, unless lr is zero, in which case it is *(uintptr*)sp.
-	
-		if(frame.pc == (uintptr)runtime·lessstack) {
-			// Hit top of stack segment.  Unwind to next segment.
-			frame.pc = stk->gobuf.pc;
-			frame.sp = stk->gobuf.sp;
-			frame.lr = 0;
-			frame.fp = 0;
-			frame.fn = nil;
-			if(printing && runtime·showframe(nil, gp))
-				runtime·printf("----- stack segment boundary -----\n");
-			stk = (Stktop*)stk->stackbase;
-
-			f = runtime·findfunc(frame.pc);
-			if(f == nil) {
-				runtime·printf("runtime: unknown pc %p after stack split\n", frame.pc);
-				if(callback != nil)
-					runtime·throw("unknown pc");
-			}
-			frame.fn = f;
-			continue;
-		}
-		
-		f = frame.fn;
-
-#ifdef GOOS_windows
-		// Windows exception handlers run on the actual g stack (there is room
-		// dedicated to this below the usual "bottom of stack"), not on a separate
-		// stack. As a result, we have to be able to unwind past the exception
-		// handler when called to unwind during stack growth inside the handler.
-		// Recognize the frame at the call to sighandler in sigtramp and unwind
-		// using the context argument passed to the call. This is awful.
-		if(f != nil && f->entry == (uintptr)runtime·sigtramp && frame.pc > f->entry) {
-			Context *r;
-			
-			// Invoke callback so that stack copier sees an uncopyable frame.
-			if(callback != nil) {
-				frame.continpc = frame.pc;
-				frame.argp = nil;
-				frame.arglen = 0;
-				if(!callback(&frame, v))
-					return n;
-			}
-			r = (Context*)((uintptr*)frame.sp)[1];
-#ifdef GOARCH_amd64
-			frame.pc = r->Rip;
-			frame.sp = r->Rsp;
-#else
-			frame.pc = r->Eip;
-			frame.sp = r->Esp;
-#endif
-			frame.lr = 0;
-			frame.fp = 0;
-			frame.fn = nil;
-			if(printing && runtime·showframe(nil, gp))
-				runtime·printf("----- exception handler -----\n");
-			f = runtime·findfunc(frame.pc);
-			if(f == nil) {
-				runtime·printf("runtime: unknown pc %p after exception handler\n", frame.pc);
-				if(callback != nil)
-					runtime·throw("unknown pc");
-			}
-			frame.fn = f;
-			continue;
-		}
-#endif
-
-		// Found an actual function.
-		// Derive frame pointer and link register.
-		if(frame.fp == 0) {
-			frame.fp = frame.sp + runtime·funcspdelta(f, frame.pc);
-			frame.fp += sizeof(uintreg); // caller PC
-		}
-		if(runtime·topofstack(f)) {
-			frame.lr = 0;
-			flr = nil;
-		} else {
-			if(frame.lr == 0)
-				frame.lr = ((uintreg*)frame.fp)[-1];
-			flr = runtime·findfunc(frame.lr);
-			if(flr == nil) {
-				runtime·printf("runtime: unexpected return pc for %s called from %p\n", runtime·funcname(f), frame.lr);
-				if(callback != nil)
-					runtime·throw("unknown caller pc");
-			}
-		}
-		
-		frame.varp = (byte*)frame.fp - sizeof(uintreg);
-
-		// Derive size of arguments.
-		// Most functions have a fixed-size argument block,
-		// so we can use metadata about the function f.
-		// Not all, though: there are some variadic functions
-		// in package runtime and reflect, and for those we use call-specific
-		// metadata recorded by f's caller.
-		if(callback != nil || printing) {
-			frame.argp = (byte*)frame.fp;
-			if(f->args != ArgsSizeUnknown)
-				frame.arglen = f->args;
-			else if(flr == nil)
-				frame.arglen = 0;
-			else if(frame.lr == (uintptr)runtime·lessstack)
-				frame.arglen = stk->argsize;
-			else if((i = runtime·funcarglen(flr, frame.lr)) >= 0)
-				frame.arglen = i;
-			else {
-				runtime·printf("runtime: unknown argument frame size for %s called from %p [%s]\n",
-					runtime·funcname(f), frame.lr, flr ? runtime·funcname(flr) : "?");
-				if(callback != nil)
-					runtime·throw("invalid stack");
-				frame.arglen = 0;
-			}
-		}
-		
-		// Determine function SP where deferproc would find its arguments.
-		// On x86 that's just the standard bottom-of-stack, so SP exactly.
-		// If the previous frame was a direct call to newproc/deferproc, however,
-		// the SP is two words lower than normal.
-		sparg = frame.sp;
-		if(wasnewproc)
-			sparg += 2*sizeof(uintptr);
-
-		// Determine frame's 'continuation PC', where it can continue.
-		// Normally this is the return address on the stack, but if sigpanic
-		// is immediately below this function on the stack, then the frame
-		// stopped executing due to a trap, and frame.pc is probably not
-		// a safe point for looking up liveness information. In this panicking case,
-		// the function either doesn't return at all (if it has no defers or if the
-		// defers do not recover) or it returns from one of the calls to 
-		// deferproc a second time (if the corresponding deferred func recovers).
-		// It suffices to assume that the most recent deferproc is the one that
-		// returns; everything live at earlier deferprocs is still live at that one.
-		frame.continpc = frame.pc;
-		if(waspanic) {
-			if(panic != nil && panic->defer->argp == (byte*)sparg)
-				frame.continpc = (uintptr)panic->defer->pc;
-			else if(defer != nil && defer->argp == (byte*)sparg)
-				frame.continpc = (uintptr)defer->pc;
-			else
-				frame.continpc = 0;
-		}
-
-		// Unwind our local panic & defer stacks past this frame.
-		while(panic != nil && (panic->defer == nil || panic->defer->argp == (byte*)sparg || panic->defer->argp == NoArgs))
-			panic = panic->link;
-		while(defer != nil && (defer->argp == (byte*)sparg || defer->argp == NoArgs))
-			defer = defer->link;	
-
-		if(skip > 0) {
-			skip--;
-			goto skipped;
-		}
-
-		if(pcbuf != nil)
-			pcbuf[n] = frame.pc;
-		if(callback != nil) {
-			if(!callback(&frame, v))
-				return n;
-		}
-		if(printing) {
-			if(printall || runtime·showframe(f, gp)) {
-				// Print during crash.
-				//	main(0x1, 0x2, 0x3)
-				//		/home/rsc/go/src/runtime/x.go:23 +0xf
-				//		
-				tracepc = frame.pc;	// back up to CALL instruction for funcline.
-				if(n > 0 && frame.pc > f->entry && !waspanic)
-					tracepc--;
-				runtime·printf("%s(", runtime·funcname(f));
-				for(i = 0; i < frame.arglen/sizeof(uintptr); i++) {
-					if(i >= 10) {
-						runtime·prints(", ...");
-						break;
-					}
-					if(i != 0)
-						runtime·prints(", ");
-					runtime·printhex(((uintptr*)frame.argp)[i]);
-				}
-				runtime·prints(")\n");
-				line = runtime·funcline(f, tracepc, &file);
-				runtime·printf("\t%S:%d", file, line);
-				if(frame.pc > f->entry)
-					runtime·printf(" +%p", (uintptr)(frame.pc - f->entry));
-				if(m->throwing > 0 && gp == m->curg || gotraceback >= 2)
-					runtime·printf(" fp=%p sp=%p", frame.fp, frame.sp);
-				runtime·printf("\n");
-				nprint++;
-			}
-		}
-		n++;
-	
-	skipped:
-		waspanic = f->entry == (uintptr)runtime·sigpanic;
-		wasnewproc = f->entry == (uintptr)runtime·newproc || f->entry == (uintptr)runtime·deferproc;
-
-		// Do not unwind past the bottom of the stack.
-		if(flr == nil)
-			break;
-
-		// Unwind to next frame.
-		frame.fn = flr;
-		frame.pc = frame.lr;
-		frame.lr = 0;
-		frame.sp = frame.fp;
-		frame.fp = 0;
-	}
-	
-	if(pcbuf == nil && callback == nil)
-		n = nprint;
-
-	// If callback != nil, we're being called to gather stack information during
-	// garbage collection or stack growth. In that context, require that we used
-	// up the entire defer stack. If not, then there is a bug somewhere and the
-	// garbage collection or stack growth may not have seen the correct picture
-	// of the stack. Crash now instead of silently executing the garbage collection
-	// or stack copy incorrectly and setting up for a mysterious crash later.
-	//
-	// Note that panic != nil is okay here: there can be leftover panics,
-	// because the defers on the panic stack do not nest in frame order as
-	// they do on the defer stack. If you have:
-	//
-	//	frame 1 defers d1
-	//	frame 2 defers d2
-	//	frame 3 defers d3
-	//	frame 4 panics
-	//	frame 4's panic starts running defers
-	//	frame 5, running d3, defers d4
-	//	frame 5 panics
-	//	frame 5's panic starts running defers
-	//	frame 6, running d4, garbage collects
-	//	frame 6, running d2, garbage collects
-	//
-	// During the execution of d4, the panic stack is d4 -> d3, which
-	// is nested properly, and we'll treat frame 3 as resumable, because we
-	// can find d3. (And in fact frame 3 is resumable. If d4 recovers
-	// and frame 5 continues running, d3, d3 can recover and we'll
-	// resume execution in (returning from) frame 3.)
-	//
-	// During the execution of d2, however, the panic stack is d2 -> d3,
-	// which is inverted. The scan will match d2 to frame 2 but having
-	// d2 on the stack until then means it will not match d3 to frame 3.
-	// This is okay: if we're running d2, then all the defers after d2 have
-	// completed and their corresponding frames are dead. Not finding d3
-	// for frame 3 means we'll set frame 3's continpc == 0, which is correct
-	// (frame 3 is dead). At the end of the walk the panic stack can thus
-	// contain defers (d3 in this case) for dead frames. The inversion here
-	// always indicates a dead frame, and the effect of the inversion on the
-	// scan is to hide those dead frames, so the scan is still okay:
-	// what's left on the panic stack are exactly (and only) the dead frames.
-	//
-	// We require callback != nil here because only when callback != nil
-	// do we know that gentraceback is being called in a "must be correct"
-	// context as opposed to a "best effort" context. The tracebacks with
-	// callbacks only happen when everything is stopped nicely.
-	// At other times, such as when gathering a stack for a profiling signal
-	// or when printing a traceback during a crash, everything may not be
-	// stopped nicely, and the stack walk may not be able to complete.
-	// It's okay in those situations not to use up the entire defer stack:
-	// incomplete information then is still better than nothing.
-	if(callback != nil && n < max && defer != nil) {
-		if(defer != nil)
-			runtime·printf("runtime: g%D: leftover defer argp=%p pc=%p\n", gp->goid, defer->argp, defer->pc);
-		if(panic != nil)
-			runtime·printf("runtime: g%D: leftover panic argp=%p pc=%p\n", gp->goid, panic->defer->argp, panic->defer->pc);
-		for(defer = gp->defer; defer != nil; defer = defer->link)
-			runtime·printf("\tdefer %p argp=%p pc=%p\n", defer, defer->argp, defer->pc);
-		for(panic = gp->panic; panic != nil; panic = panic->link) {
-			runtime·printf("\tpanic %p defer %p", panic, panic->defer);
-			if(panic->defer != nil)
-				runtime·printf(" argp=%p pc=%p", panic->defer->argp, panic->defer->pc);
-			runtime·printf("\n");
-		}
-		runtime·throw("traceback has leftover defers or panics");
-	}
-
-	return n;
-}
-
-void
-runtime·printcreatedby(G *gp)
-{
-	int32 line;
-	uintptr pc, tracepc;
-	Func *f;
-	String file;
-
-	// Show what created goroutine, except main goroutine (goid 1).
-	if((pc = gp->gopc) != 0 && (f = runtime·findfunc(pc)) != nil &&
-		runtime·showframe(f, gp) && gp->goid != 1) {
-		runtime·printf("created by %s\n", runtime·funcname(f));
-		tracepc = pc;	// back up to CALL instruction for funcline.
-		if(pc > f->entry)
-			tracepc -= PCQuantum;
-		line = runtime·funcline(f, tracepc, &file);
-		runtime·printf("\t%S:%d", file, line);
-		if(pc > f->entry)
-			runtime·printf(" +%p", (uintptr)(pc - f->entry));
-		runtime·printf("\n");
-	}
-}
-
-void
-runtime·traceback(uintptr pc, uintptr sp, uintptr lr, G *gp)
-{
-	int32 n;
-
-	USED(lr);
-
-	if(gp->status == Gsyscall) {
-		// Override signal registers if blocked in system call.
-		pc = gp->syscallpc;
-		sp = gp->syscallsp;
-	}
-	
-	// Print traceback. By default, omits runtime frames.
-	// If that means we print nothing at all, repeat forcing all frames printed.
-	n = runtime·gentraceback(pc, sp, 0, gp, 0, nil, TracebackMaxFrames, nil, nil, false);
-	if(n == 0)
-		n = runtime·gentraceback(pc, sp, 0, gp, 0, nil, TracebackMaxFrames, nil, nil, true);
-	if(n == TracebackMaxFrames)
-		runtime·printf("...additional frames elided...\n");
-	runtime·printcreatedby(gp);
-}
-
-int32
-runtime·callers(int32 skip, uintptr *pcbuf, int32 m)
-{
-	uintptr pc, sp;
-
-	sp = runtime·getcallersp(&skip);
-	pc = (uintptr)runtime·getcallerpc(&skip);
-
-	return runtime·gentraceback(pc, sp, 0, g, skip, pcbuf, m, nil, nil, false);
-}
diff --git a/src/pkg/runtime/type.go b/src/pkg/runtime/type.go
deleted file mode 100644
index 276dbc0..0000000
--- a/src/pkg/runtime/type.go
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-/*
- * Runtime type representation.
- * This file exists only to provide types that 6l can turn into
- * DWARF information for use by gdb.  Nothing else uses these.
- * They should match the same types in ../reflect/type.go.
- * For comments see ../reflect/type.go.
- */
-
-package runtime
-
-import "unsafe"
-
-type rtype struct {
-	size       uintptr
-	hash       uint32
-	_          uint8
-	align      uint8
-	fieldAlign uint8
-	kind       uint8
-	alg        unsafe.Pointer
-	gc         unsafe.Pointer
-	string     *string
-	*uncommonType
-	ptrToThis *rtype
-	zero      unsafe.Pointer
-}
-
-type _method struct {
-	name    *string
-	pkgPath *string
-	mtyp    *rtype
-	typ     *rtype
-	ifn     unsafe.Pointer
-	tfn     unsafe.Pointer
-}
-
-type uncommonType struct {
-	name    *string
-	pkgPath *string
-	methods []_method
-}
-
-type _imethod struct {
-	name    *string
-	pkgPath *string
-	typ     *rtype
-}
-
-type interfaceType struct {
-	rtype
-	methods []_imethod
-}
diff --git a/src/pkg/runtime/type.h b/src/pkg/runtime/type.h
deleted file mode 100644
index 1598acc..0000000
--- a/src/pkg/runtime/type.h
+++ /dev/null
@@ -1,102 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-/*
- * Runtime type representation; master is type.go
- *
- * The Type*s here correspond 1-1 to type.go's *rtype.
- */
-
-typedef struct Type Type;
-typedef struct UncommonType UncommonType;
-typedef struct InterfaceType InterfaceType;
-typedef struct Method Method;
-typedef struct IMethod IMethod;
-typedef struct SliceType SliceType;
-typedef struct FuncType FuncType;
-
-// Needs to be in sync with ../../cmd/ld/decodesym.c:/^commonsize
-struct Type
-{
-	uintptr size;
-	uint32 hash;
-	uint8 _unused;
-	uint8 align;
-	uint8 fieldAlign;
-	uint8 kind;
-	Alg *alg;
-	void *gc;
-	String *string;
-	UncommonType *x;
-	Type *ptrto;
-	byte *zero;  // ptr to the zero value for this type
-};
-
-struct Method
-{
-	String *name;
-	String *pkgPath;
-	Type	*mtyp;
-	Type *typ;
-	void (*ifn)(void);
-	void (*tfn)(void);
-};
-
-struct UncommonType
-{
-	String *name;
-	String *pkgPath;
-	Slice mhdr;
-	Method m[];
-};
-
-struct IMethod
-{
-	String *name;
-	String *pkgPath;
-	Type *type;
-};
-
-struct InterfaceType
-{
-	Type;
-	Slice mhdr;
-	IMethod m[];
-};
-
-struct MapType
-{
-	Type;
-	Type *key;
-	Type *elem;
-	Type *bucket; // internal type representing a hash bucket
-	Type *hmap;   // internal type representing a Hmap
-};
-
-struct ChanType
-{
-	Type;
-	Type *elem;
-	uintptr dir;
-};
-
-struct SliceType
-{
-	Type;
-	Type *elem;
-};
-
-struct FuncType
-{
-	Type;
-	bool dotdotdot;
-	Slice in;
-	Slice out;
-};
-
-struct PtrType
-{
-	Type;
-	Type *elem;
-};
diff --git a/src/pkg/runtime/typekind.h b/src/pkg/runtime/typekind.h
deleted file mode 100644
index 3f0ba9a..0000000
--- a/src/pkg/runtime/typekind.h
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// PtrSize vs sizeof(void*): This file is also included from src/cmd/ld/...
-// which defines PtrSize to be different from sizeof(void*) when crosscompiling.
-
-enum {
-	KindBool = 1,
-	KindInt,
-	KindInt8,
-	KindInt16,
-	KindInt32,
-	KindInt64,
-	KindUint,
-	KindUint8,
-	KindUint16,
-	KindUint32,
-	KindUint64,
-	KindUintptr,
-	KindFloat32,
-	KindFloat64,
-	KindComplex64,
-	KindComplex128,
-	KindArray,
-	KindChan,
-	KindFunc,
-	KindInterface,
-	KindMap,
-	KindPtr,
-	KindSlice,
-	KindString,
-	KindStruct,
-	KindUnsafePointer,
-
-	KindNoPointers = 1<<7,
-};
-
diff --git a/src/pkg/runtime/vdso_linux_amd64.c b/src/pkg/runtime/vdso_linux_amd64.c
deleted file mode 100644
index f55d312..0000000
--- a/src/pkg/runtime/vdso_linux_amd64.c
+++ /dev/null
@@ -1,337 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "runtime.h"
-
-#define AT_RANDOM 25
-#define AT_SYSINFO_EHDR 33
-#define AT_NULL	0    /* End of vector */
-#define PT_LOAD	1    /* Loadable program segment */
-#define PT_DYNAMIC 2 /* Dynamic linking information */
-#define DT_NULL 0    /* Marks end of dynamic section */
-#define DT_STRTAB 5  /* Address of string table */
-#define DT_SYMTAB 6  /* Address of symbol table */
-#define DT_VERSYM 0x6ffffff0
-#define	DT_VERDEF 0x6ffffffc
-
-#define VER_FLG_BASE 0x1 /* Version definition of file itself */
-#define SHN_UNDEF 0      /* Undefined section */
-#define SHT_DYNSYM 11    /* Dynamic linker symbol table */
-#define STT_FUNC 2       /* Symbol is a code object */
-#define STB_GLOBAL 1     /* Global symbol */
-#define STB_WEAK 2       /* Weak symbol */
-
-/* How to extract and insert information held in the st_info field.  */
-#define ELF64_ST_BIND(val) (((byte) (val)) >> 4)
-#define ELF64_ST_TYPE(val) ((val) & 0xf)
-
-#define EI_NIDENT (16)
-
-typedef uint16 Elf64_Half;
-typedef uint32 Elf64_Word;
-typedef	int32  Elf64_Sword;
-typedef uint64 Elf64_Xword;
-typedef	int64  Elf64_Sxword;
-typedef uint64 Elf64_Addr;
-typedef uint64 Elf64_Off;
-typedef uint16 Elf64_Section;
-typedef Elf64_Half Elf64_Versym;
-
-
-typedef struct
-{
-	Elf64_Word st_name;
-	byte st_info;
-	byte st_other;
-	Elf64_Section st_shndx;
-	Elf64_Addr st_value;
-	Elf64_Xword st_size;
-} Elf64_Sym;
-
-typedef struct
-{
-	Elf64_Half vd_version; /* Version revision */
-	Elf64_Half vd_flags;   /* Version information */
-	Elf64_Half vd_ndx;     /* Version Index */
-	Elf64_Half vd_cnt;     /* Number of associated aux entries */
-	Elf64_Word vd_hash;    /* Version name hash value */
-	Elf64_Word vd_aux;     /* Offset in bytes to verdaux array */
-	Elf64_Word vd_next;    /* Offset in bytes to next verdef entry */
-} Elf64_Verdef;
-
-typedef struct
-{
-	byte e_ident[EI_NIDENT]; /* Magic number and other info */
-	Elf64_Half e_type;       /* Object file type */
-	Elf64_Half e_machine;    /* Architecture */
-	Elf64_Word e_version;    /* Object file version */
-	Elf64_Addr e_entry;      /* Entry point virtual address */
-	Elf64_Off e_phoff;       /* Program header table file offset */
-	Elf64_Off e_shoff;       /* Section header table file offset */
-	Elf64_Word e_flags;      /* Processor-specific flags */
-	Elf64_Half e_ehsize;     /* ELF header size in bytes */
-	Elf64_Half e_phentsize;  /* Program header table entry size */
-	Elf64_Half e_phnum;      /* Program header table entry count */
-	Elf64_Half e_shentsize;  /* Section header table entry size */
-	Elf64_Half e_shnum;      /* Section header table entry count */
-	Elf64_Half e_shstrndx;   /* Section header string table index */
-} Elf64_Ehdr;
-
-typedef struct
-{
-	Elf64_Word p_type;    /* Segment type */
-	Elf64_Word p_flags;   /* Segment flags */
-	Elf64_Off p_offset;   /* Segment file offset */
-	Elf64_Addr p_vaddr;   /* Segment virtual address */
-	Elf64_Addr p_paddr;   /* Segment physical address */
-	Elf64_Xword p_filesz; /* Segment size in file */
-	Elf64_Xword p_memsz;  /* Segment size in memory */
-	Elf64_Xword p_align;  /* Segment alignment */
-} Elf64_Phdr;
-
-typedef struct
-{
-	Elf64_Word sh_name;       /* Section name (string tbl index) */
-	Elf64_Word sh_type;       /* Section type */
-	Elf64_Xword sh_flags;     /* Section flags */
-	Elf64_Addr sh_addr;       /* Section virtual addr at execution */
-	Elf64_Off sh_offset;      /* Section file offset */
-	Elf64_Xword sh_size;      /* Section size in bytes */
-	Elf64_Word sh_link;       /* Link to another section */
-	Elf64_Word sh_info;       /* Additional section information */
-	Elf64_Xword sh_addralign; /* Section alignment */
-	Elf64_Xword sh_entsize;   /* Entry size if section holds table */
-} Elf64_Shdr;
-
-typedef struct
-{
-	Elf64_Sxword d_tag; /* Dynamic entry type */
-	union
-	{
-		Elf64_Xword d_val;  /* Integer value */
-		Elf64_Addr d_ptr;   /* Address value */
-	} d_un;
-} Elf64_Dyn;
-
-typedef struct
-{
-	Elf64_Word vda_name; /* Version or dependency names */
-	Elf64_Word vda_next; /* Offset in bytes to next verdaux entry */
-} Elf64_Verdaux;
-
-typedef struct
-{
-	uint64 a_type;        /* Entry type */
-	union
-	{
-		uint64 a_val; /* Integer value */
-	} a_un;
-} Elf64_auxv_t;
-
-
-typedef struct {
-	byte* name;
-	void** var_ptr;
-} symbol_key;
-
-typedef struct {
-	byte* version;
-	int32 ver_hash;
-} version_key;
-
-struct vdso_info {
-	bool valid;
-
-	/* Load information */
-	uintptr load_addr;
-	uintptr load_offset;  /* load_addr - recorded vaddr */
-
-	/* Symbol table */
-	int32 num_sym;
-	Elf64_Sym *symtab;
-	const byte *symstrings;
-
-	/* Version table */
-	Elf64_Versym *versym;
-	Elf64_Verdef *verdef;
-};
-
-static version_key linux26 = { (byte*)"LINUX_2.6", 0x3ae75f6 };
-
-// initialize with vsyscall fallbacks
-void* runtime·__vdso_time_sym = (void*)0xffffffffff600400ULL;
-void* runtime·__vdso_gettimeofday_sym = (void*)0xffffffffff600000ULL;
-void* runtime·__vdso_clock_gettime_sym = (void*)0;
-
-#define SYM_KEYS_COUNT 3
-static symbol_key sym_keys[] = {
-	{ (byte*)"__vdso_time", &runtime·__vdso_time_sym },
-	{ (byte*)"__vdso_gettimeofday", &runtime·__vdso_gettimeofday_sym },
-	{ (byte*)"__vdso_clock_gettime", &runtime·__vdso_clock_gettime_sym },
-};
-
-static void
-vdso_init_from_sysinfo_ehdr(struct vdso_info *vdso_info, Elf64_Ehdr* hdr)
-{
-	uint64 i;
-	bool found_vaddr = false;
-
-	vdso_info->load_addr = (uintptr) hdr;
-
-	Elf64_Phdr *pt = (Elf64_Phdr*)(vdso_info->load_addr + hdr->e_phoff);
-	Elf64_Shdr *sh = (Elf64_Shdr*)(vdso_info->load_addr + hdr->e_shoff);
-	Elf64_Dyn *dyn = 0;
-
-	for(i=0; i<hdr->e_shnum; i++) {
-		if(sh[i].sh_type == SHT_DYNSYM) {
-			vdso_info->num_sym = sh[i].sh_size / sizeof(Elf64_Sym);
-		}
-	}
-
-	// We need two things from the segment table: the load offset
-	// and the dynamic table.
-	for(i=0; i<hdr->e_phnum; i++) {
-		if(pt[i].p_type == PT_LOAD && found_vaddr == false) {
-			found_vaddr = true;
-			vdso_info->load_offset =	(uintptr)hdr
-				+ (uintptr)pt[i].p_offset
-				- (uintptr)pt[i].p_vaddr;
-		} else if(pt[i].p_type == PT_DYNAMIC) {
-			dyn = (Elf64_Dyn*)((uintptr)hdr + pt[i].p_offset);
-		}
-	}
-
-	if(found_vaddr == false || dyn == nil)
-		return;  // Failed
-
-	// Fish out the useful bits of the dynamic table.
-	for(i=0; dyn[i].d_tag!=DT_NULL; i++) {
-		switch(dyn[i].d_tag) {
-		case DT_STRTAB:
-			vdso_info->symstrings = (const byte *)
-				((uintptr)dyn[i].d_un.d_ptr
-				 + vdso_info->load_offset);
-			break;
-		case DT_SYMTAB:
-			vdso_info->symtab = (Elf64_Sym *)
-				((uintptr)dyn[i].d_un.d_ptr
-				 + vdso_info->load_offset);
-			break;
-		case DT_VERSYM:
-			vdso_info->versym = (Elf64_Versym *)
-				((uintptr)dyn[i].d_un.d_ptr
-				 + vdso_info->load_offset);
-			break;
-		case DT_VERDEF:
-			vdso_info->verdef = (Elf64_Verdef *)
-				((uintptr)dyn[i].d_un.d_ptr
-				 + vdso_info->load_offset);
-			break;
-		}
-	}
-	if(vdso_info->symstrings == nil || vdso_info->symtab == nil)
-		return;  // Failed
-
-	if(vdso_info->verdef == nil)
-		vdso_info->versym = 0;
-
-	// That's all we need.
-	vdso_info->valid = true;
-}
-
-static int32
-vdso_find_version(struct vdso_info *vdso_info, version_key* ver)
-{
-	if(vdso_info->valid == false) {
-		return 0;
-	}
-	Elf64_Verdef *def = vdso_info->verdef;
-	while(true) {
-		if((def->vd_flags & VER_FLG_BASE) == 0) {
-			Elf64_Verdaux *aux = (Elf64_Verdaux*)((byte *)def + def->vd_aux);
-			if(def->vd_hash == ver->ver_hash &&
-				runtime·strcmp(ver->version, vdso_info->symstrings + aux->vda_name) == 0) {
-				return def->vd_ndx & 0x7fff;
-			}
-		}
-
-		if(def->vd_next == 0) {
-			break;
-		}
-		def = (Elf64_Verdef *)((byte *)def + def->vd_next);
-	}
-	return 0;
-}
-
-static void
-vdso_parse_symbols(struct vdso_info *vdso_info, int32 version)
-{
-	int32 i, j;
-
-	if(vdso_info->valid == false)
-		return;
-
-	for(i=0; i<vdso_info->num_sym; i++) {
-		Elf64_Sym *sym = &vdso_info->symtab[i];
-
-		// Check for a defined global or weak function w/ right name.
-		if(ELF64_ST_TYPE(sym->st_info) != STT_FUNC)
-			continue;
-		if(ELF64_ST_BIND(sym->st_info) != STB_GLOBAL &&
-			ELF64_ST_BIND(sym->st_info) != STB_WEAK)
-			continue;
-		if(sym->st_shndx == SHN_UNDEF)
-			continue;
-
-		for(j=0; j<SYM_KEYS_COUNT; j++) {
-			if(runtime·strcmp(sym_keys[j].name, vdso_info->symstrings + sym->st_name) != 0)
-				continue;
-
-			// Check symbol version.
-			if(vdso_info->versym != nil && version != 0
-				&& vdso_info->versym[i] & 0x7fff != version)
-				continue;
-
-			*sym_keys[j].var_ptr = (void *)(vdso_info->load_offset + sym->st_value);
-		}
-	}
-}
-
-static void
-runtime·linux_setup_vdso(int32 argc, uint8** argv)
-{
-	struct vdso_info vdso_info;
-
-	// skip argvc
-	byte **p = argv;
-	p = &p[argc+1];
-
-	// skip envp to get to ELF auxiliary vector.
-	for(; *p!=0; p++) {}
-
-	// skip NULL separator
-	p++;
-
-	// now, p points to auxv
-	Elf64_auxv_t *elf_auxv = (Elf64_auxv_t*) p;
-
-	for(int32 i=0; elf_auxv[i].a_type!=AT_NULL; i++) {
-		if(elf_auxv[i].a_type == AT_SYSINFO_EHDR) {
-			if(elf_auxv[i].a_un.a_val == 0) {
-				// Something went wrong
-				continue;
-			}
-			vdso_init_from_sysinfo_ehdr(&vdso_info, (Elf64_Ehdr*)elf_auxv[i].a_un.a_val);
-			vdso_parse_symbols(&vdso_info, vdso_find_version(&vdso_info, &linux26));
-			continue;
-		}
-		if(elf_auxv[i].a_type == AT_RANDOM) {
-		        runtime·startup_random_data = (byte*)elf_auxv[i].a_un.a_val;
-		        runtime·startup_random_data_len = 16;
-			continue;
-		}
-	}
-}
-
-void (*runtime·sysargs)(int32, uint8**) = runtime·linux_setup_vdso;
diff --git a/src/pkg/runtime/vlop_386.s b/src/pkg/runtime/vlop_386.s
deleted file mode 100644
index 9783fdc..0000000
--- a/src/pkg/runtime/vlop_386.s
+++ /dev/null
@@ -1,54 +0,0 @@
-// Inferno's libkern/vlop-386.s
-// http://code.google.com/p/inferno-os/source/browse/libkern/vlop-386.s
-//
-//         Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//         Revisions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com).  All rights reserved.
-//         Portions Copyright 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-#include "../../cmd/ld/textflag.h"
-
-/*
- * C runtime for 64-bit divide.
- */
-
-// _mul64x32(r *uint64, a uint64, b uint32)
-// sets *r = low 64 bits of 96-bit product a*b; returns high 32 bits.
-TEXT _mul64by32(SB), NOSPLIT, $0
-	MOVL	r+0(FP), CX
-	MOVL	a+4(FP), AX
-	MULL	b+12(FP)
-	MOVL	AX, 0(CX)
-	MOVL	DX, BX
-	MOVL	a+8(FP), AX
-	MULL	b+12(FP)
-	ADDL	AX, BX
-	ADCL	$0, DX
-	MOVL	BX, 4(CX)
-	MOVL	DX, AX
-	RET
-
-TEXT _div64by32(SB), NOSPLIT, $0
-	MOVL	r+12(FP), CX
-	MOVL	a+0(FP), AX
-	MOVL	a+4(FP), DX
-	DIVL	b+8(FP)
-	MOVL	DX, 0(CX)
-	RET
diff --git a/src/pkg/runtime/vlop_arm.s b/src/pkg/runtime/vlop_arm.s
deleted file mode 100644
index 80f516e..0000000
--- a/src/pkg/runtime/vlop_arm.s
+++ /dev/null
@@ -1,300 +0,0 @@
-// Inferno's libkern/vlop-arm.s
-// http://code.google.com/p/inferno-os/source/browse/libkern/vlop-arm.s
-//
-//         Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//         Revisions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com).  All rights reserved.
-//         Portions Copyright 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-#include "zasm_GOOS_GOARCH.h"
-#include "../../cmd/ld/textflag.h"
-
-arg=0
-
-/* replaced use of R10 by R11 because the former can be the data segment base register */
-
-TEXT _mulv(SB), NOSPLIT, $0
-	MOVW	0(FP), R0
-	MOVW	4(FP), R2	/* l0 */
-	MOVW	8(FP), R11	/* h0 */
-	MOVW	12(FP), R4	/* l1 */
-	MOVW	16(FP), R5	/* h1 */
-	MULLU	R4, R2, (R7,R6)
-	MUL	R11, R4, R8
-	ADD	R8, R7
-	MUL	R2, R5, R8
-	ADD	R8, R7
-	MOVW	R6, 0(R(arg))
-	MOVW	R7, 4(R(arg))
-	RET
-
-// trampoline for _sfloat2. passes LR as arg0 and
-// saves registers R0-R13 and CPSR on the stack. R0-R12 and CPSR flags can
-// be changed by _sfloat2.
-TEXT _sfloat(SB), NOSPLIT, $64-0 // 4 arg + 14*4 saved regs + cpsr
-	MOVW	R14, 4(R13)
-	MOVW	R0, 8(R13)
-	MOVW	$12(R13), R0
-	MOVM.IA.W	[R1-R12], (R0)
-	MOVW	$68(R13), R1 // correct for frame size
-	MOVW	R1, 60(R13)
-	WORD	$0xe10f1000 // mrs r1, cpsr
-	MOVW	R1, 64(R13)
-	// Disable preemption of this goroutine during _sfloat2 by
-	// m->locks++ and m->locks-- around the call.
-	// Rescheduling this goroutine may cause the loss of the
-	// contents of the software floating point registers in 
-	// m->freghi, m->freglo, m->fflag, if the goroutine is moved
-	// to a different m or another goroutine runs on this m.
-	// Rescheduling at ordinary function calls is okay because
-	// all registers are caller save, but _sfloat2 and the things
-	// that it runs are simulating the execution of individual
-	// program instructions, and those instructions do not expect
-	// the floating point registers to be lost.
-	// An alternative would be to move the software floating point
-	// registers into G, but they do not need to be kept at the 
-	// usual places a goroutine reschedules (at function calls),
-	// so it would be a waste of 132 bytes per G.
-	MOVW	m_locks(m), R1
-	ADD	$1, R1
-	MOVW	R1, m_locks(m)
-	MOVW	$1, R1
-	MOVW	R1, m_softfloat(m)
-	BL	runtime·_sfloat2(SB)
-	MOVW	m_locks(m), R1
-	SUB	$1, R1
-	MOVW	R1, m_locks(m)
-	MOVW	$0, R1
-	MOVW	R1, m_softfloat(m)
-	MOVW	R0, 0(R13)
-	MOVW	64(R13), R1
-	WORD	$0xe128f001	// msr cpsr_f, r1
-	MOVW	$12(R13), R0
-	// Restore R1-R8 and R11-R12, but ignore the saved R9 (m) and R10 (g).
-	// Both are maintained by the runtime and always have correct values,
-	// so there is no need to restore old values here.
-	// The g should not have changed, but m may have, if we were preempted
-	// and restarted on a different thread, in which case restoring the old
-	// value is incorrect and will cause serious confusion in the runtime.
-	MOVM.IA.W	(R0), [R1-R8]
-	MOVW	$52(R13), R0
-	MOVM.IA.W	(R0), [R11-R12]
-	MOVW	8(R13), R0
-	RET
-
-// func udiv(n, d uint32) (q, r uint32)
-// Reference: 
-// Sloss, Andrew et. al; ARM System Developer's Guide: Designing and Optimizing System Software
-// Morgan Kaufmann; 1 edition (April 8, 2004), ISBN 978-1558608740
-q = 0 // input d, output q
-r = 1 // input n, output r
-s = 2 // three temporary variables
-M = 3
-a = 11
-// Be careful: R(a) == R11 will be used by the linker for synthesized instructions.
-TEXT udiv<>(SB),NOSPLIT,$-4
-	CLZ 	R(q), R(s) // find normalizing shift
-	MOVW.S	R(q)<<R(s), R(a)
-	MOVW	$fast_udiv_tab<>-64(SB), R(M)
-	MOVBU.NE	R(a)>>25(R(M)), R(a) // index by most significant 7 bits of divisor
-
-	SUB.S	$7, R(s)
-	RSB 	$0, R(q), R(M) // M = -q
-	MOVW.PL	R(a)<<R(s), R(q)
-
-	// 1st Newton iteration
-	MUL.PL	R(M), R(q), R(a) // a = -q*d
-	BMI 	udiv_by_large_d
-	MULAWT	R(a), R(q), R(q), R(q) // q approx q-(q*q*d>>32)
-	TEQ 	R(M)->1, R(M) // check for d=0 or d=1
-
-	// 2nd Newton iteration
-	MUL.NE	R(M), R(q), R(a)
-	MOVW.NE	$0, R(s)
-	MULAL.NE R(q), R(a), (R(q),R(s))
-	BEQ 	udiv_by_0_or_1
-
-	// q now accurate enough for a remainder r, 0<=r<3*d
-	MULLU	R(q), R(r), (R(q),R(s)) // q = (r * q) >> 32	
-	ADD 	R(M), R(r), R(r) // r = n - d
-	MULA	R(M), R(q), R(r), R(r) // r = n - (q+1)*d
-
-	// since 0 <= n-q*d < 3*d; thus -d <= r < 2*d
-	CMN 	R(M), R(r) // t = r-d
-	SUB.CS	R(M), R(r), R(r) // if (t<-d || t>=0) r=r+d
-	ADD.CC	$1, R(q)
-	ADD.PL	R(M)<<1, R(r)
-	ADD.PL	$2, R(q)
-	RET
-
-udiv_by_large_d:
-	// at this point we know d>=2^(31-6)=2^25
-	SUB 	$4, R(a), R(a)
-	RSB 	$0, R(s), R(s)
-	MOVW	R(a)>>R(s), R(q)
-	MULLU	R(q), R(r), (R(q),R(s))
-	MULA	R(M), R(q), R(r), R(r)
-
-	// q now accurate enough for a remainder r, 0<=r<4*d
-	CMN 	R(r)>>1, R(M) // if(r/2 >= d)
-	ADD.CS	R(M)<<1, R(r)
-	ADD.CS	$2, R(q)
-	CMN 	R(r), R(M)
-	ADD.CS	R(M), R(r)
-	ADD.CS	$1, R(q)
-	RET
-
-udiv_by_0_or_1:
-	// carry set if d==1, carry clear if d==0
-	BCC udiv_by_0
-	MOVW	R(r), R(q)
-	MOVW	$0, R(r)
-	RET
-
-udiv_by_0:
-	// The ARM toolchain expects it can emit references to DIV and MOD
-	// instructions. The linker rewrites each pseudo-instruction into
-	// a sequence that pushes two values onto the stack and then calls
-	// _divu, _modu, _div, or _mod (below), all of which have a 16-byte
-	// frame plus the saved LR. The traceback routine knows the expanded
-	// stack frame size at the pseudo-instruction call site, but it
-	// doesn't know that the frame has a non-standard layout. In particular,
-	// it expects to find a saved LR in the bottom word of the frame.
-	// Unwind the stack back to the pseudo-instruction call site, copy the
-	// saved LR where the traceback routine will look for it, and make it
-	// appear that panicdivide was called from that PC.
-	MOVW	0(R13), LR
-	ADD	$20, R13
-	MOVW	8(R13), R1 // actual saved LR
-	MOVW	R1, 0(R13) // expected here for traceback
-	B 	runtime·panicdivide(SB)
-
-TEXT fast_udiv_tab<>(SB),NOSPLIT,$-4
-	// var tab [64]byte
-	// tab[0] = 255; for i := 1; i <= 63; i++ { tab[i] = (1<<14)/(64+i) }
-	// laid out here as little-endian uint32s
-	WORD $0xf4f8fcff
-	WORD $0xe6eaedf0
-	WORD $0xdadde0e3
-	WORD $0xcfd2d4d7
-	WORD $0xc5c7cacc
-	WORD $0xbcbec0c3
-	WORD $0xb4b6b8ba
-	WORD $0xacaeb0b2
-	WORD $0xa5a7a8aa
-	WORD $0x9fa0a2a3
-	WORD $0x999a9c9d
-	WORD $0x93949697
-	WORD $0x8e8f9092
-	WORD $0x898a8c8d
-	WORD $0x85868788
-	WORD $0x81828384
-
-// The linker will pass numerator in R(TMP), and it also
-// expects the result in R(TMP)
-TMP = 11
-
-TEXT _divu(SB), NOSPLIT, $16
-	MOVW	R(q), 4(R13)
-	MOVW	R(r), 8(R13)
-	MOVW	R(s), 12(R13)
-	MOVW	R(M), 16(R13)
-
-	MOVW	R(TMP), R(r)		/* numerator */
-	MOVW	0(FP), R(q) 		/* denominator */
-	BL  	udiv<>(SB)
-	MOVW	R(q), R(TMP)
-	MOVW	4(R13), R(q)
-	MOVW	8(R13), R(r)
-	MOVW	12(R13), R(s)
-	MOVW	16(R13), R(M)
-	RET
-
-TEXT _modu(SB), NOSPLIT, $16
-	MOVW	R(q), 4(R13)
-	MOVW	R(r), 8(R13)
-	MOVW	R(s), 12(R13)
-	MOVW	R(M), 16(R13)
-
-	MOVW	R(TMP), R(r)		/* numerator */
-	MOVW	0(FP), R(q) 		/* denominator */
-	BL  	udiv<>(SB)
-	MOVW	R(r), R(TMP)
-	MOVW	4(R13), R(q)
-	MOVW	8(R13), R(r)
-	MOVW	12(R13), R(s)
-	MOVW	16(R13), R(M)
-	RET
-
-TEXT _div(SB),NOSPLIT,$16
-	MOVW	R(q), 4(R13)
-	MOVW	R(r), 8(R13)
-	MOVW	R(s), 12(R13)
-	MOVW	R(M), 16(R13)
-	MOVW	R(TMP), R(r)		/* numerator */
-	MOVW	0(FP), R(q) 		/* denominator */
-	CMP 	$0, R(r)
-	BGE 	d1
-	RSB 	$0, R(r), R(r)
-	CMP 	$0, R(q)
-	BGE 	d2
-	RSB 	$0, R(q), R(q)
-d0:
-	BL  	udiv<>(SB)  		/* none/both neg */
-	MOVW	R(q), R(TMP)
-	B		out1
-d1:
-	CMP 	$0, R(q)
-	BGE 	d0
-	RSB 	$0, R(q), R(q)
-d2:
-	BL  	udiv<>(SB)  		/* one neg */
-	RSB		$0, R(q), R(TMP)
-out1:
-	MOVW	4(R13), R(q)
-	MOVW	8(R13), R(r)
-	MOVW	12(R13), R(s)
-	MOVW	16(R13), R(M)
-	RET
-
-TEXT _mod(SB),NOSPLIT,$16
-	MOVW	R(q), 4(R13)
-	MOVW	R(r), 8(R13)
-	MOVW	R(s), 12(R13)
-	MOVW	R(M), 16(R13)
-	MOVW	R(TMP), R(r)		/* numerator */
-	MOVW	0(FP), R(q) 		/* denominator */
-	CMP 	$0, R(q)
-	RSB.LT	$0, R(q), R(q)
-	CMP 	$0, R(r)
-	BGE 	m1
-	RSB 	$0, R(r), R(r)
-	BL  	udiv<>(SB)  		/* neg numerator */
-	RSB 	$0, R(r), R(TMP)
-	B   	out
-m1:
-	BL  	udiv<>(SB)  		/* pos numerator */
-	MOVW	R(r), R(TMP)
-out:
-	MOVW	4(R13), R(q)
-	MOVW	8(R13), R(r)
-	MOVW	12(R13), R(s)
-	MOVW	16(R13), R(M)
-	RET
diff --git a/src/pkg/runtime/vlrt_386.c b/src/pkg/runtime/vlrt_386.c
deleted file mode 100644
index ace1beb..0000000
--- a/src/pkg/runtime/vlrt_386.c
+++ /dev/null
@@ -1,829 +0,0 @@
-// Inferno's libkern/vlrt-386.c
-// http://code.google.com/p/inferno-os/source/browse/libkern/vlrt-386.c
-//
-//         Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//         Revisions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com).  All rights reserved.
-//         Portions Copyright 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-#include "../../cmd/ld/textflag.h"
-
-/*
- * C runtime for 64-bit divide, others.
- *
- * TODO(rsc): The simple functions are dregs--8c knows how
- * to generate the code directly now.  Find and remove.
- */
-
-extern void runtime·panicdivide(void);
-
-typedef	unsigned long	ulong;
-typedef	unsigned int	uint;
-typedef	unsigned short	ushort;
-typedef	unsigned char	uchar;
-typedef	signed char	schar;
-
-#define	SIGN(n)	(1UL<<(n-1))
-
-typedef	struct	Vlong	Vlong;
-struct	Vlong
-{
-	union
-	{
-		long long	v;
-		struct
-		{
-			ulong	lo;
-			ulong	hi;
-		};
-		struct
-		{
-			ushort	lols;
-			ushort	loms;
-			ushort	hils;
-			ushort	hims;
-		};
-	};
-};
-
-void	runtime·abort(void);
-
-void
-_d2v(Vlong *y, double d)
-{
-	union { double d; struct Vlong; } x;
-	ulong xhi, xlo, ylo, yhi;
-	int sh;
-
-	x.d = d;
-
-	xhi = (x.hi & 0xfffff) | 0x100000;
-	xlo = x.lo;
-	sh = 1075 - ((x.hi >> 20) & 0x7ff);
-
-	ylo = 0;
-	yhi = 0;
-	if(sh >= 0) {
-		/* v = (hi||lo) >> sh */
-		if(sh < 32) {
-			if(sh == 0) {
-				ylo = xlo;
-				yhi = xhi;
-			} else {
-				ylo = (xlo >> sh) | (xhi << (32-sh));
-				yhi = xhi >> sh;
-			}
-		} else {
-			if(sh == 32) {
-				ylo = xhi;
-			} else
-			if(sh < 64) {
-				ylo = xhi >> (sh-32);
-			}
-		}
-	} else {
-		/* v = (hi||lo) << -sh */
-		sh = -sh;
-		if(sh <= 10) {
-			ylo = xlo << sh;
-			yhi = (xhi << sh) | (xlo >> (32-sh));
-		} else {
-			/* overflow */
-			yhi = d;	/* causes something awful */
-		}
-	}
-	if(x.hi & SIGN(32)) {
-		if(ylo != 0) {
-			ylo = -ylo;
-			yhi = ~yhi;
-		} else
-			yhi = -yhi;
-	}
-
-	y->hi = yhi;
-	y->lo = ylo;
-}
-
-void
-_f2v(Vlong *y, float f)
-{
-
-	_d2v(y, f);
-}
-
-double
-_v2d(Vlong x)
-{
-	if(x.hi & SIGN(32)) {
-		if(x.lo) {
-			x.lo = -x.lo;
-			x.hi = ~x.hi;
-		} else
-			x.hi = -x.hi;
-		return -((long)x.hi*4294967296. + x.lo);
-	}
-	return (long)x.hi*4294967296. + x.lo;
-}
-
-float
-_v2f(Vlong x)
-{
-	return _v2d(x);
-}
-
-ulong	_div64by32(Vlong, ulong, ulong*);
-int	_mul64by32(Vlong*, Vlong, ulong);
-
-static void
-slowdodiv(Vlong num, Vlong den, Vlong *q, Vlong *r)
-{
-	ulong numlo, numhi, denhi, denlo, quohi, quolo, t;
-	int i;
-
-	numhi = num.hi;
-	numlo = num.lo;
-	denhi = den.hi;
-	denlo = den.lo;
-
-	/*
-	 * get a divide by zero
-	 */
-	if(denlo==0 && denhi==0) {
-		numlo = numlo / denlo;
-	}
-
-	/*
-	 * set up the divisor and find the number of iterations needed
-	 */
-	if(numhi >= SIGN(32)) {
-		quohi = SIGN(32);
-		quolo = 0;
-	} else {
-		quohi = numhi;
-		quolo = numlo;
-	}
-	i = 0;
-	while(denhi < quohi || (denhi == quohi && denlo < quolo)) {
-		denhi = (denhi<<1) | (denlo>>31);
-		denlo <<= 1;
-		i++;
-	}
-
-	quohi = 0;
-	quolo = 0;
-	for(; i >= 0; i--) {
-		quohi = (quohi<<1) | (quolo>>31);
-		quolo <<= 1;
-		if(numhi > denhi || (numhi == denhi && numlo >= denlo)) {
-			t = numlo;
-			numlo -= denlo;
-			if(numlo > t)
-				numhi--;
-			numhi -= denhi;
-			quolo |= 1;
-		}
-		denlo = (denlo>>1) | (denhi<<31);
-		denhi >>= 1;
-	}
-
-	if(q) {
-		q->lo = quolo;
-		q->hi = quohi;
-	}
-	if(r) {
-		r->lo = numlo;
-		r->hi = numhi;
-	}
-}
-
-static void
-dodiv(Vlong num, Vlong den, Vlong *qp, Vlong *rp)
-{
-	ulong n;
-	Vlong x, q, r;
-
-	if(den.hi > num.hi || (den.hi == num.hi && den.lo > num.lo)){
-		if(qp) {
-			qp->hi = 0;
-			qp->lo = 0;
-		}
-		if(rp) {
-			rp->hi = num.hi;
-			rp->lo = num.lo;
-		}
-		return;
-	}
-
-	if(den.hi != 0){
-		q.hi = 0;
-		n = num.hi/den.hi;
-		if(_mul64by32(&x, den, n) || x.hi > num.hi || (x.hi == num.hi && x.lo > num.lo))
-			slowdodiv(num, den, &q, &r);
-		else {
-			q.lo = n;
-			r.v = num.v - x.v;
-		}
-	} else {
-		if(num.hi >= den.lo){
-			if(den.lo == 0)
-				runtime·panicdivide();
-			q.hi = n = num.hi/den.lo;
-			num.hi -= den.lo*n;
-		} else {
-			q.hi = 0;
-		}
-		q.lo = _div64by32(num, den.lo, &r.lo);
-		r.hi = 0;
-	}
-	if(qp) {
-		qp->lo = q.lo;
-		qp->hi = q.hi;
-	}
-	if(rp) {
-		rp->lo = r.lo;
-		rp->hi = r.hi;
-	}
-}
-
-void
-_divvu(Vlong *q, Vlong n, Vlong d)
-{
-
-	if(n.hi == 0 && d.hi == 0) {
-		if(d.lo == 0)
-			runtime·panicdivide();
-		q->hi = 0;
-		q->lo = n.lo / d.lo;
-		return;
-	}
-	dodiv(n, d, q, 0);
-}
-
-void
-runtime·uint64div(Vlong n, Vlong d, Vlong q)
-{
-	_divvu(&q, n, d);
-}
-
-void
-_modvu(Vlong *r, Vlong n, Vlong d)
-{
-
-	if(n.hi == 0 && d.hi == 0) {
-		if(d.lo == 0)
-			runtime·panicdivide();
-		r->hi = 0;
-		r->lo = n.lo % d.lo;
-		return;
-	}
-	dodiv(n, d, 0, r);
-}
-
-void
-runtime·uint64mod(Vlong n, Vlong d, Vlong q)
-{
-	_modvu(&q, n, d);
-}
-
-static void
-vneg(Vlong *v)
-{
-
-	if(v->lo == 0) {
-		v->hi = -v->hi;
-		return;
-	}
-	v->lo = -v->lo;
-	v->hi = ~v->hi;
-}
-
-void
-_divv(Vlong *q, Vlong n, Vlong d)
-{
-	long nneg, dneg;
-
-	if(n.hi == (((long)n.lo)>>31) && d.hi == (((long)d.lo)>>31)) {
-		if((long)n.lo == -0x80000000 && (long)d.lo == -1) {
-			// special case: 32-bit -0x80000000 / -1 causes divide error,
-			// but it's okay in this 64-bit context.
-			q->lo = 0x80000000;
-			q->hi = 0;
-			return;
-		}
-		if(d.lo == 0)
-			runtime·panicdivide();
-		q->lo = (long)n.lo / (long)d.lo;
-		q->hi = ((long)q->lo) >> 31;
-		return;
-	}
-	nneg = n.hi >> 31;
-	if(nneg)
-		vneg(&n);
-	dneg = d.hi >> 31;
-	if(dneg)
-		vneg(&d);
-	dodiv(n, d, q, 0);
-	if(nneg != dneg)
-		vneg(q);
-}
-
-void
-runtime·int64div(Vlong n, Vlong d, Vlong q)
-{
-	_divv(&q, n, d);
-}
-
-void
-_modv(Vlong *r, Vlong n, Vlong d)
-{
-	long nneg, dneg;
-
-	if(n.hi == (((long)n.lo)>>31) && d.hi == (((long)d.lo)>>31)) {
-		if((long)n.lo == -0x80000000 && (long)d.lo == -1) {
-			// special case: 32-bit -0x80000000 % -1 causes divide error,
-			// but it's okay in this 64-bit context.
-			r->lo = 0;
-			r->hi = 0;
-			return;
-		}
-		if(d.lo == 0)
-			runtime·panicdivide();
-		r->lo = (long)n.lo % (long)d.lo;
-		r->hi = ((long)r->lo) >> 31;
-		return;
-	}
-	nneg = n.hi >> 31;
-	if(nneg)
-		vneg(&n);
-	dneg = d.hi >> 31;
-	if(dneg)
-		vneg(&d);
-	dodiv(n, d, 0, r);
-	if(nneg)
-		vneg(r);
-}
-
-void
-runtime·int64mod(Vlong n, Vlong d, Vlong q)
-{
-	_modv(&q, n, d);
-}
-
-void
-_rshav(Vlong *r, Vlong a, int b)
-{
-	long t;
-
-	t = a.hi;
-	if(b >= 32) {
-		r->hi = t>>31;
-		if(b >= 64) {
-			/* this is illegal re C standard */
-			r->lo = t>>31;
-			return;
-		}
-		r->lo = t >> (b-32);
-		return;
-	}
-	if(b <= 0) {
-		r->hi = t;
-		r->lo = a.lo;
-		return;
-	}
-	r->hi = t >> b;
-	r->lo = (t << (32-b)) | (a.lo >> b);
-}
-
-void
-_rshlv(Vlong *r, Vlong a, int b)
-{
-	ulong t;
-
-	t = a.hi;
-	if(b >= 32) {
-		r->hi = 0;
-		if(b >= 64) {
-			/* this is illegal re C standard */
-			r->lo = 0;
-			return;
-		}
-		r->lo = t >> (b-32);
-		return;
-	}
-	if(b <= 0) {
-		r->hi = t;
-		r->lo = a.lo;
-		return;
-	}
-	r->hi = t >> b;
-	r->lo = (t << (32-b)) | (a.lo >> b);
-}
-
-#pragma textflag NOSPLIT
-void
-_lshv(Vlong *r, Vlong a, int b)
-{
-	ulong t;
-
-	t = a.lo;
-	if(b >= 32) {
-		r->lo = 0;
-		if(b >= 64) {
-			/* this is illegal re C standard */
-			r->hi = 0;
-			return;
-		}
-		r->hi = t << (b-32);
-		return;
-	}
-	if(b <= 0) {
-		r->lo = t;
-		r->hi = a.hi;
-		return;
-	}
-	r->lo = t << b;
-	r->hi = (t >> (32-b)) | (a.hi << b);
-}
-
-void
-_andv(Vlong *r, Vlong a, Vlong b)
-{
-	r->hi = a.hi & b.hi;
-	r->lo = a.lo & b.lo;
-}
-
-void
-_orv(Vlong *r, Vlong a, Vlong b)
-{
-	r->hi = a.hi | b.hi;
-	r->lo = a.lo | b.lo;
-}
-
-void
-_xorv(Vlong *r, Vlong a, Vlong b)
-{
-	r->hi = a.hi ^ b.hi;
-	r->lo = a.lo ^ b.lo;
-}
-
-void
-_vpp(Vlong *l, Vlong *r)
-{
-
-	l->hi = r->hi;
-	l->lo = r->lo;
-	r->lo++;
-	if(r->lo == 0)
-		r->hi++;
-}
-
-void
-_vmm(Vlong *l, Vlong *r)
-{
-
-	l->hi = r->hi;
-	l->lo = r->lo;
-	if(r->lo == 0)
-		r->hi--;
-	r->lo--;
-}
-
-void
-_ppv(Vlong *l, Vlong *r)
-{
-
-	r->lo++;
-	if(r->lo == 0)
-		r->hi++;
-	l->hi = r->hi;
-	l->lo = r->lo;
-}
-
-void
-_mmv(Vlong *l, Vlong *r)
-{
-
-	if(r->lo == 0)
-		r->hi--;
-	r->lo--;
-	l->hi = r->hi;
-	l->lo = r->lo;
-}
-
-void
-_vasop(Vlong *ret, void *lv, void fn(Vlong*, Vlong, Vlong), int type, Vlong rv)
-{
-	Vlong t, u;
-
-	u.lo = 0;
-	u.hi = 0;
-	switch(type) {
-	default:
-		runtime·abort();
-		break;
-
-	case 1:	/* schar */
-		t.lo = *(schar*)lv;
-		t.hi = t.lo >> 31;
-		fn(&u, t, rv);
-		*(schar*)lv = u.lo;
-		break;
-
-	case 2:	/* uchar */
-		t.lo = *(uchar*)lv;
-		t.hi = 0;
-		fn(&u, t, rv);
-		*(uchar*)lv = u.lo;
-		break;
-
-	case 3:	/* short */
-		t.lo = *(short*)lv;
-		t.hi = t.lo >> 31;
-		fn(&u, t, rv);
-		*(short*)lv = u.lo;
-		break;
-
-	case 4:	/* ushort */
-		t.lo = *(ushort*)lv;
-		t.hi = 0;
-		fn(&u, t, rv);
-		*(ushort*)lv = u.lo;
-		break;
-
-	case 9:	/* int */
-		t.lo = *(int*)lv;
-		t.hi = t.lo >> 31;
-		fn(&u, t, rv);
-		*(int*)lv = u.lo;
-		break;
-
-	case 10:	/* uint */
-		t.lo = *(uint*)lv;
-		t.hi = 0;
-		fn(&u, t, rv);
-		*(uint*)lv = u.lo;
-		break;
-
-	case 5:	/* long */
-		t.lo = *(long*)lv;
-		t.hi = t.lo >> 31;
-		fn(&u, t, rv);
-		*(long*)lv = u.lo;
-		break;
-
-	case 6:	/* ulong */
-		t.lo = *(ulong*)lv;
-		t.hi = 0;
-		fn(&u, t, rv);
-		*(ulong*)lv = u.lo;
-		break;
-
-	case 7:	/* vlong */
-	case 8:	/* uvlong */
-		fn(&u, *(Vlong*)lv, rv);
-		*(Vlong*)lv = u;
-		break;
-	}
-	*ret = u;
-}
-
-void
-_p2v(Vlong *ret, void *p)
-{
-	long t;
-
-	t = (ulong)p;
-	ret->lo = t;
-	ret->hi = 0;
-}
-
-void
-_sl2v(Vlong *ret, long sl)
-{
-	long t;
-
-	t = sl;
-	ret->lo = t;
-	ret->hi = t >> 31;
-}
-
-void
-_ul2v(Vlong *ret, ulong ul)
-{
-	long t;
-
-	t = ul;
-	ret->lo = t;
-	ret->hi = 0;
-}
-
-void
-_si2v(Vlong *ret, int si)
-{
-	long t;
-
-	t = si;
-	ret->lo = t;
-	ret->hi = t >> 31;
-}
-
-void
-_ui2v(Vlong *ret, uint ui)
-{
-	long t;
-
-	t = ui;
-	ret->lo = t;
-	ret->hi = 0;
-}
-
-void
-_sh2v(Vlong *ret, long sh)
-{
-	long t;
-
-	t = (sh << 16) >> 16;
-	ret->lo = t;
-	ret->hi = t >> 31;
-}
-
-void
-_uh2v(Vlong *ret, ulong ul)
-{
-	long t;
-
-	t = ul & 0xffff;
-	ret->lo = t;
-	ret->hi = 0;
-}
-
-void
-_sc2v(Vlong *ret, long uc)
-{
-	long t;
-
-	t = (uc << 24) >> 24;
-	ret->lo = t;
-	ret->hi = t >> 31;
-}
-
-void
-_uc2v(Vlong *ret, ulong ul)
-{
-	long t;
-
-	t = ul & 0xff;
-	ret->lo = t;
-	ret->hi = 0;
-}
-
-long
-_v2sc(Vlong rv)
-{
-	long t;
-
-	t = rv.lo & 0xff;
-	return (t << 24) >> 24;
-}
-
-long
-_v2uc(Vlong rv)
-{
-
-	return rv.lo & 0xff;
-}
-
-long
-_v2sh(Vlong rv)
-{
-	long t;
-
-	t = rv.lo & 0xffff;
-	return (t << 16) >> 16;
-}
-
-long
-_v2uh(Vlong rv)
-{
-
-	return rv.lo & 0xffff;
-}
-
-long
-_v2sl(Vlong rv)
-{
-
-	return rv.lo;
-}
-
-long
-_v2ul(Vlong rv)
-{
-
-	return rv.lo;
-}
-
-long
-_v2si(Vlong rv)
-{
-
-	return rv.lo;
-}
-
-long
-_v2ui(Vlong rv)
-{
-
-	return rv.lo;
-}
-
-int
-_testv(Vlong rv)
-{
-	return rv.lo || rv.hi;
-}
-
-int
-_eqv(Vlong lv, Vlong rv)
-{
-	return lv.lo == rv.lo && lv.hi == rv.hi;
-}
-
-int
-_nev(Vlong lv, Vlong rv)
-{
-	return lv.lo != rv.lo || lv.hi != rv.hi;
-}
-
-int
-_ltv(Vlong lv, Vlong rv)
-{
-	return (long)lv.hi < (long)rv.hi ||
-		(lv.hi == rv.hi && lv.lo < rv.lo);
-}
-
-int
-_lev(Vlong lv, Vlong rv)
-{
-	return (long)lv.hi < (long)rv.hi ||
-		(lv.hi == rv.hi && lv.lo <= rv.lo);
-}
-
-int
-_gtv(Vlong lv, Vlong rv)
-{
-	return (long)lv.hi > (long)rv.hi ||
-		(lv.hi == rv.hi && lv.lo > rv.lo);
-}
-
-int
-_gev(Vlong lv, Vlong rv)
-{
-	return (long)lv.hi > (long)rv.hi ||
-		(lv.hi == rv.hi && lv.lo >= rv.lo);
-}
-
-int
-_lov(Vlong lv, Vlong rv)
-{
-	return lv.hi < rv.hi ||
-		(lv.hi == rv.hi && lv.lo < rv.lo);
-}
-
-int
-_lsv(Vlong lv, Vlong rv)
-{
-	return lv.hi < rv.hi ||
-		(lv.hi == rv.hi && lv.lo <= rv.lo);
-}
-
-int
-_hiv(Vlong lv, Vlong rv)
-{
-	return lv.hi > rv.hi ||
-		(lv.hi == rv.hi && lv.lo > rv.lo);
-}
-
-int
-_hsv(Vlong lv, Vlong rv)
-{
-	return lv.hi > rv.hi ||
-		(lv.hi == rv.hi && lv.lo >= rv.lo);
-}
diff --git a/src/pkg/runtime/vlrt_arm.c b/src/pkg/runtime/vlrt_arm.c
deleted file mode 100644
index 7dd71b4..0000000
--- a/src/pkg/runtime/vlrt_arm.c
+++ /dev/null
@@ -1,807 +0,0 @@
-// Inferno's libkern/vlrt-arm.c
-// http://code.google.com/p/inferno-os/source/browse/libkern/vlrt-arm.c
-//
-//         Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
-//         Revisions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com).  All rights reserved.
-//         Portions Copyright 2009 The Go Authors. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-#include "../../cmd/ld/textflag.h"
-
-// declared here to avoid include of runtime.h
-void	runtime·panicstring(char*);
-void	runtime·panicdivide(void);
-
-typedef unsigned long   ulong;
-typedef unsigned int    uint;
-typedef unsigned short  ushort;
-typedef unsigned char   uchar;
-typedef signed char     schar;
-
-#define SIGN(n) (1UL<<(n-1))
-
-typedef struct  Vlong   Vlong;
-struct  Vlong
-{
-	union
-	{
-		struct
-		{
-			ulong   lo;
-			ulong   hi;
-		};
-		struct
-		{
-			ushort lols;
-			ushort loms;
-			ushort hils;
-			ushort hims;
-		};
-	};
-};
-
-void    runtime·abort(void);
-
-#pragma textflag NOSPLIT
-void
-_addv(Vlong *r, Vlong a, Vlong b)
-{
-	r->lo = a.lo + b.lo;
-	r->hi = a.hi + b.hi;
-	if(r->lo < a.lo)
-		r->hi++;
-}
-
-#pragma textflag NOSPLIT
-void
-_subv(Vlong *r, Vlong a, Vlong b)
-{
-	r->lo = a.lo - b.lo;
-	r->hi = a.hi - b.hi;
-	if(r->lo > a.lo)
-		r->hi--;
-}
-
-void
-_d2v(Vlong *y, double d)
-{
-	union { double d; struct Vlong; } x;
-	ulong xhi, xlo, ylo, yhi;
-	int sh;
-
-	x.d = d;
-
-	xhi = (x.hi & 0xfffff) | 0x100000;
-	xlo = x.lo;
-	sh = 1075 - ((x.hi >> 20) & 0x7ff);
-
-	ylo = 0;
-	yhi = 0;
-	if(sh >= 0) {
-		/* v = (hi||lo) >> sh */
-		if(sh < 32) {
-			if(sh == 0) {
-				ylo = xlo;
-				yhi = xhi;
-			} else {
-				ylo = (xlo >> sh) | (xhi << (32-sh));
-				yhi = xhi >> sh;
-			}
-		} else {
-			if(sh == 32) {
-				ylo = xhi;
-			} else
-			if(sh < 64) {
-				ylo = xhi >> (sh-32);
-			}
-		}
-	} else {
-		/* v = (hi||lo) << -sh */
-		sh = -sh;
-		if(sh <= 11) {
-			ylo = xlo << sh;
-			yhi = (xhi << sh) | (xlo >> (32-sh));
-		} else {
-			/* overflow */
-			yhi = d;        /* causes something awful */
-		}
-	}
-	if(x.hi & SIGN(32)) {
-		if(ylo != 0) {
-			ylo = -ylo;
-			yhi = ~yhi;
-		} else
-			yhi = -yhi;
-	}
-
-	y->hi = yhi;
-	y->lo = ylo;
-}
-
-void
-_f2v(Vlong *y, float f)
-{
-	_d2v(y, f);
-}
-
-void
-runtime·float64toint64(double d, Vlong y)
-{
-	_d2v(&y, d);
-}
-
-void
-runtime·float64touint64(double d, Vlong y)
-{
-	_d2v(&y, d);
-}
-
-double
-_ul2d(ulong u)
-{
-	// compensate for bug in c
-	if(u & SIGN(32)) {
-		u ^= SIGN(32);
-		return 2147483648. + u;
-	}
-	return u;
-}
-
-double
-_v2d(Vlong x)
-{
-	if(x.hi & SIGN(32)) {
-		if(x.lo) {
-			x.lo = -x.lo;
-			x.hi = ~x.hi;
-		} else
-			x.hi = -x.hi;
-		return -(_ul2d(x.hi)*4294967296. + _ul2d(x.lo));
-	}
-	return x.hi*4294967296. + _ul2d(x.lo);
-}
-
-float
-_v2f(Vlong x)
-{
-	return _v2d(x);
-}
-
-void
-runtime·int64tofloat64(Vlong y, double d)
-{
-	d = _v2d(y);
-	USED(&d); // FLUSH
-}
-
-void
-runtime·uint64tofloat64(Vlong y, double d)
-{
-	d = _ul2d(y.hi)*4294967296. + _ul2d(y.lo);
-	USED(&d); // FLUSH
-}
-
-static void
-dodiv(Vlong num, Vlong den, Vlong *q, Vlong *r)
-{
-	ulong numlo, numhi, denhi, denlo, quohi, quolo, t;
-	int i;
-
-	numhi = num.hi;
-	numlo = num.lo;
-	denhi = den.hi;
-	denlo = den.lo;
-
-	/*
-	 * get a divide by zero
-	 */
-	if(denlo==0 && denhi==0) {
-		runtime·panicdivide();
-	}
-
-	/*
-	 * set up the divisor and find the number of iterations needed
-	 */
-	if(numhi >= SIGN(32)) {
-		quohi = SIGN(32);
-		quolo = 0;
-	} else {
-		quohi = numhi;
-		quolo = numlo;
-	}
-	i = 0;
-	while(denhi < quohi || (denhi == quohi && denlo < quolo)) {
-		denhi = (denhi<<1) | (denlo>>31);
-		denlo <<= 1;
-		i++;
-	}
-
-	quohi = 0;
-	quolo = 0;
-	for(; i >= 0; i--) {
-		quohi = (quohi<<1) | (quolo>>31);
-		quolo <<= 1;
-		if(numhi > denhi || (numhi == denhi && numlo >= denlo)) {
-			t = numlo;
-			numlo -= denlo;
-			if(numlo > t)
-				numhi--;
-			numhi -= denhi;
-			quolo |= 1;
-		}
-		denlo = (denlo>>1) | (denhi<<31);
-		denhi >>= 1;
-	}
-
-	if(q) {
-		q->lo = quolo;
-		q->hi = quohi;
-	}
-	if(r) {
-		r->lo = numlo;
-		r->hi = numhi;
-	}
-}
-
-void
-_divvu(Vlong *q, Vlong n, Vlong d)
-{
-
-	if(n.hi == 0 && d.hi == 0) {
-		q->hi = 0;
-		q->lo = n.lo / d.lo;
-		return;
-	}
-	dodiv(n, d, q, 0);
-}
-
-void
-runtime·uint64div(Vlong n, Vlong d, Vlong q)
-{
-	_divvu(&q, n, d);
-}
-
-void
-_modvu(Vlong *r, Vlong n, Vlong d)
-{
-
-	if(n.hi == 0 && d.hi == 0) {
-		r->hi = 0;
-		r->lo = n.lo % d.lo;
-		return;
-	}
-	dodiv(n, d, 0, r);
-}
-
-void
-runtime·uint64mod(Vlong n, Vlong d, Vlong q)
-{
-	_modvu(&q, n, d);
-}
-
-static void
-vneg(Vlong *v)
-{
-
-	if(v->lo == 0) {
-		v->hi = -v->hi;
-		return;
-	}
-	v->lo = -v->lo;
-	v->hi = ~v->hi;
-}
-
-void
-_divv(Vlong *q, Vlong n, Vlong d)
-{
-	long nneg, dneg;
-
-	if(n.hi == (((long)n.lo)>>31) && d.hi == (((long)d.lo)>>31)) {
-		if((long)n.lo == -0x80000000 && (long)d.lo == -1) {
-			// special case: 32-bit -0x80000000 / -1 causes wrong sign
-			q->lo = 0x80000000;
-			q->hi = 0;
-			return;
-		}
-		q->lo = (long)n.lo / (long)d.lo;
-		q->hi = ((long)q->lo) >> 31;
-		return;
-	}
-	nneg = n.hi >> 31;
-	if(nneg)
-		vneg(&n);
-	dneg = d.hi >> 31;
-	if(dneg)
-		vneg(&d);
-	dodiv(n, d, q, 0);
-	if(nneg != dneg)
-		vneg(q);
-}
-
-void
-runtime·int64div(Vlong n, Vlong d, Vlong q)
-{
-	_divv(&q, n, d);
-}
-
-void
-_modv(Vlong *r, Vlong n, Vlong d)
-{
-	long nneg, dneg;
-
-	if(n.hi == (((long)n.lo)>>31) && d.hi == (((long)d.lo)>>31)) {
-		r->lo = (long)n.lo % (long)d.lo;
-		r->hi = ((long)r->lo) >> 31;
-		return;
-	}
-	nneg = n.hi >> 31;
-	if(nneg)
-		vneg(&n);
-	dneg = d.hi >> 31;
-	if(dneg)
-		vneg(&d);
-	dodiv(n, d, 0, r);
-	if(nneg)
-		vneg(r);
-}
-
-void
-runtime·int64mod(Vlong n, Vlong d, Vlong q)
-{
-	_modv(&q, n, d);
-}
-
-void
-_rshav(Vlong *r, Vlong a, int b)
-{
-	long t;
-
-	t = a.hi;
-	if(b >= 32) {
-		r->hi = t>>31;
-		if(b >= 64) {
-			/* this is illegal re C standard */
-			r->lo = t>>31;
-			return;
-		}
-		r->lo = t >> (b-32);
-		return;
-	}
-	if(b <= 0) {
-		r->hi = t;
-		r->lo = a.lo;
-		return;
-	}
-	r->hi = t >> b;
-	r->lo = (t << (32-b)) | (a.lo >> b);
-}
-
-void
-_rshlv(Vlong *r, Vlong a, int b)
-{
-	ulong t;
-
-	t = a.hi;
-	if(b >= 32) {
-		r->hi = 0;
-		if(b >= 64) {
-			/* this is illegal re C standard */
-			r->lo = 0;
-			return;
-		}
-		r->lo = t >> (b-32);
-		return;
-	}
-	if(b <= 0) {
-		r->hi = t;
-		r->lo = a.lo;
-		return;
-	}
-	r->hi = t >> b;
-	r->lo = (t << (32-b)) | (a.lo >> b);
-}
-
-#pragma textflag NOSPLIT
-void
-_lshv(Vlong *r, Vlong a, int b)
-{
-	if(b >= 32) {
-		r->lo = 0;
-		if(b >= 64) {
-			/* this is illegal re C standard */
-			r->hi = 0;
-			return;
-		}
-		r->hi = a.lo << (b-32);
-		return;
-	}
-	if(b <= 0) {
-		r->lo = a.lo;
-		r->hi = a.hi;
-		return;
-	}
-	r->lo = a.lo << b;
-	r->hi = (a.lo >> (32-b)) | (a.hi << b);
-}
-
-void
-_andv(Vlong *r, Vlong a, Vlong b)
-{
-	r->hi = a.hi & b.hi;
-	r->lo = a.lo & b.lo;
-}
-
-void
-_orv(Vlong *r, Vlong a, Vlong b)
-{
-	r->hi = a.hi | b.hi;
-	r->lo = a.lo | b.lo;
-}
-
-void
-_xorv(Vlong *r, Vlong a, Vlong b)
-{
-	r->hi = a.hi ^ b.hi;
-	r->lo = a.lo ^ b.lo;
-}
-
-void
-_vpp(Vlong *l, Vlong *r)
-{
-
-	l->hi = r->hi;
-	l->lo = r->lo;
-	r->lo++;
-	if(r->lo == 0)
-		r->hi++;
-}
-
-void
-_vmm(Vlong *l, Vlong *r)
-{
-
-	l->hi = r->hi;
-	l->lo = r->lo;
-	if(r->lo == 0)
-		r->hi--;
-	r->lo--;
-}
-
-void
-_ppv(Vlong *l, Vlong *r)
-{
-
-	r->lo++;
-	if(r->lo == 0)
-		r->hi++;
-	l->hi = r->hi;
-	l->lo = r->lo;
-}
-
-void
-_mmv(Vlong *l, Vlong *r)
-{
-
-	if(r->lo == 0)
-		r->hi--;
-	r->lo--;
-	l->hi = r->hi;
-	l->lo = r->lo;
-}
-
-void
-_vasop(Vlong *ret, void *lv, void fn(Vlong*, Vlong, Vlong), int type, Vlong rv)
-{
-	Vlong t, u;
-
-	u = *ret;
-	switch(type) {
-	default:
-		runtime·abort();
-		break;
-
-	case 1: /* schar */
-		t.lo = *(schar*)lv;
-		t.hi = t.lo >> 31;
-		fn(&u, t, rv);
-		*(schar*)lv = u.lo;
-		break;
-
-	case 2: /* uchar */
-		t.lo = *(uchar*)lv;
-		t.hi = 0;
-		fn(&u, t, rv);
-		*(uchar*)lv = u.lo;
-		break;
-
-	case 3: /* short */
-		t.lo = *(short*)lv;
-		t.hi = t.lo >> 31;
-		fn(&u, t, rv);
-		*(short*)lv = u.lo;
-		break;
-
-	case 4: /* ushort */
-		t.lo = *(ushort*)lv;
-		t.hi = 0;
-		fn(&u, t, rv);
-		*(ushort*)lv = u.lo;
-		break;
-
-	case 9: /* int */
-		t.lo = *(int*)lv;
-		t.hi = t.lo >> 31;
-		fn(&u, t, rv);
-		*(int*)lv = u.lo;
-		break;
-
-	case 10:        /* uint */
-		t.lo = *(uint*)lv;
-		t.hi = 0;
-		fn(&u, t, rv);
-		*(uint*)lv = u.lo;
-		break;
-
-	case 5: /* long */
-		t.lo = *(long*)lv;
-		t.hi = t.lo >> 31;
-		fn(&u, t, rv);
-		*(long*)lv = u.lo;
-		break;
-
-	case 6: /* ulong */
-		t.lo = *(ulong*)lv;
-		t.hi = 0;
-		fn(&u, t, rv);
-		*(ulong*)lv = u.lo;
-		break;
-
-	case 7: /* vlong */
-	case 8: /* uvlong */
-		fn(&u, *(Vlong*)lv, rv);
-		*(Vlong*)lv = u;
-		break;
-	}
-	*ret = u;
-}
-
-void
-_p2v(Vlong *ret, void *p)
-{
-	long t;
-
-	t = (ulong)p;
-	ret->lo = t;
-	ret->hi = 0;
-}
-
-void
-_sl2v(Vlong *ret, long sl)
-{
-	long t;
-
-	t = sl;
-	ret->lo = t;
-	ret->hi = t >> 31;
-}
-
-void
-_ul2v(Vlong *ret, ulong ul)
-{
-	long t;
-
-	t = ul;
-	ret->lo = t;
-	ret->hi = 0;
-}
-
-#pragma textflag NOSPLIT
-void
-_si2v(Vlong *ret, int si)
-{
-	ret->lo = (long)si;
-	ret->hi = (long)si >> 31;
-}
-
-void
-_ui2v(Vlong *ret, uint ui)
-{
-	long t;
-
-	t = ui;
-	ret->lo = t;
-	ret->hi = 0;
-}
-
-void
-_sh2v(Vlong *ret, long sh)
-{
-	long t;
-
-	t = (sh << 16) >> 16;
-	ret->lo = t;
-	ret->hi = t >> 31;
-}
-
-void
-_uh2v(Vlong *ret, ulong ul)
-{
-	long t;
-
-	t = ul & 0xffff;
-	ret->lo = t;
-	ret->hi = 0;
-}
-
-void
-_sc2v(Vlong *ret, long uc)
-{
-	long t;
-
-	t = (uc << 24) >> 24;
-	ret->lo = t;
-	ret->hi = t >> 31;
-}
-
-void
-_uc2v(Vlong *ret, ulong ul)
-{
-	long t;
-
-	t = ul & 0xff;
-	ret->lo = t;
-	ret->hi = 0;
-}
-
-long
-_v2sc(Vlong rv)
-{
-	long t;
-
-	t = rv.lo & 0xff;
-	return (t << 24) >> 24;
-}
-
-long
-_v2uc(Vlong rv)
-{
-
-	return rv.lo & 0xff;
-}
-
-long
-_v2sh(Vlong rv)
-{
-	long t;
-
-	t = rv.lo & 0xffff;
-	return (t << 16) >> 16;
-}
-
-long
-_v2uh(Vlong rv)
-{
-
-	return rv.lo & 0xffff;
-}
-
-long
-_v2sl(Vlong rv)
-{
-
-	return rv.lo;
-}
-
-long
-_v2ul(Vlong rv)
-{
-
-	return rv.lo;
-}
-
-#pragma textflag NOSPLIT
-long
-_v2si(Vlong rv)
-{
-
-	return rv.lo;
-}
-
-long
-_v2ui(Vlong rv)
-{
-
-	return rv.lo;
-}
-
-int
-_testv(Vlong rv)
-{
-	return rv.lo || rv.hi;
-}
-
-int
-_eqv(Vlong lv, Vlong rv)
-{
-	return lv.lo == rv.lo && lv.hi == rv.hi;
-}
-
-int
-_nev(Vlong lv, Vlong rv)
-{
-	return lv.lo != rv.lo || lv.hi != rv.hi;
-}
-
-int
-_ltv(Vlong lv, Vlong rv)
-{
-	return (long)lv.hi < (long)rv.hi ||
-		(lv.hi == rv.hi && lv.lo < rv.lo);
-}
-
-int
-_lev(Vlong lv, Vlong rv)
-{
-	return (long)lv.hi < (long)rv.hi ||
-		(lv.hi == rv.hi && lv.lo <= rv.lo);
-}
-
-int
-_gtv(Vlong lv, Vlong rv)
-{
-	return (long)lv.hi > (long)rv.hi ||
-		(lv.hi == rv.hi && lv.lo > rv.lo);
-}
-
-#pragma textflag NOSPLIT
-int
-_gev(Vlong lv, Vlong rv)
-{
-	return (long)lv.hi > (long)rv.hi ||
-		(lv.hi == rv.hi && lv.lo >= rv.lo);
-}
-
-int
-_lov(Vlong lv, Vlong rv)
-{
-	return lv.hi < rv.hi ||
-		(lv.hi == rv.hi && lv.lo < rv.lo);
-}
-
-int
-_lsv(Vlong lv, Vlong rv)
-{
-	return lv.hi < rv.hi ||
-		(lv.hi == rv.hi && lv.lo <= rv.lo);
-}
-
-int
-_hiv(Vlong lv, Vlong rv)
-{
-	return lv.hi > rv.hi ||
-		(lv.hi == rv.hi && lv.lo > rv.lo);
-}
-
-int
-_hsv(Vlong lv, Vlong rv)
-{
-	return lv.hi > rv.hi ||
-		(lv.hi == rv.hi && lv.lo >= rv.lo);
-}
diff --git a/src/pkg/strconv/atoi.go b/src/pkg/strconv/atoi.go
deleted file mode 100644
index cbf0380..0000000
--- a/src/pkg/strconv/atoi.go
+++ /dev/null
@@ -1,198 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package strconv
-
-import "errors"
-
-// ErrRange indicates that a value is out of range for the target type.
-var ErrRange = errors.New("value out of range")
-
-// ErrSyntax indicates that a value does not have the right syntax for the target type.
-var ErrSyntax = errors.New("invalid syntax")
-
-// A NumError records a failed conversion.
-type NumError struct {
-	Func string // the failing function (ParseBool, ParseInt, ParseUint, ParseFloat)
-	Num  string // the input
-	Err  error  // the reason the conversion failed (ErrRange, ErrSyntax)
-}
-
-func (e *NumError) Error() string {
-	return "strconv." + e.Func + ": " + "parsing " + Quote(e.Num) + ": " + e.Err.Error()
-}
-
-func syntaxError(fn, str string) *NumError {
-	return &NumError{fn, str, ErrSyntax}
-}
-
-func rangeError(fn, str string) *NumError {
-	return &NumError{fn, str, ErrRange}
-}
-
-const intSize = 32 << uint(^uint(0)>>63)
-
-// IntSize is the size in bits of an int or uint value.
-const IntSize = intSize
-
-// Return the first number n such that n*base >= 1<<64.
-func cutoff64(base int) uint64 {
-	if base < 2 {
-		return 0
-	}
-	return (1<<64-1)/uint64(base) + 1
-}
-
-// ParseUint is like ParseInt but for unsigned numbers.
-func ParseUint(s string, base int, bitSize int) (n uint64, err error) {
-	var cutoff, maxVal uint64
-
-	if bitSize == 0 {
-		bitSize = int(IntSize)
-	}
-
-	s0 := s
-	switch {
-	case len(s) < 1:
-		err = ErrSyntax
-		goto Error
-
-	case 2 <= base && base <= 36:
-		// valid base; nothing to do
-
-	case base == 0:
-		// Look for octal, hex prefix.
-		switch {
-		case s[0] == '0' && len(s) > 1 && (s[1] == 'x' || s[1] == 'X'):
-			base = 16
-			s = s[2:]
-			if len(s) < 1 {
-				err = ErrSyntax
-				goto Error
-			}
-		case s[0] == '0':
-			base = 8
-		default:
-			base = 10
-		}
-
-	default:
-		err = errors.New("invalid base " + Itoa(base))
-		goto Error
-	}
-
-	n = 0
-	cutoff = cutoff64(base)
-	maxVal = 1<<uint(bitSize) - 1
-
-	for i := 0; i < len(s); i++ {
-		var v byte
-		d := s[i]
-		switch {
-		case '0' <= d && d <= '9':
-			v = d - '0'
-		case 'a' <= d && d <= 'z':
-			v = d - 'a' + 10
-		case 'A' <= d && d <= 'Z':
-			v = d - 'A' + 10
-		default:
-			n = 0
-			err = ErrSyntax
-			goto Error
-		}
-		if int(v) >= base {
-			n = 0
-			err = ErrSyntax
-			goto Error
-		}
-
-		if n >= cutoff {
-			// n*base overflows
-			n = 1<<64 - 1
-			err = ErrRange
-			goto Error
-		}
-		n *= uint64(base)
-
-		n1 := n + uint64(v)
-		if n1 < n || n1 > maxVal {
-			// n+v overflows
-			n = 1<<64 - 1
-			err = ErrRange
-			goto Error
-		}
-		n = n1
-	}
-
-	return n, nil
-
-Error:
-	return n, &NumError{"ParseUint", s0, err}
-}
-
-// ParseInt interprets a string s in the given base (2 to 36) and
-// returns the corresponding value i.  If base == 0, the base is
-// implied by the string's prefix: base 16 for "0x", base 8 for
-// "0", and base 10 otherwise.
-//
-// The bitSize argument specifies the integer type
-// that the result must fit into.  Bit sizes 0, 8, 16, 32, and 64
-// correspond to int, int8, int16, int32, and int64.
-//
-// The errors that ParseInt returns have concrete type *NumError
-// and include err.Num = s.  If s is empty or contains invalid
-// digits, err.Err = ErrSyntax and the returned value is 0;
-// if the value corresponding to s cannot be represented by a
-// signed integer of the given size, err.Err = ErrRange and the
-// returned value is the maximum magnitude integer of the
-// appropriate bitSize and sign.
-func ParseInt(s string, base int, bitSize int) (i int64, err error) {
-	const fnParseInt = "ParseInt"
-
-	if bitSize == 0 {
-		bitSize = int(IntSize)
-	}
-
-	// Empty string bad.
-	if len(s) == 0 {
-		return 0, syntaxError(fnParseInt, s)
-	}
-
-	// Pick off leading sign.
-	s0 := s
-	neg := false
-	if s[0] == '+' {
-		s = s[1:]
-	} else if s[0] == '-' {
-		neg = true
-		s = s[1:]
-	}
-
-	// Convert unsigned and check range.
-	var un uint64
-	un, err = ParseUint(s, base, bitSize)
-	if err != nil && err.(*NumError).Err != ErrRange {
-		err.(*NumError).Func = fnParseInt
-		err.(*NumError).Num = s0
-		return 0, err
-	}
-	cutoff := uint64(1 << uint(bitSize-1))
-	if !neg && un >= cutoff {
-		return int64(cutoff - 1), rangeError(fnParseInt, s0)
-	}
-	if neg && un > cutoff {
-		return -int64(cutoff), rangeError(fnParseInt, s0)
-	}
-	n := int64(un)
-	if neg {
-		n = -n
-	}
-	return n, nil
-}
-
-// Atoi is shorthand for ParseInt(s, 10, 0).
-func Atoi(s string) (i int, err error) {
-	i64, err := ParseInt(s, 10, 0)
-	return int(i64), err
-}
diff --git a/src/pkg/strconv/isprint.go b/src/pkg/strconv/isprint.go
deleted file mode 100644
index 91f1795..0000000
--- a/src/pkg/strconv/isprint.go
+++ /dev/null
@@ -1,562 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// DO NOT EDIT.  GENERATED BY
-//     go run makeisprint.go >x && mv x isprint.go
-
-package strconv
-
-// (470+136+60)*2 + (218)*4 = 2204 bytes
-
-var isPrint16 = []uint16{
-	0x0020, 0x007e,
-	0x00a1, 0x0377,
-	0x037a, 0x037e,
-	0x0384, 0x0527,
-	0x0531, 0x0556,
-	0x0559, 0x058a,
-	0x058f, 0x05c7,
-	0x05d0, 0x05ea,
-	0x05f0, 0x05f4,
-	0x0606, 0x061b,
-	0x061e, 0x070d,
-	0x0710, 0x074a,
-	0x074d, 0x07b1,
-	0x07c0, 0x07fa,
-	0x0800, 0x082d,
-	0x0830, 0x085b,
-	0x085e, 0x085e,
-	0x08a0, 0x08ac,
-	0x08e4, 0x098c,
-	0x098f, 0x0990,
-	0x0993, 0x09b2,
-	0x09b6, 0x09b9,
-	0x09bc, 0x09c4,
-	0x09c7, 0x09c8,
-	0x09cb, 0x09ce,
-	0x09d7, 0x09d7,
-	0x09dc, 0x09e3,
-	0x09e6, 0x09fb,
-	0x0a01, 0x0a0a,
-	0x0a0f, 0x0a10,
-	0x0a13, 0x0a39,
-	0x0a3c, 0x0a42,
-	0x0a47, 0x0a48,
-	0x0a4b, 0x0a4d,
-	0x0a51, 0x0a51,
-	0x0a59, 0x0a5e,
-	0x0a66, 0x0a75,
-	0x0a81, 0x0ab9,
-	0x0abc, 0x0acd,
-	0x0ad0, 0x0ad0,
-	0x0ae0, 0x0ae3,
-	0x0ae6, 0x0af1,
-	0x0b01, 0x0b0c,
-	0x0b0f, 0x0b10,
-	0x0b13, 0x0b39,
-	0x0b3c, 0x0b44,
-	0x0b47, 0x0b48,
-	0x0b4b, 0x0b4d,
-	0x0b56, 0x0b57,
-	0x0b5c, 0x0b63,
-	0x0b66, 0x0b77,
-	0x0b82, 0x0b8a,
-	0x0b8e, 0x0b95,
-	0x0b99, 0x0b9f,
-	0x0ba3, 0x0ba4,
-	0x0ba8, 0x0baa,
-	0x0bae, 0x0bb9,
-	0x0bbe, 0x0bc2,
-	0x0bc6, 0x0bcd,
-	0x0bd0, 0x0bd0,
-	0x0bd7, 0x0bd7,
-	0x0be6, 0x0bfa,
-	0x0c01, 0x0c39,
-	0x0c3d, 0x0c4d,
-	0x0c55, 0x0c59,
-	0x0c60, 0x0c63,
-	0x0c66, 0x0c6f,
-	0x0c78, 0x0c7f,
-	0x0c82, 0x0cb9,
-	0x0cbc, 0x0ccd,
-	0x0cd5, 0x0cd6,
-	0x0cde, 0x0ce3,
-	0x0ce6, 0x0cf2,
-	0x0d02, 0x0d3a,
-	0x0d3d, 0x0d4e,
-	0x0d57, 0x0d57,
-	0x0d60, 0x0d63,
-	0x0d66, 0x0d75,
-	0x0d79, 0x0d7f,
-	0x0d82, 0x0d96,
-	0x0d9a, 0x0dbd,
-	0x0dc0, 0x0dc6,
-	0x0dca, 0x0dca,
-	0x0dcf, 0x0ddf,
-	0x0df2, 0x0df4,
-	0x0e01, 0x0e3a,
-	0x0e3f, 0x0e5b,
-	0x0e81, 0x0e84,
-	0x0e87, 0x0e8a,
-	0x0e8d, 0x0e8d,
-	0x0e94, 0x0ea7,
-	0x0eaa, 0x0ebd,
-	0x0ec0, 0x0ecd,
-	0x0ed0, 0x0ed9,
-	0x0edc, 0x0edf,
-	0x0f00, 0x0f6c,
-	0x0f71, 0x0fda,
-	0x1000, 0x10c7,
-	0x10cd, 0x10cd,
-	0x10d0, 0x124d,
-	0x1250, 0x125d,
-	0x1260, 0x128d,
-	0x1290, 0x12b5,
-	0x12b8, 0x12c5,
-	0x12c8, 0x1315,
-	0x1318, 0x135a,
-	0x135d, 0x137c,
-	0x1380, 0x1399,
-	0x13a0, 0x13f4,
-	0x1400, 0x169c,
-	0x16a0, 0x16f0,
-	0x1700, 0x1714,
-	0x1720, 0x1736,
-	0x1740, 0x1753,
-	0x1760, 0x1773,
-	0x1780, 0x17dd,
-	0x17e0, 0x17e9,
-	0x17f0, 0x17f9,
-	0x1800, 0x180d,
-	0x1810, 0x1819,
-	0x1820, 0x1877,
-	0x1880, 0x18aa,
-	0x18b0, 0x18f5,
-	0x1900, 0x191c,
-	0x1920, 0x192b,
-	0x1930, 0x193b,
-	0x1940, 0x1940,
-	0x1944, 0x196d,
-	0x1970, 0x1974,
-	0x1980, 0x19ab,
-	0x19b0, 0x19c9,
-	0x19d0, 0x19da,
-	0x19de, 0x1a1b,
-	0x1a1e, 0x1a7c,
-	0x1a7f, 0x1a89,
-	0x1a90, 0x1a99,
-	0x1aa0, 0x1aad,
-	0x1b00, 0x1b4b,
-	0x1b50, 0x1b7c,
-	0x1b80, 0x1bf3,
-	0x1bfc, 0x1c37,
-	0x1c3b, 0x1c49,
-	0x1c4d, 0x1c7f,
-	0x1cc0, 0x1cc7,
-	0x1cd0, 0x1cf6,
-	0x1d00, 0x1de6,
-	0x1dfc, 0x1f15,
-	0x1f18, 0x1f1d,
-	0x1f20, 0x1f45,
-	0x1f48, 0x1f4d,
-	0x1f50, 0x1f7d,
-	0x1f80, 0x1fd3,
-	0x1fd6, 0x1fef,
-	0x1ff2, 0x1ffe,
-	0x2010, 0x2027,
-	0x2030, 0x205e,
-	0x2070, 0x2071,
-	0x2074, 0x209c,
-	0x20a0, 0x20ba,
-	0x20d0, 0x20f0,
-	0x2100, 0x2189,
-	0x2190, 0x23f3,
-	0x2400, 0x2426,
-	0x2440, 0x244a,
-	0x2460, 0x2b4c,
-	0x2b50, 0x2b59,
-	0x2c00, 0x2cf3,
-	0x2cf9, 0x2d27,
-	0x2d2d, 0x2d2d,
-	0x2d30, 0x2d67,
-	0x2d6f, 0x2d70,
-	0x2d7f, 0x2d96,
-	0x2da0, 0x2e3b,
-	0x2e80, 0x2ef3,
-	0x2f00, 0x2fd5,
-	0x2ff0, 0x2ffb,
-	0x3001, 0x3096,
-	0x3099, 0x30ff,
-	0x3105, 0x312d,
-	0x3131, 0x31ba,
-	0x31c0, 0x31e3,
-	0x31f0, 0x4db5,
-	0x4dc0, 0x9fcc,
-	0xa000, 0xa48c,
-	0xa490, 0xa4c6,
-	0xa4d0, 0xa62b,
-	0xa640, 0xa697,
-	0xa69f, 0xa6f7,
-	0xa700, 0xa793,
-	0xa7a0, 0xa7aa,
-	0xa7f8, 0xa82b,
-	0xa830, 0xa839,
-	0xa840, 0xa877,
-	0xa880, 0xa8c4,
-	0xa8ce, 0xa8d9,
-	0xa8e0, 0xa8fb,
-	0xa900, 0xa953,
-	0xa95f, 0xa97c,
-	0xa980, 0xa9d9,
-	0xa9de, 0xa9df,
-	0xaa00, 0xaa36,
-	0xaa40, 0xaa4d,
-	0xaa50, 0xaa59,
-	0xaa5c, 0xaa7b,
-	0xaa80, 0xaac2,
-	0xaadb, 0xaaf6,
-	0xab01, 0xab06,
-	0xab09, 0xab0e,
-	0xab11, 0xab16,
-	0xab20, 0xab2e,
-	0xabc0, 0xabed,
-	0xabf0, 0xabf9,
-	0xac00, 0xd7a3,
-	0xd7b0, 0xd7c6,
-	0xd7cb, 0xd7fb,
-	0xf900, 0xfa6d,
-	0xfa70, 0xfad9,
-	0xfb00, 0xfb06,
-	0xfb13, 0xfb17,
-	0xfb1d, 0xfbc1,
-	0xfbd3, 0xfd3f,
-	0xfd50, 0xfd8f,
-	0xfd92, 0xfdc7,
-	0xfdf0, 0xfdfd,
-	0xfe00, 0xfe19,
-	0xfe20, 0xfe26,
-	0xfe30, 0xfe6b,
-	0xfe70, 0xfefc,
-	0xff01, 0xffbe,
-	0xffc2, 0xffc7,
-	0xffca, 0xffcf,
-	0xffd2, 0xffd7,
-	0xffda, 0xffdc,
-	0xffe0, 0xffee,
-	0xfffc, 0xfffd,
-}
-
-var isNotPrint16 = []uint16{
-	0x00ad,
-	0x038b,
-	0x038d,
-	0x03a2,
-	0x0560,
-	0x0588,
-	0x0590,
-	0x06dd,
-	0x083f,
-	0x08a1,
-	0x08ff,
-	0x0978,
-	0x0980,
-	0x0984,
-	0x09a9,
-	0x09b1,
-	0x09de,
-	0x0a04,
-	0x0a29,
-	0x0a31,
-	0x0a34,
-	0x0a37,
-	0x0a3d,
-	0x0a5d,
-	0x0a84,
-	0x0a8e,
-	0x0a92,
-	0x0aa9,
-	0x0ab1,
-	0x0ab4,
-	0x0ac6,
-	0x0aca,
-	0x0b04,
-	0x0b29,
-	0x0b31,
-	0x0b34,
-	0x0b5e,
-	0x0b84,
-	0x0b91,
-	0x0b9b,
-	0x0b9d,
-	0x0bc9,
-	0x0c04,
-	0x0c0d,
-	0x0c11,
-	0x0c29,
-	0x0c34,
-	0x0c45,
-	0x0c49,
-	0x0c57,
-	0x0c84,
-	0x0c8d,
-	0x0c91,
-	0x0ca9,
-	0x0cb4,
-	0x0cc5,
-	0x0cc9,
-	0x0cdf,
-	0x0cf0,
-	0x0d04,
-	0x0d0d,
-	0x0d11,
-	0x0d45,
-	0x0d49,
-	0x0d84,
-	0x0db2,
-	0x0dbc,
-	0x0dd5,
-	0x0dd7,
-	0x0e83,
-	0x0e89,
-	0x0e98,
-	0x0ea0,
-	0x0ea4,
-	0x0ea6,
-	0x0eac,
-	0x0eba,
-	0x0ec5,
-	0x0ec7,
-	0x0f48,
-	0x0f98,
-	0x0fbd,
-	0x0fcd,
-	0x10c6,
-	0x1249,
-	0x1257,
-	0x1259,
-	0x1289,
-	0x12b1,
-	0x12bf,
-	0x12c1,
-	0x12d7,
-	0x1311,
-	0x1680,
-	0x170d,
-	0x176d,
-	0x1771,
-	0x1a5f,
-	0x1f58,
-	0x1f5a,
-	0x1f5c,
-	0x1f5e,
-	0x1fb5,
-	0x1fc5,
-	0x1fdc,
-	0x1ff5,
-	0x208f,
-	0x2700,
-	0x2c2f,
-	0x2c5f,
-	0x2d26,
-	0x2da7,
-	0x2daf,
-	0x2db7,
-	0x2dbf,
-	0x2dc7,
-	0x2dcf,
-	0x2dd7,
-	0x2ddf,
-	0x2e9a,
-	0x3040,
-	0x318f,
-	0x321f,
-	0x32ff,
-	0xa78f,
-	0xa9ce,
-	0xab27,
-	0xfb37,
-	0xfb3d,
-	0xfb3f,
-	0xfb42,
-	0xfb45,
-	0xfe53,
-	0xfe67,
-	0xfe75,
-	0xffe7,
-}
-
-var isPrint32 = []uint32{
-	0x010000, 0x01004d,
-	0x010050, 0x01005d,
-	0x010080, 0x0100fa,
-	0x010100, 0x010102,
-	0x010107, 0x010133,
-	0x010137, 0x01018a,
-	0x010190, 0x01019b,
-	0x0101d0, 0x0101fd,
-	0x010280, 0x01029c,
-	0x0102a0, 0x0102d0,
-	0x010300, 0x010323,
-	0x010330, 0x01034a,
-	0x010380, 0x0103c3,
-	0x0103c8, 0x0103d5,
-	0x010400, 0x01049d,
-	0x0104a0, 0x0104a9,
-	0x010800, 0x010805,
-	0x010808, 0x010838,
-	0x01083c, 0x01083c,
-	0x01083f, 0x01085f,
-	0x010900, 0x01091b,
-	0x01091f, 0x010939,
-	0x01093f, 0x01093f,
-	0x010980, 0x0109b7,
-	0x0109be, 0x0109bf,
-	0x010a00, 0x010a06,
-	0x010a0c, 0x010a33,
-	0x010a38, 0x010a3a,
-	0x010a3f, 0x010a47,
-	0x010a50, 0x010a58,
-	0x010a60, 0x010a7f,
-	0x010b00, 0x010b35,
-	0x010b39, 0x010b55,
-	0x010b58, 0x010b72,
-	0x010b78, 0x010b7f,
-	0x010c00, 0x010c48,
-	0x010e60, 0x010e7e,
-	0x011000, 0x01104d,
-	0x011052, 0x01106f,
-	0x011080, 0x0110c1,
-	0x0110d0, 0x0110e8,
-	0x0110f0, 0x0110f9,
-	0x011100, 0x011143,
-	0x011180, 0x0111c8,
-	0x0111d0, 0x0111d9,
-	0x011680, 0x0116b7,
-	0x0116c0, 0x0116c9,
-	0x012000, 0x01236e,
-	0x012400, 0x012462,
-	0x012470, 0x012473,
-	0x013000, 0x01342e,
-	0x016800, 0x016a38,
-	0x016f00, 0x016f44,
-	0x016f50, 0x016f7e,
-	0x016f8f, 0x016f9f,
-	0x01b000, 0x01b001,
-	0x01d000, 0x01d0f5,
-	0x01d100, 0x01d126,
-	0x01d129, 0x01d172,
-	0x01d17b, 0x01d1dd,
-	0x01d200, 0x01d245,
-	0x01d300, 0x01d356,
-	0x01d360, 0x01d371,
-	0x01d400, 0x01d49f,
-	0x01d4a2, 0x01d4a2,
-	0x01d4a5, 0x01d4a6,
-	0x01d4a9, 0x01d50a,
-	0x01d50d, 0x01d546,
-	0x01d54a, 0x01d6a5,
-	0x01d6a8, 0x01d7cb,
-	0x01d7ce, 0x01d7ff,
-	0x01ee00, 0x01ee24,
-	0x01ee27, 0x01ee3b,
-	0x01ee42, 0x01ee42,
-	0x01ee47, 0x01ee54,
-	0x01ee57, 0x01ee64,
-	0x01ee67, 0x01ee9b,
-	0x01eea1, 0x01eebb,
-	0x01eef0, 0x01eef1,
-	0x01f000, 0x01f02b,
-	0x01f030, 0x01f093,
-	0x01f0a0, 0x01f0ae,
-	0x01f0b1, 0x01f0be,
-	0x01f0c1, 0x01f0df,
-	0x01f100, 0x01f10a,
-	0x01f110, 0x01f16b,
-	0x01f170, 0x01f19a,
-	0x01f1e6, 0x01f202,
-	0x01f210, 0x01f23a,
-	0x01f240, 0x01f248,
-	0x01f250, 0x01f251,
-	0x01f300, 0x01f320,
-	0x01f330, 0x01f37c,
-	0x01f380, 0x01f393,
-	0x01f3a0, 0x01f3ca,
-	0x01f3e0, 0x01f3f0,
-	0x01f400, 0x01f4fc,
-	0x01f500, 0x01f53d,
-	0x01f540, 0x01f543,
-	0x01f550, 0x01f567,
-	0x01f5fb, 0x01f640,
-	0x01f645, 0x01f64f,
-	0x01f680, 0x01f6c5,
-	0x01f700, 0x01f773,
-	0x020000, 0x02a6d6,
-	0x02a700, 0x02b734,
-	0x02b740, 0x02b81d,
-	0x02f800, 0x02fa1d,
-	0x0e0100, 0x0e01ef,
-}
-
-var isNotPrint32 = []uint16{ // add 0x10000 to each entry
-	0x000c,
-	0x0027,
-	0x003b,
-	0x003e,
-	0x031f,
-	0x039e,
-	0x0809,
-	0x0836,
-	0x0856,
-	0x0a04,
-	0x0a14,
-	0x0a18,
-	0x10bd,
-	0x1135,
-	0xd455,
-	0xd49d,
-	0xd4ad,
-	0xd4ba,
-	0xd4bc,
-	0xd4c4,
-	0xd506,
-	0xd515,
-	0xd51d,
-	0xd53a,
-	0xd53f,
-	0xd545,
-	0xd551,
-	0xee04,
-	0xee20,
-	0xee23,
-	0xee28,
-	0xee33,
-	0xee38,
-	0xee3a,
-	0xee48,
-	0xee4a,
-	0xee4c,
-	0xee50,
-	0xee53,
-	0xee58,
-	0xee5a,
-	0xee5c,
-	0xee5e,
-	0xee60,
-	0xee63,
-	0xee6b,
-	0xee73,
-	0xee78,
-	0xee7d,
-	0xee7f,
-	0xee8a,
-	0xeea4,
-	0xeeaa,
-	0xf0d0,
-	0xf12f,
-	0xf336,
-	0xf3c5,
-	0xf43f,
-	0xf441,
-	0xf4f8,
-}
diff --git a/src/pkg/strconv/makeisprint.go b/src/pkg/strconv/makeisprint.go
deleted file mode 100644
index 216159c..0000000
--- a/src/pkg/strconv/makeisprint.go
+++ /dev/null
@@ -1,165 +0,0 @@
-// Copyright 2012 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build ignore
-
-// makeisprint generates the tables for strconv's compact isPrint.
-package main
-
-import (
-	"fmt"
-	"os"
-	"unicode"
-)
-
-var (
-	range16  []uint16
-	except16 []uint16
-	range32  []uint32
-	except32 []uint32
-)
-
-// bsearch16 returns the smallest i such that a[i] >= x.
-// If there is no such i, bsearch16 returns len(a).
-func bsearch16(a []uint16, x uint16) int {
-	i, j := 0, len(a)
-	for i < j {
-		h := i + (j-i)/2
-		if a[h] < x {
-			i = h + 1
-		} else {
-			j = h
-		}
-	}
-	return i
-}
-
-// bsearch32 returns the smallest i such that a[i] >= x.
-// If there is no such i, bsearch32 returns len(a).
-func bsearch32(a []uint32, x uint32) int {
-	i, j := 0, len(a)
-	for i < j {
-		h := i + (j-i)/2
-		if a[h] < x {
-			i = h + 1
-		} else {
-			j = h
-		}
-	}
-	return i
-}
-
-func isPrint(r rune) bool {
-	// Same algorithm, either on uint16 or uint32 value.
-	// First, find first i such that rang[i] >= x.
-	// This is the index of either the start or end of a pair that might span x.
-	// The start is even (rang[i&^1]) and the end is odd (rang[i|1]).
-	// If we find x in a range, make sure x is not in exception list.
-
-	if 0 <= r && r < 1<<16 {
-		rr, rang, except := uint16(r), range16, except16
-		i := bsearch16(rang, rr)
-		if i >= len(rang) || rr < rang[i&^1] || rang[i|1] < rr {
-			return false
-		}
-		j := bsearch16(except, rr)
-		return j >= len(except) || except[j] != rr
-	}
-
-	rr, rang, except := uint32(r), range32, except32
-	i := bsearch32(rang, rr)
-	if i >= len(rang) || rr < rang[i&^1] || rang[i|1] < rr {
-		return false
-	}
-	j := bsearch32(except, rr)
-	return j >= len(except) || except[j] != rr
-}
-
-func scan(min, max rune) (rang, except []uint32) {
-	lo := rune(-1)
-	for i := min; ; i++ {
-		if (i > max || !unicode.IsPrint(i)) && lo >= 0 {
-			// End range, but avoid flip flop.
-			if i+1 <= max && unicode.IsPrint(i+1) {
-				except = append(except, uint32(i))
-				continue
-			}
-			rang = append(rang, uint32(lo), uint32(i-1))
-			lo = -1
-		}
-		if i > max {
-			break
-		}
-		if lo < 0 && unicode.IsPrint(i) {
-			lo = i
-		}
-	}
-	return
-}
-
-func to16(x []uint32) []uint16 {
-	var y []uint16
-	for _, v := range x {
-		if uint32(uint16(v)) != v {
-			panic("bad 32->16 conversion")
-		}
-		y = append(y, uint16(v))
-	}
-	return y
-}
-
-func main() {
-	rang, except := scan(0, 0xFFFF)
-	range16 = to16(rang)
-	except16 = to16(except)
-	range32, except32 = scan(0x10000, unicode.MaxRune)
-
-	for i := rune(0); i <= unicode.MaxRune; i++ {
-		if isPrint(i) != unicode.IsPrint(i) {
-			fmt.Fprintf(os.Stderr, "%U: isPrint=%v, want %v\n", i, isPrint(i), unicode.IsPrint(i))
-			return
-		}
-	}
-
-	fmt.Printf(`// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.` + "\n\n")
-	fmt.Printf("// DO NOT EDIT.  GENERATED BY\n")
-	fmt.Printf("//     go run makeisprint.go >x && mv x isprint.go\n\n")
-	fmt.Printf("package strconv\n\n")
-
-	fmt.Printf("// (%d+%d+%d)*2 + (%d)*4 = %d bytes\n\n",
-		len(range16), len(except16), len(except32),
-		len(range32),
-		(len(range16)+len(except16)+len(except32))*2+
-			(len(range32))*4)
-
-	fmt.Printf("var isPrint16 = []uint16{\n")
-	for i := 0; i < len(range16); i += 2 {
-		fmt.Printf("\t%#04x, %#04x,\n", range16[i], range16[i+1])
-	}
-	fmt.Printf("}\n\n")
-
-	fmt.Printf("var isNotPrint16 = []uint16{\n")
-	for _, r := range except16 {
-		fmt.Printf("\t%#04x,\n", r)
-	}
-	fmt.Printf("}\n\n")
-
-	fmt.Printf("var isPrint32 = []uint32{\n")
-	for i := 0; i < len(range32); i += 2 {
-		fmt.Printf("\t%#06x, %#06x,\n", range32[i], range32[i+1])
-	}
-	fmt.Printf("}\n\n")
-
-	fmt.Printf("var isNotPrint32 = []uint16{ // add 0x10000 to each entry\n")
-	for _, r := range except32 {
-		if r >= 0x20000 {
-			fmt.Fprintf(os.Stderr, "%U too big for isNotPrint32\n", r)
-			return
-		}
-		fmt.Printf("\t%#04x,\n", r-0x10000)
-	}
-	fmt.Printf("}\n")
-}
diff --git a/src/pkg/strconv/quote.go b/src/pkg/strconv/quote.go
deleted file mode 100644
index aded7e5..0000000
--- a/src/pkg/strconv/quote.go
+++ /dev/null
@@ -1,443 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package strconv
-
-import (
-	"unicode/utf8"
-)
-
-const lowerhex = "0123456789abcdef"
-
-func quoteWith(s string, quote byte, ASCIIonly bool) string {
-	var runeTmp [utf8.UTFMax]byte
-	buf := make([]byte, 0, 3*len(s)/2) // Try to avoid more allocations.
-	buf = append(buf, quote)
-	for width := 0; len(s) > 0; s = s[width:] {
-		r := rune(s[0])
-		width = 1
-		if r >= utf8.RuneSelf {
-			r, width = utf8.DecodeRuneInString(s)
-		}
-		if width == 1 && r == utf8.RuneError {
-			buf = append(buf, `\x`...)
-			buf = append(buf, lowerhex[s[0]>>4])
-			buf = append(buf, lowerhex[s[0]&0xF])
-			continue
-		}
-		if r == rune(quote) || r == '\\' { // always backslashed
-			buf = append(buf, '\\')
-			buf = append(buf, byte(r))
-			continue
-		}
-		if ASCIIonly {
-			if r < utf8.RuneSelf && IsPrint(r) {
-				buf = append(buf, byte(r))
-				continue
-			}
-		} else if IsPrint(r) {
-			n := utf8.EncodeRune(runeTmp[:], r)
-			buf = append(buf, runeTmp[:n]...)
-			continue
-		}
-		switch r {
-		case '\a':
-			buf = append(buf, `\a`...)
-		case '\b':
-			buf = append(buf, `\b`...)
-		case '\f':
-			buf = append(buf, `\f`...)
-		case '\n':
-			buf = append(buf, `\n`...)
-		case '\r':
-			buf = append(buf, `\r`...)
-		case '\t':
-			buf = append(buf, `\t`...)
-		case '\v':
-			buf = append(buf, `\v`...)
-		default:
-			switch {
-			case r < ' ':
-				buf = append(buf, `\x`...)
-				buf = append(buf, lowerhex[s[0]>>4])
-				buf = append(buf, lowerhex[s[0]&0xF])
-			case r > utf8.MaxRune:
-				r = 0xFFFD
-				fallthrough
-			case r < 0x10000:
-				buf = append(buf, `\u`...)
-				for s := 12; s >= 0; s -= 4 {
-					buf = append(buf, lowerhex[r>>uint(s)&0xF])
-				}
-			default:
-				buf = append(buf, `\U`...)
-				for s := 28; s >= 0; s -= 4 {
-					buf = append(buf, lowerhex[r>>uint(s)&0xF])
-				}
-			}
-		}
-	}
-	buf = append(buf, quote)
-	return string(buf)
-
-}
-
-// Quote returns a double-quoted Go string literal representing s.  The
-// returned string uses Go escape sequences (\t, \n, \xFF, \u0100) for
-// control characters and non-printable characters as defined by
-// IsPrint.
-func Quote(s string) string {
-	return quoteWith(s, '"', false)
-}
-
-// AppendQuote appends a double-quoted Go string literal representing s,
-// as generated by Quote, to dst and returns the extended buffer.
-func AppendQuote(dst []byte, s string) []byte {
-	return append(dst, Quote(s)...)
-}
-
-// QuoteToASCII returns a double-quoted Go string literal representing s.
-// The returned string uses Go escape sequences (\t, \n, \xFF, \u0100) for
-// non-ASCII characters and non-printable characters as defined by IsPrint.
-func QuoteToASCII(s string) string {
-	return quoteWith(s, '"', true)
-}
-
-// AppendQuoteToASCII appends a double-quoted Go string literal representing s,
-// as generated by QuoteToASCII, to dst and returns the extended buffer.
-func AppendQuoteToASCII(dst []byte, s string) []byte {
-	return append(dst, QuoteToASCII(s)...)
-}
-
-// QuoteRune returns a single-quoted Go character literal representing the
-// rune.  The returned string uses Go escape sequences (\t, \n, \xFF, \u0100)
-// for control characters and non-printable characters as defined by IsPrint.
-func QuoteRune(r rune) string {
-	// TODO: avoid the allocation here.
-	return quoteWith(string(r), '\'', false)
-}
-
-// AppendQuoteRune appends a single-quoted Go character literal representing the rune,
-// as generated by QuoteRune, to dst and returns the extended buffer.
-func AppendQuoteRune(dst []byte, r rune) []byte {
-	return append(dst, QuoteRune(r)...)
-}
-
-// QuoteRuneToASCII returns a single-quoted Go character literal representing
-// the rune.  The returned string uses Go escape sequences (\t, \n, \xFF,
-// \u0100) for non-ASCII characters and non-printable characters as defined
-// by IsPrint.
-func QuoteRuneToASCII(r rune) string {
-	// TODO: avoid the allocation here.
-	return quoteWith(string(r), '\'', true)
-}
-
-// AppendQuoteRuneToASCII appends a single-quoted Go character literal representing the rune,
-// as generated by QuoteRuneToASCII, to dst and returns the extended buffer.
-func AppendQuoteRuneToASCII(dst []byte, r rune) []byte {
-	return append(dst, QuoteRuneToASCII(r)...)
-}
-
-// CanBackquote reports whether the string s can be represented
-// unchanged as a single-line backquoted string without control
-// characters other than space and tab.
-func CanBackquote(s string) bool {
-	for i := 0; i < len(s); i++ {
-		c := s[i]
-		if (c < ' ' && c != '\t') || c == '`' || c == '\u007F' {
-			return false
-		}
-	}
-	return true
-}
-
-func unhex(b byte) (v rune, ok bool) {
-	c := rune(b)
-	switch {
-	case '0' <= c && c <= '9':
-		return c - '0', true
-	case 'a' <= c && c <= 'f':
-		return c - 'a' + 10, true
-	case 'A' <= c && c <= 'F':
-		return c - 'A' + 10, true
-	}
-	return
-}
-
-// UnquoteChar decodes the first character or byte in the escaped string
-// or character literal represented by the string s.
-// It returns four values:
-//
-//	1) value, the decoded Unicode code point or byte value;
-//	2) multibyte, a boolean indicating whether the decoded character requires a multibyte UTF-8 representation;
-//	3) tail, the remainder of the string after the character; and
-//	4) an error that will be nil if the character is syntactically valid.
-//
-// The second argument, quote, specifies the type of literal being parsed
-// and therefore which escaped quote character is permitted.
-// If set to a single quote, it permits the sequence \' and disallows unescaped '.
-// If set to a double quote, it permits \" and disallows unescaped ".
-// If set to zero, it does not permit either escape and allows both quote characters to appear unescaped.
-func UnquoteChar(s string, quote byte) (value rune, multibyte bool, tail string, err error) {
-	// easy cases
-	switch c := s[0]; {
-	case c == quote && (quote == '\'' || quote == '"'):
-		err = ErrSyntax
-		return
-	case c >= utf8.RuneSelf:
-		r, size := utf8.DecodeRuneInString(s)
-		return r, true, s[size:], nil
-	case c != '\\':
-		return rune(s[0]), false, s[1:], nil
-	}
-
-	// hard case: c is backslash
-	if len(s) <= 1 {
-		err = ErrSyntax
-		return
-	}
-	c := s[1]
-	s = s[2:]
-
-	switch c {
-	case 'a':
-		value = '\a'
-	case 'b':
-		value = '\b'
-	case 'f':
-		value = '\f'
-	case 'n':
-		value = '\n'
-	case 'r':
-		value = '\r'
-	case 't':
-		value = '\t'
-	case 'v':
-		value = '\v'
-	case 'x', 'u', 'U':
-		n := 0
-		switch c {
-		case 'x':
-			n = 2
-		case 'u':
-			n = 4
-		case 'U':
-			n = 8
-		}
-		var v rune
-		if len(s) < n {
-			err = ErrSyntax
-			return
-		}
-		for j := 0; j < n; j++ {
-			x, ok := unhex(s[j])
-			if !ok {
-				err = ErrSyntax
-				return
-			}
-			v = v<<4 | x
-		}
-		s = s[n:]
-		if c == 'x' {
-			// single-byte string, possibly not UTF-8
-			value = v
-			break
-		}
-		if v > utf8.MaxRune {
-			err = ErrSyntax
-			return
-		}
-		value = v
-		multibyte = true
-	case '0', '1', '2', '3', '4', '5', '6', '7':
-		v := rune(c) - '0'
-		if len(s) < 2 {
-			err = ErrSyntax
-			return
-		}
-		for j := 0; j < 2; j++ { // one digit already; two more
-			x := rune(s[j]) - '0'
-			if x < 0 || x > 7 {
-				err = ErrSyntax
-				return
-			}
-			v = (v << 3) | x
-		}
-		s = s[2:]
-		if v > 255 {
-			err = ErrSyntax
-			return
-		}
-		value = v
-	case '\\':
-		value = '\\'
-	case '\'', '"':
-		if c != quote {
-			err = ErrSyntax
-			return
-		}
-		value = rune(c)
-	default:
-		err = ErrSyntax
-		return
-	}
-	tail = s
-	return
-}
-
-// Unquote interprets s as a single-quoted, double-quoted,
-// or backquoted Go string literal, returning the string value
-// that s quotes.  (If s is single-quoted, it would be a Go
-// character literal; Unquote returns the corresponding
-// one-character string.)
-func Unquote(s string) (t string, err error) {
-	n := len(s)
-	if n < 2 {
-		return "", ErrSyntax
-	}
-	quote := s[0]
-	if quote != s[n-1] {
-		return "", ErrSyntax
-	}
-	s = s[1 : n-1]
-
-	if quote == '`' {
-		if contains(s, '`') {
-			return "", ErrSyntax
-		}
-		return s, nil
-	}
-	if quote != '"' && quote != '\'' {
-		return "", ErrSyntax
-	}
-	if contains(s, '\n') {
-		return "", ErrSyntax
-	}
-
-	// Is it trivial?  Avoid allocation.
-	if !contains(s, '\\') && !contains(s, quote) {
-		switch quote {
-		case '"':
-			return s, nil
-		case '\'':
-			r, size := utf8.DecodeRuneInString(s)
-			if size == len(s) && (r != utf8.RuneError || size != 1) {
-				return s, nil
-			}
-		}
-	}
-
-	var runeTmp [utf8.UTFMax]byte
-	buf := make([]byte, 0, 3*len(s)/2) // Try to avoid more allocations.
-	for len(s) > 0 {
-		c, multibyte, ss, err := UnquoteChar(s, quote)
-		if err != nil {
-			return "", err
-		}
-		s = ss
-		if c < utf8.RuneSelf || !multibyte {
-			buf = append(buf, byte(c))
-		} else {
-			n := utf8.EncodeRune(runeTmp[:], c)
-			buf = append(buf, runeTmp[:n]...)
-		}
-		if quote == '\'' && len(s) != 0 {
-			// single-quoted must be single character
-			return "", ErrSyntax
-		}
-	}
-	return string(buf), nil
-}
-
-// contains reports whether the string contains the byte c.
-func contains(s string, c byte) bool {
-	for i := 0; i < len(s); i++ {
-		if s[i] == c {
-			return true
-		}
-	}
-	return false
-}
-
-// bsearch16 returns the smallest i such that a[i] >= x.
-// If there is no such i, bsearch16 returns len(a).
-func bsearch16(a []uint16, x uint16) int {
-	i, j := 0, len(a)
-	for i < j {
-		h := i + (j-i)/2
-		if a[h] < x {
-			i = h + 1
-		} else {
-			j = h
-		}
-	}
-	return i
-}
-
-// bsearch32 returns the smallest i such that a[i] >= x.
-// If there is no such i, bsearch32 returns len(a).
-func bsearch32(a []uint32, x uint32) int {
-	i, j := 0, len(a)
-	for i < j {
-		h := i + (j-i)/2
-		if a[h] < x {
-			i = h + 1
-		} else {
-			j = h
-		}
-	}
-	return i
-}
-
-// TODO: IsPrint is a local implementation of unicode.IsPrint, verified by the tests
-// to give the same answer. It allows this package not to depend on unicode,
-// and therefore not pull in all the Unicode tables. If the linker were better
-// at tossing unused tables, we could get rid of this implementation.
-// That would be nice.
-
-// IsPrint reports whether the rune is defined as printable by Go, with
-// the same definition as unicode.IsPrint: letters, numbers, punctuation,
-// symbols and ASCII space.
-func IsPrint(r rune) bool {
-	// Fast check for Latin-1
-	if r <= 0xFF {
-		if 0x20 <= r && r <= 0x7E {
-			// All the ASCII is printable from space through DEL-1.
-			return true
-		}
-		if 0xA1 <= r && r <= 0xFF {
-			// Similarly for ¡ through ÿ...
-			return r != 0xAD // ...except for the bizarre soft hyphen.
-		}
-		return false
-	}
-
-	// Same algorithm, either on uint16 or uint32 value.
-	// First, find first i such that isPrint[i] >= x.
-	// This is the index of either the start or end of a pair that might span x.
-	// The start is even (isPrint[i&^1]) and the end is odd (isPrint[i|1]).
-	// If we find x in a range, make sure x is not in isNotPrint list.
-
-	if 0 <= r && r < 1<<16 {
-		rr, isPrint, isNotPrint := uint16(r), isPrint16, isNotPrint16
-		i := bsearch16(isPrint, rr)
-		if i >= len(isPrint) || rr < isPrint[i&^1] || isPrint[i|1] < rr {
-			return false
-		}
-		j := bsearch16(isNotPrint, rr)
-		return j >= len(isNotPrint) || isNotPrint[j] != rr
-	}
-
-	rr, isPrint, isNotPrint := uint32(r), isPrint32, isNotPrint32
-	i := bsearch32(isPrint, rr)
-	if i >= len(isPrint) || rr < isPrint[i&^1] || isPrint[i|1] < rr {
-		return false
-	}
-	if r >= 0x20000 {
-		return true
-	}
-	r -= 0x10000
-	j := bsearch16(isNotPrint, uint16(r))
-	return j >= len(isNotPrint) || isNotPrint[j] != uint16(r)
-}
diff --git a/src/pkg/strconv/quote_test.go b/src/pkg/strconv/quote_test.go
deleted file mode 100644
index e4b5b6b..0000000
--- a/src/pkg/strconv/quote_test.go
+++ /dev/null
@@ -1,262 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package strconv_test
-
-import (
-	. "strconv"
-	"testing"
-	"unicode"
-)
-
-// Verify that our isPrint agrees with unicode.IsPrint
-func TestIsPrint(t *testing.T) {
-	n := 0
-	for r := rune(0); r <= unicode.MaxRune; r++ {
-		if IsPrint(r) != unicode.IsPrint(r) {
-			t.Errorf("IsPrint(%U)=%t incorrect", r, IsPrint(r))
-			n++
-			if n > 10 {
-				return
-			}
-		}
-	}
-}
-
-type quoteTest struct {
-	in    string
-	out   string
-	ascii string
-}
-
-var quotetests = []quoteTest{
-	{"\a\b\f\r\n\t\v", `"\a\b\f\r\n\t\v"`, `"\a\b\f\r\n\t\v"`},
-	{"\\", `"\\"`, `"\\"`},
-	{"abc\xffdef", `"abc\xffdef"`, `"abc\xffdef"`},
-	{"\u263a", `"☺"`, `"\u263a"`},
-	{"\U0010ffff", `"\U0010ffff"`, `"\U0010ffff"`},
-	{"\x04", `"\x04"`, `"\x04"`},
-}
-
-func TestQuote(t *testing.T) {
-	for _, tt := range quotetests {
-		if out := Quote(tt.in); out != tt.out {
-			t.Errorf("Quote(%s) = %s, want %s", tt.in, out, tt.out)
-		}
-		if out := AppendQuote([]byte("abc"), tt.in); string(out) != "abc"+tt.out {
-			t.Errorf("AppendQuote(%q, %s) = %s, want %s", "abc", tt.in, out, "abc"+tt.out)
-		}
-	}
-}
-
-func TestQuoteToASCII(t *testing.T) {
-	for _, tt := range quotetests {
-		if out := QuoteToASCII(tt.in); out != tt.ascii {
-			t.Errorf("QuoteToASCII(%s) = %s, want %s", tt.in, out, tt.ascii)
-		}
-		if out := AppendQuoteToASCII([]byte("abc"), tt.in); string(out) != "abc"+tt.ascii {
-			t.Errorf("AppendQuoteToASCII(%q, %s) = %s, want %s", "abc", tt.in, out, "abc"+tt.ascii)
-		}
-	}
-}
-
-type quoteRuneTest struct {
-	in    rune
-	out   string
-	ascii string
-}
-
-var quoterunetests = []quoteRuneTest{
-	{'a', `'a'`, `'a'`},
-	{'\a', `'\a'`, `'\a'`},
-	{'\\', `'\\'`, `'\\'`},
-	{0xFF, `'ÿ'`, `'\u00ff'`},
-	{0x263a, `'☺'`, `'\u263a'`},
-	{0xfffd, `'�'`, `'\ufffd'`},
-	{0x0010ffff, `'\U0010ffff'`, `'\U0010ffff'`},
-	{0x0010ffff + 1, `'�'`, `'\ufffd'`},
-	{0x04, `'\x04'`, `'\x04'`},
-}
-
-func TestQuoteRune(t *testing.T) {
-	for _, tt := range quoterunetests {
-		if out := QuoteRune(tt.in); out != tt.out {
-			t.Errorf("QuoteRune(%U) = %s, want %s", tt.in, out, tt.out)
-		}
-		if out := AppendQuoteRune([]byte("abc"), tt.in); string(out) != "abc"+tt.out {
-			t.Errorf("AppendQuoteRune(%q, %U) = %s, want %s", "abc", tt.in, out, "abc"+tt.out)
-		}
-	}
-}
-
-func TestQuoteRuneToASCII(t *testing.T) {
-	for _, tt := range quoterunetests {
-		if out := QuoteRuneToASCII(tt.in); out != tt.ascii {
-			t.Errorf("QuoteRuneToASCII(%U) = %s, want %s", tt.in, out, tt.ascii)
-		}
-		if out := AppendQuoteRuneToASCII([]byte("abc"), tt.in); string(out) != "abc"+tt.ascii {
-			t.Errorf("AppendQuoteRuneToASCII(%q, %U) = %s, want %s", "abc", tt.in, out, "abc"+tt.ascii)
-		}
-	}
-}
-
-type canBackquoteTest struct {
-	in  string
-	out bool
-}
-
-var canbackquotetests = []canBackquoteTest{
-	{"`", false},
-	{string(0), false},
-	{string(1), false},
-	{string(2), false},
-	{string(3), false},
-	{string(4), false},
-	{string(5), false},
-	{string(6), false},
-	{string(7), false},
-	{string(8), false},
-	{string(9), true}, // \t
-	{string(10), false},
-	{string(11), false},
-	{string(12), false},
-	{string(13), false},
-	{string(14), false},
-	{string(15), false},
-	{string(16), false},
-	{string(17), false},
-	{string(18), false},
-	{string(19), false},
-	{string(20), false},
-	{string(21), false},
-	{string(22), false},
-	{string(23), false},
-	{string(24), false},
-	{string(25), false},
-	{string(26), false},
-	{string(27), false},
-	{string(28), false},
-	{string(29), false},
-	{string(30), false},
-	{string(31), false},
-	{string(0x7F), false},
-	{`' !"#$%&'()*+,-./:;<=>?@[\]^_{|}~`, true},
-	{`0123456789`, true},
-	{`ABCDEFGHIJKLMNOPQRSTUVWXYZ`, true},
-	{`abcdefghijklmnopqrstuvwxyz`, true},
-	{`☺`, true},
-}
-
-func TestCanBackquote(t *testing.T) {
-	for _, tt := range canbackquotetests {
-		if out := CanBackquote(tt.in); out != tt.out {
-			t.Errorf("CanBackquote(%q) = %v, want %v", tt.in, out, tt.out)
-		}
-	}
-}
-
-type unQuoteTest struct {
-	in  string
-	out string
-}
-
-var unquotetests = []unQuoteTest{
-	{`""`, ""},
-	{`"a"`, "a"},
-	{`"abc"`, "abc"},
-	{`"☺"`, "☺"},
-	{`"hello world"`, "hello world"},
-	{`"\xFF"`, "\xFF"},
-	{`"\377"`, "\377"},
-	{`"\u1234"`, "\u1234"},
-	{`"\U00010111"`, "\U00010111"},
-	{`"\U0001011111"`, "\U0001011111"},
-	{`"\a\b\f\n\r\t\v\\\""`, "\a\b\f\n\r\t\v\\\""},
-	{`"'"`, "'"},
-
-	{`'a'`, "a"},
-	{`'☹'`, "☹"},
-	{`'\a'`, "\a"},
-	{`'\x10'`, "\x10"},
-	{`'\377'`, "\377"},
-	{`'\u1234'`, "\u1234"},
-	{`'\U00010111'`, "\U00010111"},
-	{`'\t'`, "\t"},
-	{`' '`, " "},
-	{`'\''`, "'"},
-	{`'"'`, "\""},
-
-	{"``", ``},
-	{"`a`", `a`},
-	{"`abc`", `abc`},
-	{"`☺`", `☺`},
-	{"`hello world`", `hello world`},
-	{"`\\xFF`", `\xFF`},
-	{"`\\377`", `\377`},
-	{"`\\`", `\`},
-	{"`\n`", "\n"},
-	{"`	`", `	`},
-	{"` `", ` `},
-}
-
-var misquoted = []string{
-	``,
-	`"`,
-	`"a`,
-	`"'`,
-	`b"`,
-	`"\"`,
-	`"\9"`,
-	`"\19"`,
-	`"\129"`,
-	`'\'`,
-	`'\9'`,
-	`'\19'`,
-	`'\129'`,
-	`'ab'`,
-	`"\x1!"`,
-	`"\U12345678"`,
-	`"\z"`,
-	"`",
-	"`xxx",
-	"`\"",
-	`"\'"`,
-	`'\"'`,
-	"\"\n\"",
-	"\"\\n\n\"",
-	"'\n'",
-}
-
-func TestUnquote(t *testing.T) {
-	for _, tt := range unquotetests {
-		if out, err := Unquote(tt.in); err != nil && out != tt.out {
-			t.Errorf("Unquote(%#q) = %q, %v want %q, nil", tt.in, out, err, tt.out)
-		}
-	}
-
-	// run the quote tests too, backward
-	for _, tt := range quotetests {
-		if in, err := Unquote(tt.out); in != tt.in {
-			t.Errorf("Unquote(%#q) = %q, %v, want %q, nil", tt.out, in, err, tt.in)
-		}
-	}
-
-	for _, s := range misquoted {
-		if out, err := Unquote(s); out != "" || err != ErrSyntax {
-			t.Errorf("Unquote(%#q) = %q, %v want %q, %v", s, out, err, "", ErrSyntax)
-		}
-	}
-}
-
-func BenchmarkUnquoteEasy(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		Unquote(`"Give me a rock, paper and scissors and I will move the world."`)
-	}
-}
-
-func BenchmarkUnquoteHard(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		Unquote(`"\x47ive me a \x72ock, \x70aper and \x73cissors and \x49 will move the world."`)
-	}
-}
diff --git a/src/pkg/strings/replace.go b/src/pkg/strings/replace.go
deleted file mode 100644
index 3e05d20..0000000
--- a/src/pkg/strings/replace.go
+++ /dev/null
@@ -1,549 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package strings
-
-import "io"
-
-// A Replacer replaces a list of strings with replacements.
-type Replacer struct {
-	r replacer
-}
-
-// replacer is the interface that a replacement algorithm needs to implement.
-type replacer interface {
-	Replace(s string) string
-	WriteString(w io.Writer, s string) (n int, err error)
-}
-
-// byteBitmap represents bytes which are sought for replacement.
-// byteBitmap is 256 bits wide, with a bit set for each old byte to be
-// replaced.
-type byteBitmap [256 / 32]uint32
-
-func (m *byteBitmap) set(b byte) {
-	m[b>>5] |= uint32(1 << (b & 31))
-}
-
-// NewReplacer returns a new Replacer from a list of old, new string pairs.
-// Replacements are performed in order, without overlapping matches.
-func NewReplacer(oldnew ...string) *Replacer {
-	if len(oldnew)%2 == 1 {
-		panic("strings.NewReplacer: odd argument count")
-	}
-
-	if len(oldnew) == 2 && len(oldnew[0]) > 1 {
-		return &Replacer{r: makeSingleStringReplacer(oldnew[0], oldnew[1])}
-	}
-
-	allNewBytes := true
-	for i := 0; i < len(oldnew); i += 2 {
-		if len(oldnew[i]) != 1 {
-			return &Replacer{r: makeGenericReplacer(oldnew)}
-		}
-		if len(oldnew[i+1]) != 1 {
-			allNewBytes = false
-		}
-	}
-
-	if allNewBytes {
-		bb := &byteReplacer{}
-		for i := 0; i < len(oldnew); i += 2 {
-			o, n := oldnew[i][0], oldnew[i+1][0]
-			if bb.old[o>>5]&uint32(1<<(o&31)) != 0 {
-				// Later old->new maps do not override previous ones with the same old string.
-				continue
-			}
-			bb.old.set(o)
-			bb.new[o] = n
-		}
-		return &Replacer{r: bb}
-	}
-
-	bs := &byteStringReplacer{}
-	for i := 0; i < len(oldnew); i += 2 {
-		o, new := oldnew[i][0], oldnew[i+1]
-		if bs.old[o>>5]&uint32(1<<(o&31)) != 0 {
-			// Later old->new maps do not override previous ones with the same old string.
-			continue
-		}
-		bs.old.set(o)
-		bs.new[o] = []byte(new)
-	}
-	return &Replacer{r: bs}
-}
-
-// Replace returns a copy of s with all replacements performed.
-func (r *Replacer) Replace(s string) string {
-	return r.r.Replace(s)
-}
-
-// WriteString writes s to w with all replacements performed.
-func (r *Replacer) WriteString(w io.Writer, s string) (n int, err error) {
-	return r.r.WriteString(w, s)
-}
-
-// trieNode is a node in a lookup trie for prioritized key/value pairs. Keys
-// and values may be empty. For example, the trie containing keys "ax", "ay",
-// "bcbc", "x" and "xy" could have eight nodes:
-//
-//  n0  -
-//  n1  a-
-//  n2  .x+
-//  n3  .y+
-//  n4  b-
-//  n5  .cbc+
-//  n6  x+
-//  n7  .y+
-//
-// n0 is the root node, and its children are n1, n4 and n6; n1's children are
-// n2 and n3; n4's child is n5; n6's child is n7. Nodes n0, n1 and n4 (marked
-// with a trailing "-") are partial keys, and nodes n2, n3, n5, n6 and n7
-// (marked with a trailing "+") are complete keys.
-type trieNode struct {
-	// value is the value of the trie node's key/value pair. It is empty if
-	// this node is not a complete key.
-	value string
-	// priority is the priority (higher is more important) of the trie node's
-	// key/value pair; keys are not necessarily matched shortest- or longest-
-	// first. Priority is positive if this node is a complete key, and zero
-	// otherwise. In the example above, positive/zero priorities are marked
-	// with a trailing "+" or "-".
-	priority int
-
-	// A trie node may have zero, one or more child nodes:
-	//  * if the remaining fields are zero, there are no children.
-	//  * if prefix and next are non-zero, there is one child in next.
-	//  * if table is non-zero, it defines all the children.
-	//
-	// Prefixes are preferred over tables when there is one child, but the
-	// root node always uses a table for lookup efficiency.
-
-	// prefix is the difference in keys between this trie node and the next.
-	// In the example above, node n4 has prefix "cbc" and n4's next node is n5.
-	// Node n5 has no children and so has zero prefix, next and table fields.
-	prefix string
-	next   *trieNode
-
-	// table is a lookup table indexed by the next byte in the key, after
-	// remapping that byte through genericReplacer.mapping to create a dense
-	// index. In the example above, the keys only use 'a', 'b', 'c', 'x' and
-	// 'y', which remap to 0, 1, 2, 3 and 4. All other bytes remap to 5, and
-	// genericReplacer.tableSize will be 5. Node n0's table will be
-	// []*trieNode{ 0:n1, 1:n4, 3:n6 }, where the 0, 1 and 3 are the remapped
-	// 'a', 'b' and 'x'.
-	table []*trieNode
-}
-
-func (t *trieNode) add(key, val string, priority int, r *genericReplacer) {
-	if key == "" {
-		if t.priority == 0 {
-			t.value = val
-			t.priority = priority
-		}
-		return
-	}
-
-	if t.prefix != "" {
-		// Need to split the prefix among multiple nodes.
-		var n int // length of the longest common prefix
-		for ; n < len(t.prefix) && n < len(key); n++ {
-			if t.prefix[n] != key[n] {
-				break
-			}
-		}
-		if n == len(t.prefix) {
-			t.next.add(key[n:], val, priority, r)
-		} else if n == 0 {
-			// First byte differs, start a new lookup table here. Looking up
-			// what is currently t.prefix[0] will lead to prefixNode, and
-			// looking up key[0] will lead to keyNode.
-			var prefixNode *trieNode
-			if len(t.prefix) == 1 {
-				prefixNode = t.next
-			} else {
-				prefixNode = &trieNode{
-					prefix: t.prefix[1:],
-					next:   t.next,
-				}
-			}
-			keyNode := new(trieNode)
-			t.table = make([]*trieNode, r.tableSize)
-			t.table[r.mapping[t.prefix[0]]] = prefixNode
-			t.table[r.mapping[key[0]]] = keyNode
-			t.prefix = ""
-			t.next = nil
-			keyNode.add(key[1:], val, priority, r)
-		} else {
-			// Insert new node after the common section of the prefix.
-			next := &trieNode{
-				prefix: t.prefix[n:],
-				next:   t.next,
-			}
-			t.prefix = t.prefix[:n]
-			t.next = next
-			next.add(key[n:], val, priority, r)
-		}
-	} else if t.table != nil {
-		// Insert into existing table.
-		m := r.mapping[key[0]]
-		if t.table[m] == nil {
-			t.table[m] = new(trieNode)
-		}
-		t.table[m].add(key[1:], val, priority, r)
-	} else {
-		t.prefix = key
-		t.next = new(trieNode)
-		t.next.add("", val, priority, r)
-	}
-}
-
-func (r *genericReplacer) lookup(s string, ignoreRoot bool) (val string, keylen int, found bool) {
-	// Iterate down the trie to the end, and grab the value and keylen with
-	// the highest priority.
-	bestPriority := 0
-	node := &r.root
-	n := 0
-	for node != nil {
-		if node.priority > bestPriority && !(ignoreRoot && node == &r.root) {
-			bestPriority = node.priority
-			val = node.value
-			keylen = n
-			found = true
-		}
-
-		if s == "" {
-			break
-		}
-		if node.table != nil {
-			index := r.mapping[s[0]]
-			if int(index) == r.tableSize {
-				break
-			}
-			node = node.table[index]
-			s = s[1:]
-			n++
-		} else if node.prefix != "" && HasPrefix(s, node.prefix) {
-			n += len(node.prefix)
-			s = s[len(node.prefix):]
-			node = node.next
-		} else {
-			break
-		}
-	}
-	return
-}
-
-// genericReplacer is the fully generic algorithm.
-// It's used as a fallback when nothing faster can be used.
-type genericReplacer struct {
-	root trieNode
-	// tableSize is the size of a trie node's lookup table. It is the number
-	// of unique key bytes.
-	tableSize int
-	// mapping maps from key bytes to a dense index for trieNode.table.
-	mapping [256]byte
-}
-
-func makeGenericReplacer(oldnew []string) *genericReplacer {
-	r := new(genericReplacer)
-	// Find each byte used, then assign them each an index.
-	for i := 0; i < len(oldnew); i += 2 {
-		key := oldnew[i]
-		for j := 0; j < len(key); j++ {
-			r.mapping[key[j]] = 1
-		}
-	}
-
-	for _, b := range r.mapping {
-		r.tableSize += int(b)
-	}
-
-	var index byte
-	for i, b := range r.mapping {
-		if b == 0 {
-			r.mapping[i] = byte(r.tableSize)
-		} else {
-			r.mapping[i] = index
-			index++
-		}
-	}
-	// Ensure root node uses a lookup table (for performance).
-	r.root.table = make([]*trieNode, r.tableSize)
-
-	for i := 0; i < len(oldnew); i += 2 {
-		r.root.add(oldnew[i], oldnew[i+1], len(oldnew)-i, r)
-	}
-	return r
-}
-
-type appendSliceWriter []byte
-
-// Write writes to the buffer to satisfy io.Writer.
-func (w *appendSliceWriter) Write(p []byte) (int, error) {
-	*w = append(*w, p...)
-	return len(p), nil
-}
-
-// WriteString writes to the buffer without string->[]byte->string allocations.
-func (w *appendSliceWriter) WriteString(s string) (int, error) {
-	*w = append(*w, s...)
-	return len(s), nil
-}
-
-type stringWriterIface interface {
-	WriteString(string) (int, error)
-}
-
-type stringWriter struct {
-	w io.Writer
-}
-
-func (w stringWriter) WriteString(s string) (int, error) {
-	return w.w.Write([]byte(s))
-}
-
-func getStringWriter(w io.Writer) stringWriterIface {
-	sw, ok := w.(stringWriterIface)
-	if !ok {
-		sw = stringWriter{w}
-	}
-	return sw
-}
-
-func (r *genericReplacer) Replace(s string) string {
-	buf := make(appendSliceWriter, 0, len(s))
-	r.WriteString(&buf, s)
-	return string(buf)
-}
-
-func (r *genericReplacer) WriteString(w io.Writer, s string) (n int, err error) {
-	sw := getStringWriter(w)
-	var last, wn int
-	var prevMatchEmpty bool
-	for i := 0; i <= len(s); {
-		// Ignore the empty match iff the previous loop found the empty match.
-		val, keylen, match := r.lookup(s[i:], prevMatchEmpty)
-		prevMatchEmpty = match && keylen == 0
-		if match {
-			wn, err = sw.WriteString(s[last:i])
-			n += wn
-			if err != nil {
-				return
-			}
-			wn, err = sw.WriteString(val)
-			n += wn
-			if err != nil {
-				return
-			}
-			i += keylen
-			last = i
-			continue
-		}
-		i++
-	}
-	if last != len(s) {
-		wn, err = sw.WriteString(s[last:])
-		n += wn
-	}
-	return
-}
-
-// singleStringReplacer is the implementation that's used when there is only
-// one string to replace (and that string has more than one byte).
-type singleStringReplacer struct {
-	finder *stringFinder
-	// value is the new string that replaces that pattern when it's found.
-	value string
-}
-
-func makeSingleStringReplacer(pattern string, value string) *singleStringReplacer {
-	return &singleStringReplacer{finder: makeStringFinder(pattern), value: value}
-}
-
-func (r *singleStringReplacer) Replace(s string) string {
-	var buf []byte
-	i, matched := 0, false
-	for {
-		match := r.finder.next(s[i:])
-		if match == -1 {
-			break
-		}
-		matched = true
-		buf = append(buf, s[i:i+match]...)
-		buf = append(buf, r.value...)
-		i += match + len(r.finder.pattern)
-	}
-	if !matched {
-		return s
-	}
-	buf = append(buf, s[i:]...)
-	return string(buf)
-}
-
-func (r *singleStringReplacer) WriteString(w io.Writer, s string) (n int, err error) {
-	sw := getStringWriter(w)
-	var i, wn int
-	for {
-		match := r.finder.next(s[i:])
-		if match == -1 {
-			break
-		}
-		wn, err = sw.WriteString(s[i : i+match])
-		n += wn
-		if err != nil {
-			return
-		}
-		wn, err = sw.WriteString(r.value)
-		n += wn
-		if err != nil {
-			return
-		}
-		i += match + len(r.finder.pattern)
-	}
-	wn, err = sw.WriteString(s[i:])
-	n += wn
-	return
-}
-
-// byteReplacer is the implementation that's used when all the "old"
-// and "new" values are single ASCII bytes.
-type byteReplacer struct {
-	// old has a bit set for each old byte that should be replaced.
-	old byteBitmap
-
-	// replacement byte, indexed by old byte. only valid if
-	// corresponding old bit is set.
-	new [256]byte
-}
-
-func (r *byteReplacer) Replace(s string) string {
-	var buf []byte // lazily allocated
-	for i := 0; i < len(s); i++ {
-		b := s[i]
-		if r.old[b>>5]&uint32(1<<(b&31)) != 0 {
-			if buf == nil {
-				buf = []byte(s)
-			}
-			buf[i] = r.new[b]
-		}
-	}
-	if buf == nil {
-		return s
-	}
-	return string(buf)
-}
-
-func (r *byteReplacer) WriteString(w io.Writer, s string) (n int, err error) {
-	// TODO(bradfitz): use io.WriteString with slices of s, avoiding allocation.
-	bufsize := 32 << 10
-	if len(s) < bufsize {
-		bufsize = len(s)
-	}
-	buf := make([]byte, bufsize)
-
-	for len(s) > 0 {
-		ncopy := copy(buf, s[:])
-		s = s[ncopy:]
-		for i, b := range buf[:ncopy] {
-			if r.old[b>>5]&uint32(1<<(b&31)) != 0 {
-				buf[i] = r.new[b]
-			}
-		}
-		wn, err := w.Write(buf[:ncopy])
-		n += wn
-		if err != nil {
-			return n, err
-		}
-	}
-	return n, nil
-}
-
-// byteStringReplacer is the implementation that's used when all the
-// "old" values are single ASCII bytes but the "new" values vary in
-// size.
-type byteStringReplacer struct {
-	// old has a bit set for each old byte that should be replaced.
-	old byteBitmap
-
-	// replacement string, indexed by old byte. only valid if
-	// corresponding old bit is set.
-	new [256][]byte
-}
-
-func (r *byteStringReplacer) Replace(s string) string {
-	newSize := 0
-	anyChanges := false
-	for i := 0; i < len(s); i++ {
-		b := s[i]
-		if r.old[b>>5]&uint32(1<<(b&31)) != 0 {
-			anyChanges = true
-			newSize += len(r.new[b])
-		} else {
-			newSize++
-		}
-	}
-	if !anyChanges {
-		return s
-	}
-	buf := make([]byte, newSize)
-	bi := buf
-	for i := 0; i < len(s); i++ {
-		b := s[i]
-		if r.old[b>>5]&uint32(1<<(b&31)) != 0 {
-			n := copy(bi, r.new[b])
-			bi = bi[n:]
-		} else {
-			bi[0] = b
-			bi = bi[1:]
-		}
-	}
-	return string(buf)
-}
-
-// WriteString maintains one buffer that's at most 32KB.  The bytes in
-// s are enumerated and the buffer is filled.  If it reaches its
-// capacity or a byte has a replacement, the buffer is flushed to w.
-func (r *byteStringReplacer) WriteString(w io.Writer, s string) (n int, err error) {
-	// TODO(bradfitz): use io.WriteString with slices of s instead.
-	bufsize := 32 << 10
-	if len(s) < bufsize {
-		bufsize = len(s)
-	}
-	buf := make([]byte, bufsize)
-	bi := buf[:0]
-
-	for i := 0; i < len(s); i++ {
-		b := s[i]
-		var new []byte
-		if r.old[b>>5]&uint32(1<<(b&31)) != 0 {
-			new = r.new[b]
-		} else {
-			bi = append(bi, b)
-		}
-		if len(bi) == cap(bi) || (len(bi) > 0 && len(new) > 0) {
-			nw, err := w.Write(bi)
-			n += nw
-			if err != nil {
-				return n, err
-			}
-			bi = buf[:0]
-		}
-		if len(new) > 0 {
-			nw, err := w.Write(new)
-			n += nw
-			if err != nil {
-				return n, err
-			}
-		}
-	}
-	if len(bi) > 0 {
-		nw, err := w.Write(bi)
-		n += nw
-		if err != nil {
-			return n, err
-		}
-	}
-	return n, nil
-}
diff --git a/src/pkg/strings/replace_test.go b/src/pkg/strings/replace_test.go
deleted file mode 100644
index 82e4b6e..0000000
--- a/src/pkg/strings/replace_test.go
+++ /dev/null
@@ -1,506 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package strings_test
-
-import (
-	"bytes"
-	"fmt"
-	. "strings"
-	"testing"
-)
-
-var htmlEscaper = NewReplacer(
-	"&", "&",
-	"<", "<",
-	">", ">",
-	`"`, """,
-	"'", "'",
-)
-
-var htmlUnescaper = NewReplacer(
-	"&", "&",
-	"<", "<",
-	">", ">",
-	""", `"`,
-	"'", "'",
-)
-
-// The http package's old HTML escaping function.
-func oldHTMLEscape(s string) string {
-	s = Replace(s, "&", "&", -1)
-	s = Replace(s, "<", "<", -1)
-	s = Replace(s, ">", ">", -1)
-	s = Replace(s, `"`, """, -1)
-	s = Replace(s, "'", "'", -1)
-	return s
-}
-
-var capitalLetters = NewReplacer("a", "A", "b", "B")
-
-// TestReplacer tests the replacer implementations.
-func TestReplacer(t *testing.T) {
-	type testCase struct {
-		r       *Replacer
-		in, out string
-	}
-	var testCases []testCase
-
-	// str converts 0xff to "\xff". This isn't just string(b) since that converts to UTF-8.
-	str := func(b byte) string {
-		return string([]byte{b})
-	}
-	var s []string
-
-	// inc maps "\x00"->"\x01", ..., "a"->"b", "b"->"c", ..., "\xff"->"\x00".
-	s = nil
-	for i := 0; i < 256; i++ {
-		s = append(s, str(byte(i)), str(byte(i+1)))
-	}
-	inc := NewReplacer(s...)
-
-	// Test cases with 1-byte old strings, 1-byte new strings.
-	testCases = append(testCases,
-		testCase{capitalLetters, "brad", "BrAd"},
-		testCase{capitalLetters, Repeat("a", (32<<10)+123), Repeat("A", (32<<10)+123)},
-		testCase{capitalLetters, "", ""},
-
-		testCase{inc, "brad", "csbe"},
-		testCase{inc, "\x00\xff", "\x01\x00"},
-		testCase{inc, "", ""},
-
-		testCase{NewReplacer("a", "1", "a", "2"), "brad", "br1d"},
-	)
-
-	// repeat maps "a"->"a", "b"->"bb", "c"->"ccc", ...
-	s = nil
-	for i := 0; i < 256; i++ {
-		n := i + 1 - 'a'
-		if n < 1 {
-			n = 1
-		}
-		s = append(s, str(byte(i)), Repeat(str(byte(i)), n))
-	}
-	repeat := NewReplacer(s...)
-
-	// Test cases with 1-byte old strings, variable length new strings.
-	testCases = append(testCases,
-		testCase{htmlEscaper, "No changes", "No changes"},
-		testCase{htmlEscaper, "I <3 escaping & stuff", "I <3 escaping & stuff"},
-		testCase{htmlEscaper, "&&&", "&&&"},
-		testCase{htmlEscaper, "", ""},
-
-		testCase{repeat, "brad", "bbrrrrrrrrrrrrrrrrrradddd"},
-		testCase{repeat, "abba", "abbbba"},
-		testCase{repeat, "", ""},
-
-		testCase{NewReplacer("a", "11", "a", "22"), "brad", "br11d"},
-	)
-
-	// The remaining test cases have variable length old strings.
-
-	testCases = append(testCases,
-		testCase{htmlUnescaper, "&amp;", "&"},
-		testCase{htmlUnescaper, "<b>HTML's neat</b>", "<b>HTML's neat</b>"},
-		testCase{htmlUnescaper, "", ""},
-
-		testCase{NewReplacer("a", "1", "a", "2", "xxx", "xxx"), "brad", "br1d"},
-
-		testCase{NewReplacer("a", "1", "aa", "2", "aaa", "3"), "aaaa", "1111"},
-
-		testCase{NewReplacer("aaa", "3", "aa", "2", "a", "1"), "aaaa", "31"},
-	)
-
-	// gen1 has multiple old strings of variable length. There is no
-	// overall non-empty common prefix, but some pairwise common prefixes.
-	gen1 := NewReplacer(
-		"aaa", "3[aaa]",
-		"aa", "2[aa]",
-		"a", "1[a]",
-		"i", "i",
-		"longerst", "most long",
-		"longer", "medium",
-		"long", "short",
-		"xx", "xx",
-		"x", "X",
-		"X", "Y",
-		"Y", "Z",
-	)
-	testCases = append(testCases,
-		testCase{gen1, "fooaaabar", "foo3[aaa]b1[a]r"},
-		testCase{gen1, "long, longerst, longer", "short, most long, medium"},
-		testCase{gen1, "xxxxx", "xxxxX"},
-		testCase{gen1, "XiX", "YiY"},
-		testCase{gen1, "", ""},
-	)
-
-	// gen2 has multiple old strings with no pairwise common prefix.
-	gen2 := NewReplacer(
-		"roses", "red",
-		"violets", "blue",
-		"sugar", "sweet",
-	)
-	testCases = append(testCases,
-		testCase{gen2, "roses are red, violets are blue...", "red are red, blue are blue..."},
-		testCase{gen2, "", ""},
-	)
-
-	// gen3 has multiple old strings with an overall common prefix.
-	gen3 := NewReplacer(
-		"abracadabra", "poof",
-		"abracadabrakazam", "splat",
-		"abraham", "lincoln",
-		"abrasion", "scrape",
-		"abraham", "isaac",
-	)
-	testCases = append(testCases,
-		testCase{gen3, "abracadabrakazam abraham", "poofkazam lincoln"},
-		testCase{gen3, "abrasion abracad", "scrape abracad"},
-		testCase{gen3, "abba abram abrasive", "abba abram abrasive"},
-		testCase{gen3, "", ""},
-	)
-
-	// foo{1,2,3,4} have multiple old strings with an overall common prefix
-	// and 1- or 2- byte extensions from the common prefix.
-	foo1 := NewReplacer(
-		"foo1", "A",
-		"foo2", "B",
-		"foo3", "C",
-	)
-	foo2 := NewReplacer(
-		"foo1", "A",
-		"foo2", "B",
-		"foo31", "C",
-		"foo32", "D",
-	)
-	foo3 := NewReplacer(
-		"foo11", "A",
-		"foo12", "B",
-		"foo31", "C",
-		"foo32", "D",
-	)
-	foo4 := NewReplacer(
-		"foo12", "B",
-		"foo32", "D",
-	)
-	testCases = append(testCases,
-		testCase{foo1, "fofoofoo12foo32oo", "fofooA2C2oo"},
-		testCase{foo1, "", ""},
-
-		testCase{foo2, "fofoofoo12foo32oo", "fofooA2Doo"},
-		testCase{foo2, "", ""},
-
-		testCase{foo3, "fofoofoo12foo32oo", "fofooBDoo"},
-		testCase{foo3, "", ""},
-
-		testCase{foo4, "fofoofoo12foo32oo", "fofooBDoo"},
-		testCase{foo4, "", ""},
-	)
-
-	// genAll maps "\x00\x01\x02...\xfe\xff" to "[all]", amongst other things.
-	allBytes := make([]byte, 256)
-	for i := range allBytes {
-		allBytes[i] = byte(i)
-	}
-	allString := string(allBytes)
-	genAll := NewReplacer(
-		allString, "[all]",
-		"\xff", "[ff]",
-		"\x00", "[00]",
-	)
-	testCases = append(testCases,
-		testCase{genAll, allString, "[all]"},
-		testCase{genAll, "a\xff" + allString + "\x00", "a[ff][all][00]"},
-		testCase{genAll, "", ""},
-	)
-
-	// Test cases with empty old strings.
-
-	blankToX1 := NewReplacer("", "X")
-	blankToX2 := NewReplacer("", "X", "", "")
-	blankHighPriority := NewReplacer("", "X", "o", "O")
-	blankLowPriority := NewReplacer("o", "O", "", "X")
-	blankNoOp1 := NewReplacer("", "")
-	blankNoOp2 := NewReplacer("", "", "", "A")
-	blankFoo := NewReplacer("", "X", "foobar", "R", "foobaz", "Z")
-	testCases = append(testCases,
-		testCase{blankToX1, "foo", "XfXoXoX"},
-		testCase{blankToX1, "", "X"},
-
-		testCase{blankToX2, "foo", "XfXoXoX"},
-		testCase{blankToX2, "", "X"},
-
-		testCase{blankHighPriority, "oo", "XOXOX"},
-		testCase{blankHighPriority, "ii", "XiXiX"},
-		testCase{blankHighPriority, "oiio", "XOXiXiXOX"},
-		testCase{blankHighPriority, "iooi", "XiXOXOXiX"},
-		testCase{blankHighPriority, "", "X"},
-
-		testCase{blankLowPriority, "oo", "OOX"},
-		testCase{blankLowPriority, "ii", "XiXiX"},
-		testCase{blankLowPriority, "oiio", "OXiXiOX"},
-		testCase{blankLowPriority, "iooi", "XiOOXiX"},
-		testCase{blankLowPriority, "", "X"},
-
-		testCase{blankNoOp1, "foo", "foo"},
-		testCase{blankNoOp1, "", ""},
-
-		testCase{blankNoOp2, "foo", "foo"},
-		testCase{blankNoOp2, "", ""},
-
-		testCase{blankFoo, "foobarfoobaz", "XRXZX"},
-		testCase{blankFoo, "foobar-foobaz", "XRX-XZX"},
-		testCase{blankFoo, "", "X"},
-	)
-
-	// single string replacer
-
-	abcMatcher := NewReplacer("abc", "[match]")
-
-	testCases = append(testCases,
-		testCase{abcMatcher, "", ""},
-		testCase{abcMatcher, "ab", "ab"},
-		testCase{abcMatcher, "abc", "[match]"},
-		testCase{abcMatcher, "abcd", "[match]d"},
-		testCase{abcMatcher, "cabcabcdabca", "c[match][match]d[match]a"},
-	)
-
-	// Issue 6659 cases (more single string replacer)
-
-	noHello := NewReplacer("Hello", "")
-	testCases = append(testCases,
-		testCase{noHello, "Hello", ""},
-		testCase{noHello, "Hellox", "x"},
-		testCase{noHello, "xHello", "x"},
-		testCase{noHello, "xHellox", "xx"},
-	)
-
-	// No-arg test cases.
-
-	nop := NewReplacer()
-	testCases = append(testCases,
-		testCase{nop, "abc", "abc"},
-		testCase{nop, "", ""},
-	)
-
-	// Run the test cases.
-
-	for i, tc := range testCases {
-		if s := tc.r.Replace(tc.in); s != tc.out {
-			t.Errorf("%d. Replace(%q) = %q, want %q", i, tc.in, s, tc.out)
-		}
-		var buf bytes.Buffer
-		n, err := tc.r.WriteString(&buf, tc.in)
-		if err != nil {
-			t.Errorf("%d. WriteString: %v", i, err)
-			continue
-		}
-		got := buf.String()
-		if got != tc.out {
-			t.Errorf("%d. WriteString(%q) wrote %q, want %q", i, tc.in, got, tc.out)
-			continue
-		}
-		if n != len(tc.out) {
-			t.Errorf("%d. WriteString(%q) wrote correct string but reported %d bytes; want %d (%q)",
-				i, tc.in, n, len(tc.out), tc.out)
-		}
-	}
-}
-
-// TestPickAlgorithm tests that NewReplacer picks the correct algorithm.
-func TestPickAlgorithm(t *testing.T) {
-	testCases := []struct {
-		r    *Replacer
-		want string
-	}{
-		{capitalLetters, "*strings.byteReplacer"},
-		{htmlEscaper, "*strings.byteStringReplacer"},
-		{NewReplacer("12", "123"), "*strings.singleStringReplacer"},
-		{NewReplacer("1", "12"), "*strings.byteStringReplacer"},
-		{NewReplacer("", "X"), "*strings.genericReplacer"},
-		{NewReplacer("a", "1", "b", "12", "cde", "123"), "*strings.genericReplacer"},
-	}
-	for i, tc := range testCases {
-		got := fmt.Sprintf("%T", tc.r.Replacer())
-		if got != tc.want {
-			t.Errorf("%d. algorithm = %s, want %s", i, got, tc.want)
-		}
-	}
-}
-
-// TestGenericTrieBuilding verifies the structure of the generated trie. There
-// is one node per line, and the key ending with the current line is in the
-// trie if it ends with a "+".
-func TestGenericTrieBuilding(t *testing.T) {
-	testCases := []struct{ in, out string }{
-		{"abc;abdef;abdefgh;xx;xy;z", `-
-			a-
-			.b-
-			..c+
-			..d-
-			...ef+
-			.....gh+
-			x-
-			.x+
-			.y+
-			z+
-			`},
-		{"abracadabra;abracadabrakazam;abraham;abrasion", `-
-			a-
-			.bra-
-			....c-
-			.....adabra+
-			...........kazam+
-			....h-
-			.....am+
-			....s-
-			.....ion+
-			`},
-		{"aaa;aa;a;i;longerst;longer;long;xx;x;X;Y", `-
-			X+
-			Y+
-			a+
-			.a+
-			..a+
-			i+
-			l-
-			.ong+
-			....er+
-			......st+
-			x+
-			.x+
-			`},
-		{"foo;;foo;foo1", `+
-			f-
-			.oo+
-			...1+
-			`},
-	}
-
-	for _, tc := range testCases {
-		keys := Split(tc.in, ";")
-		args := make([]string, len(keys)*2)
-		for i, key := range keys {
-			args[i*2] = key
-		}
-
-		got := NewReplacer(args...).PrintTrie()
-		// Remove tabs from tc.out
-		wantbuf := make([]byte, 0, len(tc.out))
-		for i := 0; i < len(tc.out); i++ {
-			if tc.out[i] != '\t' {
-				wantbuf = append(wantbuf, tc.out[i])
-			}
-		}
-		want := string(wantbuf)
-
-		if got != want {
-			t.Errorf("PrintTrie(%q)\ngot\n%swant\n%s", tc.in, got, want)
-		}
-	}
-}
-
-func BenchmarkGenericNoMatch(b *testing.B) {
-	str := Repeat("A", 100) + Repeat("B", 100)
-	generic := NewReplacer("a", "A", "b", "B", "12", "123") // varying lengths forces generic
-	for i := 0; i < b.N; i++ {
-		generic.Replace(str)
-	}
-}
-
-func BenchmarkGenericMatch1(b *testing.B) {
-	str := Repeat("a", 100) + Repeat("b", 100)
-	generic := NewReplacer("a", "A", "b", "B", "12", "123")
-	for i := 0; i < b.N; i++ {
-		generic.Replace(str)
-	}
-}
-
-func BenchmarkGenericMatch2(b *testing.B) {
-	str := Repeat("It's <b>HTML</b>!", 100)
-	for i := 0; i < b.N; i++ {
-		htmlUnescaper.Replace(str)
-	}
-}
-
-func benchmarkSingleString(b *testing.B, pattern, text string) {
-	r := NewReplacer(pattern, "[match]")
-	b.SetBytes(int64(len(text)))
-	b.ResetTimer()
-	for i := 0; i < b.N; i++ {
-		r.Replace(text)
-	}
-}
-
-func BenchmarkSingleMaxSkipping(b *testing.B) {
-	benchmarkSingleString(b, Repeat("b", 25), Repeat("a", 10000))
-}
-
-func BenchmarkSingleLongSuffixFail(b *testing.B) {
-	benchmarkSingleString(b, "b"+Repeat("a", 500), Repeat("a", 1002))
-}
-
-func BenchmarkSingleMatch(b *testing.B) {
-	benchmarkSingleString(b, "abcdef", Repeat("abcdefghijklmno", 1000))
-}
-
-func BenchmarkByteByteNoMatch(b *testing.B) {
-	str := Repeat("A", 100) + Repeat("B", 100)
-	for i := 0; i < b.N; i++ {
-		capitalLetters.Replace(str)
-	}
-}
-
-func BenchmarkByteByteMatch(b *testing.B) {
-	str := Repeat("a", 100) + Repeat("b", 100)
-	for i := 0; i < b.N; i++ {
-		capitalLetters.Replace(str)
-	}
-}
-
-func BenchmarkByteStringMatch(b *testing.B) {
-	str := "<" + Repeat("a", 99) + Repeat("b", 99) + ">"
-	for i := 0; i < b.N; i++ {
-		htmlEscaper.Replace(str)
-	}
-}
-
-func BenchmarkHTMLEscapeNew(b *testing.B) {
-	str := "I <3 to escape HTML & other text too."
-	for i := 0; i < b.N; i++ {
-		htmlEscaper.Replace(str)
-	}
-}
-
-func BenchmarkHTMLEscapeOld(b *testing.B) {
-	str := "I <3 to escape HTML & other text too."
-	for i := 0; i < b.N; i++ {
-		oldHTMLEscape(str)
-	}
-}
-
-// BenchmarkByteByteReplaces compares byteByteImpl against multiple Replaces.
-func BenchmarkByteByteReplaces(b *testing.B) {
-	str := Repeat("a", 100) + Repeat("b", 100)
-	for i := 0; i < b.N; i++ {
-		Replace(Replace(str, "a", "A", -1), "b", "B", -1)
-	}
-}
-
-// BenchmarkByteByteMap compares byteByteImpl against Map.
-func BenchmarkByteByteMap(b *testing.B) {
-	str := Repeat("a", 100) + Repeat("b", 100)
-	fn := func(r rune) rune {
-		switch r {
-		case 'a':
-			return 'A'
-		case 'b':
-			return 'B'
-		}
-		return r
-	}
-	for i := 0; i < b.N; i++ {
-		Map(fn, str)
-	}
-}
diff --git a/src/pkg/strings/strings.go b/src/pkg/strings/strings.go
deleted file mode 100644
index 5d46211..0000000
--- a/src/pkg/strings/strings.go
+++ /dev/null
@@ -1,725 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package strings implements simple functions to manipulate strings.
-package strings
-
-import (
-	"unicode"
-	"unicode/utf8"
-)
-
-// explode splits s into an array of UTF-8 sequences, one per Unicode character (still strings) up to a maximum of n (n < 0 means no limit).
-// Invalid UTF-8 sequences become correct encodings of U+FFF8.
-func explode(s string, n int) []string {
-	if n == 0 {
-		return nil
-	}
-	l := utf8.RuneCountInString(s)
-	if n <= 0 || n > l {
-		n = l
-	}
-	a := make([]string, n)
-	var size int
-	var ch rune
-	i, cur := 0, 0
-	for ; i+1 < n; i++ {
-		ch, size = utf8.DecodeRuneInString(s[cur:])
-		if ch == utf8.RuneError {
-			a[i] = string(utf8.RuneError)
-		} else {
-			a[i] = s[cur : cur+size]
-		}
-		cur += size
-	}
-	// add the rest, if there is any
-	if cur < len(s) {
-		a[i] = s[cur:]
-	}
-	return a
-}
-
-// primeRK is the prime base used in Rabin-Karp algorithm.
-const primeRK = 16777619
-
-// hashstr returns the hash and the appropriate multiplicative
-// factor for use in Rabin-Karp algorithm.
-func hashstr(sep string) (uint32, uint32) {
-	hash := uint32(0)
-	for i := 0; i < len(sep); i++ {
-		hash = hash*primeRK + uint32(sep[i])
-
-	}
-	var pow, sq uint32 = 1, primeRK
-	for i := len(sep); i > 0; i >>= 1 {
-		if i&1 != 0 {
-			pow *= sq
-		}
-		sq *= sq
-	}
-	return hash, pow
-}
-
-// Count counts the number of non-overlapping instances of sep in s.
-func Count(s, sep string) int {
-	n := 0
-	// special cases
-	switch {
-	case len(sep) == 0:
-		return utf8.RuneCountInString(s) + 1
-	case len(sep) == 1:
-		// special case worth making fast
-		c := sep[0]
-		for i := 0; i < len(s); i++ {
-			if s[i] == c {
-				n++
-			}
-		}
-		return n
-	case len(sep) > len(s):
-		return 0
-	case len(sep) == len(s):
-		if sep == s {
-			return 1
-		}
-		return 0
-	}
-	hashsep, pow := hashstr(sep)
-	h := uint32(0)
-	for i := 0; i < len(sep); i++ {
-		h = h*primeRK + uint32(s[i])
-	}
-	lastmatch := 0
-	if h == hashsep && s[:len(sep)] == sep {
-		n++
-		lastmatch = len(sep)
-	}
-	for i := len(sep); i < len(s); {
-		h *= primeRK
-		h += uint32(s[i])
-		h -= pow * uint32(s[i-len(sep)])
-		i++
-		if h == hashsep && lastmatch <= i-len(sep) && s[i-len(sep):i] == sep {
-			n++
-			lastmatch = i
-		}
-	}
-	return n
-}
-
-// Contains returns true if substr is within s.
-func Contains(s, substr string) bool {
-	return Index(s, substr) >= 0
-}
-
-// ContainsAny returns true if any Unicode code points in chars are within s.
-func ContainsAny(s, chars string) bool {
-	return IndexAny(s, chars) >= 0
-}
-
-// ContainsRune returns true if the Unicode code point r is within s.
-func ContainsRune(s string, r rune) bool {
-	return IndexRune(s, r) >= 0
-}
-
-// Index returns the index of the first instance of sep in s, or -1 if sep is not present in s.
-func Index(s, sep string) int {
-	n := len(sep)
-	switch {
-	case n == 0:
-		return 0
-	case n == 1:
-		return IndexByte(s, sep[0])
-	case n == len(s):
-		if sep == s {
-			return 0
-		}
-		return -1
-	case n > len(s):
-		return -1
-	}
-	// Hash sep.
-	hashsep, pow := hashstr(sep)
-	var h uint32
-	for i := 0; i < n; i++ {
-		h = h*primeRK + uint32(s[i])
-	}
-	if h == hashsep && s[:n] == sep {
-		return 0
-	}
-	for i := n; i < len(s); {
-		h *= primeRK
-		h += uint32(s[i])
-		h -= pow * uint32(s[i-n])
-		i++
-		if h == hashsep && s[i-n:i] == sep {
-			return i - n
-		}
-	}
-	return -1
-}
-
-// LastIndex returns the index of the last instance of sep in s, or -1 if sep is not present in s.
-func LastIndex(s, sep string) int {
-	n := len(sep)
-	if n == 0 {
-		return len(s)
-	}
-	c := sep[0]
-	if n == 1 {
-		// special case worth making fast
-		for i := len(s) - 1; i >= 0; i-- {
-			if s[i] == c {
-				return i
-			}
-		}
-		return -1
-	}
-	// n > 1
-	for i := len(s) - n; i >= 0; i-- {
-		if s[i] == c && s[i:i+n] == sep {
-			return i
-		}
-	}
-	return -1
-}
-
-// IndexRune returns the index of the first instance of the Unicode code point
-// r, or -1 if rune is not present in s.
-func IndexRune(s string, r rune) int {
-	switch {
-	case r < 0x80:
-		b := byte(r)
-		for i := 0; i < len(s); i++ {
-			if s[i] == b {
-				return i
-			}
-		}
-	default:
-		for i, c := range s {
-			if c == r {
-				return i
-			}
-		}
-	}
-	return -1
-}
-
-// IndexAny returns the index of the first instance of any Unicode code point
-// from chars in s, or -1 if no Unicode code point from chars is present in s.
-func IndexAny(s, chars string) int {
-	if len(chars) > 0 {
-		for i, c := range s {
-			for _, m := range chars {
-				if c == m {
-					return i
-				}
-			}
-		}
-	}
-	return -1
-}
-
-// LastIndexAny returns the index of the last instance of any Unicode code
-// point from chars in s, or -1 if no Unicode code point from chars is
-// present in s.
-func LastIndexAny(s, chars string) int {
-	if len(chars) > 0 {
-		for i := len(s); i > 0; {
-			rune, size := utf8.DecodeLastRuneInString(s[0:i])
-			i -= size
-			for _, m := range chars {
-				if rune == m {
-					return i
-				}
-			}
-		}
-	}
-	return -1
-}
-
-// Generic split: splits after each instance of sep,
-// including sepSave bytes of sep in the subarrays.
-func genSplit(s, sep string, sepSave, n int) []string {
-	if n == 0 {
-		return nil
-	}
-	if sep == "" {
-		return explode(s, n)
-	}
-	if n < 0 {
-		n = Count(s, sep) + 1
-	}
-	c := sep[0]
-	start := 0
-	a := make([]string, n)
-	na := 0
-	for i := 0; i+len(sep) <= len(s) && na+1 < n; i++ {
-		if s[i] == c && (len(sep) == 1 || s[i:i+len(sep)] == sep) {
-			a[na] = s[start : i+sepSave]
-			na++
-			start = i + len(sep)
-			i += len(sep) - 1
-		}
-	}
-	a[na] = s[start:]
-	return a[0 : na+1]
-}
-
-// SplitN slices s into substrings separated by sep and returns a slice of
-// the substrings between those separators.
-// If sep is empty, SplitN splits after each UTF-8 sequence.
-// The count determines the number of substrings to return:
-//   n > 0: at most n substrings; the last substring will be the unsplit remainder.
-//   n == 0: the result is nil (zero substrings)
-//   n < 0: all substrings
-func SplitN(s, sep string, n int) []string { return genSplit(s, sep, 0, n) }
-
-// SplitAfterN slices s into substrings after each instance of sep and
-// returns a slice of those substrings.
-// If sep is empty, SplitAfterN splits after each UTF-8 sequence.
-// The count determines the number of substrings to return:
-//   n > 0: at most n substrings; the last substring will be the unsplit remainder.
-//   n == 0: the result is nil (zero substrings)
-//   n < 0: all substrings
-func SplitAfterN(s, sep string, n int) []string {
-	return genSplit(s, sep, len(sep), n)
-}
-
-// Split slices s into all substrings separated by sep and returns a slice of
-// the substrings between those separators.
-// If sep is empty, Split splits after each UTF-8 sequence.
-// It is equivalent to SplitN with a count of -1.
-func Split(s, sep string) []string { return genSplit(s, sep, 0, -1) }
-
-// SplitAfter slices s into all substrings after each instance of sep and
-// returns a slice of those substrings.
-// If sep is empty, SplitAfter splits after each UTF-8 sequence.
-// It is equivalent to SplitAfterN with a count of -1.
-func SplitAfter(s, sep string) []string {
-	return genSplit(s, sep, len(sep), -1)
-}
-
-// Fields splits the string s around each instance of one or more consecutive white space
-// characters, as defined by unicode.IsSpace, returning an array of substrings of s or an
-// empty list if s contains only white space.
-func Fields(s string) []string {
-	return FieldsFunc(s, unicode.IsSpace)
-}
-
-// FieldsFunc splits the string s at each run of Unicode code points c satisfying f(c)
-// and returns an array of slices of s. If all code points in s satisfy f(c) or the
-// string is empty, an empty slice is returned.
-func FieldsFunc(s string, f func(rune) bool) []string {
-	// First count the fields.
-	n := 0
-	inField := false
-	for _, rune := range s {
-		wasInField := inField
-		inField = !f(rune)
-		if inField && !wasInField {
-			n++
-		}
-	}
-
-	// Now create them.
-	a := make([]string, n)
-	na := 0
-	fieldStart := -1 // Set to -1 when looking for start of field.
-	for i, rune := range s {
-		if f(rune) {
-			if fieldStart >= 0 {
-				a[na] = s[fieldStart:i]
-				na++
-				fieldStart = -1
-			}
-		} else if fieldStart == -1 {
-			fieldStart = i
-		}
-	}
-	if fieldStart >= 0 { // Last field might end at EOF.
-		a[na] = s[fieldStart:]
-	}
-	return a
-}
-
-// Join concatenates the elements of a to create a single string.   The separator string
-// sep is placed between elements in the resulting string.
-func Join(a []string, sep string) string {
-	if len(a) == 0 {
-		return ""
-	}
-	if len(a) == 1 {
-		return a[0]
-	}
-	n := len(sep) * (len(a) - 1)
-	for i := 0; i < len(a); i++ {
-		n += len(a[i])
-	}
-
-	b := make([]byte, n)
-	bp := copy(b, a[0])
-	for _, s := range a[1:] {
-		bp += copy(b[bp:], sep)
-		bp += copy(b[bp:], s)
-	}
-	return string(b)
-}
-
-// HasPrefix tests whether the string s begins with prefix.
-func HasPrefix(s, prefix string) bool {
-	return len(s) >= len(prefix) && s[0:len(prefix)] == prefix
-}
-
-// HasSuffix tests whether the string s ends with suffix.
-func HasSuffix(s, suffix string) bool {
-	return len(s) >= len(suffix) && s[len(s)-len(suffix):] == suffix
-}
-
-// Map returns a copy of the string s with all its characters modified
-// according to the mapping function. If mapping returns a negative value, the character is
-// dropped from the string with no replacement.
-func Map(mapping func(rune) rune, s string) string {
-	// In the worst case, the string can grow when mapped, making
-	// things unpleasant.  But it's so rare we barge in assuming it's
-	// fine.  It could also shrink but that falls out naturally.
-	maxbytes := len(s) // length of b
-	nbytes := 0        // number of bytes encoded in b
-	// The output buffer b is initialized on demand, the first
-	// time a character differs.
-	var b []byte
-
-	for i, c := range s {
-		r := mapping(c)
-		if b == nil {
-			if r == c {
-				continue
-			}
-			b = make([]byte, maxbytes)
-			nbytes = copy(b, s[:i])
-		}
-		if r >= 0 {
-			wid := 1
-			if r >= utf8.RuneSelf {
-				wid = utf8.RuneLen(r)
-			}
-			if nbytes+wid > maxbytes {
-				// Grow the buffer.
-				maxbytes = maxbytes*2 + utf8.UTFMax
-				nb := make([]byte, maxbytes)
-				copy(nb, b[0:nbytes])
-				b = nb
-			}
-			nbytes += utf8.EncodeRune(b[nbytes:maxbytes], r)
-		}
-	}
-	if b == nil {
-		return s
-	}
-	return string(b[0:nbytes])
-}
-
-// Repeat returns a new string consisting of count copies of the string s.
-func Repeat(s string, count int) string {
-	b := make([]byte, len(s)*count)
-	bp := 0
-	for i := 0; i < count; i++ {
-		bp += copy(b[bp:], s)
-	}
-	return string(b)
-}
-
-// ToUpper returns a copy of the string s with all Unicode letters mapped to their upper case.
-func ToUpper(s string) string { return Map(unicode.ToUpper, s) }
-
-// ToLower returns a copy of the string s with all Unicode letters mapped to their lower case.
-func ToLower(s string) string { return Map(unicode.ToLower, s) }
-
-// ToTitle returns a copy of the string s with all Unicode letters mapped to their title case.
-func ToTitle(s string) string { return Map(unicode.ToTitle, s) }
-
-// ToUpperSpecial returns a copy of the string s with all Unicode letters mapped to their
-// upper case, giving priority to the special casing rules.
-func ToUpperSpecial(_case unicode.SpecialCase, s string) string {
-	return Map(func(r rune) rune { return _case.ToUpper(r) }, s)
-}
-
-// ToLowerSpecial returns a copy of the string s with all Unicode letters mapped to their
-// lower case, giving priority to the special casing rules.
-func ToLowerSpecial(_case unicode.SpecialCase, s string) string {
-	return Map(func(r rune) rune { return _case.ToLower(r) }, s)
-}
-
-// ToTitleSpecial returns a copy of the string s with all Unicode letters mapped to their
-// title case, giving priority to the special casing rules.
-func ToTitleSpecial(_case unicode.SpecialCase, s string) string {
-	return Map(func(r rune) rune { return _case.ToTitle(r) }, s)
-}
-
-// isSeparator reports whether the rune could mark a word boundary.
-// TODO: update when package unicode captures more of the properties.
-func isSeparator(r rune) bool {
-	// ASCII alphanumerics and underscore are not separators
-	if r <= 0x7F {
-		switch {
-		case '0' <= r && r <= '9':
-			return false
-		case 'a' <= r && r <= 'z':
-			return false
-		case 'A' <= r && r <= 'Z':
-			return false
-		case r == '_':
-			return false
-		}
-		return true
-	}
-	// Letters and digits are not separators
-	if unicode.IsLetter(r) || unicode.IsDigit(r) {
-		return false
-	}
-	// Otherwise, all we can do for now is treat spaces as separators.
-	return unicode.IsSpace(r)
-}
-
-// Title returns a copy of the string s with all Unicode letters that begin words
-// mapped to their title case.
-//
-// BUG: The rule Title uses for word boundaries does not handle Unicode punctuation properly.
-func Title(s string) string {
-	// Use a closure here to remember state.
-	// Hackish but effective. Depends on Map scanning in order and calling
-	// the closure once per rune.
-	prev := ' '
-	return Map(
-		func(r rune) rune {
-			if isSeparator(prev) {
-				prev = r
-				return unicode.ToTitle(r)
-			}
-			prev = r
-			return r
-		},
-		s)
-}
-
-// TrimLeftFunc returns a slice of the string s with all leading
-// Unicode code points c satisfying f(c) removed.
-func TrimLeftFunc(s string, f func(rune) bool) string {
-	i := indexFunc(s, f, false)
-	if i == -1 {
-		return ""
-	}
-	return s[i:]
-}
-
-// TrimRightFunc returns a slice of the string s with all trailing
-// Unicode code points c satisfying f(c) removed.
-func TrimRightFunc(s string, f func(rune) bool) string {
-	i := lastIndexFunc(s, f, false)
-	if i >= 0 && s[i] >= utf8.RuneSelf {
-		_, wid := utf8.DecodeRuneInString(s[i:])
-		i += wid
-	} else {
-		i++
-	}
-	return s[0:i]
-}
-
-// TrimFunc returns a slice of the string s with all leading
-// and trailing Unicode code points c satisfying f(c) removed.
-func TrimFunc(s string, f func(rune) bool) string {
-	return TrimRightFunc(TrimLeftFunc(s, f), f)
-}
-
-// IndexFunc returns the index into s of the first Unicode
-// code point satisfying f(c), or -1 if none do.
-func IndexFunc(s string, f func(rune) bool) int {
-	return indexFunc(s, f, true)
-}
-
-// LastIndexFunc returns the index into s of the last
-// Unicode code point satisfying f(c), or -1 if none do.
-func LastIndexFunc(s string, f func(rune) bool) int {
-	return lastIndexFunc(s, f, true)
-}
-
-// indexFunc is the same as IndexFunc except that if
-// truth==false, the sense of the predicate function is
-// inverted.
-func indexFunc(s string, f func(rune) bool, truth bool) int {
-	start := 0
-	for start < len(s) {
-		wid := 1
-		r := rune(s[start])
-		if r >= utf8.RuneSelf {
-			r, wid = utf8.DecodeRuneInString(s[start:])
-		}
-		if f(r) == truth {
-			return start
-		}
-		start += wid
-	}
-	return -1
-}
-
-// lastIndexFunc is the same as LastIndexFunc except that if
-// truth==false, the sense of the predicate function is
-// inverted.
-func lastIndexFunc(s string, f func(rune) bool, truth bool) int {
-	for i := len(s); i > 0; {
-		r, size := utf8.DecodeLastRuneInString(s[0:i])
-		i -= size
-		if f(r) == truth {
-			return i
-		}
-	}
-	return -1
-}
-
-func makeCutsetFunc(cutset string) func(rune) bool {
-	return func(r rune) bool { return IndexRune(cutset, r) >= 0 }
-}
-
-// Trim returns a slice of the string s with all leading and
-// trailing Unicode code points contained in cutset removed.
-func Trim(s string, cutset string) string {
-	if s == "" || cutset == "" {
-		return s
-	}
-	return TrimFunc(s, makeCutsetFunc(cutset))
-}
-
-// TrimLeft returns a slice of the string s with all leading
-// Unicode code points contained in cutset removed.
-func TrimLeft(s string, cutset string) string {
-	if s == "" || cutset == "" {
-		return s
-	}
-	return TrimLeftFunc(s, makeCutsetFunc(cutset))
-}
-
-// TrimRight returns a slice of the string s, with all trailing
-// Unicode code points contained in cutset removed.
-func TrimRight(s string, cutset string) string {
-	if s == "" || cutset == "" {
-		return s
-	}
-	return TrimRightFunc(s, makeCutsetFunc(cutset))
-}
-
-// TrimSpace returns a slice of the string s, with all leading
-// and trailing white space removed, as defined by Unicode.
-func TrimSpace(s string) string {
-	return TrimFunc(s, unicode.IsSpace)
-}
-
-// TrimPrefix returns s without the provided leading prefix string.
-// If s doesn't start with prefix, s is returned unchanged.
-func TrimPrefix(s, prefix string) string {
-	if HasPrefix(s, prefix) {
-		return s[len(prefix):]
-	}
-	return s
-}
-
-// TrimSuffix returns s without the provided trailing suffix string.
-// If s doesn't end with suffix, s is returned unchanged.
-func TrimSuffix(s, suffix string) string {
-	if HasSuffix(s, suffix) {
-		return s[:len(s)-len(suffix)]
-	}
-	return s
-}
-
-// Replace returns a copy of the string s with the first n
-// non-overlapping instances of old replaced by new.
-// If n < 0, there is no limit on the number of replacements.
-func Replace(s, old, new string, n int) string {
-	if old == new || n == 0 {
-		return s // avoid allocation
-	}
-
-	// Compute number of replacements.
-	if m := Count(s, old); m == 0 {
-		return s // avoid allocation
-	} else if n < 0 || m < n {
-		n = m
-	}
-
-	// Apply replacements to buffer.
-	t := make([]byte, len(s)+n*(len(new)-len(old)))
-	w := 0
-	start := 0
-	for i := 0; i < n; i++ {
-		j := start
-		if len(old) == 0 {
-			if i > 0 {
-				_, wid := utf8.DecodeRuneInString(s[start:])
-				j += wid
-			}
-		} else {
-			j += Index(s[start:], old)
-		}
-		w += copy(t[w:], s[start:j])
-		w += copy(t[w:], new)
-		start = j + len(old)
-	}
-	w += copy(t[w:], s[start:])
-	return string(t[0:w])
-}
-
-// EqualFold reports whether s and t, interpreted as UTF-8 strings,
-// are equal under Unicode case-folding.
-func EqualFold(s, t string) bool {
-	for s != "" && t != "" {
-		// Extract first rune from each string.
-		var sr, tr rune
-		if s[0] < utf8.RuneSelf {
-			sr, s = rune(s[0]), s[1:]
-		} else {
-			r, size := utf8.DecodeRuneInString(s)
-			sr, s = r, s[size:]
-		}
-		if t[0] < utf8.RuneSelf {
-			tr, t = rune(t[0]), t[1:]
-		} else {
-			r, size := utf8.DecodeRuneInString(t)
-			tr, t = r, t[size:]
-		}
-
-		// If they match, keep going; if not, return false.
-
-		// Easy case.
-		if tr == sr {
-			continue
-		}
-
-		// Make sr < tr to simplify what follows.
-		if tr < sr {
-			tr, sr = sr, tr
-		}
-		// Fast check for ASCII.
-		if tr < utf8.RuneSelf && 'A' <= sr && sr <= 'Z' {
-			// ASCII, and sr is upper case.  tr must be lower case.
-			if tr == sr+'a'-'A' {
-				continue
-			}
-			return false
-		}
-
-		// General case.  SimpleFold(x) returns the next equivalent rune > x
-		// or wraps around to smaller values.
-		r := unicode.SimpleFold(sr)
-		for r != sr && r < tr {
-			r = unicode.SimpleFold(r)
-		}
-		if r == tr {
-			continue
-		}
-		return false
-	}
-
-	// One string is empty.  Are both?
-	return s == t
-}
diff --git a/src/pkg/strings/strings_test.go b/src/pkg/strings/strings_test.go
deleted file mode 100644
index e40a180..0000000
--- a/src/pkg/strings/strings_test.go
+++ /dev/null
@@ -1,1176 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package strings_test
-
-import (
-	"bytes"
-	"io"
-	"math/rand"
-	"reflect"
-	. "strings"
-	"testing"
-	"unicode"
-	"unicode/utf8"
-	"unsafe"
-)
-
-func eq(a, b []string) bool {
-	if len(a) != len(b) {
-		return false
-	}
-	for i := 0; i < len(a); i++ {
-		if a[i] != b[i] {
-			return false
-		}
-	}
-	return true
-}
-
-var abcd = "abcd"
-var faces = "☺☻☹"
-var commas = "1,2,3,4"
-var dots = "1....2....3....4"
-
-type IndexTest struct {
-	s   string
-	sep string
-	out int
-}
-
-var indexTests = []IndexTest{
-	{"", "", 0},
-	{"", "a", -1},
-	{"", "foo", -1},
-	{"fo", "foo", -1},
-	{"foo", "foo", 0},
-	{"oofofoofooo", "f", 2},
-	{"oofofoofooo", "foo", 4},
-	{"barfoobarfoo", "foo", 3},
-	{"foo", "", 0},
-	{"foo", "o", 1},
-	{"abcABCabc", "A", 3},
-	// cases with one byte strings - test special case in Index()
-	{"", "a", -1},
-	{"x", "a", -1},
-	{"x", "x", 0},
-	{"abc", "a", 0},
-	{"abc", "b", 1},
-	{"abc", "c", 2},
-	{"abc", "x", -1},
-}
-
-var lastIndexTests = []IndexTest{
-	{"", "", 0},
-	{"", "a", -1},
-	{"", "foo", -1},
-	{"fo", "foo", -1},
-	{"foo", "foo", 0},
-	{"foo", "f", 0},
-	{"oofofoofooo", "f", 7},
-	{"oofofoofooo", "foo", 7},
-	{"barfoobarfoo", "foo", 9},
-	{"foo", "", 3},
-	{"foo", "o", 2},
-	{"abcABCabc", "A", 3},
-	{"abcABCabc", "a", 6},
-}
-
-var indexAnyTests = []IndexTest{
-	{"", "", -1},
-	{"", "a", -1},
-	{"", "abc", -1},
-	{"a", "", -1},
-	{"a", "a", 0},
-	{"aaa", "a", 0},
-	{"abc", "xyz", -1},
-	{"abc", "xcz", 2},
-	{"a☺b☻c☹d", "uvw☻xyz", 2 + len("☺")},
-	{"aRegExp*", ".(|)*+?^$[]", 7},
-	{dots + dots + dots, " ", -1},
-}
-var lastIndexAnyTests = []IndexTest{
-	{"", "", -1},
-	{"", "a", -1},
-	{"", "abc", -1},
-	{"a", "", -1},
-	{"a", "a", 0},
-	{"aaa", "a", 2},
-	{"abc", "xyz", -1},
-	{"abc", "ab", 1},
-	{"a☺b☻c☹d", "uvw☻xyz", 2 + len("☺")},
-	{"a.RegExp*", ".(|)*+?^$[]", 8},
-	{dots + dots + dots, " ", -1},
-}
-
-// Execute f on each test case.  funcName should be the name of f; it's used
-// in failure reports.
-func runIndexTests(t *testing.T, f func(s, sep string) int, funcName string, testCases []IndexTest) {
-	for _, test := range testCases {
-		actual := f(test.s, test.sep)
-		if actual != test.out {
-			t.Errorf("%s(%q,%q) = %v; want %v", funcName, test.s, test.sep, actual, test.out)
-		}
-	}
-}
-
-func TestIndex(t *testing.T)        { runIndexTests(t, Index, "Index", indexTests) }
-func TestLastIndex(t *testing.T)    { runIndexTests(t, LastIndex, "LastIndex", lastIndexTests) }
-func TestIndexAny(t *testing.T)     { runIndexTests(t, IndexAny, "IndexAny", indexAnyTests) }
-func TestLastIndexAny(t *testing.T) { runIndexTests(t, LastIndexAny, "LastIndexAny", lastIndexAnyTests) }
-
-var indexRuneTests = []struct {
-	s    string
-	rune rune
-	out  int
-}{
-	{"a A x", 'A', 2},
-	{"some_text=some_value", '=', 9},
-	{"☺a", 'a', 3},
-	{"a☻☺b", '☺', 4},
-}
-
-func TestIndexRune(t *testing.T) {
-	for _, test := range indexRuneTests {
-		if actual := IndexRune(test.s, test.rune); actual != test.out {
-			t.Errorf("IndexRune(%q,%d)= %v; want %v", test.s, test.rune, actual, test.out)
-		}
-	}
-}
-
-const benchmarkString = "some_text=some☺value"
-
-func BenchmarkIndexRune(b *testing.B) {
-	if got := IndexRune(benchmarkString, '☺'); got != 14 {
-		b.Fatalf("wrong index: expected 14, got=%d", got)
-	}
-	for i := 0; i < b.N; i++ {
-		IndexRune(benchmarkString, '☺')
-	}
-}
-
-func BenchmarkIndexRuneFastPath(b *testing.B) {
-	if got := IndexRune(benchmarkString, 'v'); got != 17 {
-		b.Fatalf("wrong index: expected 17, got=%d", got)
-	}
-	for i := 0; i < b.N; i++ {
-		IndexRune(benchmarkString, 'v')
-	}
-}
-
-func BenchmarkIndex(b *testing.B) {
-	if got := Index(benchmarkString, "v"); got != 17 {
-		b.Fatalf("wrong index: expected 17, got=%d", got)
-	}
-	for i := 0; i < b.N; i++ {
-		Index(benchmarkString, "v")
-	}
-}
-
-func BenchmarkIndexByte(b *testing.B) {
-	if got := IndexByte(benchmarkString, 'v'); got != 17 {
-		b.Fatalf("wrong index: expected 17, got=%d", got)
-	}
-	for i := 0; i < b.N; i++ {
-		IndexByte(benchmarkString, 'v')
-	}
-}
-
-var explodetests = []struct {
-	s string
-	n int
-	a []string
-}{
-	{"", -1, []string{}},
-	{abcd, 4, []string{"a", "b", "c", "d"}},
-	{faces, 3, []string{"☺", "☻", "☹"}},
-	{abcd, 2, []string{"a", "bcd"}},
-}
-
-func TestExplode(t *testing.T) {
-	for _, tt := range explodetests {
-		a := SplitN(tt.s, "", tt.n)
-		if !eq(a, tt.a) {
-			t.Errorf("explode(%q, %d) = %v; want %v", tt.s, tt.n, a, tt.a)
-			continue
-		}
-		s := Join(a, "")
-		if s != tt.s {
-			t.Errorf(`Join(explode(%q, %d), "") = %q`, tt.s, tt.n, s)
-		}
-	}
-}
-
-type SplitTest struct {
-	s   string
-	sep string
-	n   int
-	a   []string
-}
-
-var splittests = []SplitTest{
-	{abcd, "a", 0, nil},
-	{abcd, "a", -1, []string{"", "bcd"}},
-	{abcd, "z", -1, []string{"abcd"}},
-	{abcd, "", -1, []string{"a", "b", "c", "d"}},
-	{commas, ",", -1, []string{"1", "2", "3", "4"}},
-	{dots, "...", -1, []string{"1", ".2", ".3", ".4"}},
-	{faces, "☹", -1, []string{"☺☻", ""}},
-	{faces, "~", -1, []string{faces}},
-	{faces, "", -1, []string{"☺", "☻", "☹"}},
-	{"1 2 3 4", " ", 3, []string{"1", "2", "3 4"}},
-	{"1 2", " ", 3, []string{"1", "2"}},
-	{"123", "", 2, []string{"1", "23"}},
-	{"123", "", 17, []string{"1", "2", "3"}},
-}
-
-func TestSplit(t *testing.T) {
-	for _, tt := range splittests {
-		a := SplitN(tt.s, tt.sep, tt.n)
-		if !eq(a, tt.a) {
-			t.Errorf("Split(%q, %q, %d) = %v; want %v", tt.s, tt.sep, tt.n, a, tt.a)
-			continue
-		}
-		if tt.n == 0 {
-			continue
-		}
-		s := Join(a, tt.sep)
-		if s != tt.s {
-			t.Errorf("Join(Split(%q, %q, %d), %q) = %q", tt.s, tt.sep, tt.n, tt.sep, s)
-		}
-		if tt.n < 0 {
-			b := Split(tt.s, tt.sep)
-			if !reflect.DeepEqual(a, b) {
-				t.Errorf("Split disagrees with SplitN(%q, %q, %d) = %v; want %v", tt.s, tt.sep, tt.n, b, a)
-			}
-		}
-	}
-}
-
-var splitaftertests = []SplitTest{
-	{abcd, "a", -1, []string{"a", "bcd"}},
-	{abcd, "z", -1, []string{"abcd"}},
-	{abcd, "", -1, []string{"a", "b", "c", "d"}},
-	{commas, ",", -1, []string{"1,", "2,", "3,", "4"}},
-	{dots, "...", -1, []string{"1...", ".2...", ".3...", ".4"}},
-	{faces, "☹", -1, []string{"☺☻☹", ""}},
-	{faces, "~", -1, []string{faces}},
-	{faces, "", -1, []string{"☺", "☻", "☹"}},
-	{"1 2 3 4", " ", 3, []string{"1 ", "2 ", "3 4"}},
-	{"1 2 3", " ", 3, []string{"1 ", "2 ", "3"}},
-	{"1 2", " ", 3, []string{"1 ", "2"}},
-	{"123", "", 2, []string{"1", "23"}},
-	{"123", "", 17, []string{"1", "2", "3"}},
-}
-
-func TestSplitAfter(t *testing.T) {
-	for _, tt := range splitaftertests {
-		a := SplitAfterN(tt.s, tt.sep, tt.n)
-		if !eq(a, tt.a) {
-			t.Errorf(`Split(%q, %q, %d) = %v; want %v`, tt.s, tt.sep, tt.n, a, tt.a)
-			continue
-		}
-		s := Join(a, "")
-		if s != tt.s {
-			t.Errorf(`Join(Split(%q, %q, %d), %q) = %q`, tt.s, tt.sep, tt.n, tt.sep, s)
-		}
-		if tt.n < 0 {
-			b := SplitAfter(tt.s, tt.sep)
-			if !reflect.DeepEqual(a, b) {
-				t.Errorf("SplitAfter disagrees with SplitAfterN(%q, %q, %d) = %v; want %v", tt.s, tt.sep, tt.n, b, a)
-			}
-		}
-	}
-}
-
-type FieldsTest struct {
-	s string
-	a []string
-}
-
-var fieldstests = []FieldsTest{
-	{"", []string{}},
-	{" ", []string{}},
-	{" \t ", []string{}},
-	{"  abc  ", []string{"abc"}},
-	{"1 2 3 4", []string{"1", "2", "3", "4"}},
-	{"1  2  3  4", []string{"1", "2", "3", "4"}},
-	{"1\t\t2\t\t3\t4", []string{"1", "2", "3", "4"}},
-	{"1\u20002\u20013\u20024", []string{"1", "2", "3", "4"}},
-	{"\u2000\u2001\u2002", []string{}},
-	{"\n™\t™\n", []string{"™", "™"}},
-	{faces, []string{faces}},
-}
-
-func TestFields(t *testing.T) {
-	for _, tt := range fieldstests {
-		a := Fields(tt.s)
-		if !eq(a, tt.a) {
-			t.Errorf("Fields(%q) = %v; want %v", tt.s, a, tt.a)
-			continue
-		}
-	}
-}
-
-var FieldsFuncTests = []FieldsTest{
-	{"", []string{}},
-	{"XX", []string{}},
-	{"XXhiXXX", []string{"hi"}},
-	{"aXXbXXXcX", []string{"a", "b", "c"}},
-}
-
-func TestFieldsFunc(t *testing.T) {
-	for _, tt := range fieldstests {
-		a := FieldsFunc(tt.s, unicode.IsSpace)
-		if !eq(a, tt.a) {
-			t.Errorf("FieldsFunc(%q, unicode.IsSpace) = %v; want %v", tt.s, a, tt.a)
-			continue
-		}
-	}
-	pred := func(c rune) bool { return c == 'X' }
-	for _, tt := range FieldsFuncTests {
-		a := FieldsFunc(tt.s, pred)
-		if !eq(a, tt.a) {
-			t.Errorf("FieldsFunc(%q) = %v, want %v", tt.s, a, tt.a)
-		}
-	}
-}
-
-// Test case for any function which accepts and returns a single string.
-type StringTest struct {
-	in, out string
-}
-
-// Execute f on each test case.  funcName should be the name of f; it's used
-// in failure reports.
-func runStringTests(t *testing.T, f func(string) string, funcName string, testCases []StringTest) {
-	for _, tc := range testCases {
-		actual := f(tc.in)
-		if actual != tc.out {
-			t.Errorf("%s(%q) = %q; want %q", funcName, tc.in, actual, tc.out)
-		}
-	}
-}
-
-var upperTests = []StringTest{
-	{"", ""},
-	{"abc", "ABC"},
-	{"AbC123", "ABC123"},
-	{"azAZ09_", "AZAZ09_"},
-	{"\u0250\u0250\u0250\u0250\u0250", "\u2C6F\u2C6F\u2C6F\u2C6F\u2C6F"}, // grows one byte per char
-}
-
-var lowerTests = []StringTest{
-	{"", ""},
-	{"abc", "abc"},
-	{"AbC123", "abc123"},
-	{"azAZ09_", "azaz09_"},
-	{"\u2C6D\u2C6D\u2C6D\u2C6D\u2C6D", "\u0251\u0251\u0251\u0251\u0251"}, // shrinks one byte per char
-}
-
-const space = "\t\v\r\f\n\u0085\u00a0\u2000\u3000"
-
-var trimSpaceTests = []StringTest{
-	{"", ""},
-	{"abc", "abc"},
-	{space + "abc" + space, "abc"},
-	{" ", ""},
-	{" \t\r\n \t\t\r\r\n\n ", ""},
-	{" \t\r\n x\t\t\r\r\n\n ", "x"},
-	{" \u2000\t\r\n x\t\t\r\r\ny\n \u3000", "x\t\t\r\r\ny"},
-	{"1 \t\r\n2", "1 \t\r\n2"},
-	{" x\x80", "x\x80"},
-	{" x\xc0", "x\xc0"},
-	{"x \xc0\xc0 ", "x \xc0\xc0"},
-	{"x \xc0", "x \xc0"},
-	{"x \xc0 ", "x \xc0"},
-	{"x \xc0\xc0 ", "x \xc0\xc0"},
-	{"x ☺\xc0\xc0 ", "x ☺\xc0\xc0"},
-	{"x ☺ ", "x ☺"},
-}
-
-func tenRunes(ch rune) string {
-	r := make([]rune, 10)
-	for i := range r {
-		r[i] = ch
-	}
-	return string(r)
-}
-
-// User-defined self-inverse mapping function
-func rot13(r rune) rune {
-	step := rune(13)
-	if r >= 'a' && r <= 'z' {
-		return ((r - 'a' + step) % 26) + 'a'
-	}
-	if r >= 'A' && r <= 'Z' {
-		return ((r - 'A' + step) % 26) + 'A'
-	}
-	return r
-}
-
-func TestMap(t *testing.T) {
-	// Run a couple of awful growth/shrinkage tests
-	a := tenRunes('a')
-	// 1.  Grow.  This triggers two reallocations in Map.
-	maxRune := func(rune) rune { return unicode.MaxRune }
-	m := Map(maxRune, a)
-	expect := tenRunes(unicode.MaxRune)
-	if m != expect {
-		t.Errorf("growing: expected %q got %q", expect, m)
-	}
-
-	// 2. Shrink
-	minRune := func(rune) rune { return 'a' }
-	m = Map(minRune, tenRunes(unicode.MaxRune))
-	expect = a
-	if m != expect {
-		t.Errorf("shrinking: expected %q got %q", expect, m)
-	}
-
-	// 3. Rot13
-	m = Map(rot13, "a to zed")
-	expect = "n gb mrq"
-	if m != expect {
-		t.Errorf("rot13: expected %q got %q", expect, m)
-	}
-
-	// 4. Rot13^2
-	m = Map(rot13, Map(rot13, "a to zed"))
-	expect = "a to zed"
-	if m != expect {
-		t.Errorf("rot13: expected %q got %q", expect, m)
-	}
-
-	// 5. Drop
-	dropNotLatin := func(r rune) rune {
-		if unicode.Is(unicode.Latin, r) {
-			return r
-		}
-		return -1
-	}
-	m = Map(dropNotLatin, "Hello, 세계")
-	expect = "Hello"
-	if m != expect {
-		t.Errorf("drop: expected %q got %q", expect, m)
-	}
-
-	// 6. Identity
-	identity := func(r rune) rune {
-		return r
-	}
-	orig := "Input string that we expect not to be copied."
-	m = Map(identity, orig)
-	if (*reflect.StringHeader)(unsafe.Pointer(&orig)).Data !=
-		(*reflect.StringHeader)(unsafe.Pointer(&m)).Data {
-		t.Error("unexpected copy during identity map")
-	}
-}
-
-func TestToUpper(t *testing.T) { runStringTests(t, ToUpper, "ToUpper", upperTests) }
-
-func TestToLower(t *testing.T) { runStringTests(t, ToLower, "ToLower", lowerTests) }
-
-func BenchmarkMapNoChanges(b *testing.B) {
-	identity := func(r rune) rune {
-		return r
-	}
-	for i := 0; i < b.N; i++ {
-		Map(identity, "Some string that won't be modified.")
-	}
-}
-
-func TestSpecialCase(t *testing.T) {
-	lower := "abcçdefgğhıijklmnoöprsştuüvyz"
-	upper := "ABCÇDEFGĞHIİJKLMNOÖPRSŞTUÜVYZ"
-	u := ToUpperSpecial(unicode.TurkishCase, upper)
-	if u != upper {
-		t.Errorf("Upper(upper) is %s not %s", u, upper)
-	}
-	u = ToUpperSpecial(unicode.TurkishCase, lower)
-	if u != upper {
-		t.Errorf("Upper(lower) is %s not %s", u, upper)
-	}
-	l := ToLowerSpecial(unicode.TurkishCase, lower)
-	if l != lower {
-		t.Errorf("Lower(lower) is %s not %s", l, lower)
-	}
-	l = ToLowerSpecial(unicode.TurkishCase, upper)
-	if l != lower {
-		t.Errorf("Lower(upper) is %s not %s", l, lower)
-	}
-}
-
-func TestTrimSpace(t *testing.T) { runStringTests(t, TrimSpace, "TrimSpace", trimSpaceTests) }
-
-var trimTests = []struct {
-	f            string
-	in, arg, out string
-}{
-	{"Trim", "abba", "a", "bb"},
-	{"Trim", "abba", "ab", ""},
-	{"TrimLeft", "abba", "ab", ""},
-	{"TrimRight", "abba", "ab", ""},
-	{"TrimLeft", "abba", "a", "bba"},
-	{"TrimRight", "abba", "a", "abb"},
-	{"Trim", "<tag>", "<>", "tag"},
-	{"Trim", "* listitem", " *", "listitem"},
-	{"Trim", `"quote"`, `"`, "quote"},
-	{"Trim", "\u2C6F\u2C6F\u0250\u0250\u2C6F\u2C6F", "\u2C6F", "\u0250\u0250"},
-	//empty string tests
-	{"Trim", "abba", "", "abba"},
-	{"Trim", "", "123", ""},
-	{"Trim", "", "", ""},
-	{"TrimLeft", "abba", "", "abba"},
-	{"TrimLeft", "", "123", ""},
-	{"TrimLeft", "", "", ""},
-	{"TrimRight", "abba", "", "abba"},
-	{"TrimRight", "", "123", ""},
-	{"TrimRight", "", "", ""},
-	{"TrimRight", "☺\xc0", "☺", "☺\xc0"},
-	{"TrimPrefix", "aabb", "a", "abb"},
-	{"TrimPrefix", "aabb", "b", "aabb"},
-	{"TrimSuffix", "aabb", "a", "aabb"},
-	{"TrimSuffix", "aabb", "b", "aab"},
-}
-
-func TestTrim(t *testing.T) {
-	for _, tc := range trimTests {
-		name := tc.f
-		var f func(string, string) string
-		switch name {
-		case "Trim":
-			f = Trim
-		case "TrimLeft":
-			f = TrimLeft
-		case "TrimRight":
-			f = TrimRight
-		case "TrimPrefix":
-			f = TrimPrefix
-		case "TrimSuffix":
-			f = TrimSuffix
-		default:
-			t.Errorf("Undefined trim function %s", name)
-		}
-		actual := f(tc.in, tc.arg)
-		if actual != tc.out {
-			t.Errorf("%s(%q, %q) = %q; want %q", name, tc.in, tc.arg, actual, tc.out)
-		}
-	}
-}
-
-type predicate struct {
-	f    func(rune) bool
-	name string
-}
-
-var isSpace = predicate{unicode.IsSpace, "IsSpace"}
-var isDigit = predicate{unicode.IsDigit, "IsDigit"}
-var isUpper = predicate{unicode.IsUpper, "IsUpper"}
-var isValidRune = predicate{
-	func(r rune) bool {
-		return r != utf8.RuneError
-	},
-	"IsValidRune",
-}
-
-func not(p predicate) predicate {
-	return predicate{
-		func(r rune) bool {
-			return !p.f(r)
-		},
-		"not " + p.name,
-	}
-}
-
-var trimFuncTests = []struct {
-	f       predicate
-	in, out string
-}{
-	{isSpace, space + " hello " + space, "hello"},
-	{isDigit, "\u0e50\u0e5212hello34\u0e50\u0e51", "hello"},
-	{isUpper, "\u2C6F\u2C6F\u2C6F\u2C6FABCDhelloEF\u2C6F\u2C6FGH\u2C6F\u2C6F", "hello"},
-	{not(isSpace), "hello" + space + "hello", space},
-	{not(isDigit), "hello\u0e50\u0e521234\u0e50\u0e51helo", "\u0e50\u0e521234\u0e50\u0e51"},
-	{isValidRune, "ab\xc0a\xc0cd", "\xc0a\xc0"},
-	{not(isValidRune), "\xc0a\xc0", "a"},
-}
-
-func TestTrimFunc(t *testing.T) {
-	for _, tc := range trimFuncTests {
-		actual := TrimFunc(tc.in, tc.f.f)
-		if actual != tc.out {
-			t.Errorf("TrimFunc(%q, %q) = %q; want %q", tc.in, tc.f.name, actual, tc.out)
-		}
-	}
-}
-
-var indexFuncTests = []struct {
-	in          string
-	f           predicate
-	first, last int
-}{
-	{"", isValidRune, -1, -1},
-	{"abc", isDigit, -1, -1},
-	{"0123", isDigit, 0, 3},
-	{"a1b", isDigit, 1, 1},
-	{space, isSpace, 0, len(space) - 3}, // last rune in space is 3 bytes
-	{"\u0e50\u0e5212hello34\u0e50\u0e51", isDigit, 0, 18},
-	{"\u2C6F\u2C6F\u2C6F\u2C6FABCDhelloEF\u2C6F\u2C6FGH\u2C6F\u2C6F", isUpper, 0, 34},
-	{"12\u0e50\u0e52hello34\u0e50\u0e51", not(isDigit), 8, 12},
-
-	// tests of invalid UTF-8
-	{"\x801", isDigit, 1, 1},
-	{"\x80abc", isDigit, -1, -1},
-	{"\xc0a\xc0", isValidRune, 1, 1},
-	{"\xc0a\xc0", not(isValidRune), 0, 2},
-	{"\xc0☺\xc0", not(isValidRune), 0, 4},
-	{"\xc0☺\xc0\xc0", not(isValidRune), 0, 5},
-	{"ab\xc0a\xc0cd", not(isValidRune), 2, 4},
-	{"a\xe0\x80cd", not(isValidRune), 1, 2},
-	{"\x80\x80\x80\x80", not(isValidRune), 0, 3},
-}
-
-func TestIndexFunc(t *testing.T) {
-	for _, tc := range indexFuncTests {
-		first := IndexFunc(tc.in, tc.f.f)
-		if first != tc.first {
-			t.Errorf("IndexFunc(%q, %s) = %d; want %d", tc.in, tc.f.name, first, tc.first)
-		}
-		last := LastIndexFunc(tc.in, tc.f.f)
-		if last != tc.last {
-			t.Errorf("LastIndexFunc(%q, %s) = %d; want %d", tc.in, tc.f.name, last, tc.last)
-		}
-	}
-}
-
-func equal(m string, s1, s2 string, t *testing.T) bool {
-	if s1 == s2 {
-		return true
-	}
-	e1 := Split(s1, "")
-	e2 := Split(s2, "")
-	for i, c1 := range e1 {
-		if i >= len(e2) {
-			break
-		}
-		r1, _ := utf8.DecodeRuneInString(c1)
-		r2, _ := utf8.DecodeRuneInString(e2[i])
-		if r1 != r2 {
-			t.Errorf("%s diff at %d: U+%04X U+%04X", m, i, r1, r2)
-		}
-	}
-	return false
-}
-
-func TestCaseConsistency(t *testing.T) {
-	// Make a string of all the runes.
-	numRunes := int(unicode.MaxRune + 1)
-	if testing.Short() {
-		numRunes = 1000
-	}
-	a := make([]rune, numRunes)
-	for i := range a {
-		a[i] = rune(i)
-	}
-	s := string(a)
-	// convert the cases.
-	upper := ToUpper(s)
-	lower := ToLower(s)
-
-	// Consistency checks
-	if n := utf8.RuneCountInString(upper); n != numRunes {
-		t.Error("rune count wrong in upper:", n)
-	}
-	if n := utf8.RuneCountInString(lower); n != numRunes {
-		t.Error("rune count wrong in lower:", n)
-	}
-	if !equal("ToUpper(upper)", ToUpper(upper), upper, t) {
-		t.Error("ToUpper(upper) consistency fail")
-	}
-	if !equal("ToLower(lower)", ToLower(lower), lower, t) {
-		t.Error("ToLower(lower) consistency fail")
-	}
-	/*
-		  These fail because of non-one-to-oneness of the data, such as multiple
-		  upper case 'I' mapping to 'i'.  We comment them out but keep them for
-		  interest.
-		  For instance: CAPITAL LETTER I WITH DOT ABOVE:
-			unicode.ToUpper(unicode.ToLower('\u0130')) != '\u0130'
-
-		if !equal("ToUpper(lower)", ToUpper(lower), upper, t) {
-			t.Error("ToUpper(lower) consistency fail");
-		}
-		if !equal("ToLower(upper)", ToLower(upper), lower, t) {
-			t.Error("ToLower(upper) consistency fail");
-		}
-	*/
-}
-
-var RepeatTests = []struct {
-	in, out string
-	count   int
-}{
-	{"", "", 0},
-	{"", "", 1},
-	{"", "", 2},
-	{"-", "", 0},
-	{"-", "-", 1},
-	{"-", "----------", 10},
-	{"abc ", "abc abc abc ", 3},
-}
-
-func TestRepeat(t *testing.T) {
-	for _, tt := range RepeatTests {
-		a := Repeat(tt.in, tt.count)
-		if !equal("Repeat(s)", a, tt.out, t) {
-			t.Errorf("Repeat(%v, %d) = %v; want %v", tt.in, tt.count, a, tt.out)
-			continue
-		}
-	}
-}
-
-func runesEqual(a, b []rune) bool {
-	if len(a) != len(b) {
-		return false
-	}
-	for i, r := range a {
-		if r != b[i] {
-			return false
-		}
-	}
-	return true
-}
-
-var RunesTests = []struct {
-	in    string
-	out   []rune
-	lossy bool
-}{
-	{"", []rune{}, false},
-	{" ", []rune{32}, false},
-	{"ABC", []rune{65, 66, 67}, false},
-	{"abc", []rune{97, 98, 99}, false},
-	{"\u65e5\u672c\u8a9e", []rune{26085, 26412, 35486}, false},
-	{"ab\x80c", []rune{97, 98, 0xFFFD, 99}, true},
-	{"ab\xc0c", []rune{97, 98, 0xFFFD, 99}, true},
-}
-
-func TestRunes(t *testing.T) {
-	for _, tt := range RunesTests {
-		a := []rune(tt.in)
-		if !runesEqual(a, tt.out) {
-			t.Errorf("[]rune(%q) = %v; want %v", tt.in, a, tt.out)
-			continue
-		}
-		if !tt.lossy {
-			// can only test reassembly if we didn't lose information
-			s := string(a)
-			if s != tt.in {
-				t.Errorf("string([]rune(%q)) = %x; want %x", tt.in, s, tt.in)
-			}
-		}
-	}
-}
-
-func TestReadByte(t *testing.T) {
-	testStrings := []string{"", abcd, faces, commas}
-	for _, s := range testStrings {
-		reader := NewReader(s)
-		if e := reader.UnreadByte(); e == nil {
-			t.Errorf("Unreading %q at beginning: expected error", s)
-		}
-		var res bytes.Buffer
-		for {
-			b, e := reader.ReadByte()
-			if e == io.EOF {
-				break
-			}
-			if e != nil {
-				t.Errorf("Reading %q: %s", s, e)
-				break
-			}
-			res.WriteByte(b)
-			// unread and read again
-			e = reader.UnreadByte()
-			if e != nil {
-				t.Errorf("Unreading %q: %s", s, e)
-				break
-			}
-			b1, e := reader.ReadByte()
-			if e != nil {
-				t.Errorf("Reading %q after unreading: %s", s, e)
-				break
-			}
-			if b1 != b {
-				t.Errorf("Reading %q after unreading: want byte %q, got %q", s, b, b1)
-				break
-			}
-		}
-		if res.String() != s {
-			t.Errorf("Reader(%q).ReadByte() produced %q", s, res.String())
-		}
-	}
-}
-
-func TestReadRune(t *testing.T) {
-	testStrings := []string{"", abcd, faces, commas}
-	for _, s := range testStrings {
-		reader := NewReader(s)
-		if e := reader.UnreadRune(); e == nil {
-			t.Errorf("Unreading %q at beginning: expected error", s)
-		}
-		res := ""
-		for {
-			r, z, e := reader.ReadRune()
-			if e == io.EOF {
-				break
-			}
-			if e != nil {
-				t.Errorf("Reading %q: %s", s, e)
-				break
-			}
-			res += string(r)
-			// unread and read again
-			e = reader.UnreadRune()
-			if e != nil {
-				t.Errorf("Unreading %q: %s", s, e)
-				break
-			}
-			r1, z1, e := reader.ReadRune()
-			if e != nil {
-				t.Errorf("Reading %q after unreading: %s", s, e)
-				break
-			}
-			if r1 != r {
-				t.Errorf("Reading %q after unreading: want rune %q, got %q", s, r, r1)
-				break
-			}
-			if z1 != z {
-				t.Errorf("Reading %q after unreading: want size %d, got %d", s, z, z1)
-				break
-			}
-		}
-		if res != s {
-			t.Errorf("Reader(%q).ReadRune() produced %q", s, res)
-		}
-	}
-}
-
-var UnreadRuneErrorTests = []struct {
-	name string
-	f    func(*Reader)
-}{
-	{"Read", func(r *Reader) { r.Read([]byte{0}) }},
-	{"ReadByte", func(r *Reader) { r.ReadByte() }},
-	{"UnreadRune", func(r *Reader) { r.UnreadRune() }},
-	{"Seek", func(r *Reader) { r.Seek(0, 1) }},
-	{"WriteTo", func(r *Reader) { r.WriteTo(&bytes.Buffer{}) }},
-}
-
-func TestUnreadRuneError(t *testing.T) {
-	for _, tt := range UnreadRuneErrorTests {
-		reader := NewReader("0123456789")
-		if _, _, err := reader.ReadRune(); err != nil {
-			// should not happen
-			t.Fatal(err)
-		}
-		tt.f(reader)
-		err := reader.UnreadRune()
-		if err == nil {
-			t.Errorf("Unreading after %s: expected error", tt.name)
-		}
-	}
-}
-
-var ReplaceTests = []struct {
-	in       string
-	old, new string
-	n        int
-	out      string
-}{
-	{"hello", "l", "L", 0, "hello"},
-	{"hello", "l", "L", -1, "heLLo"},
-	{"hello", "x", "X", -1, "hello"},
-	{"", "x", "X", -1, ""},
-	{"radar", "r", "<r>", -1, "<r>ada<r>"},
-	{"", "", "<>", -1, "<>"},
-	{"banana", "a", "<>", -1, "b<>n<>n<>"},
-	{"banana", "a", "<>", 1, "b<>nana"},
-	{"banana", "a", "<>", 1000, "b<>n<>n<>"},
-	{"banana", "an", "<>", -1, "b<><>a"},
-	{"banana", "ana", "<>", -1, "b<>na"},
-	{"banana", "", "<>", -1, "<>b<>a<>n<>a<>n<>a<>"},
-	{"banana", "", "<>", 10, "<>b<>a<>n<>a<>n<>a<>"},
-	{"banana", "", "<>", 6, "<>b<>a<>n<>a<>n<>a"},
-	{"banana", "", "<>", 5, "<>b<>a<>n<>a<>na"},
-	{"banana", "", "<>", 1, "<>banana"},
-	{"banana", "a", "a", -1, "banana"},
-	{"banana", "a", "a", 1, "banana"},
-	{"☺☻☹", "", "<>", -1, "<>☺<>☻<>☹<>"},
-}
-
-func TestReplace(t *testing.T) {
-	for _, tt := range ReplaceTests {
-		if s := Replace(tt.in, tt.old, tt.new, tt.n); s != tt.out {
-			t.Errorf("Replace(%q, %q, %q, %d) = %q, want %q", tt.in, tt.old, tt.new, tt.n, s, tt.out)
-		}
-	}
-}
-
-var TitleTests = []struct {
-	in, out string
-}{
-	{"", ""},
-	{"a", "A"},
-	{" aaa aaa aaa ", " Aaa Aaa Aaa "},
-	{" Aaa Aaa Aaa ", " Aaa Aaa Aaa "},
-	{"123a456", "123a456"},
-	{"double-blind", "Double-Blind"},
-	{"ÿøû", "Ÿøû"},
-	{"with_underscore", "With_underscore"},
-	{"unicode \xe2\x80\xa8 line separator", "Unicode \xe2\x80\xa8 Line Separator"},
-}
-
-func TestTitle(t *testing.T) {
-	for _, tt := range TitleTests {
-		if s := Title(tt.in); s != tt.out {
-			t.Errorf("Title(%q) = %q, want %q", tt.in, s, tt.out)
-		}
-	}
-}
-
-var ContainsTests = []struct {
-	str, substr string
-	expected    bool
-}{
-	{"abc", "bc", true},
-	{"abc", "bcd", false},
-	{"abc", "", true},
-	{"", "a", false},
-}
-
-func TestContains(t *testing.T) {
-	for _, ct := range ContainsTests {
-		if Contains(ct.str, ct.substr) != ct.expected {
-			t.Errorf("Contains(%s, %s) = %v, want %v",
-				ct.str, ct.substr, !ct.expected, ct.expected)
-		}
-	}
-}
-
-var ContainsAnyTests = []struct {
-	str, substr string
-	expected    bool
-}{
-	{"", "", false},
-	{"", "a", false},
-	{"", "abc", false},
-	{"a", "", false},
-	{"a", "a", true},
-	{"aaa", "a", true},
-	{"abc", "xyz", false},
-	{"abc", "xcz", true},
-	{"a☺b☻c☹d", "uvw☻xyz", true},
-	{"aRegExp*", ".(|)*+?^$[]", true},
-	{dots + dots + dots, " ", false},
-}
-
-func TestContainsAny(t *testing.T) {
-	for _, ct := range ContainsAnyTests {
-		if ContainsAny(ct.str, ct.substr) != ct.expected {
-			t.Errorf("ContainsAny(%s, %s) = %v, want %v",
-				ct.str, ct.substr, !ct.expected, ct.expected)
-		}
-	}
-}
-
-var ContainsRuneTests = []struct {
-	str      string
-	r        rune
-	expected bool
-}{
-	{"", 'a', false},
-	{"a", 'a', true},
-	{"aaa", 'a', true},
-	{"abc", 'y', false},
-	{"abc", 'c', true},
-	{"a☺b☻c☹d", 'x', false},
-	{"a☺b☻c☹d", '☻', true},
-	{"aRegExp*", '*', true},
-}
-
-func TestContainsRune(t *testing.T) {
-	for _, ct := range ContainsRuneTests {
-		if ContainsRune(ct.str, ct.r) != ct.expected {
-			t.Errorf("ContainsRune(%q, %q) = %v, want %v",
-				ct.str, ct.r, !ct.expected, ct.expected)
-		}
-	}
-}
-
-var EqualFoldTests = []struct {
-	s, t string
-	out  bool
-}{
-	{"abc", "abc", true},
-	{"ABcd", "ABcd", true},
-	{"123abc", "123ABC", true},
-	{"αβδ", "ΑΒΔ", true},
-	{"abc", "xyz", false},
-	{"abc", "XYZ", false},
-	{"abcdefghijk", "abcdefghijX", false},
-	{"abcdefghijk", "abcdefghij\u212A", true},
-	{"abcdefghijK", "abcdefghij\u212A", true},
-	{"abcdefghijkz", "abcdefghij\u212Ay", false},
-	{"abcdefghijKz", "abcdefghij\u212Ay", false},
-}
-
-func TestEqualFold(t *testing.T) {
-	for _, tt := range EqualFoldTests {
-		if out := EqualFold(tt.s, tt.t); out != tt.out {
-			t.Errorf("EqualFold(%#q, %#q) = %v, want %v", tt.s, tt.t, out, tt.out)
-		}
-		if out := EqualFold(tt.t, tt.s); out != tt.out {
-			t.Errorf("EqualFold(%#q, %#q) = %v, want %v", tt.t, tt.s, out, tt.out)
-		}
-	}
-}
-
-var CountTests = []struct {
-	s, sep string
-	num    int
-}{
-	{"", "", 1},
-	{"", "notempty", 0},
-	{"notempty", "", 9},
-	{"smaller", "not smaller", 0},
-	{"12345678987654321", "6", 2},
-	{"611161116", "6", 3},
-	{"notequal", "NotEqual", 0},
-	{"equal", "equal", 1},
-	{"abc1231231123q", "123", 3},
-	{"11111", "11", 2},
-}
-
-func TestCount(t *testing.T) {
-	for _, tt := range CountTests {
-		if num := Count(tt.s, tt.sep); num != tt.num {
-			t.Errorf("Count(\"%s\", \"%s\") = %d, want %d", tt.s, tt.sep, num, tt.num)
-		}
-	}
-}
-
-func makeBenchInputHard() string {
-	tokens := [...]string{
-		"<a>", "<p>", "<b>", "<strong>",
-		"</a>", "</p>", "</b>", "</strong>",
-		"hello", "world",
-	}
-	x := make([]byte, 0, 1<<20)
-	for len(x) < 1<<20 {
-		i := rand.Intn(len(tokens))
-		x = append(x, tokens[i]...)
-	}
-	return string(x)
-}
-
-var benchInputHard = makeBenchInputHard()
-
-func benchmarkIndexHard(b *testing.B, sep string) {
-	for i := 0; i < b.N; i++ {
-		Index(benchInputHard, sep)
-	}
-}
-
-func benchmarkCountHard(b *testing.B, sep string) {
-	for i := 0; i < b.N; i++ {
-		Count(benchInputHard, sep)
-	}
-}
-
-func BenchmarkIndexHard1(b *testing.B) { benchmarkIndexHard(b, "<>") }
-func BenchmarkIndexHard2(b *testing.B) { benchmarkIndexHard(b, "</pre>") }
-func BenchmarkIndexHard3(b *testing.B) { benchmarkIndexHard(b, "<b>hello world</b>") }
-
-func BenchmarkCountHard1(b *testing.B) { benchmarkCountHard(b, "<>") }
-func BenchmarkCountHard2(b *testing.B) { benchmarkCountHard(b, "</pre>") }
-func BenchmarkCountHard3(b *testing.B) { benchmarkCountHard(b, "<b>hello world</b>") }
-
-var benchInputTorture = Repeat("ABC", 1<<10) + "123" + Repeat("ABC", 1<<10)
-var benchNeedleTorture = Repeat("ABC", 1<<10+1)
-
-func BenchmarkIndexTorture(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		Index(benchInputTorture, benchNeedleTorture)
-	}
-}
-
-func BenchmarkCountTorture(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		Count(benchInputTorture, benchNeedleTorture)
-	}
-}
-
-func BenchmarkCountTortureOverlapping(b *testing.B) {
-	A := Repeat("ABC", 1<<20)
-	B := Repeat("ABC", 1<<10)
-	for i := 0; i < b.N; i++ {
-		Count(A, B)
-	}
-}
-
-var makeFieldsInput = func() string {
-	x := make([]byte, 1<<20)
-	// Input is ~10% space, ~10% 2-byte UTF-8, rest ASCII non-space.
-	for i := range x {
-		switch rand.Intn(10) {
-		case 0:
-			x[i] = ' '
-		case 1:
-			if i > 0 && x[i-1] == 'x' {
-				copy(x[i-1:], "χ")
-				break
-			}
-			fallthrough
-		default:
-			x[i] = 'x'
-		}
-	}
-	return string(x)
-}
-
-var fieldsInput = makeFieldsInput()
-
-func BenchmarkFields(b *testing.B) {
-	b.SetBytes(int64(len(fieldsInput)))
-	for i := 0; i < b.N; i++ {
-		Fields(fieldsInput)
-	}
-}
-
-func BenchmarkFieldsFunc(b *testing.B) {
-	b.SetBytes(int64(len(fieldsInput)))
-	for i := 0; i < b.N; i++ {
-		FieldsFunc(fieldsInput, unicode.IsSpace)
-	}
-}
-
-func BenchmarkSplit1(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		Split(benchInputHard, "")
-	}
-}
-
-func BenchmarkSplit2(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		Split(benchInputHard, "/")
-	}
-}
-
-func BenchmarkSplit3(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		Split(benchInputHard, "hello")
-	}
-}
diff --git a/src/pkg/sync/atomic/64bit_arm.go b/src/pkg/sync/atomic/64bit_arm.go
deleted file mode 100644
index c08f214..0000000
--- a/src/pkg/sync/atomic/64bit_arm.go
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2012 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package atomic
-
-func loadUint64(addr *uint64) (val uint64) {
-	for {
-		val = *addr
-		if CompareAndSwapUint64(addr, val, val) {
-			break
-		}
-	}
-	return
-}
-
-func storeUint64(addr *uint64, val uint64) {
-	for {
-		old := *addr
-		if CompareAndSwapUint64(addr, old, val) {
-			break
-		}
-	}
-	return
-}
-
-func addUint64(val *uint64, delta uint64) (new uint64) {
-	for {
-		old := *val
-		new = old + delta
-		if CompareAndSwapUint64(val, old, new) {
-			break
-		}
-	}
-	return
-}
-
-func swapUint64(addr *uint64, new uint64) (old uint64) {
-	for {
-		old = *addr
-		if CompareAndSwapUint64(addr, old, new) {
-			break
-		}
-	}
-	return
-}
diff --git a/src/pkg/sync/atomic/asm_386.s b/src/pkg/sync/atomic/asm_386.s
deleted file mode 100644
index 807c2f8..0000000
--- a/src/pkg/sync/atomic/asm_386.s
+++ /dev/null
@@ -1,214 +0,0 @@
-// Copyright 2011 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build !race
-
-#include "../../../cmd/ld/textflag.h"
-
-TEXT ·SwapInt32(SB),NOSPLIT,$0-12
-	JMP	·SwapUint32(SB)
-
-TEXT ·SwapUint32(SB),NOSPLIT,$0-12
-	MOVL	addr+0(FP), BP
-	MOVL	new+4(FP), AX
-	XCHGL	AX, 0(BP)
-	MOVL	AX, old+8(FP)
-	RET
-
-TEXT ·SwapInt64(SB),NOSPLIT,$0-20
-	JMP	·SwapUint64(SB)
-
-TEXT ·SwapUint64(SB),NOSPLIT,$0-20
-	// no XCHGQ so use CMPXCHG8B loop
-	MOVL	addr+0(FP), BP
-	TESTL	$7, BP
-	JZ	2(PC)
-	MOVL	0, AX // crash with nil ptr deref
-	// CX:BX = new
-	MOVL	new_lo+4(FP), BX
-	MOVL	new_hi+8(FP), CX
-	// DX:AX = *addr
-	MOVL	0(BP), AX
-	MOVL	4(BP), DX
-swaploop:
-	// if *addr == DX:AX
-	//	*addr = CX:BX
-	// else
-	//	DX:AX = *addr
-	// all in one instruction
-	LOCK
-	CMPXCHG8B	0(BP)
-	JNZ	swaploop
-
-	// success
-	// return DX:AX
-	MOVL	AX, old_lo+12(FP)
-	MOVL	DX, old_hi+16(FP)
-	RET
-
-TEXT ·SwapUintptr(SB),NOSPLIT,$0-12
-	JMP	·SwapUint32(SB)
-
-TEXT ·SwapPointer(SB),NOSPLIT,$0-12
-	JMP	·SwapUint32(SB)
-
-TEXT ·CompareAndSwapInt32(SB),NOSPLIT,$0-13
-	JMP	·CompareAndSwapUint32(SB)
-
-TEXT ·CompareAndSwapUint32(SB),NOSPLIT,$0-13
-	MOVL	addr+0(FP), BP
-	MOVL	old+4(FP), AX
-	MOVL	new+8(FP), CX
-	// CMPXCHGL was introduced on the 486.
-	LOCK
-	CMPXCHGL	CX, 0(BP)
-	SETEQ	swapped+12(FP)
-	RET
-
-TEXT ·CompareAndSwapUintptr(SB),NOSPLIT,$0-13
-	JMP	·CompareAndSwapUint32(SB)
-
-TEXT ·CompareAndSwapPointer(SB),NOSPLIT,$0-13
-	JMP	·CompareAndSwapUint32(SB)
-
-TEXT ·CompareAndSwapInt64(SB),NOSPLIT,$0-21
-	JMP	·CompareAndSwapUint64(SB)
-
-TEXT ·CompareAndSwapUint64(SB),NOSPLIT,$0-21
-	MOVL	addr+0(FP), BP
-	TESTL	$7, BP
-	JZ	2(PC)
-	MOVL	0, AX // crash with nil ptr deref
-	MOVL	old_lo+4(FP), AX
-	MOVL	old_hi+8(FP), DX
-	MOVL	new_lo+12(FP), BX
-	MOVL	new_hi+16(FP), CX
-	// CMPXCHG8B was introduced on the Pentium.
-	LOCK
-	CMPXCHG8B	0(BP)
-	SETEQ	swapped+20(FP)
-	RET
-
-TEXT ·AddInt32(SB),NOSPLIT,$0-12
-	JMP	·AddUint32(SB)
-
-TEXT ·AddUint32(SB),NOSPLIT,$0-12
-	MOVL	addr+0(FP), BP
-	MOVL	delta+4(FP), AX
-	MOVL	AX, CX
-	// XADD was introduced on the 486.
-	LOCK
-	XADDL	AX, 0(BP)
-	ADDL	AX, CX
-	MOVL	CX, new+8(FP)
-	RET
-
-TEXT ·AddUintptr(SB),NOSPLIT,$0-12
-	JMP	·AddUint32(SB)
-
-TEXT ·AddInt64(SB),NOSPLIT,$0-20
-	JMP	·AddUint64(SB)
-
-TEXT ·AddUint64(SB),NOSPLIT,$0-20
-	// no XADDQ so use CMPXCHG8B loop
-	MOVL	addr+0(FP), BP
-	TESTL	$7, BP
-	JZ	2(PC)
-	MOVL	0, AX // crash with nil ptr deref
-	// DI:SI = delta
-	MOVL	delta_lo+4(FP), SI
-	MOVL	delta_hi+8(FP), DI
-	// DX:AX = *addr
-	MOVL	0(BP), AX
-	MOVL	4(BP), DX
-addloop:
-	// CX:BX = DX:AX (*addr) + DI:SI (delta)
-	MOVL	AX, BX
-	MOVL	DX, CX
-	ADDL	SI, BX
-	ADCL	DI, CX
-
-	// if *addr == DX:AX {
-	//	*addr = CX:BX
-	// } else {
-	//	DX:AX = *addr
-	// }
-	// all in one instruction
-	LOCK
-	CMPXCHG8B	0(BP)
-
-	JNZ	addloop
-
-	// success
-	// return CX:BX
-	MOVL	BX, new_lo+12(FP)
-	MOVL	CX, new_hi+16(FP)
-	RET
-
-TEXT ·LoadInt32(SB),NOSPLIT,$0-8
-	JMP	·LoadUint32(SB)
-
-TEXT ·LoadUint32(SB),NOSPLIT,$0-8
-	MOVL	addr+0(FP), AX
-	MOVL	0(AX), AX
-	MOVL	AX, val+4(FP)
-	RET
-
-TEXT ·LoadInt64(SB),NOSPLIT,$0-12
-	JMP	·LoadUint64(SB)
-
-TEXT ·LoadUint64(SB),NOSPLIT,$0-12
-	MOVL	addr+0(FP), AX
-	TESTL	$7, AX
-	JZ	2(PC)
-	MOVL	0, AX // crash with nil ptr deref
-	// MOVQ and EMMS were introduced on the Pentium MMX.
-	// MOVQ (%EAX), %MM0
-	BYTE $0x0f; BYTE $0x6f; BYTE $0x00
-	// MOVQ %MM0, 0x8(%ESP)
-	BYTE $0x0f; BYTE $0x7f; BYTE $0x44; BYTE $0x24; BYTE $0x08
-	EMMS
-	RET
-
-TEXT ·LoadUintptr(SB),NOSPLIT,$0-8
-	JMP	·LoadUint32(SB)
-
-TEXT ·LoadPointer(SB),NOSPLIT,$0-8
-	JMP	·LoadUint32(SB)
-
-TEXT ·StoreInt32(SB),NOSPLIT,$0-8
-	JMP	·StoreUint32(SB)
-
-TEXT ·StoreUint32(SB),NOSPLIT,$0-8
-	MOVL	addr+0(FP), BP
-	MOVL	val+4(FP), AX
-	XCHGL	AX, 0(BP)
-	RET
-
-TEXT ·StoreInt64(SB),NOSPLIT,$0-12
-	JMP	·StoreUint64(SB)
-
-TEXT ·StoreUint64(SB),NOSPLIT,$0-12
-	MOVL	addr+0(FP), AX
-	TESTL	$7, AX
-	JZ	2(PC)
-	MOVL	0, AX // crash with nil ptr deref
-	// MOVQ and EMMS were introduced on the Pentium MMX.
-	// MOVQ 0x8(%ESP), %MM0
-	BYTE $0x0f; BYTE $0x6f; BYTE $0x44; BYTE $0x24; BYTE $0x08
-	// MOVQ %MM0, (%EAX)
-	BYTE $0x0f; BYTE $0x7f; BYTE $0x00 
-	EMMS
-	// This is essentially a no-op, but it provides required memory fencing.
-	// It can be replaced with MFENCE, but MFENCE was introduced only on the Pentium4 (SSE2).
-	XORL	AX, AX
-	LOCK
-	XADDL	AX, (SP)
-	RET
-
-TEXT ·StoreUintptr(SB),NOSPLIT,$0-8
-	JMP	·StoreUint32(SB)
-
-TEXT ·StorePointer(SB),NOSPLIT,$0-8
-	JMP	·StoreUint32(SB)
diff --git a/src/pkg/sync/atomic/asm_amd64.s b/src/pkg/sync/atomic/asm_amd64.s
deleted file mode 100644
index 77afa12..0000000
--- a/src/pkg/sync/atomic/asm_amd64.s
+++ /dev/null
@@ -1,146 +0,0 @@
-// Copyright 2011 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build !race
-
-#include "../../../cmd/ld/textflag.h"
-
-TEXT ·SwapInt32(SB),NOSPLIT,$0-20
-	JMP	·SwapUint32(SB)
-
-TEXT ·SwapUint32(SB),NOSPLIT,$0-20
-	MOVQ	addr+0(FP), BP
-	MOVL	new+8(FP), AX
-	XCHGL	AX, 0(BP)
-	MOVL	AX, old+16(FP)
-	RET
-
-TEXT ·SwapInt64(SB),NOSPLIT,$0-24
-	JMP	·SwapUint64(SB)
-
-TEXT ·SwapUint64(SB),NOSPLIT,$0-24
-	MOVQ	addr+0(FP), BP
-	MOVQ	new+8(FP), AX
-	XCHGQ	AX, 0(BP)
-	MOVQ	AX, old+16(FP)
-	RET
-
-TEXT ·SwapUintptr(SB),NOSPLIT,$0-24
-	JMP	·SwapUint64(SB)
-
-TEXT ·SwapPointer(SB),NOSPLIT,$0-24
-	JMP	·SwapUint64(SB)
-
-TEXT ·CompareAndSwapInt32(SB),NOSPLIT,$0-17
-	JMP	·CompareAndSwapUint32(SB)
-
-TEXT ·CompareAndSwapUint32(SB),NOSPLIT,$0-17
-	MOVQ	addr+0(FP), BP
-	MOVL	old+8(FP), AX
-	MOVL	new+12(FP), CX
-	LOCK
-	CMPXCHGL	CX, 0(BP)
-	SETEQ	swapped+16(FP)
-	RET
-
-TEXT ·CompareAndSwapUintptr(SB),NOSPLIT,$0-25
-	JMP	·CompareAndSwapUint64(SB)
-
-TEXT ·CompareAndSwapPointer(SB),NOSPLIT,$0-25
-	JMP	·CompareAndSwapUint64(SB)
-
-TEXT ·CompareAndSwapInt64(SB),NOSPLIT,$0-25
-	JMP	·CompareAndSwapUint64(SB)
-
-TEXT ·CompareAndSwapUint64(SB),NOSPLIT,$0-25
-	MOVQ	addr+0(FP), BP
-	MOVQ	old+8(FP), AX
-	MOVQ	new+16(FP), CX
-	LOCK
-	CMPXCHGQ	CX, 0(BP)
-	SETEQ	swapped+24(FP)
-	RET
-
-TEXT ·AddInt32(SB),NOSPLIT,$0-20
-	JMP	·AddUint32(SB)
-
-TEXT ·AddUint32(SB),NOSPLIT,$0-20
-	MOVQ	addr+0(FP), BP
-	MOVL	delta+8(FP), AX
-	MOVL	AX, CX
-	LOCK
-	XADDL	AX, 0(BP)
-	ADDL	AX, CX
-	MOVL	CX, new+16(FP)
-	RET
-
-TEXT ·AddUintptr(SB),NOSPLIT,$0-24
-	JMP	·AddUint64(SB)
-
-TEXT ·AddInt64(SB),NOSPLIT,$0-24
-	JMP	·AddUint64(SB)
-
-TEXT ·AddUint64(SB),NOSPLIT,$0-24
-	MOVQ	addr+0(FP), BP
-	MOVQ	delta+8(FP), AX
-	MOVQ	AX, CX
-	LOCK
-	XADDQ	AX, 0(BP)
-	ADDQ	AX, CX
-	MOVQ	CX, new+16(FP)
-	RET
-
-TEXT ·LoadInt32(SB),NOSPLIT,$0-12
-	JMP	·LoadUint32(SB)
-
-TEXT ·LoadUint32(SB),NOSPLIT,$0-12
-	MOVQ	addr+0(FP), AX
-	MOVL	0(AX), AX
-	MOVL	AX, val+8(FP)
-	RET
-
-TEXT ·LoadInt64(SB),NOSPLIT,$0-16
-	JMP	·LoadUint64(SB)
-
-TEXT ·LoadUint64(SB),NOSPLIT,$0-16
-	MOVQ	addr+0(FP), AX
-	MOVQ	0(AX), AX
-	MOVQ	AX, val+8(FP)
-	RET
-
-TEXT ·LoadUintptr(SB),NOSPLIT,$0-16
-	JMP	·LoadPointer(SB)
-
-TEXT ·LoadPointer(SB),NOSPLIT,$0-16
-	MOVQ	addr+0(FP), AX
-	MOVQ	0(AX), AX
-	MOVQ	AX, val+8(FP)
-	RET
-
-TEXT ·StoreInt32(SB),NOSPLIT,$0-12
-	JMP	·StoreUint32(SB)
-
-TEXT ·StoreUint32(SB),NOSPLIT,$0-12
-	MOVQ	addr+0(FP), BP
-	MOVL	val+8(FP), AX
-	XCHGL	AX, 0(BP)
-	RET
-
-TEXT ·StoreInt64(SB),NOSPLIT,$0-16
-	JMP	·StoreUint64(SB)
-
-TEXT ·StoreUint64(SB),NOSPLIT,$0-16
-	MOVQ	addr+0(FP), BP
-	MOVQ	val+8(FP), AX
-	XCHGQ	AX, 0(BP)
-	RET
-
-TEXT ·StoreUintptr(SB),NOSPLIT,$0-16
-	JMP	·StorePointer(SB)
-
-TEXT ·StorePointer(SB),NOSPLIT,$0-16
-	MOVQ	addr+0(FP), BP
-	MOVQ	val+8(FP), AX
-	XCHGQ	AX, 0(BP)
-	RET
diff --git a/src/pkg/sync/atomic/asm_amd64p32.s b/src/pkg/sync/atomic/asm_amd64p32.s
deleted file mode 100644
index b24ae7a..0000000
--- a/src/pkg/sync/atomic/asm_amd64p32.s
+++ /dev/null
@@ -1,159 +0,0 @@
-// Copyright 2011 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../../cmd/ld/textflag.h"
-
-TEXT ·SwapInt32(SB),NOSPLIT,$0-12
-	JMP	·SwapUint32(SB)
-
-TEXT ·SwapUint32(SB),NOSPLIT,$0-12
-	MOVL	addr+0(FP), BX
-	MOVL	new+4(FP), AX
-	XCHGL	AX, 0(BX)
-	MOVL	AX, old+8(FP)
-	RET
-
-TEXT ·SwapInt64(SB),NOSPLIT,$0-24
-	JMP	·SwapUint64(SB)
-
-TEXT ·SwapUint64(SB),NOSPLIT,$0-24
-	MOVL	addr+0(FP), BX
-	TESTL	$7, BX
-	JZ	2(PC)
-	MOVL	0, BX // crash with nil ptr deref
-	MOVQ	new+8(FP), AX
-	XCHGQ	AX, 0(BX)
-	MOVQ	AX, old+16(FP)
-	RET
-
-TEXT ·SwapUintptr(SB),NOSPLIT,$0-12
-	JMP	·SwapUint32(SB)
-
-TEXT ·SwapPointer(SB),NOSPLIT,$0-12
-	JMP	·SwapUint32(SB)
-
-TEXT ·CompareAndSwapInt32(SB),NOSPLIT,$0-17
-	JMP	·CompareAndSwapUint32(SB)
-
-TEXT ·CompareAndSwapUint32(SB),NOSPLIT,$0-17
-	MOVL	addr+0(FP), BX
-	MOVL	old+4(FP), AX
-	MOVL	new+8(FP), CX
-	LOCK
-	CMPXCHGL	CX, 0(BX)
-	SETEQ	swapped+16(FP)
-	RET
-
-TEXT ·CompareAndSwapUintptr(SB),NOSPLIT,$0-17
-	JMP	·CompareAndSwapUint32(SB)
-
-TEXT ·CompareAndSwapPointer(SB),NOSPLIT,$0-17
-	JMP	·CompareAndSwapUint32(SB)
-
-TEXT ·CompareAndSwapInt64(SB),NOSPLIT,$0-25
-	JMP	·CompareAndSwapUint64(SB)
-
-TEXT ·CompareAndSwapUint64(SB),NOSPLIT,$0-25
-	MOVL	addr+0(FP), BX
-	TESTL	$7, BX
-	JZ	2(PC)
-	MOVL	0, BX // crash with nil ptr deref
-	MOVQ	old+8(FP), AX
-	MOVQ	new+16(FP), CX
-	LOCK
-	CMPXCHGQ	CX, 0(BX)
-	SETEQ	swapped+24(FP)
-	RET
-
-TEXT ·AddInt32(SB),NOSPLIT,$0-12
-	JMP	·AddUint32(SB)
-
-TEXT ·AddUint32(SB),NOSPLIT,$0-12
-	MOVL	addr+0(FP), BX
-	MOVL	delta+4(FP), AX
-	MOVL	AX, CX
-	LOCK
-	XADDL	AX, 0(BX)
-	ADDL	AX, CX
-	MOVL	CX, new+8(FP)
-	RET
-
-TEXT ·AddUintptr(SB),NOSPLIT,$0-12
-	JMP	·AddUint32(SB)
-
-TEXT ·AddInt64(SB),NOSPLIT,$0-24
-	JMP	·AddUint64(SB)
-
-TEXT ·AddUint64(SB),NOSPLIT,$0-24
-	MOVL	addr+0(FP), BX
-	TESTL	$7, BX
-	JZ	2(PC)
-	MOVL	0, BX // crash with nil ptr deref
-	MOVQ	delta+8(FP), AX
-	MOVQ	AX, CX
-	LOCK
-	XADDQ	AX, 0(BX)
-	ADDQ	AX, CX
-	MOVQ	CX, new+16(FP)
-	RET
-
-TEXT ·LoadInt32(SB),NOSPLIT,$0-12
-	JMP	·LoadUint32(SB)
-
-TEXT ·LoadUint32(SB),NOSPLIT,$0-12
-	MOVL	addr+0(FP), AX
-	MOVL	0(AX), AX
-	MOVL	AX, val+8(FP)
-	RET
-
-TEXT ·LoadInt64(SB),NOSPLIT,$0-16
-	JMP	·LoadUint64(SB)
-
-TEXT ·LoadUint64(SB),NOSPLIT,$0-16
-	MOVL	addr+0(FP), AX
-	TESTL	$7, AX
-	JZ	2(PC)
-	MOVL	0, AX // crash with nil ptr deref
-	MOVQ	0(AX), AX
-	MOVQ	AX, val+8(FP)
-	RET
-
-TEXT ·LoadUintptr(SB),NOSPLIT,$0-12
-	JMP	·LoadPointer(SB)
-
-TEXT ·LoadPointer(SB),NOSPLIT,$0-12
-	MOVL	addr+0(FP), AX
-	MOVL	0(AX), AX
-	MOVL	AX, val+8(FP)
-	RET
-
-TEXT ·StoreInt32(SB),NOSPLIT,$0-8
-	JMP	·StoreUint32(SB)
-
-TEXT ·StoreUint32(SB),NOSPLIT,$0-8
-	MOVL	addr+0(FP), BX
-	MOVL	val+4(FP), AX
-	XCHGL	AX, 0(BX)
-	RET
-
-TEXT ·StoreInt64(SB),NOSPLIT,$0-16
-	JMP	·StoreUint64(SB)
-
-TEXT ·StoreUint64(SB),NOSPLIT,$0-16
-	MOVL	addr+0(FP), BX
-	TESTL	$7, BX
-	JZ	2(PC)
-	MOVL	0, BX // crash with nil ptr deref
-	MOVQ	val+8(FP), AX
-	XCHGQ	AX, 0(BX)
-	RET
-
-TEXT ·StoreUintptr(SB),NOSPLIT,$0-8
-	JMP	·StorePointer(SB)
-
-TEXT ·StorePointer(SB),NOSPLIT,$0-8
-	MOVL	addr+0(FP), BX
-	MOVL	val+4(FP), AX
-	XCHGL	AX, 0(BX)
-	RET
diff --git a/src/pkg/sync/atomic/asm_arm.s b/src/pkg/sync/atomic/asm_arm.s
deleted file mode 100644
index 7c8620a..0000000
--- a/src/pkg/sync/atomic/asm_arm.s
+++ /dev/null
@@ -1,197 +0,0 @@
-// Copyright 2011 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build !race
-
-#include "../../../cmd/ld/textflag.h"
-
-// ARM atomic operations, for use by asm_$(GOOS)_arm.s.
-
-TEXT ·armCompareAndSwapUint32(SB),NOSPLIT,$0-13
-	MOVW	addr+0(FP), R1
-	MOVW	old+4(FP), R2
-	MOVW	new+8(FP), R3
-casloop:
-	// LDREX and STREX were introduced in ARMv6.
-	LDREX	(R1), R0
-	CMP	R0, R2
-	BNE	casfail
-	STREX	R3, (R1), R0
-	CMP	$0, R0
-	BNE	casloop
-	MOVW	$1, R0
-	MOVBU	R0, ret+12(FP)
-	RET
-casfail:
-	MOVW	$0, R0
-	MOVBU	R0, ret+12(FP)
-	RET
-
-TEXT ·armCompareAndSwapUint64(SB),NOSPLIT,$0-21
-	BL	fastCheck64<>(SB)
-	MOVW	addr+0(FP), R1
-	// make unaligned atomic access panic
-	AND.S	$7, R1, R2
-	BEQ 	2(PC)
-	MOVW	R2, (R2)
-	MOVW	oldlo+4(FP), R2
-	MOVW	oldhi+8(FP), R3
-	MOVW	newlo+12(FP), R4
-	MOVW	newhi+16(FP), R5
-cas64loop:
-	// LDREXD and STREXD were introduced in ARMv6k.
-	LDREXD	(R1), R6  // loads R6 and R7
-	CMP	R2, R6
-	BNE	cas64fail
-	CMP	R3, R7
-	BNE	cas64fail
-	STREXD	R4, (R1), R0	// stores R4 and R5
-	CMP	$0, R0
-	BNE	cas64loop
-	MOVW	$1, R0
-	MOVBU	R0, ret+20(FP)
-	RET
-cas64fail:
-	MOVW	$0, R0
-	MOVBU	R0, ret+20(FP)
-	RET
-
-TEXT ·armAddUint32(SB),NOSPLIT,$0-12
-	MOVW	addr+0(FP), R1
-	MOVW	delta+4(FP), R2
-addloop:
-	// LDREX and STREX were introduced in ARMv6.
-	LDREX	(R1), R3
-	ADD	R2, R3
-	STREX	R3, (R1), R0
-	CMP	$0, R0
-	BNE	addloop
-	MOVW	R3, ret+8(FP)
-	RET
-
-TEXT ·armAddUint64(SB),NOSPLIT,$0-20
-	BL	fastCheck64<>(SB)
-	MOVW	addr+0(FP), R1
-	// make unaligned atomic access panic
-	AND.S	$7, R1, R2
-	BEQ 	2(PC)
-	MOVW	R2, (R2)
-	MOVW	deltalo+4(FP), R2
-	MOVW	deltahi+8(FP), R3
-add64loop:
-	// LDREXD and STREXD were introduced in ARMv6k.
-	LDREXD	(R1), R4	// loads R4 and R5
-	ADD.S	R2, R4
-	ADC	R3, R5
-	STREXD	R4, (R1), R0	// stores R4 and R5
-	CMP	$0, R0
-	BNE	add64loop
-	MOVW	R4, retlo+12(FP)
-	MOVW	R5, rethi+16(FP)
-	RET
-
-TEXT ·armSwapUint32(SB),NOSPLIT,$0-12
-	MOVW	addr+0(FP), R1
-	MOVW	new+4(FP), R2
-swaploop:
-	// LDREX and STREX were introduced in ARMv6.
-	LDREX	(R1), R3
-	STREX	R2, (R1), R0
-	CMP	$0, R0
-	BNE	swaploop
-	MOVW	R3, old+8(FP)
-	RET
-
-TEXT ·armSwapUint64(SB),NOSPLIT,$0-20
-	BL	fastCheck64<>(SB)
-	MOVW	addr+0(FP), R1
-	// make unaligned atomic access panic
-	AND.S	$7, R1, R2
-	BEQ 	2(PC)
-	MOVW	R2, (R2)
-	MOVW	newlo+4(FP), R2
-	MOVW	newhi+8(FP), R3
-swap64loop:
-	// LDREXD and STREXD were introduced in ARMv6k.
-	LDREXD	(R1), R4	// loads R4 and R5
-	STREXD	R2, (R1), R0	// stores R2 and R3
-	CMP	$0, R0
-	BNE	swap64loop
-	MOVW	R4, oldlo+12(FP)
-	MOVW	R5, oldhi+16(FP)
-	RET
-
-TEXT ·armLoadUint64(SB),NOSPLIT,$0-12
-	BL	fastCheck64<>(SB)
-	MOVW	addr+0(FP), R1
-	// make unaligned atomic access panic
-	AND.S	$7, R1, R2
-	BEQ 	2(PC)
-	MOVW	R2, (R2)
-load64loop:
-	LDREXD	(R1), R2	// loads R2 and R3
-	STREXD	R2, (R1), R0	// stores R2 and R3
-	CMP	$0, R0
-	BNE	load64loop
-	MOVW	R2, vallo+4(FP)
-	MOVW	R3, valhi+8(FP)
-	RET
-
-TEXT ·armStoreUint64(SB),NOSPLIT,$0-12
-	BL	fastCheck64<>(SB)
-	MOVW	addr+0(FP), R1
-	// make unaligned atomic access panic
-	AND.S	$7, R1, R2
-	BEQ 	2(PC)
-	MOVW	R2, (R2)
-	MOVW	vallo+4(FP), R2
-	MOVW	valhi+8(FP), R3
-store64loop:
-	LDREXD	(R1), R4	// loads R4 and R5
-	STREXD	R2, (R1), R0	// stores R2 and R3
-	CMP	$0, R0
-	BNE	store64loop
-	RET
-
-// Check for broken 64-bit LDREXD as found in QEMU.
-// LDREXD followed by immediate STREXD should succeed.
-// If it fails, try a few times just to be sure (maybe our thread got
-// rescheduled between the two instructions) and then panic.
-// A bug in some copies of QEMU makes STREXD never succeed,
-// which will make uses of the 64-bit atomic operations loop forever.
-// If things are working, set okLDREXD to avoid future checks.
-// https://bugs.launchpad.net/qemu/+bug/670883.
-TEXT	check64<>(SB),NOSPLIT,$16-0
-	MOVW	$10, R1
-	// 8-aligned stack address scratch space.
-	MOVW	$8(R13), R5
-	AND	$~7, R5
-loop:
-	LDREXD	(R5), R2
-	STREXD	R2, (R5), R0
-	CMP	$0, R0
-	BEQ	ok
-	SUB	$1, R1
-	CMP	$0, R1
-	BNE	loop
-	// Must be buggy QEMU.
-	BL	·panic64(SB)
-ok:
-	RET
-
-// Fast, cached version of check.  No frame, just MOVW CMP RET after first time.
-TEXT	fastCheck64<>(SB),NOSPLIT,$-4
-	MOVW	ok64<>(SB), R0
-	CMP	$0, R0	// have we been here before?
-	RET.NE
-	B	slowCheck64<>(SB)
-
-TEXT slowCheck64<>(SB),NOSPLIT,$0-0
-	BL	check64<>(SB)
-	// Still here, must be okay.
-	MOVW	$1, R0
-	MOVW	R0, ok64<>(SB)
-	RET
-
-GLOBL ok64<>(SB), $4
diff --git a/src/pkg/sync/atomic/asm_freebsd_arm.s b/src/pkg/sync/atomic/asm_freebsd_arm.s
deleted file mode 100644
index db37f73..0000000
--- a/src/pkg/sync/atomic/asm_freebsd_arm.s
+++ /dev/null
@@ -1,109 +0,0 @@
-// Copyright 2012 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../../cmd/ld/textflag.h"
-
-// FreeBSD/ARM atomic operations.
-// TODO(minux): this only supports ARMv6K or higher.
-
-TEXT ·CompareAndSwapInt32(SB),NOSPLIT,$0
-	B ·CompareAndSwapUint32(SB)
-
-TEXT ·CompareAndSwapUint32(SB),NOSPLIT,$0
-	B ·armCompareAndSwapUint32(SB)
-
-TEXT ·CompareAndSwapUintptr(SB),NOSPLIT,$0
-	B ·CompareAndSwapUint32(SB)
-
-TEXT ·CompareAndSwapPointer(SB),NOSPLIT,$0
-	B ·CompareAndSwapUint32(SB)
-
-TEXT ·AddInt32(SB),NOSPLIT,$0
-	B ·AddUint32(SB)
-
-TEXT ·AddUint32(SB),NOSPLIT,$0
-	B ·armAddUint32(SB)
-
-TEXT ·AddUintptr(SB),NOSPLIT,$0
-	B ·AddUint32(SB)
-
-TEXT ·SwapInt32(SB),NOSPLIT,$0
-	B ·SwapUint32(SB)
-
-TEXT ·SwapUint32(SB),NOSPLIT,$0
-	B ·armSwapUint32(SB)
-
-TEXT ·SwapUintptr(SB),NOSPLIT,$0
-	B ·SwapUint32(SB)
-
-TEXT ·SwapPointer(SB),NOSPLIT,$0
-	B ·SwapUint32(SB)
-
-TEXT ·CompareAndSwapInt64(SB),NOSPLIT,$0
-	B ·CompareAndSwapUint64(SB)
-
-TEXT ·CompareAndSwapUint64(SB),NOSPLIT,$-4
-	B ·armCompareAndSwapUint64(SB)
-
-TEXT ·AddInt64(SB),NOSPLIT,$0
-	B ·addUint64(SB)
-
-TEXT ·AddUint64(SB),NOSPLIT,$0
-	B ·addUint64(SB)
-
-TEXT ·SwapInt64(SB),NOSPLIT,$0
-	B ·swapUint64(SB)
-
-TEXT ·SwapUint64(SB),NOSPLIT,$0
-	B ·swapUint64(SB)
-
-TEXT ·LoadInt32(SB),NOSPLIT,$0
-	B ·LoadUint32(SB)
-
-TEXT ·LoadUint32(SB),NOSPLIT,$0-8
-	MOVW addr+0(FP), R1
-load32loop:
-	LDREX (R1), R2		// loads R2
-	STREX R2, (R1), R0	// stores R2
-	CMP $0, R0
-	BNE load32loop
-	MOVW R2, val+4(FP)
-	RET
-
-TEXT ·LoadInt64(SB),NOSPLIT,$0
-	B ·loadUint64(SB)
-
-TEXT ·LoadUint64(SB),NOSPLIT,$0
-	B ·loadUint64(SB)
-
-TEXT ·LoadUintptr(SB),NOSPLIT,$0
-	B ·LoadUint32(SB)
-
-TEXT ·LoadPointer(SB),NOSPLIT,$0
-	B ·LoadUint32(SB)
-
-TEXT ·StoreInt32(SB),NOSPLIT,$0
-	B ·StoreUint32(SB)
-
-TEXT ·StoreUint32(SB),NOSPLIT,$0-8
-	MOVW addr+0(FP), R1
-	MOVW val+4(FP), R2
-storeloop:
-	LDREX (R1), R4		// loads R4
-	STREX R2, (R1), R0	// stores R2
-	CMP $0, R0
-	BNE storeloop
-	RET
-
-TEXT ·StoreInt64(SB),NOSPLIT,$0
-	B ·storeUint64(SB)
-
-TEXT ·StoreUint64(SB),NOSPLIT,$0
-	B ·storeUint64(SB)
-
-TEXT ·StoreUintptr(SB),NOSPLIT,$0
-	B ·StoreUint32(SB)
-
-TEXT ·StorePointer(SB),NOSPLIT,$0
-	B ·StoreUint32(SB)
diff --git a/src/pkg/sync/atomic/asm_linux_arm.s b/src/pkg/sync/atomic/asm_linux_arm.s
deleted file mode 100644
index 27be57a..0000000
--- a/src/pkg/sync/atomic/asm_linux_arm.s
+++ /dev/null
@@ -1,236 +0,0 @@
-// Copyright 2011 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build !race
-
-#include "../../../cmd/ld/textflag.h"
-
-// Linux/ARM atomic operations.
-
-// Because there is so much variation in ARM devices,
-// the Linux kernel provides an appropriate compare-and-swap
-// implementation at address 0xffff0fc0.  Caller sets:
-//	R0 = old value
-//	R1 = new value
-//	R2 = addr
-//	LR = return address
-// The function returns with CS true if the swap happened.
-// http://lxr.linux.no/linux+v2.6.37.2/arch/arm/kernel/entry-armv.S#L850
-// On older kernels (before 2.6.24) the function can incorrectly
-// report a conflict, so we have to double-check the compare ourselves
-// and retry if necessary.
-//
-// http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=b49c0f24cf6744a3f4fd09289fe7cade349dead5
-//
-TEXT cas<>(SB),NOSPLIT,$0
-	MOVW	$0xffff0fc0, PC
-
-TEXT ·CompareAndSwapInt32(SB),NOSPLIT,$0
-	B	·CompareAndSwapUint32(SB)
-
-// Implement using kernel cas for portability.
-TEXT ·CompareAndSwapUint32(SB),NOSPLIT,$0-13
-	MOVW	addr+0(FP), R2
-	// trigger potential paging fault here,
-	// because we don't know how to traceback through __kuser_cmpxchg
-	MOVW	(R2), R0
-	MOVW	old+4(FP), R0
-casagain:
-	MOVW	new+8(FP), R1
-	BL	cas<>(SB)
-	BCC	cascheck
-	MOVW	$1, R0
-casret:
-	MOVB	R0, swapped+12(FP)
-	RET
-cascheck:
-	// Kernel lies; double-check.
-	MOVW	addr+0(FP), R2
-	MOVW	old+4(FP), R0
-	MOVW	0(R2), R3
-	CMP	R0, R3
-	BEQ	casagain
-	MOVW	$0, R0
-	B	casret
-
-TEXT ·CompareAndSwapUintptr(SB),NOSPLIT,$0
-	B	·CompareAndSwapUint32(SB)
-
-TEXT ·CompareAndSwapPointer(SB),NOSPLIT,$0
-	B	·CompareAndSwapUint32(SB)
-
-TEXT ·AddInt32(SB),NOSPLIT,$0
-	B	·AddUint32(SB)
-
-// Implement using kernel cas for portability.
-TEXT ·AddUint32(SB),NOSPLIT,$0-12
-	MOVW	addr+0(FP), R2
-	MOVW	delta+4(FP), R4
-addloop1:
-	MOVW	0(R2), R0
-	MOVW	R0, R1
-	ADD	R4, R1
-	BL	cas<>(SB)
-	BCC	addloop1
-	MOVW	R1, new+8(FP)
-	RET
-
-TEXT ·AddUintptr(SB),NOSPLIT,$0
-	B	·AddUint32(SB)
-
-TEXT ·SwapInt32(SB),NOSPLIT,$0
-	B	·SwapUint32(SB)
-
-// Implement using kernel cas for portability.
-TEXT ·SwapUint32(SB),NOSPLIT,$0-12
-	MOVW	addr+0(FP), R2
-	MOVW	new+4(FP), R1
-swaploop1:
-	MOVW	0(R2), R0
-	MOVW	R0, R4 // cas smashes R0
-	BL	cas<>(SB)
-	BCC	swaploop1
-	MOVW	R4, old+8(FP)
-	RET
-
-TEXT ·SwapUintptr(SB),NOSPLIT,$0
-	B	·SwapUint32(SB)
-
-TEXT ·SwapPointer(SB),NOSPLIT,$0
-	B	·SwapUint32(SB)
-
-TEXT cas64<>(SB),NOSPLIT,$0
-	MOVW	$0xffff0f60, PC // __kuser_cmpxchg64: Linux-3.1 and above
-
-TEXT kernelCAS64<>(SB),NOSPLIT,$0-21
-	// int (*__kuser_cmpxchg64_t)(const int64_t *oldval, const int64_t *newval, volatile int64_t *ptr);
-	MOVW	addr+0(FP), R2 // ptr
-	// trigger potential paging fault here,
-	// because we don't know how to traceback through __kuser_cmpxchg64
-	MOVW	(R2), R0
-	// make unaligned atomic access panic
-	AND.S	$7, R2, R1
-	BEQ 	2(PC)
-	MOVW	R1, (R1)
-	MOVW	$4(FP), R0 // oldval
-	MOVW	$12(FP), R1 // newval
-	BL	cas64<>(SB)
-	MOVW.CS	$1, R0 // C is set if the kernel has changed *ptr
-	MOVW.CC	$0, R0
-	MOVW	R0, 20(FP)
-	RET
-
-TEXT ·generalCAS64(SB),NOSPLIT,$20-21
-	// bool runtime·cas64(uint64 volatile *addr, uint64 old, uint64 new)
-	MOVW	addr+0(FP), R0
-	// trigger potential paging fault here,
-	// because a fault in runtime.cas64 will hang.
-	MOVW	(R0), R2
-	// make unaligned atomic access panic
-	AND.S	$7, R0, R1
-	BEQ 	2(PC)
-	MOVW	R1, (R1)
-	MOVW	R0, 4(R13)
-	MOVW	old_lo+4(FP), R1
-	MOVW	R1, 8(R13)
-	MOVW	old_hi+8(FP), R1
-	MOVW	R1, 12(R13)
-	MOVW	new_lo+12(FP), R2
-	MOVW	R2, 16(R13)
-	MOVW	new_hi+16(FP), R3
-	MOVW	R3, 20(R13)
-	BL  	runtime·cas64(SB)
-	MOVB	R0, ret+20(FP)
-	RET
-
-GLOBL armCAS64(SB), $4
-
-TEXT setupAndCallCAS64<>(SB),NOSPLIT,$-4-21
-	MOVW	$0xffff0ffc, R0 // __kuser_helper_version
-	MOVW	(R0), R0
-	// __kuser_cmpxchg64 only present if helper version >= 5
-	CMP 	$5, R0
-	MOVW.CS	$kernelCAS64<>(SB), R1
-	MOVW.CS	R1, armCAS64(SB)
-	MOVW.CS	R1, PC
-	MOVB	runtime·armArch(SB), R0
-	// LDREXD, STREXD only present on ARMv6K or higher
-	CMP	$6, R0 // TODO(minux): how to differentiate ARMv6 with ARMv6K?
-	MOVW.CS	$·armCompareAndSwapUint64(SB), R1
-	MOVW.CS	R1, armCAS64(SB)
-	MOVW.CS	R1, PC
-	// we are out of luck, can only use runtime's emulated 64-bit cas
-	MOVW	$·generalCAS64(SB), R1
-	MOVW	R1, armCAS64(SB)
-	MOVW	R1, PC
-
-TEXT ·CompareAndSwapInt64(SB),NOSPLIT,$0
-	B   	·CompareAndSwapUint64(SB)
-
-TEXT ·CompareAndSwapUint64(SB),NOSPLIT,$-4-21
-	MOVW	armCAS64(SB), R0
-	CMP 	$0, R0
-	MOVW.NE	R0, PC
-	B	setupAndCallCAS64<>(SB)
-
-TEXT ·AddInt64(SB),NOSPLIT,$0
-	B	·addUint64(SB)
-
-TEXT ·AddUint64(SB),NOSPLIT,$0
-	B	·addUint64(SB)
-
-TEXT ·SwapInt64(SB),NOSPLIT,$0
-	B	·swapUint64(SB)
-
-TEXT ·SwapUint64(SB),NOSPLIT,$0
-	B	·swapUint64(SB)
-
-TEXT ·LoadInt32(SB),NOSPLIT,$0
-	B	·LoadUint32(SB)
-
-TEXT ·LoadUint32(SB),NOSPLIT,$0-8
-	MOVW	addr+0(FP), R2
-loadloop1:
-	MOVW	0(R2), R0
-	MOVW	R0, R1
-	BL	cas<>(SB)
-	BCC	loadloop1
-	MOVW	R1, val+4(FP)
-	RET
-
-TEXT ·LoadInt64(SB),NOSPLIT,$0
-	B	·loadUint64(SB)
-
-TEXT ·LoadUint64(SB),NOSPLIT,$0
-	B	·loadUint64(SB)
-
-TEXT ·LoadUintptr(SB),NOSPLIT,$0
-	B	·LoadUint32(SB)
-
-TEXT ·LoadPointer(SB),NOSPLIT,$0
-	B	·LoadUint32(SB)
-
-TEXT ·StoreInt32(SB),NOSPLIT,$0
-	B	·StoreUint32(SB)
-
-TEXT ·StoreUint32(SB),NOSPLIT,$0-8
-	MOVW	addr+0(FP), R2
-	MOVW	val+4(FP), R1
-storeloop1:
-	MOVW	0(R2), R0
-	BL	cas<>(SB)
-	BCC	storeloop1
-	RET
-
-TEXT ·StoreInt64(SB),NOSPLIT,$0
-	B	·storeUint64(SB)
-
-TEXT ·StoreUint64(SB),NOSPLIT,$0
-	B	·storeUint64(SB)
-
-TEXT ·StoreUintptr(SB),NOSPLIT,$0
-	B	·StoreUint32(SB)
-
-TEXT ·StorePointer(SB),NOSPLIT,$0
-	B	·StoreUint32(SB)
diff --git a/src/pkg/sync/atomic/asm_netbsd_arm.s b/src/pkg/sync/atomic/asm_netbsd_arm.s
deleted file mode 100644
index 64f4dbe..0000000
--- a/src/pkg/sync/atomic/asm_netbsd_arm.s
+++ /dev/null
@@ -1,109 +0,0 @@
-// Copyright 2013 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../../cmd/ld/textflag.h"
-
-// NetBSD/ARM atomic operations.
-// TODO(minux): this only supports ARMv6K or higher.
-
-TEXT ·CompareAndSwapInt32(SB),NOSPLIT,$0
-	B ·CompareAndSwapUint32(SB)
-
-TEXT ·CompareAndSwapUint32(SB),NOSPLIT,$0
-	B ·armCompareAndSwapUint32(SB)
-
-TEXT ·CompareAndSwapUintptr(SB),NOSPLIT,$0
-	B ·CompareAndSwapUint32(SB)
-
-TEXT ·CompareAndSwapPointer(SB),NOSPLIT,$0
-	B ·CompareAndSwapUint32(SB)
-
-TEXT ·AddInt32(SB),NOSPLIT,$0
-	B ·AddUint32(SB)
-
-TEXT ·AddUint32(SB),NOSPLIT,$0
-	B ·armAddUint32(SB)
-
-TEXT ·AddUintptr(SB),NOSPLIT,$0
-	B ·AddUint32(SB)
-
-TEXT ·SwapInt32(SB),NOSPLIT,$0
-	B ·SwapUint32(SB)
-
-TEXT ·SwapUint32(SB),NOSPLIT,$0
-	B ·armSwapUint32(SB)
-
-TEXT ·SwapUintptr(SB),NOSPLIT,$0
-	B ·SwapUint32(SB)
-
-TEXT ·SwapPointer(SB),NOSPLIT,$0
-	B ·SwapUint32(SB)
-
-TEXT ·CompareAndSwapInt64(SB),NOSPLIT,$0
-	B ·CompareAndSwapUint64(SB)
-
-TEXT ·CompareAndSwapUint64(SB),NOSPLIT,$-4
-	B ·armCompareAndSwapUint64(SB)
-
-TEXT ·AddInt64(SB),NOSPLIT,$0
-	B ·addUint64(SB)
-
-TEXT ·AddUint64(SB),NOSPLIT,$0
-	B ·addUint64(SB)
-
-TEXT ·SwapInt64(SB),NOSPLIT,$0
-	B ·swapUint64(SB)
-
-TEXT ·SwapUint64(SB),NOSPLIT,$0
-	B ·swapUint64(SB)
-
-TEXT ·LoadInt32(SB),NOSPLIT,$0
-	B ·LoadUint32(SB)
-
-TEXT ·LoadUint32(SB),NOSPLIT,$0-8
-	MOVW addr+0(FP), R1
-load32loop:
-	LDREX (R1), R2		// loads R2
-	STREX R2, (R1), R0	// stores R2
-	CMP $0, R0
-	BNE load32loop
-	MOVW R2, val+4(FP)
-	RET
-
-TEXT ·LoadInt64(SB),NOSPLIT,$0
-	B ·loadUint64(SB)
-
-TEXT ·LoadUint64(SB),NOSPLIT,$0
-	B ·loadUint64(SB)
-
-TEXT ·LoadUintptr(SB),NOSPLIT,$0
-	B ·LoadUint32(SB)
-
-TEXT ·LoadPointer(SB),NOSPLIT,$0
-	B ·LoadUint32(SB)
-
-TEXT ·StoreInt32(SB),NOSPLIT,$0
-	B ·StoreUint32(SB)
-
-TEXT ·StoreUint32(SB),NOSPLIT,$0-8
-	MOVW addr+0(FP), R1
-	MOVW val+4(FP), R2
-storeloop:
-	LDREX (R1), R4		// loads R4
-	STREX R2, (R1), R0	// stores R2
-	CMP $0, R0
-	BNE storeloop
-	RET
-
-TEXT ·StoreInt64(SB),NOSPLIT,$0
-	B ·storeUint64(SB)
-
-TEXT ·StoreUint64(SB),NOSPLIT,$0
-	B ·storeUint64(SB)
-
-TEXT ·StoreUintptr(SB),NOSPLIT,$0
-	B ·StoreUint32(SB)
-
-TEXT ·StorePointer(SB),NOSPLIT,$0
-	B ·StoreUint32(SB)
diff --git a/src/pkg/sync/atomic/atomic_test.go b/src/pkg/sync/atomic/atomic_test.go
deleted file mode 100644
index a5f44f7..0000000
--- a/src/pkg/sync/atomic/atomic_test.go
+++ /dev/null
@@ -1,1509 +0,0 @@
-// Copyright 2011 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package atomic_test
-
-import (
-	"fmt"
-	"runtime"
-	"strings"
-	. "sync/atomic"
-	"testing"
-	"unsafe"
-)
-
-// Tests of correct behavior, without contention.
-// (Does the function work as advertised?)
-//
-// Test that the Add functions add correctly.
-// Test that the CompareAndSwap functions actually
-// do the comparison and the swap correctly.
-//
-// The loop over power-of-two values is meant to
-// ensure that the operations apply to the full word size.
-// The struct fields x.before and x.after check that the
-// operations do not extend past the full word size.
-
-const (
-	magic32 = 0xdedbeef
-	magic64 = 0xdeddeadbeefbeef
-)
-
-// Do the 64-bit functions panic?  If so, don't bother testing.
-var test64err = func() (err interface{}) {
-	defer func() {
-		err = recover()
-	}()
-	var x int64
-	AddInt64(&x, 1)
-	return nil
-}()
-
-func TestSwapInt32(t *testing.T) {
-	var x struct {
-		before int32
-		i      int32
-		after  int32
-	}
-	x.before = magic32
-	x.after = magic32
-	var j int32
-	for delta := int32(1); delta+delta > delta; delta += delta {
-		k := SwapInt32(&x.i, delta)
-		if x.i != delta || k != j {
-			t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i, j, k)
-		}
-		j = delta
-	}
-	if x.before != magic32 || x.after != magic32 {
-		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32)
-	}
-}
-
-func TestSwapUint32(t *testing.T) {
-	var x struct {
-		before uint32
-		i      uint32
-		after  uint32
-	}
-	x.before = magic32
-	x.after = magic32
-	var j uint32
-	for delta := uint32(1); delta+delta > delta; delta += delta {
-		k := SwapUint32(&x.i, delta)
-		if x.i != delta || k != j {
-			t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i, j, k)
-		}
-		j = delta
-	}
-	if x.before != magic32 || x.after != magic32 {
-		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32)
-	}
-}
-
-func TestSwapInt64(t *testing.T) {
-	if test64err != nil {
-		t.Skipf("Skipping 64-bit tests: %v", test64err)
-	}
-	var x struct {
-		before int64
-		i      int64
-		after  int64
-	}
-	x.before = magic64
-	x.after = magic64
-	var j int64
-	for delta := int64(1); delta+delta > delta; delta += delta {
-		k := SwapInt64(&x.i, delta)
-		if x.i != delta || k != j {
-			t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i, j, k)
-		}
-		j = delta
-	}
-	if x.before != magic64 || x.after != magic64 {
-		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, uint64(magic64), uint64(magic64))
-	}
-}
-
-func TestSwapUint64(t *testing.T) {
-	if test64err != nil {
-		t.Skipf("Skipping 64-bit tests: %v", test64err)
-	}
-	var x struct {
-		before uint64
-		i      uint64
-		after  uint64
-	}
-	x.before = magic64
-	x.after = magic64
-	var j uint64
-	for delta := uint64(1); delta+delta > delta; delta += delta {
-		k := SwapUint64(&x.i, delta)
-		if x.i != delta || k != j {
-			t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i, j, k)
-		}
-		j = delta
-	}
-	if x.before != magic64 || x.after != magic64 {
-		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, uint64(magic64), uint64(magic64))
-	}
-}
-
-func TestSwapUintptr(t *testing.T) {
-	var x struct {
-		before uintptr
-		i      uintptr
-		after  uintptr
-	}
-	var m uint64 = magic64
-	magicptr := uintptr(m)
-	x.before = magicptr
-	x.after = magicptr
-	var j uintptr
-	for delta := uintptr(1); delta+delta > delta; delta += delta {
-		k := SwapUintptr(&x.i, delta)
-		if x.i != delta || k != j {
-			t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i, j, k)
-		}
-		j = delta
-	}
-	if x.before != magicptr || x.after != magicptr {
-		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magicptr, magicptr)
-	}
-}
-
-func TestSwapPointer(t *testing.T) {
-	var x struct {
-		before uintptr
-		i      unsafe.Pointer
-		after  uintptr
-	}
-	var m uint64 = magic64
-	magicptr := uintptr(m)
-	x.before = magicptr
-	x.after = magicptr
-	var j uintptr
-	for delta := uintptr(1); delta+delta > delta; delta += delta {
-		k := SwapPointer(&x.i, unsafe.Pointer(delta))
-		if uintptr(x.i) != delta || uintptr(k) != j {
-			t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i, j, k)
-		}
-		j = delta
-	}
-	if x.before != magicptr || x.after != magicptr {
-		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magicptr, magicptr)
-	}
-}
-
-func TestAddInt32(t *testing.T) {
-	var x struct {
-		before int32
-		i      int32
-		after  int32
-	}
-	x.before = magic32
-	x.after = magic32
-	var j int32
-	for delta := int32(1); delta+delta > delta; delta += delta {
-		k := AddInt32(&x.i, delta)
-		j += delta
-		if x.i != j || k != j {
-			t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i, j, k)
-		}
-	}
-	if x.before != magic32 || x.after != magic32 {
-		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32)
-	}
-}
-
-func TestAddUint32(t *testing.T) {
-	var x struct {
-		before uint32
-		i      uint32
-		after  uint32
-	}
-	x.before = magic32
-	x.after = magic32
-	var j uint32
-	for delta := uint32(1); delta+delta > delta; delta += delta {
-		k := AddUint32(&x.i, delta)
-		j += delta
-		if x.i != j || k != j {
-			t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i, j, k)
-		}
-	}
-	if x.before != magic32 || x.after != magic32 {
-		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32)
-	}
-}
-
-func TestAddInt64(t *testing.T) {
-	if test64err != nil {
-		t.Skipf("Skipping 64-bit tests: %v", test64err)
-	}
-	var x struct {
-		before int64
-		i      int64
-		after  int64
-	}
-	x.before = magic64
-	x.after = magic64
-	var j int64
-	for delta := int64(1); delta+delta > delta; delta += delta {
-		k := AddInt64(&x.i, delta)
-		j += delta
-		if x.i != j || k != j {
-			t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i, j, k)
-		}
-	}
-	if x.before != magic64 || x.after != magic64 {
-		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, int64(magic64), int64(magic64))
-	}
-}
-
-func TestAddUint64(t *testing.T) {
-	if test64err != nil {
-		t.Skipf("Skipping 64-bit tests: %v", test64err)
-	}
-	var x struct {
-		before uint64
-		i      uint64
-		after  uint64
-	}
-	x.before = magic64
-	x.after = magic64
-	var j uint64
-	for delta := uint64(1); delta+delta > delta; delta += delta {
-		k := AddUint64(&x.i, delta)
-		j += delta
-		if x.i != j || k != j {
-			t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i, j, k)
-		}
-	}
-	if x.before != magic64 || x.after != magic64 {
-		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, uint64(magic64), uint64(magic64))
-	}
-}
-
-func TestAddUintptr(t *testing.T) {
-	var x struct {
-		before uintptr
-		i      uintptr
-		after  uintptr
-	}
-	var m uint64 = magic64
-	magicptr := uintptr(m)
-	x.before = magicptr
-	x.after = magicptr
-	var j uintptr
-	for delta := uintptr(1); delta+delta > delta; delta += delta {
-		k := AddUintptr(&x.i, delta)
-		j += delta
-		if x.i != j || k != j {
-			t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i, j, k)
-		}
-	}
-	if x.before != magicptr || x.after != magicptr {
-		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magicptr, magicptr)
-	}
-}
-
-func TestCompareAndSwapInt32(t *testing.T) {
-	var x struct {
-		before int32
-		i      int32
-		after  int32
-	}
-	x.before = magic32
-	x.after = magic32
-	for val := int32(1); val+val > val; val += val {
-		x.i = val
-		if !CompareAndSwapInt32(&x.i, val, val+1) {
-			t.Fatalf("should have swapped %#x %#x", val, val+1)
-		}
-		if x.i != val+1 {
-			t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i, val+1)
-		}
-		x.i = val + 1
-		if CompareAndSwapInt32(&x.i, val, val+2) {
-			t.Fatalf("should not have swapped %#x %#x", val, val+2)
-		}
-		if x.i != val+1 {
-			t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i, val+1)
-		}
-	}
-	if x.before != magic32 || x.after != magic32 {
-		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32)
-	}
-}
-
-func TestCompareAndSwapUint32(t *testing.T) {
-	var x struct {
-		before uint32
-		i      uint32
-		after  uint32
-	}
-	x.before = magic32
-	x.after = magic32
-	for val := uint32(1); val+val > val; val += val {
-		x.i = val
-		if !CompareAndSwapUint32(&x.i, val, val+1) {
-			t.Fatalf("should have swapped %#x %#x", val, val+1)
-		}
-		if x.i != val+1 {
-			t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i, val+1)
-		}
-		x.i = val + 1
-		if CompareAndSwapUint32(&x.i, val, val+2) {
-			t.Fatalf("should not have swapped %#x %#x", val, val+2)
-		}
-		if x.i != val+1 {
-			t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i, val+1)
-		}
-	}
-	if x.before != magic32 || x.after != magic32 {
-		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32)
-	}
-}
-
-func TestCompareAndSwapInt64(t *testing.T) {
-	if test64err != nil {
-		t.Skipf("Skipping 64-bit tests: %v", test64err)
-	}
-	var x struct {
-		before int64
-		i      int64
-		after  int64
-	}
-	x.before = magic64
-	x.after = magic64
-	for val := int64(1); val+val > val; val += val {
-		x.i = val
-		if !CompareAndSwapInt64(&x.i, val, val+1) {
-			t.Fatalf("should have swapped %#x %#x", val, val+1)
-		}
-		if x.i != val+1 {
-			t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i, val+1)
-		}
-		x.i = val + 1
-		if CompareAndSwapInt64(&x.i, val, val+2) {
-			t.Fatalf("should not have swapped %#x %#x", val, val+2)
-		}
-		if x.i != val+1 {
-			t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i, val+1)
-		}
-	}
-	if x.before != magic64 || x.after != magic64 {
-		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, uint64(magic64), uint64(magic64))
-	}
-}
-
-func testCompareAndSwapUint64(t *testing.T, cas func(*uint64, uint64, uint64) bool) {
-	if test64err != nil {
-		t.Skipf("Skipping 64-bit tests: %v", test64err)
-	}
-	var x struct {
-		before uint64
-		i      uint64
-		after  uint64
-	}
-	x.before = magic64
-	x.after = magic64
-	for val := uint64(1); val+val > val; val += val {
-		x.i = val
-		if !cas(&x.i, val, val+1) {
-			t.Fatalf("should have swapped %#x %#x", val, val+1)
-		}
-		if x.i != val+1 {
-			t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i, val+1)
-		}
-		x.i = val + 1
-		if cas(&x.i, val, val+2) {
-			t.Fatalf("should not have swapped %#x %#x", val, val+2)
-		}
-		if x.i != val+1 {
-			t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i, val+1)
-		}
-	}
-	if x.before != magic64 || x.after != magic64 {
-		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, uint64(magic64), uint64(magic64))
-	}
-}
-
-func TestCompareAndSwapUint64(t *testing.T) {
-	testCompareAndSwapUint64(t, CompareAndSwapUint64)
-}
-
-func TestCompareAndSwapUintptr(t *testing.T) {
-	var x struct {
-		before uintptr
-		i      uintptr
-		after  uintptr
-	}
-	var m uint64 = magic64
-	magicptr := uintptr(m)
-	x.before = magicptr
-	x.after = magicptr
-	for val := uintptr(1); val+val > val; val += val {
-		x.i = val
-		if !CompareAndSwapUintptr(&x.i, val, val+1) {
-			t.Fatalf("should have swapped %#x %#x", val, val+1)
-		}
-		if x.i != val+1 {
-			t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i, val+1)
-		}
-		x.i = val + 1
-		if CompareAndSwapUintptr(&x.i, val, val+2) {
-			t.Fatalf("should not have swapped %#x %#x", val, val+2)
-		}
-		if x.i != val+1 {
-			t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i, val+1)
-		}
-	}
-	if x.before != magicptr || x.after != magicptr {
-		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magicptr, magicptr)
-	}
-}
-
-func TestCompareAndSwapPointer(t *testing.T) {
-	var x struct {
-		before uintptr
-		i      unsafe.Pointer
-		after  uintptr
-	}
-	var m uint64 = magic64
-	magicptr := uintptr(m)
-	x.before = magicptr
-	x.after = magicptr
-	for val := uintptr(1); val+val > val; val += val {
-		x.i = unsafe.Pointer(val)
-		if !CompareAndSwapPointer(&x.i, unsafe.Pointer(val), unsafe.Pointer(val+1)) {
-			t.Fatalf("should have swapped %#x %#x", val, val+1)
-		}
-		if x.i != unsafe.Pointer(val+1) {
-			t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i, val+1)
-		}
-		x.i = unsafe.Pointer(val + 1)
-		if CompareAndSwapPointer(&x.i, unsafe.Pointer(val), unsafe.Pointer(val+2)) {
-			t.Fatalf("should not have swapped %#x %#x", val, val+2)
-		}
-		if x.i != unsafe.Pointer(val+1) {
-			t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i, val+1)
-		}
-	}
-	if x.before != magicptr || x.after != magicptr {
-		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magicptr, magicptr)
-	}
-}
-
-func TestLoadInt32(t *testing.T) {
-	var x struct {
-		before int32
-		i      int32
-		after  int32
-	}
-	x.before = magic32
-	x.after = magic32
-	for delta := int32(1); delta+delta > delta; delta += delta {
-		k := LoadInt32(&x.i)
-		if k != x.i {
-			t.Fatalf("delta=%d i=%d k=%d", delta, x.i, k)
-		}
-		x.i += delta
-	}
-	if x.before != magic32 || x.after != magic32 {
-		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32)
-	}
-}
-
-func TestLoadUint32(t *testing.T) {
-	var x struct {
-		before uint32
-		i      uint32
-		after  uint32
-	}
-	x.before = magic32
-	x.after = magic32
-	for delta := uint32(1); delta+delta > delta; delta += delta {
-		k := LoadUint32(&x.i)
-		if k != x.i {
-			t.Fatalf("delta=%d i=%d k=%d", delta, x.i, k)
-		}
-		x.i += delta
-	}
-	if x.before != magic32 || x.after != magic32 {
-		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32)
-	}
-}
-
-func TestLoadInt64(t *testing.T) {
-	if test64err != nil {
-		t.Skipf("Skipping 64-bit tests: %v", test64err)
-	}
-	var x struct {
-		before int64
-		i      int64
-		after  int64
-	}
-	x.before = magic64
-	x.after = magic64
-	for delta := int64(1); delta+delta > delta; delta += delta {
-		k := LoadInt64(&x.i)
-		if k != x.i {
-			t.Fatalf("delta=%d i=%d k=%d", delta, x.i, k)
-		}
-		x.i += delta
-	}
-	if x.before != magic64 || x.after != magic64 {
-		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, uint64(magic64), uint64(magic64))
-	}
-}
-
-func TestLoadUint64(t *testing.T) {
-	if test64err != nil {
-		t.Skipf("Skipping 64-bit tests: %v", test64err)
-	}
-	var x struct {
-		before uint64
-		i      uint64
-		after  uint64
-	}
-	x.before = magic64
-	x.after = magic64
-	for delta := uint64(1); delta+delta > delta; delta += delta {
-		k := LoadUint64(&x.i)
-		if k != x.i {
-			t.Fatalf("delta=%d i=%d k=%d", delta, x.i, k)
-		}
-		x.i += delta
-	}
-	if x.before != magic64 || x.after != magic64 {
-		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, uint64(magic64), uint64(magic64))
-	}
-}
-
-func TestLoadUintptr(t *testing.T) {
-	var x struct {
-		before uintptr
-		i      uintptr
-		after  uintptr
-	}
-	var m uint64 = magic64
-	magicptr := uintptr(m)
-	x.before = magicptr
-	x.after = magicptr
-	for delta := uintptr(1); delta+delta > delta; delta += delta {
-		k := LoadUintptr(&x.i)
-		if k != x.i {
-			t.Fatalf("delta=%d i=%d k=%d", delta, x.i, k)
-		}
-		x.i += delta
-	}
-	if x.before != magicptr || x.after != magicptr {
-		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magicptr, magicptr)
-	}
-}
-
-func TestLoadPointer(t *testing.T) {
-	var x struct {
-		before uintptr
-		i      unsafe.Pointer
-		after  uintptr
-	}
-	var m uint64 = magic64
-	magicptr := uintptr(m)
-	x.before = magicptr
-	x.after = magicptr
-	for delta := uintptr(1); delta+delta > delta; delta += delta {
-		k := LoadPointer(&x.i)
-		if k != x.i {
-			t.Fatalf("delta=%d i=%d k=%d", delta, x.i, k)
-		}
-		x.i = unsafe.Pointer(uintptr(x.i) + delta)
-	}
-	if x.before != magicptr || x.after != magicptr {
-		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magicptr, magicptr)
-	}
-}
-
-func TestStoreInt32(t *testing.T) {
-	var x struct {
-		before int32
-		i      int32
-		after  int32
-	}
-	x.before = magic32
-	x.after = magic32
-	v := int32(0)
-	for delta := int32(1); delta+delta > delta; delta += delta {
-		StoreInt32(&x.i, v)
-		if x.i != v {
-			t.Fatalf("delta=%d i=%d v=%d", delta, x.i, v)
-		}
-		v += delta
-	}
-	if x.before != magic32 || x.after != magic32 {
-		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32)
-	}
-}
-
-func TestStoreUint32(t *testing.T) {
-	var x struct {
-		before uint32
-		i      uint32
-		after  uint32
-	}
-	x.before = magic32
-	x.after = magic32
-	v := uint32(0)
-	for delta := uint32(1); delta+delta > delta; delta += delta {
-		StoreUint32(&x.i, v)
-		if x.i != v {
-			t.Fatalf("delta=%d i=%d v=%d", delta, x.i, v)
-		}
-		v += delta
-	}
-	if x.before != magic32 || x.after != magic32 {
-		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32)
-	}
-}
-
-func TestStoreInt64(t *testing.T) {
-	if test64err != nil {
-		t.Skipf("Skipping 64-bit tests: %v", test64err)
-	}
-	var x struct {
-		before int64
-		i      int64
-		after  int64
-	}
-	x.before = magic64
-	x.after = magic64
-	v := int64(0)
-	for delta := int64(1); delta+delta > delta; delta += delta {
-		StoreInt64(&x.i, v)
-		if x.i != v {
-			t.Fatalf("delta=%d i=%d v=%d", delta, x.i, v)
-		}
-		v += delta
-	}
-	if x.before != magic64 || x.after != magic64 {
-		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, uint64(magic64), uint64(magic64))
-	}
-}
-
-func TestStoreUint64(t *testing.T) {
-	if test64err != nil {
-		t.Skipf("Skipping 64-bit tests: %v", test64err)
-	}
-	var x struct {
-		before uint64
-		i      uint64
-		after  uint64
-	}
-	x.before = magic64
-	x.after = magic64
-	v := uint64(0)
-	for delta := uint64(1); delta+delta > delta; delta += delta {
-		StoreUint64(&x.i, v)
-		if x.i != v {
-			t.Fatalf("delta=%d i=%d v=%d", delta, x.i, v)
-		}
-		v += delta
-	}
-	if x.before != magic64 || x.after != magic64 {
-		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, uint64(magic64), uint64(magic64))
-	}
-}
-
-func TestStoreUintptr(t *testing.T) {
-	var x struct {
-		before uintptr
-		i      uintptr
-		after  uintptr
-	}
-	var m uint64 = magic64
-	magicptr := uintptr(m)
-	x.before = magicptr
-	x.after = magicptr
-	v := uintptr(0)
-	for delta := uintptr(1); delta+delta > delta; delta += delta {
-		StoreUintptr(&x.i, v)
-		if x.i != v {
-			t.Fatalf("delta=%d i=%d v=%d", delta, x.i, v)
-		}
-		v += delta
-	}
-	if x.before != magicptr || x.after != magicptr {
-		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magicptr, magicptr)
-	}
-}
-
-func TestStorePointer(t *testing.T) {
-	var x struct {
-		before uintptr
-		i      unsafe.Pointer
-		after  uintptr
-	}
-	var m uint64 = magic64
-	magicptr := uintptr(m)
-	x.before = magicptr
-	x.after = magicptr
-	v := unsafe.Pointer(uintptr(0))
-	for delta := uintptr(1); delta+delta > delta; delta += delta {
-		StorePointer(&x.i, unsafe.Pointer(v))
-		if x.i != v {
-			t.Fatalf("delta=%d i=%d v=%d", delta, x.i, v)
-		}
-		v = unsafe.Pointer(uintptr(v) + delta)
-	}
-	if x.before != magicptr || x.after != magicptr {
-		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magicptr, magicptr)
-	}
-}
-
-// Tests of correct behavior, with contention.
-// (Is the function atomic?)
-//
-// For each function, we write a "hammer" function that repeatedly
-// uses the atomic operation to add 1 to a value.  After running
-// multiple hammers in parallel, check that we end with the correct
-// total.
-// Swap can't add 1, so it uses a different scheme.
-// The functions repeatedly generate a pseudo-random number such that
-// low bits are equal to high bits, swap, check that the old value
-// has low and high bits equal.
-
-var hammer32 = map[string]func(*uint32, int){
-	"SwapInt32":             hammerSwapInt32,
-	"SwapUint32":            hammerSwapUint32,
-	"SwapUintptr":           hammerSwapUintptr32,
-	"SwapPointer":           hammerSwapPointer32,
-	"AddInt32":              hammerAddInt32,
-	"AddUint32":             hammerAddUint32,
-	"AddUintptr":            hammerAddUintptr32,
-	"CompareAndSwapInt32":   hammerCompareAndSwapInt32,
-	"CompareAndSwapUint32":  hammerCompareAndSwapUint32,
-	"CompareAndSwapUintptr": hammerCompareAndSwapUintptr32,
-	"CompareAndSwapPointer": hammerCompareAndSwapPointer32,
-}
-
-func init() {
-	var v uint64 = 1 << 50
-	if uintptr(v) != 0 {
-		// 64-bit system; clear uintptr tests
-		delete(hammer32, "SwapUintptr")
-		delete(hammer32, "SwapPointer")
-		delete(hammer32, "AddUintptr")
-		delete(hammer32, "CompareAndSwapUintptr")
-		delete(hammer32, "CompareAndSwapPointer")
-	}
-}
-
-func hammerSwapInt32(uaddr *uint32, count int) {
-	addr := (*int32)(unsafe.Pointer(uaddr))
-	seed := int(uintptr(unsafe.Pointer(&count)))
-	for i := 0; i < count; i++ {
-		new := uint32(seed+i)<<16 | uint32(seed+i)<<16>>16
-		old := uint32(SwapInt32(addr, int32(new)))
-		if old>>16 != old<<16>>16 {
-			panic(fmt.Sprintf("SwapInt32 is not atomic: %v", old))
-		}
-	}
-}
-
-func hammerSwapUint32(addr *uint32, count int) {
-	seed := int(uintptr(unsafe.Pointer(&count)))
-	for i := 0; i < count; i++ {
-		new := uint32(seed+i)<<16 | uint32(seed+i)<<16>>16
-		old := SwapUint32(addr, new)
-		if old>>16 != old<<16>>16 {
-			panic(fmt.Sprintf("SwapUint32 is not atomic: %v", old))
-		}
-	}
-}
-
-func hammerSwapUintptr32(uaddr *uint32, count int) {
-	// only safe when uintptr is 32-bit.
-	// not called on 64-bit systems.
-	addr := (*uintptr)(unsafe.Pointer(uaddr))
-	seed := int(uintptr(unsafe.Pointer(&count)))
-	for i := 0; i < count; i++ {
-		new := uintptr(seed+i)<<16 | uintptr(seed+i)<<16>>16
-		old := SwapUintptr(addr, new)
-		if old>>16 != old<<16>>16 {
-			panic(fmt.Sprintf("SwapUintptr is not atomic: %#08x", old))
-		}
-	}
-}
-
-func hammerSwapPointer32(uaddr *uint32, count int) {
-	// only safe when uintptr is 32-bit.
-	// not called on 64-bit systems.
-	addr := (*unsafe.Pointer)(unsafe.Pointer(uaddr))
-	seed := int(uintptr(unsafe.Pointer(&count)))
-	for i := 0; i < count; i++ {
-		new := uintptr(seed+i)<<16 | uintptr(seed+i)<<16>>16
-		old := uintptr(SwapPointer(addr, unsafe.Pointer(new)))
-		if old>>16 != old<<16>>16 {
-			panic(fmt.Sprintf("SwapPointer is not atomic: %#08x", old))
-		}
-	}
-}
-
-func hammerAddInt32(uaddr *uint32, count int) {
-	addr := (*int32)(unsafe.Pointer(uaddr))
-	for i := 0; i < count; i++ {
-		AddInt32(addr, 1)
-	}
-}
-
-func hammerAddUint32(addr *uint32, count int) {
-	for i := 0; i < count; i++ {
-		AddUint32(addr, 1)
-	}
-}
-
-func hammerAddUintptr32(uaddr *uint32, count int) {
-	// only safe when uintptr is 32-bit.
-	// not called on 64-bit systems.
-	addr := (*uintptr)(unsafe.Pointer(uaddr))
-	for i := 0; i < count; i++ {
-		AddUintptr(addr, 1)
-	}
-}
-
-func hammerCompareAndSwapInt32(uaddr *uint32, count int) {
-	addr := (*int32)(unsafe.Pointer(uaddr))
-	for i := 0; i < count; i++ {
-		for {
-			v := *addr
-			if CompareAndSwapInt32(addr, v, v+1) {
-				break
-			}
-		}
-	}
-}
-
-func hammerCompareAndSwapUint32(addr *uint32, count int) {
-	for i := 0; i < count; i++ {
-		for {
-			v := *addr
-			if CompareAndSwapUint32(addr, v, v+1) {
-				break
-			}
-		}
-	}
-}
-
-func hammerCompareAndSwapUintptr32(uaddr *uint32, count int) {
-	// only safe when uintptr is 32-bit.
-	// not called on 64-bit systems.
-	addr := (*uintptr)(unsafe.Pointer(uaddr))
-	for i := 0; i < count; i++ {
-		for {
-			v := *addr
-			if CompareAndSwapUintptr(addr, v, v+1) {
-				break
-			}
-		}
-	}
-}
-
-func hammerCompareAndSwapPointer32(uaddr *uint32, count int) {
-	// only safe when uintptr is 32-bit.
-	// not called on 64-bit systems.
-	addr := (*unsafe.Pointer)(unsafe.Pointer(uaddr))
-	for i := 0; i < count; i++ {
-		for {
-			v := *addr
-			if CompareAndSwapPointer(addr, v, unsafe.Pointer(uintptr(v)+1)) {
-				break
-			}
-		}
-	}
-}
-
-func TestHammer32(t *testing.T) {
-	const p = 4
-	n := 100000
-	if testing.Short() {
-		n = 1000
-	}
-	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(p))
-
-	for name, testf := range hammer32 {
-		c := make(chan int)
-		var val uint32
-		for i := 0; i < p; i++ {
-			go func() {
-				defer func() {
-					if err := recover(); err != nil {
-						t.Error(err.(string))
-					}
-					c <- 1
-				}()
-				testf(&val, n)
-			}()
-		}
-		for i := 0; i < p; i++ {
-			<-c
-		}
-		if !strings.HasPrefix(name, "Swap") && val != uint32(n)*p {
-			t.Fatalf("%s: val=%d want %d", name, val, n*p)
-		}
-	}
-}
-
-var hammer64 = map[string]func(*uint64, int){
-	"SwapInt64":             hammerSwapInt64,
-	"SwapUint64":            hammerSwapUint64,
-	"SwapUintptr":           hammerSwapUintptr64,
-	"SwapPointer":           hammerSwapPointer64,
-	"AddInt64":              hammerAddInt64,
-	"AddUint64":             hammerAddUint64,
-	"AddUintptr":            hammerAddUintptr64,
-	"CompareAndSwapInt64":   hammerCompareAndSwapInt64,
-	"CompareAndSwapUint64":  hammerCompareAndSwapUint64,
-	"CompareAndSwapUintptr": hammerCompareAndSwapUintptr64,
-	"CompareAndSwapPointer": hammerCompareAndSwapPointer64,
-}
-
-func init() {
-	var v uint64 = 1 << 50
-	if uintptr(v) == 0 {
-		// 32-bit system; clear uintptr tests
-		delete(hammer64, "SwapUintptr")
-		delete(hammer64, "SwapPointer")
-		delete(hammer64, "AddUintptr")
-		delete(hammer64, "CompareAndSwapUintptr")
-		delete(hammer64, "CompareAndSwapPointer")
-	}
-}
-
-func hammerSwapInt64(uaddr *uint64, count int) {
-	addr := (*int64)(unsafe.Pointer(uaddr))
-	seed := int(uintptr(unsafe.Pointer(&count)))
-	for i := 0; i < count; i++ {
-		new := uint64(seed+i)<<32 | uint64(seed+i)<<32>>32
-		old := uint64(SwapInt64(addr, int64(new)))
-		if old>>32 != old<<32>>32 {
-			panic(fmt.Sprintf("SwapInt64 is not atomic: %v", old))
-		}
-	}
-}
-
-func hammerSwapUint64(addr *uint64, count int) {
-	seed := int(uintptr(unsafe.Pointer(&count)))
-	for i := 0; i < count; i++ {
-		new := uint64(seed+i)<<32 | uint64(seed+i)<<32>>32
-		old := SwapUint64(addr, new)
-		if old>>32 != old<<32>>32 {
-			panic(fmt.Sprintf("SwapUint64 is not atomic: %v", old))
-		}
-	}
-}
-
-func hammerSwapUintptr64(uaddr *uint64, count int) {
-	// only safe when uintptr is 64-bit.
-	// not called on 32-bit systems.
-	addr := (*uintptr)(unsafe.Pointer(uaddr))
-	seed := int(uintptr(unsafe.Pointer(&count)))
-	for i := 0; i < count; i++ {
-		new := uintptr(seed+i)<<32 | uintptr(seed+i)<<32>>32
-		old := SwapUintptr(addr, new)
-		if old>>32 != old<<32>>32 {
-			panic(fmt.Sprintf("SwapUintptr is not atomic: %v", old))
-		}
-	}
-}
-
-func hammerSwapPointer64(uaddr *uint64, count int) {
-	// only safe when uintptr is 64-bit.
-	// not called on 32-bit systems.
-	addr := (*unsafe.Pointer)(unsafe.Pointer(uaddr))
-	seed := int(uintptr(unsafe.Pointer(&count)))
-	for i := 0; i < count; i++ {
-		new := uintptr(seed+i)<<32 | uintptr(seed+i)<<32>>32
-		old := uintptr(SwapPointer(addr, unsafe.Pointer(new)))
-		if old>>32 != old<<32>>32 {
-			panic(fmt.Sprintf("SwapPointer is not atomic: %v", old))
-		}
-	}
-}
-
-func hammerAddInt64(uaddr *uint64, count int) {
-	addr := (*int64)(unsafe.Pointer(uaddr))
-	for i := 0; i < count; i++ {
-		AddInt64(addr, 1)
-	}
-}
-
-func hammerAddUint64(addr *uint64, count int) {
-	for i := 0; i < count; i++ {
-		AddUint64(addr, 1)
-	}
-}
-
-func hammerAddUintptr64(uaddr *uint64, count int) {
-	// only safe when uintptr is 64-bit.
-	// not called on 32-bit systems.
-	addr := (*uintptr)(unsafe.Pointer(uaddr))
-	for i := 0; i < count; i++ {
-		AddUintptr(addr, 1)
-	}
-}
-
-func hammerCompareAndSwapInt64(uaddr *uint64, count int) {
-	addr := (*int64)(unsafe.Pointer(uaddr))
-	for i := 0; i < count; i++ {
-		for {
-			v := *addr
-			if CompareAndSwapInt64(addr, v, v+1) {
-				break
-			}
-		}
-	}
-}
-
-func hammerCompareAndSwapUint64(addr *uint64, count int) {
-	for i := 0; i < count; i++ {
-		for {
-			v := *addr
-			if CompareAndSwapUint64(addr, v, v+1) {
-				break
-			}
-		}
-	}
-}
-
-func hammerCompareAndSwapUintptr64(uaddr *uint64, count int) {
-	// only safe when uintptr is 64-bit.
-	// not called on 32-bit systems.
-	addr := (*uintptr)(unsafe.Pointer(uaddr))
-	for i := 0; i < count; i++ {
-		for {
-			v := *addr
-			if CompareAndSwapUintptr(addr, v, v+1) {
-				break
-			}
-		}
-	}
-}
-
-func hammerCompareAndSwapPointer64(uaddr *uint64, count int) {
-	// only safe when uintptr is 64-bit.
-	// not called on 32-bit systems.
-	addr := (*unsafe.Pointer)(unsafe.Pointer(uaddr))
-	for i := 0; i < count; i++ {
-		for {
-			v := *addr
-			if CompareAndSwapPointer(addr, v, unsafe.Pointer(uintptr(v)+1)) {
-				break
-			}
-		}
-	}
-}
-
-func TestHammer64(t *testing.T) {
-	if test64err != nil {
-		t.Skipf("Skipping 64-bit tests: %v", test64err)
-	}
-	const p = 4
-	n := 100000
-	if testing.Short() {
-		n = 1000
-	}
-	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(p))
-
-	for name, testf := range hammer64 {
-		c := make(chan int)
-		var val uint64
-		for i := 0; i < p; i++ {
-			go func() {
-				defer func() {
-					if err := recover(); err != nil {
-						t.Error(err.(string))
-					}
-					c <- 1
-				}()
-				testf(&val, n)
-			}()
-		}
-		for i := 0; i < p; i++ {
-			<-c
-		}
-		if !strings.HasPrefix(name, "Swap") && val != uint64(n)*p {
-			t.Fatalf("%s: val=%d want %d", name, val, n*p)
-		}
-	}
-}
-
-func hammerStoreLoadInt32(t *testing.T, paddr unsafe.Pointer) {
-	addr := (*int32)(paddr)
-	v := LoadInt32(addr)
-	vlo := v & ((1 << 16) - 1)
-	vhi := v >> 16
-	if vlo != vhi {
-		t.Fatalf("Int32: %#x != %#x", vlo, vhi)
-	}
-	new := v + 1 + 1<<16
-	if vlo == 1e4 {
-		new = 0
-	}
-	StoreInt32(addr, new)
-}
-
-func hammerStoreLoadUint32(t *testing.T, paddr unsafe.Pointer) {
-	addr := (*uint32)(paddr)
-	v := LoadUint32(addr)
-	vlo := v & ((1 << 16) - 1)
-	vhi := v >> 16
-	if vlo != vhi {
-		t.Fatalf("Uint32: %#x != %#x", vlo, vhi)
-	}
-	new := v + 1 + 1<<16
-	if vlo == 1e4 {
-		new = 0
-	}
-	StoreUint32(addr, new)
-}
-
-func hammerStoreLoadInt64(t *testing.T, paddr unsafe.Pointer) {
-	addr := (*int64)(paddr)
-	v := LoadInt64(addr)
-	vlo := v & ((1 << 32) - 1)
-	vhi := v >> 32
-	if vlo != vhi {
-		t.Fatalf("Int64: %#x != %#x", vlo, vhi)
-	}
-	new := v + 1 + 1<<32
-	StoreInt64(addr, new)
-}
-
-func hammerStoreLoadUint64(t *testing.T, paddr unsafe.Pointer) {
-	addr := (*uint64)(paddr)
-	v := LoadUint64(addr)
-	vlo := v & ((1 << 32) - 1)
-	vhi := v >> 32
-	if vlo != vhi {
-		t.Fatalf("Uint64: %#x != %#x", vlo, vhi)
-	}
-	new := v + 1 + 1<<32
-	StoreUint64(addr, new)
-}
-
-func hammerStoreLoadUintptr(t *testing.T, paddr unsafe.Pointer) {
-	addr := (*uintptr)(paddr)
-	var test64 uint64 = 1 << 50
-	arch32 := uintptr(test64) == 0
-	v := LoadUintptr(addr)
-	new := v
-	if arch32 {
-		vlo := v & ((1 << 16) - 1)
-		vhi := v >> 16
-		if vlo != vhi {
-			t.Fatalf("Uintptr: %#x != %#x", vlo, vhi)
-		}
-		new = v + 1 + 1<<16
-		if vlo == 1e4 {
-			new = 0
-		}
-	} else {
-		vlo := v & ((1 << 32) - 1)
-		vhi := v >> 32
-		if vlo != vhi {
-			t.Fatalf("Uintptr: %#x != %#x", vlo, vhi)
-		}
-		inc := uint64(1 + 1<<32)
-		new = v + uintptr(inc)
-	}
-	StoreUintptr(addr, new)
-}
-
-func hammerStoreLoadPointer(t *testing.T, paddr unsafe.Pointer) {
-	addr := (*unsafe.Pointer)(paddr)
-	var test64 uint64 = 1 << 50
-	arch32 := uintptr(test64) == 0
-	v := uintptr(LoadPointer(addr))
-	new := v
-	if arch32 {
-		vlo := v & ((1 << 16) - 1)
-		vhi := v >> 16
-		if vlo != vhi {
-			t.Fatalf("Pointer: %#x != %#x", vlo, vhi)
-		}
-		new = v + 1 + 1<<16
-		if vlo == 1e4 {
-			new = 0
-		}
-	} else {
-		vlo := v & ((1 << 32) - 1)
-		vhi := v >> 32
-		if vlo != vhi {
-			t.Fatalf("Pointer: %#x != %#x", vlo, vhi)
-		}
-		inc := uint64(1 + 1<<32)
-		new = v + uintptr(inc)
-	}
-	StorePointer(addr, unsafe.Pointer(new))
-}
-
-func TestHammerStoreLoad(t *testing.T) {
-	var tests []func(*testing.T, unsafe.Pointer)
-	tests = append(tests, hammerStoreLoadInt32, hammerStoreLoadUint32,
-		hammerStoreLoadUintptr, hammerStoreLoadPointer)
-	if test64err == nil {
-		tests = append(tests, hammerStoreLoadInt64, hammerStoreLoadUint64)
-	}
-	n := int(1e6)
-	if testing.Short() {
-		n = int(1e4)
-	}
-	const procs = 8
-	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(procs))
-	for _, tt := range tests {
-		c := make(chan int)
-		var val uint64
-		for p := 0; p < procs; p++ {
-			go func() {
-				for i := 0; i < n; i++ {
-					tt(t, unsafe.Pointer(&val))
-				}
-				c <- 1
-			}()
-		}
-		for p := 0; p < procs; p++ {
-			<-c
-		}
-	}
-}
-
-func TestStoreLoadSeqCst32(t *testing.T) {
-	if runtime.NumCPU() == 1 {
-		t.Skipf("Skipping test on %v processor machine", runtime.NumCPU())
-	}
-	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4))
-	N := int32(1e3)
-	if testing.Short() {
-		N = int32(1e2)
-	}
-	c := make(chan bool, 2)
-	X := [2]int32{}
-	ack := [2][3]int32{{-1, -1, -1}, {-1, -1, -1}}
-	for p := 0; p < 2; p++ {
-		go func(me int) {
-			he := 1 - me
-			for i := int32(1); i < N; i++ {
-				StoreInt32(&X[me], i)
-				my := LoadInt32(&X[he])
-				StoreInt32(&ack[me][i%3], my)
-				for w := 1; LoadInt32(&ack[he][i%3]) == -1; w++ {
-					if w%1000 == 0 {
-						runtime.Gosched()
-					}
-				}
-				his := LoadInt32(&ack[he][i%3])
-				if (my != i && my != i-1) || (his != i && his != i-1) {
-					t.Fatalf("invalid values: %d/%d (%d)", my, his, i)
-				}
-				if my != i && his != i {
-					t.Fatalf("store/load are not sequentially consistent: %d/%d (%d)", my, his, i)
-				}
-				StoreInt32(&ack[me][(i-1)%3], -1)
-			}
-			c <- true
-		}(p)
-	}
-	<-c
-	<-c
-}
-
-func TestStoreLoadSeqCst64(t *testing.T) {
-	if runtime.NumCPU() == 1 {
-		t.Skipf("Skipping test on %v processor machine", runtime.NumCPU())
-	}
-	if test64err != nil {
-		t.Skipf("Skipping 64-bit tests: %v", test64err)
-	}
-	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4))
-	N := int64(1e3)
-	if testing.Short() {
-		N = int64(1e2)
-	}
-	c := make(chan bool, 2)
-	X := [2]int64{}
-	ack := [2][3]int64{{-1, -1, -1}, {-1, -1, -1}}
-	for p := 0; p < 2; p++ {
-		go func(me int) {
-			he := 1 - me
-			for i := int64(1); i < N; i++ {
-				StoreInt64(&X[me], i)
-				my := LoadInt64(&X[he])
-				StoreInt64(&ack[me][i%3], my)
-				for w := 1; LoadInt64(&ack[he][i%3]) == -1; w++ {
-					if w%1000 == 0 {
-						runtime.Gosched()
-					}
-				}
-				his := LoadInt64(&ack[he][i%3])
-				if (my != i && my != i-1) || (his != i && his != i-1) {
-					t.Fatalf("invalid values: %d/%d (%d)", my, his, i)
-				}
-				if my != i && his != i {
-					t.Fatalf("store/load are not sequentially consistent: %d/%d (%d)", my, his, i)
-				}
-				StoreInt64(&ack[me][(i-1)%3], -1)
-			}
-			c <- true
-		}(p)
-	}
-	<-c
-	<-c
-}
-
-func TestStoreLoadRelAcq32(t *testing.T) {
-	if runtime.NumCPU() == 1 {
-		t.Skipf("Skipping test on %v processor machine", runtime.NumCPU())
-	}
-	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4))
-	N := int32(1e3)
-	if testing.Short() {
-		N = int32(1e2)
-	}
-	c := make(chan bool, 2)
-	type Data struct {
-		signal int32
-		pad1   [128]int8
-		data1  int32
-		pad2   [128]int8
-		data2  float32
-	}
-	var X Data
-	for p := int32(0); p < 2; p++ {
-		go func(p int32) {
-			for i := int32(1); i < N; i++ {
-				if (i+p)%2 == 0 {
-					X.data1 = i
-					X.data2 = float32(i)
-					StoreInt32(&X.signal, i)
-				} else {
-					for w := 1; LoadInt32(&X.signal) != i; w++ {
-						if w%1000 == 0 {
-							runtime.Gosched()
-						}
-					}
-					d1 := X.data1
-					d2 := X.data2
-					if d1 != i || d2 != float32(i) {
-						t.Fatalf("incorrect data: %d/%g (%d)", d1, d2, i)
-					}
-				}
-			}
-			c <- true
-		}(p)
-	}
-	<-c
-	<-c
-}
-
-func TestStoreLoadRelAcq64(t *testing.T) {
-	if runtime.NumCPU() == 1 {
-		t.Skipf("Skipping test on %v processor machine", runtime.NumCPU())
-	}
-	if test64err != nil {
-		t.Skipf("Skipping 64-bit tests: %v", test64err)
-	}
-	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4))
-	N := int64(1e3)
-	if testing.Short() {
-		N = int64(1e2)
-	}
-	c := make(chan bool, 2)
-	type Data struct {
-		signal int64
-		pad1   [128]int8
-		data1  int64
-		pad2   [128]int8
-		data2  float64
-	}
-	var X Data
-	for p := int64(0); p < 2; p++ {
-		go func(p int64) {
-			for i := int64(1); i < N; i++ {
-				if (i+p)%2 == 0 {
-					X.data1 = i
-					X.data2 = float64(i)
-					StoreInt64(&X.signal, i)
-				} else {
-					for w := 1; LoadInt64(&X.signal) != i; w++ {
-						if w%1000 == 0 {
-							runtime.Gosched()
-						}
-					}
-					d1 := X.data1
-					d2 := X.data2
-					if d1 != i || d2 != float64(i) {
-						t.Fatalf("incorrect data: %d/%g (%d)", d1, d2, i)
-					}
-				}
-			}
-			c <- true
-		}(p)
-	}
-	<-c
-	<-c
-}
-
-func shouldPanic(t *testing.T, name string, f func()) {
-	defer func() {
-		if recover() == nil {
-			t.Errorf("%s did not panic", name)
-		}
-	}()
-	f()
-}
-
-func TestUnaligned64(t *testing.T) {
-	// Unaligned 64-bit atomics on 32-bit systems are
-	// a continual source of pain. Test that on 32-bit systems they crash
-	// instead of failing silently.
-	if unsafe.Sizeof(int(0)) != 4 {
-		t.Skip("test only runs on 32-bit systems")
-	}
-
-	x := make([]uint32, 4)
-	p := (*uint64)(unsafe.Pointer(&x[1])) // misaligned
-
-	shouldPanic(t, "LoadUint64", func() { LoadUint64(p) })
-	shouldPanic(t, "StoreUint64", func() { StoreUint64(p, 1) })
-	shouldPanic(t, "CompareAndSwapUint64", func() { CompareAndSwapUint64(p, 1, 2) })
-	shouldPanic(t, "AddUint64", func() { AddUint64(p, 3) })
-}
-
-func TestNilDeref(t *testing.T) {
-	if p := runtime.GOOS + "/" + runtime.GOARCH; p == "freebsd/arm" || p == "netbsd/arm" {
-		t.Skipf("issue 7338: skipping test on %q", p)
-	}
-	funcs := [...]func(){
-		func() { CompareAndSwapInt32(nil, 0, 0) },
-		func() { CompareAndSwapInt64(nil, 0, 0) },
-		func() { CompareAndSwapUint32(nil, 0, 0) },
-		func() { CompareAndSwapUint64(nil, 0, 0) },
-		func() { CompareAndSwapUintptr(nil, 0, 0) },
-		func() { CompareAndSwapPointer(nil, nil, nil) },
-		func() { SwapInt32(nil, 0) },
-		func() { SwapUint32(nil, 0) },
-		func() { SwapInt64(nil, 0) },
-		func() { SwapUint64(nil, 0) },
-		func() { SwapUintptr(nil, 0) },
-		func() { SwapPointer(nil, nil) },
-		func() { AddInt32(nil, 0) },
-		func() { AddUint32(nil, 0) },
-		func() { AddInt64(nil, 0) },
-		func() { AddUint64(nil, 0) },
-		func() { AddUintptr(nil, 0) },
-		func() { LoadInt32(nil) },
-		func() { LoadInt64(nil) },
-		func() { LoadUint32(nil) },
-		func() { LoadUint64(nil) },
-		func() { LoadUintptr(nil) },
-		func() { LoadPointer(nil) },
-		func() { StoreInt32(nil, 0) },
-		func() { StoreInt64(nil, 0) },
-		func() { StoreUint32(nil, 0) },
-		func() { StoreUint64(nil, 0) },
-		func() { StoreUintptr(nil, 0) },
-		func() { StorePointer(nil, nil) },
-	}
-	for _, f := range funcs {
-		func() {
-			defer func() {
-				runtime.GC()
-				recover()
-			}()
-			f()
-		}()
-	}
-}
diff --git a/src/pkg/sync/atomic/doc.go b/src/pkg/sync/atomic/doc.go
deleted file mode 100644
index 17ba72f..0000000
--- a/src/pkg/sync/atomic/doc.go
+++ /dev/null
@@ -1,151 +0,0 @@
-// Copyright 2011 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build !race
-
-// Package atomic provides low-level atomic memory primitives
-// useful for implementing synchronization algorithms.
-//
-// These functions require great care to be used correctly.
-// Except for special, low-level applications, synchronization is better
-// done with channels or the facilities of the sync package.
-// Share memory by communicating;
-// don't communicate by sharing memory.
-//
-// The swap operation, implemented by the SwapT functions, is the atomic
-// equivalent of:
-//
-//	old = *addr
-//	*addr = new
-//	return old
-//
-// The compare-and-swap operation, implemented by the CompareAndSwapT
-// functions, is the atomic equivalent of:
-//
-//	if *addr == old {
-//		*addr = new
-//		return true
-//	}
-//	return false
-//
-// The add operation, implemented by the AddT functions, is the atomic
-// equivalent of:
-//
-//	*addr += delta
-//	return *addr
-//
-// The load and store operations, implemented by the LoadT and StoreT
-// functions, are the atomic equivalents of "return *addr" and
-// "*addr = val".
-//
-package atomic
-
-import (
-	"unsafe"
-)
-
-// BUG(rsc): On x86-32, the 64-bit functions use instructions unavailable before the Pentium MMX.
-//
-// On non-Linux ARM, the 64-bit functions use instructions unavailable before the ARMv6k core.
-//
-// On both ARM and x86-32, it is the caller's responsibility to arrange for 64-bit
-// alignment of 64-bit words accessed atomically. The first word in a global
-// variable or in an allocated struct or slice can be relied upon to be
-// 64-bit aligned.
-
-// SwapInt32 atomically stores new into *addr and returns the previous *addr value.
-func SwapInt32(addr *int32, new int32) (old int32)
-
-// SwapInt64 atomically stores new into *addr and returns the previous *addr value.
-func SwapInt64(addr *int64, new int64) (old int64)
-
-// SwapUint32 atomically stores new into *addr and returns the previous *addr value.
-func SwapUint32(addr *uint32, new uint32) (old uint32)
-
-// SwapUint64 atomically stores new into *addr and returns the previous *addr value.
-func SwapUint64(addr *uint64, new uint64) (old uint64)
-
-// SwapUintptr atomically stores new into *addr and returns the previous *addr value.
-func SwapUintptr(addr *uintptr, new uintptr) (old uintptr)
-
-// SwapPointer atomically stores new into *addr and returns the previous *addr value.
-func SwapPointer(addr *unsafe.Pointer, new unsafe.Pointer) (old unsafe.Pointer)
-
-// CompareAndSwapInt32 executes the compare-and-swap operation for an int32 value.
-func CompareAndSwapInt32(addr *int32, old, new int32) (swapped bool)
-
-// CompareAndSwapInt64 executes the compare-and-swap operation for an int64 value.
-func CompareAndSwapInt64(addr *int64, old, new int64) (swapped bool)
-
-// CompareAndSwapUint32 executes the compare-and-swap operation for a uint32 value.
-func CompareAndSwapUint32(addr *uint32, old, new uint32) (swapped bool)
-
-// CompareAndSwapUint64 executes the compare-and-swap operation for a uint64 value.
-func CompareAndSwapUint64(addr *uint64, old, new uint64) (swapped bool)
-
-// CompareAndSwapUintptr executes the compare-and-swap operation for a uintptr value.
-func CompareAndSwapUintptr(addr *uintptr, old, new uintptr) (swapped bool)
-
-// CompareAndSwapPointer executes the compare-and-swap operation for a unsafe.Pointer value.
-func CompareAndSwapPointer(addr *unsafe.Pointer, old, new unsafe.Pointer) (swapped bool)
-
-// AddInt32 atomically adds delta to *addr and returns the new value.
-func AddInt32(addr *int32, delta int32) (new int32)
-
-// AddUint32 atomically adds delta to *addr and returns the new value.
-// To subtract a signed positive constant value c from x, do AddUint32(&x, ^uint32(c-1)).
-// In particular, to decrement x, do AddUint32(&x, ^uint32(0)).
-func AddUint32(addr *uint32, delta uint32) (new uint32)
-
-// AddInt64 atomically adds delta to *addr and returns the new value.
-func AddInt64(addr *int64, delta int64) (new int64)
-
-// AddUint64 atomically adds delta to *addr and returns the new value.
-// To subtract a signed positive constant value c from x, do AddUint64(&x, ^uint64(c-1)).
-// In particular, to decrement x, do AddUint64(&x, ^uint64(0)).
-func AddUint64(addr *uint64, delta uint64) (new uint64)
-
-// AddUintptr atomically adds delta to *addr and returns the new value.
-func AddUintptr(addr *uintptr, delta uintptr) (new uintptr)
-
-// LoadInt32 atomically loads *addr.
-func LoadInt32(addr *int32) (val int32)
-
-// LoadInt64 atomically loads *addr.
-func LoadInt64(addr *int64) (val int64)
-
-// LoadUint32 atomically loads *addr.
-func LoadUint32(addr *uint32) (val uint32)
-
-// LoadUint64 atomically loads *addr.
-func LoadUint64(addr *uint64) (val uint64)
-
-// LoadUintptr atomically loads *addr.
-func LoadUintptr(addr *uintptr) (val uintptr)
-
-// LoadPointer atomically loads *addr.
-func LoadPointer(addr *unsafe.Pointer) (val unsafe.Pointer)
-
-// StoreInt32 atomically stores val into *addr.
-func StoreInt32(addr *int32, val int32)
-
-// StoreInt64 atomically stores val into *addr.
-func StoreInt64(addr *int64, val int64)
-
-// StoreUint32 atomically stores val into *addr.
-func StoreUint32(addr *uint32, val uint32)
-
-// StoreUint64 atomically stores val into *addr.
-func StoreUint64(addr *uint64, val uint64)
-
-// StoreUintptr atomically stores val into *addr.
-func StoreUintptr(addr *uintptr, val uintptr)
-
-// StorePointer atomically stores val into *addr.
-func StorePointer(addr *unsafe.Pointer, val unsafe.Pointer)
-
-// Helper for ARM.  Linker will discard on other systems
-func panic64() {
-	panic("sync/atomic: broken 64-bit atomic operations (buggy QEMU)")
-}
diff --git a/src/pkg/sync/atomic/export_linux_arm_test.go b/src/pkg/sync/atomic/export_linux_arm_test.go
deleted file mode 100644
index 5cd4335..0000000
--- a/src/pkg/sync/atomic/export_linux_arm_test.go
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright 2013 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package atomic
-
-func generalCAS64(addr *uint64, old uint64, new uint64) bool
-
-var GeneralCAS64 = generalCAS64
diff --git a/src/pkg/sync/atomic/race.go b/src/pkg/sync/atomic/race.go
deleted file mode 100644
index 6cbbf12..0000000
--- a/src/pkg/sync/atomic/race.go
+++ /dev/null
@@ -1,276 +0,0 @@
-// Copyright 2011 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build race
-
-package atomic
-
-import (
-	"runtime"
-	"unsafe"
-)
-
-// We use runtime.RaceRead() inside of atomic operations to catch races
-// between atomic and non-atomic operations.  It will also catch races
-// between Mutex.Lock() and mutex overwrite (mu = Mutex{}).  Since we use
-// only RaceRead() we won't catch races with non-atomic loads.
-// Otherwise (if we use RaceWrite()) we will report races
-// between atomic operations (false positives).
-
-var mtx uint32 = 1 // same for all
-
-func SwapInt32(addr *int32, new int32) (old int32) {
-	return int32(SwapUint32((*uint32)(unsafe.Pointer(addr)), uint32(new)))
-}
-
-func SwapUint32(addr *uint32, new uint32) (old uint32) {
-	_ = *addr
-	runtime.RaceSemacquire(&mtx)
-	runtime.RaceRead(unsafe.Pointer(addr))
-	runtime.RaceAcquire(unsafe.Pointer(addr))
-	old = *addr
-	*addr = new
-	runtime.RaceReleaseMerge(unsafe.Pointer(addr))
-	runtime.RaceSemrelease(&mtx)
-	return
-}
-
-func SwapInt64(addr *int64, new int64) (old int64) {
-	return int64(SwapUint64((*uint64)(unsafe.Pointer(addr)), uint64(new)))
-}
-
-func SwapUint64(addr *uint64, new uint64) (old uint64) {
-	_ = *addr
-	runtime.RaceSemacquire(&mtx)
-	runtime.RaceRead(unsafe.Pointer(addr))
-	runtime.RaceAcquire(unsafe.Pointer(addr))
-	old = *addr
-	*addr = new
-	runtime.RaceReleaseMerge(unsafe.Pointer(addr))
-	runtime.RaceSemrelease(&mtx)
-	return
-}
-
-func SwapUintptr(addr *uintptr, new uintptr) (old uintptr) {
-	return uintptr(SwapPointer((*unsafe.Pointer)(unsafe.Pointer(addr)), unsafe.Pointer(new)))
-}
-
-func SwapPointer(addr *unsafe.Pointer, new unsafe.Pointer) (old unsafe.Pointer) {
-	_ = *addr
-	runtime.RaceSemacquire(&mtx)
-	runtime.RaceRead(unsafe.Pointer(addr))
-	runtime.RaceAcquire(unsafe.Pointer(addr))
-	old = *addr
-	*addr = new
-	runtime.RaceReleaseMerge(unsafe.Pointer(addr))
-	runtime.RaceSemrelease(&mtx)
-	return
-}
-
-func CompareAndSwapInt32(val *int32, old, new int32) bool {
-	return CompareAndSwapUint32((*uint32)(unsafe.Pointer(val)), uint32(old), uint32(new))
-}
-
-func CompareAndSwapUint32(val *uint32, old, new uint32) (swapped bool) {
-	_ = *val
-	swapped = false
-	runtime.RaceSemacquire(&mtx)
-	runtime.RaceRead(unsafe.Pointer(val))
-	runtime.RaceAcquire(unsafe.Pointer(val))
-	if *val == old {
-		*val = new
-		swapped = true
-		runtime.RaceReleaseMerge(unsafe.Pointer(val))
-	}
-	runtime.RaceSemrelease(&mtx)
-	return
-}
-
-func CompareAndSwapInt64(val *int64, old, new int64) bool {
-	return CompareAndSwapUint64((*uint64)(unsafe.Pointer(val)), uint64(old), uint64(new))
-}
-
-func CompareAndSwapUint64(val *uint64, old, new uint64) (swapped bool) {
-	_ = *val
-	swapped = false
-	runtime.RaceSemacquire(&mtx)
-	runtime.RaceRead(unsafe.Pointer(val))
-	runtime.RaceAcquire(unsafe.Pointer(val))
-	if *val == old {
-		*val = new
-		swapped = true
-		runtime.RaceReleaseMerge(unsafe.Pointer(val))
-	}
-	runtime.RaceSemrelease(&mtx)
-	return
-}
-
-func CompareAndSwapPointer(val *unsafe.Pointer, old, new unsafe.Pointer) (swapped bool) {
-	_ = *val
-	swapped = false
-	runtime.RaceSemacquire(&mtx)
-	runtime.RaceRead(unsafe.Pointer(val))
-	runtime.RaceAcquire(unsafe.Pointer(val))
-	if *val == old {
-		*val = new
-		swapped = true
-		runtime.RaceReleaseMerge(unsafe.Pointer(val))
-	}
-	runtime.RaceSemrelease(&mtx)
-	return
-}
-
-func CompareAndSwapUintptr(val *uintptr, old, new uintptr) (swapped bool) {
-	_ = *val
-	swapped = false
-	runtime.RaceSemacquire(&mtx)
-	runtime.RaceRead(unsafe.Pointer(val))
-	runtime.RaceAcquire(unsafe.Pointer(val))
-	if *val == old {
-		*val = new
-		swapped = true
-		runtime.RaceReleaseMerge(unsafe.Pointer(val))
-	}
-	runtime.RaceSemrelease(&mtx)
-	return
-}
-
-func AddInt32(val *int32, delta int32) int32 {
-	return int32(AddUint32((*uint32)(unsafe.Pointer(val)), uint32(delta)))
-}
-
-func AddUint32(val *uint32, delta uint32) (new uint32) {
-	_ = *val
-	runtime.RaceSemacquire(&mtx)
-	runtime.RaceRead(unsafe.Pointer(val))
-	runtime.RaceAcquire(unsafe.Pointer(val))
-	*val = *val + delta
-	new = *val
-	runtime.RaceReleaseMerge(unsafe.Pointer(val))
-	runtime.RaceSemrelease(&mtx)
-
-	return
-}
-
-func AddInt64(val *int64, delta int64) int64 {
-	return int64(AddUint64((*uint64)(unsafe.Pointer(val)), uint64(delta)))
-}
-
-func AddUint64(val *uint64, delta uint64) (new uint64) {
-	_ = *val
-	runtime.RaceSemacquire(&mtx)
-	runtime.RaceRead(unsafe.Pointer(val))
-	runtime.RaceAcquire(unsafe.Pointer(val))
-	*val = *val + delta
-	new = *val
-	runtime.RaceReleaseMerge(unsafe.Pointer(val))
-	runtime.RaceSemrelease(&mtx)
-
-	return
-}
-
-func AddUintptr(val *uintptr, delta uintptr) (new uintptr) {
-	_ = *val
-	runtime.RaceSemacquire(&mtx)
-	runtime.RaceRead(unsafe.Pointer(val))
-	runtime.RaceAcquire(unsafe.Pointer(val))
-	*val = *val + delta
-	new = *val
-	runtime.RaceReleaseMerge(unsafe.Pointer(val))
-	runtime.RaceSemrelease(&mtx)
-
-	return
-}
-
-func LoadInt32(addr *int32) int32 {
-	return int32(LoadUint32((*uint32)(unsafe.Pointer(addr))))
-}
-
-func LoadUint32(addr *uint32) (val uint32) {
-	_ = *addr
-	runtime.RaceSemacquire(&mtx)
-	runtime.RaceRead(unsafe.Pointer(addr))
-	runtime.RaceAcquire(unsafe.Pointer(addr))
-	val = *addr
-	runtime.RaceSemrelease(&mtx)
-	return
-}
-
-func LoadInt64(addr *int64) int64 {
-	return int64(LoadUint64((*uint64)(unsafe.Pointer(addr))))
-}
-
-func LoadUint64(addr *uint64) (val uint64) {
-	_ = *addr
-	runtime.RaceSemacquire(&mtx)
-	runtime.RaceRead(unsafe.Pointer(addr))
-	runtime.RaceAcquire(unsafe.Pointer(addr))
-	val = *addr
-	runtime.RaceSemrelease(&mtx)
-	return
-}
-
-func LoadPointer(addr *unsafe.Pointer) (val unsafe.Pointer) {
-	_ = *addr
-	runtime.RaceSemacquire(&mtx)
-	runtime.RaceRead(unsafe.Pointer(addr))
-	runtime.RaceAcquire(unsafe.Pointer(addr))
-	val = *addr
-	runtime.RaceSemrelease(&mtx)
-	return
-}
-
-func LoadUintptr(addr *uintptr) (val uintptr) {
-	_ = *addr
-	runtime.RaceSemacquire(&mtx)
-	runtime.RaceRead(unsafe.Pointer(addr))
-	runtime.RaceAcquire(unsafe.Pointer(addr))
-	val = *addr
-	runtime.RaceSemrelease(&mtx)
-	return
-}
-
-func StoreInt32(addr *int32, val int32) {
-	StoreUint32((*uint32)(unsafe.Pointer(addr)), uint32(val))
-}
-
-func StoreUint32(addr *uint32, val uint32) {
-	_ = *addr
-	runtime.RaceSemacquire(&mtx)
-	runtime.RaceRead(unsafe.Pointer(addr))
-	*addr = val
-	runtime.RaceRelease(unsafe.Pointer(addr))
-	runtime.RaceSemrelease(&mtx)
-}
-
-func StoreInt64(addr *int64, val int64) {
-	StoreUint64((*uint64)(unsafe.Pointer(addr)), uint64(val))
-}
-
-func StoreUint64(addr *uint64, val uint64) {
-	_ = *addr
-	runtime.RaceSemacquire(&mtx)
-	runtime.RaceRead(unsafe.Pointer(addr))
-	*addr = val
-	runtime.RaceRelease(unsafe.Pointer(addr))
-	runtime.RaceSemrelease(&mtx)
-}
-
-func StorePointer(addr *unsafe.Pointer, val unsafe.Pointer) {
-	_ = *addr
-	runtime.RaceSemacquire(&mtx)
-	runtime.RaceRead(unsafe.Pointer(addr))
-	*addr = val
-	runtime.RaceRelease(unsafe.Pointer(addr))
-	runtime.RaceSemrelease(&mtx)
-}
-
-func StoreUintptr(addr *uintptr, val uintptr) {
-	_ = *addr
-	runtime.RaceSemacquire(&mtx)
-	runtime.RaceRead(unsafe.Pointer(addr))
-	*addr = val
-	runtime.RaceRelease(unsafe.Pointer(addr))
-	runtime.RaceSemrelease(&mtx)
-}
diff --git a/src/pkg/sync/once.go b/src/pkg/sync/once.go
deleted file mode 100644
index 161ae3b..0000000
--- a/src/pkg/sync/once.go
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package sync
-
-import (
-	"sync/atomic"
-)
-
-// Once is an object that will perform exactly one action.
-type Once struct {
-	m    Mutex
-	done uint32
-}
-
-// Do calls the function f if and only if Do is being called for the
-// first time for this instance of Once.  In other words, given
-// 	var once Once
-// if once.Do(f) is called multiple times, only the first call will invoke f,
-// even if f has a different value in each invocation.  A new instance of
-// Once is required for each function to execute.
-//
-// Do is intended for initialization that must be run exactly once.  Since f
-// is niladic, it may be necessary to use a function literal to capture the
-// arguments to a function to be invoked by Do:
-// 	config.once.Do(func() { config.init(filename) })
-//
-// Because no call to Do returns until the one call to f returns, if f causes
-// Do to be called, it will deadlock.
-//
-func (o *Once) Do(f func()) {
-	if atomic.LoadUint32(&o.done) == 1 {
-		return
-	}
-	// Slow-path.
-	o.m.Lock()
-	defer o.m.Unlock()
-	if o.done == 0 {
-		f()
-		atomic.StoreUint32(&o.done, 1)
-	}
-}
diff --git a/src/pkg/sync/once_test.go b/src/pkg/sync/once_test.go
deleted file mode 100644
index 8afda82..0000000
--- a/src/pkg/sync/once_test.go
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package sync_test
-
-import (
-	. "sync"
-	"testing"
-)
-
-type one int
-
-func (o *one) Increment() {
-	*o++
-}
-
-func run(t *testing.T, once *Once, o *one, c chan bool) {
-	once.Do(func() { o.Increment() })
-	if v := *o; v != 1 {
-		t.Errorf("once failed inside run: %d is not 1", v)
-	}
-	c <- true
-}
-
-func TestOnce(t *testing.T) {
-	o := new(one)
-	once := new(Once)
-	c := make(chan bool)
-	const N = 10
-	for i := 0; i < N; i++ {
-		go run(t, once, o, c)
-	}
-	for i := 0; i < N; i++ {
-		<-c
-	}
-	if *o != 1 {
-		t.Errorf("once failed outside run: %d is not 1", *o)
-	}
-}
-
-func TestOncePanic(t *testing.T) {
-	once := new(Once)
-	for i := 0; i < 2; i++ {
-		func() {
-			defer func() {
-				if recover() == nil {
-					t.Fatalf("Once.Do() has not panic'ed")
-				}
-			}()
-			once.Do(func() {
-				panic("failed")
-			})
-		}()
-	}
-	once.Do(func() {})
-	once.Do(func() {
-		t.Fatalf("Once called twice")
-	})
-}
-
-func BenchmarkOnce(b *testing.B) {
-	var once Once
-	f := func() {}
-	b.RunParallel(func(pb *testing.PB) {
-		for pb.Next() {
-			once.Do(f)
-		}
-	})
-}
diff --git a/src/pkg/sync/pool.go b/src/pkg/sync/pool.go
deleted file mode 100644
index 1f08707..0000000
--- a/src/pkg/sync/pool.go
+++ /dev/null
@@ -1,223 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package sync
-
-import (
-	"runtime"
-	"sync/atomic"
-	"unsafe"
-)
-
-// A Pool is a set of temporary objects that may be individually saved and
-// retrieved.
-//
-// Any item stored in the Pool may be removed automatically at any time without
-// notification. If the Pool holds the only reference when this happens, the
-// item might be deallocated.
-//
-// A Pool is safe for use by multiple goroutines simultaneously.
-//
-// Pool's purpose is to cache allocated but unused items for later reuse,
-// relieving pressure on the garbage collector. That is, it makes it easy to
-// build efficient, thread-safe free lists. However, it is not suitable for all
-// free lists.
-//
-// An appropriate use of a Pool is to manage a group of temporary items
-// silently shared among and potentially reused by concurrent independent
-// clients of a package. Pool provides a way to amortize allocation overhead
-// across many clients.
-//
-// An example of good use of a Pool is in the fmt package, which maintains a
-// dynamically-sized store of temporary output buffers. The store scales under
-// load (when many goroutines are actively printing) and shrinks when
-// quiescent.
-//
-// On the other hand, a free list maintained as part of a short-lived object is
-// not a suitable use for a Pool, since the overhead does not amortize well in
-// that scenario. It is more efficient to have such objects implement their own
-// free list.
-//
-type Pool struct {
-	local     unsafe.Pointer // local fixed-size per-P pool, actual type is [P]poolLocal
-	localSize uintptr        // size of the local array
-
-	// New optionally specifies a function to generate
-	// a value when Get would otherwise return nil.
-	// It may not be changed concurrently with calls to Get.
-	New func() interface{}
-}
-
-// Local per-P Pool appendix.
-type poolLocal struct {
-	private interface{}   // Can be used only by the respective P.
-	shared  []interface{} // Can be used by any P.
-	Mutex                 // Protects shared.
-	pad     [128]byte     // Prevents false sharing.
-}
-
-// Put adds x to the pool.
-func (p *Pool) Put(x interface{}) {
-	if raceenabled {
-		// Under race detector the Pool degenerates into no-op.
-		// It's conforming, simple and does not introduce excessive
-		// happens-before edges between unrelated goroutines.
-		return
-	}
-	if x == nil {
-		return
-	}
-	l := p.pin()
-	if l.private == nil {
-		l.private = x
-		x = nil
-	}
-	runtime_procUnpin()
-	if x == nil {
-		return
-	}
-	l.Lock()
-	l.shared = append(l.shared, x)
-	l.Unlock()
-}
-
-// Get selects an arbitrary item from the Pool, removes it from the
-// Pool, and returns it to the caller.
-// Get may choose to ignore the pool and treat it as empty.
-// Callers should not assume any relation between values passed to Put and
-// the values returned by Get.
-//
-// If Get would otherwise return nil and p.New is non-nil, Get returns
-// the result of calling p.New.
-func (p *Pool) Get() interface{} {
-	if raceenabled {
-		if p.New != nil {
-			return p.New()
-		}
-		return nil
-	}
-	l := p.pin()
-	x := l.private
-	l.private = nil
-	runtime_procUnpin()
-	if x != nil {
-		return x
-	}
-	l.Lock()
-	last := len(l.shared) - 1
-	if last >= 0 {
-		x = l.shared[last]
-		l.shared = l.shared[:last]
-	}
-	l.Unlock()
-	if x != nil {
-		return x
-	}
-	return p.getSlow()
-}
-
-func (p *Pool) getSlow() (x interface{}) {
-	// See the comment in pin regarding ordering of the loads.
-	size := atomic.LoadUintptr(&p.localSize) // load-acquire
-	local := p.local                         // load-consume
-	// Try to steal one element from other procs.
-	pid := runtime_procPin()
-	runtime_procUnpin()
-	for i := 0; i < int(size); i++ {
-		l := indexLocal(local, (pid+i+1)%int(size))
-		l.Lock()
-		last := len(l.shared) - 1
-		if last >= 0 {
-			x = l.shared[last]
-			l.shared = l.shared[:last]
-			l.Unlock()
-			break
-		}
-		l.Unlock()
-	}
-
-	if x == nil && p.New != nil {
-		x = p.New()
-	}
-	return x
-}
-
-// pin pins the current goroutine to P, disables preemption and returns poolLocal pool for the P.
-// Caller must call runtime_procUnpin() when done with the pool.
-func (p *Pool) pin() *poolLocal {
-	pid := runtime_procPin()
-	// In pinSlow we store to localSize and then to local, here we load in opposite order.
-	// Since we've disabled preemption, GC can not happen in between.
-	// Thus here we must observe local at least as large localSize.
-	// We can observe a newer/larger local, it is fine (we must observe its zero-initialized-ness).
-	s := atomic.LoadUintptr(&p.localSize) // load-acquire
-	l := p.local                          // load-consume
-	if uintptr(pid) < s {
-		return indexLocal(l, pid)
-	}
-	return p.pinSlow()
-}
-
-func (p *Pool) pinSlow() *poolLocal {
-	// Retry under the mutex.
-	// Can not lock the mutex while pinned.
-	runtime_procUnpin()
-	allPoolsMu.Lock()
-	defer allPoolsMu.Unlock()
-	pid := runtime_procPin()
-	// poolCleanup won't be called while we are pinned.
-	s := p.localSize
-	l := p.local
-	if uintptr(pid) < s {
-		return indexLocal(l, pid)
-	}
-	if p.local == nil {
-		allPools = append(allPools, p)
-	}
-	// If GOMAXPROCS changes between GCs, we re-allocate the array and lose the old one.
-	size := runtime.GOMAXPROCS(0)
-	local := make([]poolLocal, size)
-	atomic.StorePointer((*unsafe.Pointer)(&p.local), unsafe.Pointer(&local[0])) // store-release
-	atomic.StoreUintptr(&p.localSize, uintptr(size))                            // store-release
-	return &local[pid]
-}
-
-func poolCleanup() {
-	// This function is called with the world stopped, at the beginning of a garbage collection.
-	// It must not allocate and probably should not call any runtime functions.
-	// Defensively zero out everything, 2 reasons:
-	// 1. To prevent false retention of whole Pools.
-	// 2. If GC happens while a goroutine works with l.shared in Put/Get,
-	//    it will retain whole Pool. So next cycle memory consumption would be doubled.
-	for i, p := range allPools {
-		allPools[i] = nil
-		for i := 0; i < int(p.localSize); i++ {
-			l := indexLocal(p.local, i)
-			l.private = nil
-			for j := range l.shared {
-				l.shared[j] = nil
-			}
-			l.shared = nil
-		}
-	}
-	allPools = []*Pool{}
-}
-
-var (
-	allPoolsMu Mutex
-	allPools   []*Pool
-)
-
-func init() {
-	runtime_registerPoolCleanup(poolCleanup)
-}
-
-func indexLocal(l unsafe.Pointer, i int) *poolLocal {
-	return &(*[1000000]poolLocal)(l)[i]
-}
-
-// Implemented in runtime.
-func runtime_registerPoolCleanup(cleanup func())
-func runtime_procPin() int
-func runtime_procUnpin()
diff --git a/src/pkg/sync/pool_test.go b/src/pkg/sync/pool_test.go
deleted file mode 100644
index 509448b..0000000
--- a/src/pkg/sync/pool_test.go
+++ /dev/null
@@ -1,151 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Pool is no-op under race detector, so all these tests do not work.
-// +build !race
-
-package sync_test
-
-import (
-	"runtime"
-	"runtime/debug"
-	. "sync"
-	"sync/atomic"
-	"testing"
-	"time"
-)
-
-func TestPool(t *testing.T) {
-	// disable GC so we can control when it happens.
-	defer debug.SetGCPercent(debug.SetGCPercent(-1))
-	var p Pool
-	if p.Get() != nil {
-		t.Fatal("expected empty")
-	}
-	p.Put("a")
-	p.Put("b")
-	if g := p.Get(); g != "a" {
-		t.Fatalf("got %#v; want a", g)
-	}
-	if g := p.Get(); g != "b" {
-		t.Fatalf("got %#v; want b", g)
-	}
-	if g := p.Get(); g != nil {
-		t.Fatalf("got %#v; want nil", g)
-	}
-
-	p.Put("c")
-	debug.SetGCPercent(100) // to allow following GC to actually run
-	runtime.GC()
-	if g := p.Get(); g != nil {
-		t.Fatalf("got %#v; want nil after GC", g)
-	}
-}
-
-func TestPoolNew(t *testing.T) {
-	// disable GC so we can control when it happens.
-	defer debug.SetGCPercent(debug.SetGCPercent(-1))
-
-	i := 0
-	p := Pool{
-		New: func() interface{} {
-			i++
-			return i
-		},
-	}
-	if v := p.Get(); v != 1 {
-		t.Fatalf("got %v; want 1", v)
-	}
-	if v := p.Get(); v != 2 {
-		t.Fatalf("got %v; want 2", v)
-	}
-	p.Put(42)
-	if v := p.Get(); v != 42 {
-		t.Fatalf("got %v; want 42", v)
-	}
-	if v := p.Get(); v != 3 {
-		t.Fatalf("got %v; want 3", v)
-	}
-}
-
-// Test that Pool does not hold pointers to previously cached
-// resources
-func TestPoolGC(t *testing.T) {
-	var p Pool
-	var fin uint32
-	const N = 100
-	for i := 0; i < N; i++ {
-		v := new(string)
-		runtime.SetFinalizer(v, func(vv *string) {
-			atomic.AddUint32(&fin, 1)
-		})
-		p.Put(v)
-	}
-	for i := 0; i < N; i++ {
-		p.Get()
-	}
-	for i := 0; i < 5; i++ {
-		runtime.GC()
-		time.Sleep(time.Duration(i*100+10) * time.Millisecond)
-		// 1 pointer can remain on stack or elsewhere
-		if atomic.LoadUint32(&fin) >= N-1 {
-			return
-		}
-	}
-	t.Fatalf("only %v out of %v resources are finalized",
-		atomic.LoadUint32(&fin), N)
-}
-
-func TestPoolStress(t *testing.T) {
-	const P = 10
-	N := int(1e6)
-	if testing.Short() {
-		N /= 100
-	}
-	var p Pool
-	done := make(chan bool)
-	for i := 0; i < P; i++ {
-		go func() {
-			var v interface{} = 0
-			for j := 0; j < N; j++ {
-				if v == nil {
-					v = 0
-				}
-				p.Put(v)
-				v = p.Get()
-				if v != nil && v.(int) != 0 {
-					t.Fatalf("expect 0, got %v", v)
-				}
-			}
-			done <- true
-		}()
-	}
-	for i := 0; i < P; i++ {
-		<-done
-	}
-}
-
-func BenchmarkPool(b *testing.B) {
-	var p Pool
-	b.RunParallel(func(pb *testing.PB) {
-		for pb.Next() {
-			p.Put(1)
-			p.Get()
-		}
-	})
-}
-
-func BenchmarkPoolOverlflow(b *testing.B) {
-	var p Pool
-	b.RunParallel(func(pb *testing.PB) {
-		for pb.Next() {
-			for b := 0; b < 100; b++ {
-				p.Put(1)
-			}
-			for b := 0; b < 100; b++ {
-				p.Get()
-			}
-		}
-	})
-}
diff --git a/src/pkg/sync/runtime.go b/src/pkg/sync/runtime.go
deleted file mode 100644
index 3bf47ea..0000000
--- a/src/pkg/sync/runtime.go
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2012 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package sync
-
-import "unsafe"
-
-// defined in package runtime
-
-// Semacquire waits until *s > 0 and then atomically decrements it.
-// It is intended as a simple sleep primitive for use by the synchronization
-// library and should not be used directly.
-func runtime_Semacquire(s *uint32)
-
-// Semrelease atomically increments *s and notifies a waiting goroutine
-// if one is blocked in Semacquire.
-// It is intended as a simple wakeup primitive for use by the synchronization
-// library and should not be used directly.
-func runtime_Semrelease(s *uint32)
-
-// Opaque representation of SyncSema in runtime/sema.goc.
-type syncSema [3]uintptr
-
-// Syncsemacquire waits for a pairing Syncsemrelease on the same semaphore s.
-func runtime_Syncsemacquire(s *syncSema)
-
-// Syncsemrelease waits for n pairing Syncsemacquire on the same semaphore s.
-func runtime_Syncsemrelease(s *syncSema, n uint32)
-
-// Ensure that sync and runtime agree on size of syncSema.
-func runtime_Syncsemcheck(size uintptr)
-func init() {
-	var s syncSema
-	runtime_Syncsemcheck(unsafe.Sizeof(s))
-}
diff --git a/src/pkg/sync/rwmutex.go b/src/pkg/sync/rwmutex.go
deleted file mode 100644
index 3db5419..0000000
--- a/src/pkg/sync/rwmutex.go
+++ /dev/null
@@ -1,128 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package sync
-
-import (
-	"sync/atomic"
-	"unsafe"
-)
-
-// An RWMutex is a reader/writer mutual exclusion lock.
-// The lock can be held by an arbitrary number of readers
-// or a single writer.
-// RWMutexes can be created as part of other
-// structures; the zero value for a RWMutex is
-// an unlocked mutex.
-type RWMutex struct {
-	w           Mutex  // held if there are pending writers
-	writerSem   uint32 // semaphore for writers to wait for completing readers
-	readerSem   uint32 // semaphore for readers to wait for completing writers
-	readerCount int32  // number of pending readers
-	readerWait  int32  // number of departing readers
-}
-
-const rwmutexMaxReaders = 1 << 30
-
-// RLock locks rw for reading.
-func (rw *RWMutex) RLock() {
-	if raceenabled {
-		_ = rw.w.state
-		raceDisable()
-	}
-	if atomic.AddInt32(&rw.readerCount, 1) < 0 {
-		// A writer is pending, wait for it.
-		runtime_Semacquire(&rw.readerSem)
-	}
-	if raceenabled {
-		raceEnable()
-		raceAcquire(unsafe.Pointer(&rw.readerSem))
-	}
-}
-
-// RUnlock undoes a single RLock call;
-// it does not affect other simultaneous readers.
-// It is a run-time error if rw is not locked for reading
-// on entry to RUnlock.
-func (rw *RWMutex) RUnlock() {
-	if raceenabled {
-		_ = rw.w.state
-		raceReleaseMerge(unsafe.Pointer(&rw.writerSem))
-		raceDisable()
-	}
-	if atomic.AddInt32(&rw.readerCount, -1) < 0 {
-		// A writer is pending.
-		if atomic.AddInt32(&rw.readerWait, -1) == 0 {
-			// The last reader unblocks the writer.
-			runtime_Semrelease(&rw.writerSem)
-		}
-	}
-	if raceenabled {
-		raceEnable()
-	}
-}
-
-// Lock locks rw for writing.
-// If the lock is already locked for reading or writing,
-// Lock blocks until the lock is available.
-// To ensure that the lock eventually becomes available,
-// a blocked Lock call excludes new readers from acquiring
-// the lock.
-func (rw *RWMutex) Lock() {
-	if raceenabled {
-		_ = rw.w.state
-		raceDisable()
-	}
-	// First, resolve competition with other writers.
-	rw.w.Lock()
-	// Announce to readers there is a pending writer.
-	r := atomic.AddInt32(&rw.readerCount, -rwmutexMaxReaders) + rwmutexMaxReaders
-	// Wait for active readers.
-	if r != 0 && atomic.AddInt32(&rw.readerWait, r) != 0 {
-		runtime_Semacquire(&rw.writerSem)
-	}
-	if raceenabled {
-		raceEnable()
-		raceAcquire(unsafe.Pointer(&rw.readerSem))
-		raceAcquire(unsafe.Pointer(&rw.writerSem))
-	}
-}
-
-// Unlock unlocks rw for writing.  It is a run-time error if rw is
-// not locked for writing on entry to Unlock.
-//
-// As with Mutexes, a locked RWMutex is not associated with a particular
-// goroutine.  One goroutine may RLock (Lock) an RWMutex and then
-// arrange for another goroutine to RUnlock (Unlock) it.
-func (rw *RWMutex) Unlock() {
-	if raceenabled {
-		_ = rw.w.state
-		raceRelease(unsafe.Pointer(&rw.readerSem))
-		raceRelease(unsafe.Pointer(&rw.writerSem))
-		raceDisable()
-	}
-
-	// Announce to readers there is no active writer.
-	r := atomic.AddInt32(&rw.readerCount, rwmutexMaxReaders)
-	// Unblock blocked readers, if any.
-	for i := 0; i < int(r); i++ {
-		runtime_Semrelease(&rw.readerSem)
-	}
-	// Allow other writers to proceed.
-	rw.w.Unlock()
-	if raceenabled {
-		raceEnable()
-	}
-}
-
-// RLocker returns a Locker interface that implements
-// the Lock and Unlock methods by calling rw.RLock and rw.RUnlock.
-func (rw *RWMutex) RLocker() Locker {
-	return (*rlocker)(rw)
-}
-
-type rlocker RWMutex
-
-func (r *rlocker) Lock()   { (*RWMutex)(r).RLock() }
-func (r *rlocker) Unlock() { (*RWMutex)(r).RUnlock() }
diff --git a/src/pkg/sync/rwmutex_test.go b/src/pkg/sync/rwmutex_test.go
deleted file mode 100644
index 0436f97..0000000
--- a/src/pkg/sync/rwmutex_test.go
+++ /dev/null
@@ -1,212 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// GOMAXPROCS=10 go test
-
-package sync_test
-
-import (
-	"fmt"
-	"runtime"
-	. "sync"
-	"sync/atomic"
-	"testing"
-)
-
-func parallelReader(m *RWMutex, clocked, cunlock, cdone chan bool) {
-	m.RLock()
-	clocked <- true
-	<-cunlock
-	m.RUnlock()
-	cdone <- true
-}
-
-func doTestParallelReaders(numReaders, gomaxprocs int) {
-	runtime.GOMAXPROCS(gomaxprocs)
-	var m RWMutex
-	clocked := make(chan bool)
-	cunlock := make(chan bool)
-	cdone := make(chan bool)
-	for i := 0; i < numReaders; i++ {
-		go parallelReader(&m, clocked, cunlock, cdone)
-	}
-	// Wait for all parallel RLock()s to succeed.
-	for i := 0; i < numReaders; i++ {
-		<-clocked
-	}
-	for i := 0; i < numReaders; i++ {
-		cunlock <- true
-	}
-	// Wait for the goroutines to finish.
-	for i := 0; i < numReaders; i++ {
-		<-cdone
-	}
-}
-
-func TestParallelReaders(t *testing.T) {
-	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(-1))
-	doTestParallelReaders(1, 4)
-	doTestParallelReaders(3, 4)
-	doTestParallelReaders(4, 2)
-}
-
-func reader(rwm *RWMutex, num_iterations int, activity *int32, cdone chan bool) {
-	for i := 0; i < num_iterations; i++ {
-		rwm.RLock()
-		n := atomic.AddInt32(activity, 1)
-		if n < 1 || n >= 10000 {
-			panic(fmt.Sprintf("wlock(%d)\n", n))
-		}
-		for i := 0; i < 100; i++ {
-		}
-		atomic.AddInt32(activity, -1)
-		rwm.RUnlock()
-	}
-	cdone <- true
-}
-
-func writer(rwm *RWMutex, num_iterations int, activity *int32, cdone chan bool) {
-	for i := 0; i < num_iterations; i++ {
-		rwm.Lock()
-		n := atomic.AddInt32(activity, 10000)
-		if n != 10000 {
-			panic(fmt.Sprintf("wlock(%d)\n", n))
-		}
-		for i := 0; i < 100; i++ {
-		}
-		atomic.AddInt32(activity, -10000)
-		rwm.Unlock()
-	}
-	cdone <- true
-}
-
-func HammerRWMutex(gomaxprocs, numReaders, num_iterations int) {
-	runtime.GOMAXPROCS(gomaxprocs)
-	// Number of active readers + 10000 * number of active writers.
-	var activity int32
-	var rwm RWMutex
-	cdone := make(chan bool)
-	go writer(&rwm, num_iterations, &activity, cdone)
-	var i int
-	for i = 0; i < numReaders/2; i++ {
-		go reader(&rwm, num_iterations, &activity, cdone)
-	}
-	go writer(&rwm, num_iterations, &activity, cdone)
-	for ; i < numReaders; i++ {
-		go reader(&rwm, num_iterations, &activity, cdone)
-	}
-	// Wait for the 2 writers and all readers to finish.
-	for i := 0; i < 2+numReaders; i++ {
-		<-cdone
-	}
-}
-
-func TestRWMutex(t *testing.T) {
-	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(-1))
-	n := 1000
-	if testing.Short() {
-		n = 5
-	}
-	HammerRWMutex(1, 1, n)
-	HammerRWMutex(1, 3, n)
-	HammerRWMutex(1, 10, n)
-	HammerRWMutex(4, 1, n)
-	HammerRWMutex(4, 3, n)
-	HammerRWMutex(4, 10, n)
-	HammerRWMutex(10, 1, n)
-	HammerRWMutex(10, 3, n)
-	HammerRWMutex(10, 10, n)
-	HammerRWMutex(10, 5, n)
-}
-
-func TestRLocker(t *testing.T) {
-	var wl RWMutex
-	var rl Locker
-	wlocked := make(chan bool, 1)
-	rlocked := make(chan bool, 1)
-	rl = wl.RLocker()
-	n := 10
-	go func() {
-		for i := 0; i < n; i++ {
-			rl.Lock()
-			rl.Lock()
-			rlocked <- true
-			wl.Lock()
-			wlocked <- true
-		}
-	}()
-	for i := 0; i < n; i++ {
-		<-rlocked
-		rl.Unlock()
-		select {
-		case <-wlocked:
-			t.Fatal("RLocker() didn't read-lock it")
-		default:
-		}
-		rl.Unlock()
-		<-wlocked
-		select {
-		case <-rlocked:
-			t.Fatal("RLocker() didn't respect the write lock")
-		default:
-		}
-		wl.Unlock()
-	}
-}
-
-func BenchmarkRWMutexUncontended(b *testing.B) {
-	type PaddedRWMutex struct {
-		RWMutex
-		pad [32]uint32
-	}
-	b.RunParallel(func(pb *testing.PB) {
-		var rwm PaddedRWMutex
-		for pb.Next() {
-			rwm.RLock()
-			rwm.RLock()
-			rwm.RUnlock()
-			rwm.RUnlock()
-			rwm.Lock()
-			rwm.Unlock()
-		}
-	})
-}
-
-func benchmarkRWMutex(b *testing.B, localWork, writeRatio int) {
-	var rwm RWMutex
-	b.RunParallel(func(pb *testing.PB) {
-		foo := 0
-		for pb.Next() {
-			foo++
-			if foo%writeRatio == 0 {
-				rwm.Lock()
-				rwm.Unlock()
-			} else {
-				rwm.RLock()
-				for i := 0; i != localWork; i += 1 {
-					foo *= 2
-					foo /= 2
-				}
-				rwm.RUnlock()
-			}
-		}
-		_ = foo
-	})
-}
-
-func BenchmarkRWMutexWrite100(b *testing.B) {
-	benchmarkRWMutex(b, 0, 100)
-}
-
-func BenchmarkRWMutexWrite10(b *testing.B) {
-	benchmarkRWMutex(b, 0, 10)
-}
-
-func BenchmarkRWMutexWorkWrite100(b *testing.B) {
-	benchmarkRWMutex(b, 100, 100)
-}
-
-func BenchmarkRWMutexWorkWrite10(b *testing.B) {
-	benchmarkRWMutex(b, 100, 10)
-}
diff --git a/src/pkg/sync/waitgroup.go b/src/pkg/sync/waitgroup.go
deleted file mode 100644
index 4c64dca..0000000
--- a/src/pkg/sync/waitgroup.go
+++ /dev/null
@@ -1,134 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package sync
-
-import (
-	"sync/atomic"
-	"unsafe"
-)
-
-// A WaitGroup waits for a collection of goroutines to finish.
-// The main goroutine calls Add to set the number of
-// goroutines to wait for.  Then each of the goroutines
-// runs and calls Done when finished.  At the same time,
-// Wait can be used to block until all goroutines have finished.
-type WaitGroup struct {
-	m       Mutex
-	counter int32
-	waiters int32
-	sema    *uint32
-}
-
-// WaitGroup creates a new semaphore each time the old semaphore
-// is released. This is to avoid the following race:
-//
-// G1: Add(1)
-// G1: go G2()
-// G1: Wait() // Context switch after Unlock() and before Semacquire().
-// G2: Done() // Release semaphore: sema == 1, waiters == 0. G1 doesn't run yet.
-// G3: Wait() // Finds counter == 0, waiters == 0, doesn't block.
-// G3: Add(1) // Makes counter == 1, waiters == 0.
-// G3: go G4()
-// G3: Wait() // G1 still hasn't run, G3 finds sema == 1, unblocked! Bug.
-
-// Add adds delta, which may be negative, to the WaitGroup counter.
-// If the counter becomes zero, all goroutines blocked on Wait are released.
-// If the counter goes negative, Add panics.
-//
-// Note that calls with positive delta must happen before the call to Wait,
-// or else Wait may wait for too small a group. Typically this means the calls
-// to Add should execute before the statement creating the goroutine or
-// other event to be waited for. See the WaitGroup example.
-func (wg *WaitGroup) Add(delta int) {
-	if raceenabled {
-		_ = wg.m.state // trigger nil deref early
-		if delta < 0 {
-			// Synchronize decrements with Wait.
-			raceReleaseMerge(unsafe.Pointer(wg))
-		}
-		raceDisable()
-		defer raceEnable()
-	}
-	v := atomic.AddInt32(&wg.counter, int32(delta))
-	if raceenabled {
-		if delta > 0 && v == int32(delta) {
-			// The first increment must be synchronized with Wait.
-			// Need to model this as a read, because there can be
-			// several concurrent wg.counter transitions from 0.
-			raceRead(unsafe.Pointer(&wg.sema))
-		}
-	}
-	if v < 0 {
-		panic("sync: negative WaitGroup counter")
-	}
-	if v > 0 || atomic.LoadInt32(&wg.waiters) == 0 {
-		return
-	}
-	wg.m.Lock()
-	if atomic.LoadInt32(&wg.counter) == 0 {
-		for i := int32(0); i < wg.waiters; i++ {
-			runtime_Semrelease(wg.sema)
-		}
-		wg.waiters = 0
-		wg.sema = nil
-	}
-	wg.m.Unlock()
-}
-
-// Done decrements the WaitGroup counter.
-func (wg *WaitGroup) Done() {
-	wg.Add(-1)
-}
-
-// Wait blocks until the WaitGroup counter is zero.
-func (wg *WaitGroup) Wait() {
-	if raceenabled {
-		_ = wg.m.state // trigger nil deref early
-		raceDisable()
-	}
-	if atomic.LoadInt32(&wg.counter) == 0 {
-		if raceenabled {
-			raceEnable()
-			raceAcquire(unsafe.Pointer(wg))
-		}
-		return
-	}
-	wg.m.Lock()
-	w := atomic.AddInt32(&wg.waiters, 1)
-	// This code is racing with the unlocked path in Add above.
-	// The code above modifies counter and then reads waiters.
-	// We must modify waiters and then read counter (the opposite order)
-	// to avoid missing an Add.
-	if atomic.LoadInt32(&wg.counter) == 0 {
-		atomic.AddInt32(&wg.waiters, -1)
-		if raceenabled {
-			raceEnable()
-			raceAcquire(unsafe.Pointer(wg))
-			raceDisable()
-		}
-		wg.m.Unlock()
-		if raceenabled {
-			raceEnable()
-		}
-		return
-	}
-	if raceenabled && w == 1 {
-		// Wait must be synchronized with the first Add.
-		// Need to model this is as a write to race with the read in Add.
-		// As a consequence, can do the write only for the first waiter,
-		// otherwise concurrent Waits will race with each other.
-		raceWrite(unsafe.Pointer(&wg.sema))
-	}
-	if wg.sema == nil {
-		wg.sema = new(uint32)
-	}
-	s := wg.sema
-	wg.m.Unlock()
-	runtime_Semacquire(s)
-	if raceenabled {
-		raceEnable()
-		raceAcquire(unsafe.Pointer(wg))
-	}
-}
diff --git a/src/pkg/syscall/asm_darwin_386.s b/src/pkg/syscall/asm_darwin_386.s
deleted file mode 100644
index 9b4dfa8..0000000
--- a/src/pkg/syscall/asm_darwin_386.s
+++ /dev/null
@@ -1,142 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// TODO(rsc): Rewrite all nn(SP) references into name+(nn-8)(FP)
-// so that go vet can check that they are correct.
-
-#include "../../cmd/ld/textflag.h"
-
-//
-// System call support for 386, Darwin
-//
-
-// func Syscall(trap int32, a1, a2, a3 int32) (r1, r2, err int32);
-// func Syscall6(trap int32, a1, a2, a3, a4, a5, a6 int32) (r1, r2, err int32);
-// Trap # in AX, args on stack above caller pc.
-
-TEXT	·Syscall(SB),NOSPLIT,$0-28
-	CALL	runtime·entersyscall(SB)
-	MOVL	4(SP), AX	// syscall entry
-	// slide args down on top of system call number
-	LEAL		8(SP), SI
-	LEAL		4(SP), DI
-	CLD
-	MOVSL
-	MOVSL
-	MOVSL
-	INT	$0x80
-	JAE	ok
-	MOVL	$-1, 20(SP)	// r1
-	MOVL	$-1, 24(SP)	// r2
-	MOVL	AX, 28(SP)		// errno
-	CALL	runtime·exitsyscall(SB)
-	RET
-ok:
-	MOVL	AX, 20(SP)	// r1
-	MOVL	DX, 24(SP)	// r2
-	MOVL	$0, 28(SP)	// errno
-	CALL	runtime·exitsyscall(SB)
-	RET
-
-TEXT	·Syscall6(SB),NOSPLIT,$0-40
-	CALL	runtime·entersyscall(SB)
-	MOVL	4(SP), AX	// syscall entry
-	// slide args down on top of system call number
-	LEAL		8(SP), SI
-	LEAL		4(SP), DI
-	CLD
-	MOVSL
-	MOVSL
-	MOVSL
-	MOVSL
-	MOVSL
-	MOVSL
-	INT	$0x80
-	JAE	ok6
-	MOVL	$-1, 32(SP)	// r1
-	MOVL	$-1, 36(SP)	// r2
-	MOVL	AX, 40(SP)		// errno
-	CALL	runtime·exitsyscall(SB)
-	RET
-ok6:
-	MOVL	AX, 32(SP)	// r1
-	MOVL	DX, 36(SP)	// r2
-	MOVL	$0, 40(SP)	// errno
-	CALL	runtime·exitsyscall(SB)
-	RET
-
-TEXT	·Syscall9(SB),NOSPLIT,$0-52
-	CALL	runtime·entersyscall(SB)
-	MOVL	4(SP), AX	// syscall entry
-	// slide args down on top of system call number
-	LEAL		8(SP), SI
-	LEAL		4(SP), DI
-	CLD
-	MOVSL
-	MOVSL
-	MOVSL
-	MOVSL
-	MOVSL
-	MOVSL
-	MOVSL
-	MOVSL
-	MOVSL
-	INT	$0x80
-	JAE	ok9
-	MOVL	$-1, 44(SP)	// r1
-	MOVL	$-1, 48(SP)	// r2
-	MOVL	AX, 52(SP)		// errno
-	CALL	runtime·exitsyscall(SB)
-	RET
-ok9:
-	MOVL	AX, 44(SP)	// r1
-	MOVL	DX, 48(SP)	// r2
-	MOVL	$0, 52(SP)	// errno
-	CALL	runtime·exitsyscall(SB)
-	RET
-
-TEXT ·RawSyscall(SB),NOSPLIT,$0-28
-	MOVL	4(SP), AX	// syscall entry
-	// slide args down on top of system call number
-	LEAL		8(SP), SI
-	LEAL		4(SP), DI
-	CLD
-	MOVSL
-	MOVSL
-	MOVSL
-	INT	$0x80
-	JAE	ok1
-	MOVL	$-1, 20(SP)	// r1
-	MOVL	$-1, 24(SP)	// r2
-	MOVL	AX, 28(SP)		// errno
-	RET
-ok1:
-	MOVL	AX, 20(SP)	// r1
-	MOVL	DX, 24(SP)	// r2
-	MOVL	$0, 28(SP)	// errno
-	RET
-
-TEXT	·RawSyscall6(SB),NOSPLIT,$0-40
-	MOVL	4(SP), AX	// syscall entry
-	// slide args down on top of system call number
-	LEAL		8(SP), SI
-	LEAL		4(SP), DI
-	CLD
-	MOVSL
-	MOVSL
-	MOVSL
-	MOVSL
-	MOVSL
-	MOVSL
-	INT	$0x80
-	JAE	ok2
-	MOVL	$-1, 32(SP)	// r1
-	MOVL	$-1, 36(SP)	// r2
-	MOVL	AX, 40(SP)		// errno
-	RET
-ok2:
-	MOVL	AX, 32(SP)	// r1
-	MOVL	DX, 36(SP)	// r2
-	MOVL	$0, 40(SP)	// errno
-	RET
diff --git a/src/pkg/syscall/asm_darwin_amd64.s b/src/pkg/syscall/asm_darwin_amd64.s
deleted file mode 100644
index 19ea05b..0000000
--- a/src/pkg/syscall/asm_darwin_amd64.s
+++ /dev/null
@@ -1,106 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// TODO(rsc): Rewrite all nn(SP) references into name+(nn-8)(FP)
-// so that go vet can check that they are correct.
-
-#include "../../cmd/ld/textflag.h"
-
-//
-// System call support for AMD64, Darwin
-//
-
-// func Syscall(trap int64, a1, a2, a3 int64) (r1, r2, err int64);
-// func Syscall6(trap int64, a1, a2, a3, a4, a5, a6 int64) (r1, r2, err int64);
-// Trap # in AX, args in DI SI DX, return in AX DX
-
-TEXT	·Syscall(SB),NOSPLIT,$0-56
-	CALL	runtime·entersyscall(SB)
-	MOVQ	16(SP), DI
-	MOVQ	24(SP), SI
-	MOVQ	32(SP), DX
-	MOVQ	$0, R10
-	MOVQ	$0, R8
-	MOVQ	$0, R9
-	MOVQ	8(SP), AX	// syscall entry
-	ADDQ	$0x2000000, AX
-	SYSCALL
-	JCC	ok
-	MOVQ	$-1, 40(SP)	// r1
-	MOVQ	$0, 48(SP)	// r2
-	MOVQ	AX, 56(SP)  // errno
-	CALL	runtime·exitsyscall(SB)
-	RET
-ok:
-	MOVQ	AX, 40(SP)	// r1
-	MOVQ	DX, 48(SP)	// r2
-	MOVQ	$0, 56(SP)	// errno
-	CALL	runtime·exitsyscall(SB)
-	RET
-
-TEXT	·Syscall6(SB),NOSPLIT,$0-80
-	CALL	runtime·entersyscall(SB)
-	MOVQ	16(SP), DI
-	MOVQ	24(SP), SI
-	MOVQ	32(SP), DX
-	MOVQ	40(SP), R10
-	MOVQ	48(SP), R8
-	MOVQ	56(SP), R9
-	MOVQ	8(SP), AX	// syscall entry
-	ADDQ	$0x2000000, AX
-	SYSCALL
-	JCC	ok6
-	MOVQ	$-1, 64(SP)	// r1
-	MOVQ	$0, 72(SP)	// r2
-	MOVQ	AX, 80(SP)  // errno
-	CALL	runtime·exitsyscall(SB)
-	RET
-ok6:
-	MOVQ	AX, 64(SP)	// r1
-	MOVQ	DX, 72(SP)	// r2
-	MOVQ	$0, 80(SP)	// errno
-	CALL	runtime·exitsyscall(SB)
-	RET
-
-TEXT ·RawSyscall(SB),NOSPLIT,$0-56
-	MOVQ	16(SP), DI
-	MOVQ	24(SP), SI
-	MOVQ	32(SP), DX
-	MOVQ	$0, R10
-	MOVQ	$0, R8
-	MOVQ	$0, R9
-	MOVQ	8(SP), AX	// syscall entry
-	ADDQ	$0x2000000, AX
-	SYSCALL
-	JCC	ok1
-	MOVQ	$-1, 40(SP)	// r1
-	MOVQ	$0, 48(SP)	// r2
-	MOVQ	AX, 56(SP)  // errno
-	RET
-ok1:
-	MOVQ	AX, 40(SP)	// r1
-	MOVQ	DX, 48(SP)	// r2
-	MOVQ	$0, 56(SP)	// errno
-	RET
-
-TEXT	·RawSyscall6(SB),NOSPLIT,$0-80
-	MOVQ	16(SP), DI
-	MOVQ	24(SP), SI
-	MOVQ	32(SP), DX
-	MOVQ	40(SP), R10
-	MOVQ	48(SP), R8
-	MOVQ	56(SP), R9
-	MOVQ	8(SP), AX	// syscall entry
-	ADDQ	$0x2000000, AX
-	SYSCALL
-	JCC	ok2
-	MOVQ	$-1, 64(SP)	// r1
-	MOVQ	$0, 72(SP)	// r2
-	MOVQ	AX, 80(SP)  // errno
-	RET
-ok2:
-	MOVQ	AX, 64(SP)	// r1
-	MOVQ	DX, 72(SP)	// r2
-	MOVQ	$0, 80(SP)	// errno
-	RET
diff --git a/src/pkg/syscall/asm_dragonfly_386.s b/src/pkg/syscall/asm_dragonfly_386.s
deleted file mode 100644
index d24216f..0000000
--- a/src/pkg/syscall/asm_dragonfly_386.s
+++ /dev/null
@@ -1,139 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../cmd/ld/textflag.h"
-
-//
-// System call support for 386, FreeBSD
-//
-
-// func Syscall(trap int32, a1, a2, a3 int32) (r1, r2, err int32);
-// func Syscall6(trap int32, a1, a2, a3, a4, a5, a6 int32) (r1, r2, err int32);
-// Trap # in AX, args on stack above caller pc.
-
-TEXT	·Syscall(SB),NOSPLIT,$0-32
-	CALL	runtime·entersyscall(SB)
-	MOVL	4(SP), AX	// syscall entry
-	// slide args down on top of system call number
-	LEAL		8(SP), SI
-	LEAL		4(SP), DI
-	CLD
-	MOVSL
-	MOVSL
-	MOVSL
-	INT	$0x80
-	JAE	ok
-	MOVL	$-1, 20(SP)	// r1
-	MOVL	$-1, 24(SP)	// r2
-	MOVL	AX, 28(SP)		// errno
-	CALL	runtime·exitsyscall(SB)
-	RET
-ok:
-	MOVL	AX, 20(SP)	// r1
-	MOVL	DX, 24(SP)	// r2
-	MOVL	$0, 28(SP)	// errno
-	CALL	runtime·exitsyscall(SB)
-	RET
-
-TEXT	·Syscall6(SB),NOSPLIT,$0-44
-	CALL	runtime·entersyscall(SB)
-	MOVL	4(SP), AX	// syscall entry
-	// slide args down on top of system call number
-	LEAL		8(SP), SI
-	LEAL		4(SP), DI
-	CLD
-	MOVSL
-	MOVSL
-	MOVSL
-	MOVSL
-	MOVSL
-	MOVSL
-	INT	$0x80
-	JAE	ok6
-	MOVL	$-1, 32(SP)	// r1
-	MOVL	$-1, 36(SP)	// r2
-	MOVL	AX, 40(SP)		// errno
-	CALL	runtime·exitsyscall(SB)
-	RET
-ok6:
-	MOVL	AX, 32(SP)	// r1
-	MOVL	DX, 36(SP)	// r2
-	MOVL	$0, 40(SP)	// errno
-	CALL	runtime·exitsyscall(SB)
-	RET
-
-TEXT	·Syscall9(SB),NOSPLIT,$0-56
-	CALL	runtime·entersyscall(SB)
-	MOVL	4(SP), AX	// syscall entry
-	// slide args down on top of system call number
-	LEAL		8(SP), SI
-	LEAL		4(SP), DI
-	CLD
-	MOVSL
-	MOVSL
-	MOVSL
-	MOVSL
-	MOVSL
-	MOVSL
-	MOVSL
-	MOVSL
-	MOVSL
-	INT	$0x80
-	JAE	ok9
-	MOVL	$-1, 44(SP)	// r1
-	MOVL	$-1, 48(SP)	// r2
-	MOVL	AX, 52(SP)		// errno
-	CALL	runtime·exitsyscall(SB)
-	RET
-ok9:
-	MOVL	AX, 44(SP)	// r1
-	MOVL	DX, 48(SP)	// r2
-	MOVL	$0, 52(SP)	// errno
-	CALL	runtime·exitsyscall(SB)
-	RET
-
-TEXT ·RawSyscall(SB),NOSPLIT,$0-32
-	MOVL	4(SP), AX	// syscall entry
-	// slide args down on top of system call number
-	LEAL		8(SP), SI
-	LEAL		4(SP), DI
-	CLD
-	MOVSL
-	MOVSL
-	MOVSL
-	INT	$0x80
-	JAE	ok1
-	MOVL	$-1, 20(SP)	// r1
-	MOVL	$-1, 24(SP)	// r2
-	MOVL	AX, 28(SP)		// errno
-	RET
-ok1:
-	MOVL	AX, 20(SP)	// r1
-	MOVL	DX, 24(SP)	// r2
-	MOVL	$0, 28(SP)	// errno
-	RET
-
-TEXT	·RawSyscall6(SB),NOSPLIT,$0-44
-	MOVL	4(SP), AX	// syscall entry
-	// slide args down on top of system call number
-	LEAL		8(SP), SI
-	LEAL		4(SP), DI
-	CLD
-	MOVSL
-	MOVSL
-	MOVSL
-	MOVSL
-	MOVSL
-	MOVSL
-	INT	$0x80
-	JAE	ok2
-	MOVL	$-1, 32(SP)	// r1
-	MOVL	$-1, 36(SP)	// r2
-	MOVL	AX, 40(SP)		// errno
-	RET
-ok2:
-	MOVL	AX, 32(SP)	// r1
-	MOVL	DX, 36(SP)	// r2
-	MOVL	$0, 40(SP)	// errno
-	RET
diff --git a/src/pkg/syscall/asm_dragonfly_amd64.s b/src/pkg/syscall/asm_dragonfly_amd64.s
deleted file mode 100644
index 31d1074..0000000
--- a/src/pkg/syscall/asm_dragonfly_amd64.s
+++ /dev/null
@@ -1,133 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../cmd/ld/textflag.h"
-
-//
-// System call support for AMD64, DragonFly
-//
-
-// func Syscall(trap int64, a1, a2, a3 int64) (r1, r2, err int64);
-// func Syscall6(trap int64, a1, a2, a3, a4, a5, a6 int64) (r1, r2, err int64);
-// func Syscall9(trap int64, a1, a2, a3, a4, a5, a6, a7, a8, a9 int64) (r1, r2, err int64)
-// Trap # in AX, args in DI SI DX, return in AX DX
-
-TEXT	·Syscall(SB),NOSPLIT,$0-64
-	CALL	runtime·entersyscall(SB)
-	MOVQ	16(SP), DI
-	MOVQ	24(SP), SI
-	MOVQ	32(SP), DX
-	MOVQ	$0, R10
-	MOVQ	$0, R8
-	MOVQ	$0, R9
-	MOVQ	8(SP), AX	// syscall entry
-	SYSCALL
-	JCC	ok
-	MOVQ	$-1, 40(SP)	// r1
-	MOVQ	$0, 48(SP)	// r2
-	MOVQ	AX, 56(SP)  // errno
-	CALL	runtime·exitsyscall(SB)
-	RET
-ok:
-	MOVQ	AX, 40(SP)	// r1
-	MOVQ	DX, 48(SP)	// r2
-	MOVQ	$0, 56(SP)	// errno
-	CALL	runtime·exitsyscall(SB)
-	RET
-
-TEXT	·Syscall6(SB),NOSPLIT,$0-88
-	CALL	runtime·entersyscall(SB)
-	MOVQ	16(SP), DI
-	MOVQ	24(SP), SI
-	MOVQ	32(SP), DX
-	MOVQ	40(SP), R10
-	MOVQ	48(SP), R8
-	MOVQ	56(SP), R9
-	MOVQ	8(SP), AX	// syscall entry
-	SYSCALL
-	JCC	ok6
-	MOVQ	$-1, 64(SP)	// r1
-	MOVQ	$0, 72(SP)	// r2
-	MOVQ	AX, 80(SP)  // errno
-	CALL	runtime·exitsyscall(SB)
-	RET
-ok6:
-	MOVQ	AX, 64(SP)	// r1
-	MOVQ	DX, 72(SP)	// r2
-	MOVQ	$0, 80(SP)	// errno
-	CALL	runtime·exitsyscall(SB)
-	RET
-
-TEXT	·Syscall9(SB),NOSPLIT,$0-112
-	CALL	runtime·entersyscall(SB)
-	MOVQ	8(SP), AX
-	MOVQ	16(SP), DI
-	MOVQ	24(SP), SI
-	MOVQ	32(SP), DX
-	MOVQ	40(SP),	R10
-	MOVQ	48(SP), R8
-	MOVQ	56(SP), R9
-
-	// shift around the last three arguments so they're at the
-	// top of the stack when the syscall is called.
-	MOVQ	64(SP), R11 // arg 7
-	MOVQ	R11, 8(SP)
-	MOVQ	72(SP), R11 // arg 8
-	MOVQ	R11, 16(SP)
-	MOVQ	80(SP), R11 // arg 9
-	MOVQ	R11, 24(SP)
-
-	SYSCALL
-	JCC	ok9
-	MOVQ	$-1, 88(SP)	// r1
-	MOVQ	$0, 96(SP)	// r2
-	MOVQ	AX, 104(SP)  // errno
-	CALL	runtime·exitsyscall(SB)
-	RET
-ok9:
-	MOVQ	AX, 88(SP)	// r1
-	MOVQ	DX, 96(SP)	// r2
-	MOVQ	$0, 104(SP)	// errno
-	CALL	runtime·exitsyscall(SB)
-	RET
-
-TEXT ·RawSyscall(SB),NOSPLIT,$0-64
-	MOVQ	16(SP), DI
-	MOVQ	24(SP), SI
-	MOVQ	32(SP), DX
-	MOVQ	$0, R10
-	MOVQ	$0, R8
-	MOVQ	$0, R9
-	MOVQ	8(SP), AX	// syscall entry
-	SYSCALL
-	JCC	ok1
-	MOVQ	$-1, 40(SP)	// r1
-	MOVQ	$0, 48(SP)	// r2
-	MOVQ	AX, 56(SP)  // errno
-	RET
-ok1:
-	MOVQ	AX, 40(SP)	// r1
-	MOVQ	DX, 48(SP)	// r2
-	MOVQ	$0, 56(SP)	// errno
-	RET
-
-TEXT	·RawSyscall6(SB),NOSPLIT,$0-88
-	MOVQ	16(SP), DI
-	MOVQ	24(SP), SI
-	MOVQ	32(SP), DX
-	MOVQ	40(SP), R10
-	MOVQ	48(SP), R8
-	MOVQ	56(SP), R9
-	MOVQ	8(SP), AX	// syscall entry
-	SYSCALL
-	JCC	ok2
-	MOVQ	$-1, 64(SP)	// r1
-	MOVQ	$0, 72(SP)	// r2
-	MOVQ	AX, 80(SP)  // errno
-	RET
-ok2:
-	MOVQ	AX, 64(SP)	// r1
-	MOVQ	DX, 72(SP)	// r2
-	MOVQ	$0, 80(SP)	// errno
-	RET
diff --git a/src/pkg/syscall/asm_freebsd_386.s b/src/pkg/syscall/asm_freebsd_386.s
deleted file mode 100644
index 91a46b1..0000000
--- a/src/pkg/syscall/asm_freebsd_386.s
+++ /dev/null
@@ -1,142 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// TODO(rsc): Rewrite all nn(SP) references into name+(nn-8)(FP)
-// so that go vet can check that they are correct.
-
-#include "../../cmd/ld/textflag.h"
-
-//
-// System call support for 386, FreeBSD
-//
-
-// func Syscall(trap int32, a1, a2, a3 int32) (r1, r2, err int32);
-// func Syscall6(trap int32, a1, a2, a3, a4, a5, a6 int32) (r1, r2, err int32);
-// Trap # in AX, args on stack above caller pc.
-
-TEXT	·Syscall(SB),NOSPLIT,$0-28
-	CALL	runtime·entersyscall(SB)
-	MOVL	4(SP), AX	// syscall entry
-	// slide args down on top of system call number
-	LEAL		8(SP), SI
-	LEAL		4(SP), DI
-	CLD
-	MOVSL
-	MOVSL
-	MOVSL
-	INT	$0x80
-	JAE	ok
-	MOVL	$-1, 20(SP)	// r1
-	MOVL	$-1, 24(SP)	// r2
-	MOVL	AX, 28(SP)		// errno
-	CALL	runtime·exitsyscall(SB)
-	RET
-ok:
-	MOVL	AX, 20(SP)	// r1
-	MOVL	DX, 24(SP)	// r2
-	MOVL	$0, 28(SP)	// errno
-	CALL	runtime·exitsyscall(SB)
-	RET
-
-TEXT	·Syscall6(SB),NOSPLIT,$0-40
-	CALL	runtime·entersyscall(SB)
-	MOVL	4(SP), AX	// syscall entry
-	// slide args down on top of system call number
-	LEAL		8(SP), SI
-	LEAL		4(SP), DI
-	CLD
-	MOVSL
-	MOVSL
-	MOVSL
-	MOVSL
-	MOVSL
-	MOVSL
-	INT	$0x80
-	JAE	ok6
-	MOVL	$-1, 32(SP)	// r1
-	MOVL	$-1, 36(SP)	// r2
-	MOVL	AX, 40(SP)		// errno
-	CALL	runtime·exitsyscall(SB)
-	RET
-ok6:
-	MOVL	AX, 32(SP)	// r1
-	MOVL	DX, 36(SP)	// r2
-	MOVL	$0, 40(SP)	// errno
-	CALL	runtime·exitsyscall(SB)
-	RET
-
-TEXT	·Syscall9(SB),NOSPLIT,$0-52
-	CALL	runtime·entersyscall(SB)
-	MOVL	4(SP), AX	// syscall entry
-	// slide args down on top of system call number
-	LEAL		8(SP), SI
-	LEAL		4(SP), DI
-	CLD
-	MOVSL
-	MOVSL
-	MOVSL
-	MOVSL
-	MOVSL
-	MOVSL
-	MOVSL
-	MOVSL
-	MOVSL
-	INT	$0x80
-	JAE	ok9
-	MOVL	$-1, 44(SP)	// r1
-	MOVL	$-1, 48(SP)	// r2
-	MOVL	AX, 52(SP)		// errno
-	CALL	runtime·exitsyscall(SB)
-	RET
-ok9:
-	MOVL	AX, 44(SP)	// r1
-	MOVL	DX, 48(SP)	// r2
-	MOVL	$0, 52(SP)	// errno
-	CALL	runtime·exitsyscall(SB)
-	RET
-
-TEXT ·RawSyscall(SB),NOSPLIT,$0-28
-	MOVL	4(SP), AX	// syscall entry
-	// slide args down on top of system call number
-	LEAL		8(SP), SI
-	LEAL		4(SP), DI
-	CLD
-	MOVSL
-	MOVSL
-	MOVSL
-	INT	$0x80
-	JAE	ok1
-	MOVL	$-1, 20(SP)	// r1
-	MOVL	$-1, 24(SP)	// r2
-	MOVL	AX, 28(SP)		// errno
-	RET
-ok1:
-	MOVL	AX, 20(SP)	// r1
-	MOVL	DX, 24(SP)	// r2
-	MOVL	$0, 28(SP)	// errno
-	RET
-
-TEXT	·RawSyscall6(SB),NOSPLIT,$0-40
-	MOVL	4(SP), AX	// syscall entry
-	// slide args down on top of system call number
-	LEAL		8(SP), SI
-	LEAL		4(SP), DI
-	CLD
-	MOVSL
-	MOVSL
-	MOVSL
-	MOVSL
-	MOVSL
-	MOVSL
-	INT	$0x80
-	JAE	ok2
-	MOVL	$-1, 32(SP)	// r1
-	MOVL	$-1, 36(SP)	// r2
-	MOVL	AX, 40(SP)		// errno
-	RET
-ok2:
-	MOVL	AX, 32(SP)	// r1
-	MOVL	DX, 36(SP)	// r2
-	MOVL	$0, 40(SP)	// errno
-	RET
diff --git a/src/pkg/syscall/asm_freebsd_amd64.s b/src/pkg/syscall/asm_freebsd_amd64.s
deleted file mode 100644
index 7abb368..0000000
--- a/src/pkg/syscall/asm_freebsd_amd64.s
+++ /dev/null
@@ -1,141 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// TODO(rsc): Rewrite all nn(SP) references into name+(nn-8)(FP)
-// so that go vet can check that they are correct.
-
-#include "../../cmd/ld/textflag.h"
-
-//
-// System call support for AMD64, FreeBSD
-//
-
-// The SYSCALL variant for invoking system calls is broken in FreeBSD.
-// See comment at top of ../runtime/sys_freebsd_amd64.c and
-// golang.org/issue/6372.
-#define SYSCALL MOVQ R10, CX; INT $0x80
-
-// func Syscall(trap int64, a1, a2, a3 int64) (r1, r2, err int64);
-// func Syscall6(trap int64, a1, a2, a3, a4, a5, a6 int64) (r1, r2, err int64);
-// func Syscall9(trap int64, a1, a2, a3, a4, a5, a6, a7, a8, a9 int64) (r1, r2, err int64)
-// Trap # in AX, args in DI SI DX, return in AX DX
-
-TEXT	·Syscall(SB),NOSPLIT,$0-56
-	CALL	runtime·entersyscall(SB)
-	MOVQ	16(SP), DI
-	MOVQ	24(SP), SI
-	MOVQ	32(SP), DX
-	MOVQ	$0, R10
-	MOVQ	$0, R8
-	MOVQ	$0, R9
-	MOVQ	8(SP), AX	// syscall entry
-	SYSCALL
-	JCC	ok
-	MOVQ	$-1, 40(SP)	// r1
-	MOVQ	$0, 48(SP)	// r2
-	MOVQ	AX, 56(SP)  // errno
-	CALL	runtime·exitsyscall(SB)
-	RET
-ok:
-	MOVQ	AX, 40(SP)	// r1
-	MOVQ	DX, 48(SP)	// r2
-	MOVQ	$0, 56(SP)	// errno
-	CALL	runtime·exitsyscall(SB)
-	RET
-
-TEXT	·Syscall6(SB),NOSPLIT,$0-80
-	CALL	runtime·entersyscall(SB)
-	MOVQ	16(SP), DI
-	MOVQ	24(SP), SI
-	MOVQ	32(SP), DX
-	MOVQ	40(SP), R10
-	MOVQ	48(SP), R8
-	MOVQ	56(SP), R9
-	MOVQ	8(SP), AX	// syscall entry
-	SYSCALL
-	JCC	ok6
-	MOVQ	$-1, 64(SP)	// r1
-	MOVQ	$0, 72(SP)	// r2
-	MOVQ	AX, 80(SP)  // errno
-	CALL	runtime·exitsyscall(SB)
-	RET
-ok6:
-	MOVQ	AX, 64(SP)	// r1
-	MOVQ	DX, 72(SP)	// r2
-	MOVQ	$0, 80(SP)	// errno
-	CALL	runtime·exitsyscall(SB)
-	RET
-
-TEXT	·Syscall9(SB),NOSPLIT,$0-104
-	CALL	runtime·entersyscall(SB)
-	MOVQ	8(SP), AX
-	MOVQ	16(SP), DI
-	MOVQ	24(SP), SI
-	MOVQ	32(SP), DX
-	MOVQ	40(SP),	R10
-	MOVQ	48(SP), R8
-	MOVQ	56(SP), R9
-
-	// shift around the last three arguments so they're at the
-	// top of the stack when the syscall is called.
-	MOVQ	64(SP), R11 // arg 7
-	MOVQ	R11, 8(SP)
-	MOVQ	72(SP), R11 // arg 8
-	MOVQ	R11, 16(SP)
-	MOVQ	80(SP), R11 // arg 9
-	MOVQ	R11, 24(SP)
-
-	SYSCALL
-	JCC	ok9
-	MOVQ	$-1, 88(SP)	// r1
-	MOVQ	$0, 96(SP)	// r2
-	MOVQ	AX, 104(SP)  // errno
-	CALL	runtime·exitsyscall(SB)
-	RET
-ok9:
-	MOVQ	AX, 88(SP)	// r1
-	MOVQ	DX, 96(SP)	// r2
-	MOVQ	$0, 104(SP)	// errno
-	CALL	runtime·exitsyscall(SB)
-	RET
-
-TEXT ·RawSyscall(SB),NOSPLIT,$0-56
-	MOVQ	16(SP), DI
-	MOVQ	24(SP), SI
-	MOVQ	32(SP), DX
-	MOVQ	$0, R10
-	MOVQ	$0, R8
-	MOVQ	$0, R9
-	MOVQ	8(SP), AX	// syscall entry
-	SYSCALL
-	JCC	ok1
-	MOVQ	$-1, 40(SP)	// r1
-	MOVQ	$0, 48(SP)	// r2
-	MOVQ	AX, 56(SP)  // errno
-	RET
-ok1:
-	MOVQ	AX, 40(SP)	// r1
-	MOVQ	DX, 48(SP)	// r2
-	MOVQ	$0, 56(SP)	// errno
-	RET
-
-TEXT	·RawSyscall6(SB),NOSPLIT,$0-80
-	MOVQ	16(SP), DI
-	MOVQ	24(SP), SI
-	MOVQ	32(SP), DX
-	MOVQ	40(SP), R10
-	MOVQ	48(SP), R8
-	MOVQ	56(SP), R9
-	MOVQ	8(SP), AX	// syscall entry
-	SYSCALL
-	JCC	ok2
-	MOVQ	$-1, 64(SP)	// r1
-	MOVQ	$0, 72(SP)	// r2
-	MOVQ	AX, 80(SP)  // errno
-	RET
-ok2:
-	MOVQ	AX, 64(SP)	// r1
-	MOVQ	DX, 72(SP)	// r2
-	MOVQ	$0, 80(SP)	// errno
-	RET
diff --git a/src/pkg/syscall/asm_freebsd_arm.s b/src/pkg/syscall/asm_freebsd_arm.s
deleted file mode 100644
index c01ce6f..0000000
--- a/src/pkg/syscall/asm_freebsd_arm.s
+++ /dev/null
@@ -1,129 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../cmd/ld/textflag.h"
-
-//
-// System call support for ARM, FreeBSD
-//
-
-// func Syscall(trap, a1, a2, a3 uintptr) (r1, r2, errno uintptr);
-// func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, errno uintptr);
-// func Syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2, errno uintptr)
-
-TEXT	·Syscall(SB),NOSPLIT,$0-28
-	BL runtime·entersyscall(SB)
-	MOVW 0(FP), R7 // syscall number
-	MOVW 4(FP), R0 // a1
-	MOVW 8(FP), R1 // a2
-	MOVW 12(FP), R2 // a3
-	SWI $0 // syscall
-	MOVW $0, R2
-	BCS error
-	MOVW R0, 16(FP) // r1
-	MOVW R1, 20(FP) // r2
-	MOVW R2, 24(FP) // errno
-	BL runtime·exitsyscall(SB)
-	RET
-error:
-	MOVW $-1, R3
-	MOVW R3, 16(FP) // r1
-	MOVW R2, 20(FP) // r2
-	MOVW R0, 24(FP) // errno
-	BL runtime·exitsyscall(SB)
-	RET
-
-TEXT	·Syscall6(SB),NOSPLIT,$0-40
-	BL runtime·entersyscall(SB)
-	MOVW 0(FP), R7 // syscall number
-	MOVW 4(FP), R0 // a1
-	MOVW 8(FP), R1 // a2
-	MOVW 12(FP), R2 // a3
-	MOVW 16(FP), R3 // a4
-	MOVW R13, R4
-	MOVW $20(FP), R13 // a5 to a6 are passed on stack
-	SWI $0 // syscall
-	MOVW R4, R13
-	MOVW $0, R2
-	BCS error6
-	MOVW R0, 28(FP) // r1
-	MOVW R1, 32(FP) // r2
-	MOVW R2, 36(FP) // errno
-	BL runtime·exitsyscall(SB)
-	RET
-error6:
-	MOVW $-1, R3
-	MOVW R3, 28(FP) // r1
-	MOVW R2, 32(FP) // r2
-	MOVW R0, 36(FP) // errno
-	BL runtime·exitsyscall(SB)
-	RET
-
-TEXT	·Syscall9(SB),NOSPLIT,$0-52
-	BL runtime·entersyscall(SB)
-	MOVW 0(FP), R7 // syscall number
-	MOVW 4(FP), R0 // a1
-	MOVW 8(FP), R1 // a2
-	MOVW 12(FP), R2 // a3
-	MOVW 16(FP), R3 // a4
-	MOVW R13, R4
-	MOVW $20(FP), R13 // a5 to a9 are passed on stack
-	SWI $0 // syscall
-	MOVW R4, R13
-	MOVW $0, R2
-	BCS error9
-	MOVW R0, 40(FP) // r1
-	MOVW R1, 44(FP) // r2
-	MOVW R2, 48(FP) // errno
-	BL runtime·exitsyscall(SB)
-	RET
-error9:
-	MOVW $-1, R3
-	MOVW R3, 40(FP) // r1
-	MOVW R2, 44(FP) // r2
-	MOVW R0, 48(FP) // errno
-	BL runtime·exitsyscall(SB)
-	RET
-
-TEXT	·RawSyscall(SB),NOSPLIT,$0-28
-	MOVW 0(FP), R7 // syscall number
-	MOVW 4(FP), R0 // a1
-	MOVW 8(FP), R1 // a2
-	MOVW 12(FP), R2 // a3
-	SWI $0 // syscall
-	MOVW $0, R2
-	BCS errorr
-	MOVW R0, 16(FP) // r1
-	MOVW R1, 20(FP) // r2
-	MOVW R2, 24(FP) // errno
-	RET
-errorr:
-	MOVW $-1, R3
-	MOVW R3, 16(FP) // r1
-	MOVW R2, 20(FP) // r2
-	MOVW R0, 24(FP) // errno
-	RET
-
-TEXT	·RawSyscall6(SB),NOSPLIT,$0-40
-	MOVW 0(FP), R7 // syscall number
-	MOVW 4(FP), R0 // a1
-	MOVW 8(FP), R1 // a2
-	MOVW 12(FP), R2 // a3
-	MOVW 16(FP), R3 // a4
-	MOVW R13, R4
-	MOVW $20(FP), R13 // a5 to a6 are passed on stack
-	SWI $0 // syscall
-	MOVW R4, R13
-	MOVW $0, R2
-	BCS errorr6
-	MOVW R0, 28(FP) // r1
-	MOVW R1, 32(FP) // r2
-	MOVW R2, 36(FP) // errno
-	RET
-errorr6:
-	MOVW $-1, R3
-	MOVW R3, 28(FP) // r1
-	MOVW R2, 32(FP) // r2
-	MOVW R0, 36(FP) // errno
-	RET
diff --git a/src/pkg/syscall/asm_linux_386.s b/src/pkg/syscall/asm_linux_386.s
deleted file mode 100644
index 30b2207..0000000
--- a/src/pkg/syscall/asm_linux_386.s
+++ /dev/null
@@ -1,186 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// TODO(rsc): Rewrite all nn(SP) references into name+(nn-8)(FP)
-// so that go vet can check that they are correct.
-
-#include "../../cmd/ld/textflag.h"
-
-//
-// System calls for 386, Linux
-//
-
-// func Syscall(trap uintptr, a1, a2, a3 uintptr) (r1, r2, err uintptr);
-// Trap # in AX, args in BX CX DX SI DI, return in AX
-
-TEXT	·Syscall(SB),NOSPLIT,$0-28
-	CALL	runtime·entersyscall(SB)
-	MOVL	4(SP), AX	// syscall entry
-	MOVL	8(SP), BX
-	MOVL	12(SP), CX
-	MOVL	16(SP), DX
-	MOVL	$0, SI
-	MOVL	$0,  DI
-	CALL	*runtime·_vdso(SB)
-	CMPL	AX, $0xfffff001
-	JLS	ok
-	MOVL	$-1, 20(SP)	// r1
-	MOVL	$0, 24(SP)	// r2
-	NEGL	AX
-	MOVL	AX, 28(SP)  // errno
-	CALL	runtime·exitsyscall(SB)
-	RET
-ok:
-	MOVL	AX, 20(SP)	// r1
-	MOVL	DX, 24(SP)	// r2
-	MOVL	$0, 28(SP)	// errno
-	CALL	runtime·exitsyscall(SB)
-	RET
-
-// func Syscall6(trap uintptr, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr);
-TEXT	·Syscall6(SB),NOSPLIT,$0-40
-	CALL	runtime·entersyscall(SB)
-	MOVL	4(SP), AX	// syscall entry
-	MOVL	8(SP), BX
-	MOVL	12(SP), CX
-	MOVL	16(SP), DX
-	MOVL	20(SP), SI
-	MOVL	24(SP), DI
-	MOVL	28(SP), BP
-	CALL	*runtime·_vdso(SB)
-	CMPL	AX, $0xfffff001
-	JLS	ok6
-	MOVL	$-1, 32(SP)	// r1
-	MOVL	$0, 36(SP)	// r2
-	NEGL	AX
-	MOVL	AX, 40(SP)  // errno
-	CALL	runtime·exitsyscall(SB)
-	RET
-ok6:
-	MOVL	AX, 32(SP)	// r1
-	MOVL	DX, 36(SP)	// r2
-	MOVL	$0, 40(SP)	// errno
-	CALL	runtime·exitsyscall(SB)
-	RET
-
-// func RawSyscall(trap uintptr, a1, a2, a3 uintptr) (r1, r2, err uintptr);
-TEXT ·RawSyscall(SB),NOSPLIT,$0-28
-	MOVL	4(SP), AX	// syscall entry
-	MOVL	8(SP), BX
-	MOVL	12(SP), CX
-	MOVL	16(SP), DX
-	MOVL	$0, SI
-	MOVL	$0,  DI
-	CALL	*runtime·_vdso(SB)
-	CMPL	AX, $0xfffff001
-	JLS	ok1
-	MOVL	$-1, 20(SP)	// r1
-	MOVL	$0, 24(SP)	// r2
-	NEGL	AX
-	MOVL	AX, 28(SP)  // errno
-	RET
-ok1:
-	MOVL	AX, 20(SP)	// r1
-	MOVL	DX, 24(SP)	// r2
-	MOVL	$0, 28(SP)	// errno
-	RET
-
-// func RawSyscall6(trap uintptr, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr);
-TEXT	·RawSyscall6(SB),NOSPLIT,$0-40
-	MOVL	4(SP), AX	// syscall entry
-	MOVL	8(SP), BX
-	MOVL	12(SP), CX
-	MOVL	16(SP), DX
-	MOVL	20(SP), SI
-	MOVL	24(SP), DI
-	MOVL	28(SP), BP
-	CALL	*runtime·_vdso(SB)
-	CMPL	AX, $0xfffff001
-	JLS	ok2
-	MOVL	$-1, 32(SP)	// r1
-	MOVL	$0, 36(SP)	// r2
-	NEGL	AX
-	MOVL	AX, 40(SP)  // errno
-	RET
-ok2:
-	MOVL	AX, 32(SP)	// r1
-	MOVL	DX, 36(SP)	// r2
-	MOVL	$0, 40(SP)	// errno
-	RET
-
-#define SYS_SOCKETCALL 102	/* from zsysnum_linux_386.go */
-
-// func socketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (n int, errno int)
-// Kernel interface gets call sub-number and pointer to a0.
-TEXT ·socketcall(SB),NOSPLIT,$0-36
-	CALL	runtime·entersyscall(SB)
-	MOVL	$SYS_SOCKETCALL, AX	// syscall entry
-	MOVL	4(SP), BX	// socket call number
-	LEAL		8(SP), CX	// pointer to call arguments
-	MOVL	$0, DX
-	MOVL	$0, SI
-	MOVL	$0,  DI
-	CALL	*runtime·_vdso(SB)
-	CMPL	AX, $0xfffff001
-	JLS	oksock
-	MOVL	$-1, 32(SP)	// n
-	NEGL	AX
-	MOVL	AX, 36(SP)  // errno
-	CALL	runtime·exitsyscall(SB)
-	RET
-oksock:
-	MOVL	AX, 32(SP)	// n
-	MOVL	$0, 36(SP)	// errno
-	CALL	runtime·exitsyscall(SB)
-	RET
-
-// func rawsocketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (n int, errno int)
-// Kernel interface gets call sub-number and pointer to a0.
-TEXT ·rawsocketcall(SB),NOSPLIT,$0-36
-	MOVL	$SYS_SOCKETCALL, AX	// syscall entry
-	MOVL	4(SP), BX	// socket call number
-	LEAL		8(SP), CX	// pointer to call arguments
-	MOVL	$0, DX
-	MOVL	$0, SI
-	MOVL	$0,  DI
-	CALL	*runtime·_vdso(SB)
-	CMPL	AX, $0xfffff001
-	JLS	oksock1
-	MOVL	$-1, 32(SP)	// n
-	NEGL	AX
-	MOVL	AX, 36(SP)  // errno
-	RET
-oksock1:
-	MOVL	AX, 32(SP)	// n
-	MOVL	$0, 36(SP)	// errno
-	RET
-
-#define SYS__LLSEEK 140	/* from zsysnum_linux_386.go */
-// func Seek(fd int, offset int64, whence int) (newoffset int64, errno int)
-// Implemented in assembly to avoid allocation when
-// taking the address of the return value newoffset.
-// Underlying system call is
-//	llseek(int fd, int offhi, int offlo, int64 *result, int whence)
-TEXT ·seek(SB),NOSPLIT,$0-28
-	CALL	runtime·entersyscall(SB)
-	MOVL	$SYS__LLSEEK, AX	// syscall entry
-	MOVL	4(SP), BX	// fd
-	MOVL	12(SP), CX	// offset-high
-	MOVL	8(SP), DX	// offset-low
-	LEAL	20(SP), SI	// result pointer
-	MOVL	16(SP),  DI	// whence
-	CALL	*runtime·_vdso(SB)
-	CMPL	AX, $0xfffff001
-	JLS	okseek
-	MOVL	$-1, 20(SP)	// newoffset low
-	MOVL	$-1, 24(SP)	// newoffset high
-	NEGL	AX
-	MOVL	AX, 28(SP)  // errno
-	CALL	runtime·exitsyscall(SB)
-	RET
-okseek:
-	// system call filled in newoffset already
-	MOVL	$0, 28(SP)	// errno
-	CALL	runtime·exitsyscall(SB)
-	RET
diff --git a/src/pkg/syscall/asm_linux_amd64.s b/src/pkg/syscall/asm_linux_amd64.s
deleted file mode 100644
index 995b60e..0000000
--- a/src/pkg/syscall/asm_linux_amd64.s
+++ /dev/null
@@ -1,126 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// TODO(rsc): Rewrite all nn(SP) references into name+(nn-8)(FP)
-// so that go vet can check that they are correct.
-
-#include "../../cmd/ld/textflag.h"
-
-//
-// System calls for AMD64, Linux
-//
-
-// func Syscall(trap int64, a1, a2, a3 int64) (r1, r2, err int64);
-// Trap # in AX, args in DI SI DX R10 R8 R9, return in AX DX
-// Note that this differs from "standard" ABI convention, which
-// would pass 4th arg in CX, not R10.
-
-TEXT	·Syscall(SB),NOSPLIT,$0-56
-	CALL	runtime·entersyscall(SB)
-	MOVQ	16(SP), DI
-	MOVQ	24(SP), SI
-	MOVQ	32(SP), DX
-	MOVQ	$0, R10
-	MOVQ	$0, R8
-	MOVQ	$0, R9
-	MOVQ	8(SP), AX	// syscall entry
-	SYSCALL
-	CMPQ	AX, $0xfffffffffffff001
-	JLS	ok
-	MOVQ	$-1, 40(SP)	// r1
-	MOVQ	$0, 48(SP)	// r2
-	NEGQ	AX
-	MOVQ	AX, 56(SP)  // errno
-	CALL	runtime·exitsyscall(SB)
-	RET
-ok:
-	MOVQ	AX, 40(SP)	// r1
-	MOVQ	DX, 48(SP)	// r2
-	MOVQ	$0, 56(SP)	// errno
-	CALL	runtime·exitsyscall(SB)
-	RET
-
-TEXT ·Syscall6(SB),NOSPLIT,$0-80
-	CALL	runtime·entersyscall(SB)
-	MOVQ	16(SP), DI
-	MOVQ	24(SP), SI
-	MOVQ	32(SP), DX
-	MOVQ	40(SP), R10
-	MOVQ	48(SP), R8
-	MOVQ	56(SP), R9
-	MOVQ	8(SP), AX	// syscall entry
-	SYSCALL
-	CMPQ	AX, $0xfffffffffffff001
-	JLS	ok6
-	MOVQ	$-1, 64(SP)	// r1
-	MOVQ	$0, 72(SP)	// r2
-	NEGQ	AX
-	MOVQ	AX, 80(SP)  // errno
-	CALL	runtime·exitsyscall(SB)
-	RET
-ok6:
-	MOVQ	AX, 64(SP)	// r1
-	MOVQ	DX, 72(SP)	// r2
-	MOVQ	$0, 80(SP)	// errno
-	CALL	runtime·exitsyscall(SB)
-	RET
-
-TEXT ·RawSyscall(SB),NOSPLIT,$0-56
-	MOVQ	16(SP), DI
-	MOVQ	24(SP), SI
-	MOVQ	32(SP), DX
-	MOVQ	$0, R10
-	MOVQ	$0, R8
-	MOVQ	$0, R9
-	MOVQ	8(SP), AX	// syscall entry
-	SYSCALL
-	CMPQ	AX, $0xfffffffffffff001
-	JLS	ok1
-	MOVQ	$-1, 40(SP)	// r1
-	MOVQ	$0, 48(SP)	// r2
-	NEGQ	AX
-	MOVQ	AX, 56(SP)  // errno
-	RET
-ok1:
-	MOVQ	AX, 40(SP)	// r1
-	MOVQ	DX, 48(SP)	// r2
-	MOVQ	$0, 56(SP)	// errno
-	RET
-
-TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
-	MOVQ	16(SP), DI
-	MOVQ	24(SP), SI
-	MOVQ	32(SP), DX
-	MOVQ	40(SP), R10
-	MOVQ	48(SP), R8
-	MOVQ	56(SP), R9
-	MOVQ	8(SP), AX	// syscall entry
-	SYSCALL
-	CMPQ	AX, $0xfffffffffffff001
-	JLS	ok2
-	MOVQ	$-1, 64(SP)	// r1
-	MOVQ	$0, 72(SP)	// r2
-	NEGQ	AX
-	MOVQ	AX, 80(SP)  // errno
-	RET
-ok2:
-	MOVQ	AX, 64(SP)	// r1
-	MOVQ	DX, 72(SP)	// r2
-	MOVQ	$0, 80(SP)	// errno
-	RET
-
-TEXT ·gettimeofday(SB),NOSPLIT,$0-16
-	MOVQ	8(SP), DI
-	MOVQ	$0, SI
-	MOVQ	runtime·__vdso_gettimeofday_sym(SB), AX
-	CALL	AX
-
-	CMPQ	AX, $0xfffffffffffff001
-	JLS	ok7
-	NEGQ	AX
-	MOVQ	AX, 16(SP)  // errno
-	RET
-ok7:
-	MOVQ	$0, 16(SP)  // errno
-	RET
diff --git a/src/pkg/syscall/asm_linux_arm.s b/src/pkg/syscall/asm_linux_arm.s
deleted file mode 100644
index a28bc6c..0000000
--- a/src/pkg/syscall/asm_linux_arm.s
+++ /dev/null
@@ -1,155 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../cmd/ld/textflag.h"
-
-//
-// System calls for arm, Linux
-//
-
-// TODO(kaib): handle error returns
-
-// func Syscall(syscall uintptr, a1, a2, a3 uintptr) (r1, r2, err uintptr);
-
-TEXT	·Syscall(SB),NOSPLIT,$0-28
-	BL		runtime·entersyscall(SB)
-	MOVW	4(SP), R7
-	MOVW	8(SP), R0
-	MOVW	12(SP), R1
-	MOVW	16(SP), R2
-	SWI		$0
-	MOVW	$0xfffff001, R1
-	CMP		R1, R0
-	BLS		ok
-	MOVW	$-1, R1
-	MOVW	R1, 20(SP)	// r1
-	MOVW	$0, R2
-	MOVW	R2, 24(SP)	// r2
-	RSB		$0, R0, R0
-	MOVW	R0, 28(SP)	// errno
-	BL		runtime·exitsyscall(SB)
-	RET
-ok:
-	MOVW	R0, 20(SP) // r1
-	MOVW	$0, R0
-	MOVW	R0, 24(SP)	// r2
-	MOVW	R0, 28(SP)	// errno
-	BL		runtime·exitsyscall(SB)
-	RET
-
-// func Syscall6(trap uintptr, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr);
-// Actually Syscall5 but the rest of the code expects it to be named Syscall6.
-TEXT	·Syscall6(SB),NOSPLIT,$0-40
-	BL		runtime·entersyscall(SB)
-	MOVW	4(SP), R7	// syscall entry
-	MOVW	8(SP), R0
-	MOVW	12(SP), R1
-	MOVW	16(SP), R2
-	MOVW	20(SP), R3
-	MOVW	24(SP), R4
-	MOVW	28(SP), R5
-	SWI		$0
-	MOVW	$0xfffff001, R6
-	CMP		R6, R0
-	BLS		ok6
-	MOVW	$-1, R1
-	MOVW	R1, 32(SP)	// r1
-	MOVW	$0, R2
-	MOVW	R2, 36(SP)	// r2
-	RSB		$0, R0, R0
-	MOVW	R0, 40(SP)	// errno
-	BL		runtime·exitsyscall(SB)
-	RET
-ok6:
-	MOVW	R0, 32(SP) // r1
-	MOVW	R1, 36(SP)	// r2
-	MOVW	$0, R0
-	MOVW	R0, 40(SP)	// errno
-	BL		runtime·exitsyscall(SB)
-	RET
-
-// func RawSyscall6(trap uintptr, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr);
-// Actually RawSyscall5 but the rest of the code expects it to be named RawSyscall6.
-TEXT	·RawSyscall6(SB),NOSPLIT,$0-40
-	MOVW	4(SP), R7	// syscall entry
-	MOVW	8(SP), R0
-	MOVW	12(SP), R1
-	MOVW	16(SP), R2
-	MOVW	20(SP), R3
-	MOVW	24(SP), R4
-	MOVW	28(SP), R5
-	SWI		$0
-	MOVW	$0xfffff001, R6
-	CMP		R6, R0
-	BLS		ok2
-	MOVW	$-1, R1
-	MOVW	R1, 32(SP)	// r1
-	MOVW	$0, R2
-	MOVW	R2, 36(SP)	// r2
-	RSB		$0, R0, R0
-	MOVW	R0, 40(SP)	// errno
-	RET
-ok2:
-	MOVW	R0, 32(SP) // r1
-	MOVW	R1, 36(SP)	// r2
-	MOVW	$0, R0
-	MOVW	R0, 40(SP)	// errno
-	RET
-
-#define SYS__LLSEEK 140  /* from zsysnum_linux_arm.go */
-// func seek(fd int, offset int64, whence int) (newoffset int64, errno int)
-// Implemented in assembly to avoid allocation when
-// taking the address of the return value newoffset.
-// Underlying system call is
-//	llseek(int fd, int offhi, int offlo, int64 *result, int whence)
-TEXT ·seek(SB),NOSPLIT,$0-32
-	BL	runtime·entersyscall(SB)
-	MOVW	$SYS__LLSEEK, R7	// syscall entry
-	MOVW	4(SP), R0	// fd
-	MOVW	12(SP), R1	// offset-high
-	MOVW	8(SP), R2	// offset-low
-	MOVW	$20(SP), R3
-	MOVW	16(SP), R4	// whence
-	SWI	$0
-	MOVW	$0xfffff001, R6
-	CMP	R6, R0
-	BLS	okseek
-	MOVW	$0, R1
-	MOVW	R1, 20(SP)
-	MOVW	R1, 24(SP)
-	RSB	$0, R0, R0
-	MOVW	R0, 28(SP)	// errno
-	BL	runtime·exitsyscall(SB)
-	RET
-okseek:
-	// system call filled in newoffset already
-	MOVW	$0, R0
-	MOVW	R0, 28(SP)	// errno
-	BL	runtime·exitsyscall(SB)
-	RET	
-
-// func RawSyscall(trap uintptr, a1, a2, a3 uintptr) (r1, r2, err uintptr);
-TEXT ·RawSyscall(SB),NOSPLIT,$0-28
-	MOVW	4(SP), R7	// syscall entry
-	MOVW	8(SP), R0
-	MOVW	12(SP), R1
-	MOVW	16(SP), R2
-	SWI		$0
-	MOVW	$0xfffff001, R1
-	CMP		R1, R0
-	BLS		ok1
-	MOVW	$-1, R1
-	MOVW	R1, 20(SP)	// r1
-	MOVW	$0, R2
-	MOVW	R2, 24(SP)	// r2
-	RSB		$0, R0, R0
-	MOVW	R0, 28(SP)	// errno
-	RET
-ok1:
-	MOVW	R0, 20(SP) // r1
-	MOVW	$0, R0
-	MOVW	R0, 24(SP)	// r2
-	MOVW	R0, 28(SP)	// errno
-	RET
-
diff --git a/src/pkg/syscall/asm_nacl_386.s b/src/pkg/syscall/asm_nacl_386.s
deleted file mode 100644
index de7c3cc..0000000
--- a/src/pkg/syscall/asm_nacl_386.s
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../cmd/ld/textflag.h"
-#include "../runtime/syscall_nacl.h"
-
-//
-// System call support for 386, Native Client
-//
-
-#define NACL_SYSCALL(code) \
-	MOVL $(0x10000 + ((code)<<5)), AX; CALL AX
-
-#define NACL_SYSJMP(code) \
-	MOVL $(0x10000 + ((code)<<5)), AX; JMP AX
-
-TEXT syscall·Syscall(SB),NOSPLIT,$12-28
-	CALL	runtime·entersyscall(SB)
-	MOVL	trap+0(FP), AX
-	MOVL	a1+4(FP), BX
-	MOVL	BX, 0(SP)
-	MOVL	a2+8(FP), BX
-	MOVL	BX, 4(SP)
-	MOVL	a3+12(FP), BX
-	MOVL	BX, 8(SP)
-	SHLL	$5, AX
-	ADDL	$0x10000, AX
-	CALL	AX
-	CMPL	AX, $0
-	JGE	ok
-	MOVL	$-1, r1+16(FP)
-	MOVL	$-1, r2+20(FP)
-	NEGL	AX
-	MOVL	AX, err+24(FP)
-	CALL	runtime·exitsyscall(SB)
-	RET
-ok:
-	MOVL	AX, r1+16(FP)
-	MOVL	DX, r2+20(FP)
-	MOVL	$0, err+24(FP)
-	CALL	runtime·exitsyscall(SB)
-	RET	
diff --git a/src/pkg/syscall/asm_nacl_amd64p32.s b/src/pkg/syscall/asm_nacl_amd64p32.s
deleted file mode 100644
index de030ec..0000000
--- a/src/pkg/syscall/asm_nacl_amd64p32.s
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../cmd/ld/textflag.h"
-#include "../runtime/syscall_nacl.h"
-
-//
-// System call support for amd64, Native Client
-//
-
-#define NACL_SYSCALL(code) \
-	MOVL $(0x10000 + ((code)<<5)), AX; CALL AX
-
-#define NACL_SYSJMP(code) \
-	MOVL $(0x10000 + ((code)<<5)), AX; JMP AX
-
-TEXT syscall·Syscall(SB),NOSPLIT,$0-28
-	CALL	runtime·entersyscall(SB)
-	MOVL	trap+0(FP), AX
-	MOVL	a1+4(FP), DI
-	MOVL	a2+8(FP), SI
-	MOVL	a3+12(FP), DX
-	// more args would use CX, R8, R9
-	SHLL	$5, AX
-	ADDL	$0x10000, AX
-	CALL	AX
-	CMPL	AX, $0
-	JGE	ok
-	MOVL	$-1, r1+16(FP)
-	MOVL	$-1, r2+20(FP)
-	NEGL	AX
-	MOVL	AX, err+24(FP)
-	CALL	runtime·exitsyscall(SB)
-	RET
-ok:
-	MOVL	AX, r1+16(FP)
-	MOVL	DX, r2+20(FP)
-	MOVL	$0, err+24(FP)
-	CALL	runtime·exitsyscall(SB)
-	RET	
diff --git a/src/pkg/syscall/asm_netbsd_386.s b/src/pkg/syscall/asm_netbsd_386.s
deleted file mode 100644
index 40b30b4..0000000
--- a/src/pkg/syscall/asm_netbsd_386.s
+++ /dev/null
@@ -1,142 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// TODO(rsc): Rewrite all nn(SP) references into name+(nn-8)(FP)
-// so that go vet can check that they are correct.
-
-#include "../../cmd/ld/textflag.h"
-
-//
-// System call support for 386, NetBSD
-//
-
-// func Syscall(trap int32, a1, a2, a3 int32) (r1, r2, err int32);
-// func Syscall6(trap int32, a1, a2, a3, a4, a5, a6 int32) (r1, r2, err int32);
-// Trap # in AX, args on stack above caller pc.
-
-TEXT	·Syscall(SB),NOSPLIT,$0-28
-	CALL	runtime·entersyscall(SB)
-	MOVL	4(SP), AX	// syscall entry
-	// slide args down on top of system call number
-	LEAL		8(SP), SI
-	LEAL		4(SP), DI
-	CLD
-	MOVSL
-	MOVSL
-	MOVSL
-	INT	$0x80
-	JAE	ok
-	MOVL	$-1, 20(SP)	// r1
-	MOVL	$-1, 24(SP)	// r2
-	MOVL	AX, 28(SP)		// errno
-	CALL	runtime·exitsyscall(SB)
-	RET
-ok:
-	MOVL	AX, 20(SP)	// r1
-	MOVL	DX, 24(SP)	// r2
-	MOVL	$0, 28(SP)	// errno
-	CALL	runtime·exitsyscall(SB)
-	RET
-
-TEXT	·Syscall6(SB),NOSPLIT,$0-40
-	CALL	runtime·entersyscall(SB)
-	MOVL	4(SP), AX	// syscall entry
-	// slide args down on top of system call number
-	LEAL		8(SP), SI
-	LEAL		4(SP), DI
-	CLD
-	MOVSL
-	MOVSL
-	MOVSL
-	MOVSL
-	MOVSL
-	MOVSL
-	INT	$0x80
-	JAE	ok6
-	MOVL	$-1, 32(SP)	// r1
-	MOVL	$-1, 36(SP)	// r2
-	MOVL	AX, 40(SP)		// errno
-	CALL	runtime·exitsyscall(SB)
-	RET
-ok6:
-	MOVL	AX, 32(SP)	// r1
-	MOVL	DX, 36(SP)	// r2
-	MOVL	$0, 40(SP)	// errno
-	CALL	runtime·exitsyscall(SB)
-	RET
-
-TEXT	·Syscall9(SB),NOSPLIT,$0-52
-	CALL	runtime·entersyscall(SB)
-	MOVL	4(SP), AX	// syscall entry
-	// slide args down on top of system call number
-	LEAL		8(SP), SI
-	LEAL		4(SP), DI
-	CLD
-	MOVSL
-	MOVSL
-	MOVSL
-	MOVSL
-	MOVSL
-	MOVSL
-	MOVSL
-	MOVSL
-	MOVSL
-	INT	$0x80
-	JAE	ok9
-	MOVL	$-1, 44(SP)	// r1
-	MOVL	$-1, 48(SP)	// r2
-	MOVL	AX, 52(SP)		// errno
-	CALL	runtime·exitsyscall(SB)
-	RET
-ok9:
-	MOVL	AX, 44(SP)	// r1
-	MOVL	DX, 48(SP)	// r2
-	MOVL	$0, 52(SP)	// errno
-	CALL	runtime·exitsyscall(SB)
-	RET
-
-TEXT ·RawSyscall(SB),NOSPLIT,$0-28
-	MOVL	4(SP), AX	// syscall entry
-	// slide args down on top of system call number
-	LEAL		8(SP), SI
-	LEAL		4(SP), DI
-	CLD
-	MOVSL
-	MOVSL
-	MOVSL
-	INT	$0x80
-	JAE	ok1
-	MOVL	$-1, 20(SP)	// r1
-	MOVL	$-1, 24(SP)	// r2
-	MOVL	AX, 28(SP)		// errno
-	RET
-ok1:
-	MOVL	AX, 20(SP)	// r1
-	MOVL	DX, 24(SP)	// r2
-	MOVL	$0, 28(SP)	// errno
-	RET
-
-TEXT	·RawSyscall6(SB),NOSPLIT,$0-40
-	MOVL	4(SP), AX	// syscall entry
-	// slide args down on top of system call number
-	LEAL		8(SP), SI
-	LEAL		4(SP), DI
-	CLD
-	MOVSL
-	MOVSL
-	MOVSL
-	MOVSL
-	MOVSL
-	MOVSL
-	INT	$0x80
-	JAE	ok2
-	MOVL	$-1, 32(SP)	// r1
-	MOVL	$-1, 36(SP)	// r2
-	MOVL	AX, 40(SP)		// errno
-	RET
-ok2:
-	MOVL	AX, 32(SP)	// r1
-	MOVL	DX, 36(SP)	// r2
-	MOVL	$0, 40(SP)	// errno
-	RET
diff --git a/src/pkg/syscall/asm_netbsd_amd64.s b/src/pkg/syscall/asm_netbsd_amd64.s
deleted file mode 100644
index 94ad028..0000000
--- a/src/pkg/syscall/asm_netbsd_amd64.s
+++ /dev/null
@@ -1,135 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// TODO(rsc): Rewrite all nn(SP) references into name+(nn-8)(FP)
-// so that go vet can check that they are correct.
-
-#include "../../cmd/ld/textflag.h"
-
-//
-// System call support for AMD64, NetBSD
-//
-
-// func Syscall(trap int64, a1, a2, a3 int64) (r1, r2, err int64);
-// func Syscall6(trap int64, a1, a2, a3, a4, a5, a6 int64) (r1, r2, err int64);
-// func Syscall9(trap int64, a1, a2, a3, a4, a5, a6, a7, a8, a9 int64) (r1, r2, err int64);
-// Trap # in AX, args in DI SI DX, return in AX DX
-
-TEXT	·Syscall(SB),NOSPLIT,$0-56
-	CALL	runtime·entersyscall(SB)
-	MOVQ	8(SP), AX	// syscall entry
-	MOVQ	16(SP), DI
-	MOVQ	24(SP), SI
-	MOVQ	32(SP), DX
-	MOVQ	$0, R10
-	MOVQ	$0, R8
-	MOVQ	$0, R9
-	SYSCALL
-	JCC	ok
-	MOVQ	$-1, 40(SP)	// r1
-	MOVQ	$0, 48(SP)	// r2
-	MOVQ	AX, 56(SP)	// errno
-	CALL	runtime·exitsyscall(SB)
-	RET
-ok:
-	MOVQ	AX, 40(SP)	// r1
-	MOVQ	DX, 48(SP)	// r2
-	MOVQ	$0, 56(SP)	// errno
-	CALL	runtime·exitsyscall(SB)
-	RET
-
-TEXT	·Syscall6(SB),NOSPLIT,$0-80
-	CALL	runtime·entersyscall(SB)
-	MOVQ	8(SP), AX	// syscall entry
-	MOVQ	16(SP), DI
-	MOVQ	24(SP), SI
-	MOVQ	32(SP), DX
-	MOVQ	40(SP), R10
-	MOVQ	48(SP), R8
-	MOVQ	56(SP), R9
-	SYSCALL
-	JCC	ok6
-	MOVQ	$-1, 64(SP)	// r1
-	MOVQ	$0, 72(SP)	// r2
-	MOVQ	AX, 80(SP)  	// errno
-	CALL	runtime·exitsyscall(SB)
-	RET
-ok6:
-	MOVQ	AX, 64(SP)	// r1
-	MOVQ	DX, 72(SP)	// r2
-	MOVQ	$0, 80(SP)	// errno
-	CALL	runtime·exitsyscall(SB)
-	RET
-
-TEXT	·Syscall9(SB),NOSPLIT,$0-104
-	CALL	runtime·entersyscall(SB)
-	MOVQ	8(SP), AX	// syscall entry
-	MOVQ	16(SP), DI
-	MOVQ	24(SP), SI
-	MOVQ	32(SP), DX
-	MOVQ	40(SP), R10
-	MOVQ	48(SP), R8
-	MOVQ	56(SP), R9
-	MOVQ	64(SP), R11
-	MOVQ	72(SP), R12
-	MOVQ	80(SP), R13
-	SUBQ    $32, SP
-	MOVQ	R11, 8(SP)	// arg 7
-	MOVQ	R12, 16(SP)	// arg 8
-	MOVQ	R13, 24(SP)	// arg 9
-	SYSCALL
-	JCC	ok9
-	ADDQ    $32, SP
-	MOVQ	$-1, 88(SP)	// r1
-	MOVQ	$0, 96(SP)	// r2
-	MOVQ	AX, 104(SP)	// errno
-	CALL	runtime·exitsyscall(SB)
-	RET
-ok9:
-	ADDQ    $32, SP
-	MOVQ	AX, 88(SP)	// r1
-	MOVQ	DX, 96(SP)	// r2
-	MOVQ	$0, 104(SP)	// errno
-	CALL	runtime·exitsyscall(SB)
-	RET
-
-TEXT	·RawSyscall(SB),NOSPLIT,$0-56
-	MOVQ	16(SP), DI
-	MOVQ	24(SP), SI
-	MOVQ	32(SP), DX
-	MOVQ	$0, R10
-	MOVQ	$0, R8
-	MOVQ	$0, R9
-	MOVQ	8(SP), AX	// syscall entry
-	SYSCALL
-	JCC	ok1
-	MOVQ	$-1, 40(SP)	// r1
-	MOVQ	$0, 48(SP)	// r2
-	MOVQ	AX, 56(SP)	// errno
-	RET
-ok1:
-	MOVQ	AX, 40(SP)	// r1
-	MOVQ	DX, 48(SP)	// r2
-	MOVQ	$0, 56(SP)	// errno
-	RET
-
-TEXT	·RawSyscall6(SB),NOSPLIT,$0-80
-	MOVQ	16(SP), DI
-	MOVQ	24(SP), SI
-	MOVQ	32(SP), DX
-	MOVQ	40(SP), R10
-	MOVQ	48(SP), R8
-	MOVQ	56(SP), R9
-	MOVQ	8(SP), AX	// syscall entry
-	SYSCALL
-	JCC	ok2
-	MOVQ	$-1, 64(SP)	// r1
-	MOVQ	$0, 72(SP)	// r2
-	MOVQ	AX, 80(SP)	// errno
-	RET
-ok2:
-	MOVQ	AX, 64(SP)	// r1
-	MOVQ	DX, 72(SP)	// r2
-	MOVQ	$0, 80(SP)	// errno
-	RET
diff --git a/src/pkg/syscall/asm_netbsd_arm.s b/src/pkg/syscall/asm_netbsd_arm.s
deleted file mode 100644
index 2c0d654..0000000
--- a/src/pkg/syscall/asm_netbsd_arm.s
+++ /dev/null
@@ -1,126 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../cmd/ld/textflag.h"
-
-//
-// System call support for ARM, NetBSD
-//
-
-// func Syscall(trap int32, a1, a2, a3 int32) (r1, r2, err int32);
-// func Syscall6(trap int32, a1, a2, a3, a4, a5, a6 int32) (r1, r2, err int32);
-// func Syscall9(trap int32, a1, a2, a3, a4, a5, a6, a7, a8, a9 int64) (r1, r2, err int32)
-
-TEXT	·Syscall(SB),NOSPLIT,$0-28
-	BL runtime·entersyscall(SB)
-	MOVW 0(FP), R0 // sigcall num
-	MOVW 4(FP), R1 // a1
-	MOVW 8(FP), R2 // a2
-	MOVW 12(FP), R3 // a3
-	SWI $0 // syscall
-	MOVW $0, R2
-	BCS error
-	MOVW R0, 16(FP) // r1
-	MOVW R1, 20(FP) // r2
-	MOVW R2, 24(FP) // err
-	BL runtime·exitsyscall(SB)
-	RET
-error:
-	MOVW $-1, R3
-	MOVW R3, 16(FP) // r1
-	MOVW R2, 20(FP) // r2
-	MOVW R0, 24(FP) // err
-	BL runtime·exitsyscall(SB)
-	RET
-
-TEXT	·Syscall6(SB),NOSPLIT,$0-40
-	BL runtime·entersyscall(SB)
-	MOVW 0(FP), R0 // sigcall num
-	MOVW 4(FP), R1 // a1
-	MOVW 8(FP), R2 // a2
-	MOVW 12(FP), R3 // a3
-	MOVW R13, R4
-	MOVW $16(FP), R13 // a4 to a6 are passed on stack
-	SWI $0 // syscall
-	MOVW R4, R13
-	MOVW $0, R2
-	BCS error6
-	MOVW R0, 28(FP) // r1
-	MOVW R1, 32(FP) // r2
-	MOVW R2, 36(FP) // err
-	BL runtime·exitsyscall(SB)
-	RET
-error6:
-	MOVW $-1, R3
-	MOVW R3, 28(FP) // r1
-	MOVW R2, 32(FP) // r2
-	MOVW R0, 36(FP) // err
-	BL runtime·exitsyscall(SB)
-	RET
-
-TEXT	·Syscall9(SB),NOSPLIT,$0-52
-	BL runtime·entersyscall(SB)
-	MOVW 0(FP), R0 // sigcall num
-	MOVW 4(FP), R1 // a1
-	MOVW 8(FP), R2 // a2
-	MOVW 12(FP), R3 // a3
-	MOVW R13, R4
-	MOVW $16(FP), R13 // a4 to a9 are passed on stack
-	SWI $0 // syscall
-	MOVW R4, R13
-	MOVW $0, R2
-	BCS error9
-	MOVW R0, 40(FP) // r1
-	MOVW R1, 44(FP) // r2
-	MOVW R2, 48(FP) // err
-	BL runtime·exitsyscall(SB)
-	RET
-error9:
-	MOVW $-1, R3
-	MOVW R3, 40(FP) // r1
-	MOVW R2, 44(FP) // r2
-	MOVW R0, 48(FP) // err
-	BL runtime·exitsyscall(SB)
-	RET
-
-TEXT	·RawSyscall(SB),NOSPLIT,$0-28
-	MOVW 0(FP), R0 // sigcall num
-	MOVW 4(FP), R1 // a1
-	MOVW 8(FP), R2 // a2
-	MOVW 12(FP), R3 // a3
-	SWI $0 // syscall
-	MOVW $0, R2
-	BCS errorr
-	MOVW R0, 16(FP) // r1
-	MOVW R1, 20(FP) // r2
-	MOVW R2, 24(FP) // err
-	RET
-errorr:
-	MOVW $-1, R3
-	MOVW R3, 16(FP) // r1
-	MOVW R2, 20(FP) // r2
-	MOVW R0, 24(FP) // err
-	RET
-
-TEXT	·RawSyscall6(SB),NOSPLIT,$0-40
-	MOVW 0(FP), R0 // sigcall num
-	MOVW 4(FP), R1 // a1
-	MOVW 8(FP), R2 // a2
-	MOVW 12(FP), R3 // a3
-	MOVW R13, R4
-	MOVW $16(FP), R13 // a4 to a9 are passed on stack
-	SWI $0 // syscall
-	MOVW R4, R13
-	MOVW $0, R2
-	BCS errorr6
-	MOVW R0, 28(FP) // r1
-	MOVW R1, 32(FP) // r2
-	MOVW R2, 36(FP) // err
-	RET
-errorr6:
-	MOVW $-1, R3
-	MOVW R3, 28(FP) // r1
-	MOVW R2, 32(FP) // r2
-	MOVW R0, 36(FP) // err
-	RET
diff --git a/src/pkg/syscall/asm_openbsd_386.s b/src/pkg/syscall/asm_openbsd_386.s
deleted file mode 100644
index 7dd2e37..0000000
--- a/src/pkg/syscall/asm_openbsd_386.s
+++ /dev/null
@@ -1,142 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// TODO(rsc): Rewrite all nn(SP) references into name+(nn-8)(FP)
-// so that go vet can check that they are correct.
-
-#include "../../cmd/ld/textflag.h"
-
-//
-// System call support for 386, OpenBSD
-//
-
-// func Syscall(trap int32, a1, a2, a3 int32) (r1, r2, err int32);
-// func Syscall6(trap int32, a1, a2, a3, a4, a5, a6 int32) (r1, r2, err int32);
-// Trap # in AX, args on stack above caller pc.
-
-TEXT	·Syscall(SB),NOSPLIT,$0-28
-	CALL	runtime·entersyscall(SB)
-	MOVL	4(SP), AX	// syscall entry
-	// slide args down on top of system call number
-	LEAL		8(SP), SI
-	LEAL		4(SP), DI
-	CLD
-	MOVSL
-	MOVSL
-	MOVSL
-	INT	$0x80
-	JAE	ok
-	MOVL	$-1, 20(SP)	// r1
-	MOVL	$-1, 24(SP)	// r2
-	MOVL	AX, 28(SP)		// errno
-	CALL	runtime·exitsyscall(SB)
-	RET
-ok:
-	MOVL	AX, 20(SP)	// r1
-	MOVL	DX, 24(SP)	// r2
-	MOVL	$0, 28(SP)	// errno
-	CALL	runtime·exitsyscall(SB)
-	RET
-
-TEXT	·Syscall6(SB),NOSPLIT,$0-40
-	CALL	runtime·entersyscall(SB)
-	MOVL	4(SP), AX	// syscall entry
-	// slide args down on top of system call number
-	LEAL		8(SP), SI
-	LEAL		4(SP), DI
-	CLD
-	MOVSL
-	MOVSL
-	MOVSL
-	MOVSL
-	MOVSL
-	MOVSL
-	INT	$0x80
-	JAE	ok6
-	MOVL	$-1, 32(SP)	// r1
-	MOVL	$-1, 36(SP)	// r2
-	MOVL	AX, 40(SP)		// errno
-	CALL	runtime·exitsyscall(SB)
-	RET
-ok6:
-	MOVL	AX, 32(SP)	// r1
-	MOVL	DX, 36(SP)	// r2
-	MOVL	$0, 40(SP)	// errno
-	CALL	runtime·exitsyscall(SB)
-	RET
-
-TEXT	·Syscall9(SB),NOSPLIT,$0-52
-	CALL	runtime·entersyscall(SB)
-	MOVL	4(SP), AX	// syscall entry
-	// slide args down on top of system call number
-	LEAL		8(SP), SI
-	LEAL		4(SP), DI
-	CLD
-	MOVSL
-	MOVSL
-	MOVSL
-	MOVSL
-	MOVSL
-	MOVSL
-	MOVSL
-	MOVSL
-	MOVSL
-	INT	$0x80
-	JAE	ok9
-	MOVL	$-1, 44(SP)	// r1
-	MOVL	$-1, 48(SP)	// r2
-	MOVL	AX, 52(SP)		// errno
-	CALL	runtime·exitsyscall(SB)
-	RET
-ok9:
-	MOVL	AX, 44(SP)	// r1
-	MOVL	DX, 48(SP)	// r2
-	MOVL	$0, 52(SP)	// errno
-	CALL	runtime·exitsyscall(SB)
-	RET
-
-TEXT ·RawSyscall(SB),NOSPLIT,$0-28
-	MOVL	4(SP), AX	// syscall entry
-	// slide args down on top of system call number
-	LEAL		8(SP), SI
-	LEAL		4(SP), DI
-	CLD
-	MOVSL
-	MOVSL
-	MOVSL
-	INT	$0x80
-	JAE	ok1
-	MOVL	$-1, 20(SP)	// r1
-	MOVL	$-1, 24(SP)	// r2
-	MOVL	AX, 28(SP)		// errno
-	RET
-ok1:
-	MOVL	AX, 20(SP)	// r1
-	MOVL	DX, 24(SP)	// r2
-	MOVL	$0, 28(SP)	// errno
-	RET
-
-TEXT	·RawSyscall6(SB),NOSPLIT,$0-40
-	MOVL	4(SP), AX	// syscall entry
-	// slide args down on top of system call number
-	LEAL		8(SP), SI
-	LEAL		4(SP), DI
-	CLD
-	MOVSL
-	MOVSL
-	MOVSL
-	MOVSL
-	MOVSL
-	MOVSL
-	INT	$0x80
-	JAE	ok2
-	MOVL	$-1, 32(SP)	// r1
-	MOVL	$-1, 36(SP)	// r2
-	MOVL	AX, 40(SP)		// errno
-	RET
-ok2:
-	MOVL	AX, 32(SP)	// r1
-	MOVL	DX, 36(SP)	// r2
-	MOVL	$0, 40(SP)	// errno
-	RET
diff --git a/src/pkg/syscall/asm_openbsd_amd64.s b/src/pkg/syscall/asm_openbsd_amd64.s
deleted file mode 100644
index e127bf2..0000000
--- a/src/pkg/syscall/asm_openbsd_amd64.s
+++ /dev/null
@@ -1,135 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// TODO(rsc): Rewrite all nn(SP) references into name+(nn-8)(FP)
-// so that go vet can check that they are correct.
-
-#include "../../cmd/ld/textflag.h"
-
-//
-// System call support for AMD64, OpenBSD
-//
-
-// func Syscall(trap int64, a1, a2, a3 int64) (r1, r2, err int64);
-// func Syscall6(trap int64, a1, a2, a3, a4, a5, a6 int64) (r1, r2, err int64);
-// func Syscall9(trap int64, a1, a2, a3, a4, a5, a6, a7, a8, a9 int64) (r1, r2, err int64);
-// Trap # in AX, args in DI SI DX, return in AX DX
-
-TEXT	·Syscall(SB),NOSPLIT,$0-56
-	CALL	runtime·entersyscall(SB)
-	MOVQ	8(SP), AX	// syscall entry
-	MOVQ	16(SP), DI
-	MOVQ	24(SP), SI
-	MOVQ	32(SP), DX
-	MOVQ	$0, R10
-	MOVQ	$0, R8
-	MOVQ	$0, R9
-	SYSCALL
-	JCC	ok
-	MOVQ	$-1, 40(SP)	// r1
-	MOVQ	$0, 48(SP)	// r2
-	MOVQ	AX, 56(SP)	// errno
-	CALL	runtime·exitsyscall(SB)
-	RET
-ok:
-	MOVQ	AX, 40(SP)	// r1
-	MOVQ	DX, 48(SP)	// r2
-	MOVQ	$0, 56(SP)	// errno
-	CALL	runtime·exitsyscall(SB)
-	RET
-
-TEXT	·Syscall6(SB),NOSPLIT,$0-80
-	CALL	runtime·entersyscall(SB)
-	MOVQ	8(SP), AX	// syscall entry
-	MOVQ	16(SP), DI
-	MOVQ	24(SP), SI
-	MOVQ	32(SP), DX
-	MOVQ	40(SP), R10
-	MOVQ	48(SP), R8
-	MOVQ	56(SP), R9
-	SYSCALL
-	JCC	ok6
-	MOVQ	$-1, 64(SP)	// r1
-	MOVQ	$0, 72(SP)	// r2
-	MOVQ	AX, 80(SP)  	// errno
-	CALL	runtime·exitsyscall(SB)
-	RET
-ok6:
-	MOVQ	AX, 64(SP)	// r1
-	MOVQ	DX, 72(SP)	// r2
-	MOVQ	$0, 80(SP)	// errno
-	CALL	runtime·exitsyscall(SB)
-	RET
-
-TEXT	·Syscall9(SB),NOSPLIT,$0-104
-	CALL	runtime·entersyscall(SB)
-	MOVQ	8(SP), AX	// syscall entry
-	MOVQ	16(SP), DI
-	MOVQ	24(SP), SI
-	MOVQ	32(SP), DX
-	MOVQ	40(SP), R10
-	MOVQ	48(SP), R8
-	MOVQ	56(SP), R9
-	MOVQ	64(SP), R11
-	MOVQ	72(SP), R12
-	MOVQ	80(SP), R13
-	SUBQ    $32, SP
-	MOVQ	R11, 8(SP)	// arg 7
-	MOVQ	R12, 16(SP)	// arg 8
-	MOVQ	R13, 24(SP)	// arg 9
-	SYSCALL
-	JCC	ok9
-	ADDQ    $32, SP
-	MOVQ	$-1, 88(SP)	// r1
-	MOVQ	$0, 96(SP)	// r2
-	MOVQ	AX, 104(SP)	// errno
-	CALL	runtime·exitsyscall(SB)
-	RET
-ok9:
-	ADDQ    $32, SP
-	MOVQ	AX, 88(SP)	// r1
-	MOVQ	DX, 96(SP)	// r2
-	MOVQ	$0, 104(SP)	// errno
-	CALL	runtime·exitsyscall(SB)
-	RET
-
-TEXT	·RawSyscall(SB),NOSPLIT,$0-56
-	MOVQ	16(SP), DI
-	MOVQ	24(SP), SI
-	MOVQ	32(SP), DX
-	MOVQ	$0, R10
-	MOVQ	$0, R8
-	MOVQ	$0, R9
-	MOVQ	8(SP), AX	// syscall entry
-	SYSCALL
-	JCC	ok1
-	MOVQ	$-1, 40(SP)	// r1
-	MOVQ	$0, 48(SP)	// r2
-	MOVQ	AX, 56(SP)	// errno
-	RET
-ok1:
-	MOVQ	AX, 40(SP)	// r1
-	MOVQ	DX, 48(SP)	// r2
-	MOVQ	$0, 56(SP)	// errno
-	RET
-
-TEXT	·RawSyscall6(SB),NOSPLIT,$0-80
-	MOVQ	16(SP), DI
-	MOVQ	24(SP), SI
-	MOVQ	32(SP), DX
-	MOVQ	40(SP), R10
-	MOVQ	48(SP), R8
-	MOVQ	56(SP), R9
-	MOVQ	8(SP), AX	// syscall entry
-	SYSCALL
-	JCC	ok2
-	MOVQ	$-1, 64(SP)	// r1
-	MOVQ	$0, 72(SP)	// r2
-	MOVQ	AX, 80(SP)	// errno
-	RET
-ok2:
-	MOVQ	AX, 64(SP)	// r1
-	MOVQ	DX, 72(SP)	// r2
-	MOVQ	$0, 80(SP)	// errno
-	RET
diff --git a/src/pkg/syscall/asm_plan9_386.s b/src/pkg/syscall/asm_plan9_386.s
deleted file mode 100644
index f8c07c4..0000000
--- a/src/pkg/syscall/asm_plan9_386.s
+++ /dev/null
@@ -1,164 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// TODO(rsc): Rewrite all nn(SP) references into name+(nn-8)(FP)
-// so that go vet can check that they are correct.
-
-#include "../../cmd/ld/textflag.h"
-
-//
-// System call support for 386, Plan 9
-//
-
-//func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err string)
-//func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err string)
-//func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr)
-//func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr)
-
-// Trap # in AX, args on stack above caller pc.
-TEXT	·Syscall(SB),NOSPLIT,$0-32
-	CALL	runtime·entersyscall(SB)
-	MOVL	4(SP), AX	// syscall entry
-	// slide args down on top of system call number
-	LEAL		8(SP), SI
-	LEAL		4(SP), DI
-	CLD
-	MOVSL
-	MOVSL
-	MOVSL
-	INT	$64
-	MOVL	AX, r1+20(SP)
-	MOVL	$0, r2+24(SP)
-	CMPL	AX, $-1
-	JNE	ok3
-
-	SUBL	$8, SP
-	CALL	runtime·errstr(SB)
-	MOVL	SP, SI
-	ADDL	$8, SP
-	JMP	copyresult3
-	
-ok3:
-	LEAL	runtime·emptystring(SB), SI	
-	
-copyresult3:
-	LEAL	err+28(SP), DI
-
-	CLD
-	MOVSL
-	MOVSL
-
-	CALL	runtime·exitsyscall(SB)
-	RET
-
-TEXT	·Syscall6(SB),NOSPLIT,$0-44
-	CALL	runtime·entersyscall(SB)
-	MOVL	4(SP), AX	// syscall entry
-	// slide args down on top of system call number
-	LEAL		8(SP), SI
-	LEAL		4(SP), DI
-	CLD
-	MOVSL
-	MOVSL
-	MOVSL
-	MOVSL
-	MOVSL
-	MOVSL
-	INT	$64
-	MOVL	AX, r1+32(SP)
-	MOVL	$0, r2+36(SP)
-	CMPL	AX, $-1
-	JNE	ok4
-	
-	SUBL	$8, SP
-	CALL	runtime·errstr(SB)
-	MOVL	SP, SI
-	ADDL	$8, SP
-	JMP	copyresult4
-	
-ok4:
-	LEAL	runtime·emptystring(SB), SI
-	
-copyresult4:
-	LEAL	err+40(SP), DI
-
-	CLD
-	MOVSL
-	MOVSL
-
-	CALL	runtime·exitsyscall(SB)
-	RET
-
-TEXT ·RawSyscall(SB),NOSPLIT,$0-28
-	MOVL	4(SP), AX	// syscall entry
-	// slide args down on top of system call number
-	LEAL		8(SP), SI
-	LEAL		4(SP), DI
-	CLD
-	MOVSL
-	MOVSL
-	MOVSL
-	INT	$64
-	MOVL	AX, r1+20(SP)
-	MOVL	AX, r2+24(SP)
-	MOVL	AX, err+28(SP)
-	RET
-
-TEXT	·RawSyscall6(SB),NOSPLIT,$0-40
-	MOVL	4(SP), AX	// syscall entry
-	// slide args down on top of system call number
-	LEAL		8(SP), SI
-	LEAL		4(SP), DI
-	CLD
-	MOVSL
-	MOVSL
-	MOVSL
-	MOVSL
-	MOVSL
-	MOVSL
-	INT	$64
-	MOVL	AX, r1+32(SP)
-	MOVL	AX, r2+36(SP)
-	MOVL	AX, err+40(SP)		
-	RET
-
-#define SYS_SEEK 39	/* from zsysnum_plan9_386.go */
-
-//func seek(placeholder uintptr, fd int, offset int64, whence int) (newoffset int64, err string)
-TEXT ·seek(SB),NOSPLIT,$0-36
-	LEAL	newoffset+24(SP), AX
-	MOVL	AX, placeholder+4(SP)
-	
-	MOVL	$SYS_SEEK, AX	// syscall entry
-	INT	$64
-	
-	CMPL	AX, $-1
-	JNE	ok6
-	MOVL	AX, 24(SP)	// newoffset low
-	MOVL	AX, 28(SP)	// newoffset high
-	
-	SUBL	$8, SP
-	CALL	syscall·errstr(SB)
-	MOVL	SP, SI
-	ADDL	$8, SP	
-	JMP	copyresult6
-	
-ok6:
-	LEAL	runtime·emptystring(SB), SI
-	
-copyresult6:
-	LEAL	err+32(SP), DI
-
-	CLD
-	MOVSL
-	MOVSL
-	RET
-
-//func exit(code int)
-// Import runtime·exit for cleanly exiting.
-TEXT ·exit(SB),NOSPLIT,$4-4
-	MOVL	code+0(FP), AX
-	MOVL	AX, 0(SP)
-	CALL	runtime·exit(SB)
-	RET
diff --git a/src/pkg/syscall/asm_plan9_amd64.s b/src/pkg/syscall/asm_plan9_amd64.s
deleted file mode 100644
index 2154a87..0000000
--- a/src/pkg/syscall/asm_plan9_amd64.s
+++ /dev/null
@@ -1,170 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// TODO(rsc): Rewrite all nn(SP) references into name+(nn-8)(FP)
-// so that go vet can check that they are correct.
-
-#include "../../cmd/ld/textflag.h"
-
-//
-// System call support for Plan 9
-//
-
-//func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err string)
-//func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err string)
-//func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr)
-//func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr)
-
-// Trap # in BP, args on stack above caller pc.
-// NxM requires that Plan 9 system calls be
-// marked with $0x8000 in AX.
-TEXT	·Syscall(SB),NOSPLIT,$0-64
-	CALL	runtime·entersyscall(SB)
-	MOVQ	$0x8000, AX	// for NxM
-	MOVQ	8(SP), BP	// syscall entry
-	// slide args down on top of system call number
-	LEAQ	16(SP), SI
-	LEAQ	8(SP), DI
-	CLD
-	MOVSQ
-	MOVSQ
-	MOVSQ
-	SYSCALL
-	MOVQ	AX, r1+40(SP)
-	MOVQ	$0, r2+48(SP)
-	CMPL	AX, $-1
-	JNE	ok3
-
-	SUBQ	$16, SP
-	CALL	runtime·errstr(SB)
-	MOVQ	SP, SI
-	ADDQ	$16, SP
-	JMP	copyresult3
-	
-ok3:
-	LEAQ	runtime·emptystring(SB), SI	
-	
-copyresult3:
-	LEAQ	err+56(SP), DI
-
-	CLD
-	MOVSQ
-	MOVSQ
-
-	CALL	runtime·exitsyscall(SB)
-	RET
-
-TEXT	·Syscall6(SB),NOSPLIT,$0-88
-	CALL	runtime·entersyscall(SB)
-	MOVQ	$0x8000, AX	// for NxM
-	MOVQ	8(SP), BP	// syscall entry
-	// slide args down on top of system call number
-	LEAQ		16(SP), SI
-	LEAQ		8(SP), DI
-	CLD
-	MOVSQ
-	MOVSQ
-	MOVSQ
-	MOVSQ
-	MOVSQ
-	MOVSQ
-	SYSCALL
-	MOVQ	AX, r1+64(SP)
-	MOVQ	$0, r2+72(SP)
-	CMPL	AX, $-1
-	JNE	ok4
-	
-	SUBQ	$16, SP
-	CALL	runtime·errstr(SB)
-	MOVQ	SP, SI
-	ADDQ	$16, SP
-	JMP	copyresult4
-	
-ok4:
-	LEAQ	runtime·emptystring(SB), SI
-	
-copyresult4:
-	LEAQ	err+80(SP), DI
-
-	CLD
-	MOVSQ
-	MOVSQ
-
-	CALL	runtime·exitsyscall(SB)
-	RET
-
-TEXT ·RawSyscall(SB),NOSPLIT,$0-56
-	MOVQ	$0x8000, AX	// for NxM
-	MOVQ	8(SP), BP	// syscall entry
-	// slide args down on top of system call number
-	LEAQ		16(SP), SI
-	LEAQ		8(SP), DI
-	CLD
-	MOVSQ
-	MOVSQ
-	MOVSQ
-	SYSCALL
-	MOVQ	AX, r1+40(SP)
-	MOVQ	AX, r2+48(SP)
-	MOVQ	AX, err+56(SP)
-	RET
-
-TEXT	·RawSyscall6(SB),NOSPLIT,$0-80
-	MOVQ	$0x8000, AX	// for NxM
-	MOVQ	8(SP), BP	// syscall entry
-	// slide args down on top of system call number
-	LEAQ		16(SP), SI
-	LEAQ		8(SP), DI
-	CLD
-	MOVSQ
-	MOVSQ
-	MOVSQ
-	MOVSQ
-	MOVSQ
-	MOVSQ
-	SYSCALL
-	MOVQ	AX, r1+64(SP)
-	MOVQ	AX, r2+72(SP)
-	MOVQ	AX, err+80(SP)		
-	RET
-
-#define SYS_SEEK 39	/* from zsysnum_plan9_amd64.go */
-
-//func seek(placeholder uintptr, fd int, offset int64, whence int) (newoffset int64, err string)
-TEXT ·seek(SB),NOSPLIT,$0-56
-	LEAQ	newoffset+40(SP), AX
-	MOVQ	AX, placeholder+8(SP)
-	
-	MOVQ	$0x8000, AX	// for NxM
-	MOVQ	$SYS_SEEK, BP	// syscall entry
-	SYSCALL
-	
-	CMPL	AX, $-1
-	JNE	ok6
-	MOVQ	$-1, newoffset+40(SP)
-	
-	SUBQ	$16, SP
-	CALL	syscall·errstr(SB)
-	MOVQ	SP, SI
-	ADDQ	$16, SP	
-	JMP	copyresult6
-	
-ok6:
-	LEAQ	runtime·emptystring(SB), SI
-	
-copyresult6:
-	LEAQ	err+48(SP), DI
-
-	CLD
-	MOVSQ
-	MOVSQ
-	RET
-
-//func exit(code int)
-// Import runtime·exit for cleanly exiting.
-TEXT ·exit(SB),NOSPLIT,$8-8
-	MOVQ	code+0(FP), AX
-	MOVQ	AX, 0(SP)
-	CALL	runtime·exit(SB)
-	RET
diff --git a/src/pkg/syscall/asm_solaris_amd64.s b/src/pkg/syscall/asm_solaris_amd64.s
deleted file mode 100644
index 3735890..0000000
--- a/src/pkg/syscall/asm_solaris_amd64.s
+++ /dev/null
@@ -1,7 +0,0 @@
-// Copyright 2014 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//
-// System calls for amd64, Solaris are implemented in ../runtime/syscall_solaris.goc
-//
diff --git a/src/pkg/syscall/asm_windows_386.s b/src/pkg/syscall/asm_windows_386.s
deleted file mode 100644
index 8b52fa9..0000000
--- a/src/pkg/syscall/asm_windows_386.s
+++ /dev/null
@@ -1,7 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//
-// System calls for 386, Windows are implemented in ../runtime/syscall_windows.goc
-//
diff --git a/src/pkg/syscall/asm_windows_amd64.s b/src/pkg/syscall/asm_windows_amd64.s
deleted file mode 100644
index 5813404..0000000
--- a/src/pkg/syscall/asm_windows_amd64.s
+++ /dev/null
@@ -1,7 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//
-// System calls for amd64, Windows are implemented in ../runtime/syscall_windows.goc
-//
diff --git a/src/pkg/syscall/dll_windows.go b/src/pkg/syscall/dll_windows.go
deleted file mode 100644
index d29e992..0000000
--- a/src/pkg/syscall/dll_windows.go
+++ /dev/null
@@ -1,279 +0,0 @@
-// Copyright 2011 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package syscall
-
-import (
-	"sync"
-	"sync/atomic"
-	"unsafe"
-)
-
-// DLLError describes reasons for DLL load failures.
-type DLLError struct {
-	Err     error
-	ObjName string
-	Msg     string
-}
-
-func (e *DLLError) Error() string { return e.Msg }
-
-// Implemented in ../runtime/syscall_windows.goc.
-func Syscall(trap, nargs, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
-func Syscall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
-func Syscall9(trap, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err Errno)
-func Syscall12(trap, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12 uintptr) (r1, r2 uintptr, err Errno)
-func Syscall15(trap, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15 uintptr) (r1, r2 uintptr, err Errno)
-func loadlibrary(filename *uint16) (handle uintptr, err Errno)
-func getprocaddress(handle uintptr, procname *uint8) (proc uintptr, err Errno)
-
-// A DLL implements access to a single DLL.
-type DLL struct {
-	Name   string
-	Handle Handle
-}
-
-// LoadDLL loads DLL file into memory.
-func LoadDLL(name string) (dll *DLL, err error) {
-	namep, err := UTF16PtrFromString(name)
-	if err != nil {
-		return nil, err
-	}
-	h, e := loadlibrary(namep)
-	if e != 0 {
-		return nil, &DLLError{
-			Err:     e,
-			ObjName: name,
-			Msg:     "Failed to load " + name + ": " + e.Error(),
-		}
-	}
-	d := &DLL{
-		Name:   name,
-		Handle: Handle(h),
-	}
-	return d, nil
-}
-
-// MustLoadDLL is like LoadDLL but panics if load operation failes.
-func MustLoadDLL(name string) *DLL {
-	d, e := LoadDLL(name)
-	if e != nil {
-		panic(e)
-	}
-	return d
-}
-
-// FindProc searches DLL d for procedure named name and returns *Proc
-// if found. It returns an error if search fails.
-func (d *DLL) FindProc(name string) (proc *Proc, err error) {
-	namep, err := BytePtrFromString(name)
-	if err != nil {
-		return nil, err
-	}
-	a, e := getprocaddress(uintptr(d.Handle), namep)
-	if e != 0 {
-		return nil, &DLLError{
-			Err:     e,
-			ObjName: name,
-			Msg:     "Failed to find " + name + " procedure in " + d.Name + ": " + e.Error(),
-		}
-	}
-	p := &Proc{
-		Dll:  d,
-		Name: name,
-		addr: a,
-	}
-	return p, nil
-}
-
-// MustFindProc is like FindProc but panics if search fails.
-func (d *DLL) MustFindProc(name string) *Proc {
-	p, e := d.FindProc(name)
-	if e != nil {
-		panic(e)
-	}
-	return p
-}
-
-// Release unloads DLL d from memory.
-func (d *DLL) Release() (err error) {
-	return FreeLibrary(d.Handle)
-}
-
-// A Proc implements access to a procedure inside a DLL.
-type Proc struct {
-	Dll  *DLL
-	Name string
-	addr uintptr
-}
-
-// Addr returns the address of the procedure represented by p.
-// The return value can be passed to Syscall to run the procedure.
-func (p *Proc) Addr() uintptr {
-	return p.addr
-}
-
-// Call executes procedure p with arguments a. It will panic, if more then 15 arguments
-// are supplied.
-//
-// The returned error is always non-nil, constructed from the result of GetLastError.
-// Callers must inspect the primary return value to decide whether an error occurred
-// (according to the semantics of the specific function being called) before consulting
-// the error. The error will be guaranteed to contain syscall.Errno.
-func (p *Proc) Call(a ...uintptr) (r1, r2 uintptr, lastErr error) {
-	switch len(a) {
-	case 0:
-		return Syscall(p.Addr(), uintptr(len(a)), 0, 0, 0)
-	case 1:
-		return Syscall(p.Addr(), uintptr(len(a)), a[0], 0, 0)
-	case 2:
-		return Syscall(p.Addr(), uintptr(len(a)), a[0], a[1], 0)
-	case 3:
-		return Syscall(p.Addr(), uintptr(len(a)), a[0], a[1], a[2])
-	case 4:
-		return Syscall6(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], 0, 0)
-	case 5:
-		return Syscall6(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], 0)
-	case 6:
-		return Syscall6(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5])
-	case 7:
-		return Syscall9(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], 0, 0)
-	case 8:
-		return Syscall9(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], 0)
-	case 9:
-		return Syscall9(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8])
-	case 10:
-		return Syscall12(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], 0, 0)
-	case 11:
-		return Syscall12(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], 0)
-	case 12:
-		return Syscall12(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11])
-	case 13:
-		return Syscall15(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], 0, 0)
-	case 14:
-		return Syscall15(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], 0)
-	case 15:
-		return Syscall15(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14])
-	default:
-		panic("Call " + p.Name + " with too many arguments " + itoa(len(a)) + ".")
-	}
-	return
-}
-
-// A LazyDLL implements access to a single DLL.
-// It will delay the load of the DLL until the first
-// call to its Handle method or to one of its
-// LazyProc's Addr method.
-type LazyDLL struct {
-	mu   sync.Mutex
-	dll  *DLL // non nil once DLL is loaded
-	Name string
-}
-
-// Load loads DLL file d.Name into memory. It returns an error if fails.
-// Load will not try to load DLL, if it is already loaded into memory.
-func (d *LazyDLL) Load() error {
-	// Non-racy version of:
-	// if d.dll == nil {
-	if atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(&d.dll))) == nil {
-		d.mu.Lock()
-		defer d.mu.Unlock()
-		if d.dll == nil {
-			dll, e := LoadDLL(d.Name)
-			if e != nil {
-				return e
-			}
-			// Non-racy version of:
-			// d.dll = dll
-			atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(&d.dll)), unsafe.Pointer(dll))
-		}
-	}
-	return nil
-}
-
-// mustLoad is like Load but panics if search fails.
-func (d *LazyDLL) mustLoad() {
-	e := d.Load()
-	if e != nil {
-		panic(e)
-	}
-}
-
-// Handle returns d's module handle.
-func (d *LazyDLL) Handle() uintptr {
-	d.mustLoad()
-	return uintptr(d.dll.Handle)
-}
-
-// NewProc returns a LazyProc for accessing the named procedure in the DLL d.
-func (d *LazyDLL) NewProc(name string) *LazyProc {
-	return &LazyProc{l: d, Name: name}
-}
-
-// NewLazyDLL creates new LazyDLL associated with DLL file.
-func NewLazyDLL(name string) *LazyDLL {
-	return &LazyDLL{Name: name}
-}
-
-// A LazyProc implements access to a procedure inside a LazyDLL.
-// It delays the lookup until the Addr method is called.
-type LazyProc struct {
-	mu   sync.Mutex
-	Name string
-	l    *LazyDLL
-	proc *Proc
-}
-
-// Find searches DLL for procedure named p.Name. It returns
-// an error if search fails. Find will not search procedure,
-// if it is already found and loaded into memory.
-func (p *LazyProc) Find() error {
-	// Non-racy version of:
-	// if p.proc == nil {
-	if atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(&p.proc))) == nil {
-		p.mu.Lock()
-		defer p.mu.Unlock()
-		if p.proc == nil {
-			e := p.l.Load()
-			if e != nil {
-				return e
-			}
-			proc, e := p.l.dll.FindProc(p.Name)
-			if e != nil {
-				return e
-			}
-			// Non-racy version of:
-			// p.proc = proc
-			atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(&p.proc)), unsafe.Pointer(proc))
-		}
-	}
-	return nil
-}
-
-// mustFind is like Find but panics if search fails.
-func (p *LazyProc) mustFind() {
-	e := p.Find()
-	if e != nil {
-		panic(e)
-	}
-}
-
-// Addr returns the address of the procedure represented by p.
-// The return value can be passed to Syscall to run the procedure.
-func (p *LazyProc) Addr() uintptr {
-	p.mustFind()
-	return p.proc.Addr()
-}
-
-// Call executes procedure p with arguments a. It will panic, if more then 15 arguments
-// are supplied.
-//
-// The returned error is always non-nil, constructed from the result of GetLastError.
-// Callers must inspect the primary return value to decide whether an error occurred
-// (according to the semantics of the specific function being called) before consulting
-// the error. The error will be guaranteed to contain syscall.Errno.
-func (p *LazyProc) Call(a ...uintptr) (r1, r2 uintptr, lastErr error) {
-	p.mustFind()
-	return p.proc.Call(a...)
-}
diff --git a/src/pkg/syscall/env_plan9.go b/src/pkg/syscall/env_plan9.go
deleted file mode 100644
index 9587ab5..0000000
--- a/src/pkg/syscall/env_plan9.go
+++ /dev/null
@@ -1,142 +0,0 @@
-// Copyright 2011 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Plan 9 environment variables.
-
-package syscall
-
-import (
-	"errors"
-	"sync"
-)
-
-var (
-	// envOnce guards copyenv, which populates env.
-	envOnce sync.Once
-
-	// envLock guards env and envs.
-	envLock sync.RWMutex
-
-	// env maps from an environment variable to its value.
-	env = make(map[string]string)
-
-	// envs contains elements of env in the form "key=value".
-	envs []string
-
-	errZeroLengthKey = errors.New("zero length key")
-	errShortWrite    = errors.New("i/o count too small")
-)
-
-func readenv(key string) (string, error) {
-	fd, err := Open("/env/"+key, O_RDONLY)
-	if err != nil {
-		return "", err
-	}
-	defer Close(fd)
-	l, _ := Seek(fd, 0, 2)
-	Seek(fd, 0, 0)
-	buf := make([]byte, l)
-	n, err := Read(fd, buf)
-	if err != nil {
-		return "", err
-	}
-	if n > 0 && buf[n-1] == 0 {
-		buf = buf[:n-1]
-	}
-	return string(buf), nil
-}
-
-func writeenv(key, value string) error {
-	fd, err := Create("/env/"+key, O_RDWR, 0666)
-	if err != nil {
-		return err
-	}
-	defer Close(fd)
-	b := []byte(value)
-	n, err := Write(fd, b)
-	if err != nil {
-		return err
-	}
-	if n != len(b) {
-		return errShortWrite
-	}
-	return nil
-}
-
-func copyenv() {
-	fd, err := Open("/env", O_RDONLY)
-	if err != nil {
-		return
-	}
-	defer Close(fd)
-	files, err := readdirnames(fd)
-	if err != nil {
-		return
-	}
-	envs = make([]string, len(files))
-	i := 0
-	for _, key := range files {
-		v, err := readenv(key)
-		if err != nil {
-			continue
-		}
-		env[key] = v
-		envs[i] = key + "=" + v
-		i++
-	}
-}
-
-func Getenv(key string) (value string, found bool) {
-	if len(key) == 0 {
-		return "", false
-	}
-
-	envLock.RLock()
-	defer envLock.RUnlock()
-
-	if v, ok := env[key]; ok {
-		return v, true
-	}
-	v, err := readenv(key)
-	if err != nil {
-		return "", false
-	}
-	env[key] = v
-	envs = append(envs, key+"="+v)
-	return v, true
-}
-
-func Setenv(key, value string) error {
-	if len(key) == 0 {
-		return errZeroLengthKey
-	}
-
-	envLock.Lock()
-	defer envLock.Unlock()
-
-	err := writeenv(key, value)
-	if err != nil {
-		return err
-	}
-	env[key] = value
-	envs = append(envs, key+"="+value)
-	return nil
-}
-
-func Clearenv() {
-	envLock.Lock()
-	defer envLock.Unlock()
-
-	env = make(map[string]string)
-	envs = []string{}
-	RawSyscall(SYS_RFORK, RFCENVG, 0, 0)
-}
-
-func Environ() []string {
-	envLock.RLock()
-	defer envLock.RUnlock()
-
-	envOnce.Do(copyenv)
-	return append([]string(nil), envs...)
-}
diff --git a/src/pkg/syscall/env_unix.go b/src/pkg/syscall/env_unix.go
deleted file mode 100644
index ad354ed..0000000
--- a/src/pkg/syscall/env_unix.go
+++ /dev/null
@@ -1,119 +0,0 @@
-// Copyright 2010 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris
-
-// Unix environment variables.
-
-package syscall
-
-import "sync"
-
-var (
-	// envOnce guards initialization by copyenv, which populates env.
-	envOnce sync.Once
-
-	// envLock guards env and envs.
-	envLock sync.RWMutex
-
-	// env maps from an environment variable to its first occurrence in envs.
-	env map[string]int
-
-	// envs is provided by the runtime. elements are expected to be
-	// of the form "key=value".
-	envs []string
-)
-
-// setenv_c is provided by the runtime, but is a no-op if cgo isn't
-// loaded.
-func setenv_c(k, v string)
-
-func copyenv() {
-	env = make(map[string]int)
-	for i, s := range envs {
-		for j := 0; j < len(s); j++ {
-			if s[j] == '=' {
-				key := s[:j]
-				if _, ok := env[key]; !ok {
-					env[key] = i
-				}
-				break
-			}
-		}
-	}
-}
-
-func Getenv(key string) (value string, found bool) {
-	envOnce.Do(copyenv)
-	if len(key) == 0 {
-		return "", false
-	}
-
-	envLock.RLock()
-	defer envLock.RUnlock()
-
-	i, ok := env[key]
-	if !ok {
-		return "", false
-	}
-	s := envs[i]
-	for i := 0; i < len(s); i++ {
-		if s[i] == '=' {
-			return s[i+1:], true
-		}
-	}
-	return "", false
-}
-
-func Setenv(key, value string) error {
-	envOnce.Do(copyenv)
-	if len(key) == 0 {
-		return EINVAL
-	}
-	for i := 0; i < len(key); i++ {
-		if key[i] == '=' || key[i] == 0 {
-			return EINVAL
-		}
-	}
-	for i := 0; i < len(value); i++ {
-		if value[i] == 0 {
-			return EINVAL
-		}
-	}
-
-	envLock.Lock()
-	defer envLock.Unlock()
-
-	i, ok := env[key]
-	kv := key + "=" + value
-	if ok {
-		envs[i] = kv
-	} else {
-		i = len(envs)
-		envs = append(envs, kv)
-	}
-	env[key] = i
-	setenv_c(key, value)
-	return nil
-}
-
-func Clearenv() {
-	envOnce.Do(copyenv) // prevent copyenv in Getenv/Setenv
-
-	envLock.Lock()
-	defer envLock.Unlock()
-
-	env = make(map[string]int)
-	envs = []string{}
-	// TODO(bradfitz): pass through to C
-}
-
-func Environ() []string {
-	envOnce.Do(copyenv)
-	envLock.RLock()
-	defer envLock.RUnlock()
-	a := make([]string, len(envs))
-	copy(a, envs)
-	return a
-}
diff --git a/src/pkg/syscall/env_windows.go b/src/pkg/syscall/env_windows.go
deleted file mode 100644
index 420b387..0000000
--- a/src/pkg/syscall/env_windows.go
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright 2010 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Windows environment variables.
-
-package syscall
-
-import (
-	"unicode/utf16"
-	"unsafe"
-)
-
-func Getenv(key string) (value string, found bool) {
-	keyp, err := UTF16PtrFromString(key)
-	if err != nil {
-		return "", false
-	}
-	b := make([]uint16, 100)
-	n, e := GetEnvironmentVariable(keyp, &b[0], uint32(len(b)))
-	if n == 0 && e == ERROR_ENVVAR_NOT_FOUND {
-		return "", false
-	}
-	if n > uint32(len(b)) {
-		b = make([]uint16, n)
-		n, e = GetEnvironmentVariable(keyp, &b[0], uint32(len(b)))
-		if n > uint32(len(b)) {
-			n = 0
-		}
-	}
-	return string(utf16.Decode(b[0:n])), true
-}
-
-func Setenv(key, value string) error {
-	v, err := UTF16PtrFromString(value)
-	if err != nil {
-		return err
-	}
-	keyp, err := UTF16PtrFromString(key)
-	if err != nil {
-		return err
-	}
-	e := SetEnvironmentVariable(keyp, v)
-	if e != nil {
-		return e
-	}
-	return nil
-}
-
-func Clearenv() {
-	for _, s := range Environ() {
-		// Environment variables can begin with =
-		// so start looking for the separator = at j=1.
-		// http://blogs.msdn.com/b/oldnewthing/archive/2010/05/06/10008132.aspx
-		for j := 1; j < len(s); j++ {
-			if s[j] == '=' {
-				Setenv(s[0:j], "")
-				break
-			}
-		}
-	}
-}
-
-func Environ() []string {
-	s, e := GetEnvironmentStrings()
-	if e != nil {
-		return nil
-	}
-	defer FreeEnvironmentStrings(s)
-	r := make([]string, 0, 50) // Empty with room to grow.
-	for from, i, p := 0, 0, (*[1 << 24]uint16)(unsafe.Pointer(s)); true; i++ {
-		if p[i] == 0 {
-			// empty string marks the end
-			if i <= from {
-				break
-			}
-			r = append(r, string(utf16.Decode(p[from:i])))
-			from = i + 1
-		}
-	}
-	return r
-}
diff --git a/src/pkg/syscall/exec_linux.go b/src/pkg/syscall/exec_linux.go
deleted file mode 100644
index f27950f..0000000
--- a/src/pkg/syscall/exec_linux.go
+++ /dev/null
@@ -1,262 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build linux
-
-package syscall
-
-import (
-	"unsafe"
-)
-
-type SysProcAttr struct {
-	Chroot     string      // Chroot.
-	Credential *Credential // Credential.
-	Ptrace     bool        // Enable tracing.
-	Setsid     bool        // Create session.
-	Setpgid    bool        // Set process group ID to new pid (SYSV setpgrp)
-	Setctty    bool        // Set controlling terminal to fd Ctty (only meaningful if Setsid is set)
-	Noctty     bool        // Detach fd 0 from controlling terminal
-	Ctty       int         // Controlling TTY fd (Linux only)
-	Pdeathsig  Signal      // Signal that the process will get when its parent dies (Linux only)
-	Cloneflags uintptr     // Flags for clone calls (Linux only)
-}
-
-// Implemented in runtime package.
-func runtime_BeforeFork()
-func runtime_AfterFork()
-
-// Fork, dup fd onto 0..len(fd), and exec(argv0, argvv, envv) in child.
-// If a dup or exec fails, write the errno error to pipe.
-// (Pipe is close-on-exec so if exec succeeds, it will be closed.)
-// In the child, this function must not acquire any locks, because
-// they might have been locked at the time of the fork.  This means
-// no rescheduling, no malloc calls, and no new stack segments.
-// For the same reason compiler does not race instrument it.
-// The calls to RawSyscall are okay because they are assembly
-// functions that do not grow the stack.
-func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr *ProcAttr, sys *SysProcAttr, pipe int) (pid int, err Errno) {
-	// Declare all variables at top in case any
-	// declarations require heap allocation (e.g., err1).
-	var (
-		r1     uintptr
-		err1   Errno
-		nextfd int
-		i      int
-	)
-
-	// Guard against side effects of shuffling fds below.
-	// Make sure that nextfd is beyond any currently open files so
-	// that we can't run the risk of overwriting any of them.
-	fd := make([]int, len(attr.Files))
-	nextfd = len(attr.Files)
-	for i, ufd := range attr.Files {
-		if nextfd < int(ufd) {
-			nextfd = int(ufd)
-		}
-		fd[i] = int(ufd)
-	}
-	nextfd++
-
-	// About to call fork.
-	// No more allocation or calls of non-assembly functions.
-	runtime_BeforeFork()
-	r1, _, err1 = RawSyscall6(SYS_CLONE, uintptr(SIGCHLD)|sys.Cloneflags, 0, 0, 0, 0, 0)
-	if err1 != 0 {
-		runtime_AfterFork()
-		return 0, err1
-	}
-
-	if r1 != 0 {
-		// parent; return PID
-		runtime_AfterFork()
-		return int(r1), 0
-	}
-
-	// Fork succeeded, now in child.
-
-	// Parent death signal
-	if sys.Pdeathsig != 0 {
-		_, _, err1 = RawSyscall6(SYS_PRCTL, PR_SET_PDEATHSIG, uintptr(sys.Pdeathsig), 0, 0, 0, 0)
-		if err1 != 0 {
-			goto childerror
-		}
-
-		// Signal self if parent is already dead. This might cause a
-		// duplicate signal in rare cases, but it won't matter when
-		// using SIGKILL.
-		r1, _, _ = RawSyscall(SYS_GETPPID, 0, 0, 0)
-		if r1 == 1 {
-			pid, _, _ := RawSyscall(SYS_GETPID, 0, 0, 0)
-			_, _, err1 := RawSyscall(SYS_KILL, pid, uintptr(sys.Pdeathsig), 0)
-			if err1 != 0 {
-				goto childerror
-			}
-		}
-	}
-
-	// Enable tracing if requested.
-	if sys.Ptrace {
-		_, _, err1 = RawSyscall(SYS_PTRACE, uintptr(PTRACE_TRACEME), 0, 0)
-		if err1 != 0 {
-			goto childerror
-		}
-	}
-
-	// Session ID
-	if sys.Setsid {
-		_, _, err1 = RawSyscall(SYS_SETSID, 0, 0, 0)
-		if err1 != 0 {
-			goto childerror
-		}
-	}
-
-	// Set process group
-	if sys.Setpgid {
-		_, _, err1 = RawSyscall(SYS_SETPGID, 0, 0, 0)
-		if err1 != 0 {
-			goto childerror
-		}
-	}
-
-	// Chroot
-	if chroot != nil {
-		_, _, err1 = RawSyscall(SYS_CHROOT, uintptr(unsafe.Pointer(chroot)), 0, 0)
-		if err1 != 0 {
-			goto childerror
-		}
-	}
-
-	// User and groups
-	if cred := sys.Credential; cred != nil {
-		ngroups := uintptr(len(cred.Groups))
-		var groups unsafe.Pointer
-		if ngroups > 0 {
-			groups = unsafe.Pointer(&cred.Groups[0])
-		}
-		_, _, err1 = RawSyscall(SYS_SETGROUPS, ngroups, uintptr(groups), 0)
-		if err1 != 0 {
-			goto childerror
-		}
-		_, _, err1 = RawSyscall(SYS_SETGID, uintptr(cred.Gid), 0, 0)
-		if err1 != 0 {
-			goto childerror
-		}
-		_, _, err1 = RawSyscall(SYS_SETUID, uintptr(cred.Uid), 0, 0)
-		if err1 != 0 {
-			goto childerror
-		}
-	}
-
-	// Chdir
-	if dir != nil {
-		_, _, err1 = RawSyscall(SYS_CHDIR, uintptr(unsafe.Pointer(dir)), 0, 0)
-		if err1 != 0 {
-			goto childerror
-		}
-	}
-
-	// Pass 1: look for fd[i] < i and move those up above len(fd)
-	// so that pass 2 won't stomp on an fd it needs later.
-	if pipe < nextfd {
-		_, _, err1 = RawSyscall(SYS_DUP2, uintptr(pipe), uintptr(nextfd), 0)
-		if err1 != 0 {
-			goto childerror
-		}
-		RawSyscall(SYS_FCNTL, uintptr(nextfd), F_SETFD, FD_CLOEXEC)
-		pipe = nextfd
-		nextfd++
-	}
-	for i = 0; i < len(fd); i++ {
-		if fd[i] >= 0 && fd[i] < int(i) {
-			_, _, err1 = RawSyscall(SYS_DUP2, uintptr(fd[i]), uintptr(nextfd), 0)
-			if err1 != 0 {
-				goto childerror
-			}
-			RawSyscall(SYS_FCNTL, uintptr(nextfd), F_SETFD, FD_CLOEXEC)
-			fd[i] = nextfd
-			nextfd++
-			if nextfd == pipe { // don't stomp on pipe
-				nextfd++
-			}
-		}
-	}
-
-	// Pass 2: dup fd[i] down onto i.
-	for i = 0; i < len(fd); i++ {
-		if fd[i] == -1 {
-			RawSyscall(SYS_CLOSE, uintptr(i), 0, 0)
-			continue
-		}
-		if fd[i] == int(i) {
-			// dup2(i, i) won't clear close-on-exec flag on Linux,
-			// probably not elsewhere either.
-			_, _, err1 = RawSyscall(SYS_FCNTL, uintptr(fd[i]), F_SETFD, 0)
-			if err1 != 0 {
-				goto childerror
-			}
-			continue
-		}
-		// The new fd is created NOT close-on-exec,
-		// which is exactly what we want.
-		_, _, err1 = RawSyscall(SYS_DUP2, uintptr(fd[i]), uintptr(i), 0)
-		if err1 != 0 {
-			goto childerror
-		}
-	}
-
-	// By convention, we don't close-on-exec the fds we are
-	// started with, so if len(fd) < 3, close 0, 1, 2 as needed.
-	// Programs that know they inherit fds >= 3 will need
-	// to set them close-on-exec.
-	for i = len(fd); i < 3; i++ {
-		RawSyscall(SYS_CLOSE, uintptr(i), 0, 0)
-	}
-
-	// Detach fd 0 from tty
-	if sys.Noctty {
-		_, _, err1 = RawSyscall(SYS_IOCTL, 0, uintptr(TIOCNOTTY), 0)
-		if err1 != 0 {
-			goto childerror
-		}
-	}
-
-	// Set the controlling TTY to Ctty
-	if sys.Setctty && sys.Ctty >= 0 {
-		_, _, err1 = RawSyscall(SYS_IOCTL, uintptr(sys.Ctty), uintptr(TIOCSCTTY), 0)
-		if err1 != 0 {
-			goto childerror
-		}
-	}
-
-	// Time to exec.
-	_, _, err1 = RawSyscall(SYS_EXECVE,
-		uintptr(unsafe.Pointer(argv0)),
-		uintptr(unsafe.Pointer(&argv[0])),
-		uintptr(unsafe.Pointer(&envv[0])))
-
-childerror:
-	// send error code on pipe
-	RawSyscall(SYS_WRITE, uintptr(pipe), uintptr(unsafe.Pointer(&err1)), unsafe.Sizeof(err1))
-	for {
-		RawSyscall(SYS_EXIT, 253, 0, 0)
-	}
-}
-
-// Try to open a pipe with O_CLOEXEC set on both file descriptors.
-func forkExecPipe(p []int) (err error) {
-	err = Pipe2(p, O_CLOEXEC)
-	// pipe2 was added in 2.6.27 and our minimum requirement is 2.6.23, so it
-	// might not be implemented.
-	if err == ENOSYS {
-		if err = Pipe(p); err != nil {
-			return
-		}
-		if _, err = fcntl(p[0], F_SETFD, FD_CLOEXEC); err != nil {
-			return
-		}
-		_, err = fcntl(p[1], F_SETFD, FD_CLOEXEC)
-	}
-	return
-}
diff --git a/src/pkg/syscall/exec_windows.go b/src/pkg/syscall/exec_windows.go
deleted file mode 100644
index 82abc07..0000000
--- a/src/pkg/syscall/exec_windows.go
+++ /dev/null
@@ -1,341 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Fork, exec, wait, etc.
-
-package syscall
-
-import (
-	"sync"
-	"unicode/utf16"
-	"unsafe"
-)
-
-var ForkLock sync.RWMutex
-
-// EscapeArg rewrites command line argument s as prescribed
-// in http://msdn.microsoft.com/en-us/library/ms880421.
-// This function returns "" (2 double quotes) if s is empty.
-// Alternatively, these transformations are done:
-// - every back slash (\) is doubled, but only if immediately
-//   followed by double quote (");
-// - every double quote (") is escaped by back slash (\);
-// - finally, s is wrapped with double quotes (arg -> "arg"),
-//   but only if there is space or tab inside s.
-func EscapeArg(s string) string {
-	if len(s) == 0 {
-		return "\"\""
-	}
-	n := len(s)
-	hasSpace := false
-	for i := 0; i < len(s); i++ {
-		switch s[i] {
-		case '"', '\\':
-			n++
-		case ' ', '\t':
-			hasSpace = true
-		}
-	}
-	if hasSpace {
-		n += 2
-	}
-	if n == len(s) {
-		return s
-	}
-
-	qs := make([]byte, n)
-	j := 0
-	if hasSpace {
-		qs[j] = '"'
-		j++
-	}
-	slashes := 0
-	for i := 0; i < len(s); i++ {
-		switch s[i] {
-		default:
-			slashes = 0
-			qs[j] = s[i]
-		case '\\':
-			slashes++
-			qs[j] = s[i]
-		case '"':
-			for ; slashes > 0; slashes-- {
-				qs[j] = '\\'
-				j++
-			}
-			qs[j] = '\\'
-			j++
-			qs[j] = s[i]
-		}
-		j++
-	}
-	if hasSpace {
-		for ; slashes > 0; slashes-- {
-			qs[j] = '\\'
-			j++
-		}
-		qs[j] = '"'
-		j++
-	}
-	return string(qs[:j])
-}
-
-// makeCmdLine builds a command line out of args by escaping "special"
-// characters and joining the arguments with spaces.
-func makeCmdLine(args []string) string {
-	var s string
-	for _, v := range args {
-		if s != "" {
-			s += " "
-		}
-		s += EscapeArg(v)
-	}
-	return s
-}
-
-// createEnvBlock converts an array of environment strings into
-// the representation required by CreateProcess: a sequence of NUL
-// terminated strings followed by a nil.
-// Last bytes are two UCS-2 NULs, or four NUL bytes.
-func createEnvBlock(envv []string) *uint16 {
-	if len(envv) == 0 {
-		return &utf16.Encode([]rune("\x00\x00"))[0]
-	}
-	length := 0
-	for _, s := range envv {
-		length += len(s) + 1
-	}
-	length += 1
-
-	b := make([]byte, length)
-	i := 0
-	for _, s := range envv {
-		l := len(s)
-		copy(b[i:i+l], []byte(s))
-		copy(b[i+l:i+l+1], []byte{0})
-		i = i + l + 1
-	}
-	copy(b[i:i+1], []byte{0})
-
-	return &utf16.Encode([]rune(string(b)))[0]
-}
-
-func CloseOnExec(fd Handle) {
-	SetHandleInformation(Handle(fd), HANDLE_FLAG_INHERIT, 0)
-}
-
-func SetNonblock(fd Handle, nonblocking bool) (err error) {
-	return nil
-}
-
-// getFullPath retrieves the full path of the specified file.
-// Just a wrapper for Windows GetFullPathName api.
-func getFullPath(name string) (path string, err error) {
-	p, err := UTF16PtrFromString(name)
-	if err != nil {
-		return "", err
-	}
-	buf := make([]uint16, 100)
-	n, err := GetFullPathName(p, uint32(len(buf)), &buf[0], nil)
-	if err != nil {
-		return "", err
-	}
-	if n > uint32(len(buf)) {
-		// Windows is asking for bigger buffer.
-		buf = make([]uint16, n)
-		n, err = GetFullPathName(p, uint32(len(buf)), &buf[0], nil)
-		if err != nil {
-			return "", err
-		}
-		if n > uint32(len(buf)) {
-			return "", EINVAL
-		}
-	}
-	return UTF16ToString(buf[:n]), nil
-}
-
-func isSlash(c uint8) bool {
-	return c == '\\' || c == '/'
-}
-
-func normalizeDir(dir string) (name string, err error) {
-	ndir, err := getFullPath(dir)
-	if err != nil {
-		return "", err
-	}
-	if len(ndir) > 2 && isSlash(ndir[0]) && isSlash(ndir[1]) {
-		// dir cannot have \\server\share\path form
-		return "", EINVAL
-	}
-	return ndir, nil
-}
-
-func volToUpper(ch int) int {
-	if 'a' <= ch && ch <= 'z' {
-		ch += 'A' - 'a'
-	}
-	return ch
-}
-
-func joinExeDirAndFName(dir, p string) (name string, err error) {
-	if len(p) == 0 {
-		return "", EINVAL
-	}
-	if len(p) > 2 && isSlash(p[0]) && isSlash(p[1]) {
-		// \\server\share\path form
-		return p, nil
-	}
-	if len(p) > 1 && p[1] == ':' {
-		// has drive letter
-		if len(p) == 2 {
-			return "", EINVAL
-		}
-		if isSlash(p[2]) {
-			return p, nil
-		} else {
-			d, err := normalizeDir(dir)
-			if err != nil {
-				return "", err
-			}
-			if volToUpper(int(p[0])) == volToUpper(int(d[0])) {
-				return getFullPath(d + "\\" + p[2:])
-			} else {
-				return getFullPath(p)
-			}
-		}
-	} else {
-		// no drive letter
-		d, err := normalizeDir(dir)
-		if err != nil {
-			return "", err
-		}
-		if isSlash(p[0]) {
-			return getFullPath(d[:2] + p)
-		} else {
-			return getFullPath(d + "\\" + p)
-		}
-	}
-	// we shouldn't be here
-	return "", EINVAL
-}
-
-type ProcAttr struct {
-	Dir   string
-	Env   []string
-	Files []uintptr
-	Sys   *SysProcAttr
-}
-
-type SysProcAttr struct {
-	HideWindow    bool
-	CmdLine       string // used if non-empty, else the windows command line is built by escaping the arguments passed to StartProcess
-	CreationFlags uint32
-}
-
-var zeroProcAttr ProcAttr
-var zeroSysProcAttr SysProcAttr
-
-func StartProcess(argv0 string, argv []string, attr *ProcAttr) (pid int, handle uintptr, err error) {
-	if len(argv0) == 0 {
-		return 0, 0, EWINDOWS
-	}
-	if attr == nil {
-		attr = &zeroProcAttr
-	}
-	sys := attr.Sys
-	if sys == nil {
-		sys = &zeroSysProcAttr
-	}
-
-	if len(attr.Files) > 3 {
-		return 0, 0, EWINDOWS
-	}
-
-	if len(attr.Dir) != 0 {
-		// StartProcess assumes that argv0 is relative to attr.Dir,
-		// because it implies Chdir(attr.Dir) before executing argv0.
-		// Windows CreateProcess assumes the opposite: it looks for
-		// argv0 relative to the current directory, and, only once the new
-		// process is started, it does Chdir(attr.Dir). We are adjusting
-		// for that difference here by making argv0 absolute.
-		var err error
-		argv0, err = joinExeDirAndFName(attr.Dir, argv0)
-		if err != nil {
-			return 0, 0, err
-		}
-	}
-	argv0p, err := UTF16PtrFromString(argv0)
-	if err != nil {
-		return 0, 0, err
-	}
-
-	var cmdline string
-	// Windows CreateProcess takes the command line as a single string:
-	// use attr.CmdLine if set, else build the command line by escaping
-	// and joining each argument with spaces
-	if sys.CmdLine != "" {
-		cmdline = sys.CmdLine
-	} else {
-		cmdline = makeCmdLine(argv)
-	}
-
-	var argvp *uint16
-	if len(cmdline) != 0 {
-		argvp, err = UTF16PtrFromString(cmdline)
-		if err != nil {
-			return 0, 0, err
-		}
-	}
-
-	var dirp *uint16
-	if len(attr.Dir) != 0 {
-		dirp, err = UTF16PtrFromString(attr.Dir)
-		if err != nil {
-			return 0, 0, err
-		}
-	}
-
-	// Acquire the fork lock so that no other threads
-	// create new fds that are not yet close-on-exec
-	// before we fork.
-	ForkLock.Lock()
-	defer ForkLock.Unlock()
-
-	p, _ := GetCurrentProcess()
-	fd := make([]Handle, len(attr.Files))
-	for i := range attr.Files {
-		if attr.Files[i] > 0 {
-			err := DuplicateHandle(p, Handle(attr.Files[i]), p, &fd[i], 0, true, DUPLICATE_SAME_ACCESS)
-			if err != nil {
-				return 0, 0, err
-			}
-			defer CloseHandle(Handle(fd[i]))
-		}
-	}
-	si := new(StartupInfo)
-	si.Cb = uint32(unsafe.Sizeof(*si))
-	si.Flags = STARTF_USESTDHANDLES
-	if sys.HideWindow {
-		si.Flags |= STARTF_USESHOWWINDOW
-		si.ShowWindow = SW_HIDE
-	}
-	si.StdInput = fd[0]
-	si.StdOutput = fd[1]
-	si.StdErr = fd[2]
-
-	pi := new(ProcessInformation)
-
-	flags := sys.CreationFlags | CREATE_UNICODE_ENVIRONMENT
-	err = CreateProcess(argv0p, argvp, nil, nil, true, flags, createEnvBlock(attr.Env), dirp, si, pi)
-	if err != nil {
-		return 0, 0, err
-	}
-	defer CloseHandle(Handle(pi.Thread))
-
-	return int(pi.ProcessId), uintptr(pi.Process), nil
-}
-
-func Exec(argv0 string, argv []string, envv []string) (err error) {
-	return EWINDOWS
-}
diff --git a/src/pkg/syscall/fs_nacl.go b/src/pkg/syscall/fs_nacl.go
deleted file mode 100644
index ac92394..0000000
--- a/src/pkg/syscall/fs_nacl.go
+++ /dev/null
@@ -1,815 +0,0 @@
-// Copyright 2013 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// A simulated Unix-like file system for use within NaCl.
-//
-// The simulation is not particularly tied to NaCl other than the reuse
-// of NaCl's definition for the Stat_t structure.
-//
-// The file system need never be written to disk, so it is represented as
-// in-memory Go data structures, never in a serialized form.
-//
-// TODO: Perhaps support symlinks, although they muck everything up.
-
-package syscall
-
-import (
-	"sync"
-	"unsafe"
-)
-
-// Provided by package runtime.
-func now() (sec int64, nsec int32)
-
-// An fsys is a file system.
-// Since there is no I/O (everything is in memory),
-// the global lock mu protects the whole file system state,
-// and that's okay.
-type fsys struct {
-	mu   sync.Mutex
-	root *inode                    // root directory
-	cwd  *inode                    // process current directory
-	inum uint64                    // number of inodes created
-	dev  []func() (devFile, error) // table for opening devices
-}
-
-// A devFile is the implementation required of device files
-// like /dev/null or /dev/random.
-type devFile interface {
-	pread([]byte, int64) (int, error)
-	pwrite([]byte, int64) (int, error)
-}
-
-// An inode is a (possibly special) file in the file system.
-type inode struct {
-	Stat_t
-	data []byte
-	dir  []dirent
-}
-
-// A dirent describes a single directory entry.
-type dirent struct {
-	name  string
-	inode *inode
-}
-
-// An fsysFile is the fileImpl implementation backed by the file system.
-type fsysFile struct {
-	defaultFileImpl
-	fsys     *fsys
-	inode    *inode
-	openmode int
-	offset   int64
-	dev      devFile
-}
-
-// newFsys creates a new file system.
-func newFsys() *fsys {
-	fs := &fsys{}
-	fs.mu.Lock()
-	defer fs.mu.Unlock()
-	ip := fs.newInode()
-	ip.Mode = 0555 | S_IFDIR
-	fs.dirlink(ip, ".", ip)
-	fs.dirlink(ip, "..", ip)
-	fs.cwd = ip
-	fs.root = ip
-	return fs
-}
-
-var fs = newFsys()
-
-func init() {
-	Mkdir("/dev", 0555)
-	Mkdir("/tmp", 0777)
-	mkdev("/dev/null", 0666, openNull)
-	mkdev("/dev/random", 0444, openRandom)
-	mkdev("/dev/urandom", 0444, openRandom)
-	mkdev("/dev/zero", 0666, openZero)
-	chdirEnv()
-}
-
-func chdirEnv() {
-	pwd, ok := Getenv("NACLPWD")
-	if ok {
-		Chdir(pwd)
-	}
-}
-
-// Except where indicated otherwise, unexported methods on fsys
-// expect fs.mu to have been locked by the caller.
-
-// newInode creates a new inode.
-func (fs *fsys) newInode() *inode {
-	fs.inum++
-	ip := &inode{
-		Stat_t: Stat_t{
-			Ino:     fs.inum,
-			Blksize: 512,
-		},
-	}
-	return ip
-}
-
-// atime sets ip.Atime to the current time.
-func (fs *fsys) atime(ip *inode) {
-	sec, nsec := now()
-	ip.Atime, ip.AtimeNsec = sec, int64(nsec)
-}
-
-// mtime sets ip.Mtime to the current time.
-func (fs *fsys) mtime(ip *inode) {
-	sec, nsec := now()
-	ip.Mtime, ip.MtimeNsec = sec, int64(nsec)
-}
-
-// dirlookup looks for an entry in the directory dp with the given name.
-// It returns the directory entry and its index within the directory.
-func (fs *fsys) dirlookup(dp *inode, name string) (de *dirent, index int, err error) {
-	fs.atime(dp)
-	for i := range dp.dir {
-		de := &dp.dir[i]
-		if de.name == name {
-			fs.atime(de.inode)
-			return de, i, nil
-		}
-	}
-	return nil, 0, ENOENT
-}
-
-// dirlink adds to the directory dp an entry for name pointing at the inode ip.
-// If dp already contains an entry for name, that entry is overwritten.
-func (fs *fsys) dirlink(dp *inode, name string, ip *inode) {
-	fs.mtime(dp)
-	fs.atime(ip)
-	ip.Nlink++
-	for i := range dp.dir {
-		if dp.dir[i].name == name {
-			dp.dir[i] = dirent{name, ip}
-			return
-		}
-	}
-	dp.dir = append(dp.dir, dirent{name, ip})
-	dp.dirSize()
-}
-
-func (dp *inode) dirSize() {
-	dp.Size = int64(len(dp.dir)) * (8 + 8 + 2 + 256) // Dirent
-}
-
-// skipelem splits path into the first element and the remainder.
-// the returned first element contains no slashes, and the returned
-// remainder does not begin with a slash.
-func skipelem(path string) (elem, rest string) {
-	for len(path) > 0 && path[0] == '/' {
-		path = path[1:]
-	}
-	if len(path) == 0 {
-		return "", ""
-	}
-	i := 0
-	for i < len(path) && path[i] != '/' {
-		i++
-	}
-	elem, path = path[:i], path[i:]
-	for len(path) > 0 && path[0] == '/' {
-		path = path[1:]
-	}
-	return elem, path
-}
-
-// namei translates a file system path name into an inode.
-// If parent is false, the returned ip corresponds to the given name, and elem is the empty string.
-// If parent is false, the walk stops at the next-to-last element in the name,
-// so that ip is the parent directory and elem is the final element in the path.
-func (fs *fsys) namei(path string, parent bool) (ip *inode, elem string, err error) {
-	// Reject NUL in name.
-	for i := 0; i < len(path); i++ {
-		if path[i] == '\x00' {
-			return nil, "", EINVAL
-		}
-	}
-
-	// Reject empty name.
-	if path == "" {
-		return nil, "", EINVAL
-	}
-
-	if path[0] == '/' {
-		ip = fs.root
-	} else {
-		ip = fs.cwd
-	}
-
-	for len(path) > 0 && path[len(path)-1] == '/' {
-		path = path[:len(path)-1]
-	}
-
-	for {
-		elem, rest := skipelem(path)
-		if elem == "" {
-			if parent && ip.Mode&S_IFMT == S_IFDIR {
-				return ip, ".", nil
-			}
-			break
-		}
-		if ip.Mode&S_IFMT != S_IFDIR {
-			return nil, "", ENOTDIR
-		}
-		if len(elem) >= 256 {
-			return nil, "", ENAMETOOLONG
-		}
-		if parent && rest == "" {
-			// Stop one level early.
-			return ip, elem, nil
-		}
-		de, _, err := fs.dirlookup(ip, elem)
-		if err != nil {
-			return nil, "", err
-		}
-		ip = de.inode
-		path = rest
-	}
-	if parent {
-		return nil, "", ENOTDIR
-	}
-	return ip, "", nil
-}
-
-// open opens or creates a file with the given name, open mode,
-// and permission mode bits.
-func (fs *fsys) open(name string, openmode int, mode uint32) (fileImpl, error) {
-	dp, elem, err := fs.namei(name, true)
-	if err != nil {
-		return nil, err
-	}
-	var (
-		ip  *inode
-		dev devFile
-	)
-	de, _, err := fs.dirlookup(dp, elem)
-	if err != nil {
-		if openmode&O_CREATE == 0 {
-			return nil, err
-		}
-		ip = fs.newInode()
-		ip.Mode = mode
-		fs.dirlink(dp, elem, ip)
-		if ip.Mode&S_IFMT == S_IFDIR {
-			fs.dirlink(ip, ".", ip)
-			fs.dirlink(ip, "..", dp)
-		}
-	} else {
-		ip = de.inode
-		if openmode&(O_CREATE|O_EXCL) == O_CREATE|O_EXCL {
-			return nil, EEXIST
-		}
-		if openmode&O_TRUNC != 0 {
-			if ip.Mode&S_IFMT == S_IFDIR {
-				return nil, EISDIR
-			}
-			ip.data = nil
-		}
-		if ip.Mode&S_IFMT == S_IFCHR {
-			if ip.Rdev < 0 || ip.Rdev >= int64(len(fs.dev)) || fs.dev[ip.Rdev] == nil {
-				return nil, ENODEV
-			}
-			dev, err = fs.dev[ip.Rdev]()
-			if err != nil {
-				return nil, err
-			}
-		}
-	}
-
-	switch openmode & O_ACCMODE {
-	case O_WRONLY, O_RDWR:
-		if ip.Mode&S_IFMT == S_IFDIR {
-			return nil, EISDIR
-		}
-	}
-
-	switch ip.Mode & S_IFMT {
-	case S_IFDIR:
-		if openmode&O_ACCMODE != O_RDONLY {
-			return nil, EISDIR
-		}
-
-	case S_IFREG:
-		// ok
-
-	case S_IFCHR:
-		// handled above
-
-	default:
-		// TODO: some kind of special file
-		return nil, EPERM
-	}
-
-	f := &fsysFile{
-		fsys:     fs,
-		inode:    ip,
-		openmode: openmode,
-		dev:      dev,
-	}
-	if openmode&O_APPEND != 0 {
-		f.offset = ip.Size
-	}
-	return f, nil
-}
-
-// fsysFile methods to implement fileImpl.
-
-func (f *fsysFile) stat(st *Stat_t) error {
-	f.fsys.mu.Lock()
-	defer f.fsys.mu.Unlock()
-	*st = f.inode.Stat_t
-	return nil
-}
-
-func (f *fsysFile) read(b []byte) (int, error) {
-	f.fsys.mu.Lock()
-	defer f.fsys.mu.Unlock()
-	n, err := f.preadLocked(b, f.offset)
-	f.offset += int64(n)
-	return n, err
-}
-
-func ReadDirent(fd int, buf []byte) (int, error) {
-	f, err := fdToFsysFile(fd)
-	if err != nil {
-		return 0, err
-	}
-	f.fsys.mu.Lock()
-	defer f.fsys.mu.Unlock()
-	if f.inode.Mode&S_IFMT != S_IFDIR {
-		return 0, EINVAL
-	}
-	n, err := f.preadLocked(buf, f.offset)
-	f.offset += int64(n)
-	return n, err
-}
-
-func (f *fsysFile) write(b []byte) (int, error) {
-	f.fsys.mu.Lock()
-	defer f.fsys.mu.Unlock()
-	n, err := f.pwriteLocked(b, f.offset)
-	f.offset += int64(n)
-	return n, err
-}
-
-func (f *fsysFile) seek(offset int64, whence int) (int64, error) {
-	f.fsys.mu.Lock()
-	defer f.fsys.mu.Unlock()
-	switch whence {
-	case 1:
-		offset += f.offset
-	case 2:
-		offset += f.inode.Size
-	}
-	if offset < 0 {
-		return 0, EINVAL
-	}
-	if offset > f.inode.Size {
-		return 0, EINVAL
-	}
-	f.offset = offset
-	return offset, nil
-}
-
-func (f *fsysFile) pread(b []byte, offset int64) (int, error) {
-	f.fsys.mu.Lock()
-	defer f.fsys.mu.Unlock()
-	return f.preadLocked(b, offset)
-}
-
-func (f *fsysFile) pwrite(b []byte, offset int64) (int, error) {
-	f.fsys.mu.Lock()
-	defer f.fsys.mu.Unlock()
-	return f.pwriteLocked(b, offset)
-}
-
-func (f *fsysFile) preadLocked(b []byte, offset int64) (int, error) {
-	if f.openmode&O_ACCMODE == O_WRONLY {
-		return 0, EINVAL
-	}
-	if offset < 0 {
-		return 0, EINVAL
-	}
-	if f.dev != nil {
-		f.fsys.atime(f.inode)
-		f.fsys.mu.Unlock()
-		defer f.fsys.mu.Lock()
-		return f.dev.pread(b, offset)
-	}
-	if offset > f.inode.Size {
-		return 0, nil
-	}
-	if int64(len(b)) > f.inode.Size-offset {
-		b = b[:f.inode.Size-offset]
-	}
-
-	if f.inode.Mode&S_IFMT == S_IFDIR {
-		if offset%direntSize != 0 || len(b) != 0 && len(b) < direntSize {
-			return 0, EINVAL
-		}
-		fs.atime(f.inode)
-		n := 0
-		for len(b) >= direntSize {
-			src := f.inode.dir[int(offset/direntSize)]
-			dst := (*Dirent)(unsafe.Pointer(&b[0]))
-			dst.Ino = int64(src.inode.Ino)
-			dst.Off = offset
-			dst.Reclen = direntSize
-			for i := range dst.Name {
-				dst.Name[i] = 0
-			}
-			copy(dst.Name[:], src.name)
-			n += direntSize
-			offset += direntSize
-			b = b[direntSize:]
-		}
-		return n, nil
-	}
-
-	fs.atime(f.inode)
-	n := copy(b, f.inode.data[offset:])
-	return n, nil
-}
-
-func (f *fsysFile) pwriteLocked(b []byte, offset int64) (int, error) {
-	if f.openmode&O_ACCMODE == O_RDONLY {
-		return 0, EINVAL
-	}
-	if offset < 0 {
-		return 0, EINVAL
-	}
-	if f.dev != nil {
-		f.fsys.atime(f.inode)
-		f.fsys.mu.Unlock()
-		defer f.fsys.mu.Lock()
-		return f.dev.pwrite(b, offset)
-	}
-	if offset > f.inode.Size {
-		return 0, EINVAL
-	}
-	f.fsys.mtime(f.inode)
-	n := copy(f.inode.data[offset:], b)
-	if n < len(b) {
-		f.inode.data = append(f.inode.data, b[n:]...)
-		f.inode.Size = int64(len(f.inode.data))
-	}
-	return len(b), nil
-}
-
-// Standard Unix system calls.
-
-func Open(path string, openmode int, perm uint32) (fd int, err error) {
-	fs.mu.Lock()
-	defer fs.mu.Unlock()
-	f, err := fs.open(path, openmode, perm&0777|S_IFREG)
-	if err != nil {
-		return -1, err
-	}
-	return newFD(f), nil
-}
-
-func Mkdir(path string, perm uint32) error {
-	fs.mu.Lock()
-	defer fs.mu.Unlock()
-	_, err := fs.open(path, O_CREATE|O_EXCL, perm&0777|S_IFDIR)
-	return err
-}
-
-func Getcwd(buf []byte) (n int, err error) {
-	// Force package os to default to the old algorithm using .. and directory reads.
-	return 0, ENOSYS
-}
-
-func Stat(path string, st *Stat_t) error {
-	fs.mu.Lock()
-	defer fs.mu.Unlock()
-	ip, _, err := fs.namei(path, false)
-	if err != nil {
-		return err
-	}
-	*st = ip.Stat_t
-	return nil
-}
-
-func Lstat(path string, st *Stat_t) error {
-	return Stat(path, st)
-}
-
-func unlink(path string, isdir bool) error {
-	fs.mu.Lock()
-	defer fs.mu.Unlock()
-	dp, elem, err := fs.namei(path, true)
-	if err != nil {
-		return err
-	}
-	if elem == "." || elem == ".." {
-		return EINVAL
-	}
-	de, _, err := fs.dirlookup(dp, elem)
-	if err != nil {
-		return err
-	}
-	if isdir {
-		if de.inode.Mode&S_IFMT != S_IFDIR {
-			return ENOTDIR
-		}
-		if len(de.inode.dir) != 2 {
-			return ENOTEMPTY
-		}
-	} else {
-		if de.inode.Mode&S_IFMT == S_IFDIR {
-			return EISDIR
-		}
-	}
-	de.inode.Nlink--
-	*de = dp.dir[len(dp.dir)-1]
-	dp.dir = dp.dir[:len(dp.dir)-1]
-	dp.dirSize()
-	return nil
-}
-
-func Unlink(path string) error {
-	return unlink(path, false)
-}
-
-func Rmdir(path string) error {
-	return unlink(path, true)
-}
-
-func Chmod(path string, mode uint32) error {
-	fs.mu.Lock()
-	defer fs.mu.Unlock()
-	ip, _, err := fs.namei(path, false)
-	if err != nil {
-		return err
-	}
-	ip.Mode = ip.Mode&^0777 | mode&0777
-	return nil
-}
-
-func Fchmod(fd int, mode uint32) error {
-	f, err := fdToFsysFile(fd)
-	if err != nil {
-		return err
-	}
-	f.fsys.mu.Lock()
-	defer f.fsys.mu.Unlock()
-	f.inode.Mode = f.inode.Mode&^0777 | mode&0777
-	return nil
-}
-
-func Chown(path string, uid, gid int) error {
-	fs.mu.Lock()
-	defer fs.mu.Unlock()
-	ip, _, err := fs.namei(path, false)
-	if err != nil {
-		return err
-	}
-	ip.Uid = uint32(uid)
-	ip.Gid = uint32(gid)
-	return nil
-}
-
-func Fchown(fd int, uid, gid int) error {
-	fs.mu.Lock()
-	defer fs.mu.Unlock()
-	f, err := fdToFsysFile(fd)
-	if err != nil {
-		return err
-	}
-	f.fsys.mu.Lock()
-	defer f.fsys.mu.Unlock()
-	f.inode.Uid = uint32(uid)
-	f.inode.Gid = uint32(gid)
-	return nil
-}
-
-func Lchown(path string, uid, gid int) error {
-	return Chown(path, uid, gid)
-}
-
-func UtimesNano(path string, ts []Timespec) error {
-	if len(ts) != 2 {
-		return EINVAL
-	}
-	fs.mu.Lock()
-	defer fs.mu.Unlock()
-	ip, _, err := fs.namei(path, false)
-	if err != nil {
-		return err
-	}
-	ip.Atime = ts[0].Sec
-	ip.AtimeNsec = int64(ts[0].Nsec)
-	ip.Mtime = ts[1].Sec
-	ip.MtimeNsec = int64(ts[1].Nsec)
-	return nil
-}
-
-func Link(path, link string) error {
-	ip, _, err := fs.namei(path, false)
-	if err != nil {
-		return err
-	}
-	dp, elem, err := fs.namei(link, true)
-	if err != nil {
-		return err
-	}
-	if ip.Mode&S_IFMT == S_IFDIR {
-		return EPERM
-	}
-	fs.dirlink(dp, elem, ip)
-	return nil
-}
-
-func Rename(from, to string) error {
-	fdp, felem, err := fs.namei(from, true)
-	if err != nil {
-		return err
-	}
-	fde, _, err := fs.dirlookup(fdp, felem)
-	if err != nil {
-		return err
-	}
-	tdp, telem, err := fs.namei(to, true)
-	if err != nil {
-		return err
-	}
-	fs.dirlink(tdp, telem, fde.inode)
-	fde.inode.Nlink--
-	*fde = fdp.dir[len(fdp.dir)-1]
-	fdp.dir = fdp.dir[:len(fdp.dir)-1]
-	fdp.dirSize()
-	return nil
-}
-
-func (fs *fsys) truncate(ip *inode, length int64) error {
-	if length > 1e9 || ip.Mode&S_IFMT != S_IFREG {
-		return EINVAL
-	}
-	if length < int64(len(ip.data)) {
-		ip.data = ip.data[:length]
-	} else {
-		data := make([]byte, length)
-		copy(data, ip.data)
-		ip.data = data
-	}
-	ip.Size = int64(len(ip.data))
-	return nil
-}
-
-func Truncate(path string, length int64) error {
-	fs.mu.Lock()
-	defer fs.mu.Unlock()
-	ip, _, err := fs.namei(path, false)
-	if err != nil {
-		return err
-	}
-	return fs.truncate(ip, length)
-}
-
-func Ftruncate(fd int, length int64) error {
-	f, err := fdToFsysFile(fd)
-	if err != nil {
-		return err
-	}
-	f.fsys.mu.Lock()
-	defer f.fsys.mu.Unlock()
-	return f.fsys.truncate(f.inode, length)
-}
-
-func Chdir(path string) error {
-	fs.mu.Lock()
-	defer fs.mu.Unlock()
-	ip, _, err := fs.namei(path, false)
-	if err != nil {
-		return err
-	}
-	fs.cwd = ip
-	return nil
-}
-
-func Fchdir(fd int) error {
-	f, err := fdToFsysFile(fd)
-	if err != nil {
-		return err
-	}
-	f.fsys.mu.Lock()
-	defer f.fsys.mu.Unlock()
-	if f.inode.Mode&S_IFMT != S_IFDIR {
-		return ENOTDIR
-	}
-	fs.cwd = f.inode
-	return nil
-}
-
-func Readlink(path string, buf []byte) (n int, err error) {
-	return 0, ENOSYS
-}
-
-func Symlink(path, link string) error {
-	return ENOSYS
-}
-
-func Fsync(fd int) error {
-	return nil
-}
-
-// Special devices.
-
-func mkdev(path string, mode uint32, open func() (devFile, error)) error {
-	fs.mu.Lock()
-	fs.mu.Unlock()
-	f, err := fs.open(path, O_CREATE|O_RDONLY|O_EXCL, S_IFCHR|mode)
-	if err != nil {
-		return err
-	}
-	ip := f.(*fsysFile).inode
-	ip.Rdev = int64(len(fs.dev))
-	fs.dev = append(fs.dev, open)
-	return nil
-}
-
-type nullFile struct{}
-
-func openNull() (devFile, error)                               { return &nullFile{}, nil }
-func (f *nullFile) close() error                               { return nil }
-func (f *nullFile) pread(b []byte, offset int64) (int, error)  { return 0, nil }
-func (f *nullFile) pwrite(b []byte, offset int64) (int, error) { return len(b), nil }
-
-type zeroFile struct{}
-
-func openZero() (devFile, error)                               { return &zeroFile{}, nil }
-func (f *zeroFile) close() error                               { return nil }
-func (f *zeroFile) pwrite(b []byte, offset int64) (int, error) { return len(b), nil }
-
-func (f *zeroFile) pread(b []byte, offset int64) (int, error) {
-	for i := range b {
-		b[i] = 0
-	}
-	return len(b), nil
-}
-
-type randomFile struct {
-	naclFD int
-}
-
-func openRandom() (devFile, error) {
-	fd, err := openNamedService("SecureRandom", O_RDONLY)
-	if err != nil {
-		return nil, err
-	}
-	return &randomFile{naclFD: fd}, nil
-}
-
-func (f *randomFile) close() error {
-	naclClose(f.naclFD)
-	f.naclFD = -1
-	return nil
-}
-
-func (f *randomFile) pread(b []byte, offset int64) (int, error) {
-	return naclRead(f.naclFD, b)
-}
-
-func (f *randomFile) pwrite(b []byte, offset int64) (int, error) {
-	return 0, EPERM
-}
-
-func fdToFsysFile(fd int) (*fsysFile, error) {
-	f, err := fdToFile(fd)
-	if err != nil {
-		return nil, err
-	}
-	impl := f.impl
-	fsysf, ok := impl.(*fsysFile)
-	if !ok {
-		return nil, EINVAL
-	}
-	return fsysf, nil
-}
-
-// create creates a file in the file system with the given name, mode, time, and data.
-// It is meant to be called when initializing the file system image.
-func create(name string, mode uint32, sec int64, data []byte) error {
-	fs.mu.Lock()
-	fs.mu.Unlock()
-	f, err := fs.open(name, O_CREATE|O_EXCL, mode)
-	if err != nil {
-		return err
-	}
-	ip := f.(*fsysFile).inode
-	ip.Atime = sec
-	ip.Mtime = sec
-	ip.Ctime = sec
-	if len(data) > 0 {
-		ip.Size = int64(len(data))
-		ip.data = data
-	}
-	return nil
-}
diff --git a/src/pkg/syscall/mkall.sh b/src/pkg/syscall/mkall.sh
deleted file mode 100755
index 886db13..0000000
--- a/src/pkg/syscall/mkall.sh
+++ /dev/null
@@ -1,263 +0,0 @@
-#!/usr/bin/env bash
-# Copyright 2009 The Go Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style
-# license that can be found in the LICENSE file.
-
-# The syscall package provides access to the raw system call
-# interface of the underlying operating system.  Porting Go to
-# a new architecture/operating system combination requires
-# some manual effort, though there are tools that automate
-# much of the process.  The auto-generated files have names
-# beginning with z.
-#
-# This script runs or (given -n) prints suggested commands to generate z files
-# for the current system.  Running those commands is not automatic.
-# This script is documentation more than anything else.
-#
-# * asm_${GOOS}_${GOARCH}.s
-#
-# This hand-written assembly file implements system call dispatch.
-# There are three entry points:
-#
-# 	func Syscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr);
-# 	func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr);
-# 	func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr);
-#
-# The first and second are the standard ones; they differ only in
-# how many arguments can be passed to the kernel.
-# The third is for low-level use by the ForkExec wrapper;
-# unlike the first two, it does not call into the scheduler to
-# let it know that a system call is running.
-#
-# * syscall_${GOOS}.go
-#
-# This hand-written Go file implements system calls that need
-# special handling and lists "//sys" comments giving prototypes
-# for ones that can be auto-generated.  Mksyscall reads those
-# comments to generate the stubs.
-#
-# * syscall_${GOOS}_${GOARCH}.go
-#
-# Same as syscall_${GOOS}.go except that it contains code specific
-# to ${GOOS} on one particular architecture.
-#
-# * types_${GOOS}.c
-#
-# This hand-written C file includes standard C headers and then
-# creates typedef or enum names beginning with a dollar sign
-# (use of $ in variable names is a gcc extension).  The hardest
-# part about preparing this file is figuring out which headers to
-# include and which symbols need to be #defined to get the
-# actual data structures that pass through to the kernel system calls.
-# Some C libraries present alternate versions for binary compatibility
-# and translate them on the way in and out of system calls, but
-# there is almost always a #define that can get the real ones.
-# See types_darwin.c and types_linux.c for examples.
-#
-# * zerror_${GOOS}_${GOARCH}.go
-#
-# This machine-generated file defines the system's error numbers,
-# error strings, and signal numbers.  The generator is "mkerrors.sh".
-# Usually no arguments are needed, but mkerrors.sh will pass its
-# arguments on to godefs.
-#
-# * zsyscall_${GOOS}_${GOARCH}.go
-#
-# Generated by mksyscall.pl; see syscall_${GOOS}.go above.
-#
-# * zsysnum_${GOOS}_${GOARCH}.go
-#
-# Generated by mksysnum_${GOOS}.
-#
-# * ztypes_${GOOS}_${GOARCH}.go
-#
-# Generated by godefs; see types_${GOOS}.c above.
-
-GOOSARCH="${GOOS}_${GOARCH}"
-
-# defaults
-mksyscall="./mksyscall.pl"
-mkerrors="./mkerrors.sh"
-zerrors="zerrors_$GOOSARCH.go"
-mksysctl=""
-zsysctl="zsysctl_$GOOSARCH.go"
-mksysnum=
-mktypes=
-run="sh"
-
-case "$1" in
--syscalls)
-	for i in zsyscall*go
-	do
-		sed 1q $i | sed 's;^// ;;' | sh > _$i && gofmt < _$i > $i
-		rm _$i
-	done
-	exit 0
-	;;
--n)
-	run="cat"
-	shift
-esac
-
-case "$#" in
-0)
-	;;
-*)
-	echo 'usage: mkall.sh [-n]' 1>&2
-	exit 2
-esac
-
-case "$GOOSARCH" in
-_* | *_ | _)
-	echo 'undefined $GOOS_$GOARCH:' "$GOOSARCH" 1>&2
-	exit 1
-	;;
-darwin_386)
-	mkerrors="$mkerrors -m32"
-	mksyscall="./mksyscall.pl -l32"
-	mksysnum="./mksysnum_darwin.pl /usr/include/sys/syscall.h"
-	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
-	;;
-darwin_amd64)
-	mkerrors="$mkerrors -m64"
-	mksysnum="./mksysnum_darwin.pl /usr/include/sys/syscall.h"
-	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
-	;;
-dragonfly_386)
-	mkerrors="$mkerrors -m32"
-	mksyscall="./mksyscall.pl -l32 -dragonfly"
-	mksysnum="curl -s 'http://gitweb.dragonflybsd.org/dragonfly.git/blob_plain/HEAD:/sys/kern/syscalls.master' | ./mksysnum_dragonfly.pl"
-	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
-	;;
-dragonfly_amd64)
-	mkerrors="$mkerrors -m64"
-	mksyscall="./mksyscall.pl -dragonfly"
-	mksysnum="curl -s 'http://gitweb.dragonflybsd.org/dragonfly.git/blob_plain/HEAD:/sys/kern/syscalls.master' | ./mksysnum_dragonfly.pl"
-	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
-	;;
-freebsd_386)
-	mkerrors="$mkerrors -m32"
-	mksyscall="./mksyscall.pl -l32"
-	mksysnum="curl -s 'http://svn.freebsd.org/base/stable/10/sys/kern/syscalls.master' | ./mksysnum_freebsd.pl"
-	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
-	;;
-freebsd_amd64)
-	mkerrors="$mkerrors -m64"
-	mksysnum="curl -s 'http://svn.freebsd.org/base/stable/10/sys/kern/syscalls.master' | ./mksysnum_freebsd.pl"
-	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
-	;;
-freebsd_arm)
-	mkerrors="$mkerrors"
-	mksyscall="./mksyscall.pl -l32 -arm"
-	mksysnum="curl -s 'http://svn.freebsd.org/base/stable/10/sys/kern/syscalls.master' | ./mksysnum_freebsd.pl"
-	# Let the type of C char be singed for making the bare syscall
-	# API consistent across over platforms.
-	mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
-	;;
-linux_386)
-	mkerrors="$mkerrors -m32"
-	mksyscall="./mksyscall.pl -l32"
-	mksysnum="./mksysnum_linux.pl /usr/include/asm/unistd_32.h"
-	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
-	;;
-linux_amd64)
-	unistd_h=$(ls -1 /usr/include/asm/unistd_64.h /usr/include/x86_64-linux-gnu/asm/unistd_64.h 2>/dev/null | head -1)
-	if [ "$unistd_h" = "" ]; then
-		echo >&2 cannot find unistd_64.h
-		exit 1
-	fi
-	mkerrors="$mkerrors -m64"
-	mksysnum="./mksysnum_linux.pl $unistd_h"
-	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
-	;;
-linux_arm)
-	mkerrors="$mkerrors"
-	mksyscall="./mksyscall.pl -l32 -arm"
-	mksysnum="curl -s 'http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/plain/arch/arm/include/uapi/asm/unistd.h' | ./mksysnum_linux.pl"
-	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
-	;;
-nacl_386)
-	mkerrors=""
-	mksyscall="./mksyscall.pl -l32 -nacl"
-	mksysnum=""
-	mktypes=""
-	;;
-nacl_amd64p32)
-	mkerrors=""
-	mksyscall="./mksyscall.pl -nacl"
-	mksysnum=""
-	mktypes=""
-	;;
-netbsd_386)
-	mkerrors="$mkerrors -m32"
-	mksyscall="./mksyscall.pl -l32 -netbsd"
-	mksysnum="curl -s 'http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_netbsd.pl"
-	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
-	;;
-netbsd_amd64)
-	mkerrors="$mkerrors -m64"
-	mksyscall="./mksyscall.pl -netbsd"
-	mksysnum="curl -s 'http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_netbsd.pl"
-	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
-	;;
-openbsd_386)
-	mkerrors="$mkerrors -m32"
-	mksyscall="./mksyscall.pl -l32 -openbsd"
-	mksysctl="./mksysctl_openbsd.pl"
-	zsysctl="zsysctl_openbsd.go"
-	mksysnum="curl -s 'http://www.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_openbsd.pl"
-	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
-	;;
-openbsd_amd64)
-	mkerrors="$mkerrors -m64"
-	mksyscall="./mksyscall.pl -openbsd"
-	mksysctl="./mksysctl_openbsd.pl"
-	zsysctl="zsysctl_openbsd.go"
-	mksysnum="curl -s 'http://www.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_openbsd.pl"
-	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
-	;;
-plan9_386)
-	mkerrors=
-	mksyscall="./mksyscall.pl -l32 -plan9"
-	mksysnum="./mksysnum_plan9.sh /n/sources/plan9/sys/src/libc/9syscall/sys.h"
-	mktypes="XXX"
-	;;
-solaris_amd64)
-	mksyscall="./mksyscall_solaris.pl"
-	mkerrors="$mkerrors -m64"
-	mksysnum=
-	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
-	;;
-windows_*)
-	mksyscall=
-	mkerrors=
-	zerrors=
-	;;
-*)
-	echo 'unrecognized $GOOS_$GOARCH: ' "$GOOSARCH" 1>&2
-	exit 1
-	;;
-esac
-
-(
-	if [ -n "$mkerrors" ]; then echo "$mkerrors |gofmt >$zerrors"; fi
-	case "$GOOS" in
-	windows)
-		echo "GOOS= GOARCH= go build mksyscall_windows.go"
-		echo "./mksyscall_windows syscall_windows.go security_windows.go syscall_$GOOSARCH.go |gofmt >zsyscall_$GOOSARCH.go"
-		echo "rm -f ./mksyscall_windows"
-		;;
-	*)
-		syscall_goos="syscall_$GOOS.go"
-		case "$GOOS" in
-		darwin | dragonfly | freebsd | netbsd | openbsd)
-			syscall_goos="syscall_bsd.go $syscall_goos"
-			;;
-		esac
-		if [ -n "$mksyscall" ]; then echo "$mksyscall $syscall_goos syscall_$GOOSARCH.go |gofmt >zsyscall_$GOOSARCH.go"; fi
-		;;
-	esac
-	if [ -n "$mksysctl" ]; then echo "$mksysctl |gofmt >$zsysctl"; fi
-	if [ -n "$mksysnum" ]; then echo "$mksysnum |gofmt >zsysnum_$GOOSARCH.go"; fi
-	if [ -n "$mktypes" ]; then echo "$mktypes types_$GOOS.go |gofmt >ztypes_$GOOSARCH.go"; fi
-) | $run
diff --git a/src/pkg/syscall/mkall_windows.bat b/src/pkg/syscall/mkall_windows.bat
deleted file mode 100644
index a4a3f16..0000000
--- a/src/pkg/syscall/mkall_windows.bat
+++ /dev/null
@@ -1,21 +0,0 @@
-:: Copyright 2013 The Go Authors. All rights reserved.
-:: Use of this source code is governed by a BSD-style
-:: license that can be found in the LICENSE file.
- at echo off
-
-if exist mkall.sh goto dirok
-echo mkall_windows.bat must be run from src\pkg\syscall directory
-goto :end
-:dirok
-
-if "%1"=="386" goto :paramok
-if "%1"=="amd64" goto :paramok
-echo parameters must be 386 or amd64
-goto :end
-:paramok
-
-go build mksyscall_windows.go
-.\mksyscall_windows syscall_windows.go security_windows.go syscall_windows_%1.go |gofmt >zsyscall_windows_%1.go
-del mksyscall_windows.exe
-
-:end
\ No newline at end of file
diff --git a/src/pkg/syscall/mksyscall.pl b/src/pkg/syscall/mksyscall.pl
deleted file mode 100755
index 6d35fa6..0000000
--- a/src/pkg/syscall/mksyscall.pl
+++ /dev/null
@@ -1,313 +0,0 @@
-#!/usr/bin/env perl
-# Copyright 2009 The Go Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style
-# license that can be found in the LICENSE file.
-
-# This program reads a file containing function prototypes
-# (like syscall_darwin.go) and generates system call bodies.
-# The prototypes are marked by lines beginning with "//sys"
-# and read like func declarations if //sys is replaced by func, but:
-#	* The parameter lists must give a name for each argument.
-#	  This includes return parameters.
-#	* The parameter lists must give a type for each argument:
-#	  the (x, y, z int) shorthand is not allowed.
-#	* If the return parameter is an error number, it must be named errno.
-
-# A line beginning with //sysnb is like //sys, except that the
-# goroutine will not be suspended during the execution of the system
-# call.  This must only be used for system calls which can never
-# block, as otherwise the system call could cause all goroutines to
-# hang.
-
-use strict;
-
-my $cmdline = "mksyscall.pl " . join(' ', @ARGV);
-my $errors = 0;
-my $_32bit = "";
-my $plan9 = 0;
-my $openbsd = 0;
-my $netbsd = 0;
-my $dragonfly = 0;
-my $nacl = 0;
-my $arm = 0; # 64-bit value should use (even, odd)-pair
-
-if($ARGV[0] eq "-b32") {
-	$_32bit = "big-endian";
-	shift;
-} elsif($ARGV[0] eq "-l32") {
-	$_32bit = "little-endian";
-	shift;
-}
-if($ARGV[0] eq "-plan9") {
-	$plan9 = 1;
-	shift;
-}
-if($ARGV[0] eq "-openbsd") {
-	$openbsd = 1;
-	shift;
-}
-if($ARGV[0] eq "-netbsd") {
-	$netbsd = 1;
-	shift;
-}
-if($ARGV[0] eq "-dragonfly") {
-	$dragonfly = 1;
-	shift;
-}
-if($ARGV[0] eq "-nacl") {
-	$nacl = 1;
-	shift;
-}
-if($ARGV[0] eq "-arm") {
-	$arm = 1;
-	shift;
-}
-
-if($ARGV[0] =~ /^-/) {
-	print STDERR "usage: mksyscall.pl [-b32 | -l32] [file ...]\n";
-	exit 1;
-}
-
-sub parseparamlist($) {
-	my ($list) = @_;
-	$list =~ s/^\s*//;
-	$list =~ s/\s*$//;
-	if($list eq "") {
-		return ();
-	}
-	return split(/\s*,\s*/, $list);
-}
-
-sub parseparam($) {
-	my ($p) = @_;
-	if($p !~ /^(\S*) (\S*)$/) {
-		print STDERR "$ARGV:$.: malformed parameter: $p\n";
-		$errors = 1;
-		return ("xx", "int");
-	}
-	return ($1, $2);
-}
-
-my $text = "";
-while(<>) {
-	chomp;
-	s/\s+/ /g;
-	s/^\s+//;
-	s/\s+$//;
-	my $nonblock = /^\/\/sysnb /;
-	next if !/^\/\/sys / && !$nonblock;
-
-	# 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_]+))?$/) {
-		print STDERR "$ARGV:$.: malformed //sys declaration\n";
-		$errors = 1;
-		next;
-	}
-	my ($func, $in, $out, $sysname) = ($2, $3, $4, $5);
-
-	# Split argument lists on comma.
-	my @in = parseparamlist($in);
-	my @out = parseparamlist($out);
-
-	# Try in vain to keep people from editing this file.
-	# The theory is that they jump into the middle of the file
-	# without reading the header.
-	$text .= "// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\n";
-
-	# Go function header.
-	my $out_decl = @out ? sprintf(" (%s)", join(', ', @out)) : "";
-	$text .= sprintf "func %s(%s)%s {\n", $func, join(', ', @in), $out_decl;
-
-	# Check if err return available
-	my $errvar = "";
-	foreach my $p (@out) {
-		my ($name, $type) = parseparam($p);
-		if($type eq "error") {
-			$errvar = $name;
-			last;
-		}
-	}
-
-	# Prepare arguments to Syscall.
-	my @args = ();
-	my $n = 0;
-	foreach my $p (@in) {
-		my ($name, $type) = parseparam($p);
-		if($type =~ /^\*/) {
-			push @args, "uintptr(unsafe.Pointer($name))";
-		} elsif($type eq "string" && $errvar ne "") {
-			$text .= "\tvar _p$n *byte\n";
-			$text .= "\t_p$n, $errvar = BytePtrFromString($name)\n";
-			$text .= "\tif $errvar != nil {\n\t\treturn\n\t}\n";
-			push @args, "uintptr(unsafe.Pointer(_p$n))";
-			$n++;
-		} elsif($type eq "string") {
-			print STDERR "$ARGV:$.: $func uses string arguments, but has no error return\n";
-			$text .= "\tvar _p$n *byte\n";
-			$text .= "\t_p$n, _ = BytePtrFromString($name)\n";
-			push @args, "uintptr(unsafe.Pointer(_p$n))";
-			$n++;
-		} elsif($type =~ /^\[\](.*)/) {
-			# Convert slice into pointer, length.
-			# Have to be careful not to take address of &a[0] if len == 0:
-			# pass dummy pointer in that case.
-			# Used to pass nil, but some OSes or simulators reject write(fd, nil, 0).
-			$text .= "\tvar _p$n unsafe.Pointer\n";
-			$text .= "\tif len($name) > 0 {\n\t\t_p$n = unsafe.Pointer(\&${name}[0])\n\t}";
-			$text .= " else {\n\t\t_p$n = unsafe.Pointer(&_zero)\n\t}";
-			$text .= "\n";
-			push @args, "uintptr(_p$n)", "uintptr(len($name))";
-			$n++;
-		} elsif($type eq "int64" && ($openbsd || $netbsd)) {
-			push @args, "0";
-			if($_32bit eq "big-endian") {
-				push @args, "uintptr($name>>32)", "uintptr($name)";
-			} elsif($_32bit eq "little-endian") {
-				push @args, "uintptr($name)", "uintptr($name>>32)";
-			} else {
-				push @args, "uintptr($name)";
-			}
-		} elsif($type eq "int64" && $dragonfly) {
-			if ($func !~ /^extp(read|write)/i) {
-				push @args, "0";
-			}
-			if($_32bit eq "big-endian") {
-				push @args, "uintptr($name>>32)", "uintptr($name)";
-			} elsif($_32bit eq "little-endian") {
-				push @args, "uintptr($name)", "uintptr($name>>32)";
-			} else {
-				push @args, "uintptr($name)";
-			}
-		} elsif($type eq "int64" && $_32bit ne "") {
-			if(@args % 2 && $arm) {
-				# arm abi specifies 64-bit argument uses 
-				# (even, odd) pair
-				push @args, "0"
-			}
-			if($_32bit eq "big-endian") {
-				push @args, "uintptr($name>>32)", "uintptr($name)";
-			} else {
-				push @args, "uintptr($name)", "uintptr($name>>32)";
-			}
-		} else {
-			push @args, "uintptr($name)";
-		}
-	}
-
-	# Determine which form to use; pad args with zeros.
-	my $asm = "Syscall";
-	if ($nonblock) {
-		$asm = "RawSyscall";
-	}
-	if(@args <= 3) {
-		while(@args < 3) {
-			push @args, "0";
-		}
-	} elsif(@args <= 6) {
-		$asm .= "6";
-		while(@args < 6) {
-			push @args, "0";
-		}
-	} elsif(@args <= 9) {
-		$asm .= "9";
-		while(@args < 9) {
-			push @args, "0";
-		}
-	} else {
-		print STDERR "$ARGV:$.: too many arguments to system call\n";
-	}
-
-	# System call number.
-	if($sysname eq "") {
-		$sysname = "SYS_$func";
-		$sysname =~ s/([a-z])([A-Z])/${1}_$2/g;	# turn FooBar into Foo_Bar
-		$sysname =~ y/a-z/A-Z/;
-		if($nacl) {
-			$sysname =~ y/A-Z/a-z/;
-		}
-	}
-
-	# Actual call.
-	my $args = join(', ', @args);
-	my $call = "$asm($sysname, $args)";
-
-	# Assign return values.
-	my $body = "";
-	my @ret = ("_", "_", "_");
-	my $do_errno = 0;
-	for(my $i=0; $i<@out; $i++) {
-		my $p = $out[$i];
-		my ($name, $type) = parseparam($p);
-		my $reg = "";
-		if($name eq "err" && !$plan9) {
-			$reg = "e1";
-			$ret[2] = $reg;
-			$do_errno = 1;
-		} elsif($name eq "err" && $plan9) {
-			$ret[0] = "r0";
-			$ret[2] = "e1";
-			next;
-		} else {
-			$reg = sprintf("r%d", $i);
-			$ret[$i] = $reg;
-		}
-		if($type eq "bool") {
-			$reg = "$reg != 0";
-		}
-		if($type eq "int64" && $_32bit ne "") {
-			# 64-bit number in r1:r0 or r0:r1.
-			if($i+2 > @out) {
-				print STDERR "$ARGV:$.: not enough registers for int64 return\n";
-			}
-			if($_32bit eq "big-endian") {
-				$reg = sprintf("int64(r%d)<<32 | int64(r%d)", $i, $i+1);
-			} else {
-				$reg = sprintf("int64(r%d)<<32 | int64(r%d)", $i+1, $i);
-			}
-			$ret[$i] = sprintf("r%d", $i);
-			$ret[$i+1] = sprintf("r%d", $i+1);
-		}
-		if($reg ne "e1" || $plan9) {
-			$body .= "\t$name = $type($reg)\n";
-		}
-	}
-	if ($ret[0] eq "_" && $ret[1] eq "_" && $ret[2] eq "_") {
-		$text .= "\t$call\n";
-	} else {
-		$text .= "\t$ret[0], $ret[1], $ret[2] := $call\n";
-	}
-	$text .= $body;
-	
-	if ($plan9 && $ret[2] eq "e1") {
-		$text .= "\tif int32(r0) == -1 {\n";
-		$text .= "\t\terr = e1\n";
-		$text .= "\t}\n";
-	} elsif ($do_errno) {
-		$text .= "\tif e1 != 0 {\n";
-		$text .= "\t\terr = e1\n";
-		$text .= "\t}\n";
-	}
-	$text .= "\treturn\n";
-	$text .= "}\n\n";
-}
-
-chomp $text;
-chomp $text;
-
-if($errors) {
-	exit 1;
-}
-
-print <<EOF;
-// $cmdline
-// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
-
-package syscall
-
-import "unsafe"
-
-$text
-EOF
-exit 0;
diff --git a/src/pkg/syscall/mksyscall_solaris.pl b/src/pkg/syscall/mksyscall_solaris.pl
deleted file mode 100755
index 130d043..0000000
--- a/src/pkg/syscall/mksyscall_solaris.pl
+++ /dev/null
@@ -1,279 +0,0 @@
-#!/usr/bin/env perl
-# Copyright 2009 The Go Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style
-# license that can be found in the LICENSE file.
-
-# This program reads a file containing function prototypes
-# (like syscall_solaris.go) and generates system call bodies.
-# The prototypes are marked by lines beginning with "//sys"
-# and read like func declarations if //sys is replaced by func, but:
-#	* The parameter lists must give a name for each argument.
-#	  This includes return parameters.
-#	* The parameter lists must give a type for each argument:
-#	  the (x, y, z int) shorthand is not allowed.
-#	* If the return parameter is an error number, it must be named err.
-#	* If go func name needs to be different than its libc name, 
-#	* or the function is not in libc, name could be specified
-#	* at the end, after "=" sign, like
-#	  //sys getsockopt(s int, level int, name int, val uintptr, vallen *_Socklen) (err error) = libsocket.getsockopt
-
-use strict;
-
-my $cmdline = "mksyscall_solaris.pl " . join(' ', @ARGV);
-my $errors = 0;
-my $_32bit = "";
-
-binmode STDOUT;
-
-if($ARGV[0] eq "-b32") {
-	$_32bit = "big-endian";
-	shift;
-} elsif($ARGV[0] eq "-l32") {
-	$_32bit = "little-endian";
-	shift;
-}
-
-if($ARGV[0] =~ /^-/) {
-	print STDERR "usage: mksyscall_solaris.pl [-b32 | -l32] [file ...]\n";
-	exit 1;
-}
-
-sub parseparamlist($) {
-	my ($list) = @_;
-	$list =~ s/^\s*//;
-	$list =~ s/\s*$//;
-	if($list eq "") {
-		return ();
-	}
-	return split(/\s*,\s*/, $list);
-}
-
-sub parseparam($) {
-	my ($p) = @_;
-	if($p !~ /^(\S*) (\S*)$/) {
-		print STDERR "$ARGV:$.: malformed parameter: $p\n";
-		$errors = 1;
-		return ("xx", "int");
-	}
-	return ($1, $2);
-}
-
-my $package = "";
-my $text = "";
-my $vars = "";
-my $mods = "";
-my $modnames = "";
-while(<>) {
-	chomp;
-	s/\s+/ /g;
-	s/^\s+//;
-	s/\s+$//;
-	$package = $1 if !$package && /^package (\S+)$/;
-	my $nonblock = /^\/\/sysnb /;
-	next if !/^\/\/sys / && !$nonblock;
-
-	my $syscalldot = "";
-	$syscalldot = "syscall." if $package ne "syscall";
-
-	# Line must be of the form
-	#	func Open(path string, mode int, perm int) (fd int, err error)
-	# Split into name, in params, out params.
-	if(!/^\/\/sys(nb)? (\w+)\(([^()]*)\)\s*(?:\(([^()]+)\))?\s*(?:=\s*(?:(\w*)\.)?(\w*))?$/) {
-		print STDERR "$ARGV:$.: malformed //sys declaration\n";
-		$errors = 1;
-		next;
-	}
-	my ($nb, $func, $in, $out, $modname, $sysname) = ($1, $2, $3, $4, $5, $6);
-
-	# Split argument lists on comma.
-	my @in = parseparamlist($in);
-	my @out = parseparamlist($out);
-
-	# So file name.
-	if($modname eq "") {
-		$modname = "libc";
-	}
-	my $modvname = "mod$modname";
-	if($modnames !~ /$modname/) {
-		$modnames .= ".$modname";
-		$mods .= "\t$modvname = ${syscalldot}newLazySO(\"$modname.so\")\n";
-	}
-
-	# System call name.
-	if($sysname eq "") {
-		$sysname = "$func";
-	}
-
-	# System call pointer variable name.
-	my $sysvarname = "proc$sysname";
-
-	my $strconvfunc = "BytePtrFromString";
-	my $strconvtype = "*byte";
-
-	# Library proc address variable.
-	$sysname =~ y/A-Z/a-z/; # All libc functions are lowercase.
-	$vars .= "\t$sysvarname = $modvname.NewProc(\"$sysname\")\n";
-
-	# Go function header.
-	$out = join(', ', @out);
-	if($out ne "") {
-		$out = " ($out)";
-	}
-	if($text ne "") {
-		$text .= "\n"
-	}
-	$text .= sprintf "func %s(%s)%s {\n", $func, join(', ', @in), $out;
-
-	# Check if err return available
-	my $errvar = "";
-	foreach my $p (@out) {
-		my ($name, $type) = parseparam($p);
-		if($type eq "error") {
-			$errvar = $name;
-			last;
-		}
-	}
-
-	# Prepare arguments to Syscall.
-	my @args = ();
-	my $n = 0;
-	my @pin= ();
-	foreach my $p (@in) {
-		my ($name, $type) = parseparam($p);
-		if($type =~ /^\*/) {
-			push @args, "uintptr(unsafe.Pointer($name))";
-		} elsif($type eq "string" && $errvar ne "") {
-			$text .= "\tvar _p$n $strconvtype\n";
-			$text .= "\t_p$n, $errvar = $strconvfunc($name)\n";
-			$text .= "\tif $errvar != nil {\n\t\treturn\n\t}\n";
-			push @args, "uintptr(unsafe.Pointer(_p$n))";
-			$n++;
-		} elsif($type eq "string") {
-			print STDERR "$ARGV:$.: $func uses string arguments, but has no error return\n";
-			$text .= "\tvar _p$n $strconvtype\n";
-			$text .= "\t_p$n, _ = $strconvfunc($name)\n";
-			push @args, "uintptr(unsafe.Pointer(_p$n))";
-			$n++;
-		} elsif($type =~ /^\[\](.*)/) {
-			# Convert slice into pointer, length.
-			# Have to be careful not to take address of &a[0] if len == 0:
-			# pass nil in that case.
-			$text .= "\tvar _p$n *$1\n";
-			$text .= "\tif len($name) > 0 {\n\t\t_p$n = \&$name\[0]\n\t}\n";
-			push @args, "uintptr(unsafe.Pointer(_p$n))", "uintptr(len($name))";
-			$n++;
-		} elsif($type eq "int64" && $_32bit ne "") {
-			if($_32bit eq "big-endian") {
-				push @args, "uintptr($name >> 32)", "uintptr($name)";
-			} else {
-				push @args, "uintptr($name)", "uintptr($name >> 32)";
-			}
-		} elsif($type eq "bool") {
- 			$text .= "\tvar _p$n uint32\n";
-			$text .= "\tif $name {\n\t\t_p$n = 1\n\t} else {\n\t\t_p$n = 0\n\t}\n";
-			push @args, "uintptr(_p$n)";
-			$n++;
-		} else {
-			push @args, "uintptr($name)";
-		}
-		push @pin, sprintf "\"%s=\", %s, ", $name, $name;
-	}
-	my $nargs = @args;
-
-	# Determine which form to use; pad args with zeros.
-	my $asm = "${syscalldot}sysvicall6";
-	if ($nonblock) {
-		$asm = "${syscalldot}rawSysvicall6";
-	}
-	if(@args <= 6) {
-		while(@args < 6) {
-			push @args, "0";
-		}
-	} else {
-		print STDERR "$ARGV:$.: too many arguments to system call\n";
-	}
-
-	# Actual call.
-	my $args = join(', ', @args);
-	my $call = "$asm($sysvarname.Addr(), $nargs, $args)";
-
-	# Assign return values.
-	my $body = "";
-	my $failexpr = "";
-	my @ret = ("_", "_", "_");
-	my @pout= ();
-	my $do_errno = 0;
-	for(my $i=0; $i<@out; $i++) {
-		my $p = $out[$i];
-		my ($name, $type) = parseparam($p);
-		my $reg = "";
-		if($name eq "err") {
-			$reg = "e1";
-			$ret[2] = $reg;
-			$do_errno = 1;
-		} else {
-			$reg = sprintf("r%d", $i);
-			$ret[$i] = $reg;
-		}
-		if($type eq "bool") {
-			$reg = "$reg != 0";
-		}
-		if($type eq "int64" && $_32bit ne "") {
-			# 64-bit number in r1:r0 or r0:r1.
-			if($i+2 > @out) {
-				print STDERR "$ARGV:$.: not enough registers for int64 return\n";
-			}
-			if($_32bit eq "big-endian") {
-				$reg = sprintf("int64(r%d)<<32 | int64(r%d)", $i, $i+1);
-			} else {
-				$reg = sprintf("int64(r%d)<<32 | int64(r%d)", $i+1, $i);
-			}
-			$ret[$i] = sprintf("r%d", $i);
-			$ret[$i+1] = sprintf("r%d", $i+1);
-		}
-		if($reg ne "e1") {
-			$body .= "\t$name = $type($reg)\n";
-		}
-	}
-	if ($ret[0] eq "_" && $ret[1] eq "_" && $ret[2] eq "_") {
-		$text .= "\t$call\n";
-	} else {
-		$text .= "\t$ret[0], $ret[1], $ret[2] := $call\n";
-	}
-	$text .= $body;
-
-	if ($do_errno) {
-		$text .= "\tif e1 != 0 {\n";
-		$text .= "\t\terr = e1\n";
-		$text .= "\t}\n";
-	}
-	$text .= "\treturn\n";
-	$text .= "}\n";
-}
-
-if($errors) {
-	exit 1;
-}
-
-print <<EOF;
-// $cmdline
-// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
-
-package $package
-
-import "unsafe"
-EOF
-
-print "import \"syscall\"\n" if $package ne "syscall";
-
-print <<EOF;
-
-var (
-$mods
-$vars
-)
-
-$text
-
-EOF
-exit 0;
diff --git a/src/pkg/syscall/mksyscall_windows.go b/src/pkg/syscall/mksyscall_windows.go
deleted file mode 100644
index 4225588..0000000
--- a/src/pkg/syscall/mksyscall_windows.go
+++ /dev/null
@@ -1,662 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build ignore
-
-/*
-mksyscall_windows generates windows system call bodies
-
-It parses all files specified on command line containing function
-prototypes (like syscall_windows.go) and prints system call bodies
-to standard output.
-
-The prototypes are marked by lines beginning with "//sys" and read
-like func declarations if //sys is replaced by func, but:
-
-* The parameter lists must give a name for each argument. This
-  includes return parameters.
-
-* The parameter lists must give a type for each argument:
-  the (x, y, z int) shorthand is not allowed.
-
-* If the return parameter is an error number, it must be named err.
-
-* If go func name needs to be different from it's winapi dll name,
-  the winapi name could be specified at the end, after "=" sign, like
-  //sys LoadLibrary(libname string) (handle uint32, err error) = LoadLibraryA
-
-* Each function that returns err needs to supply a condition, that
-  return value of winapi will be tested against to detect failure.
-  This would set err to windows "last-error", otherwise it will be nil.
-  The value can be provided at end of //sys declaration, like
-  //sys LoadLibrary(libname string) (handle uint32, err error) [failretval==-1] = LoadLibraryA
-  and is [failretval==0] by default.
-
-Usage:
-	mksyscall_windows [flags] [path ...]
-
-The flags are:
-	-trace
-		Generate print statement after every syscall.
-*/
-package main
-
-import (
-	"bufio"
-	"errors"
-	"flag"
-	"fmt"
-	"io"
-	"log"
-	"os"
-	"strconv"
-	"strings"
-	"text/template"
-)
-
-var PrintTraceFlag = flag.Bool("trace", false, "generate print statement after every syscall")
-
-func trim(s string) string {
-	return strings.Trim(s, " \t")
-}
-
-// Param is function parameter
-type Param struct {
-	Name      string
-	Type      string
-	fn        *Fn
-	tmpVarIdx int
-}
-
-// tmpVar returns temp variable name that will be used to represent p during syscall.
-func (p *Param) tmpVar() string {
-	if p.tmpVarIdx < 0 {
-		p.tmpVarIdx = p.fn.curTmpVarIdx
-		p.fn.curTmpVarIdx++
-	}
-	return fmt.Sprintf("_p%d", p.tmpVarIdx)
-}
-
-// BoolTmpVarCode returns source code for bool temp variable.
-func (p *Param) BoolTmpVarCode() string {
-	const code = `var %s uint32
-	if %s {
-		%s = 1
-	} else {
-		%s = 0
-	}`
-	tmp := p.tmpVar()
-	return fmt.Sprintf(code, tmp, p.Name, tmp, tmp)
-}
-
-// SliceTmpVarCode returns source code for slice temp variable.
-func (p *Param) SliceTmpVarCode() string {
-	const code = `var %s *%s
-	if len(%s) > 0 {
-		%s = &%s[0]
-	}`
-	tmp := p.tmpVar()
-	return fmt.Sprintf(code, tmp, p.Type[2:], p.Name, tmp, p.Name)
-}
-
-// StringTmpVarCode returns source code for string temp variable.
-func (p *Param) StringTmpVarCode() string {
-	errvar := p.fn.Rets.ErrorVarName()
-	if errvar == "" {
-		errvar = "_"
-	}
-	tmp := p.tmpVar()
-	const code = `var %s %s
-	%s, %s = %s(%s)`
-	s := fmt.Sprintf(code, tmp, p.fn.StrconvType(), tmp, errvar, p.fn.StrconvFunc(), p.Name)
-	if errvar == "-" {
-		return s
-	}
-	const morecode = `
-	if %s != nil {
-		return
-	}`
-	return s + fmt.Sprintf(morecode, errvar)
-}
-
-// TmpVarCode returns source code for temp variable.
-func (p *Param) TmpVarCode() string {
-	switch {
-	case p.Type == "string":
-		return p.StringTmpVarCode()
-	case p.Type == "bool":
-		return p.BoolTmpVarCode()
-	case strings.HasPrefix(p.Type, "[]"):
-		return p.SliceTmpVarCode()
-	default:
-		return ""
-	}
-}
-
-// SyscallArgList returns source code fragments representing p parameter
-// in syscall. Slices are translated into 2 syscall parameters: pointer to
-// the first element and length.
-func (p *Param) SyscallArgList() []string {
-	var s string
-	switch {
-	case p.Type[0] == '*':
-		s = fmt.Sprintf("unsafe.Pointer(%s)", p.Name)
-	case p.Type == "string":
-		s = fmt.Sprintf("unsafe.Pointer(%s)", p.tmpVar())
-	case p.Type == "bool":
-		s = p.tmpVar()
-	case strings.HasPrefix(p.Type, "[]"):
-		return []string{
-			fmt.Sprintf("uintptr(unsafe.Pointer(%s))", p.tmpVar()),
-			fmt.Sprintf("uintptr(len(%s))", p.Name),
-		}
-	default:
-		s = p.Name
-	}
-	return []string{fmt.Sprintf("uintptr(%s)", s)}
-}
-
-// IsError determines if p parameter is used to return error.
-func (p *Param) IsError() bool {
-	return p.Name == "err" && p.Type == "error"
-}
-
-// join concatenates parameters ps into a string with sep separator.
-// Each parameter is converted into string by applying fn to it
-// before conversion.
-func join(ps []*Param, fn func(*Param) string, sep string) string {
-	if len(ps) == 0 {
-		return ""
-	}
-	a := make([]string, 0)
-	for _, p := range ps {
-		a = append(a, fn(p))
-	}
-	return strings.Join(a, sep)
-}
-
-// Rets describes function return parameters.
-type Rets struct {
-	Name         string
-	Type         string
-	ReturnsError bool
-	FailCond     string
-}
-
-// ErrorVarName returns error variable name for r.
-func (r *Rets) ErrorVarName() string {
-	if r.ReturnsError {
-		return "err"
-	}
-	if r.Type == "error" {
-		return r.Name
-	}
-	return ""
-}
-
-// ToParams converts r into slice of *Param.
-func (r *Rets) ToParams() []*Param {
-	ps := make([]*Param, 0)
-	if len(r.Name) > 0 {
-		ps = append(ps, &Param{Name: r.Name, Type: r.Type})
-	}
-	if r.ReturnsError {
-		ps = append(ps, &Param{Name: "err", Type: "error"})
-	}
-	return ps
-}
-
-// List returns source code of syscall return parameters.
-func (r *Rets) List() string {
-	s := join(r.ToParams(), func(p *Param) string { return p.Name + " " + p.Type }, ", ")
-	if len(s) > 0 {
-		s = "(" + s + ")"
-	}
-	return s
-}
-
-// PrintList returns source code of trace printing part correspondent
-// to syscall return values.
-func (r *Rets) PrintList() string {
-	return join(r.ToParams(), func(p *Param) string { return fmt.Sprintf(`"%s=", %s, `, p.Name, p.Name) }, `", ", `)
-}
-
-// SetReturnValuesCode returns source code that accepts syscall return values.
-func (r *Rets) SetReturnValuesCode() string {
-	if r.Name == "" && !r.ReturnsError {
-		return ""
-	}
-	retvar := "r0"
-	if r.Name == "" {
-		retvar = "r1"
-	}
-	errvar := "_"
-	if r.ReturnsError {
-		errvar = "e1"
-	}
-	return fmt.Sprintf("%s, _, %s := ", retvar, errvar)
-}
-
-func (r *Rets) useLongHandleErrorCode(retvar string) string {
-	const code = `if %s {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}`
-	cond := retvar + " == 0"
-	if r.FailCond != "" {
-		cond = strings.Replace(r.FailCond, "failretval", retvar, 1)
-	}
-	return fmt.Sprintf(code, cond)
-}
-
-// SetErrorCode returns source code that sets return parameters.
-func (r *Rets) SetErrorCode() string {
-	const code = `if r0 != 0 {
-		%s = Errno(r0)
-	}`
-	if r.Name == "" && !r.ReturnsError {
-		return ""
-	}
-	if r.Name == "" {
-		return r.useLongHandleErrorCode("r1")
-	}
-	if r.Type == "error" {
-		return fmt.Sprintf(code, r.Name)
-	}
-	s := ""
-	if r.Type[0] == '*' {
-		s = fmt.Sprintf("%s = (%s)(unsafe.Pointer(r0))", r.Name, r.Type)
-	} else {
-		s = fmt.Sprintf("%s = %s(r0)", r.Name, r.Type)
-	}
-	if !r.ReturnsError {
-		return s
-	}
-	return s + "\n\t" + r.useLongHandleErrorCode(r.Name)
-}
-
-// Fn describes syscall function.
-type Fn struct {
-	Name        string
-	Params      []*Param
-	Rets        *Rets
-	PrintTrace  bool
-	dllname     string
-	dllfuncname string
-	src         string
-	// TODO: get rid of this field and just use parameter index instead
-	curTmpVarIdx int // insure tmp variables have uniq names
-}
-
-// extractParams parses s to extract function parameters.
-func extractParams(s string, f *Fn) ([]*Param, error) {
-	s = trim(s)
-	if s == "" {
-		return nil, nil
-	}
-	a := strings.Split(s, ",")
-	ps := make([]*Param, len(a))
-	for i := range ps {
-		s2 := trim(a[i])
-		b := strings.Split(s2, " ")
-		if len(b) != 2 {
-			b = strings.Split(s2, "\t")
-			if len(b) != 2 {
-				return nil, errors.New("Could not extract function parameter from \"" + s2 + "\"")
-			}
-		}
-		ps[i] = &Param{
-			Name:      trim(b[0]),
-			Type:      trim(b[1]),
-			fn:        f,
-			tmpVarIdx: -1,
-		}
-	}
-	return ps, nil
-}
-
-// extractSection extracts text out of string s starting after start
-// and ending just before end. found return value will indicate success,
-// and prefix, body and suffix will contain correspondent parts of string s.
-func extractSection(s string, start, end rune) (prefix, body, suffix string, found bool) {
-	s = trim(s)
-	if strings.HasPrefix(s, string(start)) {
-		// no prefix
-		body = s[1:]
-	} else {
-		a := strings.SplitN(s, string(start), 2)
-		if len(a) != 2 {
-			return "", "", s, false
-		}
-		prefix = a[0]
-		body = a[1]
-	}
-	a := strings.SplitN(body, string(end), 2)
-	if len(a) != 2 {
-		return "", "", "", false
-	}
-	return prefix, a[0], a[1], true
-}
-
-// newFn parses string s and return created function Fn.
-func newFn(s string) (*Fn, error) {
-	s = trim(s)
-	f := &Fn{
-		Rets:       &Rets{},
-		src:        s,
-		PrintTrace: *PrintTraceFlag,
-	}
-	// function name and args
-	prefix, body, s, found := extractSection(s, '(', ')')
-	if !found || prefix == "" {
-		return nil, errors.New("Could not extract function name and parameters from \"" + f.src + "\"")
-	}
-	f.Name = prefix
-	var err error
-	f.Params, err = extractParams(body, f)
-	if err != nil {
-		return nil, err
-	}
-	// return values
-	_, body, s, found = extractSection(s, '(', ')')
-	if found {
-		r, err := extractParams(body, f)
-		if err != nil {
-			return nil, err
-		}
-		switch len(r) {
-		case 0:
-		case 1:
-			if r[0].IsError() {
-				f.Rets.ReturnsError = true
-			} else {
-				f.Rets.Name = r[0].Name
-				f.Rets.Type = r[0].Type
-			}
-		case 2:
-			if !r[1].IsError() {
-				return nil, errors.New("Only last windows error is allowed as second return value in \"" + f.src + "\"")
-			}
-			f.Rets.ReturnsError = true
-			f.Rets.Name = r[0].Name
-			f.Rets.Type = r[0].Type
-		default:
-			return nil, errors.New("Too many return values in \"" + f.src + "\"")
-		}
-	}
-	// fail condition
-	_, body, s, found = extractSection(s, '[', ']')
-	if found {
-		f.Rets.FailCond = body
-	}
-	// dll and dll function names
-	s = trim(s)
-	if s == "" {
-		return f, nil
-	}
-	if !strings.HasPrefix(s, "=") {
-		return nil, errors.New("Could not extract dll name from \"" + f.src + "\"")
-	}
-	s = trim(s[1:])
-	a := strings.Split(s, ".")
-	switch len(a) {
-	case 1:
-		f.dllfuncname = a[0]
-	case 2:
-		f.dllname = a[0]
-		f.dllfuncname = a[1]
-	default:
-		return nil, errors.New("Could not extract dll name from \"" + f.src + "\"")
-	}
-	return f, nil
-}
-
-// DLLName returns DLL name for function f.
-func (f *Fn) DLLName() string {
-	if f.dllname == "" {
-		return "kernel32"
-	}
-	return f.dllname
-}
-
-// DLLName returns DLL function name for function f.
-func (f *Fn) DLLFuncName() string {
-	if f.dllfuncname == "" {
-		return f.Name
-	}
-	return f.dllfuncname
-}
-
-// ParamList returns source code for function f parameters.
-func (f *Fn) ParamList() string {
-	return join(f.Params, func(p *Param) string { return p.Name + " " + p.Type }, ", ")
-}
-
-// ParamPrintList returns source code of trace printing part correspondent
-// to syscall input parameters.
-func (f *Fn) ParamPrintList() string {
-	return join(f.Params, func(p *Param) string { return fmt.Sprintf(`"%s=", %s, `, p.Name, p.Name) }, `", ", `)
-}
-
-// ParamCount return number of syscall parameters for function f.
-func (f *Fn) ParamCount() int {
-	n := 0
-	for _, p := range f.Params {
-		n += len(p.SyscallArgList())
-	}
-	return n
-}
-
-// SyscallParamCount determines which version of Syscall/Syscall6/Syscall9/...
-// to use. It returns parameter count for correspondent SyscallX function.
-func (f *Fn) SyscallParamCount() int {
-	n := f.ParamCount()
-	switch {
-	case n <= 3:
-		return 3
-	case n <= 6:
-		return 6
-	case n <= 9:
-		return 9
-	case n <= 12:
-		return 12
-	case n <= 15:
-		return 15
-	default:
-		panic("too many arguments to system call")
-	}
-}
-
-// Syscall determines which SyscallX function to use for function f.
-func (f *Fn) Syscall() string {
-	c := f.SyscallParamCount()
-	if c == 3 {
-		return "Syscall"
-	}
-	return "Syscall" + strconv.Itoa(c)
-}
-
-// SyscallParamList returns source code for SyscallX parameters for function f.
-func (f *Fn) SyscallParamList() string {
-	a := make([]string, 0)
-	for _, p := range f.Params {
-		a = append(a, p.SyscallArgList()...)
-	}
-	for len(a) < f.SyscallParamCount() {
-		a = append(a, "0")
-	}
-	return strings.Join(a, ", ")
-}
-
-// IsUTF16 is true, if f is W (utf16) function. It is false
-// for all A (ascii) functions.
-func (f *Fn) IsUTF16() bool {
-	s := f.DLLFuncName()
-	return s[len(s)-1] == 'W'
-}
-
-// StrconvFunc returns name of Go string to OS string function for f.
-func (f *Fn) StrconvFunc() string {
-	if f.IsUTF16() {
-		return "UTF16PtrFromString"
-	}
-	return "BytePtrFromString"
-}
-
-// StrconvType returns Go type name used for OS string for f.
-func (f *Fn) StrconvType() string {
-	if f.IsUTF16() {
-		return "*uint16"
-	}
-	return "*byte"
-}
-
-// Source files and functions.
-type Source struct {
-	Funcs []*Fn
-	Files []string
-}
-
-// ParseFiles parses files listed in fs and extracts all syscall
-// functions listed in  sys comments. It returns source files
-// and functions collection *Source if successful.
-func ParseFiles(fs []string) (*Source, error) {
-	src := &Source{
-		Funcs: make([]*Fn, 0),
-		Files: make([]string, 0),
-	}
-	for _, file := range fs {
-		if err := src.ParseFile(file); err != nil {
-			return nil, err
-		}
-	}
-	return src, nil
-}
-
-// DLLs return dll names for a source set src.
-func (src *Source) DLLs() []string {
-	uniq := make(map[string]bool)
-	r := make([]string, 0)
-	for _, f := range src.Funcs {
-		name := f.DLLName()
-		if _, found := uniq[name]; !found {
-			uniq[name] = true
-			r = append(r, name)
-		}
-	}
-	return r
-}
-
-// ParseFile adds adition file path to a source set src.
-func (src *Source) ParseFile(path string) error {
-	file, err := os.Open(path)
-	if err != nil {
-		return err
-	}
-	defer file.Close()
-
-	s := bufio.NewScanner(file)
-	for s.Scan() {
-		t := trim(s.Text())
-		if len(t) < 7 {
-			continue
-		}
-		if !strings.HasPrefix(t, "//sys") {
-			continue
-		}
-		t = t[5:]
-		if !(t[0] == ' ' || t[0] == '\t') {
-			continue
-		}
-		f, err := newFn(t[1:])
-		if err != nil {
-			return err
-		}
-		src.Funcs = append(src.Funcs, f)
-	}
-	if err := s.Err(); err != nil {
-		return err
-	}
-	src.Files = append(src.Files, path)
-	return nil
-}
-
-// Generate output source file from a source set src.
-func (src *Source) Generate(w io.Writer) error {
-	t := template.Must(template.New("main").Parse(srcTemplate))
-	err := t.Execute(w, src)
-	if err != nil {
-		return errors.New("Failed to execute template: " + err.Error())
-	}
-	return nil
-}
-
-func usage() {
-	fmt.Fprintf(os.Stderr, "usage: mksyscall_windows [flags] [path ...]\n")
-	flag.PrintDefaults()
-	os.Exit(1)
-}
-
-func main() {
-	flag.Usage = usage
-	flag.Parse()
-	if len(os.Args) <= 1 {
-		fmt.Fprintf(os.Stderr, "no files to parse provided\n")
-		usage()
-	}
-	src, err := ParseFiles(os.Args[1:])
-	if err != nil {
-		log.Fatal(err)
-	}
-	if err := src.Generate(os.Stdout); err != nil {
-		log.Fatal(err)
-	}
-}
-
-// TODO: use println instead to print in the following template
-const srcTemplate = `
-
-{{define "main"}}// go build mksyscall_windows.go && ./mksyscall_windows{{range .Files}} {{.}}{{end}}
-// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
-
-package syscall
-
-import "unsafe"
-
-var (
-{{template "dlls" .}}
-{{template "funcnames" .}})
-{{range .Funcs}}{{template "funcbody" .}}{{end}}
-{{end}}
-
-{{/* help functions */}}
-
-{{define "dlls"}}{{range .DLLs}}	mod{{.}} = NewLazyDLL("{{.}}.dll")
-{{end}}{{end}}
-
-{{define "funcnames"}}{{range .Funcs}}	proc{{.DLLFuncName}} = mod{{.DLLName}}.NewProc("{{.DLLFuncName}}")
-{{end}}{{end}}
-
-{{define "funcbody"}}
-func {{.Name}}({{.ParamList}}) {{if .Rets.List}}{{.Rets.List}} {{end}}{
-{{template "tmpvars" .}}	{{template "syscall" .}}
-{{template "seterror" .}}{{template "printtrace" .}}	return
-}
-{{end}}
-
-{{define "tmpvars"}}{{range .Params}}{{if .TmpVarCode}}	{{.TmpVarCode}}
-{{end}}{{end}}{{end}}
-
-{{define "syscall"}}{{.Rets.SetReturnValuesCode}}{{.Syscall}}(proc{{.DLLFuncName}}.Addr(), {{.ParamCount}}, {{.SyscallParamList}}){{end}}
-
-{{define "seterror"}}{{if .Rets.SetErrorCode}}	{{.Rets.SetErrorCode}}
-{{end}}{{end}}
-
-{{define "printtrace"}}{{if .PrintTrace}}	print("SYSCALL: {{.Name}}(", {{.ParamPrintList}}") (", {{.Rets.PrintList}}")\n")
-{{end}}{{end}}
-
-`
diff --git a/src/pkg/syscall/net_nacl.go b/src/pkg/syscall/net_nacl.go
deleted file mode 100644
index b9488f4..0000000
--- a/src/pkg/syscall/net_nacl.go
+++ /dev/null
@@ -1,912 +0,0 @@
-// Copyright 2013 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// A simulated network for use within NaCl.
-// The simulation is not particularly tied to NaCl,
-// but other systems have real networks.
-
-package syscall
-
-import (
-	"sync"
-	"sync/atomic"
-)
-
-// Interface to timers implemented in package runtime.
-// Must be in sync with ../runtime/runtime.h:/^struct.Timer$
-// Really for use by package time, but we cannot import time here.
-
-type runtimeTimer struct {
-	i      int32
-	when   int64
-	period int64
-	f      func(int64, interface{}) // NOTE: must not be closure
-	arg    interface{}
-}
-
-func startTimer(*runtimeTimer)
-func stopTimer(*runtimeTimer) bool
-
-type timer struct {
-	expired bool
-	q       *queue
-	r       runtimeTimer
-}
-
-func (t *timer) start(q *queue, deadline int64) {
-	if deadline == 0 {
-		return
-	}
-	t.q = q
-	t.r.when = deadline
-	t.r.f = timerExpired
-	t.r.arg = t
-	startTimer(&t.r)
-}
-
-func (t *timer) stop() {
-	stopTimer(&t.r)
-}
-
-func timerExpired(now int64, i interface{}) {
-	t := i.(*timer)
-	go func() {
-		t.q.Lock()
-		defer t.q.Unlock()
-		t.expired = true
-		t.q.canRead.Broadcast()
-		t.q.canWrite.Broadcast()
-	}()
-}
-
-// Network constants and data structures. These match the traditional values.
-
-const (
-	AF_UNSPEC = iota
-	AF_UNIX
-	AF_INET
-	AF_INET6
-)
-
-const (
-	SHUT_RD = iota
-	SHUT_WR
-	SHUT_RDWR
-)
-
-const (
-	SOCK_STREAM = 1 + iota
-	SOCK_DGRAM
-	SOCK_RAW
-	SOCK_SEQPACKET
-)
-
-const (
-	IPPROTO_IP   = 0
-	IPPROTO_IPV4 = 4
-	IPPROTO_IPV6 = 0x29
-	IPPROTO_TCP  = 6
-	IPPROTO_UDP  = 0x11
-)
-
-// Misc constants expected by package net but not supported.
-const (
-	_ = iota
-	SOL_SOCKET
-	SO_TYPE
-	NET_RT_IFLIST
-	IFNAMSIZ
-	IFF_UP
-	IFF_BROADCAST
-	IFF_LOOPBACK
-	IFF_POINTOPOINT
-	IFF_MULTICAST
-	IPV6_V6ONLY
-	SOMAXCONN
-	F_DUPFD_CLOEXEC
-	SO_BROADCAST
-	SO_REUSEADDR
-	SO_REUSEPORT
-	SO_RCVBUF
-	SO_SNDBUF
-	SO_KEEPALIVE
-	SO_LINGER
-	SO_ERROR
-	IP_PORTRANGE
-	IP_PORTRANGE_DEFAULT
-	IP_PORTRANGE_LOW
-	IP_PORTRANGE_HIGH
-	IP_MULTICAST_IF
-	IP_MULTICAST_LOOP
-	IP_ADD_MEMBERSHIP
-	IPV6_PORTRANGE
-	IPV6_PORTRANGE_DEFAULT
-	IPV6_PORTRANGE_LOW
-	IPV6_PORTRANGE_HIGH
-	IPV6_MULTICAST_IF
-	IPV6_MULTICAST_LOOP
-	IPV6_JOIN_GROUP
-	TCP_NODELAY
-	TCP_KEEPINTVL
-	TCP_KEEPIDLE
-
-	SYS_FCNTL = 500 // unsupported
-)
-
-var SocketDisableIPv6 bool
-
-// A Sockaddr is one of the SockaddrXxx structs.
-type Sockaddr interface {
-	// copy returns a copy of the underlying data.
-	copy() Sockaddr
-
-	// key returns the value of the underlying data,
-	// for comparison as a map key.
-	key() interface{}
-}
-
-type SockaddrInet4 struct {
-	Port int
-	Addr [4]byte
-}
-
-func (sa *SockaddrInet4) copy() Sockaddr {
-	sa1 := *sa
-	return &sa1
-}
-
-func (sa *SockaddrInet4) key() interface{} { return *sa }
-
-type SockaddrInet6 struct {
-	Port   int
-	ZoneId uint32
-	Addr   [16]byte
-}
-
-func (sa *SockaddrInet6) copy() Sockaddr {
-	sa1 := *sa
-	return &sa1
-}
-
-func (sa *SockaddrInet6) key() interface{} { return *sa }
-
-type SockaddrUnix struct {
-	Name string
-}
-
-func (sa *SockaddrUnix) copy() Sockaddr {
-	sa1 := *sa
-	return &sa1
-}
-
-func (sa *SockaddrUnix) key() interface{} { return *sa }
-
-type SockaddrDatalink struct {
-	Len    uint8
-	Family uint8
-	Index  uint16
-	Type   uint8
-	Nlen   uint8
-	Alen   uint8
-	Slen   uint8
-	Data   [12]int8
-}
-
-func (sa *SockaddrDatalink) copy() Sockaddr {
-	sa1 := *sa
-	return &sa1
-}
-
-func (sa *SockaddrDatalink) key() interface{} { return *sa }
-
-// RoutingMessage represents a routing message.
-type RoutingMessage interface {
-	unimplemented()
-}
-
-type IPMreq struct {
-	Multiaddr [4]byte /* in_addr */
-	Interface [4]byte /* in_addr */
-}
-
-type IPv6Mreq struct {
-	Multiaddr [16]byte /* in6_addr */
-	Interface uint32
-}
-
-type Linger struct {
-	Onoff  int32
-	Linger int32
-}
-
-type ICMPv6Filter struct {
-	Filt [8]uint32
-}
-
-// A queue is the bookkeeping for a synchronized buffered queue.
-// We do not use channels because we need to be able to handle
-// writes after and during close, and because a chan byte would
-// require too many send and receive operations in real use.
-type queue struct {
-	sync.Mutex
-	canRead  sync.Cond
-	canWrite sync.Cond
-	r        int // total read index
-	w        int // total write index
-	m        int // index mask
-	closed   bool
-}
-
-func (q *queue) init(size int) {
-	if size&(size-1) != 0 {
-		panic("invalid queue size - must be power of two")
-	}
-	q.canRead.L = &q.Mutex
-	q.canWrite.L = &q.Mutex
-	q.m = size - 1
-}
-
-func past(deadline int64) bool {
-	sec, nsec := now()
-	return deadline > 0 && deadline < sec*1e9+int64(nsec)
-}
-
-func (q *queue) waitRead(n int, deadline int64) (int, error) {
-	if past(deadline) {
-		return 0, EAGAIN
-	}
-	var t timer
-	t.start(q, deadline)
-	for q.w-q.r == 0 && !q.closed && !t.expired {
-		q.canRead.Wait()
-	}
-	t.stop()
-	m := q.w - q.r
-	if m == 0 && t.expired {
-		return 0, EAGAIN
-	}
-	if m > n {
-		m = n
-		q.canRead.Signal() // wake up next reader too
-	}
-	q.canWrite.Signal()
-	return m, nil
-}
-
-func (q *queue) waitWrite(n int, deadline int64) (int, error) {
-	if past(deadline) {
-		return 0, EAGAIN
-	}
-	var t timer
-	t.start(q, deadline)
-	for q.w-q.r > q.m && !q.closed && !t.expired {
-		q.canWrite.Wait()
-	}
-	t.stop()
-	m := q.m + 1 - (q.w - q.r)
-	if m == 0 && t.expired {
-		return 0, EAGAIN
-	}
-	if m == 0 {
-		return 0, EAGAIN
-	}
-	if m > n {
-		m = n
-		q.canWrite.Signal() // wake up next writer too
-	}
-	q.canRead.Signal()
-	return m, nil
-}
-
-func (q *queue) close() {
-	q.Lock()
-	defer q.Unlock()
-	q.closed = true
-	q.canRead.Broadcast()
-	q.canWrite.Broadcast()
-}
-
-// A byteq is a byte queue.
-type byteq struct {
-	queue
-	data []byte
-}
-
-func newByteq() *byteq {
-	q := &byteq{
-		data: make([]byte, 4096),
-	}
-	q.init(len(q.data))
-	return q
-}
-
-func (q *byteq) read(b []byte, deadline int64) (int, error) {
-	q.Lock()
-	defer q.Unlock()
-	n, err := q.waitRead(len(b), deadline)
-	if err != nil {
-		return 0, err
-	}
-	b = b[:n]
-	for len(b) > 0 {
-		m := copy(b, q.data[q.r&q.m:])
-		q.r += m
-		b = b[m:]
-	}
-	return n, nil
-}
-
-func (q *byteq) write(b []byte, deadline int64) (n int, err error) {
-	q.Lock()
-	defer q.Unlock()
-	for n < len(b) {
-		nn, err := q.waitWrite(len(b[n:]), deadline)
-		if err != nil {
-			return n, err
-		}
-		bb := b[n : n+nn]
-		n += nn
-		for len(bb) > 0 {
-			m := copy(q.data[q.w&q.m:], bb)
-			q.w += m
-			bb = bb[m:]
-		}
-	}
-	return n, nil
-}
-
-// A msgq is a queue of messages.
-type msgq struct {
-	queue
-	data []interface{}
-}
-
-func newMsgq() *msgq {
-	q := &msgq{
-		data: make([]interface{}, 32),
-	}
-	q.init(len(q.data))
-	return q
-}
-
-func (q *msgq) read(deadline int64) (interface{}, error) {
-	q.Lock()
-	defer q.Unlock()
-	n, err := q.waitRead(1, deadline)
-	if err != nil {
-		return nil, err
-	}
-	if n == 0 {
-		return nil, nil
-	}
-	m := q.data[q.r&q.m]
-	q.r++
-	return m, nil
-}
-
-func (q *msgq) write(m interface{}, deadline int64) error {
-	q.Lock()
-	defer q.Unlock()
-	_, err := q.waitWrite(1, deadline)
-	if err != nil {
-		return err
-	}
-	q.data[q.w&q.m] = m
-	q.w++
-	return nil
-}
-
-// An addr is a sequence of bytes uniquely identifying a network address.
-// It is not human-readable.
-type addr string
-
-// A conn is one side of a stream-based network connection.
-// That is, a stream-based network connection is a pair of cross-connected conns.
-type conn struct {
-	rd     *byteq
-	wr     *byteq
-	local  addr
-	remote addr
-}
-
-// A pktconn is one side of a packet-based network connection.
-// That is, a packet-based network connection is a pair of cross-connected pktconns.
-type pktconn struct {
-	rd     *msgq
-	wr     *msgq
-	local  addr
-	remote addr
-}
-
-// A listener accepts incoming stream-based network connections.
-type listener struct {
-	rd    *msgq
-	local addr
-}
-
-// A netFile is an open network file.
-type netFile struct {
-	defaultFileImpl
-	proto      *netproto
-	sotype     int
-	listener   *msgq
-	packet     *msgq
-	rd         *byteq
-	wr         *byteq
-	rddeadline int64
-	wrdeadline int64
-	addr       Sockaddr
-	raddr      Sockaddr
-}
-
-// A netAddr is a network address in the global listener map.
-// All the fields must have defined == operations.
-type netAddr struct {
-	proto  *netproto
-	sotype int
-	addr   interface{}
-}
-
-// net records the state of the network.
-// It maps a network address to the listener on that address.
-var net = struct {
-	sync.Mutex
-	listener map[netAddr]*netFile
-}{
-	listener: make(map[netAddr]*netFile),
-}
-
-// TODO(rsc): Some day, do a better job with port allocation.
-// For playground programs, incrementing is fine.
-var nextport = 2
-
-// A netproto contains protocol-specific functionality
-// (one for AF_INET, one for AF_INET6 and so on).
-// It is a struct instead of an interface because the
-// implementation needs no state, and I expect to
-// add some data fields at some point.
-type netproto struct {
-	bind func(*netFile, Sockaddr) error
-}
-
-var netprotoAF_INET = &netproto{
-	bind: func(f *netFile, sa Sockaddr) error {
-		if sa == nil {
-			f.addr = &SockaddrInet4{
-				Port: nextport,
-				Addr: [4]byte{127, 0, 0, 1},
-			}
-			nextport++
-			return nil
-		}
-		addr, ok := sa.(*SockaddrInet4)
-		if !ok {
-			return EINVAL
-		}
-		addr = addr.copy().(*SockaddrInet4)
-		if addr.Port == 0 {
-			addr.Port = nextport
-			nextport++
-		}
-		f.addr = addr
-		return nil
-	},
-}
-
-var netprotos = map[int]*netproto{
-	AF_INET: netprotoAF_INET,
-}
-
-// These functions implement the usual BSD socket operations.
-
-func (f *netFile) bind(sa Sockaddr) error {
-	if f.addr != nil {
-		return EISCONN
-	}
-	if err := f.proto.bind(f, sa); err != nil {
-		return err
-	}
-	if f.sotype == SOCK_DGRAM {
-		_, ok := net.listener[netAddr{f.proto, f.sotype, f.addr.key()}]
-		if ok {
-			f.addr = nil
-			return EADDRINUSE
-		}
-		net.listener[netAddr{f.proto, f.sotype, f.addr.key()}] = f
-		f.packet = newMsgq()
-	}
-	return nil
-}
-
-func (f *netFile) listen(backlog int) error {
-	net.Lock()
-	defer net.Unlock()
-	if f.listener != nil {
-		return EINVAL
-	}
-	_, ok := net.listener[netAddr{f.proto, f.sotype, f.addr.key()}]
-	if ok {
-		return EADDRINUSE
-	}
-	net.listener[netAddr{f.proto, f.sotype, f.addr.key()}] = f
-	f.listener = newMsgq()
-	return nil
-}
-
-func (f *netFile) accept() (fd int, sa Sockaddr, err error) {
-	msg, err := f.listener.read(f.readDeadline())
-	if err != nil {
-		return -1, nil, err
-	}
-	newf, ok := msg.(*netFile)
-	if !ok {
-		// must be eof
-		return -1, nil, EAGAIN
-	}
-	return newFD(newf), newf.raddr.copy(), nil
-}
-
-func (f *netFile) connect(sa Sockaddr) error {
-	if past(f.writeDeadline()) {
-		return EAGAIN
-	}
-	if f.addr == nil {
-		if err := f.bind(nil); err != nil {
-			return err
-		}
-	}
-	net.Lock()
-	if sa == nil {
-		net.Unlock()
-		return EINVAL
-	}
-	sa = sa.copy()
-	if f.raddr != nil {
-		net.Unlock()
-		return EISCONN
-	}
-	if f.sotype == SOCK_DGRAM {
-		net.Unlock()
-		f.raddr = sa
-		return nil
-	}
-	if f.listener != nil {
-		net.Unlock()
-		return EISCONN
-	}
-	l, ok := net.listener[netAddr{f.proto, f.sotype, sa.key()}]
-	if !ok {
-		net.Unlock()
-		return ECONNREFUSED
-	}
-	f.raddr = sa
-	f.rd = newByteq()
-	f.wr = newByteq()
-	newf := &netFile{
-		proto:  f.proto,
-		sotype: f.sotype,
-		addr:   f.raddr,
-		raddr:  f.addr,
-		rd:     f.wr,
-		wr:     f.rd,
-	}
-	net.Unlock()
-	l.listener.write(newf, f.writeDeadline())
-	return nil
-}
-
-func (f *netFile) read(b []byte) (int, error) {
-	if f.rd == nil {
-		if f.raddr != nil {
-			n, _, err := f.recvfrom(b, 0)
-			return n, err
-		}
-		return 0, ENOTCONN
-	}
-	return f.rd.read(b, f.readDeadline())
-}
-
-func (f *netFile) write(b []byte) (int, error) {
-	if f.wr == nil {
-		if f.raddr != nil {
-			err := f.sendto(b, 0, f.raddr)
-			var n int
-			if err == nil {
-				n = len(b)
-			}
-			return n, err
-		}
-		return 0, ENOTCONN
-	}
-	return f.wr.write(b, f.writeDeadline())
-}
-
-type pktmsg struct {
-	buf  []byte
-	addr Sockaddr
-}
-
-func (f *netFile) recvfrom(p []byte, flags int) (n int, from Sockaddr, err error) {
-	if f.sotype != SOCK_DGRAM {
-		return 0, nil, EINVAL
-	}
-	if f.packet == nil {
-		return 0, nil, ENOTCONN
-	}
-	msg1, err := f.packet.read(f.readDeadline())
-	if err != nil {
-		return 0, nil, err
-	}
-	msg, ok := msg1.(*pktmsg)
-	if !ok {
-		return 0, nil, EAGAIN
-	}
-	return copy(p, msg.buf), msg.addr, nil
-}
-
-func (f *netFile) sendto(p []byte, flags int, to Sockaddr) error {
-	if f.sotype != SOCK_DGRAM {
-		return EINVAL
-	}
-	if f.packet == nil {
-		if err := f.bind(nil); err != nil {
-			return err
-		}
-	}
-	net.Lock()
-	if to == nil {
-		net.Unlock()
-		return EINVAL
-	}
-	to = to.copy()
-	l, ok := net.listener[netAddr{f.proto, f.sotype, to.key()}]
-	if !ok || l.packet == nil {
-		net.Unlock()
-		return ECONNREFUSED
-	}
-	net.Unlock()
-	msg := &pktmsg{
-		buf:  make([]byte, len(p)),
-		addr: f.addr,
-	}
-	copy(msg.buf, p)
-	l.packet.write(msg, f.writeDeadline())
-	return nil
-}
-
-func (f *netFile) close() error {
-	if f.listener != nil {
-		f.listener.close()
-	}
-	if f.packet != nil {
-		f.packet.close()
-	}
-	if f.rd != nil {
-		f.rd.close()
-	}
-	if f.wr != nil {
-		f.wr.close()
-	}
-	return nil
-}
-
-func fdToNetFile(fd int) (*netFile, error) {
-	f, err := fdToFile(fd)
-	if err != nil {
-		return nil, err
-	}
-	impl := f.impl
-	netf, ok := impl.(*netFile)
-	if !ok {
-		return nil, EINVAL
-	}
-	return netf, nil
-}
-
-func Socket(proto, sotype, unused int) (fd int, err error) {
-	p := netprotos[proto]
-	if p == nil {
-		return -1, EPROTONOSUPPORT
-	}
-	if sotype != SOCK_STREAM && sotype != SOCK_DGRAM {
-		return -1, ESOCKTNOSUPPORT
-	}
-	f := &netFile{
-		proto:  p,
-		sotype: sotype,
-	}
-	return newFD(f), nil
-}
-
-func Bind(fd int, sa Sockaddr) error {
-	f, err := fdToNetFile(fd)
-	if err != nil {
-		return err
-	}
-	return f.bind(sa)
-}
-
-func StopIO(fd int) error {
-	f, err := fdToNetFile(fd)
-	if err != nil {
-		return err
-	}
-	f.close()
-	return nil
-}
-
-func Listen(fd int, backlog int) error {
-	f, err := fdToNetFile(fd)
-	if err != nil {
-		return err
-	}
-	return f.listen(backlog)
-}
-
-func Accept(fd int) (newfd int, sa Sockaddr, err error) {
-	f, err := fdToNetFile(fd)
-	if err != nil {
-		return 0, nil, err
-	}
-	return f.accept()
-}
-
-func Getsockname(fd int) (sa Sockaddr, err error) {
-	f, err := fdToNetFile(fd)
-	if err != nil {
-		return nil, err
-	}
-	if f.addr == nil {
-		return nil, ENOTCONN
-	}
-	return f.addr.copy(), nil
-}
-
-func Getpeername(fd int) (sa Sockaddr, err error) {
-	f, err := fdToNetFile(fd)
-	if err != nil {
-		return nil, err
-	}
-	if f.raddr == nil {
-		return nil, ENOTCONN
-	}
-	return f.raddr.copy(), nil
-}
-
-func Connect(fd int, sa Sockaddr) error {
-	f, err := fdToNetFile(fd)
-	if err != nil {
-		return err
-	}
-	return f.connect(sa)
-}
-
-func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, err error) {
-	f, err := fdToNetFile(fd)
-	if err != nil {
-		return 0, nil, err
-	}
-	return f.recvfrom(p, flags)
-}
-
-func Sendto(fd int, p []byte, flags int, to Sockaddr) error {
-	f, err := fdToNetFile(fd)
-	if err != nil {
-		return err
-	}
-	return f.sendto(p, flags, to)
-}
-
-func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn, recvflags int, from Sockaddr, err error) {
-	f, err := fdToNetFile(fd)
-	if err != nil {
-		return
-	}
-	n, from, err = f.recvfrom(p, flags)
-	return
-}
-
-func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) error {
-	_, err := SendmsgN(fd, p, oob, to, flags)
-	return err
-}
-
-func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) {
-	f, err := fdToNetFile(fd)
-	if err != nil {
-		return 0, err
-	}
-	switch f.sotype {
-	case SOCK_STREAM:
-		n, err = f.write(p)
-	case SOCK_DGRAM:
-		n = len(p)
-		err = f.sendto(p, flags, to)
-	}
-	if err != nil {
-		return 0, err
-	}
-	return n, nil
-}
-
-func GetsockoptInt(fd, level, opt int) (value int, err error) {
-	f, err := fdToNetFile(fd)
-	if err != nil {
-		return 0, err
-	}
-	switch {
-	case level == SOL_SOCKET && opt == SO_TYPE:
-		return f.sotype, nil
-	}
-	return 0, ENOTSUP
-}
-
-func SetsockoptInt(fd, level, opt int, value int) error {
-	return nil
-}
-
-func SetsockoptByte(fd, level, opt int, value byte) error {
-	_, err := fdToNetFile(fd)
-	if err != nil {
-		return err
-	}
-	return ENOTSUP
-}
-
-func SetsockoptLinger(fd, level, opt int, l *Linger) error {
-	return nil
-}
-
-func SetReadDeadline(fd int, t int64) error {
-	f, err := fdToNetFile(fd)
-	if err != nil {
-		return err
-	}
-	atomic.StoreInt64(&f.rddeadline, t)
-	return nil
-}
-
-func (f *netFile) readDeadline() int64 {
-	return atomic.LoadInt64(&f.rddeadline)
-}
-
-func SetWriteDeadline(fd int, t int64) error {
-	f, err := fdToNetFile(fd)
-	if err != nil {
-		return err
-	}
-	atomic.StoreInt64(&f.wrdeadline, t)
-	return nil
-}
-
-func (f *netFile) writeDeadline() int64 {
-	return atomic.LoadInt64(&f.wrdeadline)
-}
-
-func Shutdown(fd int, how int) error {
-	f, err := fdToNetFile(fd)
-	if err != nil {
-		return err
-	}
-	switch how {
-	case SHUT_RD:
-		f.rd.close()
-	case SHUT_WR:
-		f.wr.close()
-	case SHUT_RDWR:
-		f.rd.close()
-		f.wr.close()
-	}
-	return nil
-}
-
-func SetsockoptICMPv6Filter(fd, level, opt int, filter *ICMPv6Filter) error { panic("SetsockoptICMPv") }
-func SetsockoptIPMreq(fd, level, opt int, mreq *IPMreq) error               { panic("SetsockoptIPMreq") }
-func SetsockoptIPv6Mreq(fd, level, opt int, mreq *IPv6Mreq) error           { panic("SetsockoptIPv") }
-func SetsockoptInet4Addr(fd, level, opt int, value [4]byte) error           { panic("SetsockoptInet") }
-func SetsockoptString(fd, level, opt int, s string) error                   { panic("SetsockoptString") }
-func SetsockoptTimeval(fd, level, opt int, tv *Timeval) error               { panic("SetsockoptTimeval") }
-func Socketpair(domain, typ, proto int) (fd [2]int, err error)              { panic("Socketpair") }
-
-func SetNonblock(fd int, nonblocking bool) error { return nil }
diff --git a/src/pkg/syscall/netlink_linux.go b/src/pkg/syscall/netlink_linux.go
deleted file mode 100644
index 49550ea..0000000
--- a/src/pkg/syscall/netlink_linux.go
+++ /dev/null
@@ -1,177 +0,0 @@
-// Copyright 2011 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Netlink sockets and messages
-
-package syscall
-
-import "unsafe"
-
-// Round the length of a netlink message up to align it properly.
-func nlmAlignOf(msglen int) int {
-	return (msglen + NLMSG_ALIGNTO - 1) & ^(NLMSG_ALIGNTO - 1)
-}
-
-// Round the length of a netlink route attribute up to align it
-// properly.
-func rtaAlignOf(attrlen int) int {
-	return (attrlen + RTA_ALIGNTO - 1) & ^(RTA_ALIGNTO - 1)
-}
-
-// NetlinkRouteRequest represents a request message to receive routing
-// and link states from the kernel.
-type NetlinkRouteRequest struct {
-	Header NlMsghdr
-	Data   RtGenmsg
-}
-
-func (rr *NetlinkRouteRequest) toWireFormat() []byte {
-	b := make([]byte, rr.Header.Len)
-	*(*uint32)(unsafe.Pointer(&b[0:4][0])) = rr.Header.Len
-	*(*uint16)(unsafe.Pointer(&b[4:6][0])) = rr.Header.Type
-	*(*uint16)(unsafe.Pointer(&b[6:8][0])) = rr.Header.Flags
-	*(*uint32)(unsafe.Pointer(&b[8:12][0])) = rr.Header.Seq
-	*(*uint32)(unsafe.Pointer(&b[12:16][0])) = rr.Header.Pid
-	b[16] = byte(rr.Data.Family)
-	return b
-}
-
-func newNetlinkRouteRequest(proto, seq, family int) []byte {
-	rr := &NetlinkRouteRequest{}
-	rr.Header.Len = uint32(NLMSG_HDRLEN + SizeofRtGenmsg)
-	rr.Header.Type = uint16(proto)
-	rr.Header.Flags = NLM_F_DUMP | NLM_F_REQUEST
-	rr.Header.Seq = uint32(seq)
-	rr.Data.Family = uint8(family)
-	return rr.toWireFormat()
-}
-
-// NetlinkRIB returns routing information base, as known as RIB, which
-// consists of network facility information, states and parameters.
-func NetlinkRIB(proto, family int) ([]byte, error) {
-	s, err := Socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE)
-	if err != nil {
-		return nil, err
-	}
-	defer Close(s)
-	lsa := &SockaddrNetlink{Family: AF_NETLINK}
-	if err := Bind(s, lsa); err != nil {
-		return nil, err
-	}
-	wb := newNetlinkRouteRequest(proto, 1, family)
-	if err := Sendto(s, wb, 0, lsa); err != nil {
-		return nil, err
-	}
-	var tab []byte
-done:
-	for {
-		rb := make([]byte, Getpagesize())
-		nr, _, err := Recvfrom(s, rb, 0)
-		if err != nil {
-			return nil, err
-		}
-		if nr < NLMSG_HDRLEN {
-			return nil, EINVAL
-		}
-		rb = rb[:nr]
-		tab = append(tab, rb...)
-		msgs, err := ParseNetlinkMessage(rb)
-		if err != nil {
-			return nil, err
-		}
-		for _, m := range msgs {
-			lsa, err := Getsockname(s)
-			if err != nil {
-				return nil, err
-			}
-			switch v := lsa.(type) {
-			case *SockaddrNetlink:
-				if m.Header.Seq != 1 || m.Header.Pid != v.Pid {
-					return nil, EINVAL
-				}
-			default:
-				return nil, EINVAL
-			}
-			if m.Header.Type == NLMSG_DONE {
-				break done
-			}
-			if m.Header.Type == NLMSG_ERROR {
-				return nil, EINVAL
-			}
-		}
-	}
-	return tab, nil
-}
-
-// NetlinkMessage represents a netlink message.
-type NetlinkMessage struct {
-	Header NlMsghdr
-	Data   []byte
-}
-
-// ParseNetlinkMessage parses b as an array of netlink messages and
-// returns the slice containing the NetlinkMessage structures.
-func ParseNetlinkMessage(b []byte) ([]NetlinkMessage, error) {
-	var msgs []NetlinkMessage
-	for len(b) >= NLMSG_HDRLEN {
-		h, dbuf, dlen, err := netlinkMessageHeaderAndData(b)
-		if err != nil {
-			return nil, err
-		}
-		m := NetlinkMessage{Header: *h, Data: dbuf[:int(h.Len)-NLMSG_HDRLEN]}
-		msgs = append(msgs, m)
-		b = b[dlen:]
-	}
-	return msgs, nil
-}
-
-func netlinkMessageHeaderAndData(b []byte) (*NlMsghdr, []byte, int, error) {
-	h := (*NlMsghdr)(unsafe.Pointer(&b[0]))
-	if int(h.Len) < NLMSG_HDRLEN || int(h.Len) > len(b) {
-		return nil, nil, 0, EINVAL
-	}
-	return h, b[NLMSG_HDRLEN:], nlmAlignOf(int(h.Len)), nil
-}
-
-// NetlinkRouteAttr represents a netlink route attribute.
-type NetlinkRouteAttr struct {
-	Attr  RtAttr
-	Value []byte
-}
-
-// ParseNetlinkRouteAttr parses m's payload as an array of netlink
-// route attributes and returns the slice containing the
-// NetlinkRouteAttr structures.
-func ParseNetlinkRouteAttr(m *NetlinkMessage) ([]NetlinkRouteAttr, error) {
-	var b []byte
-	switch m.Header.Type {
-	case RTM_NEWLINK, RTM_DELLINK:
-		b = m.Data[SizeofIfInfomsg:]
-	case RTM_NEWADDR, RTM_DELADDR:
-		b = m.Data[SizeofIfAddrmsg:]
-	case RTM_NEWROUTE, RTM_DELROUTE:
-		b = m.Data[SizeofRtMsg:]
-	default:
-		return nil, EINVAL
-	}
-	var attrs []NetlinkRouteAttr
-	for len(b) >= SizeofRtAttr {
-		a, vbuf, alen, err := netlinkRouteAttrAndValue(b)
-		if err != nil {
-			return nil, err
-		}
-		ra := NetlinkRouteAttr{Attr: *a, Value: vbuf[:int(a.Len)-SizeofRtAttr]}
-		attrs = append(attrs, ra)
-		b = b[alen:]
-	}
-	return attrs, nil
-}
-
-func netlinkRouteAttrAndValue(b []byte) (*RtAttr, []byte, int, error) {
-	a := (*RtAttr)(unsafe.Pointer(&b[0]))
-	if int(a.Len) < SizeofRtAttr || int(a.Len) > len(b) {
-		return nil, nil, 0, EINVAL
-	}
-	return a, b[SizeofRtAttr:], rtaAlignOf(int(a.Len)), nil
-}
diff --git a/src/pkg/syscall/route_bsd.go b/src/pkg/syscall/route_bsd.go
deleted file mode 100644
index 48af587..0000000
--- a/src/pkg/syscall/route_bsd.go
+++ /dev/null
@@ -1,224 +0,0 @@
-// Copyright 2011 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build darwin dragonfly freebsd netbsd openbsd
-
-// Routing sockets and messages
-
-package syscall
-
-import "unsafe"
-
-// Round the length of a raw sockaddr up to align it properly.
-func rsaAlignOf(salen int) int {
-	salign := sizeofPtr
-	// NOTE: It seems like 64-bit Darwin kernel still requires
-	// 32-bit aligned access to BSD subsystem. Also NetBSD 6
-	// kernel and beyond require 64-bit aligned access to routing
-	// facilities.
-	if darwin64Bit {
-		salign = 4
-	} else if netbsd32Bit {
-		salign = 8
-	}
-	if salen == 0 {
-		return salign
-	}
-	return (salen + salign - 1) & ^(salign - 1)
-}
-
-// RouteRIB returns routing information base, as known as RIB,
-// which consists of network facility information, states and
-// parameters.
-func RouteRIB(facility, param int) ([]byte, error) {
-	mib := []_C_int{CTL_NET, AF_ROUTE, 0, 0, _C_int(facility), _C_int(param)}
-	// Find size.
-	n := uintptr(0)
-	if err := sysctl(mib, nil, &n, nil, 0); err != nil {
-		return nil, err
-	}
-	if n == 0 {
-		return nil, nil
-	}
-	tab := make([]byte, n)
-	if err := sysctl(mib, &tab[0], &n, nil, 0); err != nil {
-		return nil, err
-	}
-	return tab[:n], nil
-}
-
-// RoutingMessage represents a routing message.
-type RoutingMessage interface {
-	sockaddr() []Sockaddr
-}
-
-const anyMessageLen = int(unsafe.Sizeof(anyMessage{}))
-
-type anyMessage struct {
-	Msglen  uint16
-	Version uint8
-	Type    uint8
-}
-
-// RouteMessage represents a routing message containing routing
-// entries.
-type RouteMessage struct {
-	Header RtMsghdr
-	Data   []byte
-}
-
-const rtaRtMask = RTA_DST | RTA_GATEWAY | RTA_NETMASK | RTA_GENMASK
-
-func (m *RouteMessage) sockaddr() []Sockaddr {
-	var (
-		af  int
-		sas [4]Sockaddr
-	)
-	b := m.Data[:]
-	for i := uint(0); i < RTAX_MAX; i++ {
-		if m.Header.Addrs&rtaRtMask&(1<<i) == 0 {
-			continue
-		}
-		rsa := (*RawSockaddr)(unsafe.Pointer(&b[0]))
-		switch i {
-		case RTAX_DST, RTAX_GATEWAY:
-			sa, err := anyToSockaddr((*RawSockaddrAny)(unsafe.Pointer(rsa)))
-			if err != nil {
-				return nil
-			}
-			if i == RTAX_DST {
-				af = int(rsa.Family)
-			}
-			sas[i] = sa
-		case RTAX_NETMASK, RTAX_GENMASK:
-			switch af {
-			case AF_INET:
-				rsa4 := (*RawSockaddrInet4)(unsafe.Pointer(&b[0]))
-				sa := new(SockaddrInet4)
-				for j := 0; rsa4.Len > 0 && j < int(rsa4.Len)-int(unsafe.Offsetof(rsa4.Addr)); j++ {
-					sa.Addr[j] = rsa4.Addr[j]
-				}
-				sas[i] = sa
-			case AF_INET6:
-				rsa6 := (*RawSockaddrInet6)(unsafe.Pointer(&b[0]))
-				sa := new(SockaddrInet6)
-				for j := 0; rsa6.Len > 0 && j < int(rsa6.Len)-int(unsafe.Offsetof(rsa6.Addr)); j++ {
-					sa.Addr[j] = rsa6.Addr[j]
-				}
-				sas[i] = sa
-			}
-		}
-		b = b[rsaAlignOf(int(rsa.Len)):]
-	}
-	return sas[:]
-}
-
-// InterfaceMessage represents a routing message containing
-// network interface entries.
-type InterfaceMessage struct {
-	Header IfMsghdr
-	Data   []byte
-}
-
-func (m *InterfaceMessage) sockaddr() (sas []Sockaddr) {
-	if m.Header.Addrs&RTA_IFP == 0 {
-		return nil
-	}
-	sa, err := anyToSockaddr((*RawSockaddrAny)(unsafe.Pointer(&m.Data[0])))
-	if err != nil {
-		return nil
-	}
-	return append(sas, sa)
-}
-
-// InterfaceAddrMessage represents a routing message containing
-// network interface address entries.
-type InterfaceAddrMessage struct {
-	Header IfaMsghdr
-	Data   []byte
-}
-
-const rtaIfaMask = RTA_IFA | RTA_NETMASK | RTA_BRD
-
-func (m *InterfaceAddrMessage) sockaddr() (sas []Sockaddr) {
-	if m.Header.Addrs&rtaIfaMask == 0 {
-		return nil
-	}
-	b := m.Data[:]
-	// We still see AF_UNSPEC in socket addresses on some
-	// platforms. To identify each address family correctly, we
-	// will use the address family of RTAX_NETMASK as a preferred
-	// one on the 32-bit NetBSD kernel, also use the length of
-	// RTAX_NETMASK socket address on the FreeBSD kernel.
-	preferredFamily := uint8(AF_UNSPEC)
-	for i := uint(0); i < RTAX_MAX; i++ {
-		if m.Header.Addrs&rtaIfaMask&(1<<i) == 0 {
-			continue
-		}
-		rsa := (*RawSockaddr)(unsafe.Pointer(&b[0]))
-		switch i {
-		case RTAX_IFA:
-			if rsa.Family == AF_UNSPEC {
-				rsa.Family = preferredFamily
-			}
-			sa, err := anyToSockaddr((*RawSockaddrAny)(unsafe.Pointer(rsa)))
-			if err != nil {
-				return nil
-			}
-			sas = append(sas, sa)
-		case RTAX_NETMASK:
-			switch rsa.Family {
-			case AF_UNSPEC:
-				switch rsa.Len {
-				case SizeofSockaddrInet4:
-					rsa.Family = AF_INET
-				case SizeofSockaddrInet6:
-					rsa.Family = AF_INET6
-				default:
-					rsa.Family = AF_INET // an old fashion, AF_UNSPEC means AF_INET
-				}
-			case AF_INET, AF_INET6:
-				preferredFamily = rsa.Family
-			default:
-				return nil
-			}
-			sa, err := anyToSockaddr((*RawSockaddrAny)(unsafe.Pointer(rsa)))
-			if err != nil {
-				return nil
-			}
-			sas = append(sas, sa)
-		case RTAX_BRD:
-			// nothing to do
-		}
-		b = b[rsaAlignOf(int(rsa.Len)):]
-	}
-	return sas
-}
-
-// ParseRoutingMessage parses b as routing messages and returns the
-// slice containing the RoutingMessage interfaces.
-func ParseRoutingMessage(b []byte) (msgs []RoutingMessage, err error) {
-	msgCount := 0
-	for len(b) >= anyMessageLen {
-		msgCount++
-		any := (*anyMessage)(unsafe.Pointer(&b[0]))
-		if any.Version != RTM_VERSION {
-			b = b[any.Msglen:]
-			continue
-		}
-		msgs = append(msgs, any.toRoutingMessage(b))
-		b = b[any.Msglen:]
-	}
-	// We failed to parse any of the messages - version mismatch?
-	if msgCount > 0 && len(msgs) == 0 {
-		return nil, EINVAL
-	}
-	return msgs, nil
-}
-
-// ParseRoutingMessage parses msg's payload as raw sockaddrs and
-// returns the slice containing the Sockaddr interfaces.
-func ParseRoutingSockaddr(msg RoutingMessage) (sas []Sockaddr, err error) {
-	return append(sas, msg.sockaddr()...), nil
-}
diff --git a/src/pkg/syscall/so_solaris.go b/src/pkg/syscall/so_solaris.go
deleted file mode 100644
index 659cd67..0000000
--- a/src/pkg/syscall/so_solaris.go
+++ /dev/null
@@ -1,260 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package syscall
-
-import (
-	"sync"
-	"sync/atomic"
-	"unsafe"
-)
-
-// soError describes reasons for shared library load failures.
-type soError struct {
-	Err     error
-	ObjName string
-	Msg     string
-}
-
-func (e *soError) Error() string { return e.Msg }
-
-// Implemented in ../runtime/syscall_solaris.goc.
-func rawSysvicall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
-func sysvicall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
-func dlclose(handle uintptr) (err Errno)
-func dlopen(name *uint8, mode uintptr) (handle uintptr, err Errno)
-func dlsym(handle uintptr, name *uint8) (proc uintptr, err Errno)
-
-// A so implements access to a single shared library object.
-type so struct {
-	Name   string
-	Handle uintptr
-}
-
-// loadSO loads shared library file into memory.
-func loadSO(name string) (*so, error) {
-	namep, err := BytePtrFromString(name)
-	if err != nil {
-		return nil, err
-	}
-	h, e := dlopen(namep, 1) // RTLD_LAZY
-	if e != 0 {
-		return nil, &soError{
-			Err:     e,
-			ObjName: name,
-			Msg:     "Failed to load " + name + ": " + e.Error(),
-		}
-	}
-	d := &so{
-		Name:   name,
-		Handle: uintptr(h),
-	}
-	return d, nil
-}
-
-// mustLoadSO is like loadSO but panics if load operation fails.
-func mustLoadSO(name string) *so {
-	d, e := loadSO(name)
-	if e != nil {
-		panic(e)
-	}
-	return d
-}
-
-// FindProc searches shared library d for procedure named name and returns
-// *proc if found. It returns an error if the search fails.
-func (d *so) FindProc(name string) (*proc, error) {
-	namep, err := BytePtrFromString(name)
-	if err != nil {
-		return nil, err
-	}
-	a, _ := dlsym(uintptr(d.Handle), namep)
-	if a == 0 {
-		return nil, &soError{
-			Err:     ENOSYS,
-			ObjName: name,
-			Msg:     "Failed to find " + name + " procedure in " + d.Name,
-		}
-	}
-	p := &proc{
-		SO:   d,
-		Name: name,
-		addr: a,
-	}
-	return p, nil
-}
-
-// MustFindProc is like FindProc but panics if search fails.
-func (d *so) MustFindProc(name string) *proc {
-	p, e := d.FindProc(name)
-	if e != nil {
-		panic(e)
-	}
-	return p
-}
-
-// Release unloads shared library d from memory.
-func (d *so) Release() (err error) {
-	return dlclose(d.Handle)
-}
-
-// A proc implements access to a procedure inside a shared library.
-type proc struct {
-	SO   *so
-	Name string
-	addr uintptr
-}
-
-// Addr returns the address of the procedure represented by p.
-// The return value can be passed to Syscall to run the procedure.
-func (p *proc) Addr() uintptr {
-	return p.addr
-}
-
-// Call executes procedure p with arguments a. It will panic, if more then
-// 6 arguments are supplied.
-//
-// The returned error is always non-nil, constructed from the result of
-// GetLastError.  Callers must inspect the primary return value to decide
-// whether an error occurred (according to the semantics of the specific
-// function being called) before consulting the error. The error will be
-// guaranteed to contain syscall.Errno.
-func (p *proc) Call(a ...uintptr) (r1, r2 uintptr, lastErr error) {
-	switch len(a) {
-	case 0:
-		return sysvicall6(p.Addr(), uintptr(len(a)), 0, 0, 0, 0, 0, 0)
-	case 1:
-		return sysvicall6(p.Addr(), uintptr(len(a)), a[0], 0, 0, 0, 0, 0)
-	case 2:
-		return sysvicall6(p.Addr(), uintptr(len(a)), a[0], a[1], 0, 0, 0, 0)
-	case 3:
-		return sysvicall6(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], 0, 0, 0)
-	case 4:
-		return sysvicall6(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], 0, 0)
-	case 5:
-		return sysvicall6(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], 0)
-	case 6:
-		return sysvicall6(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5])
-	default:
-		panic("Call " + p.Name + " with too many arguments " + itoa(len(a)) + ".")
-	}
-	return
-}
-
-// A lazySO implements access to a single shared library.  It will delay
-// the load of the shared library until the first call to its Handle method
-// or to one of its lazyProc's Addr method.
-type lazySO struct {
-	mu   sync.Mutex
-	so   *so // non nil once SO is loaded
-	Name string
-}
-
-// Load loads single shared file d.Name into memory. It returns an error if
-// fails.  Load will not try to load SO, if it is already loaded into memory.
-func (d *lazySO) Load() error {
-	// Non-racy version of:
-	// if d.so == nil {
-	if atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(&d.so))) == nil {
-		d.mu.Lock()
-		defer d.mu.Unlock()
-		if d.so == nil {
-			so, e := loadSO(d.Name)
-			if e != nil {
-				return e
-			}
-			// Non-racy version of:
-			// d.so = so
-			atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(&d.so)), unsafe.Pointer(so))
-		}
-	}
-	return nil
-}
-
-// mustLoad is like Load but panics if search fails.
-func (d *lazySO) mustLoad() {
-	e := d.Load()
-	if e != nil {
-		panic(e)
-	}
-}
-
-// Handle returns d's module handle.
-func (d *lazySO) Handle() uintptr {
-	d.mustLoad()
-	return uintptr(d.so.Handle)
-}
-
-// NewProc returns a lazyProc for accessing the named procedure in the SO d.
-func (d *lazySO) NewProc(name string) *lazyProc {
-	return &lazyProc{l: d, Name: name}
-}
-
-// newLazySO creates new lazySO associated with SO file.
-func newLazySO(name string) *lazySO {
-	return &lazySO{Name: name}
-}
-
-// A lazyProc implements access to a procedure inside a lazySO.
-// It delays the lookup until the Addr method is called.
-type lazyProc struct {
-	mu   sync.Mutex
-	Name string
-	l    *lazySO
-	proc *proc
-}
-
-// Find searches the shared library for procedure named p.Name. It returns an
-// error if search fails. Find will not search procedure, if it is already
-// found and loaded into memory.
-func (p *lazyProc) Find() error {
-	// Non-racy version of:
-	// if p.proc == nil {
-	if atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(&p.proc))) == nil {
-		p.mu.Lock()
-		defer p.mu.Unlock()
-		if p.proc == nil {
-			e := p.l.Load()
-			if e != nil {
-				return e
-			}
-			proc, e := p.l.so.FindProc(p.Name)
-			if e != nil {
-				return e
-			}
-			// Non-racy version of:
-			// p.proc = proc
-			atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(&p.proc)), unsafe.Pointer(proc))
-		}
-	}
-	return nil
-}
-
-// mustFind is like Find but panics if search fails.
-func (p *lazyProc) mustFind() {
-	e := p.Find()
-	if e != nil {
-		panic(e)
-	}
-}
-
-// Addr returns the address of the procedure represented by p.
-// The return value can be passed to Syscall to run the procedure.
-func (p *lazyProc) Addr() uintptr {
-	p.mustFind()
-	return p.proc.Addr()
-}
-
-// Call executes procedure p with arguments a. It will panic, if more then
-// 6 arguments are supplied.
-//
-// The returned error is always non-nil, constructed from the result of
-// GetLastError.  Callers must inspect the primary return value to decide
-// whether an error occurred (according to the semantics of the specific
-// function being called) before consulting the error. The error will be
-// guaranteed to contain syscall.Errno.
-func (p *lazyProc) Call(a ...uintptr) (r1, r2 uintptr, lastErr error) {
-	p.mustFind()
-	return p.proc.Call(a...)
-}
diff --git a/src/pkg/syscall/str.go b/src/pkg/syscall/str.go
deleted file mode 100644
index 0fce842..0000000
--- a/src/pkg/syscall/str.go
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package syscall
-
-func itoa(val int) string { // do it here rather than with fmt to avoid dependency
-	if val < 0 {
-		return "-" + itoa(-val)
-	}
-	var buf [32]byte // big enough for int64
-	i := len(buf) - 1
-	for val >= 10 {
-		buf[i] = byte(val%10 + '0')
-		i--
-		val /= 10
-	}
-	buf[i] = byte(val + '0')
-	return string(buf[i:])
-}
diff --git a/src/pkg/syscall/syscall.go b/src/pkg/syscall/syscall.go
deleted file mode 100644
index f7473fd..0000000
--- a/src/pkg/syscall/syscall.go
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package syscall contains an interface to the low-level operating system
-// primitives.  The details vary depending on the underlying system, and
-// by default, godoc will display the syscall documentation for the current
-// system.  If you want godoc to display syscall documentation for another
-// system, set $GOOS and $GOARCH to the desired system.  For example, if
-// you want to view documentation for freebsd/arm on linux/amd64, set $GOOS
-// to freebsd and $GOARCH to arm.
-// The primary use of syscall is inside other packages that provide a more
-// portable interface to the system, such as "os", "time" and "net".  Use
-// those packages rather than this one if you can.
-// For details of the functions and data types in this package consult
-// the manuals for the appropriate operating system.
-// These calls return err == nil to indicate success; otherwise
-// err is an operating system error describing the failure.
-// On most systems, that error has type syscall.Errno.
-package syscall
-
-// StringByteSlice is deprecated. Use ByteSliceFromString instead.
-// If s contains a NUL byte this function panics instead of
-// returning an error.
-func StringByteSlice(s string) []byte {
-	a, err := ByteSliceFromString(s)
-	if err != nil {
-		panic("syscall: string with NUL passed to StringByteSlice")
-	}
-	return a
-}
-
-// ByteSliceFromString returns a NUL-terminated slice of bytes
-// containing the text of s. If s contains a NUL byte at any
-// location, it returns (nil, EINVAL).
-func ByteSliceFromString(s string) ([]byte, error) {
-	for i := 0; i < len(s); i++ {
-		if s[i] == 0 {
-			return nil, EINVAL
-		}
-	}
-	a := make([]byte, len(s)+1)
-	copy(a, s)
-	return a, nil
-}
-
-// StringBytePtr is deprecated. Use BytePtrFromString instead.
-// If s contains a NUL byte this function panics instead of
-// returning an error.
-func StringBytePtr(s string) *byte { return &StringByteSlice(s)[0] }
-
-// BytePtrFromString returns a pointer to a NUL-terminated array of
-// bytes containing the text of s. If s contains a NUL byte at any
-// location, it returns (nil, EINVAL).
-func BytePtrFromString(s string) (*byte, error) {
-	a, err := ByteSliceFromString(s)
-	if err != nil {
-		return nil, err
-	}
-	return &a[0], nil
-}
-
-// Single-word zero for use when we need a valid pointer to 0 bytes.
-// See mksyscall.pl.
-var _zero uintptr
-
-func (ts *Timespec) Unix() (sec int64, nsec int64) {
-	return int64(ts.Sec), int64(ts.Nsec)
-}
-
-func (tv *Timeval) Unix() (sec int64, nsec int64) {
-	return int64(tv.Sec), int64(tv.Usec) * 1000
-}
-
-func (ts *Timespec) Nano() int64 {
-	return int64(ts.Sec)*1e9 + int64(ts.Nsec)
-}
-
-func (tv *Timeval) Nano() int64 {
-	return int64(tv.Sec)*1e9 + int64(tv.Usec)*1000
-}
diff --git a/src/pkg/syscall/syscall_bsd.go b/src/pkg/syscall/syscall_bsd.go
deleted file mode 100644
index b042841..0000000
--- a/src/pkg/syscall/syscall_bsd.go
+++ /dev/null
@@ -1,553 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build darwin dragonfly freebsd netbsd openbsd
-
-// BSD system call wrappers shared by *BSD based systems
-// including OS X (Darwin) and FreeBSD.  Like the other
-// syscall_*.go files it is compiled as Go code but also
-// used as input to mksyscall which parses the //sys
-// lines and generates system call stubs.
-
-package syscall
-
-import (
-	"runtime"
-	"unsafe"
-)
-
-/*
- * Wrapped
- */
-
-//sysnb	getgroups(ngid int, gid *_Gid_t) (n int, err error)
-//sysnb	setgroups(ngid int, gid *_Gid_t) (err error)
-
-func Getgroups() (gids []int, err error) {
-	n, err := getgroups(0, nil)
-	if err != nil {
-		return nil, err
-	}
-	if n == 0 {
-		return nil, nil
-	}
-
-	// Sanity check group count.  Max is 16 on BSD.
-	if n < 0 || n > 1000 {
-		return nil, EINVAL
-	}
-
-	a := make([]_Gid_t, n)
-	n, err = getgroups(n, &a[0])
-	if err != nil {
-		return nil, err
-	}
-	gids = make([]int, n)
-	for i, v := range a[0:n] {
-		gids[i] = int(v)
-	}
-	return
-}
-
-func Setgroups(gids []int) (err error) {
-	if len(gids) == 0 {
-		return setgroups(0, nil)
-	}
-
-	a := make([]_Gid_t, len(gids))
-	for i, v := range gids {
-		a[i] = _Gid_t(v)
-	}
-	return setgroups(len(a), &a[0])
-}
-
-func ReadDirent(fd int, buf []byte) (n int, err error) {
-	// Final argument is (basep *uintptr) and the syscall doesn't take nil.
-	// 64 bits should be enough. (32 bits isn't even on 386). Since the
-	// actual system call is getdirentries64, 64 is a good guess.
-	// TODO(rsc): Can we use a single global basep for all calls?
-	var base = (*uintptr)(unsafe.Pointer(new(uint64)))
-	return Getdirentries(fd, buf, base)
-}
-
-// Wait status is 7 bits at bottom, either 0 (exited),
-// 0x7F (stopped), or a signal number that caused an exit.
-// The 0x80 bit is whether there was a core dump.
-// An extra number (exit code, signal causing a stop)
-// is in the high bits.
-
-type WaitStatus uint32
-
-const (
-	mask  = 0x7F
-	core  = 0x80
-	shift = 8
-
-	exited  = 0
-	stopped = 0x7F
-)
-
-func (w WaitStatus) Exited() bool { return w&mask == exited }
-
-func (w WaitStatus) ExitStatus() int {
-	if w&mask != exited {
-		return -1
-	}
-	return int(w >> shift)
-}
-
-func (w WaitStatus) Signaled() bool { return w&mask != stopped && w&mask != 0 }
-
-func (w WaitStatus) Signal() Signal {
-	sig := Signal(w & mask)
-	if sig == stopped || sig == 0 {
-		return -1
-	}
-	return sig
-}
-
-func (w WaitStatus) CoreDump() bool { return w.Signaled() && w&core != 0 }
-
-func (w WaitStatus) Stopped() bool { return w&mask == stopped && Signal(w>>shift) != SIGSTOP }
-
-func (w WaitStatus) Continued() bool { return w&mask == stopped && Signal(w>>shift) == SIGSTOP }
-
-func (w WaitStatus) StopSignal() Signal {
-	if !w.Stopped() {
-		return -1
-	}
-	return Signal(w>>shift) & 0xFF
-}
-
-func (w WaitStatus) TrapCause() int { return -1 }
-
-//sys	wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error)
-
-func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {
-	var status _C_int
-	wpid, err = wait4(pid, &status, options, rusage)
-	if wstatus != nil {
-		*wstatus = WaitStatus(status)
-	}
-	return
-}
-
-//sys	accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error)
-//sys	bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
-//sys	connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
-//sysnb	socket(domain int, typ int, proto int) (fd int, err error)
-//sys	getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error)
-//sys	setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error)
-//sysnb	getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)
-//sysnb	getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)
-//sys	Shutdown(s int, how int) (err error)
-
-func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) {
-	if sa.Port < 0 || sa.Port > 0xFFFF {
-		return nil, 0, EINVAL
-	}
-	sa.raw.Len = SizeofSockaddrInet4
-	sa.raw.Family = AF_INET
-	p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
-	p[0] = byte(sa.Port >> 8)
-	p[1] = byte(sa.Port)
-	for i := 0; i < len(sa.Addr); i++ {
-		sa.raw.Addr[i] = sa.Addr[i]
-	}
-	return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil
-}
-
-func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, _Socklen, error) {
-	if sa.Port < 0 || sa.Port > 0xFFFF {
-		return nil, 0, EINVAL
-	}
-	sa.raw.Len = SizeofSockaddrInet6
-	sa.raw.Family = AF_INET6
-	p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
-	p[0] = byte(sa.Port >> 8)
-	p[1] = byte(sa.Port)
-	sa.raw.Scope_id = sa.ZoneId
-	for i := 0; i < len(sa.Addr); i++ {
-		sa.raw.Addr[i] = sa.Addr[i]
-	}
-	return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil
-}
-
-func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, _Socklen, error) {
-	name := sa.Name
-	n := len(name)
-	if n >= len(sa.raw.Path) || n == 0 {
-		return nil, 0, EINVAL
-	}
-	sa.raw.Len = byte(3 + n) // 2 for Family, Len; 1 for NUL
-	sa.raw.Family = AF_UNIX
-	for i := 0; i < n; i++ {
-		sa.raw.Path[i] = int8(name[i])
-	}
-	return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil
-}
-
-func (sa *SockaddrDatalink) sockaddr() (unsafe.Pointer, _Socklen, error) {
-	if sa.Index == 0 {
-		return nil, 0, EINVAL
-	}
-	sa.raw.Len = sa.Len
-	sa.raw.Family = AF_LINK
-	sa.raw.Index = sa.Index
-	sa.raw.Type = sa.Type
-	sa.raw.Nlen = sa.Nlen
-	sa.raw.Alen = sa.Alen
-	sa.raw.Slen = sa.Slen
-	for i := 0; i < len(sa.raw.Data); i++ {
-		sa.raw.Data[i] = sa.Data[i]
-	}
-	return unsafe.Pointer(&sa.raw), SizeofSockaddrDatalink, nil
-}
-
-func anyToSockaddr(rsa *RawSockaddrAny) (Sockaddr, error) {
-	switch rsa.Addr.Family {
-	case AF_LINK:
-		pp := (*RawSockaddrDatalink)(unsafe.Pointer(rsa))
-		sa := new(SockaddrDatalink)
-		sa.Len = pp.Len
-		sa.Family = pp.Family
-		sa.Index = pp.Index
-		sa.Type = pp.Type
-		sa.Nlen = pp.Nlen
-		sa.Alen = pp.Alen
-		sa.Slen = pp.Slen
-		for i := 0; i < len(sa.Data); i++ {
-			sa.Data[i] = pp.Data[i]
-		}
-		return sa, nil
-
-	case AF_UNIX:
-		pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa))
-		if pp.Len < 2 || pp.Len > SizeofSockaddrUnix {
-			return nil, EINVAL
-		}
-		sa := new(SockaddrUnix)
-
-		// Some BSDs include the trailing NUL in the length, whereas
-		// others do not. Work around this by subtracting the leading
-		// family and len. The path is then scanned to see if a NUL
-		// terminator still exists within the length.
-		n := int(pp.Len) - 2 // subtract leading Family, Len
-		for i := 0; i < n; i++ {
-			if pp.Path[i] == 0 {
-				// found early NUL; assume Len included the NUL
-				// or was overestimating.
-				n = i
-				break
-			}
-		}
-		bytes := (*[10000]byte)(unsafe.Pointer(&pp.Path[0]))[0:n]
-		sa.Name = string(bytes)
-		return sa, nil
-
-	case AF_INET:
-		pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))
-		sa := new(SockaddrInet4)
-		p := (*[2]byte)(unsafe.Pointer(&pp.Port))
-		sa.Port = int(p[0])<<8 + int(p[1])
-		for i := 0; i < len(sa.Addr); i++ {
-			sa.Addr[i] = pp.Addr[i]
-		}
-		return sa, nil
-
-	case AF_INET6:
-		pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa))
-		sa := new(SockaddrInet6)
-		p := (*[2]byte)(unsafe.Pointer(&pp.Port))
-		sa.Port = int(p[0])<<8 + int(p[1])
-		sa.ZoneId = pp.Scope_id
-		for i := 0; i < len(sa.Addr); i++ {
-			sa.Addr[i] = pp.Addr[i]
-		}
-		return sa, nil
-	}
-	return nil, EAFNOSUPPORT
-}
-
-func Accept(fd int) (nfd int, sa Sockaddr, err error) {
-	var rsa RawSockaddrAny
-	var len _Socklen = SizeofSockaddrAny
-	nfd, err = accept(fd, &rsa, &len)
-	if err != nil {
-		return
-	}
-	if runtime.GOOS == "darwin" && len == 0 {
-		// Accepted socket has no address.
-		// This is likely due to a bug in xnu kernels,
-		// where instead of ECONNABORTED error socket
-		// is accepted, but has no address.
-		Close(nfd)
-		return 0, nil, ECONNABORTED
-	}
-	sa, err = anyToSockaddr(&rsa)
-	if err != nil {
-		Close(nfd)
-		nfd = 0
-	}
-	return
-}
-
-func Getsockname(fd int) (sa Sockaddr, err error) {
-	var rsa RawSockaddrAny
-	var len _Socklen = SizeofSockaddrAny
-	if err = getsockname(fd, &rsa, &len); err != nil {
-		return
-	}
-	// TODO(jsing): DragonFly has a "bug" (see issue 3349), which should be
-	// reported upstream.
-	if runtime.GOOS == "dragonfly" && rsa.Addr.Family == AF_UNSPEC && rsa.Addr.Len == 0 {
-		rsa.Addr.Family = AF_UNIX
-		rsa.Addr.Len = SizeofSockaddrUnix
-	}
-	return anyToSockaddr(&rsa)
-}
-
-//sysnb socketpair(domain int, typ int, proto int, fd *[2]int32) (err error)
-
-func GetsockoptByte(fd, level, opt int) (value byte, err error) {
-	var n byte
-	vallen := _Socklen(1)
-	err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen)
-	return n, err
-}
-
-func GetsockoptInet4Addr(fd, level, opt int) (value [4]byte, err error) {
-	vallen := _Socklen(4)
-	err = getsockopt(fd, level, opt, unsafe.Pointer(&value[0]), &vallen)
-	return value, err
-}
-
-func GetsockoptIPMreq(fd, level, opt int) (*IPMreq, error) {
-	var value IPMreq
-	vallen := _Socklen(SizeofIPMreq)
-	err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
-	return &value, err
-}
-
-func GetsockoptIPv6Mreq(fd, level, opt int) (*IPv6Mreq, error) {
-	var value IPv6Mreq
-	vallen := _Socklen(SizeofIPv6Mreq)
-	err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
-	return &value, err
-}
-
-func GetsockoptIPv6MTUInfo(fd, level, opt int) (*IPv6MTUInfo, error) {
-	var value IPv6MTUInfo
-	vallen := _Socklen(SizeofIPv6MTUInfo)
-	err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
-	return &value, err
-}
-
-func GetsockoptICMPv6Filter(fd, level, opt int) (*ICMPv6Filter, error) {
-	var value ICMPv6Filter
-	vallen := _Socklen(SizeofICMPv6Filter)
-	err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
-	return &value, err
-}
-
-//sys   recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error)
-//sys   sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error)
-//sys	recvmsg(s int, msg *Msghdr, flags int) (n int, err error)
-
-func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) {
-	var msg Msghdr
-	var rsa RawSockaddrAny
-	msg.Name = (*byte)(unsafe.Pointer(&rsa))
-	msg.Namelen = uint32(SizeofSockaddrAny)
-	var iov Iovec
-	if len(p) > 0 {
-		iov.Base = (*byte)(unsafe.Pointer(&p[0]))
-		iov.SetLen(len(p))
-	}
-	var dummy byte
-	if len(oob) > 0 {
-		// receive at least one normal byte
-		if len(p) == 0 {
-			iov.Base = &dummy
-			iov.SetLen(1)
-		}
-		msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
-		msg.SetControllen(len(oob))
-	}
-	msg.Iov = &iov
-	msg.Iovlen = 1
-	if n, err = recvmsg(fd, &msg, flags); err != nil {
-		return
-	}
-	oobn = int(msg.Controllen)
-	recvflags = int(msg.Flags)
-	// source address is only specified if the socket is unconnected
-	if rsa.Addr.Family != AF_UNSPEC {
-		from, err = anyToSockaddr(&rsa)
-	}
-	return
-}
-
-//sys	sendmsg(s int, msg *Msghdr, flags int) (n int, err error)
-
-func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) {
-	_, err = SendmsgN(fd, p, oob, to, flags)
-	return
-}
-
-func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) {
-	var ptr unsafe.Pointer
-	var salen _Socklen
-	if to != nil {
-		ptr, salen, err = to.sockaddr()
-		if err != nil {
-			return 0, err
-		}
-	}
-	var msg Msghdr
-	msg.Name = (*byte)(unsafe.Pointer(ptr))
-	msg.Namelen = uint32(salen)
-	var iov Iovec
-	if len(p) > 0 {
-		iov.Base = (*byte)(unsafe.Pointer(&p[0]))
-		iov.SetLen(len(p))
-	}
-	var dummy byte
-	if len(oob) > 0 {
-		// send at least one normal byte
-		if len(p) == 0 {
-			iov.Base = &dummy
-			iov.SetLen(1)
-		}
-		msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
-		msg.SetControllen(len(oob))
-	}
-	msg.Iov = &iov
-	msg.Iovlen = 1
-	if n, err = sendmsg(fd, &msg, flags); err != nil {
-		return 0, err
-	}
-	if len(oob) > 0 && len(p) == 0 {
-		n = 0
-	}
-	return n, nil
-}
-
-//sys	kevent(kq int, change unsafe.Pointer, nchange int, event unsafe.Pointer, nevent int, timeout *Timespec) (n int, err error)
-
-func Kevent(kq int, changes, events []Kevent_t, timeout *Timespec) (n int, err error) {
-	var change, event unsafe.Pointer
-	if len(changes) > 0 {
-		change = unsafe.Pointer(&changes[0])
-	}
-	if len(events) > 0 {
-		event = unsafe.Pointer(&events[0])
-	}
-	return kevent(kq, change, len(changes), event, len(events), timeout)
-}
-
-//sys	sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) = SYS___SYSCTL
-
-func Sysctl(name string) (value string, err error) {
-	// Translate name to mib number.
-	mib, err := nametomib(name)
-	if err != nil {
-		return "", err
-	}
-
-	// Find size.
-	n := uintptr(0)
-	if err = sysctl(mib, nil, &n, nil, 0); err != nil {
-		return "", err
-	}
-	if n == 0 {
-		return "", nil
-	}
-
-	// Read into buffer of that size.
-	buf := make([]byte, n)
-	if err = sysctl(mib, &buf[0], &n, nil, 0); err != nil {
-		return "", err
-	}
-
-	// Throw away terminating NUL.
-	if n > 0 && buf[n-1] == '\x00' {
-		n--
-	}
-	return string(buf[0:n]), nil
-}
-
-func SysctlUint32(name string) (value uint32, err error) {
-	// Translate name to mib number.
-	mib, err := nametomib(name)
-	if err != nil {
-		return 0, err
-	}
-
-	// Read into buffer of that size.
-	n := uintptr(4)
-	buf := make([]byte, 4)
-	if err = sysctl(mib, &buf[0], &n, nil, 0); err != nil {
-		return 0, err
-	}
-	if n != 4 {
-		return 0, EIO
-	}
-	return *(*uint32)(unsafe.Pointer(&buf[0])), nil
-}
-
-//sys	utimes(path string, timeval *[2]Timeval) (err error)
-func Utimes(path string, tv []Timeval) (err error) {
-	if len(tv) != 2 {
-		return EINVAL
-	}
-	return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
-}
-
-func UtimesNano(path string, ts []Timespec) error {
-	// TODO: The BSDs can do utimensat with SYS_UTIMENSAT but it
-	// isn't supported by darwin so this uses utimes instead
-	if len(ts) != 2 {
-		return EINVAL
-	}
-	// Not as efficient as it could be because Timespec and
-	// Timeval have different types in the different OSes
-	tv := [2]Timeval{
-		NsecToTimeval(TimespecToNsec(ts[0])),
-		NsecToTimeval(TimespecToNsec(ts[1])),
-	}
-	return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
-}
-
-//sys	futimes(fd int, timeval *[2]Timeval) (err error)
-func Futimes(fd int, tv []Timeval) (err error) {
-	if len(tv) != 2 {
-		return EINVAL
-	}
-	return futimes(fd, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
-}
-
-//sys	fcntl(fd int, cmd int, arg int) (val int, err error)
-
-// TODO: wrap
-//	Acct(name nil-string) (err error)
-//	Gethostuuid(uuid *byte, timeout *Timespec) (err error)
-//	Madvise(addr *byte, len int, behav int) (err error)
-//	Mprotect(addr *byte, len int, prot int) (err error)
-//	Msync(addr *byte, len int, flags int) (err error)
-//	Ptrace(req int, pid int, addr uintptr, data int) (ret uintptr, err error)
-
-var mapper = &mmapper{
-	active: make(map[*byte][]byte),
-	mmap:   mmap,
-	munmap: munmap,
-}
-
-func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
-	return mapper.Mmap(fd, offset, length, prot, flags)
-}
-
-func Munmap(b []byte) (err error) {
-	return mapper.Munmap(b)
-}
diff --git a/src/pkg/syscall/syscall_darwin.go b/src/pkg/syscall/syscall_darwin.go
deleted file mode 100644
index 97414dc..0000000
--- a/src/pkg/syscall/syscall_darwin.go
+++ /dev/null
@@ -1,508 +0,0 @@
-// Copyright 2009,2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Darwin system calls.
-// This file is compiled as ordinary Go code,
-// but it is also input to mksyscall,
-// which parses the //sys lines and generates system call stubs.
-// Note that sometimes we use a lowercase //sys name and wrap
-// it in our own nicer implementation, either here or in
-// syscall_bsd.go or syscall_unix.go.
-
-package syscall
-
-import (
-	errorspkg "errors"
-	"unsafe"
-)
-
-const ImplementsGetwd = true
-
-func Getwd() (string, error) {
-	buf := make([]byte, 2048)
-	attrs, err := getAttrList(".", attrList{CommonAttr: attrCmnFullpath}, buf, 0)
-	if err == nil && len(attrs) == 1 && len(attrs[0]) >= 2 {
-		wd := string(attrs[0])
-		// Sanity check that it's an absolute path and ends
-		// in a null byte, which we then strip.
-		if wd[0] == '/' && wd[len(wd)-1] == 0 {
-			return wd[:len(wd)-1], nil
-		}
-	}
-	// If pkg/os/getwd.go gets ENOTSUP, it will fall back to the
-	// slow algorithm.
-	return "", ENOTSUP
-}
-
-type SockaddrDatalink struct {
-	Len    uint8
-	Family uint8
-	Index  uint16
-	Type   uint8
-	Nlen   uint8
-	Alen   uint8
-	Slen   uint8
-	Data   [12]int8
-	raw    RawSockaddrDatalink
-}
-
-// Translate "kern.hostname" to []_C_int{0,1,2,3}.
-func nametomib(name string) (mib []_C_int, err error) {
-	const siz = unsafe.Sizeof(mib[0])
-
-	// NOTE(rsc): It seems strange to set the buffer to have
-	// size CTL_MAXNAME+2 but use only CTL_MAXNAME
-	// as the size.  I don't know why the +2 is here, but the
-	// kernel uses +2 for its own implementation of this function.
-	// I am scared that if we don't include the +2 here, the kernel
-	// will silently write 2 words farther than we specify
-	// and we'll get memory corruption.
-	var buf [CTL_MAXNAME + 2]_C_int
-	n := uintptr(CTL_MAXNAME) * siz
-
-	p := (*byte)(unsafe.Pointer(&buf[0]))
-	bytes, err := ByteSliceFromString(name)
-	if err != nil {
-		return nil, err
-	}
-
-	// Magic sysctl: "setting" 0.3 to a string name
-	// lets you read back the array of integers form.
-	if err = sysctl([]_C_int{0, 3}, p, &n, &bytes[0], uintptr(len(name))); err != nil {
-		return nil, err
-	}
-	return buf[0 : n/siz], nil
-}
-
-// ParseDirent parses up to max directory entries in buf,
-// appending the names to names.  It returns the number
-// bytes consumed from buf, the number of entries added
-// to names, and the new names slice.
-func ParseDirent(buf []byte, max int, names []string) (consumed int, count int, newnames []string) {
-	origlen := len(buf)
-	for max != 0 && len(buf) > 0 {
-		dirent := (*Dirent)(unsafe.Pointer(&buf[0]))
-		if dirent.Reclen == 0 {
-			buf = nil
-			break
-		}
-		buf = buf[dirent.Reclen:]
-		if dirent.Ino == 0 { // File absent in directory.
-			continue
-		}
-		bytes := (*[10000]byte)(unsafe.Pointer(&dirent.Name[0]))
-		var name = string(bytes[0:dirent.Namlen])
-		if name == "." || name == ".." { // Useless names
-			continue
-		}
-		max--
-		count++
-		names = append(names, name)
-	}
-	return origlen - len(buf), count, names
-}
-
-//sys   ptrace(request int, pid int, addr uintptr, data uintptr) (err error)
-func PtraceAttach(pid int) (err error) { return ptrace(PT_ATTACH, pid, 0, 0) }
-func PtraceDetach(pid int) (err error) { return ptrace(PT_DETACH, pid, 0, 0) }
-
-const (
-	attrBitMapCount = 5
-	attrCmnFullpath = 0x08000000
-)
-
-type attrList struct {
-	bitmapCount uint16
-	_           uint16
-	CommonAttr  uint32
-	VolAttr     uint32
-	DirAttr     uint32
-	FileAttr    uint32
-	Forkattr    uint32
-}
-
-func getAttrList(path string, attrList attrList, attrBuf []byte, options uint) (attrs [][]byte, err error) {
-	if len(attrBuf) < 4 {
-		return nil, errorspkg.New("attrBuf too small")
-	}
-	attrList.bitmapCount = attrBitMapCount
-
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return nil, err
-	}
-
-	_, _, e1 := Syscall6(
-		SYS_GETATTRLIST,
-		uintptr(unsafe.Pointer(_p0)),
-		uintptr(unsafe.Pointer(&attrList)),
-		uintptr(unsafe.Pointer(&attrBuf[0])),
-		uintptr(len(attrBuf)),
-		uintptr(options),
-		0,
-	)
-	if e1 != 0 {
-		return nil, e1
-	}
-	size := *(*uint32)(unsafe.Pointer(&attrBuf[0]))
-
-	// dat is the section of attrBuf that contains valid data,
-	// without the 4 byte length header. All attribute offsets
-	// are relative to dat.
-	dat := attrBuf
-	if int(size) < len(attrBuf) {
-		dat = dat[:size]
-	}
-	dat = dat[4:] // remove length prefix
-
-	for i := uint32(0); int(i) < len(dat); {
-		header := dat[i:]
-		if len(header) < 8 {
-			return attrs, errorspkg.New("truncated attribute header")
-		}
-		datOff := *(*int32)(unsafe.Pointer(&header[0]))
-		attrLen := *(*uint32)(unsafe.Pointer(&header[4]))
-		if datOff < 0 || uint32(datOff)+attrLen > uint32(len(dat)) {
-			return attrs, errorspkg.New("truncated results; attrBuf too small")
-		}
-		end := uint32(datOff) + attrLen
-		attrs = append(attrs, dat[datOff:end])
-		i = end
-		if r := i % 4; r != 0 {
-			i += (4 - r)
-		}
-	}
-	return
-}
-
-//sysnb pipe() (r int, w int, err error)
-
-func Pipe(p []int) (err error) {
-	if len(p) != 2 {
-		return EINVAL
-	}
-	p[0], p[1], err = pipe()
-	return
-}
-
-func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
-	var _p0 unsafe.Pointer
-	var bufsize uintptr
-	if len(buf) > 0 {
-		_p0 = unsafe.Pointer(&buf[0])
-		bufsize = unsafe.Sizeof(Statfs_t{}) * uintptr(len(buf))
-	}
-	r0, _, e1 := Syscall(SYS_GETFSSTAT64, uintptr(_p0), bufsize, uintptr(flags))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-/*
- * Wrapped
- */
-
-//sys	kill(pid int, signum int, posix int) (err error)
-
-func Kill(pid int, signum Signal) (err error) { return kill(pid, int(signum), 1) }
-
-/*
- * Exposed directly
- */
-//sys	Access(path string, mode uint32) (err error)
-//sys	Adjtime(delta *Timeval, olddelta *Timeval) (err error)
-//sys	Chdir(path string) (err error)
-//sys	Chflags(path string, flags int) (err error)
-//sys	Chmod(path string, mode uint32) (err error)
-//sys	Chown(path string, uid int, gid int) (err error)
-//sys	Chroot(path string) (err error)
-//sys	Close(fd int) (err error)
-//sysnb	Dup(fd int) (nfd int, err error)
-//sysnb	Dup2(from int, to int) (err error)
-//sys	Exchangedata(path1 string, path2 string, options int) (err error)
-//sys	Exit(code int)
-//sys	Fchdir(fd int) (err error)
-//sys	Fchflags(fd int, flags int) (err error)
-//sys	Fchmod(fd int, mode uint32) (err error)
-//sys	Fchown(fd int, uid int, gid int) (err error)
-//sys	Flock(fd int, how int) (err error)
-//sys	Fpathconf(fd int, name int) (val int, err error)
-//sys	Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64
-//sys	Fstatfs(fd int, stat *Statfs_t) (err error) = SYS_FSTATFS64
-//sys	Fsync(fd int) (err error)
-//sys	Ftruncate(fd int, length int64) (err error)
-//sys	Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) = SYS_GETDIRENTRIES64
-//sys	Getdtablesize() (size int)
-//sysnb	Getegid() (egid int)
-//sysnb	Geteuid() (uid int)
-//sysnb	Getgid() (gid int)
-//sysnb	Getpgid(pid int) (pgid int, err error)
-//sysnb	Getpgrp() (pgrp int)
-//sysnb	Getpid() (pid int)
-//sysnb	Getppid() (ppid int)
-//sys	Getpriority(which int, who int) (prio int, err error)
-//sysnb	Getrlimit(which int, lim *Rlimit) (err error)
-//sysnb	Getrusage(who int, rusage *Rusage) (err error)
-//sysnb	Getsid(pid int) (sid int, err error)
-//sysnb	Getuid() (uid int)
-//sysnb	Issetugid() (tainted bool)
-//sys	Kqueue() (fd int, err error)
-//sys	Lchown(path string, uid int, gid int) (err error)
-//sys	Link(path string, link string) (err error)
-//sys	Listen(s int, backlog int) (err error)
-//sys	Lstat(path string, stat *Stat_t) (err error) = SYS_LSTAT64
-//sys	Mkdir(path string, mode uint32) (err error)
-//sys	Mkfifo(path string, mode uint32) (err error)
-//sys	Mknod(path string, mode uint32, dev int) (err error)
-//sys	Mlock(b []byte) (err error)
-//sys	Mlockall(flags int) (err error)
-//sys	Mprotect(b []byte, prot int) (err error)
-//sys	Munlock(b []byte) (err error)
-//sys	Munlockall() (err error)
-//sys	Open(path string, mode int, perm uint32) (fd int, err error)
-//sys	Pathconf(path string, name int) (val int, err error)
-//sys	Pread(fd int, p []byte, offset int64) (n int, err error)
-//sys	Pwrite(fd int, p []byte, offset int64) (n int, err error)
-//sys	read(fd int, p []byte) (n int, err error)
-//sys	Readlink(path string, buf []byte) (n int, err error)
-//sys	Rename(from string, to string) (err error)
-//sys	Revoke(path string) (err error)
-//sys	Rmdir(path string) (err error)
-//sys	Seek(fd int, offset int64, whence int) (newoffset int64, err error) = SYS_LSEEK
-//sys	Select(n int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (err error)
-//sys	Setegid(egid int) (err error)
-//sysnb	Seteuid(euid int) (err error)
-//sysnb	Setgid(gid int) (err error)
-//sys	Setlogin(name string) (err error)
-//sysnb	Setpgid(pid int, pgid int) (err error)
-//sys	Setpriority(which int, who int, prio int) (err error)
-//sys	Setprivexec(flag int) (err error)
-//sysnb	Setregid(rgid int, egid int) (err error)
-//sysnb	Setreuid(ruid int, euid int) (err error)
-//sysnb	Setrlimit(which int, lim *Rlimit) (err error)
-//sysnb	Setsid() (pid int, err error)
-//sysnb	Settimeofday(tp *Timeval) (err error)
-//sysnb	Setuid(uid int) (err error)
-//sys	Stat(path string, stat *Stat_t) (err error) = SYS_STAT64
-//sys	Statfs(path string, stat *Statfs_t) (err error) = SYS_STATFS64
-//sys	Symlink(path string, link string) (err error)
-//sys	Sync() (err error)
-//sys	Truncate(path string, length int64) (err error)
-//sys	Umask(newmask int) (oldmask int)
-//sys	Undelete(path string) (err error)
-//sys	Unlink(path string) (err error)
-//sys	Unmount(path string, flags int) (err error)
-//sys	write(fd int, p []byte) (n int, err error)
-//sys   mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error)
-//sys   munmap(addr uintptr, length uintptr) (err error)
-//sys	readlen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_READ
-//sys	writelen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_WRITE
-
-/*
- * Unimplemented
- */
-// Profil
-// Sigaction
-// Sigprocmask
-// Getlogin
-// Sigpending
-// Sigaltstack
-// Ioctl
-// Reboot
-// Execve
-// Vfork
-// Sbrk
-// Sstk
-// Ovadvise
-// Mincore
-// Setitimer
-// Swapon
-// Select
-// Sigsuspend
-// Readv
-// Writev
-// Nfssvc
-// Getfh
-// Quotactl
-// Mount
-// Csops
-// Waitid
-// Add_profil
-// Kdebug_trace
-// Sigreturn
-// Mmap
-// Mlock
-// Munlock
-// Atsocket
-// Kqueue_from_portset_np
-// Kqueue_portset
-// Getattrlist
-// Setattrlist
-// Getdirentriesattr
-// Searchfs
-// Delete
-// Copyfile
-// Poll
-// Watchevent
-// Waitevent
-// Modwatch
-// Getxattr
-// Fgetxattr
-// Setxattr
-// Fsetxattr
-// Removexattr
-// Fremovexattr
-// Listxattr
-// Flistxattr
-// Fsctl
-// Initgroups
-// Posix_spawn
-// Nfsclnt
-// Fhopen
-// Minherit
-// Semsys
-// Msgsys
-// Shmsys
-// Semctl
-// Semget
-// Semop
-// Msgctl
-// Msgget
-// Msgsnd
-// Msgrcv
-// Shmat
-// Shmctl
-// Shmdt
-// Shmget
-// Shm_open
-// Shm_unlink
-// Sem_open
-// Sem_close
-// Sem_unlink
-// Sem_wait
-// Sem_trywait
-// Sem_post
-// Sem_getvalue
-// Sem_init
-// Sem_destroy
-// Open_extended
-// Umask_extended
-// Stat_extended
-// Lstat_extended
-// Fstat_extended
-// Chmod_extended
-// Fchmod_extended
-// Access_extended
-// Settid
-// Gettid
-// Setsgroups
-// Getsgroups
-// Setwgroups
-// Getwgroups
-// Mkfifo_extended
-// Mkdir_extended
-// Identitysvc
-// Shared_region_check_np
-// Shared_region_map_np
-// __pthread_mutex_destroy
-// __pthread_mutex_init
-// __pthread_mutex_lock
-// __pthread_mutex_trylock
-// __pthread_mutex_unlock
-// __pthread_cond_init
-// __pthread_cond_destroy
-// __pthread_cond_broadcast
-// __pthread_cond_signal
-// Setsid_with_pid
-// __pthread_cond_timedwait
-// Aio_fsync
-// Aio_return
-// Aio_suspend
-// Aio_cancel
-// Aio_error
-// Aio_read
-// Aio_write
-// Lio_listio
-// __pthread_cond_wait
-// Iopolicysys
-// Mlockall
-// Munlockall
-// __pthread_kill
-// __pthread_sigmask
-// __sigwait
-// __disable_threadsignal
-// __pthread_markcancel
-// __pthread_canceled
-// __semwait_signal
-// Proc_info
-// sendfile
-// Stat64_extended
-// Lstat64_extended
-// Fstat64_extended
-// __pthread_chdir
-// __pthread_fchdir
-// Audit
-// Auditon
-// Getauid
-// Setauid
-// Getaudit
-// Setaudit
-// Getaudit_addr
-// Setaudit_addr
-// Auditctl
-// Bsdthread_create
-// Bsdthread_terminate
-// Stack_snapshot
-// Bsdthread_register
-// Workq_open
-// Workq_ops
-// __mac_execve
-// __mac_syscall
-// __mac_get_file
-// __mac_set_file
-// __mac_get_link
-// __mac_set_link
-// __mac_get_proc
-// __mac_set_proc
-// __mac_get_fd
-// __mac_set_fd
-// __mac_get_pid
-// __mac_get_lcid
-// __mac_get_lctx
-// __mac_set_lctx
-// Setlcid
-// Read_nocancel
-// Write_nocancel
-// Open_nocancel
-// Close_nocancel
-// Wait4_nocancel
-// Recvmsg_nocancel
-// Sendmsg_nocancel
-// Recvfrom_nocancel
-// Accept_nocancel
-// Msync_nocancel
-// Fcntl_nocancel
-// Select_nocancel
-// Fsync_nocancel
-// Connect_nocancel
-// Sigsuspend_nocancel
-// Readv_nocancel
-// Writev_nocancel
-// Sendto_nocancel
-// Pread_nocancel
-// Pwrite_nocancel
-// Waitid_nocancel
-// Poll_nocancel
-// Msgsnd_nocancel
-// Msgrcv_nocancel
-// Sem_wait_nocancel
-// Aio_suspend_nocancel
-// __sigwait_nocancel
-// __semwait_signal_nocancel
-// __mac_mount
-// __mac_get_mount
-// __mac_getfsstat
diff --git a/src/pkg/syscall/syscall_linux.go b/src/pkg/syscall/syscall_linux.go
deleted file mode 100644
index fa0d7ea..0000000
--- a/src/pkg/syscall/syscall_linux.go
+++ /dev/null
@@ -1,1025 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Linux system calls.
-// This file is compiled as ordinary Go code,
-// but it is also input to mksyscall,
-// which parses the //sys lines and generates system call stubs.
-// Note that sometimes we use a lowercase //sys name and
-// wrap it in our own nicer implementation.
-
-package syscall
-
-import "unsafe"
-
-/*
- * Wrapped
- */
-
-//sys	open(path string, mode int, perm uint32) (fd int, err error)
-
-func Open(path string, mode int, perm uint32) (fd int, err error) {
-	return open(path, mode|O_LARGEFILE, perm)
-}
-
-//sys	openat(dirfd int, path string, flags int, mode uint32) (fd int, err error)
-
-func Openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) {
-	return openat(dirfd, path, flags|O_LARGEFILE, mode)
-}
-
-//sysnb	pipe(p *[2]_C_int) (err error)
-
-func Pipe(p []int) (err error) {
-	if len(p) != 2 {
-		return EINVAL
-	}
-	var pp [2]_C_int
-	err = pipe(&pp)
-	p[0] = int(pp[0])
-	p[1] = int(pp[1])
-	return
-}
-
-//sysnb pipe2(p *[2]_C_int, flags int) (err error)
-
-func Pipe2(p []int, flags int) (err error) {
-	if len(p) != 2 {
-		return EINVAL
-	}
-	var pp [2]_C_int
-	err = pipe2(&pp, flags)
-	p[0] = int(pp[0])
-	p[1] = int(pp[1])
-	return
-}
-
-//sys	utimes(path string, times *[2]Timeval) (err error)
-
-func Utimes(path string, tv []Timeval) (err error) {
-	if len(tv) != 2 {
-		return EINVAL
-	}
-	return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
-}
-
-//sys	utimensat(dirfd int, path string, times *[2]Timespec) (err error)
-
-func UtimesNano(path string, ts []Timespec) (err error) {
-	if len(ts) != 2 {
-		return EINVAL
-	}
-	err = utimensat(_AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])))
-	if err != ENOSYS {
-		return err
-	}
-	// If the utimensat syscall isn't available (utimensat was added to Linux
-	// in 2.6.22, Released, 8 July 2007) then fall back to utimes
-	var tv [2]Timeval
-	for i := 0; i < 2; i++ {
-		tv[i].Sec = ts[i].Sec
-		tv[i].Usec = ts[i].Nsec / 1000
-	}
-	return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
-}
-
-//sys	futimesat(dirfd int, path *byte, times *[2]Timeval) (err error)
-
-func Futimesat(dirfd int, path string, tv []Timeval) (err error) {
-	if len(tv) != 2 {
-		return EINVAL
-	}
-	pathp, err := BytePtrFromString(path)
-	if err != nil {
-		return err
-	}
-	return futimesat(dirfd, pathp, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
-}
-
-func Futimes(fd int, tv []Timeval) (err error) {
-	// Believe it or not, this is the best we can do on Linux
-	// (and is what glibc does).
-	return Utimes("/proc/self/fd/"+itoa(fd), tv)
-}
-
-const ImplementsGetwd = true
-
-//sys	Getcwd(buf []byte) (n int, err error)
-
-func Getwd() (wd string, err error) {
-	var buf [PathMax]byte
-	n, err := Getcwd(buf[0:])
-	if err != nil {
-		return "", err
-	}
-	// Getcwd returns the number of bytes written to buf, including the NUL.
-	if n < 1 || n > len(buf) || buf[n-1] != 0 {
-		return "", EINVAL
-	}
-	return string(buf[0 : n-1]), nil
-}
-
-func Getgroups() (gids []int, err error) {
-	n, err := getgroups(0, nil)
-	if err != nil {
-		return nil, err
-	}
-	if n == 0 {
-		return nil, nil
-	}
-
-	// Sanity check group count.  Max is 1<<16 on Linux.
-	if n < 0 || n > 1<<20 {
-		return nil, EINVAL
-	}
-
-	a := make([]_Gid_t, n)
-	n, err = getgroups(n, &a[0])
-	if err != nil {
-		return nil, err
-	}
-	gids = make([]int, n)
-	for i, v := range a[0:n] {
-		gids[i] = int(v)
-	}
-	return
-}
-
-func Setgroups(gids []int) (err error) {
-	if len(gids) == 0 {
-		return setgroups(0, nil)
-	}
-
-	a := make([]_Gid_t, len(gids))
-	for i, v := range gids {
-		a[i] = _Gid_t(v)
-	}
-	return setgroups(len(a), &a[0])
-}
-
-type WaitStatus uint32
-
-// Wait status is 7 bits at bottom, either 0 (exited),
-// 0x7F (stopped), or a signal number that caused an exit.
-// The 0x80 bit is whether there was a core dump.
-// An extra number (exit code, signal causing a stop)
-// is in the high bits.  At least that's the idea.
-// There are various irregularities.  For example, the
-// "continued" status is 0xFFFF, distinguishing itself
-// from stopped via the core dump bit.
-
-const (
-	mask    = 0x7F
-	core    = 0x80
-	exited  = 0x00
-	stopped = 0x7F
-	shift   = 8
-)
-
-func (w WaitStatus) Exited() bool { return w&mask == exited }
-
-func (w WaitStatus) Signaled() bool { return w&mask != stopped && w&mask != exited }
-
-func (w WaitStatus) Stopped() bool { return w&0xFF == stopped }
-
-func (w WaitStatus) Continued() bool { return w == 0xFFFF }
-
-func (w WaitStatus) CoreDump() bool { return w.Signaled() && w&core != 0 }
-
-func (w WaitStatus) ExitStatus() int {
-	if !w.Exited() {
-		return -1
-	}
-	return int(w>>shift) & 0xFF
-}
-
-func (w WaitStatus) Signal() Signal {
-	if !w.Signaled() {
-		return -1
-	}
-	return Signal(w & mask)
-}
-
-func (w WaitStatus) StopSignal() Signal {
-	if !w.Stopped() {
-		return -1
-	}
-	return Signal(w>>shift) & 0xFF
-}
-
-func (w WaitStatus) TrapCause() int {
-	if w.StopSignal() != SIGTRAP {
-		return -1
-	}
-	return int(w>>shift) >> 8
-}
-
-//sys	wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error)
-
-func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {
-	var status _C_int
-	wpid, err = wait4(pid, &status, options, rusage)
-	if wstatus != nil {
-		*wstatus = WaitStatus(status)
-	}
-	return
-}
-
-func Mkfifo(path string, mode uint32) (err error) {
-	return Mknod(path, mode|S_IFIFO, 0)
-}
-
-func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) {
-	if sa.Port < 0 || sa.Port > 0xFFFF {
-		return nil, 0, EINVAL
-	}
-	sa.raw.Family = AF_INET
-	p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
-	p[0] = byte(sa.Port >> 8)
-	p[1] = byte(sa.Port)
-	for i := 0; i < len(sa.Addr); i++ {
-		sa.raw.Addr[i] = sa.Addr[i]
-	}
-	return unsafe.Pointer(&sa.raw), SizeofSockaddrInet4, nil
-}
-
-func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, _Socklen, error) {
-	if sa.Port < 0 || sa.Port > 0xFFFF {
-		return nil, 0, EINVAL
-	}
-	sa.raw.Family = AF_INET6
-	p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
-	p[0] = byte(sa.Port >> 8)
-	p[1] = byte(sa.Port)
-	sa.raw.Scope_id = sa.ZoneId
-	for i := 0; i < len(sa.Addr); i++ {
-		sa.raw.Addr[i] = sa.Addr[i]
-	}
-	return unsafe.Pointer(&sa.raw), SizeofSockaddrInet6, nil
-}
-
-func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, _Socklen, error) {
-	name := sa.Name
-	n := len(name)
-	if n >= len(sa.raw.Path) {
-		return nil, 0, EINVAL
-	}
-	sa.raw.Family = AF_UNIX
-	for i := 0; i < n; i++ {
-		sa.raw.Path[i] = int8(name[i])
-	}
-	// length is family (uint16), name, NUL.
-	sl := _Socklen(2)
-	if n > 0 {
-		sl += _Socklen(n) + 1
-	}
-	if sa.raw.Path[0] == '@' {
-		sa.raw.Path[0] = 0
-		// Don't count trailing NUL for abstract address.
-		sl--
-	}
-
-	return unsafe.Pointer(&sa.raw), sl, nil
-}
-
-type SockaddrLinklayer struct {
-	Protocol uint16
-	Ifindex  int
-	Hatype   uint16
-	Pkttype  uint8
-	Halen    uint8
-	Addr     [8]byte
-	raw      RawSockaddrLinklayer
-}
-
-func (sa *SockaddrLinklayer) sockaddr() (unsafe.Pointer, _Socklen, error) {
-	if sa.Ifindex < 0 || sa.Ifindex > 0x7fffffff {
-		return nil, 0, EINVAL
-	}
-	sa.raw.Family = AF_PACKET
-	sa.raw.Protocol = sa.Protocol
-	sa.raw.Ifindex = int32(sa.Ifindex)
-	sa.raw.Hatype = sa.Hatype
-	sa.raw.Pkttype = sa.Pkttype
-	sa.raw.Halen = sa.Halen
-	for i := 0; i < len(sa.Addr); i++ {
-		sa.raw.Addr[i] = sa.Addr[i]
-	}
-	return unsafe.Pointer(&sa.raw), SizeofSockaddrLinklayer, nil
-}
-
-type SockaddrNetlink struct {
-	Family uint16
-	Pad    uint16
-	Pid    uint32
-	Groups uint32
-	raw    RawSockaddrNetlink
-}
-
-func (sa *SockaddrNetlink) sockaddr() (unsafe.Pointer, _Socklen, error) {
-	sa.raw.Family = AF_NETLINK
-	sa.raw.Pad = sa.Pad
-	sa.raw.Pid = sa.Pid
-	sa.raw.Groups = sa.Groups
-	return unsafe.Pointer(&sa.raw), SizeofSockaddrNetlink, nil
-}
-
-func anyToSockaddr(rsa *RawSockaddrAny) (Sockaddr, error) {
-	switch rsa.Addr.Family {
-	case AF_NETLINK:
-		pp := (*RawSockaddrNetlink)(unsafe.Pointer(rsa))
-		sa := new(SockaddrNetlink)
-		sa.Family = pp.Family
-		sa.Pad = pp.Pad
-		sa.Pid = pp.Pid
-		sa.Groups = pp.Groups
-		return sa, nil
-
-	case AF_PACKET:
-		pp := (*RawSockaddrLinklayer)(unsafe.Pointer(rsa))
-		sa := new(SockaddrLinklayer)
-		sa.Protocol = pp.Protocol
-		sa.Ifindex = int(pp.Ifindex)
-		sa.Hatype = pp.Hatype
-		sa.Pkttype = pp.Pkttype
-		sa.Halen = pp.Halen
-		for i := 0; i < len(sa.Addr); i++ {
-			sa.Addr[i] = pp.Addr[i]
-		}
-		return sa, nil
-
-	case AF_UNIX:
-		pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa))
-		sa := new(SockaddrUnix)
-		if pp.Path[0] == 0 {
-			// "Abstract" Unix domain socket.
-			// Rewrite leading NUL as @ for textual display.
-			// (This is the standard convention.)
-			// Not friendly to overwrite in place,
-			// but the callers below don't care.
-			pp.Path[0] = '@'
-		}
-
-		// Assume path ends at NUL.
-		// This is not technically the Linux semantics for
-		// abstract Unix domain sockets--they are supposed
-		// to be uninterpreted fixed-size binary blobs--but
-		// everyone uses this convention.
-		n := 0
-		for n < len(pp.Path) && pp.Path[n] != 0 {
-			n++
-		}
-		bytes := (*[10000]byte)(unsafe.Pointer(&pp.Path[0]))[0:n]
-		sa.Name = string(bytes)
-		return sa, nil
-
-	case AF_INET:
-		pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))
-		sa := new(SockaddrInet4)
-		p := (*[2]byte)(unsafe.Pointer(&pp.Port))
-		sa.Port = int(p[0])<<8 + int(p[1])
-		for i := 0; i < len(sa.Addr); i++ {
-			sa.Addr[i] = pp.Addr[i]
-		}
-		return sa, nil
-
-	case AF_INET6:
-		pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa))
-		sa := new(SockaddrInet6)
-		p := (*[2]byte)(unsafe.Pointer(&pp.Port))
-		sa.Port = int(p[0])<<8 + int(p[1])
-		sa.ZoneId = pp.Scope_id
-		for i := 0; i < len(sa.Addr); i++ {
-			sa.Addr[i] = pp.Addr[i]
-		}
-		return sa, nil
-	}
-	return nil, EAFNOSUPPORT
-}
-
-func Accept(fd int) (nfd int, sa Sockaddr, err error) {
-	var rsa RawSockaddrAny
-	var len _Socklen = SizeofSockaddrAny
-	nfd, err = accept(fd, &rsa, &len)
-	if err != nil {
-		return
-	}
-	sa, err = anyToSockaddr(&rsa)
-	if err != nil {
-		Close(nfd)
-		nfd = 0
-	}
-	return
-}
-
-func Accept4(fd int, flags int) (nfd int, sa Sockaddr, err error) {
-	var rsa RawSockaddrAny
-	var len _Socklen = SizeofSockaddrAny
-	nfd, err = accept4(fd, &rsa, &len, flags)
-	if err != nil {
-		return
-	}
-	if len > SizeofSockaddrAny {
-		panic("RawSockaddrAny too small")
-	}
-	sa, err = anyToSockaddr(&rsa)
-	if err != nil {
-		Close(nfd)
-		nfd = 0
-	}
-	return
-}
-
-func Getsockname(fd int) (sa Sockaddr, err error) {
-	var rsa RawSockaddrAny
-	var len _Socklen = SizeofSockaddrAny
-	if err = getsockname(fd, &rsa, &len); err != nil {
-		return
-	}
-	return anyToSockaddr(&rsa)
-}
-
-func GetsockoptInet4Addr(fd, level, opt int) (value [4]byte, err error) {
-	vallen := _Socklen(4)
-	err = getsockopt(fd, level, opt, unsafe.Pointer(&value[0]), &vallen)
-	return value, err
-}
-
-func GetsockoptIPMreq(fd, level, opt int) (*IPMreq, error) {
-	var value IPMreq
-	vallen := _Socklen(SizeofIPMreq)
-	err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
-	return &value, err
-}
-
-func GetsockoptIPMreqn(fd, level, opt int) (*IPMreqn, error) {
-	var value IPMreqn
-	vallen := _Socklen(SizeofIPMreqn)
-	err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
-	return &value, err
-}
-
-func GetsockoptIPv6Mreq(fd, level, opt int) (*IPv6Mreq, error) {
-	var value IPv6Mreq
-	vallen := _Socklen(SizeofIPv6Mreq)
-	err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
-	return &value, err
-}
-
-func GetsockoptIPv6MTUInfo(fd, level, opt int) (*IPv6MTUInfo, error) {
-	var value IPv6MTUInfo
-	vallen := _Socklen(SizeofIPv6MTUInfo)
-	err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
-	return &value, err
-}
-
-func GetsockoptICMPv6Filter(fd, level, opt int) (*ICMPv6Filter, error) {
-	var value ICMPv6Filter
-	vallen := _Socklen(SizeofICMPv6Filter)
-	err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
-	return &value, err
-}
-
-func GetsockoptUcred(fd, level, opt int) (*Ucred, error) {
-	var value Ucred
-	vallen := _Socklen(SizeofUcred)
-	err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
-	return &value, err
-}
-
-func SetsockoptIPMreqn(fd, level, opt int, mreq *IPMreqn) (err error) {
-	return setsockopt(fd, level, opt, unsafe.Pointer(mreq), unsafe.Sizeof(*mreq))
-}
-
-func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) {
-	var msg Msghdr
-	var rsa RawSockaddrAny
-	msg.Name = (*byte)(unsafe.Pointer(&rsa))
-	msg.Namelen = uint32(SizeofSockaddrAny)
-	var iov Iovec
-	if len(p) > 0 {
-		iov.Base = (*byte)(unsafe.Pointer(&p[0]))
-		iov.SetLen(len(p))
-	}
-	var dummy byte
-	if len(oob) > 0 {
-		// receive at least one normal byte
-		if len(p) == 0 {
-			iov.Base = &dummy
-			iov.SetLen(1)
-		}
-		msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
-		msg.SetControllen(len(oob))
-	}
-	msg.Iov = &iov
-	msg.Iovlen = 1
-	if n, err = recvmsg(fd, &msg, flags); err != nil {
-		return
-	}
-	oobn = int(msg.Controllen)
-	recvflags = int(msg.Flags)
-	// source address is only specified if the socket is unconnected
-	if rsa.Addr.Family != AF_UNSPEC {
-		from, err = anyToSockaddr(&rsa)
-	}
-	return
-}
-
-func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) {
-	_, err = SendmsgN(fd, p, oob, to, flags)
-	return
-}
-
-func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) {
-	var ptr unsafe.Pointer
-	var salen _Socklen
-	if to != nil {
-		var err error
-		ptr, salen, err = to.sockaddr()
-		if err != nil {
-			return 0, err
-		}
-	}
-	var msg Msghdr
-	msg.Name = (*byte)(unsafe.Pointer(ptr))
-	msg.Namelen = uint32(salen)
-	var iov Iovec
-	if len(p) > 0 {
-		iov.Base = (*byte)(unsafe.Pointer(&p[0]))
-		iov.SetLen(len(p))
-	}
-	var dummy byte
-	if len(oob) > 0 {
-		// send at least one normal byte
-		if len(p) == 0 {
-			iov.Base = &dummy
-			iov.SetLen(1)
-		}
-		msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
-		msg.SetControllen(len(oob))
-	}
-	msg.Iov = &iov
-	msg.Iovlen = 1
-	if n, err = sendmsg(fd, &msg, flags); err != nil {
-		return 0, err
-	}
-	if len(oob) > 0 && len(p) == 0 {
-		n = 0
-	}
-	return n, nil
-}
-
-// BindToDevice binds the socket associated with fd to device.
-func BindToDevice(fd int, device string) (err error) {
-	return SetsockoptString(fd, SOL_SOCKET, SO_BINDTODEVICE, device)
-}
-
-//sys	ptrace(request int, pid int, addr uintptr, data uintptr) (err error)
-
-func ptracePeek(req int, pid int, addr uintptr, out []byte) (count int, err error) {
-	// The peek requests are machine-size oriented, so we wrap it
-	// to retrieve arbitrary-length data.
-
-	// The ptrace syscall differs from glibc's ptrace.
-	// Peeks returns the word in *data, not as the return value.
-
-	var buf [sizeofPtr]byte
-
-	// Leading edge.  PEEKTEXT/PEEKDATA don't require aligned
-	// access (PEEKUSER warns that it might), but if we don't
-	// align our reads, we might straddle an unmapped page
-	// boundary and not get the bytes leading up to the page
-	// boundary.
-	n := 0
-	if addr%sizeofPtr != 0 {
-		err = ptrace(req, pid, addr-addr%sizeofPtr, uintptr(unsafe.Pointer(&buf[0])))
-		if err != nil {
-			return 0, err
-		}
-		n += copy(out, buf[addr%sizeofPtr:])
-		out = out[n:]
-	}
-
-	// Remainder.
-	for len(out) > 0 {
-		// We use an internal buffer to guarantee alignment.
-		// It's not documented if this is necessary, but we're paranoid.
-		err = ptrace(req, pid, addr+uintptr(n), uintptr(unsafe.Pointer(&buf[0])))
-		if err != nil {
-			return n, err
-		}
-		copied := copy(out, buf[0:])
-		n += copied
-		out = out[copied:]
-	}
-
-	return n, nil
-}
-
-func PtracePeekText(pid int, addr uintptr, out []byte) (count int, err error) {
-	return ptracePeek(PTRACE_PEEKTEXT, pid, addr, out)
-}
-
-func PtracePeekData(pid int, addr uintptr, out []byte) (count int, err error) {
-	return ptracePeek(PTRACE_PEEKDATA, pid, addr, out)
-}
-
-func ptracePoke(pokeReq int, peekReq int, pid int, addr uintptr, data []byte) (count int, err error) {
-	// As for ptracePeek, we need to align our accesses to deal
-	// with the possibility of straddling an invalid page.
-
-	// Leading edge.
-	n := 0
-	if addr%sizeofPtr != 0 {
-		var buf [sizeofPtr]byte
-		err = ptrace(peekReq, pid, addr-addr%sizeofPtr, uintptr(unsafe.Pointer(&buf[0])))
-		if err != nil {
-			return 0, err
-		}
-		n += copy(buf[addr%sizeofPtr:], data)
-		word := *((*uintptr)(unsafe.Pointer(&buf[0])))
-		err = ptrace(pokeReq, pid, addr-addr%sizeofPtr, word)
-		if err != nil {
-			return 0, err
-		}
-		data = data[n:]
-	}
-
-	// Interior.
-	for len(data) > sizeofPtr {
-		word := *((*uintptr)(unsafe.Pointer(&data[0])))
-		err = ptrace(pokeReq, pid, addr+uintptr(n), word)
-		if err != nil {
-			return n, err
-		}
-		n += sizeofPtr
-		data = data[sizeofPtr:]
-	}
-
-	// Trailing edge.
-	if len(data) > 0 {
-		var buf [sizeofPtr]byte
-		err = ptrace(peekReq, pid, addr+uintptr(n), uintptr(unsafe.Pointer(&buf[0])))
-		if err != nil {
-			return n, err
-		}
-		copy(buf[0:], data)
-		word := *((*uintptr)(unsafe.Pointer(&buf[0])))
-		err = ptrace(pokeReq, pid, addr+uintptr(n), word)
-		if err != nil {
-			return n, err
-		}
-		n += len(data)
-	}
-
-	return n, nil
-}
-
-func PtracePokeText(pid int, addr uintptr, data []byte) (count int, err error) {
-	return ptracePoke(PTRACE_POKETEXT, PTRACE_PEEKTEXT, pid, addr, data)
-}
-
-func PtracePokeData(pid int, addr uintptr, data []byte) (count int, err error) {
-	return ptracePoke(PTRACE_POKEDATA, PTRACE_PEEKDATA, pid, addr, data)
-}
-
-func PtraceGetRegs(pid int, regsout *PtraceRegs) (err error) {
-	return ptrace(PTRACE_GETREGS, pid, 0, uintptr(unsafe.Pointer(regsout)))
-}
-
-func PtraceSetRegs(pid int, regs *PtraceRegs) (err error) {
-	return ptrace(PTRACE_SETREGS, pid, 0, uintptr(unsafe.Pointer(regs)))
-}
-
-func PtraceSetOptions(pid int, options int) (err error) {
-	return ptrace(PTRACE_SETOPTIONS, pid, 0, uintptr(options))
-}
-
-func PtraceGetEventMsg(pid int) (msg uint, err error) {
-	var data _C_long
-	err = ptrace(PTRACE_GETEVENTMSG, pid, 0, uintptr(unsafe.Pointer(&data)))
-	msg = uint(data)
-	return
-}
-
-func PtraceCont(pid int, signal int) (err error) {
-	return ptrace(PTRACE_CONT, pid, 0, uintptr(signal))
-}
-
-func PtraceSyscall(pid int, signal int) (err error) {
-	return ptrace(PTRACE_SYSCALL, pid, 0, uintptr(signal))
-}
-
-func PtraceSingleStep(pid int) (err error) { return ptrace(PTRACE_SINGLESTEP, pid, 0, 0) }
-
-func PtraceAttach(pid int) (err error) { return ptrace(PTRACE_ATTACH, pid, 0, 0) }
-
-func PtraceDetach(pid int) (err error) { return ptrace(PTRACE_DETACH, pid, 0, 0) }
-
-//sys	reboot(magic1 uint, magic2 uint, cmd int, arg string) (err error)
-
-func Reboot(cmd int) (err error) {
-	return reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, cmd, "")
-}
-
-func clen(n []byte) int {
-	for i := 0; i < len(n); i++ {
-		if n[i] == 0 {
-			return i
-		}
-	}
-	return len(n)
-}
-
-func ReadDirent(fd int, buf []byte) (n int, err error) {
-	return Getdents(fd, buf)
-}
-
-func ParseDirent(buf []byte, max int, names []string) (consumed int, count int, newnames []string) {
-	origlen := len(buf)
-	count = 0
-	for max != 0 && len(buf) > 0 {
-		dirent := (*Dirent)(unsafe.Pointer(&buf[0]))
-		buf = buf[dirent.Reclen:]
-		if dirent.Ino == 0 { // File absent in directory.
-			continue
-		}
-		bytes := (*[10000]byte)(unsafe.Pointer(&dirent.Name[0]))
-		var name = string(bytes[0:clen(bytes[:])])
-		if name == "." || name == ".." { // Useless names
-			continue
-		}
-		max--
-		count++
-		names = append(names, name)
-	}
-	return origlen - len(buf), count, names
-}
-
-//sys	mount(source string, target string, fstype string, flags uintptr, data *byte) (err error)
-
-func Mount(source string, target string, fstype string, flags uintptr, data string) (err error) {
-	// Certain file systems get rather angry and EINVAL if you give
-	// them an empty string of data, rather than NULL.
-	if data == "" {
-		return mount(source, target, fstype, flags, nil)
-	}
-	datap, err := BytePtrFromString(data)
-	if err != nil {
-		return err
-	}
-	return mount(source, target, fstype, flags, datap)
-}
-
-// Sendto
-// Recvfrom
-// Socketpair
-
-/*
- * Direct access
- */
-//sys	Access(path string, mode uint32) (err error)
-//sys	Acct(path string) (err error)
-//sys	Adjtimex(buf *Timex) (state int, err error)
-//sys	Chdir(path string) (err error)
-//sys	Chmod(path string, mode uint32) (err error)
-//sys	Chroot(path string) (err error)
-//sys	Close(fd int) (err error)
-//sys	Creat(path string, mode uint32) (fd int, err error)
-//sysnb	Dup(oldfd int) (fd int, err error)
-//sysnb	Dup2(oldfd int, newfd int) (err error)
-//sysnb	Dup3(oldfd int, newfd int, flags int) (err error)
-//sysnb	EpollCreate(size int) (fd int, err error)
-//sysnb	EpollCreate1(flag int) (fd int, err error)
-//sysnb	EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error)
-//sys	EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
-//sys	Exit(code int) = SYS_EXIT_GROUP
-//sys	Faccessat(dirfd int, path string, mode uint32, flags int) (err error)
-//sys	Fallocate(fd int, mode uint32, off int64, len int64) (err error)
-//sys	Fchdir(fd int) (err error)
-//sys	Fchmod(fd int, mode uint32) (err error)
-//sys	Fchmodat(dirfd int, path string, mode uint32, flags int) (err error)
-//sys	Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error)
-//sys	fcntl(fd int, cmd int, arg int) (val int, err error)
-//sys	Fdatasync(fd int) (err error)
-//sys	Flock(fd int, how int) (err error)
-//sys	Fsync(fd int) (err error)
-//sys	Getdents(fd int, buf []byte) (n int, err error) = SYS_GETDENTS64
-//sysnb	Getpgid(pid int) (pgid int, err error)
-//sysnb	Getpgrp() (pid int)
-//sysnb	Getpid() (pid int)
-//sysnb	Getppid() (ppid int)
-//sys	Getpriority(which int, who int) (prio int, err error)
-//sysnb	Getrusage(who int, rusage *Rusage) (err error)
-//sysnb	Gettid() (tid int)
-//sys	Getxattr(path string, attr string, dest []byte) (sz int, err error)
-//sys	InotifyAddWatch(fd int, pathname string, mask uint32) (watchdesc int, err error)
-//sysnb	InotifyInit() (fd int, err error)
-//sysnb	InotifyInit1(flags int) (fd int, err error)
-//sysnb	InotifyRmWatch(fd int, watchdesc uint32) (success int, err error)
-//sysnb	Kill(pid int, sig Signal) (err error)
-//sys	Klogctl(typ int, buf []byte) (n int, err error) = SYS_SYSLOG
-//sys	Link(oldpath string, newpath string) (err error)
-//sys	Listxattr(path string, dest []byte) (sz int, err error)
-//sys	Mkdir(path string, mode uint32) (err error)
-//sys	Mkdirat(dirfd int, path string, mode uint32) (err error)
-//sys	Mknod(path string, mode uint32, dev int) (err error)
-//sys	Mknodat(dirfd int, path string, mode uint32, dev int) (err error)
-//sys	Nanosleep(time *Timespec, leftover *Timespec) (err error)
-//sys	Pause() (err error)
-//sys	PivotRoot(newroot string, putold string) (err error) = SYS_PIVOT_ROOT
-//sysnb prlimit(pid int, resource int, old *Rlimit, newlimit *Rlimit) (err error) = SYS_PRLIMIT64
-//sys	read(fd int, p []byte) (n int, err error)
-//sys	Readlink(path string, buf []byte) (n int, err error)
-//sys	Removexattr(path string, attr string) (err error)
-//sys	Rename(oldpath string, newpath string) (err error)
-//sys	Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error)
-//sys	Rmdir(path string) (err error)
-//sys	Setdomainname(p []byte) (err error)
-//sys	Sethostname(p []byte) (err error)
-//sysnb	Setpgid(pid int, pgid int) (err error)
-//sysnb	Setsid() (pid int, err error)
-//sysnb	Settimeofday(tv *Timeval) (err error)
-//sysnb	Setuid(uid int) (err error)
-//sys	Setpriority(which int, who int, prio int) (err error)
-//sys	Setxattr(path string, attr string, data []byte, flags int) (err error)
-//sys	Symlink(oldpath string, newpath string) (err error)
-//sys	Sync()
-//sysnb	Sysinfo(info *Sysinfo_t) (err error)
-//sys	Tee(rfd int, wfd int, len int, flags int) (n int64, err error)
-//sysnb	Tgkill(tgid int, tid int, sig Signal) (err error)
-//sysnb	Times(tms *Tms) (ticks uintptr, err error)
-//sysnb	Umask(mask int) (oldmask int)
-//sysnb	Uname(buf *Utsname) (err error)
-//sys	Unlink(path string) (err error)
-//sys	Unlinkat(dirfd int, path string) (err error)
-//sys	Unmount(target string, flags int) (err error) = SYS_UMOUNT2
-//sys	Unshare(flags int) (err error)
-//sys	Ustat(dev int, ubuf *Ustat_t) (err error)
-//sys	Utime(path string, buf *Utimbuf) (err error)
-//sys	write(fd int, p []byte) (n int, err error)
-//sys	exitThread(code int) (err error) = SYS_EXIT
-//sys	readlen(fd int, p *byte, np int) (n int, err error) = SYS_READ
-//sys	writelen(fd int, p *byte, np int) (n int, err error) = SYS_WRITE
-
-// mmap varies by architecture; see syscall_linux_*.go.
-//sys	munmap(addr uintptr, length uintptr) (err error)
-
-var mapper = &mmapper{
-	active: make(map[*byte][]byte),
-	mmap:   mmap,
-	munmap: munmap,
-}
-
-func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
-	return mapper.Mmap(fd, offset, length, prot, flags)
-}
-
-func Munmap(b []byte) (err error) {
-	return mapper.Munmap(b)
-}
-
-//sys	Madvise(b []byte, advice int) (err error)
-//sys	Mprotect(b []byte, prot int) (err error)
-//sys	Mlock(b []byte) (err error)
-//sys	Munlock(b []byte) (err error)
-//sys	Mlockall(flags int) (err error)
-//sys	Munlockall() (err error)
-
-/*
- * Unimplemented
- */
-// AddKey
-// AfsSyscall
-// Alarm
-// ArchPrctl
-// Brk
-// Capget
-// Capset
-// ClockGetres
-// ClockGettime
-// ClockNanosleep
-// ClockSettime
-// Clone
-// CreateModule
-// DeleteModule
-// EpollCtlOld
-// EpollPwait
-// EpollWaitOld
-// Eventfd
-// Execve
-// Fadvise64
-// Fgetxattr
-// Flistxattr
-// Fork
-// Fremovexattr
-// Fsetxattr
-// Futex
-// GetKernelSyms
-// GetMempolicy
-// GetRobustList
-// GetThreadArea
-// Getitimer
-// Getpmsg
-// IoCancel
-// IoDestroy
-// IoGetevents
-// IoSetup
-// IoSubmit
-// Ioctl
-// IoprioGet
-// IoprioSet
-// KexecLoad
-// Keyctl
-// Lgetxattr
-// Llistxattr
-// LookupDcookie
-// Lremovexattr
-// Lsetxattr
-// Mbind
-// MigratePages
-// Mincore
-// ModifyLdt
-// Mount
-// MovePages
-// Mprotect
-// MqGetsetattr
-// MqNotify
-// MqOpen
-// MqTimedreceive
-// MqTimedsend
-// MqUnlink
-// Mremap
-// Msgctl
-// Msgget
-// Msgrcv
-// Msgsnd
-// Msync
-// Newfstatat
-// Nfsservctl
-// Personality
-// Poll
-// Ppoll
-// Prctl
-// Pselect6
-// Ptrace
-// Putpmsg
-// QueryModule
-// Quotactl
-// Readahead
-// Readv
-// RemapFilePages
-// RequestKey
-// RestartSyscall
-// RtSigaction
-// RtSigpending
-// RtSigprocmask
-// RtSigqueueinfo
-// RtSigreturn
-// RtSigsuspend
-// RtSigtimedwait
-// SchedGetPriorityMax
-// SchedGetPriorityMin
-// SchedGetaffinity
-// SchedGetparam
-// SchedGetscheduler
-// SchedRrGetInterval
-// SchedSetaffinity
-// SchedSetparam
-// SchedYield
-// Security
-// Semctl
-// Semget
-// Semop
-// Semtimedop
-// SetMempolicy
-// SetRobustList
-// SetThreadArea
-// SetTidAddress
-// Shmat
-// Shmctl
-// Shmdt
-// Shmget
-// Sigaltstack
-// Signalfd
-// Swapoff
-// Swapon
-// Sysfs
-// TimerCreate
-// TimerDelete
-// TimerGetoverrun
-// TimerGettime
-// TimerSettime
-// Timerfd
-// Tkill (obsolete)
-// Tuxcall
-// Umount2
-// Uselib
-// Utimensat
-// Vfork
-// Vhangup
-// Vmsplice
-// Vserver
-// Waitid
-// _Sysctl
diff --git a/src/pkg/syscall/syscall_linux_386.go b/src/pkg/syscall/syscall_linux_386.go
deleted file mode 100644
index c491a28..0000000
--- a/src/pkg/syscall/syscall_linux_386.go
+++ /dev/null
@@ -1,356 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// TODO(rsc): Rewrite all nn(SP) references into name+(nn-8)(FP)
-// so that go vet can check that they are correct.
-
-package syscall
-
-import "unsafe"
-
-func Getpagesize() int { return 4096 }
-
-func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
-
-func NsecToTimespec(nsec int64) (ts Timespec) {
-	ts.Sec = int32(nsec / 1e9)
-	ts.Nsec = int32(nsec % 1e9)
-	return
-}
-
-func TimevalToNsec(tv Timeval) int64 { return int64(tv.Sec)*1e9 + int64(tv.Usec)*1e3 }
-
-func NsecToTimeval(nsec int64) (tv Timeval) {
-	nsec += 999 // round up to microsecond
-	tv.Sec = int32(nsec / 1e9)
-	tv.Usec = int32(nsec % 1e9 / 1e3)
-	return
-}
-
-// 64-bit file system and 32-bit uid calls
-// (386 default is 32-bit file system and 16-bit uid).
-//sys	Chown(path string, uid int, gid int) (err error) = SYS_CHOWN32
-//sys	Fchown(fd int, uid int, gid int) (err error) = SYS_FCHOWN32
-//sys	Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64
-//sys	Ftruncate(fd int, length int64) (err error) = SYS_FTRUNCATE64
-//sysnb	Getegid() (egid int) = SYS_GETEGID32
-//sysnb	Geteuid() (euid int) = SYS_GETEUID32
-//sysnb	Getgid() (gid int) = SYS_GETGID32
-//sysnb	Getuid() (uid int) = SYS_GETUID32
-//sys	Ioperm(from int, num int, on int) (err error)
-//sys	Iopl(level int) (err error)
-//sys	Lchown(path string, uid int, gid int) (err error) = SYS_LCHOWN32
-//sys	Lstat(path string, stat *Stat_t) (err error) = SYS_LSTAT64
-//sys	Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
-//sys	Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
-//sys	sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) = SYS_SENDFILE64
-//sys	Setfsgid(gid int) (err error) = SYS_SETFSGID32
-//sys	Setfsuid(uid int) (err error) = SYS_SETFSUID32
-//sysnb	Setgid(gid int) (err error) = SYS_SETGID32
-//sysnb	Setregid(rgid int, egid int) (err error) = SYS_SETREGID32
-//sysnb	Setresgid(rgid int, egid int, sgid int) (err error) = SYS_SETRESGID32
-//sysnb	Setresuid(ruid int, euid int, suid int) (err error) = SYS_SETRESUID32
-//sysnb	Setreuid(ruid int, euid int) (err error) = SYS_SETREUID32
-//sys	Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error)
-//sys	Stat(path string, stat *Stat_t) (err error) = SYS_STAT64
-//sys	SyncFileRange(fd int, off int64, n int64, flags int) (err error)
-//sys	Truncate(path string, length int64) (err error) = SYS_TRUNCATE64
-//sysnb	getgroups(n int, list *_Gid_t) (nn int, err error) = SYS_GETGROUPS32
-//sysnb	setgroups(n int, list *_Gid_t) (err error) = SYS_SETGROUPS32
-//sys	Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) = SYS__NEWSELECT
-
-//sys	mmap2(addr uintptr, length uintptr, prot int, flags int, fd int, pageOffset uintptr) (xaddr uintptr, err error)
-
-func mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) {
-	page := uintptr(offset / 4096)
-	if offset != int64(page)*4096 {
-		return 0, EINVAL
-	}
-	return mmap2(addr, length, prot, flags, fd, page)
-}
-
-type rlimit32 struct {
-	Cur uint32
-	Max uint32
-}
-
-//sysnb getrlimit(resource int, rlim *rlimit32) (err error) = SYS_GETRLIMIT
-
-const rlimInf32 = ^uint32(0)
-const rlimInf64 = ^uint64(0)
-
-func Getrlimit(resource int, rlim *Rlimit) (err error) {
-	err = prlimit(0, resource, nil, rlim)
-	if err != ENOSYS {
-		return err
-	}
-
-	rl := rlimit32{}
-	err = getrlimit(resource, &rl)
-	if err != nil {
-		return
-	}
-
-	if rl.Cur == rlimInf32 {
-		rlim.Cur = rlimInf64
-	} else {
-		rlim.Cur = uint64(rl.Cur)
-	}
-
-	if rl.Max == rlimInf32 {
-		rlim.Max = rlimInf64
-	} else {
-		rlim.Max = uint64(rl.Max)
-	}
-	return
-}
-
-//sysnb setrlimit(resource int, rlim *rlimit32) (err error) = SYS_SETRLIMIT
-
-func Setrlimit(resource int, rlim *Rlimit) (err error) {
-	err = prlimit(0, resource, rlim, nil)
-	if err != ENOSYS {
-		return err
-	}
-
-	rl := rlimit32{}
-	if rlim.Cur == rlimInf64 {
-		rl.Cur = rlimInf32
-	} else if rlim.Cur < uint64(rlimInf32) {
-		rl.Cur = uint32(rlim.Cur)
-	} else {
-		return EINVAL
-	}
-	if rlim.Max == rlimInf64 {
-		rl.Max = rlimInf32
-	} else if rlim.Max < uint64(rlimInf32) {
-		rl.Max = uint32(rlim.Max)
-	} else {
-		return EINVAL
-	}
-
-	return setrlimit(resource, &rl)
-}
-
-// Underlying system call writes to newoffset via pointer.
-// Implemented in assembly to avoid allocation.
-func seek(fd int, offset int64, whence int) (newoffset int64, err Errno)
-
-func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
-	newoffset, errno := seek(fd, offset, whence)
-	if errno != 0 {
-		return 0, errno
-	}
-	return newoffset, nil
-}
-
-// Vsyscalls on amd64.
-//sysnb	Gettimeofday(tv *Timeval) (err error)
-//sysnb	Time(t *Time_t) (tt Time_t, err error)
-
-// On x86 Linux, all the socket calls go through an extra indirection,
-// I think because the 5-register system call interface can't handle
-// the 6-argument calls like sendto and recvfrom.  Instead the
-// arguments to the underlying system call are the number below
-// and a pointer to an array of uintptr.  We hide the pointer in the
-// socketcall assembly to avoid allocation on every system call.
-
-const (
-	// see linux/net.h
-	_SOCKET      = 1
-	_BIND        = 2
-	_CONNECT     = 3
-	_LISTEN      = 4
-	_ACCEPT      = 5
-	_GETSOCKNAME = 6
-	_GETPEERNAME = 7
-	_SOCKETPAIR  = 8
-	_SEND        = 9
-	_RECV        = 10
-	_SENDTO      = 11
-	_RECVFROM    = 12
-	_SHUTDOWN    = 13
-	_SETSOCKOPT  = 14
-	_GETSOCKOPT  = 15
-	_SENDMSG     = 16
-	_RECVMSG     = 17
-	_ACCEPT4     = 18
-	_RECVMMSG    = 19
-	_SENDMMSG    = 20
-)
-
-func socketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (n int, err Errno)
-func rawsocketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (n int, err Errno)
-
-func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
-	fd, e := socketcall(_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), 0, 0, 0)
-	if e != 0 {
-		err = e
-	}
-	return
-}
-
-func accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) {
-	fd, e := socketcall(_ACCEPT4, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0)
-	if e != 0 {
-		err = e
-	}
-	return
-}
-
-func getsockname(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
-	_, e := rawsocketcall(_GETSOCKNAME, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), 0, 0, 0)
-	if e != 0 {
-		err = e
-	}
-	return
-}
-
-func getpeername(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
-	_, e := rawsocketcall(_GETPEERNAME, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), 0, 0, 0)
-	if e != 0 {
-		err = e
-	}
-	return
-}
-
-func socketpair(domain int, typ int, flags int, fd *[2]int32) (err error) {
-	_, e := rawsocketcall(_SOCKETPAIR, uintptr(domain), uintptr(typ), uintptr(flags), uintptr(unsafe.Pointer(fd)), 0, 0)
-	if e != 0 {
-		err = e
-	}
-	return
-}
-
-func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
-	_, e := socketcall(_BIND, uintptr(s), uintptr(addr), uintptr(addrlen), 0, 0, 0)
-	if e != 0 {
-		err = e
-	}
-	return
-}
-
-func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
-	_, e := socketcall(_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen), 0, 0, 0)
-	if e != 0 {
-		err = e
-	}
-	return
-}
-
-func socket(domain int, typ int, proto int) (fd int, err error) {
-	fd, e := rawsocketcall(_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto), 0, 0, 0)
-	if e != 0 {
-		err = e
-	}
-	return
-}
-
-func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) {
-	_, e := socketcall(_GETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
-	if e != 0 {
-		err = e
-	}
-	return
-}
-
-func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) {
-	_, e := socketcall(_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), vallen, 0)
-	if e != 0 {
-		err = e
-	}
-	return
-}
-
-func recvfrom(s int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) {
-	var base uintptr
-	if len(p) > 0 {
-		base = uintptr(unsafe.Pointer(&p[0]))
-	}
-	n, e := socketcall(_RECVFROM, uintptr(s), base, uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
-	if e != 0 {
-		err = e
-	}
-	return
-}
-
-func sendto(s int, p []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) {
-	var base uintptr
-	if len(p) > 0 {
-		base = uintptr(unsafe.Pointer(&p[0]))
-	}
-	_, e := socketcall(_SENDTO, uintptr(s), base, uintptr(len(p)), uintptr(flags), uintptr(to), uintptr(addrlen))
-	if e != 0 {
-		err = e
-	}
-	return
-}
-
-func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
-	n, e := socketcall(_RECVMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags), 0, 0, 0)
-	if e != 0 {
-		err = e
-	}
-	return
-}
-
-func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
-	n, e := socketcall(_SENDMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags), 0, 0, 0)
-	if e != 0 {
-		err = e
-	}
-	return
-}
-
-func Listen(s int, n int) (err error) {
-	_, e := socketcall(_LISTEN, uintptr(s), uintptr(n), 0, 0, 0, 0)
-	if e != 0 {
-		err = e
-	}
-	return
-}
-
-func Shutdown(s, how int) (err error) {
-	_, e := socketcall(_SHUTDOWN, uintptr(s), uintptr(how), 0, 0, 0, 0)
-	if e != 0 {
-		err = e
-	}
-	return
-}
-
-func Fstatfs(fd int, buf *Statfs_t) (err error) {
-	_, _, e := Syscall(SYS_FSTATFS64, uintptr(fd), unsafe.Sizeof(*buf), uintptr(unsafe.Pointer(buf)))
-	if e != 0 {
-		err = e
-	}
-	return
-}
-
-func Statfs(path string, buf *Statfs_t) (err error) {
-	pathp, err := BytePtrFromString(path)
-	if err != nil {
-		return err
-	}
-	_, _, e := Syscall(SYS_STATFS64, uintptr(unsafe.Pointer(pathp)), unsafe.Sizeof(*buf), uintptr(unsafe.Pointer(buf)))
-	if e != 0 {
-		err = e
-	}
-	return
-}
-
-func (r *PtraceRegs) PC() uint64 { return uint64(uint32(r.Eip)) }
-
-func (r *PtraceRegs) SetPC(pc uint64) { r.Eip = int32(pc) }
-
-func (iov *Iovec) SetLen(length int) {
-	iov.Len = uint32(length)
-}
-
-func (msghdr *Msghdr) SetControllen(length int) {
-	msghdr.Controllen = uint32(length)
-}
-
-func (cmsg *Cmsghdr) SetLen(length int) {
-	cmsg.Len = uint32(length)
-}
diff --git a/src/pkg/syscall/syscall_linux_amd64.go b/src/pkg/syscall/syscall_linux_amd64.go
deleted file mode 100644
index 8915ed8..0000000
--- a/src/pkg/syscall/syscall_linux_amd64.go
+++ /dev/null
@@ -1,115 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package syscall
-
-//sys	Chown(path string, uid int, gid int) (err error)
-//sys	Fchown(fd int, uid int, gid int) (err error)
-//sys	Fstat(fd int, stat *Stat_t) (err error)
-//sys	Fstatfs(fd int, buf *Statfs_t) (err error)
-//sys	Ftruncate(fd int, length int64) (err error)
-//sysnb	Getegid() (egid int)
-//sysnb	Geteuid() (euid int)
-//sysnb	Getgid() (gid int)
-//sysnb	Getrlimit(resource int, rlim *Rlimit) (err error)
-//sysnb	Getuid() (uid int)
-//sys	Ioperm(from int, num int, on int) (err error)
-//sys	Iopl(level int) (err error)
-//sys	Lchown(path string, uid int, gid int) (err error)
-//sys	Listen(s int, n int) (err error)
-//sys	Lstat(path string, stat *Stat_t) (err error)
-//sys	Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
-//sys	Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
-//sys	Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK
-//sys	Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error)
-//sys	sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
-//sys	Setfsgid(gid int) (err error)
-//sys	Setfsuid(uid int) (err error)
-//sysnb	Setgid(gid int) (err error)
-//sysnb	Setregid(rgid int, egid int) (err error)
-//sysnb	Setresgid(rgid int, egid int, sgid int) (err error)
-//sysnb	Setresuid(ruid int, euid int, suid int) (err error)
-//sysnb	Setrlimit(resource int, rlim *Rlimit) (err error)
-//sysnb	Setreuid(ruid int, euid int) (err error)
-//sys	Shutdown(fd int, how int) (err error)
-//sys	Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)
-//sys	Stat(path string, stat *Stat_t) (err error)
-//sys	Statfs(path string, buf *Statfs_t) (err error)
-//sys	SyncFileRange(fd int, off int64, n int64, flags int) (err error)
-//sys	Truncate(path string, length int64) (err error)
-//sys	accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error)
-//sys	accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error)
-//sys	bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
-//sys	connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
-//sysnb	getgroups(n int, list *_Gid_t) (nn int, err error)
-//sysnb	setgroups(n int, list *_Gid_t) (err error)
-//sys	getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error)
-//sys	setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error)
-//sysnb	socket(domain int, typ int, proto int) (fd int, err error)
-//sysnb	socketpair(domain int, typ int, proto int, fd *[2]int32) (err error)
-//sysnb	getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)
-//sysnb	getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)
-//sys	recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error)
-//sys	sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error)
-//sys	recvmsg(s int, msg *Msghdr, flags int) (n int, err error)
-//sys	sendmsg(s int, msg *Msghdr, flags int) (n int, err error)
-//sys	mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error)
-
-func Getpagesize() int { return 4096 }
-
-//go:noescape
-func gettimeofday(tv *Timeval) (err Errno)
-
-func Gettimeofday(tv *Timeval) (err error) {
-	errno := gettimeofday(tv)
-	if errno != 0 {
-		return errno
-	}
-	return nil
-}
-
-func Time(t *Time_t) (tt Time_t, err error) {
-	var tv Timeval
-	errno := gettimeofday(&tv)
-	if errno != 0 {
-		return 0, errno
-	}
-	if t != nil {
-		*t = Time_t(tv.Sec)
-	}
-	return Time_t(tv.Sec), nil
-}
-
-func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
-
-func NsecToTimespec(nsec int64) (ts Timespec) {
-	ts.Sec = nsec / 1e9
-	ts.Nsec = nsec % 1e9
-	return
-}
-
-func TimevalToNsec(tv Timeval) int64 { return int64(tv.Sec)*1e9 + int64(tv.Usec)*1e3 }
-
-func NsecToTimeval(nsec int64) (tv Timeval) {
-	nsec += 999 // round up to microsecond
-	tv.Sec = nsec / 1e9
-	tv.Usec = nsec % 1e9 / 1e3
-	return
-}
-
-func (r *PtraceRegs) PC() uint64 { return r.Rip }
-
-func (r *PtraceRegs) SetPC(pc uint64) { r.Rip = pc }
-
-func (iov *Iovec) SetLen(length int) {
-	iov.Len = uint64(length)
-}
-
-func (msghdr *Msghdr) SetControllen(length int) {
-	msghdr.Controllen = uint64(length)
-}
-
-func (cmsg *Cmsghdr) SetLen(length int) {
-	cmsg.Len = uint64(length)
-}
diff --git a/src/pkg/syscall/syscall_linux_arm.go b/src/pkg/syscall/syscall_linux_arm.go
deleted file mode 100644
index 9fe8023..0000000
--- a/src/pkg/syscall/syscall_linux_arm.go
+++ /dev/null
@@ -1,196 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package syscall
-
-import "unsafe"
-
-func Getpagesize() int { return 4096 }
-
-func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
-
-func NsecToTimespec(nsec int64) (ts Timespec) {
-	ts.Sec = int32(nsec / 1e9)
-	ts.Nsec = int32(nsec % 1e9)
-	return
-}
-
-func NsecToTimeval(nsec int64) (tv Timeval) {
-	nsec += 999 // round up to microsecond
-	tv.Sec = int32(nsec / 1e9)
-	tv.Usec = int32(nsec % 1e9 / 1e3)
-	return
-}
-
-// Underlying system call writes to newoffset via pointer.
-// Implemented in assembly to avoid allocation.
-func seek(fd int, offset int64, whence int) (newoffset int64, err Errno)
-
-func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
-	newoffset, errno := seek(fd, offset, whence)
-	if errno != 0 {
-		return 0, errno
-	}
-	return newoffset, nil
-}
-
-//sys	accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error)
-//sys	accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error)
-//sys	bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
-//sys	connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
-//sysnb	getgroups(n int, list *_Gid_t) (nn int, err error) = SYS_GETGROUPS32
-//sysnb	setgroups(n int, list *_Gid_t) (err error) = SYS_SETGROUPS32
-//sys	getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error)
-//sys	setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error)
-//sysnb	socket(domain int, typ int, proto int) (fd int, err error)
-//sysnb	getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)
-//sysnb	getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)
-//sys	recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error)
-//sys	sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error)
-//sysnb	socketpair(domain int, typ int, flags int, fd *[2]int32) (err error)
-//sys	recvmsg(s int, msg *Msghdr, flags int) (n int, err error)
-//sys	sendmsg(s int, msg *Msghdr, flags int) (n int, err error)
-
-// 64-bit file system and 32-bit uid calls
-// (16-bit uid calls are not always supported in newer kernels)
-//sys	Chown(path string, uid int, gid int) (err error) = SYS_CHOWN32
-//sys	Fchown(fd int, uid int, gid int) (err error) = SYS_FCHOWN32
-//sys	Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64
-//sysnb	Getegid() (egid int) = SYS_GETEGID32
-//sysnb	Geteuid() (euid int) = SYS_GETEUID32
-//sysnb	Getgid() (gid int) = SYS_GETGID32
-//sysnb	Getuid() (uid int) = SYS_GETUID32
-//sys	Lchown(path string, uid int, gid int) (err error) = SYS_LCHOWN32
-//sys	Listen(s int, n int) (err error)
-//sys	Lstat(path string, stat *Stat_t) (err error) = SYS_LSTAT64
-//sys	sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) = SYS_SENDFILE64
-//sys	Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) = SYS__NEWSELECT
-//sys	Setfsgid(gid int) (err error) = SYS_SETFSGID32
-//sys	Setfsuid(uid int) (err error) = SYS_SETFSUID32
-//sysnb	Setgid(gid int) (err error) = SYS_SETGID32
-//sysnb	Setregid(rgid int, egid int) (err error) = SYS_SETREGID32
-//sysnb	Setresgid(rgid int, egid int, sgid int) (err error) = SYS_SETRESGID32
-//sysnb	Setresuid(ruid int, euid int, suid int) (err error) = SYS_SETRESUID32
-//sysnb	Setreuid(ruid int, euid int) (err error) = SYS_SETREUID32
-//sys	Shutdown(fd int, how int) (err error)
-//sys	Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error)
-//sys	Stat(path string, stat *Stat_t) (err error) = SYS_STAT64
-
-// Vsyscalls on amd64.
-//sysnb	Gettimeofday(tv *Timeval) (err error)
-//sysnb	Time(t *Time_t) (tt Time_t, err error)
-
-//sys   Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
-//sys   Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
-//sys	Truncate(path string, length int64) (err error) = SYS_TRUNCATE64
-//sys	Ftruncate(fd int, length int64) (err error) = SYS_FTRUNCATE64
-
-//sys	mmap2(addr uintptr, length uintptr, prot int, flags int, fd int, pageOffset uintptr) (xaddr uintptr, err error)
-
-func Fstatfs(fd int, buf *Statfs_t) (err error) {
-	_, _, e := Syscall(SYS_FSTATFS64, uintptr(fd), unsafe.Sizeof(*buf), uintptr(unsafe.Pointer(buf)))
-	if e != 0 {
-		err = e
-	}
-	return
-}
-
-func Statfs(path string, buf *Statfs_t) (err error) {
-	pathp, err := BytePtrFromString(path)
-	if err != nil {
-		return err
-	}
-	_, _, e := Syscall(SYS_STATFS64, uintptr(unsafe.Pointer(pathp)), unsafe.Sizeof(*buf), uintptr(unsafe.Pointer(buf)))
-	if e != 0 {
-		err = e
-	}
-	return
-}
-
-func mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) {
-	page := uintptr(offset / 4096)
-	if offset != int64(page)*4096 {
-		return 0, EINVAL
-	}
-	return mmap2(addr, length, prot, flags, fd, page)
-}
-
-type rlimit32 struct {
-	Cur uint32
-	Max uint32
-}
-
-//sysnb getrlimit(resource int, rlim *rlimit32) (err error) = SYS_GETRLIMIT
-
-const rlimInf32 = ^uint32(0)
-const rlimInf64 = ^uint64(0)
-
-func Getrlimit(resource int, rlim *Rlimit) (err error) {
-	err = prlimit(0, resource, nil, rlim)
-	if err != ENOSYS {
-		return err
-	}
-
-	rl := rlimit32{}
-	err = getrlimit(resource, &rl)
-	if err != nil {
-		return
-	}
-
-	if rl.Cur == rlimInf32 {
-		rlim.Cur = rlimInf64
-	} else {
-		rlim.Cur = uint64(rl.Cur)
-	}
-
-	if rl.Max == rlimInf32 {
-		rlim.Max = rlimInf64
-	} else {
-		rlim.Max = uint64(rl.Max)
-	}
-	return
-}
-
-//sysnb setrlimit(resource int, rlim *rlimit32) (err error) = SYS_SETRLIMIT
-
-func Setrlimit(resource int, rlim *Rlimit) (err error) {
-	err = prlimit(0, resource, rlim, nil)
-	if err != ENOSYS {
-		return err
-	}
-
-	rl := rlimit32{}
-	if rlim.Cur == rlimInf64 {
-		rl.Cur = rlimInf32
-	} else if rlim.Cur < uint64(rlimInf32) {
-		rl.Cur = uint32(rlim.Cur)
-	} else {
-		return EINVAL
-	}
-	if rlim.Max == rlimInf64 {
-		rl.Max = rlimInf32
-	} else if rlim.Max < uint64(rlimInf32) {
-		rl.Max = uint32(rlim.Max)
-	} else {
-		return EINVAL
-	}
-
-	return setrlimit(resource, &rl)
-}
-
-func (r *PtraceRegs) PC() uint64 { return uint64(r.Uregs[15]) }
-
-func (r *PtraceRegs) SetPC(pc uint64) { r.Uregs[15] = uint32(pc) }
-
-func (iov *Iovec) SetLen(length int) {
-	iov.Len = uint32(length)
-}
-
-func (msghdr *Msghdr) SetControllen(length int) {
-	msghdr.Controllen = uint32(length)
-}
-
-func (cmsg *Cmsghdr) SetLen(length int) {
-	cmsg.Len = uint32(length)
-}
diff --git a/src/pkg/syscall/syscall_plan9.go b/src/pkg/syscall/syscall_plan9.go
deleted file mode 100644
index a8c3405..0000000
--- a/src/pkg/syscall/syscall_plan9.go
+++ /dev/null
@@ -1,344 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Plan 9 system calls.
-// This file is compiled as ordinary Go code,
-// but it is also input to mksyscall,
-// which parses the //sys lines and generates system call stubs.
-// Note that sometimes we use a lowercase //sys name and
-// wrap it in our own nicer implementation.
-
-package syscall
-
-import "unsafe"
-
-const ImplementsGetwd = true
-
-// ErrorString implements Error's String method by returning itself.
-type ErrorString string
-
-func (e ErrorString) Error() string { return string(e) }
-
-// NewError converts s to an ErrorString, which satisfies the Error interface.
-func NewError(s string) error { return ErrorString(s) }
-
-func (e ErrorString) Temporary() bool {
-	return e == EINTR || e == EMFILE || e.Timeout()
-}
-
-func (e ErrorString) Timeout() bool {
-	return e == EBUSY || e == ETIMEDOUT
-}
-
-// A Note is a string describing a process note.
-// It implements the os.Signal interface.
-type Note string
-
-func (n Note) Signal() {}
-
-func (n Note) String() string {
-	return string(n)
-}
-
-var (
-	Stdin  = 0
-	Stdout = 1
-	Stderr = 2
-)
-
-// For testing: clients can set this flag to force
-// creation of IPv6 sockets to return EAFNOSUPPORT.
-var SocketDisableIPv6 bool
-
-func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err ErrorString)
-func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err ErrorString)
-func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr)
-func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr)
-
-func atoi(b []byte) (n uint) {
-	n = 0
-	for i := 0; i < len(b); i++ {
-		n = n*10 + uint(b[i]-'0')
-	}
-	return
-}
-
-func cstring(s []byte) string {
-	for i := range s {
-		if s[i] == 0 {
-			return string(s[0:i])
-		}
-	}
-	return string(s)
-}
-
-func errstr() string {
-	var buf [ERRMAX]byte
-
-	RawSyscall(SYS_ERRSTR, uintptr(unsafe.Pointer(&buf[0])), uintptr(len(buf)), 0)
-
-	buf[len(buf)-1] = 0
-	return cstring(buf[:])
-}
-
-// Implemented in assembly to import from runtime.
-func exit(code int)
-
-func Exit(code int) { exit(code) }
-
-func readnum(path string) (uint, error) {
-	var b [12]byte
-
-	fd, e := Open(path, O_RDONLY)
-	if e != nil {
-		return 0, e
-	}
-	defer Close(fd)
-
-	n, e := Pread(fd, b[:], 0)
-
-	if e != nil {
-		return 0, e
-	}
-
-	m := 0
-	for ; m < n && b[m] == ' '; m++ {
-	}
-
-	return atoi(b[m : n-1]), nil
-}
-
-func Getpid() (pid int) {
-	n, _ := readnum("#c/pid")
-	return int(n)
-}
-
-func Getppid() (ppid int) {
-	n, _ := readnum("#c/ppid")
-	return int(n)
-}
-
-func Read(fd int, p []byte) (n int, err error) {
-	return Pread(fd, p, -1)
-}
-
-func Write(fd int, p []byte) (n int, err error) {
-	return Pwrite(fd, p, -1)
-}
-
-var ioSync int64
-
-func Getwd() (wd string, err error) {
-	fd, e := Open(".", O_RDONLY)
-
-	if e != nil {
-		return "", e
-	}
-	defer Close(fd)
-
-	return Fd2path(fd)
-}
-
-//sys	fd2path(fd int, buf []byte) (err error)
-func Fd2path(fd int) (path string, err error) {
-	var buf [512]byte
-
-	e := fd2path(fd, buf[:])
-	if e != nil {
-		return "", e
-	}
-	return cstring(buf[:]), nil
-}
-
-//sys	pipe(p *[2]_C_int) (err error)
-func Pipe(p []int) (err error) {
-	if len(p) != 2 {
-		return NewError("bad arg in system call")
-	}
-	var pp [2]_C_int
-	err = pipe(&pp)
-	p[0] = int(pp[0])
-	p[1] = int(pp[1])
-	return
-}
-
-// Underlying system call writes to newoffset via pointer.
-// Implemented in assembly to avoid allocation.
-func seek(placeholder uintptr, fd int, offset int64, whence int) (newoffset int64, err string)
-
-func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
-	newoffset, e := seek(0, fd, offset, whence)
-
-	if newoffset == -1 {
-		err = NewError(e)
-	}
-	return
-}
-
-func Mkdir(path string, mode uint32) (err error) {
-	fd, err := Create(path, O_RDONLY, DMDIR|mode)
-
-	if fd != -1 {
-		Close(fd)
-	}
-
-	return
-}
-
-type Waitmsg struct {
-	Pid  int
-	Time [3]uint32
-	Msg  string
-}
-
-func (w Waitmsg) Exited() bool   { return true }
-func (w Waitmsg) Signaled() bool { return false }
-
-func (w Waitmsg) ExitStatus() int {
-	if len(w.Msg) == 0 {
-		// a normal exit returns no message
-		return 0
-	}
-	return 1
-}
-
-//sys	await(s []byte) (n int, err error)
-func Await(w *Waitmsg) (err error) {
-	var buf [512]byte
-	var f [5][]byte
-
-	n, err := await(buf[:])
-
-	if err != nil || w == nil {
-		return
-	}
-
-	nf := 0
-	p := 0
-	for i := 0; i < n && nf < len(f)-1; i++ {
-		if buf[i] == ' ' {
-			f[nf] = buf[p:i]
-			p = i + 1
-			nf++
-		}
-	}
-	f[nf] = buf[p:]
-	nf++
-
-	if nf != len(f) {
-		return NewError("invalid wait message")
-	}
-	w.Pid = int(atoi(f[0]))
-	w.Time[0] = uint32(atoi(f[1]))
-	w.Time[1] = uint32(atoi(f[2]))
-	w.Time[2] = uint32(atoi(f[3]))
-	w.Msg = cstring(f[4])
-	if w.Msg == "''" {
-		// await() returns '' for no error
-		w.Msg = ""
-	}
-	return
-}
-
-func Unmount(name, old string) (err error) {
-	oldp, err := BytePtrFromString(old)
-	if err != nil {
-		return err
-	}
-	oldptr := uintptr(unsafe.Pointer(oldp))
-
-	var r0 uintptr
-	var e ErrorString
-
-	// bind(2) man page: If name is zero, everything bound or mounted upon old is unbound or unmounted.
-	if name == "" {
-		r0, _, e = Syscall(SYS_UNMOUNT, _zero, oldptr, 0)
-	} else {
-		namep, err := BytePtrFromString(name)
-		if err != nil {
-			return err
-		}
-		r0, _, e = Syscall(SYS_UNMOUNT, uintptr(unsafe.Pointer(namep)), oldptr, 0)
-	}
-
-	if int32(r0) == -1 {
-		err = e
-	}
-	return
-}
-
-func Fchdir(fd int) (err error) {
-	path, err := Fd2path(fd)
-
-	if err != nil {
-		return
-	}
-
-	return Chdir(path)
-}
-
-type Timespec struct {
-	Sec  int32
-	Nsec int32
-}
-
-type Timeval struct {
-	Sec  int32
-	Usec int32
-}
-
-func NsecToTimeval(nsec int64) (tv Timeval) {
-	nsec += 999 // round up to microsecond
-	tv.Usec = int32(nsec % 1e9 / 1e3)
-	tv.Sec = int32(nsec / 1e9)
-	return
-}
-
-func DecodeBintime(b []byte) (nsec int64, err error) {
-	if len(b) != 8 {
-		return -1, NewError("bad /dev/bintime format")
-	}
-	nsec = int64(b[0])<<56 |
-		int64(b[1])<<48 |
-		int64(b[2])<<40 |
-		int64(b[3])<<32 |
-		int64(b[4])<<24 |
-		int64(b[5])<<16 |
-		int64(b[6])<<8 |
-		int64(b[7])
-	return
-}
-
-func Gettimeofday(tv *Timeval) error {
-	nsec, e := nanotime()
-	if e != nil {
-		return e
-	}
-	*tv = NsecToTimeval(nsec)
-	return e
-}
-
-func Getegid() (egid int) { return -1 }
-func Geteuid() (euid int) { return -1 }
-func Getgid() (gid int)   { return -1 }
-func Getuid() (uid int)   { return -1 }
-
-func Getgroups() (gids []int, err error) {
-	return make([]int, 0), nil
-}
-
-//sys	Dup(oldfd int, newfd int) (fd int, err error)
-//sys	Open(path string, mode int) (fd int, err error)
-//sys	Create(path string, mode int, perm uint32) (fd int, err error)
-//sys	Remove(path string) (err error)
-//sys	Pread(fd int, p []byte, offset int64) (n int, err error)
-//sys	Pwrite(fd int, p []byte, offset int64) (n int, err error)
-//sys	Close(fd int) (err error)
-//sys	Chdir(path string) (err error)
-//sys	Bind(name string, old string, flag int) (err error)
-//sys	Mount(fd int, afd int, old string, flag int, aname string) (err error)
-//sys	Stat(path string, edir []byte) (n int, err error)
-//sys	Fstat(fd int, edir []byte) (n int, err error)
-//sys	Wstat(path string, edir []byte) (err error)
-//sys	Fwstat(fd int, edir []byte) (err error)
diff --git a/src/pkg/syscall/syscall_plan9_386.go b/src/pkg/syscall/syscall_plan9_386.go
deleted file mode 100644
index 7357e0b..0000000
--- a/src/pkg/syscall/syscall_plan9_386.go
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package syscall
-
-func Getpagesize() int { return 0x1000 }
-
-func nanotime() (nsec int64, err error) {
-	// TODO(paulzhol):
-	// avoid reopening a file descriptor for /dev/bintime on each call,
-	// use lower-level calls to avoid allocation.
-
-	var b [8]byte
-	nsec = -1
-
-	fd, err := Open("/dev/bintime", O_RDONLY)
-	if err != nil {
-		return
-	}
-	defer Close(fd)
-
-	if _, err = Pread(fd, b[:], 0); err != nil {
-		return
-	}
-
-	if nsec, err = DecodeBintime(b[:]); err != nil {
-		return -1, err
-	}
-
-	return
-}
diff --git a/src/pkg/syscall/syscall_plan9_amd64.go b/src/pkg/syscall/syscall_plan9_amd64.go
deleted file mode 100644
index 9387db3..0000000
--- a/src/pkg/syscall/syscall_plan9_amd64.go
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package syscall
-
-func Getpagesize() int { return 0x200000 }
-
-// Used by Gettimeofday, which expects
-// an error return value.
-func nanotime() (int64, error) {
-	r1, _, _ := RawSyscall(SYS_NANOTIME, 0, 0, 0)
-	return int64(r1), nil
-}
diff --git a/src/pkg/syscall/syscall_test.go b/src/pkg/syscall/syscall_test.go
deleted file mode 100644
index 2a39b54..0000000
--- a/src/pkg/syscall/syscall_test.go
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package syscall_test
-
-import (
-	"syscall"
-	"testing"
-)
-
-func testSetGetenv(t *testing.T, key, value string) {
-	err := syscall.Setenv(key, value)
-	if err != nil {
-		t.Fatalf("Setenv failed to set %q: %v", value, err)
-	}
-	newvalue, found := syscall.Getenv(key)
-	if !found {
-		t.Fatalf("Getenv failed to find %v variable (want value %q)", key, value)
-	}
-	if newvalue != value {
-		t.Fatalf("Getenv(%v) = %q; want %q", key, newvalue, value)
-	}
-}
-
-func TestEnv(t *testing.T) {
-	testSetGetenv(t, "TESTENV", "AVALUE")
-	// make sure TESTENV gets set to "", not deleted
-	testSetGetenv(t, "TESTENV", "")
-}
diff --git a/src/pkg/syscall/syscall_unix.go b/src/pkg/syscall/syscall_unix.go
deleted file mode 100644
index b288915..0000000
--- a/src/pkg/syscall/syscall_unix.go
+++ /dev/null
@@ -1,299 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build darwin dragonfly freebsd linux netbsd openbsd solaris
-
-package syscall
-
-import (
-	"runtime"
-	"sync"
-	"unsafe"
-)
-
-var (
-	Stdin  = 0
-	Stdout = 1
-	Stderr = 2
-)
-
-const (
-	darwin64Bit    = runtime.GOOS == "darwin" && sizeofPtr == 8
-	dragonfly64Bit = runtime.GOOS == "dragonfly" && sizeofPtr == 8
-	netbsd32Bit    = runtime.GOOS == "netbsd" && sizeofPtr == 4
-)
-
-func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
-func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
-func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
-func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
-
-// Mmap manager, for use by operating system-specific implementations.
-
-type mmapper struct {
-	sync.Mutex
-	active map[*byte][]byte // active mappings; key is last byte in mapping
-	mmap   func(addr, length uintptr, prot, flags, fd int, offset int64) (uintptr, error)
-	munmap func(addr uintptr, length uintptr) error
-}
-
-func (m *mmapper) Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
-	if length <= 0 {
-		return nil, EINVAL
-	}
-
-	// Map the requested memory.
-	addr, errno := m.mmap(0, uintptr(length), prot, flags, fd, offset)
-	if errno != nil {
-		return nil, errno
-	}
-
-	// Slice memory layout
-	var sl = struct {
-		addr uintptr
-		len  int
-		cap  int
-	}{addr, length, length}
-
-	// Use unsafeto turn sl into a []byte.
-	b := *(*[]byte)(unsafe.Pointer(&sl))
-
-	// Register mapping in m and return it.
-	p := &b[cap(b)-1]
-	m.Lock()
-	defer m.Unlock()
-	m.active[p] = b
-	return b, nil
-}
-
-func (m *mmapper) Munmap(data []byte) (err error) {
-	if len(data) == 0 || len(data) != cap(data) {
-		return EINVAL
-	}
-
-	// Find the base of the mapping.
-	p := &data[cap(data)-1]
-	m.Lock()
-	defer m.Unlock()
-	b := m.active[p]
-	if b == nil || &b[0] != &data[0] {
-		return EINVAL
-	}
-
-	// Unmap the memory and update m.
-	if errno := m.munmap(uintptr(unsafe.Pointer(&b[0])), uintptr(len(b))); errno != nil {
-		return errno
-	}
-	delete(m.active, p)
-	return nil
-}
-
-// An Errno is an unsigned number describing an error condition.
-// It implements the error interface.  The zero Errno is by convention
-// a non-error, so code to convert from Errno to error should use:
-//	err = nil
-//	if errno != 0 {
-//		err = errno
-//	}
-type Errno uintptr
-
-func (e Errno) Error() string {
-	if 0 <= int(e) && int(e) < len(errors) {
-		s := errors[e]
-		if s != "" {
-			return s
-		}
-	}
-	return "errno " + itoa(int(e))
-}
-
-func (e Errno) Temporary() bool {
-	return e == EINTR || e == EMFILE || e.Timeout()
-}
-
-func (e Errno) Timeout() bool {
-	return e == EAGAIN || e == EWOULDBLOCK || e == ETIMEDOUT
-}
-
-// A Signal is a number describing a process signal.
-// It implements the os.Signal interface.
-type Signal int
-
-func (s Signal) Signal() {}
-
-func (s Signal) String() string {
-	if 0 <= s && int(s) < len(signals) {
-		str := signals[s]
-		if str != "" {
-			return str
-		}
-	}
-	return "signal " + itoa(int(s))
-}
-
-func Read(fd int, p []byte) (n int, err error) {
-	n, err = read(fd, p)
-	if raceenabled {
-		if n > 0 {
-			raceWriteRange(unsafe.Pointer(&p[0]), n)
-		}
-		if err == nil {
-			raceAcquire(unsafe.Pointer(&ioSync))
-		}
-	}
-	return
-}
-
-func Write(fd int, p []byte) (n int, err error) {
-	if raceenabled {
-		raceReleaseMerge(unsafe.Pointer(&ioSync))
-	}
-	n, err = write(fd, p)
-	if raceenabled && n > 0 {
-		raceReadRange(unsafe.Pointer(&p[0]), n)
-	}
-	return
-}
-
-// For testing: clients can set this flag to force
-// creation of IPv6 sockets to return EAFNOSUPPORT.
-var SocketDisableIPv6 bool
-
-type Sockaddr interface {
-	sockaddr() (ptr unsafe.Pointer, len _Socklen, err error) // lowercase; only we can define Sockaddrs
-}
-
-type SockaddrInet4 struct {
-	Port int
-	Addr [4]byte
-	raw  RawSockaddrInet4
-}
-
-type SockaddrInet6 struct {
-	Port   int
-	ZoneId uint32
-	Addr   [16]byte
-	raw    RawSockaddrInet6
-}
-
-type SockaddrUnix struct {
-	Name string
-	raw  RawSockaddrUnix
-}
-
-func Bind(fd int, sa Sockaddr) (err error) {
-	ptr, n, err := sa.sockaddr()
-	if err != nil {
-		return err
-	}
-	return bind(fd, ptr, n)
-}
-
-func Connect(fd int, sa Sockaddr) (err error) {
-	ptr, n, err := sa.sockaddr()
-	if err != nil {
-		return err
-	}
-	return connect(fd, ptr, n)
-}
-
-func Getpeername(fd int) (sa Sockaddr, err error) {
-	var rsa RawSockaddrAny
-	var len _Socklen = SizeofSockaddrAny
-	if err = getpeername(fd, &rsa, &len); err != nil {
-		return
-	}
-	return anyToSockaddr(&rsa)
-}
-
-func GetsockoptInt(fd, level, opt int) (value int, err error) {
-	var n int32
-	vallen := _Socklen(4)
-	err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen)
-	return int(n), err
-}
-
-func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, err error) {
-	var rsa RawSockaddrAny
-	var len _Socklen = SizeofSockaddrAny
-	if n, err = recvfrom(fd, p, flags, &rsa, &len); err != nil {
-		return
-	}
-	if rsa.Addr.Family != AF_UNSPEC {
-		from, err = anyToSockaddr(&rsa)
-	}
-	return
-}
-
-func Sendto(fd int, p []byte, flags int, to Sockaddr) (err error) {
-	ptr, n, err := to.sockaddr()
-	if err != nil {
-		return err
-	}
-	return sendto(fd, p, flags, ptr, n)
-}
-
-func SetsockoptByte(fd, level, opt int, value byte) (err error) {
-	return setsockopt(fd, level, opt, unsafe.Pointer(&value), 1)
-}
-
-func SetsockoptInt(fd, level, opt int, value int) (err error) {
-	var n = int32(value)
-	return setsockopt(fd, level, opt, unsafe.Pointer(&n), 4)
-}
-
-func SetsockoptInet4Addr(fd, level, opt int, value [4]byte) (err error) {
-	return setsockopt(fd, level, opt, unsafe.Pointer(&value[0]), 4)
-}
-
-func SetsockoptIPMreq(fd, level, opt int, mreq *IPMreq) (err error) {
-	return setsockopt(fd, level, opt, unsafe.Pointer(mreq), SizeofIPMreq)
-}
-
-func SetsockoptIPv6Mreq(fd, level, opt int, mreq *IPv6Mreq) (err error) {
-	return setsockopt(fd, level, opt, unsafe.Pointer(mreq), SizeofIPv6Mreq)
-}
-
-func SetsockoptICMPv6Filter(fd, level, opt int, filter *ICMPv6Filter) error {
-	return setsockopt(fd, level, opt, unsafe.Pointer(filter), SizeofICMPv6Filter)
-}
-
-func SetsockoptLinger(fd, level, opt int, l *Linger) (err error) {
-	return setsockopt(fd, level, opt, unsafe.Pointer(l), SizeofLinger)
-}
-
-func SetsockoptString(fd, level, opt int, s string) (err error) {
-	return setsockopt(fd, level, opt, unsafe.Pointer(&[]byte(s)[0]), uintptr(len(s)))
-}
-
-func SetsockoptTimeval(fd, level, opt int, tv *Timeval) (err error) {
-	return setsockopt(fd, level, opt, unsafe.Pointer(tv), unsafe.Sizeof(*tv))
-}
-
-func Socket(domain, typ, proto int) (fd int, err error) {
-	if domain == AF_INET6 && SocketDisableIPv6 {
-		return -1, EAFNOSUPPORT
-	}
-	fd, err = socket(domain, typ, proto)
-	return
-}
-
-func Socketpair(domain, typ, proto int) (fd [2]int, err error) {
-	var fdx [2]int32
-	err = socketpair(domain, typ, proto, &fdx)
-	if err == nil {
-		fd[0] = int(fdx[0])
-		fd[1] = int(fdx[1])
-	}
-	return
-}
-
-func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
-	if raceenabled {
-		raceReleaseMerge(unsafe.Pointer(&ioSync))
-	}
-	return sendfile(outfd, infd, offset, count)
-}
-
-var ioSync int64
diff --git a/src/pkg/syscall/syscall_windows.go b/src/pkg/syscall/syscall_windows.go
deleted file mode 100644
index f9733f6..0000000
--- a/src/pkg/syscall/syscall_windows.go
+++ /dev/null
@@ -1,936 +0,0 @@
-// Copyright 2009 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Windows system calls.
-
-package syscall
-
-import (
-	errorspkg "errors"
-	"sync"
-	"unicode/utf16"
-	"unsafe"
-)
-
-type Handle uintptr
-
-const InvalidHandle = ^Handle(0)
-
-// StringToUTF16 is deprecated. Use UTF16FromString instead.
-// If s contains a NUL byte this function panics instead of
-// returning an error.
-func StringToUTF16(s string) []uint16 {
-	a, err := UTF16FromString(s)
-	if err != nil {
-		panic("syscall: string with NUL passed to StringToUTF16")
-	}
-	return a
-}
-
-// UTF16FromString returns the UTF-16 encoding of the UTF-8 string
-// s, with a terminating NUL added. If s contains a NUL byte at any
-// location, it returns (nil, EINVAL).
-func UTF16FromString(s string) ([]uint16, error) {
-	for i := 0; i < len(s); i++ {
-		if s[i] == 0 {
-			return nil, EINVAL
-		}
-	}
-	return utf16.Encode([]rune(s + "\x00")), nil
-}
-
-// UTF16ToString returns the UTF-8 encoding of the UTF-16 sequence s,
-// with a terminating NUL removed.
-func UTF16ToString(s []uint16) string {
-	for i, v := range s {
-		if v == 0 {
-			s = s[0:i]
-			break
-		}
-	}
-	return string(utf16.Decode(s))
-}
-
-// StringToUTF16Ptr is deprecated. Use UTF16PtrFromString instead.
-// If s contains a NUL byte this function panics instead of
-// returning an error.
-func StringToUTF16Ptr(s string) *uint16 { return &StringToUTF16(s)[0] }
-
-// UTF16PtrFromString returns pointer to the UTF-16 encoding of
-// the UTF-8 string s, with a terminating NUL added. If s
-// contains a NUL byte at any location, it returns (nil, EINVAL).
-func UTF16PtrFromString(s string) (*uint16, error) {
-	a, err := UTF16FromString(s)
-	if err != nil {
-		return nil, err
-	}
-	return &a[0], nil
-}
-
-func Getpagesize() int { return 4096 }
-
-// Errno is the Windows error number.
-type Errno uintptr
-
-func langid(pri, sub uint16) uint32 { return uint32(sub)<<10 | uint32(pri) }
-
-func (e Errno) Error() string {
-	// deal with special go errors
-	idx := int(e - APPLICATION_ERROR)
-	if 0 <= idx && idx < len(errors) {
-		return errors[idx]
-	}
-	// ask windows for the remaining errors
-	var flags uint32 = FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ARGUMENT_ARRAY | FORMAT_MESSAGE_IGNORE_INSERTS
-	b := make([]uint16, 300)
-	n, err := FormatMessage(flags, 0, uint32(e), langid(LANG_ENGLISH, SUBLANG_ENGLISH_US), b, nil)
-	if err != nil {
-		n, err = FormatMessage(flags, 0, uint32(e), 0, b, nil)
-		if err != nil {
-			return "winapi error #" + itoa(int(e))
-		}
-	}
-	// trim terminating \r and \n
-	for ; n > 0 && (b[n-1] == '\n' || b[n-1] == '\r'); n-- {
-	}
-	return string(utf16.Decode(b[:n]))
-}
-
-func (e Errno) Temporary() bool {
-	return e == EINTR || e == EMFILE || e.Timeout()
-}
-
-func (e Errno) Timeout() bool {
-	return e == EAGAIN || e == EWOULDBLOCK || e == ETIMEDOUT
-}
-
-// Converts a Go function to a function pointer conforming
-// to the stdcall or cdecl calling convention.  This is useful when
-// interoperating with Windows code requiring callbacks.
-// Implemented in ../runtime/syscall_windows.goc
-func NewCallback(fn interface{}) uintptr
-func NewCallbackCDecl(fn interface{}) uintptr
-
-// windows api calls
-
-//sys	GetLastError() (lasterr error)
-//sys	LoadLibrary(libname string) (handle Handle, err error) = LoadLibraryW
-//sys	FreeLibrary(handle Handle) (err error)
-//sys	GetProcAddress(module Handle, procname string) (proc uintptr, err error)
-//sys	GetVersion() (ver uint32, err error)
-//sys	FormatMessage(flags uint32, msgsrc uint32, msgid uint32, langid uint32, buf []uint16, args *byte) (n uint32, err error) = FormatMessageW
-//sys	ExitProcess(exitcode uint32)
-//sys	CreateFile(name *uint16, access uint32, mode uint32, sa *SecurityAttributes, createmode uint32, attrs uint32, templatefile int32) (handle Handle, err error) [failretval==InvalidHandle] = CreateFileW
-//sys	ReadFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) (err error)
-//sys	WriteFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) (err error)
-//sys	SetFilePointer(handle Handle, lowoffset int32, highoffsetptr *int32, whence uint32) (newlowoffset uint32, err error) [failretval==0xffffffff]
-//sys	CloseHandle(handle Handle) (err error)
-//sys	GetStdHandle(stdhandle int) (handle Handle, err error) [failretval==InvalidHandle]
-//sys	findFirstFile1(name *uint16, data *win32finddata1) (handle Handle, err error) [failretval==InvalidHandle] = FindFirstFileW
-//sys	findNextFile1(handle Handle, data *win32finddata1) (err error) = FindNextFileW
-//sys	FindClose(handle Handle) (err error)
-//sys	GetFileInformationByHandle(handle Handle, data *ByHandleFileInformation) (err error)
-//sys	GetCurrentDirectory(buflen uint32, buf *uint16) (n uint32, err error) = GetCurrentDirectoryW
-//sys	SetCurrentDirectory(path *uint16) (err error) = SetCurrentDirectoryW
-//sys	CreateDirectory(path *uint16, sa *SecurityAttributes) (err error) = CreateDirectoryW
-//sys	RemoveDirectory(path *uint16) (err error) = RemoveDirectoryW
-//sys	DeleteFile(path *uint16) (err error) = DeleteFileW
-//sys	MoveFile(from *uint16, to *uint16) (err error) = MoveFileW
-//sys	GetComputerName(buf *uint16, n *uint32) (err error) = GetComputerNameW
-//sys	SetEndOfFile(handle Handle) (err error)
-//sys	GetSystemTimeAsFileTime(time *Filetime)
-//sys	GetTimeZoneInformation(tzi *Timezoneinformation) (rc uint32, err error) [failretval==0xffffffff]
-//sys	CreateIoCompletionPort(filehandle Handle, cphandle Handle, key uint32, threadcnt uint32) (handle Handle, err error)
-//sys	GetQueuedCompletionStatus(cphandle Handle, qty *uint32, key *uint32, overlapped **Overlapped, timeout uint32) (err error)
-//sys	PostQueuedCompletionStatus(cphandle Handle, qty uint32, key uint32, overlapped *Overlapped) (err error)
-//sys	CancelIo(s Handle) (err error)
-//sys	CancelIoEx(s Handle, o *Overlapped) (err error)
-//sys	CreateProcess(appName *uint16, commandLine *uint16, procSecurity *SecurityAttributes, threadSecurity *SecurityAttributes, inheritHandles bool, creationFlags uint32, env *uint16, currentDir *uint16, startupInfo *StartupInfo, outProcInfo *ProcessInformation) (err error) = CreateProcessW
-//sys	OpenProcess(da uint32, inheritHandle bool, pid uint32) (handle Handle, err error)
-//sys	TerminateProcess(handle Handle, exitcode uint32) (err error)
-//sys	GetExitCodeProcess(handle Handle, exitcode *uint32) (err error)
-//sys	GetStartupInfo(startupInfo *StartupInfo) (err error) = GetStartupInfoW
-//sys	GetCurrentProcess() (pseudoHandle Handle, err error)
-//sys	GetProcessTimes(handle Handle, creationTime *Filetime, exitTime *Filetime, kernelTime *Filetime, userTime *Filetime) (err error)
-//sys	DuplicateHandle(hSourceProcessHandle Handle, hSourceHandle Handle, hTargetProcessHandle Handle, lpTargetHandle *Handle, dwDesiredAccess uint32, bInheritHandle bool, dwOptions uint32) (err error)
-//sys	WaitForSingleObject(handle Handle, waitMilliseconds uint32) (event uint32, err error) [failretval==0xffffffff]
-//sys	GetTempPath(buflen uint32, buf *uint16) (n uint32, err error) = GetTempPathW
-//sys	CreatePipe(readhandle *Handle, writehandle *Handle, sa *SecurityAttributes, size uint32) (err error)
-//sys	GetFileType(filehandle Handle) (n uint32, err error)
-//sys	CryptAcquireContext(provhandle *Handle, container *uint16, provider *uint16, provtype uint32, flags uint32) (err error) = advapi32.CryptAcquireContextW
-//sys	CryptReleaseContext(provhandle Handle, flags uint32) (err error) = advapi32.CryptReleaseContext
-//sys	CryptGenRandom(provhandle Handle, buflen uint32, buf *byte) (err error) = advapi32.CryptGenRandom
-//sys	GetEnvironmentStrings() (envs *uint16, err error) [failretval==nil] = kernel32.GetEnvironmentStringsW
-//sys	FreeEnvironmentStrings(envs *uint16) (err error) = kernel32.FreeEnvironmentStringsW
-//sys	GetEnvironmentVariable(name *uint16, buffer *uint16, size uint32) (n uint32, err error) = kernel32.GetEnvironmentVariableW
-//sys	SetEnvironmentVariable(name *uint16, value *uint16) (err error) = kernel32.SetEnvironmentVariableW
-//sys	SetFileTime(handle Handle, ctime *Filetime, atime *Filetime, wtime *Filetime) (err error)
-//sys	GetFileAttributes(name *uint16) (attrs uint32, err error) [failretval==INVALID_FILE_ATTRIBUTES] = kernel32.GetFileAttributesW
-//sys	SetFileAttributes(name *uint16, attrs uint32) (err error) = kernel32.SetFileAttributesW
-//sys	GetFileAttributesEx(name *uint16, level uint32, info *byte) (err error) = kernel32.GetFileAttributesExW
-//sys	GetCommandLine() (cmd *uint16) = kernel32.GetCommandLineW
-//sys	CommandLineToArgv(cmd *uint16, argc *int32) (argv *[8192]*[8192]uint16, err error) [failretval==nil] = shell32.CommandLineToArgvW
-//sys	LocalFree(hmem Handle) (handle Handle, err error) [failretval!=0]
-//sys	SetHandleInformation(handle Handle, mask uint32, flags uint32) (err error)
-//sys	FlushFileBuffers(handle Handle) (err error)
-//sys	GetFullPathName(path *uint16, buflen uint32, buf *uint16, fname **uint16) (n uint32, err error) = kernel32.GetFullPathNameW
-//sys	GetLongPathName(path *uint16, buf *uint16, buflen uint32) (n uint32, err error) = kernel32.GetLongPathNameW
-//sys	GetShortPathName(longpath *uint16, shortpath *uint16, buflen uint32) (n uint32, err error) = kernel32.GetShortPathNameW
-//sys	CreateFileMapping(fhandle Handle, sa *SecurityAttributes, prot uint32, maxSizeHigh uint32, maxSizeLow uint32, name *uint16) (handle Handle, err error) = kernel32.CreateFileMappingW
-//sys	MapViewOfFile(handle Handle, access uint32, offsetHigh uint32, offsetLow uint32, length uintptr) (addr uintptr, err error)
-//sys	UnmapViewOfFile(addr uintptr) (err error)
-//sys	FlushViewOfFile(addr uintptr, length uintptr) (err error)
-//sys	VirtualLock(addr uintptr, length uintptr) (err error)
-//sys	VirtualUnlock(addr uintptr, length uintptr) (err error)
-//sys	TransmitFile(s Handle, handle Handle, bytesToWrite uint32, bytsPerSend uint32, overlapped *Overlapped, transmitFileBuf *TransmitFileBuffers, flags uint32) (err error) = mswsock.TransmitFile
-//sys	ReadDirectoryChanges(handle Handle, buf *byte, buflen uint32, watchSubTree bool, mask uint32, retlen *uint32, overlapped *Overlapped, completionRoutine uintptr) (err error) = kernel32.ReadDirectoryChangesW
-//sys	CertOpenSystemStore(hprov Handle, name *uint16) (store Handle, err error) = crypt32.CertOpenSystemStoreW
-//sys   CertOpenStore(storeProvider uintptr, msgAndCertEncodingType uint32, cryptProv uintptr, flags uint32, para uintptr) (handle Handle, err error) [failretval==InvalidHandle] = crypt32.CertOpenStore
-//sys	CertEnumCertificatesInStore(store Handle, prevContext *CertContext) (context *CertContext, err error) [failretval==nil] = crypt32.CertEnumCertificatesInStore
-//sys   CertAddCertificateContextToStore(store Handle, certContext *CertContext, addDisposition uint32, storeContext **CertContext) (err error) = crypt32.CertAddCertificateContextToStore
-//sys	CertCloseStore(store Handle, flags uint32) (err error) = crypt32.CertCloseStore
-//sys   CertGetCertificateChain(engine Handle, leaf *CertContext, time *Filetime, additionalStore Handle, para *CertChainPara, flags uint32, reserved uintptr, chainCtx **CertChainContext) (err error) = crypt32.CertGetCertificateChain
-//sys   CertFreeCertificateChain(ctx *CertChainContext) = crypt32.CertFreeCertificateChain
-//sys   CertCreateCertificateContext(certEncodingType uint32, certEncoded *byte, encodedLen uint32) (context *CertContext, err error) [failretval==nil] = crypt32.CertCreateCertificateContext
-//sys   CertFreeCertificateContext(ctx *CertContext) (err error) = crypt32.CertFreeCertificateContext
-//sys   CertVerifyCertificateChainPolicy(policyOID uintptr, chain *CertChainContext, para *CertChainPolicyPara, status *CertChainPolicyStatus) (err error) = crypt32.CertVerifyCertificateChainPolicy
-//sys	RegOpenKeyEx(key Handle, subkey *uint16, options uint32, desiredAccess uint32, result *Handle) (regerrno error) = advapi32.RegOpenKeyExW
-//sys	RegCloseKey(key Handle) (regerrno error) = advapi32.RegCloseKey
-//sys	RegQueryInfoKey(key Handle, class *uint16, classLen *uint32, reserved *uint32, subkeysLen *uint32, maxSubkeyLen *uint32, maxClassLen *uint32, valuesLen *uint32, maxValueNameLen *uint32, maxValueLen *uint32, saLen *uint32, lastWriteTime *Filetime) (regerrno error) = advapi32.RegQueryInfoKeyW
-//sys	RegEnumKeyEx(key Handle, index uint32, name *uint16, nameLen *uint32, reserved *uint32, class *uint16, classLen *uint32, lastWriteTime *Filetime) (regerrno error) = advapi32.RegEnumKeyExW
-//sys	RegQueryValueEx(key Handle, name *uint16, reserved *uint32, valtype *uint32, buf *byte, buflen *uint32) (regerrno error) = advapi32.RegQueryValueExW
-//sys	getCurrentProcessId() (pid uint32) = kernel32.GetCurrentProcessId
-//sys	GetConsoleMode(console Handle, mode *uint32) (err error) = kernel32.GetConsoleMode
-//sys	WriteConsole(console Handle, buf *uint16, towrite uint32, written *uint32, reserved *byte) (err error) = kernel32.WriteConsoleW
-//sys	ReadConsole(console Handle, buf *uint16, toread uint32, read *uint32, inputControl *byte) (err error) = kernel32.ReadConsoleW
-
-// syscall interface implementation for other packages
-
-func Exit(code int) { ExitProcess(uint32(code)) }
-
-func makeInheritSa() *SecurityAttributes {
-	var sa SecurityAttributes
-	sa.Length = uint32(unsafe.Sizeof(sa))
-	sa.InheritHandle = 1
-	return &sa
-}
-
-func Open(path string, mode int, perm uint32) (fd Handle, err error) {
-	if len(path) == 0 {
-		return InvalidHandle, ERROR_FILE_NOT_FOUND
-	}
-	pathp, err := UTF16PtrFromString(path)
-	if err != nil {
-		return InvalidHandle, err
-	}
-	var access uint32
-	switch mode & (O_RDONLY | O_WRONLY | O_RDWR) {
-	case O_RDONLY:
-		access = GENERIC_READ
-	case O_WRONLY:
-		access = GENERIC_WRITE
-	case O_RDWR:
-		access = GENERIC_READ | GENERIC_WRITE
-	}
-	if mode&O_CREAT != 0 {
-		access |= GENERIC_WRITE
-	}
-	if mode&O_APPEND != 0 {
-		access &^= GENERIC_WRITE
-		access |= FILE_APPEND_DATA
-	}
-	sharemode := uint32(FILE_SHARE_READ | FILE_SHARE_WRITE)
-	var sa *SecurityAttributes
-	if mode&O_CLOEXEC == 0 {
-		sa = makeInheritSa()
-	}
-	var createmode uint32
-	switch {
-	case mode&(O_CREAT|O_EXCL) == (O_CREAT | O_EXCL):
-		createmode = CREATE_NEW
-	case mode&(O_CREAT|O_TRUNC) == (O_CREAT | O_TRUNC):
-		createmode = CREATE_ALWAYS
-	case mode&O_CREAT == O_CREAT:
-		createmode = OPEN_ALWAYS
-	case mode&O_TRUNC == O_TRUNC:
-		createmode = TRUNCATE_EXISTING
-	default:
-		createmode = OPEN_EXISTING
-	}
-	h, e := CreateFile(pathp, access, sharemode, sa, createmode, FILE_ATTRIBUTE_NORMAL, 0)
-	return h, e
-}
-
-func Read(fd Handle, p []byte) (n int, err error) {
-	var done uint32
-	e := ReadFile(fd, p, &done, nil)
-	if e != nil {
-		if e == ERROR_BROKEN_PIPE {
-			// NOTE(brainman): work around ERROR_BROKEN_PIPE is returned on reading EOF from stdin
-			return 0, nil
-		}
-		return 0, e
-	}
-	if raceenabled {
-		if done > 0 {
-			raceWriteRange(unsafe.Pointer(&p[0]), int(done))
-		}
-		raceAcquire(unsafe.Pointer(&ioSync))
-	}
-	return int(done), nil
-}
-
-func Write(fd Handle, p []byte) (n int, err error) {
-	if raceenabled {
-		raceReleaseMerge(unsafe.Pointer(&ioSync))
-	}
-	var done uint32
-	e := WriteFile(fd, p, &done, nil)
-	if e != nil {
-		return 0, e
-	}
-	if raceenabled && done > 0 {
-		raceReadRange(unsafe.Pointer(&p[0]), int(done))
-	}
-	return int(done), nil
-}
-
-var ioSync int64
-
-func Seek(fd Handle, offset int64, whence int) (newoffset int64, err error) {
-	var w uint32
-	switch whence {
-	case 0:
-		w = FILE_BEGIN
-	case 1:
-		w = FILE_CURRENT
-	case 2:
-		w = FILE_END
-	}
-	hi := int32(offset >> 32)
-	lo := int32(offset)
-	// use GetFileType to check pipe, pipe can't do seek
-	ft, _ := GetFileType(fd)
-	if ft == FILE_TYPE_PIPE {
-		return 0, EPIPE
-	}
-	rlo, e := SetFilePointer(fd, lo, &hi, w)
-	if e != nil {
-		return 0, e
-	}
-	return int64(hi)<<32 + int64(rlo), nil
-}
-
-func Close(fd Handle) (err error) {
-	return CloseHandle(fd)
-}
-
-var (
-	Stdin  = getStdHandle(STD_INPUT_HANDLE)
-	Stdout = getStdHandle(STD_OUTPUT_HANDLE)
-	Stderr = getStdHandle(STD_ERROR_HANDLE)
-)
-
-func getStdHandle(h int) (fd Handle) {
-	r, _ := GetStdHandle(h)
-	CloseOnExec(r)
-	return r
-}
-
-const ImplementsGetwd = true
-
-func Getwd() (wd string, err error) {
-	b := make([]uint16, 300)
-	n, e := GetCurrentDirectory(uint32(len(b)), &b[0])
-	if e != nil {
-		return "", e
-	}
-	return string(utf16.Decode(b[0:n])), nil
-}
-
-func Chdir(path string) (err error) {
-	pathp, err := UTF16PtrFromString(path)
-	if err != nil {
-		return err
-	}
-	return SetCurrentDirectory(pathp)
-}
-
-func Mkdir(path string, mode uint32) (err error) {
-	pathp, err := UTF16PtrFromString(path)
-	if err != nil {
-		return err
-	}
-	return CreateDirectory(pathp, nil)
-}
-
-func Rmdir(path string) (err error) {
-	pathp, err := UTF16PtrFromString(path)
-	if err != nil {
-		return err
-	}
-	return RemoveDirectory(pathp)
-}
-
-func Unlink(path string) (err error) {
-	pathp, err := UTF16PtrFromString(path)
-	if err != nil {
-		return err
-	}
-	return DeleteFile(pathp)
-}
-
-func Rename(oldpath, newpath string) (err error) {
-	from, err := UTF16PtrFromString(oldpath)
-	if err != nil {
-		return err
-	}
-	to, err := UTF16PtrFromString(newpath)
-	if err != nil {
-		return err
-	}
-	return MoveFile(from, to)
-}
-
-func ComputerName() (name string, err error) {
-	var n uint32 = MAX_COMPUTERNAME_LENGTH + 1
-	b := make([]uint16, n)
-	e := GetComputerName(&b[0], &n)
-	if e != nil {
-		return "", e
-	}
-	return string(utf16.Decode(b[0:n])), nil
-}
-
-func Ftruncate(fd Handle, length int64) (err error) {
-	curoffset, e := Seek(fd, 0, 1)
-	if e != nil {
-		return e
-	}
-	defer Seek(fd, curoffset, 0)
-	_, e = Seek(fd, length, 0)
-	if e != nil {
-		return e
-	}
-	e = SetEndOfFile(fd)
-	if e != nil {
-		return e
-	}
-	return nil
-}
-
-func Gettimeofday(tv *Timeval) (err error) {
-	var ft Filetime
-	GetSystemTimeAsFileTime(&ft)
-	*tv = NsecToTimeval(ft.Nanoseconds())
-	return nil
-}
-
-func Pipe(p []Handle) (err error) {
-	if len(p) != 2 {
-		return EINVAL
-	}
-	var r, w Handle
-	e := CreatePipe(&r, &w, makeInheritSa(), 0)
-	if e != nil {
-		return e
-	}
-	p[0] = r
-	p[1] = w
-	return nil
-}
-
-func Utimes(path string, tv []Timeval) (err error) {
-	if len(tv) != 2 {
-		return EINVAL
-	}
-	pathp, e := UTF16PtrFromString(path)
-	if e != nil {
-		return e
-	}
-	h, e := CreateFile(pathp,
-		FILE_WRITE_ATTRIBUTES, FILE_SHARE_WRITE, nil,
-		OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)
-	if e != nil {
-		return e
-	}
-	defer Close(h)
-	a := NsecToFiletime(tv[0].Nanoseconds())
-	w := NsecToFiletime(tv[1].Nanoseconds())
-	return SetFileTime(h, nil, &a, &w)
-}
-
-func UtimesNano(path string, ts []Timespec) (err error) {
-	if len(ts) != 2 {
-		return EINVAL
-	}
-	pathp, e := UTF16PtrFromString(path)
-	if e != nil {
-		return e
-	}
-	h, e := CreateFile(pathp,
-		FILE_WRITE_ATTRIBUTES, FILE_SHARE_WRITE, nil,
-		OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)
-	if e != nil {
-		return e
-	}
-	defer Close(h)
-	a := NsecToFiletime(TimespecToNsec(ts[0]))
-	w := NsecToFiletime(TimespecToNsec(ts[1]))
-	return SetFileTime(h, nil, &a, &w)
-}
-
-func Fsync(fd Handle) (err error) {
-	return FlushFileBuffers(fd)
-}
-
-func Chmod(path string, mode uint32) (err error) {
-	if mode == 0 {
-		return EINVAL
-	}
-	p, e := UTF16PtrFromString(path)
-	if e != nil {
-		return e
-	}
-	attrs, e := GetFileAttributes(p)
-	if e != nil {
-		return e
-	}
-	if mode&S_IWRITE != 0 {
-		attrs &^= FILE_ATTRIBUTE_READONLY
-	} else {
-		attrs |= FILE_ATTRIBUTE_READONLY
-	}
-	return SetFileAttributes(p, attrs)
-}
-
-func LoadCancelIoEx() error {
-	return procCancelIoEx.Find()
-}
-
-func LoadSetFileCompletionNotificationModes() error {
-	return procSetFileCompletionNotificationModes.Find()
-}
-
-// net api calls
-
-const socket_error = uintptr(^uint32(0))
-
-//sys	WSAStartup(verreq uint32, data *WSAData) (sockerr error) = ws2_32.WSAStartup
-//sys	WSACleanup() (err error) [failretval==socket_error] = ws2_32.WSACleanup
-//sys	WSAIoctl(s Handle, iocc uint32, inbuf *byte, cbif uint32, outbuf *byte, cbob uint32, cbbr *uint32, overlapped *Overlapped, completionRoutine uintptr) (err error) [failretval==socket_error] = ws2_32.WSAIoctl
-//sys	socket(af int32, typ int32, protocol int32) (handle Handle, err error) [failretval==InvalidHandle] = ws2_32.socket
-//sys	Setsockopt(s Handle, level int32, optname int32, optval *byte, optlen int32) (err error) [failretval==socket_error] = ws2_32.setsockopt
-//sys	Getsockopt(s Handle, level int32, optname int32, optval *byte, optlen *int32) (err error) [failretval==socket_error] = ws2_32.getsockopt
-//sys	bind(s Handle, name unsafe.Pointer, namelen int32) (err error) [failretval==socket_error] = ws2_32.bind
-//sys	connect(s Handle, name unsafe.Pointer, namelen int32) (err error) [failretval==socket_error] = ws2_32.connect
-//sys	getsockname(s Handle, rsa *RawSockaddrAny, addrlen *int32) (err error) [failretval==socket_error] = ws2_32.getsockname
-//sys	getpeername(s Handle, rsa *RawSockaddrAny, addrlen *int32) (err error) [failretval==socket_error] = ws2_32.getpeername
-//sys	listen(s Handle, backlog int32) (err error) [failretval==socket_error] = ws2_32.listen
-//sys	shutdown(s Handle, how int32) (err error) [failretval==socket_error] = ws2_32.shutdown
-//sys	Closesocket(s Handle) (err error) [failretval==socket_error] = ws2_32.closesocket
-//sys	AcceptEx(ls Handle, as Handle, buf *byte, rxdatalen uint32, laddrlen uint32, raddrlen uint32, recvd *uint32, overlapped *Overlapped) (err error) = mswsock.AcceptEx
-//sys	GetAcceptExSockaddrs(buf *byte, rxdatalen uint32, laddrlen uint32, raddrlen uint32, lrsa **RawSockaddrAny, lrsalen *int32, rrsa **RawSockaddrAny, rrsalen *int32) = mswsock.GetAcceptExSockaddrs
-//sys	WSARecv(s Handle, bufs *WSABuf, bufcnt uint32, recvd *uint32, flags *uint32, overlapped *Overlapped, croutine *byte) (err error) [failretval==socket_error] = ws2_32.WSARecv
-//sys	WSASend(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, overlapped *Overlapped, croutine *byte) (err error) [failretval==socket_error] = ws2_32.WSASend
-//sys	WSARecvFrom(s Handle, bufs *WSABuf, bufcnt uint32, recvd *uint32, flags *uint32,  from *RawSockaddrAny, fromlen *int32, overlapped *Overlapped, croutine *byte) (err error) [failretval==socket_error] = ws2_32.WSARecvFrom
-//sys	WSASendTo(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, to *RawSockaddrAny, tolen int32,  overlapped *Overlapped, croutine *byte) (err error) [failretval==socket_error] = ws2_32.WSASendTo
-//sys	GetHostByName(name string) (h *Hostent, err error) [failretval==nil] = ws2_32.gethostbyname
-//sys	GetServByName(name string, proto string) (s *Servent, err error) [failretval==nil] = ws2_32.getservbyname
-//sys	Ntohs(netshort uint16) (u uint16) = ws2_32.ntohs
-//sys	GetProtoByName(name string) (p *Protoent, err error) [failretval==nil] = ws2_32.getprotobyname
-//sys	DnsQuery(name string, qtype uint16, options uint32, extra *byte, qrs **DNSRecord, pr *byte) (status error) = dnsapi.DnsQuery_W
-//sys	DnsRecordListFree(rl *DNSRecord, freetype uint32) = dnsapi.DnsRecordListFree
-//sys	GetAddrInfoW(nodename *uint16, servicename *uint16, hints *AddrinfoW, result **AddrinfoW) (sockerr error) = ws2_32.GetAddrInfoW
-//sys	FreeAddrInfoW(addrinfo *AddrinfoW) = ws2_32.FreeAddrInfoW
-//sys	GetIfEntry(pIfRow *MibIfRow) (errcode error) = iphlpapi.GetIfEntry
-//sys	GetAdaptersInfo(ai *IpAdapterInfo, ol *uint32) (errcode error) = iphlpapi.GetAdaptersInfo
-//sys	SetFileCompletionNotificationModes(handle Handle, flags uint8) (err error) = kernel32.SetFileCompletionNotificationModes
-//sys	WSAEnumProtocols(protocols *int32, protocolBuffer *WSAProtocolInfo, bufferLength *uint32) (n int32, err error) [failretval==-1] = ws2_32.WSAEnumProtocolsW
-
-// For testing: clients can set this flag to force
-// creation of IPv6 sockets to return EAFNOSUPPORT.
-var SocketDisableIPv6 bool
-
-type RawSockaddrInet4 struct {
-	Family uint16
-	Port   uint16
-	Addr   [4]byte /* in_addr */
-	Zero   [8]uint8
-}
-
-type RawSockaddrInet6 struct {
-	Family   uint16
-	Port     uint16
-	Flowinfo uint32
-	Addr     [16]byte /* in6_addr */
-	Scope_id uint32
-}
-
-type RawSockaddr struct {
-	Family uint16
-	Data   [14]int8
-}
-
-type RawSockaddrAny struct {
-	Addr RawSockaddr
-	Pad  [96]int8
-}
-
-type Sockaddr interface {
-	sockaddr() (ptr unsafe.Pointer, len int32, err error) // lowercase; only we can define Sockaddrs
-}
-
-type SockaddrInet4 struct {
-	Port int
-	Addr [4]byte
-	raw  RawSockaddrInet4
-}
-
-func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, int32, error) {
-	if sa.Port < 0 || sa.Port > 0xFFFF {
-		return nil, 0, EINVAL
-	}
-	sa.raw.Family = AF_INET
-	p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
-	p[0] = byte(sa.Port >> 8)
-	p[1] = byte(sa.Port)
-	for i := 0; i < len(sa.Addr); i++ {
-		sa.raw.Addr[i] = sa.Addr[i]
-	}
-	return unsafe.Pointer(&sa.raw), int32(unsafe.Sizeof(sa.raw)), nil
-}
-
-type SockaddrInet6 struct {
-	Port   int
-	ZoneId uint32
-	Addr   [16]byte
-	raw    RawSockaddrInet6
-}
-
-func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, int32, error) {
-	if sa.Port < 0 || sa.Port > 0xFFFF {
-		return nil, 0, EINVAL
-	}
-	sa.raw.Family = AF_INET6
-	p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
-	p[0] = byte(sa.Port >> 8)
-	p[1] = byte(sa.Port)
-	sa.raw.Scope_id = sa.ZoneId
-	for i := 0; i < len(sa.Addr); i++ {
-		sa.raw.Addr[i] = sa.Addr[i]
-	}
-	return unsafe.Pointer(&sa.raw), int32(unsafe.Sizeof(sa.raw)), nil
-}
-
-type SockaddrUnix struct {
-	Name string
-}
-
-func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, int32, error) {
-	// TODO(brainman): implement SockaddrUnix.sockaddr()
-	return nil, 0, EWINDOWS
-}
-
-func (rsa *RawSockaddrAny) Sockaddr() (Sockaddr, error) {
-	switch rsa.Addr.Family {
-	case AF_UNIX:
-		return nil, EWINDOWS
-
-	case AF_INET:
-		pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))
-		sa := new(SockaddrInet4)
-		p := (*[2]byte)(unsafe.Pointer(&pp.Port))
-		sa.Port = int(p[0])<<8 + int(p[1])
-		for i := 0; i < len(sa.Addr); i++ {
-			sa.Addr[i] = pp.Addr[i]
-		}
-		return sa, nil
-
-	case AF_INET6:
-		pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa))
-		sa := new(SockaddrInet6)
-		p := (*[2]byte)(unsafe.Pointer(&pp.Port))
-		sa.Port = int(p[0])<<8 + int(p[1])
-		sa.ZoneId = pp.Scope_id
-		for i := 0; i < len(sa.Addr); i++ {
-			sa.Addr[i] = pp.Addr[i]
-		}
-		return sa, nil
-	}
-	return nil, EAFNOSUPPORT
-}
-
-func Socket(domain, typ, proto int) (fd Handle, err error) {
-	if domain == AF_INET6 && SocketDisableIPv6 {
-		return InvalidHandle, EAFNOSUPPORT
-	}
-	return socket(int32(domain), int32(typ), int32(proto))
-}
-
-func SetsockoptInt(fd Handle, level, opt int, value int) (err error) {
-	v := int32(value)
-	return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(&v)), int32(unsafe.Sizeof(v)))
-}
-
-func Bind(fd Handle, sa Sockaddr) (err error) {
-	ptr, n, err := sa.sockaddr()
-	if err != nil {
-		return err
-	}
-	return bind(fd, ptr, n)
-}
-
-func Connect(fd Handle, sa Sockaddr) (err error) {
-	ptr, n, err := sa.sockaddr()
-	if err != nil {
-		return err
-	}
-	return connect(fd, ptr, n)
-}
-
-func Getsockname(fd Handle) (sa Sockaddr, err error) {
-	var rsa RawSockaddrAny
-	l := int32(unsafe.Sizeof(rsa))
-	if err = getsockname(fd, &rsa, &l); err != nil {
-		return
-	}
-	return rsa.Sockaddr()
-}
-
-func Getpeername(fd Handle) (sa Sockaddr, err error) {
-	var rsa RawSockaddrAny
-	l := int32(unsafe.Sizeof(rsa))
-	if err = getpeername(fd, &rsa, &l); err != nil {
-		return
-	}
-	return rsa.Sockaddr()
-}
-
-func Listen(s Handle, n int) (err error) {
-	return listen(s, int32(n))
-}
-
-func Shutdown(fd Handle, how int) (err error) {
-	return shutdown(fd, int32(how))
-}
-
-func WSASendto(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, to Sockaddr, overlapped *Overlapped, croutine *byte) (err error) {
-	rsa, l, err := to.sockaddr()
-	if err != nil {
-		return err
-	}
-	return WSASendTo(s, bufs, bufcnt, sent, flags, (*RawSockaddrAny)(unsafe.Pointer(rsa)), l, overlapped, croutine)
-}
-
-func LoadGetAddrInfo() error {
-	return procGetAddrInfoW.Find()
-}
-
-var connectExFunc struct {
-	once sync.Once
-	addr uintptr
-	err  error
-}
-
-func LoadConnectEx() error {
-	connectExFunc.once.Do(func() {
-		var s Handle
-		s, connectExFunc.err = Socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)
-		if connectExFunc.err != nil {
-			return
-		}
-		defer CloseHandle(s)
-		var n uint32
-		connectExFunc.err = WSAIoctl(s,
-			SIO_GET_EXTENSION_FUNCTION_POINTER,
-			(*byte)(unsafe.Pointer(&WSAID_CONNECTEX)),
-			uint32(unsafe.Sizeof(WSAID_CONNECTEX)),
-			(*byte)(unsafe.Pointer(&connectExFunc.addr)),
-			uint32(unsafe.Sizeof(connectExFunc.addr)),
-			&n, nil, 0)
-	})
-	return connectExFunc.err
-}
-
-func connectEx(s Handle, name unsafe.Pointer, namelen int32, sendBuf *byte, sendDataLen uint32, bytesSent *uint32, overlapped *Overlapped) (err error) {
-	r1, _, e1 := Syscall9(connectExFunc.addr, 7, uintptr(s), uintptr(name), uintptr(namelen), uintptr(unsafe.Pointer(sendBuf)), uintptr(sendDataLen), uintptr(unsafe.Pointer(bytesSent)), uintptr(unsafe.Pointer(overlapped)), 0, 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func ConnectEx(fd Handle, sa Sockaddr, sendBuf *byte, sendDataLen uint32, bytesSent *uint32, overlapped *Overlapped) error {
-	err := LoadConnectEx()
-	if err != nil {
-		return errorspkg.New("failed to find ConnectEx: " + err.Error())
-	}
-	ptr, n, err := sa.sockaddr()
-	if err != nil {
-		return err
-	}
-	return connectEx(fd, ptr, n, sendBuf, sendDataLen, bytesSent, overlapped)
-}
-
-// Invented structures to support what package os expects.
-type Rusage struct {
-	CreationTime Filetime
-	ExitTime     Filetime
-	KernelTime   Filetime
-	UserTime     Filetime
-}
-
-type WaitStatus struct {
-	ExitCode uint32
-}
-
-func (w WaitStatus) Exited() bool { return true }
-
-func (w WaitStatus) ExitStatus() int { return int(w.ExitCode) }
-
-func (w WaitStatus) Signal() Signal { return -1 }
-
-func (w WaitStatus) CoreDump() bool { return false }
-
-func (w WaitStatus) Stopped() bool { return false }
-
-func (w WaitStatus) Continued() bool { return false }
-
-func (w WaitStatus) StopSignal() Signal { return -1 }
-
-func (w WaitStatus) Signaled() bool { return false }
-
-func (w WaitStatus) TrapCause() int { return -1 }
-
-// Timespec is an invented structure on Windows, but here for
-// consistency with the syscall package for other operating systems.
-type Timespec struct {
-	Sec  int64
-	Nsec int64
-}
-
-func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
-
-func NsecToTimespec(nsec int64) (ts Timespec) {
-	ts.Sec = nsec / 1e9
-	ts.Nsec = nsec % 1e9
-	return
-}
-
-// TODO(brainman): fix all needed for net
-
-func Accept(fd Handle) (nfd Handle, sa Sockaddr, err error) { return 0, nil, EWINDOWS }
-func Recvfrom(fd Handle, p []byte, flags int) (n int, from Sockaddr, err error) {
-	return 0, nil, EWINDOWS
-}
-func Sendto(fd Handle, p []byte, flags int, to Sockaddr) (err error)       { return EWINDOWS }
-func SetsockoptTimeval(fd Handle, level, opt int, tv *Timeval) (err error) { return EWINDOWS }
-
-// The Linger struct is wrong but we only noticed after Go 1.
-// sysLinger is the real system call structure.
-
-// BUG(brainman): The definition of Linger is not appropriate for direct use
-// with Setsockopt and Getsockopt.
-// Use SetsockoptLinger instead.
-
-type Linger struct {
-	Onoff  int32
-	Linger int32
-}
-
-type sysLinger struct {
-	Onoff  uint16
-	Linger uint16
-}
-
-type IPMreq struct {
-	Multiaddr [4]byte /* in_addr */
-	Interface [4]byte /* in_addr */
-}
-
-type IPv6Mreq struct {
-	Multiaddr [16]byte /* in6_addr */
-	Interface uint32
-}
-
-func GetsockoptInt(fd Handle, level, opt int) (int, error) { return -1, EWINDOWS }
-
-func SetsockoptLinger(fd Handle, level, opt int, l *Linger) (err error) {
-	sys := sysLinger{Onoff: uint16(l.Onoff), Linger: uint16(l.Linger)}
-	return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(&sys)), int32(unsafe.Sizeof(sys)))
-}
-
-func SetsockoptInet4Addr(fd Handle, level, opt int, value [4]byte) (err error) {
-	return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(&value[0])), 4)
-}
-func SetsockoptIPMreq(fd Handle, level, opt int, mreq *IPMreq) (err error) {
-	return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(mreq)), int32(unsafe.Sizeof(*mreq)))
-}
-func SetsockoptIPv6Mreq(fd Handle, level, opt int, mreq *IPv6Mreq) (err error) { return EWINDOWS }
-
-func Getpid() (pid int) { return int(getCurrentProcessId()) }
-
-func FindFirstFile(name *uint16, data *Win32finddata) (handle Handle, err error) {
-	// NOTE(rsc): The Win32finddata struct is wrong for the system call:
-	// the two paths are each one uint16 short. Use the correct struct,
-	// a win32finddata1, and then copy the results out.
-	// There is no loss of expressivity here, because the final
-	// uint16, if it is used, is supposed to be a NUL, and Go doesn't need that.
-	// For Go 1.1, we might avoid the allocation of win32finddata1 here
-	// by adding a final Bug [2]uint16 field to the struct and then
-	// adjusting the fields in the result directly.
-	var data1 win32finddata1
-	handle, err = findFirstFile1(name, &data1)
-	if err == nil {
-		copyFindData(data, &data1)
-	}
-	return
-}
-
-func FindNextFile(handle Handle, data *Win32finddata) (err error) {
-	var data1 win32finddata1
-	err = findNextFile1(handle, &data1)
-	if err == nil {
-		copyFindData(data, &data1)
-	}
-	return
-}
-
-// TODO(brainman): fix all needed for os
-func Getppid() (ppid int) { return -1 }
-
-func Fchdir(fd Handle) (err error)                        { return EWINDOWS }
-func Link(oldpath, newpath string) (err error)            { return EWINDOWS }
-func Symlink(path, link string) (err error)               { return EWINDOWS }
-func Readlink(path string, buf []byte) (n int, err error) { return 0, EWINDOWS }
-
-func Fchmod(fd Handle, mode uint32) (err error)        { return EWINDOWS }
-func Chown(path string, uid int, gid int) (err error)  { return EWINDOWS }
-func Lchown(path string, uid int, gid int) (err error) { return EWINDOWS }
-func Fchown(fd Handle, uid int, gid int) (err error)   { return EWINDOWS }
-
-func Getuid() (uid int)                  { return -1 }
-func Geteuid() (euid int)                { return -1 }
-func Getgid() (gid int)                  { return -1 }
-func Getegid() (egid int)                { return -1 }
-func Getgroups() (gids []int, err error) { return nil, EWINDOWS }
-
-type Signal int
-
-func (s Signal) Signal() {}
-
-func (s Signal) String() string {
-	if 0 <= s && int(s) < len(signals) {
-		str := signals[s]
-		if str != "" {
-			return str
-		}
-	}
-	return "signal " + itoa(int(s))
-}
diff --git a/src/pkg/syscall/time_nacl_386.s b/src/pkg/syscall/time_nacl_386.s
deleted file mode 100644
index b5a22d3..0000000
--- a/src/pkg/syscall/time_nacl_386.s
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2013 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../cmd/ld/textflag.h"
-
-TEXT ·startTimer(SB),NOSPLIT,$0
-	JMP time·startTimer(SB)
-
-TEXT ·stopTimer(SB),NOSPLIT,$0
-	JMP time·stopTimer(SB)
diff --git a/src/pkg/syscall/time_nacl_amd64p32.s b/src/pkg/syscall/time_nacl_amd64p32.s
deleted file mode 100644
index b5a22d3..0000000
--- a/src/pkg/syscall/time_nacl_amd64p32.s
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2013 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "../../cmd/ld/textflag.h"
-
-TEXT ·startTimer(SB),NOSPLIT,$0
-	JMP time·startTimer(SB)
-
-TEXT ·stopTimer(SB),NOSPLIT,$0
-	JMP time·stopTimer(SB)
diff --git a/src/pkg/syscall/zsyscall_darwin_386.go b/src/pkg/syscall/zsyscall_darwin_386.go
deleted file mode 100644
index a6a176b..0000000
--- a/src/pkg/syscall/zsyscall_darwin_386.go
+++ /dev/null
@@ -1,1387 +0,0 @@
-// mksyscall.pl -l32 syscall_bsd.go syscall_darwin.go syscall_darwin_386.go
-// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
-
-package syscall
-
-import "unsafe"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getgroups(ngid int, gid *_Gid_t) (n int, err error) {
-	r0, _, e1 := RawSyscall(SYS_GETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func setgroups(ngid int, gid *_Gid_t) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) {
-	r0, _, e1 := Syscall6(SYS_WAIT4, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0)
-	wpid = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
-	r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
-	_, _, e1 := Syscall(SYS_BIND, uintptr(s), uintptr(addr), uintptr(addrlen))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
-	_, _, e1 := Syscall(SYS_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func socket(domain int, typ int, proto int) (fd int, err error) {
-	r0, _, e1 := RawSyscall(SYS_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto))
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) {
-	_, _, e1 := Syscall6(SYS_GETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) {
-	_, _, e1 := Syscall6(SYS_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETPEERNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETSOCKNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Shutdown(s int, how int) (err error) {
-	_, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(s), uintptr(how), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) {
-	_, _, e1 := RawSyscall6(SYS_SOCKETPAIR, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall6(SYS_RECVFROM, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) {
-	var _p0 unsafe.Pointer
-	if len(buf) > 0 {
-		_p0 = unsafe.Pointer(&buf[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall6(SYS_SENDTO, uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_RECVMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_SENDMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func kevent(kq int, change unsafe.Pointer, nchange int, event unsafe.Pointer, nevent int, timeout *Timespec) (n int, err error) {
-	r0, _, e1 := Syscall6(SYS_KEVENT, uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) {
-	var _p0 unsafe.Pointer
-	if len(mib) > 0 {
-		_p0 = unsafe.Pointer(&mib[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall6(SYS___SYSCTL, uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func utimes(path string, timeval *[2]Timeval) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(timeval)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func futimes(fd int, timeval *[2]Timeval) (err error) {
-	_, _, e1 := Syscall(SYS_FUTIMES, uintptr(fd), uintptr(unsafe.Pointer(timeval)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func fcntl(fd int, cmd int, arg int) (val int, err error) {
-	r0, _, e1 := Syscall(SYS_FCNTL, uintptr(fd), uintptr(cmd), uintptr(arg))
-	val = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func ptrace(request int, pid int, addr uintptr, data uintptr) (err error) {
-	_, _, e1 := Syscall6(SYS_PTRACE, uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func pipe() (r int, w int, err error) {
-	r0, r1, e1 := RawSyscall(SYS_PIPE, 0, 0, 0)
-	r = int(r0)
-	w = int(r1)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func kill(pid int, signum int, posix int) (err error) {
-	_, _, e1 := Syscall(SYS_KILL, uintptr(pid), uintptr(signum), uintptr(posix))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Access(path string, mode uint32) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_ACCESS, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Adjtime(delta *Timeval, olddelta *Timeval) (err error) {
-	_, _, e1 := Syscall(SYS_ADJTIME, uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chdir(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chflags(path string, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_CHFLAGS, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chmod(path string, mode uint32) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_CHMOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chown(path string, uid int, gid int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_CHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chroot(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_CHROOT, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Close(fd int) (err error) {
-	_, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Dup(fd int) (nfd int, err error) {
-	r0, _, e1 := RawSyscall(SYS_DUP, uintptr(fd), 0, 0)
-	nfd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Dup2(from int, to int) (err error) {
-	_, _, e1 := RawSyscall(SYS_DUP2, uintptr(from), uintptr(to), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Exchangedata(path1 string, path2 string, options int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path1)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(path2)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_EXCHANGEDATA, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(options))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Exit(code int) {
-	Syscall(SYS_EXIT, uintptr(code), 0, 0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchdir(fd int) (err error) {
-	_, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchflags(fd int, flags int) (err error) {
-	_, _, e1 := Syscall(SYS_FCHFLAGS, uintptr(fd), uintptr(flags), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchmod(fd int, mode uint32) (err error) {
-	_, _, e1 := Syscall(SYS_FCHMOD, uintptr(fd), uintptr(mode), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchown(fd int, uid int, gid int) (err error) {
-	_, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Flock(fd int, how int) (err error) {
-	_, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fpathconf(fd int, name int) (val int, err error) {
-	r0, _, e1 := Syscall(SYS_FPATHCONF, uintptr(fd), uintptr(name), 0)
-	val = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fstat(fd int, stat *Stat_t) (err error) {
-	_, _, e1 := Syscall(SYS_FSTAT64, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fstatfs(fd int, stat *Statfs_t) (err error) {
-	_, _, e1 := Syscall(SYS_FSTATFS64, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fsync(fd int) (err error) {
-	_, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Ftruncate(fd int, length int64) (err error) {
-	_, _, e1 := Syscall(SYS_FTRUNCATE, uintptr(fd), uintptr(length), uintptr(length>>32))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(buf) > 0 {
-		_p0 = unsafe.Pointer(&buf[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall6(SYS_GETDIRENTRIES64, uintptr(fd), uintptr(_p0), uintptr(len(buf)), uintptr(unsafe.Pointer(basep)), 0, 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getdtablesize() (size int) {
-	r0, _, _ := Syscall(SYS_GETDTABLESIZE, 0, 0, 0)
-	size = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getegid() (egid int) {
-	r0, _, _ := RawSyscall(SYS_GETEGID, 0, 0, 0)
-	egid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Geteuid() (uid int) {
-	r0, _, _ := RawSyscall(SYS_GETEUID, 0, 0, 0)
-	uid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getgid() (gid int) {
-	r0, _, _ := RawSyscall(SYS_GETGID, 0, 0, 0)
-	gid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpgid(pid int) (pgid int, err error) {
-	r0, _, e1 := RawSyscall(SYS_GETPGID, uintptr(pid), 0, 0)
-	pgid = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpgrp() (pgrp int) {
-	r0, _, _ := RawSyscall(SYS_GETPGRP, 0, 0, 0)
-	pgrp = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpid() (pid int) {
-	r0, _, _ := RawSyscall(SYS_GETPID, 0, 0, 0)
-	pid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getppid() (ppid int) {
-	r0, _, _ := RawSyscall(SYS_GETPPID, 0, 0, 0)
-	ppid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpriority(which int, who int) (prio int, err error) {
-	r0, _, e1 := Syscall(SYS_GETPRIORITY, uintptr(which), uintptr(who), 0)
-	prio = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getrlimit(which int, lim *Rlimit) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getrusage(who int, rusage *Rusage) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETRUSAGE, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getsid(pid int) (sid int, err error) {
-	r0, _, e1 := RawSyscall(SYS_GETSID, uintptr(pid), 0, 0)
-	sid = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getuid() (uid int) {
-	r0, _, _ := RawSyscall(SYS_GETUID, 0, 0, 0)
-	uid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Issetugid() (tainted bool) {
-	r0, _, _ := RawSyscall(SYS_ISSETUGID, 0, 0, 0)
-	tainted = bool(r0 != 0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Kqueue() (fd int, err error) {
-	r0, _, e1 := Syscall(SYS_KQUEUE, 0, 0, 0)
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Lchown(path string, uid int, gid int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_LCHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Link(path string, link string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(link)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_LINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Listen(s int, backlog int) (err error) {
-	_, _, e1 := Syscall(SYS_LISTEN, uintptr(s), uintptr(backlog), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Lstat(path string, stat *Stat_t) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_LSTAT64, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mkdir(path string, mode uint32) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_MKDIR, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mkfifo(path string, mode uint32) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_MKFIFO, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mknod(path string, mode uint32, dev int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_MKNOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mlock(b []byte) (err error) {
-	var _p0 unsafe.Pointer
-	if len(b) > 0 {
-		_p0 = unsafe.Pointer(&b[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mlockall(flags int) (err error) {
-	_, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mprotect(b []byte, prot int) (err error) {
-	var _p0 unsafe.Pointer
-	if len(b) > 0 {
-		_p0 = unsafe.Pointer(&b[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Munlock(b []byte) (err error) {
-	var _p0 unsafe.Pointer
-	if len(b) > 0 {
-		_p0 = unsafe.Pointer(&b[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Munlockall() (err error) {
-	_, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Open(path string, mode int, perm uint32) (fd int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Pathconf(path string, name int) (val int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	r0, _, e1 := Syscall(SYS_PATHCONF, uintptr(unsafe.Pointer(_p0)), uintptr(name), 0)
-	val = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Pread(fd int, p []byte, offset int64) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall6(SYS_PREAD, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), uintptr(offset>>32), 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall6(SYS_PWRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), uintptr(offset>>32), 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func read(fd int, p []byte) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(_p0), uintptr(len(p)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Readlink(path string, buf []byte) (n int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 unsafe.Pointer
-	if len(buf) > 0 {
-		_p1 = unsafe.Pointer(&buf[0])
-	} else {
-		_p1 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall(SYS_READLINK, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Rename(from string, to string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(from)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(to)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_RENAME, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Revoke(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_REVOKE, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Rmdir(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_RMDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
-	r0, r1, e1 := Syscall6(SYS_LSEEK, uintptr(fd), uintptr(offset), uintptr(offset>>32), uintptr(whence), 0, 0)
-	newoffset = int64(int64(r1)<<32 | int64(r0))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Select(n int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (err error) {
-	_, _, e1 := Syscall6(SYS_SELECT, uintptr(n), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setegid(egid int) (err error) {
-	_, _, e1 := Syscall(SYS_SETEGID, uintptr(egid), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Seteuid(euid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETEUID, uintptr(euid), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setgid(gid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETGID, uintptr(gid), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setlogin(name string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(name)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_SETLOGIN, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setpgid(pid int, pgid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETPGID, uintptr(pid), uintptr(pgid), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setpriority(which int, who int, prio int) (err error) {
-	_, _, e1 := Syscall(SYS_SETPRIORITY, uintptr(which), uintptr(who), uintptr(prio))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setprivexec(flag int) (err error) {
-	_, _, e1 := Syscall(SYS_SETPRIVEXEC, uintptr(flag), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setregid(rgid int, egid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setreuid(ruid int, euid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setrlimit(which int, lim *Rlimit) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setsid() (pid int, err error) {
-	r0, _, e1 := RawSyscall(SYS_SETSID, 0, 0, 0)
-	pid = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Settimeofday(tp *Timeval) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETTIMEOFDAY, uintptr(unsafe.Pointer(tp)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setuid(uid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETUID, uintptr(uid), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Stat(path string, stat *Stat_t) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_STAT64, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Statfs(path string, stat *Statfs_t) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_STATFS64, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Symlink(path string, link string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(link)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_SYMLINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Sync() (err error) {
-	_, _, e1 := Syscall(SYS_SYNC, 0, 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Truncate(path string, length int64) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_TRUNCATE, uintptr(unsafe.Pointer(_p0)), uintptr(length), uintptr(length>>32))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Umask(newmask int) (oldmask int) {
-	r0, _, _ := Syscall(SYS_UMASK, uintptr(newmask), 0, 0)
-	oldmask = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Undelete(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_UNDELETE, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Unlink(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_UNLINK, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Unmount(path string, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_UNMOUNT, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func write(fd int, p []byte) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) {
-	r0, _, e1 := Syscall9(SYS_MMAP, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), uintptr(pos), uintptr(pos>>32), 0, 0)
-	ret = uintptr(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func munmap(addr uintptr, length uintptr) (err error) {
-	_, _, e1 := Syscall(SYS_MUNMAP, uintptr(addr), uintptr(length), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func readlen(fd int, buf *byte, nbuf int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func writelen(fd int, buf *byte, nbuf int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func gettimeofday(tp *Timeval) (sec int32, usec int32, err error) {
-	r0, r1, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tp)), 0, 0)
-	sec = int32(r0)
-	usec = int32(r1)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
diff --git a/src/pkg/syscall/zsyscall_darwin_amd64.go b/src/pkg/syscall/zsyscall_darwin_amd64.go
deleted file mode 100644
index f5867c4..0000000
--- a/src/pkg/syscall/zsyscall_darwin_amd64.go
+++ /dev/null
@@ -1,1387 +0,0 @@
-// mksyscall.pl syscall_bsd.go syscall_darwin.go syscall_darwin_amd64.go
-// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
-
-package syscall
-
-import "unsafe"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getgroups(ngid int, gid *_Gid_t) (n int, err error) {
-	r0, _, e1 := RawSyscall(SYS_GETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func setgroups(ngid int, gid *_Gid_t) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) {
-	r0, _, e1 := Syscall6(SYS_WAIT4, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0)
-	wpid = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
-	r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
-	_, _, e1 := Syscall(SYS_BIND, uintptr(s), uintptr(addr), uintptr(addrlen))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
-	_, _, e1 := Syscall(SYS_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func socket(domain int, typ int, proto int) (fd int, err error) {
-	r0, _, e1 := RawSyscall(SYS_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto))
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) {
-	_, _, e1 := Syscall6(SYS_GETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) {
-	_, _, e1 := Syscall6(SYS_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETPEERNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETSOCKNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Shutdown(s int, how int) (err error) {
-	_, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(s), uintptr(how), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) {
-	_, _, e1 := RawSyscall6(SYS_SOCKETPAIR, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall6(SYS_RECVFROM, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) {
-	var _p0 unsafe.Pointer
-	if len(buf) > 0 {
-		_p0 = unsafe.Pointer(&buf[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall6(SYS_SENDTO, uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_RECVMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_SENDMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func kevent(kq int, change unsafe.Pointer, nchange int, event unsafe.Pointer, nevent int, timeout *Timespec) (n int, err error) {
-	r0, _, e1 := Syscall6(SYS_KEVENT, uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) {
-	var _p0 unsafe.Pointer
-	if len(mib) > 0 {
-		_p0 = unsafe.Pointer(&mib[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall6(SYS___SYSCTL, uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func utimes(path string, timeval *[2]Timeval) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(timeval)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func futimes(fd int, timeval *[2]Timeval) (err error) {
-	_, _, e1 := Syscall(SYS_FUTIMES, uintptr(fd), uintptr(unsafe.Pointer(timeval)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func fcntl(fd int, cmd int, arg int) (val int, err error) {
-	r0, _, e1 := Syscall(SYS_FCNTL, uintptr(fd), uintptr(cmd), uintptr(arg))
-	val = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func ptrace(request int, pid int, addr uintptr, data uintptr) (err error) {
-	_, _, e1 := Syscall6(SYS_PTRACE, uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func pipe() (r int, w int, err error) {
-	r0, r1, e1 := RawSyscall(SYS_PIPE, 0, 0, 0)
-	r = int(r0)
-	w = int(r1)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func kill(pid int, signum int, posix int) (err error) {
-	_, _, e1 := Syscall(SYS_KILL, uintptr(pid), uintptr(signum), uintptr(posix))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Access(path string, mode uint32) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_ACCESS, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Adjtime(delta *Timeval, olddelta *Timeval) (err error) {
-	_, _, e1 := Syscall(SYS_ADJTIME, uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chdir(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chflags(path string, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_CHFLAGS, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chmod(path string, mode uint32) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_CHMOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chown(path string, uid int, gid int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_CHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chroot(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_CHROOT, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Close(fd int) (err error) {
-	_, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Dup(fd int) (nfd int, err error) {
-	r0, _, e1 := RawSyscall(SYS_DUP, uintptr(fd), 0, 0)
-	nfd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Dup2(from int, to int) (err error) {
-	_, _, e1 := RawSyscall(SYS_DUP2, uintptr(from), uintptr(to), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Exchangedata(path1 string, path2 string, options int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path1)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(path2)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_EXCHANGEDATA, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(options))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Exit(code int) {
-	Syscall(SYS_EXIT, uintptr(code), 0, 0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchdir(fd int) (err error) {
-	_, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchflags(fd int, flags int) (err error) {
-	_, _, e1 := Syscall(SYS_FCHFLAGS, uintptr(fd), uintptr(flags), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchmod(fd int, mode uint32) (err error) {
-	_, _, e1 := Syscall(SYS_FCHMOD, uintptr(fd), uintptr(mode), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchown(fd int, uid int, gid int) (err error) {
-	_, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Flock(fd int, how int) (err error) {
-	_, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fpathconf(fd int, name int) (val int, err error) {
-	r0, _, e1 := Syscall(SYS_FPATHCONF, uintptr(fd), uintptr(name), 0)
-	val = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fstat(fd int, stat *Stat_t) (err error) {
-	_, _, e1 := Syscall(SYS_FSTAT64, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fstatfs(fd int, stat *Statfs_t) (err error) {
-	_, _, e1 := Syscall(SYS_FSTATFS64, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fsync(fd int) (err error) {
-	_, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Ftruncate(fd int, length int64) (err error) {
-	_, _, e1 := Syscall(SYS_FTRUNCATE, uintptr(fd), uintptr(length), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(buf) > 0 {
-		_p0 = unsafe.Pointer(&buf[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall6(SYS_GETDIRENTRIES64, uintptr(fd), uintptr(_p0), uintptr(len(buf)), uintptr(unsafe.Pointer(basep)), 0, 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getdtablesize() (size int) {
-	r0, _, _ := Syscall(SYS_GETDTABLESIZE, 0, 0, 0)
-	size = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getegid() (egid int) {
-	r0, _, _ := RawSyscall(SYS_GETEGID, 0, 0, 0)
-	egid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Geteuid() (uid int) {
-	r0, _, _ := RawSyscall(SYS_GETEUID, 0, 0, 0)
-	uid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getgid() (gid int) {
-	r0, _, _ := RawSyscall(SYS_GETGID, 0, 0, 0)
-	gid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpgid(pid int) (pgid int, err error) {
-	r0, _, e1 := RawSyscall(SYS_GETPGID, uintptr(pid), 0, 0)
-	pgid = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpgrp() (pgrp int) {
-	r0, _, _ := RawSyscall(SYS_GETPGRP, 0, 0, 0)
-	pgrp = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpid() (pid int) {
-	r0, _, _ := RawSyscall(SYS_GETPID, 0, 0, 0)
-	pid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getppid() (ppid int) {
-	r0, _, _ := RawSyscall(SYS_GETPPID, 0, 0, 0)
-	ppid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpriority(which int, who int) (prio int, err error) {
-	r0, _, e1 := Syscall(SYS_GETPRIORITY, uintptr(which), uintptr(who), 0)
-	prio = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getrlimit(which int, lim *Rlimit) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getrusage(who int, rusage *Rusage) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETRUSAGE, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getsid(pid int) (sid int, err error) {
-	r0, _, e1 := RawSyscall(SYS_GETSID, uintptr(pid), 0, 0)
-	sid = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getuid() (uid int) {
-	r0, _, _ := RawSyscall(SYS_GETUID, 0, 0, 0)
-	uid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Issetugid() (tainted bool) {
-	r0, _, _ := RawSyscall(SYS_ISSETUGID, 0, 0, 0)
-	tainted = bool(r0 != 0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Kqueue() (fd int, err error) {
-	r0, _, e1 := Syscall(SYS_KQUEUE, 0, 0, 0)
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Lchown(path string, uid int, gid int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_LCHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Link(path string, link string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(link)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_LINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Listen(s int, backlog int) (err error) {
-	_, _, e1 := Syscall(SYS_LISTEN, uintptr(s), uintptr(backlog), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Lstat(path string, stat *Stat_t) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_LSTAT64, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mkdir(path string, mode uint32) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_MKDIR, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mkfifo(path string, mode uint32) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_MKFIFO, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mknod(path string, mode uint32, dev int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_MKNOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mlock(b []byte) (err error) {
-	var _p0 unsafe.Pointer
-	if len(b) > 0 {
-		_p0 = unsafe.Pointer(&b[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mlockall(flags int) (err error) {
-	_, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mprotect(b []byte, prot int) (err error) {
-	var _p0 unsafe.Pointer
-	if len(b) > 0 {
-		_p0 = unsafe.Pointer(&b[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Munlock(b []byte) (err error) {
-	var _p0 unsafe.Pointer
-	if len(b) > 0 {
-		_p0 = unsafe.Pointer(&b[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Munlockall() (err error) {
-	_, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Open(path string, mode int, perm uint32) (fd int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Pathconf(path string, name int) (val int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	r0, _, e1 := Syscall(SYS_PATHCONF, uintptr(unsafe.Pointer(_p0)), uintptr(name), 0)
-	val = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Pread(fd int, p []byte, offset int64) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall6(SYS_PREAD, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall6(SYS_PWRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func read(fd int, p []byte) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(_p0), uintptr(len(p)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Readlink(path string, buf []byte) (n int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 unsafe.Pointer
-	if len(buf) > 0 {
-		_p1 = unsafe.Pointer(&buf[0])
-	} else {
-		_p1 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall(SYS_READLINK, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Rename(from string, to string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(from)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(to)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_RENAME, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Revoke(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_REVOKE, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Rmdir(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_RMDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
-	r0, _, e1 := Syscall(SYS_LSEEK, uintptr(fd), uintptr(offset), uintptr(whence))
-	newoffset = int64(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Select(n int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (err error) {
-	_, _, e1 := Syscall6(SYS_SELECT, uintptr(n), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setegid(egid int) (err error) {
-	_, _, e1 := Syscall(SYS_SETEGID, uintptr(egid), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Seteuid(euid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETEUID, uintptr(euid), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setgid(gid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETGID, uintptr(gid), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setlogin(name string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(name)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_SETLOGIN, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setpgid(pid int, pgid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETPGID, uintptr(pid), uintptr(pgid), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setpriority(which int, who int, prio int) (err error) {
-	_, _, e1 := Syscall(SYS_SETPRIORITY, uintptr(which), uintptr(who), uintptr(prio))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setprivexec(flag int) (err error) {
-	_, _, e1 := Syscall(SYS_SETPRIVEXEC, uintptr(flag), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setregid(rgid int, egid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setreuid(ruid int, euid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setrlimit(which int, lim *Rlimit) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setsid() (pid int, err error) {
-	r0, _, e1 := RawSyscall(SYS_SETSID, 0, 0, 0)
-	pid = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Settimeofday(tp *Timeval) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETTIMEOFDAY, uintptr(unsafe.Pointer(tp)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setuid(uid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETUID, uintptr(uid), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Stat(path string, stat *Stat_t) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_STAT64, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Statfs(path string, stat *Statfs_t) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_STATFS64, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Symlink(path string, link string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(link)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_SYMLINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Sync() (err error) {
-	_, _, e1 := Syscall(SYS_SYNC, 0, 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Truncate(path string, length int64) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_TRUNCATE, uintptr(unsafe.Pointer(_p0)), uintptr(length), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Umask(newmask int) (oldmask int) {
-	r0, _, _ := Syscall(SYS_UMASK, uintptr(newmask), 0, 0)
-	oldmask = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Undelete(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_UNDELETE, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Unlink(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_UNLINK, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Unmount(path string, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_UNMOUNT, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func write(fd int, p []byte) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) {
-	r0, _, e1 := Syscall6(SYS_MMAP, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), uintptr(pos))
-	ret = uintptr(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func munmap(addr uintptr, length uintptr) (err error) {
-	_, _, e1 := Syscall(SYS_MUNMAP, uintptr(addr), uintptr(length), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func readlen(fd int, buf *byte, nbuf int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func writelen(fd int, buf *byte, nbuf int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func gettimeofday(tp *Timeval) (sec int64, usec int32, err error) {
-	r0, r1, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tp)), 0, 0)
-	sec = int64(r0)
-	usec = int32(r1)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
diff --git a/src/pkg/syscall/zsyscall_dragonfly_386.go b/src/pkg/syscall/zsyscall_dragonfly_386.go
deleted file mode 100644
index 0ec8132..0000000
--- a/src/pkg/syscall/zsyscall_dragonfly_386.go
+++ /dev/null
@@ -1,1287 +0,0 @@
-// mksyscall.pl -l32 -dragonfly syscall_bsd.go syscall_dragonfly.go syscall_dragonfly_386.go
-// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
-
-package syscall
-
-import "unsafe"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getgroups(ngid int, gid *_Gid_t) (n int, err error) {
-	r0, _, e1 := RawSyscall(SYS_GETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func setgroups(ngid int, gid *_Gid_t) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) {
-	r0, _, e1 := Syscall6(SYS_WAIT4, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0)
-	wpid = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
-	r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
-	_, _, e1 := Syscall(SYS_BIND, uintptr(s), uintptr(addr), uintptr(addrlen))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
-	_, _, e1 := Syscall(SYS_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func socket(domain int, typ int, proto int) (fd int, err error) {
-	r0, _, e1 := RawSyscall(SYS_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto))
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) {
-	_, _, e1 := Syscall6(SYS_GETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) {
-	_, _, e1 := Syscall6(SYS_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETPEERNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETSOCKNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Shutdown(s int, how int) (err error) {
-	_, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(s), uintptr(how), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) {
-	_, _, e1 := RawSyscall6(SYS_SOCKETPAIR, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall6(SYS_RECVFROM, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) {
-	var _p0 unsafe.Pointer
-	if len(buf) > 0 {
-		_p0 = unsafe.Pointer(&buf[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall6(SYS_SENDTO, uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_RECVMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_SENDMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func kevent(kq int, change unsafe.Pointer, nchange int, event unsafe.Pointer, nevent int, timeout *Timespec) (n int, err error) {
-	r0, _, e1 := Syscall6(SYS_KEVENT, uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) {
-	var _p0 unsafe.Pointer
-	if len(mib) > 0 {
-		_p0 = unsafe.Pointer(&mib[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall6(SYS___SYSCTL, uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func utimes(path string, timeval *[2]Timeval) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(timeval)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func futimes(fd int, timeval *[2]Timeval) (err error) {
-	_, _, e1 := Syscall(SYS_FUTIMES, uintptr(fd), uintptr(unsafe.Pointer(timeval)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func fcntl(fd int, cmd int, arg int) (val int, err error) {
-	r0, _, e1 := Syscall(SYS_FCNTL, uintptr(fd), uintptr(cmd), uintptr(arg))
-	val = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func pipe() (r int, w int, err error) {
-	r0, r1, e1 := RawSyscall(SYS_PIPE, 0, 0, 0)
-	r = int(r0)
-	w = int(r1)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func extpread(fd int, p []byte, flags int, offset int64) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall6(SYS_EXTPREAD, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(offset), uintptr(offset>>32))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func extpwrite(fd int, p []byte, flags int, offset int64) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall6(SYS_EXTPWRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(offset), uintptr(offset>>32))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Access(path string, mode uint32) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_ACCESS, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Adjtime(delta *Timeval, olddelta *Timeval) (err error) {
-	_, _, e1 := Syscall(SYS_ADJTIME, uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chdir(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chflags(path string, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_CHFLAGS, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chmod(path string, mode uint32) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_CHMOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chown(path string, uid int, gid int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_CHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chroot(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_CHROOT, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Close(fd int) (err error) {
-	_, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Dup(fd int) (nfd int, err error) {
-	r0, _, e1 := RawSyscall(SYS_DUP, uintptr(fd), 0, 0)
-	nfd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Dup2(from int, to int) (err error) {
-	_, _, e1 := RawSyscall(SYS_DUP2, uintptr(from), uintptr(to), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Exit(code int) {
-	Syscall(SYS_EXIT, uintptr(code), 0, 0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchdir(fd int) (err error) {
-	_, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchflags(fd int, flags int) (err error) {
-	_, _, e1 := Syscall(SYS_FCHFLAGS, uintptr(fd), uintptr(flags), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchmod(fd int, mode uint32) (err error) {
-	_, _, e1 := Syscall(SYS_FCHMOD, uintptr(fd), uintptr(mode), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchown(fd int, uid int, gid int) (err error) {
-	_, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Flock(fd int, how int) (err error) {
-	_, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fpathconf(fd int, name int) (val int, err error) {
-	r0, _, e1 := Syscall(SYS_FPATHCONF, uintptr(fd), uintptr(name), 0)
-	val = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fstat(fd int, stat *Stat_t) (err error) {
-	_, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fstatfs(fd int, stat *Statfs_t) (err error) {
-	_, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fsync(fd int) (err error) {
-	_, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Ftruncate(fd int, length int64) (err error) {
-	_, _, e1 := Syscall6(SYS_FTRUNCATE, uintptr(fd), 0, uintptr(length), uintptr(length>>32), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(buf) > 0 {
-		_p0 = unsafe.Pointer(&buf[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall6(SYS_GETDIRENTRIES, uintptr(fd), uintptr(_p0), uintptr(len(buf)), uintptr(unsafe.Pointer(basep)), 0, 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getdtablesize() (size int) {
-	r0, _, _ := Syscall(SYS_GETDTABLESIZE, 0, 0, 0)
-	size = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getegid() (egid int) {
-	r0, _, _ := RawSyscall(SYS_GETEGID, 0, 0, 0)
-	egid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Geteuid() (uid int) {
-	r0, _, _ := RawSyscall(SYS_GETEUID, 0, 0, 0)
-	uid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getgid() (gid int) {
-	r0, _, _ := RawSyscall(SYS_GETGID, 0, 0, 0)
-	gid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpgid(pid int) (pgid int, err error) {
-	r0, _, e1 := RawSyscall(SYS_GETPGID, uintptr(pid), 0, 0)
-	pgid = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpgrp() (pgrp int) {
-	r0, _, _ := RawSyscall(SYS_GETPGRP, 0, 0, 0)
-	pgrp = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpid() (pid int) {
-	r0, _, _ := RawSyscall(SYS_GETPID, 0, 0, 0)
-	pid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getppid() (ppid int) {
-	r0, _, _ := RawSyscall(SYS_GETPPID, 0, 0, 0)
-	ppid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpriority(which int, who int) (prio int, err error) {
-	r0, _, e1 := Syscall(SYS_GETPRIORITY, uintptr(which), uintptr(who), 0)
-	prio = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getrlimit(which int, lim *Rlimit) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getrusage(who int, rusage *Rusage) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETRUSAGE, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getsid(pid int) (sid int, err error) {
-	r0, _, e1 := RawSyscall(SYS_GETSID, uintptr(pid), 0, 0)
-	sid = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Gettimeofday(tv *Timeval) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getuid() (uid int) {
-	r0, _, _ := RawSyscall(SYS_GETUID, 0, 0, 0)
-	uid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Issetugid() (tainted bool) {
-	r0, _, _ := Syscall(SYS_ISSETUGID, 0, 0, 0)
-	tainted = bool(r0 != 0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Kill(pid int, signum Signal) (err error) {
-	_, _, e1 := Syscall(SYS_KILL, uintptr(pid), uintptr(signum), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Kqueue() (fd int, err error) {
-	r0, _, e1 := Syscall(SYS_KQUEUE, 0, 0, 0)
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Lchown(path string, uid int, gid int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_LCHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Link(path string, link string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(link)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_LINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Listen(s int, backlog int) (err error) {
-	_, _, e1 := Syscall(SYS_LISTEN, uintptr(s), uintptr(backlog), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Lstat(path string, stat *Stat_t) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_LSTAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mkdir(path string, mode uint32) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_MKDIR, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mkfifo(path string, mode uint32) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_MKFIFO, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mknod(path string, mode uint32, dev int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_MKNOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Nanosleep(time *Timespec, leftover *Timespec) (err error) {
-	_, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Open(path string, mode int, perm uint32) (fd int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Pathconf(path string, name int) (val int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	r0, _, e1 := Syscall(SYS_PATHCONF, uintptr(unsafe.Pointer(_p0)), uintptr(name), 0)
-	val = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func read(fd int, p []byte) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(_p0), uintptr(len(p)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Readlink(path string, buf []byte) (n int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 unsafe.Pointer
-	if len(buf) > 0 {
-		_p1 = unsafe.Pointer(&buf[0])
-	} else {
-		_p1 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall(SYS_READLINK, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Rename(from string, to string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(from)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(to)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_RENAME, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Revoke(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_REVOKE, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Rmdir(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_RMDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
-	r0, r1, e1 := Syscall6(SYS_LSEEK, uintptr(fd), 0, uintptr(offset), uintptr(offset>>32), uintptr(whence), 0)
-	newoffset = int64(int64(r1)<<32 | int64(r0))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Select(n int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (err error) {
-	_, _, e1 := Syscall6(SYS_SELECT, uintptr(n), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setegid(egid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETEGID, uintptr(egid), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Seteuid(euid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETEUID, uintptr(euid), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setgid(gid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETGID, uintptr(gid), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setlogin(name string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(name)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_SETLOGIN, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setpgid(pid int, pgid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETPGID, uintptr(pid), uintptr(pgid), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setpriority(which int, who int, prio int) (err error) {
-	_, _, e1 := Syscall(SYS_SETPRIORITY, uintptr(which), uintptr(who), uintptr(prio))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setregid(rgid int, egid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setreuid(ruid int, euid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setrlimit(which int, lim *Rlimit) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setsid() (pid int, err error) {
-	r0, _, e1 := RawSyscall(SYS_SETSID, 0, 0, 0)
-	pid = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Settimeofday(tp *Timeval) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETTIMEOFDAY, uintptr(unsafe.Pointer(tp)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setuid(uid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETUID, uintptr(uid), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Stat(path string, stat *Stat_t) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Statfs(path string, stat *Statfs_t) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_STATFS, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Symlink(path string, link string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(link)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_SYMLINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Sync() (err error) {
-	_, _, e1 := Syscall(SYS_SYNC, 0, 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Truncate(path string, length int64) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall6(SYS_TRUNCATE, uintptr(unsafe.Pointer(_p0)), 0, uintptr(length), uintptr(length>>32), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Umask(newmask int) (oldmask int) {
-	r0, _, _ := Syscall(SYS_UMASK, uintptr(newmask), 0, 0)
-	oldmask = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Undelete(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_UNDELETE, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Unlink(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_UNLINK, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Unmount(path string, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_UNMOUNT, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func write(fd int, p []byte) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) {
-	r0, _, e1 := Syscall9(SYS_MMAP, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), 0, uintptr(pos), uintptr(pos>>32), 0)
-	ret = uintptr(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func munmap(addr uintptr, length uintptr) (err error) {
-	_, _, e1 := Syscall(SYS_MUNMAP, uintptr(addr), uintptr(length), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func readlen(fd int, buf *byte, nbuf int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func writelen(fd int, buf *byte, nbuf int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
diff --git a/src/pkg/syscall/zsyscall_dragonfly_amd64.go b/src/pkg/syscall/zsyscall_dragonfly_amd64.go
deleted file mode 100644
index 8c7cce5..0000000
--- a/src/pkg/syscall/zsyscall_dragonfly_amd64.go
+++ /dev/null
@@ -1,1287 +0,0 @@
-// mksyscall.pl -dragonfly syscall_bsd.go syscall_dragonfly.go syscall_dragonfly_amd64.go
-// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
-
-package syscall
-
-import "unsafe"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getgroups(ngid int, gid *_Gid_t) (n int, err error) {
-	r0, _, e1 := RawSyscall(SYS_GETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func setgroups(ngid int, gid *_Gid_t) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) {
-	r0, _, e1 := Syscall6(SYS_WAIT4, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0)
-	wpid = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
-	r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
-	_, _, e1 := Syscall(SYS_BIND, uintptr(s), uintptr(addr), uintptr(addrlen))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
-	_, _, e1 := Syscall(SYS_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func socket(domain int, typ int, proto int) (fd int, err error) {
-	r0, _, e1 := RawSyscall(SYS_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto))
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) {
-	_, _, e1 := Syscall6(SYS_GETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) {
-	_, _, e1 := Syscall6(SYS_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETPEERNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETSOCKNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Shutdown(s int, how int) (err error) {
-	_, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(s), uintptr(how), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) {
-	_, _, e1 := RawSyscall6(SYS_SOCKETPAIR, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall6(SYS_RECVFROM, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) {
-	var _p0 unsafe.Pointer
-	if len(buf) > 0 {
-		_p0 = unsafe.Pointer(&buf[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall6(SYS_SENDTO, uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_RECVMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_SENDMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func kevent(kq int, change unsafe.Pointer, nchange int, event unsafe.Pointer, nevent int, timeout *Timespec) (n int, err error) {
-	r0, _, e1 := Syscall6(SYS_KEVENT, uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) {
-	var _p0 unsafe.Pointer
-	if len(mib) > 0 {
-		_p0 = unsafe.Pointer(&mib[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall6(SYS___SYSCTL, uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func utimes(path string, timeval *[2]Timeval) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(timeval)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func futimes(fd int, timeval *[2]Timeval) (err error) {
-	_, _, e1 := Syscall(SYS_FUTIMES, uintptr(fd), uintptr(unsafe.Pointer(timeval)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func fcntl(fd int, cmd int, arg int) (val int, err error) {
-	r0, _, e1 := Syscall(SYS_FCNTL, uintptr(fd), uintptr(cmd), uintptr(arg))
-	val = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func pipe() (r int, w int, err error) {
-	r0, r1, e1 := RawSyscall(SYS_PIPE, 0, 0, 0)
-	r = int(r0)
-	w = int(r1)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func extpread(fd int, p []byte, flags int, offset int64) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall6(SYS_EXTPREAD, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(offset), 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func extpwrite(fd int, p []byte, flags int, offset int64) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall6(SYS_EXTPWRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(offset), 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Access(path string, mode uint32) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_ACCESS, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Adjtime(delta *Timeval, olddelta *Timeval) (err error) {
-	_, _, e1 := Syscall(SYS_ADJTIME, uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chdir(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chflags(path string, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_CHFLAGS, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chmod(path string, mode uint32) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_CHMOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chown(path string, uid int, gid int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_CHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chroot(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_CHROOT, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Close(fd int) (err error) {
-	_, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Dup(fd int) (nfd int, err error) {
-	r0, _, e1 := RawSyscall(SYS_DUP, uintptr(fd), 0, 0)
-	nfd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Dup2(from int, to int) (err error) {
-	_, _, e1 := RawSyscall(SYS_DUP2, uintptr(from), uintptr(to), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Exit(code int) {
-	Syscall(SYS_EXIT, uintptr(code), 0, 0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchdir(fd int) (err error) {
-	_, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchflags(fd int, flags int) (err error) {
-	_, _, e1 := Syscall(SYS_FCHFLAGS, uintptr(fd), uintptr(flags), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchmod(fd int, mode uint32) (err error) {
-	_, _, e1 := Syscall(SYS_FCHMOD, uintptr(fd), uintptr(mode), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchown(fd int, uid int, gid int) (err error) {
-	_, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Flock(fd int, how int) (err error) {
-	_, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fpathconf(fd int, name int) (val int, err error) {
-	r0, _, e1 := Syscall(SYS_FPATHCONF, uintptr(fd), uintptr(name), 0)
-	val = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fstat(fd int, stat *Stat_t) (err error) {
-	_, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fstatfs(fd int, stat *Statfs_t) (err error) {
-	_, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fsync(fd int) (err error) {
-	_, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Ftruncate(fd int, length int64) (err error) {
-	_, _, e1 := Syscall(SYS_FTRUNCATE, uintptr(fd), 0, uintptr(length))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(buf) > 0 {
-		_p0 = unsafe.Pointer(&buf[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall6(SYS_GETDIRENTRIES, uintptr(fd), uintptr(_p0), uintptr(len(buf)), uintptr(unsafe.Pointer(basep)), 0, 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getdtablesize() (size int) {
-	r0, _, _ := Syscall(SYS_GETDTABLESIZE, 0, 0, 0)
-	size = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getegid() (egid int) {
-	r0, _, _ := RawSyscall(SYS_GETEGID, 0, 0, 0)
-	egid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Geteuid() (uid int) {
-	r0, _, _ := RawSyscall(SYS_GETEUID, 0, 0, 0)
-	uid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getgid() (gid int) {
-	r0, _, _ := RawSyscall(SYS_GETGID, 0, 0, 0)
-	gid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpgid(pid int) (pgid int, err error) {
-	r0, _, e1 := RawSyscall(SYS_GETPGID, uintptr(pid), 0, 0)
-	pgid = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpgrp() (pgrp int) {
-	r0, _, _ := RawSyscall(SYS_GETPGRP, 0, 0, 0)
-	pgrp = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpid() (pid int) {
-	r0, _, _ := RawSyscall(SYS_GETPID, 0, 0, 0)
-	pid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getppid() (ppid int) {
-	r0, _, _ := RawSyscall(SYS_GETPPID, 0, 0, 0)
-	ppid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpriority(which int, who int) (prio int, err error) {
-	r0, _, e1 := Syscall(SYS_GETPRIORITY, uintptr(which), uintptr(who), 0)
-	prio = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getrlimit(which int, lim *Rlimit) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getrusage(who int, rusage *Rusage) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETRUSAGE, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getsid(pid int) (sid int, err error) {
-	r0, _, e1 := RawSyscall(SYS_GETSID, uintptr(pid), 0, 0)
-	sid = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Gettimeofday(tv *Timeval) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getuid() (uid int) {
-	r0, _, _ := RawSyscall(SYS_GETUID, 0, 0, 0)
-	uid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Issetugid() (tainted bool) {
-	r0, _, _ := Syscall(SYS_ISSETUGID, 0, 0, 0)
-	tainted = bool(r0 != 0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Kill(pid int, signum Signal) (err error) {
-	_, _, e1 := Syscall(SYS_KILL, uintptr(pid), uintptr(signum), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Kqueue() (fd int, err error) {
-	r0, _, e1 := Syscall(SYS_KQUEUE, 0, 0, 0)
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Lchown(path string, uid int, gid int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_LCHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Link(path string, link string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(link)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_LINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Listen(s int, backlog int) (err error) {
-	_, _, e1 := Syscall(SYS_LISTEN, uintptr(s), uintptr(backlog), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Lstat(path string, stat *Stat_t) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_LSTAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mkdir(path string, mode uint32) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_MKDIR, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mkfifo(path string, mode uint32) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_MKFIFO, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mknod(path string, mode uint32, dev int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_MKNOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Nanosleep(time *Timespec, leftover *Timespec) (err error) {
-	_, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Open(path string, mode int, perm uint32) (fd int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Pathconf(path string, name int) (val int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	r0, _, e1 := Syscall(SYS_PATHCONF, uintptr(unsafe.Pointer(_p0)), uintptr(name), 0)
-	val = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func read(fd int, p []byte) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(_p0), uintptr(len(p)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Readlink(path string, buf []byte) (n int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 unsafe.Pointer
-	if len(buf) > 0 {
-		_p1 = unsafe.Pointer(&buf[0])
-	} else {
-		_p1 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall(SYS_READLINK, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Rename(from string, to string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(from)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(to)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_RENAME, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Revoke(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_REVOKE, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Rmdir(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_RMDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
-	r0, _, e1 := Syscall6(SYS_LSEEK, uintptr(fd), 0, uintptr(offset), uintptr(whence), 0, 0)
-	newoffset = int64(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Select(n int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (err error) {
-	_, _, e1 := Syscall6(SYS_SELECT, uintptr(n), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setegid(egid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETEGID, uintptr(egid), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Seteuid(euid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETEUID, uintptr(euid), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setgid(gid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETGID, uintptr(gid), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setlogin(name string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(name)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_SETLOGIN, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setpgid(pid int, pgid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETPGID, uintptr(pid), uintptr(pgid), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setpriority(which int, who int, prio int) (err error) {
-	_, _, e1 := Syscall(SYS_SETPRIORITY, uintptr(which), uintptr(who), uintptr(prio))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setregid(rgid int, egid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setreuid(ruid int, euid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setrlimit(which int, lim *Rlimit) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setsid() (pid int, err error) {
-	r0, _, e1 := RawSyscall(SYS_SETSID, 0, 0, 0)
-	pid = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Settimeofday(tp *Timeval) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETTIMEOFDAY, uintptr(unsafe.Pointer(tp)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setuid(uid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETUID, uintptr(uid), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Stat(path string, stat *Stat_t) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Statfs(path string, stat *Statfs_t) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_STATFS, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Symlink(path string, link string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(link)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_SYMLINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Sync() (err error) {
-	_, _, e1 := Syscall(SYS_SYNC, 0, 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Truncate(path string, length int64) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_TRUNCATE, uintptr(unsafe.Pointer(_p0)), 0, uintptr(length))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Umask(newmask int) (oldmask int) {
-	r0, _, _ := Syscall(SYS_UMASK, uintptr(newmask), 0, 0)
-	oldmask = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Undelete(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_UNDELETE, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Unlink(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_UNLINK, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Unmount(path string, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_UNMOUNT, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func write(fd int, p []byte) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) {
-	r0, _, e1 := Syscall9(SYS_MMAP, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), 0, uintptr(pos), 0, 0)
-	ret = uintptr(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func munmap(addr uintptr, length uintptr) (err error) {
-	_, _, e1 := Syscall(SYS_MUNMAP, uintptr(addr), uintptr(length), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func readlen(fd int, buf *byte, nbuf int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func writelen(fd int, buf *byte, nbuf int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
diff --git a/src/pkg/syscall/zsyscall_freebsd_386.go b/src/pkg/syscall/zsyscall_freebsd_386.go
deleted file mode 100644
index 5befe83..0000000
--- a/src/pkg/syscall/zsyscall_freebsd_386.go
+++ /dev/null
@@ -1,1298 +0,0 @@
-// mksyscall.pl -l32 syscall_bsd.go syscall_freebsd.go syscall_freebsd_386.go
-// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
-
-package syscall
-
-import "unsafe"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getgroups(ngid int, gid *_Gid_t) (n int, err error) {
-	r0, _, e1 := RawSyscall(SYS_GETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func setgroups(ngid int, gid *_Gid_t) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) {
-	r0, _, e1 := Syscall6(SYS_WAIT4, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0)
-	wpid = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
-	r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
-	_, _, e1 := Syscall(SYS_BIND, uintptr(s), uintptr(addr), uintptr(addrlen))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
-	_, _, e1 := Syscall(SYS_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func socket(domain int, typ int, proto int) (fd int, err error) {
-	r0, _, e1 := RawSyscall(SYS_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto))
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) {
-	_, _, e1 := Syscall6(SYS_GETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) {
-	_, _, e1 := Syscall6(SYS_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETPEERNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETSOCKNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Shutdown(s int, how int) (err error) {
-	_, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(s), uintptr(how), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) {
-	_, _, e1 := RawSyscall6(SYS_SOCKETPAIR, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall6(SYS_RECVFROM, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) {
-	var _p0 unsafe.Pointer
-	if len(buf) > 0 {
-		_p0 = unsafe.Pointer(&buf[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall6(SYS_SENDTO, uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_RECVMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_SENDMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func kevent(kq int, change unsafe.Pointer, nchange int, event unsafe.Pointer, nevent int, timeout *Timespec) (n int, err error) {
-	r0, _, e1 := Syscall6(SYS_KEVENT, uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) {
-	var _p0 unsafe.Pointer
-	if len(mib) > 0 {
-		_p0 = unsafe.Pointer(&mib[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall6(SYS___SYSCTL, uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func utimes(path string, timeval *[2]Timeval) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(timeval)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func futimes(fd int, timeval *[2]Timeval) (err error) {
-	_, _, e1 := Syscall(SYS_FUTIMES, uintptr(fd), uintptr(unsafe.Pointer(timeval)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func fcntl(fd int, cmd int, arg int) (val int, err error) {
-	r0, _, e1 := Syscall(SYS_FCNTL, uintptr(fd), uintptr(cmd), uintptr(arg))
-	val = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func pipe() (r int, w int, err error) {
-	r0, r1, e1 := RawSyscall(SYS_PIPE, 0, 0, 0)
-	r = int(r0)
-	w = int(r1)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Access(path string, mode uint32) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_ACCESS, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Adjtime(delta *Timeval, olddelta *Timeval) (err error) {
-	_, _, e1 := Syscall(SYS_ADJTIME, uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chdir(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chflags(path string, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_CHFLAGS, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chmod(path string, mode uint32) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_CHMOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chown(path string, uid int, gid int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_CHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chroot(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_CHROOT, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Close(fd int) (err error) {
-	_, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Dup(fd int) (nfd int, err error) {
-	r0, _, e1 := RawSyscall(SYS_DUP, uintptr(fd), 0, 0)
-	nfd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Dup2(from int, to int) (err error) {
-	_, _, e1 := RawSyscall(SYS_DUP2, uintptr(from), uintptr(to), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Exit(code int) {
-	Syscall(SYS_EXIT, uintptr(code), 0, 0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchdir(fd int) (err error) {
-	_, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchflags(fd int, flags int) (err error) {
-	_, _, e1 := Syscall(SYS_FCHFLAGS, uintptr(fd), uintptr(flags), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchmod(fd int, mode uint32) (err error) {
-	_, _, e1 := Syscall(SYS_FCHMOD, uintptr(fd), uintptr(mode), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchown(fd int, uid int, gid int) (err error) {
-	_, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Flock(fd int, how int) (err error) {
-	_, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fpathconf(fd int, name int) (val int, err error) {
-	r0, _, e1 := Syscall(SYS_FPATHCONF, uintptr(fd), uintptr(name), 0)
-	val = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fstat(fd int, stat *Stat_t) (err error) {
-	_, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fstatfs(fd int, stat *Statfs_t) (err error) {
-	_, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fsync(fd int) (err error) {
-	_, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Ftruncate(fd int, length int64) (err error) {
-	_, _, e1 := Syscall(SYS_FTRUNCATE, uintptr(fd), uintptr(length), uintptr(length>>32))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(buf) > 0 {
-		_p0 = unsafe.Pointer(&buf[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall6(SYS_GETDIRENTRIES, uintptr(fd), uintptr(_p0), uintptr(len(buf)), uintptr(unsafe.Pointer(basep)), 0, 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getdtablesize() (size int) {
-	r0, _, _ := Syscall(SYS_GETDTABLESIZE, 0, 0, 0)
-	size = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getegid() (egid int) {
-	r0, _, _ := RawSyscall(SYS_GETEGID, 0, 0, 0)
-	egid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Geteuid() (uid int) {
-	r0, _, _ := RawSyscall(SYS_GETEUID, 0, 0, 0)
-	uid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getgid() (gid int) {
-	r0, _, _ := RawSyscall(SYS_GETGID, 0, 0, 0)
-	gid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpgid(pid int) (pgid int, err error) {
-	r0, _, e1 := RawSyscall(SYS_GETPGID, uintptr(pid), 0, 0)
-	pgid = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpgrp() (pgrp int) {
-	r0, _, _ := RawSyscall(SYS_GETPGRP, 0, 0, 0)
-	pgrp = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpid() (pid int) {
-	r0, _, _ := RawSyscall(SYS_GETPID, 0, 0, 0)
-	pid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getppid() (ppid int) {
-	r0, _, _ := RawSyscall(SYS_GETPPID, 0, 0, 0)
-	ppid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpriority(which int, who int) (prio int, err error) {
-	r0, _, e1 := Syscall(SYS_GETPRIORITY, uintptr(which), uintptr(who), 0)
-	prio = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getrlimit(which int, lim *Rlimit) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getrusage(who int, rusage *Rusage) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETRUSAGE, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getsid(pid int) (sid int, err error) {
-	r0, _, e1 := RawSyscall(SYS_GETSID, uintptr(pid), 0, 0)
-	sid = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Gettimeofday(tv *Timeval) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getuid() (uid int) {
-	r0, _, _ := RawSyscall(SYS_GETUID, 0, 0, 0)
-	uid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Issetugid() (tainted bool) {
-	r0, _, _ := Syscall(SYS_ISSETUGID, 0, 0, 0)
-	tainted = bool(r0 != 0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Kill(pid int, signum Signal) (err error) {
-	_, _, e1 := Syscall(SYS_KILL, uintptr(pid), uintptr(signum), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Kqueue() (fd int, err error) {
-	r0, _, e1 := Syscall(SYS_KQUEUE, 0, 0, 0)
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Lchown(path string, uid int, gid int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_LCHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Link(path string, link string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(link)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_LINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Listen(s int, backlog int) (err error) {
-	_, _, e1 := Syscall(SYS_LISTEN, uintptr(s), uintptr(backlog), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Lstat(path string, stat *Stat_t) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_LSTAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mkdir(path string, mode uint32) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_MKDIR, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mkfifo(path string, mode uint32) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_MKFIFO, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mknod(path string, mode uint32, dev int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_MKNOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Nanosleep(time *Timespec, leftover *Timespec) (err error) {
-	_, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Open(path string, mode int, perm uint32) (fd int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Pathconf(path string, name int) (val int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	r0, _, e1 := Syscall(SYS_PATHCONF, uintptr(unsafe.Pointer(_p0)), uintptr(name), 0)
-	val = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Pread(fd int, p []byte, offset int64) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall6(SYS_PREAD, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), uintptr(offset>>32), 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall6(SYS_PWRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), uintptr(offset>>32), 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func read(fd int, p []byte) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(_p0), uintptr(len(p)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Readlink(path string, buf []byte) (n int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 unsafe.Pointer
-	if len(buf) > 0 {
-		_p1 = unsafe.Pointer(&buf[0])
-	} else {
-		_p1 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall(SYS_READLINK, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Rename(from string, to string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(from)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(to)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_RENAME, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Revoke(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_REVOKE, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Rmdir(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_RMDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
-	r0, r1, e1 := Syscall6(SYS_LSEEK, uintptr(fd), uintptr(offset), uintptr(offset>>32), uintptr(whence), 0, 0)
-	newoffset = int64(int64(r1)<<32 | int64(r0))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Select(n int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (err error) {
-	_, _, e1 := Syscall6(SYS_SELECT, uintptr(n), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setegid(egid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETEGID, uintptr(egid), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Seteuid(euid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETEUID, uintptr(euid), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setgid(gid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETGID, uintptr(gid), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setlogin(name string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(name)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_SETLOGIN, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setpgid(pid int, pgid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETPGID, uintptr(pid), uintptr(pgid), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setpriority(which int, who int, prio int) (err error) {
-	_, _, e1 := Syscall(SYS_SETPRIORITY, uintptr(which), uintptr(who), uintptr(prio))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setregid(rgid int, egid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setreuid(ruid int, euid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setrlimit(which int, lim *Rlimit) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setsid() (pid int, err error) {
-	r0, _, e1 := RawSyscall(SYS_SETSID, 0, 0, 0)
-	pid = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Settimeofday(tp *Timeval) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETTIMEOFDAY, uintptr(unsafe.Pointer(tp)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setuid(uid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETUID, uintptr(uid), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Stat(path string, stat *Stat_t) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Statfs(path string, stat *Statfs_t) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_STATFS, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Symlink(path string, link string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(link)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_SYMLINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Sync() (err error) {
-	_, _, e1 := Syscall(SYS_SYNC, 0, 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Truncate(path string, length int64) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_TRUNCATE, uintptr(unsafe.Pointer(_p0)), uintptr(length), uintptr(length>>32))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Umask(newmask int) (oldmask int) {
-	r0, _, _ := Syscall(SYS_UMASK, uintptr(newmask), 0, 0)
-	oldmask = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Undelete(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_UNDELETE, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Unlink(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_UNLINK, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Unmount(path string, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_UNMOUNT, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func write(fd int, p []byte) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) {
-	r0, _, e1 := Syscall9(SYS_MMAP, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), uintptr(pos), uintptr(pos>>32), 0, 0)
-	ret = uintptr(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func munmap(addr uintptr, length uintptr) (err error) {
-	_, _, e1 := Syscall(SYS_MUNMAP, uintptr(addr), uintptr(length), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func readlen(fd int, buf *byte, nbuf int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func writelen(fd int, buf *byte, nbuf int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func accept4(fd int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (nfd int, err error) {
-	r0, _, e1 := Syscall6(SYS_ACCEPT4, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0)
-	nfd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
diff --git a/src/pkg/syscall/zsyscall_freebsd_amd64.go b/src/pkg/syscall/zsyscall_freebsd_amd64.go
deleted file mode 100644
index ab2eb80..0000000
--- a/src/pkg/syscall/zsyscall_freebsd_amd64.go
+++ /dev/null
@@ -1,1298 +0,0 @@
-// mksyscall.pl syscall_bsd.go syscall_freebsd.go syscall_freebsd_amd64.go
-// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
-
-package syscall
-
-import "unsafe"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getgroups(ngid int, gid *_Gid_t) (n int, err error) {
-	r0, _, e1 := RawSyscall(SYS_GETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func setgroups(ngid int, gid *_Gid_t) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) {
-	r0, _, e1 := Syscall6(SYS_WAIT4, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0)
-	wpid = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
-	r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
-	_, _, e1 := Syscall(SYS_BIND, uintptr(s), uintptr(addr), uintptr(addrlen))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
-	_, _, e1 := Syscall(SYS_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func socket(domain int, typ int, proto int) (fd int, err error) {
-	r0, _, e1 := RawSyscall(SYS_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto))
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) {
-	_, _, e1 := Syscall6(SYS_GETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) {
-	_, _, e1 := Syscall6(SYS_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETPEERNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETSOCKNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Shutdown(s int, how int) (err error) {
-	_, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(s), uintptr(how), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) {
-	_, _, e1 := RawSyscall6(SYS_SOCKETPAIR, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall6(SYS_RECVFROM, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) {
-	var _p0 unsafe.Pointer
-	if len(buf) > 0 {
-		_p0 = unsafe.Pointer(&buf[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall6(SYS_SENDTO, uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_RECVMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_SENDMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func kevent(kq int, change unsafe.Pointer, nchange int, event unsafe.Pointer, nevent int, timeout *Timespec) (n int, err error) {
-	r0, _, e1 := Syscall6(SYS_KEVENT, uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) {
-	var _p0 unsafe.Pointer
-	if len(mib) > 0 {
-		_p0 = unsafe.Pointer(&mib[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall6(SYS___SYSCTL, uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func utimes(path string, timeval *[2]Timeval) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(timeval)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func futimes(fd int, timeval *[2]Timeval) (err error) {
-	_, _, e1 := Syscall(SYS_FUTIMES, uintptr(fd), uintptr(unsafe.Pointer(timeval)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func fcntl(fd int, cmd int, arg int) (val int, err error) {
-	r0, _, e1 := Syscall(SYS_FCNTL, uintptr(fd), uintptr(cmd), uintptr(arg))
-	val = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func pipe() (r int, w int, err error) {
-	r0, r1, e1 := RawSyscall(SYS_PIPE, 0, 0, 0)
-	r = int(r0)
-	w = int(r1)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Access(path string, mode uint32) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_ACCESS, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Adjtime(delta *Timeval, olddelta *Timeval) (err error) {
-	_, _, e1 := Syscall(SYS_ADJTIME, uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chdir(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chflags(path string, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_CHFLAGS, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chmod(path string, mode uint32) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_CHMOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chown(path string, uid int, gid int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_CHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chroot(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_CHROOT, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Close(fd int) (err error) {
-	_, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Dup(fd int) (nfd int, err error) {
-	r0, _, e1 := RawSyscall(SYS_DUP, uintptr(fd), 0, 0)
-	nfd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Dup2(from int, to int) (err error) {
-	_, _, e1 := RawSyscall(SYS_DUP2, uintptr(from), uintptr(to), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Exit(code int) {
-	Syscall(SYS_EXIT, uintptr(code), 0, 0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchdir(fd int) (err error) {
-	_, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchflags(fd int, flags int) (err error) {
-	_, _, e1 := Syscall(SYS_FCHFLAGS, uintptr(fd), uintptr(flags), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchmod(fd int, mode uint32) (err error) {
-	_, _, e1 := Syscall(SYS_FCHMOD, uintptr(fd), uintptr(mode), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchown(fd int, uid int, gid int) (err error) {
-	_, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Flock(fd int, how int) (err error) {
-	_, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fpathconf(fd int, name int) (val int, err error) {
-	r0, _, e1 := Syscall(SYS_FPATHCONF, uintptr(fd), uintptr(name), 0)
-	val = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fstat(fd int, stat *Stat_t) (err error) {
-	_, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fstatfs(fd int, stat *Statfs_t) (err error) {
-	_, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fsync(fd int) (err error) {
-	_, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Ftruncate(fd int, length int64) (err error) {
-	_, _, e1 := Syscall(SYS_FTRUNCATE, uintptr(fd), uintptr(length), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(buf) > 0 {
-		_p0 = unsafe.Pointer(&buf[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall6(SYS_GETDIRENTRIES, uintptr(fd), uintptr(_p0), uintptr(len(buf)), uintptr(unsafe.Pointer(basep)), 0, 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getdtablesize() (size int) {
-	r0, _, _ := Syscall(SYS_GETDTABLESIZE, 0, 0, 0)
-	size = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getegid() (egid int) {
-	r0, _, _ := RawSyscall(SYS_GETEGID, 0, 0, 0)
-	egid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Geteuid() (uid int) {
-	r0, _, _ := RawSyscall(SYS_GETEUID, 0, 0, 0)
-	uid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getgid() (gid int) {
-	r0, _, _ := RawSyscall(SYS_GETGID, 0, 0, 0)
-	gid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpgid(pid int) (pgid int, err error) {
-	r0, _, e1 := RawSyscall(SYS_GETPGID, uintptr(pid), 0, 0)
-	pgid = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpgrp() (pgrp int) {
-	r0, _, _ := RawSyscall(SYS_GETPGRP, 0, 0, 0)
-	pgrp = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpid() (pid int) {
-	r0, _, _ := RawSyscall(SYS_GETPID, 0, 0, 0)
-	pid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getppid() (ppid int) {
-	r0, _, _ := RawSyscall(SYS_GETPPID, 0, 0, 0)
-	ppid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpriority(which int, who int) (prio int, err error) {
-	r0, _, e1 := Syscall(SYS_GETPRIORITY, uintptr(which), uintptr(who), 0)
-	prio = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getrlimit(which int, lim *Rlimit) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getrusage(who int, rusage *Rusage) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETRUSAGE, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getsid(pid int) (sid int, err error) {
-	r0, _, e1 := RawSyscall(SYS_GETSID, uintptr(pid), 0, 0)
-	sid = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Gettimeofday(tv *Timeval) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getuid() (uid int) {
-	r0, _, _ := RawSyscall(SYS_GETUID, 0, 0, 0)
-	uid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Issetugid() (tainted bool) {
-	r0, _, _ := Syscall(SYS_ISSETUGID, 0, 0, 0)
-	tainted = bool(r0 != 0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Kill(pid int, signum Signal) (err error) {
-	_, _, e1 := Syscall(SYS_KILL, uintptr(pid), uintptr(signum), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Kqueue() (fd int, err error) {
-	r0, _, e1 := Syscall(SYS_KQUEUE, 0, 0, 0)
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Lchown(path string, uid int, gid int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_LCHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Link(path string, link string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(link)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_LINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Listen(s int, backlog int) (err error) {
-	_, _, e1 := Syscall(SYS_LISTEN, uintptr(s), uintptr(backlog), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Lstat(path string, stat *Stat_t) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_LSTAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mkdir(path string, mode uint32) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_MKDIR, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mkfifo(path string, mode uint32) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_MKFIFO, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mknod(path string, mode uint32, dev int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_MKNOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Nanosleep(time *Timespec, leftover *Timespec) (err error) {
-	_, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Open(path string, mode int, perm uint32) (fd int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Pathconf(path string, name int) (val int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	r0, _, e1 := Syscall(SYS_PATHCONF, uintptr(unsafe.Pointer(_p0)), uintptr(name), 0)
-	val = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Pread(fd int, p []byte, offset int64) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall6(SYS_PREAD, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall6(SYS_PWRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func read(fd int, p []byte) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(_p0), uintptr(len(p)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Readlink(path string, buf []byte) (n int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 unsafe.Pointer
-	if len(buf) > 0 {
-		_p1 = unsafe.Pointer(&buf[0])
-	} else {
-		_p1 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall(SYS_READLINK, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Rename(from string, to string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(from)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(to)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_RENAME, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Revoke(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_REVOKE, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Rmdir(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_RMDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
-	r0, _, e1 := Syscall(SYS_LSEEK, uintptr(fd), uintptr(offset), uintptr(whence))
-	newoffset = int64(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Select(n int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (err error) {
-	_, _, e1 := Syscall6(SYS_SELECT, uintptr(n), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setegid(egid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETEGID, uintptr(egid), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Seteuid(euid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETEUID, uintptr(euid), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setgid(gid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETGID, uintptr(gid), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setlogin(name string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(name)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_SETLOGIN, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setpgid(pid int, pgid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETPGID, uintptr(pid), uintptr(pgid), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setpriority(which int, who int, prio int) (err error) {
-	_, _, e1 := Syscall(SYS_SETPRIORITY, uintptr(which), uintptr(who), uintptr(prio))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setregid(rgid int, egid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setreuid(ruid int, euid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setrlimit(which int, lim *Rlimit) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setsid() (pid int, err error) {
-	r0, _, e1 := RawSyscall(SYS_SETSID, 0, 0, 0)
-	pid = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Settimeofday(tp *Timeval) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETTIMEOFDAY, uintptr(unsafe.Pointer(tp)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setuid(uid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETUID, uintptr(uid), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Stat(path string, stat *Stat_t) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Statfs(path string, stat *Statfs_t) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_STATFS, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Symlink(path string, link string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(link)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_SYMLINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Sync() (err error) {
-	_, _, e1 := Syscall(SYS_SYNC, 0, 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Truncate(path string, length int64) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_TRUNCATE, uintptr(unsafe.Pointer(_p0)), uintptr(length), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Umask(newmask int) (oldmask int) {
-	r0, _, _ := Syscall(SYS_UMASK, uintptr(newmask), 0, 0)
-	oldmask = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Undelete(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_UNDELETE, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Unlink(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_UNLINK, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Unmount(path string, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_UNMOUNT, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func write(fd int, p []byte) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) {
-	r0, _, e1 := Syscall6(SYS_MMAP, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), uintptr(pos))
-	ret = uintptr(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func munmap(addr uintptr, length uintptr) (err error) {
-	_, _, e1 := Syscall(SYS_MUNMAP, uintptr(addr), uintptr(length), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func readlen(fd int, buf *byte, nbuf int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func writelen(fd int, buf *byte, nbuf int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func accept4(fd int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (nfd int, err error) {
-	r0, _, e1 := Syscall6(SYS_ACCEPT4, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0)
-	nfd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
diff --git a/src/pkg/syscall/zsyscall_freebsd_arm.go b/src/pkg/syscall/zsyscall_freebsd_arm.go
deleted file mode 100644
index c1f0f90..0000000
--- a/src/pkg/syscall/zsyscall_freebsd_arm.go
+++ /dev/null
@@ -1,1298 +0,0 @@
-// mksyscall.pl -l32 -arm syscall_bsd.go syscall_freebsd.go syscall_freebsd_arm.go
-// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
-
-package syscall
-
-import "unsafe"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getgroups(ngid int, gid *_Gid_t) (n int, err error) {
-	r0, _, e1 := RawSyscall(SYS_GETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func setgroups(ngid int, gid *_Gid_t) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) {
-	r0, _, e1 := Syscall6(SYS_WAIT4, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0)
-	wpid = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
-	r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
-	_, _, e1 := Syscall(SYS_BIND, uintptr(s), uintptr(addr), uintptr(addrlen))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
-	_, _, e1 := Syscall(SYS_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func socket(domain int, typ int, proto int) (fd int, err error) {
-	r0, _, e1 := RawSyscall(SYS_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto))
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) {
-	_, _, e1 := Syscall6(SYS_GETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) {
-	_, _, e1 := Syscall6(SYS_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETPEERNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETSOCKNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Shutdown(s int, how int) (err error) {
-	_, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(s), uintptr(how), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) {
-	_, _, e1 := RawSyscall6(SYS_SOCKETPAIR, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall6(SYS_RECVFROM, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) {
-	var _p0 unsafe.Pointer
-	if len(buf) > 0 {
-		_p0 = unsafe.Pointer(&buf[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall6(SYS_SENDTO, uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_RECVMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_SENDMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func kevent(kq int, change unsafe.Pointer, nchange int, event unsafe.Pointer, nevent int, timeout *Timespec) (n int, err error) {
-	r0, _, e1 := Syscall6(SYS_KEVENT, uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) {
-	var _p0 unsafe.Pointer
-	if len(mib) > 0 {
-		_p0 = unsafe.Pointer(&mib[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall6(SYS___SYSCTL, uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func utimes(path string, timeval *[2]Timeval) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(timeval)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func futimes(fd int, timeval *[2]Timeval) (err error) {
-	_, _, e1 := Syscall(SYS_FUTIMES, uintptr(fd), uintptr(unsafe.Pointer(timeval)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func fcntl(fd int, cmd int, arg int) (val int, err error) {
-	r0, _, e1 := Syscall(SYS_FCNTL, uintptr(fd), uintptr(cmd), uintptr(arg))
-	val = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func pipe() (r int, w int, err error) {
-	r0, r1, e1 := RawSyscall(SYS_PIPE, 0, 0, 0)
-	r = int(r0)
-	w = int(r1)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Access(path string, mode uint32) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_ACCESS, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Adjtime(delta *Timeval, olddelta *Timeval) (err error) {
-	_, _, e1 := Syscall(SYS_ADJTIME, uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chdir(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chflags(path string, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_CHFLAGS, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chmod(path string, mode uint32) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_CHMOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chown(path string, uid int, gid int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_CHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chroot(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_CHROOT, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Close(fd int) (err error) {
-	_, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Dup(fd int) (nfd int, err error) {
-	r0, _, e1 := RawSyscall(SYS_DUP, uintptr(fd), 0, 0)
-	nfd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Dup2(from int, to int) (err error) {
-	_, _, e1 := RawSyscall(SYS_DUP2, uintptr(from), uintptr(to), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Exit(code int) {
-	Syscall(SYS_EXIT, uintptr(code), 0, 0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchdir(fd int) (err error) {
-	_, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchflags(fd int, flags int) (err error) {
-	_, _, e1 := Syscall(SYS_FCHFLAGS, uintptr(fd), uintptr(flags), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchmod(fd int, mode uint32) (err error) {
-	_, _, e1 := Syscall(SYS_FCHMOD, uintptr(fd), uintptr(mode), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchown(fd int, uid int, gid int) (err error) {
-	_, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Flock(fd int, how int) (err error) {
-	_, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fpathconf(fd int, name int) (val int, err error) {
-	r0, _, e1 := Syscall(SYS_FPATHCONF, uintptr(fd), uintptr(name), 0)
-	val = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fstat(fd int, stat *Stat_t) (err error) {
-	_, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fstatfs(fd int, stat *Statfs_t) (err error) {
-	_, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fsync(fd int) (err error) {
-	_, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Ftruncate(fd int, length int64) (err error) {
-	_, _, e1 := Syscall6(SYS_FTRUNCATE, uintptr(fd), 0, uintptr(length), uintptr(length>>32), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(buf) > 0 {
-		_p0 = unsafe.Pointer(&buf[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall6(SYS_GETDIRENTRIES, uintptr(fd), uintptr(_p0), uintptr(len(buf)), uintptr(unsafe.Pointer(basep)), 0, 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getdtablesize() (size int) {
-	r0, _, _ := Syscall(SYS_GETDTABLESIZE, 0, 0, 0)
-	size = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getegid() (egid int) {
-	r0, _, _ := RawSyscall(SYS_GETEGID, 0, 0, 0)
-	egid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Geteuid() (uid int) {
-	r0, _, _ := RawSyscall(SYS_GETEUID, 0, 0, 0)
-	uid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getgid() (gid int) {
-	r0, _, _ := RawSyscall(SYS_GETGID, 0, 0, 0)
-	gid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpgid(pid int) (pgid int, err error) {
-	r0, _, e1 := RawSyscall(SYS_GETPGID, uintptr(pid), 0, 0)
-	pgid = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpgrp() (pgrp int) {
-	r0, _, _ := RawSyscall(SYS_GETPGRP, 0, 0, 0)
-	pgrp = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpid() (pid int) {
-	r0, _, _ := RawSyscall(SYS_GETPID, 0, 0, 0)
-	pid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getppid() (ppid int) {
-	r0, _, _ := RawSyscall(SYS_GETPPID, 0, 0, 0)
-	ppid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpriority(which int, who int) (prio int, err error) {
-	r0, _, e1 := Syscall(SYS_GETPRIORITY, uintptr(which), uintptr(who), 0)
-	prio = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getrlimit(which int, lim *Rlimit) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getrusage(who int, rusage *Rusage) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETRUSAGE, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getsid(pid int) (sid int, err error) {
-	r0, _, e1 := RawSyscall(SYS_GETSID, uintptr(pid), 0, 0)
-	sid = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Gettimeofday(tv *Timeval) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getuid() (uid int) {
-	r0, _, _ := RawSyscall(SYS_GETUID, 0, 0, 0)
-	uid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Issetugid() (tainted bool) {
-	r0, _, _ := Syscall(SYS_ISSETUGID, 0, 0, 0)
-	tainted = bool(r0 != 0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Kill(pid int, signum Signal) (err error) {
-	_, _, e1 := Syscall(SYS_KILL, uintptr(pid), uintptr(signum), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Kqueue() (fd int, err error) {
-	r0, _, e1 := Syscall(SYS_KQUEUE, 0, 0, 0)
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Lchown(path string, uid int, gid int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_LCHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Link(path string, link string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(link)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_LINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Listen(s int, backlog int) (err error) {
-	_, _, e1 := Syscall(SYS_LISTEN, uintptr(s), uintptr(backlog), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Lstat(path string, stat *Stat_t) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_LSTAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mkdir(path string, mode uint32) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_MKDIR, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mkfifo(path string, mode uint32) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_MKFIFO, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mknod(path string, mode uint32, dev int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_MKNOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Nanosleep(time *Timespec, leftover *Timespec) (err error) {
-	_, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Open(path string, mode int, perm uint32) (fd int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Pathconf(path string, name int) (val int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	r0, _, e1 := Syscall(SYS_PATHCONF, uintptr(unsafe.Pointer(_p0)), uintptr(name), 0)
-	val = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Pread(fd int, p []byte, offset int64) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall6(SYS_PREAD, uintptr(fd), uintptr(_p0), uintptr(len(p)), 0, uintptr(offset), uintptr(offset>>32))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall6(SYS_PWRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)), 0, uintptr(offset), uintptr(offset>>32))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func read(fd int, p []byte) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(_p0), uintptr(len(p)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Readlink(path string, buf []byte) (n int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 unsafe.Pointer
-	if len(buf) > 0 {
-		_p1 = unsafe.Pointer(&buf[0])
-	} else {
-		_p1 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall(SYS_READLINK, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Rename(from string, to string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(from)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(to)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_RENAME, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Revoke(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_REVOKE, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Rmdir(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_RMDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
-	r0, r1, e1 := Syscall6(SYS_LSEEK, uintptr(fd), 0, uintptr(offset), uintptr(offset>>32), uintptr(whence), 0)
-	newoffset = int64(int64(r1)<<32 | int64(r0))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Select(n int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (err error) {
-	_, _, e1 := Syscall6(SYS_SELECT, uintptr(n), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setegid(egid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETEGID, uintptr(egid), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Seteuid(euid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETEUID, uintptr(euid), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setgid(gid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETGID, uintptr(gid), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setlogin(name string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(name)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_SETLOGIN, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setpgid(pid int, pgid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETPGID, uintptr(pid), uintptr(pgid), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setpriority(which int, who int, prio int) (err error) {
-	_, _, e1 := Syscall(SYS_SETPRIORITY, uintptr(which), uintptr(who), uintptr(prio))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setregid(rgid int, egid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setreuid(ruid int, euid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setrlimit(which int, lim *Rlimit) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setsid() (pid int, err error) {
-	r0, _, e1 := RawSyscall(SYS_SETSID, 0, 0, 0)
-	pid = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Settimeofday(tp *Timeval) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETTIMEOFDAY, uintptr(unsafe.Pointer(tp)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setuid(uid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETUID, uintptr(uid), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Stat(path string, stat *Stat_t) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Statfs(path string, stat *Statfs_t) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_STATFS, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Symlink(path string, link string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(link)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_SYMLINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Sync() (err error) {
-	_, _, e1 := Syscall(SYS_SYNC, 0, 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Truncate(path string, length int64) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall6(SYS_TRUNCATE, uintptr(unsafe.Pointer(_p0)), 0, uintptr(length), uintptr(length>>32), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Umask(newmask int) (oldmask int) {
-	r0, _, _ := Syscall(SYS_UMASK, uintptr(newmask), 0, 0)
-	oldmask = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Undelete(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_UNDELETE, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Unlink(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_UNLINK, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Unmount(path string, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_UNMOUNT, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func write(fd int, p []byte) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) {
-	r0, _, e1 := Syscall9(SYS_MMAP, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), 0, uintptr(pos), uintptr(pos>>32), 0)
-	ret = uintptr(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func munmap(addr uintptr, length uintptr) (err error) {
-	_, _, e1 := Syscall(SYS_MUNMAP, uintptr(addr), uintptr(length), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func readlen(fd int, buf *byte, nbuf int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func writelen(fd int, buf *byte, nbuf int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func accept4(fd int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (nfd int, err error) {
-	r0, _, e1 := Syscall6(SYS_ACCEPT4, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0)
-	nfd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
diff --git a/src/pkg/syscall/zsyscall_linux_386.go b/src/pkg/syscall/zsyscall_linux_386.go
deleted file mode 100644
index 6eeb118..0000000
--- a/src/pkg/syscall/zsyscall_linux_386.go
+++ /dev/null
@@ -1,1737 +0,0 @@
-// mksyscall.pl -l32 syscall_linux.go syscall_linux_386.go
-// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
-
-package syscall
-
-import "unsafe"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func open(path string, mode int, perm uint32) (fd int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	r0, _, e1 := Syscall6(SYS_OPENAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), uintptr(mode), 0, 0)
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func pipe(p *[2]_C_int) (err error) {
-	_, _, e1 := RawSyscall(SYS_PIPE, uintptr(unsafe.Pointer(p)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func pipe2(p *[2]_C_int, flags int) (err error) {
-	_, _, e1 := RawSyscall(SYS_PIPE2, uintptr(unsafe.Pointer(p)), uintptr(flags), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func utimes(path string, times *[2]Timeval) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func utimensat(dirfd int, path string, times *[2]Timespec) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func futimesat(dirfd int, path *byte, times *[2]Timeval) (err error) {
-	_, _, e1 := Syscall(SYS_FUTIMESAT, uintptr(dirfd), uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(times)))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getcwd(buf []byte) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(buf) > 0 {
-		_p0 = unsafe.Pointer(&buf[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall(SYS_GETCWD, uintptr(_p0), uintptr(len(buf)), 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) {
-	r0, _, e1 := Syscall6(SYS_WAIT4, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0)
-	wpid = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func ptrace(request int, pid int, addr uintptr, data uintptr) (err error) {
-	_, _, e1 := Syscall6(SYS_PTRACE, uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func reboot(magic1 uint, magic2 uint, cmd int, arg string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(arg)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall6(SYS_REBOOT, uintptr(magic1), uintptr(magic2), uintptr(cmd), uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func mount(source string, target string, fstype string, flags uintptr, data *byte) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(source)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(target)
-	if err != nil {
-		return
-	}
-	var _p2 *byte
-	_p2, err = BytePtrFromString(fstype)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall6(SYS_MOUNT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(unsafe.Pointer(_p2)), uintptr(flags), uintptr(unsafe.Pointer(data)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Access(path string, mode uint32) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_ACCESS, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Acct(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_ACCT, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Adjtimex(buf *Timex) (state int, err error) {
-	r0, _, e1 := Syscall(SYS_ADJTIMEX, uintptr(unsafe.Pointer(buf)), 0, 0)
-	state = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chdir(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chmod(path string, mode uint32) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_CHMOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chroot(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_CHROOT, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Close(fd int) (err error) {
-	_, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Creat(path string, mode uint32) (fd int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	r0, _, e1 := Syscall(SYS_CREAT, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Dup(oldfd int) (fd int, err error) {
-	r0, _, e1 := RawSyscall(SYS_DUP, uintptr(oldfd), 0, 0)
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Dup2(oldfd int, newfd int) (err error) {
-	_, _, e1 := RawSyscall(SYS_DUP2, uintptr(oldfd), uintptr(newfd), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Dup3(oldfd int, newfd int, flags int) (err error) {
-	_, _, e1 := RawSyscall(SYS_DUP3, uintptr(oldfd), uintptr(newfd), uintptr(flags))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func EpollCreate(size int) (fd int, err error) {
-	r0, _, e1 := RawSyscall(SYS_EPOLL_CREATE, uintptr(size), 0, 0)
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func EpollCreate1(flag int) (fd int, err error) {
-	r0, _, e1 := RawSyscall(SYS_EPOLL_CREATE1, uintptr(flag), 0, 0)
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error) {
-	_, _, e1 := RawSyscall6(SYS_EPOLL_CTL, uintptr(epfd), uintptr(op), uintptr(fd), uintptr(unsafe.Pointer(event)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(events) > 0 {
-		_p0 = unsafe.Pointer(&events[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall6(SYS_EPOLL_WAIT, uintptr(epfd), uintptr(_p0), uintptr(len(events)), uintptr(msec), 0, 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Exit(code int) {
-	Syscall(SYS_EXIT_GROUP, uintptr(code), 0, 0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall6(SYS_FACCESSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fallocate(fd int, mode uint32, off int64, len int64) (err error) {
-	_, _, e1 := Syscall6(SYS_FALLOCATE, uintptr(fd), uintptr(mode), uintptr(off), uintptr(off>>32), uintptr(len), uintptr(len>>32))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchdir(fd int) (err error) {
-	_, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchmod(fd int, mode uint32) (err error) {
-	_, _, e1 := Syscall(SYS_FCHMOD, uintptr(fd), uintptr(mode), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall6(SYS_FCHMODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall6(SYS_FCHOWNAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid), uintptr(flags), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func fcntl(fd int, cmd int, arg int) (val int, err error) {
-	r0, _, e1 := Syscall(SYS_FCNTL, uintptr(fd), uintptr(cmd), uintptr(arg))
-	val = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fdatasync(fd int) (err error) {
-	_, _, e1 := Syscall(SYS_FDATASYNC, uintptr(fd), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Flock(fd int, how int) (err error) {
-	_, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fsync(fd int) (err error) {
-	_, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getdents(fd int, buf []byte) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(buf) > 0 {
-		_p0 = unsafe.Pointer(&buf[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall(SYS_GETDENTS64, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpgid(pid int) (pgid int, err error) {
-	r0, _, e1 := RawSyscall(SYS_GETPGID, uintptr(pid), 0, 0)
-	pgid = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpgrp() (pid int) {
-	r0, _, _ := RawSyscall(SYS_GETPGRP, 0, 0, 0)
-	pid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpid() (pid int) {
-	r0, _, _ := RawSyscall(SYS_GETPID, 0, 0, 0)
-	pid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getppid() (ppid int) {
-	r0, _, _ := RawSyscall(SYS_GETPPID, 0, 0, 0)
-	ppid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpriority(which int, who int) (prio int, err error) {
-	r0, _, e1 := Syscall(SYS_GETPRIORITY, uintptr(which), uintptr(who), 0)
-	prio = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getrusage(who int, rusage *Rusage) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETRUSAGE, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Gettid() (tid int) {
-	r0, _, _ := RawSyscall(SYS_GETTID, 0, 0, 0)
-	tid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getxattr(path string, attr string, dest []byte) (sz int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(attr)
-	if err != nil {
-		return
-	}
-	var _p2 unsafe.Pointer
-	if len(dest) > 0 {
-		_p2 = unsafe.Pointer(&dest[0])
-	} else {
-		_p2 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall6(SYS_GETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(_p2), uintptr(len(dest)), 0, 0)
-	sz = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func InotifyAddWatch(fd int, pathname string, mask uint32) (watchdesc int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(pathname)
-	if err != nil {
-		return
-	}
-	r0, _, e1 := Syscall(SYS_INOTIFY_ADD_WATCH, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(mask))
-	watchdesc = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func InotifyInit() (fd int, err error) {
-	r0, _, e1 := RawSyscall(SYS_INOTIFY_INIT, 0, 0, 0)
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func InotifyInit1(flags int) (fd int, err error) {
-	r0, _, e1 := RawSyscall(SYS_INOTIFY_INIT1, uintptr(flags), 0, 0)
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func InotifyRmWatch(fd int, watchdesc uint32) (success int, err error) {
-	r0, _, e1 := RawSyscall(SYS_INOTIFY_RM_WATCH, uintptr(fd), uintptr(watchdesc), 0)
-	success = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Kill(pid int, sig Signal) (err error) {
-	_, _, e1 := RawSyscall(SYS_KILL, uintptr(pid), uintptr(sig), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Klogctl(typ int, buf []byte) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(buf) > 0 {
-		_p0 = unsafe.Pointer(&buf[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall(SYS_SYSLOG, uintptr(typ), uintptr(_p0), uintptr(len(buf)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Link(oldpath string, newpath string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(oldpath)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(newpath)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_LINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Listxattr(path string, dest []byte) (sz int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 unsafe.Pointer
-	if len(dest) > 0 {
-		_p1 = unsafe.Pointer(&dest[0])
-	} else {
-		_p1 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall(SYS_LISTXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(dest)))
-	sz = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mkdir(path string, mode uint32) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_MKDIR, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mkdirat(dirfd int, path string, mode uint32) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_MKDIRAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mknod(path string, mode uint32, dev int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_MKNOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mknodat(dirfd int, path string, mode uint32, dev int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall6(SYS_MKNODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Nanosleep(time *Timespec, leftover *Timespec) (err error) {
-	_, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Pause() (err error) {
-	_, _, e1 := Syscall(SYS_PAUSE, 0, 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func PivotRoot(newroot string, putold string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(newroot)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(putold)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_PIVOT_ROOT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func prlimit(pid int, resource int, old *Rlimit, newlimit *Rlimit) (err error) {
-	_, _, e1 := RawSyscall6(SYS_PRLIMIT64, uintptr(pid), uintptr(resource), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(newlimit)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func read(fd int, p []byte) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(_p0), uintptr(len(p)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Readlink(path string, buf []byte) (n int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 unsafe.Pointer
-	if len(buf) > 0 {
-		_p1 = unsafe.Pointer(&buf[0])
-	} else {
-		_p1 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall(SYS_READLINK, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Removexattr(path string, attr string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(attr)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_REMOVEXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Rename(oldpath string, newpath string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(oldpath)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(newpath)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_RENAME, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(oldpath)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(newpath)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall6(SYS_RENAMEAT, uintptr(olddirfd), uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Rmdir(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_RMDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setdomainname(p []byte) (err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall(SYS_SETDOMAINNAME, uintptr(_p0), uintptr(len(p)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Sethostname(p []byte) (err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall(SYS_SETHOSTNAME, uintptr(_p0), uintptr(len(p)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setpgid(pid int, pgid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETPGID, uintptr(pid), uintptr(pgid), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setsid() (pid int, err error) {
-	r0, _, e1 := RawSyscall(SYS_SETSID, 0, 0, 0)
-	pid = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Settimeofday(tv *Timeval) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setuid(uid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETUID, uintptr(uid), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setpriority(which int, who int, prio int) (err error) {
-	_, _, e1 := Syscall(SYS_SETPRIORITY, uintptr(which), uintptr(who), uintptr(prio))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setxattr(path string, attr string, data []byte, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(attr)
-	if err != nil {
-		return
-	}
-	var _p2 unsafe.Pointer
-	if len(data) > 0 {
-		_p2 = unsafe.Pointer(&data[0])
-	} else {
-		_p2 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall6(SYS_SETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(_p2), uintptr(len(data)), uintptr(flags), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Symlink(oldpath string, newpath string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(oldpath)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(newpath)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_SYMLINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Sync() {
-	Syscall(SYS_SYNC, 0, 0, 0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Sysinfo(info *Sysinfo_t) (err error) {
-	_, _, e1 := RawSyscall(SYS_SYSINFO, uintptr(unsafe.Pointer(info)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Tee(rfd int, wfd int, len int, flags int) (n int64, err error) {
-	r0, r1, e1 := Syscall6(SYS_TEE, uintptr(rfd), uintptr(wfd), uintptr(len), uintptr(flags), 0, 0)
-	n = int64(int64(r1)<<32 | int64(r0))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Tgkill(tgid int, tid int, sig Signal) (err error) {
-	_, _, e1 := RawSyscall(SYS_TGKILL, uintptr(tgid), uintptr(tid), uintptr(sig))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Times(tms *Tms) (ticks uintptr, err error) {
-	r0, _, e1 := RawSyscall(SYS_TIMES, uintptr(unsafe.Pointer(tms)), 0, 0)
-	ticks = uintptr(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Umask(mask int) (oldmask int) {
-	r0, _, _ := RawSyscall(SYS_UMASK, uintptr(mask), 0, 0)
-	oldmask = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Uname(buf *Utsname) (err error) {
-	_, _, e1 := RawSyscall(SYS_UNAME, uintptr(unsafe.Pointer(buf)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Unlink(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_UNLINK, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Unlinkat(dirfd int, path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_UNLINKAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Unmount(target string, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(target)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_UMOUNT2, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Unshare(flags int) (err error) {
-	_, _, e1 := Syscall(SYS_UNSHARE, uintptr(flags), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Ustat(dev int, ubuf *Ustat_t) (err error) {
-	_, _, e1 := Syscall(SYS_USTAT, uintptr(dev), uintptr(unsafe.Pointer(ubuf)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Utime(path string, buf *Utimbuf) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_UTIME, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(buf)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func write(fd int, p []byte) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func exitThread(code int) (err error) {
-	_, _, e1 := Syscall(SYS_EXIT, uintptr(code), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func readlen(fd int, p *byte, np int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(p)), uintptr(np))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func writelen(fd int, p *byte, np int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(p)), uintptr(np))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func munmap(addr uintptr, length uintptr) (err error) {
-	_, _, e1 := Syscall(SYS_MUNMAP, uintptr(addr), uintptr(length), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Madvise(b []byte, advice int) (err error) {
-	var _p0 unsafe.Pointer
-	if len(b) > 0 {
-		_p0 = unsafe.Pointer(&b[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall(SYS_MADVISE, uintptr(_p0), uintptr(len(b)), uintptr(advice))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mprotect(b []byte, prot int) (err error) {
-	var _p0 unsafe.Pointer
-	if len(b) > 0 {
-		_p0 = unsafe.Pointer(&b[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mlock(b []byte) (err error) {
-	var _p0 unsafe.Pointer
-	if len(b) > 0 {
-		_p0 = unsafe.Pointer(&b[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Munlock(b []byte) (err error) {
-	var _p0 unsafe.Pointer
-	if len(b) > 0 {
-		_p0 = unsafe.Pointer(&b[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mlockall(flags int) (err error) {
-	_, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Munlockall() (err error) {
-	_, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chown(path string, uid int, gid int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_CHOWN32, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchown(fd int, uid int, gid int) (err error) {
-	_, _, e1 := Syscall(SYS_FCHOWN32, uintptr(fd), uintptr(uid), uintptr(gid))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fstat(fd int, stat *Stat_t) (err error) {
-	_, _, e1 := Syscall(SYS_FSTAT64, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Ftruncate(fd int, length int64) (err error) {
-	_, _, e1 := Syscall(SYS_FTRUNCATE64, uintptr(fd), uintptr(length), uintptr(length>>32))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getegid() (egid int) {
-	r0, _, _ := RawSyscall(SYS_GETEGID32, 0, 0, 0)
-	egid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Geteuid() (euid int) {
-	r0, _, _ := RawSyscall(SYS_GETEUID32, 0, 0, 0)
-	euid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getgid() (gid int) {
-	r0, _, _ := RawSyscall(SYS_GETGID32, 0, 0, 0)
-	gid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getuid() (uid int) {
-	r0, _, _ := RawSyscall(SYS_GETUID32, 0, 0, 0)
-	uid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Ioperm(from int, num int, on int) (err error) {
-	_, _, e1 := Syscall(SYS_IOPERM, uintptr(from), uintptr(num), uintptr(on))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Iopl(level int) (err error) {
-	_, _, e1 := Syscall(SYS_IOPL, uintptr(level), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Lchown(path string, uid int, gid int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_LCHOWN32, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Lstat(path string, stat *Stat_t) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_LSTAT64, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Pread(fd int, p []byte, offset int64) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall6(SYS_PREAD64, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), uintptr(offset>>32), 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall6(SYS_PWRITE64, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), uintptr(offset>>32), 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
-	r0, _, e1 := Syscall6(SYS_SENDFILE64, uintptr(outfd), uintptr(infd), uintptr(unsafe.Pointer(offset)), uintptr(count), 0, 0)
-	written = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setfsgid(gid int) (err error) {
-	_, _, e1 := Syscall(SYS_SETFSGID32, uintptr(gid), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setfsuid(uid int) (err error) {
-	_, _, e1 := Syscall(SYS_SETFSUID32, uintptr(uid), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setgid(gid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETGID32, uintptr(gid), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setregid(rgid int, egid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETREGID32, uintptr(rgid), uintptr(egid), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setresgid(rgid int, egid int, sgid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETRESGID32, uintptr(rgid), uintptr(egid), uintptr(sgid))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setresuid(ruid int, euid int, suid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETRESUID32, uintptr(ruid), uintptr(euid), uintptr(suid))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setreuid(ruid int, euid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETREUID32, uintptr(ruid), uintptr(euid), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error) {
-	r0, _, e1 := Syscall6(SYS_SPLICE, uintptr(rfd), uintptr(unsafe.Pointer(roff)), uintptr(wfd), uintptr(unsafe.Pointer(woff)), uintptr(len), uintptr(flags))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Stat(path string, stat *Stat_t) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_STAT64, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func SyncFileRange(fd int, off int64, n int64, flags int) (err error) {
-	_, _, e1 := Syscall6(SYS_SYNC_FILE_RANGE, uintptr(fd), uintptr(off), uintptr(off>>32), uintptr(n), uintptr(n>>32), uintptr(flags))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Truncate(path string, length int64) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_TRUNCATE64, uintptr(unsafe.Pointer(_p0)), uintptr(length), uintptr(length>>32))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getgroups(n int, list *_Gid_t) (nn int, err error) {
-	r0, _, e1 := RawSyscall(SYS_GETGROUPS32, uintptr(n), uintptr(unsafe.Pointer(list)), 0)
-	nn = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func setgroups(n int, list *_Gid_t) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETGROUPS32, uintptr(n), uintptr(unsafe.Pointer(list)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) {
-	r0, _, e1 := Syscall6(SYS__NEWSELECT, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func mmap2(addr uintptr, length uintptr, prot int, flags int, fd int, pageOffset uintptr) (xaddr uintptr, err error) {
-	r0, _, e1 := Syscall6(SYS_MMAP2, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flags), uintptr(fd), uintptr(pageOffset))
-	xaddr = uintptr(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getrlimit(resource int, rlim *rlimit32) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETRLIMIT, uintptr(resource), uintptr(unsafe.Pointer(rlim)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func setrlimit(resource int, rlim *rlimit32) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(resource), uintptr(unsafe.Pointer(rlim)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Gettimeofday(tv *Timeval) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Time(t *Time_t) (tt Time_t, err error) {
-	r0, _, e1 := RawSyscall(SYS_TIME, uintptr(unsafe.Pointer(t)), 0, 0)
-	tt = Time_t(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
diff --git a/src/pkg/syscall/zsyscall_linux_amd64.go b/src/pkg/syscall/zsyscall_linux_amd64.go
deleted file mode 100644
index c65448e..0000000
--- a/src/pkg/syscall/zsyscall_linux_amd64.go
+++ /dev/null
@@ -1,1930 +0,0 @@
-// mksyscall.pl syscall_linux.go syscall_linux_amd64.go
-// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
-
-package syscall
-
-import "unsafe"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func open(path string, mode int, perm uint32) (fd int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	r0, _, e1 := Syscall6(SYS_OPENAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), uintptr(mode), 0, 0)
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func pipe(p *[2]_C_int) (err error) {
-	_, _, e1 := RawSyscall(SYS_PIPE, uintptr(unsafe.Pointer(p)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func pipe2(p *[2]_C_int, flags int) (err error) {
-	_, _, e1 := RawSyscall(SYS_PIPE2, uintptr(unsafe.Pointer(p)), uintptr(flags), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func utimes(path string, times *[2]Timeval) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func utimensat(dirfd int, path string, times *[2]Timespec) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func futimesat(dirfd int, path *byte, times *[2]Timeval) (err error) {
-	_, _, e1 := Syscall(SYS_FUTIMESAT, uintptr(dirfd), uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(times)))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getcwd(buf []byte) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(buf) > 0 {
-		_p0 = unsafe.Pointer(&buf[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall(SYS_GETCWD, uintptr(_p0), uintptr(len(buf)), 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) {
-	r0, _, e1 := Syscall6(SYS_WAIT4, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0)
-	wpid = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func ptrace(request int, pid int, addr uintptr, data uintptr) (err error) {
-	_, _, e1 := Syscall6(SYS_PTRACE, uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func reboot(magic1 uint, magic2 uint, cmd int, arg string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(arg)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall6(SYS_REBOOT, uintptr(magic1), uintptr(magic2), uintptr(cmd), uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func mount(source string, target string, fstype string, flags uintptr, data *byte) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(source)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(target)
-	if err != nil {
-		return
-	}
-	var _p2 *byte
-	_p2, err = BytePtrFromString(fstype)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall6(SYS_MOUNT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(unsafe.Pointer(_p2)), uintptr(flags), uintptr(unsafe.Pointer(data)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Access(path string, mode uint32) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_ACCESS, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Acct(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_ACCT, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Adjtimex(buf *Timex) (state int, err error) {
-	r0, _, e1 := Syscall(SYS_ADJTIMEX, uintptr(unsafe.Pointer(buf)), 0, 0)
-	state = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chdir(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chmod(path string, mode uint32) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_CHMOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chroot(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_CHROOT, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Close(fd int) (err error) {
-	_, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Creat(path string, mode uint32) (fd int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	r0, _, e1 := Syscall(SYS_CREAT, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Dup(oldfd int) (fd int, err error) {
-	r0, _, e1 := RawSyscall(SYS_DUP, uintptr(oldfd), 0, 0)
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Dup2(oldfd int, newfd int) (err error) {
-	_, _, e1 := RawSyscall(SYS_DUP2, uintptr(oldfd), uintptr(newfd), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Dup3(oldfd int, newfd int, flags int) (err error) {
-	_, _, e1 := RawSyscall(SYS_DUP3, uintptr(oldfd), uintptr(newfd), uintptr(flags))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func EpollCreate(size int) (fd int, err error) {
-	r0, _, e1 := RawSyscall(SYS_EPOLL_CREATE, uintptr(size), 0, 0)
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func EpollCreate1(flag int) (fd int, err error) {
-	r0, _, e1 := RawSyscall(SYS_EPOLL_CREATE1, uintptr(flag), 0, 0)
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error) {
-	_, _, e1 := RawSyscall6(SYS_EPOLL_CTL, uintptr(epfd), uintptr(op), uintptr(fd), uintptr(unsafe.Pointer(event)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(events) > 0 {
-		_p0 = unsafe.Pointer(&events[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall6(SYS_EPOLL_WAIT, uintptr(epfd), uintptr(_p0), uintptr(len(events)), uintptr(msec), 0, 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Exit(code int) {
-	Syscall(SYS_EXIT_GROUP, uintptr(code), 0, 0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall6(SYS_FACCESSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fallocate(fd int, mode uint32, off int64, len int64) (err error) {
-	_, _, e1 := Syscall6(SYS_FALLOCATE, uintptr(fd), uintptr(mode), uintptr(off), uintptr(len), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchdir(fd int) (err error) {
-	_, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchmod(fd int, mode uint32) (err error) {
-	_, _, e1 := Syscall(SYS_FCHMOD, uintptr(fd), uintptr(mode), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall6(SYS_FCHMODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall6(SYS_FCHOWNAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid), uintptr(flags), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func fcntl(fd int, cmd int, arg int) (val int, err error) {
-	r0, _, e1 := Syscall(SYS_FCNTL, uintptr(fd), uintptr(cmd), uintptr(arg))
-	val = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fdatasync(fd int) (err error) {
-	_, _, e1 := Syscall(SYS_FDATASYNC, uintptr(fd), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Flock(fd int, how int) (err error) {
-	_, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fsync(fd int) (err error) {
-	_, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getdents(fd int, buf []byte) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(buf) > 0 {
-		_p0 = unsafe.Pointer(&buf[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall(SYS_GETDENTS64, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpgid(pid int) (pgid int, err error) {
-	r0, _, e1 := RawSyscall(SYS_GETPGID, uintptr(pid), 0, 0)
-	pgid = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpgrp() (pid int) {
-	r0, _, _ := RawSyscall(SYS_GETPGRP, 0, 0, 0)
-	pid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpid() (pid int) {
-	r0, _, _ := RawSyscall(SYS_GETPID, 0, 0, 0)
-	pid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getppid() (ppid int) {
-	r0, _, _ := RawSyscall(SYS_GETPPID, 0, 0, 0)
-	ppid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpriority(which int, who int) (prio int, err error) {
-	r0, _, e1 := Syscall(SYS_GETPRIORITY, uintptr(which), uintptr(who), 0)
-	prio = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getrusage(who int, rusage *Rusage) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETRUSAGE, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Gettid() (tid int) {
-	r0, _, _ := RawSyscall(SYS_GETTID, 0, 0, 0)
-	tid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getxattr(path string, attr string, dest []byte) (sz int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(attr)
-	if err != nil {
-		return
-	}
-	var _p2 unsafe.Pointer
-	if len(dest) > 0 {
-		_p2 = unsafe.Pointer(&dest[0])
-	} else {
-		_p2 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall6(SYS_GETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(_p2), uintptr(len(dest)), 0, 0)
-	sz = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func InotifyAddWatch(fd int, pathname string, mask uint32) (watchdesc int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(pathname)
-	if err != nil {
-		return
-	}
-	r0, _, e1 := Syscall(SYS_INOTIFY_ADD_WATCH, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(mask))
-	watchdesc = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func InotifyInit() (fd int, err error) {
-	r0, _, e1 := RawSyscall(SYS_INOTIFY_INIT, 0, 0, 0)
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func InotifyInit1(flags int) (fd int, err error) {
-	r0, _, e1 := RawSyscall(SYS_INOTIFY_INIT1, uintptr(flags), 0, 0)
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func InotifyRmWatch(fd int, watchdesc uint32) (success int, err error) {
-	r0, _, e1 := RawSyscall(SYS_INOTIFY_RM_WATCH, uintptr(fd), uintptr(watchdesc), 0)
-	success = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Kill(pid int, sig Signal) (err error) {
-	_, _, e1 := RawSyscall(SYS_KILL, uintptr(pid), uintptr(sig), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Klogctl(typ int, buf []byte) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(buf) > 0 {
-		_p0 = unsafe.Pointer(&buf[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall(SYS_SYSLOG, uintptr(typ), uintptr(_p0), uintptr(len(buf)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Link(oldpath string, newpath string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(oldpath)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(newpath)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_LINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Listxattr(path string, dest []byte) (sz int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 unsafe.Pointer
-	if len(dest) > 0 {
-		_p1 = unsafe.Pointer(&dest[0])
-	} else {
-		_p1 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall(SYS_LISTXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(dest)))
-	sz = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mkdir(path string, mode uint32) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_MKDIR, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mkdirat(dirfd int, path string, mode uint32) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_MKDIRAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mknod(path string, mode uint32, dev int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_MKNOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mknodat(dirfd int, path string, mode uint32, dev int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall6(SYS_MKNODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Nanosleep(time *Timespec, leftover *Timespec) (err error) {
-	_, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Pause() (err error) {
-	_, _, e1 := Syscall(SYS_PAUSE, 0, 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func PivotRoot(newroot string, putold string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(newroot)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(putold)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_PIVOT_ROOT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func prlimit(pid int, resource int, old *Rlimit, newlimit *Rlimit) (err error) {
-	_, _, e1 := RawSyscall6(SYS_PRLIMIT64, uintptr(pid), uintptr(resource), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(newlimit)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func read(fd int, p []byte) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(_p0), uintptr(len(p)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Readlink(path string, buf []byte) (n int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 unsafe.Pointer
-	if len(buf) > 0 {
-		_p1 = unsafe.Pointer(&buf[0])
-	} else {
-		_p1 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall(SYS_READLINK, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Removexattr(path string, attr string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(attr)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_REMOVEXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Rename(oldpath string, newpath string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(oldpath)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(newpath)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_RENAME, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(oldpath)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(newpath)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall6(SYS_RENAMEAT, uintptr(olddirfd), uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Rmdir(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_RMDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setdomainname(p []byte) (err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall(SYS_SETDOMAINNAME, uintptr(_p0), uintptr(len(p)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Sethostname(p []byte) (err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall(SYS_SETHOSTNAME, uintptr(_p0), uintptr(len(p)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setpgid(pid int, pgid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETPGID, uintptr(pid), uintptr(pgid), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setsid() (pid int, err error) {
-	r0, _, e1 := RawSyscall(SYS_SETSID, 0, 0, 0)
-	pid = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Settimeofday(tv *Timeval) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setuid(uid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETUID, uintptr(uid), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setpriority(which int, who int, prio int) (err error) {
-	_, _, e1 := Syscall(SYS_SETPRIORITY, uintptr(which), uintptr(who), uintptr(prio))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setxattr(path string, attr string, data []byte, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(attr)
-	if err != nil {
-		return
-	}
-	var _p2 unsafe.Pointer
-	if len(data) > 0 {
-		_p2 = unsafe.Pointer(&data[0])
-	} else {
-		_p2 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall6(SYS_SETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(_p2), uintptr(len(data)), uintptr(flags), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Symlink(oldpath string, newpath string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(oldpath)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(newpath)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_SYMLINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Sync() {
-	Syscall(SYS_SYNC, 0, 0, 0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Sysinfo(info *Sysinfo_t) (err error) {
-	_, _, e1 := RawSyscall(SYS_SYSINFO, uintptr(unsafe.Pointer(info)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Tee(rfd int, wfd int, len int, flags int) (n int64, err error) {
-	r0, _, e1 := Syscall6(SYS_TEE, uintptr(rfd), uintptr(wfd), uintptr(len), uintptr(flags), 0, 0)
-	n = int64(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Tgkill(tgid int, tid int, sig Signal) (err error) {
-	_, _, e1 := RawSyscall(SYS_TGKILL, uintptr(tgid), uintptr(tid), uintptr(sig))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Times(tms *Tms) (ticks uintptr, err error) {
-	r0, _, e1 := RawSyscall(SYS_TIMES, uintptr(unsafe.Pointer(tms)), 0, 0)
-	ticks = uintptr(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Umask(mask int) (oldmask int) {
-	r0, _, _ := RawSyscall(SYS_UMASK, uintptr(mask), 0, 0)
-	oldmask = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Uname(buf *Utsname) (err error) {
-	_, _, e1 := RawSyscall(SYS_UNAME, uintptr(unsafe.Pointer(buf)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Unlink(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_UNLINK, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Unlinkat(dirfd int, path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_UNLINKAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Unmount(target string, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(target)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_UMOUNT2, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Unshare(flags int) (err error) {
-	_, _, e1 := Syscall(SYS_UNSHARE, uintptr(flags), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Ustat(dev int, ubuf *Ustat_t) (err error) {
-	_, _, e1 := Syscall(SYS_USTAT, uintptr(dev), uintptr(unsafe.Pointer(ubuf)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Utime(path string, buf *Utimbuf) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_UTIME, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(buf)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func write(fd int, p []byte) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func exitThread(code int) (err error) {
-	_, _, e1 := Syscall(SYS_EXIT, uintptr(code), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func readlen(fd int, p *byte, np int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(p)), uintptr(np))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func writelen(fd int, p *byte, np int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(p)), uintptr(np))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func munmap(addr uintptr, length uintptr) (err error) {
-	_, _, e1 := Syscall(SYS_MUNMAP, uintptr(addr), uintptr(length), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Madvise(b []byte, advice int) (err error) {
-	var _p0 unsafe.Pointer
-	if len(b) > 0 {
-		_p0 = unsafe.Pointer(&b[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall(SYS_MADVISE, uintptr(_p0), uintptr(len(b)), uintptr(advice))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mprotect(b []byte, prot int) (err error) {
-	var _p0 unsafe.Pointer
-	if len(b) > 0 {
-		_p0 = unsafe.Pointer(&b[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mlock(b []byte) (err error) {
-	var _p0 unsafe.Pointer
-	if len(b) > 0 {
-		_p0 = unsafe.Pointer(&b[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Munlock(b []byte) (err error) {
-	var _p0 unsafe.Pointer
-	if len(b) > 0 {
-		_p0 = unsafe.Pointer(&b[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mlockall(flags int) (err error) {
-	_, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Munlockall() (err error) {
-	_, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chown(path string, uid int, gid int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_CHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchown(fd int, uid int, gid int) (err error) {
-	_, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fstat(fd int, stat *Stat_t) (err error) {
-	_, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fstatfs(fd int, buf *Statfs_t) (err error) {
-	_, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(buf)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Ftruncate(fd int, length int64) (err error) {
-	_, _, e1 := Syscall(SYS_FTRUNCATE, uintptr(fd), uintptr(length), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getegid() (egid int) {
-	r0, _, _ := RawSyscall(SYS_GETEGID, 0, 0, 0)
-	egid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Geteuid() (euid int) {
-	r0, _, _ := RawSyscall(SYS_GETEUID, 0, 0, 0)
-	euid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getgid() (gid int) {
-	r0, _, _ := RawSyscall(SYS_GETGID, 0, 0, 0)
-	gid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getrlimit(resource int, rlim *Rlimit) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETRLIMIT, uintptr(resource), uintptr(unsafe.Pointer(rlim)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getuid() (uid int) {
-	r0, _, _ := RawSyscall(SYS_GETUID, 0, 0, 0)
-	uid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Ioperm(from int, num int, on int) (err error) {
-	_, _, e1 := Syscall(SYS_IOPERM, uintptr(from), uintptr(num), uintptr(on))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Iopl(level int) (err error) {
-	_, _, e1 := Syscall(SYS_IOPL, uintptr(level), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Lchown(path string, uid int, gid int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_LCHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Listen(s int, n int) (err error) {
-	_, _, e1 := Syscall(SYS_LISTEN, uintptr(s), uintptr(n), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Lstat(path string, stat *Stat_t) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_LSTAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Pread(fd int, p []byte, offset int64) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall6(SYS_PREAD64, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall6(SYS_PWRITE64, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Seek(fd int, offset int64, whence int) (off int64, err error) {
-	r0, _, e1 := Syscall(SYS_LSEEK, uintptr(fd), uintptr(offset), uintptr(whence))
-	off = int64(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) {
-	r0, _, e1 := Syscall6(SYS_SELECT, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
-	r0, _, e1 := Syscall6(SYS_SENDFILE, uintptr(outfd), uintptr(infd), uintptr(unsafe.Pointer(offset)), uintptr(count), 0, 0)
-	written = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setfsgid(gid int) (err error) {
-	_, _, e1 := Syscall(SYS_SETFSGID, uintptr(gid), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setfsuid(uid int) (err error) {
-	_, _, e1 := Syscall(SYS_SETFSUID, uintptr(uid), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setgid(gid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETGID, uintptr(gid), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setregid(rgid int, egid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setresgid(rgid int, egid int, sgid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETRESGID, uintptr(rgid), uintptr(egid), uintptr(sgid))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setresuid(ruid int, euid int, suid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETRESUID, uintptr(ruid), uintptr(euid), uintptr(suid))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setrlimit(resource int, rlim *Rlimit) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(resource), uintptr(unsafe.Pointer(rlim)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setreuid(ruid int, euid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Shutdown(fd int, how int) (err error) {
-	_, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(fd), uintptr(how), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error) {
-	r0, _, e1 := Syscall6(SYS_SPLICE, uintptr(rfd), uintptr(unsafe.Pointer(roff)), uintptr(wfd), uintptr(unsafe.Pointer(woff)), uintptr(len), uintptr(flags))
-	n = int64(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Stat(path string, stat *Stat_t) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Statfs(path string, buf *Statfs_t) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_STATFS, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(buf)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func SyncFileRange(fd int, off int64, n int64, flags int) (err error) {
-	_, _, e1 := Syscall6(SYS_SYNC_FILE_RANGE, uintptr(fd), uintptr(off), uintptr(n), uintptr(flags), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Truncate(path string, length int64) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_TRUNCATE, uintptr(unsafe.Pointer(_p0)), uintptr(length), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
-	r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) {
-	r0, _, e1 := Syscall6(SYS_ACCEPT4, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0)
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
-	_, _, e1 := Syscall(SYS_BIND, uintptr(s), uintptr(addr), uintptr(addrlen))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
-	_, _, e1 := Syscall(SYS_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getgroups(n int, list *_Gid_t) (nn int, err error) {
-	r0, _, e1 := RawSyscall(SYS_GETGROUPS, uintptr(n), uintptr(unsafe.Pointer(list)), 0)
-	nn = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func setgroups(n int, list *_Gid_t) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETGROUPS, uintptr(n), uintptr(unsafe.Pointer(list)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) {
-	_, _, e1 := Syscall6(SYS_GETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) {
-	_, _, e1 := Syscall6(SYS_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func socket(domain int, typ int, proto int) (fd int, err error) {
-	r0, _, e1 := RawSyscall(SYS_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto))
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) {
-	_, _, e1 := RawSyscall6(SYS_SOCKETPAIR, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETPEERNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETSOCKNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall6(SYS_RECVFROM, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) {
-	var _p0 unsafe.Pointer
-	if len(buf) > 0 {
-		_p0 = unsafe.Pointer(&buf[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall6(SYS_SENDTO, uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_RECVMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_SENDMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) {
-	r0, _, e1 := Syscall6(SYS_MMAP, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flags), uintptr(fd), uintptr(offset))
-	xaddr = uintptr(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
diff --git a/src/pkg/syscall/zsyscall_linux_arm.go b/src/pkg/syscall/zsyscall_linux_arm.go
deleted file mode 100644
index a970ce6..0000000
--- a/src/pkg/syscall/zsyscall_linux_arm.go
+++ /dev/null
@@ -1,1885 +0,0 @@
-// mksyscall.pl -l32 -arm syscall_linux.go syscall_linux_arm.go
-// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
-
-package syscall
-
-import "unsafe"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func open(path string, mode int, perm uint32) (fd int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	r0, _, e1 := Syscall6(SYS_OPENAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), uintptr(mode), 0, 0)
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func pipe(p *[2]_C_int) (err error) {
-	_, _, e1 := RawSyscall(SYS_PIPE, uintptr(unsafe.Pointer(p)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func pipe2(p *[2]_C_int, flags int) (err error) {
-	_, _, e1 := RawSyscall(SYS_PIPE2, uintptr(unsafe.Pointer(p)), uintptr(flags), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func utimes(path string, times *[2]Timeval) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func utimensat(dirfd int, path string, times *[2]Timespec) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func futimesat(dirfd int, path *byte, times *[2]Timeval) (err error) {
-	_, _, e1 := Syscall(SYS_FUTIMESAT, uintptr(dirfd), uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(times)))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getcwd(buf []byte) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(buf) > 0 {
-		_p0 = unsafe.Pointer(&buf[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall(SYS_GETCWD, uintptr(_p0), uintptr(len(buf)), 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) {
-	r0, _, e1 := Syscall6(SYS_WAIT4, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0)
-	wpid = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func ptrace(request int, pid int, addr uintptr, data uintptr) (err error) {
-	_, _, e1 := Syscall6(SYS_PTRACE, uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func reboot(magic1 uint, magic2 uint, cmd int, arg string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(arg)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall6(SYS_REBOOT, uintptr(magic1), uintptr(magic2), uintptr(cmd), uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func mount(source string, target string, fstype string, flags uintptr, data *byte) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(source)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(target)
-	if err != nil {
-		return
-	}
-	var _p2 *byte
-	_p2, err = BytePtrFromString(fstype)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall6(SYS_MOUNT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(unsafe.Pointer(_p2)), uintptr(flags), uintptr(unsafe.Pointer(data)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Access(path string, mode uint32) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_ACCESS, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Acct(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_ACCT, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Adjtimex(buf *Timex) (state int, err error) {
-	r0, _, e1 := Syscall(SYS_ADJTIMEX, uintptr(unsafe.Pointer(buf)), 0, 0)
-	state = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chdir(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chmod(path string, mode uint32) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_CHMOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chroot(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_CHROOT, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Close(fd int) (err error) {
-	_, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Creat(path string, mode uint32) (fd int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	r0, _, e1 := Syscall(SYS_CREAT, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Dup(oldfd int) (fd int, err error) {
-	r0, _, e1 := RawSyscall(SYS_DUP, uintptr(oldfd), 0, 0)
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Dup2(oldfd int, newfd int) (err error) {
-	_, _, e1 := RawSyscall(SYS_DUP2, uintptr(oldfd), uintptr(newfd), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Dup3(oldfd int, newfd int, flags int) (err error) {
-	_, _, e1 := RawSyscall(SYS_DUP3, uintptr(oldfd), uintptr(newfd), uintptr(flags))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func EpollCreate(size int) (fd int, err error) {
-	r0, _, e1 := RawSyscall(SYS_EPOLL_CREATE, uintptr(size), 0, 0)
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func EpollCreate1(flag int) (fd int, err error) {
-	r0, _, e1 := RawSyscall(SYS_EPOLL_CREATE1, uintptr(flag), 0, 0)
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error) {
-	_, _, e1 := RawSyscall6(SYS_EPOLL_CTL, uintptr(epfd), uintptr(op), uintptr(fd), uintptr(unsafe.Pointer(event)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(events) > 0 {
-		_p0 = unsafe.Pointer(&events[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall6(SYS_EPOLL_WAIT, uintptr(epfd), uintptr(_p0), uintptr(len(events)), uintptr(msec), 0, 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Exit(code int) {
-	Syscall(SYS_EXIT_GROUP, uintptr(code), 0, 0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall6(SYS_FACCESSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fallocate(fd int, mode uint32, off int64, len int64) (err error) {
-	_, _, e1 := Syscall6(SYS_FALLOCATE, uintptr(fd), uintptr(mode), uintptr(off), uintptr(off>>32), uintptr(len), uintptr(len>>32))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchdir(fd int) (err error) {
-	_, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchmod(fd int, mode uint32) (err error) {
-	_, _, e1 := Syscall(SYS_FCHMOD, uintptr(fd), uintptr(mode), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall6(SYS_FCHMODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall6(SYS_FCHOWNAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid), uintptr(flags), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func fcntl(fd int, cmd int, arg int) (val int, err error) {
-	r0, _, e1 := Syscall(SYS_FCNTL, uintptr(fd), uintptr(cmd), uintptr(arg))
-	val = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fdatasync(fd int) (err error) {
-	_, _, e1 := Syscall(SYS_FDATASYNC, uintptr(fd), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Flock(fd int, how int) (err error) {
-	_, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fsync(fd int) (err error) {
-	_, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getdents(fd int, buf []byte) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(buf) > 0 {
-		_p0 = unsafe.Pointer(&buf[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall(SYS_GETDENTS64, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpgid(pid int) (pgid int, err error) {
-	r0, _, e1 := RawSyscall(SYS_GETPGID, uintptr(pid), 0, 0)
-	pgid = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpgrp() (pid int) {
-	r0, _, _ := RawSyscall(SYS_GETPGRP, 0, 0, 0)
-	pid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpid() (pid int) {
-	r0, _, _ := RawSyscall(SYS_GETPID, 0, 0, 0)
-	pid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getppid() (ppid int) {
-	r0, _, _ := RawSyscall(SYS_GETPPID, 0, 0, 0)
-	ppid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpriority(which int, who int) (prio int, err error) {
-	r0, _, e1 := Syscall(SYS_GETPRIORITY, uintptr(which), uintptr(who), 0)
-	prio = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getrusage(who int, rusage *Rusage) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETRUSAGE, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Gettid() (tid int) {
-	r0, _, _ := RawSyscall(SYS_GETTID, 0, 0, 0)
-	tid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getxattr(path string, attr string, dest []byte) (sz int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(attr)
-	if err != nil {
-		return
-	}
-	var _p2 unsafe.Pointer
-	if len(dest) > 0 {
-		_p2 = unsafe.Pointer(&dest[0])
-	} else {
-		_p2 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall6(SYS_GETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(_p2), uintptr(len(dest)), 0, 0)
-	sz = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func InotifyAddWatch(fd int, pathname string, mask uint32) (watchdesc int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(pathname)
-	if err != nil {
-		return
-	}
-	r0, _, e1 := Syscall(SYS_INOTIFY_ADD_WATCH, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(mask))
-	watchdesc = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func InotifyInit() (fd int, err error) {
-	r0, _, e1 := RawSyscall(SYS_INOTIFY_INIT, 0, 0, 0)
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func InotifyInit1(flags int) (fd int, err error) {
-	r0, _, e1 := RawSyscall(SYS_INOTIFY_INIT1, uintptr(flags), 0, 0)
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func InotifyRmWatch(fd int, watchdesc uint32) (success int, err error) {
-	r0, _, e1 := RawSyscall(SYS_INOTIFY_RM_WATCH, uintptr(fd), uintptr(watchdesc), 0)
-	success = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Kill(pid int, sig Signal) (err error) {
-	_, _, e1 := RawSyscall(SYS_KILL, uintptr(pid), uintptr(sig), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Klogctl(typ int, buf []byte) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(buf) > 0 {
-		_p0 = unsafe.Pointer(&buf[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall(SYS_SYSLOG, uintptr(typ), uintptr(_p0), uintptr(len(buf)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Link(oldpath string, newpath string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(oldpath)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(newpath)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_LINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Listxattr(path string, dest []byte) (sz int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 unsafe.Pointer
-	if len(dest) > 0 {
-		_p1 = unsafe.Pointer(&dest[0])
-	} else {
-		_p1 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall(SYS_LISTXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(dest)))
-	sz = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mkdir(path string, mode uint32) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_MKDIR, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mkdirat(dirfd int, path string, mode uint32) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_MKDIRAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mknod(path string, mode uint32, dev int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_MKNOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mknodat(dirfd int, path string, mode uint32, dev int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall6(SYS_MKNODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Nanosleep(time *Timespec, leftover *Timespec) (err error) {
-	_, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Pause() (err error) {
-	_, _, e1 := Syscall(SYS_PAUSE, 0, 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func PivotRoot(newroot string, putold string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(newroot)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(putold)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_PIVOT_ROOT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func prlimit(pid int, resource int, old *Rlimit, newlimit *Rlimit) (err error) {
-	_, _, e1 := RawSyscall6(SYS_PRLIMIT64, uintptr(pid), uintptr(resource), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(newlimit)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func read(fd int, p []byte) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(_p0), uintptr(len(p)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Readlink(path string, buf []byte) (n int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 unsafe.Pointer
-	if len(buf) > 0 {
-		_p1 = unsafe.Pointer(&buf[0])
-	} else {
-		_p1 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall(SYS_READLINK, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Removexattr(path string, attr string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(attr)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_REMOVEXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Rename(oldpath string, newpath string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(oldpath)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(newpath)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_RENAME, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(oldpath)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(newpath)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall6(SYS_RENAMEAT, uintptr(olddirfd), uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Rmdir(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_RMDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setdomainname(p []byte) (err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall(SYS_SETDOMAINNAME, uintptr(_p0), uintptr(len(p)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Sethostname(p []byte) (err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall(SYS_SETHOSTNAME, uintptr(_p0), uintptr(len(p)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setpgid(pid int, pgid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETPGID, uintptr(pid), uintptr(pgid), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setsid() (pid int, err error) {
-	r0, _, e1 := RawSyscall(SYS_SETSID, 0, 0, 0)
-	pid = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Settimeofday(tv *Timeval) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setuid(uid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETUID, uintptr(uid), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setpriority(which int, who int, prio int) (err error) {
-	_, _, e1 := Syscall(SYS_SETPRIORITY, uintptr(which), uintptr(who), uintptr(prio))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setxattr(path string, attr string, data []byte, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(attr)
-	if err != nil {
-		return
-	}
-	var _p2 unsafe.Pointer
-	if len(data) > 0 {
-		_p2 = unsafe.Pointer(&data[0])
-	} else {
-		_p2 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall6(SYS_SETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(_p2), uintptr(len(data)), uintptr(flags), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Symlink(oldpath string, newpath string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(oldpath)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(newpath)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_SYMLINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Sync() {
-	Syscall(SYS_SYNC, 0, 0, 0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Sysinfo(info *Sysinfo_t) (err error) {
-	_, _, e1 := RawSyscall(SYS_SYSINFO, uintptr(unsafe.Pointer(info)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Tee(rfd int, wfd int, len int, flags int) (n int64, err error) {
-	r0, r1, e1 := Syscall6(SYS_TEE, uintptr(rfd), uintptr(wfd), uintptr(len), uintptr(flags), 0, 0)
-	n = int64(int64(r1)<<32 | int64(r0))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Tgkill(tgid int, tid int, sig Signal) (err error) {
-	_, _, e1 := RawSyscall(SYS_TGKILL, uintptr(tgid), uintptr(tid), uintptr(sig))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Times(tms *Tms) (ticks uintptr, err error) {
-	r0, _, e1 := RawSyscall(SYS_TIMES, uintptr(unsafe.Pointer(tms)), 0, 0)
-	ticks = uintptr(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Umask(mask int) (oldmask int) {
-	r0, _, _ := RawSyscall(SYS_UMASK, uintptr(mask), 0, 0)
-	oldmask = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Uname(buf *Utsname) (err error) {
-	_, _, e1 := RawSyscall(SYS_UNAME, uintptr(unsafe.Pointer(buf)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Unlink(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_UNLINK, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Unlinkat(dirfd int, path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_UNLINKAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Unmount(target string, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(target)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_UMOUNT2, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Unshare(flags int) (err error) {
-	_, _, e1 := Syscall(SYS_UNSHARE, uintptr(flags), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Ustat(dev int, ubuf *Ustat_t) (err error) {
-	_, _, e1 := Syscall(SYS_USTAT, uintptr(dev), uintptr(unsafe.Pointer(ubuf)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Utime(path string, buf *Utimbuf) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_UTIME, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(buf)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func write(fd int, p []byte) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func exitThread(code int) (err error) {
-	_, _, e1 := Syscall(SYS_EXIT, uintptr(code), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func readlen(fd int, p *byte, np int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(p)), uintptr(np))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func writelen(fd int, p *byte, np int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(p)), uintptr(np))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func munmap(addr uintptr, length uintptr) (err error) {
-	_, _, e1 := Syscall(SYS_MUNMAP, uintptr(addr), uintptr(length), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Madvise(b []byte, advice int) (err error) {
-	var _p0 unsafe.Pointer
-	if len(b) > 0 {
-		_p0 = unsafe.Pointer(&b[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall(SYS_MADVISE, uintptr(_p0), uintptr(len(b)), uintptr(advice))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mprotect(b []byte, prot int) (err error) {
-	var _p0 unsafe.Pointer
-	if len(b) > 0 {
-		_p0 = unsafe.Pointer(&b[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mlock(b []byte) (err error) {
-	var _p0 unsafe.Pointer
-	if len(b) > 0 {
-		_p0 = unsafe.Pointer(&b[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Munlock(b []byte) (err error) {
-	var _p0 unsafe.Pointer
-	if len(b) > 0 {
-		_p0 = unsafe.Pointer(&b[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mlockall(flags int) (err error) {
-	_, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Munlockall() (err error) {
-	_, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
-	r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) {
-	r0, _, e1 := Syscall6(SYS_ACCEPT4, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0)
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
-	_, _, e1 := Syscall(SYS_BIND, uintptr(s), uintptr(addr), uintptr(addrlen))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
-	_, _, e1 := Syscall(SYS_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getgroups(n int, list *_Gid_t) (nn int, err error) {
-	r0, _, e1 := RawSyscall(SYS_GETGROUPS32, uintptr(n), uintptr(unsafe.Pointer(list)), 0)
-	nn = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func setgroups(n int, list *_Gid_t) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETGROUPS32, uintptr(n), uintptr(unsafe.Pointer(list)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) {
-	_, _, e1 := Syscall6(SYS_GETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) {
-	_, _, e1 := Syscall6(SYS_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func socket(domain int, typ int, proto int) (fd int, err error) {
-	r0, _, e1 := RawSyscall(SYS_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto))
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETPEERNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETSOCKNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall6(SYS_RECVFROM, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) {
-	var _p0 unsafe.Pointer
-	if len(buf) > 0 {
-		_p0 = unsafe.Pointer(&buf[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall6(SYS_SENDTO, uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func socketpair(domain int, typ int, flags int, fd *[2]int32) (err error) {
-	_, _, e1 := RawSyscall6(SYS_SOCKETPAIR, uintptr(domain), uintptr(typ), uintptr(flags), uintptr(unsafe.Pointer(fd)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_RECVMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_SENDMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chown(path string, uid int, gid int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_CHOWN32, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchown(fd int, uid int, gid int) (err error) {
-	_, _, e1 := Syscall(SYS_FCHOWN32, uintptr(fd), uintptr(uid), uintptr(gid))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fstat(fd int, stat *Stat_t) (err error) {
-	_, _, e1 := Syscall(SYS_FSTAT64, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getegid() (egid int) {
-	r0, _, _ := RawSyscall(SYS_GETEGID32, 0, 0, 0)
-	egid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Geteuid() (euid int) {
-	r0, _, _ := RawSyscall(SYS_GETEUID32, 0, 0, 0)
-	euid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getgid() (gid int) {
-	r0, _, _ := RawSyscall(SYS_GETGID32, 0, 0, 0)
-	gid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getuid() (uid int) {
-	r0, _, _ := RawSyscall(SYS_GETUID32, 0, 0, 0)
-	uid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Lchown(path string, uid int, gid int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_LCHOWN32, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Listen(s int, n int) (err error) {
-	_, _, e1 := Syscall(SYS_LISTEN, uintptr(s), uintptr(n), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Lstat(path string, stat *Stat_t) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_LSTAT64, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
-	r0, _, e1 := Syscall6(SYS_SENDFILE64, uintptr(outfd), uintptr(infd), uintptr(unsafe.Pointer(offset)), uintptr(count), 0, 0)
-	written = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) {
-	r0, _, e1 := Syscall6(SYS__NEWSELECT, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setfsgid(gid int) (err error) {
-	_, _, e1 := Syscall(SYS_SETFSGID32, uintptr(gid), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setfsuid(uid int) (err error) {
-	_, _, e1 := Syscall(SYS_SETFSUID32, uintptr(uid), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setgid(gid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETGID32, uintptr(gid), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setregid(rgid int, egid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETREGID32, uintptr(rgid), uintptr(egid), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setresgid(rgid int, egid int, sgid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETRESGID32, uintptr(rgid), uintptr(egid), uintptr(sgid))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setresuid(ruid int, euid int, suid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETRESUID32, uintptr(ruid), uintptr(euid), uintptr(suid))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setreuid(ruid int, euid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETREUID32, uintptr(ruid), uintptr(euid), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Shutdown(fd int, how int) (err error) {
-	_, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(fd), uintptr(how), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error) {
-	r0, _, e1 := Syscall6(SYS_SPLICE, uintptr(rfd), uintptr(unsafe.Pointer(roff)), uintptr(wfd), uintptr(unsafe.Pointer(woff)), uintptr(len), uintptr(flags))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Stat(path string, stat *Stat_t) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_STAT64, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Gettimeofday(tv *Timeval) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Time(t *Time_t) (tt Time_t, err error) {
-	r0, _, e1 := RawSyscall(SYS_TIME, uintptr(unsafe.Pointer(t)), 0, 0)
-	tt = Time_t(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Pread(fd int, p []byte, offset int64) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall6(SYS_PREAD64, uintptr(fd), uintptr(_p0), uintptr(len(p)), 0, uintptr(offset), uintptr(offset>>32))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall6(SYS_PWRITE64, uintptr(fd), uintptr(_p0), uintptr(len(p)), 0, uintptr(offset), uintptr(offset>>32))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Truncate(path string, length int64) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall6(SYS_TRUNCATE64, uintptr(unsafe.Pointer(_p0)), 0, uintptr(length), uintptr(length>>32), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Ftruncate(fd int, length int64) (err error) {
-	_, _, e1 := Syscall6(SYS_FTRUNCATE64, uintptr(fd), 0, uintptr(length), uintptr(length>>32), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func mmap2(addr uintptr, length uintptr, prot int, flags int, fd int, pageOffset uintptr) (xaddr uintptr, err error) {
-	r0, _, e1 := Syscall6(SYS_MMAP2, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flags), uintptr(fd), uintptr(pageOffset))
-	xaddr = uintptr(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getrlimit(resource int, rlim *rlimit32) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETRLIMIT, uintptr(resource), uintptr(unsafe.Pointer(rlim)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func setrlimit(resource int, rlim *rlimit32) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(resource), uintptr(unsafe.Pointer(rlim)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
diff --git a/src/pkg/syscall/zsyscall_netbsd_386.go b/src/pkg/syscall/zsyscall_netbsd_386.go
deleted file mode 100644
index 281208f..0000000
--- a/src/pkg/syscall/zsyscall_netbsd_386.go
+++ /dev/null
@@ -1,1224 +0,0 @@
-// mksyscall.pl -l32 -netbsd syscall_bsd.go syscall_netbsd.go syscall_netbsd_386.go
-// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
-
-package syscall
-
-import "unsafe"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getgroups(ngid int, gid *_Gid_t) (n int, err error) {
-	r0, _, e1 := RawSyscall(SYS_GETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func setgroups(ngid int, gid *_Gid_t) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) {
-	r0, _, e1 := Syscall6(SYS_WAIT4, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0)
-	wpid = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
-	r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
-	_, _, e1 := Syscall(SYS_BIND, uintptr(s), uintptr(addr), uintptr(addrlen))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
-	_, _, e1 := Syscall(SYS_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func socket(domain int, typ int, proto int) (fd int, err error) {
-	r0, _, e1 := RawSyscall(SYS_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto))
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) {
-	_, _, e1 := Syscall6(SYS_GETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) {
-	_, _, e1 := Syscall6(SYS_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETPEERNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETSOCKNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Shutdown(s int, how int) (err error) {
-	_, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(s), uintptr(how), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) {
-	_, _, e1 := RawSyscall6(SYS_SOCKETPAIR, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall6(SYS_RECVFROM, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) {
-	var _p0 unsafe.Pointer
-	if len(buf) > 0 {
-		_p0 = unsafe.Pointer(&buf[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall6(SYS_SENDTO, uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_RECVMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_SENDMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func kevent(kq int, change unsafe.Pointer, nchange int, event unsafe.Pointer, nevent int, timeout *Timespec) (n int, err error) {
-	r0, _, e1 := Syscall6(SYS_KEVENT, uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) {
-	var _p0 unsafe.Pointer
-	if len(mib) > 0 {
-		_p0 = unsafe.Pointer(&mib[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall6(SYS___SYSCTL, uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func utimes(path string, timeval *[2]Timeval) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(timeval)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func futimes(fd int, timeval *[2]Timeval) (err error) {
-	_, _, e1 := Syscall(SYS_FUTIMES, uintptr(fd), uintptr(unsafe.Pointer(timeval)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func fcntl(fd int, cmd int, arg int) (val int, err error) {
-	r0, _, e1 := Syscall(SYS_FCNTL, uintptr(fd), uintptr(cmd), uintptr(arg))
-	val = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func pipe() (fd1 int, fd2 int, err error) {
-	r0, r1, e1 := RawSyscall(SYS_PIPE, 0, 0, 0)
-	fd1 = int(r0)
-	fd2 = int(r1)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getdents(fd int, buf []byte) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(buf) > 0 {
-		_p0 = unsafe.Pointer(&buf[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall(SYS_GETDENTS, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Access(path string, mode uint32) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_ACCESS, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Adjtime(delta *Timeval, olddelta *Timeval) (err error) {
-	_, _, e1 := Syscall(SYS_ADJTIME, uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chdir(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chflags(path string, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_CHFLAGS, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chmod(path string, mode uint32) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_CHMOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chown(path string, uid int, gid int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_CHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chroot(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_CHROOT, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Close(fd int) (err error) {
-	_, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Dup(fd int) (nfd int, err error) {
-	r0, _, e1 := RawSyscall(SYS_DUP, uintptr(fd), 0, 0)
-	nfd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Dup2(from int, to int) (err error) {
-	_, _, e1 := RawSyscall(SYS_DUP2, uintptr(from), uintptr(to), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Exit(code int) {
-	Syscall(SYS_EXIT, uintptr(code), 0, 0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchdir(fd int) (err error) {
-	_, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchflags(fd int, flags int) (err error) {
-	_, _, e1 := Syscall(SYS_FCHFLAGS, uintptr(fd), uintptr(flags), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchmod(fd int, mode uint32) (err error) {
-	_, _, e1 := Syscall(SYS_FCHMOD, uintptr(fd), uintptr(mode), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchown(fd int, uid int, gid int) (err error) {
-	_, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Flock(fd int, how int) (err error) {
-	_, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fpathconf(fd int, name int) (val int, err error) {
-	r0, _, e1 := Syscall(SYS_FPATHCONF, uintptr(fd), uintptr(name), 0)
-	val = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fstat(fd int, stat *Stat_t) (err error) {
-	_, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fsync(fd int) (err error) {
-	_, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Ftruncate(fd int, length int64) (err error) {
-	_, _, e1 := Syscall6(SYS_FTRUNCATE, uintptr(fd), 0, uintptr(length), uintptr(length>>32), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getegid() (egid int) {
-	r0, _, _ := RawSyscall(SYS_GETEGID, 0, 0, 0)
-	egid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Geteuid() (uid int) {
-	r0, _, _ := RawSyscall(SYS_GETEUID, 0, 0, 0)
-	uid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getgid() (gid int) {
-	r0, _, _ := RawSyscall(SYS_GETGID, 0, 0, 0)
-	gid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpgid(pid int) (pgid int, err error) {
-	r0, _, e1 := RawSyscall(SYS_GETPGID, uintptr(pid), 0, 0)
-	pgid = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpgrp() (pgrp int) {
-	r0, _, _ := RawSyscall(SYS_GETPGRP, 0, 0, 0)
-	pgrp = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpid() (pid int) {
-	r0, _, _ := RawSyscall(SYS_GETPID, 0, 0, 0)
-	pid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getppid() (ppid int) {
-	r0, _, _ := RawSyscall(SYS_GETPPID, 0, 0, 0)
-	ppid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpriority(which int, who int) (prio int, err error) {
-	r0, _, e1 := Syscall(SYS_GETPRIORITY, uintptr(which), uintptr(who), 0)
-	prio = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getrlimit(which int, lim *Rlimit) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getrusage(who int, rusage *Rusage) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETRUSAGE, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getsid(pid int) (sid int, err error) {
-	r0, _, e1 := RawSyscall(SYS_GETSID, uintptr(pid), 0, 0)
-	sid = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Gettimeofday(tv *Timeval) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getuid() (uid int) {
-	r0, _, _ := RawSyscall(SYS_GETUID, 0, 0, 0)
-	uid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Issetugid() (tainted bool) {
-	r0, _, _ := Syscall(SYS_ISSETUGID, 0, 0, 0)
-	tainted = bool(r0 != 0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Kill(pid int, signum Signal) (err error) {
-	_, _, e1 := Syscall(SYS_KILL, uintptr(pid), uintptr(signum), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Kqueue() (fd int, err error) {
-	r0, _, e1 := Syscall(SYS_KQUEUE, 0, 0, 0)
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Lchown(path string, uid int, gid int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_LCHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Link(path string, link string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(link)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_LINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Listen(s int, backlog int) (err error) {
-	_, _, e1 := Syscall(SYS_LISTEN, uintptr(s), uintptr(backlog), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Lstat(path string, stat *Stat_t) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_LSTAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mkdir(path string, mode uint32) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_MKDIR, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mkfifo(path string, mode uint32) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_MKFIFO, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mknod(path string, mode uint32, dev int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_MKNOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Nanosleep(time *Timespec, leftover *Timespec) (err error) {
-	_, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Open(path string, mode int, perm uint32) (fd int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Pathconf(path string, name int) (val int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	r0, _, e1 := Syscall(SYS_PATHCONF, uintptr(unsafe.Pointer(_p0)), uintptr(name), 0)
-	val = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Pread(fd int, p []byte, offset int64) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall6(SYS_PREAD, uintptr(fd), uintptr(_p0), uintptr(len(p)), 0, uintptr(offset), uintptr(offset>>32))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall6(SYS_PWRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)), 0, uintptr(offset), uintptr(offset>>32))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func read(fd int, p []byte) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(_p0), uintptr(len(p)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Readlink(path string, buf []byte) (n int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 unsafe.Pointer
-	if len(buf) > 0 {
-		_p1 = unsafe.Pointer(&buf[0])
-	} else {
-		_p1 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall(SYS_READLINK, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Rename(from string, to string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(from)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(to)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_RENAME, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Revoke(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_REVOKE, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Rmdir(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_RMDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
-	r0, r1, e1 := Syscall6(SYS_LSEEK, uintptr(fd), 0, uintptr(offset), uintptr(offset>>32), uintptr(whence), 0)
-	newoffset = int64(int64(r1)<<32 | int64(r0))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Select(n int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (err error) {
-	_, _, e1 := Syscall6(SYS_SELECT, uintptr(n), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setegid(egid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETEGID, uintptr(egid), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Seteuid(euid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETEUID, uintptr(euid), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setgid(gid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETGID, uintptr(gid), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setpgid(pid int, pgid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETPGID, uintptr(pid), uintptr(pgid), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setpriority(which int, who int, prio int) (err error) {
-	_, _, e1 := Syscall(SYS_SETPRIORITY, uintptr(which), uintptr(who), uintptr(prio))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setregid(rgid int, egid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setreuid(ruid int, euid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setrlimit(which int, lim *Rlimit) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setsid() (pid int, err error) {
-	r0, _, e1 := RawSyscall(SYS_SETSID, 0, 0, 0)
-	pid = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Settimeofday(tp *Timeval) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETTIMEOFDAY, uintptr(unsafe.Pointer(tp)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setuid(uid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETUID, uintptr(uid), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Stat(path string, stat *Stat_t) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Symlink(path string, link string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(link)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_SYMLINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Sync() (err error) {
-	_, _, e1 := Syscall(SYS_SYNC, 0, 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Truncate(path string, length int64) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall6(SYS_TRUNCATE, uintptr(unsafe.Pointer(_p0)), 0, uintptr(length), uintptr(length>>32), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Umask(newmask int) (oldmask int) {
-	r0, _, _ := Syscall(SYS_UMASK, uintptr(newmask), 0, 0)
-	oldmask = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Unlink(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_UNLINK, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Unmount(path string, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_UNMOUNT, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func write(fd int, p []byte) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) {
-	r0, _, e1 := Syscall9(SYS_MMAP, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), 0, uintptr(pos), uintptr(pos>>32), 0)
-	ret = uintptr(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func munmap(addr uintptr, length uintptr) (err error) {
-	_, _, e1 := Syscall(SYS_MUNMAP, uintptr(addr), uintptr(length), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func readlen(fd int, buf *byte, nbuf int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func writelen(fd int, buf *byte, nbuf int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
diff --git a/src/pkg/syscall/zsyscall_netbsd_amd64.go b/src/pkg/syscall/zsyscall_netbsd_amd64.go
deleted file mode 100644
index ed9a87d..0000000
--- a/src/pkg/syscall/zsyscall_netbsd_amd64.go
+++ /dev/null
@@ -1,1224 +0,0 @@
-// mksyscall.pl -netbsd syscall_bsd.go syscall_netbsd.go syscall_netbsd_amd64.go
-// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
-
-package syscall
-
-import "unsafe"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getgroups(ngid int, gid *_Gid_t) (n int, err error) {
-	r0, _, e1 := RawSyscall(SYS_GETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func setgroups(ngid int, gid *_Gid_t) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) {
-	r0, _, e1 := Syscall6(SYS_WAIT4, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0)
-	wpid = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
-	r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
-	_, _, e1 := Syscall(SYS_BIND, uintptr(s), uintptr(addr), uintptr(addrlen))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
-	_, _, e1 := Syscall(SYS_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func socket(domain int, typ int, proto int) (fd int, err error) {
-	r0, _, e1 := RawSyscall(SYS_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto))
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) {
-	_, _, e1 := Syscall6(SYS_GETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) {
-	_, _, e1 := Syscall6(SYS_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETPEERNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETSOCKNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Shutdown(s int, how int) (err error) {
-	_, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(s), uintptr(how), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) {
-	_, _, e1 := RawSyscall6(SYS_SOCKETPAIR, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall6(SYS_RECVFROM, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) {
-	var _p0 unsafe.Pointer
-	if len(buf) > 0 {
-		_p0 = unsafe.Pointer(&buf[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall6(SYS_SENDTO, uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_RECVMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_SENDMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func kevent(kq int, change unsafe.Pointer, nchange int, event unsafe.Pointer, nevent int, timeout *Timespec) (n int, err error) {
-	r0, _, e1 := Syscall6(SYS_KEVENT, uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) {
-	var _p0 unsafe.Pointer
-	if len(mib) > 0 {
-		_p0 = unsafe.Pointer(&mib[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall6(SYS___SYSCTL, uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func utimes(path string, timeval *[2]Timeval) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(timeval)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func futimes(fd int, timeval *[2]Timeval) (err error) {
-	_, _, e1 := Syscall(SYS_FUTIMES, uintptr(fd), uintptr(unsafe.Pointer(timeval)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func fcntl(fd int, cmd int, arg int) (val int, err error) {
-	r0, _, e1 := Syscall(SYS_FCNTL, uintptr(fd), uintptr(cmd), uintptr(arg))
-	val = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func pipe() (fd1 int, fd2 int, err error) {
-	r0, r1, e1 := RawSyscall(SYS_PIPE, 0, 0, 0)
-	fd1 = int(r0)
-	fd2 = int(r1)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getdents(fd int, buf []byte) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(buf) > 0 {
-		_p0 = unsafe.Pointer(&buf[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall(SYS_GETDENTS, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Access(path string, mode uint32) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_ACCESS, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Adjtime(delta *Timeval, olddelta *Timeval) (err error) {
-	_, _, e1 := Syscall(SYS_ADJTIME, uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chdir(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chflags(path string, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_CHFLAGS, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chmod(path string, mode uint32) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_CHMOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chown(path string, uid int, gid int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_CHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chroot(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_CHROOT, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Close(fd int) (err error) {
-	_, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Dup(fd int) (nfd int, err error) {
-	r0, _, e1 := RawSyscall(SYS_DUP, uintptr(fd), 0, 0)
-	nfd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Dup2(from int, to int) (err error) {
-	_, _, e1 := RawSyscall(SYS_DUP2, uintptr(from), uintptr(to), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Exit(code int) {
-	Syscall(SYS_EXIT, uintptr(code), 0, 0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchdir(fd int) (err error) {
-	_, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchflags(fd int, flags int) (err error) {
-	_, _, e1 := Syscall(SYS_FCHFLAGS, uintptr(fd), uintptr(flags), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchmod(fd int, mode uint32) (err error) {
-	_, _, e1 := Syscall(SYS_FCHMOD, uintptr(fd), uintptr(mode), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchown(fd int, uid int, gid int) (err error) {
-	_, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Flock(fd int, how int) (err error) {
-	_, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fpathconf(fd int, name int) (val int, err error) {
-	r0, _, e1 := Syscall(SYS_FPATHCONF, uintptr(fd), uintptr(name), 0)
-	val = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fstat(fd int, stat *Stat_t) (err error) {
-	_, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fsync(fd int) (err error) {
-	_, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Ftruncate(fd int, length int64) (err error) {
-	_, _, e1 := Syscall(SYS_FTRUNCATE, uintptr(fd), 0, uintptr(length))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getegid() (egid int) {
-	r0, _, _ := RawSyscall(SYS_GETEGID, 0, 0, 0)
-	egid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Geteuid() (uid int) {
-	r0, _, _ := RawSyscall(SYS_GETEUID, 0, 0, 0)
-	uid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getgid() (gid int) {
-	r0, _, _ := RawSyscall(SYS_GETGID, 0, 0, 0)
-	gid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpgid(pid int) (pgid int, err error) {
-	r0, _, e1 := RawSyscall(SYS_GETPGID, uintptr(pid), 0, 0)
-	pgid = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpgrp() (pgrp int) {
-	r0, _, _ := RawSyscall(SYS_GETPGRP, 0, 0, 0)
-	pgrp = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpid() (pid int) {
-	r0, _, _ := RawSyscall(SYS_GETPID, 0, 0, 0)
-	pid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getppid() (ppid int) {
-	r0, _, _ := RawSyscall(SYS_GETPPID, 0, 0, 0)
-	ppid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpriority(which int, who int) (prio int, err error) {
-	r0, _, e1 := Syscall(SYS_GETPRIORITY, uintptr(which), uintptr(who), 0)
-	prio = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getrlimit(which int, lim *Rlimit) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getrusage(who int, rusage *Rusage) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETRUSAGE, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getsid(pid int) (sid int, err error) {
-	r0, _, e1 := RawSyscall(SYS_GETSID, uintptr(pid), 0, 0)
-	sid = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Gettimeofday(tv *Timeval) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getuid() (uid int) {
-	r0, _, _ := RawSyscall(SYS_GETUID, 0, 0, 0)
-	uid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Issetugid() (tainted bool) {
-	r0, _, _ := Syscall(SYS_ISSETUGID, 0, 0, 0)
-	tainted = bool(r0 != 0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Kill(pid int, signum Signal) (err error) {
-	_, _, e1 := Syscall(SYS_KILL, uintptr(pid), uintptr(signum), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Kqueue() (fd int, err error) {
-	r0, _, e1 := Syscall(SYS_KQUEUE, 0, 0, 0)
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Lchown(path string, uid int, gid int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_LCHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Link(path string, link string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(link)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_LINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Listen(s int, backlog int) (err error) {
-	_, _, e1 := Syscall(SYS_LISTEN, uintptr(s), uintptr(backlog), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Lstat(path string, stat *Stat_t) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_LSTAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mkdir(path string, mode uint32) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_MKDIR, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mkfifo(path string, mode uint32) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_MKFIFO, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mknod(path string, mode uint32, dev int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_MKNOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Nanosleep(time *Timespec, leftover *Timespec) (err error) {
-	_, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Open(path string, mode int, perm uint32) (fd int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Pathconf(path string, name int) (val int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	r0, _, e1 := Syscall(SYS_PATHCONF, uintptr(unsafe.Pointer(_p0)), uintptr(name), 0)
-	val = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Pread(fd int, p []byte, offset int64) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall6(SYS_PREAD, uintptr(fd), uintptr(_p0), uintptr(len(p)), 0, uintptr(offset), 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall6(SYS_PWRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)), 0, uintptr(offset), 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func read(fd int, p []byte) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(_p0), uintptr(len(p)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Readlink(path string, buf []byte) (n int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 unsafe.Pointer
-	if len(buf) > 0 {
-		_p1 = unsafe.Pointer(&buf[0])
-	} else {
-		_p1 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall(SYS_READLINK, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Rename(from string, to string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(from)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(to)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_RENAME, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Revoke(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_REVOKE, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Rmdir(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_RMDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
-	r0, _, e1 := Syscall6(SYS_LSEEK, uintptr(fd), 0, uintptr(offset), uintptr(whence), 0, 0)
-	newoffset = int64(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Select(n int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (err error) {
-	_, _, e1 := Syscall6(SYS_SELECT, uintptr(n), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setegid(egid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETEGID, uintptr(egid), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Seteuid(euid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETEUID, uintptr(euid), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setgid(gid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETGID, uintptr(gid), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setpgid(pid int, pgid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETPGID, uintptr(pid), uintptr(pgid), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setpriority(which int, who int, prio int) (err error) {
-	_, _, e1 := Syscall(SYS_SETPRIORITY, uintptr(which), uintptr(who), uintptr(prio))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setregid(rgid int, egid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setreuid(ruid int, euid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setrlimit(which int, lim *Rlimit) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setsid() (pid int, err error) {
-	r0, _, e1 := RawSyscall(SYS_SETSID, 0, 0, 0)
-	pid = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Settimeofday(tp *Timeval) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETTIMEOFDAY, uintptr(unsafe.Pointer(tp)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setuid(uid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETUID, uintptr(uid), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Stat(path string, stat *Stat_t) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Symlink(path string, link string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(link)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_SYMLINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Sync() (err error) {
-	_, _, e1 := Syscall(SYS_SYNC, 0, 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Truncate(path string, length int64) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_TRUNCATE, uintptr(unsafe.Pointer(_p0)), 0, uintptr(length))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Umask(newmask int) (oldmask int) {
-	r0, _, _ := Syscall(SYS_UMASK, uintptr(newmask), 0, 0)
-	oldmask = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Unlink(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_UNLINK, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Unmount(path string, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_UNMOUNT, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func write(fd int, p []byte) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) {
-	r0, _, e1 := Syscall9(SYS_MMAP, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), 0, uintptr(pos), 0, 0)
-	ret = uintptr(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func munmap(addr uintptr, length uintptr) (err error) {
-	_, _, e1 := Syscall(SYS_MUNMAP, uintptr(addr), uintptr(length), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func readlen(fd int, buf *byte, nbuf int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func writelen(fd int, buf *byte, nbuf int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
diff --git a/src/pkg/syscall/zsyscall_netbsd_arm.go b/src/pkg/syscall/zsyscall_netbsd_arm.go
deleted file mode 100644
index c5c9a9f..0000000
--- a/src/pkg/syscall/zsyscall_netbsd_arm.go
+++ /dev/null
@@ -1,1224 +0,0 @@
-// mksyscall.pl -l32 -arm syscall_bsd.go syscall_netbsd.go syscall_netbsd_arm.go
-// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
-
-package syscall
-
-import "unsafe"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getgroups(ngid int, gid *_Gid_t) (n int, err error) {
-	r0, _, e1 := RawSyscall(SYS_GETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func setgroups(ngid int, gid *_Gid_t) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) {
-	r0, _, e1 := Syscall6(SYS_WAIT4, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0)
-	wpid = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
-	r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
-	_, _, e1 := Syscall(SYS_BIND, uintptr(s), uintptr(addr), uintptr(addrlen))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
-	_, _, e1 := Syscall(SYS_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func socket(domain int, typ int, proto int) (fd int, err error) {
-	r0, _, e1 := RawSyscall(SYS_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto))
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) {
-	_, _, e1 := Syscall6(SYS_GETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) {
-	_, _, e1 := Syscall6(SYS_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETPEERNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETSOCKNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Shutdown(s int, how int) (err error) {
-	_, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(s), uintptr(how), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) {
-	_, _, e1 := RawSyscall6(SYS_SOCKETPAIR, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall6(SYS_RECVFROM, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) {
-	var _p0 unsafe.Pointer
-	if len(buf) > 0 {
-		_p0 = unsafe.Pointer(&buf[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall6(SYS_SENDTO, uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_RECVMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_SENDMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func kevent(kq int, change unsafe.Pointer, nchange int, event unsafe.Pointer, nevent int, timeout *Timespec) (n int, err error) {
-	r0, _, e1 := Syscall6(SYS_KEVENT, uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) {
-	var _p0 unsafe.Pointer
-	if len(mib) > 0 {
-		_p0 = unsafe.Pointer(&mib[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall6(SYS___SYSCTL, uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func utimes(path string, timeval *[2]Timeval) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(timeval)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func futimes(fd int, timeval *[2]Timeval) (err error) {
-	_, _, e1 := Syscall(SYS_FUTIMES, uintptr(fd), uintptr(unsafe.Pointer(timeval)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func fcntl(fd int, cmd int, arg int) (val int, err error) {
-	r0, _, e1 := Syscall(SYS_FCNTL, uintptr(fd), uintptr(cmd), uintptr(arg))
-	val = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func pipe() (fd1 int, fd2 int, err error) {
-	r0, r1, e1 := RawSyscall(SYS_PIPE, 0, 0, 0)
-	fd1 = int(r0)
-	fd2 = int(r1)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getdents(fd int, buf []byte) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(buf) > 0 {
-		_p0 = unsafe.Pointer(&buf[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall(SYS_GETDENTS, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Access(path string, mode uint32) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_ACCESS, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Adjtime(delta *Timeval, olddelta *Timeval) (err error) {
-	_, _, e1 := Syscall(SYS_ADJTIME, uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chdir(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chflags(path string, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_CHFLAGS, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chmod(path string, mode uint32) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_CHMOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chown(path string, uid int, gid int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_CHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chroot(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_CHROOT, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Close(fd int) (err error) {
-	_, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Dup(fd int) (nfd int, err error) {
-	r0, _, e1 := RawSyscall(SYS_DUP, uintptr(fd), 0, 0)
-	nfd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Dup2(from int, to int) (err error) {
-	_, _, e1 := RawSyscall(SYS_DUP2, uintptr(from), uintptr(to), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Exit(code int) {
-	Syscall(SYS_EXIT, uintptr(code), 0, 0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchdir(fd int) (err error) {
-	_, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchflags(fd int, flags int) (err error) {
-	_, _, e1 := Syscall(SYS_FCHFLAGS, uintptr(fd), uintptr(flags), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchmod(fd int, mode uint32) (err error) {
-	_, _, e1 := Syscall(SYS_FCHMOD, uintptr(fd), uintptr(mode), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchown(fd int, uid int, gid int) (err error) {
-	_, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Flock(fd int, how int) (err error) {
-	_, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fpathconf(fd int, name int) (val int, err error) {
-	r0, _, e1 := Syscall(SYS_FPATHCONF, uintptr(fd), uintptr(name), 0)
-	val = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fstat(fd int, stat *Stat_t) (err error) {
-	_, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fsync(fd int) (err error) {
-	_, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Ftruncate(fd int, length int64) (err error) {
-	_, _, e1 := Syscall6(SYS_FTRUNCATE, uintptr(fd), 0, uintptr(length), uintptr(length>>32), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getegid() (egid int) {
-	r0, _, _ := RawSyscall(SYS_GETEGID, 0, 0, 0)
-	egid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Geteuid() (uid int) {
-	r0, _, _ := RawSyscall(SYS_GETEUID, 0, 0, 0)
-	uid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getgid() (gid int) {
-	r0, _, _ := RawSyscall(SYS_GETGID, 0, 0, 0)
-	gid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpgid(pid int) (pgid int, err error) {
-	r0, _, e1 := RawSyscall(SYS_GETPGID, uintptr(pid), 0, 0)
-	pgid = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpgrp() (pgrp int) {
-	r0, _, _ := RawSyscall(SYS_GETPGRP, 0, 0, 0)
-	pgrp = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpid() (pid int) {
-	r0, _, _ := RawSyscall(SYS_GETPID, 0, 0, 0)
-	pid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getppid() (ppid int) {
-	r0, _, _ := RawSyscall(SYS_GETPPID, 0, 0, 0)
-	ppid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpriority(which int, who int) (prio int, err error) {
-	r0, _, e1 := Syscall(SYS_GETPRIORITY, uintptr(which), uintptr(who), 0)
-	prio = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getrlimit(which int, lim *Rlimit) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getrusage(who int, rusage *Rusage) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETRUSAGE, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getsid(pid int) (sid int, err error) {
-	r0, _, e1 := RawSyscall(SYS_GETSID, uintptr(pid), 0, 0)
-	sid = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Gettimeofday(tv *Timeval) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getuid() (uid int) {
-	r0, _, _ := RawSyscall(SYS_GETUID, 0, 0, 0)
-	uid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Issetugid() (tainted bool) {
-	r0, _, _ := Syscall(SYS_ISSETUGID, 0, 0, 0)
-	tainted = bool(r0 != 0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Kill(pid int, signum Signal) (err error) {
-	_, _, e1 := Syscall(SYS_KILL, uintptr(pid), uintptr(signum), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Kqueue() (fd int, err error) {
-	r0, _, e1 := Syscall(SYS_KQUEUE, 0, 0, 0)
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Lchown(path string, uid int, gid int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_LCHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Link(path string, link string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(link)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_LINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Listen(s int, backlog int) (err error) {
-	_, _, e1 := Syscall(SYS_LISTEN, uintptr(s), uintptr(backlog), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Lstat(path string, stat *Stat_t) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_LSTAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mkdir(path string, mode uint32) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_MKDIR, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mkfifo(path string, mode uint32) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_MKFIFO, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mknod(path string, mode uint32, dev int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_MKNOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Nanosleep(time *Timespec, leftover *Timespec) (err error) {
-	_, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Open(path string, mode int, perm uint32) (fd int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Pathconf(path string, name int) (val int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	r0, _, e1 := Syscall(SYS_PATHCONF, uintptr(unsafe.Pointer(_p0)), uintptr(name), 0)
-	val = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Pread(fd int, p []byte, offset int64) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall6(SYS_PREAD, uintptr(fd), uintptr(_p0), uintptr(len(p)), 0, uintptr(offset), uintptr(offset>>32))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall6(SYS_PWRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)), 0, uintptr(offset), uintptr(offset>>32))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func read(fd int, p []byte) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(_p0), uintptr(len(p)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Readlink(path string, buf []byte) (n int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 unsafe.Pointer
-	if len(buf) > 0 {
-		_p1 = unsafe.Pointer(&buf[0])
-	} else {
-		_p1 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall(SYS_READLINK, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Rename(from string, to string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(from)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(to)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_RENAME, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Revoke(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_REVOKE, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Rmdir(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_RMDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
-	r0, r1, e1 := Syscall6(SYS_LSEEK, uintptr(fd), 0, uintptr(offset), uintptr(offset>>32), uintptr(whence), 0)
-	newoffset = int64(int64(r1)<<32 | int64(r0))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Select(n int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (err error) {
-	_, _, e1 := Syscall6(SYS_SELECT, uintptr(n), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setegid(egid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETEGID, uintptr(egid), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Seteuid(euid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETEUID, uintptr(euid), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setgid(gid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETGID, uintptr(gid), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setpgid(pid int, pgid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETPGID, uintptr(pid), uintptr(pgid), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setpriority(which int, who int, prio int) (err error) {
-	_, _, e1 := Syscall(SYS_SETPRIORITY, uintptr(which), uintptr(who), uintptr(prio))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setregid(rgid int, egid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setreuid(ruid int, euid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setrlimit(which int, lim *Rlimit) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setsid() (pid int, err error) {
-	r0, _, e1 := RawSyscall(SYS_SETSID, 0, 0, 0)
-	pid = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Settimeofday(tp *Timeval) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETTIMEOFDAY, uintptr(unsafe.Pointer(tp)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setuid(uid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETUID, uintptr(uid), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Stat(path string, stat *Stat_t) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Symlink(path string, link string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(link)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_SYMLINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Sync() (err error) {
-	_, _, e1 := Syscall(SYS_SYNC, 0, 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Truncate(path string, length int64) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall6(SYS_TRUNCATE, uintptr(unsafe.Pointer(_p0)), 0, uintptr(length), uintptr(length>>32), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Umask(newmask int) (oldmask int) {
-	r0, _, _ := Syscall(SYS_UMASK, uintptr(newmask), 0, 0)
-	oldmask = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Unlink(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_UNLINK, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Unmount(path string, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_UNMOUNT, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func write(fd int, p []byte) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) {
-	r0, _, e1 := Syscall9(SYS_MMAP, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), 0, uintptr(pos), uintptr(pos>>32), 0)
-	ret = uintptr(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func munmap(addr uintptr, length uintptr) (err error) {
-	_, _, e1 := Syscall(SYS_MUNMAP, uintptr(addr), uintptr(length), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func readlen(fd int, buf *byte, nbuf int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func writelen(fd int, buf *byte, nbuf int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
diff --git a/src/pkg/syscall/zsyscall_openbsd_386.go b/src/pkg/syscall/zsyscall_openbsd_386.go
deleted file mode 100644
index 785e7c3..0000000
--- a/src/pkg/syscall/zsyscall_openbsd_386.go
+++ /dev/null
@@ -1,1262 +0,0 @@
-// mksyscall.pl -l32 -openbsd syscall_bsd.go syscall_openbsd.go syscall_openbsd_386.go
-// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
-
-package syscall
-
-import "unsafe"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getgroups(ngid int, gid *_Gid_t) (n int, err error) {
-	r0, _, e1 := RawSyscall(SYS_GETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func setgroups(ngid int, gid *_Gid_t) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) {
-	r0, _, e1 := Syscall6(SYS_WAIT4, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0)
-	wpid = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
-	r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
-	_, _, e1 := Syscall(SYS_BIND, uintptr(s), uintptr(addr), uintptr(addrlen))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
-	_, _, e1 := Syscall(SYS_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func socket(domain int, typ int, proto int) (fd int, err error) {
-	r0, _, e1 := RawSyscall(SYS_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto))
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) {
-	_, _, e1 := Syscall6(SYS_GETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) {
-	_, _, e1 := Syscall6(SYS_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETPEERNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETSOCKNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Shutdown(s int, how int) (err error) {
-	_, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(s), uintptr(how), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) {
-	_, _, e1 := RawSyscall6(SYS_SOCKETPAIR, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall6(SYS_RECVFROM, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) {
-	var _p0 unsafe.Pointer
-	if len(buf) > 0 {
-		_p0 = unsafe.Pointer(&buf[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall6(SYS_SENDTO, uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_RECVMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_SENDMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func kevent(kq int, change unsafe.Pointer, nchange int, event unsafe.Pointer, nevent int, timeout *Timespec) (n int, err error) {
-	r0, _, e1 := Syscall6(SYS_KEVENT, uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) {
-	var _p0 unsafe.Pointer
-	if len(mib) > 0 {
-		_p0 = unsafe.Pointer(&mib[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall6(SYS___SYSCTL, uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func utimes(path string, timeval *[2]Timeval) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(timeval)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func futimes(fd int, timeval *[2]Timeval) (err error) {
-	_, _, e1 := Syscall(SYS_FUTIMES, uintptr(fd), uintptr(unsafe.Pointer(timeval)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func fcntl(fd int, cmd int, arg int) (val int, err error) {
-	r0, _, e1 := Syscall(SYS_FCNTL, uintptr(fd), uintptr(cmd), uintptr(arg))
-	val = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func pipe(p *[2]_C_int) (err error) {
-	_, _, e1 := RawSyscall(SYS_PIPE, uintptr(unsafe.Pointer(p)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getdents(fd int, buf []byte) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(buf) > 0 {
-		_p0 = unsafe.Pointer(&buf[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall(SYS_GETDENTS, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Access(path string, mode uint32) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_ACCESS, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Adjtime(delta *Timeval, olddelta *Timeval) (err error) {
-	_, _, e1 := Syscall(SYS_ADJTIME, uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chdir(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chflags(path string, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_CHFLAGS, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chmod(path string, mode uint32) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_CHMOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chown(path string, uid int, gid int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_CHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chroot(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_CHROOT, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Close(fd int) (err error) {
-	_, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Dup(fd int) (nfd int, err error) {
-	r0, _, e1 := RawSyscall(SYS_DUP, uintptr(fd), 0, 0)
-	nfd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Dup2(from int, to int) (err error) {
-	_, _, e1 := RawSyscall(SYS_DUP2, uintptr(from), uintptr(to), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Exit(code int) {
-	Syscall(SYS_EXIT, uintptr(code), 0, 0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchdir(fd int) (err error) {
-	_, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchflags(fd int, flags int) (err error) {
-	_, _, e1 := Syscall(SYS_FCHFLAGS, uintptr(fd), uintptr(flags), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchmod(fd int, mode uint32) (err error) {
-	_, _, e1 := Syscall(SYS_FCHMOD, uintptr(fd), uintptr(mode), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchown(fd int, uid int, gid int) (err error) {
-	_, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Flock(fd int, how int) (err error) {
-	_, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fpathconf(fd int, name int) (val int, err error) {
-	r0, _, e1 := Syscall(SYS_FPATHCONF, uintptr(fd), uintptr(name), 0)
-	val = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fstat(fd int, stat *Stat_t) (err error) {
-	_, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fstatfs(fd int, stat *Statfs_t) (err error) {
-	_, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fsync(fd int) (err error) {
-	_, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Ftruncate(fd int, length int64) (err error) {
-	_, _, e1 := Syscall6(SYS_FTRUNCATE, uintptr(fd), 0, uintptr(length), uintptr(length>>32), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getegid() (egid int) {
-	r0, _, _ := RawSyscall(SYS_GETEGID, 0, 0, 0)
-	egid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Geteuid() (uid int) {
-	r0, _, _ := RawSyscall(SYS_GETEUID, 0, 0, 0)
-	uid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getgid() (gid int) {
-	r0, _, _ := RawSyscall(SYS_GETGID, 0, 0, 0)
-	gid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpgid(pid int) (pgid int, err error) {
-	r0, _, e1 := RawSyscall(SYS_GETPGID, uintptr(pid), 0, 0)
-	pgid = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpgrp() (pgrp int) {
-	r0, _, _ := RawSyscall(SYS_GETPGRP, 0, 0, 0)
-	pgrp = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpid() (pid int) {
-	r0, _, _ := RawSyscall(SYS_GETPID, 0, 0, 0)
-	pid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getppid() (ppid int) {
-	r0, _, _ := RawSyscall(SYS_GETPPID, 0, 0, 0)
-	ppid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpriority(which int, who int) (prio int, err error) {
-	r0, _, e1 := Syscall(SYS_GETPRIORITY, uintptr(which), uintptr(who), 0)
-	prio = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getrlimit(which int, lim *Rlimit) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getrusage(who int, rusage *Rusage) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETRUSAGE, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getsid(pid int) (sid int, err error) {
-	r0, _, e1 := RawSyscall(SYS_GETSID, uintptr(pid), 0, 0)
-	sid = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Gettimeofday(tv *Timeval) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getuid() (uid int) {
-	r0, _, _ := RawSyscall(SYS_GETUID, 0, 0, 0)
-	uid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Issetugid() (tainted bool) {
-	r0, _, _ := Syscall(SYS_ISSETUGID, 0, 0, 0)
-	tainted = bool(r0 != 0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Kill(pid int, signum Signal) (err error) {
-	_, _, e1 := Syscall(SYS_KILL, uintptr(pid), uintptr(signum), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Kqueue() (fd int, err error) {
-	r0, _, e1 := Syscall(SYS_KQUEUE, 0, 0, 0)
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Lchown(path string, uid int, gid int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_LCHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Link(path string, link string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(link)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_LINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Listen(s int, backlog int) (err error) {
-	_, _, e1 := Syscall(SYS_LISTEN, uintptr(s), uintptr(backlog), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Lstat(path string, stat *Stat_t) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_LSTAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mkdir(path string, mode uint32) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_MKDIR, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mkfifo(path string, mode uint32) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_MKFIFO, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mknod(path string, mode uint32, dev int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_MKNOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Nanosleep(time *Timespec, leftover *Timespec) (err error) {
-	_, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Open(path string, mode int, perm uint32) (fd int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Pathconf(path string, name int) (val int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	r0, _, e1 := Syscall(SYS_PATHCONF, uintptr(unsafe.Pointer(_p0)), uintptr(name), 0)
-	val = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Pread(fd int, p []byte, offset int64) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall6(SYS_PREAD, uintptr(fd), uintptr(_p0), uintptr(len(p)), 0, uintptr(offset), uintptr(offset>>32))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall6(SYS_PWRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)), 0, uintptr(offset), uintptr(offset>>32))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func read(fd int, p []byte) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(_p0), uintptr(len(p)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Readlink(path string, buf []byte) (n int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 unsafe.Pointer
-	if len(buf) > 0 {
-		_p1 = unsafe.Pointer(&buf[0])
-	} else {
-		_p1 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall(SYS_READLINK, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Rename(from string, to string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(from)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(to)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_RENAME, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Revoke(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_REVOKE, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Rmdir(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_RMDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
-	r0, r1, e1 := Syscall6(SYS_LSEEK, uintptr(fd), 0, uintptr(offset), uintptr(offset>>32), uintptr(whence), 0)
-	newoffset = int64(int64(r1)<<32 | int64(r0))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Select(n int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (err error) {
-	_, _, e1 := Syscall6(SYS_SELECT, uintptr(n), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setegid(egid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETEGID, uintptr(egid), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Seteuid(euid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETEUID, uintptr(euid), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setgid(gid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETGID, uintptr(gid), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setlogin(name string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(name)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_SETLOGIN, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setpgid(pid int, pgid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETPGID, uintptr(pid), uintptr(pgid), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setpriority(which int, who int, prio int) (err error) {
-	_, _, e1 := Syscall(SYS_SETPRIORITY, uintptr(which), uintptr(who), uintptr(prio))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setregid(rgid int, egid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setreuid(ruid int, euid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setrlimit(which int, lim *Rlimit) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setsid() (pid int, err error) {
-	r0, _, e1 := RawSyscall(SYS_SETSID, 0, 0, 0)
-	pid = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Settimeofday(tp *Timeval) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETTIMEOFDAY, uintptr(unsafe.Pointer(tp)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setuid(uid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETUID, uintptr(uid), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Stat(path string, stat *Stat_t) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Statfs(path string, stat *Statfs_t) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_STATFS, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Symlink(path string, link string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(link)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_SYMLINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Sync() (err error) {
-	_, _, e1 := Syscall(SYS_SYNC, 0, 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Truncate(path string, length int64) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall6(SYS_TRUNCATE, uintptr(unsafe.Pointer(_p0)), 0, uintptr(length), uintptr(length>>32), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Umask(newmask int) (oldmask int) {
-	r0, _, _ := Syscall(SYS_UMASK, uintptr(newmask), 0, 0)
-	oldmask = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Unlink(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_UNLINK, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Unmount(path string, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_UNMOUNT, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func write(fd int, p []byte) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) {
-	r0, _, e1 := Syscall9(SYS_MMAP, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), 0, uintptr(pos), uintptr(pos>>32), 0)
-	ret = uintptr(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func munmap(addr uintptr, length uintptr) (err error) {
-	_, _, e1 := Syscall(SYS_MUNMAP, uintptr(addr), uintptr(length), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func readlen(fd int, buf *byte, nbuf int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func writelen(fd int, buf *byte, nbuf int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
diff --git a/src/pkg/syscall/zsyscall_openbsd_amd64.go b/src/pkg/syscall/zsyscall_openbsd_amd64.go
deleted file mode 100644
index 7a8d9b6..0000000
--- a/src/pkg/syscall/zsyscall_openbsd_amd64.go
+++ /dev/null
@@ -1,1262 +0,0 @@
-// mksyscall.pl -openbsd syscall_bsd.go syscall_openbsd.go syscall_openbsd_amd64.go
-// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
-
-package syscall
-
-import "unsafe"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getgroups(ngid int, gid *_Gid_t) (n int, err error) {
-	r0, _, e1 := RawSyscall(SYS_GETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func setgroups(ngid int, gid *_Gid_t) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) {
-	r0, _, e1 := Syscall6(SYS_WAIT4, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0)
-	wpid = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
-	r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
-	_, _, e1 := Syscall(SYS_BIND, uintptr(s), uintptr(addr), uintptr(addrlen))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
-	_, _, e1 := Syscall(SYS_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func socket(domain int, typ int, proto int) (fd int, err error) {
-	r0, _, e1 := RawSyscall(SYS_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto))
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) {
-	_, _, e1 := Syscall6(SYS_GETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) {
-	_, _, e1 := Syscall6(SYS_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETPEERNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETSOCKNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Shutdown(s int, how int) (err error) {
-	_, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(s), uintptr(how), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) {
-	_, _, e1 := RawSyscall6(SYS_SOCKETPAIR, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall6(SYS_RECVFROM, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) {
-	var _p0 unsafe.Pointer
-	if len(buf) > 0 {
-		_p0 = unsafe.Pointer(&buf[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall6(SYS_SENDTO, uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_RECVMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_SENDMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func kevent(kq int, change unsafe.Pointer, nchange int, event unsafe.Pointer, nevent int, timeout *Timespec) (n int, err error) {
-	r0, _, e1 := Syscall6(SYS_KEVENT, uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) {
-	var _p0 unsafe.Pointer
-	if len(mib) > 0 {
-		_p0 = unsafe.Pointer(&mib[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	_, _, e1 := Syscall6(SYS___SYSCTL, uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func utimes(path string, timeval *[2]Timeval) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(timeval)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func futimes(fd int, timeval *[2]Timeval) (err error) {
-	_, _, e1 := Syscall(SYS_FUTIMES, uintptr(fd), uintptr(unsafe.Pointer(timeval)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func fcntl(fd int, cmd int, arg int) (val int, err error) {
-	r0, _, e1 := Syscall(SYS_FCNTL, uintptr(fd), uintptr(cmd), uintptr(arg))
-	val = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func pipe(p *[2]_C_int) (err error) {
-	_, _, e1 := RawSyscall(SYS_PIPE, uintptr(unsafe.Pointer(p)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getdents(fd int, buf []byte) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(buf) > 0 {
-		_p0 = unsafe.Pointer(&buf[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall(SYS_GETDENTS, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Access(path string, mode uint32) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_ACCESS, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Adjtime(delta *Timeval, olddelta *Timeval) (err error) {
-	_, _, e1 := Syscall(SYS_ADJTIME, uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chdir(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chflags(path string, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_CHFLAGS, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chmod(path string, mode uint32) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_CHMOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chown(path string, uid int, gid int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_CHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chroot(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_CHROOT, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Close(fd int) (err error) {
-	_, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Dup(fd int) (nfd int, err error) {
-	r0, _, e1 := RawSyscall(SYS_DUP, uintptr(fd), 0, 0)
-	nfd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Dup2(from int, to int) (err error) {
-	_, _, e1 := RawSyscall(SYS_DUP2, uintptr(from), uintptr(to), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Exit(code int) {
-	Syscall(SYS_EXIT, uintptr(code), 0, 0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchdir(fd int) (err error) {
-	_, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchflags(fd int, flags int) (err error) {
-	_, _, e1 := Syscall(SYS_FCHFLAGS, uintptr(fd), uintptr(flags), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchmod(fd int, mode uint32) (err error) {
-	_, _, e1 := Syscall(SYS_FCHMOD, uintptr(fd), uintptr(mode), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fchown(fd int, uid int, gid int) (err error) {
-	_, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Flock(fd int, how int) (err error) {
-	_, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fpathconf(fd int, name int) (val int, err error) {
-	r0, _, e1 := Syscall(SYS_FPATHCONF, uintptr(fd), uintptr(name), 0)
-	val = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fstat(fd int, stat *Stat_t) (err error) {
-	_, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fstatfs(fd int, stat *Statfs_t) (err error) {
-	_, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fsync(fd int) (err error) {
-	_, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Ftruncate(fd int, length int64) (err error) {
-	_, _, e1 := Syscall(SYS_FTRUNCATE, uintptr(fd), 0, uintptr(length))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getegid() (egid int) {
-	r0, _, _ := RawSyscall(SYS_GETEGID, 0, 0, 0)
-	egid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Geteuid() (uid int) {
-	r0, _, _ := RawSyscall(SYS_GETEUID, 0, 0, 0)
-	uid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getgid() (gid int) {
-	r0, _, _ := RawSyscall(SYS_GETGID, 0, 0, 0)
-	gid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpgid(pid int) (pgid int, err error) {
-	r0, _, e1 := RawSyscall(SYS_GETPGID, uintptr(pid), 0, 0)
-	pgid = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpgrp() (pgrp int) {
-	r0, _, _ := RawSyscall(SYS_GETPGRP, 0, 0, 0)
-	pgrp = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpid() (pid int) {
-	r0, _, _ := RawSyscall(SYS_GETPID, 0, 0, 0)
-	pid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getppid() (ppid int) {
-	r0, _, _ := RawSyscall(SYS_GETPPID, 0, 0, 0)
-	ppid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getpriority(which int, who int) (prio int, err error) {
-	r0, _, e1 := Syscall(SYS_GETPRIORITY, uintptr(which), uintptr(who), 0)
-	prio = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getrlimit(which int, lim *Rlimit) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getrusage(who int, rusage *Rusage) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETRUSAGE, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getsid(pid int) (sid int, err error) {
-	r0, _, e1 := RawSyscall(SYS_GETSID, uintptr(pid), 0, 0)
-	sid = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Gettimeofday(tv *Timeval) (err error) {
-	_, _, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Getuid() (uid int) {
-	r0, _, _ := RawSyscall(SYS_GETUID, 0, 0, 0)
-	uid = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Issetugid() (tainted bool) {
-	r0, _, _ := Syscall(SYS_ISSETUGID, 0, 0, 0)
-	tainted = bool(r0 != 0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Kill(pid int, signum Signal) (err error) {
-	_, _, e1 := Syscall(SYS_KILL, uintptr(pid), uintptr(signum), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Kqueue() (fd int, err error) {
-	r0, _, e1 := Syscall(SYS_KQUEUE, 0, 0, 0)
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Lchown(path string, uid int, gid int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_LCHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Link(path string, link string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(link)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_LINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Listen(s int, backlog int) (err error) {
-	_, _, e1 := Syscall(SYS_LISTEN, uintptr(s), uintptr(backlog), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Lstat(path string, stat *Stat_t) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_LSTAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mkdir(path string, mode uint32) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_MKDIR, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mkfifo(path string, mode uint32) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_MKFIFO, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mknod(path string, mode uint32, dev int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_MKNOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Nanosleep(time *Timespec, leftover *Timespec) (err error) {
-	_, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Open(path string, mode int, perm uint32) (fd int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Pathconf(path string, name int) (val int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	r0, _, e1 := Syscall(SYS_PATHCONF, uintptr(unsafe.Pointer(_p0)), uintptr(name), 0)
-	val = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Pread(fd int, p []byte, offset int64) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall6(SYS_PREAD, uintptr(fd), uintptr(_p0), uintptr(len(p)), 0, uintptr(offset), 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall6(SYS_PWRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)), 0, uintptr(offset), 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func read(fd int, p []byte) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(_p0), uintptr(len(p)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Readlink(path string, buf []byte) (n int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 unsafe.Pointer
-	if len(buf) > 0 {
-		_p1 = unsafe.Pointer(&buf[0])
-	} else {
-		_p1 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall(SYS_READLINK, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Rename(from string, to string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(from)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(to)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_RENAME, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Revoke(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_REVOKE, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Rmdir(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_RMDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
-	r0, _, e1 := Syscall6(SYS_LSEEK, uintptr(fd), 0, uintptr(offset), uintptr(whence), 0, 0)
-	newoffset = int64(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Select(n int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (err error) {
-	_, _, e1 := Syscall6(SYS_SELECT, uintptr(n), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setegid(egid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETEGID, uintptr(egid), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Seteuid(euid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETEUID, uintptr(euid), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setgid(gid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETGID, uintptr(gid), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setlogin(name string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(name)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_SETLOGIN, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setpgid(pid int, pgid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETPGID, uintptr(pid), uintptr(pgid), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setpriority(which int, who int, prio int) (err error) {
-	_, _, e1 := Syscall(SYS_SETPRIORITY, uintptr(which), uintptr(who), uintptr(prio))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setregid(rgid int, egid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setreuid(ruid int, euid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setrlimit(which int, lim *Rlimit) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setsid() (pid int, err error) {
-	r0, _, e1 := RawSyscall(SYS_SETSID, 0, 0, 0)
-	pid = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Settimeofday(tp *Timeval) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETTIMEOFDAY, uintptr(unsafe.Pointer(tp)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Setuid(uid int) (err error) {
-	_, _, e1 := RawSyscall(SYS_SETUID, uintptr(uid), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Stat(path string, stat *Stat_t) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Statfs(path string, stat *Statfs_t) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_STATFS, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Symlink(path string, link string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(link)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_SYMLINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Sync() (err error) {
-	_, _, e1 := Syscall(SYS_SYNC, 0, 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Truncate(path string, length int64) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_TRUNCATE, uintptr(unsafe.Pointer(_p0)), 0, uintptr(length))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Umask(newmask int) (oldmask int) {
-	r0, _, _ := Syscall(SYS_UMASK, uintptr(newmask), 0, 0)
-	oldmask = int(r0)
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Unlink(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_UNLINK, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Unmount(path string, flags int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := Syscall(SYS_UNMOUNT, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func write(fd int, p []byte) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) {
-	r0, _, e1 := Syscall9(SYS_MMAP, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), 0, uintptr(pos), 0, 0)
-	ret = uintptr(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func munmap(addr uintptr, length uintptr) (err error) {
-	_, _, e1 := Syscall(SYS_MUNMAP, uintptr(addr), uintptr(length), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func readlen(fd int, buf *byte, nbuf int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func writelen(fd int, buf *byte, nbuf int) (n int, err error) {
-	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
diff --git a/src/pkg/syscall/zsyscall_plan9_386.go b/src/pkg/syscall/zsyscall_plan9_386.go
deleted file mode 100644
index 5ffa0e4..0000000
--- a/src/pkg/syscall/zsyscall_plan9_386.go
+++ /dev/null
@@ -1,282 +0,0 @@
-// mksyscall.pl -l32 -plan9 syscall_plan9.go syscall_plan9_386.go
-// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
-
-package syscall
-
-import "unsafe"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func fd2path(fd int, buf []byte) (err error) {
-	var _p0 unsafe.Pointer
-	if len(buf) > 0 {
-		_p0 = unsafe.Pointer(&buf[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall(SYS_FD2PATH, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
-	if int(r0) == -1 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func pipe(p *[2]_C_int) (err error) {
-	r0, _, e1 := Syscall(SYS_PIPE, uintptr(unsafe.Pointer(p)), 0, 0)
-	if int(r0) == -1 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func await(s []byte) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(s) > 0 {
-		_p0 = unsafe.Pointer(&s[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall(SYS_AWAIT, uintptr(_p0), uintptr(len(s)), 0)
-	n = int(r0)
-	if int(r0) == -1 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Dup(oldfd int, newfd int) (fd int, err error) {
-	r0, _, e1 := Syscall(SYS_DUP, uintptr(oldfd), uintptr(newfd), 0)
-	fd = int(r0)
-	if int(r0) == -1 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Open(path string, mode int) (fd int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
-	fd = int(r0)
-	if int(r0) == -1 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Create(path string, mode int, perm uint32) (fd int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	r0, _, e1 := Syscall(SYS_CREATE, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
-	fd = int(r0)
-	if int(r0) == -1 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Remove(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	r0, _, e1 := Syscall(SYS_REMOVE, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if int(r0) == -1 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Pread(fd int, p []byte, offset int64) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall6(SYS_PREAD, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), uintptr(offset>>32), 0)
-	n = int(r0)
-	if int(r0) == -1 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall6(SYS_PWRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), uintptr(offset>>32), 0)
-	n = int(r0)
-	if int(r0) == -1 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Close(fd int) (err error) {
-	r0, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0)
-	if int(r0) == -1 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chdir(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	r0, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if int(r0) == -1 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Bind(name string, old string, flag int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(name)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(old)
-	if err != nil {
-		return
-	}
-	r0, _, e1 := Syscall(SYS_BIND, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(flag))
-	if int(r0) == -1 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mount(fd int, afd int, old string, flag int, aname string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(old)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(aname)
-	if err != nil {
-		return
-	}
-	r0, _, e1 := Syscall6(SYS_MOUNT, uintptr(fd), uintptr(afd), uintptr(unsafe.Pointer(_p0)), uintptr(flag), uintptr(unsafe.Pointer(_p1)), 0)
-	if int(r0) == -1 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Stat(path string, edir []byte) (n int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 unsafe.Pointer
-	if len(edir) > 0 {
-		_p1 = unsafe.Pointer(&edir[0])
-	} else {
-		_p1 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(edir)))
-	n = int(r0)
-	if int(r0) == -1 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fstat(fd int, edir []byte) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(edir) > 0 {
-		_p0 = unsafe.Pointer(&edir[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(_p0), uintptr(len(edir)))
-	n = int(r0)
-	if int(r0) == -1 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Wstat(path string, edir []byte) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 unsafe.Pointer
-	if len(edir) > 0 {
-		_p1 = unsafe.Pointer(&edir[0])
-	} else {
-		_p1 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall(SYS_WSTAT, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(edir)))
-	if int(r0) == -1 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fwstat(fd int, edir []byte) (err error) {
-	var _p0 unsafe.Pointer
-	if len(edir) > 0 {
-		_p0 = unsafe.Pointer(&edir[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall(SYS_FWSTAT, uintptr(fd), uintptr(_p0), uintptr(len(edir)))
-	if int(r0) == -1 {
-		err = e1
-	}
-	return
-}
diff --git a/src/pkg/syscall/zsyscall_plan9_amd64.go b/src/pkg/syscall/zsyscall_plan9_amd64.go
deleted file mode 100644
index c64533f..0000000
--- a/src/pkg/syscall/zsyscall_plan9_amd64.go
+++ /dev/null
@@ -1,282 +0,0 @@
-// mksyscall.pl -l32 -plan9 syscall_plan9.go syscall_plan9_amd64.go
-// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
-
-package syscall
-
-import "unsafe"
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func fd2path(fd int, buf []byte) (err error) {
-	var _p0 unsafe.Pointer
-	if len(buf) > 0 {
-		_p0 = unsafe.Pointer(&buf[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall(SYS_FD2PATH, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
-	if int32(r0) == -1 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func pipe(p *[2]_C_int) (err error) {
-	r0, _, e1 := Syscall(SYS_PIPE, uintptr(unsafe.Pointer(p)), 0, 0)
-	if int32(r0) == -1 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func await(s []byte) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(s) > 0 {
-		_p0 = unsafe.Pointer(&s[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall(SYS_AWAIT, uintptr(_p0), uintptr(len(s)), 0)
-	n = int(r0)
-	if int32(r0) == -1 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Dup(oldfd int, newfd int) (fd int, err error) {
-	r0, _, e1 := Syscall(SYS_DUP, uintptr(oldfd), uintptr(newfd), 0)
-	fd = int(r0)
-	if int32(r0) == -1 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Open(path string, mode int) (fd int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
-	fd = int(r0)
-	if int32(r0) == -1 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Create(path string, mode int, perm uint32) (fd int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	r0, _, e1 := Syscall(SYS_CREATE, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
-	fd = int(r0)
-	if int32(r0) == -1 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Remove(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	r0, _, e1 := Syscall(SYS_REMOVE, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if int32(r0) == -1 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Pread(fd int, p []byte, offset int64) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall6(SYS_PREAD, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), uintptr(offset>>32), 0)
-	n = int(r0)
-	if int32(r0) == -1 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(p) > 0 {
-		_p0 = unsafe.Pointer(&p[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall6(SYS_PWRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), uintptr(offset>>32), 0)
-	n = int(r0)
-	if int32(r0) == -1 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Close(fd int) (err error) {
-	r0, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0)
-	if int32(r0) == -1 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Chdir(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	r0, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	if int32(r0) == -1 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Bind(name string, old string, flag int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(name)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(old)
-	if err != nil {
-		return
-	}
-	r0, _, e1 := Syscall(SYS_BIND, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(flag))
-	if int32(r0) == -1 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Mount(fd int, afd int, old string, flag int, aname string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(old)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(aname)
-	if err != nil {
-		return
-	}
-	r0, _, e1 := Syscall6(SYS_MOUNT, uintptr(fd), uintptr(afd), uintptr(unsafe.Pointer(_p0)), uintptr(flag), uintptr(unsafe.Pointer(_p1)), 0)
-	if int32(r0) == -1 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Stat(path string, edir []byte) (n int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 unsafe.Pointer
-	if len(edir) > 0 {
-		_p1 = unsafe.Pointer(&edir[0])
-	} else {
-		_p1 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(edir)))
-	n = int(r0)
-	if int32(r0) == -1 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fstat(fd int, edir []byte) (n int, err error) {
-	var _p0 unsafe.Pointer
-	if len(edir) > 0 {
-		_p0 = unsafe.Pointer(&edir[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(_p0), uintptr(len(edir)))
-	n = int(r0)
-	if int32(r0) == -1 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Wstat(path string, edir []byte) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 unsafe.Pointer
-	if len(edir) > 0 {
-		_p1 = unsafe.Pointer(&edir[0])
-	} else {
-		_p1 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall(SYS_WSTAT, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(edir)))
-	if int32(r0) == -1 {
-		err = e1
-	}
-	return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Fwstat(fd int, edir []byte) (err error) {
-	var _p0 unsafe.Pointer
-	if len(edir) > 0 {
-		_p0 = unsafe.Pointer(&edir[0])
-	} else {
-		_p0 = unsafe.Pointer(&_zero)
-	}
-	r0, _, e1 := Syscall(SYS_FWSTAT, uintptr(fd), uintptr(_p0), uintptr(len(edir)))
-	if int32(r0) == -1 {
-		err = e1
-	}
-	return
-}
diff --git a/src/pkg/syscall/zsyscall_solaris_amd64.go b/src/pkg/syscall/zsyscall_solaris_amd64.go
deleted file mode 100644
index 8847cad..0000000
--- a/src/pkg/syscall/zsyscall_solaris_amd64.go
+++ /dev/null
@@ -1,883 +0,0 @@
-// mksyscall_solaris.pl syscall_solaris.go syscall_solaris_amd64.go
-// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
-
-package syscall
-
-import "unsafe"
-
-var (
-	modlibc      = newLazySO("libc.so")
-	modlibsocket = newLazySO("libsocket.so")
-
-	procgetgroups    = modlibc.NewProc("getgroups")
-	procsetgroups    = modlibc.NewProc("setgroups")
-	procfcntl        = modlibc.NewProc("fcntl")
-	procaccept       = modlibsocket.NewProc("accept")
-	procsendmsg      = modlibsocket.NewProc("sendmsg")
-	procAccess       = modlibc.NewProc("access")
-	procAdjtime      = modlibc.NewProc("adjtime")
-	procChdir        = modlibc.NewProc("chdir")
-	procChmod        = modlibc.NewProc("chmod")
-	procChown        = modlibc.NewProc("chown")
-	procChroot       = modlibc.NewProc("chroot")
-	procClose        = modlibc.NewProc("close")
-	procDup          = modlibc.NewProc("dup")
-	procExit         = modlibc.NewProc("exit")
-	procFchdir       = modlibc.NewProc("fchdir")
-	procFchmod       = modlibc.NewProc("fchmod")
-	procFchown       = modlibc.NewProc("fchown")
-	procFpathconf    = modlibc.NewProc("fpathconf")
-	procFstat        = modlibc.NewProc("fstat")
-	procGetdents     = modlibc.NewProc("getdents")
-	procGetgid       = modlibc.NewProc("getgid")
-	procGetpid       = modlibc.NewProc("getpid")
-	procGeteuid      = modlibc.NewProc("geteuid")
-	procGetegid      = modlibc.NewProc("getegid")
-	procGetppid      = modlibc.NewProc("getppid")
-	procGetpriority  = modlibc.NewProc("getpriority")
-	procGetrlimit    = modlibc.NewProc("getrlimit")
-	procGettimeofday = modlibc.NewProc("gettimeofday")
-	procGetuid       = modlibc.NewProc("getuid")
-	procKill         = modlibc.NewProc("kill")
-	procLchown       = modlibc.NewProc("lchown")
-	procLink         = modlibc.NewProc("link")
-	proclisten       = modlibsocket.NewProc("listen")
-	procLstat        = modlibc.NewProc("lstat")
-	procMkdir        = modlibc.NewProc("mkdir")
-	procMknod        = modlibc.NewProc("mknod")
-	procNanosleep    = modlibc.NewProc("nanosleep")
-	procOpen         = modlibc.NewProc("open")
-	procPathconf     = modlibc.NewProc("pathconf")
-	procPread        = modlibc.NewProc("pread")
-	procPwrite       = modlibc.NewProc("pwrite")
-	procread         = modlibc.NewProc("read")
-	procReadlink     = modlibc.NewProc("readlink")
-	procRename       = modlibc.NewProc("rename")
-	procRmdir        = modlibc.NewProc("rmdir")
-	proclseek        = modlibc.NewProc("lseek")
-	procSetegid      = modlibc.NewProc("setegid")
-	procSeteuid      = modlibc.NewProc("seteuid")
-	procSetgid       = modlibc.NewProc("setgid")
-	procSetpgid      = modlibc.NewProc("setpgid")
-	procSetpriority  = modlibc.NewProc("setpriority")
-	procSetregid     = modlibc.NewProc("setregid")
-	procSetreuid     = modlibc.NewProc("setreuid")
-	procSetrlimit    = modlibc.NewProc("setrlimit")
-	procSetsid       = modlibc.NewProc("setsid")
-	procSetuid       = modlibc.NewProc("setuid")
-	procshutdown     = modlibsocket.NewProc("shutdown")
-	procStat         = modlibc.NewProc("stat")
-	procSymlink      = modlibc.NewProc("symlink")
-	procSync         = modlibc.NewProc("sync")
-	procTruncate     = modlibc.NewProc("truncate")
-	procFsync        = modlibc.NewProc("fsync")
-	procFtruncate    = modlibc.NewProc("ftruncate")
-	procUmask        = modlibc.NewProc("umask")
-	procUnlink       = modlibc.NewProc("unlink")
-	procUtimes       = modlibc.NewProc("utimes")
-	procbind         = modlibsocket.NewProc("bind")
-	procconnect      = modlibsocket.NewProc("connect")
-	procmmap         = modlibc.NewProc("mmap")
-	procmunmap       = modlibc.NewProc("munmap")
-	procsendto       = modlibsocket.NewProc("sendto")
-	procsocket       = modlibsocket.NewProc("socket")
-	procsocketpair   = modlibsocket.NewProc("socketpair")
-	procwrite        = modlibc.NewProc("write")
-	procgetsockopt   = modlibsocket.NewProc("getsockopt")
-	procgetpeername  = modlibsocket.NewProc("getpeername")
-	procgetsockname  = modlibsocket.NewProc("getsockname")
-	procsetsockopt   = modlibsocket.NewProc("setsockopt")
-	procrecvfrom     = modlibsocket.NewProc("recvfrom")
-	procrecvmsg      = modlibsocket.NewProc("recvmsg")
-)
-
-func getgroups(ngid int, gid *_Gid_t) (n int, err error) {
-	r0, _, e1 := rawSysvicall6(procgetgroups.Addr(), 2, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0, 0, 0, 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-func setgroups(ngid int, gid *_Gid_t) (err error) {
-	_, _, e1 := rawSysvicall6(procsetgroups.Addr(), 2, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0, 0, 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-func fcntl(fd int, cmd int, arg int) (val int, err error) {
-	r0, _, e1 := sysvicall6(procfcntl.Addr(), 3, uintptr(fd), uintptr(cmd), uintptr(arg), 0, 0, 0)
-	val = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
-	r0, _, e1 := sysvicall6(procaccept.Addr(), 3, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), 0, 0, 0)
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
-	r0, _, e1 := sysvicall6(procsendmsg.Addr(), 3, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags), 0, 0, 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-func Access(path string, mode uint32) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := sysvicall6(procAccess.Addr(), 2, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0, 0, 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-func Adjtime(delta *Timeval, olddelta *Timeval) (err error) {
-	_, _, e1 := sysvicall6(procAdjtime.Addr(), 2, uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0, 0, 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-func Chdir(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := sysvicall6(procChdir.Addr(), 1, uintptr(unsafe.Pointer(_p0)), 0, 0, 0, 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-func Chmod(path string, mode uint32) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := sysvicall6(procChmod.Addr(), 2, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0, 0, 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-func Chown(path string, uid int, gid int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := sysvicall6(procChown.Addr(), 3, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid), 0, 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-func Chroot(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := sysvicall6(procChroot.Addr(), 1, uintptr(unsafe.Pointer(_p0)), 0, 0, 0, 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-func Close(fd int) (err error) {
-	_, _, e1 := sysvicall6(procClose.Addr(), 1, uintptr(fd), 0, 0, 0, 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-func Dup(fd int) (nfd int, err error) {
-	r0, _, e1 := sysvicall6(procDup.Addr(), 1, uintptr(fd), 0, 0, 0, 0, 0)
-	nfd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-func Exit(code int) {
-	sysvicall6(procExit.Addr(), 1, uintptr(code), 0, 0, 0, 0, 0)
-	return
-}
-
-func Fchdir(fd int) (err error) {
-	_, _, e1 := sysvicall6(procFchdir.Addr(), 1, uintptr(fd), 0, 0, 0, 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-func Fchmod(fd int, mode uint32) (err error) {
-	_, _, e1 := sysvicall6(procFchmod.Addr(), 2, uintptr(fd), uintptr(mode), 0, 0, 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-func Fchown(fd int, uid int, gid int) (err error) {
-	_, _, e1 := sysvicall6(procFchown.Addr(), 3, uintptr(fd), uintptr(uid), uintptr(gid), 0, 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-func Fpathconf(fd int, name int) (val int, err error) {
-	r0, _, e1 := sysvicall6(procFpathconf.Addr(), 2, uintptr(fd), uintptr(name), 0, 0, 0, 0)
-	val = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-func Fstat(fd int, stat *Stat_t) (err error) {
-	_, _, e1 := sysvicall6(procFstat.Addr(), 2, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0, 0, 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-func Getdents(fd int, buf []byte, basep *uintptr) (n int, err error) {
-	var _p0 *byte
-	if len(buf) > 0 {
-		_p0 = &buf[0]
-	}
-	r0, _, e1 := sysvicall6(procGetdents.Addr(), 4, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(unsafe.Pointer(basep)), 0, 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-func Getgid() (gid int) {
-	r0, _, _ := rawSysvicall6(procGetgid.Addr(), 0, 0, 0, 0, 0, 0, 0)
-	gid = int(r0)
-	return
-}
-
-func Getpid() (pid int) {
-	r0, _, _ := rawSysvicall6(procGetpid.Addr(), 0, 0, 0, 0, 0, 0, 0)
-	pid = int(r0)
-	return
-}
-
-func Geteuid() (euid int) {
-	r0, _, _ := sysvicall6(procGeteuid.Addr(), 0, 0, 0, 0, 0, 0, 0)
-	euid = int(r0)
-	return
-}
-
-func Getegid() (egid int) {
-	r0, _, _ := sysvicall6(procGetegid.Addr(), 0, 0, 0, 0, 0, 0, 0)
-	egid = int(r0)
-	return
-}
-
-func Getppid() (ppid int) {
-	r0, _, _ := sysvicall6(procGetppid.Addr(), 0, 0, 0, 0, 0, 0, 0)
-	ppid = int(r0)
-	return
-}
-
-func Getpriority(which int, who int) (n int, err error) {
-	r0, _, e1 := sysvicall6(procGetpriority.Addr(), 2, uintptr(which), uintptr(who), 0, 0, 0, 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-func Getrlimit(which int, lim *Rlimit) (err error) {
-	_, _, e1 := rawSysvicall6(procGetrlimit.Addr(), 2, uintptr(which), uintptr(unsafe.Pointer(lim)), 0, 0, 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-func Gettimeofday(tv *Timeval) (err error) {
-	_, _, e1 := rawSysvicall6(procGettimeofday.Addr(), 1, uintptr(unsafe.Pointer(tv)), 0, 0, 0, 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-func Getuid() (uid int) {
-	r0, _, _ := rawSysvicall6(procGetuid.Addr(), 0, 0, 0, 0, 0, 0, 0)
-	uid = int(r0)
-	return
-}
-
-func Kill(pid int, signum Signal) (err error) {
-	_, _, e1 := sysvicall6(procKill.Addr(), 2, uintptr(pid), uintptr(signum), 0, 0, 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-func Lchown(path string, uid int, gid int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := sysvicall6(procLchown.Addr(), 3, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid), 0, 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-func Link(path string, link string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(link)
-	if err != nil {
-		return
-	}
-	_, _, e1 := sysvicall6(procLink.Addr(), 2, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0, 0, 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-func Listen(s int, backlog int) (err error) {
-	_, _, e1 := sysvicall6(proclisten.Addr(), 2, uintptr(s), uintptr(backlog), 0, 0, 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-func Lstat(path string, stat *Stat_t) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := sysvicall6(procLstat.Addr(), 2, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0, 0, 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-func Mkdir(path string, mode uint32) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := sysvicall6(procMkdir.Addr(), 2, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0, 0, 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-func Mknod(path string, mode uint32, dev int) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := sysvicall6(procMknod.Addr(), 3, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev), 0, 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-func Nanosleep(time *Timespec, leftover *Timespec) (err error) {
-	_, _, e1 := sysvicall6(procNanosleep.Addr(), 2, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0, 0, 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-func Open(path string, mode int, perm uint32) (fd int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	r0, _, e1 := sysvicall6(procOpen.Addr(), 3, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm), 0, 0, 0)
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-func Pathconf(path string, name int) (val int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	r0, _, e1 := sysvicall6(procPathconf.Addr(), 2, uintptr(unsafe.Pointer(_p0)), uintptr(name), 0, 0, 0, 0)
-	val = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-func Pread(fd int, p []byte, offset int64) (n int, err error) {
-	var _p0 *byte
-	if len(p) > 0 {
-		_p0 = &p[0]
-	}
-	r0, _, e1 := sysvicall6(procPread.Addr(), 4, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(len(p)), uintptr(offset), 0, 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
-	var _p0 *byte
-	if len(p) > 0 {
-		_p0 = &p[0]
-	}
-	r0, _, e1 := sysvicall6(procPwrite.Addr(), 4, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(len(p)), uintptr(offset), 0, 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-func read(fd int, p []byte) (n int, err error) {
-	var _p0 *byte
-	if len(p) > 0 {
-		_p0 = &p[0]
-	}
-	r0, _, e1 := sysvicall6(procread.Addr(), 3, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(len(p)), 0, 0, 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-func Readlink(path string, buf []byte) (n int, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	if len(buf) > 0 {
-		_p1 = &buf[0]
-	}
-	r0, _, e1 := sysvicall6(procReadlink.Addr(), 3, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(len(buf)), 0, 0, 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-func Rename(from string, to string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(from)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(to)
-	if err != nil {
-		return
-	}
-	_, _, e1 := sysvicall6(procRename.Addr(), 2, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0, 0, 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-func Rmdir(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := sysvicall6(procRmdir.Addr(), 1, uintptr(unsafe.Pointer(_p0)), 0, 0, 0, 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
-	r0, _, e1 := sysvicall6(proclseek.Addr(), 3, uintptr(fd), uintptr(offset), uintptr(whence), 0, 0, 0)
-	newoffset = int64(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-func Setegid(egid int) (err error) {
-	_, _, e1 := rawSysvicall6(procSetegid.Addr(), 1, uintptr(egid), 0, 0, 0, 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-func Seteuid(euid int) (err error) {
-	_, _, e1 := rawSysvicall6(procSeteuid.Addr(), 1, uintptr(euid), 0, 0, 0, 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-func Setgid(gid int) (err error) {
-	_, _, e1 := rawSysvicall6(procSetgid.Addr(), 1, uintptr(gid), 0, 0, 0, 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-func Setpgid(pid int, pgid int) (err error) {
-	_, _, e1 := rawSysvicall6(procSetpgid.Addr(), 2, uintptr(pid), uintptr(pgid), 0, 0, 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-func Setpriority(which int, who int, prio int) (err error) {
-	_, _, e1 := sysvicall6(procSetpriority.Addr(), 3, uintptr(which), uintptr(who), uintptr(prio), 0, 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-func Setregid(rgid int, egid int) (err error) {
-	_, _, e1 := rawSysvicall6(procSetregid.Addr(), 2, uintptr(rgid), uintptr(egid), 0, 0, 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-func Setreuid(ruid int, euid int) (err error) {
-	_, _, e1 := rawSysvicall6(procSetreuid.Addr(), 2, uintptr(ruid), uintptr(euid), 0, 0, 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-func Setrlimit(which int, lim *Rlimit) (err error) {
-	_, _, e1 := rawSysvicall6(procSetrlimit.Addr(), 2, uintptr(which), uintptr(unsafe.Pointer(lim)), 0, 0, 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-func Setsid() (pid int, err error) {
-	r0, _, e1 := rawSysvicall6(procSetsid.Addr(), 0, 0, 0, 0, 0, 0, 0)
-	pid = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-func Setuid(uid int) (err error) {
-	_, _, e1 := rawSysvicall6(procSetuid.Addr(), 1, uintptr(uid), 0, 0, 0, 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-func Shutdown(s int, how int) (err error) {
-	_, _, e1 := sysvicall6(procshutdown.Addr(), 2, uintptr(s), uintptr(how), 0, 0, 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-func Stat(path string, stat *Stat_t) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := sysvicall6(procStat.Addr(), 2, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0, 0, 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-func Symlink(path string, link string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(link)
-	if err != nil {
-		return
-	}
-	_, _, e1 := sysvicall6(procSymlink.Addr(), 2, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0, 0, 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-func Sync() (err error) {
-	_, _, e1 := sysvicall6(procSync.Addr(), 0, 0, 0, 0, 0, 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-func Truncate(path string, length int64) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := sysvicall6(procTruncate.Addr(), 2, uintptr(unsafe.Pointer(_p0)), uintptr(length), 0, 0, 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-func Fsync(fd int) (err error) {
-	_, _, e1 := sysvicall6(procFsync.Addr(), 1, uintptr(fd), 0, 0, 0, 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-func Ftruncate(fd int, length int64) (err error) {
-	_, _, e1 := sysvicall6(procFtruncate.Addr(), 2, uintptr(fd), uintptr(length), 0, 0, 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-func Umask(newmask int) (oldmask int) {
-	r0, _, _ := sysvicall6(procUmask.Addr(), 1, uintptr(newmask), 0, 0, 0, 0, 0)
-	oldmask = int(r0)
-	return
-}
-
-func Unlink(path string) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := sysvicall6(procUnlink.Addr(), 1, uintptr(unsafe.Pointer(_p0)), 0, 0, 0, 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-func Utimes(path string, times *[2]Timeval) (err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(path)
-	if err != nil {
-		return
-	}
-	_, _, e1 := sysvicall6(procUtimes.Addr(), 2, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), 0, 0, 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
-	_, _, e1 := sysvicall6(procbind.Addr(), 3, uintptr(s), uintptr(addr), uintptr(addrlen), 0, 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
-	_, _, e1 := sysvicall6(procconnect.Addr(), 3, uintptr(s), uintptr(addr), uintptr(addrlen), 0, 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) {
-	r0, _, e1 := sysvicall6(procmmap.Addr(), 6, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), uintptr(pos))
-	ret = uintptr(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-func munmap(addr uintptr, length uintptr) (err error) {
-	_, _, e1 := sysvicall6(procmunmap.Addr(), 2, uintptr(addr), uintptr(length), 0, 0, 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) {
-	var _p0 *byte
-	if len(buf) > 0 {
-		_p0 = &buf[0]
-	}
-	_, _, e1 := sysvicall6(procsendto.Addr(), 6, uintptr(s), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-func socket(domain int, typ int, proto int) (fd int, err error) {
-	r0, _, e1 := sysvicall6(procsocket.Addr(), 3, uintptr(domain), uintptr(typ), uintptr(proto), 0, 0, 0)
-	fd = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) {
-	_, _, e1 := rawSysvicall6(procsocketpair.Addr(), 4, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-func write(fd int, p []byte) (n int, err error) {
-	var _p0 *byte
-	if len(p) > 0 {
-		_p0 = &p[0]
-	}
-	r0, _, e1 := sysvicall6(procwrite.Addr(), 3, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(len(p)), 0, 0, 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) {
-	_, _, e1 := sysvicall6(procgetsockopt.Addr(), 5, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
-	_, _, e1 := rawSysvicall6(procgetpeername.Addr(), 3, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), 0, 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
-	_, _, e1 := sysvicall6(procgetsockname.Addr(), 3, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), 0, 0, 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) {
-	_, _, e1 := sysvicall6(procsetsockopt.Addr(), 5, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) {
-	var _p0 *byte
-	if len(p) > 0 {
-		_p0 = &p[0]
-	}
-	r0, _, e1 := sysvicall6(procrecvfrom.Addr(), 6, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
-
-func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
-	r0, _, e1 := sysvicall6(procrecvmsg.Addr(), 3, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags), 0, 0, 0)
-	n = int(r0)
-	if e1 != 0 {
-		err = e1
-	}
-	return
-}
diff --git a/src/pkg/syscall/zsyscall_windows_386.go b/src/pkg/syscall/zsyscall_windows_386.go
deleted file mode 100644
index 132adaf..0000000
--- a/src/pkg/syscall/zsyscall_windows_386.go
+++ /dev/null
@@ -1,1760 +0,0 @@
-// go build mksyscall_windows.go && ./mksyscall_windows syscall_windows.go security_windows.go syscall_windows_386.go
-// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
-
-package syscall
-
-import "unsafe"
-
-var (
-	modkernel32 = NewLazyDLL("kernel32.dll")
-	modadvapi32 = NewLazyDLL("advapi32.dll")
-	modshell32  = NewLazyDLL("shell32.dll")
-	modmswsock  = NewLazyDLL("mswsock.dll")
-	modcrypt32  = NewLazyDLL("crypt32.dll")
-	modws2_32   = NewLazyDLL("ws2_32.dll")
-	moddnsapi   = NewLazyDLL("dnsapi.dll")
-	modiphlpapi = NewLazyDLL("iphlpapi.dll")
-	modsecur32  = NewLazyDLL("secur32.dll")
-	modnetapi32 = NewLazyDLL("netapi32.dll")
-	moduserenv  = NewLazyDLL("userenv.dll")
-
-	procGetLastError                       = modkernel32.NewProc("GetLastError")
-	procLoadLibraryW                       = modkernel32.NewProc("LoadLibraryW")
-	procFreeLibrary                        = modkernel32.NewProc("FreeLibrary")
-	procGetProcAddress                     = modkernel32.NewProc("GetProcAddress")
-	procGetVersion                         = modkernel32.NewProc("GetVersion")
-	procFormatMessageW                     = modkernel32.NewProc("FormatMessageW")
-	procExitProcess                        = modkernel32.NewProc("ExitProcess")
-	procCreateFileW                        = modkernel32.NewProc("CreateFileW")
-	procReadFile                           = modkernel32.NewProc("ReadFile")
-	procWriteFile                          = modkernel32.NewProc("WriteFile")
-	procSetFilePointer                     = modkernel32.NewProc("SetFilePointer")
-	procCloseHandle                        = modkernel32.NewProc("CloseHandle")
-	procGetStdHandle                       = modkernel32.NewProc("GetStdHandle")
-	procFindFirstFileW                     = modkernel32.NewProc("FindFirstFileW")
-	procFindNextFileW                      = modkernel32.NewProc("FindNextFileW")
-	procFindClose                          = modkernel32.NewProc("FindClose")
-	procGetFileInformationByHandle         = modkernel32.NewProc("GetFileInformationByHandle")
-	procGetCurrentDirectoryW               = modkernel32.NewProc("GetCurrentDirectoryW")
-	procSetCurrentDirectoryW               = modkernel32.NewProc("SetCurrentDirectoryW")
-	procCreateDirectoryW                   = modkernel32.NewProc("CreateDirectoryW")
-	procRemoveDirectoryW                   = modkernel32.NewProc("RemoveDirectoryW")
-	procDeleteFileW                        = modkernel32.NewProc("DeleteFileW")
-	procMoveFileW                          = modkernel32.NewProc("MoveFileW")
-	procGetComputerNameW                   = modkernel32.NewProc("GetComputerNameW")
-	procSetEndOfFile                       = modkernel32.NewProc("SetEndOfFile")
-	procGetSystemTimeAsFileTime            = modkernel32.NewProc("GetSystemTimeAsFileTime")
-	procGetTimeZoneInformation             = modkernel32.NewProc("GetTimeZoneInformation")
-	procCreateIoCompletionPort             = modkernel32.NewProc("CreateIoCompletionPort")
-	procGetQueuedCompletionStatus          = modkernel32.NewProc("GetQueuedCompletionStatus")
-	procPostQueuedCompletionStatus         = modkernel32.NewProc("PostQueuedCompletionStatus")
-	procCancelIo                           = modkernel32.NewProc("CancelIo")
-	procCancelIoEx                         = modkernel32.NewProc("CancelIoEx")
-	procCreateProcessW                     = modkernel32.NewProc("CreateProcessW")
-	procOpenProcess                        = modkernel32.NewProc("OpenProcess")
-	procTerminateProcess                   = modkernel32.NewProc("TerminateProcess")
-	procGetExitCodeProcess                 = modkernel32.NewProc("GetExitCodeProcess")
-	procGetStartupInfoW                    = modkernel32.NewProc("GetStartupInfoW")
-	procGetCurrentProcess                  = modkernel32.NewProc("GetCurrentProcess")
-	procGetProcessTimes                    = modkernel32.NewProc("GetProcessTimes")
-	procDuplicateHandle                    = modkernel32.NewProc("DuplicateHandle")
-	procWaitForSingleObject                = modkernel32.NewProc("WaitForSingleObject")
-	procGetTempPathW                       = modkernel32.NewProc("GetTempPathW")
-	procCreatePipe                         = modkernel32.NewProc("CreatePipe")
-	procGetFileType                        = modkernel32.NewProc("GetFileType")
-	procCryptAcquireContextW               = modadvapi32.NewProc("CryptAcquireContextW")
-	procCryptReleaseContext                = modadvapi32.NewProc("CryptReleaseContext")
-	procCryptGenRandom                     = modadvapi32.NewProc("CryptGenRandom")
-	procGetEnvironmentStringsW             = modkernel32.NewProc("GetEnvironmentStringsW")
-	procFreeEnvironmentStringsW            = modkernel32.NewProc("FreeEnvironmentStringsW")
-	procGetEnvironmentVariableW            = modkernel32.NewProc("GetEnvironmentVariableW")
-	procSetEnvironmentVariableW            = modkernel32.NewProc("SetEnvironmentVariableW")
-	procSetFileTime                        = modkernel32.NewProc("SetFileTime")
-	procGetFileAttributesW                 = modkernel32.NewProc("GetFileAttributesW")
-	procSetFileAttributesW                 = modkernel32.NewProc("SetFileAttributesW")
-	procGetFileAttributesExW               = modkernel32.NewProc("GetFileAttributesExW")
-	procGetCommandLineW                    = modkernel32.NewProc("GetCommandLineW")
-	procCommandLineToArgvW                 = modshell32.NewProc("CommandLineToArgvW")
-	procLocalFree                          = modkernel32.NewProc("LocalFree")
-	procSetHandleInformation               = modkernel32.NewProc("SetHandleInformation")
-	procFlushFileBuffers                   = modkernel32.NewProc("FlushFileBuffers")
-	procGetFullPathNameW                   = modkernel32.NewProc("GetFullPathNameW")
-	procGetLongPathNameW                   = modkernel32.NewProc("GetLongPathNameW")
-	procGetShortPathNameW                  = modkernel32.NewProc("GetShortPathNameW")
-	procCreateFileMappingW                 = modkernel32.NewProc("CreateFileMappingW")
-	procMapViewOfFile                      = modkernel32.NewProc("MapViewOfFile")
-	procUnmapViewOfFile                    = modkernel32.NewProc("UnmapViewOfFile")
-	procFlushViewOfFile                    = modkernel32.NewProc("FlushViewOfFile")
-	procVirtualLock                        = modkernel32.NewProc("VirtualLock")
-	procVirtualUnlock                      = modkernel32.NewProc("VirtualUnlock")
-	procTransmitFile                       = modmswsock.NewProc("TransmitFile")
-	procReadDirectoryChangesW              = modkernel32.NewProc("ReadDirectoryChangesW")
-	procCertOpenSystemStoreW               = modcrypt32.NewProc("CertOpenSystemStoreW")
-	procCertOpenStore                      = modcrypt32.NewProc("CertOpenStore")
-	procCertEnumCertificatesInStore        = modcrypt32.NewProc("CertEnumCertificatesInStore")
-	procCertAddCertificateContextToStore   = modcrypt32.NewProc("CertAddCertificateContextToStore")
-	procCertCloseStore                     = modcrypt32.NewProc("CertCloseStore")
-	procCertGetCertificateChain            = modcrypt32.NewProc("CertGetCertificateChain")
-	procCertFreeCertificateChain           = modcrypt32.NewProc("CertFreeCertificateChain")
-	procCertCreateCertificateContext       = modcrypt32.NewProc("CertCreateCertificateContext")
-	procCertFreeCertificateContext         = modcrypt32.NewProc("CertFreeCertificateContext")
-	procCertVerifyCertificateChainPolicy   = modcrypt32.NewProc("CertVerifyCertificateChainPolicy")
-	procRegOpenKeyExW                      = modadvapi32.NewProc("RegOpenKeyExW")
-	procRegCloseKey                        = modadvapi32.NewProc("RegCloseKey")
-	procRegQueryInfoKeyW                   = modadvapi32.NewProc("RegQueryInfoKeyW")
-	procRegEnumKeyExW                      = modadvapi32.NewProc("RegEnumKeyExW")
-	procRegQueryValueExW                   = modadvapi32.NewProc("RegQueryValueExW")
-	procGetCurrentProcessId                = modkernel32.NewProc("GetCurrentProcessId")
-	procGetConsoleMode                     = modkernel32.NewProc("GetConsoleMode")
-	procWriteConsoleW                      = modkernel32.NewProc("WriteConsoleW")
-	procReadConsoleW                       = modkernel32.NewProc("ReadConsoleW")
-	procWSAStartup                         = modws2_32.NewProc("WSAStartup")
-	procWSACleanup                         = modws2_32.NewProc("WSACleanup")
-	procWSAIoctl                           = modws2_32.NewProc("WSAIoctl")
-	procsocket                             = modws2_32.NewProc("socket")
-	procsetsockopt                         = modws2_32.NewProc("setsockopt")
-	procgetsockopt                         = modws2_32.NewProc("getsockopt")
-	procbind                               = modws2_32.NewProc("bind")
-	procconnect                            = modws2_32.NewProc("connect")
-	procgetsockname                        = modws2_32.NewProc("getsockname")
-	procgetpeername                        = modws2_32.NewProc("getpeername")
-	proclisten                             = modws2_32.NewProc("listen")
-	procshutdown                           = modws2_32.NewProc("shutdown")
-	procclosesocket                        = modws2_32.NewProc("closesocket")
-	procAcceptEx                           = modmswsock.NewProc("AcceptEx")
-	procGetAcceptExSockaddrs               = modmswsock.NewProc("GetAcceptExSockaddrs")
-	procWSARecv                            = modws2_32.NewProc("WSARecv")
-	procWSASend                            = modws2_32.NewProc("WSASend")
-	procWSARecvFrom                        = modws2_32.NewProc("WSARecvFrom")
-	procWSASendTo                          = modws2_32.NewProc("WSASendTo")
-	procgethostbyname                      = modws2_32.NewProc("gethostbyname")
-	procgetservbyname                      = modws2_32.NewProc("getservbyname")
-	procntohs                              = modws2_32.NewProc("ntohs")
-	procgetprotobyname                     = modws2_32.NewProc("getprotobyname")
-	procDnsQuery_W                         = moddnsapi.NewProc("DnsQuery_W")
-	procDnsRecordListFree                  = moddnsapi.NewProc("DnsRecordListFree")
-	procGetAddrInfoW                       = modws2_32.NewProc("GetAddrInfoW")
-	procFreeAddrInfoW                      = modws2_32.NewProc("FreeAddrInfoW")
-	procGetIfEntry                         = modiphlpapi.NewProc("GetIfEntry")
-	procGetAdaptersInfo                    = modiphlpapi.NewProc("GetAdaptersInfo")
-	procSetFileCompletionNotificationModes = modkernel32.NewProc("SetFileCompletionNotificationModes")
-	procWSAEnumProtocolsW                  = modws2_32.NewProc("WSAEnumProtocolsW")
-	procTranslateNameW                     = modsecur32.NewProc("TranslateNameW")
-	procGetUserNameExW                     = modsecur32.NewProc("GetUserNameExW")
-	procNetUserGetInfo                     = modnetapi32.NewProc("NetUserGetInfo")
-	procNetGetJoinInformation              = modnetapi32.NewProc("NetGetJoinInformation")
-	procNetApiBufferFree                   = modnetapi32.NewProc("NetApiBufferFree")
-	procLookupAccountSidW                  = modadvapi32.NewProc("LookupAccountSidW")
-	procLookupAccountNameW                 = modadvapi32.NewProc("LookupAccountNameW")
-	procConvertSidToStringSidW             = modadvapi32.NewProc("ConvertSidToStringSidW")
-	procConvertStringSidToSidW             = modadvapi32.NewProc("ConvertStringSidToSidW")
-	procGetLengthSid                       = modadvapi32.NewProc("GetLengthSid")
-	procCopySid                            = modadvapi32.NewProc("CopySid")
-	procOpenProcessToken                   = modadvapi32.NewProc("OpenProcessToken")
-	procGetTokenInformation                = modadvapi32.NewProc("GetTokenInformation")
-	procGetUserProfileDirectoryW           = moduserenv.NewProc("GetUserProfileDirectoryW")
-)
-
-func GetLastError() (lasterr error) {
-	r0, _, _ := Syscall(procGetLastError.Addr(), 0, 0, 0, 0)
-	if r0 != 0 {
-		lasterr = Errno(r0)
-	}
-	return
-}
-
-func LoadLibrary(libname string) (handle Handle, err error) {
-	var _p0 *uint16
-	_p0, err = UTF16PtrFromString(libname)
-	if err != nil {
-		return
-	}
-	r0, _, e1 := Syscall(procLoadLibraryW.Addr(), 1, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	handle = Handle(r0)
-	if handle == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func FreeLibrary(handle Handle) (err error) {
-	r1, _, e1 := Syscall(procFreeLibrary.Addr(), 1, uintptr(handle), 0, 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func GetProcAddress(module Handle, procname string) (proc uintptr, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(procname)
-	if err != nil {
-		return
-	}
-	r0, _, e1 := Syscall(procGetProcAddress.Addr(), 2, uintptr(module), uintptr(unsafe.Pointer(_p0)), 0)
-	proc = uintptr(r0)
-	if proc == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func GetVersion() (ver uint32, err error) {
-	r0, _, e1 := Syscall(procGetVersion.Addr(), 0, 0, 0, 0)
-	ver = uint32(r0)
-	if ver == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func FormatMessage(flags uint32, msgsrc uint32, msgid uint32, langid uint32, buf []uint16, args *byte) (n uint32, err error) {
-	var _p0 *uint16
-	if len(buf) > 0 {
-		_p0 = &buf[0]
-	}
-	r0, _, e1 := Syscall9(procFormatMessageW.Addr(), 7, uintptr(flags), uintptr(msgsrc), uintptr(msgid), uintptr(langid), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(unsafe.Pointer(args)), 0, 0)
-	n = uint32(r0)
-	if n == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func ExitProcess(exitcode uint32) {
-	Syscall(procExitProcess.Addr(), 1, uintptr(exitcode), 0, 0)
-	return
-}
-
-func CreateFile(name *uint16, access uint32, mode uint32, sa *SecurityAttributes, createmode uint32, attrs uint32, templatefile int32) (handle Handle, err error) {
-	r0, _, e1 := Syscall9(procCreateFileW.Addr(), 7, uintptr(unsafe.Pointer(name)), uintptr(access), uintptr(mode), uintptr(unsafe.Pointer(sa)), uintptr(createmode), uintptr(attrs), uintptr(templatefile), 0, 0)
-	handle = Handle(r0)
-	if handle == InvalidHandle {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func ReadFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) (err error) {
-	var _p0 *byte
-	if len(buf) > 0 {
-		_p0 = &buf[0]
-	}
-	r1, _, e1 := Syscall6(procReadFile.Addr(), 5, uintptr(handle), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(unsafe.Pointer(done)), uintptr(unsafe.Pointer(overlapped)), 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func WriteFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) (err error) {
-	var _p0 *byte
-	if len(buf) > 0 {
-		_p0 = &buf[0]
-	}
-	r1, _, e1 := Syscall6(procWriteFile.Addr(), 5, uintptr(handle), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(unsafe.Pointer(done)), uintptr(unsafe.Pointer(overlapped)), 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func SetFilePointer(handle Handle, lowoffset int32, highoffsetptr *int32, whence uint32) (newlowoffset uint32, err error) {
-	r0, _, e1 := Syscall6(procSetFilePointer.Addr(), 4, uintptr(handle), uintptr(lowoffset), uintptr(unsafe.Pointer(highoffsetptr)), uintptr(whence), 0, 0)
-	newlowoffset = uint32(r0)
-	if newlowoffset == 0xffffffff {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func CloseHandle(handle Handle) (err error) {
-	r1, _, e1 := Syscall(procCloseHandle.Addr(), 1, uintptr(handle), 0, 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func GetStdHandle(stdhandle int) (handle Handle, err error) {
-	r0, _, e1 := Syscall(procGetStdHandle.Addr(), 1, uintptr(stdhandle), 0, 0)
-	handle = Handle(r0)
-	if handle == InvalidHandle {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func findFirstFile1(name *uint16, data *win32finddata1) (handle Handle, err error) {
-	r0, _, e1 := Syscall(procFindFirstFileW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(data)), 0)
-	handle = Handle(r0)
-	if handle == InvalidHandle {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func findNextFile1(handle Handle, data *win32finddata1) (err error) {
-	r1, _, e1 := Syscall(procFindNextFileW.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(data)), 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func FindClose(handle Handle) (err error) {
-	r1, _, e1 := Syscall(procFindClose.Addr(), 1, uintptr(handle), 0, 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func GetFileInformationByHandle(handle Handle, data *ByHandleFileInformation) (err error) {
-	r1, _, e1 := Syscall(procGetFileInformationByHandle.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(data)), 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func GetCurrentDirectory(buflen uint32, buf *uint16) (n uint32, err error) {
-	r0, _, e1 := Syscall(procGetCurrentDirectoryW.Addr(), 2, uintptr(buflen), uintptr(unsafe.Pointer(buf)), 0)
-	n = uint32(r0)
-	if n == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func SetCurrentDirectory(path *uint16) (err error) {
-	r1, _, e1 := Syscall(procSetCurrentDirectoryW.Addr(), 1, uintptr(unsafe.Pointer(path)), 0, 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func CreateDirectory(path *uint16, sa *SecurityAttributes) (err error) {
-	r1, _, e1 := Syscall(procCreateDirectoryW.Addr(), 2, uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(sa)), 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func RemoveDirectory(path *uint16) (err error) {
-	r1, _, e1 := Syscall(procRemoveDirectoryW.Addr(), 1, uintptr(unsafe.Pointer(path)), 0, 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func DeleteFile(path *uint16) (err error) {
-	r1, _, e1 := Syscall(procDeleteFileW.Addr(), 1, uintptr(unsafe.Pointer(path)), 0, 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func MoveFile(from *uint16, to *uint16) (err error) {
-	r1, _, e1 := Syscall(procMoveFileW.Addr(), 2, uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(to)), 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func GetComputerName(buf *uint16, n *uint32) (err error) {
-	r1, _, e1 := Syscall(procGetComputerNameW.Addr(), 2, uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(n)), 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func SetEndOfFile(handle Handle) (err error) {
-	r1, _, e1 := Syscall(procSetEndOfFile.Addr(), 1, uintptr(handle), 0, 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func GetSystemTimeAsFileTime(time *Filetime) {
-	Syscall(procGetSystemTimeAsFileTime.Addr(), 1, uintptr(unsafe.Pointer(time)), 0, 0)
-	return
-}
-
-func GetTimeZoneInformation(tzi *Timezoneinformation) (rc uint32, err error) {
-	r0, _, e1 := Syscall(procGetTimeZoneInformation.Addr(), 1, uintptr(unsafe.Pointer(tzi)), 0, 0)
-	rc = uint32(r0)
-	if rc == 0xffffffff {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func CreateIoCompletionPort(filehandle Handle, cphandle Handle, key uint32, threadcnt uint32) (handle Handle, err error) {
-	r0, _, e1 := Syscall6(procCreateIoCompletionPort.Addr(), 4, uintptr(filehandle), uintptr(cphandle), uintptr(key), uintptr(threadcnt), 0, 0)
-	handle = Handle(r0)
-	if handle == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func GetQueuedCompletionStatus(cphandle Handle, qty *uint32, key *uint32, overlapped **Overlapped, timeout uint32) (err error) {
-	r1, _, e1 := Syscall6(procGetQueuedCompletionStatus.Addr(), 5, uintptr(cphandle), uintptr(unsafe.Pointer(qty)), uintptr(unsafe.Pointer(key)), uintptr(unsafe.Pointer(overlapped)), uintptr(timeout), 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func PostQueuedCompletionStatus(cphandle Handle, qty uint32, key uint32, overlapped *Overlapped) (err error) {
-	r1, _, e1 := Syscall6(procPostQueuedCompletionStatus.Addr(), 4, uintptr(cphandle), uintptr(qty), uintptr(key), uintptr(unsafe.Pointer(overlapped)), 0, 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func CancelIo(s Handle) (err error) {
-	r1, _, e1 := Syscall(procCancelIo.Addr(), 1, uintptr(s), 0, 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func CancelIoEx(s Handle, o *Overlapped) (err error) {
-	r1, _, e1 := Syscall(procCancelIoEx.Addr(), 2, uintptr(s), uintptr(unsafe.Pointer(o)), 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func CreateProcess(appName *uint16, commandLine *uint16, procSecurity *SecurityAttributes, threadSecurity *SecurityAttributes, inheritHandles bool, creationFlags uint32, env *uint16, currentDir *uint16, startupInfo *StartupInfo, outProcInfo *ProcessInformation) (err error) {
-	var _p0 uint32
-	if inheritHandles {
-		_p0 = 1
-	} else {
-		_p0 = 0
-	}
-	r1, _, e1 := Syscall12(procCreateProcessW.Addr(), 10, uintptr(unsafe.Pointer(appName)), uintptr(unsafe.Pointer(commandLine)), uintptr(unsafe.Pointer(procSecurity)), uintptr(unsafe.Pointer(threadSecurity)), uintptr(_p0), uintptr(creationFlags), uintptr(unsafe.Pointer(env)), uintptr(unsafe.Pointer(currentDir)), uintptr(unsafe.Pointer(startupInfo)), uintptr(unsafe.Pointer(outProcInfo)), 0, 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func OpenProcess(da uint32, inheritHandle bool, pid uint32) (handle Handle, err error) {
-	var _p0 uint32
-	if inheritHandle {
-		_p0 = 1
-	} else {
-		_p0 = 0
-	}
-	r0, _, e1 := Syscall(procOpenProcess.Addr(), 3, uintptr(da), uintptr(_p0), uintptr(pid))
-	handle = Handle(r0)
-	if handle == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func TerminateProcess(handle Handle, exitcode uint32) (err error) {
-	r1, _, e1 := Syscall(procTerminateProcess.Addr(), 2, uintptr(handle), uintptr(exitcode), 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func GetExitCodeProcess(handle Handle, exitcode *uint32) (err error) {
-	r1, _, e1 := Syscall(procGetExitCodeProcess.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(exitcode)), 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func GetStartupInfo(startupInfo *StartupInfo) (err error) {
-	r1, _, e1 := Syscall(procGetStartupInfoW.Addr(), 1, uintptr(unsafe.Pointer(startupInfo)), 0, 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func GetCurrentProcess() (pseudoHandle Handle, err error) {
-	r0, _, e1 := Syscall(procGetCurrentProcess.Addr(), 0, 0, 0, 0)
-	pseudoHandle = Handle(r0)
-	if pseudoHandle == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func GetProcessTimes(handle Handle, creationTime *Filetime, exitTime *Filetime, kernelTime *Filetime, userTime *Filetime) (err error) {
-	r1, _, e1 := Syscall6(procGetProcessTimes.Addr(), 5, uintptr(handle), uintptr(unsafe.Pointer(creationTime)), uintptr(unsafe.Pointer(exitTime)), uintptr(unsafe.Pointer(kernelTime)), uintptr(unsafe.Pointer(userTime)), 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func DuplicateHandle(hSourceProcessHandle Handle, hSourceHandle Handle, hTargetProcessHandle Handle, lpTargetHandle *Handle, dwDesiredAccess uint32, bInheritHandle bool, dwOptions uint32) (err error) {
-	var _p0 uint32
-	if bInheritHandle {
-		_p0 = 1
-	} else {
-		_p0 = 0
-	}
-	r1, _, e1 := Syscall9(procDuplicateHandle.Addr(), 7, uintptr(hSourceProcessHandle), uintptr(hSourceHandle), uintptr(hTargetProcessHandle), uintptr(unsafe.Pointer(lpTargetHandle)), uintptr(dwDesiredAccess), uintptr(_p0), uintptr(dwOptions), 0, 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func WaitForSingleObject(handle Handle, waitMilliseconds uint32) (event uint32, err error) {
-	r0, _, e1 := Syscall(procWaitForSingleObject.Addr(), 2, uintptr(handle), uintptr(waitMilliseconds), 0)
-	event = uint32(r0)
-	if event == 0xffffffff {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func GetTempPath(buflen uint32, buf *uint16) (n uint32, err error) {
-	r0, _, e1 := Syscall(procGetTempPathW.Addr(), 2, uintptr(buflen), uintptr(unsafe.Pointer(buf)), 0)
-	n = uint32(r0)
-	if n == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func CreatePipe(readhandle *Handle, writehandle *Handle, sa *SecurityAttributes, size uint32) (err error) {
-	r1, _, e1 := Syscall6(procCreatePipe.Addr(), 4, uintptr(unsafe.Pointer(readhandle)), uintptr(unsafe.Pointer(writehandle)), uintptr(unsafe.Pointer(sa)), uintptr(size), 0, 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func GetFileType(filehandle Handle) (n uint32, err error) {
-	r0, _, e1 := Syscall(procGetFileType.Addr(), 1, uintptr(filehandle), 0, 0)
-	n = uint32(r0)
-	if n == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func CryptAcquireContext(provhandle *Handle, container *uint16, provider *uint16, provtype uint32, flags uint32) (err error) {
-	r1, _, e1 := Syscall6(procCryptAcquireContextW.Addr(), 5, uintptr(unsafe.Pointer(provhandle)), uintptr(unsafe.Pointer(container)), uintptr(unsafe.Pointer(provider)), uintptr(provtype), uintptr(flags), 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func CryptReleaseContext(provhandle Handle, flags uint32) (err error) {
-	r1, _, e1 := Syscall(procCryptReleaseContext.Addr(), 2, uintptr(provhandle), uintptr(flags), 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func CryptGenRandom(provhandle Handle, buflen uint32, buf *byte) (err error) {
-	r1, _, e1 := Syscall(procCryptGenRandom.Addr(), 3, uintptr(provhandle), uintptr(buflen), uintptr(unsafe.Pointer(buf)))
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func GetEnvironmentStrings() (envs *uint16, err error) {
-	r0, _, e1 := Syscall(procGetEnvironmentStringsW.Addr(), 0, 0, 0, 0)
-	envs = (*uint16)(unsafe.Pointer(r0))
-	if envs == nil {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func FreeEnvironmentStrings(envs *uint16) (err error) {
-	r1, _, e1 := Syscall(procFreeEnvironmentStringsW.Addr(), 1, uintptr(unsafe.Pointer(envs)), 0, 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func GetEnvironmentVariable(name *uint16, buffer *uint16, size uint32) (n uint32, err error) {
-	r0, _, e1 := Syscall(procGetEnvironmentVariableW.Addr(), 3, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(buffer)), uintptr(size))
-	n = uint32(r0)
-	if n == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func SetEnvironmentVariable(name *uint16, value *uint16) (err error) {
-	r1, _, e1 := Syscall(procSetEnvironmentVariableW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(value)), 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func SetFileTime(handle Handle, ctime *Filetime, atime *Filetime, wtime *Filetime) (err error) {
-	r1, _, e1 := Syscall6(procSetFileTime.Addr(), 4, uintptr(handle), uintptr(unsafe.Pointer(ctime)), uintptr(unsafe.Pointer(atime)), uintptr(unsafe.Pointer(wtime)), 0, 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func GetFileAttributes(name *uint16) (attrs uint32, err error) {
-	r0, _, e1 := Syscall(procGetFileAttributesW.Addr(), 1, uintptr(unsafe.Pointer(name)), 0, 0)
-	attrs = uint32(r0)
-	if attrs == INVALID_FILE_ATTRIBUTES {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func SetFileAttributes(name *uint16, attrs uint32) (err error) {
-	r1, _, e1 := Syscall(procSetFileAttributesW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(attrs), 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func GetFileAttributesEx(name *uint16, level uint32, info *byte) (err error) {
-	r1, _, e1 := Syscall(procGetFileAttributesExW.Addr(), 3, uintptr(unsafe.Pointer(name)), uintptr(level), uintptr(unsafe.Pointer(info)))
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func GetCommandLine() (cmd *uint16) {
-	r0, _, _ := Syscall(procGetCommandLineW.Addr(), 0, 0, 0, 0)
-	cmd = (*uint16)(unsafe.Pointer(r0))
-	return
-}
-
-func CommandLineToArgv(cmd *uint16, argc *int32) (argv *[8192]*[8192]uint16, err error) {
-	r0, _, e1 := Syscall(procCommandLineToArgvW.Addr(), 2, uintptr(unsafe.Pointer(cmd)), uintptr(unsafe.Pointer(argc)), 0)
-	argv = (*[8192]*[8192]uint16)(unsafe.Pointer(r0))
-	if argv == nil {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func LocalFree(hmem Handle) (handle Handle, err error) {
-	r0, _, e1 := Syscall(procLocalFree.Addr(), 1, uintptr(hmem), 0, 0)
-	handle = Handle(r0)
-	if handle != 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func SetHandleInformation(handle Handle, mask uint32, flags uint32) (err error) {
-	r1, _, e1 := Syscall(procSetHandleInformation.Addr(), 3, uintptr(handle), uintptr(mask), uintptr(flags))
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func FlushFileBuffers(handle Handle) (err error) {
-	r1, _, e1 := Syscall(procFlushFileBuffers.Addr(), 1, uintptr(handle), 0, 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func GetFullPathName(path *uint16, buflen uint32, buf *uint16, fname **uint16) (n uint32, err error) {
-	r0, _, e1 := Syscall6(procGetFullPathNameW.Addr(), 4, uintptr(unsafe.Pointer(path)), uintptr(buflen), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(fname)), 0, 0)
-	n = uint32(r0)
-	if n == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func GetLongPathName(path *uint16, buf *uint16, buflen uint32) (n uint32, err error) {
-	r0, _, e1 := Syscall(procGetLongPathNameW.Addr(), 3, uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(buf)), uintptr(buflen))
-	n = uint32(r0)
-	if n == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func GetShortPathName(longpath *uint16, shortpath *uint16, buflen uint32) (n uint32, err error) {
-	r0, _, e1 := Syscall(procGetShortPathNameW.Addr(), 3, uintptr(unsafe.Pointer(longpath)), uintptr(unsafe.Pointer(shortpath)), uintptr(buflen))
-	n = uint32(r0)
-	if n == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func CreateFileMapping(fhandle Handle, sa *SecurityAttributes, prot uint32, maxSizeHigh uint32, maxSizeLow uint32, name *uint16) (handle Handle, err error) {
-	r0, _, e1 := Syscall6(procCreateFileMappingW.Addr(), 6, uintptr(fhandle), uintptr(unsafe.Pointer(sa)), uintptr(prot), uintptr(maxSizeHigh), uintptr(maxSizeLow), uintptr(unsafe.Pointer(name)))
-	handle = Handle(r0)
-	if handle == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func MapViewOfFile(handle Handle, access uint32, offsetHigh uint32, offsetLow uint32, length uintptr) (addr uintptr, err error) {
-	r0, _, e1 := Syscall6(procMapViewOfFile.Addr(), 5, uintptr(handle), uintptr(access), uintptr(offsetHigh), uintptr(offsetLow), uintptr(length), 0)
-	addr = uintptr(r0)
-	if addr == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func UnmapViewOfFile(addr uintptr) (err error) {
-	r1, _, e1 := Syscall(procUnmapViewOfFile.Addr(), 1, uintptr(addr), 0, 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func FlushViewOfFile(addr uintptr, length uintptr) (err error) {
-	r1, _, e1 := Syscall(procFlushViewOfFile.Addr(), 2, uintptr(addr), uintptr(length), 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func VirtualLock(addr uintptr, length uintptr) (err error) {
-	r1, _, e1 := Syscall(procVirtualLock.Addr(), 2, uintptr(addr), uintptr(length), 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func VirtualUnlock(addr uintptr, length uintptr) (err error) {
-	r1, _, e1 := Syscall(procVirtualUnlock.Addr(), 2, uintptr(addr), uintptr(length), 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func TransmitFile(s Handle, handle Handle, bytesToWrite uint32, bytsPerSend uint32, overlapped *Overlapped, transmitFileBuf *TransmitFileBuffers, flags uint32) (err error) {
-	r1, _, e1 := Syscall9(procTransmitFile.Addr(), 7, uintptr(s), uintptr(handle), uintptr(bytesToWrite), uintptr(bytsPerSend), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(transmitFileBuf)), uintptr(flags), 0, 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func ReadDirectoryChanges(handle Handle, buf *byte, buflen uint32, watchSubTree bool, mask uint32, retlen *uint32, overlapped *Overlapped, completionRoutine uintptr) (err error) {
-	var _p0 uint32
-	if watchSubTree {
-		_p0 = 1
-	} else {
-		_p0 = 0
-	}
-	r1, _, e1 := Syscall9(procReadDirectoryChangesW.Addr(), 8, uintptr(handle), uintptr(unsafe.Pointer(buf)), uintptr(buflen), uintptr(_p0), uintptr(mask), uintptr(unsafe.Pointer(retlen)), uintptr(unsafe.Pointer(overlapped)), uintptr(completionRoutine), 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func CertOpenSystemStore(hprov Handle, name *uint16) (store Handle, err error) {
-	r0, _, e1 := Syscall(procCertOpenSystemStoreW.Addr(), 2, uintptr(hprov), uintptr(unsafe.Pointer(name)), 0)
-	store = Handle(r0)
-	if store == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func CertOpenStore(storeProvider uintptr, msgAndCertEncodingType uint32, cryptProv uintptr, flags uint32, para uintptr) (handle Handle, err error) {
-	r0, _, e1 := Syscall6(procCertOpenStore.Addr(), 5, uintptr(storeProvider), uintptr(msgAndCertEncodingType), uintptr(cryptProv), uintptr(flags), uintptr(para), 0)
-	handle = Handle(r0)
-	if handle == InvalidHandle {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func CertEnumCertificatesInStore(store Handle, prevContext *CertContext) (context *CertContext, err error) {
-	r0, _, e1 := Syscall(procCertEnumCertificatesInStore.Addr(), 2, uintptr(store), uintptr(unsafe.Pointer(prevContext)), 0)
-	context = (*CertContext)(unsafe.Pointer(r0))
-	if context == nil {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func CertAddCertificateContextToStore(store Handle, certContext *CertContext, addDisposition uint32, storeContext **CertContext) (err error) {
-	r1, _, e1 := Syscall6(procCertAddCertificateContextToStore.Addr(), 4, uintptr(store), uintptr(unsafe.Pointer(certContext)), uintptr(addDisposition), uintptr(unsafe.Pointer(storeContext)), 0, 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func CertCloseStore(store Handle, flags uint32) (err error) {
-	r1, _, e1 := Syscall(procCertCloseStore.Addr(), 2, uintptr(store), uintptr(flags), 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func CertGetCertificateChain(engine Handle, leaf *CertContext, time *Filetime, additionalStore Handle, para *CertChainPara, flags uint32, reserved uintptr, chainCtx **CertChainContext) (err error) {
-	r1, _, e1 := Syscall9(procCertGetCertificateChain.Addr(), 8, uintptr(engine), uintptr(unsafe.Pointer(leaf)), uintptr(unsafe.Pointer(time)), uintptr(additionalStore), uintptr(unsafe.Pointer(para)), uintptr(flags), uintptr(reserved), uintptr(unsafe.Pointer(chainCtx)), 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func CertFreeCertificateChain(ctx *CertChainContext) {
-	Syscall(procCertFreeCertificateChain.Addr(), 1, uintptr(unsafe.Pointer(ctx)), 0, 0)
-	return
-}
-
-func CertCreateCertificateContext(certEncodingType uint32, certEncoded *byte, encodedLen uint32) (context *CertContext, err error) {
-	r0, _, e1 := Syscall(procCertCreateCertificateContext.Addr(), 3, uintptr(certEncodingType), uintptr(unsafe.Pointer(certEncoded)), uintptr(encodedLen))
-	context = (*CertContext)(unsafe.Pointer(r0))
-	if context == nil {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func CertFreeCertificateContext(ctx *CertContext) (err error) {
-	r1, _, e1 := Syscall(procCertFreeCertificateContext.Addr(), 1, uintptr(unsafe.Pointer(ctx)), 0, 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func CertVerifyCertificateChainPolicy(policyOID uintptr, chain *CertChainContext, para *CertChainPolicyPara, status *CertChainPolicyStatus) (err error) {
-	r1, _, e1 := Syscall6(procCertVerifyCertificateChainPolicy.Addr(), 4, uintptr(policyOID), uintptr(unsafe.Pointer(chain)), uintptr(unsafe.Pointer(para)), uintptr(unsafe.Pointer(status)), 0, 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func RegOpenKeyEx(key Handle, subkey *uint16, options uint32, desiredAccess uint32, result *Handle) (regerrno error) {
-	r0, _, _ := Syscall6(procRegOpenKeyExW.Addr(), 5, uintptr(key), uintptr(unsafe.Pointer(subkey)), uintptr(options), uintptr(desiredAccess), uintptr(unsafe.Pointer(result)), 0)
-	if r0 != 0 {
-		regerrno = Errno(r0)
-	}
-	return
-}
-
-func RegCloseKey(key Handle) (regerrno error) {
-	r0, _, _ := Syscall(procRegCloseKey.Addr(), 1, uintptr(key), 0, 0)
-	if r0 != 0 {
-		regerrno = Errno(r0)
-	}
-	return
-}
-
-func RegQueryInfoKey(key Handle, class *uint16, classLen *uint32, reserved *uint32, subkeysLen *uint32, maxSubkeyLen *uint32, maxClassLen *uint32, valuesLen *uint32, maxValueNameLen *uint32, maxValueLen *uint32, saLen *uint32, lastWriteTime *Filetime) (regerrno error) {
-	r0, _, _ := Syscall12(procRegQueryInfoKeyW.Addr(), 12, uintptr(key), uintptr(unsafe.Pointer(class)), uintptr(unsafe.Pointer(classLen)), uintptr(unsafe.Pointer(reserved)), uintptr(unsafe.Pointer(subkeysLen)), uintptr(unsafe.Pointer(maxSubkeyLen)), uintptr(unsafe.Pointer(maxClassLen)), uintptr(unsafe.Pointer(valuesLen)), uintptr(unsafe.Pointer(maxValueNameLen)), uintptr(unsafe.Pointer(maxValueLen)), uintptr(unsafe.Pointer(saLen)), uintptr(unsafe.Pointer(lastWriteTime)))
-	if r0 != 0 {
-		regerrno = Errno(r0)
-	}
-	return
-}
-
-func RegEnumKeyEx(key Handle, index uint32, name *uint16, nameLen *uint32, reserved *uint32, class *uint16, classLen *uint32, lastWriteTime *Filetime) (regerrno error) {
-	r0, _, _ := Syscall9(procRegEnumKeyExW.Addr(), 8, uintptr(key), uintptr(index), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(nameLen)), uintptr(unsafe.Pointer(reserved)), uintptr(unsafe.Pointer(class)), uintptr(unsafe.Pointer(classLen)), uintptr(unsafe.Pointer(lastWriteTime)), 0)
-	if r0 != 0 {
-		regerrno = Errno(r0)
-	}
-	return
-}
-
-func RegQueryValueEx(key Handle, name *uint16, reserved *uint32, valtype *uint32, buf *byte, buflen *uint32) (regerrno error) {
-	r0, _, _ := Syscall6(procRegQueryValueExW.Addr(), 6, uintptr(key), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(reserved)), uintptr(unsafe.Pointer(valtype)), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(buflen)))
-	if r0 != 0 {
-		regerrno = Errno(r0)
-	}
-	return
-}
-
-func getCurrentProcessId() (pid uint32) {
-	r0, _, _ := Syscall(procGetCurrentProcessId.Addr(), 0, 0, 0, 0)
-	pid = uint32(r0)
-	return
-}
-
-func GetConsoleMode(console Handle, mode *uint32) (err error) {
-	r1, _, e1 := Syscall(procGetConsoleMode.Addr(), 2, uintptr(console), uintptr(unsafe.Pointer(mode)), 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func WriteConsole(console Handle, buf *uint16, towrite uint32, written *uint32, reserved *byte) (err error) {
-	r1, _, e1 := Syscall6(procWriteConsoleW.Addr(), 5, uintptr(console), uintptr(unsafe.Pointer(buf)), uintptr(towrite), uintptr(unsafe.Pointer(written)), uintptr(unsafe.Pointer(reserved)), 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func ReadConsole(console Handle, buf *uint16, toread uint32, read *uint32, inputControl *byte) (err error) {
-	r1, _, e1 := Syscall6(procReadConsoleW.Addr(), 5, uintptr(console), uintptr(unsafe.Pointer(buf)), uintptr(toread), uintptr(unsafe.Pointer(read)), uintptr(unsafe.Pointer(inputControl)), 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func WSAStartup(verreq uint32, data *WSAData) (sockerr error) {
-	r0, _, _ := Syscall(procWSAStartup.Addr(), 2, uintptr(verreq), uintptr(unsafe.Pointer(data)), 0)
-	if r0 != 0 {
-		sockerr = Errno(r0)
-	}
-	return
-}
-
-func WSACleanup() (err error) {
-	r1, _, e1 := Syscall(procWSACleanup.Addr(), 0, 0, 0, 0)
-	if r1 == socket_error {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func WSAIoctl(s Handle, iocc uint32, inbuf *byte, cbif uint32, outbuf *byte, cbob uint32, cbbr *uint32, overlapped *Overlapped, completionRoutine uintptr) (err error) {
-	r1, _, e1 := Syscall9(procWSAIoctl.Addr(), 9, uintptr(s), uintptr(iocc), uintptr(unsafe.Pointer(inbuf)), uintptr(cbif), uintptr(unsafe.Pointer(outbuf)), uintptr(cbob), uintptr(unsafe.Pointer(cbbr)), uintptr(unsafe.Pointer(overlapped)), uintptr(completionRoutine))
-	if r1 == socket_error {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func socket(af int32, typ int32, protocol int32) (handle Handle, err error) {
-	r0, _, e1 := Syscall(procsocket.Addr(), 3, uintptr(af), uintptr(typ), uintptr(protocol))
-	handle = Handle(r0)
-	if handle == InvalidHandle {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func Setsockopt(s Handle, level int32, optname int32, optval *byte, optlen int32) (err error) {
-	r1, _, e1 := Syscall6(procsetsockopt.Addr(), 5, uintptr(s), uintptr(level), uintptr(optname), uintptr(unsafe.Pointer(optval)), uintptr(optlen), 0)
-	if r1 == socket_error {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func Getsockopt(s Handle, level int32, optname int32, optval *byte, optlen *int32) (err error) {
-	r1, _, e1 := Syscall6(procgetsockopt.Addr(), 5, uintptr(s), uintptr(level), uintptr(optname), uintptr(unsafe.Pointer(optval)), uintptr(unsafe.Pointer(optlen)), 0)
-	if r1 == socket_error {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func bind(s Handle, name unsafe.Pointer, namelen int32) (err error) {
-	r1, _, e1 := Syscall(procbind.Addr(), 3, uintptr(s), uintptr(name), uintptr(namelen))
-	if r1 == socket_error {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func connect(s Handle, name unsafe.Pointer, namelen int32) (err error) {
-	r1, _, e1 := Syscall(procconnect.Addr(), 3, uintptr(s), uintptr(name), uintptr(namelen))
-	if r1 == socket_error {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func getsockname(s Handle, rsa *RawSockaddrAny, addrlen *int32) (err error) {
-	r1, _, e1 := Syscall(procgetsockname.Addr(), 3, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
-	if r1 == socket_error {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func getpeername(s Handle, rsa *RawSockaddrAny, addrlen *int32) (err error) {
-	r1, _, e1 := Syscall(procgetpeername.Addr(), 3, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
-	if r1 == socket_error {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func listen(s Handle, backlog int32) (err error) {
-	r1, _, e1 := Syscall(proclisten.Addr(), 2, uintptr(s), uintptr(backlog), 0)
-	if r1 == socket_error {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func shutdown(s Handle, how int32) (err error) {
-	r1, _, e1 := Syscall(procshutdown.Addr(), 2, uintptr(s), uintptr(how), 0)
-	if r1 == socket_error {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func Closesocket(s Handle) (err error) {
-	r1, _, e1 := Syscall(procclosesocket.Addr(), 1, uintptr(s), 0, 0)
-	if r1 == socket_error {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func AcceptEx(ls Handle, as Handle, buf *byte, rxdatalen uint32, laddrlen uint32, raddrlen uint32, recvd *uint32, overlapped *Overlapped) (err error) {
-	r1, _, e1 := Syscall9(procAcceptEx.Addr(), 8, uintptr(ls), uintptr(as), uintptr(unsafe.Pointer(buf)), uintptr(rxdatalen), uintptr(laddrlen), uintptr(raddrlen), uintptr(unsafe.Pointer(recvd)), uintptr(unsafe.Pointer(overlapped)), 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func GetAcceptExSockaddrs(buf *byte, rxdatalen uint32, laddrlen uint32, raddrlen uint32, lrsa **RawSockaddrAny, lrsalen *int32, rrsa **RawSockaddrAny, rrsalen *int32) {
-	Syscall9(procGetAcceptExSockaddrs.Addr(), 8, uintptr(unsafe.Pointer(buf)), uintptr(rxdatalen), uintptr(laddrlen), uintptr(raddrlen), uintptr(unsafe.Pointer(lrsa)), uintptr(unsafe.Pointer(lrsalen)), uintptr(unsafe.Pointer(rrsa)), uintptr(unsafe.Pointer(rrsalen)), 0)
-	return
-}
-
-func WSARecv(s Handle, bufs *WSABuf, bufcnt uint32, recvd *uint32, flags *uint32, overlapped *Overlapped, croutine *byte) (err error) {
-	r1, _, e1 := Syscall9(procWSARecv.Addr(), 7, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(recvd)), uintptr(unsafe.Pointer(flags)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)), 0, 0)
-	if r1 == socket_error {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func WSASend(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, overlapped *Overlapped, croutine *byte) (err error) {
-	r1, _, e1 := Syscall9(procWSASend.Addr(), 7, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(sent)), uintptr(flags), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)), 0, 0)
-	if r1 == socket_error {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func WSARecvFrom(s Handle, bufs *WSABuf, bufcnt uint32, recvd *uint32, flags *uint32, from *RawSockaddrAny, fromlen *int32, overlapped *Overlapped, croutine *byte) (err error) {
-	r1, _, e1 := Syscall9(procWSARecvFrom.Addr(), 9, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(recvd)), uintptr(unsafe.Pointer(flags)), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)))
-	if r1 == socket_error {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func WSASendTo(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, to *RawSockaddrAny, tolen int32, overlapped *Overlapped, croutine *byte) (err error) {
-	r1, _, e1 := Syscall9(procWSASendTo.Addr(), 9, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(sent)), uintptr(flags), uintptr(unsafe.Pointer(to)), uintptr(tolen), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)))
-	if r1 == socket_error {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func GetHostByName(name string) (h *Hostent, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(name)
-	if err != nil {
-		return
-	}
-	r0, _, e1 := Syscall(procgethostbyname.Addr(), 1, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	h = (*Hostent)(unsafe.Pointer(r0))
-	if h == nil {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func GetServByName(name string, proto string) (s *Servent, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(name)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(proto)
-	if err != nil {
-		return
-	}
-	r0, _, e1 := Syscall(procgetservbyname.Addr(), 2, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
-	s = (*Servent)(unsafe.Pointer(r0))
-	if s == nil {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func Ntohs(netshort uint16) (u uint16) {
-	r0, _, _ := Syscall(procntohs.Addr(), 1, uintptr(netshort), 0, 0)
-	u = uint16(r0)
-	return
-}
-
-func GetProtoByName(name string) (p *Protoent, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(name)
-	if err != nil {
-		return
-	}
-	r0, _, e1 := Syscall(procgetprotobyname.Addr(), 1, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	p = (*Protoent)(unsafe.Pointer(r0))
-	if p == nil {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func DnsQuery(name string, qtype uint16, options uint32, extra *byte, qrs **DNSRecord, pr *byte) (status error) {
-	var _p0 *uint16
-	_p0, status = UTF16PtrFromString(name)
-	if status != nil {
-		return
-	}
-	r0, _, _ := Syscall6(procDnsQuery_W.Addr(), 6, uintptr(unsafe.Pointer(_p0)), uintptr(qtype), uintptr(options), uintptr(unsafe.Pointer(extra)), uintptr(unsafe.Pointer(qrs)), uintptr(unsafe.Pointer(pr)))
-	if r0 != 0 {
-		status = Errno(r0)
-	}
-	return
-}
-
-func DnsRecordListFree(rl *DNSRecord, freetype uint32) {
-	Syscall(procDnsRecordListFree.Addr(), 2, uintptr(unsafe.Pointer(rl)), uintptr(freetype), 0)
-	return
-}
-
-func GetAddrInfoW(nodename *uint16, servicename *uint16, hints *AddrinfoW, result **AddrinfoW) (sockerr error) {
-	r0, _, _ := Syscall6(procGetAddrInfoW.Addr(), 4, uintptr(unsafe.Pointer(nodename)), uintptr(unsafe.Pointer(servicename)), uintptr(unsafe.Pointer(hints)), uintptr(unsafe.Pointer(result)), 0, 0)
-	if r0 != 0 {
-		sockerr = Errno(r0)
-	}
-	return
-}
-
-func FreeAddrInfoW(addrinfo *AddrinfoW) {
-	Syscall(procFreeAddrInfoW.Addr(), 1, uintptr(unsafe.Pointer(addrinfo)), 0, 0)
-	return
-}
-
-func GetIfEntry(pIfRow *MibIfRow) (errcode error) {
-	r0, _, _ := Syscall(procGetIfEntry.Addr(), 1, uintptr(unsafe.Pointer(pIfRow)), 0, 0)
-	if r0 != 0 {
-		errcode = Errno(r0)
-	}
-	return
-}
-
-func GetAdaptersInfo(ai *IpAdapterInfo, ol *uint32) (errcode error) {
-	r0, _, _ := Syscall(procGetAdaptersInfo.Addr(), 2, uintptr(unsafe.Pointer(ai)), uintptr(unsafe.Pointer(ol)), 0)
-	if r0 != 0 {
-		errcode = Errno(r0)
-	}
-	return
-}
-
-func SetFileCompletionNotificationModes(handle Handle, flags uint8) (err error) {
-	r1, _, e1 := Syscall(procSetFileCompletionNotificationModes.Addr(), 2, uintptr(handle), uintptr(flags), 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func WSAEnumProtocols(protocols *int32, protocolBuffer *WSAProtocolInfo, bufferLength *uint32) (n int32, err error) {
-	r0, _, e1 := Syscall(procWSAEnumProtocolsW.Addr(), 3, uintptr(unsafe.Pointer(protocols)), uintptr(unsafe.Pointer(protocolBuffer)), uintptr(unsafe.Pointer(bufferLength)))
-	n = int32(r0)
-	if n == -1 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func TranslateName(accName *uint16, accNameFormat uint32, desiredNameFormat uint32, translatedName *uint16, nSize *uint32) (err error) {
-	r1, _, e1 := Syscall6(procTranslateNameW.Addr(), 5, uintptr(unsafe.Pointer(accName)), uintptr(accNameFormat), uintptr(desiredNameFormat), uintptr(unsafe.Pointer(translatedName)), uintptr(unsafe.Pointer(nSize)), 0)
-	if r1&0xff == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func GetUserNameEx(nameFormat uint32, nameBuffre *uint16, nSize *uint32) (err error) {
-	r1, _, e1 := Syscall(procGetUserNameExW.Addr(), 3, uintptr(nameFormat), uintptr(unsafe.Pointer(nameBuffre)), uintptr(unsafe.Pointer(nSize)))
-	if r1&0xff == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func NetUserGetInfo(serverName *uint16, userName *uint16, level uint32, buf **byte) (neterr error) {
-	r0, _, _ := Syscall6(procNetUserGetInfo.Addr(), 4, uintptr(unsafe.Pointer(serverName)), uintptr(unsafe.Pointer(userName)), uintptr(level), uintptr(unsafe.Pointer(buf)), 0, 0)
-	if r0 != 0 {
-		neterr = Errno(r0)
-	}
-	return
-}
-
-func NetGetJoinInformation(server *uint16, name **uint16, bufType *uint32) (neterr error) {
-	r0, _, _ := Syscall(procNetGetJoinInformation.Addr(), 3, uintptr(unsafe.Pointer(server)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(bufType)))
-	if r0 != 0 {
-		neterr = Errno(r0)
-	}
-	return
-}
-
-func NetApiBufferFree(buf *byte) (neterr error) {
-	r0, _, _ := Syscall(procNetApiBufferFree.Addr(), 1, uintptr(unsafe.Pointer(buf)), 0, 0)
-	if r0 != 0 {
-		neterr = Errno(r0)
-	}
-	return
-}
-
-func LookupAccountSid(systemName *uint16, sid *SID, name *uint16, nameLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) {
-	r1, _, e1 := Syscall9(procLookupAccountSidW.Addr(), 7, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(nameLen)), uintptr(unsafe.Pointer(refdDomainName)), uintptr(unsafe.Pointer(refdDomainNameLen)), uintptr(unsafe.Pointer(use)), 0, 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func LookupAccountName(systemName *uint16, accountName *uint16, sid *SID, sidLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) {
-	r1, _, e1 := Syscall9(procLookupAccountNameW.Addr(), 7, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(accountName)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(sidLen)), uintptr(unsafe.Pointer(refdDomainName)), uintptr(unsafe.Pointer(refdDomainNameLen)), uintptr(unsafe.Pointer(use)), 0, 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func ConvertSidToStringSid(sid *SID, stringSid **uint16) (err error) {
-	r1, _, e1 := Syscall(procConvertSidToStringSidW.Addr(), 2, uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(stringSid)), 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func ConvertStringSidToSid(stringSid *uint16, sid **SID) (err error) {
-	r1, _, e1 := Syscall(procConvertStringSidToSidW.Addr(), 2, uintptr(unsafe.Pointer(stringSid)), uintptr(unsafe.Pointer(sid)), 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func GetLengthSid(sid *SID) (len uint32) {
-	r0, _, _ := Syscall(procGetLengthSid.Addr(), 1, uintptr(unsafe.Pointer(sid)), 0, 0)
-	len = uint32(r0)
-	return
-}
-
-func CopySid(destSidLen uint32, destSid *SID, srcSid *SID) (err error) {
-	r1, _, e1 := Syscall(procCopySid.Addr(), 3, uintptr(destSidLen), uintptr(unsafe.Pointer(destSid)), uintptr(unsafe.Pointer(srcSid)))
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func OpenProcessToken(h Handle, access uint32, token *Token) (err error) {
-	r1, _, e1 := Syscall(procOpenProcessToken.Addr(), 3, uintptr(h), uintptr(access), uintptr(unsafe.Pointer(token)))
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func GetTokenInformation(t Token, infoClass uint32, info *byte, infoLen uint32, returnedLen *uint32) (err error) {
-	r1, _, e1 := Syscall6(procGetTokenInformation.Addr(), 5, uintptr(t), uintptr(infoClass), uintptr(unsafe.Pointer(info)), uintptr(infoLen), uintptr(unsafe.Pointer(returnedLen)), 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func GetUserProfileDirectory(t Token, dir *uint16, dirLen *uint32) (err error) {
-	r1, _, e1 := Syscall(procGetUserProfileDirectoryW.Addr(), 3, uintptr(t), uintptr(unsafe.Pointer(dir)), uintptr(unsafe.Pointer(dirLen)))
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
diff --git a/src/pkg/syscall/zsyscall_windows_amd64.go b/src/pkg/syscall/zsyscall_windows_amd64.go
deleted file mode 100644
index 353a6fd..0000000
--- a/src/pkg/syscall/zsyscall_windows_amd64.go
+++ /dev/null
@@ -1,1760 +0,0 @@
-// go build mksyscall_windows.go && ./mksyscall_windows syscall_windows.go security_windows.go syscall_windows_amd64.go
-// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
-
-package syscall
-
-import "unsafe"
-
-var (
-	modkernel32 = NewLazyDLL("kernel32.dll")
-	modadvapi32 = NewLazyDLL("advapi32.dll")
-	modshell32  = NewLazyDLL("shell32.dll")
-	modmswsock  = NewLazyDLL("mswsock.dll")
-	modcrypt32  = NewLazyDLL("crypt32.dll")
-	modws2_32   = NewLazyDLL("ws2_32.dll")
-	moddnsapi   = NewLazyDLL("dnsapi.dll")
-	modiphlpapi = NewLazyDLL("iphlpapi.dll")
-	modsecur32  = NewLazyDLL("secur32.dll")
-	modnetapi32 = NewLazyDLL("netapi32.dll")
-	moduserenv  = NewLazyDLL("userenv.dll")
-
-	procGetLastError                       = modkernel32.NewProc("GetLastError")
-	procLoadLibraryW                       = modkernel32.NewProc("LoadLibraryW")
-	procFreeLibrary                        = modkernel32.NewProc("FreeLibrary")
-	procGetProcAddress                     = modkernel32.NewProc("GetProcAddress")
-	procGetVersion                         = modkernel32.NewProc("GetVersion")
-	procFormatMessageW                     = modkernel32.NewProc("FormatMessageW")
-	procExitProcess                        = modkernel32.NewProc("ExitProcess")
-	procCreateFileW                        = modkernel32.NewProc("CreateFileW")
-	procReadFile                           = modkernel32.NewProc("ReadFile")
-	procWriteFile                          = modkernel32.NewProc("WriteFile")
-	procSetFilePointer                     = modkernel32.NewProc("SetFilePointer")
-	procCloseHandle                        = modkernel32.NewProc("CloseHandle")
-	procGetStdHandle                       = modkernel32.NewProc("GetStdHandle")
-	procFindFirstFileW                     = modkernel32.NewProc("FindFirstFileW")
-	procFindNextFileW                      = modkernel32.NewProc("FindNextFileW")
-	procFindClose                          = modkernel32.NewProc("FindClose")
-	procGetFileInformationByHandle         = modkernel32.NewProc("GetFileInformationByHandle")
-	procGetCurrentDirectoryW               = modkernel32.NewProc("GetCurrentDirectoryW")
-	procSetCurrentDirectoryW               = modkernel32.NewProc("SetCurrentDirectoryW")
-	procCreateDirectoryW                   = modkernel32.NewProc("CreateDirectoryW")
-	procRemoveDirectoryW                   = modkernel32.NewProc("RemoveDirectoryW")
-	procDeleteFileW                        = modkernel32.NewProc("DeleteFileW")
-	procMoveFileW                          = modkernel32.NewProc("MoveFileW")
-	procGetComputerNameW                   = modkernel32.NewProc("GetComputerNameW")
-	procSetEndOfFile                       = modkernel32.NewProc("SetEndOfFile")
-	procGetSystemTimeAsFileTime            = modkernel32.NewProc("GetSystemTimeAsFileTime")
-	procGetTimeZoneInformation             = modkernel32.NewProc("GetTimeZoneInformation")
-	procCreateIoCompletionPort             = modkernel32.NewProc("CreateIoCompletionPort")
-	procGetQueuedCompletionStatus          = modkernel32.NewProc("GetQueuedCompletionStatus")
-	procPostQueuedCompletionStatus         = modkernel32.NewProc("PostQueuedCompletionStatus")
-	procCancelIo                           = modkernel32.NewProc("CancelIo")
-	procCancelIoEx                         = modkernel32.NewProc("CancelIoEx")
-	procCreateProcessW                     = modkernel32.NewProc("CreateProcessW")
-	procOpenProcess                        = modkernel32.NewProc("OpenProcess")
-	procTerminateProcess                   = modkernel32.NewProc("TerminateProcess")
-	procGetExitCodeProcess                 = modkernel32.NewProc("GetExitCodeProcess")
-	procGetStartupInfoW                    = modkernel32.NewProc("GetStartupInfoW")
-	procGetCurrentProcess                  = modkernel32.NewProc("GetCurrentProcess")
-	procGetProcessTimes                    = modkernel32.NewProc("GetProcessTimes")
-	procDuplicateHandle                    = modkernel32.NewProc("DuplicateHandle")
-	procWaitForSingleObject                = modkernel32.NewProc("WaitForSingleObject")
-	procGetTempPathW                       = modkernel32.NewProc("GetTempPathW")
-	procCreatePipe                         = modkernel32.NewProc("CreatePipe")
-	procGetFileType                        = modkernel32.NewProc("GetFileType")
-	procCryptAcquireContextW               = modadvapi32.NewProc("CryptAcquireContextW")
-	procCryptReleaseContext                = modadvapi32.NewProc("CryptReleaseContext")
-	procCryptGenRandom                     = modadvapi32.NewProc("CryptGenRandom")
-	procGetEnvironmentStringsW             = modkernel32.NewProc("GetEnvironmentStringsW")
-	procFreeEnvironmentStringsW            = modkernel32.NewProc("FreeEnvironmentStringsW")
-	procGetEnvironmentVariableW            = modkernel32.NewProc("GetEnvironmentVariableW")
-	procSetEnvironmentVariableW            = modkernel32.NewProc("SetEnvironmentVariableW")
-	procSetFileTime                        = modkernel32.NewProc("SetFileTime")
-	procGetFileAttributesW                 = modkernel32.NewProc("GetFileAttributesW")
-	procSetFileAttributesW                 = modkernel32.NewProc("SetFileAttributesW")
-	procGetFileAttributesExW               = modkernel32.NewProc("GetFileAttributesExW")
-	procGetCommandLineW                    = modkernel32.NewProc("GetCommandLineW")
-	procCommandLineToArgvW                 = modshell32.NewProc("CommandLineToArgvW")
-	procLocalFree                          = modkernel32.NewProc("LocalFree")
-	procSetHandleInformation               = modkernel32.NewProc("SetHandleInformation")
-	procFlushFileBuffers                   = modkernel32.NewProc("FlushFileBuffers")
-	procGetFullPathNameW                   = modkernel32.NewProc("GetFullPathNameW")
-	procGetLongPathNameW                   = modkernel32.NewProc("GetLongPathNameW")
-	procGetShortPathNameW                  = modkernel32.NewProc("GetShortPathNameW")
-	procCreateFileMappingW                 = modkernel32.NewProc("CreateFileMappingW")
-	procMapViewOfFile                      = modkernel32.NewProc("MapViewOfFile")
-	procUnmapViewOfFile                    = modkernel32.NewProc("UnmapViewOfFile")
-	procFlushViewOfFile                    = modkernel32.NewProc("FlushViewOfFile")
-	procVirtualLock                        = modkernel32.NewProc("VirtualLock")
-	procVirtualUnlock                      = modkernel32.NewProc("VirtualUnlock")
-	procTransmitFile                       = modmswsock.NewProc("TransmitFile")
-	procReadDirectoryChangesW              = modkernel32.NewProc("ReadDirectoryChangesW")
-	procCertOpenSystemStoreW               = modcrypt32.NewProc("CertOpenSystemStoreW")
-	procCertOpenStore                      = modcrypt32.NewProc("CertOpenStore")
-	procCertEnumCertificatesInStore        = modcrypt32.NewProc("CertEnumCertificatesInStore")
-	procCertAddCertificateContextToStore   = modcrypt32.NewProc("CertAddCertificateContextToStore")
-	procCertCloseStore                     = modcrypt32.NewProc("CertCloseStore")
-	procCertGetCertificateChain            = modcrypt32.NewProc("CertGetCertificateChain")
-	procCertFreeCertificateChain           = modcrypt32.NewProc("CertFreeCertificateChain")
-	procCertCreateCertificateContext       = modcrypt32.NewProc("CertCreateCertificateContext")
-	procCertFreeCertificateContext         = modcrypt32.NewProc("CertFreeCertificateContext")
-	procCertVerifyCertificateChainPolicy   = modcrypt32.NewProc("CertVerifyCertificateChainPolicy")
-	procRegOpenKeyExW                      = modadvapi32.NewProc("RegOpenKeyExW")
-	procRegCloseKey                        = modadvapi32.NewProc("RegCloseKey")
-	procRegQueryInfoKeyW                   = modadvapi32.NewProc("RegQueryInfoKeyW")
-	procRegEnumKeyExW                      = modadvapi32.NewProc("RegEnumKeyExW")
-	procRegQueryValueExW                   = modadvapi32.NewProc("RegQueryValueExW")
-	procGetCurrentProcessId                = modkernel32.NewProc("GetCurrentProcessId")
-	procGetConsoleMode                     = modkernel32.NewProc("GetConsoleMode")
-	procWriteConsoleW                      = modkernel32.NewProc("WriteConsoleW")
-	procReadConsoleW                       = modkernel32.NewProc("ReadConsoleW")
-	procWSAStartup                         = modws2_32.NewProc("WSAStartup")
-	procWSACleanup                         = modws2_32.NewProc("WSACleanup")
-	procWSAIoctl                           = modws2_32.NewProc("WSAIoctl")
-	procsocket                             = modws2_32.NewProc("socket")
-	procsetsockopt                         = modws2_32.NewProc("setsockopt")
-	procgetsockopt                         = modws2_32.NewProc("getsockopt")
-	procbind                               = modws2_32.NewProc("bind")
-	procconnect                            = modws2_32.NewProc("connect")
-	procgetsockname                        = modws2_32.NewProc("getsockname")
-	procgetpeername                        = modws2_32.NewProc("getpeername")
-	proclisten                             = modws2_32.NewProc("listen")
-	procshutdown                           = modws2_32.NewProc("shutdown")
-	procclosesocket                        = modws2_32.NewProc("closesocket")
-	procAcceptEx                           = modmswsock.NewProc("AcceptEx")
-	procGetAcceptExSockaddrs               = modmswsock.NewProc("GetAcceptExSockaddrs")
-	procWSARecv                            = modws2_32.NewProc("WSARecv")
-	procWSASend                            = modws2_32.NewProc("WSASend")
-	procWSARecvFrom                        = modws2_32.NewProc("WSARecvFrom")
-	procWSASendTo                          = modws2_32.NewProc("WSASendTo")
-	procgethostbyname                      = modws2_32.NewProc("gethostbyname")
-	procgetservbyname                      = modws2_32.NewProc("getservbyname")
-	procntohs                              = modws2_32.NewProc("ntohs")
-	procgetprotobyname                     = modws2_32.NewProc("getprotobyname")
-	procDnsQuery_W                         = moddnsapi.NewProc("DnsQuery_W")
-	procDnsRecordListFree                  = moddnsapi.NewProc("DnsRecordListFree")
-	procGetAddrInfoW                       = modws2_32.NewProc("GetAddrInfoW")
-	procFreeAddrInfoW                      = modws2_32.NewProc("FreeAddrInfoW")
-	procGetIfEntry                         = modiphlpapi.NewProc("GetIfEntry")
-	procGetAdaptersInfo                    = modiphlpapi.NewProc("GetAdaptersInfo")
-	procSetFileCompletionNotificationModes = modkernel32.NewProc("SetFileCompletionNotificationModes")
-	procWSAEnumProtocolsW                  = modws2_32.NewProc("WSAEnumProtocolsW")
-	procTranslateNameW                     = modsecur32.NewProc("TranslateNameW")
-	procGetUserNameExW                     = modsecur32.NewProc("GetUserNameExW")
-	procNetUserGetInfo                     = modnetapi32.NewProc("NetUserGetInfo")
-	procNetGetJoinInformation              = modnetapi32.NewProc("NetGetJoinInformation")
-	procNetApiBufferFree                   = modnetapi32.NewProc("NetApiBufferFree")
-	procLookupAccountSidW                  = modadvapi32.NewProc("LookupAccountSidW")
-	procLookupAccountNameW                 = modadvapi32.NewProc("LookupAccountNameW")
-	procConvertSidToStringSidW             = modadvapi32.NewProc("ConvertSidToStringSidW")
-	procConvertStringSidToSidW             = modadvapi32.NewProc("ConvertStringSidToSidW")
-	procGetLengthSid                       = modadvapi32.NewProc("GetLengthSid")
-	procCopySid                            = modadvapi32.NewProc("CopySid")
-	procOpenProcessToken                   = modadvapi32.NewProc("OpenProcessToken")
-	procGetTokenInformation                = modadvapi32.NewProc("GetTokenInformation")
-	procGetUserProfileDirectoryW           = moduserenv.NewProc("GetUserProfileDirectoryW")
-)
-
-func GetLastError() (lasterr error) {
-	r0, _, _ := Syscall(procGetLastError.Addr(), 0, 0, 0, 0)
-	if r0 != 0 {
-		lasterr = Errno(r0)
-	}
-	return
-}
-
-func LoadLibrary(libname string) (handle Handle, err error) {
-	var _p0 *uint16
-	_p0, err = UTF16PtrFromString(libname)
-	if err != nil {
-		return
-	}
-	r0, _, e1 := Syscall(procLoadLibraryW.Addr(), 1, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	handle = Handle(r0)
-	if handle == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func FreeLibrary(handle Handle) (err error) {
-	r1, _, e1 := Syscall(procFreeLibrary.Addr(), 1, uintptr(handle), 0, 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func GetProcAddress(module Handle, procname string) (proc uintptr, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(procname)
-	if err != nil {
-		return
-	}
-	r0, _, e1 := Syscall(procGetProcAddress.Addr(), 2, uintptr(module), uintptr(unsafe.Pointer(_p0)), 0)
-	proc = uintptr(r0)
-	if proc == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func GetVersion() (ver uint32, err error) {
-	r0, _, e1 := Syscall(procGetVersion.Addr(), 0, 0, 0, 0)
-	ver = uint32(r0)
-	if ver == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func FormatMessage(flags uint32, msgsrc uint32, msgid uint32, langid uint32, buf []uint16, args *byte) (n uint32, err error) {
-	var _p0 *uint16
-	if len(buf) > 0 {
-		_p0 = &buf[0]
-	}
-	r0, _, e1 := Syscall9(procFormatMessageW.Addr(), 7, uintptr(flags), uintptr(msgsrc), uintptr(msgid), uintptr(langid), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(unsafe.Pointer(args)), 0, 0)
-	n = uint32(r0)
-	if n == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func ExitProcess(exitcode uint32) {
-	Syscall(procExitProcess.Addr(), 1, uintptr(exitcode), 0, 0)
-	return
-}
-
-func CreateFile(name *uint16, access uint32, mode uint32, sa *SecurityAttributes, createmode uint32, attrs uint32, templatefile int32) (handle Handle, err error) {
-	r0, _, e1 := Syscall9(procCreateFileW.Addr(), 7, uintptr(unsafe.Pointer(name)), uintptr(access), uintptr(mode), uintptr(unsafe.Pointer(sa)), uintptr(createmode), uintptr(attrs), uintptr(templatefile), 0, 0)
-	handle = Handle(r0)
-	if handle == InvalidHandle {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func ReadFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) (err error) {
-	var _p0 *byte
-	if len(buf) > 0 {
-		_p0 = &buf[0]
-	}
-	r1, _, e1 := Syscall6(procReadFile.Addr(), 5, uintptr(handle), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(unsafe.Pointer(done)), uintptr(unsafe.Pointer(overlapped)), 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func WriteFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) (err error) {
-	var _p0 *byte
-	if len(buf) > 0 {
-		_p0 = &buf[0]
-	}
-	r1, _, e1 := Syscall6(procWriteFile.Addr(), 5, uintptr(handle), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(unsafe.Pointer(done)), uintptr(unsafe.Pointer(overlapped)), 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func SetFilePointer(handle Handle, lowoffset int32, highoffsetptr *int32, whence uint32) (newlowoffset uint32, err error) {
-	r0, _, e1 := Syscall6(procSetFilePointer.Addr(), 4, uintptr(handle), uintptr(lowoffset), uintptr(unsafe.Pointer(highoffsetptr)), uintptr(whence), 0, 0)
-	newlowoffset = uint32(r0)
-	if newlowoffset == 0xffffffff {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func CloseHandle(handle Handle) (err error) {
-	r1, _, e1 := Syscall(procCloseHandle.Addr(), 1, uintptr(handle), 0, 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func GetStdHandle(stdhandle int) (handle Handle, err error) {
-	r0, _, e1 := Syscall(procGetStdHandle.Addr(), 1, uintptr(stdhandle), 0, 0)
-	handle = Handle(r0)
-	if handle == InvalidHandle {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func findFirstFile1(name *uint16, data *win32finddata1) (handle Handle, err error) {
-	r0, _, e1 := Syscall(procFindFirstFileW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(data)), 0)
-	handle = Handle(r0)
-	if handle == InvalidHandle {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func findNextFile1(handle Handle, data *win32finddata1) (err error) {
-	r1, _, e1 := Syscall(procFindNextFileW.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(data)), 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func FindClose(handle Handle) (err error) {
-	r1, _, e1 := Syscall(procFindClose.Addr(), 1, uintptr(handle), 0, 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func GetFileInformationByHandle(handle Handle, data *ByHandleFileInformation) (err error) {
-	r1, _, e1 := Syscall(procGetFileInformationByHandle.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(data)), 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func GetCurrentDirectory(buflen uint32, buf *uint16) (n uint32, err error) {
-	r0, _, e1 := Syscall(procGetCurrentDirectoryW.Addr(), 2, uintptr(buflen), uintptr(unsafe.Pointer(buf)), 0)
-	n = uint32(r0)
-	if n == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func SetCurrentDirectory(path *uint16) (err error) {
-	r1, _, e1 := Syscall(procSetCurrentDirectoryW.Addr(), 1, uintptr(unsafe.Pointer(path)), 0, 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func CreateDirectory(path *uint16, sa *SecurityAttributes) (err error) {
-	r1, _, e1 := Syscall(procCreateDirectoryW.Addr(), 2, uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(sa)), 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func RemoveDirectory(path *uint16) (err error) {
-	r1, _, e1 := Syscall(procRemoveDirectoryW.Addr(), 1, uintptr(unsafe.Pointer(path)), 0, 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func DeleteFile(path *uint16) (err error) {
-	r1, _, e1 := Syscall(procDeleteFileW.Addr(), 1, uintptr(unsafe.Pointer(path)), 0, 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func MoveFile(from *uint16, to *uint16) (err error) {
-	r1, _, e1 := Syscall(procMoveFileW.Addr(), 2, uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(to)), 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func GetComputerName(buf *uint16, n *uint32) (err error) {
-	r1, _, e1 := Syscall(procGetComputerNameW.Addr(), 2, uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(n)), 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func SetEndOfFile(handle Handle) (err error) {
-	r1, _, e1 := Syscall(procSetEndOfFile.Addr(), 1, uintptr(handle), 0, 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func GetSystemTimeAsFileTime(time *Filetime) {
-	Syscall(procGetSystemTimeAsFileTime.Addr(), 1, uintptr(unsafe.Pointer(time)), 0, 0)
-	return
-}
-
-func GetTimeZoneInformation(tzi *Timezoneinformation) (rc uint32, err error) {
-	r0, _, e1 := Syscall(procGetTimeZoneInformation.Addr(), 1, uintptr(unsafe.Pointer(tzi)), 0, 0)
-	rc = uint32(r0)
-	if rc == 0xffffffff {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func CreateIoCompletionPort(filehandle Handle, cphandle Handle, key uint32, threadcnt uint32) (handle Handle, err error) {
-	r0, _, e1 := Syscall6(procCreateIoCompletionPort.Addr(), 4, uintptr(filehandle), uintptr(cphandle), uintptr(key), uintptr(threadcnt), 0, 0)
-	handle = Handle(r0)
-	if handle == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func GetQueuedCompletionStatus(cphandle Handle, qty *uint32, key *uint32, overlapped **Overlapped, timeout uint32) (err error) {
-	r1, _, e1 := Syscall6(procGetQueuedCompletionStatus.Addr(), 5, uintptr(cphandle), uintptr(unsafe.Pointer(qty)), uintptr(unsafe.Pointer(key)), uintptr(unsafe.Pointer(overlapped)), uintptr(timeout), 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func PostQueuedCompletionStatus(cphandle Handle, qty uint32, key uint32, overlapped *Overlapped) (err error) {
-	r1, _, e1 := Syscall6(procPostQueuedCompletionStatus.Addr(), 4, uintptr(cphandle), uintptr(qty), uintptr(key), uintptr(unsafe.Pointer(overlapped)), 0, 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func CancelIo(s Handle) (err error) {
-	r1, _, e1 := Syscall(procCancelIo.Addr(), 1, uintptr(s), 0, 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func CancelIoEx(s Handle, o *Overlapped) (err error) {
-	r1, _, e1 := Syscall(procCancelIoEx.Addr(), 2, uintptr(s), uintptr(unsafe.Pointer(o)), 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func CreateProcess(appName *uint16, commandLine *uint16, procSecurity *SecurityAttributes, threadSecurity *SecurityAttributes, inheritHandles bool, creationFlags uint32, env *uint16, currentDir *uint16, startupInfo *StartupInfo, outProcInfo *ProcessInformation) (err error) {
-	var _p0 uint32
-	if inheritHandles {
-		_p0 = 1
-	} else {
-		_p0 = 0
-	}
-	r1, _, e1 := Syscall12(procCreateProcessW.Addr(), 10, uintptr(unsafe.Pointer(appName)), uintptr(unsafe.Pointer(commandLine)), uintptr(unsafe.Pointer(procSecurity)), uintptr(unsafe.Pointer(threadSecurity)), uintptr(_p0), uintptr(creationFlags), uintptr(unsafe.Pointer(env)), uintptr(unsafe.Pointer(currentDir)), uintptr(unsafe.Pointer(startupInfo)), uintptr(unsafe.Pointer(outProcInfo)), 0, 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func OpenProcess(da uint32, inheritHandle bool, pid uint32) (handle Handle, err error) {
-	var _p0 uint32
-	if inheritHandle {
-		_p0 = 1
-	} else {
-		_p0 = 0
-	}
-	r0, _, e1 := Syscall(procOpenProcess.Addr(), 3, uintptr(da), uintptr(_p0), uintptr(pid))
-	handle = Handle(r0)
-	if handle == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func TerminateProcess(handle Handle, exitcode uint32) (err error) {
-	r1, _, e1 := Syscall(procTerminateProcess.Addr(), 2, uintptr(handle), uintptr(exitcode), 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func GetExitCodeProcess(handle Handle, exitcode *uint32) (err error) {
-	r1, _, e1 := Syscall(procGetExitCodeProcess.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(exitcode)), 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func GetStartupInfo(startupInfo *StartupInfo) (err error) {
-	r1, _, e1 := Syscall(procGetStartupInfoW.Addr(), 1, uintptr(unsafe.Pointer(startupInfo)), 0, 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func GetCurrentProcess() (pseudoHandle Handle, err error) {
-	r0, _, e1 := Syscall(procGetCurrentProcess.Addr(), 0, 0, 0, 0)
-	pseudoHandle = Handle(r0)
-	if pseudoHandle == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func GetProcessTimes(handle Handle, creationTime *Filetime, exitTime *Filetime, kernelTime *Filetime, userTime *Filetime) (err error) {
-	r1, _, e1 := Syscall6(procGetProcessTimes.Addr(), 5, uintptr(handle), uintptr(unsafe.Pointer(creationTime)), uintptr(unsafe.Pointer(exitTime)), uintptr(unsafe.Pointer(kernelTime)), uintptr(unsafe.Pointer(userTime)), 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func DuplicateHandle(hSourceProcessHandle Handle, hSourceHandle Handle, hTargetProcessHandle Handle, lpTargetHandle *Handle, dwDesiredAccess uint32, bInheritHandle bool, dwOptions uint32) (err error) {
-	var _p0 uint32
-	if bInheritHandle {
-		_p0 = 1
-	} else {
-		_p0 = 0
-	}
-	r1, _, e1 := Syscall9(procDuplicateHandle.Addr(), 7, uintptr(hSourceProcessHandle), uintptr(hSourceHandle), uintptr(hTargetProcessHandle), uintptr(unsafe.Pointer(lpTargetHandle)), uintptr(dwDesiredAccess), uintptr(_p0), uintptr(dwOptions), 0, 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func WaitForSingleObject(handle Handle, waitMilliseconds uint32) (event uint32, err error) {
-	r0, _, e1 := Syscall(procWaitForSingleObject.Addr(), 2, uintptr(handle), uintptr(waitMilliseconds), 0)
-	event = uint32(r0)
-	if event == 0xffffffff {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func GetTempPath(buflen uint32, buf *uint16) (n uint32, err error) {
-	r0, _, e1 := Syscall(procGetTempPathW.Addr(), 2, uintptr(buflen), uintptr(unsafe.Pointer(buf)), 0)
-	n = uint32(r0)
-	if n == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func CreatePipe(readhandle *Handle, writehandle *Handle, sa *SecurityAttributes, size uint32) (err error) {
-	r1, _, e1 := Syscall6(procCreatePipe.Addr(), 4, uintptr(unsafe.Pointer(readhandle)), uintptr(unsafe.Pointer(writehandle)), uintptr(unsafe.Pointer(sa)), uintptr(size), 0, 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func GetFileType(filehandle Handle) (n uint32, err error) {
-	r0, _, e1 := Syscall(procGetFileType.Addr(), 1, uintptr(filehandle), 0, 0)
-	n = uint32(r0)
-	if n == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func CryptAcquireContext(provhandle *Handle, container *uint16, provider *uint16, provtype uint32, flags uint32) (err error) {
-	r1, _, e1 := Syscall6(procCryptAcquireContextW.Addr(), 5, uintptr(unsafe.Pointer(provhandle)), uintptr(unsafe.Pointer(container)), uintptr(unsafe.Pointer(provider)), uintptr(provtype), uintptr(flags), 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func CryptReleaseContext(provhandle Handle, flags uint32) (err error) {
-	r1, _, e1 := Syscall(procCryptReleaseContext.Addr(), 2, uintptr(provhandle), uintptr(flags), 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func CryptGenRandom(provhandle Handle, buflen uint32, buf *byte) (err error) {
-	r1, _, e1 := Syscall(procCryptGenRandom.Addr(), 3, uintptr(provhandle), uintptr(buflen), uintptr(unsafe.Pointer(buf)))
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func GetEnvironmentStrings() (envs *uint16, err error) {
-	r0, _, e1 := Syscall(procGetEnvironmentStringsW.Addr(), 0, 0, 0, 0)
-	envs = (*uint16)(unsafe.Pointer(r0))
-	if envs == nil {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func FreeEnvironmentStrings(envs *uint16) (err error) {
-	r1, _, e1 := Syscall(procFreeEnvironmentStringsW.Addr(), 1, uintptr(unsafe.Pointer(envs)), 0, 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func GetEnvironmentVariable(name *uint16, buffer *uint16, size uint32) (n uint32, err error) {
-	r0, _, e1 := Syscall(procGetEnvironmentVariableW.Addr(), 3, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(buffer)), uintptr(size))
-	n = uint32(r0)
-	if n == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func SetEnvironmentVariable(name *uint16, value *uint16) (err error) {
-	r1, _, e1 := Syscall(procSetEnvironmentVariableW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(value)), 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func SetFileTime(handle Handle, ctime *Filetime, atime *Filetime, wtime *Filetime) (err error) {
-	r1, _, e1 := Syscall6(procSetFileTime.Addr(), 4, uintptr(handle), uintptr(unsafe.Pointer(ctime)), uintptr(unsafe.Pointer(atime)), uintptr(unsafe.Pointer(wtime)), 0, 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func GetFileAttributes(name *uint16) (attrs uint32, err error) {
-	r0, _, e1 := Syscall(procGetFileAttributesW.Addr(), 1, uintptr(unsafe.Pointer(name)), 0, 0)
-	attrs = uint32(r0)
-	if attrs == INVALID_FILE_ATTRIBUTES {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func SetFileAttributes(name *uint16, attrs uint32) (err error) {
-	r1, _, e1 := Syscall(procSetFileAttributesW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(attrs), 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func GetFileAttributesEx(name *uint16, level uint32, info *byte) (err error) {
-	r1, _, e1 := Syscall(procGetFileAttributesExW.Addr(), 3, uintptr(unsafe.Pointer(name)), uintptr(level), uintptr(unsafe.Pointer(info)))
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func GetCommandLine() (cmd *uint16) {
-	r0, _, _ := Syscall(procGetCommandLineW.Addr(), 0, 0, 0, 0)
-	cmd = (*uint16)(unsafe.Pointer(r0))
-	return
-}
-
-func CommandLineToArgv(cmd *uint16, argc *int32) (argv *[8192]*[8192]uint16, err error) {
-	r0, _, e1 := Syscall(procCommandLineToArgvW.Addr(), 2, uintptr(unsafe.Pointer(cmd)), uintptr(unsafe.Pointer(argc)), 0)
-	argv = (*[8192]*[8192]uint16)(unsafe.Pointer(r0))
-	if argv == nil {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func LocalFree(hmem Handle) (handle Handle, err error) {
-	r0, _, e1 := Syscall(procLocalFree.Addr(), 1, uintptr(hmem), 0, 0)
-	handle = Handle(r0)
-	if handle != 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func SetHandleInformation(handle Handle, mask uint32, flags uint32) (err error) {
-	r1, _, e1 := Syscall(procSetHandleInformation.Addr(), 3, uintptr(handle), uintptr(mask), uintptr(flags))
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func FlushFileBuffers(handle Handle) (err error) {
-	r1, _, e1 := Syscall(procFlushFileBuffers.Addr(), 1, uintptr(handle), 0, 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func GetFullPathName(path *uint16, buflen uint32, buf *uint16, fname **uint16) (n uint32, err error) {
-	r0, _, e1 := Syscall6(procGetFullPathNameW.Addr(), 4, uintptr(unsafe.Pointer(path)), uintptr(buflen), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(fname)), 0, 0)
-	n = uint32(r0)
-	if n == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func GetLongPathName(path *uint16, buf *uint16, buflen uint32) (n uint32, err error) {
-	r0, _, e1 := Syscall(procGetLongPathNameW.Addr(), 3, uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(buf)), uintptr(buflen))
-	n = uint32(r0)
-	if n == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func GetShortPathName(longpath *uint16, shortpath *uint16, buflen uint32) (n uint32, err error) {
-	r0, _, e1 := Syscall(procGetShortPathNameW.Addr(), 3, uintptr(unsafe.Pointer(longpath)), uintptr(unsafe.Pointer(shortpath)), uintptr(buflen))
-	n = uint32(r0)
-	if n == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func CreateFileMapping(fhandle Handle, sa *SecurityAttributes, prot uint32, maxSizeHigh uint32, maxSizeLow uint32, name *uint16) (handle Handle, err error) {
-	r0, _, e1 := Syscall6(procCreateFileMappingW.Addr(), 6, uintptr(fhandle), uintptr(unsafe.Pointer(sa)), uintptr(prot), uintptr(maxSizeHigh), uintptr(maxSizeLow), uintptr(unsafe.Pointer(name)))
-	handle = Handle(r0)
-	if handle == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func MapViewOfFile(handle Handle, access uint32, offsetHigh uint32, offsetLow uint32, length uintptr) (addr uintptr, err error) {
-	r0, _, e1 := Syscall6(procMapViewOfFile.Addr(), 5, uintptr(handle), uintptr(access), uintptr(offsetHigh), uintptr(offsetLow), uintptr(length), 0)
-	addr = uintptr(r0)
-	if addr == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func UnmapViewOfFile(addr uintptr) (err error) {
-	r1, _, e1 := Syscall(procUnmapViewOfFile.Addr(), 1, uintptr(addr), 0, 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func FlushViewOfFile(addr uintptr, length uintptr) (err error) {
-	r1, _, e1 := Syscall(procFlushViewOfFile.Addr(), 2, uintptr(addr), uintptr(length), 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func VirtualLock(addr uintptr, length uintptr) (err error) {
-	r1, _, e1 := Syscall(procVirtualLock.Addr(), 2, uintptr(addr), uintptr(length), 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func VirtualUnlock(addr uintptr, length uintptr) (err error) {
-	r1, _, e1 := Syscall(procVirtualUnlock.Addr(), 2, uintptr(addr), uintptr(length), 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func TransmitFile(s Handle, handle Handle, bytesToWrite uint32, bytsPerSend uint32, overlapped *Overlapped, transmitFileBuf *TransmitFileBuffers, flags uint32) (err error) {
-	r1, _, e1 := Syscall9(procTransmitFile.Addr(), 7, uintptr(s), uintptr(handle), uintptr(bytesToWrite), uintptr(bytsPerSend), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(transmitFileBuf)), uintptr(flags), 0, 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func ReadDirectoryChanges(handle Handle, buf *byte, buflen uint32, watchSubTree bool, mask uint32, retlen *uint32, overlapped *Overlapped, completionRoutine uintptr) (err error) {
-	var _p0 uint32
-	if watchSubTree {
-		_p0 = 1
-	} else {
-		_p0 = 0
-	}
-	r1, _, e1 := Syscall9(procReadDirectoryChangesW.Addr(), 8, uintptr(handle), uintptr(unsafe.Pointer(buf)), uintptr(buflen), uintptr(_p0), uintptr(mask), uintptr(unsafe.Pointer(retlen)), uintptr(unsafe.Pointer(overlapped)), uintptr(completionRoutine), 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func CertOpenSystemStore(hprov Handle, name *uint16) (store Handle, err error) {
-	r0, _, e1 := Syscall(procCertOpenSystemStoreW.Addr(), 2, uintptr(hprov), uintptr(unsafe.Pointer(name)), 0)
-	store = Handle(r0)
-	if store == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func CertOpenStore(storeProvider uintptr, msgAndCertEncodingType uint32, cryptProv uintptr, flags uint32, para uintptr) (handle Handle, err error) {
-	r0, _, e1 := Syscall6(procCertOpenStore.Addr(), 5, uintptr(storeProvider), uintptr(msgAndCertEncodingType), uintptr(cryptProv), uintptr(flags), uintptr(para), 0)
-	handle = Handle(r0)
-	if handle == InvalidHandle {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func CertEnumCertificatesInStore(store Handle, prevContext *CertContext) (context *CertContext, err error) {
-	r0, _, e1 := Syscall(procCertEnumCertificatesInStore.Addr(), 2, uintptr(store), uintptr(unsafe.Pointer(prevContext)), 0)
-	context = (*CertContext)(unsafe.Pointer(r0))
-	if context == nil {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func CertAddCertificateContextToStore(store Handle, certContext *CertContext, addDisposition uint32, storeContext **CertContext) (err error) {
-	r1, _, e1 := Syscall6(procCertAddCertificateContextToStore.Addr(), 4, uintptr(store), uintptr(unsafe.Pointer(certContext)), uintptr(addDisposition), uintptr(unsafe.Pointer(storeContext)), 0, 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func CertCloseStore(store Handle, flags uint32) (err error) {
-	r1, _, e1 := Syscall(procCertCloseStore.Addr(), 2, uintptr(store), uintptr(flags), 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func CertGetCertificateChain(engine Handle, leaf *CertContext, time *Filetime, additionalStore Handle, para *CertChainPara, flags uint32, reserved uintptr, chainCtx **CertChainContext) (err error) {
-	r1, _, e1 := Syscall9(procCertGetCertificateChain.Addr(), 8, uintptr(engine), uintptr(unsafe.Pointer(leaf)), uintptr(unsafe.Pointer(time)), uintptr(additionalStore), uintptr(unsafe.Pointer(para)), uintptr(flags), uintptr(reserved), uintptr(unsafe.Pointer(chainCtx)), 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func CertFreeCertificateChain(ctx *CertChainContext) {
-	Syscall(procCertFreeCertificateChain.Addr(), 1, uintptr(unsafe.Pointer(ctx)), 0, 0)
-	return
-}
-
-func CertCreateCertificateContext(certEncodingType uint32, certEncoded *byte, encodedLen uint32) (context *CertContext, err error) {
-	r0, _, e1 := Syscall(procCertCreateCertificateContext.Addr(), 3, uintptr(certEncodingType), uintptr(unsafe.Pointer(certEncoded)), uintptr(encodedLen))
-	context = (*CertContext)(unsafe.Pointer(r0))
-	if context == nil {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func CertFreeCertificateContext(ctx *CertContext) (err error) {
-	r1, _, e1 := Syscall(procCertFreeCertificateContext.Addr(), 1, uintptr(unsafe.Pointer(ctx)), 0, 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func CertVerifyCertificateChainPolicy(policyOID uintptr, chain *CertChainContext, para *CertChainPolicyPara, status *CertChainPolicyStatus) (err error) {
-	r1, _, e1 := Syscall6(procCertVerifyCertificateChainPolicy.Addr(), 4, uintptr(policyOID), uintptr(unsafe.Pointer(chain)), uintptr(unsafe.Pointer(para)), uintptr(unsafe.Pointer(status)), 0, 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func RegOpenKeyEx(key Handle, subkey *uint16, options uint32, desiredAccess uint32, result *Handle) (regerrno error) {
-	r0, _, _ := Syscall6(procRegOpenKeyExW.Addr(), 5, uintptr(key), uintptr(unsafe.Pointer(subkey)), uintptr(options), uintptr(desiredAccess), uintptr(unsafe.Pointer(result)), 0)
-	if r0 != 0 {
-		regerrno = Errno(r0)
-	}
-	return
-}
-
-func RegCloseKey(key Handle) (regerrno error) {
-	r0, _, _ := Syscall(procRegCloseKey.Addr(), 1, uintptr(key), 0, 0)
-	if r0 != 0 {
-		regerrno = Errno(r0)
-	}
-	return
-}
-
-func RegQueryInfoKey(key Handle, class *uint16, classLen *uint32, reserved *uint32, subkeysLen *uint32, maxSubkeyLen *uint32, maxClassLen *uint32, valuesLen *uint32, maxValueNameLen *uint32, maxValueLen *uint32, saLen *uint32, lastWriteTime *Filetime) (regerrno error) {
-	r0, _, _ := Syscall12(procRegQueryInfoKeyW.Addr(), 12, uintptr(key), uintptr(unsafe.Pointer(class)), uintptr(unsafe.Pointer(classLen)), uintptr(unsafe.Pointer(reserved)), uintptr(unsafe.Pointer(subkeysLen)), uintptr(unsafe.Pointer(maxSubkeyLen)), uintptr(unsafe.Pointer(maxClassLen)), uintptr(unsafe.Pointer(valuesLen)), uintptr(unsafe.Pointer(maxValueNameLen)), uintptr(unsafe.Pointer(maxValueLen)), uintptr(unsafe.Pointer(saLen)), uintptr(unsafe.Pointer(lastWriteTime)))
-	if r0 != 0 {
-		regerrno = Errno(r0)
-	}
-	return
-}
-
-func RegEnumKeyEx(key Handle, index uint32, name *uint16, nameLen *uint32, reserved *uint32, class *uint16, classLen *uint32, lastWriteTime *Filetime) (regerrno error) {
-	r0, _, _ := Syscall9(procRegEnumKeyExW.Addr(), 8, uintptr(key), uintptr(index), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(nameLen)), uintptr(unsafe.Pointer(reserved)), uintptr(unsafe.Pointer(class)), uintptr(unsafe.Pointer(classLen)), uintptr(unsafe.Pointer(lastWriteTime)), 0)
-	if r0 != 0 {
-		regerrno = Errno(r0)
-	}
-	return
-}
-
-func RegQueryValueEx(key Handle, name *uint16, reserved *uint32, valtype *uint32, buf *byte, buflen *uint32) (regerrno error) {
-	r0, _, _ := Syscall6(procRegQueryValueExW.Addr(), 6, uintptr(key), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(reserved)), uintptr(unsafe.Pointer(valtype)), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(buflen)))
-	if r0 != 0 {
-		regerrno = Errno(r0)
-	}
-	return
-}
-
-func getCurrentProcessId() (pid uint32) {
-	r0, _, _ := Syscall(procGetCurrentProcessId.Addr(), 0, 0, 0, 0)
-	pid = uint32(r0)
-	return
-}
-
-func GetConsoleMode(console Handle, mode *uint32) (err error) {
-	r1, _, e1 := Syscall(procGetConsoleMode.Addr(), 2, uintptr(console), uintptr(unsafe.Pointer(mode)), 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func WriteConsole(console Handle, buf *uint16, towrite uint32, written *uint32, reserved *byte) (err error) {
-	r1, _, e1 := Syscall6(procWriteConsoleW.Addr(), 5, uintptr(console), uintptr(unsafe.Pointer(buf)), uintptr(towrite), uintptr(unsafe.Pointer(written)), uintptr(unsafe.Pointer(reserved)), 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func ReadConsole(console Handle, buf *uint16, toread uint32, read *uint32, inputControl *byte) (err error) {
-	r1, _, e1 := Syscall6(procReadConsoleW.Addr(), 5, uintptr(console), uintptr(unsafe.Pointer(buf)), uintptr(toread), uintptr(unsafe.Pointer(read)), uintptr(unsafe.Pointer(inputControl)), 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func WSAStartup(verreq uint32, data *WSAData) (sockerr error) {
-	r0, _, _ := Syscall(procWSAStartup.Addr(), 2, uintptr(verreq), uintptr(unsafe.Pointer(data)), 0)
-	if r0 != 0 {
-		sockerr = Errno(r0)
-	}
-	return
-}
-
-func WSACleanup() (err error) {
-	r1, _, e1 := Syscall(procWSACleanup.Addr(), 0, 0, 0, 0)
-	if r1 == socket_error {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func WSAIoctl(s Handle, iocc uint32, inbuf *byte, cbif uint32, outbuf *byte, cbob uint32, cbbr *uint32, overlapped *Overlapped, completionRoutine uintptr) (err error) {
-	r1, _, e1 := Syscall9(procWSAIoctl.Addr(), 9, uintptr(s), uintptr(iocc), uintptr(unsafe.Pointer(inbuf)), uintptr(cbif), uintptr(unsafe.Pointer(outbuf)), uintptr(cbob), uintptr(unsafe.Pointer(cbbr)), uintptr(unsafe.Pointer(overlapped)), uintptr(completionRoutine))
-	if r1 == socket_error {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func socket(af int32, typ int32, protocol int32) (handle Handle, err error) {
-	r0, _, e1 := Syscall(procsocket.Addr(), 3, uintptr(af), uintptr(typ), uintptr(protocol))
-	handle = Handle(r0)
-	if handle == InvalidHandle {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func Setsockopt(s Handle, level int32, optname int32, optval *byte, optlen int32) (err error) {
-	r1, _, e1 := Syscall6(procsetsockopt.Addr(), 5, uintptr(s), uintptr(level), uintptr(optname), uintptr(unsafe.Pointer(optval)), uintptr(optlen), 0)
-	if r1 == socket_error {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func Getsockopt(s Handle, level int32, optname int32, optval *byte, optlen *int32) (err error) {
-	r1, _, e1 := Syscall6(procgetsockopt.Addr(), 5, uintptr(s), uintptr(level), uintptr(optname), uintptr(unsafe.Pointer(optval)), uintptr(unsafe.Pointer(optlen)), 0)
-	if r1 == socket_error {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func bind(s Handle, name unsafe.Pointer, namelen int32) (err error) {
-	r1, _, e1 := Syscall(procbind.Addr(), 3, uintptr(s), uintptr(name), uintptr(namelen))
-	if r1 == socket_error {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func connect(s Handle, name unsafe.Pointer, namelen int32) (err error) {
-	r1, _, e1 := Syscall(procconnect.Addr(), 3, uintptr(s), uintptr(name), uintptr(namelen))
-	if r1 == socket_error {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func getsockname(s Handle, rsa *RawSockaddrAny, addrlen *int32) (err error) {
-	r1, _, e1 := Syscall(procgetsockname.Addr(), 3, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
-	if r1 == socket_error {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func getpeername(s Handle, rsa *RawSockaddrAny, addrlen *int32) (err error) {
-	r1, _, e1 := Syscall(procgetpeername.Addr(), 3, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
-	if r1 == socket_error {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func listen(s Handle, backlog int32) (err error) {
-	r1, _, e1 := Syscall(proclisten.Addr(), 2, uintptr(s), uintptr(backlog), 0)
-	if r1 == socket_error {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func shutdown(s Handle, how int32) (err error) {
-	r1, _, e1 := Syscall(procshutdown.Addr(), 2, uintptr(s), uintptr(how), 0)
-	if r1 == socket_error {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func Closesocket(s Handle) (err error) {
-	r1, _, e1 := Syscall(procclosesocket.Addr(), 1, uintptr(s), 0, 0)
-	if r1 == socket_error {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func AcceptEx(ls Handle, as Handle, buf *byte, rxdatalen uint32, laddrlen uint32, raddrlen uint32, recvd *uint32, overlapped *Overlapped) (err error) {
-	r1, _, e1 := Syscall9(procAcceptEx.Addr(), 8, uintptr(ls), uintptr(as), uintptr(unsafe.Pointer(buf)), uintptr(rxdatalen), uintptr(laddrlen), uintptr(raddrlen), uintptr(unsafe.Pointer(recvd)), uintptr(unsafe.Pointer(overlapped)), 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func GetAcceptExSockaddrs(buf *byte, rxdatalen uint32, laddrlen uint32, raddrlen uint32, lrsa **RawSockaddrAny, lrsalen *int32, rrsa **RawSockaddrAny, rrsalen *int32) {
-	Syscall9(procGetAcceptExSockaddrs.Addr(), 8, uintptr(unsafe.Pointer(buf)), uintptr(rxdatalen), uintptr(laddrlen), uintptr(raddrlen), uintptr(unsafe.Pointer(lrsa)), uintptr(unsafe.Pointer(lrsalen)), uintptr(unsafe.Pointer(rrsa)), uintptr(unsafe.Pointer(rrsalen)), 0)
-	return
-}
-
-func WSARecv(s Handle, bufs *WSABuf, bufcnt uint32, recvd *uint32, flags *uint32, overlapped *Overlapped, croutine *byte) (err error) {
-	r1, _, e1 := Syscall9(procWSARecv.Addr(), 7, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(recvd)), uintptr(unsafe.Pointer(flags)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)), 0, 0)
-	if r1 == socket_error {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func WSASend(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, overlapped *Overlapped, croutine *byte) (err error) {
-	r1, _, e1 := Syscall9(procWSASend.Addr(), 7, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(sent)), uintptr(flags), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)), 0, 0)
-	if r1 == socket_error {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func WSARecvFrom(s Handle, bufs *WSABuf, bufcnt uint32, recvd *uint32, flags *uint32, from *RawSockaddrAny, fromlen *int32, overlapped *Overlapped, croutine *byte) (err error) {
-	r1, _, e1 := Syscall9(procWSARecvFrom.Addr(), 9, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(recvd)), uintptr(unsafe.Pointer(flags)), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)))
-	if r1 == socket_error {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func WSASendTo(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, to *RawSockaddrAny, tolen int32, overlapped *Overlapped, croutine *byte) (err error) {
-	r1, _, e1 := Syscall9(procWSASendTo.Addr(), 9, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(sent)), uintptr(flags), uintptr(unsafe.Pointer(to)), uintptr(tolen), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)))
-	if r1 == socket_error {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func GetHostByName(name string) (h *Hostent, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(name)
-	if err != nil {
-		return
-	}
-	r0, _, e1 := Syscall(procgethostbyname.Addr(), 1, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	h = (*Hostent)(unsafe.Pointer(r0))
-	if h == nil {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func GetServByName(name string, proto string) (s *Servent, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(name)
-	if err != nil {
-		return
-	}
-	var _p1 *byte
-	_p1, err = BytePtrFromString(proto)
-	if err != nil {
-		return
-	}
-	r0, _, e1 := Syscall(procgetservbyname.Addr(), 2, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
-	s = (*Servent)(unsafe.Pointer(r0))
-	if s == nil {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func Ntohs(netshort uint16) (u uint16) {
-	r0, _, _ := Syscall(procntohs.Addr(), 1, uintptr(netshort), 0, 0)
-	u = uint16(r0)
-	return
-}
-
-func GetProtoByName(name string) (p *Protoent, err error) {
-	var _p0 *byte
-	_p0, err = BytePtrFromString(name)
-	if err != nil {
-		return
-	}
-	r0, _, e1 := Syscall(procgetprotobyname.Addr(), 1, uintptr(unsafe.Pointer(_p0)), 0, 0)
-	p = (*Protoent)(unsafe.Pointer(r0))
-	if p == nil {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func DnsQuery(name string, qtype uint16, options uint32, extra *byte, qrs **DNSRecord, pr *byte) (status error) {
-	var _p0 *uint16
-	_p0, status = UTF16PtrFromString(name)
-	if status != nil {
-		return
-	}
-	r0, _, _ := Syscall6(procDnsQuery_W.Addr(), 6, uintptr(unsafe.Pointer(_p0)), uintptr(qtype), uintptr(options), uintptr(unsafe.Pointer(extra)), uintptr(unsafe.Pointer(qrs)), uintptr(unsafe.Pointer(pr)))
-	if r0 != 0 {
-		status = Errno(r0)
-	}
-	return
-}
-
-func DnsRecordListFree(rl *DNSRecord, freetype uint32) {
-	Syscall(procDnsRecordListFree.Addr(), 2, uintptr(unsafe.Pointer(rl)), uintptr(freetype), 0)
-	return
-}
-
-func GetAddrInfoW(nodename *uint16, servicename *uint16, hints *AddrinfoW, result **AddrinfoW) (sockerr error) {
-	r0, _, _ := Syscall6(procGetAddrInfoW.Addr(), 4, uintptr(unsafe.Pointer(nodename)), uintptr(unsafe.Pointer(servicename)), uintptr(unsafe.Pointer(hints)), uintptr(unsafe.Pointer(result)), 0, 0)
-	if r0 != 0 {
-		sockerr = Errno(r0)
-	}
-	return
-}
-
-func FreeAddrInfoW(addrinfo *AddrinfoW) {
-	Syscall(procFreeAddrInfoW.Addr(), 1, uintptr(unsafe.Pointer(addrinfo)), 0, 0)
-	return
-}
-
-func GetIfEntry(pIfRow *MibIfRow) (errcode error) {
-	r0, _, _ := Syscall(procGetIfEntry.Addr(), 1, uintptr(unsafe.Pointer(pIfRow)), 0, 0)
-	if r0 != 0 {
-		errcode = Errno(r0)
-	}
-	return
-}
-
-func GetAdaptersInfo(ai *IpAdapterInfo, ol *uint32) (errcode error) {
-	r0, _, _ := Syscall(procGetAdaptersInfo.Addr(), 2, uintptr(unsafe.Pointer(ai)), uintptr(unsafe.Pointer(ol)), 0)
-	if r0 != 0 {
-		errcode = Errno(r0)
-	}
-	return
-}
-
-func SetFileCompletionNotificationModes(handle Handle, flags uint8) (err error) {
-	r1, _, e1 := Syscall(procSetFileCompletionNotificationModes.Addr(), 2, uintptr(handle), uintptr(flags), 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func WSAEnumProtocols(protocols *int32, protocolBuffer *WSAProtocolInfo, bufferLength *uint32) (n int32, err error) {
-	r0, _, e1 := Syscall(procWSAEnumProtocolsW.Addr(), 3, uintptr(unsafe.Pointer(protocols)), uintptr(unsafe.Pointer(protocolBuffer)), uintptr(unsafe.Pointer(bufferLength)))
-	n = int32(r0)
-	if n == -1 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func TranslateName(accName *uint16, accNameFormat uint32, desiredNameFormat uint32, translatedName *uint16, nSize *uint32) (err error) {
-	r1, _, e1 := Syscall6(procTranslateNameW.Addr(), 5, uintptr(unsafe.Pointer(accName)), uintptr(accNameFormat), uintptr(desiredNameFormat), uintptr(unsafe.Pointer(translatedName)), uintptr(unsafe.Pointer(nSize)), 0)
-	if r1&0xff == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func GetUserNameEx(nameFormat uint32, nameBuffre *uint16, nSize *uint32) (err error) {
-	r1, _, e1 := Syscall(procGetUserNameExW.Addr(), 3, uintptr(nameFormat), uintptr(unsafe.Pointer(nameBuffre)), uintptr(unsafe.Pointer(nSize)))
-	if r1&0xff == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func NetUserGetInfo(serverName *uint16, userName *uint16, level uint32, buf **byte) (neterr error) {
-	r0, _, _ := Syscall6(procNetUserGetInfo.Addr(), 4, uintptr(unsafe.Pointer(serverName)), uintptr(unsafe.Pointer(userName)), uintptr(level), uintptr(unsafe.Pointer(buf)), 0, 0)
-	if r0 != 0 {
-		neterr = Errno(r0)
-	}
-	return
-}
-
-func NetGetJoinInformation(server *uint16, name **uint16, bufType *uint32) (neterr error) {
-	r0, _, _ := Syscall(procNetGetJoinInformation.Addr(), 3, uintptr(unsafe.Pointer(server)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(bufType)))
-	if r0 != 0 {
-		neterr = Errno(r0)
-	}
-	return
-}
-
-func NetApiBufferFree(buf *byte) (neterr error) {
-	r0, _, _ := Syscall(procNetApiBufferFree.Addr(), 1, uintptr(unsafe.Pointer(buf)), 0, 0)
-	if r0 != 0 {
-		neterr = Errno(r0)
-	}
-	return
-}
-
-func LookupAccountSid(systemName *uint16, sid *SID, name *uint16, nameLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) {
-	r1, _, e1 := Syscall9(procLookupAccountSidW.Addr(), 7, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(nameLen)), uintptr(unsafe.Pointer(refdDomainName)), uintptr(unsafe.Pointer(refdDomainNameLen)), uintptr(unsafe.Pointer(use)), 0, 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func LookupAccountName(systemName *uint16, accountName *uint16, sid *SID, sidLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) {
-	r1, _, e1 := Syscall9(procLookupAccountNameW.Addr(), 7, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(accountName)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(sidLen)), uintptr(unsafe.Pointer(refdDomainName)), uintptr(unsafe.Pointer(refdDomainNameLen)), uintptr(unsafe.Pointer(use)), 0, 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func ConvertSidToStringSid(sid *SID, stringSid **uint16) (err error) {
-	r1, _, e1 := Syscall(procConvertSidToStringSidW.Addr(), 2, uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(stringSid)), 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func ConvertStringSidToSid(stringSid *uint16, sid **SID) (err error) {
-	r1, _, e1 := Syscall(procConvertStringSidToSidW.Addr(), 2, uintptr(unsafe.Pointer(stringSid)), uintptr(unsafe.Pointer(sid)), 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func GetLengthSid(sid *SID) (len uint32) {
-	r0, _, _ := Syscall(procGetLengthSid.Addr(), 1, uintptr(unsafe.Pointer(sid)), 0, 0)
-	len = uint32(r0)
-	return
-}
-
-func CopySid(destSidLen uint32, destSid *SID, srcSid *SID) (err error) {
-	r1, _, e1 := Syscall(procCopySid.Addr(), 3, uintptr(destSidLen), uintptr(unsafe.Pointer(destSid)), uintptr(unsafe.Pointer(srcSid)))
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func OpenProcessToken(h Handle, access uint32, token *Token) (err error) {
-	r1, _, e1 := Syscall(procOpenProcessToken.Addr(), 3, uintptr(h), uintptr(access), uintptr(unsafe.Pointer(token)))
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func GetTokenInformation(t Token, infoClass uint32, info *byte, infoLen uint32, returnedLen *uint32) (err error) {
-	r1, _, e1 := Syscall6(procGetTokenInformation.Addr(), 5, uintptr(t), uintptr(infoClass), uintptr(unsafe.Pointer(info)), uintptr(infoLen), uintptr(unsafe.Pointer(returnedLen)), 0)
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
-
-func GetUserProfileDirectory(t Token, dir *uint16, dirLen *uint32) (err error) {
-	r1, _, e1 := Syscall(procGetUserProfileDirectoryW.Addr(), 3, uintptr(t), uintptr(unsafe.Pointer(dir)), uintptr(unsafe.Pointer(dirLen)))
-	if r1 == 0 {
-		if e1 != 0 {
-			err = error(e1)
-		} else {
-			err = EINVAL
-		}
-	}
-	return
-}
diff --git a/src/pkg/syscall/zsysnum_plan9_386.go b/src/pkg/syscall/zsysnum_plan9_386.go
deleted file mode 100644
index 4135b8d..0000000
--- a/src/pkg/syscall/zsysnum_plan9_386.go
+++ /dev/null
@@ -1,47 +0,0 @@
-// mksysnum_plan9.sh /media/sys/src/libc/9syscall/sys.h
-// MACHINE GENERATED BY THE ABOVE COMMAND; DO NOT EDIT
-
-package syscall
-
-const (
-	SYS_SYSR1      = 0
-	SYS_BIND       = 2
-	SYS_CHDIR      = 3
-	SYS_CLOSE      = 4
-	SYS_DUP        = 5
-	SYS_ALARM      = 6
-	SYS_EXEC       = 7
-	SYS_EXITS      = 8
-	SYS_FAUTH      = 10
-	SYS_SEGBRK     = 12
-	SYS_OPEN       = 14
-	SYS_OSEEK      = 16
-	SYS_SLEEP      = 17
-	SYS_RFORK      = 19
-	SYS_PIPE       = 21
-	SYS_CREATE     = 22
-	SYS_FD2PATH    = 23
-	SYS_BRK_       = 24
-	SYS_REMOVE     = 25
-	SYS_NOTIFY     = 28
-	SYS_NOTED      = 29
-	SYS_SEGATTACH  = 30
-	SYS_SEGDETACH  = 31
-	SYS_SEGFREE    = 32
-	SYS_SEGFLUSH   = 33
-	SYS_RENDEZVOUS = 34
-	SYS_UNMOUNT    = 35
-	SYS_SEMACQUIRE = 37
-	SYS_SEMRELEASE = 38
-	SYS_SEEK       = 39
-	SYS_FVERSION   = 40
-	SYS_ERRSTR     = 41
-	SYS_STAT       = 42
-	SYS_FSTAT      = 43
-	SYS_WSTAT      = 44
-	SYS_FWSTAT     = 45
-	SYS_MOUNT      = 46
-	SYS_AWAIT      = 47
-	SYS_PREAD      = 50
-	SYS_PWRITE     = 51
-)
diff --git a/src/pkg/syscall/zsysnum_plan9_amd64.go b/src/pkg/syscall/zsysnum_plan9_amd64.go
deleted file mode 100644
index c038646..0000000
--- a/src/pkg/syscall/zsysnum_plan9_amd64.go
+++ /dev/null
@@ -1,48 +0,0 @@
-// mksysnum_plan9.sh /media/sys/src/libc/9syscall/sys.h
-// MACHINE GENERATED BY THE ABOVE COMMAND; DO NOT EDIT
-
-package syscall
-
-const (
-	SYS_SYSR1      = 0
-	SYS_BIND       = 2
-	SYS_CHDIR      = 3
-	SYS_CLOSE      = 4
-	SYS_DUP        = 5
-	SYS_ALARM      = 6
-	SYS_EXEC       = 7
-	SYS_EXITS      = 8
-	SYS_FAUTH      = 10
-	SYS_SEGBRK     = 12
-	SYS_OPEN       = 14
-	SYS_OSEEK      = 16
-	SYS_SLEEP      = 17
-	SYS_RFORK      = 19
-	SYS_PIPE       = 21
-	SYS_CREATE     = 22
-	SYS_FD2PATH    = 23
-	SYS_BRK_       = 24
-	SYS_REMOVE     = 25
-	SYS_NOTIFY     = 28
-	SYS_NOTED      = 29
-	SYS_SEGATTACH  = 30
-	SYS_SEGDETACH  = 31
-	SYS_SEGFREE    = 32
-	SYS_SEGFLUSH   = 33
-	SYS_RENDEZVOUS = 34
-	SYS_UNMOUNT    = 35
-	SYS_SEMACQUIRE = 37
-	SYS_SEMRELEASE = 38
-	SYS_SEEK       = 39
-	SYS_FVERSION   = 40
-	SYS_ERRSTR     = 41
-	SYS_STAT       = 42
-	SYS_FSTAT      = 43
-	SYS_WSTAT      = 44
-	SYS_FWSTAT     = 45
-	SYS_MOUNT      = 46
-	SYS_AWAIT      = 47
-	SYS_PREAD      = 50
-	SYS_PWRITE     = 51
-	SYS_NANOTIME   = 60
-)
diff --git a/src/pkg/syscall/ztypes_windows.go b/src/pkg/syscall/ztypes_windows.go
deleted file mode 100644
index a1d77e0..0000000
--- a/src/pkg/syscall/ztypes_windows.go
+++ /dev/null
@@ -1,1044 +0,0 @@
-// Copyright 2011 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package syscall
-
-const (
-	// Windows errors.
-	ERROR_FILE_NOT_FOUND      Errno = 2
-	ERROR_PATH_NOT_FOUND      Errno = 3
-	ERROR_ACCESS_DENIED       Errno = 5
-	ERROR_NO_MORE_FILES       Errno = 18
-	ERROR_HANDLE_EOF          Errno = 38
-	ERROR_NETNAME_DELETED     Errno = 64
-	ERROR_FILE_EXISTS         Errno = 80
-	ERROR_BROKEN_PIPE         Errno = 109
-	ERROR_BUFFER_OVERFLOW     Errno = 111
-	ERROR_INSUFFICIENT_BUFFER Errno = 122
-	ERROR_MOD_NOT_FOUND       Errno = 126
-	ERROR_PROC_NOT_FOUND      Errno = 127
-	ERROR_ALREADY_EXISTS      Errno = 183
-	ERROR_ENVVAR_NOT_FOUND    Errno = 203
-	ERROR_MORE_DATA           Errno = 234
-	ERROR_OPERATION_ABORTED   Errno = 995
-	ERROR_IO_PENDING          Errno = 997
-	ERROR_NOT_FOUND           Errno = 1168
-	WSAEACCES                 Errno = 10013
-	WSAECONNRESET             Errno = 10054
-)
-
-const (
-	// Invented values to support what package os expects.
-	O_RDONLY   = 0x00000
-	O_WRONLY   = 0x00001
-	O_RDWR     = 0x00002
-	O_CREAT    = 0x00040
-	O_EXCL     = 0x00080
-	O_NOCTTY   = 0x00100
-	O_TRUNC    = 0x00200
-	O_NONBLOCK = 0x00800
-	O_APPEND   = 0x00400
-	O_SYNC     = 0x01000
-	O_ASYNC    = 0x02000
-	O_CLOEXEC  = 0x80000
-)
-
-const (
-	// More invented values for signals
-	SIGHUP  = Signal(0x1)
-	SIGINT  = Signal(0x2)
-	SIGQUIT = Signal(0x3)
-	SIGILL  = Signal(0x4)
-	SIGTRAP = Signal(0x5)
-	SIGABRT = Signal(0x6)
-	SIGBUS  = Signal(0x7)
-	SIGFPE  = Signal(0x8)
-	SIGKILL = Signal(0x9)
-	SIGSEGV = Signal(0xb)
-	SIGPIPE = Signal(0xd)
-	SIGALRM = Signal(0xe)
-	SIGTERM = Signal(0xf)
-)
-
-var signals = [...]string{
-	1:  "hangup",
-	2:  "interrupt",
-	3:  "quit",
-	4:  "illegal instruction",
-	5:  "trace/breakpoint trap",
-	6:  "aborted",
-	7:  "bus error",
-	8:  "floating point exception",
-	9:  "killed",
-	10: "user defined signal 1",
-	11: "segmentation fault",
-	12: "user defined signal 2",
-	13: "broken pipe",
-	14: "alarm clock",
-	15: "terminated",
-}
-
-const (
-	GENERIC_READ    = 0x80000000
-	GENERIC_WRITE   = 0x40000000
-	GENERIC_EXECUTE = 0x20000000
-	GENERIC_ALL     = 0x10000000
-
-	FILE_LIST_DIRECTORY   = 0x00000001
-	FILE_APPEND_DATA      = 0x00000004
-	FILE_WRITE_ATTRIBUTES = 0x00000100
-
-	FILE_SHARE_READ          = 0x00000001
-	FILE_SHARE_WRITE         = 0x00000002
-	FILE_SHARE_DELETE        = 0x00000004
-	FILE_ATTRIBUTE_READONLY  = 0x00000001
-	FILE_ATTRIBUTE_HIDDEN    = 0x00000002
-	FILE_ATTRIBUTE_SYSTEM    = 0x00000004
-	FILE_ATTRIBUTE_DIRECTORY = 0x00000010
-	FILE_ATTRIBUTE_ARCHIVE   = 0x00000020
-	FILE_ATTRIBUTE_NORMAL    = 0x00000080
-
-	INVALID_FILE_ATTRIBUTES = 0xffffffff
-
-	CREATE_NEW        = 1
-	CREATE_ALWAYS     = 2
-	OPEN_EXISTING     = 3
-	OPEN_ALWAYS       = 4
-	TRUNCATE_EXISTING = 5
-
-	FILE_FLAG_BACKUP_SEMANTICS = 0x02000000
-	FILE_FLAG_OVERLAPPED       = 0x40000000
-
-	HANDLE_FLAG_INHERIT    = 0x00000001
-	STARTF_USESTDHANDLES   = 0x00000100
-	STARTF_USESHOWWINDOW   = 0x00000001
-	DUPLICATE_CLOSE_SOURCE = 0x00000001
-	DUPLICATE_SAME_ACCESS  = 0x00000002
-
-	STD_INPUT_HANDLE  = -10
-	STD_OUTPUT_HANDLE = -11
-	STD_ERROR_HANDLE  = -12
-
-	FILE_BEGIN   = 0
-	FILE_CURRENT = 1
-	FILE_END     = 2
-
-	LANG_ENGLISH       = 0x09
-	SUBLANG_ENGLISH_US = 0x01
-
-	FORMAT_MESSAGE_ALLOCATE_BUFFER = 256
-	FORMAT_MESSAGE_IGNORE_INSERTS  = 512
-	FORMAT_MESSAGE_FROM_STRING     = 1024
-	FORMAT_MESSAGE_FROM_HMODULE    = 2048
-	FORMAT_MESSAGE_FROM_SYSTEM     = 4096
-	FORMAT_MESSAGE_ARGUMENT_ARRAY  = 8192
-	FORMAT_MESSAGE_MAX_WIDTH_MASK  = 255
-
-	MAX_PATH      = 260
-	MAX_LONG_PATH = 32768
-
-	MAX_COMPUTERNAME_LENGTH = 15
-
-	TIME_ZONE_ID_UNKNOWN  = 0
-	TIME_ZONE_ID_STANDARD = 1
-
-	TIME_ZONE_ID_DAYLIGHT = 2
-	IGNORE                = 0
-	INFINITE              = 0xffffffff
-
-	WAIT_TIMEOUT   = 258
-	WAIT_ABANDONED = 0x00000080
-	WAIT_OBJECT_0  = 0x00000000
-	WAIT_FAILED    = 0xFFFFFFFF
-
-	CREATE_NEW_PROCESS_GROUP   = 0x00000200
-	CREATE_UNICODE_ENVIRONMENT = 0x00000400
-
-	PROCESS_TERMINATE         = 1
-	PROCESS_QUERY_INFORMATION = 0x00000400
-	SYNCHRONIZE               = 0x00100000
-
-	PAGE_READONLY          = 0x02
-	PAGE_READWRITE         = 0x04
-	PAGE_WRITECOPY         = 0x08
-	PAGE_EXECUTE_READ      = 0x20
-	PAGE_EXECUTE_READWRITE = 0x40
-	PAGE_EXECUTE_WRITECOPY = 0x80
-
-	FILE_MAP_COPY    = 0x01
-	FILE_MAP_WRITE   = 0x02
-	FILE_MAP_READ    = 0x04
-	FILE_MAP_EXECUTE = 0x20
-
-	CTRL_C_EVENT     = 0
-	CTRL_BREAK_EVENT = 1
-)
-
-const (
-	// do not reorder
-	FILE_NOTIFY_CHANGE_FILE_NAME = 1 << iota
-	FILE_NOTIFY_CHANGE_DIR_NAME
-	FILE_NOTIFY_CHANGE_ATTRIBUTES
-	FILE_NOTIFY_CHANGE_SIZE
-	FILE_NOTIFY_CHANGE_LAST_WRITE
-	FILE_NOTIFY_CHANGE_LAST_ACCESS
-	FILE_NOTIFY_CHANGE_CREATION
-)
-
-const (
-	// do not reorder
-	FILE_ACTION_ADDED = iota + 1
-	FILE_ACTION_REMOVED
-	FILE_ACTION_MODIFIED
-	FILE_ACTION_RENAMED_OLD_NAME
-	FILE_ACTION_RENAMED_NEW_NAME
-)
-
-const (
-	// wincrypt.h
-	PROV_RSA_FULL                    = 1
-	PROV_RSA_SIG                     = 2
-	PROV_DSS                         = 3
-	PROV_FORTEZZA                    = 4
-	PROV_MS_EXCHANGE                 = 5
-	PROV_SSL                         = 6
-	PROV_RSA_SCHANNEL                = 12
-	PROV_DSS_DH                      = 13
-	PROV_EC_ECDSA_SIG                = 14
-	PROV_EC_ECNRA_SIG                = 15
-	PROV_EC_ECDSA_FULL               = 16
-	PROV_EC_ECNRA_FULL               = 17
-	PROV_DH_SCHANNEL                 = 18
-	PROV_SPYRUS_LYNKS                = 20
-	PROV_RNG                         = 21
-	PROV_INTEL_SEC                   = 22
-	PROV_REPLACE_OWF                 = 23
-	PROV_RSA_AES                     = 24
-	CRYPT_VERIFYCONTEXT              = 0xF0000000
-	CRYPT_NEWKEYSET                  = 0x00000008
-	CRYPT_DELETEKEYSET               = 0x00000010
-	CRYPT_MACHINE_KEYSET             = 0x00000020
-	CRYPT_SILENT                     = 0x00000040
-	CRYPT_DEFAULT_CONTAINER_OPTIONAL = 0x00000080
-
-	USAGE_MATCH_TYPE_AND = 0
-	USAGE_MATCH_TYPE_OR  = 1
-
-	X509_ASN_ENCODING   = 0x00000001
-	PKCS_7_ASN_ENCODING = 0x00010000
-
-	CERT_STORE_PROV_MEMORY = 2
-
-	CERT_STORE_ADD_ALWAYS = 4
-
-	CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG = 0x00000004
-
-	CERT_TRUST_NO_ERROR                          = 0x00000000
-	CERT_TRUST_IS_NOT_TIME_VALID                 = 0x00000001
-	CERT_TRUST_IS_REVOKED                        = 0x00000004
-	CERT_TRUST_IS_NOT_SIGNATURE_VALID            = 0x00000008
-	CERT_TRUST_IS_NOT_VALID_FOR_USAGE            = 0x00000010
-	CERT_TRUST_IS_UNTRUSTED_ROOT                 = 0x00000020
-	CERT_TRUST_REVOCATION_STATUS_UNKNOWN         = 0x00000040
-	CERT_TRUST_IS_CYCLIC                         = 0x00000080
-	CERT_TRUST_INVALID_EXTENSION                 = 0x00000100
-	CERT_TRUST_INVALID_POLICY_CONSTRAINTS        = 0x00000200
-	CERT_TRUST_INVALID_BASIC_CONSTRAINTS         = 0x00000400
-	CERT_TRUST_INVALID_NAME_CONSTRAINTS          = 0x00000800
-	CERT_TRUST_HAS_NOT_SUPPORTED_NAME_CONSTRAINT = 0x00001000
-	CERT_TRUST_HAS_NOT_DEFINED_NAME_CONSTRAINT   = 0x00002000
-	CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT = 0x00004000
-	CERT_TRUST_HAS_EXCLUDED_NAME_CONSTRAINT      = 0x00008000
-	CERT_TRUST_IS_OFFLINE_REVOCATION             = 0x01000000
-	CERT_TRUST_NO_ISSUANCE_CHAIN_POLICY          = 0x02000000
-	CERT_TRUST_IS_EXPLICIT_DISTRUST              = 0x04000000
-	CERT_TRUST_HAS_NOT_SUPPORTED_CRITICAL_EXT    = 0x08000000
-
-	CERT_CHAIN_POLICY_BASE              = 1
-	CERT_CHAIN_POLICY_AUTHENTICODE      = 2
-	CERT_CHAIN_POLICY_AUTHENTICODE_TS   = 3
-	CERT_CHAIN_POLICY_SSL               = 4
-	CERT_CHAIN_POLICY_BASIC_CONSTRAINTS = 5
-	CERT_CHAIN_POLICY_NT_AUTH           = 6
-	CERT_CHAIN_POLICY_MICROSOFT_ROOT    = 7
-	CERT_CHAIN_POLICY_EV                = 8
-
-	CERT_E_EXPIRED       = 0x800B0101
-	CERT_E_ROLE          = 0x800B0103
-	CERT_E_PURPOSE       = 0x800B0106
-	CERT_E_UNTRUSTEDROOT = 0x800B0109
-	CERT_E_CN_NO_MATCH   = 0x800B010F
-
-	AUTHTYPE_CLIENT = 1
-	AUTHTYPE_SERVER = 2
-)
-
-var (
-	OID_PKIX_KP_SERVER_AUTH = []byte("1.3.6.1.5.5.7.3.1\x00")
-	OID_SERVER_GATED_CRYPTO = []byte("1.3.6.1.4.1.311.10.3.3\x00")
-	OID_SGC_NETSCAPE        = []byte("2.16.840.1.113730.4.1\x00")
-)
-
-// Invented values to support what package os expects.
-type Timeval struct {
-	Sec  int32
-	Usec int32
-}
-
-func (tv *Timeval) Nanoseconds() int64 {
-	return (int64(tv.Sec)*1e6 + int64(tv.Usec)) * 1e3
-}
-
-func NsecToTimeval(nsec int64) (tv Timeval) {
-	tv.Sec = int32(nsec / 1e9)
-	tv.Usec = int32(nsec % 1e9 / 1e3)
-	return
-}
-
-type SecurityAttributes struct {
-	Length             uint32
-	SecurityDescriptor uintptr
-	InheritHandle      uint32
-}
-
-type Overlapped struct {
-	Internal     uintptr
-	InternalHigh uintptr
-	Offset       uint32
-	OffsetHigh   uint32
-	HEvent       Handle
-}
-
-type FileNotifyInformation struct {
-	NextEntryOffset uint32
-	Action          uint32
-	FileNameLength  uint32
-	FileName        uint16
-}
-
-type Filetime struct {
-	LowDateTime  uint32
-	HighDateTime uint32
-}
-
-// Nanoseconds returns Filetime ft in nanoseconds
-// since Epoch (00:00:00 UTC, January 1, 1970).
-func (ft *Filetime) Nanoseconds() int64 {
-	// 100-nanosecond intervals since January 1, 1601
-	nsec := int64(ft.HighDateTime)<<32 + int64(ft.LowDateTime)
-	// change starting time to the Epoch (00:00:00 UTC, January 1, 1970)
-	nsec -= 116444736000000000
-	// convert into nanoseconds
-	nsec *= 100
-	return nsec
-}
-
-func NsecToFiletime(nsec int64) (ft Filetime) {
-	// convert into 100-nanosecond
-	nsec /= 100
-	// change starting time to January 1, 1601
-	nsec += 116444736000000000
-	// split into high / low
-	ft.LowDateTime = uint32(nsec & 0xffffffff)
-	ft.HighDateTime = uint32(nsec >> 32 & 0xffffffff)
-	return ft
-}
-
-type Win32finddata struct {
-	FileAttributes    uint32
-	CreationTime      Filetime
-	LastAccessTime    Filetime
-	LastWriteTime     Filetime
-	FileSizeHigh      uint32
-	FileSizeLow       uint32
-	Reserved0         uint32
-	Reserved1         uint32
-	FileName          [MAX_PATH - 1]uint16
-	AlternateFileName [13]uint16
-}
-
-// This is the actual system call structure.
-// Win32finddata is what we committed to in Go 1.
-type win32finddata1 struct {
-	FileAttributes    uint32
-	CreationTime      Filetime
-	LastAccessTime    Filetime
-	LastWriteTime     Filetime
-	FileSizeHigh      uint32
-	FileSizeLow       uint32
-	Reserved0         uint32
-	Reserved1         uint32
-	FileName          [MAX_PATH]uint16
-	AlternateFileName [14]uint16
-}
-
-func copyFindData(dst *Win32finddata, src *win32finddata1) {
-	dst.FileAttributes = src.FileAttributes
-	dst.CreationTime = src.CreationTime
-	dst.LastAccessTime = src.LastAccessTime
-	dst.LastWriteTime = src.LastWriteTime
-	dst.FileSizeHigh = src.FileSizeHigh
-	dst.FileSizeLow = src.FileSizeLow
-	dst.Reserved0 = src.Reserved0
-	dst.Reserved1 = src.Reserved1
-
-	// The src is 1 element bigger than dst, but it must be NUL.
-	copy(dst.FileName[:], src.FileName[:])
-	copy(dst.AlternateFileName[:], src.AlternateFileName[:])
-}
-
-type ByHandleFileInformation struct {
-	FileAttributes     uint32
-	CreationTime       Filetime
-	LastAccessTime     Filetime
-	LastWriteTime      Filetime
-	VolumeSerialNumber uint32
-	FileSizeHigh       uint32
-	FileSizeLow        uint32
-	NumberOfLinks      uint32
-	FileIndexHigh      uint32
-	FileIndexLow       uint32
-}
-
-const (
-	GetFileExInfoStandard = 0
-	GetFileExMaxInfoLevel = 1
-)
-
-type Win32FileAttributeData struct {
-	FileAttributes uint32
-	CreationTime   Filetime
-	LastAccessTime Filetime
-	LastWriteTime  Filetime
-	FileSizeHigh   uint32
-	FileSizeLow    uint32
-}
-
-// ShowWindow constants
-const (
-	// winuser.h
-	SW_HIDE            = 0
-	SW_NORMAL          = 1
-	SW_SHOWNORMAL      = 1
-	SW_SHOWMINIMIZED   = 2
-	SW_SHOWMAXIMIZED   = 3
-	SW_MAXIMIZE        = 3
-	SW_SHOWNOACTIVATE  = 4
-	SW_SHOW            = 5
-	SW_MINIMIZE        = 6
-	SW_SHOWMINNOACTIVE = 7
-	SW_SHOWNA          = 8
-	SW_RESTORE         = 9
-	SW_SHOWDEFAULT     = 10
-	SW_FORCEMINIMIZE   = 11
-)
-
-type StartupInfo struct {
-	Cb            uint32
-	_             *uint16
-	Desktop       *uint16
-	Title         *uint16
-	X             uint32
-	Y             uint32
-	XSize         uint32
-	YSize         uint32
-	XCountChars   uint32
-	YCountChars   uint32
-	FillAttribute uint32
-	Flags         uint32
-	ShowWindow    uint16
-	_             uint16
-	_             *byte
-	StdInput      Handle
-	StdOutput     Handle
-	StdErr        Handle
-}
-
-type ProcessInformation struct {
-	Process   Handle
-	Thread    Handle
-	ProcessId uint32
-	ThreadId  uint32
-}
-
-type Systemtime struct {
-	Year         uint16
-	Month        uint16
-	DayOfWeek    uint16
-	Day          uint16
-	Hour         uint16
-	Minute       uint16
-	Second       uint16
-	Milliseconds uint16
-}
-
-type Timezoneinformation struct {
-	Bias         int32
-	StandardName [32]uint16
-	StandardDate Systemtime
-	StandardBias int32
-	DaylightName [32]uint16
-	DaylightDate Systemtime
-	DaylightBias int32
-}
-
-// Socket related.
-
-const (
-	AF_UNSPEC  = 0
-	AF_UNIX    = 1
-	AF_INET    = 2
-	AF_INET6   = 23
-	AF_NETBIOS = 17
-
-	SOCK_STREAM    = 1
-	SOCK_DGRAM     = 2
-	SOCK_RAW       = 3
-	SOCK_SEQPACKET = 5
-
-	IPPROTO_IP   = 0
-	IPPROTO_IPV6 = 0x29
-	IPPROTO_TCP  = 6
-	IPPROTO_UDP  = 17
-
-	SOL_SOCKET                = 0xffff
-	SO_REUSEADDR              = 4
-	SO_KEEPALIVE              = 8
-	SO_DONTROUTE              = 16
-	SO_BROADCAST              = 32
-	SO_LINGER                 = 128
-	SO_RCVBUF                 = 0x1002
-	SO_SNDBUF                 = 0x1001
-	SO_UPDATE_ACCEPT_CONTEXT  = 0x700b
-	SO_UPDATE_CONNECT_CONTEXT = 0x7010
-
-	IOC_OUT                            = 0x40000000
-	IOC_IN                             = 0x80000000
-	IOC_VENDOR                         = 0x18000000
-	IOC_INOUT                          = IOC_IN | IOC_OUT
-	IOC_WS2                            = 0x08000000
-	SIO_GET_EXTENSION_FUNCTION_POINTER = IOC_INOUT | IOC_WS2 | 6
-	SIO_KEEPALIVE_VALS                 = IOC_IN | IOC_VENDOR | 4
-
-	// cf. http://support.microsoft.com/default.aspx?scid=kb;en-us;257460
-
-	IP_TOS             = 0x3
-	IP_TTL             = 0x4
-	IP_MULTICAST_IF    = 0x9
-	IP_MULTICAST_TTL   = 0xa
-	IP_MULTICAST_LOOP  = 0xb
-	IP_ADD_MEMBERSHIP  = 0xc
-	IP_DROP_MEMBERSHIP = 0xd
-
-	IPV6_V6ONLY         = 0x1b
-	IPV6_UNICAST_HOPS   = 0x4
-	IPV6_MULTICAST_IF   = 0x9
-	IPV6_MULTICAST_HOPS = 0xa
-	IPV6_MULTICAST_LOOP = 0xb
-	IPV6_JOIN_GROUP     = 0xc
-	IPV6_LEAVE_GROUP    = 0xd
-
-	SOMAXCONN = 0x7fffffff
-
-	TCP_NODELAY = 1
-
-	SHUT_RD   = 0
-	SHUT_WR   = 1
-	SHUT_RDWR = 2
-
-	WSADESCRIPTION_LEN = 256
-	WSASYS_STATUS_LEN  = 128
-)
-
-type WSABuf struct {
-	Len uint32
-	Buf *byte
-}
-
-// Invented values to support what package os expects.
-const (
-	S_IFMT   = 0x1f000
-	S_IFIFO  = 0x1000
-	S_IFCHR  = 0x2000
-	S_IFDIR  = 0x4000
-	S_IFBLK  = 0x6000
-	S_IFREG  = 0x8000
-	S_IFLNK  = 0xa000
-	S_IFSOCK = 0xc000
-	S_ISUID  = 0x800
-	S_ISGID  = 0x400
-	S_ISVTX  = 0x200
-	S_IRUSR  = 0x100
-	S_IWRITE = 0x80
-	S_IWUSR  = 0x80
-	S_IXUSR  = 0x40
-)
-
-const (
-	FILE_TYPE_CHAR    = 0x0002
-	FILE_TYPE_DISK    = 0x0001
-	FILE_TYPE_PIPE    = 0x0003
-	FILE_TYPE_REMOTE  = 0x8000
-	FILE_TYPE_UNKNOWN = 0x0000
-)
-
-type Hostent struct {
-	Name     *byte
-	Aliases  **byte
-	AddrType uint16
-	Length   uint16
-	AddrList **byte
-}
-
-type Protoent struct {
-	Name    *byte
-	Aliases **byte
-	Proto   uint16
-}
-
-const (
-	DNS_TYPE_A       = 0x0001
-	DNS_TYPE_NS      = 0x0002
-	DNS_TYPE_MD      = 0x0003
-	DNS_TYPE_MF      = 0x0004
-	DNS_TYPE_CNAME   = 0x0005
-	DNS_TYPE_SOA     = 0x0006
-	DNS_TYPE_MB      = 0x0007
-	DNS_TYPE_MG      = 0x0008
-	DNS_TYPE_MR      = 0x0009
-	DNS_TYPE_NULL    = 0x000a
-	DNS_TYPE_WKS     = 0x000b
-	DNS_TYPE_PTR     = 0x000c
-	DNS_TYPE_HINFO   = 0x000d
-	DNS_TYPE_MINFO   = 0x000e
-	DNS_TYPE_MX      = 0x000f
-	DNS_TYPE_TEXT    = 0x0010
-	DNS_TYPE_RP      = 0x0011
-	DNS_TYPE_AFSDB   = 0x0012
-	DNS_TYPE_X25     = 0x0013
-	DNS_TYPE_ISDN    = 0x0014
-	DNS_TYPE_RT      = 0x0015
-	DNS_TYPE_NSAP    = 0x0016
-	DNS_TYPE_NSAPPTR = 0x0017
-	DNS_TYPE_SIG     = 0x0018
-	DNS_TYPE_KEY     = 0x0019
-	DNS_TYPE_PX      = 0x001a
-	DNS_TYPE_GPOS    = 0x001b
-	DNS_TYPE_AAAA    = 0x001c
-	DNS_TYPE_LOC     = 0x001d
-	DNS_TYPE_NXT     = 0x001e
-	DNS_TYPE_EID     = 0x001f
-	DNS_TYPE_NIMLOC  = 0x0020
-	DNS_TYPE_SRV     = 0x0021
-	DNS_TYPE_ATMA    = 0x0022
-	DNS_TYPE_NAPTR   = 0x0023
-	DNS_TYPE_KX      = 0x0024
-	DNS_TYPE_CERT    = 0x0025
-	DNS_TYPE_A6      = 0x0026
-	DNS_TYPE_DNAME   = 0x0027
-	DNS_TYPE_SINK    = 0x0028
-	DNS_TYPE_OPT     = 0x0029
-	DNS_TYPE_DS      = 0x002B
-	DNS_TYPE_RRSIG   = 0x002E
-	DNS_TYPE_NSEC    = 0x002F
-	DNS_TYPE_DNSKEY  = 0x0030
-	DNS_TYPE_DHCID   = 0x0031
-	DNS_TYPE_UINFO   = 0x0064
-	DNS_TYPE_UID     = 0x0065
-	DNS_TYPE_GID     = 0x0066
-	DNS_TYPE_UNSPEC  = 0x0067
-	DNS_TYPE_ADDRS   = 0x00f8
-	DNS_TYPE_TKEY    = 0x00f9
-	DNS_TYPE_TSIG    = 0x00fa
-	DNS_TYPE_IXFR    = 0x00fb
-	DNS_TYPE_AXFR    = 0x00fc
-	DNS_TYPE_MAILB   = 0x00fd
-	DNS_TYPE_MAILA   = 0x00fe
-	DNS_TYPE_ALL     = 0x00ff
-	DNS_TYPE_ANY     = 0x00ff
-	DNS_TYPE_WINS    = 0xff01
-	DNS_TYPE_WINSR   = 0xff02
-	DNS_TYPE_NBSTAT  = 0xff01
-)
-
-type DNSSRVData struct {
-	Target   *uint16
-	Priority uint16
-	Weight   uint16
-	Port     uint16
-	Pad      uint16
-}
-
-type DNSPTRData struct {
-	Host *uint16
-}
-
-type DNSMXData struct {
-	NameExchange *uint16
-	Preference   uint16
-	Pad          uint16
-}
-
-type DNSTXTData struct {
-	StringCount uint16
-	StringArray [1]*uint16
-}
-
-type DNSRecord struct {
-	Next     *DNSRecord
-	Name     *uint16
-	Type     uint16
-	Length   uint16
-	Dw       uint32
-	Ttl      uint32
-	Reserved uint32
-	Data     [40]byte
-}
-
-const (
-	TF_DISCONNECT         = 1
-	TF_REUSE_SOCKET       = 2
-	TF_WRITE_BEHIND       = 4
-	TF_USE_DEFAULT_WORKER = 0
-	TF_USE_SYSTEM_THREAD  = 16
-	TF_USE_KERNEL_APC     = 32
-)
-
-type TransmitFileBuffers struct {
-	Head       uintptr
-	HeadLength uint32
-	Tail       uintptr
-	TailLength uint32
-}
-
-const (
-	IFF_UP           = 1
-	IFF_BROADCAST    = 2
-	IFF_LOOPBACK     = 4
-	IFF_POINTTOPOINT = 8
-	IFF_MULTICAST    = 16
-)
-
-const SIO_GET_INTERFACE_LIST = 0x4004747F
-
-// TODO(mattn): SockaddrGen is union of sockaddr/sockaddr_in/sockaddr_in6_old.
-// will be fixed to change variable type as suitable.
-
-type SockaddrGen [24]byte
-
-type InterfaceInfo struct {
-	Flags            uint32
-	Address          SockaddrGen
-	BroadcastAddress SockaddrGen
-	Netmask          SockaddrGen
-}
-
-type IpAddressString struct {
-	String [16]byte
-}
-
-type IpMaskString IpAddressString
-
-type IpAddrString struct {
-	Next      *IpAddrString
-	IpAddress IpAddressString
-	IpMask    IpMaskString
-	Context   uint32
-}
-
-const MAX_ADAPTER_NAME_LENGTH = 256
-const MAX_ADAPTER_DESCRIPTION_LENGTH = 128
-const MAX_ADAPTER_ADDRESS_LENGTH = 8
-
-type IpAdapterInfo struct {
-	Next                *IpAdapterInfo
-	ComboIndex          uint32
-	AdapterName         [MAX_ADAPTER_NAME_LENGTH + 4]byte
-	Description         [MAX_ADAPTER_DESCRIPTION_LENGTH + 4]byte
-	AddressLength       uint32
-	Address             [MAX_ADAPTER_ADDRESS_LENGTH]byte
-	Index               uint32
-	Type                uint32
-	DhcpEnabled         uint32
-	CurrentIpAddress    *IpAddrString
-	IpAddressList       IpAddrString
-	GatewayList         IpAddrString
-	DhcpServer          IpAddrString
-	HaveWins            bool
-	PrimaryWinsServer   IpAddrString
-	SecondaryWinsServer IpAddrString
-	LeaseObtained       int64
-	LeaseExpires        int64
-}
-
-const MAXLEN_PHYSADDR = 8
-const MAX_INTERFACE_NAME_LEN = 256
-const MAXLEN_IFDESCR = 256
-
-type MibIfRow struct {
-	Name            [MAX_INTERFACE_NAME_LEN]uint16
-	Index           uint32
-	Type            uint32
-	Mtu             uint32
-	Speed           uint32
-	PhysAddrLen     uint32
-	PhysAddr        [MAXLEN_PHYSADDR]byte
-	AdminStatus     uint32
-	OperStatus      uint32
-	LastChange      uint32
-	InOctets        uint32
-	InUcastPkts     uint32
-	InNUcastPkts    uint32
-	InDiscards      uint32
-	InErrors        uint32
-	InUnknownProtos uint32
-	OutOctets       uint32
-	OutUcastPkts    uint32
-	OutNUcastPkts   uint32
-	OutDiscards     uint32
-	OutErrors       uint32
-	OutQLen         uint32
-	DescrLen        uint32
-	Descr           [MAXLEN_IFDESCR]byte
-}
-
-type CertContext struct {
-	EncodingType uint32
-	EncodedCert  *byte
-	Length       uint32
-	CertInfo     uintptr
-	Store        Handle
-}
-
-type CertChainContext struct {
-	Size                       uint32
-	TrustStatus                CertTrustStatus
-	ChainCount                 uint32
-	Chains                     **CertSimpleChain
-	LowerQualityChainCount     uint32
-	LowerQualityChains         **CertChainContext
-	HasRevocationFreshnessTime uint32
-	RevocationFreshnessTime    uint32
-}
-
-type CertSimpleChain struct {
-	Size                       uint32
-	TrustStatus                CertTrustStatus
-	NumElements                uint32
-	Elements                   **CertChainElement
-	TrustListInfo              uintptr
-	HasRevocationFreshnessTime uint32
-	RevocationFreshnessTime    uint32
-}
-
-type CertChainElement struct {
-	Size              uint32
-	CertContext       *CertContext
-	TrustStatus       CertTrustStatus
-	RevocationInfo    *CertRevocationInfo
-	IssuanceUsage     *CertEnhKeyUsage
-	ApplicationUsage  *CertEnhKeyUsage
-	ExtendedErrorInfo *uint16
-}
-
-type CertRevocationInfo struct {
-	Size             uint32
-	RevocationResult uint32
-	RevocationOid    *byte
-	OidSpecificInfo  uintptr
-	HasFreshnessTime uint32
-	FreshnessTime    uint32
-	CrlInfo          uintptr // *CertRevocationCrlInfo
-}
-
-type CertTrustStatus struct {
-	ErrorStatus uint32
-	InfoStatus  uint32
-}
-
-type CertUsageMatch struct {
-	Type  uint32
-	Usage CertEnhKeyUsage
-}
-
-type CertEnhKeyUsage struct {
-	Length           uint32
-	UsageIdentifiers **byte
-}
-
-type CertChainPara struct {
-	Size                         uint32
-	RequestedUsage               CertUsageMatch
-	RequstedIssuancePolicy       CertUsageMatch
-	URLRetrievalTimeout          uint32
-	CheckRevocationFreshnessTime uint32
-	RevocationFreshnessTime      uint32
-	CacheResync                  *Filetime
-}
-
-type CertChainPolicyPara struct {
-	Size            uint32
-	Flags           uint32
-	ExtraPolicyPara uintptr
-}
-
-type SSLExtraCertChainPolicyPara struct {
-	Size       uint32
-	AuthType   uint32
-	Checks     uint32
-	ServerName *uint16
-}
-
-type CertChainPolicyStatus struct {
-	Size              uint32
-	Error             uint32
-	ChainIndex        uint32
-	ElementIndex      uint32
-	ExtraPolicyStatus uintptr
-}
-
-const (
-	// do not reorder
-	HKEY_CLASSES_ROOT = 0x80000000 + iota
-	HKEY_CURRENT_USER
-	HKEY_LOCAL_MACHINE
-	HKEY_USERS
-	HKEY_PERFORMANCE_DATA
-	HKEY_CURRENT_CONFIG
-	HKEY_DYN_DATA
-
-	KEY_QUERY_VALUE        = 1
-	KEY_SET_VALUE          = 2
-	KEY_CREATE_SUB_KEY     = 4
-	KEY_ENUMERATE_SUB_KEYS = 8
-	KEY_NOTIFY             = 16
-	KEY_CREATE_LINK        = 32
-	KEY_WRITE              = 0x20006
-	KEY_EXECUTE            = 0x20019
-	KEY_READ               = 0x20019
-	KEY_WOW64_64KEY        = 0x0100
-	KEY_WOW64_32KEY        = 0x0200
-	KEY_ALL_ACCESS         = 0xf003f
-)
-
-const (
-	// do not reorder
-	REG_NONE = iota
-	REG_SZ
-	REG_EXPAND_SZ
-	REG_BINARY
-	REG_DWORD_LITTLE_ENDIAN
-	REG_DWORD_BIG_ENDIAN
-	REG_LINK
-	REG_MULTI_SZ
-	REG_RESOURCE_LIST
-	REG_FULL_RESOURCE_DESCRIPTOR
-	REG_RESOURCE_REQUIREMENTS_LIST
-	REG_QWORD_LITTLE_ENDIAN
-	REG_DWORD = REG_DWORD_LITTLE_ENDIAN
-	REG_QWORD = REG_QWORD_LITTLE_ENDIAN
-)
-
-type AddrinfoW struct {
-	Flags     int32
-	Family    int32
-	Socktype  int32
-	Protocol  int32
-	Addrlen   uintptr
-	Canonname *uint16
-	Addr      uintptr
-	Next      *AddrinfoW
-}
-
-const (
-	AI_PASSIVE     = 1
-	AI_CANONNAME   = 2
-	AI_NUMERICHOST = 4
-)
-
-type GUID struct {
-	Data1 uint32
-	Data2 uint16
-	Data3 uint16
-	Data4 [8]byte
-}
-
-var WSAID_CONNECTEX = GUID{
-	0x25a207b9,
-	0xddf3,
-	0x4660,
-	[8]byte{0x8e, 0xe9, 0x76, 0xe5, 0x8c, 0x74, 0x06, 0x3e},
-}
-
-const (
-	FILE_SKIP_COMPLETION_PORT_ON_SUCCESS = 1
-	FILE_SKIP_SET_EVENT_ON_HANDLE        = 2
-)
-
-const (
-	WSAPROTOCOL_LEN    = 255
-	MAX_PROTOCOL_CHAIN = 7
-	BASE_PROTOCOL      = 1
-	LAYERED_PROTOCOL   = 0
-
-	XP1_CONNECTIONLESS           = 0x00000001
-	XP1_GUARANTEED_DELIVERY      = 0x00000002
-	XP1_GUARANTEED_ORDER         = 0x00000004
-	XP1_MESSAGE_ORIENTED         = 0x00000008
-	XP1_PSEUDO_STREAM            = 0x00000010
-	XP1_GRACEFUL_CLOSE           = 0x00000020
-	XP1_EXPEDITED_DATA           = 0x00000040
-	XP1_CONNECT_DATA             = 0x00000080
-	XP1_DISCONNECT_DATA          = 0x00000100
-	XP1_SUPPORT_BROADCAST        = 0x00000200
-	XP1_SUPPORT_MULTIPOINT       = 0x00000400
-	XP1_MULTIPOINT_CONTROL_PLANE = 0x00000800
-	XP1_MULTIPOINT_DATA_PLANE    = 0x00001000
-	XP1_QOS_SUPPORTED            = 0x00002000
-	XP1_UNI_SEND                 = 0x00008000
-	XP1_UNI_RECV                 = 0x00010000
-	XP1_IFS_HANDLES              = 0x00020000
-	XP1_PARTIAL_MESSAGE          = 0x00040000
-	XP1_SAN_SUPPORT_SDP          = 0x00080000
-
-	PFL_MULTIPLE_PROTO_ENTRIES  = 0x00000001
-	PFL_RECOMMENDED_PROTO_ENTRY = 0x00000002
-	PFL_HIDDEN                  = 0x00000004
-	PFL_MATCHES_PROTOCOL_ZERO   = 0x00000008
-	PFL_NETWORKDIRECT_PROVIDER  = 0x00000010
-)
-
-type WSAProtocolInfo struct {
-	ServiceFlags1     uint32
-	ServiceFlags2     uint32
-	ServiceFlags3     uint32
-	ServiceFlags4     uint32
-	ProviderFlags     uint32
-	ProviderId        GUID
-	CatalogEntryId    uint32
-	ProtocolChain     WSAProtocolChain
-	Version           int32
-	AddressFamily     int32
-	MaxSockAddr       int32
-	MinSockAddr       int32
-	SocketType        int32
-	Protocol          int32
-	ProtocolMaxOffset int32
-	NetworkByteOrder  int32
-	SecurityScheme    int32
-	MessageSize       uint32
-	ProviderReserved  uint32
-	ProtocolName      [WSAPROTOCOL_LEN + 1]uint16
-}
-
-type WSAProtocolChain struct {
-	ChainLen     int32
-	ChainEntries [MAX_PROTOCOL_CHAIN]uint32
-}
-
-type TCPKeepalive struct {
-	OnOff    uint32
-	Time     uint32
-	Interval uint32
-}
diff --git a/src/pkg/testing/benchmark.go b/src/pkg/testing/benchmark.go
deleted file mode 100644
index 1fbf5c8..0000000
--- a/src/pkg/testing/benchmark.go
+++ /dev/null
@@ -1,444 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package testing
-
-import (
-	"flag"
-	"fmt"
-	"os"
-	"runtime"
-	"sync"
-	"sync/atomic"
-	"time"
-)
-
-var matchBenchmarks = flag.String("test.bench", "", "regular expression to select benchmarks to run")
-var benchTime = flag.Duration("test.benchtime", 1*time.Second, "approximate run time for each benchmark")
-var benchmarkMemory = flag.Bool("test.benchmem", false, "print memory allocations for benchmarks")
-
-// Global lock to ensure only one benchmark runs at a time.
-var benchmarkLock sync.Mutex
-
-// Used for every benchmark for measuring memory.
-var memStats runtime.MemStats
-
-// An internal type but exported because it is cross-package; part of the implementation
-// of the "go test" command.
-type InternalBenchmark struct {
-	Name string
-	F    func(b *B)
-}
-
-// B is a type passed to Benchmark functions to manage benchmark
-// timing and to specify the number of iterations to run.
-type B struct {
-	common
-	N                int
-	previousN        int           // number of iterations in the previous run
-	previousDuration time.Duration // total duration of the previous run
-	benchmark        InternalBenchmark
-	bytes            int64
-	timerOn          bool
-	showAllocResult  bool
-	result           BenchmarkResult
-	parallelism      int // RunParallel creates parallelism*GOMAXPROCS goroutines
-	// The initial states of memStats.Mallocs and memStats.TotalAlloc.
-	startAllocs uint64
-	startBytes  uint64
-	// The net total of this test after being run.
-	netAllocs uint64
-	netBytes  uint64
-}
-
-// StartTimer starts timing a test.  This function is called automatically
-// before a benchmark starts, but it can also used to resume timing after
-// a call to StopTimer.
-func (b *B) StartTimer() {
-	if !b.timerOn {
-		runtime.ReadMemStats(&memStats)
-		b.startAllocs = memStats.Mallocs
-		b.startBytes = memStats.TotalAlloc
-		b.start = time.Now()
-		b.timerOn = true
-	}
-}
-
-// StopTimer stops timing a test.  This can be used to pause the timer
-// while performing complex initialization that you don't
-// want to measure.
-func (b *B) StopTimer() {
-	if b.timerOn {
-		b.duration += time.Now().Sub(b.start)
-		runtime.ReadMemStats(&memStats)
-		b.netAllocs += memStats.Mallocs - b.startAllocs
-		b.netBytes += memStats.TotalAlloc - b.startBytes
-		b.timerOn = false
-	}
-}
-
-// ResetTimer zeros the elapsed benchmark time and memory allocation counters.
-// It does not affect whether the timer is running.
-func (b *B) ResetTimer() {
-	if b.timerOn {
-		runtime.ReadMemStats(&memStats)
-		b.startAllocs = memStats.Mallocs
-		b.startBytes = memStats.TotalAlloc
-		b.start = time.Now()
-	}
-	b.duration = 0
-	b.netAllocs = 0
-	b.netBytes = 0
-}
-
-// SetBytes records the number of bytes processed in a single operation.
-// If this is called, the benchmark will report ns/op and MB/s.
-func (b *B) SetBytes(n int64) { b.bytes = n }
-
-// ReportAllocs enables malloc statistics for this benchmark.
-// It is equivalent to setting -test.benchmem, but it only affects the
-// benchmark function that calls ReportAllocs.
-func (b *B) ReportAllocs() {
-	b.showAllocResult = true
-}
-
-func (b *B) nsPerOp() int64 {
-	if b.N <= 0 {
-		return 0
-	}
-	return b.duration.Nanoseconds() / int64(b.N)
-}
-
-// runN runs a single benchmark for the specified number of iterations.
-func (b *B) runN(n int) {
-	benchmarkLock.Lock()
-	defer benchmarkLock.Unlock()
-	// Try to get a comparable environment for each run
-	// by clearing garbage from previous runs.
-	runtime.GC()
-	b.N = n
-	b.parallelism = 1
-	b.ResetTimer()
-	b.StartTimer()
-	b.benchmark.F(b)
-	b.StopTimer()
-	b.previousN = n
-	b.previousDuration = b.duration
-}
-
-func min(x, y int) int {
-	if x > y {
-		return y
-	}
-	return x
-}
-
-func max(x, y int) int {
-	if x < y {
-		return y
-	}
-	return x
-}
-
-// roundDown10 rounds a number down to the nearest power of 10.
-func roundDown10(n int) int {
-	var tens = 0
-	// tens = floor(log_10(n))
-	for n >= 10 {
-		n = n / 10
-		tens++
-	}
-	// result = 10^tens
-	result := 1
-	for i := 0; i < tens; i++ {
-		result *= 10
-	}
-	return result
-}
-
-// roundUp rounds x up to a number of the form [1eX, 2eX, 5eX].
-func roundUp(n int) int {
-	base := roundDown10(n)
-	switch {
-	case n <= base:
-		return base
-	case n <= (2 * base):
-		return 2 * base
-	case n <= (5 * base):
-		return 5 * base
-	default:
-		return 10 * base
-	}
-}
-
-// run times the benchmark function in a separate goroutine.
-func (b *B) run() BenchmarkResult {
-	go b.launch()
-	<-b.signal
-	return b.result
-}
-
-// launch launches the benchmark function.  It gradually increases the number
-// of benchmark iterations until the benchmark runs for a second in order
-// to get a reasonable measurement.  It prints timing information in this form
-//		testing.BenchmarkHello	100000		19 ns/op
-// launch is run by the fun function as a separate goroutine.
-func (b *B) launch() {
-	// Run the benchmark for a single iteration in case it's expensive.
-	n := 1
-
-	// Signal that we're done whether we return normally
-	// or by FailNow's runtime.Goexit.
-	defer func() {
-		b.signal <- b
-	}()
-
-	b.runN(n)
-	// Run the benchmark for at least the specified amount of time.
-	d := *benchTime
-	for !b.failed && b.duration < d && n < 1e9 {
-		last := n
-		// Predict iterations/sec.
-		if b.nsPerOp() == 0 {
-			n = 1e9
-		} else {
-			n = int(d.Nanoseconds() / b.nsPerOp())
-		}
-		// Run more iterations than we think we'll need for a second (1.5x).
-		// Don't grow too fast in case we had timing errors previously.
-		// Be sure to run at least one more than last time.
-		n = max(min(n+n/2, 100*last), last+1)
-		// Round up to something easy to read.
-		n = roundUp(n)
-		b.runN(n)
-	}
-	b.result = BenchmarkResult{b.N, b.duration, b.bytes, b.netAllocs, b.netBytes}
-}
-
-// The results of a benchmark run.
-type BenchmarkResult struct {
-	N         int           // The number of iterations.
-	T         time.Duration // The total time taken.
-	Bytes     int64         // Bytes processed in one iteration.
-	MemAllocs uint64        // The total number of memory allocations.
-	MemBytes  uint64        // The total number of bytes allocated.
-}
-
-func (r BenchmarkResult) NsPerOp() int64 {
-	if r.N <= 0 {
-		return 0
-	}
-	return r.T.Nanoseconds() / int64(r.N)
-}
-
-func (r BenchmarkResult) mbPerSec() float64 {
-	if r.Bytes <= 0 || r.T <= 0 || r.N <= 0 {
-		return 0
-	}
-	return (float64(r.Bytes) * float64(r.N) / 1e6) / r.T.Seconds()
-}
-
-func (r BenchmarkResult) AllocsPerOp() int64 {
-	if r.N <= 0 {
-		return 0
-	}
-	return int64(r.MemAllocs) / int64(r.N)
-}
-
-func (r BenchmarkResult) AllocedBytesPerOp() int64 {
-	if r.N <= 0 {
-		return 0
-	}
-	return int64(r.MemBytes) / int64(r.N)
-}
-
-func (r BenchmarkResult) String() string {
-	mbs := r.mbPerSec()
-	mb := ""
-	if mbs != 0 {
-		mb = fmt.Sprintf("\t%7.2f MB/s", mbs)
-	}
-	nsop := r.NsPerOp()
-	ns := fmt.Sprintf("%10d ns/op", nsop)
-	if r.N > 0 && nsop < 100 {
-		// The format specifiers here make sure that
-		// the ones digits line up for all three possible formats.
-		if nsop < 10 {
-			ns = fmt.Sprintf("%13.2f ns/op", float64(r.T.Nanoseconds())/float64(r.N))
-		} else {
-			ns = fmt.Sprintf("%12.1f ns/op", float64(r.T.Nanoseconds())/float64(r.N))
-		}
-	}
-	return fmt.Sprintf("%8d\t%s%s", r.N, ns, mb)
-}
-
-func (r BenchmarkResult) MemString() string {
-	return fmt.Sprintf("%8d B/op\t%8d allocs/op",
-		r.AllocedBytesPerOp(), r.AllocsPerOp())
-}
-
-// An internal function but exported because it is cross-package; part of the implementation
-// of the "go test" command.
-func RunBenchmarks(matchString func(pat, str string) (bool, error), benchmarks []InternalBenchmark) {
-	// If no flag was specified, don't run benchmarks.
-	if len(*matchBenchmarks) == 0 {
-		return
-	}
-	for _, Benchmark := range benchmarks {
-		matched, err := matchString(*matchBenchmarks, Benchmark.Name)
-		if err != nil {
-			fmt.Fprintf(os.Stderr, "testing: invalid regexp for -test.bench: %s\n", err)
-			os.Exit(1)
-		}
-		if !matched {
-			continue
-		}
-		for _, procs := range cpuList {
-			runtime.GOMAXPROCS(procs)
-			b := &B{
-				common: common{
-					signal: make(chan interface{}),
-				},
-				benchmark: Benchmark,
-			}
-			benchName := Benchmark.Name
-			if procs != 1 {
-				benchName = fmt.Sprintf("%s-%d", Benchmark.Name, procs)
-			}
-			fmt.Printf("%s\t", benchName)
-			r := b.run()
-			if b.failed {
-				// The output could be very long here, but probably isn't.
-				// We print it all, regardless, because we don't want to trim the reason
-				// the benchmark failed.
-				fmt.Printf("--- FAIL: %s\n%s", benchName, b.output)
-				continue
-			}
-			results := r.String()
-			if *benchmarkMemory || b.showAllocResult {
-				results += "\t" + r.MemString()
-			}
-			fmt.Println(results)
-			// Unlike with tests, we ignore the -chatty flag and always print output for
-			// benchmarks since the output generation time will skew the results.
-			if len(b.output) > 0 {
-				b.trimOutput()
-				fmt.Printf("--- BENCH: %s\n%s", benchName, b.output)
-			}
-			if p := runtime.GOMAXPROCS(-1); p != procs {
-				fmt.Fprintf(os.Stderr, "testing: %s left GOMAXPROCS set to %d\n", benchName, p)
-			}
-		}
-	}
-}
-
-// trimOutput shortens the output from a benchmark, which can be very long.
-func (b *B) trimOutput() {
-	// The output is likely to appear multiple times because the benchmark
-	// is run multiple times, but at least it will be seen. This is not a big deal
-	// because benchmarks rarely print, but just in case, we trim it if it's too long.
-	const maxNewlines = 10
-	for nlCount, j := 0, 0; j < len(b.output); j++ {
-		if b.output[j] == '\n' {
-			nlCount++
-			if nlCount >= maxNewlines {
-				b.output = append(b.output[:j], "\n\t... [output truncated]\n"...)
-				break
-			}
-		}
-	}
-}
-
-// A PB is used by RunParallel for running parallel benchmarks.
-type PB struct {
-	globalN *uint64 // shared between all worker goroutines iteration counter
-	grain   uint64  // acquire that many iterations from globalN at once
-	cache   uint64  // local cache of acquired iterations
-	bN      uint64  // total number of iterations to execute (b.N)
-}
-
-// Next reports whether there are more iterations to execute.
-func (pb *PB) Next() bool {
-	if pb.cache == 0 {
-		n := atomic.AddUint64(pb.globalN, pb.grain)
-		if n <= pb.bN {
-			pb.cache = pb.grain
-		} else if n < pb.bN+pb.grain {
-			pb.cache = pb.bN + pb.grain - n
-		} else {
-			return false
-		}
-	}
-	pb.cache--
-	return true
-}
-
-// RunParallel runs a benchmark in parallel.
-// It creates multiple goroutines and distributes b.N iterations among them.
-// The number of goroutines defaults to GOMAXPROCS. To increase parallelism for
-// non-CPU-bound benchmarks, call SetParallelism before RunParallel.
-// RunParallel is usually used with the go test -cpu flag.
-//
-// The body function will be run in each goroutine. It should set up any
-// goroutine-local state and then iterate until pb.Next returns false.
-// It should not use the StartTimer, StopTimer, or ResetTimer functions,
-// because they have global effect.
-func (b *B) RunParallel(body func(*PB)) {
-	// Calculate grain size as number of iterations that take ~100µs.
-	// 100µs is enough to amortize the overhead and provide sufficient
-	// dynamic load balancing.
-	grain := uint64(0)
-	if b.previousN > 0 && b.previousDuration > 0 {
-		grain = 1e5 * uint64(b.previousN) / uint64(b.previousDuration)
-	}
-	if grain < 1 {
-		grain = 1
-	}
-	// We expect the inner loop and function call to take at least 10ns,
-	// so do not do more than 100µs/10ns=1e4 iterations.
-	if grain > 1e4 {
-		grain = 1e4
-	}
-
-	n := uint64(0)
-	numProcs := b.parallelism * runtime.GOMAXPROCS(0)
-	var wg sync.WaitGroup
-	wg.Add(numProcs)
-	for p := 0; p < numProcs; p++ {
-		go func() {
-			defer wg.Done()
-			pb := &PB{
-				globalN: &n,
-				grain:   grain,
-				bN:      uint64(b.N),
-			}
-			body(pb)
-		}()
-	}
-	wg.Wait()
-	if n <= uint64(b.N) && !b.Failed() {
-		b.Fatal("RunParallel: body exited without pb.Next() == false")
-	}
-}
-
-// SetParallelism sets the number of goroutines used by RunParallel to p*GOMAXPROCS.
-// There is usually no need to call SetParallelism for CPU-bound benchmarks.
-// If p is less than 1, this call will have no effect.
-func (b *B) SetParallelism(p int) {
-	if p >= 1 {
-		b.parallelism = p
-	}
-}
-
-// Benchmark benchmarks a single function. Useful for creating
-// custom benchmarks that do not use the "go test" command.
-func Benchmark(f func(b *B)) BenchmarkResult {
-	b := &B{
-		common: common{
-			signal: make(chan interface{}),
-		},
-		benchmark: InternalBenchmark{"", f},
-	}
-	return b.run()
-}
diff --git a/src/pkg/testing/benchmark_test.go b/src/pkg/testing/benchmark_test.go
deleted file mode 100644
index f7ea64e..0000000
--- a/src/pkg/testing/benchmark_test.go
+++ /dev/null
@@ -1,111 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package testing_test
-
-import (
-	"bytes"
-	"runtime"
-	"sync/atomic"
-	"testing"
-	"text/template"
-)
-
-var roundDownTests = []struct {
-	v, expected int
-}{
-	{1, 1},
-	{9, 1},
-	{10, 10},
-	{11, 10},
-	{100, 100},
-	{101, 100},
-	{999, 100},
-	{1000, 1000},
-	{1001, 1000},
-}
-
-func TestRoundDown10(t *testing.T) {
-	for _, tt := range roundDownTests {
-		actual := testing.RoundDown10(tt.v)
-		if tt.expected != actual {
-			t.Errorf("roundDown10(%d): expected %d, actual %d", tt.v, tt.expected, actual)
-		}
-	}
-}
-
-var roundUpTests = []struct {
-	v, expected int
-}{
-	{0, 1},
-	{1, 1},
-	{2, 2},
-	{5, 5},
-	{9, 10},
-	{999, 1000},
-	{1000, 1000},
-	{1400, 2000},
-	{1700, 2000},
-	{4999, 5000},
-	{5000, 5000},
-	{5001, 10000},
-}
-
-func TestRoundUp(t *testing.T) {
-	for _, tt := range roundUpTests {
-		actual := testing.RoundUp(tt.v)
-		if tt.expected != actual {
-			t.Errorf("roundUp(%d): expected %d, actual %d", tt.v, tt.expected, actual)
-		}
-	}
-}
-
-func TestRunParallel(t *testing.T) {
-	testing.Benchmark(func(b *testing.B) {
-		procs := uint32(0)
-		iters := uint64(0)
-		b.SetParallelism(3)
-		b.RunParallel(func(pb *testing.PB) {
-			atomic.AddUint32(&procs, 1)
-			for pb.Next() {
-				atomic.AddUint64(&iters, 1)
-			}
-		})
-		if want := uint32(3 * runtime.GOMAXPROCS(0)); procs != want {
-			t.Errorf("got %v procs, want %v", procs, want)
-		}
-		if iters != uint64(b.N) {
-			t.Errorf("got %v iters, want %v", iters, b.N)
-		}
-	})
-}
-
-func TestRunParallelFail(t *testing.T) {
-	testing.Benchmark(func(b *testing.B) {
-		b.RunParallel(func(pb *testing.PB) {
-			// The function must be able to log/abort
-			// w/o crashing/deadlocking the whole benchmark.
-			b.Log("log")
-			b.Error("error")
-		})
-	})
-}
-
-func ExampleB_RunParallel() {
-	// Parallel benchmark for text/template.Template.Execute on a single object.
-	testing.Benchmark(func(b *testing.B) {
-		templ := template.Must(template.New("test").Parse("Hello, {{.}}!"))
-		// RunParallel will create GOMAXPROCS goroutines
-		// and distribute work among them.
-		b.RunParallel(func(pb *testing.PB) {
-			// Each goroutine has its own bytes.Buffer.
-			var buf bytes.Buffer
-			for pb.Next() {
-				// The loop body is executed b.N times total across all goroutines.
-				buf.Reset()
-				templ.Execute(&buf, "World")
-			}
-		})
-	})
-}
diff --git a/src/pkg/testing/cover.go b/src/pkg/testing/cover.go
deleted file mode 100644
index dd29364..0000000
--- a/src/pkg/testing/cover.go
+++ /dev/null
@@ -1,86 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Support for test coverage.
-
-package testing
-
-import (
-	"fmt"
-	"os"
-)
-
-// CoverBlock records the coverage data for a single basic block.
-// NOTE: This struct is internal to the testing infrastructure and may change.
-// It is not covered (yet) by the Go 1 compatibility guidelines.
-type CoverBlock struct {
-	Line0 uint32
-	Col0  uint16
-	Line1 uint32
-	Col1  uint16
-	Stmts uint16
-}
-
-var cover Cover
-
-// Cover records information about test coverage checking.
-// NOTE: This struct is internal to the testing infrastructure and may change.
-// It is not covered (yet) by the Go 1 compatibility guidelines.
-type Cover struct {
-	Mode            string
-	Counters        map[string][]uint32
-	Blocks          map[string][]CoverBlock
-	CoveredPackages string
-}
-
-// RegisterCover records the coverage data accumulators for the tests.
-// NOTE: This function is internal to the testing infrastructure and may change.
-// It is not covered (yet) by the Go 1 compatibility guidelines.
-func RegisterCover(c Cover) {
-	cover = c
-}
-
-// mustBeNil checks the error and, if present, reports it and exits.
-func mustBeNil(err error) {
-	if err != nil {
-		fmt.Fprintf(os.Stderr, "testing: %s\n", err)
-		os.Exit(2)
-	}
-}
-
-// coverReport reports the coverage percentage and writes a coverage profile if requested.
-func coverReport() {
-	var f *os.File
-	var err error
-	if *coverProfile != "" {
-		f, err = os.Create(toOutputDir(*coverProfile))
-		mustBeNil(err)
-		fmt.Fprintf(f, "mode: %s\n", cover.Mode)
-		defer func() { mustBeNil(f.Close()) }()
-	}
-
-	var active, total int64
-	for name, counts := range cover.Counters {
-		blocks := cover.Blocks[name]
-		for i, count := range counts {
-			stmts := int64(blocks[i].Stmts)
-			total += stmts
-			if count > 0 {
-				active += stmts
-			}
-			if f != nil {
-				_, err := fmt.Fprintf(f, "%s:%d.%d,%d.%d %d %d\n", name,
-					blocks[i].Line0, blocks[i].Col0,
-					blocks[i].Line1, blocks[i].Col1,
-					stmts,
-					count)
-				mustBeNil(err)
-			}
-		}
-	}
-	if total == 0 {
-		total = 1
-	}
-	fmt.Printf("coverage: %.1f%% of statements%s\n", 100*float64(active)/float64(total), cover.CoveredPackages)
-}
diff --git a/src/pkg/testing/example.go b/src/pkg/testing/example.go
deleted file mode 100644
index 828c2d3..0000000
--- a/src/pkg/testing/example.go
+++ /dev/null
@@ -1,100 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package testing
-
-import (
-	"bytes"
-	"fmt"
-	"io"
-	"os"
-	"strings"
-	"time"
-)
-
-type InternalExample struct {
-	Name   string
-	F      func()
-	Output string
-}
-
-func RunExamples(matchString func(pat, str string) (bool, error), examples []InternalExample) (ok bool) {
-	ok = true
-
-	var eg InternalExample
-
-	for _, eg = range examples {
-		matched, err := matchString(*match, eg.Name)
-		if err != nil {
-			fmt.Fprintf(os.Stderr, "testing: invalid regexp for -test.run: %s\n", err)
-			os.Exit(1)
-		}
-		if !matched {
-			continue
-		}
-		if !runExample(eg) {
-			ok = false
-		}
-	}
-
-	return
-}
-
-func runExample(eg InternalExample) (ok bool) {
-	if *chatty {
-		fmt.Printf("=== RUN: %s\n", eg.Name)
-	}
-
-	// Capture stdout.
-	stdout := os.Stdout
-	r, w, err := os.Pipe()
-	if err != nil {
-		fmt.Fprintln(os.Stderr, err)
-		os.Exit(1)
-	}
-	os.Stdout = w
-	outC := make(chan string)
-	go func() {
-		buf := new(bytes.Buffer)
-		_, err := io.Copy(buf, r)
-		r.Close()
-		if err != nil {
-			fmt.Fprintf(os.Stderr, "testing: copying pipe: %v\n", err)
-			os.Exit(1)
-		}
-		outC <- buf.String()
-	}()
-
-	start := time.Now()
-	ok = true
-
-	// Clean up in a deferred call so we can recover if the example panics.
-	defer func() {
-		d := time.Now().Sub(start)
-
-		// Close pipe, restore stdout, get output.
-		w.Close()
-		os.Stdout = stdout
-		out := <-outC
-
-		var fail string
-		err := recover()
-		if g, e := strings.TrimSpace(out), strings.TrimSpace(eg.Output); g != e && err == nil {
-			fail = fmt.Sprintf("got:\n%s\nwant:\n%s\n", g, e)
-		}
-		if fail != "" || err != nil {
-			fmt.Printf("--- FAIL: %s (%v)\n%s", eg.Name, d, fail)
-			ok = false
-		} else if *chatty {
-			fmt.Printf("--- PASS: %s (%v)\n", eg.Name, d)
-		}
-		if err != nil {
-			panic(err)
-		}
-	}()
-
-	// Run example.
-	eg.F()
-	return
-}
diff --git a/src/pkg/testing/quick/quick.go b/src/pkg/testing/quick/quick.go
deleted file mode 100644
index bc79cc3..0000000
--- a/src/pkg/testing/quick/quick.go
+++ /dev/null
@@ -1,358 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package quick implements utility functions to help with black box testing.
-package quick
-
-import (
-	"flag"
-	"fmt"
-	"math"
-	"math/rand"
-	"reflect"
-	"strings"
-)
-
-var defaultMaxCount *int = flag.Int("quickchecks", 100, "The default number of iterations for each check")
-
-// A Generator can generate random values of its own type.
-type Generator interface {
-	// Generate returns a random instance of the type on which it is a
-	// method using the size as a size hint.
-	Generate(rand *rand.Rand, size int) reflect.Value
-}
-
-// randFloat32 generates a random float taking the full range of a float32.
-func randFloat32(rand *rand.Rand) float32 {
-	f := rand.Float64() * math.MaxFloat32
-	if rand.Int()&1 == 1 {
-		f = -f
-	}
-	return float32(f)
-}
-
-// randFloat64 generates a random float taking the full range of a float64.
-func randFloat64(rand *rand.Rand) float64 {
-	f := rand.Float64() * math.MaxFloat64
-	if rand.Int()&1 == 1 {
-		f = -f
-	}
-	return f
-}
-
-// randInt64 returns a random integer taking half the range of an int64.
-func randInt64(rand *rand.Rand) int64 { return rand.Int63() - 1<<62 }
-
-// complexSize is the maximum length of arbitrary values that contain other
-// values.
-const complexSize = 50
-
-// Value returns an arbitrary value of the given type.
-// If the type implements the Generator interface, that will be used.
-// Note: To create arbitrary values for structs, all the fields must be exported.
-func Value(t reflect.Type, rand *rand.Rand) (value reflect.Value, ok bool) {
-	if m, ok := reflect.Zero(t).Interface().(Generator); ok {
-		return m.Generate(rand, complexSize), true
-	}
-
-	v := reflect.New(t).Elem()
-	switch concrete := t; concrete.Kind() {
-	case reflect.Bool:
-		v.SetBool(rand.Int()&1 == 0)
-	case reflect.Float32:
-		v.SetFloat(float64(randFloat32(rand)))
-	case reflect.Float64:
-		v.SetFloat(randFloat64(rand))
-	case reflect.Complex64:
-		v.SetComplex(complex(float64(randFloat32(rand)), float64(randFloat32(rand))))
-	case reflect.Complex128:
-		v.SetComplex(complex(randFloat64(rand), randFloat64(rand)))
-	case reflect.Int16:
-		v.SetInt(randInt64(rand))
-	case reflect.Int32:
-		v.SetInt(randInt64(rand))
-	case reflect.Int64:
-		v.SetInt(randInt64(rand))
-	case reflect.Int8:
-		v.SetInt(randInt64(rand))
-	case reflect.Int:
-		v.SetInt(randInt64(rand))
-	case reflect.Uint16:
-		v.SetUint(uint64(randInt64(rand)))
-	case reflect.Uint32:
-		v.SetUint(uint64(randInt64(rand)))
-	case reflect.Uint64:
-		v.SetUint(uint64(randInt64(rand)))
-	case reflect.Uint8:
-		v.SetUint(uint64(randInt64(rand)))
-	case reflect.Uint:
-		v.SetUint(uint64(randInt64(rand)))
-	case reflect.Uintptr:
-		v.SetUint(uint64(randInt64(rand)))
-	case reflect.Map:
-		numElems := rand.Intn(complexSize)
-		v.Set(reflect.MakeMap(concrete))
-		for i := 0; i < numElems; i++ {
-			key, ok1 := Value(concrete.Key(), rand)
-			value, ok2 := Value(concrete.Elem(), rand)
-			if !ok1 || !ok2 {
-				return reflect.Value{}, false
-			}
-			v.SetMapIndex(key, value)
-		}
-	case reflect.Ptr:
-		elem, ok := Value(concrete.Elem(), rand)
-		if !ok {
-			return reflect.Value{}, false
-		}
-		v.Set(reflect.New(concrete.Elem()))
-		v.Elem().Set(elem)
-	case reflect.Slice:
-		numElems := rand.Intn(complexSize)
-		v.Set(reflect.MakeSlice(concrete, numElems, numElems))
-		for i := 0; i < numElems; i++ {
-			elem, ok := Value(concrete.Elem(), rand)
-			if !ok {
-				return reflect.Value{}, false
-			}
-			v.Index(i).Set(elem)
-		}
-	case reflect.String:
-		numChars := rand.Intn(complexSize)
-		codePoints := make([]rune, numChars)
-		for i := 0; i < numChars; i++ {
-			codePoints[i] = rune(rand.Intn(0x10ffff))
-		}
-		v.SetString(string(codePoints))
-	case reflect.Struct:
-		for i := 0; i < v.NumField(); i++ {
-			elem, ok := Value(concrete.Field(i).Type, rand)
-			if !ok {
-				return reflect.Value{}, false
-			}
-			v.Field(i).Set(elem)
-		}
-	default:
-		return reflect.Value{}, false
-	}
-
-	return v, true
-}
-
-// A Config structure contains options for running a test.
-type Config struct {
-	// MaxCount sets the maximum number of iterations. If zero,
-	// MaxCountScale is used.
-	MaxCount int
-	// MaxCountScale is a non-negative scale factor applied to the default
-	// maximum. If zero, the default is unchanged.
-	MaxCountScale float64
-	// If non-nil, rand is a source of random numbers. Otherwise a default
-	// pseudo-random source will be used.
-	Rand *rand.Rand
-	// If non-nil, the Values function generates a slice of arbitrary
-	// reflect.Values that are congruent with the arguments to the function
-	// being tested. Otherwise, the top-level Values function is used
-	// to generate them.
-	Values func([]reflect.Value, *rand.Rand)
-}
-
-var defaultConfig Config
-
-// getRand returns the *rand.Rand to use for a given Config.
-func (c *Config) getRand() *rand.Rand {
-	if c.Rand == nil {
-		return rand.New(rand.NewSource(0))
-	}
-	return c.Rand
-}
-
-// getMaxCount returns the maximum number of iterations to run for a given
-// Config.
-func (c *Config) getMaxCount() (maxCount int) {
-	maxCount = c.MaxCount
-	if maxCount == 0 {
-		if c.MaxCountScale != 0 {
-			maxCount = int(c.MaxCountScale * float64(*defaultMaxCount))
-		} else {
-			maxCount = *defaultMaxCount
-		}
-	}
-
-	return
-}
-
-// A SetupError is the result of an error in the way that check is being
-// used, independent of the functions being tested.
-type SetupError string
-
-func (s SetupError) Error() string { return string(s) }
-
-// A CheckError is the result of Check finding an error.
-type CheckError struct {
-	Count int
-	In    []interface{}
-}
-
-func (s *CheckError) Error() string {
-	return fmt.Sprintf("#%d: failed on input %s", s.Count, toString(s.In))
-}
-
-// A CheckEqualError is the result CheckEqual finding an error.
-type CheckEqualError struct {
-	CheckError
-	Out1 []interface{}
-	Out2 []interface{}
-}
-
-func (s *CheckEqualError) Error() string {
-	return fmt.Sprintf("#%d: failed on input %s. Output 1: %s. Output 2: %s", s.Count, toString(s.In), toString(s.Out1), toString(s.Out2))
-}
-
-// Check looks for an input to f, any function that returns bool,
-// such that f returns false.  It calls f repeatedly, with arbitrary
-// values for each argument.  If f returns false on a given input,
-// Check returns that input as a *CheckError.
-// For example:
-//
-// 	func TestOddMultipleOfThree(t *testing.T) {
-// 		f := func(x int) bool {
-// 			y := OddMultipleOfThree(x)
-// 			return y%2 == 1 && y%3 == 0
-// 		}
-// 		if err := quick.Check(f, nil); err != nil {
-// 			t.Error(err)
-// 		}
-// 	}
-func Check(function interface{}, config *Config) (err error) {
-	if config == nil {
-		config = &defaultConfig
-	}
-
-	f, fType, ok := functionAndType(function)
-	if !ok {
-		err = SetupError("argument is not a function")
-		return
-	}
-
-	if fType.NumOut() != 1 {
-		err = SetupError("function returns more than one value.")
-		return
-	}
-	if fType.Out(0).Kind() != reflect.Bool {
-		err = SetupError("function does not return a bool")
-		return
-	}
-
-	arguments := make([]reflect.Value, fType.NumIn())
-	rand := config.getRand()
-	maxCount := config.getMaxCount()
-
-	for i := 0; i < maxCount; i++ {
-		err = arbitraryValues(arguments, fType, config, rand)
-		if err != nil {
-			return
-		}
-
-		if !f.Call(arguments)[0].Bool() {
-			err = &CheckError{i + 1, toInterfaces(arguments)}
-			return
-		}
-	}
-
-	return
-}
-
-// CheckEqual looks for an input on which f and g return different results.
-// It calls f and g repeatedly with arbitrary values for each argument.
-// If f and g return different answers, CheckEqual returns a *CheckEqualError
-// describing the input and the outputs.
-func CheckEqual(f, g interface{}, config *Config) (err error) {
-	if config == nil {
-		config = &defaultConfig
-	}
-
-	x, xType, ok := functionAndType(f)
-	if !ok {
-		err = SetupError("f is not a function")
-		return
-	}
-	y, yType, ok := functionAndType(g)
-	if !ok {
-		err = SetupError("g is not a function")
-		return
-	}
-
-	if xType != yType {
-		err = SetupError("functions have different types")
-		return
-	}
-
-	arguments := make([]reflect.Value, xType.NumIn())
-	rand := config.getRand()
-	maxCount := config.getMaxCount()
-
-	for i := 0; i < maxCount; i++ {
-		err = arbitraryValues(arguments, xType, config, rand)
-		if err != nil {
-			return
-		}
-
-		xOut := toInterfaces(x.Call(arguments))
-		yOut := toInterfaces(y.Call(arguments))
-
-		if !reflect.DeepEqual(xOut, yOut) {
-			err = &CheckEqualError{CheckError{i + 1, toInterfaces(arguments)}, xOut, yOut}
-			return
-		}
-	}
-
-	return
-}
-
-// arbitraryValues writes Values to args such that args contains Values
-// suitable for calling f.
-func arbitraryValues(args []reflect.Value, f reflect.Type, config *Config, rand *rand.Rand) (err error) {
-	if config.Values != nil {
-		config.Values(args, rand)
-		return
-	}
-
-	for j := 0; j < len(args); j++ {
-		var ok bool
-		args[j], ok = Value(f.In(j), rand)
-		if !ok {
-			err = SetupError(fmt.Sprintf("cannot create arbitrary value of type %s for argument %d", f.In(j), j))
-			return
-		}
-	}
-
-	return
-}
-
-func functionAndType(f interface{}) (v reflect.Value, t reflect.Type, ok bool) {
-	v = reflect.ValueOf(f)
-	ok = v.Kind() == reflect.Func
-	if !ok {
-		return
-	}
-	t = v.Type()
-	return
-}
-
-func toInterfaces(values []reflect.Value) []interface{} {
-	ret := make([]interface{}, len(values))
-	for i, v := range values {
-		ret[i] = v.Interface()
-	}
-	return ret
-}
-
-func toString(interfaces []interface{}) string {
-	s := make([]string, len(interfaces))
-	for i, v := range interfaces {
-		s[i] = fmt.Sprintf("%#v", v)
-	}
-	return strings.Join(s, ", ")
-}
diff --git a/src/pkg/testing/testing.go b/src/pkg/testing/testing.go
deleted file mode 100644
index 8078ba7..0000000
--- a/src/pkg/testing/testing.go
+++ /dev/null
@@ -1,657 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package testing provides support for automated testing of Go packages.
-// It is intended to be used in concert with the ``go test'' command, which automates
-// execution of any function of the form
-//     func TestXxx(*testing.T)
-// where Xxx can be any alphanumeric string (but the first letter must not be in
-// [a-z]) and serves to identify the test routine.
-//
-// Within these functions, use the Error, Fail or related methods to signal failure.
-//
-// To write a new test suite, create a file whose name ends _test.go that
-// contains the TestXxx functions as described here. Put the file in the same
-// package as the one being tested. The file will be excluded from regular
-// package builds but will be included when the ``go test'' command is run.
-// For more detail, run ``go help test'' and ``go help testflag''.
-//
-// Tests and benchmarks may be skipped if not applicable with a call to
-// the Skip method of *T and *B:
-//     func TestTimeConsuming(t *testing.T) {
-//         if testing.Short() {
-//             t.Skip("skipping test in short mode.")
-//         }
-//         ...
-//     }
-//
-// Benchmarks
-//
-// Functions of the form
-//     func BenchmarkXxx(*testing.B)
-// are considered benchmarks, and are executed by the "go test" command when
-// its -bench flag is provided. Benchmarks are run sequentially.
-//
-// For a description of the testing flags, see
-// http://golang.org/cmd/go/#hdr-Description_of_testing_flags.
-//
-// A sample benchmark function looks like this:
-//     func BenchmarkHello(b *testing.B) {
-//         for i := 0; i < b.N; i++ {
-//             fmt.Sprintf("hello")
-//         }
-//     }
-//
-// The benchmark function must run the target code b.N times.
-// The benchmark package will vary b.N until the benchmark function lasts
-// long enough to be timed reliably.  The output
-//     BenchmarkHello    10000000    282 ns/op
-// means that the loop ran 10000000 times at a speed of 282 ns per loop.
-//
-// If a benchmark needs some expensive setup before running, the timer
-// may be reset:
-//
-//     func BenchmarkBigLen(b *testing.B) {
-//         big := NewBig()
-//         b.ResetTimer()
-//         for i := 0; i < b.N; i++ {
-//             big.Len()
-//         }
-//     }
-//
-// If a benchmark needs to test performance in a parallel setting, it may use
-// the RunParallel helper function; such benchmarks are intended to be used with
-// the go test -cpu flag:
-//
-//     func BenchmarkTemplateParallel(b *testing.B) {
-//         templ := template.Must(template.New("test").Parse("Hello, {{.}}!"))
-//         b.RunParallel(func(pb *testing.PB) {
-//             var buf bytes.Buffer
-//             for pb.Next() {
-//                 buf.Reset()
-//                 templ.Execute(&buf, "World")
-//             }
-//         })
-//     }
-//
-// Examples
-//
-// The package also runs and verifies example code. Example functions may
-// include a concluding line comment that begins with "Output:" and is compared with
-// the standard output of the function when the tests are run. (The comparison
-// ignores leading and trailing space.) These are examples of an example:
-//
-//     func ExampleHello() {
-//             fmt.Println("hello")
-//             // Output: hello
-//     }
-//
-//     func ExampleSalutations() {
-//             fmt.Println("hello, and")
-//             fmt.Println("goodbye")
-//             // Output:
-//             // hello, and
-//             // goodbye
-//     }
-//
-// Example functions without output comments are compiled but not executed.
-//
-// The naming convention to declare examples for the package, a function F, a type T and
-// method M on type T are:
-//
-//     func Example() { ... }
-//     func ExampleF() { ... }
-//     func ExampleT() { ... }
-//     func ExampleT_M() { ... }
-//
-// Multiple example functions for a package/type/function/method may be provided by
-// appending a distinct suffix to the name. The suffix must start with a
-// lower-case letter.
-//
-//     func Example_suffix() { ... }
-//     func ExampleF_suffix() { ... }
-//     func ExampleT_suffix() { ... }
-//     func ExampleT_M_suffix() { ... }
-//
-// The entire test file is presented as the example when it contains a single
-// example function, at least one other function, type, variable, or constant
-// declaration, and no test or benchmark functions.
-package testing
-
-import (
-	"bytes"
-	"flag"
-	"fmt"
-	"os"
-	"runtime"
-	"runtime/pprof"
-	"strconv"
-	"strings"
-	"sync"
-	"time"
-)
-
-var (
-	// The short flag requests that tests run more quickly, but its functionality
-	// is provided by test writers themselves.  The testing package is just its
-	// home.  The all.bash installation script sets it to make installation more
-	// efficient, but by default the flag is off so a plain "go test" will do a
-	// full test of the package.
-	short = flag.Bool("test.short", false, "run smaller test suite to save time")
-
-	// The directory in which to create profile files and the like. When run from
-	// "go test", the binary always runs in the source directory for the package;
-	// this flag lets "go test" tell the binary to write the files in the directory where
-	// the "go test" command is run.
-	outputDir = flag.String("test.outputdir", "", "directory in which to write profiles")
-
-	// Report as tests are run; default is silent for success.
-	chatty           = flag.Bool("test.v", false, "verbose: print additional output")
-	coverProfile     = flag.String("test.coverprofile", "", "write a coverage profile to the named file after execution")
-	match            = flag.String("test.run", "", "regular expression to select tests and examples to run")
-	memProfile       = flag.String("test.memprofile", "", "write a memory profile to the named file after execution")
-	memProfileRate   = flag.Int("test.memprofilerate", 0, "if >=0, sets runtime.MemProfileRate")
-	cpuProfile       = flag.String("test.cpuprofile", "", "write a cpu profile to the named file during execution")
-	blockProfile     = flag.String("test.blockprofile", "", "write a goroutine blocking profile to the named file after execution")
-	blockProfileRate = flag.Int("test.blockprofilerate", 1, "if >= 0, calls runtime.SetBlockProfileRate()")
-	timeout          = flag.Duration("test.timeout", 0, "if positive, sets an aggregate time limit for all tests")
-	cpuListStr       = flag.String("test.cpu", "", "comma-separated list of number of CPUs to use for each test")
-	parallel         = flag.Int("test.parallel", runtime.GOMAXPROCS(0), "maximum test parallelism")
-
-	haveExamples bool // are there examples?
-
-	cpuList []int
-)
-
-// common holds the elements common between T and B and
-// captures common methods such as Errorf.
-type common struct {
-	mu       sync.RWMutex // guards output and failed
-	output   []byte       // Output generated by test or benchmark.
-	failed   bool         // Test or benchmark has failed.
-	skipped  bool         // Test of benchmark has been skipped.
-	finished bool
-
-	start    time.Time // Time test or benchmark started
-	duration time.Duration
-	self     interface{}      // To be sent on signal channel when done.
-	signal   chan interface{} // Output for serial tests.
-}
-
-// Short reports whether the -test.short flag is set.
-func Short() bool {
-	return *short
-}
-
-// Verbose reports whether the -test.v flag is set.
-func Verbose() bool {
-	return *chatty
-}
-
-// decorate prefixes the string with the file and line of the call site
-// and inserts the final newline if needed and indentation tabs for formatting.
-func decorate(s string) string {
-	_, file, line, ok := runtime.Caller(3) // decorate + log + public function.
-	if ok {
-		// Truncate file name at last file name separator.
-		if index := strings.LastIndex(file, "/"); index >= 0 {
-			file = file[index+1:]
-		} else if index = strings.LastIndex(file, "\\"); index >= 0 {
-			file = file[index+1:]
-		}
-	} else {
-		file = "???"
-		line = 1
-	}
-	buf := new(bytes.Buffer)
-	// Every line is indented at least one tab.
-	buf.WriteByte('\t')
-	fmt.Fprintf(buf, "%s:%d: ", file, line)
-	lines := strings.Split(s, "\n")
-	if l := len(lines); l > 1 && lines[l-1] == "" {
-		lines = lines[:l-1]
-	}
-	for i, line := range lines {
-		if i > 0 {
-			// Second and subsequent lines are indented an extra tab.
-			buf.WriteString("\n\t\t")
-		}
-		buf.WriteString(line)
-	}
-	buf.WriteByte('\n')
-	return buf.String()
-}
-
-// TB is the interface common to T and B.
-type TB interface {
-	Error(args ...interface{})
-	Errorf(format string, args ...interface{})
-	Fail()
-	FailNow()
-	Failed() bool
-	Fatal(args ...interface{})
-	Fatalf(format string, args ...interface{})
-	Log(args ...interface{})
-	Logf(format string, args ...interface{})
-	Skip(args ...interface{})
-	SkipNow()
-	Skipf(format string, args ...interface{})
-	Skipped() bool
-
-	// A private method to prevent users implementing the
-	// interface and so future additions to it will not
-	// violate Go 1 compatibility.
-	private()
-}
-
-var _ TB = (*T)(nil)
-var _ TB = (*B)(nil)
-
-// T is a type passed to Test functions to manage test state and support formatted test logs.
-// Logs are accumulated during execution and dumped to standard error when done.
-type T struct {
-	common
-	name          string    // Name of test.
-	startParallel chan bool // Parallel tests will wait on this.
-}
-
-func (c *common) private() {}
-
-// Fail marks the function as having failed but continues execution.
-func (c *common) Fail() {
-	c.mu.Lock()
-	defer c.mu.Unlock()
-	c.failed = true
-}
-
-// Failed reports whether the function has failed.
-func (c *common) Failed() bool {
-	c.mu.RLock()
-	defer c.mu.RUnlock()
-	return c.failed
-}
-
-// FailNow marks the function as having failed and stops its execution.
-// Execution will continue at the next test or benchmark.
-// FailNow must be called from the goroutine running the
-// test or benchmark function, not from other goroutines
-// created during the test. Calling FailNow does not stop
-// those other goroutines.
-func (c *common) FailNow() {
-	c.Fail()
-
-	// Calling runtime.Goexit will exit the goroutine, which
-	// will run the deferred functions in this goroutine,
-	// which will eventually run the deferred lines in tRunner,
-	// which will signal to the test loop that this test is done.
-	//
-	// A previous version of this code said:
-	//
-	//	c.duration = ...
-	//	c.signal <- c.self
-	//	runtime.Goexit()
-	//
-	// This previous version duplicated code (those lines are in
-	// tRunner no matter what), but worse the goroutine teardown
-	// implicit in runtime.Goexit was not guaranteed to complete
-	// before the test exited.  If a test deferred an important cleanup
-	// function (like removing temporary files), there was no guarantee
-	// it would run on a test failure.  Because we send on c.signal during
-	// a top-of-stack deferred function now, we know that the send
-	// only happens after any other stacked defers have completed.
-	c.finished = true
-	runtime.Goexit()
-}
-
-// log generates the output. It's always at the same stack depth.
-func (c *common) log(s string) {
-	c.mu.Lock()
-	defer c.mu.Unlock()
-	c.output = append(c.output, decorate(s)...)
-}
-
-// Log formats its arguments using default formatting, analogous to Println,
-// and records the text in the error log. The text will be printed only if
-// the test fails or the -test.v flag is set.
-func (c *common) Log(args ...interface{}) { c.log(fmt.Sprintln(args...)) }
-
-// Logf formats its arguments according to the format, analogous to Printf,
-// and records the text in the error log. The text will be printed only if
-// the test fails or the -test.v flag is set.
-func (c *common) Logf(format string, args ...interface{}) { c.log(fmt.Sprintf(format, args...)) }
-
-// Error is equivalent to Log followed by Fail.
-func (c *common) Error(args ...interface{}) {
-	c.log(fmt.Sprintln(args...))
-	c.Fail()
-}
-
-// Errorf is equivalent to Logf followed by Fail.
-func (c *common) Errorf(format string, args ...interface{}) {
-	c.log(fmt.Sprintf(format, args...))
-	c.Fail()
-}
-
-// Fatal is equivalent to Log followed by FailNow.
-func (c *common) Fatal(args ...interface{}) {
-	c.log(fmt.Sprintln(args...))
-	c.FailNow()
-}
-
-// Fatalf is equivalent to Logf followed by FailNow.
-func (c *common) Fatalf(format string, args ...interface{}) {
-	c.log(fmt.Sprintf(format, args...))
-	c.FailNow()
-}
-
-// Skip is equivalent to Log followed by SkipNow.
-func (c *common) Skip(args ...interface{}) {
-	c.log(fmt.Sprintln(args...))
-	c.SkipNow()
-}
-
-// Skipf is equivalent to Logf followed by SkipNow.
-func (c *common) Skipf(format string, args ...interface{}) {
-	c.log(fmt.Sprintf(format, args...))
-	c.SkipNow()
-}
-
-// SkipNow marks the test as having been skipped and stops its execution.
-// Execution will continue at the next test or benchmark. See also FailNow.
-// SkipNow must be called from the goroutine running the test, not from
-// other goroutines created during the test. Calling SkipNow does not stop
-// those other goroutines.
-func (c *common) SkipNow() {
-	c.skip()
-	c.finished = true
-	runtime.Goexit()
-}
-
-func (c *common) skip() {
-	c.mu.Lock()
-	defer c.mu.Unlock()
-	c.skipped = true
-}
-
-// Skipped reports whether the test was skipped.
-func (c *common) Skipped() bool {
-	c.mu.RLock()
-	defer c.mu.RUnlock()
-	return c.skipped
-}
-
-// Parallel signals that this test is to be run in parallel with (and only with)
-// other parallel tests.
-func (t *T) Parallel() {
-	t.signal <- (*T)(nil) // Release main testing loop
-	<-t.startParallel     // Wait for serial tests to finish
-	// Assuming Parallel is the first thing a test does, which is reasonable,
-	// reinitialize the test's start time because it's actually starting now.
-	t.start = time.Now()
-}
-
-// An internal type but exported because it is cross-package; part of the implementation
-// of the "go test" command.
-type InternalTest struct {
-	Name string
-	F    func(*T)
-}
-
-func tRunner(t *T, test *InternalTest) {
-	// When this goroutine is done, either because test.F(t)
-	// returned normally or because a test failure triggered
-	// a call to runtime.Goexit, record the duration and send
-	// a signal saying that the test is done.
-	defer func() {
-		t.duration = time.Now().Sub(t.start)
-		// If the test panicked, print any test output before dying.
-		err := recover()
-		if !t.finished && err == nil {
-			err = fmt.Errorf("test executed panic(nil) or runtime.Goexit")
-		}
-		if err != nil {
-			t.Fail()
-			t.report()
-			panic(err)
-		}
-		t.signal <- t
-	}()
-
-	t.start = time.Now()
-	test.F(t)
-	t.finished = true
-}
-
-// An internal function but exported because it is cross-package; part of the implementation
-// of the "go test" command.
-func Main(matchString func(pat, str string) (bool, error), tests []InternalTest, benchmarks []InternalBenchmark, examples []InternalExample) {
-	flag.Parse()
-	parseCpuList()
-
-	before()
-	startAlarm()
-	haveExamples = len(examples) > 0
-	testOk := RunTests(matchString, tests)
-	exampleOk := RunExamples(matchString, examples)
-	stopAlarm()
-	if !testOk || !exampleOk {
-		fmt.Println("FAIL")
-		after()
-		os.Exit(1)
-	}
-	fmt.Println("PASS")
-	RunBenchmarks(matchString, benchmarks)
-	after()
-}
-
-func (t *T) report() {
-	tstr := fmt.Sprintf("(%.2f seconds)", t.duration.Seconds())
-	format := "--- %s: %s %s\n%s"
-	if t.Failed() {
-		fmt.Printf(format, "FAIL", t.name, tstr, t.output)
-	} else if *chatty {
-		if t.Skipped() {
-			fmt.Printf(format, "SKIP", t.name, tstr, t.output)
-		} else {
-			fmt.Printf(format, "PASS", t.name, tstr, t.output)
-		}
-	}
-}
-
-func RunTests(matchString func(pat, str string) (bool, error), tests []InternalTest) (ok bool) {
-	ok = true
-	if len(tests) == 0 && !haveExamples {
-		fmt.Fprintln(os.Stderr, "testing: warning: no tests to run")
-		return
-	}
-	for _, procs := range cpuList {
-		runtime.GOMAXPROCS(procs)
-		// We build a new channel tree for each run of the loop.
-		// collector merges in one channel all the upstream signals from parallel tests.
-		// If all tests pump to the same channel, a bug can occur where a test
-		// kicks off a goroutine that Fails, yet the test still delivers a completion signal,
-		// which skews the counting.
-		var collector = make(chan interface{})
-
-		numParallel := 0
-		startParallel := make(chan bool)
-
-		for i := 0; i < len(tests); i++ {
-			matched, err := matchString(*match, tests[i].Name)
-			if err != nil {
-				fmt.Fprintf(os.Stderr, "testing: invalid regexp for -test.run: %s\n", err)
-				os.Exit(1)
-			}
-			if !matched {
-				continue
-			}
-			testName := tests[i].Name
-			if procs != 1 {
-				testName = fmt.Sprintf("%s-%d", tests[i].Name, procs)
-			}
-			t := &T{
-				common: common{
-					signal: make(chan interface{}),
-				},
-				name:          testName,
-				startParallel: startParallel,
-			}
-			t.self = t
-			if *chatty {
-				fmt.Printf("=== RUN %s\n", t.name)
-			}
-			go tRunner(t, &tests[i])
-			out := (<-t.signal).(*T)
-			if out == nil { // Parallel run.
-				go func() {
-					collector <- <-t.signal
-				}()
-				numParallel++
-				continue
-			}
-			t.report()
-			ok = ok && !out.Failed()
-		}
-
-		running := 0
-		for numParallel+running > 0 {
-			if running < *parallel && numParallel > 0 {
-				startParallel <- true
-				running++
-				numParallel--
-				continue
-			}
-			t := (<-collector).(*T)
-			t.report()
-			ok = ok && !t.Failed()
-			running--
-		}
-	}
-	return
-}
-
-// before runs before all testing.
-func before() {
-	if *memProfileRate > 0 {
-		runtime.MemProfileRate = *memProfileRate
-	}
-	if *cpuProfile != "" {
-		f, err := os.Create(toOutputDir(*cpuProfile))
-		if err != nil {
-			fmt.Fprintf(os.Stderr, "testing: %s", err)
-			return
-		}
-		if err := pprof.StartCPUProfile(f); err != nil {
-			fmt.Fprintf(os.Stderr, "testing: can't start cpu profile: %s", err)
-			f.Close()
-			return
-		}
-		// Could save f so after can call f.Close; not worth the effort.
-	}
-	if *blockProfile != "" && *blockProfileRate >= 0 {
-		runtime.SetBlockProfileRate(*blockProfileRate)
-	}
-	if *coverProfile != "" && cover.Mode == "" {
-		fmt.Fprintf(os.Stderr, "testing: cannot use -test.coverprofile because test binary was not built with coverage enabled\n")
-		os.Exit(2)
-	}
-}
-
-// after runs after all testing.
-func after() {
-	if *cpuProfile != "" {
-		pprof.StopCPUProfile() // flushes profile to disk
-	}
-	if *memProfile != "" {
-		f, err := os.Create(toOutputDir(*memProfile))
-		if err != nil {
-			fmt.Fprintf(os.Stderr, "testing: %s\n", err)
-			os.Exit(2)
-		}
-		if err = pprof.WriteHeapProfile(f); err != nil {
-			fmt.Fprintf(os.Stderr, "testing: can't write %s: %s\n", *memProfile, err)
-			os.Exit(2)
-		}
-		f.Close()
-	}
-	if *blockProfile != "" && *blockProfileRate >= 0 {
-		f, err := os.Create(toOutputDir(*blockProfile))
-		if err != nil {
-			fmt.Fprintf(os.Stderr, "testing: %s\n", err)
-			os.Exit(2)
-		}
-		if err = pprof.Lookup("block").WriteTo(f, 0); err != nil {
-			fmt.Fprintf(os.Stderr, "testing: can't write %s: %s\n", *blockProfile, err)
-			os.Exit(2)
-		}
-		f.Close()
-	}
-	if cover.Mode != "" {
-		coverReport()
-	}
-}
-
-// toOutputDir returns the file name relocated, if required, to outputDir.
-// Simple implementation to avoid pulling in path/filepath.
-func toOutputDir(path string) string {
-	if *outputDir == "" || path == "" {
-		return path
-	}
-	if runtime.GOOS == "windows" {
-		// On Windows, it's clumsy, but we can be almost always correct
-		// by just looking for a drive letter and a colon.
-		// Absolute paths always have a drive letter (ignoring UNC).
-		// Problem: if path == "C:A" and outputdir == "C:\Go" it's unclear
-		// what to do, but even then path/filepath doesn't help.
-		// TODO: Worth doing better? Probably not, because we're here only
-		// under the management of go test.
-		if len(path) >= 2 {
-			letter, colon := path[0], path[1]
-			if ('a' <= letter && letter <= 'z' || 'A' <= letter && letter <= 'Z') && colon == ':' {
-				// If path starts with a drive letter we're stuck with it regardless.
-				return path
-			}
-		}
-	}
-	if os.IsPathSeparator(path[0]) {
-		return path
-	}
-	return fmt.Sprintf("%s%c%s", *outputDir, os.PathSeparator, path)
-}
-
-var timer *time.Timer
-
-// startAlarm starts an alarm if requested.
-func startAlarm() {
-	if *timeout > 0 {
-		timer = time.AfterFunc(*timeout, func() {
-			panic(fmt.Sprintf("test timed out after %v", *timeout))
-		})
-	}
-}
-
-// stopAlarm turns off the alarm.
-func stopAlarm() {
-	if *timeout > 0 {
-		timer.Stop()
-	}
-}
-
-func parseCpuList() {
-	for _, val := range strings.Split(*cpuListStr, ",") {
-		val = strings.TrimSpace(val)
-		if val == "" {
-			continue
-		}
-		cpu, err := strconv.Atoi(val)
-		if err != nil || cpu <= 0 {
-			fmt.Fprintf(os.Stderr, "testing: invalid value %q for -test.cpu\n", val)
-			os.Exit(1)
-		}
-		cpuList = append(cpuList, cpu)
-	}
-	if cpuList == nil {
-		cpuList = append(cpuList, runtime.GOMAXPROCS(-1))
-	}
-}
diff --git a/src/pkg/text/scanner/scanner.go b/src/pkg/text/scanner/scanner.go
deleted file mode 100644
index db7ca73..0000000
--- a/src/pkg/text/scanner/scanner.go
+++ /dev/null
@@ -1,674 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package scanner provides a scanner and tokenizer for UTF-8-encoded text.
-// It takes an io.Reader providing the source, which then can be tokenized
-// through repeated calls to the Scan function.  For compatibility with
-// existing tools, the NUL character is not allowed. If the first character
-// in the source is a UTF-8 encoded byte order mark (BOM), it is discarded.
-//
-// By default, a Scanner skips white space and Go comments and recognizes all
-// literals as defined by the Go language specification.  It may be
-// customized to recognize only a subset of those literals and to recognize
-// different white space characters.
-//
-// Basic usage pattern:
-//
-//	var s scanner.Scanner
-//	s.Init(src)
-//	tok := s.Scan()
-//	for tok != scanner.EOF {
-//		// do something with tok
-//		tok = s.Scan()
-//	}
-//
-package scanner
-
-import (
-	"bytes"
-	"fmt"
-	"io"
-	"os"
-	"unicode"
-	"unicode/utf8"
-)
-
-// TODO(gri): Consider changing this to use the new (token) Position package.
-
-// A source position is represented by a Position value.
-// A position is valid if Line > 0.
-type Position struct {
-	Filename string // filename, if any
-	Offset   int    // byte offset, starting at 0
-	Line     int    // line number, starting at 1
-	Column   int    // column number, starting at 1 (character count per line)
-}
-
-// IsValid returns true if the position is valid.
-func (pos *Position) IsValid() bool { return pos.Line > 0 }
-
-func (pos Position) String() string {
-	s := pos.Filename
-	if pos.IsValid() {
-		if s != "" {
-			s += ":"
-		}
-		s += fmt.Sprintf("%d:%d", pos.Line, pos.Column)
-	}
-	if s == "" {
-		s = "???"
-	}
-	return s
-}
-
-// Predefined mode bits to control recognition of tokens. For instance,
-// to configure a Scanner such that it only recognizes (Go) identifiers,
-// integers, and skips comments, set the Scanner's Mode field to:
-//
-//	ScanIdents | ScanInts | SkipComments
-//
-const (
-	ScanIdents     = 1 << -Ident
-	ScanInts       = 1 << -Int
-	ScanFloats     = 1 << -Float // includes Ints
-	ScanChars      = 1 << -Char
-	ScanStrings    = 1 << -String
-	ScanRawStrings = 1 << -RawString
-	ScanComments   = 1 << -Comment
-	SkipComments   = 1 << -skipComment // if set with ScanComments, comments become white space
-	GoTokens       = ScanIdents | ScanFloats | ScanChars | ScanStrings | ScanRawStrings | ScanComments | SkipComments
-)
-
-// The result of Scan is one of the following tokens or a Unicode character.
-const (
-	EOF = -(iota + 1)
-	Ident
-	Int
-	Float
-	Char
-	String
-	RawString
-	Comment
-	skipComment
-)
-
-var tokenString = map[rune]string{
-	EOF:       "EOF",
-	Ident:     "Ident",
-	Int:       "Int",
-	Float:     "Float",
-	Char:      "Char",
-	String:    "String",
-	RawString: "RawString",
-	Comment:   "Comment",
-}
-
-// TokenString returns a printable string for a token or Unicode character.
-func TokenString(tok rune) string {
-	if s, found := tokenString[tok]; found {
-		return s
-	}
-	return fmt.Sprintf("%q", string(tok))
-}
-
-// GoWhitespace is the default value for the Scanner's Whitespace field.
-// Its value selects Go's white space characters.
-const GoWhitespace = 1<<'\t' | 1<<'\n' | 1<<'\r' | 1<<' '
-
-const bufLen = 1024 // at least utf8.UTFMax
-
-// A Scanner implements reading of Unicode characters and tokens from an io.Reader.
-type Scanner struct {
-	// Input
-	src io.Reader
-
-	// Source buffer
-	srcBuf [bufLen + 1]byte // +1 for sentinel for common case of s.next()
-	srcPos int              // reading position (srcBuf index)
-	srcEnd int              // source end (srcBuf index)
-
-	// Source position
-	srcBufOffset int // byte offset of srcBuf[0] in source
-	line         int // line count
-	column       int // character count
-	lastLineLen  int // length of last line in characters (for correct column reporting)
-	lastCharLen  int // length of last character in bytes
-
-	// Token text buffer
-	// Typically, token text is stored completely in srcBuf, but in general
-	// the token text's head may be buffered in tokBuf while the token text's
-	// tail is stored in srcBuf.
-	tokBuf bytes.Buffer // token text head that is not in srcBuf anymore
-	tokPos int          // token text tail position (srcBuf index); valid if >= 0
-	tokEnd int          // token text tail end (srcBuf index)
-
-	// One character look-ahead
-	ch rune // character before current srcPos
-
-	// Error is called for each error encountered. If no Error
-	// function is set, the error is reported to os.Stderr.
-	Error func(s *Scanner, msg string)
-
-	// ErrorCount is incremented by one for each error encountered.
-	ErrorCount int
-
-	// The Mode field controls which tokens are recognized. For instance,
-	// to recognize Ints, set the ScanInts bit in Mode. The field may be
-	// changed at any time.
-	Mode uint
-
-	// The Whitespace field controls which characters are recognized
-	// as white space. To recognize a character ch <= ' ' as white space,
-	// set the ch'th bit in Whitespace (the Scanner's behavior is undefined
-	// for values ch > ' '). The field may be changed at any time.
-	Whitespace uint64
-
-	// Start position of most recently scanned token; set by Scan.
-	// Calling Init or Next invalidates the position (Line == 0).
-	// The Filename field is always left untouched by the Scanner.
-	// If an error is reported (via Error) and Position is invalid,
-	// the scanner is not inside a token. Call Pos to obtain an error
-	// position in that case.
-	Position
-}
-
-// Init initializes a Scanner with a new source and returns s.
-// Error is set to nil, ErrorCount is set to 0, Mode is set to GoTokens,
-// and Whitespace is set to GoWhitespace.
-func (s *Scanner) Init(src io.Reader) *Scanner {
-	s.src = src
-
-	// initialize source buffer
-	// (the first call to next() will fill it by calling src.Read)
-	s.srcBuf[0] = utf8.RuneSelf // sentinel
-	s.srcPos = 0
-	s.srcEnd = 0
-
-	// initialize source position
-	s.srcBufOffset = 0
-	s.line = 1
-	s.column = 0
-	s.lastLineLen = 0
-	s.lastCharLen = 0
-
-	// initialize token text buffer
-	// (required for first call to next()).
-	s.tokPos = -1
-
-	// initialize one character look-ahead
-	s.ch = -1 // no char read yet
-
-	// initialize public fields
-	s.Error = nil
-	s.ErrorCount = 0
-	s.Mode = GoTokens
-	s.Whitespace = GoWhitespace
-	s.Line = 0 // invalidate token position
-
-	return s
-}
-
-// next reads and returns the next Unicode character. It is designed such
-// that only a minimal amount of work needs to be done in the common ASCII
-// case (one test to check for both ASCII and end-of-buffer, and one test
-// to check for newlines).
-func (s *Scanner) next() rune {
-	ch, width := rune(s.srcBuf[s.srcPos]), 1
-
-	if ch >= utf8.RuneSelf {
-		// uncommon case: not ASCII or not enough bytes
-		for s.srcPos+utf8.UTFMax > s.srcEnd && !utf8.FullRune(s.srcBuf[s.srcPos:s.srcEnd]) {
-			// not enough bytes: read some more, but first
-			// save away token text if any
-			if s.tokPos >= 0 {
-				s.tokBuf.Write(s.srcBuf[s.tokPos:s.srcPos])
-				s.tokPos = 0
-				// s.tokEnd is set by Scan()
-			}
-			// move unread bytes to beginning of buffer
-			copy(s.srcBuf[0:], s.srcBuf[s.srcPos:s.srcEnd])
-			s.srcBufOffset += s.srcPos
-			// read more bytes
-			// (an io.Reader must return io.EOF when it reaches
-			// the end of what it is reading - simply returning
-			// n == 0 will make this loop retry forever; but the
-			// error is in the reader implementation in that case)
-			i := s.srcEnd - s.srcPos
-			n, err := s.src.Read(s.srcBuf[i:bufLen])
-			s.srcPos = 0
-			s.srcEnd = i + n
-			s.srcBuf[s.srcEnd] = utf8.RuneSelf // sentinel
-			if err != nil {
-				if err != io.EOF {
-					s.error(err.Error())
-				}
-				if s.srcEnd == 0 {
-					if s.lastCharLen > 0 {
-						// previous character was not EOF
-						s.column++
-					}
-					s.lastCharLen = 0
-					return EOF
-				}
-				// If err == EOF, we won't be getting more
-				// bytes; break to avoid infinite loop. If
-				// err is something else, we don't know if
-				// we can get more bytes; thus also break.
-				break
-			}
-		}
-		// at least one byte
-		ch = rune(s.srcBuf[s.srcPos])
-		if ch >= utf8.RuneSelf {
-			// uncommon case: not ASCII
-			ch, width = utf8.DecodeRune(s.srcBuf[s.srcPos:s.srcEnd])
-			if ch == utf8.RuneError && width == 1 {
-				// advance for correct error position
-				s.srcPos += width
-				s.lastCharLen = width
-				s.column++
-				s.error("illegal UTF-8 encoding")
-				return ch
-			}
-		}
-	}
-
-	// advance
-	s.srcPos += width
-	s.lastCharLen = width
-	s.column++
-
-	// special situations
-	switch ch {
-	case 0:
-		// for compatibility with other tools
-		s.error("illegal character NUL")
-	case '\n':
-		s.line++
-		s.lastLineLen = s.column
-		s.column = 0
-	}
-
-	return ch
-}
-
-// Next reads and returns the next Unicode character.
-// It returns EOF at the end of the source. It reports
-// a read error by calling s.Error, if not nil; otherwise
-// it prints an error message to os.Stderr. Next does not
-// update the Scanner's Position field; use Pos() to
-// get the current position.
-func (s *Scanner) Next() rune {
-	s.tokPos = -1 // don't collect token text
-	s.Line = 0    // invalidate token position
-	ch := s.Peek()
-	s.ch = s.next()
-	return ch
-}
-
-// Peek returns the next Unicode character in the source without advancing
-// the scanner. It returns EOF if the scanner's position is at the last
-// character of the source.
-func (s *Scanner) Peek() rune {
-	if s.ch < 0 {
-		// this code is only run for the very first character
-		s.ch = s.next()
-		if s.ch == '\uFEFF' {
-			s.ch = s.next() // ignore BOM
-		}
-	}
-	return s.ch
-}
-
-func (s *Scanner) error(msg string) {
-	s.ErrorCount++
-	if s.Error != nil {
-		s.Error(s, msg)
-		return
-	}
-	pos := s.Position
-	if !pos.IsValid() {
-		pos = s.Pos()
-	}
-	fmt.Fprintf(os.Stderr, "%s: %s\n", pos, msg)
-}
-
-func (s *Scanner) scanIdentifier() rune {
-	ch := s.next() // read character after first '_' or letter
-	for ch == '_' || unicode.IsLetter(ch) || unicode.IsDigit(ch) {
-		ch = s.next()
-	}
-	return ch
-}
-
-func digitVal(ch rune) int {
-	switch {
-	case '0' <= ch && ch <= '9':
-		return int(ch - '0')
-	case 'a' <= ch && ch <= 'f':
-		return int(ch - 'a' + 10)
-	case 'A' <= ch && ch <= 'F':
-		return int(ch - 'A' + 10)
-	}
-	return 16 // larger than any legal digit val
-}
-
-func isDecimal(ch rune) bool { return '0' <= ch && ch <= '9' }
-
-func (s *Scanner) scanMantissa(ch rune) rune {
-	for isDecimal(ch) {
-		ch = s.next()
-	}
-	return ch
-}
-
-func (s *Scanner) scanFraction(ch rune) rune {
-	if ch == '.' {
-		ch = s.scanMantissa(s.next())
-	}
-	return ch
-}
-
-func (s *Scanner) scanExponent(ch rune) rune {
-	if ch == 'e' || ch == 'E' {
-		ch = s.next()
-		if ch == '-' || ch == '+' {
-			ch = s.next()
-		}
-		ch = s.scanMantissa(ch)
-	}
-	return ch
-}
-
-func (s *Scanner) scanNumber(ch rune) (rune, rune) {
-	// isDecimal(ch)
-	if ch == '0' {
-		// int or float
-		ch = s.next()
-		if ch == 'x' || ch == 'X' {
-			// hexadecimal int
-			ch = s.next()
-			hasMantissa := false
-			for digitVal(ch) < 16 {
-				ch = s.next()
-				hasMantissa = true
-			}
-			if !hasMantissa {
-				s.error("illegal hexadecimal number")
-			}
-		} else {
-			// octal int or float
-			has8or9 := false
-			for isDecimal(ch) {
-				if ch > '7' {
-					has8or9 = true
-				}
-				ch = s.next()
-			}
-			if s.Mode&ScanFloats != 0 && (ch == '.' || ch == 'e' || ch == 'E') {
-				// float
-				ch = s.scanFraction(ch)
-				ch = s.scanExponent(ch)
-				return Float, ch
-			}
-			// octal int
-			if has8or9 {
-				s.error("illegal octal number")
-			}
-		}
-		return Int, ch
-	}
-	// decimal int or float
-	ch = s.scanMantissa(ch)
-	if s.Mode&ScanFloats != 0 && (ch == '.' || ch == 'e' || ch == 'E') {
-		// float
-		ch = s.scanFraction(ch)
-		ch = s.scanExponent(ch)
-		return Float, ch
-	}
-	return Int, ch
-}
-
-func (s *Scanner) scanDigits(ch rune, base, n int) rune {
-	for n > 0 && digitVal(ch) < base {
-		ch = s.next()
-		n--
-	}
-	if n > 0 {
-		s.error("illegal char escape")
-	}
-	return ch
-}
-
-func (s *Scanner) scanEscape(quote rune) rune {
-	ch := s.next() // read character after '/'
-	switch ch {
-	case 'a', 'b', 'f', 'n', 'r', 't', 'v', '\\', quote:
-		// nothing to do
-		ch = s.next()
-	case '0', '1', '2', '3', '4', '5', '6', '7':
-		ch = s.scanDigits(ch, 8, 3)
-	case 'x':
-		ch = s.scanDigits(s.next(), 16, 2)
-	case 'u':
-		ch = s.scanDigits(s.next(), 16, 4)
-	case 'U':
-		ch = s.scanDigits(s.next(), 16, 8)
-	default:
-		s.error("illegal char escape")
-	}
-	return ch
-}
-
-func (s *Scanner) scanString(quote rune) (n int) {
-	ch := s.next() // read character after quote
-	for ch != quote {
-		if ch == '\n' || ch < 0 {
-			s.error("literal not terminated")
-			return
-		}
-		if ch == '\\' {
-			ch = s.scanEscape(quote)
-		} else {
-			ch = s.next()
-		}
-		n++
-	}
-	return
-}
-
-func (s *Scanner) scanRawString() {
-	ch := s.next() // read character after '`'
-	for ch != '`' {
-		if ch < 0 {
-			s.error("literal not terminated")
-			return
-		}
-		ch = s.next()
-	}
-}
-
-func (s *Scanner) scanChar() {
-	if s.scanString('\'') != 1 {
-		s.error("illegal char literal")
-	}
-}
-
-func (s *Scanner) scanComment(ch rune) rune {
-	// ch == '/' || ch == '*'
-	if ch == '/' {
-		// line comment
-		ch = s.next() // read character after "//"
-		for ch != '\n' && ch >= 0 {
-			ch = s.next()
-		}
-		return ch
-	}
-
-	// general comment
-	ch = s.next() // read character after "/*"
-	for {
-		if ch < 0 {
-			s.error("comment not terminated")
-			break
-		}
-		ch0 := ch
-		ch = s.next()
-		if ch0 == '*' && ch == '/' {
-			ch = s.next()
-			break
-		}
-	}
-	return ch
-}
-
-// Scan reads the next token or Unicode character from source and returns it.
-// It only recognizes tokens t for which the respective Mode bit (1<<-t) is set.
-// It returns EOF at the end of the source. It reports scanner errors (read and
-// token errors) by calling s.Error, if not nil; otherwise it prints an error
-// message to os.Stderr.
-func (s *Scanner) Scan() rune {
-	ch := s.Peek()
-
-	// reset token text position
-	s.tokPos = -1
-	s.Line = 0
-
-redo:
-	// skip white space
-	for s.Whitespace&(1<<uint(ch)) != 0 {
-		ch = s.next()
-	}
-
-	// start collecting token text
-	s.tokBuf.Reset()
-	s.tokPos = s.srcPos - s.lastCharLen
-
-	// set token position
-	// (this is a slightly optimized version of the code in Pos())
-	s.Offset = s.srcBufOffset + s.tokPos
-	if s.column > 0 {
-		// common case: last character was not a '\n'
-		s.Line = s.line
-		s.Column = s.column
-	} else {
-		// last character was a '\n'
-		// (we cannot be at the beginning of the source
-		// since we have called next() at least once)
-		s.Line = s.line - 1
-		s.Column = s.lastLineLen
-	}
-
-	// determine token value
-	tok := ch
-	switch {
-	case unicode.IsLetter(ch) || ch == '_':
-		if s.Mode&ScanIdents != 0 {
-			tok = Ident
-			ch = s.scanIdentifier()
-		} else {
-			ch = s.next()
-		}
-	case isDecimal(ch):
-		if s.Mode&(ScanInts|ScanFloats) != 0 {
-			tok, ch = s.scanNumber(ch)
-		} else {
-			ch = s.next()
-		}
-	default:
-		switch ch {
-		case '"':
-			if s.Mode&ScanStrings != 0 {
-				s.scanString('"')
-				tok = String
-			}
-			ch = s.next()
-		case '\'':
-			if s.Mode&ScanChars != 0 {
-				s.scanChar()
-				tok = Char
-			}
-			ch = s.next()
-		case '.':
-			ch = s.next()
-			if isDecimal(ch) && s.Mode&ScanFloats != 0 {
-				tok = Float
-				ch = s.scanMantissa(ch)
-				ch = s.scanExponent(ch)
-			}
-		case '/':
-			ch = s.next()
-			if (ch == '/' || ch == '*') && s.Mode&ScanComments != 0 {
-				if s.Mode&SkipComments != 0 {
-					s.tokPos = -1 // don't collect token text
-					ch = s.scanComment(ch)
-					goto redo
-				}
-				ch = s.scanComment(ch)
-				tok = Comment
-			}
-		case '`':
-			if s.Mode&ScanRawStrings != 0 {
-				s.scanRawString()
-				tok = String
-			}
-			ch = s.next()
-		default:
-			ch = s.next()
-		}
-	}
-
-	// end of token text
-	s.tokEnd = s.srcPos - s.lastCharLen
-
-	s.ch = ch
-	return tok
-}
-
-// Pos returns the position of the character immediately after
-// the character or token returned by the last call to Next or Scan.
-func (s *Scanner) Pos() (pos Position) {
-	pos.Filename = s.Filename
-	pos.Offset = s.srcBufOffset + s.srcPos - s.lastCharLen
-	switch {
-	case s.column > 0:
-		// common case: last character was not a '\n'
-		pos.Line = s.line
-		pos.Column = s.column
-	case s.lastLineLen > 0:
-		// last character was a '\n'
-		pos.Line = s.line - 1
-		pos.Column = s.lastLineLen
-	default:
-		// at the beginning of the source
-		pos.Line = 1
-		pos.Column = 1
-	}
-	return
-}
-
-// TokenText returns the string corresponding to the most recently scanned token.
-// Valid after calling Scan().
-func (s *Scanner) TokenText() string {
-	if s.tokPos < 0 {
-		// no token text
-		return ""
-	}
-
-	if s.tokEnd < 0 {
-		// if EOF was reached, s.tokEnd is set to -1 (s.srcPos == 0)
-		s.tokEnd = s.tokPos
-	}
-
-	if s.tokBuf.Len() == 0 {
-		// common case: the entire token text is still in srcBuf
-		return string(s.srcBuf[s.tokPos:s.tokEnd])
-	}
-
-	// part of the token text was saved in tokBuf: save the rest in
-	// tokBuf as well and return its content
-	s.tokBuf.Write(s.srcBuf[s.tokPos:s.tokEnd])
-	s.tokPos = s.tokEnd // ensure idempotency of TokenText() call
-	return s.tokBuf.String()
-}
diff --git a/src/pkg/text/scanner/scanner_test.go b/src/pkg/text/scanner/scanner_test.go
deleted file mode 100644
index 7d3f597..0000000
--- a/src/pkg/text/scanner/scanner_test.go
+++ /dev/null
@@ -1,596 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package scanner
-
-import (
-	"bytes"
-	"fmt"
-	"io"
-	"strings"
-	"testing"
-	"unicode/utf8"
-)
-
-// A StringReader delivers its data one string segment at a time via Read.
-type StringReader struct {
-	data []string
-	step int
-}
-
-func (r *StringReader) Read(p []byte) (n int, err error) {
-	if r.step < len(r.data) {
-		s := r.data[r.step]
-		n = copy(p, s)
-		r.step++
-	} else {
-		err = io.EOF
-	}
-	return
-}
-
-func readRuneSegments(t *testing.T, segments []string) {
-	got := ""
-	want := strings.Join(segments, "")
-	s := new(Scanner).Init(&StringReader{data: segments})
-	for {
-		ch := s.Next()
-		if ch == EOF {
-			break
-		}
-		got += string(ch)
-	}
-	if got != want {
-		t.Errorf("segments=%v got=%s want=%s", segments, got, want)
-	}
-}
-
-var segmentList = [][]string{
-	{},
-	{""},
-	{"日", "本語"},
-	{"\u65e5", "\u672c", "\u8a9e"},
-	{"\U000065e5", " ", "\U0000672c", "\U00008a9e"},
-	{"\xe6", "\x97\xa5\xe6", "\x9c\xac\xe8\xaa\x9e"},
-	{"Hello", ", ", "World", "!"},
-	{"Hello", ", ", "", "World", "!"},
-}
-
-func TestNext(t *testing.T) {
-	for _, s := range segmentList {
-		readRuneSegments(t, s)
-	}
-}
-
-type token struct {
-	tok  rune
-	text string
-}
-
-var f100 = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
-
-var tokenList = []token{
-	{Comment, "// line comments"},
-	{Comment, "//"},
-	{Comment, "////"},
-	{Comment, "// comment"},
-	{Comment, "// /* comment */"},
-	{Comment, "// // comment //"},
-	{Comment, "//" + f100},
-
-	{Comment, "// general comments"},
-	{Comment, "/**/"},
-	{Comment, "/***/"},
-	{Comment, "/* comment */"},
-	{Comment, "/* // comment */"},
-	{Comment, "/* /* comment */"},
-	{Comment, "/*\n comment\n*/"},
-	{Comment, "/*" + f100 + "*/"},
-
-	{Comment, "// identifiers"},
-	{Ident, "a"},
-	{Ident, "a0"},
-	{Ident, "foobar"},
-	{Ident, "abc123"},
-	{Ident, "LGTM"},
-	{Ident, "_"},
-	{Ident, "_abc123"},
-	{Ident, "abc123_"},
-	{Ident, "_abc_123_"},
-	{Ident, "_äöü"},
-	{Ident, "_本"},
-	{Ident, "äöü"},
-	{Ident, "本"},
-	{Ident, "a۰۱۸"},
-	{Ident, "foo६४"},
-	{Ident, "bar9876"},
-	{Ident, f100},
-
-	{Comment, "// decimal ints"},
-	{Int, "0"},
-	{Int, "1"},
-	{Int, "9"},
-	{Int, "42"},
-	{Int, "1234567890"},
-
-	{Comment, "// octal ints"},
-	{Int, "00"},
-	{Int, "01"},
-	{Int, "07"},
-	{Int, "042"},
-	{Int, "01234567"},
-
-	{Comment, "// hexadecimal ints"},
-	{Int, "0x0"},
-	{Int, "0x1"},
-	{Int, "0xf"},
-	{Int, "0x42"},
-	{Int, "0x123456789abcDEF"},
-	{Int, "0x" + f100},
-	{Int, "0X0"},
-	{Int, "0X1"},
-	{Int, "0XF"},
-	{Int, "0X42"},
-	{Int, "0X123456789abcDEF"},
-	{Int, "0X" + f100},
-
-	{Comment, "// floats"},
-	{Float, "0."},
-	{Float, "1."},
-	{Float, "42."},
-	{Float, "01234567890."},
-	{Float, ".0"},
-	{Float, ".1"},
-	{Float, ".42"},
-	{Float, ".0123456789"},
-	{Float, "0.0"},
-	{Float, "1.0"},
-	{Float, "42.0"},
-	{Float, "01234567890.0"},
-	{Float, "0e0"},
-	{Float, "1e0"},
-	{Float, "42e0"},
-	{Float, "01234567890e0"},
-	{Float, "0E0"},
-	{Float, "1E0"},
-	{Float, "42E0"},
-	{Float, "01234567890E0"},
-	{Float, "0e+10"},
-	{Float, "1e-10"},
-	{Float, "42e+10"},
-	{Float, "01234567890e-10"},
-	{Float, "0E+10"},
-	{Float, "1E-10"},
-	{Float, "42E+10"},
-	{Float, "01234567890E-10"},
-
-	{Comment, "// chars"},
-	{Char, `' '`},
-	{Char, `'a'`},
-	{Char, `'本'`},
-	{Char, `'\a'`},
-	{Char, `'\b'`},
-	{Char, `'\f'`},
-	{Char, `'\n'`},
-	{Char, `'\r'`},
-	{Char, `'\t'`},
-	{Char, `'\v'`},
-	{Char, `'\''`},
-	{Char, `'\000'`},
-	{Char, `'\777'`},
-	{Char, `'\x00'`},
-	{Char, `'\xff'`},
-	{Char, `'\u0000'`},
-	{Char, `'\ufA16'`},
-	{Char, `'\U00000000'`},
-	{Char, `'\U0000ffAB'`},
-
-	{Comment, "// strings"},
-	{String, `" "`},
-	{String, `"a"`},
-	{String, `"本"`},
-	{String, `"\a"`},
-	{String, `"\b"`},
-	{String, `"\f"`},
-	{String, `"\n"`},
-	{String, `"\r"`},
-	{String, `"\t"`},
-	{String, `"\v"`},
-	{String, `"\""`},
-	{String, `"\000"`},
-	{String, `"\777"`},
-	{String, `"\x00"`},
-	{String, `"\xff"`},
-	{String, `"\u0000"`},
-	{String, `"\ufA16"`},
-	{String, `"\U00000000"`},
-	{String, `"\U0000ffAB"`},
-	{String, `"` + f100 + `"`},
-
-	{Comment, "// raw strings"},
-	{String, "``"},
-	{String, "`\\`"},
-	{String, "`" + "\n\n/* foobar */\n\n" + "`"},
-	{String, "`" + f100 + "`"},
-
-	{Comment, "// individual characters"},
-	// NUL character is not allowed
-	{'\x01', "\x01"},
-	{' ' - 1, string(' ' - 1)},
-	{'+', "+"},
-	{'/', "/"},
-	{'.', "."},
-	{'~', "~"},
-	{'(', "("},
-}
-
-func makeSource(pattern string) *bytes.Buffer {
-	var buf bytes.Buffer
-	for _, k := range tokenList {
-		fmt.Fprintf(&buf, pattern, k.text)
-	}
-	return &buf
-}
-
-func checkTok(t *testing.T, s *Scanner, line int, got, want rune, text string) {
-	if got != want {
-		t.Fatalf("tok = %s, want %s for %q", TokenString(got), TokenString(want), text)
-	}
-	if s.Line != line {
-		t.Errorf("line = %d, want %d for %q", s.Line, line, text)
-	}
-	stext := s.TokenText()
-	if stext != text {
-		t.Errorf("text = %q, want %q", stext, text)
-	} else {
-		// check idempotency of TokenText() call
-		stext = s.TokenText()
-		if stext != text {
-			t.Errorf("text = %q, want %q (idempotency check)", stext, text)
-		}
-	}
-}
-
-func countNewlines(s string) int {
-	n := 0
-	for _, ch := range s {
-		if ch == '\n' {
-			n++
-		}
-	}
-	return n
-}
-
-func testScan(t *testing.T, mode uint) {
-	s := new(Scanner).Init(makeSource(" \t%s\n"))
-	s.Mode = mode
-	tok := s.Scan()
-	line := 1
-	for _, k := range tokenList {
-		if mode&SkipComments == 0 || k.tok != Comment {
-			checkTok(t, s, line, tok, k.tok, k.text)
-			tok = s.Scan()
-		}
-		line += countNewlines(k.text) + 1 // each token is on a new line
-	}
-	checkTok(t, s, line, tok, EOF, "")
-}
-
-func TestScan(t *testing.T) {
-	testScan(t, GoTokens)
-	testScan(t, GoTokens&^SkipComments)
-}
-
-func TestPosition(t *testing.T) {
-	src := makeSource("\t\t\t\t%s\n")
-	s := new(Scanner).Init(src)
-	s.Mode = GoTokens &^ SkipComments
-	s.Scan()
-	pos := Position{"", 4, 1, 5}
-	for _, k := range tokenList {
-		if s.Offset != pos.Offset {
-			t.Errorf("offset = %d, want %d for %q", s.Offset, pos.Offset, k.text)
-		}
-		if s.Line != pos.Line {
-			t.Errorf("line = %d, want %d for %q", s.Line, pos.Line, k.text)
-		}
-		if s.Column != pos.Column {
-			t.Errorf("column = %d, want %d for %q", s.Column, pos.Column, k.text)
-		}
-		pos.Offset += 4 + len(k.text) + 1     // 4 tabs + token bytes + newline
-		pos.Line += countNewlines(k.text) + 1 // each token is on a new line
-		s.Scan()
-	}
-	// make sure there were no token-internal errors reported by scanner
-	if s.ErrorCount != 0 {
-		t.Errorf("%d errors", s.ErrorCount)
-	}
-}
-
-func TestScanZeroMode(t *testing.T) {
-	src := makeSource("%s\n")
-	str := src.String()
-	s := new(Scanner).Init(src)
-	s.Mode = 0       // don't recognize any token classes
-	s.Whitespace = 0 // don't skip any whitespace
-	tok := s.Scan()
-	for i, ch := range str {
-		if tok != ch {
-			t.Fatalf("%d. tok = %s, want %s", i, TokenString(tok), TokenString(ch))
-		}
-		tok = s.Scan()
-	}
-	if tok != EOF {
-		t.Fatalf("tok = %s, want EOF", TokenString(tok))
-	}
-	if s.ErrorCount != 0 {
-		t.Errorf("%d errors", s.ErrorCount)
-	}
-}
-
-func testScanSelectedMode(t *testing.T, mode uint, class rune) {
-	src := makeSource("%s\n")
-	s := new(Scanner).Init(src)
-	s.Mode = mode
-	tok := s.Scan()
-	for tok != EOF {
-		if tok < 0 && tok != class {
-			t.Fatalf("tok = %s, want %s", TokenString(tok), TokenString(class))
-		}
-		tok = s.Scan()
-	}
-	if s.ErrorCount != 0 {
-		t.Errorf("%d errors", s.ErrorCount)
-	}
-}
-
-func TestScanSelectedMask(t *testing.T) {
-	testScanSelectedMode(t, 0, 0)
-	testScanSelectedMode(t, ScanIdents, Ident)
-	// Don't test ScanInts and ScanNumbers since some parts of
-	// the floats in the source look like (illegal) octal ints
-	// and ScanNumbers may return either Int or Float.
-	testScanSelectedMode(t, ScanChars, Char)
-	testScanSelectedMode(t, ScanStrings, String)
-	testScanSelectedMode(t, SkipComments, 0)
-	testScanSelectedMode(t, ScanComments, Comment)
-}
-
-func TestScanNext(t *testing.T) {
-	const BOM = '\uFEFF'
-	BOMs := string(BOM)
-	s := new(Scanner).Init(strings.NewReader(BOMs + "if a == bcd /* com" + BOMs + "ment */ {\n\ta += c\n}" + BOMs + "// line comment ending in eof"))
-	checkTok(t, s, 1, s.Scan(), Ident, "if") // the first BOM is ignored
-	checkTok(t, s, 1, s.Scan(), Ident, "a")
-	checkTok(t, s, 1, s.Scan(), '=', "=")
-	checkTok(t, s, 0, s.Next(), '=', "")
-	checkTok(t, s, 0, s.Next(), ' ', "")
-	checkTok(t, s, 0, s.Next(), 'b', "")
-	checkTok(t, s, 1, s.Scan(), Ident, "cd")
-	checkTok(t, s, 1, s.Scan(), '{', "{")
-	checkTok(t, s, 2, s.Scan(), Ident, "a")
-	checkTok(t, s, 2, s.Scan(), '+', "+")
-	checkTok(t, s, 0, s.Next(), '=', "")
-	checkTok(t, s, 2, s.Scan(), Ident, "c")
-	checkTok(t, s, 3, s.Scan(), '}', "}")
-	checkTok(t, s, 3, s.Scan(), BOM, BOMs)
-	checkTok(t, s, 3, s.Scan(), -1, "")
-	if s.ErrorCount != 0 {
-		t.Errorf("%d errors", s.ErrorCount)
-	}
-}
-
-func TestScanWhitespace(t *testing.T) {
-	var buf bytes.Buffer
-	var ws uint64
-	// start at 1, NUL character is not allowed
-	for ch := byte(1); ch < ' '; ch++ {
-		buf.WriteByte(ch)
-		ws |= 1 << ch
-	}
-	const orig = 'x'
-	buf.WriteByte(orig)
-
-	s := new(Scanner).Init(&buf)
-	s.Mode = 0
-	s.Whitespace = ws
-	tok := s.Scan()
-	if tok != orig {
-		t.Errorf("tok = %s, want %s", TokenString(tok), TokenString(orig))
-	}
-}
-
-func testError(t *testing.T, src, pos, msg string, tok rune) {
-	s := new(Scanner).Init(strings.NewReader(src))
-	errorCalled := false
-	s.Error = func(s *Scanner, m string) {
-		if !errorCalled {
-			// only look at first error
-			if p := s.Pos().String(); p != pos {
-				t.Errorf("pos = %q, want %q for %q", p, pos, src)
-			}
-			if m != msg {
-				t.Errorf("msg = %q, want %q for %q", m, msg, src)
-			}
-			errorCalled = true
-		}
-	}
-	tk := s.Scan()
-	if tk != tok {
-		t.Errorf("tok = %s, want %s for %q", TokenString(tk), TokenString(tok), src)
-	}
-	if !errorCalled {
-		t.Errorf("error handler not called for %q", src)
-	}
-	if s.ErrorCount == 0 {
-		t.Errorf("count = %d, want > 0 for %q", s.ErrorCount, src)
-	}
-}
-
-func TestError(t *testing.T) {
-	testError(t, "\x00", "1:1", "illegal character NUL", 0)
-	testError(t, "\x80", "1:1", "illegal UTF-8 encoding", utf8.RuneError)
-	testError(t, "\xff", "1:1", "illegal UTF-8 encoding", utf8.RuneError)
-
-	testError(t, "a\x00", "1:2", "illegal character NUL", Ident)
-	testError(t, "ab\x80", "1:3", "illegal UTF-8 encoding", Ident)
-	testError(t, "abc\xff", "1:4", "illegal UTF-8 encoding", Ident)
-
-	testError(t, `"a`+"\x00", "1:3", "illegal character NUL", String)
-	testError(t, `"ab`+"\x80", "1:4", "illegal UTF-8 encoding", String)
-	testError(t, `"abc`+"\xff", "1:5", "illegal UTF-8 encoding", String)
-
-	testError(t, "`a"+"\x00", "1:3", "illegal character NUL", String)
-	testError(t, "`ab"+"\x80", "1:4", "illegal UTF-8 encoding", String)
-	testError(t, "`abc"+"\xff", "1:5", "illegal UTF-8 encoding", String)
-
-	testError(t, `'\"'`, "1:3", "illegal char escape", Char)
-	testError(t, `"\'"`, "1:3", "illegal char escape", String)
-
-	testError(t, `01238`, "1:6", "illegal octal number", Int)
-	testError(t, `01238123`, "1:9", "illegal octal number", Int)
-	testError(t, `0x`, "1:3", "illegal hexadecimal number", Int)
-	testError(t, `0xg`, "1:3", "illegal hexadecimal number", Int)
-	testError(t, `'aa'`, "1:4", "illegal char literal", Char)
-
-	testError(t, `'`, "1:2", "literal not terminated", Char)
-	testError(t, `'`+"\n", "1:2", "literal not terminated", Char)
-	testError(t, `"abc`, "1:5", "literal not terminated", String)
-	testError(t, `"abc`+"\n", "1:5", "literal not terminated", String)
-	testError(t, "`abc\n", "2:1", "literal not terminated", String)
-	testError(t, `/*/`, "1:4", "comment not terminated", EOF)
-}
-
-// An errReader returns (0, err) where err is not io.EOF.
-type errReader struct{}
-
-func (errReader) Read(b []byte) (int, error) {
-	return 0, io.ErrNoProgress // some error that is not io.EOF
-}
-
-func TestIOError(t *testing.T) {
-	s := new(Scanner).Init(errReader{})
-	errorCalled := false
-	s.Error = func(s *Scanner, msg string) {
-		if !errorCalled {
-			if want := io.ErrNoProgress.Error(); msg != want {
-				t.Errorf("msg = %q, want %q", msg, want)
-			}
-			errorCalled = true
-		}
-	}
-	tok := s.Scan()
-	if tok != EOF {
-		t.Errorf("tok = %s, want EOF", TokenString(tok))
-	}
-	if !errorCalled {
-		t.Errorf("error handler not called")
-	}
-}
-
-func checkPos(t *testing.T, got, want Position) {
-	if got.Offset != want.Offset || got.Line != want.Line || got.Column != want.Column {
-		t.Errorf("got offset, line, column = %d, %d, %d; want %d, %d, %d",
-			got.Offset, got.Line, got.Column, want.Offset, want.Line, want.Column)
-	}
-}
-
-func checkNextPos(t *testing.T, s *Scanner, offset, line, column int, char rune) {
-	if ch := s.Next(); ch != char {
-		t.Errorf("ch = %s, want %s", TokenString(ch), TokenString(char))
-	}
-	want := Position{Offset: offset, Line: line, Column: column}
-	checkPos(t, s.Pos(), want)
-}
-
-func checkScanPos(t *testing.T, s *Scanner, offset, line, column int, char rune) {
-	want := Position{Offset: offset, Line: line, Column: column}
-	checkPos(t, s.Pos(), want)
-	if ch := s.Scan(); ch != char {
-		t.Errorf("ch = %s, want %s", TokenString(ch), TokenString(char))
-		if string(ch) != s.TokenText() {
-			t.Errorf("tok = %q, want %q", s.TokenText(), string(ch))
-		}
-	}
-	checkPos(t, s.Position, want)
-}
-
-func TestPos(t *testing.T) {
-	// corner case: empty source
-	s := new(Scanner).Init(strings.NewReader(""))
-	checkPos(t, s.Pos(), Position{Offset: 0, Line: 1, Column: 1})
-	s.Peek() // peek doesn't affect the position
-	checkPos(t, s.Pos(), Position{Offset: 0, Line: 1, Column: 1})
-
-	// corner case: source with only a newline
-	s = new(Scanner).Init(strings.NewReader("\n"))
-	checkPos(t, s.Pos(), Position{Offset: 0, Line: 1, Column: 1})
-	checkNextPos(t, s, 1, 2, 1, '\n')
-	// after EOF position doesn't change
-	for i := 10; i > 0; i-- {
-		checkScanPos(t, s, 1, 2, 1, EOF)
-	}
-	if s.ErrorCount != 0 {
-		t.Errorf("%d errors", s.ErrorCount)
-	}
-
-	// corner case: source with only a single character
-	s = new(Scanner).Init(strings.NewReader("本"))
-	checkPos(t, s.Pos(), Position{Offset: 0, Line: 1, Column: 1})
-	checkNextPos(t, s, 3, 1, 2, '本')
-	// after EOF position doesn't change
-	for i := 10; i > 0; i-- {
-		checkScanPos(t, s, 3, 1, 2, EOF)
-	}
-	if s.ErrorCount != 0 {
-		t.Errorf("%d errors", s.ErrorCount)
-	}
-
-	// positions after calling Next
-	s = new(Scanner).Init(strings.NewReader("  foo६४  \n\n本語\n"))
-	checkNextPos(t, s, 1, 1, 2, ' ')
-	s.Peek() // peek doesn't affect the position
-	checkNextPos(t, s, 2, 1, 3, ' ')
-	checkNextPos(t, s, 3, 1, 4, 'f')
-	checkNextPos(t, s, 4, 1, 5, 'o')
-	checkNextPos(t, s, 5, 1, 6, 'o')
-	checkNextPos(t, s, 8, 1, 7, '६')
-	checkNextPos(t, s, 11, 1, 8, '४')
-	checkNextPos(t, s, 12, 1, 9, ' ')
-	checkNextPos(t, s, 13, 1, 10, ' ')
-	checkNextPos(t, s, 14, 2, 1, '\n')
-	checkNextPos(t, s, 15, 3, 1, '\n')
-	checkNextPos(t, s, 18, 3, 2, '本')
-	checkNextPos(t, s, 21, 3, 3, '語')
-	checkNextPos(t, s, 22, 4, 1, '\n')
-	// after EOF position doesn't change
-	for i := 10; i > 0; i-- {
-		checkScanPos(t, s, 22, 4, 1, EOF)
-	}
-	if s.ErrorCount != 0 {
-		t.Errorf("%d errors", s.ErrorCount)
-	}
-
-	// positions after calling Scan
-	s = new(Scanner).Init(strings.NewReader("abc\n本語\n\nx"))
-	s.Mode = 0
-	s.Whitespace = 0
-	checkScanPos(t, s, 0, 1, 1, 'a')
-	s.Peek() // peek doesn't affect the position
-	checkScanPos(t, s, 1, 1, 2, 'b')
-	checkScanPos(t, s, 2, 1, 3, 'c')
-	checkScanPos(t, s, 3, 1, 4, '\n')
-	checkScanPos(t, s, 4, 2, 1, '本')
-	checkScanPos(t, s, 7, 2, 2, '語')
-	checkScanPos(t, s, 10, 2, 3, '\n')
-	checkScanPos(t, s, 11, 3, 1, '\n')
-	checkScanPos(t, s, 12, 4, 1, 'x')
-	// after EOF position doesn't change
-	for i := 10; i > 0; i-- {
-		checkScanPos(t, s, 13, 4, 2, EOF)
-	}
-	if s.ErrorCount != 0 {
-		t.Errorf("%d errors", s.ErrorCount)
-	}
-}
diff --git a/src/pkg/text/template/doc.go b/src/pkg/text/template/doc.go
deleted file mode 100644
index 7c6efd5..0000000
--- a/src/pkg/text/template/doc.go
+++ /dev/null
@@ -1,405 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-/*
-Package template implements data-driven templates for generating textual output.
-
-To generate HTML output, see package html/template, which has the same interface
-as this package but automatically secures HTML output against certain attacks.
-
-Templates are executed by applying them to a data structure. Annotations in the
-template refer to elements of the data structure (typically a field of a struct
-or a key in a map) to control execution and derive values to be displayed.
-Execution of the template walks the structure and sets the cursor, represented
-by a period '.' and called "dot", to the value at the current location in the
-structure as execution proceeds.
-
-The input text for a template is UTF-8-encoded text in any format.
-"Actions"--data evaluations or control structures--are delimited by
-"{{" and "}}"; all text outside actions is copied to the output unchanged.
-Actions may not span newlines, although comments can.
-
-Once parsed, a template may be executed safely in parallel.
-
-Here is a trivial example that prints "17 items are made of wool".
-
-	type Inventory struct {
-		Material string
-		Count    uint
-	}
-	sweaters := Inventory{"wool", 17}
-	tmpl, err := template.New("test").Parse("{{.Count}} items are made of {{.Material}}")
-	if err != nil { panic(err) }
-	err = tmpl.Execute(os.Stdout, sweaters)
-	if err != nil { panic(err) }
-
-More intricate examples appear below.
-
-Actions
-
-Here is the list of actions. "Arguments" and "pipelines" are evaluations of
-data, defined in detail below.
-
-*/
-//	{{/* a comment */}}
-//		A comment; discarded. May contain newlines.
-//		Comments do not nest and must start and end at the
-//		delimiters, as shown here.
-/*
-
-	{{pipeline}}
-		The default textual representation of the value of the pipeline
-		is copied to the output.
-
-	{{if pipeline}} T1 {{end}}
-		If the value of the pipeline is empty, no output is generated;
-		otherwise, T1 is executed.  The empty values are false, 0, any
-		nil pointer or interface value, and any array, slice, map, or
-		string of length zero.
-		Dot is unaffected.
-
-	{{if pipeline}} T1 {{else}} T0 {{end}}
-		If the value of the pipeline is empty, T0 is executed;
-		otherwise, T1 is executed.  Dot is unaffected.
-
-	{{if pipeline}} T1 {{else if pipeline}} T0 {{end}}
-		To simplify the appearance of if-else chains, the else action
-		of an if may include another if directly; the effect is exactly
-		the same as writing
-			{{if pipeline}} T1 {{else}}{{if pipeline}} T0 {{end}}{{end}}
-
-	{{range pipeline}} T1 {{end}}
-		The value of the pipeline must be an array, slice, map, or channel.
-		If the value of the pipeline has length zero, nothing is output;
-		otherwise, dot is set to the successive elements of the array,
-		slice, or map and T1 is executed. If the value is a map and the
-		keys are of basic type with a defined order ("comparable"), the
-		elements will be visited in sorted key order.
-
-	{{range pipeline}} T1 {{else}} T0 {{end}}
-		The value of the pipeline must be an array, slice, map, or channel.
-		If the value of the pipeline has length zero, dot is unaffected and
-		T0 is executed; otherwise, dot is set to the successive elements
-		of the array, slice, or map and T1 is executed.
-
-	{{template "name"}}
-		The template with the specified name is executed with nil data.
-
-	{{template "name" pipeline}}
-		The template with the specified name is executed with dot set
-		to the value of the pipeline.
-
-	{{with pipeline}} T1 {{end}}
-		If the value of the pipeline is empty, no output is generated;
-		otherwise, dot is set to the value of the pipeline and T1 is
-		executed.
-
-	{{with pipeline}} T1 {{else}} T0 {{end}}
-		If the value of the pipeline is empty, dot is unaffected and T0
-		is executed; otherwise, dot is set to the value of the pipeline
-		and T1 is executed.
-
-Arguments
-
-An argument is a simple value, denoted by one of the following.
-
-	- A boolean, string, character, integer, floating-point, imaginary
-	  or complex constant in Go syntax. These behave like Go's untyped
-	  constants, although raw strings may not span newlines.
-	- The keyword nil, representing an untyped Go nil.
-	- The character '.' (period):
-		.
-	  The result is the value of dot.
-	- A variable name, which is a (possibly empty) alphanumeric string
-	  preceded by a dollar sign, such as
-		$piOver2
-	  or
-		$
-	  The result is the value of the variable.
-	  Variables are described below.
-	- The name of a field of the data, which must be a struct, preceded
-	  by a period, such as
-		.Field
-	  The result is the value of the field. Field invocations may be
-	  chained:
-	    .Field1.Field2
-	  Fields can also be evaluated on variables, including chaining:
-	    $x.Field1.Field2
-	- The name of a key of the data, which must be a map, preceded
-	  by a period, such as
-		.Key
-	  The result is the map element value indexed by the key.
-	  Key invocations may be chained and combined with fields to any
-	  depth:
-	    .Field1.Key1.Field2.Key2
-	  Although the key must be an alphanumeric identifier, unlike with
-	  field names they do not need to start with an upper case letter.
-	  Keys can also be evaluated on variables, including chaining:
-	    $x.key1.key2
-	- The name of a niladic method of the data, preceded by a period,
-	  such as
-		.Method
-	  The result is the value of invoking the method with dot as the
-	  receiver, dot.Method(). Such a method must have one return value (of
-	  any type) or two return values, the second of which is an error.
-	  If it has two and the returned error is non-nil, execution terminates
-	  and an error is returned to the caller as the value of Execute.
-	  Method invocations may be chained and combined with fields and keys
-	  to any depth:
-	    .Field1.Key1.Method1.Field2.Key2.Method2
-	  Methods can also be evaluated on variables, including chaining:
-	    $x.Method1.Field
-	- The name of a niladic function, such as
-		fun
-	  The result is the value of invoking the function, fun(). The return
-	  types and values behave as in methods. Functions and function
-	  names are described below.
-	- A parenthesized instance of one the above, for grouping. The result
-	  may be accessed by a field or map key invocation.
-		print (.F1 arg1) (.F2 arg2)
-		(.StructValuedMethod "arg").Field
-
-Arguments may evaluate to any type; if they are pointers the implementation
-automatically indirects to the base type when required.
-If an evaluation yields a function value, such as a function-valued
-field of a struct, the function is not invoked automatically, but it
-can be used as a truth value for an if action and the like. To invoke
-it, use the call function, defined below.
-
-A pipeline is a possibly chained sequence of "commands". A command is a simple
-value (argument) or a function or method call, possibly with multiple arguments:
-
-	Argument
-		The result is the value of evaluating the argument.
-	.Method [Argument...]
-		The method can be alone or the last element of a chain but,
-		unlike methods in the middle of a chain, it can take arguments.
-		The result is the value of calling the method with the
-		arguments:
-			dot.Method(Argument1, etc.)
-	functionName [Argument...]
-		The result is the value of calling the function associated
-		with the name:
-			function(Argument1, etc.)
-		Functions and function names are described below.
-
-Pipelines
-
-A pipeline may be "chained" by separating a sequence of commands with pipeline
-characters '|'. In a chained pipeline, the result of the each command is
-passed as the last argument of the following command. The output of the final
-command in the pipeline is the value of the pipeline.
-
-The output of a command will be either one value or two values, the second of
-which has type error. If that second value is present and evaluates to
-non-nil, execution terminates and the error is returned to the caller of
-Execute.
-
-Variables
-
-A pipeline inside an action may initialize a variable to capture the result.
-The initialization has syntax
-
-	$variable := pipeline
-
-where $variable is the name of the variable. An action that declares a
-variable produces no output.
-
-If a "range" action initializes a variable, the variable is set to the
-successive elements of the iteration.  Also, a "range" may declare two
-variables, separated by a comma:
-
-	range $index, $element := pipeline
-
-in which case $index and $element are set to the successive values of the
-array/slice index or map key and element, respectively.  Note that if there is
-only one variable, it is assigned the element; this is opposite to the
-convention in Go range clauses.
-
-A variable's scope extends to the "end" action of the control structure ("if",
-"with", or "range") in which it is declared, or to the end of the template if
-there is no such control structure.  A template invocation does not inherit
-variables from the point of its invocation.
-
-When execution begins, $ is set to the data argument passed to Execute, that is,
-to the starting value of dot.
-
-Examples
-
-Here are some example one-line templates demonstrating pipelines and variables.
-All produce the quoted word "output":
-
-	{{"\"output\""}}
-		A string constant.
-	{{`"output"`}}
-		A raw string constant.
-	{{printf "%q" "output"}}
-		A function call.
-	{{"output" | printf "%q"}}
-		A function call whose final argument comes from the previous
-		command.
-	{{printf "%q" (print "out" "put")}}
-		A parenthesized argument.
-	{{"put" | printf "%s%s" "out" | printf "%q"}}
-		A more elaborate call.
-	{{"output" | printf "%s" | printf "%q"}}
-		A longer chain.
-	{{with "output"}}{{printf "%q" .}}{{end}}
-		A with action using dot.
-	{{with $x := "output" | printf "%q"}}{{$x}}{{end}}
-		A with action that creates and uses a variable.
-	{{with $x := "output"}}{{printf "%q" $x}}{{end}}
-		A with action that uses the variable in another action.
-	{{with $x := "output"}}{{$x | printf "%q"}}{{end}}
-		The same, but pipelined.
-
-Functions
-
-During execution functions are found in two function maps: first in the
-template, then in the global function map. By default, no functions are defined
-in the template but the Funcs method can be used to add them.
-
-Predefined global functions are named as follows.
-
-	and
-		Returns the boolean AND of its arguments by returning the
-		first empty argument or the last argument, that is,
-		"and x y" behaves as "if x then y else x". All the
-		arguments are evaluated.
-	call
-		Returns the result of calling the first argument, which
-		must be a function, with the remaining arguments as parameters.
-		Thus "call .X.Y 1 2" is, in Go notation, dot.X.Y(1, 2) where
-		Y is a func-valued field, map entry, or the like.
-		The first argument must be the result of an evaluation
-		that yields a value of function type (as distinct from
-		a predefined function such as print). The function must
-		return either one or two result values, the second of which
-		is of type error. If the arguments don't match the function
-		or the returned error value is non-nil, execution stops.
-	html
-		Returns the escaped HTML equivalent of the textual
-		representation of its arguments.
-	index
-		Returns the result of indexing its first argument by the
-		following arguments. Thus "index x 1 2 3" is, in Go syntax,
-		x[1][2][3]. Each indexed item must be a map, slice, or array.
-	js
-		Returns the escaped JavaScript equivalent of the textual
-		representation of its arguments.
-	len
-		Returns the integer length of its argument.
-	not
-		Returns the boolean negation of its single argument.
-	or
-		Returns the boolean OR of its arguments by returning the
-		first non-empty argument or the last argument, that is,
-		"or x y" behaves as "if x then x else y". All the
-		arguments are evaluated.
-	print
-		An alias for fmt.Sprint
-	printf
-		An alias for fmt.Sprintf
-	println
-		An alias for fmt.Sprintln
-	urlquery
-		Returns the escaped value of the textual representation of
-		its arguments in a form suitable for embedding in a URL query.
-
-The boolean functions take any zero value to be false and a non-zero
-value to be true.
-
-There is also a set of binary comparison operators defined as
-functions:
-
-	eq
-		Returns the boolean truth of arg1 == arg2
-	ne
-		Returns the boolean truth of arg1 != arg2
-	lt
-		Returns the boolean truth of arg1 < arg2
-	le
-		Returns the boolean truth of arg1 <= arg2
-	gt
-		Returns the boolean truth of arg1 > arg2
-	ge
-		Returns the boolean truth of arg1 >= arg2
-
-For simpler multi-way equality tests, eq (only) accepts two or more
-arguments and compares the second and subsequent to the first,
-returning in effect
-
-	arg1==arg2 || arg1==arg3 || arg1==arg4 ...
-
-(Unlike with || in Go, however, eq is a function call and all the
-arguments will be evaluated.)
-
-The comparison functions work on basic types only (or named basic
-types, such as "type Celsius float32"). They implement the Go rules
-for comparison of values, except that size and exact type are
-ignored, so any integer value may be compared with any other integer
-value, any unsigned integer value may be compared with any other
-unsigned integer value, and so on. However, as usual, one may not
-compare an int with a float32 and so on.
-
-Associated templates
-
-Each template is named by a string specified when it is created. Also, each
-template is associated with zero or more other templates that it may invoke by
-name; such associations are transitive and form a name space of templates.
-
-A template may use a template invocation to instantiate another associated
-template; see the explanation of the "template" action above. The name must be
-that of a template associated with the template that contains the invocation.
-
-Nested template definitions
-
-When parsing a template, another template may be defined and associated with the
-template being parsed. Template definitions must appear at the top level of the
-template, much like global variables in a Go program.
-
-The syntax of such definitions is to surround each template declaration with a
-"define" and "end" action.
-
-The define action names the template being created by providing a string
-constant. Here is a simple example:
-
-	`{{define "T1"}}ONE{{end}}
-	{{define "T2"}}TWO{{end}}
-	{{define "T3"}}{{template "T1"}} {{template "T2"}}{{end}}
-	{{template "T3"}}`
-
-This defines two templates, T1 and T2, and a third T3 that invokes the other two
-when it is executed. Finally it invokes T3. If executed this template will
-produce the text
-
-	ONE TWO
-
-By construction, a template may reside in only one association. If it's
-necessary to have a template addressable from multiple associations, the
-template definition must be parsed multiple times to create distinct *Template
-values, or must be copied with the Clone or AddParseTree method.
-
-Parse may be called multiple times to assemble the various associated templates;
-see the ParseFiles and ParseGlob functions and methods for simple ways to parse
-related templates stored in files.
-
-A template may be executed directly or through ExecuteTemplate, which executes
-an associated template identified by name. To invoke our example above, we
-might write,
-
-	err := tmpl.Execute(os.Stdout, "no data needed")
-	if err != nil {
-		log.Fatalf("execution failed: %s", err)
-	}
-
-or to invoke a particular template explicitly by name,
-
-	err := tmpl.ExecuteTemplate(os.Stdout, "T2", "no data needed")
-	if err != nil {
-		log.Fatalf("execution failed: %s", err)
-	}
-
-*/
-package template
diff --git a/src/pkg/text/template/exec.go b/src/pkg/text/template/exec.go
deleted file mode 100644
index 2f32312..0000000
--- a/src/pkg/text/template/exec.go
+++ /dev/null
@@ -1,838 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package template
-
-import (
-	"bytes"
-	"fmt"
-	"io"
-	"reflect"
-	"runtime"
-	"sort"
-	"strings"
-	"text/template/parse"
-)
-
-// state represents the state of an execution. It's not part of the
-// template so that multiple executions of the same template
-// can execute in parallel.
-type state struct {
-	tmpl *Template
-	wr   io.Writer
-	node parse.Node // current node, for errors
-	vars []variable // push-down stack of variable values.
-}
-
-// variable holds the dynamic value of a variable such as $, $x etc.
-type variable struct {
-	name  string
-	value reflect.Value
-}
-
-// push pushes a new variable on the stack.
-func (s *state) push(name string, value reflect.Value) {
-	s.vars = append(s.vars, variable{name, value})
-}
-
-// mark returns the length of the variable stack.
-func (s *state) mark() int {
-	return len(s.vars)
-}
-
-// pop pops the variable stack up to the mark.
-func (s *state) pop(mark int) {
-	s.vars = s.vars[0:mark]
-}
-
-// setVar overwrites the top-nth variable on the stack. Used by range iterations.
-func (s *state) setVar(n int, value reflect.Value) {
-	s.vars[len(s.vars)-n].value = value
-}
-
-// varValue returns the value of the named variable.
-func (s *state) varValue(name string) reflect.Value {
-	for i := s.mark() - 1; i >= 0; i-- {
-		if s.vars[i].name == name {
-			return s.vars[i].value
-		}
-	}
-	s.errorf("undefined variable: %s", name)
-	return zero
-}
-
-var zero reflect.Value
-
-// at marks the state to be on node n, for error reporting.
-func (s *state) at(node parse.Node) {
-	s.node = node
-}
-
-// doublePercent returns the string with %'s replaced by %%, if necessary,
-// so it can be used safely inside a Printf format string.
-func doublePercent(str string) string {
-	if strings.Contains(str, "%") {
-		str = strings.Replace(str, "%", "%%", -1)
-	}
-	return str
-}
-
-// errorf formats the error and terminates processing.
-func (s *state) errorf(format string, args ...interface{}) {
-	name := doublePercent(s.tmpl.Name())
-	if s.node == nil {
-		format = fmt.Sprintf("template: %s: %s", name, format)
-	} else {
-		location, context := s.tmpl.ErrorContext(s.node)
-		format = fmt.Sprintf("template: %s: executing %q at <%s>: %s", location, name, doublePercent(context), format)
-	}
-	panic(fmt.Errorf(format, args...))
-}
-
-// errRecover is the handler that turns panics into returns from the top
-// level of Parse.
-func errRecover(errp *error) {
-	e := recover()
-	if e != nil {
-		switch err := e.(type) {
-		case runtime.Error:
-			panic(e)
-		case error:
-			*errp = err
-		default:
-			panic(e)
-		}
-	}
-}
-
-// ExecuteTemplate applies the template associated with t that has the given name
-// to the specified data object and writes the output to wr.
-// If an error occurs executing the template or writing its output,
-// execution stops, but partial results may already have been written to
-// the output writer.
-// A template may be executed safely in parallel.
-func (t *Template) ExecuteTemplate(wr io.Writer, name string, data interface{}) error {
-	tmpl := t.tmpl[name]
-	if tmpl == nil {
-		return fmt.Errorf("template: no template %q associated with template %q", name, t.name)
-	}
-	return tmpl.Execute(wr, data)
-}
-
-// Execute applies a parsed template to the specified data object,
-// and writes the output to wr.
-// If an error occurs executing the template or writing its output,
-// execution stops, but partial results may already have been written to
-// the output writer.
-// A template may be executed safely in parallel.
-func (t *Template) Execute(wr io.Writer, data interface{}) (err error) {
-	defer errRecover(&err)
-	value := reflect.ValueOf(data)
-	state := &state{
-		tmpl: t,
-		wr:   wr,
-		vars: []variable{{"$", value}},
-	}
-	t.init()
-	if t.Tree == nil || t.Root == nil {
-		var b bytes.Buffer
-		for name, tmpl := range t.tmpl {
-			if tmpl.Tree == nil || tmpl.Root == nil {
-				continue
-			}
-			if b.Len() > 0 {
-				b.WriteString(", ")
-			}
-			fmt.Fprintf(&b, "%q", name)
-		}
-		var s string
-		if b.Len() > 0 {
-			s = "; defined templates are: " + b.String()
-		}
-		state.errorf("%q is an incomplete or empty template%s", t.Name(), s)
-	}
-	state.walk(value, t.Root)
-	return
-}
-
-// Walk functions step through the major pieces of the template structure,
-// generating output as they go.
-func (s *state) walk(dot reflect.Value, node parse.Node) {
-	s.at(node)
-	switch node := node.(type) {
-	case *parse.ActionNode:
-		// Do not pop variables so they persist until next end.
-		// Also, if the action declares variables, don't print the result.
-		val := s.evalPipeline(dot, node.Pipe)
-		if len(node.Pipe.Decl) == 0 {
-			s.printValue(node, val)
-		}
-	case *parse.IfNode:
-		s.walkIfOrWith(parse.NodeIf, dot, node.Pipe, node.List, node.ElseList)
-	case *parse.ListNode:
-		for _, node := range node.Nodes {
-			s.walk(dot, node)
-		}
-	case *parse.RangeNode:
-		s.walkRange(dot, node)
-	case *parse.TemplateNode:
-		s.walkTemplate(dot, node)
-	case *parse.TextNode:
-		if _, err := s.wr.Write(node.Text); err != nil {
-			s.errorf("%s", err)
-		}
-	case *parse.WithNode:
-		s.walkIfOrWith(parse.NodeWith, dot, node.Pipe, node.List, node.ElseList)
-	default:
-		s.errorf("unknown node: %s", node)
-	}
-}
-
-// walkIfOrWith walks an 'if' or 'with' node. The two control structures
-// are identical in behavior except that 'with' sets dot.
-func (s *state) walkIfOrWith(typ parse.NodeType, dot reflect.Value, pipe *parse.PipeNode, list, elseList *parse.ListNode) {
-	defer s.pop(s.mark())
-	val := s.evalPipeline(dot, pipe)
-	truth, ok := isTrue(val)
-	if !ok {
-		s.errorf("if/with can't use %v", val)
-	}
-	if truth {
-		if typ == parse.NodeWith {
-			s.walk(val, list)
-		} else {
-			s.walk(dot, list)
-		}
-	} else if elseList != nil {
-		s.walk(dot, elseList)
-	}
-}
-
-// isTrue reports whether the value is 'true', in the sense of not the zero of its type,
-// and whether the value has a meaningful truth value.
-func isTrue(val reflect.Value) (truth, ok bool) {
-	if !val.IsValid() {
-		// Something like var x interface{}, never set. It's a form of nil.
-		return false, true
-	}
-	switch val.Kind() {
-	case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
-		truth = val.Len() > 0
-	case reflect.Bool:
-		truth = val.Bool()
-	case reflect.Complex64, reflect.Complex128:
-		truth = val.Complex() != 0
-	case reflect.Chan, reflect.Func, reflect.Ptr, reflect.Interface:
-		truth = !val.IsNil()
-	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-		truth = val.Int() != 0
-	case reflect.Float32, reflect.Float64:
-		truth = val.Float() != 0
-	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
-		truth = val.Uint() != 0
-	case reflect.Struct:
-		truth = true // Struct values are always true.
-	default:
-		return
-	}
-	return truth, true
-}
-
-func (s *state) walkRange(dot reflect.Value, r *parse.RangeNode) {
-	s.at(r)
-	defer s.pop(s.mark())
-	val, _ := indirect(s.evalPipeline(dot, r.Pipe))
-	// mark top of stack before any variables in the body are pushed.
-	mark := s.mark()
-	oneIteration := func(index, elem reflect.Value) {
-		// Set top var (lexically the second if there are two) to the element.
-		if len(r.Pipe.Decl) > 0 {
-			s.setVar(1, elem)
-		}
-		// Set next var (lexically the first if there are two) to the index.
-		if len(r.Pipe.Decl) > 1 {
-			s.setVar(2, index)
-		}
-		s.walk(elem, r.List)
-		s.pop(mark)
-	}
-	switch val.Kind() {
-	case reflect.Array, reflect.Slice:
-		if val.Len() == 0 {
-			break
-		}
-		for i := 0; i < val.Len(); i++ {
-			oneIteration(reflect.ValueOf(i), val.Index(i))
-		}
-		return
-	case reflect.Map:
-		if val.Len() == 0 {
-			break
-		}
-		for _, key := range sortKeys(val.MapKeys()) {
-			oneIteration(key, val.MapIndex(key))
-		}
-		return
-	case reflect.Chan:
-		if val.IsNil() {
-			break
-		}
-		i := 0
-		for ; ; i++ {
-			elem, ok := val.Recv()
-			if !ok {
-				break
-			}
-			oneIteration(reflect.ValueOf(i), elem)
-		}
-		if i == 0 {
-			break
-		}
-		return
-	case reflect.Invalid:
-		break // An invalid value is likely a nil map, etc. and acts like an empty map.
-	default:
-		s.errorf("range can't iterate over %v", val)
-	}
-	if r.ElseList != nil {
-		s.walk(dot, r.ElseList)
-	}
-}
-
-func (s *state) walkTemplate(dot reflect.Value, t *parse.TemplateNode) {
-	s.at(t)
-	tmpl := s.tmpl.tmpl[t.Name]
-	if tmpl == nil {
-		s.errorf("template %q not defined", t.Name)
-	}
-	// Variables declared by the pipeline persist.
-	dot = s.evalPipeline(dot, t.Pipe)
-	newState := *s
-	newState.tmpl = tmpl
-	// No dynamic scoping: template invocations inherit no variables.
-	newState.vars = []variable{{"$", dot}}
-	newState.walk(dot, tmpl.Root)
-}
-
-// Eval functions evaluate pipelines, commands, and their elements and extract
-// values from the data structure by examining fields, calling methods, and so on.
-// The printing of those values happens only through walk functions.
-
-// evalPipeline returns the value acquired by evaluating a pipeline. If the
-// pipeline has a variable declaration, the variable will be pushed on the
-// stack. Callers should therefore pop the stack after they are finished
-// executing commands depending on the pipeline value.
-func (s *state) evalPipeline(dot reflect.Value, pipe *parse.PipeNode) (value reflect.Value) {
-	if pipe == nil {
-		return
-	}
-	s.at(pipe)
-	for _, cmd := range pipe.Cmds {
-		value = s.evalCommand(dot, cmd, value) // previous value is this one's final arg.
-		// If the object has type interface{}, dig down one level to the thing inside.
-		if value.Kind() == reflect.Interface && value.Type().NumMethod() == 0 {
-			value = reflect.ValueOf(value.Interface()) // lovely!
-		}
-	}
-	for _, variable := range pipe.Decl {
-		s.push(variable.Ident[0], value)
-	}
-	return value
-}
-
-func (s *state) notAFunction(args []parse.Node, final reflect.Value) {
-	if len(args) > 1 || final.IsValid() {
-		s.errorf("can't give argument to non-function %s", args[0])
-	}
-}
-
-func (s *state) evalCommand(dot reflect.Value, cmd *parse.CommandNode, final reflect.Value) reflect.Value {
-	firstWord := cmd.Args[0]
-	switch n := firstWord.(type) {
-	case *parse.FieldNode:
-		return s.evalFieldNode(dot, n, cmd.Args, final)
-	case *parse.ChainNode:
-		return s.evalChainNode(dot, n, cmd.Args, final)
-	case *parse.IdentifierNode:
-		// Must be a function.
-		return s.evalFunction(dot, n, cmd, cmd.Args, final)
-	case *parse.PipeNode:
-		// Parenthesized pipeline. The arguments are all inside the pipeline; final is ignored.
-		return s.evalPipeline(dot, n)
-	case *parse.VariableNode:
-		return s.evalVariableNode(dot, n, cmd.Args, final)
-	}
-	s.at(firstWord)
-	s.notAFunction(cmd.Args, final)
-	switch word := firstWord.(type) {
-	case *parse.BoolNode:
-		return reflect.ValueOf(word.True)
-	case *parse.DotNode:
-		return dot
-	case *parse.NilNode:
-		s.errorf("nil is not a command")
-	case *parse.NumberNode:
-		return s.idealConstant(word)
-	case *parse.StringNode:
-		return reflect.ValueOf(word.Text)
-	}
-	s.errorf("can't evaluate command %q", firstWord)
-	panic("not reached")
-}
-
-// idealConstant is called to return the value of a number in a context where
-// we don't know the type. In that case, the syntax of the number tells us
-// its type, and we use Go rules to resolve.  Note there is no such thing as
-// a uint ideal constant in this situation - the value must be of int type.
-func (s *state) idealConstant(constant *parse.NumberNode) reflect.Value {
-	// These are ideal constants but we don't know the type
-	// and we have no context.  (If it was a method argument,
-	// we'd know what we need.) The syntax guides us to some extent.
-	s.at(constant)
-	switch {
-	case constant.IsComplex:
-		return reflect.ValueOf(constant.Complex128) // incontrovertible.
-	case constant.IsFloat && strings.IndexAny(constant.Text, ".eE") >= 0:
-		return reflect.ValueOf(constant.Float64)
-	case constant.IsInt:
-		n := int(constant.Int64)
-		if int64(n) != constant.Int64 {
-			s.errorf("%s overflows int", constant.Text)
-		}
-		return reflect.ValueOf(n)
-	case constant.IsUint:
-		s.errorf("%s overflows int", constant.Text)
-	}
-	return zero
-}
-
-func (s *state) evalFieldNode(dot reflect.Value, field *parse.FieldNode, args []parse.Node, final reflect.Value) reflect.Value {
-	s.at(field)
-	return s.evalFieldChain(dot, dot, field, field.Ident, args, final)
-}
-
-func (s *state) evalChainNode(dot reflect.Value, chain *parse.ChainNode, args []parse.Node, final reflect.Value) reflect.Value {
-	s.at(chain)
-	// (pipe).Field1.Field2 has pipe as .Node, fields as .Field. Eval the pipeline, then the fields.
-	pipe := s.evalArg(dot, nil, chain.Node)
-	if len(chain.Field) == 0 {
-		s.errorf("internal error: no fields in evalChainNode")
-	}
-	return s.evalFieldChain(dot, pipe, chain, chain.Field, args, final)
-}
-
-func (s *state) evalVariableNode(dot reflect.Value, variable *parse.VariableNode, args []parse.Node, final reflect.Value) reflect.Value {
-	// $x.Field has $x as the first ident, Field as the second. Eval the var, then the fields.
-	s.at(variable)
-	value := s.varValue(variable.Ident[0])
-	if len(variable.Ident) == 1 {
-		s.notAFunction(args, final)
-		return value
-	}
-	return s.evalFieldChain(dot, value, variable, variable.Ident[1:], args, final)
-}
-
-// evalFieldChain evaluates .X.Y.Z possibly followed by arguments.
-// dot is the environment in which to evaluate arguments, while
-// receiver is the value being walked along the chain.
-func (s *state) evalFieldChain(dot, receiver reflect.Value, node parse.Node, ident []string, args []parse.Node, final reflect.Value) reflect.Value {
-	n := len(ident)
-	for i := 0; i < n-1; i++ {
-		receiver = s.evalField(dot, ident[i], node, nil, zero, receiver)
-	}
-	// Now if it's a method, it gets the arguments.
-	return s.evalField(dot, ident[n-1], node, args, final, receiver)
-}
-
-func (s *state) evalFunction(dot reflect.Value, node *parse.IdentifierNode, cmd parse.Node, args []parse.Node, final reflect.Value) reflect.Value {
-	s.at(node)
-	name := node.Ident
-	function, ok := findFunction(name, s.tmpl)
-	if !ok {
-		s.errorf("%q is not a defined function", name)
-	}
-	return s.evalCall(dot, function, cmd, name, args, final)
-}
-
-// evalField evaluates an expression like (.Field) or (.Field arg1 arg2).
-// The 'final' argument represents the return value from the preceding
-// value of the pipeline, if any.
-func (s *state) evalField(dot reflect.Value, fieldName string, node parse.Node, args []parse.Node, final, receiver reflect.Value) reflect.Value {
-	if !receiver.IsValid() {
-		return zero
-	}
-	typ := receiver.Type()
-	receiver, _ = indirect(receiver)
-	// Unless it's an interface, need to get to a value of type *T to guarantee
-	// we see all methods of T and *T.
-	ptr := receiver
-	if ptr.Kind() != reflect.Interface && ptr.CanAddr() {
-		ptr = ptr.Addr()
-	}
-	if method := ptr.MethodByName(fieldName); method.IsValid() {
-		return s.evalCall(dot, method, node, fieldName, args, final)
-	}
-	hasArgs := len(args) > 1 || final.IsValid()
-	// It's not a method; must be a field of a struct or an element of a map. The receiver must not be nil.
-	receiver, isNil := indirect(receiver)
-	if isNil {
-		s.errorf("nil pointer evaluating %s.%s", typ, fieldName)
-	}
-	switch receiver.Kind() {
-	case reflect.Struct:
-		tField, ok := receiver.Type().FieldByName(fieldName)
-		if ok {
-			field := receiver.FieldByIndex(tField.Index)
-			if tField.PkgPath != "" { // field is unexported
-				s.errorf("%s is an unexported field of struct type %s", fieldName, typ)
-			}
-			// If it's a function, we must call it.
-			if hasArgs {
-				s.errorf("%s has arguments but cannot be invoked as function", fieldName)
-			}
-			return field
-		}
-		s.errorf("%s is not a field of struct type %s", fieldName, typ)
-	case reflect.Map:
-		// If it's a map, attempt to use the field name as a key.
-		nameVal := reflect.ValueOf(fieldName)
-		if nameVal.Type().AssignableTo(receiver.Type().Key()) {
-			if hasArgs {
-				s.errorf("%s is not a method but has arguments", fieldName)
-			}
-			return receiver.MapIndex(nameVal)
-		}
-	}
-	s.errorf("can't evaluate field %s in type %s", fieldName, typ)
-	panic("not reached")
-}
-
-var (
-	errorType       = reflect.TypeOf((*error)(nil)).Elem()
-	fmtStringerType = reflect.TypeOf((*fmt.Stringer)(nil)).Elem()
-)
-
-// evalCall executes a function or method call. If it's a method, fun already has the receiver bound, so
-// it looks just like a function call.  The arg list, if non-nil, includes (in the manner of the shell), arg[0]
-// as the function itself.
-func (s *state) evalCall(dot, fun reflect.Value, node parse.Node, name string, args []parse.Node, final reflect.Value) reflect.Value {
-	if args != nil {
-		args = args[1:] // Zeroth arg is function name/node; not passed to function.
-	}
-	typ := fun.Type()
-	numIn := len(args)
-	if final.IsValid() {
-		numIn++
-	}
-	numFixed := len(args)
-	if typ.IsVariadic() {
-		numFixed = typ.NumIn() - 1 // last arg is the variadic one.
-		if numIn < numFixed {
-			s.errorf("wrong number of args for %s: want at least %d got %d", name, typ.NumIn()-1, len(args))
-		}
-	} else if numIn < typ.NumIn()-1 || !typ.IsVariadic() && numIn != typ.NumIn() {
-		s.errorf("wrong number of args for %s: want %d got %d", name, typ.NumIn(), len(args))
-	}
-	if !goodFunc(typ) {
-		// TODO: This could still be a confusing error; maybe goodFunc should provide info.
-		s.errorf("can't call method/function %q with %d results", name, typ.NumOut())
-	}
-	// Build the arg list.
-	argv := make([]reflect.Value, numIn)
-	// Args must be evaluated. Fixed args first.
-	i := 0
-	for ; i < numFixed; i++ {
-		argv[i] = s.evalArg(dot, typ.In(i), args[i])
-	}
-	// Now the ... args.
-	if typ.IsVariadic() {
-		argType := typ.In(typ.NumIn() - 1).Elem() // Argument is a slice.
-		for ; i < len(args); i++ {
-			argv[i] = s.evalArg(dot, argType, args[i])
-		}
-	}
-	// Add final value if necessary.
-	if final.IsValid() {
-		t := typ.In(typ.NumIn() - 1)
-		if typ.IsVariadic() {
-			t = t.Elem()
-		}
-		argv[i] = s.validateType(final, t)
-	}
-	result := fun.Call(argv)
-	// If we have an error that is not nil, stop execution and return that error to the caller.
-	if len(result) == 2 && !result[1].IsNil() {
-		s.at(node)
-		s.errorf("error calling %s: %s", name, result[1].Interface().(error))
-	}
-	return result[0]
-}
-
-// canBeNil reports whether an untyped nil can be assigned to the type. See reflect.Zero.
-func canBeNil(typ reflect.Type) bool {
-	switch typ.Kind() {
-	case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
-		return true
-	}
-	return false
-}
-
-// validateType guarantees that the value is valid and assignable to the type.
-func (s *state) validateType(value reflect.Value, typ reflect.Type) reflect.Value {
-	if !value.IsValid() {
-		if typ == nil || canBeNil(typ) {
-			// An untyped nil interface{}. Accept as a proper nil value.
-			return reflect.Zero(typ)
-		}
-		s.errorf("invalid value; expected %s", typ)
-	}
-	if typ != nil && !value.Type().AssignableTo(typ) {
-		if value.Kind() == reflect.Interface && !value.IsNil() {
-			value = value.Elem()
-			if value.Type().AssignableTo(typ) {
-				return value
-			}
-			// fallthrough
-		}
-		// Does one dereference or indirection work? We could do more, as we
-		// do with method receivers, but that gets messy and method receivers
-		// are much more constrained, so it makes more sense there than here.
-		// Besides, one is almost always all you need.
-		switch {
-		case value.Kind() == reflect.Ptr && value.Type().Elem().AssignableTo(typ):
-			value = value.Elem()
-			if !value.IsValid() {
-				s.errorf("dereference of nil pointer of type %s", typ)
-			}
-		case reflect.PtrTo(value.Type()).AssignableTo(typ) && value.CanAddr():
-			value = value.Addr()
-		default:
-			s.errorf("wrong type for value; expected %s; got %s", typ, value.Type())
-		}
-	}
-	return value
-}
-
-func (s *state) evalArg(dot reflect.Value, typ reflect.Type, n parse.Node) reflect.Value {
-	s.at(n)
-	switch arg := n.(type) {
-	case *parse.DotNode:
-		return s.validateType(dot, typ)
-	case *parse.NilNode:
-		if canBeNil(typ) {
-			return reflect.Zero(typ)
-		}
-		s.errorf("cannot assign nil to %s", typ)
-	case *parse.FieldNode:
-		return s.validateType(s.evalFieldNode(dot, arg, []parse.Node{n}, zero), typ)
-	case *parse.VariableNode:
-		return s.validateType(s.evalVariableNode(dot, arg, nil, zero), typ)
-	case *parse.PipeNode:
-		return s.validateType(s.evalPipeline(dot, arg), typ)
-	case *parse.IdentifierNode:
-		return s.evalFunction(dot, arg, arg, nil, zero)
-	}
-	switch typ.Kind() {
-	case reflect.Bool:
-		return s.evalBool(typ, n)
-	case reflect.Complex64, reflect.Complex128:
-		return s.evalComplex(typ, n)
-	case reflect.Float32, reflect.Float64:
-		return s.evalFloat(typ, n)
-	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-		return s.evalInteger(typ, n)
-	case reflect.Interface:
-		if typ.NumMethod() == 0 {
-			return s.evalEmptyInterface(dot, n)
-		}
-	case reflect.String:
-		return s.evalString(typ, n)
-	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
-		return s.evalUnsignedInteger(typ, n)
-	}
-	s.errorf("can't handle %s for arg of type %s", n, typ)
-	panic("not reached")
-}
-
-func (s *state) evalBool(typ reflect.Type, n parse.Node) reflect.Value {
-	s.at(n)
-	if n, ok := n.(*parse.BoolNode); ok {
-		value := reflect.New(typ).Elem()
-		value.SetBool(n.True)
-		return value
-	}
-	s.errorf("expected bool; found %s", n)
-	panic("not reached")
-}
-
-func (s *state) evalString(typ reflect.Type, n parse.Node) reflect.Value {
-	s.at(n)
-	if n, ok := n.(*parse.StringNode); ok {
-		value := reflect.New(typ).Elem()
-		value.SetString(n.Text)
-		return value
-	}
-	s.errorf("expected string; found %s", n)
-	panic("not reached")
-}
-
-func (s *state) evalInteger(typ reflect.Type, n parse.Node) reflect.Value {
-	s.at(n)
-	if n, ok := n.(*parse.NumberNode); ok && n.IsInt {
-		value := reflect.New(typ).Elem()
-		value.SetInt(n.Int64)
-		return value
-	}
-	s.errorf("expected integer; found %s", n)
-	panic("not reached")
-}
-
-func (s *state) evalUnsignedInteger(typ reflect.Type, n parse.Node) reflect.Value {
-	s.at(n)
-	if n, ok := n.(*parse.NumberNode); ok && n.IsUint {
-		value := reflect.New(typ).Elem()
-		value.SetUint(n.Uint64)
-		return value
-	}
-	s.errorf("expected unsigned integer; found %s", n)
-	panic("not reached")
-}
-
-func (s *state) evalFloat(typ reflect.Type, n parse.Node) reflect.Value {
-	s.at(n)
-	if n, ok := n.(*parse.NumberNode); ok && n.IsFloat {
-		value := reflect.New(typ).Elem()
-		value.SetFloat(n.Float64)
-		return value
-	}
-	s.errorf("expected float; found %s", n)
-	panic("not reached")
-}
-
-func (s *state) evalComplex(typ reflect.Type, n parse.Node) reflect.Value {
-	if n, ok := n.(*parse.NumberNode); ok && n.IsComplex {
-		value := reflect.New(typ).Elem()
-		value.SetComplex(n.Complex128)
-		return value
-	}
-	s.errorf("expected complex; found %s", n)
-	panic("not reached")
-}
-
-func (s *state) evalEmptyInterface(dot reflect.Value, n parse.Node) reflect.Value {
-	s.at(n)
-	switch n := n.(type) {
-	case *parse.BoolNode:
-		return reflect.ValueOf(n.True)
-	case *parse.DotNode:
-		return dot
-	case *parse.FieldNode:
-		return s.evalFieldNode(dot, n, nil, zero)
-	case *parse.IdentifierNode:
-		return s.evalFunction(dot, n, n, nil, zero)
-	case *parse.NilNode:
-		// NilNode is handled in evalArg, the only place that calls here.
-		s.errorf("evalEmptyInterface: nil (can't happen)")
-	case *parse.NumberNode:
-		return s.idealConstant(n)
-	case *parse.StringNode:
-		return reflect.ValueOf(n.Text)
-	case *parse.VariableNode:
-		return s.evalVariableNode(dot, n, nil, zero)
-	case *parse.PipeNode:
-		return s.evalPipeline(dot, n)
-	}
-	s.errorf("can't handle assignment of %s to empty interface argument", n)
-	panic("not reached")
-}
-
-// indirect returns the item at the end of indirection, and a bool to indicate if it's nil.
-// We indirect through pointers and empty interfaces (only) because
-// non-empty interfaces have methods we might need.
-func indirect(v reflect.Value) (rv reflect.Value, isNil bool) {
-	for ; v.Kind() == reflect.Ptr || v.Kind() == reflect.Interface; v = v.Elem() {
-		if v.IsNil() {
-			return v, true
-		}
-		if v.Kind() == reflect.Interface && v.NumMethod() > 0 {
-			break
-		}
-	}
-	return v, false
-}
-
-// printValue writes the textual representation of the value to the output of
-// the template.
-func (s *state) printValue(n parse.Node, v reflect.Value) {
-	s.at(n)
-	iface, ok := printableValue(v)
-	if !ok {
-		s.errorf("can't print %s of type %s", n, v.Type())
-	}
-	fmt.Fprint(s.wr, iface)
-}
-
-// printableValue returns the, possibly indirected, interface value inside v that
-// is best for a call to formatted printer.
-func printableValue(v reflect.Value) (interface{}, bool) {
-	if v.Kind() == reflect.Ptr {
-		v, _ = indirect(v) // fmt.Fprint handles nil.
-	}
-	if !v.IsValid() {
-		return "<no value>", true
-	}
-
-	if !v.Type().Implements(errorType) && !v.Type().Implements(fmtStringerType) {
-		if v.CanAddr() && (reflect.PtrTo(v.Type()).Implements(errorType) || reflect.PtrTo(v.Type()).Implements(fmtStringerType)) {
-			v = v.Addr()
-		} else {
-			switch v.Kind() {
-			case reflect.Chan, reflect.Func:
-				return nil, false
-			}
-		}
-	}
-	return v.Interface(), true
-}
-
-// Types to help sort the keys in a map for reproducible output.
-
-type rvs []reflect.Value
-
-func (x rvs) Len() int      { return len(x) }
-func (x rvs) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
-
-type rvInts struct{ rvs }
-
-func (x rvInts) Less(i, j int) bool { return x.rvs[i].Int() < x.rvs[j].Int() }
-
-type rvUints struct{ rvs }
-
-func (x rvUints) Less(i, j int) bool { return x.rvs[i].Uint() < x.rvs[j].Uint() }
-
-type rvFloats struct{ rvs }
-
-func (x rvFloats) Less(i, j int) bool { return x.rvs[i].Float() < x.rvs[j].Float() }
-
-type rvStrings struct{ rvs }
-
-func (x rvStrings) Less(i, j int) bool { return x.rvs[i].String() < x.rvs[j].String() }
-
-// sortKeys sorts (if it can) the slice of reflect.Values, which is a slice of map keys.
-func sortKeys(v []reflect.Value) []reflect.Value {
-	if len(v) <= 1 {
-		return v
-	}
-	switch v[0].Kind() {
-	case reflect.Float32, reflect.Float64:
-		sort.Sort(rvFloats{v})
-	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-		sort.Sort(rvInts{v})
-	case reflect.String:
-		sort.Sort(rvStrings{v})
-	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
-		sort.Sort(rvUints{v})
-	}
-	return v
-}
diff --git a/src/pkg/text/template/exec_test.go b/src/pkg/text/template/exec_test.go
deleted file mode 100644
index 868f2cb..0000000
--- a/src/pkg/text/template/exec_test.go
+++ /dev/null
@@ -1,989 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package template
-
-import (
-	"bytes"
-	"errors"
-	"flag"
-	"fmt"
-	"reflect"
-	"strings"
-	"testing"
-)
-
-var debug = flag.Bool("debug", false, "show the errors produced by the tests")
-
-// T has lots of interesting pieces to use to test execution.
-type T struct {
-	// Basics
-	True        bool
-	I           int
-	U16         uint16
-	X           string
-	FloatZero   float64
-	ComplexZero complex128
-	// Nested structs.
-	U *U
-	// Struct with String method.
-	V0     V
-	V1, V2 *V
-	// Struct with Error method.
-	W0     W
-	W1, W2 *W
-	// Slices
-	SI      []int
-	SIEmpty []int
-	SB      []bool
-	// Maps
-	MSI      map[string]int
-	MSIone   map[string]int // one element, for deterministic output
-	MSIEmpty map[string]int
-	MXI      map[interface{}]int
-	MII      map[int]int
-	SMSI     []map[string]int
-	// Empty interfaces; used to see if we can dig inside one.
-	Empty0 interface{} // nil
-	Empty1 interface{}
-	Empty2 interface{}
-	Empty3 interface{}
-	Empty4 interface{}
-	// Non-empty interface.
-	NonEmptyInterface I
-	// Stringer.
-	Str fmt.Stringer
-	Err error
-	// Pointers
-	PI  *int
-	PS  *string
-	PSI *[]int
-	NIL *int
-	// Function (not method)
-	BinaryFunc      func(string, string) string
-	VariadicFunc    func(...string) string
-	VariadicFuncInt func(int, ...string) string
-	NilOKFunc       func(*int) bool
-	ErrFunc         func() (string, error)
-	// Template to test evaluation of templates.
-	Tmpl *Template
-	// Unexported field; cannot be accessed by template.
-	unexported int
-}
-
-type U struct {
-	V string
-}
-
-type V struct {
-	j int
-}
-
-func (v *V) String() string {
-	if v == nil {
-		return "nilV"
-	}
-	return fmt.Sprintf("<%d>", v.j)
-}
-
-type W struct {
-	k int
-}
-
-func (w *W) Error() string {
-	if w == nil {
-		return "nilW"
-	}
-	return fmt.Sprintf("[%d]", w.k)
-}
-
-var tVal = &T{
-	True:   true,
-	I:      17,
-	U16:    16,
-	X:      "x",
-	U:      &U{"v"},
-	V0:     V{6666},
-	V1:     &V{7777}, // leave V2 as nil
-	W0:     W{888},
-	W1:     &W{999}, // leave W2 as nil
-	SI:     []int{3, 4, 5},
-	SB:     []bool{true, false},
-	MSI:    map[string]int{"one": 1, "two": 2, "three": 3},
-	MSIone: map[string]int{"one": 1},
-	MXI:    map[interface{}]int{"one": 1},
-	MII:    map[int]int{1: 1},
-	SMSI: []map[string]int{
-		{"one": 1, "two": 2},
-		{"eleven": 11, "twelve": 12},
-	},
-	Empty1:            3,
-	Empty2:            "empty2",
-	Empty3:            []int{7, 8},
-	Empty4:            &U{"UinEmpty"},
-	NonEmptyInterface: new(T),
-	Str:               bytes.NewBuffer([]byte("foozle")),
-	Err:               errors.New("erroozle"),
-	PI:                newInt(23),
-	PS:                newString("a string"),
-	PSI:               newIntSlice(21, 22, 23),
-	BinaryFunc:        func(a, b string) string { return fmt.Sprintf("[%s=%s]", a, b) },
-	VariadicFunc:      func(s ...string) string { return fmt.Sprint("<", strings.Join(s, "+"), ">") },
-	VariadicFuncInt:   func(a int, s ...string) string { return fmt.Sprint(a, "=<", strings.Join(s, "+"), ">") },
-	NilOKFunc:         func(s *int) bool { return s == nil },
-	ErrFunc:           func() (string, error) { return "bla", nil },
-	Tmpl:              Must(New("x").Parse("test template")), // "x" is the value of .X
-}
-
-// A non-empty interface.
-type I interface {
-	Method0() string
-}
-
-var iVal I = tVal
-
-// Helpers for creation.
-func newInt(n int) *int {
-	return &n
-}
-
-func newString(s string) *string {
-	return &s
-}
-
-func newIntSlice(n ...int) *[]int {
-	p := new([]int)
-	*p = make([]int, len(n))
-	copy(*p, n)
-	return p
-}
-
-// Simple methods with and without arguments.
-func (t *T) Method0() string {
-	return "M0"
-}
-
-func (t *T) Method1(a int) int {
-	return a
-}
-
-func (t *T) Method2(a uint16, b string) string {
-	return fmt.Sprintf("Method2: %d %s", a, b)
-}
-
-func (t *T) Method3(v interface{}) string {
-	return fmt.Sprintf("Method3: %v", v)
-}
-
-func (t *T) MAdd(a int, b []int) []int {
-	v := make([]int, len(b))
-	for i, x := range b {
-		v[i] = x + a
-	}
-	return v
-}
-
-var myError = errors.New("my error")
-
-// MyError returns a value and an error according to its argument.
-func (t *T) MyError(error bool) (bool, error) {
-	if error {
-		return true, myError
-	}
-	return false, nil
-}
-
-// A few methods to test chaining.
-func (t *T) GetU() *U {
-	return t.U
-}
-
-func (u *U) TrueFalse(b bool) string {
-	if b {
-		return "true"
-	}
-	return ""
-}
-
-func typeOf(arg interface{}) string {
-	return fmt.Sprintf("%T", arg)
-}
-
-type execTest struct {
-	name   string
-	input  string
-	output string
-	data   interface{}
-	ok     bool
-}
-
-// bigInt and bigUint are hex string representing numbers either side
-// of the max int boundary.
-// We do it this way so the test doesn't depend on ints being 32 bits.
-var (
-	bigInt  = fmt.Sprintf("0x%x", int(1<<uint(reflect.TypeOf(0).Bits()-1)-1))
-	bigUint = fmt.Sprintf("0x%x", uint(1<<uint(reflect.TypeOf(0).Bits()-1)))
-)
-
-var execTests = []execTest{
-	// Trivial cases.
-	{"empty", "", "", nil, true},
-	{"text", "some text", "some text", nil, true},
-	{"nil action", "{{nil}}", "", nil, false},
-
-	// Ideal constants.
-	{"ideal int", "{{typeOf 3}}", "int", 0, true},
-	{"ideal float", "{{typeOf 1.0}}", "float64", 0, true},
-	{"ideal exp float", "{{typeOf 1e1}}", "float64", 0, true},
-	{"ideal complex", "{{typeOf 1i}}", "complex128", 0, true},
-	{"ideal int", "{{typeOf " + bigInt + "}}", "int", 0, true},
-	{"ideal too big", "{{typeOf " + bigUint + "}}", "", 0, false},
-	{"ideal nil without type", "{{nil}}", "", 0, false},
-
-	// Fields of structs.
-	{".X", "-{{.X}}-", "-x-", tVal, true},
-	{".U.V", "-{{.U.V}}-", "-v-", tVal, true},
-	{".unexported", "{{.unexported}}", "", tVal, false},
-
-	// Fields on maps.
-	{"map .one", "{{.MSI.one}}", "1", tVal, true},
-	{"map .two", "{{.MSI.two}}", "2", tVal, true},
-	{"map .NO", "{{.MSI.NO}}", "<no value>", tVal, true},
-	{"map .one interface", "{{.MXI.one}}", "1", tVal, true},
-	{"map .WRONG args", "{{.MSI.one 1}}", "", tVal, false},
-	{"map .WRONG type", "{{.MII.one}}", "", tVal, false},
-
-	// Dots of all kinds to test basic evaluation.
-	{"dot int", "<{{.}}>", "<13>", 13, true},
-	{"dot uint", "<{{.}}>", "<14>", uint(14), true},
-	{"dot float", "<{{.}}>", "<15.1>", 15.1, true},
-	{"dot bool", "<{{.}}>", "<true>", true, true},
-	{"dot complex", "<{{.}}>", "<(16.2-17i)>", 16.2 - 17i, true},
-	{"dot string", "<{{.}}>", "<hello>", "hello", true},
-	{"dot slice", "<{{.}}>", "<[-1 -2 -3]>", []int{-1, -2, -3}, true},
-	{"dot map", "<{{.}}>", "<map[two:22]>", map[string]int{"two": 22}, true},
-	{"dot struct", "<{{.}}>", "<{7 seven}>", struct {
-		a int
-		b string
-	}{7, "seven"}, true},
-
-	// Variables.
-	{"$ int", "{{$}}", "123", 123, true},
-	{"$.I", "{{$.I}}", "17", tVal, true},
-	{"$.U.V", "{{$.U.V}}", "v", tVal, true},
-	{"declare in action", "{{$x := $.U.V}}{{$x}}", "v", tVal, true},
-
-	// Type with String method.
-	{"V{6666}.String()", "-{{.V0}}-", "-<6666>-", tVal, true},
-	{"&V{7777}.String()", "-{{.V1}}-", "-<7777>-", tVal, true},
-	{"(*V)(nil).String()", "-{{.V2}}-", "-nilV-", tVal, true},
-
-	// Type with Error method.
-	{"W{888}.Error()", "-{{.W0}}-", "-[888]-", tVal, true},
-	{"&W{999}.Error()", "-{{.W1}}-", "-[999]-", tVal, true},
-	{"(*W)(nil).Error()", "-{{.W2}}-", "-nilW-", tVal, true},
-
-	// Pointers.
-	{"*int", "{{.PI}}", "23", tVal, true},
-	{"*string", "{{.PS}}", "a string", tVal, true},
-	{"*[]int", "{{.PSI}}", "[21 22 23]", tVal, true},
-	{"*[]int[1]", "{{index .PSI 1}}", "22", tVal, true},
-	{"NIL", "{{.NIL}}", "<nil>", tVal, true},
-
-	// Empty interfaces holding values.
-	{"empty nil", "{{.Empty0}}", "<no value>", tVal, true},
-	{"empty with int", "{{.Empty1}}", "3", tVal, true},
-	{"empty with string", "{{.Empty2}}", "empty2", tVal, true},
-	{"empty with slice", "{{.Empty3}}", "[7 8]", tVal, true},
-	{"empty with struct", "{{.Empty4}}", "{UinEmpty}", tVal, true},
-	{"empty with struct, field", "{{.Empty4.V}}", "UinEmpty", tVal, true},
-
-	// Method calls.
-	{".Method0", "-{{.Method0}}-", "-M0-", tVal, true},
-	{".Method1(1234)", "-{{.Method1 1234}}-", "-1234-", tVal, true},
-	{".Method1(.I)", "-{{.Method1 .I}}-", "-17-", tVal, true},
-	{".Method2(3, .X)", "-{{.Method2 3 .X}}-", "-Method2: 3 x-", tVal, true},
-	{".Method2(.U16, `str`)", "-{{.Method2 .U16 `str`}}-", "-Method2: 16 str-", tVal, true},
-	{".Method2(.U16, $x)", "{{if $x := .X}}-{{.Method2 .U16 $x}}{{end}}-", "-Method2: 16 x-", tVal, true},
-	{".Method3(nil constant)", "-{{.Method3 nil}}-", "-Method3: <nil>-", tVal, true},
-	{".Method3(nil value)", "-{{.Method3 .MXI.unset}}-", "-Method3: <nil>-", tVal, true},
-	{"method on var", "{{if $x := .}}-{{$x.Method2 .U16 $x.X}}{{end}}-", "-Method2: 16 x-", tVal, true},
-	{"method on chained var",
-		"{{range .MSIone}}{{if $.U.TrueFalse $.True}}{{$.U.TrueFalse $.True}}{{else}}WRONG{{end}}{{end}}",
-		"true", tVal, true},
-	{"chained method",
-		"{{range .MSIone}}{{if $.GetU.TrueFalse $.True}}{{$.U.TrueFalse $.True}}{{else}}WRONG{{end}}{{end}}",
-		"true", tVal, true},
-	{"chained method on variable",
-		"{{with $x := .}}{{with .SI}}{{$.GetU.TrueFalse $.True}}{{end}}{{end}}",
-		"true", tVal, true},
-	{".NilOKFunc not nil", "{{call .NilOKFunc .PI}}", "false", tVal, true},
-	{".NilOKFunc nil", "{{call .NilOKFunc nil}}", "true", tVal, true},
-
-	// Function call builtin.
-	{".BinaryFunc", "{{call .BinaryFunc `1` `2`}}", "[1=2]", tVal, true},
-	{".VariadicFunc0", "{{call .VariadicFunc}}", "<>", tVal, true},
-	{".VariadicFunc2", "{{call .VariadicFunc `he` `llo`}}", "<he+llo>", tVal, true},
-	{".VariadicFuncInt", "{{call .VariadicFuncInt 33 `he` `llo`}}", "33=<he+llo>", tVal, true},
-	{"if .BinaryFunc call", "{{ if .BinaryFunc}}{{call .BinaryFunc `1` `2`}}{{end}}", "[1=2]", tVal, true},
-	{"if not .BinaryFunc call", "{{ if not .BinaryFunc}}{{call .BinaryFunc `1` `2`}}{{else}}No{{end}}", "No", tVal, true},
-	{"Interface Call", `{{stringer .S}}`, "foozle", map[string]interface{}{"S": bytes.NewBufferString("foozle")}, true},
-	{".ErrFunc", "{{call .ErrFunc}}", "bla", tVal, true},
-
-	// Erroneous function calls (check args).
-	{".BinaryFuncTooFew", "{{call .BinaryFunc `1`}}", "", tVal, false},
-	{".BinaryFuncTooMany", "{{call .BinaryFunc `1` `2` `3`}}", "", tVal, false},
-	{".BinaryFuncBad0", "{{call .BinaryFunc 1 3}}", "", tVal, false},
-	{".BinaryFuncBad1", "{{call .BinaryFunc `1` 3}}", "", tVal, false},
-	{".VariadicFuncBad0", "{{call .VariadicFunc 3}}", "", tVal, false},
-	{".VariadicFuncIntBad0", "{{call .VariadicFuncInt}}", "", tVal, false},
-	{".VariadicFuncIntBad`", "{{call .VariadicFuncInt `x`}}", "", tVal, false},
-	{".VariadicFuncNilBad", "{{call .VariadicFunc nil}}", "", tVal, false},
-
-	// Pipelines.
-	{"pipeline", "-{{.Method0 | .Method2 .U16}}-", "-Method2: 16 M0-", tVal, true},
-	{"pipeline func", "-{{call .VariadicFunc `llo` | call .VariadicFunc `he` }}-", "-<he+<llo>>-", tVal, true},
-
-	// Parenthesized expressions
-	{"parens in pipeline", "{{printf `%d %d %d` (1) (2 | add 3) (add 4 (add 5 6))}}", "1 5 15", tVal, true},
-
-	// Parenthesized expressions with field accesses
-	{"parens: $ in paren", "{{($).X}}", "x", tVal, true},
-	{"parens: $.GetU in paren", "{{($.GetU).V}}", "v", tVal, true},
-	{"parens: $ in paren in pipe", "{{($ | echo).X}}", "x", tVal, true},
-	{"parens: spaces and args", `{{(makemap "up" "down" "left" "right").left}}`, "right", tVal, true},
-
-	// If.
-	{"if true", "{{if true}}TRUE{{end}}", "TRUE", tVal, true},
-	{"if false", "{{if false}}TRUE{{else}}FALSE{{end}}", "FALSE", tVal, true},
-	{"if nil", "{{if nil}}TRUE{{end}}", "", tVal, false},
-	{"if 1", "{{if 1}}NON-ZERO{{else}}ZERO{{end}}", "NON-ZERO", tVal, true},
-	{"if 0", "{{if 0}}NON-ZERO{{else}}ZERO{{end}}", "ZERO", tVal, true},
-	{"if 1.5", "{{if 1.5}}NON-ZERO{{else}}ZERO{{end}}", "NON-ZERO", tVal, true},
-	{"if 0.0", "{{if .FloatZero}}NON-ZERO{{else}}ZERO{{end}}", "ZERO", tVal, true},
-	{"if 1.5i", "{{if 1.5i}}NON-ZERO{{else}}ZERO{{end}}", "NON-ZERO", tVal, true},
-	{"if 0.0i", "{{if .ComplexZero}}NON-ZERO{{else}}ZERO{{end}}", "ZERO", tVal, true},
-	{"if emptystring", "{{if ``}}NON-EMPTY{{else}}EMPTY{{end}}", "EMPTY", tVal, true},
-	{"if string", "{{if `notempty`}}NON-EMPTY{{else}}EMPTY{{end}}", "NON-EMPTY", tVal, true},
-	{"if emptyslice", "{{if .SIEmpty}}NON-EMPTY{{else}}EMPTY{{end}}", "EMPTY", tVal, true},
-	{"if slice", "{{if .SI}}NON-EMPTY{{else}}EMPTY{{end}}", "NON-EMPTY", tVal, true},
-	{"if emptymap", "{{if .MSIEmpty}}NON-EMPTY{{else}}EMPTY{{end}}", "EMPTY", tVal, true},
-	{"if map", "{{if .MSI}}NON-EMPTY{{else}}EMPTY{{end}}", "NON-EMPTY", tVal, true},
-	{"if map unset", "{{if .MXI.none}}NON-ZERO{{else}}ZERO{{end}}", "ZERO", tVal, true},
-	{"if map not unset", "{{if not .MXI.none}}ZERO{{else}}NON-ZERO{{end}}", "ZERO", tVal, true},
-	{"if $x with $y int", "{{if $x := true}}{{with $y := .I}}{{$x}},{{$y}}{{end}}{{end}}", "true,17", tVal, true},
-	{"if $x with $x int", "{{if $x := true}}{{with $x := .I}}{{$x}},{{end}}{{$x}}{{end}}", "17,true", tVal, true},
-	{"if else if", "{{if false}}FALSE{{else if true}}TRUE{{end}}", "TRUE", tVal, true},
-	{"if else chain", "{{if eq 1 3}}1{{else if eq 2 3}}2{{else if eq 3 3}}3{{end}}", "3", tVal, true},
-
-	// Print etc.
-	{"print", `{{print "hello, print"}}`, "hello, print", tVal, true},
-	{"print 123", `{{print 1 2 3}}`, "1 2 3", tVal, true},
-	{"print nil", `{{print nil}}`, "<nil>", tVal, true},
-	{"println", `{{println 1 2 3}}`, "1 2 3\n", tVal, true},
-	{"printf int", `{{printf "%04x" 127}}`, "007f", tVal, true},
-	{"printf float", `{{printf "%g" 3.5}}`, "3.5", tVal, true},
-	{"printf complex", `{{printf "%g" 1+7i}}`, "(1+7i)", tVal, true},
-	{"printf string", `{{printf "%s" "hello"}}`, "hello", tVal, true},
-	{"printf function", `{{printf "%#q" zeroArgs}}`, "`zeroArgs`", tVal, true},
-	{"printf field", `{{printf "%s" .U.V}}`, "v", tVal, true},
-	{"printf method", `{{printf "%s" .Method0}}`, "M0", tVal, true},
-	{"printf dot", `{{with .I}}{{printf "%d" .}}{{end}}`, "17", tVal, true},
-	{"printf var", `{{with $x := .I}}{{printf "%d" $x}}{{end}}`, "17", tVal, true},
-	{"printf lots", `{{printf "%d %s %g %s" 127 "hello" 7-3i .Method0}}`, "127 hello (7-3i) M0", tVal, true},
-
-	// HTML.
-	{"html", `{{html "<script>alert(\"XSS\");</script>"}}`,
-		"<script>alert("XSS");</script>", nil, true},
-	{"html pipeline", `{{printf "<script>alert(\"XSS\");</script>" | html}}`,
-		"<script>alert("XSS");</script>", nil, true},
-	{"html", `{{html .PS}}`, "a string", tVal, true},
-
-	// JavaScript.
-	{"js", `{{js .}}`, `It\'d be nice.`, `It'd be nice.`, true},
-
-	// URL query.
-	{"urlquery", `{{"http://www.example.org/"|urlquery}}`, "http%3A%2F%2Fwww.example.org%2F", nil, true},
-
-	// Booleans
-	{"not", "{{not true}} {{not false}}", "false true", nil, true},
-	{"and", "{{and false 0}} {{and 1 0}} {{and 0 true}} {{and 1 1}}", "false 0 0 1", nil, true},
-	{"or", "{{or 0 0}} {{or 1 0}} {{or 0 true}} {{or 1 1}}", "0 1 true 1", nil, true},
-	{"boolean if", "{{if and true 1 `hi`}}TRUE{{else}}FALSE{{end}}", "TRUE", tVal, true},
-	{"boolean if not", "{{if and true 1 `hi` | not}}TRUE{{else}}FALSE{{end}}", "FALSE", nil, true},
-
-	// Indexing.
-	{"slice[0]", "{{index .SI 0}}", "3", tVal, true},
-	{"slice[1]", "{{index .SI 1}}", "4", tVal, true},
-	{"slice[HUGE]", "{{index .SI 10}}", "", tVal, false},
-	{"slice[WRONG]", "{{index .SI `hello`}}", "", tVal, false},
-	{"map[one]", "{{index .MSI `one`}}", "1", tVal, true},
-	{"map[two]", "{{index .MSI `two`}}", "2", tVal, true},
-	{"map[NO]", "{{index .MSI `XXX`}}", "0", tVal, true},
-	{"map[nil]", "{{index .MSI nil}}", "0", tVal, true},
-	{"map[WRONG]", "{{index .MSI 10}}", "", tVal, false},
-	{"double index", "{{index .SMSI 1 `eleven`}}", "11", tVal, true},
-
-	// Len.
-	{"slice", "{{len .SI}}", "3", tVal, true},
-	{"map", "{{len .MSI }}", "3", tVal, true},
-	{"len of int", "{{len 3}}", "", tVal, false},
-	{"len of nothing", "{{len .Empty0}}", "", tVal, false},
-
-	// With.
-	{"with true", "{{with true}}{{.}}{{end}}", "true", tVal, true},
-	{"with false", "{{with false}}{{.}}{{else}}FALSE{{end}}", "FALSE", tVal, true},
-	{"with 1", "{{with 1}}{{.}}{{else}}ZERO{{end}}", "1", tVal, true},
-	{"with 0", "{{with 0}}{{.}}{{else}}ZERO{{end}}", "ZERO", tVal, true},
-	{"with 1.5", "{{with 1.5}}{{.}}{{else}}ZERO{{end}}", "1.5", tVal, true},
-	{"with 0.0", "{{with .FloatZero}}{{.}}{{else}}ZERO{{end}}", "ZERO", tVal, true},
-	{"with 1.5i", "{{with 1.5i}}{{.}}{{else}}ZERO{{end}}", "(0+1.5i)", tVal, true},
-	{"with 0.0i", "{{with .ComplexZero}}{{.}}{{else}}ZERO{{end}}", "ZERO", tVal, true},
-	{"with emptystring", "{{with ``}}{{.}}{{else}}EMPTY{{end}}", "EMPTY", tVal, true},
-	{"with string", "{{with `notempty`}}{{.}}{{else}}EMPTY{{end}}", "notempty", tVal, true},
-	{"with emptyslice", "{{with .SIEmpty}}{{.}}{{else}}EMPTY{{end}}", "EMPTY", tVal, true},
-	{"with slice", "{{with .SI}}{{.}}{{else}}EMPTY{{end}}", "[3 4 5]", tVal, true},
-	{"with emptymap", "{{with .MSIEmpty}}{{.}}{{else}}EMPTY{{end}}", "EMPTY", tVal, true},
-	{"with map", "{{with .MSIone}}{{.}}{{else}}EMPTY{{end}}", "map[one:1]", tVal, true},
-	{"with empty interface, struct field", "{{with .Empty4}}{{.V}}{{end}}", "UinEmpty", tVal, true},
-	{"with $x int", "{{with $x := .I}}{{$x}}{{end}}", "17", tVal, true},
-	{"with $x struct.U.V", "{{with $x := $}}{{$x.U.V}}{{end}}", "v", tVal, true},
-	{"with variable and action", "{{with $x := $}}{{$y := $.U.V}}{{$y}}{{end}}", "v", tVal, true},
-
-	// Range.
-	{"range []int", "{{range .SI}}-{{.}}-{{end}}", "-3--4--5-", tVal, true},
-	{"range empty no else", "{{range .SIEmpty}}-{{.}}-{{end}}", "", tVal, true},
-	{"range []int else", "{{range .SI}}-{{.}}-{{else}}EMPTY{{end}}", "-3--4--5-", tVal, true},
-	{"range empty else", "{{range .SIEmpty}}-{{.}}-{{else}}EMPTY{{end}}", "EMPTY", tVal, true},
-	{"range []bool", "{{range .SB}}-{{.}}-{{end}}", "-true--false-", tVal, true},
-	{"range []int method", "{{range .SI | .MAdd .I}}-{{.}}-{{end}}", "-20--21--22-", tVal, true},
-	{"range map", "{{range .MSI}}-{{.}}-{{end}}", "-1--3--2-", tVal, true},
-	{"range empty map no else", "{{range .MSIEmpty}}-{{.}}-{{end}}", "", tVal, true},
-	{"range map else", "{{range .MSI}}-{{.}}-{{else}}EMPTY{{end}}", "-1--3--2-", tVal, true},
-	{"range empty map else", "{{range .MSIEmpty}}-{{.}}-{{else}}EMPTY{{end}}", "EMPTY", tVal, true},
-	{"range empty interface", "{{range .Empty3}}-{{.}}-{{else}}EMPTY{{end}}", "-7--8-", tVal, true},
-	{"range empty nil", "{{range .Empty0}}-{{.}}-{{end}}", "", tVal, true},
-	{"range $x SI", "{{range $x := .SI}}<{{$x}}>{{end}}", "<3><4><5>", tVal, true},
-	{"range $x $y SI", "{{range $x, $y := .SI}}<{{$x}}={{$y}}>{{end}}", "<0=3><1=4><2=5>", tVal, true},
-	{"range $x MSIone", "{{range $x := .MSIone}}<{{$x}}>{{end}}", "<1>", tVal, true},
-	{"range $x $y MSIone", "{{range $x, $y := .MSIone}}<{{$x}}={{$y}}>{{end}}", "<one=1>", tVal, true},
-	{"range $x PSI", "{{range $x := .PSI}}<{{$x}}>{{end}}", "<21><22><23>", tVal, true},
-	{"declare in range", "{{range $x := .PSI}}<{{$foo:=$x}}{{$x}}>{{end}}", "<21><22><23>", tVal, true},
-	{"range count", `{{range $i, $x := count 5}}[{{$i}}]{{$x}}{{end}}`, "[0]a[1]b[2]c[3]d[4]e", tVal, true},
-	{"range nil count", `{{range $i, $x := count 0}}{{else}}empty{{end}}`, "empty", tVal, true},
-
-	// Cute examples.
-	{"or as if true", `{{or .SI "slice is empty"}}`, "[3 4 5]", tVal, true},
-	{"or as if false", `{{or .SIEmpty "slice is empty"}}`, "slice is empty", tVal, true},
-
-	// Error handling.
-	{"error method, error", "{{.MyError true}}", "", tVal, false},
-	{"error method, no error", "{{.MyError false}}", "false", tVal, true},
-
-	// Fixed bugs.
-	// Must separate dot and receiver; otherwise args are evaluated with dot set to variable.
-	{"bug0", "{{range .MSIone}}{{if $.Method1 .}}X{{end}}{{end}}", "X", tVal, true},
-	// Do not loop endlessly in indirect for non-empty interfaces.
-	// The bug appears with *interface only; looped forever.
-	{"bug1", "{{.Method0}}", "M0", &iVal, true},
-	// Was taking address of interface field, so method set was empty.
-	{"bug2", "{{$.NonEmptyInterface.Method0}}", "M0", tVal, true},
-	// Struct values were not legal in with - mere oversight.
-	{"bug3", "{{with $}}{{.Method0}}{{end}}", "M0", tVal, true},
-	// Nil interface values in if.
-	{"bug4", "{{if .Empty0}}non-nil{{else}}nil{{end}}", "nil", tVal, true},
-	// Stringer.
-	{"bug5", "{{.Str}}", "foozle", tVal, true},
-	{"bug5a", "{{.Err}}", "erroozle", tVal, true},
-	// Args need to be indirected and dereferenced sometimes.
-	{"bug6a", "{{vfunc .V0 .V1}}", "vfunc", tVal, true},
-	{"bug6b", "{{vfunc .V0 .V0}}", "vfunc", tVal, true},
-	{"bug6c", "{{vfunc .V1 .V0}}", "vfunc", tVal, true},
-	{"bug6d", "{{vfunc .V1 .V1}}", "vfunc", tVal, true},
-	// Legal parse but illegal execution: non-function should have no arguments.
-	{"bug7a", "{{3 2}}", "", tVal, false},
-	{"bug7b", "{{$x := 1}}{{$x 2}}", "", tVal, false},
-	{"bug7c", "{{$x := 1}}{{3 | $x}}", "", tVal, false},
-	// Pipelined arg was not being type-checked.
-	{"bug8a", "{{3|oneArg}}", "", tVal, false},
-	{"bug8b", "{{4|dddArg 3}}", "", tVal, false},
-	// A bug was introduced that broke map lookups for lower-case names.
-	{"bug9", "{{.cause}}", "neglect", map[string]string{"cause": "neglect"}, true},
-	// Field chain starting with function did not work.
-	{"bug10", "{{mapOfThree.three}}-{{(mapOfThree).three}}", "3-3", 0, true},
-	// Dereferencing nil pointer while evaluating function arguments should not panic. Issue 7333.
-	{"bug11", "{{valueString .PS}}", "", T{}, false},
-}
-
-func zeroArgs() string {
-	return "zeroArgs"
-}
-
-func oneArg(a string) string {
-	return "oneArg=" + a
-}
-
-func dddArg(a int, b ...string) string {
-	return fmt.Sprintln(a, b)
-}
-
-// count returns a channel that will deliver n sequential 1-letter strings starting at "a"
-func count(n int) chan string {
-	if n == 0 {
-		return nil
-	}
-	c := make(chan string)
-	go func() {
-		for i := 0; i < n; i++ {
-			c <- "abcdefghijklmnop"[i : i+1]
-		}
-		close(c)
-	}()
-	return c
-}
-
-// vfunc takes a *V and a V
-func vfunc(V, *V) string {
-	return "vfunc"
-}
-
-// valueString takes a string, not a pointer.
-func valueString(v string) string {
-	return "value is ignored"
-}
-
-func add(args ...int) int {
-	sum := 0
-	for _, x := range args {
-		sum += x
-	}
-	return sum
-}
-
-func echo(arg interface{}) interface{} {
-	return arg
-}
-
-func makemap(arg ...string) map[string]string {
-	if len(arg)%2 != 0 {
-		panic("bad makemap")
-	}
-	m := make(map[string]string)
-	for i := 0; i < len(arg); i += 2 {
-		m[arg[i]] = arg[i+1]
-	}
-	return m
-}
-
-func stringer(s fmt.Stringer) string {
-	return s.String()
-}
-
-func mapOfThree() interface{} {
-	return map[string]int{"three": 3}
-}
-
-func testExecute(execTests []execTest, template *Template, t *testing.T) {
-	b := new(bytes.Buffer)
-	funcs := FuncMap{
-		"add":         add,
-		"count":       count,
-		"dddArg":      dddArg,
-		"echo":        echo,
-		"makemap":     makemap,
-		"mapOfThree":  mapOfThree,
-		"oneArg":      oneArg,
-		"stringer":    stringer,
-		"typeOf":      typeOf,
-		"valueString": valueString,
-		"vfunc":       vfunc,
-		"zeroArgs":    zeroArgs,
-	}
-	for _, test := range execTests {
-		var tmpl *Template
-		var err error
-		if template == nil {
-			tmpl, err = New(test.name).Funcs(funcs).Parse(test.input)
-		} else {
-			tmpl, err = template.New(test.name).Funcs(funcs).Parse(test.input)
-		}
-		if err != nil {
-			t.Errorf("%s: parse error: %s", test.name, err)
-			continue
-		}
-		b.Reset()
-		err = tmpl.Execute(b, test.data)
-		switch {
-		case !test.ok && err == nil:
-			t.Errorf("%s: expected error; got none", test.name)
-			continue
-		case test.ok && err != nil:
-			t.Errorf("%s: unexpected execute error: %s", test.name, err)
-			continue
-		case !test.ok && err != nil:
-			// expected error, got one
-			if *debug {
-				fmt.Printf("%s: %s\n\t%s\n", test.name, test.input, err)
-			}
-		}
-		result := b.String()
-		if result != test.output {
-			t.Errorf("%s: expected\n\t%q\ngot\n\t%q", test.name, test.output, result)
-		}
-	}
-}
-
-func TestExecute(t *testing.T) {
-	testExecute(execTests, nil, t)
-}
-
-var delimPairs = []string{
-	"", "", // default
-	"{{", "}}", // same as default
-	"<<", ">>", // distinct
-	"|", "|", // same
-	"(日)", "(本)", // peculiar
-}
-
-func TestDelims(t *testing.T) {
-	const hello = "Hello, world"
-	var value = struct{ Str string }{hello}
-	for i := 0; i < len(delimPairs); i += 2 {
-		text := ".Str"
-		left := delimPairs[i+0]
-		trueLeft := left
-		right := delimPairs[i+1]
-		trueRight := right
-		if left == "" { // default case
-			trueLeft = "{{"
-		}
-		if right == "" { // default case
-			trueRight = "}}"
-		}
-		text = trueLeft + text + trueRight
-		// Now add a comment
-		text += trueLeft + "/*comment*/" + trueRight
-		// Now add  an action containing a string.
-		text += trueLeft + `"` + trueLeft + `"` + trueRight
-		// At this point text looks like `{{.Str}}{{/*comment*/}}{{"{{"}}`.
-		tmpl, err := New("delims").Delims(left, right).Parse(text)
-		if err != nil {
-			t.Fatalf("delim %q text %q parse err %s", left, text, err)
-		}
-		var b = new(bytes.Buffer)
-		err = tmpl.Execute(b, value)
-		if err != nil {
-			t.Fatalf("delim %q exec err %s", left, err)
-		}
-		if b.String() != hello+trueLeft {
-			t.Errorf("expected %q got %q", hello+trueLeft, b.String())
-		}
-	}
-}
-
-// Check that an error from a method flows back to the top.
-func TestExecuteError(t *testing.T) {
-	b := new(bytes.Buffer)
-	tmpl := New("error")
-	_, err := tmpl.Parse("{{.MyError true}}")
-	if err != nil {
-		t.Fatalf("parse error: %s", err)
-	}
-	err = tmpl.Execute(b, tVal)
-	if err == nil {
-		t.Errorf("expected error; got none")
-	} else if !strings.Contains(err.Error(), myError.Error()) {
-		if *debug {
-			fmt.Printf("test execute error: %s\n", err)
-		}
-		t.Errorf("expected myError; got %s", err)
-	}
-}
-
-const execErrorText = `line 1
-line 2
-line 3
-{{template "one" .}}
-{{define "one"}}{{template "two" .}}{{end}}
-{{define "two"}}{{template "three" .}}{{end}}
-{{define "three"}}{{index "hi" $}}{{end}}`
-
-// Check that an error from a nested template contains all the relevant information.
-func TestExecError(t *testing.T) {
-	tmpl, err := New("top").Parse(execErrorText)
-	if err != nil {
-		t.Fatal("parse error:", err)
-	}
-	var b bytes.Buffer
-	err = tmpl.Execute(&b, 5) // 5 is out of range indexing "hi"
-	if err == nil {
-		t.Fatal("expected error")
-	}
-	const want = `template: top:7:20: executing "three" at <index "hi" $>: error calling index: index out of range: 5`
-	got := err.Error()
-	if got != want {
-		t.Errorf("expected\n%q\ngot\n%q", want, got)
-	}
-}
-
-func TestJSEscaping(t *testing.T) {
-	testCases := []struct {
-		in, exp string
-	}{
-		{`a`, `a`},
-		{`'foo`, `\'foo`},
-		{`Go "jump" \`, `Go \"jump\" \\`},
-		{`Yukihiro says "今日は世界"`, `Yukihiro says \"今日は世界\"`},
-		{"unprintable \uFDFF", `unprintable \uFDFF`},
-		{`<html>`, `\x3Chtml\x3E`},
-	}
-	for _, tc := range testCases {
-		s := JSEscapeString(tc.in)
-		if s != tc.exp {
-			t.Errorf("JS escaping [%s] got [%s] want [%s]", tc.in, s, tc.exp)
-		}
-	}
-}
-
-// A nice example: walk a binary tree.
-
-type Tree struct {
-	Val         int
-	Left, Right *Tree
-}
-
-// Use different delimiters to test Set.Delims.
-const treeTemplate = `
-	(define "tree")
-	[
-		(.Val)
-		(with .Left)
-			(template "tree" .)
-		(end)
-		(with .Right)
-			(template "tree" .)
-		(end)
-	]
-	(end)
-`
-
-func TestTree(t *testing.T) {
-	var tree = &Tree{
-		1,
-		&Tree{
-			2, &Tree{
-				3,
-				&Tree{
-					4, nil, nil,
-				},
-				nil,
-			},
-			&Tree{
-				5,
-				&Tree{
-					6, nil, nil,
-				},
-				nil,
-			},
-		},
-		&Tree{
-			7,
-			&Tree{
-				8,
-				&Tree{
-					9, nil, nil,
-				},
-				nil,
-			},
-			&Tree{
-				10,
-				&Tree{
-					11, nil, nil,
-				},
-				nil,
-			},
-		},
-	}
-	tmpl, err := New("root").Delims("(", ")").Parse(treeTemplate)
-	if err != nil {
-		t.Fatal("parse error:", err)
-	}
-	var b bytes.Buffer
-	stripSpace := func(r rune) rune {
-		if r == '\t' || r == '\n' {
-			return -1
-		}
-		return r
-	}
-	const expect = "[1[2[3[4]][5[6]]][7[8[9]][10[11]]]]"
-	// First by looking up the template.
-	err = tmpl.Lookup("tree").Execute(&b, tree)
-	if err != nil {
-		t.Fatal("exec error:", err)
-	}
-	result := strings.Map(stripSpace, b.String())
-	if result != expect {
-		t.Errorf("expected %q got %q", expect, result)
-	}
-	// Then direct to execution.
-	b.Reset()
-	err = tmpl.ExecuteTemplate(&b, "tree", tree)
-	if err != nil {
-		t.Fatal("exec error:", err)
-	}
-	result = strings.Map(stripSpace, b.String())
-	if result != expect {
-		t.Errorf("expected %q got %q", expect, result)
-	}
-}
-
-func TestExecuteOnNewTemplate(t *testing.T) {
-	// This is issue 3872.
-	_ = New("Name").Templates()
-}
-
-const testTemplates = `{{define "one"}}one{{end}}{{define "two"}}two{{end}}`
-
-func TestMessageForExecuteEmpty(t *testing.T) {
-	// Test a truly empty template.
-	tmpl := New("empty")
-	var b bytes.Buffer
-	err := tmpl.Execute(&b, 0)
-	if err == nil {
-		t.Fatal("expected initial error")
-	}
-	got := err.Error()
-	want := `template: empty: "empty" is an incomplete or empty template`
-	if got != want {
-		t.Errorf("expected error %s got %s", want, got)
-	}
-	// Add a non-empty template to check that the error is helpful.
-	tests, err := New("").Parse(testTemplates)
-	if err != nil {
-		t.Fatal(err)
-	}
-	tmpl.AddParseTree("secondary", tests.Tree)
-	err = tmpl.Execute(&b, 0)
-	if err == nil {
-		t.Fatal("expected second error")
-	}
-	got = err.Error()
-	want = `template: empty: "empty" is an incomplete or empty template; defined templates are: "secondary"`
-	if got != want {
-		t.Errorf("expected error %s got %s", want, got)
-	}
-	// Make sure we can execute the secondary.
-	err = tmpl.ExecuteTemplate(&b, "secondary", 0)
-	if err != nil {
-		t.Fatal(err)
-	}
-}
-
-type cmpTest struct {
-	expr  string
-	truth string
-	ok    bool
-}
-
-var cmpTests = []cmpTest{
-	{"eq true true", "true", true},
-	{"eq true false", "false", true},
-	{"eq 1+2i 1+2i", "true", true},
-	{"eq 1+2i 1+3i", "false", true},
-	{"eq 1.5 1.5", "true", true},
-	{"eq 1.5 2.5", "false", true},
-	{"eq 1 1", "true", true},
-	{"eq 1 2", "false", true},
-	{"eq `xy` `xy`", "true", true},
-	{"eq `xy` `xyz`", "false", true},
-	{"eq .Xuint .Xuint", "true", true},
-	{"eq .Xuint .Yuint", "false", true},
-	{"eq 3 4 5 6 3", "true", true},
-	{"eq 3 4 5 6 7", "false", true},
-	{"ne true true", "false", true},
-	{"ne true false", "true", true},
-	{"ne 1+2i 1+2i", "false", true},
-	{"ne 1+2i 1+3i", "true", true},
-	{"ne 1.5 1.5", "false", true},
-	{"ne 1.5 2.5", "true", true},
-	{"ne 1 1", "false", true},
-	{"ne 1 2", "true", true},
-	{"ne `xy` `xy`", "false", true},
-	{"ne `xy` `xyz`", "true", true},
-	{"ne .Xuint .Xuint", "false", true},
-	{"ne .Xuint .Yuint", "true", true},
-	{"lt 1.5 1.5", "false", true},
-	{"lt 1.5 2.5", "true", true},
-	{"lt 1 1", "false", true},
-	{"lt 1 2", "true", true},
-	{"lt `xy` `xy`", "false", true},
-	{"lt `xy` `xyz`", "true", true},
-	{"lt .Xuint .Xuint", "false", true},
-	{"lt .Xuint .Yuint", "true", true},
-	{"le 1.5 1.5", "true", true},
-	{"le 1.5 2.5", "true", true},
-	{"le 2.5 1.5", "false", true},
-	{"le 1 1", "true", true},
-	{"le 1 2", "true", true},
-	{"le 2 1", "false", true},
-	{"le `xy` `xy`", "true", true},
-	{"le `xy` `xyz`", "true", true},
-	{"le `xyz` `xy`", "false", true},
-	{"le .Xuint .Xuint", "true", true},
-	{"le .Xuint .Yuint", "true", true},
-	{"le .Yuint .Xuint", "false", true},
-	{"gt 1.5 1.5", "false", true},
-	{"gt 1.5 2.5", "false", true},
-	{"gt 1 1", "false", true},
-	{"gt 2 1", "true", true},
-	{"gt 1 2", "false", true},
-	{"gt `xy` `xy`", "false", true},
-	{"gt `xy` `xyz`", "false", true},
-	{"gt .Xuint .Xuint", "false", true},
-	{"gt .Xuint .Yuint", "false", true},
-	{"gt .Yuint .Xuint", "true", true},
-	{"ge 1.5 1.5", "true", true},
-	{"ge 1.5 2.5", "false", true},
-	{"ge 2.5 1.5", "true", true},
-	{"ge 1 1", "true", true},
-	{"ge 1 2", "false", true},
-	{"ge 2 1", "true", true},
-	{"ge `xy` `xy`", "true", true},
-	{"ge `xy` `xyz`", "false", true},
-	{"ge `xyz` `xy`", "true", true},
-	{"ge .Xuint .Xuint", "true", true},
-	{"ge .Xuint .Yuint", "false", true},
-	{"ge .Yuint .Xuint", "true", true},
-	// Errors
-	{"eq `xy` 1", "", false},    // Different types.
-	{"lt true true", "", false}, // Unordered types.
-	{"lt 1+0i 1+0i", "", false}, // Unordered types.
-}
-
-func TestComparison(t *testing.T) {
-	b := new(bytes.Buffer)
-	var cmpStruct = struct {
-		Xuint, Yuint uint
-	}{3, 4}
-	for _, test := range cmpTests {
-		text := fmt.Sprintf("{{if %s}}true{{else}}false{{end}}", test.expr)
-		tmpl, err := New("empty").Parse(text)
-		if err != nil {
-			t.Fatal(err)
-		}
-		b.Reset()
-		err = tmpl.Execute(b, &cmpStruct)
-		if test.ok && err != nil {
-			t.Errorf("%s errored incorrectly: %s", test.expr, err)
-			continue
-		}
-		if !test.ok && err == nil {
-			t.Errorf("%s did not error", test.expr)
-			continue
-		}
-		if b.String() != test.truth {
-			t.Errorf("%s: want %s; got %s", test.expr, test.truth, b.String())
-		}
-	}
-}
diff --git a/src/pkg/text/template/funcs.go b/src/pkg/text/template/funcs.go
deleted file mode 100644
index e854122..0000000
--- a/src/pkg/text/template/funcs.go
+++ /dev/null
@@ -1,580 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package template
-
-import (
-	"bytes"
-	"errors"
-	"fmt"
-	"io"
-	"net/url"
-	"reflect"
-	"strings"
-	"unicode"
-	"unicode/utf8"
-)
-
-// FuncMap is the type of the map defining the mapping from names to functions.
-// Each function must have either a single return value, or two return values of
-// which the second has type error. In that case, if the second (error)
-// return value evaluates to non-nil during execution, execution terminates and
-// Execute returns that error.
-type FuncMap map[string]interface{}
-
-var builtins = FuncMap{
-	"and":      and,
-	"call":     call,
-	"html":     HTMLEscaper,
-	"index":    index,
-	"js":       JSEscaper,
-	"len":      length,
-	"not":      not,
-	"or":       or,
-	"print":    fmt.Sprint,
-	"printf":   fmt.Sprintf,
-	"println":  fmt.Sprintln,
-	"urlquery": URLQueryEscaper,
-
-	// Comparisons
-	"eq": eq, // ==
-	"ge": ge, // >=
-	"gt": gt, // >
-	"le": le, // <=
-	"lt": lt, // <
-	"ne": ne, // !=
-}
-
-var builtinFuncs = createValueFuncs(builtins)
-
-// createValueFuncs turns a FuncMap into a map[string]reflect.Value
-func createValueFuncs(funcMap FuncMap) map[string]reflect.Value {
-	m := make(map[string]reflect.Value)
-	addValueFuncs(m, funcMap)
-	return m
-}
-
-// addValueFuncs adds to values the functions in funcs, converting them to reflect.Values.
-func addValueFuncs(out map[string]reflect.Value, in FuncMap) {
-	for name, fn := range in {
-		v := reflect.ValueOf(fn)
-		if v.Kind() != reflect.Func {
-			panic("value for " + name + " not a function")
-		}
-		if !goodFunc(v.Type()) {
-			panic(fmt.Errorf("can't install method/function %q with %d results", name, v.Type().NumOut()))
-		}
-		out[name] = v
-	}
-}
-
-// addFuncs adds to values the functions in funcs. It does no checking of the input -
-// call addValueFuncs first.
-func addFuncs(out, in FuncMap) {
-	for name, fn := range in {
-		out[name] = fn
-	}
-}
-
-// goodFunc checks that the function or method has the right result signature.
-func goodFunc(typ reflect.Type) bool {
-	// We allow functions with 1 result or 2 results where the second is an error.
-	switch {
-	case typ.NumOut() == 1:
-		return true
-	case typ.NumOut() == 2 && typ.Out(1) == errorType:
-		return true
-	}
-	return false
-}
-
-// findFunction looks for a function in the template, and global map.
-func findFunction(name string, tmpl *Template) (reflect.Value, bool) {
-	if tmpl != nil && tmpl.common != nil {
-		if fn := tmpl.execFuncs[name]; fn.IsValid() {
-			return fn, true
-		}
-	}
-	if fn := builtinFuncs[name]; fn.IsValid() {
-		return fn, true
-	}
-	return reflect.Value{}, false
-}
-
-// Indexing.
-
-// index returns the result of indexing its first argument by the following
-// arguments.  Thus "index x 1 2 3" is, in Go syntax, x[1][2][3]. Each
-// indexed item must be a map, slice, or array.
-func index(item interface{}, indices ...interface{}) (interface{}, error) {
-	v := reflect.ValueOf(item)
-	for _, i := range indices {
-		index := reflect.ValueOf(i)
-		var isNil bool
-		if v, isNil = indirect(v); isNil {
-			return nil, fmt.Errorf("index of nil pointer")
-		}
-		switch v.Kind() {
-		case reflect.Array, reflect.Slice, reflect.String:
-			var x int64
-			switch index.Kind() {
-			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-				x = index.Int()
-			case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
-				x = int64(index.Uint())
-			default:
-				return nil, fmt.Errorf("cannot index slice/array with type %s", index.Type())
-			}
-			if x < 0 || x >= int64(v.Len()) {
-				return nil, fmt.Errorf("index out of range: %d", x)
-			}
-			v = v.Index(int(x))
-		case reflect.Map:
-			if !index.IsValid() {
-				index = reflect.Zero(v.Type().Key())
-			}
-			if !index.Type().AssignableTo(v.Type().Key()) {
-				return nil, fmt.Errorf("%s is not index type for %s", index.Type(), v.Type())
-			}
-			if x := v.MapIndex(index); x.IsValid() {
-				v = x
-			} else {
-				v = reflect.Zero(v.Type().Elem())
-			}
-		default:
-			return nil, fmt.Errorf("can't index item of type %s", v.Type())
-		}
-	}
-	return v.Interface(), nil
-}
-
-// Length
-
-// length returns the length of the item, with an error if it has no defined length.
-func length(item interface{}) (int, error) {
-	v, isNil := indirect(reflect.ValueOf(item))
-	if isNil {
-		return 0, fmt.Errorf("len of nil pointer")
-	}
-	switch v.Kind() {
-	case reflect.Array, reflect.Chan, reflect.Map, reflect.Slice, reflect.String:
-		return v.Len(), nil
-	}
-	return 0, fmt.Errorf("len of type %s", v.Type())
-}
-
-// Function invocation
-
-// call returns the result of evaluating the first argument as a function.
-// The function must return 1 result, or 2 results, the second of which is an error.
-func call(fn interface{}, args ...interface{}) (interface{}, error) {
-	v := reflect.ValueOf(fn)
-	typ := v.Type()
-	if typ.Kind() != reflect.Func {
-		return nil, fmt.Errorf("non-function of type %s", typ)
-	}
-	if !goodFunc(typ) {
-		return nil, fmt.Errorf("function called with %d args; should be 1 or 2", typ.NumOut())
-	}
-	numIn := typ.NumIn()
-	var dddType reflect.Type
-	if typ.IsVariadic() {
-		if len(args) < numIn-1 {
-			return nil, fmt.Errorf("wrong number of args: got %d want at least %d", len(args), numIn-1)
-		}
-		dddType = typ.In(numIn - 1).Elem()
-	} else {
-		if len(args) != numIn {
-			return nil, fmt.Errorf("wrong number of args: got %d want %d", len(args), numIn)
-		}
-	}
-	argv := make([]reflect.Value, len(args))
-	for i, arg := range args {
-		value := reflect.ValueOf(arg)
-		// Compute the expected type. Clumsy because of variadics.
-		var argType reflect.Type
-		if !typ.IsVariadic() || i < numIn-1 {
-			argType = typ.In(i)
-		} else {
-			argType = dddType
-		}
-		if !value.IsValid() && canBeNil(argType) {
-			value = reflect.Zero(argType)
-		}
-		if !value.Type().AssignableTo(argType) {
-			return nil, fmt.Errorf("arg %d has type %s; should be %s", i, value.Type(), argType)
-		}
-		argv[i] = value
-	}
-	result := v.Call(argv)
-	if len(result) == 2 && !result[1].IsNil() {
-		return result[0].Interface(), result[1].Interface().(error)
-	}
-	return result[0].Interface(), nil
-}
-
-// Boolean logic.
-
-func truth(a interface{}) bool {
-	t, _ := isTrue(reflect.ValueOf(a))
-	return t
-}
-
-// and computes the Boolean AND of its arguments, returning
-// the first false argument it encounters, or the last argument.
-func and(arg0 interface{}, args ...interface{}) interface{} {
-	if !truth(arg0) {
-		return arg0
-	}
-	for i := range args {
-		arg0 = args[i]
-		if !truth(arg0) {
-			break
-		}
-	}
-	return arg0
-}
-
-// or computes the Boolean OR of its arguments, returning
-// the first true argument it encounters, or the last argument.
-func or(arg0 interface{}, args ...interface{}) interface{} {
-	if truth(arg0) {
-		return arg0
-	}
-	for i := range args {
-		arg0 = args[i]
-		if truth(arg0) {
-			break
-		}
-	}
-	return arg0
-}
-
-// not returns the Boolean negation of its argument.
-func not(arg interface{}) (truth bool) {
-	truth, _ = isTrue(reflect.ValueOf(arg))
-	return !truth
-}
-
-// Comparison.
-
-// TODO: Perhaps allow comparison between signed and unsigned integers.
-
-var (
-	errBadComparisonType = errors.New("invalid type for comparison")
-	errBadComparison     = errors.New("incompatible types for comparison")
-	errNoComparison      = errors.New("missing argument for comparison")
-)
-
-type kind int
-
-const (
-	invalidKind kind = iota
-	boolKind
-	complexKind
-	intKind
-	floatKind
-	integerKind
-	stringKind
-	uintKind
-)
-
-func basicKind(v reflect.Value) (kind, error) {
-	switch v.Kind() {
-	case reflect.Bool:
-		return boolKind, nil
-	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-		return intKind, nil
-	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
-		return uintKind, nil
-	case reflect.Float32, reflect.Float64:
-		return floatKind, nil
-	case reflect.Complex64, reflect.Complex128:
-		return complexKind, nil
-	case reflect.String:
-		return stringKind, nil
-	}
-	return invalidKind, errBadComparisonType
-}
-
-// eq evaluates the comparison a == b || a == c || ...
-func eq(arg1 interface{}, arg2 ...interface{}) (bool, error) {
-	v1 := reflect.ValueOf(arg1)
-	k1, err := basicKind(v1)
-	if err != nil {
-		return false, err
-	}
-	if len(arg2) == 0 {
-		return false, errNoComparison
-	}
-	for _, arg := range arg2 {
-		v2 := reflect.ValueOf(arg)
-		k2, err := basicKind(v2)
-		if err != nil {
-			return false, err
-		}
-		if k1 != k2 {
-			return false, errBadComparison
-		}
-		truth := false
-		switch k1 {
-		case boolKind:
-			truth = v1.Bool() == v2.Bool()
-		case complexKind:
-			truth = v1.Complex() == v2.Complex()
-		case floatKind:
-			truth = v1.Float() == v2.Float()
-		case intKind:
-			truth = v1.Int() == v2.Int()
-		case stringKind:
-			truth = v1.String() == v2.String()
-		case uintKind:
-			truth = v1.Uint() == v2.Uint()
-		default:
-			panic("invalid kind")
-		}
-		if truth {
-			return true, nil
-		}
-	}
-	return false, nil
-}
-
-// ne evaluates the comparison a != b.
-func ne(arg1, arg2 interface{}) (bool, error) {
-	// != is the inverse of ==.
-	equal, err := eq(arg1, arg2)
-	return !equal, err
-}
-
-// lt evaluates the comparison a < b.
-func lt(arg1, arg2 interface{}) (bool, error) {
-	v1 := reflect.ValueOf(arg1)
-	k1, err := basicKind(v1)
-	if err != nil {
-		return false, err
-	}
-	v2 := reflect.ValueOf(arg2)
-	k2, err := basicKind(v2)
-	if err != nil {
-		return false, err
-	}
-	if k1 != k2 {
-		return false, errBadComparison
-	}
-	truth := false
-	switch k1 {
-	case boolKind, complexKind:
-		return false, errBadComparisonType
-	case floatKind:
-		truth = v1.Float() < v2.Float()
-	case intKind:
-		truth = v1.Int() < v2.Int()
-	case stringKind:
-		truth = v1.String() < v2.String()
-	case uintKind:
-		truth = v1.Uint() < v2.Uint()
-	default:
-		panic("invalid kind")
-	}
-	return truth, nil
-}
-
-// le evaluates the comparison <= b.
-func le(arg1, arg2 interface{}) (bool, error) {
-	// <= is < or ==.
-	lessThan, err := lt(arg1, arg2)
-	if lessThan || err != nil {
-		return lessThan, err
-	}
-	return eq(arg1, arg2)
-}
-
-// gt evaluates the comparison a > b.
-func gt(arg1, arg2 interface{}) (bool, error) {
-	// > is the inverse of <=.
-	lessOrEqual, err := le(arg1, arg2)
-	if err != nil {
-		return false, err
-	}
-	return !lessOrEqual, nil
-}
-
-// ge evaluates the comparison a >= b.
-func ge(arg1, arg2 interface{}) (bool, error) {
-	// >= is the inverse of <.
-	lessThan, err := lt(arg1, arg2)
-	if err != nil {
-		return false, err
-	}
-	return !lessThan, nil
-}
-
-// HTML escaping.
-
-var (
-	htmlQuot = []byte(""") // shorter than """
-	htmlApos = []byte("'") // shorter than "'" and apos was not in HTML until HTML5
-	htmlAmp  = []byte("&")
-	htmlLt   = []byte("<")
-	htmlGt   = []byte(">")
-)
-
-// HTMLEscape writes to w the escaped HTML equivalent of the plain text data b.
-func HTMLEscape(w io.Writer, b []byte) {
-	last := 0
-	for i, c := range b {
-		var html []byte
-		switch c {
-		case '"':
-			html = htmlQuot
-		case '\'':
-			html = htmlApos
-		case '&':
-			html = htmlAmp
-		case '<':
-			html = htmlLt
-		case '>':
-			html = htmlGt
-		default:
-			continue
-		}
-		w.Write(b[last:i])
-		w.Write(html)
-		last = i + 1
-	}
-	w.Write(b[last:])
-}
-
-// 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 {
-		return s
-	}
-	var b bytes.Buffer
-	HTMLEscape(&b, []byte(s))
-	return b.String()
-}
-
-// HTMLEscaper returns the escaped HTML equivalent of the textual
-// representation of its arguments.
-func HTMLEscaper(args ...interface{}) string {
-	return HTMLEscapeString(evalArgs(args))
-}
-
-// JavaScript escaping.
-
-var (
-	jsLowUni = []byte(`\u00`)
-	hex      = []byte("0123456789ABCDEF")
-
-	jsBackslash = []byte(`\\`)
-	jsApos      = []byte(`\'`)
-	jsQuot      = []byte(`\"`)
-	jsLt        = []byte(`\x3C`)
-	jsGt        = []byte(`\x3E`)
-)
-
-// JSEscape writes to w the escaped JavaScript equivalent of the plain text data b.
-func JSEscape(w io.Writer, b []byte) {
-	last := 0
-	for i := 0; i < len(b); i++ {
-		c := b[i]
-
-		if !jsIsSpecial(rune(c)) {
-			// fast path: nothing to do
-			continue
-		}
-		w.Write(b[last:i])
-
-		if c < utf8.RuneSelf {
-			// Quotes, slashes and angle brackets get quoted.
-			// Control characters get written as \u00XX.
-			switch c {
-			case '\\':
-				w.Write(jsBackslash)
-			case '\'':
-				w.Write(jsApos)
-			case '"':
-				w.Write(jsQuot)
-			case '<':
-				w.Write(jsLt)
-			case '>':
-				w.Write(jsGt)
-			default:
-				w.Write(jsLowUni)
-				t, b := c>>4, c&0x0f
-				w.Write(hex[t : t+1])
-				w.Write(hex[b : b+1])
-			}
-		} else {
-			// Unicode rune.
-			r, size := utf8.DecodeRune(b[i:])
-			if unicode.IsPrint(r) {
-				w.Write(b[i : i+size])
-			} else {
-				fmt.Fprintf(w, "\\u%04X", r)
-			}
-			i += size - 1
-		}
-		last = i + 1
-	}
-	w.Write(b[last:])
-}
-
-// JSEscapeString returns the escaped JavaScript equivalent of the plain text data s.
-func JSEscapeString(s string) string {
-	// Avoid allocation if we can.
-	if strings.IndexFunc(s, jsIsSpecial) < 0 {
-		return s
-	}
-	var b bytes.Buffer
-	JSEscape(&b, []byte(s))
-	return b.String()
-}
-
-func jsIsSpecial(r rune) bool {
-	switch r {
-	case '\\', '\'', '"', '<', '>':
-		return true
-	}
-	return r < ' ' || utf8.RuneSelf <= r
-}
-
-// JSEscaper returns the escaped JavaScript equivalent of the textual
-// representation of its arguments.
-func JSEscaper(args ...interface{}) string {
-	return JSEscapeString(evalArgs(args))
-}
-
-// URLQueryEscaper returns the escaped value of the textual representation of
-// its arguments in a form suitable for embedding in a URL query.
-func URLQueryEscaper(args ...interface{}) string {
-	return url.QueryEscape(evalArgs(args))
-}
-
-// evalArgs formats the list of arguments into a string. It is therefore equivalent to
-//	fmt.Sprint(args...)
-// except that each argument is indirected (if a pointer), as required,
-// using the same rules as the default string evaluation during template
-// execution.
-func evalArgs(args []interface{}) string {
-	ok := false
-	var s string
-	// Fast path for simple common case.
-	if len(args) == 1 {
-		s, ok = args[0].(string)
-	}
-	if !ok {
-		for i, arg := range args {
-			a, ok := printableValue(reflect.ValueOf(arg))
-			if ok {
-				args[i] = a
-			} // else left fmt do its thing
-		}
-		s = fmt.Sprint(args...)
-	}
-	return s
-}
diff --git a/src/pkg/text/template/parse/node.go b/src/pkg/text/template/parse/node.go
deleted file mode 100644
index dc6a3bb..0000000
--- a/src/pkg/text/template/parse/node.go
+++ /dev/null
@@ -1,722 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Parse nodes.
-
-package parse
-
-import (
-	"bytes"
-	"fmt"
-	"strconv"
-	"strings"
-)
-
-var textFormat = "%s" // Changed to "%q" in tests for better error messages.
-
-// A Node is an element in the parse tree. The interface is trivial.
-// The interface contains an unexported method so that only
-// types local to this package can satisfy it.
-type Node interface {
-	Type() NodeType
-	String() string
-	// Copy does a deep copy of the Node and all its components.
-	// To avoid type assertions, some XxxNodes also have specialized
-	// CopyXxx methods that return *XxxNode.
-	Copy() Node
-	Position() Pos // byte position of start of node in full original input string
-	// Make sure only functions in this package can create Nodes.
-	unexported()
-}
-
-// NodeType identifies the type of a parse tree node.
-type NodeType int
-
-// Pos represents a byte position in the original input text from which
-// this template was parsed.
-type Pos int
-
-func (p Pos) Position() Pos {
-	return p
-}
-
-// unexported keeps Node implementations local to the package.
-// All implementations embed Pos, so this takes care of it.
-func (Pos) unexported() {
-}
-
-// Type returns itself and provides an easy default implementation
-// for embedding in a Node. Embedded in all non-trivial Nodes.
-func (t NodeType) Type() NodeType {
-	return t
-}
-
-const (
-	NodeText       NodeType = iota // Plain text.
-	NodeAction                     // A non-control action such as a field evaluation.
-	NodeBool                       // A boolean constant.
-	NodeChain                      // A sequence of field accesses.
-	NodeCommand                    // An element of a pipeline.
-	NodeDot                        // The cursor, dot.
-	nodeElse                       // An else action. Not added to tree.
-	nodeEnd                        // An end action. Not added to tree.
-	NodeField                      // A field or method name.
-	NodeIdentifier                 // An identifier; always a function name.
-	NodeIf                         // An if action.
-	NodeList                       // A list of Nodes.
-	NodeNil                        // An untyped nil constant.
-	NodeNumber                     // A numerical constant.
-	NodePipe                       // A pipeline of commands.
-	NodeRange                      // A range action.
-	NodeString                     // A string constant.
-	NodeTemplate                   // A template invocation action.
-	NodeVariable                   // A $ variable.
-	NodeWith                       // A with action.
-)
-
-// Nodes.
-
-// ListNode holds a sequence of nodes.
-type ListNode struct {
-	NodeType
-	Pos
-	Nodes []Node // The element nodes in lexical order.
-}
-
-func newList(pos Pos) *ListNode {
-	return &ListNode{NodeType: NodeList, Pos: pos}
-}
-
-func (l *ListNode) append(n Node) {
-	l.Nodes = append(l.Nodes, n)
-}
-
-func (l *ListNode) String() string {
-	b := new(bytes.Buffer)
-	for _, n := range l.Nodes {
-		fmt.Fprint(b, n)
-	}
-	return b.String()
-}
-
-func (l *ListNode) CopyList() *ListNode {
-	if l == nil {
-		return l
-	}
-	n := newList(l.Pos)
-	for _, elem := range l.Nodes {
-		n.append(elem.Copy())
-	}
-	return n
-}
-
-func (l *ListNode) Copy() Node {
-	return l.CopyList()
-}
-
-// TextNode holds plain text.
-type TextNode struct {
-	NodeType
-	Pos
-	Text []byte // The text; may span newlines.
-}
-
-func newText(pos Pos, text string) *TextNode {
-	return &TextNode{NodeType: NodeText, Pos: pos, Text: []byte(text)}
-}
-
-func (t *TextNode) String() string {
-	return fmt.Sprintf(textFormat, t.Text)
-}
-
-func (t *TextNode) Copy() Node {
-	return &TextNode{NodeType: NodeText, Text: append([]byte{}, t.Text...)}
-}
-
-// PipeNode holds a pipeline with optional declaration
-type PipeNode struct {
-	NodeType
-	Pos
-	Line int             // The line number in the input (deprecated; kept for compatibility)
-	Decl []*VariableNode // Variable declarations in lexical order.
-	Cmds []*CommandNode  // The commands in lexical order.
-}
-
-func newPipeline(pos Pos, line int, decl []*VariableNode) *PipeNode {
-	return &PipeNode{NodeType: NodePipe, Pos: pos, Line: line, Decl: decl}
-}
-
-func (p *PipeNode) append(command *CommandNode) {
-	p.Cmds = append(p.Cmds, command)
-}
-
-func (p *PipeNode) String() string {
-	s := ""
-	if len(p.Decl) > 0 {
-		for i, v := range p.Decl {
-			if i > 0 {
-				s += ", "
-			}
-			s += v.String()
-		}
-		s += " := "
-	}
-	for i, c := range p.Cmds {
-		if i > 0 {
-			s += " | "
-		}
-		s += c.String()
-	}
-	return s
-}
-
-func (p *PipeNode) CopyPipe() *PipeNode {
-	if p == nil {
-		return p
-	}
-	var decl []*VariableNode
-	for _, d := range p.Decl {
-		decl = append(decl, d.Copy().(*VariableNode))
-	}
-	n := newPipeline(p.Pos, p.Line, decl)
-	for _, c := range p.Cmds {
-		n.append(c.Copy().(*CommandNode))
-	}
-	return n
-}
-
-func (p *PipeNode) Copy() Node {
-	return p.CopyPipe()
-}
-
-// ActionNode holds an action (something bounded by delimiters).
-// Control actions have their own nodes; ActionNode represents simple
-// ones such as field evaluations and parenthesized pipelines.
-type ActionNode struct {
-	NodeType
-	Pos
-	Line int       // The line number in the input (deprecated; kept for compatibility)
-	Pipe *PipeNode // The pipeline in the action.
-}
-
-func newAction(pos Pos, line int, pipe *PipeNode) *ActionNode {
-	return &ActionNode{NodeType: NodeAction, Pos: pos, Line: line, Pipe: pipe}
-}
-
-func (a *ActionNode) String() string {
-	return fmt.Sprintf("{{%s}}", a.Pipe)
-
-}
-
-func (a *ActionNode) Copy() Node {
-	return newAction(a.Pos, a.Line, a.Pipe.CopyPipe())
-
-}
-
-// CommandNode holds a command (a pipeline inside an evaluating action).
-type CommandNode struct {
-	NodeType
-	Pos
-	Args []Node // Arguments in lexical order: Identifier, field, or constant.
-}
-
-func newCommand(pos Pos) *CommandNode {
-	return &CommandNode{NodeType: NodeCommand, Pos: pos}
-}
-
-func (c *CommandNode) append(arg Node) {
-	c.Args = append(c.Args, arg)
-}
-
-func (c *CommandNode) String() string {
-	s := ""
-	for i, arg := range c.Args {
-		if i > 0 {
-			s += " "
-		}
-		if arg, ok := arg.(*PipeNode); ok {
-			s += "(" + arg.String() + ")"
-			continue
-		}
-		s += arg.String()
-	}
-	return s
-}
-
-func (c *CommandNode) Copy() Node {
-	if c == nil {
-		return c
-	}
-	n := newCommand(c.Pos)
-	for _, c := range c.Args {
-		n.append(c.Copy())
-	}
-	return n
-}
-
-// IdentifierNode holds an identifier.
-type IdentifierNode struct {
-	NodeType
-	Pos
-	Ident string // The identifier's name.
-}
-
-// NewIdentifier returns a new IdentifierNode with the given identifier name.
-func NewIdentifier(ident string) *IdentifierNode {
-	return &IdentifierNode{NodeType: NodeIdentifier, Ident: ident}
-}
-
-// SetPos sets the position. NewIdentifier is a public method so we can't modify its signature.
-// Chained for convenience.
-// TODO: fix one day?
-func (i *IdentifierNode) SetPos(pos Pos) *IdentifierNode {
-	i.Pos = pos
-	return i
-}
-
-func (i *IdentifierNode) String() string {
-	return i.Ident
-}
-
-func (i *IdentifierNode) Copy() Node {
-	return NewIdentifier(i.Ident).SetPos(i.Pos)
-}
-
-// VariableNode holds a list of variable names, possibly with chained field
-// accesses. The dollar sign is part of the (first) name.
-type VariableNode struct {
-	NodeType
-	Pos
-	Ident []string // Variable name and fields in lexical order.
-}
-
-func newVariable(pos Pos, ident string) *VariableNode {
-	return &VariableNode{NodeType: NodeVariable, Pos: pos, Ident: strings.Split(ident, ".")}
-}
-
-func (v *VariableNode) String() string {
-	s := ""
-	for i, id := range v.Ident {
-		if i > 0 {
-			s += "."
-		}
-		s += id
-	}
-	return s
-}
-
-func (v *VariableNode) Copy() Node {
-	return &VariableNode{NodeType: NodeVariable, Pos: v.Pos, Ident: append([]string{}, v.Ident...)}
-}
-
-// DotNode holds the special identifier '.'.
-type DotNode struct {
-	Pos
-}
-
-func newDot(pos Pos) *DotNode {
-	return &DotNode{Pos: pos}
-}
-
-func (d *DotNode) Type() NodeType {
-	return NodeDot
-}
-
-func (d *DotNode) String() string {
-	return "."
-}
-
-func (d *DotNode) Copy() Node {
-	return newDot(d.Pos)
-}
-
-// NilNode holds the special identifier 'nil' representing an untyped nil constant.
-type NilNode struct {
-	Pos
-}
-
-func newNil(pos Pos) *NilNode {
-	return &NilNode{Pos: pos}
-}
-
-func (n *NilNode) Type() NodeType {
-	return NodeNil
-}
-
-func (n *NilNode) String() string {
-	return "nil"
-}
-
-func (n *NilNode) Copy() Node {
-	return newNil(n.Pos)
-}
-
-// FieldNode holds a field (identifier starting with '.').
-// The names may be chained ('.x.y').
-// The period is dropped from each ident.
-type FieldNode struct {
-	NodeType
-	Pos
-	Ident []string // The identifiers in lexical order.
-}
-
-func newField(pos Pos, ident string) *FieldNode {
-	return &FieldNode{NodeType: NodeField, Pos: pos, Ident: strings.Split(ident[1:], ".")} // [1:] to drop leading period
-}
-
-func (f *FieldNode) String() string {
-	s := ""
-	for _, id := range f.Ident {
-		s += "." + id
-	}
-	return s
-}
-
-func (f *FieldNode) Copy() Node {
-	return &FieldNode{NodeType: NodeField, Pos: f.Pos, Ident: append([]string{}, f.Ident...)}
-}
-
-// ChainNode holds a term followed by a chain of field accesses (identifier starting with '.').
-// The names may be chained ('.x.y').
-// The periods are dropped from each ident.
-type ChainNode struct {
-	NodeType
-	Pos
-	Node  Node
-	Field []string // The identifiers in lexical order.
-}
-
-func newChain(pos Pos, node Node) *ChainNode {
-	return &ChainNode{NodeType: NodeChain, Pos: pos, Node: node}
-}
-
-// Add adds the named field (which should start with a period) to the end of the chain.
-func (c *ChainNode) Add(field string) {
-	if len(field) == 0 || field[0] != '.' {
-		panic("no dot in field")
-	}
-	field = field[1:] // Remove leading dot.
-	if field == "" {
-		panic("empty field")
-	}
-	c.Field = append(c.Field, field)
-}
-
-func (c *ChainNode) String() string {
-	s := c.Node.String()
-	if _, ok := c.Node.(*PipeNode); ok {
-		s = "(" + s + ")"
-	}
-	for _, field := range c.Field {
-		s += "." + field
-	}
-	return s
-}
-
-func (c *ChainNode) Copy() Node {
-	return &ChainNode{NodeType: NodeChain, Pos: c.Pos, Node: c.Node, Field: append([]string{}, c.Field...)}
-}
-
-// BoolNode holds a boolean constant.
-type BoolNode struct {
-	NodeType
-	Pos
-	True bool // The value of the boolean constant.
-}
-
-func newBool(pos Pos, true bool) *BoolNode {
-	return &BoolNode{NodeType: NodeBool, Pos: pos, True: true}
-}
-
-func (b *BoolNode) String() string {
-	if b.True {
-		return "true"
-	}
-	return "false"
-}
-
-func (b *BoolNode) Copy() Node {
-	return newBool(b.Pos, b.True)
-}
-
-// NumberNode holds a number: signed or unsigned integer, float, or complex.
-// The value is parsed and stored under all the types that can represent the value.
-// This simulates in a small amount of code the behavior of Go's ideal constants.
-type NumberNode struct {
-	NodeType
-	Pos
-	IsInt      bool       // Number has an integral value.
-	IsUint     bool       // Number has an unsigned integral value.
-	IsFloat    bool       // Number has a floating-point value.
-	IsComplex  bool       // Number is complex.
-	Int64      int64      // The signed integer value.
-	Uint64     uint64     // The unsigned integer value.
-	Float64    float64    // The floating-point value.
-	Complex128 complex128 // The complex value.
-	Text       string     // The original textual representation from the input.
-}
-
-func newNumber(pos Pos, text string, typ itemType) (*NumberNode, error) {
-	n := &NumberNode{NodeType: NodeNumber, Pos: pos, Text: text}
-	switch typ {
-	case itemCharConstant:
-		rune, _, tail, err := strconv.UnquoteChar(text[1:], text[0])
-		if err != nil {
-			return nil, err
-		}
-		if tail != "'" {
-			return nil, fmt.Errorf("malformed character constant: %s", text)
-		}
-		n.Int64 = int64(rune)
-		n.IsInt = true
-		n.Uint64 = uint64(rune)
-		n.IsUint = true
-		n.Float64 = float64(rune) // odd but those are the rules.
-		n.IsFloat = true
-		return n, nil
-	case itemComplex:
-		// fmt.Sscan can parse the pair, so let it do the work.
-		if _, err := fmt.Sscan(text, &n.Complex128); err != nil {
-			return nil, err
-		}
-		n.IsComplex = true
-		n.simplifyComplex()
-		return n, nil
-	}
-	// Imaginary constants can only be complex unless they are zero.
-	if len(text) > 0 && text[len(text)-1] == 'i' {
-		f, err := strconv.ParseFloat(text[:len(text)-1], 64)
-		if err == nil {
-			n.IsComplex = true
-			n.Complex128 = complex(0, f)
-			n.simplifyComplex()
-			return n, nil
-		}
-	}
-	// Do integer test first so we get 0x123 etc.
-	u, err := strconv.ParseUint(text, 0, 64) // will fail for -0; fixed below.
-	if err == nil {
-		n.IsUint = true
-		n.Uint64 = u
-	}
-	i, err := strconv.ParseInt(text, 0, 64)
-	if err == nil {
-		n.IsInt = true
-		n.Int64 = i
-		if i == 0 {
-			n.IsUint = true // in case of -0.
-			n.Uint64 = u
-		}
-	}
-	// If an integer extraction succeeded, promote the float.
-	if n.IsInt {
-		n.IsFloat = true
-		n.Float64 = float64(n.Int64)
-	} else if n.IsUint {
-		n.IsFloat = true
-		n.Float64 = float64(n.Uint64)
-	} else {
-		f, err := strconv.ParseFloat(text, 64)
-		if err == nil {
-			n.IsFloat = true
-			n.Float64 = f
-			// If a floating-point extraction succeeded, extract the int if needed.
-			if !n.IsInt && float64(int64(f)) == f {
-				n.IsInt = true
-				n.Int64 = int64(f)
-			}
-			if !n.IsUint && float64(uint64(f)) == f {
-				n.IsUint = true
-				n.Uint64 = uint64(f)
-			}
-		}
-	}
-	if !n.IsInt && !n.IsUint && !n.IsFloat {
-		return nil, fmt.Errorf("illegal number syntax: %q", text)
-	}
-	return n, nil
-}
-
-// simplifyComplex pulls out any other types that are represented by the complex number.
-// These all require that the imaginary part be zero.
-func (n *NumberNode) simplifyComplex() {
-	n.IsFloat = imag(n.Complex128) == 0
-	if n.IsFloat {
-		n.Float64 = real(n.Complex128)
-		n.IsInt = float64(int64(n.Float64)) == n.Float64
-		if n.IsInt {
-			n.Int64 = int64(n.Float64)
-		}
-		n.IsUint = float64(uint64(n.Float64)) == n.Float64
-		if n.IsUint {
-			n.Uint64 = uint64(n.Float64)
-		}
-	}
-}
-
-func (n *NumberNode) String() string {
-	return n.Text
-}
-
-func (n *NumberNode) Copy() Node {
-	nn := new(NumberNode)
-	*nn = *n // Easy, fast, correct.
-	return nn
-}
-
-// StringNode holds a string constant. The value has been "unquoted".
-type StringNode struct {
-	NodeType
-	Pos
-	Quoted string // The original text of the string, with quotes.
-	Text   string // The string, after quote processing.
-}
-
-func newString(pos Pos, orig, text string) *StringNode {
-	return &StringNode{NodeType: NodeString, Pos: pos, Quoted: orig, Text: text}
-}
-
-func (s *StringNode) String() string {
-	return s.Quoted
-}
-
-func (s *StringNode) Copy() Node {
-	return newString(s.Pos, s.Quoted, s.Text)
-}
-
-// endNode represents an {{end}} action.
-// It does not appear in the final parse tree.
-type endNode struct {
-	Pos
-}
-
-func newEnd(pos Pos) *endNode {
-	return &endNode{Pos: pos}
-}
-
-func (e *endNode) Type() NodeType {
-	return nodeEnd
-}
-
-func (e *endNode) String() string {
-	return "{{end}}"
-}
-
-func (e *endNode) Copy() Node {
-	return newEnd(e.Pos)
-}
-
-// elseNode represents an {{else}} action. Does not appear in the final tree.
-type elseNode struct {
-	NodeType
-	Pos
-	Line int // The line number in the input (deprecated; kept for compatibility)
-}
-
-func newElse(pos Pos, line int) *elseNode {
-	return &elseNode{NodeType: nodeElse, Pos: pos, Line: line}
-}
-
-func (e *elseNode) Type() NodeType {
-	return nodeElse
-}
-
-func (e *elseNode) String() string {
-	return "{{else}}"
-}
-
-func (e *elseNode) Copy() Node {
-	return newElse(e.Pos, e.Line)
-}
-
-// BranchNode is the common representation of if, range, and with.
-type BranchNode struct {
-	NodeType
-	Pos
-	Line     int       // The line number in the input (deprecated; kept for compatibility)
-	Pipe     *PipeNode // The pipeline to be evaluated.
-	List     *ListNode // What to execute if the value is non-empty.
-	ElseList *ListNode // What to execute if the value is empty (nil if absent).
-}
-
-func (b *BranchNode) String() string {
-	name := ""
-	switch b.NodeType {
-	case NodeIf:
-		name = "if"
-	case NodeRange:
-		name = "range"
-	case NodeWith:
-		name = "with"
-	default:
-		panic("unknown branch type")
-	}
-	if b.ElseList != nil {
-		return fmt.Sprintf("{{%s %s}}%s{{else}}%s{{end}}", name, b.Pipe, b.List, b.ElseList)
-	}
-	return fmt.Sprintf("{{%s %s}}%s{{end}}", name, b.Pipe, b.List)
-}
-
-// IfNode represents an {{if}} action and its commands.
-type IfNode struct {
-	BranchNode
-}
-
-func newIf(pos Pos, line int, pipe *PipeNode, list, elseList *ListNode) *IfNode {
-	return &IfNode{BranchNode{NodeType: NodeIf, Pos: pos, Line: line, Pipe: pipe, List: list, ElseList: elseList}}
-}
-
-func (i *IfNode) Copy() Node {
-	return newIf(i.Pos, i.Line, i.Pipe.CopyPipe(), i.List.CopyList(), i.ElseList.CopyList())
-}
-
-// RangeNode represents a {{range}} action and its commands.
-type RangeNode struct {
-	BranchNode
-}
-
-func newRange(pos Pos, line int, pipe *PipeNode, list, elseList *ListNode) *RangeNode {
-	return &RangeNode{BranchNode{NodeType: NodeRange, Pos: pos, Line: line, Pipe: pipe, List: list, ElseList: elseList}}
-}
-
-func (r *RangeNode) Copy() Node {
-	return newRange(r.Pos, r.Line, r.Pipe.CopyPipe(), r.List.CopyList(), r.ElseList.CopyList())
-}
-
-// WithNode represents a {{with}} action and its commands.
-type WithNode struct {
-	BranchNode
-}
-
-func newWith(pos Pos, line int, pipe *PipeNode, list, elseList *ListNode) *WithNode {
-	return &WithNode{BranchNode{NodeType: NodeWith, Pos: pos, Line: line, Pipe: pipe, List: list, ElseList: elseList}}
-}
-
-func (w *WithNode) Copy() Node {
-	return newWith(w.Pos, w.Line, w.Pipe.CopyPipe(), w.List.CopyList(), w.ElseList.CopyList())
-}
-
-// TemplateNode represents a {{template}} action.
-type TemplateNode struct {
-	NodeType
-	Pos
-	Line int       // The line number in the input (deprecated; kept for compatibility)
-	Name string    // The name of the template (unquoted).
-	Pipe *PipeNode // The command to evaluate as dot for the template.
-}
-
-func newTemplate(pos Pos, line int, name string, pipe *PipeNode) *TemplateNode {
-	return &TemplateNode{NodeType: NodeTemplate, Line: line, Pos: pos, Name: name, Pipe: pipe}
-}
-
-func (t *TemplateNode) String() string {
-	if t.Pipe == nil {
-		return fmt.Sprintf("{{template %q}}", t.Name)
-	}
-	return fmt.Sprintf("{{template %q %s}}", t.Name, t.Pipe)
-}
-
-func (t *TemplateNode) Copy() Node {
-	return newTemplate(t.Pos, t.Line, t.Name, t.Pipe.CopyPipe())
-}
diff --git a/src/pkg/text/template/parse/parse.go b/src/pkg/text/template/parse/parse.go
deleted file mode 100644
index 34112fb..0000000
--- a/src/pkg/text/template/parse/parse.go
+++ /dev/null
@@ -1,671 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package parse builds parse trees for templates as defined by text/template
-// and html/template. Clients should use those packages to construct templates
-// rather than this one, which provides shared internal data structures not
-// intended for general use.
-package parse
-
-import (
-	"bytes"
-	"fmt"
-	"runtime"
-	"strconv"
-	"strings"
-)
-
-// Tree is the representation of a single parsed template.
-type Tree struct {
-	Name      string    // name of the template represented by the tree.
-	ParseName string    // name of the top-level template during parsing, for error messages.
-	Root      *ListNode // top-level root of the tree.
-	text      string    // text parsed to create the template (or its parent)
-	// Parsing only; cleared after parse.
-	funcs     []map[string]interface{}
-	lex       *lexer
-	token     [3]item // three-token lookahead for parser.
-	peekCount int
-	vars      []string // variables defined at the moment.
-}
-
-// Copy returns a copy of the Tree. Any parsing state is discarded.
-func (t *Tree) Copy() *Tree {
-	if t == nil {
-		return nil
-	}
-	return &Tree{
-		Name:      t.Name,
-		ParseName: t.ParseName,
-		Root:      t.Root.CopyList(),
-		text:      t.text,
-	}
-}
-
-// Parse returns a map from template name to parse.Tree, created by parsing the
-// templates described in the argument string. The top-level template will be
-// given the specified name. If an error is encountered, parsing stops and an
-// empty map is returned with the error.
-func Parse(name, text, leftDelim, rightDelim string, funcs ...map[string]interface{}) (treeSet map[string]*Tree, err error) {
-	treeSet = make(map[string]*Tree)
-	t := New(name)
-	t.text = text
-	_, err = t.Parse(text, leftDelim, rightDelim, treeSet, funcs...)
-	return
-}
-
-// next returns the next token.
-func (t *Tree) next() item {
-	if t.peekCount > 0 {
-		t.peekCount--
-	} else {
-		t.token[0] = t.lex.nextItem()
-	}
-	return t.token[t.peekCount]
-}
-
-// backup backs the input stream up one token.
-func (t *Tree) backup() {
-	t.peekCount++
-}
-
-// backup2 backs the input stream up two tokens.
-// The zeroth token is already there.
-func (t *Tree) backup2(t1 item) {
-	t.token[1] = t1
-	t.peekCount = 2
-}
-
-// backup3 backs the input stream up three tokens
-// The zeroth token is already there.
-func (t *Tree) backup3(t2, t1 item) { // Reverse order: we're pushing back.
-	t.token[1] = t1
-	t.token[2] = t2
-	t.peekCount = 3
-}
-
-// peek returns but does not consume the next token.
-func (t *Tree) peek() item {
-	if t.peekCount > 0 {
-		return t.token[t.peekCount-1]
-	}
-	t.peekCount = 1
-	t.token[0] = t.lex.nextItem()
-	return t.token[0]
-}
-
-// nextNonSpace returns the next non-space token.
-func (t *Tree) nextNonSpace() (token item) {
-	for {
-		token = t.next()
-		if token.typ != itemSpace {
-			break
-		}
-	}
-	return token
-}
-
-// peekNonSpace returns but does not consume the next non-space token.
-func (t *Tree) peekNonSpace() (token item) {
-	for {
-		token = t.next()
-		if token.typ != itemSpace {
-			break
-		}
-	}
-	t.backup()
-	return token
-}
-
-// Parsing.
-
-// New allocates a new parse tree with the given name.
-func New(name string, funcs ...map[string]interface{}) *Tree {
-	return &Tree{
-		Name:  name,
-		funcs: funcs,
-	}
-}
-
-// ErrorContext returns a textual representation of the location of the node in the input text.
-func (t *Tree) ErrorContext(n Node) (location, context string) {
-	pos := int(n.Position())
-	text := t.text[:pos]
-	byteNum := strings.LastIndex(text, "\n")
-	if byteNum == -1 {
-		byteNum = pos // On first line.
-	} else {
-		byteNum++ // After the newline.
-		byteNum = pos - byteNum
-	}
-	lineNum := 1 + strings.Count(text, "\n")
-	context = n.String()
-	if len(context) > 20 {
-		context = fmt.Sprintf("%.20s...", context)
-	}
-	return fmt.Sprintf("%s:%d:%d", t.ParseName, lineNum, byteNum), context
-}
-
-// errorf formats the error and terminates processing.
-func (t *Tree) errorf(format string, args ...interface{}) {
-	t.Root = nil
-	format = fmt.Sprintf("template: %s:%d: %s", t.ParseName, t.lex.lineNumber(), format)
-	panic(fmt.Errorf(format, args...))
-}
-
-// error terminates processing.
-func (t *Tree) error(err error) {
-	t.errorf("%s", err)
-}
-
-// expect consumes the next token and guarantees it has the required type.
-func (t *Tree) expect(expected itemType, context string) item {
-	token := t.nextNonSpace()
-	if token.typ != expected {
-		t.unexpected(token, context)
-	}
-	return token
-}
-
-// expectOneOf consumes the next token and guarantees it has one of the required types.
-func (t *Tree) expectOneOf(expected1, expected2 itemType, context string) item {
-	token := t.nextNonSpace()
-	if token.typ != expected1 && token.typ != expected2 {
-		t.unexpected(token, context)
-	}
-	return token
-}
-
-// unexpected complains about the token and terminates processing.
-func (t *Tree) unexpected(token item, context string) {
-	t.errorf("unexpected %s in %s", token, context)
-}
-
-// recover is the handler that turns panics into returns from the top level of Parse.
-func (t *Tree) recover(errp *error) {
-	e := recover()
-	if e != nil {
-		if _, ok := e.(runtime.Error); ok {
-			panic(e)
-		}
-		if t != nil {
-			t.stopParse()
-		}
-		*errp = e.(error)
-	}
-	return
-}
-
-// startParse initializes the parser, using the lexer.
-func (t *Tree) startParse(funcs []map[string]interface{}, lex *lexer) {
-	t.Root = nil
-	t.lex = lex
-	t.vars = []string{"$"}
-	t.funcs = funcs
-}
-
-// stopParse terminates parsing.
-func (t *Tree) stopParse() {
-	t.lex = nil
-	t.vars = nil
-	t.funcs = nil
-}
-
-// Parse parses the template definition string to construct a representation of
-// the template for execution. If either action delimiter string is empty, the
-// default ("{{" or "}}") is used. Embedded template definitions are added to
-// the treeSet map.
-func (t *Tree) Parse(text, leftDelim, rightDelim string, treeSet map[string]*Tree, funcs ...map[string]interface{}) (tree *Tree, err error) {
-	defer t.recover(&err)
-	t.ParseName = t.Name
-	t.startParse(funcs, lex(t.Name, text, leftDelim, rightDelim))
-	t.text = text
-	t.parse(treeSet)
-	t.add(treeSet)
-	t.stopParse()
-	return t, nil
-}
-
-// add adds tree to the treeSet.
-func (t *Tree) add(treeSet map[string]*Tree) {
-	tree := treeSet[t.Name]
-	if tree == nil || IsEmptyTree(tree.Root) {
-		treeSet[t.Name] = t
-		return
-	}
-	if !IsEmptyTree(t.Root) {
-		t.errorf("template: multiple definition of template %q", t.Name)
-	}
-}
-
-// IsEmptyTree reports whether this tree (node) is empty of everything but space.
-func IsEmptyTree(n Node) bool {
-	switch n := n.(type) {
-	case nil:
-		return true
-	case *ActionNode:
-	case *IfNode:
-	case *ListNode:
-		for _, node := range n.Nodes {
-			if !IsEmptyTree(node) {
-				return false
-			}
-		}
-		return true
-	case *RangeNode:
-	case *TemplateNode:
-	case *TextNode:
-		return len(bytes.TrimSpace(n.Text)) == 0
-	case *WithNode:
-	default:
-		panic("unknown node: " + n.String())
-	}
-	return false
-}
-
-// parse is the top-level parser for a template, essentially the same
-// as itemList except it also parses {{define}} actions.
-// It runs to EOF.
-func (t *Tree) parse(treeSet map[string]*Tree) (next Node) {
-	t.Root = newList(t.peek().pos)
-	for t.peek().typ != itemEOF {
-		if t.peek().typ == itemLeftDelim {
-			delim := t.next()
-			if t.nextNonSpace().typ == itemDefine {
-				newT := New("definition") // name will be updated once we know it.
-				newT.text = t.text
-				newT.ParseName = t.ParseName
-				newT.startParse(t.funcs, t.lex)
-				newT.parseDefinition(treeSet)
-				continue
-			}
-			t.backup2(delim)
-		}
-		n := t.textOrAction()
-		if n.Type() == nodeEnd {
-			t.errorf("unexpected %s", n)
-		}
-		t.Root.append(n)
-	}
-	return nil
-}
-
-// parseDefinition parses a {{define}} ...  {{end}} template definition and
-// installs the definition in the treeSet map.  The "define" keyword has already
-// been scanned.
-func (t *Tree) parseDefinition(treeSet map[string]*Tree) {
-	const context = "define clause"
-	name := t.expectOneOf(itemString, itemRawString, context)
-	var err error
-	t.Name, err = strconv.Unquote(name.val)
-	if err != nil {
-		t.error(err)
-	}
-	t.expect(itemRightDelim, context)
-	var end Node
-	t.Root, end = t.itemList()
-	if end.Type() != nodeEnd {
-		t.errorf("unexpected %s in %s", end, context)
-	}
-	t.add(treeSet)
-	t.stopParse()
-}
-
-// itemList:
-//	textOrAction*
-// Terminates at {{end}} or {{else}}, returned separately.
-func (t *Tree) itemList() (list *ListNode, next Node) {
-	list = newList(t.peekNonSpace().pos)
-	for t.peekNonSpace().typ != itemEOF {
-		n := t.textOrAction()
-		switch n.Type() {
-		case nodeEnd, nodeElse:
-			return list, n
-		}
-		list.append(n)
-	}
-	t.errorf("unexpected EOF")
-	return
-}
-
-// textOrAction:
-//	text | action
-func (t *Tree) textOrAction() Node {
-	switch token := t.nextNonSpace(); token.typ {
-	case itemText:
-		return newText(token.pos, token.val)
-	case itemLeftDelim:
-		return t.action()
-	default:
-		t.unexpected(token, "input")
-	}
-	return nil
-}
-
-// Action:
-//	control
-//	command ("|" command)*
-// Left delim is past. Now get actions.
-// First word could be a keyword such as range.
-func (t *Tree) action() (n Node) {
-	switch token := t.nextNonSpace(); token.typ {
-	case itemElse:
-		return t.elseControl()
-	case itemEnd:
-		return t.endControl()
-	case itemIf:
-		return t.ifControl()
-	case itemRange:
-		return t.rangeControl()
-	case itemTemplate:
-		return t.templateControl()
-	case itemWith:
-		return t.withControl()
-	}
-	t.backup()
-	// Do not pop variables; they persist until "end".
-	return newAction(t.peek().pos, t.lex.lineNumber(), t.pipeline("command"))
-}
-
-// Pipeline:
-//	declarations? command ('|' command)*
-func (t *Tree) pipeline(context string) (pipe *PipeNode) {
-	var decl []*VariableNode
-	pos := t.peekNonSpace().pos
-	// Are there declarations?
-	for {
-		if v := t.peekNonSpace(); v.typ == itemVariable {
-			t.next()
-			// Since space is a token, we need 3-token look-ahead here in the worst case:
-			// in "$x foo" we need to read "foo" (as opposed to ":=") to know that $x is an
-			// argument variable rather than a declaration. So remember the token
-			// adjacent to the variable so we can push it back if necessary.
-			tokenAfterVariable := t.peek()
-			if next := t.peekNonSpace(); next.typ == itemColonEquals || (next.typ == itemChar && next.val == ",") {
-				t.nextNonSpace()
-				variable := newVariable(v.pos, v.val)
-				decl = append(decl, variable)
-				t.vars = append(t.vars, v.val)
-				if next.typ == itemChar && next.val == "," {
-					if context == "range" && len(decl) < 2 {
-						continue
-					}
-					t.errorf("too many declarations in %s", context)
-				}
-			} else if tokenAfterVariable.typ == itemSpace {
-				t.backup3(v, tokenAfterVariable)
-			} else {
-				t.backup2(v)
-			}
-		}
-		break
-	}
-	pipe = newPipeline(pos, t.lex.lineNumber(), decl)
-	for {
-		switch token := t.nextNonSpace(); token.typ {
-		case itemRightDelim, itemRightParen:
-			if len(pipe.Cmds) == 0 {
-				t.errorf("missing value for %s", context)
-			}
-			if token.typ == itemRightParen {
-				t.backup()
-			}
-			return
-		case itemBool, itemCharConstant, itemComplex, itemDot, itemField, itemIdentifier,
-			itemNumber, itemNil, itemRawString, itemString, itemVariable, itemLeftParen:
-			t.backup()
-			pipe.append(t.command())
-		default:
-			t.unexpected(token, context)
-		}
-	}
-}
-
-func (t *Tree) parseControl(allowElseIf bool, context string) (pos Pos, line int, pipe *PipeNode, list, elseList *ListNode) {
-	defer t.popVars(len(t.vars))
-	line = t.lex.lineNumber()
-	pipe = t.pipeline(context)
-	var next Node
-	list, next = t.itemList()
-	switch next.Type() {
-	case nodeEnd: //done
-	case nodeElse:
-		if allowElseIf {
-			// Special case for "else if". If the "else" is followed immediately by an "if",
-			// the elseControl will have left the "if" token pending. Treat
-			//	{{if a}}_{{else if b}}_{{end}}
-			// as
-			//	{{if a}}_{{else}}{{if b}}_{{end}}{{end}}.
-			// To do this, parse the if as usual and stop at it {{end}}; the subsequent{{end}}
-			// is assumed. This technique works even for long if-else-if chains.
-			// TODO: Should we allow else-if in with and range?
-			if t.peek().typ == itemIf {
-				t.next() // Consume the "if" token.
-				elseList = newList(next.Position())
-				elseList.append(t.ifControl())
-				// Do not consume the next item - only one {{end}} required.
-				break
-			}
-		}
-		elseList, next = t.itemList()
-		if next.Type() != nodeEnd {
-			t.errorf("expected end; found %s", next)
-		}
-	}
-	return pipe.Position(), line, pipe, list, elseList
-}
-
-// If:
-//	{{if pipeline}} itemList {{end}}
-//	{{if pipeline}} itemList {{else}} itemList {{end}}
-// If keyword is past.
-func (t *Tree) ifControl() Node {
-	return newIf(t.parseControl(true, "if"))
-}
-
-// Range:
-//	{{range pipeline}} itemList {{end}}
-//	{{range pipeline}} itemList {{else}} itemList {{end}}
-// Range keyword is past.
-func (t *Tree) rangeControl() Node {
-	return newRange(t.parseControl(false, "range"))
-}
-
-// With:
-//	{{with pipeline}} itemList {{end}}
-//	{{with pipeline}} itemList {{else}} itemList {{end}}
-// If keyword is past.
-func (t *Tree) withControl() Node {
-	return newWith(t.parseControl(false, "with"))
-}
-
-// End:
-//	{{end}}
-// End keyword is past.
-func (t *Tree) endControl() Node {
-	return newEnd(t.expect(itemRightDelim, "end").pos)
-}
-
-// Else:
-//	{{else}}
-// Else keyword is past.
-func (t *Tree) elseControl() Node {
-	// Special case for "else if".
-	peek := t.peekNonSpace()
-	if peek.typ == itemIf {
-		// We see "{{else if ... " but in effect rewrite it to {{else}}{{if ... ".
-		return newElse(peek.pos, t.lex.lineNumber())
-	}
-	return newElse(t.expect(itemRightDelim, "else").pos, t.lex.lineNumber())
-}
-
-// Template:
-//	{{template stringValue pipeline}}
-// Template keyword is past.  The name must be something that can evaluate
-// to a string.
-func (t *Tree) templateControl() Node {
-	var name string
-	token := t.nextNonSpace()
-	switch token.typ {
-	case itemString, itemRawString:
-		s, err := strconv.Unquote(token.val)
-		if err != nil {
-			t.error(err)
-		}
-		name = s
-	default:
-		t.unexpected(token, "template invocation")
-	}
-	var pipe *PipeNode
-	if t.nextNonSpace().typ != itemRightDelim {
-		t.backup()
-		// Do not pop variables; they persist until "end".
-		pipe = t.pipeline("template")
-	}
-	return newTemplate(token.pos, t.lex.lineNumber(), name, pipe)
-}
-
-// command:
-//	operand (space operand)*
-// space-separated arguments up to a pipeline character or right delimiter.
-// we consume the pipe character but leave the right delim to terminate the action.
-func (t *Tree) command() *CommandNode {
-	cmd := newCommand(t.peekNonSpace().pos)
-	for {
-		t.peekNonSpace() // skip leading spaces.
-		operand := t.operand()
-		if operand != nil {
-			cmd.append(operand)
-		}
-		switch token := t.next(); token.typ {
-		case itemSpace:
-			continue
-		case itemError:
-			t.errorf("%s", token.val)
-		case itemRightDelim, itemRightParen:
-			t.backup()
-		case itemPipe:
-		default:
-			t.errorf("unexpected %s in operand; missing space?", token)
-		}
-		break
-	}
-	if len(cmd.Args) == 0 {
-		t.errorf("empty command")
-	}
-	return cmd
-}
-
-// operand:
-//	term .Field*
-// An operand is a space-separated component of a command,
-// a term possibly followed by field accesses.
-// A nil return means the next item is not an operand.
-func (t *Tree) operand() Node {
-	node := t.term()
-	if node == nil {
-		return nil
-	}
-	if t.peek().typ == itemField {
-		chain := newChain(t.peek().pos, node)
-		for t.peek().typ == itemField {
-			chain.Add(t.next().val)
-		}
-		// Compatibility with original API: If the term is of type NodeField
-		// or NodeVariable, just put more fields on the original.
-		// Otherwise, keep the Chain node.
-		// TODO: Switch to Chains always when we can.
-		switch node.Type() {
-		case NodeField:
-			node = newField(chain.Position(), chain.String())
-		case NodeVariable:
-			node = newVariable(chain.Position(), chain.String())
-		default:
-			node = chain
-		}
-	}
-	return node
-}
-
-// term:
-//	literal (number, string, nil, boolean)
-//	function (identifier)
-//	.
-//	.Field
-//	$
-//	'(' pipeline ')'
-// A term is a simple "expression".
-// A nil return means the next item is not a term.
-func (t *Tree) term() Node {
-	switch token := t.nextNonSpace(); token.typ {
-	case itemError:
-		t.errorf("%s", token.val)
-	case itemIdentifier:
-		if !t.hasFunction(token.val) {
-			t.errorf("function %q not defined", token.val)
-		}
-		return NewIdentifier(token.val).SetPos(token.pos)
-	case itemDot:
-		return newDot(token.pos)
-	case itemNil:
-		return newNil(token.pos)
-	case itemVariable:
-		return t.useVar(token.pos, token.val)
-	case itemField:
-		return newField(token.pos, token.val)
-	case itemBool:
-		return newBool(token.pos, token.val == "true")
-	case itemCharConstant, itemComplex, itemNumber:
-		number, err := newNumber(token.pos, token.val, token.typ)
-		if err != nil {
-			t.error(err)
-		}
-		return number
-	case itemLeftParen:
-		pipe := t.pipeline("parenthesized pipeline")
-		if token := t.next(); token.typ != itemRightParen {
-			t.errorf("unclosed right paren: unexpected %s", token)
-		}
-		return pipe
-	case itemString, itemRawString:
-		s, err := strconv.Unquote(token.val)
-		if err != nil {
-			t.error(err)
-		}
-		return newString(token.pos, token.val, s)
-	}
-	t.backup()
-	return nil
-}
-
-// hasFunction reports if a function name exists in the Tree's maps.
-func (t *Tree) hasFunction(name string) bool {
-	for _, funcMap := range t.funcs {
-		if funcMap == nil {
-			continue
-		}
-		if funcMap[name] != nil {
-			return true
-		}
-	}
-	return false
-}
-
-// popVars trims the variable list to the specified length
-func (t *Tree) popVars(n int) {
-	t.vars = t.vars[:n]
-}
-
-// useVar returns a node for a variable reference. It errors if the
-// variable is not defined.
-func (t *Tree) useVar(pos Pos, name string) Node {
-	v := newVariable(pos, name)
-	for _, varName := range t.vars {
-		if varName == v.Ident[0] {
-			return v
-		}
-	}
-	t.errorf("undefined variable %q", v.Ident[0])
-	return nil
-}
diff --git a/src/pkg/text/template/parse/parse_test.go b/src/pkg/text/template/parse/parse_test.go
deleted file mode 100644
index ba1a18e..0000000
--- a/src/pkg/text/template/parse/parse_test.go
+++ /dev/null
@@ -1,420 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package parse
-
-import (
-	"flag"
-	"fmt"
-	"strings"
-	"testing"
-)
-
-var debug = flag.Bool("debug", false, "show the errors produced by the main tests")
-
-type numberTest struct {
-	text      string
-	isInt     bool
-	isUint    bool
-	isFloat   bool
-	isComplex bool
-	int64
-	uint64
-	float64
-	complex128
-}
-
-var numberTests = []numberTest{
-	// basics
-	{"0", true, true, true, false, 0, 0, 0, 0},
-	{"-0", true, true, true, false, 0, 0, 0, 0}, // check that -0 is a uint.
-	{"73", true, true, true, false, 73, 73, 73, 0},
-	{"073", true, true, true, false, 073, 073, 073, 0},
-	{"0x73", true, true, true, false, 0x73, 0x73, 0x73, 0},
-	{"-73", true, false, true, false, -73, 0, -73, 0},
-	{"+73", true, false, true, false, 73, 0, 73, 0},
-	{"100", true, true, true, false, 100, 100, 100, 0},
-	{"1e9", true, true, true, false, 1e9, 1e9, 1e9, 0},
-	{"-1e9", true, false, true, false, -1e9, 0, -1e9, 0},
-	{"-1.2", false, false, true, false, 0, 0, -1.2, 0},
-	{"1e19", false, true, true, false, 0, 1e19, 1e19, 0},
-	{"-1e19", false, false, true, false, 0, 0, -1e19, 0},
-	{"4i", false, false, false, true, 0, 0, 0, 4i},
-	{"-1.2+4.2i", false, false, false, true, 0, 0, 0, -1.2 + 4.2i},
-	{"073i", false, false, false, true, 0, 0, 0, 73i}, // not octal!
-	// complex with 0 imaginary are float (and maybe integer)
-	{"0i", true, true, true, true, 0, 0, 0, 0},
-	{"-1.2+0i", false, false, true, true, 0, 0, -1.2, -1.2},
-	{"-12+0i", true, false, true, true, -12, 0, -12, -12},
-	{"13+0i", true, true, true, true, 13, 13, 13, 13},
-	// funny bases
-	{"0123", true, true, true, false, 0123, 0123, 0123, 0},
-	{"-0x0", true, true, true, false, 0, 0, 0, 0},
-	{"0xdeadbeef", true, true, true, false, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0},
-	// character constants
-	{`'a'`, true, true, true, false, 'a', 'a', 'a', 0},
-	{`'\n'`, true, true, true, false, '\n', '\n', '\n', 0},
-	{`'\\'`, true, true, true, false, '\\', '\\', '\\', 0},
-	{`'\''`, true, true, true, false, '\'', '\'', '\'', 0},
-	{`'\xFF'`, true, true, true, false, 0xFF, 0xFF, 0xFF, 0},
-	{`'パ'`, true, true, true, false, 0x30d1, 0x30d1, 0x30d1, 0},
-	{`'\u30d1'`, true, true, true, false, 0x30d1, 0x30d1, 0x30d1, 0},
-	{`'\U000030d1'`, true, true, true, false, 0x30d1, 0x30d1, 0x30d1, 0},
-	// some broken syntax
-	{text: "+-2"},
-	{text: "0x123."},
-	{text: "1e."},
-	{text: "0xi."},
-	{text: "1+2."},
-	{text: "'x"},
-	{text: "'xx'"},
-}
-
-func TestNumberParse(t *testing.T) {
-	for _, test := range numberTests {
-		// If fmt.Sscan thinks it's complex, it's complex.  We can't trust the output
-		// because imaginary comes out as a number.
-		var c complex128
-		typ := itemNumber
-		if test.text[0] == '\'' {
-			typ = itemCharConstant
-		} else {
-			_, err := fmt.Sscan(test.text, &c)
-			if err == nil {
-				typ = itemComplex
-			}
-		}
-		n, err := newNumber(0, test.text, typ)
-		ok := test.isInt || test.isUint || test.isFloat || test.isComplex
-		if ok && err != nil {
-			t.Errorf("unexpected error for %q: %s", test.text, err)
-			continue
-		}
-		if !ok && err == nil {
-			t.Errorf("expected error for %q", test.text)
-			continue
-		}
-		if !ok {
-			if *debug {
-				fmt.Printf("%s\n\t%s\n", test.text, err)
-			}
-			continue
-		}
-		if n.IsComplex != test.isComplex {
-			t.Errorf("complex incorrect for %q; should be %t", test.text, test.isComplex)
-		}
-		if test.isInt {
-			if !n.IsInt {
-				t.Errorf("expected integer for %q", test.text)
-			}
-			if n.Int64 != test.int64 {
-				t.Errorf("int64 for %q should be %d Is %d", test.text, test.int64, n.Int64)
-			}
-		} else if n.IsInt {
-			t.Errorf("did not expect integer for %q", test.text)
-		}
-		if test.isUint {
-			if !n.IsUint {
-				t.Errorf("expected unsigned integer for %q", test.text)
-			}
-			if n.Uint64 != test.uint64 {
-				t.Errorf("uint64 for %q should be %d Is %d", test.text, test.uint64, n.Uint64)
-			}
-		} else if n.IsUint {
-			t.Errorf("did not expect unsigned integer for %q", test.text)
-		}
-		if test.isFloat {
-			if !n.IsFloat {
-				t.Errorf("expected float for %q", test.text)
-			}
-			if n.Float64 != test.float64 {
-				t.Errorf("float64 for %q should be %g Is %g", test.text, test.float64, n.Float64)
-			}
-		} else if n.IsFloat {
-			t.Errorf("did not expect float for %q", test.text)
-		}
-		if test.isComplex {
-			if !n.IsComplex {
-				t.Errorf("expected complex for %q", test.text)
-			}
-			if n.Complex128 != test.complex128 {
-				t.Errorf("complex128 for %q should be %g Is %g", test.text, test.complex128, n.Complex128)
-			}
-		} else if n.IsComplex {
-			t.Errorf("did not expect complex for %q", test.text)
-		}
-	}
-}
-
-type parseTest struct {
-	name   string
-	input  string
-	ok     bool
-	result string // what the user would see in an error message.
-}
-
-const (
-	noError  = true
-	hasError = false
-)
-
-var parseTests = []parseTest{
-	{"empty", "", noError,
-		``},
-	{"comment", "{{/*\n\n\n*/}}", noError,
-		``},
-	{"spaces", " \t\n", noError,
-		`" \t\n"`},
-	{"text", "some text", noError,
-		`"some text"`},
-	{"emptyAction", "{{}}", hasError,
-		`{{}}`},
-	{"field", "{{.X}}", noError,
-		`{{.X}}`},
-	{"simple command", "{{printf}}", noError,
-		`{{printf}}`},
-	{"$ invocation", "{{$}}", noError,
-		"{{$}}"},
-	{"variable invocation", "{{with $x := 3}}{{$x 23}}{{end}}", noError,
-		"{{with $x := 3}}{{$x 23}}{{end}}"},
-	{"variable with fields", "{{$.I}}", noError,
-		"{{$.I}}"},
-	{"multi-word command", "{{printf `%d` 23}}", noError,
-		"{{printf `%d` 23}}"},
-	{"pipeline", "{{.X|.Y}}", noError,
-		`{{.X | .Y}}`},
-	{"pipeline with decl", "{{$x := .X|.Y}}", noError,
-		`{{$x := .X | .Y}}`},
-	{"nested pipeline", "{{.X (.Y .Z) (.A | .B .C) (.E)}}", noError,
-		`{{.X (.Y .Z) (.A | .B .C) (.E)}}`},
-	{"field applied to parentheses", "{{(.Y .Z).Field}}", noError,
-		`{{(.Y .Z).Field}}`},
-	{"simple if", "{{if .X}}hello{{end}}", noError,
-		`{{if .X}}"hello"{{end}}`},
-	{"if with else", "{{if .X}}true{{else}}false{{end}}", noError,
-		`{{if .X}}"true"{{else}}"false"{{end}}`},
-	{"if with else if", "{{if .X}}true{{else if .Y}}false{{end}}", noError,
-		`{{if .X}}"true"{{else}}{{if .Y}}"false"{{end}}{{end}}`},
-	{"if else chain", "+{{if .X}}X{{else if .Y}}Y{{else if .Z}}Z{{end}}+", noError,
-		`"+"{{if .X}}"X"{{else}}{{if .Y}}"Y"{{else}}{{if .Z}}"Z"{{end}}{{end}}{{end}}"+"`},
-	{"simple range", "{{range .X}}hello{{end}}", noError,
-		`{{range .X}}"hello"{{end}}`},
-	{"chained field range", "{{range .X.Y.Z}}hello{{end}}", noError,
-		`{{range .X.Y.Z}}"hello"{{end}}`},
-	{"nested range", "{{range .X}}hello{{range .Y}}goodbye{{end}}{{end}}", noError,
-		`{{range .X}}"hello"{{range .Y}}"goodbye"{{end}}{{end}}`},
-	{"range with else", "{{range .X}}true{{else}}false{{end}}", noError,
-		`{{range .X}}"true"{{else}}"false"{{end}}`},
-	{"range over pipeline", "{{range .X|.M}}true{{else}}false{{end}}", noError,
-		`{{range .X | .M}}"true"{{else}}"false"{{end}}`},
-	{"range []int", "{{range .SI}}{{.}}{{end}}", noError,
-		`{{range .SI}}{{.}}{{end}}`},
-	{"range 1 var", "{{range $x := .SI}}{{.}}{{end}}", noError,
-		`{{range $x := .SI}}{{.}}{{end}}`},
-	{"range 2 vars", "{{range $x, $y := .SI}}{{.}}{{end}}", noError,
-		`{{range $x, $y := .SI}}{{.}}{{end}}`},
-	{"constants", "{{range .SI 1 -3.2i true false 'a' nil}}{{end}}", noError,
-		`{{range .SI 1 -3.2i true false 'a' nil}}{{end}}`},
-	{"template", "{{template `x`}}", noError,
-		`{{template "x"}}`},
-	{"template with arg", "{{template `x` .Y}}", noError,
-		`{{template "x" .Y}}`},
-	{"with", "{{with .X}}hello{{end}}", noError,
-		`{{with .X}}"hello"{{end}}`},
-	{"with with else", "{{with .X}}hello{{else}}goodbye{{end}}", noError,
-		`{{with .X}}"hello"{{else}}"goodbye"{{end}}`},
-	// Errors.
-	{"unclosed action", "hello{{range", hasError, ""},
-	{"unmatched end", "{{end}}", hasError, ""},
-	{"missing end", "hello{{range .x}}", hasError, ""},
-	{"missing end after else", "hello{{range .x}}{{else}}", hasError, ""},
-	{"undefined function", "hello{{undefined}}", hasError, ""},
-	{"undefined variable", "{{$x}}", hasError, ""},
-	{"variable undefined after end", "{{with $x := 4}}{{end}}{{$x}}", hasError, ""},
-	{"variable undefined in template", "{{template $v}}", hasError, ""},
-	{"declare with field", "{{with $x.Y := 4}}{{end}}", hasError, ""},
-	{"template with field ref", "{{template .X}}", hasError, ""},
-	{"template with var", "{{template $v}}", hasError, ""},
-	{"invalid punctuation", "{{printf 3, 4}}", hasError, ""},
-	{"multidecl outside range", "{{with $v, $u := 3}}{{end}}", hasError, ""},
-	{"too many decls in range", "{{range $u, $v, $w := 3}}{{end}}", hasError, ""},
-	{"dot applied to parentheses", "{{printf (printf .).}}", hasError, ""},
-	{"adjacent args", "{{printf 3`x`}}", hasError, ""},
-	{"adjacent args with .", "{{printf `x`.}}", hasError, ""},
-	{"extra end after if", "{{if .X}}a{{else if .Y}}b{{end}}{{end}}", hasError, ""},
-	// Equals (and other chars) do not assignments make (yet).
-	{"bug0a", "{{$x := 0}}{{$x}}", noError, "{{$x := 0}}{{$x}}"},
-	{"bug0b", "{{$x = 1}}{{$x}}", hasError, ""},
-	{"bug0c", "{{$x ! 2}}{{$x}}", hasError, ""},
-	{"bug0d", "{{$x % 3}}{{$x}}", hasError, ""},
-	// Check the parse fails for := rather than comma.
-	{"bug0e", "{{range $x := $y := 3}}{{end}}", hasError, ""},
-	// Another bug: variable read must ignore following punctuation.
-	{"bug1a", "{{$x:=.}}{{$x!2}}", hasError, ""},                     // ! is just illegal here.
-	{"bug1b", "{{$x:=.}}{{$x+2}}", hasError, ""},                     // $x+2 should not parse as ($x) (+2).
-	{"bug1c", "{{$x:=.}}{{$x +2}}", noError, "{{$x := .}}{{$x +2}}"}, // It's OK with a space.
-}
-
-var builtins = map[string]interface{}{
-	"printf": fmt.Sprintf,
-}
-
-func testParse(doCopy bool, t *testing.T) {
-	textFormat = "%q"
-	defer func() { textFormat = "%s" }()
-	for _, test := range parseTests {
-		tmpl, err := New(test.name).Parse(test.input, "", "", make(map[string]*Tree), builtins)
-		switch {
-		case err == nil && !test.ok:
-			t.Errorf("%q: expected error; got none", test.name)
-			continue
-		case err != nil && test.ok:
-			t.Errorf("%q: unexpected error: %v", test.name, err)
-			continue
-		case err != nil && !test.ok:
-			// expected error, got one
-			if *debug {
-				fmt.Printf("%s: %s\n\t%s\n", test.name, test.input, err)
-			}
-			continue
-		}
-		var result string
-		if doCopy {
-			result = tmpl.Root.Copy().String()
-		} else {
-			result = tmpl.Root.String()
-		}
-		if result != test.result {
-			t.Errorf("%s=(%q): got\n\t%v\nexpected\n\t%v", test.name, test.input, result, test.result)
-		}
-	}
-}
-
-func TestParse(t *testing.T) {
-	testParse(false, t)
-}
-
-// Same as TestParse, but we copy the node first
-func TestParseCopy(t *testing.T) {
-	testParse(true, t)
-}
-
-type isEmptyTest struct {
-	name  string
-	input string
-	empty bool
-}
-
-var isEmptyTests = []isEmptyTest{
-	{"empty", ``, true},
-	{"nonempty", `hello`, false},
-	{"spaces only", " \t\n \t\n", true},
-	{"definition", `{{define "x"}}something{{end}}`, true},
-	{"definitions and space", "{{define `x`}}something{{end}}\n\n{{define `y`}}something{{end}}\n\n", true},
-	{"definitions and text", "{{define `x`}}something{{end}}\nx\n{{define `y`}}something{{end}}\ny\n", false},
-	{"definition and action", "{{define `x`}}something{{end}}{{if 3}}foo{{end}}", false},
-}
-
-func TestIsEmpty(t *testing.T) {
-	if !IsEmptyTree(nil) {
-		t.Errorf("nil tree is not empty")
-	}
-	for _, test := range isEmptyTests {
-		tree, err := New("root").Parse(test.input, "", "", make(map[string]*Tree), nil)
-		if err != nil {
-			t.Errorf("%q: unexpected error: %v", test.name, err)
-			continue
-		}
-		if empty := IsEmptyTree(tree.Root); empty != test.empty {
-			t.Errorf("%q: expected %t got %t", test.name, test.empty, empty)
-		}
-	}
-}
-
-func TestErrorContextWithTreeCopy(t *testing.T) {
-	tree, err := New("root").Parse("{{if true}}{{end}}", "", "", make(map[string]*Tree), nil)
-	if err != nil {
-		t.Fatalf("unexpected tree parse failure: %v", err)
-	}
-	treeCopy := tree.Copy()
-	wantLocation, wantContext := tree.ErrorContext(tree.Root.Nodes[0])
-	gotLocation, gotContext := treeCopy.ErrorContext(treeCopy.Root.Nodes[0])
-	if wantLocation != gotLocation {
-		t.Errorf("wrong error location want %q got %q", wantLocation, gotLocation)
-	}
-	if wantContext != gotContext {
-		t.Errorf("wrong error location want %q got %q", wantContext, gotContext)
-	}
-}
-
-// All failures, and the result is a string that must appear in the error message.
-var errorTests = []parseTest{
-	// Check line numbers are accurate.
-	{"unclosed1",
-		"line1\n{{",
-		hasError, `unclosed1:2: unexpected unclosed action in command`},
-	{"unclosed2",
-		"line1\n{{define `x`}}line2\n{{",
-		hasError, `unclosed2:3: unexpected unclosed action in command`},
-	// Specific errors.
-	{"function",
-		"{{foo}}",
-		hasError, `function "foo" not defined`},
-	{"comment",
-		"{{/*}}",
-		hasError, `unclosed comment`},
-	{"lparen",
-		"{{.X (1 2 3}}",
-		hasError, `unclosed left paren`},
-	{"rparen",
-		"{{.X 1 2 3)}}",
-		hasError, `unexpected ")"`},
-	{"space",
-		"{{`x`3}}",
-		hasError, `missing space?`},
-	{"idchar",
-		"{{a#}}",
-		hasError, `'#'`},
-	{"charconst",
-		"{{'a}}",
-		hasError, `unterminated character constant`},
-	{"stringconst",
-		`{{"a}}`,
-		hasError, `unterminated quoted string`},
-	{"rawstringconst",
-		"{{`a}}",
-		hasError, `unterminated raw quoted string`},
-	{"number",
-		"{{0xi}}",
-		hasError, `number syntax`},
-	{"multidefine",
-		"{{define `a`}}a{{end}}{{define `a`}}b{{end}}",
-		hasError, `multiple definition of template`},
-	{"eof",
-		"{{range .X}}",
-		hasError, `unexpected EOF`},
-	{"variable",
-		// Declare $x so it's defined, to avoid that error, and then check we don't parse a declaration.
-		"{{$x := 23}}{{with $x.y := 3}}{{$x 23}}{{end}}",
-		hasError, `unexpected ":="`},
-	{"multidecl",
-		"{{$a,$b,$c := 23}}",
-		hasError, `too many declarations`},
-	{"undefvar",
-		"{{$a}}",
-		hasError, `undefined variable`},
-}
-
-func TestErrors(t *testing.T) {
-	for _, test := range errorTests {
-		_, err := New(test.name).Parse(test.input, "", "", make(map[string]*Tree))
-		if err == nil {
-			t.Errorf("%q: expected error", test.name)
-			continue
-		}
-		if !strings.Contains(err.Error(), test.result) {
-			t.Errorf("%q: error %q does not contain %q", test.name, err, test.result)
-		}
-	}
-}
diff --git a/src/pkg/time/Makefile b/src/pkg/time/Makefile
deleted file mode 100644
index cba58e4..0000000
--- a/src/pkg/time/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
-# Copyright 2013 The Go Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style
-# license that can be found in the LICENSE file.
-
-genzabbrs: genzabbrs.go
-	go build genzabbrs.go
-
-windows: genzabbrs
-	./genzabbrs | gofmt >zoneinfo_abbrs_windows.go
diff --git a/src/pkg/time/example_test.go b/src/pkg/time/example_test.go
deleted file mode 100644
index cfa5b38..0000000
--- a/src/pkg/time/example_test.go
+++ /dev/null
@@ -1,160 +0,0 @@
-// Copyright 2011 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package time_test
-
-import (
-	"fmt"
-	"time"
-)
-
-func expensiveCall() {}
-
-func ExampleDuration() {
-	t0 := time.Now()
-	expensiveCall()
-	t1 := time.Now()
-	fmt.Printf("The call took %v to run.\n", t1.Sub(t0))
-}
-
-var c chan int
-
-func handle(int) {}
-
-func ExampleAfter() {
-	select {
-	case m := <-c:
-		handle(m)
-	case <-time.After(5 * time.Minute):
-		fmt.Println("timed out")
-	}
-}
-
-func ExampleSleep() {
-	time.Sleep(100 * time.Millisecond)
-}
-
-func statusUpdate() string { return "" }
-
-func ExampleTick() {
-	c := time.Tick(1 * time.Minute)
-	for now := range c {
-		fmt.Printf("%v %s\n", now, statusUpdate())
-	}
-}
-
-func ExampleMonth() {
-	_, month, day := time.Now().Date()
-	if month == time.November && day == 10 {
-		fmt.Println("Happy Go day!")
-	}
-}
-
-func ExampleDate() {
-	t := time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC)
-	fmt.Printf("Go launched at %s\n", t.Local())
-	// Output: Go launched at 2009-11-10 15:00:00 -0800 PST
-}
-
-func ExampleTime_Format() {
-	// layout shows by example how the reference time should be represented.
-	const layout = "Jan 2, 2006 at 3:04pm (MST)"
-	t := time.Date(2009, time.November, 10, 15, 0, 0, 0, time.Local)
-	fmt.Println(t.Format(layout))
-	fmt.Println(t.UTC().Format(layout))
-	// Output:
-	// Nov 10, 2009 at 3:00pm (PST)
-	// Nov 10, 2009 at 11:00pm (UTC)
-}
-
-func ExampleParse() {
-	// longForm shows by example how the reference time would be represented in
-	// the desired layout.
-	const longForm = "Jan 2, 2006 at 3:04pm (MST)"
-	t, _ := time.Parse(longForm, "Feb 3, 2013 at 7:54pm (PST)")
-	fmt.Println(t)
-
-	// shortForm is another way the reference time would be represented
-	// in the desired layout; it has no time zone present.
-	// Note: without explicit zone, returns time in UTC.
-	const shortForm = "2006-Jan-02"
-	t, _ = time.Parse(shortForm, "2013-Feb-03")
-	fmt.Println(t)
-
-	// Output:
-	// 2013-02-03 19:54:00 -0800 PST
-	// 2013-02-03 00:00:00 +0000 UTC
-}
-
-func ExampleParseInLocation() {
-	loc, _ := time.LoadLocation("Europe/Berlin")
-
-	const longForm = "Jan 2, 2006 at 3:04pm (MST)"
-	t, _ := time.ParseInLocation(longForm, "Jul 9, 2012 at 5:02am (CEST)", loc)
-	fmt.Println(t)
-
-	// Note: without explicit zone, returns time in given location.
-	const shortForm = "2006-Jan-02"
-	t, _ = time.ParseInLocation(shortForm, "2012-Jul-09", loc)
-	fmt.Println(t)
-
-	// Output:
-	// 2012-07-09 05:02:00 +0200 CEST
-	// 2012-07-09 00:00:00 +0200 CEST
-}
-
-func ExampleTime_Round() {
-	t := time.Date(0, 0, 0, 12, 15, 30, 918273645, time.UTC)
-	round := []time.Duration{
-		time.Nanosecond,
-		time.Microsecond,
-		time.Millisecond,
-		time.Second,
-		2 * time.Second,
-		time.Minute,
-		10 * time.Minute,
-		time.Hour,
-	}
-
-	for _, d := range round {
-		fmt.Printf("t.Round(%6s) = %s\n", d, t.Round(d).Format("15:04:05.999999999"))
-	}
-	// Output:
-	// t.Round(   1ns) = 12:15:30.918273645
-	// t.Round(   1us) = 12:15:30.918274
-	// t.Round(   1ms) = 12:15:30.918
-	// t.Round(    1s) = 12:15:31
-	// t.Round(    2s) = 12:15:30
-	// t.Round(  1m0s) = 12:16:00
-	// t.Round( 10m0s) = 12:20:00
-	// t.Round(1h0m0s) = 12:00:00
-}
-
-func ExampleTime_Truncate() {
-	t, _ := time.Parse("2006 Jan 02 15:04:05", "2012 Dec 07 12:15:30.918273645")
-	trunc := []time.Duration{
-		time.Nanosecond,
-		time.Microsecond,
-		time.Millisecond,
-		time.Second,
-		2 * time.Second,
-		time.Minute,
-		10 * time.Minute,
-		time.Hour,
-	}
-
-	for _, d := range trunc {
-		fmt.Printf("t.Truncate(%6s) = %s\n", d, t.Truncate(d).Format("15:04:05.999999999"))
-	}
-
-	// Output:
-	// t.Truncate(   1ns) = 12:15:30.918273645
-	// t.Truncate(   1us) = 12:15:30.918273
-	// t.Truncate(   1ms) = 12:15:30.918
-	// t.Truncate(    1s) = 12:15:30
-	// t.Truncate(    2s) = 12:15:30
-	// t.Truncate(  1m0s) = 12:15:00
-	// t.Truncate( 10m0s) = 12:10:00
-	// t.Truncate(1h0m0s) = 12:00:00
-}
diff --git a/src/pkg/time/format.go b/src/pkg/time/format.go
deleted file mode 100644
index 9f210ea..0000000
--- a/src/pkg/time/format.go
+++ /dev/null
@@ -1,1247 +0,0 @@
-// Copyright 2010 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package time
-
-import "errors"
-
-// These are predefined layouts for use in Time.Format and Time.Parse.
-// The reference time used in the layouts is:
-//	Mon Jan 2 15:04:05 MST 2006
-// which is Unix time 1136239445. Since MST is GMT-0700,
-// the reference time can be thought of as
-//	01/02 03:04:05PM '06 -0700
-// To define your own format, write down what the reference time would look
-// like formatted your way; see the values of constants like ANSIC,
-// StampMicro or Kitchen for examples. The model is to demonstrate what the
-// reference time looks like so that the Format and Parse methods can apply
-// the same transformation to a general time value.
-//
-// Within the format string, an underscore _ represents a space that may be
-// replaced by a digit if the following number (a day) has two digits; for
-// compatibility with fixed-width Unix time formats.
-//
-// A decimal point followed by one or more zeros represents a fractional
-// second, printed to the given number of decimal places.  A decimal point
-// followed by one or more nines represents a fractional second, printed to
-// the given number of decimal places, with trailing zeros removed.
-// When parsing (only), the input may contain a fractional second
-// field immediately after the seconds field, even if the layout does not
-// signify its presence. In that case a decimal point followed by a maximal
-// series of digits is parsed as a fractional second.
-//
-// Numeric time zone offsets format as follows:
-//	-0700  ±hhmm
-//	-07:00 ±hh:mm
-// Replacing the sign in the format with a Z triggers
-// the ISO 8601 behavior of printing Z instead of an
-// offset for the UTC zone.  Thus:
-//	Z0700  Z or ±hhmm
-//	Z07:00 Z or ±hh:mm
-const (
-	ANSIC       = "Mon Jan _2 15:04:05 2006"
-	UnixDate    = "Mon Jan _2 15:04:05 MST 2006"
-	RubyDate    = "Mon Jan 02 15:04:05 -0700 2006"
-	RFC822      = "02 Jan 06 15:04 MST"
-	RFC822Z     = "02 Jan 06 15:04 -0700" // RFC822 with numeric zone
-	RFC850      = "Monday, 02-Jan-06 15:04:05 MST"
-	RFC1123     = "Mon, 02 Jan 2006 15:04:05 MST"
-	RFC1123Z    = "Mon, 02 Jan 2006 15:04:05 -0700" // RFC1123 with numeric zone
-	RFC3339     = "2006-01-02T15:04:05Z07:00"
-	RFC3339Nano = "2006-01-02T15:04:05.999999999Z07:00"
-	Kitchen     = "3:04PM"
-	// Handy time stamps.
-	Stamp      = "Jan _2 15:04:05"
-	StampMilli = "Jan _2 15:04:05.000"
-	StampMicro = "Jan _2 15:04:05.000000"
-	StampNano  = "Jan _2 15:04:05.000000000"
-)
-
-const (
-	_                        = iota
-	stdLongMonth             = iota + stdNeedDate  // "January"
-	stdMonth                                       // "Jan"
-	stdNumMonth                                    // "1"
-	stdZeroMonth                                   // "01"
-	stdLongWeekDay                                 // "Monday"
-	stdWeekDay                                     // "Mon"
-	stdDay                                         // "2"
-	stdUnderDay                                    // "_2"
-	stdZeroDay                                     // "02"
-	stdHour                  = iota + stdNeedClock // "15"
-	stdHour12                                      // "3"
-	stdZeroHour12                                  // "03"
-	stdMinute                                      // "4"
-	stdZeroMinute                                  // "04"
-	stdSecond                                      // "5"
-	stdZeroSecond                                  // "05"
-	stdLongYear              = iota + stdNeedDate  // "2006"
-	stdYear                                        // "06"
-	stdPM                    = iota + stdNeedClock // "PM"
-	stdpm                                          // "pm"
-	stdTZ                    = iota                // "MST"
-	stdISO8601TZ                                   // "Z0700"  // prints Z for UTC
-	stdISO8601SecondsTZ                            // "Z070000"
-	stdISO8601ColonTZ                              // "Z07:00" // prints Z for UTC
-	stdISO8601ColonSecondsTZ                       // "Z07:00:00"
-	stdNumTZ                                       // "-0700"  // always numeric
-	stdNumSecondsTz                                // "-070000"
-	stdNumShortTZ                                  // "-07"    // always numeric
-	stdNumColonTZ                                  // "-07:00" // always numeric
-	stdNumColonSecondsTZ                           // "-07:00:00"
-	stdFracSecond0                                 // ".0", ".00", ... , trailing zeros included
-	stdFracSecond9                                 // ".9", ".99", ..., trailing zeros omitted
-
-	stdNeedDate  = 1 << 8             // need month, day, year
-	stdNeedClock = 2 << 8             // need hour, minute, second
-	stdArgShift  = 16                 // extra argument in high bits, above low stdArgShift
-	stdMask      = 1<<stdArgShift - 1 // mask out argument
-)
-
-// std0x records the std values for "01", "02", ..., "06".
-var std0x = [...]int{stdZeroMonth, stdZeroDay, stdZeroHour12, stdZeroMinute, stdZeroSecond, stdYear}
-
-// startsWithLowerCase reports whether the string has a lower-case letter at the beginning.
-// Its purpose is to prevent matching strings like "Month" when looking for "Mon".
-func startsWithLowerCase(str string) bool {
-	if len(str) == 0 {
-		return false
-	}
-	c := str[0]
-	return 'a' <= c && c <= 'z'
-}
-
-// nextStdChunk finds the first occurrence of a std string in
-// layout and returns the text before, the std string, and the text after.
-func nextStdChunk(layout string) (prefix string, std int, suffix string) {
-	for i := 0; i < len(layout); i++ {
-		switch c := int(layout[i]); c {
-		case 'J': // January, Jan
-			if len(layout) >= i+3 && layout[i:i+3] == "Jan" {
-				if len(layout) >= i+7 && layout[i:i+7] == "January" {
-					return layout[0:i], stdLongMonth, layout[i+7:]
-				}
-				if !startsWithLowerCase(layout[i+3:]) {
-					return layout[0:i], stdMonth, layout[i+3:]
-				}
-			}
-
-		case 'M': // Monday, Mon, MST
-			if len(layout) >= i+3 {
-				if layout[i:i+3] == "Mon" {
-					if len(layout) >= i+6 && layout[i:i+6] == "Monday" {
-						return layout[0:i], stdLongWeekDay, layout[i+6:]
-					}
-					if !startsWithLowerCase(layout[i+3:]) {
-						return layout[0:i], stdWeekDay, layout[i+3:]
-					}
-				}
-				if layout[i:i+3] == "MST" {
-					return layout[0:i], stdTZ, layout[i+3:]
-				}
-			}
-
-		case '0': // 01, 02, 03, 04, 05, 06
-			if len(layout) >= i+2 && '1' <= layout[i+1] && layout[i+1] <= '6' {
-				return layout[0:i], std0x[layout[i+1]-'1'], layout[i+2:]
-			}
-
-		case '1': // 15, 1
-			if len(layout) >= i+2 && layout[i+1] == '5' {
-				return layout[0:i], stdHour, layout[i+2:]
-			}
-			return layout[0:i], stdNumMonth, layout[i+1:]
-
-		case '2': // 2006, 2
-			if len(layout) >= i+4 && layout[i:i+4] == "2006" {
-				return layout[0:i], stdLongYear, layout[i+4:]
-			}
-			return layout[0:i], stdDay, layout[i+1:]
-
-		case '_': // _2
-			if len(layout) >= i+2 && layout[i+1] == '2' {
-				return layout[0:i], stdUnderDay, layout[i+2:]
-			}
-
-		case '3':
-			return layout[0:i], stdHour12, layout[i+1:]
-
-		case '4':
-			return layout[0:i], stdMinute, layout[i+1:]
-
-		case '5':
-			return layout[0:i], stdSecond, layout[i+1:]
-
-		case 'P': // PM
-			if len(layout) >= i+2 && layout[i+1] == 'M' {
-				return layout[0:i], stdPM, layout[i+2:]
-			}
-
-		case 'p': // pm
-			if len(layout) >= i+2 && layout[i+1] == 'm' {
-				return layout[0:i], stdpm, layout[i+2:]
-			}
-
-		case '-': // -070000, -07:00:00, -0700, -07:00, -07
-			if len(layout) >= i+7 && layout[i:i+7] == "-070000" {
-				return layout[0:i], stdNumSecondsTz, layout[i+7:]
-			}
-			if len(layout) >= i+9 && layout[i:i+9] == "-07:00:00" {
-				return layout[0:i], stdNumColonSecondsTZ, layout[i+9:]
-			}
-			if len(layout) >= i+5 && layout[i:i+5] == "-0700" {
-				return layout[0:i], stdNumTZ, layout[i+5:]
-			}
-			if len(layout) >= i+6 && layout[i:i+6] == "-07:00" {
-				return layout[0:i], stdNumColonTZ, layout[i+6:]
-			}
-			if len(layout) >= i+3 && layout[i:i+3] == "-07" {
-				return layout[0:i], stdNumShortTZ, layout[i+3:]
-			}
-
-		case 'Z': // Z070000, Z07:00:00, Z0700, Z07:00,
-			if len(layout) >= i+7 && layout[i:i+7] == "Z070000" {
-				return layout[0:i], stdISO8601SecondsTZ, layout[i+7:]
-			}
-			if len(layout) >= i+9 && layout[i:i+9] == "Z07:00:00" {
-				return layout[0:i], stdISO8601ColonSecondsTZ, layout[i+9:]
-			}
-			if len(layout) >= i+5 && layout[i:i+5] == "Z0700" {
-				return layout[0:i], stdISO8601TZ, layout[i+5:]
-			}
-			if len(layout) >= i+6 && layout[i:i+6] == "Z07:00" {
-				return layout[0:i], stdISO8601ColonTZ, layout[i+6:]
-			}
-
-		case '.': // .000 or .999 - repeated digits for fractional seconds.
-			if i+1 < len(layout) && (layout[i+1] == '0' || layout[i+1] == '9') {
-				ch := layout[i+1]
-				j := i + 1
-				for j < len(layout) && layout[j] == ch {
-					j++
-				}
-				// String of digits must end here - only fractional second is all digits.
-				if !isDigit(layout, j) {
-					std := stdFracSecond0
-					if layout[i+1] == '9' {
-						std = stdFracSecond9
-					}
-					std |= (j - (i + 1)) << stdArgShift
-					return layout[0:i], std, layout[j:]
-				}
-			}
-		}
-	}
-	return layout, 0, ""
-}
-
-var longDayNames = []string{
-	"Sunday",
-	"Monday",
-	"Tuesday",
-	"Wednesday",
-	"Thursday",
-	"Friday",
-	"Saturday",
-}
-
-var shortDayNames = []string{
-	"Sun",
-	"Mon",
-	"Tue",
-	"Wed",
-	"Thu",
-	"Fri",
-	"Sat",
-}
-
-var shortMonthNames = []string{
-	"---",
-	"Jan",
-	"Feb",
-	"Mar",
-	"Apr",
-	"May",
-	"Jun",
-	"Jul",
-	"Aug",
-	"Sep",
-	"Oct",
-	"Nov",
-	"Dec",
-}
-
-var longMonthNames = []string{
-	"---",
-	"January",
-	"February",
-	"March",
-	"April",
-	"May",
-	"June",
-	"July",
-	"August",
-	"September",
-	"October",
-	"November",
-	"December",
-}
-
-// match returns true if s1 and s2 match ignoring case.
-// It is assumed s1 and s2 are the same length.
-func match(s1, s2 string) bool {
-	for i := 0; i < len(s1); i++ {
-		c1 := s1[i]
-		c2 := s2[i]
-		if c1 != c2 {
-			// Switch to lower-case; 'a'-'A' is known to be a single bit.
-			c1 |= 'a' - 'A'
-			c2 |= 'a' - 'A'
-			if c1 != c2 || c1 < 'a' || c1 > 'z' {
-				return false
-			}
-		}
-	}
-	return true
-}
-
-func lookup(tab []string, val string) (int, string, error) {
-	for i, v := range tab {
-		if len(val) >= len(v) && match(val[0:len(v)], v) {
-			return i, val[len(v):], nil
-		}
-	}
-	return -1, val, errBad
-}
-
-// appendUint appends the decimal form of x to b and returns the result.
-// If x is a single-digit number and pad != 0, appendUint inserts the pad byte
-// before the digit.
-// Duplicates functionality in strconv, but avoids dependency.
-func appendUint(b []byte, x uint, pad byte) []byte {
-	if x < 10 {
-		if pad != 0 {
-			b = append(b, pad)
-		}
-		return append(b, byte('0'+x))
-	}
-	if x < 100 {
-		b = append(b, byte('0'+x/10))
-		b = append(b, byte('0'+x%10))
-		return b
-	}
-
-	var buf [32]byte
-	n := len(buf)
-	if x == 0 {
-		return append(b, '0')
-	}
-	for x >= 10 {
-		n--
-		buf[n] = byte(x%10 + '0')
-		x /= 10
-	}
-	n--
-	buf[n] = byte(x + '0')
-	return append(b, buf[n:]...)
-}
-
-// Never printed, just needs to be non-nil for return by atoi.
-var atoiError = errors.New("time: invalid number")
-
-// Duplicates functionality in strconv, but avoids dependency.
-func atoi(s string) (x int, err error) {
-	neg := false
-	if s != "" && (s[0] == '-' || s[0] == '+') {
-		neg = s[0] == '-'
-		s = s[1:]
-	}
-	q, rem, err := leadingInt(s)
-	x = int(q)
-	if err != nil || rem != "" {
-		return 0, atoiError
-	}
-	if neg {
-		x = -x
-	}
-	return x, nil
-}
-
-// formatNano appends a fractional second, as nanoseconds, to b
-// and returns the result.
-func formatNano(b []byte, nanosec uint, n int, trim bool) []byte {
-	u := nanosec
-	var buf [9]byte
-	for start := len(buf); start > 0; {
-		start--
-		buf[start] = byte(u%10 + '0')
-		u /= 10
-	}
-
-	if n > 9 {
-		n = 9
-	}
-	if trim {
-		for n > 0 && buf[n-1] == '0' {
-			n--
-		}
-		if n == 0 {
-			return b
-		}
-	}
-	b = append(b, '.')
-	return append(b, buf[:n]...)
-}
-
-// String returns the time formatted using the format string
-//	"2006-01-02 15:04:05.999999999 -0700 MST"
-func (t Time) String() string {
-	return t.Format("2006-01-02 15:04:05.999999999 -0700 MST")
-}
-
-// Format returns a textual representation of the time value formatted
-// according to layout, which defines the format by showing how the reference
-// time,
-//	Mon Jan 2 15:04:05 -0700 MST 2006
-// would be displayed if it were the value; it serves as an example of the
-// desired output. The same display rules will then be applied to the time
-// value.
-// Predefined layouts ANSIC, UnixDate, RFC3339 and others describe standard
-// and convenient representations of the reference time. For more information
-// about the formats and the definition of the reference time, see the
-// documentation for ANSIC and the other constants defined by this package.
-func (t Time) Format(layout string) string {
-	var (
-		name, offset, abs = t.locabs()
-
-		year  int = -1
-		month Month
-		day   int
-		hour  int = -1
-		min   int
-		sec   int
-
-		b   []byte
-		buf [64]byte
-	)
-	max := len(layout) + 10
-	if max <= len(buf) {
-		b = buf[:0]
-	} else {
-		b = make([]byte, 0, max)
-	}
-	// Each iteration generates one std value.
-	for layout != "" {
-		prefix, std, suffix := nextStdChunk(layout)
-		if prefix != "" {
-			b = append(b, prefix...)
-		}
-		if std == 0 {
-			break
-		}
-		layout = suffix
-
-		// Compute year, month, day if needed.
-		if year < 0 && std&stdNeedDate != 0 {
-			year, month, day, _ = absDate(abs, true)
-		}
-
-		// Compute hour, minute, second if needed.
-		if hour < 0 && std&stdNeedClock != 0 {
-			hour, min, sec = absClock(abs)
-		}
-
-		switch std & stdMask {
-		case stdYear:
-			y := year
-			if y < 0 {
-				y = -y
-			}
-			b = appendUint(b, uint(y%100), '0')
-		case stdLongYear:
-			// Pad year to at least 4 digits.
-			y := year
-			switch {
-			case year <= -1000:
-				b = append(b, '-')
-				y = -y
-			case year <= -100:
-				b = append(b, "-0"...)
-				y = -y
-			case year <= -10:
-				b = append(b, "-00"...)
-				y = -y
-			case year < 0:
-				b = append(b, "-000"...)
-				y = -y
-			case year < 10:
-				b = append(b, "000"...)
-			case year < 100:
-				b = append(b, "00"...)
-			case year < 1000:
-				b = append(b, '0')
-			}
-			b = appendUint(b, uint(y), 0)
-		case stdMonth:
-			b = append(b, month.String()[:3]...)
-		case stdLongMonth:
-			m := month.String()
-			b = append(b, m...)
-		case stdNumMonth:
-			b = appendUint(b, uint(month), 0)
-		case stdZeroMonth:
-			b = appendUint(b, uint(month), '0')
-		case stdWeekDay:
-			b = append(b, absWeekday(abs).String()[:3]...)
-		case stdLongWeekDay:
-			s := absWeekday(abs).String()
-			b = append(b, s...)
-		case stdDay:
-			b = appendUint(b, uint(day), 0)
-		case stdUnderDay:
-			b = appendUint(b, uint(day), ' ')
-		case stdZeroDay:
-			b = appendUint(b, uint(day), '0')
-		case stdHour:
-			b = appendUint(b, uint(hour), '0')
-		case stdHour12:
-			// Noon is 12PM, midnight is 12AM.
-			hr := hour % 12
-			if hr == 0 {
-				hr = 12
-			}
-			b = appendUint(b, uint(hr), 0)
-		case stdZeroHour12:
-			// Noon is 12PM, midnight is 12AM.
-			hr := hour % 12
-			if hr == 0 {
-				hr = 12
-			}
-			b = appendUint(b, uint(hr), '0')
-		case stdMinute:
-			b = appendUint(b, uint(min), 0)
-		case stdZeroMinute:
-			b = appendUint(b, uint(min), '0')
-		case stdSecond:
-			b = appendUint(b, uint(sec), 0)
-		case stdZeroSecond:
-			b = appendUint(b, uint(sec), '0')
-		case stdPM:
-			if hour >= 12 {
-				b = append(b, "PM"...)
-			} else {
-				b = append(b, "AM"...)
-			}
-		case stdpm:
-			if hour >= 12 {
-				b = append(b, "pm"...)
-			} else {
-				b = append(b, "am"...)
-			}
-		case stdISO8601TZ, stdISO8601ColonTZ, stdISO8601SecondsTZ, stdISO8601ColonSecondsTZ, stdNumTZ, stdNumColonTZ, stdNumSecondsTz, stdNumColonSecondsTZ:
-			// Ugly special case.  We cheat and take the "Z" variants
-			// to mean "the time zone as formatted for ISO 8601".
-			if offset == 0 && (std == stdISO8601TZ || std == stdISO8601ColonTZ || std == stdISO8601SecondsTZ || std == stdISO8601ColonSecondsTZ) {
-				b = append(b, 'Z')
-				break
-			}
-			zone := offset / 60 // convert to minutes
-			absoffset := offset
-			if zone < 0 {
-				b = append(b, '-')
-				zone = -zone
-				absoffset = -absoffset
-			} else {
-				b = append(b, '+')
-			}
-			b = appendUint(b, uint(zone/60), '0')
-			if std == stdISO8601ColonTZ || std == stdNumColonTZ {
-				b = append(b, ':')
-			}
-			b = appendUint(b, uint(zone%60), '0')
-
-			// append seconds if appropriate
-			if std == stdISO8601SecondsTZ || std == stdNumSecondsTz || std == stdNumColonSecondsTZ || std == stdISO8601ColonSecondsTZ {
-				if std == stdNumColonSecondsTZ || std == stdISO8601ColonSecondsTZ {
-					b = append(b, ':')
-				}
-				b = appendUint(b, uint(absoffset%60), '0')
-			}
-
-		case stdTZ:
-			if name != "" {
-				b = append(b, name...)
-				break
-			}
-			// No time zone known for this time, but we must print one.
-			// Use the -0700 format.
-			zone := offset / 60 // convert to minutes
-			if zone < 0 {
-				b = append(b, '-')
-				zone = -zone
-			} else {
-				b = append(b, '+')
-			}
-			b = appendUint(b, uint(zone/60), '0')
-			b = appendUint(b, uint(zone%60), '0')
-		case stdFracSecond0, stdFracSecond9:
-			b = formatNano(b, uint(t.Nanosecond()), std>>stdArgShift, std&stdMask == stdFracSecond9)
-		}
-	}
-	return string(b)
-}
-
-var errBad = errors.New("bad value for field") // placeholder not passed to user
-
-// ParseError describes a problem parsing a time string.
-type ParseError struct {
-	Layout     string
-	Value      string
-	LayoutElem string
-	ValueElem  string
-	Message    string
-}
-
-func quote(s string) string {
-	return "\"" + s + "\""
-}
-
-// Error returns the string representation of a ParseError.
-func (e *ParseError) Error() string {
-	if e.Message == "" {
-		return "parsing time " +
-			quote(e.Value) + " as " +
-			quote(e.Layout) + ": cannot parse " +
-			quote(e.ValueElem) + " as " +
-			quote(e.LayoutElem)
-	}
-	return "parsing time " +
-		quote(e.Value) + e.Message
-}
-
-// isDigit returns true if s[i] is a decimal digit, false if not or
-// if s[i] is out of range.
-func isDigit(s string, i int) bool {
-	if len(s) <= i {
-		return false
-	}
-	c := s[i]
-	return '0' <= c && c <= '9'
-}
-
-// getnum parses s[0:1] or s[0:2] (fixed forces the latter)
-// as a decimal integer and returns the integer and the
-// remainder of the string.
-func getnum(s string, fixed bool) (int, string, error) {
-	if !isDigit(s, 0) {
-		return 0, s, errBad
-	}
-	if !isDigit(s, 1) {
-		if fixed {
-			return 0, s, errBad
-		}
-		return int(s[0] - '0'), s[1:], nil
-	}
-	return int(s[0]-'0')*10 + int(s[1]-'0'), s[2:], nil
-}
-
-func cutspace(s string) string {
-	for len(s) > 0 && s[0] == ' ' {
-		s = s[1:]
-	}
-	return s
-}
-
-// skip removes the given prefix from value,
-// treating runs of space characters as equivalent.
-func skip(value, prefix string) (string, error) {
-	for len(prefix) > 0 {
-		if prefix[0] == ' ' {
-			if len(value) > 0 && value[0] != ' ' {
-				return value, errBad
-			}
-			prefix = cutspace(prefix)
-			value = cutspace(value)
-			continue
-		}
-		if len(value) == 0 || value[0] != prefix[0] {
-			return value, errBad
-		}
-		prefix = prefix[1:]
-		value = value[1:]
-	}
-	return value, nil
-}
-
-// Parse parses a formatted string and returns the time value it represents.
-// The layout  defines the format by showing how the reference time,
-//	Mon Jan 2 15:04:05 -0700 MST 2006
-// would be interpreted if it were the value; it serves as an example of
-// the input format. The same interpretation will then be made to the
-// input string.
-// Predefined layouts ANSIC, UnixDate, RFC3339 and others describe standard
-// and convenient representations of the reference time. For more information
-// about the formats and the definition of the reference time, see the
-// documentation for ANSIC and the other constants defined by this package.
-//
-// Elements omitted from the value are assumed to be zero or, when
-// zero is impossible, one, so parsing "3:04pm" returns the time
-// corresponding to Jan 1, year 0, 15:04:00 UTC (note that because the year is
-// 0, this time is before the zero Time).
-// Years must be in the range 0000..9999. The day of the week is checked
-// for syntax but it is otherwise ignored.
-//
-// In the absence of a time zone indicator, Parse returns a time in UTC.
-//
-// When parsing a time with a zone offset like -0700, if the offset corresponds
-// to a time zone used by the current location (Local), then Parse uses that
-// location and zone in the returned time. Otherwise it records the time as
-// being in a fabricated location with time fixed at the given zone offset.
-//
-// When parsing a time with a zone abbreviation like MST, if the zone abbreviation
-// has a defined offset in the current location, then that offset is used.
-// The zone abbreviation "UTC" is recognized as UTC regardless of location.
-// If the zone abbreviation is unknown, Parse records the time as being
-// in a fabricated location with the given zone abbreviation and a zero offset.
-// This choice means that such a time can be parse and reformatted with the
-// same layout losslessly, but the exact instant used in the representation will
-// differ by the actual zone offset. To avoid such problems, prefer time layouts
-// that use a numeric zone offset, or use ParseInLocation.
-func Parse(layout, value string) (Time, error) {
-	return parse(layout, value, UTC, Local)
-}
-
-// ParseInLocation is like Parse but differs in two important ways.
-// First, in the absence of time zone information, Parse interprets a time as UTC;
-// ParseInLocation interprets the time as in the given location.
-// Second, when given a zone offset or abbreviation, Parse tries to match it
-// against the Local location; ParseInLocation uses the given location.
-func ParseInLocation(layout, value string, loc *Location) (Time, error) {
-	return parse(layout, value, loc, loc)
-}
-
-func parse(layout, value string, defaultLocation, local *Location) (Time, error) {
-	alayout, avalue := layout, value
-	rangeErrString := "" // set if a value is out of range
-	amSet := false       // do we need to subtract 12 from the hour for midnight?
-	pmSet := false       // do we need to add 12 to the hour?
-
-	// Time being constructed.
-	var (
-		year       int
-		month      int = 1 // January
-		day        int = 1
-		hour       int
-		min        int
-		sec        int
-		nsec       int
-		z          *Location
-		zoneOffset int = -1
-		zoneName   string
-	)
-
-	// Each iteration processes one std value.
-	for {
-		var err error
-		prefix, std, suffix := nextStdChunk(layout)
-		stdstr := layout[len(prefix) : len(layout)-len(suffix)]
-		value, err = skip(value, prefix)
-		if err != nil {
-			return Time{}, &ParseError{alayout, avalue, prefix, value, ""}
-		}
-		if std == 0 {
-			if len(value) != 0 {
-				return Time{}, &ParseError{alayout, avalue, "", value, ": extra text: " + value}
-			}
-			break
-		}
-		layout = suffix
-		var p string
-		switch std & stdMask {
-		case stdYear:
-			if len(value) < 2 {
-				err = errBad
-				break
-			}
-			p, value = value[0:2], value[2:]
-			year, err = atoi(p)
-			if year >= 69 { // Unix time starts Dec 31 1969 in some time zones
-				year += 1900
-			} else {
-				year += 2000
-			}
-		case stdLongYear:
-			if len(value) < 4 || !isDigit(value, 0) {
-				err = errBad
-				break
-			}
-			p, value = value[0:4], value[4:]
-			year, err = atoi(p)
-		case stdMonth:
-			month, value, err = lookup(shortMonthNames, value)
-		case stdLongMonth:
-			month, value, err = lookup(longMonthNames, value)
-		case stdNumMonth, stdZeroMonth:
-			month, value, err = getnum(value, std == stdZeroMonth)
-			if month <= 0 || 12 < month {
-				rangeErrString = "month"
-			}
-		case stdWeekDay:
-			// Ignore weekday except for error checking.
-			_, value, err = lookup(shortDayNames, value)
-		case stdLongWeekDay:
-			_, value, err = lookup(longDayNames, value)
-		case stdDay, stdUnderDay, stdZeroDay:
-			if std == stdUnderDay && len(value) > 0 && value[0] == ' ' {
-				value = value[1:]
-			}
-			day, value, err = getnum(value, std == stdZeroDay)
-			if day < 0 || 31 < day {
-				rangeErrString = "day"
-			}
-		case stdHour:
-			hour, value, err = getnum(value, false)
-			if hour < 0 || 24 <= hour {
-				rangeErrString = "hour"
-			}
-		case stdHour12, stdZeroHour12:
-			hour, value, err = getnum(value, std == stdZeroHour12)
-			if hour < 0 || 12 < hour {
-				rangeErrString = "hour"
-			}
-		case stdMinute, stdZeroMinute:
-			min, value, err = getnum(value, std == stdZeroMinute)
-			if min < 0 || 60 <= min {
-				rangeErrString = "minute"
-			}
-		case stdSecond, stdZeroSecond:
-			sec, value, err = getnum(value, std == stdZeroSecond)
-			if sec < 0 || 60 <= sec {
-				rangeErrString = "second"
-			}
-			// Special case: do we have a fractional second but no
-			// fractional second in the format?
-			if len(value) >= 2 && value[0] == '.' && isDigit(value, 1) {
-				_, std, _ = nextStdChunk(layout)
-				std &= stdMask
-				if std == stdFracSecond0 || std == stdFracSecond9 {
-					// Fractional second in the layout; proceed normally
-					break
-				}
-				// No fractional second in the layout but we have one in the input.
-				n := 2
-				for ; n < len(value) && isDigit(value, n); n++ {
-				}
-				nsec, rangeErrString, err = parseNanoseconds(value, n)
-				value = value[n:]
-			}
-		case stdPM:
-			if len(value) < 2 {
-				err = errBad
-				break
-			}
-			p, value = value[0:2], value[2:]
-			switch p {
-			case "PM":
-				pmSet = true
-			case "AM":
-				amSet = true
-			default:
-				err = errBad
-			}
-		case stdpm:
-			if len(value) < 2 {
-				err = errBad
-				break
-			}
-			p, value = value[0:2], value[2:]
-			switch p {
-			case "pm":
-				pmSet = true
-			case "am":
-				amSet = true
-			default:
-				err = errBad
-			}
-		case stdISO8601TZ, stdISO8601ColonTZ, stdISO8601SecondsTZ, stdISO8601ColonSecondsTZ, stdNumTZ, stdNumShortTZ, stdNumColonTZ, stdNumSecondsTz, stdNumColonSecondsTZ:
-			if (std == stdISO8601TZ || std == stdISO8601ColonTZ) && len(value) >= 1 && value[0] == 'Z' {
-				value = value[1:]
-				z = UTC
-				break
-			}
-			var sign, hour, min, seconds string
-			if std == stdISO8601ColonTZ || std == stdNumColonTZ {
-				if len(value) < 6 {
-					err = errBad
-					break
-				}
-				if value[3] != ':' {
-					err = errBad
-					break
-				}
-				sign, hour, min, seconds, value = value[0:1], value[1:3], value[4:6], "00", value[6:]
-			} else if std == stdNumShortTZ {
-				if len(value) < 3 {
-					err = errBad
-					break
-				}
-				sign, hour, min, seconds, value = value[0:1], value[1:3], "00", "00", value[3:]
-			} else if std == stdISO8601ColonSecondsTZ || std == stdNumColonSecondsTZ {
-				if len(value) < 9 {
-					err = errBad
-					break
-				}
-				if value[3] != ':' || value[6] != ':' {
-					err = errBad
-					break
-				}
-				sign, hour, min, seconds, value = value[0:1], value[1:3], value[4:6], value[7:9], value[9:]
-			} else if std == stdISO8601SecondsTZ || std == stdNumSecondsTz {
-				if len(value) < 7 {
-					err = errBad
-					break
-				}
-				sign, hour, min, seconds, value = value[0:1], value[1:3], value[3:5], value[5:7], value[7:]
-			} else {
-				if len(value) < 5 {
-					err = errBad
-					break
-				}
-				sign, hour, min, seconds, value = value[0:1], value[1:3], value[3:5], "00", value[5:]
-			}
-			var hr, mm, ss int
-			hr, err = atoi(hour)
-			if err == nil {
-				mm, err = atoi(min)
-			}
-			if err == nil {
-				ss, err = atoi(seconds)
-			}
-			zoneOffset = (hr*60+mm)*60 + ss // offset is in seconds
-			switch sign[0] {
-			case '+':
-			case '-':
-				zoneOffset = -zoneOffset
-			default:
-				err = errBad
-			}
-		case stdTZ:
-			// Does it look like a time zone?
-			if len(value) >= 3 && value[0:3] == "UTC" {
-				z = UTC
-				value = value[3:]
-				break
-			}
-			n, ok := parseTimeZone(value)
-			if !ok {
-				err = errBad
-				break
-			}
-			zoneName, value = value[:n], value[n:]
-
-		case stdFracSecond0:
-			// stdFracSecond0 requires the exact number of digits as specified in
-			// the layout.
-			ndigit := 1 + (std >> stdArgShift)
-			if len(value) < ndigit {
-				err = errBad
-				break
-			}
-			nsec, rangeErrString, err = parseNanoseconds(value, ndigit)
-			value = value[ndigit:]
-
-		case stdFracSecond9:
-			if len(value) < 2 || value[0] != '.' || value[1] < '0' || '9' < value[1] {
-				// Fractional second omitted.
-				break
-			}
-			// Take any number of digits, even more than asked for,
-			// because it is what the stdSecond case would do.
-			i := 0
-			for i < 9 && i+1 < len(value) && '0' <= value[i+1] && value[i+1] <= '9' {
-				i++
-			}
-			nsec, rangeErrString, err = parseNanoseconds(value, 1+i)
-			value = value[1+i:]
-		}
-		if rangeErrString != "" {
-			return Time{}, &ParseError{alayout, avalue, stdstr, value, ": " + rangeErrString + " out of range"}
-		}
-		if err != nil {
-			return Time{}, &ParseError{alayout, avalue, stdstr, value, ""}
-		}
-	}
-	if pmSet && hour < 12 {
-		hour += 12
-	} else if amSet && hour == 12 {
-		hour = 0
-	}
-
-	if z != nil {
-		return Date(year, Month(month), day, hour, min, sec, nsec, z), nil
-	}
-
-	if zoneOffset != -1 {
-		t := Date(year, Month(month), day, hour, min, sec, nsec, UTC)
-		t.sec -= int64(zoneOffset)
-
-		// Look for local zone with the given offset.
-		// If that zone was in effect at the given time, use it.
-		name, offset, _, _, _ := local.lookup(t.sec + internalToUnix)
-		if offset == zoneOffset && (zoneName == "" || name == zoneName) {
-			t.loc = local
-			return t, nil
-		}
-
-		// Otherwise create fake zone to record offset.
-		t.loc = FixedZone(zoneName, zoneOffset)
-		return t, nil
-	}
-
-	if zoneName != "" {
-		t := Date(year, Month(month), day, hour, min, sec, nsec, UTC)
-		// Look for local zone with the given offset.
-		// If that zone was in effect at the given time, use it.
-		offset, _, ok := local.lookupName(zoneName, t.sec+internalToUnix)
-		if ok {
-			t.sec -= int64(offset)
-			t.loc = local
-			return t, nil
-		}
-
-		// Otherwise, create fake zone with unknown offset.
-		if len(zoneName) > 3 && zoneName[:3] == "GMT" {
-			offset, _ = atoi(zoneName[3:]) // Guaranteed OK by parseGMT.
-			offset *= 3600
-		}
-		t.loc = FixedZone(zoneName, offset)
-		return t, nil
-	}
-
-	// Otherwise, fall back to default.
-	return Date(year, Month(month), day, hour, min, sec, nsec, defaultLocation), nil
-}
-
-// parseTimeZone parses a time zone string and returns its length. Time zones
-// are human-generated and unpredictable. We can't do precise error checking.
-// On the other hand, for a correct parse there must be a time zone at the
-// beginning of the string, so it's almost always true that there's one
-// there. We look at the beginning of the string for a run of upper-case letters.
-// If there are more than 5, it's an error.
-// If there are 4 or 5 and the last is a T, it's a time zone.
-// If there are 3, it's a time zone.
-// Otherwise, other than special cases, it's not a time zone.
-// GMT is special because it can have an hour offset.
-func parseTimeZone(value string) (length int, ok bool) {
-	if len(value) < 3 {
-		return 0, false
-	}
-	// Special case 1: ChST and MeST are the only zones with a lower-case letter.
-	if len(value) >= 4 && (value[:4] == "ChST" || value[:4] == "MeST") {
-		return 4, true
-	}
-	// Special case 2: GMT may have an hour offset; treat it specially.
-	if value[:3] == "GMT" {
-		length = parseGMT(value)
-		return length, true
-	}
-	// How many upper-case letters are there? Need at least three, at most five.
-	var nUpper int
-	for nUpper = 0; nUpper < 6; nUpper++ {
-		if nUpper >= len(value) {
-			break
-		}
-		if c := value[nUpper]; c < 'A' || 'Z' < c {
-			break
-		}
-	}
-	switch nUpper {
-	case 0, 1, 2, 6:
-		return 0, false
-	case 5: // Must end in T to match.
-		if value[4] == 'T' {
-			return 5, true
-		}
-	case 4: // Must end in T to match.
-		if value[3] == 'T' {
-			return 4, true
-		}
-	case 3:
-		return 3, true
-	}
-	return 0, false
-}
-
-// parseGMT parses a GMT time zone. The input string is known to start "GMT".
-// The function checks whether that is followed by a sign and a number in the
-// range -14 through 12 excluding zero.
-func parseGMT(value string) int {
-	value = value[3:]
-	if len(value) == 0 {
-		return 3
-	}
-	sign := value[0]
-	if sign != '-' && sign != '+' {
-		return 3
-	}
-	x, rem, err := leadingInt(value[1:])
-	if err != nil {
-		return 3
-	}
-	if sign == '-' {
-		x = -x
-	}
-	if x == 0 || x < -14 || 12 < x {
-		return 3
-	}
-	return 3 + len(value) - len(rem)
-}
-
-func parseNanoseconds(value string, nbytes int) (ns int, rangeErrString string, err error) {
-	if value[0] != '.' {
-		err = errBad
-		return
-	}
-	if ns, err = atoi(value[1:nbytes]); err != nil {
-		return
-	}
-	if ns < 0 || 1e9 <= ns {
-		rangeErrString = "fractional second"
-		return
-	}
-	// We need nanoseconds, which means scaling by the number
-	// of missing digits in the format, maximum length 10. If it's
-	// longer than 10, we won't scale.
-	scaleDigits := 10 - nbytes
-	for i := 0; i < scaleDigits; i++ {
-		ns *= 10
-	}
-	return
-}
-
-var errLeadingInt = errors.New("time: bad [0-9]*") // never printed
-
-// leadingInt consumes the leading [0-9]* from s.
-func leadingInt(s string) (x int64, rem string, err error) {
-	i := 0
-	for ; i < len(s); i++ {
-		c := s[i]
-		if c < '0' || c > '9' {
-			break
-		}
-		if x >= (1<<63-10)/10 {
-			// overflow
-			return 0, "", errLeadingInt
-		}
-		x = x*10 + int64(c) - '0'
-	}
-	return x, s[i:], nil
-}
-
-var unitMap = map[string]float64{
-	"ns": float64(Nanosecond),
-	"us": float64(Microsecond),
-	"µs": float64(Microsecond), // U+00B5 = micro symbol
-	"μs": float64(Microsecond), // U+03BC = Greek letter mu
-	"ms": float64(Millisecond),
-	"s":  float64(Second),
-	"m":  float64(Minute),
-	"h":  float64(Hour),
-}
-
-// ParseDuration parses a duration string.
-// A duration string is a possibly signed sequence of
-// decimal numbers, each with optional fraction and a unit suffix,
-// such as "300ms", "-1.5h" or "2h45m".
-// Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".
-func ParseDuration(s string) (Duration, error) {
-	// [-+]?([0-9]*(\.[0-9]*)?[a-z]+)+
-	orig := s
-	f := float64(0)
-	neg := false
-
-	// Consume [-+]?
-	if s != "" {
-		c := s[0]
-		if c == '-' || c == '+' {
-			neg = c == '-'
-			s = s[1:]
-		}
-	}
-	// Special case: if all that is left is "0", this is zero.
-	if s == "0" {
-		return 0, nil
-	}
-	if s == "" {
-		return 0, errors.New("time: invalid duration " + orig)
-	}
-	for s != "" {
-		g := float64(0) // this element of the sequence
-
-		var x int64
-		var err error
-
-		// The next character must be [0-9.]
-		if !(s[0] == '.' || ('0' <= s[0] && s[0] <= '9')) {
-			return 0, errors.New("time: invalid duration " + orig)
-		}
-		// Consume [0-9]*
-		pl := len(s)
-		x, s, err = leadingInt(s)
-		if err != nil {
-			return 0, errors.New("time: invalid duration " + orig)
-		}
-		g = float64(x)
-		pre := pl != len(s) // whether we consumed anything before a period
-
-		// Consume (\.[0-9]*)?
-		post := false
-		if s != "" && s[0] == '.' {
-			s = s[1:]
-			pl := len(s)
-			x, s, err = leadingInt(s)
-			if err != nil {
-				return 0, errors.New("time: invalid duration " + orig)
-			}
-			scale := 1.0
-			for n := pl - len(s); n > 0; n-- {
-				scale *= 10
-			}
-			g += float64(x) / scale
-			post = pl != len(s)
-		}
-		if !pre && !post {
-			// no digits (e.g. ".s" or "-.s")
-			return 0, errors.New("time: invalid duration " + orig)
-		}
-
-		// Consume unit.
-		i := 0
-		for ; i < len(s); i++ {
-			c := s[i]
-			if c == '.' || ('0' <= c && c <= '9') {
-				break
-			}
-		}
-		if i == 0 {
-			return 0, errors.New("time: missing unit in duration " + orig)
-		}
-		u := s[:i]
-		s = s[i:]
-		unit, ok := unitMap[u]
-		if !ok {
-			return 0, errors.New("time: unknown unit " + u + " in duration " + orig)
-		}
-
-		f += g * unit
-	}
-
-	if neg {
-		f = -f
-	}
-	if f < float64(-1<<63) || f > float64(1<<63-1) {
-		return 0, errors.New("time: overflow parsing duration")
-	}
-	return Duration(f), nil
-}
diff --git a/src/pkg/time/format_test.go b/src/pkg/time/format_test.go
deleted file mode 100644
index 46a5981..0000000
--- a/src/pkg/time/format_test.go
+++ /dev/null
@@ -1,517 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package time_test
-
-import (
-	"fmt"
-	"strconv"
-	"strings"
-	"testing"
-	"testing/quick"
-	. "time"
-)
-
-type TimeFormatTest struct {
-	time           Time
-	formattedValue string
-}
-
-var rfc3339Formats = []TimeFormatTest{
-	{Date(2008, 9, 17, 20, 4, 26, 0, UTC), "2008-09-17T20:04:26Z"},
-	{Date(1994, 9, 17, 20, 4, 26, 0, FixedZone("EST", -18000)), "1994-09-17T20:04:26-05:00"},
-	{Date(2000, 12, 26, 1, 15, 6, 0, FixedZone("OTO", 15600)), "2000-12-26T01:15:06+04:20"},
-}
-
-func TestRFC3339Conversion(t *testing.T) {
-	for _, f := range rfc3339Formats {
-		if f.time.Format(RFC3339) != f.formattedValue {
-			t.Error("RFC3339:")
-			t.Errorf("  want=%+v", f.formattedValue)
-			t.Errorf("  have=%+v", f.time.Format(RFC3339))
-		}
-	}
-}
-
-type FormatTest struct {
-	name   string
-	format string
-	result string
-}
-
-var formatTests = []FormatTest{
-	{"ANSIC", ANSIC, "Wed Feb  4 21:00:57 2009"},
-	{"UnixDate", UnixDate, "Wed Feb  4 21:00:57 PST 2009"},
-	{"RubyDate", RubyDate, "Wed Feb 04 21:00:57 -0800 2009"},
-	{"RFC822", RFC822, "04 Feb 09 21:00 PST"},
-	{"RFC850", RFC850, "Wednesday, 04-Feb-09 21:00:57 PST"},
-	{"RFC1123", RFC1123, "Wed, 04 Feb 2009 21:00:57 PST"},
-	{"RFC1123Z", RFC1123Z, "Wed, 04 Feb 2009 21:00:57 -0800"},
-	{"RFC3339", RFC3339, "2009-02-04T21:00:57-08:00"},
-	{"RFC3339Nano", RFC3339Nano, "2009-02-04T21:00:57.0123456-08:00"},
-	{"Kitchen", Kitchen, "9:00PM"},
-	{"am/pm", "3pm", "9pm"},
-	{"AM/PM", "3PM", "9PM"},
-	{"two-digit year", "06 01 02", "09 02 04"},
-	// Three-letter months and days must not be followed by lower-case letter.
-	{"Janet", "Hi Janet, the Month is January", "Hi Janet, the Month is February"},
-	// Time stamps, Fractional seconds.
-	{"Stamp", Stamp, "Feb  4 21:00:57"},
-	{"StampMilli", StampMilli, "Feb  4 21:00:57.012"},
-	{"StampMicro", StampMicro, "Feb  4 21:00:57.012345"},
-	{"StampNano", StampNano, "Feb  4 21:00:57.012345600"},
-}
-
-func TestFormat(t *testing.T) {
-	// The numeric time represents Thu Feb  4 21:00:57.012345600 PST 2010
-	time := Unix(0, 1233810057012345600)
-	for _, test := range formatTests {
-		result := time.Format(test.format)
-		if result != test.result {
-			t.Errorf("%s expected %q got %q", test.name, test.result, result)
-		}
-	}
-}
-
-func TestFormatShortYear(t *testing.T) {
-	years := []int{
-		-100001, -100000, -99999,
-		-10001, -10000, -9999,
-		-1001, -1000, -999,
-		-101, -100, -99,
-		-11, -10, -9,
-		-1, 0, 1,
-		9, 10, 11,
-		99, 100, 101,
-		999, 1000, 1001,
-		9999, 10000, 10001,
-		99999, 100000, 100001,
-	}
-
-	for _, y := range years {
-		time := Date(y, January, 1, 0, 0, 0, 0, UTC)
-		result := time.Format("2006.01.02")
-		var want string
-		if y < 0 {
-			// The 4 in %04d counts the - sign, so print -y instead
-			// and introduce our own - sign.
-			want = fmt.Sprintf("-%04d.%02d.%02d", -y, 1, 1)
-		} else {
-			want = fmt.Sprintf("%04d.%02d.%02d", y, 1, 1)
-		}
-		if result != want {
-			t.Errorf("(jan 1 %d).Format(\"2006.01.02\") = %q, want %q", y, result, want)
-		}
-	}
-}
-
-type ParseTest struct {
-	name       string
-	format     string
-	value      string
-	hasTZ      bool // contains a time zone
-	hasWD      bool // contains a weekday
-	yearSign   int  // sign of year, -1 indicates the year is not present in the format
-	fracDigits int  // number of digits of fractional second
-}
-
-var parseTests = []ParseTest{
-	{"ANSIC", ANSIC, "Thu Feb  4 21:00:57 2010", false, true, 1, 0},
-	{"UnixDate", UnixDate, "Thu Feb  4 21:00:57 PST 2010", true, true, 1, 0},
-	{"RubyDate", RubyDate, "Thu Feb 04 21:00:57 -0800 2010", true, true, 1, 0},
-	{"RFC850", RFC850, "Thursday, 04-Feb-10 21:00:57 PST", true, true, 1, 0},
-	{"RFC1123", RFC1123, "Thu, 04 Feb 2010 21:00:57 PST", true, true, 1, 0},
-	{"RFC1123", RFC1123, "Thu, 04 Feb 2010 22:00:57 PDT", true, true, 1, 0},
-	{"RFC1123Z", RFC1123Z, "Thu, 04 Feb 2010 21:00:57 -0800", true, true, 1, 0},
-	{"RFC3339", RFC3339, "2010-02-04T21:00:57-08:00", true, false, 1, 0},
-	{"custom: \"2006-01-02 15:04:05-07\"", "2006-01-02 15:04:05-07", "2010-02-04 21:00:57-08", true, false, 1, 0},
-	// Optional fractional seconds.
-	{"ANSIC", ANSIC, "Thu Feb  4 21:00:57.0 2010", false, true, 1, 1},
-	{"UnixDate", UnixDate, "Thu Feb  4 21:00:57.01 PST 2010", true, true, 1, 2},
-	{"RubyDate", RubyDate, "Thu Feb 04 21:00:57.012 -0800 2010", true, true, 1, 3},
-	{"RFC850", RFC850, "Thursday, 04-Feb-10 21:00:57.0123 PST", true, true, 1, 4},
-	{"RFC1123", RFC1123, "Thu, 04 Feb 2010 21:00:57.01234 PST", true, true, 1, 5},
-	{"RFC1123Z", RFC1123Z, "Thu, 04 Feb 2010 21:00:57.01234 -0800", true, true, 1, 5},
-	{"RFC3339", RFC3339, "2010-02-04T21:00:57.012345678-08:00", true, false, 1, 9},
-	{"custom: \"2006-01-02 15:04:05\"", "2006-01-02 15:04:05", "2010-02-04 21:00:57.0", false, false, 1, 0},
-	// Amount of white space should not matter.
-	{"ANSIC", ANSIC, "Thu Feb 4 21:00:57 2010", false, true, 1, 0},
-	{"ANSIC", ANSIC, "Thu      Feb     4     21:00:57     2010", false, true, 1, 0},
-	// Case should not matter
-	{"ANSIC", ANSIC, "THU FEB 4 21:00:57 2010", false, true, 1, 0},
-	{"ANSIC", ANSIC, "thu feb 4 21:00:57 2010", false, true, 1, 0},
-	// Fractional seconds.
-	{"millisecond", "Mon Jan _2 15:04:05.000 2006", "Thu Feb  4 21:00:57.012 2010", false, true, 1, 3},
-	{"microsecond", "Mon Jan _2 15:04:05.000000 2006", "Thu Feb  4 21:00:57.012345 2010", false, true, 1, 6},
-	{"nanosecond", "Mon Jan _2 15:04:05.000000000 2006", "Thu Feb  4 21:00:57.012345678 2010", false, true, 1, 9},
-	// Leading zeros in other places should not be taken as fractional seconds.
-	{"zero1", "2006.01.02.15.04.05.0", "2010.02.04.21.00.57.0", false, false, 1, 1},
-	{"zero2", "2006.01.02.15.04.05.00", "2010.02.04.21.00.57.01", false, false, 1, 2},
-	// Month and day names only match when not followed by a lower-case letter.
-	{"Janet", "Hi Janet, the Month is January: Jan _2 15:04:05 2006", "Hi Janet, the Month is February: Feb  4 21:00:57 2010", false, true, 1, 0},
-
-	// GMT with offset.
-	{"GMT-8", UnixDate, "Fri Feb  5 05:00:57 GMT-8 2010", true, true, 1, 0},
-
-	// Accept any number of fractional second digits (including none) for .999...
-	// In Go 1, .999... was completely ignored in the format, meaning the first two
-	// cases would succeed, but the next four would not. Go 1.1 accepts all six.
-	{"", "2006-01-02 15:04:05.9999 -0700 MST", "2010-02-04 21:00:57 -0800 PST", true, false, 1, 0},
-	{"", "2006-01-02 15:04:05.999999999 -0700 MST", "2010-02-04 21:00:57 -0800 PST", true, false, 1, 0},
-	{"", "2006-01-02 15:04:05.9999 -0700 MST", "2010-02-04 21:00:57.0123 -0800 PST", true, false, 1, 4},
-	{"", "2006-01-02 15:04:05.999999999 -0700 MST", "2010-02-04 21:00:57.0123 -0800 PST", true, false, 1, 4},
-	{"", "2006-01-02 15:04:05.9999 -0700 MST", "2010-02-04 21:00:57.012345678 -0800 PST", true, false, 1, 9},
-	{"", "2006-01-02 15:04:05.999999999 -0700 MST", "2010-02-04 21:00:57.012345678 -0800 PST", true, false, 1, 9},
-
-	// issue 4502.
-	{"", StampNano, "Feb  4 21:00:57.012345678", false, false, -1, 9},
-	{"", "Jan _2 15:04:05.999", "Feb  4 21:00:57.012300000", false, false, -1, 4},
-	{"", "Jan _2 15:04:05.999", "Feb  4 21:00:57.012345678", false, false, -1, 9},
-	{"", "Jan _2 15:04:05.999999999", "Feb  4 21:00:57.0123", false, false, -1, 4},
-	{"", "Jan _2 15:04:05.999999999", "Feb  4 21:00:57.012345678", false, false, -1, 9},
-}
-
-func TestParse(t *testing.T) {
-	for _, test := range parseTests {
-		time, err := Parse(test.format, test.value)
-		if err != nil {
-			t.Errorf("%s error: %v", test.name, err)
-		} else {
-			checkTime(time, &test, t)
-		}
-	}
-}
-
-func TestParseInLocation(t *testing.T) {
-	// Check that Parse (and ParseInLocation) understand that
-	// Feb 01 AST (Arabia Standard Time) and Feb 01 AST (Atlantic Standard Time)
-	// are in different time zones even though both are called AST
-
-	baghdad, err := LoadLocation("Asia/Baghdad")
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	t1, err := ParseInLocation("Jan 02 2006 MST", "Feb 01 2013 AST", baghdad)
-	if err != nil {
-		t.Fatal(err)
-	}
-	t2 := Date(2013, February, 1, 00, 00, 00, 0, baghdad)
-	if t1 != t2 {
-		t.Fatalf("ParseInLocation(Feb 01 2013 AST, Baghdad) = %v, want %v", t1, t2)
-	}
-	_, offset := t1.Zone()
-	if offset != 3*60*60 {
-		t.Fatalf("ParseInLocation(Feb 01 2013 AST, Baghdad).Zone = _, %d, want _, %d", offset, 3*60*60)
-	}
-
-	blancSablon, err := LoadLocation("America/Blanc-Sablon")
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	t1, err = ParseInLocation("Jan 02 2006 MST", "Feb 01 2013 AST", blancSablon)
-	if err != nil {
-		t.Fatal(err)
-	}
-	t2 = Date(2013, February, 1, 00, 00, 00, 0, blancSablon)
-	if t1 != t2 {
-		t.Fatalf("ParseInLocation(Feb 01 2013 AST, Blanc-Sablon) = %v, want %v", t1, t2)
-	}
-	_, offset = t1.Zone()
-	if offset != -4*60*60 {
-		t.Fatalf("ParseInLocation(Feb 01 2013 AST, Blanc-Sablon).Zone = _, %d, want _, %d", offset, -4*60*60)
-	}
-}
-
-func TestLoadLocationZipFile(t *testing.T) {
-	ForceZipFileForTesting(true)
-	defer ForceZipFileForTesting(false)
-
-	_, err := LoadLocation("Australia/Sydney")
-	if err != nil {
-		t.Fatal(err)
-	}
-}
-
-var rubyTests = []ParseTest{
-	{"RubyDate", RubyDate, "Thu Feb 04 21:00:57 -0800 2010", true, true, 1, 0},
-	// Ignore the time zone in the test. If it parses, it'll be OK.
-	{"RubyDate", RubyDate, "Thu Feb 04 21:00:57 -0000 2010", false, true, 1, 0},
-	{"RubyDate", RubyDate, "Thu Feb 04 21:00:57 +0000 2010", false, true, 1, 0},
-	{"RubyDate", RubyDate, "Thu Feb 04 21:00:57 +1130 2010", false, true, 1, 0},
-}
-
-// Problematic time zone format needs special tests.
-func TestRubyParse(t *testing.T) {
-	for _, test := range rubyTests {
-		time, err := Parse(test.format, test.value)
-		if err != nil {
-			t.Errorf("%s error: %v", test.name, err)
-		} else {
-			checkTime(time, &test, t)
-		}
-	}
-}
-
-func checkTime(time Time, test *ParseTest, t *testing.T) {
-	// The time should be Thu Feb  4 21:00:57 PST 2010
-	if test.yearSign >= 0 && test.yearSign*time.Year() != 2010 {
-		t.Errorf("%s: bad year: %d not %d", test.name, time.Year(), 2010)
-	}
-	if time.Month() != February {
-		t.Errorf("%s: bad month: %s not %s", test.name, time.Month(), February)
-	}
-	if time.Day() != 4 {
-		t.Errorf("%s: bad day: %d not %d", test.name, time.Day(), 4)
-	}
-	if time.Hour() != 21 {
-		t.Errorf("%s: bad hour: %d not %d", test.name, time.Hour(), 21)
-	}
-	if time.Minute() != 0 {
-		t.Errorf("%s: bad minute: %d not %d", test.name, time.Minute(), 0)
-	}
-	if time.Second() != 57 {
-		t.Errorf("%s: bad second: %d not %d", test.name, time.Second(), 57)
-	}
-	// Nanoseconds must be checked against the precision of the input.
-	nanosec, err := strconv.ParseUint("012345678"[:test.fracDigits]+"000000000"[:9-test.fracDigits], 10, 0)
-	if err != nil {
-		panic(err)
-	}
-	if time.Nanosecond() != int(nanosec) {
-		t.Errorf("%s: bad nanosecond: %d not %d", test.name, time.Nanosecond(), nanosec)
-	}
-	name, offset := time.Zone()
-	if test.hasTZ && offset != -28800 {
-		t.Errorf("%s: bad tz offset: %s %d not %d", test.name, name, offset, -28800)
-	}
-	if test.hasWD && time.Weekday() != Thursday {
-		t.Errorf("%s: bad weekday: %s not %s", test.name, time.Weekday(), Thursday)
-	}
-}
-
-func TestFormatAndParse(t *testing.T) {
-	const fmt = "Mon MST " + RFC3339 // all fields
-	f := func(sec int64) bool {
-		t1 := Unix(sec, 0)
-		if t1.Year() < 1000 || t1.Year() > 9999 {
-			// not required to work
-			return true
-		}
-		t2, err := Parse(fmt, t1.Format(fmt))
-		if err != nil {
-			t.Errorf("error: %s", err)
-			return false
-		}
-		if t1.Unix() != t2.Unix() || t1.Nanosecond() != t2.Nanosecond() {
-			t.Errorf("FormatAndParse %d: %q(%d) %q(%d)", sec, t1, t1.Unix(), t2, t2.Unix())
-			return false
-		}
-		return true
-	}
-	f32 := func(sec int32) bool { return f(int64(sec)) }
-	cfg := &quick.Config{MaxCount: 10000}
-
-	// Try a reasonable date first, then the huge ones.
-	if err := quick.Check(f32, cfg); err != nil {
-		t.Fatal(err)
-	}
-	if err := quick.Check(f, cfg); err != nil {
-		t.Fatal(err)
-	}
-}
-
-type ParseTimeZoneTest struct {
-	value  string
-	length int
-	ok     bool
-}
-
-var parseTimeZoneTests = []ParseTimeZoneTest{
-	{"gmt hi there", 0, false},
-	{"GMT hi there", 3, true},
-	{"GMT+12 hi there", 6, true},
-	{"GMT+00 hi there", 3, true}, // 0 or 00 is not a legal offset.
-	{"GMT-5 hi there", 5, true},
-	{"GMT-51 hi there", 3, true},
-	{"ChST hi there", 4, true},
-	{"MeST hi there", 4, true},
-	{"MSDx", 3, true},
-	{"MSDY", 0, false}, // four letters must end in T.
-	{"ESAST hi", 5, true},
-	{"ESASTT hi", 0, false}, // run of upper-case letters too long.
-	{"ESATY hi", 0, false},  // five letters must end in T.
-}
-
-func TestParseTimeZone(t *testing.T) {
-	for _, test := range parseTimeZoneTests {
-		length, ok := ParseTimeZone(test.value)
-		if ok != test.ok {
-			t.Errorf("expected %t for %q got %t", test.ok, test.value, ok)
-		} else if length != test.length {
-			t.Errorf("expected %d for %q got %d", test.length, test.value, length)
-		}
-	}
-}
-
-type ParseErrorTest struct {
-	format string
-	value  string
-	expect string // must appear within the error
-}
-
-var parseErrorTests = []ParseErrorTest{
-	{ANSIC, "Feb  4 21:00:60 2010", "cannot parse"}, // cannot parse Feb as Mon
-	{ANSIC, "Thu Feb  4 21:00:57 @2010", "cannot parse"},
-	{ANSIC, "Thu Feb  4 21:00:60 2010", "second out of range"},
-	{ANSIC, "Thu Feb  4 21:61:57 2010", "minute out of range"},
-	{ANSIC, "Thu Feb  4 24:00:60 2010", "hour out of range"},
-	{"Mon Jan _2 15:04:05.000 2006", "Thu Feb  4 23:00:59x01 2010", "cannot parse"},
-	{"Mon Jan _2 15:04:05.000 2006", "Thu Feb  4 23:00:59.xxx 2010", "cannot parse"},
-	{"Mon Jan _2 15:04:05.000 2006", "Thu Feb  4 23:00:59.-123 2010", "fractional second out of range"},
-	// issue 4502. StampNano requires exactly 9 digits of precision.
-	{StampNano, "Dec  7 11:22:01.000000", `cannot parse ".000000" as ".000000000"`},
-	{StampNano, "Dec  7 11:22:01.0000000000", "extra text: 0"},
-	// issue 4493. Helpful errors.
-	{RFC3339, "2006-01-02T15:04:05Z07:00", `parsing time "2006-01-02T15:04:05Z07:00": extra text: 07:00`},
-	{RFC3339, "2006-01-02T15:04_abc", `parsing time "2006-01-02T15:04_abc" as "2006-01-02T15:04:05Z07:00": cannot parse "_abc" as ":"`},
-	{RFC3339, "2006-01-02T15:04:05_abc", `parsing time "2006-01-02T15:04:05_abc" as "2006-01-02T15:04:05Z07:00": cannot parse "_abc" as "Z07:00"`},
-	{RFC3339, "2006-01-02T15:04:05Z_abc", `parsing time "2006-01-02T15:04:05Z_abc": extra text: _abc`},
-}
-
-func TestParseErrors(t *testing.T) {
-	for _, test := range parseErrorTests {
-		_, 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 {
-			t.Errorf("expected error with %q for %q %q; got %s", test.expect, test.format, test.value, err)
-		}
-	}
-}
-
-func TestNoonIs12PM(t *testing.T) {
-	noon := Date(0, January, 1, 12, 0, 0, 0, UTC)
-	const expect = "12:00PM"
-	got := noon.Format("3:04PM")
-	if got != expect {
-		t.Errorf("got %q; expect %q", got, expect)
-	}
-	got = noon.Format("03:04PM")
-	if got != expect {
-		t.Errorf("got %q; expect %q", got, expect)
-	}
-}
-
-func TestMidnightIs12AM(t *testing.T) {
-	midnight := Date(0, January, 1, 0, 0, 0, 0, UTC)
-	expect := "12:00AM"
-	got := midnight.Format("3:04PM")
-	if got != expect {
-		t.Errorf("got %q; expect %q", got, expect)
-	}
-	got = midnight.Format("03:04PM")
-	if got != expect {
-		t.Errorf("got %q; expect %q", got, expect)
-	}
-}
-
-func Test12PMIsNoon(t *testing.T) {
-	noon, err := Parse("3:04PM", "12:00PM")
-	if err != nil {
-		t.Fatal("error parsing date:", err)
-	}
-	if noon.Hour() != 12 {
-		t.Errorf("got %d; expect 12", noon.Hour())
-	}
-	noon, err = Parse("03:04PM", "12:00PM")
-	if err != nil {
-		t.Fatal("error parsing date:", err)
-	}
-	if noon.Hour() != 12 {
-		t.Errorf("got %d; expect 12", noon.Hour())
-	}
-}
-
-func Test12AMIsMidnight(t *testing.T) {
-	midnight, err := Parse("3:04PM", "12:00AM")
-	if err != nil {
-		t.Fatal("error parsing date:", err)
-	}
-	if midnight.Hour() != 0 {
-		t.Errorf("got %d; expect 0", midnight.Hour())
-	}
-	midnight, err = Parse("03:04PM", "12:00AM")
-	if err != nil {
-		t.Fatal("error parsing date:", err)
-	}
-	if midnight.Hour() != 0 {
-		t.Errorf("got %d; expect 0", midnight.Hour())
-	}
-}
-
-// Check that a time without a Zone still produces a (numeric) time zone
-// when formatted with MST as a requested zone.
-func TestMissingZone(t *testing.T) {
-	time, err := Parse(RubyDate, "Thu Feb 02 16:10:03 -0500 2006")
-	if err != nil {
-		t.Fatal("error parsing date:", err)
-	}
-	expect := "Thu Feb  2 16:10:03 -0500 2006" // -0500 not EST
-	str := time.Format(UnixDate)               // uses MST as its time zone
-	if str != expect {
-		t.Errorf("got %s; expect %s", str, expect)
-	}
-}
-
-func TestMinutesInTimeZone(t *testing.T) {
-	time, err := Parse(RubyDate, "Mon Jan 02 15:04:05 +0123 2006")
-	if err != nil {
-		t.Fatal("error parsing date:", err)
-	}
-	expected := (1*60 + 23) * 60
-	_, offset := time.Zone()
-	if offset != expected {
-		t.Errorf("ZoneOffset = %d, want %d", offset, expected)
-	}
-}
-
-type SecondsTimeZoneOffsetTest struct {
-	format         string
-	value          string
-	expectedoffset int
-}
-
-var secondsTimeZoneOffsetTests = []SecondsTimeZoneOffsetTest{
-	{"2006-01-02T15:04:05-070000", "1871-01-01T05:33:02-003408", -(34*60 + 8)},
-	{"2006-01-02T15:04:05-07:00:00", "1871-01-01T05:33:02-00:34:08", -(34*60 + 8)},
-	{"2006-01-02T15:04:05-070000", "1871-01-01T05:33:02+003408", 34*60 + 8},
-	{"2006-01-02T15:04:05-07:00:00", "1871-01-01T05:33:02+00:34:08", 34*60 + 8},
-	{"2006-01-02T15:04:05Z070000", "1871-01-01T05:33:02-003408", -(34*60 + 8)},
-	{"2006-01-02T15:04:05Z07:00:00", "1871-01-01T05:33:02+00:34:08", 34*60 + 8},
-}
-
-func TestParseSecondsInTimeZone(t *testing.T) {
-	// should accept timezone offsets with seconds like: Zone America/New_York   -4:56:02 -      LMT     1883 Nov 18 12:03:58
-	for _, test := range secondsTimeZoneOffsetTests {
-		time, err := Parse(test.format, test.value)
-		if err != nil {
-			t.Fatal("error parsing date:", err)
-		}
-		_, offset := time.Zone()
-		if offset != test.expectedoffset {
-			t.Errorf("ZoneOffset = %d, want %d", offset, test.expectedoffset)
-		}
-	}
-}
-
-func TestFormatSecondsInTimeZone(t *testing.T) {
-	d := Date(1871, 9, 17, 20, 4, 26, 0, FixedZone("LMT", -(34*60+8)))
-	timestr := d.Format("2006-01-02T15:04:05Z070000")
-	expected := "1871-09-17T20:04:26-003408"
-	if timestr != expected {
-		t.Errorf("Got %s, want %s", timestr, expected)
-	}
-}
diff --git a/src/pkg/time/genzabbrs.go b/src/pkg/time/genzabbrs.go
deleted file mode 100644
index 7c637cb..0000000
--- a/src/pkg/time/genzabbrs.go
+++ /dev/null
@@ -1,145 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build ignore
-
-//
-// usage:
-//
-// go run genzabbrs.go | gofmt > $GOROOT/src/pkg/time/zoneinfo_abbrs_windows.go
-//
-
-package main
-
-import (
-	"encoding/xml"
-	"io/ioutil"
-	"log"
-	"net/http"
-	"os"
-	"sort"
-	"text/template"
-	"time"
-)
-
-// getAbbrs finds timezone abbreviations (standard and daylight saving time)
-// for location l.
-func getAbbrs(l *time.Location) (st, dt string) {
-	t := time.Date(time.Now().Year(), 0, 0, 0, 0, 0, 0, l)
-	abbr1, off1 := t.Zone()
-	for i := 0; i < 12; i++ {
-		t = t.AddDate(0, 1, 0)
-		abbr2, off2 := t.Zone()
-		if abbr1 != abbr2 {
-			if off2-off1 < 0 { // southern hemisphere
-				abbr1, abbr2 = abbr2, abbr1
-			}
-			return abbr1, abbr2
-		}
-	}
-	return abbr1, abbr1
-}
-
-type zone struct {
-	WinName  string
-	UnixName string
-	StTime   string
-	DSTime   string
-}
-
-type zones []*zone
-
-func (zs zones) Len() int           { return len(zs) }
-func (zs zones) Swap(i, j int)      { zs[i], zs[j] = zs[j], zs[i] }
-func (zs zones) Less(i, j int) bool { return zs[i].UnixName < zs[j].UnixName }
-
-const wzURL = "http://unicode.org/cldr/data/common/supplemental/windowsZones.xml"
-
-type MapZone struct {
-	Other     string `xml:"other,attr"`
-	Territory string `xml:"territory,attr"`
-	Type      string `xml:"type,attr"`
-}
-
-type SupplementalData struct {
-	Zones []MapZone `xml:"windowsZones>mapTimezones>mapZone"`
-}
-
-func readWindowsZones() (zones, error) {
-	r, err := http.Get(wzURL)
-	if err != nil {
-		return nil, err
-	}
-	defer r.Body.Close()
-
-	data, err := ioutil.ReadAll(r.Body)
-	if err != nil {
-		return nil, err
-	}
-
-	var sd SupplementalData
-	err = xml.Unmarshal(data, &sd)
-	if err != nil {
-		return nil, err
-	}
-	zs := make(zones, 0)
-	for _, z := range sd.Zones {
-		if z.Territory != "001" {
-			// to avoid dups. I don't know why.
-			continue
-		}
-		l, err := time.LoadLocation(z.Type)
-		if err != nil {
-			return nil, err
-		}
-		st, dt := getAbbrs(l)
-		zs = append(zs, &zone{
-			WinName:  z.Other,
-			UnixName: z.Type,
-			StTime:   st,
-			DSTime:   dt,
-		})
-	}
-	return zs, nil
-}
-
-func main() {
-	zs, err := readWindowsZones()
-	if err != nil {
-		log.Fatal(err)
-	}
-	sort.Sort(zs)
-	var v = struct {
-		URL string
-		Zs  zones
-	}{
-		wzURL,
-		zs,
-	}
-	err = template.Must(template.New("prog").Parse(prog)).Execute(os.Stdout, v)
-	if err != nil {
-		log.Fatal(err)
-	}
-}
-
-const prog = `
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// generated by genzabbrs.go from
-// {{.URL}}
-
-package time
-
-type abbr struct {
-	std string
-	dst string
-}
-
-var abbrs = map[string]abbr{
-{{range .Zs}}	"{{.WinName}}": {"{{.StTime}}", "{{.DSTime}}"}, // {{.UnixName}}
-{{end}}}
-
-`
diff --git a/src/pkg/time/internal_test.go b/src/pkg/time/internal_test.go
deleted file mode 100644
index 2243d36..0000000
--- a/src/pkg/time/internal_test.go
+++ /dev/null
@@ -1,92 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package time
-
-import (
-	"errors"
-	"runtime"
-)
-
-func init() {
-	// force US/Pacific for time zone tests
-	ForceUSPacificForTesting()
-}
-
-var Interrupt = interrupt
-var DaysIn = daysIn
-
-func empty(now int64, arg interface{}) {}
-
-// Test that a runtimeTimer with a duration so large it overflows
-// does not cause other timers to hang.
-//
-// This test has to be in internal_test.go since it fiddles with
-// unexported data structures.
-func CheckRuntimeTimerOverflow() error {
-	// We manually create a runtimeTimer to bypass the overflow
-	// detection logic in NewTimer: we're testing the underlying
-	// runtime.addtimer function.
-	r := &runtimeTimer{
-		when: runtimeNano() + (1<<63 - 1),
-		f:    empty,
-		arg:  nil,
-	}
-	startTimer(r)
-
-	timeout := 100 * Millisecond
-	switch runtime.GOOS {
-	// Allow more time for gobuilder to succeed.
-	case "windows":
-		timeout = Second
-	case "plan9":
-		// TODO(0intro): We don't know why it is needed.
-		timeout = 3 * Second
-	}
-
-	// Start a goroutine that should send on t.C before the timeout.
-	t := NewTimer(1)
-
-	defer func() {
-		// Subsequent tests won't work correctly if we don't stop the
-		// overflow timer and kick the timer proc back into service.
-		//
-		// The timer proc is now sleeping and can only be awoken by
-		// adding a timer to the *beginning* of the heap. We can't
-		// wake it up by calling NewTimer since other tests may have
-		// left timers running that should have expired before ours.
-		// Instead we zero the overflow timer duration and start it
-		// once more.
-		stopTimer(r)
-		t.Stop()
-		r.when = 0
-		startTimer(r)
-	}()
-
-	// Try to receive from t.C before the timeout. It will succeed
-	// iff the previous sleep was able to finish. We're forced to
-	// spin and yield after trying to receive since we can't start
-	// any more timers (they might hang due to the same bug we're
-	// now testing).
-	stop := Now().Add(timeout)
-	for {
-		select {
-		case <-t.C:
-			return nil // It worked!
-		default:
-			if Now().After(stop) {
-				return errors.New("runtime timer stuck: overflow in addtimer")
-			}
-			// Issue 6874. This test previously called runtime.Gosched to try to yield
-			// to the goroutine servicing t, however the scheduler has a bias towards the
-			// previously running goroutine in an idle system. Combined with high load due
-			// to all CPUs busy running tests t's goroutine could be delayed beyond the
-			// timeout window.
-			//
-			// Calling runtime.GC() reduces the worst case lantency for scheduling t by 20x
-			// under the current Go 1.3 scheduler.
-			runtime.GC()
-		}
-	}
-}
diff --git a/src/pkg/time/sleep.go b/src/pkg/time/sleep.go
deleted file mode 100644
index 6a03f41..0000000
--- a/src/pkg/time/sleep.go
+++ /dev/null
@@ -1,122 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package time
-
-// Sleep pauses the current goroutine for at least the duration d.
-// A negative or zero duration causes Sleep to return immediately.
-func Sleep(d Duration)
-
-// runtimeNano returns the current value of the runtime clock in nanoseconds.
-func runtimeNano() int64
-
-// Interface to timers implemented in package runtime.
-// Must be in sync with ../runtime/runtime.h:/^struct.Timer$
-type runtimeTimer struct {
-	i      int32
-	when   int64
-	period int64
-	f      func(int64, interface{}) // NOTE: must not be closure
-	arg    interface{}
-}
-
-// when is a helper function for setting the 'when' field of a runtimeTimer.
-// It returns what the time will be, in nanoseconds, Duration d in the future.
-// If d is negative, it is ignored.  If the returned value would be less than
-// zero because of an overflow, MaxInt64 is returned.
-func when(d Duration) int64 {
-	if d <= 0 {
-		return runtimeNano()
-	}
-	t := runtimeNano() + int64(d)
-	if t < 0 {
-		t = 1<<63 - 1 // math.MaxInt64
-	}
-	return t
-}
-
-func startTimer(*runtimeTimer)
-func stopTimer(*runtimeTimer) bool
-
-// The Timer type represents a single event.
-// When the Timer expires, the current time will be sent on C,
-// unless the Timer was created by AfterFunc.
-type Timer struct {
-	C <-chan Time
-	r runtimeTimer
-}
-
-// Stop prevents the Timer from firing.
-// It returns true if the call stops the timer, false if the timer has already
-// expired or been stopped.
-// Stop does not close the channel, to prevent a read from the channel succeeding
-// incorrectly.
-func (t *Timer) Stop() bool {
-	return stopTimer(&t.r)
-}
-
-// NewTimer creates a new Timer that will send
-// the current time on its channel after at least duration d.
-func NewTimer(d Duration) *Timer {
-	c := make(chan Time, 1)
-	t := &Timer{
-		C: c,
-		r: runtimeTimer{
-			when: when(d),
-			f:    sendTime,
-			arg:  c,
-		},
-	}
-	startTimer(&t.r)
-	return t
-}
-
-// Reset changes the timer to expire after duration d.
-// It returns true if the timer had been active, false if the timer had
-// expired or been stopped.
-func (t *Timer) Reset(d Duration) bool {
-	w := when(d)
-	active := stopTimer(&t.r)
-	t.r.when = w
-	startTimer(&t.r)
-	return active
-}
-
-func sendTime(now int64, c interface{}) {
-	// Non-blocking send of time on c.
-	// Used in NewTimer, it cannot block anyway (buffer).
-	// Used in NewTicker, dropping sends on the floor is
-	// the desired behavior when the reader gets behind,
-	// because the sends are periodic.
-	select {
-	case c.(chan Time) <- Now():
-	default:
-	}
-}
-
-// After waits for the duration to elapse and then sends the current time
-// on the returned channel.
-// It is equivalent to NewTimer(d).C.
-func After(d Duration) <-chan Time {
-	return NewTimer(d).C
-}
-
-// AfterFunc waits for the duration to elapse and then calls f
-// in its own goroutine. It returns a Timer that can
-// be used to cancel the call using its Stop method.
-func AfterFunc(d Duration, f func()) *Timer {
-	t := &Timer{
-		r: runtimeTimer{
-			when: when(d),
-			f:    goFunc,
-			arg:  f,
-		},
-	}
-	startTimer(&t.r)
-	return t
-}
-
-func goFunc(now int64, arg interface{}) {
-	go arg.(func())()
-}
diff --git a/src/pkg/time/sleep_test.go b/src/pkg/time/sleep_test.go
deleted file mode 100644
index 03f8e73..0000000
--- a/src/pkg/time/sleep_test.go
+++ /dev/null
@@ -1,393 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package time_test
-
-import (
-	"errors"
-	"fmt"
-	"runtime"
-	"sort"
-	"sync"
-	"sync/atomic"
-	"testing"
-	. "time"
-)
-
-func TestSleep(t *testing.T) {
-	const delay = 100 * Millisecond
-	go func() {
-		Sleep(delay / 2)
-		Interrupt()
-	}()
-	start := Now()
-	Sleep(delay)
-	duration := Now().Sub(start)
-	if duration < delay {
-		t.Fatalf("Sleep(%s) slept for only %s", delay, duration)
-	}
-}
-
-// Test the basic function calling behavior. Correct queueing
-// behavior is tested elsewhere, since After and AfterFunc share
-// the same code.
-func TestAfterFunc(t *testing.T) {
-	i := 10
-	c := make(chan bool)
-	var f func()
-	f = func() {
-		i--
-		if i >= 0 {
-			AfterFunc(0, f)
-			Sleep(1 * Second)
-		} else {
-			c <- true
-		}
-	}
-
-	AfterFunc(0, f)
-	<-c
-}
-
-func TestAfterStress(t *testing.T) {
-	stop := uint32(0)
-	go func() {
-		for atomic.LoadUint32(&stop) == 0 {
-			runtime.GC()
-			// Yield so that the OS can wake up the timer thread,
-			// so that it can generate channel sends for the main goroutine,
-			// which will eventually set stop = 1 for us.
-			Sleep(Nanosecond)
-		}
-	}()
-	ticker := NewTicker(1)
-	for i := 0; i < 100; i++ {
-		<-ticker.C
-	}
-	ticker.Stop()
-	atomic.StoreUint32(&stop, 1)
-}
-
-func benchmark(b *testing.B, bench func(n int)) {
-	garbage := make([]*Timer, 1<<17)
-	for i := 0; i < len(garbage); i++ {
-		garbage[i] = AfterFunc(Hour, nil)
-	}
-	b.ResetTimer()
-
-	b.RunParallel(func(pb *testing.PB) {
-		for pb.Next() {
-			bench(1000)
-		}
-	})
-
-	b.StopTimer()
-	for i := 0; i < len(garbage); i++ {
-		garbage[i].Stop()
-	}
-}
-
-func BenchmarkAfterFunc(b *testing.B) {
-	benchmark(b, func(n int) {
-		c := make(chan bool)
-		var f func()
-		f = func() {
-			n--
-			if n >= 0 {
-				AfterFunc(0, f)
-			} else {
-				c <- true
-			}
-		}
-
-		AfterFunc(0, f)
-		<-c
-	})
-}
-
-func BenchmarkAfter(b *testing.B) {
-	benchmark(b, func(n int) {
-		for i := 0; i < n; i++ {
-			<-After(1)
-		}
-	})
-}
-
-func BenchmarkStop(b *testing.B) {
-	benchmark(b, func(n int) {
-		for i := 0; i < n; i++ {
-			NewTimer(1 * Second).Stop()
-		}
-	})
-}
-
-func BenchmarkSimultaneousAfterFunc(b *testing.B) {
-	benchmark(b, func(n int) {
-		var wg sync.WaitGroup
-		wg.Add(n)
-		for i := 0; i < n; i++ {
-			AfterFunc(0, wg.Done)
-		}
-		wg.Wait()
-	})
-}
-
-func BenchmarkStartStop(b *testing.B) {
-	benchmark(b, func(n int) {
-		timers := make([]*Timer, n)
-		for i := 0; i < n; i++ {
-			timers[i] = AfterFunc(Hour, nil)
-		}
-
-		for i := 0; i < n; i++ {
-			timers[i].Stop()
-		}
-	})
-}
-
-func TestAfter(t *testing.T) {
-	const delay = 100 * Millisecond
-	start := Now()
-	end := <-After(delay)
-	if duration := Now().Sub(start); duration < delay {
-		t.Fatalf("After(%s) slept for only %d ns", delay, duration)
-	}
-	if min := start.Add(delay); end.Before(min) {
-		t.Fatalf("After(%s) expect >= %s, got %s", delay, min, end)
-	}
-}
-
-func TestAfterTick(t *testing.T) {
-	const Count = 10
-	Delta := 100 * Millisecond
-	if testing.Short() {
-		Delta = 10 * Millisecond
-	}
-	t0 := Now()
-	for i := 0; i < Count; i++ {
-		<-After(Delta)
-	}
-	t1 := Now()
-	d := t1.Sub(t0)
-	target := Delta * Count
-	if d < target*9/10 {
-		t.Fatalf("%d ticks of %s too fast: took %s, expected %s", Count, Delta, d, target)
-	}
-	if !testing.Short() && d > target*30/10 {
-		t.Fatalf("%d ticks of %s too slow: took %s, expected %s", Count, Delta, d, target)
-	}
-}
-
-func TestAfterStop(t *testing.T) {
-	AfterFunc(100*Millisecond, func() {})
-	t0 := NewTimer(50 * Millisecond)
-	c1 := make(chan bool, 1)
-	t1 := AfterFunc(150*Millisecond, func() { c1 <- true })
-	c2 := After(200 * Millisecond)
-	if !t0.Stop() {
-		t.Fatalf("failed to stop event 0")
-	}
-	if !t1.Stop() {
-		t.Fatalf("failed to stop event 1")
-	}
-	<-c2
-	select {
-	case <-t0.C:
-		t.Fatalf("event 0 was not stopped")
-	case <-c1:
-		t.Fatalf("event 1 was not stopped")
-	default:
-	}
-	if t1.Stop() {
-		t.Fatalf("Stop returned true twice")
-	}
-}
-
-func TestAfterQueuing(t *testing.T) {
-	// This test flakes out on some systems,
-	// so we'll try it a few times before declaring it a failure.
-	const attempts = 3
-	err := errors.New("!=nil")
-	for i := 0; i < attempts && err != nil; i++ {
-		if err = testAfterQueuing(t); err != nil {
-			t.Logf("attempt %v failed: %v", i, err)
-		}
-	}
-	if err != nil {
-		t.Fatal(err)
-	}
-}
-
-var slots = []int{5, 3, 6, 6, 6, 1, 1, 2, 7, 9, 4, 8, 0}
-
-type afterResult struct {
-	slot int
-	t    Time
-}
-
-func await(slot int, result chan<- afterResult, ac <-chan Time) {
-	result <- afterResult{slot, <-ac}
-}
-
-func testAfterQueuing(t *testing.T) error {
-	Delta := 100 * Millisecond
-	if testing.Short() {
-		Delta = 20 * Millisecond
-	}
-	// make the result channel buffered because we don't want
-	// to depend on channel queueing semantics that might
-	// possibly change in the future.
-	result := make(chan afterResult, len(slots))
-
-	t0 := Now()
-	for _, slot := range slots {
-		go await(slot, result, After(Duration(slot)*Delta))
-	}
-	sort.Ints(slots)
-	for _, slot := range slots {
-		r := <-result
-		if r.slot != slot {
-			return fmt.Errorf("after slot %d, expected %d", r.slot, slot)
-		}
-		dt := r.t.Sub(t0)
-		target := Duration(slot) * Delta
-		if dt < target-Delta/2 || dt > target+Delta*10 {
-			return fmt.Errorf("After(%s) arrived at %s, expected [%s,%s]", target, dt, target-Delta/2, target+Delta*10)
-		}
-	}
-	return nil
-}
-
-func TestTimerStopStress(t *testing.T) {
-	if testing.Short() {
-		return
-	}
-	for i := 0; i < 100; i++ {
-		go func(i int) {
-			timer := AfterFunc(2*Second, func() {
-				t.Fatalf("timer %d was not stopped", i)
-			})
-			Sleep(1 * Second)
-			timer.Stop()
-		}(i)
-	}
-	Sleep(3 * Second)
-}
-
-func TestSleepZeroDeadlock(t *testing.T) {
-	// Sleep(0) used to hang, the sequence of events was as follows.
-	// Sleep(0) sets G's status to Gwaiting, but then immediately returns leaving the status.
-	// Then the goroutine calls e.g. new and falls down into the scheduler due to pending GC.
-	// After the GC nobody wakes up the goroutine from Gwaiting status.
-	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4))
-	c := make(chan bool)
-	go func() {
-		for i := 0; i < 100; i++ {
-			runtime.GC()
-		}
-		c <- true
-	}()
-	for i := 0; i < 100; i++ {
-		Sleep(0)
-		tmp := make(chan bool, 1)
-		tmp <- true
-		<-tmp
-	}
-	<-c
-}
-
-func testReset(d Duration) error {
-	t0 := NewTimer(2 * d)
-	Sleep(d)
-	if t0.Reset(3*d) != true {
-		return errors.New("resetting unfired timer returned false")
-	}
-	Sleep(2 * d)
-	select {
-	case <-t0.C:
-		return errors.New("timer fired early")
-	default:
-	}
-	Sleep(2 * d)
-	select {
-	case <-t0.C:
-	default:
-		return errors.New("reset timer did not fire")
-	}
-
-	if t0.Reset(50*Millisecond) != false {
-		return errors.New("resetting expired timer returned true")
-	}
-	return nil
-}
-
-func TestReset(t *testing.T) {
-	// We try to run this test with increasingly larger multiples
-	// until one works so slow, loaded hardware isn't as flaky,
-	// but without slowing down fast machines unnecessarily.
-	const unit = 25 * Millisecond
-	tries := []Duration{
-		1 * unit,
-		3 * unit,
-		7 * unit,
-		15 * unit,
-	}
-	var err error
-	for _, d := range tries {
-		err = testReset(d)
-		if err == nil {
-			t.Logf("passed using duration %v", d)
-			return
-		}
-	}
-	t.Error(err)
-}
-
-// Test that sleeping for an interval so large it overflows does not
-// result in a short sleep duration.
-func TestOverflowSleep(t *testing.T) {
-	const big = Duration(int64(1<<63 - 1))
-	select {
-	case <-After(big):
-		t.Fatalf("big timeout fired")
-	case <-After(25 * Millisecond):
-		// OK
-	}
-	const neg = Duration(-1 << 63)
-	select {
-	case <-After(neg):
-		// OK
-	case <-After(1 * Second):
-		t.Fatalf("negative timeout didn't fire")
-	}
-}
-
-// Test that a panic while deleting a timer does not leave
-// the timers mutex held, deadlocking a ticker.Stop in a defer.
-func TestIssue5745(t *testing.T) {
-	ticker := NewTicker(Hour)
-	defer func() {
-		// would deadlock here before the fix due to
-		// lock taken before the segfault.
-		ticker.Stop()
-
-		if r := recover(); r == nil {
-			t.Error("Expected panic, but none happened.")
-		}
-	}()
-
-	// cause a panic due to a segfault
-	var timer *Timer
-	timer.Stop()
-	t.Error("Should be unreachable.")
-}
-
-func TestOverflowRuntimeTimer(t *testing.T) {
-	if testing.Short() {
-		t.Skip("skipping in short mode, see issue 6874")
-	}
-	if err := CheckRuntimeTimerOverflow(); err != nil {
-		t.Fatalf(err.Error())
-	}
-}
diff --git a/src/pkg/time/time.go b/src/pkg/time/time.go
deleted file mode 100644
index 0a2b091..0000000
--- a/src/pkg/time/time.go
+++ /dev/null
@@ -1,1206 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package time provides functionality for measuring and displaying time.
-//
-// The calendrical calculations always assume a Gregorian calendar.
-package time
-
-import "errors"
-
-// A Time represents an instant in time with nanosecond precision.
-//
-// Programs using times should typically store and pass them as values,
-// not pointers.  That is, time variables and struct fields should be of
-// type time.Time, not *time.Time.  A Time value can be used by
-// multiple goroutines simultaneously.
-//
-// Time instants can be compared using the Before, After, and Equal methods.
-// The Sub method subtracts two instants, producing a Duration.
-// The Add method adds a Time and a Duration, producing a Time.
-//
-// The zero value of type Time is January 1, year 1, 00:00:00.000000000 UTC.
-// As this time is unlikely to come up in practice, the IsZero method gives
-// a simple way of detecting a time that has not been initialized explicitly.
-//
-// Each Time has associated with it a Location, consulted when computing the
-// presentation form of the time, such as in the Format, Hour, and Year methods.
-// The methods Local, UTC, and In return a Time with a specific location.
-// Changing the location in this way changes only the presentation; it does not
-// change the instant in time being denoted and therefore does not affect the
-// computations described in earlier paragraphs.
-//
-type Time struct {
-	// sec gives the number of seconds elapsed since
-	// January 1, year 1 00:00:00 UTC.
-	sec int64
-
-	// nsec specifies a non-negative nanosecond
-	// offset within the second named by Seconds.
-	// It must be in the range [0, 999999999].
-	//
-	// It is declared as uintptr instead of int32 or uint32
-	// to avoid garbage collector aliasing in the case where
-	// on a 64-bit system the int32 or uint32 field is written
-	// over the low half of a pointer, creating another pointer.
-	// TODO(rsc): When the garbage collector is completely
-	// precise, change back to int32.
-	nsec uintptr
-
-	// loc specifies the Location that should be used to
-	// determine the minute, hour, month, day, and year
-	// that correspond to this Time.
-	// Only the zero Time has a nil Location.
-	// In that case it is interpreted to mean UTC.
-	loc *Location
-}
-
-// After reports whether the time instant t is after u.
-func (t Time) After(u Time) bool {
-	return t.sec > u.sec || t.sec == u.sec && t.nsec > u.nsec
-}
-
-// Before reports whether the time instant t is before u.
-func (t Time) Before(u Time) bool {
-	return t.sec < u.sec || t.sec == u.sec && t.nsec < u.nsec
-}
-
-// Equal reports whether t and u represent the same time instant.
-// Two times can be equal even if they are in different locations.
-// For example, 6:00 +0200 CEST and 4:00 UTC are Equal.
-// This comparison is different from using t == u, which also compares
-// the locations.
-func (t Time) Equal(u Time) bool {
-	return t.sec == u.sec && t.nsec == u.nsec
-}
-
-// A Month specifies a month of the year (January = 1, ...).
-type Month int
-
-const (
-	January Month = 1 + iota
-	February
-	March
-	April
-	May
-	June
-	July
-	August
-	September
-	October
-	November
-	December
-)
-
-var months = [...]string{
-	"January",
-	"February",
-	"March",
-	"April",
-	"May",
-	"June",
-	"July",
-	"August",
-	"September",
-	"October",
-	"November",
-	"December",
-}
-
-// String returns the English name of the month ("January", "February", ...).
-func (m Month) String() string { return months[m-1] }
-
-// A Weekday specifies a day of the week (Sunday = 0, ...).
-type Weekday int
-
-const (
-	Sunday Weekday = iota
-	Monday
-	Tuesday
-	Wednesday
-	Thursday
-	Friday
-	Saturday
-)
-
-var days = [...]string{
-	"Sunday",
-	"Monday",
-	"Tuesday",
-	"Wednesday",
-	"Thursday",
-	"Friday",
-	"Saturday",
-}
-
-// String returns the English name of the day ("Sunday", "Monday", ...).
-func (d Weekday) String() string { return days[d] }
-
-// Computations on time.
-//
-// The zero value for a Time is defined to be
-//	January 1, year 1, 00:00:00.000000000 UTC
-// which (1) looks like a zero, or as close as you can get in a date
-// (1-1-1 00:00:00 UTC), (2) is unlikely enough to arise in practice to
-// be a suitable "not set" sentinel, unlike Jan 1 1970, and (3) has a
-// non-negative year even in time zones west of UTC, unlike 1-1-0
-// 00:00:00 UTC, which would be 12-31-(-1) 19:00:00 in New York.
-//
-// The zero Time value does not force a specific epoch for the time
-// representation.  For example, to use the Unix epoch internally, we
-// could define that to distinguish a zero value from Jan 1 1970, that
-// time would be represented by sec=-1, nsec=1e9.  However, it does
-// suggest a representation, namely using 1-1-1 00:00:00 UTC as the
-// epoch, and that's what we do.
-//
-// The Add and Sub computations are oblivious to the choice of epoch.
-//
-// The presentation computations - year, month, minute, and so on - all
-// rely heavily on division and modulus by positive constants.  For
-// calendrical calculations we want these divisions to round down, even
-// for negative values, so that the remainder is always positive, but
-// Go's division (like most hardware division instructions) rounds to
-// zero.  We can still do those computations and then adjust the result
-// for a negative numerator, but it's annoying to write the adjustment
-// over and over.  Instead, we can change to a different epoch so long
-// ago that all the times we care about will be positive, and then round
-// to zero and round down coincide.  These presentation routines already
-// have to add the zone offset, so adding the translation to the
-// alternate epoch is cheap.  For example, having a non-negative time t
-// means that we can write
-//
-//	sec = t % 60
-//
-// instead of
-//
-//	sec = t % 60
-//	if sec < 0 {
-//		sec += 60
-//	}
-//
-// everywhere.
-//
-// The calendar runs on an exact 400 year cycle: a 400-year calendar
-// printed for 1970-2469 will apply as well to 2470-2869.  Even the days
-// of the week match up.  It simplifies the computations to choose the
-// cycle boundaries so that the exceptional years are always delayed as
-// long as possible.  That means choosing a year equal to 1 mod 400, so
-// that the first leap year is the 4th year, the first missed leap year
-// is the 100th year, and the missed missed leap year is the 400th year.
-// So we'd prefer instead to print a calendar for 2001-2400 and reuse it
-// for 2401-2800.
-//
-// Finally, it's convenient if the delta between the Unix epoch and
-// long-ago epoch is representable by an int64 constant.
-//
-// These three considerations—choose an epoch as early as possible, that
-// uses a year equal to 1 mod 400, and that is no more than 2⁶³ seconds
-// earlier than 1970—bring us to the year -292277022399.  We refer to
-// this year as the absolute zero year, and to times measured as a uint64
-// seconds since this year as absolute times.
-//
-// Times measured as an int64 seconds since the year 1—the representation
-// used for Time's sec field—are called internal times.
-//
-// Times measured as an int64 seconds since the year 1970 are called Unix
-// times.
-//
-// It is tempting to just use the year 1 as the absolute epoch, defining
-// that the routines are only valid for years >= 1.  However, the
-// routines would then be invalid when displaying the epoch in time zones
-// west of UTC, since it is year 0.  It doesn't seem tenable to say that
-// printing the zero time correctly isn't supported in half the time
-// zones.  By comparison, it's reasonable to mishandle some times in
-// the year -292277022399.
-//
-// All this is opaque to clients of the API and can be changed if a
-// better implementation presents itself.
-
-const (
-	// The unsigned zero year for internal calculations.
-	// Must be 1 mod 400, and times before it will not compute correctly,
-	// but otherwise can be changed at will.
-	absoluteZeroYear = -292277022399
-
-	// The year of the zero Time.
-	// Assumed by the unixToInternal computation below.
-	internalYear = 1
-
-	// The year of the zero Unix time.
-	unixYear = 1970
-
-	// Offsets to convert between internal and absolute or Unix times.
-	absoluteToInternal int64 = (absoluteZeroYear - internalYear) * 365.2425 * secondsPerDay
-	internalToAbsolute       = -absoluteToInternal
-
-	unixToInternal int64 = (1969*365 + 1969/4 - 1969/100 + 1969/400) * secondsPerDay
-	internalToUnix int64 = -unixToInternal
-)
-
-// IsZero reports whether t represents the zero time instant,
-// January 1, year 1, 00:00:00 UTC.
-func (t Time) IsZero() bool {
-	return t.sec == 0 && t.nsec == 0
-}
-
-// abs returns the time t as an absolute time, adjusted by the zone offset.
-// It is called when computing a presentation property like Month or Hour.
-func (t Time) abs() uint64 {
-	l := t.loc
-	// Avoid function calls when possible.
-	if l == nil || l == &localLoc {
-		l = l.get()
-	}
-	sec := t.sec + internalToUnix
-	if l != &utcLoc {
-		if l.cacheZone != nil && l.cacheStart <= sec && sec < l.cacheEnd {
-			sec += int64(l.cacheZone.offset)
-		} else {
-			_, offset, _, _, _ := l.lookup(sec)
-			sec += int64(offset)
-		}
-	}
-	return uint64(sec + (unixToInternal + internalToAbsolute))
-}
-
-// locabs is a combination of the Zone and abs methods,
-// extracting both return values from a single zone lookup.
-func (t Time) locabs() (name string, offset int, abs uint64) {
-	l := t.loc
-	if l == nil || l == &localLoc {
-		l = l.get()
-	}
-	// Avoid function call if we hit the local time cache.
-	sec := t.sec + internalToUnix
-	if l != &utcLoc {
-		if l.cacheZone != nil && l.cacheStart <= sec && sec < l.cacheEnd {
-			name = l.cacheZone.name
-			offset = l.cacheZone.offset
-		} else {
-			name, offset, _, _, _ = l.lookup(sec)
-		}
-		sec += int64(offset)
-	} else {
-		name = "UTC"
-	}
-	abs = uint64(sec + (unixToInternal + internalToAbsolute))
-	return
-}
-
-// Date returns the year, month, and day in which t occurs.
-func (t Time) Date() (year int, month Month, day int) {
-	year, month, day, _ = t.date(true)
-	return
-}
-
-// Year returns the year in which t occurs.
-func (t Time) Year() int {
-	year, _, _, _ := t.date(false)
-	return year
-}
-
-// Month returns the month of the year specified by t.
-func (t Time) Month() Month {
-	_, month, _, _ := t.date(true)
-	return month
-}
-
-// Day returns the day of the month specified by t.
-func (t Time) Day() int {
-	_, _, day, _ := t.date(true)
-	return day
-}
-
-// Weekday returns the day of the week specified by t.
-func (t Time) Weekday() Weekday {
-	return absWeekday(t.abs())
-}
-
-// absWeekday is like Weekday but operates on an absolute time.
-func absWeekday(abs uint64) Weekday {
-	// January 1 of the absolute year, like January 1 of 2001, was a Monday.
-	sec := (abs + uint64(Monday)*secondsPerDay) % secondsPerWeek
-	return Weekday(int(sec) / secondsPerDay)
-}
-
-// ISOWeek returns the ISO 8601 year and week number in which t occurs.
-// Week ranges from 1 to 53. Jan 01 to Jan 03 of year n might belong to
-// week 52 or 53 of year n-1, and Dec 29 to Dec 31 might belong to week 1
-// of year n+1.
-func (t Time) ISOWeek() (year, week int) {
-	year, month, day, yday := t.date(true)
-	wday := int(t.Weekday()+6) % 7 // weekday but Monday = 0.
-	const (
-		Mon int = iota
-		Tue
-		Wed
-		Thu
-		Fri
-		Sat
-		Sun
-	)
-
-	// Calculate week as number of Mondays in year up to
-	// and including today, plus 1 because the first week is week 0.
-	// Putting the + 1 inside the numerator as a + 7 keeps the
-	// numerator from being negative, which would cause it to
-	// round incorrectly.
-	week = (yday - wday + 7) / 7
-
-	// The week number is now correct under the assumption
-	// that the first Monday of the year is in week 1.
-	// If Jan 1 is a Tuesday, Wednesday, or Thursday, the first Monday
-	// is actually in week 2.
-	jan1wday := (wday - yday + 7*53) % 7
-	if Tue <= jan1wday && jan1wday <= Thu {
-		week++
-	}
-
-	// If the week number is still 0, we're in early January but in
-	// the last week of last year.
-	if week == 0 {
-		year--
-		week = 52
-		// A year has 53 weeks when Jan 1 or Dec 31 is a Thursday,
-		// meaning Jan 1 of the next year is a Friday
-		// or it was a leap year and Jan 1 of the next year is a Saturday.
-		if jan1wday == Fri || (jan1wday == Sat && isLeap(year)) {
-			week++
-		}
-	}
-
-	// December 29 to 31 are in week 1 of next year if
-	// they are after the last Thursday of the year and
-	// December 31 is a Monday, Tuesday, or Wednesday.
-	if month == December && day >= 29 && wday < Thu {
-		if dec31wday := (wday + 31 - day) % 7; Mon <= dec31wday && dec31wday <= Wed {
-			year++
-			week = 1
-		}
-	}
-
-	return
-}
-
-// Clock returns the hour, minute, and second within the day specified by t.
-func (t Time) Clock() (hour, min, sec int) {
-	return absClock(t.abs())
-}
-
-// absClock is like clock but operates on an absolute time.
-func absClock(abs uint64) (hour, min, sec int) {
-	sec = int(abs % secondsPerDay)
-	hour = sec / secondsPerHour
-	sec -= hour * secondsPerHour
-	min = sec / secondsPerMinute
-	sec -= min * secondsPerMinute
-	return
-}
-
-// Hour returns the hour within the day specified by t, in the range [0, 23].
-func (t Time) Hour() int {
-	return int(t.abs()%secondsPerDay) / secondsPerHour
-}
-
-// Minute returns the minute offset within the hour specified by t, in the range [0, 59].
-func (t Time) Minute() int {
-	return int(t.abs()%secondsPerHour) / secondsPerMinute
-}
-
-// Second returns the second offset within the minute specified by t, in the range [0, 59].
-func (t Time) Second() int {
-	return int(t.abs() % secondsPerMinute)
-}
-
-// Nanosecond returns the nanosecond offset within the second specified by t,
-// in the range [0, 999999999].
-func (t Time) Nanosecond() int {
-	return int(t.nsec)
-}
-
-// YearDay returns the day of the year specified by t, in the range [1,365] for non-leap years,
-// and [1,366] in leap years.
-func (t Time) YearDay() int {
-	_, _, _, yday := t.date(false)
-	return yday + 1
-}
-
-// A Duration represents the elapsed time between two instants
-// as an int64 nanosecond count.  The representation limits the
-// largest representable duration to approximately 290 years.
-type Duration int64
-
-const (
-	minDuration Duration = -1 << 63
-	maxDuration Duration = 1<<63 - 1
-)
-
-// Common durations.  There is no definition for units of Day or larger
-// to avoid confusion across daylight savings time zone transitions.
-//
-// To count the number of units in a Duration, divide:
-//	second := time.Second
-//	fmt.Print(int64(second/time.Millisecond)) // prints 1000
-//
-// To convert an integer number of units to a Duration, multiply:
-//	seconds := 10
-//	fmt.Print(time.Duration(seconds)*time.Second) // prints 10s
-//
-const (
-	Nanosecond  Duration = 1
-	Microsecond          = 1000 * Nanosecond
-	Millisecond          = 1000 * Microsecond
-	Second               = 1000 * Millisecond
-	Minute               = 60 * Second
-	Hour                 = 60 * Minute
-)
-
-// String returns a string representing the duration in the form "72h3m0.5s".
-// Leading zero units are omitted.  As a special case, durations less than one
-// second format use a smaller unit (milli-, micro-, or nanoseconds) to ensure
-// that the leading digit is non-zero.  The zero duration formats as 0,
-// with no unit.
-func (d Duration) String() string {
-	// Largest time is 2540400h10m10.000000000s
-	var buf [32]byte
-	w := len(buf)
-
-	u := uint64(d)
-	neg := d < 0
-	if neg {
-		u = -u
-	}
-
-	if u < uint64(Second) {
-		// Special case: if duration is smaller than a second,
-		// use smaller units, like 1.2ms
-		var (
-			prec int
-			unit byte
-		)
-		switch {
-		case u == 0:
-			return "0"
-		case u < uint64(Microsecond):
-			// print nanoseconds
-			prec = 0
-			unit = 'n'
-		case u < uint64(Millisecond):
-			// print microseconds
-			prec = 3
-			unit = 'u'
-		default:
-			// print milliseconds
-			prec = 6
-			unit = 'm'
-		}
-		w -= 2
-		buf[w] = unit
-		buf[w+1] = 's'
-		w, u = fmtFrac(buf[:w], u, prec)
-		w = fmtInt(buf[:w], u)
-	} else {
-		w--
-		buf[w] = 's'
-
-		w, u = fmtFrac(buf[:w], u, 9)
-
-		// u is now integer seconds
-		w = fmtInt(buf[:w], u%60)
-		u /= 60
-
-		// u is now integer minutes
-		if u > 0 {
-			w--
-			buf[w] = 'm'
-			w = fmtInt(buf[:w], u%60)
-			u /= 60
-
-			// u is now integer hours
-			// Stop at hours because days can be different lengths.
-			if u > 0 {
-				w--
-				buf[w] = 'h'
-				w = fmtInt(buf[:w], u)
-			}
-		}
-	}
-
-	if neg {
-		w--
-		buf[w] = '-'
-	}
-
-	return string(buf[w:])
-}
-
-// fmtFrac formats the fraction of v/10**prec (e.g., ".12345") into the
-// tail of buf, omitting trailing zeros.  it omits the decimal
-// point too when the fraction is 0.  It returns the index where the
-// output bytes begin and the value v/10**prec.
-func fmtFrac(buf []byte, v uint64, prec int) (nw int, nv uint64) {
-	// Omit trailing zeros up to and including decimal point.
-	w := len(buf)
-	print := false
-	for i := 0; i < prec; i++ {
-		digit := v % 10
-		print = print || digit != 0
-		if print {
-			w--
-			buf[w] = byte(digit) + '0'
-		}
-		v /= 10
-	}
-	if print {
-		w--
-		buf[w] = '.'
-	}
-	return w, v
-}
-
-// fmtInt formats v into the tail of buf.
-// It returns the index where the output begins.
-func fmtInt(buf []byte, v uint64) int {
-	w := len(buf)
-	if v == 0 {
-		w--
-		buf[w] = '0'
-	} else {
-		for v > 0 {
-			w--
-			buf[w] = byte(v%10) + '0'
-			v /= 10
-		}
-	}
-	return w
-}
-
-// Nanoseconds returns the duration as an integer nanosecond count.
-func (d Duration) Nanoseconds() int64 { return int64(d) }
-
-// These methods return float64 because the dominant
-// use case is for printing a floating point number like 1.5s, and
-// a truncation to integer would make them not useful in those cases.
-// Splitting the integer and fraction ourselves guarantees that
-// converting the returned float64 to an integer rounds the same
-// way that a pure integer conversion would have, even in cases
-// where, say, float64(d.Nanoseconds())/1e9 would have rounded
-// differently.
-
-// Seconds returns the duration as a floating point number of seconds.
-func (d Duration) Seconds() float64 {
-	sec := d / Second
-	nsec := d % Second
-	return float64(sec) + float64(nsec)*1e-9
-}
-
-// Minutes returns the duration as a floating point number of minutes.
-func (d Duration) Minutes() float64 {
-	min := d / Minute
-	nsec := d % Minute
-	return float64(min) + float64(nsec)*(1e-9/60)
-}
-
-// Hours returns the duration as a floating point number of hours.
-func (d Duration) Hours() float64 {
-	hour := d / Hour
-	nsec := d % Hour
-	return float64(hour) + float64(nsec)*(1e-9/60/60)
-}
-
-// Add returns the time t+d.
-func (t Time) Add(d Duration) Time {
-	t.sec += int64(d / 1e9)
-	nsec := int32(t.nsec) + int32(d%1e9)
-	if nsec >= 1e9 {
-		t.sec++
-		nsec -= 1e9
-	} else if nsec < 0 {
-		t.sec--
-		nsec += 1e9
-	}
-	t.nsec = uintptr(nsec)
-	return t
-}
-
-// Sub returns the duration t-u. If the result exceeds the maximum (or minimum)
-// value that can be stored in a Duration, the maximum (or minimum) duration
-// will be returned.
-// To compute t-d for a duration d, use t.Add(-d).
-func (t Time) Sub(u Time) Duration {
-	d := Duration(t.sec-u.sec)*Second + Duration(int32(t.nsec)-int32(u.nsec))
-	// Check for overflow or underflow.
-	switch {
-	case u.Add(d).Equal(t):
-		return d // d is correct
-	case t.Before(u):
-		return minDuration // t - u is negative out of range
-	default:
-		return maxDuration // t - u is positive out of range
-	}
-}
-
-// Since returns the time elapsed since t.
-// It is shorthand for time.Now().Sub(t).
-func Since(t Time) Duration {
-	return Now().Sub(t)
-}
-
-// AddDate returns the time corresponding to adding the
-// given number of years, months, and days to t.
-// For example, AddDate(-1, 2, 3) applied to January 1, 2011
-// returns March 4, 2010.
-//
-// AddDate normalizes its result in the same way that Date does,
-// so, for example, adding one month to October 31 yields
-// December 1, the normalized form for November 31.
-func (t Time) AddDate(years int, months int, days int) Time {
-	year, month, day := t.Date()
-	hour, min, sec := t.Clock()
-	return Date(year+years, month+Month(months), day+days, hour, min, sec, int(t.nsec), t.loc)
-}
-
-const (
-	secondsPerMinute = 60
-	secondsPerHour   = 60 * 60
-	secondsPerDay    = 24 * secondsPerHour
-	secondsPerWeek   = 7 * secondsPerDay
-	daysPer400Years  = 365*400 + 97
-	daysPer100Years  = 365*100 + 24
-	daysPer4Years    = 365*4 + 1
-)
-
-// date computes the year, day of year, and when full=true,
-// the month and day in which t occurs.
-func (t Time) date(full bool) (year int, month Month, day int, yday int) {
-	return absDate(t.abs(), full)
-}
-
-// absDate is like date but operates on an absolute time.
-func absDate(abs uint64, full bool) (year int, month Month, day int, yday int) {
-	// Split into time and day.
-	d := abs / secondsPerDay
-
-	// Account for 400 year cycles.
-	n := d / daysPer400Years
-	y := 400 * n
-	d -= daysPer400Years * n
-
-	// Cut off 100-year cycles.
-	// The last cycle has one extra leap year, so on the last day
-	// of that year, day / daysPer100Years will be 4 instead of 3.
-	// Cut it back down to 3 by subtracting n>>2.
-	n = d / daysPer100Years
-	n -= n >> 2
-	y += 100 * n
-	d -= daysPer100Years * n
-
-	// Cut off 4-year cycles.
-	// The last cycle has a missing leap year, which does not
-	// affect the computation.
-	n = d / daysPer4Years
-	y += 4 * n
-	d -= daysPer4Years * n
-
-	// Cut off years within a 4-year cycle.
-	// The last year is a leap year, so on the last day of that year,
-	// day / 365 will be 4 instead of 3.  Cut it back down to 3
-	// by subtracting n>>2.
-	n = d / 365
-	n -= n >> 2
-	y += n
-	d -= 365 * n
-
-	year = int(int64(y) + absoluteZeroYear)
-	yday = int(d)
-
-	if !full {
-		return
-	}
-
-	day = yday
-	if isLeap(year) {
-		// Leap year
-		switch {
-		case day > 31+29-1:
-			// After leap day; pretend it wasn't there.
-			day--
-		case day == 31+29-1:
-			// Leap day.
-			month = February
-			day = 29
-			return
-		}
-	}
-
-	// Estimate month on assumption that every month has 31 days.
-	// The estimate may be too low by at most one month, so adjust.
-	month = Month(day / 31)
-	end := int(daysBefore[month+1])
-	var begin int
-	if day >= end {
-		month++
-		begin = end
-	} else {
-		begin = int(daysBefore[month])
-	}
-
-	month++ // because January is 1
-	day = day - begin + 1
-	return
-}
-
-// daysBefore[m] counts the number of days in a non-leap year
-// before month m begins.  There is an entry for m=12, counting
-// the number of days before January of next year (365).
-var daysBefore = [...]int32{
-	0,
-	31,
-	31 + 28,
-	31 + 28 + 31,
-	31 + 28 + 31 + 30,
-	31 + 28 + 31 + 30 + 31,
-	31 + 28 + 31 + 30 + 31 + 30,
-	31 + 28 + 31 + 30 + 31 + 30 + 31,
-	31 + 28 + 31 + 30 + 31 + 30 + 31 + 31,
-	31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30,
-	31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31,
-	31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30,
-	31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31,
-}
-
-func daysIn(m Month, year int) int {
-	if m == February && isLeap(year) {
-		return 29
-	}
-	return int(daysBefore[m] - daysBefore[m-1])
-}
-
-// Provided by package runtime.
-func now() (sec int64, nsec int32)
-
-// Now returns the current local time.
-func Now() Time {
-	sec, nsec := now()
-	return Time{sec + unixToInternal, uintptr(nsec), Local}
-}
-
-// UTC returns t with the location set to UTC.
-func (t Time) UTC() Time {
-	t.loc = UTC
-	return t
-}
-
-// Local returns t with the location set to local time.
-func (t Time) Local() Time {
-	t.loc = Local
-	return t
-}
-
-// In returns t with the location information set to loc.
-//
-// In panics if loc is nil.
-func (t Time) In(loc *Location) Time {
-	if loc == nil {
-		panic("time: missing Location in call to Time.In")
-	}
-	t.loc = loc
-	return t
-}
-
-// Location returns the time zone information associated with t.
-func (t Time) Location() *Location {
-	l := t.loc
-	if l == nil {
-		l = UTC
-	}
-	return l
-}
-
-// Zone computes the time zone in effect at time t, returning the abbreviated
-// name of the zone (such as "CET") and its offset in seconds east of UTC.
-func (t Time) Zone() (name string, offset int) {
-	name, offset, _, _, _ = t.loc.lookup(t.sec + internalToUnix)
-	return
-}
-
-// Unix returns t as a Unix time, the number of seconds elapsed
-// since January 1, 1970 UTC.
-func (t Time) Unix() int64 {
-	return t.sec + internalToUnix
-}
-
-// UnixNano returns t as a Unix time, the number of nanoseconds elapsed
-// since January 1, 1970 UTC. The result is undefined if the Unix time
-// in nanoseconds cannot be represented by an int64. Note that this
-// means the result of calling UnixNano on the zero Time is undefined.
-func (t Time) UnixNano() int64 {
-	return (t.sec+internalToUnix)*1e9 + int64(t.nsec)
-}
-
-const timeBinaryVersion byte = 1
-
-// MarshalBinary implements the encoding.BinaryMarshaler interface.
-func (t Time) MarshalBinary() ([]byte, error) {
-	var offsetMin int16 // minutes east of UTC. -1 is UTC.
-
-	if t.Location() == &utcLoc {
-		offsetMin = -1
-	} else {
-		_, offset := t.Zone()
-		if offset%60 != 0 {
-			return nil, errors.New("Time.MarshalBinary: zone offset has fractional minute")
-		}
-		offset /= 60
-		if offset < -32768 || offset == -1 || offset > 32767 {
-			return nil, errors.New("Time.MarshalBinary: unexpected zone offset")
-		}
-		offsetMin = int16(offset)
-	}
-
-	enc := []byte{
-		timeBinaryVersion, // byte 0 : version
-		byte(t.sec >> 56), // bytes 1-8: seconds
-		byte(t.sec >> 48),
-		byte(t.sec >> 40),
-		byte(t.sec >> 32),
-		byte(t.sec >> 24),
-		byte(t.sec >> 16),
-		byte(t.sec >> 8),
-		byte(t.sec),
-		byte(t.nsec >> 24), // bytes 9-12: nanoseconds
-		byte(t.nsec >> 16),
-		byte(t.nsec >> 8),
-		byte(t.nsec),
-		byte(offsetMin >> 8), // bytes 13-14: zone offset in minutes
-		byte(offsetMin),
-	}
-
-	return enc, nil
-}
-
-// UnmarshalBinary implements the encoding.BinaryUnmarshaler interface.
-func (t *Time) UnmarshalBinary(data []byte) error {
-	buf := data
-	if len(buf) == 0 {
-		return errors.New("Time.UnmarshalBinary: no data")
-	}
-
-	if buf[0] != timeBinaryVersion {
-		return errors.New("Time.UnmarshalBinary: unsupported version")
-	}
-
-	if len(buf) != /*version*/ 1+ /*sec*/ 8+ /*nsec*/ 4+ /*zone offset*/ 2 {
-		return errors.New("Time.UnmarshalBinary: invalid length")
-	}
-
-	buf = buf[1:]
-	t.sec = int64(buf[7]) | int64(buf[6])<<8 | int64(buf[5])<<16 | int64(buf[4])<<24 |
-		int64(buf[3])<<32 | int64(buf[2])<<40 | int64(buf[1])<<48 | int64(buf[0])<<56
-
-	buf = buf[8:]
-	t.nsec = uintptr(int32(buf[3]) | int32(buf[2])<<8 | int32(buf[1])<<16 | int32(buf[0])<<24)
-
-	buf = buf[4:]
-	offset := int(int16(buf[1])|int16(buf[0])<<8) * 60
-
-	if offset == -1*60 {
-		t.loc = &utcLoc
-	} else if _, localoff, _, _, _ := Local.lookup(t.sec + internalToUnix); offset == localoff {
-		t.loc = Local
-	} else {
-		t.loc = FixedZone("", offset)
-	}
-
-	return nil
-}
-
-// TODO(rsc): Remove GobEncoder, GobDecoder, MarshalJSON, UnmarshalJSON in Go 2.
-// The same semantics will be provided by the generic MarshalBinary, MarshalText,
-// UnmarshalBinary, UnmarshalText.
-
-// GobEncode implements the gob.GobEncoder interface.
-func (t Time) GobEncode() ([]byte, error) {
-	return t.MarshalBinary()
-}
-
-// GobDecode implements the gob.GobDecoder interface.
-func (t *Time) GobDecode(data []byte) error {
-	return t.UnmarshalBinary(data)
-}
-
-// MarshalJSON implements the json.Marshaler interface.
-// The time is a quoted string in RFC 3339 format, with sub-second precision added if present.
-func (t Time) MarshalJSON() ([]byte, error) {
-	if y := t.Year(); y < 0 || y >= 10000 {
-		// RFC 3339 is clear that years are 4 digits exactly.
-		// See golang.org/issue/4556#c15 for more discussion.
-		return nil, errors.New("Time.MarshalJSON: year outside of range [0,9999]")
-	}
-	return []byte(t.Format(`"` + RFC3339Nano + `"`)), nil
-}
-
-// UnmarshalJSON implements the json.Unmarshaler interface.
-// The time is expected to be a quoted string in RFC 3339 format.
-func (t *Time) UnmarshalJSON(data []byte) (err error) {
-	// Fractional seconds are handled implicitly by Parse.
-	*t, err = Parse(`"`+RFC3339+`"`, string(data))
-	return
-}
-
-// MarshalText implements the encoding.TextMarshaler interface.
-// The time is formatted in RFC 3339 format, with sub-second precision added if present.
-func (t Time) MarshalText() ([]byte, error) {
-	if y := t.Year(); y < 0 || y >= 10000 {
-		return nil, errors.New("Time.MarshalText: year outside of range [0,9999]")
-	}
-	return []byte(t.Format(RFC3339Nano)), nil
-}
-
-// UnmarshalText implements the encoding.TextUnmarshaler interface.
-// The time is expected to be in RFC 3339 format.
-func (t *Time) UnmarshalText(data []byte) (err error) {
-	// Fractional seconds are handled implicitly by Parse.
-	*t, err = Parse(RFC3339, string(data))
-	return
-}
-
-// Unix returns the local Time corresponding to the given Unix time,
-// sec seconds and nsec nanoseconds since January 1, 1970 UTC.
-// It is valid to pass nsec outside the range [0, 999999999].
-func Unix(sec int64, nsec int64) Time {
-	if nsec < 0 || nsec >= 1e9 {
-		n := nsec / 1e9
-		sec += n
-		nsec -= n * 1e9
-		if nsec < 0 {
-			nsec += 1e9
-			sec--
-		}
-	}
-	return Time{sec + unixToInternal, uintptr(nsec), Local}
-}
-
-func isLeap(year int) bool {
-	return year%4 == 0 && (year%100 != 0 || year%400 == 0)
-}
-
-// norm returns nhi, nlo such that
-//	hi * base + lo == nhi * base + nlo
-//	0 <= nlo < base
-func norm(hi, lo, base int) (nhi, nlo int) {
-	if lo < 0 {
-		n := (-lo-1)/base + 1
-		hi -= n
-		lo += n * base
-	}
-	if lo >= base {
-		n := lo / base
-		hi += n
-		lo -= n * base
-	}
-	return hi, lo
-}
-
-// Date returns the Time corresponding to
-//	yyyy-mm-dd hh:mm:ss + nsec nanoseconds
-// in the appropriate zone for that time in the given location.
-//
-// The month, day, hour, min, sec, and nsec values may be outside
-// their usual ranges and will be normalized during the conversion.
-// For example, October 32 converts to November 1.
-//
-// A daylight savings time transition skips or repeats times.
-// For example, in the United States, March 13, 2011 2:15am never occurred,
-// while November 6, 2011 1:15am occurred twice.  In such cases, the
-// choice of time zone, and therefore the time, is not well-defined.
-// Date returns a time that is correct in one of the two zones involved
-// in the transition, but it does not guarantee which.
-//
-// Date panics if loc is nil.
-func Date(year int, month Month, day, hour, min, sec, nsec int, loc *Location) Time {
-	if loc == nil {
-		panic("time: missing Location in call to Date")
-	}
-
-	// Normalize month, overflowing into year.
-	m := int(month) - 1
-	year, m = norm(year, m, 12)
-	month = Month(m) + 1
-
-	// Normalize nsec, sec, min, hour, overflowing into day.
-	sec, nsec = norm(sec, nsec, 1e9)
-	min, sec = norm(min, sec, 60)
-	hour, min = norm(hour, min, 60)
-	day, hour = norm(day, hour, 24)
-
-	y := uint64(int64(year) - absoluteZeroYear)
-
-	// Compute days since the absolute epoch.
-
-	// Add in days from 400-year cycles.
-	n := y / 400
-	y -= 400 * n
-	d := daysPer400Years * n
-
-	// Add in 100-year cycles.
-	n = y / 100
-	y -= 100 * n
-	d += daysPer100Years * n
-
-	// Add in 4-year cycles.
-	n = y / 4
-	y -= 4 * n
-	d += daysPer4Years * n
-
-	// Add in non-leap years.
-	n = y
-	d += 365 * n
-
-	// Add in days before this month.
-	d += uint64(daysBefore[month-1])
-	if isLeap(year) && month >= March {
-		d++ // February 29
-	}
-
-	// Add in days before today.
-	d += uint64(day - 1)
-
-	// Add in time elapsed today.
-	abs := d * secondsPerDay
-	abs += uint64(hour*secondsPerHour + min*secondsPerMinute + sec)
-
-	unix := int64(abs) + (absoluteToInternal + internalToUnix)
-
-	// Look for zone offset for t, so we can adjust to UTC.
-	// The lookup function expects UTC, so we pass t in the
-	// hope that it will not be too close to a zone transition,
-	// and then adjust if it is.
-	_, offset, _, start, end := loc.lookup(unix)
-	if offset != 0 {
-		switch utc := unix - int64(offset); {
-		case utc < start:
-			_, offset, _, _, _ = loc.lookup(start - 1)
-		case utc >= end:
-			_, offset, _, _, _ = loc.lookup(end)
-		}
-		unix -= int64(offset)
-	}
-
-	return Time{unix + unixToInternal, uintptr(nsec), loc}
-}
-
-// Truncate returns the result of rounding t down to a multiple of d (since the zero time).
-// If d <= 0, Truncate returns t unchanged.
-func (t Time) Truncate(d Duration) Time {
-	if d <= 0 {
-		return t
-	}
-	_, r := div(t, d)
-	return t.Add(-r)
-}
-
-// Round returns the result of rounding t to the nearest multiple of d (since the zero time).
-// The rounding behavior for halfway values is to round up.
-// If d <= 0, Round returns t unchanged.
-func (t Time) Round(d Duration) Time {
-	if d <= 0 {
-		return t
-	}
-	_, r := div(t, d)
-	if r+r < d {
-		return t.Add(-r)
-	}
-	return t.Add(d - r)
-}
-
-// div divides t by d and returns the quotient parity and remainder.
-// We don't use the quotient parity anymore (round half up instead of round to even)
-// but it's still here in case we change our minds.
-func div(t Time, d Duration) (qmod2 int, r Duration) {
-	neg := false
-	nsec := int32(t.nsec)
-	if t.sec < 0 {
-		// Operate on absolute value.
-		neg = true
-		t.sec = -t.sec
-		nsec = -nsec
-		if nsec < 0 {
-			nsec += 1e9
-			t.sec-- // t.sec >= 1 before the -- so safe
-		}
-	}
-
-	switch {
-	// Special case: 2d divides 1 second.
-	case d < Second && Second%(d+d) == 0:
-		qmod2 = int(nsec/int32(d)) & 1
-		r = Duration(nsec % int32(d))
-
-	// Special case: d is a multiple of 1 second.
-	case d%Second == 0:
-		d1 := int64(d / Second)
-		qmod2 = int(t.sec/d1) & 1
-		r = Duration(t.sec%d1)*Second + Duration(nsec)
-
-	// General case.
-	// This could be faster if more cleverness were applied,
-	// but it's really only here to avoid special case restrictions in the API.
-	// No one will care about these cases.
-	default:
-		// Compute nanoseconds as 128-bit number.
-		sec := uint64(t.sec)
-		tmp := (sec >> 32) * 1e9
-		u1 := tmp >> 32
-		u0 := tmp << 32
-		tmp = uint64(sec&0xFFFFFFFF) * 1e9
-		u0x, u0 := u0, u0+tmp
-		if u0 < u0x {
-			u1++
-		}
-		u0x, u0 = u0, u0+uint64(nsec)
-		if u0 < u0x {
-			u1++
-		}
-
-		// Compute remainder by subtracting r<<k for decreasing k.
-		// Quotient parity is whether we subtract on last round.
-		d1 := uint64(d)
-		for d1>>63 != 1 {
-			d1 <<= 1
-		}
-		d0 := uint64(0)
-		for {
-			qmod2 = 0
-			if u1 > d1 || u1 == d1 && u0 >= d0 {
-				// subtract
-				qmod2 = 1
-				u0x, u0 = u0, u0-d0
-				if u0 > u0x {
-					u1--
-				}
-				u1 -= d1
-			}
-			if d1 == 0 && d0 == uint64(d) {
-				break
-			}
-			d0 >>= 1
-			d0 |= (d1 & 1) << 63
-			d1 >>= 1
-		}
-		r = Duration(u0)
-	}
-
-	if neg && r != 0 {
-		// If input was negative and not an exact multiple of d, we computed q, r such that
-		//	q*d + r = -t
-		// But the right answers are given by -(q-1), d-r:
-		//	q*d + r = -t
-		//	-q*d - r = t
-		//	-(q-1)*d + (d - r) = t
-		qmod2 ^= 1
-		r = d - r
-	}
-	return
-}
diff --git a/src/pkg/time/time_test.go b/src/pkg/time/time_test.go
deleted file mode 100644
index 4ae7da5..0000000
--- a/src/pkg/time/time_test.go
+++ /dev/null
@@ -1,1081 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package time_test
-
-import (
-	"bytes"
-	"encoding/gob"
-	"encoding/json"
-	"fmt"
-	"math/big"
-	"math/rand"
-	"runtime"
-	"testing"
-	"testing/quick"
-	. "time"
-)
-
-// We should be in PST/PDT, but if the time zone files are missing we
-// won't be. The purpose of this test is to at least explain why some of
-// the subsequent tests fail.
-func TestZoneData(t *testing.T) {
-	lt := Now()
-	// PST is 8 hours west, PDT is 7 hours west.  We could use the name but it's not unique.
-	if name, off := lt.Zone(); off != -8*60*60 && off != -7*60*60 {
-		t.Errorf("Unable to find US Pacific time zone data for testing; time zone is %q offset %d", name, off)
-		t.Error("Likely problem: the time zone files have not been installed.")
-	}
-}
-
-// parsedTime is the struct representing a parsed time value.
-type parsedTime struct {
-	Year                 int
-	Month                Month
-	Day                  int
-	Hour, Minute, Second int // 15:04:05 is 15, 4, 5.
-	Nanosecond           int // Fractional second.
-	Weekday              Weekday
-	ZoneOffset           int    // seconds east of UTC, e.g. -7*60*60 for -0700
-	Zone                 string // e.g., "MST"
-}
-
-type TimeTest struct {
-	seconds int64
-	golden  parsedTime
-}
-
-var utctests = []TimeTest{
-	{0, parsedTime{1970, January, 1, 0, 0, 0, 0, Thursday, 0, "UTC"}},
-	{1221681866, parsedTime{2008, September, 17, 20, 4, 26, 0, Wednesday, 0, "UTC"}},
-	{-1221681866, parsedTime{1931, April, 16, 3, 55, 34, 0, Thursday, 0, "UTC"}},
-	{-11644473600, parsedTime{1601, January, 1, 0, 0, 0, 0, Monday, 0, "UTC"}},
-	{599529660, parsedTime{1988, December, 31, 0, 1, 0, 0, Saturday, 0, "UTC"}},
-	{978220860, parsedTime{2000, December, 31, 0, 1, 0, 0, Sunday, 0, "UTC"}},
-}
-
-var nanoutctests = []TimeTest{
-	{0, parsedTime{1970, January, 1, 0, 0, 0, 1e8, Thursday, 0, "UTC"}},
-	{1221681866, parsedTime{2008, September, 17, 20, 4, 26, 2e8, Wednesday, 0, "UTC"}},
-}
-
-var localtests = []TimeTest{
-	{0, parsedTime{1969, December, 31, 16, 0, 0, 0, Wednesday, -8 * 60 * 60, "PST"}},
-	{1221681866, parsedTime{2008, September, 17, 13, 4, 26, 0, Wednesday, -7 * 60 * 60, "PDT"}},
-}
-
-var nanolocaltests = []TimeTest{
-	{0, parsedTime{1969, December, 31, 16, 0, 0, 1e8, Wednesday, -8 * 60 * 60, "PST"}},
-	{1221681866, parsedTime{2008, September, 17, 13, 4, 26, 3e8, Wednesday, -7 * 60 * 60, "PDT"}},
-}
-
-func same(t Time, u *parsedTime) bool {
-	// Check aggregates.
-	year, month, day := t.Date()
-	hour, min, sec := t.Clock()
-	name, offset := t.Zone()
-	if year != u.Year || month != u.Month || day != u.Day ||
-		hour != u.Hour || min != u.Minute || sec != u.Second ||
-		name != u.Zone || offset != u.ZoneOffset {
-		return false
-	}
-	// Check individual entries.
-	return t.Year() == u.Year &&
-		t.Month() == u.Month &&
-		t.Day() == u.Day &&
-		t.Hour() == u.Hour &&
-		t.Minute() == u.Minute &&
-		t.Second() == u.Second &&
-		t.Nanosecond() == u.Nanosecond &&
-		t.Weekday() == u.Weekday
-}
-
-func TestSecondsToUTC(t *testing.T) {
-	for _, test := range utctests {
-		sec := test.seconds
-		golden := &test.golden
-		tm := Unix(sec, 0).UTC()
-		newsec := tm.Unix()
-		if newsec != sec {
-			t.Errorf("SecondsToUTC(%d).Seconds() = %d", sec, newsec)
-		}
-		if !same(tm, golden) {
-			t.Errorf("SecondsToUTC(%d):  // %#v", sec, tm)
-			t.Errorf("  want=%+v", *golden)
-			t.Errorf("  have=%v", tm.Format(RFC3339+" MST"))
-		}
-	}
-}
-
-func TestNanosecondsToUTC(t *testing.T) {
-	for _, test := range nanoutctests {
-		golden := &test.golden
-		nsec := test.seconds*1e9 + int64(golden.Nanosecond)
-		tm := Unix(0, nsec).UTC()
-		newnsec := tm.Unix()*1e9 + int64(tm.Nanosecond())
-		if newnsec != nsec {
-			t.Errorf("NanosecondsToUTC(%d).Nanoseconds() = %d", nsec, newnsec)
-		}
-		if !same(tm, golden) {
-			t.Errorf("NanosecondsToUTC(%d):", nsec)
-			t.Errorf("  want=%+v", *golden)
-			t.Errorf("  have=%+v", tm.Format(RFC3339+" MST"))
-		}
-	}
-}
-
-func TestSecondsToLocalTime(t *testing.T) {
-	for _, test := range localtests {
-		sec := test.seconds
-		golden := &test.golden
-		tm := Unix(sec, 0)
-		newsec := tm.Unix()
-		if newsec != sec {
-			t.Errorf("SecondsToLocalTime(%d).Seconds() = %d", sec, newsec)
-		}
-		if !same(tm, golden) {
-			t.Errorf("SecondsToLocalTime(%d):", sec)
-			t.Errorf("  want=%+v", *golden)
-			t.Errorf("  have=%+v", tm.Format(RFC3339+" MST"))
-		}
-	}
-}
-
-func TestNanosecondsToLocalTime(t *testing.T) {
-	for _, test := range nanolocaltests {
-		golden := &test.golden
-		nsec := test.seconds*1e9 + int64(golden.Nanosecond)
-		tm := Unix(0, nsec)
-		newnsec := tm.Unix()*1e9 + int64(tm.Nanosecond())
-		if newnsec != nsec {
-			t.Errorf("NanosecondsToLocalTime(%d).Seconds() = %d", nsec, newnsec)
-		}
-		if !same(tm, golden) {
-			t.Errorf("NanosecondsToLocalTime(%d):", nsec)
-			t.Errorf("  want=%+v", *golden)
-			t.Errorf("  have=%+v", tm.Format(RFC3339+" MST"))
-		}
-	}
-}
-
-func TestSecondsToUTCAndBack(t *testing.T) {
-	f := func(sec int64) bool { return Unix(sec, 0).UTC().Unix() == sec }
-	f32 := func(sec int32) bool { return f(int64(sec)) }
-	cfg := &quick.Config{MaxCount: 10000}
-
-	// Try a reasonable date first, then the huge ones.
-	if err := quick.Check(f32, cfg); err != nil {
-		t.Fatal(err)
-	}
-	if err := quick.Check(f, cfg); err != nil {
-		t.Fatal(err)
-	}
-}
-
-func TestNanosecondsToUTCAndBack(t *testing.T) {
-	f := func(nsec int64) bool {
-		t := Unix(0, nsec).UTC()
-		ns := t.Unix()*1e9 + int64(t.Nanosecond())
-		return ns == nsec
-	}
-	f32 := func(nsec int32) bool { return f(int64(nsec)) }
-	cfg := &quick.Config{MaxCount: 10000}
-
-	// Try a small date first, then the large ones. (The span is only a few hundred years
-	// for nanoseconds in an int64.)
-	if err := quick.Check(f32, cfg); err != nil {
-		t.Fatal(err)
-	}
-	if err := quick.Check(f, cfg); err != nil {
-		t.Fatal(err)
-	}
-}
-
-// The time routines provide no way to get absolute time
-// (seconds since zero), but we need it to compute the right
-// answer for bizarre roundings like "to the nearest 3 ns".
-// Compute as t - year1 = (t - 1970) + (1970 - 2001) + (2001 - 1).
-// t - 1970 is returned by Unix and Nanosecond.
-// 1970 - 2001 is -(31*365+8)*86400 = -978307200 seconds.
-// 2001 - 1 is 2000*365.2425*86400 = 63113904000 seconds.
-const unixToZero = -978307200 + 63113904000
-
-// abs returns the absolute time stored in t, as seconds and nanoseconds.
-func abs(t Time) (sec, nsec int64) {
-	unix := t.Unix()
-	nano := t.Nanosecond()
-	return unix + unixToZero, int64(nano)
-}
-
-// absString returns abs as a decimal string.
-func absString(t Time) string {
-	sec, nsec := abs(t)
-	if sec < 0 {
-		sec = -sec
-		nsec = -nsec
-		if nsec < 0 {
-			nsec += 1e9
-			sec--
-		}
-		return fmt.Sprintf("-%d%09d", sec, nsec)
-	}
-	return fmt.Sprintf("%d%09d", sec, nsec)
-}
-
-var truncateRoundTests = []struct {
-	t Time
-	d Duration
-}{
-	{Date(-1, January, 1, 12, 15, 30, 5e8, UTC), 3},
-	{Date(-1, January, 1, 12, 15, 31, 5e8, UTC), 3},
-	{Date(2012, January, 1, 12, 15, 30, 5e8, UTC), Second},
-	{Date(2012, January, 1, 12, 15, 31, 5e8, UTC), Second},
-}
-
-func TestTruncateRound(t *testing.T) {
-	var (
-		bsec  = new(big.Int)
-		bnsec = new(big.Int)
-		bd    = new(big.Int)
-		bt    = new(big.Int)
-		br    = new(big.Int)
-		bq    = new(big.Int)
-		b1e9  = new(big.Int)
-	)
-
-	b1e9.SetInt64(1e9)
-
-	testOne := func(ti, tns, di int64) bool {
-		t0 := Unix(ti, int64(tns)).UTC()
-		d := Duration(di)
-		if d < 0 {
-			d = -d
-		}
-		if d <= 0 {
-			d = 1
-		}
-
-		// Compute bt = absolute nanoseconds.
-		sec, nsec := abs(t0)
-		bsec.SetInt64(sec)
-		bnsec.SetInt64(nsec)
-		bt.Mul(bsec, b1e9)
-		bt.Add(bt, bnsec)
-
-		// Compute quotient and remainder mod d.
-		bd.SetInt64(int64(d))
-		bq.DivMod(bt, bd, br)
-
-		// To truncate, subtract remainder.
-		// br is < d, so it fits in an int64.
-		r := br.Int64()
-		t1 := t0.Add(-Duration(r))
-
-		// Check that time.Truncate works.
-		if trunc := t0.Truncate(d); trunc != t1 {
-			t.Errorf("Time.Truncate(%s, %s) = %s, want %s\n"+
-				"%v trunc %v =\n%v want\n%v",
-				t0.Format(RFC3339Nano), d, trunc, t1.Format(RFC3339Nano),
-				absString(t0), int64(d), absString(trunc), absString(t1))
-			return false
-		}
-
-		// To round, add d back if remainder r > d/2 or r == exactly d/2.
-		// The commented out code would round half to even instead of up,
-		// but that makes it time-zone dependent, which is a bit strange.
-		if r > int64(d)/2 || r+r == int64(d) /*&& bq.Bit(0) == 1*/ {
-			t1 = t1.Add(Duration(d))
-		}
-
-		// Check that time.Round works.
-		if rnd := t0.Round(d); rnd != t1 {
-			t.Errorf("Time.Round(%s, %s) = %s, want %s\n"+
-				"%v round %v =\n%v want\n%v",
-				t0.Format(RFC3339Nano), d, rnd, t1.Format(RFC3339Nano),
-				absString(t0), int64(d), absString(rnd), absString(t1))
-			return false
-		}
-		return true
-	}
-
-	// manual test cases
-	for _, tt := range truncateRoundTests {
-		testOne(tt.t.Unix(), int64(tt.t.Nanosecond()), int64(tt.d))
-	}
-
-	// exhaustive near 0
-	for i := 0; i < 100; i++ {
-		for j := 1; j < 100; j++ {
-			testOne(unixToZero, int64(i), int64(j))
-			testOne(unixToZero, -int64(i), int64(j))
-			if t.Failed() {
-				return
-			}
-		}
-	}
-
-	if t.Failed() {
-		return
-	}
-
-	// randomly generated test cases
-	cfg := &quick.Config{MaxCount: 100000}
-	if testing.Short() {
-		cfg.MaxCount = 1000
-	}
-
-	// divisors of Second
-	f1 := func(ti int64, tns int32, logdi int32) bool {
-		d := Duration(1)
-		a, b := uint(logdi%9), (logdi>>16)%9
-		d <<= a
-		for i := 0; i < int(b); i++ {
-			d *= 5
-		}
-		return testOne(ti, int64(tns), int64(d))
-	}
-	quick.Check(f1, cfg)
-
-	// multiples of Second
-	f2 := func(ti int64, tns int32, di int32) bool {
-		d := Duration(di) * Second
-		if d < 0 {
-			d = -d
-		}
-		return testOne(ti, int64(tns), int64(d))
-	}
-	quick.Check(f2, cfg)
-
-	// halfway cases
-	f3 := func(tns, di int64) bool {
-		di &= 0xfffffffe
-		if di == 0 {
-			di = 2
-		}
-		tns -= tns % di
-		if tns < 0 {
-			tns += di / 2
-		} else {
-			tns -= di / 2
-		}
-		return testOne(0, tns, di)
-	}
-	quick.Check(f3, cfg)
-
-	// full generality
-	f4 := func(ti int64, tns int32, di int64) bool {
-		return testOne(ti, int64(tns), di)
-	}
-	quick.Check(f4, cfg)
-}
-
-type ISOWeekTest struct {
-	year       int // year
-	month, day int // month and day
-	yex        int // expected year
-	wex        int // expected week
-}
-
-var isoWeekTests = []ISOWeekTest{
-	{1981, 1, 1, 1981, 1}, {1982, 1, 1, 1981, 53}, {1983, 1, 1, 1982, 52},
-	{1984, 1, 1, 1983, 52}, {1985, 1, 1, 1985, 1}, {1986, 1, 1, 1986, 1},
-	{1987, 1, 1, 1987, 1}, {1988, 1, 1, 1987, 53}, {1989, 1, 1, 1988, 52},
-	{1990, 1, 1, 1990, 1}, {1991, 1, 1, 1991, 1}, {1992, 1, 1, 1992, 1},
-	{1993, 1, 1, 1992, 53}, {1994, 1, 1, 1993, 52}, {1995, 1, 2, 1995, 1},
-	{1996, 1, 1, 1996, 1}, {1996, 1, 7, 1996, 1}, {1996, 1, 8, 1996, 2},
-	{1997, 1, 1, 1997, 1}, {1998, 1, 1, 1998, 1}, {1999, 1, 1, 1998, 53},
-	{2000, 1, 1, 1999, 52}, {2001, 1, 1, 2001, 1}, {2002, 1, 1, 2002, 1},
-	{2003, 1, 1, 2003, 1}, {2004, 1, 1, 2004, 1}, {2005, 1, 1, 2004, 53},
-	{2006, 1, 1, 2005, 52}, {2007, 1, 1, 2007, 1}, {2008, 1, 1, 2008, 1},
-	{2009, 1, 1, 2009, 1}, {2010, 1, 1, 2009, 53}, {2010, 1, 1, 2009, 53},
-	{2011, 1, 1, 2010, 52}, {2011, 1, 2, 2010, 52}, {2011, 1, 3, 2011, 1},
-	{2011, 1, 4, 2011, 1}, {2011, 1, 5, 2011, 1}, {2011, 1, 6, 2011, 1},
-	{2011, 1, 7, 2011, 1}, {2011, 1, 8, 2011, 1}, {2011, 1, 9, 2011, 1},
-	{2011, 1, 10, 2011, 2}, {2011, 1, 11, 2011, 2}, {2011, 6, 12, 2011, 23},
-	{2011, 6, 13, 2011, 24}, {2011, 12, 25, 2011, 51}, {2011, 12, 26, 2011, 52},
-	{2011, 12, 27, 2011, 52}, {2011, 12, 28, 2011, 52}, {2011, 12, 29, 2011, 52},
-	{2011, 12, 30, 2011, 52}, {2011, 12, 31, 2011, 52}, {1995, 1, 1, 1994, 52},
-	{2012, 1, 1, 2011, 52}, {2012, 1, 2, 2012, 1}, {2012, 1, 8, 2012, 1},
-	{2012, 1, 9, 2012, 2}, {2012, 12, 23, 2012, 51}, {2012, 12, 24, 2012, 52},
-	{2012, 12, 30, 2012, 52}, {2012, 12, 31, 2013, 1}, {2013, 1, 1, 2013, 1},
-	{2013, 1, 6, 2013, 1}, {2013, 1, 7, 2013, 2}, {2013, 12, 22, 2013, 51},
-	{2013, 12, 23, 2013, 52}, {2013, 12, 29, 2013, 52}, {2013, 12, 30, 2014, 1},
-	{2014, 1, 1, 2014, 1}, {2014, 1, 5, 2014, 1}, {2014, 1, 6, 2014, 2},
-	{2015, 1, 1, 2015, 1}, {2016, 1, 1, 2015, 53}, {2017, 1, 1, 2016, 52},
-	{2018, 1, 1, 2018, 1}, {2019, 1, 1, 2019, 1}, {2020, 1, 1, 2020, 1},
-	{2021, 1, 1, 2020, 53}, {2022, 1, 1, 2021, 52}, {2023, 1, 1, 2022, 52},
-	{2024, 1, 1, 2024, 1}, {2025, 1, 1, 2025, 1}, {2026, 1, 1, 2026, 1},
-	{2027, 1, 1, 2026, 53}, {2028, 1, 1, 2027, 52}, {2029, 1, 1, 2029, 1},
-	{2030, 1, 1, 2030, 1}, {2031, 1, 1, 2031, 1}, {2032, 1, 1, 2032, 1},
-	{2033, 1, 1, 2032, 53}, {2034, 1, 1, 2033, 52}, {2035, 1, 1, 2035, 1},
-	{2036, 1, 1, 2036, 1}, {2037, 1, 1, 2037, 1}, {2038, 1, 1, 2037, 53},
-	{2039, 1, 1, 2038, 52}, {2040, 1, 1, 2039, 52},
-}
-
-func TestISOWeek(t *testing.T) {
-	// Selected dates and corner cases
-	for _, wt := range isoWeekTests {
-		dt := Date(wt.year, Month(wt.month), wt.day, 0, 0, 0, 0, UTC)
-		y, w := dt.ISOWeek()
-		if w != wt.wex || y != wt.yex {
-			t.Errorf("got %d/%d; expected %d/%d for %d-%02d-%02d",
-				y, w, wt.yex, wt.wex, wt.year, wt.month, wt.day)
-		}
-	}
-
-	// The only real invariant: Jan 04 is in week 1
-	for year := 1950; year < 2100; year++ {
-		if y, w := Date(year, January, 4, 0, 0, 0, 0, UTC).ISOWeek(); y != year || w != 1 {
-			t.Errorf("got %d/%d; expected %d/1 for Jan 04", y, w, year)
-		}
-	}
-}
-
-type YearDayTest struct {
-	year, month, day int
-	yday             int
-}
-
-// Test YearDay in several different scenarios
-// and corner cases
-var yearDayTests = []YearDayTest{
-	// Non-leap-year tests
-	{2007, 1, 1, 1},
-	{2007, 1, 15, 15},
-	{2007, 2, 1, 32},
-	{2007, 2, 15, 46},
-	{2007, 3, 1, 60},
-	{2007, 3, 15, 74},
-	{2007, 4, 1, 91},
-	{2007, 12, 31, 365},
-
-	// Leap-year tests
-	{2008, 1, 1, 1},
-	{2008, 1, 15, 15},
-	{2008, 2, 1, 32},
-	{2008, 2, 15, 46},
-	{2008, 3, 1, 61},
-	{2008, 3, 15, 75},
-	{2008, 4, 1, 92},
-	{2008, 12, 31, 366},
-
-	// Looks like leap-year (but isn't) tests
-	{1900, 1, 1, 1},
-	{1900, 1, 15, 15},
-	{1900, 2, 1, 32},
-	{1900, 2, 15, 46},
-	{1900, 3, 1, 60},
-	{1900, 3, 15, 74},
-	{1900, 4, 1, 91},
-	{1900, 12, 31, 365},
-
-	// Year one tests (non-leap)
-	{1, 1, 1, 1},
-	{1, 1, 15, 15},
-	{1, 2, 1, 32},
-	{1, 2, 15, 46},
-	{1, 3, 1, 60},
-	{1, 3, 15, 74},
-	{1, 4, 1, 91},
-	{1, 12, 31, 365},
-
-	// Year minus one tests (non-leap)
-	{-1, 1, 1, 1},
-	{-1, 1, 15, 15},
-	{-1, 2, 1, 32},
-	{-1, 2, 15, 46},
-	{-1, 3, 1, 60},
-	{-1, 3, 15, 74},
-	{-1, 4, 1, 91},
-	{-1, 12, 31, 365},
-
-	// 400 BC tests (leap-year)
-	{-400, 1, 1, 1},
-	{-400, 1, 15, 15},
-	{-400, 2, 1, 32},
-	{-400, 2, 15, 46},
-	{-400, 3, 1, 61},
-	{-400, 3, 15, 75},
-	{-400, 4, 1, 92},
-	{-400, 12, 31, 366},
-
-	// Special Cases
-
-	// Gregorian calendar change (no effect)
-	{1582, 10, 4, 277},
-	{1582, 10, 15, 288},
-}
-
-// Check to see if YearDay is location sensitive
-var yearDayLocations = []*Location{
-	FixedZone("UTC-8", -8*60*60),
-	FixedZone("UTC-4", -4*60*60),
-	UTC,
-	FixedZone("UTC+4", 4*60*60),
-	FixedZone("UTC+8", 8*60*60),
-}
-
-func TestYearDay(t *testing.T) {
-	for _, loc := range yearDayLocations {
-		for _, ydt := range yearDayTests {
-			dt := Date(ydt.year, Month(ydt.month), ydt.day, 0, 0, 0, 0, loc)
-			yday := dt.YearDay()
-			if yday != ydt.yday {
-				t.Errorf("got %d, expected %d for %d-%02d-%02d in %v",
-					yday, ydt.yday, ydt.year, ydt.month, ydt.day, loc)
-			}
-		}
-	}
-}
-
-var durationTests = []struct {
-	str string
-	d   Duration
-}{
-	{"0", 0},
-	{"1ns", 1 * Nanosecond},
-	{"1.1us", 1100 * Nanosecond},
-	{"2.2ms", 2200 * Microsecond},
-	{"3.3s", 3300 * Millisecond},
-	{"4m5s", 4*Minute + 5*Second},
-	{"4m5.001s", 4*Minute + 5001*Millisecond},
-	{"5h6m7.001s", 5*Hour + 6*Minute + 7001*Millisecond},
-	{"8m0.000000001s", 8*Minute + 1*Nanosecond},
-	{"2562047h47m16.854775807s", 1<<63 - 1},
-	{"-2562047h47m16.854775808s", -1 << 63},
-}
-
-func TestDurationString(t *testing.T) {
-	for _, tt := range durationTests {
-		if str := tt.d.String(); str != tt.str {
-			t.Errorf("Duration(%d).String() = %s, want %s", int64(tt.d), str, tt.str)
-		}
-		if tt.d > 0 {
-			if str := (-tt.d).String(); str != "-"+tt.str {
-				t.Errorf("Duration(%d).String() = %s, want %s", int64(-tt.d), str, "-"+tt.str)
-			}
-		}
-	}
-}
-
-var dateTests = []struct {
-	year, month, day, hour, min, sec, nsec int
-	z                                      *Location
-	unix                                   int64
-}{
-	{2011, 11, 6, 1, 0, 0, 0, Local, 1320566400},   // 1:00:00 PDT
-	{2011, 11, 6, 1, 59, 59, 0, Local, 1320569999}, // 1:59:59 PDT
-	{2011, 11, 6, 2, 0, 0, 0, Local, 1320573600},   // 2:00:00 PST
-
-	{2011, 3, 13, 1, 0, 0, 0, Local, 1300006800},   // 1:00:00 PST
-	{2011, 3, 13, 1, 59, 59, 0, Local, 1300010399}, // 1:59:59 PST
-	{2011, 3, 13, 3, 0, 0, 0, Local, 1300010400},   // 3:00:00 PDT
-	{2011, 3, 13, 2, 30, 0, 0, Local, 1300008600},  // 2:30:00 PDT ≡ 1:30 PST
-
-	// Many names for Fri Nov 18 7:56:35 PST 2011
-	{2011, 11, 18, 7, 56, 35, 0, Local, 1321631795},                 // Nov 18 7:56:35
-	{2011, 11, 19, -17, 56, 35, 0, Local, 1321631795},               // Nov 19 -17:56:35
-	{2011, 11, 17, 31, 56, 35, 0, Local, 1321631795},                // Nov 17 31:56:35
-	{2011, 11, 18, 6, 116, 35, 0, Local, 1321631795},                // Nov 18 6:116:35
-	{2011, 10, 49, 7, 56, 35, 0, Local, 1321631795},                 // Oct 49 7:56:35
-	{2011, 11, 18, 7, 55, 95, 0, Local, 1321631795},                 // Nov 18 7:55:95
-	{2011, 11, 18, 7, 56, 34, 1e9, Local, 1321631795},               // Nov 18 7:56:34 + 10⁹ns
-	{2011, 12, -12, 7, 56, 35, 0, Local, 1321631795},                // Dec -21 7:56:35
-	{2012, 1, -43, 7, 56, 35, 0, Local, 1321631795},                 // Jan -52 7:56:35 2012
-	{2012, int(January - 2), 18, 7, 56, 35, 0, Local, 1321631795},   // (Jan-2) 18 7:56:35 2012
-	{2010, int(December + 11), 18, 7, 56, 35, 0, Local, 1321631795}, // (Dec+11) 18 7:56:35 2010
-}
-
-func TestDate(t *testing.T) {
-	for _, tt := range dateTests {
-		time := Date(tt.year, Month(tt.month), tt.day, tt.hour, tt.min, tt.sec, tt.nsec, tt.z)
-		want := Unix(tt.unix, 0)
-		if !time.Equal(want) {
-			t.Errorf("Date(%d, %d, %d, %d, %d, %d, %d, %s) = %v, want %v",
-				tt.year, tt.month, tt.day, tt.hour, tt.min, tt.sec, tt.nsec, tt.z,
-				time, want)
-		}
-	}
-}
-
-// Several ways of getting from
-// Fri Nov 18 7:56:35 PST 2011
-// to
-// Thu Mar 19 7:56:35 PST 2016
-var addDateTests = []struct {
-	years, months, days int
-}{
-	{4, 4, 1},
-	{3, 16, 1},
-	{3, 15, 30},
-	{5, -6, -18 - 30 - 12},
-}
-
-func TestAddDate(t *testing.T) {
-	t0 := Date(2011, 11, 18, 7, 56, 35, 0, UTC)
-	t1 := Date(2016, 3, 19, 7, 56, 35, 0, UTC)
-	for _, at := range addDateTests {
-		time := t0.AddDate(at.years, at.months, at.days)
-		if !time.Equal(t1) {
-			t.Errorf("AddDate(%d, %d, %d) = %v, want %v",
-				at.years, at.months, at.days,
-				time, t1)
-		}
-	}
-}
-
-var daysInTests = []struct {
-	year, month, di int
-}{
-	{2011, 1, 31},  // January, first month, 31 days
-	{2011, 2, 28},  // February, non-leap year, 28 days
-	{2012, 2, 29},  // February, leap year, 29 days
-	{2011, 6, 30},  // June, 30 days
-	{2011, 12, 31}, // December, last month, 31 days
-}
-
-func TestDaysIn(t *testing.T) {
-	// The daysIn function is not exported.
-	// Test the daysIn function via the `var DaysIn = daysIn`
-	// statement in the internal_test.go file.
-	for _, tt := range daysInTests {
-		di := DaysIn(Month(tt.month), tt.year)
-		if di != tt.di {
-			t.Errorf("got %d; expected %d for %d-%02d",
-				di, tt.di, tt.year, tt.month)
-		}
-	}
-}
-
-func TestAddToExactSecond(t *testing.T) {
-	// Add an amount to the current time to round it up to the next exact second.
-	// This test checks that the nsec field still lies within the range [0, 999999999].
-	t1 := Now()
-	t2 := t1.Add(Second - Duration(t1.Nanosecond()))
-	sec := (t1.Second() + 1) % 60
-	if t2.Second() != sec || t2.Nanosecond() != 0 {
-		t.Errorf("sec = %d, nsec = %d, want sec = %d, nsec = 0", t2.Second(), t2.Nanosecond(), sec)
-	}
-}
-
-func equalTimeAndZone(a, b Time) bool {
-	aname, aoffset := a.Zone()
-	bname, boffset := b.Zone()
-	return a.Equal(b) && aoffset == boffset && aname == bname
-}
-
-var gobTests = []Time{
-	Date(0, 1, 2, 3, 4, 5, 6, UTC),
-	Date(7, 8, 9, 10, 11, 12, 13, FixedZone("", 0)),
-	Unix(81985467080890095, 0x76543210), // Time.sec: 0x0123456789ABCDEF
-	{}, // nil location
-	Date(1, 2, 3, 4, 5, 6, 7, FixedZone("", 32767*60)),
-	Date(1, 2, 3, 4, 5, 6, 7, FixedZone("", -32768*60)),
-}
-
-func TestTimeGob(t *testing.T) {
-	var b bytes.Buffer
-	enc := gob.NewEncoder(&b)
-	dec := gob.NewDecoder(&b)
-	for _, tt := range gobTests {
-		var gobtt Time
-		if err := enc.Encode(&tt); err != nil {
-			t.Errorf("%v gob Encode error = %q, want nil", tt, err)
-		} else if err := dec.Decode(&gobtt); err != nil {
-			t.Errorf("%v gob Decode error = %q, want nil", tt, err)
-		} else if !equalTimeAndZone(gobtt, tt) {
-			t.Errorf("Decoded time = %v, want %v", gobtt, tt)
-		}
-		b.Reset()
-	}
-}
-
-var invalidEncodingTests = []struct {
-	bytes []byte
-	want  string
-}{
-	{[]byte{}, "Time.UnmarshalBinary: no data"},
-	{[]byte{0, 2, 3}, "Time.UnmarshalBinary: unsupported version"},
-	{[]byte{1, 2, 3}, "Time.UnmarshalBinary: invalid length"},
-}
-
-func TestInvalidTimeGob(t *testing.T) {
-	for _, tt := range invalidEncodingTests {
-		var ignored Time
-		err := ignored.GobDecode(tt.bytes)
-		if err == nil || err.Error() != tt.want {
-			t.Errorf("time.GobDecode(%#v) error = %v, want %v", tt.bytes, err, tt.want)
-		}
-		err = ignored.UnmarshalBinary(tt.bytes)
-		if err == nil || err.Error() != tt.want {
-			t.Errorf("time.UnmarshalBinary(%#v) error = %v, want %v", tt.bytes, err, tt.want)
-		}
-	}
-}
-
-var notEncodableTimes = []struct {
-	time Time
-	want string
-}{
-	{Date(0, 1, 2, 3, 4, 5, 6, FixedZone("", 1)), "Time.MarshalBinary: zone offset has fractional minute"},
-	{Date(0, 1, 2, 3, 4, 5, 6, FixedZone("", -1*60)), "Time.MarshalBinary: unexpected zone offset"},
-	{Date(0, 1, 2, 3, 4, 5, 6, FixedZone("", -32769*60)), "Time.MarshalBinary: unexpected zone offset"},
-	{Date(0, 1, 2, 3, 4, 5, 6, FixedZone("", 32768*60)), "Time.MarshalBinary: unexpected zone offset"},
-}
-
-func TestNotGobEncodableTime(t *testing.T) {
-	for _, tt := range notEncodableTimes {
-		_, err := tt.time.GobEncode()
-		if err == nil || err.Error() != tt.want {
-			t.Errorf("%v GobEncode error = %v, want %v", tt.time, err, tt.want)
-		}
-		_, err = tt.time.MarshalBinary()
-		if err == nil || err.Error() != tt.want {
-			t.Errorf("%v MarshalBinary error = %v, want %v", tt.time, err, tt.want)
-		}
-	}
-}
-
-var jsonTests = []struct {
-	time Time
-	json string
-}{
-	{Date(9999, 4, 12, 23, 20, 50, 520*1e6, UTC), `"9999-04-12T23:20:50.52Z"`},
-	{Date(1996, 12, 19, 16, 39, 57, 0, Local), `"1996-12-19T16:39:57-08:00"`},
-	{Date(0, 1, 1, 0, 0, 0, 1, FixedZone("", 1*60)), `"0000-01-01T00:00:00.000000001+00:01"`},
-}
-
-func TestTimeJSON(t *testing.T) {
-	for _, tt := range jsonTests {
-		var jsonTime Time
-
-		if jsonBytes, err := json.Marshal(tt.time); err != nil {
-			t.Errorf("%v json.Marshal error = %v, want nil", tt.time, err)
-		} else if string(jsonBytes) != tt.json {
-			t.Errorf("%v JSON = %#q, want %#q", tt.time, string(jsonBytes), tt.json)
-		} else if err = json.Unmarshal(jsonBytes, &jsonTime); err != nil {
-			t.Errorf("%v json.Unmarshal error = %v, want nil", tt.time, err)
-		} else if !equalTimeAndZone(jsonTime, tt.time) {
-			t.Errorf("Unmarshaled time = %v, want %v", jsonTime, tt.time)
-		}
-	}
-}
-
-func TestInvalidTimeJSON(t *testing.T) {
-	var tt Time
-	err := json.Unmarshal([]byte(`{"now is the time":"buddy"}`), &tt)
-	_, isParseErr := err.(*ParseError)
-	if !isParseErr {
-		t.Errorf("expected *time.ParseError unmarshaling JSON, got %v", err)
-	}
-}
-
-var notJSONEncodableTimes = []struct {
-	time Time
-	want string
-}{
-	{Date(10000, 1, 1, 0, 0, 0, 0, UTC), "Time.MarshalJSON: year outside of range [0,9999]"},
-	{Date(-1, 1, 1, 0, 0, 0, 0, UTC), "Time.MarshalJSON: year outside of range [0,9999]"},
-}
-
-func TestNotJSONEncodableTime(t *testing.T) {
-	for _, tt := range notJSONEncodableTimes {
-		_, err := tt.time.MarshalJSON()
-		if err == nil || err.Error() != tt.want {
-			t.Errorf("%v MarshalJSON error = %v, want %v", tt.time, err, tt.want)
-		}
-	}
-}
-
-var parseDurationTests = []struct {
-	in   string
-	ok   bool
-	want Duration
-}{
-	// simple
-	{"0", true, 0},
-	{"5s", true, 5 * Second},
-	{"30s", true, 30 * Second},
-	{"1478s", true, 1478 * Second},
-	// sign
-	{"-5s", true, -5 * Second},
-	{"+5s", true, 5 * Second},
-	{"-0", true, 0},
-	{"+0", true, 0},
-	// decimal
-	{"5.0s", true, 5 * Second},
-	{"5.6s", true, 5*Second + 600*Millisecond},
-	{"5.s", true, 5 * Second},
-	{".5s", true, 500 * Millisecond},
-	{"1.0s", true, 1 * Second},
-	{"1.00s", true, 1 * Second},
-	{"1.004s", true, 1*Second + 4*Millisecond},
-	{"1.0040s", true, 1*Second + 4*Millisecond},
-	{"100.00100s", true, 100*Second + 1*Millisecond},
-	// different units
-	{"10ns", true, 10 * Nanosecond},
-	{"11us", true, 11 * Microsecond},
-	{"12µs", true, 12 * Microsecond}, // U+00B5
-	{"12μs", true, 12 * Microsecond}, // U+03BC
-	{"13ms", true, 13 * Millisecond},
-	{"14s", true, 14 * Second},
-	{"15m", true, 15 * Minute},
-	{"16h", true, 16 * Hour},
-	// composite durations
-	{"3h30m", true, 3*Hour + 30*Minute},
-	{"10.5s4m", true, 4*Minute + 10*Second + 500*Millisecond},
-	{"-2m3.4s", true, -(2*Minute + 3*Second + 400*Millisecond)},
-	{"1h2m3s4ms5us6ns", true, 1*Hour + 2*Minute + 3*Second + 4*Millisecond + 5*Microsecond + 6*Nanosecond},
-	{"39h9m14.425s", true, 39*Hour + 9*Minute + 14*Second + 425*Millisecond},
-	// large value
-	{"52763797000ns", true, 52763797000 * Nanosecond},
-	// more than 9 digits after decimal point, see http://golang.org/issue/6617
-	{"0.3333333333333333333h", true, 20 * Minute},
-
-	// errors
-	{"", false, 0},
-	{"3", false, 0},
-	{"-", false, 0},
-	{"s", false, 0},
-	{".", false, 0},
-	{"-.", false, 0},
-	{".s", false, 0},
-	{"+.s", false, 0},
-	{"3000000h", false, 0}, // overflow
-}
-
-func TestParseDuration(t *testing.T) {
-	for _, tc := range parseDurationTests {
-		d, err := ParseDuration(tc.in)
-		if tc.ok && (err != nil || d != tc.want) {
-			t.Errorf("ParseDuration(%q) = %v, %v, want %v, nil", tc.in, d, err, tc.want)
-		} else if !tc.ok && err == nil {
-			t.Errorf("ParseDuration(%q) = _, nil, want _, non-nil", tc.in)
-		}
-	}
-}
-
-func TestParseDurationRoundTrip(t *testing.T) {
-	for i := 0; i < 100; i++ {
-		// Resolutions finer than milliseconds will result in
-		// imprecise round-trips.
-		d0 := Duration(rand.Int31()) * Millisecond
-		s := d0.String()
-		d1, err := ParseDuration(s)
-		if err != nil || d0 != d1 {
-			t.Errorf("round-trip failed: %d => %q => %d, %v", d0, s, d1, err)
-		}
-	}
-}
-
-// golang.org/issue/4622
-func TestLocationRace(t *testing.T) {
-	ResetLocalOnceForTest() // reset the Once to trigger the race
-
-	c := make(chan string, 1)
-	go func() {
-		c <- Now().String()
-	}()
-	Now().String()
-	<-c
-	Sleep(100 * Millisecond)
-
-	// Back to Los Angeles for subsequent tests:
-	ForceUSPacificForTesting()
-}
-
-var (
-	t Time
-	u int64
-)
-
-var mallocTest = []struct {
-	count int
-	desc  string
-	fn    func()
-}{
-	{0, `time.Now()`, func() { t = Now() }},
-	{0, `time.Now().UnixNano()`, func() { u = Now().UnixNano() }},
-}
-
-func TestCountMallocs(t *testing.T) {
-	if testing.Short() {
-		t.Skip("skipping malloc count in short mode")
-	}
-	if runtime.GOMAXPROCS(0) > 1 {
-		t.Skip("skipping; GOMAXPROCS>1")
-	}
-	for _, mt := range mallocTest {
-		allocs := int(testing.AllocsPerRun(100, mt.fn))
-		if allocs > mt.count {
-			t.Errorf("%s: %d allocs, want %d", mt.desc, allocs, mt.count)
-		}
-	}
-}
-
-func TestLoadFixed(t *testing.T) {
-	// Issue 4064: handle locations without any zone transitions.
-	loc, err := LoadLocation("Etc/GMT+1")
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	// The tzdata name Etc/GMT+1 uses "east is negative",
-	// but Go and most other systems use "east is positive".
-	// So GMT+1 corresponds to -3600 in the Go zone, not +3600.
-	name, offset := Now().In(loc).Zone()
-	if name != "GMT+1" || offset != -1*60*60 {
-		t.Errorf("Now().In(loc).Zone() = %q, %d, want %q, %d", name, offset, "GMT+1", -1*60*60)
-	}
-}
-
-const (
-	minDuration Duration = -1 << 63
-	maxDuration Duration = 1<<63 - 1
-)
-
-var subTests = []struct {
-	t Time
-	u Time
-	d Duration
-}{
-	{Time{}, Time{}, Duration(0)},
-	{Date(2009, 11, 23, 0, 0, 0, 1, UTC), Date(2009, 11, 23, 0, 0, 0, 0, UTC), Duration(1)},
-	{Date(2009, 11, 23, 0, 0, 0, 0, UTC), Date(2009, 11, 24, 0, 0, 0, 0, UTC), -24 * Hour},
-	{Date(2009, 11, 24, 0, 0, 0, 0, UTC), Date(2009, 11, 23, 0, 0, 0, 0, UTC), 24 * Hour},
-	{Date(-2009, 11, 24, 0, 0, 0, 0, UTC), Date(-2009, 11, 23, 0, 0, 0, 0, UTC), 24 * Hour},
-	{Time{}, Date(2109, 11, 23, 0, 0, 0, 0, UTC), Duration(minDuration)},
-	{Date(2109, 11, 23, 0, 0, 0, 0, UTC), Time{}, Duration(maxDuration)},
-	{Time{}, Date(-2109, 11, 23, 0, 0, 0, 0, UTC), Duration(maxDuration)},
-	{Date(-2109, 11, 23, 0, 0, 0, 0, UTC), Time{}, Duration(minDuration)},
-	{Date(2290, 1, 1, 0, 0, 0, 0, UTC), Date(2000, 1, 1, 0, 0, 0, 0, UTC), 290*365*24*Hour + 71*24*Hour},
-	{Date(2300, 1, 1, 0, 0, 0, 0, UTC), Date(2000, 1, 1, 0, 0, 0, 0, UTC), Duration(maxDuration)},
-	{Date(2000, 1, 1, 0, 0, 0, 0, UTC), Date(2290, 1, 1, 0, 0, 0, 0, UTC), -290*365*24*Hour - 71*24*Hour},
-	{Date(2000, 1, 1, 0, 0, 0, 0, UTC), Date(2300, 1, 1, 0, 0, 0, 0, UTC), Duration(minDuration)},
-}
-
-func TestSub(t *testing.T) {
-	for i, st := range subTests {
-		got := st.t.Sub(st.u)
-		if got != st.d {
-			t.Errorf("#%d: Sub(%v, %v): got %v; want %v", i, st.t, st.u, got, st.d)
-		}
-	}
-}
-
-var nsDurationTests = []struct {
-	d    Duration
-	want int64
-}{
-	{Duration(-1000), -1000},
-	{Duration(-1), -1},
-	{Duration(1), 1},
-	{Duration(1000), 1000},
-}
-
-func TestDurationNanoseconds(t *testing.T) {
-	for _, tt := range nsDurationTests {
-		if got := tt.d.Nanoseconds(); got != tt.want {
-			t.Errorf("d.Nanoseconds() = %d; want: %d", got, tt.want)
-		}
-	}
-}
-
-var minDurationTests = []struct {
-	d    Duration
-	want float64
-}{
-	{Duration(-60000000000), -1},
-	{Duration(-1), -1 / 60e9},
-	{Duration(1), 1 / 60e9},
-	{Duration(60000000000), 1},
-}
-
-func TestDurationMinutes(t *testing.T) {
-	for _, tt := range minDurationTests {
-		if got := tt.d.Minutes(); got != tt.want {
-			t.Errorf("d.Minutes() = %g; want: %g", got, tt.want)
-		}
-	}
-}
-
-var hourDurationTests = []struct {
-	d    Duration
-	want float64
-}{
-	{Duration(-3600000000000), -1},
-	{Duration(-1), -1 / 3600e9},
-	{Duration(1), 1 / 3600e9},
-	{Duration(3600000000000), 1},
-}
-
-func TestDurationHours(t *testing.T) {
-	for _, tt := range hourDurationTests {
-		if got := tt.d.Hours(); got != tt.want {
-			t.Errorf("d.Hours() = %g; want: %g", got, tt.want)
-		}
-	}
-}
-
-func BenchmarkNow(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		t = Now()
-	}
-}
-
-func BenchmarkNowUnixNano(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		u = Now().UnixNano()
-	}
-}
-
-func BenchmarkFormat(b *testing.B) {
-	t := Unix(1265346057, 0)
-	for i := 0; i < b.N; i++ {
-		t.Format("Mon Jan  2 15:04:05 2006")
-	}
-}
-
-func BenchmarkFormatNow(b *testing.B) {
-	// Like BenchmarkFormat, but easier, because the time zone
-	// lookup cache is optimized for the present.
-	t := Now()
-	for i := 0; i < b.N; i++ {
-		t.Format("Mon Jan  2 15:04:05 2006")
-	}
-}
-
-func BenchmarkParse(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		Parse(ANSIC, "Mon Jan  2 15:04:05 2006")
-	}
-}
-
-func BenchmarkHour(b *testing.B) {
-	t := Now()
-	for i := 0; i < b.N; i++ {
-		_ = t.Hour()
-	}
-}
-
-func BenchmarkSecond(b *testing.B) {
-	t := Now()
-	for i := 0; i < b.N; i++ {
-		_ = t.Second()
-	}
-}
-
-func BenchmarkYear(b *testing.B) {
-	t := Now()
-	for i := 0; i < b.N; i++ {
-		_ = t.Year()
-	}
-}
-
-func BenchmarkDay(b *testing.B) {
-	t := Now()
-	for i := 0; i < b.N; i++ {
-		_ = t.Day()
-	}
-}
diff --git a/src/pkg/time/zoneinfo_abbrs_windows.go b/src/pkg/time/zoneinfo_abbrs_windows.go
deleted file mode 100644
index 8033437..0000000
--- a/src/pkg/time/zoneinfo_abbrs_windows.go
+++ /dev/null
@@ -1,115 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// generated by genzabbrs.go from
-// http://unicode.org/cldr/data/common/supplemental/windowsZones.xml
-
-package time
-
-type abbr struct {
-	std string
-	dst string
-}
-
-var abbrs = map[string]abbr{
-	"Egypt Standard Time":             {"EET", "EET"},    // Africa/Cairo
-	"Morocco Standard Time":           {"WET", "WEST"},   // Africa/Casablanca
-	"South Africa Standard Time":      {"SAST", "SAST"},  // Africa/Johannesburg
-	"W. Central Africa Standard Time": {"WAT", "WAT"},    // Africa/Lagos
-	"E. Africa Standard Time":         {"EAT", "EAT"},    // Africa/Nairobi
-	"Namibia Standard Time":           {"WAT", "WAST"},   // Africa/Windhoek
-	"Alaskan Standard Time":           {"AKST", "AKDT"},  // America/Anchorage
-	"Paraguay Standard Time":          {"PYT", "PYST"},   // America/Asuncion
-	"Bahia Standard Time":             {"BRT", "BRST"},   // America/Bahia
-	"SA Pacific Standard Time":        {"COT", "COT"},    // America/Bogota
-	"Argentina Standard Time":         {"ART", "ART"},    // America/Buenos_Aires
-	"Venezuela Standard Time":         {"VET", "VET"},    // America/Caracas
-	"SA Eastern Standard Time":        {"GFT", "GFT"},    // America/Cayenne
-	"Central Standard Time":           {"CST", "CDT"},    // America/Chicago
-	"Mountain Standard Time (Mexico)": {"MST", "MDT"},    // America/Chihuahua
-	"Central Brazilian Standard Time": {"AMT", "AMST"},   // America/Cuiaba
-	"Mountain Standard Time":          {"MST", "MDT"},    // America/Denver
-	"Greenland Standard Time":         {"WGT", "WGST"},   // America/Godthab
-	"Central America Standard Time":   {"CST", "CST"},    // America/Guatemala
-	"Atlantic Standard Time":          {"AST", "ADT"},    // America/Halifax
-	"US Eastern Standard Time":        {"EST", "EDT"},    // America/Indianapolis
-	"SA Western Standard Time":        {"BOT", "BOT"},    // America/La_Paz
-	"Pacific Standard Time":           {"PST", "PDT"},    // America/Los_Angeles
-	"Central Standard Time (Mexico)":  {"CST", "CDT"},    // America/Mexico_City
-	"Montevideo Standard Time":        {"UYT", "UYST"},   // America/Montevideo
-	"Eastern Standard Time":           {"EST", "EDT"},    // America/New_York
-	"US Mountain Standard Time":       {"MST", "MST"},    // America/Phoenix
-	"Canada Central Standard Time":    {"CST", "CST"},    // America/Regina
-	"Pacific Standard Time (Mexico)":  {"PST", "PDT"},    // America/Santa_Isabel
-	"Pacific SA Standard Time":        {"CLT", "CLST"},   // America/Santiago
-	"E. South America Standard Time":  {"BRT", "BRST"},   // America/Sao_Paulo
-	"Newfoundland Standard Time":      {"NST", "NDT"},    // America/St_Johns
-	"Central Asia Standard Time":      {"ALMT", "ALMT"},  // Asia/Almaty
-	"Jordan Standard Time":            {"EET", "EEST"},   // Asia/Amman
-	"Arabic Standard Time":            {"AST", "AST"},    // Asia/Baghdad
-	"Azerbaijan Standard Time":        {"AZT", "AZST"},   // Asia/Baku
-	"SE Asia Standard Time":           {"ICT", "ICT"},    // Asia/Bangkok
-	"Middle East Standard Time":       {"EET", "EEST"},   // Asia/Beirut
-	"India Standard Time":             {"IST", "IST"},    // Asia/Calcutta
-	"Sri Lanka Standard Time":         {"IST", "IST"},    // Asia/Colombo
-	"Syria Standard Time":             {"EET", "EEST"},   // Asia/Damascus
-	"Bangladesh Standard Time":        {"BDT", "BDT"},    // Asia/Dhaka
-	"Arabian Standard Time":           {"GST", "GST"},    // Asia/Dubai
-	"North Asia East Standard Time":   {"IRKT", "IRKT"},  // Asia/Irkutsk
-	"Israel Standard Time":            {"IST", "IDT"},    // Asia/Jerusalem
-	"Afghanistan Standard Time":       {"AFT", "AFT"},    // Asia/Kabul
-	"Pakistan Standard Time":          {"PKT", "PKT"},    // Asia/Karachi
-	"Nepal Standard Time":             {"NPT", "NPT"},    // Asia/Katmandu
-	"North Asia Standard Time":        {"KRAT", "KRAT"},  // Asia/Krasnoyarsk
-	"Magadan Standard Time":           {"MAGT", "MAGT"},  // Asia/Magadan
-	"E. Europe Standard Time":         {"EET", "EEST"},   // Asia/Nicosia
-	"N. Central Asia Standard Time":   {"NOVT", "NOVT"},  // Asia/Novosibirsk
-	"Myanmar Standard Time":           {"MMT", "MMT"},    // Asia/Rangoon
-	"Arab Standard Time":              {"AST", "AST"},    // Asia/Riyadh
-	"Korea Standard Time":             {"KST", "KST"},    // Asia/Seoul
-	"China Standard Time":             {"CST", "CST"},    // Asia/Shanghai
-	"Singapore Standard Time":         {"SGT", "SGT"},    // Asia/Singapore
-	"Taipei Standard Time":            {"CST", "CST"},    // Asia/Taipei
-	"West Asia Standard Time":         {"UZT", "UZT"},    // Asia/Tashkent
-	"Georgian Standard Time":          {"GET", "GET"},    // Asia/Tbilisi
-	"Iran Standard Time":              {"IRST", "IRDT"},  // Asia/Tehran
-	"Tokyo Standard Time":             {"JST", "JST"},    // Asia/Tokyo
-	"Ulaanbaatar Standard Time":       {"ULAT", "ULAT"},  // Asia/Ulaanbaatar
-	"Vladivostok Standard Time":       {"VLAT", "VLAT"},  // Asia/Vladivostok
-	"Yakutsk Standard Time":           {"YAKT", "YAKT"},  // Asia/Yakutsk
-	"Ekaterinburg Standard Time":      {"YEKT", "YEKT"},  // Asia/Yekaterinburg
-	"Caucasus Standard Time":          {"AMT", "AMT"},    // Asia/Yerevan
-	"Azores Standard Time":            {"AZOT", "AZOST"}, // Atlantic/Azores
-	"Cape Verde Standard Time":        {"CVT", "CVT"},    // Atlantic/Cape_Verde
-	"Greenwich Standard Time":         {"GMT", "GMT"},    // Atlantic/Reykjavik
-	"Cen. Australia Standard Time":    {"CST", "CST"},    // Australia/Adelaide
-	"E. Australia Standard Time":      {"EST", "EST"},    // Australia/Brisbane
-	"AUS Central Standard Time":       {"CST", "CST"},    // Australia/Darwin
-	"Tasmania Standard Time":          {"EST", "EST"},    // Australia/Hobart
-	"W. Australia Standard Time":      {"WST", "WST"},    // Australia/Perth
-	"AUS Eastern Standard Time":       {"EST", "EST"},    // Australia/Sydney
-	"UTC":                            {"GMT", "GMT"},       // Etc/GMT
-	"UTC-11":                         {"GMT+11", "GMT+11"}, // Etc/GMT+11
-	"Dateline Standard Time":         {"GMT+12", "GMT+12"}, // Etc/GMT+12
-	"UTC-02":                         {"GMT+2", "GMT+2"},   // Etc/GMT+2
-	"UTC+12":                         {"GMT-12", "GMT-12"}, // Etc/GMT-12
-	"W. Europe Standard Time":        {"CET", "CEST"},      // Europe/Berlin
-	"GTB Standard Time":              {"EET", "EEST"},      // Europe/Bucharest
-	"Central Europe Standard Time":   {"CET", "CEST"},      // Europe/Budapest
-	"Turkey Standard Time":           {"EET", "EEST"},      // Europe/Istanbul
-	"Kaliningrad Standard Time":      {"FET", "FET"},       // Europe/Kaliningrad
-	"FLE Standard Time":              {"EET", "EEST"},      // Europe/Kiev
-	"GMT Standard Time":              {"GMT", "BST"},       // Europe/London
-	"Russian Standard Time":          {"MSK", "MSK"},       // Europe/Moscow
-	"Romance Standard Time":          {"CET", "CEST"},      // Europe/Paris
-	"Central European Standard Time": {"CET", "CEST"},      // Europe/Warsaw
-	"Mauritius Standard Time":        {"MUT", "MUT"},       // Indian/Mauritius
-	"Samoa Standard Time":            {"WST", "WST"},       // Pacific/Apia
-	"New Zealand Standard Time":      {"NZST", "NZDT"},     // Pacific/Auckland
-	"Fiji Standard Time":             {"FJT", "FJT"},       // Pacific/Fiji
-	"Central Pacific Standard Time":  {"SBT", "SBT"},       // Pacific/Guadalcanal
-	"Hawaiian Standard Time":         {"HST", "HST"},       // Pacific/Honolulu
-	"West Pacific Standard Time":     {"PGT", "PGT"},       // Pacific/Port_Moresby
-	"Tonga Standard Time":            {"TOT", "TOT"},       // Pacific/Tongatapu
-}
diff --git a/src/pkg/time/zoneinfo_windows.go b/src/pkg/time/zoneinfo_windows.go
deleted file mode 100644
index 6046743..0000000
--- a/src/pkg/time/zoneinfo_windows.go
+++ /dev/null
@@ -1,270 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package time
-
-import (
-	"errors"
-	"runtime"
-	"syscall"
-	"unsafe"
-)
-
-// TODO(rsc): Fall back to copy of zoneinfo files.
-
-// BUG(brainman,rsc): On Windows, the operating system does not provide complete
-// time zone information.
-// The implementation assumes that this year's rules for daylight savings
-// time apply to all previous and future years as well.
-
-// getKeyValue retrieves the string value kname associated with the open registry key kh.
-func getKeyValue(kh syscall.Handle, kname string) (string, error) {
-	var buf [50]uint16 // buf needs to be large enough to fit zone descriptions
-	var typ uint32
-	n := uint32(len(buf) * 2) // RegQueryValueEx's signature expects array of bytes, not uint16
-	p, _ := syscall.UTF16PtrFromString(kname)
-	if err := syscall.RegQueryValueEx(kh, p, nil, &typ, (*byte)(unsafe.Pointer(&buf[0])), &n); err != nil {
-		return "", err
-	}
-	if typ != syscall.REG_SZ { // null terminated strings only
-		return "", errors.New("Key is not string")
-	}
-	return syscall.UTF16ToString(buf[:]), nil
-}
-
-// matchZoneKey checks if stdname and dstname match the corresponding "Std"
-// and "Dlt" key values in the kname key stored under the open registry key zones.
-func matchZoneKey(zones syscall.Handle, kname string, stdname, dstname string) (matched bool, err2 error) {
-	var h syscall.Handle
-	p, _ := syscall.UTF16PtrFromString(kname)
-	if err := syscall.RegOpenKeyEx(zones, p, 0, syscall.KEY_READ, &h); err != nil {
-		return false, err
-	}
-	defer syscall.RegCloseKey(h)
-
-	s, err := getKeyValue(h, "Std")
-	if err != nil {
-		return false, err
-	}
-	if s != stdname {
-		return false, nil
-	}
-	s, err = getKeyValue(h, "Dlt")
-	if err != nil {
-		return false, err
-	}
-	if s != dstname && dstname != stdname {
-		return false, nil
-	}
-	return true, nil
-}
-
-// toEnglishName searches the registry for an English name of a time zone
-// whose zone names are stdname and dstname and returns the English name.
-func toEnglishName(stdname, dstname string) (string, error) {
-	var zones syscall.Handle
-	p, _ := syscall.UTF16PtrFromString(`SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones`)
-	if err := syscall.RegOpenKeyEx(syscall.HKEY_LOCAL_MACHINE, p, 0, syscall.KEY_READ, &zones); err != nil {
-		return "", err
-	}
-	defer syscall.RegCloseKey(zones)
-
-	var count uint32
-	if err := syscall.RegQueryInfoKey(zones, nil, nil, nil, &count, nil, nil, nil, nil, nil, nil, nil); err != nil {
-		return "", err
-	}
-
-	var buf [50]uint16 // buf needs to be large enough to fit zone descriptions
-	for i := uint32(0); i < count; i++ {
-		n := uint32(len(buf))
-		if syscall.RegEnumKeyEx(zones, i, &buf[0], &n, nil, nil, nil, nil) != nil {
-			continue
-		}
-		kname := syscall.UTF16ToString(buf[:])
-		matched, err := matchZoneKey(zones, kname, stdname, dstname)
-		if err == nil && matched {
-			return kname, nil
-		}
-	}
-	return "", errors.New(`English name for time zone "` + stdname + `" not found in registry`)
-}
-
-// extractCAPS extracts capital letters from description desc.
-func extractCAPS(desc string) string {
-	var short []rune
-	for _, c := range desc {
-		if 'A' <= c && c <= 'Z' {
-			short = append(short, rune(c))
-		}
-	}
-	return string(short)
-}
-
-// abbrev returns the abbreviations to use for the given zone z.
-func abbrev(z *syscall.Timezoneinformation) (std, dst string) {
-	stdName := syscall.UTF16ToString(z.StandardName[:])
-	a, ok := abbrs[stdName]
-	if !ok {
-		dstName := syscall.UTF16ToString(z.DaylightName[:])
-		// Perhaps stdName is not English. Try to convert it.
-		englishName, err := toEnglishName(stdName, dstName)
-		if err == nil {
-			a, ok = abbrs[englishName]
-			if ok {
-				return a.std, a.dst
-			}
-		}
-		// fallback to using capital letters
-		return extractCAPS(stdName), extractCAPS(dstName)
-	}
-	return a.std, a.dst
-}
-
-// pseudoUnix returns the pseudo-Unix time (seconds since Jan 1 1970 *LOCAL TIME*)
-// denoted by the system date+time d in the given year.
-// It is up to the caller to convert this local time into a UTC-based time.
-func pseudoUnix(year int, d *syscall.Systemtime) int64 {
-	// Windows specifies daylight savings information in "day in month" format:
-	// d.Month is month number (1-12)
-	// d.DayOfWeek is appropriate weekday (Sunday=0 to Saturday=6)
-	// d.Day is week within the month (1 to 5, where 5 is last week of the month)
-	// d.Hour, d.Minute and d.Second are absolute time
-	day := 1
-	t := Date(year, Month(d.Month), day, int(d.Hour), int(d.Minute), int(d.Second), 0, UTC)
-	i := int(d.DayOfWeek) - int(t.Weekday())
-	if i < 0 {
-		i += 7
-	}
-	day += i
-	if week := int(d.Day) - 1; week < 4 {
-		day += week * 7
-	} else {
-		// "Last" instance of the day.
-		day += 4 * 7
-		if day > daysIn(Month(d.Month), year) {
-			day -= 7
-		}
-	}
-	return t.sec + int64(day-1)*secondsPerDay + internalToUnix
-}
-
-func initLocalFromTZI(i *syscall.Timezoneinformation) {
-	l := &localLoc
-
-	nzone := 1
-	if i.StandardDate.Month > 0 {
-		nzone++
-	}
-	l.zone = make([]zone, nzone)
-
-	stdname, dstname := abbrev(i)
-
-	std := &l.zone[0]
-	std.name = stdname
-	if nzone == 1 {
-		// No daylight savings.
-		std.offset = -int(i.Bias) * 60
-		l.cacheStart = alpha
-		l.cacheEnd = omega
-		l.cacheZone = std
-		l.tx = make([]zoneTrans, 1)
-		l.tx[0].when = l.cacheStart
-		l.tx[0].index = 0
-		return
-	}
-
-	// StandardBias must be ignored if StandardDate is not set,
-	// so this computation is delayed until after the nzone==1
-	// return above.
-	std.offset = -int(i.Bias+i.StandardBias) * 60
-
-	dst := &l.zone[1]
-	dst.name = dstname
-	dst.offset = -int(i.Bias+i.DaylightBias) * 60
-	dst.isDST = true
-
-	// Arrange so that d0 is first transition date, d1 second,
-	// i0 is index of zone after first transition, i1 second.
-	d0 := &i.StandardDate
-	d1 := &i.DaylightDate
-	i0 := 0
-	i1 := 1
-	if d0.Month > d1.Month {
-		d0, d1 = d1, d0
-		i0, i1 = i1, i0
-	}
-
-	// 2 tx per year, 100 years on each side of this year
-	l.tx = make([]zoneTrans, 400)
-
-	t := Now().UTC()
-	year := t.Year()
-	txi := 0
-	for y := year - 100; y < year+100; y++ {
-		tx := &l.tx[txi]
-		tx.when = pseudoUnix(y, d0) - int64(l.zone[i1].offset)
-		tx.index = uint8(i0)
-		txi++
-
-		tx = &l.tx[txi]
-		tx.when = pseudoUnix(y, d1) - int64(l.zone[i0].offset)
-		tx.index = uint8(i1)
-		txi++
-	}
-}
-
-var usPacific = syscall.Timezoneinformation{
-	Bias: 8 * 60,
-	StandardName: [32]uint16{
-		'P', 'a', 'c', 'i', 'f', 'i', 'c', ' ', 'S', 't', 'a', 'n', 'd', 'a', 'r', 'd', ' ', 'T', 'i', 'm', 'e',
-	},
-	StandardDate: syscall.Systemtime{Month: 11, Day: 1, Hour: 2},
-	DaylightName: [32]uint16{
-		'P', 'a', 'c', 'i', 'f', 'i', 'c', ' ', 'D', 'a', 'y', 'l', 'i', 'g', 'h', 't', ' ', 'T', 'i', 'm', 'e',
-	},
-	DaylightDate: syscall.Systemtime{Month: 3, Day: 2, Hour: 2},
-	DaylightBias: -60,
-}
-
-var aus = syscall.Timezoneinformation{
-	Bias: -10 * 60,
-	StandardName: [32]uint16{
-		'A', 'U', 'S', ' ', 'E', 'a', 's', 't', 'e', 'r', 'n', ' ', 'S', 't', 'a', 'n', 'd', 'a', 'r', 'd', ' ', 'T', 'i', 'm', 'e',
-	},
-	StandardDate: syscall.Systemtime{Month: 4, Day: 1, Hour: 3},
-	DaylightName: [32]uint16{
-		'A', 'U', 'S', ' ', 'E', 'a', 's', 't', 'e', 'r', 'n', ' ', 'D', 'a', 'y', 'l', 'i', 'g', 'h', 't', ' ', 'T', 'i', 'm', 'e',
-	},
-	DaylightDate: syscall.Systemtime{Month: 10, Day: 1, Hour: 2},
-	DaylightBias: -60,
-}
-
-func initTestingZone() {
-	initLocalFromTZI(&usPacific)
-}
-
-func initAusTestingZone() {
-	initLocalFromTZI(&aus)
-}
-
-func initLocal() {
-	var i syscall.Timezoneinformation
-	if _, err := syscall.GetTimeZoneInformation(&i); err != nil {
-		localLoc.name = "UTC"
-		return
-	}
-	initLocalFromTZI(&i)
-}
-
-func loadLocation(name string) (*Location, error) {
-	if z, err := loadZoneFile(runtime.GOROOT()+`\lib\time\zoneinfo.zip`, name); err == nil {
-		z.name = name
-		return z, nil
-	}
-	return nil, errors.New("unknown time zone " + name)
-}
-
-func forceZipFileForTesting(zipOnly bool) {
-	// We only use the zip file anyway.
-}
diff --git a/src/pkg/unicode/Makefile b/src/pkg/unicode/Makefile
deleted file mode 100644
index 33b06ca..0000000
--- a/src/pkg/unicode/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-# Copyright 2009 The Go Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style
-# license that can be found in the LICENSE file.
-
-maketables: maketables.go
-	go build maketables.go
-
-tables:	maketables
-	./maketables --tables=all > tables.go
-	gofmt -w tables.go
-
-# Downloads from www.unicode.org, so not part
-# of standard test scripts.
-testtables: maketables
-	@echo '***' Be sure to make tables and go install first
-	./maketables -test
diff --git a/src/pkg/unicode/letter.go b/src/pkg/unicode/letter.go
deleted file mode 100644
index 977bd2b..0000000
--- a/src/pkg/unicode/letter.go
+++ /dev/null
@@ -1,354 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package unicode provides data and functions to test some properties of
-// Unicode code points.
-package unicode
-
-const (
-	MaxRune         = '\U0010FFFF' // Maximum valid Unicode code point.
-	ReplacementChar = '\uFFFD'     // Represents invalid code points.
-	MaxASCII        = '\u007F'     // maximum ASCII value.
-	MaxLatin1       = '\u00FF'     // maximum Latin-1 value.
-)
-
-// RangeTable defines a set of Unicode code points by listing the ranges of
-// code points within the set. The ranges are listed in two slices
-// to save space: a slice of 16-bit ranges and a slice of 32-bit ranges.
-// The two slices must be in sorted order and non-overlapping.
-// Also, R32 should contain only values >= 0x10000 (1<<16).
-type RangeTable struct {
-	R16         []Range16
-	R32         []Range32
-	LatinOffset int // number of entries in R16 with Hi <= MaxLatin1
-}
-
-// Range16 represents of a range of 16-bit Unicode code points.  The range runs from Lo to Hi
-// inclusive and has the specified stride.
-type Range16 struct {
-	Lo     uint16
-	Hi     uint16
-	Stride uint16
-}
-
-// Range32 represents of a range of Unicode code points and is used when one or
-// more of the values will not fit in 16 bits.  The range runs from Lo to Hi
-// inclusive and has the specified stride. Lo and Hi must always be >= 1<<16.
-type Range32 struct {
-	Lo     uint32
-	Hi     uint32
-	Stride uint32
-}
-
-// CaseRange represents a range of Unicode code points for simple (one
-// code point to one code point) case conversion.
-// The range runs from Lo to Hi inclusive, with a fixed stride of 1.  Deltas
-// are the number to add to the code point to reach the code point for a
-// different case for that character.  They may be negative.  If zero, it
-// means the character is in the corresponding case. There is a special
-// case representing sequences of alternating corresponding Upper and Lower
-// pairs.  It appears with a fixed Delta of
-//	{UpperLower, UpperLower, UpperLower}
-// The constant UpperLower has an otherwise impossible delta value.
-type CaseRange struct {
-	Lo    uint32
-	Hi    uint32
-	Delta d
-}
-
-// SpecialCase represents language-specific case mappings such as Turkish.
-// Methods of SpecialCase customize (by overriding) the standard mappings.
-type SpecialCase []CaseRange
-
-// BUG(r): There is no mechanism for full case folding, that is, for
-// characters that involve multiple runes in the input or output.
-
-// Indices into the Delta arrays inside CaseRanges for case mapping.
-const (
-	UpperCase = iota
-	LowerCase
-	TitleCase
-	MaxCase
-)
-
-type d [MaxCase]rune // to make the CaseRanges text shorter
-
-// If the Delta field of a CaseRange is UpperLower, it means
-// this CaseRange represents a sequence of the form (say)
-// Upper Lower Upper Lower.
-const (
-	UpperLower = MaxRune + 1 // (Cannot be a valid delta.)
-)
-
-// linearMax is the maximum size table for linear search for non-Latin1 rune.
-// Derived by running 'go test -calibrate'.
-const linearMax = 18
-
-// is16 reports whether r is in the sorted slice of 16-bit ranges.
-func is16(ranges []Range16, r uint16) bool {
-	if len(ranges) <= linearMax || r <= MaxLatin1 {
-		for i := range ranges {
-			range_ := &ranges[i]
-			if r < range_.Lo {
-				return false
-			}
-			if r <= range_.Hi {
-				return (r-range_.Lo)%range_.Stride == 0
-			}
-		}
-		return false
-	}
-
-	// binary search over ranges
-	lo := 0
-	hi := len(ranges)
-	for lo < hi {
-		m := lo + (hi-lo)/2
-		range_ := &ranges[m]
-		if range_.Lo <= r && r <= range_.Hi {
-			return (r-range_.Lo)%range_.Stride == 0
-		}
-		if r < range_.Lo {
-			hi = m
-		} else {
-			lo = m + 1
-		}
-	}
-	return false
-}
-
-// is32 reports whether r is in the sorted slice of 32-bit ranges.
-func is32(ranges []Range32, r uint32) bool {
-	if len(ranges) <= linearMax {
-		for i := range ranges {
-			range_ := &ranges[i]
-			if r < range_.Lo {
-				return false
-			}
-			if r <= range_.Hi {
-				return (r-range_.Lo)%range_.Stride == 0
-			}
-		}
-		return false
-	}
-
-	// binary search over ranges
-	lo := 0
-	hi := len(ranges)
-	for lo < hi {
-		m := lo + (hi-lo)/2
-		range_ := ranges[m]
-		if range_.Lo <= r && r <= range_.Hi {
-			return (r-range_.Lo)%range_.Stride == 0
-		}
-		if r < range_.Lo {
-			hi = m
-		} else {
-			lo = m + 1
-		}
-	}
-	return false
-}
-
-// Is reports whether the rune is in the specified table of ranges.
-func Is(rangeTab *RangeTable, r rune) bool {
-	r16 := rangeTab.R16
-	if len(r16) > 0 && r <= rune(r16[len(r16)-1].Hi) {
-		return is16(r16, uint16(r))
-	}
-	r32 := rangeTab.R32
-	if len(r32) > 0 && r >= rune(r32[0].Lo) {
-		return is32(r32, uint32(r))
-	}
-	return false
-}
-
-func isExcludingLatin(rangeTab *RangeTable, r rune) bool {
-	r16 := rangeTab.R16
-	if off := rangeTab.LatinOffset; len(r16) > off && r <= rune(r16[len(r16)-1].Hi) {
-		return is16(r16[off:], uint16(r))
-	}
-	r32 := rangeTab.R32
-	if len(r32) > 0 && r >= rune(r32[0].Lo) {
-		return is32(r32, uint32(r))
-	}
-	return false
-}
-
-// IsUpper reports whether the rune is an upper case letter.
-func IsUpper(r rune) bool {
-	// See comment in IsGraphic.
-	if uint32(r) <= MaxLatin1 {
-		return properties[uint8(r)]&pLmask == pLu
-	}
-	return isExcludingLatin(Upper, r)
-}
-
-// IsLower reports whether the rune is a lower case letter.
-func IsLower(r rune) bool {
-	// See comment in IsGraphic.
-	if uint32(r) <= MaxLatin1 {
-		return properties[uint8(r)]&pLmask == pLl
-	}
-	return isExcludingLatin(Lower, r)
-}
-
-// IsTitle reports whether the rune is a title case letter.
-func IsTitle(r rune) bool {
-	if r <= MaxLatin1 {
-		return false
-	}
-	return isExcludingLatin(Title, r)
-}
-
-// to maps the rune using the specified case mapping.
-func to(_case int, r rune, caseRange []CaseRange) rune {
-	if _case < 0 || MaxCase <= _case {
-		return ReplacementChar // as reasonable an error as any
-	}
-	// binary search over ranges
-	lo := 0
-	hi := len(caseRange)
-	for lo < hi {
-		m := lo + (hi-lo)/2
-		cr := caseRange[m]
-		if rune(cr.Lo) <= r && r <= rune(cr.Hi) {
-			delta := rune(cr.Delta[_case])
-			if delta > MaxRune {
-				// In an Upper-Lower sequence, which always starts with
-				// an UpperCase letter, the real deltas always look like:
-				//	{0, 1, 0}    UpperCase (Lower is next)
-				//	{-1, 0, -1}  LowerCase (Upper, Title are previous)
-				// The characters at even offsets from the beginning of the
-				// sequence are upper case; the ones at odd offsets are lower.
-				// The correct mapping can be done by clearing or setting the low
-				// bit in the sequence offset.
-				// The constants UpperCase and TitleCase are even while LowerCase
-				// is odd so we take the low bit from _case.
-				return rune(cr.Lo) + ((r-rune(cr.Lo))&^1 | rune(_case&1))
-			}
-			return r + delta
-		}
-		if r < rune(cr.Lo) {
-			hi = m
-		} else {
-			lo = m + 1
-		}
-	}
-	return r
-}
-
-// To maps the rune to the specified case: UpperCase, LowerCase, or TitleCase.
-func To(_case int, r rune) rune {
-	return to(_case, r, CaseRanges)
-}
-
-// ToUpper maps the rune to upper case.
-func ToUpper(r rune) rune {
-	if r <= MaxASCII {
-		if 'a' <= r && r <= 'z' {
-			r -= 'a' - 'A'
-		}
-		return r
-	}
-	return To(UpperCase, r)
-}
-
-// ToLower maps the rune to lower case.
-func ToLower(r rune) rune {
-	if r <= MaxASCII {
-		if 'A' <= r && r <= 'Z' {
-			r += 'a' - 'A'
-		}
-		return r
-	}
-	return To(LowerCase, r)
-}
-
-// ToTitle maps the rune to title case.
-func ToTitle(r rune) rune {
-	if r <= MaxASCII {
-		if 'a' <= r && r <= 'z' { // title case is upper case for ASCII
-			r -= 'a' - 'A'
-		}
-		return r
-	}
-	return To(TitleCase, r)
-}
-
-// ToUpper maps the rune to upper case giving priority to the special mapping.
-func (special SpecialCase) ToUpper(r rune) rune {
-	r1 := to(UpperCase, r, []CaseRange(special))
-	if r1 == r {
-		r1 = ToUpper(r)
-	}
-	return r1
-}
-
-// ToTitle maps the rune to title case giving priority to the special mapping.
-func (special SpecialCase) ToTitle(r rune) rune {
-	r1 := to(TitleCase, r, []CaseRange(special))
-	if r1 == r {
-		r1 = ToTitle(r)
-	}
-	return r1
-}
-
-// ToLower maps the rune to lower case giving priority to the special mapping.
-func (special SpecialCase) ToLower(r rune) rune {
-	r1 := to(LowerCase, r, []CaseRange(special))
-	if r1 == r {
-		r1 = ToLower(r)
-	}
-	return r1
-}
-
-// caseOrbit is defined in tables.go as []foldPair.  Right now all the
-// entries fit in uint16, so use uint16.  If that changes, compilation
-// will fail (the constants in the composite literal will not fit in uint16)
-// and the types here can change to uint32.
-type foldPair struct {
-	From uint16
-	To   uint16
-}
-
-// SimpleFold iterates over Unicode code points equivalent under
-// the Unicode-defined simple case folding.  Among the code points
-// equivalent to rune (including rune itself), SimpleFold returns the
-// smallest rune > r if one exists, or else the smallest rune >= 0.
-//
-// For example:
-//	SimpleFold('A') = 'a'
-//	SimpleFold('a') = 'A'
-//
-//	SimpleFold('K') = 'k'
-//	SimpleFold('k') = '\u212A' (Kelvin symbol, K)
-//	SimpleFold('\u212A') = 'K'
-//
-//	SimpleFold('1') = '1'
-//
-func SimpleFold(r rune) rune {
-	// Consult caseOrbit table for special cases.
-	lo := 0
-	hi := len(caseOrbit)
-	for lo < hi {
-		m := lo + (hi-lo)/2
-		if rune(caseOrbit[m].From) < r {
-			lo = m + 1
-		} else {
-			hi = m
-		}
-	}
-	if lo < len(caseOrbit) && rune(caseOrbit[lo].From) == r {
-		return rune(caseOrbit[lo].To)
-	}
-
-	// No folding specified.  This is a one- or two-element
-	// equivalence class containing rune and ToLower(rune)
-	// and ToUpper(rune) if they are different from rune.
-	if l := ToLower(r); l != r {
-		return l
-	}
-	return ToUpper(r)
-}
diff --git a/src/pkg/unicode/maketables.go b/src/pkg/unicode/maketables.go
deleted file mode 100644
index 8116ab8..0000000
--- a/src/pkg/unicode/maketables.go
+++ /dev/null
@@ -1,1320 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build ignore
-
-// Unicode table generator.
-// Data read from the web.
-
-package main
-
-import (
-	"bufio"
-	"flag"
-	"fmt"
-	"log"
-	"net/http"
-	"os"
-	"path/filepath"
-	"regexp"
-	"sort"
-	"strconv"
-	"strings"
-	"unicode"
-)
-
-func main() {
-	flag.Parse()
-	loadChars() // always needed
-	loadCasefold()
-	printCategories()
-	printScriptOrProperty(false)
-	printScriptOrProperty(true)
-	printCases()
-	printLatinProperties()
-	printCasefold()
-	printSizes()
-}
-
-var dataURL = flag.String("data", "", "full URL for UnicodeData.txt; defaults to --url/UnicodeData.txt")
-var casefoldingURL = flag.String("casefolding", "", "full URL for CaseFolding.txt; defaults to --url/CaseFolding.txt")
-var url = flag.String("url",
-	"http://www.unicode.org/Public/6.3.0/ucd/",
-	"URL of Unicode database directory")
-var tablelist = flag.String("tables",
-	"all",
-	"comma-separated list of which tables to generate; can be letter")
-var scriptlist = flag.String("scripts",
-	"all",
-	"comma-separated list of which script tables to generate")
-var proplist = flag.String("props",
-	"all",
-	"comma-separated list of which property tables to generate")
-var cases = flag.Bool("cases",
-	true,
-	"generate case tables")
-var test = flag.Bool("test",
-	false,
-	"test existing tables; can be used to compare web data with package data")
-var localFiles = flag.Bool("local",
-	false,
-	"data files have been copied to current directory; for debugging only")
-
-var scriptRe = regexp.MustCompile(`^([0-9A-F]+)(\.\.[0-9A-F]+)? *; ([A-Za-z_]+)$`)
-var logger = log.New(os.Stderr, "", log.Lshortfile)
-
-type reader struct {
-	*bufio.Reader
-	fd   *os.File
-	resp *http.Response
-}
-
-func open(url string) *reader {
-	file := filepath.Base(url)
-	if *localFiles {
-		fd, err := os.Open(file)
-		if err != nil {
-			logger.Fatal(err)
-		}
-		return &reader{bufio.NewReader(fd), fd, nil}
-	}
-	resp, err := http.Get(url)
-	if err != nil {
-		logger.Fatal(err)
-	}
-	if resp.StatusCode != 200 {
-		logger.Fatalf("bad GET status for %s: %d", file, resp.Status)
-	}
-	return &reader{bufio.NewReader(resp.Body), nil, resp}
-
-}
-
-func (r *reader) close() {
-	if r.fd != nil {
-		r.fd.Close()
-	} else {
-		r.resp.Body.Close()
-	}
-}
-
-var category = map[string]bool{
-	// Nd Lu etc.
-	// We use one-character names to identify merged categories
-	"L": true, // Lu Ll Lt Lm Lo
-	"P": true, // Pc Pd Ps Pe Pu Pf Po
-	"M": true, // Mn Mc Me
-	"N": true, // Nd Nl No
-	"S": true, // Sm Sc Sk So
-	"Z": true, // Zs Zl Zp
-	"C": true, // Cc Cf Cs Co Cn
-}
-
-// UnicodeData.txt has form:
-//	0037;DIGIT SEVEN;Nd;0;EN;;7;7;7;N;;;;;
-//	007A;LATIN SMALL LETTER Z;Ll;0;L;;;;;N;;;005A;;005A
-// See http://www.unicode.org/reports/tr44/ for a full explanation
-// The fields:
-const (
-	FCodePoint = iota
-	FName
-	FGeneralCategory
-	FCanonicalCombiningClass
-	FBidiClass
-	FDecompositionTypeAndMapping
-	FNumericType
-	FNumericDigit // If a decimal digit.
-	FNumericValue // Includes non-decimal, e.g. U+2155=1/5
-	FBidiMirrored
-	FUnicode1Name
-	FISOComment
-	FSimpleUppercaseMapping
-	FSimpleLowercaseMapping
-	FSimpleTitlecaseMapping
-	NumField
-
-	MaxChar = 0x10FFFF // anything above this shouldn't exist
-)
-
-var fieldName = []string{
-	FCodePoint:                   "CodePoint",
-	FName:                        "Name",
-	FGeneralCategory:             "GeneralCategory",
-	FCanonicalCombiningClass:     "CanonicalCombiningClass",
-	FBidiClass:                   "BidiClass",
-	FDecompositionTypeAndMapping: "DecompositionTypeAndMapping",
-	FNumericType:                 "NumericType",
-	FNumericDigit:                "NumericDigit",
-	FNumericValue:                "NumericValue",
-	FBidiMirrored:                "BidiMirrored",
-	FUnicode1Name:                "Unicode1Name",
-	FISOComment:                  "ISOComment",
-	FSimpleUppercaseMapping:      "SimpleUppercaseMapping",
-	FSimpleLowercaseMapping:      "SimpleLowercaseMapping",
-	FSimpleTitlecaseMapping:      "SimpleTitlecaseMapping",
-}
-
-// This contains only the properties we're interested in.
-type Char struct {
-	field     []string // debugging only; could be deleted if we take out char.dump()
-	codePoint rune     // if zero, this index is not a valid code point.
-	category  string
-	upperCase rune
-	lowerCase rune
-	titleCase rune
-	foldCase  rune // simple case folding
-	caseOrbit rune // next in simple case folding orbit
-}
-
-// Scripts.txt has form:
-//	A673          ; Cyrillic # Po       SLAVONIC ASTERISK
-//	A67C..A67D    ; Cyrillic # Mn   [2] COMBINING CYRILLIC KAVYKA..COMBINING CYRILLIC PAYEROK
-// See http://www.unicode.org/Public/5.1.0/ucd/UCD.html for full explanation
-
-type Script struct {
-	lo, hi uint32 // range of code points
-	script string
-}
-
-var chars = make([]Char, MaxChar+1)
-var scripts = make(map[string][]Script)
-var props = make(map[string][]Script) // a property looks like a script; can share the format
-
-var lastChar rune = 0
-
-// In UnicodeData.txt, some ranges are marked like this:
-//	3400;<CJK Ideograph Extension A, First>;Lo;0;L;;;;;N;;;;;
-//	4DB5;<CJK Ideograph Extension A, Last>;Lo;0;L;;;;;N;;;;;
-// parseCategory returns a state variable indicating the weirdness.
-type State int
-
-const (
-	SNormal State = iota // known to be zero for the type
-	SFirst
-	SLast
-	SMissing
-)
-
-func parseCategory(line string) (state State) {
-	field := strings.Split(line, ";")
-	if len(field) != NumField {
-		logger.Fatalf("%5s: %d fields (expected %d)\n", line, len(field), NumField)
-	}
-	point, err := strconv.ParseUint(field[FCodePoint], 16, 64)
-	if err != nil {
-		logger.Fatalf("%.5s...: %s", line, err)
-	}
-	lastChar = rune(point)
-	if point == 0 {
-		return // not interesting and we use 0 as unset
-	}
-	if point > MaxChar {
-		return
-	}
-	char := &chars[point]
-	char.field = field
-	if char.codePoint != 0 {
-		logger.Fatalf("point %U reused", point)
-	}
-	char.codePoint = lastChar
-	char.category = field[FGeneralCategory]
-	category[char.category] = true
-	switch char.category {
-	case "Nd":
-		// Decimal digit
-		_, err := strconv.Atoi(field[FNumericValue])
-		if err != nil {
-			logger.Fatalf("%U: bad numeric field: %s", point, err)
-		}
-	case "Lu":
-		char.letter(field[FCodePoint], field[FSimpleLowercaseMapping], field[FSimpleTitlecaseMapping])
-	case "Ll":
-		char.letter(field[FSimpleUppercaseMapping], field[FCodePoint], field[FSimpleTitlecaseMapping])
-	case "Lt":
-		char.letter(field[FSimpleUppercaseMapping], field[FSimpleLowercaseMapping], field[FCodePoint])
-	default:
-		char.letter(field[FSimpleUppercaseMapping], field[FSimpleLowercaseMapping], field[FSimpleTitlecaseMapping])
-	}
-	switch {
-	case strings.Index(field[FName], ", First>") > 0:
-		state = SFirst
-	case strings.Index(field[FName], ", Last>") > 0:
-		state = SLast
-	}
-	return
-}
-
-func (char *Char) dump(s string) {
-	fmt.Print(s, " ")
-	for i := 0; i < len(char.field); i++ {
-		fmt.Printf("%s:%q ", fieldName[i], char.field[i])
-	}
-	fmt.Print("\n")
-}
-
-func (char *Char) letter(u, l, t string) {
-	char.upperCase = char.letterValue(u, "U")
-	char.lowerCase = char.letterValue(l, "L")
-	char.titleCase = char.letterValue(t, "T")
-}
-
-func (char *Char) letterValue(s string, cas string) rune {
-	if s == "" {
-		return 0
-	}
-	v, err := strconv.ParseUint(s, 16, 64)
-	if err != nil {
-		char.dump(cas)
-		logger.Fatalf("%U: bad letter(%s): %s", char.codePoint, s, err)
-	}
-	return rune(v)
-}
-
-func allCategories() []string {
-	a := make([]string, 0, len(category))
-	for k := range category {
-		a = append(a, k)
-	}
-	sort.Strings(a)
-	return a
-}
-
-func all(scripts map[string][]Script) []string {
-	a := make([]string, 0, len(scripts))
-	for k := range scripts {
-		a = append(a, k)
-	}
-	sort.Strings(a)
-	return a
-}
-
-func allCatFold(m map[string]map[rune]bool) []string {
-	a := make([]string, 0, len(m))
-	for k := range m {
-		a = append(a, k)
-	}
-	sort.Strings(a)
-	return a
-}
-
-// Extract the version number from the URL
-func version() string {
-	// Break on slashes and look for the first numeric field
-	fields := strings.Split(*url, "/")
-	for _, f := range fields {
-		if len(f) > 0 && '0' <= f[0] && f[0] <= '9' {
-			return f
-		}
-	}
-	logger.Fatal("unknown version")
-	return "Unknown"
-}
-
-func categoryOp(code rune, class uint8) bool {
-	category := chars[code].category
-	return len(category) > 0 && category[0] == class
-}
-
-func loadChars() {
-	if *dataURL == "" {
-		flag.Set("data", *url+"UnicodeData.txt")
-	}
-	input := open(*dataURL)
-	defer input.close()
-	scanner := bufio.NewScanner(input)
-	var first rune = 0
-	for scanner.Scan() {
-		switch parseCategory(scanner.Text()) {
-		case SNormal:
-			if first != 0 {
-				logger.Fatalf("bad state normal at %U", lastChar)
-			}
-		case SFirst:
-			if first != 0 {
-				logger.Fatalf("bad state first at %U", lastChar)
-			}
-			first = lastChar
-		case SLast:
-			if first == 0 {
-				logger.Fatalf("bad state last at %U", lastChar)
-			}
-			for i := first + 1; i <= lastChar; i++ {
-				chars[i] = chars[first]
-				chars[i].codePoint = i
-			}
-			first = 0
-		}
-	}
-	if scanner.Err() != nil {
-		logger.Fatal(scanner.Err())
-	}
-}
-
-func loadCasefold() {
-	if *casefoldingURL == "" {
-		flag.Set("casefolding", *url+"CaseFolding.txt")
-	}
-	input := open(*casefoldingURL)
-	defer input.close()
-	scanner := bufio.NewScanner(input)
-	for scanner.Scan() {
-		line := scanner.Text()
-		if len(line) == 0 || line[0] == '#' || len(strings.TrimSpace(line)) == 0 {
-			continue
-		}
-		field := strings.Split(line, "; ")
-		if len(field) != 4 {
-			logger.Fatalf("CaseFolding.txt %.5s...: %d fields (expected %d)\n", line, len(field), 4)
-		}
-		kind := field[1]
-		if kind != "C" && kind != "S" {
-			// Only care about 'common' and 'simple' foldings.
-			continue
-		}
-		p1, err := strconv.ParseUint(field[0], 16, 64)
-		if err != nil {
-			logger.Fatalf("CaseFolding.txt %.5s...: %s", line, err)
-		}
-		p2, err := strconv.ParseUint(field[2], 16, 64)
-		if err != nil {
-			logger.Fatalf("CaseFolding.txt %.5s...: %s", line, err)
-		}
-		chars[p1].foldCase = rune(p2)
-	}
-	if scanner.Err() != nil {
-		logger.Fatal(scanner.Err())
-	}
-}
-
-const progHeader = `// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Generated by running
-//	maketables --tables=%s --data=%s --casefolding=%s
-// DO NOT EDIT
-
-package unicode
-
-`
-
-func printCategories() {
-	if *tablelist == "" {
-		return
-	}
-	// Find out which categories to dump
-	list := strings.Split(*tablelist, ",")
-	if *tablelist == "all" {
-		list = allCategories()
-	}
-	if *test {
-		fullCategoryTest(list)
-		return
-	}
-	fmt.Printf(progHeader, *tablelist, *dataURL, *casefoldingURL)
-
-	fmt.Println("// Version is the Unicode edition from which the tables are derived.")
-	fmt.Printf("const Version = %q\n\n", version())
-
-	if *tablelist == "all" {
-		fmt.Println("// Categories is the set of Unicode category tables.")
-		fmt.Println("var Categories = map[string] *RangeTable {")
-		for _, k := range allCategories() {
-			fmt.Printf("\t%q: %s,\n", k, k)
-		}
-		fmt.Print("}\n\n")
-	}
-
-	decl := make(sort.StringSlice, len(list))
-	ndecl := 0
-	for _, name := range list {
-		if _, ok := category[name]; !ok {
-			logger.Fatal("unknown category", name)
-		}
-		// We generate an UpperCase name to serve as concise documentation and an _UnderScored
-		// name to store the data.  This stops godoc dumping all the tables but keeps them
-		// available to clients.
-		// Cases deserving special comments
-		varDecl := ""
-		switch name {
-		case "C":
-			varDecl = "\tOther = _C;	// Other/C is the set of Unicode control and special characters, category C.\n"
-			varDecl += "\tC = _C\n"
-		case "L":
-			varDecl = "\tLetter = _L;	// Letter/L is the set of Unicode letters, category L.\n"
-			varDecl += "\tL = _L\n"
-		case "M":
-			varDecl = "\tMark = _M;	// Mark/M is the set of Unicode mark characters, category M.\n"
-			varDecl += "\tM = _M\n"
-		case "N":
-			varDecl = "\tNumber = _N;	// Number/N is the set of Unicode number characters, category N.\n"
-			varDecl += "\tN = _N\n"
-		case "P":
-			varDecl = "\tPunct = _P;	// Punct/P is the set of Unicode punctuation characters, category P.\n"
-			varDecl += "\tP = _P\n"
-		case "S":
-			varDecl = "\tSymbol = _S;	// Symbol/S is the set of Unicode symbol characters, category S.\n"
-			varDecl += "\tS = _S\n"
-		case "Z":
-			varDecl = "\tSpace = _Z;	// Space/Z is the set of Unicode space characters, category Z.\n"
-			varDecl += "\tZ = _Z\n"
-		case "Nd":
-			varDecl = "\tDigit = _Nd;	// Digit is the set of Unicode characters with the \"decimal digit\" property.\n"
-		case "Lu":
-			varDecl = "\tUpper = _Lu;	// Upper is the set of Unicode upper case letters.\n"
-		case "Ll":
-			varDecl = "\tLower = _Ll;	// Lower is the set of Unicode lower case letters.\n"
-		case "Lt":
-			varDecl = "\tTitle = _Lt;	// Title is the set of Unicode title case letters.\n"
-		}
-		if len(name) > 1 {
-			varDecl += fmt.Sprintf(
-				"\t%s = _%s;	// %s is the set of Unicode characters in category %s.\n",
-				name, name, name, name)
-		}
-		decl[ndecl] = varDecl
-		ndecl++
-		if len(name) == 1 { // unified categories
-			decl := fmt.Sprintf("var _%s = &RangeTable{\n", name)
-			dumpRange(
-				decl,
-				func(code rune) bool { return categoryOp(code, name[0]) })
-			continue
-		}
-		dumpRange(
-			fmt.Sprintf("var _%s = &RangeTable{\n", name),
-			func(code rune) bool { return chars[code].category == name })
-	}
-	decl.Sort()
-	fmt.Println("// These variables have type *RangeTable.")
-	fmt.Println("var (")
-	for _, d := range decl {
-		fmt.Print(d)
-	}
-	fmt.Print(")\n\n")
-}
-
-type Op func(code rune) bool
-
-const format = "\t\t{0x%04x, 0x%04x, %d},\n"
-
-func dumpRange(header string, inCategory Op) {
-	fmt.Print(header)
-	next := rune(0)
-	latinOffset := 0
-	fmt.Print("\tR16: []Range16{\n")
-	// one Range for each iteration
-	count := &range16Count
-	size := 16
-	for {
-		// look for start of range
-		for next < rune(len(chars)) && !inCategory(next) {
-			next++
-		}
-		if next >= rune(len(chars)) {
-			// no characters remain
-			break
-		}
-
-		// start of range
-		lo := next
-		hi := next
-		stride := rune(1)
-		// accept lo
-		next++
-		// look for another character to set the stride
-		for next < rune(len(chars)) && !inCategory(next) {
-			next++
-		}
-		if next >= rune(len(chars)) {
-			// no more characters
-			fmt.Printf(format, lo, hi, stride)
-			break
-		}
-		// set stride
-		stride = next - lo
-		// check for length of run. next points to first jump in stride
-		for i := next; i < rune(len(chars)); i++ {
-			if inCategory(i) == (((i - lo) % stride) == 0) {
-				// accept
-				if inCategory(i) {
-					hi = i
-				}
-			} else {
-				// no more characters in this run
-				break
-			}
-		}
-		if uint32(hi) <= unicode.MaxLatin1 {
-			latinOffset++
-		}
-		size, count = printRange(uint32(lo), uint32(hi), uint32(stride), size, count)
-		// next range: start looking where this range ends
-		next = hi + 1
-	}
-	fmt.Print("\t},\n")
-	if latinOffset > 0 {
-		fmt.Printf("\tLatinOffset: %d,\n", latinOffset)
-	}
-	fmt.Print("}\n\n")
-}
-
-func printRange(lo, hi, stride uint32, size int, count *int) (int, *int) {
-	if size == 16 && hi >= 1<<16 {
-		if lo < 1<<16 {
-			if lo+stride != hi {
-				logger.Fatalf("unexpected straddle: %U %U %d", lo, hi, stride)
-			}
-			// No range contains U+FFFF as an instance, so split
-			// the range into two entries. That way we can maintain
-			// the invariant that R32 contains only >= 1<<16.
-			fmt.Printf(format, lo, lo, 1)
-			lo = hi
-			stride = 1
-			*count++
-		}
-		fmt.Print("\t},\n")
-		fmt.Print("\tR32: []Range32{\n")
-		size = 32
-		count = &range32Count
-	}
-	fmt.Printf(format, lo, hi, stride)
-	*count++
-	return size, count
-}
-
-func fullCategoryTest(list []string) {
-	for _, name := range list {
-		if _, ok := category[name]; !ok {
-			logger.Fatal("unknown category", name)
-		}
-		r, ok := unicode.Categories[name]
-		if !ok && len(name) > 1 {
-			logger.Fatalf("unknown table %q", name)
-		}
-		if len(name) == 1 {
-			verifyRange(name, func(code rune) bool { return categoryOp(code, name[0]) }, r)
-		} else {
-			verifyRange(
-				name,
-				func(code rune) bool { return chars[code].category == name },
-				r)
-		}
-	}
-}
-
-func verifyRange(name string, inCategory Op, table *unicode.RangeTable) {
-	count := 0
-	for j := range chars {
-		i := rune(j)
-		web := inCategory(i)
-		pkg := unicode.Is(table, i)
-		if web != pkg {
-			fmt.Fprintf(os.Stderr, "%s: %U: web=%t pkg=%t\n", name, i, web, pkg)
-			count++
-			if count > 10 {
-				break
-			}
-		}
-	}
-}
-
-func parseScript(line string, scripts map[string][]Script) {
-	comment := strings.Index(line, "#")
-	if comment >= 0 {
-		line = line[0:comment]
-	}
-	line = strings.TrimSpace(line)
-	if len(line) == 0 {
-		return
-	}
-	field := strings.Split(line, ";")
-	if len(field) != 2 {
-		logger.Fatalf("%s: %d fields (expected 2)\n", line, len(field))
-	}
-	matches := scriptRe.FindStringSubmatch(line)
-	if len(matches) != 4 {
-		logger.Fatalf("%s: %d matches (expected 3)\n", line, len(matches))
-	}
-	lo, err := strconv.ParseUint(matches[1], 16, 64)
-	if err != nil {
-		logger.Fatalf("%.5s...: %s", line, err)
-	}
-	hi := lo
-	if len(matches[2]) > 2 { // ignore leading ..
-		hi, err = strconv.ParseUint(matches[2][2:], 16, 64)
-		if err != nil {
-			logger.Fatalf("%.5s...: %s", line, err)
-		}
-	}
-	name := matches[3]
-	scripts[name] = append(scripts[name], Script{uint32(lo), uint32(hi), name})
-}
-
-// The script tables have a lot of adjacent elements. Fold them together.
-func foldAdjacent(r []Script) []unicode.Range32 {
-	s := make([]unicode.Range32, 0, len(r))
-	j := 0
-	for i := 0; i < len(r); i++ {
-		if j > 0 && r[i].lo == s[j-1].Hi+1 {
-			s[j-1].Hi = r[i].hi
-		} else {
-			s = s[0 : j+1]
-			s[j] = unicode.Range32{
-				Lo:     uint32(r[i].lo),
-				Hi:     uint32(r[i].hi),
-				Stride: 1,
-			}
-			j++
-		}
-	}
-	return s
-}
-
-func fullScriptTest(list []string, installed map[string]*unicode.RangeTable, scripts map[string][]Script) {
-	for _, name := range list {
-		if _, ok := scripts[name]; !ok {
-			logger.Fatal("unknown script", name)
-		}
-		_, ok := installed[name]
-		if !ok {
-			logger.Fatal("unknown table", name)
-		}
-		for _, script := range scripts[name] {
-			for r := script.lo; r <= script.hi; r++ {
-				if !unicode.Is(installed[name], rune(r)) {
-					fmt.Fprintf(os.Stderr, "%U: not in script %s\n", r, name)
-				}
-			}
-		}
-	}
-}
-
-// PropList.txt has the same format as Scripts.txt so we can share its parser.
-func printScriptOrProperty(doProps bool) {
-	flag := "scripts"
-	flaglist := *scriptlist
-	file := "Scripts.txt"
-	table := scripts
-	installed := unicode.Scripts
-	if doProps {
-		flag = "props"
-		flaglist = *proplist
-		file = "PropList.txt"
-		table = props
-		installed = unicode.Properties
-	}
-	if flaglist == "" {
-		return
-	}
-	input := open(*url + file)
-	scanner := bufio.NewScanner(input)
-	for scanner.Scan() {
-		parseScript(scanner.Text(), table)
-	}
-	if scanner.Err() != nil {
-		logger.Fatal(scanner.Err())
-	}
-	input.close()
-
-	// Find out which scripts to dump
-	list := strings.Split(flaglist, ",")
-	if flaglist == "all" {
-		list = all(table)
-	}
-	if *test {
-		fullScriptTest(list, installed, table)
-		return
-	}
-
-	fmt.Printf(
-		"// Generated by running\n"+
-			"//	maketables --%s=%s --url=%s\n"+
-			"// DO NOT EDIT\n\n",
-		flag,
-		flaglist,
-		*url)
-	if flaglist == "all" {
-		if doProps {
-			fmt.Println("// Properties is the set of Unicode property tables.")
-			fmt.Println("var Properties = map[string] *RangeTable{")
-		} else {
-			fmt.Println("// Scripts is the set of Unicode script tables.")
-			fmt.Println("var Scripts = map[string] *RangeTable{")
-		}
-		for _, k := range all(table) {
-			fmt.Printf("\t%q: %s,\n", k, k)
-		}
-		fmt.Print("}\n\n")
-	}
-
-	decl := make(sort.StringSlice, len(list))
-	ndecl := 0
-	for _, name := range list {
-		if doProps {
-			decl[ndecl] = fmt.Sprintf(
-				"\t%s = _%s;\t// %s is the set of Unicode characters with property %s.\n",
-				name, name, name, name)
-		} else {
-			decl[ndecl] = fmt.Sprintf(
-				"\t%s = _%s;\t// %s is the set of Unicode characters in script %s.\n",
-				name, name, name, name)
-		}
-		ndecl++
-		fmt.Printf("var _%s = &RangeTable {\n", name)
-		ranges := foldAdjacent(table[name])
-		fmt.Print("\tR16: []Range16{\n")
-		size := 16
-		count := &range16Count
-		for _, s := range ranges {
-			size, count = printRange(s.Lo, s.Hi, s.Stride, size, count)
-		}
-		fmt.Print("\t},\n")
-		if off := findLatinOffset(ranges); off > 0 {
-			fmt.Printf("\tLatinOffset: %d,\n", off)
-		}
-		fmt.Print("}\n\n")
-	}
-	decl.Sort()
-	fmt.Println("// These variables have type *RangeTable.")
-	fmt.Println("var (")
-	for _, d := range decl {
-		fmt.Print(d)
-	}
-	fmt.Print(")\n\n")
-}
-
-func findLatinOffset(ranges []unicode.Range32) int {
-	i := 0
-	for i < len(ranges) && ranges[i].Hi <= unicode.MaxLatin1 {
-		i++
-	}
-	return i
-}
-
-const (
-	CaseUpper = 1 << iota
-	CaseLower
-	CaseTitle
-	CaseNone    = 0  // must be zero
-	CaseMissing = -1 // character not present; not a valid case state
-)
-
-type caseState struct {
-	point        rune
-	_case        int
-	deltaToUpper rune
-	deltaToLower rune
-	deltaToTitle rune
-}
-
-// Is d a continuation of the state of c?
-func (c *caseState) adjacent(d *caseState) bool {
-	if d.point < c.point {
-		c, d = d, c
-	}
-	switch {
-	case d.point != c.point+1: // code points not adjacent (shouldn't happen)
-		return false
-	case d._case != c._case: // different cases
-		return c.upperLowerAdjacent(d)
-	case c._case == CaseNone:
-		return false
-	case c._case == CaseMissing:
-		return false
-	case d.deltaToUpper != c.deltaToUpper:
-		return false
-	case d.deltaToLower != c.deltaToLower:
-		return false
-	case d.deltaToTitle != c.deltaToTitle:
-		return false
-	}
-	return true
-}
-
-// Is d the same as c, but opposite in upper/lower case? this would make it
-// an element of an UpperLower sequence.
-func (c *caseState) upperLowerAdjacent(d *caseState) bool {
-	// check they're a matched case pair.  we know they have adjacent values
-	switch {
-	case c._case == CaseUpper && d._case != CaseLower:
-		return false
-	case c._case == CaseLower && d._case != CaseUpper:
-		return false
-	}
-	// matched pair (at least in upper/lower).  make the order Upper Lower
-	if c._case == CaseLower {
-		c, d = d, c
-	}
-	// for an Upper Lower sequence the deltas have to be in order
-	//	c: 0 1 0
-	//	d: -1 0 -1
-	switch {
-	case c.deltaToUpper != 0:
-		return false
-	case c.deltaToLower != 1:
-		return false
-	case c.deltaToTitle != 0:
-		return false
-	case d.deltaToUpper != -1:
-		return false
-	case d.deltaToLower != 0:
-		return false
-	case d.deltaToTitle != -1:
-		return false
-	}
-	return true
-}
-
-// Does this character start an UpperLower sequence?
-func (c *caseState) isUpperLower() bool {
-	// for an Upper Lower sequence the deltas have to be in order
-	//	c: 0 1 0
-	switch {
-	case c.deltaToUpper != 0:
-		return false
-	case c.deltaToLower != 1:
-		return false
-	case c.deltaToTitle != 0:
-		return false
-	}
-	return true
-}
-
-// Does this character start a LowerUpper sequence?
-func (c *caseState) isLowerUpper() bool {
-	// for an Upper Lower sequence the deltas have to be in order
-	//	c: -1 0 -1
-	switch {
-	case c.deltaToUpper != -1:
-		return false
-	case c.deltaToLower != 0:
-		return false
-	case c.deltaToTitle != -1:
-		return false
-	}
-	return true
-}
-
-func getCaseState(i rune) (c *caseState) {
-	c = &caseState{point: i, _case: CaseNone}
-	ch := &chars[i]
-	switch ch.codePoint {
-	case 0:
-		c._case = CaseMissing // Will get NUL wrong but that doesn't matter
-		return
-	case ch.upperCase:
-		c._case = CaseUpper
-	case ch.lowerCase:
-		c._case = CaseLower
-	case ch.titleCase:
-		c._case = CaseTitle
-	}
-	// Some things such as roman numeral U+2161 don't describe themselves
-	// as upper case, but have a lower case.  Second-guess them.
-	if c._case == CaseNone && ch.lowerCase != 0 {
-		c._case = CaseUpper
-	}
-	// Same in the other direction.
-	if c._case == CaseNone && ch.upperCase != 0 {
-		c._case = CaseLower
-	}
-
-	if ch.upperCase != 0 {
-		c.deltaToUpper = ch.upperCase - i
-	}
-	if ch.lowerCase != 0 {
-		c.deltaToLower = ch.lowerCase - i
-	}
-	if ch.titleCase != 0 {
-		c.deltaToTitle = ch.titleCase - i
-	}
-	return
-}
-
-func printCases() {
-	if !*cases {
-		return
-	}
-	if *test {
-		fullCaseTest()
-		return
-	}
-	fmt.Printf(
-		"// Generated by running\n"+
-			"//	maketables --data=%s --casefolding=%s\n"+
-			"// DO NOT EDIT\n\n"+
-			"// CaseRanges is the table describing case mappings for all letters with\n"+
-			"// non-self mappings.\n"+
-			"var CaseRanges = _CaseRanges\n"+
-			"var _CaseRanges = []CaseRange {\n",
-		*dataURL, *casefoldingURL)
-
-	var startState *caseState    // the start of a run; nil for not active
-	var prevState = &caseState{} // the state of the previous character
-	for i := range chars {
-		state := getCaseState(rune(i))
-		if state.adjacent(prevState) {
-			prevState = state
-			continue
-		}
-		// end of run (possibly)
-		printCaseRange(startState, prevState)
-		startState = nil
-		if state._case != CaseMissing && state._case != CaseNone {
-			startState = state
-		}
-		prevState = state
-	}
-	fmt.Print("}\n")
-}
-
-func printCaseRange(lo, hi *caseState) {
-	if lo == nil {
-		return
-	}
-	if lo.deltaToUpper == 0 && lo.deltaToLower == 0 && lo.deltaToTitle == 0 {
-		// character represents itself in all cases - no need to mention it
-		return
-	}
-	switch {
-	case hi.point > lo.point && lo.isUpperLower():
-		fmt.Printf("\t{0x%04X, 0x%04X, d{UpperLower, UpperLower, UpperLower}},\n",
-			lo.point, hi.point)
-	case hi.point > lo.point && lo.isLowerUpper():
-		logger.Fatalf("LowerUpper sequence: should not happen: %U.  If it's real, need to fix To()", lo.point)
-		fmt.Printf("\t{0x%04X, 0x%04X, d{LowerUpper, LowerUpper, LowerUpper}},\n",
-			lo.point, hi.point)
-	default:
-		fmt.Printf("\t{0x%04X, 0x%04X, d{%d, %d, %d}},\n",
-			lo.point, hi.point,
-			lo.deltaToUpper, lo.deltaToLower, lo.deltaToTitle)
-	}
-}
-
-// If the cased value in the Char is 0, it means use the rune itself.
-func caseIt(r, cased rune) rune {
-	if cased == 0 {
-		return r
-	}
-	return cased
-}
-
-func fullCaseTest() {
-	for j, c := range chars {
-		i := rune(j)
-		lower := unicode.ToLower(i)
-		want := caseIt(i, c.lowerCase)
-		if lower != want {
-			fmt.Fprintf(os.Stderr, "lower %U should be %U is %U\n", i, want, lower)
-		}
-		upper := unicode.ToUpper(i)
-		want = caseIt(i, c.upperCase)
-		if upper != want {
-			fmt.Fprintf(os.Stderr, "upper %U should be %U is %U\n", i, want, upper)
-		}
-		title := unicode.ToTitle(i)
-		want = caseIt(i, c.titleCase)
-		if title != want {
-			fmt.Fprintf(os.Stderr, "title %U should be %U is %U\n", i, want, title)
-		}
-	}
-}
-
-func printLatinProperties() {
-	if *test {
-		return
-	}
-	fmt.Println("var properties = [MaxLatin1+1]uint8{")
-	for code := 0; code <= unicode.MaxLatin1; code++ {
-		var property string
-		switch chars[code].category {
-		case "Cc", "": // NUL has no category.
-			property = "pC"
-		case "Cf": // soft hyphen, unique category, not printable.
-			property = "0"
-		case "Ll":
-			property = "pLl | pp"
-		case "Lo":
-			property = "pLo | pp"
-		case "Lu":
-			property = "pLu | pp"
-		case "Nd", "No":
-			property = "pN | pp"
-		case "Pc", "Pd", "Pe", "Pf", "Pi", "Po", "Ps":
-			property = "pP | pp"
-		case "Sc", "Sk", "Sm", "So":
-			property = "pS | pp"
-		case "Zs":
-			property = "pZ"
-		default:
-			logger.Fatalf("%U has unknown category %q", code, chars[code].category)
-		}
-		// Special case
-		if code == ' ' {
-			property = "pZ | pp"
-		}
-		fmt.Printf("\t0x%02X: %s, // %q\n", code, property, code)
-	}
-	fmt.Printf("}\n\n")
-}
-
-type runeSlice []rune
-
-func (p runeSlice) Len() int           { return len(p) }
-func (p runeSlice) Less(i, j int) bool { return p[i] < p[j] }
-func (p runeSlice) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
-
-func printCasefold() {
-	// Build list of case-folding groups attached to each canonical folded char (typically lower case).
-	var caseOrbit = make([][]rune, MaxChar+1)
-	for j := range chars {
-		i := rune(j)
-		c := &chars[i]
-		if c.foldCase == 0 {
-			continue
-		}
-		orb := caseOrbit[c.foldCase]
-		if orb == nil {
-			orb = append(orb, c.foldCase)
-		}
-		caseOrbit[c.foldCase] = append(orb, i)
-	}
-
-	// Insert explicit 1-element groups when assuming [lower, upper] would be wrong.
-	for j := range chars {
-		i := rune(j)
-		c := &chars[i]
-		f := c.foldCase
-		if f == 0 {
-			f = i
-		}
-		orb := caseOrbit[f]
-		if orb == nil && (c.upperCase != 0 && c.upperCase != i || c.lowerCase != 0 && c.lowerCase != i) {
-			// Default assumption of [upper, lower] is wrong.
-			caseOrbit[i] = []rune{i}
-		}
-	}
-
-	// Delete the groups for which assuming [lower, upper] is right.
-	for i, orb := range caseOrbit {
-		if len(orb) == 2 && chars[orb[0]].upperCase == orb[1] && chars[orb[1]].lowerCase == orb[0] {
-			caseOrbit[i] = nil
-		}
-	}
-
-	// Record orbit information in chars.
-	for _, orb := range caseOrbit {
-		if orb == nil {
-			continue
-		}
-		sort.Sort(runeSlice(orb))
-		c := orb[len(orb)-1]
-		for _, d := range orb {
-			chars[c].caseOrbit = d
-			c = d
-		}
-	}
-
-	printCaseOrbit()
-
-	// Tables of category and script folding exceptions: code points
-	// that must be added when interpreting a particular category/script
-	// in a case-folding context.
-	cat := make(map[string]map[rune]bool)
-	for name := range category {
-		if x := foldExceptions(inCategory(name)); len(x) > 0 {
-			cat[name] = x
-		}
-	}
-
-	scr := make(map[string]map[rune]bool)
-	for name := range scripts {
-		if x := foldExceptions(inScript(name)); len(x) > 0 {
-			cat[name] = x
-		}
-	}
-
-	printCatFold("FoldCategory", cat)
-	printCatFold("FoldScript", scr)
-}
-
-// inCategory returns a list of all the runes in the category.
-func inCategory(name string) []rune {
-	var x []rune
-	for j := range chars {
-		i := rune(j)
-		c := &chars[i]
-		if c.category == name || len(name) == 1 && len(c.category) > 1 && c.category[0] == name[0] {
-			x = append(x, i)
-		}
-	}
-	return x
-}
-
-// inScript returns a list of all the runes in the script.
-func inScript(name string) []rune {
-	var x []rune
-	for _, s := range scripts[name] {
-		for c := s.lo; c <= s.hi; c++ {
-			x = append(x, rune(c))
-		}
-	}
-	return x
-}
-
-// foldExceptions returns a list of all the runes fold-equivalent
-// to runes in class but not in class themselves.
-func foldExceptions(class []rune) map[rune]bool {
-	// Create map containing class and all fold-equivalent chars.
-	m := make(map[rune]bool)
-	for _, r := range class {
-		c := &chars[r]
-		if c.caseOrbit == 0 {
-			// Just upper and lower.
-			if u := c.upperCase; u != 0 {
-				m[u] = true
-			}
-			if l := c.lowerCase; l != 0 {
-				m[l] = true
-			}
-			m[r] = true
-			continue
-		}
-		// Otherwise walk orbit.
-		r0 := r
-		for {
-			m[r] = true
-			r = chars[r].caseOrbit
-			if r == r0 {
-				break
-			}
-		}
-	}
-
-	// Remove class itself.
-	for _, r := range class {
-		delete(m, r)
-	}
-
-	// What's left is the exceptions.
-	return m
-}
-
-var comment = map[string]string{
-	"FoldCategory": "// FoldCategory maps a category name to a table of\n" +
-		"// code points outside the category that are equivalent under\n" +
-		"// simple case folding to code points inside the category.\n" +
-		"// If there is no entry for a category name, there are no such points.\n",
-
-	"FoldScript": "// FoldScript maps a script name to a table of\n" +
-		"// code points outside the script that are equivalent under\n" +
-		"// simple case folding to code points inside the script.\n" +
-		"// If there is no entry for a script name, there are no such points.\n",
-}
-
-func printCaseOrbit() {
-	if *test {
-		for j := range chars {
-			i := rune(j)
-			c := &chars[i]
-			f := c.caseOrbit
-			if f == 0 {
-				if c.lowerCase != i && c.lowerCase != 0 {
-					f = c.lowerCase
-				} else if c.upperCase != i && c.upperCase != 0 {
-					f = c.upperCase
-				} else {
-					f = i
-				}
-			}
-			if g := unicode.SimpleFold(i); g != f {
-				fmt.Fprintf(os.Stderr, "unicode.SimpleFold(%#U) = %#U, want %#U\n", i, g, f)
-			}
-		}
-		return
-	}
-
-	fmt.Printf("var caseOrbit = []foldPair{\n")
-	for i := range chars {
-		c := &chars[i]
-		if c.caseOrbit != 0 {
-			fmt.Printf("\t{0x%04X, 0x%04X},\n", i, c.caseOrbit)
-			foldPairCount++
-		}
-	}
-	fmt.Printf("}\n\n")
-}
-
-func printCatFold(name string, m map[string]map[rune]bool) {
-	if *test {
-		var pkgMap map[string]*unicode.RangeTable
-		if name == "FoldCategory" {
-			pkgMap = unicode.FoldCategory
-		} else {
-			pkgMap = unicode.FoldScript
-		}
-		if len(pkgMap) != len(m) {
-			fmt.Fprintf(os.Stderr, "unicode.%s has %d elements, want %d\n", name, len(pkgMap), len(m))
-			return
-		}
-		for k, v := range m {
-			t, ok := pkgMap[k]
-			if !ok {
-				fmt.Fprintf(os.Stderr, "unicode.%s[%q] missing\n", name, k)
-				continue
-			}
-			n := 0
-			for _, r := range t.R16 {
-				for c := rune(r.Lo); c <= rune(r.Hi); c += rune(r.Stride) {
-					if !v[c] {
-						fmt.Fprintf(os.Stderr, "unicode.%s[%q] contains %#U, should not\n", name, k, c)
-					}
-					n++
-				}
-			}
-			for _, r := range t.R32 {
-				for c := rune(r.Lo); c <= rune(r.Hi); c += rune(r.Stride) {
-					if !v[c] {
-						fmt.Fprintf(os.Stderr, "unicode.%s[%q] contains %#U, should not\n", name, k, c)
-					}
-					n++
-				}
-			}
-			if n != len(v) {
-				fmt.Fprintf(os.Stderr, "unicode.%s[%q] has %d code points, want %d\n", name, k, n, len(v))
-			}
-		}
-		return
-	}
-
-	fmt.Print(comment[name])
-	fmt.Printf("var %s = map[string]*RangeTable{\n", name)
-	for _, name := range allCatFold(m) {
-		fmt.Printf("\t%q: fold%s,\n", name, name)
-	}
-	fmt.Printf("}\n\n")
-	for _, name := range allCatFold(m) {
-		class := m[name]
-		dumpRange(
-			fmt.Sprintf("var fold%s = &RangeTable{\n", name),
-			func(code rune) bool { return class[code] })
-	}
-}
-
-var range16Count = 0  // Number of entries in the 16-bit range tables.
-var range32Count = 0  // Number of entries in the 32-bit range tables.
-var foldPairCount = 0 // Number of fold pairs in the exception tables.
-
-func printSizes() {
-	if *test {
-		return
-	}
-	fmt.Println()
-	fmt.Printf("// Range entries: %d 16-bit, %d 32-bit, %d total.\n", range16Count, range32Count, range16Count+range32Count)
-	range16Bytes := range16Count * 3 * 2
-	range32Bytes := range32Count * 3 * 4
-	fmt.Printf("// Range bytes: %d 16-bit, %d 32-bit, %d total.\n", range16Bytes, range32Bytes, range16Bytes+range32Bytes)
-	fmt.Println()
-	fmt.Printf("// Fold orbit bytes: %d pairs, %d bytes\n", foldPairCount, foldPairCount*2*2)
-}
diff --git a/src/pkg/unicode/script_test.go b/src/pkg/unicode/script_test.go
deleted file mode 100644
index e2ba001..0000000
--- a/src/pkg/unicode/script_test.go
+++ /dev/null
@@ -1,264 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package unicode_test
-
-import (
-	"testing"
-	. "unicode"
-)
-
-type T struct {
-	rune   rune
-	script string
-}
-
-// Hand-chosen tests from Unicode 5.1.0, 6.0.0 and 6.2.0 mostly to discover when new
-// scripts and categories arise.
-var inTest = []T{
-	{0x06e2, "Arabic"},
-	{0x0567, "Armenian"},
-	{0x10b20, "Avestan"},
-	{0x1b37, "Balinese"},
-	{0xa6af, "Bamum"},
-	{0x1be1, "Batak"},
-	{0x09c2, "Bengali"},
-	{0x3115, "Bopomofo"},
-	{0x282d, "Braille"},
-	{0x1a1a, "Buginese"},
-	{0x1747, "Buhid"},
-	{0x11011, "Brahmi"},
-	{0x156d, "Canadian_Aboriginal"},
-	{0x102a9, "Carian"},
-	{0x11111, "Chakma"},
-	{0xaa4d, "Cham"},
-	{0x13c2, "Cherokee"},
-	{0x0020, "Common"},
-	{0x1d4a5, "Common"},
-	{0x2cfc, "Coptic"},
-	{0x12420, "Cuneiform"},
-	{0x1080c, "Cypriot"},
-	{0xa663, "Cyrillic"},
-	{0x10430, "Deseret"},
-	{0x094a, "Devanagari"},
-	{0x13001, "Egyptian_Hieroglyphs"},
-	{0x1271, "Ethiopic"},
-	{0x10fc, "Georgian"},
-	{0x2c40, "Glagolitic"},
-	{0x10347, "Gothic"},
-	{0x03ae, "Greek"},
-	{0x0abf, "Gujarati"},
-	{0x0a24, "Gurmukhi"},
-	{0x3028, "Han"},
-	{0x11b8, "Hangul"},
-	{0x1727, "Hanunoo"},
-	{0x05a0, "Hebrew"},
-	{0x3058, "Hiragana"},
-	{0x10841, "Imperial_Aramaic"},
-	{0x20e6, "Inherited"},
-	{0x10b70, "Inscriptional_Pahlavi"},
-	{0x10b5a, "Inscriptional_Parthian"},
-	{0xa9d0, "Javanese"},
-	{0x1109f, "Kaithi"},
-	{0x0cbd, "Kannada"},
-	{0x30a6, "Katakana"},
-	{0xa928, "Kayah_Li"},
-	{0x10a11, "Kharoshthi"},
-	{0x17c6, "Khmer"},
-	{0x0eaa, "Lao"},
-	{0x1d79, "Latin"},
-	{0x1c10, "Lepcha"},
-	{0x1930, "Limbu"},
-	{0x1003c, "Linear_B"},
-	{0xa4e1, "Lisu"},
-	{0x10290, "Lycian"},
-	{0x10930, "Lydian"},
-	{0x0d42, "Malayalam"},
-	{0x0843, "Mandaic"},
-	{0xabd0, "Meetei_Mayek"},
-	{0x1099f, "Meroitic_Hieroglyphs"},
-	{0x109a0, "Meroitic_Cursive"},
-	{0x16f00, "Miao"},
-	{0x1822, "Mongolian"},
-	{0x104c, "Myanmar"},
-	{0x19c3, "New_Tai_Lue"},
-	{0x07f8, "Nko"},
-	{0x169b, "Ogham"},
-	{0x1c6a, "Ol_Chiki"},
-	{0x10310, "Old_Italic"},
-	{0x103c9, "Old_Persian"},
-	{0x10a6f, "Old_South_Arabian"},
-	{0x10c20, "Old_Turkic"},
-	{0x0b3e, "Oriya"},
-	{0x10491, "Osmanya"},
-	{0xa860, "Phags_Pa"},
-	{0x10918, "Phoenician"},
-	{0xa949, "Rejang"},
-	{0x16c0, "Runic"},
-	{0x081d, "Samaritan"},
-	{0xa892, "Saurashtra"},
-	{0x111a0, "Sharada"},
-	{0x10463, "Shavian"},
-	{0x0dbd, "Sinhala"},
-	{0x110d0, "Sora_Sompeng"},
-	{0x1ba3, "Sundanese"},
-	{0xa803, "Syloti_Nagri"},
-	{0x070f, "Syriac"},
-	{0x170f, "Tagalog"},
-	{0x176f, "Tagbanwa"},
-	{0x1972, "Tai_Le"},
-	{0x1a62, "Tai_Tham"},
-	{0xaadc, "Tai_Viet"},
-	{0x116c9, "Takri"},
-	{0x0bbf, "Tamil"},
-	{0x0c55, "Telugu"},
-	{0x07a7, "Thaana"},
-	{0x0e46, "Thai"},
-	{0x0f36, "Tibetan"},
-	{0x2d55, "Tifinagh"},
-	{0x10388, "Ugaritic"},
-	{0xa60e, "Vai"},
-	{0xa216, "Yi"},
-}
-
-var outTest = []T{ // not really worth being thorough
-	{0x20, "Telugu"},
-}
-
-var inCategoryTest = []T{
-	{0x0081, "Cc"},
-	{0x200B, "Cf"},
-	{0xf0000, "Co"},
-	{0xdb80, "Cs"},
-	{0x0236, "Ll"},
-	{0x1d9d, "Lm"},
-	{0x07cf, "Lo"},
-	{0x1f8a, "Lt"},
-	{0x03ff, "Lu"},
-	{0x0bc1, "Mc"},
-	{0x20df, "Me"},
-	{0x07f0, "Mn"},
-	{0x1bb2, "Nd"},
-	{0x10147, "Nl"},
-	{0x2478, "No"},
-	{0xfe33, "Pc"},
-	{0x2011, "Pd"},
-	{0x301e, "Pe"},
-	{0x2e03, "Pf"},
-	{0x2e02, "Pi"},
-	{0x0022, "Po"},
-	{0x2770, "Ps"},
-	{0x00a4, "Sc"},
-	{0xa711, "Sk"},
-	{0x25f9, "Sm"},
-	{0x2108, "So"},
-	{0x2028, "Zl"},
-	{0x2029, "Zp"},
-	{0x202f, "Zs"},
-	// Unifieds.
-	{0x04aa, "L"},
-	{0x0009, "C"},
-	{0x1712, "M"},
-	{0x0031, "N"},
-	{0x00bb, "P"},
-	{0x00a2, "S"},
-	{0x00a0, "Z"},
-}
-
-var inPropTest = []T{
-	{0x0046, "ASCII_Hex_Digit"},
-	{0x200F, "Bidi_Control"},
-	{0x2212, "Dash"},
-	{0xE0001, "Deprecated"},
-	{0x00B7, "Diacritic"},
-	{0x30FE, "Extender"},
-	{0xFF46, "Hex_Digit"},
-	{0x2E17, "Hyphen"},
-	{0x2FFB, "IDS_Binary_Operator"},
-	{0x2FF3, "IDS_Trinary_Operator"},
-	{0xFA6A, "Ideographic"},
-	{0x200D, "Join_Control"},
-	{0x0EC4, "Logical_Order_Exception"},
-	{0x2FFFF, "Noncharacter_Code_Point"},
-	{0x065E, "Other_Alphabetic"},
-	{0x2065, "Other_Default_Ignorable_Code_Point"},
-	{0x0BD7, "Other_Grapheme_Extend"},
-	{0x0387, "Other_ID_Continue"},
-	{0x212E, "Other_ID_Start"},
-	{0x2094, "Other_Lowercase"},
-	{0x2040, "Other_Math"},
-	{0x216F, "Other_Uppercase"},
-	{0x0027, "Pattern_Syntax"},
-	{0x0020, "Pattern_White_Space"},
-	{0x300D, "Quotation_Mark"},
-	{0x2EF3, "Radical"},
-	{0x061F, "STerm"},
-	{0x2071, "Soft_Dotted"},
-	{0x003A, "Terminal_Punctuation"},
-	{0x9FC3, "Unified_Ideograph"},
-	{0xFE0F, "Variation_Selector"},
-	{0x0020, "White_Space"},
-}
-
-func TestScripts(t *testing.T) {
-	notTested := make(map[string]bool)
-	for k := range Scripts {
-		notTested[k] = true
-	}
-	for _, test := range inTest {
-		if _, ok := Scripts[test.script]; !ok {
-			t.Fatal(test.script, "not a known script")
-		}
-		if !Is(Scripts[test.script], test.rune) {
-			t.Errorf("IsScript(%U, %s) = false, want true", test.rune, test.script)
-		}
-		delete(notTested, test.script)
-	}
-	for _, test := range outTest {
-		if Is(Scripts[test.script], test.rune) {
-			t.Errorf("IsScript(%U, %s) = true, want false", test.rune, test.script)
-		}
-	}
-	for k := range notTested {
-		t.Error("script not tested:", k)
-	}
-}
-
-func TestCategories(t *testing.T) {
-	notTested := make(map[string]bool)
-	for k := range Categories {
-		notTested[k] = true
-	}
-	for _, test := range inCategoryTest {
-		if _, ok := Categories[test.script]; !ok {
-			t.Fatal(test.script, "not a known category")
-		}
-		if !Is(Categories[test.script], test.rune) {
-			t.Errorf("IsCategory(%U, %s) = false, want true", test.rune, test.script)
-		}
-		delete(notTested, test.script)
-	}
-	for k := range notTested {
-		t.Error("category not tested:", k)
-	}
-}
-
-func TestProperties(t *testing.T) {
-	notTested := make(map[string]bool)
-	for k := range Properties {
-		notTested[k] = true
-	}
-	for _, test := range inPropTest {
-		if _, ok := Properties[test.script]; !ok {
-			t.Fatal(test.script, "not a known prop")
-		}
-		if !Is(Properties[test.script], test.rune) {
-			t.Errorf("IsCategory(%U, %s) = false, want true", test.rune, test.script)
-		}
-		delete(notTested, test.script)
-	}
-	for k := range notTested {
-		t.Error("property not tested:", k)
-	}
-}
diff --git a/src/pkg/unicode/tables.go b/src/pkg/unicode/tables.go
deleted file mode 100644
index 5670d1c..0000000
--- a/src/pkg/unicode/tables.go
+++ /dev/null
@@ -1,6391 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Generated by running
-//	maketables --tables=all --data=http://www.unicode.org/Public/6.3.0/ucd/UnicodeData.txt --casefolding=http://www.unicode.org/Public/6.3.0/ucd/CaseFolding.txt
-// DO NOT EDIT
-
-package unicode
-
-// Version is the Unicode edition from which the tables are derived.
-const Version = "6.3.0"
-
-// Categories is the set of Unicode category tables.
-var Categories = map[string]*RangeTable{
-	"C":  C,
-	"Cc": Cc,
-	"Cf": Cf,
-	"Co": Co,
-	"Cs": Cs,
-	"L":  L,
-	"Ll": Ll,
-	"Lm": Lm,
-	"Lo": Lo,
-	"Lt": Lt,
-	"Lu": Lu,
-	"M":  M,
-	"Mc": Mc,
-	"Me": Me,
-	"Mn": Mn,
-	"N":  N,
-	"Nd": Nd,
-	"Nl": Nl,
-	"No": No,
-	"P":  P,
-	"Pc": Pc,
-	"Pd": Pd,
-	"Pe": Pe,
-	"Pf": Pf,
-	"Pi": Pi,
-	"Po": Po,
-	"Ps": Ps,
-	"S":  S,
-	"Sc": Sc,
-	"Sk": Sk,
-	"Sm": Sm,
-	"So": So,
-	"Z":  Z,
-	"Zl": Zl,
-	"Zp": Zp,
-	"Zs": Zs,
-}
-
-var _C = &RangeTable{
-	R16: []Range16{
-		{0x0001, 0x001f, 1},
-		{0x007f, 0x009f, 1},
-		{0x00ad, 0x0600, 1363},
-		{0x0601, 0x0604, 1},
-		{0x061c, 0x06dd, 193},
-		{0x070f, 0x180e, 4351},
-		{0x200b, 0x200f, 1},
-		{0x202a, 0x202e, 1},
-		{0x2060, 0x2064, 1},
-		{0x2066, 0x206f, 1},
-		{0xd800, 0xf8ff, 1},
-		{0xfeff, 0xfff9, 250},
-		{0xfffa, 0xfffb, 1},
-	},
-	R32: []Range32{
-		{0x110bd, 0x1d173, 49334},
-		{0x1d174, 0x1d17a, 1},
-		{0xe0001, 0xe0020, 31},
-		{0xe0021, 0xe007f, 1},
-		{0xf0000, 0xffffd, 1},
-		{0x100000, 0x10fffd, 1},
-	},
-	LatinOffset: 2,
-}
-
-var _Cc = &RangeTable{
-	R16: []Range16{
-		{0x0001, 0x001f, 1},
-		{0x007f, 0x009f, 1},
-	},
-	LatinOffset: 2,
-}
-
-var _Cf = &RangeTable{
-	R16: []Range16{
-		{0x00ad, 0x0600, 1363},
-		{0x0601, 0x0604, 1},
-		{0x061c, 0x06dd, 193},
-		{0x070f, 0x180e, 4351},
-		{0x200b, 0x200f, 1},
-		{0x202a, 0x202e, 1},
-		{0x2060, 0x2064, 1},
-		{0x2066, 0x206f, 1},
-		{0xfeff, 0xfff9, 250},
-		{0xfffa, 0xfffb, 1},
-	},
-	R32: []Range32{
-		{0x110bd, 0x1d173, 49334},
-		{0x1d174, 0x1d17a, 1},
-		{0xe0001, 0xe0020, 31},
-		{0xe0021, 0xe007f, 1},
-	},
-}
-
-var _Co = &RangeTable{
-	R16: []Range16{
-		{0xe000, 0xf8ff, 1},
-	},
-	R32: []Range32{
-		{0xf0000, 0xffffd, 1},
-		{0x100000, 0x10fffd, 1},
-	},
-}
-
-var _Cs = &RangeTable{
-	R16: []Range16{
-		{0xd800, 0xdfff, 1},
-	},
-}
-
-var _L = &RangeTable{
-	R16: []Range16{
-		{0x0041, 0x005a, 1},
-		{0x0061, 0x007a, 1},
-		{0x00aa, 0x00b5, 11},
-		{0x00ba, 0x00c0, 6},
-		{0x00c1, 0x00d6, 1},
-		{0x00d8, 0x00f6, 1},
-		{0x00f8, 0x02c1, 1},
-		{0x02c6, 0x02d1, 1},
-		{0x02e0, 0x02e4, 1},
-		{0x02ec, 0x02ee, 2},
-		{0x0370, 0x0374, 1},
-		{0x0376, 0x0377, 1},
-		{0x037a, 0x037d, 1},
-		{0x0386, 0x0388, 2},
-		{0x0389, 0x038a, 1},
-		{0x038c, 0x038e, 2},
-		{0x038f, 0x03a1, 1},
-		{0x03a3, 0x03f5, 1},
-		{0x03f7, 0x0481, 1},
-		{0x048a, 0x0527, 1},
-		{0x0531, 0x0556, 1},
-		{0x0559, 0x0561, 8},
-		{0x0562, 0x0587, 1},
-		{0x05d0, 0x05ea, 1},
-		{0x05f0, 0x05f2, 1},
-		{0x0620, 0x064a, 1},
-		{0x066e, 0x066f, 1},
-		{0x0671, 0x06d3, 1},
-		{0x06d5, 0x06e5, 16},
-		{0x06e6, 0x06ee, 8},
-		{0x06ef, 0x06fa, 11},
-		{0x06fb, 0x06fc, 1},
-		{0x06ff, 0x0710, 17},
-		{0x0712, 0x072f, 1},
-		{0x074d, 0x07a5, 1},
-		{0x07b1, 0x07ca, 25},
-		{0x07cb, 0x07ea, 1},
-		{0x07f4, 0x07f5, 1},
-		{0x07fa, 0x0800, 6},
-		{0x0801, 0x0815, 1},
-		{0x081a, 0x0824, 10},
-		{0x0828, 0x0840, 24},
-		{0x0841, 0x0858, 1},
-		{0x08a0, 0x08a2, 2},
-		{0x08a3, 0x08ac, 1},
-		{0x0904, 0x0939, 1},
-		{0x093d, 0x0950, 19},
-		{0x0958, 0x0961, 1},
-		{0x0971, 0x0977, 1},
-		{0x0979, 0x097f, 1},
-		{0x0985, 0x098c, 1},
-		{0x098f, 0x0990, 1},
-		{0x0993, 0x09a8, 1},
-		{0x09aa, 0x09b0, 1},
-		{0x09b2, 0x09b6, 4},
-		{0x09b7, 0x09b9, 1},
-		{0x09bd, 0x09ce, 17},
-		{0x09dc, 0x09dd, 1},
-		{0x09df, 0x09e1, 1},
-		{0x09f0, 0x09f1, 1},
-		{0x0a05, 0x0a0a, 1},
-		{0x0a0f, 0x0a10, 1},
-		{0x0a13, 0x0a28, 1},
-		{0x0a2a, 0x0a30, 1},
-		{0x0a32, 0x0a33, 1},
-		{0x0a35, 0x0a36, 1},
-		{0x0a38, 0x0a39, 1},
-		{0x0a59, 0x0a5c, 1},
-		{0x0a5e, 0x0a72, 20},
-		{0x0a73, 0x0a74, 1},
-		{0x0a85, 0x0a8d, 1},
-		{0x0a8f, 0x0a91, 1},
-		{0x0a93, 0x0aa8, 1},
-		{0x0aaa, 0x0ab0, 1},
-		{0x0ab2, 0x0ab3, 1},
-		{0x0ab5, 0x0ab9, 1},
-		{0x0abd, 0x0ad0, 19},
-		{0x0ae0, 0x0ae1, 1},
-		{0x0b05, 0x0b0c, 1},
-		{0x0b0f, 0x0b10, 1},
-		{0x0b13, 0x0b28, 1},
-		{0x0b2a, 0x0b30, 1},
-		{0x0b32, 0x0b33, 1},
-		{0x0b35, 0x0b39, 1},
-		{0x0b3d, 0x0b5c, 31},
-		{0x0b5d, 0x0b5f, 2},
-		{0x0b60, 0x0b61, 1},
-		{0x0b71, 0x0b83, 18},
-		{0x0b85, 0x0b8a, 1},
-		{0x0b8e, 0x0b90, 1},
-		{0x0b92, 0x0b95, 1},
-		{0x0b99, 0x0b9a, 1},
-		{0x0b9c, 0x0b9e, 2},
-		{0x0b9f, 0x0ba3, 4},
-		{0x0ba4, 0x0ba8, 4},
-		{0x0ba9, 0x0baa, 1},
-		{0x0bae, 0x0bb9, 1},
-		{0x0bd0, 0x0c05, 53},
-		{0x0c06, 0x0c0c, 1},
-		{0x0c0e, 0x0c10, 1},
-		{0x0c12, 0x0c28, 1},
-		{0x0c2a, 0x0c33, 1},
-		{0x0c35, 0x0c39, 1},
-		{0x0c3d, 0x0c58, 27},
-		{0x0c59, 0x0c60, 7},
-		{0x0c61, 0x0c85, 36},
-		{0x0c86, 0x0c8c, 1},
-		{0x0c8e, 0x0c90, 1},
-		{0x0c92, 0x0ca8, 1},
-		{0x0caa, 0x0cb3, 1},
-		{0x0cb5, 0x0cb9, 1},
-		{0x0cbd, 0x0cde, 33},
-		{0x0ce0, 0x0ce1, 1},
-		{0x0cf1, 0x0cf2, 1},
-		{0x0d05, 0x0d0c, 1},
-		{0x0d0e, 0x0d10, 1},
-		{0x0d12, 0x0d3a, 1},
-		{0x0d3d, 0x0d4e, 17},
-		{0x0d60, 0x0d61, 1},
-		{0x0d7a, 0x0d7f, 1},
-		{0x0d85, 0x0d96, 1},
-		{0x0d9a, 0x0db1, 1},
-		{0x0db3, 0x0dbb, 1},
-		{0x0dbd, 0x0dc0, 3},
-		{0x0dc1, 0x0dc6, 1},
-		{0x0e01, 0x0e30, 1},
-		{0x0e32, 0x0e33, 1},
-		{0x0e40, 0x0e46, 1},
-		{0x0e81, 0x0e82, 1},
-		{0x0e84, 0x0e87, 3},
-		{0x0e88, 0x0e8a, 2},
-		{0x0e8d, 0x0e94, 7},
-		{0x0e95, 0x0e97, 1},
-		{0x0e99, 0x0e9f, 1},
-		{0x0ea1, 0x0ea3, 1},
-		{0x0ea5, 0x0ea7, 2},
-		{0x0eaa, 0x0eab, 1},
-		{0x0ead, 0x0eb0, 1},
-		{0x0eb2, 0x0eb3, 1},
-		{0x0ebd, 0x0ec0, 3},
-		{0x0ec1, 0x0ec4, 1},
-		{0x0ec6, 0x0edc, 22},
-		{0x0edd, 0x0edf, 1},
-		{0x0f00, 0x0f40, 64},
-		{0x0f41, 0x0f47, 1},
-		{0x0f49, 0x0f6c, 1},
-		{0x0f88, 0x0f8c, 1},
-		{0x1000, 0x102a, 1},
-		{0x103f, 0x1050, 17},
-		{0x1051, 0x1055, 1},
-		{0x105a, 0x105d, 1},
-		{0x1061, 0x1065, 4},
-		{0x1066, 0x106e, 8},
-		{0x106f, 0x1070, 1},
-		{0x1075, 0x1081, 1},
-		{0x108e, 0x10a0, 18},
-		{0x10a1, 0x10c5, 1},
-		{0x10c7, 0x10cd, 6},
-		{0x10d0, 0x10fa, 1},
-		{0x10fc, 0x1248, 1},
-		{0x124a, 0x124d, 1},
-		{0x1250, 0x1256, 1},
-		{0x1258, 0x125a, 2},
-		{0x125b, 0x125d, 1},
-		{0x1260, 0x1288, 1},
-		{0x128a, 0x128d, 1},
-		{0x1290, 0x12b0, 1},
-		{0x12b2, 0x12b5, 1},
-		{0x12b8, 0x12be, 1},
-		{0x12c0, 0x12c2, 2},
-		{0x12c3, 0x12c5, 1},
-		{0x12c8, 0x12d6, 1},
-		{0x12d8, 0x1310, 1},
-		{0x1312, 0x1315, 1},
-		{0x1318, 0x135a, 1},
-		{0x1380, 0x138f, 1},
-		{0x13a0, 0x13f4, 1},
-		{0x1401, 0x166c, 1},
-		{0x166f, 0x167f, 1},
-		{0x1681, 0x169a, 1},
-		{0x16a0, 0x16ea, 1},
-		{0x1700, 0x170c, 1},
-		{0x170e, 0x1711, 1},
-		{0x1720, 0x1731, 1},
-		{0x1740, 0x1751, 1},
-		{0x1760, 0x176c, 1},
-		{0x176e, 0x1770, 1},
-		{0x1780, 0x17b3, 1},
-		{0x17d7, 0x17dc, 5},
-		{0x1820, 0x1877, 1},
-		{0x1880, 0x18a8, 1},
-		{0x18aa, 0x18b0, 6},
-		{0x18b1, 0x18f5, 1},
-		{0x1900, 0x191c, 1},
-		{0x1950, 0x196d, 1},
-		{0x1970, 0x1974, 1},
-		{0x1980, 0x19ab, 1},
-		{0x19c1, 0x19c7, 1},
-		{0x1a00, 0x1a16, 1},
-		{0x1a20, 0x1a54, 1},
-		{0x1aa7, 0x1b05, 94},
-		{0x1b06, 0x1b33, 1},
-		{0x1b45, 0x1b4b, 1},
-		{0x1b83, 0x1ba0, 1},
-		{0x1bae, 0x1baf, 1},
-		{0x1bba, 0x1be5, 1},
-		{0x1c00, 0x1c23, 1},
-		{0x1c4d, 0x1c4f, 1},
-		{0x1c5a, 0x1c7d, 1},
-		{0x1ce9, 0x1cec, 1},
-		{0x1cee, 0x1cf1, 1},
-		{0x1cf5, 0x1cf6, 1},
-		{0x1d00, 0x1dbf, 1},
-		{0x1e00, 0x1f15, 1},
-		{0x1f18, 0x1f1d, 1},
-		{0x1f20, 0x1f45, 1},
-		{0x1f48, 0x1f4d, 1},
-		{0x1f50, 0x1f57, 1},
-		{0x1f59, 0x1f5f, 2},
-		{0x1f60, 0x1f7d, 1},
-		{0x1f80, 0x1fb4, 1},
-		{0x1fb6, 0x1fbc, 1},
-		{0x1fbe, 0x1fc2, 4},
-		{0x1fc3, 0x1fc4, 1},
-		{0x1fc6, 0x1fcc, 1},
-		{0x1fd0, 0x1fd3, 1},
-		{0x1fd6, 0x1fdb, 1},
-		{0x1fe0, 0x1fec, 1},
-		{0x1ff2, 0x1ff4, 1},
-		{0x1ff6, 0x1ffc, 1},
-		{0x2071, 0x207f, 14},
-		{0x2090, 0x209c, 1},
-		{0x2102, 0x2107, 5},
-		{0x210a, 0x2113, 1},
-		{0x2115, 0x2119, 4},
-		{0x211a, 0x211d, 1},
-		{0x2124, 0x212a, 2},
-		{0x212b, 0x212d, 1},
-		{0x212f, 0x2139, 1},
-		{0x213c, 0x213f, 1},
-		{0x2145, 0x2149, 1},
-		{0x214e, 0x2183, 53},
-		{0x2184, 0x2c00, 2684},
-		{0x2c01, 0x2c2e, 1},
-		{0x2c30, 0x2c5e, 1},
-		{0x2c60, 0x2ce4, 1},
-		{0x2ceb, 0x2cee, 1},
-		{0x2cf2, 0x2cf3, 1},
-		{0x2d00, 0x2d25, 1},
-		{0x2d27, 0x2d2d, 6},
-		{0x2d30, 0x2d67, 1},
-		{0x2d6f, 0x2d80, 17},
-		{0x2d81, 0x2d96, 1},
-		{0x2da0, 0x2da6, 1},
-		{0x2da8, 0x2dae, 1},
-		{0x2db0, 0x2db6, 1},
-		{0x2db8, 0x2dbe, 1},
-		{0x2dc0, 0x2dc6, 1},
-		{0x2dc8, 0x2dce, 1},
-		{0x2dd0, 0x2dd6, 1},
-		{0x2dd8, 0x2dde, 1},
-		{0x2e2f, 0x3005, 470},
-		{0x3006, 0x3031, 43},
-		{0x3032, 0x3035, 1},
-		{0x303b, 0x303c, 1},
-		{0x3041, 0x3096, 1},
-		{0x309d, 0x309f, 1},
-		{0x30a1, 0x30fa, 1},
-		{0x30fc, 0x30ff, 1},
-		{0x3105, 0x312d, 1},
-		{0x3131, 0x318e, 1},
-		{0x31a0, 0x31ba, 1},
-		{0x31f0, 0x31ff, 1},
-		{0x3400, 0x4db5, 1},
-		{0x4e00, 0x9fcc, 1},
-		{0xa000, 0xa48c, 1},
-		{0xa4d0, 0xa4fd, 1},
-		{0xa500, 0xa60c, 1},
-		{0xa610, 0xa61f, 1},
-		{0xa62a, 0xa62b, 1},
-		{0xa640, 0xa66e, 1},
-		{0xa67f, 0xa697, 1},
-		{0xa6a0, 0xa6e5, 1},
-		{0xa717, 0xa71f, 1},
-		{0xa722, 0xa788, 1},
-		{0xa78b, 0xa78e, 1},
-		{0xa790, 0xa793, 1},
-		{0xa7a0, 0xa7aa, 1},
-		{0xa7f8, 0xa801, 1},
-		{0xa803, 0xa805, 1},
-		{0xa807, 0xa80a, 1},
-		{0xa80c, 0xa822, 1},
-		{0xa840, 0xa873, 1},
-		{0xa882, 0xa8b3, 1},
-		{0xa8f2, 0xa8f7, 1},
-		{0xa8fb, 0xa90a, 15},
-		{0xa90b, 0xa925, 1},
-		{0xa930, 0xa946, 1},
-		{0xa960, 0xa97c, 1},
-		{0xa984, 0xa9b2, 1},
-		{0xa9cf, 0xaa00, 49},
-		{0xaa01, 0xaa28, 1},
-		{0xaa40, 0xaa42, 1},
-		{0xaa44, 0xaa4b, 1},
-		{0xaa60, 0xaa76, 1},
-		{0xaa7a, 0xaa80, 6},
-		{0xaa81, 0xaaaf, 1},
-		{0xaab1, 0xaab5, 4},
-		{0xaab6, 0xaab9, 3},
-		{0xaaba, 0xaabd, 1},
-		{0xaac0, 0xaac2, 2},
-		{0xaadb, 0xaadd, 1},
-		{0xaae0, 0xaaea, 1},
-		{0xaaf2, 0xaaf4, 1},
-		{0xab01, 0xab06, 1},
-		{0xab09, 0xab0e, 1},
-		{0xab11, 0xab16, 1},
-		{0xab20, 0xab26, 1},
-		{0xab28, 0xab2e, 1},
-		{0xabc0, 0xabe2, 1},
-		{0xac00, 0xd7a3, 1},
-		{0xd7b0, 0xd7c6, 1},
-		{0xd7cb, 0xd7fb, 1},
-		{0xf900, 0xfa6d, 1},
-		{0xfa70, 0xfad9, 1},
-		{0xfb00, 0xfb06, 1},
-		{0xfb13, 0xfb17, 1},
-		{0xfb1d, 0xfb1f, 2},
-		{0xfb20, 0xfb28, 1},
-		{0xfb2a, 0xfb36, 1},
-		{0xfb38, 0xfb3c, 1},
-		{0xfb3e, 0xfb40, 2},
-		{0xfb41, 0xfb43, 2},
-		{0xfb44, 0xfb46, 2},
-		{0xfb47, 0xfbb1, 1},
-		{0xfbd3, 0xfd3d, 1},
-		{0xfd50, 0xfd8f, 1},
-		{0xfd92, 0xfdc7, 1},
-		{0xfdf0, 0xfdfb, 1},
-		{0xfe70, 0xfe74, 1},
-		{0xfe76, 0xfefc, 1},
-		{0xff21, 0xff3a, 1},
-		{0xff41, 0xff5a, 1},
-		{0xff66, 0xffbe, 1},
-		{0xffc2, 0xffc7, 1},
-		{0xffca, 0xffcf, 1},
-		{0xffd2, 0xffd7, 1},
-		{0xffda, 0xffdc, 1},
-	},
-	R32: []Range32{
-		{0x10000, 0x1000b, 1},
-		{0x1000d, 0x10026, 1},
-		{0x10028, 0x1003a, 1},
-		{0x1003c, 0x1003d, 1},
-		{0x1003f, 0x1004d, 1},
-		{0x10050, 0x1005d, 1},
-		{0x10080, 0x100fa, 1},
-		{0x10280, 0x1029c, 1},
-		{0x102a0, 0x102d0, 1},
-		{0x10300, 0x1031e, 1},
-		{0x10330, 0x10340, 1},
-		{0x10342, 0x10349, 1},
-		{0x10380, 0x1039d, 1},
-		{0x103a0, 0x103c3, 1},
-		{0x103c8, 0x103cf, 1},
-		{0x10400, 0x1049d, 1},
-		{0x10800, 0x10805, 1},
-		{0x10808, 0x1080a, 2},
-		{0x1080b, 0x10835, 1},
-		{0x10837, 0x10838, 1},
-		{0x1083c, 0x1083f, 3},
-		{0x10840, 0x10855, 1},
-		{0x10900, 0x10915, 1},
-		{0x10920, 0x10939, 1},
-		{0x10980, 0x109b7, 1},
-		{0x109be, 0x109bf, 1},
-		{0x10a00, 0x10a10, 16},
-		{0x10a11, 0x10a13, 1},
-		{0x10a15, 0x10a17, 1},
-		{0x10a19, 0x10a33, 1},
-		{0x10a60, 0x10a7c, 1},
-		{0x10b00, 0x10b35, 1},
-		{0x10b40, 0x10b55, 1},
-		{0x10b60, 0x10b72, 1},
-		{0x10c00, 0x10c48, 1},
-		{0x11003, 0x11037, 1},
-		{0x11083, 0x110af, 1},
-		{0x110d0, 0x110e8, 1},
-		{0x11103, 0x11126, 1},
-		{0x11183, 0x111b2, 1},
-		{0x111c1, 0x111c4, 1},
-		{0x11680, 0x116aa, 1},
-		{0x12000, 0x1236e, 1},
-		{0x13000, 0x1342e, 1},
-		{0x16800, 0x16a38, 1},
-		{0x16f00, 0x16f44, 1},
-		{0x16f50, 0x16f93, 67},
-		{0x16f94, 0x16f9f, 1},
-		{0x1b000, 0x1b001, 1},
-		{0x1d400, 0x1d454, 1},
-		{0x1d456, 0x1d49c, 1},
-		{0x1d49e, 0x1d49f, 1},
-		{0x1d4a2, 0x1d4a5, 3},
-		{0x1d4a6, 0x1d4a9, 3},
-		{0x1d4aa, 0x1d4ac, 1},
-		{0x1d4ae, 0x1d4b9, 1},
-		{0x1d4bb, 0x1d4bd, 2},
-		{0x1d4be, 0x1d4c3, 1},
-		{0x1d4c5, 0x1d505, 1},
-		{0x1d507, 0x1d50a, 1},
-		{0x1d50d, 0x1d514, 1},
-		{0x1d516, 0x1d51c, 1},
-		{0x1d51e, 0x1d539, 1},
-		{0x1d53b, 0x1d53e, 1},
-		{0x1d540, 0x1d544, 1},
-		{0x1d546, 0x1d54a, 4},
-		{0x1d54b, 0x1d550, 1},
-		{0x1d552, 0x1d6a5, 1},
-		{0x1d6a8, 0x1d6c0, 1},
-		{0x1d6c2, 0x1d6da, 1},
-		{0x1d6dc, 0x1d6fa, 1},
-		{0x1d6fc, 0x1d714, 1},
-		{0x1d716, 0x1d734, 1},
-		{0x1d736, 0x1d74e, 1},
-		{0x1d750, 0x1d76e, 1},
-		{0x1d770, 0x1d788, 1},
-		{0x1d78a, 0x1d7a8, 1},
-		{0x1d7aa, 0x1d7c2, 1},
-		{0x1d7c4, 0x1d7cb, 1},
-		{0x1ee00, 0x1ee03, 1},
-		{0x1ee05, 0x1ee1f, 1},
-		{0x1ee21, 0x1ee22, 1},
-		{0x1ee24, 0x1ee27, 3},
-		{0x1ee29, 0x1ee32, 1},
-		{0x1ee34, 0x1ee37, 1},
-		{0x1ee39, 0x1ee3b, 2},
-		{0x1ee42, 0x1ee47, 5},
-		{0x1ee49, 0x1ee4d, 2},
-		{0x1ee4e, 0x1ee4f, 1},
-		{0x1ee51, 0x1ee52, 1},
-		{0x1ee54, 0x1ee57, 3},
-		{0x1ee59, 0x1ee61, 2},
-		{0x1ee62, 0x1ee64, 2},
-		{0x1ee67, 0x1ee6a, 1},
-		{0x1ee6c, 0x1ee72, 1},
-		{0x1ee74, 0x1ee77, 1},
-		{0x1ee79, 0x1ee7c, 1},
-		{0x1ee7e, 0x1ee80, 2},
-		{0x1ee81, 0x1ee89, 1},
-		{0x1ee8b, 0x1ee9b, 1},
-		{0x1eea1, 0x1eea3, 1},
-		{0x1eea5, 0x1eea9, 1},
-		{0x1eeab, 0x1eebb, 1},
-		{0x20000, 0x2a6d6, 1},
-		{0x2a700, 0x2b734, 1},
-		{0x2b740, 0x2b81d, 1},
-		{0x2f800, 0x2fa1d, 1},
-	},
-	LatinOffset: 6,
-}
-
-var _Ll = &RangeTable{
-	R16: []Range16{
-		{0x0061, 0x007a, 1},
-		{0x00b5, 0x00df, 42},
-		{0x00e0, 0x00f6, 1},
-		{0x00f8, 0x00ff, 1},
-		{0x0101, 0x0137, 2},
-		{0x0138, 0x0148, 2},
-		{0x0149, 0x0177, 2},
-		{0x017a, 0x017e, 2},
-		{0x017f, 0x0180, 1},
-		{0x0183, 0x0185, 2},
-		{0x0188, 0x018c, 4},
-		{0x018d, 0x0192, 5},
-		{0x0195, 0x0199, 4},
-		{0x019a, 0x019b, 1},
-		{0x019e, 0x01a1, 3},
-		{0x01a3, 0x01a5, 2},
-		{0x01a8, 0x01aa, 2},
-		{0x01ab, 0x01ad, 2},
-		{0x01b0, 0x01b4, 4},
-		{0x01b6, 0x01b9, 3},
-		{0x01ba, 0x01bd, 3},
-		{0x01be, 0x01bf, 1},
-		{0x01c6, 0x01cc, 3},
-		{0x01ce, 0x01dc, 2},
-		{0x01dd, 0x01ef, 2},
-		{0x01f0, 0x01f3, 3},
-		{0x01f5, 0x01f9, 4},
-		{0x01fb, 0x0233, 2},
-		{0x0234, 0x0239, 1},
-		{0x023c, 0x023f, 3},
-		{0x0240, 0x0242, 2},
-		{0x0247, 0x024f, 2},
-		{0x0250, 0x0293, 1},
-		{0x0295, 0x02af, 1},
-		{0x0371, 0x0373, 2},
-		{0x0377, 0x037b, 4},
-		{0x037c, 0x037d, 1},
-		{0x0390, 0x03ac, 28},
-		{0x03ad, 0x03ce, 1},
-		{0x03d0, 0x03d1, 1},
-		{0x03d5, 0x03d7, 1},
-		{0x03d9, 0x03ef, 2},
-		{0x03f0, 0x03f3, 1},
-		{0x03f5, 0x03fb, 3},
-		{0x03fc, 0x0430, 52},
-		{0x0431, 0x045f, 1},
-		{0x0461, 0x0481, 2},
-		{0x048b, 0x04bf, 2},
-		{0x04c2, 0x04ce, 2},
-		{0x04cf, 0x0527, 2},
-		{0x0561, 0x0587, 1},
-		{0x1d00, 0x1d2b, 1},
-		{0x1d6b, 0x1d77, 1},
-		{0x1d79, 0x1d9a, 1},
-		{0x1e01, 0x1e95, 2},
-		{0x1e96, 0x1e9d, 1},
-		{0x1e9f, 0x1eff, 2},
-		{0x1f00, 0x1f07, 1},
-		{0x1f10, 0x1f15, 1},
-		{0x1f20, 0x1f27, 1},
-		{0x1f30, 0x1f37, 1},
-		{0x1f40, 0x1f45, 1},
-		{0x1f50, 0x1f57, 1},
-		{0x1f60, 0x1f67, 1},
-		{0x1f70, 0x1f7d, 1},
-		{0x1f80, 0x1f87, 1},
-		{0x1f90, 0x1f97, 1},
-		{0x1fa0, 0x1fa7, 1},
-		{0x1fb0, 0x1fb4, 1},
-		{0x1fb6, 0x1fb7, 1},
-		{0x1fbe, 0x1fc2, 4},
-		{0x1fc3, 0x1fc4, 1},
-		{0x1fc6, 0x1fc7, 1},
-		{0x1fd0, 0x1fd3, 1},
-		{0x1fd6, 0x1fd7, 1},
-		{0x1fe0, 0x1fe7, 1},
-		{0x1ff2, 0x1ff4, 1},
-		{0x1ff6, 0x1ff7, 1},
-		{0x210a, 0x210e, 4},
-		{0x210f, 0x2113, 4},
-		{0x212f, 0x2139, 5},
-		{0x213c, 0x213d, 1},
-		{0x2146, 0x2149, 1},
-		{0x214e, 0x2184, 54},
-		{0x2c30, 0x2c5e, 1},
-		{0x2c61, 0x2c65, 4},
-		{0x2c66, 0x2c6c, 2},
-		{0x2c71, 0x2c73, 2},
-		{0x2c74, 0x2c76, 2},
-		{0x2c77, 0x2c7b, 1},
-		{0x2c81, 0x2ce3, 2},
-		{0x2ce4, 0x2cec, 8},
-		{0x2cee, 0x2cf3, 5},
-		{0x2d00, 0x2d25, 1},
-		{0x2d27, 0x2d2d, 6},
-		{0xa641, 0xa66d, 2},
-		{0xa681, 0xa697, 2},
-		{0xa723, 0xa72f, 2},
-		{0xa730, 0xa731, 1},
-		{0xa733, 0xa771, 2},
-		{0xa772, 0xa778, 1},
-		{0xa77a, 0xa77c, 2},
-		{0xa77f, 0xa787, 2},
-		{0xa78c, 0xa78e, 2},
-		{0xa791, 0xa793, 2},
-		{0xa7a1, 0xa7a9, 2},
-		{0xa7fa, 0xfb00, 21254},
-		{0xfb01, 0xfb06, 1},
-		{0xfb13, 0xfb17, 1},
-		{0xff41, 0xff5a, 1},
-	},
-	R32: []Range32{
-		{0x10428, 0x1044f, 1},
-		{0x1d41a, 0x1d433, 1},
-		{0x1d44e, 0x1d454, 1},
-		{0x1d456, 0x1d467, 1},
-		{0x1d482, 0x1d49b, 1},
-		{0x1d4b6, 0x1d4b9, 1},
-		{0x1d4bb, 0x1d4bd, 2},
-		{0x1d4be, 0x1d4c3, 1},
-		{0x1d4c5, 0x1d4cf, 1},
-		{0x1d4ea, 0x1d503, 1},
-		{0x1d51e, 0x1d537, 1},
-		{0x1d552, 0x1d56b, 1},
-		{0x1d586, 0x1d59f, 1},
-		{0x1d5ba, 0x1d5d3, 1},
-		{0x1d5ee, 0x1d607, 1},
-		{0x1d622, 0x1d63b, 1},
-		{0x1d656, 0x1d66f, 1},
-		{0x1d68a, 0x1d6a5, 1},
-		{0x1d6c2, 0x1d6da, 1},
-		{0x1d6dc, 0x1d6e1, 1},
-		{0x1d6fc, 0x1d714, 1},
-		{0x1d716, 0x1d71b, 1},
-		{0x1d736, 0x1d74e, 1},
-		{0x1d750, 0x1d755, 1},
-		{0x1d770, 0x1d788, 1},
-		{0x1d78a, 0x1d78f, 1},
-		{0x1d7aa, 0x1d7c2, 1},
-		{0x1d7c4, 0x1d7c9, 1},
-		{0x1d7cb, 0x1d7cb, 1},
-	},
-	LatinOffset: 4,
-}
-
-var _Lm = &RangeTable{
-	R16: []Range16{
-		{0x02b0, 0x02c1, 1},
-		{0x02c6, 0x02d1, 1},
-		{0x02e0, 0x02e4, 1},
-		{0x02ec, 0x02ee, 2},
-		{0x0374, 0x037a, 6},
-		{0x0559, 0x0640, 231},
-		{0x06e5, 0x06e6, 1},
-		{0x07f4, 0x07f5, 1},
-		{0x07fa, 0x081a, 32},
-		{0x0824, 0x0828, 4},
-		{0x0971, 0x0e46, 1237},
-		{0x0ec6, 0x10fc, 566},
-		{0x17d7, 0x1843, 108},
-		{0x1aa7, 0x1c78, 465},
-		{0x1c79, 0x1c7d, 1},
-		{0x1d2c, 0x1d6a, 1},
-		{0x1d78, 0x1d9b, 35},
-		{0x1d9c, 0x1dbf, 1},
-		{0x2071, 0x207f, 14},
-		{0x2090, 0x209c, 1},
-		{0x2c7c, 0x2c7d, 1},
-		{0x2d6f, 0x2e2f, 192},
-		{0x3005, 0x3031, 44},
-		{0x3032, 0x3035, 1},
-		{0x303b, 0x309d, 98},
-		{0x309e, 0x30fc, 94},
-		{0x30fd, 0x30fe, 1},
-		{0xa015, 0xa4f8, 1251},
-		{0xa4f9, 0xa4fd, 1},
-		{0xa60c, 0xa67f, 115},
-		{0xa717, 0xa71f, 1},
-		{0xa770, 0xa788, 24},
-		{0xa7f8, 0xa7f9, 1},
-		{0xa9cf, 0xaa70, 161},
-		{0xaadd, 0xaaf3, 22},
-		{0xaaf4, 0xff70, 21628},
-		{0xff9e, 0xff9f, 1},
-	},
-	R32: []Range32{
-		{0x16f93, 0x16f9f, 1},
-	},
-}
-
-var _Lo = &RangeTable{
-	R16: []Range16{
-		{0x00aa, 0x00ba, 16},
-		{0x01bb, 0x01c0, 5},
-		{0x01c1, 0x01c3, 1},
-		{0x0294, 0x05d0, 828},
-		{0x05d1, 0x05ea, 1},
-		{0x05f0, 0x05f2, 1},
-		{0x0620, 0x063f, 1},
-		{0x0641, 0x064a, 1},
-		{0x066e, 0x066f, 1},
-		{0x0671, 0x06d3, 1},
-		{0x06d5, 0x06ee, 25},
-		{0x06ef, 0x06fa, 11},
-		{0x06fb, 0x06fc, 1},
-		{0x06ff, 0x0710, 17},
-		{0x0712, 0x072f, 1},
-		{0x074d, 0x07a5, 1},
-		{0x07b1, 0x07ca, 25},
-		{0x07cb, 0x07ea, 1},
-		{0x0800, 0x0815, 1},
-		{0x0840, 0x0858, 1},
-		{0x08a0, 0x08a2, 2},
-		{0x08a3, 0x08ac, 1},
-		{0x0904, 0x0939, 1},
-		{0x093d, 0x0950, 19},
-		{0x0958, 0x0961, 1},
-		{0x0972, 0x0977, 1},
-		{0x0979, 0x097f, 1},
-		{0x0985, 0x098c, 1},
-		{0x098f, 0x0990, 1},
-		{0x0993, 0x09a8, 1},
-		{0x09aa, 0x09b0, 1},
-		{0x09b2, 0x09b6, 4},
-		{0x09b7, 0x09b9, 1},
-		{0x09bd, 0x09ce, 17},
-		{0x09dc, 0x09dd, 1},
-		{0x09df, 0x09e1, 1},
-		{0x09f0, 0x09f1, 1},
-		{0x0a05, 0x0a0a, 1},
-		{0x0a0f, 0x0a10, 1},
-		{0x0a13, 0x0a28, 1},
-		{0x0a2a, 0x0a30, 1},
-		{0x0a32, 0x0a33, 1},
-		{0x0a35, 0x0a36, 1},
-		{0x0a38, 0x0a39, 1},
-		{0x0a59, 0x0a5c, 1},
-		{0x0a5e, 0x0a72, 20},
-		{0x0a73, 0x0a74, 1},
-		{0x0a85, 0x0a8d, 1},
-		{0x0a8f, 0x0a91, 1},
-		{0x0a93, 0x0aa8, 1},
-		{0x0aaa, 0x0ab0, 1},
-		{0x0ab2, 0x0ab3, 1},
-		{0x0ab5, 0x0ab9, 1},
-		{0x0abd, 0x0ad0, 19},
-		{0x0ae0, 0x0ae1, 1},
-		{0x0b05, 0x0b0c, 1},
-		{0x0b0f, 0x0b10, 1},
-		{0x0b13, 0x0b28, 1},
-		{0x0b2a, 0x0b30, 1},
-		{0x0b32, 0x0b33, 1},
-		{0x0b35, 0x0b39, 1},
-		{0x0b3d, 0x0b5c, 31},
-		{0x0b5d, 0x0b5f, 2},
-		{0x0b60, 0x0b61, 1},
-		{0x0b71, 0x0b83, 18},
-		{0x0b85, 0x0b8a, 1},
-		{0x0b8e, 0x0b90, 1},
-		{0x0b92, 0x0b95, 1},
-		{0x0b99, 0x0b9a, 1},
-		{0x0b9c, 0x0b9e, 2},
-		{0x0b9f, 0x0ba3, 4},
-		{0x0ba4, 0x0ba8, 4},
-		{0x0ba9, 0x0baa, 1},
-		{0x0bae, 0x0bb9, 1},
-		{0x0bd0, 0x0c05, 53},
-		{0x0c06, 0x0c0c, 1},
-		{0x0c0e, 0x0c10, 1},
-		{0x0c12, 0x0c28, 1},
-		{0x0c2a, 0x0c33, 1},
-		{0x0c35, 0x0c39, 1},
-		{0x0c3d, 0x0c58, 27},
-		{0x0c59, 0x0c60, 7},
-		{0x0c61, 0x0c85, 36},
-		{0x0c86, 0x0c8c, 1},
-		{0x0c8e, 0x0c90, 1},
-		{0x0c92, 0x0ca8, 1},
-		{0x0caa, 0x0cb3, 1},
-		{0x0cb5, 0x0cb9, 1},
-		{0x0cbd, 0x0cde, 33},
-		{0x0ce0, 0x0ce1, 1},
-		{0x0cf1, 0x0cf2, 1},
-		{0x0d05, 0x0d0c, 1},
-		{0x0d0e, 0x0d10, 1},
-		{0x0d12, 0x0d3a, 1},
-		{0x0d3d, 0x0d4e, 17},
-		{0x0d60, 0x0d61, 1},
-		{0x0d7a, 0x0d7f, 1},
-		{0x0d85, 0x0d96, 1},
-		{0x0d9a, 0x0db1, 1},
-		{0x0db3, 0x0dbb, 1},
-		{0x0dbd, 0x0dc0, 3},
-		{0x0dc1, 0x0dc6, 1},
-		{0x0e01, 0x0e30, 1},
-		{0x0e32, 0x0e33, 1},
-		{0x0e40, 0x0e45, 1},
-		{0x0e81, 0x0e82, 1},
-		{0x0e84, 0x0e87, 3},
-		{0x0e88, 0x0e8a, 2},
-		{0x0e8d, 0x0e94, 7},
-		{0x0e95, 0x0e97, 1},
-		{0x0e99, 0x0e9f, 1},
-		{0x0ea1, 0x0ea3, 1},
-		{0x0ea5, 0x0ea7, 2},
-		{0x0eaa, 0x0eab, 1},
-		{0x0ead, 0x0eb0, 1},
-		{0x0eb2, 0x0eb3, 1},
-		{0x0ebd, 0x0ec0, 3},
-		{0x0ec1, 0x0ec4, 1},
-		{0x0edc, 0x0edf, 1},
-		{0x0f00, 0x0f40, 64},
-		{0x0f41, 0x0f47, 1},
-		{0x0f49, 0x0f6c, 1},
-		{0x0f88, 0x0f8c, 1},
-		{0x1000, 0x102a, 1},
-		{0x103f, 0x1050, 17},
-		{0x1051, 0x1055, 1},
-		{0x105a, 0x105d, 1},
-		{0x1061, 0x1065, 4},
-		{0x1066, 0x106e, 8},
-		{0x106f, 0x1070, 1},
-		{0x1075, 0x1081, 1},
-		{0x108e, 0x10d0, 66},
-		{0x10d1, 0x10fa, 1},
-		{0x10fd, 0x1248, 1},
-		{0x124a, 0x124d, 1},
-		{0x1250, 0x1256, 1},
-		{0x1258, 0x125a, 2},
-		{0x125b, 0x125d, 1},
-		{0x1260, 0x1288, 1},
-		{0x128a, 0x128d, 1},
-		{0x1290, 0x12b0, 1},
-		{0x12b2, 0x12b5, 1},
-		{0x12b8, 0x12be, 1},
-		{0x12c0, 0x12c2, 2},
-		{0x12c3, 0x12c5, 1},
-		{0x12c8, 0x12d6, 1},
-		{0x12d8, 0x1310, 1},
-		{0x1312, 0x1315, 1},
-		{0x1318, 0x135a, 1},
-		{0x1380, 0x138f, 1},
-		{0x13a0, 0x13f4, 1},
-		{0x1401, 0x166c, 1},
-		{0x166f, 0x167f, 1},
-		{0x1681, 0x169a, 1},
-		{0x16a0, 0x16ea, 1},
-		{0x1700, 0x170c, 1},
-		{0x170e, 0x1711, 1},
-		{0x1720, 0x1731, 1},
-		{0x1740, 0x1751, 1},
-		{0x1760, 0x176c, 1},
-		{0x176e, 0x1770, 1},
-		{0x1780, 0x17b3, 1},
-		{0x17dc, 0x1820, 68},
-		{0x1821, 0x1842, 1},
-		{0x1844, 0x1877, 1},
-		{0x1880, 0x18a8, 1},
-		{0x18aa, 0x18b0, 6},
-		{0x18b1, 0x18f5, 1},
-		{0x1900, 0x191c, 1},
-		{0x1950, 0x196d, 1},
-		{0x1970, 0x1974, 1},
-		{0x1980, 0x19ab, 1},
-		{0x19c1, 0x19c7, 1},
-		{0x1a00, 0x1a16, 1},
-		{0x1a20, 0x1a54, 1},
-		{0x1b05, 0x1b33, 1},
-		{0x1b45, 0x1b4b, 1},
-		{0x1b83, 0x1ba0, 1},
-		{0x1bae, 0x1baf, 1},
-		{0x1bba, 0x1be5, 1},
-		{0x1c00, 0x1c23, 1},
-		{0x1c4d, 0x1c4f, 1},
-		{0x1c5a, 0x1c77, 1},
-		{0x1ce9, 0x1cec, 1},
-		{0x1cee, 0x1cf1, 1},
-		{0x1cf5, 0x1cf6, 1},
-		{0x2135, 0x2138, 1},
-		{0x2d30, 0x2d67, 1},
-		{0x2d80, 0x2d96, 1},
-		{0x2da0, 0x2da6, 1},
-		{0x2da8, 0x2dae, 1},
-		{0x2db0, 0x2db6, 1},
-		{0x2db8, 0x2dbe, 1},
-		{0x2dc0, 0x2dc6, 1},
-		{0x2dc8, 0x2dce, 1},
-		{0x2dd0, 0x2dd6, 1},
-		{0x2dd8, 0x2dde, 1},
-		{0x3006, 0x303c, 54},
-		{0x3041, 0x3096, 1},
-		{0x309f, 0x30a1, 2},
-		{0x30a2, 0x30fa, 1},
-		{0x30ff, 0x3105, 6},
-		{0x3106, 0x312d, 1},
-		{0x3131, 0x318e, 1},
-		{0x31a0, 0x31ba, 1},
-		{0x31f0, 0x31ff, 1},
-		{0x3400, 0x4db5, 1},
-		{0x4e00, 0x9fcc, 1},
-		{0xa000, 0xa014, 1},
-		{0xa016, 0xa48c, 1},
-		{0xa4d0, 0xa4f7, 1},
-		{0xa500, 0xa60b, 1},
-		{0xa610, 0xa61f, 1},
-		{0xa62a, 0xa62b, 1},
-		{0xa66e, 0xa6a0, 50},
-		{0xa6a1, 0xa6e5, 1},
-		{0xa7fb, 0xa801, 1},
-		{0xa803, 0xa805, 1},
-		{0xa807, 0xa80a, 1},
-		{0xa80c, 0xa822, 1},
-		{0xa840, 0xa873, 1},
-		{0xa882, 0xa8b3, 1},
-		{0xa8f2, 0xa8f7, 1},
-		{0xa8fb, 0xa90a, 15},
-		{0xa90b, 0xa925, 1},
-		{0xa930, 0xa946, 1},
-		{0xa960, 0xa97c, 1},
-		{0xa984, 0xa9b2, 1},
-		{0xaa00, 0xaa28, 1},
-		{0xaa40, 0xaa42, 1},
-		{0xaa44, 0xaa4b, 1},
-		{0xaa60, 0xaa6f, 1},
-		{0xaa71, 0xaa76, 1},
-		{0xaa7a, 0xaa80, 6},
-		{0xaa81, 0xaaaf, 1},
-		{0xaab1, 0xaab5, 4},
-		{0xaab6, 0xaab9, 3},
-		{0xaaba, 0xaabd, 1},
-		{0xaac0, 0xaac2, 2},
-		{0xaadb, 0xaadc, 1},
-		{0xaae0, 0xaaea, 1},
-		{0xaaf2, 0xab01, 15},
-		{0xab02, 0xab06, 1},
-		{0xab09, 0xab0e, 1},
-		{0xab11, 0xab16, 1},
-		{0xab20, 0xab26, 1},
-		{0xab28, 0xab2e, 1},
-		{0xabc0, 0xabe2, 1},
-		{0xac00, 0xd7a3, 1},
-		{0xd7b0, 0xd7c6, 1},
-		{0xd7cb, 0xd7fb, 1},
-		{0xf900, 0xfa6d, 1},
-		{0xfa70, 0xfad9, 1},
-		{0xfb1d, 0xfb1f, 2},
-		{0xfb20, 0xfb28, 1},
-		{0xfb2a, 0xfb36, 1},
-		{0xfb38, 0xfb3c, 1},
-		{0xfb3e, 0xfb40, 2},
-		{0xfb41, 0xfb43, 2},
-		{0xfb44, 0xfb46, 2},
-		{0xfb47, 0xfbb1, 1},
-		{0xfbd3, 0xfd3d, 1},
-		{0xfd50, 0xfd8f, 1},
-		{0xfd92, 0xfdc7, 1},
-		{0xfdf0, 0xfdfb, 1},
-		{0xfe70, 0xfe74, 1},
-		{0xfe76, 0xfefc, 1},
-		{0xff66, 0xff6f, 1},
-		{0xff71, 0xff9d, 1},
-		{0xffa0, 0xffbe, 1},
-		{0xffc2, 0xffc7, 1},
-		{0xffca, 0xffcf, 1},
-		{0xffd2, 0xffd7, 1},
-		{0xffda, 0xffdc, 1},
-	},
-	R32: []Range32{
-		{0x10000, 0x1000b, 1},
-		{0x1000d, 0x10026, 1},
-		{0x10028, 0x1003a, 1},
-		{0x1003c, 0x1003d, 1},
-		{0x1003f, 0x1004d, 1},
-		{0x10050, 0x1005d, 1},
-		{0x10080, 0x100fa, 1},
-		{0x10280, 0x1029c, 1},
-		{0x102a0, 0x102d0, 1},
-		{0x10300, 0x1031e, 1},
-		{0x10330, 0x10340, 1},
-		{0x10342, 0x10349, 1},
-		{0x10380, 0x1039d, 1},
-		{0x103a0, 0x103c3, 1},
-		{0x103c8, 0x103cf, 1},
-		{0x10450, 0x1049d, 1},
-		{0x10800, 0x10805, 1},
-		{0x10808, 0x1080a, 2},
-		{0x1080b, 0x10835, 1},
-		{0x10837, 0x10838, 1},
-		{0x1083c, 0x1083f, 3},
-		{0x10840, 0x10855, 1},
-		{0x10900, 0x10915, 1},
-		{0x10920, 0x10939, 1},
-		{0x10980, 0x109b7, 1},
-		{0x109be, 0x109bf, 1},
-		{0x10a00, 0x10a10, 16},
-		{0x10a11, 0x10a13, 1},
-		{0x10a15, 0x10a17, 1},
-		{0x10a19, 0x10a33, 1},
-		{0x10a60, 0x10a7c, 1},
-		{0x10b00, 0x10b35, 1},
-		{0x10b40, 0x10b55, 1},
-		{0x10b60, 0x10b72, 1},
-		{0x10c00, 0x10c48, 1},
-		{0x11003, 0x11037, 1},
-		{0x11083, 0x110af, 1},
-		{0x110d0, 0x110e8, 1},
-		{0x11103, 0x11126, 1},
-		{0x11183, 0x111b2, 1},
-		{0x111c1, 0x111c4, 1},
-		{0x11680, 0x116aa, 1},
-		{0x12000, 0x1236e, 1},
-		{0x13000, 0x1342e, 1},
-		{0x16800, 0x16a38, 1},
-		{0x16f00, 0x16f44, 1},
-		{0x16f50, 0x1b000, 16560},
-		{0x1b001, 0x1ee00, 15871},
-		{0x1ee01, 0x1ee03, 1},
-		{0x1ee05, 0x1ee1f, 1},
-		{0x1ee21, 0x1ee22, 1},
-		{0x1ee24, 0x1ee27, 3},
-		{0x1ee29, 0x1ee32, 1},
-		{0x1ee34, 0x1ee37, 1},
-		{0x1ee39, 0x1ee3b, 2},
-		{0x1ee42, 0x1ee47, 5},
-		{0x1ee49, 0x1ee4d, 2},
-		{0x1ee4e, 0x1ee4f, 1},
-		{0x1ee51, 0x1ee52, 1},
-		{0x1ee54, 0x1ee57, 3},
-		{0x1ee59, 0x1ee61, 2},
-		{0x1ee62, 0x1ee64, 2},
-		{0x1ee67, 0x1ee6a, 1},
-		{0x1ee6c, 0x1ee72, 1},
-		{0x1ee74, 0x1ee77, 1},
-		{0x1ee79, 0x1ee7c, 1},
-		{0x1ee7e, 0x1ee80, 2},
-		{0x1ee81, 0x1ee89, 1},
-		{0x1ee8b, 0x1ee9b, 1},
-		{0x1eea1, 0x1eea3, 1},
-		{0x1eea5, 0x1eea9, 1},
-		{0x1eeab, 0x1eebb, 1},
-		{0x20000, 0x2a6d6, 1},
-		{0x2a700, 0x2b734, 1},
-		{0x2b740, 0x2b81d, 1},
-		{0x2f800, 0x2fa1d, 1},
-	},
-	LatinOffset: 1,
-}
-
-var _Lt = &RangeTable{
-	R16: []Range16{
-		{0x01c5, 0x01cb, 3},
-		{0x01f2, 0x1f88, 7574},
-		{0x1f89, 0x1f8f, 1},
-		{0x1f98, 0x1f9f, 1},
-		{0x1fa8, 0x1faf, 1},
-		{0x1fbc, 0x1fcc, 16},
-		{0x1ffc, 0x1ffc, 1},
-	},
-}
-
-var _Lu = &RangeTable{
-	R16: []Range16{
-		{0x0041, 0x005a, 1},
-		{0x00c0, 0x00d6, 1},
-		{0x00d8, 0x00de, 1},
-		{0x0100, 0x0136, 2},
-		{0x0139, 0x0147, 2},
-		{0x014a, 0x0178, 2},
-		{0x0179, 0x017d, 2},
-		{0x0181, 0x0182, 1},
-		{0x0184, 0x0186, 2},
-		{0x0187, 0x0189, 2},
-		{0x018a, 0x018b, 1},
-		{0x018e, 0x0191, 1},
-		{0x0193, 0x0194, 1},
-		{0x0196, 0x0198, 1},
-		{0x019c, 0x019d, 1},
-		{0x019f, 0x01a0, 1},
-		{0x01a2, 0x01a6, 2},
-		{0x01a7, 0x01a9, 2},
-		{0x01ac, 0x01ae, 2},
-		{0x01af, 0x01b1, 2},
-		{0x01b2, 0x01b3, 1},
-		{0x01b5, 0x01b7, 2},
-		{0x01b8, 0x01bc, 4},
-		{0x01c4, 0x01cd, 3},
-		{0x01cf, 0x01db, 2},
-		{0x01de, 0x01ee, 2},
-		{0x01f1, 0x01f4, 3},
-		{0x01f6, 0x01f8, 1},
-		{0x01fa, 0x0232, 2},
-		{0x023a, 0x023b, 1},
-		{0x023d, 0x023e, 1},
-		{0x0241, 0x0243, 2},
-		{0x0244, 0x0246, 1},
-		{0x0248, 0x024e, 2},
-		{0x0370, 0x0372, 2},
-		{0x0376, 0x0386, 16},
-		{0x0388, 0x038a, 1},
-		{0x038c, 0x038e, 2},
-		{0x038f, 0x0391, 2},
-		{0x0392, 0x03a1, 1},
-		{0x03a3, 0x03ab, 1},
-		{0x03cf, 0x03d2, 3},
-		{0x03d3, 0x03d4, 1},
-		{0x03d8, 0x03ee, 2},
-		{0x03f4, 0x03f7, 3},
-		{0x03f9, 0x03fa, 1},
-		{0x03fd, 0x042f, 1},
-		{0x0460, 0x0480, 2},
-		{0x048a, 0x04c0, 2},
-		{0x04c1, 0x04cd, 2},
-		{0x04d0, 0x0526, 2},
-		{0x0531, 0x0556, 1},
-		{0x10a0, 0x10c5, 1},
-		{0x10c7, 0x10cd, 6},
-		{0x1e00, 0x1e94, 2},
-		{0x1e9e, 0x1efe, 2},
-		{0x1f08, 0x1f0f, 1},
-		{0x1f18, 0x1f1d, 1},
-		{0x1f28, 0x1f2f, 1},
-		{0x1f38, 0x1f3f, 1},
-		{0x1f48, 0x1f4d, 1},
-		{0x1f59, 0x1f5f, 2},
-		{0x1f68, 0x1f6f, 1},
-		{0x1fb8, 0x1fbb, 1},
-		{0x1fc8, 0x1fcb, 1},
-		{0x1fd8, 0x1fdb, 1},
-		{0x1fe8, 0x1fec, 1},
-		{0x1ff8, 0x1ffb, 1},
-		{0x2102, 0x2107, 5},
-		{0x210b, 0x210d, 1},
-		{0x2110, 0x2112, 1},
-		{0x2115, 0x2119, 4},
-		{0x211a, 0x211d, 1},
-		{0x2124, 0x212a, 2},
-		{0x212b, 0x212d, 1},
-		{0x2130, 0x2133, 1},
-		{0x213e, 0x213f, 1},
-		{0x2145, 0x2183, 62},
-		{0x2c00, 0x2c2e, 1},
-		{0x2c60, 0x2c62, 2},
-		{0x2c63, 0x2c64, 1},
-		{0x2c67, 0x2c6d, 2},
-		{0x2c6e, 0x2c70, 1},
-		{0x2c72, 0x2c75, 3},
-		{0x2c7e, 0x2c80, 1},
-		{0x2c82, 0x2ce2, 2},
-		{0x2ceb, 0x2ced, 2},
-		{0x2cf2, 0xa640, 31054},
-		{0xa642, 0xa66c, 2},
-		{0xa680, 0xa696, 2},
-		{0xa722, 0xa72e, 2},
-		{0xa732, 0xa76e, 2},
-		{0xa779, 0xa77d, 2},
-		{0xa77e, 0xa786, 2},
-		{0xa78b, 0xa78d, 2},
-		{0xa790, 0xa792, 2},
-		{0xa7a0, 0xa7aa, 2},
-		{0xff21, 0xff3a, 1},
-	},
-	R32: []Range32{
-		{0x10400, 0x10427, 1},
-		{0x1d400, 0x1d419, 1},
-		{0x1d434, 0x1d44d, 1},
-		{0x1d468, 0x1d481, 1},
-		{0x1d49c, 0x1d49e, 2},
-		{0x1d49f, 0x1d4a5, 3},
-		{0x1d4a6, 0x1d4a9, 3},
-		{0x1d4aa, 0x1d4ac, 1},
-		{0x1d4ae, 0x1d4b5, 1},
-		{0x1d4d0, 0x1d4e9, 1},
-		{0x1d504, 0x1d505, 1},
-		{0x1d507, 0x1d50a, 1},
-		{0x1d50d, 0x1d514, 1},
-		{0x1d516, 0x1d51c, 1},
-		{0x1d538, 0x1d539, 1},
-		{0x1d53b, 0x1d53e, 1},
-		{0x1d540, 0x1d544, 1},
-		{0x1d546, 0x1d54a, 4},
-		{0x1d54b, 0x1d550, 1},
-		{0x1d56c, 0x1d585, 1},
-		{0x1d5a0, 0x1d5b9, 1},
-		{0x1d5d4, 0x1d5ed, 1},
-		{0x1d608, 0x1d621, 1},
-		{0x1d63c, 0x1d655, 1},
-		{0x1d670, 0x1d689, 1},
-		{0x1d6a8, 0x1d6c0, 1},
-		{0x1d6e2, 0x1d6fa, 1},
-		{0x1d71c, 0x1d734, 1},
-		{0x1d756, 0x1d76e, 1},
-		{0x1d790, 0x1d7a8, 1},
-		{0x1d7ca, 0x1d7ca, 1},
-	},
-	LatinOffset: 3,
-}
-
-var _M = &RangeTable{
-	R16: []Range16{
-		{0x0300, 0x036f, 1},
-		{0x0483, 0x0489, 1},
-		{0x0591, 0x05bd, 1},
-		{0x05bf, 0x05c1, 2},
-		{0x05c2, 0x05c4, 2},
-		{0x05c5, 0x05c7, 2},
-		{0x0610, 0x061a, 1},
-		{0x064b, 0x065f, 1},
-		{0x0670, 0x06d6, 102},
-		{0x06d7, 0x06dc, 1},
-		{0x06df, 0x06e4, 1},
-		{0x06e7, 0x06e8, 1},
-		{0x06ea, 0x06ed, 1},
-		{0x0711, 0x0730, 31},
-		{0x0731, 0x074a, 1},
-		{0x07a6, 0x07b0, 1},
-		{0x07eb, 0x07f3, 1},
-		{0x0816, 0x0819, 1},
-		{0x081b, 0x0823, 1},
-		{0x0825, 0x0827, 1},
-		{0x0829, 0x082d, 1},
-		{0x0859, 0x085b, 1},
-		{0x08e4, 0x08fe, 1},
-		{0x0900, 0x0903, 1},
-		{0x093a, 0x093c, 1},
-		{0x093e, 0x094f, 1},
-		{0x0951, 0x0957, 1},
-		{0x0962, 0x0963, 1},
-		{0x0981, 0x0983, 1},
-		{0x09bc, 0x09be, 2},
-		{0x09bf, 0x09c4, 1},
-		{0x09c7, 0x09c8, 1},
-		{0x09cb, 0x09cd, 1},
-		{0x09d7, 0x09e2, 11},
-		{0x09e3, 0x0a01, 30},
-		{0x0a02, 0x0a03, 1},
-		{0x0a3c, 0x0a3e, 2},
-		{0x0a3f, 0x0a42, 1},
-		{0x0a47, 0x0a48, 1},
-		{0x0a4b, 0x0a4d, 1},
-		{0x0a51, 0x0a70, 31},
-		{0x0a71, 0x0a75, 4},
-		{0x0a81, 0x0a83, 1},
-		{0x0abc, 0x0abe, 2},
-		{0x0abf, 0x0ac5, 1},
-		{0x0ac7, 0x0ac9, 1},
-		{0x0acb, 0x0acd, 1},
-		{0x0ae2, 0x0ae3, 1},
-		{0x0b01, 0x0b03, 1},
-		{0x0b3c, 0x0b3e, 2},
-		{0x0b3f, 0x0b44, 1},
-		{0x0b47, 0x0b48, 1},
-		{0x0b4b, 0x0b4d, 1},
-		{0x0b56, 0x0b57, 1},
-		{0x0b62, 0x0b63, 1},
-		{0x0b82, 0x0bbe, 60},
-		{0x0bbf, 0x0bc2, 1},
-		{0x0bc6, 0x0bc8, 1},
-		{0x0bca, 0x0bcd, 1},
-		{0x0bd7, 0x0c01, 42},
-		{0x0c02, 0x0c03, 1},
-		{0x0c3e, 0x0c44, 1},
-		{0x0c46, 0x0c48, 1},
-		{0x0c4a, 0x0c4d, 1},
-		{0x0c55, 0x0c56, 1},
-		{0x0c62, 0x0c63, 1},
-		{0x0c82, 0x0c83, 1},
-		{0x0cbc, 0x0cbe, 2},
-		{0x0cbf, 0x0cc4, 1},
-		{0x0cc6, 0x0cc8, 1},
-		{0x0cca, 0x0ccd, 1},
-		{0x0cd5, 0x0cd6, 1},
-		{0x0ce2, 0x0ce3, 1},
-		{0x0d02, 0x0d03, 1},
-		{0x0d3e, 0x0d44, 1},
-		{0x0d46, 0x0d48, 1},
-		{0x0d4a, 0x0d4d, 1},
-		{0x0d57, 0x0d62, 11},
-		{0x0d63, 0x0d82, 31},
-		{0x0d83, 0x0dca, 71},
-		{0x0dcf, 0x0dd4, 1},
-		{0x0dd6, 0x0dd8, 2},
-		{0x0dd9, 0x0ddf, 1},
-		{0x0df2, 0x0df3, 1},
-		{0x0e31, 0x0e34, 3},
-		{0x0e35, 0x0e3a, 1},
-		{0x0e47, 0x0e4e, 1},
-		{0x0eb1, 0x0eb4, 3},
-		{0x0eb5, 0x0eb9, 1},
-		{0x0ebb, 0x0ebc, 1},
-		{0x0ec8, 0x0ecd, 1},
-		{0x0f18, 0x0f19, 1},
-		{0x0f35, 0x0f39, 2},
-		{0x0f3e, 0x0f3f, 1},
-		{0x0f71, 0x0f84, 1},
-		{0x0f86, 0x0f87, 1},
-		{0x0f8d, 0x0f97, 1},
-		{0x0f99, 0x0fbc, 1},
-		{0x0fc6, 0x102b, 101},
-		{0x102c, 0x103e, 1},
-		{0x1056, 0x1059, 1},
-		{0x105e, 0x1060, 1},
-		{0x1062, 0x1064, 1},
-		{0x1067, 0x106d, 1},
-		{0x1071, 0x1074, 1},
-		{0x1082, 0x108d, 1},
-		{0x108f, 0x109a, 11},
-		{0x109b, 0x109d, 1},
-		{0x135d, 0x135f, 1},
-		{0x1712, 0x1714, 1},
-		{0x1732, 0x1734, 1},
-		{0x1752, 0x1753, 1},
-		{0x1772, 0x1773, 1},
-		{0x17b4, 0x17d3, 1},
-		{0x17dd, 0x180b, 46},
-		{0x180c, 0x180d, 1},
-		{0x18a9, 0x1920, 119},
-		{0x1921, 0x192b, 1},
-		{0x1930, 0x193b, 1},
-		{0x19b0, 0x19c0, 1},
-		{0x19c8, 0x19c9, 1},
-		{0x1a17, 0x1a1b, 1},
-		{0x1a55, 0x1a5e, 1},
-		{0x1a60, 0x1a7c, 1},
-		{0x1a7f, 0x1b00, 129},
-		{0x1b01, 0x1b04, 1},
-		{0x1b34, 0x1b44, 1},
-		{0x1b6b, 0x1b73, 1},
-		{0x1b80, 0x1b82, 1},
-		{0x1ba1, 0x1bad, 1},
-		{0x1be6, 0x1bf3, 1},
-		{0x1c24, 0x1c37, 1},
-		{0x1cd0, 0x1cd2, 1},
-		{0x1cd4, 0x1ce8, 1},
-		{0x1ced, 0x1cf2, 5},
-		{0x1cf3, 0x1cf4, 1},
-		{0x1dc0, 0x1de6, 1},
-		{0x1dfc, 0x1dff, 1},
-		{0x20d0, 0x20f0, 1},
-		{0x2cef, 0x2cf1, 1},
-		{0x2d7f, 0x2de0, 97},
-		{0x2de1, 0x2dff, 1},
-		{0x302a, 0x302f, 1},
-		{0x3099, 0x309a, 1},
-		{0xa66f, 0xa672, 1},
-		{0xa674, 0xa67d, 1},
-		{0xa69f, 0xa6f0, 81},
-		{0xa6f1, 0xa802, 273},
-		{0xa806, 0xa80b, 5},
-		{0xa823, 0xa827, 1},
-		{0xa880, 0xa881, 1},
-		{0xa8b4, 0xa8c4, 1},
-		{0xa8e0, 0xa8f1, 1},
-		{0xa926, 0xa92d, 1},
-		{0xa947, 0xa953, 1},
-		{0xa980, 0xa983, 1},
-		{0xa9b3, 0xa9c0, 1},
-		{0xaa29, 0xaa36, 1},
-		{0xaa43, 0xaa4c, 9},
-		{0xaa4d, 0xaa7b, 46},
-		{0xaab0, 0xaab2, 2},
-		{0xaab3, 0xaab4, 1},
-		{0xaab7, 0xaab8, 1},
-		{0xaabe, 0xaabf, 1},
-		{0xaac1, 0xaaeb, 42},
-		{0xaaec, 0xaaef, 1},
-		{0xaaf5, 0xaaf6, 1},
-		{0xabe3, 0xabea, 1},
-		{0xabec, 0xabed, 1},
-		{0xfb1e, 0xfe00, 738},
-		{0xfe01, 0xfe0f, 1},
-		{0xfe20, 0xfe26, 1},
-	},
-	R32: []Range32{
-		{0x101fd, 0x10a01, 2052},
-		{0x10a02, 0x10a03, 1},
-		{0x10a05, 0x10a06, 1},
-		{0x10a0c, 0x10a0f, 1},
-		{0x10a38, 0x10a3a, 1},
-		{0x10a3f, 0x11000, 1473},
-		{0x11001, 0x11002, 1},
-		{0x11038, 0x11046, 1},
-		{0x11080, 0x11082, 1},
-		{0x110b0, 0x110ba, 1},
-		{0x11100, 0x11102, 1},
-		{0x11127, 0x11134, 1},
-		{0x11180, 0x11182, 1},
-		{0x111b3, 0x111c0, 1},
-		{0x116ab, 0x116b7, 1},
-		{0x16f51, 0x16f7e, 1},
-		{0x16f8f, 0x16f92, 1},
-		{0x1d165, 0x1d169, 1},
-		{0x1d16d, 0x1d172, 1},
-		{0x1d17b, 0x1d182, 1},
-		{0x1d185, 0x1d18b, 1},
-		{0x1d1aa, 0x1d1ad, 1},
-		{0x1d242, 0x1d244, 1},
-		{0xe0100, 0xe01ef, 1},
-	},
-}
-
-var _Mc = &RangeTable{
-	R16: []Range16{
-		{0x0903, 0x093b, 56},
-		{0x093e, 0x0940, 1},
-		{0x0949, 0x094c, 1},
-		{0x094e, 0x094f, 1},
-		{0x0982, 0x0983, 1},
-		{0x09be, 0x09c0, 1},
-		{0x09c7, 0x09c8, 1},
-		{0x09cb, 0x09cc, 1},
-		{0x09d7, 0x0a03, 44},
-		{0x0a3e, 0x0a40, 1},
-		{0x0a83, 0x0abe, 59},
-		{0x0abf, 0x0ac0, 1},
-		{0x0ac9, 0x0acb, 2},
-		{0x0acc, 0x0b02, 54},
-		{0x0b03, 0x0b3e, 59},
-		{0x0b40, 0x0b47, 7},
-		{0x0b48, 0x0b4b, 3},
-		{0x0b4c, 0x0b57, 11},
-		{0x0bbe, 0x0bbf, 1},
-		{0x0bc1, 0x0bc2, 1},
-		{0x0bc6, 0x0bc8, 1},
-		{0x0bca, 0x0bcc, 1},
-		{0x0bd7, 0x0c01, 42},
-		{0x0c02, 0x0c03, 1},
-		{0x0c41, 0x0c44, 1},
-		{0x0c82, 0x0c83, 1},
-		{0x0cbe, 0x0cc0, 2},
-		{0x0cc1, 0x0cc4, 1},
-		{0x0cc7, 0x0cc8, 1},
-		{0x0cca, 0x0ccb, 1},
-		{0x0cd5, 0x0cd6, 1},
-		{0x0d02, 0x0d03, 1},
-		{0x0d3e, 0x0d40, 1},
-		{0x0d46, 0x0d48, 1},
-		{0x0d4a, 0x0d4c, 1},
-		{0x0d57, 0x0d82, 43},
-		{0x0d83, 0x0dcf, 76},
-		{0x0dd0, 0x0dd1, 1},
-		{0x0dd8, 0x0ddf, 1},
-		{0x0df2, 0x0df3, 1},
-		{0x0f3e, 0x0f3f, 1},
-		{0x0f7f, 0x102b, 172},
-		{0x102c, 0x1031, 5},
-		{0x1038, 0x103b, 3},
-		{0x103c, 0x1056, 26},
-		{0x1057, 0x1062, 11},
-		{0x1063, 0x1064, 1},
-		{0x1067, 0x106d, 1},
-		{0x1083, 0x1084, 1},
-		{0x1087, 0x108c, 1},
-		{0x108f, 0x109a, 11},
-		{0x109b, 0x109c, 1},
-		{0x17b6, 0x17be, 8},
-		{0x17bf, 0x17c5, 1},
-		{0x17c7, 0x17c8, 1},
-		{0x1923, 0x1926, 1},
-		{0x1929, 0x192b, 1},
-		{0x1930, 0x1931, 1},
-		{0x1933, 0x1938, 1},
-		{0x19b0, 0x19c0, 1},
-		{0x19c8, 0x19c9, 1},
-		{0x1a19, 0x1a1a, 1},
-		{0x1a55, 0x1a57, 2},
-		{0x1a61, 0x1a63, 2},
-		{0x1a64, 0x1a6d, 9},
-		{0x1a6e, 0x1a72, 1},
-		{0x1b04, 0x1b35, 49},
-		{0x1b3b, 0x1b3d, 2},
-		{0x1b3e, 0x1b41, 1},
-		{0x1b43, 0x1b44, 1},
-		{0x1b82, 0x1ba1, 31},
-		{0x1ba6, 0x1ba7, 1},
-		{0x1baa, 0x1bac, 2},
-		{0x1bad, 0x1be7, 58},
-		{0x1bea, 0x1bec, 1},
-		{0x1bee, 0x1bf2, 4},
-		{0x1bf3, 0x1c24, 49},
-		{0x1c25, 0x1c2b, 1},
-		{0x1c34, 0x1c35, 1},
-		{0x1ce1, 0x1cf2, 17},
-		{0x1cf3, 0x302e, 4923},
-		{0x302f, 0xa823, 30708},
-		{0xa824, 0xa827, 3},
-		{0xa880, 0xa881, 1},
-		{0xa8b4, 0xa8c3, 1},
-		{0xa952, 0xa953, 1},
-		{0xa983, 0xa9b4, 49},
-		{0xa9b5, 0xa9ba, 5},
-		{0xa9bb, 0xa9bd, 2},
-		{0xa9be, 0xa9c0, 1},
-		{0xaa2f, 0xaa30, 1},
-		{0xaa33, 0xaa34, 1},
-		{0xaa4d, 0xaa7b, 46},
-		{0xaaeb, 0xaaee, 3},
-		{0xaaef, 0xaaf5, 6},
-		{0xabe3, 0xabe4, 1},
-		{0xabe6, 0xabe7, 1},
-		{0xabe9, 0xabea, 1},
-		{0xabec, 0xabec, 1},
-	},
-	R32: []Range32{
-		{0x11000, 0x11000, 1},
-		{0x11002, 0x11082, 128},
-		{0x110b0, 0x110b2, 1},
-		{0x110b7, 0x110b8, 1},
-		{0x1112c, 0x11182, 86},
-		{0x111b3, 0x111b5, 1},
-		{0x111bf, 0x111c0, 1},
-		{0x116ac, 0x116ae, 2},
-		{0x116af, 0x116b6, 7},
-		{0x16f51, 0x16f7e, 1},
-		{0x1d165, 0x1d166, 1},
-		{0x1d16d, 0x1d172, 1},
-	},
-}
-
-var _Me = &RangeTable{
-	R16: []Range16{
-		{0x0488, 0x0489, 1},
-		{0x20dd, 0x20e0, 1},
-		{0x20e2, 0x20e4, 1},
-		{0xa670, 0xa672, 1},
-	},
-}
-
-var _Mn = &RangeTable{
-	R16: []Range16{
-		{0x0300, 0x036f, 1},
-		{0x0483, 0x0487, 1},
-		{0x0591, 0x05bd, 1},
-		{0x05bf, 0x05c1, 2},
-		{0x05c2, 0x05c4, 2},
-		{0x05c5, 0x05c7, 2},
-		{0x0610, 0x061a, 1},
-		{0x064b, 0x065f, 1},
-		{0x0670, 0x06d6, 102},
-		{0x06d7, 0x06dc, 1},
-		{0x06df, 0x06e4, 1},
-		{0x06e7, 0x06e8, 1},
-		{0x06ea, 0x06ed, 1},
-		{0x0711, 0x0730, 31},
-		{0x0731, 0x074a, 1},
-		{0x07a6, 0x07b0, 1},
-		{0x07eb, 0x07f3, 1},
-		{0x0816, 0x0819, 1},
-		{0x081b, 0x0823, 1},
-		{0x0825, 0x0827, 1},
-		{0x0829, 0x082d, 1},
-		{0x0859, 0x085b, 1},
-		{0x08e4, 0x08fe, 1},
-		{0x0900, 0x0902, 1},
-		{0x093a, 0x093c, 2},
-		{0x0941, 0x0948, 1},
-		{0x094d, 0x0951, 4},
-		{0x0952, 0x0957, 1},
-		{0x0962, 0x0963, 1},
-		{0x0981, 0x09bc, 59},
-		{0x09c1, 0x09c4, 1},
-		{0x09cd, 0x09e2, 21},
-		{0x09e3, 0x0a01, 30},
-		{0x0a02, 0x0a3c, 58},
-		{0x0a41, 0x0a42, 1},
-		{0x0a47, 0x0a48, 1},
-		{0x0a4b, 0x0a4d, 1},
-		{0x0a51, 0x0a70, 31},
-		{0x0a71, 0x0a75, 4},
-		{0x0a81, 0x0a82, 1},
-		{0x0abc, 0x0ac1, 5},
-		{0x0ac2, 0x0ac5, 1},
-		{0x0ac7, 0x0ac8, 1},
-		{0x0acd, 0x0ae2, 21},
-		{0x0ae3, 0x0b01, 30},
-		{0x0b3c, 0x0b3f, 3},
-		{0x0b41, 0x0b44, 1},
-		{0x0b4d, 0x0b56, 9},
-		{0x0b62, 0x0b63, 1},
-		{0x0b82, 0x0bc0, 62},
-		{0x0bcd, 0x0c3e, 113},
-		{0x0c3f, 0x0c40, 1},
-		{0x0c46, 0x0c48, 1},
-		{0x0c4a, 0x0c4d, 1},
-		{0x0c55, 0x0c56, 1},
-		{0x0c62, 0x0c63, 1},
-		{0x0cbc, 0x0cbf, 3},
-		{0x0cc6, 0x0ccc, 6},
-		{0x0ccd, 0x0ce2, 21},
-		{0x0ce3, 0x0d41, 94},
-		{0x0d42, 0x0d44, 1},
-		{0x0d4d, 0x0d62, 21},
-		{0x0d63, 0x0dca, 103},
-		{0x0dd2, 0x0dd4, 1},
-		{0x0dd6, 0x0e31, 91},
-		{0x0e34, 0x0e3a, 1},
-		{0x0e47, 0x0e4e, 1},
-		{0x0eb1, 0x0eb4, 3},
-		{0x0eb5, 0x0eb9, 1},
-		{0x0ebb, 0x0ebc, 1},
-		{0x0ec8, 0x0ecd, 1},
-		{0x0f18, 0x0f19, 1},
-		{0x0f35, 0x0f39, 2},
-		{0x0f71, 0x0f7e, 1},
-		{0x0f80, 0x0f84, 1},
-		{0x0f86, 0x0f87, 1},
-		{0x0f8d, 0x0f97, 1},
-		{0x0f99, 0x0fbc, 1},
-		{0x0fc6, 0x102d, 103},
-		{0x102e, 0x1030, 1},
-		{0x1032, 0x1037, 1},
-		{0x1039, 0x103a, 1},
-		{0x103d, 0x103e, 1},
-		{0x1058, 0x1059, 1},
-		{0x105e, 0x1060, 1},
-		{0x1071, 0x1074, 1},
-		{0x1082, 0x1085, 3},
-		{0x1086, 0x108d, 7},
-		{0x109d, 0x135d, 704},
-		{0x135e, 0x135f, 1},
-		{0x1712, 0x1714, 1},
-		{0x1732, 0x1734, 1},
-		{0x1752, 0x1753, 1},
-		{0x1772, 0x1773, 1},
-		{0x17b4, 0x17b5, 1},
-		{0x17b7, 0x17bd, 1},
-		{0x17c6, 0x17c9, 3},
-		{0x17ca, 0x17d3, 1},
-		{0x17dd, 0x180b, 46},
-		{0x180c, 0x180d, 1},
-		{0x18a9, 0x1920, 119},
-		{0x1921, 0x1922, 1},
-		{0x1927, 0x1928, 1},
-		{0x1932, 0x1939, 7},
-		{0x193a, 0x193b, 1},
-		{0x1a17, 0x1a18, 1},
-		{0x1a1b, 0x1a56, 59},
-		{0x1a58, 0x1a5e, 1},
-		{0x1a60, 0x1a62, 2},
-		{0x1a65, 0x1a6c, 1},
-		{0x1a73, 0x1a7c, 1},
-		{0x1a7f, 0x1b00, 129},
-		{0x1b01, 0x1b03, 1},
-		{0x1b34, 0x1b36, 2},
-		{0x1b37, 0x1b3a, 1},
-		{0x1b3c, 0x1b42, 6},
-		{0x1b6b, 0x1b73, 1},
-		{0x1b80, 0x1b81, 1},
-		{0x1ba2, 0x1ba5, 1},
-		{0x1ba8, 0x1ba9, 1},
-		{0x1bab, 0x1be6, 59},
-		{0x1be8, 0x1be9, 1},
-		{0x1bed, 0x1bef, 2},
-		{0x1bf0, 0x1bf1, 1},
-		{0x1c2c, 0x1c33, 1},
-		{0x1c36, 0x1c37, 1},
-		{0x1cd0, 0x1cd2, 1},
-		{0x1cd4, 0x1ce0, 1},
-		{0x1ce2, 0x1ce8, 1},
-		{0x1ced, 0x1cf4, 7},
-		{0x1dc0, 0x1de6, 1},
-		{0x1dfc, 0x1dff, 1},
-		{0x20d0, 0x20dc, 1},
-		{0x20e1, 0x20e5, 4},
-		{0x20e6, 0x20f0, 1},
-		{0x2cef, 0x2cf1, 1},
-		{0x2d7f, 0x2de0, 97},
-		{0x2de1, 0x2dff, 1},
-		{0x302a, 0x302d, 1},
-		{0x3099, 0x309a, 1},
-		{0xa66f, 0xa674, 5},
-		{0xa675, 0xa67d, 1},
-		{0xa69f, 0xa6f0, 81},
-		{0xa6f1, 0xa802, 273},
-		{0xa806, 0xa80b, 5},
-		{0xa825, 0xa826, 1},
-		{0xa8c4, 0xa8e0, 28},
-		{0xa8e1, 0xa8f1, 1},
-		{0xa926, 0xa92d, 1},
-		{0xa947, 0xa951, 1},
-		{0xa980, 0xa982, 1},
-		{0xa9b3, 0xa9b6, 3},
-		{0xa9b7, 0xa9b9, 1},
-		{0xa9bc, 0xaa29, 109},
-		{0xaa2a, 0xaa2e, 1},
-		{0xaa31, 0xaa32, 1},
-		{0xaa35, 0xaa36, 1},
-		{0xaa43, 0xaa4c, 9},
-		{0xaab0, 0xaab2, 2},
-		{0xaab3, 0xaab4, 1},
-		{0xaab7, 0xaab8, 1},
-		{0xaabe, 0xaabf, 1},
-		{0xaac1, 0xaaec, 43},
-		{0xaaed, 0xaaf6, 9},
-		{0xabe5, 0xabe8, 3},
-		{0xabed, 0xfb1e, 20273},
-		{0xfe00, 0xfe0f, 1},
-		{0xfe20, 0xfe26, 1},
-	},
-	R32: []Range32{
-		{0x101fd, 0x10a01, 2052},
-		{0x10a02, 0x10a03, 1},
-		{0x10a05, 0x10a06, 1},
-		{0x10a0c, 0x10a0f, 1},
-		{0x10a38, 0x10a3a, 1},
-		{0x10a3f, 0x11001, 1474},
-		{0x11038, 0x11046, 1},
-		{0x11080, 0x11081, 1},
-		{0x110b3, 0x110b6, 1},
-		{0x110b9, 0x110ba, 1},
-		{0x11100, 0x11102, 1},
-		{0x11127, 0x1112b, 1},
-		{0x1112d, 0x11134, 1},
-		{0x11180, 0x11181, 1},
-		{0x111b6, 0x111be, 1},
-		{0x116ab, 0x116ad, 2},
-		{0x116b0, 0x116b5, 1},
-		{0x116b7, 0x16f8f, 22744},
-		{0x16f90, 0x16f92, 1},
-		{0x1d167, 0x1d169, 1},
-		{0x1d17b, 0x1d182, 1},
-		{0x1d185, 0x1d18b, 1},
-		{0x1d1aa, 0x1d1ad, 1},
-		{0x1d242, 0x1d244, 1},
-		{0xe0100, 0xe01ef, 1},
-	},
-}
-
-var _N = &RangeTable{
-	R16: []Range16{
-		{0x0030, 0x0039, 1},
-		{0x00b2, 0x00b3, 1},
-		{0x00b9, 0x00bc, 3},
-		{0x00bd, 0x00be, 1},
-		{0x0660, 0x0669, 1},
-		{0x06f0, 0x06f9, 1},
-		{0x07c0, 0x07c9, 1},
-		{0x0966, 0x096f, 1},
-		{0x09e6, 0x09ef, 1},
-		{0x09f4, 0x09f9, 1},
-		{0x0a66, 0x0a6f, 1},
-		{0x0ae6, 0x0aef, 1},
-		{0x0b66, 0x0b6f, 1},
-		{0x0b72, 0x0b77, 1},
-		{0x0be6, 0x0bf2, 1},
-		{0x0c66, 0x0c6f, 1},
-		{0x0c78, 0x0c7e, 1},
-		{0x0ce6, 0x0cef, 1},
-		{0x0d66, 0x0d75, 1},
-		{0x0e50, 0x0e59, 1},
-		{0x0ed0, 0x0ed9, 1},
-		{0x0f20, 0x0f33, 1},
-		{0x1040, 0x1049, 1},
-		{0x1090, 0x1099, 1},
-		{0x1369, 0x137c, 1},
-		{0x16ee, 0x16f0, 1},
-		{0x17e0, 0x17e9, 1},
-		{0x17f0, 0x17f9, 1},
-		{0x1810, 0x1819, 1},
-		{0x1946, 0x194f, 1},
-		{0x19d0, 0x19da, 1},
-		{0x1a80, 0x1a89, 1},
-		{0x1a90, 0x1a99, 1},
-		{0x1b50, 0x1b59, 1},
-		{0x1bb0, 0x1bb9, 1},
-		{0x1c40, 0x1c49, 1},
-		{0x1c50, 0x1c59, 1},
-		{0x2070, 0x2074, 4},
-		{0x2075, 0x2079, 1},
-		{0x2080, 0x2089, 1},
-		{0x2150, 0x2182, 1},
-		{0x2185, 0x2189, 1},
-		{0x2460, 0x249b, 1},
-		{0x24ea, 0x24ff, 1},
-		{0x2776, 0x2793, 1},
-		{0x2cfd, 0x3007, 778},
-		{0x3021, 0x3029, 1},
-		{0x3038, 0x303a, 1},
-		{0x3192, 0x3195, 1},
-		{0x3220, 0x3229, 1},
-		{0x3248, 0x324f, 1},
-		{0x3251, 0x325f, 1},
-		{0x3280, 0x3289, 1},
-		{0x32b1, 0x32bf, 1},
-		{0xa620, 0xa629, 1},
-		{0xa6e6, 0xa6ef, 1},
-		{0xa830, 0xa835, 1},
-		{0xa8d0, 0xa8d9, 1},
-		{0xa900, 0xa909, 1},
-		{0xa9d0, 0xa9d9, 1},
-		{0xaa50, 0xaa59, 1},
-		{0xabf0, 0xabf9, 1},
-		{0xff10, 0xff19, 1},
-	},
-	R32: []Range32{
-		{0x10107, 0x10133, 1},
-		{0x10140, 0x10178, 1},
-		{0x1018a, 0x10320, 406},
-		{0x10321, 0x10323, 1},
-		{0x10341, 0x1034a, 9},
-		{0x103d1, 0x103d5, 1},
-		{0x104a0, 0x104a9, 1},
-		{0x10858, 0x1085f, 1},
-		{0x10916, 0x1091b, 1},
-		{0x10a40, 0x10a47, 1},
-		{0x10a7d, 0x10a7e, 1},
-		{0x10b58, 0x10b5f, 1},
-		{0x10b78, 0x10b7f, 1},
-		{0x10e60, 0x10e7e, 1},
-		{0x11052, 0x1106f, 1},
-		{0x110f0, 0x110f9, 1},
-		{0x11136, 0x1113f, 1},
-		{0x111d0, 0x111d9, 1},
-		{0x116c0, 0x116c9, 1},
-		{0x12400, 0x12462, 1},
-		{0x1d360, 0x1d371, 1},
-		{0x1d7ce, 0x1d7ff, 1},
-		{0x1f100, 0x1f10a, 1},
-	},
-	LatinOffset: 4,
-}
-
-var _Nd = &RangeTable{
-	R16: []Range16{
-		{0x0030, 0x0039, 1},
-		{0x0660, 0x0669, 1},
-		{0x06f0, 0x06f9, 1},
-		{0x07c0, 0x07c9, 1},
-		{0x0966, 0x096f, 1},
-		{0x09e6, 0x09ef, 1},
-		{0x0a66, 0x0a6f, 1},
-		{0x0ae6, 0x0aef, 1},
-		{0x0b66, 0x0b6f, 1},
-		{0x0be6, 0x0bef, 1},
-		{0x0c66, 0x0c6f, 1},
-		{0x0ce6, 0x0cef, 1},
-		{0x0d66, 0x0d6f, 1},
-		{0x0e50, 0x0e59, 1},
-		{0x0ed0, 0x0ed9, 1},
-		{0x0f20, 0x0f29, 1},
-		{0x1040, 0x1049, 1},
-		{0x1090, 0x1099, 1},
-		{0x17e0, 0x17e9, 1},
-		{0x1810, 0x1819, 1},
-		{0x1946, 0x194f, 1},
-		{0x19d0, 0x19d9, 1},
-		{0x1a80, 0x1a89, 1},
-		{0x1a90, 0x1a99, 1},
-		{0x1b50, 0x1b59, 1},
-		{0x1bb0, 0x1bb9, 1},
-		{0x1c40, 0x1c49, 1},
-		{0x1c50, 0x1c59, 1},
-		{0xa620, 0xa629, 1},
-		{0xa8d0, 0xa8d9, 1},
-		{0xa900, 0xa909, 1},
-		{0xa9d0, 0xa9d9, 1},
-		{0xaa50, 0xaa59, 1},
-		{0xabf0, 0xabf9, 1},
-		{0xff10, 0xff19, 1},
-	},
-	R32: []Range32{
-		{0x104a0, 0x104a9, 1},
-		{0x11066, 0x1106f, 1},
-		{0x110f0, 0x110f9, 1},
-		{0x11136, 0x1113f, 1},
-		{0x111d0, 0x111d9, 1},
-		{0x116c0, 0x116c9, 1},
-		{0x1d7ce, 0x1d7ff, 1},
-	},
-	LatinOffset: 1,
-}
-
-var _Nl = &RangeTable{
-	R16: []Range16{
-		{0x16ee, 0x16f0, 1},
-		{0x2160, 0x2182, 1},
-		{0x2185, 0x2188, 1},
-		{0x3007, 0x3021, 26},
-		{0x3022, 0x3029, 1},
-		{0x3038, 0x303a, 1},
-		{0xa6e6, 0xa6ef, 1},
-	},
-	R32: []Range32{
-		{0x10140, 0x10174, 1},
-		{0x10341, 0x1034a, 9},
-		{0x103d1, 0x103d5, 1},
-		{0x12400, 0x12462, 1},
-	},
-}
-
-var _No = &RangeTable{
-	R16: []Range16{
-		{0x00b2, 0x00b3, 1},
-		{0x00b9, 0x00bc, 3},
-		{0x00bd, 0x00be, 1},
-		{0x09f4, 0x09f9, 1},
-		{0x0b72, 0x0b77, 1},
-		{0x0bf0, 0x0bf2, 1},
-		{0x0c78, 0x0c7e, 1},
-		{0x0d70, 0x0d75, 1},
-		{0x0f2a, 0x0f33, 1},
-		{0x1369, 0x137c, 1},
-		{0x17f0, 0x17f9, 1},
-		{0x19da, 0x2070, 1686},
-		{0x2074, 0x2079, 1},
-		{0x2080, 0x2089, 1},
-		{0x2150, 0x215f, 1},
-		{0x2189, 0x2460, 727},
-		{0x2461, 0x249b, 1},
-		{0x24ea, 0x24ff, 1},
-		{0x2776, 0x2793, 1},
-		{0x2cfd, 0x3192, 1173},
-		{0x3193, 0x3195, 1},
-		{0x3220, 0x3229, 1},
-		{0x3248, 0x324f, 1},
-		{0x3251, 0x325f, 1},
-		{0x3280, 0x3289, 1},
-		{0x32b1, 0x32bf, 1},
-		{0xa830, 0xa835, 1},
-	},
-	R32: []Range32{
-		{0x10107, 0x10133, 1},
-		{0x10175, 0x10178, 1},
-		{0x1018a, 0x10320, 406},
-		{0x10321, 0x10323, 1},
-		{0x10858, 0x1085f, 1},
-		{0x10916, 0x1091b, 1},
-		{0x10a40, 0x10a47, 1},
-		{0x10a7d, 0x10a7e, 1},
-		{0x10b58, 0x10b5f, 1},
-		{0x10b78, 0x10b7f, 1},
-		{0x10e60, 0x10e7e, 1},
-		{0x11052, 0x11065, 1},
-		{0x1d360, 0x1d371, 1},
-		{0x1f100, 0x1f10a, 1},
-	},
-	LatinOffset: 3,
-}
-
-var _P = &RangeTable{
-	R16: []Range16{
-		{0x0021, 0x0023, 1},
-		{0x0025, 0x002a, 1},
-		{0x002c, 0x002f, 1},
-		{0x003a, 0x003b, 1},
-		{0x003f, 0x0040, 1},
-		{0x005b, 0x005d, 1},
-		{0x005f, 0x007b, 28},
-		{0x007d, 0x00a1, 36},
-		{0x00a7, 0x00ab, 4},
-		{0x00b6, 0x00b7, 1},
-		{0x00bb, 0x00bf, 4},
-		{0x037e, 0x0387, 9},
-		{0x055a, 0x055f, 1},
-		{0x0589, 0x058a, 1},
-		{0x05be, 0x05c0, 2},
-		{0x05c3, 0x05c6, 3},
-		{0x05f3, 0x05f4, 1},
-		{0x0609, 0x060a, 1},
-		{0x060c, 0x060d, 1},
-		{0x061b, 0x061e, 3},
-		{0x061f, 0x066a, 75},
-		{0x066b, 0x066d, 1},
-		{0x06d4, 0x0700, 44},
-		{0x0701, 0x070d, 1},
-		{0x07f7, 0x07f9, 1},
-		{0x0830, 0x083e, 1},
-		{0x085e, 0x0964, 262},
-		{0x0965, 0x0970, 11},
-		{0x0af0, 0x0df4, 772},
-		{0x0e4f, 0x0e5a, 11},
-		{0x0e5b, 0x0f04, 169},
-		{0x0f05, 0x0f12, 1},
-		{0x0f14, 0x0f3a, 38},
-		{0x0f3b, 0x0f3d, 1},
-		{0x0f85, 0x0fd0, 75},
-		{0x0fd1, 0x0fd4, 1},
-		{0x0fd9, 0x0fda, 1},
-		{0x104a, 0x104f, 1},
-		{0x10fb, 0x1360, 613},
-		{0x1361, 0x1368, 1},
-		{0x1400, 0x166d, 621},
-		{0x166e, 0x169b, 45},
-		{0x169c, 0x16eb, 79},
-		{0x16ec, 0x16ed, 1},
-		{0x1735, 0x1736, 1},
-		{0x17d4, 0x17d6, 1},
-		{0x17d8, 0x17da, 1},
-		{0x1800, 0x180a, 1},
-		{0x1944, 0x1945, 1},
-		{0x1a1e, 0x1a1f, 1},
-		{0x1aa0, 0x1aa6, 1},
-		{0x1aa8, 0x1aad, 1},
-		{0x1b5a, 0x1b60, 1},
-		{0x1bfc, 0x1bff, 1},
-		{0x1c3b, 0x1c3f, 1},
-		{0x1c7e, 0x1c7f, 1},
-		{0x1cc0, 0x1cc7, 1},
-		{0x1cd3, 0x2010, 829},
-		{0x2011, 0x2027, 1},
-		{0x2030, 0x2043, 1},
-		{0x2045, 0x2051, 1},
-		{0x2053, 0x205e, 1},
-		{0x207d, 0x207e, 1},
-		{0x208d, 0x208e, 1},
-		{0x2308, 0x230b, 1},
-		{0x2329, 0x232a, 1},
-		{0x2768, 0x2775, 1},
-		{0x27c5, 0x27c6, 1},
-		{0x27e6, 0x27ef, 1},
-		{0x2983, 0x2998, 1},
-		{0x29d8, 0x29db, 1},
-		{0x29fc, 0x29fd, 1},
-		{0x2cf9, 0x2cfc, 1},
-		{0x2cfe, 0x2cff, 1},
-		{0x2d70, 0x2e00, 144},
-		{0x2e01, 0x2e2e, 1},
-		{0x2e30, 0x2e3b, 1},
-		{0x3001, 0x3003, 1},
-		{0x3008, 0x3011, 1},
-		{0x3014, 0x301f, 1},
-		{0x3030, 0x303d, 13},
-		{0x30a0, 0x30fb, 91},
-		{0xa4fe, 0xa4ff, 1},
-		{0xa60d, 0xa60f, 1},
-		{0xa673, 0xa67e, 11},
-		{0xa6f2, 0xa6f7, 1},
-		{0xa874, 0xa877, 1},
-		{0xa8ce, 0xa8cf, 1},
-		{0xa8f8, 0xa8fa, 1},
-		{0xa92e, 0xa92f, 1},
-		{0xa95f, 0xa9c1, 98},
-		{0xa9c2, 0xa9cd, 1},
-		{0xa9de, 0xa9df, 1},
-		{0xaa5c, 0xaa5f, 1},
-		{0xaade, 0xaadf, 1},
-		{0xaaf0, 0xaaf1, 1},
-		{0xabeb, 0xfd3e, 20819},
-		{0xfd3f, 0xfe10, 209},
-		{0xfe11, 0xfe19, 1},
-		{0xfe30, 0xfe52, 1},
-		{0xfe54, 0xfe61, 1},
-		{0xfe63, 0xfe68, 5},
-		{0xfe6a, 0xfe6b, 1},
-		{0xff01, 0xff03, 1},
-		{0xff05, 0xff0a, 1},
-		{0xff0c, 0xff0f, 1},
-		{0xff1a, 0xff1b, 1},
-		{0xff1f, 0xff20, 1},
-		{0xff3b, 0xff3d, 1},
-		{0xff3f, 0xff5b, 28},
-		{0xff5d, 0xff5f, 2},
-		{0xff60, 0xff65, 1},
-	},
-	R32: []Range32{
-		{0x10100, 0x10102, 1},
-		{0x1039f, 0x103d0, 49},
-		{0x10857, 0x1091f, 200},
-		{0x1093f, 0x10a50, 273},
-		{0x10a51, 0x10a58, 1},
-		{0x10a7f, 0x10b39, 186},
-		{0x10b3a, 0x10b3f, 1},
-		{0x11047, 0x1104d, 1},
-		{0x110bb, 0x110bc, 1},
-		{0x110be, 0x110c1, 1},
-		{0x11140, 0x11143, 1},
-		{0x111c5, 0x111c8, 1},
-		{0x12470, 0x12473, 1},
-	},
-	LatinOffset: 11,
-}
-
-var _Pc = &RangeTable{
-	R16: []Range16{
-		{0x005f, 0x203f, 8160},
-		{0x2040, 0x2054, 20},
-		{0xfe33, 0xfe34, 1},
-		{0xfe4d, 0xfe4f, 1},
-		{0xff3f, 0xff3f, 1},
-	},
-}
-
-var _Pd = &RangeTable{
-	R16: []Range16{
-		{0x002d, 0x058a, 1373},
-		{0x05be, 0x1400, 3650},
-		{0x1806, 0x2010, 2058},
-		{0x2011, 0x2015, 1},
-		{0x2e17, 0x2e1a, 3},
-		{0x2e3a, 0x2e3b, 1},
-		{0x301c, 0x3030, 20},
-		{0x30a0, 0xfe31, 52625},
-		{0xfe32, 0xfe58, 38},
-		{0xfe63, 0xff0d, 170},
-	},
-}
-
-var _Pe = &RangeTable{
-	R16: []Range16{
-		{0x0029, 0x005d, 52},
-		{0x007d, 0x0f3b, 3774},
-		{0x0f3d, 0x169c, 1887},
-		{0x2046, 0x207e, 56},
-		{0x208e, 0x2309, 635},
-		{0x230b, 0x232a, 31},
-		{0x2769, 0x2775, 2},
-		{0x27c6, 0x27e7, 33},
-		{0x27e9, 0x27ef, 2},
-		{0x2984, 0x2998, 2},
-		{0x29d9, 0x29db, 2},
-		{0x29fd, 0x2e23, 1062},
-		{0x2e25, 0x2e29, 2},
-		{0x3009, 0x3011, 2},
-		{0x3015, 0x301b, 2},
-		{0x301e, 0x301f, 1},
-		{0xfd3f, 0xfe18, 217},
-		{0xfe36, 0xfe44, 2},
-		{0xfe48, 0xfe5a, 18},
-		{0xfe5c, 0xfe5e, 2},
-		{0xff09, 0xff3d, 52},
-		{0xff5d, 0xff63, 3},
-	},
-	LatinOffset: 1,
-}
-
-var _Pf = &RangeTable{
-	R16: []Range16{
-		{0x00bb, 0x2019, 8030},
-		{0x201d, 0x203a, 29},
-		{0x2e03, 0x2e05, 2},
-		{0x2e0a, 0x2e0d, 3},
-		{0x2e1d, 0x2e21, 4},
-	},
-}
-
-var _Pi = &RangeTable{
-	R16: []Range16{
-		{0x00ab, 0x2018, 8045},
-		{0x201b, 0x201c, 1},
-		{0x201f, 0x2039, 26},
-		{0x2e02, 0x2e04, 2},
-		{0x2e09, 0x2e0c, 3},
-		{0x2e1c, 0x2e20, 4},
-	},
-}
-
-var _Po = &RangeTable{
-	R16: []Range16{
-		{0x0021, 0x0023, 1},
-		{0x0025, 0x0027, 1},
-		{0x002a, 0x002e, 2},
-		{0x002f, 0x003a, 11},
-		{0x003b, 0x003f, 4},
-		{0x0040, 0x005c, 28},
-		{0x00a1, 0x00a7, 6},
-		{0x00b6, 0x00b7, 1},
-		{0x00bf, 0x037e, 703},
-		{0x0387, 0x055a, 467},
-		{0x055b, 0x055f, 1},
-		{0x0589, 0x05c0, 55},
-		{0x05c3, 0x05c6, 3},
-		{0x05f3, 0x05f4, 1},
-		{0x0609, 0x060a, 1},
-		{0x060c, 0x060d, 1},
-		{0x061b, 0x061e, 3},
-		{0x061f, 0x066a, 75},
-		{0x066b, 0x066d, 1},
-		{0x06d4, 0x0700, 44},
-		{0x0701, 0x070d, 1},
-		{0x07f7, 0x07f9, 1},
-		{0x0830, 0x083e, 1},
-		{0x085e, 0x0964, 262},
-		{0x0965, 0x0970, 11},
-		{0x0af0, 0x0df4, 772},
-		{0x0e4f, 0x0e5a, 11},
-		{0x0e5b, 0x0f04, 169},
-		{0x0f05, 0x0f12, 1},
-		{0x0f14, 0x0f85, 113},
-		{0x0fd0, 0x0fd4, 1},
-		{0x0fd9, 0x0fda, 1},
-		{0x104a, 0x104f, 1},
-		{0x10fb, 0x1360, 613},
-		{0x1361, 0x1368, 1},
-		{0x166d, 0x166e, 1},
-		{0x16eb, 0x16ed, 1},
-		{0x1735, 0x1736, 1},
-		{0x17d4, 0x17d6, 1},
-		{0x17d8, 0x17da, 1},
-		{0x1800, 0x1805, 1},
-		{0x1807, 0x180a, 1},
-		{0x1944, 0x1945, 1},
-		{0x1a1e, 0x1a1f, 1},
-		{0x1aa0, 0x1aa6, 1},
-		{0x1aa8, 0x1aad, 1},
-		{0x1b5a, 0x1b60, 1},
-		{0x1bfc, 0x1bff, 1},
-		{0x1c3b, 0x1c3f, 1},
-		{0x1c7e, 0x1c7f, 1},
-		{0x1cc0, 0x1cc7, 1},
-		{0x1cd3, 0x2016, 835},
-		{0x2017, 0x2020, 9},
-		{0x2021, 0x2027, 1},
-		{0x2030, 0x2038, 1},
-		{0x203b, 0x203e, 1},
-		{0x2041, 0x2043, 1},
-		{0x2047, 0x2051, 1},
-		{0x2053, 0x2055, 2},
-		{0x2056, 0x205e, 1},
-		{0x2cf9, 0x2cfc, 1},
-		{0x2cfe, 0x2cff, 1},
-		{0x2d70, 0x2e00, 144},
-		{0x2e01, 0x2e06, 5},
-		{0x2e07, 0x2e08, 1},
-		{0x2e0b, 0x2e0e, 3},
-		{0x2e0f, 0x2e16, 1},
-		{0x2e18, 0x2e19, 1},
-		{0x2e1b, 0x2e1e, 3},
-		{0x2e1f, 0x2e2a, 11},
-		{0x2e2b, 0x2e2e, 1},
-		{0x2e30, 0x2e39, 1},
-		{0x3001, 0x3003, 1},
-		{0x303d, 0x30fb, 190},
-		{0xa4fe, 0xa4ff, 1},
-		{0xa60d, 0xa60f, 1},
-		{0xa673, 0xa67e, 11},
-		{0xa6f2, 0xa6f7, 1},
-		{0xa874, 0xa877, 1},
-		{0xa8ce, 0xa8cf, 1},
-		{0xa8f8, 0xa8fa, 1},
-		{0xa92e, 0xa92f, 1},
-		{0xa95f, 0xa9c1, 98},
-		{0xa9c2, 0xa9cd, 1},
-		{0xa9de, 0xa9df, 1},
-		{0xaa5c, 0xaa5f, 1},
-		{0xaade, 0xaadf, 1},
-		{0xaaf0, 0xaaf1, 1},
-		{0xabeb, 0xfe10, 21029},
-		{0xfe11, 0xfe16, 1},
-		{0xfe19, 0xfe30, 23},
-		{0xfe45, 0xfe46, 1},
-		{0xfe49, 0xfe4c, 1},
-		{0xfe50, 0xfe52, 1},
-		{0xfe54, 0xfe57, 1},
-		{0xfe5f, 0xfe61, 1},
-		{0xfe68, 0xfe6a, 2},
-		{0xfe6b, 0xff01, 150},
-		{0xff02, 0xff03, 1},
-		{0xff05, 0xff07, 1},
-		{0xff0a, 0xff0e, 2},
-		{0xff0f, 0xff1a, 11},
-		{0xff1b, 0xff1f, 4},
-		{0xff20, 0xff3c, 28},
-		{0xff61, 0xff64, 3},
-		{0xff65, 0xff65, 1},
-	},
-	R32: []Range32{
-		{0x10100, 0x10100, 1},
-		{0x10101, 0x10102, 1},
-		{0x1039f, 0x103d0, 49},
-		{0x10857, 0x1091f, 200},
-		{0x1093f, 0x10a50, 273},
-		{0x10a51, 0x10a58, 1},
-		{0x10a7f, 0x10b39, 186},
-		{0x10b3a, 0x10b3f, 1},
-		{0x11047, 0x1104d, 1},
-		{0x110bb, 0x110bc, 1},
-		{0x110be, 0x110c1, 1},
-		{0x11140, 0x11143, 1},
-		{0x111c5, 0x111c8, 1},
-		{0x12470, 0x12473, 1},
-	},
-	LatinOffset: 8,
-}
-
-var _Ps = &RangeTable{
-	R16: []Range16{
-		{0x0028, 0x005b, 51},
-		{0x007b, 0x0f3a, 3775},
-		{0x0f3c, 0x169b, 1887},
-		{0x201a, 0x201e, 4},
-		{0x2045, 0x207d, 56},
-		{0x208d, 0x2308, 635},
-		{0x230a, 0x2329, 31},
-		{0x2768, 0x2774, 2},
-		{0x27c5, 0x27e6, 33},
-		{0x27e8, 0x27ee, 2},
-		{0x2983, 0x2997, 2},
-		{0x29d8, 0x29da, 2},
-		{0x29fc, 0x2e22, 1062},
-		{0x2e24, 0x2e28, 2},
-		{0x3008, 0x3010, 2},
-		{0x3014, 0x301a, 2},
-		{0x301d, 0xfd3e, 52513},
-		{0xfe17, 0xfe35, 30},
-		{0xfe37, 0xfe43, 2},
-		{0xfe47, 0xfe59, 18},
-		{0xfe5b, 0xfe5d, 2},
-		{0xff08, 0xff3b, 51},
-		{0xff5b, 0xff5f, 4},
-		{0xff62, 0xff62, 1},
-	},
-	LatinOffset: 1,
-}
-
-var _S = &RangeTable{
-	R16: []Range16{
-		{0x0024, 0x002b, 7},
-		{0x003c, 0x003e, 1},
-		{0x005e, 0x0060, 2},
-		{0x007c, 0x007e, 2},
-		{0x00a2, 0x00a6, 1},
-		{0x00a8, 0x00a9, 1},
-		{0x00ac, 0x00ae, 2},
-		{0x00af, 0x00b1, 1},
-		{0x00b4, 0x00b8, 4},
-		{0x00d7, 0x00f7, 32},
-		{0x02c2, 0x02c5, 1},
-		{0x02d2, 0x02df, 1},
-		{0x02e5, 0x02eb, 1},
-		{0x02ed, 0x02ef, 2},
-		{0x02f0, 0x02ff, 1},
-		{0x0375, 0x0384, 15},
-		{0x0385, 0x03f6, 113},
-		{0x0482, 0x058f, 269},
-		{0x0606, 0x0608, 1},
-		{0x060b, 0x060e, 3},
-		{0x060f, 0x06de, 207},
-		{0x06e9, 0x06fd, 20},
-		{0x06fe, 0x07f6, 248},
-		{0x09f2, 0x09f3, 1},
-		{0x09fa, 0x09fb, 1},
-		{0x0af1, 0x0b70, 127},
-		{0x0bf3, 0x0bfa, 1},
-		{0x0c7f, 0x0d79, 250},
-		{0x0e3f, 0x0f01, 194},
-		{0x0f02, 0x0f03, 1},
-		{0x0f13, 0x0f15, 2},
-		{0x0f16, 0x0f17, 1},
-		{0x0f1a, 0x0f1f, 1},
-		{0x0f34, 0x0f38, 2},
-		{0x0fbe, 0x0fc5, 1},
-		{0x0fc7, 0x0fcc, 1},
-		{0x0fce, 0x0fcf, 1},
-		{0x0fd5, 0x0fd8, 1},
-		{0x109e, 0x109f, 1},
-		{0x1390, 0x1399, 1},
-		{0x17db, 0x1940, 357},
-		{0x19de, 0x19ff, 1},
-		{0x1b61, 0x1b6a, 1},
-		{0x1b74, 0x1b7c, 1},
-		{0x1fbd, 0x1fbf, 2},
-		{0x1fc0, 0x1fc1, 1},
-		{0x1fcd, 0x1fcf, 1},
-		{0x1fdd, 0x1fdf, 1},
-		{0x1fed, 0x1fef, 1},
-		{0x1ffd, 0x1ffe, 1},
-		{0x2044, 0x2052, 14},
-		{0x207a, 0x207c, 1},
-		{0x208a, 0x208c, 1},
-		{0x20a0, 0x20ba, 1},
-		{0x2100, 0x2101, 1},
-		{0x2103, 0x2106, 1},
-		{0x2108, 0x2109, 1},
-		{0x2114, 0x2116, 2},
-		{0x2117, 0x2118, 1},
-		{0x211e, 0x2123, 1},
-		{0x2125, 0x2129, 2},
-		{0x212e, 0x213a, 12},
-		{0x213b, 0x2140, 5},
-		{0x2141, 0x2144, 1},
-		{0x214a, 0x214d, 1},
-		{0x214f, 0x2190, 65},
-		{0x2191, 0x2307, 1},
-		{0x230c, 0x2328, 1},
-		{0x232b, 0x23f3, 1},
-		{0x2400, 0x2426, 1},
-		{0x2440, 0x244a, 1},
-		{0x249c, 0x24e9, 1},
-		{0x2500, 0x26ff, 1},
-		{0x2701, 0x2767, 1},
-		{0x2794, 0x27c4, 1},
-		{0x27c7, 0x27e5, 1},
-		{0x27f0, 0x2982, 1},
-		{0x2999, 0x29d7, 1},
-		{0x29dc, 0x29fb, 1},
-		{0x29fe, 0x2b4c, 1},
-		{0x2b50, 0x2b59, 1},
-		{0x2ce5, 0x2cea, 1},
-		{0x2e80, 0x2e99, 1},
-		{0x2e9b, 0x2ef3, 1},
-		{0x2f00, 0x2fd5, 1},
-		{0x2ff0, 0x2ffb, 1},
-		{0x3004, 0x3012, 14},
-		{0x3013, 0x3020, 13},
-		{0x3036, 0x3037, 1},
-		{0x303e, 0x303f, 1},
-		{0x309b, 0x309c, 1},
-		{0x3190, 0x3191, 1},
-		{0x3196, 0x319f, 1},
-		{0x31c0, 0x31e3, 1},
-		{0x3200, 0x321e, 1},
-		{0x322a, 0x3247, 1},
-		{0x3250, 0x3260, 16},
-		{0x3261, 0x327f, 1},
-		{0x328a, 0x32b0, 1},
-		{0x32c0, 0x32fe, 1},
-		{0x3300, 0x33ff, 1},
-		{0x4dc0, 0x4dff, 1},
-		{0xa490, 0xa4c6, 1},
-		{0xa700, 0xa716, 1},
-		{0xa720, 0xa721, 1},
-		{0xa789, 0xa78a, 1},
-		{0xa828, 0xa82b, 1},
-		{0xa836, 0xa839, 1},
-		{0xaa77, 0xaa79, 1},
-		{0xfb29, 0xfbb2, 137},
-		{0xfbb3, 0xfbc1, 1},
-		{0xfdfc, 0xfdfd, 1},
-		{0xfe62, 0xfe64, 2},
-		{0xfe65, 0xfe66, 1},
-		{0xfe69, 0xff04, 155},
-		{0xff0b, 0xff1c, 17},
-		{0xff1d, 0xff1e, 1},
-		{0xff3e, 0xff40, 2},
-		{0xff5c, 0xff5e, 2},
-		{0xffe0, 0xffe6, 1},
-		{0xffe8, 0xffee, 1},
-		{0xfffc, 0xfffd, 1},
-	},
-	R32: []Range32{
-		{0x10137, 0x1013f, 1},
-		{0x10179, 0x10189, 1},
-		{0x10190, 0x1019b, 1},
-		{0x101d0, 0x101fc, 1},
-		{0x1d000, 0x1d0f5, 1},
-		{0x1d100, 0x1d126, 1},
-		{0x1d129, 0x1d164, 1},
-		{0x1d16a, 0x1d16c, 1},
-		{0x1d183, 0x1d184, 1},
-		{0x1d18c, 0x1d1a9, 1},
-		{0x1d1ae, 0x1d1dd, 1},
-		{0x1d200, 0x1d241, 1},
-		{0x1d245, 0x1d300, 187},
-		{0x1d301, 0x1d356, 1},
-		{0x1d6c1, 0x1d6db, 26},
-		{0x1d6fb, 0x1d715, 26},
-		{0x1d735, 0x1d74f, 26},
-		{0x1d76f, 0x1d789, 26},
-		{0x1d7a9, 0x1d7c3, 26},
-		{0x1eef0, 0x1eef1, 1},
-		{0x1f000, 0x1f02b, 1},
-		{0x1f030, 0x1f093, 1},
-		{0x1f0a0, 0x1f0ae, 1},
-		{0x1f0b1, 0x1f0be, 1},
-		{0x1f0c1, 0x1f0cf, 1},
-		{0x1f0d1, 0x1f0df, 1},
-		{0x1f110, 0x1f12e, 1},
-		{0x1f130, 0x1f16b, 1},
-		{0x1f170, 0x1f19a, 1},
-		{0x1f1e6, 0x1f202, 1},
-		{0x1f210, 0x1f23a, 1},
-		{0x1f240, 0x1f248, 1},
-		{0x1f250, 0x1f251, 1},
-		{0x1f300, 0x1f320, 1},
-		{0x1f330, 0x1f335, 1},
-		{0x1f337, 0x1f37c, 1},
-		{0x1f380, 0x1f393, 1},
-		{0x1f3a0, 0x1f3c4, 1},
-		{0x1f3c6, 0x1f3ca, 1},
-		{0x1f3e0, 0x1f3f0, 1},
-		{0x1f400, 0x1f43e, 1},
-		{0x1f440, 0x1f442, 2},
-		{0x1f443, 0x1f4f7, 1},
-		{0x1f4f9, 0x1f4fc, 1},
-		{0x1f500, 0x1f53d, 1},
-		{0x1f540, 0x1f543, 1},
-		{0x1f550, 0x1f567, 1},
-		{0x1f5fb, 0x1f640, 1},
-		{0x1f645, 0x1f64f, 1},
-		{0x1f680, 0x1f6c5, 1},
-		{0x1f700, 0x1f773, 1},
-	},
-	LatinOffset: 10,
-}
-
-var _Sc = &RangeTable{
-	R16: []Range16{
-		{0x0024, 0x00a2, 126},
-		{0x00a3, 0x00a5, 1},
-		{0x058f, 0x060b, 124},
-		{0x09f2, 0x09f3, 1},
-		{0x09fb, 0x0af1, 246},
-		{0x0bf9, 0x0e3f, 582},
-		{0x17db, 0x20a0, 2245},
-		{0x20a1, 0x20ba, 1},
-		{0xa838, 0xfdfc, 21956},
-		{0xfe69, 0xff04, 155},
-		{0xffe0, 0xffe1, 1},
-		{0xffe5, 0xffe6, 1},
-	},
-	LatinOffset: 2,
-}
-
-var _Sk = &RangeTable{
-	R16: []Range16{
-		{0x005e, 0x0060, 2},
-		{0x00a8, 0x00af, 7},
-		{0x00b4, 0x00b8, 4},
-		{0x02c2, 0x02c5, 1},
-		{0x02d2, 0x02df, 1},
-		{0x02e5, 0x02eb, 1},
-		{0x02ed, 0x02ef, 2},
-		{0x02f0, 0x02ff, 1},
-		{0x0375, 0x0384, 15},
-		{0x0385, 0x1fbd, 7224},
-		{0x1fbf, 0x1fc1, 1},
-		{0x1fcd, 0x1fcf, 1},
-		{0x1fdd, 0x1fdf, 1},
-		{0x1fed, 0x1fef, 1},
-		{0x1ffd, 0x1ffe, 1},
-		{0x309b, 0x309c, 1},
-		{0xa700, 0xa716, 1},
-		{0xa720, 0xa721, 1},
-		{0xa789, 0xa78a, 1},
-		{0xfbb2, 0xfbc1, 1},
-		{0xff3e, 0xff40, 2},
-		{0xffe3, 0xffe3, 1},
-	},
-	LatinOffset: 3,
-}
-
-var _Sm = &RangeTable{
-	R16: []Range16{
-		{0x002b, 0x003c, 17},
-		{0x003d, 0x003e, 1},
-		{0x007c, 0x007e, 2},
-		{0x00ac, 0x00b1, 5},
-		{0x00d7, 0x00f7, 32},
-		{0x03f6, 0x0606, 528},
-		{0x0607, 0x0608, 1},
-		{0x2044, 0x2052, 14},
-		{0x207a, 0x207c, 1},
-		{0x208a, 0x208c, 1},
-		{0x2118, 0x2140, 40},
-		{0x2141, 0x2144, 1},
-		{0x214b, 0x2190, 69},
-		{0x2191, 0x2194, 1},
-		{0x219a, 0x219b, 1},
-		{0x21a0, 0x21a6, 3},
-		{0x21ae, 0x21ce, 32},
-		{0x21cf, 0x21d2, 3},
-		{0x21d4, 0x21f4, 32},
-		{0x21f5, 0x22ff, 1},
-		{0x2320, 0x2321, 1},
-		{0x237c, 0x239b, 31},
-		{0x239c, 0x23b3, 1},
-		{0x23dc, 0x23e1, 1},
-		{0x25b7, 0x25c1, 10},
-		{0x25f8, 0x25ff, 1},
-		{0x266f, 0x27c0, 337},
-		{0x27c1, 0x27c4, 1},
-		{0x27c7, 0x27e5, 1},
-		{0x27f0, 0x27ff, 1},
-		{0x2900, 0x2982, 1},
-		{0x2999, 0x29d7, 1},
-		{0x29dc, 0x29fb, 1},
-		{0x29fe, 0x2aff, 1},
-		{0x2b30, 0x2b44, 1},
-		{0x2b47, 0x2b4c, 1},
-		{0xfb29, 0xfe62, 825},
-		{0xfe64, 0xfe66, 1},
-		{0xff0b, 0xff1c, 17},
-		{0xff1d, 0xff1e, 1},
-		{0xff5c, 0xff5e, 2},
-		{0xffe2, 0xffe9, 7},
-		{0xffea, 0xffec, 1},
-	},
-	R32: []Range32{
-		{0x1d6c1, 0x1d6db, 26},
-		{0x1d6fb, 0x1d715, 26},
-		{0x1d735, 0x1d74f, 26},
-		{0x1d76f, 0x1d789, 26},
-		{0x1d7a9, 0x1d7c3, 26},
-		{0x1eef0, 0x1eef1, 1},
-	},
-	LatinOffset: 5,
-}
-
-var _So = &RangeTable{
-	R16: []Range16{
-		{0x00a6, 0x00a9, 3},
-		{0x00ae, 0x00b0, 2},
-		{0x0482, 0x060e, 396},
-		{0x060f, 0x06de, 207},
-		{0x06e9, 0x06fd, 20},
-		{0x06fe, 0x07f6, 248},
-		{0x09fa, 0x0b70, 374},
-		{0x0bf3, 0x0bf8, 1},
-		{0x0bfa, 0x0c7f, 133},
-		{0x0d79, 0x0f01, 392},
-		{0x0f02, 0x0f03, 1},
-		{0x0f13, 0x0f15, 2},
-		{0x0f16, 0x0f17, 1},
-		{0x0f1a, 0x0f1f, 1},
-		{0x0f34, 0x0f38, 2},
-		{0x0fbe, 0x0fc5, 1},
-		{0x0fc7, 0x0fcc, 1},
-		{0x0fce, 0x0fcf, 1},
-		{0x0fd5, 0x0fd8, 1},
-		{0x109e, 0x109f, 1},
-		{0x1390, 0x1399, 1},
-		{0x1940, 0x19de, 158},
-		{0x19df, 0x19ff, 1},
-		{0x1b61, 0x1b6a, 1},
-		{0x1b74, 0x1b7c, 1},
-		{0x2100, 0x2101, 1},
-		{0x2103, 0x2106, 1},
-		{0x2108, 0x2109, 1},
-		{0x2114, 0x2116, 2},
-		{0x2117, 0x211e, 7},
-		{0x211f, 0x2123, 1},
-		{0x2125, 0x2129, 2},
-		{0x212e, 0x213a, 12},
-		{0x213b, 0x214a, 15},
-		{0x214c, 0x214d, 1},
-		{0x214f, 0x2195, 70},
-		{0x2196, 0x2199, 1},
-		{0x219c, 0x219f, 1},
-		{0x21a1, 0x21a2, 1},
-		{0x21a4, 0x21a5, 1},
-		{0x21a7, 0x21ad, 1},
-		{0x21af, 0x21cd, 1},
-		{0x21d0, 0x21d1, 1},
-		{0x21d3, 0x21d5, 2},
-		{0x21d6, 0x21f3, 1},
-		{0x2300, 0x2307, 1},
-		{0x230c, 0x231f, 1},
-		{0x2322, 0x2328, 1},
-		{0x232b, 0x237b, 1},
-		{0x237d, 0x239a, 1},
-		{0x23b4, 0x23db, 1},
-		{0x23e2, 0x23f3, 1},
-		{0x2400, 0x2426, 1},
-		{0x2440, 0x244a, 1},
-		{0x249c, 0x24e9, 1},
-		{0x2500, 0x25b6, 1},
-		{0x25b8, 0x25c0, 1},
-		{0x25c2, 0x25f7, 1},
-		{0x2600, 0x266e, 1},
-		{0x2670, 0x26ff, 1},
-		{0x2701, 0x2767, 1},
-		{0x2794, 0x27bf, 1},
-		{0x2800, 0x28ff, 1},
-		{0x2b00, 0x2b2f, 1},
-		{0x2b45, 0x2b46, 1},
-		{0x2b50, 0x2b59, 1},
-		{0x2ce5, 0x2cea, 1},
-		{0x2e80, 0x2e99, 1},
-		{0x2e9b, 0x2ef3, 1},
-		{0x2f00, 0x2fd5, 1},
-		{0x2ff0, 0x2ffb, 1},
-		{0x3004, 0x3012, 14},
-		{0x3013, 0x3020, 13},
-		{0x3036, 0x3037, 1},
-		{0x303e, 0x303f, 1},
-		{0x3190, 0x3191, 1},
-		{0x3196, 0x319f, 1},
-		{0x31c0, 0x31e3, 1},
-		{0x3200, 0x321e, 1},
-		{0x322a, 0x3247, 1},
-		{0x3250, 0x3260, 16},
-		{0x3261, 0x327f, 1},
-		{0x328a, 0x32b0, 1},
-		{0x32c0, 0x32fe, 1},
-		{0x3300, 0x33ff, 1},
-		{0x4dc0, 0x4dff, 1},
-		{0xa490, 0xa4c6, 1},
-		{0xa828, 0xa82b, 1},
-		{0xa836, 0xa837, 1},
-		{0xa839, 0xaa77, 574},
-		{0xaa78, 0xaa79, 1},
-		{0xfdfd, 0xffe4, 487},
-		{0xffe8, 0xffed, 5},
-		{0xffee, 0xfffc, 14},
-		{0xfffd, 0xfffd, 1},
-	},
-	R32: []Range32{
-		{0x10137, 0x10137, 1},
-		{0x10138, 0x1013f, 1},
-		{0x10179, 0x10189, 1},
-		{0x10190, 0x1019b, 1},
-		{0x101d0, 0x101fc, 1},
-		{0x1d000, 0x1d0f5, 1},
-		{0x1d100, 0x1d126, 1},
-		{0x1d129, 0x1d164, 1},
-		{0x1d16a, 0x1d16c, 1},
-		{0x1d183, 0x1d184, 1},
-		{0x1d18c, 0x1d1a9, 1},
-		{0x1d1ae, 0x1d1dd, 1},
-		{0x1d200, 0x1d241, 1},
-		{0x1d245, 0x1d300, 187},
-		{0x1d301, 0x1d356, 1},
-		{0x1f000, 0x1f02b, 1},
-		{0x1f030, 0x1f093, 1},
-		{0x1f0a0, 0x1f0ae, 1},
-		{0x1f0b1, 0x1f0be, 1},
-		{0x1f0c1, 0x1f0cf, 1},
-		{0x1f0d1, 0x1f0df, 1},
-		{0x1f110, 0x1f12e, 1},
-		{0x1f130, 0x1f16b, 1},
-		{0x1f170, 0x1f19a, 1},
-		{0x1f1e6, 0x1f202, 1},
-		{0x1f210, 0x1f23a, 1},
-		{0x1f240, 0x1f248, 1},
-		{0x1f250, 0x1f251, 1},
-		{0x1f300, 0x1f320, 1},
-		{0x1f330, 0x1f335, 1},
-		{0x1f337, 0x1f37c, 1},
-		{0x1f380, 0x1f393, 1},
-		{0x1f3a0, 0x1f3c4, 1},
-		{0x1f3c6, 0x1f3ca, 1},
-		{0x1f3e0, 0x1f3f0, 1},
-		{0x1f400, 0x1f43e, 1},
-		{0x1f440, 0x1f442, 2},
-		{0x1f443, 0x1f4f7, 1},
-		{0x1f4f9, 0x1f4fc, 1},
-		{0x1f500, 0x1f53d, 1},
-		{0x1f540, 0x1f543, 1},
-		{0x1f550, 0x1f567, 1},
-		{0x1f5fb, 0x1f640, 1},
-		{0x1f645, 0x1f64f, 1},
-		{0x1f680, 0x1f6c5, 1},
-		{0x1f700, 0x1f773, 1},
-	},
-	LatinOffset: 2,
-}
-
-var _Z = &RangeTable{
-	R16: []Range16{
-		{0x0020, 0x00a0, 128},
-		{0x1680, 0x2000, 2432},
-		{0x2001, 0x200a, 1},
-		{0x2028, 0x2029, 1},
-		{0x202f, 0x205f, 48},
-		{0x3000, 0x3000, 1},
-	},
-	LatinOffset: 1,
-}
-
-var _Zl = &RangeTable{
-	R16: []Range16{
-		{0x2028, 0x2028, 1},
-	},
-}
-
-var _Zp = &RangeTable{
-	R16: []Range16{
-		{0x2029, 0x2029, 1},
-	},
-}
-
-var _Zs = &RangeTable{
-	R16: []Range16{
-		{0x0020, 0x00a0, 128},
-		{0x1680, 0x2000, 2432},
-		{0x2001, 0x200a, 1},
-		{0x202f, 0x205f, 48},
-		{0x3000, 0x3000, 1},
-	},
-	LatinOffset: 1,
-}
-
-// These variables have type *RangeTable.
-var (
-	Cc     = _Cc // Cc is the set of Unicode characters in category Cc.
-	Cf     = _Cf // Cf is the set of Unicode characters in category Cf.
-	Co     = _Co // Co is the set of Unicode characters in category Co.
-	Cs     = _Cs // Cs is the set of Unicode characters in category Cs.
-	Digit  = _Nd // Digit is the set of Unicode characters with the "decimal digit" property.
-	Nd     = _Nd // Nd is the set of Unicode characters in category Nd.
-	Letter = _L  // Letter/L is the set of Unicode letters, category L.
-	L      = _L
-	Lm     = _Lm // Lm is the set of Unicode characters in category Lm.
-	Lo     = _Lo // Lo is the set of Unicode characters in category Lo.
-	Lower  = _Ll // Lower is the set of Unicode lower case letters.
-	Ll     = _Ll // Ll is the set of Unicode characters in category Ll.
-	Mark   = _M  // Mark/M is the set of Unicode mark characters, category M.
-	M      = _M
-	Mc     = _Mc // Mc is the set of Unicode characters in category Mc.
-	Me     = _Me // Me is the set of Unicode characters in category Me.
-	Mn     = _Mn // Mn is the set of Unicode characters in category Mn.
-	Nl     = _Nl // Nl is the set of Unicode characters in category Nl.
-	No     = _No // No is the set of Unicode characters in category No.
-	Number = _N  // Number/N is the set of Unicode number characters, category N.
-	N      = _N
-	Other  = _C // Other/C is the set of Unicode control and special characters, category C.
-	C      = _C
-	Pc     = _Pc // Pc is the set of Unicode characters in category Pc.
-	Pd     = _Pd // Pd is the set of Unicode characters in category Pd.
-	Pe     = _Pe // Pe is the set of Unicode characters in category Pe.
-	Pf     = _Pf // Pf is the set of Unicode characters in category Pf.
-	Pi     = _Pi // Pi is the set of Unicode characters in category Pi.
-	Po     = _Po // Po is the set of Unicode characters in category Po.
-	Ps     = _Ps // Ps is the set of Unicode characters in category Ps.
-	Punct  = _P  // Punct/P is the set of Unicode punctuation characters, category P.
-	P      = _P
-	Sc     = _Sc // Sc is the set of Unicode characters in category Sc.
-	Sk     = _Sk // Sk is the set of Unicode characters in category Sk.
-	Sm     = _Sm // Sm is the set of Unicode characters in category Sm.
-	So     = _So // So is the set of Unicode characters in category So.
-	Space  = _Z  // Space/Z is the set of Unicode space characters, category Z.
-	Z      = _Z
-	Symbol = _S // Symbol/S is the set of Unicode symbol characters, category S.
-	S      = _S
-	Title  = _Lt // Title is the set of Unicode title case letters.
-	Lt     = _Lt // Lt is the set of Unicode characters in category Lt.
-	Upper  = _Lu // Upper is the set of Unicode upper case letters.
-	Lu     = _Lu // Lu is the set of Unicode characters in category Lu.
-	Zl     = _Zl // Zl is the set of Unicode characters in category Zl.
-	Zp     = _Zp // Zp is the set of Unicode characters in category Zp.
-	Zs     = _Zs // Zs is the set of Unicode characters in category Zs.
-)
-
-// Generated by running
-//	maketables --scripts=all --url=http://www.unicode.org/Public/6.3.0/ucd/
-// DO NOT EDIT
-
-// Scripts is the set of Unicode script tables.
-var Scripts = map[string]*RangeTable{
-	"Arabic":                 Arabic,
-	"Armenian":               Armenian,
-	"Avestan":                Avestan,
-	"Balinese":               Balinese,
-	"Bamum":                  Bamum,
-	"Batak":                  Batak,
-	"Bengali":                Bengali,
-	"Bopomofo":               Bopomofo,
-	"Brahmi":                 Brahmi,
-	"Braille":                Braille,
-	"Buginese":               Buginese,
-	"Buhid":                  Buhid,
-	"Canadian_Aboriginal":    Canadian_Aboriginal,
-	"Carian":                 Carian,
-	"Chakma":                 Chakma,
-	"Cham":                   Cham,
-	"Cherokee":               Cherokee,
-	"Common":                 Common,
-	"Coptic":                 Coptic,
-	"Cuneiform":              Cuneiform,
-	"Cypriot":                Cypriot,
-	"Cyrillic":               Cyrillic,
-	"Deseret":                Deseret,
-	"Devanagari":             Devanagari,
-	"Egyptian_Hieroglyphs":   Egyptian_Hieroglyphs,
-	"Ethiopic":               Ethiopic,
-	"Georgian":               Georgian,
-	"Glagolitic":             Glagolitic,
-	"Gothic":                 Gothic,
-	"Greek":                  Greek,
-	"Gujarati":               Gujarati,
-	"Gurmukhi":               Gurmukhi,
-	"Han":                    Han,
-	"Hangul":                 Hangul,
-	"Hanunoo":                Hanunoo,
-	"Hebrew":                 Hebrew,
-	"Hiragana":               Hiragana,
-	"Imperial_Aramaic":       Imperial_Aramaic,
-	"Inherited":              Inherited,
-	"Inscriptional_Pahlavi":  Inscriptional_Pahlavi,
-	"Inscriptional_Parthian": Inscriptional_Parthian,
-	"Javanese":               Javanese,
-	"Kaithi":                 Kaithi,
-	"Kannada":                Kannada,
-	"Katakana":               Katakana,
-	"Kayah_Li":               Kayah_Li,
-	"Kharoshthi":             Kharoshthi,
-	"Khmer":                  Khmer,
-	"Lao":                    Lao,
-	"Latin":                  Latin,
-	"Lepcha":                 Lepcha,
-	"Limbu":                  Limbu,
-	"Linear_B":               Linear_B,
-	"Lisu":                   Lisu,
-	"Lycian":                 Lycian,
-	"Lydian":                 Lydian,
-	"Malayalam":              Malayalam,
-	"Mandaic":                Mandaic,
-	"Meetei_Mayek":           Meetei_Mayek,
-	"Meroitic_Cursive":       Meroitic_Cursive,
-	"Meroitic_Hieroglyphs":   Meroitic_Hieroglyphs,
-	"Miao":                   Miao,
-	"Mongolian":              Mongolian,
-	"Myanmar":                Myanmar,
-	"New_Tai_Lue":            New_Tai_Lue,
-	"Nko":                    Nko,
-	"Ogham":                  Ogham,
-	"Ol_Chiki":               Ol_Chiki,
-	"Old_Italic":             Old_Italic,
-	"Old_Persian":            Old_Persian,
-	"Old_South_Arabian":      Old_South_Arabian,
-	"Old_Turkic":             Old_Turkic,
-	"Oriya":                  Oriya,
-	"Osmanya":                Osmanya,
-	"Phags_Pa":               Phags_Pa,
-	"Phoenician":             Phoenician,
-	"Rejang":                 Rejang,
-	"Runic":                  Runic,
-	"Samaritan":              Samaritan,
-	"Saurashtra":             Saurashtra,
-	"Sharada":                Sharada,
-	"Shavian":                Shavian,
-	"Sinhala":                Sinhala,
-	"Sora_Sompeng":           Sora_Sompeng,
-	"Sundanese":              Sundanese,
-	"Syloti_Nagri":           Syloti_Nagri,
-	"Syriac":                 Syriac,
-	"Tagalog":                Tagalog,
-	"Tagbanwa":               Tagbanwa,
-	"Tai_Le":                 Tai_Le,
-	"Tai_Tham":               Tai_Tham,
-	"Tai_Viet":               Tai_Viet,
-	"Takri":                  Takri,
-	"Tamil":                  Tamil,
-	"Telugu":                 Telugu,
-	"Thaana":                 Thaana,
-	"Thai":                   Thai,
-	"Tibetan":                Tibetan,
-	"Tifinagh":               Tifinagh,
-	"Ugaritic":               Ugaritic,
-	"Vai":                    Vai,
-	"Yi":                     Yi,
-}
-
-var _Arabic = &RangeTable{
-	R16: []Range16{
-		{0x0600, 0x0604, 1},
-		{0x0606, 0x060b, 1},
-		{0x060d, 0x061a, 1},
-		{0x061c, 0x061c, 1},
-		{0x061e, 0x061e, 1},
-		{0x0620, 0x063f, 1},
-		{0x0641, 0x064a, 1},
-		{0x0656, 0x065f, 1},
-		{0x066a, 0x066f, 1},
-		{0x0671, 0x06dc, 1},
-		{0x06de, 0x06ff, 1},
-		{0x0750, 0x077f, 1},
-		{0x08a0, 0x08a0, 1},
-		{0x08a2, 0x08ac, 1},
-		{0x08e4, 0x08fe, 1},
-		{0xfb50, 0xfbc1, 1},
-		{0xfbd3, 0xfd3d, 1},
-		{0xfd50, 0xfd8f, 1},
-		{0xfd92, 0xfdc7, 1},
-		{0xfdf0, 0xfdfc, 1},
-		{0xfe70, 0xfe74, 1},
-		{0xfe76, 0xfefc, 1},
-	},
-	R32: []Range32{
-		{0x10e60, 0x10e7e, 1},
-		{0x1ee00, 0x1ee03, 1},
-		{0x1ee05, 0x1ee1f, 1},
-		{0x1ee21, 0x1ee22, 1},
-		{0x1ee24, 0x1ee24, 1},
-		{0x1ee27, 0x1ee27, 1},
-		{0x1ee29, 0x1ee32, 1},
-		{0x1ee34, 0x1ee37, 1},
-		{0x1ee39, 0x1ee39, 1},
-		{0x1ee3b, 0x1ee3b, 1},
-		{0x1ee42, 0x1ee42, 1},
-		{0x1ee47, 0x1ee47, 1},
-		{0x1ee49, 0x1ee49, 1},
-		{0x1ee4b, 0x1ee4b, 1},
-		{0x1ee4d, 0x1ee4f, 1},
-		{0x1ee51, 0x1ee52, 1},
-		{0x1ee54, 0x1ee54, 1},
-		{0x1ee57, 0x1ee57, 1},
-		{0x1ee59, 0x1ee59, 1},
-		{0x1ee5b, 0x1ee5b, 1},
-		{0x1ee5d, 0x1ee5d, 1},
-		{0x1ee5f, 0x1ee5f, 1},
-		{0x1ee61, 0x1ee62, 1},
-		{0x1ee64, 0x1ee64, 1},
-		{0x1ee67, 0x1ee6a, 1},
-		{0x1ee6c, 0x1ee72, 1},
-		{0x1ee74, 0x1ee77, 1},
-		{0x1ee79, 0x1ee7c, 1},
-		{0x1ee7e, 0x1ee7e, 1},
-		{0x1ee80, 0x1ee89, 1},
-		{0x1ee8b, 0x1ee9b, 1},
-		{0x1eea1, 0x1eea3, 1},
-		{0x1eea5, 0x1eea9, 1},
-		{0x1eeab, 0x1eebb, 1},
-		{0x1eef0, 0x1eef1, 1},
-	},
-}
-
-var _Armenian = &RangeTable{
-	R16: []Range16{
-		{0x0531, 0x0556, 1},
-		{0x0559, 0x055f, 1},
-		{0x0561, 0x0587, 1},
-		{0x058a, 0x058a, 1},
-		{0x058f, 0x058f, 1},
-		{0xfb13, 0xfb17, 1},
-	},
-}
-
-var _Avestan = &RangeTable{
-	R16: []Range16{},
-	R32: []Range32{
-		{0x10b00, 0x10b35, 1},
-		{0x10b39, 0x10b3f, 1},
-	},
-}
-
-var _Balinese = &RangeTable{
-	R16: []Range16{
-		{0x1b00, 0x1b4b, 1},
-		{0x1b50, 0x1b7c, 1},
-	},
-}
-
-var _Bamum = &RangeTable{
-	R16: []Range16{
-		{0xa6a0, 0xa6f7, 1},
-	},
-	R32: []Range32{
-		{0x16800, 0x16a38, 1},
-	},
-}
-
-var _Batak = &RangeTable{
-	R16: []Range16{
-		{0x1bc0, 0x1bf3, 1},
-		{0x1bfc, 0x1bff, 1},
-	},
-}
-
-var _Bengali = &RangeTable{
-	R16: []Range16{
-		{0x0981, 0x0983, 1},
-		{0x0985, 0x098c, 1},
-		{0x098f, 0x0990, 1},
-		{0x0993, 0x09a8, 1},
-		{0x09aa, 0x09b0, 1},
-		{0x09b2, 0x09b2, 1},
-		{0x09b6, 0x09b9, 1},
-		{0x09bc, 0x09c4, 1},
-		{0x09c7, 0x09c8, 1},
-		{0x09cb, 0x09ce, 1},
-		{0x09d7, 0x09d7, 1},
-		{0x09dc, 0x09dd, 1},
-		{0x09df, 0x09e3, 1},
-		{0x09e6, 0x09fb, 1},
-	},
-}
-
-var _Bopomofo = &RangeTable{
-	R16: []Range16{
-		{0x02ea, 0x02eb, 1},
-		{0x3105, 0x312d, 1},
-		{0x31a0, 0x31ba, 1},
-	},
-}
-
-var _Brahmi = &RangeTable{
-	R16: []Range16{},
-	R32: []Range32{
-		{0x11000, 0x1104d, 1},
-		{0x11052, 0x1106f, 1},
-	},
-}
-
-var _Braille = &RangeTable{
-	R16: []Range16{
-		{0x2800, 0x28ff, 1},
-	},
-}
-
-var _Buginese = &RangeTable{
-	R16: []Range16{
-		{0x1a00, 0x1a1b, 1},
-		{0x1a1e, 0x1a1f, 1},
-	},
-}
-
-var _Buhid = &RangeTable{
-	R16: []Range16{
-		{0x1740, 0x1753, 1},
-	},
-}
-
-var _Canadian_Aboriginal = &RangeTable{
-	R16: []Range16{
-		{0x1400, 0x167f, 1},
-		{0x18b0, 0x18f5, 1},
-	},
-}
-
-var _Carian = &RangeTable{
-	R16: []Range16{},
-	R32: []Range32{
-		{0x102a0, 0x102d0, 1},
-	},
-}
-
-var _Chakma = &RangeTable{
-	R16: []Range16{},
-	R32: []Range32{
-		{0x11100, 0x11134, 1},
-		{0x11136, 0x11143, 1},
-	},
-}
-
-var _Cham = &RangeTable{
-	R16: []Range16{
-		{0xaa00, 0xaa36, 1},
-		{0xaa40, 0xaa4d, 1},
-		{0xaa50, 0xaa59, 1},
-		{0xaa5c, 0xaa5f, 1},
-	},
-}
-
-var _Cherokee = &RangeTable{
-	R16: []Range16{
-		{0x13a0, 0x13f4, 1},
-	},
-}
-
-var _Common = &RangeTable{
-	R16: []Range16{
-		{0x0000, 0x0040, 1},
-		{0x005b, 0x0060, 1},
-		{0x007b, 0x00a9, 1},
-		{0x00ab, 0x00b9, 1},
-		{0x00bb, 0x00bf, 1},
-		{0x00d7, 0x00d7, 1},
-		{0x00f7, 0x00f7, 1},
-		{0x02b9, 0x02df, 1},
-		{0x02e5, 0x02e9, 1},
-		{0x02ec, 0x02ff, 1},
-		{0x0374, 0x0374, 1},
-		{0x037e, 0x037e, 1},
-		{0x0385, 0x0385, 1},
-		{0x0387, 0x0387, 1},
-		{0x0589, 0x0589, 1},
-		{0x060c, 0x060c, 1},
-		{0x061b, 0x061b, 1},
-		{0x061f, 0x061f, 1},
-		{0x0640, 0x0640, 1},
-		{0x0660, 0x0669, 1},
-		{0x06dd, 0x06dd, 1},
-		{0x0964, 0x0965, 1},
-		{0x0e3f, 0x0e3f, 1},
-		{0x0fd5, 0x0fd8, 1},
-		{0x10fb, 0x10fb, 1},
-		{0x16eb, 0x16ed, 1},
-		{0x1735, 0x1736, 1},
-		{0x1802, 0x1803, 1},
-		{0x1805, 0x1805, 1},
-		{0x1cd3, 0x1cd3, 1},
-		{0x1ce1, 0x1ce1, 1},
-		{0x1ce9, 0x1cec, 1},
-		{0x1cee, 0x1cf3, 1},
-		{0x1cf5, 0x1cf6, 1},
-		{0x2000, 0x200b, 1},
-		{0x200e, 0x2064, 1},
-		{0x2066, 0x2070, 1},
-		{0x2074, 0x207e, 1},
-		{0x2080, 0x208e, 1},
-		{0x20a0, 0x20ba, 1},
-		{0x2100, 0x2125, 1},
-		{0x2127, 0x2129, 1},
-		{0x212c, 0x2131, 1},
-		{0x2133, 0x214d, 1},
-		{0x214f, 0x215f, 1},
-		{0x2189, 0x2189, 1},
-		{0x2190, 0x23f3, 1},
-		{0x2400, 0x2426, 1},
-		{0x2440, 0x244a, 1},
-		{0x2460, 0x26ff, 1},
-		{0x2701, 0x27ff, 1},
-		{0x2900, 0x2b4c, 1},
-		{0x2b50, 0x2b59, 1},
-		{0x2e00, 0x2e3b, 1},
-		{0x2ff0, 0x2ffb, 1},
-		{0x3000, 0x3004, 1},
-		{0x3006, 0x3006, 1},
-		{0x3008, 0x3020, 1},
-		{0x3030, 0x3037, 1},
-		{0x303c, 0x303f, 1},
-		{0x309b, 0x309c, 1},
-		{0x30a0, 0x30a0, 1},
-		{0x30fb, 0x30fc, 1},
-		{0x3190, 0x319f, 1},
-		{0x31c0, 0x31e3, 1},
-		{0x3220, 0x325f, 1},
-		{0x327f, 0x32cf, 1},
-		{0x3358, 0x33ff, 1},
-		{0x4dc0, 0x4dff, 1},
-		{0xa700, 0xa721, 1},
-		{0xa788, 0xa78a, 1},
-		{0xa830, 0xa839, 1},
-		{0xa9cf, 0xa9cf, 1},
-		{0xfd3e, 0xfd3f, 1},
-		{0xfdfd, 0xfdfd, 1},
-		{0xfe10, 0xfe19, 1},
-		{0xfe30, 0xfe52, 1},
-		{0xfe54, 0xfe66, 1},
-		{0xfe68, 0xfe6b, 1},
-		{0xfeff, 0xfeff, 1},
-		{0xff01, 0xff20, 1},
-		{0xff3b, 0xff40, 1},
-		{0xff5b, 0xff65, 1},
-		{0xff70, 0xff70, 1},
-		{0xff9e, 0xff9f, 1},
-		{0xffe0, 0xffe6, 1},
-		{0xffe8, 0xffee, 1},
-		{0xfff9, 0xfffd, 1},
-	},
-	R32: []Range32{
-		{0x10100, 0x10102, 1},
-		{0x10107, 0x10133, 1},
-		{0x10137, 0x1013f, 1},
-		{0x10190, 0x1019b, 1},
-		{0x101d0, 0x101fc, 1},
-		{0x1d000, 0x1d0f5, 1},
-		{0x1d100, 0x1d126, 1},
-		{0x1d129, 0x1d166, 1},
-		{0x1d16a, 0x1d17a, 1},
-		{0x1d183, 0x1d184, 1},
-		{0x1d18c, 0x1d1a9, 1},
-		{0x1d1ae, 0x1d1dd, 1},
-		{0x1d300, 0x1d356, 1},
-		{0x1d360, 0x1d371, 1},
-		{0x1d400, 0x1d454, 1},
-		{0x1d456, 0x1d49c, 1},
-		{0x1d49e, 0x1d49f, 1},
-		{0x1d4a2, 0x1d4a2, 1},
-		{0x1d4a5, 0x1d4a6, 1},
-		{0x1d4a9, 0x1d4ac, 1},
-		{0x1d4ae, 0x1d4b9, 1},
-		{0x1d4bb, 0x1d4bb, 1},
-		{0x1d4bd, 0x1d4c3, 1},
-		{0x1d4c5, 0x1d505, 1},
-		{0x1d507, 0x1d50a, 1},
-		{0x1d50d, 0x1d514, 1},
-		{0x1d516, 0x1d51c, 1},
-		{0x1d51e, 0x1d539, 1},
-		{0x1d53b, 0x1d53e, 1},
-		{0x1d540, 0x1d544, 1},
-		{0x1d546, 0x1d546, 1},
-		{0x1d54a, 0x1d550, 1},
-		{0x1d552, 0x1d6a5, 1},
-		{0x1d6a8, 0x1d7cb, 1},
-		{0x1d7ce, 0x1d7ff, 1},
-		{0x1f000, 0x1f02b, 1},
-		{0x1f030, 0x1f093, 1},
-		{0x1f0a0, 0x1f0ae, 1},
-		{0x1f0b1, 0x1f0be, 1},
-		{0x1f0c1, 0x1f0cf, 1},
-		{0x1f0d1, 0x1f0df, 1},
-		{0x1f100, 0x1f10a, 1},
-		{0x1f110, 0x1f12e, 1},
-		{0x1f130, 0x1f16b, 1},
-		{0x1f170, 0x1f19a, 1},
-		{0x1f1e6, 0x1f1ff, 1},
-		{0x1f201, 0x1f202, 1},
-		{0x1f210, 0x1f23a, 1},
-		{0x1f240, 0x1f248, 1},
-		{0x1f250, 0x1f251, 1},
-		{0x1f300, 0x1f320, 1},
-		{0x1f330, 0x1f335, 1},
-		{0x1f337, 0x1f37c, 1},
-		{0x1f380, 0x1f393, 1},
-		{0x1f3a0, 0x1f3c4, 1},
-		{0x1f3c6, 0x1f3ca, 1},
-		{0x1f3e0, 0x1f3f0, 1},
-		{0x1f400, 0x1f43e, 1},
-		{0x1f440, 0x1f440, 1},
-		{0x1f442, 0x1f4f7, 1},
-		{0x1f4f9, 0x1f4fc, 1},
-		{0x1f500, 0x1f53d, 1},
-		{0x1f540, 0x1f543, 1},
-		{0x1f550, 0x1f567, 1},
-		{0x1f5fb, 0x1f640, 1},
-		{0x1f645, 0x1f64f, 1},
-		{0x1f680, 0x1f6c5, 1},
-		{0x1f700, 0x1f773, 1},
-		{0xe0001, 0xe0001, 1},
-		{0xe0020, 0xe007f, 1},
-	},
-	LatinOffset: 7,
-}
-
-var _Coptic = &RangeTable{
-	R16: []Range16{
-		{0x03e2, 0x03ef, 1},
-		{0x2c80, 0x2cf3, 1},
-		{0x2cf9, 0x2cff, 1},
-	},
-}
-
-var _Cuneiform = &RangeTable{
-	R16: []Range16{},
-	R32: []Range32{
-		{0x12000, 0x1236e, 1},
-		{0x12400, 0x12462, 1},
-		{0x12470, 0x12473, 1},
-	},
-}
-
-var _Cypriot = &RangeTable{
-	R16: []Range16{},
-	R32: []Range32{
-		{0x10800, 0x10805, 1},
-		{0x10808, 0x10808, 1},
-		{0x1080a, 0x10835, 1},
-		{0x10837, 0x10838, 1},
-		{0x1083c, 0x1083c, 1},
-		{0x1083f, 0x1083f, 1},
-	},
-}
-
-var _Cyrillic = &RangeTable{
-	R16: []Range16{
-		{0x0400, 0x0484, 1},
-		{0x0487, 0x0527, 1},
-		{0x1d2b, 0x1d2b, 1},
-		{0x1d78, 0x1d78, 1},
-		{0x2de0, 0x2dff, 1},
-		{0xa640, 0xa697, 1},
-		{0xa69f, 0xa69f, 1},
-	},
-}
-
-var _Deseret = &RangeTable{
-	R16: []Range16{},
-	R32: []Range32{
-		{0x10400, 0x1044f, 1},
-	},
-}
-
-var _Devanagari = &RangeTable{
-	R16: []Range16{
-		{0x0900, 0x0950, 1},
-		{0x0953, 0x0963, 1},
-		{0x0966, 0x0977, 1},
-		{0x0979, 0x097f, 1},
-		{0xa8e0, 0xa8fb, 1},
-	},
-}
-
-var _Egyptian_Hieroglyphs = &RangeTable{
-	R16: []Range16{},
-	R32: []Range32{
-		{0x13000, 0x1342e, 1},
-	},
-}
-
-var _Ethiopic = &RangeTable{
-	R16: []Range16{
-		{0x1200, 0x1248, 1},
-		{0x124a, 0x124d, 1},
-		{0x1250, 0x1256, 1},
-		{0x1258, 0x1258, 1},
-		{0x125a, 0x125d, 1},
-		{0x1260, 0x1288, 1},
-		{0x128a, 0x128d, 1},
-		{0x1290, 0x12b0, 1},
-		{0x12b2, 0x12b5, 1},
-		{0x12b8, 0x12be, 1},
-		{0x12c0, 0x12c0, 1},
-		{0x12c2, 0x12c5, 1},
-		{0x12c8, 0x12d6, 1},
-		{0x12d8, 0x1310, 1},
-		{0x1312, 0x1315, 1},
-		{0x1318, 0x135a, 1},
-		{0x135d, 0x137c, 1},
-		{0x1380, 0x1399, 1},
-		{0x2d80, 0x2d96, 1},
-		{0x2da0, 0x2da6, 1},
-		{0x2da8, 0x2dae, 1},
-		{0x2db0, 0x2db6, 1},
-		{0x2db8, 0x2dbe, 1},
-		{0x2dc0, 0x2dc6, 1},
-		{0x2dc8, 0x2dce, 1},
-		{0x2dd0, 0x2dd6, 1},
-		{0x2dd8, 0x2dde, 1},
-		{0xab01, 0xab06, 1},
-		{0xab09, 0xab0e, 1},
-		{0xab11, 0xab16, 1},
-		{0xab20, 0xab26, 1},
-		{0xab28, 0xab2e, 1},
-	},
-}
-
-var _Georgian = &RangeTable{
-	R16: []Range16{
-		{0x10a0, 0x10c5, 1},
-		{0x10c7, 0x10c7, 1},
-		{0x10cd, 0x10cd, 1},
-		{0x10d0, 0x10fa, 1},
-		{0x10fc, 0x10ff, 1},
-		{0x2d00, 0x2d25, 1},
-		{0x2d27, 0x2d27, 1},
-		{0x2d2d, 0x2d2d, 1},
-	},
-}
-
-var _Glagolitic = &RangeTable{
-	R16: []Range16{
-		{0x2c00, 0x2c2e, 1},
-		{0x2c30, 0x2c5e, 1},
-	},
-}
-
-var _Gothic = &RangeTable{
-	R16: []Range16{},
-	R32: []Range32{
-		{0x10330, 0x1034a, 1},
-	},
-}
-
-var _Greek = &RangeTable{
-	R16: []Range16{
-		{0x0370, 0x0373, 1},
-		{0x0375, 0x0377, 1},
-		{0x037a, 0x037d, 1},
-		{0x0384, 0x0384, 1},
-		{0x0386, 0x0386, 1},
-		{0x0388, 0x038a, 1},
-		{0x038c, 0x038c, 1},
-		{0x038e, 0x03a1, 1},
-		{0x03a3, 0x03e1, 1},
-		{0x03f0, 0x03ff, 1},
-		{0x1d26, 0x1d2a, 1},
-		{0x1d5d, 0x1d61, 1},
-		{0x1d66, 0x1d6a, 1},
-		{0x1dbf, 0x1dbf, 1},
-		{0x1f00, 0x1f15, 1},
-		{0x1f18, 0x1f1d, 1},
-		{0x1f20, 0x1f45, 1},
-		{0x1f48, 0x1f4d, 1},
-		{0x1f50, 0x1f57, 1},
-		{0x1f59, 0x1f59, 1},
-		{0x1f5b, 0x1f5b, 1},
-		{0x1f5d, 0x1f5d, 1},
-		{0x1f5f, 0x1f7d, 1},
-		{0x1f80, 0x1fb4, 1},
-		{0x1fb6, 0x1fc4, 1},
-		{0x1fc6, 0x1fd3, 1},
-		{0x1fd6, 0x1fdb, 1},
-		{0x1fdd, 0x1fef, 1},
-		{0x1ff2, 0x1ff4, 1},
-		{0x1ff6, 0x1ffe, 1},
-		{0x2126, 0x2126, 1},
-	},
-	R32: []Range32{
-		{0x10140, 0x1018a, 1},
-		{0x1d200, 0x1d245, 1},
-	},
-}
-
-var _Gujarati = &RangeTable{
-	R16: []Range16{
-		{0x0a81, 0x0a83, 1},
-		{0x0a85, 0x0a8d, 1},
-		{0x0a8f, 0x0a91, 1},
-		{0x0a93, 0x0aa8, 1},
-		{0x0aaa, 0x0ab0, 1},
-		{0x0ab2, 0x0ab3, 1},
-		{0x0ab5, 0x0ab9, 1},
-		{0x0abc, 0x0ac5, 1},
-		{0x0ac7, 0x0ac9, 1},
-		{0x0acb, 0x0acd, 1},
-		{0x0ad0, 0x0ad0, 1},
-		{0x0ae0, 0x0ae3, 1},
-		{0x0ae6, 0x0af1, 1},
-	},
-}
-
-var _Gurmukhi = &RangeTable{
-	R16: []Range16{
-		{0x0a01, 0x0a03, 1},
-		{0x0a05, 0x0a0a, 1},
-		{0x0a0f, 0x0a10, 1},
-		{0x0a13, 0x0a28, 1},
-		{0x0a2a, 0x0a30, 1},
-		{0x0a32, 0x0a33, 1},
-		{0x0a35, 0x0a36, 1},
-		{0x0a38, 0x0a39, 1},
-		{0x0a3c, 0x0a3c, 1},
-		{0x0a3e, 0x0a42, 1},
-		{0x0a47, 0x0a48, 1},
-		{0x0a4b, 0x0a4d, 1},
-		{0x0a51, 0x0a51, 1},
-		{0x0a59, 0x0a5c, 1},
-		{0x0a5e, 0x0a5e, 1},
-		{0x0a66, 0x0a75, 1},
-	},
-}
-
-var _Han = &RangeTable{
-	R16: []Range16{
-		{0x2e80, 0x2e99, 1},
-		{0x2e9b, 0x2ef3, 1},
-		{0x2f00, 0x2fd5, 1},
-		{0x3005, 0x3005, 1},
-		{0x3007, 0x3007, 1},
-		{0x3021, 0x3029, 1},
-		{0x3038, 0x303b, 1},
-		{0x3400, 0x4db5, 1},
-		{0x4e00, 0x9fcc, 1},
-		{0xf900, 0xfa6d, 1},
-		{0xfa70, 0xfad9, 1},
-	},
-	R32: []Range32{
-		{0x20000, 0x2a6d6, 1},
-		{0x2a700, 0x2b734, 1},
-		{0x2b740, 0x2b81d, 1},
-		{0x2f800, 0x2fa1d, 1},
-	},
-}
-
-var _Hangul = &RangeTable{
-	R16: []Range16{
-		{0x1100, 0x11ff, 1},
-		{0x302e, 0x302f, 1},
-		{0x3131, 0x318e, 1},
-		{0x3200, 0x321e, 1},
-		{0x3260, 0x327e, 1},
-		{0xa960, 0xa97c, 1},
-		{0xac00, 0xd7a3, 1},
-		{0xd7b0, 0xd7c6, 1},
-		{0xd7cb, 0xd7fb, 1},
-		{0xffa0, 0xffbe, 1},
-		{0xffc2, 0xffc7, 1},
-		{0xffca, 0xffcf, 1},
-		{0xffd2, 0xffd7, 1},
-		{0xffda, 0xffdc, 1},
-	},
-}
-
-var _Hanunoo = &RangeTable{
-	R16: []Range16{
-		{0x1720, 0x1734, 1},
-	},
-}
-
-var _Hebrew = &RangeTable{
-	R16: []Range16{
-		{0x0591, 0x05c7, 1},
-		{0x05d0, 0x05ea, 1},
-		{0x05f0, 0x05f4, 1},
-		{0xfb1d, 0xfb36, 1},
-		{0xfb38, 0xfb3c, 1},
-		{0xfb3e, 0xfb3e, 1},
-		{0xfb40, 0xfb41, 1},
-		{0xfb43, 0xfb44, 1},
-		{0xfb46, 0xfb4f, 1},
-	},
-}
-
-var _Hiragana = &RangeTable{
-	R16: []Range16{
-		{0x3041, 0x3096, 1},
-		{0x309d, 0x309f, 1},
-	},
-	R32: []Range32{
-		{0x1b001, 0x1b001, 1},
-		{0x1f200, 0x1f200, 1},
-	},
-}
-
-var _Imperial_Aramaic = &RangeTable{
-	R16: []Range16{},
-	R32: []Range32{
-		{0x10840, 0x10855, 1},
-		{0x10857, 0x1085f, 1},
-	},
-}
-
-var _Inherited = &RangeTable{
-	R16: []Range16{
-		{0x0300, 0x036f, 1},
-		{0x0485, 0x0486, 1},
-		{0x064b, 0x0655, 1},
-		{0x0670, 0x0670, 1},
-		{0x0951, 0x0952, 1},
-		{0x1cd0, 0x1cd2, 1},
-		{0x1cd4, 0x1ce0, 1},
-		{0x1ce2, 0x1ce8, 1},
-		{0x1ced, 0x1ced, 1},
-		{0x1cf4, 0x1cf4, 1},
-		{0x1dc0, 0x1de6, 1},
-		{0x1dfc, 0x1dff, 1},
-		{0x200c, 0x200d, 1},
-		{0x20d0, 0x20f0, 1},
-		{0x302a, 0x302d, 1},
-		{0x3099, 0x309a, 1},
-		{0xfe00, 0xfe0f, 1},
-		{0xfe20, 0xfe26, 1},
-	},
-	R32: []Range32{
-		{0x101fd, 0x101fd, 1},
-		{0x1d167, 0x1d169, 1},
-		{0x1d17b, 0x1d182, 1},
-		{0x1d185, 0x1d18b, 1},
-		{0x1d1aa, 0x1d1ad, 1},
-		{0xe0100, 0xe01ef, 1},
-	},
-}
-
-var _Inscriptional_Pahlavi = &RangeTable{
-	R16: []Range16{},
-	R32: []Range32{
-		{0x10b60, 0x10b72, 1},
-		{0x10b78, 0x10b7f, 1},
-	},
-}
-
-var _Inscriptional_Parthian = &RangeTable{
-	R16: []Range16{},
-	R32: []Range32{
-		{0x10b40, 0x10b55, 1},
-		{0x10b58, 0x10b5f, 1},
-	},
-}
-
-var _Javanese = &RangeTable{
-	R16: []Range16{
-		{0xa980, 0xa9cd, 1},
-		{0xa9d0, 0xa9d9, 1},
-		{0xa9de, 0xa9df, 1},
-	},
-}
-
-var _Kaithi = &RangeTable{
-	R16: []Range16{},
-	R32: []Range32{
-		{0x11080, 0x110c1, 1},
-	},
-}
-
-var _Kannada = &RangeTable{
-	R16: []Range16{
-		{0x0c82, 0x0c83, 1},
-		{0x0c85, 0x0c8c, 1},
-		{0x0c8e, 0x0c90, 1},
-		{0x0c92, 0x0ca8, 1},
-		{0x0caa, 0x0cb3, 1},
-		{0x0cb5, 0x0cb9, 1},
-		{0x0cbc, 0x0cc4, 1},
-		{0x0cc6, 0x0cc8, 1},
-		{0x0cca, 0x0ccd, 1},
-		{0x0cd5, 0x0cd6, 1},
-		{0x0cde, 0x0cde, 1},
-		{0x0ce0, 0x0ce3, 1},
-		{0x0ce6, 0x0cef, 1},
-		{0x0cf1, 0x0cf2, 1},
-	},
-}
-
-var _Katakana = &RangeTable{
-	R16: []Range16{
-		{0x30a1, 0x30fa, 1},
-		{0x30fd, 0x30ff, 1},
-		{0x31f0, 0x31ff, 1},
-		{0x32d0, 0x32fe, 1},
-		{0x3300, 0x3357, 1},
-		{0xff66, 0xff6f, 1},
-		{0xff71, 0xff9d, 1},
-	},
-	R32: []Range32{
-		{0x1b000, 0x1b000, 1},
-	},
-}
-
-var _Kayah_Li = &RangeTable{
-	R16: []Range16{
-		{0xa900, 0xa92f, 1},
-	},
-}
-
-var _Kharoshthi = &RangeTable{
-	R16: []Range16{},
-	R32: []Range32{
-		{0x10a00, 0x10a03, 1},
-		{0x10a05, 0x10a06, 1},
-		{0x10a0c, 0x10a13, 1},
-		{0x10a15, 0x10a17, 1},
-		{0x10a19, 0x10a33, 1},
-		{0x10a38, 0x10a3a, 1},
-		{0x10a3f, 0x10a47, 1},
-		{0x10a50, 0x10a58, 1},
-	},
-}
-
-var _Khmer = &RangeTable{
-	R16: []Range16{
-		{0x1780, 0x17dd, 1},
-		{0x17e0, 0x17e9, 1},
-		{0x17f0, 0x17f9, 1},
-		{0x19e0, 0x19ff, 1},
-	},
-}
-
-var _Lao = &RangeTable{
-	R16: []Range16{
-		{0x0e81, 0x0e82, 1},
-		{0x0e84, 0x0e84, 1},
-		{0x0e87, 0x0e88, 1},
-		{0x0e8a, 0x0e8a, 1},
-		{0x0e8d, 0x0e8d, 1},
-		{0x0e94, 0x0e97, 1},
-		{0x0e99, 0x0e9f, 1},
-		{0x0ea1, 0x0ea3, 1},
-		{0x0ea5, 0x0ea5, 1},
-		{0x0ea7, 0x0ea7, 1},
-		{0x0eaa, 0x0eab, 1},
-		{0x0ead, 0x0eb9, 1},
-		{0x0ebb, 0x0ebd, 1},
-		{0x0ec0, 0x0ec4, 1},
-		{0x0ec6, 0x0ec6, 1},
-		{0x0ec8, 0x0ecd, 1},
-		{0x0ed0, 0x0ed9, 1},
-		{0x0edc, 0x0edf, 1},
-	},
-}
-
-var _Latin = &RangeTable{
-	R16: []Range16{
-		{0x0041, 0x005a, 1},
-		{0x0061, 0x007a, 1},
-		{0x00aa, 0x00aa, 1},
-		{0x00ba, 0x00ba, 1},
-		{0x00c0, 0x00d6, 1},
-		{0x00d8, 0x00f6, 1},
-		{0x00f8, 0x02b8, 1},
-		{0x02e0, 0x02e4, 1},
-		{0x1d00, 0x1d25, 1},
-		{0x1d2c, 0x1d5c, 1},
-		{0x1d62, 0x1d65, 1},
-		{0x1d6b, 0x1d77, 1},
-		{0x1d79, 0x1dbe, 1},
-		{0x1e00, 0x1eff, 1},
-		{0x2071, 0x2071, 1},
-		{0x207f, 0x207f, 1},
-		{0x2090, 0x209c, 1},
-		{0x212a, 0x212b, 1},
-		{0x2132, 0x2132, 1},
-		{0x214e, 0x214e, 1},
-		{0x2160, 0x2188, 1},
-		{0x2c60, 0x2c7f, 1},
-		{0xa722, 0xa787, 1},
-		{0xa78b, 0xa78e, 1},
-		{0xa790, 0xa793, 1},
-		{0xa7a0, 0xa7aa, 1},
-		{0xa7f8, 0xa7ff, 1},
-		{0xfb00, 0xfb06, 1},
-		{0xff21, 0xff3a, 1},
-		{0xff41, 0xff5a, 1},
-	},
-	LatinOffset: 6,
-}
-
-var _Lepcha = &RangeTable{
-	R16: []Range16{
-		{0x1c00, 0x1c37, 1},
-		{0x1c3b, 0x1c49, 1},
-		{0x1c4d, 0x1c4f, 1},
-	},
-}
-
-var _Limbu = &RangeTable{
-	R16: []Range16{
-		{0x1900, 0x191c, 1},
-		{0x1920, 0x192b, 1},
-		{0x1930, 0x193b, 1},
-		{0x1940, 0x1940, 1},
-		{0x1944, 0x194f, 1},
-	},
-}
-
-var _Linear_B = &RangeTable{
-	R16: []Range16{},
-	R32: []Range32{
-		{0x10000, 0x1000b, 1},
-		{0x1000d, 0x10026, 1},
-		{0x10028, 0x1003a, 1},
-		{0x1003c, 0x1003d, 1},
-		{0x1003f, 0x1004d, 1},
-		{0x10050, 0x1005d, 1},
-		{0x10080, 0x100fa, 1},
-	},
-}
-
-var _Lisu = &RangeTable{
-	R16: []Range16{
-		{0xa4d0, 0xa4ff, 1},
-	},
-}
-
-var _Lycian = &RangeTable{
-	R16: []Range16{},
-	R32: []Range32{
-		{0x10280, 0x1029c, 1},
-	},
-}
-
-var _Lydian = &RangeTable{
-	R16: []Range16{},
-	R32: []Range32{
-		{0x10920, 0x10939, 1},
-		{0x1093f, 0x1093f, 1},
-	},
-}
-
-var _Malayalam = &RangeTable{
-	R16: []Range16{
-		{0x0d02, 0x0d03, 1},
-		{0x0d05, 0x0d0c, 1},
-		{0x0d0e, 0x0d10, 1},
-		{0x0d12, 0x0d3a, 1},
-		{0x0d3d, 0x0d44, 1},
-		{0x0d46, 0x0d48, 1},
-		{0x0d4a, 0x0d4e, 1},
-		{0x0d57, 0x0d57, 1},
-		{0x0d60, 0x0d63, 1},
-		{0x0d66, 0x0d75, 1},
-		{0x0d79, 0x0d7f, 1},
-	},
-}
-
-var _Mandaic = &RangeTable{
-	R16: []Range16{
-		{0x0840, 0x085b, 1},
-		{0x085e, 0x085e, 1},
-	},
-}
-
-var _Meetei_Mayek = &RangeTable{
-	R16: []Range16{
-		{0xaae0, 0xaaf6, 1},
-		{0xabc0, 0xabed, 1},
-		{0xabf0, 0xabf9, 1},
-	},
-}
-
-var _Meroitic_Cursive = &RangeTable{
-	R16: []Range16{},
-	R32: []Range32{
-		{0x109a0, 0x109b7, 1},
-		{0x109be, 0x109bf, 1},
-	},
-}
-
-var _Meroitic_Hieroglyphs = &RangeTable{
-	R16: []Range16{},
-	R32: []Range32{
-		{0x10980, 0x1099f, 1},
-	},
-}
-
-var _Miao = &RangeTable{
-	R16: []Range16{},
-	R32: []Range32{
-		{0x16f00, 0x16f44, 1},
-		{0x16f50, 0x16f7e, 1},
-		{0x16f8f, 0x16f9f, 1},
-	},
-}
-
-var _Mongolian = &RangeTable{
-	R16: []Range16{
-		{0x1800, 0x1801, 1},
-		{0x1804, 0x1804, 1},
-		{0x1806, 0x180e, 1},
-		{0x1810, 0x1819, 1},
-		{0x1820, 0x1877, 1},
-		{0x1880, 0x18aa, 1},
-	},
-}
-
-var _Myanmar = &RangeTable{
-	R16: []Range16{
-		{0x1000, 0x109f, 1},
-		{0xaa60, 0xaa7b, 1},
-	},
-}
-
-var _New_Tai_Lue = &RangeTable{
-	R16: []Range16{
-		{0x1980, 0x19ab, 1},
-		{0x19b0, 0x19c9, 1},
-		{0x19d0, 0x19da, 1},
-		{0x19de, 0x19df, 1},
-	},
-}
-
-var _Nko = &RangeTable{
-	R16: []Range16{
-		{0x07c0, 0x07fa, 1},
-	},
-}
-
-var _Ogham = &RangeTable{
-	R16: []Range16{
-		{0x1680, 0x169c, 1},
-	},
-}
-
-var _Ol_Chiki = &RangeTable{
-	R16: []Range16{
-		{0x1c50, 0x1c7f, 1},
-	},
-}
-
-var _Old_Italic = &RangeTable{
-	R16: []Range16{},
-	R32: []Range32{
-		{0x10300, 0x1031e, 1},
-		{0x10320, 0x10323, 1},
-	},
-}
-
-var _Old_Persian = &RangeTable{
-	R16: []Range16{},
-	R32: []Range32{
-		{0x103a0, 0x103c3, 1},
-		{0x103c8, 0x103d5, 1},
-	},
-}
-
-var _Old_South_Arabian = &RangeTable{
-	R16: []Range16{},
-	R32: []Range32{
-		{0x10a60, 0x10a7f, 1},
-	},
-}
-
-var _Old_Turkic = &RangeTable{
-	R16: []Range16{},
-	R32: []Range32{
-		{0x10c00, 0x10c48, 1},
-	},
-}
-
-var _Oriya = &RangeTable{
-	R16: []Range16{
-		{0x0b01, 0x0b03, 1},
-		{0x0b05, 0x0b0c, 1},
-		{0x0b0f, 0x0b10, 1},
-		{0x0b13, 0x0b28, 1},
-		{0x0b2a, 0x0b30, 1},
-		{0x0b32, 0x0b33, 1},
-		{0x0b35, 0x0b39, 1},
-		{0x0b3c, 0x0b44, 1},
-		{0x0b47, 0x0b48, 1},
-		{0x0b4b, 0x0b4d, 1},
-		{0x0b56, 0x0b57, 1},
-		{0x0b5c, 0x0b5d, 1},
-		{0x0b5f, 0x0b63, 1},
-		{0x0b66, 0x0b77, 1},
-	},
-}
-
-var _Osmanya = &RangeTable{
-	R16: []Range16{},
-	R32: []Range32{
-		{0x10480, 0x1049d, 1},
-		{0x104a0, 0x104a9, 1},
-	},
-}
-
-var _Phags_Pa = &RangeTable{
-	R16: []Range16{
-		{0xa840, 0xa877, 1},
-	},
-}
-
-var _Phoenician = &RangeTable{
-	R16: []Range16{},
-	R32: []Range32{
-		{0x10900, 0x1091b, 1},
-		{0x1091f, 0x1091f, 1},
-	},
-}
-
-var _Rejang = &RangeTable{
-	R16: []Range16{
-		{0xa930, 0xa953, 1},
-		{0xa95f, 0xa95f, 1},
-	},
-}
-
-var _Runic = &RangeTable{
-	R16: []Range16{
-		{0x16a0, 0x16ea, 1},
-		{0x16ee, 0x16f0, 1},
-	},
-}
-
-var _Samaritan = &RangeTable{
-	R16: []Range16{
-		{0x0800, 0x082d, 1},
-		{0x0830, 0x083e, 1},
-	},
-}
-
-var _Saurashtra = &RangeTable{
-	R16: []Range16{
-		{0xa880, 0xa8c4, 1},
-		{0xa8ce, 0xa8d9, 1},
-	},
-}
-
-var _Sharada = &RangeTable{
-	R16: []Range16{},
-	R32: []Range32{
-		{0x11180, 0x111c8, 1},
-		{0x111d0, 0x111d9, 1},
-	},
-}
-
-var _Shavian = &RangeTable{
-	R16: []Range16{},
-	R32: []Range32{
-		{0x10450, 0x1047f, 1},
-	},
-}
-
-var _Sinhala = &RangeTable{
-	R16: []Range16{
-		{0x0d82, 0x0d83, 1},
-		{0x0d85, 0x0d96, 1},
-		{0x0d9a, 0x0db1, 1},
-		{0x0db3, 0x0dbb, 1},
-		{0x0dbd, 0x0dbd, 1},
-		{0x0dc0, 0x0dc6, 1},
-		{0x0dca, 0x0dca, 1},
-		{0x0dcf, 0x0dd4, 1},
-		{0x0dd6, 0x0dd6, 1},
-		{0x0dd8, 0x0ddf, 1},
-		{0x0df2, 0x0df4, 1},
-	},
-}
-
-var _Sora_Sompeng = &RangeTable{
-	R16: []Range16{},
-	R32: []Range32{
-		{0x110d0, 0x110e8, 1},
-		{0x110f0, 0x110f9, 1},
-	},
-}
-
-var _Sundanese = &RangeTable{
-	R16: []Range16{
-		{0x1b80, 0x1bbf, 1},
-		{0x1cc0, 0x1cc7, 1},
-	},
-}
-
-var _Syloti_Nagri = &RangeTable{
-	R16: []Range16{
-		{0xa800, 0xa82b, 1},
-	},
-}
-
-var _Syriac = &RangeTable{
-	R16: []Range16{
-		{0x0700, 0x070d, 1},
-		{0x070f, 0x074a, 1},
-		{0x074d, 0x074f, 1},
-	},
-}
-
-var _Tagalog = &RangeTable{
-	R16: []Range16{
-		{0x1700, 0x170c, 1},
-		{0x170e, 0x1714, 1},
-	},
-}
-
-var _Tagbanwa = &RangeTable{
-	R16: []Range16{
-		{0x1760, 0x176c, 1},
-		{0x176e, 0x1770, 1},
-		{0x1772, 0x1773, 1},
-	},
-}
-
-var _Tai_Le = &RangeTable{
-	R16: []Range16{
-		{0x1950, 0x196d, 1},
-		{0x1970, 0x1974, 1},
-	},
-}
-
-var _Tai_Tham = &RangeTable{
-	R16: []Range16{
-		{0x1a20, 0x1a5e, 1},
-		{0x1a60, 0x1a7c, 1},
-		{0x1a7f, 0x1a89, 1},
-		{0x1a90, 0x1a99, 1},
-		{0x1aa0, 0x1aad, 1},
-	},
-}
-
-var _Tai_Viet = &RangeTable{
-	R16: []Range16{
-		{0xaa80, 0xaac2, 1},
-		{0xaadb, 0xaadf, 1},
-	},
-}
-
-var _Takri = &RangeTable{
-	R16: []Range16{},
-	R32: []Range32{
-		{0x11680, 0x116b7, 1},
-		{0x116c0, 0x116c9, 1},
-	},
-}
-
-var _Tamil = &RangeTable{
-	R16: []Range16{
-		{0x0b82, 0x0b83, 1},
-		{0x0b85, 0x0b8a, 1},
-		{0x0b8e, 0x0b90, 1},
-		{0x0b92, 0x0b95, 1},
-		{0x0b99, 0x0b9a, 1},
-		{0x0b9c, 0x0b9c, 1},
-		{0x0b9e, 0x0b9f, 1},
-		{0x0ba3, 0x0ba4, 1},
-		{0x0ba8, 0x0baa, 1},
-		{0x0bae, 0x0bb9, 1},
-		{0x0bbe, 0x0bc2, 1},
-		{0x0bc6, 0x0bc8, 1},
-		{0x0bca, 0x0bcd, 1},
-		{0x0bd0, 0x0bd0, 1},
-		{0x0bd7, 0x0bd7, 1},
-		{0x0be6, 0x0bfa, 1},
-	},
-}
-
-var _Telugu = &RangeTable{
-	R16: []Range16{
-		{0x0c01, 0x0c03, 1},
-		{0x0c05, 0x0c0c, 1},
-		{0x0c0e, 0x0c10, 1},
-		{0x0c12, 0x0c28, 1},
-		{0x0c2a, 0x0c33, 1},
-		{0x0c35, 0x0c39, 1},
-		{0x0c3d, 0x0c44, 1},
-		{0x0c46, 0x0c48, 1},
-		{0x0c4a, 0x0c4d, 1},
-		{0x0c55, 0x0c56, 1},
-		{0x0c58, 0x0c59, 1},
-		{0x0c60, 0x0c63, 1},
-		{0x0c66, 0x0c6f, 1},
-		{0x0c78, 0x0c7f, 1},
-	},
-}
-
-var _Thaana = &RangeTable{
-	R16: []Range16{
-		{0x0780, 0x07b1, 1},
-	},
-}
-
-var _Thai = &RangeTable{
-	R16: []Range16{
-		{0x0e01, 0x0e3a, 1},
-		{0x0e40, 0x0e5b, 1},
-	},
-}
-
-var _Tibetan = &RangeTable{
-	R16: []Range16{
-		{0x0f00, 0x0f47, 1},
-		{0x0f49, 0x0f6c, 1},
-		{0x0f71, 0x0f97, 1},
-		{0x0f99, 0x0fbc, 1},
-		{0x0fbe, 0x0fcc, 1},
-		{0x0fce, 0x0fd4, 1},
-		{0x0fd9, 0x0fda, 1},
-	},
-}
-
-var _Tifinagh = &RangeTable{
-	R16: []Range16{
-		{0x2d30, 0x2d67, 1},
-		{0x2d6f, 0x2d70, 1},
-		{0x2d7f, 0x2d7f, 1},
-	},
-}
-
-var _Ugaritic = &RangeTable{
-	R16: []Range16{},
-	R32: []Range32{
-		{0x10380, 0x1039d, 1},
-		{0x1039f, 0x1039f, 1},
-	},
-}
-
-var _Vai = &RangeTable{
-	R16: []Range16{
-		{0xa500, 0xa62b, 1},
-	},
-}
-
-var _Yi = &RangeTable{
-	R16: []Range16{
-		{0xa000, 0xa48c, 1},
-		{0xa490, 0xa4c6, 1},
-	},
-}
-
-// These variables have type *RangeTable.
-var (
-	Arabic                 = _Arabic                 // Arabic is the set of Unicode characters in script Arabic.
-	Armenian               = _Armenian               // Armenian is the set of Unicode characters in script Armenian.
-	Avestan                = _Avestan                // Avestan is the set of Unicode characters in script Avestan.
-	Balinese               = _Balinese               // Balinese is the set of Unicode characters in script Balinese.
-	Bamum                  = _Bamum                  // Bamum is the set of Unicode characters in script Bamum.
-	Batak                  = _Batak                  // Batak is the set of Unicode characters in script Batak.
-	Bengali                = _Bengali                // Bengali is the set of Unicode characters in script Bengali.
-	Bopomofo               = _Bopomofo               // Bopomofo is the set of Unicode characters in script Bopomofo.
-	Brahmi                 = _Brahmi                 // Brahmi is the set of Unicode characters in script Brahmi.
-	Braille                = _Braille                // Braille is the set of Unicode characters in script Braille.
-	Buginese               = _Buginese               // Buginese is the set of Unicode characters in script Buginese.
-	Buhid                  = _Buhid                  // Buhid is the set of Unicode characters in script Buhid.
-	Canadian_Aboriginal    = _Canadian_Aboriginal    // Canadian_Aboriginal is the set of Unicode characters in script Canadian_Aboriginal.
-	Carian                 = _Carian                 // Carian is the set of Unicode characters in script Carian.
-	Chakma                 = _Chakma                 // Chakma is the set of Unicode characters in script Chakma.
-	Cham                   = _Cham                   // Cham is the set of Unicode characters in script Cham.
-	Cherokee               = _Cherokee               // Cherokee is the set of Unicode characters in script Cherokee.
-	Common                 = _Common                 // Common is the set of Unicode characters in script Common.
-	Coptic                 = _Coptic                 // Coptic is the set of Unicode characters in script Coptic.
-	Cuneiform              = _Cuneiform              // Cuneiform is the set of Unicode characters in script Cuneiform.
-	Cypriot                = _Cypriot                // Cypriot is the set of Unicode characters in script Cypriot.
-	Cyrillic               = _Cyrillic               // Cyrillic is the set of Unicode characters in script Cyrillic.
-	Deseret                = _Deseret                // Deseret is the set of Unicode characters in script Deseret.
-	Devanagari             = _Devanagari             // Devanagari is the set of Unicode characters in script Devanagari.
-	Egyptian_Hieroglyphs   = _Egyptian_Hieroglyphs   // Egyptian_Hieroglyphs is the set of Unicode characters in script Egyptian_Hieroglyphs.
-	Ethiopic               = _Ethiopic               // Ethiopic is the set of Unicode characters in script Ethiopic.
-	Georgian               = _Georgian               // Georgian is the set of Unicode characters in script Georgian.
-	Glagolitic             = _Glagolitic             // Glagolitic is the set of Unicode characters in script Glagolitic.
-	Gothic                 = _Gothic                 // Gothic is the set of Unicode characters in script Gothic.
-	Greek                  = _Greek                  // Greek is the set of Unicode characters in script Greek.
-	Gujarati               = _Gujarati               // Gujarati is the set of Unicode characters in script Gujarati.
-	Gurmukhi               = _Gurmukhi               // Gurmukhi is the set of Unicode characters in script Gurmukhi.
-	Han                    = _Han                    // Han is the set of Unicode characters in script Han.
-	Hangul                 = _Hangul                 // Hangul is the set of Unicode characters in script Hangul.
-	Hanunoo                = _Hanunoo                // Hanunoo is the set of Unicode characters in script Hanunoo.
-	Hebrew                 = _Hebrew                 // Hebrew is the set of Unicode characters in script Hebrew.
-	Hiragana               = _Hiragana               // Hiragana is the set of Unicode characters in script Hiragana.
-	Imperial_Aramaic       = _Imperial_Aramaic       // Imperial_Aramaic is the set of Unicode characters in script Imperial_Aramaic.
-	Inherited              = _Inherited              // Inherited is the set of Unicode characters in script Inherited.
-	Inscriptional_Pahlavi  = _Inscriptional_Pahlavi  // Inscriptional_Pahlavi is the set of Unicode characters in script Inscriptional_Pahlavi.
-	Inscriptional_Parthian = _Inscriptional_Parthian // Inscriptional_Parthian is the set of Unicode characters in script Inscriptional_Parthian.
-	Javanese               = _Javanese               // Javanese is the set of Unicode characters in script Javanese.
-	Kaithi                 = _Kaithi                 // Kaithi is the set of Unicode characters in script Kaithi.
-	Kannada                = _Kannada                // Kannada is the set of Unicode characters in script Kannada.
-	Katakana               = _Katakana               // Katakana is the set of Unicode characters in script Katakana.
-	Kayah_Li               = _Kayah_Li               // Kayah_Li is the set of Unicode characters in script Kayah_Li.
-	Kharoshthi             = _Kharoshthi             // Kharoshthi is the set of Unicode characters in script Kharoshthi.
-	Khmer                  = _Khmer                  // Khmer is the set of Unicode characters in script Khmer.
-	Lao                    = _Lao                    // Lao is the set of Unicode characters in script Lao.
-	Latin                  = _Latin                  // Latin is the set of Unicode characters in script Latin.
-	Lepcha                 = _Lepcha                 // Lepcha is the set of Unicode characters in script Lepcha.
-	Limbu                  = _Limbu                  // Limbu is the set of Unicode characters in script Limbu.
-	Linear_B               = _Linear_B               // Linear_B is the set of Unicode characters in script Linear_B.
-	Lisu                   = _Lisu                   // Lisu is the set of Unicode characters in script Lisu.
-	Lycian                 = _Lycian                 // Lycian is the set of Unicode characters in script Lycian.
-	Lydian                 = _Lydian                 // Lydian is the set of Unicode characters in script Lydian.
-	Malayalam              = _Malayalam              // Malayalam is the set of Unicode characters in script Malayalam.
-	Mandaic                = _Mandaic                // Mandaic is the set of Unicode characters in script Mandaic.
-	Meetei_Mayek           = _Meetei_Mayek           // Meetei_Mayek is the set of Unicode characters in script Meetei_Mayek.
-	Meroitic_Cursive       = _Meroitic_Cursive       // Meroitic_Cursive is the set of Unicode characters in script Meroitic_Cursive.
-	Meroitic_Hieroglyphs   = _Meroitic_Hieroglyphs   // Meroitic_Hieroglyphs is the set of Unicode characters in script Meroitic_Hieroglyphs.
-	Miao                   = _Miao                   // Miao is the set of Unicode characters in script Miao.
-	Mongolian              = _Mongolian              // Mongolian is the set of Unicode characters in script Mongolian.
-	Myanmar                = _Myanmar                // Myanmar is the set of Unicode characters in script Myanmar.
-	New_Tai_Lue            = _New_Tai_Lue            // New_Tai_Lue is the set of Unicode characters in script New_Tai_Lue.
-	Nko                    = _Nko                    // Nko is the set of Unicode characters in script Nko.
-	Ogham                  = _Ogham                  // Ogham is the set of Unicode characters in script Ogham.
-	Ol_Chiki               = _Ol_Chiki               // Ol_Chiki is the set of Unicode characters in script Ol_Chiki.
-	Old_Italic             = _Old_Italic             // Old_Italic is the set of Unicode characters in script Old_Italic.
-	Old_Persian            = _Old_Persian            // Old_Persian is the set of Unicode characters in script Old_Persian.
-	Old_South_Arabian      = _Old_South_Arabian      // Old_South_Arabian is the set of Unicode characters in script Old_South_Arabian.
-	Old_Turkic             = _Old_Turkic             // Old_Turkic is the set of Unicode characters in script Old_Turkic.
-	Oriya                  = _Oriya                  // Oriya is the set of Unicode characters in script Oriya.
-	Osmanya                = _Osmanya                // Osmanya is the set of Unicode characters in script Osmanya.
-	Phags_Pa               = _Phags_Pa               // Phags_Pa is the set of Unicode characters in script Phags_Pa.
-	Phoenician             = _Phoenician             // Phoenician is the set of Unicode characters in script Phoenician.
-	Rejang                 = _Rejang                 // Rejang is the set of Unicode characters in script Rejang.
-	Runic                  = _Runic                  // Runic is the set of Unicode characters in script Runic.
-	Samaritan              = _Samaritan              // Samaritan is the set of Unicode characters in script Samaritan.
-	Saurashtra             = _Saurashtra             // Saurashtra is the set of Unicode characters in script Saurashtra.
-	Sharada                = _Sharada                // Sharada is the set of Unicode characters in script Sharada.
-	Shavian                = _Shavian                // Shavian is the set of Unicode characters in script Shavian.
-	Sinhala                = _Sinhala                // Sinhala is the set of Unicode characters in script Sinhala.
-	Sora_Sompeng           = _Sora_Sompeng           // Sora_Sompeng is the set of Unicode characters in script Sora_Sompeng.
-	Sundanese              = _Sundanese              // Sundanese is the set of Unicode characters in script Sundanese.
-	Syloti_Nagri           = _Syloti_Nagri           // Syloti_Nagri is the set of Unicode characters in script Syloti_Nagri.
-	Syriac                 = _Syriac                 // Syriac is the set of Unicode characters in script Syriac.
-	Tagalog                = _Tagalog                // Tagalog is the set of Unicode characters in script Tagalog.
-	Tagbanwa               = _Tagbanwa               // Tagbanwa is the set of Unicode characters in script Tagbanwa.
-	Tai_Le                 = _Tai_Le                 // Tai_Le is the set of Unicode characters in script Tai_Le.
-	Tai_Tham               = _Tai_Tham               // Tai_Tham is the set of Unicode characters in script Tai_Tham.
-	Tai_Viet               = _Tai_Viet               // Tai_Viet is the set of Unicode characters in script Tai_Viet.
-	Takri                  = _Takri                  // Takri is the set of Unicode characters in script Takri.
-	Tamil                  = _Tamil                  // Tamil is the set of Unicode characters in script Tamil.
-	Telugu                 = _Telugu                 // Telugu is the set of Unicode characters in script Telugu.
-	Thaana                 = _Thaana                 // Thaana is the set of Unicode characters in script Thaana.
-	Thai                   = _Thai                   // Thai is the set of Unicode characters in script Thai.
-	Tibetan                = _Tibetan                // Tibetan is the set of Unicode characters in script Tibetan.
-	Tifinagh               = _Tifinagh               // Tifinagh is the set of Unicode characters in script Tifinagh.
-	Ugaritic               = _Ugaritic               // Ugaritic is the set of Unicode characters in script Ugaritic.
-	Vai                    = _Vai                    // Vai is the set of Unicode characters in script Vai.
-	Yi                     = _Yi                     // Yi is the set of Unicode characters in script Yi.
-)
-
-// Generated by running
-//	maketables --props=all --url=http://www.unicode.org/Public/6.3.0/ucd/
-// DO NOT EDIT
-
-// Properties is the set of Unicode property tables.
-var Properties = map[string]*RangeTable{
-	"ASCII_Hex_Digit":                    ASCII_Hex_Digit,
-	"Bidi_Control":                       Bidi_Control,
-	"Dash":                               Dash,
-	"Deprecated":                         Deprecated,
-	"Diacritic":                          Diacritic,
-	"Extender":                           Extender,
-	"Hex_Digit":                          Hex_Digit,
-	"Hyphen":                             Hyphen,
-	"IDS_Binary_Operator":                IDS_Binary_Operator,
-	"IDS_Trinary_Operator":               IDS_Trinary_Operator,
-	"Ideographic":                        Ideographic,
-	"Join_Control":                       Join_Control,
-	"Logical_Order_Exception":            Logical_Order_Exception,
-	"Noncharacter_Code_Point":            Noncharacter_Code_Point,
-	"Other_Alphabetic":                   Other_Alphabetic,
-	"Other_Default_Ignorable_Code_Point": Other_Default_Ignorable_Code_Point,
-	"Other_Grapheme_Extend":              Other_Grapheme_Extend,
-	"Other_ID_Continue":                  Other_ID_Continue,
-	"Other_ID_Start":                     Other_ID_Start,
-	"Other_Lowercase":                    Other_Lowercase,
-	"Other_Math":                         Other_Math,
-	"Other_Uppercase":                    Other_Uppercase,
-	"Pattern_Syntax":                     Pattern_Syntax,
-	"Pattern_White_Space":                Pattern_White_Space,
-	"Quotation_Mark":                     Quotation_Mark,
-	"Radical":                            Radical,
-	"STerm":                              STerm,
-	"Soft_Dotted":                        Soft_Dotted,
-	"Terminal_Punctuation":               Terminal_Punctuation,
-	"Unified_Ideograph":                  Unified_Ideograph,
-	"Variation_Selector":                 Variation_Selector,
-	"White_Space":                        White_Space,
-}
-
-var _ASCII_Hex_Digit = &RangeTable{
-	R16: []Range16{
-		{0x0030, 0x0039, 1},
-		{0x0041, 0x0046, 1},
-		{0x0061, 0x0066, 1},
-	},
-	LatinOffset: 3,
-}
-
-var _Bidi_Control = &RangeTable{
-	R16: []Range16{
-		{0x061c, 0x061c, 1},
-		{0x200e, 0x200f, 1},
-		{0x202a, 0x202e, 1},
-		{0x2066, 0x2069, 1},
-	},
-}
-
-var _Dash = &RangeTable{
-	R16: []Range16{
-		{0x002d, 0x002d, 1},
-		{0x058a, 0x058a, 1},
-		{0x05be, 0x05be, 1},
-		{0x1400, 0x1400, 1},
-		{0x1806, 0x1806, 1},
-		{0x2010, 0x2015, 1},
-		{0x2053, 0x2053, 1},
-		{0x207b, 0x207b, 1},
-		{0x208b, 0x208b, 1},
-		{0x2212, 0x2212, 1},
-		{0x2e17, 0x2e17, 1},
-		{0x2e1a, 0x2e1a, 1},
-		{0x2e3a, 0x2e3b, 1},
-		{0x301c, 0x301c, 1},
-		{0x3030, 0x3030, 1},
-		{0x30a0, 0x30a0, 1},
-		{0xfe31, 0xfe32, 1},
-		{0xfe58, 0xfe58, 1},
-		{0xfe63, 0xfe63, 1},
-		{0xff0d, 0xff0d, 1},
-	},
-	LatinOffset: 1,
-}
-
-var _Deprecated = &RangeTable{
-	R16: []Range16{
-		{0x0149, 0x0149, 1},
-		{0x0673, 0x0673, 1},
-		{0x0f77, 0x0f77, 1},
-		{0x0f79, 0x0f79, 1},
-		{0x17a3, 0x17a4, 1},
-		{0x206a, 0x206f, 1},
-		{0x2329, 0x232a, 1},
-	},
-	R32: []Range32{
-		{0xe0001, 0xe0001, 1},
-		{0xe0020, 0xe007f, 1},
-	},
-}
-
-var _Diacritic = &RangeTable{
-	R16: []Range16{
-		{0x005e, 0x005e, 1},
-		{0x0060, 0x0060, 1},
-		{0x00a8, 0x00a8, 1},
-		{0x00af, 0x00af, 1},
-		{0x00b4, 0x00b4, 1},
-		{0x00b7, 0x00b8, 1},
-		{0x02b0, 0x034e, 1},
-		{0x0350, 0x0357, 1},
-		{0x035d, 0x0362, 1},
-		{0x0374, 0x0375, 1},
-		{0x037a, 0x037a, 1},
-		{0x0384, 0x0385, 1},
-		{0x0483, 0x0487, 1},
-		{0x0559, 0x0559, 1},
-		{0x0591, 0x05a1, 1},
-		{0x05a3, 0x05bd, 1},
-		{0x05bf, 0x05bf, 1},
-		{0x05c1, 0x05c2, 1},
-		{0x05c4, 0x05c4, 1},
-		{0x064b, 0x0652, 1},
-		{0x0657, 0x0658, 1},
-		{0x06df, 0x06e0, 1},
-		{0x06e5, 0x06e6, 1},
-		{0x06ea, 0x06ec, 1},
-		{0x0730, 0x074a, 1},
-		{0x07a6, 0x07b0, 1},
-		{0x07eb, 0x07f5, 1},
-		{0x0818, 0x0819, 1},
-		{0x08e4, 0x08fe, 1},
-		{0x093c, 0x093c, 1},
-		{0x094d, 0x094d, 1},
-		{0x0951, 0x0954, 1},
-		{0x0971, 0x0971, 1},
-		{0x09bc, 0x09bc, 1},
-		{0x09cd, 0x09cd, 1},
-		{0x0a3c, 0x0a3c, 1},
-		{0x0a4d, 0x0a4d, 1},
-		{0x0abc, 0x0abc, 1},
-		{0x0acd, 0x0acd, 1},
-		{0x0b3c, 0x0b3c, 1},
-		{0x0b4d, 0x0b4d, 1},
-		{0x0bcd, 0x0bcd, 1},
-		{0x0c4d, 0x0c4d, 1},
-		{0x0cbc, 0x0cbc, 1},
-		{0x0ccd, 0x0ccd, 1},
-		{0x0d4d, 0x0d4d, 1},
-		{0x0dca, 0x0dca, 1},
-		{0x0e47, 0x0e4c, 1},
-		{0x0e4e, 0x0e4e, 1},
-		{0x0ec8, 0x0ecc, 1},
-		{0x0f18, 0x0f19, 1},
-		{0x0f35, 0x0f35, 1},
-		{0x0f37, 0x0f37, 1},
-		{0x0f39, 0x0f39, 1},
-		{0x0f3e, 0x0f3f, 1},
-		{0x0f82, 0x0f84, 1},
-		{0x0f86, 0x0f87, 1},
-		{0x0fc6, 0x0fc6, 1},
-		{0x1037, 0x1037, 1},
-		{0x1039, 0x103a, 1},
-		{0x1087, 0x108d, 1},
-		{0x108f, 0x108f, 1},
-		{0x109a, 0x109b, 1},
-		{0x17c9, 0x17d3, 1},
-		{0x17dd, 0x17dd, 1},
-		{0x1939, 0x193b, 1},
-		{0x1a75, 0x1a7c, 1},
-		{0x1a7f, 0x1a7f, 1},
-		{0x1b34, 0x1b34, 1},
-		{0x1b44, 0x1b44, 1},
-		{0x1b6b, 0x1b73, 1},
-		{0x1baa, 0x1bab, 1},
-		{0x1c36, 0x1c37, 1},
-		{0x1c78, 0x1c7d, 1},
-		{0x1cd0, 0x1ce8, 1},
-		{0x1ced, 0x1ced, 1},
-		{0x1cf4, 0x1cf4, 1},
-		{0x1d2c, 0x1d6a, 1},
-		{0x1dc4, 0x1dcf, 1},
-		{0x1dfd, 0x1dff, 1},
-		{0x1fbd, 0x1fbd, 1},
-		{0x1fbf, 0x1fc1, 1},
-		{0x1fcd, 0x1fcf, 1},
-		{0x1fdd, 0x1fdf, 1},
-		{0x1fed, 0x1fef, 1},
-		{0x1ffd, 0x1ffe, 1},
-		{0x2cef, 0x2cf1, 1},
-		{0x2e2f, 0x2e2f, 1},
-		{0x302a, 0x302f, 1},
-		{0x3099, 0x309c, 1},
-		{0x30fc, 0x30fc, 1},
-		{0xa66f, 0xa66f, 1},
-		{0xa67c, 0xa67d, 1},
-		{0xa67f, 0xa67f, 1},
-		{0xa6f0, 0xa6f1, 1},
-		{0xa717, 0xa721, 1},
-		{0xa788, 0xa788, 1},
-		{0xa7f8, 0xa7f9, 1},
-		{0xa8c4, 0xa8c4, 1},
-		{0xa8e0, 0xa8f1, 1},
-		{0xa92b, 0xa92e, 1},
-		{0xa953, 0xa953, 1},
-		{0xa9b3, 0xa9b3, 1},
-		{0xa9c0, 0xa9c0, 1},
-		{0xaa7b, 0xaa7b, 1},
-		{0xaabf, 0xaac2, 1},
-		{0xaaf6, 0xaaf6, 1},
-		{0xabec, 0xabed, 1},
-		{0xfb1e, 0xfb1e, 1},
-		{0xfe20, 0xfe26, 1},
-		{0xff3e, 0xff3e, 1},
-		{0xff40, 0xff40, 1},
-		{0xff70, 0xff70, 1},
-		{0xff9e, 0xff9f, 1},
-		{0xffe3, 0xffe3, 1},
-	},
-	R32: []Range32{
-		{0x110b9, 0x110ba, 1},
-		{0x11133, 0x11134, 1},
-		{0x111c0, 0x111c0, 1},
-		{0x116b6, 0x116b7, 1},
-		{0x16f8f, 0x16f9f, 1},
-		{0x1d167, 0x1d169, 1},
-		{0x1d16d, 0x1d172, 1},
-		{0x1d17b, 0x1d182, 1},
-		{0x1d185, 0x1d18b, 1},
-		{0x1d1aa, 0x1d1ad, 1},
-	},
-	LatinOffset: 6,
-}
-
-var _Extender = &RangeTable{
-	R16: []Range16{
-		{0x00b7, 0x00b7, 1},
-		{0x02d0, 0x02d1, 1},
-		{0x0640, 0x0640, 1},
-		{0x07fa, 0x07fa, 1},
-		{0x0e46, 0x0e46, 1},
-		{0x0ec6, 0x0ec6, 1},
-		{0x180a, 0x180a, 1},
-		{0x1843, 0x1843, 1},
-		{0x1aa7, 0x1aa7, 1},
-		{0x1c36, 0x1c36, 1},
-		{0x1c7b, 0x1c7b, 1},
-		{0x3005, 0x3005, 1},
-		{0x3031, 0x3035, 1},
-		{0x309d, 0x309e, 1},
-		{0x30fc, 0x30fe, 1},
-		{0xa015, 0xa015, 1},
-		{0xa60c, 0xa60c, 1},
-		{0xa9cf, 0xa9cf, 1},
-		{0xaa70, 0xaa70, 1},
-		{0xaadd, 0xaadd, 1},
-		{0xaaf3, 0xaaf4, 1},
-		{0xff70, 0xff70, 1},
-	},
-	LatinOffset: 1,
-}
-
-var _Hex_Digit = &RangeTable{
-	R16: []Range16{
-		{0x0030, 0x0039, 1},
-		{0x0041, 0x0046, 1},
-		{0x0061, 0x0066, 1},
-		{0xff10, 0xff19, 1},
-		{0xff21, 0xff26, 1},
-		{0xff41, 0xff46, 1},
-	},
-	LatinOffset: 3,
-}
-
-var _Hyphen = &RangeTable{
-	R16: []Range16{
-		{0x002d, 0x002d, 1},
-		{0x00ad, 0x00ad, 1},
-		{0x058a, 0x058a, 1},
-		{0x1806, 0x1806, 1},
-		{0x2010, 0x2011, 1},
-		{0x2e17, 0x2e17, 1},
-		{0x30fb, 0x30fb, 1},
-		{0xfe63, 0xfe63, 1},
-		{0xff0d, 0xff0d, 1},
-		{0xff65, 0xff65, 1},
-	},
-	LatinOffset: 2,
-}
-
-var _IDS_Binary_Operator = &RangeTable{
-	R16: []Range16{
-		{0x2ff0, 0x2ff1, 1},
-		{0x2ff4, 0x2ffb, 1},
-	},
-}
-
-var _IDS_Trinary_Operator = &RangeTable{
-	R16: []Range16{
-		{0x2ff2, 0x2ff3, 1},
-	},
-}
-
-var _Ideographic = &RangeTable{
-	R16: []Range16{
-		{0x3006, 0x3007, 1},
-		{0x3021, 0x3029, 1},
-		{0x3038, 0x303a, 1},
-		{0x3400, 0x4db5, 1},
-		{0x4e00, 0x9fcc, 1},
-		{0xf900, 0xfa6d, 1},
-		{0xfa70, 0xfad9, 1},
-	},
-	R32: []Range32{
-		{0x20000, 0x2a6d6, 1},
-		{0x2a700, 0x2b734, 1},
-		{0x2b740, 0x2b81d, 1},
-		{0x2f800, 0x2fa1d, 1},
-	},
-}
-
-var _Join_Control = &RangeTable{
-	R16: []Range16{
-		{0x200c, 0x200d, 1},
-	},
-}
-
-var _Logical_Order_Exception = &RangeTable{
-	R16: []Range16{
-		{0x0e40, 0x0e44, 1},
-		{0x0ec0, 0x0ec4, 1},
-		{0xaab5, 0xaab6, 1},
-		{0xaab9, 0xaab9, 1},
-		{0xaabb, 0xaabc, 1},
-	},
-}
-
-var _Noncharacter_Code_Point = &RangeTable{
-	R16: []Range16{
-		{0xfdd0, 0xfdef, 1},
-		{0xfffe, 0xffff, 1},
-	},
-	R32: []Range32{
-		{0x1fffe, 0x1ffff, 1},
-		{0x2fffe, 0x2ffff, 1},
-		{0x3fffe, 0x3ffff, 1},
-		{0x4fffe, 0x4ffff, 1},
-		{0x5fffe, 0x5ffff, 1},
-		{0x6fffe, 0x6ffff, 1},
-		{0x7fffe, 0x7ffff, 1},
-		{0x8fffe, 0x8ffff, 1},
-		{0x9fffe, 0x9ffff, 1},
-		{0xafffe, 0xaffff, 1},
-		{0xbfffe, 0xbffff, 1},
-		{0xcfffe, 0xcffff, 1},
-		{0xdfffe, 0xdffff, 1},
-		{0xefffe, 0xeffff, 1},
-		{0xffffe, 0xfffff, 1},
-		{0x10fffe, 0x10ffff, 1},
-	},
-}
-
-var _Other_Alphabetic = &RangeTable{
-	R16: []Range16{
-		{0x0345, 0x0345, 1},
-		{0x05b0, 0x05bd, 1},
-		{0x05bf, 0x05bf, 1},
-		{0x05c1, 0x05c2, 1},
-		{0x05c4, 0x05c5, 1},
-		{0x05c7, 0x05c7, 1},
-		{0x0610, 0x061a, 1},
-		{0x064b, 0x0657, 1},
-		{0x0659, 0x065f, 1},
-		{0x0670, 0x0670, 1},
-		{0x06d6, 0x06dc, 1},
-		{0x06e1, 0x06e4, 1},
-		{0x06e7, 0x06e8, 1},
-		{0x06ed, 0x06ed, 1},
-		{0x0711, 0x0711, 1},
-		{0x0730, 0x073f, 1},
-		{0x07a6, 0x07b0, 1},
-		{0x0816, 0x0817, 1},
-		{0x081b, 0x0823, 1},
-		{0x0825, 0x0827, 1},
-		{0x0829, 0x082c, 1},
-		{0x08e4, 0x08e9, 1},
-		{0x08f0, 0x08fe, 1},
-		{0x0900, 0x0903, 1},
-		{0x093a, 0x093b, 1},
-		{0x093e, 0x094c, 1},
-		{0x094e, 0x094f, 1},
-		{0x0955, 0x0957, 1},
-		{0x0962, 0x0963, 1},
-		{0x0981, 0x0983, 1},
-		{0x09be, 0x09c4, 1},
-		{0x09c7, 0x09c8, 1},
-		{0x09cb, 0x09cc, 1},
-		{0x09d7, 0x09d7, 1},
-		{0x09e2, 0x09e3, 1},
-		{0x0a01, 0x0a03, 1},
-		{0x0a3e, 0x0a42, 1},
-		{0x0a47, 0x0a48, 1},
-		{0x0a4b, 0x0a4c, 1},
-		{0x0a51, 0x0a51, 1},
-		{0x0a70, 0x0a71, 1},
-		{0x0a75, 0x0a75, 1},
-		{0x0a81, 0x0a83, 1},
-		{0x0abe, 0x0ac5, 1},
-		{0x0ac7, 0x0ac9, 1},
-		{0x0acb, 0x0acc, 1},
-		{0x0ae2, 0x0ae3, 1},
-		{0x0b01, 0x0b03, 1},
-		{0x0b3e, 0x0b44, 1},
-		{0x0b47, 0x0b48, 1},
-		{0x0b4b, 0x0b4c, 1},
-		{0x0b56, 0x0b57, 1},
-		{0x0b62, 0x0b63, 1},
-		{0x0b82, 0x0b82, 1},
-		{0x0bbe, 0x0bc2, 1},
-		{0x0bc6, 0x0bc8, 1},
-		{0x0bca, 0x0bcc, 1},
-		{0x0bd7, 0x0bd7, 1},
-		{0x0c01, 0x0c03, 1},
-		{0x0c3e, 0x0c44, 1},
-		{0x0c46, 0x0c48, 1},
-		{0x0c4a, 0x0c4c, 1},
-		{0x0c55, 0x0c56, 1},
-		{0x0c62, 0x0c63, 1},
-		{0x0c82, 0x0c83, 1},
-		{0x0cbe, 0x0cc4, 1},
-		{0x0cc6, 0x0cc8, 1},
-		{0x0cca, 0x0ccc, 1},
-		{0x0cd5, 0x0cd6, 1},
-		{0x0ce2, 0x0ce3, 1},
-		{0x0d02, 0x0d03, 1},
-		{0x0d3e, 0x0d44, 1},
-		{0x0d46, 0x0d48, 1},
-		{0x0d4a, 0x0d4c, 1},
-		{0x0d57, 0x0d57, 1},
-		{0x0d62, 0x0d63, 1},
-		{0x0d82, 0x0d83, 1},
-		{0x0dcf, 0x0dd4, 1},
-		{0x0dd6, 0x0dd6, 1},
-		{0x0dd8, 0x0ddf, 1},
-		{0x0df2, 0x0df3, 1},
-		{0x0e31, 0x0e31, 1},
-		{0x0e34, 0x0e3a, 1},
-		{0x0e4d, 0x0e4d, 1},
-		{0x0eb1, 0x0eb1, 1},
-		{0x0eb4, 0x0eb9, 1},
-		{0x0ebb, 0x0ebc, 1},
-		{0x0ecd, 0x0ecd, 1},
-		{0x0f71, 0x0f81, 1},
-		{0x0f8d, 0x0f97, 1},
-		{0x0f99, 0x0fbc, 1},
-		{0x102b, 0x1036, 1},
-		{0x1038, 0x1038, 1},
-		{0x103b, 0x103e, 1},
-		{0x1056, 0x1059, 1},
-		{0x105e, 0x1060, 1},
-		{0x1062, 0x1062, 1},
-		{0x1067, 0x1068, 1},
-		{0x1071, 0x1074, 1},
-		{0x1082, 0x1086, 1},
-		{0x109c, 0x109d, 1},
-		{0x135f, 0x135f, 1},
-		{0x1712, 0x1713, 1},
-		{0x1732, 0x1733, 1},
-		{0x1752, 0x1753, 1},
-		{0x1772, 0x1773, 1},
-		{0x17b6, 0x17c8, 1},
-		{0x18a9, 0x18a9, 1},
-		{0x1920, 0x192b, 1},
-		{0x1930, 0x1938, 1},
-		{0x19b0, 0x19c0, 1},
-		{0x19c8, 0x19c9, 1},
-		{0x1a17, 0x1a1b, 1},
-		{0x1a55, 0x1a5e, 1},
-		{0x1a61, 0x1a74, 1},
-		{0x1b00, 0x1b04, 1},
-		{0x1b35, 0x1b43, 1},
-		{0x1b80, 0x1b82, 1},
-		{0x1ba1, 0x1ba9, 1},
-		{0x1bac, 0x1bad, 1},
-		{0x1be7, 0x1bf1, 1},
-		{0x1c24, 0x1c35, 1},
-		{0x1cf2, 0x1cf3, 1},
-		{0x24b6, 0x24e9, 1},
-		{0x2de0, 0x2dff, 1},
-		{0xa674, 0xa67b, 1},
-		{0xa69f, 0xa69f, 1},
-		{0xa823, 0xa827, 1},
-		{0xa880, 0xa881, 1},
-		{0xa8b4, 0xa8c3, 1},
-		{0xa926, 0xa92a, 1},
-		{0xa947, 0xa952, 1},
-		{0xa980, 0xa983, 1},
-		{0xa9b4, 0xa9bf, 1},
-		{0xaa29, 0xaa36, 1},
-		{0xaa43, 0xaa43, 1},
-		{0xaa4c, 0xaa4d, 1},
-		{0xaab0, 0xaab0, 1},
-		{0xaab2, 0xaab4, 1},
-		{0xaab7, 0xaab8, 1},
-		{0xaabe, 0xaabe, 1},
-		{0xaaeb, 0xaaef, 1},
-		{0xaaf5, 0xaaf5, 1},
-		{0xabe3, 0xabea, 1},
-		{0xfb1e, 0xfb1e, 1},
-	},
-	R32: []Range32{
-		{0x10a01, 0x10a03, 1},
-		{0x10a05, 0x10a06, 1},
-		{0x10a0c, 0x10a0f, 1},
-		{0x11000, 0x11002, 1},
-		{0x11038, 0x11045, 1},
-		{0x11082, 0x11082, 1},
-		{0x110b0, 0x110b8, 1},
-		{0x11100, 0x11102, 1},
-		{0x11127, 0x11132, 1},
-		{0x11180, 0x11182, 1},
-		{0x111b3, 0x111bf, 1},
-		{0x116ab, 0x116b5, 1},
-		{0x16f51, 0x16f7e, 1},
-	},
-}
-
-var _Other_Default_Ignorable_Code_Point = &RangeTable{
-	R16: []Range16{
-		{0x034f, 0x034f, 1},
-		{0x115f, 0x1160, 1},
-		{0x17b4, 0x17b5, 1},
-		{0x2065, 0x2065, 1},
-		{0x3164, 0x3164, 1},
-		{0xffa0, 0xffa0, 1},
-		{0xfff0, 0xfff8, 1},
-	},
-	R32: []Range32{
-		{0xe0000, 0xe0000, 1},
-		{0xe0002, 0xe001f, 1},
-		{0xe0080, 0xe00ff, 1},
-		{0xe01f0, 0xe0fff, 1},
-	},
-}
-
-var _Other_Grapheme_Extend = &RangeTable{
-	R16: []Range16{
-		{0x09be, 0x09be, 1},
-		{0x09d7, 0x09d7, 1},
-		{0x0b3e, 0x0b3e, 1},
-		{0x0b57, 0x0b57, 1},
-		{0x0bbe, 0x0bbe, 1},
-		{0x0bd7, 0x0bd7, 1},
-		{0x0cc2, 0x0cc2, 1},
-		{0x0cd5, 0x0cd6, 1},
-		{0x0d3e, 0x0d3e, 1},
-		{0x0d57, 0x0d57, 1},
-		{0x0dcf, 0x0dcf, 1},
-		{0x0ddf, 0x0ddf, 1},
-		{0x200c, 0x200d, 1},
-		{0x302e, 0x302f, 1},
-		{0xff9e, 0xff9f, 1},
-	},
-	R32: []Range32{
-		{0x1d165, 0x1d165, 1},
-		{0x1d16e, 0x1d172, 1},
-	},
-}
-
-var _Other_ID_Continue = &RangeTable{
-	R16: []Range16{
-		{0x00b7, 0x00b7, 1},
-		{0x0387, 0x0387, 1},
-		{0x1369, 0x1371, 1},
-		{0x19da, 0x19da, 1},
-	},
-	LatinOffset: 1,
-}
-
-var _Other_ID_Start = &RangeTable{
-	R16: []Range16{
-		{0x2118, 0x2118, 1},
-		{0x212e, 0x212e, 1},
-		{0x309b, 0x309c, 1},
-	},
-}
-
-var _Other_Lowercase = &RangeTable{
-	R16: []Range16{
-		{0x00aa, 0x00aa, 1},
-		{0x00ba, 0x00ba, 1},
-		{0x02b0, 0x02b8, 1},
-		{0x02c0, 0x02c1, 1},
-		{0x02e0, 0x02e4, 1},
-		{0x0345, 0x0345, 1},
-		{0x037a, 0x037a, 1},
-		{0x1d2c, 0x1d6a, 1},
-		{0x1d78, 0x1d78, 1},
-		{0x1d9b, 0x1dbf, 1},
-		{0x2071, 0x2071, 1},
-		{0x207f, 0x207f, 1},
-		{0x2090, 0x209c, 1},
-		{0x2170, 0x217f, 1},
-		{0x24d0, 0x24e9, 1},
-		{0x2c7c, 0x2c7d, 1},
-		{0xa770, 0xa770, 1},
-		{0xa7f8, 0xa7f9, 1},
-	},
-	LatinOffset: 2,
-}
-
-var _Other_Math = &RangeTable{
-	R16: []Range16{
-		{0x005e, 0x005e, 1},
-		{0x03d0, 0x03d2, 1},
-		{0x03d5, 0x03d5, 1},
-		{0x03f0, 0x03f1, 1},
-		{0x03f4, 0x03f5, 1},
-		{0x2016, 0x2016, 1},
-		{0x2032, 0x2034, 1},
-		{0x2040, 0x2040, 1},
-		{0x2061, 0x2064, 1},
-		{0x207d, 0x207e, 1},
-		{0x208d, 0x208e, 1},
-		{0x20d0, 0x20dc, 1},
-		{0x20e1, 0x20e1, 1},
-		{0x20e5, 0x20e6, 1},
-		{0x20eb, 0x20ef, 1},
-		{0x2102, 0x2102, 1},
-		{0x2107, 0x2107, 1},
-		{0x210a, 0x2113, 1},
-		{0x2115, 0x2115, 1},
-		{0x2119, 0x211d, 1},
-		{0x2124, 0x2124, 1},
-		{0x2128, 0x2129, 1},
-		{0x212c, 0x212d, 1},
-		{0x212f, 0x2131, 1},
-		{0x2133, 0x2138, 1},
-		{0x213c, 0x213f, 1},
-		{0x2145, 0x2149, 1},
-		{0x2195, 0x2199, 1},
-		{0x219c, 0x219f, 1},
-		{0x21a1, 0x21a2, 1},
-		{0x21a4, 0x21a5, 1},
-		{0x21a7, 0x21a7, 1},
-		{0x21a9, 0x21ad, 1},
-		{0x21b0, 0x21b1, 1},
-		{0x21b6, 0x21b7, 1},
-		{0x21bc, 0x21cd, 1},
-		{0x21d0, 0x21d1, 1},
-		{0x21d3, 0x21d3, 1},
-		{0x21d5, 0x21db, 1},
-		{0x21dd, 0x21dd, 1},
-		{0x21e4, 0x21e5, 1},
-		{0x2308, 0x230b, 1},
-		{0x23b4, 0x23b5, 1},
-		{0x23b7, 0x23b7, 1},
-		{0x23d0, 0x23d0, 1},
-		{0x23e2, 0x23e2, 1},
-		{0x25a0, 0x25a1, 1},
-		{0x25ae, 0x25b6, 1},
-		{0x25bc, 0x25c0, 1},
-		{0x25c6, 0x25c7, 1},
-		{0x25ca, 0x25cb, 1},
-		{0x25cf, 0x25d3, 1},
-		{0x25e2, 0x25e2, 1},
-		{0x25e4, 0x25e4, 1},
-		{0x25e7, 0x25ec, 1},
-		{0x2605, 0x2606, 1},
-		{0x2640, 0x2640, 1},
-		{0x2642, 0x2642, 1},
-		{0x2660, 0x2663, 1},
-		{0x266d, 0x266e, 1},
-		{0x27c5, 0x27c6, 1},
-		{0x27e6, 0x27ef, 1},
-		{0x2983, 0x2998, 1},
-		{0x29d8, 0x29db, 1},
-		{0x29fc, 0x29fd, 1},
-		{0xfe61, 0xfe61, 1},
-		{0xfe63, 0xfe63, 1},
-		{0xfe68, 0xfe68, 1},
-		{0xff3c, 0xff3c, 1},
-		{0xff3e, 0xff3e, 1},
-	},
-	R32: []Range32{
-		{0x1d400, 0x1d454, 1},
-		{0x1d456, 0x1d49c, 1},
-		{0x1d49e, 0x1d49f, 1},
-		{0x1d4a2, 0x1d4a2, 1},
-		{0x1d4a5, 0x1d4a6, 1},
-		{0x1d4a9, 0x1d4ac, 1},
-		{0x1d4ae, 0x1d4b9, 1},
-		{0x1d4bb, 0x1d4bb, 1},
-		{0x1d4bd, 0x1d4c3, 1},
-		{0x1d4c5, 0x1d505, 1},
-		{0x1d507, 0x1d50a, 1},
-		{0x1d50d, 0x1d514, 1},
-		{0x1d516, 0x1d51c, 1},
-		{0x1d51e, 0x1d539, 1},
-		{0x1d53b, 0x1d53e, 1},
-		{0x1d540, 0x1d544, 1},
-		{0x1d546, 0x1d546, 1},
-		{0x1d54a, 0x1d550, 1},
-		{0x1d552, 0x1d6a5, 1},
-		{0x1d6a8, 0x1d6c0, 1},
-		{0x1d6c2, 0x1d6da, 1},
-		{0x1d6dc, 0x1d6fa, 1},
-		{0x1d6fc, 0x1d714, 1},
-		{0x1d716, 0x1d734, 1},
-		{0x1d736, 0x1d74e, 1},
-		{0x1d750, 0x1d76e, 1},
-		{0x1d770, 0x1d788, 1},
-		{0x1d78a, 0x1d7a8, 1},
-		{0x1d7aa, 0x1d7c2, 1},
-		{0x1d7c4, 0x1d7cb, 1},
-		{0x1d7ce, 0x1d7ff, 1},
-		{0x1ee00, 0x1ee03, 1},
-		{0x1ee05, 0x1ee1f, 1},
-		{0x1ee21, 0x1ee22, 1},
-		{0x1ee24, 0x1ee24, 1},
-		{0x1ee27, 0x1ee27, 1},
-		{0x1ee29, 0x1ee32, 1},
-		{0x1ee34, 0x1ee37, 1},
-		{0x1ee39, 0x1ee39, 1},
-		{0x1ee3b, 0x1ee3b, 1},
-		{0x1ee42, 0x1ee42, 1},
-		{0x1ee47, 0x1ee47, 1},
-		{0x1ee49, 0x1ee49, 1},
-		{0x1ee4b, 0x1ee4b, 1},
-		{0x1ee4d, 0x1ee4f, 1},
-		{0x1ee51, 0x1ee52, 1},
-		{0x1ee54, 0x1ee54, 1},
-		{0x1ee57, 0x1ee57, 1},
-		{0x1ee59, 0x1ee59, 1},
-		{0x1ee5b, 0x1ee5b, 1},
-		{0x1ee5d, 0x1ee5d, 1},
-		{0x1ee5f, 0x1ee5f, 1},
-		{0x1ee61, 0x1ee62, 1},
-		{0x1ee64, 0x1ee64, 1},
-		{0x1ee67, 0x1ee6a, 1},
-		{0x1ee6c, 0x1ee72, 1},
-		{0x1ee74, 0x1ee77, 1},
-		{0x1ee79, 0x1ee7c, 1},
-		{0x1ee7e, 0x1ee7e, 1},
-		{0x1ee80, 0x1ee89, 1},
-		{0x1ee8b, 0x1ee9b, 1},
-		{0x1eea1, 0x1eea3, 1},
-		{0x1eea5, 0x1eea9, 1},
-		{0x1eeab, 0x1eebb, 1},
-	},
-	LatinOffset: 1,
-}
-
-var _Other_Uppercase = &RangeTable{
-	R16: []Range16{
-		{0x2160, 0x216f, 1},
-		{0x24b6, 0x24cf, 1},
-	},
-}
-
-var _Pattern_Syntax = &RangeTable{
-	R16: []Range16{
-		{0x0021, 0x002f, 1},
-		{0x003a, 0x0040, 1},
-		{0x005b, 0x005e, 1},
-		{0x0060, 0x0060, 1},
-		{0x007b, 0x007e, 1},
-		{0x00a1, 0x00a7, 1},
-		{0x00a9, 0x00a9, 1},
-		{0x00ab, 0x00ac, 1},
-		{0x00ae, 0x00ae, 1},
-		{0x00b0, 0x00b1, 1},
-		{0x00b6, 0x00b6, 1},
-		{0x00bb, 0x00bb, 1},
-		{0x00bf, 0x00bf, 1},
-		{0x00d7, 0x00d7, 1},
-		{0x00f7, 0x00f7, 1},
-		{0x2010, 0x2027, 1},
-		{0x2030, 0x203e, 1},
-		{0x2041, 0x2053, 1},
-		{0x2055, 0x205e, 1},
-		{0x2190, 0x245f, 1},
-		{0x2500, 0x2775, 1},
-		{0x2794, 0x2bff, 1},
-		{0x2e00, 0x2e7f, 1},
-		{0x3001, 0x3003, 1},
-		{0x3008, 0x3020, 1},
-		{0x3030, 0x3030, 1},
-		{0xfd3e, 0xfd3f, 1},
-		{0xfe45, 0xfe46, 1},
-	},
-	LatinOffset: 15,
-}
-
-var _Pattern_White_Space = &RangeTable{
-	R16: []Range16{
-		{0x0009, 0x000d, 1},
-		{0x0020, 0x0020, 1},
-		{0x0085, 0x0085, 1},
-		{0x200e, 0x200f, 1},
-		{0x2028, 0x2029, 1},
-	},
-	LatinOffset: 3,
-}
-
-var _Quotation_Mark = &RangeTable{
-	R16: []Range16{
-		{0x0022, 0x0022, 1},
-		{0x0027, 0x0027, 1},
-		{0x00ab, 0x00ab, 1},
-		{0x00bb, 0x00bb, 1},
-		{0x2018, 0x201f, 1},
-		{0x2039, 0x203a, 1},
-		{0x300c, 0x300f, 1},
-		{0x301d, 0x301f, 1},
-		{0xfe41, 0xfe44, 1},
-		{0xff02, 0xff02, 1},
-		{0xff07, 0xff07, 1},
-		{0xff62, 0xff63, 1},
-	},
-	LatinOffset: 4,
-}
-
-var _Radical = &RangeTable{
-	R16: []Range16{
-		{0x2e80, 0x2e99, 1},
-		{0x2e9b, 0x2ef3, 1},
-		{0x2f00, 0x2fd5, 1},
-	},
-}
-
-var _STerm = &RangeTable{
-	R16: []Range16{
-		{0x0021, 0x0021, 1},
-		{0x002e, 0x002e, 1},
-		{0x003f, 0x003f, 1},
-		{0x055c, 0x055c, 1},
-		{0x055e, 0x055e, 1},
-		{0x0589, 0x0589, 1},
-		{0x061f, 0x061f, 1},
-		{0x06d4, 0x06d4, 1},
-		{0x0700, 0x0702, 1},
-		{0x07f9, 0x07f9, 1},
-		{0x0964, 0x0965, 1},
-		{0x104a, 0x104b, 1},
-		{0x1362, 0x1362, 1},
-		{0x1367, 0x1368, 1},
-		{0x166e, 0x166e, 1},
-		{0x1735, 0x1736, 1},
-		{0x1803, 0x1803, 1},
-		{0x1809, 0x1809, 1},
-		{0x1944, 0x1945, 1},
-		{0x1aa8, 0x1aab, 1},
-		{0x1b5a, 0x1b5b, 1},
-		{0x1b5e, 0x1b5f, 1},
-		{0x1c3b, 0x1c3c, 1},
-		{0x1c7e, 0x1c7f, 1},
-		{0x203c, 0x203d, 1},
-		{0x2047, 0x2049, 1},
-		{0x2e2e, 0x2e2e, 1},
-		{0x3002, 0x3002, 1},
-		{0xa4ff, 0xa4ff, 1},
-		{0xa60e, 0xa60f, 1},
-		{0xa6f3, 0xa6f3, 1},
-		{0xa6f7, 0xa6f7, 1},
-		{0xa876, 0xa877, 1},
-		{0xa8ce, 0xa8cf, 1},
-		{0xa92f, 0xa92f, 1},
-		{0xa9c8, 0xa9c9, 1},
-		{0xaa5d, 0xaa5f, 1},
-		{0xaaf0, 0xaaf1, 1},
-		{0xabeb, 0xabeb, 1},
-		{0xfe52, 0xfe52, 1},
-		{0xfe56, 0xfe57, 1},
-		{0xff01, 0xff01, 1},
-		{0xff0e, 0xff0e, 1},
-		{0xff1f, 0xff1f, 1},
-		{0xff61, 0xff61, 1},
-	},
-	R32: []Range32{
-		{0x10a56, 0x10a57, 1},
-		{0x11047, 0x11048, 1},
-		{0x110be, 0x110c1, 1},
-		{0x11141, 0x11143, 1},
-		{0x111c5, 0x111c6, 1},
-	},
-	LatinOffset: 3,
-}
-
-var _Soft_Dotted = &RangeTable{
-	R16: []Range16{
-		{0x0069, 0x006a, 1},
-		{0x012f, 0x012f, 1},
-		{0x0249, 0x0249, 1},
-		{0x0268, 0x0268, 1},
-		{0x029d, 0x029d, 1},
-		{0x02b2, 0x02b2, 1},
-		{0x03f3, 0x03f3, 1},
-		{0x0456, 0x0456, 1},
-		{0x0458, 0x0458, 1},
-		{0x1d62, 0x1d62, 1},
-		{0x1d96, 0x1d96, 1},
-		{0x1da4, 0x1da4, 1},
-		{0x1da8, 0x1da8, 1},
-		{0x1e2d, 0x1e2d, 1},
-		{0x1ecb, 0x1ecb, 1},
-		{0x2071, 0x2071, 1},
-		{0x2148, 0x2149, 1},
-		{0x2c7c, 0x2c7c, 1},
-	},
-	R32: []Range32{
-		{0x1d422, 0x1d423, 1},
-		{0x1d456, 0x1d457, 1},
-		{0x1d48a, 0x1d48b, 1},
-		{0x1d4be, 0x1d4bf, 1},
-		{0x1d4f2, 0x1d4f3, 1},
-		{0x1d526, 0x1d527, 1},
-		{0x1d55a, 0x1d55b, 1},
-		{0x1d58e, 0x1d58f, 1},
-		{0x1d5c2, 0x1d5c3, 1},
-		{0x1d5f6, 0x1d5f7, 1},
-		{0x1d62a, 0x1d62b, 1},
-		{0x1d65e, 0x1d65f, 1},
-		{0x1d692, 0x1d693, 1},
-	},
-	LatinOffset: 1,
-}
-
-var _Terminal_Punctuation = &RangeTable{
-	R16: []Range16{
-		{0x0021, 0x0021, 1},
-		{0x002c, 0x002c, 1},
-		{0x002e, 0x002e, 1},
-		{0x003a, 0x003b, 1},
-		{0x003f, 0x003f, 1},
-		{0x037e, 0x037e, 1},
-		{0x0387, 0x0387, 1},
-		{0x0589, 0x0589, 1},
-		{0x05c3, 0x05c3, 1},
-		{0x060c, 0x060c, 1},
-		{0x061b, 0x061b, 1},
-		{0x061f, 0x061f, 1},
-		{0x06d4, 0x06d4, 1},
-		{0x0700, 0x070a, 1},
-		{0x070c, 0x070c, 1},
-		{0x07f8, 0x07f9, 1},
-		{0x0830, 0x083e, 1},
-		{0x085e, 0x085e, 1},
-		{0x0964, 0x0965, 1},
-		{0x0e5a, 0x0e5b, 1},
-		{0x0f08, 0x0f08, 1},
-		{0x0f0d, 0x0f12, 1},
-		{0x104a, 0x104b, 1},
-		{0x1361, 0x1368, 1},
-		{0x166d, 0x166e, 1},
-		{0x16eb, 0x16ed, 1},
-		{0x17d4, 0x17d6, 1},
-		{0x17da, 0x17da, 1},
-		{0x1802, 0x1805, 1},
-		{0x1808, 0x1809, 1},
-		{0x1944, 0x1945, 1},
-		{0x1aa8, 0x1aab, 1},
-		{0x1b5a, 0x1b5b, 1},
-		{0x1b5d, 0x1b5f, 1},
-		{0x1c3b, 0x1c3f, 1},
-		{0x1c7e, 0x1c7f, 1},
-		{0x203c, 0x203d, 1},
-		{0x2047, 0x2049, 1},
-		{0x2e2e, 0x2e2e, 1},
-		{0x3001, 0x3002, 1},
-		{0xa4fe, 0xa4ff, 1},
-		{0xa60d, 0xa60f, 1},
-		{0xa6f3, 0xa6f7, 1},
-		{0xa876, 0xa877, 1},
-		{0xa8ce, 0xa8cf, 1},
-		{0xa92f, 0xa92f, 1},
-		{0xa9c7, 0xa9c9, 1},
-		{0xaa5d, 0xaa5f, 1},
-		{0xaadf, 0xaadf, 1},
-		{0xaaf0, 0xaaf1, 1},
-		{0xabeb, 0xabeb, 1},
-		{0xfe50, 0xfe52, 1},
-		{0xfe54, 0xfe57, 1},
-		{0xff01, 0xff01, 1},
-		{0xff0c, 0xff0c, 1},
-		{0xff0e, 0xff0e, 1},
-		{0xff1a, 0xff1b, 1},
-		{0xff1f, 0xff1f, 1},
-		{0xff61, 0xff61, 1},
-		{0xff64, 0xff64, 1},
-	},
-	R32: []Range32{
-		{0x1039f, 0x1039f, 1},
-		{0x103d0, 0x103d0, 1},
-		{0x10857, 0x10857, 1},
-		{0x1091f, 0x1091f, 1},
-		{0x10b3a, 0x10b3f, 1},
-		{0x11047, 0x1104d, 1},
-		{0x110be, 0x110c1, 1},
-		{0x11141, 0x11143, 1},
-		{0x111c5, 0x111c6, 1},
-		{0x12470, 0x12473, 1},
-	},
-	LatinOffset: 5,
-}
-
-var _Unified_Ideograph = &RangeTable{
-	R16: []Range16{
-		{0x3400, 0x4db5, 1},
-		{0x4e00, 0x9fcc, 1},
-		{0xfa0e, 0xfa0f, 1},
-		{0xfa11, 0xfa11, 1},
-		{0xfa13, 0xfa14, 1},
-		{0xfa1f, 0xfa1f, 1},
-		{0xfa21, 0xfa21, 1},
-		{0xfa23, 0xfa24, 1},
-		{0xfa27, 0xfa29, 1},
-	},
-	R32: []Range32{
-		{0x20000, 0x2a6d6, 1},
-		{0x2a700, 0x2b734, 1},
-		{0x2b740, 0x2b81d, 1},
-	},
-}
-
-var _Variation_Selector = &RangeTable{
-	R16: []Range16{
-		{0x180b, 0x180d, 1},
-		{0xfe00, 0xfe0f, 1},
-	},
-	R32: []Range32{
-		{0xe0100, 0xe01ef, 1},
-	},
-}
-
-var _White_Space = &RangeTable{
-	R16: []Range16{
-		{0x0009, 0x000d, 1},
-		{0x0020, 0x0020, 1},
-		{0x0085, 0x0085, 1},
-		{0x00a0, 0x00a0, 1},
-		{0x1680, 0x1680, 1},
-		{0x2000, 0x200a, 1},
-		{0x2028, 0x2029, 1},
-		{0x202f, 0x202f, 1},
-		{0x205f, 0x205f, 1},
-		{0x3000, 0x3000, 1},
-	},
-	LatinOffset: 4,
-}
-
-// These variables have type *RangeTable.
-var (
-	ASCII_Hex_Digit                    = _ASCII_Hex_Digit                    // ASCII_Hex_Digit is the set of Unicode characters with property ASCII_Hex_Digit.
-	Bidi_Control                       = _Bidi_Control                       // Bidi_Control is the set of Unicode characters with property Bidi_Control.
-	Dash                               = _Dash                               // Dash is the set of Unicode characters with property Dash.
-	Deprecated                         = _Deprecated                         // Deprecated is the set of Unicode characters with property Deprecated.
-	Diacritic                          = _Diacritic                          // Diacritic is the set of Unicode characters with property Diacritic.
-	Extender                           = _Extender                           // Extender is the set of Unicode characters with property Extender.
-	Hex_Digit                          = _Hex_Digit                          // Hex_Digit is the set of Unicode characters with property Hex_Digit.
-	Hyphen                             = _Hyphen                             // Hyphen is the set of Unicode characters with property Hyphen.
-	IDS_Binary_Operator                = _IDS_Binary_Operator                // IDS_Binary_Operator is the set of Unicode characters with property IDS_Binary_Operator.
-	IDS_Trinary_Operator               = _IDS_Trinary_Operator               // IDS_Trinary_Operator is the set of Unicode characters with property IDS_Trinary_Operator.
-	Ideographic                        = _Ideographic                        // Ideographic is the set of Unicode characters with property Ideographic.
-	Join_Control                       = _Join_Control                       // Join_Control is the set of Unicode characters with property Join_Control.
-	Logical_Order_Exception            = _Logical_Order_Exception            // Logical_Order_Exception is the set of Unicode characters with property Logical_Order_Exception.
-	Noncharacter_Code_Point            = _Noncharacter_Code_Point            // Noncharacter_Code_Point is the set of Unicode characters with property Noncharacter_Code_Point.
-	Other_Alphabetic                   = _Other_Alphabetic                   // Other_Alphabetic is the set of Unicode characters with property Other_Alphabetic.
-	Other_Default_Ignorable_Code_Point = _Other_Default_Ignorable_Code_Point // Other_Default_Ignorable_Code_Point is the set of Unicode characters with property Other_Default_Ignorable_Code_Point.
-	Other_Grapheme_Extend              = _Other_Grapheme_Extend              // Other_Grapheme_Extend is the set of Unicode characters with property Other_Grapheme_Extend.
-	Other_ID_Continue                  = _Other_ID_Continue                  // Other_ID_Continue is the set of Unicode characters with property Other_ID_Continue.
-	Other_ID_Start                     = _Other_ID_Start                     // Other_ID_Start is the set of Unicode characters with property Other_ID_Start.
-	Other_Lowercase                    = _Other_Lowercase                    // Other_Lowercase is the set of Unicode characters with property Other_Lowercase.
-	Other_Math                         = _Other_Math                         // Other_Math is the set of Unicode characters with property Other_Math.
-	Other_Uppercase                    = _Other_Uppercase                    // Other_Uppercase is the set of Unicode characters with property Other_Uppercase.
-	Pattern_Syntax                     = _Pattern_Syntax                     // Pattern_Syntax is the set of Unicode characters with property Pattern_Syntax.
-	Pattern_White_Space                = _Pattern_White_Space                // Pattern_White_Space is the set of Unicode characters with property Pattern_White_Space.
-	Quotation_Mark                     = _Quotation_Mark                     // Quotation_Mark is the set of Unicode characters with property Quotation_Mark.
-	Radical                            = _Radical                            // Radical is the set of Unicode characters with property Radical.
-	STerm                              = _STerm                              // STerm is the set of Unicode characters with property STerm.
-	Soft_Dotted                        = _Soft_Dotted                        // Soft_Dotted is the set of Unicode characters with property Soft_Dotted.
-	Terminal_Punctuation               = _Terminal_Punctuation               // Terminal_Punctuation is the set of Unicode characters with property Terminal_Punctuation.
-	Unified_Ideograph                  = _Unified_Ideograph                  // Unified_Ideograph is the set of Unicode characters with property Unified_Ideograph.
-	Variation_Selector                 = _Variation_Selector                 // Variation_Selector is the set of Unicode characters with property Variation_Selector.
-	White_Space                        = _White_Space                        // White_Space is the set of Unicode characters with property White_Space.
-)
-
-// Generated by running
-//	maketables --data=http://www.unicode.org/Public/6.3.0/ucd/UnicodeData.txt --casefolding=http://www.unicode.org/Public/6.3.0/ucd/CaseFolding.txt
-// DO NOT EDIT
-
-// CaseRanges is the table describing case mappings for all letters with
-// non-self mappings.
-var CaseRanges = _CaseRanges
-var _CaseRanges = []CaseRange{
-	{0x0041, 0x005A, d{0, 32, 0}},
-	{0x0061, 0x007A, d{-32, 0, -32}},
-	{0x00B5, 0x00B5, d{743, 0, 743}},
-	{0x00C0, 0x00D6, d{0, 32, 0}},
-	{0x00D8, 0x00DE, d{0, 32, 0}},
-	{0x00E0, 0x00F6, d{-32, 0, -32}},
-	{0x00F8, 0x00FE, d{-32, 0, -32}},
-	{0x00FF, 0x00FF, d{121, 0, 121}},
-	{0x0100, 0x012F, d{UpperLower, UpperLower, UpperLower}},
-	{0x0130, 0x0130, d{0, -199, 0}},
-	{0x0131, 0x0131, d{-232, 0, -232}},
-	{0x0132, 0x0137, d{UpperLower, UpperLower, UpperLower}},
-	{0x0139, 0x0148, d{UpperLower, UpperLower, UpperLower}},
-	{0x014A, 0x0177, d{UpperLower, UpperLower, UpperLower}},
-	{0x0178, 0x0178, d{0, -121, 0}},
-	{0x0179, 0x017E, d{UpperLower, UpperLower, UpperLower}},
-	{0x017F, 0x017F, d{-300, 0, -300}},
-	{0x0180, 0x0180, d{195, 0, 195}},
-	{0x0181, 0x0181, d{0, 210, 0}},
-	{0x0182, 0x0185, d{UpperLower, UpperLower, UpperLower}},
-	{0x0186, 0x0186, d{0, 206, 0}},
-	{0x0187, 0x0188, d{UpperLower, UpperLower, UpperLower}},
-	{0x0189, 0x018A, d{0, 205, 0}},
-	{0x018B, 0x018C, d{UpperLower, UpperLower, UpperLower}},
-	{0x018E, 0x018E, d{0, 79, 0}},
-	{0x018F, 0x018F, d{0, 202, 0}},
-	{0x0190, 0x0190, d{0, 203, 0}},
-	{0x0191, 0x0192, d{UpperLower, UpperLower, UpperLower}},
-	{0x0193, 0x0193, d{0, 205, 0}},
-	{0x0194, 0x0194, d{0, 207, 0}},
-	{0x0195, 0x0195, d{97, 0, 97}},
-	{0x0196, 0x0196, d{0, 211, 0}},
-	{0x0197, 0x0197, d{0, 209, 0}},
-	{0x0198, 0x0199, d{UpperLower, UpperLower, UpperLower}},
-	{0x019A, 0x019A, d{163, 0, 163}},
-	{0x019C, 0x019C, d{0, 211, 0}},
-	{0x019D, 0x019D, d{0, 213, 0}},
-	{0x019E, 0x019E, d{130, 0, 130}},
-	{0x019F, 0x019F, d{0, 214, 0}},
-	{0x01A0, 0x01A5, d{UpperLower, UpperLower, UpperLower}},
-	{0x01A6, 0x01A6, d{0, 218, 0}},
-	{0x01A7, 0x01A8, d{UpperLower, UpperLower, UpperLower}},
-	{0x01A9, 0x01A9, d{0, 218, 0}},
-	{0x01AC, 0x01AD, d{UpperLower, UpperLower, UpperLower}},
-	{0x01AE, 0x01AE, d{0, 218, 0}},
-	{0x01AF, 0x01B0, d{UpperLower, UpperLower, UpperLower}},
-	{0x01B1, 0x01B2, d{0, 217, 0}},
-	{0x01B3, 0x01B6, d{UpperLower, UpperLower, UpperLower}},
-	{0x01B7, 0x01B7, d{0, 219, 0}},
-	{0x01B8, 0x01B9, d{UpperLower, UpperLower, UpperLower}},
-	{0x01BC, 0x01BD, d{UpperLower, UpperLower, UpperLower}},
-	{0x01BF, 0x01BF, d{56, 0, 56}},
-	{0x01C4, 0x01C4, d{0, 2, 1}},
-	{0x01C5, 0x01C5, d{-1, 1, 0}},
-	{0x01C6, 0x01C6, d{-2, 0, -1}},
-	{0x01C7, 0x01C7, d{0, 2, 1}},
-	{0x01C8, 0x01C8, d{-1, 1, 0}},
-	{0x01C9, 0x01C9, d{-2, 0, -1}},
-	{0x01CA, 0x01CA, d{0, 2, 1}},
-	{0x01CB, 0x01CB, d{-1, 1, 0}},
-	{0x01CC, 0x01CC, d{-2, 0, -1}},
-	{0x01CD, 0x01DC, d{UpperLower, UpperLower, UpperLower}},
-	{0x01DD, 0x01DD, d{-79, 0, -79}},
-	{0x01DE, 0x01EF, d{UpperLower, UpperLower, UpperLower}},
-	{0x01F1, 0x01F1, d{0, 2, 1}},
-	{0x01F2, 0x01F2, d{-1, 1, 0}},
-	{0x01F3, 0x01F3, d{-2, 0, -1}},
-	{0x01F4, 0x01F5, d{UpperLower, UpperLower, UpperLower}},
-	{0x01F6, 0x01F6, d{0, -97, 0}},
-	{0x01F7, 0x01F7, d{0, -56, 0}},
-	{0x01F8, 0x021F, d{UpperLower, UpperLower, UpperLower}},
-	{0x0220, 0x0220, d{0, -130, 0}},
-	{0x0222, 0x0233, d{UpperLower, UpperLower, UpperLower}},
-	{0x023A, 0x023A, d{0, 10795, 0}},
-	{0x023B, 0x023C, d{UpperLower, UpperLower, UpperLower}},
-	{0x023D, 0x023D, d{0, -163, 0}},
-	{0x023E, 0x023E, d{0, 10792, 0}},
-	{0x023F, 0x0240, d{10815, 0, 10815}},
-	{0x0241, 0x0242, d{UpperLower, UpperLower, UpperLower}},
-	{0x0243, 0x0243, d{0, -195, 0}},
-	{0x0244, 0x0244, d{0, 69, 0}},
-	{0x0245, 0x0245, d{0, 71, 0}},
-	{0x0246, 0x024F, d{UpperLower, UpperLower, UpperLower}},
-	{0x0250, 0x0250, d{10783, 0, 10783}},
-	{0x0251, 0x0251, d{10780, 0, 10780}},
-	{0x0252, 0x0252, d{10782, 0, 10782}},
-	{0x0253, 0x0253, d{-210, 0, -210}},
-	{0x0254, 0x0254, d{-206, 0, -206}},
-	{0x0256, 0x0257, d{-205, 0, -205}},
-	{0x0259, 0x0259, d{-202, 0, -202}},
-	{0x025B, 0x025B, d{-203, 0, -203}},
-	{0x0260, 0x0260, d{-205, 0, -205}},
-	{0x0263, 0x0263, d{-207, 0, -207}},
-	{0x0265, 0x0265, d{42280, 0, 42280}},
-	{0x0266, 0x0266, d{42308, 0, 42308}},
-	{0x0268, 0x0268, d{-209, 0, -209}},
-	{0x0269, 0x0269, d{-211, 0, -211}},
-	{0x026B, 0x026B, d{10743, 0, 10743}},
-	{0x026F, 0x026F, d{-211, 0, -211}},
-	{0x0271, 0x0271, d{10749, 0, 10749}},
-	{0x0272, 0x0272, d{-213, 0, -213}},
-	{0x0275, 0x0275, d{-214, 0, -214}},
-	{0x027D, 0x027D, d{10727, 0, 10727}},
-	{0x0280, 0x0280, d{-218, 0, -218}},
-	{0x0283, 0x0283, d{-218, 0, -218}},
-	{0x0288, 0x0288, d{-218, 0, -218}},
-	{0x0289, 0x0289, d{-69, 0, -69}},
-	{0x028A, 0x028B, d{-217, 0, -217}},
-	{0x028C, 0x028C, d{-71, 0, -71}},
-	{0x0292, 0x0292, d{-219, 0, -219}},
-	{0x0345, 0x0345, d{84, 0, 84}},
-	{0x0370, 0x0373, d{UpperLower, UpperLower, UpperLower}},
-	{0x0376, 0x0377, d{UpperLower, UpperLower, UpperLower}},
-	{0x037B, 0x037D, d{130, 0, 130}},
-	{0x0386, 0x0386, d{0, 38, 0}},
-	{0x0388, 0x038A, d{0, 37, 0}},
-	{0x038C, 0x038C, d{0, 64, 0}},
-	{0x038E, 0x038F, d{0, 63, 0}},
-	{0x0391, 0x03A1, d{0, 32, 0}},
-	{0x03A3, 0x03AB, d{0, 32, 0}},
-	{0x03AC, 0x03AC, d{-38, 0, -38}},
-	{0x03AD, 0x03AF, d{-37, 0, -37}},
-	{0x03B1, 0x03C1, d{-32, 0, -32}},
-	{0x03C2, 0x03C2, d{-31, 0, -31}},
-	{0x03C3, 0x03CB, d{-32, 0, -32}},
-	{0x03CC, 0x03CC, d{-64, 0, -64}},
-	{0x03CD, 0x03CE, d{-63, 0, -63}},
-	{0x03CF, 0x03CF, d{0, 8, 0}},
-	{0x03D0, 0x03D0, d{-62, 0, -62}},
-	{0x03D1, 0x03D1, d{-57, 0, -57}},
-	{0x03D5, 0x03D5, d{-47, 0, -47}},
-	{0x03D6, 0x03D6, d{-54, 0, -54}},
-	{0x03D7, 0x03D7, d{-8, 0, -8}},
-	{0x03D8, 0x03EF, d{UpperLower, UpperLower, UpperLower}},
-	{0x03F0, 0x03F0, d{-86, 0, -86}},
-	{0x03F1, 0x03F1, d{-80, 0, -80}},
-	{0x03F2, 0x03F2, d{7, 0, 7}},
-	{0x03F4, 0x03F4, d{0, -60, 0}},
-	{0x03F5, 0x03F5, d{-96, 0, -96}},
-	{0x03F7, 0x03F8, d{UpperLower, UpperLower, UpperLower}},
-	{0x03F9, 0x03F9, d{0, -7, 0}},
-	{0x03FA, 0x03FB, d{UpperLower, UpperLower, UpperLower}},
-	{0x03FD, 0x03FF, d{0, -130, 0}},
-	{0x0400, 0x040F, d{0, 80, 0}},
-	{0x0410, 0x042F, d{0, 32, 0}},
-	{0x0430, 0x044F, d{-32, 0, -32}},
-	{0x0450, 0x045F, d{-80, 0, -80}},
-	{0x0460, 0x0481, d{UpperLower, UpperLower, UpperLower}},
-	{0x048A, 0x04BF, d{UpperLower, UpperLower, UpperLower}},
-	{0x04C0, 0x04C0, d{0, 15, 0}},
-	{0x04C1, 0x04CE, d{UpperLower, UpperLower, UpperLower}},
-	{0x04CF, 0x04CF, d{-15, 0, -15}},
-	{0x04D0, 0x0527, d{UpperLower, UpperLower, UpperLower}},
-	{0x0531, 0x0556, d{0, 48, 0}},
-	{0x0561, 0x0586, d{-48, 0, -48}},
-	{0x10A0, 0x10C5, d{0, 7264, 0}},
-	{0x10C7, 0x10C7, d{0, 7264, 0}},
-	{0x10CD, 0x10CD, d{0, 7264, 0}},
-	{0x1D79, 0x1D79, d{35332, 0, 35332}},
-	{0x1D7D, 0x1D7D, d{3814, 0, 3814}},
-	{0x1E00, 0x1E95, d{UpperLower, UpperLower, UpperLower}},
-	{0x1E9B, 0x1E9B, d{-59, 0, -59}},
-	{0x1E9E, 0x1E9E, d{0, -7615, 0}},
-	{0x1EA0, 0x1EFF, d{UpperLower, UpperLower, UpperLower}},
-	{0x1F00, 0x1F07, d{8, 0, 8}},
-	{0x1F08, 0x1F0F, d{0, -8, 0}},
-	{0x1F10, 0x1F15, d{8, 0, 8}},
-	{0x1F18, 0x1F1D, d{0, -8, 0}},
-	{0x1F20, 0x1F27, d{8, 0, 8}},
-	{0x1F28, 0x1F2F, d{0, -8, 0}},
-	{0x1F30, 0x1F37, d{8, 0, 8}},
-	{0x1F38, 0x1F3F, d{0, -8, 0}},
-	{0x1F40, 0x1F45, d{8, 0, 8}},
-	{0x1F48, 0x1F4D, d{0, -8, 0}},
-	{0x1F51, 0x1F51, d{8, 0, 8}},
-	{0x1F53, 0x1F53, d{8, 0, 8}},
-	{0x1F55, 0x1F55, d{8, 0, 8}},
-	{0x1F57, 0x1F57, d{8, 0, 8}},
-	{0x1F59, 0x1F59, d{0, -8, 0}},
-	{0x1F5B, 0x1F5B, d{0, -8, 0}},
-	{0x1F5D, 0x1F5D, d{0, -8, 0}},
-	{0x1F5F, 0x1F5F, d{0, -8, 0}},
-	{0x1F60, 0x1F67, d{8, 0, 8}},
-	{0x1F68, 0x1F6F, d{0, -8, 0}},
-	{0x1F70, 0x1F71, d{74, 0, 74}},
-	{0x1F72, 0x1F75, d{86, 0, 86}},
-	{0x1F76, 0x1F77, d{100, 0, 100}},
-	{0x1F78, 0x1F79, d{128, 0, 128}},
-	{0x1F7A, 0x1F7B, d{112, 0, 112}},
-	{0x1F7C, 0x1F7D, d{126, 0, 126}},
-	{0x1F80, 0x1F87, d{8, 0, 8}},
-	{0x1F88, 0x1F8F, d{0, -8, 0}},
-	{0x1F90, 0x1F97, d{8, 0, 8}},
-	{0x1F98, 0x1F9F, d{0, -8, 0}},
-	{0x1FA0, 0x1FA7, d{8, 0, 8}},
-	{0x1FA8, 0x1FAF, d{0, -8, 0}},
-	{0x1FB0, 0x1FB1, d{8, 0, 8}},
-	{0x1FB3, 0x1FB3, d{9, 0, 9}},
-	{0x1FB8, 0x1FB9, d{0, -8, 0}},
-	{0x1FBA, 0x1FBB, d{0, -74, 0}},
-	{0x1FBC, 0x1FBC, d{0, -9, 0}},
-	{0x1FBE, 0x1FBE, d{-7205, 0, -7205}},
-	{0x1FC3, 0x1FC3, d{9, 0, 9}},
-	{0x1FC8, 0x1FCB, d{0, -86, 0}},
-	{0x1FCC, 0x1FCC, d{0, -9, 0}},
-	{0x1FD0, 0x1FD1, d{8, 0, 8}},
-	{0x1FD8, 0x1FD9, d{0, -8, 0}},
-	{0x1FDA, 0x1FDB, d{0, -100, 0}},
-	{0x1FE0, 0x1FE1, d{8, 0, 8}},
-	{0x1FE5, 0x1FE5, d{7, 0, 7}},
-	{0x1FE8, 0x1FE9, d{0, -8, 0}},
-	{0x1FEA, 0x1FEB, d{0, -112, 0}},
-	{0x1FEC, 0x1FEC, d{0, -7, 0}},
-	{0x1FF3, 0x1FF3, d{9, 0, 9}},
-	{0x1FF8, 0x1FF9, d{0, -128, 0}},
-	{0x1FFA, 0x1FFB, d{0, -126, 0}},
-	{0x1FFC, 0x1FFC, d{0, -9, 0}},
-	{0x2126, 0x2126, d{0, -7517, 0}},
-	{0x212A, 0x212A, d{0, -8383, 0}},
-	{0x212B, 0x212B, d{0, -8262, 0}},
-	{0x2132, 0x2132, d{0, 28, 0}},
-	{0x214E, 0x214E, d{-28, 0, -28}},
-	{0x2160, 0x216F, d{0, 16, 0}},
-	{0x2170, 0x217F, d{-16, 0, -16}},
-	{0x2183, 0x2184, d{UpperLower, UpperLower, UpperLower}},
-	{0x24B6, 0x24CF, d{0, 26, 0}},
-	{0x24D0, 0x24E9, d{-26, 0, -26}},
-	{0x2C00, 0x2C2E, d{0, 48, 0}},
-	{0x2C30, 0x2C5E, d{-48, 0, -48}},
-	{0x2C60, 0x2C61, d{UpperLower, UpperLower, UpperLower}},
-	{0x2C62, 0x2C62, d{0, -10743, 0}},
-	{0x2C63, 0x2C63, d{0, -3814, 0}},
-	{0x2C64, 0x2C64, d{0, -10727, 0}},
-	{0x2C65, 0x2C65, d{-10795, 0, -10795}},
-	{0x2C66, 0x2C66, d{-10792, 0, -10792}},
-	{0x2C67, 0x2C6C, d{UpperLower, UpperLower, UpperLower}},
-	{0x2C6D, 0x2C6D, d{0, -10780, 0}},
-	{0x2C6E, 0x2C6E, d{0, -10749, 0}},
-	{0x2C6F, 0x2C6F, d{0, -10783, 0}},
-	{0x2C70, 0x2C70, d{0, -10782, 0}},
-	{0x2C72, 0x2C73, d{UpperLower, UpperLower, UpperLower}},
-	{0x2C75, 0x2C76, d{UpperLower, UpperLower, UpperLower}},
-	{0x2C7E, 0x2C7F, d{0, -10815, 0}},
-	{0x2C80, 0x2CE3, d{UpperLower, UpperLower, UpperLower}},
-	{0x2CEB, 0x2CEE, d{UpperLower, UpperLower, UpperLower}},
-	{0x2CF2, 0x2CF3, d{UpperLower, UpperLower, UpperLower}},
-	{0x2D00, 0x2D25, d{-7264, 0, -7264}},
-	{0x2D27, 0x2D27, d{-7264, 0, -7264}},
-	{0x2D2D, 0x2D2D, d{-7264, 0, -7264}},
-	{0xA640, 0xA66D, d{UpperLower, UpperLower, UpperLower}},
-	{0xA680, 0xA697, d{UpperLower, UpperLower, UpperLower}},
-	{0xA722, 0xA72F, d{UpperLower, UpperLower, UpperLower}},
-	{0xA732, 0xA76F, d{UpperLower, UpperLower, UpperLower}},
-	{0xA779, 0xA77C, d{UpperLower, UpperLower, UpperLower}},
-	{0xA77D, 0xA77D, d{0, -35332, 0}},
-	{0xA77E, 0xA787, d{UpperLower, UpperLower, UpperLower}},
-	{0xA78B, 0xA78C, d{UpperLower, UpperLower, UpperLower}},
-	{0xA78D, 0xA78D, d{0, -42280, 0}},
-	{0xA790, 0xA793, d{UpperLower, UpperLower, UpperLower}},
-	{0xA7A0, 0xA7A9, d{UpperLower, UpperLower, UpperLower}},
-	{0xA7AA, 0xA7AA, d{0, -42308, 0}},
-	{0xFF21, 0xFF3A, d{0, 32, 0}},
-	{0xFF41, 0xFF5A, d{-32, 0, -32}},
-	{0x10400, 0x10427, d{0, 40, 0}},
-	{0x10428, 0x1044F, d{-40, 0, -40}},
-}
-var properties = [MaxLatin1 + 1]uint8{
-	0x00: pC,       // '\x00'
-	0x01: pC,       // '\x01'
-	0x02: pC,       // '\x02'
-	0x03: pC,       // '\x03'
-	0x04: pC,       // '\x04'
-	0x05: pC,       // '\x05'
-	0x06: pC,       // '\x06'
-	0x07: pC,       // '\a'
-	0x08: pC,       // '\b'
-	0x09: pC,       // '\t'
-	0x0A: pC,       // '\n'
-	0x0B: pC,       // '\v'
-	0x0C: pC,       // '\f'
-	0x0D: pC,       // '\r'
-	0x0E: pC,       // '\x0e'
-	0x0F: pC,       // '\x0f'
-	0x10: pC,       // '\x10'
-	0x11: pC,       // '\x11'
-	0x12: pC,       // '\x12'
-	0x13: pC,       // '\x13'
-	0x14: pC,       // '\x14'
-	0x15: pC,       // '\x15'
-	0x16: pC,       // '\x16'
-	0x17: pC,       // '\x17'
-	0x18: pC,       // '\x18'
-	0x19: pC,       // '\x19'
-	0x1A: pC,       // '\x1a'
-	0x1B: pC,       // '\x1b'
-	0x1C: pC,       // '\x1c'
-	0x1D: pC,       // '\x1d'
-	0x1E: pC,       // '\x1e'
-	0x1F: pC,       // '\x1f'
-	0x20: pZ | pp,  // ' '
-	0x21: pP | pp,  // '!'
-	0x22: pP | pp,  // '"'
-	0x23: pP | pp,  // '#'
-	0x24: pS | pp,  // '$'
-	0x25: pP | pp,  // '%'
-	0x26: pP | pp,  // '&'
-	0x27: pP | pp,  // '\''
-	0x28: pP | pp,  // '('
-	0x29: pP | pp,  // ')'
-	0x2A: pP | pp,  // '*'
-	0x2B: pS | pp,  // '+'
-	0x2C: pP | pp,  // ','
-	0x2D: pP | pp,  // '-'
-	0x2E: pP | pp,  // '.'
-	0x2F: pP | pp,  // '/'
-	0x30: pN | pp,  // '0'
-	0x31: pN | pp,  // '1'
-	0x32: pN | pp,  // '2'
-	0x33: pN | pp,  // '3'
-	0x34: pN | pp,  // '4'
-	0x35: pN | pp,  // '5'
-	0x36: pN | pp,  // '6'
-	0x37: pN | pp,  // '7'
-	0x38: pN | pp,  // '8'
-	0x39: pN | pp,  // '9'
-	0x3A: pP | pp,  // ':'
-	0x3B: pP | pp,  // ';'
-	0x3C: pS | pp,  // '<'
-	0x3D: pS | pp,  // '='
-	0x3E: pS | pp,  // '>'
-	0x3F: pP | pp,  // '?'
-	0x40: pP | pp,  // '@'
-	0x41: pLu | pp, // 'A'
-	0x42: pLu | pp, // 'B'
-	0x43: pLu | pp, // 'C'
-	0x44: pLu | pp, // 'D'
-	0x45: pLu | pp, // 'E'
-	0x46: pLu | pp, // 'F'
-	0x47: pLu | pp, // 'G'
-	0x48: pLu | pp, // 'H'
-	0x49: pLu | pp, // 'I'
-	0x4A: pLu | pp, // 'J'
-	0x4B: pLu | pp, // 'K'
-	0x4C: pLu | pp, // 'L'
-	0x4D: pLu | pp, // 'M'
-	0x4E: pLu | pp, // 'N'
-	0x4F: pLu | pp, // 'O'
-	0x50: pLu | pp, // 'P'
-	0x51: pLu | pp, // 'Q'
-	0x52: pLu | pp, // 'R'
-	0x53: pLu | pp, // 'S'
-	0x54: pLu | pp, // 'T'
-	0x55: pLu | pp, // 'U'
-	0x56: pLu | pp, // 'V'
-	0x57: pLu | pp, // 'W'
-	0x58: pLu | pp, // 'X'
-	0x59: pLu | pp, // 'Y'
-	0x5A: pLu | pp, // 'Z'
-	0x5B: pP | pp,  // '['
-	0x5C: pP | pp,  // '\\'
-	0x5D: pP | pp,  // ']'
-	0x5E: pS | pp,  // '^'
-	0x5F: pP | pp,  // '_'
-	0x60: pS | pp,  // '`'
-	0x61: pLl | pp, // 'a'
-	0x62: pLl | pp, // 'b'
-	0x63: pLl | pp, // 'c'
-	0x64: pLl | pp, // 'd'
-	0x65: pLl | pp, // 'e'
-	0x66: pLl | pp, // 'f'
-	0x67: pLl | pp, // 'g'
-	0x68: pLl | pp, // 'h'
-	0x69: pLl | pp, // 'i'
-	0x6A: pLl | pp, // 'j'
-	0x6B: pLl | pp, // 'k'
-	0x6C: pLl | pp, // 'l'
-	0x6D: pLl | pp, // 'm'
-	0x6E: pLl | pp, // 'n'
-	0x6F: pLl | pp, // 'o'
-	0x70: pLl | pp, // 'p'
-	0x71: pLl | pp, // 'q'
-	0x72: pLl | pp, // 'r'
-	0x73: pLl | pp, // 's'
-	0x74: pLl | pp, // 't'
-	0x75: pLl | pp, // 'u'
-	0x76: pLl | pp, // 'v'
-	0x77: pLl | pp, // 'w'
-	0x78: pLl | pp, // 'x'
-	0x79: pLl | pp, // 'y'
-	0x7A: pLl | pp, // 'z'
-	0x7B: pP | pp,  // '{'
-	0x7C: pS | pp,  // '|'
-	0x7D: pP | pp,  // '}'
-	0x7E: pS | pp,  // '~'
-	0x7F: pC,       // '\u007f'
-	0x80: pC,       // '\u0080'
-	0x81: pC,       // '\u0081'
-	0x82: pC,       // '\u0082'
-	0x83: pC,       // '\u0083'
-	0x84: pC,       // '\u0084'
-	0x85: pC,       // '\u0085'
-	0x86: pC,       // '\u0086'
-	0x87: pC,       // '\u0087'
-	0x88: pC,       // '\u0088'
-	0x89: pC,       // '\u0089'
-	0x8A: pC,       // '\u008a'
-	0x8B: pC,       // '\u008b'
-	0x8C: pC,       // '\u008c'
-	0x8D: pC,       // '\u008d'
-	0x8E: pC,       // '\u008e'
-	0x8F: pC,       // '\u008f'
-	0x90: pC,       // '\u0090'
-	0x91: pC,       // '\u0091'
-	0x92: pC,       // '\u0092'
-	0x93: pC,       // '\u0093'
-	0x94: pC,       // '\u0094'
-	0x95: pC,       // '\u0095'
-	0x96: pC,       // '\u0096'
-	0x97: pC,       // '\u0097'
-	0x98: pC,       // '\u0098'
-	0x99: pC,       // '\u0099'
-	0x9A: pC,       // '\u009a'
-	0x9B: pC,       // '\u009b'
-	0x9C: pC,       // '\u009c'
-	0x9D: pC,       // '\u009d'
-	0x9E: pC,       // '\u009e'
-	0x9F: pC,       // '\u009f'
-	0xA0: pZ,       // '\u00a0'
-	0xA1: pP | pp,  // '¡'
-	0xA2: pS | pp,  // '¢'
-	0xA3: pS | pp,  // '£'
-	0xA4: pS | pp,  // '¤'
-	0xA5: pS | pp,  // '¥'
-	0xA6: pS | pp,  // '¦'
-	0xA7: pP | pp,  // '§'
-	0xA8: pS | pp,  // '¨'
-	0xA9: pS | pp,  // '©'
-	0xAA: pLo | pp, // 'ª'
-	0xAB: pP | pp,  // '«'
-	0xAC: pS | pp,  // '¬'
-	0xAD: 0,        // '\u00ad'
-	0xAE: pS | pp,  // '®'
-	0xAF: pS | pp,  // '¯'
-	0xB0: pS | pp,  // '°'
-	0xB1: pS | pp,  // '±'
-	0xB2: pN | pp,  // '²'
-	0xB3: pN | pp,  // '³'
-	0xB4: pS | pp,  // '´'
-	0xB5: pLl | pp, // 'µ'
-	0xB6: pP | pp,  // '¶'
-	0xB7: pP | pp,  // '·'
-	0xB8: pS | pp,  // '¸'
-	0xB9: pN | pp,  // '¹'
-	0xBA: pLo | pp, // 'º'
-	0xBB: pP | pp,  // '»'
-	0xBC: pN | pp,  // '¼'
-	0xBD: pN | pp,  // '½'
-	0xBE: pN | pp,  // '¾'
-	0xBF: pP | pp,  // '¿'
-	0xC0: pLu | pp, // 'À'
-	0xC1: pLu | pp, // 'Á'
-	0xC2: pLu | pp, // 'Â'
-	0xC3: pLu | pp, // 'Ã'
-	0xC4: pLu | pp, // 'Ä'
-	0xC5: pLu | pp, // 'Å'
-	0xC6: pLu | pp, // 'Æ'
-	0xC7: pLu | pp, // 'Ç'
-	0xC8: pLu | pp, // 'È'
-	0xC9: pLu | pp, // 'É'
-	0xCA: pLu | pp, // 'Ê'
-	0xCB: pLu | pp, // 'Ë'
-	0xCC: pLu | pp, // 'Ì'
-	0xCD: pLu | pp, // 'Í'
-	0xCE: pLu | pp, // 'Î'
-	0xCF: pLu | pp, // 'Ï'
-	0xD0: pLu | pp, // 'Ð'
-	0xD1: pLu | pp, // 'Ñ'
-	0xD2: pLu | pp, // 'Ò'
-	0xD3: pLu | pp, // 'Ó'
-	0xD4: pLu | pp, // 'Ô'
-	0xD5: pLu | pp, // 'Õ'
-	0xD6: pLu | pp, // 'Ö'
-	0xD7: pS | pp,  // '×'
-	0xD8: pLu | pp, // 'Ø'
-	0xD9: pLu | pp, // 'Ù'
-	0xDA: pLu | pp, // 'Ú'
-	0xDB: pLu | pp, // 'Û'
-	0xDC: pLu | pp, // 'Ü'
-	0xDD: pLu | pp, // 'Ý'
-	0xDE: pLu | pp, // 'Þ'
-	0xDF: pLl | pp, // 'ß'
-	0xE0: pLl | pp, // 'à'
-	0xE1: pLl | pp, // 'á'
-	0xE2: pLl | pp, // 'â'
-	0xE3: pLl | pp, // 'ã'
-	0xE4: pLl | pp, // 'ä'
-	0xE5: pLl | pp, // 'å'
-	0xE6: pLl | pp, // 'æ'
-	0xE7: pLl | pp, // 'ç'
-	0xE8: pLl | pp, // 'è'
-	0xE9: pLl | pp, // 'é'
-	0xEA: pLl | pp, // 'ê'
-	0xEB: pLl | pp, // 'ë'
-	0xEC: pLl | pp, // 'ì'
-	0xED: pLl | pp, // 'í'
-	0xEE: pLl | pp, // 'î'
-	0xEF: pLl | pp, // 'ï'
-	0xF0: pLl | pp, // 'ð'
-	0xF1: pLl | pp, // 'ñ'
-	0xF2: pLl | pp, // 'ò'
-	0xF3: pLl | pp, // 'ó'
-	0xF4: pLl | pp, // 'ô'
-	0xF5: pLl | pp, // 'õ'
-	0xF6: pLl | pp, // 'ö'
-	0xF7: pS | pp,  // '÷'
-	0xF8: pLl | pp, // 'ø'
-	0xF9: pLl | pp, // 'ù'
-	0xFA: pLl | pp, // 'ú'
-	0xFB: pLl | pp, // 'û'
-	0xFC: pLl | pp, // 'ü'
-	0xFD: pLl | pp, // 'ý'
-	0xFE: pLl | pp, // 'þ'
-	0xFF: pLl | pp, // 'ÿ'
-}
-
-var caseOrbit = []foldPair{
-	{0x004B, 0x006B},
-	{0x0053, 0x0073},
-	{0x006B, 0x212A},
-	{0x0073, 0x017F},
-	{0x00B5, 0x039C},
-	{0x00C5, 0x00E5},
-	{0x00DF, 0x1E9E},
-	{0x00E5, 0x212B},
-	{0x0130, 0x0130},
-	{0x0131, 0x0131},
-	{0x017F, 0x0053},
-	{0x01C4, 0x01C5},
-	{0x01C5, 0x01C6},
-	{0x01C6, 0x01C4},
-	{0x01C7, 0x01C8},
-	{0x01C8, 0x01C9},
-	{0x01C9, 0x01C7},
-	{0x01CA, 0x01CB},
-	{0x01CB, 0x01CC},
-	{0x01CC, 0x01CA},
-	{0x01F1, 0x01F2},
-	{0x01F2, 0x01F3},
-	{0x01F3, 0x01F1},
-	{0x0345, 0x0399},
-	{0x0392, 0x03B2},
-	{0x0395, 0x03B5},
-	{0x0398, 0x03B8},
-	{0x0399, 0x03B9},
-	{0x039A, 0x03BA},
-	{0x039C, 0x03BC},
-	{0x03A0, 0x03C0},
-	{0x03A1, 0x03C1},
-	{0x03A3, 0x03C2},
-	{0x03A6, 0x03C6},
-	{0x03A9, 0x03C9},
-	{0x03B2, 0x03D0},
-	{0x03B5, 0x03F5},
-	{0x03B8, 0x03D1},
-	{0x03B9, 0x1FBE},
-	{0x03BA, 0x03F0},
-	{0x03BC, 0x00B5},
-	{0x03C0, 0x03D6},
-	{0x03C1, 0x03F1},
-	{0x03C2, 0x03C3},
-	{0x03C3, 0x03A3},
-	{0x03C6, 0x03D5},
-	{0x03C9, 0x2126},
-	{0x03D0, 0x0392},
-	{0x03D1, 0x03F4},
-	{0x03D5, 0x03A6},
-	{0x03D6, 0x03A0},
-	{0x03F0, 0x039A},
-	{0x03F1, 0x03A1},
-	{0x03F4, 0x0398},
-	{0x03F5, 0x0395},
-	{0x1E60, 0x1E61},
-	{0x1E61, 0x1E9B},
-	{0x1E9B, 0x1E60},
-	{0x1E9E, 0x00DF},
-	{0x1FBE, 0x0345},
-	{0x2126, 0x03A9},
-	{0x212A, 0x004B},
-	{0x212B, 0x00C5},
-}
-
-// FoldCategory maps a category name to a table of
-// code points outside the category that are equivalent under
-// simple case folding to code points inside the category.
-// If there is no entry for a category name, there are no such points.
-var FoldCategory = map[string]*RangeTable{
-	"Common":    foldCommon,
-	"Greek":     foldGreek,
-	"Inherited": foldInherited,
-	"L":         foldL,
-	"Ll":        foldLl,
-	"Lt":        foldLt,
-	"Lu":        foldLu,
-	"M":         foldM,
-	"Mn":        foldMn,
-}
-
-var foldCommon = &RangeTable{
-	R16: []Range16{
-		{0x039c, 0x03bc, 32},
-	},
-}
-
-var foldGreek = &RangeTable{
-	R16: []Range16{
-		{0x00b5, 0x0345, 656},
-	},
-}
-
-var foldInherited = &RangeTable{
-	R16: []Range16{
-		{0x0399, 0x03b9, 32},
-		{0x1fbe, 0x1fbe, 1},
-	},
-}
-
-var foldL = &RangeTable{
-	R16: []Range16{
-		{0x0345, 0x0345, 1},
-	},
-}
-
-var foldLl = &RangeTable{
-	R16: []Range16{
-		{0x0041, 0x005a, 1},
-		{0x00c0, 0x00d6, 1},
-		{0x00d8, 0x00de, 1},
-		{0x0100, 0x012e, 2},
-		{0x0132, 0x0136, 2},
-		{0x0139, 0x0147, 2},
-		{0x014a, 0x0178, 2},
-		{0x0179, 0x017d, 2},
-		{0x0181, 0x0182, 1},
-		{0x0184, 0x0186, 2},
-		{0x0187, 0x0189, 2},
-		{0x018a, 0x018b, 1},
-		{0x018e, 0x0191, 1},
-		{0x0193, 0x0194, 1},
-		{0x0196, 0x0198, 1},
-		{0x019c, 0x019d, 1},
-		{0x019f, 0x01a0, 1},
-		{0x01a2, 0x01a6, 2},
-		{0x01a7, 0x01a9, 2},
-		{0x01ac, 0x01ae, 2},
-		{0x01af, 0x01b1, 2},
-		{0x01b2, 0x01b3, 1},
-		{0x01b5, 0x01b7, 2},
-		{0x01b8, 0x01bc, 4},
-		{0x01c4, 0x01c5, 1},
-		{0x01c7, 0x01c8, 1},
-		{0x01ca, 0x01cb, 1},
-		{0x01cd, 0x01db, 2},
-		{0x01de, 0x01ee, 2},
-		{0x01f1, 0x01f2, 1},
-		{0x01f4, 0x01f6, 2},
-		{0x01f7, 0x01f8, 1},
-		{0x01fa, 0x0232, 2},
-		{0x023a, 0x023b, 1},
-		{0x023d, 0x023e, 1},
-		{0x0241, 0x0243, 2},
-		{0x0244, 0x0246, 1},
-		{0x0248, 0x024e, 2},
-		{0x0345, 0x0370, 43},
-		{0x0372, 0x0376, 4},
-		{0x0386, 0x0388, 2},
-		{0x0389, 0x038a, 1},
-		{0x038c, 0x038e, 2},
-		{0x038f, 0x0391, 2},
-		{0x0392, 0x03a1, 1},
-		{0x03a3, 0x03ab, 1},
-		{0x03cf, 0x03d8, 9},
-		{0x03da, 0x03ee, 2},
-		{0x03f4, 0x03f7, 3},
-		{0x03f9, 0x03fa, 1},
-		{0x03fd, 0x042f, 1},
-		{0x0460, 0x0480, 2},
-		{0x048a, 0x04c0, 2},
-		{0x04c1, 0x04cd, 2},
-		{0x04d0, 0x0526, 2},
-		{0x0531, 0x0556, 1},
-		{0x10a0, 0x10c5, 1},
-		{0x10c7, 0x10cd, 6},
-		{0x1e00, 0x1e94, 2},
-		{0x1e9e, 0x1efe, 2},
-		{0x1f08, 0x1f0f, 1},
-		{0x1f18, 0x1f1d, 1},
-		{0x1f28, 0x1f2f, 1},
-		{0x1f38, 0x1f3f, 1},
-		{0x1f48, 0x1f4d, 1},
-		{0x1f59, 0x1f5f, 2},
-		{0x1f68, 0x1f6f, 1},
-		{0x1f88, 0x1f8f, 1},
-		{0x1f98, 0x1f9f, 1},
-		{0x1fa8, 0x1faf, 1},
-		{0x1fb8, 0x1fbc, 1},
-		{0x1fc8, 0x1fcc, 1},
-		{0x1fd8, 0x1fdb, 1},
-		{0x1fe8, 0x1fec, 1},
-		{0x1ff8, 0x1ffc, 1},
-		{0x2126, 0x212a, 4},
-		{0x212b, 0x2132, 7},
-		{0x2183, 0x2c00, 2685},
-		{0x2c01, 0x2c2e, 1},
-		{0x2c60, 0x2c62, 2},
-		{0x2c63, 0x2c64, 1},
-		{0x2c67, 0x2c6d, 2},
-		{0x2c6e, 0x2c70, 1},
-		{0x2c72, 0x2c75, 3},
-		{0x2c7e, 0x2c80, 1},
-		{0x2c82, 0x2ce2, 2},
-		{0x2ceb, 0x2ced, 2},
-		{0x2cf2, 0xa640, 31054},
-		{0xa642, 0xa66c, 2},
-		{0xa680, 0xa696, 2},
-		{0xa722, 0xa72e, 2},
-		{0xa732, 0xa76e, 2},
-		{0xa779, 0xa77d, 2},
-		{0xa77e, 0xa786, 2},
-		{0xa78b, 0xa78d, 2},
-		{0xa790, 0xa792, 2},
-		{0xa7a0, 0xa7aa, 2},
-		{0xff21, 0xff3a, 1},
-	},
-	R32: []Range32{
-		{0x10400, 0x10427, 1},
-	},
-	LatinOffset: 3,
-}
-
-var foldLt = &RangeTable{
-	R16: []Range16{
-		{0x01c4, 0x01c6, 2},
-		{0x01c7, 0x01c9, 2},
-		{0x01ca, 0x01cc, 2},
-		{0x01f1, 0x01f3, 2},
-		{0x1f80, 0x1f87, 1},
-		{0x1f90, 0x1f97, 1},
-		{0x1fa0, 0x1fa7, 1},
-		{0x1fb3, 0x1fc3, 16},
-		{0x1ff3, 0x1ff3, 1},
-	},
-}
-
-var foldLu = &RangeTable{
-	R16: []Range16{
-		{0x0061, 0x007a, 1},
-		{0x00b5, 0x00df, 42},
-		{0x00e0, 0x00f6, 1},
-		{0x00f8, 0x00ff, 1},
-		{0x0101, 0x012f, 2},
-		{0x0133, 0x0137, 2},
-		{0x013a, 0x0148, 2},
-		{0x014b, 0x0177, 2},
-		{0x017a, 0x017e, 2},
-		{0x017f, 0x0180, 1},
-		{0x0183, 0x0185, 2},
-		{0x0188, 0x018c, 4},
-		{0x0192, 0x0195, 3},
-		{0x0199, 0x019a, 1},
-		{0x019e, 0x01a1, 3},
-		{0x01a3, 0x01a5, 2},
-		{0x01a8, 0x01ad, 5},
-		{0x01b0, 0x01b4, 4},
-		{0x01b6, 0x01b9, 3},
-		{0x01bd, 0x01bf, 2},
-		{0x01c5, 0x01c6, 1},
-		{0x01c8, 0x01c9, 1},
-		{0x01cb, 0x01cc, 1},
-		{0x01ce, 0x01dc, 2},
-		{0x01dd, 0x01ef, 2},
-		{0x01f2, 0x01f3, 1},
-		{0x01f5, 0x01f9, 4},
-		{0x01fb, 0x021f, 2},
-		{0x0223, 0x0233, 2},
-		{0x023c, 0x023f, 3},
-		{0x0240, 0x0242, 2},
-		{0x0247, 0x024f, 2},
-		{0x0250, 0x0254, 1},
-		{0x0256, 0x0257, 1},
-		{0x0259, 0x025b, 2},
-		{0x0260, 0x0263, 3},
-		{0x0265, 0x0266, 1},
-		{0x0268, 0x0269, 1},
-		{0x026b, 0x026f, 4},
-		{0x0271, 0x0272, 1},
-		{0x0275, 0x027d, 8},
-		{0x0280, 0x0283, 3},
-		{0x0288, 0x028c, 1},
-		{0x0292, 0x0345, 179},
-		{0x0371, 0x0373, 2},
-		{0x0377, 0x037b, 4},
-		{0x037c, 0x037d, 1},
-		{0x03ac, 0x03af, 1},
-		{0x03b1, 0x03ce, 1},
-		{0x03d0, 0x03d1, 1},
-		{0x03d5, 0x03d7, 1},
-		{0x03d9, 0x03ef, 2},
-		{0x03f0, 0x03f2, 1},
-		{0x03f5, 0x03fb, 3},
-		{0x0430, 0x045f, 1},
-		{0x0461, 0x0481, 2},
-		{0x048b, 0x04bf, 2},
-		{0x04c2, 0x04ce, 2},
-		{0x04cf, 0x0527, 2},
-		{0x0561, 0x0586, 1},
-		{0x1d79, 0x1d7d, 4},
-		{0x1e01, 0x1e95, 2},
-		{0x1e9b, 0x1ea1, 6},
-		{0x1ea3, 0x1eff, 2},
-		{0x1f00, 0x1f07, 1},
-		{0x1f10, 0x1f15, 1},
-		{0x1f20, 0x1f27, 1},
-		{0x1f30, 0x1f37, 1},
-		{0x1f40, 0x1f45, 1},
-		{0x1f51, 0x1f57, 2},
-		{0x1f60, 0x1f67, 1},
-		{0x1f70, 0x1f7d, 1},
-		{0x1fb0, 0x1fb1, 1},
-		{0x1fbe, 0x1fd0, 18},
-		{0x1fd1, 0x1fe0, 15},
-		{0x1fe1, 0x1fe5, 4},
-		{0x214e, 0x2184, 54},
-		{0x2c30, 0x2c5e, 1},
-		{0x2c61, 0x2c65, 4},
-		{0x2c66, 0x2c6c, 2},
-		{0x2c73, 0x2c76, 3},
-		{0x2c81, 0x2ce3, 2},
-		{0x2cec, 0x2cee, 2},
-		{0x2cf3, 0x2d00, 13},
-		{0x2d01, 0x2d25, 1},
-		{0x2d27, 0x2d2d, 6},
-		{0xa641, 0xa66d, 2},
-		{0xa681, 0xa697, 2},
-		{0xa723, 0xa72f, 2},
-		{0xa733, 0xa76f, 2},
-		{0xa77a, 0xa77c, 2},
-		{0xa77f, 0xa787, 2},
-		{0xa78c, 0xa791, 5},
-		{0xa793, 0xa7a1, 14},
-		{0xa7a3, 0xa7a9, 2},
-		{0xff41, 0xff5a, 1},
-	},
-	R32: []Range32{
-		{0x10428, 0x1044f, 1},
-	},
-	LatinOffset: 4,
-}
-
-var foldM = &RangeTable{
-	R16: []Range16{
-		{0x0399, 0x03b9, 32},
-		{0x1fbe, 0x1fbe, 1},
-	},
-}
-
-var foldMn = &RangeTable{
-	R16: []Range16{
-		{0x0399, 0x03b9, 32},
-		{0x1fbe, 0x1fbe, 1},
-	},
-}
-
-// FoldScript maps a script name to a table of
-// code points outside the script that are equivalent under
-// simple case folding to code points inside the script.
-// If there is no entry for a script name, there are no such points.
-var FoldScript = map[string]*RangeTable{}
-
-// Range entries: 3471 16-bit, 832 32-bit, 4303 total.
-// Range bytes: 20826 16-bit, 9984 32-bit, 30810 total.
-
-// Fold orbit bytes: 63 pairs, 252 bytes
diff --git a/src/pkg/unicode/utf8/utf8.go b/src/pkg/unicode/utf8/utf8.go
deleted file mode 100644
index 0dc859a..0000000
--- a/src/pkg/unicode/utf8/utf8.go
+++ /dev/null
@@ -1,435 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package utf8 implements functions and constants to support text encoded in
-// UTF-8. It includes functions to translate between runes and UTF-8 byte sequences.
-package utf8
-
-// The conditions RuneError==unicode.ReplacementChar and
-// MaxRune==unicode.MaxRune are verified in the tests.
-// Defining them locally avoids this package depending on package unicode.
-
-// Numbers fundamental to the encoding.
-const (
-	RuneError = '\uFFFD'     // the "error" Rune or "Unicode replacement character"
-	RuneSelf  = 0x80         // characters below Runeself are represented as themselves in a single byte.
-	MaxRune   = '\U0010FFFF' // Maximum valid Unicode code point.
-	UTFMax    = 4            // maximum number of bytes of a UTF-8 encoded Unicode character.
-)
-
-// Code points in the surrogate range are not valid for UTF-8.
-const (
-	surrogateMin = 0xD800
-	surrogateMax = 0xDFFF
-)
-
-const (
-	t1 = 0x00 // 0000 0000
-	tx = 0x80 // 1000 0000
-	t2 = 0xC0 // 1100 0000
-	t3 = 0xE0 // 1110 0000
-	t4 = 0xF0 // 1111 0000
-	t5 = 0xF8 // 1111 1000
-
-	maskx = 0x3F // 0011 1111
-	mask2 = 0x1F // 0001 1111
-	mask3 = 0x0F // 0000 1111
-	mask4 = 0x07 // 0000 0111
-
-	rune1Max = 1<<7 - 1
-	rune2Max = 1<<11 - 1
-	rune3Max = 1<<16 - 1
-)
-
-func decodeRuneInternal(p []byte) (r rune, size int, short bool) {
-	n := len(p)
-	if n < 1 {
-		return RuneError, 0, true
-	}
-	c0 := p[0]
-
-	// 1-byte, 7-bit sequence?
-	if c0 < tx {
-		return rune(c0), 1, false
-	}
-
-	// unexpected continuation byte?
-	if c0 < t2 {
-		return RuneError, 1, false
-	}
-
-	// need first continuation byte
-	if n < 2 {
-		return RuneError, 1, true
-	}
-	c1 := p[1]
-	if c1 < tx || t2 <= c1 {
-		return RuneError, 1, false
-	}
-
-	// 2-byte, 11-bit sequence?
-	if c0 < t3 {
-		r = rune(c0&mask2)<<6 | rune(c1&maskx)
-		if r <= rune1Max {
-			return RuneError, 1, false
-		}
-		return r, 2, false
-	}
-
-	// need second continuation byte
-	if n < 3 {
-		return RuneError, 1, true
-	}
-	c2 := p[2]
-	if c2 < tx || t2 <= c2 {
-		return RuneError, 1, false
-	}
-
-	// 3-byte, 16-bit sequence?
-	if c0 < t4 {
-		r = rune(c0&mask3)<<12 | rune(c1&maskx)<<6 | rune(c2&maskx)
-		if r <= rune2Max {
-			return RuneError, 1, false
-		}
-		if surrogateMin <= r && r <= surrogateMax {
-			return RuneError, 1, false
-		}
-		return r, 3, false
-	}
-
-	// need third continuation byte
-	if n < 4 {
-		return RuneError, 1, true
-	}
-	c3 := p[3]
-	if c3 < tx || t2 <= c3 {
-		return RuneError, 1, false
-	}
-
-	// 4-byte, 21-bit sequence?
-	if c0 < t5 {
-		r = rune(c0&mask4)<<18 | rune(c1&maskx)<<12 | rune(c2&maskx)<<6 | rune(c3&maskx)
-		if r <= rune3Max || MaxRune < r {
-			return RuneError, 1, false
-		}
-		return r, 4, false
-	}
-
-	// error
-	return RuneError, 1, false
-}
-
-func decodeRuneInStringInternal(s string) (r rune, size int, short bool) {
-	n := len(s)
-	if n < 1 {
-		return RuneError, 0, true
-	}
-	c0 := s[0]
-
-	// 1-byte, 7-bit sequence?
-	if c0 < tx {
-		return rune(c0), 1, false
-	}
-
-	// unexpected continuation byte?
-	if c0 < t2 {
-		return RuneError, 1, false
-	}
-
-	// need first continuation byte
-	if n < 2 {
-		return RuneError, 1, true
-	}
-	c1 := s[1]
-	if c1 < tx || t2 <= c1 {
-		return RuneError, 1, false
-	}
-
-	// 2-byte, 11-bit sequence?
-	if c0 < t3 {
-		r = rune(c0&mask2)<<6 | rune(c1&maskx)
-		if r <= rune1Max {
-			return RuneError, 1, false
-		}
-		return r, 2, false
-	}
-
-	// need second continuation byte
-	if n < 3 {
-		return RuneError, 1, true
-	}
-	c2 := s[2]
-	if c2 < tx || t2 <= c2 {
-		return RuneError, 1, false
-	}
-
-	// 3-byte, 16-bit sequence?
-	if c0 < t4 {
-		r = rune(c0&mask3)<<12 | rune(c1&maskx)<<6 | rune(c2&maskx)
-		if r <= rune2Max {
-			return RuneError, 1, false
-		}
-		if surrogateMin <= r && r <= surrogateMax {
-			return RuneError, 1, false
-		}
-		return r, 3, false
-	}
-
-	// need third continuation byte
-	if n < 4 {
-		return RuneError, 1, true
-	}
-	c3 := s[3]
-	if c3 < tx || t2 <= c3 {
-		return RuneError, 1, false
-	}
-
-	// 4-byte, 21-bit sequence?
-	if c0 < t5 {
-		r = rune(c0&mask4)<<18 | rune(c1&maskx)<<12 | rune(c2&maskx)<<6 | rune(c3&maskx)
-		if r <= rune3Max || MaxRune < r {
-			return RuneError, 1, false
-		}
-		return r, 4, false
-	}
-
-	// error
-	return RuneError, 1, false
-}
-
-// FullRune reports whether the bytes in p begin with a full UTF-8 encoding of a rune.
-// An invalid encoding is considered a full Rune since it will convert as a width-1 error rune.
-func FullRune(p []byte) bool {
-	_, _, short := decodeRuneInternal(p)
-	return !short
-}
-
-// FullRuneInString is like FullRune but its input is a string.
-func FullRuneInString(s string) bool {
-	_, _, short := decodeRuneInStringInternal(s)
-	return !short
-}
-
-// DecodeRune unpacks the first UTF-8 encoding in p and returns the rune and its width in bytes.
-// If the encoding is invalid, it returns (RuneError, 1), an impossible result for correct UTF-8.
-// An encoding is invalid if it is incorrect UTF-8, encodes a rune that is
-// out of range, or is not the shortest possible UTF-8 encoding for the
-// value. No other validation is performed.
-func DecodeRune(p []byte) (r rune, size int) {
-	r, size, _ = decodeRuneInternal(p)
-	return
-}
-
-// DecodeRuneInString is like DecodeRune but its input is a string.
-// If the encoding is invalid, it returns (RuneError, 1), an impossible result for correct UTF-8.
-// An encoding is invalid if it is incorrect UTF-8, encodes a rune that is
-// out of range, or is not the shortest possible UTF-8 encoding for the
-// value. No other validation is performed.
-func DecodeRuneInString(s string) (r rune, size int) {
-	r, size, _ = decodeRuneInStringInternal(s)
-	return
-}
-
-// DecodeLastRune unpacks the last UTF-8 encoding in p and returns the rune and its width in bytes.
-// If the encoding is invalid, it returns (RuneError, 1), an impossible result for correct UTF-8.
-// An encoding is invalid if it is incorrect UTF-8, encodes a rune that is
-// out of range, or is not the shortest possible UTF-8 encoding for the
-// value. No other validation is performed.
-func DecodeLastRune(p []byte) (r rune, size int) {
-	end := len(p)
-	if end == 0 {
-		return RuneError, 0
-	}
-	start := end - 1
-	r = rune(p[start])
-	if r < RuneSelf {
-		return r, 1
-	}
-	// guard against O(n^2) behavior when traversing
-	// backwards through strings with long sequences of
-	// invalid UTF-8.
-	lim := end - UTFMax
-	if lim < 0 {
-		lim = 0
-	}
-	for start--; start >= lim; start-- {
-		if RuneStart(p[start]) {
-			break
-		}
-	}
-	if start < 0 {
-		start = 0
-	}
-	r, size = DecodeRune(p[start:end])
-	if start+size != end {
-		return RuneError, 1
-	}
-	return r, size
-}
-
-// DecodeLastRuneInString is like DecodeLastRune but its input is a string.
-// If the encoding is invalid, it returns (RuneError, 1), an impossible result for correct UTF-8.
-// An encoding is invalid if it is incorrect UTF-8, encodes a rune that is
-// out of range, or is not the shortest possible UTF-8 encoding for the
-// value. No other validation is performed.
-func DecodeLastRuneInString(s string) (r rune, size int) {
-	end := len(s)
-	if end == 0 {
-		return RuneError, 0
-	}
-	start := end - 1
-	r = rune(s[start])
-	if r < RuneSelf {
-		return r, 1
-	}
-	// guard against O(n^2) behavior when traversing
-	// backwards through strings with long sequences of
-	// invalid UTF-8.
-	lim := end - UTFMax
-	if lim < 0 {
-		lim = 0
-	}
-	for start--; start >= lim; start-- {
-		if RuneStart(s[start]) {
-			break
-		}
-	}
-	if start < 0 {
-		start = 0
-	}
-	r, size = DecodeRuneInString(s[start:end])
-	if start+size != end {
-		return RuneError, 1
-	}
-	return r, size
-}
-
-// RuneLen returns the number of bytes required to encode the rune.
-// It returns -1 if the rune is not a valid value to encode in UTF-8.
-func RuneLen(r rune) int {
-	switch {
-	case r < 0:
-		return -1
-	case r <= rune1Max:
-		return 1
-	case r <= rune2Max:
-		return 2
-	case surrogateMin <= r && r <= surrogateMax:
-		return -1
-	case r <= rune3Max:
-		return 3
-	case r <= MaxRune:
-		return 4
-	}
-	return -1
-}
-
-// EncodeRune writes into p (which must be large enough) the UTF-8 encoding of the rune.
-// It returns the number of bytes written.
-func EncodeRune(p []byte, r rune) int {
-	// Negative values are erroneous.  Making it unsigned addresses the problem.
-	switch i := uint32(r); {
-	case i <= rune1Max:
-		p[0] = byte(r)
-		return 1
-	case i <= rune2Max:
-		p[0] = t2 | byte(r>>6)
-		p[1] = tx | byte(r)&maskx
-		return 2
-	case i > MaxRune, surrogateMin <= i && i <= surrogateMax:
-		r = RuneError
-		fallthrough
-	case i <= rune3Max:
-		p[0] = t3 | byte(r>>12)
-		p[1] = tx | byte(r>>6)&maskx
-		p[2] = tx | byte(r)&maskx
-		return 3
-	default:
-		p[0] = t4 | byte(r>>18)
-		p[1] = tx | byte(r>>12)&maskx
-		p[2] = tx | byte(r>>6)&maskx
-		p[3] = tx | byte(r)&maskx
-		return 4
-	}
-}
-
-// RuneCount returns the number of runes in p.  Erroneous and short
-// encodings are treated as single runes of width 1 byte.
-func RuneCount(p []byte) int {
-	i := 0
-	var n int
-	for n = 0; i < len(p); n++ {
-		if p[i] < RuneSelf {
-			i++
-		} else {
-			_, size := DecodeRune(p[i:])
-			i += size
-		}
-	}
-	return n
-}
-
-// RuneCountInString is like RuneCount but its input is a string.
-func RuneCountInString(s string) (n int) {
-	for _ = range s {
-		n++
-	}
-	return
-}
-
-// RuneStart reports whether the byte could be the first byte of
-// an encoded rune.  Second and subsequent bytes always have the top
-// two bits set to 10.
-func RuneStart(b byte) bool { return b&0xC0 != 0x80 }
-
-// Valid reports whether p consists entirely of valid UTF-8-encoded runes.
-func Valid(p []byte) bool {
-	i := 0
-	for i < len(p) {
-		if p[i] < RuneSelf {
-			i++
-		} else {
-			_, size := DecodeRune(p[i:])
-			if size == 1 {
-				// All valid runes of size 1 (those
-				// below RuneSelf) were handled above.
-				// This must be a RuneError.
-				return false
-			}
-			i += size
-		}
-	}
-	return true
-}
-
-// ValidString reports whether s consists entirely of valid UTF-8-encoded runes.
-func ValidString(s string) bool {
-	for i, r := range s {
-		if r == RuneError {
-			// The RuneError value can be an error
-			// sentinel value (if it's size 1) or the same
-			// value encoded properly. Decode it to see if
-			// it's the 1 byte sentinel value.
-			_, size := DecodeRuneInString(s[i:])
-			if size == 1 {
-				return false
-			}
-		}
-	}
-	return true
-}
-
-// ValidRune reports whether r can be legally encoded as UTF-8.
-// Code points that are out of range or a surrogate half are illegal.
-func ValidRune(r rune) bool {
-	switch {
-	case r < 0:
-		return false
-	case surrogateMin <= r && r <= surrogateMax:
-		return false
-	case r > MaxRune:
-		return false
-	}
-	return true
-}
diff --git a/src/pkg/unsafe/unsafe.go b/src/pkg/unsafe/unsafe.go
deleted file mode 100644
index 83b2e14..0000000
--- a/src/pkg/unsafe/unsafe.go
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-/*
-	Package unsafe contains operations that step around the type safety of Go programs.
-*/
-package unsafe
-
-// ArbitraryType is here for the purposes of documentation only and is not actually
-// part of the unsafe package.  It represents the type of an arbitrary Go expression.
-type ArbitraryType int
-
-// Pointer represents a pointer to an arbitrary type.  There are four special operations
-// available for type Pointer that are not available for other types.
-//	1) A pointer value of any type can be converted to a Pointer.
-//	2) A Pointer can be converted to a pointer value of any type.
-//	3) A uintptr can be converted to a Pointer.
-//	4) A Pointer can be converted to a uintptr.
-// Pointer therefore allows a program to defeat the type system and read and write
-// arbitrary memory. It should be used with extreme care.
-type Pointer *ArbitraryType
-
-// Sizeof returns the size in bytes occupied by the value v.  The size is that of the
-// "top level" of the value only.  For instance, if v is a slice, it returns the size of
-// the slice descriptor, not the size of the memory referenced by the slice.
-func Sizeof(v ArbitraryType) uintptr
-
-// Offsetof returns the offset within the struct of the field represented by v,
-// which must be of the form structValue.field.  In other words, it returns the
-// number of bytes between the start of the struct and the start of the field.
-func Offsetof(v ArbitraryType) uintptr
-
-// Alignof returns the alignment of the value v.  It is the maximum value m such
-// that the address of a variable with the type of v will always be zero mod m.
-// If v is of the form structValue.field, it returns the alignment of field f within struct object obj.
-func Alignof(v ArbitraryType) uintptr
diff --git a/src/race.bash b/src/race.bash
index 1680c09..6225840 100755
--- a/src/race.bash
+++ b/src/race.bash
@@ -9,7 +9,7 @@
 set -e
 
 function usage {
-	echo 'race detector is only supported on linux/amd64 and darwin/amd64' 1>&2
+	echo 'race detector is only supported on linux/amd64, freebsd/amd64 and darwin/amd64' 1>&2
 	exit 1
 }
 
@@ -25,6 +25,11 @@ case $(uname) in
 		usage
 	fi
 	;;
+"FreeBSD")
+	if [ $(uname -m) != "amd64" ]; then
+		usage
+	fi
+	;;
 *)
 	usage
 	;;
diff --git a/src/reflect/all_test.go b/src/reflect/all_test.go
new file mode 100644
index 0000000..7a01c95
--- /dev/null
+++ b/src/reflect/all_test.go
@@ -0,0 +1,4158 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package reflect_test
+
+import (
+	"bytes"
+	"encoding/base64"
+	"flag"
+	"fmt"
+	"io"
+	"math/rand"
+	"os"
+	. "reflect"
+	"runtime"
+	"sort"
+	"strings"
+	"sync"
+	"testing"
+	"time"
+	"unsafe"
+)
+
+func TestBool(t *testing.T) {
+	v := ValueOf(true)
+	if v.Bool() != true {
+		t.Fatal("ValueOf(true).Bool() = false")
+	}
+}
+
+type integer int
+type T struct {
+	a int
+	b float64
+	c string
+	d *int
+}
+
+type pair struct {
+	i interface{}
+	s string
+}
+
+func isDigit(c uint8) bool { return '0' <= c && c <= '9' }
+
+func assert(t *testing.T, s, want string) {
+	if s != want {
+		t.Errorf("have %#q want %#q", s, want)
+	}
+}
+
+func typestring(i interface{}) string { return TypeOf(i).String() }
+
+var typeTests = []pair{
+	{struct{ x int }{}, "int"},
+	{struct{ x int8 }{}, "int8"},
+	{struct{ x int16 }{}, "int16"},
+	{struct{ x int32 }{}, "int32"},
+	{struct{ x int64 }{}, "int64"},
+	{struct{ x uint }{}, "uint"},
+	{struct{ x uint8 }{}, "uint8"},
+	{struct{ x uint16 }{}, "uint16"},
+	{struct{ x uint32 }{}, "uint32"},
+	{struct{ x uint64 }{}, "uint64"},
+	{struct{ x float32 }{}, "float32"},
+	{struct{ x float64 }{}, "float64"},
+	{struct{ x int8 }{}, "int8"},
+	{struct{ x (**int8) }{}, "**int8"},
+	{struct{ x (**integer) }{}, "**reflect_test.integer"},
+	{struct{ x ([32]int32) }{}, "[32]int32"},
+	{struct{ x ([]int8) }{}, "[]int8"},
+	{struct{ x (map[string]int32) }{}, "map[string]int32"},
+	{struct{ x (chan<- string) }{}, "chan<- string"},
+	{struct {
+		x struct {
+			c chan *int32
+			d float32
+		}
+	}{},
+		"struct { c chan *int32; d float32 }",
+	},
+	{struct{ x (func(a int8, b int32)) }{}, "func(int8, int32)"},
+	{struct {
+		x struct {
+			c func(chan *integer, *int8)
+		}
+	}{},
+		"struct { c func(chan *reflect_test.integer, *int8) }",
+	},
+	{struct {
+		x struct {
+			a int8
+			b int32
+		}
+	}{},
+		"struct { a int8; b int32 }",
+	},
+	{struct {
+		x struct {
+			a int8
+			b int8
+			c int32
+		}
+	}{},
+		"struct { a int8; b int8; c int32 }",
+	},
+	{struct {
+		x struct {
+			a int8
+			b int8
+			c int8
+			d int32
+		}
+	}{},
+		"struct { a int8; b int8; c int8; d int32 }",
+	},
+	{struct {
+		x struct {
+			a int8
+			b int8
+			c int8
+			d int8
+			e int32
+		}
+	}{},
+		"struct { a int8; b int8; c int8; d int8; e int32 }",
+	},
+	{struct {
+		x struct {
+			a int8
+			b int8
+			c int8
+			d int8
+			e int8
+			f int32
+		}
+	}{},
+		"struct { a int8; b int8; c int8; d int8; e int8; f int32 }",
+	},
+	{struct {
+		x struct {
+			a int8 `reflect:"hi there"`
+		}
+	}{},
+		`struct { a int8 "reflect:\"hi there\"" }`,
+	},
+	{struct {
+		x struct {
+			a int8 `reflect:"hi \x00there\t\n\"\\"`
+		}
+	}{},
+		`struct { a int8 "reflect:\"hi \\x00there\\t\\n\\\"\\\\\"" }`,
+	},
+	{struct {
+		x struct {
+			f func(args ...int)
+		}
+	}{},
+		"struct { f func(...int) }",
+	},
+	{struct {
+		x (interface {
+			a(func(func(int) int) func(func(int)) int)
+			b()
+		})
+	}{},
+		"interface { reflect_test.a(func(func(int) int) func(func(int)) int); reflect_test.b() }",
+	},
+}
+
+var valueTests = []pair{
+	{new(int), "132"},
+	{new(int8), "8"},
+	{new(int16), "16"},
+	{new(int32), "32"},
+	{new(int64), "64"},
+	{new(uint), "132"},
+	{new(uint8), "8"},
+	{new(uint16), "16"},
+	{new(uint32), "32"},
+	{new(uint64), "64"},
+	{new(float32), "256.25"},
+	{new(float64), "512.125"},
+	{new(complex64), "532.125+10i"},
+	{new(complex128), "564.25+1i"},
+	{new(string), "stringy cheese"},
+	{new(bool), "true"},
+	{new(*int8), "*int8(0)"},
+	{new(**int8), "**int8(0)"},
+	{new([5]int32), "[5]int32{0, 0, 0, 0, 0}"},
+	{new(**integer), "**reflect_test.integer(0)"},
+	{new(map[string]int32), "map[string]int32{<can't iterate on maps>}"},
+	{new(chan<- string), "chan<- string"},
+	{new(func(a int8, b int32)), "func(int8, int32)(0)"},
+	{new(struct {
+		c chan *int32
+		d float32
+	}),
+		"struct { c chan *int32; d float32 }{chan *int32, 0}",
+	},
+	{new(struct{ c func(chan *integer, *int8) }),
+		"struct { c func(chan *reflect_test.integer, *int8) }{func(chan *reflect_test.integer, *int8)(0)}",
+	},
+	{new(struct {
+		a int8
+		b int32
+	}),
+		"struct { a int8; b int32 }{0, 0}",
+	},
+	{new(struct {
+		a int8
+		b int8
+		c int32
+	}),
+		"struct { a int8; b int8; c int32 }{0, 0, 0}",
+	},
+}
+
+func testType(t *testing.T, i int, typ Type, want string) {
+	s := typ.String()
+	if s != want {
+		t.Errorf("#%d: have %#q, want %#q", i, s, want)
+	}
+}
+
+func TestTypes(t *testing.T) {
+	for i, tt := range typeTests {
+		testType(t, i, ValueOf(tt.i).Field(0).Type(), tt.s)
+	}
+}
+
+func TestSet(t *testing.T) {
+	for i, tt := range valueTests {
+		v := ValueOf(tt.i)
+		v = v.Elem()
+		switch v.Kind() {
+		case Int:
+			v.SetInt(132)
+		case Int8:
+			v.SetInt(8)
+		case Int16:
+			v.SetInt(16)
+		case Int32:
+			v.SetInt(32)
+		case Int64:
+			v.SetInt(64)
+		case Uint:
+			v.SetUint(132)
+		case Uint8:
+			v.SetUint(8)
+		case Uint16:
+			v.SetUint(16)
+		case Uint32:
+			v.SetUint(32)
+		case Uint64:
+			v.SetUint(64)
+		case Float32:
+			v.SetFloat(256.25)
+		case Float64:
+			v.SetFloat(512.125)
+		case Complex64:
+			v.SetComplex(532.125 + 10i)
+		case Complex128:
+			v.SetComplex(564.25 + 1i)
+		case String:
+			v.SetString("stringy cheese")
+		case Bool:
+			v.SetBool(true)
+		}
+		s := valueToString(v)
+		if s != tt.s {
+			t.Errorf("#%d: have %#q, want %#q", i, s, tt.s)
+		}
+	}
+}
+
+func TestSetValue(t *testing.T) {
+	for i, tt := range valueTests {
+		v := ValueOf(tt.i).Elem()
+		switch v.Kind() {
+		case Int:
+			v.Set(ValueOf(int(132)))
+		case Int8:
+			v.Set(ValueOf(int8(8)))
+		case Int16:
+			v.Set(ValueOf(int16(16)))
+		case Int32:
+			v.Set(ValueOf(int32(32)))
+		case Int64:
+			v.Set(ValueOf(int64(64)))
+		case Uint:
+			v.Set(ValueOf(uint(132)))
+		case Uint8:
+			v.Set(ValueOf(uint8(8)))
+		case Uint16:
+			v.Set(ValueOf(uint16(16)))
+		case Uint32:
+			v.Set(ValueOf(uint32(32)))
+		case Uint64:
+			v.Set(ValueOf(uint64(64)))
+		case Float32:
+			v.Set(ValueOf(float32(256.25)))
+		case Float64:
+			v.Set(ValueOf(512.125))
+		case Complex64:
+			v.Set(ValueOf(complex64(532.125 + 10i)))
+		case Complex128:
+			v.Set(ValueOf(complex128(564.25 + 1i)))
+		case String:
+			v.Set(ValueOf("stringy cheese"))
+		case Bool:
+			v.Set(ValueOf(true))
+		}
+		s := valueToString(v)
+		if s != tt.s {
+			t.Errorf("#%d: have %#q, want %#q", i, s, tt.s)
+		}
+	}
+}
+
+var _i = 7
+
+var valueToStringTests = []pair{
+	{123, "123"},
+	{123.5, "123.5"},
+	{byte(123), "123"},
+	{"abc", "abc"},
+	{T{123, 456.75, "hello", &_i}, "reflect_test.T{123, 456.75, hello, *int(&7)}"},
+	{new(chan *T), "*chan *reflect_test.T(&chan *reflect_test.T)"},
+	{[10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, "[10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}"},
+	{&[10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, "*[10]int(&[10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10})"},
+	{[]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, "[]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}"},
+	{&[]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, "*[]int(&[]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10})"},
+}
+
+func TestValueToString(t *testing.T) {
+	for i, test := range valueToStringTests {
+		s := valueToString(ValueOf(test.i))
+		if s != test.s {
+			t.Errorf("#%d: have %#q, want %#q", i, s, test.s)
+		}
+	}
+}
+
+func TestArrayElemSet(t *testing.T) {
+	v := ValueOf(&[10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}).Elem()
+	v.Index(4).SetInt(123)
+	s := valueToString(v)
+	const want = "[10]int{1, 2, 3, 4, 123, 6, 7, 8, 9, 10}"
+	if s != want {
+		t.Errorf("[10]int: have %#q want %#q", s, want)
+	}
+
+	v = ValueOf([]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10})
+	v.Index(4).SetInt(123)
+	s = valueToString(v)
+	const want1 = "[]int{1, 2, 3, 4, 123, 6, 7, 8, 9, 10}"
+	if s != want1 {
+		t.Errorf("[]int: have %#q want %#q", s, want1)
+	}
+}
+
+func TestPtrPointTo(t *testing.T) {
+	var ip *int32
+	var i int32 = 1234
+	vip := ValueOf(&ip)
+	vi := ValueOf(&i).Elem()
+	vip.Elem().Set(vi.Addr())
+	if *ip != 1234 {
+		t.Errorf("got %d, want 1234", *ip)
+	}
+
+	ip = nil
+	vp := ValueOf(&ip).Elem()
+	vp.Set(Zero(vp.Type()))
+	if ip != nil {
+		t.Errorf("got non-nil (%p), want nil", ip)
+	}
+}
+
+func TestPtrSetNil(t *testing.T) {
+	var i int32 = 1234
+	ip := &i
+	vip := ValueOf(&ip)
+	vip.Elem().Set(Zero(vip.Elem().Type()))
+	if ip != nil {
+		t.Errorf("got non-nil (%d), want nil", *ip)
+	}
+}
+
+func TestMapSetNil(t *testing.T) {
+	m := make(map[string]int)
+	vm := ValueOf(&m)
+	vm.Elem().Set(Zero(vm.Elem().Type()))
+	if m != nil {
+		t.Errorf("got non-nil (%p), want nil", m)
+	}
+}
+
+func TestAll(t *testing.T) {
+	testType(t, 1, TypeOf((int8)(0)), "int8")
+	testType(t, 2, TypeOf((*int8)(nil)).Elem(), "int8")
+
+	typ := TypeOf((*struct {
+		c chan *int32
+		d float32
+	})(nil))
+	testType(t, 3, typ, "*struct { c chan *int32; d float32 }")
+	etyp := typ.Elem()
+	testType(t, 4, etyp, "struct { c chan *int32; d float32 }")
+	styp := etyp
+	f := styp.Field(0)
+	testType(t, 5, f.Type, "chan *int32")
+
+	f, present := styp.FieldByName("d")
+	if !present {
+		t.Errorf("FieldByName says present field is absent")
+	}
+	testType(t, 6, f.Type, "float32")
+
+	f, present = styp.FieldByName("absent")
+	if present {
+		t.Errorf("FieldByName says absent field is present")
+	}
+
+	typ = TypeOf([32]int32{})
+	testType(t, 7, typ, "[32]int32")
+	testType(t, 8, typ.Elem(), "int32")
+
+	typ = TypeOf((map[string]*int32)(nil))
+	testType(t, 9, typ, "map[string]*int32")
+	mtyp := typ
+	testType(t, 10, mtyp.Key(), "string")
+	testType(t, 11, mtyp.Elem(), "*int32")
+
+	typ = TypeOf((chan<- string)(nil))
+	testType(t, 12, typ, "chan<- string")
+	testType(t, 13, typ.Elem(), "string")
+
+	// make sure tag strings are not part of element type
+	typ = TypeOf(struct {
+		d []uint32 `reflect:"TAG"`
+	}{}).Field(0).Type
+	testType(t, 14, typ, "[]uint32")
+}
+
+func TestInterfaceGet(t *testing.T) {
+	var inter struct {
+		E interface{}
+	}
+	inter.E = 123.456
+	v1 := ValueOf(&inter)
+	v2 := v1.Elem().Field(0)
+	assert(t, v2.Type().String(), "interface {}")
+	i2 := v2.Interface()
+	v3 := ValueOf(i2)
+	assert(t, v3.Type().String(), "float64")
+}
+
+func TestInterfaceValue(t *testing.T) {
+	var inter struct {
+		E interface{}
+	}
+	inter.E = 123.456
+	v1 := ValueOf(&inter)
+	v2 := v1.Elem().Field(0)
+	assert(t, v2.Type().String(), "interface {}")
+	v3 := v2.Elem()
+	assert(t, v3.Type().String(), "float64")
+
+	i3 := v2.Interface()
+	if _, ok := i3.(float64); !ok {
+		t.Error("v2.Interface() did not return float64, got ", TypeOf(i3))
+	}
+}
+
+func TestFunctionValue(t *testing.T) {
+	var x interface{} = func() {}
+	v := ValueOf(x)
+	if fmt.Sprint(v.Interface()) != fmt.Sprint(x) {
+		t.Fatalf("TestFunction returned wrong pointer")
+	}
+	assert(t, v.Type().String(), "func()")
+}
+
+var appendTests = []struct {
+	orig, extra []int
+}{
+	{make([]int, 2, 4), []int{22}},
+	{make([]int, 2, 4), []int{22, 33, 44}},
+}
+
+func sameInts(x, y []int) bool {
+	if len(x) != len(y) {
+		return false
+	}
+	for i, xx := range x {
+		if xx != y[i] {
+			return false
+		}
+	}
+	return true
+}
+
+func TestAppend(t *testing.T) {
+	for i, test := range appendTests {
+		origLen, extraLen := len(test.orig), len(test.extra)
+		want := append(test.orig, test.extra...)
+		// Convert extra from []int to []Value.
+		e0 := make([]Value, len(test.extra))
+		for j, e := range test.extra {
+			e0[j] = ValueOf(e)
+		}
+		// Convert extra from []int to *SliceValue.
+		e1 := ValueOf(test.extra)
+		// Test Append.
+		a0 := ValueOf(test.orig)
+		have0 := Append(a0, e0...).Interface().([]int)
+		if !sameInts(have0, want) {
+			t.Errorf("Append #%d: have %v, want %v (%p %p)", i, have0, want, test.orig, have0)
+		}
+		// Check that the orig and extra slices were not modified.
+		if len(test.orig) != origLen {
+			t.Errorf("Append #%d origLen: have %v, want %v", i, len(test.orig), origLen)
+		}
+		if len(test.extra) != extraLen {
+			t.Errorf("Append #%d extraLen: have %v, want %v", i, len(test.extra), extraLen)
+		}
+		// Test AppendSlice.
+		a1 := ValueOf(test.orig)
+		have1 := AppendSlice(a1, e1).Interface().([]int)
+		if !sameInts(have1, want) {
+			t.Errorf("AppendSlice #%d: have %v, want %v", i, have1, want)
+		}
+		// Check that the orig and extra slices were not modified.
+		if len(test.orig) != origLen {
+			t.Errorf("AppendSlice #%d origLen: have %v, want %v", i, len(test.orig), origLen)
+		}
+		if len(test.extra) != extraLen {
+			t.Errorf("AppendSlice #%d extraLen: have %v, want %v", i, len(test.extra), extraLen)
+		}
+	}
+}
+
+func TestCopy(t *testing.T) {
+	a := []int{1, 2, 3, 4, 10, 9, 8, 7}
+	b := []int{11, 22, 33, 44, 1010, 99, 88, 77, 66, 55, 44}
+	c := []int{11, 22, 33, 44, 1010, 99, 88, 77, 66, 55, 44}
+	for i := 0; i < len(b); i++ {
+		if b[i] != c[i] {
+			t.Fatalf("b != c before test")
+		}
+	}
+	a1 := a
+	b1 := b
+	aa := ValueOf(&a1).Elem()
+	ab := ValueOf(&b1).Elem()
+	for tocopy := 1; tocopy <= 7; tocopy++ {
+		aa.SetLen(tocopy)
+		Copy(ab, aa)
+		aa.SetLen(8)
+		for i := 0; i < tocopy; i++ {
+			if a[i] != b[i] {
+				t.Errorf("(i) tocopy=%d a[%d]=%d, b[%d]=%d",
+					tocopy, i, a[i], i, b[i])
+			}
+		}
+		for i := tocopy; i < len(b); i++ {
+			if b[i] != c[i] {
+				if i < len(a) {
+					t.Errorf("(ii) tocopy=%d a[%d]=%d, b[%d]=%d, c[%d]=%d",
+						tocopy, i, a[i], i, b[i], i, c[i])
+				} else {
+					t.Errorf("(iii) tocopy=%d b[%d]=%d, c[%d]=%d",
+						tocopy, i, b[i], i, c[i])
+				}
+			} else {
+				t.Logf("tocopy=%d elem %d is okay\n", tocopy, i)
+			}
+		}
+	}
+}
+
+func TestCopyArray(t *testing.T) {
+	a := [8]int{1, 2, 3, 4, 10, 9, 8, 7}
+	b := [11]int{11, 22, 33, 44, 1010, 99, 88, 77, 66, 55, 44}
+	c := b
+	aa := ValueOf(&a).Elem()
+	ab := ValueOf(&b).Elem()
+	Copy(ab, aa)
+	for i := 0; i < len(a); i++ {
+		if a[i] != b[i] {
+			t.Errorf("(i) a[%d]=%d, b[%d]=%d", i, a[i], i, b[i])
+		}
+	}
+	for i := len(a); i < len(b); i++ {
+		if b[i] != c[i] {
+			t.Errorf("(ii) b[%d]=%d, c[%d]=%d", i, b[i], i, c[i])
+		} else {
+			t.Logf("elem %d is okay\n", i)
+		}
+	}
+}
+
+func TestBigUnnamedStruct(t *testing.T) {
+	b := struct{ a, b, c, d int64 }{1, 2, 3, 4}
+	v := ValueOf(b)
+	b1 := v.Interface().(struct {
+		a, b, c, d int64
+	})
+	if b1.a != b.a || b1.b != b.b || b1.c != b.c || b1.d != b.d {
+		t.Errorf("ValueOf(%v).Interface().(*Big) = %v", b, b1)
+	}
+}
+
+type big struct {
+	a, b, c, d, e int64
+}
+
+func TestBigStruct(t *testing.T) {
+	b := big{1, 2, 3, 4, 5}
+	v := ValueOf(b)
+	b1 := v.Interface().(big)
+	if b1.a != b.a || b1.b != b.b || b1.c != b.c || b1.d != b.d || b1.e != b.e {
+		t.Errorf("ValueOf(%v).Interface().(big) = %v", b, b1)
+	}
+}
+
+type Basic struct {
+	x int
+	y float32
+}
+
+type NotBasic Basic
+
+type DeepEqualTest struct {
+	a, b interface{}
+	eq   bool
+}
+
+// Simple functions for DeepEqual tests.
+var (
+	fn1 func()             // nil.
+	fn2 func()             // nil.
+	fn3 = func() { fn1() } // Not nil.
+)
+
+var deepEqualTests = []DeepEqualTest{
+	// Equalities
+	{nil, nil, true},
+	{1, 1, true},
+	{int32(1), int32(1), true},
+	{0.5, 0.5, true},
+	{float32(0.5), float32(0.5), true},
+	{"hello", "hello", true},
+	{make([]int, 10), make([]int, 10), true},
+	{&[3]int{1, 2, 3}, &[3]int{1, 2, 3}, true},
+	{Basic{1, 0.5}, Basic{1, 0.5}, true},
+	{error(nil), error(nil), true},
+	{map[int]string{1: "one", 2: "two"}, map[int]string{2: "two", 1: "one"}, true},
+	{fn1, fn2, true},
+
+	// Inequalities
+	{1, 2, false},
+	{int32(1), int32(2), false},
+	{0.5, 0.6, false},
+	{float32(0.5), float32(0.6), false},
+	{"hello", "hey", false},
+	{make([]int, 10), make([]int, 11), false},
+	{&[3]int{1, 2, 3}, &[3]int{1, 2, 4}, false},
+	{Basic{1, 0.5}, Basic{1, 0.6}, false},
+	{Basic{1, 0}, Basic{2, 0}, false},
+	{map[int]string{1: "one", 3: "two"}, map[int]string{2: "two", 1: "one"}, false},
+	{map[int]string{1: "one", 2: "txo"}, map[int]string{2: "two", 1: "one"}, false},
+	{map[int]string{1: "one"}, map[int]string{2: "two", 1: "one"}, false},
+	{map[int]string{2: "two", 1: "one"}, map[int]string{1: "one"}, false},
+	{nil, 1, false},
+	{1, nil, false},
+	{fn1, fn3, false},
+	{fn3, fn3, false},
+	{[][]int{{1}}, [][]int{{2}}, false},
+
+	// Nil vs empty: not the same.
+	{[]int{}, []int(nil), false},
+	{[]int{}, []int{}, true},
+	{[]int(nil), []int(nil), true},
+	{map[int]int{}, map[int]int(nil), false},
+	{map[int]int{}, map[int]int{}, true},
+	{map[int]int(nil), map[int]int(nil), true},
+
+	// Mismatched types
+	{1, 1.0, false},
+	{int32(1), int64(1), false},
+	{0.5, "hello", false},
+	{[]int{1, 2, 3}, [3]int{1, 2, 3}, false},
+	{&[3]interface{}{1, 2, 4}, &[3]interface{}{1, 2, "s"}, false},
+	{Basic{1, 0.5}, NotBasic{1, 0.5}, false},
+	{map[uint]string{1: "one", 2: "two"}, map[int]string{2: "two", 1: "one"}, false},
+}
+
+func TestDeepEqual(t *testing.T) {
+	for _, test := range deepEqualTests {
+		if r := DeepEqual(test.a, test.b); r != test.eq {
+			t.Errorf("DeepEqual(%v, %v) = %v, want %v", test.a, test.b, r, test.eq)
+		}
+	}
+}
+
+func TestTypeOf(t *testing.T) {
+	// Special case for nil
+	if typ := TypeOf(nil); typ != nil {
+		t.Errorf("expected nil type for nil value; got %v", typ)
+	}
+	for _, test := range deepEqualTests {
+		v := ValueOf(test.a)
+		if !v.IsValid() {
+			continue
+		}
+		typ := TypeOf(test.a)
+		if typ != v.Type() {
+			t.Errorf("TypeOf(%v) = %v, but ValueOf(%v).Type() = %v", test.a, typ, test.a, v.Type())
+		}
+	}
+}
+
+type Recursive struct {
+	x int
+	r *Recursive
+}
+
+func TestDeepEqualRecursiveStruct(t *testing.T) {
+	a, b := new(Recursive), new(Recursive)
+	*a = Recursive{12, a}
+	*b = Recursive{12, b}
+	if !DeepEqual(a, b) {
+		t.Error("DeepEqual(recursive same) = false, want true")
+	}
+}
+
+type _Complex struct {
+	a int
+	b [3]*_Complex
+	c *string
+	d map[float64]float64
+}
+
+func TestDeepEqualComplexStruct(t *testing.T) {
+	m := make(map[float64]float64)
+	stra, strb := "hello", "hello"
+	a, b := new(_Complex), new(_Complex)
+	*a = _Complex{5, [3]*_Complex{a, b, a}, &stra, m}
+	*b = _Complex{5, [3]*_Complex{b, a, a}, &strb, m}
+	if !DeepEqual(a, b) {
+		t.Error("DeepEqual(complex same) = false, want true")
+	}
+}
+
+func TestDeepEqualComplexStructInequality(t *testing.T) {
+	m := make(map[float64]float64)
+	stra, strb := "hello", "helloo" // Difference is here
+	a, b := new(_Complex), new(_Complex)
+	*a = _Complex{5, [3]*_Complex{a, b, a}, &stra, m}
+	*b = _Complex{5, [3]*_Complex{b, a, a}, &strb, m}
+	if DeepEqual(a, b) {
+		t.Error("DeepEqual(complex different) = true, want false")
+	}
+}
+
+type UnexpT struct {
+	m map[int]int
+}
+
+func TestDeepEqualUnexportedMap(t *testing.T) {
+	// Check that DeepEqual can look at unexported fields.
+	x1 := UnexpT{map[int]int{1: 2}}
+	x2 := UnexpT{map[int]int{1: 2}}
+	if !DeepEqual(&x1, &x2) {
+		t.Error("DeepEqual(x1, x2) = false, want true")
+	}
+
+	y1 := UnexpT{map[int]int{2: 3}}
+	if DeepEqual(&x1, &y1) {
+		t.Error("DeepEqual(x1, y1) = true, want false")
+	}
+}
+
+func check2ndField(x interface{}, offs uintptr, t *testing.T) {
+	s := ValueOf(x)
+	f := s.Type().Field(1)
+	if f.Offset != offs {
+		t.Error("mismatched offsets in structure alignment:", f.Offset, offs)
+	}
+}
+
+// Check that structure alignment & offsets viewed through reflect agree with those
+// from the compiler itself.
+func TestAlignment(t *testing.T) {
+	type T1inner struct {
+		a int
+	}
+	type T1 struct {
+		T1inner
+		f int
+	}
+	type T2inner struct {
+		a, b int
+	}
+	type T2 struct {
+		T2inner
+		f int
+	}
+
+	x := T1{T1inner{2}, 17}
+	check2ndField(x, uintptr(unsafe.Pointer(&x.f))-uintptr(unsafe.Pointer(&x)), t)
+
+	x1 := T2{T2inner{2, 3}, 17}
+	check2ndField(x1, uintptr(unsafe.Pointer(&x1.f))-uintptr(unsafe.Pointer(&x1)), t)
+}
+
+func Nil(a interface{}, t *testing.T) {
+	n := ValueOf(a).Field(0)
+	if !n.IsNil() {
+		t.Errorf("%v should be nil", a)
+	}
+}
+
+func NotNil(a interface{}, t *testing.T) {
+	n := ValueOf(a).Field(0)
+	if n.IsNil() {
+		t.Errorf("value of type %v should not be nil", ValueOf(a).Type().String())
+	}
+}
+
+func TestIsNil(t *testing.T) {
+	// These implement IsNil.
+	// Wrap in extra struct to hide interface type.
+	doNil := []interface{}{
+		struct{ x *int }{},
+		struct{ x interface{} }{},
+		struct{ x map[string]int }{},
+		struct{ x func() bool }{},
+		struct{ x chan int }{},
+		struct{ x []string }{},
+	}
+	for _, ts := range doNil {
+		ty := TypeOf(ts).Field(0).Type
+		v := Zero(ty)
+		v.IsNil() // panics if not okay to call
+	}
+
+	// Check the implementations
+	var pi struct {
+		x *int
+	}
+	Nil(pi, t)
+	pi.x = new(int)
+	NotNil(pi, t)
+
+	var si struct {
+		x []int
+	}
+	Nil(si, t)
+	si.x = make([]int, 10)
+	NotNil(si, t)
+
+	var ci struct {
+		x chan int
+	}
+	Nil(ci, t)
+	ci.x = make(chan int)
+	NotNil(ci, t)
+
+	var mi struct {
+		x map[int]int
+	}
+	Nil(mi, t)
+	mi.x = make(map[int]int)
+	NotNil(mi, t)
+
+	var ii struct {
+		x interface{}
+	}
+	Nil(ii, t)
+	ii.x = 2
+	NotNil(ii, t)
+
+	var fi struct {
+		x func(t *testing.T)
+	}
+	Nil(fi, t)
+	fi.x = TestIsNil
+	NotNil(fi, t)
+}
+
+func TestInterfaceExtraction(t *testing.T) {
+	var s struct {
+		W io.Writer
+	}
+
+	s.W = os.Stdout
+	v := Indirect(ValueOf(&s)).Field(0).Interface()
+	if v != s.W.(interface{}) {
+		t.Error("Interface() on interface: ", v, s.W)
+	}
+}
+
+func TestNilPtrValueSub(t *testing.T) {
+	var pi *int
+	if pv := ValueOf(pi); pv.Elem().IsValid() {
+		t.Error("ValueOf((*int)(nil)).Elem().IsValid()")
+	}
+}
+
+func TestMap(t *testing.T) {
+	m := map[string]int{"a": 1, "b": 2}
+	mv := ValueOf(m)
+	if n := mv.Len(); n != len(m) {
+		t.Errorf("Len = %d, want %d", n, len(m))
+	}
+	keys := mv.MapKeys()
+	newmap := MakeMap(mv.Type())
+	for k, v := range m {
+		// Check that returned Keys match keys in range.
+		// These aren't required to be in the same order.
+		seen := false
+		for _, kv := range keys {
+			if kv.String() == k {
+				seen = true
+				break
+			}
+		}
+		if !seen {
+			t.Errorf("Missing key %q", k)
+		}
+
+		// Check that value lookup is correct.
+		vv := mv.MapIndex(ValueOf(k))
+		if vi := vv.Int(); vi != int64(v) {
+			t.Errorf("Key %q: have value %d, want %d", k, vi, v)
+		}
+
+		// Copy into new map.
+		newmap.SetMapIndex(ValueOf(k), ValueOf(v))
+	}
+	vv := mv.MapIndex(ValueOf("not-present"))
+	if vv.IsValid() {
+		t.Errorf("Invalid key: got non-nil value %s", valueToString(vv))
+	}
+
+	newm := newmap.Interface().(map[string]int)
+	if len(newm) != len(m) {
+		t.Errorf("length after copy: newm=%d, m=%d", len(newm), len(m))
+	}
+
+	for k, v := range newm {
+		mv, ok := m[k]
+		if mv != v {
+			t.Errorf("newm[%q] = %d, but m[%q] = %d, %v", k, v, k, mv, ok)
+		}
+	}
+
+	newmap.SetMapIndex(ValueOf("a"), Value{})
+	v, ok := newm["a"]
+	if ok {
+		t.Errorf("newm[\"a\"] = %d after delete", v)
+	}
+
+	mv = ValueOf(&m).Elem()
+	mv.Set(Zero(mv.Type()))
+	if m != nil {
+		t.Errorf("mv.Set(nil) failed")
+	}
+}
+
+func TestNilMap(t *testing.T) {
+	var m map[string]int
+	mv := ValueOf(m)
+	keys := mv.MapKeys()
+	if len(keys) != 0 {
+		t.Errorf(">0 keys for nil map: %v", keys)
+	}
+
+	// Check that value for missing key is zero.
+	x := mv.MapIndex(ValueOf("hello"))
+	if x.Kind() != Invalid {
+		t.Errorf("m.MapIndex(\"hello\") for nil map = %v, want Invalid Value", x)
+	}
+
+	// Check big value too.
+	var mbig map[string][10 << 20]byte
+	x = ValueOf(mbig).MapIndex(ValueOf("hello"))
+	if x.Kind() != Invalid {
+		t.Errorf("mbig.MapIndex(\"hello\") for nil map = %v, want Invalid Value", x)
+	}
+
+	// Test that deletes from a nil map succeed.
+	mv.SetMapIndex(ValueOf("hi"), Value{})
+}
+
+func TestChan(t *testing.T) {
+	for loop := 0; loop < 2; loop++ {
+		var c chan int
+		var cv Value
+
+		// check both ways to allocate channels
+		switch loop {
+		case 1:
+			c = make(chan int, 1)
+			cv = ValueOf(c)
+		case 0:
+			cv = MakeChan(TypeOf(c), 1)
+			c = cv.Interface().(chan int)
+		}
+
+		// Send
+		cv.Send(ValueOf(2))
+		if i := <-c; i != 2 {
+			t.Errorf("reflect Send 2, native recv %d", i)
+		}
+
+		// Recv
+		c <- 3
+		if i, ok := cv.Recv(); i.Int() != 3 || !ok {
+			t.Errorf("native send 3, reflect Recv %d, %t", i.Int(), ok)
+		}
+
+		// TryRecv fail
+		val, ok := cv.TryRecv()
+		if val.IsValid() || ok {
+			t.Errorf("TryRecv on empty chan: %s, %t", valueToString(val), ok)
+		}
+
+		// TryRecv success
+		c <- 4
+		val, ok = cv.TryRecv()
+		if !val.IsValid() {
+			t.Errorf("TryRecv on ready chan got nil")
+		} else if i := val.Int(); i != 4 || !ok {
+			t.Errorf("native send 4, TryRecv %d, %t", i, ok)
+		}
+
+		// TrySend fail
+		c <- 100
+		ok = cv.TrySend(ValueOf(5))
+		i := <-c
+		if ok {
+			t.Errorf("TrySend on full chan succeeded: value %d", i)
+		}
+
+		// TrySend success
+		ok = cv.TrySend(ValueOf(6))
+		if !ok {
+			t.Errorf("TrySend on empty chan failed")
+		} else {
+			if i = <-c; i != 6 {
+				t.Errorf("TrySend 6, recv %d", i)
+			}
+		}
+
+		// Close
+		c <- 123
+		cv.Close()
+		if i, ok := cv.Recv(); i.Int() != 123 || !ok {
+			t.Errorf("send 123 then close; Recv %d, %t", i.Int(), ok)
+		}
+		if i, ok := cv.Recv(); i.Int() != 0 || ok {
+			t.Errorf("after close Recv %d, %t", i.Int(), ok)
+		}
+	}
+
+	// check creation of unbuffered channel
+	var c chan int
+	cv := MakeChan(TypeOf(c), 0)
+	c = cv.Interface().(chan int)
+	if cv.TrySend(ValueOf(7)) {
+		t.Errorf("TrySend on sync chan succeeded")
+	}
+	if v, ok := cv.TryRecv(); v.IsValid() || ok {
+		t.Errorf("TryRecv on sync chan succeeded: isvalid=%v ok=%v", v.IsValid(), ok)
+	}
+
+	// len/cap
+	cv = MakeChan(TypeOf(c), 10)
+	c = cv.Interface().(chan int)
+	for i := 0; i < 3; i++ {
+		c <- i
+	}
+	if l, m := cv.Len(), cv.Cap(); l != len(c) || m != cap(c) {
+		t.Errorf("Len/Cap = %d/%d want %d/%d", l, m, len(c), cap(c))
+	}
+}
+
+// caseInfo describes a single case in a select test.
+type caseInfo struct {
+	desc      string
+	canSelect bool
+	recv      Value
+	closed    bool
+	helper    func()
+	panic     bool
+}
+
+var allselect = flag.Bool("allselect", false, "exhaustive select test")
+
+func TestSelect(t *testing.T) {
+	selectWatch.once.Do(func() { go selectWatcher() })
+
+	var x exhaustive
+	nch := 0
+	newop := func(n int, cap int) (ch, val Value) {
+		nch++
+		if nch%101%2 == 1 {
+			c := make(chan int, cap)
+			ch = ValueOf(c)
+			val = ValueOf(n)
+		} else {
+			c := make(chan string, cap)
+			ch = ValueOf(c)
+			val = ValueOf(fmt.Sprint(n))
+		}
+		return
+	}
+
+	for n := 0; x.Next(); n++ {
+		if testing.Short() && n >= 1000 {
+			break
+		}
+		if n >= 100000 && !*allselect {
+			break
+		}
+		if n%100000 == 0 && testing.Verbose() {
+			println("TestSelect", n)
+		}
+		var cases []SelectCase
+		var info []caseInfo
+
+		// Ready send.
+		if x.Maybe() {
+			ch, val := newop(len(cases), 1)
+			cases = append(cases, SelectCase{
+				Dir:  SelectSend,
+				Chan: ch,
+				Send: val,
+			})
+			info = append(info, caseInfo{desc: "ready send", canSelect: true})
+		}
+
+		// Ready recv.
+		if x.Maybe() {
+			ch, val := newop(len(cases), 1)
+			ch.Send(val)
+			cases = append(cases, SelectCase{
+				Dir:  SelectRecv,
+				Chan: ch,
+			})
+			info = append(info, caseInfo{desc: "ready recv", canSelect: true, recv: val})
+		}
+
+		// Blocking send.
+		if x.Maybe() {
+			ch, val := newop(len(cases), 0)
+			cases = append(cases, SelectCase{
+				Dir:  SelectSend,
+				Chan: ch,
+				Send: val,
+			})
+			// Let it execute?
+			if x.Maybe() {
+				f := func() { ch.Recv() }
+				info = append(info, caseInfo{desc: "blocking send", helper: f})
+			} else {
+				info = append(info, caseInfo{desc: "blocking send"})
+			}
+		}
+
+		// Blocking recv.
+		if x.Maybe() {
+			ch, val := newop(len(cases), 0)
+			cases = append(cases, SelectCase{
+				Dir:  SelectRecv,
+				Chan: ch,
+			})
+			// Let it execute?
+			if x.Maybe() {
+				f := func() { ch.Send(val) }
+				info = append(info, caseInfo{desc: "blocking recv", recv: val, helper: f})
+			} else {
+				info = append(info, caseInfo{desc: "blocking recv"})
+			}
+		}
+
+		// Zero Chan send.
+		if x.Maybe() {
+			// Maybe include value to send.
+			var val Value
+			if x.Maybe() {
+				val = ValueOf(100)
+			}
+			cases = append(cases, SelectCase{
+				Dir:  SelectSend,
+				Send: val,
+			})
+			info = append(info, caseInfo{desc: "zero Chan send"})
+		}
+
+		// Zero Chan receive.
+		if x.Maybe() {
+			cases = append(cases, SelectCase{
+				Dir: SelectRecv,
+			})
+			info = append(info, caseInfo{desc: "zero Chan recv"})
+		}
+
+		// nil Chan send.
+		if x.Maybe() {
+			cases = append(cases, SelectCase{
+				Dir:  SelectSend,
+				Chan: ValueOf((chan int)(nil)),
+				Send: ValueOf(101),
+			})
+			info = append(info, caseInfo{desc: "nil Chan send"})
+		}
+
+		// nil Chan recv.
+		if x.Maybe() {
+			cases = append(cases, SelectCase{
+				Dir:  SelectRecv,
+				Chan: ValueOf((chan int)(nil)),
+			})
+			info = append(info, caseInfo{desc: "nil Chan recv"})
+		}
+
+		// closed Chan send.
+		if x.Maybe() {
+			ch := make(chan int)
+			close(ch)
+			cases = append(cases, SelectCase{
+				Dir:  SelectSend,
+				Chan: ValueOf(ch),
+				Send: ValueOf(101),
+			})
+			info = append(info, caseInfo{desc: "closed Chan send", canSelect: true, panic: true})
+		}
+
+		// closed Chan recv.
+		if x.Maybe() {
+			ch, val := newop(len(cases), 0)
+			ch.Close()
+			val = Zero(val.Type())
+			cases = append(cases, SelectCase{
+				Dir:  SelectRecv,
+				Chan: ch,
+			})
+			info = append(info, caseInfo{desc: "closed Chan recv", canSelect: true, closed: true, recv: val})
+		}
+
+		var helper func() // goroutine to help the select complete
+
+		// Add default? Must be last case here, but will permute.
+		// Add the default if the select would otherwise
+		// block forever, and maybe add it anyway.
+		numCanSelect := 0
+		canProceed := false
+		canBlock := true
+		canPanic := false
+		helpers := []int{}
+		for i, c := range info {
+			if c.canSelect {
+				canProceed = true
+				canBlock = false
+				numCanSelect++
+				if c.panic {
+					canPanic = true
+				}
+			} else if c.helper != nil {
+				canProceed = true
+				helpers = append(helpers, i)
+			}
+		}
+		if !canProceed || x.Maybe() {
+			cases = append(cases, SelectCase{
+				Dir: SelectDefault,
+			})
+			info = append(info, caseInfo{desc: "default", canSelect: canBlock})
+			numCanSelect++
+		} else if canBlock {
+			// Select needs to communicate with another goroutine.
+			cas := &info[helpers[x.Choose(len(helpers))]]
+			helper = cas.helper
+			cas.canSelect = true
+			numCanSelect++
+		}
+
+		// Permute cases and case info.
+		// Doing too much here makes the exhaustive loop
+		// too exhausting, so just do two swaps.
+		for loop := 0; loop < 2; loop++ {
+			i := x.Choose(len(cases))
+			j := x.Choose(len(cases))
+			cases[i], cases[j] = cases[j], cases[i]
+			info[i], info[j] = info[j], info[i]
+		}
+
+		if helper != nil {
+			// We wait before kicking off a goroutine to satisfy a blocked select.
+			// The pause needs to be big enough to let the select block before
+			// we run the helper, but if we lose that race once in a while it's okay: the
+			// select will just proceed immediately. Not a big deal.
+			// For short tests we can grow [sic] the timeout a bit without fear of taking too long
+			pause := 10 * time.Microsecond
+			if testing.Short() {
+				pause = 100 * time.Microsecond
+			}
+			time.AfterFunc(pause, helper)
+		}
+
+		// Run select.
+		i, recv, recvOK, panicErr := runSelect(cases, info)
+		if panicErr != nil && !canPanic {
+			t.Fatalf("%s\npanicked unexpectedly: %v", fmtSelect(info), panicErr)
+		}
+		if panicErr == nil && canPanic && numCanSelect == 1 {
+			t.Fatalf("%s\nselected #%d incorrectly (should panic)", fmtSelect(info), i)
+		}
+		if panicErr != nil {
+			continue
+		}
+
+		cas := info[i]
+		if !cas.canSelect {
+			recvStr := ""
+			if recv.IsValid() {
+				recvStr = fmt.Sprintf(", received %v, %v", recv.Interface(), recvOK)
+			}
+			t.Fatalf("%s\nselected #%d incorrectly%s", fmtSelect(info), i, recvStr)
+			continue
+		}
+		if cas.panic {
+			t.Fatalf("%s\nselected #%d incorrectly (case should panic)", fmtSelect(info), i)
+			continue
+		}
+
+		if cases[i].Dir == SelectRecv {
+			if !recv.IsValid() {
+				t.Fatalf("%s\nselected #%d but got %v, %v, want %v, %v", fmtSelect(info), i, recv, recvOK, cas.recv.Interface(), !cas.closed)
+			}
+			if !cas.recv.IsValid() {
+				t.Fatalf("%s\nselected #%d but internal error: missing recv value", fmtSelect(info), i)
+			}
+			if recv.Interface() != cas.recv.Interface() || recvOK != !cas.closed {
+				if recv.Interface() == cas.recv.Interface() && recvOK == !cas.closed {
+					t.Fatalf("%s\nselected #%d, got %#v, %v, and DeepEqual is broken on %T", fmtSelect(info), i, recv.Interface(), recvOK, recv.Interface())
+				}
+				t.Fatalf("%s\nselected #%d but got %#v, %v, want %#v, %v", fmtSelect(info), i, recv.Interface(), recvOK, cas.recv.Interface(), !cas.closed)
+			}
+		} else {
+			if recv.IsValid() || recvOK {
+				t.Fatalf("%s\nselected #%d but got %v, %v, want %v, %v", fmtSelect(info), i, recv, recvOK, Value{}, false)
+			}
+		}
+	}
+}
+
+// selectWatch and the selectWatcher are a watchdog mechanism for running Select.
+// If the selectWatcher notices that the select has been blocked for >1 second, it prints
+// an error describing the select and panics the entire test binary.
+var selectWatch struct {
+	sync.Mutex
+	once sync.Once
+	now  time.Time
+	info []caseInfo
+}
+
+func selectWatcher() {
+	for {
+		time.Sleep(1 * time.Second)
+		selectWatch.Lock()
+		if selectWatch.info != nil && time.Since(selectWatch.now) > 1*time.Second {
+			fmt.Fprintf(os.Stderr, "TestSelect:\n%s blocked indefinitely\n", fmtSelect(selectWatch.info))
+			panic("select stuck")
+		}
+		selectWatch.Unlock()
+	}
+}
+
+// runSelect runs a single select test.
+// It returns the values returned by Select but also returns
+// a panic value if the Select panics.
+func runSelect(cases []SelectCase, info []caseInfo) (chosen int, recv Value, recvOK bool, panicErr interface{}) {
+	defer func() {
+		panicErr = recover()
+
+		selectWatch.Lock()
+		selectWatch.info = nil
+		selectWatch.Unlock()
+	}()
+
+	selectWatch.Lock()
+	selectWatch.now = time.Now()
+	selectWatch.info = info
+	selectWatch.Unlock()
+
+	chosen, recv, recvOK = Select(cases)
+	return
+}
+
+// fmtSelect formats the information about a single select test.
+func fmtSelect(info []caseInfo) string {
+	var buf bytes.Buffer
+	fmt.Fprintf(&buf, "\nselect {\n")
+	for i, cas := range info {
+		fmt.Fprintf(&buf, "%d: %s", i, cas.desc)
+		if cas.recv.IsValid() {
+			fmt.Fprintf(&buf, " val=%#v", cas.recv.Interface())
+		}
+		if cas.canSelect {
+			fmt.Fprintf(&buf, " canselect")
+		}
+		if cas.panic {
+			fmt.Fprintf(&buf, " panic")
+		}
+		fmt.Fprintf(&buf, "\n")
+	}
+	fmt.Fprintf(&buf, "}")
+	return buf.String()
+}
+
+type two [2]uintptr
+
+// Difficult test for function call because of
+// implicit padding between arguments.
+func dummy(b byte, c int, d byte, e two, f byte, g float32, h byte) (i byte, j int, k byte, l two, m byte, n float32, o byte) {
+	return b, c, d, e, f, g, h
+}
+
+func TestFunc(t *testing.T) {
+	ret := ValueOf(dummy).Call([]Value{
+		ValueOf(byte(10)),
+		ValueOf(20),
+		ValueOf(byte(30)),
+		ValueOf(two{40, 50}),
+		ValueOf(byte(60)),
+		ValueOf(float32(70)),
+		ValueOf(byte(80)),
+	})
+	if len(ret) != 7 {
+		t.Fatalf("Call returned %d values, want 7", len(ret))
+	}
+
+	i := byte(ret[0].Uint())
+	j := int(ret[1].Int())
+	k := byte(ret[2].Uint())
+	l := ret[3].Interface().(two)
+	m := byte(ret[4].Uint())
+	n := float32(ret[5].Float())
+	o := byte(ret[6].Uint())
+
+	if i != 10 || j != 20 || k != 30 || l != (two{40, 50}) || m != 60 || n != 70 || o != 80 {
+		t.Errorf("Call returned %d, %d, %d, %v, %d, %g, %d; want 10, 20, 30, [40, 50], 60, 70, 80", i, j, k, l, m, n, o)
+	}
+}
+
+type emptyStruct struct{}
+
+type nonEmptyStruct struct {
+	member int
+}
+
+func returnEmpty() emptyStruct {
+	return emptyStruct{}
+}
+
+func takesEmpty(e emptyStruct) {
+}
+
+func returnNonEmpty(i int) nonEmptyStruct {
+	return nonEmptyStruct{member: i}
+}
+
+func takesNonEmpty(n nonEmptyStruct) int {
+	return n.member
+}
+
+func TestCallWithStruct(t *testing.T) {
+	r := ValueOf(returnEmpty).Call(nil)
+	if len(r) != 1 || r[0].Type() != TypeOf(emptyStruct{}) {
+		t.Errorf("returning empty struct returned %#v instead", r)
+	}
+	r = ValueOf(takesEmpty).Call([]Value{ValueOf(emptyStruct{})})
+	if len(r) != 0 {
+		t.Errorf("takesEmpty returned values: %#v", r)
+	}
+	r = ValueOf(returnNonEmpty).Call([]Value{ValueOf(42)})
+	if len(r) != 1 || r[0].Type() != TypeOf(nonEmptyStruct{}) || r[0].Field(0).Int() != 42 {
+		t.Errorf("returnNonEmpty returned %#v", r)
+	}
+	r = ValueOf(takesNonEmpty).Call([]Value{ValueOf(nonEmptyStruct{member: 42})})
+	if len(r) != 1 || r[0].Type() != TypeOf(1) || r[0].Int() != 42 {
+		t.Errorf("takesNonEmpty returned %#v", r)
+	}
+}
+
+func TestMakeFunc(t *testing.T) {
+	f := dummy
+	fv := MakeFunc(TypeOf(f), func(in []Value) []Value { return in })
+	ValueOf(&f).Elem().Set(fv)
+
+	// Call g with small arguments so that there is
+	// something predictable (and different from the
+	// correct results) in those positions on the stack.
+	g := dummy
+	g(1, 2, 3, two{4, 5}, 6, 7, 8)
+
+	// Call constructed function f.
+	i, j, k, l, m, n, o := f(10, 20, 30, two{40, 50}, 60, 70, 80)
+	if i != 10 || j != 20 || k != 30 || l != (two{40, 50}) || m != 60 || n != 70 || o != 80 {
+		t.Errorf("Call returned %d, %d, %d, %v, %d, %g, %d; want 10, 20, 30, [40, 50], 60, 70, 80", i, j, k, l, m, n, o)
+	}
+}
+
+func TestMakeFuncInterface(t *testing.T) {
+	fn := func(i int) int { return i }
+	incr := func(in []Value) []Value {
+		return []Value{ValueOf(int(in[0].Int() + 1))}
+	}
+	fv := MakeFunc(TypeOf(fn), incr)
+	ValueOf(&fn).Elem().Set(fv)
+	if r := fn(2); r != 3 {
+		t.Errorf("Call returned %d, want 3", r)
+	}
+	if r := fv.Call([]Value{ValueOf(14)})[0].Int(); r != 15 {
+		t.Errorf("Call returned %d, want 15", r)
+	}
+	if r := fv.Interface().(func(int) int)(26); r != 27 {
+		t.Errorf("Call returned %d, want 27", r)
+	}
+}
+
+func TestMakeFuncVariadic(t *testing.T) {
+	// Test that variadic arguments are packed into a slice and passed as last arg
+	fn := func(_ int, is ...int) []int { return nil }
+	fv := MakeFunc(TypeOf(fn), func(in []Value) []Value { return in[1:2] })
+	ValueOf(&fn).Elem().Set(fv)
+
+	r := fn(1, 2, 3)
+	if r[0] != 2 || r[1] != 3 {
+		t.Errorf("Call returned [%v, %v]; want 2, 3", r[0], r[1])
+	}
+
+	r = fn(1, []int{2, 3}...)
+	if r[0] != 2 || r[1] != 3 {
+		t.Errorf("Call returned [%v, %v]; want 2, 3", r[0], r[1])
+	}
+
+	r = fv.Call([]Value{ValueOf(1), ValueOf(2), ValueOf(3)})[0].Interface().([]int)
+	if r[0] != 2 || r[1] != 3 {
+		t.Errorf("Call returned [%v, %v]; want 2, 3", r[0], r[1])
+	}
+
+	r = fv.CallSlice([]Value{ValueOf(1), ValueOf([]int{2, 3})})[0].Interface().([]int)
+	if r[0] != 2 || r[1] != 3 {
+		t.Errorf("Call returned [%v, %v]; want 2, 3", r[0], r[1])
+	}
+
+	f := fv.Interface().(func(int, ...int) []int)
+
+	r = f(1, 2, 3)
+	if r[0] != 2 || r[1] != 3 {
+		t.Errorf("Call returned [%v, %v]; want 2, 3", r[0], r[1])
+	}
+	r = f(1, []int{2, 3}...)
+	if r[0] != 2 || r[1] != 3 {
+		t.Errorf("Call returned [%v, %v]; want 2, 3", r[0], r[1])
+	}
+}
+
+type Point struct {
+	x, y int
+}
+
+// This will be index 0.
+func (p Point) AnotherMethod(scale int) int {
+	return -1
+}
+
+// This will be index 1.
+func (p Point) Dist(scale int) int {
+	//println("Point.Dist", p.x, p.y, scale)
+	return p.x*p.x*scale + p.y*p.y*scale
+}
+
+// This will be index 2.
+func (p Point) GCMethod(k int) int {
+	runtime.GC()
+	return k + p.x
+}
+
+// This will be index 3.
+func (p Point) TotalDist(points ...Point) int {
+	tot := 0
+	for _, q := range points {
+		dx := q.x - p.x
+		dy := q.y - p.y
+		tot += dx*dx + dy*dy // Should call Sqrt, but it's just a test.
+
+	}
+	return tot
+}
+
+func TestMethod(t *testing.T) {
+	// Non-curried method of type.
+	p := Point{3, 4}
+	i := TypeOf(p).Method(1).Func.Call([]Value{ValueOf(p), ValueOf(10)})[0].Int()
+	if i != 250 {
+		t.Errorf("Type Method returned %d; want 250", i)
+	}
+
+	m, ok := TypeOf(p).MethodByName("Dist")
+	if !ok {
+		t.Fatalf("method by name failed")
+	}
+	i = m.Func.Call([]Value{ValueOf(p), ValueOf(11)})[0].Int()
+	if i != 275 {
+		t.Errorf("Type MethodByName returned %d; want 275", i)
+	}
+
+	i = TypeOf(&p).Method(1).Func.Call([]Value{ValueOf(&p), ValueOf(12)})[0].Int()
+	if i != 300 {
+		t.Errorf("Pointer Type Method returned %d; want 300", i)
+	}
+
+	m, ok = TypeOf(&p).MethodByName("Dist")
+	if !ok {
+		t.Fatalf("ptr method by name failed")
+	}
+	i = m.Func.Call([]Value{ValueOf(&p), ValueOf(13)})[0].Int()
+	if i != 325 {
+		t.Errorf("Pointer Type MethodByName returned %d; want 325", i)
+	}
+
+	// Curried method of value.
+	tfunc := TypeOf((func(int) int)(nil))
+	v := ValueOf(p).Method(1)
+	if tt := v.Type(); tt != tfunc {
+		t.Errorf("Value Method Type is %s; want %s", tt, tfunc)
+	}
+	i = v.Call([]Value{ValueOf(14)})[0].Int()
+	if i != 350 {
+		t.Errorf("Value Method returned %d; want 350", i)
+	}
+	v = ValueOf(p).MethodByName("Dist")
+	if tt := v.Type(); tt != tfunc {
+		t.Errorf("Value MethodByName Type is %s; want %s", tt, tfunc)
+	}
+	i = v.Call([]Value{ValueOf(15)})[0].Int()
+	if i != 375 {
+		t.Errorf("Value MethodByName returned %d; want 375", i)
+	}
+
+	// Curried method of pointer.
+	v = ValueOf(&p).Method(1)
+	if tt := v.Type(); tt != tfunc {
+		t.Errorf("Pointer Value Method Type is %s; want %s", tt, tfunc)
+	}
+	i = v.Call([]Value{ValueOf(16)})[0].Int()
+	if i != 400 {
+		t.Errorf("Pointer Value Method returned %d; want 400", i)
+	}
+	v = ValueOf(&p).MethodByName("Dist")
+	if tt := v.Type(); tt != tfunc {
+		t.Errorf("Pointer Value MethodByName Type is %s; want %s", tt, tfunc)
+	}
+	i = v.Call([]Value{ValueOf(17)})[0].Int()
+	if i != 425 {
+		t.Errorf("Pointer Value MethodByName returned %d; want 425", i)
+	}
+
+	// Curried method of interface value.
+	// Have to wrap interface value in a struct to get at it.
+	// Passing it to ValueOf directly would
+	// access the underlying Point, not the interface.
+	var x interface {
+		Dist(int) int
+	} = p
+	pv := ValueOf(&x).Elem()
+	v = pv.Method(0)
+	if tt := v.Type(); tt != tfunc {
+		t.Errorf("Interface Method Type is %s; want %s", tt, tfunc)
+	}
+	i = v.Call([]Value{ValueOf(18)})[0].Int()
+	if i != 450 {
+		t.Errorf("Interface Method returned %d; want 450", i)
+	}
+	v = pv.MethodByName("Dist")
+	if tt := v.Type(); tt != tfunc {
+		t.Errorf("Interface MethodByName Type is %s; want %s", tt, tfunc)
+	}
+	i = v.Call([]Value{ValueOf(19)})[0].Int()
+	if i != 475 {
+		t.Errorf("Interface MethodByName returned %d; want 475", i)
+	}
+}
+
+func TestMethodValue(t *testing.T) {
+	p := Point{3, 4}
+	var i int64
+
+	// Curried method of value.
+	tfunc := TypeOf((func(int) int)(nil))
+	v := ValueOf(p).Method(1)
+	if tt := v.Type(); tt != tfunc {
+		t.Errorf("Value Method Type is %s; want %s", tt, tfunc)
+	}
+	i = ValueOf(v.Interface()).Call([]Value{ValueOf(10)})[0].Int()
+	if i != 250 {
+		t.Errorf("Value Method returned %d; want 250", i)
+	}
+	v = ValueOf(p).MethodByName("Dist")
+	if tt := v.Type(); tt != tfunc {
+		t.Errorf("Value MethodByName Type is %s; want %s", tt, tfunc)
+	}
+	i = ValueOf(v.Interface()).Call([]Value{ValueOf(11)})[0].Int()
+	if i != 275 {
+		t.Errorf("Value MethodByName returned %d; want 275", i)
+	}
+
+	// Curried method of pointer.
+	v = ValueOf(&p).Method(1)
+	if tt := v.Type(); tt != tfunc {
+		t.Errorf("Pointer Value Method Type is %s; want %s", tt, tfunc)
+	}
+	i = ValueOf(v.Interface()).Call([]Value{ValueOf(12)})[0].Int()
+	if i != 300 {
+		t.Errorf("Pointer Value Method returned %d; want 300", i)
+	}
+	v = ValueOf(&p).MethodByName("Dist")
+	if tt := v.Type(); tt != tfunc {
+		t.Errorf("Pointer Value MethodByName Type is %s; want %s", tt, tfunc)
+	}
+	i = ValueOf(v.Interface()).Call([]Value{ValueOf(13)})[0].Int()
+	if i != 325 {
+		t.Errorf("Pointer Value MethodByName returned %d; want 325", i)
+	}
+
+	// Curried method of pointer to pointer.
+	pp := &p
+	v = ValueOf(&pp).Elem().Method(1)
+	if tt := v.Type(); tt != tfunc {
+		t.Errorf("Pointer Pointer Value Method Type is %s; want %s", tt, tfunc)
+	}
+	i = ValueOf(v.Interface()).Call([]Value{ValueOf(14)})[0].Int()
+	if i != 350 {
+		t.Errorf("Pointer Pointer Value Method returned %d; want 350", i)
+	}
+	v = ValueOf(&pp).Elem().MethodByName("Dist")
+	if tt := v.Type(); tt != tfunc {
+		t.Errorf("Pointer Pointer Value MethodByName Type is %s; want %s", tt, tfunc)
+	}
+	i = ValueOf(v.Interface()).Call([]Value{ValueOf(15)})[0].Int()
+	if i != 375 {
+		t.Errorf("Pointer Pointer Value MethodByName returned %d; want 375", i)
+	}
+
+	// Curried method of interface value.
+	// Have to wrap interface value in a struct to get at it.
+	// Passing it to ValueOf directly would
+	// access the underlying Point, not the interface.
+	var s = struct {
+		X interface {
+			Dist(int) int
+		}
+	}{p}
+	pv := ValueOf(s).Field(0)
+	v = pv.Method(0)
+	if tt := v.Type(); tt != tfunc {
+		t.Errorf("Interface Method Type is %s; want %s", tt, tfunc)
+	}
+	i = ValueOf(v.Interface()).Call([]Value{ValueOf(16)})[0].Int()
+	if i != 400 {
+		t.Errorf("Interface Method returned %d; want 400", i)
+	}
+	v = pv.MethodByName("Dist")
+	if tt := v.Type(); tt != tfunc {
+		t.Errorf("Interface MethodByName Type is %s; want %s", tt, tfunc)
+	}
+	i = ValueOf(v.Interface()).Call([]Value{ValueOf(17)})[0].Int()
+	if i != 425 {
+		t.Errorf("Interface MethodByName returned %d; want 425", i)
+	}
+}
+
+func TestVariadicMethodValue(t *testing.T) {
+	p := Point{3, 4}
+	points := []Point{{20, 21}, {22, 23}, {24, 25}}
+	want := int64(p.TotalDist(points[0], points[1], points[2]))
+
+	// Curried method of value.
+	tfunc := TypeOf((func(...Point) int)(nil))
+	v := ValueOf(p).Method(3)
+	if tt := v.Type(); tt != tfunc {
+		t.Errorf("Variadic Method Type is %s; want %s", tt, tfunc)
+	}
+	i := ValueOf(v.Interface()).Call([]Value{ValueOf(points[0]), ValueOf(points[1]), ValueOf(points[2])})[0].Int()
+	if i != want {
+		t.Errorf("Variadic Method returned %d; want %d", i, want)
+	}
+	i = ValueOf(v.Interface()).CallSlice([]Value{ValueOf(points)})[0].Int()
+	if i != want {
+		t.Errorf("Variadic Method CallSlice returned %d; want %d", i, want)
+	}
+
+	f := v.Interface().(func(...Point) int)
+	i = int64(f(points[0], points[1], points[2]))
+	if i != want {
+		t.Errorf("Variadic Method Interface returned %d; want %d", i, want)
+	}
+	i = int64(f(points...))
+	if i != want {
+		t.Errorf("Variadic Method Interface Slice returned %d; want %d", i, want)
+	}
+}
+
+// Reflect version of $GOROOT/test/method5.go
+
+// Concrete types implementing M method.
+// Smaller than a word, word-sized, larger than a word.
+// Value and pointer receivers.
+
+type Tinter interface {
+	M(int, byte) (byte, int)
+}
+
+type Tsmallv byte
+
+func (v Tsmallv) M(x int, b byte) (byte, int) { return b, x + int(v) }
+
+type Tsmallp byte
+
+func (p *Tsmallp) M(x int, b byte) (byte, int) { return b, x + int(*p) }
+
+type Twordv uintptr
+
+func (v Twordv) M(x int, b byte) (byte, int) { return b, x + int(v) }
+
+type Twordp uintptr
+
+func (p *Twordp) M(x int, b byte) (byte, int) { return b, x + int(*p) }
+
+type Tbigv [2]uintptr
+
+func (v Tbigv) M(x int, b byte) (byte, int) { return b, x + int(v[0]) + int(v[1]) }
+
+type Tbigp [2]uintptr
+
+func (p *Tbigp) M(x int, b byte) (byte, int) { return b, x + int(p[0]) + int(p[1]) }
+
+// Again, with an unexported method.
+
+type tsmallv byte
+
+func (v tsmallv) m(x int, b byte) (byte, int) { return b, x + int(v) }
+
+type tsmallp byte
+
+func (p *tsmallp) m(x int, b byte) (byte, int) { return b, x + int(*p) }
+
+type twordv uintptr
+
+func (v twordv) m(x int, b byte) (byte, int) { return b, x + int(v) }
+
+type twordp uintptr
+
+func (p *twordp) m(x int, b byte) (byte, int) { return b, x + int(*p) }
+
+type tbigv [2]uintptr
+
+func (v tbigv) m(x int, b byte) (byte, int) { return b, x + int(v[0]) + int(v[1]) }
+
+type tbigp [2]uintptr
+
+func (p *tbigp) m(x int, b byte) (byte, int) { return b, x + int(p[0]) + int(p[1]) }
+
+type tinter interface {
+	m(int, byte) (byte, int)
+}
+
+// Embedding via pointer.
+
+type Tm1 struct {
+	Tm2
+}
+
+type Tm2 struct {
+	*Tm3
+}
+
+type Tm3 struct {
+	*Tm4
+}
+
+type Tm4 struct {
+}
+
+func (t4 Tm4) M(x int, b byte) (byte, int) { return b, x + 40 }
+
+func TestMethod5(t *testing.T) {
+	CheckF := func(name string, f func(int, byte) (byte, int), inc int) {
+		b, x := f(1000, 99)
+		if b != 99 || x != 1000+inc {
+			t.Errorf("%s(1000, 99) = %v, %v, want 99, %v", name, b, x, 1000+inc)
+		}
+	}
+
+	CheckV := func(name string, i Value, inc int) {
+		bx := i.Method(0).Call([]Value{ValueOf(1000), ValueOf(byte(99))})
+		b := bx[0].Interface()
+		x := bx[1].Interface()
+		if b != byte(99) || x != 1000+inc {
+			t.Errorf("direct %s.M(1000, 99) = %v, %v, want 99, %v", name, b, x, 1000+inc)
+		}
+
+		CheckF(name+".M", i.Method(0).Interface().(func(int, byte) (byte, int)), inc)
+	}
+
+	var TinterType = TypeOf(new(Tinter)).Elem()
+	var tinterType = TypeOf(new(tinter)).Elem()
+
+	CheckI := func(name string, i interface{}, inc int) {
+		v := ValueOf(i)
+		CheckV(name, v, inc)
+		CheckV("(i="+name+")", v.Convert(TinterType), inc)
+	}
+
+	sv := Tsmallv(1)
+	CheckI("sv", sv, 1)
+	CheckI("&sv", &sv, 1)
+
+	sp := Tsmallp(2)
+	CheckI("&sp", &sp, 2)
+
+	wv := Twordv(3)
+	CheckI("wv", wv, 3)
+	CheckI("&wv", &wv, 3)
+
+	wp := Twordp(4)
+	CheckI("&wp", &wp, 4)
+
+	bv := Tbigv([2]uintptr{5, 6})
+	CheckI("bv", bv, 11)
+	CheckI("&bv", &bv, 11)
+
+	bp := Tbigp([2]uintptr{7, 8})
+	CheckI("&bp", &bp, 15)
+
+	t4 := Tm4{}
+	t3 := Tm3{&t4}
+	t2 := Tm2{&t3}
+	t1 := Tm1{t2}
+	CheckI("t4", t4, 40)
+	CheckI("&t4", &t4, 40)
+	CheckI("t3", t3, 40)
+	CheckI("&t3", &t3, 40)
+	CheckI("t2", t2, 40)
+	CheckI("&t2", &t2, 40)
+	CheckI("t1", t1, 40)
+	CheckI("&t1", &t1, 40)
+
+	methodShouldPanic := func(name string, i interface{}) {
+		v := ValueOf(i)
+		m := v.Method(0)
+		shouldPanic(func() { m.Call([]Value{ValueOf(1000), ValueOf(byte(99))}) })
+		shouldPanic(func() { m.Interface() })
+
+		v = v.Convert(tinterType)
+		m = v.Method(0)
+		shouldPanic(func() { m.Call([]Value{ValueOf(1000), ValueOf(byte(99))}) })
+		shouldPanic(func() { m.Interface() })
+	}
+
+	_sv := tsmallv(1)
+	methodShouldPanic("_sv", _sv)
+	methodShouldPanic("&_sv", &_sv)
+
+	_sp := tsmallp(2)
+	methodShouldPanic("&_sp", &_sp)
+
+	_wv := twordv(3)
+	methodShouldPanic("_wv", _wv)
+	methodShouldPanic("&_wv", &_wv)
+
+	_wp := twordp(4)
+	methodShouldPanic("&_wp", &_wp)
+
+	_bv := tbigv([2]uintptr{5, 6})
+	methodShouldPanic("_bv", _bv)
+	methodShouldPanic("&_bv", &_bv)
+
+	_bp := tbigp([2]uintptr{7, 8})
+	methodShouldPanic("&_bp", &_bp)
+
+	var tnil Tinter
+	vnil := ValueOf(&tnil).Elem()
+	shouldPanic(func() { vnil.Method(0) })
+}
+
+func TestInterfaceSet(t *testing.T) {
+	p := &Point{3, 4}
+
+	var s struct {
+		I interface{}
+		P interface {
+			Dist(int) int
+		}
+	}
+	sv := ValueOf(&s).Elem()
+	sv.Field(0).Set(ValueOf(p))
+	if q := s.I.(*Point); q != p {
+		t.Errorf("i: have %p want %p", q, p)
+	}
+
+	pv := sv.Field(1)
+	pv.Set(ValueOf(p))
+	if q := s.P.(*Point); q != p {
+		t.Errorf("i: have %p want %p", q, p)
+	}
+
+	i := pv.Method(0).Call([]Value{ValueOf(10)})[0].Int()
+	if i != 250 {
+		t.Errorf("Interface Method returned %d; want 250", i)
+	}
+}
+
+type T1 struct {
+	a string
+	int
+}
+
+func TestAnonymousFields(t *testing.T) {
+	var field StructField
+	var ok bool
+	var t1 T1
+	type1 := TypeOf(t1)
+	if field, ok = type1.FieldByName("int"); !ok {
+		t.Fatal("no field 'int'")
+	}
+	if field.Index[0] != 1 {
+		t.Error("field index should be 1; is", field.Index)
+	}
+}
+
+type FTest struct {
+	s     interface{}
+	name  string
+	index []int
+	value int
+}
+
+type D1 struct {
+	d int
+}
+type D2 struct {
+	d int
+}
+
+type S0 struct {
+	A, B, C int
+	D1
+	D2
+}
+
+type S1 struct {
+	B int
+	S0
+}
+
+type S2 struct {
+	A int
+	*S1
+}
+
+type S1x struct {
+	S1
+}
+
+type S1y struct {
+	S1
+}
+
+type S3 struct {
+	S1x
+	S2
+	D, E int
+	*S1y
+}
+
+type S4 struct {
+	*S4
+	A int
+}
+
+// The X in S6 and S7 annihilate, but they also block the X in S8.S9.
+type S5 struct {
+	S6
+	S7
+	S8
+}
+
+type S6 struct {
+	X int
+}
+
+type S7 S6
+
+type S8 struct {
+	S9
+}
+
+type S9 struct {
+	X int
+	Y int
+}
+
+// The X in S11.S6 and S12.S6 annihilate, but they also block the X in S13.S8.S9.
+type S10 struct {
+	S11
+	S12
+	S13
+}
+
+type S11 struct {
+	S6
+}
+
+type S12 struct {
+	S6
+}
+
+type S13 struct {
+	S8
+}
+
+// The X in S15.S11.S1 and S16.S11.S1 annihilate.
+type S14 struct {
+	S15
+	S16
+}
+
+type S15 struct {
+	S11
+}
+
+type S16 struct {
+	S11
+}
+
+var fieldTests = []FTest{
+	{struct{}{}, "", nil, 0},
+	{struct{}{}, "Foo", nil, 0},
+	{S0{A: 'a'}, "A", []int{0}, 'a'},
+	{S0{}, "D", nil, 0},
+	{S1{S0: S0{A: 'a'}}, "A", []int{1, 0}, 'a'},
+	{S1{B: 'b'}, "B", []int{0}, 'b'},
+	{S1{}, "S0", []int{1}, 0},
+	{S1{S0: S0{C: 'c'}}, "C", []int{1, 2}, 'c'},
+	{S2{A: 'a'}, "A", []int{0}, 'a'},
+	{S2{}, "S1", []int{1}, 0},
+	{S2{S1: &S1{B: 'b'}}, "B", []int{1, 0}, 'b'},
+	{S2{S1: &S1{S0: S0{C: 'c'}}}, "C", []int{1, 1, 2}, 'c'},
+	{S2{}, "D", nil, 0},
+	{S3{}, "S1", nil, 0},
+	{S3{S2: S2{A: 'a'}}, "A", []int{1, 0}, 'a'},
+	{S3{}, "B", nil, 0},
+	{S3{D: 'd'}, "D", []int{2}, 0},
+	{S3{E: 'e'}, "E", []int{3}, 'e'},
+	{S4{A: 'a'}, "A", []int{1}, 'a'},
+	{S4{}, "B", nil, 0},
+	{S5{}, "X", nil, 0},
+	{S5{}, "Y", []int{2, 0, 1}, 0},
+	{S10{}, "X", nil, 0},
+	{S10{}, "Y", []int{2, 0, 0, 1}, 0},
+	{S14{}, "X", nil, 0},
+}
+
+func TestFieldByIndex(t *testing.T) {
+	for _, test := range fieldTests {
+		s := TypeOf(test.s)
+		f := s.FieldByIndex(test.index)
+		if f.Name != "" {
+			if test.index != nil {
+				if f.Name != test.name {
+					t.Errorf("%s.%s found; want %s", s.Name(), f.Name, test.name)
+				}
+			} else {
+				t.Errorf("%s.%s found", s.Name(), f.Name)
+			}
+		} else if len(test.index) > 0 {
+			t.Errorf("%s.%s not found", s.Name(), test.name)
+		}
+
+		if test.value != 0 {
+			v := ValueOf(test.s).FieldByIndex(test.index)
+			if v.IsValid() {
+				if x, ok := v.Interface().(int); ok {
+					if x != test.value {
+						t.Errorf("%s%v is %d; want %d", s.Name(), test.index, x, test.value)
+					}
+				} else {
+					t.Errorf("%s%v value not an int", s.Name(), test.index)
+				}
+			} else {
+				t.Errorf("%s%v value not found", s.Name(), test.index)
+			}
+		}
+	}
+}
+
+func TestFieldByName(t *testing.T) {
+	for _, test := range fieldTests {
+		s := TypeOf(test.s)
+		f, found := s.FieldByName(test.name)
+		if found {
+			if test.index != nil {
+				// Verify field depth and index.
+				if len(f.Index) != len(test.index) {
+					t.Errorf("%s.%s depth %d; want %d: %v vs %v", s.Name(), test.name, len(f.Index), len(test.index), f.Index, test.index)
+				} else {
+					for i, x := range f.Index {
+						if x != test.index[i] {
+							t.Errorf("%s.%s.Index[%d] is %d; want %d", s.Name(), test.name, i, x, test.index[i])
+						}
+					}
+				}
+			} else {
+				t.Errorf("%s.%s found", s.Name(), f.Name)
+			}
+		} else if len(test.index) > 0 {
+			t.Errorf("%s.%s not found", s.Name(), test.name)
+		}
+
+		if test.value != 0 {
+			v := ValueOf(test.s).FieldByName(test.name)
+			if v.IsValid() {
+				if x, ok := v.Interface().(int); ok {
+					if x != test.value {
+						t.Errorf("%s.%s is %d; want %d", s.Name(), test.name, x, test.value)
+					}
+				} else {
+					t.Errorf("%s.%s value not an int", s.Name(), test.name)
+				}
+			} else {
+				t.Errorf("%s.%s value not found", s.Name(), test.name)
+			}
+		}
+	}
+}
+
+func TestImportPath(t *testing.T) {
+	tests := []struct {
+		t    Type
+		path string
+	}{
+		{TypeOf(&base64.Encoding{}).Elem(), "encoding/base64"},
+		{TypeOf(int(0)), ""},
+		{TypeOf(int8(0)), ""},
+		{TypeOf(int16(0)), ""},
+		{TypeOf(int32(0)), ""},
+		{TypeOf(int64(0)), ""},
+		{TypeOf(uint(0)), ""},
+		{TypeOf(uint8(0)), ""},
+		{TypeOf(uint16(0)), ""},
+		{TypeOf(uint32(0)), ""},
+		{TypeOf(uint64(0)), ""},
+		{TypeOf(uintptr(0)), ""},
+		{TypeOf(float32(0)), ""},
+		{TypeOf(float64(0)), ""},
+		{TypeOf(complex64(0)), ""},
+		{TypeOf(complex128(0)), ""},
+		{TypeOf(byte(0)), ""},
+		{TypeOf(rune(0)), ""},
+		{TypeOf([]byte(nil)), ""},
+		{TypeOf([]rune(nil)), ""},
+		{TypeOf(string("")), ""},
+		{TypeOf((*interface{})(nil)).Elem(), ""},
+		{TypeOf((*byte)(nil)), ""},
+		{TypeOf((*rune)(nil)), ""},
+		{TypeOf((*int64)(nil)), ""},
+		{TypeOf(map[string]int{}), ""},
+		{TypeOf((*error)(nil)).Elem(), ""},
+	}
+	for _, test := range tests {
+		if path := test.t.PkgPath(); path != test.path {
+			t.Errorf("%v.PkgPath() = %q, want %q", test.t, path, test.path)
+		}
+	}
+}
+
+func TestVariadicType(t *testing.T) {
+	// Test example from Type documentation.
+	var f func(x int, y ...float64)
+	typ := TypeOf(f)
+	if typ.NumIn() == 2 && typ.In(0) == TypeOf(int(0)) {
+		sl := typ.In(1)
+		if sl.Kind() == Slice {
+			if sl.Elem() == TypeOf(0.0) {
+				// ok
+				return
+			}
+		}
+	}
+
+	// Failed
+	t.Errorf("want NumIn() = 2, In(0) = int, In(1) = []float64")
+	s := fmt.Sprintf("have NumIn() = %d", typ.NumIn())
+	for i := 0; i < typ.NumIn(); i++ {
+		s += fmt.Sprintf(", In(%d) = %s", i, typ.In(i))
+	}
+	t.Error(s)
+}
+
+type inner struct {
+	x int
+}
+
+type outer struct {
+	y int
+	inner
+}
+
+func (*inner) m() {}
+func (*outer) m() {}
+
+func TestNestedMethods(t *testing.T) {
+	typ := TypeOf((*outer)(nil))
+	if typ.NumMethod() != 1 || typ.Method(0).Func.Pointer() != ValueOf((*outer).m).Pointer() {
+		t.Errorf("Wrong method table for outer: (m=%p)", (*outer).m)
+		for i := 0; i < typ.NumMethod(); i++ {
+			m := typ.Method(i)
+			t.Errorf("\t%d: %s %#x\n", i, m.Name, m.Func.Pointer())
+		}
+	}
+}
+
+type InnerInt struct {
+	X int
+}
+
+type OuterInt struct {
+	Y int
+	InnerInt
+}
+
+func (i *InnerInt) M() int {
+	return i.X
+}
+
+func TestEmbeddedMethods(t *testing.T) {
+	typ := TypeOf((*OuterInt)(nil))
+	if typ.NumMethod() != 1 || typ.Method(0).Func.Pointer() != ValueOf((*OuterInt).M).Pointer() {
+		t.Errorf("Wrong method table for OuterInt: (m=%p)", (*OuterInt).M)
+		for i := 0; i < typ.NumMethod(); i++ {
+			m := typ.Method(i)
+			t.Errorf("\t%d: %s %#x\n", i, m.Name, m.Func.Pointer())
+		}
+	}
+
+	i := &InnerInt{3}
+	if v := ValueOf(i).Method(0).Call(nil)[0].Int(); v != 3 {
+		t.Errorf("i.M() = %d, want 3", v)
+	}
+
+	o := &OuterInt{1, InnerInt{2}}
+	if v := ValueOf(o).Method(0).Call(nil)[0].Int(); v != 2 {
+		t.Errorf("i.M() = %d, want 2", v)
+	}
+
+	f := (*OuterInt).M
+	if v := f(o); v != 2 {
+		t.Errorf("f(o) = %d, want 2", v)
+	}
+}
+
+func TestPtrTo(t *testing.T) {
+	var i int
+
+	typ := TypeOf(i)
+	for i = 0; i < 100; i++ {
+		typ = PtrTo(typ)
+	}
+	for i = 0; i < 100; i++ {
+		typ = typ.Elem()
+	}
+	if typ != TypeOf(i) {
+		t.Errorf("after 100 PtrTo and Elem, have %s, want %s", typ, TypeOf(i))
+	}
+}
+
+func TestPtrToGC(t *testing.T) {
+	type T *uintptr
+	tt := TypeOf(T(nil))
+	pt := PtrTo(tt)
+	const n = 100
+	var x []interface{}
+	for i := 0; i < n; i++ {
+		v := New(pt)
+		p := new(*uintptr)
+		*p = new(uintptr)
+		**p = uintptr(i)
+		v.Elem().Set(ValueOf(p).Convert(pt))
+		x = append(x, v.Interface())
+	}
+	runtime.GC()
+
+	for i, xi := range x {
+		k := ValueOf(xi).Elem().Elem().Elem().Interface().(uintptr)
+		if k != uintptr(i) {
+			t.Errorf("lost x[%d] = %d, want %d", i, k, i)
+		}
+	}
+}
+
+func TestAddr(t *testing.T) {
+	var p struct {
+		X, Y int
+	}
+
+	v := ValueOf(&p)
+	v = v.Elem()
+	v = v.Addr()
+	v = v.Elem()
+	v = v.Field(0)
+	v.SetInt(2)
+	if p.X != 2 {
+		t.Errorf("Addr.Elem.Set failed to set value")
+	}
+
+	// Again but take address of the ValueOf value.
+	// Exercises generation of PtrTypes not present in the binary.
+	q := &p
+	v = ValueOf(&q).Elem()
+	v = v.Addr()
+	v = v.Elem()
+	v = v.Elem()
+	v = v.Addr()
+	v = v.Elem()
+	v = v.Field(0)
+	v.SetInt(3)
+	if p.X != 3 {
+		t.Errorf("Addr.Elem.Set failed to set value")
+	}
+
+	// Starting without pointer we should get changed value
+	// in interface.
+	qq := p
+	v = ValueOf(&qq).Elem()
+	v0 := v
+	v = v.Addr()
+	v = v.Elem()
+	v = v.Field(0)
+	v.SetInt(4)
+	if p.X != 3 { // should be unchanged from last time
+		t.Errorf("somehow value Set changed original p")
+	}
+	p = v0.Interface().(struct {
+		X, Y int
+	})
+	if p.X != 4 {
+		t.Errorf("Addr.Elem.Set valued to set value in top value")
+	}
+
+	// Verify that taking the address of a type gives us a pointer
+	// which we can convert back using the usual interface
+	// notation.
+	var s struct {
+		B *bool
+	}
+	ps := ValueOf(&s).Elem().Field(0).Addr().Interface()
+	*(ps.(**bool)) = new(bool)
+	if s.B == nil {
+		t.Errorf("Addr.Interface direct assignment failed")
+	}
+}
+
+func noAlloc(t *testing.T, n int, f func(int)) {
+	if testing.Short() {
+		t.Skip("skipping malloc count in short mode")
+	}
+	if runtime.GOMAXPROCS(0) > 1 {
+		t.Skip("skipping; GOMAXPROCS>1")
+	}
+	i := -1
+	allocs := testing.AllocsPerRun(n, func() {
+		f(i)
+		i++
+	})
+	if allocs > 0 {
+		t.Errorf("%d iterations: got %v mallocs, want 0", n, allocs)
+	}
+}
+
+func TestAllocations(t *testing.T) {
+	noAlloc(t, 100, func(j int) {
+		var i interface{}
+		var v Value
+
+		// We can uncomment this when compiler escape analysis
+		// is good enough to see that the integer assigned to i
+		// does not escape and therefore need not be allocated.
+		//
+		// i = 42 + j
+		// v = ValueOf(i)
+		// if int(v.Int()) != 42+j {
+		// 	panic("wrong int")
+		// }
+
+		i = func(j int) int { return j }
+		v = ValueOf(i)
+		if v.Interface().(func(int) int)(j) != j {
+			panic("wrong result")
+		}
+	})
+}
+
+func TestSmallNegativeInt(t *testing.T) {
+	i := int16(-1)
+	v := ValueOf(i)
+	if v.Int() != -1 {
+		t.Errorf("int16(-1).Int() returned %v", v.Int())
+	}
+}
+
+func TestIndex(t *testing.T) {
+	xs := []byte{1, 2, 3, 4, 5, 6, 7, 8}
+	v := ValueOf(xs).Index(3).Interface().(byte)
+	if v != xs[3] {
+		t.Errorf("xs.Index(3) = %v; expected %v", v, xs[3])
+	}
+	xa := [8]byte{10, 20, 30, 40, 50, 60, 70, 80}
+	v = ValueOf(xa).Index(2).Interface().(byte)
+	if v != xa[2] {
+		t.Errorf("xa.Index(2) = %v; expected %v", v, xa[2])
+	}
+	s := "0123456789"
+	v = ValueOf(s).Index(3).Interface().(byte)
+	if v != s[3] {
+		t.Errorf("s.Index(3) = %v; expected %v", v, s[3])
+	}
+}
+
+func TestSlice(t *testing.T) {
+	xs := []int{1, 2, 3, 4, 5, 6, 7, 8}
+	v := ValueOf(xs).Slice(3, 5).Interface().([]int)
+	if len(v) != 2 {
+		t.Errorf("len(xs.Slice(3, 5)) = %d", len(v))
+	}
+	if cap(v) != 5 {
+		t.Errorf("cap(xs.Slice(3, 5)) = %d", cap(v))
+	}
+	if !DeepEqual(v[0:5], xs[3:]) {
+		t.Errorf("xs.Slice(3, 5)[0:5] = %v", v[0:5])
+	}
+	xa := [8]int{10, 20, 30, 40, 50, 60, 70, 80}
+	v = ValueOf(&xa).Elem().Slice(2, 5).Interface().([]int)
+	if len(v) != 3 {
+		t.Errorf("len(xa.Slice(2, 5)) = %d", len(v))
+	}
+	if cap(v) != 6 {
+		t.Errorf("cap(xa.Slice(2, 5)) = %d", cap(v))
+	}
+	if !DeepEqual(v[0:6], xa[2:]) {
+		t.Errorf("xs.Slice(2, 5)[0:6] = %v", v[0:6])
+	}
+	s := "0123456789"
+	vs := ValueOf(s).Slice(3, 5).Interface().(string)
+	if vs != s[3:5] {
+		t.Errorf("s.Slice(3, 5) = %q; expected %q", vs, s[3:5])
+	}
+
+	rv := ValueOf(&xs).Elem()
+	rv = rv.Slice(3, 4)
+	ptr2 := rv.Pointer()
+	rv = rv.Slice(5, 5)
+	ptr3 := rv.Pointer()
+	if ptr3 != ptr2 {
+		t.Errorf("xs.Slice(3,4).Slice3(5,5).Pointer() = %#x, want %#x", ptr3, ptr2)
+	}
+}
+
+func TestSlice3(t *testing.T) {
+	xs := []int{1, 2, 3, 4, 5, 6, 7, 8}
+	v := ValueOf(xs).Slice3(3, 5, 7).Interface().([]int)
+	if len(v) != 2 {
+		t.Errorf("len(xs.Slice3(3, 5, 7)) = %d", len(v))
+	}
+	if cap(v) != 4 {
+		t.Errorf("cap(xs.Slice3(3, 5, 7)) = %d", cap(v))
+	}
+	if !DeepEqual(v[0:4], xs[3:7:7]) {
+		t.Errorf("xs.Slice3(3, 5, 7)[0:4] = %v", v[0:4])
+	}
+	rv := ValueOf(&xs).Elem()
+	shouldPanic(func() { rv.Slice3(1, 2, 1) })
+	shouldPanic(func() { rv.Slice3(1, 1, 11) })
+	shouldPanic(func() { rv.Slice3(2, 2, 1) })
+
+	xa := [8]int{10, 20, 30, 40, 50, 60, 70, 80}
+	v = ValueOf(&xa).Elem().Slice3(2, 5, 6).Interface().([]int)
+	if len(v) != 3 {
+		t.Errorf("len(xa.Slice(2, 5, 6)) = %d", len(v))
+	}
+	if cap(v) != 4 {
+		t.Errorf("cap(xa.Slice(2, 5, 6)) = %d", cap(v))
+	}
+	if !DeepEqual(v[0:4], xa[2:6:6]) {
+		t.Errorf("xs.Slice(2, 5, 6)[0:4] = %v", v[0:4])
+	}
+	rv = ValueOf(&xa).Elem()
+	shouldPanic(func() { rv.Slice3(1, 2, 1) })
+	shouldPanic(func() { rv.Slice3(1, 1, 11) })
+	shouldPanic(func() { rv.Slice3(2, 2, 1) })
+
+	s := "hello world"
+	rv = ValueOf(&s).Elem()
+	shouldPanic(func() { rv.Slice3(1, 2, 3) })
+
+	rv = ValueOf(&xs).Elem()
+	rv = rv.Slice3(3, 5, 7)
+	ptr2 := rv.Pointer()
+	rv = rv.Slice3(4, 4, 4)
+	ptr3 := rv.Pointer()
+	if ptr3 != ptr2 {
+		t.Errorf("xs.Slice3(3,5,7).Slice3(4,4,4).Pointer() = %#x, want %#x", ptr3, ptr2)
+	}
+}
+
+func TestSetLenCap(t *testing.T) {
+	xs := []int{1, 2, 3, 4, 5, 6, 7, 8}
+	xa := [8]int{10, 20, 30, 40, 50, 60, 70, 80}
+
+	vs := ValueOf(&xs).Elem()
+	shouldPanic(func() { vs.SetLen(10) })
+	shouldPanic(func() { vs.SetCap(10) })
+	shouldPanic(func() { vs.SetLen(-1) })
+	shouldPanic(func() { vs.SetCap(-1) })
+	shouldPanic(func() { vs.SetCap(6) }) // smaller than len
+	vs.SetLen(5)
+	if len(xs) != 5 || cap(xs) != 8 {
+		t.Errorf("after SetLen(5), len, cap = %d, %d, want 5, 8", len(xs), cap(xs))
+	}
+	vs.SetCap(6)
+	if len(xs) != 5 || cap(xs) != 6 {
+		t.Errorf("after SetCap(6), len, cap = %d, %d, want 5, 6", len(xs), cap(xs))
+	}
+	vs.SetCap(5)
+	if len(xs) != 5 || cap(xs) != 5 {
+		t.Errorf("after SetCap(5), len, cap = %d, %d, want 5, 5", len(xs), cap(xs))
+	}
+	shouldPanic(func() { vs.SetCap(4) }) // smaller than len
+	shouldPanic(func() { vs.SetLen(6) }) // bigger than cap
+
+	va := ValueOf(&xa).Elem()
+	shouldPanic(func() { va.SetLen(8) })
+	shouldPanic(func() { va.SetCap(8) })
+}
+
+func TestVariadic(t *testing.T) {
+	var b bytes.Buffer
+	V := ValueOf
+
+	b.Reset()
+	V(fmt.Fprintf).Call([]Value{V(&b), V("%s, %d world"), V("hello"), V(42)})
+	if b.String() != "hello, 42 world" {
+		t.Errorf("after Fprintf Call: %q != %q", b.String(), "hello 42 world")
+	}
+
+	b.Reset()
+	V(fmt.Fprintf).CallSlice([]Value{V(&b), V("%s, %d world"), V([]interface{}{"hello", 42})})
+	if b.String() != "hello, 42 world" {
+		t.Errorf("after Fprintf CallSlice: %q != %q", b.String(), "hello 42 world")
+	}
+}
+
+func TestFuncArg(t *testing.T) {
+	f1 := func(i int, f func(int) int) int { return f(i) }
+	f2 := func(i int) int { return i + 1 }
+	r := ValueOf(f1).Call([]Value{ValueOf(100), ValueOf(f2)})
+	if r[0].Int() != 101 {
+		t.Errorf("function returned %d, want 101", r[0].Int())
+	}
+}
+
+func TestStructArg(t *testing.T) {
+	type padded struct {
+		B string
+		C int32
+	}
+	var (
+		gotA  padded
+		gotB  uint32
+		wantA = padded{"3", 4}
+		wantB = uint32(5)
+	)
+	f := func(a padded, b uint32) {
+		gotA, gotB = a, b
+	}
+	ValueOf(f).Call([]Value{ValueOf(wantA), ValueOf(wantB)})
+	if gotA != wantA || gotB != wantB {
+		t.Errorf("function called with (%v, %v), want (%v, %v)", gotA, gotB, wantA, wantB)
+	}
+}
+
+var tagGetTests = []struct {
+	Tag   StructTag
+	Key   string
+	Value string
+}{
+	{`protobuf:"PB(1,2)"`, `protobuf`, `PB(1,2)`},
+	{`protobuf:"PB(1,2)"`, `foo`, ``},
+	{`protobuf:"PB(1,2)"`, `rotobuf`, ``},
+	{`protobuf:"PB(1,2)" json:"name"`, `json`, `name`},
+	{`protobuf:"PB(1,2)" json:"name"`, `protobuf`, `PB(1,2)`},
+}
+
+func TestTagGet(t *testing.T) {
+	for _, tt := range tagGetTests {
+		if v := tt.Tag.Get(tt.Key); v != tt.Value {
+			t.Errorf("StructTag(%#q).Get(%#q) = %#q, want %#q", tt.Tag, tt.Key, v, tt.Value)
+		}
+	}
+}
+
+func TestBytes(t *testing.T) {
+	type B []byte
+	x := B{1, 2, 3, 4}
+	y := ValueOf(x).Bytes()
+	if !bytes.Equal(x, y) {
+		t.Fatalf("ValueOf(%v).Bytes() = %v", x, y)
+	}
+	if &x[0] != &y[0] {
+		t.Errorf("ValueOf(%p).Bytes() = %p", &x[0], &y[0])
+	}
+}
+
+func TestSetBytes(t *testing.T) {
+	type B []byte
+	var x B
+	y := []byte{1, 2, 3, 4}
+	ValueOf(&x).Elem().SetBytes(y)
+	if !bytes.Equal(x, y) {
+		t.Fatalf("ValueOf(%v).Bytes() = %v", x, y)
+	}
+	if &x[0] != &y[0] {
+		t.Errorf("ValueOf(%p).Bytes() = %p", &x[0], &y[0])
+	}
+}
+
+type Private struct {
+	x int
+	y **int
+}
+
+func (p *Private) m() {
+}
+
+type Public struct {
+	X int
+	Y **int
+}
+
+func (p *Public) M() {
+}
+
+func TestUnexported(t *testing.T) {
+	var pub Public
+	v := ValueOf(&pub)
+	isValid(v.Elem().Field(0))
+	isValid(v.Elem().Field(1))
+	isValid(v.Elem().FieldByName("X"))
+	isValid(v.Elem().FieldByName("Y"))
+	isValid(v.Type().Method(0).Func)
+	isNonNil(v.Elem().Field(0).Interface())
+	isNonNil(v.Elem().Field(1).Interface())
+	isNonNil(v.Elem().FieldByName("X").Interface())
+	isNonNil(v.Elem().FieldByName("Y").Interface())
+	isNonNil(v.Type().Method(0).Func.Interface())
+
+	var priv Private
+	v = ValueOf(&priv)
+	isValid(v.Elem().Field(0))
+	isValid(v.Elem().Field(1))
+	isValid(v.Elem().FieldByName("x"))
+	isValid(v.Elem().FieldByName("y"))
+	isValid(v.Type().Method(0).Func)
+	shouldPanic(func() { v.Elem().Field(0).Interface() })
+	shouldPanic(func() { v.Elem().Field(1).Interface() })
+	shouldPanic(func() { v.Elem().FieldByName("x").Interface() })
+	shouldPanic(func() { v.Elem().FieldByName("y").Interface() })
+	shouldPanic(func() { v.Type().Method(0).Func.Interface() })
+}
+
+func shouldPanic(f func()) {
+	defer func() {
+		if recover() == nil {
+			panic("did not panic")
+		}
+	}()
+	f()
+}
+
+func isNonNil(x interface{}) {
+	if x == nil {
+		panic("nil interface")
+	}
+}
+
+func isValid(v Value) {
+	if !v.IsValid() {
+		panic("zero Value")
+	}
+}
+
+func TestAlias(t *testing.T) {
+	x := string("hello")
+	v := ValueOf(&x).Elem()
+	oldvalue := v.Interface()
+	v.SetString("world")
+	newvalue := v.Interface()
+
+	if oldvalue != "hello" || newvalue != "world" {
+		t.Errorf("aliasing: old=%q new=%q, want hello, world", oldvalue, newvalue)
+	}
+}
+
+var V = ValueOf
+
+func EmptyInterfaceV(x interface{}) Value {
+	return ValueOf(&x).Elem()
+}
+
+func ReaderV(x io.Reader) Value {
+	return ValueOf(&x).Elem()
+}
+
+func ReadWriterV(x io.ReadWriter) Value {
+	return ValueOf(&x).Elem()
+}
+
+type Empty struct{}
+type MyString string
+type MyBytes []byte
+type MyRunes []int32
+type MyFunc func()
+type MyByte byte
+
+var convertTests = []struct {
+	in  Value
+	out Value
+}{
+	// numbers
+	/*
+		Edit .+1,/\*\//-1>cat >/tmp/x.go && go run /tmp/x.go
+
+		package main
+
+		import "fmt"
+
+		var numbers = []string{
+			"int8", "uint8", "int16", "uint16",
+			"int32", "uint32", "int64", "uint64",
+			"int", "uint", "uintptr",
+			"float32", "float64",
+		}
+
+		func main() {
+			// all pairs but in an unusual order,
+			// to emit all the int8, uint8 cases
+			// before n grows too big.
+			n := 1
+			for i, f := range numbers {
+				for _, g := range numbers[i:] {
+					fmt.Printf("\t{V(%s(%d)), V(%s(%d))},\n", f, n, g, n)
+					n++
+					if f != g {
+						fmt.Printf("\t{V(%s(%d)), V(%s(%d))},\n", g, n, f, n)
+						n++
+					}
+				}
+			}
+		}
+	*/
+	{V(int8(1)), V(int8(1))},
+	{V(int8(2)), V(uint8(2))},
+	{V(uint8(3)), V(int8(3))},
+	{V(int8(4)), V(int16(4))},
+	{V(int16(5)), V(int8(5))},
+	{V(int8(6)), V(uint16(6))},
+	{V(uint16(7)), V(int8(7))},
+	{V(int8(8)), V(int32(8))},
+	{V(int32(9)), V(int8(9))},
+	{V(int8(10)), V(uint32(10))},
+	{V(uint32(11)), V(int8(11))},
+	{V(int8(12)), V(int64(12))},
+	{V(int64(13)), V(int8(13))},
+	{V(int8(14)), V(uint64(14))},
+	{V(uint64(15)), V(int8(15))},
+	{V(int8(16)), V(int(16))},
+	{V(int(17)), V(int8(17))},
+	{V(int8(18)), V(uint(18))},
+	{V(uint(19)), V(int8(19))},
+	{V(int8(20)), V(uintptr(20))},
+	{V(uintptr(21)), V(int8(21))},
+	{V(int8(22)), V(float32(22))},
+	{V(float32(23)), V(int8(23))},
+	{V(int8(24)), V(float64(24))},
+	{V(float64(25)), V(int8(25))},
+	{V(uint8(26)), V(uint8(26))},
+	{V(uint8(27)), V(int16(27))},
+	{V(int16(28)), V(uint8(28))},
+	{V(uint8(29)), V(uint16(29))},
+	{V(uint16(30)), V(uint8(30))},
+	{V(uint8(31)), V(int32(31))},
+	{V(int32(32)), V(uint8(32))},
+	{V(uint8(33)), V(uint32(33))},
+	{V(uint32(34)), V(uint8(34))},
+	{V(uint8(35)), V(int64(35))},
+	{V(int64(36)), V(uint8(36))},
+	{V(uint8(37)), V(uint64(37))},
+	{V(uint64(38)), V(uint8(38))},
+	{V(uint8(39)), V(int(39))},
+	{V(int(40)), V(uint8(40))},
+	{V(uint8(41)), V(uint(41))},
+	{V(uint(42)), V(uint8(42))},
+	{V(uint8(43)), V(uintptr(43))},
+	{V(uintptr(44)), V(uint8(44))},
+	{V(uint8(45)), V(float32(45))},
+	{V(float32(46)), V(uint8(46))},
+	{V(uint8(47)), V(float64(47))},
+	{V(float64(48)), V(uint8(48))},
+	{V(int16(49)), V(int16(49))},
+	{V(int16(50)), V(uint16(50))},
+	{V(uint16(51)), V(int16(51))},
+	{V(int16(52)), V(int32(52))},
+	{V(int32(53)), V(int16(53))},
+	{V(int16(54)), V(uint32(54))},
+	{V(uint32(55)), V(int16(55))},
+	{V(int16(56)), V(int64(56))},
+	{V(int64(57)), V(int16(57))},
+	{V(int16(58)), V(uint64(58))},
+	{V(uint64(59)), V(int16(59))},
+	{V(int16(60)), V(int(60))},
+	{V(int(61)), V(int16(61))},
+	{V(int16(62)), V(uint(62))},
+	{V(uint(63)), V(int16(63))},
+	{V(int16(64)), V(uintptr(64))},
+	{V(uintptr(65)), V(int16(65))},
+	{V(int16(66)), V(float32(66))},
+	{V(float32(67)), V(int16(67))},
+	{V(int16(68)), V(float64(68))},
+	{V(float64(69)), V(int16(69))},
+	{V(uint16(70)), V(uint16(70))},
+	{V(uint16(71)), V(int32(71))},
+	{V(int32(72)), V(uint16(72))},
+	{V(uint16(73)), V(uint32(73))},
+	{V(uint32(74)), V(uint16(74))},
+	{V(uint16(75)), V(int64(75))},
+	{V(int64(76)), V(uint16(76))},
+	{V(uint16(77)), V(uint64(77))},
+	{V(uint64(78)), V(uint16(78))},
+	{V(uint16(79)), V(int(79))},
+	{V(int(80)), V(uint16(80))},
+	{V(uint16(81)), V(uint(81))},
+	{V(uint(82)), V(uint16(82))},
+	{V(uint16(83)), V(uintptr(83))},
+	{V(uintptr(84)), V(uint16(84))},
+	{V(uint16(85)), V(float32(85))},
+	{V(float32(86)), V(uint16(86))},
+	{V(uint16(87)), V(float64(87))},
+	{V(float64(88)), V(uint16(88))},
+	{V(int32(89)), V(int32(89))},
+	{V(int32(90)), V(uint32(90))},
+	{V(uint32(91)), V(int32(91))},
+	{V(int32(92)), V(int64(92))},
+	{V(int64(93)), V(int32(93))},
+	{V(int32(94)), V(uint64(94))},
+	{V(uint64(95)), V(int32(95))},
+	{V(int32(96)), V(int(96))},
+	{V(int(97)), V(int32(97))},
+	{V(int32(98)), V(uint(98))},
+	{V(uint(99)), V(int32(99))},
+	{V(int32(100)), V(uintptr(100))},
+	{V(uintptr(101)), V(int32(101))},
+	{V(int32(102)), V(float32(102))},
+	{V(float32(103)), V(int32(103))},
+	{V(int32(104)), V(float64(104))},
+	{V(float64(105)), V(int32(105))},
+	{V(uint32(106)), V(uint32(106))},
+	{V(uint32(107)), V(int64(107))},
+	{V(int64(108)), V(uint32(108))},
+	{V(uint32(109)), V(uint64(109))},
+	{V(uint64(110)), V(uint32(110))},
+	{V(uint32(111)), V(int(111))},
+	{V(int(112)), V(uint32(112))},
+	{V(uint32(113)), V(uint(113))},
+	{V(uint(114)), V(uint32(114))},
+	{V(uint32(115)), V(uintptr(115))},
+	{V(uintptr(116)), V(uint32(116))},
+	{V(uint32(117)), V(float32(117))},
+	{V(float32(118)), V(uint32(118))},
+	{V(uint32(119)), V(float64(119))},
+	{V(float64(120)), V(uint32(120))},
+	{V(int64(121)), V(int64(121))},
+	{V(int64(122)), V(uint64(122))},
+	{V(uint64(123)), V(int64(123))},
+	{V(int64(124)), V(int(124))},
+	{V(int(125)), V(int64(125))},
+	{V(int64(126)), V(uint(126))},
+	{V(uint(127)), V(int64(127))},
+	{V(int64(128)), V(uintptr(128))},
+	{V(uintptr(129)), V(int64(129))},
+	{V(int64(130)), V(float32(130))},
+	{V(float32(131)), V(int64(131))},
+	{V(int64(132)), V(float64(132))},
+	{V(float64(133)), V(int64(133))},
+	{V(uint64(134)), V(uint64(134))},
+	{V(uint64(135)), V(int(135))},
+	{V(int(136)), V(uint64(136))},
+	{V(uint64(137)), V(uint(137))},
+	{V(uint(138)), V(uint64(138))},
+	{V(uint64(139)), V(uintptr(139))},
+	{V(uintptr(140)), V(uint64(140))},
+	{V(uint64(141)), V(float32(141))},
+	{V(float32(142)), V(uint64(142))},
+	{V(uint64(143)), V(float64(143))},
+	{V(float64(144)), V(uint64(144))},
+	{V(int(145)), V(int(145))},
+	{V(int(146)), V(uint(146))},
+	{V(uint(147)), V(int(147))},
+	{V(int(148)), V(uintptr(148))},
+	{V(uintptr(149)), V(int(149))},
+	{V(int(150)), V(float32(150))},
+	{V(float32(151)), V(int(151))},
+	{V(int(152)), V(float64(152))},
+	{V(float64(153)), V(int(153))},
+	{V(uint(154)), V(uint(154))},
+	{V(uint(155)), V(uintptr(155))},
+	{V(uintptr(156)), V(uint(156))},
+	{V(uint(157)), V(float32(157))},
+	{V(float32(158)), V(uint(158))},
+	{V(uint(159)), V(float64(159))},
+	{V(float64(160)), V(uint(160))},
+	{V(uintptr(161)), V(uintptr(161))},
+	{V(uintptr(162)), V(float32(162))},
+	{V(float32(163)), V(uintptr(163))},
+	{V(uintptr(164)), V(float64(164))},
+	{V(float64(165)), V(uintptr(165))},
+	{V(float32(166)), V(float32(166))},
+	{V(float32(167)), V(float64(167))},
+	{V(float64(168)), V(float32(168))},
+	{V(float64(169)), V(float64(169))},
+
+	// truncation
+	{V(float64(1.5)), V(int(1))},
+
+	// complex
+	{V(complex64(1i)), V(complex64(1i))},
+	{V(complex64(2i)), V(complex128(2i))},
+	{V(complex128(3i)), V(complex64(3i))},
+	{V(complex128(4i)), V(complex128(4i))},
+
+	// string
+	{V(string("hello")), V(string("hello"))},
+	{V(string("bytes1")), V([]byte("bytes1"))},
+	{V([]byte("bytes2")), V(string("bytes2"))},
+	{V([]byte("bytes3")), V([]byte("bytes3"))},
+	{V(string("runes♝")), V([]rune("runes♝"))},
+	{V([]rune("runes♕")), V(string("runes♕"))},
+	{V([]rune("runes🙈🙉🙊")), V([]rune("runes🙈🙉🙊"))},
+	{V(int('a')), V(string("a"))},
+	{V(int8('a')), V(string("a"))},
+	{V(int16('a')), V(string("a"))},
+	{V(int32('a')), V(string("a"))},
+	{V(int64('a')), V(string("a"))},
+	{V(uint('a')), V(string("a"))},
+	{V(uint8('a')), V(string("a"))},
+	{V(uint16('a')), V(string("a"))},
+	{V(uint32('a')), V(string("a"))},
+	{V(uint64('a')), V(string("a"))},
+	{V(uintptr('a')), V(string("a"))},
+	{V(int(-1)), V(string("\uFFFD"))},
+	{V(int8(-2)), V(string("\uFFFD"))},
+	{V(int16(-3)), V(string("\uFFFD"))},
+	{V(int32(-4)), V(string("\uFFFD"))},
+	{V(int64(-5)), V(string("\uFFFD"))},
+	{V(uint(0x110001)), V(string("\uFFFD"))},
+	{V(uint32(0x110002)), V(string("\uFFFD"))},
+	{V(uint64(0x110003)), V(string("\uFFFD"))},
+	{V(uintptr(0x110004)), V(string("\uFFFD"))},
+
+	// named string
+	{V(MyString("hello")), V(string("hello"))},
+	{V(string("hello")), V(MyString("hello"))},
+	{V(string("hello")), V(string("hello"))},
+	{V(MyString("hello")), V(MyString("hello"))},
+	{V(MyString("bytes1")), V([]byte("bytes1"))},
+	{V([]byte("bytes2")), V(MyString("bytes2"))},
+	{V([]byte("bytes3")), V([]byte("bytes3"))},
+	{V(MyString("runes♝")), V([]rune("runes♝"))},
+	{V([]rune("runes♕")), V(MyString("runes♕"))},
+	{V([]rune("runes🙈🙉🙊")), V([]rune("runes🙈🙉🙊"))},
+	{V([]rune("runes🙈🙉🙊")), V(MyRunes("runes🙈🙉🙊"))},
+	{V(MyRunes("runes🙈🙉🙊")), V([]rune("runes🙈🙉🙊"))},
+	{V(int('a')), V(MyString("a"))},
+	{V(int8('a')), V(MyString("a"))},
+	{V(int16('a')), V(MyString("a"))},
+	{V(int32('a')), V(MyString("a"))},
+	{V(int64('a')), V(MyString("a"))},
+	{V(uint('a')), V(MyString("a"))},
+	{V(uint8('a')), V(MyString("a"))},
+	{V(uint16('a')), V(MyString("a"))},
+	{V(uint32('a')), V(MyString("a"))},
+	{V(uint64('a')), V(MyString("a"))},
+	{V(uintptr('a')), V(MyString("a"))},
+	{V(int(-1)), V(MyString("\uFFFD"))},
+	{V(int8(-2)), V(MyString("\uFFFD"))},
+	{V(int16(-3)), V(MyString("\uFFFD"))},
+	{V(int32(-4)), V(MyString("\uFFFD"))},
+	{V(int64(-5)), V(MyString("\uFFFD"))},
+	{V(uint(0x110001)), V(MyString("\uFFFD"))},
+	{V(uint32(0x110002)), V(MyString("\uFFFD"))},
+	{V(uint64(0x110003)), V(MyString("\uFFFD"))},
+	{V(uintptr(0x110004)), V(MyString("\uFFFD"))},
+
+	// named []byte
+	{V(string("bytes1")), V(MyBytes("bytes1"))},
+	{V(MyBytes("bytes2")), V(string("bytes2"))},
+	{V(MyBytes("bytes3")), V(MyBytes("bytes3"))},
+	{V(MyString("bytes1")), V(MyBytes("bytes1"))},
+	{V(MyBytes("bytes2")), V(MyString("bytes2"))},
+
+	// named []rune
+	{V(string("runes♝")), V(MyRunes("runes♝"))},
+	{V(MyRunes("runes♕")), V(string("runes♕"))},
+	{V(MyRunes("runes🙈🙉🙊")), V(MyRunes("runes🙈🙉🙊"))},
+	{V(MyString("runes♝")), V(MyRunes("runes♝"))},
+	{V(MyRunes("runes♕")), V(MyString("runes♕"))},
+
+	// named types and equal underlying types
+	{V(new(int)), V(new(integer))},
+	{V(new(integer)), V(new(int))},
+	{V(Empty{}), V(struct{}{})},
+	{V(new(Empty)), V(new(struct{}))},
+	{V(struct{}{}), V(Empty{})},
+	{V(new(struct{})), V(new(Empty))},
+	{V(Empty{}), V(Empty{})},
+	{V(MyBytes{}), V([]byte{})},
+	{V([]byte{}), V(MyBytes{})},
+	{V((func())(nil)), V(MyFunc(nil))},
+	{V((MyFunc)(nil)), V((func())(nil))},
+
+	// can convert *byte and *MyByte
+	{V((*byte)(nil)), V((*MyByte)(nil))},
+	{V((*MyByte)(nil)), V((*byte)(nil))},
+
+	// cannot convert mismatched array sizes
+	{V([2]byte{}), V([2]byte{})},
+	{V([3]byte{}), V([3]byte{})},
+
+	// cannot convert other instances
+	{V((**byte)(nil)), V((**byte)(nil))},
+	{V((**MyByte)(nil)), V((**MyByte)(nil))},
+	{V((chan byte)(nil)), V((chan byte)(nil))},
+	{V((chan MyByte)(nil)), V((chan MyByte)(nil))},
+	{V(([]byte)(nil)), V(([]byte)(nil))},
+	{V(([]MyByte)(nil)), V(([]MyByte)(nil))},
+	{V((map[int]byte)(nil)), V((map[int]byte)(nil))},
+	{V((map[int]MyByte)(nil)), V((map[int]MyByte)(nil))},
+	{V((map[byte]int)(nil)), V((map[byte]int)(nil))},
+	{V((map[MyByte]int)(nil)), V((map[MyByte]int)(nil))},
+	{V([2]byte{}), V([2]byte{})},
+	{V([2]MyByte{}), V([2]MyByte{})},
+
+	// other
+	{V((***int)(nil)), V((***int)(nil))},
+	{V((***byte)(nil)), V((***byte)(nil))},
+	{V((***int32)(nil)), V((***int32)(nil))},
+	{V((***int64)(nil)), V((***int64)(nil))},
+	{V((chan int)(nil)), V((<-chan int)(nil))},
+	{V((chan int)(nil)), V((chan<- int)(nil))},
+	{V((chan string)(nil)), V((<-chan string)(nil))},
+	{V((chan string)(nil)), V((chan<- string)(nil))},
+	{V((chan byte)(nil)), V((chan byte)(nil))},
+	{V((chan MyByte)(nil)), V((chan MyByte)(nil))},
+	{V((map[int]bool)(nil)), V((map[int]bool)(nil))},
+	{V((map[int]byte)(nil)), V((map[int]byte)(nil))},
+	{V((map[uint]bool)(nil)), V((map[uint]bool)(nil))},
+	{V([]uint(nil)), V([]uint(nil))},
+	{V([]int(nil)), V([]int(nil))},
+	{V(new(interface{})), V(new(interface{}))},
+	{V(new(io.Reader)), V(new(io.Reader))},
+	{V(new(io.Writer)), V(new(io.Writer))},
+
+	// interfaces
+	{V(int(1)), EmptyInterfaceV(int(1))},
+	{V(string("hello")), EmptyInterfaceV(string("hello"))},
+	{V(new(bytes.Buffer)), ReaderV(new(bytes.Buffer))},
+	{ReadWriterV(new(bytes.Buffer)), ReaderV(new(bytes.Buffer))},
+	{V(new(bytes.Buffer)), ReadWriterV(new(bytes.Buffer))},
+}
+
+func TestConvert(t *testing.T) {
+	canConvert := map[[2]Type]bool{}
+	all := map[Type]bool{}
+
+	for _, tt := range convertTests {
+		t1 := tt.in.Type()
+		if !t1.ConvertibleTo(t1) {
+			t.Errorf("(%s).ConvertibleTo(%s) = false, want true", t1, t1)
+			continue
+		}
+
+		t2 := tt.out.Type()
+		if !t1.ConvertibleTo(t2) {
+			t.Errorf("(%s).ConvertibleTo(%s) = false, want true", t1, t2)
+			continue
+		}
+
+		all[t1] = true
+		all[t2] = true
+		canConvert[[2]Type{t1, t2}] = true
+
+		// vout1 represents the in value converted to the in type.
+		v1 := tt.in
+		vout1 := v1.Convert(t1)
+		out1 := vout1.Interface()
+		if vout1.Type() != tt.in.Type() || !DeepEqual(out1, tt.in.Interface()) {
+			t.Errorf("ValueOf(%T(%[1]v)).Convert(%s) = %T(%[3]v), want %T(%[4]v)", tt.in.Interface(), t1, out1, tt.in.Interface())
+		}
+
+		// vout2 represents the in value converted to the out type.
+		vout2 := v1.Convert(t2)
+		out2 := vout2.Interface()
+		if vout2.Type() != tt.out.Type() || !DeepEqual(out2, tt.out.Interface()) {
+			t.Errorf("ValueOf(%T(%[1]v)).Convert(%s) = %T(%[3]v), want %T(%[4]v)", tt.in.Interface(), t2, out2, tt.out.Interface())
+		}
+
+		// vout3 represents a new value of the out type, set to vout2.  This makes
+		// sure the converted value vout2 is really usable as a regular value.
+		vout3 := New(t2).Elem()
+		vout3.Set(vout2)
+		out3 := vout3.Interface()
+		if vout3.Type() != tt.out.Type() || !DeepEqual(out3, tt.out.Interface()) {
+			t.Errorf("Set(ValueOf(%T(%[1]v)).Convert(%s)) = %T(%[3]v), want %T(%[4]v)", tt.in.Interface(), t2, out3, tt.out.Interface())
+		}
+
+		if IsRO(v1) {
+			t.Errorf("table entry %v is RO, should not be", v1)
+		}
+		if IsRO(vout1) {
+			t.Errorf("self-conversion output %v is RO, should not be", vout1)
+		}
+		if IsRO(vout2) {
+			t.Errorf("conversion output %v is RO, should not be", vout2)
+		}
+		if IsRO(vout3) {
+			t.Errorf("set(conversion output) %v is RO, should not be", vout3)
+		}
+		if !IsRO(MakeRO(v1).Convert(t1)) {
+			t.Errorf("RO self-conversion output %v is not RO, should be", v1)
+		}
+		if !IsRO(MakeRO(v1).Convert(t2)) {
+			t.Errorf("RO conversion output %v is not RO, should be", v1)
+		}
+	}
+
+	// Assume that of all the types we saw during the tests,
+	// if there wasn't an explicit entry for a conversion between
+	// a pair of types, then it's not to be allowed. This checks for
+	// things like 'int64' converting to '*int'.
+	for t1 := range all {
+		for t2 := range all {
+			expectOK := t1 == t2 || canConvert[[2]Type{t1, t2}] || t2.Kind() == Interface && t2.NumMethod() == 0
+			if ok := t1.ConvertibleTo(t2); ok != expectOK {
+				t.Errorf("(%s).ConvertibleTo(%s) = %v, want %v", t1, t2, ok, expectOK)
+			}
+		}
+	}
+}
+
+type ComparableStruct struct {
+	X int
+}
+
+type NonComparableStruct struct {
+	X int
+	Y map[string]int
+}
+
+var comparableTests = []struct {
+	typ Type
+	ok  bool
+}{
+	{TypeOf(1), true},
+	{TypeOf("hello"), true},
+	{TypeOf(new(byte)), true},
+	{TypeOf((func())(nil)), false},
+	{TypeOf([]byte{}), false},
+	{TypeOf(map[string]int{}), false},
+	{TypeOf(make(chan int)), true},
+	{TypeOf(1.5), true},
+	{TypeOf(false), true},
+	{TypeOf(1i), true},
+	{TypeOf(ComparableStruct{}), true},
+	{TypeOf(NonComparableStruct{}), false},
+	{TypeOf([10]map[string]int{}), false},
+	{TypeOf([10]string{}), true},
+	{TypeOf(new(interface{})).Elem(), true},
+}
+
+func TestComparable(t *testing.T) {
+	for _, tt := range comparableTests {
+		if ok := tt.typ.Comparable(); ok != tt.ok {
+			t.Errorf("TypeOf(%v).Comparable() = %v, want %v", tt.typ, ok, tt.ok)
+		}
+	}
+}
+
+func TestOverflow(t *testing.T) {
+	if ovf := V(float64(0)).OverflowFloat(1e300); ovf {
+		t.Errorf("%v wrongly overflows float64", 1e300)
+	}
+
+	maxFloat32 := float64((1<<24 - 1) << (127 - 23))
+	if ovf := V(float32(0)).OverflowFloat(maxFloat32); ovf {
+		t.Errorf("%v wrongly overflows float32", maxFloat32)
+	}
+	ovfFloat32 := float64((1<<24-1)<<(127-23) + 1<<(127-52))
+	if ovf := V(float32(0)).OverflowFloat(ovfFloat32); !ovf {
+		t.Errorf("%v should overflow float32", ovfFloat32)
+	}
+	if ovf := V(float32(0)).OverflowFloat(-ovfFloat32); !ovf {
+		t.Errorf("%v should overflow float32", -ovfFloat32)
+	}
+
+	maxInt32 := int64(0x7fffffff)
+	if ovf := V(int32(0)).OverflowInt(maxInt32); ovf {
+		t.Errorf("%v wrongly overflows int32", maxInt32)
+	}
+	if ovf := V(int32(0)).OverflowInt(-1 << 31); ovf {
+		t.Errorf("%v wrongly overflows int32", -int64(1)<<31)
+	}
+	ovfInt32 := int64(1 << 31)
+	if ovf := V(int32(0)).OverflowInt(ovfInt32); !ovf {
+		t.Errorf("%v should overflow int32", ovfInt32)
+	}
+
+	maxUint32 := uint64(0xffffffff)
+	if ovf := V(uint32(0)).OverflowUint(maxUint32); ovf {
+		t.Errorf("%v wrongly overflows uint32", maxUint32)
+	}
+	ovfUint32 := uint64(1 << 32)
+	if ovf := V(uint32(0)).OverflowUint(ovfUint32); !ovf {
+		t.Errorf("%v should overflow uint32", ovfUint32)
+	}
+}
+
+func checkSameType(t *testing.T, x, y interface{}) {
+	if TypeOf(x) != TypeOf(y) {
+		t.Errorf("did not find preexisting type for %s (vs %s)", TypeOf(x), TypeOf(y))
+	}
+}
+
+func TestArrayOf(t *testing.T) {
+	// TODO(rsc): Finish ArrayOf and enable-test.
+	t.Skip("ArrayOf is not finished (and not exported)")
+
+	// check construction and use of type not in binary
+	type T int
+	at := ArrayOf(10, TypeOf(T(1)))
+	v := New(at).Elem()
+	for i := 0; i < v.Len(); i++ {
+		v.Index(i).Set(ValueOf(T(i)))
+	}
+	s := fmt.Sprint(v.Interface())
+	want := "[0 1 2 3 4 5 6 7 8 9]"
+	if s != want {
+		t.Errorf("constructed array = %s, want %s", s, want)
+	}
+
+	// check that type already in binary is found
+	checkSameType(t, Zero(ArrayOf(5, TypeOf(T(1)))).Interface(), [5]T{})
+}
+
+func TestSliceOf(t *testing.T) {
+	// check construction and use of type not in binary
+	type T int
+	st := SliceOf(TypeOf(T(1)))
+	v := MakeSlice(st, 10, 10)
+	runtime.GC()
+	for i := 0; i < v.Len(); i++ {
+		v.Index(i).Set(ValueOf(T(i)))
+		runtime.GC()
+	}
+	s := fmt.Sprint(v.Interface())
+	want := "[0 1 2 3 4 5 6 7 8 9]"
+	if s != want {
+		t.Errorf("constructed slice = %s, want %s", s, want)
+	}
+
+	// check that type already in binary is found
+	type T1 int
+	checkSameType(t, Zero(SliceOf(TypeOf(T1(1)))).Interface(), []T1{})
+}
+
+func TestSliceOverflow(t *testing.T) {
+	// check that MakeSlice panics when size of slice overflows uint
+	const S = 1e6
+	s := uint(S)
+	l := (1<<(unsafe.Sizeof((*byte)(nil))*8)-1)/s + 1
+	if l*s >= s {
+		t.Fatal("slice size does not overflow")
+	}
+	var x [S]byte
+	st := SliceOf(TypeOf(x))
+	defer func() {
+		err := recover()
+		if err == nil {
+			t.Fatal("slice overflow does not panic")
+		}
+	}()
+	MakeSlice(st, int(l), int(l))
+}
+
+func TestSliceOfGC(t *testing.T) {
+	type T *uintptr
+	tt := TypeOf(T(nil))
+	st := SliceOf(tt)
+	const n = 100
+	var x []interface{}
+	for i := 0; i < n; i++ {
+		v := MakeSlice(st, n, n)
+		for j := 0; j < v.Len(); j++ {
+			p := new(uintptr)
+			*p = uintptr(i*n + j)
+			v.Index(j).Set(ValueOf(p).Convert(tt))
+		}
+		x = append(x, v.Interface())
+	}
+	runtime.GC()
+
+	for i, xi := range x {
+		v := ValueOf(xi)
+		for j := 0; j < v.Len(); j++ {
+			k := v.Index(j).Elem().Interface()
+			if k != uintptr(i*n+j) {
+				t.Errorf("lost x[%d][%d] = %d, want %d", i, j, k, i*n+j)
+			}
+		}
+	}
+}
+
+func TestChanOf(t *testing.T) {
+	// check construction and use of type not in binary
+	type T string
+	ct := ChanOf(BothDir, TypeOf(T("")))
+	v := MakeChan(ct, 2)
+	runtime.GC()
+	v.Send(ValueOf(T("hello")))
+	runtime.GC()
+	v.Send(ValueOf(T("world")))
+	runtime.GC()
+
+	sv1, _ := v.Recv()
+	sv2, _ := v.Recv()
+	s1 := sv1.String()
+	s2 := sv2.String()
+	if s1 != "hello" || s2 != "world" {
+		t.Errorf("constructed chan: have %q, %q, want %q, %q", s1, s2, "hello", "world")
+	}
+
+	// check that type already in binary is found
+	type T1 int
+	checkSameType(t, Zero(ChanOf(BothDir, TypeOf(T1(1)))).Interface(), (chan T1)(nil))
+}
+
+func TestChanOfGC(t *testing.T) {
+	done := make(chan bool, 1)
+	go func() {
+		select {
+		case <-done:
+		case <-time.After(5 * time.Second):
+			panic("deadlock in TestChanOfGC")
+		}
+	}()
+
+	defer func() {
+		done <- true
+	}()
+
+	type T *uintptr
+	tt := TypeOf(T(nil))
+	ct := ChanOf(BothDir, tt)
+
+	// NOTE: The garbage collector handles allocated channels specially,
+	// so we have to save pointers to channels in x; the pointer code will
+	// use the gc info in the newly constructed chan type.
+	const n = 100
+	var x []interface{}
+	for i := 0; i < n; i++ {
+		v := MakeChan(ct, n)
+		for j := 0; j < n; j++ {
+			p := new(uintptr)
+			*p = uintptr(i*n + j)
+			v.Send(ValueOf(p).Convert(tt))
+		}
+		pv := New(ct)
+		pv.Elem().Set(v)
+		x = append(x, pv.Interface())
+	}
+	runtime.GC()
+
+	for i, xi := range x {
+		v := ValueOf(xi).Elem()
+		for j := 0; j < n; j++ {
+			pv, _ := v.Recv()
+			k := pv.Elem().Interface()
+			if k != uintptr(i*n+j) {
+				t.Errorf("lost x[%d][%d] = %d, want %d", i, j, k, i*n+j)
+			}
+		}
+	}
+}
+
+func TestMapOf(t *testing.T) {
+	// check construction and use of type not in binary
+	type K string
+	type V float64
+
+	v := MakeMap(MapOf(TypeOf(K("")), TypeOf(V(0))))
+	runtime.GC()
+	v.SetMapIndex(ValueOf(K("a")), ValueOf(V(1)))
+	runtime.GC()
+
+	s := fmt.Sprint(v.Interface())
+	want := "map[a:1]"
+	if s != want {
+		t.Errorf("constructed map = %s, want %s", s, want)
+	}
+
+	// check that type already in binary is found
+	checkSameType(t, Zero(MapOf(TypeOf(V(0)), TypeOf(K("")))).Interface(), map[V]K(nil))
+
+	// check that invalid key type panics
+	shouldPanic(func() { MapOf(TypeOf((func())(nil)), TypeOf(false)) })
+}
+
+func TestMapOfGCKeys(t *testing.T) {
+	type T *uintptr
+	tt := TypeOf(T(nil))
+	mt := MapOf(tt, TypeOf(false))
+
+	// NOTE: The garbage collector handles allocated maps specially,
+	// so we have to save pointers to maps in x; the pointer code will
+	// use the gc info in the newly constructed map type.
+	const n = 100
+	var x []interface{}
+	for i := 0; i < n; i++ {
+		v := MakeMap(mt)
+		for j := 0; j < n; j++ {
+			p := new(uintptr)
+			*p = uintptr(i*n + j)
+			v.SetMapIndex(ValueOf(p).Convert(tt), ValueOf(true))
+		}
+		pv := New(mt)
+		pv.Elem().Set(v)
+		x = append(x, pv.Interface())
+	}
+	runtime.GC()
+
+	for i, xi := range x {
+		v := ValueOf(xi).Elem()
+		var out []int
+		for _, kv := range v.MapKeys() {
+			out = append(out, int(kv.Elem().Interface().(uintptr)))
+		}
+		sort.Ints(out)
+		for j, k := range out {
+			if k != i*n+j {
+				t.Errorf("lost x[%d][%d] = %d, want %d", i, j, k, i*n+j)
+			}
+		}
+	}
+}
+
+func TestMapOfGCValues(t *testing.T) {
+	type T *uintptr
+	tt := TypeOf(T(nil))
+	mt := MapOf(TypeOf(1), tt)
+
+	// NOTE: The garbage collector handles allocated maps specially,
+	// so we have to save pointers to maps in x; the pointer code will
+	// use the gc info in the newly constructed map type.
+	const n = 100
+	var x []interface{}
+	for i := 0; i < n; i++ {
+		v := MakeMap(mt)
+		for j := 0; j < n; j++ {
+			p := new(uintptr)
+			*p = uintptr(i*n + j)
+			v.SetMapIndex(ValueOf(j), ValueOf(p).Convert(tt))
+		}
+		pv := New(mt)
+		pv.Elem().Set(v)
+		x = append(x, pv.Interface())
+	}
+	runtime.GC()
+
+	for i, xi := range x {
+		v := ValueOf(xi).Elem()
+		for j := 0; j < n; j++ {
+			k := v.MapIndex(ValueOf(j)).Elem().Interface().(uintptr)
+			if k != uintptr(i*n+j) {
+				t.Errorf("lost x[%d][%d] = %d, want %d", i, j, k, i*n+j)
+			}
+		}
+	}
+}
+
+type B1 struct {
+	X int
+	Y int
+	Z int
+}
+
+func BenchmarkFieldByName1(b *testing.B) {
+	t := TypeOf(B1{})
+	for i := 0; i < b.N; i++ {
+		t.FieldByName("Z")
+	}
+}
+
+func BenchmarkFieldByName2(b *testing.B) {
+	t := TypeOf(S3{})
+	for i := 0; i < b.N; i++ {
+		t.FieldByName("B")
+	}
+}
+
+type R0 struct {
+	*R1
+	*R2
+	*R3
+	*R4
+}
+
+type R1 struct {
+	*R5
+	*R6
+	*R7
+	*R8
+}
+
+type R2 R1
+type R3 R1
+type R4 R1
+
+type R5 struct {
+	*R9
+	*R10
+	*R11
+	*R12
+}
+
+type R6 R5
+type R7 R5
+type R8 R5
+
+type R9 struct {
+	*R13
+	*R14
+	*R15
+	*R16
+}
+
+type R10 R9
+type R11 R9
+type R12 R9
+
+type R13 struct {
+	*R17
+	*R18
+	*R19
+	*R20
+}
+
+type R14 R13
+type R15 R13
+type R16 R13
+
+type R17 struct {
+	*R21
+	*R22
+	*R23
+	*R24
+}
+
+type R18 R17
+type R19 R17
+type R20 R17
+
+type R21 struct {
+	X int
+}
+
+type R22 R21
+type R23 R21
+type R24 R21
+
+func TestEmbed(t *testing.T) {
+	typ := TypeOf(R0{})
+	f, ok := typ.FieldByName("X")
+	if ok {
+		t.Fatalf(`FieldByName("X") should fail, returned %v`, f.Index)
+	}
+}
+
+func BenchmarkFieldByName3(b *testing.B) {
+	t := TypeOf(R0{})
+	for i := 0; i < b.N; i++ {
+		t.FieldByName("X")
+	}
+}
+
+type S struct {
+	i1 int64
+	i2 int64
+}
+
+func BenchmarkInterfaceBig(b *testing.B) {
+	v := ValueOf(S{})
+	for i := 0; i < b.N; i++ {
+		v.Interface()
+	}
+	b.StopTimer()
+}
+
+func TestAllocsInterfaceBig(t *testing.T) {
+	if testing.Short() {
+		t.Skip("skipping malloc count in short mode")
+	}
+	v := ValueOf(S{})
+	if allocs := testing.AllocsPerRun(100, func() { v.Interface() }); allocs > 0 {
+		t.Error("allocs:", allocs)
+	}
+}
+
+func BenchmarkInterfaceSmall(b *testing.B) {
+	v := ValueOf(int64(0))
+	for i := 0; i < b.N; i++ {
+		v.Interface()
+	}
+}
+
+func TestAllocsInterfaceSmall(t *testing.T) {
+	if testing.Short() {
+		t.Skip("skipping malloc count in short mode")
+	}
+	v := ValueOf(int64(0))
+	if allocs := testing.AllocsPerRun(100, func() { v.Interface() }); allocs > 0 {
+		t.Error("allocs:", allocs)
+	}
+}
+
+// An exhaustive is a mechanism for writing exhaustive or stochastic tests.
+// The basic usage is:
+//
+//	for x.Next() {
+//		... code using x.Maybe() or x.Choice(n) to create test cases ...
+//	}
+//
+// Each iteration of the loop returns a different set of results, until all
+// possible result sets have been explored. It is okay for different code paths
+// to make different method call sequences on x, but there must be no
+// other source of non-determinism in the call sequences.
+//
+// When faced with a new decision, x chooses randomly. Future explorations
+// of that path will choose successive values for the result. Thus, stopping
+// the loop after a fixed number of iterations gives somewhat stochastic
+// testing.
+//
+// Example:
+//
+//	for x.Next() {
+//		v := make([]bool, x.Choose(4))
+//		for i := range v {
+//			v[i] = x.Maybe()
+//		}
+//		fmt.Println(v)
+//	}
+//
+// prints (in some order):
+//
+//	[]
+//	[false]
+//	[true]
+//	[false false]
+//	[false true]
+//	...
+//	[true true]
+//	[false false false]
+//	...
+//	[true true true]
+//	[false false false false]
+//	...
+//	[true true true true]
+//
+type exhaustive struct {
+	r    *rand.Rand
+	pos  int
+	last []choice
+}
+
+type choice struct {
+	off int
+	n   int
+	max int
+}
+
+func (x *exhaustive) Next() bool {
+	if x.r == nil {
+		x.r = rand.New(rand.NewSource(time.Now().UnixNano()))
+	}
+	x.pos = 0
+	if x.last == nil {
+		x.last = []choice{}
+		return true
+	}
+	for i := len(x.last) - 1; i >= 0; i-- {
+		c := &x.last[i]
+		if c.n+1 < c.max {
+			c.n++
+			x.last = x.last[:i+1]
+			return true
+		}
+	}
+	return false
+}
+
+func (x *exhaustive) Choose(max int) int {
+	if x.pos >= len(x.last) {
+		x.last = append(x.last, choice{x.r.Intn(max), 0, max})
+	}
+	c := &x.last[x.pos]
+	x.pos++
+	if c.max != max {
+		panic("inconsistent use of exhaustive tester")
+	}
+	return (c.n + c.off) % max
+}
+
+func (x *exhaustive) Maybe() bool {
+	return x.Choose(2) == 1
+}
+
+func GCFunc(args []Value) []Value {
+	runtime.GC()
+	return []Value{}
+}
+
+func TestReflectFuncTraceback(t *testing.T) {
+	f := MakeFunc(TypeOf(func() {}), GCFunc)
+	f.Call([]Value{})
+}
+
+func TestReflectMethodTraceback(t *testing.T) {
+	p := Point{3, 4}
+	m := ValueOf(p).MethodByName("GCMethod")
+	i := ValueOf(m.Interface()).Call([]Value{ValueOf(5)})[0].Int()
+	if i != 8 {
+		t.Errorf("Call returned %d; want 8", i)
+	}
+}
+
+func TestBigZero(t *testing.T) {
+	const size = 1 << 10
+	var v [size]byte
+	z := Zero(ValueOf(v).Type()).Interface().([size]byte)
+	for i := 0; i < size; i++ {
+		if z[i] != 0 {
+			t.Fatalf("Zero object not all zero, index %d", i)
+		}
+	}
+}
+
+func TestFieldByIndexNil(t *testing.T) {
+	type P struct {
+		F int
+	}
+	type T struct {
+		*P
+	}
+	v := ValueOf(T{})
+
+	v.FieldByName("P") // should be fine
+
+	defer func() {
+		if err := recover(); err == nil {
+			t.Fatalf("no error")
+		} else if !strings.Contains(fmt.Sprint(err), "nil pointer to embedded struct") {
+			t.Fatalf(`err=%q, wanted error containing "nil pointer to embedded struct"`, err)
+		}
+	}()
+	v.FieldByName("F") // should panic
+
+	t.Fatalf("did not panic")
+}
+
+// Given
+//	type Outer struct {
+//		*Inner
+//		...
+//	}
+// the compiler generates the implementation of (*Outer).M dispatching to the embedded Inner.
+// The implementation is logically:
+//	func (p *Outer) M() {
+//		(p.Inner).M()
+//	}
+// but since the only change here is the replacement of one pointer receiver with another,
+// the actual generated code overwrites the original receiver with the p.Inner pointer and
+// then jumps to the M method expecting the *Inner receiver.
+//
+// During reflect.Value.Call, we create an argument frame and the associated data structures
+// to describe it to the garbage collector, populate the frame, call reflect.call to
+// run a function call using that frame, and then copy the results back out of the frame.
+// The reflect.call function does a memmove of the frame structure onto the
+// stack (to set up the inputs), runs the call, and the memmoves the stack back to
+// the frame structure (to preserve the outputs).
+//
+// Originally reflect.call did not distinguish inputs from outputs: both memmoves
+// were for the full stack frame. However, in the case where the called function was
+// one of these wrappers, the rewritten receiver is almost certainly a different type
+// than the original receiver. This is not a problem on the stack, where we use the
+// program counter to determine the type information and understand that
+// during (*Outer).M the receiver is an *Outer while during (*Inner).M the receiver in the same
+// memory word is now an *Inner. But in the statically typed argument frame created
+// by reflect, the receiver is always an *Outer. Copying the modified receiver pointer
+// off the stack into the frame will store an *Inner there, and then if a garbage collection
+// happens to scan that argument frame before it is discarded, it will scan the *Inner
+// memory as if it were an *Outer. If the two have different memory layouts, the
+// collection will intepret the memory incorrectly.
+//
+// One such possible incorrect interpretation is to treat two arbitrary memory words
+// (Inner.P1 and Inner.P2 below) as an interface (Outer.R below). Because interpreting
+// an interface requires dereferencing the itab word, the misinterpretation will try to
+// deference Inner.P1, causing a crash during garbage collection.
+//
+// This came up in a real program in issue 7725.
+
+type Outer struct {
+	*Inner
+	R io.Reader
+}
+
+type Inner struct {
+	X  *Outer
+	P1 uintptr
+	P2 uintptr
+}
+
+func (pi *Inner) M() {
+	// Clear references to pi so that the only way the
+	// garbage collection will find the pointer is in the
+	// argument frame, typed as a *Outer.
+	pi.X.Inner = nil
+
+	// Set up an interface value that will cause a crash.
+	// P1 = 1 is a non-zero, so the interface looks non-nil.
+	// P2 = pi ensures that the data word points into the
+	// allocated heap; if not the collection skips the interface
+	// value as irrelevant, without dereferencing P1.
+	pi.P1 = 1
+	pi.P2 = uintptr(unsafe.Pointer(pi))
+}
+
+func TestCallMethodJump(t *testing.T) {
+	// In reflect.Value.Call, trigger a garbage collection after reflect.call
+	// returns but before the args frame has been discarded.
+	// This is a little clumsy but makes the failure repeatable.
+	*CallGC = true
+
+	p := &Outer{Inner: new(Inner)}
+	p.Inner.X = p
+	ValueOf(p).Method(0).Call(nil)
+
+	// Stop garbage collecting during reflect.call.
+	*CallGC = false
+}
+
+func TestMakeFuncStackCopy(t *testing.T) {
+	target := func(in []Value) []Value {
+		runtime.GC()
+		useStack(16)
+		return []Value{ValueOf(9)}
+	}
+
+	var concrete func(*int, int) int
+	fn := MakeFunc(ValueOf(concrete).Type(), target)
+	ValueOf(&concrete).Elem().Set(fn)
+	x := concrete(nil, 7)
+	if x != 9 {
+		t.Errorf("have %#q want 9", x)
+	}
+}
+
+// use about n KB of stack
+func useStack(n int) {
+	if n == 0 {
+		return
+	}
+	var b [1024]byte // makes frame about 1KB
+	useStack(n - 1 + int(b[99]))
+}
+
+type Impl struct{}
+
+func (Impl) f() {}
+
+func TestValueString(t *testing.T) {
+	rv := ValueOf(Impl{})
+	if rv.String() != "<reflect_test.Impl Value>" {
+		t.Errorf("ValueOf(Impl{}).String() = %q, want %q", rv.String(), "<reflect_test.Impl Value>")
+	}
+
+	method := rv.Method(0)
+	if method.String() != "<func() Value>" {
+		t.Errorf("ValueOf(Impl{}).Method(0).String() = %q, want %q", method.String(), "<func() Value>")
+	}
+}
+
+func TestInvalid(t *testing.T) {
+	// Used to have inconsistency between IsValid() and Kind() != Invalid.
+	type T struct{ v interface{} }
+
+	v := ValueOf(T{}).Field(0)
+	if v.IsValid() != true || v.Kind() != Interface {
+		t.Errorf("field: IsValid=%v, Kind=%v, want true, Interface", v.IsValid(), v.Kind())
+	}
+	v = v.Elem()
+	if v.IsValid() != false || v.Kind() != Invalid {
+		t.Errorf("field elem: IsValid=%v, Kind=%v, want false, Invalid", v.IsValid(), v.Kind())
+	}
+}
+
+// Issue 8917.
+func TestLargeGCProg(t *testing.T) {
+	fv := ValueOf(func([256]*byte) {})
+	fv.Call([]Value{ValueOf([256]*byte{})})
+}
+
+// Issue 9179.
+func TestCallGC(t *testing.T) {
+	f := func(a, b, c, d, e string) {
+	}
+	g := func(in []Value) []Value {
+		runtime.GC()
+		return nil
+	}
+	typ := ValueOf(f).Type()
+	f2 := MakeFunc(typ, g).Interface().(func(string, string, string, string, string))
+	f2("four", "five5", "six666", "seven77", "eight888")
+}
+
+type funcLayoutTest struct {
+	rcvr, t            Type
+	argsize, retOffset uintptr
+	stack              []byte
+}
+
+var funcLayoutTests []funcLayoutTest
+
+func init() {
+	var argAlign = PtrSize
+	if runtime.GOARCH == "amd64p32" {
+		argAlign = 2 * PtrSize
+	}
+	roundup := func(x uintptr, a uintptr) uintptr {
+		return (x + a - 1) / a * a
+	}
+
+	funcLayoutTests = append(funcLayoutTests,
+		funcLayoutTest{
+			nil,
+			ValueOf(func(a, b string) string { return "" }).Type(),
+			4 * PtrSize,
+			4 * PtrSize,
+			[]byte{BitsPointer, BitsScalar, BitsPointer},
+		})
+
+	var r []byte
+	if PtrSize == 4 {
+		r = []byte{BitsScalar, BitsScalar, BitsScalar, BitsPointer}
+	} else {
+		r = []byte{BitsScalar, BitsScalar, BitsPointer}
+	}
+	funcLayoutTests = append(funcLayoutTests,
+		funcLayoutTest{
+			nil,
+			ValueOf(func(a, b, c uint32, p *byte, d uint16) {}).Type(),
+			roundup(3*4, PtrSize) + PtrSize + 2,
+			roundup(roundup(3*4, PtrSize)+PtrSize+2, argAlign),
+			r,
+		})
+
+	funcLayoutTests = append(funcLayoutTests,
+		funcLayoutTest{
+			nil,
+			ValueOf(func(a map[int]int, b uintptr, c interface{}) {}).Type(),
+			4 * PtrSize,
+			4 * PtrSize,
+			[]byte{BitsPointer, BitsScalar, BitsPointer, BitsPointer},
+		})
+
+	type S struct {
+		a, b uintptr
+		c, d *byte
+	}
+	funcLayoutTests = append(funcLayoutTests,
+		funcLayoutTest{
+			nil,
+			ValueOf(func(a S) {}).Type(),
+			4 * PtrSize,
+			4 * PtrSize,
+			[]byte{BitsScalar, BitsScalar, BitsPointer, BitsPointer},
+		})
+
+	funcLayoutTests = append(funcLayoutTests,
+		funcLayoutTest{
+			ValueOf((*byte)(nil)).Type(),
+			ValueOf(func(a uintptr, b *int) {}).Type(),
+			3 * PtrSize,
+			roundup(3*PtrSize, argAlign),
+			[]byte{BitsPointer, BitsScalar, BitsPointer},
+		})
+}
+
+func TestFuncLayout(t *testing.T) {
+	for _, lt := range funcLayoutTests {
+		_, argsize, retOffset, stack := FuncLayout(lt.t, lt.rcvr)
+		if argsize != lt.argsize {
+			t.Errorf("funcLayout(%v, %v).argsize=%d, want %d", lt.t, lt.rcvr, argsize, lt.argsize)
+		}
+		if retOffset != lt.retOffset {
+			t.Errorf("funcLayout(%v, %v).retOffset=%d, want %d", lt.t, lt.rcvr, retOffset, lt.retOffset)
+		}
+		if !bytes.Equal(stack, lt.stack) {
+			t.Errorf("funcLayout(%v, %v).stack=%v, want %v", lt.t, lt.rcvr, stack, lt.stack)
+		}
+	}
+}
diff --git a/src/reflect/asm_386.s b/src/reflect/asm_386.s
new file mode 100644
index 0000000..0ffccf7
--- /dev/null
+++ b/src/reflect/asm_386.s
@@ -0,0 +1,30 @@
+// Copyright 2012 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+#include "funcdata.h"
+
+// makeFuncStub is the code half of the function returned by MakeFunc.
+// See the comment on the declaration of makeFuncStub in makefunc.go
+// for more details.
+// No argsize here, gc generates argsize info at call site.
+TEXT ·makeFuncStub(SB),(NOSPLIT|WRAPPER),$8
+	NO_LOCAL_POINTERS
+	MOVL	DX, 0(SP)
+	LEAL	argframe+0(FP), CX
+	MOVL	CX, 4(SP)
+	CALL	·callReflect(SB)
+	RET
+
+// methodValueCall is the code half of the function returned by makeMethodValue.
+// See the comment on the declaration of methodValueCall in makefunc.go
+// for more details.
+// No argsize here, gc generates argsize info at call site.
+TEXT ·methodValueCall(SB),(NOSPLIT|WRAPPER),$8
+	NO_LOCAL_POINTERS
+	MOVL	DX, 0(SP)
+	LEAL	argframe+0(FP), CX
+	MOVL	CX, 4(SP)
+	CALL	·callMethod(SB)
+	RET
diff --git a/src/reflect/asm_amd64.s b/src/reflect/asm_amd64.s
new file mode 100644
index 0000000..5a6c27a
--- /dev/null
+++ b/src/reflect/asm_amd64.s
@@ -0,0 +1,30 @@
+// Copyright 2012 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+#include "funcdata.h"
+
+// makeFuncStub is the code half of the function returned by MakeFunc.
+// See the comment on the declaration of makeFuncStub in makefunc.go
+// for more details.
+// No arg size here; runtime pulls arg map out of the func value.
+TEXT ·makeFuncStub(SB),(NOSPLIT|WRAPPER),$16
+	NO_LOCAL_POINTERS
+	MOVQ	DX, 0(SP)
+	LEAQ	argframe+0(FP), CX
+	MOVQ	CX, 8(SP)
+	CALL	·callReflect(SB)
+	RET
+
+// methodValueCall is the code half of the function returned by makeMethodValue.
+// See the comment on the declaration of methodValueCall in makefunc.go
+// for more details.
+// No arg size here; runtime pulls arg map out of the func value.
+TEXT ·methodValueCall(SB),(NOSPLIT|WRAPPER),$16
+	NO_LOCAL_POINTERS
+	MOVQ	DX, 0(SP)
+	LEAQ	argframe+0(FP), CX
+	MOVQ	CX, 8(SP)
+	CALL	·callMethod(SB)
+	RET
diff --git a/src/reflect/asm_amd64p32.s b/src/reflect/asm_amd64p32.s
new file mode 100644
index 0000000..0ffccf7
--- /dev/null
+++ b/src/reflect/asm_amd64p32.s
@@ -0,0 +1,30 @@
+// Copyright 2012 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+#include "funcdata.h"
+
+// makeFuncStub is the code half of the function returned by MakeFunc.
+// See the comment on the declaration of makeFuncStub in makefunc.go
+// for more details.
+// No argsize here, gc generates argsize info at call site.
+TEXT ·makeFuncStub(SB),(NOSPLIT|WRAPPER),$8
+	NO_LOCAL_POINTERS
+	MOVL	DX, 0(SP)
+	LEAL	argframe+0(FP), CX
+	MOVL	CX, 4(SP)
+	CALL	·callReflect(SB)
+	RET
+
+// methodValueCall is the code half of the function returned by makeMethodValue.
+// See the comment on the declaration of methodValueCall in makefunc.go
+// for more details.
+// No argsize here, gc generates argsize info at call site.
+TEXT ·methodValueCall(SB),(NOSPLIT|WRAPPER),$8
+	NO_LOCAL_POINTERS
+	MOVL	DX, 0(SP)
+	LEAL	argframe+0(FP), CX
+	MOVL	CX, 4(SP)
+	CALL	·callMethod(SB)
+	RET
diff --git a/src/reflect/asm_arm.s b/src/reflect/asm_arm.s
new file mode 100644
index 0000000..5a14c6f
--- /dev/null
+++ b/src/reflect/asm_arm.s
@@ -0,0 +1,30 @@
+// Copyright 2012 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+#include "funcdata.h"
+
+// makeFuncStub is jumped to by the code generated by MakeFunc.
+// See the comment on the declaration of makeFuncStub in makefunc.go
+// for more details.
+// No argsize here, gc generates argsize info at call site.
+TEXT ·makeFuncStub(SB),(NOSPLIT|WRAPPER),$8
+	NO_LOCAL_POINTERS
+	MOVW	R7, 4(R13)
+	MOVW	$argframe+0(FP), R1
+	MOVW	R1, 8(R13)
+	BL	·callReflect(SB)
+	RET
+
+// methodValueCall is the code half of the function returned by makeMethodValue.
+// See the comment on the declaration of methodValueCall in makefunc.go
+// for more details.
+// No argsize here, gc generates argsize info at call site.
+TEXT ·methodValueCall(SB),(NOSPLIT|WRAPPER),$8
+	NO_LOCAL_POINTERS
+	MOVW	R7, 4(R13)
+	MOVW	$argframe+0(FP), R1
+	MOVW	R1, 8(R13)
+	BL	·callMethod(SB)
+	RET
diff --git a/src/pkg/reflect/deepequal.go b/src/reflect/deepequal.go
similarity index 100%
rename from src/pkg/reflect/deepequal.go
rename to src/reflect/deepequal.go
diff --git a/src/pkg/reflect/example_test.go b/src/reflect/example_test.go
similarity index 100%
rename from src/pkg/reflect/example_test.go
rename to src/reflect/example_test.go
diff --git a/src/reflect/export_test.go b/src/reflect/export_test.go
new file mode 100644
index 0000000..caaf51a
--- /dev/null
+++ b/src/reflect/export_test.go
@@ -0,0 +1,38 @@
+// Copyright 2012 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package reflect
+
+// MakeRO returns a copy of v with the read-only flag set.
+func MakeRO(v Value) Value {
+	v.flag |= flagRO
+	return v
+}
+
+// IsRO reports whether v's read-only flag is set.
+func IsRO(v Value) bool {
+	return v.flag&flagRO != 0
+}
+
+var ArrayOf = arrayOf
+var CallGC = &callGC
+
+const PtrSize = ptrSize
+const BitsPointer = bitsPointer
+const BitsScalar = bitsScalar
+
+func FuncLayout(t Type, rcvr Type) (frametype Type, argSize, retOffset uintptr, stack []byte) {
+	var ft *rtype
+	var s *bitVector
+	if rcvr != nil {
+		ft, argSize, retOffset, s = funcLayout(t.(*rtype), rcvr.(*rtype))
+	} else {
+		ft, argSize, retOffset, s = funcLayout(t.(*rtype), nil)
+	}
+	frametype = ft
+	for i := uint32(0); i < s.n; i += 2 {
+		stack = append(stack, s.data[i/8]>>(i%8)&3)
+	}
+	return
+}
diff --git a/src/reflect/makefunc.go b/src/reflect/makefunc.go
new file mode 100644
index 0000000..d89f7f6
--- /dev/null
+++ b/src/reflect/makefunc.go
@@ -0,0 +1,129 @@
+// Copyright 2012 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// MakeFunc implementation.
+
+package reflect
+
+import (
+	"unsafe"
+)
+
+// makeFuncImpl is the closure value implementing the function
+// returned by MakeFunc.
+type makeFuncImpl struct {
+	code  uintptr
+	stack *bitVector // stack bitmap for args - offset known to runtime
+	typ   *funcType
+	fn    func([]Value) []Value
+}
+
+// MakeFunc returns a new function of the given Type
+// that wraps the function fn. When called, that new function
+// does the following:
+//
+//	- converts its arguments to a slice of Values.
+//	- runs results := fn(args).
+//	- returns the results as a slice of Values, one per formal result.
+//
+// The implementation fn can assume that the argument Value slice
+// has the number and type of arguments given by typ.
+// If typ describes a variadic function, the final Value is itself
+// a slice representing the variadic arguments, as in the
+// body of a variadic function. The result Value slice returned by fn
+// must have the number and type of results given by typ.
+//
+// The Value.Call method allows the caller to invoke a typed function
+// in terms of Values; in contrast, MakeFunc allows the caller to implement
+// a typed function in terms of Values.
+//
+// The Examples section of the documentation includes an illustration
+// of how to use MakeFunc to build a swap function for different types.
+//
+func MakeFunc(typ Type, fn func(args []Value) (results []Value)) Value {
+	if typ.Kind() != Func {
+		panic("reflect: call of MakeFunc with non-Func type")
+	}
+
+	t := typ.common()
+	ftyp := (*funcType)(unsafe.Pointer(t))
+
+	// Indirect Go func value (dummy) to obtain
+	// actual code address. (A Go func value is a pointer
+	// to a C function pointer. http://golang.org/s/go11func.)
+	dummy := makeFuncStub
+	code := **(**uintptr)(unsafe.Pointer(&dummy))
+
+	// makeFuncImpl contains a stack map for use by the runtime
+	_, _, _, stack := funcLayout(t, nil)
+
+	impl := &makeFuncImpl{code: code, stack: stack, typ: ftyp, fn: fn}
+
+	return Value{t, unsafe.Pointer(impl), flag(Func)}
+}
+
+// makeFuncStub is an assembly function that is the code half of
+// the function returned from MakeFunc. It expects a *callReflectFunc
+// as its context register, and its job is to invoke callReflect(ctxt, frame)
+// where ctxt is the context register and frame is a pointer to the first
+// word in the passed-in argument frame.
+func makeFuncStub()
+
+type methodValue struct {
+	fn     uintptr
+	stack  *bitVector // stack bitmap for args - offset known to runtime
+	method int
+	rcvr   Value
+}
+
+// makeMethodValue converts v from the rcvr+method index representation
+// of a method value to an actual method func value, which is
+// basically the receiver value with a special bit set, into a true
+// func value - a value holding an actual func. The output is
+// semantically equivalent to the input as far as the user of package
+// reflect can tell, but the true func representation can be handled
+// by code like Convert and Interface and Assign.
+func makeMethodValue(op string, v Value) Value {
+	if v.flag&flagMethod == 0 {
+		panic("reflect: internal error: invalid use of makeMethodValue")
+	}
+
+	// Ignoring the flagMethod bit, v describes the receiver, not the method type.
+	fl := v.flag & (flagRO | flagAddr | flagIndir)
+	fl |= flag(v.typ.Kind())
+	rcvr := Value{v.typ, v.ptr, fl}
+
+	// v.Type returns the actual type of the method value.
+	funcType := v.Type().(*rtype)
+
+	// Indirect Go func value (dummy) to obtain
+	// actual code address. (A Go func value is a pointer
+	// to a C function pointer. http://golang.org/s/go11func.)
+	dummy := methodValueCall
+	code := **(**uintptr)(unsafe.Pointer(&dummy))
+
+	// methodValue contains a stack map for use by the runtime
+	_, _, _, stack := funcLayout(funcType, nil)
+
+	fv := &methodValue{
+		fn:     code,
+		stack:  stack,
+		method: int(v.flag) >> flagMethodShift,
+		rcvr:   rcvr,
+	}
+
+	// Cause panic if method is not appropriate.
+	// The panic would still happen during the call if we omit this,
+	// but we want Interface() and other operations to fail early.
+	methodReceiver(op, fv.rcvr, fv.method)
+
+	return Value{funcType, unsafe.Pointer(fv), v.flag&flagRO | flag(Func)}
+}
+
+// methodValueCall is an assembly function that is the code half of
+// the function returned from makeMethodValue. It expects a *methodValue
+// as its context register, and its job is to invoke callMethod(ctxt, frame)
+// where ctxt is the context register and frame is a pointer to the first
+// word in the passed-in argument frame.
+func methodValueCall()
diff --git a/src/pkg/reflect/set_test.go b/src/reflect/set_test.go
similarity index 100%
rename from src/pkg/reflect/set_test.go
rename to src/reflect/set_test.go
diff --git a/src/pkg/reflect/tostring_test.go b/src/reflect/tostring_test.go
similarity index 100%
rename from src/pkg/reflect/tostring_test.go
rename to src/reflect/tostring_test.go
diff --git a/src/reflect/type.go b/src/reflect/type.go
new file mode 100644
index 0000000..c0ddfca
--- /dev/null
+++ b/src/reflect/type.go
@@ -0,0 +1,1929 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package reflect implements run-time reflection, allowing a program to
+// manipulate objects with arbitrary types.  The typical use is to take a value
+// with static type interface{} and extract its dynamic type information by
+// calling TypeOf, which returns a Type.
+//
+// A call to ValueOf returns a Value representing the run-time data.
+// Zero takes a Type and returns a Value representing a zero value
+// for that type.
+//
+// See "The Laws of Reflection" for an introduction to reflection in Go:
+// http://golang.org/doc/articles/laws_of_reflection.html
+package reflect
+
+import (
+	"runtime"
+	"strconv"
+	"sync"
+	"unsafe"
+)
+
+// Type is the representation of a Go type.
+//
+// Not all methods apply to all kinds of types.  Restrictions,
+// if any, are noted in the documentation for each method.
+// Use the Kind method to find out the kind of type before
+// calling kind-specific methods.  Calling a method
+// inappropriate to the kind of type causes a run-time panic.
+type Type interface {
+	// Methods applicable to all types.
+
+	// Align returns the alignment in bytes of a value of
+	// this type when allocated in memory.
+	Align() int
+
+	// FieldAlign returns the alignment in bytes of a value of
+	// this type when used as a field in a struct.
+	FieldAlign() int
+
+	// Method returns the i'th method in the type's method set.
+	// It panics if i is not in the range [0, NumMethod()).
+	//
+	// For a non-interface type T or *T, the returned Method's Type and Func
+	// fields describe a function whose first argument is the receiver.
+	//
+	// For an interface type, the returned Method's Type field gives the
+	// method signature, without a receiver, and the Func field is nil.
+	Method(int) Method
+
+	// MethodByName returns the method with that name in the type's
+	// method set and a boolean indicating if the method was found.
+	//
+	// For a non-interface type T or *T, the returned Method's Type and Func
+	// fields describe a function whose first argument is the receiver.
+	//
+	// For an interface type, the returned Method's Type field gives the
+	// method signature, without a receiver, and the Func field is nil.
+	MethodByName(string) (Method, bool)
+
+	// NumMethod returns the number of methods in the type's method set.
+	NumMethod() int
+
+	// Name returns the type's name within its package.
+	// It returns an empty string for unnamed types.
+	Name() string
+
+	// PkgPath returns a named type's package path, that is, the import path
+	// that uniquely identifies the package, such as "encoding/base64".
+	// If the type was predeclared (string, error) or unnamed (*T, struct{}, []int),
+	// the package path will be the empty string.
+	PkgPath() string
+
+	// Size returns the number of bytes needed to store
+	// a value of the given type; it is analogous to unsafe.Sizeof.
+	Size() uintptr
+
+	// String returns a string representation of the type.
+	// The string representation may use shortened package names
+	// (e.g., base64 instead of "encoding/base64") and is not
+	// guaranteed to be unique among types.  To test for equality,
+	// compare the Types directly.
+	String() string
+
+	// Kind returns the specific kind of this type.
+	Kind() Kind
+
+	// Implements returns true if the type implements the interface type u.
+	Implements(u Type) bool
+
+	// AssignableTo returns true if a value of the type is assignable to type u.
+	AssignableTo(u Type) bool
+
+	// ConvertibleTo returns true if a value of the type is convertible to type u.
+	ConvertibleTo(u Type) bool
+
+	// Comparable returns true if values of this type are comparable.
+	Comparable() bool
+
+	// Methods applicable only to some types, depending on Kind.
+	// The methods allowed for each kind are:
+	//
+	//	Int*, Uint*, Float*, Complex*: Bits
+	//	Array: Elem, Len
+	//	Chan: ChanDir, Elem
+	//	Func: In, NumIn, Out, NumOut, IsVariadic.
+	//	Map: Key, Elem
+	//	Ptr: Elem
+	//	Slice: Elem
+	//	Struct: Field, FieldByIndex, FieldByName, FieldByNameFunc, NumField
+
+	// Bits returns the size of the type in bits.
+	// It panics if the type's Kind is not one of the
+	// sized or unsized Int, Uint, Float, or Complex kinds.
+	Bits() int
+
+	// ChanDir returns a channel type's direction.
+	// It panics if the type's Kind is not Chan.
+	ChanDir() ChanDir
+
+	// IsVariadic returns true if a function type's final input parameter
+	// is a "..." parameter.  If so, t.In(t.NumIn() - 1) returns the parameter's
+	// implicit actual type []T.
+	//
+	// For concreteness, if t represents func(x int, y ... float64), then
+	//
+	//	t.NumIn() == 2
+	//	t.In(0) is the reflect.Type for "int"
+	//	t.In(1) is the reflect.Type for "[]float64"
+	//	t.IsVariadic() == true
+	//
+	// IsVariadic panics if the type's Kind is not Func.
+	IsVariadic() bool
+
+	// Elem returns a type's element type.
+	// It panics if the type's Kind is not Array, Chan, Map, Ptr, or Slice.
+	Elem() Type
+
+	// Field returns a struct type's i'th field.
+	// It panics if the type's Kind is not Struct.
+	// It panics if i is not in the range [0, NumField()).
+	Field(i int) StructField
+
+	// FieldByIndex returns the nested field corresponding
+	// to the index sequence.  It is equivalent to calling Field
+	// successively for each index i.
+	// It panics if the type's Kind is not Struct.
+	FieldByIndex(index []int) StructField
+
+	// FieldByName returns the struct field with the given name
+	// and a boolean indicating if the field was found.
+	FieldByName(name string) (StructField, bool)
+
+	// FieldByNameFunc returns the first struct field with a name
+	// that satisfies the match function and a boolean indicating if
+	// the field was found.
+	FieldByNameFunc(match func(string) bool) (StructField, bool)
+
+	// In returns the type of a function type's i'th input parameter.
+	// It panics if the type's Kind is not Func.
+	// It panics if i is not in the range [0, NumIn()).
+	In(i int) Type
+
+	// Key returns a map type's key type.
+	// It panics if the type's Kind is not Map.
+	Key() Type
+
+	// Len returns an array type's length.
+	// It panics if the type's Kind is not Array.
+	Len() int
+
+	// NumField returns a struct type's field count.
+	// It panics if the type's Kind is not Struct.
+	NumField() int
+
+	// NumIn returns a function type's input parameter count.
+	// It panics if the type's Kind is not Func.
+	NumIn() int
+
+	// NumOut returns a function type's output parameter count.
+	// It panics if the type's Kind is not Func.
+	NumOut() int
+
+	// Out returns the type of a function type's i'th output parameter.
+	// It panics if the type's Kind is not Func.
+	// It panics if i is not in the range [0, NumOut()).
+	Out(i int) Type
+
+	common() *rtype
+	uncommon() *uncommonType
+}
+
+// BUG(rsc): FieldByName and related functions consider struct field names to be equal
+// if the names are equal, even if they are unexported names originating
+// in different packages. The practical effect of this is that the result of
+// t.FieldByName("x") is not well defined if the struct type t contains
+// multiple fields named x (embedded from different packages).
+// FieldByName may return one of the fields named x or may report that there are none.
+// See golang.org/issue/4876 for more details.
+
+/*
+ * These data structures are known to the compiler (../../cmd/gc/reflect.c).
+ * A few are known to ../runtime/type.go to convey to debuggers.
+ * They are also known to ../runtime/type.h.
+ */
+
+// A Kind represents the specific kind of type that a Type represents.
+// The zero Kind is not a valid kind.
+type Kind uint
+
+const (
+	Invalid Kind = iota
+	Bool
+	Int
+	Int8
+	Int16
+	Int32
+	Int64
+	Uint
+	Uint8
+	Uint16
+	Uint32
+	Uint64
+	Uintptr
+	Float32
+	Float64
+	Complex64
+	Complex128
+	Array
+	Chan
+	Func
+	Interface
+	Map
+	Ptr
+	Slice
+	String
+	Struct
+	UnsafePointer
+)
+
+// rtype is the common implementation of most values.
+// It is embedded in other, public struct types, but always
+// with a unique tag like `reflect:"array"` or `reflect:"ptr"`
+// so that code cannot convert from, say, *arrayType to *ptrType.
+type rtype struct {
+	size          uintptr
+	hash          uint32            // hash of type; avoids computation in hash tables
+	_             uint8             // unused/padding
+	align         uint8             // alignment of variable with this type
+	fieldAlign    uint8             // alignment of struct field with this type
+	kind          uint8             // enumeration for C
+	alg           *typeAlg          // algorithm table (../runtime/runtime.h:/Alg)
+	gc            [2]unsafe.Pointer // garbage collection data
+	string        *string           // string form; unnecessary but undeniably useful
+	*uncommonType                   // (relatively) uncommon fields
+	ptrToThis     *rtype            // type for pointer to this type, if used in binary or has methods
+	zero          unsafe.Pointer    // pointer to zero value
+}
+
+type typeAlg struct {
+	// function for hashing objects of this type
+	// (ptr to object, size, seed) -> hash
+	hash func(unsafe.Pointer, uintptr, uintptr) uintptr
+	// function for comparing objects of this type
+	// (ptr to object A, ptr to object B, size) -> ==?
+	equal func(unsafe.Pointer, unsafe.Pointer, uintptr) bool
+}
+
+// Method on non-interface type
+type method struct {
+	name    *string        // name of method
+	pkgPath *string        // nil for exported Names; otherwise import path
+	mtyp    *rtype         // method type (without receiver)
+	typ     *rtype         // .(*FuncType) underneath (with receiver)
+	ifn     unsafe.Pointer // fn used in interface call (one-word receiver)
+	tfn     unsafe.Pointer // fn used for normal method call
+}
+
+// uncommonType is present only for types with names or methods
+// (if T is a named type, the uncommonTypes for T and *T have methods).
+// Using a pointer to this struct reduces the overall size required
+// to describe an unnamed type with no methods.
+type uncommonType struct {
+	name    *string  // name of type
+	pkgPath *string  // import path; nil for built-in types like int, string
+	methods []method // methods associated with type
+}
+
+// ChanDir represents a channel type's direction.
+type ChanDir int
+
+const (
+	RecvDir ChanDir             = 1 << iota // <-chan
+	SendDir                                 // chan<-
+	BothDir = RecvDir | SendDir             // chan
+)
+
+// arrayType represents a fixed array type.
+type arrayType struct {
+	rtype `reflect:"array"`
+	elem  *rtype // array element type
+	slice *rtype // slice type
+	len   uintptr
+}
+
+// chanType represents a channel type.
+type chanType struct {
+	rtype `reflect:"chan"`
+	elem  *rtype  // channel element type
+	dir   uintptr // channel direction (ChanDir)
+}
+
+// funcType represents a function type.
+type funcType struct {
+	rtype     `reflect:"func"`
+	dotdotdot bool     // last input parameter is ...
+	in        []*rtype // input parameter types
+	out       []*rtype // output parameter types
+}
+
+// imethod represents a method on an interface type
+type imethod struct {
+	name    *string // name of method
+	pkgPath *string // nil for exported Names; otherwise import path
+	typ     *rtype  // .(*FuncType) underneath
+}
+
+// interfaceType represents an interface type.
+type interfaceType struct {
+	rtype   `reflect:"interface"`
+	methods []imethod // sorted by hash
+}
+
+// mapType represents a map type.
+type mapType struct {
+	rtype         `reflect:"map"`
+	key           *rtype // map key type
+	elem          *rtype // map element (value) type
+	bucket        *rtype // internal bucket structure
+	hmap          *rtype // internal map header
+	keysize       uint8  // size of key slot
+	indirectkey   uint8  // store ptr to key instead of key itself
+	valuesize     uint8  // size of value slot
+	indirectvalue uint8  // store ptr to value instead of value itself
+	bucketsize    uint16 // size of bucket
+}
+
+// ptrType represents a pointer type.
+type ptrType struct {
+	rtype `reflect:"ptr"`
+	elem  *rtype // pointer element (pointed at) type
+}
+
+// sliceType represents a slice type.
+type sliceType struct {
+	rtype `reflect:"slice"`
+	elem  *rtype // slice element type
+}
+
+// Struct field
+type structField struct {
+	name    *string // nil for embedded fields
+	pkgPath *string // nil for exported Names; otherwise import path
+	typ     *rtype  // type of field
+	tag     *string // nil if no tag
+	offset  uintptr // byte offset of field within struct
+}
+
+// structType represents a struct type.
+type structType struct {
+	rtype  `reflect:"struct"`
+	fields []structField // sorted by offset
+}
+
+/*
+ * The compiler knows the exact layout of all the data structures above.
+ * The compiler does not know about the data structures and methods below.
+ */
+
+// Method represents a single method.
+type Method struct {
+	// Name is the method name.
+	// PkgPath is the package path that qualifies a lower case (unexported)
+	// method name.  It is empty for upper case (exported) method names.
+	// The combination of PkgPath and Name uniquely identifies a method
+	// in a method set.
+	// See http://golang.org/ref/spec#Uniqueness_of_identifiers
+	Name    string
+	PkgPath string
+
+	Type  Type  // method type
+	Func  Value // func with receiver as first argument
+	Index int   // index for Type.Method
+}
+
+const (
+	kindDirectIface = 1 << 5
+	kindGCProg      = 1 << 6 // Type.gc points to GC program
+	kindNoPointers  = 1 << 7
+	kindMask        = (1 << 5) - 1
+)
+
+func (k Kind) String() string {
+	if int(k) < len(kindNames) {
+		return kindNames[k]
+	}
+	return "kind" + strconv.Itoa(int(k))
+}
+
+var kindNames = []string{
+	Invalid:       "invalid",
+	Bool:          "bool",
+	Int:           "int",
+	Int8:          "int8",
+	Int16:         "int16",
+	Int32:         "int32",
+	Int64:         "int64",
+	Uint:          "uint",
+	Uint8:         "uint8",
+	Uint16:        "uint16",
+	Uint32:        "uint32",
+	Uint64:        "uint64",
+	Uintptr:       "uintptr",
+	Float32:       "float32",
+	Float64:       "float64",
+	Complex64:     "complex64",
+	Complex128:    "complex128",
+	Array:         "array",
+	Chan:          "chan",
+	Func:          "func",
+	Interface:     "interface",
+	Map:           "map",
+	Ptr:           "ptr",
+	Slice:         "slice",
+	String:        "string",
+	Struct:        "struct",
+	UnsafePointer: "unsafe.Pointer",
+}
+
+func (t *uncommonType) uncommon() *uncommonType {
+	return t
+}
+
+func (t *uncommonType) PkgPath() string {
+	if t == nil || t.pkgPath == nil {
+		return ""
+	}
+	return *t.pkgPath
+}
+
+func (t *uncommonType) Name() string {
+	if t == nil || t.name == nil {
+		return ""
+	}
+	return *t.name
+}
+
+func (t *rtype) String() string { return *t.string }
+
+func (t *rtype) Size() uintptr { return t.size }
+
+func (t *rtype) Bits() int {
+	if t == nil {
+		panic("reflect: Bits of nil Type")
+	}
+	k := t.Kind()
+	if k < Int || k > Complex128 {
+		panic("reflect: Bits of non-arithmetic Type " + t.String())
+	}
+	return int(t.size) * 8
+}
+
+func (t *rtype) Align() int { return int(t.align) }
+
+func (t *rtype) FieldAlign() int { return int(t.fieldAlign) }
+
+func (t *rtype) Kind() Kind { return Kind(t.kind & kindMask) }
+
+func (t *rtype) pointers() bool { return t.kind&kindNoPointers == 0 }
+
+func (t *rtype) common() *rtype { return t }
+
+func (t *uncommonType) Method(i int) (m Method) {
+	if t == nil || i < 0 || i >= len(t.methods) {
+		panic("reflect: Method index out of range")
+	}
+	p := &t.methods[i]
+	if p.name != nil {
+		m.Name = *p.name
+	}
+	fl := flag(Func)
+	if p.pkgPath != nil {
+		m.PkgPath = *p.pkgPath
+		fl |= flagRO
+	}
+	mt := p.typ
+	m.Type = mt
+	fn := unsafe.Pointer(&p.tfn)
+	m.Func = Value{mt, fn, fl}
+	m.Index = i
+	return
+}
+
+func (t *uncommonType) NumMethod() int {
+	if t == nil {
+		return 0
+	}
+	return len(t.methods)
+}
+
+func (t *uncommonType) MethodByName(name string) (m Method, ok bool) {
+	if t == nil {
+		return
+	}
+	var p *method
+	for i := range t.methods {
+		p = &t.methods[i]
+		if p.name != nil && *p.name == name {
+			return t.Method(i), true
+		}
+	}
+	return
+}
+
+// TODO(rsc): 6g supplies these, but they are not
+// as efficient as they could be: they have commonType
+// as the receiver instead of *rtype.
+func (t *rtype) NumMethod() int {
+	if t.Kind() == Interface {
+		tt := (*interfaceType)(unsafe.Pointer(t))
+		return tt.NumMethod()
+	}
+	return t.uncommonType.NumMethod()
+}
+
+func (t *rtype) Method(i int) (m Method) {
+	if t.Kind() == Interface {
+		tt := (*interfaceType)(unsafe.Pointer(t))
+		return tt.Method(i)
+	}
+	return t.uncommonType.Method(i)
+}
+
+func (t *rtype) MethodByName(name string) (m Method, ok bool) {
+	if t.Kind() == Interface {
+		tt := (*interfaceType)(unsafe.Pointer(t))
+		return tt.MethodByName(name)
+	}
+	return t.uncommonType.MethodByName(name)
+}
+
+func (t *rtype) PkgPath() string {
+	return t.uncommonType.PkgPath()
+}
+
+func (t *rtype) Name() string {
+	return t.uncommonType.Name()
+}
+
+func (t *rtype) ChanDir() ChanDir {
+	if t.Kind() != Chan {
+		panic("reflect: ChanDir of non-chan type")
+	}
+	tt := (*chanType)(unsafe.Pointer(t))
+	return ChanDir(tt.dir)
+}
+
+func (t *rtype) IsVariadic() bool {
+	if t.Kind() != Func {
+		panic("reflect: IsVariadic of non-func type")
+	}
+	tt := (*funcType)(unsafe.Pointer(t))
+	return tt.dotdotdot
+}
+
+func (t *rtype) Elem() Type {
+	switch t.Kind() {
+	case Array:
+		tt := (*arrayType)(unsafe.Pointer(t))
+		return toType(tt.elem)
+	case Chan:
+		tt := (*chanType)(unsafe.Pointer(t))
+		return toType(tt.elem)
+	case Map:
+		tt := (*mapType)(unsafe.Pointer(t))
+		return toType(tt.elem)
+	case Ptr:
+		tt := (*ptrType)(unsafe.Pointer(t))
+		return toType(tt.elem)
+	case Slice:
+		tt := (*sliceType)(unsafe.Pointer(t))
+		return toType(tt.elem)
+	}
+	panic("reflect: Elem of invalid type")
+}
+
+func (t *rtype) Field(i int) StructField {
+	if t.Kind() != Struct {
+		panic("reflect: Field of non-struct type")
+	}
+	tt := (*structType)(unsafe.Pointer(t))
+	return tt.Field(i)
+}
+
+func (t *rtype) FieldByIndex(index []int) StructField {
+	if t.Kind() != Struct {
+		panic("reflect: FieldByIndex of non-struct type")
+	}
+	tt := (*structType)(unsafe.Pointer(t))
+	return tt.FieldByIndex(index)
+}
+
+func (t *rtype) FieldByName(name string) (StructField, bool) {
+	if t.Kind() != Struct {
+		panic("reflect: FieldByName of non-struct type")
+	}
+	tt := (*structType)(unsafe.Pointer(t))
+	return tt.FieldByName(name)
+}
+
+func (t *rtype) FieldByNameFunc(match func(string) bool) (StructField, bool) {
+	if t.Kind() != Struct {
+		panic("reflect: FieldByNameFunc of non-struct type")
+	}
+	tt := (*structType)(unsafe.Pointer(t))
+	return tt.FieldByNameFunc(match)
+}
+
+func (t *rtype) In(i int) Type {
+	if t.Kind() != Func {
+		panic("reflect: In of non-func type")
+	}
+	tt := (*funcType)(unsafe.Pointer(t))
+	return toType(tt.in[i])
+}
+
+func (t *rtype) Key() Type {
+	if t.Kind() != Map {
+		panic("reflect: Key of non-map type")
+	}
+	tt := (*mapType)(unsafe.Pointer(t))
+	return toType(tt.key)
+}
+
+func (t *rtype) Len() int {
+	if t.Kind() != Array {
+		panic("reflect: Len of non-array type")
+	}
+	tt := (*arrayType)(unsafe.Pointer(t))
+	return int(tt.len)
+}
+
+func (t *rtype) NumField() int {
+	if t.Kind() != Struct {
+		panic("reflect: NumField of non-struct type")
+	}
+	tt := (*structType)(unsafe.Pointer(t))
+	return len(tt.fields)
+}
+
+func (t *rtype) NumIn() int {
+	if t.Kind() != Func {
+		panic("reflect: NumIn of non-func type")
+	}
+	tt := (*funcType)(unsafe.Pointer(t))
+	return len(tt.in)
+}
+
+func (t *rtype) NumOut() int {
+	if t.Kind() != Func {
+		panic("reflect: NumOut of non-func type")
+	}
+	tt := (*funcType)(unsafe.Pointer(t))
+	return len(tt.out)
+}
+
+func (t *rtype) Out(i int) Type {
+	if t.Kind() != Func {
+		panic("reflect: Out of non-func type")
+	}
+	tt := (*funcType)(unsafe.Pointer(t))
+	return toType(tt.out[i])
+}
+
+func (d ChanDir) String() string {
+	switch d {
+	case SendDir:
+		return "chan<-"
+	case RecvDir:
+		return "<-chan"
+	case BothDir:
+		return "chan"
+	}
+	return "ChanDir" + strconv.Itoa(int(d))
+}
+
+// Method returns the i'th method in the type's method set.
+func (t *interfaceType) Method(i int) (m Method) {
+	if i < 0 || i >= len(t.methods) {
+		return
+	}
+	p := &t.methods[i]
+	m.Name = *p.name
+	if p.pkgPath != nil {
+		m.PkgPath = *p.pkgPath
+	}
+	m.Type = toType(p.typ)
+	m.Index = i
+	return
+}
+
+// NumMethod returns the number of interface methods in the type's method set.
+func (t *interfaceType) NumMethod() int { return len(t.methods) }
+
+// MethodByName method with the given name in the type's method set.
+func (t *interfaceType) MethodByName(name string) (m Method, ok bool) {
+	if t == nil {
+		return
+	}
+	var p *imethod
+	for i := range t.methods {
+		p = &t.methods[i]
+		if *p.name == name {
+			return t.Method(i), true
+		}
+	}
+	return
+}
+
+// A StructField describes a single field in a struct.
+type StructField struct {
+	// Name is the field name.
+	// PkgPath is the package path that qualifies a lower case (unexported)
+	// field name.  It is empty for upper case (exported) field names.
+	// See http://golang.org/ref/spec#Uniqueness_of_identifiers
+	Name    string
+	PkgPath string
+
+	Type      Type      // field type
+	Tag       StructTag // field tag string
+	Offset    uintptr   // offset within struct, in bytes
+	Index     []int     // index sequence for Type.FieldByIndex
+	Anonymous bool      // is an embedded field
+}
+
+// A StructTag is the tag string in a struct field.
+//
+// By convention, tag strings are a concatenation of
+// optionally space-separated key:"value" pairs.
+// Each key is a non-empty string consisting of non-control
+// characters other than space (U+0020 ' '), quote (U+0022 '"'),
+// and colon (U+003A ':').  Each value is quoted using U+0022 '"'
+// characters and Go string literal syntax.
+type StructTag string
+
+// Get returns the value associated with key in the tag string.
+// If there is no such key in the tag, Get returns the empty string.
+// If the tag does not have the conventional format, the value
+// returned by Get is unspecified.
+func (tag StructTag) Get(key string) string {
+	for tag != "" {
+		// skip leading space
+		i := 0
+		for i < len(tag) && tag[i] == ' ' {
+			i++
+		}
+		tag = tag[i:]
+		if tag == "" {
+			break
+		}
+
+		// scan to colon.
+		// a space or a quote is a syntax error
+		i = 0
+		for i < len(tag) && tag[i] != ' ' && tag[i] != ':' && tag[i] != '"' {
+			i++
+		}
+		if i+1 >= len(tag) || tag[i] != ':' || tag[i+1] != '"' {
+			break
+		}
+		name := string(tag[:i])
+		tag = tag[i+1:]
+
+		// scan quoted string to find value
+		i = 1
+		for i < len(tag) && tag[i] != '"' {
+			if tag[i] == '\\' {
+				i++
+			}
+			i++
+		}
+		if i >= len(tag) {
+			break
+		}
+		qvalue := string(tag[:i+1])
+		tag = tag[i+1:]
+
+		if key == name {
+			value, _ := strconv.Unquote(qvalue)
+			return value
+		}
+	}
+	return ""
+}
+
+// Field returns the i'th struct field.
+func (t *structType) Field(i int) (f StructField) {
+	if i < 0 || i >= len(t.fields) {
+		return
+	}
+	p := &t.fields[i]
+	f.Type = toType(p.typ)
+	if p.name != nil {
+		f.Name = *p.name
+	} else {
+		t := f.Type
+		if t.Kind() == Ptr {
+			t = t.Elem()
+		}
+		f.Name = t.Name()
+		f.Anonymous = true
+	}
+	if p.pkgPath != nil {
+		f.PkgPath = *p.pkgPath
+	}
+	if p.tag != nil {
+		f.Tag = StructTag(*p.tag)
+	}
+	f.Offset = p.offset
+
+	// NOTE(rsc): This is the only allocation in the interface
+	// presented by a reflect.Type.  It would be nice to avoid,
+	// at least in the common cases, but we need to make sure
+	// that misbehaving clients of reflect cannot affect other
+	// uses of reflect.  One possibility is CL 5371098, but we
+	// postponed that ugliness until there is a demonstrated
+	// need for the performance.  This is issue 2320.
+	f.Index = []int{i}
+	return
+}
+
+// TODO(gri): Should there be an error/bool indicator if the index
+//            is wrong for FieldByIndex?
+
+// FieldByIndex returns the nested field corresponding to index.
+func (t *structType) FieldByIndex(index []int) (f StructField) {
+	f.Type = toType(&t.rtype)
+	for i, x := range index {
+		if i > 0 {
+			ft := f.Type
+			if ft.Kind() == Ptr && ft.Elem().Kind() == Struct {
+				ft = ft.Elem()
+			}
+			f.Type = ft
+		}
+		f = f.Type.Field(x)
+	}
+	return
+}
+
+// A fieldScan represents an item on the fieldByNameFunc scan work list.
+type fieldScan struct {
+	typ   *structType
+	index []int
+}
+
+// FieldByNameFunc returns the struct field with a name that satisfies the
+// match function and a boolean to indicate if the field was found.
+func (t *structType) FieldByNameFunc(match func(string) bool) (result StructField, ok bool) {
+	// This uses the same condition that the Go language does: there must be a unique instance
+	// of the match at a given depth level. If there are multiple instances of a match at the
+	// same depth, they annihilate each other and inhibit any possible match at a lower level.
+	// The algorithm is breadth first search, one depth level at a time.
+
+	// The current and next slices are work queues:
+	// current lists the fields to visit on this depth level,
+	// and next lists the fields on the next lower level.
+	current := []fieldScan{}
+	next := []fieldScan{{typ: t}}
+
+	// nextCount records the number of times an embedded type has been
+	// encountered and considered for queueing in the 'next' slice.
+	// We only queue the first one, but we increment the count on each.
+	// If a struct type T can be reached more than once at a given depth level,
+	// then it annihilates itself and need not be considered at all when we
+	// process that next depth level.
+	var nextCount map[*structType]int
+
+	// visited records the structs that have been considered already.
+	// Embedded pointer fields can create cycles in the graph of
+	// reachable embedded types; visited avoids following those cycles.
+	// It also avoids duplicated effort: if we didn't find the field in an
+	// embedded type T at level 2, we won't find it in one at level 4 either.
+	visited := map[*structType]bool{}
+
+	for len(next) > 0 {
+		current, next = next, current[:0]
+		count := nextCount
+		nextCount = nil
+
+		// Process all the fields at this depth, now listed in 'current'.
+		// The loop queues embedded fields found in 'next', for processing during the next
+		// iteration. The multiplicity of the 'current' field counts is recorded
+		// in 'count'; the multiplicity of the 'next' field counts is recorded in 'nextCount'.
+		for _, scan := range current {
+			t := scan.typ
+			if visited[t] {
+				// We've looked through this type before, at a higher level.
+				// That higher level would shadow the lower level we're now at,
+				// so this one can't be useful to us. Ignore it.
+				continue
+			}
+			visited[t] = true
+			for i := range t.fields {
+				f := &t.fields[i]
+				// Find name and type for field f.
+				var fname string
+				var ntyp *rtype
+				if f.name != nil {
+					fname = *f.name
+				} else {
+					// Anonymous field of type T or *T.
+					// Name taken from type.
+					ntyp = f.typ
+					if ntyp.Kind() == Ptr {
+						ntyp = ntyp.Elem().common()
+					}
+					fname = ntyp.Name()
+				}
+
+				// Does it match?
+				if match(fname) {
+					// Potential match
+					if count[t] > 1 || ok {
+						// Name appeared multiple times at this level: annihilate.
+						return StructField{}, false
+					}
+					result = t.Field(i)
+					result.Index = nil
+					result.Index = append(result.Index, scan.index...)
+					result.Index = append(result.Index, i)
+					ok = true
+					continue
+				}
+
+				// Queue embedded struct fields for processing with next level,
+				// but only if we haven't seen a match yet at this level and only
+				// if the embedded types haven't already been queued.
+				if ok || ntyp == nil || ntyp.Kind() != Struct {
+					continue
+				}
+				styp := (*structType)(unsafe.Pointer(ntyp))
+				if nextCount[styp] > 0 {
+					nextCount[styp] = 2 // exact multiple doesn't matter
+					continue
+				}
+				if nextCount == nil {
+					nextCount = map[*structType]int{}
+				}
+				nextCount[styp] = 1
+				if count[t] > 1 {
+					nextCount[styp] = 2 // exact multiple doesn't matter
+				}
+				var index []int
+				index = append(index, scan.index...)
+				index = append(index, i)
+				next = append(next, fieldScan{styp, index})
+			}
+		}
+		if ok {
+			break
+		}
+	}
+	return
+}
+
+// FieldByName returns the struct field with the given name
+// and a boolean to indicate if the field was found.
+func (t *structType) FieldByName(name string) (f StructField, present bool) {
+	// Quick check for top-level name, or struct without anonymous fields.
+	hasAnon := false
+	if name != "" {
+		for i := range t.fields {
+			tf := &t.fields[i]
+			if tf.name == nil {
+				hasAnon = true
+				continue
+			}
+			if *tf.name == name {
+				return t.Field(i), true
+			}
+		}
+	}
+	if !hasAnon {
+		return
+	}
+	return t.FieldByNameFunc(func(s string) bool { return s == name })
+}
+
+// TypeOf returns the reflection Type of the value in the interface{}.
+// TypeOf(nil) returns nil.
+func TypeOf(i interface{}) Type {
+	eface := *(*emptyInterface)(unsafe.Pointer(&i))
+	return toType(eface.typ)
+}
+
+// ptrMap is the cache for PtrTo.
+var ptrMap struct {
+	sync.RWMutex
+	m map[*rtype]*ptrType
+}
+
+// PtrTo returns the pointer type with element t.
+// For example, if t represents type Foo, PtrTo(t) represents *Foo.
+func PtrTo(t Type) Type {
+	return t.(*rtype).ptrTo()
+}
+
+func (t *rtype) ptrTo() *rtype {
+	if p := t.ptrToThis; p != nil {
+		return p
+	}
+
+	// Otherwise, synthesize one.
+	// This only happens for pointers with no methods.
+	// We keep the mapping in a map on the side, because
+	// this operation is rare and a separate map lets us keep
+	// the type structures in read-only memory.
+	ptrMap.RLock()
+	if m := ptrMap.m; m != nil {
+		if p := m[t]; p != nil {
+			ptrMap.RUnlock()
+			return &p.rtype
+		}
+	}
+	ptrMap.RUnlock()
+	ptrMap.Lock()
+	if ptrMap.m == nil {
+		ptrMap.m = make(map[*rtype]*ptrType)
+	}
+	p := ptrMap.m[t]
+	if p != nil {
+		// some other goroutine won the race and created it
+		ptrMap.Unlock()
+		return &p.rtype
+	}
+
+	// Create a new ptrType starting with the description
+	// of an *unsafe.Pointer.
+	p = new(ptrType)
+	var iptr interface{} = (*unsafe.Pointer)(nil)
+	prototype := *(**ptrType)(unsafe.Pointer(&iptr))
+	*p = *prototype
+
+	s := "*" + *t.string
+	p.string = &s
+
+	// For the type structures linked into the binary, the
+	// compiler provides a good hash of the string.
+	// Create a good hash for the new string by using
+	// the FNV-1 hash's mixing function to combine the
+	// old hash and the new "*".
+	p.hash = fnv1(t.hash, '*')
+
+	p.uncommonType = nil
+	p.ptrToThis = nil
+	p.zero = unsafe.Pointer(&make([]byte, p.size)[0])
+	p.elem = t
+
+	ptrMap.m[t] = p
+	ptrMap.Unlock()
+	return &p.rtype
+}
+
+// fnv1 incorporates the list of bytes into the hash x using the FNV-1 hash function.
+func fnv1(x uint32, list ...byte) uint32 {
+	for _, b := range list {
+		x = x*16777619 ^ uint32(b)
+	}
+	return x
+}
+
+func (t *rtype) Implements(u Type) bool {
+	if u == nil {
+		panic("reflect: nil type passed to Type.Implements")
+	}
+	if u.Kind() != Interface {
+		panic("reflect: non-interface type passed to Type.Implements")
+	}
+	return implements(u.(*rtype), t)
+}
+
+func (t *rtype) AssignableTo(u Type) bool {
+	if u == nil {
+		panic("reflect: nil type passed to Type.AssignableTo")
+	}
+	uu := u.(*rtype)
+	return directlyAssignable(uu, t) || implements(uu, t)
+}
+
+func (t *rtype) ConvertibleTo(u Type) bool {
+	if u == nil {
+		panic("reflect: nil type passed to Type.ConvertibleTo")
+	}
+	uu := u.(*rtype)
+	return convertOp(uu, t) != nil
+}
+
+func (t *rtype) Comparable() bool {
+	return t.alg != nil && t.alg.equal != nil
+}
+
+// implements returns true if the type V implements the interface type T.
+func implements(T, V *rtype) bool {
+	if T.Kind() != Interface {
+		return false
+	}
+	t := (*interfaceType)(unsafe.Pointer(T))
+	if len(t.methods) == 0 {
+		return true
+	}
+
+	// The same algorithm applies in both cases, but the
+	// method tables for an interface type and a concrete type
+	// are different, so the code is duplicated.
+	// In both cases the algorithm is a linear scan over the two
+	// lists - T's methods and V's methods - simultaneously.
+	// Since method tables are stored in a unique sorted order
+	// (alphabetical, with no duplicate method names), the scan
+	// through V's methods must hit a match for each of T's
+	// methods along the way, or else V does not implement T.
+	// This lets us run the scan in overall linear time instead of
+	// the quadratic time  a naive search would require.
+	// See also ../runtime/iface.c.
+	if V.Kind() == Interface {
+		v := (*interfaceType)(unsafe.Pointer(V))
+		i := 0
+		for j := 0; j < len(v.methods); j++ {
+			tm := &t.methods[i]
+			vm := &v.methods[j]
+			if vm.name == tm.name && vm.pkgPath == tm.pkgPath && vm.typ == tm.typ {
+				if i++; i >= len(t.methods) {
+					return true
+				}
+			}
+		}
+		return false
+	}
+
+	v := V.uncommon()
+	if v == nil {
+		return false
+	}
+	i := 0
+	for j := 0; j < len(v.methods); j++ {
+		tm := &t.methods[i]
+		vm := &v.methods[j]
+		if vm.name == tm.name && vm.pkgPath == tm.pkgPath && vm.mtyp == tm.typ {
+			if i++; i >= len(t.methods) {
+				return true
+			}
+		}
+	}
+	return false
+}
+
+// directlyAssignable returns true if a value x of type V can be directly
+// assigned (using memmove) to a value of type T.
+// http://golang.org/doc/go_spec.html#Assignability
+// Ignoring the interface rules (implemented elsewhere)
+// and the ideal constant rules (no ideal constants at run time).
+func directlyAssignable(T, V *rtype) bool {
+	// x's type V is identical to T?
+	if T == V {
+		return true
+	}
+
+	// Otherwise at least one of T and V must be unnamed
+	// and they must have the same kind.
+	if T.Name() != "" && V.Name() != "" || T.Kind() != V.Kind() {
+		return false
+	}
+
+	// x's type T and V must  have identical underlying types.
+	return haveIdenticalUnderlyingType(T, V)
+}
+
+func haveIdenticalUnderlyingType(T, V *rtype) bool {
+	if T == V {
+		return true
+	}
+
+	kind := T.Kind()
+	if kind != V.Kind() {
+		return false
+	}
+
+	// Non-composite types of equal kind have same underlying type
+	// (the predefined instance of the type).
+	if Bool <= kind && kind <= Complex128 || kind == String || kind == UnsafePointer {
+		return true
+	}
+
+	// Composite types.
+	switch kind {
+	case Array:
+		return T.Elem() == V.Elem() && T.Len() == V.Len()
+
+	case Chan:
+		// Special case:
+		// x is a bidirectional channel value, T is a channel type,
+		// and x's type V and T have identical element types.
+		if V.ChanDir() == BothDir && T.Elem() == V.Elem() {
+			return true
+		}
+
+		// Otherwise continue test for identical underlying type.
+		return V.ChanDir() == T.ChanDir() && T.Elem() == V.Elem()
+
+	case Func:
+		t := (*funcType)(unsafe.Pointer(T))
+		v := (*funcType)(unsafe.Pointer(V))
+		if t.dotdotdot != v.dotdotdot || len(t.in) != len(v.in) || len(t.out) != len(v.out) {
+			return false
+		}
+		for i, typ := range t.in {
+			if typ != v.in[i] {
+				return false
+			}
+		}
+		for i, typ := range t.out {
+			if typ != v.out[i] {
+				return false
+			}
+		}
+		return true
+
+	case Interface:
+		t := (*interfaceType)(unsafe.Pointer(T))
+		v := (*interfaceType)(unsafe.Pointer(V))
+		if len(t.methods) == 0 && len(v.methods) == 0 {
+			return true
+		}
+		// Might have the same methods but still
+		// need a run time conversion.
+		return false
+
+	case Map:
+		return T.Key() == V.Key() && T.Elem() == V.Elem()
+
+	case Ptr, Slice:
+		return T.Elem() == V.Elem()
+
+	case Struct:
+		t := (*structType)(unsafe.Pointer(T))
+		v := (*structType)(unsafe.Pointer(V))
+		if len(t.fields) != len(v.fields) {
+			return false
+		}
+		for i := range t.fields {
+			tf := &t.fields[i]
+			vf := &v.fields[i]
+			if tf.name != vf.name && (tf.name == nil || vf.name == nil || *tf.name != *vf.name) {
+				return false
+			}
+			if tf.pkgPath != vf.pkgPath && (tf.pkgPath == nil || vf.pkgPath == nil || *tf.pkgPath != *vf.pkgPath) {
+				return false
+			}
+			if tf.typ != vf.typ {
+				return false
+			}
+			if tf.tag != vf.tag && (tf.tag == nil || vf.tag == nil || *tf.tag != *vf.tag) {
+				return false
+			}
+			if tf.offset != vf.offset {
+				return false
+			}
+		}
+		return true
+	}
+
+	return false
+}
+
+// typelinks is implemented in package runtime.
+// It returns a slice of all the 'typelink' information in the binary,
+// which is to say a slice of known types, sorted by string.
+// Note that strings are not unique identifiers for types:
+// there can be more than one with a given string.
+// Only types we might want to look up are included:
+// channels, maps, slices, and arrays.
+func typelinks() []*rtype
+
+// typesByString returns the subslice of typelinks() whose elements have
+// the given string representation.
+// It may be empty (no known types with that string) or may have
+// multiple elements (multiple types with that string).
+func typesByString(s string) []*rtype {
+	typ := typelinks()
+
+	// We are looking for the first index i where the string becomes >= s.
+	// This is a copy of sort.Search, with f(h) replaced by (*typ[h].string >= s).
+	i, j := 0, len(typ)
+	for i < j {
+		h := i + (j-i)/2 // avoid overflow when computing h
+		// i ≤ h < j
+		if !(*typ[h].string >= s) {
+			i = h + 1 // preserves f(i-1) == false
+		} else {
+			j = h // preserves f(j) == true
+		}
+	}
+	// i == j, f(i-1) == false, and f(j) (= f(i)) == true  =>  answer is i.
+
+	// Having found the first, linear scan forward to find the last.
+	// We could do a second binary search, but the caller is going
+	// to do a linear scan anyway.
+	j = i
+	for j < len(typ) && *typ[j].string == s {
+		j++
+	}
+
+	// This slice will be empty if the string is not found.
+	return typ[i:j]
+}
+
+// The lookupCache caches ChanOf, MapOf, and SliceOf lookups.
+var lookupCache struct {
+	sync.RWMutex
+	m map[cacheKey]*rtype
+}
+
+// A cacheKey is the key for use in the lookupCache.
+// Four values describe any of the types we are looking for:
+// type kind, one or two subtypes, and an extra integer.
+type cacheKey struct {
+	kind  Kind
+	t1    *rtype
+	t2    *rtype
+	extra uintptr
+}
+
+// cacheGet looks for a type under the key k in the lookupCache.
+// If it finds one, it returns that type.
+// If not, it returns nil with the cache locked.
+// The caller is expected to use cachePut to unlock the cache.
+func cacheGet(k cacheKey) Type {
+	lookupCache.RLock()
+	t := lookupCache.m[k]
+	lookupCache.RUnlock()
+	if t != nil {
+		return t
+	}
+
+	lookupCache.Lock()
+	t = lookupCache.m[k]
+	if t != nil {
+		lookupCache.Unlock()
+		return t
+	}
+
+	if lookupCache.m == nil {
+		lookupCache.m = make(map[cacheKey]*rtype)
+	}
+
+	return nil
+}
+
+// cachePut stores the given type in the cache, unlocks the cache,
+// and returns the type. It is expected that the cache is locked
+// because cacheGet returned nil.
+func cachePut(k cacheKey, t *rtype) Type {
+	lookupCache.m[k] = t
+	lookupCache.Unlock()
+	return t
+}
+
+// ChanOf returns the channel type with the given direction and element type.
+// For example, if t represents int, ChanOf(RecvDir, t) represents <-chan int.
+//
+// The gc runtime imposes a limit of 64 kB on channel element types.
+// If t's size is equal to or exceeds this limit, ChanOf panics.
+func ChanOf(dir ChanDir, t Type) Type {
+	typ := t.(*rtype)
+
+	// Look in cache.
+	ckey := cacheKey{Chan, typ, nil, uintptr(dir)}
+	if ch := cacheGet(ckey); ch != nil {
+		return ch
+	}
+
+	// This restriction is imposed by the gc compiler and the runtime.
+	if typ.size >= 1<<16 {
+		lookupCache.Unlock()
+		panic("reflect.ChanOf: element size too large")
+	}
+
+	// Look in known types.
+	// TODO: Precedence when constructing string.
+	var s string
+	switch dir {
+	default:
+		lookupCache.Unlock()
+		panic("reflect.ChanOf: invalid dir")
+	case SendDir:
+		s = "chan<- " + *typ.string
+	case RecvDir:
+		s = "<-chan " + *typ.string
+	case BothDir:
+		s = "chan " + *typ.string
+	}
+	for _, tt := range typesByString(s) {
+		ch := (*chanType)(unsafe.Pointer(tt))
+		if ch.elem == typ && ch.dir == uintptr(dir) {
+			return cachePut(ckey, tt)
+		}
+	}
+
+	// Make a channel type.
+	var ichan interface{} = (chan unsafe.Pointer)(nil)
+	prototype := *(**chanType)(unsafe.Pointer(&ichan))
+	ch := new(chanType)
+	*ch = *prototype
+	ch.string = &s
+	ch.hash = fnv1(typ.hash, 'c', byte(dir))
+	ch.elem = typ
+	ch.uncommonType = nil
+	ch.ptrToThis = nil
+	ch.zero = unsafe.Pointer(&make([]byte, ch.size)[0])
+
+	return cachePut(ckey, &ch.rtype)
+}
+
+func ismapkey(*rtype) bool // implemented in runtime
+
+// MapOf returns the map type with the given key and element types.
+// For example, if k represents int and e represents string,
+// MapOf(k, e) represents map[int]string.
+//
+// If the key type is not a valid map key type (that is, if it does
+// not implement Go's == operator), MapOf panics.
+func MapOf(key, elem Type) Type {
+	ktyp := key.(*rtype)
+	etyp := elem.(*rtype)
+
+	if !ismapkey(ktyp) {
+		panic("reflect.MapOf: invalid key type " + ktyp.String())
+	}
+
+	// Look in cache.
+	ckey := cacheKey{Map, ktyp, etyp, 0}
+	if mt := cacheGet(ckey); mt != nil {
+		return mt
+	}
+
+	// Look in known types.
+	s := "map[" + *ktyp.string + "]" + *etyp.string
+	for _, tt := range typesByString(s) {
+		mt := (*mapType)(unsafe.Pointer(tt))
+		if mt.key == ktyp && mt.elem == etyp {
+			return cachePut(ckey, tt)
+		}
+	}
+
+	// Make a map type.
+	var imap interface{} = (map[unsafe.Pointer]unsafe.Pointer)(nil)
+	prototype := *(**mapType)(unsafe.Pointer(&imap))
+	mt := new(mapType)
+	*mt = *prototype
+	mt.string = &s
+	mt.hash = fnv1(etyp.hash, 'm', byte(ktyp.hash>>24), byte(ktyp.hash>>16), byte(ktyp.hash>>8), byte(ktyp.hash))
+	mt.key = ktyp
+	mt.elem = etyp
+	mt.bucket = bucketOf(ktyp, etyp)
+	if ktyp.size > maxKeySize {
+		mt.keysize = uint8(ptrSize)
+		mt.indirectkey = 1
+	} else {
+		mt.keysize = uint8(ktyp.size)
+		mt.indirectkey = 0
+	}
+	if etyp.size > maxValSize {
+		mt.valuesize = uint8(ptrSize)
+		mt.indirectvalue = 1
+	} else {
+		mt.valuesize = uint8(etyp.size)
+		mt.indirectvalue = 0
+	}
+	mt.bucketsize = uint16(mt.bucket.size)
+	mt.uncommonType = nil
+	mt.ptrToThis = nil
+	mt.zero = unsafe.Pointer(&make([]byte, mt.size)[0])
+
+	return cachePut(ckey, &mt.rtype)
+}
+
+// gcProg is a helper type for generatation of GC pointer info.
+type gcProg struct {
+	gc   []byte
+	size uintptr // size of type in bytes
+}
+
+func (gc *gcProg) append(v byte) {
+	gc.align(unsafe.Sizeof(uintptr(0)))
+	gc.appendWord(v)
+}
+
+// Appends t's type info to the current program.
+func (gc *gcProg) appendProg(t *rtype) {
+	gc.align(uintptr(t.align))
+	if !t.pointers() {
+		gc.size += t.size
+		return
+	}
+	switch t.Kind() {
+	default:
+		panic("reflect: non-pointer type marked as having pointers")
+	case Ptr, UnsafePointer, Chan, Func, Map:
+		gc.appendWord(bitsPointer)
+	case Slice:
+		gc.appendWord(bitsPointer)
+		gc.appendWord(bitsScalar)
+		gc.appendWord(bitsScalar)
+	case String:
+		gc.appendWord(bitsPointer)
+		gc.appendWord(bitsScalar)
+	case Array:
+		c := t.Len()
+		e := t.Elem().common()
+		for i := 0; i < c; i++ {
+			gc.appendProg(e)
+		}
+	case Interface:
+		gc.appendWord(bitsMultiWord)
+		if t.NumMethod() == 0 {
+			gc.appendWord(bitsEface)
+		} else {
+			gc.appendWord(bitsIface)
+		}
+	case Struct:
+		c := t.NumField()
+		for i := 0; i < c; i++ {
+			gc.appendProg(t.Field(i).Type.common())
+		}
+		gc.align(uintptr(t.align))
+	}
+}
+
+func (gc *gcProg) appendWord(v byte) {
+	ptrsize := unsafe.Sizeof(uintptr(0))
+	if gc.size%ptrsize != 0 {
+		panic("reflect: unaligned GC program")
+	}
+	nptr := gc.size / ptrsize
+	for uintptr(len(gc.gc)) < nptr/2+1 {
+		gc.gc = append(gc.gc, 0x44) // BitsScalar
+	}
+	gc.gc[nptr/2] &= ^(3 << ((nptr%2)*4 + 2))
+	gc.gc[nptr/2] |= v << ((nptr%2)*4 + 2)
+	gc.size += ptrsize
+}
+
+func (gc *gcProg) finalize() unsafe.Pointer {
+	if gc.size == 0 {
+		return nil
+	}
+	ptrsize := unsafe.Sizeof(uintptr(0))
+	gc.align(ptrsize)
+	nptr := gc.size / ptrsize
+	for uintptr(len(gc.gc)) < nptr/2+1 {
+		gc.gc = append(gc.gc, 0x44) // BitsScalar
+	}
+	// If number of words is odd, repeat the mask twice.
+	// Compiler does the same.
+	if nptr%2 != 0 {
+		for i := uintptr(0); i < nptr; i++ {
+			gc.appendWord(extractGCWord(gc.gc, i))
+		}
+	}
+	return unsafe.Pointer(&gc.gc[0])
+}
+
+func extractGCWord(gc []byte, i uintptr) byte {
+	return (gc[i/2] >> ((i%2)*4 + 2)) & 3
+}
+
+func (gc *gcProg) align(a uintptr) {
+	gc.size = align(gc.size, a)
+}
+
+// These constants must stay in sync with ../runtime/mgc0.h.
+const (
+	bitsScalar    = 1
+	bitsPointer   = 2
+	bitsMultiWord = 3
+
+	bitsIface = 2
+	bitsEface = 3
+)
+
+// Make sure these routines stay in sync with ../../runtime/hashmap.go!
+// These types exist only for GC, so we only fill out GC relevant info.
+// Currently, that's just size and the GC program.  We also fill in string
+// for possible debugging use.
+const (
+	bucketSize = 8
+	maxKeySize = 128
+	maxValSize = 128
+)
+
+func bucketOf(ktyp, etyp *rtype) *rtype {
+	if ktyp.size > maxKeySize {
+		ktyp = PtrTo(ktyp).(*rtype)
+	}
+	if etyp.size > maxValSize {
+		etyp = PtrTo(etyp).(*rtype)
+	}
+	ptrsize := unsafe.Sizeof(uintptr(0))
+
+	var gc gcProg
+	// topbits
+	for i := 0; i < int(bucketSize*unsafe.Sizeof(uint8(0))/ptrsize); i++ {
+		gc.append(bitsScalar)
+	}
+	gc.append(bitsPointer) // overflow
+	if runtime.GOARCH == "amd64p32" {
+		gc.append(bitsScalar)
+	}
+	// keys
+	for i := 0; i < bucketSize; i++ {
+		gc.appendProg(ktyp)
+	}
+	// values
+	for i := 0; i < bucketSize; i++ {
+		gc.appendProg(etyp)
+	}
+
+	b := new(rtype)
+	b.size = gc.size
+	b.gc[0] = gc.finalize()
+	s := "bucket(" + *ktyp.string + "," + *etyp.string + ")"
+	b.string = &s
+	return b
+}
+
+// SliceOf returns the slice type with element type t.
+// For example, if t represents int, SliceOf(t) represents []int.
+func SliceOf(t Type) Type {
+	typ := t.(*rtype)
+
+	// Look in cache.
+	ckey := cacheKey{Slice, typ, nil, 0}
+	if slice := cacheGet(ckey); slice != nil {
+		return slice
+	}
+
+	// Look in known types.
+	s := "[]" + *typ.string
+	for _, tt := range typesByString(s) {
+		slice := (*sliceType)(unsafe.Pointer(tt))
+		if slice.elem == typ {
+			return cachePut(ckey, tt)
+		}
+	}
+
+	// Make a slice type.
+	var islice interface{} = ([]unsafe.Pointer)(nil)
+	prototype := *(**sliceType)(unsafe.Pointer(&islice))
+	slice := new(sliceType)
+	*slice = *prototype
+	slice.string = &s
+	slice.hash = fnv1(typ.hash, '[')
+	slice.elem = typ
+	slice.uncommonType = nil
+	slice.ptrToThis = nil
+	slice.zero = unsafe.Pointer(&make([]byte, slice.size)[0])
+
+	return cachePut(ckey, &slice.rtype)
+}
+
+// ArrayOf returns the array type with the given count and element type.
+// For example, if t represents int, ArrayOf(5, t) represents [5]int.
+//
+// If the resulting type would be larger than the available address space,
+// ArrayOf panics.
+//
+// TODO(rsc): Unexported for now. Export once the alg field is set correctly
+// for the type. This may require significant work.
+//
+// TODO(rsc): TestArrayOf is also disabled. Re-enable.
+func arrayOf(count int, elem Type) Type {
+	typ := elem.(*rtype)
+	slice := SliceOf(elem)
+
+	// Look in cache.
+	ckey := cacheKey{Array, typ, nil, uintptr(count)}
+	if slice := cacheGet(ckey); slice != nil {
+		return slice
+	}
+
+	// Look in known types.
+	s := "[" + strconv.Itoa(count) + "]" + *typ.string
+	for _, tt := range typesByString(s) {
+		slice := (*sliceType)(unsafe.Pointer(tt))
+		if slice.elem == typ {
+			return cachePut(ckey, tt)
+		}
+	}
+
+	// Make an array type.
+	var iarray interface{} = [1]unsafe.Pointer{}
+	prototype := *(**arrayType)(unsafe.Pointer(&iarray))
+	array := new(arrayType)
+	*array = *prototype
+	// TODO: Set extra kind bits correctly.
+	array.string = &s
+	array.hash = fnv1(typ.hash, '[')
+	for n := uint32(count); n > 0; n >>= 8 {
+		array.hash = fnv1(array.hash, byte(n))
+	}
+	array.hash = fnv1(array.hash, ']')
+	array.elem = typ
+	max := ^uintptr(0) / typ.size
+	if uintptr(count) > max {
+		panic("reflect.ArrayOf: array size would exceed virtual address space")
+	}
+	array.size = typ.size * uintptr(count)
+	array.align = typ.align
+	array.fieldAlign = typ.fieldAlign
+	// TODO: array.alg
+	// TODO: array.gc
+	// TODO:
+	array.uncommonType = nil
+	array.ptrToThis = nil
+	array.zero = unsafe.Pointer(&make([]byte, array.size)[0])
+	array.len = uintptr(count)
+	array.slice = slice.(*rtype)
+
+	return cachePut(ckey, &array.rtype)
+}
+
+// toType converts from a *rtype to a Type that can be returned
+// to the client of package reflect. In gc, the only concern is that
+// a nil *rtype must be replaced by a nil Type, but in gccgo this
+// function takes care of ensuring that multiple *rtype for the same
+// type are coalesced into a single Type.
+func toType(t *rtype) Type {
+	if t == nil {
+		return nil
+	}
+	return t
+}
+
+type layoutKey struct {
+	t    *rtype // function signature
+	rcvr *rtype // receiver type, or nil if none
+}
+
+type layoutType struct {
+	t         *rtype
+	argSize   uintptr // size of arguments
+	retOffset uintptr // offset of return values.
+	stack     *bitVector
+}
+
+var layoutCache struct {
+	sync.RWMutex
+	m map[layoutKey]layoutType
+}
+
+// funcLayout computes a struct type representing the layout of the
+// function arguments and return values for the function type t.
+// If rcvr != nil, rcvr specifies the type of the receiver.
+// The returned type exists only for GC, so we only fill out GC relevant info.
+// Currently, that's just size and the GC program.  We also fill in
+// the name for possible debugging use.
+func funcLayout(t *rtype, rcvr *rtype) (frametype *rtype, argSize, retOffset uintptr, stack *bitVector) {
+	if t.Kind() != Func {
+		panic("reflect: funcLayout of non-func type")
+	}
+	if rcvr != nil && rcvr.Kind() == Interface {
+		panic("reflect: funcLayout with interface receiver " + rcvr.String())
+	}
+	k := layoutKey{t, rcvr}
+	layoutCache.RLock()
+	if x := layoutCache.m[k]; x.t != nil {
+		layoutCache.RUnlock()
+		return x.t, x.argSize, x.retOffset, x.stack
+	}
+	layoutCache.RUnlock()
+	layoutCache.Lock()
+	if x := layoutCache.m[k]; x.t != nil {
+		layoutCache.Unlock()
+		return x.t, x.argSize, x.retOffset, x.stack
+	}
+
+	tt := (*funcType)(unsafe.Pointer(t))
+
+	// compute gc program & stack bitmap for arguments
+	stack = new(bitVector)
+	var gc gcProg
+	var offset uintptr
+	if rcvr != nil {
+		// Reflect uses the "interface" calling convention for
+		// methods, where receivers take one word of argument
+		// space no matter how big they actually are.
+		if ifaceIndir(rcvr) {
+			// we pass a pointer to the receiver.
+			gc.append(bitsPointer)
+			stack.append2(bitsPointer)
+		} else if rcvr.pointers() {
+			// rcvr is a one-word pointer object.  Its gc program
+			// is just what we need here.
+			gc.append(bitsPointer)
+			stack.append2(bitsPointer)
+		} else {
+			gc.append(bitsScalar)
+			stack.append2(bitsScalar)
+		}
+		offset += ptrSize
+	}
+	for _, arg := range tt.in {
+		gc.appendProg(arg)
+		addTypeBits(stack, &offset, arg)
+	}
+	argSize = gc.size
+	if runtime.GOARCH == "amd64p32" {
+		gc.align(8)
+	}
+	gc.align(ptrSize)
+	retOffset = gc.size
+	for _, res := range tt.out {
+		gc.appendProg(res)
+		// stack map does not need result bits
+	}
+	gc.align(ptrSize)
+
+	// build dummy rtype holding gc program
+	x := new(rtype)
+	x.size = gc.size
+	x.gc[0] = gc.finalize()
+	var s string
+	if rcvr != nil {
+		s = "methodargs(" + *rcvr.string + ")(" + *t.string + ")"
+	} else {
+		s = "funcargs(" + *t.string + ")"
+	}
+	x.string = &s
+
+	// cache result for future callers
+	if layoutCache.m == nil {
+		layoutCache.m = make(map[layoutKey]layoutType)
+	}
+	layoutCache.m[k] = layoutType{
+		t:         x,
+		argSize:   argSize,
+		retOffset: retOffset,
+		stack:     stack,
+	}
+	layoutCache.Unlock()
+	return x, argSize, retOffset, stack
+}
+
+// ifaceIndir reports whether t is stored indirectly in an interface value.
+func ifaceIndir(t *rtype) bool {
+	return t.kind&kindDirectIface == 0
+}
+
+// Layout matches runtime.BitVector (well enough).
+type bitVector struct {
+	n    uint32 // number of bits
+	data []byte
+}
+
+// append a bit pair to the bitmap.
+func (bv *bitVector) append2(bits uint8) {
+	// assume bv.n is a multiple of 2, since append2 is the only operation.
+	if bv.n%8 == 0 {
+		bv.data = append(bv.data, 0)
+	}
+	bv.data[bv.n/8] |= bits << (bv.n % 8)
+	bv.n += 2
+}
+
+func addTypeBits(bv *bitVector, offset *uintptr, t *rtype) {
+	*offset = align(*offset, uintptr(t.align))
+	if t.kind&kindNoPointers != 0 {
+		*offset += t.size
+		return
+	}
+
+	switch Kind(t.kind & kindMask) {
+	case Chan, Func, Map, Ptr, Slice, String, UnsafePointer:
+		// 1 pointer at start of representation
+		for bv.n < 2*uint32(*offset/uintptr(ptrSize)) {
+			bv.append2(bitsScalar)
+		}
+		bv.append2(bitsPointer)
+
+	case Interface:
+		// 2 pointers
+		for bv.n < 2*uint32(*offset/uintptr(ptrSize)) {
+			bv.append2(bitsScalar)
+		}
+		bv.append2(bitsPointer)
+		bv.append2(bitsPointer)
+
+	case Array:
+		// repeat inner type
+		tt := (*arrayType)(unsafe.Pointer(t))
+		for i := 0; i < int(tt.len); i++ {
+			addTypeBits(bv, offset, tt.elem)
+		}
+
+	case Struct:
+		// apply fields
+		tt := (*structType)(unsafe.Pointer(t))
+		start := *offset
+		for i := range tt.fields {
+			f := &tt.fields[i]
+			off := start + f.offset
+			addTypeBits(bv, &off, f.typ)
+		}
+	}
+
+	*offset += t.size
+}
diff --git a/src/reflect/value.go b/src/reflect/value.go
new file mode 100644
index 0000000..43843e9
--- /dev/null
+++ b/src/reflect/value.go
@@ -0,0 +1,2443 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package reflect
+
+import (
+	"math"
+	"runtime"
+	"unsafe"
+)
+
+const ptrSize = unsafe.Sizeof((*byte)(nil))
+const cannotSet = "cannot set value obtained from unexported struct field"
+
+// Value is the reflection interface to a Go value.
+//
+// Not all methods apply to all kinds of values.  Restrictions,
+// if any, are noted in the documentation for each method.
+// Use the Kind method to find out the kind of value before
+// calling kind-specific methods.  Calling a method
+// inappropriate to the kind of type causes a run time panic.
+//
+// The zero Value represents no value.
+// Its IsValid method returns false, its Kind method returns Invalid,
+// its String method returns "<invalid Value>", and all other methods panic.
+// Most functions and methods never return an invalid value.
+// If one does, its documentation states the conditions explicitly.
+//
+// A Value can be used concurrently by multiple goroutines provided that
+// the underlying Go value can be used concurrently for the equivalent
+// direct operations.
+type Value struct {
+	// typ holds the type of the value represented by a Value.
+	typ *rtype
+
+	// Pointer-valued data or, if flagIndir is set, pointer to data.
+	// Valid when either flagIndir is set or typ.pointers() is true.
+	ptr unsafe.Pointer
+
+	// flag holds metadata about the value.
+	// The lowest bits are flag bits:
+	//	- flagRO: obtained via unexported field, so read-only
+	//	- flagIndir: val holds a pointer to the data
+	//	- flagAddr: v.CanAddr is true (implies flagIndir)
+	//	- flagMethod: v is a method value.
+	// The next five bits give the Kind of the value.
+	// This repeats typ.Kind() except for method values.
+	// The remaining 23+ bits give a method number for method values.
+	// If flag.kind() != Func, code can assume that flagMethod is unset.
+	// If ifaceIndir(typ), code can assume that flagIndir is set.
+	flag
+
+	// A method value represents a curried method invocation
+	// like r.Read for some receiver r.  The typ+val+flag bits describe
+	// the receiver r, but the flag's Kind bits say Func (methods are
+	// functions), and the top bits of the flag give the method number
+	// in r's type's method table.
+}
+
+type flag uintptr
+
+const (
+	flagKindWidth        = 5 // there are 27 kinds
+	flagKindMask    flag = 1<<flagKindWidth - 1
+	flagRO          flag = 1 << 5
+	flagIndir       flag = 1 << 6
+	flagAddr        flag = 1 << 7
+	flagMethod      flag = 1 << 8
+	flagMethodShift      = 9
+)
+
+func (f flag) kind() Kind {
+	return Kind(f & flagKindMask)
+}
+
+// pointer returns the underlying pointer represented by v.
+// v.Kind() must be Ptr, Map, Chan, Func, or UnsafePointer
+func (v Value) pointer() unsafe.Pointer {
+	if v.typ.size != ptrSize || !v.typ.pointers() {
+		panic("can't call pointer on a non-pointer Value")
+	}
+	if v.flag&flagIndir != 0 {
+		return *(*unsafe.Pointer)(v.ptr)
+	}
+	return v.ptr
+}
+
+// packEface converts v to the empty interface.
+func packEface(v Value) interface{} {
+	t := v.typ
+	var i interface{}
+	e := (*emptyInterface)(unsafe.Pointer(&i))
+	// First, fill in the data portion of the interface.
+	switch {
+	case ifaceIndir(t):
+		if v.flag&flagIndir == 0 {
+			panic("bad indir")
+		}
+		// Value is indirect, and so is the interface we're making.
+		ptr := v.ptr
+		if v.flag&flagAddr != 0 {
+			// TODO: pass safe boolean from valueInterface so
+			// we don't need to copy if safe==true?
+			c := unsafe_New(t)
+			memmove(c, ptr, t.size)
+			ptr = c
+		}
+		e.word = ptr
+	case v.flag&flagIndir != 0:
+		// Value is indirect, but interface is direct.  We need
+		// to load the data at v.ptr into the interface data word.
+		e.word = *(*unsafe.Pointer)(v.ptr)
+	default:
+		// Value is direct, and so is the interface.
+		e.word = v.ptr
+	}
+	// Now, fill in the type portion.  We're very careful here not
+	// to have any operation between the e.word and e.typ assignments
+	// that would let the garbage collector observe the partially-built
+	// interface value.
+	e.typ = t
+	return i
+}
+
+// unpackEface converts the empty interface i to a Value.
+func unpackEface(i interface{}) Value {
+	e := (*emptyInterface)(unsafe.Pointer(&i))
+	// NOTE: don't read e.word until we know whether it is really a pointer or not.
+	t := e.typ
+	if t == nil {
+		return Value{}
+	}
+	f := flag(t.Kind())
+	if ifaceIndir(t) {
+		f |= flagIndir
+	}
+	return Value{t, unsafe.Pointer(e.word), f}
+}
+
+// A ValueError occurs when a Value method is invoked on
+// a Value that does not support it.  Such cases are documented
+// in the description of each method.
+type ValueError struct {
+	Method string
+	Kind   Kind
+}
+
+func (e *ValueError) Error() string {
+	if e.Kind == 0 {
+		return "reflect: call of " + e.Method + " on zero Value"
+	}
+	return "reflect: call of " + e.Method + " on " + e.Kind.String() + " Value"
+}
+
+// methodName returns the name of the calling method,
+// assumed to be two stack frames above.
+func methodName() string {
+	pc, _, _, _ := runtime.Caller(2)
+	f := runtime.FuncForPC(pc)
+	if f == nil {
+		return "unknown method"
+	}
+	return f.Name()
+}
+
+// emptyInterface is the header for an interface{} value.
+type emptyInterface struct {
+	typ  *rtype
+	word unsafe.Pointer
+}
+
+// nonEmptyInterface is the header for a interface value with methods.
+type nonEmptyInterface struct {
+	// see ../runtime/iface.c:/Itab
+	itab *struct {
+		ityp   *rtype // static interface type
+		typ    *rtype // dynamic concrete type
+		link   unsafe.Pointer
+		bad    int32
+		unused int32
+		fun    [100000]unsafe.Pointer // method table
+	}
+	word unsafe.Pointer
+}
+
+// mustBe panics if f's kind is not expected.
+// Making this a method on flag instead of on Value
+// (and embedding flag in Value) means that we can write
+// the very clear v.mustBe(Bool) and have it compile into
+// v.flag.mustBe(Bool), which will only bother to copy the
+// single important word for the receiver.
+func (f flag) mustBe(expected Kind) {
+	if f.kind() != expected {
+		panic(&ValueError{methodName(), f.kind()})
+	}
+}
+
+// mustBeExported panics if f records that the value was obtained using
+// an unexported field.
+func (f flag) mustBeExported() {
+	if f == 0 {
+		panic(&ValueError{methodName(), 0})
+	}
+	if f&flagRO != 0 {
+		panic("reflect: " + methodName() + " using value obtained using unexported field")
+	}
+}
+
+// mustBeAssignable panics if f records that the value is not assignable,
+// which is to say that either it was obtained using an unexported field
+// or it is not addressable.
+func (f flag) mustBeAssignable() {
+	if f == 0 {
+		panic(&ValueError{methodName(), Invalid})
+	}
+	// Assignable if addressable and not read-only.
+	if f&flagRO != 0 {
+		panic("reflect: " + methodName() + " using value obtained using unexported field")
+	}
+	if f&flagAddr == 0 {
+		panic("reflect: " + methodName() + " using unaddressable value")
+	}
+}
+
+// Addr returns a pointer value representing the address of v.
+// It panics if CanAddr() returns false.
+// Addr is typically used to obtain a pointer to a struct field
+// or slice element in order to call a method that requires a
+// pointer receiver.
+func (v Value) Addr() Value {
+	if v.flag&flagAddr == 0 {
+		panic("reflect.Value.Addr of unaddressable value")
+	}
+	return Value{v.typ.ptrTo(), v.ptr, (v.flag & flagRO) | flag(Ptr)}
+}
+
+// Bool returns v's underlying value.
+// It panics if v's kind is not Bool.
+func (v Value) Bool() bool {
+	v.mustBe(Bool)
+	return *(*bool)(v.ptr)
+}
+
+// Bytes returns v's underlying value.
+// It panics if v's underlying value is not a slice of bytes.
+func (v Value) Bytes() []byte {
+	v.mustBe(Slice)
+	if v.typ.Elem().Kind() != Uint8 {
+		panic("reflect.Value.Bytes of non-byte slice")
+	}
+	// Slice is always bigger than a word; assume flagIndir.
+	return *(*[]byte)(v.ptr)
+}
+
+// runes returns v's underlying value.
+// It panics if v's underlying value is not a slice of runes (int32s).
+func (v Value) runes() []rune {
+	v.mustBe(Slice)
+	if v.typ.Elem().Kind() != Int32 {
+		panic("reflect.Value.Bytes of non-rune slice")
+	}
+	// Slice is always bigger than a word; assume flagIndir.
+	return *(*[]rune)(v.ptr)
+}
+
+// CanAddr returns true if the value's address can be obtained with Addr.
+// Such values are called addressable.  A value is addressable if it is
+// an element of a slice, an element of an addressable array,
+// a field of an addressable struct, or the result of dereferencing a pointer.
+// If CanAddr returns false, calling Addr will panic.
+func (v Value) CanAddr() bool {
+	return v.flag&flagAddr != 0
+}
+
+// CanSet returns true if the value of v can be changed.
+// A Value can be changed only if it is addressable and was not
+// obtained by the use of unexported struct fields.
+// If CanSet returns false, calling Set or any type-specific
+// setter (e.g., SetBool, SetInt64) will panic.
+func (v Value) CanSet() bool {
+	return v.flag&(flagAddr|flagRO) == flagAddr
+}
+
+// Call calls the function v with the input arguments in.
+// For example, if len(in) == 3, v.Call(in) represents the Go call v(in[0], in[1], in[2]).
+// Call panics if v's Kind is not Func.
+// It returns the output results as Values.
+// As in Go, each input argument must be assignable to the
+// type of the function's corresponding input parameter.
+// If v is a variadic function, Call creates the variadic slice parameter
+// itself, copying in the corresponding values.
+func (v Value) Call(in []Value) []Value {
+	v.mustBe(Func)
+	v.mustBeExported()
+	return v.call("Call", in)
+}
+
+// CallSlice calls the variadic function v with the input arguments in,
+// assigning the slice in[len(in)-1] to v's final variadic argument.
+// For example, if len(in) == 3, v.Call(in) represents the Go call v(in[0], in[1], in[2]...).
+// Call panics if v's Kind is not Func or if v is not variadic.
+// It returns the output results as Values.
+// As in Go, each input argument must be assignable to the
+// type of the function's corresponding input parameter.
+func (v Value) CallSlice(in []Value) []Value {
+	v.mustBe(Func)
+	v.mustBeExported()
+	return v.call("CallSlice", in)
+}
+
+var callGC bool // for testing; see TestCallMethodJump
+
+func (v Value) call(op string, in []Value) []Value {
+	// Get function pointer, type.
+	t := v.typ
+	var (
+		fn       unsafe.Pointer
+		rcvr     Value
+		rcvrtype *rtype
+	)
+	if v.flag&flagMethod != 0 {
+		rcvr = v
+		rcvrtype, t, fn = methodReceiver(op, v, int(v.flag)>>flagMethodShift)
+	} else if v.flag&flagIndir != 0 {
+		fn = *(*unsafe.Pointer)(v.ptr)
+	} else {
+		fn = v.ptr
+	}
+
+	if fn == nil {
+		panic("reflect.Value.Call: call of nil function")
+	}
+
+	isSlice := op == "CallSlice"
+	n := t.NumIn()
+	if isSlice {
+		if !t.IsVariadic() {
+			panic("reflect: CallSlice of non-variadic function")
+		}
+		if len(in) < n {
+			panic("reflect: CallSlice with too few input arguments")
+		}
+		if len(in) > n {
+			panic("reflect: CallSlice with too many input arguments")
+		}
+	} else {
+		if t.IsVariadic() {
+			n--
+		}
+		if len(in) < n {
+			panic("reflect: Call with too few input arguments")
+		}
+		if !t.IsVariadic() && len(in) > n {
+			panic("reflect: Call with too many input arguments")
+		}
+	}
+	for _, x := range in {
+		if x.Kind() == Invalid {
+			panic("reflect: " + op + " using zero Value argument")
+		}
+	}
+	for i := 0; i < n; i++ {
+		if xt, targ := in[i].Type(), t.In(i); !xt.AssignableTo(targ) {
+			panic("reflect: " + op + " using " + xt.String() + " as type " + targ.String())
+		}
+	}
+	if !isSlice && t.IsVariadic() {
+		// prepare slice for remaining values
+		m := len(in) - n
+		slice := MakeSlice(t.In(n), m, m)
+		elem := t.In(n).Elem()
+		for i := 0; i < m; i++ {
+			x := in[n+i]
+			if xt := x.Type(); !xt.AssignableTo(elem) {
+				panic("reflect: cannot use " + xt.String() + " as type " + elem.String() + " in " + op)
+			}
+			slice.Index(i).Set(x)
+		}
+		origIn := in
+		in = make([]Value, n+1)
+		copy(in[:n], origIn)
+		in[n] = slice
+	}
+
+	nin := len(in)
+	if nin != t.NumIn() {
+		panic("reflect.Value.Call: wrong argument count")
+	}
+	nout := t.NumOut()
+
+	// Compute frame type, allocate a chunk of memory for frame
+	frametype, _, retOffset, _ := funcLayout(t, rcvrtype)
+	args := unsafe_New(frametype)
+	off := uintptr(0)
+
+	// Copy inputs into args.
+	if rcvrtype != nil {
+		storeRcvr(rcvr, args)
+		off = ptrSize
+	}
+	for i, v := range in {
+		v.mustBeExported()
+		targ := t.In(i).(*rtype)
+		a := uintptr(targ.align)
+		off = (off + a - 1) &^ (a - 1)
+		n := targ.size
+		addr := unsafe.Pointer(uintptr(args) + off)
+		v = v.assignTo("reflect.Value.Call", targ, addr)
+		if v.flag&flagIndir != 0 {
+			memmove(addr, v.ptr, n)
+		} else {
+			*(*unsafe.Pointer)(addr) = v.ptr
+		}
+		off += n
+	}
+
+	// Call.
+	call(fn, args, uint32(frametype.size), uint32(retOffset))
+
+	// For testing; see TestCallMethodJump.
+	if callGC {
+		runtime.GC()
+	}
+
+	// Copy return values out of args.
+	ret := make([]Value, nout)
+	off = retOffset
+	for i := 0; i < nout; i++ {
+		tv := t.Out(i)
+		a := uintptr(tv.Align())
+		off = (off + a - 1) &^ (a - 1)
+		fl := flagIndir | flag(tv.Kind())
+		ret[i] = Value{tv.common(), unsafe.Pointer(uintptr(args) + off), fl}
+		off += tv.Size()
+	}
+
+	return ret
+}
+
+// callReflect is the call implementation used by a function
+// returned by MakeFunc. In many ways it is the opposite of the
+// method Value.call above. The method above converts a call using Values
+// into a call of a function with a concrete argument frame, while
+// callReflect converts a call of a function with a concrete argument
+// frame into a call using Values.
+// It is in this file so that it can be next to the call method above.
+// The remainder of the MakeFunc implementation is in makefunc.go.
+//
+// NOTE: This function must be marked as a "wrapper" in the generated code,
+// so that the linker can make it work correctly for panic and recover.
+// The gc compilers know to do that for the name "reflect.callReflect".
+func callReflect(ctxt *makeFuncImpl, frame unsafe.Pointer) {
+	ftyp := ctxt.typ
+	f := ctxt.fn
+
+	// Copy argument frame into Values.
+	ptr := frame
+	off := uintptr(0)
+	in := make([]Value, 0, len(ftyp.in))
+	for _, arg := range ftyp.in {
+		typ := arg
+		off += -off & uintptr(typ.align-1)
+		addr := unsafe.Pointer(uintptr(ptr) + off)
+		v := Value{typ, nil, flag(typ.Kind())}
+		if ifaceIndir(typ) {
+			// value cannot be inlined in interface data.
+			// Must make a copy, because f might keep a reference to it,
+			// and we cannot let f keep a reference to the stack frame
+			// after this function returns, not even a read-only reference.
+			v.ptr = unsafe_New(typ)
+			memmove(v.ptr, addr, typ.size)
+			v.flag |= flagIndir
+		} else {
+			v.ptr = *(*unsafe.Pointer)(addr)
+		}
+		in = append(in, v)
+		off += typ.size
+	}
+
+	// Call underlying function.
+	out := f(in)
+	if len(out) != len(ftyp.out) {
+		panic("reflect: wrong return count from function created by MakeFunc")
+	}
+
+	// Copy results back into argument frame.
+	if len(ftyp.out) > 0 {
+		off += -off & (ptrSize - 1)
+		if runtime.GOARCH == "amd64p32" {
+			off = align(off, 8)
+		}
+		for i, arg := range ftyp.out {
+			typ := arg
+			v := out[i]
+			if v.typ != typ {
+				panic("reflect: function created by MakeFunc using " + funcName(f) +
+					" returned wrong type: have " +
+					out[i].typ.String() + " for " + typ.String())
+			}
+			if v.flag&flagRO != 0 {
+				panic("reflect: function created by MakeFunc using " + funcName(f) +
+					" returned value obtained from unexported field")
+			}
+			off += -off & uintptr(typ.align-1)
+			addr := unsafe.Pointer(uintptr(ptr) + off)
+			if v.flag&flagIndir != 0 {
+				memmove(addr, v.ptr, typ.size)
+			} else {
+				*(*unsafe.Pointer)(addr) = v.ptr
+			}
+			off += typ.size
+		}
+	}
+}
+
+// methodReceiver returns information about the receiver
+// described by v. The Value v may or may not have the
+// flagMethod bit set, so the kind cached in v.flag should
+// not be used.
+// The return value rcvrtype gives the method's actual receiver type.
+// The return value t gives the method type signature (without the receiver).
+// The return value fn is a pointer to the method code.
+func methodReceiver(op string, v Value, methodIndex int) (rcvrtype, t *rtype, fn unsafe.Pointer) {
+	i := methodIndex
+	if v.typ.Kind() == Interface {
+		tt := (*interfaceType)(unsafe.Pointer(v.typ))
+		if uint(i) >= uint(len(tt.methods)) {
+			panic("reflect: internal error: invalid method index")
+		}
+		m := &tt.methods[i]
+		if m.pkgPath != nil {
+			panic("reflect: " + op + " of unexported method")
+		}
+		iface := (*nonEmptyInterface)(v.ptr)
+		if iface.itab == nil {
+			panic("reflect: " + op + " of method on nil interface value")
+		}
+		rcvrtype = iface.itab.typ
+		fn = unsafe.Pointer(&iface.itab.fun[i])
+		t = m.typ
+	} else {
+		rcvrtype = v.typ
+		ut := v.typ.uncommon()
+		if ut == nil || uint(i) >= uint(len(ut.methods)) {
+			panic("reflect: internal error: invalid method index")
+		}
+		m := &ut.methods[i]
+		if m.pkgPath != nil {
+			panic("reflect: " + op + " of unexported method")
+		}
+		fn = unsafe.Pointer(&m.ifn)
+		t = m.mtyp
+	}
+	return
+}
+
+// v is a method receiver.  Store at p the word which is used to
+// encode that receiver at the start of the argument list.
+// Reflect uses the "interface" calling convention for
+// methods, which always uses one word to record the receiver.
+func storeRcvr(v Value, p unsafe.Pointer) {
+	t := v.typ
+	if t.Kind() == Interface {
+		// the interface data word becomes the receiver word
+		iface := (*nonEmptyInterface)(v.ptr)
+		*(*unsafe.Pointer)(p) = unsafe.Pointer(iface.word)
+	} else if v.flag&flagIndir != 0 && !ifaceIndir(t) {
+		*(*unsafe.Pointer)(p) = *(*unsafe.Pointer)(v.ptr)
+	} else {
+		*(*unsafe.Pointer)(p) = v.ptr
+	}
+}
+
+// align returns the result of rounding x up to a multiple of n.
+// n must be a power of two.
+func align(x, n uintptr) uintptr {
+	return (x + n - 1) &^ (n - 1)
+}
+
+// callMethod is the call implementation used by a function returned
+// by makeMethodValue (used by v.Method(i).Interface()).
+// It is a streamlined version of the usual reflect call: the caller has
+// already laid out the argument frame for us, so we don't have
+// to deal with individual Values for each argument.
+// It is in this file so that it can be next to the two similar functions above.
+// The remainder of the makeMethodValue implementation is in makefunc.go.
+//
+// NOTE: This function must be marked as a "wrapper" in the generated code,
+// so that the linker can make it work correctly for panic and recover.
+// The gc compilers know to do that for the name "reflect.callMethod".
+func callMethod(ctxt *methodValue, frame unsafe.Pointer) {
+	rcvr := ctxt.rcvr
+	rcvrtype, t, fn := methodReceiver("call", rcvr, ctxt.method)
+	frametype, argSize, retOffset, _ := funcLayout(t, rcvrtype)
+
+	// Make a new frame that is one word bigger so we can store the receiver.
+	args := unsafe_New(frametype)
+
+	// Copy in receiver and rest of args.
+	storeRcvr(rcvr, args)
+	memmove(unsafe.Pointer(uintptr(args)+ptrSize), frame, argSize-ptrSize)
+
+	// Call.
+	call(fn, args, uint32(frametype.size), uint32(retOffset))
+
+	// Copy return values. On amd64p32, the beginning of return values
+	// is 64-bit aligned, so the caller's frame layout (which doesn't have
+	// a receiver) is different from the layout of the fn call, which has
+	// a receiver.
+	// Ignore any changes to args and just copy return values.
+	callerRetOffset := retOffset - ptrSize
+	if runtime.GOARCH == "amd64p32" {
+		callerRetOffset = align(argSize-ptrSize, 8)
+	}
+	memmove(unsafe.Pointer(uintptr(frame)+callerRetOffset),
+		unsafe.Pointer(uintptr(args)+retOffset), frametype.size-retOffset)
+}
+
+// funcName returns the name of f, for use in error messages.
+func funcName(f func([]Value) []Value) string {
+	pc := *(*uintptr)(unsafe.Pointer(&f))
+	rf := runtime.FuncForPC(pc)
+	if rf != nil {
+		return rf.Name()
+	}
+	return "closure"
+}
+
+// Cap returns v's capacity.
+// It panics if v's Kind is not Array, Chan, or Slice.
+func (v Value) Cap() int {
+	k := v.kind()
+	switch k {
+	case Array:
+		return v.typ.Len()
+	case Chan:
+		return int(chancap(v.pointer()))
+	case Slice:
+		// Slice is always bigger than a word; assume flagIndir.
+		return (*sliceHeader)(v.ptr).Cap
+	}
+	panic(&ValueError{"reflect.Value.Cap", v.kind()})
+}
+
+// Close closes the channel v.
+// It panics if v's Kind is not Chan.
+func (v Value) Close() {
+	v.mustBe(Chan)
+	v.mustBeExported()
+	chanclose(v.pointer())
+}
+
+// Complex returns v's underlying value, as a complex128.
+// It panics if v's Kind is not Complex64 or Complex128
+func (v Value) Complex() complex128 {
+	k := v.kind()
+	switch k {
+	case Complex64:
+		return complex128(*(*complex64)(v.ptr))
+	case Complex128:
+		return *(*complex128)(v.ptr)
+	}
+	panic(&ValueError{"reflect.Value.Complex", v.kind()})
+}
+
+// Elem returns the value that the interface v contains
+// or that the pointer v points to.
+// It panics if v's Kind is not Interface or Ptr.
+// It returns the zero Value if v is nil.
+func (v Value) Elem() Value {
+	k := v.kind()
+	switch k {
+	case Interface:
+		var eface interface{}
+		if v.typ.NumMethod() == 0 {
+			eface = *(*interface{})(v.ptr)
+		} else {
+			eface = (interface{})(*(*interface {
+				M()
+			})(v.ptr))
+		}
+		x := unpackEface(eface)
+		if x.flag != 0 {
+			x.flag |= v.flag & flagRO
+		}
+		return x
+	case Ptr:
+		ptr := v.ptr
+		if v.flag&flagIndir != 0 {
+			ptr = *(*unsafe.Pointer)(ptr)
+		}
+		// The returned value's address is v's value.
+		if ptr == nil {
+			return Value{}
+		}
+		tt := (*ptrType)(unsafe.Pointer(v.typ))
+		typ := tt.elem
+		fl := v.flag&flagRO | flagIndir | flagAddr
+		fl |= flag(typ.Kind())
+		return Value{typ, ptr, fl}
+	}
+	panic(&ValueError{"reflect.Value.Elem", v.kind()})
+}
+
+// Field returns the i'th field of the struct v.
+// It panics if v's Kind is not Struct or i is out of range.
+func (v Value) Field(i int) Value {
+	if v.kind() != Struct {
+		panic(&ValueError{"reflect.Value.Field", v.kind()})
+	}
+	tt := (*structType)(unsafe.Pointer(v.typ))
+	if uint(i) >= uint(len(tt.fields)) {
+		panic("reflect: Field index out of range")
+	}
+	field := &tt.fields[i]
+	typ := field.typ
+
+	// Inherit permission bits from v.
+	fl := v.flag&(flagRO|flagIndir|flagAddr) | flag(typ.Kind())
+	// Using an unexported field forces flagRO.
+	if field.pkgPath != nil {
+		fl |= flagRO
+	}
+	// Either flagIndir is set and v.ptr points at struct,
+	// or flagIndir is not set and v.ptr is the actual struct data.
+	// In the former case, we want v.ptr + offset.
+	// In the latter case, we must be have field.offset = 0,
+	// so v.ptr + field.offset is still okay.
+	ptr := unsafe.Pointer(uintptr(v.ptr) + field.offset)
+	return Value{typ, ptr, fl}
+}
+
+// FieldByIndex returns the nested field corresponding to index.
+// It panics if v's Kind is not struct.
+func (v Value) FieldByIndex(index []int) Value {
+	if len(index) == 1 {
+		return v.Field(index[0])
+	}
+	v.mustBe(Struct)
+	for i, x := range index {
+		if i > 0 {
+			if v.Kind() == Ptr && v.typ.Elem().Kind() == Struct {
+				if v.IsNil() {
+					panic("reflect: indirection through nil pointer to embedded struct")
+				}
+				v = v.Elem()
+			}
+		}
+		v = v.Field(x)
+	}
+	return v
+}
+
+// FieldByName returns the struct field with the given name.
+// It returns the zero Value if no field was found.
+// It panics if v's Kind is not struct.
+func (v Value) FieldByName(name string) Value {
+	v.mustBe(Struct)
+	if f, ok := v.typ.FieldByName(name); ok {
+		return v.FieldByIndex(f.Index)
+	}
+	return Value{}
+}
+
+// FieldByNameFunc returns the struct field with a name
+// that satisfies the match function.
+// It panics if v's Kind is not struct.
+// It returns the zero Value if no field was found.
+func (v Value) FieldByNameFunc(match func(string) bool) Value {
+	if f, ok := v.typ.FieldByNameFunc(match); ok {
+		return v.FieldByIndex(f.Index)
+	}
+	return Value{}
+}
+
+// Float returns v's underlying value, as a float64.
+// It panics if v's Kind is not Float32 or Float64
+func (v Value) Float() float64 {
+	k := v.kind()
+	switch k {
+	case Float32:
+		return float64(*(*float32)(v.ptr))
+	case Float64:
+		return *(*float64)(v.ptr)
+	}
+	panic(&ValueError{"reflect.Value.Float", v.kind()})
+}
+
+var uint8Type = TypeOf(uint8(0)).(*rtype)
+
+// Index returns v's i'th element.
+// It panics if v's Kind is not Array, Slice, or String or i is out of range.
+func (v Value) Index(i int) Value {
+	switch v.kind() {
+	case Array:
+		tt := (*arrayType)(unsafe.Pointer(v.typ))
+		if uint(i) >= uint(tt.len) {
+			panic("reflect: array index out of range")
+		}
+		typ := tt.elem
+		offset := uintptr(i) * typ.size
+
+		// Either flagIndir is set and v.ptr points at array,
+		// or flagIndir is not set and v.ptr is the actual array data.
+		// In the former case, we want v.ptr + offset.
+		// In the latter case, we must be doing Index(0), so offset = 0,
+		// so v.ptr + offset is still okay.
+		val := unsafe.Pointer(uintptr(v.ptr) + offset)
+		fl := v.flag&(flagRO|flagIndir|flagAddr) | flag(typ.Kind()) // bits same as overall array
+		return Value{typ, val, fl}
+
+	case Slice:
+		// Element flag same as Elem of Ptr.
+		// Addressable, indirect, possibly read-only.
+		s := (*sliceHeader)(v.ptr)
+		if uint(i) >= uint(s.Len) {
+			panic("reflect: slice index out of range")
+		}
+		tt := (*sliceType)(unsafe.Pointer(v.typ))
+		typ := tt.elem
+		val := unsafe.Pointer(uintptr(s.Data) + uintptr(i)*typ.size)
+		fl := flagAddr | flagIndir | v.flag&flagRO | flag(typ.Kind())
+		return Value{typ, val, fl}
+
+	case String:
+		s := (*stringHeader)(v.ptr)
+		if uint(i) >= uint(s.Len) {
+			panic("reflect: string index out of range")
+		}
+		p := unsafe.Pointer(uintptr(s.Data) + uintptr(i))
+		fl := v.flag&flagRO | flag(Uint8) | flagIndir
+		return Value{uint8Type, p, fl}
+	}
+	panic(&ValueError{"reflect.Value.Index", v.kind()})
+}
+
+// Int returns v's underlying value, as an int64.
+// It panics if v's Kind is not Int, Int8, Int16, Int32, or Int64.
+func (v Value) Int() int64 {
+	k := v.kind()
+	p := v.ptr
+	switch k {
+	case Int:
+		return int64(*(*int)(p))
+	case Int8:
+		return int64(*(*int8)(p))
+	case Int16:
+		return int64(*(*int16)(p))
+	case Int32:
+		return int64(*(*int32)(p))
+	case Int64:
+		return int64(*(*int64)(p))
+	}
+	panic(&ValueError{"reflect.Value.Int", v.kind()})
+}
+
+// CanInterface returns true if Interface can be used without panicking.
+func (v Value) CanInterface() bool {
+	if v.flag == 0 {
+		panic(&ValueError{"reflect.Value.CanInterface", Invalid})
+	}
+	return v.flag&flagRO == 0
+}
+
+// Interface returns v's current value as an interface{}.
+// It is equivalent to:
+//	var i interface{} = (v's underlying value)
+// It panics if the Value was obtained by accessing
+// unexported struct fields.
+func (v Value) Interface() (i interface{}) {
+	return valueInterface(v, true)
+}
+
+func valueInterface(v Value, safe bool) interface{} {
+	if v.flag == 0 {
+		panic(&ValueError{"reflect.Value.Interface", 0})
+	}
+	if safe && v.flag&flagRO != 0 {
+		// Do not allow access to unexported values via Interface,
+		// because they might be pointers that should not be
+		// writable or methods or function that should not be callable.
+		panic("reflect.Value.Interface: cannot return value obtained from unexported field or method")
+	}
+	if v.flag&flagMethod != 0 {
+		v = makeMethodValue("Interface", v)
+	}
+
+	if v.kind() == Interface {
+		// Special case: return the element inside the interface.
+		// Empty interface has one layout, all interfaces with
+		// methods have a second layout.
+		if v.NumMethod() == 0 {
+			return *(*interface{})(v.ptr)
+		}
+		return *(*interface {
+			M()
+		})(v.ptr)
+	}
+
+	// TODO: pass safe to packEface so we don't need to copy if safe==true?
+	return packEface(v)
+}
+
+// InterfaceData returns the interface v's value as a uintptr pair.
+// It panics if v's Kind is not Interface.
+func (v Value) InterfaceData() [2]uintptr {
+	// TODO: deprecate this
+	v.mustBe(Interface)
+	// We treat this as a read operation, so we allow
+	// it even for unexported data, because the caller
+	// has to import "unsafe" to turn it into something
+	// that can be abused.
+	// Interface value is always bigger than a word; assume flagIndir.
+	return *(*[2]uintptr)(v.ptr)
+}
+
+// IsNil reports whether its argument v is nil. The argument must be
+// a chan, func, interface, map, pointer, or slice value; if it is
+// not, IsNil panics. Note that IsNil is not always equivalent to a
+// regular comparison with nil in Go. For example, if v was created
+// by calling ValueOf with an uninitialized interface variable i,
+// i==nil will be true but v.IsNil will panic as v will be the zero
+// Value.
+func (v Value) IsNil() bool {
+	k := v.kind()
+	switch k {
+	case Chan, Func, Map, Ptr:
+		if v.flag&flagMethod != 0 {
+			return false
+		}
+		ptr := v.ptr
+		if v.flag&flagIndir != 0 {
+			ptr = *(*unsafe.Pointer)(ptr)
+		}
+		return ptr == nil
+	case Interface, Slice:
+		// Both interface and slice are nil if first word is 0.
+		// Both are always bigger than a word; assume flagIndir.
+		return *(*unsafe.Pointer)(v.ptr) == nil
+	}
+	panic(&ValueError{"reflect.Value.IsNil", v.kind()})
+}
+
+// IsValid returns true if v represents a value.
+// It returns false if v is the zero Value.
+// If IsValid returns false, all other methods except String panic.
+// Most functions and methods never return an invalid value.
+// If one does, its documentation states the conditions explicitly.
+func (v Value) IsValid() bool {
+	return v.flag != 0
+}
+
+// Kind returns v's Kind.
+// If v is the zero Value (IsValid returns false), Kind returns Invalid.
+func (v Value) Kind() Kind {
+	return v.kind()
+}
+
+// Len returns v's length.
+// It panics if v's Kind is not Array, Chan, Map, Slice, or String.
+func (v Value) Len() int {
+	k := v.kind()
+	switch k {
+	case Array:
+		tt := (*arrayType)(unsafe.Pointer(v.typ))
+		return int(tt.len)
+	case Chan:
+		return chanlen(v.pointer())
+	case Map:
+		return maplen(v.pointer())
+	case Slice:
+		// Slice is bigger than a word; assume flagIndir.
+		return (*sliceHeader)(v.ptr).Len
+	case String:
+		// String is bigger than a word; assume flagIndir.
+		return (*stringHeader)(v.ptr).Len
+	}
+	panic(&ValueError{"reflect.Value.Len", v.kind()})
+}
+
+// MapIndex returns the value associated with key in the map v.
+// It panics if v's Kind is not Map.
+// It returns the zero Value if key is not found in the map or if v represents a nil map.
+// As in Go, the key's value must be assignable to the map's key type.
+func (v Value) MapIndex(key Value) Value {
+	v.mustBe(Map)
+	tt := (*mapType)(unsafe.Pointer(v.typ))
+
+	// Do not require key to be exported, so that DeepEqual
+	// and other programs can use all the keys returned by
+	// MapKeys as arguments to MapIndex.  If either the map
+	// or the key is unexported, though, the result will be
+	// considered unexported.  This is consistent with the
+	// behavior for structs, which allow read but not write
+	// of unexported fields.
+	key = key.assignTo("reflect.Value.MapIndex", tt.key, nil)
+
+	var k unsafe.Pointer
+	if key.flag&flagIndir != 0 {
+		k = key.ptr
+	} else {
+		k = unsafe.Pointer(&key.ptr)
+	}
+	e := mapaccess(v.typ, v.pointer(), k)
+	if e == nil {
+		return Value{}
+	}
+	typ := tt.elem
+	fl := (v.flag | key.flag) & flagRO
+	fl |= flag(typ.Kind())
+	if ifaceIndir(typ) {
+		// Copy result so future changes to the map
+		// won't change the underlying value.
+		c := unsafe_New(typ)
+		memmove(c, e, typ.size)
+		return Value{typ, c, fl | flagIndir}
+	} else {
+		return Value{typ, *(*unsafe.Pointer)(e), fl}
+	}
+}
+
+// MapKeys returns a slice containing all the keys present in the map,
+// in unspecified order.
+// It panics if v's Kind is not Map.
+// It returns an empty slice if v represents a nil map.
+func (v Value) MapKeys() []Value {
+	v.mustBe(Map)
+	tt := (*mapType)(unsafe.Pointer(v.typ))
+	keyType := tt.key
+
+	fl := v.flag&flagRO | flag(keyType.Kind())
+
+	m := v.pointer()
+	mlen := int(0)
+	if m != nil {
+		mlen = maplen(m)
+	}
+	it := mapiterinit(v.typ, m)
+	a := make([]Value, mlen)
+	var i int
+	for i = 0; i < len(a); i++ {
+		key := mapiterkey(it)
+		if key == nil {
+			// Someone deleted an entry from the map since we
+			// called maplen above.  It's a data race, but nothing
+			// we can do about it.
+			break
+		}
+		if ifaceIndir(keyType) {
+			// Copy result so future changes to the map
+			// won't change the underlying value.
+			c := unsafe_New(keyType)
+			memmove(c, key, keyType.size)
+			a[i] = Value{keyType, c, fl | flagIndir}
+		} else {
+			a[i] = Value{keyType, *(*unsafe.Pointer)(key), fl}
+		}
+		mapiternext(it)
+	}
+	return a[:i]
+}
+
+// Method returns a function value corresponding to v's i'th method.
+// The arguments to a Call on the returned function should not include
+// a receiver; the returned function will always use v as the receiver.
+// Method panics if i is out of range or if v is a nil interface value.
+func (v Value) Method(i int) Value {
+	if v.typ == nil {
+		panic(&ValueError{"reflect.Value.Method", Invalid})
+	}
+	if v.flag&flagMethod != 0 || uint(i) >= uint(v.typ.NumMethod()) {
+		panic("reflect: Method index out of range")
+	}
+	if v.typ.Kind() == Interface && v.IsNil() {
+		panic("reflect: Method on nil interface value")
+	}
+	fl := v.flag & (flagRO | flagIndir)
+	fl |= flag(Func)
+	fl |= flag(i)<<flagMethodShift | flagMethod
+	return Value{v.typ, v.ptr, fl}
+}
+
+// NumMethod returns the number of methods in the value's method set.
+func (v Value) NumMethod() int {
+	if v.typ == nil {
+		panic(&ValueError{"reflect.Value.NumMethod", Invalid})
+	}
+	if v.flag&flagMethod != 0 {
+		return 0
+	}
+	return v.typ.NumMethod()
+}
+
+// MethodByName returns a function value corresponding to the method
+// of v with the given name.
+// The arguments to a Call on the returned function should not include
+// a receiver; the returned function will always use v as the receiver.
+// It returns the zero Value if no method was found.
+func (v Value) MethodByName(name string) Value {
+	if v.typ == nil {
+		panic(&ValueError{"reflect.Value.MethodByName", Invalid})
+	}
+	if v.flag&flagMethod != 0 {
+		return Value{}
+	}
+	m, ok := v.typ.MethodByName(name)
+	if !ok {
+		return Value{}
+	}
+	return v.Method(m.Index)
+}
+
+// NumField returns the number of fields in the struct v.
+// It panics if v's Kind is not Struct.
+func (v Value) NumField() int {
+	v.mustBe(Struct)
+	tt := (*structType)(unsafe.Pointer(v.typ))
+	return len(tt.fields)
+}
+
+// OverflowComplex returns true if the complex128 x cannot be represented by v's type.
+// It panics if v's Kind is not Complex64 or Complex128.
+func (v Value) OverflowComplex(x complex128) bool {
+	k := v.kind()
+	switch k {
+	case Complex64:
+		return overflowFloat32(real(x)) || overflowFloat32(imag(x))
+	case Complex128:
+		return false
+	}
+	panic(&ValueError{"reflect.Value.OverflowComplex", v.kind()})
+}
+
+// OverflowFloat returns true if the float64 x cannot be represented by v's type.
+// It panics if v's Kind is not Float32 or Float64.
+func (v Value) OverflowFloat(x float64) bool {
+	k := v.kind()
+	switch k {
+	case Float32:
+		return overflowFloat32(x)
+	case Float64:
+		return false
+	}
+	panic(&ValueError{"reflect.Value.OverflowFloat", v.kind()})
+}
+
+func overflowFloat32(x float64) bool {
+	if x < 0 {
+		x = -x
+	}
+	return math.MaxFloat32 < x && x <= math.MaxFloat64
+}
+
+// OverflowInt returns true if the int64 x cannot be represented by v's type.
+// It panics if v's Kind is not Int, Int8, int16, Int32, or Int64.
+func (v Value) OverflowInt(x int64) bool {
+	k := v.kind()
+	switch k {
+	case Int, Int8, Int16, Int32, Int64:
+		bitSize := v.typ.size * 8
+		trunc := (x << (64 - bitSize)) >> (64 - bitSize)
+		return x != trunc
+	}
+	panic(&ValueError{"reflect.Value.OverflowInt", v.kind()})
+}
+
+// OverflowUint returns true if the uint64 x cannot be represented by v's type.
+// It panics if v's Kind is not Uint, Uintptr, Uint8, Uint16, Uint32, or Uint64.
+func (v Value) OverflowUint(x uint64) bool {
+	k := v.kind()
+	switch k {
+	case Uint, Uintptr, Uint8, Uint16, Uint32, Uint64:
+		bitSize := v.typ.size * 8
+		trunc := (x << (64 - bitSize)) >> (64 - bitSize)
+		return x != trunc
+	}
+	panic(&ValueError{"reflect.Value.OverflowUint", v.kind()})
+}
+
+// Pointer returns v's value as a uintptr.
+// It returns uintptr instead of unsafe.Pointer so that
+// code using reflect cannot obtain unsafe.Pointers
+// without importing the unsafe package explicitly.
+// It panics if v's Kind is not Chan, Func, Map, Ptr, Slice, or UnsafePointer.
+//
+// If v's Kind is Func, the returned pointer is an underlying
+// code pointer, but not necessarily enough to identify a
+// single function uniquely. The only guarantee is that the
+// result is zero if and only if v is a nil func Value.
+//
+// If v's Kind is Slice, the returned pointer is to the first
+// element of the slice.  If the slice is nil the returned value
+// is 0.  If the slice is empty but non-nil the return value is non-zero.
+func (v Value) Pointer() uintptr {
+	// TODO: deprecate
+	k := v.kind()
+	switch k {
+	case Chan, Map, Ptr, UnsafePointer:
+		return uintptr(v.pointer())
+	case Func:
+		if v.flag&flagMethod != 0 {
+			// As the doc comment says, the returned pointer is an
+			// underlying code pointer but not necessarily enough to
+			// identify a single function uniquely. All method expressions
+			// created via reflect have the same underlying code pointer,
+			// so their Pointers are equal. The function used here must
+			// match the one used in makeMethodValue.
+			f := methodValueCall
+			return **(**uintptr)(unsafe.Pointer(&f))
+		}
+		p := v.pointer()
+		// Non-nil func value points at data block.
+		// First word of data block is actual code.
+		if p != nil {
+			p = *(*unsafe.Pointer)(p)
+		}
+		return uintptr(p)
+
+	case Slice:
+		return (*SliceHeader)(v.ptr).Data
+	}
+	panic(&ValueError{"reflect.Value.Pointer", v.kind()})
+}
+
+// Recv receives and returns a value from the channel v.
+// It panics if v's Kind is not Chan.
+// The receive blocks until a value is ready.
+// The boolean value ok is true if the value x corresponds to a send
+// on the channel, false if it is a zero value received because the channel is closed.
+func (v Value) Recv() (x Value, ok bool) {
+	v.mustBe(Chan)
+	v.mustBeExported()
+	return v.recv(false)
+}
+
+// internal recv, possibly non-blocking (nb).
+// v is known to be a channel.
+func (v Value) recv(nb bool) (val Value, ok bool) {
+	tt := (*chanType)(unsafe.Pointer(v.typ))
+	if ChanDir(tt.dir)&RecvDir == 0 {
+		panic("reflect: recv on send-only channel")
+	}
+	t := tt.elem
+	val = Value{t, nil, flag(t.Kind())}
+	var p unsafe.Pointer
+	if ifaceIndir(t) {
+		p = unsafe_New(t)
+		val.ptr = p
+		val.flag |= flagIndir
+	} else {
+		p = unsafe.Pointer(&val.ptr)
+	}
+	selected, ok := chanrecv(v.typ, v.pointer(), nb, p)
+	if !selected {
+		val = Value{}
+	}
+	return
+}
+
+// Send sends x on the channel v.
+// It panics if v's kind is not Chan or if x's type is not the same type as v's element type.
+// As in Go, x's value must be assignable to the channel's element type.
+func (v Value) Send(x Value) {
+	v.mustBe(Chan)
+	v.mustBeExported()
+	v.send(x, false)
+}
+
+// internal send, possibly non-blocking.
+// v is known to be a channel.
+func (v Value) send(x Value, nb bool) (selected bool) {
+	tt := (*chanType)(unsafe.Pointer(v.typ))
+	if ChanDir(tt.dir)&SendDir == 0 {
+		panic("reflect: send on recv-only channel")
+	}
+	x.mustBeExported()
+	x = x.assignTo("reflect.Value.Send", tt.elem, nil)
+	var p unsafe.Pointer
+	if x.flag&flagIndir != 0 {
+		p = x.ptr
+	} else {
+		p = unsafe.Pointer(&x.ptr)
+	}
+	return chansend(v.typ, v.pointer(), p, nb)
+}
+
+// Set assigns x to the value v.
+// It panics if CanSet returns false.
+// As in Go, x's value must be assignable to v's type.
+func (v Value) Set(x Value) {
+	v.mustBeAssignable()
+	x.mustBeExported() // do not let unexported x leak
+	var target unsafe.Pointer
+	if v.kind() == Interface {
+		target = v.ptr
+	}
+	x = x.assignTo("reflect.Set", v.typ, target)
+	if x.flag&flagIndir != 0 {
+		memmove(v.ptr, x.ptr, v.typ.size)
+	} else {
+		*(*unsafe.Pointer)(v.ptr) = x.ptr
+	}
+}
+
+// SetBool sets v's underlying value.
+// It panics if v's Kind is not Bool or if CanSet() is false.
+func (v Value) SetBool(x bool) {
+	v.mustBeAssignable()
+	v.mustBe(Bool)
+	*(*bool)(v.ptr) = x
+}
+
+// SetBytes sets v's underlying value.
+// It panics if v's underlying value is not a slice of bytes.
+func (v Value) SetBytes(x []byte) {
+	v.mustBeAssignable()
+	v.mustBe(Slice)
+	if v.typ.Elem().Kind() != Uint8 {
+		panic("reflect.Value.SetBytes of non-byte slice")
+	}
+	*(*[]byte)(v.ptr) = x
+}
+
+// setRunes sets v's underlying value.
+// It panics if v's underlying value is not a slice of runes (int32s).
+func (v Value) setRunes(x []rune) {
+	v.mustBeAssignable()
+	v.mustBe(Slice)
+	if v.typ.Elem().Kind() != Int32 {
+		panic("reflect.Value.setRunes of non-rune slice")
+	}
+	*(*[]rune)(v.ptr) = x
+}
+
+// SetComplex sets v's underlying value to x.
+// It panics if v's Kind is not Complex64 or Complex128, or if CanSet() is false.
+func (v Value) SetComplex(x complex128) {
+	v.mustBeAssignable()
+	switch k := v.kind(); k {
+	default:
+		panic(&ValueError{"reflect.Value.SetComplex", v.kind()})
+	case Complex64:
+		*(*complex64)(v.ptr) = complex64(x)
+	case Complex128:
+		*(*complex128)(v.ptr) = x
+	}
+}
+
+// SetFloat sets v's underlying value to x.
+// It panics if v's Kind is not Float32 or Float64, or if CanSet() is false.
+func (v Value) SetFloat(x float64) {
+	v.mustBeAssignable()
+	switch k := v.kind(); k {
+	default:
+		panic(&ValueError{"reflect.Value.SetFloat", v.kind()})
+	case Float32:
+		*(*float32)(v.ptr) = float32(x)
+	case Float64:
+		*(*float64)(v.ptr) = x
+	}
+}
+
+// SetInt sets v's underlying value to x.
+// It panics if v's Kind is not Int, Int8, Int16, Int32, or Int64, or if CanSet() is false.
+func (v Value) SetInt(x int64) {
+	v.mustBeAssignable()
+	switch k := v.kind(); k {
+	default:
+		panic(&ValueError{"reflect.Value.SetInt", v.kind()})
+	case Int:
+		*(*int)(v.ptr) = int(x)
+	case Int8:
+		*(*int8)(v.ptr) = int8(x)
+	case Int16:
+		*(*int16)(v.ptr) = int16(x)
+	case Int32:
+		*(*int32)(v.ptr) = int32(x)
+	case Int64:
+		*(*int64)(v.ptr) = x
+	}
+}
+
+// SetLen sets v's length to n.
+// It panics if v's Kind is not Slice or if n is negative or
+// greater than the capacity of the slice.
+func (v Value) SetLen(n int) {
+	v.mustBeAssignable()
+	v.mustBe(Slice)
+	s := (*sliceHeader)(v.ptr)
+	if uint(n) > uint(s.Cap) {
+		panic("reflect: slice length out of range in SetLen")
+	}
+	s.Len = n
+}
+
+// SetCap sets v's capacity to n.
+// It panics if v's Kind is not Slice or if n is smaller than the length or
+// greater than the capacity of the slice.
+func (v Value) SetCap(n int) {
+	v.mustBeAssignable()
+	v.mustBe(Slice)
+	s := (*sliceHeader)(v.ptr)
+	if n < int(s.Len) || n > int(s.Cap) {
+		panic("reflect: slice capacity out of range in SetCap")
+	}
+	s.Cap = n
+}
+
+// SetMapIndex sets the value associated with key in the map v to val.
+// It panics if v's Kind is not Map.
+// If val is the zero Value, SetMapIndex deletes the key from the map.
+// Otherwise if v holds a nil map, SetMapIndex will panic.
+// As in Go, key's value must be assignable to the map's key type,
+// and val's value must be assignable to the map's value type.
+func (v Value) SetMapIndex(key, val Value) {
+	v.mustBe(Map)
+	v.mustBeExported()
+	key.mustBeExported()
+	tt := (*mapType)(unsafe.Pointer(v.typ))
+	key = key.assignTo("reflect.Value.SetMapIndex", tt.key, nil)
+	var k unsafe.Pointer
+	if key.flag&flagIndir != 0 {
+		k = key.ptr
+	} else {
+		k = unsafe.Pointer(&key.ptr)
+	}
+	if val.typ == nil {
+		mapdelete(v.typ, v.pointer(), k)
+		return
+	}
+	val.mustBeExported()
+	val = val.assignTo("reflect.Value.SetMapIndex", tt.elem, nil)
+	var e unsafe.Pointer
+	if val.flag&flagIndir != 0 {
+		e = val.ptr
+	} else {
+		e = unsafe.Pointer(&val.ptr)
+	}
+	mapassign(v.typ, v.pointer(), k, e)
+}
+
+// SetUint sets v's underlying value to x.
+// It panics if v's Kind is not Uint, Uintptr, Uint8, Uint16, Uint32, or Uint64, or if CanSet() is false.
+func (v Value) SetUint(x uint64) {
+	v.mustBeAssignable()
+	switch k := v.kind(); k {
+	default:
+		panic(&ValueError{"reflect.Value.SetUint", v.kind()})
+	case Uint:
+		*(*uint)(v.ptr) = uint(x)
+	case Uint8:
+		*(*uint8)(v.ptr) = uint8(x)
+	case Uint16:
+		*(*uint16)(v.ptr) = uint16(x)
+	case Uint32:
+		*(*uint32)(v.ptr) = uint32(x)
+	case Uint64:
+		*(*uint64)(v.ptr) = x
+	case Uintptr:
+		*(*uintptr)(v.ptr) = uintptr(x)
+	}
+}
+
+// SetPointer sets the unsafe.Pointer value v to x.
+// It panics if v's Kind is not UnsafePointer.
+func (v Value) SetPointer(x unsafe.Pointer) {
+	v.mustBeAssignable()
+	v.mustBe(UnsafePointer)
+	*(*unsafe.Pointer)(v.ptr) = x
+}
+
+// SetString sets v's underlying value to x.
+// It panics if v's Kind is not String or if CanSet() is false.
+func (v Value) SetString(x string) {
+	v.mustBeAssignable()
+	v.mustBe(String)
+	*(*string)(v.ptr) = x
+}
+
+// Slice returns v[i:j].
+// It panics if v's Kind is not Array, Slice or String, or if v is an unaddressable array,
+// or if the indexes are out of bounds.
+func (v Value) Slice(i, j int) Value {
+	var (
+		cap  int
+		typ  *sliceType
+		base unsafe.Pointer
+	)
+	switch kind := v.kind(); kind {
+	default:
+		panic(&ValueError{"reflect.Value.Slice", v.kind()})
+
+	case Array:
+		if v.flag&flagAddr == 0 {
+			panic("reflect.Value.Slice: slice of unaddressable array")
+		}
+		tt := (*arrayType)(unsafe.Pointer(v.typ))
+		cap = int(tt.len)
+		typ = (*sliceType)(unsafe.Pointer(tt.slice))
+		base = v.ptr
+
+	case Slice:
+		typ = (*sliceType)(unsafe.Pointer(v.typ))
+		s := (*sliceHeader)(v.ptr)
+		base = unsafe.Pointer(s.Data)
+		cap = s.Cap
+
+	case String:
+		s := (*stringHeader)(v.ptr)
+		if i < 0 || j < i || j > s.Len {
+			panic("reflect.Value.Slice: string slice index out of bounds")
+		}
+		t := stringHeader{unsafe.Pointer(uintptr(s.Data) + uintptr(i)), j - i}
+		return Value{v.typ, unsafe.Pointer(&t), v.flag}
+	}
+
+	if i < 0 || j < i || j > cap {
+		panic("reflect.Value.Slice: slice index out of bounds")
+	}
+
+	// Declare slice so that gc can see the base pointer in it.
+	var x []unsafe.Pointer
+
+	// Reinterpret as *sliceHeader to edit.
+	s := (*sliceHeader)(unsafe.Pointer(&x))
+	s.Len = j - i
+	s.Cap = cap - i
+	if cap-i > 0 {
+		s.Data = unsafe.Pointer(uintptr(base) + uintptr(i)*typ.elem.Size())
+	} else {
+		// do not advance pointer, to avoid pointing beyond end of slice
+		s.Data = base
+	}
+
+	fl := v.flag&flagRO | flagIndir | flag(Slice)
+	return Value{typ.common(), unsafe.Pointer(&x), fl}
+}
+
+// Slice3 is the 3-index form of the slice operation: it returns v[i:j:k].
+// It panics if v's Kind is not Array or Slice, or if v is an unaddressable array,
+// or if the indexes are out of bounds.
+func (v Value) Slice3(i, j, k int) Value {
+	var (
+		cap  int
+		typ  *sliceType
+		base unsafe.Pointer
+	)
+	switch kind := v.kind(); kind {
+	default:
+		panic(&ValueError{"reflect.Value.Slice3", v.kind()})
+
+	case Array:
+		if v.flag&flagAddr == 0 {
+			panic("reflect.Value.Slice3: slice of unaddressable array")
+		}
+		tt := (*arrayType)(unsafe.Pointer(v.typ))
+		cap = int(tt.len)
+		typ = (*sliceType)(unsafe.Pointer(tt.slice))
+		base = v.ptr
+
+	case Slice:
+		typ = (*sliceType)(unsafe.Pointer(v.typ))
+		s := (*sliceHeader)(v.ptr)
+		base = s.Data
+		cap = s.Cap
+	}
+
+	if i < 0 || j < i || k < j || k > cap {
+		panic("reflect.Value.Slice3: slice index out of bounds")
+	}
+
+	// Declare slice so that the garbage collector
+	// can see the base pointer in it.
+	var x []unsafe.Pointer
+
+	// Reinterpret as *sliceHeader to edit.
+	s := (*sliceHeader)(unsafe.Pointer(&x))
+	s.Len = j - i
+	s.Cap = k - i
+	if k-i > 0 {
+		s.Data = unsafe.Pointer(uintptr(base) + uintptr(i)*typ.elem.Size())
+	} else {
+		// do not advance pointer, to avoid pointing beyond end of slice
+		s.Data = base
+	}
+
+	fl := v.flag&flagRO | flagIndir | flag(Slice)
+	return Value{typ.common(), unsafe.Pointer(&x), fl}
+}
+
+// String returns the string v's underlying value, as a string.
+// String is a special case because of Go's String method convention.
+// Unlike the other getters, it does not panic if v's Kind is not String.
+// Instead, it returns a string of the form "<T value>" where T is v's type.
+func (v Value) String() string {
+	switch k := v.kind(); k {
+	case Invalid:
+		return "<invalid Value>"
+	case String:
+		return *(*string)(v.ptr)
+	}
+	// If you call String on a reflect.Value of other type, it's better to
+	// print something than to panic. Useful in debugging.
+	return "<" + v.Type().String() + " Value>"
+}
+
+// TryRecv attempts to receive a value from the channel v but will not block.
+// It panics if v's Kind is not Chan.
+// If the receive delivers a value, x is the transferred value and ok is true.
+// If the receive cannot finish without blocking, x is the zero Value and ok is false.
+// If the channel is closed, x is the zero value for the channel's element type and ok is false.
+func (v Value) TryRecv() (x Value, ok bool) {
+	v.mustBe(Chan)
+	v.mustBeExported()
+	return v.recv(true)
+}
+
+// TrySend attempts to send x on the channel v but will not block.
+// It panics if v's Kind is not Chan.
+// It returns true if the value was sent, false otherwise.
+// As in Go, x's value must be assignable to the channel's element type.
+func (v Value) TrySend(x Value) bool {
+	v.mustBe(Chan)
+	v.mustBeExported()
+	return v.send(x, true)
+}
+
+// Type returns v's type.
+func (v Value) Type() Type {
+	f := v.flag
+	if f == 0 {
+		panic(&ValueError{"reflect.Value.Type", Invalid})
+	}
+	if f&flagMethod == 0 {
+		// Easy case
+		return v.typ
+	}
+
+	// Method value.
+	// v.typ describes the receiver, not the method type.
+	i := int(v.flag) >> flagMethodShift
+	if v.typ.Kind() == Interface {
+		// Method on interface.
+		tt := (*interfaceType)(unsafe.Pointer(v.typ))
+		if uint(i) >= uint(len(tt.methods)) {
+			panic("reflect: internal error: invalid method index")
+		}
+		m := &tt.methods[i]
+		return m.typ
+	}
+	// Method on concrete type.
+	ut := v.typ.uncommon()
+	if ut == nil || uint(i) >= uint(len(ut.methods)) {
+		panic("reflect: internal error: invalid method index")
+	}
+	m := &ut.methods[i]
+	return m.mtyp
+}
+
+// Uint returns v's underlying value, as a uint64.
+// It panics if v's Kind is not Uint, Uintptr, Uint8, Uint16, Uint32, or Uint64.
+func (v Value) Uint() uint64 {
+	k := v.kind()
+	p := v.ptr
+	switch k {
+	case Uint:
+		return uint64(*(*uint)(p))
+	case Uint8:
+		return uint64(*(*uint8)(p))
+	case Uint16:
+		return uint64(*(*uint16)(p))
+	case Uint32:
+		return uint64(*(*uint32)(p))
+	case Uint64:
+		return uint64(*(*uint64)(p))
+	case Uintptr:
+		return uint64(*(*uintptr)(p))
+	}
+	panic(&ValueError{"reflect.Value.Uint", v.kind()})
+}
+
+// UnsafeAddr returns a pointer to v's data.
+// It is for advanced clients that also import the "unsafe" package.
+// It panics if v is not addressable.
+func (v Value) UnsafeAddr() uintptr {
+	// TODO: deprecate
+	if v.typ == nil {
+		panic(&ValueError{"reflect.Value.UnsafeAddr", Invalid})
+	}
+	if v.flag&flagAddr == 0 {
+		panic("reflect.Value.UnsafeAddr of unaddressable value")
+	}
+	return uintptr(v.ptr)
+}
+
+// StringHeader is the runtime representation of a string.
+// It cannot be used safely or portably and its representation may
+// change in a later release.
+// Moreover, the Data field is not sufficient to guarantee the data
+// it references will not be garbage collected, so programs must keep
+// a separate, correctly typed pointer to the underlying data.
+type StringHeader struct {
+	Data uintptr
+	Len  int
+}
+
+// stringHeader is a safe version of StringHeader used within this package.
+type stringHeader struct {
+	Data unsafe.Pointer
+	Len  int
+}
+
+// SliceHeader is the runtime representation of a slice.
+// It cannot be used safely or portably and its representation may
+// change in a later release.
+// Moreover, the Data field is not sufficient to guarantee the data
+// it references will not be garbage collected, so programs must keep
+// a separate, correctly typed pointer to the underlying data.
+type SliceHeader struct {
+	Data uintptr
+	Len  int
+	Cap  int
+}
+
+// sliceHeader is a safe version of SliceHeader used within this package.
+type sliceHeader struct {
+	Data unsafe.Pointer
+	Len  int
+	Cap  int
+}
+
+func typesMustMatch(what string, t1, t2 Type) {
+	if t1 != t2 {
+		panic(what + ": " + t1.String() + " != " + t2.String())
+	}
+}
+
+// grow grows the slice s so that it can hold extra more values, allocating
+// more capacity if needed. It also returns the old and new slice lengths.
+func grow(s Value, extra int) (Value, int, int) {
+	i0 := s.Len()
+	i1 := i0 + extra
+	if i1 < i0 {
+		panic("reflect.Append: slice overflow")
+	}
+	m := s.Cap()
+	if i1 <= m {
+		return s.Slice(0, i1), i0, i1
+	}
+	if m == 0 {
+		m = extra
+	} else {
+		for m < i1 {
+			if i0 < 1024 {
+				m += m
+			} else {
+				m += m / 4
+			}
+		}
+	}
+	t := MakeSlice(s.Type(), i1, m)
+	Copy(t, s)
+	return t, i0, i1
+}
+
+// Append appends the values x to a slice s and returns the resulting slice.
+// As in Go, each x's value must be assignable to the slice's element type.
+func Append(s Value, x ...Value) Value {
+	s.mustBe(Slice)
+	s, i0, i1 := grow(s, len(x))
+	for i, j := i0, 0; i < i1; i, j = i+1, j+1 {
+		s.Index(i).Set(x[j])
+	}
+	return s
+}
+
+// AppendSlice appends a slice t to a slice s and returns the resulting slice.
+// The slices s and t must have the same element type.
+func AppendSlice(s, t Value) Value {
+	s.mustBe(Slice)
+	t.mustBe(Slice)
+	typesMustMatch("reflect.AppendSlice", s.Type().Elem(), t.Type().Elem())
+	s, i0, i1 := grow(s, t.Len())
+	Copy(s.Slice(i0, i1), t)
+	return s
+}
+
+// Copy copies the contents of src into dst until either
+// dst has been filled or src has been exhausted.
+// It returns the number of elements copied.
+// Dst and src each must have kind Slice or Array, and
+// dst and src must have the same element type.
+func Copy(dst, src Value) int {
+	dk := dst.kind()
+	if dk != Array && dk != Slice {
+		panic(&ValueError{"reflect.Copy", dk})
+	}
+	if dk == Array {
+		dst.mustBeAssignable()
+	}
+	dst.mustBeExported()
+
+	sk := src.kind()
+	if sk != Array && sk != Slice {
+		panic(&ValueError{"reflect.Copy", sk})
+	}
+	src.mustBeExported()
+
+	de := dst.typ.Elem()
+	se := src.typ.Elem()
+	typesMustMatch("reflect.Copy", de, se)
+
+	n := dst.Len()
+	if sn := src.Len(); n > sn {
+		n = sn
+	}
+
+	// Copy via memmove.
+	var da, sa unsafe.Pointer
+	if dk == Array {
+		da = dst.ptr
+	} else {
+		da = (*sliceHeader)(dst.ptr).Data
+	}
+	if src.flag&flagIndir == 0 {
+		sa = unsafe.Pointer(&src.ptr)
+	} else if sk == Array {
+		sa = src.ptr
+	} else {
+		sa = (*sliceHeader)(src.ptr).Data
+	}
+	memmove(da, sa, uintptr(n)*de.Size())
+	return n
+}
+
+// A runtimeSelect is a single case passed to rselect.
+// This must match ../runtime/select.go:/runtimeSelect
+type runtimeSelect struct {
+	dir uintptr        // 0, SendDir, or RecvDir
+	typ *rtype         // channel type
+	ch  unsafe.Pointer // channel
+	val unsafe.Pointer // ptr to data (SendDir) or ptr to receive buffer (RecvDir)
+}
+
+// rselect runs a select.  It returns the index of the chosen case.
+// If the case was a receive, val is filled in with the received value.
+// The conventional OK bool indicates whether the receive corresponds
+// to a sent value.
+//go:noescape
+func rselect([]runtimeSelect) (chosen int, recvOK bool)
+
+// A SelectDir describes the communication direction of a select case.
+type SelectDir int
+
+// NOTE: These values must match ../runtime/select.go:/selectDir.
+
+const (
+	_             SelectDir = iota
+	SelectSend              // case Chan <- Send
+	SelectRecv              // case <-Chan:
+	SelectDefault           // default
+)
+
+// A SelectCase describes a single case in a select operation.
+// The kind of case depends on Dir, the communication direction.
+//
+// If Dir is SelectDefault, the case represents a default case.
+// Chan and Send must be zero Values.
+//
+// If Dir is SelectSend, the case represents a send operation.
+// Normally Chan's underlying value must be a channel, and Send's underlying value must be
+// assignable to the channel's element type. As a special case, if Chan is a zero Value,
+// then the case is ignored, and the field Send will also be ignored and may be either zero
+// or non-zero.
+//
+// If Dir is SelectRecv, the case represents a receive operation.
+// Normally Chan's underlying value must be a channel and Send must be a zero Value.
+// If Chan is a zero Value, then the case is ignored, but Send must still be a zero Value.
+// When a receive operation is selected, the received Value is returned by Select.
+//
+type SelectCase struct {
+	Dir  SelectDir // direction of case
+	Chan Value     // channel to use (for send or receive)
+	Send Value     // value to send (for send)
+}
+
+// Select executes a select operation described by the list of cases.
+// Like the Go select statement, it blocks until at least one of the cases
+// can proceed, makes a uniform pseudo-random choice,
+// and then executes that case. It returns the index of the chosen case
+// and, if that case was a receive operation, the value received and a
+// boolean indicating whether the value corresponds to a send on the channel
+// (as opposed to a zero value received because the channel is closed).
+func Select(cases []SelectCase) (chosen int, recv Value, recvOK bool) {
+	// NOTE: Do not trust that caller is not modifying cases data underfoot.
+	// The range is safe because the caller cannot modify our copy of the len
+	// and each iteration makes its own copy of the value c.
+	runcases := make([]runtimeSelect, len(cases))
+	haveDefault := false
+	for i, c := range cases {
+		rc := &runcases[i]
+		rc.dir = uintptr(c.Dir)
+		switch c.Dir {
+		default:
+			panic("reflect.Select: invalid Dir")
+
+		case SelectDefault: // default
+			if haveDefault {
+				panic("reflect.Select: multiple default cases")
+			}
+			haveDefault = true
+			if c.Chan.IsValid() {
+				panic("reflect.Select: default case has Chan value")
+			}
+			if c.Send.IsValid() {
+				panic("reflect.Select: default case has Send value")
+			}
+
+		case SelectSend:
+			ch := c.Chan
+			if !ch.IsValid() {
+				break
+			}
+			ch.mustBe(Chan)
+			ch.mustBeExported()
+			tt := (*chanType)(unsafe.Pointer(ch.typ))
+			if ChanDir(tt.dir)&SendDir == 0 {
+				panic("reflect.Select: SendDir case using recv-only channel")
+			}
+			rc.ch = ch.pointer()
+			rc.typ = &tt.rtype
+			v := c.Send
+			if !v.IsValid() {
+				panic("reflect.Select: SendDir case missing Send value")
+			}
+			v.mustBeExported()
+			v = v.assignTo("reflect.Select", tt.elem, nil)
+			if v.flag&flagIndir != 0 {
+				rc.val = v.ptr
+			} else {
+				rc.val = unsafe.Pointer(&v.ptr)
+			}
+
+		case SelectRecv:
+			if c.Send.IsValid() {
+				panic("reflect.Select: RecvDir case has Send value")
+			}
+			ch := c.Chan
+			if !ch.IsValid() {
+				break
+			}
+			ch.mustBe(Chan)
+			ch.mustBeExported()
+			tt := (*chanType)(unsafe.Pointer(ch.typ))
+			if ChanDir(tt.dir)&RecvDir == 0 {
+				panic("reflect.Select: RecvDir case using send-only channel")
+			}
+			rc.ch = ch.pointer()
+			rc.typ = &tt.rtype
+			rc.val = unsafe_New(tt.elem)
+		}
+	}
+
+	chosen, recvOK = rselect(runcases)
+	if runcases[chosen].dir == uintptr(SelectRecv) {
+		tt := (*chanType)(unsafe.Pointer(runcases[chosen].typ))
+		t := tt.elem
+		p := runcases[chosen].val
+		fl := flag(t.Kind())
+		if ifaceIndir(t) {
+			recv = Value{t, p, fl | flagIndir}
+		} else {
+			recv = Value{t, *(*unsafe.Pointer)(p), fl}
+		}
+	}
+	return chosen, recv, recvOK
+}
+
+/*
+ * constructors
+ */
+
+// implemented in package runtime
+func unsafe_New(*rtype) unsafe.Pointer
+func unsafe_NewArray(*rtype, int) unsafe.Pointer
+
+// MakeSlice creates a new zero-initialized slice value
+// for the specified slice type, length, and capacity.
+func MakeSlice(typ Type, len, cap int) Value {
+	if typ.Kind() != Slice {
+		panic("reflect.MakeSlice of non-slice type")
+	}
+	if len < 0 {
+		panic("reflect.MakeSlice: negative len")
+	}
+	if cap < 0 {
+		panic("reflect.MakeSlice: negative cap")
+	}
+	if len > cap {
+		panic("reflect.MakeSlice: len > cap")
+	}
+
+	s := sliceHeader{unsafe_NewArray(typ.Elem().(*rtype), cap), len, cap}
+	return Value{typ.common(), unsafe.Pointer(&s), flagIndir | flag(Slice)}
+}
+
+// MakeChan creates a new channel with the specified type and buffer size.
+func MakeChan(typ Type, buffer int) Value {
+	if typ.Kind() != Chan {
+		panic("reflect.MakeChan of non-chan type")
+	}
+	if buffer < 0 {
+		panic("reflect.MakeChan: negative buffer size")
+	}
+	if typ.ChanDir() != BothDir {
+		panic("reflect.MakeChan: unidirectional channel type")
+	}
+	ch := makechan(typ.(*rtype), uint64(buffer))
+	return Value{typ.common(), ch, flag(Chan)}
+}
+
+// MakeMap creates a new map of the specified type.
+func MakeMap(typ Type) Value {
+	if typ.Kind() != Map {
+		panic("reflect.MakeMap of non-map type")
+	}
+	m := makemap(typ.(*rtype))
+	return Value{typ.common(), m, flag(Map)}
+}
+
+// Indirect returns the value that v points to.
+// If v is a nil pointer, Indirect returns a zero Value.
+// If v is not a pointer, Indirect returns v.
+func Indirect(v Value) Value {
+	if v.Kind() != Ptr {
+		return v
+	}
+	return v.Elem()
+}
+
+// ValueOf returns a new Value initialized to the concrete value
+// stored in the interface i.  ValueOf(nil) returns the zero Value.
+func ValueOf(i interface{}) Value {
+	if i == nil {
+		return Value{}
+	}
+
+	// TODO(rsc): Eliminate this terrible hack.
+	// In the call to unpackEface, i.typ doesn't escape,
+	// and i.word is an integer.  So it looks like
+	// i doesn't escape.  But really it does,
+	// because i.word is actually a pointer.
+	escapes(i)
+
+	return unpackEface(i)
+}
+
+// Zero returns a Value representing the zero value for the specified type.
+// The result is different from the zero value of the Value struct,
+// which represents no value at all.
+// For example, Zero(TypeOf(42)) returns a Value with Kind Int and value 0.
+// The returned value is neither addressable nor settable.
+func Zero(typ Type) Value {
+	if typ == nil {
+		panic("reflect: Zero(nil)")
+	}
+	t := typ.common()
+	fl := flag(t.Kind())
+	if ifaceIndir(t) {
+		return Value{t, unsafe_New(typ.(*rtype)), fl | flagIndir}
+	}
+	return Value{t, nil, fl}
+}
+
+// New returns a Value representing a pointer to a new zero value
+// for the specified type.  That is, the returned Value's Type is PtrTo(typ).
+func New(typ Type) Value {
+	if typ == nil {
+		panic("reflect: New(nil)")
+	}
+	ptr := unsafe_New(typ.(*rtype))
+	fl := flag(Ptr)
+	return Value{typ.common().ptrTo(), ptr, fl}
+}
+
+// NewAt returns a Value representing a pointer to a value of the
+// specified type, using p as that pointer.
+func NewAt(typ Type, p unsafe.Pointer) Value {
+	fl := flag(Ptr)
+	return Value{typ.common().ptrTo(), p, fl}
+}
+
+// assignTo returns a value v that can be assigned directly to typ.
+// It panics if v is not assignable to typ.
+// For a conversion to an interface type, target is a suggested scratch space to use.
+func (v Value) assignTo(context string, dst *rtype, target unsafe.Pointer) Value {
+	if v.flag&flagMethod != 0 {
+		v = makeMethodValue(context, v)
+	}
+
+	switch {
+	case directlyAssignable(dst, v.typ):
+		// Overwrite type so that they match.
+		// Same memory layout, so no harm done.
+		v.typ = dst
+		fl := v.flag & (flagRO | flagAddr | flagIndir)
+		fl |= flag(dst.Kind())
+		return Value{dst, v.ptr, fl}
+
+	case implements(dst, v.typ):
+		if target == nil {
+			target = unsafe_New(dst)
+		}
+		x := valueInterface(v, false)
+		if dst.NumMethod() == 0 {
+			*(*interface{})(target) = x
+		} else {
+			ifaceE2I(dst, x, target)
+		}
+		return Value{dst, target, flagIndir | flag(Interface)}
+	}
+
+	// Failed.
+	panic(context + ": value of type " + v.typ.String() + " is not assignable to type " + dst.String())
+}
+
+// Convert returns the value v converted to type t.
+// If the usual Go conversion rules do not allow conversion
+// of the value v to type t, Convert panics.
+func (v Value) Convert(t Type) Value {
+	if v.flag&flagMethod != 0 {
+		v = makeMethodValue("Convert", v)
+	}
+	op := convertOp(t.common(), v.typ)
+	if op == nil {
+		panic("reflect.Value.Convert: value of type " + v.typ.String() + " cannot be converted to type " + t.String())
+	}
+	return op(v, t)
+}
+
+// convertOp returns the function to convert a value of type src
+// to a value of type dst. If the conversion is illegal, convertOp returns nil.
+func convertOp(dst, src *rtype) func(Value, Type) Value {
+	switch src.Kind() {
+	case Int, Int8, Int16, Int32, Int64:
+		switch dst.Kind() {
+		case Int, Int8, Int16, Int32, Int64, Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
+			return cvtInt
+		case Float32, Float64:
+			return cvtIntFloat
+		case String:
+			return cvtIntString
+		}
+
+	case Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
+		switch dst.Kind() {
+		case Int, Int8, Int16, Int32, Int64, Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
+			return cvtUint
+		case Float32, Float64:
+			return cvtUintFloat
+		case String:
+			return cvtUintString
+		}
+
+	case Float32, Float64:
+		switch dst.Kind() {
+		case Int, Int8, Int16, Int32, Int64:
+			return cvtFloatInt
+		case Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
+			return cvtFloatUint
+		case Float32, Float64:
+			return cvtFloat
+		}
+
+	case Complex64, Complex128:
+		switch dst.Kind() {
+		case Complex64, Complex128:
+			return cvtComplex
+		}
+
+	case String:
+		if dst.Kind() == Slice && dst.Elem().PkgPath() == "" {
+			switch dst.Elem().Kind() {
+			case Uint8:
+				return cvtStringBytes
+			case Int32:
+				return cvtStringRunes
+			}
+		}
+
+	case Slice:
+		if dst.Kind() == String && src.Elem().PkgPath() == "" {
+			switch src.Elem().Kind() {
+			case Uint8:
+				return cvtBytesString
+			case Int32:
+				return cvtRunesString
+			}
+		}
+	}
+
+	// dst and src have same underlying type.
+	if haveIdenticalUnderlyingType(dst, src) {
+		return cvtDirect
+	}
+
+	// dst and src are unnamed pointer types with same underlying base type.
+	if dst.Kind() == Ptr && dst.Name() == "" &&
+		src.Kind() == Ptr && src.Name() == "" &&
+		haveIdenticalUnderlyingType(dst.Elem().common(), src.Elem().common()) {
+		return cvtDirect
+	}
+
+	if implements(dst, src) {
+		if src.Kind() == Interface {
+			return cvtI2I
+		}
+		return cvtT2I
+	}
+
+	return nil
+}
+
+// makeInt returns a Value of type t equal to bits (possibly truncated),
+// where t is a signed or unsigned int type.
+func makeInt(f flag, bits uint64, t Type) Value {
+	typ := t.common()
+	ptr := unsafe_New(typ)
+	switch typ.size {
+	case 1:
+		*(*uint8)(unsafe.Pointer(ptr)) = uint8(bits)
+	case 2:
+		*(*uint16)(unsafe.Pointer(ptr)) = uint16(bits)
+	case 4:
+		*(*uint32)(unsafe.Pointer(ptr)) = uint32(bits)
+	case 8:
+		*(*uint64)(unsafe.Pointer(ptr)) = bits
+	}
+	return Value{typ, ptr, f | flagIndir | flag(typ.Kind())}
+}
+
+// makeFloat returns a Value of type t equal to v (possibly truncated to float32),
+// where t is a float32 or float64 type.
+func makeFloat(f flag, v float64, t Type) Value {
+	typ := t.common()
+	ptr := unsafe_New(typ)
+	switch typ.size {
+	case 4:
+		*(*float32)(unsafe.Pointer(ptr)) = float32(v)
+	case 8:
+		*(*float64)(unsafe.Pointer(ptr)) = v
+	}
+	return Value{typ, ptr, f | flagIndir | flag(typ.Kind())}
+}
+
+// makeComplex returns a Value of type t equal to v (possibly truncated to complex64),
+// where t is a complex64 or complex128 type.
+func makeComplex(f flag, v complex128, t Type) Value {
+	typ := t.common()
+	ptr := unsafe_New(typ)
+	switch typ.size {
+	case 8:
+		*(*complex64)(unsafe.Pointer(ptr)) = complex64(v)
+	case 16:
+		*(*complex128)(unsafe.Pointer(ptr)) = v
+	}
+	return Value{typ, ptr, f | flagIndir | flag(typ.Kind())}
+}
+
+func makeString(f flag, v string, t Type) Value {
+	ret := New(t).Elem()
+	ret.SetString(v)
+	ret.flag = ret.flag&^flagAddr | f
+	return ret
+}
+
+func makeBytes(f flag, v []byte, t Type) Value {
+	ret := New(t).Elem()
+	ret.SetBytes(v)
+	ret.flag = ret.flag&^flagAddr | f
+	return ret
+}
+
+func makeRunes(f flag, v []rune, t Type) Value {
+	ret := New(t).Elem()
+	ret.setRunes(v)
+	ret.flag = ret.flag&^flagAddr | f
+	return ret
+}
+
+// These conversion functions are returned by convertOp
+// for classes of conversions. For example, the first function, cvtInt,
+// takes any value v of signed int type and returns the value converted
+// to type t, where t is any signed or unsigned int type.
+
+// convertOp: intXX -> [u]intXX
+func cvtInt(v Value, t Type) Value {
+	return makeInt(v.flag&flagRO, uint64(v.Int()), t)
+}
+
+// convertOp: uintXX -> [u]intXX
+func cvtUint(v Value, t Type) Value {
+	return makeInt(v.flag&flagRO, v.Uint(), t)
+}
+
+// convertOp: floatXX -> intXX
+func cvtFloatInt(v Value, t Type) Value {
+	return makeInt(v.flag&flagRO, uint64(int64(v.Float())), t)
+}
+
+// convertOp: floatXX -> uintXX
+func cvtFloatUint(v Value, t Type) Value {
+	return makeInt(v.flag&flagRO, uint64(v.Float()), t)
+}
+
+// convertOp: intXX -> floatXX
+func cvtIntFloat(v Value, t Type) Value {
+	return makeFloat(v.flag&flagRO, float64(v.Int()), t)
+}
+
+// convertOp: uintXX -> floatXX
+func cvtUintFloat(v Value, t Type) Value {
+	return makeFloat(v.flag&flagRO, float64(v.Uint()), t)
+}
+
+// convertOp: floatXX -> floatXX
+func cvtFloat(v Value, t Type) Value {
+	return makeFloat(v.flag&flagRO, v.Float(), t)
+}
+
+// convertOp: complexXX -> complexXX
+func cvtComplex(v Value, t Type) Value {
+	return makeComplex(v.flag&flagRO, v.Complex(), t)
+}
+
+// convertOp: intXX -> string
+func cvtIntString(v Value, t Type) Value {
+	return makeString(v.flag&flagRO, string(v.Int()), t)
+}
+
+// convertOp: uintXX -> string
+func cvtUintString(v Value, t Type) Value {
+	return makeString(v.flag&flagRO, string(v.Uint()), t)
+}
+
+// convertOp: []byte -> string
+func cvtBytesString(v Value, t Type) Value {
+	return makeString(v.flag&flagRO, string(v.Bytes()), t)
+}
+
+// convertOp: string -> []byte
+func cvtStringBytes(v Value, t Type) Value {
+	return makeBytes(v.flag&flagRO, []byte(v.String()), t)
+}
+
+// convertOp: []rune -> string
+func cvtRunesString(v Value, t Type) Value {
+	return makeString(v.flag&flagRO, string(v.runes()), t)
+}
+
+// convertOp: string -> []rune
+func cvtStringRunes(v Value, t Type) Value {
+	return makeRunes(v.flag&flagRO, []rune(v.String()), t)
+}
+
+// convertOp: direct copy
+func cvtDirect(v Value, typ Type) Value {
+	f := v.flag
+	t := typ.common()
+	ptr := v.ptr
+	if f&flagAddr != 0 {
+		// indirect, mutable word - make a copy
+		c := unsafe_New(t)
+		memmove(c, ptr, t.size)
+		ptr = c
+		f &^= flagAddr
+	}
+	return Value{t, ptr, v.flag&flagRO | f} // v.flag&flagRO|f == f?
+}
+
+// convertOp: concrete -> interface
+func cvtT2I(v Value, typ Type) Value {
+	target := unsafe_New(typ.common())
+	x := valueInterface(v, false)
+	if typ.NumMethod() == 0 {
+		*(*interface{})(target) = x
+	} else {
+		ifaceE2I(typ.(*rtype), x, target)
+	}
+	return Value{typ.common(), target, v.flag&flagRO | flagIndir | flag(Interface)}
+}
+
+// convertOp: interface -> interface
+func cvtI2I(v Value, typ Type) Value {
+	if v.IsNil() {
+		ret := Zero(typ)
+		ret.flag |= v.flag & flagRO
+		return ret
+	}
+	return cvtT2I(v.Elem(), typ)
+}
+
+// implemented in ../runtime
+func chancap(ch unsafe.Pointer) int
+func chanclose(ch unsafe.Pointer)
+func chanlen(ch unsafe.Pointer) int
+
+//go:noescape
+func chanrecv(t *rtype, ch unsafe.Pointer, nb bool, val unsafe.Pointer) (selected, received bool)
+
+//go:noescape
+func chansend(t *rtype, ch unsafe.Pointer, val unsafe.Pointer, nb bool) bool
+
+func makechan(typ *rtype, size uint64) (ch unsafe.Pointer)
+func makemap(t *rtype) (m unsafe.Pointer)
+func mapaccess(t *rtype, m unsafe.Pointer, key unsafe.Pointer) (val unsafe.Pointer)
+func mapassign(t *rtype, m unsafe.Pointer, key, val unsafe.Pointer)
+func mapdelete(t *rtype, m unsafe.Pointer, key unsafe.Pointer)
+func mapiterinit(t *rtype, m unsafe.Pointer) unsafe.Pointer
+func mapiterkey(it unsafe.Pointer) (key unsafe.Pointer)
+func mapiternext(it unsafe.Pointer)
+func maplen(m unsafe.Pointer) int
+func call(fn, arg unsafe.Pointer, n uint32, retoffset uint32)
+
+func ifaceE2I(t *rtype, src interface{}, dst unsafe.Pointer)
+
+//go:noescape
+func memmove(adst, asrc unsafe.Pointer, n uintptr)
+
+// Dummy annotation marking that the value x escapes,
+// for use in cases where the reflect code is so clever that
+// the compiler cannot follow.
+func escapes(x interface{}) {
+	if dummy.b {
+		dummy.x = x
+	}
+}
+
+var dummy struct {
+	b bool
+	x interface{}
+}
diff --git a/src/regexp/all_test.go b/src/regexp/all_test.go
new file mode 100644
index 0000000..01ea374
--- /dev/null
+++ b/src/regexp/all_test.go
@@ -0,0 +1,656 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package regexp
+
+import (
+	"reflect"
+	"regexp/syntax"
+	"strings"
+	"testing"
+)
+
+var good_re = []string{
+	``,
+	`.`,
+	`^.$`,
+	`a`,
+	`a*`,
+	`a+`,
+	`a?`,
+	`a|b`,
+	`a*|b*`,
+	`(a*|b)(c*|d)`,
+	`[a-z]`,
+	`[a-abc-c\-\]\[]`,
+	`[a-z]+`,
+	`[abc]`,
+	`[^1234]`,
+	`[^\n]`,
+	`\!\\`,
+}
+
+type stringError struct {
+	re  string
+	err string
+}
+
+var bad_re = []stringError{
+	{`*`, "missing argument to repetition operator: `*`"},
+	{`+`, "missing argument to repetition operator: `+`"},
+	{`?`, "missing argument to repetition operator: `?`"},
+	{`(abc`, "missing closing ): `(abc`"},
+	{`abc)`, "unexpected ): `abc)`"},
+	{`x[a-z`, "missing closing ]: `[a-z`"},
+	{`[z-a]`, "invalid character class range: `z-a`"},
+	{`abc\`, "trailing backslash at end of expression"},
+	{`a**`, "invalid nested repetition operator: `**`"},
+	{`a*+`, "invalid nested repetition operator: `*+`"},
+	{`\x`, "invalid escape sequence: `\\x`"},
+}
+
+func compileTest(t *testing.T, expr string, error string) *Regexp {
+	re, err := Compile(expr)
+	if error == "" && err != nil {
+		t.Error("compiling `", expr, "`; unexpected error: ", err.Error())
+	}
+	if error != "" && err == nil {
+		t.Error("compiling `", expr, "`; missing error")
+	} else if error != "" && !strings.Contains(err.Error(), error) {
+		t.Error("compiling `", expr, "`; wrong error: ", err.Error(), "; want ", error)
+	}
+	return re
+}
+
+func TestGoodCompile(t *testing.T) {
+	for i := 0; i < len(good_re); i++ {
+		compileTest(t, good_re[i], "")
+	}
+}
+
+func TestBadCompile(t *testing.T) {
+	for i := 0; i < len(bad_re); i++ {
+		compileTest(t, bad_re[i].re, bad_re[i].err)
+	}
+}
+
+func matchTest(t *testing.T, test *FindTest) {
+	re := compileTest(t, test.pat, "")
+	if re == nil {
+		return
+	}
+	m := re.MatchString(test.text)
+	if m != (len(test.matches) > 0) {
+		t.Errorf("MatchString failure on %s: %t should be %t", test, m, len(test.matches) > 0)
+	}
+	// now try bytes
+	m = re.Match([]byte(test.text))
+	if m != (len(test.matches) > 0) {
+		t.Errorf("Match failure on %s: %t should be %t", test, m, len(test.matches) > 0)
+	}
+}
+
+func TestMatch(t *testing.T) {
+	for _, test := range findTests {
+		matchTest(t, &test)
+	}
+}
+
+func matchFunctionTest(t *testing.T, test *FindTest) {
+	m, err := MatchString(test.pat, test.text)
+	if err == nil {
+		return
+	}
+	if m != (len(test.matches) > 0) {
+		t.Errorf("Match failure on %s: %t should be %t", test, m, len(test.matches) > 0)
+	}
+}
+
+func TestMatchFunction(t *testing.T) {
+	for _, test := range findTests {
+		matchFunctionTest(t, &test)
+	}
+}
+
+type ReplaceTest struct {
+	pattern, replacement, input, output string
+}
+
+var replaceTests = []ReplaceTest{
+	// Test empty input and/or replacement, with pattern that matches the empty string.
+	{"", "", "", ""},
+	{"", "x", "", "x"},
+	{"", "", "abc", "abc"},
+	{"", "x", "abc", "xaxbxcx"},
+
+	// Test empty input and/or replacement, with pattern that does not match the empty string.
+	{"b", "", "", ""},
+	{"b", "x", "", ""},
+	{"b", "", "abc", "ac"},
+	{"b", "x", "abc", "axc"},
+	{"y", "", "", ""},
+	{"y", "x", "", ""},
+	{"y", "", "abc", "abc"},
+	{"y", "x", "abc", "abc"},
+
+	// Multibyte characters -- verify that we don't try to match in the middle
+	// of a character.
+	{"[a-c]*", "x", "\u65e5", "x\u65e5x"},
+	{"[^\u65e5]", "x", "abc\u65e5def", "xxx\u65e5xxx"},
+
+	// Start and end of a string.
+	{"^[a-c]*", "x", "abcdabc", "xdabc"},
+	{"[a-c]*$", "x", "abcdabc", "abcdx"},
+	{"^[a-c]*$", "x", "abcdabc", "abcdabc"},
+	{"^[a-c]*", "x", "abc", "x"},
+	{"[a-c]*$", "x", "abc", "x"},
+	{"^[a-c]*$", "x", "abc", "x"},
+	{"^[a-c]*", "x", "dabce", "xdabce"},
+	{"[a-c]*$", "x", "dabce", "dabcex"},
+	{"^[a-c]*$", "x", "dabce", "dabce"},
+	{"^[a-c]*", "x", "", "x"},
+	{"[a-c]*$", "x", "", "x"},
+	{"^[a-c]*$", "x", "", "x"},
+
+	{"^[a-c]+", "x", "abcdabc", "xdabc"},
+	{"[a-c]+$", "x", "abcdabc", "abcdx"},
+	{"^[a-c]+$", "x", "abcdabc", "abcdabc"},
+	{"^[a-c]+", "x", "abc", "x"},
+	{"[a-c]+$", "x", "abc", "x"},
+	{"^[a-c]+$", "x", "abc", "x"},
+	{"^[a-c]+", "x", "dabce", "dabce"},
+	{"[a-c]+$", "x", "dabce", "dabce"},
+	{"^[a-c]+$", "x", "dabce", "dabce"},
+	{"^[a-c]+", "x", "", ""},
+	{"[a-c]+$", "x", "", ""},
+	{"^[a-c]+$", "x", "", ""},
+
+	// Other cases.
+	{"abc", "def", "abcdefg", "defdefg"},
+	{"bc", "BC", "abcbcdcdedef", "aBCBCdcdedef"},
+	{"abc", "", "abcdabc", "d"},
+	{"x", "xXx", "xxxXxxx", "xXxxXxxXxXxXxxXxxXx"},
+	{"abc", "d", "", ""},
+	{"abc", "d", "abc", "d"},
+	{".+", "x", "abc", "x"},
+	{"[a-c]*", "x", "def", "xdxexfx"},
+	{"[a-c]+", "x", "abcbcdcdedef", "xdxdedef"},
+	{"[a-c]*", "x", "abcbcdcdedef", "xdxdxexdxexfx"},
+
+	// Substitutions
+	{"a+", "($0)", "banana", "b(a)n(a)n(a)"},
+	{"a+", "(${0})", "banana", "b(a)n(a)n(a)"},
+	{"a+", "(${0})$0", "banana", "b(a)an(a)an(a)a"},
+	{"a+", "(${0})$0", "banana", "b(a)an(a)an(a)a"},
+	{"hello, (.+)", "goodbye, ${1}", "hello, world", "goodbye, world"},
+	{"hello, (.+)", "goodbye, $1x", "hello, world", "goodbye, "},
+	{"hello, (.+)", "goodbye, ${1}x", "hello, world", "goodbye, worldx"},
+	{"hello, (.+)", "<$0><$1><$2><$3>", "hello, world", "<hello, world><world><><>"},
+	{"hello, (?P<noun>.+)", "goodbye, $noun!", "hello, world", "goodbye, world!"},
+	{"hello, (?P<noun>.+)", "goodbye, ${noun}", "hello, world", "goodbye, world"},
+	{"(?P<x>hi)|(?P<x>bye)", "$x$x$x", "hi", "hihihi"},
+	{"(?P<x>hi)|(?P<x>bye)", "$x$x$x", "bye", "byebyebye"},
+	{"(?P<x>hi)|(?P<x>bye)", "$xyz", "hi", ""},
+	{"(?P<x>hi)|(?P<x>bye)", "${x}yz", "hi", "hiyz"},
+	{"(?P<x>hi)|(?P<x>bye)", "hello $$x", "hi", "hello $x"},
+	{"a+", "${oops", "aaa", "${oops"},
+	{"a+", "$$", "aaa", "$"},
+	{"a+", "$", "aaa", "$"},
+
+	// Substitution when subexpression isn't found
+	{"(x)?", "$1", "123", "123"},
+	{"abc", "$1", "123", "123"},
+}
+
+var replaceLiteralTests = []ReplaceTest{
+	// Substitutions
+	{"a+", "($0)", "banana", "b($0)n($0)n($0)"},
+	{"a+", "(${0})", "banana", "b(${0})n(${0})n(${0})"},
+	{"a+", "(${0})$0", "banana", "b(${0})$0n(${0})$0n(${0})$0"},
+	{"a+", "(${0})$0", "banana", "b(${0})$0n(${0})$0n(${0})$0"},
+	{"hello, (.+)", "goodbye, ${1}", "hello, world", "goodbye, ${1}"},
+	{"hello, (?P<noun>.+)", "goodbye, $noun!", "hello, world", "goodbye, $noun!"},
+	{"hello, (?P<noun>.+)", "goodbye, ${noun}", "hello, world", "goodbye, ${noun}"},
+	{"(?P<x>hi)|(?P<x>bye)", "$x$x$x", "hi", "$x$x$x"},
+	{"(?P<x>hi)|(?P<x>bye)", "$x$x$x", "bye", "$x$x$x"},
+	{"(?P<x>hi)|(?P<x>bye)", "$xyz", "hi", "$xyz"},
+	{"(?P<x>hi)|(?P<x>bye)", "${x}yz", "hi", "${x}yz"},
+	{"(?P<x>hi)|(?P<x>bye)", "hello $$x", "hi", "hello $$x"},
+	{"a+", "${oops", "aaa", "${oops"},
+	{"a+", "$$", "aaa", "$$"},
+	{"a+", "$", "aaa", "$"},
+}
+
+type ReplaceFuncTest struct {
+	pattern       string
+	replacement   func(string) string
+	input, output string
+}
+
+var replaceFuncTests = []ReplaceFuncTest{
+	{"[a-c]", func(s string) string { return "x" + s + "y" }, "defabcdef", "defxayxbyxcydef"},
+	{"[a-c]+", func(s string) string { return "x" + s + "y" }, "defabcdef", "defxabcydef"},
+	{"[a-c]*", func(s string) string { return "x" + s + "y" }, "defabcdef", "xydxyexyfxabcydxyexyfxy"},
+}
+
+func TestReplaceAll(t *testing.T) {
+	for _, tc := range replaceTests {
+		re, err := Compile(tc.pattern)
+		if err != nil {
+			t.Errorf("Unexpected error compiling %q: %v", tc.pattern, err)
+			continue
+		}
+		actual := re.ReplaceAllString(tc.input, tc.replacement)
+		if actual != tc.output {
+			t.Errorf("%q.ReplaceAllString(%q,%q) = %q; want %q",
+				tc.pattern, tc.input, tc.replacement, actual, tc.output)
+		}
+		// now try bytes
+		actual = string(re.ReplaceAll([]byte(tc.input), []byte(tc.replacement)))
+		if actual != tc.output {
+			t.Errorf("%q.ReplaceAll(%q,%q) = %q; want %q",
+				tc.pattern, tc.input, tc.replacement, actual, tc.output)
+		}
+	}
+}
+
+func TestReplaceAllLiteral(t *testing.T) {
+	// Run ReplaceAll tests that do not have $ expansions.
+	for _, tc := range replaceTests {
+		if strings.Contains(tc.replacement, "$") {
+			continue
+		}
+		re, err := Compile(tc.pattern)
+		if err != nil {
+			t.Errorf("Unexpected error compiling %q: %v", tc.pattern, err)
+			continue
+		}
+		actual := re.ReplaceAllLiteralString(tc.input, tc.replacement)
+		if actual != tc.output {
+			t.Errorf("%q.ReplaceAllLiteralString(%q,%q) = %q; want %q",
+				tc.pattern, tc.input, tc.replacement, actual, tc.output)
+		}
+		// now try bytes
+		actual = string(re.ReplaceAllLiteral([]byte(tc.input), []byte(tc.replacement)))
+		if actual != tc.output {
+			t.Errorf("%q.ReplaceAllLiteral(%q,%q) = %q; want %q",
+				tc.pattern, tc.input, tc.replacement, actual, tc.output)
+		}
+	}
+
+	// Run literal-specific tests.
+	for _, tc := range replaceLiteralTests {
+		re, err := Compile(tc.pattern)
+		if err != nil {
+			t.Errorf("Unexpected error compiling %q: %v", tc.pattern, err)
+			continue
+		}
+		actual := re.ReplaceAllLiteralString(tc.input, tc.replacement)
+		if actual != tc.output {
+			t.Errorf("%q.ReplaceAllLiteralString(%q,%q) = %q; want %q",
+				tc.pattern, tc.input, tc.replacement, actual, tc.output)
+		}
+		// now try bytes
+		actual = string(re.ReplaceAllLiteral([]byte(tc.input), []byte(tc.replacement)))
+		if actual != tc.output {
+			t.Errorf("%q.ReplaceAllLiteral(%q,%q) = %q; want %q",
+				tc.pattern, tc.input, tc.replacement, actual, tc.output)
+		}
+	}
+}
+
+func TestReplaceAllFunc(t *testing.T) {
+	for _, tc := range replaceFuncTests {
+		re, err := Compile(tc.pattern)
+		if err != nil {
+			t.Errorf("Unexpected error compiling %q: %v", tc.pattern, err)
+			continue
+		}
+		actual := re.ReplaceAllStringFunc(tc.input, tc.replacement)
+		if actual != tc.output {
+			t.Errorf("%q.ReplaceFunc(%q,fn) = %q; want %q",
+				tc.pattern, tc.input, actual, tc.output)
+		}
+		// now try bytes
+		actual = string(re.ReplaceAllFunc([]byte(tc.input), func(s []byte) []byte { return []byte(tc.replacement(string(s))) }))
+		if actual != tc.output {
+			t.Errorf("%q.ReplaceFunc(%q,fn) = %q; want %q",
+				tc.pattern, tc.input, actual, tc.output)
+		}
+	}
+}
+
+type MetaTest struct {
+	pattern, output, literal string
+	isLiteral                bool
+}
+
+var metaTests = []MetaTest{
+	{``, ``, ``, true},
+	{`foo`, `foo`, `foo`, true},
+	{`foo\.\$`, `foo\\\.\\\$`, `foo.$`, true}, // has meta but no operator
+	{`foo.\$`, `foo\.\\\$`, `foo`, false},     // has escaped operators and real operators
+	{`!@#$%^&*()_+-=[{]}\|,<.>/?~`, `!@#\$%\^&\*\(\)_\+-=\[\{\]\}\\\|,<\.>/\?~`, `!@#`, false},
+}
+
+func TestQuoteMeta(t *testing.T) {
+	for _, tc := range metaTests {
+		// Verify that QuoteMeta returns the expected string.
+		quoted := QuoteMeta(tc.pattern)
+		if quoted != tc.output {
+			t.Errorf("QuoteMeta(`%s`) = `%s`; want `%s`",
+				tc.pattern, quoted, tc.output)
+			continue
+		}
+
+		// Verify that the quoted string is in fact treated as expected
+		// by Compile -- i.e. that it matches the original, unquoted string.
+		if tc.pattern != "" {
+			re, err := Compile(quoted)
+			if err != nil {
+				t.Errorf("Unexpected error compiling QuoteMeta(`%s`): %v", tc.pattern, err)
+				continue
+			}
+			src := "abc" + tc.pattern + "def"
+			repl := "xyz"
+			replaced := re.ReplaceAllString(src, repl)
+			expected := "abcxyzdef"
+			if replaced != expected {
+				t.Errorf("QuoteMeta(`%s`).Replace(`%s`,`%s`) = `%s`; want `%s`",
+					tc.pattern, src, repl, replaced, expected)
+			}
+		}
+	}
+}
+
+func TestLiteralPrefix(t *testing.T) {
+	for _, tc := range metaTests {
+		// Literal method needs to scan the pattern.
+		re := MustCompile(tc.pattern)
+		str, complete := re.LiteralPrefix()
+		if complete != tc.isLiteral {
+			t.Errorf("LiteralPrefix(`%s`) = %t; want %t", tc.pattern, complete, tc.isLiteral)
+		}
+		if str != tc.literal {
+			t.Errorf("LiteralPrefix(`%s`) = `%s`; want `%s`", tc.pattern, str, tc.literal)
+		}
+	}
+}
+
+type subexpCase struct {
+	input string
+	num   int
+	names []string
+}
+
+var subexpCases = []subexpCase{
+	{``, 0, nil},
+	{`.*`, 0, nil},
+	{`abba`, 0, nil},
+	{`ab(b)a`, 1, []string{"", ""}},
+	{`ab(.*)a`, 1, []string{"", ""}},
+	{`(.*)ab(.*)a`, 2, []string{"", "", ""}},
+	{`(.*)(ab)(.*)a`, 3, []string{"", "", "", ""}},
+	{`(.*)((a)b)(.*)a`, 4, []string{"", "", "", "", ""}},
+	{`(.*)(\(ab)(.*)a`, 3, []string{"", "", "", ""}},
+	{`(.*)(\(a\)b)(.*)a`, 3, []string{"", "", "", ""}},
+	{`(?P<foo>.*)(?P<bar>(a)b)(?P<foo>.*)a`, 4, []string{"", "foo", "bar", "", "foo"}},
+}
+
+func TestSubexp(t *testing.T) {
+	for _, c := range subexpCases {
+		re := MustCompile(c.input)
+		n := re.NumSubexp()
+		if n != c.num {
+			t.Errorf("%q: NumSubexp = %d, want %d", c.input, n, c.num)
+			continue
+		}
+		names := re.SubexpNames()
+		if len(names) != 1+n {
+			t.Errorf("%q: len(SubexpNames) = %d, want %d", c.input, len(names), n)
+			continue
+		}
+		if c.names != nil {
+			for i := 0; i < 1+n; i++ {
+				if names[i] != c.names[i] {
+					t.Errorf("%q: SubexpNames[%d] = %q, want %q", c.input, i, names[i], c.names[i])
+				}
+			}
+		}
+	}
+}
+
+var splitTests = []struct {
+	s   string
+	r   string
+	n   int
+	out []string
+}{
+	{"foo:and:bar", ":", -1, []string{"foo", "and", "bar"}},
+	{"foo:and:bar", ":", 1, []string{"foo:and:bar"}},
+	{"foo:and:bar", ":", 2, []string{"foo", "and:bar"}},
+	{"foo:and:bar", "foo", -1, []string{"", ":and:bar"}},
+	{"foo:and:bar", "bar", -1, []string{"foo:and:", ""}},
+	{"foo:and:bar", "baz", -1, []string{"foo:and:bar"}},
+	{"baabaab", "a", -1, []string{"b", "", "b", "", "b"}},
+	{"baabaab", "a*", -1, []string{"b", "b", "b"}},
+	{"baabaab", "ba*", -1, []string{"", "", "", ""}},
+	{"foobar", "f*b*", -1, []string{"", "o", "o", "a", "r"}},
+	{"foobar", "f+.*b+", -1, []string{"", "ar"}},
+	{"foobooboar", "o{2}", -1, []string{"f", "b", "boar"}},
+	{"a,b,c,d,e,f", ",", 3, []string{"a", "b", "c,d,e,f"}},
+	{"a,b,c,d,e,f", ",", 0, nil},
+	{",", ",", -1, []string{"", ""}},
+	{",,,", ",", -1, []string{"", "", "", ""}},
+	{"", ",", -1, []string{""}},
+	{"", ".*", -1, []string{""}},
+	{"", ".+", -1, []string{""}},
+	{"", "", -1, []string{}},
+	{"foobar", "", -1, []string{"f", "o", "o", "b", "a", "r"}},
+	{"abaabaccadaaae", "a*", 5, []string{"", "b", "b", "c", "cadaaae"}},
+	{":x:y:z:", ":", -1, []string{"", "x", "y", "z", ""}},
+}
+
+func TestSplit(t *testing.T) {
+	for i, test := range splitTests {
+		re, err := Compile(test.r)
+		if err != nil {
+			t.Errorf("#%d: %q: compile error: %s", i, test.r, err.Error())
+			continue
+		}
+
+		split := re.Split(test.s, test.n)
+		if !reflect.DeepEqual(split, test.out) {
+			t.Errorf("#%d: %q: got %q; want %q", i, test.r, split, test.out)
+		}
+
+		if QuoteMeta(test.r) == test.r {
+			strsplit := strings.SplitN(test.s, test.r, test.n)
+			if !reflect.DeepEqual(split, strsplit) {
+				t.Errorf("#%d: Split(%q, %q, %d): regexp vs strings mismatch\nregexp=%q\nstrings=%q", i, test.s, test.r, test.n, split, strsplit)
+			}
+		}
+	}
+}
+
+// Check that one-pass cutoff does trigger.
+func TestOnePassCutoff(t *testing.T) {
+	re, err := syntax.Parse(`^x{1,1000}y{1,1000}$`, syntax.Perl)
+	if err != nil {
+		t.Fatalf("parse: %v", err)
+	}
+	p, err := syntax.Compile(re.Simplify())
+	if err != nil {
+		t.Fatalf("compile: %v", err)
+	}
+	if compileOnePass(p) != notOnePass {
+		t.Fatalf("makeOnePass succeeded; wanted notOnePass")
+	}
+}
+
+func BenchmarkLiteral(b *testing.B) {
+	x := strings.Repeat("x", 50) + "y"
+	b.StopTimer()
+	re := MustCompile("y")
+	b.StartTimer()
+	for i := 0; i < b.N; i++ {
+		if !re.MatchString(x) {
+			b.Fatalf("no match!")
+		}
+	}
+}
+
+func BenchmarkNotLiteral(b *testing.B) {
+	x := strings.Repeat("x", 50) + "y"
+	b.StopTimer()
+	re := MustCompile(".y")
+	b.StartTimer()
+	for i := 0; i < b.N; i++ {
+		if !re.MatchString(x) {
+			b.Fatalf("no match!")
+		}
+	}
+}
+
+func BenchmarkMatchClass(b *testing.B) {
+	b.StopTimer()
+	x := strings.Repeat("xxxx", 20) + "w"
+	re := MustCompile("[abcdw]")
+	b.StartTimer()
+	for i := 0; i < b.N; i++ {
+		if !re.MatchString(x) {
+			b.Fatalf("no match!")
+		}
+	}
+}
+
+func BenchmarkMatchClass_InRange(b *testing.B) {
+	b.StopTimer()
+	// 'b' is between 'a' and 'c', so the charclass
+	// range checking is no help here.
+	x := strings.Repeat("bbbb", 20) + "c"
+	re := MustCompile("[ac]")
+	b.StartTimer()
+	for i := 0; i < b.N; i++ {
+		if !re.MatchString(x) {
+			b.Fatalf("no match!")
+		}
+	}
+}
+
+func BenchmarkReplaceAll(b *testing.B) {
+	x := "abcdefghijklmnopqrstuvwxyz"
+	b.StopTimer()
+	re := MustCompile("[cjrw]")
+	b.StartTimer()
+	for i := 0; i < b.N; i++ {
+		re.ReplaceAllString(x, "")
+	}
+}
+
+func BenchmarkAnchoredLiteralShortNonMatch(b *testing.B) {
+	b.StopTimer()
+	x := []byte("abcdefghijklmnopqrstuvwxyz")
+	re := MustCompile("^zbc(d|e)")
+	b.StartTimer()
+	for i := 0; i < b.N; i++ {
+		re.Match(x)
+	}
+}
+
+func BenchmarkAnchoredLiteralLongNonMatch(b *testing.B) {
+	b.StopTimer()
+	x := []byte("abcdefghijklmnopqrstuvwxyz")
+	for i := 0; i < 15; i++ {
+		x = append(x, x...)
+	}
+	re := MustCompile("^zbc(d|e)")
+	b.StartTimer()
+	for i := 0; i < b.N; i++ {
+		re.Match(x)
+	}
+}
+
+func BenchmarkAnchoredShortMatch(b *testing.B) {
+	b.StopTimer()
+	x := []byte("abcdefghijklmnopqrstuvwxyz")
+	re := MustCompile("^.bc(d|e)")
+	b.StartTimer()
+	for i := 0; i < b.N; i++ {
+		re.Match(x)
+	}
+}
+
+func BenchmarkAnchoredLongMatch(b *testing.B) {
+	b.StopTimer()
+	x := []byte("abcdefghijklmnopqrstuvwxyz")
+	for i := 0; i < 15; i++ {
+		x = append(x, x...)
+	}
+	re := MustCompile("^.bc(d|e)")
+	b.StartTimer()
+	for i := 0; i < b.N; i++ {
+		re.Match(x)
+	}
+}
+
+func BenchmarkOnePassShortA(b *testing.B) {
+	b.StopTimer()
+	x := []byte("abcddddddeeeededd")
+	re := MustCompile("^.bc(d|e)*$")
+	b.StartTimer()
+	for i := 0; i < b.N; i++ {
+		re.Match(x)
+	}
+}
+
+func BenchmarkNotOnePassShortA(b *testing.B) {
+	b.StopTimer()
+	x := []byte("abcddddddeeeededd")
+	re := MustCompile(".bc(d|e)*$")
+	b.StartTimer()
+	for i := 0; i < b.N; i++ {
+		re.Match(x)
+	}
+}
+
+func BenchmarkOnePassShortB(b *testing.B) {
+	b.StopTimer()
+	x := []byte("abcddddddeeeededd")
+	re := MustCompile("^.bc(?:d|e)*$")
+	b.StartTimer()
+	for i := 0; i < b.N; i++ {
+		re.Match(x)
+	}
+}
+
+func BenchmarkNotOnePassShortB(b *testing.B) {
+	b.StopTimer()
+	x := []byte("abcddddddeeeededd")
+	re := MustCompile(".bc(?:d|e)*$")
+	b.StartTimer()
+	for i := 0; i < b.N; i++ {
+		re.Match(x)
+	}
+}
+
+func BenchmarkOnePassLongPrefix(b *testing.B) {
+	b.StopTimer()
+	x := []byte("abcdefghijklmnopqrstuvwxyz")
+	re := MustCompile("^abcdefghijklmnopqrstuvwxyz.*$")
+	b.StartTimer()
+	for i := 0; i < b.N; i++ {
+		re.Match(x)
+	}
+}
+
+func BenchmarkOnePassLongNotPrefix(b *testing.B) {
+	b.StopTimer()
+	x := []byte("abcdefghijklmnopqrstuvwxyz")
+	re := MustCompile("^.bcdefghijklmnopqrstuvwxyz.*$")
+	b.StartTimer()
+	for i := 0; i < b.N; i++ {
+		re.Match(x)
+	}
+}
diff --git a/src/pkg/regexp/example_test.go b/src/regexp/example_test.go
similarity index 100%
rename from src/pkg/regexp/example_test.go
rename to src/regexp/example_test.go
diff --git a/src/pkg/regexp/exec.go b/src/regexp/exec.go
similarity index 100%
rename from src/pkg/regexp/exec.go
rename to src/regexp/exec.go
diff --git a/src/pkg/regexp/exec2_test.go b/src/regexp/exec2_test.go
similarity index 100%
rename from src/pkg/regexp/exec2_test.go
rename to src/regexp/exec2_test.go
diff --git a/src/pkg/regexp/exec_test.go b/src/regexp/exec_test.go
similarity index 100%
rename from src/pkg/regexp/exec_test.go
rename to src/regexp/exec_test.go
diff --git a/src/pkg/regexp/find_test.go b/src/regexp/find_test.go
similarity index 100%
rename from src/pkg/regexp/find_test.go
rename to src/regexp/find_test.go
diff --git a/src/regexp/onepass.go b/src/regexp/onepass.go
new file mode 100644
index 0000000..e6f4285
--- /dev/null
+++ b/src/regexp/onepass.go
@@ -0,0 +1,581 @@
+// 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 regexp
+
+import (
+	"bytes"
+	"regexp/syntax"
+	"sort"
+	"unicode"
+)
+
+// "One-pass" regexp execution.
+// Some regexps can be analyzed to determine that they never need
+// backtracking: they are guaranteed to run in one pass over the string
+// without bothering to save all the usual NFA state.
+// Detect those and execute them more quickly.
+
+// A onePassProg is a compiled one-pass regular expression program.
+// It is the same as syntax.Prog except for the use of onePassInst.
+type onePassProg struct {
+	Inst   []onePassInst
+	Start  int // index of start instruction
+	NumCap int // number of InstCapture insts in re
+}
+
+// A onePassInst is a single instruction in a one-pass regular expression program.
+// It is the same as syntax.Inst except for the new 'Next' field.
+type onePassInst struct {
+	syntax.Inst
+	Next []uint32
+}
+
+// OnePassPrefix returns a literal string that all matches for the
+// regexp must start with.  Complete is true if the prefix
+// is the entire match. Pc is the index of the last rune instruction
+// in the string. The OnePassPrefix skips over the mandatory
+// EmptyBeginText
+func onePassPrefix(p *syntax.Prog) (prefix string, complete bool, pc uint32) {
+	i := &p.Inst[p.Start]
+	if i.Op != syntax.InstEmptyWidth || (syntax.EmptyOp(i.Arg))&syntax.EmptyBeginText == 0 {
+		return "", i.Op == syntax.InstMatch, uint32(p.Start)
+	}
+	pc = i.Out
+	i = &p.Inst[pc]
+	for i.Op == syntax.InstNop {
+		pc = i.Out
+		i = &p.Inst[pc]
+	}
+	// Avoid allocation of buffer if prefix is empty.
+	if iop(i) != syntax.InstRune || len(i.Rune) != 1 {
+		return "", i.Op == syntax.InstMatch, uint32(p.Start)
+	}
+
+	// Have prefix; gather characters.
+	var buf bytes.Buffer
+	for iop(i) == syntax.InstRune && len(i.Rune) == 1 && syntax.Flags(i.Arg)&syntax.FoldCase == 0 {
+		buf.WriteRune(i.Rune[0])
+		pc, i = i.Out, &p.Inst[i.Out]
+	}
+	return buf.String(), i.Op == syntax.InstEmptyWidth && (syntax.EmptyOp(i.Arg))&syntax.EmptyBeginText != 0, pc
+}
+
+// OnePassNext selects the next actionable state of the prog, based on the input character.
+// It should only be called when i.Op == InstAlt or InstAltMatch, and from the one-pass machine.
+// One of the alternates may ultimately lead without input to end of line. If the instruction
+// is InstAltMatch the path to the InstMatch is in i.Out, the normal node in i.Next.
+func onePassNext(i *onePassInst, r rune) uint32 {
+	next := i.MatchRunePos(r)
+	if next >= 0 {
+		return i.Next[next]
+	}
+	if i.Op == syntax.InstAltMatch {
+		return i.Out
+	}
+	return 0
+}
+
+func iop(i *syntax.Inst) syntax.InstOp {
+	op := i.Op
+	switch op {
+	case syntax.InstRune1, syntax.InstRuneAny, syntax.InstRuneAnyNotNL:
+		op = syntax.InstRune
+	}
+	return op
+}
+
+// Sparse Array implementation is used as a queueOnePass.
+type queueOnePass struct {
+	sparse          []uint32
+	dense           []uint32
+	size, nextIndex uint32
+}
+
+func (q *queueOnePass) empty() bool {
+	return q.nextIndex >= q.size
+}
+
+func (q *queueOnePass) next() (n uint32) {
+	n = q.dense[q.nextIndex]
+	q.nextIndex++
+	return
+}
+
+func (q *queueOnePass) clear() {
+	q.size = 0
+	q.nextIndex = 0
+}
+
+func (q *queueOnePass) reset() {
+	q.nextIndex = 0
+}
+
+func (q *queueOnePass) contains(u uint32) bool {
+	if u >= uint32(len(q.sparse)) {
+		return false
+	}
+	return q.sparse[u] < q.size && q.dense[q.sparse[u]] == u
+}
+
+func (q *queueOnePass) insert(u uint32) {
+	if !q.contains(u) {
+		q.insertNew(u)
+	}
+}
+
+func (q *queueOnePass) insertNew(u uint32) {
+	if u >= uint32(len(q.sparse)) {
+		return
+	}
+	q.sparse[u] = q.size
+	q.dense[q.size] = u
+	q.size++
+}
+
+func newQueue(size int) (q *queueOnePass) {
+	return &queueOnePass{
+		sparse: make([]uint32, size),
+		dense:  make([]uint32, size),
+	}
+}
+
+// mergeRuneSets merges two non-intersecting runesets, and returns the merged result,
+// and a NextIp array. The idea is that if a rune matches the OnePassRunes at index
+// i, NextIp[i/2] is the target. If the input sets intersect, an empty runeset and a
+// NextIp array with the single element mergeFailed is returned.
+// The code assumes that both inputs contain ordered and non-intersecting rune pairs.
+const mergeFailed = uint32(0xffffffff)
+
+var (
+	noRune = []rune{}
+	noNext = []uint32{mergeFailed}
+)
+
+func mergeRuneSets(leftRunes, rightRunes *[]rune, leftPC, rightPC uint32) ([]rune, []uint32) {
+	leftLen := len(*leftRunes)
+	rightLen := len(*rightRunes)
+	if leftLen&0x1 != 0 || rightLen&0x1 != 0 {
+		panic("mergeRuneSets odd length []rune")
+	}
+	var (
+		lx, rx int
+	)
+	merged := make([]rune, 0)
+	next := make([]uint32, 0)
+	ok := true
+	defer func() {
+		if !ok {
+			merged = nil
+			next = nil
+		}
+	}()
+
+	ix := -1
+	extend := func(newLow *int, newArray *[]rune, pc uint32) bool {
+		if ix > 0 && (*newArray)[*newLow] <= merged[ix] {
+			return false
+		}
+		merged = append(merged, (*newArray)[*newLow], (*newArray)[*newLow+1])
+		*newLow += 2
+		ix += 2
+		next = append(next, pc)
+		return true
+	}
+
+	for lx < leftLen || rx < rightLen {
+		switch {
+		case rx >= rightLen:
+			ok = extend(&lx, leftRunes, leftPC)
+		case lx >= leftLen:
+			ok = extend(&rx, rightRunes, rightPC)
+		case (*rightRunes)[rx] < (*leftRunes)[lx]:
+			ok = extend(&rx, rightRunes, rightPC)
+		default:
+			ok = extend(&lx, leftRunes, leftPC)
+		}
+		if !ok {
+			return noRune, noNext
+		}
+	}
+	return merged, next
+}
+
+// cleanupOnePass drops working memory, and restores certain shortcut instructions.
+func cleanupOnePass(prog *onePassProg, original *syntax.Prog) {
+	for ix, instOriginal := range original.Inst {
+		switch instOriginal.Op {
+		case syntax.InstAlt, syntax.InstAltMatch, syntax.InstRune:
+		case syntax.InstCapture, syntax.InstEmptyWidth, syntax.InstNop, syntax.InstMatch, syntax.InstFail:
+			prog.Inst[ix].Next = nil
+		case syntax.InstRune1, syntax.InstRuneAny, syntax.InstRuneAnyNotNL:
+			prog.Inst[ix].Next = nil
+			prog.Inst[ix] = onePassInst{Inst: instOriginal}
+		}
+	}
+}
+
+// onePassCopy creates a copy of the original Prog, as we'll be modifying it
+func onePassCopy(prog *syntax.Prog) *onePassProg {
+	p := &onePassProg{
+		Start:  prog.Start,
+		NumCap: prog.NumCap,
+	}
+	for _, inst := range prog.Inst {
+		p.Inst = append(p.Inst, onePassInst{Inst: inst})
+	}
+
+	// rewrites one or more common Prog constructs that enable some otherwise
+	// non-onepass Progs to be onepass. A:BD (for example) means an InstAlt at
+	// ip A, that points to ips B & C.
+	// A:BC + B:DA => A:BC + B:CD
+	// A:BC + B:DC => A:DC + B:DC
+	for pc := range p.Inst {
+		switch p.Inst[pc].Op {
+		default:
+			continue
+		case syntax.InstAlt, syntax.InstAltMatch:
+			// A:Bx + B:Ay
+			p_A_Other := &p.Inst[pc].Out
+			p_A_Alt := &p.Inst[pc].Arg
+			// make sure a target is another Alt
+			instAlt := p.Inst[*p_A_Alt]
+			if !(instAlt.Op == syntax.InstAlt || instAlt.Op == syntax.InstAltMatch) {
+				p_A_Alt, p_A_Other = p_A_Other, p_A_Alt
+				instAlt = p.Inst[*p_A_Alt]
+				if !(instAlt.Op == syntax.InstAlt || instAlt.Op == syntax.InstAltMatch) {
+					continue
+				}
+			}
+			instOther := p.Inst[*p_A_Other]
+			// Analyzing both legs pointing to Alts is for another day
+			if instOther.Op == syntax.InstAlt || instOther.Op == syntax.InstAltMatch {
+				// too complicated
+				continue
+			}
+			// simple empty transition loop
+			// A:BC + B:DA => A:BC + B:DC
+			p_B_Alt := &p.Inst[*p_A_Alt].Out
+			p_B_Other := &p.Inst[*p_A_Alt].Arg
+			patch := false
+			if instAlt.Out == uint32(pc) {
+				patch = true
+			} else if instAlt.Arg == uint32(pc) {
+				patch = true
+				p_B_Alt, p_B_Other = p_B_Other, p_B_Alt
+			}
+			if patch {
+				*p_B_Alt = *p_A_Other
+			}
+
+			// empty transition to common target
+			// A:BC + B:DC => A:DC + B:DC
+			if *p_A_Other == *p_B_Alt {
+				*p_A_Alt = *p_B_Other
+			}
+		}
+	}
+	return p
+}
+
+// runeSlice exists to permit sorting the case-folded rune sets.
+type runeSlice []rune
+
+func (p runeSlice) Len() int           { return len(p) }
+func (p runeSlice) Less(i, j int) bool { return p[i] < p[j] }
+func (p runeSlice) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
+
+// Sort is a convenience method.
+func (p runeSlice) Sort() {
+	sort.Sort(p)
+}
+
+var anyRuneNotNL = []rune{0, '\n' - 1, '\n' + 1, unicode.MaxRune}
+var anyRune = []rune{0, unicode.MaxRune}
+
+// makeOnePass creates a onepass Prog, if possible. It is possible if at any alt,
+// the match engine can always tell which branch to take. The routine may modify
+// p if it is turned into a onepass Prog. If it isn't possible for this to be a
+// onepass Prog, the Prog notOnePass is returned. makeOnePass is recursive
+// to the size of the Prog.
+func makeOnePass(p *onePassProg) *onePassProg {
+	// If the machine is very long, it's not worth the time to check if we can use one pass.
+	if len(p.Inst) >= 1000 {
+		return notOnePass
+	}
+
+	var (
+		instQueue    = newQueue(len(p.Inst))
+		visitQueue   = newQueue(len(p.Inst))
+		build        func(uint32, *queueOnePass)
+		check        func(uint32, map[uint32]bool) bool
+		onePassRunes = make([][]rune, len(p.Inst))
+	)
+	build = func(pc uint32, q *queueOnePass) {
+		if q.contains(pc) {
+			return
+		}
+		inst := p.Inst[pc]
+		switch inst.Op {
+		case syntax.InstAlt, syntax.InstAltMatch:
+			q.insert(inst.Out)
+			build(inst.Out, q)
+			q.insert(inst.Arg)
+		case syntax.InstMatch, syntax.InstFail:
+		default:
+			q.insert(inst.Out)
+		}
+	}
+
+	// check that paths from Alt instructions are unambiguous, and rebuild the new
+	// program as a onepass program
+	check = func(pc uint32, m map[uint32]bool) (ok bool) {
+		ok = true
+		inst := &p.Inst[pc]
+		if visitQueue.contains(pc) {
+			return
+		}
+		visitQueue.insert(pc)
+		switch inst.Op {
+		case syntax.InstAlt, syntax.InstAltMatch:
+			ok = check(inst.Out, m) && check(inst.Arg, m)
+			// check no-input paths to InstMatch
+			matchOut := m[inst.Out]
+			matchArg := m[inst.Arg]
+			if matchOut && matchArg {
+				ok = false
+				break
+			}
+			// Match on empty goes in inst.Out
+			if matchArg {
+				inst.Out, inst.Arg = inst.Arg, inst.Out
+				matchOut, matchArg = matchArg, matchOut
+			}
+			if matchOut {
+				m[pc] = true
+				inst.Op = syntax.InstAltMatch
+			}
+
+			// build a dispatch operator from the two legs of the alt.
+			onePassRunes[pc], inst.Next = mergeRuneSets(
+				&onePassRunes[inst.Out], &onePassRunes[inst.Arg], inst.Out, inst.Arg)
+			if len(inst.Next) > 0 && inst.Next[0] == mergeFailed {
+				ok = false
+				break
+			}
+		case syntax.InstCapture, syntax.InstNop:
+			ok = check(inst.Out, m)
+			m[pc] = m[inst.Out]
+			// pass matching runes back through these no-ops.
+			onePassRunes[pc] = append([]rune{}, onePassRunes[inst.Out]...)
+			inst.Next = []uint32{}
+			for i := len(onePassRunes[pc]) / 2; i >= 0; i-- {
+				inst.Next = append(inst.Next, inst.Out)
+			}
+		case syntax.InstEmptyWidth:
+			ok = check(inst.Out, m)
+			m[pc] = m[inst.Out]
+			onePassRunes[pc] = append([]rune{}, onePassRunes[inst.Out]...)
+			inst.Next = []uint32{}
+			for i := len(onePassRunes[pc]) / 2; i >= 0; i-- {
+				inst.Next = append(inst.Next, inst.Out)
+			}
+		case syntax.InstMatch, syntax.InstFail:
+			m[pc] = inst.Op == syntax.InstMatch
+			break
+		case syntax.InstRune:
+			ok = check(inst.Out, m)
+			m[pc] = false
+			if len(inst.Next) > 0 {
+				break
+			}
+			if len(inst.Rune) == 0 {
+				onePassRunes[pc] = []rune{}
+				inst.Next = []uint32{inst.Out}
+				break
+			}
+			runes := make([]rune, 0)
+			if len(inst.Rune) == 1 && syntax.Flags(inst.Arg)&syntax.FoldCase != 0 {
+				r0 := inst.Rune[0]
+				runes = append(runes, r0, r0)
+				for r1 := unicode.SimpleFold(r0); r1 != r0; r1 = unicode.SimpleFold(r1) {
+					runes = append(runes, r1, r1)
+				}
+				sort.Sort(runeSlice(runes))
+			} else {
+				runes = append(runes, inst.Rune...)
+			}
+			onePassRunes[pc] = runes
+			inst.Next = []uint32{}
+			for i := len(onePassRunes[pc]) / 2; i >= 0; i-- {
+				inst.Next = append(inst.Next, inst.Out)
+			}
+			inst.Op = syntax.InstRune
+		case syntax.InstRune1:
+			ok = check(inst.Out, m)
+			m[pc] = false
+			if len(inst.Next) > 0 {
+				break
+			}
+			runes := []rune{}
+			// expand case-folded runes
+			if syntax.Flags(inst.Arg)&syntax.FoldCase != 0 {
+				r0 := inst.Rune[0]
+				runes = append(runes, r0, r0)
+				for r1 := unicode.SimpleFold(r0); r1 != r0; r1 = unicode.SimpleFold(r1) {
+					runes = append(runes, r1, r1)
+				}
+				sort.Sort(runeSlice(runes))
+			} else {
+				runes = append(runes, inst.Rune[0], inst.Rune[0])
+			}
+			onePassRunes[pc] = runes
+			inst.Next = []uint32{}
+			for i := len(onePassRunes[pc]) / 2; i >= 0; i-- {
+				inst.Next = append(inst.Next, inst.Out)
+			}
+			inst.Op = syntax.InstRune
+		case syntax.InstRuneAny:
+			ok = check(inst.Out, m)
+			m[pc] = false
+			if len(inst.Next) > 0 {
+				break
+			}
+			onePassRunes[pc] = append([]rune{}, anyRune...)
+			inst.Next = []uint32{inst.Out}
+		case syntax.InstRuneAnyNotNL:
+			ok = check(inst.Out, m)
+			m[pc] = false
+			if len(inst.Next) > 0 {
+				break
+			}
+			onePassRunes[pc] = append([]rune{}, anyRuneNotNL...)
+			inst.Next = []uint32{}
+			for i := len(onePassRunes[pc]) / 2; i >= 0; i-- {
+				inst.Next = append(inst.Next, inst.Out)
+			}
+		}
+		return
+	}
+
+	instQueue.clear()
+	instQueue.insert(uint32(p.Start))
+	m := make(map[uint32]bool, len(p.Inst))
+	for !instQueue.empty() {
+		pc := instQueue.next()
+		inst := p.Inst[pc]
+		visitQueue.clear()
+		if !check(uint32(pc), m) {
+			p = notOnePass
+			break
+		}
+		switch inst.Op {
+		case syntax.InstAlt, syntax.InstAltMatch:
+			instQueue.insert(inst.Out)
+			instQueue.insert(inst.Arg)
+		case syntax.InstCapture, syntax.InstEmptyWidth, syntax.InstNop:
+			instQueue.insert(inst.Out)
+		case syntax.InstMatch:
+		case syntax.InstFail:
+		case syntax.InstRune, syntax.InstRune1, syntax.InstRuneAny, syntax.InstRuneAnyNotNL:
+		default:
+		}
+	}
+	if p != notOnePass {
+		for i := range p.Inst {
+			p.Inst[i].Rune = onePassRunes[i]
+		}
+	}
+	return p
+}
+
+// walk visits each Inst in the prog once, and applies the argument
+// function(ip, next), in pre-order.
+func walk(prog *syntax.Prog, funcs ...func(ip, next uint32)) {
+	var walk1 func(uint32)
+	progQueue := newQueue(len(prog.Inst))
+	walk1 = func(ip uint32) {
+		if progQueue.contains(ip) {
+			return
+		}
+		progQueue.insert(ip)
+		inst := prog.Inst[ip]
+		switch inst.Op {
+		case syntax.InstAlt, syntax.InstAltMatch:
+			for _, f := range funcs {
+				f(ip, inst.Out)
+				f(ip, inst.Arg)
+			}
+			walk1(inst.Out)
+			walk1(inst.Arg)
+		default:
+			for _, f := range funcs {
+				f(ip, inst.Out)
+			}
+			walk1(inst.Out)
+		}
+	}
+	walk1(uint32(prog.Start))
+}
+
+// find returns the Insts that match the argument predicate function
+func find(prog *syntax.Prog, f func(*syntax.Prog, int) bool) (matches []uint32) {
+	matches = []uint32{}
+
+	for ip := range prog.Inst {
+		if f(prog, ip) {
+			matches = append(matches, uint32(ip))
+		}
+	}
+	return
+}
+
+var notOnePass *onePassProg = nil
+
+// compileOnePass returns a new *syntax.Prog suitable for onePass execution if the original Prog
+// can be recharacterized as a one-pass regexp program, or syntax.notOnePass if the
+// Prog cannot be converted. For a one pass prog, the fundamental condition that must
+// be true is: at any InstAlt, there must be no ambiguity about what branch to  take.
+func compileOnePass(prog *syntax.Prog) (p *onePassProg) {
+	if prog.Start == 0 {
+		return notOnePass
+	}
+	// onepass regexp is anchored
+	if prog.Inst[prog.Start].Op != syntax.InstEmptyWidth ||
+		syntax.EmptyOp(prog.Inst[prog.Start].Arg)&syntax.EmptyBeginText != syntax.EmptyBeginText {
+		return notOnePass
+	}
+	// every instruction leading to InstMatch must be EmptyEndText
+	for _, inst := range prog.Inst {
+		opOut := prog.Inst[inst.Out].Op
+		switch inst.Op {
+		default:
+			if opOut == syntax.InstMatch {
+				return notOnePass
+			}
+		case syntax.InstAlt, syntax.InstAltMatch:
+			if opOut == syntax.InstMatch || prog.Inst[inst.Arg].Op == syntax.InstMatch {
+				return notOnePass
+			}
+		case syntax.InstEmptyWidth:
+			if opOut == syntax.InstMatch {
+				if syntax.EmptyOp(inst.Arg)&syntax.EmptyEndText == syntax.EmptyEndText {
+					continue
+				}
+				return notOnePass
+			}
+		}
+	}
+	// Creates a slightly optimized copy of the original Prog
+	// that cleans up some Prog idioms that block valid onepass programs
+	p = onePassCopy(prog)
+
+	// checkAmbiguity on InstAlts, build onepass Prog if possible
+	p = makeOnePass(p)
+
+	if p != notOnePass {
+		cleanupOnePass(p, prog)
+	}
+	return p
+}
diff --git a/src/pkg/regexp/onepass_test.go b/src/regexp/onepass_test.go
similarity index 100%
rename from src/pkg/regexp/onepass_test.go
rename to src/regexp/onepass_test.go
diff --git a/src/regexp/regexp.go b/src/regexp/regexp.go
new file mode 100644
index 0000000..b615acd
--- /dev/null
+++ b/src/regexp/regexp.go
@@ -0,0 +1,1120 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package regexp implements regular expression search.
+//
+// The syntax of the regular expressions accepted is the same
+// general syntax used by Perl, Python, and other languages.
+// More precisely, it is the syntax accepted by RE2 and described at
+// http://code.google.com/p/re2/wiki/Syntax, except for \C.
+// For an overview of the syntax, run
+//   godoc regexp/syntax
+//
+// The regexp implementation provided by this package is
+// guaranteed to run in time linear in the size of the input.
+// (This is a property not guaranteed by most open source
+// implementations of regular expressions.) For more information
+// about this property, see
+//	http://swtch.com/~rsc/regexp/regexp1.html
+// or any book about automata theory.
+//
+// All characters are UTF-8-encoded code points.
+//
+// There are 16 methods of Regexp that match a regular expression and identify
+// the matched text.  Their names are matched by this regular expression:
+//
+//	Find(All)?(String)?(Submatch)?(Index)?
+//
+// If 'All' is present, the routine matches successive non-overlapping
+// matches of the entire expression.  Empty matches abutting a preceding
+// match are ignored.  The return value is a slice containing the successive
+// return values of the corresponding non-'All' routine.  These routines take
+// an extra integer argument, n; if n >= 0, the function returns at most n
+// matches/submatches.
+//
+// If 'String' is present, the argument is a string; otherwise it is a slice
+// of bytes; return values are adjusted as appropriate.
+//
+// If 'Submatch' is present, the return value is a slice identifying the
+// successive submatches of the expression. Submatches are matches of
+// parenthesized subexpressions (also known as capturing groups) within the
+// regular expression, numbered from left to right in order of opening
+// parenthesis. Submatch 0 is the match of the entire expression, submatch 1
+// the match of the first parenthesized subexpression, and so on.
+//
+// If 'Index' is present, matches and submatches are identified by byte index
+// pairs within the input string: result[2*n:2*n+1] identifies the indexes of
+// the nth submatch.  The pair for n==0 identifies the match of the entire
+// expression.  If 'Index' is not present, the match is identified by the
+// text of the match/submatch.  If an index is negative, it means that
+// subexpression did not match any string in the input.
+//
+// There is also a subset of the methods that can be applied to text read
+// from a RuneReader:
+//
+//	MatchReader, FindReaderIndex, FindReaderSubmatchIndex
+//
+// This set may grow.  Note that regular expression matches may need to
+// examine text beyond the text returned by a match, so the methods that
+// match text from a RuneReader may read arbitrarily far into the input
+// before returning.
+//
+// (There are a few other methods that do not match this pattern.)
+//
+package regexp
+
+import (
+	"bytes"
+	"io"
+	"regexp/syntax"
+	"strconv"
+	"strings"
+	"sync"
+	"unicode"
+	"unicode/utf8"
+)
+
+var debug = false
+
+// Regexp is the representation of a compiled regular expression.
+// A Regexp is safe for concurrent use by multiple goroutines.
+type Regexp struct {
+	// read-only after Compile
+	expr           string         // as passed to Compile
+	prog           *syntax.Prog   // compiled program
+	onepass        *onePassProg   // onpass program or nil
+	prefix         string         // required prefix in unanchored matches
+	prefixBytes    []byte         // prefix, as a []byte
+	prefixComplete bool           // prefix is the entire regexp
+	prefixRune     rune           // first rune in prefix
+	prefixEnd      uint32         // pc for last rune in prefix
+	cond           syntax.EmptyOp // empty-width conditions required at start of match
+	numSubexp      int
+	subexpNames    []string
+	longest        bool
+
+	// cache of machines for running regexp
+	mu      sync.Mutex
+	machine []*machine
+}
+
+// String returns the source text used to compile the regular expression.
+func (re *Regexp) String() string {
+	return re.expr
+}
+
+// Compile parses a regular expression and returns, if successful,
+// a Regexp object that can be used to match against text.
+//
+// When matching against text, the regexp returns a match that
+// begins as early as possible in the input (leftmost), and among those
+// it chooses the one that a backtracking search would have found first.
+// This so-called leftmost-first matching is the same semantics
+// that Perl, Python, and other implementations use, although this
+// package implements it without the expense of backtracking.
+// For POSIX leftmost-longest matching, see CompilePOSIX.
+func Compile(expr string) (*Regexp, error) {
+	return compile(expr, syntax.Perl, false)
+}
+
+// CompilePOSIX is like Compile but restricts the regular expression
+// to POSIX ERE (egrep) syntax and changes the match semantics to
+// leftmost-longest.
+//
+// That is, when matching against text, the regexp returns a match that
+// begins as early as possible in the input (leftmost), and among those
+// it chooses a match that is as long as possible.
+// This so-called leftmost-longest matching is the same semantics
+// that early regular expression implementations used and that POSIX
+// specifies.
+//
+// However, there can be multiple leftmost-longest matches, with different
+// submatch choices, and here this package diverges from POSIX.
+// Among the possible leftmost-longest matches, this package chooses
+// the one that a backtracking search would have found first, while POSIX
+// specifies that the match be chosen to maximize the length of the first
+// subexpression, then the second, and so on from left to right.
+// The POSIX rule is computationally prohibitive and not even well-defined.
+// See http://swtch.com/~rsc/regexp/regexp2.html#posix for details.
+func CompilePOSIX(expr string) (*Regexp, error) {
+	return compile(expr, syntax.POSIX, true)
+}
+
+// Longest makes future searches prefer the leftmost-longest match.
+// That is, when matching against text, the regexp returns a match that
+// begins as early as possible in the input (leftmost), and among those
+// it chooses a match that is as long as possible.
+func (re *Regexp) Longest() {
+	re.longest = true
+}
+
+func compile(expr string, mode syntax.Flags, longest bool) (*Regexp, error) {
+	re, err := syntax.Parse(expr, mode)
+	if err != nil {
+		return nil, err
+	}
+	maxCap := re.MaxCap()
+	capNames := re.CapNames()
+
+	re = re.Simplify()
+	prog, err := syntax.Compile(re)
+	if err != nil {
+		return nil, err
+	}
+	regexp := &Regexp{
+		expr:        expr,
+		prog:        prog,
+		onepass:     compileOnePass(prog),
+		numSubexp:   maxCap,
+		subexpNames: capNames,
+		cond:        prog.StartCond(),
+		longest:     longest,
+	}
+	if regexp.onepass == notOnePass {
+		regexp.prefix, regexp.prefixComplete = prog.Prefix()
+	} else {
+		regexp.prefix, regexp.prefixComplete, regexp.prefixEnd = onePassPrefix(prog)
+	}
+	if regexp.prefix != "" {
+		// TODO(rsc): Remove this allocation by adding
+		// IndexString to package bytes.
+		regexp.prefixBytes = []byte(regexp.prefix)
+		regexp.prefixRune, _ = utf8.DecodeRuneInString(regexp.prefix)
+	}
+	return regexp, nil
+}
+
+// get returns a machine to use for matching re.
+// It uses the re's machine cache if possible, to avoid
+// unnecessary allocation.
+func (re *Regexp) get() *machine {
+	re.mu.Lock()
+	if n := len(re.machine); n > 0 {
+		z := re.machine[n-1]
+		re.machine = re.machine[:n-1]
+		re.mu.Unlock()
+		return z
+	}
+	re.mu.Unlock()
+	z := progMachine(re.prog, re.onepass)
+	z.re = re
+	return z
+}
+
+// put returns a machine to the re's machine cache.
+// There is no attempt to limit the size of the cache, so it will
+// grow to the maximum number of simultaneous matches
+// run using re.  (The cache empties when re gets garbage collected.)
+func (re *Regexp) put(z *machine) {
+	re.mu.Lock()
+	re.machine = append(re.machine, z)
+	re.mu.Unlock()
+}
+
+// MustCompile is like Compile but panics if the expression cannot be parsed.
+// It simplifies safe initialization of global variables holding compiled regular
+// expressions.
+func MustCompile(str string) *Regexp {
+	regexp, error := Compile(str)
+	if error != nil {
+		panic(`regexp: Compile(` + quote(str) + `): ` + error.Error())
+	}
+	return regexp
+}
+
+// MustCompilePOSIX is like CompilePOSIX but panics if the expression cannot be parsed.
+// It simplifies safe initialization of global variables holding compiled regular
+// expressions.
+func MustCompilePOSIX(str string) *Regexp {
+	regexp, error := CompilePOSIX(str)
+	if error != nil {
+		panic(`regexp: CompilePOSIX(` + quote(str) + `): ` + error.Error())
+	}
+	return regexp
+}
+
+func quote(s string) string {
+	if strconv.CanBackquote(s) {
+		return "`" + s + "`"
+	}
+	return strconv.Quote(s)
+}
+
+// NumSubexp returns the number of parenthesized subexpressions in this Regexp.
+func (re *Regexp) NumSubexp() int {
+	return re.numSubexp
+}
+
+// SubexpNames returns the names of the parenthesized subexpressions
+// in this Regexp.  The name for the first sub-expression is names[1],
+// so that if m is a match slice, the name for m[i] is SubexpNames()[i].
+// Since the Regexp as a whole cannot be named, names[0] is always
+// the empty string.  The slice should not be modified.
+func (re *Regexp) SubexpNames() []string {
+	return re.subexpNames
+}
+
+const endOfText rune = -1
+
+// input abstracts different representations of the input text. It provides
+// one-character lookahead.
+type input interface {
+	step(pos int) (r rune, width int) // advance one rune
+	canCheckPrefix() bool             // can we look ahead without losing info?
+	hasPrefix(re *Regexp) bool
+	index(re *Regexp, pos int) int
+	context(pos int) syntax.EmptyOp
+}
+
+// inputString scans a string.
+type inputString struct {
+	str string
+}
+
+func (i *inputString) step(pos int) (rune, int) {
+	if pos < len(i.str) {
+		c := i.str[pos]
+		if c < utf8.RuneSelf {
+			return rune(c), 1
+		}
+		return utf8.DecodeRuneInString(i.str[pos:])
+	}
+	return endOfText, 0
+}
+
+func (i *inputString) canCheckPrefix() bool {
+	return true
+}
+
+func (i *inputString) hasPrefix(re *Regexp) bool {
+	return strings.HasPrefix(i.str, re.prefix)
+}
+
+func (i *inputString) index(re *Regexp, pos int) int {
+	return strings.Index(i.str[pos:], re.prefix)
+}
+
+func (i *inputString) context(pos int) syntax.EmptyOp {
+	r1, r2 := endOfText, endOfText
+	if pos > 0 && pos <= len(i.str) {
+		r1, _ = utf8.DecodeLastRuneInString(i.str[:pos])
+	}
+	if pos < len(i.str) {
+		r2, _ = utf8.DecodeRuneInString(i.str[pos:])
+	}
+	return syntax.EmptyOpContext(r1, r2)
+}
+
+// inputBytes scans a byte slice.
+type inputBytes struct {
+	str []byte
+}
+
+func (i *inputBytes) step(pos int) (rune, int) {
+	if pos < len(i.str) {
+		c := i.str[pos]
+		if c < utf8.RuneSelf {
+			return rune(c), 1
+		}
+		return utf8.DecodeRune(i.str[pos:])
+	}
+	return endOfText, 0
+}
+
+func (i *inputBytes) canCheckPrefix() bool {
+	return true
+}
+
+func (i *inputBytes) hasPrefix(re *Regexp) bool {
+	return bytes.HasPrefix(i.str, re.prefixBytes)
+}
+
+func (i *inputBytes) index(re *Regexp, pos int) int {
+	return bytes.Index(i.str[pos:], re.prefixBytes)
+}
+
+func (i *inputBytes) context(pos int) syntax.EmptyOp {
+	r1, r2 := endOfText, endOfText
+	if pos > 0 && pos <= len(i.str) {
+		r1, _ = utf8.DecodeLastRune(i.str[:pos])
+	}
+	if pos < len(i.str) {
+		r2, _ = utf8.DecodeRune(i.str[pos:])
+	}
+	return syntax.EmptyOpContext(r1, r2)
+}
+
+// inputReader scans a RuneReader.
+type inputReader struct {
+	r     io.RuneReader
+	atEOT bool
+	pos   int
+}
+
+func (i *inputReader) step(pos int) (rune, int) {
+	if !i.atEOT && pos != i.pos {
+		return endOfText, 0
+
+	}
+	r, w, err := i.r.ReadRune()
+	if err != nil {
+		i.atEOT = true
+		return endOfText, 0
+	}
+	i.pos += w
+	return r, w
+}
+
+func (i *inputReader) canCheckPrefix() bool {
+	return false
+}
+
+func (i *inputReader) hasPrefix(re *Regexp) bool {
+	return false
+}
+
+func (i *inputReader) index(re *Regexp, pos int) int {
+	return -1
+}
+
+func (i *inputReader) context(pos int) syntax.EmptyOp {
+	return 0
+}
+
+// LiteralPrefix returns a literal string that must begin any match
+// of the regular expression re.  It returns the boolean true if the
+// literal string comprises the entire regular expression.
+func (re *Regexp) LiteralPrefix() (prefix string, complete bool) {
+	return re.prefix, re.prefixComplete
+}
+
+// MatchReader reports whether the Regexp matches the text read by the
+// RuneReader.
+func (re *Regexp) MatchReader(r io.RuneReader) bool {
+	return re.doExecute(r, nil, "", 0, 0) != nil
+}
+
+// MatchString reports whether the Regexp matches the string s.
+func (re *Regexp) MatchString(s string) bool {
+	return re.doExecute(nil, nil, s, 0, 0) != nil
+}
+
+// Match reports whether the Regexp matches the byte slice b.
+func (re *Regexp) Match(b []byte) bool {
+	return re.doExecute(nil, b, "", 0, 0) != nil
+}
+
+// MatchReader checks whether a textual regular expression matches the text
+// read by the RuneReader.  More complicated queries need to use Compile and
+// the full Regexp interface.
+func MatchReader(pattern string, r io.RuneReader) (matched bool, err error) {
+	re, err := Compile(pattern)
+	if err != nil {
+		return false, err
+	}
+	return re.MatchReader(r), nil
+}
+
+// MatchString checks whether a textual regular expression
+// matches a string.  More complicated queries need
+// to use Compile and the full Regexp interface.
+func MatchString(pattern string, s string) (matched bool, err error) {
+	re, err := Compile(pattern)
+	if err != nil {
+		return false, err
+	}
+	return re.MatchString(s), nil
+}
+
+// Match checks whether a textual regular expression
+// matches a byte slice.  More complicated queries need
+// to use Compile and the full Regexp interface.
+func Match(pattern string, b []byte) (matched bool, err error) {
+	re, err := Compile(pattern)
+	if err != nil {
+		return false, err
+	}
+	return re.Match(b), nil
+}
+
+// ReplaceAllString returns a copy of src, replacing matches of the Regexp
+// with the replacement string repl.  Inside repl, $ signs are interpreted as
+// 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 {
+		n = 2 * (re.numSubexp + 1)
+	}
+	b := re.replaceAll(nil, src, n, func(dst []byte, match []int) []byte {
+		return re.expand(dst, repl, nil, src, match)
+	})
+	return string(b)
+}
+
+// ReplaceAllLiteralString returns a copy of src, replacing matches of the Regexp
+// with the replacement string repl.  The replacement repl is substituted directly,
+// without using Expand.
+func (re *Regexp) ReplaceAllLiteralString(src, repl string) string {
+	return string(re.replaceAll(nil, src, 2, func(dst []byte, match []int) []byte {
+		return append(dst, repl...)
+	}))
+}
+
+// ReplaceAllStringFunc returns a copy of src in which all matches of the
+// Regexp have been replaced by the return value of function repl applied
+// to the matched substring.  The replacement returned by repl is substituted
+// directly, without using Expand.
+func (re *Regexp) ReplaceAllStringFunc(src string, repl func(string) string) string {
+	b := re.replaceAll(nil, src, 2, func(dst []byte, match []int) []byte {
+		return append(dst, repl(src[match[0]:match[1]])...)
+	})
+	return string(b)
+}
+
+func (re *Regexp) replaceAll(bsrc []byte, src string, nmatch int, repl func(dst []byte, m []int) []byte) []byte {
+	lastMatchEnd := 0 // end position of the most recent match
+	searchPos := 0    // position where we next look for a match
+	var buf []byte
+	var endPos int
+	if bsrc != nil {
+		endPos = len(bsrc)
+	} else {
+		endPos = len(src)
+	}
+	for searchPos <= endPos {
+		a := re.doExecute(nil, bsrc, src, searchPos, nmatch)
+		if len(a) == 0 {
+			break // no more matches
+		}
+
+		// Copy the unmatched characters before this match.
+		if bsrc != nil {
+			buf = append(buf, bsrc[lastMatchEnd:a[0]]...)
+		} else {
+			buf = append(buf, src[lastMatchEnd:a[0]]...)
+		}
+
+		// Now insert a copy of the replacement string, but not for a
+		// match of the empty string immediately after another match.
+		// (Otherwise, we get double replacement for patterns that
+		// match both empty and nonempty strings.)
+		if a[1] > lastMatchEnd || a[0] == 0 {
+			buf = repl(buf, a)
+		}
+		lastMatchEnd = a[1]
+
+		// Advance past this match; always advance at least one character.
+		var width int
+		if bsrc != nil {
+			_, width = utf8.DecodeRune(bsrc[searchPos:])
+		} else {
+			_, width = utf8.DecodeRuneInString(src[searchPos:])
+		}
+		if searchPos+width > a[1] {
+			searchPos += width
+		} else if searchPos+1 > a[1] {
+			// This clause is only needed at the end of the input
+			// string.  In that case, DecodeRuneInString returns width=0.
+			searchPos++
+		} else {
+			searchPos = a[1]
+		}
+	}
+
+	// Copy the unmatched characters after the last match.
+	if bsrc != nil {
+		buf = append(buf, bsrc[lastMatchEnd:]...)
+	} else {
+		buf = append(buf, src[lastMatchEnd:]...)
+	}
+
+	return buf
+}
+
+// ReplaceAll returns a copy of src, replacing matches of the Regexp
+// with the replacement text repl.  Inside repl, $ signs are interpreted as
+// in Expand, so for instance $1 represents the text of the first submatch.
+func (re *Regexp) ReplaceAll(src, repl []byte) []byte {
+	n := 2
+	if bytes.IndexByte(repl, '$') >= 0 {
+		n = 2 * (re.numSubexp + 1)
+	}
+	srepl := ""
+	b := re.replaceAll(src, "", n, func(dst []byte, match []int) []byte {
+		if len(srepl) != len(repl) {
+			srepl = string(repl)
+		}
+		return re.expand(dst, srepl, src, "", match)
+	})
+	return b
+}
+
+// ReplaceAllLiteral returns a copy of src, replacing matches of the Regexp
+// with the replacement bytes repl.  The replacement repl is substituted directly,
+// without using Expand.
+func (re *Regexp) ReplaceAllLiteral(src, repl []byte) []byte {
+	return re.replaceAll(src, "", 2, func(dst []byte, match []int) []byte {
+		return append(dst, repl...)
+	})
+}
+
+// ReplaceAllFunc returns a copy of src in which all matches of the
+// Regexp have been replaced by the return value of function repl applied
+// to the matched byte slice.  The replacement returned by repl is substituted
+// directly, without using Expand.
+func (re *Regexp) ReplaceAllFunc(src []byte, repl func([]byte) []byte) []byte {
+	return re.replaceAll(src, "", 2, func(dst []byte, match []int) []byte {
+		return append(dst, repl(src[match[0]:match[1]])...)
+	})
+}
+
+var specialBytes = []byte(`\.+*?()|[]{}^$`)
+
+func special(b byte) bool {
+	return bytes.IndexByte(specialBytes, b) >= 0
+}
+
+// QuoteMeta returns a string that quotes all regular expression metacharacters
+// inside the argument text; the returned string is a regular expression matching
+// the literal text.  For example, QuoteMeta(`[foo]`) returns `\[foo\]`.
+func QuoteMeta(s string) string {
+	b := make([]byte, 2*len(s))
+
+	// A byte loop is correct because all metacharacters are ASCII.
+	j := 0
+	for i := 0; i < len(s); i++ {
+		if special(s[i]) {
+			b[j] = '\\'
+			j++
+		}
+		b[j] = s[i]
+		j++
+	}
+	return string(b[0:j])
+}
+
+// The number of capture values in the program may correspond
+// to fewer capturing expressions than are in the regexp.
+// For example, "(a){0}" turns into an empty program, so the
+// maximum capture in the program is 0 but we need to return
+// an expression for \1.  Pad appends -1s to the slice a as needed.
+func (re *Regexp) pad(a []int) []int {
+	if a == nil {
+		// No match.
+		return nil
+	}
+	n := (1 + re.numSubexp) * 2
+	for len(a) < n {
+		a = append(a, -1)
+	}
+	return a
+}
+
+// Find matches in slice b if b is non-nil, otherwise find matches in string s.
+func (re *Regexp) allMatches(s string, b []byte, n int, deliver func([]int)) {
+	var end int
+	if b == nil {
+		end = len(s)
+	} else {
+		end = len(b)
+	}
+
+	for pos, i, prevMatchEnd := 0, 0, -1; i < n && pos <= end; {
+		matches := re.doExecute(nil, b, s, pos, re.prog.NumCap)
+		if len(matches) == 0 {
+			break
+		}
+
+		accept := true
+		if matches[1] == pos {
+			// We've found an empty match.
+			if matches[0] == prevMatchEnd {
+				// We don't allow an empty match right
+				// after a previous match, so ignore it.
+				accept = false
+			}
+			var width int
+			// TODO: use step()
+			if b == nil {
+				_, width = utf8.DecodeRuneInString(s[pos:end])
+			} else {
+				_, width = utf8.DecodeRune(b[pos:end])
+			}
+			if width > 0 {
+				pos += width
+			} else {
+				pos = end + 1
+			}
+		} else {
+			pos = matches[1]
+		}
+		prevMatchEnd = matches[1]
+
+		if accept {
+			deliver(re.pad(matches))
+			i++
+		}
+	}
+}
+
+// Find returns a slice holding the text of the leftmost match in b of the regular expression.
+// A return value of nil indicates no match.
+func (re *Regexp) Find(b []byte) []byte {
+	a := re.doExecute(nil, b, "", 0, 2)
+	if a == nil {
+		return nil
+	}
+	return b[a[0]:a[1]]
+}
+
+// FindIndex returns a two-element slice of integers defining the location of
+// the leftmost match in b of the regular expression.  The match itself is at
+// b[loc[0]:loc[1]].
+// A return value of nil indicates no match.
+func (re *Regexp) FindIndex(b []byte) (loc []int) {
+	a := re.doExecute(nil, b, "", 0, 2)
+	if a == nil {
+		return nil
+	}
+	return a[0:2]
+}
+
+// FindString returns a string holding the text of the leftmost match in s of the regular
+// expression.  If there is no match, the return value is an empty string,
+// but it will also be empty if the regular expression successfully matches
+// an empty string.  Use FindStringIndex or FindStringSubmatch if it is
+// necessary to distinguish these cases.
+func (re *Regexp) FindString(s string) string {
+	a := re.doExecute(nil, nil, s, 0, 2)
+	if a == nil {
+		return ""
+	}
+	return s[a[0]:a[1]]
+}
+
+// FindStringIndex returns a two-element slice of integers defining the
+// location of the leftmost match in s of the regular expression.  The match
+// itself is at s[loc[0]:loc[1]].
+// A return value of nil indicates no match.
+func (re *Regexp) FindStringIndex(s string) (loc []int) {
+	a := re.doExecute(nil, nil, s, 0, 2)
+	if a == nil {
+		return nil
+	}
+	return a[0:2]
+}
+
+// FindReaderIndex returns a two-element slice of integers defining the
+// location of the leftmost match of the regular expression in text read from
+// the RuneReader.  The match text was found in the input stream at
+// byte offset loc[0] through loc[1]-1.
+// A return value of nil indicates no match.
+func (re *Regexp) FindReaderIndex(r io.RuneReader) (loc []int) {
+	a := re.doExecute(r, nil, "", 0, 2)
+	if a == nil {
+		return nil
+	}
+	return a[0:2]
+}
+
+// FindSubmatch returns a slice of slices holding the text of the leftmost
+// match of the regular expression in b and the matches, if any, of its
+// subexpressions, as defined by the 'Submatch' descriptions in the package
+// comment.
+// A return value of nil indicates no match.
+func (re *Regexp) FindSubmatch(b []byte) [][]byte {
+	a := re.doExecute(nil, b, "", 0, re.prog.NumCap)
+	if a == nil {
+		return nil
+	}
+	ret := make([][]byte, 1+re.numSubexp)
+	for i := range ret {
+		if 2*i < len(a) && a[2*i] >= 0 {
+			ret[i] = b[a[2*i]:a[2*i+1]]
+		}
+	}
+	return ret
+}
+
+// Expand appends template to dst and returns the result; during the
+// append, Expand replaces variables in the template with corresponding
+// matches drawn from src.  The match slice should have been returned by
+// FindSubmatchIndex.
+//
+// In the template, a variable is denoted by a substring of the form
+// $name or ${name}, where name is a non-empty sequence of letters,
+// digits, and underscores.  A purely numeric name like $1 refers to
+// the submatch with the corresponding index; other names refer to
+// capturing parentheses named with the (?P<name>...) syntax.  A
+// reference to an out of range or unmatched index or a name that is not
+// present in the regular expression is replaced with an empty slice.
+//
+// In the $name form, name is taken to be as long as possible: $1x is
+// equivalent to ${1x}, not ${1}x, and, $10 is equivalent to ${10}, not ${1}0.
+//
+// To insert a literal $ in the output, use $$ in the template.
+func (re *Regexp) Expand(dst []byte, template []byte, src []byte, match []int) []byte {
+	return re.expand(dst, string(template), src, "", match)
+}
+
+// ExpandString is like Expand but the template and source are strings.
+// It appends to and returns a byte slice in order to give the calling
+// code control over allocation.
+func (re *Regexp) ExpandString(dst []byte, template string, src string, match []int) []byte {
+	return re.expand(dst, template, nil, src, match)
+}
+
+func (re *Regexp) expand(dst []byte, template string, bsrc []byte, src string, match []int) []byte {
+	for len(template) > 0 {
+		i := strings.Index(template, "$")
+		if i < 0 {
+			break
+		}
+		dst = append(dst, template[:i]...)
+		template = template[i:]
+		if len(template) > 1 && template[1] == '$' {
+			// Treat $$ as $.
+			dst = append(dst, '$')
+			template = template[2:]
+			continue
+		}
+		name, num, rest, ok := extract(template)
+		if !ok {
+			// Malformed; treat $ as raw text.
+			dst = append(dst, '$')
+			template = template[1:]
+			continue
+		}
+		template = rest
+		if num >= 0 {
+			if 2*num+1 < len(match) && match[2*num] >= 0 {
+				if bsrc != nil {
+					dst = append(dst, bsrc[match[2*num]:match[2*num+1]]...)
+				} else {
+					dst = append(dst, src[match[2*num]:match[2*num+1]]...)
+				}
+			}
+		} else {
+			for i, namei := range re.subexpNames {
+				if name == namei && 2*i+1 < len(match) && match[2*i] >= 0 {
+					if bsrc != nil {
+						dst = append(dst, bsrc[match[2*i]:match[2*i+1]]...)
+					} else {
+						dst = append(dst, src[match[2*i]:match[2*i+1]]...)
+					}
+					break
+				}
+			}
+		}
+	}
+	dst = append(dst, template...)
+	return dst
+}
+
+// extract returns the name from a leading "$name" or "${name}" in str.
+// If it is a number, extract returns num set to that number; otherwise num = -1.
+func extract(str string) (name string, num int, rest string, ok bool) {
+	if len(str) < 2 || str[0] != '$' {
+		return
+	}
+	brace := false
+	if str[1] == '{' {
+		brace = true
+		str = str[2:]
+	} else {
+		str = str[1:]
+	}
+	i := 0
+	for i < len(str) {
+		rune, size := utf8.DecodeRuneInString(str[i:])
+		if !unicode.IsLetter(rune) && !unicode.IsDigit(rune) && rune != '_' {
+			break
+		}
+		i += size
+	}
+	if i == 0 {
+		// empty name is not okay
+		return
+	}
+	name = str[:i]
+	if brace {
+		if i >= len(str) || str[i] != '}' {
+			// missing closing brace
+			return
+		}
+		i++
+	}
+
+	// Parse number.
+	num = 0
+	for i := 0; i < len(name); i++ {
+		if name[i] < '0' || '9' < name[i] || num >= 1e8 {
+			num = -1
+			break
+		}
+		num = num*10 + int(name[i]) - '0'
+	}
+	// Disallow leading zeros.
+	if name[0] == '0' && len(name) > 1 {
+		num = -1
+	}
+
+	rest = str[i:]
+	ok = true
+	return
+}
+
+// FindSubmatchIndex returns a slice holding the index pairs identifying the
+// leftmost match of the regular expression in b and the matches, if any, of
+// its subexpressions, as defined by the 'Submatch' and 'Index' descriptions
+// in the package comment.
+// A return value of nil indicates no match.
+func (re *Regexp) FindSubmatchIndex(b []byte) []int {
+	return re.pad(re.doExecute(nil, b, "", 0, re.prog.NumCap))
+}
+
+// FindStringSubmatch returns a slice of strings holding the text of the
+// leftmost match of the regular expression in s and the matches, if any, of
+// its subexpressions, as defined by the 'Submatch' description in the
+// package comment.
+// A return value of nil indicates no match.
+func (re *Regexp) FindStringSubmatch(s string) []string {
+	a := re.doExecute(nil, nil, s, 0, re.prog.NumCap)
+	if a == nil {
+		return nil
+	}
+	ret := make([]string, 1+re.numSubexp)
+	for i := range ret {
+		if 2*i < len(a) && a[2*i] >= 0 {
+			ret[i] = s[a[2*i]:a[2*i+1]]
+		}
+	}
+	return ret
+}
+
+// FindStringSubmatchIndex returns a slice holding the index pairs
+// identifying the leftmost match of the regular expression in s and the
+// matches, if any, of its subexpressions, as defined by the 'Submatch' and
+// 'Index' descriptions in the package comment.
+// A return value of nil indicates no match.
+func (re *Regexp) FindStringSubmatchIndex(s string) []int {
+	return re.pad(re.doExecute(nil, nil, s, 0, re.prog.NumCap))
+}
+
+// FindReaderSubmatchIndex returns a slice holding the index pairs
+// identifying the leftmost match of the regular expression of text read by
+// the RuneReader, and the matches, if any, of its subexpressions, as defined
+// by the 'Submatch' and 'Index' descriptions in the package comment.  A
+// return value of nil indicates no match.
+func (re *Regexp) FindReaderSubmatchIndex(r io.RuneReader) []int {
+	return re.pad(re.doExecute(r, nil, "", 0, re.prog.NumCap))
+}
+
+const startSize = 10 // The size at which to start a slice in the 'All' routines.
+
+// FindAll is the 'All' version of Find; it returns a slice of all successive
+// matches of the expression, as defined by the 'All' description in the
+// package comment.
+// A return value of nil indicates no match.
+func (re *Regexp) FindAll(b []byte, n int) [][]byte {
+	if n < 0 {
+		n = len(b) + 1
+	}
+	result := make([][]byte, 0, startSize)
+	re.allMatches("", b, n, func(match []int) {
+		result = append(result, b[match[0]:match[1]])
+	})
+	if len(result) == 0 {
+		return nil
+	}
+	return result
+}
+
+// FindAllIndex is the 'All' version of FindIndex; it returns a slice of all
+// successive matches of the expression, as defined by the 'All' description
+// in the package comment.
+// A return value of nil indicates no match.
+func (re *Regexp) FindAllIndex(b []byte, n int) [][]int {
+	if n < 0 {
+		n = len(b) + 1
+	}
+	result := make([][]int, 0, startSize)
+	re.allMatches("", b, n, func(match []int) {
+		result = append(result, match[0:2])
+	})
+	if len(result) == 0 {
+		return nil
+	}
+	return result
+}
+
+// FindAllString is the 'All' version of FindString; it returns a slice of all
+// successive matches of the expression, as defined by the 'All' description
+// in the package comment.
+// A return value of nil indicates no match.
+func (re *Regexp) FindAllString(s string, n int) []string {
+	if n < 0 {
+		n = len(s) + 1
+	}
+	result := make([]string, 0, startSize)
+	re.allMatches(s, nil, n, func(match []int) {
+		result = append(result, s[match[0]:match[1]])
+	})
+	if len(result) == 0 {
+		return nil
+	}
+	return result
+}
+
+// FindAllStringIndex is the 'All' version of FindStringIndex; it returns a
+// slice of all successive matches of the expression, as defined by the 'All'
+// description in the package comment.
+// A return value of nil indicates no match.
+func (re *Regexp) FindAllStringIndex(s string, n int) [][]int {
+	if n < 0 {
+		n = len(s) + 1
+	}
+	result := make([][]int, 0, startSize)
+	re.allMatches(s, nil, n, func(match []int) {
+		result = append(result, match[0:2])
+	})
+	if len(result) == 0 {
+		return nil
+	}
+	return result
+}
+
+// FindAllSubmatch is the 'All' version of FindSubmatch; it returns a slice
+// of all successive matches of the expression, as defined by the 'All'
+// description in the package comment.
+// A return value of nil indicates no match.
+func (re *Regexp) FindAllSubmatch(b []byte, n int) [][][]byte {
+	if n < 0 {
+		n = len(b) + 1
+	}
+	result := make([][][]byte, 0, startSize)
+	re.allMatches("", b, n, func(match []int) {
+		slice := make([][]byte, len(match)/2)
+		for j := range slice {
+			if match[2*j] >= 0 {
+				slice[j] = b[match[2*j]:match[2*j+1]]
+			}
+		}
+		result = append(result, slice)
+	})
+	if len(result) == 0 {
+		return nil
+	}
+	return result
+}
+
+// FindAllSubmatchIndex is the 'All' version of FindSubmatchIndex; it returns
+// a slice of all successive matches of the expression, as defined by the
+// 'All' description in the package comment.
+// A return value of nil indicates no match.
+func (re *Regexp) FindAllSubmatchIndex(b []byte, n int) [][]int {
+	if n < 0 {
+		n = len(b) + 1
+	}
+	result := make([][]int, 0, startSize)
+	re.allMatches("", b, n, func(match []int) {
+		result = append(result, match)
+	})
+	if len(result) == 0 {
+		return nil
+	}
+	return result
+}
+
+// FindAllStringSubmatch is the 'All' version of FindStringSubmatch; it
+// returns a slice of all successive matches of the expression, as defined by
+// the 'All' description in the package comment.
+// A return value of nil indicates no match.
+func (re *Regexp) FindAllStringSubmatch(s string, n int) [][]string {
+	if n < 0 {
+		n = len(s) + 1
+	}
+	result := make([][]string, 0, startSize)
+	re.allMatches(s, nil, n, func(match []int) {
+		slice := make([]string, len(match)/2)
+		for j := range slice {
+			if match[2*j] >= 0 {
+				slice[j] = s[match[2*j]:match[2*j+1]]
+			}
+		}
+		result = append(result, slice)
+	})
+	if len(result) == 0 {
+		return nil
+	}
+	return result
+}
+
+// FindAllStringSubmatchIndex is the 'All' version of
+// FindStringSubmatchIndex; it returns a slice of all successive matches of
+// the expression, as defined by the 'All' description in the package
+// comment.
+// A return value of nil indicates no match.
+func (re *Regexp) FindAllStringSubmatchIndex(s string, n int) [][]int {
+	if n < 0 {
+		n = len(s) + 1
+	}
+	result := make([][]int, 0, startSize)
+	re.allMatches(s, nil, n, func(match []int) {
+		result = append(result, match)
+	})
+	if len(result) == 0 {
+		return nil
+	}
+	return result
+}
+
+// Split slices s into substrings separated by the expression and returns a slice of
+// the substrings between those expression matches.
+//
+// The slice returned by this method consists of all the substrings of s
+// not contained in the slice returned by FindAllString. When called on an expression
+// that contains no metacharacters, it is equivalent to strings.SplitN.
+//
+// Example:
+//   s := regexp.MustCompile("a*").Split("abaabaccadaaae", 5)
+//   // s: ["", "b", "b", "c", "cadaaae"]
+//
+// The count determines the number of substrings to return:
+//   n > 0: at most n substrings; the last substring will be the unsplit remainder.
+//   n == 0: the result is nil (zero substrings)
+//   n < 0: all substrings
+func (re *Regexp) Split(s string, n int) []string {
+
+	if n == 0 {
+		return nil
+	}
+
+	if len(re.expr) > 0 && len(s) == 0 {
+		return []string{""}
+	}
+
+	matches := re.FindAllStringIndex(s, n)
+	strings := make([]string, 0, len(matches))
+
+	beg := 0
+	end := 0
+	for _, match := range matches {
+		if n > 0 && len(strings) >= n-1 {
+			break
+		}
+
+		end = match[0]
+		if match[1] != 0 {
+			strings = append(strings, s[beg:end])
+		}
+		beg = match[1]
+	}
+
+	if end != len(s) {
+		strings = append(strings, s[beg:])
+	}
+
+	return strings
+}
diff --git a/src/pkg/regexp/syntax/compile.go b/src/regexp/syntax/compile.go
similarity index 100%
rename from src/pkg/regexp/syntax/compile.go
rename to src/regexp/syntax/compile.go
diff --git a/src/regexp/syntax/doc.go b/src/regexp/syntax/doc.go
new file mode 100644
index 0000000..e5e71f1
--- /dev/null
+++ b/src/regexp/syntax/doc.go
@@ -0,0 +1,131 @@
+// Copyright 2012 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// DO NOT EDIT. This file is generated by mksyntaxgo from the RE2 distribution.
+
+/*
+Package syntax parses regular expressions into parse trees and compiles
+parse trees into programs. Most clients of regular expressions will use the
+facilities of package regexp (such as Compile and Match) instead of this package.
+
+Syntax
+
+The regular expression syntax understood by this package when parsing with the Perl flag is as follows.
+Parts of the syntax can be disabled by passing alternate flags to Parse.
+
+
+Single characters:
+  .              any character, possibly including newline (flag s=true)
+  [xyz]          character class
+  [^xyz]         negated character class
+  \d             Perl character class
+  \D             negated Perl character class
+  [[:alpha:]]    ASCII character class
+  [[:^alpha:]]   negated ASCII character class
+  \pN            Unicode character class (one-letter name)
+  \p{Greek}      Unicode character class
+  \PN            negated Unicode character class (one-letter name)
+  \P{Greek}      negated Unicode character class
+
+Composites:
+  xy             x followed by y
+  x|y            x or y (prefer x)
+
+Repetitions:
+  x*             zero or more x, prefer more
+  x+             one or more x, prefer more
+  x?             zero or one x, prefer one
+  x{n,m}         n or n+1 or ... or m x, prefer more
+  x{n,}          n or more x, prefer more
+  x{n}           exactly n x
+  x*?            zero or more x, prefer fewer
+  x+?            one or more x, prefer fewer
+  x??            zero or one x, prefer zero
+  x{n,m}?        n or n+1 or ... or m x, prefer fewer
+  x{n,}?         n or more x, prefer fewer
+  x{n}?          exactly n x
+
+Implementation restriction: The counting forms x{n,m}, x{n,}, and x{n}
+reject forms that create a minimum or maximum repetition count above 1000.
+Unlimited repetitions are not subject to this restriction.
+
+Grouping:
+  (re)           numbered capturing group (submatch)
+  (?P<name>re)   named & numbered capturing group (submatch)
+  (?:re)         non-capturing group
+  (?flags)       set flags within current group; non-capturing
+  (?flags:re)    set flags during re; non-capturing
+
+  Flag syntax is xyz (set) or -xyz (clear) or xy-z (set xy, clear z). The flags are:
+
+  i              case-insensitive (default false)
+  m              multi-line mode: ^ and $ match begin/end line in addition to begin/end text (default false)
+  s              let . match \n (default false)
+  U              ungreedy: swap meaning of x* and x*?, x+ and x+?, etc (default false)
+
+Empty strings:
+  ^              at beginning of text or line (flag m=true)
+  $              at end of text (like \z not \Z) or line (flag m=true)
+  \A             at beginning of text
+  \b             at ASCII word boundary (\w on one side and \W, \A, or \z on the other)
+  \B             not at ASCII word boundary
+  \z             at end of text
+
+Escape sequences:
+  \a             bell (== \007)
+  \f             form feed (== \014)
+  \t             horizontal tab (== \011)
+  \n             newline (== \012)
+  \r             carriage return (== \015)
+  \v             vertical tab character (== \013)
+  \*             literal *, for any punctuation character *
+  \123           octal character code (up to three digits)
+  \x7F           hex character code (exactly two digits)
+  \x{10FFFF}     hex character code
+  \Q...\E        literal text ... even if ... has punctuation
+
+Character class elements:
+  x              single character
+  A-Z            character range (inclusive)
+  \d             Perl character class
+  [:foo:]        ASCII character class foo
+  \p{Foo}        Unicode character class Foo
+  \pF            Unicode character class F (one-letter name)
+
+Named character classes as character class elements:
+  [\d]           digits (== \d)
+  [^\d]          not digits (== \D)
+  [\D]           not digits (== \D)
+  [^\D]          not not digits (== \d)
+  [[:name:]]     named ASCII class inside character class (== [:name:])
+  [^[:name:]]    named ASCII class inside negated character class (== [:^name:])
+  [\p{Name}]     named Unicode property inside character class (== \p{Name})
+  [^\p{Name}]    named Unicode property inside negated character class (== \P{Name})
+
+Perl character classes (all ASCII-only):
+  \d             digits (== [0-9])
+  \D             not digits (== [^0-9])
+  \s             whitespace (== [\t\n\f\r ])
+  \S             not whitespace (== [^\t\n\f\r ])
+  \w             word characters (== [0-9A-Za-z_])
+  \W             not word characters (== [^0-9A-Za-z_])
+
+ASCII character classes:
+  [[:alnum:]]    alphanumeric (== [0-9A-Za-z])
+  [[:alpha:]]    alphabetic (== [A-Za-z])
+  [[:ascii:]]    ASCII (== [\x00-\x7F])
+  [[:blank:]]    blank (== [\t ])
+  [[:cntrl:]]    control (== [\x00-\x1F\x7F])
+  [[:digit:]]    digits (== [0-9])
+  [[:graph:]]    graphical (== [!-~] == [A-Za-z0-9!"#$%&'()*+,\-./:;<=>?@[\\\]^_`{|}~])
+  [[:lower:]]    lower case (== [a-z])
+  [[:print:]]    printable (== [ -~] == [ [:graph:]])
+  [[:punct:]]    punctuation (== [!-/:-@[-`{-~])
+  [[:space:]]    whitespace (== [\t\n\v\f\r ])
+  [[:upper:]]    upper case (== [A-Z])
+  [[:word:]]     word characters (== [0-9A-Za-z_])
+  [[:xdigit:]]   hex digit (== [0-9A-Fa-f])
+
+*/
+package syntax
diff --git a/src/pkg/regexp/syntax/make_perl_groups.pl b/src/regexp/syntax/make_perl_groups.pl
similarity index 100%
rename from src/pkg/regexp/syntax/make_perl_groups.pl
rename to src/regexp/syntax/make_perl_groups.pl
diff --git a/src/regexp/syntax/parse.go b/src/regexp/syntax/parse.go
new file mode 100644
index 0000000..d579a40
--- /dev/null
+++ b/src/regexp/syntax/parse.go
@@ -0,0 +1,1902 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package syntax
+
+import (
+	"sort"
+	"strings"
+	"unicode"
+	"unicode/utf8"
+)
+
+// An Error describes a failure to parse a regular expression
+// and gives the offending expression.
+type Error struct {
+	Code ErrorCode
+	Expr string
+}
+
+func (e *Error) Error() string {
+	return "error parsing regexp: " + e.Code.String() + ": `" + e.Expr + "`"
+}
+
+// An ErrorCode describes a failure to parse a regular expression.
+type ErrorCode string
+
+const (
+	// Unexpected error
+	ErrInternalError ErrorCode = "regexp/syntax: internal error"
+
+	// Parse errors
+	ErrInvalidCharClass      ErrorCode = "invalid character class"
+	ErrInvalidCharRange      ErrorCode = "invalid character class range"
+	ErrInvalidEscape         ErrorCode = "invalid escape sequence"
+	ErrInvalidNamedCapture   ErrorCode = "invalid named capture"
+	ErrInvalidPerlOp         ErrorCode = "invalid or unsupported Perl syntax"
+	ErrInvalidRepeatOp       ErrorCode = "invalid nested repetition operator"
+	ErrInvalidRepeatSize     ErrorCode = "invalid repeat count"
+	ErrInvalidUTF8           ErrorCode = "invalid UTF-8"
+	ErrMissingBracket        ErrorCode = "missing closing ]"
+	ErrMissingParen          ErrorCode = "missing closing )"
+	ErrMissingRepeatArgument ErrorCode = "missing argument to repetition operator"
+	ErrTrailingBackslash     ErrorCode = "trailing backslash at end of expression"
+	ErrUnexpectedParen       ErrorCode = "unexpected )"
+)
+
+func (e ErrorCode) String() string {
+	return string(e)
+}
+
+// Flags control the behavior of the parser and record information about regexp context.
+type Flags uint16
+
+const (
+	FoldCase      Flags = 1 << iota // case-insensitive match
+	Literal                         // treat pattern as literal string
+	ClassNL                         // allow character classes like [^a-z] and [[:space:]] to match newline
+	DotNL                           // allow . to match newline
+	OneLine                         // treat ^ and $ as only matching at beginning and end of text
+	NonGreedy                       // make repetition operators default to non-greedy
+	PerlX                           // allow Perl extensions
+	UnicodeGroups                   // allow \p{Han}, \P{Han} for Unicode group and negation
+	WasDollar                       // regexp OpEndText was $, not \z
+	Simple                          // regexp contains no counted repetition
+
+	MatchNL = ClassNL | DotNL
+
+	Perl        = ClassNL | OneLine | PerlX | UnicodeGroups // as close to Perl as possible
+	POSIX Flags = 0                                         // POSIX syntax
+)
+
+// Pseudo-ops for parsing stack.
+const (
+	opLeftParen = opPseudo + iota
+	opVerticalBar
+)
+
+type parser struct {
+	flags       Flags     // parse mode flags
+	stack       []*Regexp // stack of parsed expressions
+	free        *Regexp
+	numCap      int // number of capturing groups seen
+	wholeRegexp string
+	tmpClass    []rune // temporary char class work space
+}
+
+func (p *parser) newRegexp(op Op) *Regexp {
+	re := p.free
+	if re != nil {
+		p.free = re.Sub0[0]
+		*re = Regexp{}
+	} else {
+		re = new(Regexp)
+	}
+	re.Op = op
+	return re
+}
+
+func (p *parser) reuse(re *Regexp) {
+	re.Sub0[0] = p.free
+	p.free = re
+}
+
+// Parse stack manipulation.
+
+// push pushes the regexp re onto the parse stack and returns the regexp.
+func (p *parser) push(re *Regexp) *Regexp {
+	if re.Op == OpCharClass && len(re.Rune) == 2 && re.Rune[0] == re.Rune[1] {
+		// Single rune.
+		if p.maybeConcat(re.Rune[0], p.flags&^FoldCase) {
+			return nil
+		}
+		re.Op = OpLiteral
+		re.Rune = re.Rune[:1]
+		re.Flags = p.flags &^ FoldCase
+	} else if re.Op == OpCharClass && len(re.Rune) == 4 &&
+		re.Rune[0] == re.Rune[1] && re.Rune[2] == re.Rune[3] &&
+		unicode.SimpleFold(re.Rune[0]) == re.Rune[2] &&
+		unicode.SimpleFold(re.Rune[2]) == re.Rune[0] ||
+		re.Op == OpCharClass && len(re.Rune) == 2 &&
+			re.Rune[0]+1 == re.Rune[1] &&
+			unicode.SimpleFold(re.Rune[0]) == re.Rune[1] &&
+			unicode.SimpleFold(re.Rune[1]) == re.Rune[0] {
+		// Case-insensitive rune like [Aa] or [Δδ].
+		if p.maybeConcat(re.Rune[0], p.flags|FoldCase) {
+			return nil
+		}
+
+		// Rewrite as (case-insensitive) literal.
+		re.Op = OpLiteral
+		re.Rune = re.Rune[:1]
+		re.Flags = p.flags | FoldCase
+	} else {
+		// Incremental concatenation.
+		p.maybeConcat(-1, 0)
+	}
+
+	p.stack = append(p.stack, re)
+	return re
+}
+
+// maybeConcat implements incremental concatenation
+// of literal runes into string nodes.  The parser calls this
+// before each push, so only the top fragment of the stack
+// might need processing.  Since this is called before a push,
+// the topmost literal is no longer subject to operators like *
+// (Otherwise ab* would turn into (ab)*.)
+// If r >= 0 and there's a node left over, maybeConcat uses it
+// to push r with the given flags.
+// maybeConcat reports whether r was pushed.
+func (p *parser) maybeConcat(r rune, flags Flags) bool {
+	n := len(p.stack)
+	if n < 2 {
+		return false
+	}
+
+	re1 := p.stack[n-1]
+	re2 := p.stack[n-2]
+	if re1.Op != OpLiteral || re2.Op != OpLiteral || re1.Flags&FoldCase != re2.Flags&FoldCase {
+		return false
+	}
+
+	// Push re1 into re2.
+	re2.Rune = append(re2.Rune, re1.Rune...)
+
+	// Reuse re1 if possible.
+	if r >= 0 {
+		re1.Rune = re1.Rune0[:1]
+		re1.Rune[0] = r
+		re1.Flags = flags
+		return true
+	}
+
+	p.stack = p.stack[:n-1]
+	p.reuse(re1)
+	return false // did not push r
+}
+
+// newLiteral returns a new OpLiteral Regexp with the given flags
+func (p *parser) newLiteral(r rune, flags Flags) *Regexp {
+	re := p.newRegexp(OpLiteral)
+	re.Flags = flags
+	if flags&FoldCase != 0 {
+		r = minFoldRune(r)
+	}
+	re.Rune0[0] = r
+	re.Rune = re.Rune0[:1]
+	return re
+}
+
+// minFoldRune returns the minimum rune fold-equivalent to r.
+func minFoldRune(r rune) rune {
+	if r < minFold || r > maxFold {
+		return r
+	}
+	min := r
+	r0 := r
+	for r = unicode.SimpleFold(r); r != r0; r = unicode.SimpleFold(r) {
+		if min > r {
+			min = r
+		}
+	}
+	return min
+}
+
+// literal pushes a literal regexp for the rune r on the stack
+// and returns that regexp.
+func (p *parser) literal(r rune) {
+	p.push(p.newLiteral(r, p.flags))
+}
+
+// op pushes a regexp with the given op onto the stack
+// and returns that regexp.
+func (p *parser) op(op Op) *Regexp {
+	re := p.newRegexp(op)
+	re.Flags = p.flags
+	return p.push(re)
+}
+
+// repeat replaces the top stack element with itself repeated according to op, min, max.
+// before is the regexp suffix starting at the repetition operator.
+// after is the regexp suffix following after the repetition operator.
+// repeat returns an updated 'after' and an error, if any.
+func (p *parser) repeat(op Op, min, max int, before, after, lastRepeat string) (string, error) {
+	flags := p.flags
+	if p.flags&PerlX != 0 {
+		if len(after) > 0 && after[0] == '?' {
+			after = after[1:]
+			flags ^= NonGreedy
+		}
+		if lastRepeat != "" {
+			// In Perl it is not allowed to stack repetition operators:
+			// a** is a syntax error, not a doubled star, and a++ means
+			// something else entirely, which we don't support!
+			return "", &Error{ErrInvalidRepeatOp, lastRepeat[:len(lastRepeat)-len(after)]}
+		}
+	}
+	n := len(p.stack)
+	if n == 0 {
+		return "", &Error{ErrMissingRepeatArgument, before[:len(before)-len(after)]}
+	}
+	sub := p.stack[n-1]
+	if sub.Op >= opPseudo {
+		return "", &Error{ErrMissingRepeatArgument, before[:len(before)-len(after)]}
+	}
+
+	re := p.newRegexp(op)
+	re.Min = min
+	re.Max = max
+	re.Flags = flags
+	re.Sub = re.Sub0[:1]
+	re.Sub[0] = sub
+	p.stack[n-1] = re
+
+	if op == OpRepeat && (min >= 2 || max >= 2) && !repeatIsValid(re, 1000) {
+		return "", &Error{ErrInvalidRepeatSize, before[:len(before)-len(after)]}
+	}
+
+	return after, nil
+}
+
+// repeatIsValid reports whether the repetition re is valid.
+// Valid means that the combination of the top-level repetition
+// and any inner repetitions does not exceed n copies of the
+// innermost thing.
+// This function rewalks the regexp tree and is called for every repetition,
+// so we have to worry about inducing quadratic behavior in the parser.
+// We avoid this by only calling repeatIsValid when min or max >= 2.
+// In that case the depth of any >= 2 nesting can only get to 9 without
+// triggering a parse error, so each subtree can only be rewalked 9 times.
+func repeatIsValid(re *Regexp, n int) bool {
+	if re.Op == OpRepeat {
+		m := re.Max
+		if m == 0 {
+			return true
+		}
+		if m < 0 {
+			m = re.Min
+		}
+		if m > n {
+			return false
+		}
+		if m > 0 {
+			n /= m
+		}
+	}
+	for _, sub := range re.Sub {
+		if !repeatIsValid(sub, n) {
+			return false
+		}
+	}
+	return true
+}
+
+// concat replaces the top of the stack (above the topmost '|' or '(') with its concatenation.
+func (p *parser) concat() *Regexp {
+	p.maybeConcat(-1, 0)
+
+	// Scan down to find pseudo-operator | or (.
+	i := len(p.stack)
+	for i > 0 && p.stack[i-1].Op < opPseudo {
+		i--
+	}
+	subs := p.stack[i:]
+	p.stack = p.stack[:i]
+
+	// Empty concatenation is special case.
+	if len(subs) == 0 {
+		return p.push(p.newRegexp(OpEmptyMatch))
+	}
+
+	return p.push(p.collapse(subs, OpConcat))
+}
+
+// alternate replaces the top of the stack (above the topmost '(') with its alternation.
+func (p *parser) alternate() *Regexp {
+	// Scan down to find pseudo-operator (.
+	// There are no | above (.
+	i := len(p.stack)
+	for i > 0 && p.stack[i-1].Op < opPseudo {
+		i--
+	}
+	subs := p.stack[i:]
+	p.stack = p.stack[:i]
+
+	// Make sure top class is clean.
+	// All the others already are (see swapVerticalBar).
+	if len(subs) > 0 {
+		cleanAlt(subs[len(subs)-1])
+	}
+
+	// Empty alternate is special case
+	// (shouldn't happen but easy to handle).
+	if len(subs) == 0 {
+		return p.push(p.newRegexp(OpNoMatch))
+	}
+
+	return p.push(p.collapse(subs, OpAlternate))
+}
+
+// cleanAlt cleans re for eventual inclusion in an alternation.
+func cleanAlt(re *Regexp) {
+	switch re.Op {
+	case OpCharClass:
+		re.Rune = cleanClass(&re.Rune)
+		if len(re.Rune) == 2 && re.Rune[0] == 0 && re.Rune[1] == unicode.MaxRune {
+			re.Rune = nil
+			re.Op = OpAnyChar
+			return
+		}
+		if len(re.Rune) == 4 && re.Rune[0] == 0 && re.Rune[1] == '\n'-1 && re.Rune[2] == '\n'+1 && re.Rune[3] == unicode.MaxRune {
+			re.Rune = nil
+			re.Op = OpAnyCharNotNL
+			return
+		}
+		if cap(re.Rune)-len(re.Rune) > 100 {
+			// re.Rune will not grow any more.
+			// Make a copy or inline to reclaim storage.
+			re.Rune = append(re.Rune0[:0], re.Rune...)
+		}
+	}
+}
+
+// collapse returns the result of applying op to sub.
+// If sub contains op nodes, they all get hoisted up
+// so that there is never a concat of a concat or an
+// alternate of an alternate.
+func (p *parser) collapse(subs []*Regexp, op Op) *Regexp {
+	if len(subs) == 1 {
+		return subs[0]
+	}
+	re := p.newRegexp(op)
+	re.Sub = re.Sub0[:0]
+	for _, sub := range subs {
+		if sub.Op == op {
+			re.Sub = append(re.Sub, sub.Sub...)
+			p.reuse(sub)
+		} else {
+			re.Sub = append(re.Sub, sub)
+		}
+	}
+	if op == OpAlternate {
+		re.Sub = p.factor(re.Sub, re.Flags)
+		if len(re.Sub) == 1 {
+			old := re
+			re = re.Sub[0]
+			p.reuse(old)
+		}
+	}
+	return re
+}
+
+// factor factors common prefixes from the alternation list sub.
+// It returns a replacement list that reuses the same storage and
+// frees (passes to p.reuse) any removed *Regexps.
+//
+// For example,
+//     ABC|ABD|AEF|BCX|BCY
+// simplifies by literal prefix extraction to
+//     A(B(C|D)|EF)|BC(X|Y)
+// which simplifies by character class introduction to
+//     A(B[CD]|EF)|BC[XY]
+//
+func (p *parser) factor(sub []*Regexp, flags Flags) []*Regexp {
+	if len(sub) < 2 {
+		return sub
+	}
+
+	// Round 1: Factor out common literal prefixes.
+	var str []rune
+	var strflags Flags
+	start := 0
+	out := sub[:0]
+	for i := 0; i <= len(sub); i++ {
+		// Invariant: the Regexps that were in sub[0:start] have been
+		// used or marked for reuse, and the slice space has been reused
+		// for out (len(out) <= start).
+		//
+		// Invariant: sub[start:i] consists of regexps that all begin
+		// with str as modified by strflags.
+		var istr []rune
+		var iflags Flags
+		if i < len(sub) {
+			istr, iflags = p.leadingString(sub[i])
+			if iflags == strflags {
+				same := 0
+				for same < len(str) && same < len(istr) && str[same] == istr[same] {
+					same++
+				}
+				if same > 0 {
+					// Matches at least one rune in current range.
+					// Keep going around.
+					str = str[:same]
+					continue
+				}
+			}
+		}
+
+		// Found end of a run with common leading literal string:
+		// sub[start:i] all begin with str[0:len(str)], but sub[i]
+		// does not even begin with str[0].
+		//
+		// Factor out common string and append factored expression to out.
+		if i == start {
+			// Nothing to do - run of length 0.
+		} else if i == start+1 {
+			// Just one: don't bother factoring.
+			out = append(out, sub[start])
+		} else {
+			// Construct factored form: prefix(suffix1|suffix2|...)
+			prefix := p.newRegexp(OpLiteral)
+			prefix.Flags = strflags
+			prefix.Rune = append(prefix.Rune[:0], str...)
+
+			for j := start; j < i; j++ {
+				sub[j] = p.removeLeadingString(sub[j], len(str))
+			}
+			suffix := p.collapse(sub[start:i], OpAlternate) // recurse
+
+			re := p.newRegexp(OpConcat)
+			re.Sub = append(re.Sub[:0], prefix, suffix)
+			out = append(out, re)
+		}
+
+		// Prepare for next iteration.
+		start = i
+		str = istr
+		strflags = iflags
+	}
+	sub = out
+
+	// Round 2: Factor out common complex prefixes,
+	// just the first piece of each concatenation,
+	// whatever it is.  This is good enough a lot of the time.
+	start = 0
+	out = sub[:0]
+	var first *Regexp
+	for i := 0; i <= len(sub); i++ {
+		// Invariant: the Regexps that were in sub[0:start] have been
+		// used or marked for reuse, and the slice space has been reused
+		// for out (len(out) <= start).
+		//
+		// Invariant: sub[start:i] consists of regexps that all begin with ifirst.
+		var ifirst *Regexp
+		if i < len(sub) {
+			ifirst = p.leadingRegexp(sub[i])
+			if first != nil && first.Equal(ifirst) {
+				continue
+			}
+		}
+
+		// Found end of a run with common leading regexp:
+		// sub[start:i] all begin with first but sub[i] does not.
+		//
+		// Factor out common regexp and append factored expression to out.
+		if i == start {
+			// Nothing to do - run of length 0.
+		} else if i == start+1 {
+			// Just one: don't bother factoring.
+			out = append(out, sub[start])
+		} else {
+			// Construct factored form: prefix(suffix1|suffix2|...)
+			prefix := first
+			for j := start; j < i; j++ {
+				reuse := j != start // prefix came from sub[start]
+				sub[j] = p.removeLeadingRegexp(sub[j], reuse)
+			}
+			suffix := p.collapse(sub[start:i], OpAlternate) // recurse
+
+			re := p.newRegexp(OpConcat)
+			re.Sub = append(re.Sub[:0], prefix, suffix)
+			out = append(out, re)
+		}
+
+		// Prepare for next iteration.
+		start = i
+		first = ifirst
+	}
+	sub = out
+
+	// Round 3: Collapse runs of single literals into character classes.
+	start = 0
+	out = sub[:0]
+	for i := 0; i <= len(sub); i++ {
+		// Invariant: the Regexps that were in sub[0:start] have been
+		// used or marked for reuse, and the slice space has been reused
+		// for out (len(out) <= start).
+		//
+		// Invariant: sub[start:i] consists of regexps that are either
+		// literal runes or character classes.
+		if i < len(sub) && isCharClass(sub[i]) {
+			continue
+		}
+
+		// sub[i] is not a char or char class;
+		// emit char class for sub[start:i]...
+		if i == start {
+			// Nothing to do - run of length 0.
+		} else if i == start+1 {
+			out = append(out, sub[start])
+		} else {
+			// Make new char class.
+			// Start with most complex regexp in sub[start].
+			max := start
+			for j := start + 1; j < i; j++ {
+				if sub[max].Op < sub[j].Op || sub[max].Op == sub[j].Op && len(sub[max].Rune) < len(sub[j].Rune) {
+					max = j
+				}
+			}
+			sub[start], sub[max] = sub[max], sub[start]
+
+			for j := start + 1; j < i; j++ {
+				mergeCharClass(sub[start], sub[j])
+				p.reuse(sub[j])
+			}
+			cleanAlt(sub[start])
+			out = append(out, sub[start])
+		}
+
+		// ... and then emit sub[i].
+		if i < len(sub) {
+			out = append(out, sub[i])
+		}
+		start = i + 1
+	}
+	sub = out
+
+	// Round 4: Collapse runs of empty matches into a single empty match.
+	start = 0
+	out = sub[:0]
+	for i := range sub {
+		if i+1 < len(sub) && sub[i].Op == OpEmptyMatch && sub[i+1].Op == OpEmptyMatch {
+			continue
+		}
+		out = append(out, sub[i])
+	}
+	sub = out
+
+	return sub
+}
+
+// leadingString returns the leading literal string that re begins with.
+// The string refers to storage in re or its children.
+func (p *parser) leadingString(re *Regexp) ([]rune, Flags) {
+	if re.Op == OpConcat && len(re.Sub) > 0 {
+		re = re.Sub[0]
+	}
+	if re.Op != OpLiteral {
+		return nil, 0
+	}
+	return re.Rune, re.Flags & FoldCase
+}
+
+// removeLeadingString removes the first n leading runes
+// from the beginning of re.  It returns the replacement for re.
+func (p *parser) removeLeadingString(re *Regexp, n int) *Regexp {
+	if re.Op == OpConcat && len(re.Sub) > 0 {
+		// Removing a leading string in a concatenation
+		// might simplify the concatenation.
+		sub := re.Sub[0]
+		sub = p.removeLeadingString(sub, n)
+		re.Sub[0] = sub
+		if sub.Op == OpEmptyMatch {
+			p.reuse(sub)
+			switch len(re.Sub) {
+			case 0, 1:
+				// Impossible but handle.
+				re.Op = OpEmptyMatch
+				re.Sub = nil
+			case 2:
+				old := re
+				re = re.Sub[1]
+				p.reuse(old)
+			default:
+				copy(re.Sub, re.Sub[1:])
+				re.Sub = re.Sub[:len(re.Sub)-1]
+			}
+		}
+		return re
+	}
+
+	if re.Op == OpLiteral {
+		re.Rune = re.Rune[:copy(re.Rune, re.Rune[n:])]
+		if len(re.Rune) == 0 {
+			re.Op = OpEmptyMatch
+		}
+	}
+	return re
+}
+
+// leadingRegexp returns the leading regexp that re begins with.
+// The regexp refers to storage in re or its children.
+func (p *parser) leadingRegexp(re *Regexp) *Regexp {
+	if re.Op == OpEmptyMatch {
+		return nil
+	}
+	if re.Op == OpConcat && len(re.Sub) > 0 {
+		sub := re.Sub[0]
+		if sub.Op == OpEmptyMatch {
+			return nil
+		}
+		return sub
+	}
+	return re
+}
+
+// removeLeadingRegexp removes the leading regexp in re.
+// It returns the replacement for re.
+// If reuse is true, it passes the removed regexp (if no longer needed) to p.reuse.
+func (p *parser) removeLeadingRegexp(re *Regexp, reuse bool) *Regexp {
+	if re.Op == OpConcat && len(re.Sub) > 0 {
+		if reuse {
+			p.reuse(re.Sub[0])
+		}
+		re.Sub = re.Sub[:copy(re.Sub, re.Sub[1:])]
+		switch len(re.Sub) {
+		case 0:
+			re.Op = OpEmptyMatch
+			re.Sub = nil
+		case 1:
+			old := re
+			re = re.Sub[0]
+			p.reuse(old)
+		}
+		return re
+	}
+	if reuse {
+		p.reuse(re)
+	}
+	return p.newRegexp(OpEmptyMatch)
+}
+
+func literalRegexp(s string, flags Flags) *Regexp {
+	re := &Regexp{Op: OpLiteral}
+	re.Flags = flags
+	re.Rune = re.Rune0[:0] // use local storage for small strings
+	for _, c := range s {
+		if len(re.Rune) >= cap(re.Rune) {
+			// string is too long to fit in Rune0.  let Go handle it
+			re.Rune = []rune(s)
+			break
+		}
+		re.Rune = append(re.Rune, c)
+	}
+	return re
+}
+
+// Parsing.
+
+// Parse parses a regular expression string s, controlled by the specified
+// Flags, and returns a regular expression parse tree. The syntax is
+// described in the top-level comment.
+func Parse(s string, flags Flags) (*Regexp, error) {
+	if flags&Literal != 0 {
+		// Trivial parser for literal string.
+		if err := checkUTF8(s); err != nil {
+			return nil, err
+		}
+		return literalRegexp(s, flags), nil
+	}
+
+	// Otherwise, must do real work.
+	var (
+		p          parser
+		err        error
+		c          rune
+		op         Op
+		lastRepeat string
+	)
+	p.flags = flags
+	p.wholeRegexp = s
+	t := s
+	for t != "" {
+		repeat := ""
+	BigSwitch:
+		switch t[0] {
+		default:
+			if c, t, err = nextRune(t); err != nil {
+				return nil, err
+			}
+			p.literal(c)
+
+		case '(':
+			if p.flags&PerlX != 0 && len(t) >= 2 && t[1] == '?' {
+				// Flag changes and non-capturing groups.
+				if t, err = p.parsePerlFlags(t); err != nil {
+					return nil, err
+				}
+				break
+			}
+			p.numCap++
+			p.op(opLeftParen).Cap = p.numCap
+			t = t[1:]
+		case '|':
+			if err = p.parseVerticalBar(); err != nil {
+				return nil, err
+			}
+			t = t[1:]
+		case ')':
+			if err = p.parseRightParen(); err != nil {
+				return nil, err
+			}
+			t = t[1:]
+		case '^':
+			if p.flags&OneLine != 0 {
+				p.op(OpBeginText)
+			} else {
+				p.op(OpBeginLine)
+			}
+			t = t[1:]
+		case '$':
+			if p.flags&OneLine != 0 {
+				p.op(OpEndText).Flags |= WasDollar
+			} else {
+				p.op(OpEndLine)
+			}
+			t = t[1:]
+		case '.':
+			if p.flags&DotNL != 0 {
+				p.op(OpAnyChar)
+			} else {
+				p.op(OpAnyCharNotNL)
+			}
+			t = t[1:]
+		case '[':
+			if t, err = p.parseClass(t); err != nil {
+				return nil, err
+			}
+		case '*', '+', '?':
+			before := t
+			switch t[0] {
+			case '*':
+				op = OpStar
+			case '+':
+				op = OpPlus
+			case '?':
+				op = OpQuest
+			}
+			after := t[1:]
+			if after, err = p.repeat(op, 0, 0, before, after, lastRepeat); err != nil {
+				return nil, err
+			}
+			repeat = before
+			t = after
+		case '{':
+			op = OpRepeat
+			before := t
+			min, max, after, ok := p.parseRepeat(t)
+			if !ok {
+				// If the repeat cannot be parsed, { is a literal.
+				p.literal('{')
+				t = t[1:]
+				break
+			}
+			if min < 0 || min > 1000 || max > 1000 || max >= 0 && min > max {
+				// Numbers were too big, or max is present and min > max.
+				return nil, &Error{ErrInvalidRepeatSize, before[:len(before)-len(after)]}
+			}
+			if after, err = p.repeat(op, min, max, before, after, lastRepeat); err != nil {
+				return nil, err
+			}
+			repeat = before
+			t = after
+		case '\\':
+			if p.flags&PerlX != 0 && len(t) >= 2 {
+				switch t[1] {
+				case 'A':
+					p.op(OpBeginText)
+					t = t[2:]
+					break BigSwitch
+				case 'b':
+					p.op(OpWordBoundary)
+					t = t[2:]
+					break BigSwitch
+				case 'B':
+					p.op(OpNoWordBoundary)
+					t = t[2:]
+					break BigSwitch
+				case 'C':
+					// any byte; not supported
+					return nil, &Error{ErrInvalidEscape, t[:2]}
+				case 'Q':
+					// \Q ... \E: the ... is always literals
+					var lit string
+					if i := strings.Index(t, `\E`); i < 0 {
+						lit = t[2:]
+						t = ""
+					} else {
+						lit = t[2:i]
+						t = t[i+2:]
+					}
+					p.push(literalRegexp(lit, p.flags))
+					break BigSwitch
+				case 'z':
+					p.op(OpEndText)
+					t = t[2:]
+					break BigSwitch
+				}
+			}
+
+			re := p.newRegexp(OpCharClass)
+			re.Flags = p.flags
+
+			// Look for Unicode character group like \p{Han}
+			if len(t) >= 2 && (t[1] == 'p' || t[1] == 'P') {
+				r, rest, err := p.parseUnicodeClass(t, re.Rune0[:0])
+				if err != nil {
+					return nil, err
+				}
+				if r != nil {
+					re.Rune = r
+					t = rest
+					p.push(re)
+					break BigSwitch
+				}
+			}
+
+			// Perl character class escape.
+			if r, rest := p.parsePerlClassEscape(t, re.Rune0[:0]); r != nil {
+				re.Rune = r
+				t = rest
+				p.push(re)
+				break BigSwitch
+			}
+			p.reuse(re)
+
+			// Ordinary single-character escape.
+			if c, t, err = p.parseEscape(t); err != nil {
+				return nil, err
+			}
+			p.literal(c)
+		}
+		lastRepeat = repeat
+	}
+
+	p.concat()
+	if p.swapVerticalBar() {
+		// pop vertical bar
+		p.stack = p.stack[:len(p.stack)-1]
+	}
+	p.alternate()
+
+	n := len(p.stack)
+	if n != 1 {
+		return nil, &Error{ErrMissingParen, s}
+	}
+	return p.stack[0], nil
+}
+
+// parseRepeat parses {min} (max=min) or {min,} (max=-1) or {min,max}.
+// If s is not of that form, it returns ok == false.
+// If s has the right form but the values are too big, it returns min == -1, ok == true.
+func (p *parser) parseRepeat(s string) (min, max int, rest string, ok bool) {
+	if s == "" || s[0] != '{' {
+		return
+	}
+	s = s[1:]
+	var ok1 bool
+	if min, s, ok1 = p.parseInt(s); !ok1 {
+		return
+	}
+	if s == "" {
+		return
+	}
+	if s[0] != ',' {
+		max = min
+	} else {
+		s = s[1:]
+		if s == "" {
+			return
+		}
+		if s[0] == '}' {
+			max = -1
+		} else if max, s, ok1 = p.parseInt(s); !ok1 {
+			return
+		} else if max < 0 {
+			// parseInt found too big a number
+			min = -1
+		}
+	}
+	if s == "" || s[0] != '}' {
+		return
+	}
+	rest = s[1:]
+	ok = true
+	return
+}
+
+// parsePerlFlags parses a Perl flag setting or non-capturing group or both,
+// like (?i) or (?: or (?i:.  It removes the prefix from s and updates the parse state.
+// The caller must have ensured that s begins with "(?".
+func (p *parser) parsePerlFlags(s string) (rest string, err error) {
+	t := s
+
+	// Check for named captures, first introduced in Python's regexp library.
+	// As usual, there are three slightly different syntaxes:
+	//
+	//   (?P<name>expr)   the original, introduced by Python
+	//   (?<name>expr)    the .NET alteration, adopted by Perl 5.10
+	//   (?'name'expr)    another .NET alteration, adopted by Perl 5.10
+	//
+	// Perl 5.10 gave in and implemented the Python version too,
+	// but they claim that the last two are the preferred forms.
+	// PCRE and languages based on it (specifically, PHP and Ruby)
+	// support all three as well.  EcmaScript 4 uses only the Python form.
+	//
+	// In both the open source world (via Code Search) and the
+	// Google source tree, (?P<expr>name) is the dominant form,
+	// so that's the one we implement.  One is enough.
+	if len(t) > 4 && t[2] == 'P' && t[3] == '<' {
+		// Pull out name.
+		end := strings.IndexRune(t, '>')
+		if end < 0 {
+			if err = checkUTF8(t); err != nil {
+				return "", err
+			}
+			return "", &Error{ErrInvalidNamedCapture, s}
+		}
+
+		capture := t[:end+1] // "(?P<name>"
+		name := t[4:end]     // "name"
+		if err = checkUTF8(name); err != nil {
+			return "", err
+		}
+		if !isValidCaptureName(name) {
+			return "", &Error{ErrInvalidNamedCapture, capture}
+		}
+
+		// Like ordinary capture, but named.
+		p.numCap++
+		re := p.op(opLeftParen)
+		re.Cap = p.numCap
+		re.Name = name
+		return t[end+1:], nil
+	}
+
+	// Non-capturing group.  Might also twiddle Perl flags.
+	var c rune
+	t = t[2:] // skip (?
+	flags := p.flags
+	sign := +1
+	sawFlag := false
+Loop:
+	for t != "" {
+		if c, t, err = nextRune(t); err != nil {
+			return "", err
+		}
+		switch c {
+		default:
+			break Loop
+
+		// Flags.
+		case 'i':
+			flags |= FoldCase
+			sawFlag = true
+		case 'm':
+			flags &^= OneLine
+			sawFlag = true
+		case 's':
+			flags |= DotNL
+			sawFlag = true
+		case 'U':
+			flags |= NonGreedy
+			sawFlag = true
+
+		// Switch to negation.
+		case '-':
+			if sign < 0 {
+				break Loop
+			}
+			sign = -1
+			// Invert flags so that | above turn into &^ and vice versa.
+			// We'll invert flags again before using it below.
+			flags = ^flags
+			sawFlag = false
+
+		// End of flags, starting group or not.
+		case ':', ')':
+			if sign < 0 {
+				if !sawFlag {
+					break Loop
+				}
+				flags = ^flags
+			}
+			if c == ':' {
+				// Open new group
+				p.op(opLeftParen)
+			}
+			p.flags = flags
+			return t, nil
+		}
+	}
+
+	return "", &Error{ErrInvalidPerlOp, s[:len(s)-len(t)]}
+}
+
+// isValidCaptureName reports whether name
+// is a valid capture name: [A-Za-z0-9_]+.
+// PCRE limits names to 32 bytes.
+// Python rejects names starting with digits.
+// We don't enforce either of those.
+func isValidCaptureName(name string) bool {
+	if name == "" {
+		return false
+	}
+	for _, c := range name {
+		if c != '_' && !isalnum(c) {
+			return false
+		}
+	}
+	return true
+}
+
+// parseInt parses a decimal integer.
+func (p *parser) parseInt(s string) (n int, rest string, ok bool) {
+	if s == "" || s[0] < '0' || '9' < s[0] {
+		return
+	}
+	// Disallow leading zeros.
+	if len(s) >= 2 && s[0] == '0' && '0' <= s[1] && s[1] <= '9' {
+		return
+	}
+	t := s
+	for s != "" && '0' <= s[0] && s[0] <= '9' {
+		s = s[1:]
+	}
+	rest = s
+	ok = true
+	// Have digits, compute value.
+	t = t[:len(t)-len(s)]
+	for i := 0; i < len(t); i++ {
+		// Avoid overflow.
+		if n >= 1e8 {
+			n = -1
+			break
+		}
+		n = n*10 + int(t[i]) - '0'
+	}
+	return
+}
+
+// can this be represented as a character class?
+// single-rune literal string, char class, ., and .|\n.
+func isCharClass(re *Regexp) bool {
+	return re.Op == OpLiteral && len(re.Rune) == 1 ||
+		re.Op == OpCharClass ||
+		re.Op == OpAnyCharNotNL ||
+		re.Op == OpAnyChar
+}
+
+// does re match r?
+func matchRune(re *Regexp, r rune) bool {
+	switch re.Op {
+	case OpLiteral:
+		return len(re.Rune) == 1 && re.Rune[0] == r
+	case OpCharClass:
+		for i := 0; i < len(re.Rune); i += 2 {
+			if re.Rune[i] <= r && r <= re.Rune[i+1] {
+				return true
+			}
+		}
+		return false
+	case OpAnyCharNotNL:
+		return r != '\n'
+	case OpAnyChar:
+		return true
+	}
+	return false
+}
+
+// parseVerticalBar handles a | in the input.
+func (p *parser) parseVerticalBar() error {
+	p.concat()
+
+	// The concatenation we just parsed is on top of the stack.
+	// If it sits above an opVerticalBar, swap it below
+	// (things below an opVerticalBar become an alternation).
+	// Otherwise, push a new vertical bar.
+	if !p.swapVerticalBar() {
+		p.op(opVerticalBar)
+	}
+
+	return nil
+}
+
+// mergeCharClass makes dst = dst|src.
+// The caller must ensure that dst.Op >= src.Op,
+// to reduce the amount of copying.
+func mergeCharClass(dst, src *Regexp) {
+	switch dst.Op {
+	case OpAnyChar:
+		// src doesn't add anything.
+	case OpAnyCharNotNL:
+		// src might add \n
+		if matchRune(src, '\n') {
+			dst.Op = OpAnyChar
+		}
+	case OpCharClass:
+		// src is simpler, so either literal or char class
+		if src.Op == OpLiteral {
+			dst.Rune = appendLiteral(dst.Rune, src.Rune[0], src.Flags)
+		} else {
+			dst.Rune = appendClass(dst.Rune, src.Rune)
+		}
+	case OpLiteral:
+		// both literal
+		if src.Rune[0] == dst.Rune[0] && src.Flags == dst.Flags {
+			break
+		}
+		dst.Op = OpCharClass
+		dst.Rune = appendLiteral(dst.Rune[:0], dst.Rune[0], dst.Flags)
+		dst.Rune = appendLiteral(dst.Rune, src.Rune[0], src.Flags)
+	}
+}
+
+// If the top of the stack is an element followed by an opVerticalBar
+// swapVerticalBar swaps the two and returns true.
+// Otherwise it returns false.
+func (p *parser) swapVerticalBar() bool {
+	// If above and below vertical bar are literal or char class,
+	// can merge into a single char class.
+	n := len(p.stack)
+	if n >= 3 && p.stack[n-2].Op == opVerticalBar && isCharClass(p.stack[n-1]) && isCharClass(p.stack[n-3]) {
+		re1 := p.stack[n-1]
+		re3 := p.stack[n-3]
+		// Make re3 the more complex of the two.
+		if re1.Op > re3.Op {
+			re1, re3 = re3, re1
+			p.stack[n-3] = re3
+		}
+		mergeCharClass(re3, re1)
+		p.reuse(re1)
+		p.stack = p.stack[:n-1]
+		return true
+	}
+
+	if n >= 2 {
+		re1 := p.stack[n-1]
+		re2 := p.stack[n-2]
+		if re2.Op == opVerticalBar {
+			if n >= 3 {
+				// Now out of reach.
+				// Clean opportunistically.
+				cleanAlt(p.stack[n-3])
+			}
+			p.stack[n-2] = re1
+			p.stack[n-1] = re2
+			return true
+		}
+	}
+	return false
+}
+
+// parseRightParen handles a ) in the input.
+func (p *parser) parseRightParen() error {
+	p.concat()
+	if p.swapVerticalBar() {
+		// pop vertical bar
+		p.stack = p.stack[:len(p.stack)-1]
+	}
+	p.alternate()
+
+	n := len(p.stack)
+	if n < 2 {
+		return &Error{ErrUnexpectedParen, p.wholeRegexp}
+	}
+	re1 := p.stack[n-1]
+	re2 := p.stack[n-2]
+	p.stack = p.stack[:n-2]
+	if re2.Op != opLeftParen {
+		return &Error{ErrUnexpectedParen, p.wholeRegexp}
+	}
+	// Restore flags at time of paren.
+	p.flags = re2.Flags
+	if re2.Cap == 0 {
+		// Just for grouping.
+		p.push(re1)
+	} else {
+		re2.Op = OpCapture
+		re2.Sub = re2.Sub0[:1]
+		re2.Sub[0] = re1
+		p.push(re2)
+	}
+	return nil
+}
+
+// parseEscape parses an escape sequence at the beginning of s
+// and returns the rune.
+func (p *parser) parseEscape(s string) (r rune, rest string, err error) {
+	t := s[1:]
+	if t == "" {
+		return 0, "", &Error{ErrTrailingBackslash, ""}
+	}
+	c, t, err := nextRune(t)
+	if err != nil {
+		return 0, "", err
+	}
+
+Switch:
+	switch c {
+	default:
+		if c < utf8.RuneSelf && !isalnum(c) {
+			// Escaped non-word characters are always themselves.
+			// PCRE is not quite so rigorous: it accepts things like
+			// \q, but we don't.  We once rejected \_, but too many
+			// programs and people insist on using it, so allow \_.
+			return c, t, nil
+		}
+
+	// Octal escapes.
+	case '1', '2', '3', '4', '5', '6', '7':
+		// Single non-zero digit is a backreference; not supported
+		if t == "" || t[0] < '0' || t[0] > '7' {
+			break
+		}
+		fallthrough
+	case '0':
+		// Consume up to three octal digits; already have one.
+		r = c - '0'
+		for i := 1; i < 3; i++ {
+			if t == "" || t[0] < '0' || t[0] > '7' {
+				break
+			}
+			r = r*8 + rune(t[0]) - '0'
+			t = t[1:]
+		}
+		return r, t, nil
+
+	// Hexadecimal escapes.
+	case 'x':
+		if t == "" {
+			break
+		}
+		if c, t, err = nextRune(t); err != nil {
+			return 0, "", err
+		}
+		if c == '{' {
+			// Any number of digits in braces.
+			// Perl accepts any text at all; it ignores all text
+			// after the first non-hex digit.  We require only hex digits,
+			// and at least one.
+			nhex := 0
+			r = 0
+			for {
+				if t == "" {
+					break Switch
+				}
+				if c, t, err = nextRune(t); err != nil {
+					return 0, "", err
+				}
+				if c == '}' {
+					break
+				}
+				v := unhex(c)
+				if v < 0 {
+					break Switch
+				}
+				r = r*16 + v
+				if r > unicode.MaxRune {
+					break Switch
+				}
+				nhex++
+			}
+			if nhex == 0 {
+				break Switch
+			}
+			return r, t, nil
+		}
+
+		// Easy case: two hex digits.
+		x := unhex(c)
+		if c, t, err = nextRune(t); err != nil {
+			return 0, "", err
+		}
+		y := unhex(c)
+		if x < 0 || y < 0 {
+			break
+		}
+		return x*16 + y, t, nil
+
+	// C escapes.  There is no case 'b', to avoid misparsing
+	// the Perl word-boundary \b as the C backspace \b
+	// when in POSIX mode.  In Perl, /\b/ means word-boundary
+	// but /[\b]/ means backspace.  We don't support that.
+	// If you want a backspace, embed a literal backspace
+	// character or use \x08.
+	case 'a':
+		return '\a', t, err
+	case 'f':
+		return '\f', t, err
+	case 'n':
+		return '\n', t, err
+	case 'r':
+		return '\r', t, err
+	case 't':
+		return '\t', t, err
+	case 'v':
+		return '\v', t, err
+	}
+	return 0, "", &Error{ErrInvalidEscape, s[:len(s)-len(t)]}
+}
+
+// parseClassChar parses a character class character at the beginning of s
+// and returns it.
+func (p *parser) parseClassChar(s, wholeClass string) (r rune, rest string, err error) {
+	if s == "" {
+		return 0, "", &Error{Code: ErrMissingBracket, Expr: wholeClass}
+	}
+
+	// Allow regular escape sequences even though
+	// many need not be escaped in this context.
+	if s[0] == '\\' {
+		return p.parseEscape(s)
+	}
+
+	return nextRune(s)
+}
+
+type charGroup struct {
+	sign  int
+	class []rune
+}
+
+// parsePerlClassEscape parses a leading Perl character class escape like \d
+// from the beginning of s.  If one is present, it appends the characters to r
+// and returns the new slice r and the remainder of the string.
+func (p *parser) parsePerlClassEscape(s string, r []rune) (out []rune, rest string) {
+	if p.flags&PerlX == 0 || len(s) < 2 || s[0] != '\\' {
+		return
+	}
+	g := perlGroup[s[0:2]]
+	if g.sign == 0 {
+		return
+	}
+	return p.appendGroup(r, g), s[2:]
+}
+
+// parseNamedClass parses a leading POSIX named character class like [:alnum:]
+// from the beginning of s.  If one is present, it appends the characters to r
+// and returns the new slice r and the remainder of the string.
+func (p *parser) parseNamedClass(s string, r []rune) (out []rune, rest string, err error) {
+	if len(s) < 2 || s[0] != '[' || s[1] != ':' {
+		return
+	}
+
+	i := strings.Index(s[2:], ":]")
+	if i < 0 {
+		return
+	}
+	i += 2
+	name, s := s[0:i+2], s[i+2:]
+	g := posixGroup[name]
+	if g.sign == 0 {
+		return nil, "", &Error{ErrInvalidCharRange, name}
+	}
+	return p.appendGroup(r, g), s, nil
+}
+
+func (p *parser) appendGroup(r []rune, g charGroup) []rune {
+	if p.flags&FoldCase == 0 {
+		if g.sign < 0 {
+			r = appendNegatedClass(r, g.class)
+		} else {
+			r = appendClass(r, g.class)
+		}
+	} else {
+		tmp := p.tmpClass[:0]
+		tmp = appendFoldedClass(tmp, g.class)
+		p.tmpClass = tmp
+		tmp = cleanClass(&p.tmpClass)
+		if g.sign < 0 {
+			r = appendNegatedClass(r, tmp)
+		} else {
+			r = appendClass(r, tmp)
+		}
+	}
+	return r
+}
+
+var anyTable = &unicode.RangeTable{
+	R16: []unicode.Range16{{Lo: 0, Hi: 1<<16 - 1, Stride: 1}},
+	R32: []unicode.Range32{{Lo: 1 << 16, Hi: unicode.MaxRune, Stride: 1}},
+}
+
+// unicodeTable returns the unicode.RangeTable identified by name
+// and the table of additional fold-equivalent code points.
+func unicodeTable(name string) (*unicode.RangeTable, *unicode.RangeTable) {
+	// Special case: "Any" means any.
+	if name == "Any" {
+		return anyTable, anyTable
+	}
+	if t := unicode.Categories[name]; t != nil {
+		return t, unicode.FoldCategory[name]
+	}
+	if t := unicode.Scripts[name]; t != nil {
+		return t, unicode.FoldScript[name]
+	}
+	return nil, nil
+}
+
+// parseUnicodeClass parses a leading Unicode character class like \p{Han}
+// from the beginning of s.  If one is present, it appends the characters to r
+// and returns the new slice r and the remainder of the string.
+func (p *parser) parseUnicodeClass(s string, r []rune) (out []rune, rest string, err error) {
+	if p.flags&UnicodeGroups == 0 || len(s) < 2 || s[0] != '\\' || s[1] != 'p' && s[1] != 'P' {
+		return
+	}
+
+	// Committed to parse or return error.
+	sign := +1
+	if s[1] == 'P' {
+		sign = -1
+	}
+	t := s[2:]
+	c, t, err := nextRune(t)
+	if err != nil {
+		return
+	}
+	var seq, name string
+	if c != '{' {
+		// Single-letter name.
+		seq = s[:len(s)-len(t)]
+		name = seq[2:]
+	} else {
+		// Name is in braces.
+		end := strings.IndexRune(s, '}')
+		if end < 0 {
+			if err = checkUTF8(s); err != nil {
+				return
+			}
+			return nil, "", &Error{ErrInvalidCharRange, s}
+		}
+		seq, t = s[:end+1], s[end+1:]
+		name = s[3:end]
+		if err = checkUTF8(name); err != nil {
+			return
+		}
+	}
+
+	// Group can have leading negation too.  \p{^Han} == \P{Han}, \P{^Han} == \p{Han}.
+	if name != "" && name[0] == '^' {
+		sign = -sign
+		name = name[1:]
+	}
+
+	tab, fold := unicodeTable(name)
+	if tab == nil {
+		return nil, "", &Error{ErrInvalidCharRange, seq}
+	}
+
+	if p.flags&FoldCase == 0 || fold == nil {
+		if sign > 0 {
+			r = appendTable(r, tab)
+		} else {
+			r = appendNegatedTable(r, tab)
+		}
+	} else {
+		// Merge and clean tab and fold in a temporary buffer.
+		// This is necessary for the negative case and just tidy
+		// for the positive case.
+		tmp := p.tmpClass[:0]
+		tmp = appendTable(tmp, tab)
+		tmp = appendTable(tmp, fold)
+		p.tmpClass = tmp
+		tmp = cleanClass(&p.tmpClass)
+		if sign > 0 {
+			r = appendClass(r, tmp)
+		} else {
+			r = appendNegatedClass(r, tmp)
+		}
+	}
+	return r, t, nil
+}
+
+// parseClass parses a character class at the beginning of s
+// and pushes it onto the parse stack.
+func (p *parser) parseClass(s string) (rest string, err error) {
+	t := s[1:] // chop [
+	re := p.newRegexp(OpCharClass)
+	re.Flags = p.flags
+	re.Rune = re.Rune0[:0]
+
+	sign := +1
+	if t != "" && t[0] == '^' {
+		sign = -1
+		t = t[1:]
+
+		// If character class does not match \n, add it here,
+		// so that negation later will do the right thing.
+		if p.flags&ClassNL == 0 {
+			re.Rune = append(re.Rune, '\n', '\n')
+		}
+	}
+
+	class := re.Rune
+	first := true // ] and - are okay as first char in class
+	for t == "" || t[0] != ']' || first {
+		// POSIX: - is only okay unescaped as first or last in class.
+		// Perl: - is okay anywhere.
+		if t != "" && t[0] == '-' && p.flags&PerlX == 0 && !first && (len(t) == 1 || t[1] != ']') {
+			_, size := utf8.DecodeRuneInString(t[1:])
+			return "", &Error{Code: ErrInvalidCharRange, Expr: t[:1+size]}
+		}
+		first = false
+
+		// Look for POSIX [:alnum:] etc.
+		if len(t) > 2 && t[0] == '[' && t[1] == ':' {
+			nclass, nt, err := p.parseNamedClass(t, class)
+			if err != nil {
+				return "", err
+			}
+			if nclass != nil {
+				class, t = nclass, nt
+				continue
+			}
+		}
+
+		// Look for Unicode character group like \p{Han}.
+		nclass, nt, err := p.parseUnicodeClass(t, class)
+		if err != nil {
+			return "", err
+		}
+		if nclass != nil {
+			class, t = nclass, nt
+			continue
+		}
+
+		// Look for Perl character class symbols (extension).
+		if nclass, nt := p.parsePerlClassEscape(t, class); nclass != nil {
+			class, t = nclass, nt
+			continue
+		}
+
+		// Single character or simple range.
+		rng := t
+		var lo, hi rune
+		if lo, t, err = p.parseClassChar(t, s); err != nil {
+			return "", err
+		}
+		hi = lo
+		// [a-] means (a|-) so check for final ].
+		if len(t) >= 2 && t[0] == '-' && t[1] != ']' {
+			t = t[1:]
+			if hi, t, err = p.parseClassChar(t, s); err != nil {
+				return "", err
+			}
+			if hi < lo {
+				rng = rng[:len(rng)-len(t)]
+				return "", &Error{Code: ErrInvalidCharRange, Expr: rng}
+			}
+		}
+		if p.flags&FoldCase == 0 {
+			class = appendRange(class, lo, hi)
+		} else {
+			class = appendFoldedRange(class, lo, hi)
+		}
+	}
+	t = t[1:] // chop ]
+
+	// Use &re.Rune instead of &class to avoid allocation.
+	re.Rune = class
+	class = cleanClass(&re.Rune)
+	if sign < 0 {
+		class = negateClass(class)
+	}
+	re.Rune = class
+	p.push(re)
+	return t, nil
+}
+
+// cleanClass sorts the ranges (pairs of elements of r),
+// merges them, and eliminates duplicates.
+func cleanClass(rp *[]rune) []rune {
+
+	// Sort by lo increasing, hi decreasing to break ties.
+	sort.Sort(ranges{rp})
+
+	r := *rp
+	if len(r) < 2 {
+		return r
+	}
+
+	// Merge abutting, overlapping.
+	w := 2 // write index
+	for i := 2; i < len(r); i += 2 {
+		lo, hi := r[i], r[i+1]
+		if lo <= r[w-1]+1 {
+			// merge with previous range
+			if hi > r[w-1] {
+				r[w-1] = hi
+			}
+			continue
+		}
+		// new disjoint range
+		r[w] = lo
+		r[w+1] = hi
+		w += 2
+	}
+
+	return r[:w]
+}
+
+// appendLiteral returns the result of appending the literal x to the class r.
+func appendLiteral(r []rune, x rune, flags Flags) []rune {
+	if flags&FoldCase != 0 {
+		return appendFoldedRange(r, x, x)
+	}
+	return appendRange(r, x, x)
+}
+
+// appendRange returns the result of appending the range lo-hi to the class r.
+func appendRange(r []rune, lo, hi rune) []rune {
+	// Expand last range or next to last range if it overlaps or abuts.
+	// Checking two ranges helps when appending case-folded
+	// alphabets, so that one range can be expanding A-Z and the
+	// other expanding a-z.
+	n := len(r)
+	for i := 2; i <= 4; i += 2 { // twice, using i=2, i=4
+		if n >= i {
+			rlo, rhi := r[n-i], r[n-i+1]
+			if lo <= rhi+1 && rlo <= hi+1 {
+				if lo < rlo {
+					r[n-i] = lo
+				}
+				if hi > rhi {
+					r[n-i+1] = hi
+				}
+				return r
+			}
+		}
+	}
+
+	return append(r, lo, hi)
+}
+
+const (
+	// minimum and maximum runes involved in folding.
+	// checked during test.
+	minFold = 0x0041
+	maxFold = 0x118df
+)
+
+// appendFoldedRange returns the result of appending the range lo-hi
+// and its case folding-equivalent runes to the class r.
+func appendFoldedRange(r []rune, lo, hi rune) []rune {
+	// Optimizations.
+	if lo <= minFold && hi >= maxFold {
+		// Range is full: folding can't add more.
+		return appendRange(r, lo, hi)
+	}
+	if hi < minFold || lo > maxFold {
+		// Range is outside folding possibilities.
+		return appendRange(r, lo, hi)
+	}
+	if lo < minFold {
+		// [lo, minFold-1] needs no folding.
+		r = appendRange(r, lo, minFold-1)
+		lo = minFold
+	}
+	if hi > maxFold {
+		// [maxFold+1, hi] needs no folding.
+		r = appendRange(r, maxFold+1, hi)
+		hi = maxFold
+	}
+
+	// Brute force.  Depend on appendRange to coalesce ranges on the fly.
+	for c := lo; c <= hi; c++ {
+		r = appendRange(r, c, c)
+		f := unicode.SimpleFold(c)
+		for f != c {
+			r = appendRange(r, f, f)
+			f = unicode.SimpleFold(f)
+		}
+	}
+	return r
+}
+
+// appendClass returns the result of appending the class x to the class r.
+// It assume x is clean.
+func appendClass(r []rune, x []rune) []rune {
+	for i := 0; i < len(x); i += 2 {
+		r = appendRange(r, x[i], x[i+1])
+	}
+	return r
+}
+
+// appendFolded returns the result of appending the case folding of the class x to the class r.
+func appendFoldedClass(r []rune, x []rune) []rune {
+	for i := 0; i < len(x); i += 2 {
+		r = appendFoldedRange(r, x[i], x[i+1])
+	}
+	return r
+}
+
+// appendNegatedClass returns the result of appending the negation of the class x to the class r.
+// It assumes x is clean.
+func appendNegatedClass(r []rune, x []rune) []rune {
+	nextLo := '\u0000'
+	for i := 0; i < len(x); i += 2 {
+		lo, hi := x[i], x[i+1]
+		if nextLo <= lo-1 {
+			r = appendRange(r, nextLo, lo-1)
+		}
+		nextLo = hi + 1
+	}
+	if nextLo <= unicode.MaxRune {
+		r = appendRange(r, nextLo, unicode.MaxRune)
+	}
+	return r
+}
+
+// appendTable returns the result of appending x to the class r.
+func appendTable(r []rune, x *unicode.RangeTable) []rune {
+	for _, xr := range x.R16 {
+		lo, hi, stride := rune(xr.Lo), rune(xr.Hi), rune(xr.Stride)
+		if stride == 1 {
+			r = appendRange(r, lo, hi)
+			continue
+		}
+		for c := lo; c <= hi; c += stride {
+			r = appendRange(r, c, c)
+		}
+	}
+	for _, xr := range x.R32 {
+		lo, hi, stride := rune(xr.Lo), rune(xr.Hi), rune(xr.Stride)
+		if stride == 1 {
+			r = appendRange(r, lo, hi)
+			continue
+		}
+		for c := lo; c <= hi; c += stride {
+			r = appendRange(r, c, c)
+		}
+	}
+	return r
+}
+
+// appendNegatedTable returns the result of appending the negation of x to the class r.
+func appendNegatedTable(r []rune, x *unicode.RangeTable) []rune {
+	nextLo := '\u0000' // lo end of next class to add
+	for _, xr := range x.R16 {
+		lo, hi, stride := rune(xr.Lo), rune(xr.Hi), rune(xr.Stride)
+		if stride == 1 {
+			if nextLo <= lo-1 {
+				r = appendRange(r, nextLo, lo-1)
+			}
+			nextLo = hi + 1
+			continue
+		}
+		for c := lo; c <= hi; c += stride {
+			if nextLo <= c-1 {
+				r = appendRange(r, nextLo, c-1)
+			}
+			nextLo = c + 1
+		}
+	}
+	for _, xr := range x.R32 {
+		lo, hi, stride := rune(xr.Lo), rune(xr.Hi), rune(xr.Stride)
+		if stride == 1 {
+			if nextLo <= lo-1 {
+				r = appendRange(r, nextLo, lo-1)
+			}
+			nextLo = hi + 1
+			continue
+		}
+		for c := lo; c <= hi; c += stride {
+			if nextLo <= c-1 {
+				r = appendRange(r, nextLo, c-1)
+			}
+			nextLo = c + 1
+		}
+	}
+	if nextLo <= unicode.MaxRune {
+		r = appendRange(r, nextLo, unicode.MaxRune)
+	}
+	return r
+}
+
+// negateClass overwrites r and returns r's negation.
+// It assumes the class r is already clean.
+func negateClass(r []rune) []rune {
+	nextLo := '\u0000' // lo end of next class to add
+	w := 0             // write index
+	for i := 0; i < len(r); i += 2 {
+		lo, hi := r[i], r[i+1]
+		if nextLo <= lo-1 {
+			r[w] = nextLo
+			r[w+1] = lo - 1
+			w += 2
+		}
+		nextLo = hi + 1
+	}
+	r = r[:w]
+	if nextLo <= unicode.MaxRune {
+		// It's possible for the negation to have one more
+		// range - this one - than the original class, so use append.
+		r = append(r, nextLo, unicode.MaxRune)
+	}
+	return r
+}
+
+// ranges implements sort.Interface on a []rune.
+// The choice of receiver type definition is strange
+// but avoids an allocation since we already have
+// a *[]rune.
+type ranges struct {
+	p *[]rune
+}
+
+func (ra ranges) Less(i, j int) bool {
+	p := *ra.p
+	i *= 2
+	j *= 2
+	return p[i] < p[j] || p[i] == p[j] && p[i+1] > p[j+1]
+}
+
+func (ra ranges) Len() int {
+	return len(*ra.p) / 2
+}
+
+func (ra ranges) Swap(i, j int) {
+	p := *ra.p
+	i *= 2
+	j *= 2
+	p[i], p[i+1], p[j], p[j+1] = p[j], p[j+1], p[i], p[i+1]
+}
+
+func checkUTF8(s string) error {
+	for s != "" {
+		rune, size := utf8.DecodeRuneInString(s)
+		if rune == utf8.RuneError && size == 1 {
+			return &Error{Code: ErrInvalidUTF8, Expr: s}
+		}
+		s = s[size:]
+	}
+	return nil
+}
+
+func nextRune(s string) (c rune, t string, err error) {
+	c, size := utf8.DecodeRuneInString(s)
+	if c == utf8.RuneError && size == 1 {
+		return 0, "", &Error{Code: ErrInvalidUTF8, Expr: s}
+	}
+	return c, s[size:], nil
+}
+
+func isalnum(c rune) bool {
+	return '0' <= c && c <= '9' || 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z'
+}
+
+func unhex(c rune) rune {
+	if '0' <= c && c <= '9' {
+		return c - '0'
+	}
+	if 'a' <= c && c <= 'f' {
+		return c - 'a' + 10
+	}
+	if 'A' <= c && c <= 'F' {
+		return c - 'A' + 10
+	}
+	return -1
+}
diff --git a/src/regexp/syntax/parse_test.go b/src/regexp/syntax/parse_test.go
new file mode 100644
index 0000000..c4a1117
--- /dev/null
+++ b/src/regexp/syntax/parse_test.go
@@ -0,0 +1,572 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package syntax
+
+import (
+	"bytes"
+	"fmt"
+	"testing"
+	"unicode"
+)
+
+type parseTest struct {
+	Regexp string
+	Dump   string
+}
+
+var parseTests = []parseTest{
+	// Base cases
+	{`a`, `lit{a}`},
+	{`a.`, `cat{lit{a}dot{}}`},
+	{`a.b`, `cat{lit{a}dot{}lit{b}}`},
+	{`ab`, `str{ab}`},
+	{`a.b.c`, `cat{lit{a}dot{}lit{b}dot{}lit{c}}`},
+	{`abc`, `str{abc}`},
+	{`a|^`, `alt{lit{a}bol{}}`},
+	{`a|b`, `cc{0x61-0x62}`},
+	{`(a)`, `cap{lit{a}}`},
+	{`(a)|b`, `alt{cap{lit{a}}lit{b}}`},
+	{`a*`, `star{lit{a}}`},
+	{`a+`, `plus{lit{a}}`},
+	{`a?`, `que{lit{a}}`},
+	{`a{2}`, `rep{2,2 lit{a}}`},
+	{`a{2,3}`, `rep{2,3 lit{a}}`},
+	{`a{2,}`, `rep{2,-1 lit{a}}`},
+	{`a*?`, `nstar{lit{a}}`},
+	{`a+?`, `nplus{lit{a}}`},
+	{`a??`, `nque{lit{a}}`},
+	{`a{2}?`, `nrep{2,2 lit{a}}`},
+	{`a{2,3}?`, `nrep{2,3 lit{a}}`},
+	{`a{2,}?`, `nrep{2,-1 lit{a}}`},
+	// Malformed { } are treated as literals.
+	{`x{1001`, `str{x{1001}`},
+	{`x{9876543210`, `str{x{9876543210}`},
+	{`x{9876543210,`, `str{x{9876543210,}`},
+	{`x{2,1`, `str{x{2,1}`},
+	{`x{1,9876543210`, `str{x{1,9876543210}`},
+	{``, `emp{}`},
+	{`|`, `emp{}`}, // alt{emp{}emp{}} but got factored
+	{`|x|`, `alt{emp{}lit{x}emp{}}`},
+	{`.`, `dot{}`},
+	{`^`, `bol{}`},
+	{`$`, `eol{}`},
+	{`\|`, `lit{|}`},
+	{`\(`, `lit{(}`},
+	{`\)`, `lit{)}`},
+	{`\*`, `lit{*}`},
+	{`\+`, `lit{+}`},
+	{`\?`, `lit{?}`},
+	{`{`, `lit{{}`},
+	{`}`, `lit{}}`},
+	{`\.`, `lit{.}`},
+	{`\^`, `lit{^}`},
+	{`\$`, `lit{$}`},
+	{`\\`, `lit{\}`},
+	{`[ace]`, `cc{0x61 0x63 0x65}`},
+	{`[abc]`, `cc{0x61-0x63}`},
+	{`[a-z]`, `cc{0x61-0x7a}`},
+	{`[a]`, `lit{a}`},
+	{`\-`, `lit{-}`},
+	{`-`, `lit{-}`},
+	{`\_`, `lit{_}`},
+	{`abc`, `str{abc}`},
+	{`abc|def`, `alt{str{abc}str{def}}`},
+	{`abc|def|ghi`, `alt{str{abc}str{def}str{ghi}}`},
+
+	// Posix and Perl extensions
+	{`[[:lower:]]`, `cc{0x61-0x7a}`},
+	{`[a-z]`, `cc{0x61-0x7a}`},
+	{`[^[:lower:]]`, `cc{0x0-0x60 0x7b-0x10ffff}`},
+	{`[[:^lower:]]`, `cc{0x0-0x60 0x7b-0x10ffff}`},
+	{`(?i)[[:lower:]]`, `cc{0x41-0x5a 0x61-0x7a 0x17f 0x212a}`},
+	{`(?i)[a-z]`, `cc{0x41-0x5a 0x61-0x7a 0x17f 0x212a}`},
+	{`(?i)[^[:lower:]]`, `cc{0x0-0x40 0x5b-0x60 0x7b-0x17e 0x180-0x2129 0x212b-0x10ffff}`},
+	{`(?i)[[:^lower:]]`, `cc{0x0-0x40 0x5b-0x60 0x7b-0x17e 0x180-0x2129 0x212b-0x10ffff}`},
+	{`\d`, `cc{0x30-0x39}`},
+	{`\D`, `cc{0x0-0x2f 0x3a-0x10ffff}`},
+	{`\s`, `cc{0x9-0xa 0xc-0xd 0x20}`},
+	{`\S`, `cc{0x0-0x8 0xb 0xe-0x1f 0x21-0x10ffff}`},
+	{`\w`, `cc{0x30-0x39 0x41-0x5a 0x5f 0x61-0x7a}`},
+	{`\W`, `cc{0x0-0x2f 0x3a-0x40 0x5b-0x5e 0x60 0x7b-0x10ffff}`},
+	{`(?i)\w`, `cc{0x30-0x39 0x41-0x5a 0x5f 0x61-0x7a 0x17f 0x212a}`},
+	{`(?i)\W`, `cc{0x0-0x2f 0x3a-0x40 0x5b-0x5e 0x60 0x7b-0x17e 0x180-0x2129 0x212b-0x10ffff}`},
+	{`[^\\]`, `cc{0x0-0x5b 0x5d-0x10ffff}`},
+	//	{ `\C`, `byte{}` },  // probably never
+
+	// Unicode, negatives, and a double negative.
+	{`\p{Braille}`, `cc{0x2800-0x28ff}`},
+	{`\P{Braille}`, `cc{0x0-0x27ff 0x2900-0x10ffff}`},
+	{`\p{^Braille}`, `cc{0x0-0x27ff 0x2900-0x10ffff}`},
+	{`\P{^Braille}`, `cc{0x2800-0x28ff}`},
+	{`\pZ`, `cc{0x20 0xa0 0x1680 0x2000-0x200a 0x2028-0x2029 0x202f 0x205f 0x3000}`},
+	{`[\p{Braille}]`, `cc{0x2800-0x28ff}`},
+	{`[\P{Braille}]`, `cc{0x0-0x27ff 0x2900-0x10ffff}`},
+	{`[\p{^Braille}]`, `cc{0x0-0x27ff 0x2900-0x10ffff}`},
+	{`[\P{^Braille}]`, `cc{0x2800-0x28ff}`},
+	{`[\pZ]`, `cc{0x20 0xa0 0x1680 0x2000-0x200a 0x2028-0x2029 0x202f 0x205f 0x3000}`},
+	{`\p{Lu}`, mkCharClass(unicode.IsUpper)},
+	{`[\p{Lu}]`, mkCharClass(unicode.IsUpper)},
+	{`(?i)[\p{Lu}]`, mkCharClass(isUpperFold)},
+	{`\p{Any}`, `dot{}`},
+	{`\p{^Any}`, `cc{}`},
+
+	// Hex, octal.
+	{`[\012-\234]\141`, `cat{cc{0xa-0x9c}lit{a}}`},
+	{`[\x{41}-\x7a]\x61`, `cat{cc{0x41-0x7a}lit{a}}`},
+
+	// More interesting regular expressions.
+	{`a{,2}`, `str{a{,2}}`},
+	{`\.\^\$\\`, `str{.^$\}`},
+	{`[a-zABC]`, `cc{0x41-0x43 0x61-0x7a}`},
+	{`[^a]`, `cc{0x0-0x60 0x62-0x10ffff}`},
+	{`[α-ε☺]`, `cc{0x3b1-0x3b5 0x263a}`}, // utf-8
+	{`a*{`, `cat{star{lit{a}}lit{{}}`},
+
+	// Test precedences
+	{`(?:ab)*`, `star{str{ab}}`},
+	{`(ab)*`, `star{cap{str{ab}}}`},
+	{`ab|cd`, `alt{str{ab}str{cd}}`},
+	{`a(b|c)d`, `cat{lit{a}cap{cc{0x62-0x63}}lit{d}}`},
+
+	// Test flattening.
+	{`(?:a)`, `lit{a}`},
+	{`(?:ab)(?:cd)`, `str{abcd}`},
+	{`(?:a+b+)(?:c+d+)`, `cat{plus{lit{a}}plus{lit{b}}plus{lit{c}}plus{lit{d}}}`},
+	{`(?:a+|b+)|(?:c+|d+)`, `alt{plus{lit{a}}plus{lit{b}}plus{lit{c}}plus{lit{d}}}`},
+	{`(?:a|b)|(?:c|d)`, `cc{0x61-0x64}`},
+	{`a|.`, `dot{}`},
+	{`.|a`, `dot{}`},
+	{`(?:[abc]|A|Z|hello|world)`, `alt{cc{0x41 0x5a 0x61-0x63}str{hello}str{world}}`},
+	{`(?:[abc]|A|Z)`, `cc{0x41 0x5a 0x61-0x63}`},
+
+	// Test Perl quoted literals
+	{`\Q+|*?{[\E`, `str{+|*?{[}`},
+	{`\Q+\E+`, `plus{lit{+}}`},
+	{`\Q\\E`, `lit{\}`},
+	{`\Q\\\E`, `str{\\}`},
+
+	// Test Perl \A and \z
+	{`(?m)^`, `bol{}`},
+	{`(?m)$`, `eol{}`},
+	{`(?-m)^`, `bot{}`},
+	{`(?-m)$`, `eot{}`},
+	{`(?m)\A`, `bot{}`},
+	{`(?m)\z`, `eot{\z}`},
+	{`(?-m)\A`, `bot{}`},
+	{`(?-m)\z`, `eot{\z}`},
+
+	// Test named captures
+	{`(?P<name>a)`, `cap{name:lit{a}}`},
+
+	// Case-folded literals
+	{`[Aa]`, `litfold{A}`},
+	{`[\x{100}\x{101}]`, `litfold{Ā}`},
+	{`[Δδ]`, `litfold{Δ}`},
+
+	// Strings
+	{`abcde`, `str{abcde}`},
+	{`[Aa][Bb]cd`, `cat{strfold{AB}str{cd}}`},
+
+	// Factoring.
+	{`abc|abd|aef|bcx|bcy`, `alt{cat{lit{a}alt{cat{lit{b}cc{0x63-0x64}}str{ef}}}cat{str{bc}cc{0x78-0x79}}}`},
+	{`ax+y|ax+z|ay+w`, `cat{lit{a}alt{cat{plus{lit{x}}cc{0x79-0x7a}}cat{plus{lit{y}}lit{w}}}}`},
+
+	// Bug fixes.
+	{`(?:.)`, `dot{}`},
+	{`(?:x|(?:xa))`, `cat{lit{x}alt{emp{}lit{a}}}`},
+	{`(?:.|(?:.a))`, `cat{dot{}alt{emp{}lit{a}}}`},
+	{`(?:A(?:A|a))`, `cat{lit{A}litfold{A}}`},
+	{`(?:A|a)`, `litfold{A}`},
+	{`A|(?:A|a)`, `litfold{A}`},
+	{`(?s).`, `dot{}`},
+	{`(?-s).`, `dnl{}`},
+	{`(?:(?:^).)`, `cat{bol{}dot{}}`},
+	{`(?-s)(?:(?:^).)`, `cat{bol{}dnl{}}`},
+
+	// RE2 prefix_tests
+	{`abc|abd`, `cat{str{ab}cc{0x63-0x64}}`},
+	{`a(?:b)c|abd`, `cat{str{ab}cc{0x63-0x64}}`},
+	{`abc|abd|aef|bcx|bcy`,
+		`alt{cat{lit{a}alt{cat{lit{b}cc{0x63-0x64}}str{ef}}}` +
+			`cat{str{bc}cc{0x78-0x79}}}`},
+	{`abc|x|abd`, `alt{str{abc}lit{x}str{abd}}`},
+	{`(?i)abc|ABD`, `cat{strfold{AB}cc{0x43-0x44 0x63-0x64}}`},
+	{`[ab]c|[ab]d`, `cat{cc{0x61-0x62}cc{0x63-0x64}}`},
+	{`(?:xx|yy)c|(?:xx|yy)d`,
+		`cat{alt{str{xx}str{yy}}cc{0x63-0x64}}`},
+	{`x{2}|x{2}[0-9]`,
+		`cat{rep{2,2 lit{x}}alt{emp{}cc{0x30-0x39}}}`},
+	{`x{2}y|x{2}[0-9]y`,
+		`cat{rep{2,2 lit{x}}alt{lit{y}cat{cc{0x30-0x39}lit{y}}}}`},
+
+	// Valid repetitions.
+	{`((((((((((x{2}){2}){2}){2}){2}){2}){2}){2}){2}))`, ``},
+	{`((((((((((x{1}){2}){2}){2}){2}){2}){2}){2}){2}){2})`, ``},
+}
+
+const testFlags = MatchNL | PerlX | UnicodeGroups
+
+func TestParseSimple(t *testing.T) {
+	testParseDump(t, parseTests, testFlags)
+}
+
+var foldcaseTests = []parseTest{
+	{`AbCdE`, `strfold{ABCDE}`},
+	{`[Aa]`, `litfold{A}`},
+	{`a`, `litfold{A}`},
+
+	// 0x17F is an old English long s (looks like an f) and folds to s.
+	// 0x212A is the Kelvin symbol and folds to k.
+	{`A[F-g]`, `cat{litfold{A}cc{0x41-0x7a 0x17f 0x212a}}`}, // [Aa][A-z...]
+	{`[[:upper:]]`, `cc{0x41-0x5a 0x61-0x7a 0x17f 0x212a}`},
+	{`[[:lower:]]`, `cc{0x41-0x5a 0x61-0x7a 0x17f 0x212a}`},
+}
+
+func TestParseFoldCase(t *testing.T) {
+	testParseDump(t, foldcaseTests, FoldCase)
+}
+
+var literalTests = []parseTest{
+	{"(|)^$.[*+?]{5,10},\\", "str{(|)^$.[*+?]{5,10},\\}"},
+}
+
+func TestParseLiteral(t *testing.T) {
+	testParseDump(t, literalTests, Literal)
+}
+
+var matchnlTests = []parseTest{
+	{`.`, `dot{}`},
+	{"\n", "lit{\n}"},
+	{`[^a]`, `cc{0x0-0x60 0x62-0x10ffff}`},
+	{`[a\n]`, `cc{0xa 0x61}`},
+}
+
+func TestParseMatchNL(t *testing.T) {
+	testParseDump(t, matchnlTests, MatchNL)
+}
+
+var nomatchnlTests = []parseTest{
+	{`.`, `dnl{}`},
+	{"\n", "lit{\n}"},
+	{`[^a]`, `cc{0x0-0x9 0xb-0x60 0x62-0x10ffff}`},
+	{`[a\n]`, `cc{0xa 0x61}`},
+}
+
+func TestParseNoMatchNL(t *testing.T) {
+	testParseDump(t, nomatchnlTests, 0)
+}
+
+// Test Parse -> Dump.
+func testParseDump(t *testing.T, tests []parseTest, flags Flags) {
+	for _, tt := range tests {
+		re, err := Parse(tt.Regexp, flags)
+		if err != nil {
+			t.Errorf("Parse(%#q): %v", tt.Regexp, err)
+			continue
+		}
+		if tt.Dump == "" {
+			// It parsed. That's all we care about.
+			continue
+		}
+		d := dump(re)
+		if d != tt.Dump {
+			t.Errorf("Parse(%#q).Dump() = %#q want %#q", tt.Regexp, d, tt.Dump)
+		}
+	}
+}
+
+// dump prints a string representation of the regexp showing
+// the structure explicitly.
+func dump(re *Regexp) string {
+	var b bytes.Buffer
+	dumpRegexp(&b, re)
+	return b.String()
+}
+
+var opNames = []string{
+	OpNoMatch:        "no",
+	OpEmptyMatch:     "emp",
+	OpLiteral:        "lit",
+	OpCharClass:      "cc",
+	OpAnyCharNotNL:   "dnl",
+	OpAnyChar:        "dot",
+	OpBeginLine:      "bol",
+	OpEndLine:        "eol",
+	OpBeginText:      "bot",
+	OpEndText:        "eot",
+	OpWordBoundary:   "wb",
+	OpNoWordBoundary: "nwb",
+	OpCapture:        "cap",
+	OpStar:           "star",
+	OpPlus:           "plus",
+	OpQuest:          "que",
+	OpRepeat:         "rep",
+	OpConcat:         "cat",
+	OpAlternate:      "alt",
+}
+
+// dumpRegexp writes an encoding of the syntax tree for the regexp re to b.
+// It is used during testing to distinguish between parses that might print
+// the same using re's String method.
+func dumpRegexp(b *bytes.Buffer, re *Regexp) {
+	if int(re.Op) >= len(opNames) || opNames[re.Op] == "" {
+		fmt.Fprintf(b, "op%d", re.Op)
+	} else {
+		switch re.Op {
+		default:
+			b.WriteString(opNames[re.Op])
+		case OpStar, OpPlus, OpQuest, OpRepeat:
+			if re.Flags&NonGreedy != 0 {
+				b.WriteByte('n')
+			}
+			b.WriteString(opNames[re.Op])
+		case OpLiteral:
+			if len(re.Rune) > 1 {
+				b.WriteString("str")
+			} else {
+				b.WriteString("lit")
+			}
+			if re.Flags&FoldCase != 0 {
+				for _, r := range re.Rune {
+					if unicode.SimpleFold(r) != r {
+						b.WriteString("fold")
+						break
+					}
+				}
+			}
+		}
+	}
+	b.WriteByte('{')
+	switch re.Op {
+	case OpEndText:
+		if re.Flags&WasDollar == 0 {
+			b.WriteString(`\z`)
+		}
+	case OpLiteral:
+		for _, r := range re.Rune {
+			b.WriteRune(r)
+		}
+	case OpConcat, OpAlternate:
+		for _, sub := range re.Sub {
+			dumpRegexp(b, sub)
+		}
+	case OpStar, OpPlus, OpQuest:
+		dumpRegexp(b, re.Sub[0])
+	case OpRepeat:
+		fmt.Fprintf(b, "%d,%d ", re.Min, re.Max)
+		dumpRegexp(b, re.Sub[0])
+	case OpCapture:
+		if re.Name != "" {
+			b.WriteString(re.Name)
+			b.WriteByte(':')
+		}
+		dumpRegexp(b, re.Sub[0])
+	case OpCharClass:
+		sep := ""
+		for i := 0; i < len(re.Rune); i += 2 {
+			b.WriteString(sep)
+			sep = " "
+			lo, hi := re.Rune[i], re.Rune[i+1]
+			if lo == hi {
+				fmt.Fprintf(b, "%#x", lo)
+			} else {
+				fmt.Fprintf(b, "%#x-%#x", lo, hi)
+			}
+		}
+	}
+	b.WriteByte('}')
+}
+
+func mkCharClass(f func(rune) bool) string {
+	re := &Regexp{Op: OpCharClass}
+	lo := rune(-1)
+	for i := rune(0); i <= unicode.MaxRune; i++ {
+		if f(i) {
+			if lo < 0 {
+				lo = i
+			}
+		} else {
+			if lo >= 0 {
+				re.Rune = append(re.Rune, lo, i-1)
+				lo = -1
+			}
+		}
+	}
+	if lo >= 0 {
+		re.Rune = append(re.Rune, lo, unicode.MaxRune)
+	}
+	return dump(re)
+}
+
+func isUpperFold(r rune) bool {
+	if unicode.IsUpper(r) {
+		return true
+	}
+	c := unicode.SimpleFold(r)
+	for c != r {
+		if unicode.IsUpper(c) {
+			return true
+		}
+		c = unicode.SimpleFold(c)
+	}
+	return false
+}
+
+func TestFoldConstants(t *testing.T) {
+	last := rune(-1)
+	for i := rune(0); i <= unicode.MaxRune; i++ {
+		if unicode.SimpleFold(i) == i {
+			continue
+		}
+		if last == -1 && minFold != i {
+			t.Errorf("minFold=%#U should be %#U", minFold, i)
+		}
+		last = i
+	}
+	if maxFold != last {
+		t.Errorf("maxFold=%#U should be %#U", maxFold, last)
+	}
+}
+
+func TestAppendRangeCollapse(t *testing.T) {
+	// AppendRange should collapse each of the new ranges
+	// into the earlier ones (it looks back two ranges), so that
+	// the slice never grows very large.
+	// Note that we are not calling cleanClass.
+	var r []rune
+	for i := rune('A'); i <= 'Z'; i++ {
+		r = appendRange(r, i, i)
+		r = appendRange(r, i+'a'-'A', i+'a'-'A')
+	}
+	if string(r) != "AZaz" {
+		t.Errorf("appendRange interlaced A-Z a-z = %s, want AZaz", string(r))
+	}
+}
+
+var invalidRegexps = []string{
+	`(`,
+	`)`,
+	`(a`,
+	`a)`,
+	`(a))`,
+	`(a|b|`,
+	`a|b|)`,
+	`(a|b|))`,
+	`(a|b`,
+	`a|b)`,
+	`(a|b))`,
+	`[a-z`,
+	`([a-z)`,
+	`[a-z)`,
+	`([a-z]))`,
+	`x{1001}`,
+	`x{9876543210}`,
+	`x{2,1}`,
+	`x{1,9876543210}`,
+	"\xff", // Invalid UTF-8
+	"[\xff]",
+	"[\\\xff]",
+	"\\\xff",
+	`(?P<name>a`,
+	`(?P<name>`,
+	`(?P<name`,
+	`(?P<x y>a)`,
+	`(?P<>a)`,
+	`[a-Z]`,
+	`(?i)[a-Z]`,
+	`a{100000}`,
+	`a{100000,}`,
+	"((((((((((x{2}){2}){2}){2}){2}){2}){2}){2}){2}){2})",
+}
+
+var onlyPerl = []string{
+	`[a-b-c]`,
+	`\Qabc\E`,
+	`\Q*+?{[\E`,
+	`\Q\\E`,
+	`\Q\\\E`,
+	`\Q\\\\E`,
+	`\Q\\\\\E`,
+	`(?:a)`,
+	`(?P<name>a)`,
+}
+
+var onlyPOSIX = []string{
+	"a++",
+	"a**",
+	"a?*",
+	"a+*",
+	"a{1}*",
+	".{1}{2}.{3}",
+}
+
+func TestParseInvalidRegexps(t *testing.T) {
+	for _, regexp := range invalidRegexps {
+		if re, err := Parse(regexp, Perl); err == nil {
+			t.Errorf("Parse(%#q, Perl) = %s, should have failed", regexp, dump(re))
+		}
+		if re, err := Parse(regexp, POSIX); err == nil {
+			t.Errorf("Parse(%#q, POSIX) = %s, should have failed", regexp, dump(re))
+		}
+	}
+	for _, regexp := range onlyPerl {
+		if _, err := Parse(regexp, Perl); err != nil {
+			t.Errorf("Parse(%#q, Perl): %v", regexp, err)
+		}
+		if re, err := Parse(regexp, POSIX); err == nil {
+			t.Errorf("Parse(%#q, POSIX) = %s, should have failed", regexp, dump(re))
+		}
+	}
+	for _, regexp := range onlyPOSIX {
+		if re, err := Parse(regexp, Perl); err == nil {
+			t.Errorf("Parse(%#q, Perl) = %s, should have failed", regexp, dump(re))
+		}
+		if _, err := Parse(regexp, POSIX); err != nil {
+			t.Errorf("Parse(%#q, POSIX): %v", regexp, err)
+		}
+	}
+}
+
+func TestToStringEquivalentParse(t *testing.T) {
+	for _, tt := range parseTests {
+		re, err := Parse(tt.Regexp, testFlags)
+		if err != nil {
+			t.Errorf("Parse(%#q): %v", tt.Regexp, err)
+			continue
+		}
+		if tt.Dump == "" {
+			// It parsed. That's all we care about.
+			continue
+		}
+		d := dump(re)
+		if d != tt.Dump {
+			t.Errorf("Parse(%#q).Dump() = %#q want %#q", tt.Regexp, d, tt.Dump)
+			continue
+		}
+
+		s := re.String()
+		if s != tt.Regexp {
+			// If ToString didn't return the original regexp,
+			// it must have found one with fewer parens.
+			// Unfortunately we can't check the length here, because
+			// ToString produces "\\{" for a literal brace,
+			// but "{" is a shorter equivalent in some contexts.
+			nre, err := Parse(s, testFlags)
+			if err != nil {
+				t.Errorf("Parse(%#q.String() = %#q): %v", tt.Regexp, s, err)
+				continue
+			}
+			nd := dump(nre)
+			if d != nd {
+				t.Errorf("Parse(%#q) -> %#q; %#q vs %#q", tt.Regexp, s, d, nd)
+			}
+
+			ns := nre.String()
+			if s != ns {
+				t.Errorf("Parse(%#q) -> %#q -> %#q", tt.Regexp, s, ns)
+			}
+		}
+	}
+}
diff --git a/src/pkg/regexp/syntax/perl_groups.go b/src/regexp/syntax/perl_groups.go
similarity index 100%
rename from src/pkg/regexp/syntax/perl_groups.go
rename to src/regexp/syntax/perl_groups.go
diff --git a/src/pkg/regexp/syntax/prog.go b/src/regexp/syntax/prog.go
similarity index 100%
rename from src/pkg/regexp/syntax/prog.go
rename to src/regexp/syntax/prog.go
diff --git a/src/pkg/regexp/syntax/prog_test.go b/src/regexp/syntax/prog_test.go
similarity index 100%
rename from src/pkg/regexp/syntax/prog_test.go
rename to src/regexp/syntax/prog_test.go
diff --git a/src/regexp/syntax/regexp.go b/src/regexp/syntax/regexp.go
new file mode 100644
index 0000000..cea7d9e
--- /dev/null
+++ b/src/regexp/syntax/regexp.go
@@ -0,0 +1,319 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package syntax
+
+// Note to implementers:
+// In this package, re is always a *Regexp and r is always a rune.
+
+import (
+	"bytes"
+	"strconv"
+	"strings"
+	"unicode"
+)
+
+// A Regexp is a node in a regular expression syntax tree.
+type Regexp struct {
+	Op       Op // operator
+	Flags    Flags
+	Sub      []*Regexp  // subexpressions, if any
+	Sub0     [1]*Regexp // storage for short Sub
+	Rune     []rune     // matched runes, for OpLiteral, OpCharClass
+	Rune0    [2]rune    // storage for short Rune
+	Min, Max int        // min, max for OpRepeat
+	Cap      int        // capturing index, for OpCapture
+	Name     string     // capturing name, for OpCapture
+}
+
+// An Op is a single regular expression operator.
+type Op uint8
+
+// Operators are listed in precedence order, tightest binding to weakest.
+// Character class operators are listed simplest to most complex
+// (OpLiteral, OpCharClass, OpAnyCharNotNL, OpAnyChar).
+
+const (
+	OpNoMatch        Op = 1 + iota // matches no strings
+	OpEmptyMatch                   // matches empty string
+	OpLiteral                      // matches Runes sequence
+	OpCharClass                    // matches Runes interpreted as range pair list
+	OpAnyCharNotNL                 // matches any character except newline
+	OpAnyChar                      // matches any character
+	OpBeginLine                    // matches empty string at beginning of line
+	OpEndLine                      // matches empty string at end of line
+	OpBeginText                    // matches empty string at beginning of text
+	OpEndText                      // matches empty string at end of text
+	OpWordBoundary                 // matches word boundary `\b`
+	OpNoWordBoundary               // matches word non-boundary `\B`
+	OpCapture                      // capturing subexpression with index Cap, optional name Name
+	OpStar                         // matches Sub[0] zero or more times
+	OpPlus                         // matches Sub[0] one or more times
+	OpQuest                        // matches Sub[0] zero or one times
+	OpRepeat                       // matches Sub[0] at least Min times, at most Max (Max == -1 is no limit)
+	OpConcat                       // matches concatenation of Subs
+	OpAlternate                    // matches alternation of Subs
+)
+
+const opPseudo Op = 128 // where pseudo-ops start
+
+// Equal returns true if x and y have identical structure.
+func (x *Regexp) Equal(y *Regexp) bool {
+	if x == nil || y == nil {
+		return x == y
+	}
+	if x.Op != y.Op {
+		return false
+	}
+	switch x.Op {
+	case OpEndText:
+		// The parse flags remember whether this is \z or \Z.
+		if x.Flags&WasDollar != y.Flags&WasDollar {
+			return false
+		}
+
+	case OpLiteral, OpCharClass:
+		if len(x.Rune) != len(y.Rune) {
+			return false
+		}
+		for i, r := range x.Rune {
+			if r != y.Rune[i] {
+				return false
+			}
+		}
+
+	case OpAlternate, OpConcat:
+		if len(x.Sub) != len(y.Sub) {
+			return false
+		}
+		for i, sub := range x.Sub {
+			if !sub.Equal(y.Sub[i]) {
+				return false
+			}
+		}
+
+	case OpStar, OpPlus, OpQuest:
+		if x.Flags&NonGreedy != y.Flags&NonGreedy || !x.Sub[0].Equal(y.Sub[0]) {
+			return false
+		}
+
+	case OpRepeat:
+		if x.Flags&NonGreedy != y.Flags&NonGreedy || x.Min != y.Min || x.Max != y.Max || !x.Sub[0].Equal(y.Sub[0]) {
+			return false
+		}
+
+	case OpCapture:
+		if x.Cap != y.Cap || x.Name != y.Name || !x.Sub[0].Equal(y.Sub[0]) {
+			return false
+		}
+	}
+	return true
+}
+
+// writeRegexp writes the Perl syntax for the regular expression re to b.
+func writeRegexp(b *bytes.Buffer, re *Regexp) {
+	switch re.Op {
+	default:
+		b.WriteString("<invalid op" + strconv.Itoa(int(re.Op)) + ">")
+	case OpNoMatch:
+		b.WriteString(`[^\x00-\x{10FFFF}]`)
+	case OpEmptyMatch:
+		b.WriteString(`(?:)`)
+	case OpLiteral:
+		if re.Flags&FoldCase != 0 {
+			b.WriteString(`(?i:`)
+		}
+		for _, r := range re.Rune {
+			escape(b, r, false)
+		}
+		if re.Flags&FoldCase != 0 {
+			b.WriteString(`)`)
+		}
+	case OpCharClass:
+		if len(re.Rune)%2 != 0 {
+			b.WriteString(`[invalid char class]`)
+			break
+		}
+		b.WriteRune('[')
+		if len(re.Rune) == 0 {
+			b.WriteString(`^\x00-\x{10FFFF}`)
+		} else if re.Rune[0] == 0 && re.Rune[len(re.Rune)-1] == unicode.MaxRune {
+			// Contains 0 and MaxRune.  Probably a negated class.
+			// Print the gaps.
+			b.WriteRune('^')
+			for i := 1; i < len(re.Rune)-1; i += 2 {
+				lo, hi := re.Rune[i]+1, re.Rune[i+1]-1
+				escape(b, lo, lo == '-')
+				if lo != hi {
+					b.WriteRune('-')
+					escape(b, hi, hi == '-')
+				}
+			}
+		} else {
+			for i := 0; i < len(re.Rune); i += 2 {
+				lo, hi := re.Rune[i], re.Rune[i+1]
+				escape(b, lo, lo == '-')
+				if lo != hi {
+					b.WriteRune('-')
+					escape(b, hi, hi == '-')
+				}
+			}
+		}
+		b.WriteRune(']')
+	case OpAnyCharNotNL:
+		b.WriteString(`(?-s:.)`)
+	case OpAnyChar:
+		b.WriteString(`(?s:.)`)
+	case OpBeginLine:
+		b.WriteRune('^')
+	case OpEndLine:
+		b.WriteRune('$')
+	case OpBeginText:
+		b.WriteString(`\A`)
+	case OpEndText:
+		if re.Flags&WasDollar != 0 {
+			b.WriteString(`(?-m:$)`)
+		} else {
+			b.WriteString(`\z`)
+		}
+	case OpWordBoundary:
+		b.WriteString(`\b`)
+	case OpNoWordBoundary:
+		b.WriteString(`\B`)
+	case OpCapture:
+		if re.Name != "" {
+			b.WriteString(`(?P<`)
+			b.WriteString(re.Name)
+			b.WriteRune('>')
+		} else {
+			b.WriteRune('(')
+		}
+		if re.Sub[0].Op != OpEmptyMatch {
+			writeRegexp(b, re.Sub[0])
+		}
+		b.WriteRune(')')
+	case OpStar, OpPlus, OpQuest, OpRepeat:
+		if sub := re.Sub[0]; sub.Op > OpCapture || sub.Op == OpLiteral && len(sub.Rune) > 1 {
+			b.WriteString(`(?:`)
+			writeRegexp(b, sub)
+			b.WriteString(`)`)
+		} else {
+			writeRegexp(b, sub)
+		}
+		switch re.Op {
+		case OpStar:
+			b.WriteRune('*')
+		case OpPlus:
+			b.WriteRune('+')
+		case OpQuest:
+			b.WriteRune('?')
+		case OpRepeat:
+			b.WriteRune('{')
+			b.WriteString(strconv.Itoa(re.Min))
+			if re.Max != re.Min {
+				b.WriteRune(',')
+				if re.Max >= 0 {
+					b.WriteString(strconv.Itoa(re.Max))
+				}
+			}
+			b.WriteRune('}')
+		}
+		if re.Flags&NonGreedy != 0 {
+			b.WriteRune('?')
+		}
+	case OpConcat:
+		for _, sub := range re.Sub {
+			if sub.Op == OpAlternate {
+				b.WriteString(`(?:`)
+				writeRegexp(b, sub)
+				b.WriteString(`)`)
+			} else {
+				writeRegexp(b, sub)
+			}
+		}
+	case OpAlternate:
+		for i, sub := range re.Sub {
+			if i > 0 {
+				b.WriteRune('|')
+			}
+			writeRegexp(b, sub)
+		}
+	}
+}
+
+func (re *Regexp) String() string {
+	var b bytes.Buffer
+	writeRegexp(&b, re)
+	return b.String()
+}
+
+const meta = `\.+*?()|[]{}^$`
+
+func escape(b *bytes.Buffer, r rune, force bool) {
+	if unicode.IsPrint(r) {
+		if strings.IndexRune(meta, r) >= 0 || force {
+			b.WriteRune('\\')
+		}
+		b.WriteRune(r)
+		return
+	}
+
+	switch r {
+	case '\a':
+		b.WriteString(`\a`)
+	case '\f':
+		b.WriteString(`\f`)
+	case '\n':
+		b.WriteString(`\n`)
+	case '\r':
+		b.WriteString(`\r`)
+	case '\t':
+		b.WriteString(`\t`)
+	case '\v':
+		b.WriteString(`\v`)
+	default:
+		if r < 0x100 {
+			b.WriteString(`\x`)
+			s := strconv.FormatInt(int64(r), 16)
+			if len(s) == 1 {
+				b.WriteRune('0')
+			}
+			b.WriteString(s)
+			break
+		}
+		b.WriteString(`\x{`)
+		b.WriteString(strconv.FormatInt(int64(r), 16))
+		b.WriteString(`}`)
+	}
+}
+
+// MaxCap walks the regexp to find the maximum capture index.
+func (re *Regexp) MaxCap() int {
+	m := 0
+	if re.Op == OpCapture {
+		m = re.Cap
+	}
+	for _, sub := range re.Sub {
+		if n := sub.MaxCap(); m < n {
+			m = n
+		}
+	}
+	return m
+}
+
+// CapNames walks the regexp to find the names of capturing groups.
+func (re *Regexp) CapNames() []string {
+	names := make([]string, re.MaxCap()+1)
+	re.capNames(names)
+	return names
+}
+
+func (re *Regexp) capNames(names []string) {
+	if re.Op == OpCapture {
+		names[re.Cap] = re.Name
+	}
+	for _, sub := range re.Sub {
+		sub.capNames(names)
+	}
+}
diff --git a/src/pkg/regexp/syntax/simplify.go b/src/regexp/syntax/simplify.go
similarity index 100%
rename from src/pkg/regexp/syntax/simplify.go
rename to src/regexp/syntax/simplify.go
diff --git a/src/pkg/regexp/syntax/simplify_test.go b/src/regexp/syntax/simplify_test.go
similarity index 100%
rename from src/pkg/regexp/syntax/simplify_test.go
rename to src/regexp/syntax/simplify_test.go
diff --git a/src/pkg/regexp/testdata/README b/src/regexp/testdata/README
similarity index 100%
rename from src/pkg/regexp/testdata/README
rename to src/regexp/testdata/README
diff --git a/src/pkg/regexp/testdata/basic.dat b/src/regexp/testdata/basic.dat
similarity index 100%
rename from src/pkg/regexp/testdata/basic.dat
rename to src/regexp/testdata/basic.dat
diff --git a/src/pkg/regexp/testdata/nullsubexpr.dat b/src/regexp/testdata/nullsubexpr.dat
similarity index 100%
rename from src/pkg/regexp/testdata/nullsubexpr.dat
rename to src/regexp/testdata/nullsubexpr.dat
diff --git a/src/pkg/regexp/testdata/re2-exhaustive.txt.bz2 b/src/regexp/testdata/re2-exhaustive.txt.bz2
similarity index 100%
rename from src/pkg/regexp/testdata/re2-exhaustive.txt.bz2
rename to src/regexp/testdata/re2-exhaustive.txt.bz2
diff --git a/src/pkg/regexp/testdata/re2-search.txt b/src/regexp/testdata/re2-search.txt
similarity index 100%
rename from src/pkg/regexp/testdata/re2-search.txt
rename to src/regexp/testdata/re2-search.txt
diff --git a/src/pkg/regexp/testdata/repetition.dat b/src/regexp/testdata/repetition.dat
similarity index 100%
rename from src/pkg/regexp/testdata/repetition.dat
rename to src/regexp/testdata/repetition.dat
diff --git a/src/pkg/regexp/testdata/testregex.c b/src/regexp/testdata/testregex.c
similarity index 100%
rename from src/pkg/regexp/testdata/testregex.c
rename to src/regexp/testdata/testregex.c
diff --git a/src/run.bash b/src/run.bash
index 8590ea8..5f20451 100755
--- a/src/run.bash
+++ b/src/run.bash
@@ -52,7 +52,7 @@ timeout_scale=1
 [ "$GOARCH" == "arm" ] && timeout_scale=3
 
 echo '# Testing packages.'
-time go test std -short -timeout=$(expr 120 \* $timeout_scale)s
+time go test std -short -timeout=$(expr 120 \* $timeout_scale)s -gcflags "$GO_GCFLAGS"
 echo
 
 # We set GOMAXPROCS=2 in addition to -cpu=1,2,4 in order to test runtime bootstrap code,
@@ -64,17 +64,6 @@ echo
 echo '# sync -cpu=10'
 go test sync -short -timeout=$(expr 120 \* $timeout_scale)s -cpu=10
 
-# Race detector only supported on Linux and OS X,
-# and only on amd64, and only when cgo is enabled.
-case "$GOHOSTOS-$GOOS-$GOARCH-$CGO_ENABLED" in
-linux-linux-amd64-1 | darwin-darwin-amd64-1)
-	echo
-	echo '# Testing race detector.'
-	go test -race -i runtime/race flag
-	go test -race -run=Output runtime/race
-	go test -race -short flag
-esac
-
 xcd() {
 	echo
 	echo '#' $1
@@ -99,6 +88,13 @@ xcd() {
 # Strictly speaking, the test may be unnecessary on the final command of
 # the subshell, but it aids later editing and may avoid future bash bugs.
 
+if [ "$GOOS" == "android" ]; then
+	# Disable cgo tests on android.
+	# They are not designed to run off the host.
+	# golang.org/issue/8345
+	CGO_ENABLED=0
+fi
+
 [ "$CGO_ENABLED" != 1 ] ||
 [ "$GOHOSTOS" == windows ] ||
 (xcd ../misc/cgo/stdio
@@ -113,6 +109,7 @@ go run $GOROOT/test/run.go - . || exit 1
 [ "$CGO_ENABLED" != 1 ] ||
 (xcd ../misc/cgo/test
 # cgo tests inspect the traceback for runtime functions
+extlink=0
 export GOTRACEBACK=2
 go test -ldflags '-linkmode=auto' || exit 1
 # linkmode=internal fails on dragonfly since errno is a TLS relocation.
@@ -121,19 +118,24 @@ case "$GOHOSTOS-$GOARCH" in
 openbsd-386 | openbsd-amd64)
 	# test linkmode=external, but __thread not supported, so skip testtls.
 	go test -ldflags '-linkmode=external' || exit 1
+	extlink=1
 	;;
 darwin-386 | darwin-amd64)
 	# linkmode=external fails on OS X 10.6 and earlier == Darwin
 	# 10.8 and earlier.
 	case $(uname -r) in
 	[0-9].* | 10.*) ;;
-	*) go test -ldflags '-linkmode=external'  || exit 1;;
+	*)
+		go test -ldflags '-linkmode=external'  || exit 1
+		extlink=1
+		;;
 	esac
 	;;
-dragonfly-386 | dragonfly-amd64 | freebsd-386 | freebsd-amd64 | freebsd-arm | linux-386 | linux-amd64 | linux-arm | netbsd-386 | netbsd-amd64)
+android-arm | dragonfly-386 | dragonfly-amd64 | freebsd-386 | freebsd-amd64 | freebsd-arm | linux-386 | linux-amd64 | linux-arm | netbsd-386 | netbsd-amd64)
 	go test -ldflags '-linkmode=external' || exit 1
 	go test -ldflags '-linkmode=auto' ../testtls || exit 1
 	go test -ldflags '-linkmode=external' ../testtls || exit 1
+	extlink=1
 	
 	case "$GOHOSTOS-$GOARCH" in
 	netbsd-386 | netbsd-amd64) ;; # no static linking
@@ -157,11 +159,36 @@ dragonfly-386 | dragonfly-amd64 | freebsd-386 | freebsd-amd64 | freebsd-arm | li
 esac
 ) || exit $?
 
-# This tests cgo -godefs. That mode is not supported,
+# Race detector only supported on Linux, FreeBSD and OS X,
+# and only on amd64, and only when cgo is enabled.
+# Delayed until here so we know whether to try external linking.
+case "$GOHOSTOS-$GOOS-$GOARCH-$CGO_ENABLED" in
+linux-linux-amd64-1 | freebsd-freebsd-amd64-1 | darwin-darwin-amd64-1)
+	echo
+	echo '# Testing race detector.'
+	go test -race -i runtime/race flag os/exec
+	go test -race -run=Output runtime/race
+	go test -race -short flag os/exec
+	
+	# Test with external linking; see issue 9133.
+	if [ "$extlink" = 1 ]; then
+		go test -race -short -ldflags=-linkmode=external flag os/exec
+	fi
+esac
+
+# This tests cgo -cdefs. That mode is not supported,
 # so it's okay if it doesn't work on some systems.
 # In particular, it works badly with clang on OS X.
+# It doesn't work at all now that we disallow C code
+# outside runtime. Once runtime has no C code it won't
+# even be necessary.
+# [ "$CGO_ENABLED" != 1 ] || [ "$GOOS" == darwin ] ||
+# (xcd ../misc/cgo/testcdefs
+# ./test.bash || exit 1
+# ) || exit $?
+
 [ "$CGO_ENABLED" != 1 ] || [ "$GOOS" == darwin ] ||
-(xcd ../misc/cgo/testcdefs
+(xcd ../misc/cgo/testgodefs
 ./test.bash || exit 1
 ) || exit $?
 
@@ -184,16 +211,19 @@ go run main.go || exit 1
 ) || exit $?
 
 [ "$GOOS" == nacl ] ||
+[ "$GOOS" == android ] ||
 (xcd ../doc/progs
 time ./run || exit 1
 ) || exit $?
 
+[ "$GOOS" == android ] ||
 [ "$GOOS" == nacl ] ||
 [ "$GOARCH" == arm ] ||  # uses network, fails under QEMU
 (xcd ../doc/articles/wiki
 ./test.bash || exit 1
 ) || exit $?
 
+[ "$GOOS" == android ] ||
 [ "$GOOS" == nacl ] ||
 (xcd ../doc/codewalk
 time ./run || exit 1
@@ -205,6 +235,7 @@ time ./run || exit 1
 time ./timing.sh -test || exit 1
 ) || exit $?
 
+[ "$GOOS" == android ] || # TODO(crawshaw): get this working
 [ "$GOOS" == openbsd ] || # golang.org/issue/5057
 (
 echo
@@ -212,6 +243,7 @@ echo '#' ../test/bench/go1
 go test ../test/bench/go1 || exit 1
 ) || exit $?
 
+[ "$GOOS" == android ] ||
 (xcd ../test
 unset GOMAXPROCS
 GOOS=$GOHOSTOS GOARCH=$GOHOSTARCH go build -o runtest run.go || exit 1
@@ -219,6 +251,7 @@ time ./runtest || exit 1
 rm -f runtest
 ) || exit $?
 
+[ "$GOOS" == android ] ||
 [ "$GOOS" == nacl ] ||
 (
 echo
diff --git a/src/run.rc b/src/run.rc
index 65e2c07..b0995d8 100755
--- a/src/run.rc
+++ b/src/run.rc
@@ -54,7 +54,7 @@ go test ../test/bench/go1
 
 @{
 	xcd ../test
-	GOMAXPROCS='' time go run run.go
+	GOMAXPROCS='' time go run run.go -v
 }
 
 echo
diff --git a/src/runtime/Makefile b/src/runtime/Makefile
new file mode 100644
index 0000000..55087de
--- /dev/null
+++ b/src/runtime/Makefile
@@ -0,0 +1,5 @@
+# Copyright 2009 The Go Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file.
+
+include ../Make.dist
diff --git a/src/runtime/alg.go b/src/runtime/alg.go
new file mode 100644
index 0000000..e9ed595
--- /dev/null
+++ b/src/runtime/alg.go
@@ -0,0 +1,352 @@
+// 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 runtime
+
+import "unsafe"
+
+const (
+	c0 = uintptr((8-ptrSize)/4*2860486313 + (ptrSize-4)/4*33054211828000289)
+	c1 = uintptr((8-ptrSize)/4*3267000013 + (ptrSize-4)/4*23344194077549503)
+)
+
+// type algorithms - known to compiler
+const (
+	alg_MEM = iota
+	alg_MEM0
+	alg_MEM8
+	alg_MEM16
+	alg_MEM32
+	alg_MEM64
+	alg_MEM128
+	alg_NOEQ
+	alg_NOEQ0
+	alg_NOEQ8
+	alg_NOEQ16
+	alg_NOEQ32
+	alg_NOEQ64
+	alg_NOEQ128
+	alg_STRING
+	alg_INTER
+	alg_NILINTER
+	alg_SLICE
+	alg_FLOAT32
+	alg_FLOAT64
+	alg_CPLX64
+	alg_CPLX128
+	alg_max
+)
+
+type typeAlg struct {
+	// function for hashing objects of this type
+	// (ptr to object, size, seed) -> hash
+	hash func(unsafe.Pointer, uintptr, uintptr) uintptr
+	// function for comparing objects of this type
+	// (ptr to object A, ptr to object B, size) -> ==?
+	equal func(unsafe.Pointer, unsafe.Pointer, uintptr) bool
+}
+
+var algarray = [alg_max]typeAlg{
+	alg_MEM:      {memhash, memequal},
+	alg_MEM0:     {memhash, memequal0},
+	alg_MEM8:     {memhash, memequal8},
+	alg_MEM16:    {memhash, memequal16},
+	alg_MEM32:    {memhash, memequal32},
+	alg_MEM64:    {memhash, memequal64},
+	alg_MEM128:   {memhash, memequal128},
+	alg_NOEQ:     {nil, nil},
+	alg_NOEQ0:    {nil, nil},
+	alg_NOEQ8:    {nil, nil},
+	alg_NOEQ16:   {nil, nil},
+	alg_NOEQ32:   {nil, nil},
+	alg_NOEQ64:   {nil, nil},
+	alg_NOEQ128:  {nil, nil},
+	alg_STRING:   {strhash, strequal},
+	alg_INTER:    {interhash, interequal},
+	alg_NILINTER: {nilinterhash, nilinterequal},
+	alg_SLICE:    {nil, nil},
+	alg_FLOAT32:  {f32hash, f32equal},
+	alg_FLOAT64:  {f64hash, f64equal},
+	alg_CPLX64:   {c64hash, c64equal},
+	alg_CPLX128:  {c128hash, c128equal},
+}
+
+const nacl = GOOS == "nacl"
+
+var useAeshash bool
+
+// in asm_*.s
+func aeshash(p unsafe.Pointer, s, h uintptr) uintptr
+func aeshash32(p unsafe.Pointer, s, h uintptr) uintptr
+func aeshash64(p unsafe.Pointer, s, h uintptr) uintptr
+func aeshashstr(p unsafe.Pointer, s, h uintptr) uintptr
+
+func memhash(p unsafe.Pointer, s, h uintptr) uintptr {
+	if !nacl && useAeshash {
+		return aeshash(p, s, h)
+	}
+
+	h ^= c0
+	for s > 0 {
+		h = (h ^ uintptr(*(*byte)(p))) * c1
+		p = add(p, 1)
+		s--
+	}
+	return h
+}
+
+func strhash(a unsafe.Pointer, s, h uintptr) uintptr {
+	return memhash((*stringStruct)(a).str, uintptr(len(*(*string)(a))), h)
+}
+
+// NOTE: Because NaN != NaN, a map can contain any
+// number of (mostly useless) entries keyed with NaNs.
+// To avoid long hash chains, we assign a random number
+// as the hash value for a NaN.
+
+func f32hash(p unsafe.Pointer, s, h uintptr) uintptr {
+	f := *(*float32)(p)
+	switch {
+	case f == 0:
+		return c1 * (c0 ^ h) // +0, -0
+	case f != f:
+		return c1 * (c0 ^ h ^ uintptr(fastrand1())) // any kind of NaN
+	default:
+		return memhash(p, 4, h)
+	}
+}
+
+func f64hash(p unsafe.Pointer, s, h uintptr) uintptr {
+	f := *(*float64)(p)
+	switch {
+	case f == 0:
+		return c1 * (c0 ^ h) // +0, -0
+	case f != f:
+		return c1 * (c0 ^ h ^ uintptr(fastrand1())) // any kind of NaN
+	default:
+		return memhash(p, 8, h)
+	}
+}
+
+func c64hash(p unsafe.Pointer, s, h uintptr) uintptr {
+	x := (*[2]float32)(p)
+	return f32hash(unsafe.Pointer(&x[1]), 4, f32hash(unsafe.Pointer(&x[0]), 4, h))
+}
+
+func c128hash(p unsafe.Pointer, s, h uintptr) uintptr {
+	x := (*[2]float64)(p)
+	return f64hash(unsafe.Pointer(&x[1]), 8, f64hash(unsafe.Pointer(&x[0]), 8, h))
+}
+
+func interhash(p unsafe.Pointer, s, h uintptr) uintptr {
+	a := (*iface)(p)
+	tab := a.tab
+	if tab == nil {
+		return h
+	}
+	t := tab._type
+	fn := goalg(t.alg).hash
+	if fn == nil {
+		panic(errorString("hash of unhashable type " + *t._string))
+	}
+	if isDirectIface(t) {
+		return c1 * fn(unsafe.Pointer(&a.data), uintptr(t.size), h^c0)
+	} else {
+		return c1 * fn(a.data, uintptr(t.size), h^c0)
+	}
+}
+
+func nilinterhash(p unsafe.Pointer, s, h uintptr) uintptr {
+	a := (*eface)(p)
+	t := a._type
+	if t == nil {
+		return h
+	}
+	fn := goalg(t.alg).hash
+	if fn == nil {
+		panic(errorString("hash of unhashable type " + *t._string))
+	}
+	if isDirectIface(t) {
+		return c1 * fn(unsafe.Pointer(&a.data), uintptr(t.size), h^c0)
+	} else {
+		return c1 * fn(a.data, uintptr(t.size), h^c0)
+	}
+}
+
+func memequal(p, q unsafe.Pointer, size uintptr) bool {
+	if p == q {
+		return true
+	}
+	return memeq(p, q, size)
+}
+
+func memequal0(p, q unsafe.Pointer, size uintptr) bool {
+	return true
+}
+func memequal8(p, q unsafe.Pointer, size uintptr) bool {
+	return *(*int8)(p) == *(*int8)(q)
+}
+func memequal16(p, q unsafe.Pointer, size uintptr) bool {
+	return *(*int16)(p) == *(*int16)(q)
+}
+func memequal32(p, q unsafe.Pointer, size uintptr) bool {
+	return *(*int32)(p) == *(*int32)(q)
+}
+func memequal64(p, q unsafe.Pointer, size uintptr) bool {
+	return *(*int64)(p) == *(*int64)(q)
+}
+func memequal128(p, q unsafe.Pointer, size uintptr) bool {
+	return *(*[2]int64)(p) == *(*[2]int64)(q)
+}
+func f32equal(p, q unsafe.Pointer, size uintptr) bool {
+	return *(*float32)(p) == *(*float32)(q)
+}
+func f64equal(p, q unsafe.Pointer, size uintptr) bool {
+	return *(*float64)(p) == *(*float64)(q)
+}
+func c64equal(p, q unsafe.Pointer, size uintptr) bool {
+	return *(*complex64)(p) == *(*complex64)(q)
+}
+func c128equal(p, q unsafe.Pointer, size uintptr) bool {
+	return *(*complex128)(p) == *(*complex128)(q)
+}
+func strequal(p, q unsafe.Pointer, size uintptr) bool {
+	return *(*string)(p) == *(*string)(q)
+}
+func interequal(p, q unsafe.Pointer, size uintptr) bool {
+	return ifaceeq(*(*interface {
+		f()
+	})(p), *(*interface {
+		f()
+	})(q))
+}
+func nilinterequal(p, q unsafe.Pointer, size uintptr) bool {
+	return efaceeq(*(*interface{})(p), *(*interface{})(q))
+}
+func efaceeq(p, q interface{}) bool {
+	x := (*eface)(unsafe.Pointer(&p))
+	y := (*eface)(unsafe.Pointer(&q))
+	t := x._type
+	if t != y._type {
+		return false
+	}
+	if t == nil {
+		return true
+	}
+	eq := goalg(t.alg).equal
+	if eq == nil {
+		panic(errorString("comparing uncomparable type " + *t._string))
+	}
+	if isDirectIface(t) {
+		return eq(noescape(unsafe.Pointer(&x.data)), noescape(unsafe.Pointer(&y.data)), uintptr(t.size))
+	}
+	return eq(x.data, y.data, uintptr(t.size))
+}
+func ifaceeq(p, q interface {
+	f()
+}) bool {
+	x := (*iface)(unsafe.Pointer(&p))
+	y := (*iface)(unsafe.Pointer(&q))
+	xtab := x.tab
+	if xtab != y.tab {
+		return false
+	}
+	if xtab == nil {
+		return true
+	}
+	t := xtab._type
+	eq := goalg(t.alg).equal
+	if eq == nil {
+		panic(errorString("comparing uncomparable type " + *t._string))
+	}
+	if isDirectIface(t) {
+		return eq(noescape(unsafe.Pointer(&x.data)), noescape(unsafe.Pointer(&y.data)), uintptr(t.size))
+	}
+	return eq(x.data, y.data, uintptr(t.size))
+}
+
+// Testing adapters for hash quality tests (see hash_test.go)
+func haveGoodHash() bool {
+	return useAeshash
+}
+
+func stringHash(s string, seed uintptr) uintptr {
+	return algarray[alg_STRING].hash(noescape(unsafe.Pointer(&s)), unsafe.Sizeof(s), seed)
+}
+
+func bytesHash(b []byte, seed uintptr) uintptr {
+	s := (*sliceStruct)(unsafe.Pointer(&b))
+	return algarray[alg_MEM].hash(s.array, uintptr(s.len), seed)
+}
+
+func int32Hash(i uint32, seed uintptr) uintptr {
+	return algarray[alg_MEM32].hash(noescape(unsafe.Pointer(&i)), 4, seed)
+}
+
+func int64Hash(i uint64, seed uintptr) uintptr {
+	return algarray[alg_MEM64].hash(noescape(unsafe.Pointer(&i)), 8, seed)
+}
+
+func efaceHash(i interface{}, seed uintptr) uintptr {
+	return algarray[alg_NILINTER].hash(noescape(unsafe.Pointer(&i)), unsafe.Sizeof(i), seed)
+}
+
+func ifaceHash(i interface {
+	F()
+}, seed uintptr) uintptr {
+	return algarray[alg_INTER].hash(noescape(unsafe.Pointer(&i)), unsafe.Sizeof(i), seed)
+}
+
+// Testing adapter for memclr
+func memclrBytes(b []byte) {
+	s := (*sliceStruct)(unsafe.Pointer(&b))
+	memclr(s.array, uintptr(s.len))
+}
+
+// TODO(dvyukov): remove when Type is converted to Go and contains *typeAlg.
+func goalg(a unsafe.Pointer) *typeAlg {
+	return (*typeAlg)(a)
+}
+
+// used in asm_{386,amd64}.s
+const hashRandomBytes = 32
+
+var aeskeysched [hashRandomBytes]byte
+
+//go:noescape
+func get_random_data(rnd *unsafe.Pointer, n *int32)
+
+func init() {
+	if theGoos == "nacl" {
+		return
+	}
+
+	// Install aes hash algorithm if we have the instructions we need
+	if (cpuid_ecx&(1<<25)) != 0 && // aes (aesenc)
+		(cpuid_ecx&(1<<9)) != 0 && // sse3 (pshufb)
+		(cpuid_ecx&(1<<19)) != 0 { // sse4.1 (pinsr{d,q})
+		useAeshash = true
+		algarray[alg_MEM].hash = aeshash
+		algarray[alg_MEM8].hash = aeshash
+		algarray[alg_MEM16].hash = aeshash
+		algarray[alg_MEM32].hash = aeshash32
+		algarray[alg_MEM64].hash = aeshash64
+		algarray[alg_MEM128].hash = aeshash
+		algarray[alg_STRING].hash = aeshashstr
+		// Initialize with random data so hash collisions will be hard to engineer.
+		var rnd unsafe.Pointer
+		var n int32
+		get_random_data(&rnd, &n)
+		if n > hashRandomBytes {
+			n = hashRandomBytes
+		}
+		memmove(unsafe.Pointer(&aeskeysched[0]), rnd, uintptr(n))
+		if n < hashRandomBytes {
+			// Not very random, but better than nothing.
+			for t := nanotime(); n < hashRandomBytes; n++ {
+				aeskeysched[n] = byte(t >> uint(8*(n%8)))
+			}
+		}
+	}
+}
diff --git a/src/pkg/runtime/append_test.go b/src/runtime/append_test.go
similarity index 100%
rename from src/pkg/runtime/append_test.go
rename to src/runtime/append_test.go
diff --git a/src/runtime/arch_386.go b/src/runtime/arch_386.go
new file mode 100644
index 0000000..79d38c7
--- /dev/null
+++ b/src/runtime/arch_386.go
@@ -0,0 +1,8 @@
+// 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 runtime
+
+type uintreg uint32
+type intptr int32 // TODO(rsc): remove
diff --git a/src/runtime/arch_386.h b/src/runtime/arch_386.h
new file mode 100644
index 0000000..75a5ba7
--- /dev/null
+++ b/src/runtime/arch_386.h
@@ -0,0 +1,17 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+enum {
+	thechar = '8',
+	BigEndian = 0,
+	CacheLineSize = 64,
+	RuntimeGogoBytes = 64,
+#ifdef GOOS_nacl
+	PhysPageSize = 65536,
+#else
+	PhysPageSize = 4096,
+#endif
+	PCQuantum = 1,
+	Int64Align = 4
+};
diff --git a/src/runtime/arch_amd64.go b/src/runtime/arch_amd64.go
new file mode 100644
index 0000000..270cd7b
--- /dev/null
+++ b/src/runtime/arch_amd64.go
@@ -0,0 +1,8 @@
+// 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 runtime
+
+type uintreg uint64
+type intptr int64 // TODO(rsc): remove
diff --git a/src/runtime/arch_amd64.h b/src/runtime/arch_amd64.h
new file mode 100644
index 0000000..d7b81ee
--- /dev/null
+++ b/src/runtime/arch_amd64.h
@@ -0,0 +1,25 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+enum {
+	thechar = '6',
+	BigEndian = 0,
+	CacheLineSize = 64,
+#ifdef GOOS_solaris
+	RuntimeGogoBytes = 80,
+#else
+#ifdef GOOS_windows
+	RuntimeGogoBytes = 80,
+#else
+#ifdef GOOS_plan9
+	RuntimeGogoBytes = 80,
+#else
+	RuntimeGogoBytes = 64,
+#endif	// Plan 9
+#endif	// Windows
+#endif	// Solaris
+	PhysPageSize = 4096,
+	PCQuantum = 1,
+	Int64Align = 8
+};
diff --git a/src/runtime/arch_amd64p32.go b/src/runtime/arch_amd64p32.go
new file mode 100644
index 0000000..5c636ae
--- /dev/null
+++ b/src/runtime/arch_amd64p32.go
@@ -0,0 +1,8 @@
+// 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 runtime
+
+type uintreg uint64
+type intptr int32 // TODO(rsc): remove
diff --git a/src/runtime/arch_amd64p32.h b/src/runtime/arch_amd64p32.h
new file mode 100644
index 0000000..d3e8649
--- /dev/null
+++ b/src/runtime/arch_amd64p32.h
@@ -0,0 +1,17 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+enum {
+	thechar = '6',
+	BigEndian = 0,
+	CacheLineSize = 64,
+	RuntimeGogoBytes = 64,
+#ifdef GOOS_nacl
+	PhysPageSize = 65536,
+#else
+	PhysPageSize = 4096,
+#endif
+	PCQuantum = 1,
+	Int64Align = 8
+};
diff --git a/src/runtime/arch_arm.go b/src/runtime/arch_arm.go
new file mode 100644
index 0000000..79d38c7
--- /dev/null
+++ b/src/runtime/arch_arm.go
@@ -0,0 +1,8 @@
+// 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 runtime
+
+type uintreg uint32
+type intptr int32 // TODO(rsc): remove
diff --git a/src/runtime/arch_arm.h b/src/runtime/arch_arm.h
new file mode 100644
index 0000000..637a334
--- /dev/null
+++ b/src/runtime/arch_arm.h
@@ -0,0 +1,17 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+enum {
+	thechar = '5',
+	BigEndian = 0,
+	CacheLineSize = 32,
+	RuntimeGogoBytes = 60,
+#ifdef GOOS_nacl
+	PhysPageSize = 65536,
+#else
+	PhysPageSize = 4096,
+#endif
+	PCQuantum = 4,
+	Int64Align = 4
+};
diff --git a/src/runtime/asm.s b/src/runtime/asm.s
new file mode 100644
index 0000000..e6d782f
--- /dev/null
+++ b/src/runtime/asm.s
@@ -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.
+
+#include "textflag.h"
+
+// funcdata for functions with no local variables in frame.
+// Define two zero-length bitmaps, because the same index is used
+// for the local variables as for the argument frame, and assembly
+// frames have two argument bitmaps, one without results and one with results.
+DATA runtime·no_pointers_stackmap+0x00(SB)/4, $2
+DATA runtime·no_pointers_stackmap+0x04(SB)/4, $0
+GLOBL runtime·no_pointers_stackmap(SB),RODATA, $8
+
diff --git a/src/runtime/asm_386.s b/src/runtime/asm_386.s
new file mode 100644
index 0000000..b4b81d7
--- /dev/null
+++ b/src/runtime/asm_386.s
@@ -0,0 +1,2292 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "zasm_GOOS_GOARCH.h"
+#include "funcdata.h"
+#include "textflag.h"
+
+TEXT runtime·rt0_go(SB),NOSPLIT,$0
+	// copy arguments forward on an even stack
+	MOVL	argc+0(FP), AX
+	MOVL	argv+4(FP), BX
+	SUBL	$128, SP		// plenty of scratch
+	ANDL	$~15, SP
+	MOVL	AX, 120(SP)		// save argc, argv away
+	MOVL	BX, 124(SP)
+
+	// set default stack bounds.
+	// _cgo_init may update stackguard.
+	MOVL	$runtime·g0(SB), BP
+	LEAL	(-64*1024+104)(SP), BX
+	MOVL	BX, g_stackguard0(BP)
+	MOVL	BX, g_stackguard1(BP)
+	MOVL	BX, (g_stack+stack_lo)(BP)
+	MOVL	SP, (g_stack+stack_hi)(BP)
+	
+	// find out information about the processor we're on
+	MOVL	$0, AX
+	CPUID
+	CMPL	AX, $0
+	JE	nocpuinfo
+	MOVL	$1, AX
+	CPUID
+	MOVL	CX, runtime·cpuid_ecx(SB)
+	MOVL	DX, runtime·cpuid_edx(SB)
+nocpuinfo:	
+
+	// if there is an _cgo_init, call it to let it
+	// initialize and to set up GS.  if not,
+	// we set up GS ourselves.
+	MOVL	_cgo_init(SB), AX
+	TESTL	AX, AX
+	JZ	needtls
+	MOVL	$setg_gcc<>(SB), BX
+	MOVL	BX, 4(SP)
+	MOVL	BP, 0(SP)
+	CALL	AX
+
+	// update stackguard after _cgo_init
+	MOVL	$runtime·g0(SB), CX
+	MOVL	(g_stack+stack_lo)(CX), AX
+	ADDL	$const_StackGuard, AX
+	MOVL	AX, g_stackguard0(CX)
+	MOVL	AX, g_stackguard1(CX)
+
+	// skip runtime·ldt0setup(SB) and tls test after _cgo_init for non-windows
+	CMPL runtime·iswindows(SB), $0
+	JEQ ok
+needtls:
+	// skip runtime·ldt0setup(SB) and tls test on Plan 9 in all cases
+	CMPL	runtime·isplan9(SB), $1
+	JEQ	ok
+
+	// set up %gs
+	CALL	runtime·ldt0setup(SB)
+
+	// store through it, to make sure it works
+	get_tls(BX)
+	MOVL	$0x123, g(BX)
+	MOVL	runtime·tls0(SB), AX
+	CMPL	AX, $0x123
+	JEQ	ok
+	MOVL	AX, 0	// abort
+ok:
+	// set up m and g "registers"
+	get_tls(BX)
+	LEAL	runtime·g0(SB), CX
+	MOVL	CX, g(BX)
+	LEAL	runtime·m0(SB), AX
+
+	// save m->g0 = g0
+	MOVL	CX, m_g0(AX)
+	// save g0->m = m0
+	MOVL	AX, g_m(CX)
+
+	CALL	runtime·emptyfunc(SB)	// fault if stack check is wrong
+
+	// convention is D is always cleared
+	CLD
+
+	CALL	runtime·check(SB)
+
+	// saved argc, argv
+	MOVL	120(SP), AX
+	MOVL	AX, 0(SP)
+	MOVL	124(SP), AX
+	MOVL	AX, 4(SP)
+	CALL	runtime·args(SB)
+	CALL	runtime·osinit(SB)
+	CALL	runtime·schedinit(SB)
+
+	// create a new goroutine to start program
+	PUSHL	$runtime·main·f(SB)	// entry
+	PUSHL	$0	// arg size
+	CALL	runtime·newproc(SB)
+	POPL	AX
+	POPL	AX
+
+	// start this M
+	CALL	runtime·mstart(SB)
+
+	INT $3
+	RET
+
+DATA	runtime·main·f+0(SB)/4,$runtime·main(SB)
+GLOBL	runtime·main·f(SB),RODATA,$4
+
+TEXT runtime·breakpoint(SB),NOSPLIT,$0-0
+	INT $3
+	RET
+
+TEXT runtime·asminit(SB),NOSPLIT,$0-0
+	// Linux and MinGW start the FPU in extended double precision.
+	// Other operating systems use double precision.
+	// Change to double precision to match them,
+	// and to match other hardware that only has double.
+	PUSHL $0x27F
+	FLDCW	0(SP)
+	POPL AX
+	RET
+
+/*
+ *  go-routine
+ */
+
+// void gosave(Gobuf*)
+// save state in Gobuf; setjmp
+TEXT runtime·gosave(SB), NOSPLIT, $0-4
+	MOVL	buf+0(FP), AX		// gobuf
+	LEAL	buf+0(FP), BX		// caller's SP
+	MOVL	BX, gobuf_sp(AX)
+	MOVL	0(SP), BX		// caller's PC
+	MOVL	BX, gobuf_pc(AX)
+	MOVL	$0, gobuf_ret(AX)
+	MOVL	$0, gobuf_ctxt(AX)
+	get_tls(CX)
+	MOVL	g(CX), BX
+	MOVL	BX, gobuf_g(AX)
+	RET
+
+// void gogo(Gobuf*)
+// restore state from Gobuf; longjmp
+TEXT runtime·gogo(SB), NOSPLIT, $0-4
+	MOVL	buf+0(FP), BX		// gobuf
+	MOVL	gobuf_g(BX), DX
+	MOVL	0(DX), CX		// make sure g != nil
+	get_tls(CX)
+	MOVL	DX, g(CX)
+	MOVL	gobuf_sp(BX), SP	// restore SP
+	MOVL	gobuf_ret(BX), AX
+	MOVL	gobuf_ctxt(BX), DX
+	MOVL	$0, gobuf_sp(BX)	// clear to help garbage collector
+	MOVL	$0, gobuf_ret(BX)
+	MOVL	$0, gobuf_ctxt(BX)
+	MOVL	gobuf_pc(BX), BX
+	JMP	BX
+
+// func mcall(fn func(*g))
+// Switch to m->g0's stack, call fn(g).
+// Fn must never return.  It should gogo(&g->sched)
+// to keep running g.
+TEXT runtime·mcall(SB), NOSPLIT, $0-4
+	MOVL	fn+0(FP), DI
+	
+	get_tls(CX)
+	MOVL	g(CX), AX	// save state in g->sched
+	MOVL	0(SP), BX	// caller's PC
+	MOVL	BX, (g_sched+gobuf_pc)(AX)
+	LEAL	fn+0(FP), BX	// caller's SP
+	MOVL	BX, (g_sched+gobuf_sp)(AX)
+	MOVL	AX, (g_sched+gobuf_g)(AX)
+
+	// switch to m->g0 & its stack, call fn
+	MOVL	g(CX), BX
+	MOVL	g_m(BX), BX
+	MOVL	m_g0(BX), SI
+	CMPL	SI, AX	// if g == m->g0 call badmcall
+	JNE	3(PC)
+	MOVL	$runtime·badmcall(SB), AX
+	JMP	AX
+	MOVL	SI, g(CX)	// g = m->g0
+	MOVL	(g_sched+gobuf_sp)(SI), SP	// sp = m->g0->sched.sp
+	PUSHL	AX
+	MOVL	DI, DX
+	MOVL	0(DI), DI
+	CALL	DI
+	POPL	AX
+	MOVL	$runtime·badmcall2(SB), AX
+	JMP	AX
+	RET
+
+// switchtoM is a dummy routine that onM leaves at the bottom
+// of the G stack.  We need to distinguish the routine that
+// lives at the bottom of the G stack from the one that lives
+// at the top of the M stack because the one at the top of
+// the M stack terminates the stack walk (see topofstack()).
+TEXT runtime·switchtoM(SB), NOSPLIT, $0-0
+	RET
+
+// func onM_signalok(fn func())
+TEXT runtime·onM_signalok(SB), NOSPLIT, $0-4
+	get_tls(CX)
+	MOVL	g(CX), AX	// AX = g
+	MOVL	g_m(AX), BX	// BX = m
+	MOVL	m_gsignal(BX), DX	// DX = gsignal
+	CMPL	AX, DX
+	JEQ	ongsignal
+	JMP	runtime·onM(SB)
+
+ongsignal:
+	MOVL	fn+0(FP), DI	// DI = fn
+	MOVL	DI, DX
+	MOVL	0(DI), DI
+	CALL	DI
+	RET
+
+// func onM(fn func())
+TEXT runtime·onM(SB), NOSPLIT, $0-4
+	MOVL	fn+0(FP), DI	// DI = fn
+	get_tls(CX)
+	MOVL	g(CX), AX	// AX = g
+	MOVL	g_m(AX), BX	// BX = m
+
+	MOVL	m_g0(BX), DX	// DX = g0
+	CMPL	AX, DX
+	JEQ	onm
+
+	MOVL	m_curg(BX), BP
+	CMPL	AX, BP
+	JEQ	oncurg
+	
+	// Not g0, not curg. Must be gsignal, but that's not allowed.
+	// Hide call from linker nosplit analysis.
+	MOVL	$runtime·badonm(SB), AX
+	CALL	AX
+
+oncurg:
+	// save our state in g->sched.  Pretend to
+	// be switchtoM if the G stack is scanned.
+	MOVL	$runtime·switchtoM(SB), (g_sched+gobuf_pc)(AX)
+	MOVL	SP, (g_sched+gobuf_sp)(AX)
+	MOVL	AX, (g_sched+gobuf_g)(AX)
+
+	// switch to g0
+	MOVL	DX, g(CX)
+	MOVL	(g_sched+gobuf_sp)(DX), BX
+	// make it look like mstart called onM on g0, to stop traceback
+	SUBL	$4, BX
+	MOVL	$runtime·mstart(SB), DX
+	MOVL	DX, 0(BX)
+	MOVL	BX, SP
+
+	// call target function
+	MOVL	DI, DX
+	MOVL	0(DI), DI
+	CALL	DI
+
+	// switch back to g
+	get_tls(CX)
+	MOVL	g(CX), AX
+	MOVL	g_m(AX), BX
+	MOVL	m_curg(BX), AX
+	MOVL	AX, g(CX)
+	MOVL	(g_sched+gobuf_sp)(AX), SP
+	MOVL	$0, (g_sched+gobuf_sp)(AX)
+	RET
+
+onm:
+	// already on m stack, just call directly
+	MOVL	DI, DX
+	MOVL	0(DI), DI
+	CALL	DI
+	RET
+
+/*
+ * support for morestack
+ */
+
+// Called during function prolog when more stack is needed.
+//
+// The traceback routines see morestack on a g0 as being
+// the top of a stack (for example, morestack calling newstack
+// calling the scheduler calling newm calling gc), so we must
+// record an argument size. For that purpose, it has no arguments.
+TEXT runtime·morestack(SB),NOSPLIT,$0-0
+	// Cannot grow scheduler stack (m->g0).
+	get_tls(CX)
+	MOVL	g(CX), BX
+	MOVL	g_m(BX), BX
+	MOVL	m_g0(BX), SI
+	CMPL	g(CX), SI
+	JNE	2(PC)
+	INT	$3
+
+	// Cannot grow signal stack.
+	MOVL	m_gsignal(BX), SI
+	CMPL	g(CX), SI
+	JNE	2(PC)
+	INT	$3
+
+	// Called from f.
+	// Set m->morebuf to f's caller.
+	MOVL	4(SP), DI	// f's caller's PC
+	MOVL	DI, (m_morebuf+gobuf_pc)(BX)
+	LEAL	8(SP), CX	// f's caller's SP
+	MOVL	CX, (m_morebuf+gobuf_sp)(BX)
+	get_tls(CX)
+	MOVL	g(CX), SI
+	MOVL	SI, (m_morebuf+gobuf_g)(BX)
+
+	// Set g->sched to context in f.
+	MOVL	0(SP), AX	// f's PC
+	MOVL	AX, (g_sched+gobuf_pc)(SI)
+	MOVL	SI, (g_sched+gobuf_g)(SI)
+	LEAL	4(SP), AX	// f's SP
+	MOVL	AX, (g_sched+gobuf_sp)(SI)
+	MOVL	DX, (g_sched+gobuf_ctxt)(SI)
+
+	// Call newstack on m->g0's stack.
+	MOVL	m_g0(BX), BP
+	MOVL	BP, g(CX)
+	MOVL	(g_sched+gobuf_sp)(BP), AX
+	MOVL	-4(AX), BX	// fault if CALL would, before smashing SP
+	MOVL	AX, SP
+	CALL	runtime·newstack(SB)
+	MOVL	$0, 0x1003	// crash if newstack returns
+	RET
+
+TEXT runtime·morestack_noctxt(SB),NOSPLIT,$0-0
+	MOVL	$0, DX
+	JMP runtime·morestack(SB)
+
+// reflectcall: call a function with the given argument list
+// func call(f *FuncVal, arg *byte, argsize, retoffset uint32).
+// we don't have variable-sized frames, so we use a small number
+// of constant-sized-frame functions to encode a few bits of size in the pc.
+// Caution: ugly multiline assembly macros in your future!
+
+#define DISPATCH(NAME,MAXSIZE)		\
+	CMPL	CX, $MAXSIZE;		\
+	JA	3(PC);			\
+	MOVL	$NAME(SB), AX;		\
+	JMP	AX
+// Note: can't just "JMP NAME(SB)" - bad inlining results.
+
+TEXT ·reflectcall(SB), NOSPLIT, $0-16
+	MOVL	argsize+8(FP), CX
+	DISPATCH(runtime·call16, 16)
+	DISPATCH(runtime·call32, 32)
+	DISPATCH(runtime·call64, 64)
+	DISPATCH(runtime·call128, 128)
+	DISPATCH(runtime·call256, 256)
+	DISPATCH(runtime·call512, 512)
+	DISPATCH(runtime·call1024, 1024)
+	DISPATCH(runtime·call2048, 2048)
+	DISPATCH(runtime·call4096, 4096)
+	DISPATCH(runtime·call8192, 8192)
+	DISPATCH(runtime·call16384, 16384)
+	DISPATCH(runtime·call32768, 32768)
+	DISPATCH(runtime·call65536, 65536)
+	DISPATCH(runtime·call131072, 131072)
+	DISPATCH(runtime·call262144, 262144)
+	DISPATCH(runtime·call524288, 524288)
+	DISPATCH(runtime·call1048576, 1048576)
+	DISPATCH(runtime·call2097152, 2097152)
+	DISPATCH(runtime·call4194304, 4194304)
+	DISPATCH(runtime·call8388608, 8388608)
+	DISPATCH(runtime·call16777216, 16777216)
+	DISPATCH(runtime·call33554432, 33554432)
+	DISPATCH(runtime·call67108864, 67108864)
+	DISPATCH(runtime·call134217728, 134217728)
+	DISPATCH(runtime·call268435456, 268435456)
+	DISPATCH(runtime·call536870912, 536870912)
+	DISPATCH(runtime·call1073741824, 1073741824)
+	MOVL	$runtime·badreflectcall(SB), AX
+	JMP	AX
+
+#define CALLFN(NAME,MAXSIZE)			\
+TEXT NAME(SB), WRAPPER, $MAXSIZE-16;		\
+	NO_LOCAL_POINTERS;			\
+	/* copy arguments to stack */		\
+	MOVL	argptr+4(FP), SI;		\
+	MOVL	argsize+8(FP), CX;		\
+	MOVL	SP, DI;				\
+	REP;MOVSB;				\
+	/* call function */			\
+	MOVL	f+0(FP), DX;			\
+	MOVL	(DX), AX; 			\
+	PCDATA  $PCDATA_StackMapIndex, $0;	\
+	CALL	AX;				\
+	/* copy return values back */		\
+	MOVL	argptr+4(FP), DI;		\
+	MOVL	argsize+8(FP), CX;		\
+	MOVL	retoffset+12(FP), BX;		\
+	MOVL	SP, SI;				\
+	ADDL	BX, DI;				\
+	ADDL	BX, SI;				\
+	SUBL	BX, CX;				\
+	REP;MOVSB;				\
+	RET
+
+CALLFN(·call16, 16)
+CALLFN(·call32, 32)
+CALLFN(·call64, 64)
+CALLFN(·call128, 128)
+CALLFN(·call256, 256)
+CALLFN(·call512, 512)
+CALLFN(·call1024, 1024)
+CALLFN(·call2048, 2048)
+CALLFN(·call4096, 4096)
+CALLFN(·call8192, 8192)
+CALLFN(·call16384, 16384)
+CALLFN(·call32768, 32768)
+CALLFN(·call65536, 65536)
+CALLFN(·call131072, 131072)
+CALLFN(·call262144, 262144)
+CALLFN(·call524288, 524288)
+CALLFN(·call1048576, 1048576)
+CALLFN(·call2097152, 2097152)
+CALLFN(·call4194304, 4194304)
+CALLFN(·call8388608, 8388608)
+CALLFN(·call16777216, 16777216)
+CALLFN(·call33554432, 33554432)
+CALLFN(·call67108864, 67108864)
+CALLFN(·call134217728, 134217728)
+CALLFN(·call268435456, 268435456)
+CALLFN(·call536870912, 536870912)
+CALLFN(·call1073741824, 1073741824)
+
+// bool cas(int32 *val, int32 old, int32 new)
+// Atomically:
+//	if(*val == old){
+//		*val = new;
+//		return 1;
+//	}else
+//		return 0;
+TEXT runtime·cas(SB), NOSPLIT, $0-13
+	MOVL	ptr+0(FP), BX
+	MOVL	old+4(FP), AX
+	MOVL	new+8(FP), CX
+	LOCK
+	CMPXCHGL	CX, 0(BX)
+	JZ 4(PC)
+	MOVL	$0, AX
+	MOVB	AX, ret+12(FP)
+	RET
+	MOVL	$1, AX
+	MOVB	AX, ret+12(FP)
+	RET
+
+TEXT runtime·casuintptr(SB), NOSPLIT, $0-13
+	JMP	runtime·cas(SB)
+
+TEXT runtime·atomicloaduintptr(SB), NOSPLIT, $0-8
+	JMP	runtime·atomicload(SB)
+
+TEXT runtime·atomicloaduint(SB), NOSPLIT, $0-8
+	JMP	runtime·atomicload(SB)
+
+TEXT runtime·atomicstoreuintptr(SB), NOSPLIT, $0-8
+	JMP	runtime·atomicstore(SB)
+
+// bool runtime·cas64(uint64 *val, uint64 old, uint64 new)
+// Atomically:
+//	if(*val == *old){
+//		*val = new;
+//		return 1;
+//	} else {
+//		return 0;
+//	}
+TEXT runtime·cas64(SB), NOSPLIT, $0-21
+	MOVL	ptr+0(FP), BP
+	MOVL	old_lo+4(FP), AX
+	MOVL	old_hi+8(FP), DX
+	MOVL	new_lo+12(FP), BX
+	MOVL	new_hi+16(FP), CX
+	LOCK
+	CMPXCHG8B	0(BP)
+	JNZ	cas64_fail
+	MOVL	$1, AX
+	MOVB	AX, ret+20(FP)
+	RET
+cas64_fail:
+	MOVL	$0, AX
+	MOVB	AX, ret+20(FP)
+	RET
+
+// bool casp(void **p, void *old, void *new)
+// Atomically:
+//	if(*p == old){
+//		*p = new;
+//		return 1;
+//	}else
+//		return 0;
+TEXT runtime·casp(SB), NOSPLIT, $0-13
+	MOVL	ptr+0(FP), BX
+	MOVL	old+4(FP), AX
+	MOVL	new+8(FP), CX
+	LOCK
+	CMPXCHGL	CX, 0(BX)
+	JZ 4(PC)
+	MOVL	$0, AX
+	MOVB	AX, ret+12(FP)
+	RET
+	MOVL	$1, AX
+	MOVB	AX, ret+12(FP)
+	RET
+
+// uint32 xadd(uint32 volatile *val, int32 delta)
+// Atomically:
+//	*val += delta;
+//	return *val;
+TEXT runtime·xadd(SB), NOSPLIT, $0-12
+	MOVL	ptr+0(FP), BX
+	MOVL	delta+4(FP), AX
+	MOVL	AX, CX
+	LOCK
+	XADDL	AX, 0(BX)
+	ADDL	CX, AX
+	MOVL	AX, ret+8(FP)
+	RET
+
+TEXT runtime·xchg(SB), NOSPLIT, $0-12
+	MOVL	ptr+0(FP), BX
+	MOVL	new+4(FP), AX
+	XCHGL	AX, 0(BX)
+	MOVL	AX, ret+8(FP)
+	RET
+
+TEXT runtime·xchgp(SB), NOSPLIT, $0-12
+	MOVL	ptr+0(FP), BX
+	MOVL	new+4(FP), AX
+	XCHGL	AX, 0(BX)
+	MOVL	AX, ret+8(FP)
+	RET
+
+TEXT runtime·xchguintptr(SB), NOSPLIT, $0-12
+	JMP	runtime·xchg(SB)
+
+TEXT runtime·procyield(SB),NOSPLIT,$0-0
+	MOVL	cycles+0(FP), AX
+again:
+	PAUSE
+	SUBL	$1, AX
+	JNZ	again
+	RET
+
+TEXT runtime·atomicstorep(SB), NOSPLIT, $0-8
+	MOVL	ptr+0(FP), BX
+	MOVL	val+4(FP), AX
+	XCHGL	AX, 0(BX)
+	RET
+
+TEXT runtime·atomicstore(SB), NOSPLIT, $0-8
+	MOVL	ptr+0(FP), BX
+	MOVL	val+4(FP), AX
+	XCHGL	AX, 0(BX)
+	RET
+
+// uint64 atomicload64(uint64 volatile* addr);
+TEXT runtime·atomicload64(SB), NOSPLIT, $0-12
+	MOVL	ptr+0(FP), AX
+	LEAL	ret_lo+4(FP), BX
+	// MOVQ (%EAX), %MM0
+	BYTE $0x0f; BYTE $0x6f; BYTE $0x00
+	// MOVQ %MM0, 0(%EBX)
+	BYTE $0x0f; BYTE $0x7f; BYTE $0x03
+	// EMMS
+	BYTE $0x0F; BYTE $0x77
+	RET
+
+// void runtime·atomicstore64(uint64 volatile* addr, uint64 v);
+TEXT runtime·atomicstore64(SB), NOSPLIT, $0-12
+	MOVL	ptr+0(FP), AX
+	// MOVQ and EMMS were introduced on the Pentium MMX.
+	// MOVQ 0x8(%ESP), %MM0
+	BYTE $0x0f; BYTE $0x6f; BYTE $0x44; BYTE $0x24; BYTE $0x08
+	// MOVQ %MM0, (%EAX)
+	BYTE $0x0f; BYTE $0x7f; BYTE $0x00 
+	// EMMS
+	BYTE $0x0F; BYTE $0x77
+	// This is essentially a no-op, but it provides required memory fencing.
+	// It can be replaced with MFENCE, but MFENCE was introduced only on the Pentium4 (SSE2).
+	MOVL	$0, AX
+	LOCK
+	XADDL	AX, (SP)
+	RET
+
+// void	runtime·atomicor8(byte volatile*, byte);
+TEXT runtime·atomicor8(SB), NOSPLIT, $0-5
+	MOVL	ptr+0(FP), AX
+	MOVB	val+4(FP), BX
+	LOCK
+	ORB	BX, (AX)
+	RET
+
+// void jmpdefer(fn, sp);
+// called from deferreturn.
+// 1. pop the caller
+// 2. sub 5 bytes from the callers return
+// 3. jmp to the argument
+TEXT runtime·jmpdefer(SB), NOSPLIT, $0-8
+	MOVL	fv+0(FP), DX	// fn
+	MOVL	argp+4(FP), BX	// caller sp
+	LEAL	-4(BX), SP	// caller sp after CALL
+	SUBL	$5, (SP)	// return to CALL again
+	MOVL	0(DX), BX
+	JMP	BX	// but first run the deferred function
+
+// Save state of caller into g->sched.
+TEXT gosave<>(SB),NOSPLIT,$0
+	PUSHL	AX
+	PUSHL	BX
+	get_tls(BX)
+	MOVL	g(BX), BX
+	LEAL	arg+0(FP), AX
+	MOVL	AX, (g_sched+gobuf_sp)(BX)
+	MOVL	-4(AX), AX
+	MOVL	AX, (g_sched+gobuf_pc)(BX)
+	MOVL	$0, (g_sched+gobuf_ret)(BX)
+	MOVL	$0, (g_sched+gobuf_ctxt)(BX)
+	POPL	BX
+	POPL	AX
+	RET
+
+// asmcgocall(void(*fn)(void*), void *arg)
+// Call fn(arg) on the scheduler stack,
+// aligned appropriately for the gcc ABI.
+// See cgocall.c for more details.
+TEXT ·asmcgocall(SB),NOSPLIT,$0-8
+	MOVL	fn+0(FP), AX
+	MOVL	arg+4(FP), BX
+	CALL	asmcgocall<>(SB)
+	RET
+
+TEXT ·asmcgocall_errno(SB),NOSPLIT,$0-12
+	MOVL	fn+0(FP), AX
+	MOVL	arg+4(FP), BX
+	CALL	asmcgocall<>(SB)
+	MOVL	AX, ret+8(FP)
+	RET
+
+TEXT asmcgocall<>(SB),NOSPLIT,$0-0
+	// fn in AX, arg in BX
+	MOVL	SP, DX
+
+	// Figure out if we need to switch to m->g0 stack.
+	// We get called to create new OS threads too, and those
+	// come in on the m->g0 stack already.
+	get_tls(CX)
+	MOVL	g(CX), BP
+	MOVL	g_m(BP), BP
+	MOVL	m_g0(BP), SI
+	MOVL	g(CX), DI
+	CMPL	SI, DI
+	JEQ	4(PC)
+	CALL	gosave<>(SB)
+	MOVL	SI, g(CX)
+	MOVL	(g_sched+gobuf_sp)(SI), SP
+
+	// Now on a scheduling stack (a pthread-created stack).
+	SUBL	$32, SP
+	ANDL	$~15, SP	// alignment, perhaps unnecessary
+	MOVL	DI, 8(SP)	// save g
+	MOVL	(g_stack+stack_hi)(DI), DI
+	SUBL	DX, DI
+	MOVL	DI, 4(SP)	// save depth in stack (can't just save SP, as stack might be copied during a callback)
+	MOVL	BX, 0(SP)	// first argument in x86-32 ABI
+	CALL	AX
+
+	// Restore registers, g, stack pointer.
+	get_tls(CX)
+	MOVL	8(SP), DI
+	MOVL	(g_stack+stack_hi)(DI), SI
+	SUBL	4(SP), SI
+	MOVL	DI, g(CX)
+	MOVL	SI, SP
+	RET
+
+// cgocallback(void (*fn)(void*), void *frame, uintptr framesize)
+// Turn the fn into a Go func (by taking its address) and call
+// cgocallback_gofunc.
+TEXT runtime·cgocallback(SB),NOSPLIT,$12-12
+	LEAL	fn+0(FP), AX
+	MOVL	AX, 0(SP)
+	MOVL	frame+4(FP), AX
+	MOVL	AX, 4(SP)
+	MOVL	framesize+8(FP), AX
+	MOVL	AX, 8(SP)
+	MOVL	$runtime·cgocallback_gofunc(SB), AX
+	CALL	AX
+	RET
+
+// cgocallback_gofunc(FuncVal*, void *frame, uintptr framesize)
+// See cgocall.c for more details.
+TEXT ·cgocallback_gofunc(SB),NOSPLIT,$12-12
+	NO_LOCAL_POINTERS
+
+	// If g is nil, Go did not create the current thread.
+	// Call needm to obtain one for temporary use.
+	// In this case, we're running on the thread stack, so there's
+	// lots of space, but the linker doesn't know. Hide the call from
+	// the linker analysis by using an indirect call through AX.
+	get_tls(CX)
+#ifdef GOOS_windows
+	MOVL	$0, BP
+	CMPL	CX, $0
+	JEQ	2(PC) // TODO
+#endif
+	MOVL	g(CX), BP
+	CMPL	BP, $0
+	JEQ	needm
+	MOVL	g_m(BP), BP
+	MOVL	BP, DX // saved copy of oldm
+	JMP	havem
+needm:
+	MOVL	$0, 0(SP)
+	MOVL	$runtime·needm(SB), AX
+	CALL	AX
+	MOVL	0(SP), DX
+	get_tls(CX)
+	MOVL	g(CX), BP
+	MOVL	g_m(BP), BP
+
+	// Set m->sched.sp = SP, so that if a panic happens
+	// during the function we are about to execute, it will
+	// have a valid SP to run on the g0 stack.
+	// The next few lines (after the havem label)
+	// will save this SP onto the stack and then write
+	// the same SP back to m->sched.sp. That seems redundant,
+	// but if an unrecovered panic happens, unwindm will
+	// restore the g->sched.sp from the stack location
+	// and then onM will try to use it. If we don't set it here,
+	// that restored SP will be uninitialized (typically 0) and
+	// will not be usable.
+	MOVL	m_g0(BP), SI
+	MOVL	SP, (g_sched+gobuf_sp)(SI)
+
+havem:
+	// Now there's a valid m, and we're running on its m->g0.
+	// Save current m->g0->sched.sp on stack and then set it to SP.
+	// Save current sp in m->g0->sched.sp in preparation for
+	// switch back to m->curg stack.
+	// NOTE: unwindm knows that the saved g->sched.sp is at 0(SP).
+	MOVL	m_g0(BP), SI
+	MOVL	(g_sched+gobuf_sp)(SI), AX
+	MOVL	AX, 0(SP)
+	MOVL	SP, (g_sched+gobuf_sp)(SI)
+
+	// Switch to m->curg stack and call runtime.cgocallbackg.
+	// Because we are taking over the execution of m->curg
+	// but *not* resuming what had been running, we need to
+	// save that information (m->curg->sched) so we can restore it.
+	// We can restore m->curg->sched.sp easily, because calling
+	// runtime.cgocallbackg leaves SP unchanged upon return.
+	// To save m->curg->sched.pc, we push it onto the stack.
+	// This has the added benefit that it looks to the traceback
+	// routine like cgocallbackg is going to return to that
+	// PC (because the frame we allocate below has the same
+	// size as cgocallback_gofunc's frame declared above)
+	// so that the traceback will seamlessly trace back into
+	// the earlier calls.
+	//
+	// In the new goroutine, 0(SP) holds the saved oldm (DX) register.
+	// 4(SP) and 8(SP) are unused.
+	MOVL	m_curg(BP), SI
+	MOVL	SI, g(CX)
+	MOVL	(g_sched+gobuf_sp)(SI), DI // prepare stack as DI
+	MOVL	(g_sched+gobuf_pc)(SI), BP
+	MOVL	BP, -4(DI)
+	LEAL	-(4+12)(DI), SP
+	MOVL	DX, 0(SP)
+	CALL	runtime·cgocallbackg(SB)
+	MOVL	0(SP), DX
+
+	// Restore g->sched (== m->curg->sched) from saved values.
+	get_tls(CX)
+	MOVL	g(CX), SI
+	MOVL	12(SP), BP
+	MOVL	BP, (g_sched+gobuf_pc)(SI)
+	LEAL	(12+4)(SP), DI
+	MOVL	DI, (g_sched+gobuf_sp)(SI)
+
+	// Switch back to m->g0's stack and restore m->g0->sched.sp.
+	// (Unlike m->curg, the g0 goroutine never uses sched.pc,
+	// so we do not have to restore it.)
+	MOVL	g(CX), BP
+	MOVL	g_m(BP), BP
+	MOVL	m_g0(BP), SI
+	MOVL	SI, g(CX)
+	MOVL	(g_sched+gobuf_sp)(SI), SP
+	MOVL	0(SP), AX
+	MOVL	AX, (g_sched+gobuf_sp)(SI)
+	
+	// If the m on entry was nil, we called needm above to borrow an m
+	// for the duration of the call. Since the call is over, return it with dropm.
+	CMPL	DX, $0
+	JNE 3(PC)
+	MOVL	$runtime·dropm(SB), AX
+	CALL	AX
+
+	// Done!
+	RET
+
+// void setg(G*); set g. for use by needm.
+TEXT runtime·setg(SB), NOSPLIT, $0-4
+	MOVL	gg+0(FP), BX
+#ifdef GOOS_windows
+	CMPL	BX, $0
+	JNE	settls
+	MOVL	$0, 0x14(FS)
+	RET
+settls:
+	MOVL	g_m(BX), AX
+	LEAL	m_tls(AX), AX
+	MOVL	AX, 0x14(FS)
+#endif
+	get_tls(CX)
+	MOVL	BX, g(CX)
+	RET
+
+// void setg_gcc(G*); set g. for use by gcc
+TEXT setg_gcc<>(SB), NOSPLIT, $0
+	get_tls(AX)
+	MOVL	gg+0(FP), DX
+	MOVL	DX, g(AX)
+	RET
+
+// check that SP is in range [g->stack.lo, g->stack.hi)
+TEXT runtime·stackcheck(SB), NOSPLIT, $0-0
+	get_tls(CX)
+	MOVL	g(CX), AX
+	CMPL	(g_stack+stack_hi)(AX), SP
+	JHI	2(PC)
+	INT	$3
+	CMPL	SP, (g_stack+stack_lo)(AX)
+	JHI	2(PC)
+	INT	$3
+	RET
+
+TEXT runtime·getcallerpc(SB),NOSPLIT,$0-8
+	MOVL	argp+0(FP),AX		// addr of first arg
+	MOVL	-4(AX),AX		// get calling pc
+	MOVL	AX, ret+4(FP)
+	RET
+
+TEXT runtime·gogetcallerpc(SB),NOSPLIT,$0-8
+	MOVL	p+0(FP),AX		// addr of first arg
+	MOVL	-4(AX),AX		// get calling pc
+	MOVL	AX, ret+4(FP)
+	RET
+
+TEXT runtime·setcallerpc(SB),NOSPLIT,$0-8
+	MOVL	argp+0(FP),AX		// addr of first arg
+	MOVL	pc+4(FP), BX
+	MOVL	BX, -4(AX)		// set calling pc
+	RET
+
+TEXT runtime·getcallersp(SB), NOSPLIT, $0-8
+	MOVL	argp+0(FP), AX
+	MOVL	AX, ret+4(FP)
+	RET
+
+// func gogetcallersp(p unsafe.Pointer) uintptr
+TEXT runtime·gogetcallersp(SB),NOSPLIT,$0-8
+	MOVL	p+0(FP),AX		// addr of first arg
+	MOVL	AX, ret+4(FP)
+	RET
+
+// int64 runtime·cputicks(void), so really
+// void runtime·cputicks(int64 *ticks)
+TEXT runtime·cputicks(SB),NOSPLIT,$0-8
+	RDTSC
+	MOVL	AX, ret_lo+0(FP)
+	MOVL	DX, ret_hi+4(FP)
+	RET
+
+TEXT runtime·ldt0setup(SB),NOSPLIT,$16-0
+	// set up ldt 7 to point at tls0
+	// ldt 1 would be fine on Linux, but on OS X, 7 is as low as we can go.
+	// the entry number is just a hint.  setldt will set up GS with what it used.
+	MOVL	$7, 0(SP)
+	LEAL	runtime·tls0(SB), AX
+	MOVL	AX, 4(SP)
+	MOVL	$32, 8(SP)	// sizeof(tls array)
+	CALL	runtime·setldt(SB)
+	RET
+
+TEXT runtime·emptyfunc(SB),0,$0-0
+	RET
+
+TEXT runtime·abort(SB),NOSPLIT,$0-0
+	INT $0x3
+
+// hash function using AES hardware instructions
+TEXT runtime·aeshash(SB),NOSPLIT,$0-16
+	MOVL	p+0(FP), AX	// ptr to data
+	MOVL	s+4(FP), CX	// size
+	JMP	runtime·aeshashbody(SB)
+
+TEXT runtime·aeshashstr(SB),NOSPLIT,$0-16
+	MOVL	p+0(FP), AX	// ptr to string object
+	// s+4(FP) is ignored, it is always sizeof(String)
+	MOVL	4(AX), CX	// length of string
+	MOVL	(AX), AX	// string data
+	JMP	runtime·aeshashbody(SB)
+
+// AX: data
+// CX: length
+TEXT runtime·aeshashbody(SB),NOSPLIT,$0-16
+	MOVL	h+8(FP), X0	// seed to low 32 bits of xmm0
+	PINSRD	$1, CX, X0	// size to next 32 bits of xmm0
+	MOVO	runtime·aeskeysched+0(SB), X2
+	MOVO	runtime·aeskeysched+16(SB), X3
+	CMPL	CX, $16
+	JB	aessmall
+aesloop:
+	CMPL	CX, $16
+	JBE	aesloopend
+	MOVOU	(AX), X1
+	AESENC	X2, X0
+	AESENC	X1, X0
+	SUBL	$16, CX
+	ADDL	$16, AX
+	JMP	aesloop
+// 1-16 bytes remaining
+aesloopend:
+	// This load may overlap with the previous load above.
+	// We'll hash some bytes twice, but that's ok.
+	MOVOU	-16(AX)(CX*1), X1
+	JMP	partial
+// 0-15 bytes
+aessmall:
+	TESTL	CX, CX
+	JE	finalize	// 0 bytes
+
+	CMPB	AX, $0xf0
+	JA	highpartial
+
+	// 16 bytes loaded at this address won't cross
+	// a page boundary, so we can load it directly.
+	MOVOU	(AX), X1
+	ADDL	CX, CX
+	PAND	masks<>(SB)(CX*8), X1
+	JMP	partial
+highpartial:
+	// address ends in 1111xxxx.  Might be up against
+	// a page boundary, so load ending at last byte.
+	// Then shift bytes down using pshufb.
+	MOVOU	-16(AX)(CX*1), X1
+	ADDL	CX, CX
+	PSHUFB	shifts<>(SB)(CX*8), X1
+partial:
+	// incorporate partial block into hash
+	AESENC	X3, X0
+	AESENC	X1, X0
+finalize:	
+	// finalize hash
+	AESENC	X2, X0
+	AESENC	X3, X0
+	AESENC	X2, X0
+	MOVL	X0, ret+12(FP)
+	RET
+
+TEXT runtime·aeshash32(SB),NOSPLIT,$0-16
+	MOVL	p+0(FP), AX	// ptr to data
+	// s+4(FP) is ignored, it is always sizeof(int32)
+	MOVL	h+8(FP), X0	// seed
+	PINSRD	$1, (AX), X0	// data
+	AESENC	runtime·aeskeysched+0(SB), X0
+	AESENC	runtime·aeskeysched+16(SB), X0
+	AESENC	runtime·aeskeysched+0(SB), X0
+	MOVL	X0, ret+12(FP)
+	RET
+
+TEXT runtime·aeshash64(SB),NOSPLIT,$0-16
+	MOVL	p+0(FP), AX	// ptr to data
+	// s+4(FP) is ignored, it is always sizeof(int64)
+	MOVQ	(AX), X0	// data
+	PINSRD	$2, h+8(FP), X0	// seed
+	AESENC	runtime·aeskeysched+0(SB), X0
+	AESENC	runtime·aeskeysched+16(SB), X0
+	AESENC	runtime·aeskeysched+0(SB), X0
+	MOVL	X0, ret+12(FP)
+	RET
+
+// simple mask to get rid of data in the high part of the register.
+DATA masks<>+0x00(SB)/4, $0x00000000
+DATA masks<>+0x04(SB)/4, $0x00000000
+DATA masks<>+0x08(SB)/4, $0x00000000
+DATA masks<>+0x0c(SB)/4, $0x00000000
+	
+DATA masks<>+0x10(SB)/4, $0x000000ff
+DATA masks<>+0x14(SB)/4, $0x00000000
+DATA masks<>+0x18(SB)/4, $0x00000000
+DATA masks<>+0x1c(SB)/4, $0x00000000
+	
+DATA masks<>+0x20(SB)/4, $0x0000ffff
+DATA masks<>+0x24(SB)/4, $0x00000000
+DATA masks<>+0x28(SB)/4, $0x00000000
+DATA masks<>+0x2c(SB)/4, $0x00000000
+	
+DATA masks<>+0x30(SB)/4, $0x00ffffff
+DATA masks<>+0x34(SB)/4, $0x00000000
+DATA masks<>+0x38(SB)/4, $0x00000000
+DATA masks<>+0x3c(SB)/4, $0x00000000
+	
+DATA masks<>+0x40(SB)/4, $0xffffffff
+DATA masks<>+0x44(SB)/4, $0x00000000
+DATA masks<>+0x48(SB)/4, $0x00000000
+DATA masks<>+0x4c(SB)/4, $0x00000000
+	
+DATA masks<>+0x50(SB)/4, $0xffffffff
+DATA masks<>+0x54(SB)/4, $0x000000ff
+DATA masks<>+0x58(SB)/4, $0x00000000
+DATA masks<>+0x5c(SB)/4, $0x00000000
+	
+DATA masks<>+0x60(SB)/4, $0xffffffff
+DATA masks<>+0x64(SB)/4, $0x0000ffff
+DATA masks<>+0x68(SB)/4, $0x00000000
+DATA masks<>+0x6c(SB)/4, $0x00000000
+	
+DATA masks<>+0x70(SB)/4, $0xffffffff
+DATA masks<>+0x74(SB)/4, $0x00ffffff
+DATA masks<>+0x78(SB)/4, $0x00000000
+DATA masks<>+0x7c(SB)/4, $0x00000000
+	
+DATA masks<>+0x80(SB)/4, $0xffffffff
+DATA masks<>+0x84(SB)/4, $0xffffffff
+DATA masks<>+0x88(SB)/4, $0x00000000
+DATA masks<>+0x8c(SB)/4, $0x00000000
+	
+DATA masks<>+0x90(SB)/4, $0xffffffff
+DATA masks<>+0x94(SB)/4, $0xffffffff
+DATA masks<>+0x98(SB)/4, $0x000000ff
+DATA masks<>+0x9c(SB)/4, $0x00000000
+	
+DATA masks<>+0xa0(SB)/4, $0xffffffff
+DATA masks<>+0xa4(SB)/4, $0xffffffff
+DATA masks<>+0xa8(SB)/4, $0x0000ffff
+DATA masks<>+0xac(SB)/4, $0x00000000
+	
+DATA masks<>+0xb0(SB)/4, $0xffffffff
+DATA masks<>+0xb4(SB)/4, $0xffffffff
+DATA masks<>+0xb8(SB)/4, $0x00ffffff
+DATA masks<>+0xbc(SB)/4, $0x00000000
+	
+DATA masks<>+0xc0(SB)/4, $0xffffffff
+DATA masks<>+0xc4(SB)/4, $0xffffffff
+DATA masks<>+0xc8(SB)/4, $0xffffffff
+DATA masks<>+0xcc(SB)/4, $0x00000000
+	
+DATA masks<>+0xd0(SB)/4, $0xffffffff
+DATA masks<>+0xd4(SB)/4, $0xffffffff
+DATA masks<>+0xd8(SB)/4, $0xffffffff
+DATA masks<>+0xdc(SB)/4, $0x000000ff
+	
+DATA masks<>+0xe0(SB)/4, $0xffffffff
+DATA masks<>+0xe4(SB)/4, $0xffffffff
+DATA masks<>+0xe8(SB)/4, $0xffffffff
+DATA masks<>+0xec(SB)/4, $0x0000ffff
+	
+DATA masks<>+0xf0(SB)/4, $0xffffffff
+DATA masks<>+0xf4(SB)/4, $0xffffffff
+DATA masks<>+0xf8(SB)/4, $0xffffffff
+DATA masks<>+0xfc(SB)/4, $0x00ffffff
+
+GLOBL masks<>(SB),RODATA,$256
+
+// these are arguments to pshufb.  They move data down from
+// the high bytes of the register to the low bytes of the register.
+// index is how many bytes to move.
+DATA shifts<>+0x00(SB)/4, $0x00000000
+DATA shifts<>+0x04(SB)/4, $0x00000000
+DATA shifts<>+0x08(SB)/4, $0x00000000
+DATA shifts<>+0x0c(SB)/4, $0x00000000
+	
+DATA shifts<>+0x10(SB)/4, $0xffffff0f
+DATA shifts<>+0x14(SB)/4, $0xffffffff
+DATA shifts<>+0x18(SB)/4, $0xffffffff
+DATA shifts<>+0x1c(SB)/4, $0xffffffff
+	
+DATA shifts<>+0x20(SB)/4, $0xffff0f0e
+DATA shifts<>+0x24(SB)/4, $0xffffffff
+DATA shifts<>+0x28(SB)/4, $0xffffffff
+DATA shifts<>+0x2c(SB)/4, $0xffffffff
+	
+DATA shifts<>+0x30(SB)/4, $0xff0f0e0d
+DATA shifts<>+0x34(SB)/4, $0xffffffff
+DATA shifts<>+0x38(SB)/4, $0xffffffff
+DATA shifts<>+0x3c(SB)/4, $0xffffffff
+	
+DATA shifts<>+0x40(SB)/4, $0x0f0e0d0c
+DATA shifts<>+0x44(SB)/4, $0xffffffff
+DATA shifts<>+0x48(SB)/4, $0xffffffff
+DATA shifts<>+0x4c(SB)/4, $0xffffffff
+	
+DATA shifts<>+0x50(SB)/4, $0x0e0d0c0b
+DATA shifts<>+0x54(SB)/4, $0xffffff0f
+DATA shifts<>+0x58(SB)/4, $0xffffffff
+DATA shifts<>+0x5c(SB)/4, $0xffffffff
+	
+DATA shifts<>+0x60(SB)/4, $0x0d0c0b0a
+DATA shifts<>+0x64(SB)/4, $0xffff0f0e
+DATA shifts<>+0x68(SB)/4, $0xffffffff
+DATA shifts<>+0x6c(SB)/4, $0xffffffff
+	
+DATA shifts<>+0x70(SB)/4, $0x0c0b0a09
+DATA shifts<>+0x74(SB)/4, $0xff0f0e0d
+DATA shifts<>+0x78(SB)/4, $0xffffffff
+DATA shifts<>+0x7c(SB)/4, $0xffffffff
+	
+DATA shifts<>+0x80(SB)/4, $0x0b0a0908
+DATA shifts<>+0x84(SB)/4, $0x0f0e0d0c
+DATA shifts<>+0x88(SB)/4, $0xffffffff
+DATA shifts<>+0x8c(SB)/4, $0xffffffff
+	
+DATA shifts<>+0x90(SB)/4, $0x0a090807
+DATA shifts<>+0x94(SB)/4, $0x0e0d0c0b
+DATA shifts<>+0x98(SB)/4, $0xffffff0f
+DATA shifts<>+0x9c(SB)/4, $0xffffffff
+	
+DATA shifts<>+0xa0(SB)/4, $0x09080706
+DATA shifts<>+0xa4(SB)/4, $0x0d0c0b0a
+DATA shifts<>+0xa8(SB)/4, $0xffff0f0e
+DATA shifts<>+0xac(SB)/4, $0xffffffff
+	
+DATA shifts<>+0xb0(SB)/4, $0x08070605
+DATA shifts<>+0xb4(SB)/4, $0x0c0b0a09
+DATA shifts<>+0xb8(SB)/4, $0xff0f0e0d
+DATA shifts<>+0xbc(SB)/4, $0xffffffff
+	
+DATA shifts<>+0xc0(SB)/4, $0x07060504
+DATA shifts<>+0xc4(SB)/4, $0x0b0a0908
+DATA shifts<>+0xc8(SB)/4, $0x0f0e0d0c
+DATA shifts<>+0xcc(SB)/4, $0xffffffff
+	
+DATA shifts<>+0xd0(SB)/4, $0x06050403
+DATA shifts<>+0xd4(SB)/4, $0x0a090807
+DATA shifts<>+0xd8(SB)/4, $0x0e0d0c0b
+DATA shifts<>+0xdc(SB)/4, $0xffffff0f
+	
+DATA shifts<>+0xe0(SB)/4, $0x05040302
+DATA shifts<>+0xe4(SB)/4, $0x09080706
+DATA shifts<>+0xe8(SB)/4, $0x0d0c0b0a
+DATA shifts<>+0xec(SB)/4, $0xffff0f0e
+	
+DATA shifts<>+0xf0(SB)/4, $0x04030201
+DATA shifts<>+0xf4(SB)/4, $0x08070605
+DATA shifts<>+0xf8(SB)/4, $0x0c0b0a09
+DATA shifts<>+0xfc(SB)/4, $0xff0f0e0d
+
+GLOBL shifts<>(SB),RODATA,$256
+
+TEXT runtime·memeq(SB),NOSPLIT,$0-13
+	MOVL	a+0(FP), SI
+	MOVL	b+4(FP), DI
+	MOVL	size+8(FP), BX
+	CALL	runtime·memeqbody(SB)
+	MOVB	AX, ret+12(FP)
+	RET
+
+// eqstring tests whether two strings are equal.
+// See runtime_test.go:eqstring_generic for
+// equivalent Go code.
+TEXT runtime·eqstring(SB),NOSPLIT,$0-17
+	MOVL	s1len+4(FP), AX
+	MOVL	s2len+12(FP), BX
+	CMPL	AX, BX
+	JNE	different
+	MOVL	s1str+0(FP), SI
+	MOVL	s2str+8(FP), DI
+	CMPL	SI, DI
+	JEQ	same
+	CALL	runtime·memeqbody(SB)
+	MOVB	AX, v+16(FP)
+	RET
+same:
+	MOVB	$1, v+16(FP)
+	RET
+different:
+	MOVB	$0, v+16(FP)
+	RET
+
+TEXT bytes·Equal(SB),NOSPLIT,$0-25
+	MOVL	a_len+4(FP), BX
+	MOVL	b_len+16(FP), CX
+	XORL	AX, AX
+	CMPL	BX, CX
+	JNE	eqret
+	MOVL	a+0(FP), SI
+	MOVL	b+12(FP), DI
+	CALL	runtime·memeqbody(SB)
+eqret:
+	MOVB	AX, ret+24(FP)
+	RET
+
+// a in SI
+// b in DI
+// count in BX
+TEXT runtime·memeqbody(SB),NOSPLIT,$0-0
+	XORL	AX, AX
+
+	CMPL	BX, $4
+	JB	small
+
+	// 64 bytes at a time using xmm registers
+hugeloop:
+	CMPL	BX, $64
+	JB	bigloop
+	TESTL	$0x4000000, runtime·cpuid_edx(SB) // check for sse2
+	JE	bigloop
+	MOVOU	(SI), X0
+	MOVOU	(DI), X1
+	MOVOU	16(SI), X2
+	MOVOU	16(DI), X3
+	MOVOU	32(SI), X4
+	MOVOU	32(DI), X5
+	MOVOU	48(SI), X6
+	MOVOU	48(DI), X7
+	PCMPEQB	X1, X0
+	PCMPEQB	X3, X2
+	PCMPEQB	X5, X4
+	PCMPEQB	X7, X6
+	PAND	X2, X0
+	PAND	X6, X4
+	PAND	X4, X0
+	PMOVMSKB X0, DX
+	ADDL	$64, SI
+	ADDL	$64, DI
+	SUBL	$64, BX
+	CMPL	DX, $0xffff
+	JEQ	hugeloop
+	RET
+
+	// 4 bytes at a time using 32-bit register
+bigloop:
+	CMPL	BX, $4
+	JBE	leftover
+	MOVL	(SI), CX
+	MOVL	(DI), DX
+	ADDL	$4, SI
+	ADDL	$4, DI
+	SUBL	$4, BX
+	CMPL	CX, DX
+	JEQ	bigloop
+	RET
+
+	// remaining 0-4 bytes
+leftover:
+	MOVL	-4(SI)(BX*1), CX
+	MOVL	-4(DI)(BX*1), DX
+	CMPL	CX, DX
+	SETEQ	AX
+	RET
+
+small:
+	CMPL	BX, $0
+	JEQ	equal
+
+	LEAL	0(BX*8), CX
+	NEGL	CX
+
+	MOVL	SI, DX
+	CMPB	DX, $0xfc
+	JA	si_high
+
+	// load at SI won't cross a page boundary.
+	MOVL	(SI), SI
+	JMP	si_finish
+si_high:
+	// address ends in 111111xx.  Load up to bytes we want, move to correct position.
+	MOVL	-4(SI)(BX*1), SI
+	SHRL	CX, SI
+si_finish:
+
+	// same for DI.
+	MOVL	DI, DX
+	CMPB	DX, $0xfc
+	JA	di_high
+	MOVL	(DI), DI
+	JMP	di_finish
+di_high:
+	MOVL	-4(DI)(BX*1), DI
+	SHRL	CX, DI
+di_finish:
+
+	SUBL	SI, DI
+	SHLL	CX, DI
+equal:
+	SETEQ	AX
+	RET
+
+TEXT runtime·cmpstring(SB),NOSPLIT,$0-20
+	MOVL	s1_base+0(FP), SI
+	MOVL	s1_len+4(FP), BX
+	MOVL	s2_base+8(FP), DI
+	MOVL	s2_len+12(FP), DX
+	CALL	runtime·cmpbody(SB)
+	MOVL	AX, ret+16(FP)
+	RET
+
+TEXT runtime·cmpbytes(SB),NOSPLIT,$0-28
+	MOVL	s1+0(FP), SI
+	MOVL	s1+4(FP), BX
+	MOVL	s2+12(FP), DI
+	MOVL	s2+16(FP), DX
+	CALL	runtime·cmpbody(SB)
+	MOVL	AX, ret+24(FP)
+	RET
+
+TEXT bytes·IndexByte(SB),NOSPLIT,$0
+	MOVL	s+0(FP), SI
+	MOVL	s_len+4(FP), CX
+	MOVB	c+12(FP), AL
+	MOVL	SI, DI
+	CLD; REPN; SCASB
+	JZ 3(PC)
+	MOVL	$-1, ret+16(FP)
+	RET
+	SUBL	SI, DI
+	SUBL	$1, DI
+	MOVL	DI, ret+16(FP)
+	RET
+
+TEXT strings·IndexByte(SB),NOSPLIT,$0
+	MOVL	s+0(FP), SI
+	MOVL	s_len+4(FP), CX
+	MOVB	c+8(FP), AL
+	MOVL	SI, DI
+	CLD; REPN; SCASB
+	JZ 3(PC)
+	MOVL	$-1, ret+12(FP)
+	RET
+	SUBL	SI, DI
+	SUBL	$1, DI
+	MOVL	DI, ret+12(FP)
+	RET
+
+// input:
+//   SI = a
+//   DI = b
+//   BX = alen
+//   DX = blen
+// output:
+//   AX = 1/0/-1
+TEXT runtime·cmpbody(SB),NOSPLIT,$0-0
+	CMPL	SI, DI
+	JEQ	cmp_allsame
+	CMPL	BX, DX
+	MOVL	DX, BP
+	CMOVLLT	BX, BP // BP = min(alen, blen)
+	CMPL	BP, $4
+	JB	cmp_small
+	TESTL	$0x4000000, runtime·cpuid_edx(SB) // check for sse2
+	JE	cmp_mediumloop
+cmp_largeloop:
+	CMPL	BP, $16
+	JB	cmp_mediumloop
+	MOVOU	(SI), X0
+	MOVOU	(DI), X1
+	PCMPEQB X0, X1
+	PMOVMSKB X1, AX
+	XORL	$0xffff, AX	// convert EQ to NE
+	JNE	cmp_diff16	// branch if at least one byte is not equal
+	ADDL	$16, SI
+	ADDL	$16, DI
+	SUBL	$16, BP
+	JMP	cmp_largeloop
+
+cmp_diff16:
+	BSFL	AX, BX	// index of first byte that differs
+	XORL	AX, AX
+	MOVB	(SI)(BX*1), CX
+	CMPB	CX, (DI)(BX*1)
+	SETHI	AX
+	LEAL	-1(AX*2), AX	// convert 1/0 to +1/-1
+	RET
+
+cmp_mediumloop:
+	CMPL	BP, $4
+	JBE	cmp_0through4
+	MOVL	(SI), AX
+	MOVL	(DI), CX
+	CMPL	AX, CX
+	JNE	cmp_diff4
+	ADDL	$4, SI
+	ADDL	$4, DI
+	SUBL	$4, BP
+	JMP	cmp_mediumloop
+
+cmp_0through4:
+	MOVL	-4(SI)(BP*1), AX
+	MOVL	-4(DI)(BP*1), CX
+	CMPL	AX, CX
+	JEQ	cmp_allsame
+
+cmp_diff4:
+	BSWAPL	AX	// reverse order of bytes
+	BSWAPL	CX
+	XORL	AX, CX	// find bit differences
+	BSRL	CX, CX	// index of highest bit difference
+	SHRL	CX, AX	// move a's bit to bottom
+	ANDL	$1, AX	// mask bit
+	LEAL	-1(AX*2), AX // 1/0 => +1/-1
+	RET
+
+	// 0-3 bytes in common
+cmp_small:
+	LEAL	(BP*8), CX
+	NEGL	CX
+	JEQ	cmp_allsame
+
+	// load si
+	CMPB	SI, $0xfc
+	JA	cmp_si_high
+	MOVL	(SI), SI
+	JMP	cmp_si_finish
+cmp_si_high:
+	MOVL	-4(SI)(BP*1), SI
+	SHRL	CX, SI
+cmp_si_finish:
+	SHLL	CX, SI
+
+	// same for di
+	CMPB	DI, $0xfc
+	JA	cmp_di_high
+	MOVL	(DI), DI
+	JMP	cmp_di_finish
+cmp_di_high:
+	MOVL	-4(DI)(BP*1), DI
+	SHRL	CX, DI
+cmp_di_finish:
+	SHLL	CX, DI
+
+	BSWAPL	SI	// reverse order of bytes
+	BSWAPL	DI
+	XORL	SI, DI	// find bit differences
+	JEQ	cmp_allsame
+	BSRL	DI, CX	// index of highest bit difference
+	SHRL	CX, SI	// move a's bit to bottom
+	ANDL	$1, SI	// mask bit
+	LEAL	-1(SI*2), AX // 1/0 => +1/-1
+	RET
+
+	// all the bytes in common are the same, so we just need
+	// to compare the lengths.
+cmp_allsame:
+	XORL	AX, AX
+	XORL	CX, CX
+	CMPL	BX, DX
+	SETGT	AX	// 1 if alen > blen
+	SETEQ	CX	// 1 if alen == blen
+	LEAL	-1(CX)(AX*2), AX	// 1,0,-1 result
+	RET
+
+// A Duff's device for zeroing memory.
+// The compiler jumps to computed addresses within
+// this routine to zero chunks of memory.  Do not
+// change this code without also changing the code
+// in ../../cmd/8g/ggen.c:clearfat.
+// AX: zero
+// DI: ptr to memory to be zeroed
+// DI is updated as a side effect.
+TEXT runtime·duffzero(SB), NOSPLIT, $0-0
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	STOSL
+	RET
+
+// A Duff's device for copying memory.
+// The compiler jumps to computed addresses within
+// this routine to copy chunks of memory.  Source
+// and destination must not overlap.  Do not
+// change this code without also changing the code
+// in ../../cmd/6g/cgen.c:sgen.
+// SI: ptr to source memory
+// DI: ptr to destination memory
+// SI and DI are updated as a side effect.
+
+// NOTE: this is equivalent to a sequence of MOVSL but
+// for some reason MOVSL is really slow.
+TEXT runtime·duffcopy(SB), NOSPLIT, $0-0
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	MOVL	(SI),CX
+	ADDL	$4,SI
+	MOVL	CX,(DI)
+	ADDL	$4,DI
+	
+	RET
+
+TEXT runtime·fastrand1(SB), NOSPLIT, $0-4
+	get_tls(CX)
+	MOVL	g(CX), AX
+	MOVL	g_m(AX), AX
+	MOVL	m_fastrand(AX), DX
+	ADDL	DX, DX
+	MOVL	DX, BX
+	XORL	$0x88888eef, DX
+	CMOVLMI	BX, DX
+	MOVL	DX, m_fastrand(AX)
+	MOVL	DX, ret+0(FP)
+	RET
+
+TEXT runtime·return0(SB), NOSPLIT, $0
+	MOVL	$0, AX
+	RET
+
+// Called from cgo wrappers, this function returns g->m->curg.stack.hi.
+// Must obey the gcc calling convention.
+TEXT _cgo_topofstack(SB),NOSPLIT,$0
+	get_tls(CX)
+	MOVL	g(CX), AX
+	MOVL	g_m(AX), AX
+	MOVL	m_curg(AX), AX
+	MOVL	(g_stack+stack_hi)(AX), AX
+	RET
+
+// The top-most function running on a goroutine
+// returns to goexit+PCQuantum.
+TEXT runtime·goexit(SB),NOSPLIT,$0-0
+	BYTE	$0x90	// NOP
+	CALL	runtime·goexit1(SB)	// does not return
diff --git a/src/runtime/asm_amd64.s b/src/runtime/asm_amd64.s
new file mode 100644
index 0000000..39d7c78
--- /dev/null
+++ b/src/runtime/asm_amd64.s
@@ -0,0 +1,2237 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "zasm_GOOS_GOARCH.h"
+#include "funcdata.h"
+#include "textflag.h"
+
+TEXT runtime·rt0_go(SB),NOSPLIT,$0
+	// copy arguments forward on an even stack
+	MOVQ	DI, AX		// argc
+	MOVQ	SI, BX		// argv
+	SUBQ	$(4*8+7), SP		// 2args 2auto
+	ANDQ	$~15, SP
+	MOVQ	AX, 16(SP)
+	MOVQ	BX, 24(SP)
+	
+	// create istack out of the given (operating system) stack.
+	// _cgo_init may update stackguard.
+	MOVQ	$runtime·g0(SB), DI
+	LEAQ	(-64*1024+104)(SP), BX
+	MOVQ	BX, g_stackguard0(DI)
+	MOVQ	BX, g_stackguard1(DI)
+	MOVQ	BX, (g_stack+stack_lo)(DI)
+	MOVQ	SP, (g_stack+stack_hi)(DI)
+
+	// find out information about the processor we're on
+	MOVQ	$0, AX
+	CPUID
+	CMPQ	AX, $0
+	JE	nocpuinfo
+	MOVQ	$1, AX
+	CPUID
+	MOVL	CX, runtime·cpuid_ecx(SB)
+	MOVL	DX, runtime·cpuid_edx(SB)
+nocpuinfo:	
+	
+	// if there is an _cgo_init, call it.
+	MOVQ	_cgo_init(SB), AX
+	TESTQ	AX, AX
+	JZ	needtls
+	// g0 already in DI
+	MOVQ	DI, CX	// Win64 uses CX for first parameter
+	MOVQ	$setg_gcc<>(SB), SI
+	CALL	AX
+
+	// update stackguard after _cgo_init
+	MOVQ	$runtime·g0(SB), CX
+	MOVQ	(g_stack+stack_lo)(CX), AX
+	ADDQ	$const_StackGuard, AX
+	MOVQ	AX, g_stackguard0(CX)
+	MOVQ	AX, g_stackguard1(CX)
+
+	CMPL	runtime·iswindows(SB), $0
+	JEQ ok
+needtls:
+	// skip TLS setup on Plan 9
+	CMPL	runtime·isplan9(SB), $1
+	JEQ ok
+	// skip TLS setup on Solaris
+	CMPL	runtime·issolaris(SB), $1
+	JEQ ok
+
+	LEAQ	runtime·tls0(SB), DI
+	CALL	runtime·settls(SB)
+
+	// store through it, to make sure it works
+	get_tls(BX)
+	MOVQ	$0x123, g(BX)
+	MOVQ	runtime·tls0(SB), AX
+	CMPQ	AX, $0x123
+	JEQ 2(PC)
+	MOVL	AX, 0	// abort
+ok:
+	// set the per-goroutine and per-mach "registers"
+	get_tls(BX)
+	LEAQ	runtime·g0(SB), CX
+	MOVQ	CX, g(BX)
+	LEAQ	runtime·m0(SB), AX
+
+	// save m->g0 = g0
+	MOVQ	CX, m_g0(AX)
+	// save m0 to g0->m
+	MOVQ	AX, g_m(CX)
+
+	CLD				// convention is D is always left cleared
+	CALL	runtime·check(SB)
+
+	MOVL	16(SP), AX		// copy argc
+	MOVL	AX, 0(SP)
+	MOVQ	24(SP), AX		// copy argv
+	MOVQ	AX, 8(SP)
+	CALL	runtime·args(SB)
+	CALL	runtime·osinit(SB)
+	CALL	runtime·schedinit(SB)
+
+	// create a new goroutine to start program
+	MOVQ	$runtime·main·f(SB), BP		// entry
+	PUSHQ	BP
+	PUSHQ	$0			// arg size
+	CALL	runtime·newproc(SB)
+	POPQ	AX
+	POPQ	AX
+
+	// start this M
+	CALL	runtime·mstart(SB)
+
+	MOVL	$0xf1, 0xf1  // crash
+	RET
+
+DATA	runtime·main·f+0(SB)/8,$runtime·main(SB)
+GLOBL	runtime·main·f(SB),RODATA,$8
+
+TEXT runtime·breakpoint(SB),NOSPLIT,$0-0
+	BYTE	$0xcc
+	RET
+
+TEXT runtime·asminit(SB),NOSPLIT,$0-0
+	// No per-thread init.
+	RET
+
+/*
+ *  go-routine
+ */
+
+// void gosave(Gobuf*)
+// save state in Gobuf; setjmp
+TEXT runtime·gosave(SB), NOSPLIT, $0-8
+	MOVQ	buf+0(FP), AX		// gobuf
+	LEAQ	buf+0(FP), BX		// caller's SP
+	MOVQ	BX, gobuf_sp(AX)
+	MOVQ	0(SP), BX		// caller's PC
+	MOVQ	BX, gobuf_pc(AX)
+	MOVQ	$0, gobuf_ret(AX)
+	MOVQ	$0, gobuf_ctxt(AX)
+	get_tls(CX)
+	MOVQ	g(CX), BX
+	MOVQ	BX, gobuf_g(AX)
+	RET
+
+// void gogo(Gobuf*)
+// restore state from Gobuf; longjmp
+TEXT runtime·gogo(SB), NOSPLIT, $0-8
+	MOVQ	buf+0(FP), BX		// gobuf
+	MOVQ	gobuf_g(BX), DX
+	MOVQ	0(DX), CX		// make sure g != nil
+	get_tls(CX)
+	MOVQ	DX, g(CX)
+	MOVQ	gobuf_sp(BX), SP	// restore SP
+	MOVQ	gobuf_ret(BX), AX
+	MOVQ	gobuf_ctxt(BX), DX
+	MOVQ	$0, gobuf_sp(BX)	// clear to help garbage collector
+	MOVQ	$0, gobuf_ret(BX)
+	MOVQ	$0, gobuf_ctxt(BX)
+	MOVQ	gobuf_pc(BX), BX
+	JMP	BX
+
+// func mcall(fn func(*g))
+// Switch to m->g0's stack, call fn(g).
+// Fn must never return.  It should gogo(&g->sched)
+// to keep running g.
+TEXT runtime·mcall(SB), NOSPLIT, $0-8
+	MOVQ	fn+0(FP), DI
+	
+	get_tls(CX)
+	MOVQ	g(CX), AX	// save state in g->sched
+	MOVQ	0(SP), BX	// caller's PC
+	MOVQ	BX, (g_sched+gobuf_pc)(AX)
+	LEAQ	fn+0(FP), BX	// caller's SP
+	MOVQ	BX, (g_sched+gobuf_sp)(AX)
+	MOVQ	AX, (g_sched+gobuf_g)(AX)
+
+	// switch to m->g0 & its stack, call fn
+	MOVQ	g(CX), BX
+	MOVQ	g_m(BX), BX
+	MOVQ	m_g0(BX), SI
+	CMPQ	SI, AX	// if g == m->g0 call badmcall
+	JNE	3(PC)
+	MOVQ	$runtime·badmcall(SB), AX
+	JMP	AX
+	MOVQ	SI, g(CX)	// g = m->g0
+	MOVQ	(g_sched+gobuf_sp)(SI), SP	// sp = m->g0->sched.sp
+	PUSHQ	AX
+	MOVQ	DI, DX
+	MOVQ	0(DI), DI
+	CALL	DI
+	POPQ	AX
+	MOVQ	$runtime·badmcall2(SB), AX
+	JMP	AX
+	RET
+
+// switchtoM is a dummy routine that onM leaves at the bottom
+// of the G stack.  We need to distinguish the routine that
+// lives at the bottom of the G stack from the one that lives
+// at the top of the M stack because the one at the top of
+// the M stack terminates the stack walk (see topofstack()).
+TEXT runtime·switchtoM(SB), NOSPLIT, $0-0
+	RET
+
+// func onM_signalok(fn func())
+TEXT runtime·onM_signalok(SB), NOSPLIT, $0-8
+	get_tls(CX)
+	MOVQ	g(CX), AX	// AX = g
+	MOVQ	g_m(AX), BX	// BX = m
+	MOVQ	m_gsignal(BX), DX	// DX = gsignal
+	CMPQ	AX, DX
+	JEQ	ongsignal
+	JMP	runtime·onM(SB)
+
+ongsignal:
+	MOVQ	fn+0(FP), DI	// DI = fn
+	MOVQ	DI, DX
+	MOVQ	0(DI), DI
+	CALL	DI
+	RET
+
+// func onM(fn func())
+TEXT runtime·onM(SB), NOSPLIT, $0-8
+	MOVQ	fn+0(FP), DI	// DI = fn
+	get_tls(CX)
+	MOVQ	g(CX), AX	// AX = g
+	MOVQ	g_m(AX), BX	// BX = m
+
+	MOVQ	m_g0(BX), DX	// DX = g0
+	CMPQ	AX, DX
+	JEQ	onm
+
+	MOVQ	m_curg(BX), BP
+	CMPQ	AX, BP
+	JEQ	oncurg
+	
+	// Not g0, not curg. Must be gsignal, but that's not allowed.
+	// Hide call from linker nosplit analysis.
+	MOVQ	$runtime·badonm(SB), AX
+	CALL	AX
+
+oncurg:
+	// save our state in g->sched.  Pretend to
+	// be switchtoM if the G stack is scanned.
+	MOVQ	$runtime·switchtoM(SB), BP
+	MOVQ	BP, (g_sched+gobuf_pc)(AX)
+	MOVQ	SP, (g_sched+gobuf_sp)(AX)
+	MOVQ	AX, (g_sched+gobuf_g)(AX)
+
+	// switch to g0
+	MOVQ	DX, g(CX)
+	MOVQ	(g_sched+gobuf_sp)(DX), BX
+	// make it look like mstart called onM on g0, to stop traceback
+	SUBQ	$8, BX
+	MOVQ	$runtime·mstart(SB), DX
+	MOVQ	DX, 0(BX)
+	MOVQ	BX, SP
+
+	// call target function
+	MOVQ	DI, DX
+	MOVQ	0(DI), DI
+	CALL	DI
+
+	// switch back to g
+	get_tls(CX)
+	MOVQ	g(CX), AX
+	MOVQ	g_m(AX), BX
+	MOVQ	m_curg(BX), AX
+	MOVQ	AX, g(CX)
+	MOVQ	(g_sched+gobuf_sp)(AX), SP
+	MOVQ	$0, (g_sched+gobuf_sp)(AX)
+	RET
+
+onm:
+	// already on m stack, just call directly
+	MOVQ	DI, DX
+	MOVQ	0(DI), DI
+	CALL	DI
+	RET
+
+/*
+ * support for morestack
+ */
+
+// Called during function prolog when more stack is needed.
+//
+// The traceback routines see morestack on a g0 as being
+// the top of a stack (for example, morestack calling newstack
+// calling the scheduler calling newm calling gc), so we must
+// record an argument size. For that purpose, it has no arguments.
+TEXT runtime·morestack(SB),NOSPLIT,$0-0
+	// Cannot grow scheduler stack (m->g0).
+	get_tls(CX)
+	MOVQ	g(CX), BX
+	MOVQ	g_m(BX), BX
+	MOVQ	m_g0(BX), SI
+	CMPQ	g(CX), SI
+	JNE	2(PC)
+	INT	$3
+
+	// Cannot grow signal stack (m->gsignal).
+	MOVQ	m_gsignal(BX), SI
+	CMPQ	g(CX), SI
+	JNE	2(PC)
+	INT	$3
+
+	// Called from f.
+	// Set m->morebuf to f's caller.
+	MOVQ	8(SP), AX	// f's caller's PC
+	MOVQ	AX, (m_morebuf+gobuf_pc)(BX)
+	LEAQ	16(SP), AX	// f's caller's SP
+	MOVQ	AX, (m_morebuf+gobuf_sp)(BX)
+	get_tls(CX)
+	MOVQ	g(CX), SI
+	MOVQ	SI, (m_morebuf+gobuf_g)(BX)
+
+	// Set g->sched to context in f.
+	MOVQ	0(SP), AX // f's PC
+	MOVQ	AX, (g_sched+gobuf_pc)(SI)
+	MOVQ	SI, (g_sched+gobuf_g)(SI)
+	LEAQ	8(SP), AX // f's SP
+	MOVQ	AX, (g_sched+gobuf_sp)(SI)
+	MOVQ	DX, (g_sched+gobuf_ctxt)(SI)
+
+	// Call newstack on m->g0's stack.
+	MOVQ	m_g0(BX), BP
+	MOVQ	BP, g(CX)
+	MOVQ	(g_sched+gobuf_sp)(BP), SP
+	CALL	runtime·newstack(SB)
+	MOVQ	$0, 0x1003	// crash if newstack returns
+	RET
+
+// morestack but not preserving ctxt.
+TEXT runtime·morestack_noctxt(SB),NOSPLIT,$0
+	MOVL	$0, DX
+	JMP	runtime·morestack(SB)
+
+// reflectcall: call a function with the given argument list
+// func call(f *FuncVal, arg *byte, argsize, retoffset uint32).
+// we don't have variable-sized frames, so we use a small number
+// of constant-sized-frame functions to encode a few bits of size in the pc.
+// Caution: ugly multiline assembly macros in your future!
+
+#define DISPATCH(NAME,MAXSIZE)		\
+	CMPQ	CX, $MAXSIZE;		\
+	JA	3(PC);			\
+	MOVQ	$NAME(SB), AX;		\
+	JMP	AX
+// Note: can't just "JMP NAME(SB)" - bad inlining results.
+
+TEXT ·reflectcall(SB), NOSPLIT, $0-24
+	MOVLQZX argsize+16(FP), CX
+	DISPATCH(runtime·call16, 16)
+	DISPATCH(runtime·call32, 32)
+	DISPATCH(runtime·call64, 64)
+	DISPATCH(runtime·call128, 128)
+	DISPATCH(runtime·call256, 256)
+	DISPATCH(runtime·call512, 512)
+	DISPATCH(runtime·call1024, 1024)
+	DISPATCH(runtime·call2048, 2048)
+	DISPATCH(runtime·call4096, 4096)
+	DISPATCH(runtime·call8192, 8192)
+	DISPATCH(runtime·call16384, 16384)
+	DISPATCH(runtime·call32768, 32768)
+	DISPATCH(runtime·call65536, 65536)
+	DISPATCH(runtime·call131072, 131072)
+	DISPATCH(runtime·call262144, 262144)
+	DISPATCH(runtime·call524288, 524288)
+	DISPATCH(runtime·call1048576, 1048576)
+	DISPATCH(runtime·call2097152, 2097152)
+	DISPATCH(runtime·call4194304, 4194304)
+	DISPATCH(runtime·call8388608, 8388608)
+	DISPATCH(runtime·call16777216, 16777216)
+	DISPATCH(runtime·call33554432, 33554432)
+	DISPATCH(runtime·call67108864, 67108864)
+	DISPATCH(runtime·call134217728, 134217728)
+	DISPATCH(runtime·call268435456, 268435456)
+	DISPATCH(runtime·call536870912, 536870912)
+	DISPATCH(runtime·call1073741824, 1073741824)
+	MOVQ	$runtime·badreflectcall(SB), AX
+	JMP	AX
+
+#define CALLFN(NAME,MAXSIZE)			\
+TEXT NAME(SB), WRAPPER, $MAXSIZE-24;		\
+	NO_LOCAL_POINTERS;			\
+	/* copy arguments to stack */		\
+	MOVQ	argptr+8(FP), SI;		\
+	MOVLQZX argsize+16(FP), CX;		\
+	MOVQ	SP, DI;				\
+	REP;MOVSB;				\
+	/* call function */			\
+	MOVQ	f+0(FP), DX;			\
+	PCDATA  $PCDATA_StackMapIndex, $0;	\
+	CALL	(DX);				\
+	/* copy return values back */		\
+	MOVQ	argptr+8(FP), DI;		\
+	MOVLQZX	argsize+16(FP), CX;		\
+	MOVLQZX retoffset+20(FP), BX;		\
+	MOVQ	SP, SI;				\
+	ADDQ	BX, DI;				\
+	ADDQ	BX, SI;				\
+	SUBQ	BX, CX;				\
+	REP;MOVSB;				\
+	RET
+
+CALLFN(·call16, 16)
+CALLFN(·call32, 32)
+CALLFN(·call64, 64)
+CALLFN(·call128, 128)
+CALLFN(·call256, 256)
+CALLFN(·call512, 512)
+CALLFN(·call1024, 1024)
+CALLFN(·call2048, 2048)
+CALLFN(·call4096, 4096)
+CALLFN(·call8192, 8192)
+CALLFN(·call16384, 16384)
+CALLFN(·call32768, 32768)
+CALLFN(·call65536, 65536)
+CALLFN(·call131072, 131072)
+CALLFN(·call262144, 262144)
+CALLFN(·call524288, 524288)
+CALLFN(·call1048576, 1048576)
+CALLFN(·call2097152, 2097152)
+CALLFN(·call4194304, 4194304)
+CALLFN(·call8388608, 8388608)
+CALLFN(·call16777216, 16777216)
+CALLFN(·call33554432, 33554432)
+CALLFN(·call67108864, 67108864)
+CALLFN(·call134217728, 134217728)
+CALLFN(·call268435456, 268435456)
+CALLFN(·call536870912, 536870912)
+CALLFN(·call1073741824, 1073741824)
+
+// bool cas(int32 *val, int32 old, int32 new)
+// Atomically:
+//	if(*val == old){
+//		*val = new;
+//		return 1;
+//	} else
+//		return 0;
+TEXT runtime·cas(SB), NOSPLIT, $0-17
+	MOVQ	ptr+0(FP), BX
+	MOVL	old+8(FP), AX
+	MOVL	new+12(FP), CX
+	LOCK
+	CMPXCHGL	CX, 0(BX)
+	JZ 4(PC)
+	MOVL	$0, AX
+	MOVB	AX, ret+16(FP)
+	RET
+	MOVL	$1, AX
+	MOVB	AX, ret+16(FP)
+	RET
+
+// bool	runtime·cas64(uint64 *val, uint64 old, uint64 new)
+// Atomically:
+//	if(*val == *old){
+//		*val = new;
+//		return 1;
+//	} else {
+//		return 0;
+//	}
+TEXT runtime·cas64(SB), NOSPLIT, $0-25
+	MOVQ	ptr+0(FP), BX
+	MOVQ	old+8(FP), AX
+	MOVQ	new+16(FP), CX
+	LOCK
+	CMPXCHGQ	CX, 0(BX)
+	JNZ	cas64_fail
+	MOVL	$1, AX
+	MOVB	AX, ret+24(FP)
+	RET
+cas64_fail:
+	MOVL	$0, AX
+	MOVB	AX, ret+24(FP)
+	RET
+	
+TEXT runtime·casuintptr(SB), NOSPLIT, $0-25
+	JMP	runtime·cas64(SB)
+
+TEXT runtime·atomicloaduintptr(SB), NOSPLIT, $0-16
+	JMP	runtime·atomicload64(SB)
+
+TEXT runtime·atomicloaduint(SB), NOSPLIT, $0-16
+	JMP	runtime·atomicload64(SB)
+
+TEXT runtime·atomicstoreuintptr(SB), NOSPLIT, $0-16
+	JMP	runtime·atomicstore64(SB)
+
+// bool casp(void **val, void *old, void *new)
+// Atomically:
+//	if(*val == old){
+//		*val = new;
+//		return 1;
+//	} else
+//		return 0;
+TEXT runtime·casp(SB), NOSPLIT, $0-25
+	MOVQ	ptr+0(FP), BX
+	MOVQ	old+8(FP), AX
+	MOVQ	new+16(FP), CX
+	LOCK
+	CMPXCHGQ	CX, 0(BX)
+	JZ 4(PC)
+	MOVL	$0, AX
+	MOVB	AX, ret+24(FP)
+	RET
+	MOVL	$1, AX
+	MOVB	AX, ret+24(FP)
+	RET
+
+// uint32 xadd(uint32 volatile *val, int32 delta)
+// Atomically:
+//	*val += delta;
+//	return *val;
+TEXT runtime·xadd(SB), NOSPLIT, $0-20
+	MOVQ	ptr+0(FP), BX
+	MOVL	delta+8(FP), AX
+	MOVL	AX, CX
+	LOCK
+	XADDL	AX, 0(BX)
+	ADDL	CX, AX
+	MOVL	AX, ret+16(FP)
+	RET
+
+TEXT runtime·xadd64(SB), NOSPLIT, $0-24
+	MOVQ	ptr+0(FP), BX
+	MOVQ	delta+8(FP), AX
+	MOVQ	AX, CX
+	LOCK
+	XADDQ	AX, 0(BX)
+	ADDQ	CX, AX
+	MOVQ	AX, ret+16(FP)
+	RET
+
+TEXT runtime·xchg(SB), NOSPLIT, $0-20
+	MOVQ	ptr+0(FP), BX
+	MOVL	new+8(FP), AX
+	XCHGL	AX, 0(BX)
+	MOVL	AX, ret+16(FP)
+	RET
+
+TEXT runtime·xchg64(SB), NOSPLIT, $0-24
+	MOVQ	ptr+0(FP), BX
+	MOVQ	new+8(FP), AX
+	XCHGQ	AX, 0(BX)
+	MOVQ	AX, ret+16(FP)
+	RET
+
+TEXT runtime·xchgp(SB), NOSPLIT, $0-24
+	MOVQ	ptr+0(FP), BX
+	MOVQ	new+8(FP), AX
+	XCHGQ	AX, 0(BX)
+	MOVQ	AX, ret+16(FP)
+	RET
+
+TEXT runtime·xchguintptr(SB), NOSPLIT, $0-24
+	JMP	runtime·xchg64(SB)
+
+TEXT runtime·procyield(SB),NOSPLIT,$0-0
+	MOVL	cycles+0(FP), AX
+again:
+	PAUSE
+	SUBL	$1, AX
+	JNZ	again
+	RET
+
+TEXT runtime·atomicstorep(SB), NOSPLIT, $0-16
+	MOVQ	ptr+0(FP), BX
+	MOVQ	val+8(FP), AX
+	XCHGQ	AX, 0(BX)
+	RET
+
+TEXT runtime·atomicstore(SB), NOSPLIT, $0-12
+	MOVQ	ptr+0(FP), BX
+	MOVL	val+8(FP), AX
+	XCHGL	AX, 0(BX)
+	RET
+
+TEXT runtime·atomicstore64(SB), NOSPLIT, $0-16
+	MOVQ	ptr+0(FP), BX
+	MOVQ	val+8(FP), AX
+	XCHGQ	AX, 0(BX)
+	RET
+
+// void	runtime·atomicor8(byte volatile*, byte);
+TEXT runtime·atomicor8(SB), NOSPLIT, $0-9
+	MOVQ	ptr+0(FP), AX
+	MOVB	val+8(FP), BX
+	LOCK
+	ORB	BX, (AX)
+	RET
+
+// void jmpdefer(fn, sp);
+// called from deferreturn.
+// 1. pop the caller
+// 2. sub 5 bytes from the callers return
+// 3. jmp to the argument
+TEXT runtime·jmpdefer(SB), NOSPLIT, $0-16
+	MOVQ	fv+0(FP), DX	// fn
+	MOVQ	argp+8(FP), BX	// caller sp
+	LEAQ	-8(BX), SP	// caller sp after CALL
+	SUBQ	$5, (SP)	// return to CALL again
+	MOVQ	0(DX), BX
+	JMP	BX	// but first run the deferred function
+
+// Save state of caller into g->sched. Smashes R8, R9.
+TEXT gosave<>(SB),NOSPLIT,$0
+	get_tls(R8)
+	MOVQ	g(R8), R8
+	MOVQ	0(SP), R9
+	MOVQ	R9, (g_sched+gobuf_pc)(R8)
+	LEAQ	8(SP), R9
+	MOVQ	R9, (g_sched+gobuf_sp)(R8)
+	MOVQ	$0, (g_sched+gobuf_ret)(R8)
+	MOVQ	$0, (g_sched+gobuf_ctxt)(R8)
+	RET
+
+// asmcgocall(void(*fn)(void*), void *arg)
+// Call fn(arg) on the scheduler stack,
+// aligned appropriately for the gcc ABI.
+// See cgocall.c for more details.
+TEXT ·asmcgocall(SB),NOSPLIT,$0-16
+	MOVQ	fn+0(FP), AX
+	MOVQ	arg+8(FP), BX
+	CALL	asmcgocall<>(SB)
+	RET
+
+TEXT ·asmcgocall_errno(SB),NOSPLIT,$0-20
+	MOVQ	fn+0(FP), AX
+	MOVQ	arg+8(FP), BX
+	CALL	asmcgocall<>(SB)
+	MOVL	AX, ret+16(FP)
+	RET
+
+// asmcgocall common code. fn in AX, arg in BX. returns errno in AX.
+TEXT asmcgocall<>(SB),NOSPLIT,$0-0
+	MOVQ	SP, DX
+
+	// Figure out if we need to switch to m->g0 stack.
+	// We get called to create new OS threads too, and those
+	// come in on the m->g0 stack already.
+	get_tls(CX)
+	MOVQ	g(CX), BP
+	MOVQ	g_m(BP), BP
+	MOVQ	m_g0(BP), SI
+	MOVQ	g(CX), DI
+	CMPQ	SI, DI
+	JEQ	nosave
+	MOVQ	m_gsignal(BP), SI
+	CMPQ	SI, DI
+	JEQ	nosave
+	
+	MOVQ	m_g0(BP), SI
+	CALL	gosave<>(SB)
+	MOVQ	SI, g(CX)
+	MOVQ	(g_sched+gobuf_sp)(SI), SP
+nosave:
+
+	// Now on a scheduling stack (a pthread-created stack).
+	// Make sure we have enough room for 4 stack-backed fast-call
+	// registers as per windows amd64 calling convention.
+	SUBQ	$64, SP
+	ANDQ	$~15, SP	// alignment for gcc ABI
+	MOVQ	DI, 48(SP)	// save g
+	MOVQ	(g_stack+stack_hi)(DI), DI
+	SUBQ	DX, DI
+	MOVQ	DI, 40(SP)	// save depth in stack (can't just save SP, as stack might be copied during a callback)
+	MOVQ	BX, DI		// DI = first argument in AMD64 ABI
+	MOVQ	BX, CX		// CX = first argument in Win64
+	CALL	AX
+
+	// Restore registers, g, stack pointer.
+	get_tls(CX)
+	MOVQ	48(SP), DI
+	MOVQ	(g_stack+stack_hi)(DI), SI
+	SUBQ	40(SP), SI
+	MOVQ	DI, g(CX)
+	MOVQ	SI, SP
+	RET
+
+// cgocallback(void (*fn)(void*), void *frame, uintptr framesize)
+// Turn the fn into a Go func (by taking its address) and call
+// cgocallback_gofunc.
+TEXT runtime·cgocallback(SB),NOSPLIT,$24-24
+	LEAQ	fn+0(FP), AX
+	MOVQ	AX, 0(SP)
+	MOVQ	frame+8(FP), AX
+	MOVQ	AX, 8(SP)
+	MOVQ	framesize+16(FP), AX
+	MOVQ	AX, 16(SP)
+	MOVQ	$runtime·cgocallback_gofunc(SB), AX
+	CALL	AX
+	RET
+
+// cgocallback_gofunc(FuncVal*, void *frame, uintptr framesize)
+// See cgocall.c for more details.
+TEXT ·cgocallback_gofunc(SB),NOSPLIT,$8-24
+	NO_LOCAL_POINTERS
+
+	// If g is nil, Go did not create the current thread.
+	// Call needm to obtain one m for temporary use.
+	// In this case, we're running on the thread stack, so there's
+	// lots of space, but the linker doesn't know. Hide the call from
+	// the linker analysis by using an indirect call through AX.
+	get_tls(CX)
+#ifdef GOOS_windows
+	MOVL	$0, BP
+	CMPQ	CX, $0
+	JEQ	2(PC)
+#endif
+	MOVQ	g(CX), BP
+	CMPQ	BP, $0
+	JEQ	needm
+	MOVQ	g_m(BP), BP
+	MOVQ	BP, R8 // holds oldm until end of function
+	JMP	havem
+needm:
+	MOVQ	$0, 0(SP)
+	MOVQ	$runtime·needm(SB), AX
+	CALL	AX
+	MOVQ	0(SP), R8
+	get_tls(CX)
+	MOVQ	g(CX), BP
+	MOVQ	g_m(BP), BP
+	
+	// Set m->sched.sp = SP, so that if a panic happens
+	// during the function we are about to execute, it will
+	// have a valid SP to run on the g0 stack.
+	// The next few lines (after the havem label)
+	// will save this SP onto the stack and then write
+	// the same SP back to m->sched.sp. That seems redundant,
+	// but if an unrecovered panic happens, unwindm will
+	// restore the g->sched.sp from the stack location
+	// and then onM will try to use it. If we don't set it here,
+	// that restored SP will be uninitialized (typically 0) and
+	// will not be usable.
+	MOVQ	m_g0(BP), SI
+	MOVQ	SP, (g_sched+gobuf_sp)(SI)
+
+havem:
+	// Now there's a valid m, and we're running on its m->g0.
+	// Save current m->g0->sched.sp on stack and then set it to SP.
+	// Save current sp in m->g0->sched.sp in preparation for
+	// switch back to m->curg stack.
+	// NOTE: unwindm knows that the saved g->sched.sp is at 0(SP).
+	MOVQ	m_g0(BP), SI
+	MOVQ	(g_sched+gobuf_sp)(SI), AX
+	MOVQ	AX, 0(SP)
+	MOVQ	SP, (g_sched+gobuf_sp)(SI)
+
+	// Switch to m->curg stack and call runtime.cgocallbackg.
+	// Because we are taking over the execution of m->curg
+	// but *not* resuming what had been running, we need to
+	// save that information (m->curg->sched) so we can restore it.
+	// We can restore m->curg->sched.sp easily, because calling
+	// runtime.cgocallbackg leaves SP unchanged upon return.
+	// To save m->curg->sched.pc, we push it onto the stack.
+	// This has the added benefit that it looks to the traceback
+	// routine like cgocallbackg is going to return to that
+	// PC (because the frame we allocate below has the same
+	// size as cgocallback_gofunc's frame declared above)
+	// so that the traceback will seamlessly trace back into
+	// the earlier calls.
+	//
+	// In the new goroutine, 0(SP) holds the saved R8.
+	MOVQ	m_curg(BP), SI
+	MOVQ	SI, g(CX)
+	MOVQ	(g_sched+gobuf_sp)(SI), DI  // prepare stack as DI
+	MOVQ	(g_sched+gobuf_pc)(SI), BP
+	MOVQ	BP, -8(DI)
+	LEAQ	-(8+8)(DI), SP
+	MOVQ	R8, 0(SP)
+	CALL	runtime·cgocallbackg(SB)
+	MOVQ	0(SP), R8
+
+	// Restore g->sched (== m->curg->sched) from saved values.
+	get_tls(CX)
+	MOVQ	g(CX), SI
+	MOVQ	8(SP), BP
+	MOVQ	BP, (g_sched+gobuf_pc)(SI)
+	LEAQ	(8+8)(SP), DI
+	MOVQ	DI, (g_sched+gobuf_sp)(SI)
+
+	// Switch back to m->g0's stack and restore m->g0->sched.sp.
+	// (Unlike m->curg, the g0 goroutine never uses sched.pc,
+	// so we do not have to restore it.)
+	MOVQ	g(CX), BP
+	MOVQ	g_m(BP), BP
+	MOVQ	m_g0(BP), SI
+	MOVQ	SI, g(CX)
+	MOVQ	(g_sched+gobuf_sp)(SI), SP
+	MOVQ	0(SP), AX
+	MOVQ	AX, (g_sched+gobuf_sp)(SI)
+	
+	// If the m on entry was nil, we called needm above to borrow an m
+	// for the duration of the call. Since the call is over, return it with dropm.
+	CMPQ	R8, $0
+	JNE 3(PC)
+	MOVQ	$runtime·dropm(SB), AX
+	CALL	AX
+
+	// Done!
+	RET
+
+// void setg(G*); set g. for use by needm.
+TEXT runtime·setg(SB), NOSPLIT, $0-8
+	MOVQ	gg+0(FP), BX
+#ifdef GOOS_windows
+	CMPQ	BX, $0
+	JNE	settls
+	MOVQ	$0, 0x28(GS)
+	RET
+settls:
+	MOVQ	g_m(BX), AX
+	LEAQ	m_tls(AX), AX
+	MOVQ	AX, 0x28(GS)
+#endif
+	get_tls(CX)
+	MOVQ	BX, g(CX)
+	RET
+
+// void setg_gcc(G*); set g called from gcc.
+TEXT setg_gcc<>(SB),NOSPLIT,$0
+	get_tls(AX)
+	MOVQ	DI, g(AX)
+	RET
+
+// check that SP is in range [g->stack.lo, g->stack.hi)
+TEXT runtime·stackcheck(SB), NOSPLIT, $0-0
+	get_tls(CX)
+	MOVQ	g(CX), AX
+	CMPQ	(g_stack+stack_hi)(AX), SP
+	JHI	2(PC)
+	INT	$3
+	CMPQ	SP, (g_stack+stack_lo)(AX)
+	JHI	2(PC)
+	INT	$3
+	RET
+
+TEXT runtime·getcallerpc(SB),NOSPLIT,$0-16
+	MOVQ	argp+0(FP),AX		// addr of first arg
+	MOVQ	-8(AX),AX		// get calling pc
+	MOVQ	AX, ret+8(FP)
+	RET
+
+TEXT runtime·gogetcallerpc(SB),NOSPLIT,$0-16
+	MOVQ	p+0(FP),AX		// addr of first arg
+	MOVQ	-8(AX),AX		// get calling pc
+	MOVQ	AX,ret+8(FP)
+	RET
+
+TEXT runtime·setcallerpc(SB),NOSPLIT,$0-16
+	MOVQ	argp+0(FP),AX		// addr of first arg
+	MOVQ	pc+8(FP), BX
+	MOVQ	BX, -8(AX)		// set calling pc
+	RET
+
+TEXT runtime·getcallersp(SB),NOSPLIT,$0-16
+	MOVQ	argp+0(FP), AX
+	MOVQ	AX, ret+8(FP)
+	RET
+
+// func gogetcallersp(p unsafe.Pointer) uintptr
+TEXT runtime·gogetcallersp(SB),NOSPLIT,$0-16
+	MOVQ	p+0(FP),AX		// addr of first arg
+	MOVQ	AX, ret+8(FP)
+	RET
+
+// int64 runtime·cputicks(void)
+TEXT runtime·cputicks(SB),NOSPLIT,$0-0
+	RDTSC
+	SHLQ	$32, DX
+	ADDQ	DX, AX
+	MOVQ	AX, ret+0(FP)
+	RET
+
+// hash function using AES hardware instructions
+TEXT runtime·aeshash(SB),NOSPLIT,$0-32
+	MOVQ	p+0(FP), AX	// ptr to data
+	MOVQ	s+8(FP), CX	// size
+	JMP	runtime·aeshashbody(SB)
+
+TEXT runtime·aeshashstr(SB),NOSPLIT,$0-32
+	MOVQ	p+0(FP), AX	// ptr to string struct
+	// s+8(FP) is ignored, it is always sizeof(String)
+	MOVQ	8(AX), CX	// length of string
+	MOVQ	(AX), AX	// string data
+	JMP	runtime·aeshashbody(SB)
+
+// AX: data
+// CX: length
+TEXT runtime·aeshashbody(SB),NOSPLIT,$0-32
+	MOVQ	h+16(FP), X0	// seed to low 64 bits of xmm0
+	PINSRQ	$1, CX, X0	// size to high 64 bits of xmm0
+	MOVO	runtime·aeskeysched+0(SB), X2
+	MOVO	runtime·aeskeysched+16(SB), X3
+	CMPQ	CX, $16
+	JB	aessmall
+aesloop:
+	CMPQ	CX, $16
+	JBE	aesloopend
+	MOVOU	(AX), X1
+	AESENC	X2, X0
+	AESENC	X1, X0
+	SUBQ	$16, CX
+	ADDQ	$16, AX
+	JMP	aesloop
+// 1-16 bytes remaining
+aesloopend:
+	// This load may overlap with the previous load above.
+	// We'll hash some bytes twice, but that's ok.
+	MOVOU	-16(AX)(CX*1), X1
+	JMP	partial
+// 0-15 bytes
+aessmall:
+	TESTQ	CX, CX
+	JE	finalize	// 0 bytes
+
+	CMPB	AX, $0xf0
+	JA	highpartial
+
+	// 16 bytes loaded at this address won't cross
+	// a page boundary, so we can load it directly.
+	MOVOU	(AX), X1
+	ADDQ	CX, CX
+	MOVQ	$masks<>(SB), BP
+	PAND	(BP)(CX*8), X1
+	JMP	partial
+highpartial:
+	// address ends in 1111xxxx.  Might be up against
+	// a page boundary, so load ending at last byte.
+	// Then shift bytes down using pshufb.
+	MOVOU	-16(AX)(CX*1), X1
+	ADDQ	CX, CX
+	MOVQ	$shifts<>(SB), BP
+	PSHUFB	(BP)(CX*8), X1
+partial:
+	// incorporate partial block into hash
+	AESENC	X3, X0
+	AESENC	X1, X0
+finalize:	
+	// finalize hash
+	AESENC	X2, X0
+	AESENC	X3, X0
+	AESENC	X2, X0
+	MOVQ	X0, res+24(FP)
+	RET
+
+TEXT runtime·aeshash32(SB),NOSPLIT,$0-32
+	MOVQ	p+0(FP), AX	// ptr to data
+	// s+8(FP) is ignored, it is always sizeof(int32)
+	MOVQ	h+16(FP), X0	// seed
+	PINSRD	$2, (AX), X0	// data
+	AESENC	runtime·aeskeysched+0(SB), X0
+	AESENC	runtime·aeskeysched+16(SB), X0
+	AESENC	runtime·aeskeysched+0(SB), X0
+	MOVQ	X0, ret+24(FP)
+	RET
+
+TEXT runtime·aeshash64(SB),NOSPLIT,$0-32
+	MOVQ	p+0(FP), AX	// ptr to data
+	// s+8(FP) is ignored, it is always sizeof(int64)
+	MOVQ	h+16(FP), X0	// seed
+	PINSRQ	$1, (AX), X0	// data
+	AESENC	runtime·aeskeysched+0(SB), X0
+	AESENC	runtime·aeskeysched+16(SB), X0
+	AESENC	runtime·aeskeysched+0(SB), X0
+	MOVQ	X0, ret+24(FP)
+	RET
+
+// simple mask to get rid of data in the high part of the register.
+DATA masks<>+0x00(SB)/8, $0x0000000000000000
+DATA masks<>+0x08(SB)/8, $0x0000000000000000
+DATA masks<>+0x10(SB)/8, $0x00000000000000ff
+DATA masks<>+0x18(SB)/8, $0x0000000000000000
+DATA masks<>+0x20(SB)/8, $0x000000000000ffff
+DATA masks<>+0x28(SB)/8, $0x0000000000000000
+DATA masks<>+0x30(SB)/8, $0x0000000000ffffff
+DATA masks<>+0x38(SB)/8, $0x0000000000000000
+DATA masks<>+0x40(SB)/8, $0x00000000ffffffff
+DATA masks<>+0x48(SB)/8, $0x0000000000000000
+DATA masks<>+0x50(SB)/8, $0x000000ffffffffff
+DATA masks<>+0x58(SB)/8, $0x0000000000000000
+DATA masks<>+0x60(SB)/8, $0x0000ffffffffffff
+DATA masks<>+0x68(SB)/8, $0x0000000000000000
+DATA masks<>+0x70(SB)/8, $0x00ffffffffffffff
+DATA masks<>+0x78(SB)/8, $0x0000000000000000
+DATA masks<>+0x80(SB)/8, $0xffffffffffffffff
+DATA masks<>+0x88(SB)/8, $0x0000000000000000
+DATA masks<>+0x90(SB)/8, $0xffffffffffffffff
+DATA masks<>+0x98(SB)/8, $0x00000000000000ff
+DATA masks<>+0xa0(SB)/8, $0xffffffffffffffff
+DATA masks<>+0xa8(SB)/8, $0x000000000000ffff
+DATA masks<>+0xb0(SB)/8, $0xffffffffffffffff
+DATA masks<>+0xb8(SB)/8, $0x0000000000ffffff
+DATA masks<>+0xc0(SB)/8, $0xffffffffffffffff
+DATA masks<>+0xc8(SB)/8, $0x00000000ffffffff
+DATA masks<>+0xd0(SB)/8, $0xffffffffffffffff
+DATA masks<>+0xd8(SB)/8, $0x000000ffffffffff
+DATA masks<>+0xe0(SB)/8, $0xffffffffffffffff
+DATA masks<>+0xe8(SB)/8, $0x0000ffffffffffff
+DATA masks<>+0xf0(SB)/8, $0xffffffffffffffff
+DATA masks<>+0xf8(SB)/8, $0x00ffffffffffffff
+GLOBL masks<>(SB),RODATA,$256
+
+// these are arguments to pshufb.  They move data down from
+// the high bytes of the register to the low bytes of the register.
+// index is how many bytes to move.
+DATA shifts<>+0x00(SB)/8, $0x0000000000000000
+DATA shifts<>+0x08(SB)/8, $0x0000000000000000
+DATA shifts<>+0x10(SB)/8, $0xffffffffffffff0f
+DATA shifts<>+0x18(SB)/8, $0xffffffffffffffff
+DATA shifts<>+0x20(SB)/8, $0xffffffffffff0f0e
+DATA shifts<>+0x28(SB)/8, $0xffffffffffffffff
+DATA shifts<>+0x30(SB)/8, $0xffffffffff0f0e0d
+DATA shifts<>+0x38(SB)/8, $0xffffffffffffffff
+DATA shifts<>+0x40(SB)/8, $0xffffffff0f0e0d0c
+DATA shifts<>+0x48(SB)/8, $0xffffffffffffffff
+DATA shifts<>+0x50(SB)/8, $0xffffff0f0e0d0c0b
+DATA shifts<>+0x58(SB)/8, $0xffffffffffffffff
+DATA shifts<>+0x60(SB)/8, $0xffff0f0e0d0c0b0a
+DATA shifts<>+0x68(SB)/8, $0xffffffffffffffff
+DATA shifts<>+0x70(SB)/8, $0xff0f0e0d0c0b0a09
+DATA shifts<>+0x78(SB)/8, $0xffffffffffffffff
+DATA shifts<>+0x80(SB)/8, $0x0f0e0d0c0b0a0908
+DATA shifts<>+0x88(SB)/8, $0xffffffffffffffff
+DATA shifts<>+0x90(SB)/8, $0x0e0d0c0b0a090807
+DATA shifts<>+0x98(SB)/8, $0xffffffffffffff0f
+DATA shifts<>+0xa0(SB)/8, $0x0d0c0b0a09080706
+DATA shifts<>+0xa8(SB)/8, $0xffffffffffff0f0e
+DATA shifts<>+0xb0(SB)/8, $0x0c0b0a0908070605
+DATA shifts<>+0xb8(SB)/8, $0xffffffffff0f0e0d
+DATA shifts<>+0xc0(SB)/8, $0x0b0a090807060504
+DATA shifts<>+0xc8(SB)/8, $0xffffffff0f0e0d0c
+DATA shifts<>+0xd0(SB)/8, $0x0a09080706050403
+DATA shifts<>+0xd8(SB)/8, $0xffffff0f0e0d0c0b
+DATA shifts<>+0xe0(SB)/8, $0x0908070605040302
+DATA shifts<>+0xe8(SB)/8, $0xffff0f0e0d0c0b0a
+DATA shifts<>+0xf0(SB)/8, $0x0807060504030201
+DATA shifts<>+0xf8(SB)/8, $0xff0f0e0d0c0b0a09
+GLOBL shifts<>(SB),RODATA,$256
+
+TEXT runtime·memeq(SB),NOSPLIT,$0-25
+	MOVQ	a+0(FP), SI
+	MOVQ	b+8(FP), DI
+	MOVQ	size+16(FP), BX
+	CALL	runtime·memeqbody(SB)
+	MOVB	AX, ret+24(FP)
+	RET
+
+// eqstring tests whether two strings are equal.
+// See runtime_test.go:eqstring_generic for
+// equivalent Go code.
+TEXT runtime·eqstring(SB),NOSPLIT,$0-33
+	MOVQ	s1len+8(FP), AX
+	MOVQ	s2len+24(FP), BX
+	CMPQ	AX, BX
+	JNE	different
+	MOVQ	s1str+0(FP), SI
+	MOVQ	s2str+16(FP), DI
+	CMPQ	SI, DI
+	JEQ	same
+	CALL	runtime·memeqbody(SB)
+	MOVB	AX, v+32(FP)
+	RET
+same:
+	MOVB	$1, v+32(FP)
+	RET
+different:
+	MOVB	$0, v+32(FP)
+	RET
+
+// a in SI
+// b in DI
+// count in BX
+TEXT runtime·memeqbody(SB),NOSPLIT,$0-0
+	XORQ	AX, AX
+
+	CMPQ	BX, $8
+	JB	small
+	
+	// 64 bytes at a time using xmm registers
+hugeloop:
+	CMPQ	BX, $64
+	JB	bigloop
+	MOVOU	(SI), X0
+	MOVOU	(DI), X1
+	MOVOU	16(SI), X2
+	MOVOU	16(DI), X3
+	MOVOU	32(SI), X4
+	MOVOU	32(DI), X5
+	MOVOU	48(SI), X6
+	MOVOU	48(DI), X7
+	PCMPEQB	X1, X0
+	PCMPEQB	X3, X2
+	PCMPEQB	X5, X4
+	PCMPEQB	X7, X6
+	PAND	X2, X0
+	PAND	X6, X4
+	PAND	X4, X0
+	PMOVMSKB X0, DX
+	ADDQ	$64, SI
+	ADDQ	$64, DI
+	SUBQ	$64, BX
+	CMPL	DX, $0xffff
+	JEQ	hugeloop
+	RET
+
+	// 8 bytes at a time using 64-bit register
+bigloop:
+	CMPQ	BX, $8
+	JBE	leftover
+	MOVQ	(SI), CX
+	MOVQ	(DI), DX
+	ADDQ	$8, SI
+	ADDQ	$8, DI
+	SUBQ	$8, BX
+	CMPQ	CX, DX
+	JEQ	bigloop
+	RET
+
+	// remaining 0-8 bytes
+leftover:
+	MOVQ	-8(SI)(BX*1), CX
+	MOVQ	-8(DI)(BX*1), DX
+	CMPQ	CX, DX
+	SETEQ	AX
+	RET
+
+small:
+	CMPQ	BX, $0
+	JEQ	equal
+
+	LEAQ	0(BX*8), CX
+	NEGQ	CX
+
+	CMPB	SI, $0xf8
+	JA	si_high
+
+	// load at SI won't cross a page boundary.
+	MOVQ	(SI), SI
+	JMP	si_finish
+si_high:
+	// address ends in 11111xxx.  Load up to bytes we want, move to correct position.
+	MOVQ	-8(SI)(BX*1), SI
+	SHRQ	CX, SI
+si_finish:
+
+	// same for DI.
+	CMPB	DI, $0xf8
+	JA	di_high
+	MOVQ	(DI), DI
+	JMP	di_finish
+di_high:
+	MOVQ	-8(DI)(BX*1), DI
+	SHRQ	CX, DI
+di_finish:
+
+	SUBQ	SI, DI
+	SHLQ	CX, DI
+equal:
+	SETEQ	AX
+	RET
+
+TEXT runtime·cmpstring(SB),NOSPLIT,$0-40
+	MOVQ	s1_base+0(FP), SI
+	MOVQ	s1_len+8(FP), BX
+	MOVQ	s2_base+16(FP), DI
+	MOVQ	s2_len+24(FP), DX
+	CALL	runtime·cmpbody(SB)
+	MOVQ	AX, ret+32(FP)
+	RET
+
+TEXT runtime·cmpbytes(SB),NOSPLIT,$0-56
+	MOVQ	s1+0(FP), SI
+	MOVQ	s1+8(FP), BX
+	MOVQ	s2+24(FP), DI
+	MOVQ	s2+32(FP), DX
+	CALL	runtime·cmpbody(SB)
+	MOVQ	AX, res+48(FP)
+	RET
+
+// input:
+//   SI = a
+//   DI = b
+//   BX = alen
+//   DX = blen
+// output:
+//   AX = 1/0/-1
+TEXT runtime·cmpbody(SB),NOSPLIT,$0-0
+	CMPQ	SI, DI
+	JEQ	cmp_allsame
+	CMPQ	BX, DX
+	MOVQ	DX, BP
+	CMOVQLT	BX, BP // BP = min(alen, blen) = # of bytes to compare
+	CMPQ	BP, $8
+	JB	cmp_small
+
+cmp_loop:
+	CMPQ	BP, $16
+	JBE	cmp_0through16
+	MOVOU	(SI), X0
+	MOVOU	(DI), X1
+	PCMPEQB X0, X1
+	PMOVMSKB X1, AX
+	XORQ	$0xffff, AX	// convert EQ to NE
+	JNE	cmp_diff16	// branch if at least one byte is not equal
+	ADDQ	$16, SI
+	ADDQ	$16, DI
+	SUBQ	$16, BP
+	JMP	cmp_loop
+	
+	// AX = bit mask of differences
+cmp_diff16:
+	BSFQ	AX, BX	// index of first byte that differs
+	XORQ	AX, AX
+	MOVB	(SI)(BX*1), CX
+	CMPB	CX, (DI)(BX*1)
+	SETHI	AX
+	LEAQ	-1(AX*2), AX	// convert 1/0 to +1/-1
+	RET
+
+	// 0 through 16 bytes left, alen>=8, blen>=8
+cmp_0through16:
+	CMPQ	BP, $8
+	JBE	cmp_0through8
+	MOVQ	(SI), AX
+	MOVQ	(DI), CX
+	CMPQ	AX, CX
+	JNE	cmp_diff8
+cmp_0through8:
+	MOVQ	-8(SI)(BP*1), AX
+	MOVQ	-8(DI)(BP*1), CX
+	CMPQ	AX, CX
+	JEQ	cmp_allsame
+
+	// AX and CX contain parts of a and b that differ.
+cmp_diff8:
+	BSWAPQ	AX	// reverse order of bytes
+	BSWAPQ	CX
+	XORQ	AX, CX
+	BSRQ	CX, CX	// index of highest bit difference
+	SHRQ	CX, AX	// move a's bit to bottom
+	ANDQ	$1, AX	// mask bit
+	LEAQ	-1(AX*2), AX // 1/0 => +1/-1
+	RET
+
+	// 0-7 bytes in common
+cmp_small:
+	LEAQ	(BP*8), CX	// bytes left -> bits left
+	NEGQ	CX		//  - bits lift (== 64 - bits left mod 64)
+	JEQ	cmp_allsame
+
+	// load bytes of a into high bytes of AX
+	CMPB	SI, $0xf8
+	JA	cmp_si_high
+	MOVQ	(SI), SI
+	JMP	cmp_si_finish
+cmp_si_high:
+	MOVQ	-8(SI)(BP*1), SI
+	SHRQ	CX, SI
+cmp_si_finish:
+	SHLQ	CX, SI
+
+	// load bytes of b in to high bytes of BX
+	CMPB	DI, $0xf8
+	JA	cmp_di_high
+	MOVQ	(DI), DI
+	JMP	cmp_di_finish
+cmp_di_high:
+	MOVQ	-8(DI)(BP*1), DI
+	SHRQ	CX, DI
+cmp_di_finish:
+	SHLQ	CX, DI
+
+	BSWAPQ	SI	// reverse order of bytes
+	BSWAPQ	DI
+	XORQ	SI, DI	// find bit differences
+	JEQ	cmp_allsame
+	BSRQ	DI, CX	// index of highest bit difference
+	SHRQ	CX, SI	// move a's bit to bottom
+	ANDQ	$1, SI	// mask bit
+	LEAQ	-1(SI*2), AX // 1/0 => +1/-1
+	RET
+
+cmp_allsame:
+	XORQ	AX, AX
+	XORQ	CX, CX
+	CMPQ	BX, DX
+	SETGT	AX	// 1 if alen > blen
+	SETEQ	CX	// 1 if alen == blen
+	LEAQ	-1(CX)(AX*2), AX	// 1,0,-1 result
+	RET
+
+TEXT bytes·IndexByte(SB),NOSPLIT,$0
+	MOVQ s+0(FP), SI
+	MOVQ s_len+8(FP), BX
+	MOVB c+24(FP), AL
+	CALL runtime·indexbytebody(SB)
+	MOVQ AX, ret+32(FP)
+	RET
+
+TEXT strings·IndexByte(SB),NOSPLIT,$0
+	MOVQ s+0(FP), SI
+	MOVQ s_len+8(FP), BX
+	MOVB c+16(FP), AL
+	CALL runtime·indexbytebody(SB)
+	MOVQ AX, ret+24(FP)
+	RET
+
+// input:
+//   SI: data
+//   BX: data len
+//   AL: byte sought
+// output:
+//   AX
+TEXT runtime·indexbytebody(SB),NOSPLIT,$0
+	MOVQ SI, DI
+
+	CMPQ BX, $16
+	JLT indexbyte_small
+
+	// round up to first 16-byte boundary
+	TESTQ $15, SI
+	JZ aligned
+	MOVQ SI, CX
+	ANDQ $~15, CX
+	ADDQ $16, CX
+
+	// search the beginning
+	SUBQ SI, CX
+	REPN; SCASB
+	JZ success
+
+// DI is 16-byte aligned; get ready to search using SSE instructions
+aligned:
+	// round down to last 16-byte boundary
+	MOVQ BX, R11
+	ADDQ SI, R11
+	ANDQ $~15, R11
+
+	// shuffle X0 around so that each byte contains c
+	MOVD AX, X0
+	PUNPCKLBW X0, X0
+	PUNPCKLBW X0, X0
+	PSHUFL $0, X0, X0
+	JMP condition
+
+sse:
+	// move the next 16-byte chunk of the buffer into X1
+	MOVO (DI), X1
+	// compare bytes in X0 to X1
+	PCMPEQB X0, X1
+	// take the top bit of each byte in X1 and put the result in DX
+	PMOVMSKB X1, DX
+	TESTL DX, DX
+	JNZ ssesuccess
+	ADDQ $16, DI
+
+condition:
+	CMPQ DI, R11
+	JLT sse
+
+	// search the end
+	MOVQ SI, CX
+	ADDQ BX, CX
+	SUBQ R11, CX
+	// if CX == 0, the zero flag will be set and we'll end up
+	// returning a false success
+	JZ failure
+	REPN; SCASB
+	JZ success
+
+failure:
+	MOVQ $-1, AX
+	RET
+
+// handle for lengths < 16
+indexbyte_small:
+	MOVQ BX, CX
+	REPN; SCASB
+	JZ success
+	MOVQ $-1, AX
+	RET
+
+// we've found the chunk containing the byte
+// now just figure out which specific byte it is
+ssesuccess:
+	// get the index of the least significant set bit
+	BSFW DX, DX
+	SUBQ SI, DI
+	ADDQ DI, DX
+	MOVQ DX, AX
+	RET
+
+success:
+	SUBQ SI, DI
+	SUBL $1, DI
+	MOVQ DI, AX
+	RET
+
+TEXT bytes·Equal(SB),NOSPLIT,$0-49
+	MOVQ	a_len+8(FP), BX
+	MOVQ	b_len+32(FP), CX
+	XORQ	AX, AX
+	CMPQ	BX, CX
+	JNE	eqret
+	MOVQ	a+0(FP), SI
+	MOVQ	b+24(FP), DI
+	CALL	runtime·memeqbody(SB)
+eqret:
+	MOVB	AX, ret+48(FP)
+	RET
+
+// A Duff's device for zeroing memory.
+// The compiler jumps to computed addresses within
+// this routine to zero chunks of memory.  Do not
+// change this code without also changing the code
+// in ../../cmd/6g/ggen.c:clearfat.
+// AX: zero
+// DI: ptr to memory to be zeroed
+// DI is updated as a side effect.
+TEXT runtime·duffzero(SB), NOSPLIT, $0-0
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	STOSQ
+	RET
+
+// A Duff's device for copying memory.
+// The compiler jumps to computed addresses within
+// this routine to copy chunks of memory.  Source
+// and destination must not overlap.  Do not
+// change this code without also changing the code
+// in ../../cmd/6g/cgen.c:sgen.
+// SI: ptr to source memory
+// DI: ptr to destination memory
+// SI and DI are updated as a side effect.
+
+// NOTE: this is equivalent to a sequence of MOVSQ but
+// for some reason that is 3.5x slower than this code.
+// The STOSQ above seem fine, though.
+TEXT runtime·duffcopy(SB), NOSPLIT, $0-0
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	MOVQ	(SI),CX
+	ADDQ	$8,SI
+	MOVQ	CX,(DI)
+	ADDQ	$8,DI
+
+	RET
+
+TEXT runtime·fastrand1(SB), NOSPLIT, $0-4
+	get_tls(CX)
+	MOVQ	g(CX), AX
+	MOVQ	g_m(AX), AX
+	MOVL	m_fastrand(AX), DX
+	ADDL	DX, DX
+	MOVL	DX, BX
+	XORL	$0x88888eef, DX
+	CMOVLMI	BX, DX
+	MOVL	DX, m_fastrand(AX)
+	MOVL	DX, ret+0(FP)
+	RET
+
+TEXT runtime·return0(SB), NOSPLIT, $0
+	MOVL	$0, AX
+	RET
+
+
+// Called from cgo wrappers, this function returns g->m->curg.stack.hi.
+// Must obey the gcc calling convention.
+TEXT _cgo_topofstack(SB),NOSPLIT,$0
+	get_tls(CX)
+	MOVQ	g(CX), AX
+	MOVQ	g_m(AX), AX
+	MOVQ	m_curg(AX), AX
+	MOVQ	(g_stack+stack_hi)(AX), AX
+	RET
+
+// The top-most function running on a goroutine
+// returns to goexit+PCQuantum.
+TEXT runtime·goexit(SB),NOSPLIT,$0-0
+	BYTE	$0x90	// NOP
+	CALL	runtime·goexit1(SB)	// does not return
diff --git a/src/runtime/asm_amd64p32.s b/src/runtime/asm_amd64p32.s
new file mode 100644
index 0000000..a1116b5
--- /dev/null
+++ b/src/runtime/asm_amd64p32.s
@@ -0,0 +1,1087 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "zasm_GOOS_GOARCH.h"
+#include "funcdata.h"
+#include "textflag.h"
+
+TEXT runtime·rt0_go(SB),NOSPLIT,$0
+	// copy arguments forward on an even stack
+	MOVL	argc+0(FP), AX
+	MOVL	argv+4(FP), BX
+	MOVL	SP, CX
+	SUBL	$128, SP		// plenty of scratch
+	ANDL	$~15, CX
+	MOVL	CX, SP
+
+	MOVL	AX, 16(SP)
+	MOVL	BX, 24(SP)
+	
+	// create istack out of the given (operating system) stack.
+	MOVL	$runtime·g0(SB), DI
+	LEAL	(-64*1024+104)(SP), BX
+	MOVL	BX, g_stackguard0(DI)
+	MOVL	BX, g_stackguard1(DI)
+	MOVL	BX, (g_stack+stack_lo)(DI)
+	MOVL	SP, (g_stack+stack_hi)(DI)
+
+	// find out information about the processor we're on
+	MOVQ	$0, AX
+	CPUID
+	CMPQ	AX, $0
+	JE	nocpuinfo
+	MOVQ	$1, AX
+	CPUID
+	MOVL	CX, runtime·cpuid_ecx(SB)
+	MOVL	DX, runtime·cpuid_edx(SB)
+nocpuinfo:	
+	
+needtls:
+	LEAL	runtime·tls0(SB), DI
+	CALL	runtime·settls(SB)
+
+	// store through it, to make sure it works
+	get_tls(BX)
+	MOVQ	$0x123, g(BX)
+	MOVQ	runtime·tls0(SB), AX
+	CMPQ	AX, $0x123
+	JEQ 2(PC)
+	MOVL	AX, 0	// abort
+ok:
+	// set the per-goroutine and per-mach "registers"
+	get_tls(BX)
+	LEAL	runtime·g0(SB), CX
+	MOVL	CX, g(BX)
+	LEAL	runtime·m0(SB), AX
+
+	// save m->g0 = g0
+	MOVL	CX, m_g0(AX)
+	// save m0 to g0->m
+	MOVL	AX, g_m(CX)
+
+	CLD				// convention is D is always left cleared
+	CALL	runtime·check(SB)
+
+	MOVL	16(SP), AX		// copy argc
+	MOVL	AX, 0(SP)
+	MOVL	24(SP), AX		// copy argv
+	MOVL	AX, 4(SP)
+	CALL	runtime·args(SB)
+	CALL	runtime·osinit(SB)
+	CALL	runtime·schedinit(SB)
+
+	// create a new goroutine to start program
+	MOVL	$runtime·main·f(SB), AX	// entry
+	MOVL	$0, 0(SP)
+	MOVL	AX, 4(SP)
+	CALL	runtime·newproc(SB)
+
+	// start this M
+	CALL	runtime·mstart(SB)
+
+	MOVL	$0xf1, 0xf1  // crash
+	RET
+
+DATA	runtime·main·f+0(SB)/4,$runtime·main(SB)
+GLOBL	runtime·main·f(SB),RODATA,$4
+
+TEXT runtime·breakpoint(SB),NOSPLIT,$0-0
+	INT $3
+	RET
+
+TEXT runtime·asminit(SB),NOSPLIT,$0-0
+	// No per-thread init.
+	RET
+
+/*
+ *  go-routine
+ */
+
+// void gosave(Gobuf*)
+// save state in Gobuf; setjmp
+TEXT runtime·gosave(SB), NOSPLIT, $0-4
+	MOVL	buf+0(FP), AX	// gobuf
+	LEAL	buf+0(FP), BX	// caller's SP
+	MOVL	BX, gobuf_sp(AX)
+	MOVL	0(SP), BX		// caller's PC
+	MOVL	BX, gobuf_pc(AX)
+	MOVL	$0, gobuf_ctxt(AX)
+	MOVQ	$0, gobuf_ret(AX)
+	get_tls(CX)
+	MOVL	g(CX), BX
+	MOVL	BX, gobuf_g(AX)
+	RET
+
+// void gogo(Gobuf*)
+// restore state from Gobuf; longjmp
+TEXT runtime·gogo(SB), NOSPLIT, $0-4
+	MOVL	buf+0(FP), BX		// gobuf
+	MOVL	gobuf_g(BX), DX
+	MOVL	0(DX), CX		// make sure g != nil
+	get_tls(CX)
+	MOVL	DX, g(CX)
+	MOVL	gobuf_sp(BX), SP	// restore SP
+	MOVL	gobuf_ctxt(BX), DX
+	MOVQ	gobuf_ret(BX), AX
+	MOVL	$0, gobuf_sp(BX)	// clear to help garbage collector
+	MOVQ	$0, gobuf_ret(BX)
+	MOVL	$0, gobuf_ctxt(BX)
+	MOVL	gobuf_pc(BX), BX
+	JMP	BX
+
+// func mcall(fn func(*g))
+// Switch to m->g0's stack, call fn(g).
+// Fn must never return.  It should gogo(&g->sched)
+// to keep running g.
+TEXT runtime·mcall(SB), NOSPLIT, $0-4
+	MOVL	fn+0(FP), DI
+	
+	get_tls(CX)
+	MOVL	g(CX), AX	// save state in g->sched
+	MOVL	0(SP), BX	// caller's PC
+	MOVL	BX, (g_sched+gobuf_pc)(AX)
+	LEAL	fn+0(FP), BX	// caller's SP
+	MOVL	BX, (g_sched+gobuf_sp)(AX)
+	MOVL	AX, (g_sched+gobuf_g)(AX)
+
+	// switch to m->g0 & its stack, call fn
+	MOVL	g(CX), BX
+	MOVL	g_m(BX), BX
+	MOVL	m_g0(BX), SI
+	CMPL	SI, AX	// if g == m->g0 call badmcall
+	JNE	3(PC)
+	MOVL	$runtime·badmcall(SB), AX
+	JMP	AX
+	MOVL	SI, g(CX)	// g = m->g0
+	MOVL	(g_sched+gobuf_sp)(SI), SP	// sp = m->g0->sched.sp
+	PUSHQ	AX
+	MOVL	DI, DX
+	MOVL	0(DI), DI
+	CALL	DI
+	POPQ	AX
+	MOVL	$runtime·badmcall2(SB), AX
+	JMP	AX
+	RET
+
+// switchtoM is a dummy routine that onM leaves at the bottom
+// of the G stack.  We need to distinguish the routine that
+// lives at the bottom of the G stack from the one that lives
+// at the top of the M stack because the one at the top of
+// the M stack terminates the stack walk (see topofstack()).
+TEXT runtime·switchtoM(SB), NOSPLIT, $0-0
+	RET
+
+// func onM_signalok(fn func())
+TEXT runtime·onM_signalok(SB), NOSPLIT, $0-4
+	get_tls(CX)
+	MOVL	g(CX), AX	// AX = g
+	MOVL	g_m(AX), BX	// BX = m
+	MOVL	m_gsignal(BX), DX	// DX = gsignal
+	CMPL	AX, DX
+	JEQ	ongsignal
+	JMP	runtime·onM(SB)
+
+ongsignal:
+	MOVL	fn+0(FP), DI	// DI = fn
+	MOVL	DI, DX
+	MOVL	0(DI), DI
+	CALL	DI
+	RET
+
+// func onM(fn func())
+TEXT runtime·onM(SB), NOSPLIT, $0-4
+	MOVL	fn+0(FP), DI	// DI = fn
+	get_tls(CX)
+	MOVL	g(CX), AX	// AX = g
+	MOVL	g_m(AX), BX	// BX = m
+
+	MOVL	m_g0(BX), DX	// DX = g0
+	CMPL	AX, DX
+	JEQ	onm
+
+	MOVL	m_curg(BX), R8
+	CMPL	AX, R8
+	JEQ	oncurg
+	
+	// Not g0, not curg. Must be gsignal, but that's not allowed.
+	// Hide call from linker nosplit analysis.
+	MOVL	$runtime·badonm(SB), AX
+	CALL	AX
+
+oncurg:
+	// save our state in g->sched.  Pretend to
+	// be switchtoM if the G stack is scanned.
+	MOVL	$runtime·switchtoM(SB), SI
+	MOVL	SI, (g_sched+gobuf_pc)(AX)
+	MOVL	SP, (g_sched+gobuf_sp)(AX)
+	MOVL	AX, (g_sched+gobuf_g)(AX)
+
+	// switch to g0
+	MOVL	DX, g(CX)
+	MOVL	(g_sched+gobuf_sp)(DX), SP
+
+	// call target function
+	MOVL	DI, DX
+	MOVL	0(DI), DI
+	CALL	DI
+
+	// switch back to g
+	get_tls(CX)
+	MOVL	g(CX), AX
+	MOVL	g_m(AX), BX
+	MOVL	m_curg(BX), AX
+	MOVL	AX, g(CX)
+	MOVL	(g_sched+gobuf_sp)(AX), SP
+	MOVL	$0, (g_sched+gobuf_sp)(AX)
+	RET
+
+onm:
+	// already on m stack, just call directly
+	MOVL	DI, DX
+	MOVL	0(DI), DI
+	CALL	DI
+	RET
+
+/*
+ * support for morestack
+ */
+
+// Called during function prolog when more stack is needed.
+//
+// The traceback routines see morestack on a g0 as being
+// the top of a stack (for example, morestack calling newstack
+// calling the scheduler calling newm calling gc), so we must
+// record an argument size. For that purpose, it has no arguments.
+TEXT runtime·morestack(SB),NOSPLIT,$0-0
+	get_tls(CX)
+	MOVL	g(CX), BX
+	MOVL	g_m(BX), BX
+
+	// Cannot grow scheduler stack (m->g0).
+	MOVL	m_g0(BX), SI
+	CMPL	g(CX), SI
+	JNE	2(PC)
+	MOVL	0, AX
+
+	// Cannot grow signal stack (m->gsignal).
+	MOVL	m_gsignal(BX), SI
+	CMPL	g(CX), SI
+	JNE	2(PC)
+	MOVL	0, AX
+
+	// Called from f.
+	// Set m->morebuf to f's caller.
+	MOVL	8(SP), AX	// f's caller's PC
+	MOVL	AX, (m_morebuf+gobuf_pc)(BX)
+	LEAL	16(SP), AX	// f's caller's SP
+	MOVL	AX, (m_morebuf+gobuf_sp)(BX)
+	get_tls(CX)
+	MOVL	g(CX), SI
+	MOVL	SI, (m_morebuf+gobuf_g)(BX)
+
+	// Set g->sched to context in f.
+	MOVL	0(SP), AX // f's PC
+	MOVL	AX, (g_sched+gobuf_pc)(SI)
+	MOVL	SI, (g_sched+gobuf_g)(SI)
+	LEAL	8(SP), AX // f's SP
+	MOVL	AX, (g_sched+gobuf_sp)(SI)
+	MOVL	DX, (g_sched+gobuf_ctxt)(SI)
+
+	// Call newstack on m->g0's stack.
+	MOVL	m_g0(BX), BX
+	MOVL	BX, g(CX)
+	MOVL	(g_sched+gobuf_sp)(BX), SP
+	CALL	runtime·newstack(SB)
+	MOVL	$0, 0x1003	// crash if newstack returns
+	RET
+
+// morestack trampolines
+TEXT runtime·morestack_noctxt(SB),NOSPLIT,$0
+	MOVL	$0, DX
+	JMP	runtime·morestack(SB)
+
+// reflectcall: call a function with the given argument list
+// func call(f *FuncVal, arg *byte, argsize, retoffset uint32).
+// we don't have variable-sized frames, so we use a small number
+// of constant-sized-frame functions to encode a few bits of size in the pc.
+// Caution: ugly multiline assembly macros in your future!
+
+#define DISPATCH(NAME,MAXSIZE)		\
+	CMPL	CX, $MAXSIZE;		\
+	JA	3(PC);			\
+	MOVL	$NAME(SB), AX;		\
+	JMP	AX
+// Note: can't just "JMP NAME(SB)" - bad inlining results.
+
+TEXT ·reflectcall(SB), NOSPLIT, $0-16
+	MOVLQZX argsize+8(FP), CX
+	DISPATCH(runtime·call16, 16)
+	DISPATCH(runtime·call32, 32)
+	DISPATCH(runtime·call64, 64)
+	DISPATCH(runtime·call128, 128)
+	DISPATCH(runtime·call256, 256)
+	DISPATCH(runtime·call512, 512)
+	DISPATCH(runtime·call1024, 1024)
+	DISPATCH(runtime·call2048, 2048)
+	DISPATCH(runtime·call4096, 4096)
+	DISPATCH(runtime·call8192, 8192)
+	DISPATCH(runtime·call16384, 16384)
+	DISPATCH(runtime·call32768, 32768)
+	DISPATCH(runtime·call65536, 65536)
+	DISPATCH(runtime·call131072, 131072)
+	DISPATCH(runtime·call262144, 262144)
+	DISPATCH(runtime·call524288, 524288)
+	DISPATCH(runtime·call1048576, 1048576)
+	DISPATCH(runtime·call2097152, 2097152)
+	DISPATCH(runtime·call4194304, 4194304)
+	DISPATCH(runtime·call8388608, 8388608)
+	DISPATCH(runtime·call16777216, 16777216)
+	DISPATCH(runtime·call33554432, 33554432)
+	DISPATCH(runtime·call67108864, 67108864)
+	DISPATCH(runtime·call134217728, 134217728)
+	DISPATCH(runtime·call268435456, 268435456)
+	DISPATCH(runtime·call536870912, 536870912)
+	DISPATCH(runtime·call1073741824, 1073741824)
+	MOVL	$runtime·badreflectcall(SB), AX
+	JMP	AX
+
+#define CALLFN(NAME,MAXSIZE)			\
+TEXT NAME(SB), WRAPPER, $MAXSIZE-16;		\
+	NO_LOCAL_POINTERS;			\
+	/* copy arguments to stack */		\
+	MOVL	argptr+4(FP), SI;		\
+	MOVL	argsize+8(FP), CX;		\
+	MOVL	SP, DI;				\
+	REP;MOVSB;				\
+	/* call function */			\
+	MOVL	f+0(FP), DX;			\
+	MOVL	(DX), AX;			\
+	CALL	AX;				\
+	/* copy return values back */		\
+	MOVL	argptr+4(FP), DI;		\
+	MOVL	argsize+8(FP), CX;		\
+	MOVL	retoffset+12(FP), BX;		\
+	MOVL	SP, SI;				\
+	ADDL	BX, DI;				\
+	ADDL	BX, SI;				\
+	SUBL	BX, CX;				\
+	REP;MOVSB;				\
+	RET
+
+CALLFN(·call16, 16)
+CALLFN(·call32, 32)
+CALLFN(·call64, 64)
+CALLFN(·call128, 128)
+CALLFN(·call256, 256)
+CALLFN(·call512, 512)
+CALLFN(·call1024, 1024)
+CALLFN(·call2048, 2048)
+CALLFN(·call4096, 4096)
+CALLFN(·call8192, 8192)
+CALLFN(·call16384, 16384)
+CALLFN(·call32768, 32768)
+CALLFN(·call65536, 65536)
+CALLFN(·call131072, 131072)
+CALLFN(·call262144, 262144)
+CALLFN(·call524288, 524288)
+CALLFN(·call1048576, 1048576)
+CALLFN(·call2097152, 2097152)
+CALLFN(·call4194304, 4194304)
+CALLFN(·call8388608, 8388608)
+CALLFN(·call16777216, 16777216)
+CALLFN(·call33554432, 33554432)
+CALLFN(·call67108864, 67108864)
+CALLFN(·call134217728, 134217728)
+CALLFN(·call268435456, 268435456)
+CALLFN(·call536870912, 536870912)
+CALLFN(·call1073741824, 1073741824)
+
+// bool cas(int32 *val, int32 old, int32 new)
+// Atomically:
+//	if(*val == old){
+//		*val = new;
+//		return 1;
+//	} else
+//		return 0;
+TEXT runtime·cas(SB), NOSPLIT, $0-17
+	MOVL	ptr+0(FP), BX
+	MOVL	old+4(FP), AX
+	MOVL	new+8(FP), CX
+	LOCK
+	CMPXCHGL	CX, 0(BX)
+	JZ 4(PC)
+	MOVL	$0, AX
+	MOVB	AX, ret+16(FP)
+	RET
+	MOVL	$1, AX
+	MOVB	AX, ret+16(FP)
+	RET
+
+TEXT runtime·casuintptr(SB), NOSPLIT, $0-17
+	JMP	runtime·cas(SB)
+
+TEXT runtime·atomicloaduintptr(SB), NOSPLIT, $0-12
+	JMP	runtime·atomicload(SB)
+
+TEXT runtime·atomicloaduint(SB), NOSPLIT, $0-12
+	JMP	runtime·atomicload(SB)
+
+TEXT runtime·atomicstoreuintptr(SB), NOSPLIT, $0-12
+	JMP	runtime·atomicstore(SB)
+
+// bool	runtime·cas64(uint64 *val, uint64 old, uint64 new)
+// Atomically:
+//	if(*val == *old){
+//		*val = new;
+//		return 1;
+//	} else {
+//		return 0;
+//	}
+TEXT runtime·cas64(SB), NOSPLIT, $0-25
+	MOVL	ptr+0(FP), BX
+	MOVQ	old+8(FP), AX
+	MOVQ	new+16(FP), CX
+	LOCK
+	CMPXCHGQ	CX, 0(BX)
+	JNZ	cas64_fail
+	MOVL	$1, AX
+	MOVB	AX, ret+24(FP)
+	RET
+cas64_fail:
+	MOVL	$0, AX
+	MOVB	AX, ret+24(FP)
+	RET
+
+// bool casp(void **val, void *old, void *new)
+// Atomically:
+//	if(*val == old){
+//		*val = new;
+//		return 1;
+//	} else
+//		return 0;
+TEXT runtime·casp(SB), NOSPLIT, $0-17
+	MOVL	ptr+0(FP), BX
+	MOVL	old+4(FP), AX
+	MOVL	new+8(FP), CX
+	LOCK
+	CMPXCHGL	CX, 0(BX)
+	JZ 4(PC)
+	MOVL	$0, AX
+	MOVB	AX, ret+16(FP)
+	RET
+	MOVL	$1, AX
+	MOVB	AX, ret+16(FP)
+	RET
+
+// uint32 xadd(uint32 volatile *val, int32 delta)
+// Atomically:
+//	*val += delta;
+//	return *val;
+TEXT runtime·xadd(SB), NOSPLIT, $0-12
+	MOVL	ptr+0(FP), BX
+	MOVL	delta+4(FP), AX
+	MOVL	AX, CX
+	LOCK
+	XADDL	AX, 0(BX)
+	ADDL	CX, AX
+	MOVL	AX, ret+8(FP)
+	RET
+
+TEXT runtime·xadd64(SB), NOSPLIT, $0-24
+	MOVL	ptr+0(FP), BX
+	MOVQ	delta+8(FP), AX
+	MOVQ	AX, CX
+	LOCK
+	XADDQ	AX, 0(BX)
+	ADDQ	CX, AX
+	MOVQ	AX, ret+16(FP)
+	RET
+
+TEXT runtime·xchg(SB), NOSPLIT, $0-12
+	MOVL	ptr+0(FP), BX
+	MOVL	new+4(FP), AX
+	XCHGL	AX, 0(BX)
+	MOVL	AX, ret+8(FP)
+	RET
+
+TEXT runtime·xchg64(SB), NOSPLIT, $0-24
+	MOVL	ptr+0(FP), BX
+	MOVQ	new+8(FP), AX
+	XCHGQ	AX, 0(BX)
+	MOVQ	AX, ret+16(FP)
+	RET
+
+TEXT runtime·xchgp(SB), NOSPLIT, $0-12
+	MOVL	ptr+0(FP), BX
+	MOVL	new+4(FP), AX
+	XCHGL	AX, 0(BX)
+	MOVL	AX, ret+8(FP)
+	RET
+
+TEXT runtime·xchguintptr(SB), NOSPLIT, $0-12
+	JMP	runtime·xchg(SB)
+
+TEXT runtime·procyield(SB),NOSPLIT,$0-0
+	MOVL	cycles+0(FP), AX
+again:
+	PAUSE
+	SUBL	$1, AX
+	JNZ	again
+	RET
+
+TEXT runtime·atomicstorep(SB), NOSPLIT, $0-8
+	MOVL	ptr+0(FP), BX
+	MOVL	val+4(FP), AX
+	XCHGL	AX, 0(BX)
+	RET
+
+TEXT runtime·atomicstore(SB), NOSPLIT, $0-8
+	MOVL	ptr+0(FP), BX
+	MOVL	val+4(FP), AX
+	XCHGL	AX, 0(BX)
+	RET
+
+TEXT runtime·atomicstore64(SB), NOSPLIT, $0-16
+	MOVL	ptr+0(FP), BX
+	MOVQ	val+8(FP), AX
+	XCHGQ	AX, 0(BX)
+	RET
+
+// void	runtime·atomicor8(byte volatile*, byte);
+TEXT runtime·atomicor8(SB), NOSPLIT, $0-5
+	MOVL	ptr+0(FP), BX
+	MOVB	val+4(FP), AX
+	LOCK
+	ORB	AX, 0(BX)
+	RET
+
+// void jmpdefer(fn, sp);
+// called from deferreturn.
+// 1. pop the caller
+// 2. sub 5 bytes from the callers return
+// 3. jmp to the argument
+TEXT runtime·jmpdefer(SB), NOSPLIT, $0-8
+	MOVL	fv+0(FP), DX
+	MOVL	argp+4(FP), BX
+	LEAL	-8(BX), SP	// caller sp after CALL
+	SUBL	$5, (SP)	// return to CALL again
+	MOVL	0(DX), BX
+	JMP	BX	// but first run the deferred function
+
+// asmcgocall(void(*fn)(void*), void *arg)
+// Not implemented.
+TEXT runtime·asmcgocall(SB),NOSPLIT,$0-8
+	MOVL	0, AX
+	RET
+
+// asmcgocall(void(*fn)(void*), void *arg)
+// Not implemented.
+TEXT runtime·asmcgocall_errno(SB),NOSPLIT,$0-12
+	MOVL	0, AX
+	RET
+
+// cgocallback(void (*fn)(void*), void *frame, uintptr framesize)
+// Not implemented.
+TEXT runtime·cgocallback(SB),NOSPLIT,$0-12
+	MOVL	0, AX
+	RET
+
+// void setg(G*); set g. for use by needm.
+// Not implemented.
+TEXT runtime·setg(SB), NOSPLIT, $0-4
+	MOVL	0, AX
+	RET
+
+// check that SP is in range [g->stack.lo, g->stack.hi)
+TEXT runtime·stackcheck(SB), NOSPLIT, $0-0
+	get_tls(CX)
+	MOVL	g(CX), AX
+	CMPL	(g_stack+stack_hi)(AX), SP
+	JHI	2(PC)
+	MOVL	0, AX
+	CMPL	SP, (g_stack+stack_lo)(AX)
+	JHI	2(PC)
+	MOVL	0, AX
+	RET
+
+TEXT runtime·memclr(SB),NOSPLIT,$0-8
+	MOVL	ptr+0(FP), DI
+	MOVL	n+4(FP), CX
+	MOVQ	CX, BX
+	ANDQ	$7, BX
+	SHRQ	$3, CX
+	MOVQ	$0, AX
+	CLD
+	REP
+	STOSQ
+	MOVQ	BX, CX
+	REP
+	STOSB
+	RET
+
+TEXT runtime·getcallerpc(SB),NOSPLIT,$0-12
+	MOVL	argp+0(FP),AX		// addr of first arg
+	MOVL	-8(AX),AX		// get calling pc
+	MOVL	AX, ret+8(FP)
+	RET
+
+TEXT runtime·gogetcallerpc(SB),NOSPLIT,$0-12
+	MOVL	p+0(FP),AX		// addr of first arg
+	MOVL	-8(AX),AX		// get calling pc
+	MOVL	AX, ret+8(FP)
+	RET
+
+TEXT runtime·setcallerpc(SB),NOSPLIT,$0-8
+	MOVL	argp+0(FP),AX		// addr of first arg
+	MOVL	pc+4(FP), BX		// pc to set
+	MOVQ	BX, -8(AX)		// set calling pc
+	RET
+
+TEXT runtime·getcallersp(SB),NOSPLIT,$0-12
+	MOVL	argp+0(FP), AX
+	MOVL	AX, ret+8(FP)
+	RET
+
+// func gogetcallersp(p unsafe.Pointer) uintptr
+TEXT runtime·gogetcallersp(SB),NOSPLIT,$0-12
+	MOVL	p+0(FP),AX		// addr of first arg
+	MOVL	AX, ret+8(FP)
+	RET
+
+// int64 runtime·cputicks(void)
+TEXT runtime·cputicks(SB),NOSPLIT,$0-0
+	RDTSC
+	SHLQ	$32, DX
+	ADDQ	DX, AX
+	MOVQ	AX, ret+0(FP)
+	RET
+
+// hash function using AES hardware instructions
+// For now, our one amd64p32 system (NaCl) does not
+// support using AES instructions, so have not bothered to
+// write the implementations. Can copy and adjust the ones
+// in asm_amd64.s when the time comes.
+
+TEXT runtime·aeshash(SB),NOSPLIT,$0-20
+	MOVL	AX, ret+16(FP)
+	RET
+
+TEXT runtime·aeshashstr(SB),NOSPLIT,$0-20
+	MOVL	AX, ret+16(FP)
+	RET
+
+TEXT runtime·aeshash32(SB),NOSPLIT,$0-20
+	MOVL	AX, ret+16(FP)
+	RET
+
+TEXT runtime·aeshash64(SB),NOSPLIT,$0-20
+	MOVL	AX, ret+16(FP)
+	RET
+
+TEXT runtime·memeq(SB),NOSPLIT,$0-17
+	MOVL	a+0(FP), SI
+	MOVL	b+4(FP), DI
+	MOVL	size+8(FP), BX
+	CALL	runtime·memeqbody(SB)
+	MOVB	AX, ret+16(FP)
+	RET
+
+// eqstring tests whether two strings are equal.
+// See runtime_test.go:eqstring_generic for
+// equivalent Go code.
+TEXT runtime·eqstring(SB),NOSPLIT,$0-17
+	MOVL	s1len+4(FP), AX
+	MOVL	s2len+12(FP), BX
+	CMPL	AX, BX
+	JNE	different
+	MOVL	s1str+0(FP), SI
+	MOVL	s2str+8(FP), DI
+	CMPL	SI, DI
+	JEQ	same
+	CALL	runtime·memeqbody(SB)
+	MOVB	AX, v+16(FP)
+	RET
+same:
+	MOVB	$1, v+16(FP)
+	RET
+different:
+	MOVB	$0, v+16(FP)
+	RET
+
+// a in SI
+// b in DI
+// count in BX
+TEXT runtime·memeqbody(SB),NOSPLIT,$0-0
+	XORQ	AX, AX
+
+	CMPQ	BX, $8
+	JB	small
+	
+	// 64 bytes at a time using xmm registers
+hugeloop:
+	CMPQ	BX, $64
+	JB	bigloop
+	MOVOU	(SI), X0
+	MOVOU	(DI), X1
+	MOVOU	16(SI), X2
+	MOVOU	16(DI), X3
+	MOVOU	32(SI), X4
+	MOVOU	32(DI), X5
+	MOVOU	48(SI), X6
+	MOVOU	48(DI), X7
+	PCMPEQB	X1, X0
+	PCMPEQB	X3, X2
+	PCMPEQB	X5, X4
+	PCMPEQB	X7, X6
+	PAND	X2, X0
+	PAND	X6, X4
+	PAND	X4, X0
+	PMOVMSKB X0, DX
+	ADDQ	$64, SI
+	ADDQ	$64, DI
+	SUBQ	$64, BX
+	CMPL	DX, $0xffff
+	JEQ	hugeloop
+	RET
+
+	// 8 bytes at a time using 64-bit register
+bigloop:
+	CMPQ	BX, $8
+	JBE	leftover
+	MOVQ	(SI), CX
+	MOVQ	(DI), DX
+	ADDQ	$8, SI
+	ADDQ	$8, DI
+	SUBQ	$8, BX
+	CMPQ	CX, DX
+	JEQ	bigloop
+	RET
+
+	// remaining 0-8 bytes
+leftover:
+	ADDQ	BX, SI
+	ADDQ	BX, DI
+	MOVQ	-8(SI), CX
+	MOVQ	-8(DI), DX
+	CMPQ	CX, DX
+	SETEQ	AX
+	RET
+
+small:
+	CMPQ	BX, $0
+	JEQ	equal
+
+	LEAQ	0(BX*8), CX
+	NEGQ	CX
+
+	CMPB	SI, $0xf8
+	JA	si_high
+
+	// load at SI won't cross a page boundary.
+	MOVQ	(SI), SI
+	JMP	si_finish
+si_high:
+	// address ends in 11111xxx.  Load up to bytes we want, move to correct position.
+	MOVQ	BX, DX
+	ADDQ	SI, DX
+	MOVQ	-8(DX), SI
+	SHRQ	CX, SI
+si_finish:
+
+	// same for DI.
+	CMPB	DI, $0xf8
+	JA	di_high
+	MOVQ	(DI), DI
+	JMP	di_finish
+di_high:
+	MOVQ	BX, DX
+	ADDQ	DI, DX
+	MOVQ	-8(DX), DI
+	SHRQ	CX, DI
+di_finish:
+
+	SUBQ	SI, DI
+	SHLQ	CX, DI
+equal:
+	SETEQ	AX
+	RET
+
+TEXT runtime·cmpstring(SB),NOSPLIT,$0-20
+	MOVL	s1_base+0(FP), SI
+	MOVL	s1_len+4(FP), BX
+	MOVL	s2_base+8(FP), DI
+	MOVL	s2_len+12(FP), DX
+	CALL	runtime·cmpbody(SB)
+	MOVL	AX, ret+16(FP)
+	RET
+
+TEXT runtime·cmpbytes(SB),NOSPLIT,$0-28
+	MOVL	s1+0(FP), SI
+	MOVL	s1+4(FP), BX
+	MOVL	s2+12(FP), DI
+	MOVL	s2+16(FP), DX
+	CALL	runtime·cmpbody(SB)
+	MOVQ	AX, res+24(FP)
+	RET
+
+// input:
+//   SI = a
+//   DI = b
+//   BX = alen
+//   DX = blen
+// output:
+//   AX = 1/0/-1
+TEXT runtime·cmpbody(SB),NOSPLIT,$0-0
+	CMPQ	SI, DI
+	JEQ	cmp_allsame
+	CMPQ	BX, DX
+	MOVQ	DX, R8
+	CMOVQLT	BX, R8 // R8 = min(alen, blen) = # of bytes to compare
+	CMPQ	R8, $8
+	JB	cmp_small
+
+cmp_loop:
+	CMPQ	R8, $16
+	JBE	cmp_0through16
+	MOVOU	(SI), X0
+	MOVOU	(DI), X1
+	PCMPEQB X0, X1
+	PMOVMSKB X1, AX
+	XORQ	$0xffff, AX	// convert EQ to NE
+	JNE	cmp_diff16	// branch if at least one byte is not equal
+	ADDQ	$16, SI
+	ADDQ	$16, DI
+	SUBQ	$16, R8
+	JMP	cmp_loop
+	
+	// AX = bit mask of differences
+cmp_diff16:
+	BSFQ	AX, BX	// index of first byte that differs
+	XORQ	AX, AX
+	ADDQ	BX, SI
+	MOVB	(SI), CX
+	ADDQ	BX, DI
+	CMPB	CX, (DI)
+	SETHI	AX
+	LEAQ	-1(AX*2), AX	// convert 1/0 to +1/-1
+	RET
+
+	// 0 through 16 bytes left, alen>=8, blen>=8
+cmp_0through16:
+	CMPQ	R8, $8
+	JBE	cmp_0through8
+	MOVQ	(SI), AX
+	MOVQ	(DI), CX
+	CMPQ	AX, CX
+	JNE	cmp_diff8
+cmp_0through8:
+	ADDQ	R8, SI
+	ADDQ	R8, DI
+	MOVQ	-8(SI), AX
+	MOVQ	-8(DI), CX
+	CMPQ	AX, CX
+	JEQ	cmp_allsame
+
+	// AX and CX contain parts of a and b that differ.
+cmp_diff8:
+	BSWAPQ	AX	// reverse order of bytes
+	BSWAPQ	CX
+	XORQ	AX, CX
+	BSRQ	CX, CX	// index of highest bit difference
+	SHRQ	CX, AX	// move a's bit to bottom
+	ANDQ	$1, AX	// mask bit
+	LEAQ	-1(AX*2), AX // 1/0 => +1/-1
+	RET
+
+	// 0-7 bytes in common
+cmp_small:
+	LEAQ	(R8*8), CX	// bytes left -> bits left
+	NEGQ	CX		//  - bits lift (== 64 - bits left mod 64)
+	JEQ	cmp_allsame
+
+	// load bytes of a into high bytes of AX
+	CMPB	SI, $0xf8
+	JA	cmp_si_high
+	MOVQ	(SI), SI
+	JMP	cmp_si_finish
+cmp_si_high:
+	ADDQ	R8, SI
+	MOVQ	-8(SI), SI
+	SHRQ	CX, SI
+cmp_si_finish:
+	SHLQ	CX, SI
+
+	// load bytes of b in to high bytes of BX
+	CMPB	DI, $0xf8
+	JA	cmp_di_high
+	MOVQ	(DI), DI
+	JMP	cmp_di_finish
+cmp_di_high:
+	ADDQ	R8, DI
+	MOVQ	-8(DI), DI
+	SHRQ	CX, DI
+cmp_di_finish:
+	SHLQ	CX, DI
+
+	BSWAPQ	SI	// reverse order of bytes
+	BSWAPQ	DI
+	XORQ	SI, DI	// find bit differences
+	JEQ	cmp_allsame
+	BSRQ	DI, CX	// index of highest bit difference
+	SHRQ	CX, SI	// move a's bit to bottom
+	ANDQ	$1, SI	// mask bit
+	LEAQ	-1(SI*2), AX // 1/0 => +1/-1
+	RET
+
+cmp_allsame:
+	XORQ	AX, AX
+	XORQ	CX, CX
+	CMPQ	BX, DX
+	SETGT	AX	// 1 if alen > blen
+	SETEQ	CX	// 1 if alen == blen
+	LEAQ	-1(CX)(AX*2), AX	// 1,0,-1 result
+	RET
+
+TEXT bytes·IndexByte(SB),NOSPLIT,$0
+	MOVL s+0(FP), SI
+	MOVL s_len+4(FP), BX
+	MOVB c+12(FP), AL
+	CALL runtime·indexbytebody(SB)
+	MOVL AX, ret+16(FP)
+	RET
+
+TEXT strings·IndexByte(SB),NOSPLIT,$0
+	MOVL s+0(FP), SI
+	MOVL s_len+4(FP), BX
+	MOVB c+8(FP), AL
+	CALL runtime·indexbytebody(SB)
+	MOVL AX, ret+16(FP)
+	RET
+
+// input:
+//   SI: data
+//   BX: data len
+//   AL: byte sought
+// output:
+//   AX
+TEXT runtime·indexbytebody(SB),NOSPLIT,$0
+	MOVL SI, DI
+
+	CMPL BX, $16
+	JLT indexbyte_small
+
+	// round up to first 16-byte boundary
+	TESTL $15, SI
+	JZ aligned
+	MOVL SI, CX
+	ANDL $~15, CX
+	ADDL $16, CX
+
+	// search the beginning
+	SUBL SI, CX
+	REPN; SCASB
+	JZ success
+
+// DI is 16-byte aligned; get ready to search using SSE instructions
+aligned:
+	// round down to last 16-byte boundary
+	MOVL BX, R11
+	ADDL SI, R11
+	ANDL $~15, R11
+
+	// shuffle X0 around so that each byte contains c
+	MOVD AX, X0
+	PUNPCKLBW X0, X0
+	PUNPCKLBW X0, X0
+	PSHUFL $0, X0, X0
+	JMP condition
+
+sse:
+	// move the next 16-byte chunk of the buffer into X1
+	MOVO (DI), X1
+	// compare bytes in X0 to X1
+	PCMPEQB X0, X1
+	// take the top bit of each byte in X1 and put the result in DX
+	PMOVMSKB X1, DX
+	TESTL DX, DX
+	JNZ ssesuccess
+	ADDL $16, DI
+
+condition:
+	CMPL DI, R11
+	JLT sse
+
+	// search the end
+	MOVL SI, CX
+	ADDL BX, CX
+	SUBL R11, CX
+	// if CX == 0, the zero flag will be set and we'll end up
+	// returning a false success
+	JZ failure
+	REPN; SCASB
+	JZ success
+
+failure:
+	MOVL $-1, AX
+	RET
+
+// handle for lengths < 16
+indexbyte_small:
+	MOVL BX, CX
+	REPN; SCASB
+	JZ success
+	MOVL $-1, AX
+	RET
+
+// we've found the chunk containing the byte
+// now just figure out which specific byte it is
+ssesuccess:
+	// get the index of the least significant set bit
+	BSFW DX, DX
+	SUBL SI, DI
+	ADDL DI, DX
+	MOVL DX, AX
+	RET
+
+success:
+	SUBL SI, DI
+	SUBL $1, DI
+	MOVL DI, AX
+	RET
+
+TEXT bytes·Equal(SB),NOSPLIT,$0-25
+	MOVL	a_len+4(FP), BX
+	MOVL	b_len+16(FP), CX
+	XORL	AX, AX
+	CMPL	BX, CX
+	JNE	eqret
+	MOVL	a+0(FP), SI
+	MOVL	b+12(FP), DI
+	CALL	runtime·memeqbody(SB)
+eqret:
+	MOVB	AX, ret+24(FP)
+	RET
+
+TEXT runtime·fastrand1(SB), NOSPLIT, $0-4
+	get_tls(CX)
+	MOVL	g(CX), AX
+	MOVL	g_m(AX), AX
+	MOVL	m_fastrand(AX), DX
+	ADDL	DX, DX
+	MOVL	DX, BX
+	XORL	$0x88888eef, DX
+	CMOVLMI	BX, DX
+	MOVL	DX, m_fastrand(AX)
+	MOVL	DX, ret+0(FP)
+	RET
+
+TEXT runtime·return0(SB), NOSPLIT, $0
+	MOVL	$0, AX
+	RET
+
+// The top-most function running on a goroutine
+// returns to goexit+PCQuantum.
+TEXT runtime·goexit(SB),NOSPLIT,$0-0
+	BYTE	$0x90	// NOP
+	CALL	runtime·goexit1(SB)	// does not return
diff --git a/src/runtime/asm_arm.s b/src/runtime/asm_arm.s
new file mode 100644
index 0000000..0f3b5ee
--- /dev/null
+++ b/src/runtime/asm_arm.s
@@ -0,0 +1,1328 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "zasm_GOOS_GOARCH.h"
+#include "funcdata.h"
+#include "textflag.h"
+
+// using frame size $-4 means do not save LR on stack.
+TEXT runtime·rt0_go(SB),NOSPLIT,$-4
+	MOVW	$0xcafebabe, R12
+
+	// copy arguments forward on an even stack
+	// use R13 instead of SP to avoid linker rewriting the offsets
+	MOVW	0(R13), R0		// argc
+	MOVW	4(R13), R1		// argv
+	SUB	$64, R13		// plenty of scratch
+	AND	$~7, R13
+	MOVW	R0, 60(R13)		// save argc, argv away
+	MOVW	R1, 64(R13)
+
+	// set up g register
+	// g is R10
+	MOVW	$runtime·g0(SB), g
+	MOVW	$runtime·m0(SB), R8
+
+	// save m->g0 = g0
+	MOVW	g, m_g0(R8)
+	// save g->m = m0
+	MOVW	R8, g_m(g)
+
+	// create istack out of the OS stack
+	MOVW	$(-8192+104)(R13), R0
+	MOVW	R0, g_stackguard0(g)
+	MOVW	R0, g_stackguard1(g)
+	MOVW	R0, (g_stack+stack_lo)(g)
+	MOVW	R13, (g_stack+stack_hi)(g)
+
+	BL	runtime·emptyfunc(SB)	// fault if stack check is wrong
+
+#ifndef GOOS_nacl
+	// if there is an _cgo_init, call it.
+	MOVW	_cgo_init(SB), R4
+	CMP	$0, R4
+	B.EQ	nocgo
+	MRC     15, 0, R0, C13, C0, 3 	// load TLS base pointer
+	MOVW 	R0, R3 			// arg 3: TLS base pointer
+	MOVW 	$runtime·tlsg(SB), R2 	// arg 2: tlsg
+	MOVW	$setg_gcc<>(SB), R1 	// arg 1: setg
+	MOVW	g, R0 			// arg 0: G
+	BL	(R4) // will clobber R0-R3
+#endif
+
+nocgo:
+	// update stackguard after _cgo_init
+	MOVW	(g_stack+stack_lo)(g), R0
+	ADD	$const_StackGuard, R0
+	MOVW	R0, g_stackguard0(g)
+	MOVW	R0, g_stackguard1(g)
+
+	BL	runtime·checkgoarm(SB)
+	BL	runtime·check(SB)
+
+	// saved argc, argv
+	MOVW	60(R13), R0
+	MOVW	R0, 4(R13)
+	MOVW	64(R13), R1
+	MOVW	R1, 8(R13)
+	BL	runtime·args(SB)
+	BL	runtime·osinit(SB)
+	BL	runtime·schedinit(SB)
+
+	// create a new goroutine to start program
+	MOVW	$runtime·main·f(SB), R0
+	MOVW.W	R0, -4(R13)
+	MOVW	$8, R0
+	MOVW.W	R0, -4(R13)
+	MOVW	$0, R0
+	MOVW.W	R0, -4(R13)	// push $0 as guard
+	BL	runtime·newproc(SB)
+	MOVW	$12(R13), R13	// pop args and LR
+
+	// start this M
+	BL	runtime·mstart(SB)
+
+	MOVW	$1234, R0
+	MOVW	$1000, R1
+	MOVW	R0, (R1)	// fail hard
+
+DATA	runtime·main·f+0(SB)/4,$runtime·main(SB)
+GLOBL	runtime·main·f(SB),RODATA,$4
+
+TEXT runtime·breakpoint(SB),NOSPLIT,$0-0
+	// gdb won't skip this breakpoint instruction automatically,
+	// so you must manually "set $pc+=4" to skip it and continue.
+#ifdef GOOS_nacl
+	WORD	$0xe125be7f	// BKPT 0x5bef, NACL_INSTR_ARM_BREAKPOINT
+#else
+	WORD	$0xe7f001f0	// undefined instruction that gdb understands is a software breakpoint
+#endif
+	RET
+
+TEXT runtime·asminit(SB),NOSPLIT,$0-0
+	// disable runfast (flush-to-zero) mode of vfp if runtime.goarm > 5
+	MOVB	runtime·goarm(SB), R11
+	CMP	$5, R11
+	BLE	4(PC)
+	WORD	$0xeef1ba10	// vmrs r11, fpscr
+	BIC	$(1<<24), R11
+	WORD	$0xeee1ba10	// vmsr fpscr, r11
+	RET
+
+/*
+ *  go-routine
+ */
+
+// void gosave(Gobuf*)
+// save state in Gobuf; setjmp
+TEXT runtime·gosave(SB),NOSPLIT,$-4-4
+	MOVW	0(FP), R0		// gobuf
+	MOVW	SP, gobuf_sp(R0)
+	MOVW	LR, gobuf_pc(R0)
+	MOVW	g, gobuf_g(R0)
+	MOVW	$0, R11
+	MOVW	R11, gobuf_lr(R0)
+	MOVW	R11, gobuf_ret(R0)
+	MOVW	R11, gobuf_ctxt(R0)
+	RET
+
+// void gogo(Gobuf*)
+// restore state from Gobuf; longjmp
+TEXT runtime·gogo(SB),NOSPLIT,$-4-4
+	MOVW	0(FP), R1		// gobuf
+	MOVW	gobuf_g(R1), R0
+	BL	setg<>(SB)
+
+	// NOTE: We updated g above, and we are about to update SP.
+	// Until LR and PC are also updated, the g/SP/LR/PC quadruple
+	// are out of sync and must not be used as the basis of a traceback.
+	// Sigprof skips the traceback when SP is not within g's bounds,
+	// and when the PC is inside this function, runtime.gogo.
+	// Since we are about to update SP, until we complete runtime.gogo
+	// we must not leave this function. In particular, no calls
+	// after this point: it must be straight-line code until the
+	// final B instruction.
+	// See large comment in sigprof for more details.
+	MOVW	gobuf_sp(R1), SP	// restore SP
+	MOVW	gobuf_lr(R1), LR
+	MOVW	gobuf_ret(R1), R0
+	MOVW	gobuf_ctxt(R1), R7
+	MOVW	$0, R11
+	MOVW	R11, gobuf_sp(R1)	// clear to help garbage collector
+	MOVW	R11, gobuf_ret(R1)
+	MOVW	R11, gobuf_lr(R1)
+	MOVW	R11, gobuf_ctxt(R1)
+	MOVW	gobuf_pc(R1), R11
+	CMP	R11, R11 // set condition codes for == test, needed by stack split
+	B	(R11)
+
+// func mcall(fn func(*g))
+// Switch to m->g0's stack, call fn(g).
+// Fn must never return.  It should gogo(&g->sched)
+// to keep running g.
+TEXT runtime·mcall(SB),NOSPLIT,$-4-4
+	// Save caller state in g->sched.
+	MOVW	SP, (g_sched+gobuf_sp)(g)
+	MOVW	LR, (g_sched+gobuf_pc)(g)
+	MOVW	$0, R11
+	MOVW	R11, (g_sched+gobuf_lr)(g)
+	MOVW	g, (g_sched+gobuf_g)(g)
+
+	// Switch to m->g0 & its stack, call fn.
+	MOVW	g, R1
+	MOVW	g_m(g), R8
+	MOVW	m_g0(R8), R0
+	BL	setg<>(SB)
+	CMP	g, R1
+	B.NE	2(PC)
+	B	runtime·badmcall(SB)
+	MOVB	runtime·iscgo(SB), R11
+	CMP	$0, R11
+	BL.NE	runtime·save_g(SB)
+	MOVW	fn+0(FP), R0
+	MOVW	(g_sched+gobuf_sp)(g), SP
+	SUB	$8, SP
+	MOVW	R1, 4(SP)
+	MOVW	R0, R7
+	MOVW	0(R0), R0
+	BL	(R0)
+	B	runtime·badmcall2(SB)
+	RET
+
+// switchtoM is a dummy routine that onM leaves at the bottom
+// of the G stack.  We need to distinguish the routine that
+// lives at the bottom of the G stack from the one that lives
+// at the top of the M stack because the one at the top of
+// the M stack terminates the stack walk (see topofstack()).
+TEXT runtime·switchtoM(SB),NOSPLIT,$0-0
+	MOVW	$0, R0
+	BL	(R0) // clobber lr to ensure push {lr} is kept
+	RET
+
+// func onM_signalok(fn func())
+TEXT runtime·onM_signalok(SB), NOSPLIT, $-4-4
+	MOVW	g_m(g), R1
+	MOVW	m_gsignal(R1), R2
+	CMP	g, R2
+	B.EQ	ongsignal
+	B	runtime·onM(SB)
+
+ongsignal:
+	MOVW	fn+0(FP), R0
+	MOVW	R0, R7
+	MOVW	0(R0), R0
+	BL	(R0)
+	RET
+
+// func onM(fn func())
+TEXT runtime·onM(SB),NOSPLIT,$0-4
+	MOVW	fn+0(FP), R0	// R0 = fn
+	MOVW	g_m(g), R1	// R1 = m
+
+	MOVW	m_g0(R1), R2	// R2 = g0
+	CMP	g, R2
+	B.EQ	onm
+
+	MOVW	m_curg(R1), R3
+	CMP	g, R3
+	B.EQ	oncurg
+
+	// Not g0, not curg. Must be gsignal, but that's not allowed.
+	// Hide call from linker nosplit analysis.
+	MOVW	$runtime·badonm(SB), R0
+	BL	(R0)
+
+oncurg:
+	// save our state in g->sched.  Pretend to
+	// be switchtoM if the G stack is scanned.
+	MOVW	$runtime·switchtoM(SB), R3
+	ADD	$4, R3, R3 // get past push {lr}
+	MOVW	R3, (g_sched+gobuf_pc)(g)
+	MOVW	SP, (g_sched+gobuf_sp)(g)
+	MOVW	LR, (g_sched+gobuf_lr)(g)
+	MOVW	g, (g_sched+gobuf_g)(g)
+
+	// switch to g0
+	MOVW	R0, R5
+	MOVW	R2, R0
+	BL	setg<>(SB)
+	MOVW	R5, R0
+	MOVW	(g_sched+gobuf_sp)(R2), R3
+	// make it look like mstart called onM on g0, to stop traceback
+	SUB	$4, R3, R3
+	MOVW	$runtime·mstart(SB), R4
+	MOVW	R4, 0(R3)
+	MOVW	R3, SP
+
+	// call target function
+	MOVW	R0, R7
+	MOVW	0(R0), R0
+	BL	(R0)
+
+	// switch back to g
+	MOVW	g_m(g), R1
+	MOVW	m_curg(R1), R0
+	BL	setg<>(SB)
+	MOVW	(g_sched+gobuf_sp)(g), SP
+	MOVW	$0, R3
+	MOVW	R3, (g_sched+gobuf_sp)(g)
+	RET
+
+onm:
+	MOVW	R0, R7
+	MOVW	0(R0), R0
+	BL	(R0)
+	RET
+
+/*
+ * support for morestack
+ */
+
+// Called during function prolog when more stack is needed.
+// R1 frame size
+// R2 arg size
+// R3 prolog's LR
+// NB. we do not save R0 because we've forced 5c to pass all arguments
+// on the stack.
+// using frame size $-4 means do not save LR on stack.
+//
+// The traceback routines see morestack on a g0 as being
+// the top of a stack (for example, morestack calling newstack
+// calling the scheduler calling newm calling gc), so we must
+// record an argument size. For that purpose, it has no arguments.
+TEXT runtime·morestack(SB),NOSPLIT,$-4-0
+	// Cannot grow scheduler stack (m->g0).
+	MOVW	g_m(g), R8
+	MOVW	m_g0(R8), R4
+	CMP	g, R4
+	BL.EQ	runtime·abort(SB)
+
+	// Cannot grow signal stack (m->gsignal).
+	MOVW	m_gsignal(R8), R4
+	CMP	g, R4
+	BL.EQ	runtime·abort(SB)
+
+	// Called from f.
+	// Set g->sched to context in f.
+	MOVW	R7, (g_sched+gobuf_ctxt)(g)
+	MOVW	SP, (g_sched+gobuf_sp)(g)
+	MOVW	LR, (g_sched+gobuf_pc)(g)
+	MOVW	R3, (g_sched+gobuf_lr)(g)
+
+	// Called from f.
+	// Set m->morebuf to f's caller.
+	MOVW	R3, (m_morebuf+gobuf_pc)(R8)	// f's caller's PC
+	MOVW	SP, (m_morebuf+gobuf_sp)(R8)	// f's caller's SP
+	MOVW	$4(SP), R3			// f's argument pointer
+	MOVW	g, (m_morebuf+gobuf_g)(R8)
+
+	// Call newstack on m->g0's stack.
+	MOVW	m_g0(R8), R0
+	BL	setg<>(SB)
+	MOVW	(g_sched+gobuf_sp)(g), SP
+	BL	runtime·newstack(SB)
+
+	// Not reached, but make sure the return PC from the call to newstack
+	// is still in this function, and not the beginning of the next.
+	RET
+
+TEXT runtime·morestack_noctxt(SB),NOSPLIT,$-4-0
+	MOVW	$0, R7
+	B runtime·morestack(SB)
+
+// reflectcall: call a function with the given argument list
+// func call(f *FuncVal, arg *byte, argsize, retoffset uint32).
+// we don't have variable-sized frames, so we use a small number
+// of constant-sized-frame functions to encode a few bits of size in the pc.
+// Caution: ugly multiline assembly macros in your future!
+
+#define DISPATCH(NAME,MAXSIZE)		\
+	CMP	$MAXSIZE, R0;		\
+	B.HI	3(PC);			\
+	MOVW	$NAME(SB), R1;		\
+	B	(R1)
+
+TEXT ·reflectcall(SB),NOSPLIT,$-4-16
+	MOVW	argsize+8(FP), R0
+	DISPATCH(runtime·call16, 16)
+	DISPATCH(runtime·call32, 32)
+	DISPATCH(runtime·call64, 64)
+	DISPATCH(runtime·call128, 128)
+	DISPATCH(runtime·call256, 256)
+	DISPATCH(runtime·call512, 512)
+	DISPATCH(runtime·call1024, 1024)
+	DISPATCH(runtime·call2048, 2048)
+	DISPATCH(runtime·call4096, 4096)
+	DISPATCH(runtime·call8192, 8192)
+	DISPATCH(runtime·call16384, 16384)
+	DISPATCH(runtime·call32768, 32768)
+	DISPATCH(runtime·call65536, 65536)
+	DISPATCH(runtime·call131072, 131072)
+	DISPATCH(runtime·call262144, 262144)
+	DISPATCH(runtime·call524288, 524288)
+	DISPATCH(runtime·call1048576, 1048576)
+	DISPATCH(runtime·call2097152, 2097152)
+	DISPATCH(runtime·call4194304, 4194304)
+	DISPATCH(runtime·call8388608, 8388608)
+	DISPATCH(runtime·call16777216, 16777216)
+	DISPATCH(runtime·call33554432, 33554432)
+	DISPATCH(runtime·call67108864, 67108864)
+	DISPATCH(runtime·call134217728, 134217728)
+	DISPATCH(runtime·call268435456, 268435456)
+	DISPATCH(runtime·call536870912, 536870912)
+	DISPATCH(runtime·call1073741824, 1073741824)
+	MOVW	$runtime·badreflectcall(SB), R1
+	B	(R1)
+
+#define CALLFN(NAME,MAXSIZE)			\
+TEXT NAME(SB), WRAPPER, $MAXSIZE-16;		\
+	NO_LOCAL_POINTERS;			\
+	/* copy arguments to stack */		\
+	MOVW	argptr+4(FP), R0;		\
+	MOVW	argsize+8(FP), R2;		\
+	ADD	$4, SP, R1;			\
+	CMP	$0, R2;				\
+	B.EQ	5(PC);				\
+	MOVBU.P	1(R0), R5;			\
+	MOVBU.P R5, 1(R1);			\
+	SUB	$1, R2, R2;			\
+	B	-5(PC);				\
+	/* call function */			\
+	MOVW	f+0(FP), R7;			\
+	MOVW	(R7), R0;			\
+	PCDATA  $PCDATA_StackMapIndex, $0;	\
+	BL	(R0);				\
+	/* copy return values back */		\
+	MOVW	argptr+4(FP), R0;		\
+	MOVW	argsize+8(FP), R2;		\
+	MOVW	retoffset+12(FP), R3;		\
+	ADD	$4, SP, R1;			\
+	ADD	R3, R1;				\
+	ADD	R3, R0;				\
+	SUB	R3, R2;				\
+	CMP	$0, R2;				\
+	RET.EQ	;				\
+	MOVBU.P	1(R1), R5;			\
+	MOVBU.P R5, 1(R0);			\
+	SUB	$1, R2, R2;			\
+	B	-5(PC)				\
+
+CALLFN(·call16, 16)
+CALLFN(·call32, 32)
+CALLFN(·call64, 64)
+CALLFN(·call128, 128)
+CALLFN(·call256, 256)
+CALLFN(·call512, 512)
+CALLFN(·call1024, 1024)
+CALLFN(·call2048, 2048)
+CALLFN(·call4096, 4096)
+CALLFN(·call8192, 8192)
+CALLFN(·call16384, 16384)
+CALLFN(·call32768, 32768)
+CALLFN(·call65536, 65536)
+CALLFN(·call131072, 131072)
+CALLFN(·call262144, 262144)
+CALLFN(·call524288, 524288)
+CALLFN(·call1048576, 1048576)
+CALLFN(·call2097152, 2097152)
+CALLFN(·call4194304, 4194304)
+CALLFN(·call8388608, 8388608)
+CALLFN(·call16777216, 16777216)
+CALLFN(·call33554432, 33554432)
+CALLFN(·call67108864, 67108864)
+CALLFN(·call134217728, 134217728)
+CALLFN(·call268435456, 268435456)
+CALLFN(·call536870912, 536870912)
+CALLFN(·call1073741824, 1073741824)
+
+// void jmpdefer(fn, sp);
+// called from deferreturn.
+// 1. grab stored LR for caller
+// 2. sub 4 bytes to get back to BL deferreturn
+// 3. B to fn
+// TODO(rsc): Push things on stack and then use pop
+// to load all registers simultaneously, so that a profiling
+// interrupt can never see mismatched SP/LR/PC.
+// (And double-check that pop is atomic in that way.)
+TEXT runtime·jmpdefer(SB),NOSPLIT,$0-8
+	MOVW	0(SP), LR
+	MOVW	$-4(LR), LR	// BL deferreturn
+	MOVW	fv+0(FP), R7
+	MOVW	argp+4(FP), SP
+	MOVW	$-4(SP), SP	// SP is 4 below argp, due to saved LR
+	MOVW	0(R7), R1
+	B	(R1)
+
+// Save state of caller into g->sched. Smashes R11.
+TEXT gosave<>(SB),NOSPLIT,$0
+	MOVW	LR, (g_sched+gobuf_pc)(g)
+	MOVW	R13, (g_sched+gobuf_sp)(g)
+	MOVW	$0, R11
+	MOVW	R11, (g_sched+gobuf_lr)(g)
+	MOVW	R11, (g_sched+gobuf_ret)(g)
+	MOVW	R11, (g_sched+gobuf_ctxt)(g)
+	RET
+
+// asmcgocall(void(*fn)(void*), void *arg)
+// Call fn(arg) on the scheduler stack,
+// aligned appropriately for the gcc ABI.
+// See cgocall.c for more details.
+TEXT	·asmcgocall(SB),NOSPLIT,$0-8
+	MOVW	fn+0(FP), R1
+	MOVW	arg+4(FP), R0
+	BL	asmcgocall<>(SB)
+	RET
+
+TEXT ·asmcgocall_errno(SB),NOSPLIT,$0-12
+	MOVW	fn+0(FP), R1
+	MOVW	arg+4(FP), R0
+	BL	asmcgocall<>(SB)
+	MOVW	R0, ret+8(FP)
+	RET
+
+TEXT asmcgocall<>(SB),NOSPLIT,$0-0
+	// fn in R1, arg in R0.
+	MOVW	R13, R2
+	MOVW	g, R4
+
+	// Figure out if we need to switch to m->g0 stack.
+	// We get called to create new OS threads too, and those
+	// come in on the m->g0 stack already.
+	MOVW	g_m(g), R8
+	MOVW	m_g0(R8), R3
+	CMP	R3, g
+	BEQ	asmcgocall_g0
+	BL	gosave<>(SB)
+	MOVW	R0, R5
+	MOVW	R3, R0
+	BL	setg<>(SB)
+	MOVW	R5, R0
+	MOVW	(g_sched+gobuf_sp)(g), R13
+
+	// Now on a scheduling stack (a pthread-created stack).
+asmcgocall_g0:
+	SUB	$24, R13
+	BIC	$0x7, R13	// alignment for gcc ABI
+	MOVW	R4, 20(R13) // save old g
+	MOVW	(g_stack+stack_hi)(R4), R4
+	SUB	R2, R4
+	MOVW	R4, 16(R13)	// save depth in stack (can't just save SP, as stack might be copied during a callback)
+	BL	(R1)
+
+	// Restore registers, g, stack pointer.
+	MOVW	R0, R5
+	MOVW	20(R13), R0
+	BL	setg<>(SB)
+	MOVW	(g_stack+stack_hi)(g), R1
+	MOVW	16(R13), R2
+	SUB	R2, R1
+	MOVW	R5, R0
+	MOVW	R1, R13
+	RET
+
+// cgocallback(void (*fn)(void*), void *frame, uintptr framesize)
+// Turn the fn into a Go func (by taking its address) and call
+// cgocallback_gofunc.
+TEXT runtime·cgocallback(SB),NOSPLIT,$12-12
+	MOVW	$fn+0(FP), R0
+	MOVW	R0, 4(R13)
+	MOVW	frame+4(FP), R0
+	MOVW	R0, 8(R13)
+	MOVW	framesize+8(FP), R0
+	MOVW	R0, 12(R13)
+	MOVW	$runtime·cgocallback_gofunc(SB), R0
+	BL	(R0)
+	RET
+
+// cgocallback_gofunc(void (*fn)(void*), void *frame, uintptr framesize)
+// See cgocall.c for more details.
+TEXT	·cgocallback_gofunc(SB),NOSPLIT,$8-12
+	NO_LOCAL_POINTERS
+	
+	// Load m and g from thread-local storage.
+	MOVB	runtime·iscgo(SB), R0
+	CMP	$0, R0
+	BL.NE	runtime·load_g(SB)
+
+	// If g is nil, Go did not create the current thread.
+	// Call needm to obtain one for temporary use.
+	// In this case, we're running on the thread stack, so there's
+	// lots of space, but the linker doesn't know. Hide the call from
+	// the linker analysis by using an indirect call.
+	CMP	$0, g
+	B.NE	havem
+	MOVW	g, savedm-4(SP) // g is zero, so is m.
+	MOVW	$runtime·needm(SB), R0
+	BL	(R0)
+
+	// Set m->sched.sp = SP, so that if a panic happens
+	// during the function we are about to execute, it will
+	// have a valid SP to run on the g0 stack.
+	// The next few lines (after the havem label)
+	// will save this SP onto the stack and then write
+	// the same SP back to m->sched.sp. That seems redundant,
+	// but if an unrecovered panic happens, unwindm will
+	// restore the g->sched.sp from the stack location
+	// and then onM will try to use it. If we don't set it here,
+	// that restored SP will be uninitialized (typically 0) and
+	// will not be usable.
+	MOVW	g_m(g), R8
+	MOVW	m_g0(R8), R3
+	MOVW	R13, (g_sched+gobuf_sp)(R3)
+
+havem:
+	MOVW	g_m(g), R8
+	MOVW	R8, savedm-4(SP)
+	// Now there's a valid m, and we're running on its m->g0.
+	// Save current m->g0->sched.sp on stack and then set it to SP.
+	// Save current sp in m->g0->sched.sp in preparation for
+	// switch back to m->curg stack.
+	// NOTE: unwindm knows that the saved g->sched.sp is at 4(R13) aka savedsp-8(SP).
+	MOVW	m_g0(R8), R3
+	MOVW	(g_sched+gobuf_sp)(R3), R4
+	MOVW	R4, savedsp-8(SP)
+	MOVW	R13, (g_sched+gobuf_sp)(R3)
+
+	// Switch to m->curg stack and call runtime.cgocallbackg.
+	// Because we are taking over the execution of m->curg
+	// but *not* resuming what had been running, we need to
+	// save that information (m->curg->sched) so we can restore it.
+	// We can restore m->curg->sched.sp easily, because calling
+	// runtime.cgocallbackg leaves SP unchanged upon return.
+	// To save m->curg->sched.pc, we push it onto the stack.
+	// This has the added benefit that it looks to the traceback
+	// routine like cgocallbackg is going to return to that
+	// PC (because the frame we allocate below has the same
+	// size as cgocallback_gofunc's frame declared above)
+	// so that the traceback will seamlessly trace back into
+	// the earlier calls.
+	//
+	// In the new goroutine, -8(SP) and -4(SP) are unused.
+	MOVW	m_curg(R8), R0
+	BL	setg<>(SB)
+	MOVW	(g_sched+gobuf_sp)(g), R4 // prepare stack as R4
+	MOVW	(g_sched+gobuf_pc)(g), R5
+	MOVW	R5, -12(R4)
+	MOVW	$-12(R4), R13
+	BL	runtime·cgocallbackg(SB)
+
+	// Restore g->sched (== m->curg->sched) from saved values.
+	MOVW	0(R13), R5
+	MOVW	R5, (g_sched+gobuf_pc)(g)
+	MOVW	$12(R13), R4
+	MOVW	R4, (g_sched+gobuf_sp)(g)
+
+	// Switch back to m->g0's stack and restore m->g0->sched.sp.
+	// (Unlike m->curg, the g0 goroutine never uses sched.pc,
+	// so we do not have to restore it.)
+	MOVW	g_m(g), R8
+	MOVW	m_g0(R8), R0
+	BL	setg<>(SB)
+	MOVW	(g_sched+gobuf_sp)(g), R13
+	MOVW	savedsp-8(SP), R4
+	MOVW	R4, (g_sched+gobuf_sp)(g)
+
+	// If the m on entry was nil, we called needm above to borrow an m
+	// for the duration of the call. Since the call is over, return it with dropm.
+	MOVW	savedm-4(SP), R6
+	CMP	$0, R6
+	B.NE	3(PC)
+	MOVW	$runtime·dropm(SB), R0
+	BL	(R0)
+
+	// Done!
+	RET
+
+// void setg(G*); set g. for use by needm.
+TEXT runtime·setg(SB),NOSPLIT,$-4-4
+	MOVW	gg+0(FP), R0
+	B	setg<>(SB)
+
+TEXT setg<>(SB),NOSPLIT,$-4-0
+	MOVW	R0, g
+
+	// Save g to thread-local storage.
+	MOVB	runtime·iscgo(SB), R0
+	CMP	$0, R0
+	B.EQ	2(PC)
+	B	runtime·save_g(SB)
+
+	MOVW	g, R0
+	RET
+
+TEXT runtime·getcallerpc(SB),NOSPLIT,$-4-4
+	MOVW	0(SP), R0
+	MOVW	R0, ret+4(FP)
+	RET
+
+TEXT runtime·gogetcallerpc(SB),NOSPLIT,$-4-8
+	MOVW	R14, ret+4(FP)
+	RET
+
+TEXT runtime·setcallerpc(SB),NOSPLIT,$-4-8
+	MOVW	pc+4(FP), R0
+	MOVW	R0, 0(SP)
+	RET
+
+TEXT runtime·getcallersp(SB),NOSPLIT,$-4-4
+	MOVW	0(FP), R0
+	MOVW	$-4(R0), R0
+	MOVW	R0, ret+4(FP)
+	RET
+
+// func gogetcallersp(p unsafe.Pointer) uintptr
+TEXT runtime·gogetcallersp(SB),NOSPLIT,$-4-8
+	MOVW	0(FP), R0
+	MOVW	$-4(R0), R0
+	MOVW	R0, ret+4(FP)
+	RET
+
+TEXT runtime·emptyfunc(SB),0,$0-0
+	RET
+
+TEXT runtime·abort(SB),NOSPLIT,$-4-0
+	MOVW	$0, R0
+	MOVW	(R0), R1
+
+// bool armcas(int32 *val, int32 old, int32 new)
+// Atomically:
+//	if(*val == old){
+//		*val = new;
+//		return 1;
+//	}else
+//		return 0;
+//
+// To implement runtime·cas in sys_$GOOS_arm.s
+// using the native instructions, use:
+//
+//	TEXT runtime·cas(SB),NOSPLIT,$0
+//		B	runtime·armcas(SB)
+//
+TEXT runtime·armcas(SB),NOSPLIT,$0-13
+	MOVW	valptr+0(FP), R1
+	MOVW	old+4(FP), R2
+	MOVW	new+8(FP), R3
+casl:
+	LDREX	(R1), R0
+	CMP	R0, R2
+	BNE	casfail
+	STREX	R3, (R1), R0
+	CMP	$0, R0
+	BNE	casl
+	MOVW	$1, R0
+	MOVB	R0, ret+12(FP)
+	RET
+casfail:
+	MOVW	$0, R0
+	MOVB	R0, ret+12(FP)
+	RET
+
+TEXT runtime·casuintptr(SB),NOSPLIT,$0-13
+	B	runtime·cas(SB)
+
+TEXT runtime·atomicloaduintptr(SB),NOSPLIT,$0-8
+	B	runtime·atomicload(SB)
+
+TEXT runtime·atomicloaduint(SB),NOSPLIT,$0-8
+	B	runtime·atomicload(SB)
+
+TEXT runtime·atomicstoreuintptr(SB),NOSPLIT,$0-8
+	B	runtime·atomicstore(SB)
+
+// AES hashing not implemented for ARM
+TEXT runtime·aeshash(SB),NOSPLIT,$-4-0
+	MOVW	$0, R0
+	MOVW	(R0), R1
+TEXT runtime·aeshash32(SB),NOSPLIT,$-4-0
+	MOVW	$0, R0
+	MOVW	(R0), R1
+TEXT runtime·aeshash64(SB),NOSPLIT,$-4-0
+	MOVW	$0, R0
+	MOVW	(R0), R1
+TEXT runtime·aeshashstr(SB),NOSPLIT,$-4-0
+	MOVW	$0, R0
+	MOVW	(R0), R1
+
+TEXT runtime·memeq(SB),NOSPLIT,$-4-13
+	MOVW	a+0(FP), R1
+	MOVW	b+4(FP), R2
+	MOVW	size+8(FP), R3
+	ADD	R1, R3, R6
+	MOVW	$1, R0
+	MOVB	R0, ret+12(FP)
+_next2:
+	CMP	R1, R6
+	RET.EQ
+	MOVBU.P	1(R1), R4
+	MOVBU.P	1(R2), R5
+	CMP	R4, R5
+	BEQ	_next2
+
+	MOVW	$0, R0
+	MOVB	R0, ret+12(FP)
+	RET
+
+// eqstring tests whether two strings are equal.
+// See runtime_test.go:eqstring_generic for
+// equivalent Go code.
+TEXT runtime·eqstring(SB),NOSPLIT,$-4-17
+	MOVW	s1len+4(FP), R0
+	MOVW	s2len+12(FP), R1
+	MOVW	$0, R7
+	CMP	R0, R1
+	MOVB.NE R7, v+16(FP)
+	RET.NE
+	MOVW	s1str+0(FP), R2
+	MOVW	s2str+8(FP), R3
+	MOVW	$1, R8
+	MOVB	R8, v+16(FP)
+	CMP	R2, R3
+	RET.EQ
+	ADD	R2, R0, R6
+_eqnext:
+	CMP	R2, R6
+	RET.EQ
+	MOVBU.P	1(R2), R4
+	MOVBU.P	1(R3), R5
+	CMP	R4, R5
+	BEQ	_eqnext
+	MOVB	R7, v+16(FP)
+	RET
+
+// void setg_gcc(G*); set g called from gcc.
+TEXT setg_gcc<>(SB),NOSPLIT,$0
+	MOVW	R0, g
+	B		runtime·save_g(SB)
+
+// TODO: share code with memeq?
+TEXT bytes·Equal(SB),NOSPLIT,$0
+	MOVW	a_len+4(FP), R1
+	MOVW	b_len+16(FP), R3
+	
+	CMP	R1, R3		// unequal lengths are not equal
+	B.NE	_notequal
+
+	MOVW	a+0(FP), R0
+	MOVW	b+12(FP), R2
+	ADD	R0, R1		// end
+
+_byteseq_next:
+	CMP	R0, R1
+	B.EQ	_equal		// reached the end
+	MOVBU.P	1(R0), R4
+	MOVBU.P	1(R2), R5
+	CMP	R4, R5
+	B.EQ	_byteseq_next
+
+_notequal:
+	MOVW	$0, R0
+	MOVBU	R0, ret+24(FP)
+	RET
+
+_equal:
+	MOVW	$1, R0
+	MOVBU	R0, ret+24(FP)
+	RET
+
+TEXT bytes·IndexByte(SB),NOSPLIT,$0
+	MOVW	s+0(FP), R0
+	MOVW	s_len+4(FP), R1
+	MOVBU	c+12(FP), R2	// byte to find
+	MOVW	R0, R4		// store base for later
+	ADD	R0, R1		// end 
+
+_loop:
+	CMP	R0, R1
+	B.EQ	_notfound
+	MOVBU.P	1(R0), R3
+	CMP	R2, R3
+	B.NE	_loop
+
+	SUB	$1, R0		// R0 will be one beyond the position we want
+	SUB	R4, R0		// remove base
+	MOVW    R0, ret+16(FP) 
+	RET
+
+_notfound:
+	MOVW	$-1, R0
+	MOVW	R0, ret+16(FP)
+	RET
+
+TEXT strings·IndexByte(SB),NOSPLIT,$0
+	MOVW	s+0(FP), R0
+	MOVW	s_len+4(FP), R1
+	MOVBU	c+8(FP), R2	// byte to find
+	MOVW	R0, R4		// store base for later
+	ADD	R0, R1		// end 
+
+_sib_loop:
+	CMP	R0, R1
+	B.EQ	_sib_notfound
+	MOVBU.P	1(R0), R3
+	CMP	R2, R3
+	B.NE	_sib_loop
+
+	SUB	$1, R0		// R0 will be one beyond the position we want
+	SUB	R4, R0		// remove base
+	MOVW	R0, ret+12(FP) 
+	RET
+
+_sib_notfound:
+	MOVW	$-1, R0
+	MOVW	R0, ret+12(FP)
+	RET
+
+// A Duff's device for zeroing memory.
+// The compiler jumps to computed addresses within
+// this routine to zero chunks of memory.  Do not
+// change this code without also changing the code
+// in ../../cmd/5g/ggen.c:clearfat.
+// R0: zero
+// R1: ptr to memory to be zeroed
+// R1 is updated as a side effect.
+TEXT runtime·duffzero(SB),NOSPLIT,$0-0
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	MOVW.P	R0, 4(R1)
+	RET
+
+// A Duff's device for copying memory.
+// The compiler jumps to computed addresses within
+// this routine to copy chunks of memory.  Source
+// and destination must not overlap.  Do not
+// change this code without also changing the code
+// in ../../cmd/5g/cgen.c:sgen.
+// R0: scratch space
+// R1: ptr to source memory
+// R2: ptr to destination memory
+// R1 and R2 are updated as a side effect
+TEXT runtime·duffcopy(SB),NOSPLIT,$0-0
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	MOVW.P	4(R1), R0
+	MOVW.P	R0, 4(R2)
+	RET
+
+TEXT runtime·fastrand1(SB),NOSPLIT,$-4-4
+	MOVW	g_m(g), R1
+	MOVW	m_fastrand(R1), R0
+	ADD.S	R0, R0
+	EOR.MI	$0x88888eef, R0
+	MOVW	R0, m_fastrand(R1)
+	MOVW	R0, ret+0(FP)
+	RET
+
+TEXT runtime·return0(SB),NOSPLIT,$0
+	MOVW	$0, R0
+	RET
+
+TEXT runtime·procyield(SB),NOSPLIT,$-4
+	MOVW	cycles+0(FP), R1
+	MOVW	$0, R0
+yieldloop:
+	CMP	R0, R1
+	B.NE	2(PC)
+	RET
+	SUB	$1, R1
+	B yieldloop
+
+// Called from cgo wrappers, this function returns g->m->curg.stack.hi.
+// Must obey the gcc calling convention.
+TEXT _cgo_topofstack(SB),NOSPLIT,$8
+	// R11 and g register are clobbered by load_g.  They are
+	// callee-save in the gcc calling convention, so save them here.
+	MOVW	R11, saveR11-4(SP)
+	MOVW	g, saveG-8(SP)
+	
+	BL	runtime·load_g(SB)
+	MOVW	g_m(g), R0
+	MOVW	m_curg(R0), R0
+	MOVW	(g_stack+stack_hi)(R0), R0
+	
+	MOVW	saveG-8(SP), g
+	MOVW	saveR11-4(SP), R11
+	RET
+
+// The top-most function running on a goroutine
+// returns to goexit+PCQuantum.
+TEXT runtime·goexit(SB),NOSPLIT,$-4-0
+	MOVW	R0, R0	// NOP
+	BL	runtime·goexit1(SB)	// does not return
diff --git a/src/runtime/atomic.go b/src/runtime/atomic.go
new file mode 100644
index 0000000..7e9d9b3
--- /dev/null
+++ b/src/runtime/atomic.go
@@ -0,0 +1,51 @@
+// 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.
+
+// +build !arm
+
+package runtime
+
+import "unsafe"
+
+//go:noescape
+func xadd(ptr *uint32, delta int32) uint32
+
+//go:noescape
+func xadd64(ptr *uint64, delta int64) uint64
+
+//go:noescape
+func xchg(ptr *uint32, new uint32) uint32
+
+//go:noescape
+func xchg64(ptr *uint64, new uint64) uint64
+
+//go:noescape
+func xchgp(ptr unsafe.Pointer, new unsafe.Pointer) unsafe.Pointer
+
+//go:noescape
+func xchguintptr(ptr *uintptr, new uintptr) uintptr
+
+//go:noescape
+func atomicload(ptr *uint32) uint32
+
+//go:noescape
+func atomicload64(ptr *uint64) uint64
+
+//go:noescape
+func atomicloadp(ptr unsafe.Pointer) unsafe.Pointer
+
+//go:noescape
+func atomicor8(ptr *uint8, val uint8)
+
+//go:noescape
+func cas64(ptr *uint64, old, new uint64) bool
+
+//go:noescape
+func atomicstore(ptr *uint32, val uint32)
+
+//go:noescape
+func atomicstore64(ptr *uint64, val uint64)
+
+//go:noescape
+func atomicstorep(ptr unsafe.Pointer, val unsafe.Pointer)
diff --git a/src/runtime/atomic_386.c b/src/runtime/atomic_386.c
new file mode 100644
index 0000000..82d36f2
--- /dev/null
+++ b/src/runtime/atomic_386.c
@@ -0,0 +1,46 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "runtime.h"
+#include "textflag.h"
+
+#pragma textflag NOSPLIT
+uint32
+runtime·atomicload(uint32 volatile* addr)
+{
+	return *addr;
+}
+
+#pragma textflag NOSPLIT
+void*
+runtime·atomicloadp(void* volatile* addr)
+{
+	return *addr;
+}
+
+#pragma textflag NOSPLIT
+uint64
+runtime·xadd64(uint64 volatile* addr, int64 v)
+{
+	uint64 old;
+
+	do
+		old = *addr;
+	while(!runtime·cas64(addr, old, old+v));
+
+	return old+v;
+}
+
+#pragma textflag NOSPLIT
+uint64
+runtime·xchg64(uint64 volatile* addr, uint64 v)
+{
+	uint64 old;
+
+	do
+		old = *addr;
+	while(!runtime·cas64(addr, old, v));
+
+	return old;
+}
diff --git a/src/runtime/atomic_amd64x.c b/src/runtime/atomic_amd64x.c
new file mode 100644
index 0000000..7be57ac
--- /dev/null
+++ b/src/runtime/atomic_amd64x.c
@@ -0,0 +1,29 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build amd64 amd64p32
+
+#include "runtime.h"
+#include "textflag.h"
+
+#pragma textflag NOSPLIT
+uint32
+runtime·atomicload(uint32 volatile* addr)
+{
+	return *addr;
+}
+
+#pragma textflag NOSPLIT
+uint64
+runtime·atomicload64(uint64 volatile* addr)
+{
+	return *addr;
+}
+
+#pragma textflag NOSPLIT
+void*
+runtime·atomicloadp(void* volatile* addr)
+{
+	return *addr;
+}
diff --git a/src/runtime/atomic_arm.go b/src/runtime/atomic_arm.go
new file mode 100644
index 0000000..b1632cd
--- /dev/null
+++ b/src/runtime/atomic_arm.go
@@ -0,0 +1,155 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package runtime
+
+import "unsafe"
+
+var locktab [57]struct {
+	l   mutex
+	pad [_CacheLineSize - unsafe.Sizeof(mutex{})]byte
+}
+
+func addrLock(addr *uint64) *mutex {
+	return &locktab[(uintptr(unsafe.Pointer(addr))>>3)%uintptr(len(locktab))].l
+}
+
+// Atomic add and return new value.
+//go:nosplit
+func xadd(val *uint32, delta int32) uint32 {
+	for {
+		oval := *val
+		nval := oval + uint32(delta)
+		if cas(val, oval, nval) {
+			return nval
+		}
+	}
+}
+
+//go:nosplit
+func xchg(addr *uint32, v uint32) uint32 {
+	for {
+		old := *addr
+		if cas(addr, old, v) {
+			return old
+		}
+	}
+}
+
+//go:nosplit
+func xchgp(addr *unsafe.Pointer, v unsafe.Pointer) unsafe.Pointer {
+	for {
+		old := *addr
+		if casp(addr, old, v) {
+			return old
+		}
+	}
+}
+
+//go:nosplit
+func xchguintptr(addr *uintptr, v uintptr) uintptr {
+	return uintptr(xchg((*uint32)(unsafe.Pointer(addr)), uint32(v)))
+}
+
+//go:nosplit
+func atomicload(addr *uint32) uint32 {
+	return xadd(addr, 0)
+}
+
+//go:nosplit
+func atomicloadp(addr unsafe.Pointer) unsafe.Pointer {
+	return unsafe.Pointer(uintptr(xadd((*uint32)(addr), 0)))
+}
+
+//go:nosplit
+func atomicstorep(addr unsafe.Pointer, v unsafe.Pointer) {
+	for {
+		old := *(*unsafe.Pointer)(addr)
+		if casp((*unsafe.Pointer)(addr), old, v) {
+			return
+		}
+	}
+}
+
+//go:nosplit
+func atomicstore(addr *uint32, v uint32) {
+	for {
+		old := *addr
+		if cas(addr, old, v) {
+			return
+		}
+	}
+}
+
+//go:nosplit
+func cas64(addr *uint64, old, new uint64) bool {
+	var ok bool
+	onM(func() {
+		lock(addrLock(addr))
+		if *addr == old {
+			*addr = new
+			ok = true
+		}
+		unlock(addrLock(addr))
+	})
+	return ok
+}
+
+//go:nosplit
+func xadd64(addr *uint64, delta int64) uint64 {
+	var r uint64
+	onM(func() {
+		lock(addrLock(addr))
+		r = *addr + uint64(delta)
+		*addr = r
+		unlock(addrLock(addr))
+	})
+	return r
+}
+
+//go:nosplit
+func xchg64(addr *uint64, v uint64) uint64 {
+	var r uint64
+	onM(func() {
+		lock(addrLock(addr))
+		r = *addr
+		*addr = v
+		unlock(addrLock(addr))
+	})
+	return r
+}
+
+//go:nosplit
+func atomicload64(addr *uint64) uint64 {
+	var r uint64
+	onM(func() {
+		lock(addrLock(addr))
+		r = *addr
+		unlock(addrLock(addr))
+	})
+	return r
+}
+
+//go:nosplit
+func atomicstore64(addr *uint64, v uint64) {
+	onM(func() {
+		lock(addrLock(addr))
+		*addr = v
+		unlock(addrLock(addr))
+	})
+}
+
+//go:nosplit
+func atomicor8(addr *uint8, v uint8) {
+	// Align down to 4 bytes and use 32-bit CAS.
+	uaddr := uintptr(unsafe.Pointer(addr))
+	addr32 := (*uint32)(unsafe.Pointer(uaddr &^ 3))
+	word := uint32(v) << ((uaddr & 3) * 8) // little endian
+	for {
+		old := *addr32
+		if cas(addr32, old, old|word) {
+			return
+		}
+	}
+}
diff --git a/src/runtime/cgo/asm_386.s b/src/runtime/cgo/asm_386.s
new file mode 100644
index 0000000..a895083
--- /dev/null
+++ b/src/runtime/cgo/asm_386.s
@@ -0,0 +1,31 @@
+// Copyright 2009 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+/*
+ * void crosscall2(void (*fn)(void*, int32), void*, int32)
+ * Save registers and call fn with two arguments.
+ */
+TEXT crosscall2(SB),NOSPLIT,$0
+	PUSHL	BP
+	MOVL	SP, BP
+	PUSHL	BX
+	PUSHL	SI
+	PUSHL	DI
+	
+	SUBL	$8, SP
+	MOVL	16(BP), AX
+	MOVL	AX, 4(SP)
+	MOVL	12(BP), AX
+	MOVL	AX, 0(SP)
+	MOVL	8(BP), AX
+	CALL	AX
+	ADDL	$8, SP
+	
+	POPL	DI
+	POPL	SI
+	POPL	BX
+	POPL	BP
+	RET
diff --git a/src/runtime/cgo/asm_amd64.s b/src/runtime/cgo/asm_amd64.s
new file mode 100644
index 0000000..6095bd1
--- /dev/null
+++ b/src/runtime/cgo/asm_amd64.s
@@ -0,0 +1,47 @@
+// Copyright 2009 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+/*
+ * void crosscall2(void (*fn)(void*, int32), void*, int32)
+ * Save registers and call fn with two arguments.
+ */
+TEXT crosscall2(SB),NOSPLIT,$0
+	SUBQ	$0x58, SP	/* keeps stack pointer 32-byte aligned */
+	MOVQ	BX, 0x10(SP)
+	MOVQ	BP, 0x18(SP)
+	MOVQ	R12, 0x20(SP)
+	MOVQ	R13, 0x28(SP)
+	MOVQ	R14, 0x30(SP)
+	MOVQ	R15, 0x38(SP)
+
+#ifdef GOOS_windows
+	// Win64 save RBX, RBP, RDI, RSI, RSP, R12, R13, R14, and R15
+	MOVQ	DI, 0x40(SP)
+	MOVQ	SI, 0x48(SP)
+
+	MOVQ	DX, 0(SP)	/* arg */
+	MOVQ	R8, 8(SP)	/* argsize (includes padding) */
+	
+	CALL	CX	/* fn */
+	
+	MOVQ	0x40(SP), DI
+	MOVQ	0x48(SP), SI
+#else
+	MOVQ	SI, 0(SP)	/* arg */
+	MOVQ	DX, 8(SP)	/* argsize (includes padding) */
+
+	CALL	DI	/* fn */
+#endif
+
+	MOVQ	0x10(SP), BX
+	MOVQ	0x18(SP), BP
+	MOVQ	0x20(SP), R12
+	MOVQ	0x28(SP), R13
+	MOVQ	0x30(SP), R14
+	MOVQ	0x38(SP), R15
+	
+	ADDQ	$0x58, SP
+	RET
diff --git a/src/runtime/cgo/asm_arm.s b/src/runtime/cgo/asm_arm.s
new file mode 100644
index 0000000..6e57432
--- /dev/null
+++ b/src/runtime/cgo/asm_arm.s
@@ -0,0 +1,24 @@
+// Copyright 2012 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+/*
+ * void crosscall2(void (*fn)(void*, int32), void*, int32)
+ * Save registers and call fn with two arguments.
+ */
+TEXT crosscall2(SB),NOSPLIT,$-4
+	/* 
+	 * We still need to save all callee save register as before, and then
+	 *  push 2 args for fn (R1 and R2).
+	 * Also note that at procedure entry in 5c/5g world, 4(R13) will be the
+	 *  first arg, so we must push another dummy reg (R0) for 0(R13).
+	 *  Additionally, runtime·load_g will clobber R0, so we need to save R0
+	 *  nevertheless.
+	 */
+	MOVM.WP	[R0, R1, R2, R4, R5, R6, R7, R8, R9, g, R11, R12, R14], (R13)
+	BL	runtime·load_g(SB)
+	MOVW	PC, R14
+	MOVW	0(R13), PC
+	MOVM.IAW	(R13), [R0, R1, R2, R4, R5, R6, R7, R8, R9, g, R11, R12, PC]
diff --git a/src/runtime/cgo/asm_nacl_amd64p32.s b/src/runtime/cgo/asm_nacl_amd64p32.s
new file mode 100644
index 0000000..eb92014
--- /dev/null
+++ b/src/runtime/cgo/asm_nacl_amd64p32.s
@@ -0,0 +1,13 @@
+// Copyright 2013 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+/*
+ * void crosscall2(void (*fn)(void*, int32), void*, int32)
+ * Save registers and call fn with two arguments.
+ */
+TEXT crosscall2(SB),NOSPLIT,$0
+	INT $3
+	RET
diff --git a/src/runtime/cgo/callbacks.c b/src/runtime/cgo/callbacks.c
new file mode 100644
index 0000000..282beee
--- /dev/null
+++ b/src/runtime/cgo/callbacks.c
@@ -0,0 +1,83 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "../runtime.h"
+#include "../cgocall.h"
+#include "textflag.h"
+
+// These utility functions are available to be called from code
+// compiled with gcc via crosscall2.
+
+// The declaration of crosscall2 is:
+//   void crosscall2(void (*fn)(void *, int), void *, int);
+// 
+// We need to export the symbol crosscall2 in order to support
+// callbacks from shared libraries. This applies regardless of
+// linking mode.
+#pragma cgo_export_static crosscall2
+#pragma cgo_export_dynamic crosscall2
+
+// Allocate memory.  This allocates the requested number of bytes in
+// memory controlled by the Go runtime.  The allocated memory will be
+// zeroed.  You are responsible for ensuring that the Go garbage
+// collector can see a pointer to the allocated memory for as long as
+// it is valid, e.g., by storing a pointer in a local variable in your
+// C function, or in memory allocated by the Go runtime.  If the only
+// pointers are in a C global variable or in memory allocated via
+// malloc, then the Go garbage collector may collect the memory.
+
+// Call like this in code compiled with gcc:
+//   struct { size_t len; void *ret; } a;
+//   a.len = /* number of bytes to allocate */;
+//   crosscall2(_cgo_allocate, &a, sizeof a);
+//   /* Here a.ret is a pointer to the allocated memory.  */
+
+void runtime·_cgo_allocate_internal(void);
+
+#pragma cgo_export_static _cgo_allocate
+#pragma cgo_export_dynamic _cgo_allocate
+#pragma textflag NOSPLIT
+void
+_cgo_allocate(void *a, int32 n)
+{
+	runtime·cgocallback((void(*)(void))runtime·_cgo_allocate_internal, a, n);
+}
+
+// Panic.  The argument is converted into a Go string.
+
+// Call like this in code compiled with gcc:
+//   struct { const char *p; } a;
+//   a.p = /* string to pass to panic */;
+//   crosscall2(_cgo_panic, &a, sizeof a);
+//   /* The function call will not return.  */
+
+void runtime·_cgo_panic_internal(void);
+
+#pragma cgo_export_static _cgo_panic
+#pragma cgo_export_dynamic _cgo_panic
+#pragma textflag NOSPLIT
+void
+_cgo_panic(void *a, int32 n)
+{
+	runtime·cgocallback((void(*)(void))runtime·_cgo_panic_internal, a, n);
+}
+
+#pragma cgo_import_static x_cgo_init
+extern void x_cgo_init(G*);
+void (*_cgo_init)(G*) = x_cgo_init;
+
+#pragma cgo_import_static x_cgo_malloc
+extern void x_cgo_malloc(void*);
+void (*_cgo_malloc)(void*) = x_cgo_malloc;
+
+#pragma cgo_import_static x_cgo_free
+extern void x_cgo_free(void*);
+void (*_cgo_free)(void*) = x_cgo_free;
+
+#pragma cgo_import_static x_cgo_thread_start
+extern void x_cgo_thread_start(void*);
+void (*_cgo_thread_start)(void*) = x_cgo_thread_start;
+
+#pragma cgo_export_static _cgo_topofstack
+#pragma cgo_export_dynamic _cgo_topofstack
diff --git a/src/runtime/cgo/cgo.go b/src/runtime/cgo/cgo.go
new file mode 100644
index 0000000..8528692
--- /dev/null
+++ b/src/runtime/cgo/cgo.go
@@ -0,0 +1,26 @@
+// Copyright 2010 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+/*
+Package cgo contains runtime support for code generated
+by the cgo tool.  See the documentation for the cgo command
+for details on using cgo.
+*/
+package cgo
+
+/*
+
+#cgo darwin LDFLAGS: -lpthread
+#cgo dragonfly LDFLAGS: -lpthread
+#cgo freebsd LDFLAGS: -lpthread
+#cgo android LDFLAGS: -llog
+#cgo !android,linux LDFLAGS: -lpthread
+#cgo netbsd LDFLAGS: -lpthread
+#cgo openbsd LDFLAGS: -lpthread
+#cgo windows LDFLAGS: -lm -mthreads
+
+#cgo CFLAGS: -Wall -Werror
+
+*/
+import "C"
diff --git a/src/runtime/cgo/dragonfly.c b/src/runtime/cgo/dragonfly.c
new file mode 100644
index 0000000..c233c8b
--- /dev/null
+++ b/src/runtime/cgo/dragonfly.c
@@ -0,0 +1,19 @@
+// Copyright 2010 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build dragonfly
+
+#include "textflag.h"
+
+// Supply environ and __progname, because we don't
+// link against the standard DragonFly crt0.o and the
+// libc dynamic library needs them.
+
+#pragma dataflag NOPTR
+char *environ[1];
+#pragma dataflag NOPTR
+char *__progname;
+
+#pragma dynexport environ environ
+#pragma dynexport __progname __progname
diff --git a/src/runtime/cgo/freebsd.c b/src/runtime/cgo/freebsd.c
new file mode 100644
index 0000000..4876b2a
--- /dev/null
+++ b/src/runtime/cgo/freebsd.c
@@ -0,0 +1,19 @@
+// Copyright 2010 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build freebsd
+
+#include "textflag.h"
+
+// Supply environ and __progname, because we don't
+// link against the standard FreeBSD crt0.o and the
+// libc dynamic library needs them.
+
+#pragma dataflag NOPTR
+char *environ[1];
+#pragma dataflag NOPTR
+char *__progname;
+
+#pragma dynexport environ environ
+#pragma dynexport __progname __progname
diff --git a/src/pkg/runtime/cgo/gcc_386.S b/src/runtime/cgo/gcc_386.S
similarity index 100%
rename from src/pkg/runtime/cgo/gcc_386.S
rename to src/runtime/cgo/gcc_386.S
diff --git a/src/pkg/runtime/cgo/gcc_amd64.S b/src/runtime/cgo/gcc_amd64.S
similarity index 100%
rename from src/pkg/runtime/cgo/gcc_amd64.S
rename to src/runtime/cgo/gcc_amd64.S
diff --git a/src/runtime/cgo/gcc_android.c b/src/runtime/cgo/gcc_android.c
new file mode 100644
index 0000000..be27725
--- /dev/null
+++ b/src/runtime/cgo/gcc_android.c
@@ -0,0 +1,31 @@
+// 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 <stdarg.h>
+#include <android/log.h>
+#include "libcgo.h"
+
+void
+fatalf(const char* format, ...)
+{
+	va_list ap;
+
+	// Write to both stderr and logcat.
+	//
+	// When running from an .apk, /dev/stderr and /dev/stdout
+	// redirect to /dev/null. And when running a test binary
+	// via adb shell, it's easy to miss logcat.
+
+	fprintf(stderr, "runtime/cgo: ");
+	va_start(ap, format);
+	vfprintf(stderr, format, ap);
+	va_end(ap);
+	fprintf(stderr, "\n");
+
+	va_start(ap, format);
+	__android_log_vprint(ANDROID_LOG_FATAL, "runtime/cgo", format, ap);
+	va_end(ap);
+
+	abort();
+}
diff --git a/src/runtime/cgo/gcc_android_arm.c b/src/runtime/cgo/gcc_android_arm.c
new file mode 100644
index 0000000..07f7e72
--- /dev/null
+++ b/src/runtime/cgo/gcc_android_arm.c
@@ -0,0 +1,43 @@
+// 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 <pthread.h>
+#include <signal.h>
+#include <stdio.h>
+#include <sys/limits.h>
+#include "libcgo.h"
+
+#define magic1 (0x23581321U)
+
+// PTHREAD_KEYS_MAX has been added to sys/limits.h at head in bionic:
+// https://android.googlesource.com/platform/bionic/+/master/libc/include/sys/limits.h
+// TODO(crawshaw): remove this definition when a new NDK is released.
+#define PTHREAD_KEYS_MAX 128
+
+// inittls allocates a thread-local storage slot for g.
+//
+// It finds the first available slot using pthread_key_create and uses
+// it as the offset value for runtime.tlsg.
+static void
+inittls(void **tlsg, void **tlsbase)
+{
+	pthread_key_t k;
+	int i, err;
+
+	err = pthread_key_create(&k, nil);
+	if(err != 0) {
+		fatalf("pthread_key_create failed: %d", err);
+	}
+	pthread_setspecific(k, (void*)magic1);
+	for (i=0; i<PTHREAD_KEYS_MAX; i++) {
+		if (*(tlsbase+i) == (void*)magic1) {
+			*tlsg = (void*)(i*sizeof(void *));
+			pthread_setspecific(k, 0);
+			return;
+		}
+	}
+	fatalf("could not find pthread key");
+}
+
+void (*x_cgo_inittls)(void **tlsg, void **tlsbase) = inittls;
diff --git a/src/runtime/cgo/gcc_arm.S b/src/runtime/cgo/gcc_arm.S
new file mode 100644
index 0000000..d5833bf
--- /dev/null
+++ b/src/runtime/cgo/gcc_arm.S
@@ -0,0 +1,42 @@
+// Copyright 2012 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+/*
+ * Apple still insists on underscore prefixes for C function names.
+ */
+#if defined(__APPLE__)
+#define EXT(s) _##s
+#else
+#define EXT(s) s
+#endif
+
+/*
+ * void crosscall_arm1(void (*fn)(void), void (*setg_gcc)(void *g), void *g)
+ *
+ * Calling into the 5c tool chain, where all registers are caller save.
+ * Called from standard ARM EABI, where r4-r11 are callee-save, so they
+ * must be saved explicitly.
+ */
+.globl EXT(crosscall_arm1)
+EXT(crosscall_arm1):
+	push {r4, r5, r6, r7, r8, r9, r10, r11, ip, lr}
+	mov r4, r0
+	mov r5, r1
+	mov r0, r2
+
+	// Because the assembler might target an earlier revision of the ISA
+	// by default, we encode BLX as a .word.
+	.word 0xe12fff35 // blx r5 // setg(g)
+	.word 0xe12fff34 // blx r4 // fn()
+
+	pop {r4, r5, r6, r7, r8, r9, r10, r11, ip, pc}
+
+.globl EXT(__stack_chk_fail_local)
+EXT(__stack_chk_fail_local):
+1:
+	b 1b
+
+#ifdef __ELF__
+.section .note.GNU-stack,"",%progbits
+#endif
diff --git a/src/runtime/cgo/gcc_darwin_386.c b/src/runtime/cgo/gcc_darwin_386.c
new file mode 100644
index 0000000..6668ba4
--- /dev/null
+++ b/src/runtime/cgo/gcc_darwin_386.c
@@ -0,0 +1,148 @@
+// Copyright 2009 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include <string.h> /* for strerror */
+#include <pthread.h>
+#include <signal.h>
+#include "libcgo.h"
+
+static void* threadentry(void*);
+static pthread_key_t k1;
+
+#define magic1 (0x23581321U)
+
+static void
+inittls(void)
+{
+	uint32 x;
+	pthread_key_t tofree[128], k;
+	int i, ntofree;
+
+	/*
+	 * Allocate thread-local storage slot for g.
+	 * The key numbers start at 0x100, and we expect to be
+	 * one of the early calls to pthread_key_create, so we
+	 * should be able to get a pretty low number.
+	 *
+	 * In Darwin/386 pthreads, %gs points at the thread
+	 * structure, and each key is an index into the thread-local
+	 * storage array that begins at offset 0x48 within in that structure.
+	 * It may happen that we are not quite the first function to try
+	 * to allocate thread-local storage keys, so instead of depending
+	 * on getting 0x100, we try for 0x108, allocating keys until
+	 * we get the one we want and then freeing the ones we didn't want.
+	 *
+	 * Thus the final offset to use in %gs references is
+	 * 0x48+4*0x108 = 0x468.
+	 *
+	 * The linker and runtime hard-code this constant offset
+	 * from %gs where we expect to find g.
+	 * Known to ../../../liblink/sym.c:/468
+	 * and to ../sys_darwin_386.s:/468
+	 *
+	 * This is truly disgusting and a bit fragile, but taking care
+	 * of it here protects the rest of the system from damage.
+	 * The alternative would be to use a global variable that
+	 * held the offset and refer to that variable each time we
+	 * need a %gs variable (g).  That approach would
+	 * require an extra instruction and memory reference in
+	 * every stack growth prolog and would also require
+	 * rewriting the code that 8c generates for extern registers.
+	 *
+	 * Things get more disgusting on OS X 10.7 Lion.
+	 * The 0x48 base mentioned above is the offset of the tsd
+	 * array within the per-thread structure on Leopard and Snow Leopard.
+	 * On Lion, the base moved a little, so while the math above
+	 * still applies, the base is different.  Thus, we cannot
+	 * look for specific key values if we want to build binaries
+	 * that run on both systems.  Instead, forget about the
+	 * specific key values and just allocate and initialize per-thread
+	 * storage until we find a key that writes to the memory location
+	 * we want.  Then keep that key.
+	 */
+	ntofree = 0;
+	for(;;) {
+		if(pthread_key_create(&k, nil) < 0) {
+			fprintf(stderr, "runtime/cgo: pthread_key_create failed\n");
+			abort();
+		}
+		pthread_setspecific(k, (void*)magic1);
+		asm volatile("movl %%gs:0x468, %0" : "=r"(x));
+		pthread_setspecific(k, 0);
+		if(x == magic1) {
+			k1 = k;
+			break;
+		}
+		if(ntofree >= nelem(tofree)) {
+			fprintf(stderr, "runtime/cgo: could not obtain pthread_keys\n");
+			fprintf(stderr, "\ttried");
+			for(i=0; i<ntofree; i++)
+				fprintf(stderr, " %#x", (unsigned)tofree[i]);
+			fprintf(stderr, "\n");
+			abort();
+		}
+		tofree[ntofree++] = k;
+	}
+
+	/*
+	 * We got the key we wanted.  Free the others.
+	 */
+	for(i=0; i<ntofree; i++)
+		pthread_key_delete(tofree[i]);
+}
+
+void
+x_cgo_init(G *g)
+{
+	pthread_attr_t attr;
+	size_t size;
+
+	pthread_attr_init(&attr);
+	pthread_attr_getstacksize(&attr, &size);
+	g->stacklo = (uintptr)&attr - size + 4096;
+	pthread_attr_destroy(&attr);
+
+	inittls();
+}
+
+
+void
+_cgo_sys_thread_start(ThreadStart *ts)
+{
+	pthread_attr_t attr;
+	sigset_t ign, oset;
+	pthread_t p;
+	size_t size;
+	int err;
+
+	sigfillset(&ign);
+	pthread_sigmask(SIG_SETMASK, &ign, &oset);
+
+	pthread_attr_init(&attr);
+	pthread_attr_getstacksize(&attr, &size);
+	// Leave stacklo=0 and set stackhi=size; mstack will do the rest.
+	ts->g->stackhi = size;
+	err = pthread_create(&p, &attr, threadentry, ts);
+
+	pthread_sigmask(SIG_SETMASK, &oset, nil);
+
+	if (err != 0) {
+		fprintf(stderr, "runtime/cgo: pthread_create failed: %s\n", strerror(err));
+		abort();
+	}
+}
+
+static void*
+threadentry(void *v)
+{
+	ThreadStart ts;
+
+	ts = *(ThreadStart*)v;
+	free(v);
+
+	pthread_setspecific(k1, (void*)ts.g);
+
+	crosscall_386(ts.fn);
+	return nil;
+}
diff --git a/src/runtime/cgo/gcc_darwin_amd64.c b/src/runtime/cgo/gcc_darwin_amd64.c
new file mode 100644
index 0000000..dc679ac
--- /dev/null
+++ b/src/runtime/cgo/gcc_darwin_amd64.c
@@ -0,0 +1,119 @@
+// Copyright 2009 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include <string.h> /* for strerror */
+#include <pthread.h>
+#include <signal.h>
+#include "libcgo.h"
+
+static void* threadentry(void*);
+static pthread_key_t k1;
+
+#define magic1 (0x23581321345589ULL)
+
+static void
+inittls(void)
+{
+	uint64 x;
+	pthread_key_t tofree[128], k;
+	int i, ntofree;
+
+	/*
+	 * Same logic, code as darwin_386.c:/inittls, except that words
+	 * are 8 bytes long now, and the thread-local storage starts
+	 * at 0x60 on Leopard / Snow Leopard. So the offset is
+	 * 0x60+8*0x108 = 0x8a0.
+	 *
+	 * The linker and runtime hard-code this constant offset
+	 * from %gs where we expect to find g.
+	 * Known to ../../../liblink/sym.c:/8a0
+	 * and to ../sys_darwin_amd64.s:/8a0
+	 *
+	 * As disgusting as on the 386; same justification.
+	 */
+	ntofree = 0;
+	for(;;) {
+		if(pthread_key_create(&k, nil) < 0) {
+			fprintf(stderr, "runtime/cgo: pthread_key_create failed\n");
+			abort();
+		}
+		pthread_setspecific(k, (void*)magic1);
+		asm volatile("movq %%gs:0x8a0, %0" : "=r"(x));
+		pthread_setspecific(k, 0);
+		if(x == magic1) {
+			k1 = k;
+			break;
+		}
+		if(ntofree >= nelem(tofree)) {
+			fprintf(stderr, "runtime/cgo: could not obtain pthread_keys\n");
+			fprintf(stderr, "\ttried");
+			for(i=0; i<ntofree; i++)
+				fprintf(stderr, " %#x", (unsigned)tofree[i]);
+			fprintf(stderr, "\n");
+			abort();
+		}
+		tofree[ntofree++] = k;
+	}
+
+	/*
+	 * We got the key we wanted.  Free the others.
+	 */
+	for(i=0; i<ntofree; i++)
+		pthread_key_delete(tofree[i]);
+}
+
+void
+x_cgo_init(G *g)
+{
+	pthread_attr_t attr;
+	size_t size;
+
+	pthread_attr_init(&attr);
+	pthread_attr_getstacksize(&attr, &size);
+	g->stacklo = (uintptr)&attr - size + 4096;
+	pthread_attr_destroy(&attr);
+
+	inittls();
+}
+
+
+void
+_cgo_sys_thread_start(ThreadStart *ts)
+{
+	pthread_attr_t attr;
+	sigset_t ign, oset;
+	pthread_t p;
+	size_t size;
+	int err;
+
+	sigfillset(&ign);
+	pthread_sigmask(SIG_SETMASK, &ign, &oset);
+
+	pthread_attr_init(&attr);
+	pthread_attr_getstacksize(&attr, &size);
+	// Leave stacklo=0 and set stackhi=size; mstack will do the rest.
+	ts->g->stackhi = size;
+	err = pthread_create(&p, &attr, threadentry, ts);
+
+	pthread_sigmask(SIG_SETMASK, &oset, nil);
+
+	if (err != 0) {
+		fprintf(stderr, "runtime/cgo: pthread_create failed: %s\n", strerror(err));
+		abort();
+	}
+}
+
+static void*
+threadentry(void *v)
+{
+	ThreadStart ts;
+
+	ts = *(ThreadStart*)v;
+	free(v);
+
+	pthread_setspecific(k1, (void*)ts.g);
+
+	crosscall_amd64(ts.fn);
+	return nil;
+}
diff --git a/src/runtime/cgo/gcc_dragonfly_386.c b/src/runtime/cgo/gcc_dragonfly_386.c
new file mode 100644
index 0000000..074418f
--- /dev/null
+++ b/src/runtime/cgo/gcc_dragonfly_386.c
@@ -0,0 +1,70 @@
+// Copyright 2009 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include <sys/types.h>
+#include <sys/signalvar.h>
+#include <pthread.h>
+#include <signal.h>
+#include <string.h>
+#include "libcgo.h"
+
+static void* threadentry(void*);
+static void (*setg_gcc)(void*);
+
+void
+x_cgo_init(G *g, void (*setg)(void*))
+{
+	pthread_attr_t attr;
+	size_t size;
+
+	setg_gcc = setg;
+	pthread_attr_init(&attr);
+	pthread_attr_getstacksize(&attr, &size);
+	g->stacklo = (uintptr)&attr - size + 4096;
+	pthread_attr_destroy(&attr);
+}
+
+
+void
+_cgo_sys_thread_start(ThreadStart *ts)
+{
+	pthread_attr_t attr;
+	sigset_t ign, oset;
+	pthread_t p;
+	size_t size;
+	int err;
+
+	SIGFILLSET(ign);
+	pthread_sigmask(SIG_SETMASK, &ign, &oset);
+
+	pthread_attr_init(&attr);
+	pthread_attr_getstacksize(&attr, &size);
+	// Leave stacklo=0 and set stackhi=size; mstack will do the rest.
+	ts->g->stackhi = size;
+	err = pthread_create(&p, &attr, threadentry, ts);
+
+	pthread_sigmask(SIG_SETMASK, &oset, nil);
+
+	if (err != 0) {
+		fprintf(stderr, "runtime/cgo: pthread_create failed: %s\n", strerror(err));
+		abort();
+	}
+}
+
+static void*
+threadentry(void *v)
+{
+	ThreadStart ts;
+
+	ts = *(ThreadStart*)v;
+	free(v);
+
+	/*
+	 * Set specific keys.
+	 */
+	setg_gcc((void*)ts.g);
+
+	crosscall_386(ts.fn);
+	return nil;
+}
diff --git a/src/runtime/cgo/gcc_dragonfly_amd64.c b/src/runtime/cgo/gcc_dragonfly_amd64.c
new file mode 100644
index 0000000..f79f652
--- /dev/null
+++ b/src/runtime/cgo/gcc_dragonfly_amd64.c
@@ -0,0 +1,70 @@
+// Copyright 2009 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include <sys/types.h>
+#include <sys/signalvar.h>
+#include <pthread.h>
+#include <signal.h>
+#include <string.h>
+#include "libcgo.h"
+
+static void* threadentry(void*);
+static void (*setg_gcc)(void*);
+
+void
+x_cgo_init(G *g, void (*setg)(void*))
+{
+	pthread_attr_t attr;
+	size_t size;
+
+	setg_gcc = setg;
+	pthread_attr_init(&attr);
+	pthread_attr_getstacksize(&attr, &size);
+	g->stacklo = (uintptr)&attr - size + 4096;
+	pthread_attr_destroy(&attr);
+}
+
+void
+_cgo_sys_thread_start(ThreadStart *ts)
+{
+	pthread_attr_t attr;
+	sigset_t ign, oset;
+	pthread_t p;
+	size_t size;
+	int err;
+
+	SIGFILLSET(ign);
+	pthread_sigmask(SIG_SETMASK, &ign, &oset);
+
+	pthread_attr_init(&attr);
+	pthread_attr_getstacksize(&attr, &size);
+
+	// Leave stacklo=0 and set stackhi=size; mstack will do the rest.
+	ts->g->stackhi = size;
+	err = pthread_create(&p, &attr, threadentry, ts);
+
+	pthread_sigmask(SIG_SETMASK, &oset, nil);
+
+	if (err != 0) {
+		fprintf(stderr, "runtime/cgo: pthread_create failed: %s\n", strerror(err));
+		abort();
+	}
+}
+
+static void*
+threadentry(void *v)
+{
+	ThreadStart ts;
+
+	ts = *(ThreadStart*)v;
+	free(v);
+
+	/*
+	 * Set specific keys.
+	 */
+	setg_gcc((void*)ts.g);
+
+	crosscall_amd64(ts.fn);
+	return nil;
+}
diff --git a/src/runtime/cgo/gcc_fatalf.c b/src/runtime/cgo/gcc_fatalf.c
new file mode 100644
index 0000000..21c1acf
--- /dev/null
+++ b/src/runtime/cgo/gcc_fatalf.c
@@ -0,0 +1,23 @@
+// 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.
+
+// +build !android,linux
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "libcgo.h"
+
+void
+fatalf(const char* format, ...)
+{
+	va_list ap;
+
+	fprintf(stderr, "runtime/cgo: ");
+	va_start(ap, format);
+	vfprintf(stderr, format, ap);
+	va_end(ap);
+	fprintf(stderr, "\n");
+	abort();
+}
diff --git a/src/runtime/cgo/gcc_freebsd_386.c b/src/runtime/cgo/gcc_freebsd_386.c
new file mode 100644
index 0000000..074418f
--- /dev/null
+++ b/src/runtime/cgo/gcc_freebsd_386.c
@@ -0,0 +1,70 @@
+// Copyright 2009 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include <sys/types.h>
+#include <sys/signalvar.h>
+#include <pthread.h>
+#include <signal.h>
+#include <string.h>
+#include "libcgo.h"
+
+static void* threadentry(void*);
+static void (*setg_gcc)(void*);
+
+void
+x_cgo_init(G *g, void (*setg)(void*))
+{
+	pthread_attr_t attr;
+	size_t size;
+
+	setg_gcc = setg;
+	pthread_attr_init(&attr);
+	pthread_attr_getstacksize(&attr, &size);
+	g->stacklo = (uintptr)&attr - size + 4096;
+	pthread_attr_destroy(&attr);
+}
+
+
+void
+_cgo_sys_thread_start(ThreadStart *ts)
+{
+	pthread_attr_t attr;
+	sigset_t ign, oset;
+	pthread_t p;
+	size_t size;
+	int err;
+
+	SIGFILLSET(ign);
+	pthread_sigmask(SIG_SETMASK, &ign, &oset);
+
+	pthread_attr_init(&attr);
+	pthread_attr_getstacksize(&attr, &size);
+	// Leave stacklo=0 and set stackhi=size; mstack will do the rest.
+	ts->g->stackhi = size;
+	err = pthread_create(&p, &attr, threadentry, ts);
+
+	pthread_sigmask(SIG_SETMASK, &oset, nil);
+
+	if (err != 0) {
+		fprintf(stderr, "runtime/cgo: pthread_create failed: %s\n", strerror(err));
+		abort();
+	}
+}
+
+static void*
+threadentry(void *v)
+{
+	ThreadStart ts;
+
+	ts = *(ThreadStart*)v;
+	free(v);
+
+	/*
+	 * Set specific keys.
+	 */
+	setg_gcc((void*)ts.g);
+
+	crosscall_386(ts.fn);
+	return nil;
+}
diff --git a/src/runtime/cgo/gcc_freebsd_amd64.c b/src/runtime/cgo/gcc_freebsd_amd64.c
new file mode 100644
index 0000000..f79f652
--- /dev/null
+++ b/src/runtime/cgo/gcc_freebsd_amd64.c
@@ -0,0 +1,70 @@
+// Copyright 2009 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include <sys/types.h>
+#include <sys/signalvar.h>
+#include <pthread.h>
+#include <signal.h>
+#include <string.h>
+#include "libcgo.h"
+
+static void* threadentry(void*);
+static void (*setg_gcc)(void*);
+
+void
+x_cgo_init(G *g, void (*setg)(void*))
+{
+	pthread_attr_t attr;
+	size_t size;
+
+	setg_gcc = setg;
+	pthread_attr_init(&attr);
+	pthread_attr_getstacksize(&attr, &size);
+	g->stacklo = (uintptr)&attr - size + 4096;
+	pthread_attr_destroy(&attr);
+}
+
+void
+_cgo_sys_thread_start(ThreadStart *ts)
+{
+	pthread_attr_t attr;
+	sigset_t ign, oset;
+	pthread_t p;
+	size_t size;
+	int err;
+
+	SIGFILLSET(ign);
+	pthread_sigmask(SIG_SETMASK, &ign, &oset);
+
+	pthread_attr_init(&attr);
+	pthread_attr_getstacksize(&attr, &size);
+
+	// Leave stacklo=0 and set stackhi=size; mstack will do the rest.
+	ts->g->stackhi = size;
+	err = pthread_create(&p, &attr, threadentry, ts);
+
+	pthread_sigmask(SIG_SETMASK, &oset, nil);
+
+	if (err != 0) {
+		fprintf(stderr, "runtime/cgo: pthread_create failed: %s\n", strerror(err));
+		abort();
+	}
+}
+
+static void*
+threadentry(void *v)
+{
+	ThreadStart ts;
+
+	ts = *(ThreadStart*)v;
+	free(v);
+
+	/*
+	 * Set specific keys.
+	 */
+	setg_gcc((void*)ts.g);
+
+	crosscall_amd64(ts.fn);
+	return nil;
+}
diff --git a/src/runtime/cgo/gcc_freebsd_arm.c b/src/runtime/cgo/gcc_freebsd_arm.c
new file mode 100644
index 0000000..2a86a91
--- /dev/null
+++ b/src/runtime/cgo/gcc_freebsd_arm.c
@@ -0,0 +1,82 @@
+// Copyright 2012 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include <sys/types.h>
+#include <machine/sysarch.h>
+#include <sys/signalvar.h>
+#include <pthread.h>
+#include <signal.h>
+#include <string.h>
+#include "libcgo.h"
+
+#ifdef ARM_TP_ADDRESS
+// ARM_TP_ADDRESS is (ARM_VECTORS_HIGH + 0x1000) or 0xffff1000
+// and is known to runtime.read_tls_fallback. Verify it with
+// cpp.
+#if ARM_TP_ADDRESS != 0xffff1000
+#error Wrong ARM_TP_ADDRESS!
+#endif
+#endif
+
+static void *threadentry(void*);
+
+static void (*setg_gcc)(void*);
+
+void
+x_cgo_init(G *g, void (*setg)(void*))
+{
+	pthread_attr_t attr;
+	size_t size;
+
+	setg_gcc = setg;
+	pthread_attr_init(&attr);
+	pthread_attr_getstacksize(&attr, &size);
+	g->stacklo = (uintptr)&attr - size + 4096;
+	pthread_attr_destroy(&attr);
+}
+
+
+void
+_cgo_sys_thread_start(ThreadStart *ts)
+{
+	pthread_attr_t attr;
+	sigset_t ign, oset;
+	pthread_t p;
+	size_t size;
+	int err;
+
+	SIGFILLSET(ign);
+	pthread_sigmask(SIG_SETMASK, &ign, &oset);
+
+	// Not sure why the memset is necessary here,
+	// but without it, we get a bogus stack size
+	// out of pthread_attr_getstacksize.  C'est la Linux.
+	memset(&attr, 0, sizeof attr);
+	pthread_attr_init(&attr);
+	size = 0;
+	pthread_attr_getstacksize(&attr, &size);
+	// Leave stacklo=0 and set stackhi=size; mstack will do the rest.
+	ts->g->stackhi = size;
+	err = pthread_create(&p, &attr, threadentry, ts);
+
+	pthread_sigmask(SIG_SETMASK, &oset, nil);
+
+	if (err != 0) {
+		fprintf(stderr, "runtime/cgo: pthread_create failed: %s\n", strerror(err));
+		abort();
+	}
+}
+
+extern void crosscall_arm1(void (*fn)(void), void (*setg_gcc)(void*), void *g);
+static void*
+threadentry(void *v)
+{
+	ThreadStart ts;
+
+	ts = *(ThreadStart*)v;
+	free(v);
+
+	crosscall_arm1(ts.fn, setg_gcc, (void*)ts.g);
+	return nil;
+}
diff --git a/src/runtime/cgo/gcc_linux_386.c b/src/runtime/cgo/gcc_linux_386.c
new file mode 100644
index 0000000..9801c87
--- /dev/null
+++ b/src/runtime/cgo/gcc_linux_386.c
@@ -0,0 +1,72 @@
+// Copyright 2009 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include <pthread.h>
+#include <string.h>
+#include <signal.h>
+#include "libcgo.h"
+
+static void *threadentry(void*);
+static void (*setg_gcc)(void*);
+
+void
+x_cgo_init(G *g, void (*setg)(void*))
+{
+	pthread_attr_t attr;
+	size_t size;
+
+	setg_gcc = setg;
+	pthread_attr_init(&attr);
+	pthread_attr_getstacksize(&attr, &size);
+	g->stacklo = (uintptr)&attr - size + 4096;
+	pthread_attr_destroy(&attr);
+}
+
+
+void
+_cgo_sys_thread_start(ThreadStart *ts)
+{
+	pthread_attr_t attr;
+	sigset_t ign, oset;
+	pthread_t p;
+	size_t size;
+	int err;
+
+	sigfillset(&ign);
+	pthread_sigmask(SIG_SETMASK, &ign, &oset);
+
+	// Not sure why the memset is necessary here,
+	// but without it, we get a bogus stack size
+	// out of pthread_attr_getstacksize.  C'est la Linux.
+	memset(&attr, 0, sizeof attr);
+	pthread_attr_init(&attr);
+	size = 0;
+	pthread_attr_getstacksize(&attr, &size);
+	// Leave stacklo=0 and set stackhi=size; mstack will do the rest.
+	ts->g->stackhi = size;
+	err = pthread_create(&p, &attr, threadentry, ts);
+
+	pthread_sigmask(SIG_SETMASK, &oset, nil);
+
+	if (err != 0) {
+		fatalf("pthread_create failed: %s", strerror(err));
+	}
+}
+
+static void*
+threadentry(void *v)
+{
+	ThreadStart ts;
+
+	ts = *(ThreadStart*)v;
+	free(v);
+
+	/*
+	 * Set specific keys.
+	 */
+	setg_gcc((void*)ts.g);
+
+	crosscall_386(ts.fn);
+	return nil;
+}
diff --git a/src/runtime/cgo/gcc_linux_amd64.c b/src/runtime/cgo/gcc_linux_amd64.c
new file mode 100644
index 0000000..275d5dd
--- /dev/null
+++ b/src/runtime/cgo/gcc_linux_amd64.c
@@ -0,0 +1,67 @@
+// Copyright 2009 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include <pthread.h>
+#include <string.h> // strerror
+#include <signal.h>
+#include "libcgo.h"
+
+static void* threadentry(void*);
+static void (*setg_gcc)(void*);
+
+void
+x_cgo_init(G* g, void (*setg)(void*))
+{
+	pthread_attr_t attr;
+	size_t size;
+
+	setg_gcc = setg;
+	pthread_attr_init(&attr);
+	pthread_attr_getstacksize(&attr, &size);
+	g->stacklo = (uintptr)&attr - size + 4096;
+	pthread_attr_destroy(&attr);
+}
+
+
+void
+_cgo_sys_thread_start(ThreadStart *ts)
+{
+	pthread_attr_t attr;
+	sigset_t ign, oset;
+	pthread_t p;
+	size_t size;
+	int err;
+
+	sigfillset(&ign);
+	pthread_sigmask(SIG_SETMASK, &ign, &oset);
+
+	pthread_attr_init(&attr);
+	pthread_attr_getstacksize(&attr, &size);
+	// Leave stacklo=0 and set stackhi=size; mstack will do the rest.
+	ts->g->stackhi = size;
+	err = pthread_create(&p, &attr, threadentry, ts);
+
+	pthread_sigmask(SIG_SETMASK, &oset, nil);
+
+	if (err != 0) {
+		fatalf("pthread_create failed: %s", strerror(err));
+	}
+}
+
+static void*
+threadentry(void *v)
+{
+	ThreadStart ts;
+
+	ts = *(ThreadStart*)v;
+	free(v);
+
+	/*
+	 * Set specific keys.
+	 */
+	setg_gcc((void*)ts.g);
+
+	crosscall_amd64(ts.fn);
+	return nil;
+}
diff --git a/src/runtime/cgo/gcc_linux_arm.c b/src/runtime/cgo/gcc_linux_arm.c
new file mode 100644
index 0000000..7d4b4d6
--- /dev/null
+++ b/src/runtime/cgo/gcc_linux_arm.c
@@ -0,0 +1,73 @@
+// Copyright 2010 The Go 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 <pthread.h>
+#include <string.h>
+#include <signal.h>
+#include "libcgo.h"
+
+static void *threadentry(void*);
+
+void (*x_cgo_inittls)(void **tlsg, void **tlsbase);
+void (*setg_gcc)(void*);
+
+void
+_cgo_sys_thread_start(ThreadStart *ts)
+{
+	pthread_attr_t attr;
+	sigset_t ign, oset;
+	pthread_t p;
+	size_t size;
+	int err;
+
+	sigfillset(&ign);
+	pthread_sigmask(SIG_SETMASK, &ign, &oset);
+
+	// Not sure why the memset is necessary here,
+	// but without it, we get a bogus stack size
+	// out of pthread_attr_getstacksize.  C'est la Linux.
+	memset(&attr, 0, sizeof attr);
+	pthread_attr_init(&attr);
+	size = 0;
+	pthread_attr_getstacksize(&attr, &size);
+	// Leave stacklo=0 and set stackhi=size; mstack will do the rest.
+	ts->g->stackhi = size;
+	err = pthread_create(&p, &attr, threadentry, ts);
+
+	pthread_sigmask(SIG_SETMASK, &oset, nil);
+
+	if (err != 0) {
+		fatalf("pthread_create failed: %s", strerror(err));
+	}
+}
+
+extern void crosscall_arm1(void (*fn)(void), void (*setg_gcc)(void*), void *g);
+static void*
+threadentry(void *v)
+{
+	ThreadStart ts;
+
+	ts = *(ThreadStart*)v;
+	free(v);
+
+	crosscall_arm1(ts.fn, setg_gcc, (void*)ts.g);
+	return nil;
+}
+
+void
+x_cgo_init(G *g, void (*setg)(void*), void **tlsg, void **tlsbase)
+{
+	pthread_attr_t attr;
+	size_t size;
+
+	setg_gcc = setg;
+	pthread_attr_init(&attr);
+	pthread_attr_getstacksize(&attr, &size);
+	g->stacklo = (uintptr)&attr - size + 4096;
+	pthread_attr_destroy(&attr);
+
+	if (x_cgo_inittls) {
+		x_cgo_inittls(tlsg, tlsbase);
+	}
+}
diff --git a/src/runtime/cgo/gcc_netbsd_386.c b/src/runtime/cgo/gcc_netbsd_386.c
new file mode 100644
index 0000000..2505e6d
--- /dev/null
+++ b/src/runtime/cgo/gcc_netbsd_386.c
@@ -0,0 +1,69 @@
+// Copyright 2009 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include <sys/types.h>
+#include <pthread.h>
+#include <signal.h>
+#include <string.h>
+#include "libcgo.h"
+
+static void* threadentry(void*);
+static void (*setg_gcc)(void*);
+
+void
+x_cgo_init(G *g, void (*setg)(void*))
+{
+	pthread_attr_t attr;
+	size_t size;
+
+	setg_gcc = setg;
+	pthread_attr_init(&attr);
+	pthread_attr_getstacksize(&attr, &size);
+	g->stacklo = (uintptr)&attr - size + 4096;
+	pthread_attr_destroy(&attr);
+}
+
+
+void
+_cgo_sys_thread_start(ThreadStart *ts)
+{
+	pthread_attr_t attr;
+	sigset_t ign, oset;
+	pthread_t p;
+	size_t size;
+	int err;
+
+	sigfillset(&ign);
+	pthread_sigmask(SIG_SETMASK, &ign, &oset);
+
+	pthread_attr_init(&attr);
+	pthread_attr_getstacksize(&attr, &size);
+	// Leave stacklo=0 and set stackhi=size; mstack will do the rest.
+	ts->g->stackhi = size;
+	err = pthread_create(&p, &attr, threadentry, ts);
+
+	pthread_sigmask(SIG_SETMASK, &oset, nil);
+
+	if (err != 0) {
+		fprintf(stderr, "runtime/cgo: pthread_create failed: %s\n", strerror(err));
+		abort();
+	}
+}
+
+static void*
+threadentry(void *v)
+{
+	ThreadStart ts;
+
+	ts = *(ThreadStart*)v;
+	free(v);
+
+	/*
+	 * Set specific keys.
+	 */
+	setg_gcc((void*)ts.g);
+
+	crosscall_386(ts.fn);
+	return nil;
+}
diff --git a/src/runtime/cgo/gcc_netbsd_amd64.c b/src/runtime/cgo/gcc_netbsd_amd64.c
new file mode 100644
index 0000000..8f64650
--- /dev/null
+++ b/src/runtime/cgo/gcc_netbsd_amd64.c
@@ -0,0 +1,70 @@
+// Copyright 2009 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include <sys/types.h>
+#include <pthread.h>
+#include <signal.h>
+#include <string.h>
+#include "libcgo.h"
+
+static void* threadentry(void*);
+static void (*setg_gcc)(void*);
+
+void
+x_cgo_init(G *g, void (*setg)(void*))
+{
+	pthread_attr_t attr;
+	size_t size;
+
+	setg_gcc = setg;
+	pthread_attr_init(&attr);
+	pthread_attr_getstacksize(&attr, &size);
+	g->stacklo = (uintptr)&attr - size + 4096;
+	pthread_attr_destroy(&attr);
+}
+
+
+void
+_cgo_sys_thread_start(ThreadStart *ts)
+{
+	pthread_attr_t attr;
+	sigset_t ign, oset;
+	pthread_t p;
+	size_t size;
+	int err;
+
+	sigfillset(&ign);
+	pthread_sigmask(SIG_SETMASK, &ign, &oset);
+
+	pthread_attr_init(&attr);
+	pthread_attr_getstacksize(&attr, &size);
+
+	// Leave stacklo=0 and set stackhi=size; mstack will do the rest.
+	ts->g->stackhi = size;
+	err = pthread_create(&p, &attr, threadentry, ts);
+
+	pthread_sigmask(SIG_SETMASK, &oset, nil);
+
+	if (err != 0) {
+		fprintf(stderr, "runtime/cgo: pthread_create failed: %s\n", strerror(err));
+		abort();
+	}
+}
+
+static void*
+threadentry(void *v)
+{
+	ThreadStart ts;
+
+	ts = *(ThreadStart*)v;
+	free(v);
+
+	/*
+	 * Set specific keys.
+	 */
+	setg_gcc((void*)ts.g);
+
+	crosscall_amd64(ts.fn);
+	return nil;
+}
diff --git a/src/runtime/cgo/gcc_netbsd_arm.c b/src/runtime/cgo/gcc_netbsd_arm.c
new file mode 100644
index 0000000..7a98c0d
--- /dev/null
+++ b/src/runtime/cgo/gcc_netbsd_arm.c
@@ -0,0 +1,66 @@
+// Copyright 2013 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include <sys/types.h>
+#include <pthread.h>
+#include <signal.h>
+#include <string.h>
+#include "libcgo.h"
+
+static void *threadentry(void*);
+
+static void (*setg_gcc)(void*);
+
+void
+x_cgo_init(G *g, void (*setg)(void*))
+{
+	pthread_attr_t attr;
+	size_t size;
+
+	setg_gcc = setg;
+	pthread_attr_init(&attr);
+	pthread_attr_getstacksize(&attr, &size);
+	g->stacklo = (uintptr)&attr - size + 4096;
+	pthread_attr_destroy(&attr);
+}
+
+
+void
+_cgo_sys_thread_start(ThreadStart *ts)
+{
+	pthread_attr_t attr;
+	sigset_t ign, oset;
+	pthread_t p;
+	size_t size;
+	int err;
+
+	sigfillset(&ign);
+	pthread_sigmask(SIG_SETMASK, &ign, &oset);
+
+	pthread_attr_init(&attr);
+	pthread_attr_getstacksize(&attr, &size);
+	// Leave stacklo=0 and set stackhi=size; mstack will do the rest.
+	ts->g->stackhi = size;
+	err = pthread_create(&p, &attr, threadentry, ts);
+
+	pthread_sigmask(SIG_SETMASK, &oset, nil);
+
+	if (err != 0) {
+		fprintf(stderr, "runtime/cgo: pthread_create failed: %s\n", strerror(err));
+		abort();
+	}
+}
+
+extern void crosscall_arm1(void (*fn)(void), void (*setg_gcc)(void*), void *g);
+static void*
+threadentry(void *v)
+{
+	ThreadStart ts;
+
+	ts = *(ThreadStart*)v;
+	free(v);
+
+	crosscall_arm1(ts.fn, setg_gcc, (void*)ts.g);
+	return nil;
+}
diff --git a/src/runtime/cgo/gcc_openbsd_386.c b/src/runtime/cgo/gcc_openbsd_386.c
new file mode 100644
index 0000000..582e943
--- /dev/null
+++ b/src/runtime/cgo/gcc_openbsd_386.c
@@ -0,0 +1,158 @@
+// Copyright 2009 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include <sys/types.h>
+#include <dlfcn.h>
+#include <errno.h>
+#include <pthread.h>
+#include <signal.h>
+#include <string.h>
+#include "libcgo.h"
+
+static void* threadentry(void*);
+static void (*setg_gcc)(void*);
+
+// TCB_SIZE is sizeof(struct thread_control_block),
+// as defined in /usr/src/lib/librthread/tcb.h
+#define TCB_SIZE (4 * sizeof(void *))
+#define TLS_SIZE (2 * sizeof(void *))
+
+void *__get_tcb(void);
+void __set_tcb(void *);
+
+static int (*sys_pthread_create)(pthread_t *thread, const pthread_attr_t *attr,
+	void *(*start_routine)(void *), void *arg);
+
+struct thread_args {
+	void *(*func)(void *);
+	void *arg;
+};
+
+static void
+tcb_fixup(int mainthread)
+{
+	void *newtcb, *oldtcb;
+
+	// The OpenBSD ld.so(1) does not currently support PT_TLS. As a result,
+	// we need to allocate our own TLS space while preserving the existing
+	// TCB that has been setup via librthread.
+
+	newtcb = malloc(TCB_SIZE + TLS_SIZE);
+	if(newtcb == NULL)
+		abort();
+
+	// The signal trampoline expects the TLS slots to be zeroed.
+	bzero(newtcb, TLS_SIZE);
+
+	oldtcb = __get_tcb();
+	bcopy(oldtcb, newtcb + TLS_SIZE, TCB_SIZE);
+	__set_tcb(newtcb + TLS_SIZE);
+
+	// NOTE(jsing, minux): we can't free oldtcb without causing double-free
+	// problem. so newtcb will be memory leaks. Get rid of this when OpenBSD
+	// has proper support for PT_TLS.
+}
+
+static void *
+thread_start_wrapper(void *arg)
+{
+	struct thread_args args = *(struct thread_args *)arg;
+
+	free(arg);
+	tcb_fixup(0);
+
+	return args.func(args.arg);
+}
+
+int
+pthread_create(pthread_t *thread, const pthread_attr_t *attr,
+	void *(*start_routine)(void *), void *arg)
+{
+	struct thread_args *p;
+
+	p = malloc(sizeof(*p));
+	if(p == NULL) {
+		errno = ENOMEM;
+		return -1;
+	}
+	p->func = start_routine;
+	p->arg = arg;
+
+	return sys_pthread_create(thread, attr, thread_start_wrapper, p);
+}
+
+void
+x_cgo_init(G *g, void (*setg)(void*))
+{
+	pthread_attr_t attr;
+	size_t size;
+	void *handle;
+
+	setg_gcc = setg;
+	pthread_attr_init(&attr);
+	pthread_attr_getstacksize(&attr, &size);
+	g->stacklo = (uintptr)&attr - size + 4096;
+	pthread_attr_destroy(&attr);
+
+	// Locate symbol for the system pthread_create function.
+	handle = dlopen("libpthread.so", RTLD_LAZY);
+	if(handle == NULL) {
+		fprintf(stderr, "dlopen: failed to load libpthread: %s\n", dlerror());
+		abort();
+	}
+	sys_pthread_create = dlsym(handle, "pthread_create");
+	if(sys_pthread_create == NULL) {
+		fprintf(stderr, "dlsym: failed to find pthread_create: %s\n", dlerror());
+		abort();
+	}
+	dlclose(handle);
+
+	tcb_fixup(1);
+}
+
+
+void
+_cgo_sys_thread_start(ThreadStart *ts)
+{
+	pthread_attr_t attr;
+	sigset_t ign, oset;
+	pthread_t p;
+	size_t size;
+	int err;
+
+	sigfillset(&ign);
+	pthread_sigmask(SIG_SETMASK, &ign, &oset);
+
+	pthread_attr_init(&attr);
+	pthread_attr_getstacksize(&attr, &size);
+	// Leave stacklo=0 and set stackhi=size; mstack will do the rest.
+	ts->g->stackhi = size;
+	err = sys_pthread_create(&p, &attr, threadentry, ts);
+
+	pthread_sigmask(SIG_SETMASK, &oset, nil);
+
+	if (err != 0) {
+		fprintf(stderr, "runtime/cgo: pthread_create failed: %s\n", strerror(err));
+		abort();
+	}
+}
+
+static void*
+threadentry(void *v)
+{
+	ThreadStart ts;
+
+	tcb_fixup(0);
+
+	ts = *(ThreadStart*)v;
+	free(v);
+
+	/*
+	 * Set specific keys.
+	 */
+	setg_gcc((void*)ts.g);
+
+	crosscall_386(ts.fn);
+	return nil;
+}
diff --git a/src/runtime/cgo/gcc_openbsd_amd64.c b/src/runtime/cgo/gcc_openbsd_amd64.c
new file mode 100644
index 0000000..35b359b
--- /dev/null
+++ b/src/runtime/cgo/gcc_openbsd_amd64.c
@@ -0,0 +1,159 @@
+// Copyright 2009 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include <sys/types.h>
+#include <dlfcn.h>
+#include <errno.h>
+#include <pthread.h>
+#include <signal.h>
+#include <string.h>
+#include "libcgo.h"
+
+static void* threadentry(void*);
+static void (*setg_gcc)(void*);
+
+// TCB_SIZE is sizeof(struct thread_control_block),
+// as defined in /usr/src/lib/librthread/tcb.h
+#define TCB_SIZE (4 * sizeof(void *))
+#define TLS_SIZE (2 * sizeof(void *))
+
+void *__get_tcb(void);
+void __set_tcb(void *);
+
+static int (*sys_pthread_create)(pthread_t *thread, const pthread_attr_t *attr,
+	void *(*start_routine)(void *), void *arg);
+
+struct thread_args {
+	void *(*func)(void *);
+	void *arg;
+};
+
+static void
+tcb_fixup(int mainthread)
+{
+	void *newtcb, *oldtcb;
+
+	// The OpenBSD ld.so(1) does not currently support PT_TLS. As a result,
+	// we need to allocate our own TLS space while preserving the existing
+	// TCB that has been setup via librthread.
+
+	newtcb = malloc(TCB_SIZE + TLS_SIZE);
+	if(newtcb == NULL)
+		abort();
+
+	// The signal trampoline expects the TLS slots to be zeroed.
+	bzero(newtcb, TLS_SIZE);
+
+	oldtcb = __get_tcb();
+	bcopy(oldtcb, newtcb + TLS_SIZE, TCB_SIZE);
+	__set_tcb(newtcb + TLS_SIZE);
+
+	// NOTE(jsing, minux): we can't free oldtcb without causing double-free
+	// problem. so newtcb will be memory leaks. Get rid of this when OpenBSD
+	// has proper support for PT_TLS.
+}
+
+static void *
+thread_start_wrapper(void *arg)
+{
+	struct thread_args args = *(struct thread_args *)arg;
+
+	free(arg);
+	tcb_fixup(0);
+
+	return args.func(args.arg);
+}
+
+int
+pthread_create(pthread_t *thread, const pthread_attr_t *attr,
+	void *(*start_routine)(void *), void *arg)
+{
+	struct thread_args *p;
+
+	p = malloc(sizeof(*p));
+	if(p == NULL) {
+		errno = ENOMEM;
+		return -1;
+	}
+	p->func = start_routine;
+	p->arg = arg;
+
+	return sys_pthread_create(thread, attr, thread_start_wrapper, p);
+}
+
+void
+x_cgo_init(G *g, void (*setg)(void*))
+{
+	pthread_attr_t attr;
+	size_t size;
+	void *handle;
+
+	setg_gcc = setg;
+	pthread_attr_init(&attr);
+	pthread_attr_getstacksize(&attr, &size);
+	g->stacklo = (uintptr)&attr - size + 4096;
+	pthread_attr_destroy(&attr);
+
+	// Locate symbol for the system pthread_create function.
+	handle = dlopen("libpthread.so", RTLD_LAZY);
+	if(handle == NULL) {
+		fprintf(stderr, "dlopen: failed to load libpthread: %s\n", dlerror());
+		abort();
+	}
+	sys_pthread_create = dlsym(handle, "pthread_create");
+	if(sys_pthread_create == NULL) {
+		fprintf(stderr, "dlsym: failed to find pthread_create: %s\n", dlerror());
+		abort();
+	}
+	dlclose(handle);
+
+	tcb_fixup(1);
+}
+
+
+void
+_cgo_sys_thread_start(ThreadStart *ts)
+{
+	pthread_attr_t attr;
+	sigset_t ign, oset;
+	pthread_t p;
+	size_t size;
+	int err;
+
+	sigfillset(&ign);
+	pthread_sigmask(SIG_SETMASK, &ign, &oset);
+
+	pthread_attr_init(&attr);
+	pthread_attr_getstacksize(&attr, &size);
+
+	// Leave stacklo=0 and set stackhi=size; mstack will do the rest.
+	ts->g->stackhi = size;
+	err = sys_pthread_create(&p, &attr, threadentry, ts);
+
+	pthread_sigmask(SIG_SETMASK, &oset, nil);
+
+	if (err != 0) {
+		fprintf(stderr, "runtime/cgo: pthread_create failed: %s\n", strerror(err));
+		abort();
+	}
+}
+
+static void*
+threadentry(void *v)
+{
+	ThreadStart ts;
+
+	tcb_fixup(0);
+
+	ts = *(ThreadStart*)v;
+	free(v);
+
+	/*
+	 * Set specific keys.
+	 */
+	setg_gcc((void*)ts.g);
+
+	crosscall_amd64(ts.fn);
+	return nil;
+}
diff --git a/src/runtime/cgo/gcc_setenv.c b/src/runtime/cgo/gcc_setenv.c
new file mode 100644
index 0000000..af0fc5d
--- /dev/null
+++ b/src/runtime/cgo/gcc_setenv.c
@@ -0,0 +1,23 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin dragonfly freebsd linux netbsd openbsd
+
+#include "libcgo.h"
+
+#include <stdlib.h>
+
+/* Stub for calling setenv */
+void
+x_cgo_setenv(char **arg)
+{
+	setenv(arg[0], arg[1], 1);
+}
+
+/* Stub for calling unsetenv */
+void
+x_cgo_unsetenv(char *arg)
+{
+	unsetenv(arg);
+}
diff --git a/src/pkg/runtime/cgo/gcc_util.c b/src/runtime/cgo/gcc_util.c
similarity index 100%
rename from src/pkg/runtime/cgo/gcc_util.c
rename to src/runtime/cgo/gcc_util.c
diff --git a/src/runtime/cgo/gcc_windows_386.c b/src/runtime/cgo/gcc_windows_386.c
new file mode 100644
index 0000000..acd038c
--- /dev/null
+++ b/src/runtime/cgo/gcc_windows_386.c
@@ -0,0 +1,61 @@
+// Copyright 2009 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <process.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "libcgo.h"
+
+static void threadentry(void*);
+
+/* 1MB is default stack size for 32-bit Windows.
+   Allocation granularity on Windows is typically 64 KB.
+   The constant is also hardcoded in cmd/ld/pe.c (keep synchronized). */
+#define STACKSIZE (1*1024*1024)
+
+void
+x_cgo_init(G *g)
+{
+	int tmp;
+	g->stacklo = (uintptr)&tmp - STACKSIZE + 8*1024;
+}
+
+
+void
+_cgo_sys_thread_start(ThreadStart *ts)
+{
+	uintptr_t thandle;
+
+	thandle = _beginthread(threadentry, 0, ts);
+	if(thandle == -1) {
+		fprintf(stderr, "runtime: failed to create new OS thread (%d)\n", errno);
+		abort();
+	}
+}
+
+static void
+threadentry(void *v)
+{
+	ThreadStart ts;
+
+	ts = *(ThreadStart*)v;
+	free(v);
+
+	ts.g->stackhi = (uintptr)&ts;
+	ts.g->stacklo = (uintptr)&ts - STACKSIZE + 8*1024;
+
+	/*
+	 * Set specific keys in thread local storage.
+	 */
+	asm volatile (
+		"movl %0, %%fs:0x14\n"	// MOVL tls0, 0x14(FS)
+		"movl %%fs:0x14, %%eax\n"	// MOVL 0x14(FS), tmp
+		"movl %1, 0(%%eax)\n"	// MOVL g, 0(FS)
+		:: "r"(ts.tls), "r"(ts.g) : "%eax"
+	);
+	
+	crosscall_386(ts.fn);
+}
diff --git a/src/runtime/cgo/gcc_windows_amd64.c b/src/runtime/cgo/gcc_windows_amd64.c
new file mode 100644
index 0000000..ce7e06b
--- /dev/null
+++ b/src/runtime/cgo/gcc_windows_amd64.c
@@ -0,0 +1,61 @@
+// Copyright 2009 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#define WIN64_LEAN_AND_MEAN
+#include <windows.h>
+#include <process.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "libcgo.h"
+
+static void threadentry(void*);
+
+/* 2MB is default stack size for 64-bit Windows.
+   Allocation granularity on Windows is typically 64 KB.
+   The constant is also hardcoded in cmd/ld/pe.c (keep synchronized). */
+#define STACKSIZE (2*1024*1024)
+
+void
+x_cgo_init(G *g)
+{
+	int tmp;
+	g->stacklo = (uintptr)&tmp - STACKSIZE + 8*1024;
+}
+
+
+void
+_cgo_sys_thread_start(ThreadStart *ts)
+{
+	uintptr_t thandle;
+
+	thandle = _beginthread(threadentry, 0, ts);
+	if(thandle == -1) {
+		fprintf(stderr, "runtime: failed to create new OS thread (%d)\n", errno);
+		abort();
+	}
+}
+
+static void
+threadentry(void *v)
+{
+	ThreadStart ts;
+
+	ts = *(ThreadStart*)v;
+	free(v);
+
+	ts.g->stackhi = (uintptr)&ts;
+	ts.g->stacklo = (uintptr)&ts - STACKSIZE + 8*1024;
+
+	/*
+	 * Set specific keys in thread local storage.
+	 */
+	asm volatile (
+	  "movq %0, %%gs:0x28\n"	// MOVL tls0, 0x28(GS)
+	  "movq %%gs:0x28, %%rax\n" // MOVQ 0x28(GS), tmp
+	  "movq %1, 0(%%rax)\n" // MOVQ g, 0(GS)
+	  :: "r"(ts.tls), "r"(ts.g) : "%rax"
+	);
+
+	crosscall_amd64(ts.fn);
+}
diff --git a/src/pkg/runtime/cgo/iscgo.c b/src/runtime/cgo/iscgo.c
similarity index 100%
rename from src/pkg/runtime/cgo/iscgo.c
rename to src/runtime/cgo/iscgo.c
diff --git a/src/runtime/cgo/libcgo.h b/src/runtime/cgo/libcgo.h
new file mode 100644
index 0000000..9d918fd
--- /dev/null
+++ b/src/runtime/cgo/libcgo.h
@@ -0,0 +1,65 @@
+// Copyright 2009 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#define nil ((void*)0)
+#define nelem(x) (sizeof(x)/sizeof((x)[0]))
+
+typedef uint32_t uint32;
+typedef uint64_t uint64;
+typedef uintptr_t uintptr;
+
+/*
+ * The beginning of the per-goroutine structure,
+ * as defined in ../pkg/runtime/runtime.h.
+ * Just enough to edit these two fields.
+ */
+typedef struct G G;
+struct G
+{
+	uintptr stacklo;
+	uintptr stackhi;
+};
+
+/*
+ * Arguments to the _cgo_thread_start call.
+ * Also known to ../pkg/runtime/runtime.h.
+ */
+typedef struct ThreadStart ThreadStart;
+struct ThreadStart
+{
+	G *g;
+	uintptr *tls;
+	void (*fn)(void);
+};
+
+/*
+ * Called by 5c/6c/8c world.
+ * Makes a local copy of the ThreadStart and
+ * calls _cgo_sys_thread_start(ts).
+ */
+extern void (*_cgo_thread_start)(ThreadStart *ts);
+
+/*
+ * Creates the new operating system thread (OS, arch dependent).
+ */
+void _cgo_sys_thread_start(ThreadStart *ts);
+
+/*
+ * Call fn in the 6c world.
+ */
+void crosscall_amd64(void (*fn)(void));
+
+/*
+ * Call fn in the 8c world.
+ */
+void crosscall_386(void (*fn)(void));
+
+/*
+ * Prints error then calls abort. For linux and android.
+ */
+void fatalf(const char* format, ...);
diff --git a/src/runtime/cgo/netbsd.c b/src/runtime/cgo/netbsd.c
new file mode 100644
index 0000000..076cc87
--- /dev/null
+++ b/src/runtime/cgo/netbsd.c
@@ -0,0 +1,19 @@
+// Copyright 2010 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build netbsd
+
+#include "textflag.h"
+
+// Supply environ and __progname, because we don't
+// link against the standard NetBSD crt0.o and the
+// libc dynamic library needs them.
+
+#pragma dataflag NOPTR
+char *environ[1];
+#pragma dataflag NOPTR
+char *__progname;
+
+#pragma dynexport environ environ
+#pragma dynexport __progname __progname
diff --git a/src/runtime/cgo/openbsd.c b/src/runtime/cgo/openbsd.c
new file mode 100644
index 0000000..4766495
--- /dev/null
+++ b/src/runtime/cgo/openbsd.c
@@ -0,0 +1,27 @@
+// Copyright 2010 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build openbsd
+
+#include "textflag.h"
+
+// Supply environ, __progname and __guard_local, because
+// we don't link against the standard OpenBSD crt0.o and
+// the libc dynamic library needs them.
+
+#pragma dataflag NOPTR
+char *environ[1];
+#pragma dataflag NOPTR
+char *__progname;
+long __guard_local;
+
+#pragma dynexport environ environ
+#pragma dynexport __progname __progname
+
+// This is normally marked as hidden and placed in the
+// .openbsd.randomdata section.
+#pragma dynexport __guard_local __guard_local
+
+// We override pthread_create to support PT_TLS.
+#pragma dynexport pthread_create pthread_create
diff --git a/src/runtime/cgo/setenv.c b/src/runtime/cgo/setenv.c
new file mode 100644
index 0000000..76d88cb
--- /dev/null
+++ b/src/runtime/cgo/setenv.c
@@ -0,0 +1,13 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin dragonfly freebsd linux netbsd openbsd
+
+#pragma cgo_import_static x_cgo_setenv
+#pragma cgo_import_static x_cgo_unsetenv
+
+void x_cgo_setenv(char**);
+void (*runtime·_cgo_setenv)(char**) = x_cgo_setenv;
+void x_cgo_unsetenv(char**);
+void (*runtime·_cgo_unsetenv)(char**) = x_cgo_unsetenv;
diff --git a/src/runtime/cgocall.go b/src/runtime/cgocall.go
new file mode 100644
index 0000000..7fd9146
--- /dev/null
+++ b/src/runtime/cgocall.go
@@ -0,0 +1,279 @@
+// Copyright 2009 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Cgo call and callback support.
+//
+// To call into the C function f from Go, the cgo-generated code calls
+// runtime.cgocall(_cgo_Cfunc_f, frame), where _cgo_Cfunc_f is a
+// gcc-compiled function written by cgo.
+//
+// runtime.cgocall (below) locks g to m, calls entersyscall
+// so as not to block other goroutines or the garbage collector,
+// and then calls runtime.asmcgocall(_cgo_Cfunc_f, frame).
+//
+// runtime.asmcgocall (in asm_$GOARCH.s) switches to the m->g0 stack
+// (assumed to be an operating system-allocated stack, so safe to run
+// gcc-compiled code on) and calls _cgo_Cfunc_f(frame).
+//
+// _cgo_Cfunc_f invokes the actual C function f with arguments
+// taken from the frame structure, records the results in the frame,
+// and returns to runtime.asmcgocall.
+//
+// After it regains control, runtime.asmcgocall switches back to the
+// original g (m->curg)'s stack and returns to runtime.cgocall.
+//
+// After it regains control, runtime.cgocall calls exitsyscall, which blocks
+// until this m can run Go code without violating the $GOMAXPROCS limit,
+// and then unlocks g from m.
+//
+// The above description skipped over the possibility of the gcc-compiled
+// function f calling back into Go.  If that happens, we continue down
+// the rabbit hole during the execution of f.
+//
+// To make it possible for gcc-compiled C code to call a Go function p.GoF,
+// cgo writes a gcc-compiled function named GoF (not p.GoF, since gcc doesn't
+// know about packages).  The gcc-compiled C function f calls GoF.
+//
+// GoF calls crosscall2(_cgoexp_GoF, frame, framesize).  Crosscall2
+// (in cgo/gcc_$GOARCH.S, a gcc-compiled assembly file) is a two-argument
+// adapter from the gcc function call ABI to the 6c function call ABI.
+// It is called from gcc to call 6c functions.  In this case it calls
+// _cgoexp_GoF(frame, framesize), still running on m->g0's stack
+// and outside the $GOMAXPROCS limit.  Thus, this code cannot yet
+// call arbitrary Go code directly and must be careful not to allocate
+// memory or use up m->g0's stack.
+//
+// _cgoexp_GoF calls runtime.cgocallback(p.GoF, frame, framesize).
+// (The reason for having _cgoexp_GoF instead of writing a crosscall3
+// to make this call directly is that _cgoexp_GoF, because it is compiled
+// with 6c instead of gcc, can refer to dotted names like
+// runtime.cgocallback and p.GoF.)
+//
+// runtime.cgocallback (in asm_$GOARCH.s) switches from m->g0's
+// stack to the original g (m->curg)'s stack, on which it calls
+// runtime.cgocallbackg(p.GoF, frame, framesize).
+// As part of the stack switch, runtime.cgocallback saves the current
+// SP as m->g0->sched.sp, so that any use of m->g0's stack during the
+// execution of the callback will be done below the existing stack frames.
+// Before overwriting m->g0->sched.sp, it pushes the old value on the
+// m->g0 stack, so that it can be restored later.
+//
+// runtime.cgocallbackg (below) is now running on a real goroutine
+// stack (not an m->g0 stack).  First it calls runtime.exitsyscall, which will
+// block until the $GOMAXPROCS limit allows running this goroutine.
+// Once exitsyscall has returned, it is safe to do things like call the memory
+// allocator or invoke the Go callback function p.GoF.  runtime.cgocallbackg
+// first defers a function to unwind m->g0.sched.sp, so that if p.GoF
+// panics, m->g0.sched.sp will be restored to its old value: the m->g0 stack
+// and the m->curg stack will be unwound in lock step.
+// Then it calls p.GoF.  Finally it pops but does not execute the deferred
+// function, calls runtime.entersyscall, and returns to runtime.cgocallback.
+//
+// After it regains control, runtime.cgocallback switches back to
+// m->g0's stack (the pointer is still in m->g0.sched.sp), restores the old
+// m->g0.sched.sp value from the stack, and returns to _cgoexp_GoF.
+//
+// _cgoexp_GoF immediately returns to crosscall2, which restores the
+// callee-save registers for gcc and returns to GoF, which returns to f.
+
+package runtime
+
+import "unsafe"
+
+// Call from Go to C.
+//go:nosplit
+func cgocall(fn, arg unsafe.Pointer) {
+	cgocall_errno(fn, arg)
+}
+
+//go:nosplit
+func cgocall_errno(fn, arg unsafe.Pointer) int32 {
+	if !iscgo && GOOS != "solaris" && GOOS != "windows" {
+		gothrow("cgocall unavailable")
+	}
+
+	if fn == nil {
+		gothrow("cgocall nil")
+	}
+
+	if raceenabled {
+		racereleasemerge(unsafe.Pointer(&racecgosync))
+	}
+
+	// Create an extra M for callbacks on threads not created by Go on first cgo call.
+	if needextram == 1 && cas(&needextram, 1, 0) {
+		onM(newextram)
+	}
+
+	/*
+	 * Lock g to m to ensure we stay on the same stack if we do a
+	 * cgo callback. Add entry to defer stack in case of panic.
+	 */
+	lockOSThread()
+	mp := getg().m
+	mp.ncgocall++
+	mp.ncgo++
+	defer endcgo(mp)
+
+	/*
+	 * Announce we are entering a system call
+	 * so that the scheduler knows to create another
+	 * M to run goroutines while we are in the
+	 * foreign code.
+	 *
+	 * The call to asmcgocall is guaranteed not to
+	 * split the stack and does not allocate memory,
+	 * so it is safe to call while "in a system call", outside
+	 * the $GOMAXPROCS accounting.
+	 */
+	entersyscall()
+	errno := asmcgocall_errno(fn, arg)
+	exitsyscall()
+
+	return errno
+}
+
+//go:nosplit
+func endcgo(mp *m) {
+	mp.ncgo--
+	if mp.ncgo == 0 {
+		// We are going back to Go and are not in a recursive
+		// call.  Let the GC collect any memory allocated via
+		// _cgo_allocate that is no longer referenced.
+		mp.cgomal = nil
+	}
+
+	if raceenabled {
+		raceacquire(unsafe.Pointer(&racecgosync))
+	}
+
+	unlockOSThread() // invalidates mp
+}
+
+// Helper functions for cgo code.
+
+// Filled by schedinit from corresponding C variables,
+// which are in turn filled in by dynamic linker when Cgo is available.
+var cgoMalloc, cgoFree unsafe.Pointer
+
+func cmalloc(n uintptr) unsafe.Pointer {
+	var args struct {
+		n   uint64
+		ret unsafe.Pointer
+	}
+	args.n = uint64(n)
+	cgocall(cgoMalloc, unsafe.Pointer(&args))
+	if args.ret == nil {
+		gothrow("C malloc failed")
+	}
+	return args.ret
+}
+
+func cfree(p unsafe.Pointer) {
+	cgocall(cgoFree, p)
+}
+
+// Call from C back to Go.
+//go:nosplit
+func cgocallbackg() {
+	gp := getg()
+	if gp != gp.m.curg {
+		println("runtime: bad g in cgocallback")
+		exit(2)
+	}
+
+	// entersyscall saves the caller's SP to allow the GC to trace the Go
+	// stack. However, since we're returning to an earlier stack frame and
+	// need to pair with the entersyscall() call made by cgocall, we must
+	// save syscall* and let reentersyscall restore them.
+	savedsp := unsafe.Pointer(gp.syscallsp)
+	savedpc := gp.syscallpc
+	exitsyscall() // coming out of cgo call
+	cgocallbackg1()
+	// going back to cgo call
+	reentersyscall(savedpc, savedsp)
+}
+
+func cgocallbackg1() {
+	gp := getg()
+	if gp.m.needextram {
+		gp.m.needextram = false
+		onM(newextram)
+	}
+
+	// Add entry to defer stack in case of panic.
+	restore := true
+	defer unwindm(&restore)
+
+	if raceenabled {
+		raceacquire(unsafe.Pointer(&racecgosync))
+	}
+
+	type args struct {
+		fn      *funcval
+		arg     unsafe.Pointer
+		argsize uintptr
+	}
+	var cb *args
+
+	// Location of callback arguments depends on stack frame layout
+	// and size of stack frame of cgocallback_gofunc.
+	sp := gp.m.g0.sched.sp
+	switch GOARCH {
+	default:
+		gothrow("cgocallbackg is unimplemented on arch")
+	case "arm":
+		// On arm, stack frame is two words and there's a saved LR between
+		// SP and the stack frame and between the stack frame and the arguments.
+		cb = (*args)(unsafe.Pointer(sp + 4*ptrSize))
+	case "amd64":
+		// On amd64, stack frame is one word, plus caller PC.
+		cb = (*args)(unsafe.Pointer(sp + 2*ptrSize))
+	case "386":
+		// On 386, stack frame is three words, plus caller PC.
+		cb = (*args)(unsafe.Pointer(sp + 4*ptrSize))
+	}
+
+	// Invoke callback.
+	reflectcall(unsafe.Pointer(cb.fn), unsafe.Pointer(cb.arg), uint32(cb.argsize), 0)
+
+	if raceenabled {
+		racereleasemerge(unsafe.Pointer(&racecgosync))
+	}
+
+	// Do not unwind m->g0->sched.sp.
+	// Our caller, cgocallback, will do that.
+	restore = false
+}
+
+func unwindm(restore *bool) {
+	if !*restore {
+		return
+	}
+	// Restore sp saved by cgocallback during
+	// unwind of g's stack (see comment at top of file).
+	mp := acquirem()
+	sched := &mp.g0.sched
+	switch GOARCH {
+	default:
+		gothrow("unwindm not implemented")
+	case "386", "amd64":
+		sched.sp = *(*uintptr)(unsafe.Pointer(sched.sp))
+	case "arm":
+		sched.sp = *(*uintptr)(unsafe.Pointer(sched.sp + 4))
+	}
+	releasem(mp)
+}
+
+// called from assembly
+func badcgocallback() {
+	gothrow("misaligned stack in cgocallback")
+}
+
+// called from (incomplete) assembly
+func cgounimpl() {
+	gothrow("cgo not implemented")
+}
+
+var racecgosync uint64 // represents possible synchronization in C code
diff --git a/src/runtime/cgocall.h b/src/runtime/cgocall.h
new file mode 100644
index 0000000..c87a9cd
--- /dev/null
+++ b/src/runtime/cgocall.h
@@ -0,0 +1,13 @@
+// Copyright 2009 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+/*
+ * Cgo interface.
+ */
+
+void runtime·cgocall(void (*fn)(void*), void*);
+int32 runtime·cgocall_errno(void (*fn)(void*), void*);
+void runtime·cgocallback(void (*fn)(void), void*, uintptr);
+void *runtime·cmalloc(uintptr);
+void runtime·cfree(void*);
diff --git a/src/runtime/cgocallback.go b/src/runtime/cgocallback.go
new file mode 100644
index 0000000..2c89143
--- /dev/null
+++ b/src/runtime/cgocallback.go
@@ -0,0 +1,40 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package runtime
+
+import "unsafe"
+
+// These functions are called from C code via cgo/callbacks.c.
+
+// Allocate memory.  This allocates the requested number of bytes in
+// memory controlled by the Go runtime.  The allocated memory will be
+// zeroed.  You are responsible for ensuring that the Go garbage
+// collector can see a pointer to the allocated memory for as long as
+// it is valid, e.g., by storing a pointer in a local variable in your
+// C function, or in memory allocated by the Go runtime.  If the only
+// pointers are in a C global variable or in memory allocated via
+// malloc, then the Go garbage collector may collect the memory.
+//
+// TODO(rsc,iant): This memory is untyped.
+// Either we need to add types or we need to stop using it.
+
+func _cgo_allocate_internal(len uintptr) unsafe.Pointer {
+	if len == 0 {
+		len = 1
+	}
+	ret := unsafe.Pointer(&make([]unsafe.Pointer, (len+ptrSize-1)/ptrSize)[0])
+	c := new(cgomal)
+	c.alloc = ret
+	gp := getg()
+	c.next = gp.m.cgomal
+	gp.m.cgomal = c
+	return ret
+}
+
+// Panic.
+
+func _cgo_panic_internal(p *byte) {
+	panic(gostringnocopy(p))
+}
diff --git a/src/runtime/chan.go b/src/runtime/chan.go
new file mode 100644
index 0000000..0eb87df
--- /dev/null
+++ b/src/runtime/chan.go
@@ -0,0 +1,655 @@
+// 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 runtime
+
+// This file contains the implementation of Go channels.
+
+import "unsafe"
+
+const (
+	maxAlign  = 8
+	hchanSize = unsafe.Sizeof(hchan{}) + uintptr(-int(unsafe.Sizeof(hchan{}))&(maxAlign-1))
+	debugChan = false
+)
+
+// TODO(khr): make hchan.buf an unsafe.Pointer, not a *uint8
+
+func makechan(t *chantype, size int64) *hchan {
+	elem := t.elem
+
+	// compiler checks this but be safe.
+	if elem.size >= 1<<16 {
+		gothrow("makechan: invalid channel element type")
+	}
+	if hchanSize%maxAlign != 0 || elem.align > maxAlign {
+		gothrow("makechan: bad alignment")
+	}
+	if size < 0 || int64(uintptr(size)) != size || (elem.size > 0 && uintptr(size) > (maxmem-hchanSize)/uintptr(elem.size)) {
+		panic("makechan: size out of range")
+	}
+
+	var c *hchan
+	if elem.kind&kindNoPointers != 0 || size == 0 {
+		// Allocate memory in one call.
+		// Hchan does not contain pointers interesting for GC in this case:
+		// buf points into the same allocation, elemtype is persistent.
+		// SudoG's are referenced from their owning thread so they can't be collected.
+		// TODO(dvyukov,rlh): Rethink when collector can move allocated objects.
+		c = (*hchan)(mallocgc(hchanSize+uintptr(size)*uintptr(elem.size), nil, flagNoScan))
+		if size > 0 && elem.size != 0 {
+			c.buf = (*uint8)(add(unsafe.Pointer(c), hchanSize))
+		} else {
+			c.buf = (*uint8)(unsafe.Pointer(c)) // race detector uses this location for synchronization
+		}
+	} else {
+		c = new(hchan)
+		c.buf = (*uint8)(newarray(elem, uintptr(size)))
+	}
+	c.elemsize = uint16(elem.size)
+	c.elemtype = elem
+	c.dataqsiz = uint(size)
+
+	if debugChan {
+		print("makechan: chan=", c, "; elemsize=", elem.size, "; elemalg=", elem.alg, "; dataqsiz=", size, "\n")
+	}
+	return c
+}
+
+// chanbuf(c, i) is pointer to the i'th slot in the buffer.
+func chanbuf(c *hchan, i uint) unsafe.Pointer {
+	return add(unsafe.Pointer(c.buf), uintptr(i)*uintptr(c.elemsize))
+}
+
+// entry point for c <- x from compiled code
+//go:nosplit
+func chansend1(t *chantype, c *hchan, elem unsafe.Pointer) {
+	chansend(t, c, elem, true, getcallerpc(unsafe.Pointer(&t)))
+}
+
+/*
+ * generic single channel send/recv
+ * If block is not nil,
+ * then the protocol will not
+ * sleep but return if it could
+ * not complete.
+ *
+ * sleep can wake up with g.param == nil
+ * when a channel involved in the sleep has
+ * been closed.  it is easiest to loop and re-run
+ * the operation; we'll see that it's now closed.
+ */
+func chansend(t *chantype, c *hchan, ep unsafe.Pointer, block bool, callerpc uintptr) bool {
+	if raceenabled {
+		raceReadObjectPC(t.elem, ep, callerpc, funcPC(chansend))
+	}
+
+	if c == nil {
+		if !block {
+			return false
+		}
+		gopark(nil, nil, "chan send (nil chan)")
+		gothrow("unreachable")
+	}
+
+	if debugChan {
+		print("chansend: chan=", c, "\n")
+	}
+
+	if raceenabled {
+		racereadpc(unsafe.Pointer(c), callerpc, funcPC(chansend))
+	}
+
+	// Fast path: check for failed non-blocking operation without acquiring the lock.
+	//
+	// After observing that the channel is not closed, we observe that the channel is
+	// not ready for sending. Each of these observations is a single word-sized read
+	// (first c.closed and second c.recvq.first or c.qcount depending on kind of channel).
+	// Because a closed channel cannot transition from 'ready for sending' to
+	// 'not ready for sending', even if the channel is closed between the two observations,
+	// they imply a moment between the two when the channel was both not yet closed
+	// and not ready for sending. We behave as if we observed the channel at that moment,
+	// and report that the send cannot proceed.
+	//
+	// It is okay if the reads are reordered here: if we observe that the channel is not
+	// ready for sending and then observe that it is not closed, that implies that the
+	// channel wasn't closed during the first observation.
+	if !block && c.closed == 0 && ((c.dataqsiz == 0 && c.recvq.first == nil) ||
+		(c.dataqsiz > 0 && c.qcount == c.dataqsiz)) {
+		return false
+	}
+
+	var t0 int64
+	if blockprofilerate > 0 {
+		t0 = cputicks()
+	}
+
+	lock(&c.lock)
+	if c.closed != 0 {
+		unlock(&c.lock)
+		panic("send on closed channel")
+	}
+
+	if c.dataqsiz == 0 { // synchronous channel
+		sg := c.recvq.dequeue()
+		if sg != nil { // found a waiting receiver
+			if raceenabled {
+				racesync(c, sg)
+			}
+			unlock(&c.lock)
+
+			recvg := sg.g
+			if sg.elem != nil {
+				memmove(unsafe.Pointer(sg.elem), ep, uintptr(c.elemsize))
+				sg.elem = nil
+			}
+			recvg.param = unsafe.Pointer(sg)
+			if sg.releasetime != 0 {
+				sg.releasetime = cputicks()
+			}
+			goready(recvg)
+			return true
+		}
+
+		if !block {
+			unlock(&c.lock)
+			return false
+		}
+
+		// no receiver available: block on this channel.
+		gp := getg()
+		mysg := acquireSudog()
+		mysg.releasetime = 0
+		if t0 != 0 {
+			mysg.releasetime = -1
+		}
+		mysg.elem = ep
+		mysg.waitlink = nil
+		gp.waiting = mysg
+		mysg.g = gp
+		mysg.selectdone = nil
+		gp.param = nil
+		c.sendq.enqueue(mysg)
+		goparkunlock(&c.lock, "chan send")
+
+		// someone woke us up.
+		if mysg != gp.waiting {
+			gothrow("G waiting list is corrupted!")
+		}
+		gp.waiting = nil
+		if gp.param == nil {
+			if c.closed == 0 {
+				gothrow("chansend: spurious wakeup")
+			}
+			panic("send on closed channel")
+		}
+		gp.param = nil
+		if mysg.releasetime > 0 {
+			blockevent(int64(mysg.releasetime)-t0, 2)
+		}
+		releaseSudog(mysg)
+		return true
+	}
+
+	// asynchronous channel
+	// wait for some space to write our data
+	var t1 int64
+	for c.qcount >= c.dataqsiz {
+		if !block {
+			unlock(&c.lock)
+			return false
+		}
+		gp := getg()
+		mysg := acquireSudog()
+		mysg.releasetime = 0
+		if t0 != 0 {
+			mysg.releasetime = -1
+		}
+		mysg.g = gp
+		mysg.elem = nil
+		mysg.selectdone = nil
+		c.sendq.enqueue(mysg)
+		goparkunlock(&c.lock, "chan send")
+
+		// someone woke us up - try again
+		if mysg.releasetime > 0 {
+			t1 = mysg.releasetime
+		}
+		releaseSudog(mysg)
+		lock(&c.lock)
+		if c.closed != 0 {
+			unlock(&c.lock)
+			panic("send on closed channel")
+		}
+	}
+
+	// write our data into the channel buffer
+	if raceenabled {
+		raceacquire(chanbuf(c, c.sendx))
+		racerelease(chanbuf(c, c.sendx))
+	}
+	memmove(chanbuf(c, c.sendx), ep, uintptr(c.elemsize))
+	c.sendx++
+	if c.sendx == c.dataqsiz {
+		c.sendx = 0
+	}
+	c.qcount++
+
+	// wake up a waiting receiver
+	sg := c.recvq.dequeue()
+	if sg != nil {
+		recvg := sg.g
+		unlock(&c.lock)
+		if sg.releasetime != 0 {
+			sg.releasetime = cputicks()
+		}
+		goready(recvg)
+	} else {
+		unlock(&c.lock)
+	}
+	if t1 > 0 {
+		blockevent(t1-t0, 2)
+	}
+	return true
+}
+
+func closechan(c *hchan) {
+	if c == nil {
+		panic("close of nil channel")
+	}
+
+	lock(&c.lock)
+	if c.closed != 0 {
+		unlock(&c.lock)
+		panic("close of closed channel")
+	}
+
+	if raceenabled {
+		callerpc := getcallerpc(unsafe.Pointer(&c))
+		racewritepc(unsafe.Pointer(c), callerpc, funcPC(closechan))
+		racerelease(unsafe.Pointer(c))
+	}
+
+	c.closed = 1
+
+	// release all readers
+	for {
+		sg := c.recvq.dequeue()
+		if sg == nil {
+			break
+		}
+		gp := sg.g
+		sg.elem = nil
+		gp.param = nil
+		if sg.releasetime != 0 {
+			sg.releasetime = cputicks()
+		}
+		goready(gp)
+	}
+
+	// release all writers
+	for {
+		sg := c.sendq.dequeue()
+		if sg == nil {
+			break
+		}
+		gp := sg.g
+		sg.elem = nil
+		gp.param = nil
+		if sg.releasetime != 0 {
+			sg.releasetime = cputicks()
+		}
+		goready(gp)
+	}
+	unlock(&c.lock)
+}
+
+// entry points for <- c from compiled code
+//go:nosplit
+func chanrecv1(t *chantype, c *hchan, elem unsafe.Pointer) {
+	chanrecv(t, c, elem, true)
+}
+
+//go:nosplit
+func chanrecv2(t *chantype, c *hchan, elem unsafe.Pointer) (received bool) {
+	_, received = chanrecv(t, c, elem, true)
+	return
+}
+
+// chanrecv receives on channel c and writes the received data to ep.
+// ep may be nil, in which case received data is ignored.
+// If block == false and no elements are available, returns (false, false).
+// Otherwise, if c is closed, zeros *ep and returns (true, false).
+// Otherwise, fills in *ep with an element and returns (true, true).
+func chanrecv(t *chantype, c *hchan, ep unsafe.Pointer, block bool) (selected, received bool) {
+	// raceenabled: don't need to check ep, as it is always on the stack.
+
+	if debugChan {
+		print("chanrecv: chan=", c, "\n")
+	}
+
+	if c == nil {
+		if !block {
+			return
+		}
+		gopark(nil, nil, "chan receive (nil chan)")
+		gothrow("unreachable")
+	}
+
+	// Fast path: check for failed non-blocking operation without acquiring the lock.
+	//
+	// After observing that the channel is not ready for receiving, we observe that the
+	// channel is not closed. Each of these observations is a single word-sized read
+	// (first c.sendq.first or c.qcount, and second c.closed).
+	// Because a channel cannot be reopened, the later observation of the channel
+	// being not closed implies that it was also not closed at the moment of the
+	// first observation. We behave as if we observed the channel at that moment
+	// and report that the receive cannot proceed.
+	//
+	// The order of operations is important here: reversing the operations can lead to
+	// incorrect behavior when racing with a close.
+	if !block && (c.dataqsiz == 0 && c.sendq.first == nil ||
+		c.dataqsiz > 0 && atomicloaduint(&c.qcount) == 0) &&
+		atomicload(&c.closed) == 0 {
+		return
+	}
+
+	var t0 int64
+	if blockprofilerate > 0 {
+		t0 = cputicks()
+	}
+
+	lock(&c.lock)
+	if c.dataqsiz == 0 { // synchronous channel
+		if c.closed != 0 {
+			return recvclosed(c, ep)
+		}
+
+		sg := c.sendq.dequeue()
+		if sg != nil {
+			if raceenabled {
+				racesync(c, sg)
+			}
+			unlock(&c.lock)
+
+			if ep != nil {
+				memmove(ep, sg.elem, uintptr(c.elemsize))
+			}
+			sg.elem = nil
+			gp := sg.g
+			gp.param = unsafe.Pointer(sg)
+			if sg.releasetime != 0 {
+				sg.releasetime = cputicks()
+			}
+			goready(gp)
+			selected = true
+			received = true
+			return
+		}
+
+		if !block {
+			unlock(&c.lock)
+			return
+		}
+
+		// no sender available: block on this channel.
+		gp := getg()
+		mysg := acquireSudog()
+		mysg.releasetime = 0
+		if t0 != 0 {
+			mysg.releasetime = -1
+		}
+		mysg.elem = ep
+		mysg.waitlink = nil
+		gp.waiting = mysg
+		mysg.g = gp
+		mysg.selectdone = nil
+		gp.param = nil
+		c.recvq.enqueue(mysg)
+		goparkunlock(&c.lock, "chan receive")
+
+		// someone woke us up
+		if mysg != gp.waiting {
+			gothrow("G waiting list is corrupted!")
+		}
+		gp.waiting = nil
+		if mysg.releasetime > 0 {
+			blockevent(mysg.releasetime-t0, 2)
+		}
+		haveData := gp.param != nil
+		gp.param = nil
+		releaseSudog(mysg)
+
+		if haveData {
+			// a sender sent us some data. It already wrote to ep.
+			selected = true
+			received = true
+			return
+		}
+
+		lock(&c.lock)
+		if c.closed == 0 {
+			gothrow("chanrecv: spurious wakeup")
+		}
+		return recvclosed(c, ep)
+	}
+
+	// asynchronous channel
+	// wait for some data to appear
+	var t1 int64
+	for c.qcount <= 0 {
+		if c.closed != 0 {
+			selected, received = recvclosed(c, ep)
+			if t1 > 0 {
+				blockevent(t1-t0, 2)
+			}
+			return
+		}
+
+		if !block {
+			unlock(&c.lock)
+			return
+		}
+
+		// wait for someone to send an element
+		gp := getg()
+		mysg := acquireSudog()
+		mysg.releasetime = 0
+		if t0 != 0 {
+			mysg.releasetime = -1
+		}
+		mysg.elem = nil
+		mysg.g = gp
+		mysg.selectdone = nil
+
+		c.recvq.enqueue(mysg)
+		goparkunlock(&c.lock, "chan receive")
+
+		// someone woke us up - try again
+		if mysg.releasetime > 0 {
+			t1 = mysg.releasetime
+		}
+		releaseSudog(mysg)
+		lock(&c.lock)
+	}
+
+	if raceenabled {
+		raceacquire(chanbuf(c, c.recvx))
+		racerelease(chanbuf(c, c.recvx))
+	}
+	if ep != nil {
+		memmove(ep, chanbuf(c, c.recvx), uintptr(c.elemsize))
+	}
+	memclr(chanbuf(c, c.recvx), uintptr(c.elemsize))
+
+	c.recvx++
+	if c.recvx == c.dataqsiz {
+		c.recvx = 0
+	}
+	c.qcount--
+
+	// ping a sender now that there is space
+	sg := c.sendq.dequeue()
+	if sg != nil {
+		gp := sg.g
+		unlock(&c.lock)
+		if sg.releasetime != 0 {
+			sg.releasetime = cputicks()
+		}
+		goready(gp)
+	} else {
+		unlock(&c.lock)
+	}
+
+	if t1 > 0 {
+		blockevent(t1-t0, 2)
+	}
+	selected = true
+	received = true
+	return
+}
+
+// recvclosed is a helper function for chanrecv.  Handles cleanup
+// when the receiver encounters a closed channel.
+// Caller must hold c.lock, recvclosed will release the lock.
+func recvclosed(c *hchan, ep unsafe.Pointer) (selected, recevied bool) {
+	if raceenabled {
+		raceacquire(unsafe.Pointer(c))
+	}
+	unlock(&c.lock)
+	if ep != nil {
+		memclr(ep, uintptr(c.elemsize))
+	}
+	return true, false
+}
+
+// compiler implements
+//
+//	select {
+//	case c <- v:
+//		... foo
+//	default:
+//		... bar
+//	}
+//
+// as
+//
+//	if selectnbsend(c, v) {
+//		... foo
+//	} else {
+//		... bar
+//	}
+//
+func selectnbsend(t *chantype, c *hchan, elem unsafe.Pointer) (selected bool) {
+	return chansend(t, c, elem, false, getcallerpc(unsafe.Pointer(&t)))
+}
+
+// compiler implements
+//
+//	select {
+//	case v = <-c:
+//		... foo
+//	default:
+//		... bar
+//	}
+//
+// as
+//
+//	if selectnbrecv(&v, c) {
+//		... foo
+//	} else {
+//		... bar
+//	}
+//
+func selectnbrecv(t *chantype, elem unsafe.Pointer, c *hchan) (selected bool) {
+	selected, _ = chanrecv(t, c, elem, false)
+	return
+}
+
+// compiler implements
+//
+//	select {
+//	case v, ok = <-c:
+//		... foo
+//	default:
+//		... bar
+//	}
+//
+// as
+//
+//	if c != nil && selectnbrecv2(&v, &ok, c) {
+//		... foo
+//	} else {
+//		... bar
+//	}
+//
+func selectnbrecv2(t *chantype, elem unsafe.Pointer, received *bool, c *hchan) (selected bool) {
+	// TODO(khr): just return 2 values from this function, now that it is in Go.
+	selected, *received = chanrecv(t, c, elem, false)
+	return
+}
+
+func reflect_chansend(t *chantype, c *hchan, elem unsafe.Pointer, nb bool) (selected bool) {
+	return chansend(t, c, elem, !nb, getcallerpc(unsafe.Pointer(&t)))
+}
+
+func reflect_chanrecv(t *chantype, c *hchan, nb bool, elem unsafe.Pointer) (selected bool, received bool) {
+	return chanrecv(t, c, elem, !nb)
+}
+
+func reflect_chanlen(c *hchan) int {
+	if c == nil {
+		return 0
+	}
+	return int(c.qcount)
+}
+
+func reflect_chancap(c *hchan) int {
+	if c == nil {
+		return 0
+	}
+	return int(c.dataqsiz)
+}
+
+func (q *waitq) enqueue(sgp *sudog) {
+	sgp.next = nil
+	if q.first == nil {
+		q.first = sgp
+		q.last = sgp
+		return
+	}
+	q.last.next = sgp
+	q.last = sgp
+}
+
+func (q *waitq) dequeue() *sudog {
+	for {
+		sgp := q.first
+		if sgp == nil {
+			return nil
+		}
+		q.first = sgp.next
+		sgp.next = nil
+		if q.last == sgp {
+			q.last = nil
+		}
+
+		// if sgp participates in a select and is already signaled, ignore it
+		if sgp.selectdone != nil {
+			// claim the right to signal
+			if *sgp.selectdone != 0 || !cas(sgp.selectdone, 0, 1) {
+				continue
+			}
+		}
+
+		return sgp
+	}
+}
+
+func racesync(c *hchan, sg *sudog) {
+	racerelease(chanbuf(c, 0))
+	raceacquireg(sg.g, chanbuf(c, 0))
+	racereleaseg(sg.g, chanbuf(c, 0))
+	raceacquire(chanbuf(c, 0))
+}
diff --git a/src/runtime/chan.h b/src/runtime/chan.h
new file mode 100644
index 0000000..c34ff15
--- /dev/null
+++ b/src/runtime/chan.h
@@ -0,0 +1,68 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#define	MAXALIGN	8
+
+typedef	struct	WaitQ	WaitQ;
+typedef	struct	Select	Select;
+typedef	struct	Scase	Scase;
+
+struct	WaitQ
+{
+	SudoG*	first;
+	SudoG*	last;
+};
+
+struct	Hchan
+{
+	uintgo	qcount;			// total data in the q
+	uintgo	dataqsiz;		// size of the circular q
+	byte*	buf;
+	uint16	elemsize;
+	uint32	closed;
+	Type*	elemtype;		// element type
+	uintgo	sendx;			// send index
+	uintgo	recvx;			// receive index
+	WaitQ	recvq;			// list of recv waiters
+	WaitQ	sendq;			// list of send waiters
+	Mutex	lock;
+};
+
+// Buffer follows Hchan immediately in memory.
+// chanbuf(c, i) is pointer to the i'th slot in the buffer.
+#define chanbuf(c, i) ((byte*)((c)->buf)+(uintptr)(c)->elemsize*(i))
+
+enum
+{
+	debug = 0,
+
+	// Scase.kind
+	CaseRecv,
+	CaseSend,
+	CaseDefault,
+};
+
+// Known to compiler.
+// Changes here must also be made in src/cmd/gc/select.c's selecttype.
+struct	Scase
+{
+	void*	elem;			// data element
+	Hchan*	chan;			// chan
+	uintptr	pc;			// return pc
+	uint16	kind;
+	uint16	so;			// vararg of selected bool
+	bool*	receivedp;		// pointer to received bool (recv2)
+	int64	releasetime;
+};
+
+// Known to compiler.
+// Changes here must also be made in src/cmd/gc/select.c's selecttype.
+struct	Select
+{
+	uint16	tcase;			// total count of scase[]
+	uint16	ncase;			// currently filled scase[]
+	uint16*	pollorder;		// case poll order
+	Hchan**	lockorder;		// channel lock order
+	Scase	scase[1];		// one per case (in order of appearance)
+};
diff --git a/src/runtime/chan_test.go b/src/runtime/chan_test.go
new file mode 100644
index 0000000..e689cea
--- /dev/null
+++ b/src/runtime/chan_test.go
@@ -0,0 +1,820 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package runtime_test
+
+import (
+	"runtime"
+	"sync"
+	"sync/atomic"
+	"testing"
+	"time"
+)
+
+func TestChan(t *testing.T) {
+	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4))
+	N := 200
+	if testing.Short() {
+		N = 20
+	}
+	for chanCap := 0; chanCap < N; chanCap++ {
+		{
+			// Ensure that receive from empty chan blocks.
+			c := make(chan int, chanCap)
+			recv1 := false
+			go func() {
+				_ = <-c
+				recv1 = true
+			}()
+			recv2 := false
+			go func() {
+				_, _ = <-c
+				recv2 = true
+			}()
+			time.Sleep(time.Millisecond)
+			if recv1 || recv2 {
+				t.Fatalf("chan[%d]: receive from empty chan", chanCap)
+			}
+			// Ensure that non-blocking receive does not block.
+			select {
+			case _ = <-c:
+				t.Fatalf("chan[%d]: receive from empty chan", chanCap)
+			default:
+			}
+			select {
+			case _, _ = <-c:
+				t.Fatalf("chan[%d]: receive from empty chan", chanCap)
+			default:
+			}
+			c <- 0
+			c <- 0
+		}
+
+		{
+			// Ensure that send to full chan blocks.
+			c := make(chan int, chanCap)
+			for i := 0; i < chanCap; i++ {
+				c <- i
+			}
+			sent := uint32(0)
+			go func() {
+				c <- 0
+				atomic.StoreUint32(&sent, 1)
+			}()
+			time.Sleep(time.Millisecond)
+			if atomic.LoadUint32(&sent) != 0 {
+				t.Fatalf("chan[%d]: send to full chan", chanCap)
+			}
+			// Ensure that non-blocking send does not block.
+			select {
+			case c <- 0:
+				t.Fatalf("chan[%d]: send to full chan", chanCap)
+			default:
+			}
+			<-c
+		}
+
+		{
+			// Ensure that we receive 0 from closed chan.
+			c := make(chan int, chanCap)
+			for i := 0; i < chanCap; i++ {
+				c <- i
+			}
+			close(c)
+			for i := 0; i < chanCap; i++ {
+				v := <-c
+				if v != i {
+					t.Fatalf("chan[%d]: received %v, expected %v", chanCap, v, i)
+				}
+			}
+			if v := <-c; v != 0 {
+				t.Fatalf("chan[%d]: received %v, expected %v", chanCap, v, 0)
+			}
+			if v, ok := <-c; v != 0 || ok {
+				t.Fatalf("chan[%d]: received %v/%v, expected %v/%v", chanCap, v, ok, 0, false)
+			}
+		}
+
+		{
+			// Ensure that close unblocks receive.
+			c := make(chan int, chanCap)
+			done := make(chan bool)
+			go func() {
+				v, ok := <-c
+				done <- v == 0 && ok == false
+			}()
+			time.Sleep(time.Millisecond)
+			close(c)
+			if !<-done {
+				t.Fatalf("chan[%d]: received non zero from closed chan", chanCap)
+			}
+		}
+
+		{
+			// Send 100 integers,
+			// ensure that we receive them non-corrupted in FIFO order.
+			c := make(chan int, chanCap)
+			go func() {
+				for i := 0; i < 100; i++ {
+					c <- i
+				}
+			}()
+			for i := 0; i < 100; i++ {
+				v := <-c
+				if v != i {
+					t.Fatalf("chan[%d]: received %v, expected %v", chanCap, v, i)
+				}
+			}
+
+			// Same, but using recv2.
+			go func() {
+				for i := 0; i < 100; i++ {
+					c <- i
+				}
+			}()
+			for i := 0; i < 100; i++ {
+				v, ok := <-c
+				if !ok {
+					t.Fatalf("chan[%d]: receive failed, expected %v", chanCap, i)
+				}
+				if v != i {
+					t.Fatalf("chan[%d]: received %v, expected %v", chanCap, v, i)
+				}
+			}
+
+			// Send 1000 integers in 4 goroutines,
+			// ensure that we receive what we send.
+			const P = 4
+			const L = 1000
+			for p := 0; p < P; p++ {
+				go func() {
+					for i := 0; i < L; i++ {
+						c <- i
+					}
+				}()
+			}
+			done := make(chan map[int]int)
+			for p := 0; p < P; p++ {
+				go func() {
+					recv := make(map[int]int)
+					for i := 0; i < L; i++ {
+						v := <-c
+						recv[v] = recv[v] + 1
+					}
+					done <- recv
+				}()
+			}
+			recv := make(map[int]int)
+			for p := 0; p < P; p++ {
+				for k, v := range <-done {
+					recv[k] = recv[k] + v
+				}
+			}
+			if len(recv) != L {
+				t.Fatalf("chan[%d]: received %v values, expected %v", chanCap, len(recv), L)
+			}
+			for _, v := range recv {
+				if v != P {
+					t.Fatalf("chan[%d]: received %v values, expected %v", chanCap, v, P)
+				}
+			}
+		}
+
+		{
+			// Test len/cap.
+			c := make(chan int, chanCap)
+			if len(c) != 0 || cap(c) != chanCap {
+				t.Fatalf("chan[%d]: bad len/cap, expect %v/%v, got %v/%v", chanCap, 0, chanCap, len(c), cap(c))
+			}
+			for i := 0; i < chanCap; i++ {
+				c <- i
+			}
+			if len(c) != chanCap || cap(c) != chanCap {
+				t.Fatalf("chan[%d]: bad len/cap, expect %v/%v, got %v/%v", chanCap, chanCap, chanCap, len(c), cap(c))
+			}
+		}
+
+	}
+}
+
+func TestNonblockRecvRace(t *testing.T) {
+	n := 10000
+	if testing.Short() {
+		n = 100
+	}
+	for i := 0; i < n; i++ {
+		c := make(chan int, 1)
+		c <- 1
+		go func() {
+			select {
+			case <-c:
+			default:
+				t.Fatal("chan is not ready")
+			}
+		}()
+		close(c)
+		<-c
+	}
+}
+
+func TestSelfSelect(t *testing.T) {
+	// Ensure that send/recv on the same chan in select
+	// does not crash nor deadlock.
+	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(2))
+	for _, chanCap := range []int{0, 10} {
+		var wg sync.WaitGroup
+		wg.Add(2)
+		c := make(chan int, chanCap)
+		for p := 0; p < 2; p++ {
+			p := p
+			go func() {
+				defer wg.Done()
+				for i := 0; i < 1000; i++ {
+					if p == 0 || i%2 == 0 {
+						select {
+						case c <- p:
+						case v := <-c:
+							if chanCap == 0 && v == p {
+								t.Fatalf("self receive")
+							}
+						}
+					} else {
+						select {
+						case v := <-c:
+							if chanCap == 0 && v == p {
+								t.Fatalf("self receive")
+							}
+						case c <- p:
+						}
+					}
+				}
+			}()
+		}
+		wg.Wait()
+	}
+}
+
+func TestSelectStress(t *testing.T) {
+	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(10))
+	var c [4]chan int
+	c[0] = make(chan int)
+	c[1] = make(chan int)
+	c[2] = make(chan int, 2)
+	c[3] = make(chan int, 3)
+	N := int(1e5)
+	if testing.Short() {
+		N /= 10
+	}
+	// There are 4 goroutines that send N values on each of the chans,
+	// + 4 goroutines that receive N values on each of the chans,
+	// + 1 goroutine that sends N values on each of the chans in a single select,
+	// + 1 goroutine that receives N values on each of the chans in a single select.
+	// All these sends, receives and selects interact chaotically at runtime,
+	// but we are careful that this whole construct does not deadlock.
+	var wg sync.WaitGroup
+	wg.Add(10)
+	for k := 0; k < 4; k++ {
+		k := k
+		go func() {
+			for i := 0; i < N; i++ {
+				c[k] <- 0
+			}
+			wg.Done()
+		}()
+		go func() {
+			for i := 0; i < N; i++ {
+				<-c[k]
+			}
+			wg.Done()
+		}()
+	}
+	go func() {
+		var n [4]int
+		c1 := c
+		for i := 0; i < 4*N; i++ {
+			select {
+			case c1[3] <- 0:
+				n[3]++
+				if n[3] == N {
+					c1[3] = nil
+				}
+			case c1[2] <- 0:
+				n[2]++
+				if n[2] == N {
+					c1[2] = nil
+				}
+			case c1[0] <- 0:
+				n[0]++
+				if n[0] == N {
+					c1[0] = nil
+				}
+			case c1[1] <- 0:
+				n[1]++
+				if n[1] == N {
+					c1[1] = nil
+				}
+			}
+		}
+		wg.Done()
+	}()
+	go func() {
+		var n [4]int
+		c1 := c
+		for i := 0; i < 4*N; i++ {
+			select {
+			case <-c1[0]:
+				n[0]++
+				if n[0] == N {
+					c1[0] = nil
+				}
+			case <-c1[1]:
+				n[1]++
+				if n[1] == N {
+					c1[1] = nil
+				}
+			case <-c1[2]:
+				n[2]++
+				if n[2] == N {
+					c1[2] = nil
+				}
+			case <-c1[3]:
+				n[3]++
+				if n[3] == N {
+					c1[3] = nil
+				}
+			}
+		}
+		wg.Done()
+	}()
+	wg.Wait()
+}
+
+func TestChanSendInterface(t *testing.T) {
+	type mt struct{}
+	m := &mt{}
+	c := make(chan interface{}, 1)
+	c <- m
+	select {
+	case c <- m:
+	default:
+	}
+	select {
+	case c <- m:
+	case c <- &mt{}:
+	default:
+	}
+}
+
+func TestPseudoRandomSend(t *testing.T) {
+	n := 100
+	for _, chanCap := range []int{0, n} {
+		c := make(chan int, chanCap)
+		l := make([]int, n)
+		var m sync.Mutex
+		m.Lock()
+		go func() {
+			for i := 0; i < n; i++ {
+				runtime.Gosched()
+				l[i] = <-c
+			}
+			m.Unlock()
+		}()
+		for i := 0; i < n; i++ {
+			select {
+			case c <- 1:
+			case c <- 0:
+			}
+		}
+		m.Lock() // wait
+		n0 := 0
+		n1 := 0
+		for _, i := range l {
+			n0 += (i + 1) % 2
+			n1 += i
+		}
+		if n0 <= n/10 || n1 <= n/10 {
+			t.Errorf("Want pseudorandom, got %d zeros and %d ones (chan cap %d)", n0, n1, chanCap)
+		}
+	}
+}
+
+func TestMultiConsumer(t *testing.T) {
+	const nwork = 23
+	const niter = 271828
+
+	pn := []int{2, 3, 7, 11, 13, 17, 19, 23, 27, 31}
+
+	q := make(chan int, nwork*3)
+	r := make(chan int, nwork*3)
+
+	// workers
+	var wg sync.WaitGroup
+	for i := 0; i < nwork; i++ {
+		wg.Add(1)
+		go func(w int) {
+			for v := range q {
+				// mess with the fifo-ish nature of range
+				if pn[w%len(pn)] == v {
+					runtime.Gosched()
+				}
+				r <- v
+			}
+			wg.Done()
+		}(i)
+	}
+
+	// feeder & closer
+	expect := 0
+	go func() {
+		for i := 0; i < niter; i++ {
+			v := pn[i%len(pn)]
+			expect += v
+			q <- v
+		}
+		close(q)  // no more work
+		wg.Wait() // workers done
+		close(r)  // ... so there can be no more results
+	}()
+
+	// consume & check
+	n := 0
+	s := 0
+	for v := range r {
+		n++
+		s += v
+	}
+	if n != niter || s != expect {
+		t.Errorf("Expected sum %d (got %d) from %d iter (saw %d)",
+			expect, s, niter, n)
+	}
+}
+
+func TestShrinkStackDuringBlockedSend(t *testing.T) {
+	// make sure that channel operations still work when we are
+	// blocked on a channel send and we shrink the stack.
+	// NOTE: this test probably won't fail unless stack.c:StackDebug
+	// is set to >= 1.
+	const n = 10
+	c := make(chan int)
+	done := make(chan struct{})
+
+	go func() {
+		for i := 0; i < n; i++ {
+			c <- i
+			// use lots of stack, briefly.
+			stackGrowthRecursive(20)
+		}
+		done <- struct{}{}
+	}()
+
+	for i := 0; i < n; i++ {
+		x := <-c
+		if x != i {
+			t.Errorf("bad channel read: want %d, got %d", i, x)
+		}
+		// Waste some time so sender can finish using lots of stack
+		// and block in channel send.
+		time.Sleep(1 * time.Millisecond)
+		// trigger GC which will shrink the stack of the sender.
+		runtime.GC()
+	}
+	<-done
+}
+
+func TestSelectDuplicateChannel(t *testing.T) {
+	// This test makes sure we can queue a G on
+	// the same channel multiple times.
+	c := make(chan int)
+	d := make(chan int)
+	e := make(chan int)
+
+	// goroutine A
+	go func() {
+		select {
+		case <-c:
+		case <-c:
+		case <-d:
+		}
+		e <- 9
+	}()
+	time.Sleep(time.Millisecond) // make sure goroutine A gets qeueued first on c
+
+	// goroutine B
+	go func() {
+		<-c
+	}()
+	time.Sleep(time.Millisecond) // make sure goroutine B gets queued on c before continuing
+
+	d <- 7 // wake up A, it dequeues itself from c.  This operation used to corrupt c.recvq.
+	<-e    // A tells us it's done
+	c <- 8 // wake up B.  This operation used to fail because c.recvq was corrupted (it tries to wake up an already running G instead of B)
+}
+
+func BenchmarkChanNonblocking(b *testing.B) {
+	myc := make(chan int)
+	b.RunParallel(func(pb *testing.PB) {
+		for pb.Next() {
+			select {
+			case <-myc:
+			default:
+			}
+		}
+	})
+}
+
+func BenchmarkSelectUncontended(b *testing.B) {
+	b.RunParallel(func(pb *testing.PB) {
+		myc1 := make(chan int, 1)
+		myc2 := make(chan int, 1)
+		myc1 <- 0
+		for pb.Next() {
+			select {
+			case <-myc1:
+				myc2 <- 0
+			case <-myc2:
+				myc1 <- 0
+			}
+		}
+	})
+}
+
+func BenchmarkSelectSyncContended(b *testing.B) {
+	myc1 := make(chan int)
+	myc2 := make(chan int)
+	myc3 := make(chan int)
+	done := make(chan int)
+	b.RunParallel(func(pb *testing.PB) {
+		go func() {
+			for {
+				select {
+				case myc1 <- 0:
+				case myc2 <- 0:
+				case myc3 <- 0:
+				case <-done:
+					return
+				}
+			}
+		}()
+		for pb.Next() {
+			select {
+			case <-myc1:
+			case <-myc2:
+			case <-myc3:
+			}
+		}
+	})
+	close(done)
+}
+
+func BenchmarkSelectAsyncContended(b *testing.B) {
+	procs := runtime.GOMAXPROCS(0)
+	myc1 := make(chan int, procs)
+	myc2 := make(chan int, procs)
+	b.RunParallel(func(pb *testing.PB) {
+		myc1 <- 0
+		for pb.Next() {
+			select {
+			case <-myc1:
+				myc2 <- 0
+			case <-myc2:
+				myc1 <- 0
+			}
+		}
+	})
+}
+
+func BenchmarkSelectNonblock(b *testing.B) {
+	myc1 := make(chan int)
+	myc2 := make(chan int)
+	myc3 := make(chan int, 1)
+	myc4 := make(chan int, 1)
+	b.RunParallel(func(pb *testing.PB) {
+		for pb.Next() {
+			select {
+			case <-myc1:
+			default:
+			}
+			select {
+			case myc2 <- 0:
+			default:
+			}
+			select {
+			case <-myc3:
+			default:
+			}
+			select {
+			case myc4 <- 0:
+			default:
+			}
+		}
+	})
+}
+
+func BenchmarkChanUncontended(b *testing.B) {
+	const C = 100
+	b.RunParallel(func(pb *testing.PB) {
+		myc := make(chan int, C)
+		for pb.Next() {
+			for i := 0; i < C; i++ {
+				myc <- 0
+			}
+			for i := 0; i < C; i++ {
+				<-myc
+			}
+		}
+	})
+}
+
+func BenchmarkChanContended(b *testing.B) {
+	const C = 100
+	myc := make(chan int, C*runtime.GOMAXPROCS(0))
+	b.RunParallel(func(pb *testing.PB) {
+		for pb.Next() {
+			for i := 0; i < C; i++ {
+				myc <- 0
+			}
+			for i := 0; i < C; i++ {
+				<-myc
+			}
+		}
+	})
+}
+
+func BenchmarkChanSync(b *testing.B) {
+	const CallsPerSched = 1000
+	procs := 2
+	N := int32(b.N / CallsPerSched / procs * procs)
+	c := make(chan bool, procs)
+	myc := make(chan int)
+	for p := 0; p < procs; p++ {
+		go func() {
+			for {
+				i := atomic.AddInt32(&N, -1)
+				if i < 0 {
+					break
+				}
+				for g := 0; g < CallsPerSched; g++ {
+					if i%2 == 0 {
+						<-myc
+						myc <- 0
+					} else {
+						myc <- 0
+						<-myc
+					}
+				}
+			}
+			c <- true
+		}()
+	}
+	for p := 0; p < procs; p++ {
+		<-c
+	}
+}
+
+func benchmarkChanProdCons(b *testing.B, chanSize, localWork int) {
+	const CallsPerSched = 1000
+	procs := runtime.GOMAXPROCS(-1)
+	N := int32(b.N / CallsPerSched)
+	c := make(chan bool, 2*procs)
+	myc := make(chan int, chanSize)
+	for p := 0; p < procs; p++ {
+		go func() {
+			foo := 0
+			for atomic.AddInt32(&N, -1) >= 0 {
+				for g := 0; g < CallsPerSched; g++ {
+					for i := 0; i < localWork; i++ {
+						foo *= 2
+						foo /= 2
+					}
+					myc <- 1
+				}
+			}
+			myc <- 0
+			c <- foo == 42
+		}()
+		go func() {
+			foo := 0
+			for {
+				v := <-myc
+				if v == 0 {
+					break
+				}
+				for i := 0; i < localWork; i++ {
+					foo *= 2
+					foo /= 2
+				}
+			}
+			c <- foo == 42
+		}()
+	}
+	for p := 0; p < procs; p++ {
+		<-c
+		<-c
+	}
+}
+
+func BenchmarkChanProdCons0(b *testing.B) {
+	benchmarkChanProdCons(b, 0, 0)
+}
+
+func BenchmarkChanProdCons10(b *testing.B) {
+	benchmarkChanProdCons(b, 10, 0)
+}
+
+func BenchmarkChanProdCons100(b *testing.B) {
+	benchmarkChanProdCons(b, 100, 0)
+}
+
+func BenchmarkChanProdConsWork0(b *testing.B) {
+	benchmarkChanProdCons(b, 0, 100)
+}
+
+func BenchmarkChanProdConsWork10(b *testing.B) {
+	benchmarkChanProdCons(b, 10, 100)
+}
+
+func BenchmarkChanProdConsWork100(b *testing.B) {
+	benchmarkChanProdCons(b, 100, 100)
+}
+
+func BenchmarkSelectProdCons(b *testing.B) {
+	const CallsPerSched = 1000
+	procs := runtime.GOMAXPROCS(-1)
+	N := int32(b.N / CallsPerSched)
+	c := make(chan bool, 2*procs)
+	myc := make(chan int, 128)
+	myclose := make(chan bool)
+	for p := 0; p < procs; p++ {
+		go func() {
+			// Producer: sends to myc.
+			foo := 0
+			// Intended to not fire during benchmarking.
+			mytimer := time.After(time.Hour)
+			for atomic.AddInt32(&N, -1) >= 0 {
+				for g := 0; g < CallsPerSched; g++ {
+					// Model some local work.
+					for i := 0; i < 100; i++ {
+						foo *= 2
+						foo /= 2
+					}
+					select {
+					case myc <- 1:
+					case <-mytimer:
+					case <-myclose:
+					}
+				}
+			}
+			myc <- 0
+			c <- foo == 42
+		}()
+		go func() {
+			// Consumer: receives from myc.
+			foo := 0
+			// Intended to not fire during benchmarking.
+			mytimer := time.After(time.Hour)
+		loop:
+			for {
+				select {
+				case v := <-myc:
+					if v == 0 {
+						break loop
+					}
+				case <-mytimer:
+				case <-myclose:
+				}
+				// Model some local work.
+				for i := 0; i < 100; i++ {
+					foo *= 2
+					foo /= 2
+				}
+			}
+			c <- foo == 42
+		}()
+	}
+	for p := 0; p < procs; p++ {
+		<-c
+		<-c
+	}
+}
+
+func BenchmarkChanCreation(b *testing.B) {
+	b.RunParallel(func(pb *testing.PB) {
+		for pb.Next() {
+			myc := make(chan int, 1)
+			myc <- 0
+			<-myc
+		}
+	})
+}
+
+func BenchmarkChanSem(b *testing.B) {
+	type Empty struct{}
+	myc := make(chan Empty, runtime.GOMAXPROCS(0))
+	b.RunParallel(func(pb *testing.PB) {
+		for pb.Next() {
+			myc <- Empty{}
+			<-myc
+		}
+	})
+}
diff --git a/src/pkg/runtime/closure_test.go b/src/runtime/closure_test.go
similarity index 100%
rename from src/pkg/runtime/closure_test.go
rename to src/runtime/closure_test.go
diff --git a/src/pkg/runtime/compiler.go b/src/runtime/compiler.go
similarity index 100%
rename from src/pkg/runtime/compiler.go
rename to src/runtime/compiler.go
diff --git a/src/runtime/complex.go b/src/runtime/complex.go
new file mode 100644
index 0000000..ec50f89
--- /dev/null
+++ b/src/runtime/complex.go
@@ -0,0 +1,52 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package runtime
+
+func complex128div(n complex128, d complex128) complex128 {
+	// Special cases as in C99.
+	ninf := real(n) == posinf || real(n) == neginf ||
+		imag(n) == posinf || imag(n) == neginf
+	dinf := real(d) == posinf || real(d) == neginf ||
+		imag(d) == posinf || imag(d) == neginf
+
+	nnan := !ninf && (real(n) != real(n) || imag(n) != imag(n))
+	dnan := !dinf && (real(d) != real(d) || imag(d) != imag(d))
+
+	switch {
+	case nnan || dnan:
+		return complex(nan, nan)
+	case ninf && !dinf:
+		return complex(posinf, posinf)
+	case !ninf && dinf:
+		return complex(0, 0)
+	case real(d) == 0 && imag(d) == 0:
+		if real(n) == 0 && imag(n) == 0 {
+			return complex(nan, nan)
+		} else {
+			return complex(posinf, posinf)
+		}
+	default:
+		// Standard complex arithmetic, factored to avoid unnecessary overflow.
+		a := real(d)
+		if a < 0 {
+			a = -a
+		}
+		b := imag(d)
+		if b < 0 {
+			b = -b
+		}
+		if a <= b {
+			ratio := real(d) / imag(d)
+			denom := real(d)*ratio + imag(d)
+			return complex((real(n)*ratio+imag(n))/denom,
+				(imag(n)*ratio-real(n))/denom)
+		} else {
+			ratio := imag(d) / real(d)
+			denom := imag(d)*ratio + real(d)
+			return complex((imag(n)*ratio+real(n))/denom,
+				(imag(n)-real(n)*ratio)/denom)
+		}
+	}
+}
diff --git a/src/pkg/runtime/complex_test.go b/src/runtime/complex_test.go
similarity index 100%
rename from src/pkg/runtime/complex_test.go
rename to src/runtime/complex_test.go
diff --git a/src/runtime/cpuprof.go b/src/runtime/cpuprof.go
new file mode 100644
index 0000000..8b1c1c6
--- /dev/null
+++ b/src/runtime/cpuprof.go
@@ -0,0 +1,425 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// CPU profiling.
+// Based on algorithms and data structures used in
+// http://code.google.com/p/google-perftools/.
+//
+// The main difference between this code and the google-perftools
+// code is that this code is written to allow copying the profile data
+// to an arbitrary io.Writer, while the google-perftools code always
+// writes to an operating system file.
+//
+// The signal handler for the profiling clock tick adds a new stack trace
+// to a hash table tracking counts for recent traces.  Most clock ticks
+// hit in the cache.  In the event of a cache miss, an entry must be
+// evicted from the hash table, copied to a log that will eventually be
+// written as profile data.  The google-perftools code flushed the
+// log itself during the signal handler.  This code cannot do that, because
+// the io.Writer might block or need system calls or locks that are not
+// safe to use from within the signal handler.  Instead, we split the log
+// into two halves and let the signal handler fill one half while a goroutine
+// is writing out the other half.  When the signal handler fills its half, it
+// offers to swap with the goroutine.  If the writer is not done with its half,
+// we lose the stack trace for this clock tick (and record that loss).
+// The goroutine interacts with the signal handler by calling getprofile() to
+// get the next log piece to write, implicitly handing back the last log
+// piece it obtained.
+//
+// The state of this dance between the signal handler and the goroutine
+// is encoded in the Profile.handoff field.  If handoff == 0, then the goroutine
+// is not using either log half and is waiting (or will soon be waiting) for
+// a new piece by calling notesleep(&p->wait).  If the signal handler
+// changes handoff from 0 to non-zero, it must call notewakeup(&p->wait)
+// to wake the goroutine.  The value indicates the number of entries in the
+// log half being handed off.  The goroutine leaves the non-zero value in
+// place until it has finished processing the log half and then flips the number
+// back to zero.  Setting the high bit in handoff means that the profiling is over,
+// and the goroutine is now in charge of flushing the data left in the hash table
+// to the log and returning that data.
+//
+// The handoff field is manipulated using atomic operations.
+// For the most part, the manipulation of handoff is orderly: if handoff == 0
+// then the signal handler owns it and can change it to non-zero.
+// If handoff != 0 then the goroutine owns it and can change it to zero.
+// If that were the end of the story then we would not need to manipulate
+// handoff using atomic operations.  The operations are needed, however,
+// in order to let the log closer set the high bit to indicate "EOF" safely
+// in the situation when normally the goroutine "owns" handoff.
+
+package runtime
+
+import "unsafe"
+
+const (
+	numBuckets      = 1 << 10
+	logSize         = 1 << 17
+	assoc           = 4
+	maxCPUProfStack = 64
+)
+
+type cpuprofEntry struct {
+	count uintptr
+	depth uintptr
+	stack [maxCPUProfStack]uintptr
+}
+
+type cpuProfile struct {
+	on     bool    // profiling is on
+	wait   note    // goroutine waits here
+	count  uintptr // tick count
+	evicts uintptr // eviction count
+	lost   uintptr // lost ticks that need to be logged
+
+	// Active recent stack traces.
+	hash [numBuckets]struct {
+		entry [assoc]cpuprofEntry
+	}
+
+	// Log of traces evicted from hash.
+	// Signal handler has filled log[toggle][:nlog].
+	// Goroutine is writing log[1-toggle][:handoff].
+	log     [2][logSize / 2]uintptr
+	nlog    uintptr
+	toggle  int32
+	handoff uint32
+
+	// Writer state.
+	// Writer maintains its own toggle to avoid races
+	// looking at signal handler's toggle.
+	wtoggle  uint32
+	wholding bool // holding & need to release a log half
+	flushing bool // flushing hash table - profile is over
+	eodSent  bool // special end-of-data record sent; => flushing
+}
+
+var (
+	cpuprofLock mutex
+	cpuprof     *cpuProfile
+
+	eod = [3]uintptr{0, 1, 0}
+)
+
+func setcpuprofilerate_m() // proc.c
+
+func setcpuprofilerate(hz int32) {
+	g := getg()
+	g.m.scalararg[0] = uintptr(hz)
+	onM(setcpuprofilerate_m)
+}
+
+// lostProfileData is a no-op function used in profiles
+// to mark the number of profiling stack traces that were
+// discarded due to slow data writers.
+func lostProfileData() {}
+
+// SetCPUProfileRate sets the CPU profiling rate to hz samples per second.
+// If hz <= 0, SetCPUProfileRate turns off profiling.
+// If the profiler is on, the rate cannot be changed without first turning it off.
+//
+// Most clients should use the runtime/pprof package or
+// the testing package's -test.cpuprofile flag instead of calling
+// SetCPUProfileRate directly.
+func SetCPUProfileRate(hz int) {
+	// Clamp hz to something reasonable.
+	if hz < 0 {
+		hz = 0
+	}
+	if hz > 1000000 {
+		hz = 1000000
+	}
+
+	lock(&cpuprofLock)
+	if hz > 0 {
+		if cpuprof == nil {
+			cpuprof = (*cpuProfile)(sysAlloc(unsafe.Sizeof(cpuProfile{}), &memstats.other_sys))
+			if cpuprof == nil {
+				print("runtime: cpu profiling cannot allocate memory\n")
+				unlock(&cpuprofLock)
+				return
+			}
+		}
+		if cpuprof.on || cpuprof.handoff != 0 {
+			print("runtime: cannot set cpu profile rate until previous profile has finished.\n")
+			unlock(&cpuprofLock)
+			return
+		}
+
+		cpuprof.on = true
+		// pprof binary header format.
+		// http://code.google.com/p/google-perftools/source/browse/trunk/src/profiledata.cc#117
+		p := &cpuprof.log[0]
+		p[0] = 0                 // count for header
+		p[1] = 3                 // depth for header
+		p[2] = 0                 // version number
+		p[3] = uintptr(1e6 / hz) // period (microseconds)
+		p[4] = 0
+		cpuprof.nlog = 5
+		cpuprof.toggle = 0
+		cpuprof.wholding = false
+		cpuprof.wtoggle = 0
+		cpuprof.flushing = false
+		cpuprof.eodSent = false
+		noteclear(&cpuprof.wait)
+
+		setcpuprofilerate(int32(hz))
+	} else if cpuprof != nil && cpuprof.on {
+		setcpuprofilerate(0)
+		cpuprof.on = false
+
+		// Now add is not running anymore, and getprofile owns the entire log.
+		// Set the high bit in prof->handoff to tell getprofile.
+		for {
+			n := cpuprof.handoff
+			if n&0x80000000 != 0 {
+				print("runtime: setcpuprofile(off) twice\n")
+			}
+			if cas(&cpuprof.handoff, n, n|0x80000000) {
+				if n == 0 {
+					// we did the transition from 0 -> nonzero so we wake getprofile
+					notewakeup(&cpuprof.wait)
+				}
+				break
+			}
+		}
+	}
+	unlock(&cpuprofLock)
+}
+
+func cpuproftick(pc *uintptr, n int32) {
+	if n > maxCPUProfStack {
+		n = maxCPUProfStack
+	}
+	s := (*[maxCPUProfStack]uintptr)(unsafe.Pointer(pc))[:n]
+	cpuprof.add(s)
+}
+
+// add adds the stack trace to the profile.
+// It is called from signal handlers and other limited environments
+// and cannot allocate memory or acquire locks that might be
+// held at the time of the signal, nor can it use substantial amounts
+// of stack.  It is allowed to call evict.
+func (p *cpuProfile) add(pc []uintptr) {
+	// Compute hash.
+	h := uintptr(0)
+	for _, x := range pc {
+		h = h<<8 | (h >> (8 * (unsafe.Sizeof(h) - 1)))
+		h += x*31 + x*7 + x*3
+	}
+	p.count++
+
+	// Add to entry count if already present in table.
+	b := &p.hash[h%numBuckets]
+Assoc:
+	for i := range b.entry {
+		e := &b.entry[i]
+		if e.depth != uintptr(len(pc)) {
+			continue
+		}
+		for j := range pc {
+			if e.stack[j] != pc[j] {
+				continue Assoc
+			}
+		}
+		e.count++
+		return
+	}
+
+	// Evict entry with smallest count.
+	var e *cpuprofEntry
+	for i := range b.entry {
+		if e == nil || b.entry[i].count < e.count {
+			e = &b.entry[i]
+		}
+	}
+	if e.count > 0 {
+		if !p.evict(e) {
+			// Could not evict entry.  Record lost stack.
+			p.lost++
+			return
+		}
+		p.evicts++
+	}
+
+	// Reuse the newly evicted entry.
+	e.depth = uintptr(len(pc))
+	e.count = 1
+	copy(e.stack[:], pc)
+}
+
+// evict copies the given entry's data into the log, so that
+// the entry can be reused.  evict is called from add, which
+// is called from the profiling signal handler, so it must not
+// allocate memory or block.  It is safe to call flushlog.
+// evict returns true if the entry was copied to the log,
+// false if there was no room available.
+func (p *cpuProfile) evict(e *cpuprofEntry) bool {
+	d := e.depth
+	nslot := d + 2
+	log := &p.log[p.toggle]
+	if p.nlog+nslot > uintptr(len(p.log[0])) {
+		if !p.flushlog() {
+			return false
+		}
+		log = &p.log[p.toggle]
+	}
+
+	q := p.nlog
+	log[q] = e.count
+	q++
+	log[q] = d
+	q++
+	copy(log[q:], e.stack[:d])
+	q += d
+	p.nlog = q
+	e.count = 0
+	return true
+}
+
+// flushlog tries to flush the current log and switch to the other one.
+// flushlog is called from evict, called from add, called from the signal handler,
+// so it cannot allocate memory or block.  It can try to swap logs with
+// the writing goroutine, as explained in the comment at the top of this file.
+func (p *cpuProfile) flushlog() bool {
+	if !cas(&p.handoff, 0, uint32(p.nlog)) {
+		return false
+	}
+	notewakeup(&p.wait)
+
+	p.toggle = 1 - p.toggle
+	log := &p.log[p.toggle]
+	q := uintptr(0)
+	if p.lost > 0 {
+		lostPC := funcPC(lostProfileData)
+		log[0] = p.lost
+		log[1] = 1
+		log[2] = lostPC
+		q = 3
+		p.lost = 0
+	}
+	p.nlog = q
+	return true
+}
+
+// getprofile blocks until the next block of profiling data is available
+// and returns it as a []byte.  It is called from the writing goroutine.
+func (p *cpuProfile) getprofile() []byte {
+	if p == nil {
+		return nil
+	}
+
+	if p.wholding {
+		// Release previous log to signal handling side.
+		// Loop because we are racing against SetCPUProfileRate(0).
+		for {
+			n := p.handoff
+			if n == 0 {
+				print("runtime: phase error during cpu profile handoff\n")
+				return nil
+			}
+			if n&0x80000000 != 0 {
+				p.wtoggle = 1 - p.wtoggle
+				p.wholding = false
+				p.flushing = true
+				goto Flush
+			}
+			if cas(&p.handoff, n, 0) {
+				break
+			}
+		}
+		p.wtoggle = 1 - p.wtoggle
+		p.wholding = false
+	}
+
+	if p.flushing {
+		goto Flush
+	}
+
+	if !p.on && p.handoff == 0 {
+		return nil
+	}
+
+	// Wait for new log.
+	notetsleepg(&p.wait, -1)
+	noteclear(&p.wait)
+
+	switch n := p.handoff; {
+	case n == 0:
+		print("runtime: phase error during cpu profile wait\n")
+		return nil
+	case n == 0x80000000:
+		p.flushing = true
+		goto Flush
+	default:
+		n &^= 0x80000000
+
+		// Return new log to caller.
+		p.wholding = true
+
+		return uintptrBytes(p.log[p.wtoggle][:n])
+	}
+
+	// In flush mode.
+	// Add is no longer being called.  We own the log.
+	// Also, p->handoff is non-zero, so flushlog will return false.
+	// Evict the hash table into the log and return it.
+Flush:
+	for i := range p.hash {
+		b := &p.hash[i]
+		for j := range b.entry {
+			e := &b.entry[j]
+			if e.count > 0 && !p.evict(e) {
+				// Filled the log.  Stop the loop and return what we've got.
+				break Flush
+			}
+		}
+	}
+
+	// Return pending log data.
+	if p.nlog > 0 {
+		// Note that we're using toggle now, not wtoggle,
+		// because we're working on the log directly.
+		n := p.nlog
+		p.nlog = 0
+		return uintptrBytes(p.log[p.toggle][:n])
+	}
+
+	// Made it through the table without finding anything to log.
+	if !p.eodSent {
+		// We may not have space to append this to the partial log buf,
+		// so we always return a new slice for the end-of-data marker.
+		p.eodSent = true
+		return uintptrBytes(eod[:])
+	}
+
+	// Finally done.  Clean up and return nil.
+	p.flushing = false
+	if !cas(&p.handoff, p.handoff, 0) {
+		print("runtime: profile flush racing with something\n")
+	}
+	return nil
+}
+
+func uintptrBytes(p []uintptr) (ret []byte) {
+	pp := (*sliceStruct)(unsafe.Pointer(&p))
+	rp := (*sliceStruct)(unsafe.Pointer(&ret))
+
+	rp.array = pp.array
+	rp.len = pp.len * int(unsafe.Sizeof(p[0]))
+	rp.cap = rp.len
+
+	return
+}
+
+// CPUProfile returns the next chunk of binary CPU profiling stack trace data,
+// blocking until data is available.  If profiling is turned off and all the profile
+// data accumulated while it was on has been returned, CPUProfile returns nil.
+// The caller must save the returned data before calling CPUProfile again.
+//
+// Most clients should use the runtime/pprof package or
+// the testing package's -test.cpuprofile flag instead of calling
+// CPUProfile directly.
+func CPUProfile() []byte {
+	return cpuprof.getprofile()
+}
diff --git a/src/runtime/crash_cgo_test.go b/src/runtime/crash_cgo_test.go
new file mode 100644
index 0000000..972eedc
--- /dev/null
+++ b/src/runtime/crash_cgo_test.go
@@ -0,0 +1,196 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build cgo
+
+package runtime_test
+
+import (
+	"runtime"
+	"strings"
+	"testing"
+)
+
+func TestCgoCrashHandler(t *testing.T) {
+	testCrashHandler(t, true)
+}
+
+func TestCgoSignalDeadlock(t *testing.T) {
+	if testing.Short() && runtime.GOOS == "windows" {
+		t.Skip("Skipping in short mode") // takes up to 64 seconds
+	}
+	got := executeTest(t, cgoSignalDeadlockSource, nil)
+	want := "OK\n"
+	if got != want {
+		t.Fatalf("expected %q, but got %q", want, got)
+	}
+}
+
+func TestCgoTraceback(t *testing.T) {
+	got := executeTest(t, cgoTracebackSource, nil)
+	want := "OK\n"
+	if got != want {
+		t.Fatalf("expected %q, but got %q", want, got)
+	}
+}
+
+func TestCgoExternalThreadPanic(t *testing.T) {
+	if runtime.GOOS == "plan9" {
+		t.Skipf("no pthreads on %s", runtime.GOOS)
+	}
+	csrc := cgoExternalThreadPanicC
+	if runtime.GOOS == "windows" {
+		csrc = cgoExternalThreadPanicC_windows
+	}
+	got := executeTest(t, cgoExternalThreadPanicSource, nil, "main.c", csrc)
+	want := "panic: BOOM"
+	if !strings.Contains(got, want) {
+		t.Fatalf("want failure containing %q. output:\n%s\n", want, got)
+	}
+}
+
+const cgoSignalDeadlockSource = `
+package main
+
+import "C"
+
+import (
+	"fmt"
+	"runtime"
+	"time"
+)
+
+func main() {
+	runtime.GOMAXPROCS(100)
+	ping := make(chan bool)
+	go func() {
+		for i := 0; ; i++ {
+			runtime.Gosched()
+			select {
+			case done := <-ping:
+				if done {
+					ping <- true
+					return
+				}
+				ping <- true
+			default:
+			}
+			func() {
+				defer func() {
+					recover()
+				}()
+				var s *string
+				*s = ""
+			}()
+		}
+	}()
+	time.Sleep(time.Millisecond)
+	for i := 0; i < 64; i++ {
+		go func() {
+			runtime.LockOSThread()
+			select {}
+		}()
+		go func() {
+			runtime.LockOSThread()
+			select {}
+		}()
+		time.Sleep(time.Millisecond)
+		ping <- false
+		select {
+		case <-ping:
+		case <-time.After(time.Second):
+			fmt.Printf("HANG\n")
+			return
+		}
+	}
+	ping <- true
+	select {
+	case <-ping:
+	case <-time.After(time.Second):
+		fmt.Printf("HANG\n")
+		return
+	}
+	fmt.Printf("OK\n")
+}
+`
+
+const cgoTracebackSource = `
+package main
+
+/* void foo(void) {} */
+import "C"
+
+import (
+	"fmt"
+	"runtime"
+)
+
+func main() {
+	C.foo()
+	buf := make([]byte, 1)
+	runtime.Stack(buf, true)
+	fmt.Printf("OK\n")
+}
+`
+
+const cgoExternalThreadPanicSource = `
+package main
+
+// void start(void);
+import "C"
+
+func main() {
+	C.start()
+	select {}
+}
+
+//export gopanic
+func gopanic() {
+	panic("BOOM")
+}
+`
+
+const cgoExternalThreadPanicC = `
+#include <stdlib.h>
+#include <stdio.h>
+#include <pthread.h>
+
+void gopanic(void);
+
+static void*
+die(void* x)
+{
+	gopanic();
+	return 0;
+}
+
+void
+start(void)
+{
+	pthread_t t;
+	if(pthread_create(&t, 0, die, 0) != 0)
+		printf("pthread_create failed\n");
+}
+`
+
+const cgoExternalThreadPanicC_windows = `
+#include <stdlib.h>
+#include <stdio.h>
+
+void gopanic(void);
+
+static void*
+die(void* x)
+{
+	gopanic();
+	return 0;
+}
+
+void
+start(void)
+{
+	if(_beginthreadex(0, 0, die, 0, 0, 0) != 0)
+		printf("_beginthreadex failed\n");
+}
+`
diff --git a/src/runtime/crash_test.go b/src/runtime/crash_test.go
new file mode 100644
index 0000000..211a047
--- /dev/null
+++ b/src/runtime/crash_test.go
@@ -0,0 +1,515 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package runtime_test
+
+import (
+	"io/ioutil"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"runtime"
+	"strings"
+	"testing"
+	"text/template"
+)
+
+// testEnv excludes GODEBUG from the environment
+// to prevent its output from breaking tests that
+// are trying to parse other command output.
+func testEnv(cmd *exec.Cmd) *exec.Cmd {
+	if cmd.Env != nil {
+		panic("environment already set")
+	}
+	for _, env := range os.Environ() {
+		if strings.HasPrefix(env, "GODEBUG=") {
+			continue
+		}
+		cmd.Env = append(cmd.Env, env)
+	}
+	return cmd
+}
+
+func executeTest(t *testing.T, templ string, data interface{}, extra ...string) string {
+	switch runtime.GOOS {
+	case "android", "nacl":
+		t.Skipf("skipping on %s", runtime.GOOS)
+	}
+
+	checkStaleRuntime(t)
+
+	st := template.Must(template.New("crashSource").Parse(templ))
+
+	dir, err := ioutil.TempDir("", "go-build")
+	if err != nil {
+		t.Fatalf("failed to create temp directory: %v", err)
+	}
+	defer os.RemoveAll(dir)
+
+	src := filepath.Join(dir, "main.go")
+	f, err := os.Create(src)
+	if err != nil {
+		t.Fatalf("failed to create file: %v", err)
+	}
+	err = st.Execute(f, data)
+	if err != nil {
+		f.Close()
+		t.Fatalf("failed to execute template: %v", err)
+	}
+	if err := f.Close(); err != nil {
+		t.Fatalf("failed to close file: %v", err)
+	}
+
+	for i := 0; i < len(extra); i += 2 {
+		if err := ioutil.WriteFile(filepath.Join(dir, extra[i]), []byte(extra[i+1]), 0666); err != nil {
+			t.Fatal(err)
+		}
+	}
+
+	cmd := exec.Command("go", "build", "-o", "a.exe")
+	cmd.Dir = dir
+	out, err := testEnv(cmd).CombinedOutput()
+	if err != nil {
+		t.Fatalf("building source: %v\n%s", err, out)
+	}
+
+	got, _ := testEnv(exec.Command(filepath.Join(dir, "a.exe"))).CombinedOutput()
+	return string(got)
+}
+
+func checkStaleRuntime(t *testing.T) {
+	// 'go run' uses the installed copy of runtime.a, which may be out of date.
+	out, err := testEnv(exec.Command("go", "list", "-f", "{{.Stale}}", "runtime")).CombinedOutput()
+	if err != nil {
+		t.Fatalf("failed to execute 'go list': %v\n%v", err, string(out))
+	}
+	if string(out) != "false\n" {
+		t.Fatalf("Stale runtime.a. Run 'go install runtime'.")
+	}
+}
+
+func testCrashHandler(t *testing.T, cgo bool) {
+	type crashTest struct {
+		Cgo bool
+	}
+	output := executeTest(t, crashSource, &crashTest{Cgo: cgo})
+	want := "main: recovered done\nnew-thread: recovered done\nsecond-new-thread: recovered done\nmain-again: recovered done\n"
+	if output != want {
+		t.Fatalf("output:\n%s\n\nwanted:\n%s", output, want)
+	}
+}
+
+func TestCrashHandler(t *testing.T) {
+	testCrashHandler(t, false)
+}
+
+func testDeadlock(t *testing.T, source string) {
+	output := executeTest(t, source, nil)
+	want := "fatal error: all goroutines are asleep - deadlock!\n"
+	if !strings.HasPrefix(output, want) {
+		t.Fatalf("output does not start with %q:\n%s", want, output)
+	}
+}
+
+func TestSimpleDeadlock(t *testing.T) {
+	testDeadlock(t, simpleDeadlockSource)
+}
+
+func TestInitDeadlock(t *testing.T) {
+	testDeadlock(t, initDeadlockSource)
+}
+
+func TestLockedDeadlock(t *testing.T) {
+	testDeadlock(t, lockedDeadlockSource)
+}
+
+func TestLockedDeadlock2(t *testing.T) {
+	testDeadlock(t, lockedDeadlockSource2)
+}
+
+func TestGoexitDeadlock(t *testing.T) {
+	output := executeTest(t, goexitDeadlockSource, nil)
+	want := "no goroutines (main called runtime.Goexit) - deadlock!"
+	if !strings.Contains(output, want) {
+		t.Fatalf("output:\n%s\n\nwant output containing: %s", output, want)
+	}
+}
+
+func TestStackOverflow(t *testing.T) {
+	output := executeTest(t, stackOverflowSource, nil)
+	want := "runtime: goroutine stack exceeds 4194304-byte limit\nfatal error: stack overflow"
+	if !strings.HasPrefix(output, want) {
+		t.Fatalf("output does not start with %q:\n%s", want, output)
+	}
+}
+
+func TestThreadExhaustion(t *testing.T) {
+	output := executeTest(t, threadExhaustionSource, nil)
+	want := "runtime: program exceeds 10-thread limit\nfatal error: thread exhaustion"
+	if !strings.HasPrefix(output, want) {
+		t.Fatalf("output does not start with %q:\n%s", want, output)
+	}
+}
+
+func TestRecursivePanic(t *testing.T) {
+	output := executeTest(t, recursivePanicSource, nil)
+	want := `wrap: bad
+panic: again
+
+`
+	if !strings.HasPrefix(output, want) {
+		t.Fatalf("output does not start with %q:\n%s", want, output)
+	}
+
+}
+
+func TestGoexitCrash(t *testing.T) {
+	output := executeTest(t, goexitExitSource, nil)
+	want := "no goroutines (main called runtime.Goexit) - deadlock!"
+	if !strings.Contains(output, want) {
+		t.Fatalf("output:\n%s\n\nwant output containing: %s", output, want)
+	}
+}
+
+func TestGoexitDefer(t *testing.T) {
+	c := make(chan struct{})
+	go func() {
+		defer func() {
+			r := recover()
+			if r != nil {
+				t.Errorf("non-nil recover during Goexit")
+			}
+			c <- struct{}{}
+		}()
+		runtime.Goexit()
+	}()
+	// Note: if the defer fails to run, we will get a deadlock here
+	<-c
+}
+
+func TestGoNil(t *testing.T) {
+	output := executeTest(t, goNilSource, nil)
+	want := "go of nil func value"
+	if !strings.Contains(output, want) {
+		t.Fatalf("output:\n%s\n\nwant output containing: %s", output, want)
+	}
+}
+
+func TestMainGoroutineId(t *testing.T) {
+	output := executeTest(t, mainGoroutineIdSource, nil)
+	want := "panic: test\n\ngoroutine 1 [running]:\n"
+	if !strings.HasPrefix(output, want) {
+		t.Fatalf("output does not start with %q:\n%s", want, output)
+	}
+}
+
+func TestBreakpoint(t *testing.T) {
+	output := executeTest(t, breakpointSource, nil)
+	want := "runtime.Breakpoint()"
+	if !strings.Contains(output, want) {
+		t.Fatalf("output:\n%s\n\nwant output containing: %s", output, want)
+	}
+}
+
+const crashSource = `
+package main
+
+import (
+	"fmt"
+	"runtime"
+)
+
+{{if .Cgo}}
+import "C"
+{{end}}
+
+func test(name string) {
+	defer func() {
+		if x := recover(); x != nil {
+			fmt.Printf(" recovered")
+		}
+		fmt.Printf(" done\n")
+	}()
+	fmt.Printf("%s:", name)
+	var s *string
+	_ = *s
+	fmt.Print("SHOULD NOT BE HERE")
+}
+
+func testInNewThread(name string) {
+	c := make(chan bool)
+	go func() {
+		runtime.LockOSThread()
+		test(name)
+		c <- true
+	}()
+	<-c
+}
+
+func main() {
+	runtime.LockOSThread()
+	test("main")
+	testInNewThread("new-thread")
+	testInNewThread("second-new-thread")
+	test("main-again")
+}
+`
+
+const simpleDeadlockSource = `
+package main
+func main() {
+	select {}
+}
+`
+
+const initDeadlockSource = `
+package main
+func init() {
+	select {}
+}
+func main() {
+}
+`
+
+const lockedDeadlockSource = `
+package main
+import "runtime"
+func main() {
+	runtime.LockOSThread()
+	select {}
+}
+`
+
+const lockedDeadlockSource2 = `
+package main
+import (
+	"runtime"
+	"time"
+)
+func main() {
+	go func() {
+		runtime.LockOSThread()
+		select {}
+	}()
+	time.Sleep(time.Millisecond)
+	select {}
+}
+`
+
+const goexitDeadlockSource = `
+package main
+import (
+      "runtime"
+)
+
+func F() {
+      for i := 0; i < 10; i++ {
+      }
+}
+
+func main() {
+      go F()
+      go F()
+      runtime.Goexit()
+}
+`
+
+const stackOverflowSource = `
+package main
+
+import "runtime/debug"
+
+func main() {
+	debug.SetMaxStack(4<<20)
+	f(make([]byte, 10))
+}
+
+func f(x []byte) byte {
+	var buf [64<<10]byte
+	return x[0] + f(buf[:])
+}
+`
+
+const threadExhaustionSource = `
+package main
+
+import (
+	"runtime"
+	"runtime/debug"
+)
+
+func main() {
+	debug.SetMaxThreads(10)
+	c := make(chan int)
+	for i := 0; i < 100; i++ {
+		go func() {
+			runtime.LockOSThread()
+			c <- 0
+			select{}
+		}()
+		<-c
+	}
+}
+`
+
+const recursivePanicSource = `
+package main
+
+import (
+	"fmt"
+)
+
+func main() {
+	func() {
+		defer func() {
+			fmt.Println(recover())
+		}()
+		var x [8192]byte
+		func(x [8192]byte) {
+			defer func() {
+				if err := recover(); err != nil {
+					panic("wrap: " + err.(string))
+				}
+			}()
+			panic("bad")
+		}(x)
+	}()
+	panic("again")
+}
+`
+
+const goexitExitSource = `
+package main
+
+import (
+	"runtime"
+	"time"
+)
+
+func main() {
+	go func() {
+		time.Sleep(time.Millisecond)
+	}()
+	i := 0
+	runtime.SetFinalizer(&i, func(p *int) {})
+	runtime.GC()
+	runtime.Goexit()
+}
+`
+
+const goNilSource = `
+package main
+
+func main() {
+	defer func() {
+		recover()
+	}()
+	var f func()
+	go f()
+	select{}
+}
+`
+
+const mainGoroutineIdSource = `
+package main
+func main() {
+	panic("test")
+}
+`
+
+const breakpointSource = `
+package main
+import "runtime"
+func main() {
+	runtime.Breakpoint()
+}
+`
+
+func TestGoexitInPanic(t *testing.T) {
+	// see issue 8774: this code used to trigger an infinite recursion
+	output := executeTest(t, goexitInPanicSource, nil)
+	want := "fatal error: no goroutines (main called runtime.Goexit) - deadlock!"
+	if !strings.HasPrefix(output, want) {
+		t.Fatalf("output does not start with %q:\n%s", want, output)
+	}
+}
+
+const goexitInPanicSource = `
+package main
+import "runtime"
+func main() {
+	go func() {
+		defer func() {
+			runtime.Goexit()
+		}()
+		panic("hello")
+	}()
+	runtime.Goexit()
+}
+`
+
+func TestPanicAfterGoexit(t *testing.T) {
+	// an uncaught panic should still work after goexit
+	output := executeTest(t, panicAfterGoexitSource, nil)
+	want := "panic: hello"
+	if !strings.HasPrefix(output, want) {
+		t.Fatalf("output does not start with %q:\n%s", want, output)
+	}
+}
+
+const panicAfterGoexitSource = `
+package main
+import "runtime"
+func main() {
+	defer func() {
+		panic("hello")
+	}()
+	runtime.Goexit()
+}
+`
+
+func TestRecoveredPanicAfterGoexit(t *testing.T) {
+	output := executeTest(t, recoveredPanicAfterGoexitSource, nil)
+	want := "fatal error: no goroutines (main called runtime.Goexit) - deadlock!"
+	if !strings.HasPrefix(output, want) {
+		t.Fatalf("output does not start with %q:\n%s", want, output)
+	}
+}
+
+const recoveredPanicAfterGoexitSource = `
+package main
+import "runtime"
+func main() {
+	defer func() {
+		defer func() {
+			r := recover()
+			if r == nil {
+				panic("bad recover")
+			}
+		}()
+		panic("hello")
+	}()
+	runtime.Goexit()
+}
+`
+
+func TestRecoverBeforePanicAfterGoexit(t *testing.T) {
+	// 1. defer a function that recovers
+	// 2. defer a function that panics
+	// 3. call goexit
+	// Goexit should run the #2 defer.  Its panic
+	// should be caught by the #1 defer, and execution
+	// should resume in the caller.  Like the Goexit
+	// never happened!
+	defer func() {
+		r := recover()
+		if r == nil {
+			panic("bad recover")
+		}
+	}()
+	defer func() {
+		panic("hello")
+	}()
+	runtime.Goexit()
+}
diff --git a/src/runtime/debug.go b/src/runtime/debug.go
new file mode 100644
index 0000000..4414dd5
--- /dev/null
+++ b/src/runtime/debug.go
@@ -0,0 +1,70 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package runtime
+
+import "unsafe"
+
+// Breakpoint executes a breakpoint trap.
+func Breakpoint()
+
+// LockOSThread wires the calling goroutine to its current operating system thread.
+// Until the calling goroutine exits or calls UnlockOSThread, it will always
+// execute in that thread, and no other goroutine can.
+func LockOSThread()
+
+// UnlockOSThread unwires the calling goroutine from its fixed operating system thread.
+// If the calling goroutine has not called LockOSThread, UnlockOSThread is a no-op.
+func UnlockOSThread()
+
+// GOMAXPROCS sets the maximum number of CPUs that can be executing
+// simultaneously and returns the previous setting.  If n < 1, it does not
+// change the current setting.
+// The number of logical CPUs on the local machine can be queried with NumCPU.
+// This call will go away when the scheduler improves.
+func GOMAXPROCS(n int) int {
+	if n > _MaxGomaxprocs {
+		n = _MaxGomaxprocs
+	}
+	lock(&sched.lock)
+	ret := int(gomaxprocs)
+	unlock(&sched.lock)
+	if n <= 0 || n == ret {
+		return ret
+	}
+
+	semacquire(&worldsema, false)
+	gp := getg()
+	gp.m.gcing = 1
+	onM(stoptheworld)
+
+	// newprocs will be processed by starttheworld
+	newprocs = int32(n)
+
+	gp.m.gcing = 0
+	semrelease(&worldsema)
+	onM(starttheworld)
+	return ret
+}
+
+// NumCPU returns the number of logical CPUs on the local machine.
+func NumCPU() int {
+	return int(ncpu)
+}
+
+// NumCgoCall returns the number of cgo calls made by the current process.
+func NumCgoCall() int64 {
+	var n int64
+	for mp := (*m)(atomicloadp(unsafe.Pointer(&allm))); mp != nil; mp = mp.alllink {
+		n += int64(mp.ncgocall)
+	}
+	return n
+}
+
+// NumGoroutine returns the number of goroutines that currently exist.
+func NumGoroutine() int {
+	return int(gcount())
+}
+
+func gcount() int32
diff --git a/src/pkg/runtime/debug/debug.c b/src/runtime/debug/debug.s
similarity index 100%
rename from src/pkg/runtime/debug/debug.c
rename to src/runtime/debug/debug.s
diff --git a/src/runtime/debug/garbage.go b/src/runtime/debug/garbage.go
new file mode 100644
index 0000000..4a77dcf
--- /dev/null
+++ b/src/runtime/debug/garbage.go
@@ -0,0 +1,159 @@
+// Copyright 2013 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package debug
+
+import (
+	"runtime"
+	"sort"
+	"time"
+)
+
+// GCStats collect information about recent garbage collections.
+type GCStats struct {
+	LastGC         time.Time       // time of last collection
+	NumGC          int64           // number of garbage collections
+	PauseTotal     time.Duration   // total pause for all collections
+	Pause          []time.Duration // pause history, most recent first
+	PauseEnd       []time.Time     // pause end times history, most recent first
+	PauseQuantiles []time.Duration
+}
+
+// ReadGCStats reads statistics about garbage collection into stats.
+// The number of entries in the pause history is system-dependent;
+// stats.Pause slice will be reused if large enough, reallocated otherwise.
+// ReadGCStats may use the full capacity of the stats.Pause slice.
+// If stats.PauseQuantiles is non-empty, ReadGCStats fills it with quantiles
+// summarizing the distribution of pause time. For example, if
+// len(stats.PauseQuantiles) is 5, it will be filled with the minimum,
+// 25%, 50%, 75%, and maximum pause times.
+func ReadGCStats(stats *GCStats) {
+	// Create a buffer with space for at least two copies of the
+	// pause history tracked by the runtime. One will be returned
+	// to the caller and the other will be used as transfer buffer
+	// for end times history and as a temporary buffer for
+	// computing quantiles.
+	const maxPause = len(((*runtime.MemStats)(nil)).PauseNs)
+	if cap(stats.Pause) < 2*maxPause+3 {
+		stats.Pause = make([]time.Duration, 2*maxPause+3)
+	}
+
+	// readGCStats fills in the pause and end times histories (up to
+	// maxPause entries) and then three more: Unix ns time of last GC,
+	// number of GC, and total pause time in nanoseconds. Here we
+	// depend on the fact that time.Duration's native unit is
+	// nanoseconds, so the pauses and the total pause time do not need
+	// any conversion.
+	readGCStats(&stats.Pause)
+	n := len(stats.Pause) - 3
+	stats.LastGC = time.Unix(0, int64(stats.Pause[n]))
+	stats.NumGC = int64(stats.Pause[n+1])
+	stats.PauseTotal = stats.Pause[n+2]
+	n /= 2 // buffer holds pauses and end times
+	stats.Pause = stats.Pause[:n]
+
+	if cap(stats.PauseEnd) < maxPause {
+		stats.PauseEnd = make([]time.Time, 0, maxPause)
+	}
+	stats.PauseEnd = stats.PauseEnd[:0]
+	for _, ns := range stats.Pause[n : n+n] {
+		stats.PauseEnd = append(stats.PauseEnd, time.Unix(0, int64(ns)))
+	}
+
+	if len(stats.PauseQuantiles) > 0 {
+		if n == 0 {
+			for i := range stats.PauseQuantiles {
+				stats.PauseQuantiles[i] = 0
+			}
+		} else {
+			// There's room for a second copy of the data in stats.Pause.
+			// See the allocation at the top of the function.
+			sorted := stats.Pause[n : n+n]
+			copy(sorted, stats.Pause)
+			sort.Sort(byDuration(sorted))
+			nq := len(stats.PauseQuantiles) - 1
+			for i := 0; i < nq; i++ {
+				stats.PauseQuantiles[i] = sorted[len(sorted)*i/nq]
+			}
+			stats.PauseQuantiles[nq] = sorted[len(sorted)-1]
+		}
+	}
+}
+
+type byDuration []time.Duration
+
+func (x byDuration) Len() int           { return len(x) }
+func (x byDuration) Swap(i, j int)      { x[i], x[j] = x[j], x[i] }
+func (x byDuration) Less(i, j int) bool { return x[i] < x[j] }
+
+// SetGCPercent sets the garbage collection target percentage:
+// a collection is triggered when the ratio of freshly allocated data
+// to live data remaining after the previous collection reaches this percentage.
+// SetGCPercent returns the previous setting.
+// The initial setting is the value of the GOGC environment variable
+// at startup, or 100 if the variable is not set.
+// A negative percentage disables garbage collection.
+func SetGCPercent(percent int) int {
+	old := setGCPercent(int32(percent))
+	runtime.GC()
+	return int(old)
+}
+
+// FreeOSMemory forces a garbage collection followed by an
+// attempt to return as much memory to the operating system
+// as possible. (Even if this is not called, the runtime gradually
+// returns memory to the operating system in a background task.)
+func FreeOSMemory() {
+	freeOSMemory()
+}
+
+// SetMaxStack sets the maximum amount of memory that
+// can be used by a single goroutine stack.
+// If any goroutine exceeds this limit while growing its stack,
+// the program crashes.
+// SetMaxStack returns the previous setting.
+// The initial setting is 1 GB on 64-bit systems, 250 MB on 32-bit systems.
+//
+// SetMaxStack is useful mainly for limiting the damage done by
+// goroutines that enter an infinite recursion. It only limits future
+// stack growth.
+func SetMaxStack(bytes int) int {
+	return setMaxStack(bytes)
+}
+
+// SetMaxThreads sets the maximum number of operating system
+// threads that the Go program can use. If it attempts to use more than
+// this many, the program crashes.
+// SetMaxThreads returns the previous setting.
+// The initial setting is 10,000 threads.
+//
+// The limit controls the number of operating system threads, not the number
+// of goroutines. A Go program creates a new thread only when a goroutine
+// is ready to run but all the existing threads are blocked in system calls, cgo calls,
+// or are locked to other goroutines due to use of runtime.LockOSThread.
+//
+// SetMaxThreads is useful mainly for limiting the damage done by
+// programs that create an unbounded number of threads. The idea is
+// to take down the program before it takes down the operating system.
+func SetMaxThreads(threads int) int {
+	return setMaxThreads(threads)
+}
+
+// SetPanicOnFault controls the runtime's behavior when a program faults
+// at an unexpected (non-nil) address. Such faults are typically caused by
+// bugs such as runtime memory corruption, so the default response is to crash
+// the program. Programs working with memory-mapped files or unsafe
+// manipulation of memory may cause faults at non-nil addresses in less
+// dramatic situations; SetPanicOnFault allows such programs to request
+// that the runtime trigger only a panic, not a crash.
+// SetPanicOnFault applies only to the current goroutine.
+// It returns the previous setting.
+func SetPanicOnFault(enabled bool) bool {
+	return setPanicOnFault(enabled)
+}
+
+// WriteHeapDump writes a description of the heap and the objects in
+// it to the given file descriptor.
+// The heap dump format is defined at http://golang.org/s/go13heapdump.
+func WriteHeapDump(fd uintptr)
diff --git a/src/runtime/debug/garbage_test.go b/src/runtime/debug/garbage_test.go
new file mode 100644
index 0000000..54c33bd
--- /dev/null
+++ b/src/runtime/debug/garbage_test.go
@@ -0,0 +1,115 @@
+// Copyright 2013 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package debug
+
+import (
+	"runtime"
+	"testing"
+	"time"
+)
+
+func TestReadGCStats(t *testing.T) {
+	defer SetGCPercent(SetGCPercent(-1))
+
+	var stats GCStats
+	var mstats runtime.MemStats
+	var min, max time.Duration
+
+	// First ReadGCStats will allocate, second should not,
+	// especially if we follow up with an explicit garbage collection.
+	stats.PauseQuantiles = make([]time.Duration, 10)
+	ReadGCStats(&stats)
+	runtime.GC()
+
+	// Assume these will return same data: no GC during ReadGCStats.
+	ReadGCStats(&stats)
+	runtime.ReadMemStats(&mstats)
+
+	if stats.NumGC != int64(mstats.NumGC) {
+		t.Errorf("stats.NumGC = %d, but mstats.NumGC = %d", stats.NumGC, mstats.NumGC)
+	}
+	if stats.PauseTotal != time.Duration(mstats.PauseTotalNs) {
+		t.Errorf("stats.PauseTotal = %d, but mstats.PauseTotalNs = %d", stats.PauseTotal, mstats.PauseTotalNs)
+	}
+	if stats.LastGC.UnixNano() != int64(mstats.LastGC) {
+		t.Errorf("stats.LastGC.UnixNano = %d, but mstats.LastGC = %d", stats.LastGC.UnixNano(), mstats.LastGC)
+	}
+	n := int(mstats.NumGC)
+	if n > len(mstats.PauseNs) {
+		n = len(mstats.PauseNs)
+	}
+	if len(stats.Pause) != n {
+		t.Errorf("len(stats.Pause) = %d, want %d", len(stats.Pause), n)
+	} else {
+		off := (int(mstats.NumGC) + len(mstats.PauseNs) - 1) % len(mstats.PauseNs)
+		for i := 0; i < n; i++ {
+			dt := stats.Pause[i]
+			if dt != time.Duration(mstats.PauseNs[off]) {
+				t.Errorf("stats.Pause[%d] = %d, want %d", i, dt, mstats.PauseNs[off])
+			}
+			if max < dt {
+				max = dt
+			}
+			if min > dt || i == 0 {
+				min = dt
+			}
+			off = (off + len(mstats.PauseNs) - 1) % len(mstats.PauseNs)
+		}
+	}
+
+	q := stats.PauseQuantiles
+	nq := len(q)
+	if q[0] != min || q[nq-1] != max {
+		t.Errorf("stats.PauseQuantiles = [%d, ..., %d], want [%d, ..., %d]", q[0], q[nq-1], min, max)
+	}
+
+	for i := 0; i < nq-1; i++ {
+		if q[i] > q[i+1] {
+			t.Errorf("stats.PauseQuantiles[%d]=%d > stats.PauseQuantiles[%d]=%d", i, q[i], i+1, q[i+1])
+		}
+	}
+
+	// compare memory stats with gc stats:
+	if len(stats.PauseEnd) != n {
+		t.Fatalf("len(stats.PauseEnd) = %d, want %d", len(stats.PauseEnd), n)
+	}
+	off := (int(mstats.NumGC) + len(mstats.PauseEnd) - 1) % len(mstats.PauseEnd)
+	for i := 0; i < n; i++ {
+		dt := stats.PauseEnd[i]
+		if dt.UnixNano() != int64(mstats.PauseEnd[off]) {
+			t.Errorf("stats.PauseEnd[%d] = %d, want %d", i, dt, mstats.PauseEnd[off])
+		}
+		off = (off + len(mstats.PauseEnd) - 1) % len(mstats.PauseEnd)
+	}
+}
+
+var big = make([]byte, 1<<20)
+
+func TestFreeOSMemory(t *testing.T) {
+	var ms1, ms2 runtime.MemStats
+
+	if big == nil {
+		t.Skip("test is not reliable when run multiple times")
+	}
+	big = nil
+	runtime.GC()
+	runtime.ReadMemStats(&ms1)
+	FreeOSMemory()
+	runtime.ReadMemStats(&ms2)
+	if ms1.HeapReleased >= ms2.HeapReleased {
+		t.Errorf("released before=%d; released after=%d; did not go up", ms1.HeapReleased, ms2.HeapReleased)
+	}
+}
+
+func TestSetGCPercent(t *testing.T) {
+	// Test that the variable is being set and returned correctly.
+	// Assume the percentage itself is implemented fine during GC,
+	// which is harder to test.
+	old := SetGCPercent(123)
+	new := SetGCPercent(old)
+	if new != 123 {
+		t.Errorf("SetGCPercent(123); SetGCPercent(x) = %d, want 123", new)
+	}
+}
diff --git a/src/pkg/runtime/debug/heapdump_test.go b/src/runtime/debug/heapdump_test.go
similarity index 100%
rename from src/pkg/runtime/debug/heapdump_test.go
rename to src/runtime/debug/heapdump_test.go
diff --git a/src/pkg/runtime/debug/stack.go b/src/runtime/debug/stack.go
similarity index 100%
rename from src/pkg/runtime/debug/stack.go
rename to src/runtime/debug/stack.go
diff --git a/src/runtime/debug/stack_test.go b/src/runtime/debug/stack_test.go
new file mode 100644
index 0000000..28691ee
--- /dev/null
+++ b/src/runtime/debug/stack_test.go
@@ -0,0 +1,62 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package debug
+
+import (
+	"strings"
+	"testing"
+)
+
+type T int
+
+func (t *T) ptrmethod() []byte {
+	return Stack()
+}
+func (t T) method() []byte {
+	return t.ptrmethod()
+}
+
+/*
+	The traceback should look something like this, modulo line numbers and hex constants.
+	Don't worry much about the base levels, but check the ones in our own package.
+
+		/Users/r/go/src/runtime/debug/stack_test.go:15 (0x13878)
+			(*T).ptrmethod: return Stack()
+		/Users/r/go/src/runtime/debug/stack_test.go:18 (0x138dd)
+			T.method: return t.ptrmethod()
+		/Users/r/go/src/runtime/debug/stack_test.go:23 (0x13920)
+			TestStack: b := T(0).method()
+		/Users/r/go/src/testing/testing.go:132 (0x14a7a)
+			tRunner: test.F(t)
+		/Users/r/go/src/runtime/proc.c:145 (0xc970)
+			???: runtime·unlock(&runtime·sched);
+*/
+func TestStack(t *testing.T) {
+	b := T(0).method()
+	lines := strings.Split(string(b), "\n")
+	if len(lines) < 6 {
+		t.Fatal("too few lines")
+	}
+	n := 0
+	frame := func(line, code string) {
+		check(t, lines[n], line)
+		n++
+		// The source might not be available while running the test.
+		if strings.HasPrefix(lines[n], "\t") {
+			check(t, lines[n], code)
+			n++
+		}
+	}
+	frame("src/runtime/debug/stack_test.go", "\t(*T).ptrmethod: return Stack()")
+	frame("src/runtime/debug/stack_test.go", "\tT.method: return t.ptrmethod()")
+	frame("src/runtime/debug/stack_test.go", "\tTestStack: b := T(0).method()")
+	frame("src/testing/testing.go", "")
+}
+
+func check(t *testing.T, line, has string) {
+	if strings.Index(line, has) < 0 {
+		t.Errorf("expected %q in %q", has, line)
+	}
+}
diff --git a/src/runtime/debug/stubs.go b/src/runtime/debug/stubs.go
new file mode 100644
index 0000000..8fba6cf
--- /dev/null
+++ b/src/runtime/debug/stubs.go
@@ -0,0 +1,20 @@
+// 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 debug
+
+import (
+	"time"
+)
+
+// Uses assembly to call corresponding runtime-internal functions.
+func setMaxStack(int) int
+func setGCPercent(int32) int32
+func setPanicOnFault(bool) bool
+func setMaxThreads(int) int
+
+// Implemented in package runtime.
+func readGCStats(*[]time.Duration)
+func enableGC(bool) bool
+func freeOSMemory()
diff --git a/src/runtime/debug/stubs.s b/src/runtime/debug/stubs.s
new file mode 100644
index 0000000..d56274f
--- /dev/null
+++ b/src/runtime/debug/stubs.s
@@ -0,0 +1,21 @@
+// 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"
+
+#ifdef GOARCH_arm
+#define JMP B
+#endif
+
+TEXT ·setMaxStack(SB),NOSPLIT,$0-0
+  JMP runtime·setMaxStack(SB)
+
+TEXT ·setGCPercent(SB),NOSPLIT,$0-0
+  JMP runtime·setGCPercent(SB)
+
+TEXT ·setPanicOnFault(SB),NOSPLIT,$0-0
+  JMP runtime·setPanicOnFault(SB)
+
+TEXT ·setMaxThreads(SB),NOSPLIT,$0-0
+  JMP runtime·setMaxThreads(SB)
diff --git a/src/runtime/defs.c b/src/runtime/defs.c
new file mode 100644
index 0000000..b0a9b20
--- /dev/null
+++ b/src/runtime/defs.c
@@ -0,0 +1,15 @@
+// Copyright 2013 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file is compiled by cmd/dist to obtain debug information
+// about the given header files.
+
+#include "runtime.h"
+#include "arch_GOARCH.h"
+#include "malloc.h"
+#include "type.h"
+#include "race.h"
+#include "chan.h"
+#include "defs_GOOS_GOARCH.h"
+#include "os_GOOS.h"
diff --git a/src/runtime/defs1_linux.go b/src/runtime/defs1_linux.go
new file mode 100644
index 0000000..392cc4a
--- /dev/null
+++ b/src/runtime/defs1_linux.go
@@ -0,0 +1,37 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build ignore
+
+/*
+Input to cgo -cdefs
+
+GOARCH=amd64 cgo -cdefs defs.go defs1.go >amd64/defs.h
+*/
+
+package runtime
+
+/*
+#include <ucontext.h>
+#include <fcntl.h>
+*/
+import "C"
+
+const (
+	O_RDONLY  = C.O_RDONLY
+	O_CLOEXEC = C.O_CLOEXEC
+)
+
+type Usigset C.__sigset_t
+type Fpxreg C.struct__libc_fpxreg
+type Xmmreg C.struct__libc_xmmreg
+type Fpstate C.struct__libc_fpstate
+type Fpxreg1 C.struct__fpxreg
+type Xmmreg1 C.struct__xmmreg
+type Fpstate1 C.struct__fpstate
+type Fpreg1 C.struct__fpreg
+type SigaltstackT C.struct_sigaltstack
+type Mcontext C.mcontext_t
+type Ucontext C.ucontext_t
+type Sigcontext C.struct_sigcontext
diff --git a/src/runtime/defs2_linux.go b/src/runtime/defs2_linux.go
new file mode 100644
index 0000000..980df9e
--- /dev/null
+++ b/src/runtime/defs2_linux.go
@@ -0,0 +1,146 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build ignore
+
+/*
+ * Input to cgo -cdefs
+
+GOARCH=386 go tool cgo -cdefs defs2_linux.go >defs_linux_386.h
+
+The asm header tricks we have to use for Linux on amd64
+(see defs.c and defs1.c) don't work here, so this is yet another
+file.  Sigh.
+*/
+
+package runtime
+
+/*
+#cgo CFLAGS: -I/tmp/linux/arch/x86/include -I/tmp/linux/include -D_LOOSE_KERNEL_NAMES -D__ARCH_SI_UID_T=__kernel_uid32_t
+
+#define size_t __kernel_size_t
+#define pid_t int
+#include <asm/signal.h>
+#include <asm/mman.h>
+#include <asm/sigcontext.h>
+#include <asm/ucontext.h>
+#include <asm/siginfo.h>
+#include <asm-generic/errno.h>
+#include <asm-generic/fcntl.h>
+#include <asm-generic/poll.h>
+#include <linux/eventpoll.h>
+
+// This is the sigaction structure from the Linux 2.1.68 kernel which
+//   is used with the rt_sigaction system call.  For 386 this is not
+//   defined in any public header file.
+
+struct kernel_sigaction {
+	__sighandler_t k_sa_handler;
+	unsigned long sa_flags;
+	void (*sa_restorer) (void);
+	unsigned long long sa_mask;
+};
+*/
+import "C"
+
+const (
+	EINTR  = C.EINTR
+	EAGAIN = C.EAGAIN
+	ENOMEM = C.ENOMEM
+
+	PROT_NONE  = C.PROT_NONE
+	PROT_READ  = C.PROT_READ
+	PROT_WRITE = C.PROT_WRITE
+	PROT_EXEC  = C.PROT_EXEC
+
+	MAP_ANON    = C.MAP_ANONYMOUS
+	MAP_PRIVATE = C.MAP_PRIVATE
+	MAP_FIXED   = C.MAP_FIXED
+
+	MADV_DONTNEED = C.MADV_DONTNEED
+
+	SA_RESTART  = C.SA_RESTART
+	SA_ONSTACK  = C.SA_ONSTACK
+	SA_RESTORER = C.SA_RESTORER
+	SA_SIGINFO  = C.SA_SIGINFO
+
+	SIGHUP    = C.SIGHUP
+	SIGINT    = C.SIGINT
+	SIGQUIT   = C.SIGQUIT
+	SIGILL    = C.SIGILL
+	SIGTRAP   = C.SIGTRAP
+	SIGABRT   = C.SIGABRT
+	SIGBUS    = C.SIGBUS
+	SIGFPE    = C.SIGFPE
+	SIGKILL   = C.SIGKILL
+	SIGUSR1   = C.SIGUSR1
+	SIGSEGV   = C.SIGSEGV
+	SIGUSR2   = C.SIGUSR2
+	SIGPIPE   = C.SIGPIPE
+	SIGALRM   = C.SIGALRM
+	SIGSTKFLT = C.SIGSTKFLT
+	SIGCHLD   = C.SIGCHLD
+	SIGCONT   = C.SIGCONT
+	SIGSTOP   = C.SIGSTOP
+	SIGTSTP   = C.SIGTSTP
+	SIGTTIN   = C.SIGTTIN
+	SIGTTOU   = C.SIGTTOU
+	SIGURG    = C.SIGURG
+	SIGXCPU   = C.SIGXCPU
+	SIGXFSZ   = C.SIGXFSZ
+	SIGVTALRM = C.SIGVTALRM
+	SIGPROF   = C.SIGPROF
+	SIGWINCH  = C.SIGWINCH
+	SIGIO     = C.SIGIO
+	SIGPWR    = C.SIGPWR
+	SIGSYS    = C.SIGSYS
+
+	FPE_INTDIV = C.FPE_INTDIV
+	FPE_INTOVF = C.FPE_INTOVF
+	FPE_FLTDIV = C.FPE_FLTDIV
+	FPE_FLTOVF = C.FPE_FLTOVF
+	FPE_FLTUND = C.FPE_FLTUND
+	FPE_FLTRES = C.FPE_FLTRES
+	FPE_FLTINV = C.FPE_FLTINV
+	FPE_FLTSUB = C.FPE_FLTSUB
+
+	BUS_ADRALN = C.BUS_ADRALN
+	BUS_ADRERR = C.BUS_ADRERR
+	BUS_OBJERR = C.BUS_OBJERR
+
+	SEGV_MAPERR = C.SEGV_MAPERR
+	SEGV_ACCERR = C.SEGV_ACCERR
+
+	ITIMER_REAL    = C.ITIMER_REAL
+	ITIMER_VIRTUAL = C.ITIMER_VIRTUAL
+	ITIMER_PROF    = C.ITIMER_PROF
+
+	O_RDONLY  = C.O_RDONLY
+	O_CLOEXEC = C.O_CLOEXEC
+
+	EPOLLIN       = C.POLLIN
+	EPOLLOUT      = C.POLLOUT
+	EPOLLERR      = C.POLLERR
+	EPOLLHUP      = C.POLLHUP
+	EPOLLRDHUP    = C.POLLRDHUP
+	EPOLLET       = C.EPOLLET
+	EPOLL_CLOEXEC = C.EPOLL_CLOEXEC
+	EPOLL_CTL_ADD = C.EPOLL_CTL_ADD
+	EPOLL_CTL_DEL = C.EPOLL_CTL_DEL
+	EPOLL_CTL_MOD = C.EPOLL_CTL_MOD
+)
+
+type Fpreg C.struct__fpreg
+type Fpxreg C.struct__fpxreg
+type Xmmreg C.struct__xmmreg
+type Fpstate C.struct__fpstate
+type Timespec C.struct_timespec
+type Timeval C.struct_timeval
+type Sigaction C.struct_kernel_sigaction
+type Siginfo C.siginfo_t
+type SigaltstackT C.struct_sigaltstack
+type Sigcontext C.struct_sigcontext
+type Ucontext C.struct_ucontext
+type Itimerval C.struct_itimerval
+type EpollEvent C.struct_epoll_event
diff --git a/src/runtime/defs_android_arm.h b/src/runtime/defs_android_arm.h
new file mode 100644
index 0000000..3611b3a
--- /dev/null
+++ b/src/runtime/defs_android_arm.h
@@ -0,0 +1,3 @@
+// TODO: Generate using cgo like defs_linux_{386,amd64}.h
+
+#include "defs_linux_arm.h"
diff --git a/src/runtime/defs_arm_linux.go b/src/runtime/defs_arm_linux.go
new file mode 100644
index 0000000..afd6897
--- /dev/null
+++ b/src/runtime/defs_arm_linux.go
@@ -0,0 +1,124 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build ignore
+
+/*
+Input to cgo.
+On a Debian Lenny arm linux distribution:
+
+cgo -cdefs defs_arm.c >arm/defs.h
+*/
+
+package runtime
+
+/*
+#cgo CFLAGS: -I/usr/src/linux-headers-2.6.26-2-versatile/include
+
+#define __ARCH_SI_UID_T int
+#include <asm/signal.h>
+#include <asm/mman.h>
+#include <asm/sigcontext.h>
+#include <asm/ucontext.h>
+#include <asm/siginfo.h>
+#include <linux/time.h>
+
+struct xsiginfo {
+	int si_signo;
+	int si_errno;
+	int si_code;
+	char _sifields[4];
+};
+
+#undef sa_handler
+#undef sa_flags
+#undef sa_restorer
+#undef sa_mask
+
+struct xsigaction {
+	void (*sa_handler)(void);
+	unsigned long sa_flags;
+	void (*sa_restorer)(void);
+	unsigned int sa_mask;		// mask last for extensibility
+};
+*/
+import "C"
+
+const (
+	PROT_NONE  = C.PROT_NONE
+	PROT_READ  = C.PROT_READ
+	PROT_WRITE = C.PROT_WRITE
+	PROT_EXEC  = C.PROT_EXEC
+
+	MAP_ANON    = C.MAP_ANONYMOUS
+	MAP_PRIVATE = C.MAP_PRIVATE
+	MAP_FIXED   = C.MAP_FIXED
+
+	MADV_DONTNEED = C.MADV_DONTNEED
+
+	SA_RESTART  = C.SA_RESTART
+	SA_ONSTACK  = C.SA_ONSTACK
+	SA_RESTORER = C.SA_RESTORER
+	SA_SIGINFO  = C.SA_SIGINFO
+
+	SIGHUP    = C.SIGHUP
+	SIGINT    = C.SIGINT
+	SIGQUIT   = C.SIGQUIT
+	SIGILL    = C.SIGILL
+	SIGTRAP   = C.SIGTRAP
+	SIGABRT   = C.SIGABRT
+	SIGBUS    = C.SIGBUS
+	SIGFPE    = C.SIGFPE
+	SIGKILL   = C.SIGKILL
+	SIGUSR1   = C.SIGUSR1
+	SIGSEGV   = C.SIGSEGV
+	SIGUSR2   = C.SIGUSR2
+	SIGPIPE   = C.SIGPIPE
+	SIGALRM   = C.SIGALRM
+	SIGSTKFLT = C.SIGSTKFLT
+	SIGCHLD   = C.SIGCHLD
+	SIGCONT   = C.SIGCONT
+	SIGSTOP   = C.SIGSTOP
+	SIGTSTP   = C.SIGTSTP
+	SIGTTIN   = C.SIGTTIN
+	SIGTTOU   = C.SIGTTOU
+	SIGURG    = C.SIGURG
+	SIGXCPU   = C.SIGXCPU
+	SIGXFSZ   = C.SIGXFSZ
+	SIGVTALRM = C.SIGVTALRM
+	SIGPROF   = C.SIGPROF
+	SIGWINCH  = C.SIGWINCH
+	SIGIO     = C.SIGIO
+	SIGPWR    = C.SIGPWR
+	SIGSYS    = C.SIGSYS
+
+	FPE_INTDIV = C.FPE_INTDIV & 0xFFFF
+	FPE_INTOVF = C.FPE_INTOVF & 0xFFFF
+	FPE_FLTDIV = C.FPE_FLTDIV & 0xFFFF
+	FPE_FLTOVF = C.FPE_FLTOVF & 0xFFFF
+	FPE_FLTUND = C.FPE_FLTUND & 0xFFFF
+	FPE_FLTRES = C.FPE_FLTRES & 0xFFFF
+	FPE_FLTINV = C.FPE_FLTINV & 0xFFFF
+	FPE_FLTSUB = C.FPE_FLTSUB & 0xFFFF
+
+	BUS_ADRALN = C.BUS_ADRALN & 0xFFFF
+	BUS_ADRERR = C.BUS_ADRERR & 0xFFFF
+	BUS_OBJERR = C.BUS_OBJERR & 0xFFFF
+
+	SEGV_MAPERR = C.SEGV_MAPERR & 0xFFFF
+	SEGV_ACCERR = C.SEGV_ACCERR & 0xFFFF
+
+	ITIMER_REAL    = C.ITIMER_REAL
+	ITIMER_PROF    = C.ITIMER_PROF
+	ITIMER_VIRTUAL = C.ITIMER_VIRTUAL
+)
+
+type Timespec C.struct_timespec
+type SigaltstackT C.struct_sigaltstack
+type Sigcontext C.struct_sigcontext
+type Ucontext C.struct_ucontext
+type Timeval C.struct_timeval
+type Itimerval C.struct_itimerval
+type Siginfo C.struct_xsiginfo
+type Sigaction C.struct_xsigaction
diff --git a/src/pkg/runtime/defs_darwin.go b/src/runtime/defs_darwin.go
similarity index 100%
rename from src/pkg/runtime/defs_darwin.go
rename to src/runtime/defs_darwin.go
diff --git a/src/runtime/defs_darwin_386.h b/src/runtime/defs_darwin_386.h
new file mode 100644
index 0000000..0e0b4fb
--- /dev/null
+++ b/src/runtime/defs_darwin_386.h
@@ -0,0 +1,392 @@
+// Created by cgo -cdefs - DO NOT EDIT
+// cgo -cdefs defs_darwin.go
+
+
+enum {
+	EINTR	= 0x4,
+	EFAULT	= 0xe,
+
+	PROT_NONE	= 0x0,
+	PROT_READ	= 0x1,
+	PROT_WRITE	= 0x2,
+	PROT_EXEC	= 0x4,
+
+	MAP_ANON	= 0x1000,
+	MAP_PRIVATE	= 0x2,
+	MAP_FIXED	= 0x10,
+
+	MADV_DONTNEED	= 0x4,
+	MADV_FREE	= 0x5,
+
+	MACH_MSG_TYPE_MOVE_RECEIVE	= 0x10,
+	MACH_MSG_TYPE_MOVE_SEND		= 0x11,
+	MACH_MSG_TYPE_MOVE_SEND_ONCE	= 0x12,
+	MACH_MSG_TYPE_COPY_SEND		= 0x13,
+	MACH_MSG_TYPE_MAKE_SEND		= 0x14,
+	MACH_MSG_TYPE_MAKE_SEND_ONCE	= 0x15,
+	MACH_MSG_TYPE_COPY_RECEIVE	= 0x16,
+
+	MACH_MSG_PORT_DESCRIPTOR		= 0x0,
+	MACH_MSG_OOL_DESCRIPTOR			= 0x1,
+	MACH_MSG_OOL_PORTS_DESCRIPTOR		= 0x2,
+	MACH_MSG_OOL_VOLATILE_DESCRIPTOR	= 0x3,
+
+	MACH_MSGH_BITS_COMPLEX	= 0x80000000,
+
+	MACH_SEND_MSG	= 0x1,
+	MACH_RCV_MSG	= 0x2,
+	MACH_RCV_LARGE	= 0x4,
+
+	MACH_SEND_TIMEOUT	= 0x10,
+	MACH_SEND_INTERRUPT	= 0x40,
+	MACH_SEND_ALWAYS	= 0x10000,
+	MACH_SEND_TRAILER	= 0x20000,
+	MACH_RCV_TIMEOUT	= 0x100,
+	MACH_RCV_NOTIFY		= 0x200,
+	MACH_RCV_INTERRUPT	= 0x400,
+	MACH_RCV_OVERWRITE	= 0x1000,
+
+	NDR_PROTOCOL_2_0	= 0x0,
+	NDR_INT_BIG_ENDIAN	= 0x0,
+	NDR_INT_LITTLE_ENDIAN	= 0x1,
+	NDR_FLOAT_IEEE		= 0x0,
+	NDR_CHAR_ASCII		= 0x0,
+
+	SA_SIGINFO	= 0x40,
+	SA_RESTART	= 0x2,
+	SA_ONSTACK	= 0x1,
+	SA_USERTRAMP	= 0x100,
+	SA_64REGSET	= 0x200,
+
+	SIGHUP		= 0x1,
+	SIGINT		= 0x2,
+	SIGQUIT		= 0x3,
+	SIGILL		= 0x4,
+	SIGTRAP		= 0x5,
+	SIGABRT		= 0x6,
+	SIGEMT		= 0x7,
+	SIGFPE		= 0x8,
+	SIGKILL		= 0x9,
+	SIGBUS		= 0xa,
+	SIGSEGV		= 0xb,
+	SIGSYS		= 0xc,
+	SIGPIPE		= 0xd,
+	SIGALRM		= 0xe,
+	SIGTERM		= 0xf,
+	SIGURG		= 0x10,
+	SIGSTOP		= 0x11,
+	SIGTSTP		= 0x12,
+	SIGCONT		= 0x13,
+	SIGCHLD		= 0x14,
+	SIGTTIN		= 0x15,
+	SIGTTOU		= 0x16,
+	SIGIO		= 0x17,
+	SIGXCPU		= 0x18,
+	SIGXFSZ		= 0x19,
+	SIGVTALRM	= 0x1a,
+	SIGPROF		= 0x1b,
+	SIGWINCH	= 0x1c,
+	SIGINFO		= 0x1d,
+	SIGUSR1		= 0x1e,
+	SIGUSR2		= 0x1f,
+
+	FPE_INTDIV	= 0x7,
+	FPE_INTOVF	= 0x8,
+	FPE_FLTDIV	= 0x1,
+	FPE_FLTOVF	= 0x2,
+	FPE_FLTUND	= 0x3,
+	FPE_FLTRES	= 0x4,
+	FPE_FLTINV	= 0x5,
+	FPE_FLTSUB	= 0x6,
+
+	BUS_ADRALN	= 0x1,
+	BUS_ADRERR	= 0x2,
+	BUS_OBJERR	= 0x3,
+
+	SEGV_MAPERR	= 0x1,
+	SEGV_ACCERR	= 0x2,
+
+	ITIMER_REAL	= 0x0,
+	ITIMER_VIRTUAL	= 0x1,
+	ITIMER_PROF	= 0x2,
+
+	EV_ADD		= 0x1,
+	EV_DELETE	= 0x2,
+	EV_CLEAR	= 0x20,
+	EV_RECEIPT	= 0x40,
+	EV_ERROR	= 0x4000,
+	EVFILT_READ	= -0x1,
+	EVFILT_WRITE	= -0x2,
+};
+
+typedef struct MachBody MachBody;
+typedef struct MachHeader MachHeader;
+typedef struct MachNDR MachNDR;
+typedef struct MachPort MachPort;
+typedef struct StackT StackT;
+typedef struct SigactionT SigactionT;
+typedef struct Siginfo Siginfo;
+typedef struct Timeval Timeval;
+typedef struct Itimerval Itimerval;
+typedef struct Timespec Timespec;
+typedef struct FPControl FPControl;
+typedef struct FPStatus FPStatus;
+typedef struct RegMMST RegMMST;
+typedef struct RegXMM RegXMM;
+typedef struct Regs64 Regs64;
+typedef struct FloatState64 FloatState64;
+typedef struct ExceptionState64 ExceptionState64;
+typedef struct Mcontext64 Mcontext64;
+typedef struct Regs32 Regs32;
+typedef struct FloatState32 FloatState32;
+typedef struct ExceptionState32 ExceptionState32;
+typedef struct Mcontext32 Mcontext32;
+typedef struct Ucontext Ucontext;
+typedef struct KeventT KeventT;
+
+#pragma pack on
+
+struct MachBody {
+	uint32	msgh_descriptor_count;
+};
+struct MachHeader {
+	uint32	msgh_bits;
+	uint32	msgh_size;
+	uint32	msgh_remote_port;
+	uint32	msgh_local_port;
+	uint32	msgh_reserved;
+	int32	msgh_id;
+};
+struct MachNDR {
+	uint8	mig_vers;
+	uint8	if_vers;
+	uint8	reserved1;
+	uint8	mig_encoding;
+	uint8	int_rep;
+	uint8	char_rep;
+	uint8	float_rep;
+	uint8	reserved2;
+};
+struct MachPort {
+	uint32	name;
+	uint32	pad1;
+	uint16	pad2;
+	uint8	disposition;
+	uint8	type;
+};
+
+struct StackT {
+	byte	*ss_sp;
+	uint32	ss_size;
+	int32	ss_flags;
+};
+typedef	byte	Sighandler[4];
+
+struct SigactionT {
+	byte	__sigaction_u[4];
+	void	*sa_tramp;
+	uint32	sa_mask;
+	int32	sa_flags;
+};
+
+typedef	byte	Sigval[4];
+struct Siginfo {
+	int32	si_signo;
+	int32	si_errno;
+	int32	si_code;
+	int32	si_pid;
+	uint32	si_uid;
+	int32	si_status;
+	byte	*si_addr;
+	byte	si_value[4];
+	int32	si_band;
+	uint32	__pad[7];
+};
+struct Timeval {
+	int32	tv_sec;
+	int32	tv_usec;
+};
+struct Itimerval {
+	Timeval	it_interval;
+	Timeval	it_value;
+};
+struct Timespec {
+	int32	tv_sec;
+	int32	tv_nsec;
+};
+
+struct FPControl {
+	byte	Pad_cgo_0[2];
+};
+struct FPStatus {
+	byte	Pad_cgo_0[2];
+};
+struct RegMMST {
+	int8	mmst_reg[10];
+	int8	mmst_rsrv[6];
+};
+struct RegXMM {
+	int8	xmm_reg[16];
+};
+
+struct Regs64 {
+	uint64	rax;
+	uint64	rbx;
+	uint64	rcx;
+	uint64	rdx;
+	uint64	rdi;
+	uint64	rsi;
+	uint64	rbp;
+	uint64	rsp;
+	uint64	r8;
+	uint64	r9;
+	uint64	r10;
+	uint64	r11;
+	uint64	r12;
+	uint64	r13;
+	uint64	r14;
+	uint64	r15;
+	uint64	rip;
+	uint64	rflags;
+	uint64	cs;
+	uint64	fs;
+	uint64	gs;
+};
+struct FloatState64 {
+	int32	fpu_reserved[2];
+	FPControl	fpu_fcw;
+	FPStatus	fpu_fsw;
+	uint8	fpu_ftw;
+	uint8	fpu_rsrv1;
+	uint16	fpu_fop;
+	uint32	fpu_ip;
+	uint16	fpu_cs;
+	uint16	fpu_rsrv2;
+	uint32	fpu_dp;
+	uint16	fpu_ds;
+	uint16	fpu_rsrv3;
+	uint32	fpu_mxcsr;
+	uint32	fpu_mxcsrmask;
+	RegMMST	fpu_stmm0;
+	RegMMST	fpu_stmm1;
+	RegMMST	fpu_stmm2;
+	RegMMST	fpu_stmm3;
+	RegMMST	fpu_stmm4;
+	RegMMST	fpu_stmm5;
+	RegMMST	fpu_stmm6;
+	RegMMST	fpu_stmm7;
+	RegXMM	fpu_xmm0;
+	RegXMM	fpu_xmm1;
+	RegXMM	fpu_xmm2;
+	RegXMM	fpu_xmm3;
+	RegXMM	fpu_xmm4;
+	RegXMM	fpu_xmm5;
+	RegXMM	fpu_xmm6;
+	RegXMM	fpu_xmm7;
+	RegXMM	fpu_xmm8;
+	RegXMM	fpu_xmm9;
+	RegXMM	fpu_xmm10;
+	RegXMM	fpu_xmm11;
+	RegXMM	fpu_xmm12;
+	RegXMM	fpu_xmm13;
+	RegXMM	fpu_xmm14;
+	RegXMM	fpu_xmm15;
+	int8	fpu_rsrv4[96];
+	int32	fpu_reserved1;
+};
+struct ExceptionState64 {
+	uint16	trapno;
+	uint16	cpu;
+	uint32	err;
+	uint64	faultvaddr;
+};
+struct Mcontext64 {
+	ExceptionState64	es;
+	Regs64	ss;
+	FloatState64	fs;
+};
+
+struct Regs32 {
+	uint32	eax;
+	uint32	ebx;
+	uint32	ecx;
+	uint32	edx;
+	uint32	edi;
+	uint32	esi;
+	uint32	ebp;
+	uint32	esp;
+	uint32	ss;
+	uint32	eflags;
+	uint32	eip;
+	uint32	cs;
+	uint32	ds;
+	uint32	es;
+	uint32	fs;
+	uint32	gs;
+};
+struct FloatState32 {
+	int32	fpu_reserved[2];
+	FPControl	fpu_fcw;
+	FPStatus	fpu_fsw;
+	uint8	fpu_ftw;
+	uint8	fpu_rsrv1;
+	uint16	fpu_fop;
+	uint32	fpu_ip;
+	uint16	fpu_cs;
+	uint16	fpu_rsrv2;
+	uint32	fpu_dp;
+	uint16	fpu_ds;
+	uint16	fpu_rsrv3;
+	uint32	fpu_mxcsr;
+	uint32	fpu_mxcsrmask;
+	RegMMST	fpu_stmm0;
+	RegMMST	fpu_stmm1;
+	RegMMST	fpu_stmm2;
+	RegMMST	fpu_stmm3;
+	RegMMST	fpu_stmm4;
+	RegMMST	fpu_stmm5;
+	RegMMST	fpu_stmm6;
+	RegMMST	fpu_stmm7;
+	RegXMM	fpu_xmm0;
+	RegXMM	fpu_xmm1;
+	RegXMM	fpu_xmm2;
+	RegXMM	fpu_xmm3;
+	RegXMM	fpu_xmm4;
+	RegXMM	fpu_xmm5;
+	RegXMM	fpu_xmm6;
+	RegXMM	fpu_xmm7;
+	int8	fpu_rsrv4[224];
+	int32	fpu_reserved1;
+};
+struct ExceptionState32 {
+	uint16	trapno;
+	uint16	cpu;
+	uint32	err;
+	uint32	faultvaddr;
+};
+struct Mcontext32 {
+	ExceptionState32	es;
+	Regs32	ss;
+	FloatState32	fs;
+};
+
+struct Ucontext {
+	int32	uc_onstack;
+	uint32	uc_sigmask;
+	StackT	uc_stack;
+	Ucontext	*uc_link;
+	uint32	uc_mcsize;
+	Mcontext32	*uc_mcontext;
+};
+
+struct KeventT {
+	uint32	ident;
+	int16	filter;
+	uint16	flags;
+	uint32	fflags;
+	int32	data;
+	byte	*udata;
+};
+
+
+#pragma pack off
diff --git a/src/runtime/defs_darwin_amd64.h b/src/runtime/defs_darwin_amd64.h
new file mode 100644
index 0000000..4bf83c1
--- /dev/null
+++ b/src/runtime/defs_darwin_amd64.h
@@ -0,0 +1,395 @@
+// Created by cgo -cdefs - DO NOT EDIT
+// cgo -cdefs defs_darwin.go
+
+
+enum {
+	EINTR	= 0x4,
+	EFAULT	= 0xe,
+
+	PROT_NONE	= 0x0,
+	PROT_READ	= 0x1,
+	PROT_WRITE	= 0x2,
+	PROT_EXEC	= 0x4,
+
+	MAP_ANON	= 0x1000,
+	MAP_PRIVATE	= 0x2,
+	MAP_FIXED	= 0x10,
+
+	MADV_DONTNEED	= 0x4,
+	MADV_FREE	= 0x5,
+
+	MACH_MSG_TYPE_MOVE_RECEIVE	= 0x10,
+	MACH_MSG_TYPE_MOVE_SEND		= 0x11,
+	MACH_MSG_TYPE_MOVE_SEND_ONCE	= 0x12,
+	MACH_MSG_TYPE_COPY_SEND		= 0x13,
+	MACH_MSG_TYPE_MAKE_SEND		= 0x14,
+	MACH_MSG_TYPE_MAKE_SEND_ONCE	= 0x15,
+	MACH_MSG_TYPE_COPY_RECEIVE	= 0x16,
+
+	MACH_MSG_PORT_DESCRIPTOR		= 0x0,
+	MACH_MSG_OOL_DESCRIPTOR			= 0x1,
+	MACH_MSG_OOL_PORTS_DESCRIPTOR		= 0x2,
+	MACH_MSG_OOL_VOLATILE_DESCRIPTOR	= 0x3,
+
+	MACH_MSGH_BITS_COMPLEX	= 0x80000000,
+
+	MACH_SEND_MSG	= 0x1,
+	MACH_RCV_MSG	= 0x2,
+	MACH_RCV_LARGE	= 0x4,
+
+	MACH_SEND_TIMEOUT	= 0x10,
+	MACH_SEND_INTERRUPT	= 0x40,
+	MACH_SEND_ALWAYS	= 0x10000,
+	MACH_SEND_TRAILER	= 0x20000,
+	MACH_RCV_TIMEOUT	= 0x100,
+	MACH_RCV_NOTIFY		= 0x200,
+	MACH_RCV_INTERRUPT	= 0x400,
+	MACH_RCV_OVERWRITE	= 0x1000,
+
+	NDR_PROTOCOL_2_0	= 0x0,
+	NDR_INT_BIG_ENDIAN	= 0x0,
+	NDR_INT_LITTLE_ENDIAN	= 0x1,
+	NDR_FLOAT_IEEE		= 0x0,
+	NDR_CHAR_ASCII		= 0x0,
+
+	SA_SIGINFO	= 0x40,
+	SA_RESTART	= 0x2,
+	SA_ONSTACK	= 0x1,
+	SA_USERTRAMP	= 0x100,
+	SA_64REGSET	= 0x200,
+
+	SIGHUP		= 0x1,
+	SIGINT		= 0x2,
+	SIGQUIT		= 0x3,
+	SIGILL		= 0x4,
+	SIGTRAP		= 0x5,
+	SIGABRT		= 0x6,
+	SIGEMT		= 0x7,
+	SIGFPE		= 0x8,
+	SIGKILL		= 0x9,
+	SIGBUS		= 0xa,
+	SIGSEGV		= 0xb,
+	SIGSYS		= 0xc,
+	SIGPIPE		= 0xd,
+	SIGALRM		= 0xe,
+	SIGTERM		= 0xf,
+	SIGURG		= 0x10,
+	SIGSTOP		= 0x11,
+	SIGTSTP		= 0x12,
+	SIGCONT		= 0x13,
+	SIGCHLD		= 0x14,
+	SIGTTIN		= 0x15,
+	SIGTTOU		= 0x16,
+	SIGIO		= 0x17,
+	SIGXCPU		= 0x18,
+	SIGXFSZ		= 0x19,
+	SIGVTALRM	= 0x1a,
+	SIGPROF		= 0x1b,
+	SIGWINCH	= 0x1c,
+	SIGINFO		= 0x1d,
+	SIGUSR1		= 0x1e,
+	SIGUSR2		= 0x1f,
+
+	FPE_INTDIV	= 0x7,
+	FPE_INTOVF	= 0x8,
+	FPE_FLTDIV	= 0x1,
+	FPE_FLTOVF	= 0x2,
+	FPE_FLTUND	= 0x3,
+	FPE_FLTRES	= 0x4,
+	FPE_FLTINV	= 0x5,
+	FPE_FLTSUB	= 0x6,
+
+	BUS_ADRALN	= 0x1,
+	BUS_ADRERR	= 0x2,
+	BUS_OBJERR	= 0x3,
+
+	SEGV_MAPERR	= 0x1,
+	SEGV_ACCERR	= 0x2,
+
+	ITIMER_REAL	= 0x0,
+	ITIMER_VIRTUAL	= 0x1,
+	ITIMER_PROF	= 0x2,
+
+	EV_ADD		= 0x1,
+	EV_DELETE	= 0x2,
+	EV_CLEAR	= 0x20,
+	EV_RECEIPT	= 0x40,
+	EV_ERROR	= 0x4000,
+	EVFILT_READ	= -0x1,
+	EVFILT_WRITE	= -0x2,
+};
+
+typedef struct MachBody MachBody;
+typedef struct MachHeader MachHeader;
+typedef struct MachNDR MachNDR;
+typedef struct MachPort MachPort;
+typedef struct StackT StackT;
+typedef struct SigactionT SigactionT;
+typedef struct Siginfo Siginfo;
+typedef struct Timeval Timeval;
+typedef struct Itimerval Itimerval;
+typedef struct Timespec Timespec;
+typedef struct FPControl FPControl;
+typedef struct FPStatus FPStatus;
+typedef struct RegMMST RegMMST;
+typedef struct RegXMM RegXMM;
+typedef struct Regs64 Regs64;
+typedef struct FloatState64 FloatState64;
+typedef struct ExceptionState64 ExceptionState64;
+typedef struct Mcontext64 Mcontext64;
+typedef struct Regs32 Regs32;
+typedef struct FloatState32 FloatState32;
+typedef struct ExceptionState32 ExceptionState32;
+typedef struct Mcontext32 Mcontext32;
+typedef struct Ucontext Ucontext;
+typedef struct KeventT KeventT;
+
+#pragma pack on
+
+struct MachBody {
+	uint32	msgh_descriptor_count;
+};
+struct MachHeader {
+	uint32	msgh_bits;
+	uint32	msgh_size;
+	uint32	msgh_remote_port;
+	uint32	msgh_local_port;
+	uint32	msgh_reserved;
+	int32	msgh_id;
+};
+struct MachNDR {
+	uint8	mig_vers;
+	uint8	if_vers;
+	uint8	reserved1;
+	uint8	mig_encoding;
+	uint8	int_rep;
+	uint8	char_rep;
+	uint8	float_rep;
+	uint8	reserved2;
+};
+struct MachPort {
+	uint32	name;
+	uint32	pad1;
+	uint16	pad2;
+	uint8	disposition;
+	uint8	type;
+};
+
+struct StackT {
+	byte	*ss_sp;
+	uint64	ss_size;
+	int32	ss_flags;
+	byte	Pad_cgo_0[4];
+};
+typedef	byte	Sighandler[8];
+
+struct SigactionT {
+	byte	__sigaction_u[8];
+	void	*sa_tramp;
+	uint32	sa_mask;
+	int32	sa_flags;
+};
+
+typedef	byte	Sigval[8];
+struct Siginfo {
+	int32	si_signo;
+	int32	si_errno;
+	int32	si_code;
+	int32	si_pid;
+	uint32	si_uid;
+	int32	si_status;
+	byte	*si_addr;
+	byte	si_value[8];
+	int64	si_band;
+	uint64	__pad[7];
+};
+struct Timeval {
+	int64	tv_sec;
+	int32	tv_usec;
+	byte	Pad_cgo_0[4];
+};
+struct Itimerval {
+	Timeval	it_interval;
+	Timeval	it_value;
+};
+struct Timespec {
+	int64	tv_sec;
+	int64	tv_nsec;
+};
+
+struct FPControl {
+	byte	Pad_cgo_0[2];
+};
+struct FPStatus {
+	byte	Pad_cgo_0[2];
+};
+struct RegMMST {
+	int8	mmst_reg[10];
+	int8	mmst_rsrv[6];
+};
+struct RegXMM {
+	int8	xmm_reg[16];
+};
+
+struct Regs64 {
+	uint64	rax;
+	uint64	rbx;
+	uint64	rcx;
+	uint64	rdx;
+	uint64	rdi;
+	uint64	rsi;
+	uint64	rbp;
+	uint64	rsp;
+	uint64	r8;
+	uint64	r9;
+	uint64	r10;
+	uint64	r11;
+	uint64	r12;
+	uint64	r13;
+	uint64	r14;
+	uint64	r15;
+	uint64	rip;
+	uint64	rflags;
+	uint64	cs;
+	uint64	fs;
+	uint64	gs;
+};
+struct FloatState64 {
+	int32	fpu_reserved[2];
+	FPControl	fpu_fcw;
+	FPStatus	fpu_fsw;
+	uint8	fpu_ftw;
+	uint8	fpu_rsrv1;
+	uint16	fpu_fop;
+	uint32	fpu_ip;
+	uint16	fpu_cs;
+	uint16	fpu_rsrv2;
+	uint32	fpu_dp;
+	uint16	fpu_ds;
+	uint16	fpu_rsrv3;
+	uint32	fpu_mxcsr;
+	uint32	fpu_mxcsrmask;
+	RegMMST	fpu_stmm0;
+	RegMMST	fpu_stmm1;
+	RegMMST	fpu_stmm2;
+	RegMMST	fpu_stmm3;
+	RegMMST	fpu_stmm4;
+	RegMMST	fpu_stmm5;
+	RegMMST	fpu_stmm6;
+	RegMMST	fpu_stmm7;
+	RegXMM	fpu_xmm0;
+	RegXMM	fpu_xmm1;
+	RegXMM	fpu_xmm2;
+	RegXMM	fpu_xmm3;
+	RegXMM	fpu_xmm4;
+	RegXMM	fpu_xmm5;
+	RegXMM	fpu_xmm6;
+	RegXMM	fpu_xmm7;
+	RegXMM	fpu_xmm8;
+	RegXMM	fpu_xmm9;
+	RegXMM	fpu_xmm10;
+	RegXMM	fpu_xmm11;
+	RegXMM	fpu_xmm12;
+	RegXMM	fpu_xmm13;
+	RegXMM	fpu_xmm14;
+	RegXMM	fpu_xmm15;
+	int8	fpu_rsrv4[96];
+	int32	fpu_reserved1;
+};
+struct ExceptionState64 {
+	uint16	trapno;
+	uint16	cpu;
+	uint32	err;
+	uint64	faultvaddr;
+};
+struct Mcontext64 {
+	ExceptionState64	es;
+	Regs64	ss;
+	FloatState64	fs;
+	byte	Pad_cgo_0[4];
+};
+
+struct Regs32 {
+	uint32	eax;
+	uint32	ebx;
+	uint32	ecx;
+	uint32	edx;
+	uint32	edi;
+	uint32	esi;
+	uint32	ebp;
+	uint32	esp;
+	uint32	ss;
+	uint32	eflags;
+	uint32	eip;
+	uint32	cs;
+	uint32	ds;
+	uint32	es;
+	uint32	fs;
+	uint32	gs;
+};
+struct FloatState32 {
+	int32	fpu_reserved[2];
+	FPControl	fpu_fcw;
+	FPStatus	fpu_fsw;
+	uint8	fpu_ftw;
+	uint8	fpu_rsrv1;
+	uint16	fpu_fop;
+	uint32	fpu_ip;
+	uint16	fpu_cs;
+	uint16	fpu_rsrv2;
+	uint32	fpu_dp;
+	uint16	fpu_ds;
+	uint16	fpu_rsrv3;
+	uint32	fpu_mxcsr;
+	uint32	fpu_mxcsrmask;
+	RegMMST	fpu_stmm0;
+	RegMMST	fpu_stmm1;
+	RegMMST	fpu_stmm2;
+	RegMMST	fpu_stmm3;
+	RegMMST	fpu_stmm4;
+	RegMMST	fpu_stmm5;
+	RegMMST	fpu_stmm6;
+	RegMMST	fpu_stmm7;
+	RegXMM	fpu_xmm0;
+	RegXMM	fpu_xmm1;
+	RegXMM	fpu_xmm2;
+	RegXMM	fpu_xmm3;
+	RegXMM	fpu_xmm4;
+	RegXMM	fpu_xmm5;
+	RegXMM	fpu_xmm6;
+	RegXMM	fpu_xmm7;
+	int8	fpu_rsrv4[224];
+	int32	fpu_reserved1;
+};
+struct ExceptionState32 {
+	uint16	trapno;
+	uint16	cpu;
+	uint32	err;
+	uint32	faultvaddr;
+};
+struct Mcontext32 {
+	ExceptionState32	es;
+	Regs32	ss;
+	FloatState32	fs;
+};
+
+struct Ucontext {
+	int32	uc_onstack;
+	uint32	uc_sigmask;
+	StackT	uc_stack;
+	Ucontext	*uc_link;
+	uint64	uc_mcsize;
+	Mcontext64	*uc_mcontext;
+};
+
+struct KeventT {
+	uint64	ident;
+	int16	filter;
+	uint16	flags;
+	uint32	fflags;
+	int64	data;
+	byte	*udata;
+};
+
+
+#pragma pack off
diff --git a/src/runtime/defs_dragonfly.go b/src/runtime/defs_dragonfly.go
new file mode 100644
index 0000000..555b8f5
--- /dev/null
+++ b/src/runtime/defs_dragonfly.go
@@ -0,0 +1,126 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build ignore
+
+/*
+Input to cgo.
+
+GOARCH=amd64 go tool cgo -cdefs defs_dragonfly.go >defs_dragonfly_amd64.h
+GOARCH=386 go tool cgo -cdefs defs_dragonfly.go >defs_dragonfly_386.h
+*/
+
+package runtime
+
+/*
+#include <sys/user.h>
+#include <sys/time.h>
+#include <sys/event.h>
+#include <sys/mman.h>
+#include <sys/ucontext.h>
+#include <sys/rtprio.h>
+#include <sys/signal.h>
+#include <sys/unistd.h>
+#include <errno.h>
+#include <signal.h>
+*/
+import "C"
+
+const (
+	EINTR  = C.EINTR
+	EFAULT = C.EFAULT
+	EBUSY  = C.EBUSY
+	EAGAIN = C.EAGAIN
+
+	PROT_NONE  = C.PROT_NONE
+	PROT_READ  = C.PROT_READ
+	PROT_WRITE = C.PROT_WRITE
+	PROT_EXEC  = C.PROT_EXEC
+
+	MAP_ANON    = C.MAP_ANON
+	MAP_PRIVATE = C.MAP_PRIVATE
+	MAP_FIXED   = C.MAP_FIXED
+
+	MADV_FREE = C.MADV_FREE
+
+	SA_SIGINFO = C.SA_SIGINFO
+	SA_RESTART = C.SA_RESTART
+	SA_ONSTACK = C.SA_ONSTACK
+
+	SIGHUP    = C.SIGHUP
+	SIGINT    = C.SIGINT
+	SIGQUIT   = C.SIGQUIT
+	SIGILL    = C.SIGILL
+	SIGTRAP   = C.SIGTRAP
+	SIGABRT   = C.SIGABRT
+	SIGEMT    = C.SIGEMT
+	SIGFPE    = C.SIGFPE
+	SIGKILL   = C.SIGKILL
+	SIGBUS    = C.SIGBUS
+	SIGSEGV   = C.SIGSEGV
+	SIGSYS    = C.SIGSYS
+	SIGPIPE   = C.SIGPIPE
+	SIGALRM   = C.SIGALRM
+	SIGTERM   = C.SIGTERM
+	SIGURG    = C.SIGURG
+	SIGSTOP   = C.SIGSTOP
+	SIGTSTP   = C.SIGTSTP
+	SIGCONT   = C.SIGCONT
+	SIGCHLD   = C.SIGCHLD
+	SIGTTIN   = C.SIGTTIN
+	SIGTTOU   = C.SIGTTOU
+	SIGIO     = C.SIGIO
+	SIGXCPU   = C.SIGXCPU
+	SIGXFSZ   = C.SIGXFSZ
+	SIGVTALRM = C.SIGVTALRM
+	SIGPROF   = C.SIGPROF
+	SIGWINCH  = C.SIGWINCH
+	SIGINFO   = C.SIGINFO
+	SIGUSR1   = C.SIGUSR1
+	SIGUSR2   = C.SIGUSR2
+
+	FPE_INTDIV = C.FPE_INTDIV
+	FPE_INTOVF = C.FPE_INTOVF
+	FPE_FLTDIV = C.FPE_FLTDIV
+	FPE_FLTOVF = C.FPE_FLTOVF
+	FPE_FLTUND = C.FPE_FLTUND
+	FPE_FLTRES = C.FPE_FLTRES
+	FPE_FLTINV = C.FPE_FLTINV
+	FPE_FLTSUB = C.FPE_FLTSUB
+
+	BUS_ADRALN = C.BUS_ADRALN
+	BUS_ADRERR = C.BUS_ADRERR
+	BUS_OBJERR = C.BUS_OBJERR
+
+	SEGV_MAPERR = C.SEGV_MAPERR
+	SEGV_ACCERR = C.SEGV_ACCERR
+
+	ITIMER_REAL    = C.ITIMER_REAL
+	ITIMER_VIRTUAL = C.ITIMER_VIRTUAL
+	ITIMER_PROF    = C.ITIMER_PROF
+
+	EV_ADD       = C.EV_ADD
+	EV_DELETE    = C.EV_DELETE
+	EV_CLEAR     = C.EV_CLEAR
+	EV_ERROR     = C.EV_ERROR
+	EVFILT_READ  = C.EVFILT_READ
+	EVFILT_WRITE = C.EVFILT_WRITE
+)
+
+type Rtprio C.struct_rtprio
+type Lwpparams C.struct_lwp_params
+type SigaltstackT C.struct_sigaltstack
+type Sigset C.struct___sigset
+type StackT C.stack_t
+
+type Siginfo C.siginfo_t
+
+type Mcontext C.mcontext_t
+type Ucontext C.ucontext_t
+
+type Timespec C.struct_timespec
+type Timeval C.struct_timeval
+type Itimerval C.struct_itimerval
+
+type Kevent C.struct_kevent
diff --git a/src/runtime/defs_dragonfly_386.h b/src/runtime/defs_dragonfly_386.h
new file mode 100644
index 0000000..f86b9c6
--- /dev/null
+++ b/src/runtime/defs_dragonfly_386.h
@@ -0,0 +1,198 @@
+// Created by cgo -cdefs - DO NOT EDIT
+// cgo -cdefs defs_dragonfly.go
+
+
+enum {
+	EINTR	= 0x4,
+	EFAULT	= 0xe,
+	EBUSY	= 0x10,
+	EAGAIN	= 0x23,
+
+	PROT_NONE	= 0x0,
+	PROT_READ	= 0x1,
+	PROT_WRITE	= 0x2,
+	PROT_EXEC	= 0x4,
+
+	MAP_ANON	= 0x1000,
+	MAP_PRIVATE	= 0x2,
+	MAP_FIXED	= 0x10,
+
+	MADV_FREE	= 0x5,
+
+	SA_SIGINFO	= 0x40,
+	SA_RESTART	= 0x2,
+	SA_ONSTACK	= 0x1,
+
+	SIGHUP		= 0x1,
+	SIGINT		= 0x2,
+	SIGQUIT		= 0x3,
+	SIGILL		= 0x4,
+	SIGTRAP		= 0x5,
+	SIGABRT		= 0x6,
+	SIGEMT		= 0x7,
+	SIGFPE		= 0x8,
+	SIGKILL		= 0x9,
+	SIGBUS		= 0xa,
+	SIGSEGV		= 0xb,
+	SIGSYS		= 0xc,
+	SIGPIPE		= 0xd,
+	SIGALRM		= 0xe,
+	SIGTERM		= 0xf,
+	SIGURG		= 0x10,
+	SIGSTOP		= 0x11,
+	SIGTSTP		= 0x12,
+	SIGCONT		= 0x13,
+	SIGCHLD		= 0x14,
+	SIGTTIN		= 0x15,
+	SIGTTOU		= 0x16,
+	SIGIO		= 0x17,
+	SIGXCPU		= 0x18,
+	SIGXFSZ		= 0x19,
+	SIGVTALRM	= 0x1a,
+	SIGPROF		= 0x1b,
+	SIGWINCH	= 0x1c,
+	SIGINFO		= 0x1d,
+	SIGUSR1		= 0x1e,
+	SIGUSR2		= 0x1f,
+
+	FPE_INTDIV	= 0x2,
+	FPE_INTOVF	= 0x1,
+	FPE_FLTDIV	= 0x3,
+	FPE_FLTOVF	= 0x4,
+	FPE_FLTUND	= 0x5,
+	FPE_FLTRES	= 0x6,
+	FPE_FLTINV	= 0x7,
+	FPE_FLTSUB	= 0x8,
+
+	BUS_ADRALN	= 0x1,
+	BUS_ADRERR	= 0x2,
+	BUS_OBJERR	= 0x3,
+
+	SEGV_MAPERR	= 0x1,
+	SEGV_ACCERR	= 0x2,
+
+	ITIMER_REAL	= 0x0,
+	ITIMER_VIRTUAL	= 0x1,
+	ITIMER_PROF	= 0x2,
+
+	EV_ADD		= 0x1,
+	EV_DELETE	= 0x2,
+	EV_CLEAR	= 0x20,
+	EV_ERROR	= 0x4000,
+	EVFILT_READ	= -0x1,
+	EVFILT_WRITE	= -0x2,
+};
+
+typedef struct Rtprio Rtprio;
+typedef struct Lwpparams Lwpparams;
+typedef struct SigaltstackT SigaltstackT;
+typedef struct Sigset Sigset;
+typedef struct StackT StackT;
+typedef struct Siginfo Siginfo;
+typedef struct Mcontext Mcontext;
+typedef struct Ucontext Ucontext;
+typedef struct Timespec Timespec;
+typedef struct Timeval Timeval;
+typedef struct Itimerval Itimerval;
+typedef struct KeventT KeventT;
+
+#pragma pack on
+
+struct Rtprio {
+	uint16	type;
+	uint16	prio;
+};
+struct Lwpparams {
+	void	*func;
+	byte	*arg;
+	byte	*stack;
+	int32	*tid1;
+	int32	*tid2;
+};
+struct SigaltstackT {
+	int8	*ss_sp;
+	uint32	ss_size;
+	int32	ss_flags;
+};
+struct Sigset {
+	uint32	__bits[4];
+};
+struct StackT {
+	int8	*ss_sp;
+	uint32	ss_size;
+	int32	ss_flags;
+};
+
+struct Siginfo {
+	int32	si_signo;
+	int32	si_errno;
+	int32	si_code;
+	int32	si_pid;
+	uint32	si_uid;
+	int32	si_status;
+	byte	*si_addr;
+	byte	si_value[4];
+	int32	si_band;
+	int32	__spare__[7];
+};
+
+struct Mcontext {
+	int32	mc_onstack;
+	int32	mc_gs;
+	int32	mc_fs;
+	int32	mc_es;
+	int32	mc_ds;
+	int32	mc_edi;
+	int32	mc_esi;
+	int32	mc_ebp;
+	int32	mc_isp;
+	int32	mc_ebx;
+	int32	mc_edx;
+	int32	mc_ecx;
+	int32	mc_eax;
+	int32	mc_xflags;
+	int32	mc_trapno;
+	int32	mc_err;
+	int32	mc_eip;
+	int32	mc_cs;
+	int32	mc_eflags;
+	int32	mc_esp;
+	int32	mc_ss;
+	int32	mc_len;
+	int32	mc_fpformat;
+	int32	mc_ownedfp;
+	int32	mc_fpregs[128];
+	int32	__spare__[16];
+};
+struct Ucontext {
+	Sigset	uc_sigmask;
+	Mcontext	uc_mcontext;
+	Ucontext	*uc_link;
+	StackT	uc_stack;
+	int32	__spare__[8];
+};
+
+struct Timespec {
+	int32	tv_sec;
+	int32	tv_nsec;
+};
+struct Timeval {
+	int32	tv_sec;
+	int32	tv_usec;
+};
+struct Itimerval {
+	Timeval	it_interval;
+	Timeval	it_value;
+};
+
+struct KeventT {
+	uint32	ident;
+	int16	filter;
+	uint16	flags;
+	uint32	fflags;
+	int32	data;
+	byte	*udata;
+};
+
+
+#pragma pack off
diff --git a/src/runtime/defs_dragonfly_amd64.h b/src/runtime/defs_dragonfly_amd64.h
new file mode 100644
index 0000000..6715552
--- /dev/null
+++ b/src/runtime/defs_dragonfly_amd64.h
@@ -0,0 +1,208 @@
+// Created by cgo -cdefs - DO NOT EDIT
+// cgo -cdefs defs_dragonfly.go
+
+
+enum {
+	EINTR	= 0x4,
+	EFAULT	= 0xe,
+	EBUSY	= 0x10,
+	EAGAIN	= 0x23,
+
+	PROT_NONE	= 0x0,
+	PROT_READ	= 0x1,
+	PROT_WRITE	= 0x2,
+	PROT_EXEC	= 0x4,
+
+	MAP_ANON	= 0x1000,
+	MAP_PRIVATE	= 0x2,
+	MAP_FIXED	= 0x10,
+
+	MADV_FREE	= 0x5,
+
+	SA_SIGINFO	= 0x40,
+	SA_RESTART	= 0x2,
+	SA_ONSTACK	= 0x1,
+
+	SIGHUP		= 0x1,
+	SIGINT		= 0x2,
+	SIGQUIT		= 0x3,
+	SIGILL		= 0x4,
+	SIGTRAP		= 0x5,
+	SIGABRT		= 0x6,
+	SIGEMT		= 0x7,
+	SIGFPE		= 0x8,
+	SIGKILL		= 0x9,
+	SIGBUS		= 0xa,
+	SIGSEGV		= 0xb,
+	SIGSYS		= 0xc,
+	SIGPIPE		= 0xd,
+	SIGALRM		= 0xe,
+	SIGTERM		= 0xf,
+	SIGURG		= 0x10,
+	SIGSTOP		= 0x11,
+	SIGTSTP		= 0x12,
+	SIGCONT		= 0x13,
+	SIGCHLD		= 0x14,
+	SIGTTIN		= 0x15,
+	SIGTTOU		= 0x16,
+	SIGIO		= 0x17,
+	SIGXCPU		= 0x18,
+	SIGXFSZ		= 0x19,
+	SIGVTALRM	= 0x1a,
+	SIGPROF		= 0x1b,
+	SIGWINCH	= 0x1c,
+	SIGINFO		= 0x1d,
+	SIGUSR1		= 0x1e,
+	SIGUSR2		= 0x1f,
+
+	FPE_INTDIV	= 0x2,
+	FPE_INTOVF	= 0x1,
+	FPE_FLTDIV	= 0x3,
+	FPE_FLTOVF	= 0x4,
+	FPE_FLTUND	= 0x5,
+	FPE_FLTRES	= 0x6,
+	FPE_FLTINV	= 0x7,
+	FPE_FLTSUB	= 0x8,
+
+	BUS_ADRALN	= 0x1,
+	BUS_ADRERR	= 0x2,
+	BUS_OBJERR	= 0x3,
+
+	SEGV_MAPERR	= 0x1,
+	SEGV_ACCERR	= 0x2,
+
+	ITIMER_REAL	= 0x0,
+	ITIMER_VIRTUAL	= 0x1,
+	ITIMER_PROF	= 0x2,
+
+	EV_ADD		= 0x1,
+	EV_DELETE	= 0x2,
+	EV_CLEAR	= 0x20,
+	EV_ERROR	= 0x4000,
+	EVFILT_READ	= -0x1,
+	EVFILT_WRITE	= -0x2,
+};
+
+typedef struct Rtprio Rtprio;
+typedef struct Lwpparams Lwpparams;
+typedef struct SigaltstackT SigaltstackT;
+typedef struct Sigset Sigset;
+typedef struct StackT StackT;
+typedef struct Siginfo Siginfo;
+typedef struct Mcontext Mcontext;
+typedef struct Ucontext Ucontext;
+typedef struct Timespec Timespec;
+typedef struct Timeval Timeval;
+typedef struct Itimerval Itimerval;
+typedef struct KeventT KeventT;
+
+#pragma pack on
+
+struct Rtprio {
+	uint16	type;
+	uint16	prio;
+};
+struct Lwpparams {
+	void	*func;
+	byte	*arg;
+	byte	*stack;
+	int32	*tid1;
+	int32	*tid2;
+};
+struct SigaltstackT {
+	int8	*ss_sp;
+	uint64	ss_size;
+	int32	ss_flags;
+	byte	Pad_cgo_0[4];
+};
+struct Sigset {
+	uint32	__bits[4];
+};
+struct StackT {
+	int8	*ss_sp;
+	uint64	ss_size;
+	int32	ss_flags;
+	byte	Pad_cgo_0[4];
+};
+
+struct Siginfo {
+	int32	si_signo;
+	int32	si_errno;
+	int32	si_code;
+	int32	si_pid;
+	uint32	si_uid;
+	int32	si_status;
+	byte	*si_addr;
+	byte	si_value[8];
+	int64	si_band;
+	int32	__spare__[7];
+	byte	Pad_cgo_0[4];
+};
+
+struct Mcontext {
+	int64	mc_onstack;
+	int64	mc_rdi;
+	int64	mc_rsi;
+	int64	mc_rdx;
+	int64	mc_rcx;
+	int64	mc_r8;
+	int64	mc_r9;
+	int64	mc_rax;
+	int64	mc_rbx;
+	int64	mc_rbp;
+	int64	mc_r10;
+	int64	mc_r11;
+	int64	mc_r12;
+	int64	mc_r13;
+	int64	mc_r14;
+	int64	mc_r15;
+	int64	mc_xflags;
+	int64	mc_trapno;
+	int64	mc_addr;
+	int64	mc_flags;
+	int64	mc_err;
+	int64	mc_rip;
+	int64	mc_cs;
+	int64	mc_rflags;
+	int64	mc_rsp;
+	int64	mc_ss;
+	uint32	mc_len;
+	uint32	mc_fpformat;
+	uint32	mc_ownedfp;
+	uint32	mc_reserved;
+	uint32	mc_unused[8];
+	int32	mc_fpregs[256];
+};
+struct Ucontext {
+	Sigset	uc_sigmask;
+	byte	Pad_cgo_0[48];
+	Mcontext	uc_mcontext;
+	Ucontext	*uc_link;
+	StackT	uc_stack;
+	int32	__spare__[8];
+};
+
+struct Timespec {
+	int64	tv_sec;
+	int64	tv_nsec;
+};
+struct Timeval {
+	int64	tv_sec;
+	int64	tv_usec;
+};
+struct Itimerval {
+	Timeval	it_interval;
+	Timeval	it_value;
+};
+
+struct KeventT {
+	uint64	ident;
+	int16	filter;
+	uint16	flags;
+	uint32	fflags;
+	int64	data;
+	byte	*udata;
+};
+
+
+#pragma pack off
diff --git a/src/runtime/defs_freebsd.go b/src/runtime/defs_freebsd.go
new file mode 100644
index 0000000..0253685
--- /dev/null
+++ b/src/runtime/defs_freebsd.go
@@ -0,0 +1,133 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build ignore
+
+/*
+Input to cgo.
+
+GOARCH=amd64 go tool cgo -cdefs defs_freebsd.go >defs_freebsd_amd64.h
+GOARCH=386 go tool cgo -cdefs defs_freebsd.go >defs_freebsd_386.h
+GOARCH=arm go tool cgo -cdefs defs_freebsd.go >defs_freebsd_arm.h
+*/
+
+package runtime
+
+/*
+#include <sys/types.h>
+#include <sys/time.h>
+#include <signal.h>
+#include <errno.h>
+#include <sys/event.h>
+#include <sys/mman.h>
+#include <sys/ucontext.h>
+#include <sys/umtx.h>
+#include <sys/rtprio.h>
+#include <sys/thr.h>
+#include <sys/_sigset.h>
+#include <sys/unistd.h>
+*/
+import "C"
+
+const (
+	EINTR  = C.EINTR
+	EFAULT = C.EFAULT
+
+	PROT_NONE  = C.PROT_NONE
+	PROT_READ  = C.PROT_READ
+	PROT_WRITE = C.PROT_WRITE
+	PROT_EXEC  = C.PROT_EXEC
+
+	MAP_ANON    = C.MAP_ANON
+	MAP_PRIVATE = C.MAP_PRIVATE
+	MAP_FIXED   = C.MAP_FIXED
+
+	MADV_FREE = C.MADV_FREE
+
+	SA_SIGINFO = C.SA_SIGINFO
+	SA_RESTART = C.SA_RESTART
+	SA_ONSTACK = C.SA_ONSTACK
+
+	UMTX_OP_WAIT_UINT         = C.UMTX_OP_WAIT_UINT
+	UMTX_OP_WAIT_UINT_PRIVATE = C.UMTX_OP_WAIT_UINT_PRIVATE
+	UMTX_OP_WAKE              = C.UMTX_OP_WAKE
+	UMTX_OP_WAKE_PRIVATE      = C.UMTX_OP_WAKE_PRIVATE
+
+	SIGHUP    = C.SIGHUP
+	SIGINT    = C.SIGINT
+	SIGQUIT   = C.SIGQUIT
+	SIGILL    = C.SIGILL
+	SIGTRAP   = C.SIGTRAP
+	SIGABRT   = C.SIGABRT
+	SIGEMT    = C.SIGEMT
+	SIGFPE    = C.SIGFPE
+	SIGKILL   = C.SIGKILL
+	SIGBUS    = C.SIGBUS
+	SIGSEGV   = C.SIGSEGV
+	SIGSYS    = C.SIGSYS
+	SIGPIPE   = C.SIGPIPE
+	SIGALRM   = C.SIGALRM
+	SIGTERM   = C.SIGTERM
+	SIGURG    = C.SIGURG
+	SIGSTOP   = C.SIGSTOP
+	SIGTSTP   = C.SIGTSTP
+	SIGCONT   = C.SIGCONT
+	SIGCHLD   = C.SIGCHLD
+	SIGTTIN   = C.SIGTTIN
+	SIGTTOU   = C.SIGTTOU
+	SIGIO     = C.SIGIO
+	SIGXCPU   = C.SIGXCPU
+	SIGXFSZ   = C.SIGXFSZ
+	SIGVTALRM = C.SIGVTALRM
+	SIGPROF   = C.SIGPROF
+	SIGWINCH  = C.SIGWINCH
+	SIGINFO   = C.SIGINFO
+	SIGUSR1   = C.SIGUSR1
+	SIGUSR2   = C.SIGUSR2
+
+	FPE_INTDIV = C.FPE_INTDIV
+	FPE_INTOVF = C.FPE_INTOVF
+	FPE_FLTDIV = C.FPE_FLTDIV
+	FPE_FLTOVF = C.FPE_FLTOVF
+	FPE_FLTUND = C.FPE_FLTUND
+	FPE_FLTRES = C.FPE_FLTRES
+	FPE_FLTINV = C.FPE_FLTINV
+	FPE_FLTSUB = C.FPE_FLTSUB
+
+	BUS_ADRALN = C.BUS_ADRALN
+	BUS_ADRERR = C.BUS_ADRERR
+	BUS_OBJERR = C.BUS_OBJERR
+
+	SEGV_MAPERR = C.SEGV_MAPERR
+	SEGV_ACCERR = C.SEGV_ACCERR
+
+	ITIMER_REAL    = C.ITIMER_REAL
+	ITIMER_VIRTUAL = C.ITIMER_VIRTUAL
+	ITIMER_PROF    = C.ITIMER_PROF
+
+	EV_ADD       = C.EV_ADD
+	EV_DELETE    = C.EV_DELETE
+	EV_CLEAR     = C.EV_CLEAR
+	EV_RECEIPT   = C.EV_RECEIPT
+	EV_ERROR     = C.EV_ERROR
+	EVFILT_READ  = C.EVFILT_READ
+	EVFILT_WRITE = C.EVFILT_WRITE
+)
+
+type Rtprio C.struct_rtprio
+type ThrParam C.struct_thr_param
+type SigaltstackT C.struct_sigaltstack
+type Sigset C.struct___sigset
+type StackT C.stack_t
+
+type Siginfo C.siginfo_t
+
+type Mcontext C.mcontext_t
+type Ucontext C.ucontext_t
+
+type Timespec C.struct_timespec
+type Timeval C.struct_timeval
+type Itimerval C.struct_itimerval
+
+type Kevent C.struct_kevent
diff --git a/src/runtime/defs_freebsd_386.h b/src/runtime/defs_freebsd_386.h
new file mode 100644
index 0000000..156dccb
--- /dev/null
+++ b/src/runtime/defs_freebsd_386.h
@@ -0,0 +1,213 @@
+// Created by cgo -cdefs - DO NOT EDIT
+// cgo -cdefs defs_freebsd.go
+
+
+enum {
+	EINTR	= 0x4,
+	EFAULT	= 0xe,
+
+	PROT_NONE	= 0x0,
+	PROT_READ	= 0x1,
+	PROT_WRITE	= 0x2,
+	PROT_EXEC	= 0x4,
+
+	MAP_ANON	= 0x1000,
+	MAP_PRIVATE	= 0x2,
+	MAP_FIXED	= 0x10,
+
+	MADV_FREE	= 0x5,
+
+	SA_SIGINFO	= 0x40,
+	SA_RESTART	= 0x2,
+	SA_ONSTACK	= 0x1,
+
+	UMTX_OP_WAIT_UINT		= 0xb,
+	UMTX_OP_WAIT_UINT_PRIVATE	= 0xf,
+	UMTX_OP_WAKE			= 0x3,
+	UMTX_OP_WAKE_PRIVATE		= 0x10,
+
+	SIGHUP		= 0x1,
+	SIGINT		= 0x2,
+	SIGQUIT		= 0x3,
+	SIGILL		= 0x4,
+	SIGTRAP		= 0x5,
+	SIGABRT		= 0x6,
+	SIGEMT		= 0x7,
+	SIGFPE		= 0x8,
+	SIGKILL		= 0x9,
+	SIGBUS		= 0xa,
+	SIGSEGV		= 0xb,
+	SIGSYS		= 0xc,
+	SIGPIPE		= 0xd,
+	SIGALRM		= 0xe,
+	SIGTERM		= 0xf,
+	SIGURG		= 0x10,
+	SIGSTOP		= 0x11,
+	SIGTSTP		= 0x12,
+	SIGCONT		= 0x13,
+	SIGCHLD		= 0x14,
+	SIGTTIN		= 0x15,
+	SIGTTOU		= 0x16,
+	SIGIO		= 0x17,
+	SIGXCPU		= 0x18,
+	SIGXFSZ		= 0x19,
+	SIGVTALRM	= 0x1a,
+	SIGPROF		= 0x1b,
+	SIGWINCH	= 0x1c,
+	SIGINFO		= 0x1d,
+	SIGUSR1		= 0x1e,
+	SIGUSR2		= 0x1f,
+
+	FPE_INTDIV	= 0x2,
+	FPE_INTOVF	= 0x1,
+	FPE_FLTDIV	= 0x3,
+	FPE_FLTOVF	= 0x4,
+	FPE_FLTUND	= 0x5,
+	FPE_FLTRES	= 0x6,
+	FPE_FLTINV	= 0x7,
+	FPE_FLTSUB	= 0x8,
+
+	BUS_ADRALN	= 0x1,
+	BUS_ADRERR	= 0x2,
+	BUS_OBJERR	= 0x3,
+
+	SEGV_MAPERR	= 0x1,
+	SEGV_ACCERR	= 0x2,
+
+	ITIMER_REAL	= 0x0,
+	ITIMER_VIRTUAL	= 0x1,
+	ITIMER_PROF	= 0x2,
+
+	EV_ADD		= 0x1,
+	EV_DELETE	= 0x2,
+	EV_CLEAR	= 0x20,
+	EV_RECEIPT	= 0x40,
+	EV_ERROR	= 0x4000,
+	EVFILT_READ	= -0x1,
+	EVFILT_WRITE	= -0x2,
+};
+
+typedef struct Rtprio Rtprio;
+typedef struct ThrParam ThrParam;
+typedef struct SigaltstackT SigaltstackT;
+typedef struct Sigset Sigset;
+typedef struct StackT StackT;
+typedef struct Siginfo Siginfo;
+typedef struct Mcontext Mcontext;
+typedef struct Ucontext Ucontext;
+typedef struct Timespec Timespec;
+typedef struct Timeval Timeval;
+typedef struct Itimerval Itimerval;
+typedef struct KeventT KeventT;
+
+#pragma pack on
+
+struct Rtprio {
+	uint16	type;
+	uint16	prio;
+};
+struct ThrParam {
+	void	*start_func;
+	byte	*arg;
+	int8	*stack_base;
+	uint32	stack_size;
+	int8	*tls_base;
+	uint32	tls_size;
+	int32	*child_tid;
+	int32	*parent_tid;
+	int32	flags;
+	Rtprio	*rtp;
+	void	*spare[3];
+};
+struct SigaltstackT {
+	int8	*ss_sp;
+	uint32	ss_size;
+	int32	ss_flags;
+};
+struct Sigset {
+	uint32	__bits[4];
+};
+struct StackT {
+	int8	*ss_sp;
+	uint32	ss_size;
+	int32	ss_flags;
+};
+
+struct Siginfo {
+	int32	si_signo;
+	int32	si_errno;
+	int32	si_code;
+	int32	si_pid;
+	uint32	si_uid;
+	int32	si_status;
+	byte	*si_addr;
+	byte	si_value[4];
+	byte	_reason[32];
+};
+
+struct Mcontext {
+	int32	mc_onstack;
+	int32	mc_gs;
+	int32	mc_fs;
+	int32	mc_es;
+	int32	mc_ds;
+	int32	mc_edi;
+	int32	mc_esi;
+	int32	mc_ebp;
+	int32	mc_isp;
+	int32	mc_ebx;
+	int32	mc_edx;
+	int32	mc_ecx;
+	int32	mc_eax;
+	int32	mc_trapno;
+	int32	mc_err;
+	int32	mc_eip;
+	int32	mc_cs;
+	int32	mc_eflags;
+	int32	mc_esp;
+	int32	mc_ss;
+	int32	mc_len;
+	int32	mc_fpformat;
+	int32	mc_ownedfp;
+	int32	mc_flags;
+	int32	mc_fpstate[128];
+	int32	mc_fsbase;
+	int32	mc_gsbase;
+	int32	mc_xfpustate;
+	int32	mc_xfpustate_len;
+	int32	mc_spare2[4];
+};
+struct Ucontext {
+	Sigset	uc_sigmask;
+	Mcontext	uc_mcontext;
+	Ucontext	*uc_link;
+	StackT	uc_stack;
+	int32	uc_flags;
+	int32	__spare__[4];
+	byte	Pad_cgo_0[12];
+};
+
+struct Timespec {
+	int32	tv_sec;
+	int32	tv_nsec;
+};
+struct Timeval {
+	int32	tv_sec;
+	int32	tv_usec;
+};
+struct Itimerval {
+	Timeval	it_interval;
+	Timeval	it_value;
+};
+
+struct KeventT {
+	uint32	ident;
+	int16	filter;
+	uint16	flags;
+	uint32	fflags;
+	int32	data;
+	byte	*udata;
+};
+
+
+#pragma pack off
diff --git a/src/runtime/defs_freebsd_amd64.h b/src/runtime/defs_freebsd_amd64.h
new file mode 100644
index 0000000..4ba8956
--- /dev/null
+++ b/src/runtime/defs_freebsd_amd64.h
@@ -0,0 +1,224 @@
+// Created by cgo -cdefs - DO NOT EDIT
+// cgo -cdefs defs_freebsd.go
+
+
+enum {
+	EINTR	= 0x4,
+	EFAULT	= 0xe,
+
+	PROT_NONE	= 0x0,
+	PROT_READ	= 0x1,
+	PROT_WRITE	= 0x2,
+	PROT_EXEC	= 0x4,
+
+	MAP_ANON	= 0x1000,
+	MAP_PRIVATE	= 0x2,
+	MAP_FIXED	= 0x10,
+
+	MADV_FREE	= 0x5,
+
+	SA_SIGINFO	= 0x40,
+	SA_RESTART	= 0x2,
+	SA_ONSTACK	= 0x1,
+
+	UMTX_OP_WAIT_UINT		= 0xb,
+	UMTX_OP_WAIT_UINT_PRIVATE	= 0xf,
+	UMTX_OP_WAKE			= 0x3,
+	UMTX_OP_WAKE_PRIVATE		= 0x10,
+
+	SIGHUP		= 0x1,
+	SIGINT		= 0x2,
+	SIGQUIT		= 0x3,
+	SIGILL		= 0x4,
+	SIGTRAP		= 0x5,
+	SIGABRT		= 0x6,
+	SIGEMT		= 0x7,
+	SIGFPE		= 0x8,
+	SIGKILL		= 0x9,
+	SIGBUS		= 0xa,
+	SIGSEGV		= 0xb,
+	SIGSYS		= 0xc,
+	SIGPIPE		= 0xd,
+	SIGALRM		= 0xe,
+	SIGTERM		= 0xf,
+	SIGURG		= 0x10,
+	SIGSTOP		= 0x11,
+	SIGTSTP		= 0x12,
+	SIGCONT		= 0x13,
+	SIGCHLD		= 0x14,
+	SIGTTIN		= 0x15,
+	SIGTTOU		= 0x16,
+	SIGIO		= 0x17,
+	SIGXCPU		= 0x18,
+	SIGXFSZ		= 0x19,
+	SIGVTALRM	= 0x1a,
+	SIGPROF		= 0x1b,
+	SIGWINCH	= 0x1c,
+	SIGINFO		= 0x1d,
+	SIGUSR1		= 0x1e,
+	SIGUSR2		= 0x1f,
+
+	FPE_INTDIV	= 0x2,
+	FPE_INTOVF	= 0x1,
+	FPE_FLTDIV	= 0x3,
+	FPE_FLTOVF	= 0x4,
+	FPE_FLTUND	= 0x5,
+	FPE_FLTRES	= 0x6,
+	FPE_FLTINV	= 0x7,
+	FPE_FLTSUB	= 0x8,
+
+	BUS_ADRALN	= 0x1,
+	BUS_ADRERR	= 0x2,
+	BUS_OBJERR	= 0x3,
+
+	SEGV_MAPERR	= 0x1,
+	SEGV_ACCERR	= 0x2,
+
+	ITIMER_REAL	= 0x0,
+	ITIMER_VIRTUAL	= 0x1,
+	ITIMER_PROF	= 0x2,
+
+	EV_ADD		= 0x1,
+	EV_DELETE	= 0x2,
+	EV_CLEAR	= 0x20,
+	EV_RECEIPT	= 0x40,
+	EV_ERROR	= 0x4000,
+	EVFILT_READ	= -0x1,
+	EVFILT_WRITE	= -0x2,
+};
+
+typedef struct Rtprio Rtprio;
+typedef struct ThrParam ThrParam;
+typedef struct SigaltstackT SigaltstackT;
+typedef struct Sigset Sigset;
+typedef struct StackT StackT;
+typedef struct Siginfo Siginfo;
+typedef struct Mcontext Mcontext;
+typedef struct Ucontext Ucontext;
+typedef struct Timespec Timespec;
+typedef struct Timeval Timeval;
+typedef struct Itimerval Itimerval;
+typedef struct KeventT KeventT;
+
+#pragma pack on
+
+struct Rtprio {
+	uint16	type;
+	uint16	prio;
+};
+struct ThrParam {
+	void	*start_func;
+	byte	*arg;
+	int8	*stack_base;
+	uint64	stack_size;
+	int8	*tls_base;
+	uint64	tls_size;
+	int64	*child_tid;
+	int64	*parent_tid;
+	int32	flags;
+	byte	Pad_cgo_0[4];
+	Rtprio	*rtp;
+	void	*spare[3];
+};
+struct SigaltstackT {
+	int8	*ss_sp;
+	uint64	ss_size;
+	int32	ss_flags;
+	byte	Pad_cgo_0[4];
+};
+struct Sigset {
+	uint32	__bits[4];
+};
+struct StackT {
+	int8	*ss_sp;
+	uint64	ss_size;
+	int32	ss_flags;
+	byte	Pad_cgo_0[4];
+};
+
+struct Siginfo {
+	int32	si_signo;
+	int32	si_errno;
+	int32	si_code;
+	int32	si_pid;
+	uint32	si_uid;
+	int32	si_status;
+	byte	*si_addr;
+	byte	si_value[8];
+	byte	_reason[40];
+};
+
+struct Mcontext {
+	int64	mc_onstack;
+	int64	mc_rdi;
+	int64	mc_rsi;
+	int64	mc_rdx;
+	int64	mc_rcx;
+	int64	mc_r8;
+	int64	mc_r9;
+	int64	mc_rax;
+	int64	mc_rbx;
+	int64	mc_rbp;
+	int64	mc_r10;
+	int64	mc_r11;
+	int64	mc_r12;
+	int64	mc_r13;
+	int64	mc_r14;
+	int64	mc_r15;
+	uint32	mc_trapno;
+	uint16	mc_fs;
+	uint16	mc_gs;
+	int64	mc_addr;
+	uint32	mc_flags;
+	uint16	mc_es;
+	uint16	mc_ds;
+	int64	mc_err;
+	int64	mc_rip;
+	int64	mc_cs;
+	int64	mc_rflags;
+	int64	mc_rsp;
+	int64	mc_ss;
+	int64	mc_len;
+	int64	mc_fpformat;
+	int64	mc_ownedfp;
+	int64	mc_fpstate[64];
+	int64	mc_fsbase;
+	int64	mc_gsbase;
+	int64	mc_xfpustate;
+	int64	mc_xfpustate_len;
+	int64	mc_spare[4];
+};
+struct Ucontext {
+	Sigset	uc_sigmask;
+	Mcontext	uc_mcontext;
+	Ucontext	*uc_link;
+	StackT	uc_stack;
+	int32	uc_flags;
+	int32	__spare__[4];
+	byte	Pad_cgo_0[12];
+};
+
+struct Timespec {
+	int64	tv_sec;
+	int64	tv_nsec;
+};
+struct Timeval {
+	int64	tv_sec;
+	int64	tv_usec;
+};
+struct Itimerval {
+	Timeval	it_interval;
+	Timeval	it_value;
+};
+
+struct KeventT {
+	uint64	ident;
+	int16	filter;
+	uint16	flags;
+	uint32	fflags;
+	int64	data;
+	byte	*udata;
+};
+
+
+#pragma pack off
diff --git a/src/runtime/defs_freebsd_arm.h b/src/runtime/defs_freebsd_arm.h
new file mode 100644
index 0000000..17deba6
--- /dev/null
+++ b/src/runtime/defs_freebsd_arm.h
@@ -0,0 +1,186 @@
+// Created by cgo -cdefs - DO NOT EDIT
+// cgo -cdefs defs_freebsd.go
+
+
+enum {
+	EINTR	= 0x4,
+	EFAULT	= 0xe,
+
+	PROT_NONE	= 0x0,
+	PROT_READ	= 0x1,
+	PROT_WRITE	= 0x2,
+	PROT_EXEC	= 0x4,
+
+	MAP_ANON	= 0x1000,
+	MAP_PRIVATE	= 0x2,
+	MAP_FIXED	= 0x10,
+
+	MADV_FREE	= 0x5,
+
+	SA_SIGINFO	= 0x40,
+	SA_RESTART	= 0x2,
+	SA_ONSTACK	= 0x1,
+
+	UMTX_OP_WAIT_UINT		= 0xb,
+	UMTX_OP_WAIT_UINT_PRIVATE	= 0xf,
+	UMTX_OP_WAKE			= 0x3,
+	UMTX_OP_WAKE_PRIVATE		= 0x10,
+
+	SIGHUP		= 0x1,
+	SIGINT		= 0x2,
+	SIGQUIT		= 0x3,
+	SIGILL		= 0x4,
+	SIGTRAP		= 0x5,
+	SIGABRT		= 0x6,
+	SIGEMT		= 0x7,
+	SIGFPE		= 0x8,
+	SIGKILL		= 0x9,
+	SIGBUS		= 0xa,
+	SIGSEGV		= 0xb,
+	SIGSYS		= 0xc,
+	SIGPIPE		= 0xd,
+	SIGALRM		= 0xe,
+	SIGTERM		= 0xf,
+	SIGURG		= 0x10,
+	SIGSTOP		= 0x11,
+	SIGTSTP		= 0x12,
+	SIGCONT		= 0x13,
+	SIGCHLD		= 0x14,
+	SIGTTIN		= 0x15,
+	SIGTTOU		= 0x16,
+	SIGIO		= 0x17,
+	SIGXCPU		= 0x18,
+	SIGXFSZ		= 0x19,
+	SIGVTALRM	= 0x1a,
+	SIGPROF		= 0x1b,
+	SIGWINCH	= 0x1c,
+	SIGINFO		= 0x1d,
+	SIGUSR1		= 0x1e,
+	SIGUSR2		= 0x1f,
+
+	FPE_INTDIV	= 0x2,
+	FPE_INTOVF	= 0x1,
+	FPE_FLTDIV	= 0x3,
+	FPE_FLTOVF	= 0x4,
+	FPE_FLTUND	= 0x5,
+	FPE_FLTRES	= 0x6,
+	FPE_FLTINV	= 0x7,
+	FPE_FLTSUB	= 0x8,
+
+	BUS_ADRALN	= 0x1,
+	BUS_ADRERR	= 0x2,
+	BUS_OBJERR	= 0x3,
+
+	SEGV_MAPERR	= 0x1,
+	SEGV_ACCERR	= 0x2,
+
+	ITIMER_REAL	= 0x0,
+	ITIMER_VIRTUAL	= 0x1,
+	ITIMER_PROF	= 0x2,
+
+	EV_ADD		= 0x1,
+	EV_DELETE	= 0x2,
+	EV_CLEAR	= 0x20,
+	EV_RECEIPT	= 0x40,
+	EV_ERROR	= 0x4000,
+	EVFILT_READ	= -0x1,
+	EVFILT_WRITE	= -0x2,
+};
+
+typedef struct Rtprio Rtprio;
+typedef struct ThrParam ThrParam;
+typedef struct SigaltstackT SigaltstackT;
+typedef struct Sigset Sigset;
+typedef struct StackT StackT;
+typedef struct Siginfo Siginfo;
+typedef struct Mcontext Mcontext;
+typedef struct Ucontext Ucontext;
+typedef struct Timespec Timespec;
+typedef struct Timeval Timeval;
+typedef struct Itimerval Itimerval;
+typedef struct KeventT KeventT;
+
+#pragma pack on
+
+struct Rtprio {
+	uint16	type;
+	uint16	prio;
+};
+struct ThrParam {
+	void	*start_func;
+	byte	*arg;
+	uint8	*stack_base;
+	uint32	stack_size;
+	uint8	*tls_base;
+	uint32	tls_size;
+	int32	*child_tid;
+	int32	*parent_tid;
+	int32	flags;
+	Rtprio	*rtp;
+	void	*spare[3];
+};
+struct SigaltstackT {
+	uint8	*ss_sp;
+	uint32	ss_size;
+	int32	ss_flags;
+};
+struct Sigset {
+	uint32	__bits[4];
+};
+struct StackT {
+	uint8	*ss_sp;
+	uint32	ss_size;
+	int32	ss_flags;
+};
+
+struct Siginfo {
+	int32	si_signo;
+	int32	si_errno;
+	int32	si_code;
+	int32	si_pid;
+	uint32	si_uid;
+	int32	si_status;
+	byte	*si_addr;
+	byte	si_value[4];
+	byte	_reason[32];
+};
+
+struct Mcontext {
+	uint32	__gregs[17];
+	byte	__fpu[140];
+};
+struct Ucontext {
+	Sigset	uc_sigmask;
+	Mcontext	uc_mcontext;
+	Ucontext	*uc_link;
+	StackT	uc_stack;
+	int32	uc_flags;
+	int32	__spare__[4];
+};
+
+struct Timespec {
+	int64	tv_sec;
+	int32	tv_nsec;
+	byte	Pad_cgo_0[4];
+};
+struct Timeval {
+	int64	tv_sec;
+	int32	tv_usec;
+	byte	Pad_cgo_0[4];
+};
+struct Itimerval {
+	Timeval	it_interval;
+	Timeval	it_value;
+};
+
+struct KeventT {
+	uint32	ident;
+	int16	filter;
+	uint16	flags;
+	uint32	fflags;
+	int32	data;
+	byte	*udata;
+};
+
+
+#pragma pack off
diff --git a/src/runtime/defs_linux.go b/src/runtime/defs_linux.go
new file mode 100644
index 0000000..8657dbb
--- /dev/null
+++ b/src/runtime/defs_linux.go
@@ -0,0 +1,124 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build ignore
+
+/*
+Input to cgo -cdefs
+
+GOARCH=amd64 go tool cgo -cdefs defs_linux.go defs1_linux.go >defs_linux_amd64.h
+*/
+
+package runtime
+
+/*
+// Linux glibc and Linux kernel define different and conflicting
+// definitions for struct sigaction, struct timespec, etc.
+// We want the kernel ones, which are in the asm/* headers.
+// But then we'd get conflicts when we include the system
+// headers for things like ucontext_t, so that happens in
+// a separate file, defs1.go.
+
+#include <asm/posix_types.h>
+#define size_t __kernel_size_t
+#include <asm/signal.h>
+#include <asm/siginfo.h>
+#include <asm/mman.h>
+#include <asm-generic/errno.h>
+#include <asm-generic/poll.h>
+#include <linux/eventpoll.h>
+#undef size_t
+*/
+import "C"
+
+const (
+	EINTR  = C.EINTR
+	EAGAIN = C.EAGAIN
+	ENOMEM = C.ENOMEM
+
+	PROT_NONE  = C.PROT_NONE
+	PROT_READ  = C.PROT_READ
+	PROT_WRITE = C.PROT_WRITE
+	PROT_EXEC  = C.PROT_EXEC
+
+	MAP_ANON    = C.MAP_ANONYMOUS
+	MAP_PRIVATE = C.MAP_PRIVATE
+	MAP_FIXED   = C.MAP_FIXED
+
+	MADV_DONTNEED = C.MADV_DONTNEED
+
+	SA_RESTART  = C.SA_RESTART
+	SA_ONSTACK  = C.SA_ONSTACK
+	SA_RESTORER = C.SA_RESTORER
+	SA_SIGINFO  = C.SA_SIGINFO
+
+	SIGHUP    = C.SIGHUP
+	SIGINT    = C.SIGINT
+	SIGQUIT   = C.SIGQUIT
+	SIGILL    = C.SIGILL
+	SIGTRAP   = C.SIGTRAP
+	SIGABRT   = C.SIGABRT
+	SIGBUS    = C.SIGBUS
+	SIGFPE    = C.SIGFPE
+	SIGKILL   = C.SIGKILL
+	SIGUSR1   = C.SIGUSR1
+	SIGSEGV   = C.SIGSEGV
+	SIGUSR2   = C.SIGUSR2
+	SIGPIPE   = C.SIGPIPE
+	SIGALRM   = C.SIGALRM
+	SIGSTKFLT = C.SIGSTKFLT
+	SIGCHLD   = C.SIGCHLD
+	SIGCONT   = C.SIGCONT
+	SIGSTOP   = C.SIGSTOP
+	SIGTSTP   = C.SIGTSTP
+	SIGTTIN   = C.SIGTTIN
+	SIGTTOU   = C.SIGTTOU
+	SIGURG    = C.SIGURG
+	SIGXCPU   = C.SIGXCPU
+	SIGXFSZ   = C.SIGXFSZ
+	SIGVTALRM = C.SIGVTALRM
+	SIGPROF   = C.SIGPROF
+	SIGWINCH  = C.SIGWINCH
+	SIGIO     = C.SIGIO
+	SIGPWR    = C.SIGPWR
+	SIGSYS    = C.SIGSYS
+
+	FPE_INTDIV = C.FPE_INTDIV
+	FPE_INTOVF = C.FPE_INTOVF
+	FPE_FLTDIV = C.FPE_FLTDIV
+	FPE_FLTOVF = C.FPE_FLTOVF
+	FPE_FLTUND = C.FPE_FLTUND
+	FPE_FLTRES = C.FPE_FLTRES
+	FPE_FLTINV = C.FPE_FLTINV
+	FPE_FLTSUB = C.FPE_FLTSUB
+
+	BUS_ADRALN = C.BUS_ADRALN
+	BUS_ADRERR = C.BUS_ADRERR
+	BUS_OBJERR = C.BUS_OBJERR
+
+	SEGV_MAPERR = C.SEGV_MAPERR
+	SEGV_ACCERR = C.SEGV_ACCERR
+
+	ITIMER_REAL    = C.ITIMER_REAL
+	ITIMER_VIRTUAL = C.ITIMER_VIRTUAL
+	ITIMER_PROF    = C.ITIMER_PROF
+
+	EPOLLIN       = C.POLLIN
+	EPOLLOUT      = C.POLLOUT
+	EPOLLERR      = C.POLLERR
+	EPOLLHUP      = C.POLLHUP
+	EPOLLRDHUP    = C.POLLRDHUP
+	EPOLLET       = C.EPOLLET
+	EPOLL_CLOEXEC = C.EPOLL_CLOEXEC
+	EPOLL_CTL_ADD = C.EPOLL_CTL_ADD
+	EPOLL_CTL_DEL = C.EPOLL_CTL_DEL
+	EPOLL_CTL_MOD = C.EPOLL_CTL_MOD
+)
+
+type Timespec C.struct_timespec
+type Timeval C.struct_timeval
+type Sigaction C.struct_sigaction
+type Siginfo C.siginfo_t
+type Itimerval C.struct_itimerval
+type EpollEvent C.struct_epoll_event
diff --git a/src/runtime/defs_linux_386.h b/src/runtime/defs_linux_386.h
new file mode 100644
index 0000000..24a05d8
--- /dev/null
+++ b/src/runtime/defs_linux_386.h
@@ -0,0 +1,211 @@
+// Created by cgo -cdefs - DO NOT EDIT
+// cgo -cdefs defs2_linux.go
+
+
+enum {
+	EINTR	= 0x4,
+	EAGAIN	= 0xb,
+	ENOMEM	= 0xc,
+
+	PROT_NONE	= 0x0,
+	PROT_READ	= 0x1,
+	PROT_WRITE	= 0x2,
+	PROT_EXEC	= 0x4,
+
+	MAP_ANON	= 0x20,
+	MAP_PRIVATE	= 0x2,
+	MAP_FIXED	= 0x10,
+
+	MADV_DONTNEED	= 0x4,
+
+	SA_RESTART	= 0x10000000,
+	SA_ONSTACK	= 0x8000000,
+	SA_RESTORER	= 0x4000000,
+	SA_SIGINFO	= 0x4,
+
+	SIGHUP		= 0x1,
+	SIGINT		= 0x2,
+	SIGQUIT		= 0x3,
+	SIGILL		= 0x4,
+	SIGTRAP		= 0x5,
+	SIGABRT		= 0x6,
+	SIGBUS		= 0x7,
+	SIGFPE		= 0x8,
+	SIGKILL		= 0x9,
+	SIGUSR1		= 0xa,
+	SIGSEGV		= 0xb,
+	SIGUSR2		= 0xc,
+	SIGPIPE		= 0xd,
+	SIGALRM		= 0xe,
+	SIGSTKFLT	= 0x10,
+	SIGCHLD		= 0x11,
+	SIGCONT		= 0x12,
+	SIGSTOP		= 0x13,
+	SIGTSTP		= 0x14,
+	SIGTTIN		= 0x15,
+	SIGTTOU		= 0x16,
+	SIGURG		= 0x17,
+	SIGXCPU		= 0x18,
+	SIGXFSZ		= 0x19,
+	SIGVTALRM	= 0x1a,
+	SIGPROF		= 0x1b,
+	SIGWINCH	= 0x1c,
+	SIGIO		= 0x1d,
+	SIGPWR		= 0x1e,
+	SIGSYS		= 0x1f,
+
+	FPE_INTDIV	= 0x1,
+	FPE_INTOVF	= 0x2,
+	FPE_FLTDIV	= 0x3,
+	FPE_FLTOVF	= 0x4,
+	FPE_FLTUND	= 0x5,
+	FPE_FLTRES	= 0x6,
+	FPE_FLTINV	= 0x7,
+	FPE_FLTSUB	= 0x8,
+
+	BUS_ADRALN	= 0x1,
+	BUS_ADRERR	= 0x2,
+	BUS_OBJERR	= 0x3,
+
+	SEGV_MAPERR	= 0x1,
+	SEGV_ACCERR	= 0x2,
+
+	ITIMER_REAL	= 0x0,
+	ITIMER_VIRTUAL	= 0x1,
+	ITIMER_PROF	= 0x2,
+
+	O_RDONLY	= 0x0,
+	O_CLOEXEC	= 0x80000,
+
+	EPOLLIN		= 0x1,
+	EPOLLOUT	= 0x4,
+	EPOLLERR	= 0x8,
+	EPOLLHUP	= 0x10,
+	EPOLLRDHUP	= 0x2000,
+	EPOLLET		= -0x80000000,
+	EPOLL_CLOEXEC	= 0x80000,
+	EPOLL_CTL_ADD	= 0x1,
+	EPOLL_CTL_DEL	= 0x2,
+	EPOLL_CTL_MOD	= 0x3,
+};
+
+typedef struct Fpreg Fpreg;
+typedef struct Fpxreg Fpxreg;
+typedef struct Xmmreg Xmmreg;
+typedef struct Fpstate Fpstate;
+typedef struct Timespec Timespec;
+typedef struct Timeval Timeval;
+typedef struct SigactionT SigactionT;
+typedef struct Siginfo Siginfo;
+typedef struct SigaltstackT SigaltstackT;
+typedef struct Sigcontext Sigcontext;
+typedef struct Ucontext Ucontext;
+typedef struct Itimerval Itimerval;
+typedef struct EpollEvent EpollEvent;
+
+#pragma pack on
+
+struct Fpreg {
+	uint16	significand[4];
+	uint16	exponent;
+};
+struct Fpxreg {
+	uint16	significand[4];
+	uint16	exponent;
+	uint16	padding[3];
+};
+struct Xmmreg {
+	uint32	element[4];
+};
+struct Fpstate {
+	uint32	cw;
+	uint32	sw;
+	uint32	tag;
+	uint32	ipoff;
+	uint32	cssel;
+	uint32	dataoff;
+	uint32	datasel;
+	Fpreg	_st[8];
+	uint16	status;
+	uint16	magic;
+	uint32	_fxsr_env[6];
+	uint32	mxcsr;
+	uint32	reserved;
+	Fpxreg	_fxsr_st[8];
+	Xmmreg	_xmm[8];
+	uint32	padding1[44];
+	byte	anon0[48];
+};
+struct Timespec {
+	int32	tv_sec;
+	int32	tv_nsec;
+};
+struct Timeval {
+	int32	tv_sec;
+	int32	tv_usec;
+};
+struct SigactionT {
+	void	*k_sa_handler;
+	uint32	sa_flags;
+	void	*sa_restorer;
+	uint64	sa_mask;
+};
+struct Siginfo {
+	int32	si_signo;
+	int32	si_errno;
+	int32	si_code;
+	byte	_sifields[116];
+};
+struct SigaltstackT {
+	byte	*ss_sp;
+	int32	ss_flags;
+	uint32	ss_size;
+};
+struct Sigcontext {
+	uint16	gs;
+	uint16	__gsh;
+	uint16	fs;
+	uint16	__fsh;
+	uint16	es;
+	uint16	__esh;
+	uint16	ds;
+	uint16	__dsh;
+	uint32	edi;
+	uint32	esi;
+	uint32	ebp;
+	uint32	esp;
+	uint32	ebx;
+	uint32	edx;
+	uint32	ecx;
+	uint32	eax;
+	uint32	trapno;
+	uint32	err;
+	uint32	eip;
+	uint16	cs;
+	uint16	__csh;
+	uint32	eflags;
+	uint32	esp_at_signal;
+	uint16	ss;
+	uint16	__ssh;
+	Fpstate	*fpstate;
+	uint32	oldmask;
+	uint32	cr2;
+};
+struct Ucontext {
+	uint32	uc_flags;
+	Ucontext	*uc_link;
+	SigaltstackT	uc_stack;
+	Sigcontext	uc_mcontext;
+	uint32	uc_sigmask;
+};
+struct Itimerval {
+	Timeval	it_interval;
+	Timeval	it_value;
+};
+struct EpollEvent {
+	uint32	events;
+	byte	data[8]; // to match amd64
+};
+
+
+#pragma pack off
diff --git a/src/runtime/defs_linux_amd64.h b/src/runtime/defs_linux_amd64.h
new file mode 100644
index 0000000..14616df
--- /dev/null
+++ b/src/runtime/defs_linux_amd64.h
@@ -0,0 +1,254 @@
+// Created by cgo -cdefs - DO NOT EDIT
+// cgo -cdefs defs_linux.go defs1_linux.go
+
+
+enum {
+	EINTR	= 0x4,
+	EAGAIN	= 0xb,
+	ENOMEM	= 0xc,
+
+	PROT_NONE	= 0x0,
+	PROT_READ	= 0x1,
+	PROT_WRITE	= 0x2,
+	PROT_EXEC	= 0x4,
+
+	MAP_ANON	= 0x20,
+	MAP_PRIVATE	= 0x2,
+	MAP_FIXED	= 0x10,
+
+	MADV_DONTNEED	= 0x4,
+
+	SA_RESTART	= 0x10000000,
+	SA_ONSTACK	= 0x8000000,
+	SA_RESTORER	= 0x4000000,
+	SA_SIGINFO	= 0x4,
+
+	SIGHUP		= 0x1,
+	SIGINT		= 0x2,
+	SIGQUIT		= 0x3,
+	SIGILL		= 0x4,
+	SIGTRAP		= 0x5,
+	SIGABRT		= 0x6,
+	SIGBUS		= 0x7,
+	SIGFPE		= 0x8,
+	SIGKILL		= 0x9,
+	SIGUSR1		= 0xa,
+	SIGSEGV		= 0xb,
+	SIGUSR2		= 0xc,
+	SIGPIPE		= 0xd,
+	SIGALRM		= 0xe,
+	SIGSTKFLT	= 0x10,
+	SIGCHLD		= 0x11,
+	SIGCONT		= 0x12,
+	SIGSTOP		= 0x13,
+	SIGTSTP		= 0x14,
+	SIGTTIN		= 0x15,
+	SIGTTOU		= 0x16,
+	SIGURG		= 0x17,
+	SIGXCPU		= 0x18,
+	SIGXFSZ		= 0x19,
+	SIGVTALRM	= 0x1a,
+	SIGPROF		= 0x1b,
+	SIGWINCH	= 0x1c,
+	SIGIO		= 0x1d,
+	SIGPWR		= 0x1e,
+	SIGSYS		= 0x1f,
+
+	FPE_INTDIV	= 0x1,
+	FPE_INTOVF	= 0x2,
+	FPE_FLTDIV	= 0x3,
+	FPE_FLTOVF	= 0x4,
+	FPE_FLTUND	= 0x5,
+	FPE_FLTRES	= 0x6,
+	FPE_FLTINV	= 0x7,
+	FPE_FLTSUB	= 0x8,
+
+	BUS_ADRALN	= 0x1,
+	BUS_ADRERR	= 0x2,
+	BUS_OBJERR	= 0x3,
+
+	SEGV_MAPERR	= 0x1,
+	SEGV_ACCERR	= 0x2,
+
+	ITIMER_REAL	= 0x0,
+	ITIMER_VIRTUAL	= 0x1,
+	ITIMER_PROF	= 0x2,
+
+	EPOLLIN		= 0x1,
+	EPOLLOUT	= 0x4,
+	EPOLLERR	= 0x8,
+	EPOLLHUP	= 0x10,
+	EPOLLRDHUP	= 0x2000,
+	EPOLLET		= -0x80000000,
+	EPOLL_CLOEXEC	= 0x80000,
+	EPOLL_CTL_ADD	= 0x1,
+	EPOLL_CTL_DEL	= 0x2,
+	EPOLL_CTL_MOD	= 0x3,
+};
+
+typedef struct Timespec Timespec;
+typedef struct Timeval Timeval;
+typedef struct SigactionT SigactionT;
+typedef struct Siginfo Siginfo;
+typedef struct Itimerval Itimerval;
+typedef struct EpollEvent EpollEvent;
+
+#pragma pack on
+
+struct Timespec {
+	int64	tv_sec;
+	int64	tv_nsec;
+};
+struct Timeval {
+	int64	tv_sec;
+	int64	tv_usec;
+};
+struct SigactionT {
+	void	*sa_handler;
+	uint64	sa_flags;
+	void	*sa_restorer;
+	uint64	sa_mask;
+};
+struct Siginfo {
+	int32	si_signo;
+	int32	si_errno;
+	int32	si_code;
+	byte	Pad_cgo_0[4];
+	byte	_sifields[112];
+};
+struct Itimerval {
+	Timeval	it_interval;
+	Timeval	it_value;
+};
+struct EpollEvent {
+	uint32	events;
+	byte	data[8]; // unaligned uintptr
+};
+
+
+#pragma pack off
+// Created by cgo -cdefs - DO NOT EDIT
+// cgo -cdefs defs_linux.go defs1_linux.go
+
+
+enum {
+	O_RDONLY	= 0x0,
+	O_CLOEXEC	= 0x80000,
+};
+
+typedef struct Usigset Usigset;
+typedef struct Fpxreg Fpxreg;
+typedef struct Xmmreg Xmmreg;
+typedef struct Fpstate Fpstate;
+typedef struct Fpxreg1 Fpxreg1;
+typedef struct Xmmreg1 Xmmreg1;
+typedef struct Fpstate1 Fpstate1;
+typedef struct Fpreg1 Fpreg1;
+typedef struct SigaltstackT SigaltstackT;
+typedef struct Mcontext Mcontext;
+typedef struct Ucontext Ucontext;
+typedef struct Sigcontext Sigcontext;
+
+#pragma pack on
+
+struct Usigset {
+	uint64	__val[16];
+};
+struct Fpxreg {
+	uint16	significand[4];
+	uint16	exponent;
+	uint16	padding[3];
+};
+struct Xmmreg {
+	uint32	element[4];
+};
+struct Fpstate {
+	uint16	cwd;
+	uint16	swd;
+	uint16	ftw;
+	uint16	fop;
+	uint64	rip;
+	uint64	rdp;
+	uint32	mxcsr;
+	uint32	mxcr_mask;
+	Fpxreg	_st[8];
+	Xmmreg	_xmm[16];
+	uint32	padding[24];
+};
+struct Fpxreg1 {
+	uint16	significand[4];
+	uint16	exponent;
+	uint16	padding[3];
+};
+struct Xmmreg1 {
+	uint32	element[4];
+};
+struct Fpstate1 {
+	uint16	cwd;
+	uint16	swd;
+	uint16	ftw;
+	uint16	fop;
+	uint64	rip;
+	uint64	rdp;
+	uint32	mxcsr;
+	uint32	mxcr_mask;
+	Fpxreg1	_st[8];
+	Xmmreg1	_xmm[16];
+	uint32	padding[24];
+};
+struct Fpreg1 {
+	uint16	significand[4];
+	uint16	exponent;
+};
+struct SigaltstackT {
+	byte	*ss_sp;
+	int32	ss_flags;
+	byte	Pad_cgo_0[4];
+	uint64	ss_size;
+};
+struct Mcontext {
+	int64	gregs[23];
+	Fpstate	*fpregs;
+	uint64	__reserved1[8];
+};
+struct Ucontext {
+	uint64	uc_flags;
+	Ucontext	*uc_link;
+	SigaltstackT	uc_stack;
+	Mcontext	uc_mcontext;
+	Usigset	uc_sigmask;
+	Fpstate	__fpregs_mem;
+};
+struct Sigcontext {
+	uint64	r8;
+	uint64	r9;
+	uint64	r10;
+	uint64	r11;
+	uint64	r12;
+	uint64	r13;
+	uint64	r14;
+	uint64	r15;
+	uint64	rdi;
+	uint64	rsi;
+	uint64	rbp;
+	uint64	rbx;
+	uint64	rdx;
+	uint64	rax;
+	uint64	rcx;
+	uint64	rsp;
+	uint64	rip;
+	uint64	eflags;
+	uint16	cs;
+	uint16	gs;
+	uint16	fs;
+	uint16	__pad0;
+	uint64	err;
+	uint64	trapno;
+	uint64	oldmask;
+	uint64	cr2;
+	Fpstate1	*fpstate;
+	uint64	__reserved1[8];
+};
+
+
+#pragma pack off
diff --git a/src/runtime/defs_linux_arm.h b/src/runtime/defs_linux_arm.h
new file mode 100644
index 0000000..50b3c91
--- /dev/null
+++ b/src/runtime/defs_linux_arm.h
@@ -0,0 +1,168 @@
+// TODO: Generate using cgo like defs_linux_{386,amd64}.h
+
+// Constants
+enum {
+	EINTR  = 0x4,
+	ENOMEM = 0xc,
+	EAGAIN = 0xb,
+
+	PROT_NONE = 0,
+	PROT_READ = 0x1,
+	PROT_WRITE = 0x2,
+	PROT_EXEC = 0x4,
+	MAP_ANON = 0x20,
+	MAP_PRIVATE = 0x2,
+	MAP_FIXED = 0x10,
+	MADV_DONTNEED = 0x4,
+	SA_RESTART = 0x10000000,
+	SA_ONSTACK = 0x8000000,
+	SA_RESTORER = 0, // unused on ARM
+	SA_SIGINFO = 0x4,
+	SIGHUP = 0x1,
+	SIGINT = 0x2,
+	SIGQUIT = 0x3,
+	SIGILL = 0x4,
+	SIGTRAP = 0x5,
+	SIGABRT = 0x6,
+	SIGBUS = 0x7,
+	SIGFPE = 0x8,
+	SIGKILL = 0x9,
+	SIGUSR1 = 0xa,
+	SIGSEGV = 0xb,
+	SIGUSR2 = 0xc,
+	SIGPIPE = 0xd,
+	SIGALRM = 0xe,
+	SIGSTKFLT = 0x10,
+	SIGCHLD = 0x11,
+	SIGCONT = 0x12,
+	SIGSTOP = 0x13,
+	SIGTSTP = 0x14,
+	SIGTTIN = 0x15,
+	SIGTTOU = 0x16,
+	SIGURG = 0x17,
+	SIGXCPU = 0x18,
+	SIGXFSZ = 0x19,
+	SIGVTALRM = 0x1a,
+	SIGPROF = 0x1b,
+	SIGWINCH = 0x1c,
+	SIGIO = 0x1d,
+	SIGPWR = 0x1e,
+	SIGSYS = 0x1f,
+	FPE_INTDIV = 0x1,
+	FPE_INTOVF = 0x2,
+	FPE_FLTDIV = 0x3,
+	FPE_FLTOVF = 0x4,
+	FPE_FLTUND = 0x5,
+	FPE_FLTRES = 0x6,
+	FPE_FLTINV = 0x7,
+	FPE_FLTSUB = 0x8,
+	BUS_ADRALN = 0x1,
+	BUS_ADRERR = 0x2,
+	BUS_OBJERR = 0x3,
+	SEGV_MAPERR = 0x1,
+	SEGV_ACCERR = 0x2,
+	ITIMER_REAL = 0,
+	ITIMER_PROF = 0x2,
+	ITIMER_VIRTUAL = 0x1,
+	O_RDONLY = 0,
+	O_CLOEXEC = 02000000,
+
+	EPOLLIN		= 0x1,
+	EPOLLOUT	= 0x4,
+	EPOLLERR	= 0x8,
+	EPOLLHUP	= 0x10,
+	EPOLLRDHUP	= 0x2000,
+	EPOLLET		= -0x80000000,
+	EPOLL_CLOEXEC	= 0x80000,
+	EPOLL_CTL_ADD	= 0x1,
+	EPOLL_CTL_DEL	= 0x2,
+	EPOLL_CTL_MOD	= 0x3,
+};
+
+// Types
+#pragma pack on
+
+typedef struct Timespec Timespec;
+struct Timespec {
+	int32 tv_sec;
+	int32 tv_nsec;
+};
+
+typedef struct SigaltstackT SigaltstackT;
+struct SigaltstackT {
+	void *ss_sp;
+	int32 ss_flags;
+	uint32 ss_size;
+};
+
+typedef struct Sigcontext Sigcontext;
+struct Sigcontext {
+	uint32 trap_no;
+	uint32 error_code;
+	uint32 oldmask;
+	uint32 arm_r0;
+	uint32 arm_r1;
+	uint32 arm_r2;
+	uint32 arm_r3;
+	uint32 arm_r4;
+	uint32 arm_r5;
+	uint32 arm_r6;
+	uint32 arm_r7;
+	uint32 arm_r8;
+	uint32 arm_r9;
+	uint32 arm_r10;
+	uint32 arm_fp;
+	uint32 arm_ip;
+	uint32 arm_sp;
+	uint32 arm_lr;
+	uint32 arm_pc;
+	uint32 arm_cpsr;
+	uint32 fault_address;
+};
+
+typedef struct Ucontext Ucontext;
+struct Ucontext {
+	uint32 uc_flags;
+	Ucontext *uc_link;
+	SigaltstackT uc_stack;
+	Sigcontext uc_mcontext;
+	uint32 uc_sigmask;
+	int32 __unused[31];
+	uint32 uc_regspace[128];
+};
+
+typedef struct Timeval Timeval;
+struct Timeval {
+	int32 tv_sec;
+	int32 tv_usec;
+};
+
+typedef struct Itimerval Itimerval;
+struct Itimerval {
+	Timeval it_interval;
+	Timeval it_value;
+};
+
+typedef struct Siginfo Siginfo;
+struct Siginfo {
+	int32 si_signo;
+	int32 si_errno;
+	int32 si_code;
+	uint8 _sifields[4];
+};
+
+typedef struct SigactionT SigactionT;
+struct SigactionT {
+	void *sa_handler;
+	uint32 sa_flags;
+	void *sa_restorer;
+	uint64 sa_mask;
+};
+
+typedef struct EpollEvent EpollEvent;
+struct EpollEvent {
+	uint32	events;
+	uint32	_pad;
+	byte	data[8]; // to match amd64
+};
+#pragma pack off
diff --git a/src/pkg/runtime/defs_nacl_386.h b/src/runtime/defs_nacl_386.h
similarity index 100%
rename from src/pkg/runtime/defs_nacl_386.h
rename to src/runtime/defs_nacl_386.h
diff --git a/src/runtime/defs_nacl_amd64p32.h b/src/runtime/defs_nacl_amd64p32.h
new file mode 100644
index 0000000..45663d4
--- /dev/null
+++ b/src/runtime/defs_nacl_amd64p32.h
@@ -0,0 +1,90 @@
+// Copyright 2013 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Created by hand, not machine generated.
+
+enum
+{
+	// These values are referred to in the source code
+	// but really don't matter. Even so, use the standard numbers.
+	SIGSEGV = 11,
+	SIGPROF = 27,
+};
+
+typedef struct Siginfo Siginfo;
+
+
+// native_client/src/trusted/service_runtime/include/machine/_types.h
+typedef struct Timespec Timespec;
+
+struct Timespec
+{
+	int64 tv_sec;
+	int32 tv_nsec;
+};
+
+// native_client/src/trusted/service_runtime/nacl_exception.h
+// native_client/src/include/nacl/nacl_exception.h
+
+typedef struct ExcContext ExcContext;
+typedef struct ExcPortable ExcPortable;
+typedef struct ExcRegs386 ExcRegs386;
+typedef struct ExcRegsAmd64 ExcRegsAmd64;
+
+struct ExcRegs386
+{
+	uint32	eax;
+	uint32	ecx;
+	uint32	edx;
+	uint32	ebx;
+	uint32	esp;
+	uint32	ebp;
+	uint32	esi;
+	uint32	edi;
+	uint32	eip;
+	uint32	eflags;
+};
+
+struct ExcRegsAmd64
+{
+	uint64	rax;
+	uint64	rcx;
+	uint64	rdx;
+	uint64	rbx;
+	uint64	rsp;
+	uint64	rbp;
+	uint64	rsi;
+	uint64	rdi;
+	uint64	r8;
+	uint64	r9;
+	uint64	r10;
+	uint64	r11;
+	uint64	r12;
+	uint64	r13;
+	uint64	r14;
+	uint64	r15;
+	uint64	rip;
+	uint32	rflags;
+};
+
+struct ExcContext
+{
+	uint32	size;
+	uint32	portable_context_offset;
+	uint32	portable_context_size;
+	uint32	arch;
+	uint32	regs_size;
+	uint32	reserved[11];
+	union {
+		ExcRegs386	regs;
+		ExcRegsAmd64	regs64;
+	} regs;
+};
+
+struct ExcPortableContext
+{
+	uint32	pc;
+	uint32	sp;
+	uint32	fp;
+};
diff --git a/src/runtime/defs_nacl_arm.h b/src/runtime/defs_nacl_arm.h
new file mode 100644
index 0000000..9ce07cc
--- /dev/null
+++ b/src/runtime/defs_nacl_arm.h
@@ -0,0 +1,70 @@
+// 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.
+
+// Created by hand, not machine generated.
+
+enum
+{
+	// These values are referred to in the source code
+	// but really don't matter. Even so, use the standard numbers.
+	SIGSEGV = 11,
+	SIGPROF = 27,
+};
+
+typedef struct Siginfo Siginfo;
+
+// native_client/src/trusted/service_runtime/include/machine/_types.h
+typedef struct Timespec Timespec;
+
+struct Timespec
+{
+	int64 tv_sec;
+	int32 tv_nsec;
+};
+
+// native_client/src/trusted/service_runtime/nacl_exception.h
+// native_client/src/include/nacl/nacl_exception.h
+
+typedef struct ExcContext ExcContext;
+typedef struct ExcPortable ExcPortable;
+typedef struct ExcRegsARM ExcRegsARM;
+
+struct ExcRegsARM
+{
+	uint32	r0;
+	uint32	r1;
+	uint32	r2;
+	uint32	r3;
+	uint32	r4;
+	uint32	r5;
+	uint32	r6;
+	uint32	r7;
+	uint32	r8;
+	uint32	r9;	// the value reported here is undefined.
+	uint32	r10;
+	uint32	r11;
+	uint32	r12;
+	uint32	sp;	/* r13 */
+	uint32	lr;	/* r14 */
+	uint32	pc;	/* r15 */
+	uint32	cpsr;
+};
+
+struct ExcContext
+{
+	uint32	size;
+	uint32	portable_context_offset;
+	uint32	portable_context_size;
+	uint32	arch;
+	uint32	regs_size;
+	uint32	reserved[11];
+	ExcRegsARM	regs;
+};
+
+struct ExcPortableContext
+{
+	uint32	pc;
+	uint32	sp;
+	uint32	fp;
+};
diff --git a/src/runtime/defs_netbsd.go b/src/runtime/defs_netbsd.go
new file mode 100644
index 0000000..b27949e
--- /dev/null
+++ b/src/runtime/defs_netbsd.go
@@ -0,0 +1,125 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build ignore
+
+/*
+Input to cgo.
+
+GOARCH=amd64 go tool cgo -cdefs defs_netbsd.go defs_netbsd_amd64.go >defs_netbsd_amd64.h
+GOARCH=386 go tool cgo -cdefs defs_netbsd.go defs_netbsd_386.go >defs_netbsd_386.h
+GOARCH=arm go tool cgo -cdefs defs_netbsd.go defs_netbsd_arm.go >defs_netbsd_arm.h
+*/
+
+// +godefs map __fpregset_t [644]byte
+
+package runtime
+
+/*
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/signal.h>
+#include <sys/event.h>
+#include <sys/time.h>
+#include <sys/ucontext.h>
+#include <sys/unistd.h>
+#include <errno.h>
+#include <signal.h>
+*/
+import "C"
+
+const (
+	EINTR  = C.EINTR
+	EFAULT = C.EFAULT
+
+	PROT_NONE  = C.PROT_NONE
+	PROT_READ  = C.PROT_READ
+	PROT_WRITE = C.PROT_WRITE
+	PROT_EXEC  = C.PROT_EXEC
+
+	MAP_ANON    = C.MAP_ANON
+	MAP_PRIVATE = C.MAP_PRIVATE
+	MAP_FIXED   = C.MAP_FIXED
+
+	MADV_FREE = C.MADV_FREE
+
+	SA_SIGINFO = C.SA_SIGINFO
+	SA_RESTART = C.SA_RESTART
+	SA_ONSTACK = C.SA_ONSTACK
+
+	SIGHUP    = C.SIGHUP
+	SIGINT    = C.SIGINT
+	SIGQUIT   = C.SIGQUIT
+	SIGILL    = C.SIGILL
+	SIGTRAP   = C.SIGTRAP
+	SIGABRT   = C.SIGABRT
+	SIGEMT    = C.SIGEMT
+	SIGFPE    = C.SIGFPE
+	SIGKILL   = C.SIGKILL
+	SIGBUS    = C.SIGBUS
+	SIGSEGV   = C.SIGSEGV
+	SIGSYS    = C.SIGSYS
+	SIGPIPE   = C.SIGPIPE
+	SIGALRM   = C.SIGALRM
+	SIGTERM   = C.SIGTERM
+	SIGURG    = C.SIGURG
+	SIGSTOP   = C.SIGSTOP
+	SIGTSTP   = C.SIGTSTP
+	SIGCONT   = C.SIGCONT
+	SIGCHLD   = C.SIGCHLD
+	SIGTTIN   = C.SIGTTIN
+	SIGTTOU   = C.SIGTTOU
+	SIGIO     = C.SIGIO
+	SIGXCPU   = C.SIGXCPU
+	SIGXFSZ   = C.SIGXFSZ
+	SIGVTALRM = C.SIGVTALRM
+	SIGPROF   = C.SIGPROF
+	SIGWINCH  = C.SIGWINCH
+	SIGINFO   = C.SIGINFO
+	SIGUSR1   = C.SIGUSR1
+	SIGUSR2   = C.SIGUSR2
+
+	FPE_INTDIV = C.FPE_INTDIV
+	FPE_INTOVF = C.FPE_INTOVF
+	FPE_FLTDIV = C.FPE_FLTDIV
+	FPE_FLTOVF = C.FPE_FLTOVF
+	FPE_FLTUND = C.FPE_FLTUND
+	FPE_FLTRES = C.FPE_FLTRES
+	FPE_FLTINV = C.FPE_FLTINV
+	FPE_FLTSUB = C.FPE_FLTSUB
+
+	BUS_ADRALN = C.BUS_ADRALN
+	BUS_ADRERR = C.BUS_ADRERR
+	BUS_OBJERR = C.BUS_OBJERR
+
+	SEGV_MAPERR = C.SEGV_MAPERR
+	SEGV_ACCERR = C.SEGV_ACCERR
+
+	ITIMER_REAL    = C.ITIMER_REAL
+	ITIMER_VIRTUAL = C.ITIMER_VIRTUAL
+	ITIMER_PROF    = C.ITIMER_PROF
+
+	EV_ADD       = C.EV_ADD
+	EV_DELETE    = C.EV_DELETE
+	EV_CLEAR     = C.EV_CLEAR
+	EV_RECEIPT   = 0
+	EV_ERROR     = C.EV_ERROR
+	EVFILT_READ  = C.EVFILT_READ
+	EVFILT_WRITE = C.EVFILT_WRITE
+)
+
+type SigaltstackT C.struct_sigaltstack
+type Sigset C.sigset_t
+type Siginfo C.struct__ksiginfo
+
+type StackT C.stack_t
+
+type Timespec C.struct_timespec
+type Timeval C.struct_timeval
+type Itimerval C.struct_itimerval
+
+type McontextT C.mcontext_t
+type UcontextT C.ucontext_t
+
+type Kevent C.struct_kevent
diff --git a/src/pkg/runtime/defs_netbsd_386.go b/src/runtime/defs_netbsd_386.go
similarity index 100%
rename from src/pkg/runtime/defs_netbsd_386.go
rename to src/runtime/defs_netbsd_386.go
diff --git a/src/runtime/defs_netbsd_386.h b/src/runtime/defs_netbsd_386.h
new file mode 100644
index 0000000..fd87804
--- /dev/null
+++ b/src/runtime/defs_netbsd_386.h
@@ -0,0 +1,182 @@
+// Created by cgo -cdefs - DO NOT EDIT
+// cgo -cdefs defs_netbsd.go defs_netbsd_386.go
+
+
+enum {
+	EINTR	= 0x4,
+	EFAULT	= 0xe,
+
+	PROT_NONE	= 0x0,
+	PROT_READ	= 0x1,
+	PROT_WRITE	= 0x2,
+	PROT_EXEC	= 0x4,
+
+	MAP_ANON	= 0x1000,
+	MAP_PRIVATE	= 0x2,
+	MAP_FIXED	= 0x10,
+
+	MADV_FREE	= 0x6,
+
+	SA_SIGINFO	= 0x40,
+	SA_RESTART	= 0x2,
+	SA_ONSTACK	= 0x1,
+
+	SIGHUP		= 0x1,
+	SIGINT		= 0x2,
+	SIGQUIT		= 0x3,
+	SIGILL		= 0x4,
+	SIGTRAP		= 0x5,
+	SIGABRT		= 0x6,
+	SIGEMT		= 0x7,
+	SIGFPE		= 0x8,
+	SIGKILL		= 0x9,
+	SIGBUS		= 0xa,
+	SIGSEGV		= 0xb,
+	SIGSYS		= 0xc,
+	SIGPIPE		= 0xd,
+	SIGALRM		= 0xe,
+	SIGTERM		= 0xf,
+	SIGURG		= 0x10,
+	SIGSTOP		= 0x11,
+	SIGTSTP		= 0x12,
+	SIGCONT		= 0x13,
+	SIGCHLD		= 0x14,
+	SIGTTIN		= 0x15,
+	SIGTTOU		= 0x16,
+	SIGIO		= 0x17,
+	SIGXCPU		= 0x18,
+	SIGXFSZ		= 0x19,
+	SIGVTALRM	= 0x1a,
+	SIGPROF		= 0x1b,
+	SIGWINCH	= 0x1c,
+	SIGINFO		= 0x1d,
+	SIGUSR1		= 0x1e,
+	SIGUSR2		= 0x1f,
+
+	FPE_INTDIV	= 0x1,
+	FPE_INTOVF	= 0x2,
+	FPE_FLTDIV	= 0x3,
+	FPE_FLTOVF	= 0x4,
+	FPE_FLTUND	= 0x5,
+	FPE_FLTRES	= 0x6,
+	FPE_FLTINV	= 0x7,
+	FPE_FLTSUB	= 0x8,
+
+	BUS_ADRALN	= 0x1,
+	BUS_ADRERR	= 0x2,
+	BUS_OBJERR	= 0x3,
+
+	SEGV_MAPERR	= 0x1,
+	SEGV_ACCERR	= 0x2,
+
+	ITIMER_REAL	= 0x0,
+	ITIMER_VIRTUAL	= 0x1,
+	ITIMER_PROF	= 0x2,
+
+	EV_ADD		= 0x1,
+	EV_DELETE	= 0x2,
+	EV_CLEAR	= 0x20,
+	EV_RECEIPT	= 0,
+	EV_ERROR	= 0x4000,
+	EVFILT_READ	= 0x0,
+	EVFILT_WRITE	= 0x1,
+};
+
+typedef struct SigaltstackT SigaltstackT;
+typedef struct Sigset Sigset;
+typedef struct Siginfo Siginfo;
+typedef struct StackT StackT;
+typedef struct Timespec Timespec;
+typedef struct Timeval Timeval;
+typedef struct Itimerval Itimerval;
+typedef struct McontextT McontextT;
+typedef struct UcontextT UcontextT;
+typedef struct KeventT KeventT;
+
+#pragma pack on
+
+struct SigaltstackT {
+	byte	*ss_sp;
+	uint32	ss_size;
+	int32	ss_flags;
+};
+struct Sigset {
+	uint32	__bits[4];
+};
+struct Siginfo {
+	int32	_signo;
+	int32	_code;
+	int32	_errno;
+	byte	_reason[20];
+};
+
+struct StackT {
+	byte	*ss_sp;
+	uint32	ss_size;
+	int32	ss_flags;
+};
+
+struct Timespec {
+	int64	tv_sec;
+	int32	tv_nsec;
+};
+struct Timeval {
+	int64	tv_sec;
+	int32	tv_usec;
+};
+struct Itimerval {
+	Timeval	it_interval;
+	Timeval	it_value;
+};
+
+struct McontextT {
+	int32	__gregs[19];
+	byte	__fpregs[644];
+	int32	_mc_tlsbase;
+};
+struct UcontextT {
+	uint32	uc_flags;
+	UcontextT	*uc_link;
+	Sigset	uc_sigmask;
+	StackT	uc_stack;
+	McontextT	uc_mcontext;
+	int32	__uc_pad[4];
+};
+
+struct KeventT {
+	uint32	ident;
+	uint32	filter;
+	uint32	flags;
+	uint32	fflags;
+	int64	data;
+	byte	*udata;
+};
+
+
+#pragma pack off
+// Created by cgo -cdefs - DO NOT EDIT
+// cgo -cdefs defs_netbsd.go defs_netbsd_386.go
+
+
+enum {
+	REG_GS		= 0x0,
+	REG_FS		= 0x1,
+	REG_ES		= 0x2,
+	REG_DS		= 0x3,
+	REG_EDI		= 0x4,
+	REG_ESI		= 0x5,
+	REG_EBP		= 0x6,
+	REG_ESP		= 0x7,
+	REG_EBX		= 0x8,
+	REG_EDX		= 0x9,
+	REG_ECX		= 0xa,
+	REG_EAX		= 0xb,
+	REG_TRAPNO	= 0xc,
+	REG_ERR		= 0xd,
+	REG_EIP		= 0xe,
+	REG_CS		= 0xf,
+	REG_EFL		= 0x10,
+	REG_UESP	= 0x11,
+	REG_SS		= 0x12,
+};
+
diff --git a/src/pkg/runtime/defs_netbsd_amd64.go b/src/runtime/defs_netbsd_amd64.go
similarity index 100%
rename from src/pkg/runtime/defs_netbsd_amd64.go
rename to src/runtime/defs_netbsd_amd64.go
diff --git a/src/runtime/defs_netbsd_amd64.h b/src/runtime/defs_netbsd_amd64.h
new file mode 100644
index 0000000..dac94b1
--- /dev/null
+++ b/src/runtime/defs_netbsd_amd64.h
@@ -0,0 +1,194 @@
+// Created by cgo -cdefs - DO NOT EDIT
+// cgo -cdefs defs_netbsd.go defs_netbsd_amd64.go
+
+
+enum {
+	EINTR	= 0x4,
+	EFAULT	= 0xe,
+
+	PROT_NONE	= 0x0,
+	PROT_READ	= 0x1,
+	PROT_WRITE	= 0x2,
+	PROT_EXEC	= 0x4,
+
+	MAP_ANON	= 0x1000,
+	MAP_PRIVATE	= 0x2,
+	MAP_FIXED	= 0x10,
+
+	MADV_FREE	= 0x6,
+
+	SA_SIGINFO	= 0x40,
+	SA_RESTART	= 0x2,
+	SA_ONSTACK	= 0x1,
+
+	SIGHUP		= 0x1,
+	SIGINT		= 0x2,
+	SIGQUIT		= 0x3,
+	SIGILL		= 0x4,
+	SIGTRAP		= 0x5,
+	SIGABRT		= 0x6,
+	SIGEMT		= 0x7,
+	SIGFPE		= 0x8,
+	SIGKILL		= 0x9,
+	SIGBUS		= 0xa,
+	SIGSEGV		= 0xb,
+	SIGSYS		= 0xc,
+	SIGPIPE		= 0xd,
+	SIGALRM		= 0xe,
+	SIGTERM		= 0xf,
+	SIGURG		= 0x10,
+	SIGSTOP		= 0x11,
+	SIGTSTP		= 0x12,
+	SIGCONT		= 0x13,
+	SIGCHLD		= 0x14,
+	SIGTTIN		= 0x15,
+	SIGTTOU		= 0x16,
+	SIGIO		= 0x17,
+	SIGXCPU		= 0x18,
+	SIGXFSZ		= 0x19,
+	SIGVTALRM	= 0x1a,
+	SIGPROF		= 0x1b,
+	SIGWINCH	= 0x1c,
+	SIGINFO		= 0x1d,
+	SIGUSR1		= 0x1e,
+	SIGUSR2		= 0x1f,
+
+	FPE_INTDIV	= 0x1,
+	FPE_INTOVF	= 0x2,
+	FPE_FLTDIV	= 0x3,
+	FPE_FLTOVF	= 0x4,
+	FPE_FLTUND	= 0x5,
+	FPE_FLTRES	= 0x6,
+	FPE_FLTINV	= 0x7,
+	FPE_FLTSUB	= 0x8,
+
+	BUS_ADRALN	= 0x1,
+	BUS_ADRERR	= 0x2,
+	BUS_OBJERR	= 0x3,
+
+	SEGV_MAPERR	= 0x1,
+	SEGV_ACCERR	= 0x2,
+
+	ITIMER_REAL	= 0x0,
+	ITIMER_VIRTUAL	= 0x1,
+	ITIMER_PROF	= 0x2,
+
+	EV_ADD		= 0x1,
+	EV_DELETE	= 0x2,
+	EV_CLEAR	= 0x20,
+	EV_RECEIPT	= 0,
+	EV_ERROR	= 0x4000,
+	EVFILT_READ	= 0x0,
+	EVFILT_WRITE	= 0x1,
+};
+
+typedef struct SigaltstackT SigaltstackT;
+typedef struct Sigset Sigset;
+typedef struct Siginfo Siginfo;
+typedef struct StackT StackT;
+typedef struct Timespec Timespec;
+typedef struct Timeval Timeval;
+typedef struct Itimerval Itimerval;
+typedef struct McontextT McontextT;
+typedef struct UcontextT UcontextT;
+typedef struct KeventT KeventT;
+
+#pragma pack on
+
+struct SigaltstackT {
+	byte	*ss_sp;
+	uint64	ss_size;
+	int32	ss_flags;
+	byte	Pad_cgo_0[4];
+};
+struct Sigset {
+	uint32	__bits[4];
+};
+struct Siginfo {
+	int32	_signo;
+	int32	_code;
+	int32	_errno;
+	int32	_pad;
+	byte	_reason[24];
+};
+
+struct StackT {
+	byte	*ss_sp;
+	uint64	ss_size;
+	int32	ss_flags;
+	byte	Pad_cgo_0[4];
+};
+
+struct Timespec {
+	int64	tv_sec;
+	int64	tv_nsec;
+};
+struct Timeval {
+	int64	tv_sec;
+	int32	tv_usec;
+	byte	Pad_cgo_0[4];
+};
+struct Itimerval {
+	Timeval	it_interval;
+	Timeval	it_value;
+};
+
+struct McontextT {
+	uint64	__gregs[26];
+	uint64	_mc_tlsbase;
+	int8	__fpregs[512];
+};
+struct UcontextT {
+	uint32	uc_flags;
+	byte	Pad_cgo_0[4];
+	UcontextT	*uc_link;
+	Sigset	uc_sigmask;
+	StackT	uc_stack;
+	McontextT	uc_mcontext;
+};
+
+struct KeventT {
+	uint64	ident;
+	uint32	filter;
+	uint32	flags;
+	uint32	fflags;
+	byte	Pad_cgo_0[4];
+	int64	data;
+	byte	*udata;
+};
+
+
+#pragma pack off
+// Created by cgo -cdefs - DO NOT EDIT
+// cgo -cdefs defs_netbsd.go defs_netbsd_amd64.go
+
+
+enum {
+	REG_RDI		= 0x0,
+	REG_RSI		= 0x1,
+	REG_RDX		= 0x2,
+	REG_RCX		= 0x3,
+	REG_R8		= 0x4,
+	REG_R9		= 0x5,
+	REG_R10		= 0x6,
+	REG_R11		= 0x7,
+	REG_R12		= 0x8,
+	REG_R13		= 0x9,
+	REG_R14		= 0xa,
+	REG_R15		= 0xb,
+	REG_RBP		= 0xc,
+	REG_RBX		= 0xd,
+	REG_RAX		= 0xe,
+	REG_GS		= 0xf,
+	REG_FS		= 0x10,
+	REG_ES		= 0x11,
+	REG_DS		= 0x12,
+	REG_TRAPNO	= 0x13,
+	REG_ERR		= 0x14,
+	REG_RIP		= 0x15,
+	REG_CS		= 0x16,
+	REG_RFLAGS	= 0x17,
+	REG_RSP		= 0x18,
+	REG_SS		= 0x19,
+};
+
diff --git a/src/pkg/runtime/defs_netbsd_arm.go b/src/runtime/defs_netbsd_arm.go
similarity index 100%
rename from src/pkg/runtime/defs_netbsd_arm.go
rename to src/runtime/defs_netbsd_arm.go
diff --git a/src/runtime/defs_netbsd_arm.h b/src/runtime/defs_netbsd_arm.h
new file mode 100644
index 0000000..70f34af
--- /dev/null
+++ b/src/runtime/defs_netbsd_arm.h
@@ -0,0 +1,184 @@
+// Created by cgo -cdefs - DO NOT EDIT
+// cgo -cdefs defs_netbsd.go defs_netbsd_arm.go
+
+
+enum {
+	EINTR	= 0x4,
+	EFAULT	= 0xe,
+
+	PROT_NONE	= 0x0,
+	PROT_READ	= 0x1,
+	PROT_WRITE	= 0x2,
+	PROT_EXEC	= 0x4,
+
+	MAP_ANON	= 0x1000,
+	MAP_PRIVATE	= 0x2,
+	MAP_FIXED	= 0x10,
+
+	MADV_FREE	= 0x6,
+
+	SA_SIGINFO	= 0x40,
+	SA_RESTART	= 0x2,
+	SA_ONSTACK	= 0x1,
+
+	SIGHUP		= 0x1,
+	SIGINT		= 0x2,
+	SIGQUIT		= 0x3,
+	SIGILL		= 0x4,
+	SIGTRAP		= 0x5,
+	SIGABRT		= 0x6,
+	SIGEMT		= 0x7,
+	SIGFPE		= 0x8,
+	SIGKILL		= 0x9,
+	SIGBUS		= 0xa,
+	SIGSEGV		= 0xb,
+	SIGSYS		= 0xc,
+	SIGPIPE		= 0xd,
+	SIGALRM		= 0xe,
+	SIGTERM		= 0xf,
+	SIGURG		= 0x10,
+	SIGSTOP		= 0x11,
+	SIGTSTP		= 0x12,
+	SIGCONT		= 0x13,
+	SIGCHLD		= 0x14,
+	SIGTTIN		= 0x15,
+	SIGTTOU		= 0x16,
+	SIGIO		= 0x17,
+	SIGXCPU		= 0x18,
+	SIGXFSZ		= 0x19,
+	SIGVTALRM	= 0x1a,
+	SIGPROF		= 0x1b,
+	SIGWINCH	= 0x1c,
+	SIGINFO		= 0x1d,
+	SIGUSR1		= 0x1e,
+	SIGUSR2		= 0x1f,
+
+	FPE_INTDIV	= 0x1,
+	FPE_INTOVF	= 0x2,
+	FPE_FLTDIV	= 0x3,
+	FPE_FLTOVF	= 0x4,
+	FPE_FLTUND	= 0x5,
+	FPE_FLTRES	= 0x6,
+	FPE_FLTINV	= 0x7,
+	FPE_FLTSUB	= 0x8,
+
+	BUS_ADRALN	= 0x1,
+	BUS_ADRERR	= 0x2,
+	BUS_OBJERR	= 0x3,
+
+	SEGV_MAPERR	= 0x1,
+	SEGV_ACCERR	= 0x2,
+
+	ITIMER_REAL	= 0x0,
+	ITIMER_VIRTUAL	= 0x1,
+	ITIMER_PROF	= 0x2,
+
+	EV_ADD		= 0x1,
+	EV_DELETE	= 0x2,
+	EV_CLEAR	= 0x20,
+	EV_RECEIPT	= 0,
+	EV_ERROR	= 0x4000,
+	EVFILT_READ	= 0x0,
+	EVFILT_WRITE	= 0x1,
+};
+
+typedef struct SigaltstackT SigaltstackT;
+typedef struct Sigset Sigset;
+typedef struct Siginfo Siginfo;
+typedef struct StackT StackT;
+typedef struct Timespec Timespec;
+typedef struct Timeval Timeval;
+typedef struct Itimerval Itimerval;
+typedef struct McontextT McontextT;
+typedef struct UcontextT UcontextT;
+typedef struct KeventT KeventT;
+
+#pragma pack on
+
+struct SigaltstackT {
+	byte	*ss_sp;
+	uint32	ss_size;
+	int32	ss_flags;
+};
+struct Sigset {
+	uint32	__bits[4];
+};
+struct Siginfo {
+	int32	_signo;
+	int32	_code;
+	int32	_errno;
+	byte	_reason[20];
+};
+
+struct StackT {
+	byte	*ss_sp;
+	uint32	ss_size;
+	int32	ss_flags;
+};
+
+struct Timespec {
+	int64	tv_sec;
+	int32	tv_nsec;
+};
+struct Timeval {
+	int64	tv_sec;
+	int32	tv_usec;
+};
+struct Itimerval {
+	Timeval	it_interval;
+	Timeval	it_value;
+};
+
+struct McontextT {
+	uint32	__gregs[17];
+#ifdef __ARM_EABI__
+	byte	__fpu[4+8*32+4];
+#else
+	byte	__fpu[4+4*33+4];
+#endif
+	uint32	_mc_tlsbase;
+};
+struct UcontextT {
+	uint32	uc_flags;
+	UcontextT	*uc_link;
+	Sigset	uc_sigmask;
+	StackT	uc_stack;
+	McontextT	uc_mcontext;
+	int32	__uc_pad[2];
+};
+
+struct KeventT {
+	uint32	ident;
+	uint32	filter;
+	uint32	flags;
+	uint32	fflags;
+	int64	data;
+	byte	*udata;
+};
+
+
+#pragma pack off
+// Created by cgo -cdefs - DO NOT EDIT
+// cgo -cdefs defs_netbsd.go defs_netbsd_arm.go
+
+
+enum {
+	REG_R0		= 0x0,
+	REG_R1		= 0x1,
+	REG_R2		= 0x2,
+	REG_R3		= 0x3,
+	REG_R4		= 0x4,
+	REG_R5		= 0x5,
+	REG_R6		= 0x6,
+	REG_R7		= 0x7,
+	REG_R8		= 0x8,
+	REG_R9		= 0x9,
+	REG_R10		= 0xa,
+	REG_R11		= 0xb,
+	REG_R12		= 0xc,
+	REG_R13		= 0xd,
+	REG_R14		= 0xe,
+	REG_R15		= 0xf,
+	REG_CPSR	= 0x10,
+};
+
diff --git a/src/runtime/defs_openbsd.go b/src/runtime/defs_openbsd.go
new file mode 100644
index 0000000..39224c9
--- /dev/null
+++ b/src/runtime/defs_openbsd.go
@@ -0,0 +1,121 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build ignore
+
+/*
+Input to cgo.
+
+GOARCH=amd64 go tool cgo -cdefs defs_openbsd.go >defs_openbsd_amd64.h
+GOARCH=386 go tool cgo -cdefs defs_openbsd.go >defs_openbsd_386.h
+*/
+
+package runtime
+
+/*
+#include <sys/types.h>
+#include <sys/event.h>
+#include <sys/mman.h>
+#include <sys/time.h>
+#include <sys/unistd.h>
+#include <sys/signal.h>
+#include <errno.h>
+#include <signal.h>
+*/
+import "C"
+
+const (
+	EINTR  = C.EINTR
+	EFAULT = C.EFAULT
+
+	PROT_NONE  = C.PROT_NONE
+	PROT_READ  = C.PROT_READ
+	PROT_WRITE = C.PROT_WRITE
+	PROT_EXEC  = C.PROT_EXEC
+
+	MAP_ANON    = C.MAP_ANON
+	MAP_PRIVATE = C.MAP_PRIVATE
+	MAP_FIXED   = C.MAP_FIXED
+
+	MADV_FREE = C.MADV_FREE
+
+	SA_SIGINFO = C.SA_SIGINFO
+	SA_RESTART = C.SA_RESTART
+	SA_ONSTACK = C.SA_ONSTACK
+
+	SIGHUP    = C.SIGHUP
+	SIGINT    = C.SIGINT
+	SIGQUIT   = C.SIGQUIT
+	SIGILL    = C.SIGILL
+	SIGTRAP   = C.SIGTRAP
+	SIGABRT   = C.SIGABRT
+	SIGEMT    = C.SIGEMT
+	SIGFPE    = C.SIGFPE
+	SIGKILL   = C.SIGKILL
+	SIGBUS    = C.SIGBUS
+	SIGSEGV   = C.SIGSEGV
+	SIGSYS    = C.SIGSYS
+	SIGPIPE   = C.SIGPIPE
+	SIGALRM   = C.SIGALRM
+	SIGTERM   = C.SIGTERM
+	SIGURG    = C.SIGURG
+	SIGSTOP   = C.SIGSTOP
+	SIGTSTP   = C.SIGTSTP
+	SIGCONT   = C.SIGCONT
+	SIGCHLD   = C.SIGCHLD
+	SIGTTIN   = C.SIGTTIN
+	SIGTTOU   = C.SIGTTOU
+	SIGIO     = C.SIGIO
+	SIGXCPU   = C.SIGXCPU
+	SIGXFSZ   = C.SIGXFSZ
+	SIGVTALRM = C.SIGVTALRM
+	SIGPROF   = C.SIGPROF
+	SIGWINCH  = C.SIGWINCH
+	SIGINFO   = C.SIGINFO
+	SIGUSR1   = C.SIGUSR1
+	SIGUSR2   = C.SIGUSR2
+
+	FPE_INTDIV = C.FPE_INTDIV
+	FPE_INTOVF = C.FPE_INTOVF
+	FPE_FLTDIV = C.FPE_FLTDIV
+	FPE_FLTOVF = C.FPE_FLTOVF
+	FPE_FLTUND = C.FPE_FLTUND
+	FPE_FLTRES = C.FPE_FLTRES
+	FPE_FLTINV = C.FPE_FLTINV
+	FPE_FLTSUB = C.FPE_FLTSUB
+
+	BUS_ADRALN = C.BUS_ADRALN
+	BUS_ADRERR = C.BUS_ADRERR
+	BUS_OBJERR = C.BUS_OBJERR
+
+	SEGV_MAPERR = C.SEGV_MAPERR
+	SEGV_ACCERR = C.SEGV_ACCERR
+
+	ITIMER_REAL    = C.ITIMER_REAL
+	ITIMER_VIRTUAL = C.ITIMER_VIRTUAL
+	ITIMER_PROF    = C.ITIMER_PROF
+
+	EV_ADD       = C.EV_ADD
+	EV_DELETE    = C.EV_DELETE
+	EV_CLEAR     = C.EV_CLEAR
+	EV_ERROR     = C.EV_ERROR
+	EVFILT_READ  = C.EVFILT_READ
+	EVFILT_WRITE = C.EVFILT_WRITE
+)
+
+type TforkT C.struct___tfork
+
+type SigaltstackT C.struct_sigaltstack
+type Sigcontext C.struct_sigcontext
+type Siginfo C.siginfo_t
+type Sigset C.sigset_t
+type Sigval C.union_sigval
+
+type StackT C.stack_t
+
+type Timespec C.struct_timespec
+type Timeval C.struct_timeval
+type Itimerval C.struct_itimerval
+
+type KeventT C.struct_kevent
diff --git a/src/runtime/defs_openbsd_386.h b/src/runtime/defs_openbsd_386.h
new file mode 100644
index 0000000..6b77e00
--- /dev/null
+++ b/src/runtime/defs_openbsd_386.h
@@ -0,0 +1,168 @@
+// Created by cgo -cdefs - DO NOT EDIT
+// cgo -cdefs defs_openbsd.go
+
+
+enum {
+	EINTR	= 0x4,
+	EFAULT	= 0xe,
+
+	PROT_NONE	= 0x0,
+	PROT_READ	= 0x1,
+	PROT_WRITE	= 0x2,
+	PROT_EXEC	= 0x4,
+
+	MAP_ANON	= 0x1000,
+	MAP_PRIVATE	= 0x2,
+	MAP_FIXED	= 0x10,
+
+	MADV_FREE	= 0x6,
+
+	SA_SIGINFO	= 0x40,
+	SA_RESTART	= 0x2,
+	SA_ONSTACK	= 0x1,
+
+	SIGHUP		= 0x1,
+	SIGINT		= 0x2,
+	SIGQUIT		= 0x3,
+	SIGILL		= 0x4,
+	SIGTRAP		= 0x5,
+	SIGABRT		= 0x6,
+	SIGEMT		= 0x7,
+	SIGFPE		= 0x8,
+	SIGKILL		= 0x9,
+	SIGBUS		= 0xa,
+	SIGSEGV		= 0xb,
+	SIGSYS		= 0xc,
+	SIGPIPE		= 0xd,
+	SIGALRM		= 0xe,
+	SIGTERM		= 0xf,
+	SIGURG		= 0x10,
+	SIGSTOP		= 0x11,
+	SIGTSTP		= 0x12,
+	SIGCONT		= 0x13,
+	SIGCHLD		= 0x14,
+	SIGTTIN		= 0x15,
+	SIGTTOU		= 0x16,
+	SIGIO		= 0x17,
+	SIGXCPU		= 0x18,
+	SIGXFSZ		= 0x19,
+	SIGVTALRM	= 0x1a,
+	SIGPROF		= 0x1b,
+	SIGWINCH	= 0x1c,
+	SIGINFO		= 0x1d,
+	SIGUSR1		= 0x1e,
+	SIGUSR2		= 0x1f,
+
+	FPE_INTDIV	= 0x1,
+	FPE_INTOVF	= 0x2,
+	FPE_FLTDIV	= 0x3,
+	FPE_FLTOVF	= 0x4,
+	FPE_FLTUND	= 0x5,
+	FPE_FLTRES	= 0x6,
+	FPE_FLTINV	= 0x7,
+	FPE_FLTSUB	= 0x8,
+
+	BUS_ADRALN	= 0x1,
+	BUS_ADRERR	= 0x2,
+	BUS_OBJERR	= 0x3,
+
+	SEGV_MAPERR	= 0x1,
+	SEGV_ACCERR	= 0x2,
+
+	ITIMER_REAL	= 0x0,
+	ITIMER_VIRTUAL	= 0x1,
+	ITIMER_PROF	= 0x2,
+
+	EV_ADD		= 0x1,
+	EV_DELETE	= 0x2,
+	EV_CLEAR	= 0x20,
+	EV_ERROR	= 0x4000,
+	EVFILT_READ	= -0x1,
+	EVFILT_WRITE	= -0x2,
+};
+
+typedef struct TforkT TforkT;
+typedef struct SigaltstackT SigaltstackT;
+typedef struct Sigcontext Sigcontext;
+typedef struct Siginfo Siginfo;
+typedef struct StackT StackT;
+typedef struct Timespec Timespec;
+typedef struct Timeval Timeval;
+typedef struct Itimerval Itimerval;
+typedef struct KeventT KeventT;
+
+#pragma pack on
+
+struct TforkT {
+	byte	*tf_tcb;
+	int32	*tf_tid;
+	byte	*tf_stack;
+};
+
+struct SigaltstackT {
+	byte	*ss_sp;
+	uint32	ss_size;
+	int32	ss_flags;
+};
+struct Sigcontext {
+	int32	sc_gs;
+	int32	sc_fs;
+	int32	sc_es;
+	int32	sc_ds;
+	int32	sc_edi;
+	int32	sc_esi;
+	int32	sc_ebp;
+	int32	sc_ebx;
+	int32	sc_edx;
+	int32	sc_ecx;
+	int32	sc_eax;
+	int32	sc_eip;
+	int32	sc_cs;
+	int32	sc_eflags;
+	int32	sc_esp;
+	int32	sc_ss;
+	int32	__sc_unused;
+	int32	sc_mask;
+	int32	sc_trapno;
+	int32	sc_err;
+	void	*sc_fpstate;
+};
+struct Siginfo {
+	int32	si_signo;
+	int32	si_code;
+	int32	si_errno;
+	byte	_data[116];
+};
+typedef	uint32	Sigset;
+typedef	byte	Sigval[4];
+
+struct StackT {
+	byte	*ss_sp;
+	uint32	ss_size;
+	int32	ss_flags;
+};
+
+struct Timespec {
+	int64	tv_sec;
+	int32	tv_nsec;
+};
+struct Timeval {
+	int64	tv_sec;
+	int32	tv_usec;
+};
+struct Itimerval {
+	Timeval	it_interval;
+	Timeval	it_value;
+};
+
+struct KeventT {
+	uint32	ident;
+	int16	filter;
+	uint16	flags;
+	uint32	fflags;
+	int64	data;
+	byte	*udata;
+};
+
+
+#pragma pack off
diff --git a/src/runtime/defs_openbsd_amd64.h b/src/runtime/defs_openbsd_amd64.h
new file mode 100644
index 0000000..761e8e4
--- /dev/null
+++ b/src/runtime/defs_openbsd_amd64.h
@@ -0,0 +1,179 @@
+// Created by cgo -cdefs - DO NOT EDIT
+// cgo -cdefs defs_openbsd.go
+
+
+enum {
+	EINTR	= 0x4,
+	EFAULT	= 0xe,
+
+	PROT_NONE	= 0x0,
+	PROT_READ	= 0x1,
+	PROT_WRITE	= 0x2,
+	PROT_EXEC	= 0x4,
+
+	MAP_ANON	= 0x1000,
+	MAP_PRIVATE	= 0x2,
+	MAP_FIXED	= 0x10,
+
+	MADV_FREE	= 0x6,
+
+	SA_SIGINFO	= 0x40,
+	SA_RESTART	= 0x2,
+	SA_ONSTACK	= 0x1,
+
+	SIGHUP		= 0x1,
+	SIGINT		= 0x2,
+	SIGQUIT		= 0x3,
+	SIGILL		= 0x4,
+	SIGTRAP		= 0x5,
+	SIGABRT		= 0x6,
+	SIGEMT		= 0x7,
+	SIGFPE		= 0x8,
+	SIGKILL		= 0x9,
+	SIGBUS		= 0xa,
+	SIGSEGV		= 0xb,
+	SIGSYS		= 0xc,
+	SIGPIPE		= 0xd,
+	SIGALRM		= 0xe,
+	SIGTERM		= 0xf,
+	SIGURG		= 0x10,
+	SIGSTOP		= 0x11,
+	SIGTSTP		= 0x12,
+	SIGCONT		= 0x13,
+	SIGCHLD		= 0x14,
+	SIGTTIN		= 0x15,
+	SIGTTOU		= 0x16,
+	SIGIO		= 0x17,
+	SIGXCPU		= 0x18,
+	SIGXFSZ		= 0x19,
+	SIGVTALRM	= 0x1a,
+	SIGPROF		= 0x1b,
+	SIGWINCH	= 0x1c,
+	SIGINFO		= 0x1d,
+	SIGUSR1		= 0x1e,
+	SIGUSR2		= 0x1f,
+
+	FPE_INTDIV	= 0x1,
+	FPE_INTOVF	= 0x2,
+	FPE_FLTDIV	= 0x3,
+	FPE_FLTOVF	= 0x4,
+	FPE_FLTUND	= 0x5,
+	FPE_FLTRES	= 0x6,
+	FPE_FLTINV	= 0x7,
+	FPE_FLTSUB	= 0x8,
+
+	BUS_ADRALN	= 0x1,
+	BUS_ADRERR	= 0x2,
+	BUS_OBJERR	= 0x3,
+
+	SEGV_MAPERR	= 0x1,
+	SEGV_ACCERR	= 0x2,
+
+	ITIMER_REAL	= 0x0,
+	ITIMER_VIRTUAL	= 0x1,
+	ITIMER_PROF	= 0x2,
+
+	EV_ADD		= 0x1,
+	EV_DELETE	= 0x2,
+	EV_CLEAR	= 0x20,
+	EV_ERROR	= 0x4000,
+	EVFILT_READ	= -0x1,
+	EVFILT_WRITE	= -0x2,
+};
+
+typedef struct TforkT TforkT;
+typedef struct SigaltstackT SigaltstackT;
+typedef struct Sigcontext Sigcontext;
+typedef struct Siginfo Siginfo;
+typedef struct StackT StackT;
+typedef struct Timespec Timespec;
+typedef struct Timeval Timeval;
+typedef struct Itimerval Itimerval;
+typedef struct KeventT KeventT;
+
+#pragma pack on
+
+struct TforkT {
+	byte	*tf_tcb;
+	int32	*tf_tid;
+	byte	*tf_stack;
+};
+
+struct SigaltstackT {
+	byte	*ss_sp;
+	uint64	ss_size;
+	int32	ss_flags;
+	byte	Pad_cgo_0[4];
+};
+struct Sigcontext {
+	int64	sc_rdi;
+	int64	sc_rsi;
+	int64	sc_rdx;
+	int64	sc_rcx;
+	int64	sc_r8;
+	int64	sc_r9;
+	int64	sc_r10;
+	int64	sc_r11;
+	int64	sc_r12;
+	int64	sc_r13;
+	int64	sc_r14;
+	int64	sc_r15;
+	int64	sc_rbp;
+	int64	sc_rbx;
+	int64	sc_rax;
+	int64	sc_gs;
+	int64	sc_fs;
+	int64	sc_es;
+	int64	sc_ds;
+	int64	sc_trapno;
+	int64	sc_err;
+	int64	sc_rip;
+	int64	sc_cs;
+	int64	sc_rflags;
+	int64	sc_rsp;
+	int64	sc_ss;
+	void	*sc_fpstate;
+	int32	__sc_unused;
+	int32	sc_mask;
+};
+struct Siginfo {
+	int32	si_signo;
+	int32	si_code;
+	int32	si_errno;
+	byte	Pad_cgo_0[4];
+	byte	_data[120];
+};
+typedef	uint32	Sigset;
+typedef	byte	Sigval[8];
+
+struct StackT {
+	byte	*ss_sp;
+	uint64	ss_size;
+	int32	ss_flags;
+	byte	Pad_cgo_0[4];
+};
+
+struct Timespec {
+	int64	tv_sec;
+	int64	tv_nsec;
+};
+struct Timeval {
+	int64	tv_sec;
+	int64	tv_usec;
+};
+struct Itimerval {
+	Timeval	it_interval;
+	Timeval	it_value;
+};
+
+struct KeventT {
+	uint64	ident;
+	int16	filter;
+	uint16	flags;
+	uint32	fflags;
+	int64	data;
+	byte	*udata;
+};
+
+
+#pragma pack off
diff --git a/src/runtime/defs_plan9_386.h b/src/runtime/defs_plan9_386.h
new file mode 100644
index 0000000..a762b85
--- /dev/null
+++ b/src/runtime/defs_plan9_386.h
@@ -0,0 +1,26 @@
+#define PAGESIZE 0x1000
+
+typedef struct Ureg Ureg;
+
+struct Ureg
+{
+	uint32	di;		/* general registers */
+	uint32	si;		/* ... */
+	uint32	bp;		/* ... */
+	uint32	nsp;
+	uint32	bx;		/* ... */
+	uint32	dx;		/* ... */
+	uint32	cx;		/* ... */
+	uint32	ax;		/* ... */
+	uint32	gs;		/* data segments */
+	uint32	fs;		/* ... */
+	uint32	es;		/* ... */
+	uint32	ds;		/* ... */
+	uint32	trap;		/* trap type */
+	uint32	ecode;		/* error code (or zero) */
+	uint32	pc;		/* pc */
+	uint32	cs;		/* old context */
+	uint32	flags;		/* old flags */
+	uint32	sp;
+	uint32	ss;		/* old stack segment */
+};
diff --git a/src/runtime/defs_plan9_amd64.h b/src/runtime/defs_plan9_amd64.h
new file mode 100644
index 0000000..20bca47
--- /dev/null
+++ b/src/runtime/defs_plan9_amd64.h
@@ -0,0 +1,34 @@
+#define PAGESIZE 0x1000
+
+typedef struct Ureg Ureg;
+
+struct Ureg {
+	uint64	ax;
+	uint64	bx;
+	uint64	cx;
+	uint64	dx;
+	uint64	si;
+	uint64	di;
+	uint64	bp;
+	uint64	r8;
+	uint64	r9;
+	uint64	r10;
+	uint64	r11;
+	uint64	r12;
+	uint64	r13;
+	uint64	r14;
+	uint64	r15;
+
+	uint16	ds;
+	uint16	es;
+	uint16	fs;
+	uint16	gs;
+
+	uint64	type;
+	uint64	error;				/* error code (or zero) */
+	uint64	ip;				/* pc */
+	uint64	cs;				/* old context */
+	uint64	flags;				/* old flags */
+	uint64	sp;				/* sp */
+	uint64	ss;				/* old stack segment */
+};
diff --git a/src/runtime/defs_solaris.go b/src/runtime/defs_solaris.go
new file mode 100644
index 0000000..ba44e5f
--- /dev/null
+++ b/src/runtime/defs_solaris.go
@@ -0,0 +1,156 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build ignore
+
+/*
+Input to cgo.
+
+GOARCH=amd64 go tool cgo -cdefs defs_solaris.go >defs_solaris_amd64.h
+*/
+
+package runtime
+
+/*
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/select.h>
+#include <sys/siginfo.h>
+#include <sys/signal.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/ucontext.h>
+#include <sys/regset.h>
+#include <sys/unistd.h>
+#include <sys/fork.h>
+#include <sys/port.h>
+#include <semaphore.h>
+#include <errno.h>
+#include <signal.h>
+#include <pthread.h>
+#include <netdb.h>
+*/
+import "C"
+
+const (
+	EINTR       = C.EINTR
+	EBADF       = C.EBADF
+	EFAULT      = C.EFAULT
+	EAGAIN      = C.EAGAIN
+	ETIMEDOUT   = C.ETIMEDOUT
+	EWOULDBLOCK = C.EWOULDBLOCK
+	EINPROGRESS = C.EINPROGRESS
+
+	PROT_NONE  = C.PROT_NONE
+	PROT_READ  = C.PROT_READ
+	PROT_WRITE = C.PROT_WRITE
+	PROT_EXEC  = C.PROT_EXEC
+
+	MAP_ANON    = C.MAP_ANON
+	MAP_PRIVATE = C.MAP_PRIVATE
+	MAP_FIXED   = C.MAP_FIXED
+
+	MADV_FREE = C.MADV_FREE
+
+	SA_SIGINFO = C.SA_SIGINFO
+	SA_RESTART = C.SA_RESTART
+	SA_ONSTACK = C.SA_ONSTACK
+
+	SIGHUP    = C.SIGHUP
+	SIGINT    = C.SIGINT
+	SIGQUIT   = C.SIGQUIT
+	SIGILL    = C.SIGILL
+	SIGTRAP   = C.SIGTRAP
+	SIGABRT   = C.SIGABRT
+	SIGEMT    = C.SIGEMT
+	SIGFPE    = C.SIGFPE
+	SIGKILL   = C.SIGKILL
+	SIGBUS    = C.SIGBUS
+	SIGSEGV   = C.SIGSEGV
+	SIGSYS    = C.SIGSYS
+	SIGPIPE   = C.SIGPIPE
+	SIGALRM   = C.SIGALRM
+	SIGTERM   = C.SIGTERM
+	SIGURG    = C.SIGURG
+	SIGSTOP   = C.SIGSTOP
+	SIGTSTP   = C.SIGTSTP
+	SIGCONT   = C.SIGCONT
+	SIGCHLD   = C.SIGCHLD
+	SIGTTIN   = C.SIGTTIN
+	SIGTTOU   = C.SIGTTOU
+	SIGIO     = C.SIGIO
+	SIGXCPU   = C.SIGXCPU
+	SIGXFSZ   = C.SIGXFSZ
+	SIGVTALRM = C.SIGVTALRM
+	SIGPROF   = C.SIGPROF
+	SIGWINCH  = C.SIGWINCH
+	SIGUSR1   = C.SIGUSR1
+	SIGUSR2   = C.SIGUSR2
+
+	FPE_INTDIV = C.FPE_INTDIV
+	FPE_INTOVF = C.FPE_INTOVF
+	FPE_FLTDIV = C.FPE_FLTDIV
+	FPE_FLTOVF = C.FPE_FLTOVF
+	FPE_FLTUND = C.FPE_FLTUND
+	FPE_FLTRES = C.FPE_FLTRES
+	FPE_FLTINV = C.FPE_FLTINV
+	FPE_FLTSUB = C.FPE_FLTSUB
+
+	BUS_ADRALN = C.BUS_ADRALN
+	BUS_ADRERR = C.BUS_ADRERR
+	BUS_OBJERR = C.BUS_OBJERR
+
+	SEGV_MAPERR = C.SEGV_MAPERR
+	SEGV_ACCERR = C.SEGV_ACCERR
+
+	ITIMER_REAL    = C.ITIMER_REAL
+	ITIMER_VIRTUAL = C.ITIMER_VIRTUAL
+	ITIMER_PROF    = C.ITIMER_PROF
+
+	_SC_NPROCESSORS_ONLN = C._SC_NPROCESSORS_ONLN
+
+	PTHREAD_CREATE_DETACHED = C.PTHREAD_CREATE_DETACHED
+
+	FORK_NOSIGCHLD = C.FORK_NOSIGCHLD
+	FORK_WAITPID   = C.FORK_WAITPID
+
+	MAXHOSTNAMELEN = C.MAXHOSTNAMELEN
+
+	O_NONBLOCK = C.O_NONBLOCK
+	FD_CLOEXEC = C.FD_CLOEXEC
+	F_GETFL    = C.F_GETFL
+	F_SETFL    = C.F_SETFL
+	F_SETFD    = C.F_SETFD
+
+	POLLIN  = C.POLLIN
+	POLLOUT = C.POLLOUT
+	POLLHUP = C.POLLHUP
+	POLLERR = C.POLLERR
+
+	PORT_SOURCE_FD = C.PORT_SOURCE_FD
+)
+
+type SemT C.sem_t
+
+type SigaltstackT C.struct_sigaltstack
+type Sigset C.sigset_t
+type StackT C.stack_t
+
+type Siginfo C.siginfo_t
+type Sigaction C.struct_sigaction
+
+type Fpregset C.fpregset_t
+type Mcontext C.mcontext_t
+type Ucontext C.ucontext_t
+
+type Timespec C.struct_timespec
+type Timeval C.struct_timeval
+type Itimerval C.struct_itimerval
+
+type PortEvent C.port_event_t
+type Pthread C.pthread_t
+type PthreadAttr C.pthread_attr_t
+
+// depends on Timespec, must appear below
+type Stat C.struct_stat
diff --git a/src/pkg/runtime/defs_solaris_amd64.go b/src/runtime/defs_solaris_amd64.go
similarity index 100%
rename from src/pkg/runtime/defs_solaris_amd64.go
rename to src/runtime/defs_solaris_amd64.go
diff --git a/src/runtime/defs_solaris_amd64.h b/src/runtime/defs_solaris_amd64.h
new file mode 100644
index 0000000..cb1cfea
--- /dev/null
+++ b/src/runtime/defs_solaris_amd64.h
@@ -0,0 +1,254 @@
+// Created by cgo -cdefs - DO NOT EDIT
+// cgo -cdefs defs_solaris.go defs_solaris_amd64.go
+
+
+enum {
+	EINTR		= 0x4,
+	EBADF		= 0x9,
+	EFAULT		= 0xe,
+	EAGAIN		= 0xb,
+	ETIMEDOUT	= 0x91,
+	EWOULDBLOCK	= 0xb,
+	EINPROGRESS	= 0x96,
+
+	PROT_NONE	= 0x0,
+	PROT_READ	= 0x1,
+	PROT_WRITE	= 0x2,
+	PROT_EXEC	= 0x4,
+
+	MAP_ANON	= 0x100,
+	MAP_PRIVATE	= 0x2,
+	MAP_FIXED	= 0x10,
+
+	MADV_FREE	= 0x5,
+
+	SA_SIGINFO	= 0x8,
+	SA_RESTART	= 0x4,
+	SA_ONSTACK	= 0x1,
+
+	SIGHUP		= 0x1,
+	SIGINT		= 0x2,
+	SIGQUIT		= 0x3,
+	SIGILL		= 0x4,
+	SIGTRAP		= 0x5,
+	SIGABRT		= 0x6,
+	SIGEMT		= 0x7,
+	SIGFPE		= 0x8,
+	SIGKILL		= 0x9,
+	SIGBUS		= 0xa,
+	SIGSEGV		= 0xb,
+	SIGSYS		= 0xc,
+	SIGPIPE		= 0xd,
+	SIGALRM		= 0xe,
+	SIGTERM		= 0xf,
+	SIGURG		= 0x15,
+	SIGSTOP		= 0x17,
+	SIGTSTP		= 0x18,
+	SIGCONT		= 0x19,
+	SIGCHLD		= 0x12,
+	SIGTTIN		= 0x1a,
+	SIGTTOU		= 0x1b,
+	SIGIO		= 0x16,
+	SIGXCPU		= 0x1e,
+	SIGXFSZ		= 0x1f,
+	SIGVTALRM	= 0x1c,
+	SIGPROF		= 0x1d,
+	SIGWINCH	= 0x14,
+	SIGUSR1		= 0x10,
+	SIGUSR2		= 0x11,
+
+	FPE_INTDIV	= 0x1,
+	FPE_INTOVF	= 0x2,
+	FPE_FLTDIV	= 0x3,
+	FPE_FLTOVF	= 0x4,
+	FPE_FLTUND	= 0x5,
+	FPE_FLTRES	= 0x6,
+	FPE_FLTINV	= 0x7,
+	FPE_FLTSUB	= 0x8,
+
+	BUS_ADRALN	= 0x1,
+	BUS_ADRERR	= 0x2,
+	BUS_OBJERR	= 0x3,
+
+	SEGV_MAPERR	= 0x1,
+	SEGV_ACCERR	= 0x2,
+
+	ITIMER_REAL	= 0x0,
+	ITIMER_VIRTUAL	= 0x1,
+	ITIMER_PROF	= 0x2,
+
+	_SC_NPROCESSORS_ONLN	= 0xf,
+
+	PTHREAD_CREATE_DETACHED	= 0x40,
+
+	FORK_NOSIGCHLD	= 0x1,
+	FORK_WAITPID	= 0x2,
+
+	MAXHOSTNAMELEN	= 0x100,
+
+	O_NONBLOCK	= 0x80,
+	FD_CLOEXEC	= 0x1,
+	F_GETFL		= 0x3,
+	F_SETFL		= 0x4,
+	F_SETFD		= 0x2,
+
+	POLLIN	= 0x1,
+	POLLOUT	= 0x4,
+	POLLHUP	= 0x10,
+	POLLERR	= 0x8,
+
+	PORT_SOURCE_FD	= 0x4,
+};
+
+typedef struct SemT SemT;
+typedef struct SigaltstackT SigaltstackT;
+typedef struct Sigset Sigset;
+typedef struct StackT StackT;
+typedef struct Siginfo Siginfo;
+typedef struct SigactionT SigactionT;
+typedef struct Fpregset Fpregset;
+typedef struct Mcontext Mcontext;
+typedef struct Ucontext Ucontext;
+typedef struct Timespec Timespec;
+typedef struct Timeval Timeval;
+typedef struct Itimerval Itimerval;
+typedef struct PortEvent PortEvent;
+typedef struct PthreadAttr PthreadAttr;
+typedef struct Stat Stat;
+
+#pragma pack on
+
+struct SemT {
+	uint32	sem_count;
+	uint16	sem_type;
+	uint16	sem_magic;
+	uint64	sem_pad1[3];
+	uint64	sem_pad2[2];
+};
+
+struct SigaltstackT {
+	byte	*ss_sp;
+	uint64	ss_size;
+	int32	ss_flags;
+	byte	Pad_cgo_0[4];
+};
+struct Sigset {
+	uint32	__sigbits[4];
+};
+struct StackT {
+	byte	*ss_sp;
+	uint64	ss_size;
+	int32	ss_flags;
+	byte	Pad_cgo_0[4];
+};
+
+struct Siginfo {
+	int32	si_signo;
+	int32	si_code;
+	int32	si_errno;
+	int32	si_pad;
+	byte	__data[240];
+};
+struct SigactionT {
+	int32	sa_flags;
+	byte	Pad_cgo_0[4];
+	byte	_funcptr[8];
+	Sigset	sa_mask;
+};
+
+struct Fpregset {
+	byte	fp_reg_set[528];
+};
+struct Mcontext {
+	int64	gregs[28];
+	Fpregset	fpregs;
+};
+struct Ucontext {
+	uint64	uc_flags;
+	Ucontext	*uc_link;
+	Sigset	uc_sigmask;
+	StackT	uc_stack;
+	byte	Pad_cgo_0[8];
+	Mcontext	uc_mcontext;
+	int64	uc_filler[5];
+	byte	Pad_cgo_1[8];
+};
+
+struct Timespec {
+	int64	tv_sec;
+	int64	tv_nsec;
+};
+struct Timeval {
+	int64	tv_sec;
+	int64	tv_usec;
+};
+struct Itimerval {
+	Timeval	it_interval;
+	Timeval	it_value;
+};
+
+struct PortEvent {
+	int32	portev_events;
+	uint16	portev_source;
+	uint16	portev_pad;
+	uint64	portev_object;
+	byte	*portev_user;
+};
+typedef	uint32	Pthread;
+struct PthreadAttr {
+	byte	*__pthread_attrp;
+};
+
+struct Stat {
+	uint64	st_dev;
+	uint64	st_ino;
+	uint32	st_mode;
+	uint32	st_nlink;
+	uint32	st_uid;
+	uint32	st_gid;
+	uint64	st_rdev;
+	int64	st_size;
+	Timespec	st_atim;
+	Timespec	st_mtim;
+	Timespec	st_ctim;
+	int32	st_blksize;
+	byte	Pad_cgo_0[4];
+	int64	st_blocks;
+	int8	st_fstype[16];
+};
+
+
+#pragma pack off
+// Created by cgo -cdefs - DO NOT EDIT
+// cgo -cdefs defs_solaris.go defs_solaris_amd64.go
+
+
+enum {
+	REG_RDI		= 0x8,
+	REG_RSI		= 0x9,
+	REG_RDX		= 0xc,
+	REG_RCX		= 0xd,
+	REG_R8		= 0x7,
+	REG_R9		= 0x6,
+	REG_R10		= 0x5,
+	REG_R11		= 0x4,
+	REG_R12		= 0x3,
+	REG_R13		= 0x2,
+	REG_R14		= 0x1,
+	REG_R15		= 0x0,
+	REG_RBP		= 0xa,
+	REG_RBX		= 0xb,
+	REG_RAX		= 0xe,
+	REG_GS		= 0x17,
+	REG_FS		= 0x16,
+	REG_ES		= 0x18,
+	REG_DS		= 0x19,
+	REG_TRAPNO	= 0xf,
+	REG_ERR		= 0x10,
+	REG_RIP		= 0x11,
+	REG_CS		= 0x12,
+	REG_RFLAGS	= 0x13,
+	REG_RSP		= 0x14,
+	REG_SS		= 0x15,
+};
+
diff --git a/src/runtime/defs_windows.go b/src/runtime/defs_windows.go
new file mode 100644
index 0000000..7ce6797
--- /dev/null
+++ b/src/runtime/defs_windows.go
@@ -0,0 +1,73 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build ignore
+
+/*
+Input to cgo.
+
+GOARCH=amd64 go tool cgo -cdefs defs_windows.go > defs_windows_amd64.h
+GOARCH=386 go tool cgo -cdefs defs_windows.go > defs_windows_386.h
+*/
+
+package runtime
+
+/*
+#include <signal.h>
+#include <stdarg.h>
+#include <windef.h>
+#include <winbase.h>
+#include <wincon.h>
+
+#ifndef _X86_
+typedef struct {} FLOATING_SAVE_AREA;
+#endif
+#ifndef _AMD64_
+typedef struct {} M128A;
+#endif
+*/
+import "C"
+
+const (
+	PROT_NONE  = 0
+	PROT_READ  = 1
+	PROT_WRITE = 2
+	PROT_EXEC  = 4
+
+	MAP_ANON    = 1
+	MAP_PRIVATE = 2
+
+	DUPLICATE_SAME_ACCESS   = C.DUPLICATE_SAME_ACCESS
+	THREAD_PRIORITY_HIGHEST = C.THREAD_PRIORITY_HIGHEST
+
+	SIGINT           = C.SIGINT
+	CTRL_C_EVENT     = C.CTRL_C_EVENT
+	CTRL_BREAK_EVENT = C.CTRL_BREAK_EVENT
+
+	CONTEXT_CONTROL = C.CONTEXT_CONTROL
+	CONTEXT_FULL    = C.CONTEXT_FULL
+
+	EXCEPTION_ACCESS_VIOLATION     = C.STATUS_ACCESS_VIOLATION
+	EXCEPTION_BREAKPOINT           = C.STATUS_BREAKPOINT
+	EXCEPTION_FLT_DENORMAL_OPERAND = C.STATUS_FLOAT_DENORMAL_OPERAND
+	EXCEPTION_FLT_DIVIDE_BY_ZERO   = C.STATUS_FLOAT_DIVIDE_BY_ZERO
+	EXCEPTION_FLT_INEXACT_RESULT   = C.STATUS_FLOAT_INEXACT_RESULT
+	EXCEPTION_FLT_OVERFLOW         = C.STATUS_FLOAT_OVERFLOW
+	EXCEPTION_FLT_UNDERFLOW        = C.STATUS_FLOAT_UNDERFLOW
+	EXCEPTION_INT_DIVIDE_BY_ZERO   = C.STATUS_INTEGER_DIVIDE_BY_ZERO
+	EXCEPTION_INT_OVERFLOW         = C.STATUS_INTEGER_OVERFLOW
+
+	INFINITE     = C.INFINITE
+	WAIT_TIMEOUT = C.WAIT_TIMEOUT
+
+	EXCEPTION_CONTINUE_EXECUTION = C.EXCEPTION_CONTINUE_EXECUTION
+	EXCEPTION_CONTINUE_SEARCH    = C.EXCEPTION_CONTINUE_SEARCH
+)
+
+type SystemInfo C.SYSTEM_INFO
+type ExceptionRecord C.EXCEPTION_RECORD
+type FloatingSaveArea C.FLOATING_SAVE_AREA
+type M128a C.M128A
+type Context C.CONTEXT
+type Overlapped C.OVERLAPPED
diff --git a/src/runtime/defs_windows_386.h b/src/runtime/defs_windows_386.h
new file mode 100644
index 0000000..2317c04
--- /dev/null
+++ b/src/runtime/defs_windows_386.h
@@ -0,0 +1,116 @@
+// Created by cgo -cdefs - DO NOT EDIT
+// cgo -cdefs defs_windows.go
+
+
+enum {
+	PROT_NONE	= 0,
+	PROT_READ	= 1,
+	PROT_WRITE	= 2,
+	PROT_EXEC	= 4,
+
+	MAP_ANON	= 1,
+	MAP_PRIVATE	= 2,
+
+	DUPLICATE_SAME_ACCESS	= 0x2,
+	THREAD_PRIORITY_HIGHEST	= 0x2,
+
+	SIGINT			= 0x2,
+	CTRL_C_EVENT		= 0x0,
+	CTRL_BREAK_EVENT	= 0x1,
+
+	CONTEXT_CONTROL	= 0x10001,
+	CONTEXT_FULL	= 0x10007,
+
+	EXCEPTION_ACCESS_VIOLATION	= 0xc0000005,
+	EXCEPTION_BREAKPOINT		= 0x80000003,
+	EXCEPTION_FLT_DENORMAL_OPERAND	= 0xc000008d,
+	EXCEPTION_FLT_DIVIDE_BY_ZERO	= 0xc000008e,
+	EXCEPTION_FLT_INEXACT_RESULT	= 0xc000008f,
+	EXCEPTION_FLT_OVERFLOW		= 0xc0000091,
+	EXCEPTION_FLT_UNDERFLOW		= 0xc0000093,
+	EXCEPTION_INT_DIVIDE_BY_ZERO	= 0xc0000094,
+	EXCEPTION_INT_OVERFLOW		= 0xc0000095,
+
+	INFINITE	= 0xffffffff,
+	WAIT_TIMEOUT	= 0x102,
+
+	EXCEPTION_CONTINUE_EXECUTION	= -0x1,
+	EXCEPTION_CONTINUE_SEARCH	= 0x0,
+};
+
+typedef struct SystemInfo SystemInfo;
+typedef struct ExceptionRecord ExceptionRecord;
+typedef struct FloatingSaveArea FloatingSaveArea;
+typedef struct M128a M128a;
+typedef struct Context Context;
+typedef struct Overlapped Overlapped;
+
+#pragma pack on
+
+struct SystemInfo {
+	byte	anon0[4];
+	uint32	dwPageSize;
+	byte	*lpMinimumApplicationAddress;
+	byte	*lpMaximumApplicationAddress;
+	uint32	dwActiveProcessorMask;
+	uint32	dwNumberOfProcessors;
+	uint32	dwProcessorType;
+	uint32	dwAllocationGranularity;
+	uint16	wProcessorLevel;
+	uint16	wProcessorRevision;
+};
+struct ExceptionRecord {
+	uint32	ExceptionCode;
+	uint32	ExceptionFlags;
+	ExceptionRecord	*ExceptionRecord;
+	byte	*ExceptionAddress;
+	uint32	NumberParameters;
+	uint32	ExceptionInformation[15];
+};
+struct FloatingSaveArea {
+	uint32	ControlWord;
+	uint32	StatusWord;
+	uint32	TagWord;
+	uint32	ErrorOffset;
+	uint32	ErrorSelector;
+	uint32	DataOffset;
+	uint32	DataSelector;
+	uint8	RegisterArea[80];
+	uint32	Cr0NpxState;
+};
+struct Context {
+	uint32	ContextFlags;
+	uint32	Dr0;
+	uint32	Dr1;
+	uint32	Dr2;
+	uint32	Dr3;
+	uint32	Dr6;
+	uint32	Dr7;
+	FloatingSaveArea	FloatSave;
+	uint32	SegGs;
+	uint32	SegFs;
+	uint32	SegEs;
+	uint32	SegDs;
+	uint32	Edi;
+	uint32	Esi;
+	uint32	Ebx;
+	uint32	Edx;
+	uint32	Ecx;
+	uint32	Eax;
+	uint32	Ebp;
+	uint32	Eip;
+	uint32	SegCs;
+	uint32	EFlags;
+	uint32	Esp;
+	uint32	SegSs;
+	uint8	ExtendedRegisters[512];
+};
+struct Overlapped {
+	uint32	Internal;
+	uint32	InternalHigh;
+	byte	anon0[8];
+	byte	*hEvent;
+};
+
+
+#pragma pack off
diff --git a/src/runtime/defs_windows_amd64.h b/src/runtime/defs_windows_amd64.h
new file mode 100644
index 0000000..7f37a7a
--- /dev/null
+++ b/src/runtime/defs_windows_amd64.h
@@ -0,0 +1,131 @@
+// Created by cgo -cdefs - DO NOT EDIT
+// cgo -cdefs defs_windows.go
+
+
+enum {
+	PROT_NONE	= 0,
+	PROT_READ	= 1,
+	PROT_WRITE	= 2,
+	PROT_EXEC	= 4,
+
+	MAP_ANON	= 1,
+	MAP_PRIVATE	= 2,
+
+	DUPLICATE_SAME_ACCESS	= 0x2,
+	THREAD_PRIORITY_HIGHEST	= 0x2,
+
+	SIGINT			= 0x2,
+	CTRL_C_EVENT		= 0x0,
+	CTRL_BREAK_EVENT	= 0x1,
+
+	CONTEXT_CONTROL	= 0x100001,
+	CONTEXT_FULL	= 0x10000b,
+
+	EXCEPTION_ACCESS_VIOLATION	= 0xc0000005,
+	EXCEPTION_BREAKPOINT		= 0x80000003,
+	EXCEPTION_FLT_DENORMAL_OPERAND	= 0xc000008d,
+	EXCEPTION_FLT_DIVIDE_BY_ZERO	= 0xc000008e,
+	EXCEPTION_FLT_INEXACT_RESULT	= 0xc000008f,
+	EXCEPTION_FLT_OVERFLOW		= 0xc0000091,
+	EXCEPTION_FLT_UNDERFLOW		= 0xc0000093,
+	EXCEPTION_INT_DIVIDE_BY_ZERO	= 0xc0000094,
+	EXCEPTION_INT_OVERFLOW		= 0xc0000095,
+
+	INFINITE	= 0xffffffff,
+	WAIT_TIMEOUT	= 0x102,
+
+	EXCEPTION_CONTINUE_EXECUTION	= -0x1,
+	EXCEPTION_CONTINUE_SEARCH	= 0x0,
+};
+
+typedef struct SystemInfo SystemInfo;
+typedef struct ExceptionRecord ExceptionRecord;
+typedef struct FloatingSaveArea FloatingSaveArea;
+typedef struct M128a M128a;
+typedef struct Context Context;
+typedef struct Overlapped Overlapped;
+
+#pragma pack on
+
+struct SystemInfo {
+	byte	anon0[4];
+	uint32	dwPageSize;
+	byte	*lpMinimumApplicationAddress;
+	byte	*lpMaximumApplicationAddress;
+	uint64	dwActiveProcessorMask;
+	uint32	dwNumberOfProcessors;
+	uint32	dwProcessorType;
+	uint32	dwAllocationGranularity;
+	uint16	wProcessorLevel;
+	uint16	wProcessorRevision;
+};
+struct ExceptionRecord {
+	uint32	ExceptionCode;
+	uint32	ExceptionFlags;
+	ExceptionRecord	*ExceptionRecord;
+	byte	*ExceptionAddress;
+	uint32	NumberParameters;
+	byte	Pad_cgo_0[4];
+	uint64	ExceptionInformation[15];
+};
+struct M128a {
+	uint64	Low;
+	int64	High;
+};
+struct Context {
+	uint64	P1Home;
+	uint64	P2Home;
+	uint64	P3Home;
+	uint64	P4Home;
+	uint64	P5Home;
+	uint64	P6Home;
+	uint32	ContextFlags;
+	uint32	MxCsr;
+	uint16	SegCs;
+	uint16	SegDs;
+	uint16	SegEs;
+	uint16	SegFs;
+	uint16	SegGs;
+	uint16	SegSs;
+	uint32	EFlags;
+	uint64	Dr0;
+	uint64	Dr1;
+	uint64	Dr2;
+	uint64	Dr3;
+	uint64	Dr6;
+	uint64	Dr7;
+	uint64	Rax;
+	uint64	Rcx;
+	uint64	Rdx;
+	uint64	Rbx;
+	uint64	Rsp;
+	uint64	Rbp;
+	uint64	Rsi;
+	uint64	Rdi;
+	uint64	R8;
+	uint64	R9;
+	uint64	R10;
+	uint64	R11;
+	uint64	R12;
+	uint64	R13;
+	uint64	R14;
+	uint64	R15;
+	uint64	Rip;
+	byte	anon0[512];
+	M128a	VectorRegister[26];
+	uint64	VectorControl;
+	uint64	DebugControl;
+	uint64	LastBranchToRip;
+	uint64	LastBranchFromRip;
+	uint64	LastExceptionToRip;
+	uint64	LastExceptionFromRip;
+};
+struct Overlapped {
+	uint64	Internal;
+	uint64	InternalHigh;
+	byte	anon0[8];
+	byte	*hEvent;
+};
+
+
+#pragma pack off
diff --git a/src/runtime/env_plan9.go b/src/runtime/env_plan9.go
new file mode 100644
index 0000000..e442c34
--- /dev/null
+++ b/src/runtime/env_plan9.go
@@ -0,0 +1,56 @@
+// Copyright 2012 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package runtime
+
+import "unsafe"
+
+func getenv(s *byte) *byte {
+	val := gogetenv(gostringnocopy(s))
+	if val == "" {
+		return nil
+	}
+	// Strings found in environment are NUL-terminated.
+	return &bytes(val)[0]
+}
+
+var tracebackbuf [128]byte
+
+func gogetenv(key string) string {
+	var file [128]byte
+	if len(key) > len(file)-6 {
+		return ""
+	}
+
+	copy(file[:], "/env/")
+	copy(file[5:], key)
+
+	fd := open(&file[0], _OREAD, 0)
+	if fd < 0 {
+		return ""
+	}
+	n := seek(fd, 0, 2)
+	if n <= 0 {
+		close(fd)
+		return ""
+	}
+
+	p := make([]byte, n)
+
+	r := pread(fd, unsafe.Pointer(&p[0]), int32(n), 0)
+	close(fd)
+	if r < 0 {
+		return ""
+	}
+
+	if p[r-1] == 0 {
+		r--
+	}
+
+	var s string
+	sp := (*_string)(unsafe.Pointer(&s))
+	sp.str = &p[0]
+	sp.len = int(r)
+	return s
+}
diff --git a/src/runtime/env_posix.go b/src/runtime/env_posix.go
new file mode 100644
index 0000000..dd57872
--- /dev/null
+++ b/src/runtime/env_posix.go
@@ -0,0 +1,63 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris windows
+
+package runtime
+
+import "unsafe"
+
+func environ() []string
+
+func getenv(s *byte) *byte {
+	val := gogetenv(gostringnocopy(s))
+	if val == "" {
+		return nil
+	}
+	// Strings found in environment are NUL-terminated.
+	return &bytes(val)[0]
+}
+
+func gogetenv(key string) string {
+	env := environ()
+	if env == nil {
+		gothrow("getenv before env init")
+	}
+	for _, s := range environ() {
+		if len(s) > len(key) && s[len(key)] == '=' && s[:len(key)] == key {
+			return s[len(key)+1:]
+		}
+	}
+	return ""
+}
+
+var _cgo_setenv uintptr   // pointer to C function
+var _cgo_unsetenv uintptr // pointer to C function
+
+// Update the C environment if cgo is loaded.
+// Called from syscall.Setenv.
+func syscall_setenv_c(k string, v string) {
+	if _cgo_setenv == 0 {
+		return
+	}
+	arg := [2]unsafe.Pointer{cstring(k), cstring(v)}
+	asmcgocall(unsafe.Pointer(_cgo_setenv), unsafe.Pointer(&arg))
+}
+
+// Update the C environment if cgo is loaded.
+// Called from syscall.unsetenv.
+func syscall_unsetenv_c(k string) {
+	if _cgo_unsetenv == 0 {
+		return
+	}
+	arg := [1]unsafe.Pointer{cstring(k)}
+	asmcgocall(unsafe.Pointer(_cgo_unsetenv), unsafe.Pointer(&arg))
+}
+
+func cstring(s string) unsafe.Pointer {
+	p := make([]byte, len(s)+1)
+	sp := (*_string)(unsafe.Pointer(&s))
+	memmove(unsafe.Pointer(&p[0]), unsafe.Pointer(sp.str), uintptr(len(s)))
+	return unsafe.Pointer(&p[0])
+}
diff --git a/src/runtime/error.go b/src/runtime/error.go
new file mode 100644
index 0000000..0b40c70
--- /dev/null
+++ b/src/runtime/error.go
@@ -0,0 +1,107 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package runtime
+
+import "unsafe"
+
+// The Error interface identifies a run time error.
+type Error interface {
+	error
+
+	// RuntimeError is a no-op function but
+	// serves to distinguish types that are runtime
+	// errors from ordinary errors: a type is a
+	// runtime error if it has a RuntimeError method.
+	RuntimeError()
+}
+
+// A TypeAssertionError explains a failed type assertion.
+type TypeAssertionError struct {
+	interfaceString string
+	concreteString  string
+	assertedString  string
+	missingMethod   string // one method needed by Interface, missing from Concrete
+}
+
+func (*TypeAssertionError) RuntimeError() {}
+
+func (e *TypeAssertionError) Error() string {
+	inter := e.interfaceString
+	if inter == "" {
+		inter = "interface"
+	}
+	if e.concreteString == "" {
+		return "interface conversion: " + inter + " is nil, not " + e.assertedString
+	}
+	if e.missingMethod == "" {
+		return "interface conversion: " + inter + " is " + e.concreteString +
+			", not " + e.assertedString
+	}
+	return "interface conversion: " + e.concreteString + " is not " + e.assertedString +
+		": missing method " + e.missingMethod
+}
+
+// For calling from C.
+func newTypeAssertionError(ps1, ps2, ps3 *string, pmeth *string, ret *interface{}) {
+	var s1, s2, s3, meth string
+
+	if ps1 != nil {
+		s1 = *ps1
+	}
+	if ps2 != nil {
+		s2 = *ps2
+	}
+	if ps3 != nil {
+		s3 = *ps3
+	}
+	if pmeth != nil {
+		meth = *pmeth
+	}
+	*ret = &TypeAssertionError{s1, s2, s3, meth}
+}
+
+// An errorString represents a runtime error described by a single string.
+type errorString string
+
+func (e errorString) RuntimeError() {}
+
+func (e errorString) Error() string {
+	return "runtime error: " + string(e)
+}
+
+type stringer interface {
+	String() string
+}
+
+func typestring(x interface{}) string {
+	e := (*eface)(unsafe.Pointer(&x))
+	return *e._type._string
+}
+
+// For calling from C.
+// Prints an argument passed to panic.
+// There's room for arbitrary complexity here, but we keep it
+// simple and handle just a few important cases: int, string, and Stringer.
+func printany(i interface{}) {
+	switch v := i.(type) {
+	case nil:
+		print("nil")
+	case stringer:
+		print(v.String())
+	case error:
+		print(v.Error())
+	case int:
+		print(v)
+	case string:
+		print(v)
+	default:
+		print("(", typestring(i), ") ", i)
+	}
+}
+
+// called from generated code
+func panicwrap(pkg, typ, meth string) {
+	panic("value method " + pkg + "." + typ + "." + meth + " called using nil *" + typ + " pointer")
+}
diff --git a/src/runtime/export_futex_test.go b/src/runtime/export_futex_test.go
new file mode 100644
index 0000000..96281f6
--- /dev/null
+++ b/src/runtime/export_futex_test.go
@@ -0,0 +1,10 @@
+// Copyright 2013 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build dragonfly freebsd linux
+
+package runtime
+
+var Futexsleep = futexsleep
+var Futexwakeup = futexwakeup
diff --git a/src/runtime/export_test.go b/src/runtime/export_test.go
new file mode 100644
index 0000000..be35255
--- /dev/null
+++ b/src/runtime/export_test.go
@@ -0,0 +1,165 @@
+// Copyright 2010 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Export guts for testing.
+
+package runtime
+
+import "unsafe"
+
+var Fadd64 = fadd64
+var Fsub64 = fsub64
+var Fmul64 = fmul64
+var Fdiv64 = fdiv64
+var F64to32 = f64to32
+var F32to64 = f32to64
+var Fcmp64 = fcmp64
+var Fintto64 = fintto64
+var F64toint = f64toint
+
+// in asm_*.s
+func stackguard() (sp, limit uintptr)
+
+var Entersyscall = entersyscall
+var Exitsyscall = exitsyscall
+var LockedOSThread = lockedOSThread
+
+type LFNode struct {
+	Next    *LFNode
+	Pushcnt uintptr
+}
+
+func lfstackpush_m()
+func lfstackpop_m()
+
+func LFStackPush(head *uint64, node *LFNode) {
+	mp := acquirem()
+	mp.ptrarg[0] = unsafe.Pointer(head)
+	mp.ptrarg[1] = unsafe.Pointer(node)
+	onM(lfstackpush_m)
+	releasem(mp)
+}
+
+func LFStackPop(head *uint64) *LFNode {
+	mp := acquirem()
+	mp.ptrarg[0] = unsafe.Pointer(head)
+	onM(lfstackpop_m)
+	node := (*LFNode)(unsafe.Pointer(mp.ptrarg[0]))
+	mp.ptrarg[0] = nil
+	releasem(mp)
+	return node
+}
+
+type ParFor struct {
+	body    *byte
+	done    uint32
+	Nthr    uint32
+	nthrmax uint32
+	thrseq  uint32
+	Cnt     uint32
+	Ctx     *byte
+	wait    bool
+}
+
+func newparfor_m()
+func parforsetup_m()
+func parfordo_m()
+func parforiters_m()
+
+func NewParFor(nthrmax uint32) *ParFor {
+	mp := acquirem()
+	mp.scalararg[0] = uintptr(nthrmax)
+	onM(newparfor_m)
+	desc := (*ParFor)(mp.ptrarg[0])
+	mp.ptrarg[0] = nil
+	releasem(mp)
+	return desc
+}
+
+func ParForSetup(desc *ParFor, nthr, n uint32, ctx *byte, wait bool, body func(*ParFor, uint32)) {
+	mp := acquirem()
+	mp.ptrarg[0] = unsafe.Pointer(desc)
+	mp.ptrarg[1] = unsafe.Pointer(ctx)
+	mp.ptrarg[2] = unsafe.Pointer(funcPC(body)) // TODO(rsc): Should be a scalar.
+	mp.scalararg[0] = uintptr(nthr)
+	mp.scalararg[1] = uintptr(n)
+	mp.scalararg[2] = 0
+	if wait {
+		mp.scalararg[2] = 1
+	}
+	onM(parforsetup_m)
+	releasem(mp)
+}
+
+func ParForDo(desc *ParFor) {
+	mp := acquirem()
+	mp.ptrarg[0] = unsafe.Pointer(desc)
+	onM(parfordo_m)
+	releasem(mp)
+}
+
+func ParForIters(desc *ParFor, tid uint32) (uint32, uint32) {
+	mp := acquirem()
+	mp.ptrarg[0] = unsafe.Pointer(desc)
+	mp.scalararg[0] = uintptr(tid)
+	onM(parforiters_m)
+	begin := uint32(mp.scalararg[0])
+	end := uint32(mp.scalararg[1])
+	releasem(mp)
+	return begin, end
+}
+
+// in mgc0.c
+//go:noescape
+func getgcmask(data unsafe.Pointer, typ *_type, array **byte, len *uint)
+
+func GCMask(x interface{}) (ret []byte) {
+	e := (*eface)(unsafe.Pointer(&x))
+	s := (*slice)(unsafe.Pointer(&ret))
+	onM(func() {
+		getgcmask(e.data, e._type, &s.array, &s.len)
+		s.cap = s.len
+	})
+	return
+}
+
+func testSchedLocalQueue()
+func testSchedLocalQueueSteal()
+func RunSchedLocalQueueTest() {
+	onM(testSchedLocalQueue)
+}
+func RunSchedLocalQueueStealTest() {
+	onM(testSchedLocalQueueSteal)
+}
+
+var HaveGoodHash = haveGoodHash
+var StringHash = stringHash
+var BytesHash = bytesHash
+var Int32Hash = int32Hash
+var Int64Hash = int64Hash
+var EfaceHash = efaceHash
+var IfaceHash = ifaceHash
+var MemclrBytes = memclrBytes
+
+var HashLoad = &hashLoad
+
+// For testing.
+func GogoBytes() int32 {
+	return _RuntimeGogoBytes
+}
+
+// in string.c
+//go:noescape
+func gostringw(w *uint16) string
+
+// entry point for testing
+func GostringW(w []uint16) (s string) {
+	onM(func() {
+		s = gostringw(&w[0])
+	})
+	return
+}
+
+var Gostringnocopy = gostringnocopy
+var Maxstring = &maxstring
diff --git a/src/runtime/extern.go b/src/runtime/extern.go
new file mode 100644
index 0000000..6cc5df8
--- /dev/null
+++ b/src/runtime/extern.go
@@ -0,0 +1,168 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+/*
+Package runtime contains operations that interact with Go's runtime system,
+such as functions to control goroutines. It also includes the low-level type information
+used by the reflect package; see reflect's documentation for the programmable
+interface to the run-time type system.
+
+Environment Variables
+
+The following environment variables ($name or %name%, depending on the host
+operating system) control the run-time behavior of Go programs. The meanings
+and use may change from release to release.
+
+The GOGC variable sets the initial garbage collection target percentage.
+A collection is triggered when the ratio of freshly allocated data to live data
+remaining after the previous collection reaches this percentage. The default
+is GOGC=100. Setting GOGC=off disables the garbage collector entirely.
+The runtime/debug package's SetGCPercent function allows changing this
+percentage at run time. See http://golang.org/pkg/runtime/debug/#SetGCPercent.
+
+The GODEBUG variable controls debug output from the runtime. GODEBUG value is
+a comma-separated list of name=val pairs. Supported names are:
+
+	allocfreetrace: setting allocfreetrace=1 causes every allocation to be
+	profiled and a stack trace printed on each object's allocation and free.
+
+	efence: setting efence=1 causes the allocator to run in a mode
+	where each object is allocated on a unique page and addresses are
+	never recycled.
+
+	gctrace: setting gctrace=1 causes the garbage collector to emit a single line to standard
+	error at each collection, summarizing the amount of memory collected and the
+	length of the pause. Setting gctrace=2 emits the same summary but also
+	repeats each collection.
+
+	gcdead: setting gcdead=1 causes the garbage collector to clobber all stack slots
+	that it thinks are dead.
+
+	invalidptr: defaults to invalidptr=1, causing the garbage collector and stack
+	copier to crash the program if an invalid pointer value (for example, 1)
+	is found in a pointer-typed location. Setting invalidptr=0 disables this check.
+	This should only be used as a temporary workaround to diagnose buggy code.
+	The real fix is to not store integers in pointer-typed locations.
+
+	scheddetail: setting schedtrace=X and scheddetail=1 causes the scheduler to emit
+	detailed multiline info every X milliseconds, describing state of the scheduler,
+	processors, threads and goroutines.
+
+	schedtrace: setting schedtrace=X causes the scheduler to emit a single line to standard
+	error every X milliseconds, summarizing the scheduler state.
+
+	scavenge: scavenge=1 enables debugging mode of heap scavenger.
+
+The GOMAXPROCS variable limits the number of operating system threads that
+can execute user-level Go code simultaneously. There is no limit to the number of threads
+that can be blocked in system calls on behalf of Go code; those do not count against
+the GOMAXPROCS limit. This package's GOMAXPROCS function queries and changes
+the limit.
+
+The GOTRACEBACK variable controls the amount of output generated when a Go
+program fails due to an unrecovered panic or an unexpected runtime condition.
+By default, a failure prints a stack trace for every extant goroutine, eliding functions
+internal to the run-time system, and then exits with exit code 2.
+If GOTRACEBACK=0, the per-goroutine stack traces are omitted entirely.
+If GOTRACEBACK=1, the default behavior is used.
+If GOTRACEBACK=2, the per-goroutine stack traces include run-time functions.
+If GOTRACEBACK=crash, the per-goroutine stack traces include run-time functions,
+and if possible the program crashes in an operating-specific manner instead of
+exiting. For example, on Unix systems, the program raises SIGABRT to trigger a
+core dump.
+
+The GOARCH, GOOS, GOPATH, and GOROOT environment variables complete
+the set of Go environment variables. They influence the building of Go programs
+(see http://golang.org/cmd/go and http://golang.org/pkg/go/build).
+GOARCH, GOOS, and GOROOT are recorded at compile time and made available by
+constants or functions in this package, but they do not influence the execution
+of the run-time system.
+*/
+package runtime
+
+// Caller reports file and line number information about function invocations on
+// the calling goroutine's stack.  The argument skip is the number of stack frames
+// to ascend, with 0 identifying the caller of Caller.  (For historical reasons the
+// meaning of skip differs between Caller and Callers.) The return values report the
+// program counter, file name, and line number within the file of the corresponding
+// call.  The boolean ok is false if it was not possible to recover the information.
+func Caller(skip int) (pc uintptr, file string, line int, ok bool) {
+	// Ask for two PCs: the one we were asked for
+	// and what it called, so that we can see if it
+	// "called" sigpanic.
+	var rpc [2]uintptr
+	if callers(1+skip-1, &rpc[0], 2) < 2 {
+		return
+	}
+	f := findfunc(rpc[1])
+	if f == nil {
+		// TODO(rsc): Probably a bug?
+		// The C version said "have retpc at least"
+		// but actually returned pc=0.
+		ok = true
+		return
+	}
+	pc = rpc[1]
+	xpc := pc
+	g := findfunc(rpc[0])
+	// All architectures turn faults into apparent calls to sigpanic.
+	// If we see a call to sigpanic, we do not back up the PC to find
+	// the line number of the call instruction, because there is no call.
+	if xpc > f.entry && (g == nil || g.entry != funcPC(sigpanic)) {
+		xpc--
+	}
+	line = int(funcline(f, xpc, &file))
+	ok = true
+	return
+}
+
+// Callers fills the slice pc with the return program counters of function invocations
+// on the calling goroutine's stack.  The argument skip is the number of stack frames
+// to skip before recording in pc, with 0 identifying the frame for Callers itself and
+// 1 identifying the caller of Callers.
+// It returns the number of entries written to pc.
+//
+// Note that since each slice entry pc[i] is a return program counter,
+// looking up the file and line for pc[i] (for example, using (*Func).FileLine)
+// will return the file and line number of the instruction immediately
+// following the call.
+// To look up the file and line number of the call itself, use pc[i]-1.
+// As an exception to this rule, if pc[i-1] corresponds to the function
+// runtime.sigpanic, then pc[i] is the program counter of a faulting
+// instruction and should be used without any subtraction.
+func Callers(skip int, pc []uintptr) int {
+	// runtime.callers uses pc.array==nil as a signal
+	// to print a stack trace.  Pick off 0-length pc here
+	// so that we don't let a nil pc slice get to it.
+	if len(pc) == 0 {
+		return 0
+	}
+	return callers(skip, &pc[0], len(pc))
+}
+
+// GOROOT returns the root of the Go tree.
+// It uses the GOROOT environment variable, if set,
+// or else the root used during the Go build.
+func GOROOT() string {
+	s := gogetenv("GOROOT")
+	if s != "" {
+		return s
+	}
+	return defaultGoroot
+}
+
+// Version returns the Go tree's version string.
+// It is either the commit hash and date at the time of the build or,
+// when possible, a release tag like "go1.3".
+func Version() string {
+	return theVersion
+}
+
+// GOOS is the running program's operating system target:
+// one of darwin, freebsd, linux, and so on.
+const GOOS string = theGoos
+
+// GOARCH is the running program's architecture target:
+// 386, amd64, or arm.
+const GOARCH string = theGoarch
diff --git a/src/pkg/runtime/float.c b/src/runtime/float.c
similarity index 100%
rename from src/pkg/runtime/float.c
rename to src/runtime/float.c
diff --git a/src/runtime/funcdata.h b/src/runtime/funcdata.h
new file mode 100644
index 0000000..d6c14fc
--- /dev/null
+++ b/src/runtime/funcdata.h
@@ -0,0 +1,60 @@
+// Copyright 2013 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file defines the IDs for PCDATA and FUNCDATA instructions
+// in Go binaries. It is included by both C and assembly, so it must
+// be written using #defines. It is included by the runtime package
+// as well as the compilers.
+//
+// symtab.go also contains a copy of these constants.
+
+#define PCDATA_StackMapIndex 0
+
+#define FUNCDATA_ArgsPointerMaps 0 /* garbage collector blocks */
+#define FUNCDATA_LocalsPointerMaps 1
+#define FUNCDATA_DeadValueMaps 2
+
+// Pseudo-assembly statements.
+
+// GO_ARGS, GO_RESULTS_INITIALIZED, and NO_LOCAL_POINTERS are macros
+// that communicate to the runtime information about the location and liveness
+// of pointers in an assembly function's arguments, results, and stack frame.
+// This communication is only required in assembly functions that make calls
+// to other functions that might be preempted or grow the stack.
+// NOSPLIT functions that make no calls do not need to use these macros.
+
+// GO_ARGS indicates that the Go prototype for this assembly function
+// defines the pointer map for the function's arguments.
+// GO_ARGS should be the first instruction in a function that uses it.
+// It can be omitted if there are no arguments at all.
+// GO_ARGS is inserted implicitly by the linker for any function
+// that also has a Go prototype and therefore is usually not necessary
+// to write explicitly.
+#define GO_ARGS	FUNCDATA $FUNCDATA_ArgsPointerMaps, go_args_stackmap(SB)
+
+// GO_RESULTS_INITIALIZED indicates that the assembly function
+// has initialized the stack space for its results and that those results
+// should be considered live for the remainder of the function.
+#define GO_RESULTS_INITIALIZED	FUNCDATA PCDATA $PCDATA_StackMapIndex, 1
+
+// NO_LOCAL_POINTERS indicates that the assembly function stores
+// no pointers to heap objects in its local stack variables.
+#define NO_LOCAL_POINTERS	FUNCDATA $FUNCDATA_LocalsPointerMaps, runtime·no_pointers_stackmap(SB)
+
+// ArgsSizeUnknown is set in Func.argsize to mark all functions
+// whose argument size is unknown (C vararg functions, and
+// assembly code without an explicit specification).
+// This value is generated by the compiler, assembler, or linker.
+#define ArgsSizeUnknown 0x80000000
+
+/*c2go
+enum {
+	PCDATA_ArgSize = 0,
+	PCDATA_StackMapIndex = 1,
+	FUNCDATA_ArgsPointerMaps = 0,
+	FUNCDATA_LocalsPointerMaps = 1,
+	FUNCDATA_DeadValueMaps = 2,
+	ArgsSizeUnknown = 0x80000000,
+};
+*/
diff --git a/src/pkg/runtime/futex_test.go b/src/runtime/futex_test.go
similarity index 100%
rename from src/pkg/runtime/futex_test.go
rename to src/runtime/futex_test.go
diff --git a/src/runtime/gc_test.go b/src/runtime/gc_test.go
new file mode 100644
index 0000000..6abec4c
--- /dev/null
+++ b/src/runtime/gc_test.go
@@ -0,0 +1,292 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package runtime_test
+
+import (
+	"os"
+	"runtime"
+	"runtime/debug"
+	"testing"
+	"time"
+	"unsafe"
+)
+
+func TestGcSys(t *testing.T) {
+	if os.Getenv("GOGC") == "off" {
+		t.Skip("skipping test; GOGC=off in environment")
+	}
+	data := struct{ Short bool }{testing.Short()}
+	got := executeTest(t, testGCSysSource, &data)
+	want := "OK\n"
+	if got != want {
+		t.Fatalf("expected %q, but got %q", want, got)
+	}
+}
+
+const testGCSysSource = `
+package main
+
+import (
+	"fmt"
+	"runtime"
+)
+
+func main() {
+	runtime.GOMAXPROCS(1)
+	memstats := new(runtime.MemStats)
+	runtime.GC()
+	runtime.ReadMemStats(memstats)
+	sys := memstats.Sys
+
+	runtime.MemProfileRate = 0 // disable profiler
+
+	itercount := 1000000
+{{if .Short}}
+	itercount = 100000
+{{end}}
+	for i := 0; i < itercount; i++ {
+		workthegc()
+	}
+
+	// Should only be using a few MB.
+	// We allocated 100 MB or (if not short) 1 GB.
+	runtime.ReadMemStats(memstats)
+	if sys > memstats.Sys {
+		sys = 0
+	} else {
+		sys = memstats.Sys - sys
+	}
+	if sys > 16<<20 {
+		fmt.Printf("using too much memory: %d bytes\n", sys)
+		return
+	}
+	fmt.Printf("OK\n")
+}
+
+func workthegc() []byte {
+	return make([]byte, 1029)
+}
+`
+
+func TestGcDeepNesting(t *testing.T) {
+	type T [2][2][2][2][2][2][2][2][2][2]*int
+	a := new(T)
+
+	// Prevent the compiler from applying escape analysis.
+	// This makes sure new(T) is allocated on heap, not on the stack.
+	t.Logf("%p", a)
+
+	a[0][0][0][0][0][0][0][0][0][0] = new(int)
+	*a[0][0][0][0][0][0][0][0][0][0] = 13
+	runtime.GC()
+	if *a[0][0][0][0][0][0][0][0][0][0] != 13 {
+		t.Fail()
+	}
+}
+
+func TestGcHashmapIndirection(t *testing.T) {
+	defer debug.SetGCPercent(debug.SetGCPercent(1))
+	runtime.GC()
+	type T struct {
+		a [256]int
+	}
+	m := make(map[T]T)
+	for i := 0; i < 2000; i++ {
+		var a T
+		a.a[0] = i
+		m[a] = T{}
+	}
+}
+
+func TestGcArraySlice(t *testing.T) {
+	type X struct {
+		buf     [1]byte
+		nextbuf []byte
+		next    *X
+	}
+	var head *X
+	for i := 0; i < 10; i++ {
+		p := &X{}
+		p.buf[0] = 42
+		p.next = head
+		if head != nil {
+			p.nextbuf = head.buf[:]
+		}
+		head = p
+		runtime.GC()
+	}
+	for p := head; p != nil; p = p.next {
+		if p.buf[0] != 42 {
+			t.Fatal("corrupted heap")
+		}
+	}
+}
+
+func TestGcRescan(t *testing.T) {
+	type X struct {
+		c     chan error
+		nextx *X
+	}
+	type Y struct {
+		X
+		nexty *Y
+		p     *int
+	}
+	var head *Y
+	for i := 0; i < 10; i++ {
+		p := &Y{}
+		p.c = make(chan error)
+		if head != nil {
+			p.nextx = &head.X
+		}
+		p.nexty = head
+		p.p = new(int)
+		*p.p = 42
+		head = p
+		runtime.GC()
+	}
+	for p := head; p != nil; p = p.nexty {
+		if *p.p != 42 {
+			t.Fatal("corrupted heap")
+		}
+	}
+}
+
+func TestGcLastTime(t *testing.T) {
+	ms := new(runtime.MemStats)
+	t0 := time.Now().UnixNano()
+	runtime.GC()
+	t1 := time.Now().UnixNano()
+	runtime.ReadMemStats(ms)
+	last := int64(ms.LastGC)
+	if t0 > last || last > t1 {
+		t.Fatalf("bad last GC time: got %v, want [%v, %v]", last, t0, t1)
+	}
+	pause := ms.PauseNs[(ms.NumGC+255)%256]
+	// Due to timer granularity, pause can actually be 0 on windows
+	// or on virtualized environments.
+	if pause == 0 {
+		t.Logf("last GC pause was 0")
+	} else if pause > 10e9 {
+		t.Logf("bad last GC pause: got %v, want [0, 10e9]", pause)
+	}
+}
+
+var hugeSink interface{}
+
+func TestHugeGCInfo(t *testing.T) {
+	// The test ensures that compiler can chew these huge types even on weakest machines.
+	// The types are not allocated at runtime.
+	if hugeSink != nil {
+		// 400MB on 32 bots, 4TB on 64-bits.
+		const n = (400 << 20) + (unsafe.Sizeof(uintptr(0))-4)<<40
+		hugeSink = new([n]*byte)
+		hugeSink = new([n]uintptr)
+		hugeSink = new(struct {
+			x float64
+			y [n]*byte
+			z []string
+		})
+		hugeSink = new(struct {
+			x float64
+			y [n]uintptr
+			z []string
+		})
+	}
+}
+
+func BenchmarkSetTypeNoPtr1(b *testing.B) {
+	type NoPtr1 struct {
+		p uintptr
+	}
+	var p *NoPtr1
+	for i := 0; i < b.N; i++ {
+		p = &NoPtr1{}
+	}
+	_ = p
+}
+func BenchmarkSetTypeNoPtr2(b *testing.B) {
+	type NoPtr2 struct {
+		p, q uintptr
+	}
+	var p *NoPtr2
+	for i := 0; i < b.N; i++ {
+		p = &NoPtr2{}
+	}
+	_ = p
+}
+func BenchmarkSetTypePtr1(b *testing.B) {
+	type Ptr1 struct {
+		p *byte
+	}
+	var p *Ptr1
+	for i := 0; i < b.N; i++ {
+		p = &Ptr1{}
+	}
+	_ = p
+}
+func BenchmarkSetTypePtr2(b *testing.B) {
+	type Ptr2 struct {
+		p, q *byte
+	}
+	var p *Ptr2
+	for i := 0; i < b.N; i++ {
+		p = &Ptr2{}
+	}
+	_ = p
+}
+
+func BenchmarkAllocation(b *testing.B) {
+	type T struct {
+		x, y *byte
+	}
+	ngo := runtime.GOMAXPROCS(0)
+	work := make(chan bool, b.N+ngo)
+	result := make(chan *T)
+	for i := 0; i < b.N; i++ {
+		work <- true
+	}
+	for i := 0; i < ngo; i++ {
+		work <- false
+	}
+	for i := 0; i < ngo; i++ {
+		go func() {
+			var x *T
+			for <-work {
+				for i := 0; i < 1000; i++ {
+					x = &T{}
+				}
+			}
+			result <- x
+		}()
+	}
+	for i := 0; i < ngo; i++ {
+		<-result
+	}
+}
+
+func TestPrintGC(t *testing.T) {
+	if testing.Short() {
+		t.Skip("Skipping in short mode")
+	}
+	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(2))
+	done := make(chan bool)
+	go func() {
+		for {
+			select {
+			case <-done:
+				return
+			default:
+				runtime.GC()
+			}
+		}
+	}()
+	for i := 0; i < 1e4; i++ {
+		func() {
+			defer print("")
+		}()
+	}
+	close(done)
+}
diff --git a/src/runtime/gcinfo_test.go b/src/runtime/gcinfo_test.go
new file mode 100644
index 0000000..88f6703
--- /dev/null
+++ b/src/runtime/gcinfo_test.go
@@ -0,0 +1,193 @@
+// 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 runtime_test
+
+import (
+	"bytes"
+	"runtime"
+	"testing"
+)
+
+// TestGCInfo tests that various objects in heap, data and bss receive correct GC pointer type info.
+func TestGCInfo(t *testing.T) {
+	verifyGCInfo(t, "bss ScalarPtr", &bssScalarPtr, nonStackInfo(infoScalarPtr))
+	verifyGCInfo(t, "bss PtrScalar", &bssPtrScalar, nonStackInfo(infoPtrScalar))
+	verifyGCInfo(t, "bss BigStruct", &bssBigStruct, nonStackInfo(infoBigStruct()))
+	verifyGCInfo(t, "bss string", &bssString, nonStackInfo(infoString))
+	verifyGCInfo(t, "bss slice", &bssSlice, nonStackInfo(infoSlice))
+	verifyGCInfo(t, "bss eface", &bssEface, nonStackInfo(infoEface))
+	verifyGCInfo(t, "bss iface", &bssIface, nonStackInfo(infoIface))
+
+	verifyGCInfo(t, "data ScalarPtr", &dataScalarPtr, nonStackInfo(infoScalarPtr))
+	verifyGCInfo(t, "data PtrScalar", &dataPtrScalar, nonStackInfo(infoPtrScalar))
+	verifyGCInfo(t, "data BigStruct", &dataBigStruct, nonStackInfo(infoBigStruct()))
+	verifyGCInfo(t, "data string", &dataString, nonStackInfo(infoString))
+	verifyGCInfo(t, "data slice", &dataSlice, nonStackInfo(infoSlice))
+	verifyGCInfo(t, "data eface", &dataEface, nonStackInfo(infoEface))
+	verifyGCInfo(t, "data iface", &dataIface, nonStackInfo(infoIface))
+
+	verifyGCInfo(t, "stack ScalarPtr", new(ScalarPtr), infoScalarPtr)
+	verifyGCInfo(t, "stack PtrScalar", new(PtrScalar), infoPtrScalar)
+	verifyGCInfo(t, "stack BigStruct", new(BigStruct), infoBigStruct())
+	verifyGCInfo(t, "stack string", new(string), infoString)
+	verifyGCInfo(t, "stack slice", new([]string), infoSlice)
+	verifyGCInfo(t, "stack eface", new(interface{}), infoEface)
+	verifyGCInfo(t, "stack iface", new(Iface), infoIface)
+
+	for i := 0; i < 10; i++ {
+		verifyGCInfo(t, "heap ScalarPtr", escape(new(ScalarPtr)), nonStackInfo(infoScalarPtr))
+		verifyGCInfo(t, "heap PtrScalar", escape(new(PtrScalar)), nonStackInfo(infoPtrScalar))
+		verifyGCInfo(t, "heap BigStruct", escape(new(BigStruct)), nonStackInfo(infoBigStruct()))
+		verifyGCInfo(t, "heap string", escape(new(string)), nonStackInfo(infoString))
+		verifyGCInfo(t, "heap eface", escape(new(interface{})), nonStackInfo(infoEface))
+		verifyGCInfo(t, "heap iface", escape(new(Iface)), nonStackInfo(infoIface))
+	}
+
+}
+
+func verifyGCInfo(t *testing.T, name string, p interface{}, mask0 []byte) {
+	mask := runtime.GCMask(p)
+	if len(mask) > len(mask0) {
+		mask0 = append(mask0, BitsDead)
+		mask = mask[:len(mask0)]
+	}
+	if bytes.Compare(mask, mask0) != 0 {
+		t.Errorf("bad GC program for %v:\nwant %+v\ngot  %+v", name, mask0, mask)
+		return
+	}
+}
+
+func nonStackInfo(mask []byte) []byte {
+	// BitsDead is replaced with BitsScalar everywhere except stacks.
+	mask1 := make([]byte, len(mask))
+	mw := false
+	for i, v := range mask {
+		if !mw && v == BitsDead {
+			v = BitsScalar
+		}
+		mw = !mw && v == BitsMultiWord
+		mask1[i] = v
+	}
+	return mask1
+}
+
+var gcinfoSink interface{}
+
+func escape(p interface{}) interface{} {
+	gcinfoSink = p
+	return p
+}
+
+const (
+	BitsDead = iota
+	BitsScalar
+	BitsPointer
+	BitsMultiWord
+)
+
+const (
+	BitsString = iota // unused
+	BitsSlice         // unused
+	BitsIface
+	BitsEface
+)
+
+type ScalarPtr struct {
+	q int
+	w *int
+	e int
+	r *int
+	t int
+	y *int
+}
+
+var infoScalarPtr = []byte{BitsScalar, BitsPointer, BitsScalar, BitsPointer, BitsScalar, BitsPointer}
+
+type PtrScalar struct {
+	q *int
+	w int
+	e *int
+	r int
+	t *int
+	y int
+}
+
+var infoPtrScalar = []byte{BitsPointer, BitsScalar, BitsPointer, BitsScalar, BitsPointer, BitsScalar}
+
+type BigStruct struct {
+	q *int
+	w byte
+	e [17]byte
+	r []byte
+	t int
+	y uint16
+	u uint64
+	i string
+}
+
+func infoBigStruct() []byte {
+	switch runtime.GOARCH {
+	case "386", "arm":
+		return []byte{
+			BitsPointer,                                                // q *int
+			BitsScalar, BitsScalar, BitsScalar, BitsScalar, BitsScalar, // w byte; e [17]byte
+			BitsPointer, BitsDead, BitsDead, // r []byte
+			BitsScalar, BitsScalar, BitsScalar, BitsScalar, // t int; y uint16; u uint64
+			BitsPointer, BitsDead, // i string
+		}
+	case "amd64":
+		return []byte{
+			BitsPointer,                        // q *int
+			BitsScalar, BitsScalar, BitsScalar, // w byte; e [17]byte
+			BitsPointer, BitsDead, BitsDead, // r []byte
+			BitsScalar, BitsScalar, BitsScalar, // t int; y uint16; u uint64
+			BitsPointer, BitsDead, // i string
+		}
+	case "amd64p32":
+		return []byte{
+			BitsPointer,                                                // q *int
+			BitsScalar, BitsScalar, BitsScalar, BitsScalar, BitsScalar, // w byte; e [17]byte
+			BitsPointer, BitsDead, BitsDead, // r []byte
+			BitsScalar, BitsScalar, BitsDead, BitsScalar, BitsScalar, // t int; y uint16; u uint64
+			BitsPointer, BitsDead, // i string
+		}
+	default:
+		panic("unknown arch")
+	}
+}
+
+type Iface interface {
+	f()
+}
+
+type IfaceImpl int
+
+func (IfaceImpl) f() {
+}
+
+var (
+	// BSS
+	bssScalarPtr ScalarPtr
+	bssPtrScalar PtrScalar
+	bssBigStruct BigStruct
+	bssString    string
+	bssSlice     []string
+	bssEface     interface{}
+	bssIface     Iface
+
+	// DATA
+	dataScalarPtr             = ScalarPtr{q: 1}
+	dataPtrScalar             = PtrScalar{w: 1}
+	dataBigStruct             = BigStruct{w: 1}
+	dataString                = "foo"
+	dataSlice                 = []string{"foo"}
+	dataEface     interface{} = 42
+	dataIface     Iface       = IfaceImpl(42)
+
+	infoString = []byte{BitsPointer, BitsDead}
+	infoSlice  = []byte{BitsPointer, BitsDead, BitsDead}
+	infoEface  = []byte{BitsMultiWord, BitsEface}
+	infoIface  = []byte{BitsMultiWord, BitsIface}
+)
diff --git a/src/runtime/hash_test.go b/src/runtime/hash_test.go
new file mode 100644
index 0000000..41fff98
--- /dev/null
+++ b/src/runtime/hash_test.go
@@ -0,0 +1,572 @@
+// Copyright 2013 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package runtime_test
+
+import (
+	"fmt"
+	"math"
+	"math/rand"
+	. "runtime"
+	"strings"
+	"testing"
+)
+
+// Smhasher is a torture test for hash functions.
+// https://code.google.com/p/smhasher/
+// This code is a port of some of the Smhasher tests to Go.
+//
+// The current AES hash function passes Smhasher.  Our fallback
+// hash functions don't, so we only enable the difficult tests when
+// we know the AES implementation is available.
+
+// Sanity checks.
+// hash should not depend on values outside key.
+// hash should not depend on alignment.
+func TestSmhasherSanity(t *testing.T) {
+	r := rand.New(rand.NewSource(1234))
+	const REP = 10
+	const KEYMAX = 128
+	const PAD = 16
+	const OFFMAX = 16
+	for k := 0; k < REP; k++ {
+		for n := 0; n < KEYMAX; n++ {
+			for i := 0; i < OFFMAX; i++ {
+				var b [KEYMAX + OFFMAX + 2*PAD]byte
+				var c [KEYMAX + OFFMAX + 2*PAD]byte
+				randBytes(r, b[:])
+				randBytes(r, c[:])
+				copy(c[PAD+i:PAD+i+n], b[PAD:PAD+n])
+				if BytesHash(b[PAD:PAD+n], 0) != BytesHash(c[PAD+i:PAD+i+n], 0) {
+					t.Errorf("hash depends on bytes outside key")
+				}
+			}
+		}
+	}
+}
+
+type HashSet struct {
+	m map[uintptr]struct{} // set of hashes added
+	n int                  // number of hashes added
+}
+
+func newHashSet() *HashSet {
+	return &HashSet{make(map[uintptr]struct{}), 0}
+}
+func (s *HashSet) add(h uintptr) {
+	s.m[h] = struct{}{}
+	s.n++
+}
+func (s *HashSet) addS(x string) {
+	s.add(StringHash(x, 0))
+}
+func (s *HashSet) addB(x []byte) {
+	s.add(BytesHash(x, 0))
+}
+func (s *HashSet) addS_seed(x string, seed uintptr) {
+	s.add(StringHash(x, seed))
+}
+func (s *HashSet) check(t *testing.T) {
+	const SLOP = 10.0
+	collisions := s.n - len(s.m)
+	//fmt.Printf("%d/%d\n", len(s.m), s.n)
+	pairs := int64(s.n) * int64(s.n-1) / 2
+	expected := float64(pairs) / math.Pow(2.0, float64(hashSize))
+	stddev := math.Sqrt(expected)
+	if float64(collisions) > expected+SLOP*3*stddev {
+		t.Errorf("unexpected number of collisions: got=%d mean=%f stddev=%f", collisions, expected, stddev)
+	}
+}
+
+// a string plus adding zeros must make distinct hashes
+func TestSmhasherAppendedZeros(t *testing.T) {
+	s := "hello" + strings.Repeat("\x00", 256)
+	h := newHashSet()
+	for i := 0; i <= len(s); i++ {
+		h.addS(s[:i])
+	}
+	h.check(t)
+}
+
+// All 0-3 byte strings have distinct hashes.
+func TestSmhasherSmallKeys(t *testing.T) {
+	h := newHashSet()
+	var b [3]byte
+	for i := 0; i < 256; i++ {
+		b[0] = byte(i)
+		h.addB(b[:1])
+		for j := 0; j < 256; j++ {
+			b[1] = byte(j)
+			h.addB(b[:2])
+			if !testing.Short() {
+				for k := 0; k < 256; k++ {
+					b[2] = byte(k)
+					h.addB(b[:3])
+				}
+			}
+		}
+	}
+	h.check(t)
+}
+
+// Different length strings of all zeros have distinct hashes.
+func TestSmhasherZeros(t *testing.T) {
+	N := 256 * 1024
+	if testing.Short() {
+		N = 1024
+	}
+	h := newHashSet()
+	b := make([]byte, N)
+	for i := 0; i <= N; i++ {
+		h.addB(b[:i])
+	}
+	h.check(t)
+}
+
+// Strings with up to two nonzero bytes all have distinct hashes.
+func TestSmhasherTwoNonzero(t *testing.T) {
+	if testing.Short() {
+		t.Skip("Skipping in short mode")
+	}
+	h := newHashSet()
+	for n := 2; n <= 16; n++ {
+		twoNonZero(h, n)
+	}
+	h.check(t)
+}
+func twoNonZero(h *HashSet, n int) {
+	b := make([]byte, n)
+
+	// all zero
+	h.addB(b[:])
+
+	// one non-zero byte
+	for i := 0; i < n; i++ {
+		for x := 1; x < 256; x++ {
+			b[i] = byte(x)
+			h.addB(b[:])
+			b[i] = 0
+		}
+	}
+
+	// two non-zero bytes
+	for i := 0; i < n; i++ {
+		for x := 1; x < 256; x++ {
+			b[i] = byte(x)
+			for j := i + 1; j < n; j++ {
+				for y := 1; y < 256; y++ {
+					b[j] = byte(y)
+					h.addB(b[:])
+					b[j] = 0
+				}
+			}
+			b[i] = 0
+		}
+	}
+}
+
+// Test strings with repeats, like "abcdabcdabcdabcd..."
+func TestSmhasherCyclic(t *testing.T) {
+	if testing.Short() {
+		t.Skip("Skipping in short mode")
+	}
+	if !HaveGoodHash() {
+		t.Skip("fallback hash not good enough for this test")
+	}
+	r := rand.New(rand.NewSource(1234))
+	const REPEAT = 8
+	const N = 1000000
+	for n := 4; n <= 12; n++ {
+		h := newHashSet()
+		b := make([]byte, REPEAT*n)
+		for i := 0; i < N; i++ {
+			b[0] = byte(i * 79 % 97)
+			b[1] = byte(i * 43 % 137)
+			b[2] = byte(i * 151 % 197)
+			b[3] = byte(i * 199 % 251)
+			randBytes(r, b[4:n])
+			for j := n; j < n*REPEAT; j++ {
+				b[j] = b[j-n]
+			}
+			h.addB(b)
+		}
+		h.check(t)
+	}
+}
+
+// Test strings with only a few bits set
+func TestSmhasherSparse(t *testing.T) {
+	if testing.Short() {
+		t.Skip("Skipping in short mode")
+	}
+	sparse(t, 32, 6)
+	sparse(t, 40, 6)
+	sparse(t, 48, 5)
+	sparse(t, 56, 5)
+	sparse(t, 64, 5)
+	sparse(t, 96, 4)
+	sparse(t, 256, 3)
+	sparse(t, 2048, 2)
+}
+func sparse(t *testing.T, n int, k int) {
+	b := make([]byte, n/8)
+	h := newHashSet()
+	setbits(h, b, 0, k)
+	h.check(t)
+}
+
+// set up to k bits at index i and greater
+func setbits(h *HashSet, b []byte, i int, k int) {
+	h.addB(b)
+	if k == 0 {
+		return
+	}
+	for j := i; j < len(b)*8; j++ {
+		b[j/8] |= byte(1 << uint(j&7))
+		setbits(h, b, j+1, k-1)
+		b[j/8] &= byte(^(1 << uint(j&7)))
+	}
+}
+
+// Test all possible combinations of n blocks from the set s.
+// "permutation" is a bad name here, but it is what Smhasher uses.
+func TestSmhasherPermutation(t *testing.T) {
+	if testing.Short() {
+		t.Skip("Skipping in short mode")
+	}
+	if !HaveGoodHash() {
+		t.Skip("fallback hash not good enough for this test")
+	}
+	permutation(t, []uint32{0, 1, 2, 3, 4, 5, 6, 7}, 8)
+	permutation(t, []uint32{0, 1 << 29, 2 << 29, 3 << 29, 4 << 29, 5 << 29, 6 << 29, 7 << 29}, 8)
+	permutation(t, []uint32{0, 1}, 20)
+	permutation(t, []uint32{0, 1 << 31}, 20)
+	permutation(t, []uint32{0, 1, 2, 3, 4, 5, 6, 7, 1 << 29, 2 << 29, 3 << 29, 4 << 29, 5 << 29, 6 << 29, 7 << 29}, 6)
+}
+func permutation(t *testing.T, s []uint32, n int) {
+	b := make([]byte, n*4)
+	h := newHashSet()
+	genPerm(h, b, s, 0)
+	h.check(t)
+}
+func genPerm(h *HashSet, b []byte, s []uint32, n int) {
+	h.addB(b[:n])
+	if n == len(b) {
+		return
+	}
+	for _, v := range s {
+		b[n] = byte(v)
+		b[n+1] = byte(v >> 8)
+		b[n+2] = byte(v >> 16)
+		b[n+3] = byte(v >> 24)
+		genPerm(h, b, s, n+4)
+	}
+}
+
+type Key interface {
+	clear()              // set bits all to 0
+	random(r *rand.Rand) // set key to something random
+	bits() int           // how many bits key has
+	flipBit(i int)       // flip bit i of the key
+	hash() uintptr       // hash the key
+	name() string        // for error reporting
+}
+
+type BytesKey struct {
+	b []byte
+}
+
+func (k *BytesKey) clear() {
+	for i := range k.b {
+		k.b[i] = 0
+	}
+}
+func (k *BytesKey) random(r *rand.Rand) {
+	randBytes(r, k.b)
+}
+func (k *BytesKey) bits() int {
+	return len(k.b) * 8
+}
+func (k *BytesKey) flipBit(i int) {
+	k.b[i>>3] ^= byte(1 << uint(i&7))
+}
+func (k *BytesKey) hash() uintptr {
+	return BytesHash(k.b, 0)
+}
+func (k *BytesKey) name() string {
+	return fmt.Sprintf("bytes%d", len(k.b))
+}
+
+type Int32Key struct {
+	i uint32
+}
+
+func (k *Int32Key) clear() {
+	k.i = 0
+}
+func (k *Int32Key) random(r *rand.Rand) {
+	k.i = r.Uint32()
+}
+func (k *Int32Key) bits() int {
+	return 32
+}
+func (k *Int32Key) flipBit(i int) {
+	k.i ^= 1 << uint(i)
+}
+func (k *Int32Key) hash() uintptr {
+	return Int32Hash(k.i, 0)
+}
+func (k *Int32Key) name() string {
+	return "int32"
+}
+
+type Int64Key struct {
+	i uint64
+}
+
+func (k *Int64Key) clear() {
+	k.i = 0
+}
+func (k *Int64Key) random(r *rand.Rand) {
+	k.i = uint64(r.Uint32()) + uint64(r.Uint32())<<32
+}
+func (k *Int64Key) bits() int {
+	return 64
+}
+func (k *Int64Key) flipBit(i int) {
+	k.i ^= 1 << uint(i)
+}
+func (k *Int64Key) hash() uintptr {
+	return Int64Hash(k.i, 0)
+}
+func (k *Int64Key) name() string {
+	return "int64"
+}
+
+type EfaceKey struct {
+	i interface{}
+}
+
+func (k *EfaceKey) clear() {
+	k.i = nil
+}
+func (k *EfaceKey) random(r *rand.Rand) {
+	k.i = uint64(r.Int63())
+}
+func (k *EfaceKey) bits() int {
+	// use 64 bits.  This tests inlined interfaces
+	// on 64-bit targets and indirect interfaces on
+	// 32-bit targets.
+	return 64
+}
+func (k *EfaceKey) flipBit(i int) {
+	k.i = k.i.(uint64) ^ uint64(1)<<uint(i)
+}
+func (k *EfaceKey) hash() uintptr {
+	return EfaceHash(k.i, 0)
+}
+func (k *EfaceKey) name() string {
+	return "Eface"
+}
+
+type IfaceKey struct {
+	i interface {
+		F()
+	}
+}
+type fInter uint64
+
+func (x fInter) F() {
+}
+
+func (k *IfaceKey) clear() {
+	k.i = nil
+}
+func (k *IfaceKey) random(r *rand.Rand) {
+	k.i = fInter(r.Int63())
+}
+func (k *IfaceKey) bits() int {
+	// use 64 bits.  This tests inlined interfaces
+	// on 64-bit targets and indirect interfaces on
+	// 32-bit targets.
+	return 64
+}
+func (k *IfaceKey) flipBit(i int) {
+	k.i = k.i.(fInter) ^ fInter(1)<<uint(i)
+}
+func (k *IfaceKey) hash() uintptr {
+	return IfaceHash(k.i, 0)
+}
+func (k *IfaceKey) name() string {
+	return "Iface"
+}
+
+// Flipping a single bit of a key should flip each output bit with 50% probability.
+func TestSmhasherAvalanche(t *testing.T) {
+	if !HaveGoodHash() {
+		t.Skip("fallback hash not good enough for this test")
+	}
+	if testing.Short() {
+		t.Skip("Skipping in short mode")
+	}
+	avalancheTest1(t, &BytesKey{make([]byte, 2)})
+	avalancheTest1(t, &BytesKey{make([]byte, 4)})
+	avalancheTest1(t, &BytesKey{make([]byte, 8)})
+	avalancheTest1(t, &BytesKey{make([]byte, 16)})
+	avalancheTest1(t, &BytesKey{make([]byte, 32)})
+	avalancheTest1(t, &BytesKey{make([]byte, 200)})
+	avalancheTest1(t, &Int32Key{})
+	avalancheTest1(t, &Int64Key{})
+	avalancheTest1(t, &EfaceKey{})
+	avalancheTest1(t, &IfaceKey{})
+}
+func avalancheTest1(t *testing.T, k Key) {
+	const REP = 100000
+	r := rand.New(rand.NewSource(1234))
+	n := k.bits()
+
+	// grid[i][j] is a count of whether flipping
+	// input bit i affects output bit j.
+	grid := make([][hashSize]int, n)
+
+	for z := 0; z < REP; z++ {
+		// pick a random key, hash it
+		k.random(r)
+		h := k.hash()
+
+		// flip each bit, hash & compare the results
+		for i := 0; i < n; i++ {
+			k.flipBit(i)
+			d := h ^ k.hash()
+			k.flipBit(i)
+
+			// record the effects of that bit flip
+			g := &grid[i]
+			for j := 0; j < hashSize; j++ {
+				g[j] += int(d & 1)
+				d >>= 1
+			}
+		}
+	}
+
+	// Each entry in the grid should be about REP/2.
+	// More precisely, we did N = k.bits() * hashSize experiments where
+	// each is the sum of REP coin flips.  We want to find bounds on the
+	// sum of coin flips such that a truly random experiment would have
+	// all sums inside those bounds with 99% probability.
+	N := n * hashSize
+	var c float64
+	// find c such that Prob(mean-c*stddev < x < mean+c*stddev)^N > .9999
+	for c = 0.0; math.Pow(math.Erf(c/math.Sqrt(2)), float64(N)) < .9999; c += .1 {
+	}
+	c *= 4.0 // allowed slack - we don't need to be perfectly random
+	mean := .5 * REP
+	stddev := .5 * math.Sqrt(REP)
+	low := int(mean - c*stddev)
+	high := int(mean + c*stddev)
+	for i := 0; i < n; i++ {
+		for j := 0; j < hashSize; j++ {
+			x := grid[i][j]
+			if x < low || x > high {
+				t.Errorf("bad bias for %s bit %d -> bit %d: %d/%d\n", k.name(), i, j, x, REP)
+			}
+		}
+	}
+}
+
+// All bit rotations of a set of distinct keys
+func TestSmhasherWindowed(t *testing.T) {
+	windowed(t, &Int32Key{})
+	windowed(t, &Int64Key{})
+	windowed(t, &BytesKey{make([]byte, 128)})
+}
+func windowed(t *testing.T, k Key) {
+	if testing.Short() {
+		t.Skip("Skipping in short mode")
+	}
+	const BITS = 16
+
+	for r := 0; r < k.bits(); r++ {
+		h := newHashSet()
+		for i := 0; i < 1<<BITS; i++ {
+			k.clear()
+			for j := 0; j < BITS; j++ {
+				if i>>uint(j)&1 != 0 {
+					k.flipBit((j + r) % k.bits())
+				}
+			}
+			h.add(k.hash())
+		}
+		h.check(t)
+	}
+}
+
+// All keys of the form prefix + [A-Za-z0-9]*N + suffix.
+func TestSmhasherText(t *testing.T) {
+	if testing.Short() {
+		t.Skip("Skipping in short mode")
+	}
+	text(t, "Foo", "Bar")
+	text(t, "FooBar", "")
+	text(t, "", "FooBar")
+}
+func text(t *testing.T, prefix, suffix string) {
+	const N = 4
+	const S = "ABCDEFGHIJKLMNOPQRSTabcdefghijklmnopqrst0123456789"
+	const L = len(S)
+	b := make([]byte, len(prefix)+N+len(suffix))
+	copy(b, prefix)
+	copy(b[len(prefix)+N:], suffix)
+	h := newHashSet()
+	c := b[len(prefix):]
+	for i := 0; i < L; i++ {
+		c[0] = S[i]
+		for j := 0; j < L; j++ {
+			c[1] = S[j]
+			for k := 0; k < L; k++ {
+				c[2] = S[k]
+				for x := 0; x < L; x++ {
+					c[3] = S[x]
+					h.addB(b)
+				}
+			}
+		}
+	}
+	h.check(t)
+}
+
+// Make sure different seed values generate different hashes.
+func TestSmhasherSeed(t *testing.T) {
+	h := newHashSet()
+	const N = 100000
+	s := "hello"
+	for i := 0; i < N; i++ {
+		h.addS_seed(s, uintptr(i))
+	}
+	h.check(t)
+}
+
+// size of the hash output (32 or 64 bits)
+const hashSize = 32 + int(^uintptr(0)>>63<<5)
+
+func randBytes(r *rand.Rand, b []byte) {
+	for i := range b {
+		b[i] = byte(r.Uint32())
+	}
+}
+
+func benchmarkHash(b *testing.B, n int) {
+	s := strings.Repeat("A", n)
+
+	for i := 0; i < b.N; i++ {
+		StringHash(s, 0)
+	}
+	b.SetBytes(int64(n))
+}
+
+func BenchmarkHash5(b *testing.B)     { benchmarkHash(b, 5) }
+func BenchmarkHash16(b *testing.B)    { benchmarkHash(b, 16) }
+func BenchmarkHash64(b *testing.B)    { benchmarkHash(b, 64) }
+func BenchmarkHash1024(b *testing.B)  { benchmarkHash(b, 1024) }
+func BenchmarkHash65536(b *testing.B) { benchmarkHash(b, 65536) }
diff --git a/src/runtime/hashmap.go b/src/runtime/hashmap.go
new file mode 100644
index 0000000..b4e6244
--- /dev/null
+++ b/src/runtime/hashmap.go
@@ -0,0 +1,953 @@
+// 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 runtime
+
+// This file contains the implementation of Go's map type.
+//
+// A map is just a hash table.  The data is arranged
+// into an array of buckets.  Each bucket contains up to
+// 8 key/value pairs.  The low-order bits of the hash are
+// used to select a bucket.  Each bucket contains a few
+// high-order bits of each hash to distinguish the entries
+// within a single bucket.
+//
+// If more than 8 keys hash to a bucket, we chain on
+// extra buckets.
+//
+// When the hashtable grows, we allocate a new array
+// of buckets twice as big.  Buckets are incrementally
+// copied from the old bucket array to the new bucket array.
+//
+// Map iterators walk through the array of buckets and
+// return the keys in walk order (bucket #, then overflow
+// chain order, then bucket index).  To maintain iteration
+// semantics, we never move keys within their bucket (if
+// we did, keys might be returned 0 or 2 times).  When
+// growing the table, iterators remain iterating through the
+// old table and must check the new table if the bucket
+// they are iterating through has been moved ("evacuated")
+// to the new table.
+
+// Picking loadFactor: too large and we have lots of overflow
+// buckets, too small and we waste a lot of space.  I wrote
+// a simple program to check some stats for different loads:
+// (64-bit, 8 byte keys and values)
+//  loadFactor    %overflow  bytes/entry     hitprobe    missprobe
+//        4.00         2.13        20.77         3.00         4.00
+//        4.50         4.05        17.30         3.25         4.50
+//        5.00         6.85        14.77         3.50         5.00
+//        5.50        10.55        12.94         3.75         5.50
+//        6.00        15.27        11.67         4.00         6.00
+//        6.50        20.90        10.79         4.25         6.50
+//        7.00        27.14        10.15         4.50         7.00
+//        7.50        34.03         9.73         4.75         7.50
+//        8.00        41.10         9.40         5.00         8.00
+//
+// %overflow   = percentage of buckets which have an overflow bucket
+// bytes/entry = overhead bytes used per key/value pair
+// hitprobe    = # of entries to check when looking up a present key
+// missprobe   = # of entries to check when looking up an absent key
+//
+// Keep in mind this data is for maximally loaded tables, i.e. just
+// before the table grows.  Typical tables will be somewhat less loaded.
+
+import (
+	"unsafe"
+)
+
+const (
+	// Maximum number of key/value pairs a bucket can hold.
+	bucketCntBits = 3
+	bucketCnt     = 1 << bucketCntBits
+
+	// Maximum average load of a bucket that triggers growth.
+	loadFactor = 6.5
+
+	// Maximum key or value size to keep inline (instead of mallocing per element).
+	// Must fit in a uint8.
+	// Fast versions cannot handle big values - the cutoff size for
+	// fast versions in ../../cmd/gc/walk.c must be at most this value.
+	maxKeySize   = 128
+	maxValueSize = 128
+
+	// data offset should be the size of the bmap struct, but needs to be
+	// aligned correctly.  For amd64p32 this means 64-bit alignment
+	// even though pointers are 32 bit.
+	dataOffset = unsafe.Offsetof(struct {
+		b bmap
+		v int64
+	}{}.v)
+
+	// Possible tophash values.  We reserve a few possibilities for special marks.
+	// Each bucket (including its overflow buckets, if any) will have either all or none of its
+	// entries in the evacuated* states (except during the evacuate() method, which only happens
+	// during map writes and thus no one else can observe the map during that time).
+	empty          = 0 // cell is empty
+	evacuatedEmpty = 1 // cell is empty, bucket is evacuated.
+	evacuatedX     = 2 // key/value is valid.  Entry has been evacuated to first half of larger table.
+	evacuatedY     = 3 // same as above, but evacuated to second half of larger table.
+	minTopHash     = 4 // minimum tophash for a normal filled cell.
+
+	// flags
+	iterator    = 1 // there may be an iterator using buckets
+	oldIterator = 2 // there may be an iterator using oldbuckets
+
+	// sentinel bucket ID for iterator checks
+	noCheck = 1<<(8*ptrSize) - 1
+
+	// trigger a garbage collection at every alloc called from this code
+	checkgc = false
+)
+
+// A header for a Go map.
+type hmap struct {
+	// Note: the format of the Hmap is encoded in ../../cmd/gc/reflect.c and
+	// ../reflect/type.go.  Don't change this structure without also changing that code!
+	count int // # live cells == size of map.  Must be first (used by len() builtin)
+	flags uint32
+	hash0 uint32 // hash seed
+	B     uint8  // log_2 of # of buckets (can hold up to loadFactor * 2^B items)
+
+	buckets    unsafe.Pointer // array of 2^B Buckets. may be nil if count==0.
+	oldbuckets unsafe.Pointer // previous bucket array of half the size, non-nil only when growing
+	nevacuate  uintptr        // progress counter for evacuation (buckets less than this have been evacuated)
+}
+
+// A bucket for a Go map.
+type bmap struct {
+	tophash  [bucketCnt]uint8
+	overflow *bmap
+	// Followed by bucketCnt keys and then bucketCnt values.
+	// NOTE: packing all the keys together and then all the values together makes the
+	// code a bit more complicated than alternating key/value/key/value/... but it allows
+	// us to eliminate padding which would be needed for, e.g., map[int64]int8.
+}
+
+// A hash iteration structure.
+// If you modify hiter, also change cmd/gc/reflect.c to indicate
+// the layout of this structure.
+type hiter struct {
+	key         unsafe.Pointer // Must be in first position.  Write nil to indicate iteration end (see cmd/gc/range.c).
+	value       unsafe.Pointer // Must be in second position (see cmd/gc/range.c).
+	t           *maptype
+	h           *hmap
+	buckets     unsafe.Pointer // bucket ptr at hash_iter initialization time
+	bptr        *bmap          // current bucket
+	startBucket uintptr        // bucket iteration started at
+	offset      uint8          // intra-bucket offset to start from during iteration (should be big enough to hold bucketCnt-1)
+	wrapped     bool           // already wrapped around from end of bucket array to beginning
+	B           uint8
+	i           uint8
+	bucket      uintptr
+	checkBucket uintptr
+}
+
+func evacuated(b *bmap) bool {
+	h := b.tophash[0]
+	return h > empty && h < minTopHash
+}
+
+func makemap(t *maptype, hint int64) *hmap {
+	if sz := unsafe.Sizeof(hmap{}); sz > 48 || sz != uintptr(t.hmap.size) {
+		gothrow("bad hmap size")
+	}
+
+	if hint < 0 || int64(int32(hint)) != hint {
+		panic("makemap: size out of range")
+		// TODO: make hint an int, then none of this nonsense
+	}
+
+	if !ismapkey(t.key) {
+		gothrow("runtime.makemap: unsupported map key type")
+	}
+
+	// check compiler's and reflect's math
+	if t.key.size > maxKeySize && (!t.indirectkey || t.keysize != uint8(ptrSize)) ||
+		t.key.size <= maxKeySize && (t.indirectkey || t.keysize != uint8(t.key.size)) {
+		gothrow("key size wrong")
+	}
+	if t.elem.size > maxValueSize && (!t.indirectvalue || t.valuesize != uint8(ptrSize)) ||
+		t.elem.size <= maxValueSize && (t.indirectvalue || t.valuesize != uint8(t.elem.size)) {
+		gothrow("value size wrong")
+	}
+
+	// invariants we depend on.  We should probably check these at compile time
+	// somewhere, but for now we'll do it here.
+	if t.key.align > bucketCnt {
+		gothrow("key align too big")
+	}
+	if t.elem.align > bucketCnt {
+		gothrow("value align too big")
+	}
+	if uintptr(t.key.size)%uintptr(t.key.align) != 0 {
+		gothrow("key size not a multiple of key align")
+	}
+	if uintptr(t.elem.size)%uintptr(t.elem.align) != 0 {
+		gothrow("value size not a multiple of value align")
+	}
+	if bucketCnt < 8 {
+		gothrow("bucketsize too small for proper alignment")
+	}
+	if dataOffset%uintptr(t.key.align) != 0 {
+		gothrow("need padding in bucket (key)")
+	}
+	if dataOffset%uintptr(t.elem.align) != 0 {
+		gothrow("need padding in bucket (value)")
+	}
+
+	// find size parameter which will hold the requested # of elements
+	B := uint8(0)
+	for ; hint > bucketCnt && float32(hint) > loadFactor*float32(uintptr(1)<<B); B++ {
+	}
+
+	// allocate initial hash table
+	// if B == 0, the buckets field is allocated lazily later (in mapassign)
+	// If hint is large zeroing this memory could take a while.
+	var buckets unsafe.Pointer
+	if B != 0 {
+		if checkgc {
+			memstats.next_gc = memstats.heap_alloc
+		}
+		buckets = newarray(t.bucket, uintptr(1)<<B)
+	}
+
+	// initialize Hmap
+	if checkgc {
+		memstats.next_gc = memstats.heap_alloc
+	}
+	h := (*hmap)(newobject(t.hmap))
+	h.count = 0
+	h.B = B
+	h.flags = 0
+	h.hash0 = fastrand1()
+	h.buckets = buckets
+	h.oldbuckets = nil
+	h.nevacuate = 0
+
+	return h
+}
+
+// mapaccess1 returns a pointer to h[key].  Never returns nil, instead
+// it will return a reference to the zero object for the value type if
+// the key is not in the map.
+// NOTE: The returned pointer may keep the whole map live, so don't
+// hold onto it for very long.
+func mapaccess1(t *maptype, h *hmap, key unsafe.Pointer) unsafe.Pointer {
+	if raceenabled && h != nil {
+		callerpc := getcallerpc(unsafe.Pointer(&t))
+		pc := funcPC(mapaccess1)
+		racereadpc(unsafe.Pointer(h), callerpc, pc)
+		raceReadObjectPC(t.key, key, callerpc, pc)
+	}
+	if h == nil || h.count == 0 {
+		return unsafe.Pointer(t.elem.zero)
+	}
+	alg := goalg(t.key.alg)
+	hash := alg.hash(key, uintptr(t.key.size), uintptr(h.hash0))
+	m := uintptr(1)<<h.B - 1
+	b := (*bmap)(add(h.buckets, (hash&m)*uintptr(t.bucketsize)))
+	if c := h.oldbuckets; c != nil {
+		oldb := (*bmap)(add(c, (hash&(m>>1))*uintptr(t.bucketsize)))
+		if !evacuated(oldb) {
+			b = oldb
+		}
+	}
+	top := uint8(hash >> (ptrSize*8 - 8))
+	if top < minTopHash {
+		top += minTopHash
+	}
+	for {
+		for i := uintptr(0); i < bucketCnt; i++ {
+			if b.tophash[i] != top {
+				continue
+			}
+			k := add(unsafe.Pointer(b), dataOffset+i*uintptr(t.keysize))
+			if t.indirectkey {
+				k = *((*unsafe.Pointer)(k))
+			}
+			if alg.equal(key, k, uintptr(t.key.size)) {
+				v := add(unsafe.Pointer(b), dataOffset+bucketCnt*uintptr(t.keysize)+i*uintptr(t.valuesize))
+				if t.indirectvalue {
+					v = *((*unsafe.Pointer)(v))
+				}
+				return v
+			}
+		}
+		b = b.overflow
+		if b == nil {
+			return unsafe.Pointer(t.elem.zero)
+		}
+	}
+}
+
+func mapaccess2(t *maptype, h *hmap, key unsafe.Pointer) (unsafe.Pointer, bool) {
+	if raceenabled && h != nil {
+		callerpc := getcallerpc(unsafe.Pointer(&t))
+		pc := funcPC(mapaccess2)
+		racereadpc(unsafe.Pointer(h), callerpc, pc)
+		raceReadObjectPC(t.key, key, callerpc, pc)
+	}
+	if h == nil || h.count == 0 {
+		return unsafe.Pointer(t.elem.zero), false
+	}
+	alg := goalg(t.key.alg)
+	hash := alg.hash(key, uintptr(t.key.size), uintptr(h.hash0))
+	m := uintptr(1)<<h.B - 1
+	b := (*bmap)(unsafe.Pointer(uintptr(h.buckets) + (hash&m)*uintptr(t.bucketsize)))
+	if c := h.oldbuckets; c != nil {
+		oldb := (*bmap)(unsafe.Pointer(uintptr(c) + (hash&(m>>1))*uintptr(t.bucketsize)))
+		if !evacuated(oldb) {
+			b = oldb
+		}
+	}
+	top := uint8(hash >> (ptrSize*8 - 8))
+	if top < minTopHash {
+		top += minTopHash
+	}
+	for {
+		for i := uintptr(0); i < bucketCnt; i++ {
+			if b.tophash[i] != top {
+				continue
+			}
+			k := add(unsafe.Pointer(b), dataOffset+i*uintptr(t.keysize))
+			if t.indirectkey {
+				k = *((*unsafe.Pointer)(k))
+			}
+			if alg.equal(key, k, uintptr(t.key.size)) {
+				v := add(unsafe.Pointer(b), dataOffset+bucketCnt*uintptr(t.keysize)+i*uintptr(t.valuesize))
+				if t.indirectvalue {
+					v = *((*unsafe.Pointer)(v))
+				}
+				return v, true
+			}
+		}
+		b = b.overflow
+		if b == nil {
+			return unsafe.Pointer(t.elem.zero), false
+		}
+	}
+}
+
+// returns both key and value.  Used by map iterator
+func mapaccessK(t *maptype, h *hmap, key unsafe.Pointer) (unsafe.Pointer, unsafe.Pointer) {
+	if h == nil || h.count == 0 {
+		return nil, nil
+	}
+	alg := goalg(t.key.alg)
+	hash := alg.hash(key, uintptr(t.key.size), uintptr(h.hash0))
+	m := uintptr(1)<<h.B - 1
+	b := (*bmap)(unsafe.Pointer(uintptr(h.buckets) + (hash&m)*uintptr(t.bucketsize)))
+	if c := h.oldbuckets; c != nil {
+		oldb := (*bmap)(unsafe.Pointer(uintptr(c) + (hash&(m>>1))*uintptr(t.bucketsize)))
+		if !evacuated(oldb) {
+			b = oldb
+		}
+	}
+	top := uint8(hash >> (ptrSize*8 - 8))
+	if top < minTopHash {
+		top += minTopHash
+	}
+	for {
+		for i := uintptr(0); i < bucketCnt; i++ {
+			if b.tophash[i] != top {
+				continue
+			}
+			k := add(unsafe.Pointer(b), dataOffset+i*uintptr(t.keysize))
+			if t.indirectkey {
+				k = *((*unsafe.Pointer)(k))
+			}
+			if alg.equal(key, k, uintptr(t.key.size)) {
+				v := add(unsafe.Pointer(b), dataOffset+bucketCnt*uintptr(t.keysize)+i*uintptr(t.valuesize))
+				if t.indirectvalue {
+					v = *((*unsafe.Pointer)(v))
+				}
+				return k, v
+			}
+		}
+		b = b.overflow
+		if b == nil {
+			return nil, nil
+		}
+	}
+}
+
+func mapassign1(t *maptype, h *hmap, key unsafe.Pointer, val unsafe.Pointer) {
+	if h == nil {
+		panic("assignment to entry in nil map")
+	}
+	if raceenabled {
+		callerpc := getcallerpc(unsafe.Pointer(&t))
+		pc := funcPC(mapassign1)
+		racewritepc(unsafe.Pointer(h), callerpc, pc)
+		raceReadObjectPC(t.key, key, callerpc, pc)
+		raceReadObjectPC(t.elem, val, callerpc, pc)
+	}
+
+	alg := goalg(t.key.alg)
+	hash := alg.hash(key, uintptr(t.key.size), uintptr(h.hash0))
+
+	if h.buckets == nil {
+		if checkgc {
+			memstats.next_gc = memstats.heap_alloc
+		}
+		h.buckets = newarray(t.bucket, 1)
+	}
+
+again:
+	bucket := hash & (uintptr(1)<<h.B - 1)
+	if h.oldbuckets != nil {
+		growWork(t, h, bucket)
+	}
+	b := (*bmap)(unsafe.Pointer(uintptr(h.buckets) + bucket*uintptr(t.bucketsize)))
+	top := uint8(hash >> (ptrSize*8 - 8))
+	if top < minTopHash {
+		top += minTopHash
+	}
+
+	var inserti *uint8
+	var insertk unsafe.Pointer
+	var insertv unsafe.Pointer
+	for {
+		for i := uintptr(0); i < bucketCnt; i++ {
+			if b.tophash[i] != top {
+				if b.tophash[i] == empty && inserti == nil {
+					inserti = &b.tophash[i]
+					insertk = add(unsafe.Pointer(b), dataOffset+i*uintptr(t.keysize))
+					insertv = add(unsafe.Pointer(b), dataOffset+bucketCnt*uintptr(t.keysize)+i*uintptr(t.valuesize))
+				}
+				continue
+			}
+			k := add(unsafe.Pointer(b), dataOffset+i*uintptr(t.keysize))
+			k2 := k
+			if t.indirectkey {
+				k2 = *((*unsafe.Pointer)(k2))
+			}
+			if !alg.equal(key, k2, uintptr(t.key.size)) {
+				continue
+			}
+			// already have a mapping for key.  Update it.
+			memmove(k2, key, uintptr(t.key.size))
+			v := add(unsafe.Pointer(b), dataOffset+bucketCnt*uintptr(t.keysize)+i*uintptr(t.valuesize))
+			v2 := v
+			if t.indirectvalue {
+				v2 = *((*unsafe.Pointer)(v2))
+			}
+			memmove(v2, val, uintptr(t.elem.size))
+			return
+		}
+		if b.overflow == nil {
+			break
+		}
+		b = b.overflow
+	}
+
+	// did not find mapping for key.  Allocate new cell & add entry.
+	if float32(h.count) >= loadFactor*float32((uintptr(1)<<h.B)) && h.count >= bucketCnt {
+		hashGrow(t, h)
+		goto again // Growing the table invalidates everything, so try again
+	}
+
+	if inserti == nil {
+		// all current buckets are full, allocate a new one.
+		if checkgc {
+			memstats.next_gc = memstats.heap_alloc
+		}
+		newb := (*bmap)(newobject(t.bucket))
+		b.overflow = newb
+		inserti = &newb.tophash[0]
+		insertk = add(unsafe.Pointer(newb), dataOffset)
+		insertv = add(insertk, bucketCnt*uintptr(t.keysize))
+	}
+
+	// store new key/value at insert position
+	if t.indirectkey {
+		if checkgc {
+			memstats.next_gc = memstats.heap_alloc
+		}
+		kmem := newobject(t.key)
+		*(*unsafe.Pointer)(insertk) = kmem
+		insertk = kmem
+	}
+	if t.indirectvalue {
+		if checkgc {
+			memstats.next_gc = memstats.heap_alloc
+		}
+		vmem := newobject(t.elem)
+		*(*unsafe.Pointer)(insertv) = vmem
+		insertv = vmem
+	}
+	memmove(insertk, key, uintptr(t.key.size))
+	memmove(insertv, val, uintptr(t.elem.size))
+	*inserti = top
+	h.count++
+}
+
+func mapdelete(t *maptype, h *hmap, key unsafe.Pointer) {
+	if raceenabled && h != nil {
+		callerpc := getcallerpc(unsafe.Pointer(&t))
+		pc := funcPC(mapdelete)
+		racewritepc(unsafe.Pointer(h), callerpc, pc)
+		raceReadObjectPC(t.key, key, callerpc, pc)
+	}
+	if h == nil || h.count == 0 {
+		return
+	}
+	alg := goalg(t.key.alg)
+	hash := alg.hash(key, uintptr(t.key.size), uintptr(h.hash0))
+	bucket := hash & (uintptr(1)<<h.B - 1)
+	if h.oldbuckets != nil {
+		growWork(t, h, bucket)
+	}
+	b := (*bmap)(unsafe.Pointer(uintptr(h.buckets) + bucket*uintptr(t.bucketsize)))
+	top := uint8(hash >> (ptrSize*8 - 8))
+	if top < minTopHash {
+		top += minTopHash
+	}
+	for {
+		for i := uintptr(0); i < bucketCnt; i++ {
+			if b.tophash[i] != top {
+				continue
+			}
+			k := add(unsafe.Pointer(b), dataOffset+i*uintptr(t.keysize))
+			k2 := k
+			if t.indirectkey {
+				k2 = *((*unsafe.Pointer)(k2))
+			}
+			if !alg.equal(key, k2, uintptr(t.key.size)) {
+				continue
+			}
+			memclr(k, uintptr(t.keysize))
+			v := unsafe.Pointer(uintptr(unsafe.Pointer(b)) + dataOffset + bucketCnt*uintptr(t.keysize) + i*uintptr(t.valuesize))
+			memclr(v, uintptr(t.valuesize))
+			b.tophash[i] = empty
+			h.count--
+			return
+		}
+		b = b.overflow
+		if b == nil {
+			return
+		}
+	}
+}
+
+func mapiterinit(t *maptype, h *hmap, it *hiter) {
+	// Clear pointer fields so garbage collector does not complain.
+	it.key = nil
+	it.value = nil
+	it.t = nil
+	it.h = nil
+	it.buckets = nil
+	it.bptr = nil
+
+	if raceenabled && h != nil {
+		callerpc := getcallerpc(unsafe.Pointer(&t))
+		racereadpc(unsafe.Pointer(h), callerpc, funcPC(mapiterinit))
+	}
+
+	if h == nil || h.count == 0 {
+		it.key = nil
+		it.value = nil
+		return
+	}
+
+	if unsafe.Sizeof(hiter{})/ptrSize != 10 {
+		gothrow("hash_iter size incorrect") // see ../../cmd/gc/reflect.c
+	}
+	it.t = t
+	it.h = h
+
+	// grab snapshot of bucket state
+	it.B = h.B
+	it.buckets = h.buckets
+
+	// decide where to start
+	r := uintptr(fastrand1())
+	if h.B > 31-bucketCntBits {
+		r += uintptr(fastrand1()) << 31
+	}
+	it.startBucket = r & (uintptr(1)<<h.B - 1)
+	it.offset = uint8(r >> h.B & (bucketCnt - 1))
+
+	// iterator state
+	it.bucket = it.startBucket
+	it.wrapped = false
+	it.bptr = nil
+
+	// Remember we have an iterator.
+	// Can run concurrently with another hash_iter_init().
+	for {
+		old := h.flags
+		if old == old|iterator|oldIterator {
+			break
+		}
+		if cas(&h.flags, old, old|iterator|oldIterator) {
+			break
+		}
+	}
+
+	mapiternext(it)
+}
+
+func mapiternext(it *hiter) {
+	h := it.h
+	if raceenabled {
+		callerpc := getcallerpc(unsafe.Pointer(&it))
+		racereadpc(unsafe.Pointer(h), callerpc, funcPC(mapiternext))
+	}
+	t := it.t
+	bucket := it.bucket
+	b := it.bptr
+	i := it.i
+	checkBucket := it.checkBucket
+	alg := goalg(t.key.alg)
+
+next:
+	if b == nil {
+		if bucket == it.startBucket && it.wrapped {
+			// end of iteration
+			it.key = nil
+			it.value = nil
+			return
+		}
+		if h.oldbuckets != nil && it.B == h.B {
+			// Iterator was started in the middle of a grow, and the grow isn't done yet.
+			// If the bucket we're looking at hasn't been filled in yet (i.e. the old
+			// bucket hasn't been evacuated) then we need to iterate through the old
+			// bucket and only return the ones that will be migrated to this bucket.
+			oldbucket := bucket & (uintptr(1)<<(it.B-1) - 1)
+			b = (*bmap)(add(h.oldbuckets, oldbucket*uintptr(t.bucketsize)))
+			if !evacuated(b) {
+				checkBucket = bucket
+			} else {
+				b = (*bmap)(add(it.buckets, bucket*uintptr(t.bucketsize)))
+				checkBucket = noCheck
+			}
+		} else {
+			b = (*bmap)(add(it.buckets, bucket*uintptr(t.bucketsize)))
+			checkBucket = noCheck
+		}
+		bucket++
+		if bucket == uintptr(1)<<it.B {
+			bucket = 0
+			it.wrapped = true
+		}
+		i = 0
+	}
+	for ; i < bucketCnt; i++ {
+		offi := (i + it.offset) & (bucketCnt - 1)
+		k := add(unsafe.Pointer(b), dataOffset+uintptr(offi)*uintptr(t.keysize))
+		v := add(unsafe.Pointer(b), dataOffset+bucketCnt*uintptr(t.keysize)+uintptr(offi)*uintptr(t.valuesize))
+		if b.tophash[offi] != empty && b.tophash[offi] != evacuatedEmpty {
+			if checkBucket != noCheck {
+				// Special case: iterator was started during a grow and the
+				// grow is not done yet.  We're working on a bucket whose
+				// oldbucket has not been evacuated yet.  Or at least, it wasn't
+				// evacuated when we started the bucket.  So we're iterating
+				// through the oldbucket, skipping any keys that will go
+				// to the other new bucket (each oldbucket expands to two
+				// buckets during a grow).
+				k2 := k
+				if t.indirectkey {
+					k2 = *((*unsafe.Pointer)(k2))
+				}
+				if alg.equal(k2, k2, uintptr(t.key.size)) {
+					// If the item in the oldbucket is not destined for
+					// the current new bucket in the iteration, skip it.
+					hash := alg.hash(k2, uintptr(t.key.size), uintptr(h.hash0))
+					if hash&(uintptr(1)<<it.B-1) != checkBucket {
+						continue
+					}
+				} else {
+					// Hash isn't repeatable if k != k (NaNs).  We need a
+					// repeatable and randomish choice of which direction
+					// to send NaNs during evacuation.  We'll use the low
+					// bit of tophash to decide which way NaNs go.
+					// NOTE: this case is why we need two evacuate tophash
+					// values, evacuatedX and evacuatedY, that differ in
+					// their low bit.
+					if checkBucket>>(it.B-1) != uintptr(b.tophash[offi]&1) {
+						continue
+					}
+				}
+			}
+			if b.tophash[offi] != evacuatedX && b.tophash[offi] != evacuatedY {
+				// this is the golden data, we can return it.
+				if t.indirectkey {
+					k = *((*unsafe.Pointer)(k))
+				}
+				it.key = k
+				if t.indirectvalue {
+					v = *((*unsafe.Pointer)(v))
+				}
+				it.value = v
+			} else {
+				// The hash table has grown since the iterator was started.
+				// The golden data for this key is now somewhere else.
+				k2 := k
+				if t.indirectkey {
+					k2 = *((*unsafe.Pointer)(k2))
+				}
+				if alg.equal(k2, k2, uintptr(t.key.size)) {
+					// Check the current hash table for the data.
+					// This code handles the case where the key
+					// has been deleted, updated, or deleted and reinserted.
+					// NOTE: we need to regrab the key as it has potentially been
+					// updated to an equal() but not identical key (e.g. +0.0 vs -0.0).
+					rk, rv := mapaccessK(t, h, k2)
+					if rk == nil {
+						continue // key has been deleted
+					}
+					it.key = rk
+					it.value = rv
+				} else {
+					// if key!=key then the entry can't be deleted or
+					// updated, so we can just return it.  That's lucky for
+					// us because when key!=key we can't look it up
+					// successfully in the current table.
+					it.key = k2
+					if t.indirectvalue {
+						v = *((*unsafe.Pointer)(v))
+					}
+					it.value = v
+				}
+			}
+			it.bucket = bucket
+			it.bptr = b
+			it.i = i + 1
+			it.checkBucket = checkBucket
+			return
+		}
+	}
+	b = b.overflow
+	i = 0
+	goto next
+}
+
+func hashGrow(t *maptype, h *hmap) {
+	if h.oldbuckets != nil {
+		gothrow("evacuation not done in time")
+	}
+	oldbuckets := h.buckets
+	if checkgc {
+		memstats.next_gc = memstats.heap_alloc
+	}
+	newbuckets := newarray(t.bucket, uintptr(1)<<(h.B+1))
+	flags := h.flags &^ (iterator | oldIterator)
+	if h.flags&iterator != 0 {
+		flags |= oldIterator
+	}
+	// commit the grow (atomic wrt gc)
+	h.B++
+	h.flags = flags
+	h.oldbuckets = oldbuckets
+	h.buckets = newbuckets
+	h.nevacuate = 0
+
+	// the actual copying of the hash table data is done incrementally
+	// by growWork() and evacuate().
+}
+
+func growWork(t *maptype, h *hmap, bucket uintptr) {
+	noldbuckets := uintptr(1) << (h.B - 1)
+
+	// make sure we evacuate the oldbucket corresponding
+	// to the bucket we're about to use
+	evacuate(t, h, bucket&(noldbuckets-1))
+
+	// evacuate one more oldbucket to make progress on growing
+	if h.oldbuckets != nil {
+		evacuate(t, h, h.nevacuate)
+	}
+}
+
+func evacuate(t *maptype, h *hmap, oldbucket uintptr) {
+	b := (*bmap)(add(h.oldbuckets, oldbucket*uintptr(t.bucketsize)))
+	newbit := uintptr(1) << (h.B - 1)
+	alg := goalg(t.key.alg)
+	if !evacuated(b) {
+		// TODO: reuse overflow buckets instead of using new ones, if there
+		// is no iterator using the old buckets.  (If !oldIterator.)
+
+		x := (*bmap)(add(h.buckets, oldbucket*uintptr(t.bucketsize)))
+		y := (*bmap)(add(h.buckets, (oldbucket+newbit)*uintptr(t.bucketsize)))
+		xi := 0
+		yi := 0
+		xk := add(unsafe.Pointer(x), dataOffset)
+		yk := add(unsafe.Pointer(y), dataOffset)
+		xv := add(xk, bucketCnt*uintptr(t.keysize))
+		yv := add(yk, bucketCnt*uintptr(t.keysize))
+		for ; b != nil; b = b.overflow {
+			k := add(unsafe.Pointer(b), dataOffset)
+			v := add(k, bucketCnt*uintptr(t.keysize))
+			for i := 0; i < bucketCnt; i, k, v = i+1, add(k, uintptr(t.keysize)), add(v, uintptr(t.valuesize)) {
+				top := b.tophash[i]
+				if top == empty {
+					b.tophash[i] = evacuatedEmpty
+					continue
+				}
+				if top < minTopHash {
+					gothrow("bad map state")
+				}
+				k2 := k
+				if t.indirectkey {
+					k2 = *((*unsafe.Pointer)(k2))
+				}
+				// Compute hash to make our evacuation decision (whether we need
+				// to send this key/value to bucket x or bucket y).
+				hash := alg.hash(k2, uintptr(t.key.size), uintptr(h.hash0))
+				if h.flags&iterator != 0 {
+					if !alg.equal(k2, k2, uintptr(t.key.size)) {
+						// If key != key (NaNs), then the hash could be (and probably
+						// will be) entirely different from the old hash.  Moreover,
+						// it isn't reproducible.  Reproducibility is required in the
+						// presence of iterators, as our evacuation decision must
+						// match whatever decision the iterator made.
+						// Fortunately, we have the freedom to send these keys either
+						// way.  Also, tophash is meaningless for these kinds of keys.
+						// We let the low bit of tophash drive the evacuation decision.
+						// We recompute a new random tophash for the next level so
+						// these keys will get evenly distributed across all buckets
+						// after multiple grows.
+						if (top & 1) != 0 {
+							hash |= newbit
+						} else {
+							hash &^= newbit
+						}
+						top = uint8(hash >> (ptrSize*8 - 8))
+						if top < minTopHash {
+							top += minTopHash
+						}
+					}
+				}
+				if (hash & newbit) == 0 {
+					b.tophash[i] = evacuatedX
+					if xi == bucketCnt {
+						if checkgc {
+							memstats.next_gc = memstats.heap_alloc
+						}
+						newx := (*bmap)(newobject(t.bucket))
+						x.overflow = newx
+						x = newx
+						xi = 0
+						xk = add(unsafe.Pointer(x), dataOffset)
+						xv = add(xk, bucketCnt*uintptr(t.keysize))
+					}
+					x.tophash[xi] = top
+					if t.indirectkey {
+						*(*unsafe.Pointer)(xk) = k2 // copy pointer
+					} else {
+						memmove(xk, k, uintptr(t.key.size)) // copy value
+					}
+					if t.indirectvalue {
+						*(*unsafe.Pointer)(xv) = *(*unsafe.Pointer)(v)
+					} else {
+						memmove(xv, v, uintptr(t.elem.size))
+					}
+					xi++
+					xk = add(xk, uintptr(t.keysize))
+					xv = add(xv, uintptr(t.valuesize))
+				} else {
+					b.tophash[i] = evacuatedY
+					if yi == bucketCnt {
+						if checkgc {
+							memstats.next_gc = memstats.heap_alloc
+						}
+						newy := (*bmap)(newobject(t.bucket))
+						y.overflow = newy
+						y = newy
+						yi = 0
+						yk = add(unsafe.Pointer(y), dataOffset)
+						yv = add(yk, bucketCnt*uintptr(t.keysize))
+					}
+					y.tophash[yi] = top
+					if t.indirectkey {
+						*(*unsafe.Pointer)(yk) = k2
+					} else {
+						memmove(yk, k, uintptr(t.key.size))
+					}
+					if t.indirectvalue {
+						*(*unsafe.Pointer)(yv) = *(*unsafe.Pointer)(v)
+					} else {
+						memmove(yv, v, uintptr(t.elem.size))
+					}
+					yi++
+					yk = add(yk, uintptr(t.keysize))
+					yv = add(yv, uintptr(t.valuesize))
+				}
+			}
+		}
+		// Unlink the overflow buckets & clear key/value to help GC.
+		if h.flags&oldIterator == 0 {
+			b = (*bmap)(add(h.oldbuckets, oldbucket*uintptr(t.bucketsize)))
+			b.overflow = nil
+			memclr(add(unsafe.Pointer(b), dataOffset), uintptr(t.bucketsize)-dataOffset)
+		}
+	}
+
+	// Advance evacuation mark
+	if oldbucket == h.nevacuate {
+		h.nevacuate = oldbucket + 1
+		if oldbucket+1 == newbit { // newbit == # of oldbuckets
+			// Growing is all done.  Free old main bucket array.
+			h.oldbuckets = nil
+		}
+	}
+}
+
+func ismapkey(t *_type) bool {
+	return goalg(t.alg).hash != nil
+}
+
+// Reflect stubs.  Called from ../reflect/asm_*.s
+
+func reflect_makemap(t *maptype) *hmap {
+	return makemap(t, 0)
+}
+
+func reflect_mapaccess(t *maptype, h *hmap, key unsafe.Pointer) unsafe.Pointer {
+	val, ok := mapaccess2(t, h, key)
+	if !ok {
+		// reflect wants nil for a missing element
+		val = nil
+	}
+	return val
+}
+
+func reflect_mapassign(t *maptype, h *hmap, key unsafe.Pointer, val unsafe.Pointer) {
+	mapassign1(t, h, key, val)
+}
+
+func reflect_mapdelete(t *maptype, h *hmap, key unsafe.Pointer) {
+	mapdelete(t, h, key)
+}
+
+func reflect_mapiterinit(t *maptype, h *hmap) *hiter {
+	it := new(hiter)
+	mapiterinit(t, h, it)
+	return it
+}
+
+func reflect_mapiternext(it *hiter) {
+	mapiternext(it)
+}
+
+func reflect_mapiterkey(it *hiter) unsafe.Pointer {
+	return it.key
+}
+
+func reflect_maplen(h *hmap) int {
+	if h == nil {
+		return 0
+	}
+	if raceenabled {
+		callerpc := getcallerpc(unsafe.Pointer(&h))
+		racereadpc(unsafe.Pointer(h), callerpc, funcPC(reflect_maplen))
+	}
+	return h.count
+}
+
+func reflect_ismapkey(t *_type) bool {
+	return ismapkey(t)
+}
diff --git a/src/runtime/hashmap_fast.go b/src/runtime/hashmap_fast.go
new file mode 100644
index 0000000..8e21e02
--- /dev/null
+++ b/src/runtime/hashmap_fast.go
@@ -0,0 +1,379 @@
+// 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 runtime
+
+import (
+	"unsafe"
+)
+
+func mapaccess1_fast32(t *maptype, h *hmap, key uint32) unsafe.Pointer {
+	if raceenabled && h != nil {
+		callerpc := getcallerpc(unsafe.Pointer(&t))
+		racereadpc(unsafe.Pointer(h), callerpc, funcPC(mapaccess1_fast32))
+	}
+	if h == nil || h.count == 0 {
+		return unsafe.Pointer(t.elem.zero)
+	}
+	var b *bmap
+	if h.B == 0 {
+		// One-bucket table.  No need to hash.
+		b = (*bmap)(h.buckets)
+	} else {
+		hash := goalg(t.key.alg).hash(noescape(unsafe.Pointer(&key)), 4, uintptr(h.hash0))
+		m := uintptr(1)<<h.B - 1
+		b = (*bmap)(add(h.buckets, (hash&m)*uintptr(t.bucketsize)))
+		if c := h.oldbuckets; c != nil {
+			oldb := (*bmap)(add(c, (hash&(m>>1))*uintptr(t.bucketsize)))
+			if !evacuated(oldb) {
+				b = oldb
+			}
+		}
+	}
+	for {
+		for i := uintptr(0); i < bucketCnt; i++ {
+			k := *((*uint32)(add(unsafe.Pointer(b), dataOffset+i*4)))
+			if k != key {
+				continue
+			}
+			x := *((*uint8)(add(unsafe.Pointer(b), i))) // b.topbits[i] without the bounds check
+			if x == empty {
+				continue
+			}
+			return add(unsafe.Pointer(b), dataOffset+bucketCnt*4+i*uintptr(t.valuesize))
+		}
+		b = b.overflow
+		if b == nil {
+			return unsafe.Pointer(t.elem.zero)
+		}
+	}
+}
+
+func mapaccess2_fast32(t *maptype, h *hmap, key uint32) (unsafe.Pointer, bool) {
+	if raceenabled && h != nil {
+		callerpc := getcallerpc(unsafe.Pointer(&t))
+		racereadpc(unsafe.Pointer(h), callerpc, funcPC(mapaccess2_fast32))
+	}
+	if h == nil || h.count == 0 {
+		return unsafe.Pointer(t.elem.zero), false
+	}
+	var b *bmap
+	if h.B == 0 {
+		// One-bucket table.  No need to hash.
+		b = (*bmap)(h.buckets)
+	} else {
+		hash := goalg(t.key.alg).hash(noescape(unsafe.Pointer(&key)), 4, uintptr(h.hash0))
+		m := uintptr(1)<<h.B - 1
+		b = (*bmap)(add(h.buckets, (hash&m)*uintptr(t.bucketsize)))
+		if c := h.oldbuckets; c != nil {
+			oldb := (*bmap)(add(c, (hash&(m>>1))*uintptr(t.bucketsize)))
+			if !evacuated(oldb) {
+				b = oldb
+			}
+		}
+	}
+	for {
+		for i := uintptr(0); i < bucketCnt; i++ {
+			k := *((*uint32)(add(unsafe.Pointer(b), dataOffset+i*4)))
+			if k != key {
+				continue
+			}
+			x := *((*uint8)(add(unsafe.Pointer(b), i))) // b.topbits[i] without the bounds check
+			if x == empty {
+				continue
+			}
+			return add(unsafe.Pointer(b), dataOffset+bucketCnt*4+i*uintptr(t.valuesize)), true
+		}
+		b = b.overflow
+		if b == nil {
+			return unsafe.Pointer(t.elem.zero), false
+		}
+	}
+}
+
+func mapaccess1_fast64(t *maptype, h *hmap, key uint64) unsafe.Pointer {
+	if raceenabled && h != nil {
+		callerpc := getcallerpc(unsafe.Pointer(&t))
+		racereadpc(unsafe.Pointer(h), callerpc, funcPC(mapaccess1_fast64))
+	}
+	if h == nil || h.count == 0 {
+		return unsafe.Pointer(t.elem.zero)
+	}
+	var b *bmap
+	if h.B == 0 {
+		// One-bucket table.  No need to hash.
+		b = (*bmap)(h.buckets)
+	} else {
+		hash := goalg(t.key.alg).hash(noescape(unsafe.Pointer(&key)), 8, uintptr(h.hash0))
+		m := uintptr(1)<<h.B - 1
+		b = (*bmap)(add(h.buckets, (hash&m)*uintptr(t.bucketsize)))
+		if c := h.oldbuckets; c != nil {
+			oldb := (*bmap)(add(c, (hash&(m>>1))*uintptr(t.bucketsize)))
+			if !evacuated(oldb) {
+				b = oldb
+			}
+		}
+	}
+	for {
+		for i := uintptr(0); i < bucketCnt; i++ {
+			k := *((*uint64)(add(unsafe.Pointer(b), dataOffset+i*8)))
+			if k != key {
+				continue
+			}
+			x := *((*uint8)(add(unsafe.Pointer(b), i))) // b.topbits[i] without the bounds check
+			if x == empty {
+				continue
+			}
+			return add(unsafe.Pointer(b), dataOffset+bucketCnt*8+i*uintptr(t.valuesize))
+		}
+		b = b.overflow
+		if b == nil {
+			return unsafe.Pointer(t.elem.zero)
+		}
+	}
+}
+
+func mapaccess2_fast64(t *maptype, h *hmap, key uint64) (unsafe.Pointer, bool) {
+	if raceenabled && h != nil {
+		callerpc := getcallerpc(unsafe.Pointer(&t))
+		racereadpc(unsafe.Pointer(h), callerpc, funcPC(mapaccess2_fast64))
+	}
+	if h == nil || h.count == 0 {
+		return unsafe.Pointer(t.elem.zero), false
+	}
+	var b *bmap
+	if h.B == 0 {
+		// One-bucket table.  No need to hash.
+		b = (*bmap)(h.buckets)
+	} else {
+		hash := goalg(t.key.alg).hash(noescape(unsafe.Pointer(&key)), 8, uintptr(h.hash0))
+		m := uintptr(1)<<h.B - 1
+		b = (*bmap)(add(h.buckets, (hash&m)*uintptr(t.bucketsize)))
+		if c := h.oldbuckets; c != nil {
+			oldb := (*bmap)(add(c, (hash&(m>>1))*uintptr(t.bucketsize)))
+			if !evacuated(oldb) {
+				b = oldb
+			}
+		}
+	}
+	for {
+		for i := uintptr(0); i < bucketCnt; i++ {
+			k := *((*uint64)(add(unsafe.Pointer(b), dataOffset+i*8)))
+			if k != key {
+				continue
+			}
+			x := *((*uint8)(add(unsafe.Pointer(b), i))) // b.topbits[i] without the bounds check
+			if x == empty {
+				continue
+			}
+			return add(unsafe.Pointer(b), dataOffset+bucketCnt*8+i*uintptr(t.valuesize)), true
+		}
+		b = b.overflow
+		if b == nil {
+			return unsafe.Pointer(t.elem.zero), false
+		}
+	}
+}
+
+func mapaccess1_faststr(t *maptype, h *hmap, ky string) unsafe.Pointer {
+	if raceenabled && h != nil {
+		callerpc := getcallerpc(unsafe.Pointer(&t))
+		racereadpc(unsafe.Pointer(h), callerpc, funcPC(mapaccess1_faststr))
+	}
+	if h == nil || h.count == 0 {
+		return unsafe.Pointer(t.elem.zero)
+	}
+	key := (*stringStruct)(unsafe.Pointer(&ky))
+	if h.B == 0 {
+		// One-bucket table.
+		b := (*bmap)(h.buckets)
+		if key.len < 32 {
+			// short key, doing lots of comparisons is ok
+			for i := uintptr(0); i < bucketCnt; i++ {
+				x := *((*uint8)(add(unsafe.Pointer(b), i))) // b.topbits[i] without the bounds check
+				if x == empty {
+					continue
+				}
+				k := (*stringStruct)(add(unsafe.Pointer(b), dataOffset+i*2*ptrSize))
+				if k.len != key.len {
+					continue
+				}
+				if k.str == key.str || memeq(k.str, key.str, uintptr(key.len)) {
+					return add(unsafe.Pointer(b), dataOffset+bucketCnt*2*ptrSize+i*uintptr(t.valuesize))
+				}
+			}
+			return unsafe.Pointer(t.elem.zero)
+		}
+		// long key, try not to do more comparisons than necessary
+		keymaybe := uintptr(bucketCnt)
+		for i := uintptr(0); i < bucketCnt; i++ {
+			x := *((*uint8)(add(unsafe.Pointer(b), i))) // b.topbits[i] without the bounds check
+			if x == empty {
+				continue
+			}
+			k := (*stringStruct)(add(unsafe.Pointer(b), dataOffset+i*2*ptrSize))
+			if k.len != key.len {
+				continue
+			}
+			if k.str == key.str {
+				return add(unsafe.Pointer(b), dataOffset+bucketCnt*2*ptrSize+i*uintptr(t.valuesize))
+			}
+			// check first 4 bytes
+			// TODO: on amd64/386 at least, make this compile to one 4-byte comparison instead of
+			// four 1-byte comparisons.
+			if *((*[4]byte)(key.str)) != *((*[4]byte)(k.str)) {
+				continue
+			}
+			// check last 4 bytes
+			if *((*[4]byte)(add(key.str, uintptr(key.len)-4))) != *((*[4]byte)(add(k.str, uintptr(key.len)-4))) {
+				continue
+			}
+			if keymaybe != bucketCnt {
+				// Two keys are potential matches.  Use hash to distinguish them.
+				goto dohash
+			}
+			keymaybe = i
+		}
+		if keymaybe != bucketCnt {
+			k := (*stringStruct)(add(unsafe.Pointer(b), dataOffset+keymaybe*2*ptrSize))
+			if memeq(k.str, key.str, uintptr(key.len)) {
+				return add(unsafe.Pointer(b), dataOffset+bucketCnt*2*ptrSize+keymaybe*uintptr(t.valuesize))
+			}
+		}
+		return unsafe.Pointer(t.elem.zero)
+	}
+dohash:
+	hash := goalg(t.key.alg).hash(noescape(unsafe.Pointer(&ky)), 2*ptrSize, uintptr(h.hash0))
+	m := uintptr(1)<<h.B - 1
+	b := (*bmap)(add(h.buckets, (hash&m)*uintptr(t.bucketsize)))
+	if c := h.oldbuckets; c != nil {
+		oldb := (*bmap)(add(c, (hash&(m>>1))*uintptr(t.bucketsize)))
+		if !evacuated(oldb) {
+			b = oldb
+		}
+	}
+	top := uint8(hash >> (ptrSize*8 - 8))
+	if top < minTopHash {
+		top += minTopHash
+	}
+	for {
+		for i := uintptr(0); i < bucketCnt; i++ {
+			x := *((*uint8)(add(unsafe.Pointer(b), i))) // b.topbits[i] without the bounds check
+			if x != top {
+				continue
+			}
+			k := (*stringStruct)(add(unsafe.Pointer(b), dataOffset+i*2*ptrSize))
+			if k.len != key.len {
+				continue
+			}
+			if k.str == key.str || memeq(k.str, key.str, uintptr(key.len)) {
+				return add(unsafe.Pointer(b), dataOffset+bucketCnt*2*ptrSize+i*uintptr(t.valuesize))
+			}
+		}
+		b = b.overflow
+		if b == nil {
+			return unsafe.Pointer(t.elem.zero)
+		}
+	}
+}
+
+func mapaccess2_faststr(t *maptype, h *hmap, ky string) (unsafe.Pointer, bool) {
+	if raceenabled && h != nil {
+		callerpc := getcallerpc(unsafe.Pointer(&t))
+		racereadpc(unsafe.Pointer(h), callerpc, funcPC(mapaccess2_faststr))
+	}
+	if h == nil || h.count == 0 {
+		return unsafe.Pointer(t.elem.zero), false
+	}
+	key := (*stringStruct)(unsafe.Pointer(&ky))
+	if h.B == 0 {
+		// One-bucket table.
+		b := (*bmap)(h.buckets)
+		if key.len < 32 {
+			// short key, doing lots of comparisons is ok
+			for i := uintptr(0); i < bucketCnt; i++ {
+				x := *((*uint8)(add(unsafe.Pointer(b), i))) // b.topbits[i] without the bounds check
+				if x == empty {
+					continue
+				}
+				k := (*stringStruct)(add(unsafe.Pointer(b), dataOffset+i*2*ptrSize))
+				if k.len != key.len {
+					continue
+				}
+				if k.str == key.str || memeq(k.str, key.str, uintptr(key.len)) {
+					return add(unsafe.Pointer(b), dataOffset+bucketCnt*2*ptrSize+i*uintptr(t.valuesize)), true
+				}
+			}
+			return unsafe.Pointer(t.elem.zero), false
+		}
+		// long key, try not to do more comparisons than necessary
+		keymaybe := uintptr(bucketCnt)
+		for i := uintptr(0); i < bucketCnt; i++ {
+			x := *((*uint8)(add(unsafe.Pointer(b), i))) // b.topbits[i] without the bounds check
+			if x == empty {
+				continue
+			}
+			k := (*stringStruct)(add(unsafe.Pointer(b), dataOffset+i*2*ptrSize))
+			if k.len != key.len {
+				continue
+			}
+			if k.str == key.str {
+				return add(unsafe.Pointer(b), dataOffset+bucketCnt*2*ptrSize+i*uintptr(t.valuesize)), true
+			}
+			// check first 4 bytes
+			if *((*[4]byte)(key.str)) != *((*[4]byte)(k.str)) {
+				continue
+			}
+			// check last 4 bytes
+			if *((*[4]byte)(add(key.str, uintptr(key.len)-4))) != *((*[4]byte)(add(k.str, uintptr(key.len)-4))) {
+				continue
+			}
+			if keymaybe != bucketCnt {
+				// Two keys are potential matches.  Use hash to distinguish them.
+				goto dohash
+			}
+			keymaybe = i
+		}
+		if keymaybe != bucketCnt {
+			k := (*stringStruct)(add(unsafe.Pointer(b), dataOffset+keymaybe*2*ptrSize))
+			if memeq(k.str, key.str, uintptr(key.len)) {
+				return add(unsafe.Pointer(b), dataOffset+bucketCnt*2*ptrSize+keymaybe*uintptr(t.valuesize)), true
+			}
+		}
+		return unsafe.Pointer(t.elem.zero), false
+	}
+dohash:
+	hash := goalg(t.key.alg).hash(noescape(unsafe.Pointer(&ky)), 2*ptrSize, uintptr(h.hash0))
+	m := uintptr(1)<<h.B - 1
+	b := (*bmap)(add(h.buckets, (hash&m)*uintptr(t.bucketsize)))
+	if c := h.oldbuckets; c != nil {
+		oldb := (*bmap)(add(c, (hash&(m>>1))*uintptr(t.bucketsize)))
+		if !evacuated(oldb) {
+			b = oldb
+		}
+	}
+	top := uint8(hash >> (ptrSize*8 - 8))
+	if top < minTopHash {
+		top += minTopHash
+	}
+	for {
+		for i := uintptr(0); i < bucketCnt; i++ {
+			x := *((*uint8)(add(unsafe.Pointer(b), i))) // b.topbits[i] without the bounds check
+			if x != top {
+				continue
+			}
+			k := (*stringStruct)(add(unsafe.Pointer(b), dataOffset+i*2*ptrSize))
+			if k.len != key.len {
+				continue
+			}
+			if k.str == key.str || memeq(k.str, key.str, uintptr(key.len)) {
+				return add(unsafe.Pointer(b), dataOffset+bucketCnt*2*ptrSize+i*uintptr(t.valuesize)), true
+			}
+		}
+		b = b.overflow
+		if b == nil {
+			return unsafe.Pointer(t.elem.zero), false
+		}
+	}
+}
diff --git a/src/runtime/heapdump.c b/src/runtime/heapdump.c
new file mode 100644
index 0000000..7eba8c0
--- /dev/null
+++ b/src/runtime/heapdump.c
@@ -0,0 +1,864 @@
+// 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.
+
+// Implementation of runtime/debug.WriteHeapDump.  Writes all
+// objects in the heap plus additional info (roots, threads,
+// finalizers, etc.) to a file.
+
+// The format of the dumped file is described at
+// http://golang.org/s/go14heapdump.
+
+#include "runtime.h"
+#include "arch_GOARCH.h"
+#include "malloc.h"
+#include "mgc0.h"
+#include "type.h"
+#include "typekind.h"
+#include "funcdata.h"
+#include "zaexperiment.h"
+#include "textflag.h"
+
+extern byte runtime·data[];
+extern byte runtime·edata[];
+extern byte runtime·bss[];
+extern byte runtime·ebss[];
+
+enum {
+	FieldKindEol = 0,
+	FieldKindPtr = 1,
+	FieldKindIface = 2,
+	FieldKindEface = 3,
+
+	TagEOF = 0,
+	TagObject = 1,
+	TagOtherRoot = 2,
+	TagType = 3,
+	TagGoRoutine = 4,
+	TagStackFrame = 5,
+	TagParams = 6,
+	TagFinalizer = 7,
+	TagItab = 8,
+	TagOSThread = 9,
+	TagMemStats = 10,
+	TagQueuedFinalizer = 11,
+	TagData = 12,
+	TagBss = 13,
+	TagDefer = 14,
+	TagPanic = 15,
+	TagMemProf = 16,
+	TagAllocSample = 17,
+};
+
+static uintptr* playgcprog(uintptr offset, uintptr *prog, void (*callback)(void*,uintptr,uintptr), void *arg);
+static void dumpfields(BitVector bv);
+static void dumpbvtypes(BitVector *bv, byte *base);
+static BitVector makeheapobjbv(byte *p, uintptr size);
+
+// fd to write the dump to.
+static uintptr	dumpfd;
+
+#pragma dataflag NOPTR /* tmpbuf not a heap pointer at least */
+static byte	*tmpbuf;
+static uintptr	tmpbufsize;
+
+// buffer of pending write data
+enum {
+	BufSize = 4096,
+};
+#pragma dataflag NOPTR
+static byte buf[BufSize];
+static uintptr nbuf;
+
+static void
+write(byte *data, uintptr len)
+{
+	if(len + nbuf <= BufSize) {
+		runtime·memmove(buf + nbuf, data, len);
+		nbuf += len;
+		return;
+	}
+	runtime·write(dumpfd, buf, nbuf);
+	if(len >= BufSize) {
+		runtime·write(dumpfd, data, len);
+		nbuf = 0;
+	} else {
+		runtime·memmove(buf, data, len);
+		nbuf = len;
+	}
+}
+
+static void
+flush(void)
+{
+	runtime·write(dumpfd, buf, nbuf);
+	nbuf = 0;
+}
+
+// Cache of types that have been serialized already.
+// We use a type's hash field to pick a bucket.
+// Inside a bucket, we keep a list of types that
+// have been serialized so far, most recently used first.
+// Note: when a bucket overflows we may end up
+// serializing a type more than once.  That's ok.
+enum {
+	TypeCacheBuckets = 256, // must be a power of 2
+	TypeCacheAssoc = 4,
+};
+typedef struct TypeCacheBucket TypeCacheBucket;
+struct TypeCacheBucket {
+	Type *t[TypeCacheAssoc];
+};
+#pragma dataflag NOPTR /* only initialized and used while world is stopped */
+static TypeCacheBucket typecache[TypeCacheBuckets];
+
+// dump a uint64 in a varint format parseable by encoding/binary
+static void
+dumpint(uint64 v)
+{
+	byte buf[10];
+	int32 n;
+	n = 0;
+	while(v >= 0x80) {
+		buf[n++] = v | 0x80;
+		v >>= 7;
+	}
+	buf[n++] = v;
+	write(buf, n);
+}
+
+static void
+dumpbool(bool b)
+{
+	dumpint(b ? 1 : 0);
+}
+
+// dump varint uint64 length followed by memory contents
+static void
+dumpmemrange(byte *data, uintptr len)
+{
+	dumpint(len);
+	write(data, len);
+}
+
+static void
+dumpstr(String s)
+{
+	dumpmemrange(s.str, s.len);
+}
+
+static void
+dumpcstr(int8 *c)
+{
+	dumpmemrange((byte*)c, runtime·findnull((byte*)c));
+}
+
+// dump information for a type
+static void
+dumptype(Type *t)
+{
+	TypeCacheBucket *b;
+	int32 i, j;
+
+	if(t == nil) {
+		return;
+	}
+
+	// If we've definitely serialized the type before,
+	// no need to do it again.
+	b = &typecache[t->hash & (TypeCacheBuckets-1)];
+	if(t == b->t[0]) return;
+	for(i = 1; i < TypeCacheAssoc; i++) {
+		if(t == b->t[i]) {
+			// Move-to-front
+			for(j = i; j > 0; j--) {
+				b->t[j] = b->t[j-1];
+			}
+			b->t[0] = t;
+			return;
+		}
+	}
+	// Might not have been dumped yet.  Dump it and
+	// remember we did so.
+	for(j = TypeCacheAssoc-1; j > 0; j--) {
+		b->t[j] = b->t[j-1];
+	}
+	b->t[0] = t;
+	
+	// dump the type
+	dumpint(TagType);
+	dumpint((uintptr)t);
+	dumpint(t->size);
+	if(t->x == nil || t->x->pkgPath == nil || t->x->name == nil) {
+		dumpstr(*t->string);
+	} else {
+		dumpint(t->x->pkgPath->len + 1 + t->x->name->len);
+		write(t->x->pkgPath->str, t->x->pkgPath->len);
+		write((byte*)".", 1);
+		write(t->x->name->str, t->x->name->len);
+	}
+	dumpbool((t->kind & KindDirectIface) == 0 || (t->kind & KindNoPointers) == 0);
+}
+
+// dump an object
+static void
+dumpobj(byte *obj, uintptr size, BitVector bv)
+{
+	dumpbvtypes(&bv, obj);
+	dumpint(TagObject);
+	dumpint((uintptr)obj);
+	dumpmemrange(obj, size);
+	dumpfields(bv);
+}
+
+static void
+dumpotherroot(int8 *description, byte *to)
+{
+	dumpint(TagOtherRoot);
+	dumpcstr(description);
+	dumpint((uintptr)to);
+}
+
+static void
+dumpfinalizer(byte *obj, FuncVal *fn, Type* fint, PtrType *ot)
+{
+	dumpint(TagFinalizer);
+	dumpint((uintptr)obj);
+	dumpint((uintptr)fn);
+	dumpint((uintptr)fn->fn);
+	dumpint((uintptr)fint);
+	dumpint((uintptr)ot);
+}
+
+typedef struct ChildInfo ChildInfo;
+struct ChildInfo {
+	// Information passed up from the callee frame about
+	// the layout of the outargs region.
+	uintptr argoff;     // where the arguments start in the frame
+	uintptr arglen;     // size of args region
+	BitVector args;    // if args.n >= 0, pointer map of args region
+
+	byte *sp;           // callee sp
+	uintptr depth;      // depth in call stack (0 == most recent)
+};
+
+// dump kinds & offsets of interesting fields in bv
+static void
+dumpbv(BitVector *bv, uintptr offset)
+{
+	uintptr i;
+
+	for(i = 0; i < bv->n; i += BitsPerPointer) {
+		switch(bv->bytedata[i/8] >> i%8 & 3) {
+		case BitsDead:
+			// BitsDead has already been processed in makeheapobjbv.
+			// We should only see it in stack maps, in which case we should continue processing.
+			break;
+		case BitsScalar:
+			break;
+		case BitsPointer:
+			dumpint(FieldKindPtr);
+			dumpint(offset + i / BitsPerPointer * PtrSize);
+			break;
+		case BitsMultiWord:
+			switch(bv->bytedata[(i+BitsPerPointer)/8] >> (i+BitsPerPointer)%8 & 3) {
+			default:
+				runtime·throw("unexpected garbage collection bits");
+			case BitsIface:
+				dumpint(FieldKindIface);
+				dumpint(offset + i / BitsPerPointer * PtrSize);
+				i += BitsPerPointer;
+				break;
+			case BitsEface:
+				dumpint(FieldKindEface);
+				dumpint(offset + i / BitsPerPointer * PtrSize);
+				i += BitsPerPointer;
+				break;
+			}
+		}
+	}
+}
+
+static bool
+dumpframe(Stkframe *s, void *arg)
+{
+	Func *f;
+	ChildInfo *child;
+	uintptr pc, off, size;
+	int32 pcdata;
+	StackMap *stackmap;
+	int8 *name;
+	BitVector bv;
+
+	child = (ChildInfo*)arg;
+	f = s->fn;
+
+	// Figure out what we can about our stack map
+	pc = s->pc;
+	if(pc != f->entry)
+		pc--;
+	pcdata = runtime·pcdatavalue(f, PCDATA_StackMapIndex, pc);
+	if(pcdata == -1) {
+		// We do not have a valid pcdata value but there might be a
+		// stackmap for this function.  It is likely that we are looking
+		// at the function prologue, assume so and hope for the best.
+		pcdata = 0;
+	}
+	stackmap = runtime·funcdata(f, FUNCDATA_LocalsPointerMaps);
+
+	// Dump any types we will need to resolve Efaces.
+	if(child->args.n >= 0)
+		dumpbvtypes(&child->args, (byte*)s->sp + child->argoff);
+	if(stackmap != nil && stackmap->n > 0) {
+		bv = runtime·stackmapdata(stackmap, pcdata);
+		dumpbvtypes(&bv, (byte*)(s->varp - bv.n / BitsPerPointer * PtrSize));
+	} else {
+		bv.n = -1;
+	}
+
+	// Dump main body of stack frame.
+	dumpint(TagStackFrame);
+	dumpint(s->sp); // lowest address in frame
+	dumpint(child->depth); // # of frames deep on the stack
+	dumpint((uintptr)child->sp); // sp of child, or 0 if bottom of stack
+	dumpmemrange((byte*)s->sp, s->fp - s->sp);  // frame contents
+	dumpint(f->entry);
+	dumpint(s->pc);
+	dumpint(s->continpc);
+	name = runtime·funcname(f);
+	if(name == nil)
+		name = "unknown function";
+	dumpcstr(name);
+
+	// Dump fields in the outargs section
+	if(child->args.n >= 0) {
+		dumpbv(&child->args, child->argoff);
+	} else {
+		// conservative - everything might be a pointer
+		for(off = child->argoff; off < child->argoff + child->arglen; off += PtrSize) {
+			dumpint(FieldKindPtr);
+			dumpint(off);
+		}
+	}
+
+	// Dump fields in the local vars section
+	if(stackmap == nil) {
+		// No locals information, dump everything.
+		for(off = child->arglen; off < s->varp - s->sp; off += PtrSize) {
+			dumpint(FieldKindPtr);
+			dumpint(off);
+		}
+	} else if(stackmap->n < 0) {
+		// Locals size information, dump just the locals.
+		size = -stackmap->n;
+		for(off = s->varp - size - s->sp; off <  s->varp - s->sp; off += PtrSize) {
+			dumpint(FieldKindPtr);
+			dumpint(off);
+		}
+	} else if(stackmap->n > 0) {
+		// Locals bitmap information, scan just the pointers in
+		// locals.
+		dumpbv(&bv, s->varp - bv.n / BitsPerPointer * PtrSize - s->sp);
+	}
+	dumpint(FieldKindEol);
+
+	// Record arg info for parent.
+	child->argoff = s->argp - s->fp;
+	child->arglen = s->arglen;
+	child->sp = (byte*)s->sp;
+	child->depth++;
+	stackmap = runtime·funcdata(f, FUNCDATA_ArgsPointerMaps);
+	if(stackmap != nil)
+		child->args = runtime·stackmapdata(stackmap, pcdata);
+	else
+		child->args.n = -1;
+	return true;
+}
+
+static void
+dumpgoroutine(G *gp)
+{
+	uintptr sp, pc, lr;
+	ChildInfo child;
+	Defer *d;
+	Panic *p;
+	bool (*fn)(Stkframe*, void*);
+
+	if(gp->syscallsp != (uintptr)nil) {
+		sp = gp->syscallsp;
+		pc = gp->syscallpc;
+		lr = 0;
+	} else {
+		sp = gp->sched.sp;
+		pc = gp->sched.pc;
+		lr = gp->sched.lr;
+	}
+
+	dumpint(TagGoRoutine);
+	dumpint((uintptr)gp);
+	dumpint((uintptr)sp);
+	dumpint(gp->goid);
+	dumpint(gp->gopc);
+	dumpint(runtime·readgstatus(gp));
+	dumpbool(gp->issystem);
+	dumpbool(false);  // isbackground
+	dumpint(gp->waitsince);
+	dumpstr(gp->waitreason);
+	dumpint((uintptr)gp->sched.ctxt);
+	dumpint((uintptr)gp->m);
+	dumpint((uintptr)gp->defer);
+	dumpint((uintptr)gp->panic);
+
+	// dump stack
+	child.args.n = -1;
+	child.arglen = 0;
+	child.sp = nil;
+	child.depth = 0;
+	fn = dumpframe;
+	runtime·gentraceback(pc, sp, lr, gp, 0, nil, 0x7fffffff, &fn, &child, 0);
+
+	// dump defer & panic records
+	for(d = gp->defer; d != nil; d = d->link) {
+		dumpint(TagDefer);
+		dumpint((uintptr)d);
+		dumpint((uintptr)gp);
+		dumpint((uintptr)d->argp);
+		dumpint((uintptr)d->pc);
+		dumpint((uintptr)d->fn);
+		dumpint((uintptr)d->fn->fn);
+		dumpint((uintptr)d->link);
+	}
+	for (p = gp->panic; p != nil; p = p->link) {
+		dumpint(TagPanic);
+		dumpint((uintptr)p);
+		dumpint((uintptr)gp);
+		dumpint((uintptr)p->arg.type);
+		dumpint((uintptr)p->arg.data);
+		dumpint(0); // was p->defer, no longer recorded
+		dumpint((uintptr)p->link);
+	}
+}
+
+static void
+dumpgs(void)
+{
+	G *gp;
+	uint32 i;
+	uint32 status;
+
+	// goroutines & stacks
+	for(i = 0; i < runtime·allglen; i++) {
+		gp = runtime·allg[i];
+		status = runtime·readgstatus(gp); // The world is stopped so gp will not be in a scan state.
+		switch(status){
+		default:
+			runtime·printf("runtime: unexpected G.status %d\n", status);
+			runtime·throw("dumpgs in STW - bad status");
+		case Gdead:
+			break;
+		case Grunnable:
+		case Gsyscall:
+		case Gwaiting:
+			dumpgoroutine(gp);
+			break;
+		}
+	}
+}
+
+static void
+finq_callback(FuncVal *fn, byte *obj, uintptr nret, Type *fint, PtrType *ot)
+{
+	dumpint(TagQueuedFinalizer);
+	dumpint((uintptr)obj);
+	dumpint((uintptr)fn);
+	dumpint((uintptr)fn->fn);
+	dumpint((uintptr)fint);
+	dumpint((uintptr)ot);
+	USED(&nret);
+}
+
+
+static void
+dumproots(void)
+{
+	MSpan *s, **allspans;
+	uint32 spanidx;
+	Special *sp;
+	SpecialFinalizer *spf;
+	byte *p;
+
+	// data segment
+	dumpbvtypes(&runtime·gcdatamask, runtime·data);
+	dumpint(TagData);
+	dumpint((uintptr)runtime·data);
+	dumpmemrange(runtime·data, runtime·edata - runtime·data);
+	dumpfields(runtime·gcdatamask);
+
+	// bss segment
+	dumpbvtypes(&runtime·gcbssmask, runtime·bss);
+	dumpint(TagBss);
+	dumpint((uintptr)runtime·bss);
+	dumpmemrange(runtime·bss, runtime·ebss - runtime·bss);
+	dumpfields(runtime·gcbssmask);
+
+	// MSpan.types
+	allspans = runtime·mheap.allspans;
+	for(spanidx=0; spanidx<runtime·mheap.nspan; spanidx++) {
+		s = allspans[spanidx];
+		if(s->state == MSpanInUse) {
+			// Finalizers
+			for(sp = s->specials; sp != nil; sp = sp->next) {
+				if(sp->kind != KindSpecialFinalizer)
+					continue;
+				spf = (SpecialFinalizer*)sp;
+				p = (byte*)((s->start << PageShift) + spf->special.offset);
+				dumpfinalizer(p, spf->fn, spf->fint, spf->ot);
+			}
+		}
+	}
+
+	// Finalizer queue
+	runtime·iterate_finq(finq_callback);
+}
+
+// Bit vector of free marks.	
+// Needs to be as big as the largest number of objects per span.	
+#pragma dataflag NOPTR
+static byte free[PageSize/8];	
+
+static void
+dumpobjs(void)
+{
+	uintptr i, j, size, n;
+	MSpan *s;
+	MLink *l;
+	byte *p;
+
+	for(i = 0; i < runtime·mheap.nspan; i++) {
+		s = runtime·mheap.allspans[i];
+		if(s->state != MSpanInUse)
+			continue;
+		p = (byte*)(s->start << PageShift);
+		size = s->elemsize;
+		n = (s->npages << PageShift) / size;
+		if(n > nelem(free))	
+			runtime·throw("free array doesn't have enough entries");	
+		for(l = s->freelist; l != nil; l = l->next)
+			free[((byte*)l - p) / size] = true;	
+		for(j = 0; j < n; j++, p += size) {
+			if(free[j]) {	
+				free[j] = false;	
+				continue;	
+			}
+			dumpobj(p, size, makeheapobjbv(p, size));
+		}
+	}
+}
+
+static void
+dumpparams(void)
+{
+	byte *x;
+
+	dumpint(TagParams);
+	x = (byte*)1;
+	if(*(byte*)&x == 1)
+		dumpbool(false); // little-endian ptrs
+	else
+		dumpbool(true); // big-endian ptrs
+	dumpint(PtrSize);
+	dumpint((uintptr)runtime·mheap.arena_start);
+	dumpint((uintptr)runtime·mheap.arena_used);
+	dumpint(thechar);
+	dumpcstr(GOEXPERIMENT);
+	dumpint(runtime·ncpu);
+}
+
+static void
+itab_callback(Itab *tab)
+{
+	Type *t;
+
+	t = tab->type;
+	// Dump a map from itab* to the type of its data field.
+	// We want this map so we can deduce types of interface referents.
+	if((t->kind & KindDirectIface) == 0) {
+		// indirect - data slot is a pointer to t.
+		dumptype(t->ptrto);
+		dumpint(TagItab);
+		dumpint((uintptr)tab);
+		dumpint((uintptr)t->ptrto);
+	} else if((t->kind & KindNoPointers) == 0) {
+		// t is pointer-like - data slot is a t.
+		dumptype(t);
+		dumpint(TagItab);
+		dumpint((uintptr)tab);
+		dumpint((uintptr)t);
+	} else {
+		// Data slot is a scalar.  Dump type just for fun.
+		// With pointer-only interfaces, this shouldn't happen.
+		dumptype(t);
+		dumpint(TagItab);
+		dumpint((uintptr)tab);
+		dumpint((uintptr)t);
+	}
+}
+
+static void
+dumpitabs(void)
+{
+	void (*fn)(Itab*);
+	
+	fn = itab_callback;
+	runtime·iterate_itabs(&fn);
+}
+
+static void
+dumpms(void)
+{
+	M *mp;
+
+	for(mp = runtime·allm; mp != nil; mp = mp->alllink) {
+		dumpint(TagOSThread);
+		dumpint((uintptr)mp);
+		dumpint(mp->id);
+		dumpint(mp->procid);
+	}
+}
+
+static void
+dumpmemstats(void)
+{
+	int32 i;
+
+	dumpint(TagMemStats);
+	dumpint(mstats.alloc);
+	dumpint(mstats.total_alloc);
+	dumpint(mstats.sys);
+	dumpint(mstats.nlookup);
+	dumpint(mstats.nmalloc);
+	dumpint(mstats.nfree);
+	dumpint(mstats.heap_alloc);
+	dumpint(mstats.heap_sys);
+	dumpint(mstats.heap_idle);
+	dumpint(mstats.heap_inuse);
+	dumpint(mstats.heap_released);
+	dumpint(mstats.heap_objects);
+	dumpint(mstats.stacks_inuse);
+	dumpint(mstats.stacks_sys);
+	dumpint(mstats.mspan_inuse);
+	dumpint(mstats.mspan_sys);
+	dumpint(mstats.mcache_inuse);
+	dumpint(mstats.mcache_sys);
+	dumpint(mstats.buckhash_sys);
+	dumpint(mstats.gc_sys);
+	dumpint(mstats.other_sys);
+	dumpint(mstats.next_gc);
+	dumpint(mstats.last_gc);
+	dumpint(mstats.pause_total_ns);
+	for(i = 0; i < 256; i++)
+		dumpint(mstats.pause_ns[i]);
+	dumpint(mstats.numgc);
+}
+
+static void
+dumpmemprof_callback(Bucket *b, uintptr nstk, uintptr *stk, uintptr size, uintptr allocs, uintptr frees)
+{
+	uintptr i, pc;
+	Func *f;
+	byte buf[20];
+	String file;
+	int32 line;
+
+	dumpint(TagMemProf);
+	dumpint((uintptr)b);
+	dumpint(size);
+	dumpint(nstk);
+	for(i = 0; i < nstk; i++) {
+		pc = stk[i];
+		f = runtime·findfunc(pc);
+		if(f == nil) {
+			runtime·snprintf(buf, sizeof(buf), "%X", (uint64)pc);
+			dumpcstr((int8*)buf);
+			dumpcstr("?");
+			dumpint(0);
+		} else {
+			dumpcstr(runtime·funcname(f));
+			// TODO: Why do we need to back up to a call instruction here?
+			// Maybe profiler should do this.
+			if(i > 0 && pc > f->entry) {
+				if(thechar == '6' || thechar == '8')
+					pc--;
+				else
+					pc -= 4; // arm, etc
+			}
+			line = runtime·funcline(f, pc, &file);
+			dumpstr(file);
+			dumpint(line);
+		}
+	}
+	dumpint(allocs);
+	dumpint(frees);
+}
+
+static void
+dumpmemprof(void)
+{
+	MSpan *s, **allspans;
+	uint32 spanidx;
+	Special *sp;
+	SpecialProfile *spp;
+	byte *p;
+	void (*fn)(Bucket*, uintptr, uintptr*, uintptr, uintptr, uintptr);
+	
+	fn = dumpmemprof_callback;
+	runtime·iterate_memprof(&fn);
+
+	allspans = runtime·mheap.allspans;
+	for(spanidx=0; spanidx<runtime·mheap.nspan; spanidx++) {
+		s = allspans[spanidx];
+		if(s->state != MSpanInUse)
+			continue;
+		for(sp = s->specials; sp != nil; sp = sp->next) {
+			if(sp->kind != KindSpecialProfile)
+				continue;
+			spp = (SpecialProfile*)sp;
+			p = (byte*)((s->start << PageShift) + spp->special.offset);
+			dumpint(TagAllocSample);
+			dumpint((uintptr)p);
+			dumpint((uintptr)spp->b);
+		}
+	}
+}
+
+static void
+mdump(void)
+{
+	byte *hdr;
+	uintptr i;
+	MSpan *s;
+
+	// make sure we're done sweeping
+	for(i = 0; i < runtime·mheap.nspan; i++) {
+		s = runtime·mheap.allspans[i];
+		if(s->state == MSpanInUse)
+			runtime·MSpan_EnsureSwept(s);
+	}
+
+	runtime·memclr((byte*)&typecache[0], sizeof(typecache));
+	hdr = (byte*)"go1.4 heap dump\n";
+	write(hdr, runtime·findnull(hdr));
+	dumpparams();
+	dumpitabs();
+	dumpobjs();
+	dumpgs();
+	dumpms();
+	dumproots();
+	dumpmemstats();
+	dumpmemprof();
+	dumpint(TagEOF);
+	flush();
+}
+
+void
+runtime·writeheapdump_m(void)
+{
+	uintptr fd;
+	
+	fd = g->m->scalararg[0];
+	g->m->scalararg[0] = 0;
+
+	runtime·casgstatus(g->m->curg, Grunning, Gwaiting);
+	g->waitreason = runtime·gostringnocopy((byte*)"dumping heap");
+
+	// Update stats so we can dump them.
+	// As a side effect, flushes all the MCaches so the MSpan.freelist
+	// lists contain all the free objects.
+	runtime·updatememstats(nil);
+
+	// Set dump file.
+	dumpfd = fd;
+
+	// Call dump routine.
+	mdump();
+
+	// Reset dump file.
+	dumpfd = 0;
+	if(tmpbuf != nil) {
+		runtime·SysFree(tmpbuf, tmpbufsize, &mstats.other_sys);
+		tmpbuf = nil;
+		tmpbufsize = 0;
+	}
+
+	runtime·casgstatus(g->m->curg, Gwaiting, Grunning);
+}
+
+// dumpint() the kind & offset of each field in an object.
+static void
+dumpfields(BitVector bv)
+{
+	dumpbv(&bv, 0);
+	dumpint(FieldKindEol);
+}
+
+// The heap dump reader needs to be able to disambiguate
+// Eface entries.  So it needs to know every type that might
+// appear in such an entry.  The following routine accomplishes that.
+
+// Dump all the types that appear in the type field of
+// any Eface described by this bit vector.
+static void
+dumpbvtypes(BitVector *bv, byte *base)
+{
+	uintptr i;
+
+	for(i = 0; i < bv->n; i += BitsPerPointer) {
+		if((bv->bytedata[i/8] >> i%8 & 3) != BitsMultiWord)
+			continue;
+		switch(bv->bytedata[(i+BitsPerPointer)/8] >> (i+BitsPerPointer)%8 & 3) {
+		default:
+			runtime·throw("unexpected garbage collection bits");
+		case BitsIface:
+			i += BitsPerPointer;
+			break;
+		case BitsEface:
+			dumptype(*(Type**)(base + i / BitsPerPointer * PtrSize));
+			i += BitsPerPointer;
+			break;
+		}
+	}
+}
+
+static BitVector
+makeheapobjbv(byte *p, uintptr size)
+{
+	uintptr off, nptr, i;
+	byte shift, *bitp, bits;
+	bool mw;
+
+	// Extend the temp buffer if necessary.
+	nptr = size/PtrSize;
+	if(tmpbufsize < nptr*BitsPerPointer/8+1) {
+		if(tmpbuf != nil)
+			runtime·SysFree(tmpbuf, tmpbufsize, &mstats.other_sys);
+		tmpbufsize = nptr*BitsPerPointer/8+1;
+		tmpbuf = runtime·sysAlloc(tmpbufsize, &mstats.other_sys);
+		if(tmpbuf == nil)
+			runtime·throw("heapdump: out of memory");
+	}
+
+	// Copy and compact the bitmap.
+	mw = false;
+	for(i = 0; i < nptr; i++) {
+		off = (uintptr*)(p + i*PtrSize) - (uintptr*)runtime·mheap.arena_start;
+		bitp = runtime·mheap.arena_start - off/wordsPerBitmapByte - 1;
+		shift = (off % wordsPerBitmapByte) * gcBits;
+		bits = (*bitp >> (shift + 2)) & BitsMask;
+		if(!mw && bits == BitsDead)
+			break;  // end of heap object
+		mw = !mw && bits == BitsMultiWord;
+		tmpbuf[i*BitsPerPointer/8] &= ~(BitsMask<<((i*BitsPerPointer)%8));
+		tmpbuf[i*BitsPerPointer/8] |= bits<<((i*BitsPerPointer)%8);
+	}
+	return (BitVector){i*BitsPerPointer, tmpbuf};
+}
diff --git a/src/runtime/iface.go b/src/runtime/iface.go
new file mode 100644
index 0000000..f60b6a7
--- /dev/null
+++ b/src/runtime/iface.go
@@ -0,0 +1,439 @@
+// 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 runtime
+
+import (
+	"unsafe"
+)
+
+const (
+	hashSize = 1009
+)
+
+var (
+	ifaceLock mutex // lock for accessing hash
+	hash      [hashSize]*itab
+)
+
+// fInterface is our standard non-empty interface.  We use it instead
+// of interface{f()} in function prototypes because gofmt insists on
+// putting lots of newlines in the otherwise concise interface{f()}.
+type fInterface interface {
+	f()
+}
+
+func getitab(inter *interfacetype, typ *_type, canfail bool) *itab {
+	if len(inter.mhdr) == 0 {
+		gothrow("internal error - misuse of itab")
+	}
+
+	// easy case
+	x := typ.x
+	if x == nil {
+		if canfail {
+			return nil
+		}
+		i := (*imethod)(add(unsafe.Pointer(inter), unsafe.Sizeof(interfacetype{})))
+		panic(&TypeAssertionError{"", *typ._string, *inter.typ._string, *i.name})
+	}
+
+	// compiler has provided some good hash codes for us.
+	h := inter.typ.hash
+	h += 17 * typ.hash
+	// TODO(rsc): h += 23 * x.mhash ?
+	h %= hashSize
+
+	// look twice - once without lock, once with.
+	// common case will be no lock contention.
+	var m *itab
+	var locked int
+	for locked = 0; locked < 2; locked++ {
+		if locked != 0 {
+			lock(&ifaceLock)
+		}
+		for m = (*itab)(atomicloadp(unsafe.Pointer(&hash[h]))); m != nil; m = m.link {
+			if m.inter == inter && m._type == typ {
+				if m.bad != 0 {
+					m = nil
+					if !canfail {
+						// this can only happen if the conversion
+						// was already done once using the , ok form
+						// and we have a cached negative result.
+						// the cached result doesn't record which
+						// interface function was missing, so jump
+						// down to the interface check, which will
+						// do more work but give a better error.
+						goto search
+					}
+				}
+				if locked != 0 {
+					unlock(&ifaceLock)
+				}
+				return m
+			}
+		}
+	}
+
+	m = (*itab)(persistentalloc(unsafe.Sizeof(itab{})+uintptr(len(inter.mhdr))*ptrSize, 0, &memstats.other_sys))
+	m.inter = inter
+	m._type = typ
+
+search:
+	// both inter and typ have method sorted by name,
+	// and interface names are unique,
+	// so can iterate over both in lock step;
+	// the loop is O(ni+nt) not O(ni*nt).
+	ni := len(inter.mhdr)
+	nt := len(x.mhdr)
+	j := 0
+	for k := 0; k < ni; k++ {
+		i := (*imethod)(add(unsafe.Pointer(inter), unsafe.Sizeof(interfacetype{})+uintptr(k)*unsafe.Sizeof(imethod{})))
+		iname := i.name
+		ipkgpath := i.pkgpath
+		itype := i._type
+		for ; j < nt; j++ {
+			t := (*method)(add(unsafe.Pointer(x), unsafe.Sizeof(uncommontype{})+uintptr(j)*unsafe.Sizeof(method{})))
+			if t.mtyp == itype && t.name == iname && t.pkgpath == ipkgpath {
+				if m != nil {
+					*(*unsafe.Pointer)(add(unsafe.Pointer(m), unsafe.Sizeof(itab{})+uintptr(k)*ptrSize)) = t.ifn
+				}
+				goto nextimethod
+			}
+		}
+		// didn't find method
+		if !canfail {
+			if locked != 0 {
+				unlock(&ifaceLock)
+			}
+			panic(&TypeAssertionError{"", *typ._string, *inter.typ._string, *iname})
+		}
+		m.bad = 1
+		break
+	nextimethod:
+	}
+	if locked == 0 {
+		gothrow("invalid itab locking")
+	}
+	m.link = hash[h]
+	atomicstorep(unsafe.Pointer(&hash[h]), unsafe.Pointer(m))
+	unlock(&ifaceLock)
+	if m.bad != 0 {
+		return nil
+	}
+	return m
+}
+
+func typ2Itab(t *_type, inter *interfacetype, cache **itab) *itab {
+	tab := getitab(inter, t, false)
+	atomicstorep(unsafe.Pointer(cache), unsafe.Pointer(tab))
+	return tab
+}
+
+func convT2E(t *_type, elem unsafe.Pointer) (e interface{}) {
+	size := uintptr(t.size)
+	ep := (*eface)(unsafe.Pointer(&e))
+	if isDirectIface(t) {
+		ep._type = t
+		memmove(unsafe.Pointer(&ep.data), elem, size)
+	} else {
+		x := newobject(t)
+		// TODO: We allocate a zeroed object only to overwrite it with
+		// actual data.  Figure out how to avoid zeroing.  Also below in convT2I.
+		memmove(x, elem, size)
+		ep._type = t
+		ep.data = x
+	}
+	return
+}
+
+func convT2I(t *_type, inter *interfacetype, cache **itab, elem unsafe.Pointer) (i fInterface) {
+	tab := (*itab)(atomicloadp(unsafe.Pointer(cache)))
+	if tab == nil {
+		tab = getitab(inter, t, false)
+		atomicstorep(unsafe.Pointer(cache), unsafe.Pointer(tab))
+	}
+	size := uintptr(t.size)
+	pi := (*iface)(unsafe.Pointer(&i))
+	if isDirectIface(t) {
+		pi.tab = tab
+		memmove(unsafe.Pointer(&pi.data), elem, size)
+	} else {
+		x := newobject(t)
+		memmove(x, elem, size)
+		pi.tab = tab
+		pi.data = x
+	}
+	return
+}
+
+// TODO: give these routines a pointer to the result area instead of writing
+// extra data in the outargs section.  Then we can get rid of go:nosplit.
+//go:nosplit
+func assertI2T(t *_type, i fInterface) (r struct{}) {
+	ip := (*iface)(unsafe.Pointer(&i))
+	tab := ip.tab
+	if tab == nil {
+		panic(&TypeAssertionError{"", "", *t._string, ""})
+	}
+	if tab._type != t {
+		panic(&TypeAssertionError{*tab.inter.typ._string, *tab._type._string, *t._string, ""})
+	}
+	size := uintptr(t.size)
+	if isDirectIface(t) {
+		memmove(unsafe.Pointer(&r), unsafe.Pointer(&ip.data), size)
+	} else {
+		memmove(unsafe.Pointer(&r), ip.data, size)
+	}
+	return
+}
+
+//go:nosplit
+func assertI2T2(t *_type, i fInterface) (r byte) {
+	ip := (*iface)(unsafe.Pointer(&i))
+	size := uintptr(t.size)
+	ok := (*bool)(add(unsafe.Pointer(&r), size))
+	tab := ip.tab
+	if tab == nil || tab._type != t {
+		*ok = false
+		memclr(unsafe.Pointer(&r), size)
+		return
+	}
+	*ok = true
+	if isDirectIface(t) {
+		memmove(unsafe.Pointer(&r), unsafe.Pointer(&ip.data), size)
+	} else {
+		memmove(unsafe.Pointer(&r), ip.data, size)
+	}
+	return
+}
+
+func assertI2TOK(t *_type, i fInterface) bool {
+	ip := (*iface)(unsafe.Pointer(&i))
+	tab := ip.tab
+	return tab != nil && tab._type == t
+}
+
+//go:nosplit
+func assertE2T(t *_type, e interface{}) (r struct{}) {
+	ep := (*eface)(unsafe.Pointer(&e))
+	if ep._type == nil {
+		panic(&TypeAssertionError{"", "", *t._string, ""})
+	}
+	if ep._type != t {
+		panic(&TypeAssertionError{"", *ep._type._string, *t._string, ""})
+	}
+	size := uintptr(t.size)
+	if isDirectIface(t) {
+		memmove(unsafe.Pointer(&r), unsafe.Pointer(&ep.data), size)
+	} else {
+		memmove(unsafe.Pointer(&r), ep.data, size)
+	}
+	return
+}
+
+//go:nosplit
+func assertE2T2(t *_type, e interface{}) (r byte) {
+	ep := (*eface)(unsafe.Pointer(&e))
+	size := uintptr(t.size)
+	ok := (*bool)(add(unsafe.Pointer(&r), size))
+	if ep._type != t {
+		*ok = false
+		memclr(unsafe.Pointer(&r), size)
+		return
+	}
+	*ok = true
+	if isDirectIface(t) {
+		memmove(unsafe.Pointer(&r), unsafe.Pointer(&ep.data), size)
+	} else {
+		memmove(unsafe.Pointer(&r), ep.data, size)
+	}
+	return
+}
+
+func assertE2TOK(t *_type, e interface{}) bool {
+	ep := (*eface)(unsafe.Pointer(&e))
+	return t == ep._type
+}
+
+func convI2E(i fInterface) (r interface{}) {
+	ip := (*iface)(unsafe.Pointer(&i))
+	tab := ip.tab
+	if tab == nil {
+		return
+	}
+	rp := (*eface)(unsafe.Pointer(&r))
+	rp._type = tab._type
+	rp.data = ip.data
+	return
+}
+
+func assertI2E(inter *interfacetype, i fInterface) (r interface{}) {
+	ip := (*iface)(unsafe.Pointer(&i))
+	tab := ip.tab
+	if tab == nil {
+		// explicit conversions require non-nil interface value.
+		panic(&TypeAssertionError{"", "", *inter.typ._string, ""})
+	}
+	rp := (*eface)(unsafe.Pointer(&r))
+	rp._type = tab._type
+	rp.data = ip.data
+	return
+}
+
+func assertI2E2(inter *interfacetype, i fInterface) (r interface{}, ok bool) {
+	ip := (*iface)(unsafe.Pointer(&i))
+	tab := ip.tab
+	if tab == nil {
+		return
+	}
+	rp := (*eface)(unsafe.Pointer(&r))
+	rp._type = tab._type
+	rp.data = ip.data
+	ok = true
+	return
+}
+
+func convI2I(inter *interfacetype, i fInterface) (r fInterface) {
+	ip := (*iface)(unsafe.Pointer(&i))
+	tab := ip.tab
+	if tab == nil {
+		return
+	}
+	rp := (*iface)(unsafe.Pointer(&r))
+	if tab.inter == inter {
+		rp.tab = tab
+		rp.data = ip.data
+		return
+	}
+	rp.tab = getitab(inter, tab._type, false)
+	rp.data = ip.data
+	return
+}
+
+func assertI2I(inter *interfacetype, i fInterface) (r fInterface) {
+	ip := (*iface)(unsafe.Pointer(&i))
+	tab := ip.tab
+	if tab == nil {
+		// explicit conversions require non-nil interface value.
+		panic(&TypeAssertionError{"", "", *inter.typ._string, ""})
+	}
+	rp := (*iface)(unsafe.Pointer(&r))
+	if tab.inter == inter {
+		rp.tab = tab
+		rp.data = ip.data
+		return
+	}
+	rp.tab = getitab(inter, tab._type, false)
+	rp.data = ip.data
+	return
+}
+
+func assertI2I2(inter *interfacetype, i fInterface) (r fInterface, ok bool) {
+	ip := (*iface)(unsafe.Pointer(&i))
+	tab := ip.tab
+	if tab == nil {
+		return
+	}
+	rp := (*iface)(unsafe.Pointer(&r))
+	if tab.inter == inter {
+		rp.tab = tab
+		rp.data = ip.data
+		ok = true
+		return
+	}
+	tab = getitab(inter, tab._type, true)
+	if tab == nil {
+		rp.data = nil
+		rp.tab = nil
+		ok = false
+		return
+	}
+	rp.tab = tab
+	rp.data = ip.data
+	ok = true
+	return
+}
+
+func assertE2I(inter *interfacetype, e interface{}) (r fInterface) {
+	ep := (*eface)(unsafe.Pointer(&e))
+	t := ep._type
+	if t == nil {
+		// explicit conversions require non-nil interface value.
+		panic(&TypeAssertionError{"", "", *inter.typ._string, ""})
+	}
+	rp := (*iface)(unsafe.Pointer(&r))
+	rp.tab = getitab(inter, t, false)
+	rp.data = ep.data
+	return
+}
+
+func assertE2I2(inter *interfacetype, e interface{}) (r fInterface, ok bool) {
+	ep := (*eface)(unsafe.Pointer(&e))
+	t := ep._type
+	if t == nil {
+		return
+	}
+	tab := getitab(inter, t, true)
+	if tab == nil {
+		return
+	}
+	rp := (*iface)(unsafe.Pointer(&r))
+	rp.tab = tab
+	rp.data = ep.data
+	ok = true
+	return
+}
+
+func reflect_ifaceE2I(inter *interfacetype, e interface{}, dst *fInterface) {
+	*dst = assertE2I(inter, e)
+}
+
+func assertE2E(inter *interfacetype, e interface{}) interface{} {
+	ep := (*eface)(unsafe.Pointer(&e))
+	if ep._type == nil {
+		// explicit conversions require non-nil interface value.
+		panic(&TypeAssertionError{"", "", *inter.typ._string, ""})
+	}
+	return e
+}
+
+func assertE2E2(inter *interfacetype, e interface{}) (interface{}, bool) {
+	ep := (*eface)(unsafe.Pointer(&e))
+	if ep._type == nil {
+		return nil, false
+	}
+	return e, true
+}
+
+func ifacethash(i fInterface) uint32 {
+	ip := (*iface)(unsafe.Pointer(&i))
+	tab := ip.tab
+	if tab == nil {
+		return 0
+	}
+	return tab._type.hash
+}
+
+func efacethash(e interface{}) uint32 {
+	ep := (*eface)(unsafe.Pointer(&e))
+	t := ep._type
+	if t == nil {
+		return 0
+	}
+	return t.hash
+}
+
+func iterate_itabs(fn func(*itab)) {
+	for _, h := range &hash {
+		for ; h != nil; h = h.link {
+			fn(h)
+		}
+	}
+}
+
+func ifaceE2I2(inter *interfacetype, e interface{}, r *fInterface) (ok bool) {
+	*r, ok = assertE2I2(inter, e)
+	return
+}
diff --git a/src/pkg/runtime/iface_test.go b/src/runtime/iface_test.go
similarity index 100%
rename from src/pkg/runtime/iface_test.go
rename to src/runtime/iface_test.go
diff --git a/src/runtime/lfstack.c b/src/runtime/lfstack.c
new file mode 100644
index 0000000..57e0af2
--- /dev/null
+++ b/src/runtime/lfstack.c
@@ -0,0 +1,87 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Lock-free stack.
+// The following code runs only on g0 stack.
+
+#include "runtime.h"
+#include "arch_GOARCH.h"
+
+#ifdef _64BIT
+// Amd64 uses 48-bit virtual addresses, 47-th bit is used as kernel/user flag.
+// So we use 17msb of pointers as ABA counter.
+# define PTR_BITS 47
+#else
+# define PTR_BITS 32
+#endif
+#define PTR_MASK ((1ull<<PTR_BITS)-1)
+#define CNT_MASK (0ull-1)
+
+#ifdef _64BIT
+#ifdef GOOS_solaris
+// SPARC64 and Solaris on AMD64 uses all 64 bits of virtual addresses.
+// Use low-order three bits as ABA counter.
+// http://docs.oracle.com/cd/E19120-01/open.solaris/816-5138/6mba6ua5p/index.html
+#undef PTR_BITS
+#undef CNT_MASK
+#undef PTR_MASK
+#define PTR_BITS 0
+#define CNT_MASK 7
+#define PTR_MASK ((0ull-1)<<3)
+#endif
+#endif
+
+void
+runtime·lfstackpush(uint64 *head, LFNode *node)
+{
+	uint64 old, new;
+
+	if((uintptr)node != ((uintptr)node&PTR_MASK)) {
+		runtime·printf("p=%p\n", node);
+		runtime·throw("runtime·lfstackpush: invalid pointer");
+	}
+
+	node->pushcnt++;
+	new = (uint64)(uintptr)node|(((uint64)node->pushcnt&CNT_MASK)<<PTR_BITS);
+	for(;;) {
+		old = runtime·atomicload64(head);
+		node->next = (LFNode*)(uintptr)(old&PTR_MASK);
+		if(runtime·cas64(head, old, new))
+			break;
+	}
+}
+
+LFNode*
+runtime·lfstackpop(uint64 *head)
+{
+	LFNode *node, *node2;
+	uint64 old, new;
+
+	for(;;) {
+		old = runtime·atomicload64(head);
+		if(old == 0)
+			return nil;
+		node = (LFNode*)(uintptr)(old&PTR_MASK);
+		node2 = runtime·atomicloadp(&node->next);
+		new = 0;
+		if(node2 != nil)
+			new = (uint64)(uintptr)node2|(((uint64)node2->pushcnt&CNT_MASK)<<PTR_BITS);
+		if(runtime·cas64(head, old, new))
+			return node;
+	}
+}
+
+void
+runtime·lfstackpush_m(void)
+{
+	runtime·lfstackpush(g->m->ptrarg[0], g->m->ptrarg[1]);
+	g->m->ptrarg[0] = nil;
+	g->m->ptrarg[1] = nil;
+}
+
+void
+runtime·lfstackpop_m(void)
+{
+	g->m->ptrarg[0] = runtime·lfstackpop(g->m->ptrarg[0]);
+}
diff --git a/src/pkg/runtime/lfstack_test.go b/src/runtime/lfstack_test.go
similarity index 100%
rename from src/pkg/runtime/lfstack_test.go
rename to src/runtime/lfstack_test.go
diff --git a/src/runtime/lock_futex.go b/src/runtime/lock_futex.go
new file mode 100644
index 0000000..7259623
--- /dev/null
+++ b/src/runtime/lock_futex.go
@@ -0,0 +1,205 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build dragonfly freebsd linux
+
+package runtime
+
+import "unsafe"
+
+// This implementation depends on OS-specific implementations of
+//
+//	runtime·futexsleep(uint32 *addr, uint32 val, int64 ns)
+//		Atomically,
+//			if(*addr == val) sleep
+//		Might be woken up spuriously; that's allowed.
+//		Don't sleep longer than ns; ns < 0 means forever.
+//
+//	runtime·futexwakeup(uint32 *addr, uint32 cnt)
+//		If any procs are sleeping on addr, wake up at most cnt.
+
+const (
+	mutex_unlocked = 0
+	mutex_locked   = 1
+	mutex_sleeping = 2
+
+	active_spin     = 4
+	active_spin_cnt = 30
+	passive_spin    = 1
+)
+
+// Possible lock states are mutex_unlocked, mutex_locked and mutex_sleeping.
+// mutex_sleeping means that there is presumably at least one sleeping thread.
+// Note that there can be spinning threads during all states - they do not
+// affect mutex's state.
+
+func futexsleep(addr *uint32, val uint32, ns int64)
+func futexwakeup(addr *uint32, cnt uint32)
+
+// We use the uintptr mutex.key and note.key as a uint32.
+func key32(p *uintptr) *uint32 {
+	return (*uint32)(unsafe.Pointer(p))
+}
+
+func lock(l *mutex) {
+	gp := getg()
+
+	if gp.m.locks < 0 {
+		gothrow("runtime·lock: lock count")
+	}
+	gp.m.locks++
+
+	// Speculative grab for lock.
+	v := xchg(key32(&l.key), mutex_locked)
+	if v == mutex_unlocked {
+		return
+	}
+
+	// wait is either MUTEX_LOCKED or MUTEX_SLEEPING
+	// depending on whether there is a thread sleeping
+	// on this mutex.  If we ever change l->key from
+	// MUTEX_SLEEPING to some other value, we must be
+	// careful to change it back to MUTEX_SLEEPING before
+	// returning, to ensure that the sleeping thread gets
+	// its wakeup call.
+	wait := v
+
+	// On uniprocessors, no point spinning.
+	// On multiprocessors, spin for ACTIVE_SPIN attempts.
+	spin := 0
+	if ncpu > 1 {
+		spin = active_spin
+	}
+	for {
+		// Try for lock, spinning.
+		for i := 0; i < spin; i++ {
+			for l.key == mutex_unlocked {
+				if cas(key32(&l.key), mutex_unlocked, wait) {
+					return
+				}
+			}
+			procyield(active_spin_cnt)
+		}
+
+		// Try for lock, rescheduling.
+		for i := 0; i < passive_spin; i++ {
+			for l.key == mutex_unlocked {
+				if cas(key32(&l.key), mutex_unlocked, wait) {
+					return
+				}
+			}
+			osyield()
+		}
+
+		// Sleep.
+		v = xchg(key32(&l.key), mutex_sleeping)
+		if v == mutex_unlocked {
+			return
+		}
+		wait = mutex_sleeping
+		futexsleep(key32(&l.key), mutex_sleeping, -1)
+	}
+}
+
+func unlock(l *mutex) {
+	v := xchg(key32(&l.key), mutex_unlocked)
+	if v == mutex_unlocked {
+		gothrow("unlock of unlocked lock")
+	}
+	if v == mutex_sleeping {
+		futexwakeup(key32(&l.key), 1)
+	}
+
+	gp := getg()
+	gp.m.locks--
+	if gp.m.locks < 0 {
+		gothrow("runtime·unlock: lock count")
+	}
+	if gp.m.locks == 0 && gp.preempt { // restore the preemption request in case we've cleared it in newstack
+		gp.stackguard0 = stackPreempt
+	}
+}
+
+// One-time notifications.
+func noteclear(n *note) {
+	n.key = 0
+}
+
+func notewakeup(n *note) {
+	old := xchg(key32(&n.key), 1)
+	if old != 0 {
+		print("notewakeup - double wakeup (", old, ")\n")
+		gothrow("notewakeup - double wakeup")
+	}
+	futexwakeup(key32(&n.key), 1)
+}
+
+func notesleep(n *note) {
+	gp := getg()
+	if gp != gp.m.g0 {
+		gothrow("notesleep not on g0")
+	}
+	for atomicload(key32(&n.key)) == 0 {
+		gp.m.blocked = true
+		futexsleep(key32(&n.key), 0, -1)
+		gp.m.blocked = false
+	}
+}
+
+//go:nosplit
+func notetsleep_internal(n *note, ns int64) bool {
+	gp := getg()
+
+	if ns < 0 {
+		for atomicload(key32(&n.key)) == 0 {
+			gp.m.blocked = true
+			futexsleep(key32(&n.key), 0, -1)
+			gp.m.blocked = false
+		}
+		return true
+	}
+
+	if atomicload(key32(&n.key)) != 0 {
+		return true
+	}
+
+	deadline := nanotime() + ns
+	for {
+		gp.m.blocked = true
+		futexsleep(key32(&n.key), 0, ns)
+		gp.m.blocked = false
+		if atomicload(key32(&n.key)) != 0 {
+			break
+		}
+		now := nanotime()
+		if now >= deadline {
+			break
+		}
+		ns = deadline - now
+	}
+	return atomicload(key32(&n.key)) != 0
+}
+
+func notetsleep(n *note, ns int64) bool {
+	gp := getg()
+	if gp != gp.m.g0 && gp.m.gcing == 0 {
+		gothrow("notetsleep not on g0")
+	}
+
+	return notetsleep_internal(n, ns)
+}
+
+// same as runtime·notetsleep, but called on user g (not g0)
+// calls only nosplit functions between entersyscallblock/exitsyscall
+func notetsleepg(n *note, ns int64) bool {
+	gp := getg()
+	if gp == gp.m.g0 {
+		gothrow("notetsleepg on g0")
+	}
+
+	entersyscallblock()
+	ok := notetsleep_internal(n, ns)
+	exitsyscall()
+	return ok
+}
diff --git a/src/runtime/lock_sema.go b/src/runtime/lock_sema.go
new file mode 100644
index 0000000..d136b82
--- /dev/null
+++ b/src/runtime/lock_sema.go
@@ -0,0 +1,270 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin nacl netbsd openbsd plan9 solaris windows
+
+package runtime
+
+import "unsafe"
+
+// This implementation depends on OS-specific implementations of
+//
+//	uintptr runtime·semacreate(void)
+//		Create a semaphore, which will be assigned to m->waitsema.
+//		The zero value is treated as absence of any semaphore,
+//		so be sure to return a non-zero value.
+//
+//	int32 runtime·semasleep(int64 ns)
+//		If ns < 0, acquire m->waitsema and return 0.
+//		If ns >= 0, try to acquire m->waitsema for at most ns nanoseconds.
+//		Return 0 if the semaphore was acquired, -1 if interrupted or timed out.
+//
+//	int32 runtime·semawakeup(M *mp)
+//		Wake up mp, which is or will soon be sleeping on mp->waitsema.
+//
+const (
+	locked uintptr = 1
+
+	active_spin     = 4
+	active_spin_cnt = 30
+	passive_spin    = 1
+)
+
+func semacreate() uintptr
+func semasleep(int64) int32
+func semawakeup(mp *m)
+
+func lock(l *mutex) {
+	gp := getg()
+	if gp.m.locks < 0 {
+		gothrow("runtime·lock: lock count")
+	}
+	gp.m.locks++
+
+	// Speculative grab for lock.
+	if casuintptr(&l.key, 0, locked) {
+		return
+	}
+	if gp.m.waitsema == 0 {
+		gp.m.waitsema = semacreate()
+	}
+
+	// On uniprocessor's, no point spinning.
+	// On multiprocessors, spin for ACTIVE_SPIN attempts.
+	spin := 0
+	if ncpu > 1 {
+		spin = active_spin
+	}
+Loop:
+	for i := 0; ; i++ {
+		v := atomicloaduintptr(&l.key)
+		if v&locked == 0 {
+			// Unlocked. Try to lock.
+			if casuintptr(&l.key, v, v|locked) {
+				return
+			}
+			i = 0
+		}
+		if i < spin {
+			procyield(active_spin_cnt)
+		} else if i < spin+passive_spin {
+			osyield()
+		} else {
+			// Someone else has it.
+			// l->waitm points to a linked list of M's waiting
+			// for this lock, chained through m->nextwaitm.
+			// Queue this M.
+			for {
+				gp.m.nextwaitm = (*m)((unsafe.Pointer)(v &^ locked))
+				if casuintptr(&l.key, v, uintptr(unsafe.Pointer(gp.m))|locked) {
+					break
+				}
+				v = atomicloaduintptr(&l.key)
+				if v&locked == 0 {
+					continue Loop
+				}
+			}
+			if v&locked != 0 {
+				// Queued.  Wait.
+				semasleep(-1)
+				i = 0
+			}
+		}
+	}
+}
+
+func unlock(l *mutex) {
+	gp := getg()
+	var mp *m
+	for {
+		v := atomicloaduintptr(&l.key)
+		if v == locked {
+			if casuintptr(&l.key, locked, 0) {
+				break
+			}
+		} else {
+			// Other M's are waiting for the lock.
+			// Dequeue an M.
+			mp = (*m)((unsafe.Pointer)(v &^ locked))
+			if casuintptr(&l.key, v, uintptr(unsafe.Pointer(mp.nextwaitm))) {
+				// Dequeued an M.  Wake it.
+				semawakeup(mp)
+				break
+			}
+		}
+	}
+	gp.m.locks--
+	if gp.m.locks < 0 {
+		gothrow("runtime·unlock: lock count")
+	}
+	if gp.m.locks == 0 && gp.preempt { // restore the preemption request in case we've cleared it in newstack
+		gp.stackguard0 = stackPreempt
+	}
+}
+
+// One-time notifications.
+func noteclear(n *note) {
+	n.key = 0
+}
+
+func notewakeup(n *note) {
+	var v uintptr
+	for {
+		v = atomicloaduintptr(&n.key)
+		if casuintptr(&n.key, v, locked) {
+			break
+		}
+	}
+
+	// Successfully set waitm to locked.
+	// What was it before?
+	switch {
+	case v == 0:
+		// Nothing was waiting. Done.
+	case v == locked:
+		// Two notewakeups!  Not allowed.
+		gothrow("notewakeup - double wakeup")
+	default:
+		// Must be the waiting m.  Wake it up.
+		semawakeup((*m)(unsafe.Pointer(v)))
+	}
+}
+
+func notesleep(n *note) {
+	gp := getg()
+	if gp != gp.m.g0 {
+		gothrow("notesleep not on g0")
+	}
+	if gp.m.waitsema == 0 {
+		gp.m.waitsema = semacreate()
+	}
+	if !casuintptr(&n.key, 0, uintptr(unsafe.Pointer(gp.m))) {
+		// Must be locked (got wakeup).
+		if n.key != locked {
+			gothrow("notesleep - waitm out of sync")
+		}
+		return
+	}
+	// Queued.  Sleep.
+	gp.m.blocked = true
+	semasleep(-1)
+	gp.m.blocked = false
+}
+
+//go:nosplit
+func notetsleep_internal(n *note, ns int64, gp *g, deadline int64) bool {
+	// gp and deadline are logically local variables, but they are written
+	// as parameters so that the stack space they require is charged
+	// to the caller.
+	// This reduces the nosplit footprint of notetsleep_internal.
+	gp = getg()
+
+	// Register for wakeup on n->waitm.
+	if !casuintptr(&n.key, 0, uintptr(unsafe.Pointer(gp.m))) {
+		// Must be locked (got wakeup).
+		if n.key != locked {
+			gothrow("notetsleep - waitm out of sync")
+		}
+		return true
+	}
+	if ns < 0 {
+		// Queued.  Sleep.
+		gp.m.blocked = true
+		semasleep(-1)
+		gp.m.blocked = false
+		return true
+	}
+
+	deadline = nanotime() + ns
+	for {
+		// Registered.  Sleep.
+		gp.m.blocked = true
+		if semasleep(ns) >= 0 {
+			gp.m.blocked = false
+			// Acquired semaphore, semawakeup unregistered us.
+			// Done.
+			return true
+		}
+		gp.m.blocked = false
+		// Interrupted or timed out.  Still registered.  Semaphore not acquired.
+		ns = deadline - nanotime()
+		if ns <= 0 {
+			break
+		}
+		// Deadline hasn't arrived.  Keep sleeping.
+	}
+
+	// Deadline arrived.  Still registered.  Semaphore not acquired.
+	// Want to give up and return, but have to unregister first,
+	// so that any notewakeup racing with the return does not
+	// try to grant us the semaphore when we don't expect it.
+	for {
+		v := atomicloaduintptr(&n.key)
+		switch v {
+		case uintptr(unsafe.Pointer(gp.m)):
+			// No wakeup yet; unregister if possible.
+			if casuintptr(&n.key, v, 0) {
+				return false
+			}
+		case locked:
+			// Wakeup happened so semaphore is available.
+			// Grab it to avoid getting out of sync.
+			gp.m.blocked = true
+			if semasleep(-1) < 0 {
+				gothrow("runtime: unable to acquire - semaphore out of sync")
+			}
+			gp.m.blocked = false
+			return true
+		default:
+			gothrow("runtime: unexpected waitm - semaphore out of sync")
+		}
+	}
+}
+
+func notetsleep(n *note, ns int64) bool {
+	gp := getg()
+	if gp != gp.m.g0 && gp.m.gcing == 0 {
+		gothrow("notetsleep not on g0")
+	}
+	if gp.m.waitsema == 0 {
+		gp.m.waitsema = semacreate()
+	}
+	return notetsleep_internal(n, ns, nil, 0)
+}
+
+// same as runtime·notetsleep, but called on user g (not g0)
+// calls only nosplit functions between entersyscallblock/exitsyscall
+func notetsleepg(n *note, ns int64) bool {
+	gp := getg()
+	if gp == gp.m.g0 {
+		gothrow("notetsleepg on g0")
+	}
+	if gp.m.waitsema == 0 {
+		gp.m.waitsema = semacreate()
+	}
+	entersyscallblock()
+	ok := notetsleep_internal(n, ns, nil, 0)
+	exitsyscall()
+	return ok
+}
diff --git a/src/runtime/malloc.c b/src/runtime/malloc.c
new file mode 100644
index 0000000..b79c30b
--- /dev/null
+++ b/src/runtime/malloc.c
@@ -0,0 +1,396 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// See malloc.h for overview.
+//
+// TODO(rsc): double-check stats.
+
+#include "runtime.h"
+#include "arch_GOARCH.h"
+#include "malloc.h"
+#include "type.h"
+#include "typekind.h"
+#include "race.h"
+#include "stack.h"
+#include "textflag.h"
+
+// Mark mheap as 'no pointers', it does not contain interesting pointers but occupies ~45K.
+#pragma dataflag NOPTR
+MHeap runtime·mheap;
+#pragma dataflag NOPTR
+MStats runtime·memstats;
+
+int32
+runtime·mlookup(void *v, byte **base, uintptr *size, MSpan **sp)
+{
+	uintptr n, i;
+	byte *p;
+	MSpan *s;
+
+	g->m->mcache->local_nlookup++;
+	if (sizeof(void*) == 4 && g->m->mcache->local_nlookup >= (1<<30)) {
+		// purge cache stats to prevent overflow
+		runtime·lock(&runtime·mheap.lock);
+		runtime·purgecachedstats(g->m->mcache);
+		runtime·unlock(&runtime·mheap.lock);
+	}
+
+	s = runtime·MHeap_LookupMaybe(&runtime·mheap, v);
+	if(sp)
+		*sp = s;
+	if(s == nil) {
+		if(base)
+			*base = nil;
+		if(size)
+			*size = 0;
+		return 0;
+	}
+
+	p = (byte*)((uintptr)s->start<<PageShift);
+	if(s->sizeclass == 0) {
+		// Large object.
+		if(base)
+			*base = p;
+		if(size)
+			*size = s->npages<<PageShift;
+		return 1;
+	}
+
+	n = s->elemsize;
+	if(base) {
+		i = ((byte*)v - p)/n;
+		*base = p + i*n;
+	}
+	if(size)
+		*size = n;
+
+	return 1;
+}
+
+#pragma textflag NOSPLIT
+void
+runtime·purgecachedstats(MCache *c)
+{
+	MHeap *h;
+	int32 i;
+
+	// Protected by either heap or GC lock.
+	h = &runtime·mheap;
+	mstats.heap_alloc += c->local_cachealloc;
+	c->local_cachealloc = 0;
+	mstats.tinyallocs += c->local_tinyallocs;
+	c->local_tinyallocs = 0;
+	mstats.nlookup += c->local_nlookup;
+	c->local_nlookup = 0;
+	h->largefree += c->local_largefree;
+	c->local_largefree = 0;
+	h->nlargefree += c->local_nlargefree;
+	c->local_nlargefree = 0;
+	for(i=0; i<nelem(c->local_nsmallfree); i++) {
+		h->nsmallfree[i] += c->local_nsmallfree[i];
+		c->local_nsmallfree[i] = 0;
+	}
+}
+
+// Size of the trailing by_size array differs between Go and C,
+// and all data after by_size is local to C, not exported to Go.
+// NumSizeClasses was changed, but we can not change Go struct because of backward compatibility.
+// sizeof_C_MStats is what C thinks about size of Go struct.
+uintptr runtime·sizeof_C_MStats = offsetof(MStats, by_size[61]);
+
+#define MaxArena32 (2U<<30)
+
+// For use by Go. If it were a C enum it would be made available automatically,
+// but the value of MaxMem is too large for enum.
+uintptr runtime·maxmem = MaxMem;
+
+void
+runtime·mallocinit(void)
+{
+	byte *p, *p1;
+	uintptr arena_size, bitmap_size, spans_size, p_size;
+	extern byte runtime·end[];
+	uintptr limit;
+	uint64 i;
+	bool reserved;
+
+	p = nil;
+	p_size = 0;
+	arena_size = 0;
+	bitmap_size = 0;
+	spans_size = 0;
+	reserved = false;
+
+	// for 64-bit build
+	USED(p);
+	USED(p_size);
+	USED(arena_size);
+	USED(bitmap_size);
+	USED(spans_size);
+
+	runtime·InitSizes();
+
+	if(runtime·class_to_size[TinySizeClass] != TinySize)
+		runtime·throw("bad TinySizeClass");
+
+	// limit = runtime·memlimit();
+	// See https://code.google.com/p/go/issues/detail?id=5049
+	// TODO(rsc): Fix after 1.1.
+	limit = 0;
+
+	// Set up the allocation arena, a contiguous area of memory where
+	// allocated data will be found.  The arena begins with a bitmap large
+	// enough to hold 4 bits per allocated word.
+	if(sizeof(void*) == 8 && (limit == 0 || limit > (1<<30))) {
+		// On a 64-bit machine, allocate from a single contiguous reservation.
+		// 128 GB (MaxMem) should be big enough for now.
+		//
+		// The code will work with the reservation at any address, but ask
+		// SysReserve to use 0x0000XXc000000000 if possible (XX=00...7f).
+		// Allocating a 128 GB region takes away 37 bits, and the amd64
+		// doesn't let us choose the top 17 bits, so that leaves the 11 bits
+		// in the middle of 0x00c0 for us to choose.  Choosing 0x00c0 means
+		// that the valid memory addresses will begin 0x00c0, 0x00c1, ..., 0x00df.
+		// In little-endian, that's c0 00, c1 00, ..., df 00. None of those are valid
+		// UTF-8 sequences, and they are otherwise as far away from 
+		// ff (likely a common byte) as possible.  If that fails, we try other 0xXXc0
+		// addresses.  An earlier attempt to use 0x11f8 caused out of memory errors
+		// on OS X during thread allocations.  0x00c0 causes conflicts with
+		// AddressSanitizer which reserves all memory up to 0x0100.
+		// These choices are both for debuggability and to reduce the
+		// odds of the conservative garbage collector not collecting memory
+		// because some non-pointer block of memory had a bit pattern
+		// that matched a memory address.
+		//
+		// Actually we reserve 136 GB (because the bitmap ends up being 8 GB)
+		// but it hardly matters: e0 00 is not valid UTF-8 either.
+		//
+		// If this fails we fall back to the 32 bit memory mechanism
+		arena_size = MaxMem;
+		bitmap_size = arena_size / (sizeof(void*)*8/4);
+		spans_size = arena_size / PageSize * sizeof(runtime·mheap.spans[0]);
+		spans_size = ROUND(spans_size, PageSize);
+		for(i = 0; i <= 0x7f; i++) {
+			p = (void*)(i<<40 | 0x00c0ULL<<32);
+			p_size = bitmap_size + spans_size + arena_size + PageSize;
+			p = runtime·SysReserve(p, p_size, &reserved);
+			if(p != nil)
+				break;
+		}
+	}
+	if (p == nil) {
+		// On a 32-bit machine, we can't typically get away
+		// with a giant virtual address space reservation.
+		// Instead we map the memory information bitmap
+		// immediately after the data segment, large enough
+		// to handle another 2GB of mappings (256 MB),
+		// along with a reservation for another 512 MB of memory.
+		// When that gets used up, we'll start asking the kernel
+		// for any memory anywhere and hope it's in the 2GB
+		// following the bitmap (presumably the executable begins
+		// near the bottom of memory, so we'll have to use up
+		// most of memory before the kernel resorts to giving out
+		// memory before the beginning of the text segment).
+		//
+		// Alternatively we could reserve 512 MB bitmap, enough
+		// for 4GB of mappings, and then accept any memory the
+		// kernel threw at us, but normally that's a waste of 512 MB
+		// of address space, which is probably too much in a 32-bit world.
+		bitmap_size = MaxArena32 / (sizeof(void*)*8/4);
+		arena_size = 512<<20;
+		spans_size = MaxArena32 / PageSize * sizeof(runtime·mheap.spans[0]);
+		if(limit > 0 && arena_size+bitmap_size+spans_size > limit) {
+			bitmap_size = (limit / 9) & ~((1<<PageShift) - 1);
+			arena_size = bitmap_size * 8;
+			spans_size = arena_size / PageSize * sizeof(runtime·mheap.spans[0]);
+		}
+		spans_size = ROUND(spans_size, PageSize);
+
+		// SysReserve treats the address we ask for, end, as a hint,
+		// not as an absolute requirement.  If we ask for the end
+		// of the data segment but the operating system requires
+		// a little more space before we can start allocating, it will
+		// give out a slightly higher pointer.  Except QEMU, which
+		// is buggy, as usual: it won't adjust the pointer upward.
+		// So adjust it upward a little bit ourselves: 1/4 MB to get
+		// away from the running binary image and then round up
+		// to a MB boundary.
+		p = (byte*)ROUND((uintptr)runtime·end + (1<<18), 1<<20);
+		p_size = bitmap_size + spans_size + arena_size + PageSize;
+		p = runtime·SysReserve(p, p_size, &reserved);
+		if(p == nil)
+			runtime·throw("runtime: cannot reserve arena virtual address space");
+	}
+
+	// PageSize can be larger than OS definition of page size,
+	// so SysReserve can give us a PageSize-unaligned pointer.
+	// To overcome this we ask for PageSize more and round up the pointer.
+	p1 = (byte*)ROUND((uintptr)p, PageSize);
+
+	runtime·mheap.spans = (MSpan**)p1;
+	runtime·mheap.bitmap = p1 + spans_size;
+	runtime·mheap.arena_start = p1 + spans_size + bitmap_size;
+	runtime·mheap.arena_used = runtime·mheap.arena_start;
+	runtime·mheap.arena_end = p + p_size;
+	runtime·mheap.arena_reserved = reserved;
+
+	if(((uintptr)runtime·mheap.arena_start & (PageSize-1)) != 0)
+		runtime·throw("misrounded allocation in mallocinit");
+
+	// Initialize the rest of the allocator.	
+	runtime·MHeap_Init(&runtime·mheap);
+	g->m->mcache = runtime·allocmcache();
+}
+
+void*
+runtime·MHeap_SysAlloc(MHeap *h, uintptr n)
+{
+	byte *p, *p_end;
+	uintptr p_size;
+	bool reserved;
+
+	if(n > h->arena_end - h->arena_used) {
+		// We are in 32-bit mode, maybe we didn't use all possible address space yet.
+		// Reserve some more space.
+		byte *new_end;
+
+		p_size = ROUND(n + PageSize, 256<<20);
+		new_end = h->arena_end + p_size;
+		if(new_end <= h->arena_start + MaxArena32) {
+			// TODO: It would be bad if part of the arena
+			// is reserved and part is not.
+			p = runtime·SysReserve(h->arena_end, p_size, &reserved);
+			if(p == h->arena_end) {
+				h->arena_end = new_end;
+				h->arena_reserved = reserved;
+			}
+			else if(p+p_size <= h->arena_start + MaxArena32) {
+				// Keep everything page-aligned.
+				// Our pages are bigger than hardware pages.
+				h->arena_end = p+p_size;
+				h->arena_used = p + (-(uintptr)p&(PageSize-1));
+				h->arena_reserved = reserved;
+			} else {
+				uint64 stat;
+				stat = 0;
+				runtime·SysFree(p, p_size, &stat);
+			}
+		}
+	}
+	if(n <= h->arena_end - h->arena_used) {
+		// Keep taking from our reservation.
+		p = h->arena_used;
+		runtime·SysMap(p, n, h->arena_reserved, &mstats.heap_sys);
+		h->arena_used += n;
+		runtime·MHeap_MapBits(h);
+		runtime·MHeap_MapSpans(h);
+		if(raceenabled)
+			runtime·racemapshadow(p, n);
+		
+		if(((uintptr)p & (PageSize-1)) != 0)
+			runtime·throw("misrounded allocation in MHeap_SysAlloc");
+		return p;
+	}
+	
+	// If using 64-bit, our reservation is all we have.
+	if(h->arena_end - h->arena_start >= MaxArena32)
+		return nil;
+
+	// On 32-bit, once the reservation is gone we can
+	// try to get memory at a location chosen by the OS
+	// and hope that it is in the range we allocated bitmap for.
+	p_size = ROUND(n, PageSize) + PageSize;
+	p = runtime·sysAlloc(p_size, &mstats.heap_sys);
+	if(p == nil)
+		return nil;
+
+	if(p < h->arena_start || p+p_size - h->arena_start >= MaxArena32) {
+		runtime·printf("runtime: memory allocated by OS (%p) not in usable range [%p,%p)\n",
+			p, h->arena_start, h->arena_start+MaxArena32);
+		runtime·SysFree(p, p_size, &mstats.heap_sys);
+		return nil;
+	}
+	
+	p_end = p + p_size;
+	p += -(uintptr)p & (PageSize-1);
+	if(p+n > h->arena_used) {
+		h->arena_used = p+n;
+		if(p_end > h->arena_end)
+			h->arena_end = p_end;
+		runtime·MHeap_MapBits(h);
+		runtime·MHeap_MapSpans(h);
+		if(raceenabled)
+			runtime·racemapshadow(p, n);
+	}
+	
+	if(((uintptr)p & (PageSize-1)) != 0)
+		runtime·throw("misrounded allocation in MHeap_SysAlloc");
+	return p;
+}
+
+void
+runtime·setFinalizer_m(void)
+{
+	FuncVal *fn;
+	void *arg;
+	uintptr nret;
+	Type *fint;
+	PtrType *ot;
+
+	fn = g->m->ptrarg[0];
+	arg = g->m->ptrarg[1];
+	nret = g->m->scalararg[0];
+	fint = g->m->ptrarg[2];
+	ot = g->m->ptrarg[3];
+	g->m->ptrarg[0] = nil;
+	g->m->ptrarg[1] = nil;
+	g->m->ptrarg[2] = nil;
+	g->m->ptrarg[3] = nil;
+
+	g->m->scalararg[0] = runtime·addfinalizer(arg, fn, nret, fint, ot);
+}
+
+void
+runtime·removeFinalizer_m(void)
+{
+	void *p;
+
+	p = g->m->ptrarg[0];
+	g->m->ptrarg[0] = nil;
+	runtime·removefinalizer(p);
+}
+
+// mcallable cache refill
+void 
+runtime·mcacheRefill_m(void)
+{
+	runtime·MCache_Refill(g->m->mcache, (int32)g->m->scalararg[0]);
+}
+
+void
+runtime·largeAlloc_m(void)
+{
+	uintptr npages, size;
+	MSpan *s;
+	void *v;
+	int32 flag;
+
+	//runtime·printf("largeAlloc size=%D\n", g->m->scalararg[0]);
+	// Allocate directly from heap.
+	size = g->m->scalararg[0];
+	flag = (int32)g->m->scalararg[1];
+	if(size + PageSize < size)
+		runtime·throw("out of memory");
+	npages = size >> PageShift;
+	if((size & PageMask) != 0)
+		npages++;
+	s = runtime·MHeap_Alloc(&runtime·mheap, npages, 0, 1, !(flag & FlagNoZero));
+	if(s == nil)
+		runtime·throw("out of memory");
+	s->limit = (byte*)(s->start<<PageShift) + size;
+	v = (void*)(s->start << PageShift);
+	// setup for mark sweep
+	runtime·markspan(v, 0, 0, true);
+	g->m->ptrarg[0] = s;
+}
diff --git a/src/runtime/malloc.go b/src/runtime/malloc.go
new file mode 100644
index 0000000..1170449
--- /dev/null
+++ b/src/runtime/malloc.go
@@ -0,0 +1,837 @@
+// 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 runtime
+
+import (
+	"unsafe"
+)
+
+const (
+	debugMalloc = false
+
+	flagNoScan = _FlagNoScan
+	flagNoZero = _FlagNoZero
+
+	maxTinySize   = _TinySize
+	tinySizeClass = _TinySizeClass
+	maxSmallSize  = _MaxSmallSize
+
+	pageShift = _PageShift
+	pageSize  = _PageSize
+	pageMask  = _PageMask
+
+	bitsPerPointer  = _BitsPerPointer
+	bitsMask        = _BitsMask
+	pointersPerByte = _PointersPerByte
+	maxGCMask       = _MaxGCMask
+	bitsDead        = _BitsDead
+	bitsPointer     = _BitsPointer
+
+	mSpanInUse = _MSpanInUse
+
+	concurrentSweep = _ConcurrentSweep != 0
+)
+
+// Page number (address>>pageShift)
+type pageID uintptr
+
+// base address for all 0-byte allocations
+var zerobase uintptr
+
+// Allocate an object of size bytes.
+// Small objects are allocated from the per-P cache's free lists.
+// Large objects (> 32 kB) are allocated straight from the heap.
+func mallocgc(size uintptr, typ *_type, flags uint32) unsafe.Pointer {
+	if size == 0 {
+		return unsafe.Pointer(&zerobase)
+	}
+	size0 := size
+
+	if flags&flagNoScan == 0 && typ == nil {
+		gothrow("malloc missing type")
+	}
+
+	// This function must be atomic wrt GC, but for performance reasons
+	// we don't acquirem/releasem on fast path. The code below does not have
+	// split stack checks, so it can't be preempted by GC.
+	// Functions like roundup/add are inlined. And onM/racemalloc are nosplit.
+	// If debugMalloc = true, these assumptions are checked below.
+	if debugMalloc {
+		mp := acquirem()
+		if mp.mallocing != 0 {
+			gothrow("malloc deadlock")
+		}
+		mp.mallocing = 1
+		if mp.curg != nil {
+			mp.curg.stackguard0 = ^uintptr(0xfff) | 0xbad
+		}
+	}
+
+	c := gomcache()
+	var s *mspan
+	var x unsafe.Pointer
+	if size <= maxSmallSize {
+		if flags&flagNoScan != 0 && size < maxTinySize {
+			// Tiny allocator.
+			//
+			// Tiny allocator combines several tiny allocation requests
+			// into a single memory block. The resulting memory block
+			// is freed when all subobjects are unreachable. The subobjects
+			// must be FlagNoScan (don't have pointers), this ensures that
+			// the amount of potentially wasted memory is bounded.
+			//
+			// Size of the memory block used for combining (maxTinySize) is tunable.
+			// Current setting is 16 bytes, which relates to 2x worst case memory
+			// wastage (when all but one subobjects are unreachable).
+			// 8 bytes would result in no wastage at all, but provides less
+			// opportunities for combining.
+			// 32 bytes provides more opportunities for combining,
+			// but can lead to 4x worst case wastage.
+			// The best case winning is 8x regardless of block size.
+			//
+			// Objects obtained from tiny allocator must not be freed explicitly.
+			// So when an object will be freed explicitly, we ensure that
+			// its size >= maxTinySize.
+			//
+			// SetFinalizer has a special case for objects potentially coming
+			// from tiny allocator, it such case it allows to set finalizers
+			// for an inner byte of a memory block.
+			//
+			// The main targets of tiny allocator are small strings and
+			// standalone escaping variables. On a json benchmark
+			// the allocator reduces number of allocations by ~12% and
+			// reduces heap size by ~20%.
+			tinysize := uintptr(c.tinysize)
+			if size <= tinysize {
+				tiny := unsafe.Pointer(c.tiny)
+				// Align tiny pointer for required (conservative) alignment.
+				if size&7 == 0 {
+					tiny = roundup(tiny, 8)
+				} else if size&3 == 0 {
+					tiny = roundup(tiny, 4)
+				} else if size&1 == 0 {
+					tiny = roundup(tiny, 2)
+				}
+				size1 := size + (uintptr(tiny) - uintptr(unsafe.Pointer(c.tiny)))
+				if size1 <= tinysize {
+					// The object fits into existing tiny block.
+					x = tiny
+					c.tiny = (*byte)(add(x, size))
+					c.tinysize -= uintptr(size1)
+					c.local_tinyallocs++
+					if debugMalloc {
+						mp := acquirem()
+						if mp.mallocing == 0 {
+							gothrow("bad malloc")
+						}
+						mp.mallocing = 0
+						if mp.curg != nil {
+							mp.curg.stackguard0 = mp.curg.stack.lo + _StackGuard
+						}
+						// Note: one releasem for the acquirem just above.
+						// The other for the acquirem at start of malloc.
+						releasem(mp)
+						releasem(mp)
+					}
+					return x
+				}
+			}
+			// Allocate a new maxTinySize block.
+			s = c.alloc[tinySizeClass]
+			v := s.freelist
+			if v == nil {
+				mp := acquirem()
+				mp.scalararg[0] = tinySizeClass
+				onM(mcacheRefill_m)
+				releasem(mp)
+				s = c.alloc[tinySizeClass]
+				v = s.freelist
+			}
+			s.freelist = v.next
+			s.ref++
+			//TODO: prefetch v.next
+			x = unsafe.Pointer(v)
+			(*[2]uint64)(x)[0] = 0
+			(*[2]uint64)(x)[1] = 0
+			// See if we need to replace the existing tiny block with the new one
+			// based on amount of remaining free space.
+			if maxTinySize-size > tinysize {
+				c.tiny = (*byte)(add(x, size))
+				c.tinysize = uintptr(maxTinySize - size)
+			}
+			size = maxTinySize
+		} else {
+			var sizeclass int8
+			if size <= 1024-8 {
+				sizeclass = size_to_class8[(size+7)>>3]
+			} else {
+				sizeclass = size_to_class128[(size-1024+127)>>7]
+			}
+			size = uintptr(class_to_size[sizeclass])
+			s = c.alloc[sizeclass]
+			v := s.freelist
+			if v == nil {
+				mp := acquirem()
+				mp.scalararg[0] = uintptr(sizeclass)
+				onM(mcacheRefill_m)
+				releasem(mp)
+				s = c.alloc[sizeclass]
+				v = s.freelist
+			}
+			s.freelist = v.next
+			s.ref++
+			//TODO: prefetch
+			x = unsafe.Pointer(v)
+			if flags&flagNoZero == 0 {
+				v.next = nil
+				if size > 2*ptrSize && ((*[2]uintptr)(x))[1] != 0 {
+					memclr(unsafe.Pointer(v), size)
+				}
+			}
+		}
+		c.local_cachealloc += intptr(size)
+	} else {
+		mp := acquirem()
+		mp.scalararg[0] = uintptr(size)
+		mp.scalararg[1] = uintptr(flags)
+		onM(largeAlloc_m)
+		s = (*mspan)(mp.ptrarg[0])
+		mp.ptrarg[0] = nil
+		releasem(mp)
+		x = unsafe.Pointer(uintptr(s.start << pageShift))
+		size = uintptr(s.elemsize)
+	}
+
+	if flags&flagNoScan != 0 {
+		// All objects are pre-marked as noscan.
+		goto marked
+	}
+
+	// If allocating a defer+arg block, now that we've picked a malloc size
+	// large enough to hold everything, cut the "asked for" size down to
+	// just the defer header, so that the GC bitmap will record the arg block
+	// as containing nothing at all (as if it were unused space at the end of
+	// a malloc block caused by size rounding).
+	// The defer arg areas are scanned as part of scanstack.
+	if typ == deferType {
+		size0 = unsafe.Sizeof(_defer{})
+	}
+
+	// From here till marked label marking the object as allocated
+	// and storing type info in the GC bitmap.
+	{
+		arena_start := uintptr(unsafe.Pointer(mheap_.arena_start))
+		off := (uintptr(x) - arena_start) / ptrSize
+		xbits := (*uint8)(unsafe.Pointer(arena_start - off/wordsPerBitmapByte - 1))
+		shift := (off % wordsPerBitmapByte) * gcBits
+		if debugMalloc && ((*xbits>>shift)&(bitMask|bitPtrMask)) != bitBoundary {
+			println("runtime: bits =", (*xbits>>shift)&(bitMask|bitPtrMask))
+			gothrow("bad bits in markallocated")
+		}
+
+		var ti, te uintptr
+		var ptrmask *uint8
+		if size == ptrSize {
+			// It's one word and it has pointers, it must be a pointer.
+			*xbits |= (bitsPointer << 2) << shift
+			goto marked
+		}
+		if typ.kind&kindGCProg != 0 {
+			nptr := (uintptr(typ.size) + ptrSize - 1) / ptrSize
+			masksize := nptr
+			if masksize%2 != 0 {
+				masksize *= 2 // repeated
+			}
+			masksize = masksize * pointersPerByte / 8 // 4 bits per word
+			masksize++                                // unroll flag in the beginning
+			if masksize > maxGCMask && typ.gc[1] != 0 {
+				// If the mask is too large, unroll the program directly
+				// into the GC bitmap. It's 7 times slower than copying
+				// from the pre-unrolled mask, but saves 1/16 of type size
+				// memory for the mask.
+				mp := acquirem()
+				mp.ptrarg[0] = x
+				mp.ptrarg[1] = unsafe.Pointer(typ)
+				mp.scalararg[0] = uintptr(size)
+				mp.scalararg[1] = uintptr(size0)
+				onM(unrollgcproginplace_m)
+				releasem(mp)
+				goto marked
+			}
+			ptrmask = (*uint8)(unsafe.Pointer(uintptr(typ.gc[0])))
+			// Check whether the program is already unrolled.
+			if uintptr(atomicloadp(unsafe.Pointer(ptrmask)))&0xff == 0 {
+				mp := acquirem()
+				mp.ptrarg[0] = unsafe.Pointer(typ)
+				onM(unrollgcprog_m)
+				releasem(mp)
+			}
+			ptrmask = (*uint8)(add(unsafe.Pointer(ptrmask), 1)) // skip the unroll flag byte
+		} else {
+			ptrmask = (*uint8)(unsafe.Pointer(typ.gc[0])) // pointer to unrolled mask
+		}
+		if size == 2*ptrSize {
+			*xbits = *ptrmask | bitBoundary
+			goto marked
+		}
+		te = uintptr(typ.size) / ptrSize
+		// If the type occupies odd number of words, its mask is repeated.
+		if te%2 == 0 {
+			te /= 2
+		}
+		// Copy pointer bitmask into the bitmap.
+		for i := uintptr(0); i < size0; i += 2 * ptrSize {
+			v := *(*uint8)(add(unsafe.Pointer(ptrmask), ti))
+			ti++
+			if ti == te {
+				ti = 0
+			}
+			if i == 0 {
+				v |= bitBoundary
+			}
+			if i+ptrSize == size0 {
+				v &^= uint8(bitPtrMask << 4)
+			}
+
+			*xbits = v
+			xbits = (*byte)(add(unsafe.Pointer(xbits), ^uintptr(0)))
+		}
+		if size0%(2*ptrSize) == 0 && size0 < size {
+			// Mark the word after last object's word as bitsDead.
+			*xbits = bitsDead << 2
+		}
+	}
+marked:
+	if raceenabled {
+		racemalloc(x, size)
+	}
+
+	if debugMalloc {
+		mp := acquirem()
+		if mp.mallocing == 0 {
+			gothrow("bad malloc")
+		}
+		mp.mallocing = 0
+		if mp.curg != nil {
+			mp.curg.stackguard0 = mp.curg.stack.lo + _StackGuard
+		}
+		// Note: one releasem for the acquirem just above.
+		// The other for the acquirem at start of malloc.
+		releasem(mp)
+		releasem(mp)
+	}
+
+	if debug.allocfreetrace != 0 {
+		tracealloc(x, size, typ)
+	}
+
+	if rate := MemProfileRate; rate > 0 {
+		if size < uintptr(rate) && int32(size) < c.next_sample {
+			c.next_sample -= int32(size)
+		} else {
+			mp := acquirem()
+			profilealloc(mp, x, size)
+			releasem(mp)
+		}
+	}
+
+	if memstats.heap_alloc >= memstats.next_gc {
+		gogc(0)
+	}
+
+	return x
+}
+
+// implementation of new builtin
+func newobject(typ *_type) unsafe.Pointer {
+	flags := uint32(0)
+	if typ.kind&kindNoPointers != 0 {
+		flags |= flagNoScan
+	}
+	return mallocgc(uintptr(typ.size), typ, flags)
+}
+
+// implementation of make builtin for slices
+func newarray(typ *_type, n uintptr) unsafe.Pointer {
+	flags := uint32(0)
+	if typ.kind&kindNoPointers != 0 {
+		flags |= flagNoScan
+	}
+	if int(n) < 0 || (typ.size > 0 && n > maxmem/uintptr(typ.size)) {
+		panic("runtime: allocation size out of range")
+	}
+	return mallocgc(uintptr(typ.size)*n, typ, flags)
+}
+
+// rawmem returns a chunk of pointerless memory.  It is
+// not zeroed.
+func rawmem(size uintptr) unsafe.Pointer {
+	return mallocgc(size, nil, flagNoScan|flagNoZero)
+}
+
+// round size up to next size class
+func goroundupsize(size uintptr) uintptr {
+	if size < maxSmallSize {
+		if size <= 1024-8 {
+			return uintptr(class_to_size[size_to_class8[(size+7)>>3]])
+		}
+		return uintptr(class_to_size[size_to_class128[(size-1024+127)>>7]])
+	}
+	if size+pageSize < size {
+		return size
+	}
+	return (size + pageSize - 1) &^ pageMask
+}
+
+func profilealloc(mp *m, x unsafe.Pointer, size uintptr) {
+	c := mp.mcache
+	rate := MemProfileRate
+	if size < uintptr(rate) {
+		// pick next profile time
+		// If you change this, also change allocmcache.
+		if rate > 0x3fffffff { // make 2*rate not overflow
+			rate = 0x3fffffff
+		}
+		next := int32(fastrand1()) % (2 * int32(rate))
+		// Subtract the "remainder" of the current allocation.
+		// Otherwise objects that are close in size to sampling rate
+		// will be under-sampled, because we consistently discard this remainder.
+		next -= (int32(size) - c.next_sample)
+		if next < 0 {
+			next = 0
+		}
+		c.next_sample = next
+	}
+
+	mProf_Malloc(x, size)
+}
+
+// force = 1 - do GC regardless of current heap usage
+// force = 2 - go GC and eager sweep
+func gogc(force int32) {
+	// The gc is turned off (via enablegc) until the bootstrap has completed.
+	// Also, malloc gets called in the guts of a number of libraries that might be
+	// holding locks. To avoid deadlocks during stoptheworld, don't bother
+	// trying to run gc while holding a lock. The next mallocgc without a lock
+	// will do the gc instead.
+	mp := acquirem()
+	if gp := getg(); gp == mp.g0 || mp.locks > 1 || !memstats.enablegc || panicking != 0 || gcpercent < 0 {
+		releasem(mp)
+		return
+	}
+	releasem(mp)
+	mp = nil
+
+	semacquire(&worldsema, false)
+
+	if force == 0 && memstats.heap_alloc < memstats.next_gc {
+		// typically threads which lost the race to grab
+		// worldsema exit here when gc is done.
+		semrelease(&worldsema)
+		return
+	}
+
+	// Ok, we're doing it!  Stop everybody else
+	startTime := nanotime()
+	mp = acquirem()
+	mp.gcing = 1
+	releasem(mp)
+	onM(stoptheworld)
+	if mp != acquirem() {
+		gothrow("gogc: rescheduled")
+	}
+
+	clearpools()
+
+	// Run gc on the g0 stack.  We do this so that the g stack
+	// we're currently running on will no longer change.  Cuts
+	// the root set down a bit (g0 stacks are not scanned, and
+	// we don't need to scan gc's internal state).  We also
+	// need to switch to g0 so we can shrink the stack.
+	n := 1
+	if debug.gctrace > 1 {
+		n = 2
+	}
+	for i := 0; i < n; i++ {
+		if i > 0 {
+			startTime = nanotime()
+		}
+		// switch to g0, call gc, then switch back
+		mp.scalararg[0] = uintptr(uint32(startTime)) // low 32 bits
+		mp.scalararg[1] = uintptr(startTime >> 32)   // high 32 bits
+		if force >= 2 {
+			mp.scalararg[2] = 1 // eagersweep
+		} else {
+			mp.scalararg[2] = 0
+		}
+		onM(gc_m)
+	}
+
+	// all done
+	mp.gcing = 0
+	semrelease(&worldsema)
+	onM(starttheworld)
+	releasem(mp)
+	mp = nil
+
+	// now that gc is done, kick off finalizer thread if needed
+	if !concurrentSweep {
+		// give the queued finalizers, if any, a chance to run
+		Gosched()
+	}
+}
+
+// GC runs a garbage collection.
+func GC() {
+	gogc(2)
+}
+
+// linker-provided
+var noptrdata struct{}
+var enoptrdata struct{}
+var noptrbss struct{}
+var enoptrbss struct{}
+
+// SetFinalizer sets the finalizer associated with x to f.
+// When the garbage collector finds an unreachable block
+// with an associated finalizer, it clears the association and runs
+// f(x) in a separate goroutine.  This makes x reachable again, but
+// now without an associated finalizer.  Assuming that SetFinalizer
+// is not called again, the next time the garbage collector sees
+// that x is unreachable, it will free x.
+//
+// SetFinalizer(x, nil) clears any finalizer associated with x.
+//
+// The argument x must be a pointer to an object allocated by
+// calling new or by taking the address of a composite literal.
+// The argument f must be a function that takes a single argument
+// to which x's type can be assigned, and can have arbitrary ignored return
+// values. If either of these is not true, SetFinalizer aborts the
+// program.
+//
+// Finalizers are run in dependency order: if A points at B, both have
+// finalizers, and they are otherwise unreachable, only the finalizer
+// for A runs; once A is freed, the finalizer for B can run.
+// If a cyclic structure includes a block with a finalizer, that
+// cycle is not guaranteed to be garbage collected and the finalizer
+// is not guaranteed to run, because there is no ordering that
+// respects the dependencies.
+//
+// The finalizer for x is scheduled to run at some arbitrary time after
+// x becomes unreachable.
+// There is no guarantee that finalizers will run before a program exits,
+// so typically they are useful only for releasing non-memory resources
+// associated with an object during a long-running program.
+// For example, an os.File object could use a finalizer to close the
+// associated operating system file descriptor when a program discards
+// an os.File without calling Close, but it would be a mistake
+// to depend on a finalizer to flush an in-memory I/O buffer such as a
+// bufio.Writer, because the buffer would not be flushed at program exit.
+//
+// It is not guaranteed that a finalizer will run if the size of *x is
+// zero bytes.
+//
+// It is not guaranteed that a finalizer will run for objects allocated
+// in initializers for package-level variables. Such objects may be
+// linker-allocated, not heap-allocated.
+//
+// A single goroutine runs all finalizers for a program, sequentially.
+// If a finalizer must run for a long time, it should do so by starting
+// a new goroutine.
+func SetFinalizer(obj interface{}, finalizer interface{}) {
+	e := (*eface)(unsafe.Pointer(&obj))
+	etyp := e._type
+	if etyp == nil {
+		gothrow("runtime.SetFinalizer: first argument is nil")
+	}
+	if etyp.kind&kindMask != kindPtr {
+		gothrow("runtime.SetFinalizer: first argument is " + *etyp._string + ", not pointer")
+	}
+	ot := (*ptrtype)(unsafe.Pointer(etyp))
+	if ot.elem == nil {
+		gothrow("nil elem type!")
+	}
+
+	// find the containing object
+	_, base, _ := findObject(e.data)
+
+	if base == nil {
+		// 0-length objects are okay.
+		if e.data == unsafe.Pointer(&zerobase) {
+			return
+		}
+
+		// Global initializers might be linker-allocated.
+		//	var Foo = &Object{}
+		//	func main() {
+		//		runtime.SetFinalizer(Foo, nil)
+		//	}
+		// The relevant segments are: noptrdata, data, bss, noptrbss.
+		// We cannot assume they are in any order or even contiguous,
+		// due to external linking.
+		if uintptr(unsafe.Pointer(&noptrdata)) <= uintptr(e.data) && uintptr(e.data) < uintptr(unsafe.Pointer(&enoptrdata)) ||
+			uintptr(unsafe.Pointer(&data)) <= uintptr(e.data) && uintptr(e.data) < uintptr(unsafe.Pointer(&edata)) ||
+			uintptr(unsafe.Pointer(&bss)) <= uintptr(e.data) && uintptr(e.data) < uintptr(unsafe.Pointer(&ebss)) ||
+			uintptr(unsafe.Pointer(&noptrbss)) <= uintptr(e.data) && uintptr(e.data) < uintptr(unsafe.Pointer(&enoptrbss)) {
+			return
+		}
+		gothrow("runtime.SetFinalizer: pointer not in allocated block")
+	}
+
+	if e.data != base {
+		// As an implementation detail we allow to set finalizers for an inner byte
+		// of an object if it could come from tiny alloc (see mallocgc for details).
+		if ot.elem == nil || ot.elem.kind&kindNoPointers == 0 || ot.elem.size >= maxTinySize {
+			gothrow("runtime.SetFinalizer: pointer not at beginning of allocated block")
+		}
+	}
+
+	f := (*eface)(unsafe.Pointer(&finalizer))
+	ftyp := f._type
+	if ftyp == nil {
+		// switch to M stack and remove finalizer
+		mp := acquirem()
+		mp.ptrarg[0] = e.data
+		onM(removeFinalizer_m)
+		releasem(mp)
+		return
+	}
+
+	if ftyp.kind&kindMask != kindFunc {
+		gothrow("runtime.SetFinalizer: second argument is " + *ftyp._string + ", not a function")
+	}
+	ft := (*functype)(unsafe.Pointer(ftyp))
+	ins := *(*[]*_type)(unsafe.Pointer(&ft.in))
+	if ft.dotdotdot || len(ins) != 1 {
+		gothrow("runtime.SetFinalizer: cannot pass " + *etyp._string + " to finalizer " + *ftyp._string)
+	}
+	fint := ins[0]
+	switch {
+	case fint == etyp:
+		// ok - same type
+		goto okarg
+	case fint.kind&kindMask == kindPtr:
+		if (fint.x == nil || fint.x.name == nil || etyp.x == nil || etyp.x.name == nil) && (*ptrtype)(unsafe.Pointer(fint)).elem == ot.elem {
+			// ok - not same type, but both pointers,
+			// one or the other is unnamed, and same element type, so assignable.
+			goto okarg
+		}
+	case fint.kind&kindMask == kindInterface:
+		ityp := (*interfacetype)(unsafe.Pointer(fint))
+		if len(ityp.mhdr) == 0 {
+			// ok - satisfies empty interface
+			goto okarg
+		}
+		if _, ok := assertE2I2(ityp, obj); ok {
+			goto okarg
+		}
+	}
+	gothrow("runtime.SetFinalizer: cannot pass " + *etyp._string + " to finalizer " + *ftyp._string)
+okarg:
+	// compute size needed for return parameters
+	nret := uintptr(0)
+	for _, t := range *(*[]*_type)(unsafe.Pointer(&ft.out)) {
+		nret = round(nret, uintptr(t.align)) + uintptr(t.size)
+	}
+	nret = round(nret, ptrSize)
+
+	// make sure we have a finalizer goroutine
+	createfing()
+
+	// switch to M stack to add finalizer record
+	mp := acquirem()
+	mp.ptrarg[0] = f.data
+	mp.ptrarg[1] = e.data
+	mp.scalararg[0] = nret
+	mp.ptrarg[2] = unsafe.Pointer(fint)
+	mp.ptrarg[3] = unsafe.Pointer(ot)
+	onM(setFinalizer_m)
+	if mp.scalararg[0] != 1 {
+		gothrow("runtime.SetFinalizer: finalizer already set")
+	}
+	releasem(mp)
+}
+
+// round n up to a multiple of a.  a must be a power of 2.
+func round(n, a uintptr) uintptr {
+	return (n + a - 1) &^ (a - 1)
+}
+
+// Look up pointer v in heap.  Return the span containing the object,
+// the start of the object, and the size of the object.  If the object
+// does not exist, return nil, nil, 0.
+func findObject(v unsafe.Pointer) (s *mspan, x unsafe.Pointer, n uintptr) {
+	c := gomcache()
+	c.local_nlookup++
+	if ptrSize == 4 && c.local_nlookup >= 1<<30 {
+		// purge cache stats to prevent overflow
+		lock(&mheap_.lock)
+		purgecachedstats(c)
+		unlock(&mheap_.lock)
+	}
+
+	// find span
+	arena_start := uintptr(unsafe.Pointer(mheap_.arena_start))
+	arena_used := uintptr(unsafe.Pointer(mheap_.arena_used))
+	if uintptr(v) < arena_start || uintptr(v) >= arena_used {
+		return
+	}
+	p := uintptr(v) >> pageShift
+	q := p - arena_start>>pageShift
+	s = *(**mspan)(add(unsafe.Pointer(mheap_.spans), q*ptrSize))
+	if s == nil {
+		return
+	}
+	x = unsafe.Pointer(uintptr(s.start) << pageShift)
+
+	if uintptr(v) < uintptr(x) || uintptr(v) >= uintptr(unsafe.Pointer(s.limit)) || s.state != mSpanInUse {
+		s = nil
+		x = nil
+		return
+	}
+
+	n = uintptr(s.elemsize)
+	if s.sizeclass != 0 {
+		x = add(x, (uintptr(v)-uintptr(x))/n*n)
+	}
+	return
+}
+
+var fingCreate uint32
+
+func createfing() {
+	// start the finalizer goroutine exactly once
+	if fingCreate == 0 && cas(&fingCreate, 0, 1) {
+		go runfinq()
+	}
+}
+
+// This is the goroutine that runs all of the finalizers
+func runfinq() {
+	var (
+		frame    unsafe.Pointer
+		framecap uintptr
+	)
+
+	for {
+		lock(&finlock)
+		fb := finq
+		finq = nil
+		if fb == nil {
+			gp := getg()
+			fing = gp
+			fingwait = true
+			gp.issystem = true
+			goparkunlock(&finlock, "finalizer wait")
+			gp.issystem = false
+			continue
+		}
+		unlock(&finlock)
+		if raceenabled {
+			racefingo()
+		}
+		for fb != nil {
+			for i := int32(0); i < fb.cnt; i++ {
+				f := (*finalizer)(add(unsafe.Pointer(&fb.fin), uintptr(i)*unsafe.Sizeof(finalizer{})))
+
+				framesz := unsafe.Sizeof((interface{})(nil)) + uintptr(f.nret)
+				if framecap < framesz {
+					// The frame does not contain pointers interesting for GC,
+					// all not yet finalized objects are stored in finq.
+					// If we do not mark it as FlagNoScan,
+					// the last finalized object is not collected.
+					frame = mallocgc(framesz, nil, flagNoScan)
+					framecap = framesz
+				}
+
+				if f.fint == nil {
+					gothrow("missing type in runfinq")
+				}
+				switch f.fint.kind & kindMask {
+				case kindPtr:
+					// direct use of pointer
+					*(*unsafe.Pointer)(frame) = f.arg
+				case kindInterface:
+					ityp := (*interfacetype)(unsafe.Pointer(f.fint))
+					// set up with empty interface
+					(*eface)(frame)._type = &f.ot.typ
+					(*eface)(frame).data = f.arg
+					if len(ityp.mhdr) != 0 {
+						// convert to interface with methods
+						// this conversion is guaranteed to succeed - we checked in SetFinalizer
+						*(*fInterface)(frame) = assertE2I(ityp, *(*interface{})(frame))
+					}
+				default:
+					gothrow("bad kind in runfinq")
+				}
+				reflectcall(unsafe.Pointer(f.fn), frame, uint32(framesz), uint32(framesz))
+
+				// drop finalizer queue references to finalized object
+				f.fn = nil
+				f.arg = nil
+				f.ot = nil
+			}
+			fb.cnt = 0
+			next := fb.next
+			lock(&finlock)
+			fb.next = finc
+			finc = fb
+			unlock(&finlock)
+			fb = next
+		}
+	}
+}
+
+var persistent struct {
+	lock mutex
+	pos  unsafe.Pointer
+	end  unsafe.Pointer
+}
+
+// Wrapper around sysAlloc that can allocate small chunks.
+// There is no associated free operation.
+// Intended for things like function/type/debug-related persistent data.
+// If align is 0, uses default align (currently 8).
+func persistentalloc(size, align uintptr, stat *uint64) unsafe.Pointer {
+	const (
+		chunk    = 256 << 10
+		maxBlock = 64 << 10 // VM reservation granularity is 64K on windows
+	)
+
+	if align != 0 {
+		if align&(align-1) != 0 {
+			gothrow("persistentalloc: align is not a power of 2")
+		}
+		if align > _PageSize {
+			gothrow("persistentalloc: align is too large")
+		}
+	} else {
+		align = 8
+	}
+
+	if size >= maxBlock {
+		return sysAlloc(size, stat)
+	}
+
+	lock(&persistent.lock)
+	persistent.pos = roundup(persistent.pos, align)
+	if uintptr(persistent.pos)+size > uintptr(persistent.end) {
+		persistent.pos = sysAlloc(chunk, &memstats.other_sys)
+		if persistent.pos == nil {
+			unlock(&persistent.lock)
+			gothrow("runtime: cannot allocate memory")
+		}
+		persistent.end = add(persistent.pos, chunk)
+	}
+	p := persistent.pos
+	persistent.pos = add(persistent.pos, size)
+	unlock(&persistent.lock)
+
+	if stat != &memstats.other_sys {
+		xadd64(stat, int64(size))
+		xadd64(&memstats.other_sys, -int64(size))
+	}
+	return p
+}
diff --git a/src/runtime/malloc.h b/src/runtime/malloc.h
new file mode 100644
index 0000000..adb8d3d
--- /dev/null
+++ b/src/runtime/malloc.h
@@ -0,0 +1,621 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Memory allocator, based on tcmalloc.
+// http://goog-perftools.sourceforge.net/doc/tcmalloc.html
+
+// The main allocator works in runs of pages.
+// Small allocation sizes (up to and including 32 kB) are
+// rounded to one of about 100 size classes, each of which
+// has its own free list of objects of exactly that size.
+// Any free page of memory can be split into a set of objects
+// of one size class, which are then managed using free list
+// allocators.
+//
+// The allocator's data structures are:
+//
+//	FixAlloc: a free-list allocator for fixed-size objects,
+//		used to manage storage used by the allocator.
+//	MHeap: the malloc heap, managed at page (4096-byte) granularity.
+//	MSpan: a run of pages managed by the MHeap.
+//	MCentral: a shared free list for a given size class.
+//	MCache: a per-thread (in Go, per-P) cache for small objects.
+//	MStats: allocation statistics.
+//
+// Allocating a small object proceeds up a hierarchy of caches:
+//
+//	1. Round the size up to one of the small size classes
+//	   and look in the corresponding MCache free list.
+//	   If the list is not empty, allocate an object from it.
+//	   This can all be done without acquiring a lock.
+//
+//	2. If the MCache free list is empty, replenish it by
+//	   taking a bunch of objects from the MCentral free list.
+//	   Moving a bunch amortizes the cost of acquiring the MCentral lock.
+//
+//	3. If the MCentral free list is empty, replenish it by
+//	   allocating a run of pages from the MHeap and then
+//	   chopping that memory into a objects of the given size.
+//	   Allocating many objects amortizes the cost of locking
+//	   the heap.
+//
+//	4. If the MHeap is empty or has no page runs large enough,
+//	   allocate a new group of pages (at least 1MB) from the
+//	   operating system.  Allocating a large run of pages
+//	   amortizes the cost of talking to the operating system.
+//
+// Freeing a small object proceeds up the same hierarchy:
+//
+//	1. Look up the size class for the object and add it to
+//	   the MCache free list.
+//
+//	2. If the MCache free list is too long or the MCache has
+//	   too much memory, return some to the MCentral free lists.
+//
+//	3. If all the objects in a given span have returned to
+//	   the MCentral list, return that span to the page heap.
+//
+//	4. If the heap has too much memory, return some to the
+//	   operating system.
+//
+//	TODO(rsc): Step 4 is not implemented.
+//
+// Allocating and freeing a large object uses the page heap
+// directly, bypassing the MCache and MCentral free lists.
+//
+// The small objects on the MCache and MCentral free lists
+// may or may not be zeroed.  They are zeroed if and only if
+// the second word of the object is zero.  A span in the
+// page heap is zeroed unless s->needzero is set. When a span
+// is allocated to break into small objects, it is zeroed if needed
+// and s->needzero is set. There are two main benefits to delaying the
+// zeroing this way:
+//
+//	1. stack frames allocated from the small object lists
+//	   or the page heap can avoid zeroing altogether.
+//	2. the cost of zeroing when reusing a small object is
+//	   charged to the mutator, not the garbage collector.
+//
+// This C code was written with an eye toward translating to Go
+// in the future.  Methods have the form Type_Method(Type *t, ...).
+
+typedef struct MCentral	MCentral;
+typedef struct MHeap	MHeap;
+typedef struct MSpan	MSpan;
+typedef struct MStats	MStats;
+typedef struct MLink	MLink;
+typedef struct GCStats	GCStats;
+
+enum
+{
+	PageShift	= 13,
+	PageSize	= 1<<PageShift,
+	PageMask	= PageSize - 1,
+};
+typedef	uintptr	pageID;		// address >> PageShift
+
+enum
+{
+	// Computed constant.  The definition of MaxSmallSize and the
+	// algorithm in msize.c produce some number of different allocation
+	// size classes.  NumSizeClasses is that number.  It's needed here
+	// because there are static arrays of this length; when msize runs its
+	// size choosing algorithm it double-checks that NumSizeClasses agrees.
+	NumSizeClasses = 67,
+
+	// Tunable constants.
+	MaxSmallSize = 32<<10,
+
+	// Tiny allocator parameters, see "Tiny allocator" comment in malloc.goc.
+	TinySize = 16,
+	TinySizeClass = 2,
+
+	FixAllocChunk = 16<<10,		// Chunk size for FixAlloc
+	MaxMHeapList = 1<<(20 - PageShift),	// Maximum page length for fixed-size list in MHeap.
+	HeapAllocChunk = 1<<20,		// Chunk size for heap growth
+
+	// Per-P, per order stack segment cache size.
+	StackCacheSize = 32*1024,
+	// Number of orders that get caching.  Order 0 is FixedStack
+	// and each successive order is twice as large.
+	NumStackOrders = 3,
+
+	// Number of bits in page to span calculations (4k pages).
+	// On Windows 64-bit we limit the arena to 32GB or 35 bits (see below for reason).
+	// On other 64-bit platforms, we limit the arena to 128GB, or 37 bits.
+	// On 32-bit, we don't bother limiting anything, so we use the full 32-bit address.
+#ifdef _64BIT
+#ifdef GOOS_windows
+	// Windows counts memory used by page table into committed memory
+	// of the process, so we can't reserve too much memory.
+	// See http://golang.org/issue/5402 and http://golang.org/issue/5236.
+	MHeapMap_Bits = 35 - PageShift,
+#else
+	MHeapMap_Bits = 37 - PageShift,
+#endif
+#else
+	MHeapMap_Bits = 32 - PageShift,
+#endif
+
+	// Max number of threads to run garbage collection.
+	// 2, 3, and 4 are all plausible maximums depending
+	// on the hardware details of the machine.  The garbage
+	// collector scales well to 32 cpus.
+	MaxGcproc = 32,
+};
+
+// Maximum memory allocation size, a hint for callers.
+// This must be a #define instead of an enum because it
+// is so large.
+#ifdef _64BIT
+#define	MaxMem	(1ULL<<(MHeapMap_Bits+PageShift))	/* 128 GB or 32 GB */
+#else
+#define	MaxMem	((uintptr)-1)
+#endif
+
+// A generic linked list of blocks.  (Typically the block is bigger than sizeof(MLink).)
+struct MLink
+{
+	MLink *next;
+};
+
+// sysAlloc obtains a large chunk of zeroed memory from the
+// operating system, typically on the order of a hundred kilobytes
+// or a megabyte.
+// NOTE: sysAlloc returns OS-aligned memory, but the heap allocator
+// may use larger alignment, so the caller must be careful to realign the
+// memory obtained by sysAlloc.
+//
+// SysUnused notifies the operating system that the contents
+// of the memory region are no longer needed and can be reused
+// for other purposes.
+// SysUsed notifies the operating system that the contents
+// of the memory region are needed again.
+//
+// SysFree returns it unconditionally; this is only used if
+// an out-of-memory error has been detected midway through
+// an allocation.  It is okay if SysFree is a no-op.
+//
+// SysReserve reserves address space without allocating memory.
+// If the pointer passed to it is non-nil, the caller wants the
+// reservation there, but SysReserve can still choose another
+// location if that one is unavailable.  On some systems and in some
+// cases SysReserve will simply check that the address space is
+// available and not actually reserve it.  If SysReserve returns
+// non-nil, it sets *reserved to true if the address space is
+// reserved, false if it has merely been checked.
+// NOTE: SysReserve returns OS-aligned memory, but the heap allocator
+// may use larger alignment, so the caller must be careful to realign the
+// memory obtained by sysAlloc.
+//
+// SysMap maps previously reserved address space for use.
+// The reserved argument is true if the address space was really
+// reserved, not merely checked.
+//
+// SysFault marks a (already sysAlloc'd) region to fault
+// if accessed.  Used only for debugging the runtime.
+
+void*	runtime·sysAlloc(uintptr nbytes, uint64 *stat);
+void	runtime·SysFree(void *v, uintptr nbytes, uint64 *stat);
+void	runtime·SysUnused(void *v, uintptr nbytes);
+void	runtime·SysUsed(void *v, uintptr nbytes);
+void	runtime·SysMap(void *v, uintptr nbytes, bool reserved, uint64 *stat);
+void*	runtime·SysReserve(void *v, uintptr nbytes, bool *reserved);
+void	runtime·SysFault(void *v, uintptr nbytes);
+
+// FixAlloc is a simple free-list allocator for fixed size objects.
+// Malloc uses a FixAlloc wrapped around sysAlloc to manages its
+// MCache and MSpan objects.
+//
+// Memory returned by FixAlloc_Alloc is not zeroed.
+// The caller is responsible for locking around FixAlloc calls.
+// Callers can keep state in the object but the first word is
+// smashed by freeing and reallocating.
+struct FixAlloc
+{
+	uintptr	size;
+	void	(*first)(void *arg, byte *p);	// called first time p is returned
+	void*	arg;
+	MLink*	list;
+	byte*	chunk;
+	uint32	nchunk;
+	uintptr	inuse;	// in-use bytes now
+	uint64*	stat;
+};
+
+void	runtime·FixAlloc_Init(FixAlloc *f, uintptr size, void (*first)(void*, byte*), void *arg, uint64 *stat);
+void*	runtime·FixAlloc_Alloc(FixAlloc *f);
+void	runtime·FixAlloc_Free(FixAlloc *f, void *p);
+
+
+// Statistics.
+// Shared with Go: if you edit this structure, also edit type MemStats in mem.go.
+struct MStats
+{
+	// General statistics.
+	uint64	alloc;		// bytes allocated and still in use
+	uint64	total_alloc;	// bytes allocated (even if freed)
+	uint64	sys;		// bytes obtained from system (should be sum of xxx_sys below, no locking, approximate)
+	uint64	nlookup;	// number of pointer lookups
+	uint64	nmalloc;	// number of mallocs
+	uint64	nfree;  // number of frees
+
+	// Statistics about malloc heap.
+	// protected by mheap.lock
+	uint64	heap_alloc;	// bytes allocated and still in use
+	uint64	heap_sys;	// bytes obtained from system
+	uint64	heap_idle;	// bytes in idle spans
+	uint64	heap_inuse;	// bytes in non-idle spans
+	uint64	heap_released;	// bytes released to the OS
+	uint64	heap_objects;	// total number of allocated objects
+
+	// Statistics about allocation of low-level fixed-size structures.
+	// Protected by FixAlloc locks.
+	uint64	stacks_inuse;	// this number is included in heap_inuse above
+	uint64	stacks_sys;	// always 0 in mstats
+	uint64	mspan_inuse;	// MSpan structures
+	uint64	mspan_sys;
+	uint64	mcache_inuse;	// MCache structures
+	uint64	mcache_sys;
+	uint64	buckhash_sys;	// profiling bucket hash table
+	uint64	gc_sys;
+	uint64	other_sys;
+
+	// Statistics about garbage collector.
+	// Protected by mheap or stopping the world during GC.
+	uint64	next_gc;	// next GC (in heap_alloc time)
+	uint64  last_gc;	// last GC (in absolute time)
+	uint64	pause_total_ns;
+	uint64	pause_ns[256];  // circular buffer of recent GC pause lengths
+	uint64	pause_end[256]; // circular buffer of recent GC end times (nanoseconds since 1970)
+	uint32	numgc;
+	bool	enablegc;
+	bool	debuggc;
+
+	// Statistics about allocation size classes.
+	
+	struct MStatsBySize {
+		uint32 size;
+		uint64 nmalloc;
+		uint64 nfree;
+	} by_size[NumSizeClasses];
+	
+	uint64	tinyallocs;	// number of tiny allocations that didn't cause actual allocation; not exported to Go directly
+};
+
+
+#define mstats runtime·memstats
+extern MStats mstats;
+void	runtime·updatememstats(GCStats *stats);
+void	runtime·ReadMemStats(MStats *stats);
+
+// Size classes.  Computed and initialized by InitSizes.
+//
+// SizeToClass(0 <= n <= MaxSmallSize) returns the size class,
+//	1 <= sizeclass < NumSizeClasses, for n.
+//	Size class 0 is reserved to mean "not small".
+//
+// class_to_size[i] = largest size in class i
+// class_to_allocnpages[i] = number of pages to allocate when
+//	making new objects in class i
+
+int32	runtime·SizeToClass(int32);
+uintptr	runtime·roundupsize(uintptr);
+extern	int32	runtime·class_to_size[NumSizeClasses];
+extern	int32	runtime·class_to_allocnpages[NumSizeClasses];
+extern	int8	runtime·size_to_class8[1024/8 + 1];
+extern	int8	runtime·size_to_class128[(MaxSmallSize-1024)/128 + 1];
+extern	void	runtime·InitSizes(void);
+
+typedef struct MCacheList MCacheList;
+struct MCacheList
+{
+	MLink *list;
+	uint32 nlist;
+};
+
+typedef struct StackFreeList StackFreeList;
+struct StackFreeList
+{
+	MLink *list;  // linked list of free stacks
+	uintptr size; // total size of stacks in list
+};
+
+typedef struct SudoG SudoG;
+
+// Per-thread (in Go, per-P) cache for small objects.
+// No locking needed because it is per-thread (per-P).
+struct MCache
+{
+	// The following members are accessed on every malloc,
+	// so they are grouped here for better caching.
+	int32 next_sample;		// trigger heap sample after allocating this many bytes
+	intptr local_cachealloc;	// bytes allocated (or freed) from cache since last lock of heap
+	// Allocator cache for tiny objects w/o pointers.
+	// See "Tiny allocator" comment in malloc.goc.
+	byte*	tiny;
+	uintptr	tinysize;
+	uintptr	local_tinyallocs;	// number of tiny allocs not counted in other stats
+	// The rest is not accessed on every malloc.
+	MSpan*	alloc[NumSizeClasses];	// spans to allocate from
+
+	StackFreeList stackcache[NumStackOrders];
+
+	SudoG*	sudogcache;
+
+	void*	gcworkbuf;
+
+	// Local allocator stats, flushed during GC.
+	uintptr local_nlookup;		// number of pointer lookups
+	uintptr local_largefree;	// bytes freed for large objects (>MaxSmallSize)
+	uintptr local_nlargefree;	// number of frees for large objects (>MaxSmallSize)
+	uintptr local_nsmallfree[NumSizeClasses];	// number of frees for small objects (<=MaxSmallSize)
+};
+
+MSpan*	runtime·MCache_Refill(MCache *c, int32 sizeclass);
+void	runtime·MCache_ReleaseAll(MCache *c);
+void	runtime·stackcache_clear(MCache *c);
+void	runtime·gcworkbuffree(void *b);
+
+enum
+{
+	KindSpecialFinalizer = 1,
+	KindSpecialProfile = 2,
+	// Note: The finalizer special must be first because if we're freeing
+	// an object, a finalizer special will cause the freeing operation
+	// to abort, and we want to keep the other special records around
+	// if that happens.
+};
+
+typedef struct Special Special;
+struct Special
+{
+	Special*	next;	// linked list in span
+	uint16		offset;	// span offset of object
+	byte		kind;	// kind of Special
+};
+
+// The described object has a finalizer set for it.
+typedef struct SpecialFinalizer SpecialFinalizer;
+struct SpecialFinalizer
+{
+	Special		special;
+	FuncVal*	fn;
+	uintptr		nret;
+	Type*		fint;
+	PtrType*	ot;
+};
+
+// The described object is being heap profiled.
+typedef struct Bucket Bucket; // from mprof.h
+typedef struct SpecialProfile SpecialProfile;
+struct SpecialProfile
+{
+	Special	special;
+	Bucket*	b;
+};
+
+// An MSpan is a run of pages.
+enum
+{
+	MSpanInUse = 0, // allocated for garbage collected heap
+	MSpanStack,     // allocated for use by stack allocator
+	MSpanFree,
+	MSpanListHead,
+	MSpanDead,
+};
+struct MSpan
+{
+	MSpan	*next;		// in a span linked list
+	MSpan	*prev;		// in a span linked list
+	pageID	start;		// starting page number
+	uintptr	npages;		// number of pages in span
+	MLink	*freelist;	// list of free objects
+	// sweep generation:
+	// if sweepgen == h->sweepgen - 2, the span needs sweeping
+	// if sweepgen == h->sweepgen - 1, the span is currently being swept
+	// if sweepgen == h->sweepgen, the span is swept and ready to use
+	// h->sweepgen is incremented by 2 after every GC
+	uint32	sweepgen;
+	uint16	ref;		// capacity - number of objects in freelist
+	uint8	sizeclass;	// size class
+	bool	incache;	// being used by an MCache
+	uint8	state;		// MSpanInUse etc
+	uint8	needzero;	// needs to be zeroed before allocation
+	uintptr	elemsize;	// computed from sizeclass or from npages
+	int64   unusedsince;	// First time spotted by GC in MSpanFree state
+	uintptr npreleased;	// number of pages released to the OS
+	byte	*limit;		// end of data in span
+	Mutex	specialLock;	// guards specials list
+	Special	*specials;	// linked list of special records sorted by offset.
+};
+
+void	runtime·MSpan_Init(MSpan *span, pageID start, uintptr npages);
+void	runtime·MSpan_EnsureSwept(MSpan *span);
+bool	runtime·MSpan_Sweep(MSpan *span, bool preserve);
+
+// Every MSpan is in one doubly-linked list,
+// either one of the MHeap's free lists or one of the
+// MCentral's span lists.  We use empty MSpan structures as list heads.
+void	runtime·MSpanList_Init(MSpan *list);
+bool	runtime·MSpanList_IsEmpty(MSpan *list);
+void	runtime·MSpanList_Insert(MSpan *list, MSpan *span);
+void	runtime·MSpanList_InsertBack(MSpan *list, MSpan *span);
+void	runtime·MSpanList_Remove(MSpan *span);	// from whatever list it is in
+
+
+// Central list of free objects of a given size.
+struct MCentral
+{
+	Mutex  lock;
+	int32 sizeclass;
+	MSpan nonempty;	// list of spans with a free object
+	MSpan empty;	// list of spans with no free objects (or cached in an MCache)
+};
+
+void	runtime·MCentral_Init(MCentral *c, int32 sizeclass);
+MSpan*	runtime·MCentral_CacheSpan(MCentral *c);
+void	runtime·MCentral_UncacheSpan(MCentral *c, MSpan *s);
+bool	runtime·MCentral_FreeSpan(MCentral *c, MSpan *s, int32 n, MLink *start, MLink *end, bool preserve);
+
+// Main malloc heap.
+// The heap itself is the "free[]" and "large" arrays,
+// but all the other global data is here too.
+struct MHeap
+{
+	Mutex  lock;
+	MSpan free[MaxMHeapList];	// free lists of given length
+	MSpan freelarge;		// free lists length >= MaxMHeapList
+	MSpan busy[MaxMHeapList];	// busy lists of large objects of given length
+	MSpan busylarge;		// busy lists of large objects length >= MaxMHeapList
+	MSpan **allspans;		// all spans out there
+	MSpan **gcspans;		// copy of allspans referenced by GC marker or sweeper
+	uint32	nspan;
+	uint32	nspancap;
+	uint32	sweepgen;		// sweep generation, see comment in MSpan
+	uint32	sweepdone;		// all spans are swept
+
+	// span lookup
+	MSpan**	spans;
+	uintptr	spans_mapped;
+
+	// range of addresses we might see in the heap
+	byte *bitmap;
+	uintptr bitmap_mapped;
+	byte *arena_start;
+	byte *arena_used;
+	byte *arena_end;
+	bool arena_reserved;
+
+	// central free lists for small size classes.
+	// the padding makes sure that the MCentrals are
+	// spaced CacheLineSize bytes apart, so that each MCentral.lock
+	// gets its own cache line.
+	struct MHeapCentral {
+		MCentral mcentral;
+		byte pad[CacheLineSize];
+	} central[NumSizeClasses];
+
+	FixAlloc spanalloc;	// allocator for Span*
+	FixAlloc cachealloc;	// allocator for MCache*
+	FixAlloc specialfinalizeralloc;	// allocator for SpecialFinalizer*
+	FixAlloc specialprofilealloc;	// allocator for SpecialProfile*
+	Mutex speciallock; // lock for sepcial record allocators.
+
+	// Malloc stats.
+	uint64 largefree;	// bytes freed for large objects (>MaxSmallSize)
+	uint64 nlargefree;	// number of frees for large objects (>MaxSmallSize)
+	uint64 nsmallfree[NumSizeClasses];	// number of frees for small objects (<=MaxSmallSize)
+};
+#define runtime·mheap runtime·mheap_
+extern MHeap runtime·mheap;
+
+void	runtime·MHeap_Init(MHeap *h);
+MSpan*	runtime·MHeap_Alloc(MHeap *h, uintptr npage, int32 sizeclass, bool large, bool needzero);
+MSpan*	runtime·MHeap_AllocStack(MHeap *h, uintptr npage);
+void	runtime·MHeap_Free(MHeap *h, MSpan *s, int32 acct);
+void	runtime·MHeap_FreeStack(MHeap *h, MSpan *s);
+MSpan*	runtime·MHeap_Lookup(MHeap *h, void *v);
+MSpan*	runtime·MHeap_LookupMaybe(MHeap *h, void *v);
+void*	runtime·MHeap_SysAlloc(MHeap *h, uintptr n);
+void	runtime·MHeap_MapBits(MHeap *h);
+void	runtime·MHeap_MapSpans(MHeap *h);
+void	runtime·MHeap_Scavenge(int32 k, uint64 now, uint64 limit);
+
+void*	runtime·persistentalloc(uintptr size, uintptr align, uint64 *stat);
+int32	runtime·mlookup(void *v, byte **base, uintptr *size, MSpan **s);
+uintptr	runtime·sweepone(void);
+void	runtime·markspan(void *v, uintptr size, uintptr n, bool leftover);
+void	runtime·unmarkspan(void *v, uintptr size);
+void	runtime·purgecachedstats(MCache*);
+void	runtime·tracealloc(void*, uintptr, Type*);
+void	runtime·tracefree(void*, uintptr);
+void	runtime·tracegc(void);
+
+int32	runtime·gcpercent;
+int32	runtime·readgogc(void);
+void	runtime·clearpools(void);
+
+enum
+{
+	// flags to malloc
+	FlagNoScan	= 1<<0,	// GC doesn't have to scan object
+	FlagNoZero	= 1<<1, // don't zero memory
+};
+
+void	runtime·mProf_Malloc(void*, uintptr);
+void	runtime·mProf_Free(Bucket*, uintptr, bool);
+void	runtime·mProf_GC(void);
+void	runtime·iterate_memprof(void (**callback)(Bucket*, uintptr, uintptr*, uintptr, uintptr, uintptr));
+int32	runtime·gcprocs(void);
+void	runtime·helpgc(int32 nproc);
+void	runtime·gchelper(void);
+void	runtime·createfing(void);
+G*	runtime·wakefing(void);
+void	runtime·getgcmask(byte*, Type*, byte**, uintptr*);
+
+// NOTE: Layout known to queuefinalizer.
+typedef struct Finalizer Finalizer;
+struct Finalizer
+{
+	FuncVal *fn;	// function to call
+	void *arg;	// ptr to object
+	uintptr nret;	// bytes of return values from fn
+	Type *fint;	// type of first argument of fn
+	PtrType *ot;	// type of ptr to object
+};
+
+typedef struct FinBlock FinBlock;
+struct FinBlock
+{
+	FinBlock *alllink;
+	FinBlock *next;
+	int32 cnt;
+	int32 cap;
+	Finalizer fin[1];
+};
+extern Mutex	runtime·finlock;	// protects the following variables
+extern G*	runtime·fing;
+extern bool	runtime·fingwait;
+extern bool	runtime·fingwake;
+extern FinBlock	*runtime·finq;		// list of finalizers that are to be executed
+extern FinBlock	*runtime·finc;		// cache of free blocks
+
+void	runtime·setprofilebucket_m(void);
+
+bool	runtime·addfinalizer(void*, FuncVal *fn, uintptr, Type*, PtrType*);
+void	runtime·removefinalizer(void*);
+void	runtime·queuefinalizer(byte *p, FuncVal *fn, uintptr nret, Type *fint, PtrType *ot);
+bool	runtime·freespecial(Special *s, void *p, uintptr size, bool freed);
+
+// Information from the compiler about the layout of stack frames.
+struct BitVector
+{
+	int32 n; // # of bits
+	uint8 *bytedata;
+};
+typedef struct StackMap StackMap;
+struct StackMap
+{
+	int32 n; // number of bitmaps
+	int32 nbit; // number of bits in each bitmap
+	uint8 bytedata[]; // bitmaps, each starting on a 32-bit boundary
+};
+// Returns pointer map data for the given stackmap index
+// (the index is encoded in PCDATA_StackMapIndex).
+BitVector	runtime·stackmapdata(StackMap *stackmap, int32 n);
+
+extern	BitVector	runtime·gcdatamask;
+extern	BitVector	runtime·gcbssmask;
+
+// defined in mgc0.go
+void	runtime·gc_m_ptr(Eface*);
+void	runtime·gc_g_ptr(Eface*);
+void	runtime·gc_itab_ptr(Eface*);
+
+void  runtime·setgcpercent_m(void);
+
+// Value we use to mark dead pointers when GODEBUG=gcdead=1.
+#define PoisonGC ((uintptr)0xf969696969696969ULL)
+#define PoisonStack ((uintptr)0x6868686868686868ULL)
diff --git a/src/runtime/malloc_test.go b/src/runtime/malloc_test.go
new file mode 100644
index 0000000..b7795aa
--- /dev/null
+++ b/src/runtime/malloc_test.go
@@ -0,0 +1,189 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package runtime_test
+
+import (
+	"flag"
+	. "runtime"
+	"testing"
+	"time"
+	"unsafe"
+)
+
+func TestMemStats(t *testing.T) {
+	// Test that MemStats has sane values.
+	st := new(MemStats)
+	ReadMemStats(st)
+
+	// Everything except HeapReleased and HeapIdle, because they indeed can be 0.
+	if st.Alloc == 0 || st.TotalAlloc == 0 || st.Sys == 0 || st.Lookups == 0 ||
+		st.Mallocs == 0 || st.Frees == 0 || st.HeapAlloc == 0 || st.HeapSys == 0 ||
+		st.HeapInuse == 0 || st.HeapObjects == 0 || st.StackInuse == 0 ||
+		st.StackSys == 0 || st.MSpanInuse == 0 || st.MSpanSys == 0 || st.MCacheInuse == 0 ||
+		st.MCacheSys == 0 || st.BuckHashSys == 0 || st.GCSys == 0 || st.OtherSys == 0 ||
+		st.NextGC == 0 || st.NumGC == 0 {
+		t.Fatalf("Zero value: %+v", *st)
+	}
+
+	if st.Alloc > 1e10 || st.TotalAlloc > 1e11 || st.Sys > 1e10 || st.Lookups > 1e10 ||
+		st.Mallocs > 1e10 || st.Frees > 1e10 || st.HeapAlloc > 1e10 || st.HeapSys > 1e10 ||
+		st.HeapIdle > 1e10 || st.HeapInuse > 1e10 || st.HeapObjects > 1e10 || st.StackInuse > 1e10 ||
+		st.StackSys > 1e10 || st.MSpanInuse > 1e10 || st.MSpanSys > 1e10 || st.MCacheInuse > 1e10 ||
+		st.MCacheSys > 1e10 || st.BuckHashSys > 1e10 || st.GCSys > 1e10 || st.OtherSys > 1e10 ||
+		st.NextGC > 1e10 || st.NumGC > 1e9 {
+		t.Fatalf("Insanely high value (overflow?): %+v", *st)
+	}
+
+	if st.Sys != st.HeapSys+st.StackSys+st.MSpanSys+st.MCacheSys+
+		st.BuckHashSys+st.GCSys+st.OtherSys {
+		t.Fatalf("Bad sys value: %+v", *st)
+	}
+
+	if st.HeapIdle+st.HeapInuse != st.HeapSys {
+		t.Fatalf("HeapIdle(%d) + HeapInuse(%d) should be equal to HeapSys(%d), but isn't.", st.HeapIdle, st.HeapInuse, st.HeapSys)
+	}
+}
+
+var mallocSink uintptr
+
+func BenchmarkMalloc8(b *testing.B) {
+	var x uintptr
+	for i := 0; i < b.N; i++ {
+		p := new(int64)
+		x ^= uintptr(unsafe.Pointer(p))
+	}
+	mallocSink = x
+}
+
+func BenchmarkMalloc16(b *testing.B) {
+	var x uintptr
+	for i := 0; i < b.N; i++ {
+		p := new([2]int64)
+		x ^= uintptr(unsafe.Pointer(p))
+	}
+	mallocSink = x
+}
+
+func BenchmarkMallocTypeInfo8(b *testing.B) {
+	var x uintptr
+	for i := 0; i < b.N; i++ {
+		p := new(struct {
+			p [8 / unsafe.Sizeof(uintptr(0))]*int
+		})
+		x ^= uintptr(unsafe.Pointer(p))
+	}
+	mallocSink = x
+}
+
+func BenchmarkMallocTypeInfo16(b *testing.B) {
+	var x uintptr
+	for i := 0; i < b.N; i++ {
+		p := new(struct {
+			p [16 / unsafe.Sizeof(uintptr(0))]*int
+		})
+		x ^= uintptr(unsafe.Pointer(p))
+	}
+	mallocSink = x
+}
+
+type LargeStruct struct {
+	x [16][]byte
+}
+
+func BenchmarkMallocLargeStruct(b *testing.B) {
+	var x uintptr
+	for i := 0; i < b.N; i++ {
+		p := make([]LargeStruct, 2)
+		x ^= uintptr(unsafe.Pointer(&p[0]))
+	}
+	mallocSink = x
+}
+
+var n = flag.Int("n", 1000, "number of goroutines")
+
+func BenchmarkGoroutineSelect(b *testing.B) {
+	quit := make(chan struct{})
+	read := func(ch chan struct{}) {
+		for {
+			select {
+			case _, ok := <-ch:
+				if !ok {
+					return
+				}
+			case <-quit:
+				return
+			}
+		}
+	}
+	benchHelper(b, *n, read)
+}
+
+func BenchmarkGoroutineBlocking(b *testing.B) {
+	read := func(ch chan struct{}) {
+		for {
+			if _, ok := <-ch; !ok {
+				return
+			}
+		}
+	}
+	benchHelper(b, *n, read)
+}
+
+func BenchmarkGoroutineForRange(b *testing.B) {
+	read := func(ch chan struct{}) {
+		for range ch {
+		}
+	}
+	benchHelper(b, *n, read)
+}
+
+func benchHelper(b *testing.B, n int, read func(chan struct{})) {
+	m := make([]chan struct{}, n)
+	for i := range m {
+		m[i] = make(chan struct{}, 1)
+		go read(m[i])
+	}
+	b.StopTimer()
+	b.ResetTimer()
+	GC()
+
+	for i := 0; i < b.N; i++ {
+		for _, ch := range m {
+			if ch != nil {
+				ch <- struct{}{}
+			}
+		}
+		time.Sleep(10 * time.Millisecond)
+		b.StartTimer()
+		GC()
+		b.StopTimer()
+	}
+
+	for _, ch := range m {
+		close(ch)
+	}
+	time.Sleep(10 * time.Millisecond)
+}
+
+func BenchmarkGoroutineIdle(b *testing.B) {
+	quit := make(chan struct{})
+	fn := func() {
+		<-quit
+	}
+	for i := 0; i < *n; i++ {
+		go fn()
+	}
+
+	GC()
+	b.ResetTimer()
+
+	for i := 0; i < b.N; i++ {
+		GC()
+	}
+
+	b.StopTimer()
+	close(quit)
+	time.Sleep(10 * time.Millisecond)
+}
diff --git a/src/runtime/map_test.go b/src/runtime/map_test.go
new file mode 100644
index 0000000..92da2d8
--- /dev/null
+++ b/src/runtime/map_test.go
@@ -0,0 +1,537 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package runtime_test
+
+import (
+	"fmt"
+	"math"
+	"reflect"
+	"runtime"
+	"sort"
+	"strings"
+	"sync"
+	"testing"
+)
+
+// negative zero is a good test because:
+//  1) 0 and -0 are equal, yet have distinct representations.
+//  2) 0 is represented as all zeros, -0 isn't.
+// I'm not sure the language spec actually requires this behavior,
+// but it's what the current map implementation does.
+func TestNegativeZero(t *testing.T) {
+	m := make(map[float64]bool, 0)
+
+	m[+0.0] = true
+	m[math.Copysign(0.0, -1.0)] = true // should overwrite +0 entry
+
+	if len(m) != 1 {
+		t.Error("length wrong")
+	}
+
+	for k := range m {
+		if math.Copysign(1.0, k) > 0 {
+			t.Error("wrong sign")
+		}
+	}
+
+	m = make(map[float64]bool, 0)
+	m[math.Copysign(0.0, -1.0)] = true
+	m[+0.0] = true // should overwrite -0.0 entry
+
+	if len(m) != 1 {
+		t.Error("length wrong")
+	}
+
+	for k := range m {
+		if math.Copysign(1.0, k) < 0 {
+			t.Error("wrong sign")
+		}
+	}
+}
+
+// nan is a good test because nan != nan, and nan has
+// a randomized hash value.
+func TestNan(t *testing.T) {
+	m := make(map[float64]int, 0)
+	nan := math.NaN()
+	m[nan] = 1
+	m[nan] = 2
+	m[nan] = 4
+	if len(m) != 3 {
+		t.Error("length wrong")
+	}
+	s := 0
+	for k, v := range m {
+		if k == k {
+			t.Error("nan disappeared")
+		}
+		if (v & (v - 1)) != 0 {
+			t.Error("value wrong")
+		}
+		s |= v
+	}
+	if s != 7 {
+		t.Error("values wrong")
+	}
+}
+
+// Maps aren't actually copied on assignment.
+func TestAlias(t *testing.T) {
+	m := make(map[int]int, 0)
+	m[0] = 5
+	n := m
+	n[0] = 6
+	if m[0] != 6 {
+		t.Error("alias didn't work")
+	}
+}
+
+func TestGrowWithNaN(t *testing.T) {
+	m := make(map[float64]int, 4)
+	nan := math.NaN()
+	m[nan] = 1
+	m[nan] = 2
+	m[nan] = 4
+	cnt := 0
+	s := 0
+	growflag := true
+	for k, v := range m {
+		if growflag {
+			// force a hashtable resize
+			for i := 0; i < 100; i++ {
+				m[float64(i)] = i
+			}
+			growflag = false
+		}
+		if k != k {
+			cnt++
+			s |= v
+		}
+	}
+	if cnt != 3 {
+		t.Error("NaN keys lost during grow")
+	}
+	if s != 7 {
+		t.Error("NaN values lost during grow")
+	}
+}
+
+type FloatInt struct {
+	x float64
+	y int
+}
+
+func TestGrowWithNegativeZero(t *testing.T) {
+	negzero := math.Copysign(0.0, -1.0)
+	m := make(map[FloatInt]int, 4)
+	m[FloatInt{0.0, 0}] = 1
+	m[FloatInt{0.0, 1}] = 2
+	m[FloatInt{0.0, 2}] = 4
+	m[FloatInt{0.0, 3}] = 8
+	growflag := true
+	s := 0
+	cnt := 0
+	negcnt := 0
+	// The first iteration should return the +0 key.
+	// The subsequent iterations should return the -0 key.
+	// I'm not really sure this is required by the spec,
+	// but it makes sense.
+	// TODO: are we allowed to get the first entry returned again???
+	for k, v := range m {
+		if v == 0 {
+			continue
+		} // ignore entries added to grow table
+		cnt++
+		if math.Copysign(1.0, k.x) < 0 {
+			if v&16 == 0 {
+				t.Error("key/value not updated together 1")
+			}
+			negcnt++
+			s |= v & 15
+		} else {
+			if v&16 == 16 {
+				t.Error("key/value not updated together 2", k, v)
+			}
+			s |= v
+		}
+		if growflag {
+			// force a hashtable resize
+			for i := 0; i < 100; i++ {
+				m[FloatInt{3.0, i}] = 0
+			}
+			// then change all the entries
+			// to negative zero
+			m[FloatInt{negzero, 0}] = 1 | 16
+			m[FloatInt{negzero, 1}] = 2 | 16
+			m[FloatInt{negzero, 2}] = 4 | 16
+			m[FloatInt{negzero, 3}] = 8 | 16
+			growflag = false
+		}
+	}
+	if s != 15 {
+		t.Error("entry missing", s)
+	}
+	if cnt != 4 {
+		t.Error("wrong number of entries returned by iterator", cnt)
+	}
+	if negcnt != 3 {
+		t.Error("update to negzero missed by iteration", negcnt)
+	}
+}
+
+func TestIterGrowAndDelete(t *testing.T) {
+	m := make(map[int]int, 4)
+	for i := 0; i < 100; i++ {
+		m[i] = i
+	}
+	growflag := true
+	for k := range m {
+		if growflag {
+			// grow the table
+			for i := 100; i < 1000; i++ {
+				m[i] = i
+			}
+			// delete all odd keys
+			for i := 1; i < 1000; i += 2 {
+				delete(m, i)
+			}
+			growflag = false
+		} else {
+			if k&1 == 1 {
+				t.Error("odd value returned")
+			}
+		}
+	}
+}
+
+// make sure old bucket arrays don't get GCd while
+// an iterator is still using them.
+func TestIterGrowWithGC(t *testing.T) {
+	m := make(map[int]int, 4)
+	for i := 0; i < 16; i++ {
+		m[i] = i
+	}
+	growflag := true
+	bitmask := 0
+	for k := range m {
+		if k < 16 {
+			bitmask |= 1 << uint(k)
+		}
+		if growflag {
+			// grow the table
+			for i := 100; i < 1000; i++ {
+				m[i] = i
+			}
+			// trigger a gc
+			runtime.GC()
+			growflag = false
+		}
+	}
+	if bitmask != 1<<16-1 {
+		t.Error("missing key", bitmask)
+	}
+}
+
+func testConcurrentReadsAfterGrowth(t *testing.T, useReflect bool) {
+	if runtime.GOMAXPROCS(-1) == 1 {
+		defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(16))
+	}
+	numLoop := 10
+	numGrowStep := 250
+	numReader := 16
+	if testing.Short() {
+		numLoop, numGrowStep = 2, 500
+	}
+	for i := 0; i < numLoop; i++ {
+		m := make(map[int]int, 0)
+		for gs := 0; gs < numGrowStep; gs++ {
+			m[gs] = gs
+			var wg sync.WaitGroup
+			wg.Add(numReader * 2)
+			for nr := 0; nr < numReader; nr++ {
+				go func() {
+					defer wg.Done()
+					for range m {
+					}
+				}()
+				go func() {
+					defer wg.Done()
+					for key := 0; key < gs; key++ {
+						_ = m[key]
+					}
+				}()
+				if useReflect {
+					wg.Add(1)
+					go func() {
+						defer wg.Done()
+						mv := reflect.ValueOf(m)
+						keys := mv.MapKeys()
+						for _, k := range keys {
+							mv.MapIndex(k)
+						}
+					}()
+				}
+			}
+			wg.Wait()
+		}
+	}
+}
+
+func TestConcurrentReadsAfterGrowth(t *testing.T) {
+	testConcurrentReadsAfterGrowth(t, false)
+}
+
+func TestConcurrentReadsAfterGrowthReflect(t *testing.T) {
+	testConcurrentReadsAfterGrowth(t, true)
+}
+
+func TestBigItems(t *testing.T) {
+	var key [256]string
+	for i := 0; i < 256; i++ {
+		key[i] = "foo"
+	}
+	m := make(map[[256]string][256]string, 4)
+	for i := 0; i < 100; i++ {
+		key[37] = fmt.Sprintf("string%02d", i)
+		m[key] = key
+	}
+	var keys [100]string
+	var values [100]string
+	i := 0
+	for k, v := range m {
+		keys[i] = k[37]
+		values[i] = v[37]
+		i++
+	}
+	sort.Strings(keys[:])
+	sort.Strings(values[:])
+	for i := 0; i < 100; i++ {
+		if keys[i] != fmt.Sprintf("string%02d", i) {
+			t.Errorf("#%d: missing key: %v", i, keys[i])
+		}
+		if values[i] != fmt.Sprintf("string%02d", i) {
+			t.Errorf("#%d: missing value: %v", i, values[i])
+		}
+	}
+}
+
+type empty struct {
+}
+
+func TestEmptyKeyAndValue(t *testing.T) {
+	a := make(map[int]empty, 4)
+	b := make(map[empty]int, 4)
+	c := make(map[empty]empty, 4)
+	a[0] = empty{}
+	b[empty{}] = 0
+	b[empty{}] = 1
+	c[empty{}] = empty{}
+
+	if len(a) != 1 {
+		t.Errorf("empty value insert problem")
+	}
+	if b[empty{}] != 1 {
+		t.Errorf("empty key returned wrong value")
+	}
+}
+
+// Tests a map with a single bucket, with same-lengthed short keys
+// ("quick keys") as well as long keys.
+func TestSingleBucketMapStringKeys_DupLen(t *testing.T) {
+	testMapLookups(t, map[string]string{
+		"x":    "x1val",
+		"xx":   "x2val",
+		"foo":  "fooval",
+		"bar":  "barval", // same key length as "foo"
+		"xxxx": "x4val",
+		strings.Repeat("x", 128): "longval1",
+		strings.Repeat("y", 128): "longval2",
+	})
+}
+
+// Tests a map with a single bucket, with all keys having different lengths.
+func TestSingleBucketMapStringKeys_NoDupLen(t *testing.T) {
+	testMapLookups(t, map[string]string{
+		"x":                      "x1val",
+		"xx":                     "x2val",
+		"foo":                    "fooval",
+		"xxxx":                   "x4val",
+		"xxxxx":                  "x5val",
+		"xxxxxx":                 "x6val",
+		strings.Repeat("x", 128): "longval",
+	})
+}
+
+func testMapLookups(t *testing.T, m map[string]string) {
+	for k, v := range m {
+		if m[k] != v {
+			t.Fatalf("m[%q] = %q; want %q", k, m[k], v)
+		}
+	}
+}
+
+// Tests whether the iterator returns the right elements when
+// started in the middle of a grow, when the keys are NaNs.
+func TestMapNanGrowIterator(t *testing.T) {
+	m := make(map[float64]int)
+	nan := math.NaN()
+	const nBuckets = 16
+	// To fill nBuckets buckets takes LOAD * nBuckets keys.
+	nKeys := int(nBuckets * *runtime.HashLoad)
+
+	// Get map to full point with nan keys.
+	for i := 0; i < nKeys; i++ {
+		m[nan] = i
+	}
+	// Trigger grow
+	m[1.0] = 1
+	delete(m, 1.0)
+
+	// Run iterator
+	found := make(map[int]struct{})
+	for _, v := range m {
+		if v != -1 {
+			if _, repeat := found[v]; repeat {
+				t.Fatalf("repeat of value %d", v)
+			}
+			found[v] = struct{}{}
+		}
+		if len(found) == nKeys/2 {
+			// Halfway through iteration, finish grow.
+			for i := 0; i < nBuckets; i++ {
+				delete(m, 1.0)
+			}
+		}
+	}
+	if len(found) != nKeys {
+		t.Fatalf("missing value")
+	}
+}
+
+func TestMapIterOrder(t *testing.T) {
+	for _, n := range [...]int{3, 7, 9, 15} {
+		for i := 0; i < 1000; i++ {
+			// Make m be {0: true, 1: true, ..., n-1: true}.
+			m := make(map[int]bool)
+			for i := 0; i < n; i++ {
+				m[i] = true
+			}
+			// Check that iterating over the map produces at least two different orderings.
+			ord := func() []int {
+				var s []int
+				for key := range m {
+					s = append(s, key)
+				}
+				return s
+			}
+			first := ord()
+			ok := false
+			for try := 0; try < 100; try++ {
+				if !reflect.DeepEqual(first, ord()) {
+					ok = true
+					break
+				}
+			}
+			if !ok {
+				t.Errorf("Map with n=%d elements had consistent iteration order: %v", n, first)
+				break
+			}
+		}
+	}
+}
+
+// Issue 8410
+func TestMapSparseIterOrder(t *testing.T) {
+	// Run several rounds to increase the probability
+	// of failure. One is not enough.
+NextRound:
+	for round := 0; round < 10; round++ {
+		m := make(map[int]bool)
+		// Add 1000 items, remove 980.
+		for i := 0; i < 1000; i++ {
+			m[i] = true
+		}
+		for i := 20; i < 1000; i++ {
+			delete(m, i)
+		}
+
+		var first []int
+		for i := range m {
+			first = append(first, i)
+		}
+
+		// 800 chances to get a different iteration order.
+		// See bug 8736 for why we need so many tries.
+		for n := 0; n < 800; n++ {
+			idx := 0
+			for i := range m {
+				if i != first[idx] {
+					// iteration order changed.
+					continue NextRound
+				}
+				idx++
+			}
+		}
+		t.Fatalf("constant iteration order on round %d: %v", round, first)
+	}
+}
+
+func TestMapStringBytesLookup(t *testing.T) {
+	// Use large string keys to avoid small-allocation coalescing,
+	// which can cause AllocsPerRun to report lower counts than it should.
+	m := map[string]int{
+		"1000000000000000000000000000000000000000000000000": 1,
+		"2000000000000000000000000000000000000000000000000": 2,
+	}
+	buf := []byte("1000000000000000000000000000000000000000000000000")
+	if x := m[string(buf)]; x != 1 {
+		t.Errorf(`m[string([]byte("1"))] = %d, want 1`, x)
+	}
+	buf[0] = '2'
+	if x := m[string(buf)]; x != 2 {
+		t.Errorf(`m[string([]byte("2"))] = %d, want 2`, x)
+	}
+
+	var x int
+	n := testing.AllocsPerRun(100, func() {
+		x += m[string(buf)]
+	})
+	if n != 0 {
+		t.Errorf("AllocsPerRun for m[string(buf)] = %v, want 0", n)
+	}
+
+	x = 0
+	n = testing.AllocsPerRun(100, func() {
+		y, ok := m[string(buf)]
+		if !ok {
+			panic("!ok")
+		}
+		x += y
+	})
+	if n != 0 {
+		t.Errorf("AllocsPerRun for x,ok = m[string(buf)] = %v, want 0", n)
+	}
+}
+
+func benchmarkMapPop(b *testing.B, n int) {
+	m := map[int]int{}
+	for i := 0; i < b.N; i++ {
+		for j := 0; j < n; j++ {
+			m[j] = j
+		}
+		for j := 0; j < n; j++ {
+			// Use iterator to pop an element.
+			// We want this to be fast, see issue 8412.
+			for k := range m {
+				delete(m, k)
+				break
+			}
+		}
+	}
+}
+
+func BenchmarkMapPop100(b *testing.B)   { benchmarkMapPop(b, 100) }
+func BenchmarkMapPop1000(b *testing.B)  { benchmarkMapPop(b, 1000) }
+func BenchmarkMapPop10000(b *testing.B) { benchmarkMapPop(b, 10000) }
diff --git a/src/runtime/mapspeed_test.go b/src/runtime/mapspeed_test.go
new file mode 100644
index 0000000..119eb3f
--- /dev/null
+++ b/src/runtime/mapspeed_test.go
@@ -0,0 +1,300 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+package runtime_test
+
+import (
+	"fmt"
+	"strings"
+	"testing"
+)
+
+const size = 10
+
+func BenchmarkHashStringSpeed(b *testing.B) {
+	strings := make([]string, size)
+	for i := 0; i < size; i++ {
+		strings[i] = fmt.Sprintf("string#%d", i)
+	}
+	sum := 0
+	m := make(map[string]int, size)
+	for i := 0; i < size; i++ {
+		m[strings[i]] = 0
+	}
+	idx := 0
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		sum += m[strings[idx]]
+		idx++
+		if idx == size {
+			idx = 0
+		}
+	}
+}
+
+type chunk [17]byte
+
+func BenchmarkHashBytesSpeed(b *testing.B) {
+	// a bunch of chunks, each with a different alignment mod 16
+	var chunks [size]chunk
+	// initialize each to a different value
+	for i := 0; i < size; i++ {
+		chunks[i][0] = byte(i)
+	}
+	// put into a map
+	m := make(map[chunk]int, size)
+	for i, c := range chunks {
+		m[c] = i
+	}
+	idx := 0
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		if m[chunks[idx]] != idx {
+			b.Error("bad map entry for chunk")
+		}
+		idx++
+		if idx == size {
+			idx = 0
+		}
+	}
+}
+
+func BenchmarkHashInt32Speed(b *testing.B) {
+	ints := make([]int32, size)
+	for i := 0; i < size; i++ {
+		ints[i] = int32(i)
+	}
+	sum := 0
+	m := make(map[int32]int, size)
+	for i := 0; i < size; i++ {
+		m[ints[i]] = 0
+	}
+	idx := 0
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		sum += m[ints[idx]]
+		idx++
+		if idx == size {
+			idx = 0
+		}
+	}
+}
+
+func BenchmarkHashInt64Speed(b *testing.B) {
+	ints := make([]int64, size)
+	for i := 0; i < size; i++ {
+		ints[i] = int64(i)
+	}
+	sum := 0
+	m := make(map[int64]int, size)
+	for i := 0; i < size; i++ {
+		m[ints[i]] = 0
+	}
+	idx := 0
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		sum += m[ints[idx]]
+		idx++
+		if idx == size {
+			idx = 0
+		}
+	}
+}
+func BenchmarkHashStringArraySpeed(b *testing.B) {
+	stringpairs := make([][2]string, size)
+	for i := 0; i < size; i++ {
+		for j := 0; j < 2; j++ {
+			stringpairs[i][j] = fmt.Sprintf("string#%d/%d", i, j)
+		}
+	}
+	sum := 0
+	m := make(map[[2]string]int, size)
+	for i := 0; i < size; i++ {
+		m[stringpairs[i]] = 0
+	}
+	idx := 0
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		sum += m[stringpairs[idx]]
+		idx++
+		if idx == size {
+			idx = 0
+		}
+	}
+}
+
+func BenchmarkMegMap(b *testing.B) {
+	m := make(map[string]bool)
+	for suffix := 'A'; suffix <= 'G'; suffix++ {
+		m[strings.Repeat("X", 1<<20-1)+fmt.Sprint(suffix)] = true
+	}
+	key := strings.Repeat("X", 1<<20-1) + "k"
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		_, _ = m[key]
+	}
+}
+
+func BenchmarkMegOneMap(b *testing.B) {
+	m := make(map[string]bool)
+	m[strings.Repeat("X", 1<<20)] = true
+	key := strings.Repeat("Y", 1<<20)
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		_, _ = m[key]
+	}
+}
+
+func BenchmarkMegEqMap(b *testing.B) {
+	m := make(map[string]bool)
+	key1 := strings.Repeat("X", 1<<20)
+	key2 := strings.Repeat("X", 1<<20) // equal but different instance
+	m[key1] = true
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		_, _ = m[key2]
+	}
+}
+
+func BenchmarkMegEmptyMap(b *testing.B) {
+	m := make(map[string]bool)
+	key := strings.Repeat("X", 1<<20)
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		_, _ = m[key]
+	}
+}
+
+func BenchmarkSmallStrMap(b *testing.B) {
+	m := make(map[string]bool)
+	for suffix := 'A'; suffix <= 'G'; suffix++ {
+		m[fmt.Sprint(suffix)] = true
+	}
+	key := "k"
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		_, _ = m[key]
+	}
+}
+
+func BenchmarkMapStringKeysEight_16(b *testing.B) { benchmarkMapStringKeysEight(b, 16) }
+func BenchmarkMapStringKeysEight_32(b *testing.B) { benchmarkMapStringKeysEight(b, 32) }
+func BenchmarkMapStringKeysEight_64(b *testing.B) { benchmarkMapStringKeysEight(b, 64) }
+func BenchmarkMapStringKeysEight_1M(b *testing.B) { benchmarkMapStringKeysEight(b, 1<<20) }
+
+func benchmarkMapStringKeysEight(b *testing.B, keySize int) {
+	m := make(map[string]bool)
+	for i := 0; i < 8; i++ {
+		m[strings.Repeat("K", i+1)] = true
+	}
+	key := strings.Repeat("K", keySize)
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		_ = m[key]
+	}
+}
+
+func BenchmarkIntMap(b *testing.B) {
+	m := make(map[int]bool)
+	for i := 0; i < 8; i++ {
+		m[i] = true
+	}
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		_, _ = m[7]
+	}
+}
+
+// Accessing the same keys in a row.
+func benchmarkRepeatedLookup(b *testing.B, lookupKeySize int) {
+	m := make(map[string]bool)
+	// At least bigger than a single bucket:
+	for i := 0; i < 64; i++ {
+		m[fmt.Sprintf("some key %d", i)] = true
+	}
+	base := strings.Repeat("x", lookupKeySize-1)
+	key1 := base + "1"
+	key2 := base + "2"
+	b.ResetTimer()
+	for i := 0; i < b.N/4; i++ {
+		_ = m[key1]
+		_ = m[key1]
+		_ = m[key2]
+		_ = m[key2]
+	}
+}
+
+func BenchmarkRepeatedLookupStrMapKey32(b *testing.B) { benchmarkRepeatedLookup(b, 32) }
+func BenchmarkRepeatedLookupStrMapKey1M(b *testing.B) { benchmarkRepeatedLookup(b, 1<<20) }
+
+func BenchmarkNewEmptyMap(b *testing.B) {
+	b.ReportAllocs()
+	for i := 0; i < b.N; i++ {
+		_ = make(map[int]int)
+	}
+}
+
+func BenchmarkMapIter(b *testing.B) {
+	m := make(map[int]bool)
+	for i := 0; i < 8; i++ {
+		m[i] = true
+	}
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		for range m {
+		}
+	}
+}
+
+func BenchmarkMapIterEmpty(b *testing.B) {
+	m := make(map[int]bool)
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		for range m {
+		}
+	}
+}
+
+func BenchmarkSameLengthMap(b *testing.B) {
+	// long strings, same length, differ in first few
+	// and last few bytes.
+	m := make(map[string]bool)
+	s1 := "foo" + strings.Repeat("-", 100) + "bar"
+	s2 := "goo" + strings.Repeat("-", 100) + "ber"
+	m[s1] = true
+	m[s2] = true
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		_ = m[s1]
+	}
+}
+
+type BigKey [3]int64
+
+func BenchmarkBigKeyMap(b *testing.B) {
+	m := make(map[BigKey]bool)
+	k := BigKey{3, 4, 5}
+	m[k] = true
+	for i := 0; i < b.N; i++ {
+		_ = m[k]
+	}
+}
+
+type BigVal [3]int64
+
+func BenchmarkBigValMap(b *testing.B) {
+	m := make(map[BigKey]BigVal)
+	k := BigKey{3, 4, 5}
+	m[k] = BigVal{6, 7, 8}
+	for i := 0; i < b.N; i++ {
+		_ = m[k]
+	}
+}
+
+func BenchmarkSmallKeyMap(b *testing.B) {
+	m := make(map[int16]bool)
+	m[5] = true
+	for i := 0; i < b.N; i++ {
+		_ = m[5]
+	}
+}
diff --git a/src/runtime/mcache.c b/src/runtime/mcache.c
new file mode 100644
index 0000000..5fdbe32
--- /dev/null
+++ b/src/runtime/mcache.c
@@ -0,0 +1,115 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Per-P malloc cache for small objects.
+//
+// See malloc.h for an overview.
+
+#include "runtime.h"
+#include "arch_GOARCH.h"
+#include "malloc.h"
+
+extern volatile intgo runtime·MemProfileRate;
+
+// dummy MSpan that contains no free objects.
+MSpan runtime·emptymspan;
+
+MCache*
+runtime·allocmcache(void)
+{
+	intgo rate;
+	MCache *c;
+	int32 i;
+
+	runtime·lock(&runtime·mheap.lock);
+	c = runtime·FixAlloc_Alloc(&runtime·mheap.cachealloc);
+	runtime·unlock(&runtime·mheap.lock);
+	runtime·memclr((byte*)c, sizeof(*c));
+	for(i = 0; i < NumSizeClasses; i++)
+		c->alloc[i] = &runtime·emptymspan;
+
+	// Set first allocation sample size.
+	rate = runtime·MemProfileRate;
+	if(rate > 0x3fffffff)	// make 2*rate not overflow
+		rate = 0x3fffffff;
+	if(rate != 0)
+		c->next_sample = runtime·fastrand1() % (2*rate);
+
+	return c;
+}
+
+static void
+freemcache(MCache *c)
+{
+	runtime·MCache_ReleaseAll(c);
+	runtime·stackcache_clear(c);
+	runtime·gcworkbuffree(c->gcworkbuf);
+	runtime·lock(&runtime·mheap.lock);
+	runtime·purgecachedstats(c);
+	runtime·FixAlloc_Free(&runtime·mheap.cachealloc, c);
+	runtime·unlock(&runtime·mheap.lock);
+}
+
+static void
+freemcache_m(void)
+{
+	MCache *c;
+
+	c = g->m->ptrarg[0];
+	g->m->ptrarg[0] = nil;
+	freemcache(c);
+}
+
+void
+runtime·freemcache(MCache *c)
+{
+	void (*fn)(void);
+
+	g->m->ptrarg[0] = c;
+	fn = freemcache_m;
+	runtime·onM(&fn);
+}
+
+// Gets a span that has a free object in it and assigns it
+// to be the cached span for the given sizeclass.  Returns this span.
+MSpan*
+runtime·MCache_Refill(MCache *c, int32 sizeclass)
+{
+	MSpan *s;
+
+	g->m->locks++;
+	// Return the current cached span to the central lists.
+	s = c->alloc[sizeclass];
+	if(s->freelist != nil)
+		runtime·throw("refill on a nonempty span");
+	if(s != &runtime·emptymspan)
+		s->incache = false;
+
+	// Get a new cached span from the central lists.
+	s = runtime·MCentral_CacheSpan(&runtime·mheap.central[sizeclass].mcentral);
+	if(s == nil)
+		runtime·throw("out of memory");
+	if(s->freelist == nil) {
+		runtime·printf("%d %d\n", s->ref, (int32)((s->npages << PageShift) / s->elemsize));
+		runtime·throw("empty span");
+	}
+	c->alloc[sizeclass] = s;
+	g->m->locks--;
+	return s;
+}
+
+void
+runtime·MCache_ReleaseAll(MCache *c)
+{
+	int32 i;
+	MSpan *s;
+
+	for(i=0; i<NumSizeClasses; i++) {
+		s = c->alloc[i];
+		if(s != &runtime·emptymspan) {
+			runtime·MCentral_UncacheSpan(&runtime·mheap.central[i].mcentral, s);
+			c->alloc[i] = &runtime·emptymspan;
+		}
+	}
+}
diff --git a/src/runtime/mcentral.c b/src/runtime/mcentral.c
new file mode 100644
index 0000000..fe6bcfe
--- /dev/null
+++ b/src/runtime/mcentral.c
@@ -0,0 +1,214 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Central free lists.
+//
+// See malloc.h for an overview.
+//
+// The MCentral doesn't actually contain the list of free objects; the MSpan does.
+// Each MCentral is two lists of MSpans: those with free objects (c->nonempty)
+// and those that are completely allocated (c->empty).
+
+#include "runtime.h"
+#include "arch_GOARCH.h"
+#include "malloc.h"
+
+static MSpan* MCentral_Grow(MCentral *c);
+
+// Initialize a single central free list.
+void
+runtime·MCentral_Init(MCentral *c, int32 sizeclass)
+{
+	c->sizeclass = sizeclass;
+	runtime·MSpanList_Init(&c->nonempty);
+	runtime·MSpanList_Init(&c->empty);
+}
+
+// Allocate a span to use in an MCache.
+MSpan*
+runtime·MCentral_CacheSpan(MCentral *c)
+{
+	MSpan *s;
+	int32 cap, n;
+	uint32 sg;
+
+	runtime·lock(&c->lock);
+	sg = runtime·mheap.sweepgen;
+retry:
+	for(s = c->nonempty.next; s != &c->nonempty; s = s->next) {
+		if(s->sweepgen == sg-2 && runtime·cas(&s->sweepgen, sg-2, sg-1)) {
+			runtime·MSpanList_Remove(s);
+			runtime·MSpanList_InsertBack(&c->empty, s);
+			runtime·unlock(&c->lock);
+			runtime·MSpan_Sweep(s, true);
+			goto havespan;
+		}
+		if(s->sweepgen == sg-1) {
+			// the span is being swept by background sweeper, skip
+			continue;
+		}
+		// we have a nonempty span that does not require sweeping, allocate from it
+		runtime·MSpanList_Remove(s);
+		runtime·MSpanList_InsertBack(&c->empty, s);
+		runtime·unlock(&c->lock);
+		goto havespan;
+	}
+
+	for(s = c->empty.next; s != &c->empty; s = s->next) {
+		if(s->sweepgen == sg-2 && runtime·cas(&s->sweepgen, sg-2, sg-1)) {
+			// we have an empty span that requires sweeping,
+			// sweep it and see if we can free some space in it
+			runtime·MSpanList_Remove(s);
+			// swept spans are at the end of the list
+			runtime·MSpanList_InsertBack(&c->empty, s);
+			runtime·unlock(&c->lock);
+			runtime·MSpan_Sweep(s, true);
+			if(s->freelist != nil)
+				goto havespan;
+			runtime·lock(&c->lock);
+			// the span is still empty after sweep
+			// it is already in the empty list, so just retry
+			goto retry;
+		}
+		if(s->sweepgen == sg-1) {
+			// the span is being swept by background sweeper, skip
+			continue;
+		}
+		// already swept empty span,
+		// all subsequent ones must also be either swept or in process of sweeping
+		break;
+	}
+	runtime·unlock(&c->lock);
+
+	// Replenish central list if empty.
+	s = MCentral_Grow(c);
+	if(s == nil)
+		return nil;
+	runtime·lock(&c->lock);
+	runtime·MSpanList_InsertBack(&c->empty, s);
+	runtime·unlock(&c->lock);
+
+havespan:
+	// At this point s is a non-empty span, queued at the end of the empty list,
+	// c is unlocked.
+	cap = (s->npages << PageShift) / s->elemsize;
+	n = cap - s->ref;
+	if(n == 0)
+		runtime·throw("empty span");
+	if(s->freelist == nil)
+		runtime·throw("freelist empty");
+	s->incache = true;
+	return s;
+}
+
+// Return span from an MCache.
+void
+runtime·MCentral_UncacheSpan(MCentral *c, MSpan *s)
+{
+	int32 cap, n;
+
+	runtime·lock(&c->lock);
+
+	s->incache = false;
+
+	if(s->ref == 0)
+		runtime·throw("uncaching full span");
+
+	cap = (s->npages << PageShift) / s->elemsize;
+	n = cap - s->ref;
+	if(n > 0) {
+		runtime·MSpanList_Remove(s);
+		runtime·MSpanList_Insert(&c->nonempty, s);
+	}
+	runtime·unlock(&c->lock);
+}
+
+// Free n objects from a span s back into the central free list c.
+// Called during sweep.
+// Returns true if the span was returned to heap.  Sets sweepgen to
+// the latest generation.
+// If preserve=true, don't return the span to heap nor relink in MCentral lists;
+// caller takes care of it.
+bool
+runtime·MCentral_FreeSpan(MCentral *c, MSpan *s, int32 n, MLink *start, MLink *end, bool preserve)
+{
+	bool wasempty;
+
+	if(s->incache)
+		runtime·throw("freespan into cached span");
+
+	// Add the objects back to s's free list.
+	wasempty = s->freelist == nil;
+	end->next = s->freelist;
+	s->freelist = start;
+	s->ref -= n;
+
+	if(preserve) {
+		// preserve is set only when called from MCentral_CacheSpan above,
+		// the span must be in the empty list.
+		if(s->next == nil)
+			runtime·throw("can't preserve unlinked span");
+		runtime·atomicstore(&s->sweepgen, runtime·mheap.sweepgen);
+		return false;
+	}
+
+	runtime·lock(&c->lock);
+
+	// Move to nonempty if necessary.
+	if(wasempty) {
+		runtime·MSpanList_Remove(s);
+		runtime·MSpanList_Insert(&c->nonempty, s);
+	}
+
+	// delay updating sweepgen until here.  This is the signal that
+	// the span may be used in an MCache, so it must come after the
+	// linked list operations above (actually, just after the
+	// lock of c above.)
+	runtime·atomicstore(&s->sweepgen, runtime·mheap.sweepgen);
+
+	if(s->ref != 0) {
+		runtime·unlock(&c->lock);
+		return false;
+	}
+
+	// s is completely freed, return it to the heap.
+	runtime·MSpanList_Remove(s);
+	s->needzero = 1;
+	s->freelist = nil;
+	runtime·unlock(&c->lock);
+	runtime·unmarkspan((byte*)(s->start<<PageShift), s->npages<<PageShift);
+	runtime·MHeap_Free(&runtime·mheap, s, 0);
+	return true;
+}
+
+// Fetch a new span from the heap and carve into objects for the free list.
+static MSpan*
+MCentral_Grow(MCentral *c)
+{
+	uintptr size, npages, i, n;
+	MLink **tailp, *v;
+	byte *p;
+	MSpan *s;
+
+	npages = runtime·class_to_allocnpages[c->sizeclass];
+	size = runtime·class_to_size[c->sizeclass];
+	n = (npages << PageShift) / size;
+	s = runtime·MHeap_Alloc(&runtime·mheap, npages, c->sizeclass, 0, 1);
+	if(s == nil)
+		return nil;
+
+	// Carve span into sequence of blocks.
+	tailp = &s->freelist;
+	p = (byte*)(s->start << PageShift);
+	s->limit = p + size*n;
+	for(i=0; i<n; i++) {
+		v = (MLink*)p;
+		*tailp = v;
+		tailp = &v->next;
+		p += size;
+	}
+	*tailp = nil;
+	runtime·markspan((byte*)(s->start<<PageShift), size, n, size*n < (s->npages<<PageShift));
+	return s;
+}
diff --git a/src/runtime/mem.go b/src/runtime/mem.go
new file mode 100644
index 0000000..e6f1eb0
--- /dev/null
+++ b/src/runtime/mem.go
@@ -0,0 +1,108 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package runtime
+
+import "unsafe"
+
+// Note: the MemStats struct should be kept in sync with
+// struct MStats in malloc.h
+
+// A MemStats records statistics about the memory allocator.
+type MemStats struct {
+	// General statistics.
+	Alloc      uint64 // bytes allocated and still in use
+	TotalAlloc uint64 // bytes allocated (even if freed)
+	Sys        uint64 // bytes obtained from system (sum of XxxSys below)
+	Lookups    uint64 // number of pointer lookups
+	Mallocs    uint64 // number of mallocs
+	Frees      uint64 // number of frees
+
+	// Main allocation heap statistics.
+	HeapAlloc    uint64 // bytes allocated and still in use
+	HeapSys      uint64 // bytes obtained from system
+	HeapIdle     uint64 // bytes in idle spans
+	HeapInuse    uint64 // bytes in non-idle span
+	HeapReleased uint64 // bytes released to the OS
+	HeapObjects  uint64 // total number of allocated objects
+
+	// Low-level fixed-size structure allocator statistics.
+	//	Inuse is bytes used now.
+	//	Sys is bytes obtained from system.
+	StackInuse  uint64 // bytes used by stack allocator
+	StackSys    uint64
+	MSpanInuse  uint64 // mspan structures
+	MSpanSys    uint64
+	MCacheInuse uint64 // mcache structures
+	MCacheSys   uint64
+	BuckHashSys uint64 // profiling bucket hash table
+	GCSys       uint64 // GC metadata
+	OtherSys    uint64 // other system allocations
+
+	// Garbage collector statistics.
+	NextGC       uint64 // next collection will happen when HeapAlloc ≥ this amount
+	LastGC       uint64 // end time of last collection (nanoseconds since 1970)
+	PauseTotalNs uint64
+	PauseNs      [256]uint64 // circular buffer of recent GC pause durations, most recent at [(NumGC+255)%256]
+	PauseEnd     [256]uint64 // circular buffer of recent GC pause end times
+	NumGC        uint32
+	EnableGC     bool
+	DebugGC      bool
+
+	// Per-size allocation statistics.
+	// 61 is NumSizeClasses in the C code.
+	BySize [61]struct {
+		Size    uint32
+		Mallocs uint64
+		Frees   uint64
+	}
+}
+
+var sizeof_C_MStats uintptr // filled in by malloc.goc
+
+func init() {
+	var memStats MemStats
+	if sizeof_C_MStats != unsafe.Sizeof(memStats) {
+		println(sizeof_C_MStats, unsafe.Sizeof(memStats))
+		gothrow("MStats vs MemStatsType size mismatch")
+	}
+}
+
+// ReadMemStats populates m with memory allocator statistics.
+func ReadMemStats(m *MemStats) {
+	// Have to acquire worldsema to stop the world,
+	// because stoptheworld can only be used by
+	// one goroutine at a time, and there might be
+	// a pending garbage collection already calling it.
+	semacquire(&worldsema, false)
+	gp := getg()
+	gp.m.gcing = 1
+	onM(stoptheworld)
+
+	gp.m.ptrarg[0] = noescape(unsafe.Pointer(m))
+	onM(readmemstats_m)
+
+	gp.m.gcing = 0
+	gp.m.locks++
+	semrelease(&worldsema)
+	onM(starttheworld)
+	gp.m.locks--
+}
+
+// Implementation of runtime/debug.WriteHeapDump
+func writeHeapDump(fd uintptr) {
+	semacquire(&worldsema, false)
+	gp := getg()
+	gp.m.gcing = 1
+	onM(stoptheworld)
+
+	gp.m.scalararg[0] = fd
+	onM(writeheapdump_m)
+
+	gp.m.gcing = 0
+	gp.m.locks++
+	semrelease(&worldsema)
+	onM(starttheworld)
+	gp.m.locks--
+}
diff --git a/src/runtime/mem_darwin.c b/src/runtime/mem_darwin.c
new file mode 100644
index 0000000..bf3ede5
--- /dev/null
+++ b/src/runtime/mem_darwin.c
@@ -0,0 +1,82 @@
+// Copyright 2010 The Go 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 "runtime.h"
+#include "arch_GOARCH.h"
+#include "defs_GOOS_GOARCH.h"
+#include "os_GOOS.h"
+#include "malloc.h"
+#include "textflag.h"
+
+#pragma textflag NOSPLIT
+void*
+runtime·sysAlloc(uintptr n, uint64 *stat)
+{
+	void *v;
+
+	v = runtime·mmap(nil, n, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0);
+	if(v < (void*)4096)
+		return nil;
+	runtime·xadd64(stat, n);
+	return v;
+}
+
+void
+runtime·SysUnused(void *v, uintptr n)
+{
+	// Linux's MADV_DONTNEED is like BSD's MADV_FREE.
+	runtime·madvise(v, n, MADV_FREE);
+}
+
+void
+runtime·SysUsed(void *v, uintptr n)
+{
+	USED(v);
+	USED(n);
+}
+
+void
+runtime·SysFree(void *v, uintptr n, uint64 *stat)
+{
+	runtime·xadd64(stat, -(uint64)n);
+	runtime·munmap(v, n);
+}
+
+void
+runtime·SysFault(void *v, uintptr n)
+{
+	runtime·mmap(v, n, PROT_NONE, MAP_ANON|MAP_PRIVATE|MAP_FIXED, -1, 0);
+}
+
+void*
+runtime·SysReserve(void *v, uintptr n, bool *reserved)
+{
+	void *p;
+
+	*reserved = true;
+	p = runtime·mmap(v, n, PROT_NONE, MAP_ANON|MAP_PRIVATE, -1, 0);
+	if(p < (void*)4096)
+		return nil;
+	return p;
+}
+
+enum
+{
+	ENOMEM = 12,
+};
+
+void
+runtime·SysMap(void *v, uintptr n, bool reserved, uint64 *stat)
+{
+	void *p;
+	
+	USED(reserved);
+
+	runtime·xadd64(stat, n);
+	p = runtime·mmap(v, n, PROT_READ|PROT_WRITE, MAP_ANON|MAP_FIXED|MAP_PRIVATE, -1, 0);
+	if(p == (void*)ENOMEM)
+		runtime·throw("runtime: out of memory");
+	if(p != v)
+		runtime·throw("runtime: cannot map pages in arena address space");
+}
diff --git a/src/runtime/mem_dragonfly.c b/src/runtime/mem_dragonfly.c
new file mode 100644
index 0000000..11457b2
--- /dev/null
+++ b/src/runtime/mem_dragonfly.c
@@ -0,0 +1,105 @@
+// Copyright 2010 The Go 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 "runtime.h"
+#include "arch_GOARCH.h"
+#include "defs_GOOS_GOARCH.h"
+#include "os_GOOS.h"
+#include "malloc.h"
+#include "textflag.h"
+
+enum
+{
+	ENOMEM = 12,
+};
+
+#pragma textflag NOSPLIT
+void*
+runtime·sysAlloc(uintptr n, uint64 *stat)
+{
+	void *v;
+
+	v = runtime·mmap(nil, n, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0);
+	if(v < (void*)4096)
+		return nil;
+	runtime·xadd64(stat, n);
+	return v;
+}
+
+void
+runtime·SysUnused(void *v, uintptr n)
+{
+	runtime·madvise(v, n, MADV_FREE);
+}
+
+void
+runtime·SysUsed(void *v, uintptr n)
+{
+	USED(v);
+	USED(n);
+}
+
+void
+runtime·SysFree(void *v, uintptr n, uint64 *stat)
+{
+	runtime·xadd64(stat, -(uint64)n);
+	runtime·munmap(v, n);
+}
+
+void
+runtime·SysFault(void *v, uintptr n)
+{
+	runtime·mmap(v, n, PROT_NONE, MAP_ANON|MAP_PRIVATE|MAP_FIXED, -1, 0);
+}
+
+void*
+runtime·SysReserve(void *v, uintptr n, bool *reserved)
+{
+	void *p;
+
+	// On 64-bit, people with ulimit -v set complain if we reserve too
+	// much address space.  Instead, assume that the reservation is okay
+	// and check the assumption in SysMap.
+	if(sizeof(void*) == 8 && n > 1LL<<32) {
+		*reserved = false;
+		return v;
+	}
+
+	*reserved = true;
+	p = runtime·mmap(v, n, PROT_NONE, MAP_ANON|MAP_PRIVATE, -1, 0);
+	if(p < (void*)4096)
+		return nil;
+	return p;
+}
+
+void
+runtime·SysMap(void *v, uintptr n, bool reserved, uint64 *stat)
+{
+	void *p;
+	
+	runtime·xadd64(stat, n);
+
+	// On 64-bit, we don't actually have v reserved, so tread carefully.
+	if(!reserved) {
+		// TODO(jsing): For some reason DragonFly seems to return
+		// memory at a different address than we requested, even when
+		// there should be no reason for it to do so. This can be
+		// avoided by using MAP_FIXED, but I'm not sure we should need
+		// to do this - we do not on other platforms.
+		p = runtime·mmap(v, n, PROT_READ|PROT_WRITE, MAP_ANON|MAP_FIXED|MAP_PRIVATE, -1, 0);
+		if(p == (void*)ENOMEM)
+			runtime·throw("runtime: out of memory");
+		if(p != v) {
+			runtime·printf("runtime: address space conflict: map(%p) = %p\n", v, p);
+			runtime·throw("runtime: address space conflict");
+		}
+		return;
+	}
+
+	p = runtime·mmap(v, n, PROT_READ|PROT_WRITE, MAP_ANON|MAP_FIXED|MAP_PRIVATE, -1, 0);
+	if(p == (void*)ENOMEM)
+		runtime·throw("runtime: out of memory");
+	if(p != v)
+		runtime·throw("runtime: cannot map pages in arena address space");
+}
diff --git a/src/runtime/mem_freebsd.c b/src/runtime/mem_freebsd.c
new file mode 100644
index 0000000..18a9a2f
--- /dev/null
+++ b/src/runtime/mem_freebsd.c
@@ -0,0 +1,100 @@
+// Copyright 2010 The Go 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 "runtime.h"
+#include "arch_GOARCH.h"
+#include "defs_GOOS_GOARCH.h"
+#include "os_GOOS.h"
+#include "malloc.h"
+#include "textflag.h"
+
+enum
+{
+	ENOMEM = 12,
+};
+
+#pragma textflag NOSPLIT
+void*
+runtime·sysAlloc(uintptr n, uint64 *stat)
+{
+	void *v;
+
+	v = runtime·mmap(nil, n, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0);
+	if(v < (void*)4096)
+		return nil;
+	runtime·xadd64(stat, n);
+	return v;
+}
+
+void
+runtime·SysUnused(void *v, uintptr n)
+{
+	runtime·madvise(v, n, MADV_FREE);
+}
+
+void
+runtime·SysUsed(void *v, uintptr n)
+{
+	USED(v);
+	USED(n);
+}
+
+void
+runtime·SysFree(void *v, uintptr n, uint64 *stat)
+{
+	runtime·xadd64(stat, -(uint64)n);
+	runtime·munmap(v, n);
+}
+
+void
+runtime·SysFault(void *v, uintptr n)
+{
+	runtime·mmap(v, n, PROT_NONE, MAP_ANON|MAP_PRIVATE|MAP_FIXED, -1, 0);
+}
+
+void*
+runtime·SysReserve(void *v, uintptr n, bool *reserved)
+{
+	void *p;
+
+	// On 64-bit, people with ulimit -v set complain if we reserve too
+	// much address space.  Instead, assume that the reservation is okay
+	// and check the assumption in SysMap.
+	if(sizeof(void*) == 8 && n > 1LL<<32) {
+		*reserved = false;
+		return v;
+	}
+
+	*reserved = true;
+	p = runtime·mmap(v, n, PROT_NONE, MAP_ANON|MAP_PRIVATE, -1, 0);
+	if(p < (void*)4096)
+		return nil;
+	return p;
+}
+
+void
+runtime·SysMap(void *v, uintptr n, bool reserved, uint64 *stat)
+{
+	void *p;
+	
+	runtime·xadd64(stat, n);
+
+	// On 64-bit, we don't actually have v reserved, so tread carefully.
+	if(!reserved) {
+		p = runtime·mmap(v, n, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0);
+		if(p == (void*)ENOMEM)
+			runtime·throw("runtime: out of memory");
+		if(p != v) {
+			runtime·printf("runtime: address space conflict: map(%p) = %p\n", v, p);
+			runtime·throw("runtime: address space conflict");
+		}
+		return;
+	}
+
+	p = runtime·mmap(v, n, PROT_READ|PROT_WRITE, MAP_ANON|MAP_FIXED|MAP_PRIVATE, -1, 0);
+	if(p == (void*)ENOMEM)
+		runtime·throw("runtime: out of memory");
+	if(p != v)
+		runtime·throw("runtime: cannot map pages in arena address space");
+}
diff --git a/src/runtime/mem_linux.c b/src/runtime/mem_linux.c
new file mode 100644
index 0000000..bfb4056
--- /dev/null
+++ b/src/runtime/mem_linux.c
@@ -0,0 +1,162 @@
+// Copyright 2010 The Go 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 "runtime.h"
+#include "arch_GOARCH.h"
+#include "defs_GOOS_GOARCH.h"
+#include "os_GOOS.h"
+#include "malloc.h"
+#include "textflag.h"
+
+enum
+{
+	_PAGE_SIZE = 4096,
+	EACCES = 13,
+};
+
+static int32
+addrspace_free(void *v, uintptr n)
+{
+	int32 errval;
+	uintptr chunk;
+	uintptr off;
+	
+	// NOTE: vec must be just 1 byte long here.
+	// Mincore returns ENOMEM if any of the pages are unmapped,
+	// but we want to know that all of the pages are unmapped.
+	// To make these the same, we can only ask about one page
+	// at a time. See golang.org/issue/7476.
+	static byte vec[1];
+
+	for(off = 0; off < n; off += chunk) {
+		chunk = _PAGE_SIZE * sizeof vec;
+		if(chunk > (n - off))
+			chunk = n - off;
+		errval = runtime·mincore((int8*)v + off, chunk, vec);
+		// ENOMEM means unmapped, which is what we want.
+		// Anything else we assume means the pages are mapped.
+		if (errval != -ENOMEM)
+			return 0;
+	}
+	return 1;
+}
+
+static void *
+mmap_fixed(byte *v, uintptr n, int32 prot, int32 flags, int32 fd, uint32 offset)
+{
+	void *p;
+
+	p = runtime·mmap(v, n, prot, flags, fd, offset);
+	if(p != v && addrspace_free(v, n)) {
+		// On some systems, mmap ignores v without
+		// MAP_FIXED, so retry if the address space is free.
+		if(p > (void*)4096)
+			runtime·munmap(p, n);
+		p = runtime·mmap(v, n, prot, flags|MAP_FIXED, fd, offset);
+	}
+	return p;
+}
+
+#pragma textflag NOSPLIT
+void*
+runtime·sysAlloc(uintptr n, uint64 *stat)
+{
+	void *p;
+
+	p = runtime·mmap(nil, n, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0);
+	if(p < (void*)4096) {
+		if(p == (void*)EACCES) {
+			runtime·printf("runtime: mmap: access denied\n");
+			runtime·printf("if you're running SELinux, enable execmem for this process.\n");
+			runtime·exit(2);
+		}
+		if(p == (void*)EAGAIN) {
+			runtime·printf("runtime: mmap: too much locked memory (check 'ulimit -l').\n");
+			runtime·exit(2);
+		}
+		return nil;
+	}
+	runtime·xadd64(stat, n);
+	return p;
+}
+
+void
+runtime·SysUnused(void *v, uintptr n)
+{
+	runtime·madvise(v, n, MADV_DONTNEED);
+}
+
+void
+runtime·SysUsed(void *v, uintptr n)
+{
+	USED(v);
+	USED(n);
+}
+
+void
+runtime·SysFree(void *v, uintptr n, uint64 *stat)
+{
+	runtime·xadd64(stat, -(uint64)n);
+	runtime·munmap(v, n);
+}
+
+void
+runtime·SysFault(void *v, uintptr n)
+{
+	runtime·mmap(v, n, PROT_NONE, MAP_ANON|MAP_PRIVATE|MAP_FIXED, -1, 0);
+}
+
+void*
+runtime·SysReserve(void *v, uintptr n, bool *reserved)
+{
+	void *p;
+
+	// On 64-bit, people with ulimit -v set complain if we reserve too
+	// much address space.  Instead, assume that the reservation is okay
+	// if we can reserve at least 64K and check the assumption in SysMap.
+	// Only user-mode Linux (UML) rejects these requests.
+	if(sizeof(void*) == 8 && n > 1LL<<32) {
+		p = mmap_fixed(v, 64<<10, PROT_NONE, MAP_ANON|MAP_PRIVATE, -1, 0);
+		if (p != v) {
+			if(p >= (void*)4096)
+				runtime·munmap(p, 64<<10);
+			return nil;
+		}
+		runtime·munmap(p, 64<<10);
+		*reserved = false;
+		return v;
+	}
+
+	p = runtime·mmap(v, n, PROT_NONE, MAP_ANON|MAP_PRIVATE, -1, 0);
+	if((uintptr)p < 4096)
+		return nil;
+	*reserved = true;
+	return p;
+}
+
+void
+runtime·SysMap(void *v, uintptr n, bool reserved, uint64 *stat)
+{
+	void *p;
+	
+	runtime·xadd64(stat, n);
+
+	// On 64-bit, we don't actually have v reserved, so tread carefully.
+	if(!reserved) {
+		p = mmap_fixed(v, n, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0);
+		if(p == (void*)ENOMEM)
+			runtime·throw("runtime: out of memory");
+		if(p != v) {
+			runtime·printf("runtime: address space conflict: map(%p) = %p\n", v, p);
+			runtime·throw("runtime: address space conflict");
+		}
+		return;
+	}
+
+	p = runtime·mmap(v, n, PROT_READ|PROT_WRITE, MAP_ANON|MAP_FIXED|MAP_PRIVATE, -1, 0);
+	if(p == (void*)ENOMEM)
+		runtime·throw("runtime: out of memory");
+	if(p != v)
+		runtime·throw("runtime: cannot map pages in arena address space");
+}
diff --git a/src/runtime/mem_nacl.c b/src/runtime/mem_nacl.c
new file mode 100644
index 0000000..6c836f1
--- /dev/null
+++ b/src/runtime/mem_nacl.c
@@ -0,0 +1,120 @@
+// Copyright 2010 The Go 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 "runtime.h"
+#include "arch_GOARCH.h"
+#include "defs_GOOS_GOARCH.h"
+#include "os_GOOS.h"
+#include "malloc.h"
+#include "textflag.h"
+
+enum
+{
+	Debug = 0,
+};
+
+#pragma textflag NOSPLIT
+void*
+runtime·sysAlloc(uintptr n, uint64 *stat)
+{
+	void *v;
+
+	v = runtime·mmap(nil, n, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0);
+	if(v < (void*)4096) {
+		if(Debug)
+			runtime·printf("sysAlloc(%p): %p\n", n, v);
+		return nil;
+	}
+	runtime·xadd64(stat, n);
+	if(Debug)
+		runtime·printf("sysAlloc(%p) = %p\n", n, v);
+	return v;
+}
+
+void
+runtime·SysUnused(void *v, uintptr n)
+{
+	if(Debug)
+		runtime·printf("SysUnused(%p, %p)\n", v, n);
+}
+
+void
+runtime·SysUsed(void *v, uintptr n)
+{
+	USED(v);
+	USED(n);
+}
+
+void
+runtime·SysFree(void *v, uintptr n, uint64 *stat)
+{
+	if(Debug)
+		runtime·printf("SysFree(%p, %p)\n", v, n);
+	runtime·xadd64(stat, -(uint64)n);
+	runtime·munmap(v, n);
+}
+
+void
+runtime·SysFault(void *v, uintptr n)
+{
+	runtime·mmap(v, n, PROT_NONE, MAP_ANON|MAP_PRIVATE|MAP_FIXED, -1, 0);
+}
+
+void*
+runtime·SysReserve(void *v, uintptr n, bool *reserved)
+{
+	void *p;
+
+	// On 64-bit, people with ulimit -v set complain if we reserve too
+	// much address space.  Instead, assume that the reservation is okay
+	// and check the assumption in SysMap.
+	if(NaCl || sizeof(void*) == 8) {
+		*reserved = false;
+		return v;
+	}
+	
+	p = runtime·mmap(v, n, PROT_NONE, MAP_ANON|MAP_PRIVATE, -1, 0);
+	if(p < (void*)4096)
+		return nil;
+	*reserved = true;
+	return p;
+}
+
+void
+runtime·SysMap(void *v, uintptr n, bool reserved, uint64 *stat)
+{
+	void *p;
+	
+	runtime·xadd64(stat, n);
+
+	// On 64-bit, we don't actually have v reserved, so tread carefully.
+	if(!reserved) {
+		p = runtime·mmap(v, n, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0);
+		if(p == (void*)ENOMEM) {
+			runtime·printf("SysMap(%p, %p): %p\n", v, n, p);
+			runtime·throw("runtime: out of memory");
+		}
+		if(p != v) {
+			runtime·printf("SysMap(%p, %p): %p\n", v, n, p);
+			runtime·printf("runtime: address space conflict: map(%p) = %p\n", v, p);
+			runtime·throw("runtime: address space conflict");
+		}
+		if(Debug)
+			runtime·printf("SysMap(%p, %p) = %p\n", v, n, p);
+		return;
+	}
+
+	p = runtime·mmap(v, n, PROT_READ|PROT_WRITE, MAP_ANON|MAP_FIXED|MAP_PRIVATE, -1, 0);
+	if(p == (void*)ENOMEM) {
+		runtime·printf("SysMap(%p, %p): %p\n", v, n, p);
+		runtime·throw("runtime: out of memory");
+	}
+	if(p != v) {
+		runtime·printf("SysMap(%p, %p): %p\n", v, n, p);
+		runtime·printf("mmap MAP_FIXED %p returned %p\n", v, p);
+		runtime·throw("runtime: cannot map pages in arena address space");
+	}
+	if(Debug)
+		runtime·printf("SysMap(%p, %p) = %p\n", v, n, p);
+}
diff --git a/src/runtime/mem_netbsd.c b/src/runtime/mem_netbsd.c
new file mode 100644
index 0000000..31820e5
--- /dev/null
+++ b/src/runtime/mem_netbsd.c
@@ -0,0 +1,100 @@
+// Copyright 2010 The Go 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 "runtime.h"
+#include "arch_GOARCH.h"
+#include "defs_GOOS_GOARCH.h"
+#include "os_GOOS.h"
+#include "malloc.h"
+#include "textflag.h"
+
+enum
+{
+	ENOMEM = 12,
+};
+
+#pragma textflag NOSPLIT
+void*
+runtime·sysAlloc(uintptr n, uint64 *stat)
+{
+	void *v;
+
+	v = runtime·mmap(nil, n, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0);
+	if(v < (void*)4096)
+		return nil;
+	runtime·xadd64(stat, n);
+	return v;
+}
+
+void
+runtime·SysUnused(void *v, uintptr n)
+{
+	runtime·madvise(v, n, MADV_FREE);
+}
+
+void
+runtime·SysUsed(void *v, uintptr n)
+{
+	USED(v);
+	USED(n);
+}
+
+void
+runtime·SysFree(void *v, uintptr n, uint64 *stat)
+{
+	runtime·xadd64(stat, -(uint64)n);
+	runtime·munmap(v, n);
+}
+
+void
+runtime·SysFault(void *v, uintptr n)
+{
+	runtime·mmap(v, n, PROT_NONE, MAP_ANON|MAP_PRIVATE|MAP_FIXED, -1, 0);
+}
+
+void*
+runtime·SysReserve(void *v, uintptr n, bool *reserved)
+{
+	void *p;
+
+	// On 64-bit, people with ulimit -v set complain if we reserve too
+	// much address space.  Instead, assume that the reservation is okay
+	// and check the assumption in SysMap.
+	if(sizeof(void*) == 8 && n > 1LL<<32) {
+		*reserved = false;
+		return v;
+	}
+
+	p = runtime·mmap(v, n, PROT_NONE, MAP_ANON|MAP_PRIVATE, -1, 0);
+	if(p < (void*)4096)
+		return nil;
+	*reserved = true;
+	return p;
+}
+
+void
+runtime·SysMap(void *v, uintptr n, bool reserved, uint64 *stat)
+{
+	void *p;
+	
+	runtime·xadd64(stat, n);
+
+	// On 64-bit, we don't actually have v reserved, so tread carefully.
+	if(!reserved) {
+		p = runtime·mmap(v, n, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0);
+		if(p == (void*)ENOMEM)
+			runtime·throw("runtime: out of memory");
+		if(p != v) {
+			runtime·printf("runtime: address space conflict: map(%p) = %p\n", v, p);
+			runtime·throw("runtime: address space conflict");
+		}
+		return;
+	}
+
+	p = runtime·mmap(v, n, PROT_READ|PROT_WRITE, MAP_ANON|MAP_FIXED|MAP_PRIVATE, -1, 0);
+	if(p == (void*)ENOMEM)
+		runtime·throw("runtime: out of memory");
+	if(p != v)
+		runtime·throw("runtime: cannot map pages in arena address space");
+}
diff --git a/src/runtime/mem_openbsd.c b/src/runtime/mem_openbsd.c
new file mode 100644
index 0000000..31820e5
--- /dev/null
+++ b/src/runtime/mem_openbsd.c
@@ -0,0 +1,100 @@
+// Copyright 2010 The Go 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 "runtime.h"
+#include "arch_GOARCH.h"
+#include "defs_GOOS_GOARCH.h"
+#include "os_GOOS.h"
+#include "malloc.h"
+#include "textflag.h"
+
+enum
+{
+	ENOMEM = 12,
+};
+
+#pragma textflag NOSPLIT
+void*
+runtime·sysAlloc(uintptr n, uint64 *stat)
+{
+	void *v;
+
+	v = runtime·mmap(nil, n, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0);
+	if(v < (void*)4096)
+		return nil;
+	runtime·xadd64(stat, n);
+	return v;
+}
+
+void
+runtime·SysUnused(void *v, uintptr n)
+{
+	runtime·madvise(v, n, MADV_FREE);
+}
+
+void
+runtime·SysUsed(void *v, uintptr n)
+{
+	USED(v);
+	USED(n);
+}
+
+void
+runtime·SysFree(void *v, uintptr n, uint64 *stat)
+{
+	runtime·xadd64(stat, -(uint64)n);
+	runtime·munmap(v, n);
+}
+
+void
+runtime·SysFault(void *v, uintptr n)
+{
+	runtime·mmap(v, n, PROT_NONE, MAP_ANON|MAP_PRIVATE|MAP_FIXED, -1, 0);
+}
+
+void*
+runtime·SysReserve(void *v, uintptr n, bool *reserved)
+{
+	void *p;
+
+	// On 64-bit, people with ulimit -v set complain if we reserve too
+	// much address space.  Instead, assume that the reservation is okay
+	// and check the assumption in SysMap.
+	if(sizeof(void*) == 8 && n > 1LL<<32) {
+		*reserved = false;
+		return v;
+	}
+
+	p = runtime·mmap(v, n, PROT_NONE, MAP_ANON|MAP_PRIVATE, -1, 0);
+	if(p < (void*)4096)
+		return nil;
+	*reserved = true;
+	return p;
+}
+
+void
+runtime·SysMap(void *v, uintptr n, bool reserved, uint64 *stat)
+{
+	void *p;
+	
+	runtime·xadd64(stat, n);
+
+	// On 64-bit, we don't actually have v reserved, so tread carefully.
+	if(!reserved) {
+		p = runtime·mmap(v, n, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0);
+		if(p == (void*)ENOMEM)
+			runtime·throw("runtime: out of memory");
+		if(p != v) {
+			runtime·printf("runtime: address space conflict: map(%p) = %p\n", v, p);
+			runtime·throw("runtime: address space conflict");
+		}
+		return;
+	}
+
+	p = runtime·mmap(v, n, PROT_READ|PROT_WRITE, MAP_ANON|MAP_FIXED|MAP_PRIVATE, -1, 0);
+	if(p == (void*)ENOMEM)
+		runtime·throw("runtime: out of memory");
+	if(p != v)
+		runtime·throw("runtime: cannot map pages in arena address space");
+}
diff --git a/src/runtime/mem_plan9.c b/src/runtime/mem_plan9.c
new file mode 100644
index 0000000..d673d6f
--- /dev/null
+++ b/src/runtime/mem_plan9.c
@@ -0,0 +1,121 @@
+// Copyright 2010 The Go 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 "runtime.h"
+#include "defs_GOOS_GOARCH.h"
+#include "arch_GOARCH.h"
+#include "malloc.h"
+#include "os_GOOS.h"
+#include "textflag.h"
+
+extern byte runtime·end[];
+#pragma dataflag NOPTR
+static byte *bloc = { runtime·end };
+static Mutex memlock;
+
+enum
+{
+	Round = PAGESIZE-1
+};
+
+static void*
+brk(uintptr nbytes)
+{
+	uintptr bl;
+
+	runtime·lock(&memlock);
+	// Plan 9 sbrk from /sys/src/libc/9sys/sbrk.c
+	bl = ((uintptr)bloc + Round) & ~Round;
+	if(runtime·brk_((void*)(bl + nbytes)) < 0) {
+		runtime·unlock(&memlock);
+		return nil;
+	}
+	bloc = (byte*)bl + nbytes;
+	runtime·unlock(&memlock);
+	return (void*)bl;	
+}
+
+static void
+sysalloc(void)
+{
+	uintptr nbytes;
+	uint64 *stat;
+	void *p;
+
+	nbytes = g->m->scalararg[0];
+	stat = g->m->ptrarg[0];
+	g->m->scalararg[0] = 0;
+	g->m->ptrarg[0] = nil;
+
+	p = brk(nbytes);
+	if(p != nil)
+		runtime·xadd64(stat, nbytes);
+
+	g->m->ptrarg[0] = p;
+}
+
+#pragma textflag NOSPLIT
+void*
+runtime·sysAlloc(uintptr nbytes, uint64 *stat)
+{
+	void (*fn)(void);
+	void *p;
+
+	g->m->scalararg[0] = nbytes;
+	g->m->ptrarg[0] = stat;
+	fn = sysalloc;
+	runtime·onM(&fn);
+	p = g->m->ptrarg[0];
+	g->m->ptrarg[0] = nil;
+	return p;
+}
+
+void
+runtime·SysFree(void *v, uintptr nbytes, uint64 *stat)
+{
+	runtime·xadd64(stat, -(uint64)nbytes);
+	runtime·lock(&memlock);
+	// from tiny/mem.c
+	// Push pointer back if this is a free
+	// of the most recent sysAlloc.
+	nbytes += (nbytes + Round) & ~Round;
+	if(bloc == (byte*)v+nbytes)
+		bloc -= nbytes;
+	runtime·unlock(&memlock);
+}
+
+void
+runtime·SysUnused(void *v, uintptr nbytes)
+{
+	USED(v, nbytes);
+}
+
+void
+runtime·SysUsed(void *v, uintptr nbytes)
+{
+	USED(v, nbytes);
+}
+
+void
+runtime·SysMap(void *v, uintptr nbytes, bool reserved, uint64 *stat)
+{
+	// SysReserve has already allocated all heap memory,
+	// but has not adjusted stats.
+	USED(v, reserved);
+	runtime·xadd64(stat, nbytes);
+}
+
+void
+runtime·SysFault(void *v, uintptr nbytes)
+{
+	USED(v, nbytes);
+}
+
+void*
+runtime·SysReserve(void *v, uintptr nbytes, bool *reserved)
+{
+	USED(v);
+	*reserved = true;
+	return brk(nbytes);
+}
diff --git a/src/runtime/mem_solaris.c b/src/runtime/mem_solaris.c
new file mode 100644
index 0000000..8e90ba1
--- /dev/null
+++ b/src/runtime/mem_solaris.c
@@ -0,0 +1,101 @@
+// Copyright 2010 The Go 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 "runtime.h"
+#include "arch_GOARCH.h"
+#include "defs_GOOS_GOARCH.h"
+#include "os_GOOS.h"
+#include "malloc.h"
+#include "textflag.h"
+
+enum
+{
+	ENOMEM = 12,
+};
+
+#pragma textflag NOSPLIT
+void*
+runtime·sysAlloc(uintptr n, uint64 *stat)
+{
+	void *v;
+
+	v = runtime·mmap(nil, n, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0);
+	if(v < (void*)4096)
+		return nil;
+	runtime·xadd64(stat, n);
+	return v;
+}
+
+void
+runtime·SysUnused(void *v, uintptr n)
+{
+	USED(v);
+	USED(n);
+}
+
+void
+runtime·SysUsed(void *v, uintptr n)
+{
+	USED(v);
+	USED(n);
+}
+
+void
+runtime·SysFree(void *v, uintptr n, uint64 *stat)
+{
+	runtime·xadd64(stat, -(uint64)n);
+	runtime·munmap(v, n);
+}
+
+void
+runtime·SysFault(void *v, uintptr n)
+{
+	runtime·mmap(v, n, PROT_NONE, MAP_ANON|MAP_PRIVATE|MAP_FIXED, -1, 0);
+}
+
+void*
+runtime·SysReserve(void *v, uintptr n, bool *reserved)
+{
+	void *p;
+
+	// On 64-bit, people with ulimit -v set complain if we reserve too
+	// much address space.  Instead, assume that the reservation is okay
+	// and check the assumption in SysMap.
+	if(sizeof(void*) == 8 && n > 1LL<<32) {
+		*reserved = false;
+		return v;
+	}
+	
+	p = runtime·mmap(v, n, PROT_NONE, MAP_ANON|MAP_PRIVATE, -1, 0);
+	if(p < (void*)4096)
+		return nil;
+	*reserved = true;
+	return p;
+}
+
+void
+runtime·SysMap(void *v, uintptr n, bool reserved, uint64 *stat)
+{
+	void *p;
+	
+	runtime·xadd64(stat, n);
+
+	// On 64-bit, we don't actually have v reserved, so tread carefully.
+	if(!reserved) {
+		p = runtime·mmap(v, n, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0);
+		if(p == (void*)ENOMEM)
+			runtime·throw("runtime: out of memory");
+		if(p != v) {
+			runtime·printf("runtime: address space conflict: map(%p) = %p\n", v, p);
+			runtime·throw("runtime: address space conflict");
+		}
+		return;
+	}
+
+	p = runtime·mmap(v, n, PROT_READ|PROT_WRITE, MAP_ANON|MAP_FIXED|MAP_PRIVATE, -1, 0);
+	if(p == (void*)ENOMEM)
+		runtime·throw("runtime: out of memory");
+	if(p != v)
+		runtime·throw("runtime: cannot map pages in arena address space");
+}
diff --git a/src/runtime/mem_windows.c b/src/runtime/mem_windows.c
new file mode 100644
index 0000000..6ea9920
--- /dev/null
+++ b/src/runtime/mem_windows.c
@@ -0,0 +1,132 @@
+// Copyright 2010 The Go 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 "runtime.h"
+#include "arch_GOARCH.h"
+#include "os_GOOS.h"
+#include "defs_GOOS_GOARCH.h"
+#include "malloc.h"
+#include "textflag.h"
+
+enum {
+	MEM_COMMIT = 0x1000,
+	MEM_RESERVE = 0x2000,
+	MEM_DECOMMIT = 0x4000,
+	MEM_RELEASE = 0x8000,
+	
+	PAGE_READWRITE = 0x0004,
+	PAGE_NOACCESS = 0x0001,
+};
+
+#pragma dynimport runtime·VirtualAlloc VirtualAlloc "kernel32.dll"
+#pragma dynimport runtime·VirtualFree VirtualFree "kernel32.dll"
+#pragma dynimport runtime·VirtualProtect VirtualProtect "kernel32.dll"
+extern void *runtime·VirtualAlloc;
+extern void *runtime·VirtualFree;
+extern void *runtime·VirtualProtect;
+
+#pragma textflag NOSPLIT
+void*
+runtime·sysAlloc(uintptr n, uint64 *stat)
+{
+	runtime·xadd64(stat, n);
+	return runtime·stdcall4(runtime·VirtualAlloc, 0, n, MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE);
+}
+
+void
+runtime·SysUnused(void *v, uintptr n)
+{
+	void *r;
+	uintptr small;
+
+	r = runtime·stdcall3(runtime·VirtualFree, (uintptr)v, n, MEM_DECOMMIT);
+	if(r != nil)
+		return;
+
+	// Decommit failed. Usual reason is that we've merged memory from two different
+	// VirtualAlloc calls, and Windows will only let each VirtualFree handle pages from
+	// a single VirtualAlloc. It is okay to specify a subset of the pages from a single alloc,
+	// just not pages from multiple allocs. This is a rare case, arising only when we're
+	// trying to give memory back to the operating system, which happens on a time
+	// scale of minutes. It doesn't have to be terribly fast. Instead of extra bookkeeping
+	// on all our VirtualAlloc calls, try freeing successively smaller pieces until
+	// we manage to free something, and then repeat. This ends up being O(n log n)
+	// in the worst case, but that's fast enough.
+	while(n > 0) {
+		small = n;
+		while(small >= 4096 && runtime·stdcall3(runtime·VirtualFree, (uintptr)v, small, MEM_DECOMMIT) == nil)
+			small = (small / 2) & ~(4096-1);
+		if(small < 4096)
+			runtime·throw("runtime: failed to decommit pages");
+		v = (byte*)v + small;
+		n -= small;
+	}
+}
+
+void
+runtime·SysUsed(void *v, uintptr n)
+{
+	void *r;
+	uintptr small;
+
+	r = runtime·stdcall4(runtime·VirtualAlloc, (uintptr)v, n, MEM_COMMIT, PAGE_READWRITE);
+	if(r != v)
+		runtime·throw("runtime: failed to commit pages");
+
+	// Commit failed. See SysUnused.
+	while(n > 0) {
+		small = n;
+		while(small >= 4096 && runtime·stdcall4(runtime·VirtualAlloc, (uintptr)v, small, MEM_COMMIT, PAGE_READWRITE) == nil)
+			small = (small / 2) & ~(4096-1);
+		if(small < 4096)
+			runtime·throw("runtime: failed to decommit pages");
+		v = (byte*)v + small;
+		n -= small;
+	}
+}
+
+void
+runtime·SysFree(void *v, uintptr n, uint64 *stat)
+{
+	uintptr r;
+
+	runtime·xadd64(stat, -(uint64)n);
+	r = (uintptr)runtime·stdcall3(runtime·VirtualFree, (uintptr)v, 0, MEM_RELEASE);
+	if(r == 0)
+		runtime·throw("runtime: failed to release pages");
+}
+
+void
+runtime·SysFault(void *v, uintptr n)
+{
+	// SysUnused makes the memory inaccessible and prevents its reuse
+	runtime·SysUnused(v, n);
+}
+
+void*
+runtime·SysReserve(void *v, uintptr n, bool *reserved)
+{
+	*reserved = true;
+	// v is just a hint.
+	// First try at v.
+	v = runtime·stdcall4(runtime·VirtualAlloc, (uintptr)v, n, MEM_RESERVE, PAGE_READWRITE);
+	if(v != nil)
+		return v;
+	
+	// Next let the kernel choose the address.
+	return runtime·stdcall4(runtime·VirtualAlloc, 0, n, MEM_RESERVE, PAGE_READWRITE);
+}
+
+void
+runtime·SysMap(void *v, uintptr n, bool reserved, uint64 *stat)
+{
+	void *p;
+
+	USED(reserved);
+
+	runtime·xadd64(stat, n);
+	p = runtime·stdcall4(runtime·VirtualAlloc, (uintptr)v, n, MEM_COMMIT, PAGE_READWRITE);
+	if(p != v)
+		runtime·throw("runtime: cannot map pages in arena address space");
+}
diff --git a/src/runtime/memclr_386.s b/src/runtime/memclr_386.s
new file mode 100644
index 0000000..1520aea
--- /dev/null
+++ b/src/runtime/memclr_386.s
@@ -0,0 +1,130 @@
+// 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.
+
+// +build !plan9
+
+#include "textflag.h"
+
+// NOTE: Windows externalthreadhandler expects memclr to preserve DX.
+
+// void runtime·memclr(void*, uintptr)
+TEXT runtime·memclr(SB), NOSPLIT, $0-8
+	MOVL	ptr+0(FP), DI
+	MOVL	n+4(FP), BX
+	XORL	AX, AX
+
+	// MOVOU seems always faster than REP STOSL.
+clr_tail:
+	TESTL	BX, BX
+	JEQ	clr_0
+	CMPL	BX, $2
+	JBE	clr_1or2
+	CMPL	BX, $4
+	JBE	clr_3or4
+	CMPL	BX, $8
+	JBE	clr_5through8
+	CMPL	BX, $16
+	JBE	clr_9through16
+	TESTL	$0x4000000, runtime·cpuid_edx(SB) // check for sse2
+	JEQ	nosse2
+	PXOR	X0, X0
+	CMPL	BX, $32
+	JBE	clr_17through32
+	CMPL	BX, $64
+	JBE	clr_33through64
+	CMPL	BX, $128
+	JBE	clr_65through128
+	CMPL	BX, $256
+	JBE	clr_129through256
+	// TODO: use branch table and BSR to make this just a single dispatch
+
+clr_loop:
+	MOVOU	X0, 0(DI)
+	MOVOU	X0, 16(DI)
+	MOVOU	X0, 32(DI)
+	MOVOU	X0, 48(DI)
+	MOVOU	X0, 64(DI)
+	MOVOU	X0, 80(DI)
+	MOVOU	X0, 96(DI)
+	MOVOU	X0, 112(DI)
+	MOVOU	X0, 128(DI)
+	MOVOU	X0, 144(DI)
+	MOVOU	X0, 160(DI)
+	MOVOU	X0, 176(DI)
+	MOVOU	X0, 192(DI)
+	MOVOU	X0, 208(DI)
+	MOVOU	X0, 224(DI)
+	MOVOU	X0, 240(DI)
+	SUBL	$256, BX
+	ADDL	$256, DI
+	CMPL	BX, $256
+	JAE	clr_loop
+	JMP	clr_tail
+
+clr_1or2:
+	MOVB	AX, (DI)
+	MOVB	AX, -1(DI)(BX*1)
+	RET
+clr_0:
+	RET
+clr_3or4:
+	MOVW	AX, (DI)
+	MOVW	AX, -2(DI)(BX*1)
+	RET
+clr_5through8:
+	MOVL	AX, (DI)
+	MOVL	AX, -4(DI)(BX*1)
+	RET
+clr_9through16:
+	MOVL	AX, (DI)
+	MOVL	AX, 4(DI)
+	MOVL	AX, -8(DI)(BX*1)
+	MOVL	AX, -4(DI)(BX*1)
+	RET
+clr_17through32:
+	MOVOU	X0, (DI)
+	MOVOU	X0, -16(DI)(BX*1)
+	RET
+clr_33through64:
+	MOVOU	X0, (DI)
+	MOVOU	X0, 16(DI)
+	MOVOU	X0, -32(DI)(BX*1)
+	MOVOU	X0, -16(DI)(BX*1)
+	RET
+clr_65through128:
+	MOVOU	X0, (DI)
+	MOVOU	X0, 16(DI)
+	MOVOU	X0, 32(DI)
+	MOVOU	X0, 48(DI)
+	MOVOU	X0, -64(DI)(BX*1)
+	MOVOU	X0, -48(DI)(BX*1)
+	MOVOU	X0, -32(DI)(BX*1)
+	MOVOU	X0, -16(DI)(BX*1)
+	RET
+clr_129through256:
+	MOVOU	X0, (DI)
+	MOVOU	X0, 16(DI)
+	MOVOU	X0, 32(DI)
+	MOVOU	X0, 48(DI)
+	MOVOU	X0, 64(DI)
+	MOVOU	X0, 80(DI)
+	MOVOU	X0, 96(DI)
+	MOVOU	X0, 112(DI)
+	MOVOU	X0, -128(DI)(BX*1)
+	MOVOU	X0, -112(DI)(BX*1)
+	MOVOU	X0, -96(DI)(BX*1)
+	MOVOU	X0, -80(DI)(BX*1)
+	MOVOU	X0, -64(DI)(BX*1)
+	MOVOU	X0, -48(DI)(BX*1)
+	MOVOU	X0, -32(DI)(BX*1)
+	MOVOU	X0, -16(DI)(BX*1)
+	RET
+nosse2:
+	MOVL	BX, CX
+	SHRL	$2, CX
+	REP
+	STOSL
+	ANDL	$3, BX
+	JNE	clr_tail
+	RET
diff --git a/src/runtime/memclr_amd64.s b/src/runtime/memclr_amd64.s
new file mode 100644
index 0000000..94a2c7f
--- /dev/null
+++ b/src/runtime/memclr_amd64.s
@@ -0,0 +1,119 @@
+// 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.
+
+// +build !plan9
+
+#include "textflag.h"
+
+// NOTE: Windows externalthreadhandler expects memclr to preserve DX.
+
+// void runtime·memclr(void*, uintptr)
+TEXT runtime·memclr(SB), NOSPLIT, $0-16
+	MOVQ	ptr+0(FP), DI
+	MOVQ	n+8(FP), BX
+	XORQ	AX, AX
+
+	// MOVOU seems always faster than REP STOSQ.
+clr_tail:
+	TESTQ	BX, BX
+	JEQ	clr_0
+	CMPQ	BX, $2
+	JBE	clr_1or2
+	CMPQ	BX, $4
+	JBE	clr_3or4
+	CMPQ	BX, $8
+	JBE	clr_5through8
+	CMPQ	BX, $16
+	JBE	clr_9through16
+	PXOR	X0, X0
+	CMPQ	BX, $32
+	JBE	clr_17through32
+	CMPQ	BX, $64
+	JBE	clr_33through64
+	CMPQ	BX, $128
+	JBE	clr_65through128
+	CMPQ	BX, $256
+	JBE	clr_129through256
+	// TODO: use branch table and BSR to make this just a single dispatch
+	// TODO: for really big clears, use MOVNTDQ.
+
+clr_loop:
+	MOVOU	X0, 0(DI)
+	MOVOU	X0, 16(DI)
+	MOVOU	X0, 32(DI)
+	MOVOU	X0, 48(DI)
+	MOVOU	X0, 64(DI)
+	MOVOU	X0, 80(DI)
+	MOVOU	X0, 96(DI)
+	MOVOU	X0, 112(DI)
+	MOVOU	X0, 128(DI)
+	MOVOU	X0, 144(DI)
+	MOVOU	X0, 160(DI)
+	MOVOU	X0, 176(DI)
+	MOVOU	X0, 192(DI)
+	MOVOU	X0, 208(DI)
+	MOVOU	X0, 224(DI)
+	MOVOU	X0, 240(DI)
+	SUBQ	$256, BX
+	ADDQ	$256, DI
+	CMPQ	BX, $256
+	JAE	clr_loop
+	JMP	clr_tail
+
+clr_1or2:
+	MOVB	AX, (DI)
+	MOVB	AX, -1(DI)(BX*1)
+	RET
+clr_0:
+	RET
+clr_3or4:
+	MOVW	AX, (DI)
+	MOVW	AX, -2(DI)(BX*1)
+	RET
+clr_5through8:
+	MOVL	AX, (DI)
+	MOVL	AX, -4(DI)(BX*1)
+	RET
+clr_9through16:
+	MOVQ	AX, (DI)
+	MOVQ	AX, -8(DI)(BX*1)
+	RET
+clr_17through32:
+	MOVOU	X0, (DI)
+	MOVOU	X0, -16(DI)(BX*1)
+	RET
+clr_33through64:
+	MOVOU	X0, (DI)
+	MOVOU	X0, 16(DI)
+	MOVOU	X0, -32(DI)(BX*1)
+	MOVOU	X0, -16(DI)(BX*1)
+	RET
+clr_65through128:
+	MOVOU	X0, (DI)
+	MOVOU	X0, 16(DI)
+	MOVOU	X0, 32(DI)
+	MOVOU	X0, 48(DI)
+	MOVOU	X0, -64(DI)(BX*1)
+	MOVOU	X0, -48(DI)(BX*1)
+	MOVOU	X0, -32(DI)(BX*1)
+	MOVOU	X0, -16(DI)(BX*1)
+	RET
+clr_129through256:
+	MOVOU	X0, (DI)
+	MOVOU	X0, 16(DI)
+	MOVOU	X0, 32(DI)
+	MOVOU	X0, 48(DI)
+	MOVOU	X0, 64(DI)
+	MOVOU	X0, 80(DI)
+	MOVOU	X0, 96(DI)
+	MOVOU	X0, 112(DI)
+	MOVOU	X0, -128(DI)(BX*1)
+	MOVOU	X0, -112(DI)(BX*1)
+	MOVOU	X0, -96(DI)(BX*1)
+	MOVOU	X0, -80(DI)(BX*1)
+	MOVOU	X0, -64(DI)(BX*1)
+	MOVOU	X0, -48(DI)(BX*1)
+	MOVOU	X0, -32(DI)(BX*1)
+	MOVOU	X0, -16(DI)(BX*1)
+	RET
diff --git a/src/runtime/memclr_arm.s b/src/runtime/memclr_arm.s
new file mode 100644
index 0000000..1824d33
--- /dev/null
+++ b/src/runtime/memclr_arm.s
@@ -0,0 +1,87 @@
+// Inferno's libkern/memset-arm.s
+// http://code.google.com/p/inferno-os/source/browse/libkern/memset-arm.s
+//
+//         Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
+//         Revisions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com).  All rights reserved.
+//         Portions Copyright 2009 The Go Authors. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#include "textflag.h"
+
+TO = 8
+TOE = 11
+N = 12
+TMP = 12				/* N and TMP don't overlap */
+
+TEXT runtime·memclr(SB),NOSPLIT,$0-8
+	MOVW	ptr+0(FP), R(TO)
+	MOVW	n+4(FP), R(N)
+	MOVW	$0, R(0)
+
+	ADD	R(N), R(TO), R(TOE)	/* to end pointer */
+
+	CMP	$4, R(N)		/* need at least 4 bytes to copy */
+	BLT	_1tail
+
+_4align:				/* align on 4 */
+	AND.S	$3, R(TO), R(TMP)
+	BEQ	_4aligned
+
+	MOVBU.P	R(0), 1(R(TO))		/* implicit write back */
+	B	_4align
+
+_4aligned:
+	SUB	$31, R(TOE), R(TMP)	/* do 32-byte chunks if possible */
+	CMP	R(TMP), R(TO)
+	BHS	_4tail
+
+	MOVW	R0, R1			/* replicate */
+	MOVW	R0, R2
+	MOVW	R0, R3
+	MOVW	R0, R4
+	MOVW	R0, R5
+	MOVW	R0, R6
+	MOVW	R0, R7
+
+_f32loop:
+	CMP	R(TMP), R(TO)
+	BHS	_4tail
+
+	MOVM.IA.W [R0-R7], (R(TO))
+	B	_f32loop
+
+_4tail:
+	SUB	$3, R(TOE), R(TMP)	/* do remaining words if possible */
+_4loop:
+	CMP	R(TMP), R(TO)
+	BHS	_1tail
+
+	MOVW.P	R(0), 4(R(TO))		/* implicit write back */
+	B	_4loop
+
+_1tail:
+	CMP	R(TO), R(TOE)
+	BEQ	_return
+
+	MOVBU.P	R(0), 1(R(TO))		/* implicit write back */
+	B	_1tail
+
+_return:
+	RET
diff --git a/src/runtime/memclr_plan9_386.s b/src/runtime/memclr_plan9_386.s
new file mode 100644
index 0000000..b4b671f
--- /dev/null
+++ b/src/runtime/memclr_plan9_386.s
@@ -0,0 +1,51 @@
+// 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"
+
+// void runtime·memclr(void*, uintptr)
+TEXT runtime·memclr(SB), NOSPLIT, $0-8
+	MOVL	ptr+0(FP), DI
+	MOVL	n+4(FP), BX
+	XORL	AX, AX
+
+clr_tail:
+	TESTL	BX, BX
+	JEQ	clr_0
+	CMPL	BX, $2
+	JBE	clr_1or2
+	CMPL	BX, $4
+	JBE	clr_3or4
+	CMPL	BX, $8
+	JBE	clr_5through8
+	CMPL	BX, $16
+	JBE	clr_9through16
+	MOVL	BX, CX
+	SHRL	$2, CX
+	REP
+	STOSL
+	ANDL	$3, BX
+	JNE	clr_tail
+	RET
+
+clr_1or2:
+	MOVB	AX, (DI)
+	MOVB	AX, -1(DI)(BX*1)
+	RET
+clr_0:
+	RET
+clr_3or4:
+	MOVW	AX, (DI)
+	MOVW	AX, -2(DI)(BX*1)
+	RET
+clr_5through8:
+	MOVL	AX, (DI)
+	MOVL	AX, -4(DI)(BX*1)
+	RET
+clr_9through16:
+	MOVL	AX, (DI)
+	MOVL	AX, 4(DI)
+	MOVL	AX, -8(DI)(BX*1)
+	MOVL	AX, -4(DI)(BX*1)
+	RET
diff --git a/src/runtime/memclr_plan9_amd64.s b/src/runtime/memclr_plan9_amd64.s
new file mode 100644
index 0000000..37e61df
--- /dev/null
+++ b/src/runtime/memclr_plan9_amd64.s
@@ -0,0 +1,21 @@
+// 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"
+
+// void runtime·memclr(void*, uintptr)
+TEXT runtime·memclr(SB),NOSPLIT,$0-16
+	MOVQ	ptr+0(FP), DI
+	MOVQ	n+8(FP), CX
+	MOVQ	CX, BX
+	ANDQ	$7, BX
+	SHRQ	$3, CX
+	MOVQ	$0, AX
+	CLD
+	REP
+	STOSQ
+	MOVQ	BX, CX
+	REP
+	STOSB
+	RET
diff --git a/src/runtime/memmove_386.s b/src/runtime/memmove_386.s
new file mode 100644
index 0000000..4c0c74c
--- /dev/null
+++ b/src/runtime/memmove_386.s
@@ -0,0 +1,176 @@
+// Inferno's libkern/memmove-386.s
+// http://code.google.com/p/inferno-os/source/browse/libkern/memmove-386.s
+//
+//         Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
+//         Revisions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com).  All rights reserved.
+//         Portions Copyright 2009 The Go Authors. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+// +build !plan9
+
+#include "textflag.h"
+
+TEXT runtime·memmove(SB), NOSPLIT, $0-12
+	MOVL	to+0(FP), DI
+	MOVL	from+4(FP), SI
+	MOVL	n+8(FP), BX
+
+	// REP instructions have a high startup cost, so we handle small sizes
+	// with some straightline code.  The REP MOVSL instruction is really fast
+	// for large sizes.  The cutover is approximately 1K.  We implement up to
+	// 128 because that is the maximum SSE register load (loading all data
+	// into registers lets us ignore copy direction).
+tail:
+	TESTL	BX, BX
+	JEQ	move_0
+	CMPL	BX, $2
+	JBE	move_1or2
+	CMPL	BX, $4
+	JBE	move_3or4
+	CMPL	BX, $8
+	JBE	move_5through8
+	CMPL	BX, $16
+	JBE	move_9through16
+	TESTL	$0x4000000, runtime·cpuid_edx(SB) // check for sse2
+	JEQ	nosse2
+	CMPL	BX, $32
+	JBE	move_17through32
+	CMPL	BX, $64
+	JBE	move_33through64
+	CMPL	BX, $128
+	JBE	move_65through128
+	// TODO: use branch table and BSR to make this just a single dispatch
+
+nosse2:
+/*
+ * check and set for backwards
+ */
+	CMPL	SI, DI
+	JLS	back
+
+/*
+ * forward copy loop
+ */
+forward:	
+	MOVL	BX, CX
+	SHRL	$2, CX
+	ANDL	$3, BX
+
+	REP;	MOVSL
+	JMP	tail
+/*
+ * check overlap
+ */
+back:
+	MOVL	SI, CX
+	ADDL	BX, CX
+	CMPL	CX, DI
+	JLS	forward
+/*
+ * whole thing backwards has
+ * adjusted addresses
+ */
+
+	ADDL	BX, DI
+	ADDL	BX, SI
+	STD
+
+/*
+ * copy
+ */
+	MOVL	BX, CX
+	SHRL	$2, CX
+	ANDL	$3, BX
+
+	SUBL	$4, DI
+	SUBL	$4, SI
+	REP;	MOVSL
+
+	CLD
+	ADDL	$4, DI
+	ADDL	$4, SI
+	SUBL	BX, DI
+	SUBL	BX, SI
+	JMP	tail
+
+move_1or2:
+	MOVB	(SI), AX
+	MOVB	-1(SI)(BX*1), CX
+	MOVB	AX, (DI)
+	MOVB	CX, -1(DI)(BX*1)
+	RET
+move_0:
+	RET
+move_3or4:
+	MOVW	(SI), AX
+	MOVW	-2(SI)(BX*1), CX
+	MOVW	AX, (DI)
+	MOVW	CX, -2(DI)(BX*1)
+	RET
+move_5through8:
+	MOVL	(SI), AX
+	MOVL	-4(SI)(BX*1), CX
+	MOVL	AX, (DI)
+	MOVL	CX, -4(DI)(BX*1)
+	RET
+move_9through16:
+	MOVL	(SI), AX
+	MOVL	4(SI), CX
+	MOVL	-8(SI)(BX*1), DX
+	MOVL	-4(SI)(BX*1), BP
+	MOVL	AX, (DI)
+	MOVL	CX, 4(DI)
+	MOVL	DX, -8(DI)(BX*1)
+	MOVL	BP, -4(DI)(BX*1)
+	RET
+move_17through32:
+	MOVOU	(SI), X0
+	MOVOU	-16(SI)(BX*1), X1
+	MOVOU	X0, (DI)
+	MOVOU	X1, -16(DI)(BX*1)
+	RET
+move_33through64:
+	MOVOU	(SI), X0
+	MOVOU	16(SI), X1
+	MOVOU	-32(SI)(BX*1), X2
+	MOVOU	-16(SI)(BX*1), X3
+	MOVOU	X0, (DI)
+	MOVOU	X1, 16(DI)
+	MOVOU	X2, -32(DI)(BX*1)
+	MOVOU	X3, -16(DI)(BX*1)
+	RET
+move_65through128:
+	MOVOU	(SI), X0
+	MOVOU	16(SI), X1
+	MOVOU	32(SI), X2
+	MOVOU	48(SI), X3
+	MOVOU	-64(SI)(BX*1), X4
+	MOVOU	-48(SI)(BX*1), X5
+	MOVOU	-32(SI)(BX*1), X6
+	MOVOU	-16(SI)(BX*1), X7
+	MOVOU	X0, (DI)
+	MOVOU	X1, 16(DI)
+	MOVOU	X2, 32(DI)
+	MOVOU	X3, 48(DI)
+	MOVOU	X4, -64(DI)(BX*1)
+	MOVOU	X5, -48(DI)(BX*1)
+	MOVOU	X6, -32(DI)(BX*1)
+	MOVOU	X7, -16(DI)(BX*1)
+	RET
diff --git a/src/runtime/memmove_amd64.s b/src/runtime/memmove_amd64.s
new file mode 100644
index 0000000..f968435
--- /dev/null
+++ b/src/runtime/memmove_amd64.s
@@ -0,0 +1,252 @@
+// Derived from Inferno's libkern/memmove-386.s (adapted for amd64)
+// http://code.google.com/p/inferno-os/source/browse/libkern/memmove-386.s
+//
+//         Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
+//         Revisions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com).  All rights reserved.
+//         Portions Copyright 2009 The Go Authors. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+// +build !plan9
+
+#include "textflag.h"
+
+// void runtime·memmove(void*, void*, uintptr)
+TEXT runtime·memmove(SB), NOSPLIT, $0-24
+
+	MOVQ	to+0(FP), DI
+	MOVQ	from+8(FP), SI
+	MOVQ	n+16(FP), BX
+
+	// REP instructions have a high startup cost, so we handle small sizes
+	// with some straightline code.  The REP MOVSQ instruction is really fast
+	// for large sizes.  The cutover is approximately 2K.
+tail:
+	// move_129through256 or smaller work whether or not the source and the
+	// destination memory regions overlap because they load all data into
+	// registers before writing it back.  move_256through2048 on the other
+	// hand can be used only when the memory regions don't overlap or the copy
+	// direction is forward.
+	TESTQ	BX, BX
+	JEQ	move_0
+	CMPQ	BX, $2
+	JBE	move_1or2
+	CMPQ	BX, $4
+	JBE	move_3or4
+	CMPQ	BX, $8
+	JBE	move_5through8
+	CMPQ	BX, $16
+	JBE	move_9through16
+	CMPQ	BX, $32
+	JBE	move_17through32
+	CMPQ	BX, $64
+	JBE	move_33through64
+	CMPQ	BX, $128
+	JBE	move_65through128
+	CMPQ	BX, $256
+	JBE	move_129through256
+	// TODO: use branch table and BSR to make this just a single dispatch
+
+/*
+ * check and set for backwards
+ */
+	CMPQ	SI, DI
+	JLS	back
+
+/*
+ * forward copy loop
+ */
+forward:
+	CMPQ	BX, $2048
+	JLS	move_256through2048
+
+	MOVQ	BX, CX
+	SHRQ	$3, CX
+	ANDQ	$7, BX
+	REP;	MOVSQ
+	JMP	tail
+
+back:
+/*
+ * check overlap
+ */
+	MOVQ	SI, CX
+	ADDQ	BX, CX
+	CMPQ	CX, DI
+	JLS	forward
+	
+/*
+ * whole thing backwards has
+ * adjusted addresses
+ */
+	ADDQ	BX, DI
+	ADDQ	BX, SI
+	STD
+
+/*
+ * copy
+ */
+	MOVQ	BX, CX
+	SHRQ	$3, CX
+	ANDQ	$7, BX
+
+	SUBQ	$8, DI
+	SUBQ	$8, SI
+	REP;	MOVSQ
+
+	CLD
+	ADDQ	$8, DI
+	ADDQ	$8, SI
+	SUBQ	BX, DI
+	SUBQ	BX, SI
+	JMP	tail
+
+move_1or2:
+	MOVB	(SI), AX
+	MOVB	-1(SI)(BX*1), CX
+	MOVB	AX, (DI)
+	MOVB	CX, -1(DI)(BX*1)
+	RET
+move_0:
+	RET
+move_3or4:
+	MOVW	(SI), AX
+	MOVW	-2(SI)(BX*1), CX
+	MOVW	AX, (DI)
+	MOVW	CX, -2(DI)(BX*1)
+	RET
+move_5through8:
+	MOVL	(SI), AX
+	MOVL	-4(SI)(BX*1), CX
+	MOVL	AX, (DI)
+	MOVL	CX, -4(DI)(BX*1)
+	RET
+move_9through16:
+	MOVQ	(SI), AX
+	MOVQ	-8(SI)(BX*1), CX
+	MOVQ	AX, (DI)
+	MOVQ	CX, -8(DI)(BX*1)
+	RET
+move_17through32:
+	MOVOU	(SI), X0
+	MOVOU	-16(SI)(BX*1), X1
+	MOVOU	X0, (DI)
+	MOVOU	X1, -16(DI)(BX*1)
+	RET
+move_33through64:
+	MOVOU	(SI), X0
+	MOVOU	16(SI), X1
+	MOVOU	-32(SI)(BX*1), X2
+	MOVOU	-16(SI)(BX*1), X3
+	MOVOU	X0, (DI)
+	MOVOU	X1, 16(DI)
+	MOVOU	X2, -32(DI)(BX*1)
+	MOVOU	X3, -16(DI)(BX*1)
+	RET
+move_65through128:
+	MOVOU	(SI), X0
+	MOVOU	16(SI), X1
+	MOVOU	32(SI), X2
+	MOVOU	48(SI), X3
+	MOVOU	-64(SI)(BX*1), X4
+	MOVOU	-48(SI)(BX*1), X5
+	MOVOU	-32(SI)(BX*1), X6
+	MOVOU	-16(SI)(BX*1), X7
+	MOVOU	X0, (DI)
+	MOVOU	X1, 16(DI)
+	MOVOU	X2, 32(DI)
+	MOVOU	X3, 48(DI)
+	MOVOU	X4, -64(DI)(BX*1)
+	MOVOU	X5, -48(DI)(BX*1)
+	MOVOU	X6, -32(DI)(BX*1)
+	MOVOU	X7, -16(DI)(BX*1)
+	RET
+move_129through256:
+	MOVOU	(SI), X0
+	MOVOU	16(SI), X1
+	MOVOU	32(SI), X2
+	MOVOU	48(SI), X3
+	MOVOU	64(SI), X4
+	MOVOU	80(SI), X5
+	MOVOU	96(SI), X6
+	MOVOU	112(SI), X7
+	MOVOU	-128(SI)(BX*1), X8
+	MOVOU	-112(SI)(BX*1), X9
+	MOVOU	-96(SI)(BX*1), X10
+	MOVOU	-80(SI)(BX*1), X11
+	MOVOU	-64(SI)(BX*1), X12
+	MOVOU	-48(SI)(BX*1), X13
+	MOVOU	-32(SI)(BX*1), X14
+	MOVOU	-16(SI)(BX*1), X15
+	MOVOU	X0, (DI)
+	MOVOU	X1, 16(DI)
+	MOVOU	X2, 32(DI)
+	MOVOU	X3, 48(DI)
+	MOVOU	X4, 64(DI)
+	MOVOU	X5, 80(DI)
+	MOVOU	X6, 96(DI)
+	MOVOU	X7, 112(DI)
+	MOVOU	X8, -128(DI)(BX*1)
+	MOVOU	X9, -112(DI)(BX*1)
+	MOVOU	X10, -96(DI)(BX*1)
+	MOVOU	X11, -80(DI)(BX*1)
+	MOVOU	X12, -64(DI)(BX*1)
+	MOVOU	X13, -48(DI)(BX*1)
+	MOVOU	X14, -32(DI)(BX*1)
+	MOVOU	X15, -16(DI)(BX*1)
+	RET
+move_256through2048:
+	SUBQ	$256, BX
+	MOVOU	(SI), X0
+	MOVOU	16(SI), X1
+	MOVOU	32(SI), X2
+	MOVOU	48(SI), X3
+	MOVOU	64(SI), X4
+	MOVOU	80(SI), X5
+	MOVOU	96(SI), X6
+	MOVOU	112(SI), X7
+	MOVOU	128(SI), X8
+	MOVOU	144(SI), X9
+	MOVOU	160(SI), X10
+	MOVOU	176(SI), X11
+	MOVOU	192(SI), X12
+	MOVOU	208(SI), X13
+	MOVOU	224(SI), X14
+	MOVOU	240(SI), X15
+	MOVOU	X0, (DI)
+	MOVOU	X1, 16(DI)
+	MOVOU	X2, 32(DI)
+	MOVOU	X3, 48(DI)
+	MOVOU	X4, 64(DI)
+	MOVOU	X5, 80(DI)
+	MOVOU	X6, 96(DI)
+	MOVOU	X7, 112(DI)
+	MOVOU	X8, 128(DI)
+	MOVOU	X9, 144(DI)
+	MOVOU	X10, 160(DI)
+	MOVOU	X11, 176(DI)
+	MOVOU	X12, 192(DI)
+	MOVOU	X13, 208(DI)
+	MOVOU	X14, 224(DI)
+	MOVOU	X15, 240(DI)
+	CMPQ	BX, $256
+	LEAQ	256(SI), SI
+	LEAQ	256(DI), DI
+	JGE	move_256through2048
+	JMP	tail
diff --git a/src/runtime/memmove_arm.s b/src/runtime/memmove_arm.s
new file mode 100644
index 0000000..f187d42
--- /dev/null
+++ b/src/runtime/memmove_arm.s
@@ -0,0 +1,261 @@
+// Inferno's libkern/memmove-arm.s
+// http://code.google.com/p/inferno-os/source/browse/libkern/memmove-arm.s
+//
+//         Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
+//         Revisions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com).  All rights reserved.
+//         Portions Copyright 2009 The Go Authors. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#include "textflag.h"
+
+// TE or TS are spilled to the stack during bulk register moves.
+TS = 0
+TE = 8
+
+// Warning: the linker will use R11 to synthesize certain instructions. Please
+// take care and double check with objdump.
+FROM = 11
+N = 12
+TMP = 12				/* N and TMP don't overlap */
+TMP1 = 5
+
+RSHIFT = 5
+LSHIFT = 6
+OFFSET = 7
+
+BR0 = 0					/* shared with TS */
+BW0 = 1
+BR1 = 1
+BW1 = 2
+BR2 = 2
+BW2 = 3
+BR3 = 3
+BW3 = 4
+
+FW0 = 1
+FR0 = 2
+FW1 = 2
+FR1 = 3
+FW2 = 3
+FR2 = 4
+FW3 = 4
+FR3 = 8					/* shared with TE */
+
+TEXT runtime·memmove(SB), NOSPLIT, $4-12
+_memmove:
+	MOVW	to+0(FP), R(TS)
+	MOVW	from+4(FP), R(FROM)
+	MOVW	n+8(FP), R(N)
+
+	ADD	R(N), R(TS), R(TE)	/* to end pointer */
+
+	CMP	R(FROM), R(TS)
+	BLS	_forward
+
+_back:
+	ADD	R(N), R(FROM)		/* from end pointer */
+	CMP	$4, R(N)		/* need at least 4 bytes to copy */
+	BLT	_b1tail
+
+_b4align:				/* align destination on 4 */
+	AND.S	$3, R(TE), R(TMP)
+	BEQ	_b4aligned
+
+	MOVBU.W	-1(R(FROM)), R(TMP)	/* pre-indexed */
+	MOVBU.W	R(TMP), -1(R(TE))	/* pre-indexed */
+	B	_b4align
+
+_b4aligned:				/* is source now aligned? */
+	AND.S	$3, R(FROM), R(TMP)
+	BNE	_bunaligned
+
+	ADD	$31, R(TS), R(TMP)	/* do 32-byte chunks if possible */
+	MOVW	R(TS), savedts-4(SP)
+_b32loop:
+	CMP	R(TMP), R(TE)
+	BLS	_b4tail
+
+	MOVM.DB.W (R(FROM)), [R0-R7]
+	MOVM.DB.W [R0-R7], (R(TE))
+	B	_b32loop
+
+_b4tail:				/* do remaining words if possible */
+	MOVW	savedts-4(SP), R(TS)
+	ADD	$3, R(TS), R(TMP)
+_b4loop:
+	CMP	R(TMP), R(TE)
+	BLS	_b1tail
+
+	MOVW.W	-4(R(FROM)), R(TMP1)	/* pre-indexed */
+	MOVW.W	R(TMP1), -4(R(TE))	/* pre-indexed */
+	B	_b4loop
+
+_b1tail:				/* remaining bytes */
+	CMP	R(TE), R(TS)
+	BEQ	_return
+
+	MOVBU.W	-1(R(FROM)), R(TMP)	/* pre-indexed */
+	MOVBU.W	R(TMP), -1(R(TE))	/* pre-indexed */
+	B	_b1tail
+
+_forward:
+	CMP	$4, R(N)		/* need at least 4 bytes to copy */
+	BLT	_f1tail
+
+_f4align:				/* align destination on 4 */
+	AND.S	$3, R(TS), R(TMP)
+	BEQ	_f4aligned
+
+	MOVBU.P	1(R(FROM)), R(TMP)	/* implicit write back */
+	MOVBU.P	R(TMP), 1(R(TS))	/* implicit write back */
+	B	_f4align
+
+_f4aligned:				/* is source now aligned? */
+	AND.S	$3, R(FROM), R(TMP)
+	BNE	_funaligned
+
+	SUB	$31, R(TE), R(TMP)	/* do 32-byte chunks if possible */
+	MOVW	R(TE), savedte-4(SP)
+_f32loop:
+	CMP	R(TMP), R(TS)
+	BHS	_f4tail
+
+	MOVM.IA.W (R(FROM)), [R1-R8] 
+	MOVM.IA.W [R1-R8], (R(TS))
+	B	_f32loop
+
+_f4tail:
+	MOVW	savedte-4(SP), R(TE)
+	SUB	$3, R(TE), R(TMP)	/* do remaining words if possible */
+_f4loop:
+	CMP	R(TMP), R(TS)
+	BHS	_f1tail
+
+	MOVW.P	4(R(FROM)), R(TMP1)	/* implicit write back */
+	MOVW.P	R(TMP1), 4(R(TS))	/* implicit write back */
+	B	_f4loop
+
+_f1tail:
+	CMP	R(TS), R(TE)
+	BEQ	_return
+
+	MOVBU.P	1(R(FROM)), R(TMP)	/* implicit write back */
+	MOVBU.P	R(TMP), 1(R(TS))	/* implicit write back */
+	B	_f1tail
+
+_return:
+	MOVW	to+0(FP), R0
+	RET
+
+_bunaligned:
+	CMP	$2, R(TMP)		/* is R(TMP) < 2 ? */
+
+	MOVW.LT	$8, R(RSHIFT)		/* (R(n)<<24)|(R(n-1)>>8) */
+	MOVW.LT	$24, R(LSHIFT)
+	MOVW.LT	$1, R(OFFSET)
+
+	MOVW.EQ	$16, R(RSHIFT)		/* (R(n)<<16)|(R(n-1)>>16) */
+	MOVW.EQ	$16, R(LSHIFT)
+	MOVW.EQ	$2, R(OFFSET)
+
+	MOVW.GT	$24, R(RSHIFT)		/* (R(n)<<8)|(R(n-1)>>24) */
+	MOVW.GT	$8, R(LSHIFT)
+	MOVW.GT	$3, R(OFFSET)
+
+	ADD	$16, R(TS), R(TMP)	/* do 16-byte chunks if possible */
+	CMP	R(TMP), R(TE)
+	BLS	_b1tail
+
+	BIC	$3, R(FROM)		/* align source */
+	MOVW	R(TS), savedts-4(SP)
+	MOVW	(R(FROM)), R(BR0)	/* prime first block register */
+
+_bu16loop:
+	CMP	R(TMP), R(TE)
+	BLS	_bu1tail
+
+	MOVW	R(BR0)<<R(LSHIFT), R(BW3)
+	MOVM.DB.W (R(FROM)), [R(BR0)-R(BR3)]
+	ORR	R(BR3)>>R(RSHIFT), R(BW3)
+
+	MOVW	R(BR3)<<R(LSHIFT), R(BW2)
+	ORR	R(BR2)>>R(RSHIFT), R(BW2)
+
+	MOVW	R(BR2)<<R(LSHIFT), R(BW1)
+	ORR	R(BR1)>>R(RSHIFT), R(BW1)
+
+	MOVW	R(BR1)<<R(LSHIFT), R(BW0)
+	ORR	R(BR0)>>R(RSHIFT), R(BW0)
+
+	MOVM.DB.W [R(BW0)-R(BW3)], (R(TE))
+	B	_bu16loop
+
+_bu1tail:
+	MOVW	savedts-4(SP), R(TS)
+	ADD	R(OFFSET), R(FROM)
+	B	_b1tail
+
+_funaligned:
+	CMP	$2, R(TMP)
+
+	MOVW.LT	$8, R(RSHIFT)		/* (R(n+1)<<24)|(R(n)>>8) */
+	MOVW.LT	$24, R(LSHIFT)
+	MOVW.LT	$3, R(OFFSET)
+
+	MOVW.EQ	$16, R(RSHIFT)		/* (R(n+1)<<16)|(R(n)>>16) */
+	MOVW.EQ	$16, R(LSHIFT)
+	MOVW.EQ	$2, R(OFFSET)
+
+	MOVW.GT	$24, R(RSHIFT)		/* (R(n+1)<<8)|(R(n)>>24) */
+	MOVW.GT	$8, R(LSHIFT)
+	MOVW.GT	$1, R(OFFSET)
+
+	SUB	$16, R(TE), R(TMP)	/* do 16-byte chunks if possible */
+	CMP	R(TMP), R(TS)
+	BHS	_f1tail
+
+	BIC	$3, R(FROM)		/* align source */
+	MOVW	R(TE), savedte-4(SP)
+	MOVW.P	4(R(FROM)), R(FR3)	/* prime last block register, implicit write back */
+
+_fu16loop:
+	CMP	R(TMP), R(TS)
+	BHS	_fu1tail
+
+	MOVW	R(FR3)>>R(RSHIFT), R(FW0)
+	MOVM.IA.W (R(FROM)), [R(FR0),R(FR1),R(FR2),R(FR3)]
+	ORR	R(FR0)<<R(LSHIFT), R(FW0)
+
+	MOVW	R(FR0)>>R(RSHIFT), R(FW1)
+	ORR	R(FR1)<<R(LSHIFT), R(FW1)
+
+	MOVW	R(FR1)>>R(RSHIFT), R(FW2)
+	ORR	R(FR2)<<R(LSHIFT), R(FW2)
+
+	MOVW	R(FR2)>>R(RSHIFT), R(FW3)
+	ORR	R(FR3)<<R(LSHIFT), R(FW3)
+
+	MOVM.IA.W [R(FW0),R(FW1),R(FW2),R(FW3)], (R(TS))
+	B	_fu16loop
+
+_fu1tail:
+	MOVW	savedte-4(SP), R(TE)
+	SUB	R(OFFSET), R(FROM)
+	B	_f1tail
diff --git a/src/pkg/runtime/memmove_linux_amd64_test.go b/src/runtime/memmove_linux_amd64_test.go
similarity index 100%
rename from src/pkg/runtime/memmove_linux_amd64_test.go
rename to src/runtime/memmove_linux_amd64_test.go
diff --git a/src/runtime/memmove_nacl_amd64p32.s b/src/runtime/memmove_nacl_amd64p32.s
new file mode 100644
index 0000000..373607a
--- /dev/null
+++ b/src/runtime/memmove_nacl_amd64p32.s
@@ -0,0 +1,46 @@
+// Copyright 2013 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+TEXT runtime·memmove(SB), NOSPLIT, $0-12
+	MOVL	to+0(FP), DI
+	MOVL	from+4(FP), SI
+	MOVL	n+8(FP), BX
+
+	CMPL	SI, DI
+	JLS back
+
+forward:
+	MOVL	BX, CX
+	SHRL	$3, CX
+	ANDL	$7, BX
+	REP; MOVSQ
+	MOVL	BX, CX
+	REP; MOVSB
+	RET
+
+back:
+	MOVL	SI, CX
+	ADDL	BX, CX
+	CMPL	CX, DI
+	JLS forward
+
+	ADDL	BX, DI
+	ADDL	BX, SI
+	STD
+	
+	MOVL	BX, CX
+	SHRL	$3, CX
+	ANDL	$7, BX
+	SUBL	$8, DI
+	SUBL	$8, SI
+	REP; MOVSQ
+	ADDL	$7, DI
+	ADDL	$7, SI
+	MOVL	BX, CX
+	REP; MOVSB
+	CLD
+
+	RET
diff --git a/src/runtime/memmove_plan9_386.s b/src/runtime/memmove_plan9_386.s
new file mode 100644
index 0000000..025d4ce
--- /dev/null
+++ b/src/runtime/memmove_plan9_386.s
@@ -0,0 +1,128 @@
+// Inferno's libkern/memmove-386.s
+// http://code.google.com/p/inferno-os/source/browse/libkern/memmove-386.s
+//
+//         Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
+//         Revisions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com).  All rights reserved.
+//         Portions Copyright 2009 The Go Authors. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#include "textflag.h"
+
+TEXT runtime·memmove(SB), NOSPLIT, $0-12
+	MOVL	to+0(FP), DI
+	MOVL	from+4(FP), SI
+	MOVL	n+8(FP), BX
+
+	// REP instructions have a high startup cost, so we handle small sizes
+	// with some straightline code.  The REP MOVSL instruction is really fast
+	// for large sizes.  The cutover is approximately 1K.
+tail:
+	TESTL	BX, BX
+	JEQ	move_0
+	CMPL	BX, $2
+	JBE	move_1or2
+	CMPL	BX, $4
+	JBE	move_3or4
+	CMPL	BX, $8
+	JBE	move_5through8
+	CMPL	BX, $16
+	JBE	move_9through16
+
+/*
+ * check and set for backwards
+ */
+	CMPL	SI, DI
+	JLS	back
+
+/*
+ * forward copy loop
+ */
+forward:	
+	MOVL	BX, CX
+	SHRL	$2, CX
+	ANDL	$3, BX
+
+	REP;	MOVSL
+	JMP	tail
+/*
+ * check overlap
+ */
+back:
+	MOVL	SI, CX
+	ADDL	BX, CX
+	CMPL	CX, DI
+	JLS	forward
+/*
+ * whole thing backwards has
+ * adjusted addresses
+ */
+
+	ADDL	BX, DI
+	ADDL	BX, SI
+	STD
+
+/*
+ * copy
+ */
+	MOVL	BX, CX
+	SHRL	$2, CX
+	ANDL	$3, BX
+
+	SUBL	$4, DI
+	SUBL	$4, SI
+	REP;	MOVSL
+
+	CLD
+	ADDL	$4, DI
+	ADDL	$4, SI
+	SUBL	BX, DI
+	SUBL	BX, SI
+	JMP	tail
+
+move_1or2:
+	MOVB	(SI), AX
+	MOVB	-1(SI)(BX*1), CX
+	MOVB	AX, (DI)
+	MOVB	CX, -1(DI)(BX*1)
+	RET
+move_0:
+	RET
+move_3or4:
+	MOVW	(SI), AX
+	MOVW	-2(SI)(BX*1), CX
+	MOVW	AX, (DI)
+	MOVW	CX, -2(DI)(BX*1)
+	RET
+move_5through8:
+	MOVL	(SI), AX
+	MOVL	-4(SI)(BX*1), CX
+	MOVL	AX, (DI)
+	MOVL	CX, -4(DI)(BX*1)
+	RET
+move_9through16:
+	MOVL	(SI), AX
+	MOVL	4(SI), CX
+	MOVL	-8(SI)(BX*1), DX
+	MOVL	-4(SI)(BX*1), BP
+	MOVL	AX, (DI)
+	MOVL	CX, 4(DI)
+	MOVL	DX, -8(DI)(BX*1)
+	MOVL	BP, -4(DI)(BX*1)
+	RET
diff --git a/src/runtime/memmove_plan9_amd64.s b/src/runtime/memmove_plan9_amd64.s
new file mode 100644
index 0000000..8e96b87
--- /dev/null
+++ b/src/runtime/memmove_plan9_amd64.s
@@ -0,0 +1,127 @@
+// Derived from Inferno's libkern/memmove-386.s (adapted for amd64)
+// http://code.google.com/p/inferno-os/source/browse/libkern/memmove-386.s
+//
+//         Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
+//         Revisions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com).  All rights reserved.
+//         Portions Copyright 2009 The Go Authors. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#include "textflag.h"
+
+// void runtime·memmove(void*, void*, uintptr)
+TEXT runtime·memmove(SB), NOSPLIT, $0-24
+
+	MOVQ	to+0(FP), DI
+	MOVQ	from+8(FP), SI
+	MOVQ	n+16(FP), BX
+
+	// REP instructions have a high startup cost, so we handle small sizes
+	// with some straightline code.  The REP MOVSQ instruction is really fast
+	// for large sizes.  The cutover is approximately 1K.
+tail:
+	TESTQ	BX, BX
+	JEQ	move_0
+	CMPQ	BX, $2
+	JBE	move_1or2
+	CMPQ	BX, $4
+	JBE	move_3or4
+	CMPQ	BX, $8
+	JBE	move_5through8
+	CMPQ	BX, $16
+	JBE	move_9through16
+
+/*
+ * check and set for backwards
+ */
+	CMPQ	SI, DI
+	JLS	back
+
+/*
+ * forward copy loop
+ */
+forward:
+	MOVQ	BX, CX
+	SHRQ	$3, CX
+	ANDQ	$7, BX
+
+	REP;	MOVSQ
+	JMP	tail
+
+back:
+/*
+ * check overlap
+ */
+	MOVQ	SI, CX
+	ADDQ	BX, CX
+	CMPQ	CX, DI
+	JLS	forward
+	
+/*
+ * whole thing backwards has
+ * adjusted addresses
+ */
+	ADDQ	BX, DI
+	ADDQ	BX, SI
+	STD
+
+/*
+ * copy
+ */
+	MOVQ	BX, CX
+	SHRQ	$3, CX
+	ANDQ	$7, BX
+
+	SUBQ	$8, DI
+	SUBQ	$8, SI
+	REP;	MOVSQ
+
+	CLD
+	ADDQ	$8, DI
+	ADDQ	$8, SI
+	SUBQ	BX, DI
+	SUBQ	BX, SI
+	JMP	tail
+
+move_1or2:
+	MOVB	(SI), AX
+	MOVB	-1(SI)(BX*1), CX
+	MOVB	AX, (DI)
+	MOVB	CX, -1(DI)(BX*1)
+	RET
+move_0:
+	RET
+move_3or4:
+	MOVW	(SI), AX
+	MOVW	-2(SI)(BX*1), CX
+	MOVW	AX, (DI)
+	MOVW	CX, -2(DI)(BX*1)
+	RET
+move_5through8:
+	MOVL	(SI), AX
+	MOVL	-4(SI)(BX*1), CX
+	MOVL	AX, (DI)
+	MOVL	CX, -4(DI)(BX*1)
+	RET
+move_9through16:
+	MOVQ	(SI), AX
+	MOVQ	-8(SI)(BX*1), CX
+	MOVQ	AX, (DI)
+	MOVQ	CX, -8(DI)(BX*1)
+	RET
diff --git a/src/runtime/memmove_test.go b/src/runtime/memmove_test.go
new file mode 100644
index 0000000..ffda4fe
--- /dev/null
+++ b/src/runtime/memmove_test.go
@@ -0,0 +1,295 @@
+// Copyright 2013 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package runtime_test
+
+import (
+	. "runtime"
+	"testing"
+)
+
+func TestMemmove(t *testing.T) {
+	size := 256
+	if testing.Short() {
+		size = 128 + 16
+	}
+	src := make([]byte, size)
+	dst := make([]byte, size)
+	for i := 0; i < size; i++ {
+		src[i] = byte(128 + (i & 127))
+	}
+	for i := 0; i < size; i++ {
+		dst[i] = byte(i & 127)
+	}
+	for n := 0; n <= size; n++ {
+		for x := 0; x <= size-n; x++ { // offset in src
+			for y := 0; y <= size-n; y++ { // offset in dst
+				copy(dst[y:y+n], src[x:x+n])
+				for i := 0; i < y; i++ {
+					if dst[i] != byte(i&127) {
+						t.Fatalf("prefix dst[%d] = %d", i, dst[i])
+					}
+				}
+				for i := y; i < y+n; i++ {
+					if dst[i] != byte(128+((i-y+x)&127)) {
+						t.Fatalf("copied dst[%d] = %d", i, dst[i])
+					}
+					dst[i] = byte(i & 127) // reset dst
+				}
+				for i := y + n; i < size; i++ {
+					if dst[i] != byte(i&127) {
+						t.Fatalf("suffix dst[%d] = %d", i, dst[i])
+					}
+				}
+			}
+		}
+	}
+}
+
+func TestMemmoveAlias(t *testing.T) {
+	size := 256
+	if testing.Short() {
+		size = 128 + 16
+	}
+	buf := make([]byte, size)
+	for i := 0; i < size; i++ {
+		buf[i] = byte(i)
+	}
+	for n := 0; n <= size; n++ {
+		for x := 0; x <= size-n; x++ { // src offset
+			for y := 0; y <= size-n; y++ { // dst offset
+				copy(buf[y:y+n], buf[x:x+n])
+				for i := 0; i < y; i++ {
+					if buf[i] != byte(i) {
+						t.Fatalf("prefix buf[%d] = %d", i, buf[i])
+					}
+				}
+				for i := y; i < y+n; i++ {
+					if buf[i] != byte(i-y+x) {
+						t.Fatalf("copied buf[%d] = %d", i, buf[i])
+					}
+					buf[i] = byte(i) // reset buf
+				}
+				for i := y + n; i < size; i++ {
+					if buf[i] != byte(i) {
+						t.Fatalf("suffix buf[%d] = %d", i, buf[i])
+					}
+				}
+			}
+		}
+	}
+}
+
+func bmMemmove(b *testing.B, n int) {
+	x := make([]byte, n)
+	y := make([]byte, n)
+	b.SetBytes(int64(n))
+	for i := 0; i < b.N; i++ {
+		copy(x, y)
+	}
+}
+
+func BenchmarkMemmove0(b *testing.B)    { bmMemmove(b, 0) }
+func BenchmarkMemmove1(b *testing.B)    { bmMemmove(b, 1) }
+func BenchmarkMemmove2(b *testing.B)    { bmMemmove(b, 2) }
+func BenchmarkMemmove3(b *testing.B)    { bmMemmove(b, 3) }
+func BenchmarkMemmove4(b *testing.B)    { bmMemmove(b, 4) }
+func BenchmarkMemmove5(b *testing.B)    { bmMemmove(b, 5) }
+func BenchmarkMemmove6(b *testing.B)    { bmMemmove(b, 6) }
+func BenchmarkMemmove7(b *testing.B)    { bmMemmove(b, 7) }
+func BenchmarkMemmove8(b *testing.B)    { bmMemmove(b, 8) }
+func BenchmarkMemmove9(b *testing.B)    { bmMemmove(b, 9) }
+func BenchmarkMemmove10(b *testing.B)   { bmMemmove(b, 10) }
+func BenchmarkMemmove11(b *testing.B)   { bmMemmove(b, 11) }
+func BenchmarkMemmove12(b *testing.B)   { bmMemmove(b, 12) }
+func BenchmarkMemmove13(b *testing.B)   { bmMemmove(b, 13) }
+func BenchmarkMemmove14(b *testing.B)   { bmMemmove(b, 14) }
+func BenchmarkMemmove15(b *testing.B)   { bmMemmove(b, 15) }
+func BenchmarkMemmove16(b *testing.B)   { bmMemmove(b, 16) }
+func BenchmarkMemmove32(b *testing.B)   { bmMemmove(b, 32) }
+func BenchmarkMemmove64(b *testing.B)   { bmMemmove(b, 64) }
+func BenchmarkMemmove128(b *testing.B)  { bmMemmove(b, 128) }
+func BenchmarkMemmove256(b *testing.B)  { bmMemmove(b, 256) }
+func BenchmarkMemmove512(b *testing.B)  { bmMemmove(b, 512) }
+func BenchmarkMemmove1024(b *testing.B) { bmMemmove(b, 1024) }
+func BenchmarkMemmove2048(b *testing.B) { bmMemmove(b, 2048) }
+func BenchmarkMemmove4096(b *testing.B) { bmMemmove(b, 4096) }
+
+func TestMemclr(t *testing.T) {
+	size := 512
+	if testing.Short() {
+		size = 128 + 16
+	}
+	mem := make([]byte, size)
+	for i := 0; i < size; i++ {
+		mem[i] = 0xee
+	}
+	for n := 0; n < size; n++ {
+		for x := 0; x <= size-n; x++ { // offset in mem
+			MemclrBytes(mem[x : x+n])
+			for i := 0; i < x; i++ {
+				if mem[i] != 0xee {
+					t.Fatalf("overwrite prefix mem[%d] = %d", i, mem[i])
+				}
+			}
+			for i := x; i < x+n; i++ {
+				if mem[i] != 0 {
+					t.Fatalf("failed clear mem[%d] = %d", i, mem[i])
+				}
+				mem[i] = 0xee
+			}
+			for i := x + n; i < size; i++ {
+				if mem[i] != 0xee {
+					t.Fatalf("overwrite suffix mem[%d] = %d", i, mem[i])
+				}
+			}
+		}
+	}
+}
+
+func bmMemclr(b *testing.B, n int) {
+	x := make([]byte, n)
+	b.SetBytes(int64(n))
+	for i := 0; i < b.N; i++ {
+		MemclrBytes(x)
+	}
+}
+func BenchmarkMemclr5(b *testing.B)     { bmMemclr(b, 5) }
+func BenchmarkMemclr16(b *testing.B)    { bmMemclr(b, 16) }
+func BenchmarkMemclr64(b *testing.B)    { bmMemclr(b, 64) }
+func BenchmarkMemclr256(b *testing.B)   { bmMemclr(b, 256) }
+func BenchmarkMemclr4096(b *testing.B)  { bmMemclr(b, 4096) }
+func BenchmarkMemclr65536(b *testing.B) { bmMemclr(b, 65536) }
+
+func BenchmarkClearFat8(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		var x [8 / 4]uint32
+		_ = x
+	}
+}
+func BenchmarkClearFat12(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		var x [12 / 4]uint32
+		_ = x
+	}
+}
+func BenchmarkClearFat16(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		var x [16 / 4]uint32
+		_ = x
+	}
+}
+func BenchmarkClearFat24(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		var x [24 / 4]uint32
+		_ = x
+	}
+}
+func BenchmarkClearFat32(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		var x [32 / 4]uint32
+		_ = x
+	}
+}
+func BenchmarkClearFat64(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		var x [64 / 4]uint32
+		_ = x
+	}
+}
+func BenchmarkClearFat128(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		var x [128 / 4]uint32
+		_ = x
+	}
+}
+func BenchmarkClearFat256(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		var x [256 / 4]uint32
+		_ = x
+	}
+}
+func BenchmarkClearFat512(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		var x [512 / 4]uint32
+		_ = x
+	}
+}
+func BenchmarkClearFat1024(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		var x [1024 / 4]uint32
+		_ = x
+	}
+}
+
+func BenchmarkCopyFat8(b *testing.B) {
+	var x [8 / 4]uint32
+	for i := 0; i < b.N; i++ {
+		y := x
+		_ = y
+	}
+}
+func BenchmarkCopyFat12(b *testing.B) {
+	var x [12 / 4]uint32
+	for i := 0; i < b.N; i++ {
+		y := x
+		_ = y
+	}
+}
+func BenchmarkCopyFat16(b *testing.B) {
+	var x [16 / 4]uint32
+	for i := 0; i < b.N; i++ {
+		y := x
+		_ = y
+	}
+}
+func BenchmarkCopyFat24(b *testing.B) {
+	var x [24 / 4]uint32
+	for i := 0; i < b.N; i++ {
+		y := x
+		_ = y
+	}
+}
+func BenchmarkCopyFat32(b *testing.B) {
+	var x [32 / 4]uint32
+	for i := 0; i < b.N; i++ {
+		y := x
+		_ = y
+	}
+}
+func BenchmarkCopyFat64(b *testing.B) {
+	var x [64 / 4]uint32
+	for i := 0; i < b.N; i++ {
+		y := x
+		_ = y
+	}
+}
+func BenchmarkCopyFat128(b *testing.B) {
+	var x [128 / 4]uint32
+	for i := 0; i < b.N; i++ {
+		y := x
+		_ = y
+	}
+}
+func BenchmarkCopyFat256(b *testing.B) {
+	var x [256 / 4]uint32
+	for i := 0; i < b.N; i++ {
+		y := x
+		_ = y
+	}
+}
+func BenchmarkCopyFat512(b *testing.B) {
+	var x [512 / 4]uint32
+	for i := 0; i < b.N; i++ {
+		y := x
+		_ = y
+	}
+}
+func BenchmarkCopyFat1024(b *testing.B) {
+	var x [1024 / 4]uint32
+	for i := 0; i < b.N; i++ {
+		y := x
+		_ = y
+	}
+}
diff --git a/src/runtime/mfinal_test.go b/src/runtime/mfinal_test.go
new file mode 100644
index 0000000..d2cead2
--- /dev/null
+++ b/src/runtime/mfinal_test.go
@@ -0,0 +1,246 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package runtime_test
+
+import (
+	"runtime"
+	"testing"
+	"time"
+	"unsafe"
+)
+
+type Tintptr *int // assignable to *int
+type Tint int     // *Tint implements Tinter, interface{}
+
+func (t *Tint) m() {}
+
+type Tinter interface {
+	m()
+}
+
+func TestFinalizerType(t *testing.T) {
+	if runtime.GOARCH != "amd64" {
+		t.Skipf("Skipping on non-amd64 machine")
+	}
+
+	ch := make(chan bool, 10)
+	finalize := func(x *int) {
+		if *x != 97531 {
+			t.Errorf("finalizer %d, want %d", *x, 97531)
+		}
+		ch <- true
+	}
+
+	var finalizerTests = []struct {
+		convert   func(*int) interface{}
+		finalizer interface{}
+	}{
+		{func(x *int) interface{} { return x }, func(v *int) { finalize(v) }},
+		{func(x *int) interface{} { return Tintptr(x) }, func(v Tintptr) { finalize(v) }},
+		{func(x *int) interface{} { return Tintptr(x) }, func(v *int) { finalize(v) }},
+		{func(x *int) interface{} { return (*Tint)(x) }, func(v *Tint) { finalize((*int)(v)) }},
+		{func(x *int) interface{} { return (*Tint)(x) }, func(v Tinter) { finalize((*int)(v.(*Tint))) }},
+	}
+
+	for i, tt := range finalizerTests {
+		done := make(chan bool, 1)
+		go func() {
+			// allocate struct with pointer to avoid hitting tinyalloc.
+			// Otherwise we can't be sure when the allocation will
+			// be freed.
+			type T struct {
+				v int
+				p unsafe.Pointer
+			}
+			v := &new(T).v
+			*v = 97531
+			runtime.SetFinalizer(tt.convert(v), tt.finalizer)
+			v = nil
+			done <- true
+		}()
+		<-done
+		runtime.GC()
+		select {
+		case <-ch:
+		case <-time.After(time.Second * 4):
+			t.Errorf("#%d: finalizer for type %T didn't run", i, tt.finalizer)
+		}
+	}
+}
+
+type bigValue struct {
+	fill uint64
+	it   bool
+	up   string
+}
+
+func TestFinalizerInterfaceBig(t *testing.T) {
+	if runtime.GOARCH != "amd64" {
+		t.Skipf("Skipping on non-amd64 machine")
+	}
+	ch := make(chan bool)
+	done := make(chan bool, 1)
+	go func() {
+		v := &bigValue{0xDEADBEEFDEADBEEF, true, "It matters not how strait the gate"}
+		old := *v
+		runtime.SetFinalizer(v, func(v interface{}) {
+			i, ok := v.(*bigValue)
+			if !ok {
+				t.Errorf("finalizer called with type %T, want *bigValue", v)
+			}
+			if *i != old {
+				t.Errorf("finalizer called with %+v, want %+v", *i, old)
+			}
+			close(ch)
+		})
+		v = nil
+		done <- true
+	}()
+	<-done
+	runtime.GC()
+	select {
+	case <-ch:
+	case <-time.After(4 * time.Second):
+		t.Errorf("finalizer for type *bigValue didn't run")
+	}
+}
+
+func fin(v *int) {
+}
+
+// Verify we don't crash at least. golang.org/issue/6857
+func TestFinalizerZeroSizedStruct(t *testing.T) {
+	type Z struct{}
+	z := new(Z)
+	runtime.SetFinalizer(z, func(*Z) {})
+}
+
+func BenchmarkFinalizer(b *testing.B) {
+	const Batch = 1000
+	b.RunParallel(func(pb *testing.PB) {
+		var data [Batch]*int
+		for i := 0; i < Batch; i++ {
+			data[i] = new(int)
+		}
+		for pb.Next() {
+			for i := 0; i < Batch; i++ {
+				runtime.SetFinalizer(data[i], fin)
+			}
+			for i := 0; i < Batch; i++ {
+				runtime.SetFinalizer(data[i], nil)
+			}
+		}
+	})
+}
+
+func BenchmarkFinalizerRun(b *testing.B) {
+	b.RunParallel(func(pb *testing.PB) {
+		for pb.Next() {
+			v := new(int)
+			runtime.SetFinalizer(v, fin)
+		}
+	})
+}
+
+// One chunk must be exactly one sizeclass in size.
+// It should be a sizeclass not used much by others, so we
+// have a greater chance of finding adjacent ones.
+// size class 19: 320 byte objects, 25 per page, 1 page alloc at a time
+const objsize = 320
+
+type objtype [objsize]byte
+
+func adjChunks() (*objtype, *objtype) {
+	var s []*objtype
+
+	for {
+		c := new(objtype)
+		for _, d := range s {
+			if uintptr(unsafe.Pointer(c))+unsafe.Sizeof(*c) == uintptr(unsafe.Pointer(d)) {
+				return c, d
+			}
+			if uintptr(unsafe.Pointer(d))+unsafe.Sizeof(*c) == uintptr(unsafe.Pointer(c)) {
+				return d, c
+			}
+		}
+		s = append(s, c)
+	}
+}
+
+// Make sure an empty slice on the stack doesn't pin the next object in memory.
+func TestEmptySlice(t *testing.T) {
+	if true { // disable until bug 7564 is fixed.
+		return
+	}
+	x, y := adjChunks()
+
+	// the pointer inside xs points to y.
+	xs := x[objsize:] // change objsize to objsize-1 and the test passes
+
+	fin := make(chan bool, 1)
+	runtime.SetFinalizer(y, func(z *objtype) { fin <- true })
+	runtime.GC()
+	select {
+	case <-fin:
+	case <-time.After(4 * time.Second):
+		t.Errorf("finalizer of next object in memory didn't run")
+	}
+	xsglobal = xs // keep empty slice alive until here
+}
+
+var xsglobal []byte
+
+func adjStringChunk() (string, *objtype) {
+	b := make([]byte, objsize)
+	for {
+		s := string(b)
+		t := new(objtype)
+		p := *(*uintptr)(unsafe.Pointer(&s))
+		q := uintptr(unsafe.Pointer(t))
+		if p+objsize == q {
+			return s, t
+		}
+	}
+}
+
+// Make sure an empty string on the stack doesn't pin the next object in memory.
+func TestEmptyString(t *testing.T) {
+	x, y := adjStringChunk()
+
+	ss := x[objsize:] // change objsize to objsize-1 and the test passes
+	fin := make(chan bool, 1)
+	// set finalizer on string contents of y
+	runtime.SetFinalizer(y, func(z *objtype) { fin <- true })
+	runtime.GC()
+	select {
+	case <-fin:
+	case <-time.After(4 * time.Second):
+		t.Errorf("finalizer of next string in memory didn't run")
+	}
+	ssglobal = ss // keep 0-length string live until here
+}
+
+var ssglobal string
+
+// Test for issue 7656.
+func TestFinalizerOnGlobal(t *testing.T) {
+	runtime.SetFinalizer(Foo1, func(p *Object1) {})
+	runtime.SetFinalizer(Foo2, func(p *Object2) {})
+	runtime.SetFinalizer(Foo1, nil)
+	runtime.SetFinalizer(Foo2, nil)
+}
+
+type Object1 struct {
+	Something []byte
+}
+
+type Object2 struct {
+	Something byte
+}
+
+var (
+	Foo2 = &Object2{}
+	Foo1 = &Object1{}
+)
diff --git a/src/pkg/runtime/mfixalloc.c b/src/runtime/mfixalloc.c
similarity index 100%
rename from src/pkg/runtime/mfixalloc.c
rename to src/runtime/mfixalloc.c
diff --git a/src/runtime/mgc0.c b/src/runtime/mgc0.c
new file mode 100644
index 0000000..7754bad
--- /dev/null
+++ b/src/runtime/mgc0.c
@@ -0,0 +1,2010 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Garbage collector (GC).
+//
+// GC is:
+// - mark&sweep
+// - mostly precise (with the exception of some C-allocated objects, assembly frames/arguments, etc)
+// - parallel (up to MaxGcproc threads)
+// - partially concurrent (mark is stop-the-world, while sweep is concurrent)
+// - non-moving/non-compacting
+// - full (non-partial)
+//
+// GC rate.
+// Next GC is after we've allocated an extra amount of memory proportional to
+// the amount already in use. The proportion is controlled by GOGC environment variable
+// (100 by default). If GOGC=100 and we're using 4M, we'll GC again when we get to 8M
+// (this mark is tracked in next_gc variable). This keeps the GC cost in linear
+// proportion to the allocation cost. Adjusting GOGC just changes the linear constant
+// (and also the amount of extra memory used).
+//
+// Concurrent sweep.
+// The sweep phase proceeds concurrently with normal program execution.
+// The heap is swept span-by-span both lazily (when a goroutine needs another span)
+// and concurrently in a background goroutine (this helps programs that are not CPU bound).
+// However, at the end of the stop-the-world GC phase we don't know the size of the live heap,
+// and so next_gc calculation is tricky and happens as follows.
+// At the end of the stop-the-world phase next_gc is conservatively set based on total
+// heap size; all spans are marked as "needs sweeping".
+// Whenever a span is swept, next_gc is decremented by GOGC*newly_freed_memory.
+// The background sweeper goroutine simply sweeps spans one-by-one bringing next_gc
+// closer to the target value. However, this is not enough to avoid over-allocating memory.
+// Consider that a goroutine wants to allocate a new span for a large object and
+// there are no free swept spans, but there are small-object unswept spans.
+// If the goroutine naively allocates a new span, it can surpass the yet-unknown
+// target next_gc value. In order to prevent such cases (1) when a goroutine needs
+// to allocate a new small-object span, it sweeps small-object spans for the same
+// object size until it frees at least one object; (2) when a goroutine needs to
+// allocate large-object span from heap, it sweeps spans until it frees at least
+// that many pages into heap. Together these two measures ensure that we don't surpass
+// target next_gc value by a large margin. There is an exception: if a goroutine sweeps
+// and frees two nonadjacent one-page spans to the heap, it will allocate a new two-page span,
+// but there can still be other one-page unswept spans which could be combined into a two-page span.
+// It's critical to ensure that no operations proceed on unswept spans (that would corrupt
+// mark bits in GC bitmap). During GC all mcaches are flushed into the central cache,
+// so they are empty. When a goroutine grabs a new span into mcache, it sweeps it.
+// When a goroutine explicitly frees an object or sets a finalizer, it ensures that
+// the span is swept (either by sweeping it, or by waiting for the concurrent sweep to finish).
+// The finalizer goroutine is kicked off only when all spans are swept.
+// When the next GC starts, it sweeps all not-yet-swept spans (if any).
+
+#include "runtime.h"
+#include "arch_GOARCH.h"
+#include "malloc.h"
+#include "stack.h"
+#include "mgc0.h"
+#include "chan.h"
+#include "race.h"
+#include "type.h"
+#include "typekind.h"
+#include "funcdata.h"
+#include "textflag.h"
+
+enum {
+	Debug		= 0,
+	DebugPtrs	= 0, // if 1, print trace of every pointer load during GC
+	ConcurrentSweep	= 1,
+
+	WorkbufSize	= 4*1024,
+	FinBlockSize	= 4*1024,
+	RootData	= 0,
+	RootBss		= 1,
+	RootFinalizers	= 2,
+	RootSpans	= 3,
+	RootFlushCaches = 4,
+	RootCount	= 5,
+};
+
+// ptrmask for an allocation containing a single pointer.
+static byte oneptr[] = {BitsPointer};
+
+// Initialized from $GOGC.  GOGC=off means no gc.
+extern int32 runtime·gcpercent;
+
+// Holding worldsema grants an M the right to try to stop the world.
+// The procedure is:
+//
+//	runtime·semacquire(&runtime·worldsema);
+//	m->gcing = 1;
+//	runtime·stoptheworld();
+//
+//	... do stuff ...
+//
+//	m->gcing = 0;
+//	runtime·semrelease(&runtime·worldsema);
+//	runtime·starttheworld();
+//
+uint32 runtime·worldsema = 1;
+
+typedef struct Workbuf Workbuf;
+struct Workbuf
+{
+	LFNode	node; // must be first
+	uintptr	nobj;
+	byte*	obj[(WorkbufSize-sizeof(LFNode)-sizeof(uintptr))/PtrSize];
+};
+
+extern byte runtime·data[];
+extern byte runtime·edata[];
+extern byte runtime·bss[];
+extern byte runtime·ebss[];
+
+extern byte runtime·gcdata[];
+extern byte runtime·gcbss[];
+
+Mutex	runtime·finlock;	// protects the following variables
+G*	runtime·fing;		// goroutine that runs finalizers
+FinBlock*	runtime·finq;	// list of finalizers that are to be executed
+FinBlock*	runtime·finc;	// cache of free blocks
+static byte finptrmask[FinBlockSize/PtrSize/PointersPerByte];
+bool	runtime·fingwait;
+bool	runtime·fingwake;
+FinBlock	*runtime·allfin;	// list of all blocks
+
+BitVector	runtime·gcdatamask;
+BitVector	runtime·gcbssmask;
+
+Mutex	runtime·gclock;
+
+static	uintptr	badblock[1024];
+static	int32	nbadblock;
+
+static Workbuf* getempty(Workbuf*);
+static Workbuf* getfull(Workbuf*);
+static void	putempty(Workbuf*);
+static Workbuf* handoff(Workbuf*);
+static void	gchelperstart(void);
+static void	flushallmcaches(void);
+static bool	scanframe(Stkframe *frame, void *unused);
+static void	scanstack(G *gp);
+static BitVector	unrollglobgcprog(byte *prog, uintptr size);
+
+void runtime·bgsweep(void);
+static FuncVal bgsweepv = {runtime·bgsweep};
+
+typedef struct WorkData WorkData;
+struct WorkData {
+	uint64	full;  // lock-free list of full blocks
+	uint64	empty; // lock-free list of empty blocks
+	byte	pad0[CacheLineSize]; // prevents false-sharing between full/empty and nproc/nwait
+	uint32	nproc;
+	int64	tstart;
+	volatile uint32	nwait;
+	volatile uint32	ndone;
+	Note	alldone;
+	ParFor*	markfor;
+
+	// Copy of mheap.allspans for marker or sweeper.
+	MSpan**	spans;
+	uint32	nspan;
+};
+WorkData runtime·work;
+
+// Is _cgo_allocate linked into the binary?
+static bool
+have_cgo_allocate(void)
+{
+	extern	byte	go·weak·runtime·_cgo_allocate_internal[1];
+	return go·weak·runtime·_cgo_allocate_internal != nil;
+}
+
+// scanblock scans a block of n bytes starting at pointer b for references
+// to other objects, scanning any it finds recursively until there are no
+// unscanned objects left.  Instead of using an explicit recursion, it keeps
+// a work list in the Workbuf* structures and loops in the main function
+// body.  Keeping an explicit work list is easier on the stack allocator and
+// more efficient.
+static void
+scanblock(byte *b, uintptr n, byte *ptrmask)
+{
+	byte *obj, *obj0, *p, *arena_start, *arena_used, **wp, *scanbuf[8], *ptrbitp, *bitp;
+	uintptr i, j, nobj, size, idx, x, off, scanbufpos, bits, xbits, shift;
+	Workbuf *wbuf;
+	Iface *iface;
+	Eface *eface;
+	Type *typ;
+	MSpan *s;
+	pageID k;
+	bool keepworking;
+
+	// Cache memory arena parameters in local vars.
+	arena_start = runtime·mheap.arena_start;
+	arena_used = runtime·mheap.arena_used;
+
+	wbuf = getempty(nil);
+	nobj = wbuf->nobj;
+	wp = &wbuf->obj[nobj];
+	keepworking = b == nil;
+	scanbufpos = 0;
+	for(i = 0; i < nelem(scanbuf); i++)
+		scanbuf[i] = nil;
+
+	ptrbitp = nil;
+
+	// ptrmask can have 2 possible values:
+	// 1. nil - obtain pointer mask from GC bitmap.
+	// 2. pointer to a compact mask (for stacks and data).
+	if(b != nil)
+		goto scanobj;
+	for(;;) {
+		if(nobj == 0) {
+			// Out of work in workbuf.
+			// First, see is there is any work in scanbuf.
+			for(i = 0; i < nelem(scanbuf); i++) {
+				b = scanbuf[scanbufpos];
+				scanbuf[scanbufpos++] = nil;
+				scanbufpos %= nelem(scanbuf);
+				if(b != nil) {
+					n = arena_used - b; // scan until bitBoundary or BitsDead
+					ptrmask = nil; // use GC bitmap for pointer info
+					goto scanobj;
+				}
+			}
+			if(!keepworking) {
+				putempty(wbuf);
+				return;
+			}
+			// Refill workbuf from global queue.
+			wbuf = getfull(wbuf);
+			if(wbuf == nil)
+				return;
+			nobj = wbuf->nobj;
+			wp = &wbuf->obj[nobj];
+		}
+
+		// If another proc wants a pointer, give it some.
+		if(runtime·work.nwait > 0 && nobj > 4 && runtime·work.full == 0) {
+			wbuf->nobj = nobj;
+			wbuf = handoff(wbuf);
+			nobj = wbuf->nobj;
+			wp = &wbuf->obj[nobj];
+		}
+
+		wp--;
+		nobj--;
+		b = *wp;
+		n = arena_used - b; // scan until next bitBoundary or BitsDead
+		ptrmask = nil; // use GC bitmap for pointer info
+
+	scanobj:
+		if(DebugPtrs)
+			runtime·printf("scanblock %p +%p %p\n", b, n, ptrmask);
+		// Find bits of the beginning of the object.
+		if(ptrmask == nil) {
+			off = (uintptr*)b - (uintptr*)arena_start;
+			ptrbitp = arena_start - off/wordsPerBitmapByte - 1;
+		}
+		for(i = 0; i < n; i += PtrSize) {
+			obj = nil;
+			// Find bits for this word.
+			if(ptrmask == nil) {
+				// Check is we have reached end of span.
+				if((((uintptr)b+i)%PageSize) == 0 &&
+					runtime·mheap.spans[(b-arena_start)>>PageShift] != runtime·mheap.spans[(b+i-arena_start)>>PageShift])
+					break;
+				// Consult GC bitmap.
+				bits = *ptrbitp;
+
+				if(wordsPerBitmapByte != 2)
+					runtime·throw("alg doesn't work for wordsPerBitmapByte != 2");
+				j = ((uintptr)b+i)/PtrSize & 1;
+				ptrbitp -= j;
+				bits >>= gcBits*j;
+
+				if((bits&bitBoundary) != 0 && i != 0)
+					break; // reached beginning of the next object
+				bits = (bits>>2)&BitsMask;
+				if(bits == BitsDead)
+					break; // reached no-scan part of the object
+			} else // dense mask (stack or data)
+				bits = (ptrmask[(i/PtrSize)/4]>>(((i/PtrSize)%4)*BitsPerPointer))&BitsMask;
+
+			if(bits <= BitsScalar) // BitsScalar || BitsDead
+				continue;
+			if(bits == BitsPointer) {
+				obj = *(byte**)(b+i);
+				obj0 = obj;
+				goto markobj;
+			}
+
+			// With those three out of the way, must be multi-word.
+			if(Debug && bits != BitsMultiWord)
+				runtime·throw("unexpected garbage collection bits");
+			// Find the next pair of bits.
+			if(ptrmask == nil) {
+				bits = *ptrbitp;
+				j = ((uintptr)b+i+PtrSize)/PtrSize & 1;
+				ptrbitp -= j;
+				bits >>= gcBits*j;
+				bits = (bits>>2)&BitsMask;
+			} else
+				bits = (ptrmask[((i+PtrSize)/PtrSize)/4]>>((((i+PtrSize)/PtrSize)%4)*BitsPerPointer))&BitsMask;
+
+			if(Debug && bits != BitsIface && bits != BitsEface)
+				runtime·throw("unexpected garbage collection bits");
+
+			if(bits == BitsIface) {
+				iface = (Iface*)(b+i);
+				if(iface->tab != nil) {
+					typ = iface->tab->type;
+					if(!(typ->kind&KindDirectIface) || !(typ->kind&KindNoPointers))
+						obj = iface->data;
+				}
+			} else {
+				eface = (Eface*)(b+i);
+				typ = eface->type;
+				if(typ != nil) {
+					if(!(typ->kind&KindDirectIface) || !(typ->kind&KindNoPointers))
+						obj = eface->data;
+				}
+			}
+
+			i += PtrSize;
+
+			obj0 = obj;
+		markobj:
+			// At this point we have extracted the next potential pointer.
+			// Check if it points into heap.
+			if(obj == nil)
+				continue;
+			if(obj < arena_start || obj >= arena_used) {
+				if((uintptr)obj < PhysPageSize && runtime·invalidptr) {
+					s = nil;
+					goto badobj;
+				}
+				continue;
+			}
+			// Mark the object.
+			obj = (byte*)((uintptr)obj & ~(PtrSize-1));
+			off = (uintptr*)obj - (uintptr*)arena_start;
+			bitp = arena_start - off/wordsPerBitmapByte - 1;
+			shift = (off % wordsPerBitmapByte) * gcBits;
+			xbits = *bitp;
+			bits = (xbits >> shift) & bitMask;
+			if((bits&bitBoundary) == 0) {
+				// Not a beginning of a block, consult span table to find the block beginning.
+				k = (uintptr)obj>>PageShift;
+				x = k;
+				x -= (uintptr)arena_start>>PageShift;
+				s = runtime·mheap.spans[x];
+				if(s == nil || k < s->start || obj >= s->limit || s->state != MSpanInUse) {
+					// Stack pointers lie within the arena bounds but are not part of the GC heap.
+					// Ignore them.
+					if(s != nil && s->state == MSpanStack)
+						continue;
+				
+				badobj:
+					// If cgo_allocate is linked into the binary, it can allocate
+					// memory as []unsafe.Pointer that may not contain actual
+					// pointers and must be scanned conservatively.
+					// In this case alone, allow the bad pointer.
+					if(have_cgo_allocate() && ptrmask == nil)
+						continue;
+
+					// Anything else indicates a bug somewhere.
+					// If we're in the middle of chasing down a different bad pointer,
+					// don't confuse the trace by printing about this one.
+					if(nbadblock > 0)
+						continue;
+
+					runtime·printf("runtime: garbage collector found invalid heap pointer *(%p+%p)=%p", b, i, obj);
+					if(s == nil)
+						runtime·printf(" s=nil\n");
+					else
+						runtime·printf(" span=%p-%p-%p state=%d\n", (uintptr)s->start<<PageShift, s->limit, (uintptr)(s->start+s->npages)<<PageShift, s->state);
+					if(ptrmask != nil)
+						runtime·throw("invalid heap pointer");
+					// Add to badblock list, which will cause the garbage collection
+					// to keep repeating until it has traced the chain of pointers
+					// leading to obj all the way back to a root.
+					if(nbadblock == 0)
+						badblock[nbadblock++] = (uintptr)b;
+					continue;
+				}
+				p = (byte*)((uintptr)s->start<<PageShift);
+				if(s->sizeclass != 0) {
+					size = s->elemsize;
+					idx = ((byte*)obj - p)/size;
+					p = p+idx*size;
+				}
+				if(p == obj) {
+					runtime·printf("runtime: failed to find block beginning for %p s=%p s->limit=%p\n",
+						p, s->start*PageSize, s->limit);
+					runtime·throw("failed to find block beginning");
+				}
+				obj = p;
+				goto markobj;
+			}
+			if(DebugPtrs)
+				runtime·printf("scan *%p = %p => base %p\n", b+i, obj0, obj);
+
+			if(nbadblock > 0 && (uintptr)obj == badblock[nbadblock-1]) {
+				// Running garbage collection again because
+				// we want to find the path from a root to a bad pointer.
+				// Found possible next step; extend or finish path.
+				for(j=0; j<nbadblock; j++)
+					if(badblock[j] == (uintptr)b)
+						goto AlreadyBad;
+				runtime·printf("runtime: found *(%p+%p) = %p+%p\n", b, i, obj0, (uintptr)(obj-obj0));
+				if(ptrmask != nil)
+					runtime·throw("bad pointer");
+				if(nbadblock >= nelem(badblock))
+					runtime·throw("badblock trace too long");
+				badblock[nbadblock++] = (uintptr)b;
+			AlreadyBad:;
+			}
+
+			// Now we have bits, bitp, and shift correct for
+			// obj pointing at the base of the object.
+			// Only care about not marked objects.
+			if((bits&bitMarked) != 0)
+				continue;
+			// If obj size is greater than 8, then each byte of GC bitmap
+			// contains info for at most one object. In such case we use
+			// non-atomic byte store to mark the object. This can lead
+			// to double enqueue of the object for scanning, but scanning
+			// is an idempotent operation, so it is OK. This cannot lead
+			// to bitmap corruption because the single marked bit is the
+			// only thing that can change in the byte.
+			// For 8-byte objects we use non-atomic store, if the other
+			// quadruple is already marked. Otherwise we resort to CAS
+			// loop for marking.
+			if((xbits&(bitMask|(bitMask<<gcBits))) != (bitBoundary|(bitBoundary<<gcBits)) ||
+				runtime·work.nproc == 1)
+				*bitp = xbits | (bitMarked<<shift);
+			else
+				runtime·atomicor8(bitp, bitMarked<<shift);
+
+			if(((xbits>>(shift+2))&BitsMask) == BitsDead)
+				continue;  // noscan object
+
+			// Queue the obj for scanning.
+			PREFETCH(obj);
+			p = scanbuf[scanbufpos];
+			scanbuf[scanbufpos++] = obj;
+			scanbufpos %= nelem(scanbuf);
+			if(p == nil)
+				continue;
+
+			// If workbuf is full, obtain an empty one.
+			if(nobj >= nelem(wbuf->obj)) {
+				wbuf->nobj = nobj;
+				wbuf = getempty(wbuf);
+				nobj = wbuf->nobj;
+				wp = &wbuf->obj[nobj];
+			}
+			*wp = p;
+			wp++;
+			nobj++;
+		}
+		if(DebugPtrs)
+			runtime·printf("end scanblock %p +%p %p\n", b, n, ptrmask);
+
+		if(Debug && ptrmask == nil) {
+			// For heap objects ensure that we did not overscan.
+			n = 0;
+			p = nil;
+			if(!runtime·mlookup(b, &p, &n, nil) || b != p || i > n) {
+				runtime·printf("runtime: scanned (%p,%p), heap object (%p,%p)\n", b, i, p, n);
+				runtime·throw("scanblock: scanned invalid object");
+			}
+		}
+	}
+}
+
+static void
+markroot(ParFor *desc, uint32 i)
+{
+	FinBlock *fb;
+	MSpan *s;
+	uint32 spanidx, sg;
+	G *gp;
+	void *p;
+	uint32 status;
+	bool restart;
+
+	USED(&desc);
+	// Note: if you add a case here, please also update heapdump.c:dumproots.
+	switch(i) {
+	case RootData:
+		scanblock(runtime·data, runtime·edata - runtime·data, runtime·gcdatamask.bytedata);
+		break;
+
+	case RootBss:
+		scanblock(runtime·bss, runtime·ebss - runtime·bss, runtime·gcbssmask.bytedata);
+		break;
+
+	case RootFinalizers:
+		for(fb=runtime·allfin; fb; fb=fb->alllink)
+			scanblock((byte*)fb->fin, fb->cnt*sizeof(fb->fin[0]), finptrmask);
+		break;
+
+	case RootSpans:
+		// mark MSpan.specials
+		sg = runtime·mheap.sweepgen;
+		for(spanidx=0; spanidx<runtime·work.nspan; spanidx++) {
+			Special *sp;
+			SpecialFinalizer *spf;
+
+			s = runtime·work.spans[spanidx];
+			if(s->state != MSpanInUse)
+				continue;
+			if(s->sweepgen != sg) {
+				runtime·printf("sweep %d %d\n", s->sweepgen, sg);
+				runtime·throw("gc: unswept span");
+			}
+			for(sp = s->specials; sp != nil; sp = sp->next) {
+				if(sp->kind != KindSpecialFinalizer)
+					continue;
+				// don't mark finalized object, but scan it so we
+				// retain everything it points to.
+				spf = (SpecialFinalizer*)sp;
+				// A finalizer can be set for an inner byte of an object, find object beginning.
+				p = (void*)((s->start << PageShift) + spf->special.offset/s->elemsize*s->elemsize);
+				scanblock(p, s->elemsize, nil);
+				scanblock((void*)&spf->fn, PtrSize, oneptr);
+			}
+		}
+		break;
+
+	case RootFlushCaches:
+		flushallmcaches();
+		break;
+
+	default:
+		// the rest is scanning goroutine stacks
+		if(i - RootCount >= runtime·allglen)
+			runtime·throw("markroot: bad index");
+		gp = runtime·allg[i - RootCount];
+		// remember when we've first observed the G blocked
+		// needed only to output in traceback
+		status = runtime·readgstatus(gp);
+		if((status == Gwaiting || status == Gsyscall) && gp->waitsince == 0)
+			gp->waitsince = runtime·work.tstart;
+		// Shrink a stack if not much of it is being used.
+		runtime·shrinkstack(gp);
+		if(runtime·readgstatus(gp) == Gdead) 
+			gp->gcworkdone = true;
+		else 
+			gp->gcworkdone = false; 
+		restart = runtime·stopg(gp);
+		scanstack(gp);
+		if(restart)
+			runtime·restartg(gp);
+		break;
+	}
+}
+
+// Get an empty work buffer off the work.empty list,
+// allocating new buffers as needed.
+static Workbuf*
+getempty(Workbuf *b)
+{
+	MCache *c;
+
+	if(b != nil)
+		runtime·lfstackpush(&runtime·work.full, &b->node);
+	b = nil;
+	c = g->m->mcache;
+	if(c->gcworkbuf != nil) {
+		b = c->gcworkbuf;
+		c->gcworkbuf = nil;
+	}
+	if(b == nil)
+		b = (Workbuf*)runtime·lfstackpop(&runtime·work.empty);
+	if(b == nil)
+		b = runtime·persistentalloc(sizeof(*b), CacheLineSize, &mstats.gc_sys);
+	b->nobj = 0;
+	return b;
+}
+
+static void
+putempty(Workbuf *b)
+{
+	MCache *c;
+
+	c = g->m->mcache;
+	if(c->gcworkbuf == nil) {
+		c->gcworkbuf = b;
+		return;
+	}
+	runtime·lfstackpush(&runtime·work.empty, &b->node);
+}
+
+void
+runtime·gcworkbuffree(void *b)
+{
+	if(b != nil)
+		putempty(b);
+}
+
+// Get a full work buffer off the work.full list, or return nil.
+static Workbuf*
+getfull(Workbuf *b)
+{
+	int32 i;
+
+	if(b != nil)
+		runtime·lfstackpush(&runtime·work.empty, &b->node);
+	b = (Workbuf*)runtime·lfstackpop(&runtime·work.full);
+	if(b != nil || runtime·work.nproc == 1)
+		return b;
+
+	runtime·xadd(&runtime·work.nwait, +1);
+	for(i=0;; i++) {
+		if(runtime·work.full != 0) {
+			runtime·xadd(&runtime·work.nwait, -1);
+			b = (Workbuf*)runtime·lfstackpop(&runtime·work.full);
+			if(b != nil)
+				return b;
+			runtime·xadd(&runtime·work.nwait, +1);
+		}
+		if(runtime·work.nwait == runtime·work.nproc)
+			return nil;
+		if(i < 10) {
+			g->m->gcstats.nprocyield++;
+			runtime·procyield(20);
+		} else if(i < 20) {
+			g->m->gcstats.nosyield++;
+			runtime·osyield();
+		} else {
+			g->m->gcstats.nsleep++;
+			runtime·usleep(100);
+		}
+	}
+}
+
+static Workbuf*
+handoff(Workbuf *b)
+{
+	int32 n;
+	Workbuf *b1;
+
+	// Make new buffer with half of b's pointers.
+	b1 = getempty(nil);
+	n = b->nobj/2;
+	b->nobj -= n;
+	b1->nobj = n;
+	runtime·memmove(b1->obj, b->obj+b->nobj, n*sizeof b1->obj[0]);
+	g->m->gcstats.nhandoff++;
+	g->m->gcstats.nhandoffcnt += n;
+
+	// Put b on full list - let first half of b get stolen.
+	runtime·lfstackpush(&runtime·work.full, &b->node);
+	return b1;
+}
+
+BitVector
+runtime·stackmapdata(StackMap *stackmap, int32 n)
+{
+	if(n < 0 || n >= stackmap->n)
+		runtime·throw("stackmapdata: index out of range");
+	return (BitVector){stackmap->nbit, stackmap->bytedata + n*((stackmap->nbit+31)/32*4)};
+}
+
+// Scan a stack frame: local variables and function arguments/results.
+static bool
+scanframe(Stkframe *frame, void *unused)
+{
+	Func *f;
+	StackMap *stackmap;
+	BitVector bv;
+	uintptr size, minsize;
+	uintptr targetpc;
+	int32 pcdata;
+
+	USED(unused);
+	f = frame->fn;
+	targetpc = frame->continpc;
+	if(targetpc == 0) {
+		// Frame is dead.
+		return true;
+	}
+	if(Debug > 1)
+		runtime·printf("scanframe %s\n", runtime·funcname(f));
+	if(targetpc != f->entry)
+		targetpc--;
+	pcdata = runtime·pcdatavalue(f, PCDATA_StackMapIndex, targetpc);
+	if(pcdata == -1) {
+		// We do not have a valid pcdata value but there might be a
+		// stackmap for this function.  It is likely that we are looking
+		// at the function prologue, assume so and hope for the best.
+		pcdata = 0;
+	}
+
+	// Scan local variables if stack frame has been allocated.
+	size = frame->varp - frame->sp;
+	if(thechar != '6' && thechar != '8')
+		minsize = sizeof(uintptr);
+	else
+		minsize = 0;
+	if(size > minsize) {
+		stackmap = runtime·funcdata(f, FUNCDATA_LocalsPointerMaps);
+		if(stackmap == nil || stackmap->n <= 0) {
+			runtime·printf("runtime: frame %s untyped locals %p+%p\n", runtime·funcname(f), (byte*)(frame->varp-size), size);
+			runtime·throw("missing stackmap");
+		}
+
+		// Locals bitmap information, scan just the pointers in locals.
+		if(pcdata < 0 || pcdata >= stackmap->n) {
+			// don't know where we are
+			runtime·printf("runtime: pcdata is %d and %d locals stack map entries for %s (targetpc=%p)\n",
+				pcdata, stackmap->n, runtime·funcname(f), targetpc);
+			runtime·throw("scanframe: bad symbol table");
+		}
+		bv = runtime·stackmapdata(stackmap, pcdata);
+		size = (bv.n * PtrSize) / BitsPerPointer;
+		scanblock((byte*)(frame->varp - size), bv.n/BitsPerPointer*PtrSize, bv.bytedata);
+	}
+
+	// Scan arguments.
+	if(frame->arglen > 0) {
+		if(frame->argmap != nil)
+			bv = *frame->argmap;
+		else {
+			stackmap = runtime·funcdata(f, FUNCDATA_ArgsPointerMaps);
+			if(stackmap == nil || stackmap->n <= 0) {
+				runtime·printf("runtime: frame %s untyped args %p+%p\n", runtime·funcname(f), frame->argp, (uintptr)frame->arglen);
+				runtime·throw("missing stackmap");
+			}
+			if(pcdata < 0 || pcdata >= stackmap->n) {
+				// don't know where we are
+				runtime·printf("runtime: pcdata is %d and %d args stack map entries for %s (targetpc=%p)\n",
+					pcdata, stackmap->n, runtime·funcname(f), targetpc);
+				runtime·throw("scanframe: bad symbol table");
+			}
+ 			bv = runtime·stackmapdata(stackmap, pcdata);
+		}
+ 		scanblock((byte*)frame->argp, bv.n/BitsPerPointer*PtrSize, bv.bytedata);
+ 	}
+ 	return true;
+}
+
+static void
+scanstack(G *gp)
+{
+	M *mp;
+	bool (*fn)(Stkframe*, void*);
+
+	if(runtime·readgstatus(gp)&Gscan == 0) {
+		runtime·printf("runtime: gp=%p, goid=%D, gp->atomicstatus=%d\n", gp, gp->goid, runtime·readgstatus(gp));
+		runtime·throw("mark - bad status");
+	}
+
+	switch(runtime·readgstatus(gp)&~Gscan) {
+	default:
+		runtime·printf("runtime: gp=%p, goid=%D, gp->atomicstatus=%d\n", gp, gp->goid, runtime·readgstatus(gp));
+		runtime·throw("mark - bad status");
+	case Gdead:
+		return;
+	case Grunning:
+		runtime·printf("runtime: gp=%p, goid=%D, gp->atomicstatus=%d\n", gp, gp->goid, runtime·readgstatus(gp));
+		runtime·throw("mark - world not stopped");
+	case Grunnable:
+	case Gsyscall:
+	case Gwaiting:
+		break;
+	}
+
+	if(gp == g)
+		runtime·throw("can't scan our own stack");
+	if((mp = gp->m) != nil && mp->helpgc)
+		runtime·throw("can't scan gchelper stack");
+
+	fn = scanframe;
+	runtime·gentraceback(~(uintptr)0, ~(uintptr)0, 0, gp, 0, nil, 0x7fffffff, &fn, nil, 0);
+	runtime·tracebackdefers(gp, &fn, nil);
+}
+
+// The gp has been moved to a gc safepoint. If there is gcphase specific
+// work it is done here. 
+void
+runtime·gcphasework(G *gp)
+{
+	switch(runtime·gcphase) {
+	default:
+		runtime·throw("gcphasework in bad gcphase");
+	case GCoff:
+	case GCquiesce:
+	case GCstw:
+	case GCsweep:
+		// No work for now.
+		break;
+	case GCmark:
+		// Disabled until concurrent GC is implemented
+		// but indicate the scan has been done. 
+		// scanstack(gp);
+		break;
+	}
+	gp->gcworkdone = true;
+}
+
+#pragma dataflag NOPTR
+static byte finalizer1[] = {
+	// Each Finalizer is 5 words, ptr ptr uintptr ptr ptr.
+	// Each byte describes 4 words.
+	// Need 4 Finalizers described by 5 bytes before pattern repeats:
+	//	ptr ptr uintptr ptr ptr
+	//	ptr ptr uintptr ptr ptr
+	//	ptr ptr uintptr ptr ptr
+	//	ptr ptr uintptr ptr ptr
+	// aka
+	//	ptr ptr uintptr ptr
+	//	ptr ptr ptr uintptr
+	//	ptr ptr ptr ptr
+	//	uintptr ptr ptr ptr
+	//	ptr uintptr ptr ptr
+	// Assumptions about Finalizer layout checked below.
+	BitsPointer | BitsPointer<<2 | BitsScalar<<4 | BitsPointer<<6,
+	BitsPointer | BitsPointer<<2 | BitsPointer<<4 | BitsScalar<<6,
+	BitsPointer | BitsPointer<<2 | BitsPointer<<4 | BitsPointer<<6,
+	BitsScalar | BitsPointer<<2 | BitsPointer<<4 | BitsPointer<<6,
+	BitsPointer | BitsScalar<<2 | BitsPointer<<4 | BitsPointer<<6,
+};
+
+void
+runtime·queuefinalizer(byte *p, FuncVal *fn, uintptr nret, Type *fint, PtrType *ot)
+{
+	FinBlock *block;
+	Finalizer *f;
+	int32 i;
+
+	runtime·lock(&runtime·finlock);
+	if(runtime·finq == nil || runtime·finq->cnt == runtime·finq->cap) {
+		if(runtime·finc == nil) {
+			runtime·finc = runtime·persistentalloc(FinBlockSize, 0, &mstats.gc_sys);
+			runtime·finc->cap = (FinBlockSize - sizeof(FinBlock)) / sizeof(Finalizer) + 1;
+			runtime·finc->alllink = runtime·allfin;
+			runtime·allfin = runtime·finc;
+			if(finptrmask[0] == 0) {
+				// Build pointer mask for Finalizer array in block.
+				// Check assumptions made in finalizer1 array above.
+				if(sizeof(Finalizer) != 5*PtrSize ||
+					offsetof(Finalizer, fn) != 0 ||
+					offsetof(Finalizer, arg) != PtrSize ||
+					offsetof(Finalizer, nret) != 2*PtrSize ||
+					offsetof(Finalizer, fint) != 3*PtrSize ||
+					offsetof(Finalizer, ot) != 4*PtrSize ||
+					BitsPerPointer != 2) {
+					runtime·throw("finalizer out of sync");
+				}
+				for(i=0; i<nelem(finptrmask); i++)
+					finptrmask[i] = finalizer1[i%nelem(finalizer1)];
+			}
+		}
+		block = runtime·finc;
+		runtime·finc = block->next;
+		block->next = runtime·finq;
+		runtime·finq = block;
+	}
+	f = &runtime·finq->fin[runtime·finq->cnt];
+	runtime·finq->cnt++;
+	f->fn = fn;
+	f->nret = nret;
+	f->fint = fint;
+	f->ot = ot;
+	f->arg = p;
+	runtime·fingwake = true;
+	runtime·unlock(&runtime·finlock);
+}
+
+void
+runtime·iterate_finq(void (*callback)(FuncVal*, byte*, uintptr, Type*, PtrType*))
+{
+	FinBlock *fb;
+	Finalizer *f;
+	uintptr i;
+
+	for(fb = runtime·allfin; fb; fb = fb->alllink) {
+		for(i = 0; i < fb->cnt; i++) {
+			f = &fb->fin[i];
+			callback(f->fn, f->arg, f->nret, f->fint, f->ot);
+		}
+	}
+}
+
+void
+runtime·MSpan_EnsureSwept(MSpan *s)
+{
+	uint32 sg;
+
+	// Caller must disable preemption.
+	// Otherwise when this function returns the span can become unswept again
+	// (if GC is triggered on another goroutine).
+	if(g->m->locks == 0 && g->m->mallocing == 0 && g != g->m->g0)
+		runtime·throw("MSpan_EnsureSwept: m is not locked");
+
+	sg = runtime·mheap.sweepgen;
+	if(runtime·atomicload(&s->sweepgen) == sg)
+		return;
+	if(runtime·cas(&s->sweepgen, sg-2, sg-1)) {
+		runtime·MSpan_Sweep(s, false);
+		return;
+	}
+	// unfortunate condition, and we don't have efficient means to wait
+	while(runtime·atomicload(&s->sweepgen) != sg)
+		runtime·osyield();
+}
+
+// Sweep frees or collects finalizers for blocks not marked in the mark phase.
+// It clears the mark bits in preparation for the next GC round.
+// Returns true if the span was returned to heap.
+// If preserve=true, don't return it to heap nor relink in MCentral lists;
+// caller takes care of it.
+bool
+runtime·MSpan_Sweep(MSpan *s, bool preserve)
+{
+	int32 cl, n, npages, nfree;
+	uintptr size, off, step;
+	uint32 sweepgen;
+	byte *p, *bitp, shift, xbits, bits;
+	MCache *c;
+	byte *arena_start;
+	MLink head, *end, *link;
+	Special *special, **specialp, *y;
+	bool res, sweepgenset;
+
+	// It's critical that we enter this function with preemption disabled,
+	// GC must not start while we are in the middle of this function.
+	if(g->m->locks == 0 && g->m->mallocing == 0 && g != g->m->g0)
+		runtime·throw("MSpan_Sweep: m is not locked");
+	sweepgen = runtime·mheap.sweepgen;
+	if(s->state != MSpanInUse || s->sweepgen != sweepgen-1) {
+		runtime·printf("MSpan_Sweep: state=%d sweepgen=%d mheap.sweepgen=%d\n",
+			s->state, s->sweepgen, sweepgen);
+		runtime·throw("MSpan_Sweep: bad span state");
+	}
+	arena_start = runtime·mheap.arena_start;
+	cl = s->sizeclass;
+	size = s->elemsize;
+	if(cl == 0) {
+		n = 1;
+	} else {
+		// Chunk full of small blocks.
+		npages = runtime·class_to_allocnpages[cl];
+		n = (npages << PageShift) / size;
+	}
+	res = false;
+	nfree = 0;
+	end = &head;
+	c = g->m->mcache;
+	sweepgenset = false;
+
+	// Mark any free objects in this span so we don't collect them.
+	for(link = s->freelist; link != nil; link = link->next) {
+		off = (uintptr*)link - (uintptr*)arena_start;
+		bitp = arena_start - off/wordsPerBitmapByte - 1;
+		shift = (off % wordsPerBitmapByte) * gcBits;
+		*bitp |= bitMarked<<shift;
+	}
+
+	// Unlink & free special records for any objects we're about to free.
+	specialp = &s->specials;
+	special = *specialp;
+	while(special != nil) {
+		// A finalizer can be set for an inner byte of an object, find object beginning.
+		p = (byte*)(s->start << PageShift) + special->offset/size*size;
+		off = (uintptr*)p - (uintptr*)arena_start;
+		bitp = arena_start - off/wordsPerBitmapByte - 1;
+		shift = (off % wordsPerBitmapByte) * gcBits;
+		bits = (*bitp>>shift) & bitMask;
+		if((bits&bitMarked) == 0) {
+			// Find the exact byte for which the special was setup
+			// (as opposed to object beginning).
+			p = (byte*)(s->start << PageShift) + special->offset;
+			// about to free object: splice out special record
+			y = special;
+			special = special->next;
+			*specialp = special;
+			if(!runtime·freespecial(y, p, size, false)) {
+				// stop freeing of object if it has a finalizer
+				*bitp |= bitMarked << shift;
+			}
+		} else {
+			// object is still live: keep special record
+			specialp = &special->next;
+			special = *specialp;
+		}
+	}
+
+	// Sweep through n objects of given size starting at p.
+	// This thread owns the span now, so it can manipulate
+	// the block bitmap without atomic operations.
+	p = (byte*)(s->start << PageShift);
+	// Find bits for the beginning of the span.
+	off = (uintptr*)p - (uintptr*)arena_start;
+	bitp = arena_start - off/wordsPerBitmapByte - 1;
+	shift = 0;
+	step = size/(PtrSize*wordsPerBitmapByte);
+	// Rewind to the previous quadruple as we move to the next
+	// in the beginning of the loop.
+	bitp += step;
+	if(step == 0) {
+		// 8-byte objects.
+		bitp++;
+		shift = gcBits;
+	}
+	for(; n > 0; n--, p += size) {
+		bitp -= step;
+		if(step == 0) {
+			if(shift != 0)
+				bitp--;
+			shift = gcBits - shift;
+		}
+
+		xbits = *bitp;
+		bits = (xbits>>shift) & bitMask;
+
+		// Allocated and marked object, reset bits to allocated.
+		if((bits&bitMarked) != 0) {
+			*bitp &= ~(bitMarked<<shift);
+			continue;
+		}
+		// At this point we know that we are looking at garbage object
+		// that needs to be collected.
+		if(runtime·debug.allocfreetrace)
+			runtime·tracefree(p, size);
+		// Reset to allocated+noscan.
+		*bitp = (xbits & ~((bitMarked|(BitsMask<<2))<<shift)) | ((uintptr)BitsDead<<(shift+2));
+		if(cl == 0) {
+			// Free large span.
+			if(preserve)
+				runtime·throw("can't preserve large span");
+			runtime·unmarkspan(p, s->npages<<PageShift);
+			s->needzero = 1;
+			// important to set sweepgen before returning it to heap
+			runtime·atomicstore(&s->sweepgen, sweepgen);
+			sweepgenset = true;
+			// NOTE(rsc,dvyukov): The original implementation of efence
+			// in CL 22060046 used SysFree instead of SysFault, so that
+			// the operating system would eventually give the memory
+			// back to us again, so that an efence program could run
+			// longer without running out of memory. Unfortunately,
+			// calling SysFree here without any kind of adjustment of the
+			// heap data structures means that when the memory does
+			// come back to us, we have the wrong metadata for it, either in
+			// the MSpan structures or in the garbage collection bitmap.
+			// Using SysFault here means that the program will run out of
+			// memory fairly quickly in efence mode, but at least it won't
+			// have mysterious crashes due to confused memory reuse.
+			// It should be possible to switch back to SysFree if we also
+			// implement and then call some kind of MHeap_DeleteSpan.
+			if(runtime·debug.efence) {
+				s->limit = nil;	// prevent mlookup from finding this span
+				runtime·SysFault(p, size);
+			} else
+				runtime·MHeap_Free(&runtime·mheap, s, 1);
+			c->local_nlargefree++;
+			c->local_largefree += size;
+			runtime·xadd64(&mstats.next_gc, -(uint64)(size * (runtime·gcpercent + 100)/100));
+			res = true;
+		} else {
+			// Free small object.
+			if(size > 2*sizeof(uintptr))
+				((uintptr*)p)[1] = (uintptr)0xdeaddeaddeaddeadll;	// mark as "needs to be zeroed"
+			else if(size > sizeof(uintptr))
+				((uintptr*)p)[1] = 0;
+
+			end->next = (MLink*)p;
+			end = (MLink*)p;
+			nfree++;
+		}
+	}
+
+	// We need to set s->sweepgen = h->sweepgen only when all blocks are swept,
+	// because of the potential for a concurrent free/SetFinalizer.
+	// But we need to set it before we make the span available for allocation
+	// (return it to heap or mcentral), because allocation code assumes that a
+	// span is already swept if available for allocation.
+
+	if(!sweepgenset && nfree == 0) {
+		// The span must be in our exclusive ownership until we update sweepgen,
+		// check for potential races.
+		if(s->state != MSpanInUse || s->sweepgen != sweepgen-1) {
+			runtime·printf("MSpan_Sweep: state=%d sweepgen=%d mheap.sweepgen=%d\n",
+				s->state, s->sweepgen, sweepgen);
+			runtime·throw("MSpan_Sweep: bad span state after sweep");
+		}
+		runtime·atomicstore(&s->sweepgen, sweepgen);
+	}
+	if(nfree > 0) {
+		c->local_nsmallfree[cl] += nfree;
+		c->local_cachealloc -= nfree * size;
+		runtime·xadd64(&mstats.next_gc, -(uint64)(nfree * size * (runtime·gcpercent + 100)/100));
+		res = runtime·MCentral_FreeSpan(&runtime·mheap.central[cl].mcentral, s, nfree, head.next, end, preserve);
+		// MCentral_FreeSpan updates sweepgen
+	}
+	return res;
+}
+
+// State of background runtime·sweep.
+// Protected by runtime·gclock.
+typedef struct SweepData SweepData;
+struct SweepData
+{
+	G*	g;
+	bool	parked;
+
+	uint32	spanidx;	// background sweeper position
+
+	uint32	nbgsweep;
+	uint32	npausesweep;
+};
+SweepData runtime·sweep;
+
+// sweeps one span
+// returns number of pages returned to heap, or -1 if there is nothing to sweep
+uintptr
+runtime·sweepone(void)
+{
+	MSpan *s;
+	uint32 idx, sg;
+	uintptr npages;
+
+	// increment locks to ensure that the goroutine is not preempted
+	// in the middle of sweep thus leaving the span in an inconsistent state for next GC
+	g->m->locks++;
+	sg = runtime·mheap.sweepgen;
+	for(;;) {
+		idx = runtime·xadd(&runtime·sweep.spanidx, 1) - 1;
+		if(idx >= runtime·work.nspan) {
+			runtime·mheap.sweepdone = true;
+			g->m->locks--;
+			return -1;
+		}
+		s = runtime·work.spans[idx];
+		if(s->state != MSpanInUse) {
+			s->sweepgen = sg;
+			continue;
+		}
+		if(s->sweepgen != sg-2 || !runtime·cas(&s->sweepgen, sg-2, sg-1))
+			continue;
+		npages = s->npages;
+		if(!runtime·MSpan_Sweep(s, false))
+			npages = 0;
+		g->m->locks--;
+		return npages;
+	}
+}
+
+static void
+sweepone_m(void)
+{
+	g->m->scalararg[0] = runtime·sweepone();
+}
+
+#pragma textflag NOSPLIT
+uintptr
+runtime·gosweepone(void)
+{
+	void (*fn)(void);
+	
+	fn = sweepone_m;
+	runtime·onM(&fn);
+	return g->m->scalararg[0];
+}
+
+#pragma textflag NOSPLIT
+bool
+runtime·gosweepdone(void)
+{
+	return runtime·mheap.sweepdone;
+}
+
+void
+runtime·gchelper(void)
+{
+	uint32 nproc;
+
+	g->m->traceback = 2;
+	gchelperstart();
+
+	// parallel mark for over gc roots
+	runtime·parfordo(runtime·work.markfor);
+
+	// help other threads scan secondary blocks
+	scanblock(nil, 0, nil);
+
+	nproc = runtime·work.nproc;  // runtime·work.nproc can change right after we increment runtime·work.ndone
+	if(runtime·xadd(&runtime·work.ndone, +1) == nproc-1)
+		runtime·notewakeup(&runtime·work.alldone);
+	g->m->traceback = 0;
+}
+
+static void
+cachestats(void)
+{
+	MCache *c;
+	P *p, **pp;
+
+	for(pp=runtime·allp; p=*pp; pp++) {
+		c = p->mcache;
+		if(c==nil)
+			continue;
+		runtime·purgecachedstats(c);
+	}
+}
+
+static void
+flushallmcaches(void)
+{
+	P *p, **pp;
+	MCache *c;
+
+	// Flush MCache's to MCentral.
+	for(pp=runtime·allp; p=*pp; pp++) {
+		c = p->mcache;
+		if(c==nil)
+			continue;
+		runtime·MCache_ReleaseAll(c);
+		runtime·stackcache_clear(c);
+	}
+}
+
+static void
+flushallmcaches_m(G *gp)
+{
+	flushallmcaches();
+	runtime·gogo(&gp->sched);
+}
+
+void
+runtime·updatememstats(GCStats *stats)
+{
+	M *mp;
+	MSpan *s;
+	int32 i;
+	uint64 smallfree;
+	uint64 *src, *dst;
+	void (*fn)(G*);
+
+	if(stats)
+		runtime·memclr((byte*)stats, sizeof(*stats));
+	for(mp=runtime·allm; mp; mp=mp->alllink) {
+		if(stats) {
+			src = (uint64*)&mp->gcstats;
+			dst = (uint64*)stats;
+			for(i=0; i<sizeof(*stats)/sizeof(uint64); i++)
+				dst[i] += src[i];
+			runtime·memclr((byte*)&mp->gcstats, sizeof(mp->gcstats));
+		}
+	}
+	mstats.mcache_inuse = runtime·mheap.cachealloc.inuse;
+	mstats.mspan_inuse = runtime·mheap.spanalloc.inuse;
+	mstats.sys = mstats.heap_sys + mstats.stacks_sys + mstats.mspan_sys +
+		mstats.mcache_sys + mstats.buckhash_sys + mstats.gc_sys + mstats.other_sys;
+	
+	// Calculate memory allocator stats.
+	// During program execution we only count number of frees and amount of freed memory.
+	// Current number of alive object in the heap and amount of alive heap memory
+	// are calculated by scanning all spans.
+	// Total number of mallocs is calculated as number of frees plus number of alive objects.
+	// Similarly, total amount of allocated memory is calculated as amount of freed memory
+	// plus amount of alive heap memory.
+	mstats.alloc = 0;
+	mstats.total_alloc = 0;
+	mstats.nmalloc = 0;
+	mstats.nfree = 0;
+	for(i = 0; i < nelem(mstats.by_size); i++) {
+		mstats.by_size[i].nmalloc = 0;
+		mstats.by_size[i].nfree = 0;
+	}
+
+	// Flush MCache's to MCentral.
+	if(g == g->m->g0)
+		flushallmcaches();
+	else {
+		fn = flushallmcaches_m;
+		runtime·mcall(&fn);
+	}
+
+	// Aggregate local stats.
+	cachestats();
+
+	// Scan all spans and count number of alive objects.
+	runtime·lock(&runtime·mheap.lock);
+	for(i = 0; i < runtime·mheap.nspan; i++) {
+		s = runtime·mheap.allspans[i];
+		if(s->state != MSpanInUse)
+			continue;
+		if(s->sizeclass == 0) {
+			mstats.nmalloc++;
+			mstats.alloc += s->elemsize;
+		} else {
+			mstats.nmalloc += s->ref;
+			mstats.by_size[s->sizeclass].nmalloc += s->ref;
+			mstats.alloc += s->ref*s->elemsize;
+		}
+	}
+	runtime·unlock(&runtime·mheap.lock);
+
+	// Aggregate by size class.
+	smallfree = 0;
+	mstats.nfree = runtime·mheap.nlargefree;
+	for(i = 0; i < nelem(mstats.by_size); i++) {
+		mstats.nfree += runtime·mheap.nsmallfree[i];
+		mstats.by_size[i].nfree = runtime·mheap.nsmallfree[i];
+		mstats.by_size[i].nmalloc += runtime·mheap.nsmallfree[i];
+		smallfree += runtime·mheap.nsmallfree[i] * runtime·class_to_size[i];
+	}
+	mstats.nfree += mstats.tinyallocs;
+	mstats.nmalloc += mstats.nfree;
+
+	// Calculate derived stats.
+	mstats.total_alloc = mstats.alloc + runtime·mheap.largefree + smallfree;
+	mstats.heap_alloc = mstats.alloc;
+	mstats.heap_objects = mstats.nmalloc - mstats.nfree;
+}
+
+// Structure of arguments passed to function gc().
+// This allows the arguments to be passed via runtime·mcall.
+struct gc_args
+{
+	int64 start_time; // start time of GC in ns (just before stoptheworld)
+	bool  eagersweep;
+};
+
+static void gc(struct gc_args *args);
+
+int32
+runtime·readgogc(void)
+{
+	byte *p;
+
+	p = runtime·getenv("GOGC");
+	if(p == nil || p[0] == '\0')
+		return 100;
+	if(runtime·strcmp(p, (byte*)"off") == 0)
+		return -1;
+	return runtime·atoi(p);
+}
+
+void
+runtime·gcinit(void)
+{
+	if(sizeof(Workbuf) != WorkbufSize)
+		runtime·throw("runtime: size of Workbuf is suboptimal");
+
+	runtime·work.markfor = runtime·parforalloc(MaxGcproc);
+	runtime·gcpercent = runtime·readgogc();
+	runtime·gcdatamask = unrollglobgcprog(runtime·gcdata, runtime·edata - runtime·data);
+	runtime·gcbssmask = unrollglobgcprog(runtime·gcbss, runtime·ebss - runtime·bss);
+}
+
+void
+runtime·gc_m(void)
+{
+	struct gc_args a;
+	G *gp;
+
+	gp = g->m->curg;
+	runtime·casgstatus(gp, Grunning, Gwaiting);
+	gp->waitreason = runtime·gostringnocopy((byte*)"garbage collection");
+
+	a.start_time = (uint64)(g->m->scalararg[0]) | ((uint64)(g->m->scalararg[1]) << 32);
+	a.eagersweep = g->m->scalararg[2];
+	gc(&a);
+
+	if(nbadblock > 0) {
+		// Work out path from root to bad block.
+		for(;;) {
+			gc(&a);
+			if(nbadblock >= nelem(badblock))
+				runtime·throw("cannot find path to bad pointer");
+		}
+	}
+
+	runtime·casgstatus(gp, Gwaiting, Grunning);
+}
+
+static void
+gc(struct gc_args *args)
+{
+	int64 t0, t1, t2, t3, t4;
+	uint64 heap0, heap1, obj;
+	GCStats stats;
+
+	if(DebugPtrs)
+		runtime·printf("GC start\n");
+
+	if(runtime·debug.allocfreetrace)
+		runtime·tracegc();
+
+	g->m->traceback = 2;
+	t0 = args->start_time;
+	runtime·work.tstart = args->start_time; 
+
+	t1 = 0;
+	if(runtime·debug.gctrace)
+		t1 = runtime·nanotime();
+
+	// Sweep what is not sweeped by bgsweep.
+	while(runtime·sweepone() != -1)
+		runtime·sweep.npausesweep++;
+
+	// Cache runtime.mheap.allspans in work.spans to avoid conflicts with
+	// resizing/freeing allspans.
+	// New spans can be created while GC progresses, but they are not garbage for
+	// this round:
+	//  - new stack spans can be created even while the world is stopped.
+	//  - new malloc spans can be created during the concurrent sweep
+
+	// Even if this is stop-the-world, a concurrent exitsyscall can allocate a stack from heap.
+	runtime·lock(&runtime·mheap.lock);
+	// Free the old cached sweep array if necessary.
+	if(runtime·work.spans != nil && runtime·work.spans != runtime·mheap.allspans)
+		runtime·SysFree(runtime·work.spans, runtime·work.nspan*sizeof(runtime·work.spans[0]), &mstats.other_sys);
+	// Cache the current array for marking.
+	runtime·mheap.gcspans = runtime·mheap.allspans;
+	runtime·work.spans = runtime·mheap.allspans;
+	runtime·work.nspan = runtime·mheap.nspan;
+	runtime·unlock(&runtime·mheap.lock);
+
+	runtime·work.nwait = 0;
+	runtime·work.ndone = 0;
+	runtime·work.nproc = runtime·gcprocs();
+	runtime·parforsetup(runtime·work.markfor, runtime·work.nproc, RootCount + runtime·allglen, nil, false, markroot);
+	if(runtime·work.nproc > 1) {
+		runtime·noteclear(&runtime·work.alldone);
+		runtime·helpgc(runtime·work.nproc);
+	}
+
+	t2 = 0;
+	if(runtime·debug.gctrace)
+		t2 = runtime·nanotime();
+
+	gchelperstart();
+	runtime·parfordo(runtime·work.markfor);
+	scanblock(nil, 0, nil);
+
+	t3 = 0;
+	if(runtime·debug.gctrace)
+		t3 = runtime·nanotime();
+
+	if(runtime·work.nproc > 1)
+		runtime·notesleep(&runtime·work.alldone);
+
+	runtime·shrinkfinish();
+
+	cachestats();
+	// next_gc calculation is tricky with concurrent sweep since we don't know size of live heap
+	// estimate what was live heap size after previous GC (for tracing only)
+	heap0 = mstats.next_gc*100/(runtime·gcpercent+100);
+	// conservatively set next_gc to high value assuming that everything is live
+	// concurrent/lazy sweep will reduce this number while discovering new garbage
+	mstats.next_gc = mstats.heap_alloc+mstats.heap_alloc*runtime·gcpercent/100;
+
+	t4 = runtime·nanotime();
+	runtime·atomicstore64(&mstats.last_gc, runtime·unixnanotime());  // must be Unix time to make sense to user
+	mstats.pause_ns[mstats.numgc%nelem(mstats.pause_ns)] = t4 - t0;
+	mstats.pause_end[mstats.numgc%nelem(mstats.pause_end)] = t4;
+	mstats.pause_total_ns += t4 - t0;
+	mstats.numgc++;
+	if(mstats.debuggc)
+		runtime·printf("pause %D\n", t4-t0);
+
+	if(runtime·debug.gctrace) {
+		heap1 = mstats.heap_alloc;
+		runtime·updatememstats(&stats);
+		if(heap1 != mstats.heap_alloc) {
+			runtime·printf("runtime: mstats skew: heap=%D/%D\n", heap1, mstats.heap_alloc);
+			runtime·throw("mstats skew");
+		}
+		obj = mstats.nmalloc - mstats.nfree;
+
+		stats.nprocyield += runtime·work.markfor->nprocyield;
+		stats.nosyield += runtime·work.markfor->nosyield;
+		stats.nsleep += runtime·work.markfor->nsleep;
+
+		runtime·printf("gc%d(%d): %D+%D+%D+%D us, %D -> %D MB, %D (%D-%D) objects,"
+				" %d goroutines,"
+				" %d/%d/%d sweeps,"
+				" %D(%D) handoff, %D(%D) steal, %D/%D/%D yields\n",
+			mstats.numgc, runtime·work.nproc, (t1-t0)/1000, (t2-t1)/1000, (t3-t2)/1000, (t4-t3)/1000,
+			heap0>>20, heap1>>20, obj,
+			mstats.nmalloc, mstats.nfree,
+			runtime·gcount(),
+			runtime·work.nspan, runtime·sweep.nbgsweep, runtime·sweep.npausesweep,
+			stats.nhandoff, stats.nhandoffcnt,
+			runtime·work.markfor->nsteal, runtime·work.markfor->nstealcnt,
+			stats.nprocyield, stats.nosyield, stats.nsleep);
+		runtime·sweep.nbgsweep = runtime·sweep.npausesweep = 0;
+	}
+
+	// See the comment in the beginning of this function as to why we need the following.
+	// Even if this is still stop-the-world, a concurrent exitsyscall can allocate a stack from heap.
+	runtime·lock(&runtime·mheap.lock);
+	// Free the old cached mark array if necessary.
+	if(runtime·work.spans != nil && runtime·work.spans != runtime·mheap.allspans)
+		runtime·SysFree(runtime·work.spans, runtime·work.nspan*sizeof(runtime·work.spans[0]), &mstats.other_sys);
+	// Cache the current array for sweeping.
+	runtime·mheap.gcspans = runtime·mheap.allspans;
+	runtime·mheap.sweepgen += 2;
+	runtime·mheap.sweepdone = false;
+	runtime·work.spans = runtime·mheap.allspans;
+	runtime·work.nspan = runtime·mheap.nspan;
+	runtime·sweep.spanidx = 0;
+	runtime·unlock(&runtime·mheap.lock);
+
+	if(ConcurrentSweep && !args->eagersweep) {
+		runtime·lock(&runtime·gclock);
+		if(runtime·sweep.g == nil)
+			runtime·sweep.g = runtime·newproc1(&bgsweepv, nil, 0, 0, gc);
+		else if(runtime·sweep.parked) {
+			runtime·sweep.parked = false;
+			runtime·ready(runtime·sweep.g);
+		}
+		runtime·unlock(&runtime·gclock);
+	} else {
+		// Sweep all spans eagerly.
+		while(runtime·sweepone() != -1)
+			runtime·sweep.npausesweep++;
+		// Do an additional mProf_GC, because all 'free' events are now real as well.
+		runtime·mProf_GC();
+	}
+
+	runtime·mProf_GC();
+	g->m->traceback = 0;
+
+	if(DebugPtrs)
+		runtime·printf("GC end\n");
+}
+
+extern uintptr runtime·sizeof_C_MStats;
+
+static void readmemstats_m(void);
+
+void
+runtime·readmemstats_m(void)
+{
+	MStats *stats;
+	
+	stats = g->m->ptrarg[0];
+	g->m->ptrarg[0] = nil;
+
+	runtime·updatememstats(nil);
+	// Size of the trailing by_size array differs between Go and C,
+	// NumSizeClasses was changed, but we can not change Go struct because of backward compatibility.
+	runtime·memmove(stats, &mstats, runtime·sizeof_C_MStats);
+
+	// Stack numbers are part of the heap numbers, separate those out for user consumption
+	stats->stacks_sys = stats->stacks_inuse;
+	stats->heap_inuse -= stats->stacks_inuse;
+	stats->heap_sys -= stats->stacks_inuse;
+}
+
+static void readgcstats_m(void);
+
+#pragma textflag NOSPLIT
+void
+runtime∕debug·readGCStats(Slice *pauses)
+{
+	void (*fn)(void);
+	
+	g->m->ptrarg[0] = pauses;
+	fn = readgcstats_m;
+	runtime·onM(&fn);
+}
+
+static void
+readgcstats_m(void)
+{
+	Slice *pauses;	
+	uint64 *p;
+	uint32 i, j, n;
+	
+	pauses = g->m->ptrarg[0];
+	g->m->ptrarg[0] = nil;
+
+	// Calling code in runtime/debug should make the slice large enough.
+	if(pauses->cap < nelem(mstats.pause_ns)+3)
+		runtime·throw("runtime: short slice passed to readGCStats");
+
+	// Pass back: pauses, pause ends, last gc (absolute time), number of gc, total pause ns.
+	p = (uint64*)pauses->array;
+	runtime·lock(&runtime·mheap.lock);
+
+	n = mstats.numgc;
+	if(n > nelem(mstats.pause_ns))
+		n = nelem(mstats.pause_ns);
+
+	// The pause buffer is circular. The most recent pause is at
+	// pause_ns[(numgc-1)%nelem(pause_ns)], and then backward
+	// from there to go back farther in time. We deliver the times
+	// most recent first (in p[0]).
+	for(i=0; i<n; i++) {
+		j = (mstats.numgc-1-i)%nelem(mstats.pause_ns);
+		p[i] = mstats.pause_ns[j];
+		p[n+i] = mstats.pause_end[j];
+	}
+
+	p[n+n] = mstats.last_gc;
+	p[n+n+1] = mstats.numgc;
+	p[n+n+2] = mstats.pause_total_ns;	
+	runtime·unlock(&runtime·mheap.lock);
+	pauses->len = n+n+3;
+}
+
+void
+runtime·setgcpercent_m(void)
+{
+	int32 in;
+	int32 out;
+
+	in = (int32)(intptr)g->m->scalararg[0];
+
+	runtime·lock(&runtime·mheap.lock);
+	out = runtime·gcpercent;
+	if(in < 0)
+		in = -1;
+	runtime·gcpercent = in;
+	runtime·unlock(&runtime·mheap.lock);
+
+	g->m->scalararg[0] = (uintptr)(intptr)out;
+}
+
+static void
+gchelperstart(void)
+{
+	if(g->m->helpgc < 0 || g->m->helpgc >= MaxGcproc)
+		runtime·throw("gchelperstart: bad m->helpgc");
+	if(g != g->m->g0)
+		runtime·throw("gchelper not running on g0 stack");
+}
+
+G*
+runtime·wakefing(void)
+{
+	G *res;
+
+	res = nil;
+	runtime·lock(&runtime·finlock);
+	if(runtime·fingwait && runtime·fingwake) {
+		runtime·fingwait = false;
+		runtime·fingwake = false;
+		res = runtime·fing;
+	}
+	runtime·unlock(&runtime·finlock);
+	return res;
+}
+
+// Recursively unrolls GC program in prog.
+// mask is where to store the result.
+// ppos is a pointer to position in mask, in bits.
+// sparse says to generate 4-bits per word mask for heap (2-bits for data/bss otherwise).
+static byte*
+unrollgcprog1(byte *mask, byte *prog, uintptr *ppos, bool inplace, bool sparse)
+{
+	uintptr pos, siz, i, off;
+	byte *arena_start, *prog1, v, *bitp, shift;
+
+	arena_start = runtime·mheap.arena_start;
+	pos = *ppos;
+	for(;;) {
+		switch(prog[0]) {
+		case insData:
+			prog++;
+			siz = prog[0];
+			prog++;
+			for(i = 0; i < siz; i++) {
+				v = prog[i/PointersPerByte];
+				v >>= (i%PointersPerByte)*BitsPerPointer;
+				v &= BitsMask;
+				if(inplace) {
+					// Store directly into GC bitmap.
+					off = (uintptr*)(mask+pos) - (uintptr*)arena_start;
+					bitp = arena_start - off/wordsPerBitmapByte - 1;
+					shift = (off % wordsPerBitmapByte) * gcBits;
+					if(shift==0)
+						*bitp = 0;
+					*bitp |= v<<(shift+2);
+					pos += PtrSize;
+				} else if(sparse) {
+					// 4-bits per word
+					v <<= (pos%8)+2;
+					mask[pos/8] |= v;
+					pos += gcBits;
+				} else {
+					// 2-bits per word
+					v <<= pos%8;
+					mask[pos/8] |= v;
+					pos += BitsPerPointer;
+				}
+			}
+			prog += ROUND(siz*BitsPerPointer, 8)/8;
+			break;
+		case insArray:
+			prog++;
+			siz = 0;
+			for(i = 0; i < PtrSize; i++)
+				siz = (siz<<8) + prog[PtrSize-i-1];
+			prog += PtrSize;
+			prog1 = nil;
+			for(i = 0; i < siz; i++)
+				prog1 = unrollgcprog1(mask, prog, &pos, inplace, sparse);
+			if(prog1[0] != insArrayEnd)
+				runtime·throw("unrollgcprog: array does not end with insArrayEnd");
+			prog = prog1+1;
+			break;
+		case insArrayEnd:
+		case insEnd:
+			*ppos = pos;
+			return prog;
+		default:
+			runtime·throw("unrollgcprog: unknown instruction");
+		}
+	}
+}
+
+// Unrolls GC program prog for data/bss, returns dense GC mask.
+static BitVector
+unrollglobgcprog(byte *prog, uintptr size)
+{
+	byte *mask;
+	uintptr pos, masksize;
+
+	masksize = ROUND(ROUND(size, PtrSize)/PtrSize*BitsPerPointer, 8)/8;
+	mask = runtime·persistentalloc(masksize+1, 0, &mstats.gc_sys);
+	mask[masksize] = 0xa1;
+	pos = 0;
+	prog = unrollgcprog1(mask, prog, &pos, false, false);
+	if(pos != size/PtrSize*BitsPerPointer) {
+		runtime·printf("unrollglobgcprog: bad program size, got %D, expect %D\n",
+			(uint64)pos, (uint64)size/PtrSize*BitsPerPointer);
+		runtime·throw("unrollglobgcprog: bad program size");
+	}
+	if(prog[0] != insEnd)
+		runtime·throw("unrollglobgcprog: program does not end with insEnd");
+	if(mask[masksize] != 0xa1)
+		runtime·throw("unrollglobgcprog: overflow");
+	return (BitVector){masksize*8, mask};
+}
+
+void
+runtime·unrollgcproginplace_m(void)
+{
+	uintptr size, size0, pos, off;
+	byte *arena_start, *prog, *bitp, shift;
+	Type *typ;
+	void *v;
+
+	v = g->m->ptrarg[0];
+	typ = g->m->ptrarg[1];
+	size = g->m->scalararg[0];
+	size0 = g->m->scalararg[1];
+	g->m->ptrarg[0] = nil;
+	g->m->ptrarg[1] = nil;
+
+	pos = 0;
+	prog = (byte*)typ->gc[1];
+	while(pos != size0)
+		unrollgcprog1(v, prog, &pos, true, true);
+	// Mark first word as bitAllocated.
+	arena_start = runtime·mheap.arena_start;
+	off = (uintptr*)v - (uintptr*)arena_start;
+	bitp = arena_start - off/wordsPerBitmapByte - 1;
+	shift = (off % wordsPerBitmapByte) * gcBits;
+	*bitp |= bitBoundary<<shift;
+	// Mark word after last as BitsDead.
+	if(size0 < size) {
+		off = (uintptr*)((byte*)v + size0) - (uintptr*)arena_start;
+		bitp = arena_start - off/wordsPerBitmapByte - 1;
+		shift = (off % wordsPerBitmapByte) * gcBits;
+		*bitp &= ~(bitPtrMask<<shift) | ((uintptr)BitsDead<<(shift+2));
+	}
+}
+
+// Unrolls GC program in typ->gc[1] into typ->gc[0]
+void
+runtime·unrollgcprog_m(void)
+{
+	static Mutex lock;
+	Type *typ;
+	byte *mask, *prog;
+	uintptr pos;
+	uint32 x;
+
+	typ = g->m->ptrarg[0];
+	g->m->ptrarg[0] = nil;
+
+	runtime·lock(&lock);
+	mask = (byte*)typ->gc[0];
+	if(mask[0] == 0) {
+		pos = 8;  // skip the unroll flag
+		prog = (byte*)typ->gc[1];
+		prog = unrollgcprog1(mask, prog, &pos, false, true);
+		if(prog[0] != insEnd)
+			runtime·throw("unrollgcprog: program does not end with insEnd");
+		if(((typ->size/PtrSize)%2) != 0) {
+			// repeat the program twice
+			prog = (byte*)typ->gc[1];
+			unrollgcprog1(mask, prog, &pos, false, true);
+		}
+		// atomic way to say mask[0] = 1
+		x = ((uint32*)mask)[0];
+		runtime·atomicstore((uint32*)mask, x|1);
+	}
+	runtime·unlock(&lock);
+}
+
+// mark the span of memory at v as having n blocks of the given size.
+// if leftover is true, there is left over space at the end of the span.
+void
+runtime·markspan(void *v, uintptr size, uintptr n, bool leftover)
+{
+	uintptr i, off, step;
+	byte *b;
+
+	if((byte*)v+size*n > (byte*)runtime·mheap.arena_used || (byte*)v < runtime·mheap.arena_start)
+		runtime·throw("markspan: bad pointer");
+
+	// Find bits of the beginning of the span.
+	off = (uintptr*)v - (uintptr*)runtime·mheap.arena_start;  // word offset
+	b = runtime·mheap.arena_start - off/wordsPerBitmapByte - 1;
+	if((off%wordsPerBitmapByte) != 0)
+		runtime·throw("markspan: unaligned length");
+
+	// Okay to use non-atomic ops here, because we control
+	// the entire span, and each bitmap byte has bits for only
+	// one span, so no other goroutines are changing these bitmap words.
+
+	if(size == PtrSize) {
+		// Possible only on 64-bits (minimal size class is 8 bytes).
+		// Poor man's memset(0x11).
+		if(0x11 != ((bitBoundary+BitsDead)<<gcBits) + (bitBoundary+BitsDead))
+			runtime·throw("markspan: bad bits");
+		if((n%(wordsPerBitmapByte*PtrSize)) != 0)
+			runtime·throw("markspan: unaligned length");
+		b = b - n/wordsPerBitmapByte + 1;	// find first byte
+		if(((uintptr)b%PtrSize) != 0)
+			runtime·throw("markspan: unaligned pointer");
+		for(i = 0; i != n; i += wordsPerBitmapByte*PtrSize, b += PtrSize)
+			*(uintptr*)b = (uintptr)0x1111111111111111ULL;  // bitBoundary+BitsDead
+		return;
+	}
+
+	if(leftover)
+		n++;	// mark a boundary just past end of last block too
+	step = size/(PtrSize*wordsPerBitmapByte);
+	for(i = 0; i != n; i++, b -= step)
+		*b = bitBoundary|(BitsDead<<2);
+}
+
+// unmark the span of memory at v of length n bytes.
+void
+runtime·unmarkspan(void *v, uintptr n)
+{
+	uintptr off;
+	byte *b;
+
+	if((byte*)v+n > (byte*)runtime·mheap.arena_used || (byte*)v < runtime·mheap.arena_start)
+		runtime·throw("markspan: bad pointer");
+
+	off = (uintptr*)v - (uintptr*)runtime·mheap.arena_start;  // word offset
+	if((off % (PtrSize*wordsPerBitmapByte)) != 0)
+		runtime·throw("markspan: unaligned pointer");
+	b = runtime·mheap.arena_start - off/wordsPerBitmapByte - 1;
+	n /= PtrSize;
+	if(n%(PtrSize*wordsPerBitmapByte) != 0)
+		runtime·throw("unmarkspan: unaligned length");
+	// Okay to use non-atomic ops here, because we control
+	// the entire span, and each bitmap word has bits for only
+	// one span, so no other goroutines are changing these
+	// bitmap words.
+	n /= wordsPerBitmapByte;
+	runtime·memclr(b - n + 1, n);
+}
+
+void
+runtime·MHeap_MapBits(MHeap *h)
+{
+	// Caller has added extra mappings to the arena.
+	// Add extra mappings of bitmap words as needed.
+	// We allocate extra bitmap pieces in chunks of bitmapChunk.
+	enum {
+		bitmapChunk = 8192
+	};
+	uintptr n;
+
+	n = (h->arena_used - h->arena_start) / (PtrSize*wordsPerBitmapByte);
+	n = ROUND(n, bitmapChunk);
+	n = ROUND(n, PhysPageSize);
+	if(h->bitmap_mapped >= n)
+		return;
+
+	runtime·SysMap(h->arena_start - n, n - h->bitmap_mapped, h->arena_reserved, &mstats.gc_sys);
+	h->bitmap_mapped = n;
+}
+
+static bool
+getgcmaskcb(Stkframe *frame, void *ctxt)
+{
+	Stkframe *frame0;
+
+	frame0 = ctxt;
+	if(frame->sp <= frame0->sp && frame0->sp < frame->varp) {
+		*frame0 = *frame;
+		return false;
+	}
+	return true;
+}
+
+// Returns GC type info for object p for testing.
+void
+runtime·getgcmask(byte *p, Type *t, byte **mask, uintptr *len)
+{
+	Stkframe frame;
+	uintptr i, n, off;
+	byte *base, bits, shift, *b;
+	bool (*cb)(Stkframe*, void*);
+
+	*mask = nil;
+	*len = 0;
+
+	// data
+	if(p >= runtime·data && p < runtime·edata) {
+		n = ((PtrType*)t)->elem->size;
+		*len = n/PtrSize;
+		*mask = runtime·mallocgc(*len, nil, FlagNoScan);
+		for(i = 0; i < n; i += PtrSize) {
+			off = (p+i-runtime·data)/PtrSize;
+			bits = (runtime·gcdatamask.bytedata[off/PointersPerByte] >> ((off%PointersPerByte)*BitsPerPointer))&BitsMask;
+			(*mask)[i/PtrSize] = bits;
+		}
+		return;
+	}
+	// bss
+	if(p >= runtime·bss && p < runtime·ebss) {
+		n = ((PtrType*)t)->elem->size;
+		*len = n/PtrSize;
+		*mask = runtime·mallocgc(*len, nil, FlagNoScan);
+		for(i = 0; i < n; i += PtrSize) {
+			off = (p+i-runtime·bss)/PtrSize;
+			bits = (runtime·gcbssmask.bytedata[off/PointersPerByte] >> ((off%PointersPerByte)*BitsPerPointer))&BitsMask;
+			(*mask)[i/PtrSize] = bits;
+		}
+		return;
+	}
+	// heap
+	if(runtime·mlookup(p, &base, &n, nil)) {
+		*len = n/PtrSize;
+		*mask = runtime·mallocgc(*len, nil, FlagNoScan);
+		for(i = 0; i < n; i += PtrSize) {
+			off = (uintptr*)(base+i) - (uintptr*)runtime·mheap.arena_start;
+			b = runtime·mheap.arena_start - off/wordsPerBitmapByte - 1;
+			shift = (off % wordsPerBitmapByte) * gcBits;
+			bits = (*b >> (shift+2))&BitsMask;
+			(*mask)[i/PtrSize] = bits;
+		}
+		return;
+	}
+	// stack
+	frame.fn = nil;
+	frame.sp = (uintptr)p;
+	cb = getgcmaskcb;
+	runtime·gentraceback(g->m->curg->sched.pc, g->m->curg->sched.sp, 0, g->m->curg, 0, nil, 1000, &cb, &frame, 0);
+	if(frame.fn != nil) {
+		Func *f;
+		StackMap *stackmap;
+		BitVector bv;
+		uintptr size;
+		uintptr targetpc;
+		int32 pcdata;
+
+		f = frame.fn;
+		targetpc = frame.continpc;
+		if(targetpc == 0)
+			return;
+		if(targetpc != f->entry)
+			targetpc--;
+		pcdata = runtime·pcdatavalue(f, PCDATA_StackMapIndex, targetpc);
+		if(pcdata == -1)
+			return;
+		stackmap = runtime·funcdata(f, FUNCDATA_LocalsPointerMaps);
+		if(stackmap == nil || stackmap->n <= 0)
+			return;
+		bv = runtime·stackmapdata(stackmap, pcdata);
+		size = bv.n/BitsPerPointer*PtrSize;
+		n = ((PtrType*)t)->elem->size;
+		*len = n/PtrSize;
+		*mask = runtime·mallocgc(*len, nil, FlagNoScan);
+		for(i = 0; i < n; i += PtrSize) {
+			off = (p+i-(byte*)frame.varp+size)/PtrSize;
+			bits = (bv.bytedata[off*BitsPerPointer/8] >> ((off*BitsPerPointer)%8))&BitsMask;
+			(*mask)[i/PtrSize] = bits;
+		}
+	}
+}
+
+void runtime·gc_unixnanotime(int64 *now);
+
+int64
+runtime·unixnanotime(void)
+{
+	int64 now;
+
+	runtime·gc_unixnanotime(&now);
+	return now;
+}
diff --git a/src/runtime/mgc0.go b/src/runtime/mgc0.go
new file mode 100644
index 0000000..cbf5e9c
--- /dev/null
+++ b/src/runtime/mgc0.go
@@ -0,0 +1,152 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package runtime
+
+import "unsafe"
+
+// Called from C. Returns the Go type *m.
+func gc_m_ptr(ret *interface{}) {
+	*ret = (*m)(nil)
+}
+
+// Called from C. Returns the Go type *g.
+func gc_g_ptr(ret *interface{}) {
+	*ret = (*g)(nil)
+}
+
+// Called from C. Returns the Go type *itab.
+func gc_itab_ptr(ret *interface{}) {
+	*ret = (*itab)(nil)
+}
+
+func gc_unixnanotime(now *int64) {
+	sec, nsec := timenow()
+	*now = sec*1e9 + int64(nsec)
+}
+
+func freeOSMemory() {
+	gogc(2) // force GC and do eager sweep
+	onM(scavenge_m)
+}
+
+var poolcleanup func()
+
+func registerPoolCleanup(f func()) {
+	poolcleanup = f
+}
+
+func clearpools() {
+	// clear sync.Pools
+	if poolcleanup != nil {
+		poolcleanup()
+	}
+
+	for _, p := range &allp {
+		if p == nil {
+			break
+		}
+		// clear tinyalloc pool
+		if c := p.mcache; c != nil {
+			c.tiny = nil
+			c.tinysize = 0
+
+			// disconnect cached list before dropping it on the floor,
+			// so that a dangling ref to one entry does not pin all of them.
+			var sg, sgnext *sudog
+			for sg = c.sudogcache; sg != nil; sg = sgnext {
+				sgnext = sg.next
+				sg.next = nil
+			}
+			c.sudogcache = nil
+		}
+
+		// clear defer pools
+		for i := range p.deferpool {
+			// disconnect cached list before dropping it on the floor,
+			// so that a dangling ref to one entry does not pin all of them.
+			var d, dlink *_defer
+			for d = p.deferpool[i]; d != nil; d = dlink {
+				dlink = d.link
+				d.link = nil
+			}
+			p.deferpool[i] = nil
+		}
+	}
+}
+
+func gosweepone() uintptr
+func gosweepdone() bool
+
+func bgsweep() {
+	getg().issystem = true
+	for {
+		for gosweepone() != ^uintptr(0) {
+			sweep.nbgsweep++
+			Gosched()
+		}
+		lock(&gclock)
+		if !gosweepdone() {
+			// This can happen if a GC runs between
+			// gosweepone returning ^0 above
+			// and the lock being acquired.
+			unlock(&gclock)
+			continue
+		}
+		sweep.parked = true
+		goparkunlock(&gclock, "GC sweep wait")
+	}
+}
+
+// NOTE: Really dst *unsafe.Pointer, src unsafe.Pointer,
+// but if we do that, Go inserts a write barrier on *dst = src.
+//go:nosplit
+func writebarrierptr(dst *uintptr, src uintptr) {
+	*dst = src
+}
+
+//go:nosplit
+func writebarrierstring(dst *[2]uintptr, src [2]uintptr) {
+	dst[0] = src[0]
+	dst[1] = src[1]
+}
+
+//go:nosplit
+func writebarrierslice(dst *[3]uintptr, src [3]uintptr) {
+	dst[0] = src[0]
+	dst[1] = src[1]
+	dst[2] = src[2]
+}
+
+//go:nosplit
+func writebarrieriface(dst *[2]uintptr, src [2]uintptr) {
+	dst[0] = src[0]
+	dst[1] = src[1]
+}
+
+//go:nosplit
+func writebarrierfat2(dst *[2]uintptr, _ *byte, src [2]uintptr) {
+	dst[0] = src[0]
+	dst[1] = src[1]
+}
+
+//go:nosplit
+func writebarrierfat3(dst *[3]uintptr, _ *byte, src [3]uintptr) {
+	dst[0] = src[0]
+	dst[1] = src[1]
+	dst[2] = src[2]
+}
+
+//go:nosplit
+func writebarrierfat4(dst *[4]uintptr, _ *byte, src [4]uintptr) {
+	dst[0] = src[0]
+	dst[1] = src[1]
+	dst[2] = src[2]
+	dst[3] = src[3]
+}
+
+//go:nosplit
+func writebarrierfat(typ *_type, dst, src unsafe.Pointer) {
+	memmove(dst, src, typ.size)
+}
diff --git a/src/runtime/mgc0.h b/src/runtime/mgc0.h
new file mode 100644
index 0000000..64f8189
--- /dev/null
+++ b/src/runtime/mgc0.h
@@ -0,0 +1,78 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Garbage collector (GC)
+
+enum {
+	// Four bits per word (see #defines below).
+	gcBits = 4,
+	wordsPerBitmapByte = 8/gcBits,
+
+	// GC type info programs.
+	// The programs allow to store type info required for GC in a compact form.
+	// Most importantly arrays take O(1) space instead of O(n).
+	// The program grammar is:
+	//
+	// Program = {Block} "insEnd"
+	// Block = Data | Array
+	// Data = "insData" DataSize DataBlock
+	// DataSize = int // size of the DataBlock in bit pairs, 1 byte
+	// DataBlock = binary // dense GC mask (2 bits per word) of size ]DataSize/4[ bytes
+	// Array = "insArray" ArrayLen Block "insArrayEnd"
+	// ArrayLen = int // length of the array, 8 bytes (4 bytes for 32-bit arch)
+	//
+	// Each instruction (insData, insArray, etc) is 1 byte.
+	// For example, for type struct { x []byte; y [20]struct{ z int; w *byte }; }
+	// the program looks as:
+	//
+	// insData 3 (BitsMultiWord BitsSlice BitsScalar)
+	//	insArray 20 insData 2 (BitsScalar BitsPointer) insArrayEnd insEnd
+	//
+	// Total size of the program is 17 bytes (13 bytes on 32-bits).
+	// The corresponding GC mask would take 43 bytes (it would be repeated
+	// because the type has odd number of words).
+	insData = 1,
+	insArray,
+	insArrayEnd,
+	insEnd,
+
+	// Pointer map
+	BitsPerPointer	= 2,
+	BitsMask	= (1<<BitsPerPointer)-1,
+	PointersPerByte	= 8/BitsPerPointer,
+
+	// If you change these, also change scanblock.
+	// scanblock does "if(bits == BitsScalar || bits == BitsDead)" as "if(bits <= BitsScalar)".
+	BitsDead	= 0,
+	BitsScalar	= 1,
+	BitsPointer	= 2,
+	BitsMultiWord	= 3,
+	// BitsMultiWord will be set for the first word of a multi-word item.
+	// When it is set, one of the following will be set for the second word.
+	// NOT USED ANYMORE: BitsString	= 0,
+	// NOT USED ANYMORE: BitsSlice	= 1,
+	BitsIface	= 2,
+	BitsEface	= 3,
+
+	// 64 bytes cover objects of size 1024/512 on 64/32 bits, respectively.
+	MaxGCMask	= 64,
+};
+
+// Bits in per-word bitmap.
+// #defines because we shift the values beyond 32 bits.
+//
+// Each word in the bitmap describes wordsPerBitmapWord words
+// of heap memory.  There are 4 bitmap bits dedicated to each heap word,
+// so on a 64-bit system there is one bitmap word per 16 heap words.
+//
+// The bitmap starts at mheap.arena_start and extends *backward* from
+// there.  On a 64-bit system the off'th word in the arena is tracked by
+// the off/16+1'th word before mheap.arena_start.  (On a 32-bit system,
+// the only difference is that the divisor is 8.)
+enum {
+	bitBoundary = 1, // boundary of an object
+	bitMarked = 2, // marked object
+	bitMask = bitBoundary | bitMarked,
+	bitPtrMask = BitsMask<<2,
+};
diff --git a/src/runtime/mheap.c b/src/runtime/mheap.c
new file mode 100644
index 0000000..bb203d5
--- /dev/null
+++ b/src/runtime/mheap.c
@@ -0,0 +1,889 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Page heap.
+//
+// See malloc.h for overview.
+//
+// When a MSpan is in the heap free list, state == MSpanFree
+// and heapmap(s->start) == span, heapmap(s->start+s->npages-1) == span.
+//
+// When a MSpan is allocated, state == MSpanInUse or MSpanStack
+// and heapmap(i) == span for all s->start <= i < s->start+s->npages.
+
+#include "runtime.h"
+#include "arch_GOARCH.h"
+#include "malloc.h"
+
+static MSpan *MHeap_AllocSpanLocked(MHeap*, uintptr);
+static void MHeap_FreeSpanLocked(MHeap*, MSpan*, bool, bool);
+static bool MHeap_Grow(MHeap*, uintptr);
+static MSpan *MHeap_AllocLarge(MHeap*, uintptr);
+static MSpan *BestFit(MSpan*, uintptr, MSpan*);
+
+static void
+RecordSpan(void *vh, byte *p)
+{
+	MHeap *h;
+	MSpan *s;
+	MSpan **all;
+	uint32 cap;
+
+	h = vh;
+	s = (MSpan*)p;
+	if(h->nspan >= h->nspancap) {
+		cap = 64*1024/sizeof(all[0]);
+		if(cap < h->nspancap*3/2)
+			cap = h->nspancap*3/2;
+		all = (MSpan**)runtime·sysAlloc(cap*sizeof(all[0]), &mstats.other_sys);
+		if(all == nil)
+			runtime·throw("runtime: cannot allocate memory");
+		if(h->allspans) {
+			runtime·memmove(all, h->allspans, h->nspancap*sizeof(all[0]));
+			// Don't free the old array if it's referenced by sweep.
+			// See the comment in mgc0.c.
+			if(h->allspans != runtime·mheap.gcspans)
+				runtime·SysFree(h->allspans, h->nspancap*sizeof(all[0]), &mstats.other_sys);
+		}
+		h->allspans = all;
+		h->nspancap = cap;
+	}
+	h->allspans[h->nspan++] = s;
+}
+
+// Initialize the heap; fetch memory using alloc.
+void
+runtime·MHeap_Init(MHeap *h)
+{
+	uint32 i;
+
+	runtime·FixAlloc_Init(&h->spanalloc, sizeof(MSpan), RecordSpan, h, &mstats.mspan_sys);
+	runtime·FixAlloc_Init(&h->cachealloc, sizeof(MCache), nil, nil, &mstats.mcache_sys);
+	runtime·FixAlloc_Init(&h->specialfinalizeralloc, sizeof(SpecialFinalizer), nil, nil, &mstats.other_sys);
+	runtime·FixAlloc_Init(&h->specialprofilealloc, sizeof(SpecialProfile), nil, nil, &mstats.other_sys);
+	// h->mapcache needs no init
+	for(i=0; i<nelem(h->free); i++) {
+		runtime·MSpanList_Init(&h->free[i]);
+		runtime·MSpanList_Init(&h->busy[i]);
+	}
+	runtime·MSpanList_Init(&h->freelarge);
+	runtime·MSpanList_Init(&h->busylarge);
+	for(i=0; i<nelem(h->central); i++)
+		runtime·MCentral_Init(&h->central[i].mcentral, i);
+}
+
+void
+runtime·MHeap_MapSpans(MHeap *h)
+{
+	uintptr n;
+
+	// Map spans array, PageSize at a time.
+	n = (uintptr)h->arena_used;
+	n -= (uintptr)h->arena_start;
+	n = n / PageSize * sizeof(h->spans[0]);
+	n = ROUND(n, PhysPageSize);
+	if(h->spans_mapped >= n)
+		return;
+	runtime·SysMap((byte*)h->spans + h->spans_mapped, n - h->spans_mapped, h->arena_reserved, &mstats.other_sys);
+	h->spans_mapped = n;
+}
+
+// Sweeps spans in list until reclaims at least npages into heap.
+// Returns the actual number of pages reclaimed.
+static uintptr
+MHeap_ReclaimList(MHeap *h, MSpan *list, uintptr npages)
+{
+	MSpan *s;
+	uintptr n;
+	uint32 sg;
+
+	n = 0;
+	sg = runtime·mheap.sweepgen;
+retry:
+	for(s = list->next; s != list; s = s->next) {
+		if(s->sweepgen == sg-2 && runtime·cas(&s->sweepgen, sg-2, sg-1)) {
+			runtime·MSpanList_Remove(s);
+			// swept spans are at the end of the list
+			runtime·MSpanList_InsertBack(list, s);
+			runtime·unlock(&h->lock);
+			n += runtime·MSpan_Sweep(s, false);
+			runtime·lock(&h->lock);
+			if(n >= npages)
+				return n;
+			// the span could have been moved elsewhere
+			goto retry;
+		}
+		if(s->sweepgen == sg-1) {
+			// the span is being sweept by background sweeper, skip
+			continue;
+		}
+		// already swept empty span,
+		// all subsequent ones must also be either swept or in process of sweeping
+		break;
+	}
+	return n;
+}
+
+// Sweeps and reclaims at least npage pages into heap.
+// Called before allocating npage pages.
+static void
+MHeap_Reclaim(MHeap *h, uintptr npage)
+{
+	uintptr reclaimed, n;
+
+	// First try to sweep busy spans with large objects of size >= npage,
+	// this has good chances of reclaiming the necessary space.
+	for(n=npage; n < nelem(h->busy); n++) {
+		if(MHeap_ReclaimList(h, &h->busy[n], npage))
+			return;  // Bingo!
+	}
+
+	// Then -- even larger objects.
+	if(MHeap_ReclaimList(h, &h->busylarge, npage))
+		return;  // Bingo!
+
+	// Now try smaller objects.
+	// One such object is not enough, so we need to reclaim several of them.
+	reclaimed = 0;
+	for(n=0; n < npage && n < nelem(h->busy); n++) {
+		reclaimed += MHeap_ReclaimList(h, &h->busy[n], npage-reclaimed);
+		if(reclaimed >= npage)
+			return;
+	}
+
+	// Now sweep everything that is not yet swept.
+	runtime·unlock(&h->lock);
+	for(;;) {
+		n = runtime·sweepone();
+		if(n == -1)  // all spans are swept
+			break;
+		reclaimed += n;
+		if(reclaimed >= npage)
+			break;
+	}
+	runtime·lock(&h->lock);
+}
+
+// Allocate a new span of npage pages from the heap for GC'd memory
+// and record its size class in the HeapMap and HeapMapCache.
+static MSpan*
+mheap_alloc(MHeap *h, uintptr npage, int32 sizeclass, bool large)
+{
+	MSpan *s;
+
+	if(g != g->m->g0)
+		runtime·throw("mheap_alloc not on M stack");
+	runtime·lock(&h->lock);
+
+	// To prevent excessive heap growth, before allocating n pages
+	// we need to sweep and reclaim at least n pages.
+	if(!h->sweepdone)
+		MHeap_Reclaim(h, npage);
+
+	// transfer stats from cache to global
+	mstats.heap_alloc += g->m->mcache->local_cachealloc;
+	g->m->mcache->local_cachealloc = 0;
+	mstats.tinyallocs += g->m->mcache->local_tinyallocs;
+	g->m->mcache->local_tinyallocs = 0;
+
+	s = MHeap_AllocSpanLocked(h, npage);
+	if(s != nil) {
+		// Record span info, because gc needs to be
+		// able to map interior pointer to containing span.
+		runtime·atomicstore(&s->sweepgen, h->sweepgen);
+		s->state = MSpanInUse;
+		s->freelist = nil;
+		s->ref = 0;
+		s->sizeclass = sizeclass;
+		s->elemsize = (sizeclass==0 ? s->npages<<PageShift : runtime·class_to_size[sizeclass]);
+
+		// update stats, sweep lists
+		if(large) {
+			mstats.heap_objects++;
+			mstats.heap_alloc += npage<<PageShift;
+			// Swept spans are at the end of lists.
+			if(s->npages < nelem(h->free))
+				runtime·MSpanList_InsertBack(&h->busy[s->npages], s);
+			else
+				runtime·MSpanList_InsertBack(&h->busylarge, s);
+		}
+	}
+	runtime·unlock(&h->lock);
+	return s;
+}
+
+static void
+mheap_alloc_m(G *gp)
+{
+	MHeap *h;
+	MSpan *s;
+
+	h = g->m->ptrarg[0];
+	g->m->ptrarg[0] = nil;
+	s = mheap_alloc(h, g->m->scalararg[0], g->m->scalararg[1], g->m->scalararg[2]);
+	g->m->ptrarg[0] = s;
+
+	runtime·gogo(&gp->sched);
+}
+
+MSpan*
+runtime·MHeap_Alloc(MHeap *h, uintptr npage, int32 sizeclass, bool large, bool needzero)
+{
+	MSpan *s;
+	void (*fn)(G*);
+
+	// Don't do any operations that lock the heap on the G stack.
+	// It might trigger stack growth, and the stack growth code needs
+	// to be able to allocate heap.
+	if(g == g->m->g0) {
+		s = mheap_alloc(h, npage, sizeclass, large);
+	} else {
+		g->m->ptrarg[0] = h;
+		g->m->scalararg[0] = npage;
+		g->m->scalararg[1] = sizeclass;
+		g->m->scalararg[2] = large;
+		fn = mheap_alloc_m;
+		runtime·mcall(&fn);
+		s = g->m->ptrarg[0];
+		g->m->ptrarg[0] = nil;
+	}
+	if(s != nil) {
+		if(needzero && s->needzero)
+			runtime·memclr((byte*)(s->start<<PageShift), s->npages<<PageShift);
+		s->needzero = 0;
+	}
+	return s;
+}
+
+MSpan*
+runtime·MHeap_AllocStack(MHeap *h, uintptr npage)
+{
+	MSpan *s;
+
+	if(g != g->m->g0)
+		runtime·throw("mheap_allocstack not on M stack");
+	runtime·lock(&h->lock);
+	s = MHeap_AllocSpanLocked(h, npage);
+	if(s != nil) {
+		s->state = MSpanStack;
+		s->freelist = nil;
+		s->ref = 0;
+		mstats.stacks_inuse += s->npages<<PageShift;
+	}
+	runtime·unlock(&h->lock);
+	return s;
+}
+
+// Allocates a span of the given size.  h must be locked.
+// The returned span has been removed from the
+// free list, but its state is still MSpanFree.
+static MSpan*
+MHeap_AllocSpanLocked(MHeap *h, uintptr npage)
+{
+	uintptr n;
+	MSpan *s, *t;
+	pageID p;
+
+	// Try in fixed-size lists up to max.
+	for(n=npage; n < nelem(h->free); n++) {
+		if(!runtime·MSpanList_IsEmpty(&h->free[n])) {
+			s = h->free[n].next;
+			goto HaveSpan;
+		}
+	}
+
+	// Best fit in list of large spans.
+	if((s = MHeap_AllocLarge(h, npage)) == nil) {
+		if(!MHeap_Grow(h, npage))
+			return nil;
+		if((s = MHeap_AllocLarge(h, npage)) == nil)
+			return nil;
+	}
+
+HaveSpan:
+	// Mark span in use.
+	if(s->state != MSpanFree)
+		runtime·throw("MHeap_AllocLocked - MSpan not free");
+	if(s->npages < npage)
+		runtime·throw("MHeap_AllocLocked - bad npages");
+	runtime·MSpanList_Remove(s);
+	if(s->next != nil || s->prev != nil)
+		runtime·throw("still in list");
+	if(s->npreleased > 0) {
+		runtime·SysUsed((void*)(s->start<<PageShift), s->npages<<PageShift);
+		mstats.heap_released -= s->npreleased<<PageShift;
+		s->npreleased = 0;
+	}
+
+	if(s->npages > npage) {
+		// Trim extra and put it back in the heap.
+		t = runtime·FixAlloc_Alloc(&h->spanalloc);
+		runtime·MSpan_Init(t, s->start + npage, s->npages - npage);
+		s->npages = npage;
+		p = t->start;
+		p -= ((uintptr)h->arena_start>>PageShift);
+		if(p > 0)
+			h->spans[p-1] = s;
+		h->spans[p] = t;
+		h->spans[p+t->npages-1] = t;
+		t->needzero = s->needzero;
+		s->state = MSpanStack; // prevent coalescing with s
+		t->state = MSpanStack;
+		MHeap_FreeSpanLocked(h, t, false, false);
+		t->unusedsince = s->unusedsince; // preserve age (TODO: wrong: t is possibly merged and/or deallocated at this point)
+		s->state = MSpanFree;
+	}
+	s->unusedsince = 0;
+
+	p = s->start;
+	p -= ((uintptr)h->arena_start>>PageShift);
+	for(n=0; n<npage; n++)
+		h->spans[p+n] = s;
+
+	mstats.heap_inuse += npage<<PageShift;
+	mstats.heap_idle -= npage<<PageShift;
+
+	//runtime·printf("spanalloc %p\n", s->start << PageShift);
+	if(s->next != nil || s->prev != nil)
+		runtime·throw("still in list");
+	return s;
+}
+
+// Allocate a span of exactly npage pages from the list of large spans.
+static MSpan*
+MHeap_AllocLarge(MHeap *h, uintptr npage)
+{
+	return BestFit(&h->freelarge, npage, nil);
+}
+
+// Search list for smallest span with >= npage pages.
+// If there are multiple smallest spans, take the one
+// with the earliest starting address.
+static MSpan*
+BestFit(MSpan *list, uintptr npage, MSpan *best)
+{
+	MSpan *s;
+
+	for(s=list->next; s != list; s=s->next) {
+		if(s->npages < npage)
+			continue;
+		if(best == nil
+		|| s->npages < best->npages
+		|| (s->npages == best->npages && s->start < best->start))
+			best = s;
+	}
+	return best;
+}
+
+// Try to add at least npage pages of memory to the heap,
+// returning whether it worked.
+static bool
+MHeap_Grow(MHeap *h, uintptr npage)
+{
+	uintptr ask;
+	void *v;
+	MSpan *s;
+	pageID p;
+
+	// Ask for a big chunk, to reduce the number of mappings
+	// the operating system needs to track; also amortizes
+	// the overhead of an operating system mapping.
+	// Allocate a multiple of 64kB.
+	npage = ROUND(npage, (64<<10)/PageSize);
+	ask = npage<<PageShift;
+	if(ask < HeapAllocChunk)
+		ask = HeapAllocChunk;
+
+	v = runtime·MHeap_SysAlloc(h, ask);
+	if(v == nil) {
+		if(ask > (npage<<PageShift)) {
+			ask = npage<<PageShift;
+			v = runtime·MHeap_SysAlloc(h, ask);
+		}
+		if(v == nil) {
+			runtime·printf("runtime: out of memory: cannot allocate %D-byte block (%D in use)\n", (uint64)ask, mstats.heap_sys);
+			return false;
+		}
+	}
+
+	// Create a fake "in use" span and free it, so that the
+	// right coalescing happens.
+	s = runtime·FixAlloc_Alloc(&h->spanalloc);
+	runtime·MSpan_Init(s, (uintptr)v>>PageShift, ask>>PageShift);
+	p = s->start;
+	p -= ((uintptr)h->arena_start>>PageShift);
+	h->spans[p] = s;
+	h->spans[p + s->npages - 1] = s;
+	runtime·atomicstore(&s->sweepgen, h->sweepgen);
+	s->state = MSpanInUse;
+	MHeap_FreeSpanLocked(h, s, false, true);
+	return true;
+}
+
+// Look up the span at the given address.
+// Address is guaranteed to be in map
+// and is guaranteed to be start or end of span.
+MSpan*
+runtime·MHeap_Lookup(MHeap *h, void *v)
+{
+	uintptr p;
+	
+	p = (uintptr)v;
+	p -= (uintptr)h->arena_start;
+	return h->spans[p >> PageShift];
+}
+
+// Look up the span at the given address.
+// Address is *not* guaranteed to be in map
+// and may be anywhere in the span.
+// Map entries for the middle of a span are only
+// valid for allocated spans.  Free spans may have
+// other garbage in their middles, so we have to
+// check for that.
+MSpan*
+runtime·MHeap_LookupMaybe(MHeap *h, void *v)
+{
+	MSpan *s;
+	pageID p, q;
+
+	if((byte*)v < h->arena_start || (byte*)v >= h->arena_used)
+		return nil;
+	p = (uintptr)v>>PageShift;
+	q = p;
+	q -= (uintptr)h->arena_start >> PageShift;
+	s = h->spans[q];
+	if(s == nil || p < s->start || v >= s->limit || s->state != MSpanInUse)
+		return nil;
+	return s;
+}
+
+// Free the span back into the heap.
+static void
+mheap_free(MHeap *h, MSpan *s, int32 acct)
+{
+	if(g != g->m->g0)
+		runtime·throw("mheap_free not on M stack");
+	runtime·lock(&h->lock);
+	mstats.heap_alloc += g->m->mcache->local_cachealloc;
+	g->m->mcache->local_cachealloc = 0;
+	mstats.tinyallocs += g->m->mcache->local_tinyallocs;
+	g->m->mcache->local_tinyallocs = 0;
+	if(acct) {
+		mstats.heap_alloc -= s->npages<<PageShift;
+		mstats.heap_objects--;
+	}
+	MHeap_FreeSpanLocked(h, s, true, true);
+	runtime·unlock(&h->lock);
+}
+
+static void
+mheap_free_m(G *gp)
+{
+	MHeap *h;
+	MSpan *s;
+	
+	h = g->m->ptrarg[0];
+	s = g->m->ptrarg[1];
+	g->m->ptrarg[0] = nil;
+	g->m->ptrarg[1] = nil;
+	mheap_free(h, s, g->m->scalararg[0]);
+	runtime·gogo(&gp->sched);
+}
+
+void
+runtime·MHeap_Free(MHeap *h, MSpan *s, int32 acct)
+{
+	void (*fn)(G*);
+
+	if(g == g->m->g0) {
+		mheap_free(h, s, acct);
+	} else {
+		g->m->ptrarg[0] = h;
+		g->m->ptrarg[1] = s;
+		g->m->scalararg[0] = acct;
+		fn = mheap_free_m;
+		runtime·mcall(&fn);
+	}
+}
+
+void
+runtime·MHeap_FreeStack(MHeap *h, MSpan *s)
+{
+	if(g != g->m->g0)
+		runtime·throw("mheap_freestack not on M stack");
+	s->needzero = 1;
+	runtime·lock(&h->lock);
+	mstats.stacks_inuse -= s->npages<<PageShift;
+	MHeap_FreeSpanLocked(h, s, true, true);
+	runtime·unlock(&h->lock);
+}
+
+static void
+MHeap_FreeSpanLocked(MHeap *h, MSpan *s, bool acctinuse, bool acctidle)
+{
+	MSpan *t;
+	pageID p;
+
+	switch(s->state) {
+	case MSpanStack:
+		if(s->ref != 0)
+			runtime·throw("MHeap_FreeSpanLocked - invalid stack free");
+		break;
+	case MSpanInUse:
+		if(s->ref != 0 || s->sweepgen != h->sweepgen) {
+			runtime·printf("MHeap_FreeSpanLocked - span %p ptr %p ref %d sweepgen %d/%d\n",
+				       s, s->start<<PageShift, s->ref, s->sweepgen, h->sweepgen);
+			runtime·throw("MHeap_FreeSpanLocked - invalid free");
+		}
+		break;
+	default:
+		runtime·throw("MHeap_FreeSpanLocked - invalid span state");
+		break;
+	}
+	if(acctinuse)
+		mstats.heap_inuse -= s->npages<<PageShift;
+	if(acctidle)
+		mstats.heap_idle += s->npages<<PageShift;
+	s->state = MSpanFree;
+	runtime·MSpanList_Remove(s);
+	// Stamp newly unused spans. The scavenger will use that
+	// info to potentially give back some pages to the OS.
+	s->unusedsince = runtime·nanotime();
+	s->npreleased = 0;
+
+	// Coalesce with earlier, later spans.
+	p = s->start;
+	p -= (uintptr)h->arena_start >> PageShift;
+	if(p > 0 && (t = h->spans[p-1]) != nil && t->state != MSpanInUse && t->state != MSpanStack) {
+		s->start = t->start;
+		s->npages += t->npages;
+		s->npreleased = t->npreleased; // absorb released pages
+		s->needzero |= t->needzero;
+		p -= t->npages;
+		h->spans[p] = s;
+		runtime·MSpanList_Remove(t);
+		t->state = MSpanDead;
+		runtime·FixAlloc_Free(&h->spanalloc, t);
+	}
+	if((p+s->npages)*sizeof(h->spans[0]) < h->spans_mapped && (t = h->spans[p+s->npages]) != nil && t->state != MSpanInUse && t->state != MSpanStack) {
+		s->npages += t->npages;
+		s->npreleased += t->npreleased;
+		s->needzero |= t->needzero;
+		h->spans[p + s->npages - 1] = s;
+		runtime·MSpanList_Remove(t);
+		t->state = MSpanDead;
+		runtime·FixAlloc_Free(&h->spanalloc, t);
+	}
+
+	// Insert s into appropriate list.
+	if(s->npages < nelem(h->free))
+		runtime·MSpanList_Insert(&h->free[s->npages], s);
+	else
+		runtime·MSpanList_Insert(&h->freelarge, s);
+}
+
+static uintptr
+scavengelist(MSpan *list, uint64 now, uint64 limit)
+{
+	uintptr released, sumreleased;
+	MSpan *s;
+
+	if(runtime·MSpanList_IsEmpty(list))
+		return 0;
+
+	sumreleased = 0;
+	for(s=list->next; s != list; s=s->next) {
+		if((now - s->unusedsince) > limit && s->npreleased != s->npages) {
+			released = (s->npages - s->npreleased) << PageShift;
+			mstats.heap_released += released;
+			sumreleased += released;
+			s->npreleased = s->npages;
+			runtime·SysUnused((void*)(s->start << PageShift), s->npages << PageShift);
+		}
+	}
+	return sumreleased;
+}
+
+void
+runtime·MHeap_Scavenge(int32 k, uint64 now, uint64 limit)
+{
+	uint32 i;
+	uintptr sumreleased;
+	MHeap *h;
+	
+	h = &runtime·mheap;
+	runtime·lock(&h->lock);
+	sumreleased = 0;
+	for(i=0; i < nelem(h->free); i++)
+		sumreleased += scavengelist(&h->free[i], now, limit);
+	sumreleased += scavengelist(&h->freelarge, now, limit);
+	runtime·unlock(&h->lock);
+
+	if(runtime·debug.gctrace > 0) {
+		if(sumreleased > 0)
+			runtime·printf("scvg%d: %D MB released\n", k, (uint64)sumreleased>>20);
+		// TODO(dvyukov): these stats are incorrect as we don't subtract stack usage from heap.
+		// But we can't call ReadMemStats on g0 holding locks.
+		runtime·printf("scvg%d: inuse: %D, idle: %D, sys: %D, released: %D, consumed: %D (MB)\n",
+			k, mstats.heap_inuse>>20, mstats.heap_idle>>20, mstats.heap_sys>>20,
+			mstats.heap_released>>20, (mstats.heap_sys - mstats.heap_released)>>20);
+	}
+}
+
+void
+runtime·scavenge_m(void)
+{
+	runtime·MHeap_Scavenge(-1, ~(uintptr)0, 0);
+}
+
+// Initialize a new span with the given start and npages.
+void
+runtime·MSpan_Init(MSpan *span, pageID start, uintptr npages)
+{
+	span->next = nil;
+	span->prev = nil;
+	span->start = start;
+	span->npages = npages;
+	span->freelist = nil;
+	span->ref = 0;
+	span->sizeclass = 0;
+	span->incache = false;
+	span->elemsize = 0;
+	span->state = MSpanDead;
+	span->unusedsince = 0;
+	span->npreleased = 0;
+	span->specialLock.key = 0;
+	span->specials = nil;
+	span->needzero = 0;
+}
+
+// Initialize an empty doubly-linked list.
+void
+runtime·MSpanList_Init(MSpan *list)
+{
+	list->state = MSpanListHead;
+	list->next = list;
+	list->prev = list;
+}
+
+void
+runtime·MSpanList_Remove(MSpan *span)
+{
+	if(span->prev == nil && span->next == nil)
+		return;
+	span->prev->next = span->next;
+	span->next->prev = span->prev;
+	span->prev = nil;
+	span->next = nil;
+}
+
+bool
+runtime·MSpanList_IsEmpty(MSpan *list)
+{
+	return list->next == list;
+}
+
+void
+runtime·MSpanList_Insert(MSpan *list, MSpan *span)
+{
+	if(span->next != nil || span->prev != nil) {
+		runtime·printf("failed MSpanList_Insert %p %p %p\n", span, span->next, span->prev);
+		runtime·throw("MSpanList_Insert");
+	}
+	span->next = list->next;
+	span->prev = list;
+	span->next->prev = span;
+	span->prev->next = span;
+}
+
+void
+runtime·MSpanList_InsertBack(MSpan *list, MSpan *span)
+{
+	if(span->next != nil || span->prev != nil) {
+		runtime·printf("failed MSpanList_Insert %p %p %p\n", span, span->next, span->prev);
+		runtime·throw("MSpanList_Insert");
+	}
+	span->next = list;
+	span->prev = list->prev;
+	span->next->prev = span;
+	span->prev->next = span;
+}
+
+// Adds the special record s to the list of special records for
+// the object p.  All fields of s should be filled in except for
+// offset & next, which this routine will fill in.
+// Returns true if the special was successfully added, false otherwise.
+// (The add will fail only if a record with the same p and s->kind
+//  already exists.)
+static bool
+addspecial(void *p, Special *s)
+{
+	MSpan *span;
+	Special **t, *x;
+	uintptr offset;
+	byte kind;
+
+	span = runtime·MHeap_LookupMaybe(&runtime·mheap, p);
+	if(span == nil)
+		runtime·throw("addspecial on invalid pointer");
+
+	// Ensure that the span is swept.
+	// GC accesses specials list w/o locks. And it's just much safer.
+	g->m->locks++;
+	runtime·MSpan_EnsureSwept(span);
+
+	offset = (uintptr)p - (span->start << PageShift);
+	kind = s->kind;
+
+	runtime·lock(&span->specialLock);
+
+	// Find splice point, check for existing record.
+	t = &span->specials;
+	while((x = *t) != nil) {
+		if(offset == x->offset && kind == x->kind) {
+			runtime·unlock(&span->specialLock);
+			g->m->locks--;
+			return false; // already exists
+		}
+		if(offset < x->offset || (offset == x->offset && kind < x->kind))
+			break;
+		t = &x->next;
+	}
+	// Splice in record, fill in offset.
+	s->offset = offset;
+	s->next = x;
+	*t = s;
+	runtime·unlock(&span->specialLock);
+	g->m->locks--;
+	return true;
+}
+
+// Removes the Special record of the given kind for the object p.
+// Returns the record if the record existed, nil otherwise.
+// The caller must FixAlloc_Free the result.
+static Special*
+removespecial(void *p, byte kind)
+{
+	MSpan *span;
+	Special *s, **t;
+	uintptr offset;
+
+	span = runtime·MHeap_LookupMaybe(&runtime·mheap, p);
+	if(span == nil)
+		runtime·throw("removespecial on invalid pointer");
+
+	// Ensure that the span is swept.
+	// GC accesses specials list w/o locks. And it's just much safer.
+	g->m->locks++;
+	runtime·MSpan_EnsureSwept(span);
+
+	offset = (uintptr)p - (span->start << PageShift);
+
+	runtime·lock(&span->specialLock);
+	t = &span->specials;
+	while((s = *t) != nil) {
+		// This function is used for finalizers only, so we don't check for
+		// "interior" specials (p must be exactly equal to s->offset).
+		if(offset == s->offset && kind == s->kind) {
+			*t = s->next;
+			runtime·unlock(&span->specialLock);
+			g->m->locks--;
+			return s;
+		}
+		t = &s->next;
+	}
+	runtime·unlock(&span->specialLock);
+	g->m->locks--;
+	return nil;
+}
+
+// Adds a finalizer to the object p.  Returns true if it succeeded.
+bool
+runtime·addfinalizer(void *p, FuncVal *f, uintptr nret, Type *fint, PtrType *ot)
+{
+	SpecialFinalizer *s;
+
+	runtime·lock(&runtime·mheap.speciallock);
+	s = runtime·FixAlloc_Alloc(&runtime·mheap.specialfinalizeralloc);
+	runtime·unlock(&runtime·mheap.speciallock);
+	s->special.kind = KindSpecialFinalizer;
+	s->fn = f;
+	s->nret = nret;
+	s->fint = fint;
+	s->ot = ot;
+	if(addspecial(p, &s->special))
+		return true;
+
+	// There was an old finalizer
+	runtime·lock(&runtime·mheap.speciallock);
+	runtime·FixAlloc_Free(&runtime·mheap.specialfinalizeralloc, s);
+	runtime·unlock(&runtime·mheap.speciallock);
+	return false;
+}
+
+// Removes the finalizer (if any) from the object p.
+void
+runtime·removefinalizer(void *p)
+{
+	SpecialFinalizer *s;
+
+	s = (SpecialFinalizer*)removespecial(p, KindSpecialFinalizer);
+	if(s == nil)
+		return; // there wasn't a finalizer to remove
+	runtime·lock(&runtime·mheap.speciallock);
+	runtime·FixAlloc_Free(&runtime·mheap.specialfinalizeralloc, s);
+	runtime·unlock(&runtime·mheap.speciallock);
+}
+
+// Set the heap profile bucket associated with addr to b.
+void
+runtime·setprofilebucket_m(void)
+{	
+	void *p;
+	Bucket *b;
+	SpecialProfile *s;
+	
+	p = g->m->ptrarg[0];
+	b = g->m->ptrarg[1];
+	g->m->ptrarg[0] = nil;
+	g->m->ptrarg[1] = nil;
+
+	runtime·lock(&runtime·mheap.speciallock);
+	s = runtime·FixAlloc_Alloc(&runtime·mheap.specialprofilealloc);
+	runtime·unlock(&runtime·mheap.speciallock);
+	s->special.kind = KindSpecialProfile;
+	s->b = b;
+	if(!addspecial(p, &s->special))
+		runtime·throw("setprofilebucket: profile already set");
+}
+
+// Do whatever cleanup needs to be done to deallocate s.  It has
+// already been unlinked from the MSpan specials list.
+// Returns true if we should keep working on deallocating p.
+bool
+runtime·freespecial(Special *s, void *p, uintptr size, bool freed)
+{
+	SpecialFinalizer *sf;
+	SpecialProfile *sp;
+
+	switch(s->kind) {
+	case KindSpecialFinalizer:
+		sf = (SpecialFinalizer*)s;
+		runtime·queuefinalizer(p, sf->fn, sf->nret, sf->fint, sf->ot);
+		runtime·lock(&runtime·mheap.speciallock);
+		runtime·FixAlloc_Free(&runtime·mheap.specialfinalizeralloc, sf);
+		runtime·unlock(&runtime·mheap.speciallock);
+		return false; // don't free p until finalizer is done
+	case KindSpecialProfile:
+		sp = (SpecialProfile*)s;
+		runtime·mProf_Free(sp->b, size, freed);
+		runtime·lock(&runtime·mheap.speciallock);
+		runtime·FixAlloc_Free(&runtime·mheap.specialprofilealloc, sp);
+		runtime·unlock(&runtime·mheap.speciallock);
+		return true;
+	default:
+		runtime·throw("bad special kind");
+		return true;
+	}
+}
diff --git a/src/pkg/runtime/mknacl.sh b/src/runtime/mknacl.sh
similarity index 100%
rename from src/pkg/runtime/mknacl.sh
rename to src/runtime/mknacl.sh
diff --git a/src/runtime/mprof.go b/src/runtime/mprof.go
new file mode 100644
index 0000000..d409c6c
--- /dev/null
+++ b/src/runtime/mprof.go
@@ -0,0 +1,672 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Malloc profiling.
+// Patterned after tcmalloc's algorithms; shorter code.
+
+package runtime
+
+import (
+	"unsafe"
+)
+
+// NOTE(rsc): Everything here could use cas if contention became an issue.
+var proflock mutex
+
+// All memory allocations are local and do not escape outside of the profiler.
+// The profiler is forbidden from referring to garbage-collected memory.
+
+const (
+	// profile types
+	memProfile bucketType = 1 + iota
+	blockProfile
+
+	// size of bucket hash table
+	buckHashSize = 179999
+
+	// max depth of stack to record in bucket
+	maxStack = 32
+)
+
+type bucketType int
+
+// A bucket holds per-call-stack profiling information.
+// The representation is a bit sleazy, inherited from C.
+// This struct defines the bucket header. It is followed in
+// memory by the stack words and then the actual record
+// data, either a memRecord or a blockRecord.
+//
+// Per-call-stack profiling information.
+// Lookup by hashing call stack into a linked-list hash table.
+type bucket struct {
+	next    *bucket
+	allnext *bucket
+	typ     bucketType // memBucket or blockBucket
+	hash    uintptr
+	size    uintptr
+	nstk    uintptr
+}
+
+// A memRecord is the bucket data for a bucket of type memProfile,
+// part of the memory profile.
+type memRecord struct {
+	// The following complex 3-stage scheme of stats accumulation
+	// is required to obtain a consistent picture of mallocs and frees
+	// for some point in time.
+	// The problem is that mallocs come in real time, while frees
+	// come only after a GC during concurrent sweeping. So if we would
+	// naively count them, we would get a skew toward mallocs.
+	//
+	// Mallocs are accounted in recent stats.
+	// Explicit frees are accounted in recent stats.
+	// GC frees are accounted in prev stats.
+	// After GC prev stats are added to final stats and
+	// recent stats are moved into prev stats.
+	allocs      uintptr
+	frees       uintptr
+	alloc_bytes uintptr
+	free_bytes  uintptr
+
+	// changes between next-to-last GC and last GC
+	prev_allocs      uintptr
+	prev_frees       uintptr
+	prev_alloc_bytes uintptr
+	prev_free_bytes  uintptr
+
+	// changes since last GC
+	recent_allocs      uintptr
+	recent_frees       uintptr
+	recent_alloc_bytes uintptr
+	recent_free_bytes  uintptr
+}
+
+// A blockRecord is the bucket data for a bucket of type blockProfile,
+// part of the blocking profile.
+type blockRecord struct {
+	count  int64
+	cycles int64
+}
+
+var (
+	mbuckets  *bucket // memory profile buckets
+	bbuckets  *bucket // blocking profile buckets
+	buckhash  *[179999]*bucket
+	bucketmem uintptr
+)
+
+// newBucket allocates a bucket with the given type and number of stack entries.
+func newBucket(typ bucketType, nstk int) *bucket {
+	size := unsafe.Sizeof(bucket{}) + uintptr(nstk)*unsafe.Sizeof(uintptr(0))
+	switch typ {
+	default:
+		gothrow("invalid profile bucket type")
+	case memProfile:
+		size += unsafe.Sizeof(memRecord{})
+	case blockProfile:
+		size += unsafe.Sizeof(blockRecord{})
+	}
+
+	b := (*bucket)(persistentalloc(size, 0, &memstats.buckhash_sys))
+	bucketmem += size
+	b.typ = typ
+	b.nstk = uintptr(nstk)
+	return b
+}
+
+// stk returns the slice in b holding the stack.
+func (b *bucket) stk() []uintptr {
+	stk := (*[maxStack]uintptr)(add(unsafe.Pointer(b), unsafe.Sizeof(*b)))
+	return stk[:b.nstk:b.nstk]
+}
+
+// mp returns the memRecord associated with the memProfile bucket b.
+func (b *bucket) mp() *memRecord {
+	if b.typ != memProfile {
+		gothrow("bad use of bucket.mp")
+	}
+	data := add(unsafe.Pointer(b), unsafe.Sizeof(*b)+b.nstk*unsafe.Sizeof(uintptr(0)))
+	return (*memRecord)(data)
+}
+
+// bp returns the blockRecord associated with the blockProfile bucket b.
+func (b *bucket) bp() *blockRecord {
+	if b.typ != blockProfile {
+		gothrow("bad use of bucket.bp")
+	}
+	data := add(unsafe.Pointer(b), unsafe.Sizeof(*b)+b.nstk*unsafe.Sizeof(uintptr(0)))
+	return (*blockRecord)(data)
+}
+
+// Return the bucket for stk[0:nstk], allocating new bucket if needed.
+func stkbucket(typ bucketType, size uintptr, stk []uintptr, alloc bool) *bucket {
+	if buckhash == nil {
+		buckhash = (*[buckHashSize]*bucket)(sysAlloc(unsafe.Sizeof(*buckhash), &memstats.buckhash_sys))
+		if buckhash == nil {
+			gothrow("runtime: cannot allocate memory")
+		}
+	}
+
+	// Hash stack.
+	var h uintptr
+	for _, pc := range stk {
+		h += pc
+		h += h << 10
+		h ^= h >> 6
+	}
+	// hash in size
+	h += size
+	h += h << 10
+	h ^= h >> 6
+	// finalize
+	h += h << 3
+	h ^= h >> 11
+
+	i := int(h % buckHashSize)
+	for b := buckhash[i]; b != nil; b = b.next {
+		if b.typ == typ && b.hash == h && b.size == size && eqslice(b.stk(), stk) {
+			return b
+		}
+	}
+
+	if !alloc {
+		return nil
+	}
+
+	// Create new bucket.
+	b := newBucket(typ, len(stk))
+	copy(b.stk(), stk)
+	b.hash = h
+	b.size = size
+	b.next = buckhash[i]
+	buckhash[i] = b
+	if typ == memProfile {
+		b.allnext = mbuckets
+		mbuckets = b
+	} else {
+		b.allnext = bbuckets
+		bbuckets = b
+	}
+	return b
+}
+
+func sysAlloc(n uintptr, stat *uint64) unsafe.Pointer
+
+func eqslice(x, y []uintptr) bool {
+	if len(x) != len(y) {
+		return false
+	}
+	for i, xi := range x {
+		if xi != y[i] {
+			return false
+		}
+	}
+	return true
+}
+
+func mprof_GC() {
+	for b := mbuckets; b != nil; b = b.allnext {
+		mp := b.mp()
+		mp.allocs += mp.prev_allocs
+		mp.frees += mp.prev_frees
+		mp.alloc_bytes += mp.prev_alloc_bytes
+		mp.free_bytes += mp.prev_free_bytes
+
+		mp.prev_allocs = mp.recent_allocs
+		mp.prev_frees = mp.recent_frees
+		mp.prev_alloc_bytes = mp.recent_alloc_bytes
+		mp.prev_free_bytes = mp.recent_free_bytes
+
+		mp.recent_allocs = 0
+		mp.recent_frees = 0
+		mp.recent_alloc_bytes = 0
+		mp.recent_free_bytes = 0
+	}
+}
+
+// Record that a gc just happened: all the 'recent' statistics are now real.
+func mProf_GC() {
+	lock(&proflock)
+	mprof_GC()
+	unlock(&proflock)
+}
+
+// Called by malloc to record a profiled block.
+func mProf_Malloc(p unsafe.Pointer, size uintptr) {
+	var stk [maxStack]uintptr
+	nstk := callers(4, &stk[0], len(stk))
+	lock(&proflock)
+	b := stkbucket(memProfile, size, stk[:nstk], true)
+	mp := b.mp()
+	mp.recent_allocs++
+	mp.recent_alloc_bytes += size
+	unlock(&proflock)
+
+	// Setprofilebucket locks a bunch of other mutexes, so we call it outside of proflock.
+	// This reduces potential contention and chances of deadlocks.
+	// Since the object must be alive during call to mProf_Malloc,
+	// it's fine to do this non-atomically.
+	setprofilebucket(p, b)
+}
+
+func setprofilebucket_m() // mheap.c
+
+func setprofilebucket(p unsafe.Pointer, b *bucket) {
+	g := getg()
+	g.m.ptrarg[0] = p
+	g.m.ptrarg[1] = unsafe.Pointer(b)
+	onM(setprofilebucket_m)
+}
+
+// Called when freeing a profiled block.
+func mProf_Free(b *bucket, size uintptr, freed bool) {
+	lock(&proflock)
+	mp := b.mp()
+	if freed {
+		mp.recent_frees++
+		mp.recent_free_bytes += size
+	} else {
+		mp.prev_frees++
+		mp.prev_free_bytes += size
+	}
+	unlock(&proflock)
+}
+
+var blockprofilerate uint64 // in CPU ticks
+
+// SetBlockProfileRate controls the fraction of goroutine blocking events
+// that are reported in the blocking profile.  The profiler aims to sample
+// an average of one blocking event per rate nanoseconds spent blocked.
+//
+// To include every blocking event in the profile, pass rate = 1.
+// To turn off profiling entirely, pass rate <= 0.
+func SetBlockProfileRate(rate int) {
+	var r int64
+	if rate <= 0 {
+		r = 0 // disable profiling
+	} else if rate == 1 {
+		r = 1 // profile everything
+	} else {
+		// convert ns to cycles, use float64 to prevent overflow during multiplication
+		r = int64(float64(rate) * float64(tickspersecond()) / (1000 * 1000 * 1000))
+		if r == 0 {
+			r = 1
+		}
+	}
+
+	atomicstore64(&blockprofilerate, uint64(r))
+}
+
+func blockevent(cycles int64, skip int) {
+	if cycles <= 0 {
+		cycles = 1
+	}
+	rate := int64(atomicload64(&blockprofilerate))
+	if rate <= 0 || (rate > cycles && int64(fastrand1())%rate > cycles) {
+		return
+	}
+	gp := getg()
+	var nstk int
+	var stk [maxStack]uintptr
+	if gp.m.curg == nil || gp.m.curg == gp {
+		nstk = callers(skip, &stk[0], len(stk))
+	} else {
+		nstk = gcallers(gp.m.curg, skip, &stk[0], len(stk))
+	}
+	lock(&proflock)
+	b := stkbucket(blockProfile, 0, stk[:nstk], true)
+	b.bp().count++
+	b.bp().cycles += cycles
+	unlock(&proflock)
+}
+
+// Go interface to profile data.
+
+// A StackRecord describes a single execution stack.
+type StackRecord struct {
+	Stack0 [32]uintptr // stack trace for this record; ends at first 0 entry
+}
+
+// Stack returns the stack trace associated with the record,
+// a prefix of r.Stack0.
+func (r *StackRecord) Stack() []uintptr {
+	for i, v := range r.Stack0 {
+		if v == 0 {
+			return r.Stack0[0:i]
+		}
+	}
+	return r.Stack0[0:]
+}
+
+// MemProfileRate controls the fraction of memory allocations
+// that are recorded and reported in the memory profile.
+// The profiler aims to sample an average of
+// one allocation per MemProfileRate bytes allocated.
+//
+// To include every allocated block in the profile, set MemProfileRate to 1.
+// To turn off profiling entirely, set MemProfileRate to 0.
+//
+// The tools that process the memory profiles assume that the
+// profile rate is constant across the lifetime of the program
+// and equal to the current value.  Programs that change the
+// memory profiling rate should do so just once, as early as
+// possible in the execution of the program (for example,
+// at the beginning of main).
+var MemProfileRate int = 512 * 1024
+
+// A MemProfileRecord describes the live objects allocated
+// by a particular call sequence (stack trace).
+type MemProfileRecord struct {
+	AllocBytes, FreeBytes     int64       // number of bytes allocated, freed
+	AllocObjects, FreeObjects int64       // number of objects allocated, freed
+	Stack0                    [32]uintptr // stack trace for this record; ends at first 0 entry
+}
+
+// InUseBytes returns the number of bytes in use (AllocBytes - FreeBytes).
+func (r *MemProfileRecord) InUseBytes() int64 { return r.AllocBytes - r.FreeBytes }
+
+// InUseObjects returns the number of objects in use (AllocObjects - FreeObjects).
+func (r *MemProfileRecord) InUseObjects() int64 {
+	return r.AllocObjects - r.FreeObjects
+}
+
+// Stack returns the stack trace associated with the record,
+// a prefix of r.Stack0.
+func (r *MemProfileRecord) Stack() []uintptr {
+	for i, v := range r.Stack0 {
+		if v == 0 {
+			return r.Stack0[0:i]
+		}
+	}
+	return r.Stack0[0:]
+}
+
+// MemProfile returns n, the number of records in the current memory profile.
+// If len(p) >= n, MemProfile copies the profile into p and returns n, true.
+// If len(p) < n, MemProfile does not change p and returns n, false.
+//
+// If inuseZero is true, the profile includes allocation records
+// where r.AllocBytes > 0 but r.AllocBytes == r.FreeBytes.
+// These are sites where memory was allocated, but it has all
+// been released back to the runtime.
+//
+// Most clients should use the runtime/pprof package or
+// the testing package's -test.memprofile flag instead
+// of calling MemProfile directly.
+func MemProfile(p []MemProfileRecord, inuseZero bool) (n int, ok bool) {
+	lock(&proflock)
+	clear := true
+	for b := mbuckets; b != nil; b = b.allnext {
+		mp := b.mp()
+		if inuseZero || mp.alloc_bytes != mp.free_bytes {
+			n++
+		}
+		if mp.allocs != 0 || mp.frees != 0 {
+			clear = false
+		}
+	}
+	if clear {
+		// Absolutely no data, suggesting that a garbage collection
+		// has not yet happened. In order to allow profiling when
+		// garbage collection is disabled from the beginning of execution,
+		// accumulate stats as if a GC just happened, and recount buckets.
+		mprof_GC()
+		mprof_GC()
+		n = 0
+		for b := mbuckets; b != nil; b = b.allnext {
+			mp := b.mp()
+			if inuseZero || mp.alloc_bytes != mp.free_bytes {
+				n++
+			}
+		}
+	}
+	if n <= len(p) {
+		ok = true
+		idx := 0
+		for b := mbuckets; b != nil; b = b.allnext {
+			mp := b.mp()
+			if inuseZero || mp.alloc_bytes != mp.free_bytes {
+				record(&p[idx], b)
+				idx++
+			}
+		}
+	}
+	unlock(&proflock)
+	return
+}
+
+// Write b's data to r.
+func record(r *MemProfileRecord, b *bucket) {
+	mp := b.mp()
+	r.AllocBytes = int64(mp.alloc_bytes)
+	r.FreeBytes = int64(mp.free_bytes)
+	r.AllocObjects = int64(mp.allocs)
+	r.FreeObjects = int64(mp.frees)
+	copy(r.Stack0[:], b.stk())
+	for i := int(b.nstk); i < len(r.Stack0); i++ {
+		r.Stack0[i] = 0
+	}
+}
+
+func iterate_memprof(fn func(*bucket, uintptr, *uintptr, uintptr, uintptr, uintptr)) {
+	lock(&proflock)
+	for b := mbuckets; b != nil; b = b.allnext {
+		mp := b.mp()
+		fn(b, uintptr(b.nstk), &b.stk()[0], b.size, mp.allocs, mp.frees)
+	}
+	unlock(&proflock)
+}
+
+// BlockProfileRecord describes blocking events originated
+// at a particular call sequence (stack trace).
+type BlockProfileRecord struct {
+	Count  int64
+	Cycles int64
+	StackRecord
+}
+
+// BlockProfile returns n, the number of records in the current blocking profile.
+// If len(p) >= n, BlockProfile copies the profile into p and returns n, true.
+// If len(p) < n, BlockProfile does not change p and returns n, false.
+//
+// Most clients should use the runtime/pprof package or
+// the testing package's -test.blockprofile flag instead
+// of calling BlockProfile directly.
+func BlockProfile(p []BlockProfileRecord) (n int, ok bool) {
+	lock(&proflock)
+	for b := bbuckets; b != nil; b = b.allnext {
+		n++
+	}
+	if n <= len(p) {
+		ok = true
+		for b := bbuckets; b != nil; b = b.allnext {
+			bp := b.bp()
+			r := &p[0]
+			r.Count = int64(bp.count)
+			r.Cycles = int64(bp.cycles)
+			i := copy(r.Stack0[:], b.stk())
+			for ; i < len(r.Stack0); i++ {
+				r.Stack0[i] = 0
+			}
+			p = p[1:]
+		}
+	}
+	unlock(&proflock)
+	return
+}
+
+// ThreadCreateProfile returns n, the number of records in the thread creation profile.
+// If len(p) >= n, ThreadCreateProfile copies the profile into p and returns n, true.
+// If len(p) < n, ThreadCreateProfile does not change p and returns n, false.
+//
+// Most clients should use the runtime/pprof package instead
+// of calling ThreadCreateProfile directly.
+func ThreadCreateProfile(p []StackRecord) (n int, ok bool) {
+	first := (*m)(atomicloadp(unsafe.Pointer(&allm)))
+	for mp := first; mp != nil; mp = mp.alllink {
+		n++
+	}
+	if n <= len(p) {
+		ok = true
+		i := 0
+		for mp := first; mp != nil; mp = mp.alllink {
+			for s := range mp.createstack {
+				p[i].Stack0[s] = uintptr(mp.createstack[s])
+			}
+			i++
+		}
+	}
+	return
+}
+
+var allgs []*g // proc.c
+
+// GoroutineProfile returns n, the number of records in the active goroutine stack profile.
+// If len(p) >= n, GoroutineProfile copies the profile into p and returns n, true.
+// If len(p) < n, GoroutineProfile does not change p and returns n, false.
+//
+// Most clients should use the runtime/pprof package instead
+// of calling GoroutineProfile directly.
+func GoroutineProfile(p []StackRecord) (n int, ok bool) {
+
+	n = NumGoroutine()
+	if n <= len(p) {
+		gp := getg()
+		semacquire(&worldsema, false)
+		gp.m.gcing = 1
+		onM(stoptheworld)
+
+		n = NumGoroutine()
+		if n <= len(p) {
+			ok = true
+			r := p
+			sp := getcallersp(unsafe.Pointer(&p))
+			pc := getcallerpc(unsafe.Pointer(&p))
+			onM(func() {
+				saveg(pc, sp, gp, &r[0])
+			})
+			r = r[1:]
+			for _, gp1 := range allgs {
+				if gp1 == gp || readgstatus(gp1) == _Gdead {
+					continue
+				}
+				saveg(^uintptr(0), ^uintptr(0), gp1, &r[0])
+				r = r[1:]
+			}
+		}
+
+		gp.m.gcing = 0
+		semrelease(&worldsema)
+		onM(starttheworld)
+	}
+
+	return n, ok
+}
+
+func saveg(pc, sp uintptr, gp *g, r *StackRecord) {
+	n := gentraceback(pc, sp, 0, gp, 0, &r.Stack0[0], len(r.Stack0), nil, nil, 0)
+	if n < len(r.Stack0) {
+		r.Stack0[n] = 0
+	}
+}
+
+// Stack formats a stack trace of the calling goroutine into buf
+// and returns the number of bytes written to buf.
+// If all is true, Stack formats stack traces of all other goroutines
+// into buf after the trace for the current goroutine.
+func Stack(buf []byte, all bool) int {
+	mp := acquirem()
+	gp := mp.curg
+	if all {
+		semacquire(&worldsema, false)
+		mp.gcing = 1
+		releasem(mp)
+		onM(stoptheworld)
+		if mp != acquirem() {
+			gothrow("Stack: rescheduled")
+		}
+	}
+
+	n := 0
+	if len(buf) > 0 {
+		sp := getcallersp(unsafe.Pointer(&buf))
+		pc := getcallerpc(unsafe.Pointer(&buf))
+		onM(func() {
+			g0 := getg()
+			g0.writebuf = buf[0:0:len(buf)]
+			goroutineheader(gp)
+			traceback(pc, sp, 0, gp)
+			if all {
+				tracebackothers(gp)
+			}
+			n = len(g0.writebuf)
+			g0.writebuf = nil
+		})
+	}
+
+	if all {
+		mp.gcing = 0
+		semrelease(&worldsema)
+		onM(starttheworld)
+	}
+	releasem(mp)
+	return n
+}
+
+// Tracing of alloc/free/gc.
+
+var tracelock mutex
+
+func tracealloc(p unsafe.Pointer, size uintptr, typ *_type) {
+	lock(&tracelock)
+	gp := getg()
+	gp.m.traceback = 2
+	if typ == nil {
+		print("tracealloc(", p, ", ", hex(size), ")\n")
+	} else {
+		print("tracealloc(", p, ", ", hex(size), ", ", *typ._string, ")\n")
+	}
+	if gp.m.curg == nil || gp == gp.m.curg {
+		goroutineheader(gp)
+		pc := getcallerpc(unsafe.Pointer(&p))
+		sp := getcallersp(unsafe.Pointer(&p))
+		onM(func() {
+			traceback(pc, sp, 0, gp)
+		})
+	} else {
+		goroutineheader(gp.m.curg)
+		traceback(^uintptr(0), ^uintptr(0), 0, gp.m.curg)
+	}
+	print("\n")
+	gp.m.traceback = 0
+	unlock(&tracelock)
+}
+
+func tracefree(p unsafe.Pointer, size uintptr) {
+	lock(&tracelock)
+	gp := getg()
+	gp.m.traceback = 2
+	print("tracefree(", p, ", ", hex(size), ")\n")
+	goroutineheader(gp)
+	pc := getcallerpc(unsafe.Pointer(&p))
+	sp := getcallersp(unsafe.Pointer(&p))
+	onM(func() {
+		traceback(pc, sp, 0, gp)
+	})
+	print("\n")
+	gp.m.traceback = 0
+	unlock(&tracelock)
+}
+
+func tracegc() {
+	lock(&tracelock)
+	gp := getg()
+	gp.m.traceback = 2
+	print("tracegc()\n")
+	// running on m->g0 stack; show all non-g0 goroutines
+	tracebackothers(gp)
+	print("end tracegc\n")
+	print("\n")
+	gp.m.traceback = 0
+	unlock(&tracelock)
+}
diff --git a/src/runtime/msize.c b/src/runtime/msize.c
new file mode 100644
index 0000000..7cb65da
--- /dev/null
+++ b/src/runtime/msize.c
@@ -0,0 +1,184 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Malloc small size classes.
+//
+// See malloc.h for overview.
+//
+// The size classes are chosen so that rounding an allocation
+// request up to the next size class wastes at most 12.5% (1.125x).
+//
+// Each size class has its own page count that gets allocated
+// and chopped up when new objects of the size class are needed.
+// That page count is chosen so that chopping up the run of
+// pages into objects of the given size wastes at most 12.5% (1.125x)
+// of the memory.  It is not necessary that the cutoff here be
+// the same as above.
+//
+// The two sources of waste multiply, so the worst possible case
+// for the above constraints would be that allocations of some
+// size might have a 26.6% (1.266x) overhead.
+// In practice, only one of the wastes comes into play for a
+// given size (sizes < 512 waste mainly on the round-up,
+// sizes > 512 waste mainly on the page chopping).
+//
+// TODO(rsc): Compute max waste for any given size.
+
+#include "runtime.h"
+#include "arch_GOARCH.h"
+#include "malloc.h"
+#include "textflag.h"
+
+#pragma dataflag NOPTR
+int32 runtime·class_to_size[NumSizeClasses];
+#pragma dataflag NOPTR
+int32 runtime·class_to_allocnpages[NumSizeClasses];
+
+// The SizeToClass lookup is implemented using two arrays,
+// one mapping sizes <= 1024 to their class and one mapping
+// sizes >= 1024 and <= MaxSmallSize to their class.
+// All objects are 8-aligned, so the first array is indexed by
+// the size divided by 8 (rounded up).  Objects >= 1024 bytes
+// are 128-aligned, so the second array is indexed by the
+// size divided by 128 (rounded up).  The arrays are filled in
+// by InitSizes.
+
+#pragma dataflag NOPTR
+int8 runtime·size_to_class8[1024/8 + 1];
+#pragma dataflag NOPTR
+int8 runtime·size_to_class128[(MaxSmallSize-1024)/128 + 1];
+
+void runtime·testdefersizes(void);
+
+int32
+runtime·SizeToClass(int32 size)
+{
+	if(size > MaxSmallSize)
+		runtime·throw("SizeToClass - invalid size");
+	if(size > 1024-8)
+		return runtime·size_to_class128[(size-1024+127) >> 7];
+	return runtime·size_to_class8[(size+7)>>3];
+}
+
+void
+runtime·InitSizes(void)
+{
+	int32 align, sizeclass, size, nextsize, n;
+	uint32 i;
+	uintptr allocsize, npages;
+
+	// Initialize the runtime·class_to_size table (and choose class sizes in the process).
+	runtime·class_to_size[0] = 0;
+	sizeclass = 1;	// 0 means no class
+	align = 8;
+	for(size = align; size <= MaxSmallSize; size += align) {
+		if((size&(size-1)) == 0) {	// bump alignment once in a while
+			if(size >= 2048)
+				align = 256;
+			else if(size >= 128)
+				align = size / 8;
+			else if(size >= 16)
+				align = 16;	// required for x86 SSE instructions, if we want to use them
+		}
+		if((align&(align-1)) != 0)
+			runtime·throw("InitSizes - bug");
+
+		// Make the allocnpages big enough that
+		// the leftover is less than 1/8 of the total,
+		// so wasted space is at most 12.5%.
+		allocsize = PageSize;
+		while(allocsize%size > allocsize/8)
+			allocsize += PageSize;
+		npages = allocsize >> PageShift;
+
+		// If the previous sizeclass chose the same
+		// allocation size and fit the same number of
+		// objects into the page, we might as well
+		// use just this size instead of having two
+		// different sizes.
+		if(sizeclass > 1 &&
+			npages == runtime·class_to_allocnpages[sizeclass-1] &&
+			allocsize/size == allocsize/runtime·class_to_size[sizeclass-1]) {
+			runtime·class_to_size[sizeclass-1] = size;
+			continue;
+		}
+
+		runtime·class_to_allocnpages[sizeclass] = npages;
+		runtime·class_to_size[sizeclass] = size;
+		sizeclass++;
+	}
+	if(sizeclass != NumSizeClasses) {
+		runtime·printf("sizeclass=%d NumSizeClasses=%d\n", sizeclass, NumSizeClasses);
+		runtime·throw("InitSizes - bad NumSizeClasses");
+	}
+
+	// Initialize the size_to_class tables.
+	nextsize = 0;
+	for (sizeclass = 1; sizeclass < NumSizeClasses; sizeclass++) {
+		for(; nextsize < 1024 && nextsize <= runtime·class_to_size[sizeclass]; nextsize+=8)
+			runtime·size_to_class8[nextsize/8] = sizeclass;
+		if(nextsize >= 1024)
+			for(; nextsize <= runtime·class_to_size[sizeclass]; nextsize += 128)
+				runtime·size_to_class128[(nextsize-1024)/128] = sizeclass;
+	}
+
+	// Double-check SizeToClass.
+	if(0) {
+		for(n=0; n < MaxSmallSize; n++) {
+			sizeclass = runtime·SizeToClass(n);
+			if(sizeclass < 1 || sizeclass >= NumSizeClasses || runtime·class_to_size[sizeclass] < n) {
+				runtime·printf("size=%d sizeclass=%d runtime·class_to_size=%d\n", n, sizeclass, runtime·class_to_size[sizeclass]);
+				runtime·printf("incorrect SizeToClass");
+				goto dump;
+			}
+			if(sizeclass > 1 && runtime·class_to_size[sizeclass-1] >= n) {
+				runtime·printf("size=%d sizeclass=%d runtime·class_to_size=%d\n", n, sizeclass, runtime·class_to_size[sizeclass]);
+				runtime·printf("SizeToClass too big");
+				goto dump;
+			}
+		}
+	}
+
+	runtime·testdefersizes();
+
+	// Copy out for statistics table.
+	for(i=0; i<nelem(runtime·class_to_size); i++)
+		mstats.by_size[i].size = runtime·class_to_size[i];
+	return;
+
+dump:
+	if(1){
+		runtime·printf("NumSizeClasses=%d\n", NumSizeClasses);
+		runtime·printf("runtime·class_to_size:");
+		for(sizeclass=0; sizeclass<NumSizeClasses; sizeclass++)
+			runtime·printf(" %d", runtime·class_to_size[sizeclass]);
+		runtime·printf("\n\n");
+		runtime·printf("size_to_class8:");
+		for(i=0; i<nelem(runtime·size_to_class8); i++)
+			runtime·printf(" %d=>%d(%d)\n", i*8, runtime·size_to_class8[i],
+				runtime·class_to_size[runtime·size_to_class8[i]]);
+		runtime·printf("\n");
+		runtime·printf("size_to_class128:");
+		for(i=0; i<nelem(runtime·size_to_class128); i++)
+			runtime·printf(" %d=>%d(%d)\n", i*128, runtime·size_to_class128[i],
+				runtime·class_to_size[runtime·size_to_class128[i]]);
+		runtime·printf("\n");
+	}
+	runtime·throw("InitSizes failed");
+}
+
+// Returns size of the memory block that mallocgc will allocate if you ask for the size.
+uintptr
+runtime·roundupsize(uintptr size)
+{
+	if(size < MaxSmallSize) {
+		if(size <= 1024-8)
+			return runtime·class_to_size[runtime·size_to_class8[(size+7)>>3]];
+		else
+			return runtime·class_to_size[runtime·size_to_class128[(size-1024+127) >> 7]];
+	}
+	if(size + PageSize < size)
+		return size;
+	return ROUND(size, PageSize);
+}
diff --git a/src/runtime/netpoll.go b/src/runtime/netpoll.go
new file mode 100644
index 0000000..3456e02
--- /dev/null
+++ b/src/runtime/netpoll.go
@@ -0,0 +1,455 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris windows
+
+package runtime
+
+import "unsafe"
+
+// Integrated network poller (platform-independent part).
+// A particular implementation (epoll/kqueue) must define the following functions:
+// func netpollinit()			// to initialize the poller
+// func netpollopen(fd uintptr, pd *pollDesc) int32	// to arm edge-triggered notifications
+// and associate fd with pd.
+// An implementation must call the following function to denote that the pd is ready.
+// func netpollready(gpp **g, pd *pollDesc, mode int32)
+
+// pollDesc contains 2 binary semaphores, rg and wg, to park reader and writer
+// goroutines respectively. The semaphore can be in the following states:
+// pdReady - io readiness notification is pending;
+//           a goroutine consumes the notification by changing the state to nil.
+// pdWait - a goroutine prepares to park on the semaphore, but not yet parked;
+//          the goroutine commits to park by changing the state to G pointer,
+//          or, alternatively, concurrent io notification changes the state to READY,
+//          or, alternatively, concurrent timeout/close changes the state to nil.
+// G pointer - the goroutine is blocked on the semaphore;
+//             io notification or timeout/close changes the state to READY or nil respectively
+//             and unparks the goroutine.
+// nil - nothing of the above.
+const (
+	pdReady uintptr = 1
+	pdWait  uintptr = 2
+)
+
+const pollBlockSize = 4 * 1024
+
+// Network poller descriptor.
+type pollDesc struct {
+	link *pollDesc // in pollcache, protected by pollcache.lock
+
+	// The lock protects pollOpen, pollSetDeadline, pollUnblock and deadlineimpl operations.
+	// This fully covers seq, rt and wt variables. fd is constant throughout the PollDesc lifetime.
+	// pollReset, pollWait, pollWaitCanceled and runtime·netpollready (IO readiness notification)
+	// proceed w/o taking the lock. So closing, rg, rd, wg and wd are manipulated
+	// in a lock-free way by all operations.
+	// NOTE(dvyukov): the following code uses uintptr to store *g (rg/wg),
+	// that will blow up when GC starts moving objects.
+	lock    mutex // protectes the following fields
+	fd      uintptr
+	closing bool
+	seq     uintptr        // protects from stale timers and ready notifications
+	rg      uintptr        // pdReady, pdWait, G waiting for read or nil
+	rt      timer          // read deadline timer (set if rt.f != nil)
+	rd      int64          // read deadline
+	wg      uintptr        // pdReady, pdWait, G waiting for write or nil
+	wt      timer          // write deadline timer
+	wd      int64          // write deadline
+	user    unsafe.Pointer // user settable cookie
+}
+
+type pollCache struct {
+	lock  mutex
+	first *pollDesc
+	// PollDesc objects must be type-stable,
+	// because we can get ready notification from epoll/kqueue
+	// after the descriptor is closed/reused.
+	// Stale notifications are detected using seq variable,
+	// seq is incremented when deadlines are changed or descriptor is reused.
+}
+
+var pollcache pollCache
+
+func netpollServerInit() {
+	onM(netpollinit)
+}
+
+func netpollOpen(fd uintptr) (*pollDesc, int) {
+	pd := pollcache.alloc()
+	lock(&pd.lock)
+	if pd.wg != 0 && pd.wg != pdReady {
+		gothrow("netpollOpen: blocked write on free descriptor")
+	}
+	if pd.rg != 0 && pd.rg != pdReady {
+		gothrow("netpollOpen: blocked read on free descriptor")
+	}
+	pd.fd = fd
+	pd.closing = false
+	pd.seq++
+	pd.rg = 0
+	pd.rd = 0
+	pd.wg = 0
+	pd.wd = 0
+	unlock(&pd.lock)
+
+	var errno int32
+	onM(func() {
+		errno = netpollopen(fd, pd)
+	})
+	return pd, int(errno)
+}
+
+func netpollClose(pd *pollDesc) {
+	if !pd.closing {
+		gothrow("netpollClose: close w/o unblock")
+	}
+	if pd.wg != 0 && pd.wg != pdReady {
+		gothrow("netpollClose: blocked write on closing descriptor")
+	}
+	if pd.rg != 0 && pd.rg != pdReady {
+		gothrow("netpollClose: blocked read on closing descriptor")
+	}
+	onM(func() {
+		netpollclose(uintptr(pd.fd))
+	})
+	pollcache.free(pd)
+}
+
+func (c *pollCache) free(pd *pollDesc) {
+	lock(&c.lock)
+	pd.link = c.first
+	c.first = pd
+	unlock(&c.lock)
+}
+
+func netpollReset(pd *pollDesc, mode int) int {
+	err := netpollcheckerr(pd, int32(mode))
+	if err != 0 {
+		return err
+	}
+	if mode == 'r' {
+		pd.rg = 0
+	} else if mode == 'w' {
+		pd.wg = 0
+	}
+	return 0
+}
+
+func netpollWait(pd *pollDesc, mode int) int {
+	err := netpollcheckerr(pd, int32(mode))
+	if err != 0 {
+		return err
+	}
+	// As for now only Solaris uses level-triggered IO.
+	if GOOS == "solaris" {
+		onM(func() {
+			netpollarm(pd, mode)
+		})
+	}
+	for !netpollblock(pd, int32(mode), false) {
+		err = netpollcheckerr(pd, int32(mode))
+		if err != 0 {
+			return err
+		}
+		// Can happen if timeout has fired and unblocked us,
+		// but before we had a chance to run, timeout has been reset.
+		// Pretend it has not happened and retry.
+	}
+	return 0
+}
+
+func netpollWaitCanceled(pd *pollDesc, mode int) {
+	// This function is used only on windows after a failed attempt to cancel
+	// a pending async IO operation. Wait for ioready, ignore closing or timeouts.
+	for !netpollblock(pd, int32(mode), true) {
+	}
+}
+
+func netpollSetDeadline(pd *pollDesc, d int64, mode int) {
+	lock(&pd.lock)
+	if pd.closing {
+		unlock(&pd.lock)
+		return
+	}
+	pd.seq++ // invalidate current timers
+	// Reset current timers.
+	if pd.rt.f != nil {
+		deltimer(&pd.rt)
+		pd.rt.f = nil
+	}
+	if pd.wt.f != nil {
+		deltimer(&pd.wt)
+		pd.wt.f = nil
+	}
+	// Setup new timers.
+	if d != 0 && d <= nanotime() {
+		d = -1
+	}
+	if mode == 'r' || mode == 'r'+'w' {
+		pd.rd = d
+	}
+	if mode == 'w' || mode == 'r'+'w' {
+		pd.wd = d
+	}
+	if pd.rd > 0 && pd.rd == pd.wd {
+		pd.rt.f = netpollDeadline
+		pd.rt.when = pd.rd
+		// Copy current seq into the timer arg.
+		// Timer func will check the seq against current descriptor seq,
+		// if they differ the descriptor was reused or timers were reset.
+		pd.rt.arg = pd
+		pd.rt.seq = pd.seq
+		addtimer(&pd.rt)
+	} else {
+		if pd.rd > 0 {
+			pd.rt.f = netpollReadDeadline
+			pd.rt.when = pd.rd
+			pd.rt.arg = pd
+			pd.rt.seq = pd.seq
+			addtimer(&pd.rt)
+		}
+		if pd.wd > 0 {
+			pd.wt.f = netpollWriteDeadline
+			pd.wt.when = pd.wd
+			pd.wt.arg = pd
+			pd.wt.seq = pd.seq
+			addtimer(&pd.wt)
+		}
+	}
+	// If we set the new deadline in the past, unblock currently pending IO if any.
+	var rg, wg *g
+	atomicstorep(unsafe.Pointer(&wg), nil) // full memory barrier between stores to rd/wd and load of rg/wg in netpollunblock
+	if pd.rd < 0 {
+		rg = netpollunblock(pd, 'r', false)
+	}
+	if pd.wd < 0 {
+		wg = netpollunblock(pd, 'w', false)
+	}
+	unlock(&pd.lock)
+	if rg != nil {
+		goready(rg)
+	}
+	if wg != nil {
+		goready(wg)
+	}
+}
+
+func netpollUnblock(pd *pollDesc) {
+	lock(&pd.lock)
+	if pd.closing {
+		gothrow("netpollUnblock: already closing")
+	}
+	pd.closing = true
+	pd.seq++
+	var rg, wg *g
+	atomicstorep(unsafe.Pointer(&rg), nil) // full memory barrier between store to closing and read of rg/wg in netpollunblock
+	rg = netpollunblock(pd, 'r', false)
+	wg = netpollunblock(pd, 'w', false)
+	if pd.rt.f != nil {
+		deltimer(&pd.rt)
+		pd.rt.f = nil
+	}
+	if pd.wt.f != nil {
+		deltimer(&pd.wt)
+		pd.wt.f = nil
+	}
+	unlock(&pd.lock)
+	if rg != nil {
+		goready(rg)
+	}
+	if wg != nil {
+		goready(wg)
+	}
+}
+
+func netpollfd(pd *pollDesc) uintptr {
+	return pd.fd
+}
+
+func netpolluser(pd *pollDesc) *unsafe.Pointer {
+	return &pd.user
+}
+
+func netpollclosing(pd *pollDesc) bool {
+	return pd.closing
+}
+
+func netpolllock(pd *pollDesc) {
+	lock(&pd.lock)
+}
+
+func netpollunlock(pd *pollDesc) {
+	unlock(&pd.lock)
+}
+
+// make pd ready, newly runnable goroutines (if any) are returned in rg/wg
+func netpollready(gpp **g, pd *pollDesc, mode int32) {
+	var rg, wg *g
+	if mode == 'r' || mode == 'r'+'w' {
+		rg = netpollunblock(pd, 'r', true)
+	}
+	if mode == 'w' || mode == 'r'+'w' {
+		wg = netpollunblock(pd, 'w', true)
+	}
+	if rg != nil {
+		rg.schedlink = *gpp
+		*gpp = rg
+	}
+	if wg != nil {
+		wg.schedlink = *gpp
+		*gpp = wg
+	}
+}
+
+func netpollcheckerr(pd *pollDesc, mode int32) int {
+	if pd.closing {
+		return 1 // errClosing
+	}
+	if (mode == 'r' && pd.rd < 0) || (mode == 'w' && pd.wd < 0) {
+		return 2 // errTimeout
+	}
+	return 0
+}
+
+func netpollblockcommit(gp *g, gpp unsafe.Pointer) bool {
+	return casuintptr((*uintptr)(gpp), pdWait, uintptr(unsafe.Pointer(gp)))
+}
+
+// returns true if IO is ready, or false if timedout or closed
+// waitio - wait only for completed IO, ignore errors
+func netpollblock(pd *pollDesc, mode int32, waitio bool) bool {
+	gpp := &pd.rg
+	if mode == 'w' {
+		gpp = &pd.wg
+	}
+
+	// set the gpp semaphore to WAIT
+	for {
+		old := *gpp
+		if old == pdReady {
+			*gpp = 0
+			return true
+		}
+		if old != 0 {
+			gothrow("netpollblock: double wait")
+		}
+		if casuintptr(gpp, 0, pdWait) {
+			break
+		}
+	}
+
+	// need to recheck error states after setting gpp to WAIT
+	// this is necessary because runtime_pollUnblock/runtime_pollSetDeadline/deadlineimpl
+	// do the opposite: store to closing/rd/wd, membarrier, load of rg/wg
+	if waitio || netpollcheckerr(pd, mode) == 0 {
+		f := netpollblockcommit
+		gopark(**(**unsafe.Pointer)(unsafe.Pointer(&f)), unsafe.Pointer(gpp), "IO wait")
+	}
+	// be careful to not lose concurrent READY notification
+	old := xchguintptr(gpp, 0)
+	if old > pdWait {
+		gothrow("netpollblock: corrupted state")
+	}
+	return old == pdReady
+}
+
+func netpollunblock(pd *pollDesc, mode int32, ioready bool) *g {
+	gpp := &pd.rg
+	if mode == 'w' {
+		gpp = &pd.wg
+	}
+
+	for {
+		old := *gpp
+		if old == pdReady {
+			return nil
+		}
+		if old == 0 && !ioready {
+			// Only set READY for ioready. runtime_pollWait
+			// will check for timeout/cancel before waiting.
+			return nil
+		}
+		var new uintptr
+		if ioready {
+			new = pdReady
+		}
+		if casuintptr(gpp, old, new) {
+			if old == pdReady || old == pdWait {
+				old = 0
+			}
+			return (*g)(unsafe.Pointer(old))
+		}
+	}
+}
+
+func netpolldeadlineimpl(pd *pollDesc, seq uintptr, read, write bool) {
+	lock(&pd.lock)
+	// Seq arg is seq when the timer was set.
+	// If it's stale, ignore the timer event.
+	if seq != pd.seq {
+		// The descriptor was reused or timers were reset.
+		unlock(&pd.lock)
+		return
+	}
+	var rg *g
+	if read {
+		if pd.rd <= 0 || pd.rt.f == nil {
+			gothrow("netpolldeadlineimpl: inconsistent read deadline")
+		}
+		pd.rd = -1
+		atomicstorep(unsafe.Pointer(&pd.rt.f), nil) // full memory barrier between store to rd and load of rg in netpollunblock
+		rg = netpollunblock(pd, 'r', false)
+	}
+	var wg *g
+	if write {
+		if pd.wd <= 0 || pd.wt.f == nil && !read {
+			gothrow("netpolldeadlineimpl: inconsistent write deadline")
+		}
+		pd.wd = -1
+		atomicstorep(unsafe.Pointer(&pd.wt.f), nil) // full memory barrier between store to wd and load of wg in netpollunblock
+		wg = netpollunblock(pd, 'w', false)
+	}
+	unlock(&pd.lock)
+	if rg != nil {
+		goready(rg)
+	}
+	if wg != nil {
+		goready(wg)
+	}
+}
+
+func netpollDeadline(arg interface{}, seq uintptr) {
+	netpolldeadlineimpl(arg.(*pollDesc), seq, true, true)
+}
+
+func netpollReadDeadline(arg interface{}, seq uintptr) {
+	netpolldeadlineimpl(arg.(*pollDesc), seq, true, false)
+}
+
+func netpollWriteDeadline(arg interface{}, seq uintptr) {
+	netpolldeadlineimpl(arg.(*pollDesc), seq, false, true)
+}
+
+func (c *pollCache) alloc() *pollDesc {
+	lock(&c.lock)
+	if c.first == nil {
+		const pdSize = unsafe.Sizeof(pollDesc{})
+		n := pollBlockSize / pdSize
+		if n == 0 {
+			n = 1
+		}
+		// Must be in non-GC memory because can be referenced
+		// only from epoll/kqueue internals.
+		mem := persistentalloc(n*pdSize, 0, &memstats.other_sys)
+		for i := uintptr(0); i < n; i++ {
+			pd := (*pollDesc)(add(mem, i*pdSize))
+			pd.link = c.first
+			c.first = pd
+		}
+	}
+	pd := c.first
+	c.first = pd.link
+	unlock(&c.lock)
+	return pd
+}
diff --git a/src/runtime/netpoll_epoll.go b/src/runtime/netpoll_epoll.go
new file mode 100644
index 0000000..ecfc9cd
--- /dev/null
+++ b/src/runtime/netpoll_epoll.go
@@ -0,0 +1,97 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build linux
+
+package runtime
+
+import "unsafe"
+
+func epollcreate(size int32) int32
+func epollcreate1(flags int32) int32
+
+//go:noescape
+func epollctl(epfd, op, fd int32, ev *epollevent) int32
+
+//go:noescape
+func epollwait(epfd int32, ev *epollevent, nev, timeout int32) int32
+func closeonexec(fd int32)
+
+var (
+	epfd           int32 = -1 // epoll descriptor
+	netpolllasterr int32
+)
+
+func netpollinit() {
+	epfd = epollcreate1(_EPOLL_CLOEXEC)
+	if epfd >= 0 {
+		return
+	}
+	epfd = epollcreate(1024)
+	if epfd >= 0 {
+		closeonexec(epfd)
+		return
+	}
+	println("netpollinit: failed to create epoll descriptor", -epfd)
+	gothrow("netpollinit: failed to create descriptor")
+}
+
+func netpollopen(fd uintptr, pd *pollDesc) int32 {
+	var ev epollevent
+	ev.events = _EPOLLIN | _EPOLLOUT | _EPOLLRDHUP | _EPOLLET
+	*(**pollDesc)(unsafe.Pointer(&ev.data)) = pd
+	return -epollctl(epfd, _EPOLL_CTL_ADD, int32(fd), &ev)
+}
+
+func netpollclose(fd uintptr) int32 {
+	var ev epollevent
+	return -epollctl(epfd, _EPOLL_CTL_DEL, int32(fd), &ev)
+}
+
+func netpollarm(pd *pollDesc, mode int) {
+	gothrow("unused")
+}
+
+// polls for ready network connections
+// returns list of goroutines that become runnable
+func netpoll(block bool) (gp *g) {
+	if epfd == -1 {
+		return
+	}
+	waitms := int32(-1)
+	if !block {
+		waitms = 0
+	}
+	var events [128]epollevent
+retry:
+	n := epollwait(epfd, &events[0], int32(len(events)), waitms)
+	if n < 0 {
+		if n != -_EINTR && n != netpolllasterr {
+			netpolllasterr = n
+			println("runtime: epollwait on fd", epfd, "failed with", -n)
+		}
+		goto retry
+	}
+	for i := int32(0); i < n; i++ {
+		ev := &events[i]
+		if ev.events == 0 {
+			continue
+		}
+		var mode int32
+		if ev.events&(_EPOLLIN|_EPOLLRDHUP|_EPOLLHUP|_EPOLLERR) != 0 {
+			mode += 'r'
+		}
+		if ev.events&(_EPOLLOUT|_EPOLLHUP|_EPOLLERR) != 0 {
+			mode += 'w'
+		}
+		if mode != 0 {
+			pd := *(**pollDesc)(unsafe.Pointer(&ev.data))
+			netpollready((**g)(noescape(unsafe.Pointer(&gp))), pd, mode)
+		}
+	}
+	if block && gp == nil {
+		goto retry
+	}
+	return gp
+}
diff --git a/src/runtime/netpoll_kqueue.go b/src/runtime/netpoll_kqueue.go
new file mode 100644
index 0000000..d6d55b9
--- /dev/null
+++ b/src/runtime/netpoll_kqueue.go
@@ -0,0 +1,101 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin dragonfly freebsd netbsd openbsd
+
+package runtime
+
+// Integrated network poller (kqueue-based implementation).
+
+import "unsafe"
+
+func kqueue() int32
+
+//go:noescape
+func kevent(kq int32, ch *keventt, nch int32, ev *keventt, nev int32, ts *timespec) int32
+func closeonexec(fd int32)
+
+var (
+	kq             int32 = -1
+	netpolllasterr int32
+)
+
+func netpollinit() {
+	kq = kqueue()
+	if kq < 0 {
+		println("netpollinit: kqueue failed with", -kq)
+		gothrow("netpollinit: kqueue failed")
+	}
+	closeonexec(kq)
+}
+
+func netpollopen(fd uintptr, pd *pollDesc) int32 {
+	// Arm both EVFILT_READ and EVFILT_WRITE in edge-triggered mode (EV_CLEAR)
+	// for the whole fd lifetime.  The notifications are automatically unregistered
+	// when fd is closed.
+	var ev [2]keventt
+	*(*uintptr)(unsafe.Pointer(&ev[0].ident)) = fd
+	ev[0].filter = _EVFILT_READ
+	ev[0].flags = _EV_ADD | _EV_CLEAR
+	ev[0].fflags = 0
+	ev[0].data = 0
+	ev[0].udata = (*byte)(unsafe.Pointer(pd))
+	ev[1] = ev[0]
+	ev[1].filter = _EVFILT_WRITE
+	n := kevent(kq, &ev[0], 2, nil, 0, nil)
+	if n < 0 {
+		return -n
+	}
+	return 0
+}
+
+func netpollclose(fd uintptr) int32 {
+	// Don't need to unregister because calling close()
+	// on fd will remove any kevents that reference the descriptor.
+	return 0
+}
+
+func netpollarm(pd *pollDesc, mode int) {
+	gothrow("unused")
+}
+
+// Polls for ready network connections.
+// Returns list of goroutines that become runnable.
+func netpoll(block bool) (gp *g) {
+	if kq == -1 {
+		return
+	}
+	var tp *timespec
+	var ts timespec
+	if !block {
+		tp = &ts
+	}
+	var events [64]keventt
+retry:
+	n := kevent(kq, nil, 0, &events[0], int32(len(events)), tp)
+	if n < 0 {
+		if n != -_EINTR && n != netpolllasterr {
+			netpolllasterr = n
+			println("runtime: kevent on fd", kq, "failed with", -n)
+		}
+		goto retry
+	}
+	for i := 0; i < int(n); i++ {
+		ev := &events[i]
+		var mode int32
+		if ev.filter == _EVFILT_READ {
+			mode += 'r'
+		}
+		if ev.filter == _EVFILT_WRITE {
+			mode += 'w'
+		}
+		if mode != 0 {
+			netpollready((**g)(noescape(unsafe.Pointer(&gp))), (*pollDesc)(unsafe.Pointer(ev.udata)), mode)
+		}
+	}
+	if block && gp == nil {
+		goto retry
+	}
+	return gp
+}
diff --git a/src/runtime/netpoll_nacl.go b/src/runtime/netpoll_nacl.go
new file mode 100644
index 0000000..5cbc300
--- /dev/null
+++ b/src/runtime/netpoll_nacl.go
@@ -0,0 +1,26 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Fake network poller for NaCl.
+// Should never be used, because NaCl network connections do not honor "SetNonblock".
+
+package runtime
+
+func netpollinit() {
+}
+
+func netpollopen(fd uintptr, pd *pollDesc) int32 {
+	return 0
+}
+
+func netpollclose(fd uintptr) int32 {
+	return 0
+}
+
+func netpollarm(pd *pollDesc, mode int) {
+}
+
+func netpoll(block bool) *g {
+	return nil
+}
diff --git a/src/runtime/netpoll_solaris.c b/src/runtime/netpoll_solaris.c
new file mode 100644
index 0000000..d422719
--- /dev/null
+++ b/src/runtime/netpoll_solaris.c
@@ -0,0 +1,264 @@
+// 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 "runtime.h"
+#include "arch_GOARCH.h"
+#include "defs_GOOS_GOARCH.h"
+#include "os_GOOS.h"
+
+// Solaris runtime-integrated network poller.
+// 
+// Solaris uses event ports for scalable network I/O. Event
+// ports are level-triggered, unlike epoll and kqueue which
+// can be configured in both level-triggered and edge-triggered
+// mode. Level triggering means we have to keep track of a few things
+// ourselves. After we receive an event for a file descriptor,
+// it's our responsibility to ask again to be notified for future
+// events for that descriptor. When doing this we must keep track of
+// what kind of events the goroutines are currently interested in,
+// for example a fd may be open both for reading and writing.
+// 
+// A description of the high level operation of this code
+// follows. Networking code will get a file descriptor by some means
+// and will register it with the netpolling mechanism by a code path
+// that eventually calls runtime·netpollopen. runtime·netpollopen
+// calls port_associate with an empty event set. That means that we
+// will not receive any events at this point. The association needs
+// to be done at this early point because we need to process the I/O
+// readiness notification at some point in the future. If I/O becomes
+// ready when nobody is listening, when we finally care about it,
+// nobody will tell us anymore.
+// 
+// Beside calling runtime·netpollopen, the networking code paths
+// will call runtime·netpollarm each time goroutines are interested
+// in doing network I/O. Because now we know what kind of I/O we
+// are interested in (reading/writting), we can call port_associate
+// passing the correct type of event set (POLLIN/POLLOUT). As we made
+// sure to have already associated the file descriptor with the port,
+// when we now call port_associate, we will unblock the main poller
+// loop (in runtime·netpoll) right away if the socket is actually
+// ready for I/O.
+// 
+// The main poller loop runs in its own thread waiting for events
+// using port_getn. When an event happens, it will tell the scheduler
+// about it using runtime·netpollready. Besides doing this, it must
+// also re-associate the events that were not part of this current
+// notification with the file descriptor. Failing to do this would
+// mean each notification will prevent concurrent code using the
+// same file descriptor in parallel.
+// 
+// The logic dealing with re-associations is encapsulated in
+// runtime·netpollupdate. This function takes care to associate the
+// descriptor only with the subset of events that were previously
+// part of the association, except the one that just happened. We
+// can't re-associate with that right away, because event ports
+// are level triggered so it would cause a busy loop. Instead, that
+// association is effected only by the runtime·netpollarm code path,
+// when Go code actually asks for I/O.
+// 
+// The open and arming mechanisms are serialized using the lock
+// inside PollDesc. This is required because the netpoll loop runs
+// asynchonously in respect to other Go code and by the time we get
+// to call port_associate to update the association in the loop, the
+// file descriptor might have been closed and reopened already. The
+// lock allows runtime·netpollupdate to be called synchronously from
+// the loop thread while preventing other threads operating to the
+// same PollDesc, so once we unblock in the main loop, until we loop
+// again we know for sure we are always talking about the same file
+// descriptor and can safely access the data we want (the event set).
+
+#pragma dynimport libc·fcntl fcntl "libc.so"
+#pragma dynimport libc·port_create port_create "libc.so"
+#pragma dynimport libc·port_associate port_associate "libc.so"
+#pragma dynimport libc·port_dissociate port_dissociate "libc.so"
+#pragma dynimport libc·port_getn port_getn "libc.so"
+extern uintptr libc·fcntl;
+extern uintptr libc·port_create;
+extern uintptr libc·port_associate;
+extern uintptr libc·port_dissociate;
+extern uintptr libc·port_getn;
+
+#define errno (*g->m->perrno)
+
+int32
+runtime·fcntl(int32 fd, int32 cmd, uintptr arg)
+{
+	return runtime·sysvicall3(libc·fcntl, (uintptr)fd, (uintptr)cmd, (uintptr)arg);
+}
+
+int32
+runtime·port_create(void)
+{
+	return runtime·sysvicall0(libc·port_create);
+}
+
+int32
+runtime·port_associate(int32 port, int32 source, uintptr object, int32 events, uintptr user)
+{
+	return runtime·sysvicall5(libc·port_associate, (uintptr)port, (uintptr)source, object, (uintptr)events, user);
+}
+
+int32
+runtime·port_dissociate(int32 port, int32 source, uintptr object)
+{
+	return runtime·sysvicall3(libc·port_dissociate, (uintptr)port, (uintptr)source, object);
+}
+
+int32
+runtime·port_getn(int32 port, PortEvent *evs, uint32 max, uint32 *nget, Timespec *timeout)
+{
+	return runtime·sysvicall5(libc·port_getn, (uintptr)port, (uintptr)evs, (uintptr)max, (uintptr)nget, (uintptr)timeout);
+}
+
+static int32 portfd = -1;
+
+void
+runtime·netpollinit(void)
+{
+	if((portfd = runtime·port_create()) >= 0) {
+		runtime·fcntl(portfd, F_SETFD, FD_CLOEXEC);
+		return;
+	}
+
+	runtime·printf("netpollinit: failed to create port (%d)\n", errno);
+	runtime·throw("netpollinit: failed to create port");
+}
+
+int32
+runtime·netpollopen(uintptr fd, PollDesc *pd)
+{
+	int32 r;
+
+	runtime·netpolllock(pd);
+	// We don't register for any specific type of events yet, that's
+	// netpollarm's job. We merely ensure we call port_associate before
+	// asynchonous connect/accept completes, so when we actually want
+	// to do any I/O, the call to port_associate (from netpollarm,
+	// with the interested event set) will unblock port_getn right away
+	// because of the I/O readiness notification.
+	*runtime·netpolluser(pd) = 0;
+	r = runtime·port_associate(portfd, PORT_SOURCE_FD, fd, 0, (uintptr)pd);
+	runtime·netpollunlock(pd);
+	return r;
+}
+
+int32
+runtime·netpollclose(uintptr fd)
+{
+	return runtime·port_dissociate(portfd, PORT_SOURCE_FD, fd);
+}
+
+// Updates the association with a new set of interested events. After
+// this call, port_getn will return one and only one event for that
+// particular descriptor, so this function needs to be called again.
+void
+runtime·netpollupdate(PollDesc* pd, uint32 set, uint32 clear)
+{
+	uint32 *ep, old, events;
+	uintptr fd = runtime·netpollfd(pd);
+	ep = (uint32*)runtime·netpolluser(pd);
+
+	if(runtime·netpollclosing(pd))
+		return;
+
+	old = *ep;
+	events = (old & ~clear) | set;
+	if(old == events)
+		return;
+
+	if(events && runtime·port_associate(portfd, PORT_SOURCE_FD, fd, events, (uintptr)pd) != 0) {
+		runtime·printf("netpollupdate: failed to associate (%d)\n", errno);
+		runtime·throw("netpollupdate: failed to associate");
+	} 
+	*ep = events;
+}
+
+// subscribe the fd to the port such that port_getn will return one event.
+void
+runtime·netpollarm(PollDesc* pd, int32 mode)
+{
+	runtime·netpolllock(pd);
+	switch(mode) {
+	case 'r':
+		runtime·netpollupdate(pd, POLLIN, 0);
+		break;
+	case 'w':
+		runtime·netpollupdate(pd, POLLOUT, 0);
+		break;
+	default:
+		runtime·throw("netpollarm: bad mode");
+	}
+	runtime·netpollunlock(pd);
+}
+
+// polls for ready network connections
+// returns list of goroutines that become runnable
+G*
+runtime·netpoll(bool block)
+{
+	static int32 lasterr;
+	PortEvent events[128], *ev;
+	PollDesc *pd;
+	int32 i, mode, clear;
+	uint32 n;
+	Timespec *wait = nil, zero;
+	G *gp;
+
+	if(portfd == -1)
+		return (nil);
+
+	if(!block) {
+		zero.tv_sec = 0;
+		zero.tv_nsec = 0;
+		wait = &zero;
+	}
+
+retry:
+	n = 1;
+	if(runtime·port_getn(portfd, events, nelem(events), &n, wait) < 0) {
+		if(errno != EINTR && errno != lasterr) {
+			lasterr = errno;
+			runtime·printf("runtime: port_getn on fd %d failed with %d\n", portfd, errno);
+		}
+		goto retry;
+	}
+
+	gp = nil;
+	for(i = 0; i < n; i++) {
+		ev = &events[i];
+
+		if(ev->portev_events == 0)
+			continue;
+		pd = (PollDesc *)ev->portev_user;
+
+		mode = 0;
+		clear = 0;
+		if(ev->portev_events & (POLLIN|POLLHUP|POLLERR)) {
+			mode += 'r';
+			clear |= POLLIN;
+		}
+		if(ev->portev_events & (POLLOUT|POLLHUP|POLLERR)) {
+			mode += 'w';
+			clear |= POLLOUT;
+		}
+		// To effect edge-triggered events, we need to be sure to
+		// update our association with whatever events were not
+		// set with the event. For example if we are registered
+		// for POLLIN|POLLOUT, and we get POLLIN, besides waking
+		// the goroutine interested in POLLIN we have to not forget
+		// about the one interested in POLLOUT.
+		if(clear != 0) {
+			runtime·netpolllock(pd);
+			runtime·netpollupdate(pd, 0, clear);
+			runtime·netpollunlock(pd);
+		}
+
+		if(mode)
+			runtime·netpollready(&gp, pd, mode);
+	}
+
+	if(block && gp == nil)
+		goto retry;
+	return gp;
+}
diff --git a/src/pkg/runtime/netpoll_stub.c b/src/runtime/netpoll_stub.c
similarity index 100%
rename from src/pkg/runtime/netpoll_stub.c
rename to src/runtime/netpoll_stub.c
diff --git a/src/runtime/netpoll_windows.c b/src/runtime/netpoll_windows.c
new file mode 100644
index 0000000..64da41a
--- /dev/null
+++ b/src/runtime/netpoll_windows.c
@@ -0,0 +1,163 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "runtime.h"
+#include "defs_GOOS_GOARCH.h"
+#include "os_GOOS.h"
+
+#define DWORD_MAX 0xffffffff
+
+#pragma dynimport runtime·CreateIoCompletionPort CreateIoCompletionPort "kernel32.dll"
+#pragma dynimport runtime·GetQueuedCompletionStatus GetQueuedCompletionStatus "kernel32.dll"
+#pragma dynimport runtime·WSAGetOverlappedResult WSAGetOverlappedResult "ws2_32.dll"
+
+extern void *runtime·CreateIoCompletionPort;
+extern void *runtime·GetQueuedCompletionStatus;
+extern void *runtime·WSAGetOverlappedResult;
+
+#define INVALID_HANDLE_VALUE ((uintptr)-1)
+
+// net_op must be the same as beginning of net.operation. Keep these in sync.
+typedef struct net_op net_op;
+struct net_op
+{
+	// used by windows
+	Overlapped	o;
+	// used by netpoll
+	PollDesc*	pd;
+	int32	mode;
+	int32	errno;
+	uint32	qty;
+};
+
+typedef struct OverlappedEntry OverlappedEntry;
+struct OverlappedEntry
+{
+	uintptr	key;
+	net_op*	op;  // In reality it's Overlapped*, but we cast it to net_op* anyway.
+	uintptr	internal;
+	uint32	qty;
+};
+
+static void handlecompletion(G **gpp, net_op *o, int32 errno, uint32 qty);
+
+static uintptr iocphandle = INVALID_HANDLE_VALUE;  // completion port io handle
+
+void
+runtime·netpollinit(void)
+{
+	iocphandle = (uintptr)runtime·stdcall4(runtime·CreateIoCompletionPort, INVALID_HANDLE_VALUE, 0, 0, DWORD_MAX);
+	if(iocphandle == 0) {
+		runtime·printf("netpoll: failed to create iocp handle (errno=%d)\n", runtime·getlasterror());
+		runtime·throw("netpoll: failed to create iocp handle");
+	}
+	return;
+}
+
+int32
+runtime·netpollopen(uintptr fd, PollDesc *pd)
+{
+	USED(pd);
+	if(runtime·stdcall4(runtime·CreateIoCompletionPort, fd, iocphandle, 0, 0) == 0)
+		return -runtime·getlasterror();
+	return 0;
+}
+
+int32
+runtime·netpollclose(uintptr fd)
+{
+	// nothing to do
+	USED(fd);
+	return 0;
+}
+
+void
+runtime·netpollarm(PollDesc* pd, int32 mode)
+{
+	USED(pd, mode);
+	runtime·throw("unused");
+}
+
+// Polls for completed network IO.
+// Returns list of goroutines that become runnable.
+G*
+runtime·netpoll(bool block)
+{
+	OverlappedEntry entries[64];
+	uint32 wait, qty, key, flags, n, i;
+	int32 errno;
+	net_op *op;
+	G *gp;
+
+	if(iocphandle == INVALID_HANDLE_VALUE)
+		return nil;
+	gp = nil;
+	wait = 0;
+	if(block)
+		wait = INFINITE;
+retry:
+	if(runtime·GetQueuedCompletionStatusEx != nil) {
+		n = nelem(entries) / runtime·gomaxprocs;
+		if(n < 8)
+			n = 8;
+		if(block)
+			g->m->blocked = true;
+		if(runtime·stdcall6(runtime·GetQueuedCompletionStatusEx, iocphandle, (uintptr)entries, n, (uintptr)&n, wait, 0) == 0) {
+			g->m->blocked = false;
+			errno = runtime·getlasterror();
+			if(!block && errno == WAIT_TIMEOUT)
+				return nil;
+			runtime·printf("netpoll: GetQueuedCompletionStatusEx failed (errno=%d)\n", errno);
+			runtime·throw("netpoll: GetQueuedCompletionStatusEx failed");
+		}
+		g->m->blocked = false;
+		for(i = 0; i < n; i++) {
+			op = entries[i].op;
+			errno = 0;
+			qty = 0;
+			if(runtime·stdcall5(runtime·WSAGetOverlappedResult, runtime·netpollfd(op->pd), (uintptr)op, (uintptr)&qty, 0, (uintptr)&flags) == 0)
+				errno = runtime·getlasterror();
+			handlecompletion(&gp, op, errno, qty);
+		}
+	} else {
+		op = nil;
+		errno = 0;
+		qty = 0;
+		if(block)
+			g->m->blocked = true;
+		if(runtime·stdcall5(runtime·GetQueuedCompletionStatus, iocphandle, (uintptr)&qty, (uintptr)&key, (uintptr)&op, wait) == 0) {
+			g->m->blocked = false;
+			errno = runtime·getlasterror();
+			if(!block && errno == WAIT_TIMEOUT)
+				return nil;
+			if(op == nil) {
+				runtime·printf("netpoll: GetQueuedCompletionStatus failed (errno=%d)\n", errno);
+				runtime·throw("netpoll: GetQueuedCompletionStatus failed");
+			}
+			// dequeued failed IO packet, so report that
+		}
+		g->m->blocked = false;
+		handlecompletion(&gp, op, errno, qty);
+	}
+	if(block && gp == nil)
+		goto retry;
+	return gp;
+}
+
+static void
+handlecompletion(G **gpp, net_op *op, int32 errno, uint32 qty)
+{
+	int32 mode;
+
+	if(op == nil)
+		runtime·throw("netpoll: GetQueuedCompletionStatus returned op == nil");
+	mode = op->mode;
+	if(mode != 'r' && mode != 'w') {
+		runtime·printf("netpoll: GetQueuedCompletionStatus returned invalid mode=%d\n", mode);
+		runtime·throw("netpoll: GetQueuedCompletionStatus returned invalid mode");
+	}
+	op->errno = errno;
+	op->qty = qty;
+	runtime·netpollready(gpp, op->pd, mode);
+}
diff --git a/src/runtime/noasm_arm.go b/src/runtime/noasm_arm.go
new file mode 100644
index 0000000..dd3ef82
--- /dev/null
+++ b/src/runtime/noasm_arm.go
@@ -0,0 +1,54 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Routines that are implemented in assembly in asm_{amd64,386}.s
+// but are implemented in Go for arm.
+
+package runtime
+
+func cmpstring(s1, s2 string) int {
+	l := len(s1)
+	if len(s2) < l {
+		l = len(s2)
+	}
+	for i := 0; i < l; i++ {
+		c1, c2 := s1[i], s2[i]
+		if c1 < c2 {
+			return -1
+		}
+		if c1 > c2 {
+			return +1
+		}
+	}
+	if len(s1) < len(s2) {
+		return -1
+	}
+	if len(s1) > len(s2) {
+		return +1
+	}
+	return 0
+}
+
+func cmpbytes(s1, s2 []byte) int {
+	l := len(s1)
+	if len(s2) < l {
+		l = len(s2)
+	}
+	for i := 0; i < l; i++ {
+		c1, c2 := s1[i], s2[i]
+		if c1 < c2 {
+			return -1
+		}
+		if c1 > c2 {
+			return +1
+		}
+	}
+	if len(s1) < len(s2) {
+		return -1
+	}
+	if len(s1) > len(s2) {
+		return +1
+	}
+	return 0
+}
diff --git a/src/pkg/runtime/norace_test.go b/src/runtime/norace_test.go
similarity index 100%
rename from src/pkg/runtime/norace_test.go
rename to src/runtime/norace_test.go
diff --git a/src/runtime/os_android.c b/src/runtime/os_android.c
new file mode 100644
index 0000000..5805f68
--- /dev/null
+++ b/src/runtime/os_android.c
@@ -0,0 +1,16 @@
+// 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 "runtime.h"
+#include "defs_GOOS_GOARCH.h"
+#include "os_GOOS.h"
+
+// Export the runtime entry point symbol.
+//
+// Used by the app package to start the Go runtime after loading
+// a shared library via JNI. See golang.org/x/mobile/app.
+
+void _rt0_arm_linux1();
+#pragma cgo_export_static _rt0_arm_linux1
+#pragma cgo_export_dynamic _rt0_arm_linux1
diff --git a/src/runtime/os_android.h b/src/runtime/os_android.h
new file mode 100644
index 0000000..c7c1098
--- /dev/null
+++ b/src/runtime/os_android.h
@@ -0,0 +1 @@
+#include "os_linux.h"
diff --git a/src/runtime/os_darwin.c b/src/runtime/os_darwin.c
new file mode 100644
index 0000000..bbd2928
--- /dev/null
+++ b/src/runtime/os_darwin.c
@@ -0,0 +1,567 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "runtime.h"
+#include "defs_GOOS_GOARCH.h"
+#include "os_GOOS.h"
+#include "signal_unix.h"
+#include "stack.h"
+#include "textflag.h"
+
+extern SigTab runtime·sigtab[];
+
+static Sigset sigset_none;
+static Sigset sigset_all = ~(Sigset)0;
+
+static void
+unimplemented(int8 *name)
+{
+	runtime·prints(name);
+	runtime·prints(" not implemented\n");
+	*(int32*)1231 = 1231;
+}
+
+#pragma textflag NOSPLIT
+void
+runtime·semawakeup(M *mp)
+{
+	runtime·mach_semrelease(mp->waitsema);
+}
+
+static void
+semacreate(void)
+{
+	g->m->scalararg[0] = runtime·mach_semcreate();
+}
+
+#pragma textflag NOSPLIT
+uintptr
+runtime·semacreate(void)
+{
+	uintptr x;
+	void (*fn)(void);
+	
+	fn = semacreate;
+	runtime·onM(&fn);
+	x = g->m->scalararg[0];
+	g->m->scalararg[0] = 0;
+	return x;
+}
+
+// BSD interface for threading.
+void
+runtime·osinit(void)
+{
+	// bsdthread_register delayed until end of goenvs so that we
+	// can look at the environment first.
+
+	// Use sysctl to fetch hw.ncpu.
+	uint32 mib[2];
+	uint32 out;
+	int32 ret;
+	uintptr nout;
+
+	mib[0] = 6;
+	mib[1] = 3;
+	nout = sizeof out;
+	out = 0;
+	ret = runtime·sysctl(mib, 2, (byte*)&out, &nout, nil, 0);
+	if(ret >= 0)
+		runtime·ncpu = out;
+}
+
+#pragma textflag NOSPLIT
+void
+runtime·get_random_data(byte **rnd, int32 *rnd_len)
+{
+	#pragma dataflag NOPTR
+	static byte urandom_data[HashRandomBytes];
+	int32 fd;
+	fd = runtime·open("/dev/urandom", 0 /* O_RDONLY */, 0);
+	if(runtime·read(fd, urandom_data, HashRandomBytes) == HashRandomBytes) {
+		*rnd = urandom_data;
+		*rnd_len = HashRandomBytes;
+	} else {
+		*rnd = nil;
+		*rnd_len = 0;
+	}
+	runtime·close(fd);
+}
+
+void
+runtime·goenvs(void)
+{
+	runtime·goenvs_unix();
+
+	// Register our thread-creation callback (see sys_darwin_{amd64,386}.s)
+	// but only if we're not using cgo.  If we are using cgo we need
+	// to let the C pthread library install its own thread-creation callback.
+	if(!runtime·iscgo) {
+		if(runtime·bsdthread_register() != 0) {
+			if(runtime·getenv("DYLD_INSERT_LIBRARIES"))
+				runtime·throw("runtime: bsdthread_register error (unset DYLD_INSERT_LIBRARIES)");
+			runtime·throw("runtime: bsdthread_register error");
+		}
+	}
+
+}
+
+void
+runtime·newosproc(M *mp, void *stk)
+{
+	int32 errno;
+	Sigset oset;
+
+	mp->tls[0] = mp->id;	// so 386 asm can find it
+	if(0){
+		runtime·printf("newosproc stk=%p m=%p g=%p id=%d/%d ostk=%p\n",
+			stk, mp, mp->g0, mp->id, (int32)mp->tls[0], &mp);
+	}
+
+	runtime·sigprocmask(SIG_SETMASK, &sigset_all, &oset);
+	errno = runtime·bsdthread_create(stk, mp, mp->g0, runtime·mstart);
+	runtime·sigprocmask(SIG_SETMASK, &oset, nil);
+
+	if(errno < 0) {
+		runtime·printf("runtime: failed to create new OS thread (have %d already; errno=%d)\n", runtime·mcount(), -errno);
+		runtime·throw("runtime.newosproc");
+	}
+}
+
+// Called to initialize a new m (including the bootstrap m).
+// Called on the parent thread (main thread in case of bootstrap), can allocate memory.
+void
+runtime·mpreinit(M *mp)
+{
+	mp->gsignal = runtime·malg(32*1024);	// OS X wants >=8K, Linux >=2K
+	mp->gsignal->m = mp;
+}
+
+// Called to initialize a new m (including the bootstrap m).
+// Called on the new thread, can not allocate memory.
+void
+runtime·minit(void)
+{
+	// Initialize signal handling.
+	runtime·signalstack((byte*)g->m->gsignal->stack.lo, 32*1024);
+
+	runtime·sigprocmask(SIG_SETMASK, &sigset_none, nil);
+}
+
+// Called from dropm to undo the effect of an minit.
+void
+runtime·unminit(void)
+{
+	runtime·signalstack(nil, 0);
+}
+
+// Mach IPC, to get at semaphores
+// Definitions are in /usr/include/mach on a Mac.
+
+static void
+macherror(int32 r, int8 *fn)
+{
+	runtime·prints("mach error ");
+	runtime·prints(fn);
+	runtime·prints(": ");
+	runtime·printint(r);
+	runtime·prints("\n");
+	runtime·throw("mach error");
+}
+
+enum
+{
+	DebugMach = 0
+};
+
+static MachNDR zerondr;
+
+#define MACH_MSGH_BITS(a, b) ((a) | ((b)<<8))
+
+static int32
+mach_msg(MachHeader *h,
+	int32 op,
+	uint32 send_size,
+	uint32 rcv_size,
+	uint32 rcv_name,
+	uint32 timeout,
+	uint32 notify)
+{
+	// TODO: Loop on interrupt.
+	return runtime·mach_msg_trap(h, op, send_size, rcv_size, rcv_name, timeout, notify);
+}
+
+// Mach RPC (MIG)
+
+enum
+{
+	MinMachMsg = 48,
+	Reply = 100,
+};
+
+#pragma pack on
+typedef struct CodeMsg CodeMsg;
+struct CodeMsg
+{
+	MachHeader h;
+	MachNDR NDR;
+	int32 code;
+};
+#pragma pack off
+
+static int32
+machcall(MachHeader *h, int32 maxsize, int32 rxsize)
+{
+	uint32 *p;
+	int32 i, ret, id;
+	uint32 port;
+	CodeMsg *c;
+
+	if((port = g->m->machport) == 0){
+		port = runtime·mach_reply_port();
+		g->m->machport = port;
+	}
+
+	h->msgh_bits |= MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, MACH_MSG_TYPE_MAKE_SEND_ONCE);
+	h->msgh_local_port = port;
+	h->msgh_reserved = 0;
+	id = h->msgh_id;
+
+	if(DebugMach){
+		p = (uint32*)h;
+		runtime·prints("send:\t");
+		for(i=0; i<h->msgh_size/sizeof(p[0]); i++){
+			runtime·prints(" ");
+			runtime·printpointer((void*)p[i]);
+			if(i%8 == 7)
+				runtime·prints("\n\t");
+		}
+		if(i%8)
+			runtime·prints("\n");
+	}
+
+	ret = mach_msg(h, MACH_SEND_MSG|MACH_RCV_MSG,
+		h->msgh_size, maxsize, port, 0, 0);
+	if(ret != 0){
+		if(DebugMach){
+			runtime·prints("mach_msg error ");
+			runtime·printint(ret);
+			runtime·prints("\n");
+		}
+		return ret;
+	}
+
+	if(DebugMach){
+		p = (uint32*)h;
+		runtime·prints("recv:\t");
+		for(i=0; i<h->msgh_size/sizeof(p[0]); i++){
+			runtime·prints(" ");
+			runtime·printpointer((void*)p[i]);
+			if(i%8 == 7)
+				runtime·prints("\n\t");
+		}
+		if(i%8)
+			runtime·prints("\n");
+	}
+
+	if(h->msgh_id != id+Reply){
+		if(DebugMach){
+			runtime·prints("mach_msg reply id mismatch ");
+			runtime·printint(h->msgh_id);
+			runtime·prints(" != ");
+			runtime·printint(id+Reply);
+			runtime·prints("\n");
+		}
+		return -303;	// MIG_REPLY_MISMATCH
+	}
+
+	// Look for a response giving the return value.
+	// Any call can send this back with an error,
+	// and some calls only have return values so they
+	// send it back on success too.  I don't quite see how
+	// you know it's one of these and not the full response
+	// format, so just look if the message is right.
+	c = (CodeMsg*)h;
+	if(h->msgh_size == sizeof(CodeMsg)
+	&& !(h->msgh_bits & MACH_MSGH_BITS_COMPLEX)){
+		if(DebugMach){
+			runtime·prints("mig result ");
+			runtime·printint(c->code);
+			runtime·prints("\n");
+		}
+		return c->code;
+	}
+
+	if(h->msgh_size != rxsize){
+		if(DebugMach){
+			runtime·prints("mach_msg reply size mismatch ");
+			runtime·printint(h->msgh_size);
+			runtime·prints(" != ");
+			runtime·printint(rxsize);
+			runtime·prints("\n");
+		}
+		return -307;	// MIG_ARRAY_TOO_LARGE
+	}
+
+	return 0;
+}
+
+
+// Semaphores!
+
+enum
+{
+	Tmach_semcreate = 3418,
+	Rmach_semcreate = Tmach_semcreate + Reply,
+
+	Tmach_semdestroy = 3419,
+	Rmach_semdestroy = Tmach_semdestroy + Reply,
+
+	// Mach calls that get interrupted by Unix signals
+	// return this error code.  We retry them.
+	KERN_ABORTED = 14,
+	KERN_OPERATION_TIMED_OUT = 49,
+};
+
+typedef struct Tmach_semcreateMsg Tmach_semcreateMsg;
+typedef struct Rmach_semcreateMsg Rmach_semcreateMsg;
+typedef struct Tmach_semdestroyMsg Tmach_semdestroyMsg;
+// Rmach_semdestroyMsg = CodeMsg
+
+#pragma pack on
+struct Tmach_semcreateMsg
+{
+	MachHeader h;
+	MachNDR ndr;
+	int32 policy;
+	int32 value;
+};
+
+struct Rmach_semcreateMsg
+{
+	MachHeader h;
+	MachBody body;
+	MachPort semaphore;
+};
+
+struct Tmach_semdestroyMsg
+{
+	MachHeader h;
+	MachBody body;
+	MachPort semaphore;
+};
+#pragma pack off
+
+uint32
+runtime·mach_semcreate(void)
+{
+	union {
+		Tmach_semcreateMsg tx;
+		Rmach_semcreateMsg rx;
+		uint8 pad[MinMachMsg];
+	} m;
+	int32 r;
+
+	m.tx.h.msgh_bits = 0;
+	m.tx.h.msgh_size = sizeof(m.tx);
+	m.tx.h.msgh_remote_port = runtime·mach_task_self();
+	m.tx.h.msgh_id = Tmach_semcreate;
+	m.tx.ndr = zerondr;
+
+	m.tx.policy = 0;	// 0 = SYNC_POLICY_FIFO
+	m.tx.value = 0;
+
+	while((r = machcall(&m.tx.h, sizeof m, sizeof(m.rx))) != 0){
+		if(r == KERN_ABORTED)	// interrupted
+			continue;
+		macherror(r, "semaphore_create");
+	}
+	if(m.rx.body.msgh_descriptor_count != 1)
+		unimplemented("mach_semcreate desc count");
+	return m.rx.semaphore.name;
+}
+
+void
+runtime·mach_semdestroy(uint32 sem)
+{
+	union {
+		Tmach_semdestroyMsg tx;
+		uint8 pad[MinMachMsg];
+	} m;
+	int32 r;
+
+	m.tx.h.msgh_bits = MACH_MSGH_BITS_COMPLEX;
+	m.tx.h.msgh_size = sizeof(m.tx);
+	m.tx.h.msgh_remote_port = runtime·mach_task_self();
+	m.tx.h.msgh_id = Tmach_semdestroy;
+	m.tx.body.msgh_descriptor_count = 1;
+	m.tx.semaphore.name = sem;
+	m.tx.semaphore.disposition = MACH_MSG_TYPE_MOVE_SEND;
+	m.tx.semaphore.type = 0;
+
+	while((r = machcall(&m.tx.h, sizeof m, 0)) != 0){
+		if(r == KERN_ABORTED)	// interrupted
+			continue;
+		macherror(r, "semaphore_destroy");
+	}
+}
+
+// The other calls have simple system call traps in sys_darwin_{amd64,386}.s
+int32 runtime·mach_semaphore_wait(uint32 sema);
+int32 runtime·mach_semaphore_timedwait(uint32 sema, uint32 sec, uint32 nsec);
+int32 runtime·mach_semaphore_signal(uint32 sema);
+int32 runtime·mach_semaphore_signal_all(uint32 sema);
+
+static void
+semasleep(void)
+{
+	int32 r, secs, nsecs;
+	int64 ns;
+	
+	ns = (int64)(uint32)g->m->scalararg[0] | (int64)(uint32)g->m->scalararg[1]<<32;
+	g->m->scalararg[0] = 0;
+	g->m->scalararg[1] = 0;
+
+	if(ns >= 0) {
+		secs = runtime·timediv(ns, 1000000000, &nsecs);
+		r = runtime·mach_semaphore_timedwait(g->m->waitsema, secs, nsecs);
+		if(r == KERN_ABORTED || r == KERN_OPERATION_TIMED_OUT) {
+			g->m->scalararg[0] = -1;
+			return;
+		}
+		if(r != 0)
+			macherror(r, "semaphore_wait");
+		g->m->scalararg[0] = 0;
+		return;
+	}
+	while((r = runtime·mach_semaphore_wait(g->m->waitsema)) != 0) {
+		if(r == KERN_ABORTED)	// interrupted
+			continue;
+		macherror(r, "semaphore_wait");
+	}
+	g->m->scalararg[0] = 0;
+	return;
+}
+
+#pragma textflag NOSPLIT
+int32
+runtime·semasleep(int64 ns)
+{
+	int32 r;
+	void (*fn)(void);
+
+	g->m->scalararg[0] = (uint32)ns;
+	g->m->scalararg[1] = (uint32)(ns>>32);
+	fn = semasleep;
+	runtime·onM(&fn);
+	r = g->m->scalararg[0];
+	g->m->scalararg[0] = 0;
+	return r;
+}
+
+static int32 mach_semrelease_errno;
+
+static void
+mach_semrelease_fail(void)
+{
+	macherror(mach_semrelease_errno, "semaphore_signal");
+}
+
+#pragma textflag NOSPLIT
+void
+runtime·mach_semrelease(uint32 sem)
+{
+	int32 r;
+	void (*fn)(void);
+
+	while((r = runtime·mach_semaphore_signal(sem)) != 0) {
+		if(r == KERN_ABORTED)	// interrupted
+			continue;
+		
+		// mach_semrelease must be completely nosplit,
+		// because it is called from Go code.
+		// If we're going to die, start that process on the m stack
+		// to avoid a Go stack split.
+		// Only do that if we're actually running on the g stack.
+		// We might be on the gsignal stack, and if so, onM will abort.
+		// We use the global variable instead of scalararg because
+		// we might be on the gsignal stack, having interrupted a
+		// normal call to onM. It doesn't quite matter, since the
+		// program is about to die, but better to be clean.
+		mach_semrelease_errno = r;
+		fn = mach_semrelease_fail;
+		if(g == g->m->curg)
+			runtime·onM(&fn);
+		else
+			fn();
+	}
+}
+
+#pragma textflag NOSPLIT
+void
+runtime·osyield(void)
+{
+	runtime·usleep(1);
+}
+
+uintptr
+runtime·memlimit(void)
+{
+	// NOTE(rsc): Could use getrlimit here,
+	// like on FreeBSD or Linux, but Darwin doesn't enforce
+	// ulimit -v, so it's unclear why we'd try to stay within
+	// the limit.
+	return 0;
+}
+
+void
+runtime·setsig(int32 i, GoSighandler *fn, bool restart)
+{
+	SigactionT sa;
+		
+	runtime·memclr((byte*)&sa, sizeof sa);
+	sa.sa_flags = SA_SIGINFO|SA_ONSTACK;
+	if(restart)
+		sa.sa_flags |= SA_RESTART;
+	sa.sa_mask = ~(uintptr)0;
+	sa.sa_tramp = (void*)runtime·sigtramp;	// runtime·sigtramp's job is to call into real handler
+	*(uintptr*)sa.__sigaction_u = (uintptr)fn;
+	runtime·sigaction(i, &sa, nil);
+}
+
+GoSighandler*
+runtime·getsig(int32 i)
+{
+	SigactionT sa;
+
+	runtime·memclr((byte*)&sa, sizeof sa);
+	runtime·sigaction(i, nil, &sa);
+	return *(void**)sa.__sigaction_u;
+}
+
+void
+runtime·signalstack(byte *p, int32 n)
+{
+	StackT st;
+
+	st.ss_sp = (void*)p;
+	st.ss_size = n;
+	st.ss_flags = 0;
+	if(p == nil)
+		st.ss_flags = SS_DISABLE;
+	runtime·sigaltstack(&st, nil);
+}
+
+void
+runtime·unblocksignals(void)
+{
+	runtime·sigprocmask(SIG_SETMASK, &sigset_none, nil);
+}
+
+#pragma textflag NOSPLIT
+int8*
+runtime·signame(int32 sig)
+{
+	return runtime·sigtab[sig].name;
+}
diff --git a/src/runtime/os_darwin.go b/src/runtime/os_darwin.go
new file mode 100644
index 0000000..4327ced
--- /dev/null
+++ b/src/runtime/os_darwin.go
@@ -0,0 +1,24 @@
+// 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 runtime
+
+import "unsafe"
+
+func bsdthread_create(stk, mm, gg, fn unsafe.Pointer) int32
+func bsdthread_register() int32
+func mach_msg_trap(h unsafe.Pointer, op int32, send_size, rcv_size, rcv_name, timeout, notify uint32) int32
+func mach_reply_port() uint32
+func mach_task_self() uint32
+func mach_thread_self() uint32
+func sysctl(mib *uint32, miblen uint32, out *byte, size *uintptr, dst *byte, ndst uintptr) int32
+func sigprocmask(sig int32, new, old unsafe.Pointer)
+func sigaction(mode uint32, new, old unsafe.Pointer)
+func sigaltstack(new, old unsafe.Pointer)
+func sigtramp()
+func setitimer(mode int32, new, old unsafe.Pointer)
+func mach_semaphore_wait(sema uint32) int32
+func mach_semaphore_timedwait(sema, sec, nsec uint32) int32
+func mach_semaphore_signal(sema uint32) int32
+func mach_semaphore_signal_all(sema uint32) int32
diff --git a/src/runtime/os_darwin.h b/src/runtime/os_darwin.h
new file mode 100644
index 0000000..e8bb45d
--- /dev/null
+++ b/src/runtime/os_darwin.h
@@ -0,0 +1,43 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+typedef byte* kevent_udata;
+
+int32	runtime·bsdthread_create(void*, M*, G*, void(*)(void));
+int32	runtime·bsdthread_register(void);
+int32	runtime·mach_msg_trap(MachHeader*, int32, uint32, uint32, uint32, uint32, uint32);
+uint32	runtime·mach_reply_port(void);
+int32	runtime·mach_semacquire(uint32, int64);
+uint32	runtime·mach_semcreate(void);
+void	runtime·mach_semdestroy(uint32);
+void	runtime·mach_semrelease(uint32);
+void	runtime·mach_semreset(uint32);
+uint32	runtime·mach_task_self(void);
+uint32	runtime·mach_task_self(void);
+uint32	runtime·mach_thread_self(void);
+uint32	runtime·mach_thread_self(void);
+int32	runtime·sysctl(uint32*, uint32, byte*, uintptr*, byte*, uintptr);
+
+typedef uint32 Sigset;
+void	runtime·sigprocmask(int32, Sigset*, Sigset*);
+void	runtime·unblocksignals(void);
+
+struct SigactionT;
+void	runtime·sigaction(uintptr, struct SigactionT*, struct SigactionT*);
+
+struct StackT;
+void	runtime·sigaltstack(struct StackT*, struct StackT*);
+void	runtime·sigtramp(void);
+void	runtime·sigpanic(void);
+void	runtime·setitimer(int32, Itimerval*, Itimerval*);
+
+
+enum {
+	NSIG = 32,
+	SI_USER = 0, /* empirically true, but not what headers say */
+	SIG_BLOCK = 1,
+	SIG_UNBLOCK = 2,
+	SIG_SETMASK = 3,
+	SS_DISABLE = 4,
+};
diff --git a/src/runtime/os_dragonfly.c b/src/runtime/os_dragonfly.c
new file mode 100644
index 0000000..e372205
--- /dev/null
+++ b/src/runtime/os_dragonfly.c
@@ -0,0 +1,312 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "runtime.h"
+#include "defs_GOOS_GOARCH.h"
+#include "os_GOOS.h"
+#include "signal_unix.h"
+#include "stack.h"
+#include "textflag.h"
+
+extern SigTab runtime·sigtab[];
+extern int32 runtime·sys_umtx_sleep(uint32*, int32, int32);
+extern int32 runtime·sys_umtx_wakeup(uint32*, int32);
+
+// From DragonFly's <sys/sysctl.h>
+#define	CTL_HW	6
+#define	HW_NCPU	3
+
+static Sigset sigset_none;
+static Sigset sigset_all = { ~(uint32)0, ~(uint32)0, ~(uint32)0, ~(uint32)0, };
+
+static int32
+getncpu(void)
+{
+	uint32 mib[2];
+	uint32 out;
+	int32 ret;
+	uintptr nout;
+
+	// Fetch hw.ncpu via sysctl.
+	mib[0] = CTL_HW;
+	mib[1] = HW_NCPU;
+	nout = sizeof out;
+	out = 0;
+	ret = runtime·sysctl(mib, 2, (byte*)&out, &nout, nil, 0);
+	if(ret >= 0)
+		return out;
+	else
+		return 1;
+}
+
+static void futexsleep(void);
+
+#pragma textflag NOSPLIT
+void
+runtime·futexsleep(uint32 *addr, uint32 val, int64 ns)
+{
+	void (*fn)(void);
+
+	g->m->ptrarg[0] = addr;
+	g->m->scalararg[0] = val;
+	g->m->ptrarg[1] = &ns;
+
+	fn = futexsleep;
+	runtime·onM(&fn);
+}
+
+static void
+futexsleep(void)
+{
+	uint32 *addr;
+	uint32 val;
+	int64 ns;
+	int32 timeout = 0;
+	int32 ret;
+
+	addr = g->m->ptrarg[0];
+	val = g->m->scalararg[0];
+	ns = *(int64*)g->m->ptrarg[1];
+	g->m->ptrarg[0] = nil;
+	g->m->scalararg[0] = 0;
+	g->m->ptrarg[1] = nil;
+
+	if(ns >= 0) {
+		// The timeout is specified in microseconds - ensure that we
+		// do not end up dividing to zero, which would put us to sleep
+		// indefinitely...
+		timeout = runtime·timediv(ns, 1000, nil);
+		if(timeout == 0)
+			timeout = 1;
+	}
+
+	// sys_umtx_sleep will return EWOULDBLOCK (EAGAIN) when the timeout
+	// expires or EBUSY if the mutex value does not match. 
+	ret = runtime·sys_umtx_sleep(addr, val, timeout);
+	if(ret >= 0 || ret == -EINTR || ret == -EAGAIN || ret == -EBUSY)
+		return;
+
+	runtime·prints("umtx_wait addr=");
+	runtime·printpointer(addr);
+	runtime·prints(" val=");
+	runtime·printint(val);
+	runtime·prints(" ret=");
+	runtime·printint(ret);
+	runtime·prints("\n");
+	*(int32*)0x1005 = 0x1005;
+}
+
+static void badfutexwakeup(void);
+
+#pragma textflag NOSPLIT
+void
+runtime·futexwakeup(uint32 *addr, uint32 cnt)
+{
+	int32 ret;
+	void (*fn)(void);
+
+	ret = runtime·sys_umtx_wakeup(addr, cnt);
+	if(ret >= 0)
+		return;
+
+	g->m->ptrarg[0] = addr;
+	g->m->scalararg[0] = ret;
+	fn = badfutexwakeup;
+	if(g == g->m->gsignal)
+		fn();
+	else
+		runtime·onM(&fn);
+	*(int32*)0x1006 = 0x1006;
+}
+
+static void
+badfutexwakeup(void)
+{
+	void *addr;
+	int32 ret;
+	
+	addr = g->m->ptrarg[0];
+	ret = g->m->scalararg[0];
+	runtime·printf("umtx_wake addr=%p ret=%d\n", addr, ret);
+}
+
+void runtime·lwp_start(void*);
+
+void
+runtime·newosproc(M *mp, void *stk)
+{
+	Lwpparams params;
+	Sigset oset;
+
+	if(0){
+		runtime·printf("newosproc stk=%p m=%p g=%p id=%d/%d ostk=%p\n",
+			stk, mp, mp->g0, mp->id, (int32)mp->tls[0], &mp);
+	}
+
+	runtime·sigprocmask(&sigset_all, &oset);
+	runtime·memclr((byte*)&params, sizeof params);
+
+	params.func = runtime·lwp_start;
+	params.arg = (byte*)mp;
+	params.stack = (byte*)stk;
+	params.tid1 = (int32*)&mp->procid;
+	params.tid2 = nil;
+
+	mp->tls[0] = mp->id;	// so 386 asm can find it
+
+	runtime·lwp_create(&params);
+	runtime·sigprocmask(&oset, nil);
+}
+
+void
+runtime·osinit(void)
+{
+	runtime·ncpu = getncpu();
+}
+
+#pragma textflag NOSPLIT
+void
+runtime·get_random_data(byte **rnd, int32 *rnd_len)
+{
+	#pragma dataflag NOPTR
+	static byte urandom_data[HashRandomBytes];
+	int32 fd;
+	fd = runtime·open("/dev/urandom", 0 /* O_RDONLY */, 0);
+	if(runtime·read(fd, urandom_data, HashRandomBytes) == HashRandomBytes) {
+		*rnd = urandom_data;
+		*rnd_len = HashRandomBytes;
+	} else {
+		*rnd = nil;
+		*rnd_len = 0;
+	}
+	runtime·close(fd);
+}
+
+void
+runtime·goenvs(void)
+{
+	runtime·goenvs_unix();
+}
+
+// Called to initialize a new m (including the bootstrap m).
+// Called on the parent thread (main thread in case of bootstrap), can allocate memory.
+void
+runtime·mpreinit(M *mp)
+{
+	mp->gsignal = runtime·malg(32*1024);
+	mp->gsignal->m = mp;
+}
+
+// Called to initialize a new m (including the bootstrap m).
+// Called on the new thread, can not allocate memory.
+void
+runtime·minit(void)
+{
+	// Initialize signal handling
+	runtime·signalstack((byte*)g->m->gsignal->stack.lo, 32*1024);
+	runtime·sigprocmask(&sigset_none, nil);
+}
+
+// Called from dropm to undo the effect of an minit.
+void
+runtime·unminit(void)
+{
+	runtime·signalstack(nil, 0);
+}
+
+uintptr
+runtime·memlimit(void)
+{
+	Rlimit rl;
+	extern byte runtime·text[], runtime·end[];
+	uintptr used;
+	
+	if(runtime·getrlimit(RLIMIT_AS, &rl) != 0)
+		return 0;
+	if(rl.rlim_cur >= 0x7fffffff)
+		return 0;
+
+	// Estimate our VM footprint excluding the heap.
+	// Not an exact science: use size of binary plus
+	// some room for thread stacks.
+	used = runtime·end - runtime·text + (64<<20);
+	if(used >= rl.rlim_cur)
+		return 0;
+
+	// If there's not at least 16 MB left, we're probably
+	// not going to be able to do much.  Treat as no limit.
+	rl.rlim_cur -= used;
+	if(rl.rlim_cur < (16<<20))
+		return 0;
+
+	return rl.rlim_cur - used;
+}
+
+extern void runtime·sigtramp(void);
+
+typedef struct sigaction {
+	union {
+		void    (*__sa_handler)(int32);
+		void    (*__sa_sigaction)(int32, Siginfo*, void *);
+	} __sigaction_u;		/* signal handler */
+	int32	sa_flags;		/* see signal options below */
+	Sigset	sa_mask;		/* signal mask to apply */
+} SigactionT;
+
+void
+runtime·setsig(int32 i, GoSighandler *fn, bool restart)
+{
+	SigactionT sa;
+
+	runtime·memclr((byte*)&sa, sizeof sa);
+	sa.sa_flags = SA_SIGINFO|SA_ONSTACK;
+	if(restart)
+		sa.sa_flags |= SA_RESTART;
+	sa.sa_mask.__bits[0] = ~(uint32)0;
+	sa.sa_mask.__bits[1] = ~(uint32)0;
+	sa.sa_mask.__bits[2] = ~(uint32)0;
+	sa.sa_mask.__bits[3] = ~(uint32)0;
+	if(fn == runtime·sighandler)
+		fn = (void*)runtime·sigtramp;
+	sa.__sigaction_u.__sa_sigaction = (void*)fn;
+	runtime·sigaction(i, &sa, nil);
+}
+
+GoSighandler*
+runtime·getsig(int32 i)
+{
+	SigactionT sa;
+
+	runtime·memclr((byte*)&sa, sizeof sa);
+	runtime·sigaction(i, nil, &sa);
+	if((void*)sa.__sigaction_u.__sa_sigaction == runtime·sigtramp)
+		return runtime·sighandler;
+	return (void*)sa.__sigaction_u.__sa_sigaction;
+}
+
+void
+runtime·signalstack(byte *p, int32 n)
+{
+	StackT st;
+
+	st.ss_sp = (void*)p;
+	st.ss_size = n;
+	st.ss_flags = 0;
+	if(p == nil)
+		st.ss_flags = SS_DISABLE;
+	runtime·sigaltstack(&st, nil);
+}
+
+void
+runtime·unblocksignals(void)
+{
+	runtime·sigprocmask(&sigset_none, nil);
+}
+
+#pragma textflag NOSPLIT
+int8*
+runtime·signame(int32 sig)
+{
+	return runtime·sigtab[sig].name;
+}
diff --git a/src/runtime/os_dragonfly.go b/src/runtime/os_dragonfly.go
new file mode 100644
index 0000000..cdaa069
--- /dev/null
+++ b/src/runtime/os_dragonfly.go
@@ -0,0 +1,20 @@
+// 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 runtime
+
+import "unsafe"
+
+func lwp_create(param unsafe.Pointer) int32
+func sigaltstack(new, old unsafe.Pointer)
+func sigaction(sig int32, new, old unsafe.Pointer)
+func sigprocmask(new, old unsafe.Pointer)
+func setitimer(mode int32, new, old unsafe.Pointer)
+func sysctl(mib *uint32, miblen uint32, out *byte, size *uintptr, dst *byte, ndst uintptr) int32
+func getrlimit(kind int32, limit unsafe.Pointer) int32
+func raise(sig int32)
+func sys_umtx_sleep(addr unsafe.Pointer, val, timeout int32) int32
+func sys_umtx_wakeup(addr unsafe.Pointer, val int32) int32
+
+const stackSystem = 0
diff --git a/src/runtime/os_dragonfly.h b/src/runtime/os_dragonfly.h
new file mode 100644
index 0000000..389736a
--- /dev/null
+++ b/src/runtime/os_dragonfly.h
@@ -0,0 +1,30 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+
+typedef byte* kevent_udata;
+
+int32	runtime·lwp_create(Lwpparams*);
+void	runtime·sigpanic(void);
+void	runtime·sigaltstack(SigaltstackT*, SigaltstackT*);
+struct	sigaction;
+void	runtime·sigaction(int32, struct sigaction*, struct sigaction*);
+void	runtime·sigprocmask(Sigset *, Sigset *);
+void	runtime·unblocksignals(void);
+void	runtime·setitimer(int32, Itimerval*, Itimerval*);
+int32	runtime·sysctl(uint32*, uint32, byte*, uintptr*, byte*, uintptr);
+
+enum {
+	NSIG = 33,
+	SI_USER = 0x10001,
+	SS_DISABLE = 4,
+	RLIMIT_AS = 10,
+};
+
+typedef struct Rlimit Rlimit;
+struct Rlimit {
+	int64	rlim_cur;
+	int64	rlim_max;
+};
+int32	runtime·getrlimit(int32, Rlimit*);
diff --git a/src/runtime/os_freebsd.c b/src/runtime/os_freebsd.c
new file mode 100644
index 0000000..a513cb6
--- /dev/null
+++ b/src/runtime/os_freebsd.c
@@ -0,0 +1,320 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "runtime.h"
+#include "defs_GOOS_GOARCH.h"
+#include "os_GOOS.h"
+#include "signal_unix.h"
+#include "stack.h"
+#include "textflag.h"
+
+extern SigTab runtime·sigtab[];
+extern int32 runtime·sys_umtx_op(uint32*, int32, uint32, void*, void*);
+
+// From FreeBSD's <sys/sysctl.h>
+#define	CTL_HW	6
+#define	HW_NCPU	3
+
+static Sigset sigset_none;
+static Sigset sigset_all = { ~(uint32)0, ~(uint32)0, ~(uint32)0, ~(uint32)0, };
+
+static int32
+getncpu(void)
+{
+	uint32 mib[2];
+	uint32 out;
+	int32 ret;
+	uintptr nout;
+
+	// Fetch hw.ncpu via sysctl.
+	mib[0] = CTL_HW;
+	mib[1] = HW_NCPU;
+	nout = sizeof out;
+	out = 0;
+	ret = runtime·sysctl(mib, 2, (byte*)&out, &nout, nil, 0);
+	if(ret >= 0)
+		return out;
+	else
+		return 1;
+}
+
+// FreeBSD's umtx_op syscall is effectively the same as Linux's futex, and
+// thus the code is largely similar. See linux/thread.c and lock_futex.c for comments.
+
+static void futexsleep(void);
+
+#pragma textflag NOSPLIT
+void
+runtime·futexsleep(uint32 *addr, uint32 val, int64 ns)
+{
+	void (*fn)(void);
+
+	g->m->ptrarg[0] = addr;
+	g->m->scalararg[0] = val;
+	g->m->ptrarg[1] = &ns;
+
+	fn = futexsleep;
+	runtime·onM(&fn);
+}
+
+static void
+futexsleep(void)
+{
+	uint32 *addr;
+	uint32 val;
+	int64 ns;
+	int32 ret;
+	Timespec ts;
+	
+	addr = g->m->ptrarg[0];
+	val = g->m->scalararg[0];
+	ns = *(int64*)g->m->ptrarg[1];
+	g->m->ptrarg[0] = nil;
+	g->m->scalararg[0] = 0;
+	g->m->ptrarg[1] = nil;
+
+	if(ns < 0) {
+		ret = runtime·sys_umtx_op(addr, UMTX_OP_WAIT_UINT_PRIVATE, val, nil, nil);
+		if(ret >= 0 || ret == -EINTR)
+			return;
+		goto fail;
+	}
+	// NOTE: tv_nsec is int64 on amd64, so this assumes a little-endian system.
+	ts.tv_nsec = 0;
+	ts.tv_sec = runtime·timediv(ns, 1000000000, (int32*)&ts.tv_nsec);
+	ret = runtime·sys_umtx_op(addr, UMTX_OP_WAIT_UINT_PRIVATE, val, nil, &ts);
+	if(ret >= 0 || ret == -EINTR)
+		return;
+
+fail:
+	runtime·prints("umtx_wait addr=");
+	runtime·printpointer(addr);
+	runtime·prints(" val=");
+	runtime·printint(val);
+	runtime·prints(" ret=");
+	runtime·printint(ret);
+	runtime·prints("\n");
+	*(int32*)0x1005 = 0x1005;
+}
+
+static void badfutexwakeup(void);
+
+#pragma textflag NOSPLIT
+void
+runtime·futexwakeup(uint32 *addr, uint32 cnt)
+{
+	int32 ret;
+	void (*fn)(void);
+
+	ret = runtime·sys_umtx_op(addr, UMTX_OP_WAKE_PRIVATE, cnt, nil, nil);
+	if(ret >= 0)
+		return;
+
+	g->m->ptrarg[0] = addr;
+	g->m->scalararg[0] = ret;
+	fn = badfutexwakeup;
+	if(g == g->m->gsignal)
+		fn();
+	else
+		runtime·onM(&fn);
+	*(int32*)0x1006 = 0x1006;
+}
+
+static void
+badfutexwakeup(void)
+{
+	void *addr;
+	int32 ret;
+	
+	addr = g->m->ptrarg[0];
+	ret = g->m->scalararg[0];
+	runtime·printf("umtx_wake addr=%p ret=%d\n", addr, ret);
+}
+
+void runtime·thr_start(void*);
+
+void
+runtime·newosproc(M *mp, void *stk)
+{
+	ThrParam param;
+	Sigset oset;
+
+	if(0){
+		runtime·printf("newosproc stk=%p m=%p g=%p id=%d/%d ostk=%p\n",
+			stk, mp, mp->g0, mp->id, (int32)mp->tls[0], &mp);
+	}
+
+	runtime·sigprocmask(&sigset_all, &oset);
+	runtime·memclr((byte*)&param, sizeof param);
+
+	param.start_func = runtime·thr_start;
+	param.arg = (byte*)mp;
+	
+	// NOTE(rsc): This code is confused. stackbase is the top of the stack
+	// and is equal to stk. However, it's working, so I'm not changing it.
+	param.stack_base = (void*)mp->g0->stack.hi;
+	param.stack_size = (byte*)stk - (byte*)mp->g0->stack.hi;
+
+	param.child_tid = (void*)&mp->procid;
+	param.parent_tid = nil;
+	param.tls_base = (void*)&mp->tls[0];
+	param.tls_size = sizeof mp->tls;
+
+	mp->tls[0] = mp->id;	// so 386 asm can find it
+
+	runtime·thr_new(&param, sizeof param);
+	runtime·sigprocmask(&oset, nil);
+}
+
+void
+runtime·osinit(void)
+{
+	runtime·ncpu = getncpu();
+}
+
+#pragma textflag NOSPLIT
+void
+runtime·get_random_data(byte **rnd, int32 *rnd_len)
+{
+	#pragma dataflag NOPTR
+	static byte urandom_data[HashRandomBytes];
+	int32 fd;
+	fd = runtime·open("/dev/urandom", 0 /* O_RDONLY */, 0);
+	if(runtime·read(fd, urandom_data, HashRandomBytes) == HashRandomBytes) {
+		*rnd = urandom_data;
+		*rnd_len = HashRandomBytes;
+	} else {
+		*rnd = nil;
+		*rnd_len = 0;
+	}
+	runtime·close(fd);
+}
+
+void
+runtime·goenvs(void)
+{
+	runtime·goenvs_unix();
+}
+
+// Called to initialize a new m (including the bootstrap m).
+// Called on the parent thread (main thread in case of bootstrap), can allocate memory.
+void
+runtime·mpreinit(M *mp)
+{
+	mp->gsignal = runtime·malg(32*1024);
+	mp->gsignal->m = mp;
+}
+
+// Called to initialize a new m (including the bootstrap m).
+// Called on the new thread, can not allocate memory.
+void
+runtime·minit(void)
+{
+	// Initialize signal handling
+	runtime·signalstack((byte*)g->m->gsignal->stack.lo, 32*1024);
+	runtime·sigprocmask(&sigset_none, nil);
+}
+
+// Called from dropm to undo the effect of an minit.
+void
+runtime·unminit(void)
+{
+	runtime·signalstack(nil, 0);
+}
+
+uintptr
+runtime·memlimit(void)
+{
+	Rlimit rl;
+	extern byte runtime·text[], runtime·end[];
+	uintptr used;
+	
+	if(runtime·getrlimit(RLIMIT_AS, &rl) != 0)
+		return 0;
+	if(rl.rlim_cur >= 0x7fffffff)
+		return 0;
+
+	// Estimate our VM footprint excluding the heap.
+	// Not an exact science: use size of binary plus
+	// some room for thread stacks.
+	used = runtime·end - runtime·text + (64<<20);
+	if(used >= rl.rlim_cur)
+		return 0;
+
+	// If there's not at least 16 MB left, we're probably
+	// not going to be able to do much.  Treat as no limit.
+	rl.rlim_cur -= used;
+	if(rl.rlim_cur < (16<<20))
+		return 0;
+
+	return rl.rlim_cur - used;
+}
+
+extern void runtime·sigtramp(void);
+
+typedef struct sigaction {
+	union {
+		void    (*__sa_handler)(int32);
+		void    (*__sa_sigaction)(int32, Siginfo*, void *);
+	} __sigaction_u;		/* signal handler */
+	int32	sa_flags;		/* see signal options below */
+	Sigset	sa_mask;		/* signal mask to apply */
+} SigactionT;
+
+void
+runtime·setsig(int32 i, GoSighandler *fn, bool restart)
+{
+	SigactionT sa;
+
+	runtime·memclr((byte*)&sa, sizeof sa);
+	sa.sa_flags = SA_SIGINFO|SA_ONSTACK;
+	if(restart)
+		sa.sa_flags |= SA_RESTART;
+	sa.sa_mask.__bits[0] = ~(uint32)0;
+	sa.sa_mask.__bits[1] = ~(uint32)0;
+	sa.sa_mask.__bits[2] = ~(uint32)0;
+	sa.sa_mask.__bits[3] = ~(uint32)0;
+	if(fn == runtime·sighandler)
+		fn = (void*)runtime·sigtramp;
+	sa.__sigaction_u.__sa_sigaction = (void*)fn;
+	runtime·sigaction(i, &sa, nil);
+}
+
+GoSighandler*
+runtime·getsig(int32 i)
+{
+	SigactionT sa;
+
+	runtime·memclr((byte*)&sa, sizeof sa);
+	runtime·sigaction(i, nil, &sa);
+	if((void*)sa.__sigaction_u.__sa_sigaction == runtime·sigtramp)
+		return runtime·sighandler;
+	return (void*)sa.__sigaction_u.__sa_sigaction;
+}
+
+void
+runtime·signalstack(byte *p, int32 n)
+{
+	StackT st;
+
+	st.ss_sp = (void*)p;
+	st.ss_size = n;
+	st.ss_flags = 0;
+	if(p == nil)
+		st.ss_flags = SS_DISABLE;
+	runtime·sigaltstack(&st, nil);
+}
+
+void
+runtime·unblocksignals(void)
+{
+	runtime·sigprocmask(&sigset_none, nil);
+}
+
+#pragma textflag NOSPLIT
+int8*
+runtime·signame(int32 sig)
+{
+	return runtime·sigtab[sig].name;
+}
diff --git a/src/runtime/os_freebsd.go b/src/runtime/os_freebsd.go
new file mode 100644
index 0000000..5970804
--- /dev/null
+++ b/src/runtime/os_freebsd.go
@@ -0,0 +1,17 @@
+// Copyright 2014 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package runtime
+
+import "unsafe"
+
+func thr_new(param unsafe.Pointer, size int32)
+func sigaltstack(new, old unsafe.Pointer)
+func sigaction(sig int32, new, old unsafe.Pointer)
+func sigprocmask(new, old unsafe.Pointer)
+func setitimer(mode int32, new, old unsafe.Pointer)
+func sysctl(mib *uint32, miblen uint32, out *byte, size *uintptr, dst *byte, ndst uintptr) int32
+func getrlimit(kind int32, limit unsafe.Pointer) int32
+func raise(sig int32)
+func sys_umtx_op(addr unsafe.Pointer, mode int32, val uint32, ptr2, ts unsafe.Pointer) int32
diff --git a/src/runtime/os_freebsd.h b/src/runtime/os_freebsd.h
new file mode 100644
index 0000000..b86bb39
--- /dev/null
+++ b/src/runtime/os_freebsd.h
@@ -0,0 +1,29 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+typedef byte* kevent_udata;
+
+int32	runtime·thr_new(ThrParam*, int32);
+void	runtime·sigpanic(void);
+void	runtime·sigaltstack(SigaltstackT*, SigaltstackT*);
+struct	sigaction;
+void	runtime·sigaction(int32, struct sigaction*, struct sigaction*);
+void	runtime·sigprocmask(Sigset *, Sigset *);
+void	runtime·unblocksignals(void);
+void	runtime·setitimer(int32, Itimerval*, Itimerval*);
+int32	runtime·sysctl(uint32*, uint32, byte*, uintptr*, byte*, uintptr);
+
+enum {
+	SS_DISABLE = 4,
+	NSIG = 33,
+	SI_USER = 0x10001,
+	RLIMIT_AS = 10,
+};
+
+typedef struct Rlimit Rlimit;
+struct Rlimit {
+	int64	rlim_cur;
+	int64	rlim_max;
+};
+int32	runtime·getrlimit(int32, Rlimit*);
diff --git a/src/runtime/os_freebsd_arm.c b/src/runtime/os_freebsd_arm.c
new file mode 100644
index 0000000..2f2d776
--- /dev/null
+++ b/src/runtime/os_freebsd_arm.c
@@ -0,0 +1,24 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "runtime.h"
+#include "defs_GOOS_GOARCH.h"
+#include "os_GOOS.h"
+#include "textflag.h"
+
+void
+runtime·checkgoarm(void)
+{
+	// TODO(minux)
+}
+
+#pragma textflag NOSPLIT
+int64
+runtime·cputicks(void)
+{
+	// Currently cputicks() is used in blocking profiler and to seed runtime·fastrand1().
+	// runtime·nanotime() is a poor approximation of CPU ticks that is enough for the profiler.
+	// TODO: need more entropy to better seed fastrand1.
+	return runtime·nanotime();
+}
diff --git a/src/runtime/os_linux.c b/src/runtime/os_linux.c
new file mode 100644
index 0000000..0d8ffc9
--- /dev/null
+++ b/src/runtime/os_linux.c
@@ -0,0 +1,342 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "runtime.h"
+#include "defs_GOOS_GOARCH.h"
+#include "os_GOOS.h"
+#include "signal_unix.h"
+#include "stack.h"
+#include "textflag.h"
+
+extern SigTab runtime·sigtab[];
+
+static Sigset sigset_none;
+static Sigset sigset_all = { ~(uint32)0, ~(uint32)0 };
+
+// Linux futex.
+//
+//	futexsleep(uint32 *addr, uint32 val)
+//	futexwakeup(uint32 *addr)
+//
+// Futexsleep atomically checks if *addr == val and if so, sleeps on addr.
+// Futexwakeup wakes up threads sleeping on addr.
+// Futexsleep is allowed to wake up spuriously.
+
+enum
+{
+	FUTEX_WAIT = 0,
+	FUTEX_WAKE = 1,
+};
+
+// Atomically,
+//	if(*addr == val) sleep
+// Might be woken up spuriously; that's allowed.
+// Don't sleep longer than ns; ns < 0 means forever.
+#pragma textflag NOSPLIT
+void
+runtime·futexsleep(uint32 *addr, uint32 val, int64 ns)
+{
+	Timespec ts;
+
+	// Some Linux kernels have a bug where futex of
+	// FUTEX_WAIT returns an internal error code
+	// as an errno.  Libpthread ignores the return value
+	// here, and so can we: as it says a few lines up,
+	// spurious wakeups are allowed.
+
+	if(ns < 0) {
+		runtime·futex(addr, FUTEX_WAIT, val, nil, nil, 0);
+		return;
+	}
+	// NOTE: tv_nsec is int64 on amd64, so this assumes a little-endian system.
+	ts.tv_nsec = 0;
+	ts.tv_sec = runtime·timediv(ns, 1000000000LL, (int32*)&ts.tv_nsec);
+	runtime·futex(addr, FUTEX_WAIT, val, &ts, nil, 0);
+}
+
+static void badfutexwakeup(void);
+
+// If any procs are sleeping on addr, wake up at most cnt.
+#pragma textflag NOSPLIT
+void
+runtime·futexwakeup(uint32 *addr, uint32 cnt)
+{
+	int64 ret;
+	void (*fn)(void);
+
+	ret = runtime·futex(addr, FUTEX_WAKE, cnt, nil, nil, 0);
+	if(ret >= 0)
+		return;
+
+	// I don't know that futex wakeup can return
+	// EAGAIN or EINTR, but if it does, it would be
+	// safe to loop and call futex again.
+	g->m->ptrarg[0] = addr;
+	g->m->scalararg[0] = (int32)ret; // truncated but fine
+	fn = badfutexwakeup;
+	if(g == g->m->gsignal)
+		fn();
+	else
+		runtime·onM(&fn);
+	*(int32*)0x1006 = 0x1006;
+}
+
+static void
+badfutexwakeup(void)
+{
+	void *addr;
+	int64 ret;
+	
+	addr = g->m->ptrarg[0];
+	ret = (int32)g->m->scalararg[0];
+	runtime·printf("futexwakeup addr=%p returned %D\n", addr, ret);
+}
+
+extern runtime·sched_getaffinity(uintptr pid, uintptr len, uintptr *buf);
+static int32
+getproccount(void)
+{
+	uintptr buf[16], t;
+	int32 r, cnt, i;
+
+	cnt = 0;
+	r = runtime·sched_getaffinity(0, sizeof(buf), buf);
+	if(r > 0)
+	for(i = 0; i < r/sizeof(buf[0]); i++) {
+		t = buf[i];
+		t = t - ((t >> 1) & 0x5555555555555555ULL);
+		t = (t & 0x3333333333333333ULL) + ((t >> 2) & 0x3333333333333333ULL);
+		cnt += (int32)((((t + (t >> 4)) & 0xF0F0F0F0F0F0F0FULL) * 0x101010101010101ULL) >> 56);
+	}
+
+	return cnt ? cnt : 1;
+}
+
+// Clone, the Linux rfork.
+enum
+{
+	CLONE_VM = 0x100,
+	CLONE_FS = 0x200,
+	CLONE_FILES = 0x400,
+	CLONE_SIGHAND = 0x800,
+	CLONE_PTRACE = 0x2000,
+	CLONE_VFORK = 0x4000,
+	CLONE_PARENT = 0x8000,
+	CLONE_THREAD = 0x10000,
+	CLONE_NEWNS = 0x20000,
+	CLONE_SYSVSEM = 0x40000,
+	CLONE_SETTLS = 0x80000,
+	CLONE_PARENT_SETTID = 0x100000,
+	CLONE_CHILD_CLEARTID = 0x200000,
+	CLONE_UNTRACED = 0x800000,
+	CLONE_CHILD_SETTID = 0x1000000,
+	CLONE_STOPPED = 0x2000000,
+	CLONE_NEWUTS = 0x4000000,
+	CLONE_NEWIPC = 0x8000000,
+};
+
+void
+runtime·newosproc(M *mp, void *stk)
+{
+	int32 ret;
+	int32 flags;
+	Sigset oset;
+
+	/*
+	 * note: strace gets confused if we use CLONE_PTRACE here.
+	 */
+	flags = CLONE_VM	/* share memory */
+		| CLONE_FS	/* share cwd, etc */
+		| CLONE_FILES	/* share fd table */
+		| CLONE_SIGHAND	/* share sig handler table */
+		| CLONE_THREAD	/* revisit - okay for now */
+		;
+
+	mp->tls[0] = mp->id;	// so 386 asm can find it
+	if(0){
+		runtime·printf("newosproc stk=%p m=%p g=%p clone=%p id=%d/%d ostk=%p\n",
+			stk, mp, mp->g0, runtime·clone, mp->id, (int32)mp->tls[0], &mp);
+	}
+
+	// Disable signals during clone, so that the new thread starts
+	// with signals disabled.  It will enable them in minit.
+	runtime·rtsigprocmask(SIG_SETMASK, &sigset_all, &oset, sizeof oset);
+	ret = runtime·clone(flags, stk, mp, mp->g0, runtime·mstart);
+	runtime·rtsigprocmask(SIG_SETMASK, &oset, nil, sizeof oset);
+
+	if(ret < 0) {
+		runtime·printf("runtime: failed to create new OS thread (have %d already; errno=%d)\n", runtime·mcount(), -ret);
+		runtime·throw("runtime.newosproc");
+	}
+}
+
+void
+runtime·osinit(void)
+{
+	runtime·ncpu = getproccount();
+}
+
+// Random bytes initialized at startup.  These come
+// from the ELF AT_RANDOM auxiliary vector (vdso_linux_amd64.c).
+byte*	runtime·startup_random_data;
+uint32	runtime·startup_random_data_len;
+
+#pragma textflag NOSPLIT
+void
+runtime·get_random_data(byte **rnd, int32 *rnd_len)
+{
+	if(runtime·startup_random_data != nil) {
+		*rnd = runtime·startup_random_data;
+		*rnd_len = runtime·startup_random_data_len;
+	} else {
+		#pragma dataflag NOPTR
+		static byte urandom_data[HashRandomBytes];
+		int32 fd;
+		fd = runtime·open("/dev/urandom", 0 /* O_RDONLY */, 0);
+		if(runtime·read(fd, urandom_data, HashRandomBytes) == HashRandomBytes) {
+			*rnd = urandom_data;
+			*rnd_len = HashRandomBytes;
+		} else {
+			*rnd = nil;
+			*rnd_len = 0;
+		}
+		runtime·close(fd);
+	}
+}
+
+void
+runtime·goenvs(void)
+{
+	runtime·goenvs_unix();
+}
+
+// Called to initialize a new m (including the bootstrap m).
+// Called on the parent thread (main thread in case of bootstrap), can allocate memory.
+void
+runtime·mpreinit(M *mp)
+{
+	mp->gsignal = runtime·malg(32*1024);	// OS X wants >=8K, Linux >=2K
+	mp->gsignal->m = mp;
+}
+
+// Called to initialize a new m (including the bootstrap m).
+// Called on the new thread, can not allocate memory.
+void
+runtime·minit(void)
+{
+	// Initialize signal handling.
+	runtime·signalstack((byte*)g->m->gsignal->stack.lo, 32*1024);
+	runtime·rtsigprocmask(SIG_SETMASK, &sigset_none, nil, sizeof(Sigset));
+}
+
+// Called from dropm to undo the effect of an minit.
+void
+runtime·unminit(void)
+{
+	runtime·signalstack(nil, 0);
+}
+
+uintptr
+runtime·memlimit(void)
+{
+	Rlimit rl;
+	extern byte runtime·text[], runtime·end[];
+	uintptr used;
+
+	if(runtime·getrlimit(RLIMIT_AS, &rl) != 0)
+		return 0;
+	if(rl.rlim_cur >= 0x7fffffff)
+		return 0;
+
+	// Estimate our VM footprint excluding the heap.
+	// Not an exact science: use size of binary plus
+	// some room for thread stacks.
+	used = runtime·end - runtime·text + (64<<20);
+	if(used >= rl.rlim_cur)
+		return 0;
+
+	// If there's not at least 16 MB left, we're probably
+	// not going to be able to do much.  Treat as no limit.
+	rl.rlim_cur -= used;
+	if(rl.rlim_cur < (16<<20))
+		return 0;
+
+	return rl.rlim_cur - used;
+}
+
+#ifdef GOARCH_386
+#define sa_handler k_sa_handler
+#endif
+
+/*
+ * This assembler routine takes the args from registers, puts them on the stack,
+ * and calls sighandler().
+ */
+extern void runtime·sigtramp(void);
+extern void runtime·sigreturn(void);	// calls rt_sigreturn, only used with SA_RESTORER
+
+void
+runtime·setsig(int32 i, GoSighandler *fn, bool restart)
+{
+	SigactionT sa;
+
+	runtime·memclr((byte*)&sa, sizeof sa);
+	sa.sa_flags = SA_ONSTACK | SA_SIGINFO | SA_RESTORER;
+	if(restart)
+		sa.sa_flags |= SA_RESTART;
+	sa.sa_mask = ~0ULL;
+	// Although Linux manpage says "sa_restorer element is obsolete and
+	// should not be used". x86_64 kernel requires it. Only use it on
+	// x86.
+#ifdef GOARCH_386
+	sa.sa_restorer = (void*)runtime·sigreturn;
+#endif
+#ifdef GOARCH_amd64
+	sa.sa_restorer = (void*)runtime·sigreturn;
+#endif
+	if(fn == runtime·sighandler)
+		fn = (void*)runtime·sigtramp;
+	sa.sa_handler = fn;
+	if(runtime·rt_sigaction(i, &sa, nil, sizeof(sa.sa_mask)) != 0)
+		runtime·throw("rt_sigaction failure");
+}
+
+GoSighandler*
+runtime·getsig(int32 i)
+{
+	SigactionT sa;
+
+	runtime·memclr((byte*)&sa, sizeof sa);
+	if(runtime·rt_sigaction(i, nil, &sa, sizeof(sa.sa_mask)) != 0)
+		runtime·throw("rt_sigaction read failure");
+	if((void*)sa.sa_handler == runtime·sigtramp)
+		return runtime·sighandler;
+	return (void*)sa.sa_handler;
+}
+
+void
+runtime·signalstack(byte *p, int32 n)
+{
+	SigaltstackT st;
+
+	st.ss_sp = p;
+	st.ss_size = n;
+	st.ss_flags = 0;
+	if(p == nil)
+		st.ss_flags = SS_DISABLE;
+	runtime·sigaltstack(&st, nil);
+}
+
+void
+runtime·unblocksignals(void)
+{
+	runtime·rtsigprocmask(SIG_SETMASK, &sigset_none, nil, sizeof sigset_none);
+}
+
+#pragma textflag NOSPLIT
+int8*
+runtime·signame(int32 sig)
+{
+	return runtime·sigtab[sig].name;
+}
diff --git a/src/runtime/os_linux.go b/src/runtime/os_linux.go
new file mode 100644
index 0000000..41123ad
--- /dev/null
+++ b/src/runtime/os_linux.go
@@ -0,0 +1,17 @@
+// Copyright 2014 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package runtime
+
+import "unsafe"
+
+func futex(addr unsafe.Pointer, op int32, val uint32, ts, addr2 unsafe.Pointer, val3 uint32) int32
+func clone(flags int32, stk, mm, gg, fn unsafe.Pointer) int32
+func rt_sigaction(sig uintptr, new, old unsafe.Pointer, size uintptr) int32
+func sigaltstack(new, old unsafe.Pointer)
+func setitimer(mode int32, new, old unsafe.Pointer)
+func rtsigprocmask(sig int32, new, old unsafe.Pointer, size int32)
+func getrlimit(kind int32, limit unsafe.Pointer) int32
+func raise(sig int32)
+func sched_getaffinity(pid, len uintptr, buf *uintptr) int32
diff --git a/src/runtime/os_linux.h b/src/runtime/os_linux.h
new file mode 100644
index 0000000..75606d6
--- /dev/null
+++ b/src/runtime/os_linux.h
@@ -0,0 +1,41 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+
+// Linux-specific system calls
+int32	runtime·futex(uint32*, int32, uint32, Timespec*, uint32*, uint32);
+int32	runtime·clone(int32, void*, M*, G*, void(*)(void));
+
+struct SigactionT;
+int32	runtime·rt_sigaction(uintptr, struct SigactionT*, void*, uintptr);
+
+void	runtime·sigaltstack(SigaltstackT*, SigaltstackT*);
+void	runtime·sigpanic(void);
+void runtime·setitimer(int32, Itimerval*, Itimerval*);
+
+enum {
+	SS_DISABLE = 2,
+	NSIG = 65,
+	SI_USER = 0,
+	SIG_SETMASK = 2,
+	RLIMIT_AS = 9,
+};
+
+// It's hard to tease out exactly how big a Sigset is, but
+// rt_sigprocmask crashes if we get it wrong, so if binaries
+// are running, this is right.
+typedef struct Sigset Sigset;
+struct Sigset
+{
+	uint32 mask[2];
+};
+void	runtime·rtsigprocmask(int32, Sigset*, Sigset*, int32);
+void	runtime·unblocksignals(void);
+
+typedef struct Rlimit Rlimit;
+struct Rlimit {
+	uintptr	rlim_cur;
+	uintptr	rlim_max;
+};
+int32	runtime·getrlimit(int32, Rlimit*);
diff --git a/src/runtime/os_linux_386.c b/src/runtime/os_linux_386.c
new file mode 100644
index 0000000..dc89d04
--- /dev/null
+++ b/src/runtime/os_linux_386.c
@@ -0,0 +1,38 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "runtime.h"
+#include "defs_GOOS_GOARCH.h"
+#include "os_GOOS.h"
+#include "textflag.h"
+
+#define AT_NULL		0
+#define AT_RANDOM	25
+#define AT_SYSINFO	32
+extern uint32 runtime·_vdso;
+
+#pragma textflag NOSPLIT
+void
+runtime·linux_setup_vdso(int32 argc, byte **argv)
+{
+	byte **envp;
+	uint32 *auxv;
+
+	// skip envp to get to ELF auxiliary vector.
+	for(envp = &argv[argc+1]; *envp != nil; envp++)
+		;
+	envp++;
+	
+	for(auxv=(uint32*)envp; auxv[0] != AT_NULL; auxv += 2) {
+		if(auxv[0] == AT_SYSINFO) {
+			runtime·_vdso = auxv[1];
+			continue;
+		}
+		if(auxv[0] == AT_RANDOM) {
+			runtime·startup_random_data = (byte*)auxv[1];
+			runtime·startup_random_data_len = 16;
+			continue;
+		}
+	}
+}
diff --git a/src/runtime/os_linux_arm.c b/src/runtime/os_linux_arm.c
new file mode 100644
index 0000000..e3eda7c
--- /dev/null
+++ b/src/runtime/os_linux_arm.c
@@ -0,0 +1,80 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "runtime.h"
+#include "defs_GOOS_GOARCH.h"
+#include "os_GOOS.h"
+#include "textflag.h"
+
+#define AT_NULL		0
+#define AT_PLATFORM	15 // introduced in at least 2.6.11
+#define AT_HWCAP	16 // introduced in at least 2.6.11
+#define AT_RANDOM	25 // introduced in 2.6.29
+#define HWCAP_VFP	(1 << 6) // introduced in at least 2.6.11
+#define HWCAP_VFPv3	(1 << 13) // introduced in 2.6.30
+static uint32 runtime·randomNumber;
+uint8  runtime·armArch = 6;	// we default to ARMv6
+uint32 runtime·hwcap;	// set by setup_auxv
+extern uint8  runtime·goarm;	// set by 5l
+
+void
+runtime·checkgoarm(void)
+{
+	if(runtime·goarm > 5 && !(runtime·hwcap & HWCAP_VFP)) {
+		runtime·printf("runtime: this CPU has no floating point hardware, so it cannot run\n");
+		runtime·printf("this GOARM=%d binary. Recompile using GOARM=5.\n", runtime·goarm);
+		runtime·exit(1);
+	}
+	if(runtime·goarm > 6 && !(runtime·hwcap & HWCAP_VFPv3)) {
+		runtime·printf("runtime: this CPU has no VFPv3 floating point hardware, so it cannot run\n");
+		runtime·printf("this GOARM=%d binary. Recompile using GOARM=6.\n", runtime·goarm);
+		runtime·exit(1);
+	}
+}
+
+#pragma textflag NOSPLIT
+void
+runtime·setup_auxv(int32 argc, byte **argv)
+{
+	byte **envp;
+	byte *rnd;
+	uint32 *auxv;
+	uint32 t;
+
+	// skip envp to get to ELF auxiliary vector.
+	for(envp = &argv[argc+1]; *envp != nil; envp++)
+		;
+	envp++;
+	
+	for(auxv=(uint32*)envp; auxv[0] != AT_NULL; auxv += 2) {
+		switch(auxv[0]) {
+		case AT_RANDOM: // kernel provided 16-byte worth of random data
+			if(auxv[1]) {
+				rnd = (byte*)auxv[1];
+				runtime·randomNumber = rnd[4] | rnd[5]<<8 | rnd[6]<<16 | rnd[7]<<24;
+			}
+			break;
+		case AT_PLATFORM: // v5l, v6l, v7l
+			if(auxv[1]) {
+				t = *(uint8*)(auxv[1]+1);
+				if(t >= '5' && t <= '7')
+					runtime·armArch = t - '0';
+			}
+			break;
+		case AT_HWCAP: // CPU capability bit flags
+			runtime·hwcap = auxv[1];
+			break;
+		}
+	}
+}
+
+#pragma textflag NOSPLIT
+int64
+runtime·cputicks(void)
+{
+	// Currently cputicks() is used in blocking profiler and to seed runtime·fastrand1().
+	// runtime·nanotime() is a poor approximation of CPU ticks that is enough for the profiler.
+	// runtime·randomNumber provides better seeding of fastrand1.
+	return runtime·nanotime() + runtime·randomNumber;
+}
diff --git a/src/runtime/os_nacl.c b/src/runtime/os_nacl.c
new file mode 100644
index 0000000..14b5583
--- /dev/null
+++ b/src/runtime/os_nacl.c
@@ -0,0 +1,312 @@
+// Copyright 2010 The Go 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 "runtime.h"
+#include "defs_GOOS_GOARCH.h"
+#include "os_GOOS.h"
+#include "arch_GOARCH.h"
+#include "textflag.h"
+#include "stack.h"
+
+int8 *goos = "nacl";
+extern SigTab runtime·sigtab[];
+
+void runtime·sigtramp(void);
+
+// Called to initialize a new m (including the bootstrap m).
+// Called on the parent thread (main thread in case of bootstrap), can allocate memory.
+void
+runtime·mpreinit(M *mp)
+{
+	mp->gsignal = runtime·malg(32*1024);	// OS X wants >=8K, Linux >=2K
+	mp->gsignal->m = mp;
+}
+
+// Called to initialize a new m (including the bootstrap m).
+// Called on the new thread, can not allocate memory.
+void
+runtime·minit(void)
+{
+	int32 ret;
+
+	// Initialize signal handling
+	ret = runtime·nacl_exception_stack((byte*)g->m->gsignal->stack.lo, 32*1024);
+	if(ret < 0)
+		runtime·printf("runtime: nacl_exception_stack: error %d\n", -ret);
+
+	ret = runtime·nacl_exception_handler(runtime·sigtramp, nil);
+	if(ret < 0)
+		runtime·printf("runtime: nacl_exception_handler: error %d\n", -ret);
+}
+
+// Called from dropm to undo the effect of an minit.
+void
+runtime·unminit(void)
+{
+}
+
+int8 runtime·sigtrampf[] = "runtime: signal at PC=%X AX=%X CX=%X DX=%X BX=%X DI=%X R15=%X *SP=%X\n";
+int8 runtime·sigtrampp[] = "runtime: sigtramp";
+
+extern byte runtime·tls0[];
+
+void
+runtime·osinit(void)
+{
+	runtime·ncpu = 1;
+	g->m->procid = 2;
+//runtime·nacl_exception_handler(runtime·sigtramp, nil);
+}
+
+void
+runtime·crash(void)
+{
+	*(int32*)0 = 0;
+}
+
+#pragma textflag NOSPLIT
+void
+runtime·get_random_data(byte **rnd, int32 *rnd_len)
+{
+	*rnd = nil;
+	*rnd_len = 0;
+}
+
+void
+runtime·goenvs(void)
+{
+	runtime·goenvs_unix();
+}
+
+void
+runtime·initsig(void)
+{
+}
+
+#pragma textflag NOSPLIT
+void
+runtime·usleep(uint32 us)
+{
+	Timespec ts;
+	
+	ts.tv_sec = us/1000000;
+	ts.tv_nsec = (us%1000000)*1000;
+	runtime·nacl_nanosleep(&ts, nil);
+}
+
+void runtime·mstart_nacl(void);
+
+void
+runtime·newosproc(M *mp, void *stk)
+{
+	int32 ret;
+	void **tls;
+
+	tls = (void**)mp->tls;
+	tls[0] = mp->g0;
+	tls[1] = mp;
+	ret = runtime·nacl_thread_create(runtime·mstart_nacl, stk, tls+2, 0);
+	if(ret < 0) {
+		runtime·printf("nacl_thread_create: error %d\n", -ret);
+		runtime·throw("newosproc");
+	}
+}
+
+static void
+semacreate(void)
+{
+	int32 mu, cond;
+	
+	mu = runtime·nacl_mutex_create(0);
+	if(mu < 0) {
+		runtime·printf("nacl_mutex_create: error %d\n", -mu);
+		runtime·throw("semacreate");
+	}
+	cond = runtime·nacl_cond_create(0);
+	if(cond < 0) {
+		runtime·printf("nacl_cond_create: error %d\n", -cond);
+		runtime·throw("semacreate");
+	}
+	g->m->waitsemalock = mu;
+	g->m->scalararg[0] = cond; // assigned to m->waitsema
+}
+
+#pragma textflag NOSPLIT
+uint32
+runtime·semacreate(void)
+{
+	void (*fn)(void);
+	uint32 x;
+	
+	fn = semacreate;
+	runtime·onM(&fn);
+	x = g->m->scalararg[0];
+	g->m->scalararg[0] = 0;
+	return x;
+}
+
+static void
+semasleep(void)
+{
+	int32 ret;
+	int64 ns;
+	
+	ns = (int64)(uint32)g->m->scalararg[0] | (int64)(uint32)g->m->scalararg[1]<<32;
+	g->m->scalararg[0] = 0;
+	g->m->scalararg[1] = 0;
+	
+	ret = runtime·nacl_mutex_lock(g->m->waitsemalock);
+	if(ret < 0) {
+		//runtime·printf("nacl_mutex_lock: error %d\n", -ret);
+		runtime·throw("semasleep");
+	}
+	if(g->m->waitsemacount > 0) {
+		g->m->waitsemacount = 0;
+		runtime·nacl_mutex_unlock(g->m->waitsemalock);
+		g->m->scalararg[0] = 0;
+		return;
+	}
+
+	while(g->m->waitsemacount == 0) {
+		if(ns < 0) {
+			ret = runtime·nacl_cond_wait(g->m->waitsema, g->m->waitsemalock);
+			if(ret < 0) {
+				//runtime·printf("nacl_cond_wait: error %d\n", -ret);
+				runtime·throw("semasleep");
+			}
+		} else {
+			Timespec ts;
+			
+			ns += runtime·nanotime();
+			ts.tv_sec = runtime·timediv(ns, 1000000000, (int32*)&ts.tv_nsec);
+			ret = runtime·nacl_cond_timed_wait_abs(g->m->waitsema, g->m->waitsemalock, &ts);
+			if(ret == -ETIMEDOUT) {
+				runtime·nacl_mutex_unlock(g->m->waitsemalock);
+				g->m->scalararg[0] = -1;
+				return;
+			}
+			if(ret < 0) {
+				//runtime·printf("nacl_cond_timed_wait_abs: error %d\n", -ret);
+				runtime·throw("semasleep");
+			}
+		}
+	}
+			
+	g->m->waitsemacount = 0;
+	runtime·nacl_mutex_unlock(g->m->waitsemalock);
+	g->m->scalararg[0] = 0;
+}
+
+#pragma textflag NOSPLIT
+int32
+runtime·semasleep(int64 ns)
+{
+	int32 r;
+	void (*fn)(void);
+
+	g->m->scalararg[0] = (uint32)ns;
+	g->m->scalararg[1] = (uint32)(ns>>32);
+	fn = semasleep;
+	runtime·onM(&fn);
+	r = g->m->scalararg[0];
+	g->m->scalararg[0] = 0;
+	return r;
+}
+
+static void
+semawakeup(void)
+{
+	int32 ret;
+	M *mp;
+	
+	mp = g->m->ptrarg[0];
+	g->m->ptrarg[0] = nil;
+
+	ret = runtime·nacl_mutex_lock(mp->waitsemalock);
+	if(ret < 0) {
+		//runtime·printf("nacl_mutex_lock: error %d\n", -ret);
+		runtime·throw("semawakeup");
+	}
+	if(mp->waitsemacount != 0) {
+		//runtime·printf("semawakeup: double wakeup\n");
+		runtime·throw("semawakeup");
+	}
+	mp->waitsemacount = 1;
+	runtime·nacl_cond_signal(mp->waitsema);
+	runtime·nacl_mutex_unlock(mp->waitsemalock);
+}
+
+#pragma textflag NOSPLIT
+void
+runtime·semawakeup(M *mp)
+{
+	void (*fn)(void);
+
+	g->m->ptrarg[0] = mp;
+	fn = semawakeup;
+	runtime·onM(&fn);
+}
+
+uintptr
+runtime·memlimit(void)
+{
+	runtime·printf("memlimit\n");
+	return 0;
+}
+
+#pragma dataflag NOPTR
+static int8 badsignal[] = "runtime: signal received on thread not created by Go.\n";
+
+// This runs on a foreign stack, without an m or a g.  No stack split.
+#pragma textflag NOSPLIT
+void
+runtime·badsignal2(void)
+{
+	runtime·write(2, badsignal, sizeof badsignal - 1);
+	runtime·exit(2);
+}
+
+void	runtime·madvise(byte*, uintptr, int32) { }
+void runtime·munmap(byte*, uintptr) {}
+
+void
+runtime·resetcpuprofiler(int32 hz)
+{
+	USED(hz);
+}
+
+void
+runtime·sigdisable(uint32)
+{
+}
+
+void
+runtime·sigenable(uint32)
+{
+}
+
+void
+runtime·closeonexec(int32)
+{
+}
+
+uint32 runtime·writelock; // test-and-set spin lock for runtime.write
+
+/*
+An attempt at IRT. Doesn't work. See end of sys_nacl_amd64.s.
+
+void (*runtime·nacl_irt_query)(void);
+
+int8 runtime·nacl_irt_basic_v0_1_str[] = "nacl-irt-basic-0.1";
+void *runtime·nacl_irt_basic_v0_1[6]; // exit, gettod, clock, nanosleep, sched_yield, sysconf
+int32 runtime·nacl_irt_basic_v0_1_size = sizeof(runtime·nacl_irt_basic_v0_1);
+
+int8 runtime·nacl_irt_memory_v0_3_str[] = "nacl-irt-memory-0.3";
+void *runtime·nacl_irt_memory_v0_3[3]; // mmap, munmap, mprotect
+int32 runtime·nacl_irt_memory_v0_3_size = sizeof(runtime·nacl_irt_memory_v0_3);
+
+int8 runtime·nacl_irt_thread_v0_1_str[] = "nacl-irt-thread-0.1";
+void *runtime·nacl_irt_thread_v0_1[3]; // thread_create, thread_exit, thread_nice
+int32 runtime·nacl_irt_thread_v0_1_size = sizeof(runtime·nacl_irt_thread_v0_1);
+*/
diff --git a/src/runtime/os_nacl.go b/src/runtime/os_nacl.go
new file mode 100644
index 0000000..8dd43ff
--- /dev/null
+++ b/src/runtime/os_nacl.go
@@ -0,0 +1,39 @@
+// 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 runtime
+
+import "unsafe"
+
+func nacl_exception_stack(p unsafe.Pointer, size int32) int32
+func nacl_exception_handler(fn, arg unsafe.Pointer) int32
+func nacl_sem_create(flag int32) int32
+func nacl_sem_wait(sem int32) int32
+func nacl_sem_post(sem int32) int32
+func nacl_mutex_create(flag int32) int32
+func nacl_mutex_lock(mutex int32) int32
+func nacl_mutex_trylock(mutex int32) int32
+func nacl_mutex_unlock(mutex int32) int32
+func nacl_cond_create(flag int32) int32
+func nacl_cond_wait(cond, n int32) int32
+func nacl_cond_signal(cond int32) int32
+func nacl_cond_broadcast(cond int32) int32
+func nacl_cond_timed_wait_abs(cond, lock int32, ts unsafe.Pointer) int32
+func nacl_thread_create(fn, stk, tls, xx unsafe.Pointer) int32
+func nacl_nanosleep(ts, extra unsafe.Pointer) int32
+
+func os_sigpipe() {
+	gothrow("too many writes on closed pipe")
+}
+
+func sigpanic() {
+	g := getg()
+	if !canpanic(g) {
+		gothrow("unexpected signal during runtime execution")
+	}
+
+	// Native Client only invokes the exception handler for memory faults.
+	g.sig = _SIGSEGV
+	panicmem()
+}
diff --git a/src/pkg/runtime/os_nacl.h b/src/runtime/os_nacl.h
similarity index 100%
rename from src/pkg/runtime/os_nacl.h
rename to src/runtime/os_nacl.h
diff --git a/src/runtime/os_nacl_arm.c b/src/runtime/os_nacl_arm.c
new file mode 100644
index 0000000..1248ea6
--- /dev/null
+++ b/src/runtime/os_nacl_arm.c
@@ -0,0 +1,24 @@
+// 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 "runtime.h"
+#include "defs_GOOS_GOARCH.h"
+#include "os_GOOS.h"
+#include "textflag.h"
+
+void
+runtime·checkgoarm(void)
+{
+	return; // NaCl/ARM only supports ARMv7
+}
+
+#pragma textflag NOSPLIT
+int64
+runtime·cputicks(void)
+{
+	// Currently cputicks() is used in blocking profiler and to seed runtime·fastrand1().
+	// runtime·nanotime() is a poor approximation of CPU ticks that is enough for the profiler.
+	// TODO: need more entropy to better seed fastrand1.
+	return runtime·nanotime();
+}
diff --git a/src/runtime/os_netbsd.c b/src/runtime/os_netbsd.c
new file mode 100644
index 0000000..58e5bed
--- /dev/null
+++ b/src/runtime/os_netbsd.c
@@ -0,0 +1,368 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "runtime.h"
+#include "defs_GOOS_GOARCH.h"
+#include "os_GOOS.h"
+#include "signal_unix.h"
+#include "stack.h"
+#include "textflag.h"
+
+enum
+{
+	ESRCH = 3,
+	ENOTSUP = 91,
+
+	// From NetBSD's <sys/time.h>
+	CLOCK_REALTIME = 0,
+	CLOCK_VIRTUAL = 1,
+	CLOCK_PROF = 2,
+	CLOCK_MONOTONIC = 3
+};
+
+extern SigTab runtime·sigtab[];
+
+static Sigset sigset_none;
+static Sigset sigset_all = { ~(uint32)0, ~(uint32)0, ~(uint32)0, ~(uint32)0, };
+
+extern void runtime·getcontext(UcontextT *context);
+extern int32 runtime·lwp_create(UcontextT *context, uintptr flags, void *lwpid);
+extern void runtime·lwp_mcontext_init(void *mc, void *stack, M *mp, G *gp, void (*fn)(void));
+extern int32 runtime·lwp_park(Timespec *abstime, int32 unpark, void *hint, void *unparkhint);
+extern int32 runtime·lwp_unpark(int32 lwp, void *hint);
+extern int32 runtime·lwp_self(void);
+
+// From NetBSD's <sys/sysctl.h>
+#define	CTL_HW	6
+#define	HW_NCPU	3
+
+static int32
+getncpu(void)
+{
+	uint32 mib[2];
+	uint32 out;
+	int32 ret;
+	uintptr nout;
+
+	// Fetch hw.ncpu via sysctl.
+	mib[0] = CTL_HW;
+	mib[1] = HW_NCPU;
+	nout = sizeof out;
+	out = 0;
+	ret = runtime·sysctl(mib, 2, (byte*)&out, &nout, nil, 0);
+	if(ret >= 0)
+		return out;
+	else
+		return 1;
+}
+
+#pragma textflag NOSPLIT
+uintptr
+runtime·semacreate(void)
+{
+	return 1;
+}
+
+static void
+semasleep(void)
+{
+	int64 ns;
+	Timespec ts;
+
+	ns = (int64)(uint32)g->m->scalararg[0] | (int64)(uint32)g->m->scalararg[1]<<32;
+	g->m->scalararg[0] = 0;
+	g->m->scalararg[1] = 0;
+
+	// spin-mutex lock
+	while(runtime·xchg(&g->m->waitsemalock, 1))
+		runtime·osyield();
+
+	for(;;) {
+		// lock held
+		if(g->m->waitsemacount == 0) {
+			// sleep until semaphore != 0 or timeout.
+			// thrsleep unlocks m->waitsemalock.
+			if(ns < 0) {
+				// TODO(jsing) - potential deadlock!
+				//
+				// There is a potential deadlock here since we
+				// have to release the waitsemalock mutex
+				// before we call lwp_park() to suspend the
+				// thread. This allows another thread to
+				// release the lock and call lwp_unpark()
+				// before the thread is actually suspended.
+				// If this occurs the current thread will end
+				// up sleeping indefinitely. Unfortunately
+				// the NetBSD kernel does not appear to provide
+				// a mechanism for unlocking the userspace
+				// mutex once the thread is actually parked.
+				runtime·atomicstore(&g->m->waitsemalock, 0);
+				runtime·lwp_park(nil, 0, &g->m->waitsemacount, nil);
+			} else {
+				ns = ns + runtime·nanotime();
+				// NOTE: tv_nsec is int64 on amd64, so this assumes a little-endian system.
+				ts.tv_nsec = 0;
+				ts.tv_sec = runtime·timediv(ns, 1000000000, (int32*)&ts.tv_nsec);
+				// TODO(jsing) - potential deadlock!
+				// See above for details.
+				runtime·atomicstore(&g->m->waitsemalock, 0);
+				runtime·lwp_park(&ts, 0, &g->m->waitsemacount, nil);
+			}
+			// reacquire lock
+			while(runtime·xchg(&g->m->waitsemalock, 1))
+				runtime·osyield();
+		}
+
+		// lock held (again)
+		if(g->m->waitsemacount != 0) {
+			// semaphore is available.
+			g->m->waitsemacount--;
+			// spin-mutex unlock
+			runtime·atomicstore(&g->m->waitsemalock, 0);
+			g->m->scalararg[0] = 0; // semaphore acquired
+			return;
+		}
+
+		// semaphore not available.
+		// if there is a timeout, stop now.
+		// otherwise keep trying.
+		if(ns >= 0)
+			break;
+	}
+
+	// lock held but giving up
+	// spin-mutex unlock
+	runtime·atomicstore(&g->m->waitsemalock, 0);
+	g->m->scalararg[0] = -1;
+	return;
+}
+
+#pragma textflag NOSPLIT
+int32
+runtime·semasleep(int64 ns)
+{
+	int32 r;
+	void (*fn)(void);
+
+	g->m->scalararg[0] = (uint32)ns;
+	g->m->scalararg[1] = (uint32)(ns>>32);
+	fn = semasleep;
+	runtime·onM(&fn);
+	r = g->m->scalararg[0];
+	g->m->scalararg[0] = 0;
+	return r;
+}
+
+static void badsemawakeup(void);
+
+#pragma textflag NOSPLIT
+void
+runtime·semawakeup(M *mp)
+{
+	uint32 ret;
+	void (*fn)(void);
+	void *oldptr;
+	uintptr oldscalar;
+
+	// spin-mutex lock
+	while(runtime·xchg(&mp->waitsemalock, 1))
+		runtime·osyield();
+	mp->waitsemacount++;
+	// TODO(jsing) - potential deadlock, see semasleep() for details.
+	// Confirm that LWP is parked before unparking...
+	ret = runtime·lwp_unpark(mp->procid, &mp->waitsemacount);
+	if(ret != 0 && ret != ESRCH) {
+		// semawakeup can be called on signal stack.
+		// Save old ptrarg/scalararg so we can restore them.
+		oldptr = g->m->ptrarg[0];
+		oldscalar = g->m->scalararg[0];
+		g->m->ptrarg[0] = mp;
+		g->m->scalararg[0] = ret;
+		fn = badsemawakeup;
+		if(g == g->m->gsignal)
+			fn();
+		else
+			runtime·onM(&fn);
+		g->m->ptrarg[0] = oldptr;
+		g->m->scalararg[0] = oldscalar;
+	}
+	// spin-mutex unlock
+	runtime·atomicstore(&mp->waitsemalock, 0);
+}
+
+static void
+badsemawakeup(void)
+{
+	M *mp;
+	int32 ret;
+
+	mp = g->m->ptrarg[0];
+	g->m->ptrarg[0] = nil;
+	ret = g->m->scalararg[0];
+	g->m->scalararg[0] = 0;
+
+	runtime·printf("thrwakeup addr=%p sem=%d ret=%d\n", &mp->waitsemacount, mp->waitsemacount, ret);
+}
+
+void
+runtime·newosproc(M *mp, void *stk)
+{
+	UcontextT uc;
+	int32 ret;
+
+	if(0) {
+		runtime·printf(
+			"newosproc stk=%p m=%p g=%p id=%d/%d ostk=%p\n",
+			stk, mp, mp->g0, mp->id, (int32)mp->tls[0], &mp);
+	}
+
+	mp->tls[0] = mp->id;	// so 386 asm can find it
+
+	runtime·getcontext(&uc);
+	
+	uc.uc_flags = _UC_SIGMASK | _UC_CPU;
+	uc.uc_link = nil;
+	uc.uc_sigmask = sigset_all;
+
+	runtime·lwp_mcontext_init(&uc.uc_mcontext, stk, mp, mp->g0, runtime·mstart);
+
+	ret = runtime·lwp_create(&uc, 0, &mp->procid);
+
+	if(ret < 0) {
+		runtime·printf("runtime: failed to create new OS thread (have %d already; errno=%d)\n", runtime·mcount() - 1, -ret);
+		runtime·throw("runtime.newosproc");
+	}
+}
+
+void
+runtime·osinit(void)
+{
+	runtime·ncpu = getncpu();
+}
+
+#pragma textflag NOSPLIT
+void
+runtime·get_random_data(byte **rnd, int32 *rnd_len)
+{
+	#pragma dataflag NOPTR
+	static byte urandom_data[HashRandomBytes];
+	int32 fd;
+	fd = runtime·open("/dev/urandom", 0 /* O_RDONLY */, 0);
+	if(runtime·read(fd, urandom_data, HashRandomBytes) == HashRandomBytes) {
+		*rnd = urandom_data;
+		*rnd_len = HashRandomBytes;
+	} else {
+		*rnd = nil;
+		*rnd_len = 0;
+	}
+	runtime·close(fd);
+}
+
+void
+runtime·goenvs(void)
+{
+	runtime·goenvs_unix();
+}
+
+// Called to initialize a new m (including the bootstrap m).
+// Called on the parent thread (main thread in case of bootstrap), can allocate memory.
+void
+runtime·mpreinit(M *mp)
+{
+	mp->gsignal = runtime·malg(32*1024);
+	mp->gsignal->m = mp;
+}
+
+// Called to initialize a new m (including the bootstrap m).
+// Called on the new thread, can not allocate memory.
+void
+runtime·minit(void)
+{
+	g->m->procid = runtime·lwp_self();
+
+	// Initialize signal handling
+	runtime·signalstack((byte*)g->m->gsignal->stack.lo, 32*1024);
+	runtime·sigprocmask(SIG_SETMASK, &sigset_none, nil);
+}
+
+// Called from dropm to undo the effect of an minit.
+void
+runtime·unminit(void)
+{
+	runtime·signalstack(nil, 0);
+}
+
+uintptr
+runtime·memlimit(void)
+{
+	return 0;
+}
+
+extern void runtime·sigtramp(void);
+
+typedef struct sigaction {
+	union {
+		void    (*_sa_handler)(int32);
+		void    (*_sa_sigaction)(int32, Siginfo*, void *);
+	} _sa_u;			/* signal handler */
+	uint32	sa_mask[4];		/* signal mask to apply */
+	int32	sa_flags;		/* see signal options below */
+} SigactionT;
+
+void
+runtime·setsig(int32 i, GoSighandler *fn, bool restart)
+{
+	SigactionT sa;
+
+	runtime·memclr((byte*)&sa, sizeof sa);
+	sa.sa_flags = SA_SIGINFO|SA_ONSTACK;
+	if(restart)
+		sa.sa_flags |= SA_RESTART;
+	sa.sa_mask[0] = ~0U;
+	sa.sa_mask[1] = ~0U;
+	sa.sa_mask[2] = ~0U;
+	sa.sa_mask[3] = ~0U;
+	if (fn == runtime·sighandler)
+		fn = (void*)runtime·sigtramp;
+	sa._sa_u._sa_sigaction = (void*)fn;
+	runtime·sigaction(i, &sa, nil);
+}
+
+GoSighandler*
+runtime·getsig(int32 i)
+{
+	SigactionT sa;
+
+	runtime·memclr((byte*)&sa, sizeof sa);
+	runtime·sigaction(i, nil, &sa);
+	if((void*)sa._sa_u._sa_sigaction == runtime·sigtramp)
+		return runtime·sighandler;
+	return (void*)sa._sa_u._sa_sigaction;
+}
+
+void
+runtime·signalstack(byte *p, int32 n)
+{
+	StackT st;
+
+	st.ss_sp = (void*)p;
+	st.ss_size = n;
+	st.ss_flags = 0;
+	if(p == nil)
+		st.ss_flags = SS_DISABLE;
+	runtime·sigaltstack(&st, nil);
+}
+
+void
+runtime·unblocksignals(void)
+{
+	runtime·sigprocmask(SIG_SETMASK, &sigset_none, nil);
+}
+
+#pragma textflag NOSPLIT
+int8*
+runtime·signame(int32 sig)
+{
+	return runtime·sigtab[sig].name;
+}
diff --git a/src/runtime/os_netbsd.go b/src/runtime/os_netbsd.go
new file mode 100644
index 0000000..f000c5e
--- /dev/null
+++ b/src/runtime/os_netbsd.go
@@ -0,0 +1,20 @@
+// 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 runtime
+
+import "unsafe"
+
+func setitimer(mode int32, new, old unsafe.Pointer)
+func sigaction(sig int32, new, old unsafe.Pointer)
+func sigaltstack(new, old unsafe.Pointer)
+func sigprocmask(mode int32, new, old unsafe.Pointer)
+func sysctl(mib *uint32, miblen uint32, out *byte, size *uintptr, dst *byte, ndst uintptr) int32
+func lwp_tramp()
+func raise(sig int32)
+func getcontext(ctxt unsafe.Pointer)
+func lwp_create(ctxt unsafe.Pointer, flags uintptr, lwpid unsafe.Pointer) int32
+func lwp_park(abstime unsafe.Pointer, unpark int32, hint, unparkhint unsafe.Pointer) int32
+func lwp_unpark(lwp int32, hint unsafe.Pointer) int32
+func lwp_self() int32
diff --git a/src/runtime/os_netbsd.h b/src/runtime/os_netbsd.h
new file mode 100644
index 0000000..f95db32
--- /dev/null
+++ b/src/runtime/os_netbsd.h
@@ -0,0 +1,31 @@
+// Copyright 2010 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+
+typedef uintptr kevent_udata;
+
+struct sigaction;
+
+void	runtime·sigpanic(void);
+
+void	runtime·setitimer(int32, Itimerval*, Itimerval*);
+void	runtime·sigaction(int32, struct sigaction*, struct sigaction*);
+void	runtime·sigaltstack(SigaltstackT*, SigaltstackT*);
+void	runtime·sigprocmask(int32, Sigset*, Sigset*);
+void	runtime·unblocksignals(void);
+int32	runtime·sysctl(uint32*, uint32, byte*, uintptr*, byte*, uintptr);
+extern void runtime·lwp_tramp(void);
+
+enum {
+	SS_DISABLE = 4,
+	SIG_BLOCK = 1,
+	SIG_UNBLOCK = 2,
+	SIG_SETMASK = 3,
+	NSIG = 33,
+	SI_USER = 0,
+
+	// From NetBSD's <sys/ucontext.h>
+	_UC_SIGMASK = 0x01,
+	_UC_CPU = 0x04,
+};
diff --git a/src/pkg/runtime/os_netbsd_386.c b/src/runtime/os_netbsd_386.c
similarity index 100%
rename from src/pkg/runtime/os_netbsd_386.c
rename to src/runtime/os_netbsd_386.c
diff --git a/src/pkg/runtime/os_netbsd_amd64.c b/src/runtime/os_netbsd_amd64.c
similarity index 100%
rename from src/pkg/runtime/os_netbsd_amd64.c
rename to src/runtime/os_netbsd_amd64.c
diff --git a/src/runtime/os_netbsd_arm.c b/src/runtime/os_netbsd_arm.c
new file mode 100644
index 0000000..9dd4bcd
--- /dev/null
+++ b/src/runtime/os_netbsd_arm.c
@@ -0,0 +1,34 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "runtime.h"
+#include "defs_GOOS_GOARCH.h"
+#include "os_GOOS.h"
+#include "signal_GOOS_GOARCH.h"
+#include "textflag.h"
+
+void
+runtime·lwp_mcontext_init(McontextT *mc, void *stack, M *mp, G *gp, void (*fn)(void))
+{
+	mc->__gregs[REG_R15] = (uint32)runtime·lwp_tramp;
+	mc->__gregs[REG_R13] = (uint32)stack;
+	mc->__gregs[REG_R0] = (uint32)mp;
+	mc->__gregs[REG_R1] = (uint32)gp;
+	mc->__gregs[REG_R2] = (uint32)fn;
+}
+
+void
+runtime·checkgoarm(void)
+{
+	// TODO(minux)
+}
+
+#pragma textflag NOSPLIT
+int64
+runtime·cputicks() {
+	// Currently cputicks() is used in blocking profiler and to seed runtime·fastrand1().
+	// runtime·nanotime() is a poor approximation of CPU ticks that is enough for the profiler.
+	// TODO: need more entropy to better seed fastrand1.
+	return runtime·nanotime();
+}
diff --git a/src/runtime/os_openbsd.c b/src/runtime/os_openbsd.c
new file mode 100644
index 0000000..eebaa13
--- /dev/null
+++ b/src/runtime/os_openbsd.c
@@ -0,0 +1,309 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "runtime.h"
+#include "defs_GOOS_GOARCH.h"
+#include "os_GOOS.h"
+#include "signal_unix.h"
+#include "stack.h"
+#include "textflag.h"
+
+enum
+{
+	ESRCH = 3,
+	EAGAIN = 35,
+	EWOULDBLOCK = EAGAIN,
+	ENOTSUP = 91,
+
+	// From OpenBSD's sys/time.h
+	CLOCK_REALTIME = 0,
+	CLOCK_VIRTUAL = 1,
+	CLOCK_PROF = 2,
+	CLOCK_MONOTONIC = 3
+};
+
+extern SigTab runtime·sigtab[];
+
+static Sigset sigset_none;
+static Sigset sigset_all = ~(Sigset)0;
+
+extern int32 runtime·tfork(TforkT *param, uintptr psize, M *mp, G *gp, void (*fn)(void));
+extern int32 runtime·thrsleep(void *ident, int32 clock_id, void *tsp, void *lock, const int32 *abort);
+extern int32 runtime·thrwakeup(void *ident, int32 n);
+
+// From OpenBSD's <sys/sysctl.h>
+#define	CTL_HW	6
+#define	HW_NCPU	3
+
+static int32
+getncpu(void)
+{
+	uint32 mib[2];
+	uint32 out;
+	int32 ret;
+	uintptr nout;
+
+	// Fetch hw.ncpu via sysctl.
+	mib[0] = CTL_HW;
+	mib[1] = HW_NCPU;
+	nout = sizeof out;
+	out = 0;
+	ret = runtime·sysctl(mib, 2, (byte*)&out, &nout, nil, 0);
+	if(ret >= 0)
+		return out;
+	else
+		return 1;
+}
+
+#pragma textflag NOSPLIT
+uintptr
+runtime·semacreate(void)
+{
+	return 1;
+}
+
+#pragma textflag NOSPLIT
+int32
+runtime·semasleep(int64 ns)
+{
+	Timespec ts, *tsp = nil;
+
+	// Compute sleep deadline.
+	if(ns >= 0) {
+		int32 nsec;
+		ns += runtime·nanotime();
+		ts.tv_sec = runtime·timediv(ns, 1000000000, &nsec);
+		ts.tv_nsec = nsec; // tv_nsec is int64 on amd64
+		tsp = &ts;
+	}
+
+	for(;;) {
+		int32 ret;
+
+		// spin-mutex lock
+		while(runtime·xchg(&g->m->waitsemalock, 1))
+			runtime·osyield();
+
+		if(g->m->waitsemacount != 0) {
+			// semaphore is available.
+			g->m->waitsemacount--;
+			// spin-mutex unlock
+			runtime·atomicstore(&g->m->waitsemalock, 0);
+			return 0;  // semaphore acquired
+		}
+
+		// sleep until semaphore != 0 or timeout.
+		// thrsleep unlocks m->waitsemalock.
+		ret = runtime·thrsleep(&g->m->waitsemacount, CLOCK_MONOTONIC, tsp, &g->m->waitsemalock, (int32 *)&g->m->waitsemacount);
+		if(ret == EWOULDBLOCK)
+			return -1;
+	}
+}
+
+static void badsemawakeup(void);
+
+#pragma textflag NOSPLIT
+void
+runtime·semawakeup(M *mp)
+{
+	uint32 ret;
+	void *oldptr;
+	uint32 oldscalar;
+	void (*fn)(void);
+
+	// spin-mutex lock
+	while(runtime·xchg(&mp->waitsemalock, 1))
+		runtime·osyield();
+	mp->waitsemacount++;
+	ret = runtime·thrwakeup(&mp->waitsemacount, 1);
+	if(ret != 0 && ret != ESRCH) {
+		// semawakeup can be called on signal stack.
+		// Save old ptrarg/scalararg so we can restore them.
+		oldptr = g->m->ptrarg[0];
+		oldscalar = g->m->scalararg[0];
+		g->m->ptrarg[0] = mp;
+		g->m->scalararg[0] = ret;
+		fn = badsemawakeup;
+		if(g == g->m->gsignal)
+			fn();
+		else
+			runtime·onM(&fn);
+		g->m->ptrarg[0] = oldptr;
+		g->m->scalararg[0] = oldscalar;
+	}
+	// spin-mutex unlock
+	runtime·atomicstore(&mp->waitsemalock, 0);
+}
+
+static void
+badsemawakeup(void)
+{
+	M *mp;
+	int32 ret;
+
+	mp = g->m->ptrarg[0];
+	g->m->ptrarg[0] = nil;
+	ret = g->m->scalararg[0];
+	g->m->scalararg[0] = 0;
+
+	runtime·printf("thrwakeup addr=%p sem=%d ret=%d\n", &mp->waitsemacount, mp->waitsemacount, ret);
+}
+
+void
+runtime·newosproc(M *mp, void *stk)
+{
+	TforkT param;
+	Sigset oset;
+	int32 ret;
+
+	if(0) {
+		runtime·printf(
+			"newosproc stk=%p m=%p g=%p id=%d/%d ostk=%p\n",
+			stk, mp, mp->g0, mp->id, (int32)mp->tls[0], &mp);
+	}
+
+	mp->tls[0] = mp->id;	// so 386 asm can find it
+
+	param.tf_tcb = (byte*)&mp->tls[0];
+	param.tf_tid = (int32*)&mp->procid;
+	param.tf_stack = stk;
+
+	oset = runtime·sigprocmask(SIG_SETMASK, sigset_all);
+	ret = runtime·tfork(&param, sizeof(param), mp, mp->g0, runtime·mstart);
+	runtime·sigprocmask(SIG_SETMASK, oset);
+
+	if(ret < 0) {
+		runtime·printf("runtime: failed to create new OS thread (have %d already; errno=%d)\n", runtime·mcount() - 1, -ret);
+		if (ret == -ENOTSUP)
+			runtime·printf("runtime: is kern.rthreads disabled?\n");
+		runtime·throw("runtime.newosproc");
+	}
+}
+
+void
+runtime·osinit(void)
+{
+	runtime·ncpu = getncpu();
+}
+
+#pragma textflag NOSPLIT
+void
+runtime·get_random_data(byte **rnd, int32 *rnd_len)
+{
+	#pragma dataflag NOPTR
+	static byte urandom_data[HashRandomBytes];
+	int32 fd;
+	fd = runtime·open("/dev/urandom", 0 /* O_RDONLY */, 0);
+	if(runtime·read(fd, urandom_data, HashRandomBytes) == HashRandomBytes) {
+		*rnd = urandom_data;
+		*rnd_len = HashRandomBytes;
+	} else {
+		*rnd = nil;
+		*rnd_len = 0;
+	}
+	runtime·close(fd);
+}
+
+void
+runtime·goenvs(void)
+{
+	runtime·goenvs_unix();
+}
+
+// Called to initialize a new m (including the bootstrap m).
+// Called on the parent thread (main thread in case of bootstrap), can allocate memory.
+void
+runtime·mpreinit(M *mp)
+{
+	mp->gsignal = runtime·malg(32*1024);
+	mp->gsignal->m = mp;
+}
+
+// Called to initialize a new m (including the bootstrap m).
+// Called on the new thread, can not allocate memory.
+void
+runtime·minit(void)
+{
+	// Initialize signal handling
+	runtime·signalstack((byte*)g->m->gsignal->stack.lo, 32*1024);
+	runtime·sigprocmask(SIG_SETMASK, sigset_none);
+}
+
+// Called from dropm to undo the effect of an minit.
+void
+runtime·unminit(void)
+{
+	runtime·signalstack(nil, 0);
+}
+
+uintptr
+runtime·memlimit(void)
+{
+	return 0;
+}
+
+extern void runtime·sigtramp(void);
+
+typedef struct sigaction {
+	union {
+		void    (*__sa_handler)(int32);
+		void    (*__sa_sigaction)(int32, Siginfo*, void *);
+	} __sigaction_u;		/* signal handler */
+	uint32	sa_mask;		/* signal mask to apply */
+	int32	sa_flags;		/* see signal options below */
+} SigactionT;
+
+void
+runtime·setsig(int32 i, GoSighandler *fn, bool restart)
+{
+	SigactionT sa;
+
+	runtime·memclr((byte*)&sa, sizeof sa);
+	sa.sa_flags = SA_SIGINFO|SA_ONSTACK;
+	if(restart)
+		sa.sa_flags |= SA_RESTART;
+	sa.sa_mask = ~0U;
+	if(fn == runtime·sighandler)
+		fn = (void*)runtime·sigtramp;
+	sa.__sigaction_u.__sa_sigaction = (void*)fn;
+	runtime·sigaction(i, &sa, nil);
+}
+
+GoSighandler*
+runtime·getsig(int32 i)
+{
+	SigactionT sa;
+
+	runtime·memclr((byte*)&sa, sizeof sa);
+	runtime·sigaction(i, nil, &sa);
+	if((void*)sa.__sigaction_u.__sa_sigaction == runtime·sigtramp)
+		return runtime·sighandler;
+	return (void*)sa.__sigaction_u.__sa_sigaction;
+}
+
+void
+runtime·signalstack(byte *p, int32 n)
+{
+	StackT st;
+
+	st.ss_sp = (void*)p;
+	st.ss_size = n;
+	st.ss_flags = 0;
+	if(p == nil)
+		st.ss_flags = SS_DISABLE;
+	runtime·sigaltstack(&st, nil);
+}
+
+void
+runtime·unblocksignals(void)
+{
+	runtime·sigprocmask(SIG_SETMASK, sigset_none);
+}
+
+#pragma textflag NOSPLIT
+int8*
+runtime·signame(int32 sig)
+{
+	return runtime·sigtab[sig].name;
+}
diff --git a/src/runtime/os_openbsd.go b/src/runtime/os_openbsd.go
new file mode 100644
index 0000000..a000f96
--- /dev/null
+++ b/src/runtime/os_openbsd.go
@@ -0,0 +1,17 @@
+// Copyright 2014 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package runtime
+
+import "unsafe"
+
+func setitimer(mode int32, new, old unsafe.Pointer)
+func sigaction(sig int32, new, old unsafe.Pointer)
+func sigaltstack(new, old unsafe.Pointer)
+func sigprocmask(mode int32, new uint32) uint32
+func sysctl(mib *uint32, miblen uint32, out *byte, size *uintptr, dst *byte, ndst uintptr) int32
+func raise(sig int32)
+func tfork(param unsafe.Pointer, psize uintptr, mm, gg, fn unsafe.Pointer) int32
+func thrsleep(ident unsafe.Pointer, clock_id int32, tsp, lock, abort unsafe.Pointer) int32
+func thrwakeup(ident unsafe.Pointer, n int32) int32
diff --git a/src/runtime/os_openbsd.h b/src/runtime/os_openbsd.h
new file mode 100644
index 0000000..6ad9810
--- /dev/null
+++ b/src/runtime/os_openbsd.h
@@ -0,0 +1,26 @@
+// Copyright 2010 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+
+typedef byte* kevent_udata;
+
+struct sigaction;
+
+void	runtime·sigpanic(void);
+
+void	runtime·setitimer(int32, Itimerval*, Itimerval*);
+void	runtime·sigaction(int32, struct sigaction*, struct sigaction*);
+void	runtime·sigaltstack(SigaltstackT*, SigaltstackT*);
+Sigset	runtime·sigprocmask(int32, Sigset);
+void	runtime·unblocksignals(void);
+int32	runtime·sysctl(uint32*, uint32, byte*, uintptr*, byte*, uintptr);
+
+enum {
+	SS_DISABLE = 4,
+	SIG_BLOCK = 1,
+	SIG_UNBLOCK = 2,
+	SIG_SETMASK = 3,
+	NSIG = 33,
+	SI_USER = 0,
+};
diff --git a/src/runtime/os_plan9.c b/src/runtime/os_plan9.c
new file mode 100644
index 0000000..f8c543f
--- /dev/null
+++ b/src/runtime/os_plan9.c
@@ -0,0 +1,362 @@
+// Copyright 2010 The Go 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 "runtime.h"
+#include "os_GOOS.h"
+#include "arch_GOARCH.h"
+#include "textflag.h"
+#include "malloc.h"
+
+int8 *goos = "plan9";
+extern SigTab runtime·sigtab[];
+
+int32 runtime·postnote(int32, int8*);
+
+// Called to initialize a new m (including the bootstrap m).
+// Called on the parent thread (main thread in case of bootstrap), can allocate memory.
+void
+runtime·mpreinit(M *mp)
+{
+	// Initialize stack and goroutine for note handling.
+	mp->gsignal = runtime·malg(32*1024);
+	mp->gsignal->m = mp;
+	mp->notesig = (int8*)runtime·mallocgc(ERRMAX*sizeof(int8), nil, FlagNoScan);
+
+	// Initialize stack for handling strings from the
+	// errstr system call, as used in package syscall.
+	mp->errstr = (byte*)runtime·mallocgc(ERRMAX*sizeof(byte), nil, FlagNoScan);
+}
+
+// Called to initialize a new m (including the bootstrap m).
+// Called on the new thread, can not allocate memory.
+void
+runtime·minit(void)
+{
+	// Mask all SSE floating-point exceptions
+	// when running on the 64-bit kernel.
+	runtime·setfpmasks();
+}
+
+// Called from dropm to undo the effect of an minit.
+void
+runtime·unminit(void)
+{
+}
+
+
+static int32
+getproccount(void)
+{
+	int32 fd, i, n, ncpu;
+	byte buf[2048];
+
+	fd = runtime·open("/dev/sysstat", OREAD, 0);
+	if(fd < 0)
+		return 1;
+	ncpu = 0;
+	for(;;) {
+		n = runtime·read(fd, buf, sizeof buf);
+		if(n <= 0)
+			break;
+		for(i = 0; i < n; i++) {
+			if(buf[i] == '\n')
+				ncpu++;
+		}
+	}
+	runtime·close(fd);
+	return ncpu > 0 ? ncpu : 1;
+}
+
+static int32
+getpid(void)
+{
+	byte b[20], *c;
+	int32 fd;
+
+	runtime·memclr(b, sizeof(b));
+	fd = runtime·open("#c/pid", 0, 0);
+	if(fd >= 0) {
+		runtime·read(fd, b, sizeof(b));
+		runtime·close(fd);
+	}
+	c = b;
+	while(*c == ' ' || *c == '\t')
+		c++;
+	return runtime·atoi(c);
+}
+
+void
+runtime·osinit(void)
+{
+	runtime·ncpu = getproccount();
+	g->m->procid = getpid();
+	runtime·notify(runtime·sigtramp);
+}
+
+void
+runtime·crash(void)
+{
+	runtime·notify(nil);
+	*(int32*)0 = 0;
+}
+
+#pragma textflag NOSPLIT
+void
+runtime·get_random_data(byte **rnd, int32 *rnd_len)
+{
+	static byte random_data[HashRandomBytes];
+	int32 fd;
+
+	fd = runtime·open("/dev/random", 0 /* O_RDONLY */, 0);
+	if(runtime·read(fd, random_data, HashRandomBytes) == HashRandomBytes) {
+		*rnd = random_data;
+		*rnd_len = HashRandomBytes;
+	} else {
+		*rnd = nil;
+		*rnd_len = 0;
+	}
+	runtime·close(fd);
+}
+
+void
+runtime·goenvs(void)
+{
+}
+
+void
+runtime·initsig(void)
+{
+}
+
+#pragma textflag NOSPLIT
+void
+runtime·osyield(void)
+{
+	runtime·sleep(0);
+}
+
+#pragma textflag NOSPLIT
+void
+runtime·usleep(uint32 µs)
+{
+	uint32 ms;
+
+	ms = µs/1000;
+	if(ms == 0)
+		ms = 1;
+	runtime·sleep(ms);
+}
+
+#pragma textflag NOSPLIT
+int64
+runtime·nanotime(void)
+{
+	int64 ns, scratch;
+
+	ns = runtime·nsec(&scratch);
+	// TODO(aram): remove hack after I fix _nsec in the pc64 kernel.
+	if(ns == 0)
+		return scratch;
+	return ns;
+}
+
+#pragma textflag NOSPLIT
+void
+runtime·itoa(int32 n, byte *p, uint32 len)
+{
+	byte *q, c;
+	uint32 i;
+
+	if(len <= 1)
+		return;
+
+	runtime·memclr(p, len);
+	q = p;
+
+	if(n==0) {
+		*q++ = '0';
+		USED(q);
+		return;
+	}
+	if(n < 0) {
+		*q++ = '-';
+		p++;
+		n = -n;
+	}
+	for(i=0; n > 0 && i < len; i++) {
+		*q++ = '0' + (n%10);
+		n = n/10;
+	}
+	for(q--; q >= p; ) {
+		c = *p;
+		*p++ = *q;
+		*q-- = c;
+	}
+}
+
+void
+runtime·goexitsall(int8 *status)
+{
+	int8 buf[ERRMAX];
+	M *mp;
+	int32 pid;
+
+	runtime·snprintf((byte*)buf, sizeof buf, "go: exit %s", status);
+	pid = getpid();
+	for(mp=runtime·atomicloadp(&runtime·allm); mp; mp=mp->alllink)
+		if(mp->procid != pid)
+			runtime·postnote(mp->procid, buf);
+}
+
+int32
+runtime·postnote(int32 pid, int8* msg)
+{
+	int32 fd;
+	intgo len;
+	uint8 buf[128];
+	uint8 tmp[16];
+	uint8 *p, *q;
+
+	runtime·memclr(buf, sizeof buf);
+
+	/* build path string /proc/pid/note */
+	q = tmp;
+	p = buf;
+	runtime·itoa(pid, tmp, sizeof tmp);
+	runtime·memmove((void*)p, (void*)"/proc/", 6);
+	for(p += 6; *p++ = *q++; );
+	p--;
+	runtime·memmove((void*)p, (void*)"/note", 5);
+
+	fd = runtime·open((int8*)buf, OWRITE, 0);
+	if(fd < 0)
+		return -1;
+
+	len = runtime·findnull((byte*)msg);
+	if(runtime·write(fd, msg, len) != len) {
+		runtime·close(fd);
+		return -1;
+	}
+	runtime·close(fd);
+	return 0;
+}
+
+static void exit(void);
+
+#pragma textflag NOSPLIT
+void
+runtime·exit(int32 e)
+{
+	void (*fn)(void);
+
+	g->m->scalararg[0] = e;
+	fn = exit;
+	runtime·onM(&fn);
+}
+
+static void
+exit(void)
+{
+	int32 e;
+	byte tmp[16];
+	int8 *status;
+ 
+ 	e = g->m->scalararg[0];
+ 	g->m->scalararg[0] = 0;
+
+	if(e == 0)
+		status = "";
+	else {
+		/* build error string */
+		runtime·itoa(e, tmp, sizeof tmp);
+		status = (int8*)tmp;
+	}
+
+	runtime·goexitsall(status);
+	runtime·exits(status);
+}
+
+void
+runtime·newosproc(M *mp, void *stk)
+{
+	int32 pid;
+
+	if(0)
+		runtime·printf("newosproc mp=%p ostk=%p\n", mp, &mp);
+
+	USED(stk);
+	if((pid = runtime·rfork(RFPROC|RFMEM|RFNOWAIT)) < 0)
+		runtime·throw("newosproc: rfork failed\n");
+	if(pid == 0)
+		runtime·tstart_plan9(mp);
+}
+
+#pragma textflag NOSPLIT
+uintptr
+runtime·semacreate(void)
+{
+	return 1;
+}
+
+#pragma textflag NOSPLIT
+int32
+runtime·semasleep(int64 ns)
+{
+	int32 ret;
+	int32 ms;
+
+	if(ns >= 0) {
+		ms = runtime·timediv(ns, 1000000, nil);
+		if(ms == 0)
+			ms = 1;
+		ret = runtime·plan9_tsemacquire(&g->m->waitsemacount, ms);
+		if(ret == 1)
+			return 0;  // success
+		return -1;  // timeout or interrupted
+	}
+
+	while(runtime·plan9_semacquire(&g->m->waitsemacount, 1) < 0) {
+		/* interrupted; try again (c.f. lock_sema.c) */
+	}
+	return 0;  // success
+}
+
+#pragma textflag NOSPLIT
+void
+runtime·semawakeup(M *mp)
+{
+	runtime·plan9_semrelease(&mp->waitsemacount, 1);
+}
+
+#pragma textflag NOSPLIT
+int32
+runtime·read(int32 fd, void *buf, int32 nbytes)
+{
+	return runtime·pread(fd, buf, nbytes, -1LL);
+}
+
+#pragma textflag NOSPLIT
+int32
+runtime·write(uintptr fd, void *buf, int32 nbytes)
+{
+	return runtime·pwrite((int32)fd, buf, nbytes, -1LL);
+}
+
+uintptr
+runtime·memlimit(void)
+{
+	return 0;
+}
+
+#pragma dataflag NOPTR
+static int8 badsignal[] = "runtime: signal received on thread not created by Go.\n";
+
+// This runs on a foreign stack, without an m or a g.  No stack split.
+#pragma textflag NOSPLIT
+void
+runtime·badsignal2(void)
+{
+	runtime·pwrite(2, badsignal, sizeof badsignal - 1, -1LL);
+	runtime·exits(badsignal);
+}
diff --git a/src/runtime/os_plan9.go b/src/runtime/os_plan9.go
new file mode 100644
index 0000000..20e47bf
--- /dev/null
+++ b/src/runtime/os_plan9.go
@@ -0,0 +1,103 @@
+// 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 runtime
+
+import "unsafe"
+
+func pread(fd int32, buf unsafe.Pointer, nbytes int32, offset int64) int32
+func pwrite(fd int32, buf unsafe.Pointer, nbytes int32, offset int64) int32
+func seek(fd int32, offset int64, whence int32) int64
+func exits(msg *byte)
+func brk_(addr unsafe.Pointer) uintptr
+func sleep(ms int32) int32
+func rfork(flags int32) int32
+func plan9_semacquire(addr *uint32, block int32) int32
+func plan9_tsemacquire(addr *uint32, ms int32) int32
+func plan9_semrelease(addr *uint32, count int32) int32
+func notify(fn unsafe.Pointer) int32
+func noted(mode int32) int32
+func nsec(*int64) int64
+func sigtramp(ureg, msg unsafe.Pointer)
+func setfpmasks()
+func tstart_plan9(newm *m)
+func errstr() string
+
+type _Plink uintptr
+
+func os_sigpipe() {
+	gothrow("too many writes on closed pipe")
+}
+
+func sigpanic() {
+	g := getg()
+	if !canpanic(g) {
+		gothrow("unexpected signal during runtime execution")
+	}
+
+	note := gostringnocopy((*byte)(unsafe.Pointer(g.m.notesig)))
+	switch g.sig {
+	case _SIGRFAULT, _SIGWFAULT:
+		addr := note[index(note, "addr=")+5:]
+		g.sigcode1 = uintptr(atolwhex(addr))
+		if g.sigcode1 < 0x1000 || g.paniconfault {
+			panicmem()
+		}
+		print("unexpected fault address ", hex(g.sigcode1), "\n")
+		gothrow("fault")
+	case _SIGTRAP:
+		if g.paniconfault {
+			panicmem()
+		}
+		gothrow(note)
+	case _SIGINTDIV:
+		panicdivide()
+	case _SIGFLOAT:
+		panicfloat()
+	default:
+		panic(errorString(note))
+	}
+}
+
+func atolwhex(p string) int64 {
+	for hasprefix(p, " ") || hasprefix(p, "\t") {
+		p = p[1:]
+	}
+	neg := false
+	if hasprefix(p, "-") || hasprefix(p, "+") {
+		neg = p[0] == '-'
+		p = p[1:]
+		for hasprefix(p, " ") || hasprefix(p, "\t") {
+			p = p[1:]
+		}
+	}
+	var n int64
+	switch {
+	case hasprefix(p, "0x"), hasprefix(p, "0X"):
+		p = p[2:]
+		for ; len(p) > 0; p = p[1:] {
+			if '0' <= p[0] && p[0] <= '9' {
+				n = n*16 + int64(p[0]-'0')
+			} else if 'a' <= p[0] && p[0] <= 'f' {
+				n = n*16 + int64(p[0]-'a'+10)
+			} else if 'A' <= p[0] && p[0] <= 'F' {
+				n = n*16 + int64(p[0]-'A'+10)
+			} else {
+				break
+			}
+		}
+	case hasprefix(p, "0"):
+		for ; len(p) > 0 && '0' <= p[0] && p[0] <= '7'; p = p[1:] {
+			n = n*8 + int64(p[0]-'0')
+		}
+	default:
+		for ; len(p) > 0 && '0' <= p[0] && p[0] <= '9'; p = p[1:] {
+			n = n*10 + int64(p[0]-'0')
+		}
+	}
+	if neg {
+		n = -n
+	}
+	return n
+}
diff --git a/src/runtime/os_plan9.h b/src/runtime/os_plan9.h
new file mode 100644
index 0000000..6d18024
--- /dev/null
+++ b/src/runtime/os_plan9.h
@@ -0,0 +1,93 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Plan 9-specific system calls
+int32	runtime·pread(int32 fd, void *buf, int32 nbytes, int64 offset);
+int32	runtime·pwrite(int32 fd, void *buf, int32 nbytes, int64 offset);
+int64	runtime·seek(int32 fd, int64 offset, int32 whence);
+void	runtime·exits(int8* msg);
+intptr	runtime·brk_(void*);
+int32	runtime·sleep(int32 ms);
+int32	runtime·rfork(int32 flags);
+int32	runtime·plan9_semacquire(uint32 *addr, int32 block);
+int32	runtime·plan9_tsemacquire(uint32 *addr, int32 ms);
+int32 	runtime·plan9_semrelease(uint32 *addr, int32 count);
+int32	runtime·notify(void (*fn)(void*, int8*));
+int32	runtime·noted(int32);
+int64	runtime·nsec(int64*);
+void	runtime·sigtramp(void*, int8*);
+void	runtime·sigpanic(void);
+void	runtime·goexitsall(int8*);
+void	runtime·setfpmasks(void);
+void	runtime·tstart_plan9(M *newm);
+
+/* open */
+enum
+{
+	OREAD	= 0,
+	OWRITE	= 1,
+	ORDWR	= 2,
+	OEXEC	= 3,
+	OTRUNC	= 16,
+	OCEXEC	= 32,
+	ORCLOSE	= 64,
+	OEXCL	= 0x1000
+};
+
+/* rfork */
+enum
+{
+	RFNAMEG         = (1<<0),
+	RFENVG          = (1<<1),
+	RFFDG           = (1<<2),
+	RFNOTEG         = (1<<3),
+	RFPROC          = (1<<4),
+	RFMEM           = (1<<5),
+	RFNOWAIT        = (1<<6),
+	RFCNAMEG        = (1<<10),
+	RFCENVG         = (1<<11),
+	RFCFDG          = (1<<12),
+	RFREND          = (1<<13),
+	RFNOMNT         = (1<<14)
+};
+
+/* notify */
+enum
+{
+	NCONT	= 0,
+	NDFLT	= 1
+};
+
+typedef struct Tos Tos;
+typedef intptr _Plink;
+
+struct Tos {
+	struct TosProf			/* Per process profiling */
+	{
+		_Plink	*pp;	/* known to be 0(ptr) */
+		_Plink	*next;	/* known to be 4(ptr) */
+		_Plink	*last;
+		_Plink	*first;
+		uint32	pid;
+		uint32	what;
+	} prof;
+	uint64	cyclefreq;	/* cycle clock frequency if there is one, 0 otherwise */
+	int64	kcycles;	/* cycles spent in kernel */
+	int64	pcycles;	/* cycles spent in process (kernel + user) */
+	uint32	pid;		/* might as well put the pid here */
+	uint32	clock;
+	/* top of stack is here */
+};
+
+enum {
+	NSIG = 14, /* number of signals in runtime·SigTab array */
+	ERRMAX = 128, /* max length of note string */
+
+	/* Notes in runtime·sigtab that are handled by runtime·sigpanic. */
+	SIGRFAULT = 2,
+	SIGWFAULT = 3,
+	SIGINTDIV = 4,
+	SIGFLOAT = 5,
+	SIGTRAP = 6,
+};
diff --git a/src/runtime/os_plan9_386.c b/src/runtime/os_plan9_386.c
new file mode 100644
index 0000000..42c6d16
--- /dev/null
+++ b/src/runtime/os_plan9_386.c
@@ -0,0 +1,150 @@
+// Copyright 2010 The Go 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 "runtime.h"
+#include "defs_GOOS_GOARCH.h"
+#include "os_GOOS.h"
+#include "signals_GOOS.h"
+
+void
+runtime·dumpregs(Ureg *u)
+{
+	runtime·printf("ax	%x\n", u->ax);
+	runtime·printf("bx	%x\n", u->bx);
+	runtime·printf("cx	%x\n", u->cx);
+	runtime·printf("dx	%x\n", u->dx);
+	runtime·printf("di	%x\n", u->di);
+	runtime·printf("si	%x\n", u->si);
+	runtime·printf("bp	%x\n", u->bp);
+	runtime·printf("sp	%x\n", u->sp);
+	runtime·printf("pc	%x\n", u->pc);
+	runtime·printf("flags	%x\n", u->flags);
+	runtime·printf("cs	%x\n", u->cs);
+	runtime·printf("fs	%x\n", u->fs);
+	runtime·printf("gs	%x\n", u->gs);
+}
+
+int32
+runtime·sighandler(void *v, int8 *note, G *gp)
+{
+	uintptr *sp;
+	SigTab *t;
+	bool crash;
+	Ureg *ureg;
+	intgo len, n;
+	int32 sig, flags;
+
+	ureg = (Ureg*)v;
+
+	// The kernel will never pass us a nil note or ureg so we probably
+	// made a mistake somewhere in runtime·sigtramp.
+	if(ureg == nil || note == nil) {
+		runtime·printf("sighandler: ureg %p note %p\n", ureg, note);
+		goto Throw;
+	}
+
+	// Check that the note is no more than ERRMAX bytes (including
+	// the trailing NUL). We should never receive a longer note.
+	len = runtime·findnull((byte*)note);
+	if(len > ERRMAX-1) {
+		runtime·printf("sighandler: note is longer than ERRMAX\n");
+		goto Throw;
+	}
+
+	// See if the note matches one of the patterns in runtime·sigtab.
+	// Notes that do not match any pattern can be handled at a higher
+	// level by the program but will otherwise be ignored.
+	flags = SigNotify;
+	for(sig = 0; sig < nelem(runtime·sigtab); sig++) {
+		t = &runtime·sigtab[sig];
+		n = runtime·findnull((byte*)t->name);
+		if(len < n)
+			continue;
+		if(runtime·strncmp((byte*)note, (byte*)t->name, n) == 0) {
+			flags = t->flags;
+			break;
+		}
+	}
+
+	if(flags & SigGoExit)
+		runtime·exits(note+9); // Strip "go: exit " prefix.
+
+	if(flags & SigPanic) {
+		// Copy the error string from sigtramp's stack into m->notesig so
+		// we can reliably access it from the panic routines.
+		runtime·memmove(g->m->notesig, note, len+1);
+
+		gp->sig = sig;
+		gp->sigpc = ureg->pc;
+
+		// Only push runtime·sigpanic if PC != 0.
+		//
+		// If PC == 0, probably panicked because of a call to a nil func.
+		// Not pushing that onto SP will make the trace look like a call
+		// to runtime·sigpanic instead. (Otherwise the trace will end at
+		// runtime·sigpanic and we won't get to see who faulted).
+		if(ureg->pc != 0) {
+			sp = (uintptr*)ureg->sp;
+			*--sp = ureg->pc;
+			ureg->sp = (uint32)sp;
+		}
+		ureg->pc = (uintptr)runtime·sigpanic;
+		return NCONT;
+	}
+
+	if(flags & SigNotify) {
+		// TODO(ality): See if os/signal wants it.
+		//if(runtime·sigsend(...))
+		//	return NCONT;
+	}
+	if(flags & SigKill)
+		goto Exit;
+	if(!(flags & SigThrow))
+		return NCONT;
+
+Throw:
+	g->m->throwing = 1;
+	g->m->caughtsig = gp;
+	runtime·startpanic();
+
+	runtime·printf("%s\n", note);
+	runtime·printf("PC=%x\n", ureg->pc);
+	runtime·printf("\n");
+
+	if(runtime·gotraceback(&crash)) {
+		runtime·goroutineheader(gp);
+		runtime·tracebacktrap(ureg->pc, ureg->sp, 0, gp);
+		runtime·tracebackothers(gp);
+		runtime·printf("\n");
+		runtime·dumpregs(ureg);
+	}
+	
+	if(crash)
+		runtime·crash();
+
+Exit:
+	runtime·goexitsall(note);
+	runtime·exits(note);
+	return NDFLT; // not reached
+}
+
+void
+runtime·sigenable(uint32 sig)
+{
+	USED(sig);
+}
+
+void
+runtime·sigdisable(uint32 sig)
+{
+	USED(sig);
+}
+
+void
+runtime·resetcpuprofiler(int32 hz)
+{
+	// TODO: Enable profiling interrupts.
+	
+	g->m->profilehz = hz;
+}
diff --git a/src/runtime/os_plan9_amd64.c b/src/runtime/os_plan9_amd64.c
new file mode 100644
index 0000000..a9dc0eb
--- /dev/null
+++ b/src/runtime/os_plan9_amd64.c
@@ -0,0 +1,158 @@
+// Copyright 2010 The Go 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 "runtime.h"
+#include "defs_GOOS_GOARCH.h"
+#include "os_GOOS.h"
+#include "signals_GOOS.h"
+
+void
+runtime·dumpregs(Ureg *u)
+{
+	runtime·printf("ax	%X\n", u->ax);
+	runtime·printf("bx	%X\n", u->bx);
+	runtime·printf("cx	%X\n", u->cx);
+	runtime·printf("dx	%X\n", u->dx);
+	runtime·printf("di	%X\n", u->di);
+	runtime·printf("si	%X\n", u->si);
+	runtime·printf("bp	%X\n", u->bp);
+	runtime·printf("sp	%X\n", u->sp);
+	runtime·printf("r8	%X\n", u->r8);
+	runtime·printf("r9	%X\n", u->r9);
+	runtime·printf("r10	%X\n", u->r10);
+	runtime·printf("r11	%X\n", u->r11);
+	runtime·printf("r12	%X\n", u->r12);
+	runtime·printf("r13	%X\n", u->r13);
+	runtime·printf("r14	%X\n", u->r14);
+	runtime·printf("r15	%X\n", u->r15);
+	runtime·printf("ip	%X\n", u->ip);
+	runtime·printf("flags	%X\n", u->flags);
+	runtime·printf("cs	%X\n", (uint64)u->cs);
+	runtime·printf("fs	%X\n", (uint64)u->fs);
+	runtime·printf("gs	%X\n", (uint64)u->gs);
+}
+
+int32
+runtime·sighandler(void *v, int8 *note, G *gp)
+{
+	uintptr *sp;
+	SigTab *t;
+	bool crash;
+	Ureg *ureg;
+	intgo len, n;
+	int32 sig, flags;
+
+	ureg = (Ureg*)v;
+
+	// The kernel will never pass us a nil note or ureg so we probably
+	// made a mistake somewhere in runtime·sigtramp.
+	if(ureg == nil || note == nil) {
+		runtime·printf("sighandler: ureg %p note %p\n", ureg, note);
+		goto Throw;
+	}
+
+	// Check that the note is no more than ERRMAX bytes (including
+	// the trailing NUL). We should never receive a longer note.
+	len = runtime·findnull((byte*)note);
+	if(len > ERRMAX-1) {
+		runtime·printf("sighandler: note is longer than ERRMAX\n");
+		goto Throw;
+	}
+
+	// See if the note matches one of the patterns in runtime·sigtab.
+	// Notes that do not match any pattern can be handled at a higher
+	// level by the program but will otherwise be ignored.
+	flags = SigNotify;
+	for(sig = 0; sig < nelem(runtime·sigtab); sig++) {
+		t = &runtime·sigtab[sig];
+		n = runtime·findnull((byte*)t->name);
+		if(len < n)
+			continue;
+		if(runtime·strncmp((byte*)note, (byte*)t->name, n) == 0) {
+			flags = t->flags;
+			break;
+		}
+	}
+
+	if(flags & SigGoExit)
+		runtime·exits(note+9); // Strip "go: exit " prefix.
+
+	if(flags & SigPanic) {
+		// Copy the error string from sigtramp's stack into m->notesig so
+		// we can reliably access it from the panic routines.
+		runtime·memmove(g->m->notesig, note, len+1);
+
+		gp->sig = sig;
+		gp->sigpc = ureg->ip;
+
+		// Only push runtime·sigpanic if PC != 0.
+		//
+		// If PC == 0, probably panicked because of a call to a nil func.
+		// Not pushing that onto SP will make the trace look like a call
+		// to runtime·sigpanic instead. (Otherwise the trace will end at
+		// runtime·sigpanic and we won't get to see who faulted).
+		if(ureg->ip != 0) {
+			sp = (uintptr*)ureg->sp;
+			*--sp = ureg->ip;
+			ureg->sp = (uint64)sp;
+		}
+		ureg->ip = (uintptr)runtime·sigpanic;
+		return NCONT;
+	}
+
+	if(flags & SigNotify) {
+		// TODO(ality): See if os/signal wants it.
+		//if(runtime·sigsend(...))
+		//	return NCONT;
+	}
+	if(flags & SigKill)
+		goto Exit;
+	if(!(flags & SigThrow))
+		return NCONT;
+
+Throw:
+	g->m->throwing = 1;
+	g->m->caughtsig = gp;
+	runtime·startpanic();
+
+	runtime·printf("%s\n", note);
+	runtime·printf("PC=%X\n", ureg->ip);
+	runtime·printf("\n");
+
+	if(runtime·gotraceback(&crash)) {
+		runtime·goroutineheader(gp);
+		runtime·tracebacktrap(ureg->ip, ureg->sp, 0, gp);
+		runtime·tracebackothers(gp);
+		runtime·printf("\n");
+		runtime·dumpregs(ureg);
+	}
+	
+	if(crash)
+		runtime·crash();
+
+Exit:
+	runtime·goexitsall(note);
+	runtime·exits(note);
+	return NDFLT; // not reached
+}
+
+void
+runtime·sigenable(uint32 sig)
+{
+	USED(sig);
+}
+
+void
+runtime·sigdisable(uint32 sig)
+{
+	USED(sig);
+}
+
+void
+runtime·resetcpuprofiler(int32 hz)
+{
+	// TODO: Enable profiling interrupts.
+	
+	g->m->profilehz = hz;
+}
diff --git a/src/runtime/os_solaris.c b/src/runtime/os_solaris.c
new file mode 100644
index 0000000..e16b8e6
--- /dev/null
+++ b/src/runtime/os_solaris.c
@@ -0,0 +1,557 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "runtime.h"
+#include "defs_GOOS_GOARCH.h"
+#include "os_GOOS.h"
+#include "signal_unix.h"
+#include "stack.h"
+#include "textflag.h"
+
+#pragma dynexport runtime·end _end
+#pragma dynexport runtime·etext _etext
+#pragma dynexport runtime·edata _edata
+
+#pragma dynimport libc·___errno ___errno "libc.so"
+#pragma dynimport libc·clock_gettime clock_gettime "libc.so"
+#pragma dynimport libc·close close "libc.so"
+#pragma dynimport libc·exit exit "libc.so"
+#pragma dynimport libc·fstat fstat "libc.so"
+#pragma dynimport libc·getcontext getcontext "libc.so"
+#pragma dynimport libc·getrlimit getrlimit "libc.so"
+#pragma dynimport libc·malloc malloc "libc.so"
+#pragma dynimport libc·mmap mmap "libc.so"
+#pragma dynimport libc·munmap munmap "libc.so"
+#pragma dynimport libc·open open "libc.so"
+#pragma dynimport libc·pthread_attr_destroy pthread_attr_destroy "libc.so"
+#pragma dynimport libc·pthread_attr_getstack pthread_attr_getstack "libc.so"
+#pragma dynimport libc·pthread_attr_init pthread_attr_init "libc.so"
+#pragma dynimport libc·pthread_attr_setdetachstate pthread_attr_setdetachstate "libc.so"
+#pragma dynimport libc·pthread_attr_setstack pthread_attr_setstack "libc.so"
+#pragma dynimport libc·pthread_create pthread_create "libc.so"
+#pragma dynimport libc·raise raise "libc.so"
+#pragma dynimport libc·read read "libc.so"
+#pragma dynimport libc·select select "libc.so"
+#pragma dynimport libc·sched_yield sched_yield "libc.so"
+#pragma dynimport libc·sem_init sem_init "libc.so"
+#pragma dynimport libc·sem_post sem_post "libc.so"
+#pragma dynimport libc·sem_reltimedwait_np sem_reltimedwait_np "libc.so"
+#pragma dynimport libc·sem_wait sem_wait "libc.so"
+#pragma dynimport libc·setitimer setitimer "libc.so"
+#pragma dynimport libc·sigaction sigaction "libc.so"
+#pragma dynimport libc·sigaltstack sigaltstack "libc.so"
+#pragma dynimport libc·sigprocmask sigprocmask "libc.so"
+#pragma dynimport libc·sysconf sysconf "libc.so"
+#pragma dynimport libc·usleep usleep "libc.so"
+#pragma dynimport libc·write write "libc.so"
+
+extern uintptr libc·___errno;
+extern uintptr libc·clock_gettime;
+extern uintptr libc·close;
+extern uintptr libc·exit;
+extern uintptr libc·fstat;
+extern uintptr libc·getcontext;
+extern uintptr libc·getrlimit;
+extern uintptr libc·malloc;
+extern uintptr libc·mmap;
+extern uintptr libc·munmap;
+extern uintptr libc·open;
+extern uintptr libc·pthread_attr_destroy;
+extern uintptr libc·pthread_attr_getstack;
+extern uintptr libc·pthread_attr_init;
+extern uintptr libc·pthread_attr_setdetachstate;
+extern uintptr libc·pthread_attr_setstack;
+extern uintptr libc·pthread_create;
+extern uintptr libc·raise;
+extern uintptr libc·read;
+extern uintptr libc·sched_yield;
+extern uintptr libc·select;
+extern uintptr libc·sem_init;
+extern uintptr libc·sem_post;
+extern uintptr libc·sem_reltimedwait_np;
+extern uintptr libc·sem_wait;
+extern uintptr libc·setitimer;
+extern uintptr libc·sigaction;
+extern uintptr libc·sigaltstack;
+extern uintptr libc·sigprocmask;
+extern uintptr libc·sysconf;
+extern uintptr libc·usleep;
+extern uintptr libc·write;
+
+void	runtime·getcontext(Ucontext *context);
+int32	runtime·pthread_attr_destroy(PthreadAttr* attr);
+int32	runtime·pthread_attr_init(PthreadAttr* attr);
+int32	runtime·pthread_attr_getstack(PthreadAttr* attr, void** addr, uint64* size);
+int32	runtime·pthread_attr_setdetachstate(PthreadAttr* attr, int32 state);
+int32	runtime·pthread_attr_setstack(PthreadAttr* attr, void* addr, uint64 size);
+int32	runtime·pthread_create(Pthread* thread, PthreadAttr* attr, void(*fn)(void), void *arg);
+uint32	runtime·tstart_sysvicall(M *newm);
+int32	runtime·sem_init(SemT* sem, int32 pshared, uint32 value);
+int32	runtime·sem_post(SemT* sem);
+int32	runtime·sem_reltimedwait_np(SemT* sem, Timespec* timeout);
+int32	runtime·sem_wait(SemT* sem);
+int64	runtime·sysconf(int32 name);
+
+extern SigTab runtime·sigtab[];
+static Sigset sigset_none;
+static Sigset sigset_all = { ~(uint32)0, ~(uint32)0, ~(uint32)0, ~(uint32)0, };
+
+static int32
+getncpu(void) 
+{
+	int32 n;
+	
+	n = (int32)runtime·sysconf(_SC_NPROCESSORS_ONLN);
+	if(n < 1)
+		return 1;
+	return n;
+}
+
+void
+runtime·osinit(void)
+{
+	runtime·ncpu = getncpu(); 
+}
+
+void
+runtime·newosproc(M *mp, void *stk)
+{
+	PthreadAttr attr;
+	Sigset oset;
+	Pthread tid;
+	int32 ret;
+	uint64 size;
+
+	USED(stk);
+	if(runtime·pthread_attr_init(&attr) != 0)
+		runtime·throw("pthread_attr_init");
+	if(runtime·pthread_attr_setstack(&attr, 0, 0x200000) != 0)
+		runtime·throw("pthread_attr_setstack");
+	size = 0;
+	if(runtime·pthread_attr_getstack(&attr, (void**)&mp->g0->stack.hi, &size) != 0)
+		runtime·throw("pthread_attr_getstack");	
+	mp->g0->stack.lo = mp->g0->stack.hi - size;
+	if(runtime·pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) != 0)
+		runtime·throw("pthread_attr_setdetachstate");
+
+	// Disable signals during create, so that the new thread starts
+	// with signals disabled.  It will enable them in minit.
+	runtime·sigprocmask(SIG_SETMASK, &sigset_all, &oset);
+	ret = runtime·pthread_create(&tid, &attr, (void (*)(void))runtime·tstart_sysvicall, mp);
+	runtime·sigprocmask(SIG_SETMASK, &oset, nil);
+	if(ret != 0) {
+		runtime·printf("runtime: failed to create new OS thread (have %d already; errno=%d)\n", runtime·mcount(), ret);
+		runtime·throw("runtime.newosproc");
+	}
+}
+
+#pragma textflag NOSPLIT
+void
+runtime·get_random_data(byte **rnd, int32 *rnd_len)
+{
+	#pragma dataflag NOPTR
+	static byte urandom_data[HashRandomBytes];
+	int32 fd;
+	fd = runtime·open("/dev/urandom", 0 /* O_RDONLY */, 0);
+	if(runtime·read(fd, urandom_data, HashRandomBytes) == HashRandomBytes) {
+		*rnd = urandom_data;
+		*rnd_len = HashRandomBytes;
+	} else {
+		*rnd = nil;
+		*rnd_len = 0;
+	}
+	runtime·close(fd);
+}
+
+void
+runtime·goenvs(void)
+{
+	runtime·goenvs_unix();
+}
+
+// Called to initialize a new m (including the bootstrap m).
+// Called on the parent thread (main thread in case of bootstrap), can allocate memory.
+void
+runtime·mpreinit(M *mp)
+{
+	mp->gsignal = runtime·malg(32*1024);
+	mp->gsignal->m = mp;
+}
+
+// Called to initialize a new m (including the bootstrap m).
+// Called on the new thread, can not allocate memory.
+void
+runtime·minit(void)
+{
+	runtime·asmcgocall(runtime·miniterrno, (void *)libc·___errno);
+	// Initialize signal handling
+	runtime·signalstack((byte*)g->m->gsignal->stack.lo, 32*1024);
+	runtime·sigprocmask(SIG_SETMASK, &sigset_none, nil);
+}
+
+// Called from dropm to undo the effect of an minit.
+void
+runtime·unminit(void)
+{
+	runtime·signalstack(nil, 0);
+}
+
+uintptr
+runtime·memlimit(void)
+{
+	Rlimit rl;
+	extern byte runtime·text[], runtime·end[];
+	uintptr used;
+	
+	if(runtime·getrlimit(RLIMIT_AS, &rl) != 0)
+		return 0;
+	if(rl.rlim_cur >= 0x7fffffff)
+		return 0;
+
+	// Estimate our VM footprint excluding the heap.
+	// Not an exact science: use size of binary plus
+	// some room for thread stacks.
+	used = runtime·end - runtime·text + (64<<20);
+	if(used >= rl.rlim_cur)
+		return 0;
+
+	// If there's not at least 16 MB left, we're probably
+	// not going to be able to do much.  Treat as no limit.
+	rl.rlim_cur -= used;
+	if(rl.rlim_cur < (16<<20))
+		return 0;
+
+	return rl.rlim_cur - used;
+}
+
+void
+runtime·setprof(bool on)
+{
+	USED(on);
+}
+
+extern void runtime·sigtramp(void);
+
+void
+runtime·setsig(int32 i, GoSighandler *fn, bool restart)
+{
+	SigactionT sa;
+
+	runtime·memclr((byte*)&sa, sizeof sa);
+	sa.sa_flags = SA_SIGINFO|SA_ONSTACK;
+	if(restart)
+		sa.sa_flags |= SA_RESTART;
+	sa.sa_mask.__sigbits[0] = ~(uint32)0;
+	sa.sa_mask.__sigbits[1] = ~(uint32)0;
+	sa.sa_mask.__sigbits[2] = ~(uint32)0;
+	sa.sa_mask.__sigbits[3] = ~(uint32)0;
+	if(fn == runtime·sighandler)
+		fn = (void*)runtime·sigtramp;
+	*((void**)&sa._funcptr[0]) = (void*)fn;
+	runtime·sigaction(i, &sa, nil);
+}
+
+GoSighandler*
+runtime·getsig(int32 i)
+{
+	SigactionT sa;
+
+	runtime·memclr((byte*)&sa, sizeof sa);
+	runtime·sigaction(i, nil, &sa);
+	if(*((void**)&sa._funcptr[0]) == runtime·sigtramp)
+		return runtime·sighandler;
+	return *((void**)&sa._funcptr[0]);
+}
+
+void
+runtime·signalstack(byte *p, int32 n)
+{
+	StackT st;
+
+	st.ss_sp = (void*)p;
+	st.ss_size = n;
+	st.ss_flags = 0;
+	if(p == nil)
+		st.ss_flags = SS_DISABLE;
+	runtime·sigaltstack(&st, nil);
+}
+
+void
+runtime·unblocksignals(void)
+{
+	runtime·sigprocmask(SIG_SETMASK, &sigset_none, nil);
+}
+
+#pragma textflag NOSPLIT
+uintptr
+runtime·semacreate(void)
+{
+	SemT* sem;
+
+	// Call libc's malloc rather than runtime·malloc.  This will
+	// allocate space on the C heap.  We can't call runtime·malloc
+	// here because it could cause a deadlock.
+	g->m->libcall.fn = (uintptr)(void*)libc·malloc;
+	g->m->libcall.n = 1;
+	runtime·memclr((byte*)&g->m->scratch, sizeof(g->m->scratch));
+	g->m->scratch.v[0] = (uintptr)sizeof(*sem);
+	g->m->libcall.args = (uintptr)(uintptr*)&g->m->scratch;
+	runtime·asmcgocall(runtime·asmsysvicall6, &g->m->libcall);
+	sem = (void*)g->m->libcall.r1;
+	if(runtime·sem_init(sem, 0, 0) != 0)
+		runtime·throw("sem_init");
+	return (uintptr)sem;
+}
+
+#pragma textflag NOSPLIT
+int32
+runtime·semasleep(int64 ns)
+{
+	M *m;
+
+	m = g->m;
+	if(ns >= 0) {
+		m->ts.tv_sec = ns / 1000000000LL;
+		m->ts.tv_nsec = ns % 1000000000LL;
+
+		m->libcall.fn = (uintptr)(void*)libc·sem_reltimedwait_np;
+		m->libcall.n = 2;
+		runtime·memclr((byte*)&m->scratch, sizeof(m->scratch));
+		m->scratch.v[0] = m->waitsema;
+		m->scratch.v[1] = (uintptr)&m->ts;
+		m->libcall.args = (uintptr)(uintptr*)&m->scratch;
+		runtime·asmcgocall(runtime·asmsysvicall6, &m->libcall);
+		if(*m->perrno != 0) {
+			if(*m->perrno == ETIMEDOUT || *m->perrno == EAGAIN || *m->perrno == EINTR)
+				return -1;
+			runtime·throw("sem_reltimedwait_np");
+		}
+		return 0;
+	}
+	for(;;) {
+		m->libcall.fn = (uintptr)(void*)libc·sem_wait;
+		m->libcall.n = 1;
+		runtime·memclr((byte*)&m->scratch, sizeof(m->scratch));
+		m->scratch.v[0] = m->waitsema;
+		m->libcall.args = (uintptr)(uintptr*)&m->scratch;
+		runtime·asmcgocall(runtime·asmsysvicall6, &m->libcall);
+		if(m->libcall.r1 == 0)
+			break;
+		if(*m->perrno == EINTR) 
+			continue;
+		runtime·throw("sem_wait");
+	}
+	return 0;
+}
+
+#pragma textflag NOSPLIT
+void
+runtime·semawakeup(M *mp)
+{
+	SemT* sem = (SemT*)mp->waitsema;
+	if(runtime·sem_post(sem) != 0)
+		runtime·throw("sem_post");
+}
+
+#pragma textflag NOSPLIT
+int32
+runtime·close(int32 fd)
+{
+	return runtime·sysvicall1(libc·close, (uintptr)fd);
+}
+
+#pragma textflag NOSPLIT
+void
+runtime·exit(int32 r)
+{
+	runtime·sysvicall1(libc·exit, (uintptr)r);
+}
+
+#pragma textflag NOSPLIT
+/* int32 */ void
+runtime·getcontext(Ucontext* context)
+{
+	runtime·sysvicall1(libc·getcontext, (uintptr)context);
+}
+
+#pragma textflag NOSPLIT
+int32
+runtime·getrlimit(int32 res, Rlimit* rlp)
+{
+	return runtime·sysvicall2(libc·getrlimit, (uintptr)res, (uintptr)rlp);
+}
+
+#pragma textflag NOSPLIT
+uint8*
+runtime·mmap(byte* addr, uintptr len, int32 prot, int32 flags, int32 fildes, uint32 off)
+{
+	return (uint8*)runtime·sysvicall6(libc·mmap, (uintptr)addr, (uintptr)len, (uintptr)prot, (uintptr)flags, (uintptr)fildes, (uintptr)off);
+}
+
+#pragma textflag NOSPLIT
+void
+runtime·munmap(byte* addr, uintptr len)
+{
+	runtime·sysvicall2(libc·munmap, (uintptr)addr, (uintptr)len);
+}
+
+extern int64 runtime·nanotime1(void);
+#pragma textflag NOSPLIT
+int64
+runtime·nanotime(void)
+{
+	return runtime·sysvicall0((uintptr)runtime·nanotime1);
+}
+
+#pragma textflag NOSPLIT
+int32
+runtime·open(int8* path, int32 oflag, int32 mode)
+{
+	return runtime·sysvicall3(libc·open, (uintptr)path, (uintptr)oflag, (uintptr)mode);
+}
+
+int32
+runtime·pthread_attr_destroy(PthreadAttr* attr)
+{
+	return runtime·sysvicall1(libc·pthread_attr_destroy, (uintptr)attr);
+}
+
+int32
+runtime·pthread_attr_getstack(PthreadAttr* attr, void** addr, uint64* size)
+{
+	return runtime·sysvicall3(libc·pthread_attr_getstack, (uintptr)attr, (uintptr)addr, (uintptr)size);
+}
+
+int32
+runtime·pthread_attr_init(PthreadAttr* attr)
+{
+	return runtime·sysvicall1(libc·pthread_attr_init, (uintptr)attr);
+}
+
+int32
+runtime·pthread_attr_setdetachstate(PthreadAttr* attr, int32 state)
+{
+	return runtime·sysvicall2(libc·pthread_attr_setdetachstate, (uintptr)attr, (uintptr)state);
+}
+
+int32
+runtime·pthread_attr_setstack(PthreadAttr* attr, void* addr, uint64 size)
+{
+	return runtime·sysvicall3(libc·pthread_attr_setstack, (uintptr)attr, (uintptr)addr, (uintptr)size);
+}
+
+int32
+runtime·pthread_create(Pthread* thread, PthreadAttr* attr, void(*fn)(void), void *arg)
+{
+	return runtime·sysvicall4(libc·pthread_create, (uintptr)thread, (uintptr)attr, (uintptr)fn, (uintptr)arg);
+}
+
+/* int32 */ void
+runtime·raise(int32 sig)
+{
+	runtime·sysvicall1(libc·raise, (uintptr)sig);
+}
+
+#pragma textflag NOSPLIT
+int32
+runtime·read(int32 fd, void* buf, int32 nbyte)
+{
+	return runtime·sysvicall3(libc·read, (uintptr)fd, (uintptr)buf, (uintptr)nbyte);
+}
+
+#pragma textflag NOSPLIT
+int32
+runtime·sem_init(SemT* sem, int32 pshared, uint32 value)
+{
+	return runtime·sysvicall3(libc·sem_init, (uintptr)sem, (uintptr)pshared, (uintptr)value);
+}
+
+#pragma textflag NOSPLIT
+int32
+runtime·sem_post(SemT* sem)
+{
+	return runtime·sysvicall1(libc·sem_post, (uintptr)sem);
+}
+
+#pragma textflag NOSPLIT
+int32
+runtime·sem_reltimedwait_np(SemT* sem, Timespec* timeout)
+{
+	return runtime·sysvicall2(libc·sem_reltimedwait_np, (uintptr)sem, (uintptr)timeout);
+}
+
+#pragma textflag NOSPLIT
+int32
+runtime·sem_wait(SemT* sem)
+{
+	return runtime·sysvicall1(libc·sem_wait, (uintptr)sem);
+}
+
+/* int32 */ void
+runtime·setitimer(int32 which, Itimerval* value, Itimerval* ovalue)
+{
+	runtime·sysvicall3(libc·setitimer, (uintptr)which, (uintptr)value, (uintptr)ovalue);
+}
+
+/* int32 */ void
+runtime·sigaction(int32 sig, struct SigactionT* act, struct SigactionT* oact)
+{
+	runtime·sysvicall3(libc·sigaction, (uintptr)sig, (uintptr)act, (uintptr)oact);
+}
+
+/* int32 */ void
+runtime·sigaltstack(SigaltstackT* ss, SigaltstackT* oss)
+{
+	runtime·sysvicall2(libc·sigaltstack, (uintptr)ss, (uintptr)oss);
+}
+
+/* int32 */ void
+runtime·sigprocmask(int32 how, Sigset* set, Sigset* oset)
+{
+	runtime·sysvicall3(libc·sigprocmask, (uintptr)how, (uintptr)set, (uintptr)oset);
+}
+
+int64
+runtime·sysconf(int32 name)
+{
+	return runtime·sysvicall1(libc·sysconf, (uintptr)name);
+}
+
+extern void runtime·usleep1(uint32);
+
+#pragma textflag NOSPLIT
+void
+runtime·usleep(uint32 µs)
+{
+	runtime·usleep1(µs);
+}
+
+#pragma textflag NOSPLIT
+int32
+runtime·write(uintptr fd, void* buf, int32 nbyte)
+{
+	return runtime·sysvicall3(libc·write, (uintptr)fd, (uintptr)buf, (uintptr)nbyte);
+}
+
+extern void runtime·osyield1(void);
+
+#pragma textflag NOSPLIT
+void
+runtime·osyield(void)
+{
+	// Check the validity of m because we might be called in cgo callback
+	// path early enough where there isn't a m available yet.
+	if(g && g->m != nil) {
+		runtime·sysvicall0(libc·sched_yield);
+		return;
+	}
+	runtime·osyield1();
+}
+
+#pragma textflag NOSPLIT
+int8*
+runtime·signame(int32 sig)
+{
+	return runtime·sigtab[sig].name;
+}
diff --git a/src/runtime/os_solaris.go b/src/runtime/os_solaris.go
new file mode 100644
index 0000000..ca13151
--- /dev/null
+++ b/src/runtime/os_solaris.go
@@ -0,0 +1,100 @@
+// 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 runtime
+
+import "unsafe"
+
+func setitimer(mode int32, new, old unsafe.Pointer)
+func sigaction(sig int32, new, old unsafe.Pointer)
+func sigaltstack(new, old unsafe.Pointer)
+func sigprocmask(mode int32, new, old unsafe.Pointer)
+func sysctl(mib *uint32, miblen uint32, out *byte, size *uintptr, dst *byte, ndst uintptr) int32
+func getrlimit(kind int32, limit unsafe.Pointer)
+func miniterrno(fn unsafe.Pointer)
+func raise(sig int32)
+func getcontext(ctxt unsafe.Pointer)
+func tstart_sysvicall(mm unsafe.Pointer) uint32
+func nanotime1() int64
+func usleep1(usec uint32)
+func osyield1()
+func netpollinit()
+func netpollopen(fd uintptr, pd *pollDesc) int32
+func netpollclose(fd uintptr) int32
+func netpollarm(pd *pollDesc, mode int)
+
+type libcFunc byte
+
+var asmsysvicall6 libcFunc
+
+//go:nosplit
+func sysvicall0(fn *libcFunc) uintptr {
+	libcall := &getg().m.libcall
+	libcall.fn = uintptr(unsafe.Pointer(fn))
+	libcall.n = 0
+	// TODO(rsc): Why is noescape necessary here and below?
+	libcall.args = uintptr(noescape(unsafe.Pointer(&fn))) // it's unused but must be non-nil, otherwise crashes
+	asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(libcall))
+	return libcall.r1
+}
+
+//go:nosplit
+func sysvicall1(fn *libcFunc, a1 uintptr) uintptr {
+	libcall := &getg().m.libcall
+	libcall.fn = uintptr(unsafe.Pointer(fn))
+	libcall.n = 1
+	libcall.args = uintptr(noescape(unsafe.Pointer(&a1)))
+	asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(libcall))
+	return libcall.r1
+}
+
+//go:nosplit
+func sysvicall2(fn *libcFunc, a1, a2 uintptr) uintptr {
+	libcall := &getg().m.libcall
+	libcall.fn = uintptr(unsafe.Pointer(fn))
+	libcall.n = 2
+	libcall.args = uintptr(noescape(unsafe.Pointer(&a1)))
+	asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(libcall))
+	return libcall.r1
+}
+
+//go:nosplit
+func sysvicall3(fn *libcFunc, a1, a2, a3 uintptr) uintptr {
+	libcall := &getg().m.libcall
+	libcall.fn = uintptr(unsafe.Pointer(fn))
+	libcall.n = 3
+	libcall.args = uintptr(noescape(unsafe.Pointer(&a1)))
+	asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(libcall))
+	return libcall.r1
+}
+
+//go:nosplit
+func sysvicall4(fn *libcFunc, a1, a2, a3, a4 uintptr) uintptr {
+	libcall := &getg().m.libcall
+	libcall.fn = uintptr(unsafe.Pointer(fn))
+	libcall.n = 4
+	libcall.args = uintptr(noescape(unsafe.Pointer(&a1)))
+	asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(libcall))
+	return libcall.r1
+}
+
+//go:nosplit
+func sysvicall5(fn *libcFunc, a1, a2, a3, a4, a5 uintptr) uintptr {
+	libcall := &getg().m.libcall
+	libcall.fn = uintptr(unsafe.Pointer(fn))
+	libcall.n = 5
+	libcall.args = uintptr(noescape(unsafe.Pointer(&a1)))
+	asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(libcall))
+	return libcall.r1
+}
+
+//go:nosplit
+func sysvicall6(fn *libcFunc, a1, a2, a3, a4, a5, a6 uintptr) uintptr {
+	libcall := &getg().m.libcall
+	libcall.fn = uintptr(unsafe.Pointer(fn))
+	libcall.n = 6
+	libcall.args = uintptr(noescape(unsafe.Pointer(&a1)))
+	asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(libcall))
+	return libcall.r1
+}
diff --git a/src/runtime/os_solaris.h b/src/runtime/os_solaris.h
new file mode 100644
index 0000000..3d9e1a2
--- /dev/null
+++ b/src/runtime/os_solaris.h
@@ -0,0 +1,55 @@
+// 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.
+
+
+typedef uintptr kevent_udata;
+
+struct sigaction;
+
+void	runtime·sigpanic(void);
+
+void	runtime·setitimer(int32, Itimerval*, Itimerval*);
+void	runtime·sigaction(int32, struct SigactionT*, struct SigactionT*);
+void	runtime·sigaltstack(SigaltstackT*, SigaltstackT*);
+void	runtime·sigprocmask(int32, Sigset*, Sigset*);
+void	runtime·unblocksignals(void);
+int32	runtime·sysctl(uint32*, uint32, byte*, uintptr*, byte*, uintptr);
+
+
+void	runtime·raisesigpipe(void);
+void	runtime·setsig(int32, void(*)(int32, Siginfo*, void*, G*), bool);
+void	runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp);
+void	runtime·sigpanic(void);
+
+enum {
+	SS_DISABLE = 2,
+	SIG_BLOCK = 1,
+	SIG_UNBLOCK = 2,
+	SIG_SETMASK = 3,
+	NSIG = 73, /* number of signals in runtime·SigTab array */
+	SI_USER = 0,
+	_UC_SIGMASK = 0x01,
+	_UC_CPU = 0x04,
+	RLIMIT_AS = 10,
+};
+
+typedef struct Rlimit Rlimit;
+struct Rlimit {
+	int64   rlim_cur;
+	int64   rlim_max;
+};
+int32   runtime·getrlimit(int32, Rlimit*);
+
+// Call an external library function described by {fn, a0, ..., an}, with
+// SysV conventions, switching to os stack during the call, if necessary.
+uintptr	runtime·sysvicall0(uintptr fn);
+uintptr	runtime·sysvicall1(uintptr fn, uintptr a1);
+uintptr	runtime·sysvicall2(uintptr fn, uintptr a1, uintptr a2);
+uintptr	runtime·sysvicall3(uintptr fn, uintptr a1, uintptr a2, uintptr a3);
+uintptr	runtime·sysvicall4(uintptr fn, uintptr a1, uintptr a2, uintptr a3, uintptr a4);
+uintptr	runtime·sysvicall5(uintptr fn, uintptr a1, uintptr a2, uintptr a3, uintptr a4, uintptr a5);
+uintptr	runtime·sysvicall6(uintptr fn, uintptr a1, uintptr a2, uintptr a3, uintptr a4, uintptr a5, uintptr a6);
+void	runtime·asmsysvicall6(void *c);
+
+void	runtime·miniterrno(void *fn);
diff --git a/src/runtime/os_windows.c b/src/runtime/os_windows.c
new file mode 100644
index 0000000..b8b8eda
--- /dev/null
+++ b/src/runtime/os_windows.c
@@ -0,0 +1,636 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "runtime.h"
+#include "type.h"
+#include "defs_GOOS_GOARCH.h"
+#include "os_GOOS.h"
+#include "textflag.h"
+#include "arch_GOARCH.h"
+#include "malloc.h"
+
+#pragma dynimport runtime·AddVectoredExceptionHandler AddVectoredExceptionHandler "kernel32.dll"
+#pragma dynimport runtime·CloseHandle CloseHandle "kernel32.dll"
+#pragma dynimport runtime·CreateEvent CreateEventA "kernel32.dll"
+#pragma dynimport runtime·CreateThread CreateThread "kernel32.dll"
+#pragma dynimport runtime·CreateWaitableTimer CreateWaitableTimerA "kernel32.dll"
+#pragma dynimport runtime·CryptAcquireContextW CryptAcquireContextW "advapi32.dll"
+#pragma dynimport runtime·CryptGenRandom CryptGenRandom "advapi32.dll"
+#pragma dynimport runtime·CryptReleaseContext CryptReleaseContext "advapi32.dll"
+#pragma dynimport runtime·DuplicateHandle DuplicateHandle "kernel32.dll"
+#pragma dynimport runtime·ExitProcess ExitProcess "kernel32.dll"
+#pragma dynimport runtime·FreeEnvironmentStringsW FreeEnvironmentStringsW "kernel32.dll"
+#pragma dynimport runtime·GetEnvironmentStringsW GetEnvironmentStringsW "kernel32.dll"
+#pragma dynimport runtime·GetProcAddress GetProcAddress "kernel32.dll"
+#pragma dynimport runtime·GetStdHandle GetStdHandle "kernel32.dll"
+#pragma dynimport runtime·GetSystemInfo GetSystemInfo "kernel32.dll"
+#pragma dynimport runtime·GetThreadContext GetThreadContext "kernel32.dll"
+#pragma dynimport runtime·LoadLibrary LoadLibraryW "kernel32.dll"
+#pragma dynimport runtime·LoadLibraryA LoadLibraryA "kernel32.dll"
+#pragma dynimport runtime·NtWaitForSingleObject NtWaitForSingleObject "ntdll.dll"
+#pragma dynimport runtime·ResumeThread ResumeThread "kernel32.dll"
+#pragma dynimport runtime·SetConsoleCtrlHandler SetConsoleCtrlHandler "kernel32.dll"
+#pragma dynimport runtime·SetEvent SetEvent "kernel32.dll"
+#pragma dynimport runtime·SetProcessPriorityBoost SetProcessPriorityBoost "kernel32.dll"
+#pragma dynimport runtime·SetThreadPriority SetThreadPriority "kernel32.dll"
+#pragma dynimport runtime·SetUnhandledExceptionFilter SetUnhandledExceptionFilter "kernel32.dll"
+#pragma dynimport runtime·SetWaitableTimer SetWaitableTimer "kernel32.dll"
+#pragma dynimport runtime·Sleep Sleep "kernel32.dll"
+#pragma dynimport runtime·SuspendThread SuspendThread "kernel32.dll"
+#pragma dynimport runtime·WaitForSingleObject WaitForSingleObject "kernel32.dll"
+#pragma dynimport runtime·WriteFile WriteFile "kernel32.dll"
+#pragma dynimport runtime·timeBeginPeriod timeBeginPeriod "winmm.dll"
+
+extern void *runtime·AddVectoredExceptionHandler;
+extern void *runtime·CloseHandle;
+extern void *runtime·CreateEvent;
+extern void *runtime·CreateThread;
+extern void *runtime·CreateWaitableTimer;
+extern void *runtime·CryptAcquireContextW;
+extern void *runtime·CryptGenRandom;
+extern void *runtime·CryptReleaseContext;
+extern void *runtime·DuplicateHandle;
+extern void *runtime·ExitProcess;
+extern void *runtime·FreeEnvironmentStringsW;
+extern void *runtime·GetEnvironmentStringsW;
+extern void *runtime·GetProcAddress;
+extern void *runtime·GetStdHandle;
+extern void *runtime·GetSystemInfo;
+extern void *runtime·GetThreadContext;
+extern void *runtime·LoadLibrary;
+extern void *runtime·LoadLibraryA;
+extern void *runtime·NtWaitForSingleObject;
+extern void *runtime·ResumeThread;
+extern void *runtime·SetConsoleCtrlHandler;
+extern void *runtime·SetEvent;
+extern void *runtime·SetProcessPriorityBoost;
+extern void *runtime·SetThreadPriority;
+extern void *runtime·SetUnhandledExceptionFilter;
+extern void *runtime·SetWaitableTimer;
+extern void *runtime·Sleep;
+extern void *runtime·SuspendThread;
+extern void *runtime·WaitForSingleObject;
+extern void *runtime·WriteFile;
+extern void *runtime·timeBeginPeriod;
+
+#pragma dataflag NOPTR
+void *runtime·GetQueuedCompletionStatusEx;
+
+extern uintptr runtime·externalthreadhandlerp;
+void runtime·externalthreadhandler(void);
+void runtime·exceptiontramp(void);
+void runtime·firstcontinuetramp(void);
+void runtime·lastcontinuetramp(void);
+
+#pragma textflag NOSPLIT
+uintptr
+runtime·getLoadLibrary(void)
+{
+	return (uintptr)runtime·LoadLibrary;
+}
+
+#pragma textflag NOSPLIT
+uintptr
+runtime·getGetProcAddress(void)
+{
+	return (uintptr)runtime·GetProcAddress;
+}
+
+static int32
+getproccount(void)
+{
+	SystemInfo info;
+
+	runtime·stdcall1(runtime·GetSystemInfo, (uintptr)&info);
+	return info.dwNumberOfProcessors;
+}
+
+void
+runtime·osinit(void)
+{
+	void *kernel32;
+	void *addVectoredContinueHandler;
+
+	kernel32 = runtime·stdcall1(runtime·LoadLibraryA, (uintptr)"kernel32.dll");
+
+	runtime·externalthreadhandlerp = (uintptr)runtime·externalthreadhandler;
+
+	runtime·stdcall2(runtime·AddVectoredExceptionHandler, 1, (uintptr)runtime·exceptiontramp);
+	addVectoredContinueHandler = nil;
+	if(kernel32 != nil)
+		addVectoredContinueHandler = runtime·stdcall2(runtime·GetProcAddress, (uintptr)kernel32, (uintptr)"AddVectoredContinueHandler");
+	if(addVectoredContinueHandler == nil || sizeof(void*) == 4) {
+		// use SetUnhandledExceptionFilter for windows-386 or
+		// if VectoredContinueHandler is unavailable.
+		// note: SetUnhandledExceptionFilter handler won't be called, if debugging.
+		runtime·stdcall1(runtime·SetUnhandledExceptionFilter, (uintptr)runtime·lastcontinuetramp);
+	} else {
+		runtime·stdcall2(addVectoredContinueHandler, 1, (uintptr)runtime·firstcontinuetramp);
+		runtime·stdcall2(addVectoredContinueHandler, 0, (uintptr)runtime·lastcontinuetramp);
+	}
+
+	runtime·stdcall2(runtime·SetConsoleCtrlHandler, (uintptr)runtime·ctrlhandler, 1);
+
+	runtime·stdcall1(runtime·timeBeginPeriod, 1);
+
+	runtime·ncpu = getproccount();
+	
+	// Windows dynamic priority boosting assumes that a process has different types
+	// of dedicated threads -- GUI, IO, computational, etc. Go processes use
+	// equivalent threads that all do a mix of GUI, IO, computations, etc.
+	// In such context dynamic priority boosting does nothing but harm, so we turn it off.
+	runtime·stdcall2(runtime·SetProcessPriorityBoost, -1, 1);
+
+	if(kernel32 != nil) {
+		runtime·GetQueuedCompletionStatusEx = runtime·stdcall2(runtime·GetProcAddress, (uintptr)kernel32, (uintptr)"GetQueuedCompletionStatusEx");
+	}
+}
+
+#pragma textflag NOSPLIT
+void
+runtime·get_random_data(byte **rnd, int32 *rnd_len)
+{
+	uintptr handle;
+	*rnd = nil;
+	*rnd_len = 0;
+	if(runtime·stdcall5(runtime·CryptAcquireContextW, (uintptr)&handle, (uintptr)nil, (uintptr)nil,
+			   1 /* PROV_RSA_FULL */,
+			   0xf0000000U /* CRYPT_VERIFYCONTEXT */) != 0) {
+		static byte random_data[HashRandomBytes];
+		if(runtime·stdcall3(runtime·CryptGenRandom, handle, HashRandomBytes, (uintptr)&random_data[0])) {
+			*rnd = random_data;
+			*rnd_len = HashRandomBytes;
+		}
+		runtime·stdcall2(runtime·CryptReleaseContext, handle, 0);
+	}
+}
+
+void
+runtime·goenvs(void)
+{
+	extern Slice runtime·envs;
+
+	uint16 *env;
+	String *s;
+	int32 i, n;
+	uint16 *p;
+
+	env = runtime·stdcall0(runtime·GetEnvironmentStringsW);
+
+	n = 0;
+	for(p=env; *p; n++)
+		p += runtime·findnullw(p)+1;
+
+	runtime·envs = runtime·makeStringSlice(n);
+	s = (String*)runtime·envs.array;
+
+	p = env;
+	for(i=0; i<n; i++) {
+		s[i] = runtime·gostringw(p);
+		p += runtime·findnullw(p)+1;
+	}
+
+	runtime·stdcall1(runtime·FreeEnvironmentStringsW, (uintptr)env);
+}
+
+#pragma textflag NOSPLIT
+void
+runtime·exit(int32 code)
+{
+	runtime·stdcall1(runtime·ExitProcess, code);
+}
+
+#pragma textflag NOSPLIT
+int32
+runtime·write(uintptr fd, void *buf, int32 n)
+{
+	void *handle;
+	uint32 written;
+
+	written = 0;
+	switch(fd) {
+	case 1:
+		handle = runtime·stdcall1(runtime·GetStdHandle, -11);
+		break;
+	case 2:
+		handle = runtime·stdcall1(runtime·GetStdHandle, -12);
+		break;
+	default:
+		// assume fd is real windows handle.
+		handle = (void*)fd;
+		break;
+	}
+	runtime·stdcall5(runtime·WriteFile, (uintptr)handle, (uintptr)buf, n, (uintptr)&written, 0);
+	return written;
+}
+
+#define INFINITE ((uintptr)0xFFFFFFFF)
+
+#pragma textflag NOSPLIT
+int32
+runtime·semasleep(int64 ns)
+{
+	// store ms in ns to save stack space
+	if(ns < 0)
+		ns = INFINITE;
+	else {
+		ns = runtime·timediv(ns, 1000000, nil);
+		if(ns == 0)
+			ns = 1;
+	}
+	if(runtime·stdcall2(runtime·WaitForSingleObject, (uintptr)g->m->waitsema, ns) != 0)
+		return -1;  // timeout
+	return 0;
+}
+
+#pragma textflag NOSPLIT
+void
+runtime·semawakeup(M *mp)
+{
+	runtime·stdcall1(runtime·SetEvent, mp->waitsema);
+}
+
+#pragma textflag NOSPLIT
+uintptr
+runtime·semacreate(void)
+{
+	return (uintptr)runtime·stdcall4(runtime·CreateEvent, 0, 0, 0, 0);
+}
+
+#define STACK_SIZE_PARAM_IS_A_RESERVATION ((uintptr)0x00010000)
+
+void
+runtime·newosproc(M *mp, void *stk)
+{
+	void *thandle;
+
+	USED(stk);
+
+	thandle = runtime·stdcall6(runtime·CreateThread,
+		(uintptr)nil, 0x20000, (uintptr)runtime·tstart_stdcall, (uintptr)mp,
+		STACK_SIZE_PARAM_IS_A_RESERVATION, (uintptr)nil);
+	if(thandle == nil) {
+		runtime·printf("runtime: failed to create new OS thread (have %d already; errno=%d)\n", runtime·mcount(), runtime·getlasterror());
+		runtime·throw("runtime.newosproc");
+	}
+}
+
+// Called to initialize a new m (including the bootstrap m).
+// Called on the parent thread (main thread in case of bootstrap), can allocate memory.
+void
+runtime·mpreinit(M *mp)
+{
+	USED(mp);
+}
+
+// Called to initialize a new m (including the bootstrap m).
+// Called on the new thread, can not allocate memory.
+void
+runtime·minit(void)
+{
+	uintptr thandle;
+
+	// -1 = current process, -2 = current thread
+	runtime·stdcall7(runtime·DuplicateHandle, -1, -2, -1, (uintptr)&thandle, 0, 0, DUPLICATE_SAME_ACCESS);
+	runtime·atomicstoreuintptr(&g->m->thread, thandle);
+}
+
+// Called from dropm to undo the effect of an minit.
+void
+runtime·unminit(void)
+{
+	runtime·stdcall1(runtime·CloseHandle, g->m->thread);
+	g->m->thread = 0;
+}
+
+// Described in http://www.dcl.hpi.uni-potsdam.de/research/WRK/2007/08/getting-os-information-the-kuser_shared_data-structure/
+typedef struct KSYSTEM_TIME {
+	uint32	LowPart;
+	int32	High1Time;
+	int32	High2Time;
+} KSYSTEM_TIME;
+
+#pragma dataflag NOPTR
+const KSYSTEM_TIME* INTERRUPT_TIME	= (KSYSTEM_TIME*)0x7ffe0008;
+#pragma dataflag NOPTR
+const KSYSTEM_TIME* SYSTEM_TIME		= (KSYSTEM_TIME*)0x7ffe0014;
+
+static void badsystime(void);
+
+#pragma textflag NOSPLIT
+int64
+runtime·systime(KSYSTEM_TIME *timeaddr)
+{
+	KSYSTEM_TIME t;
+	int32 i;
+	void (*fn)(void);
+
+	for(i = 1; i < 10000; i++) {
+		// these fields must be read in that order (see URL above)
+		t.High1Time = timeaddr->High1Time;
+		t.LowPart = timeaddr->LowPart;
+		t.High2Time = timeaddr->High2Time;
+		if(t.High1Time == t.High2Time)
+			return (int64)t.High1Time<<32 | t.LowPart;
+		if((i%100) == 0)
+			runtime·osyield();
+	}
+	fn = badsystime;
+	runtime·onM(&fn);
+	return 0;
+}
+
+#pragma textflag NOSPLIT
+int64
+runtime·unixnano(void)
+{
+	return (runtime·systime(SYSTEM_TIME) - 116444736000000000LL) * 100LL;
+}
+
+static void
+badsystime(void)
+{
+	runtime·throw("interrupt/system time is changing too fast");
+}
+
+#pragma textflag NOSPLIT
+int64
+runtime·nanotime(void)
+{
+	return runtime·systime(INTERRUPT_TIME) * 100LL;
+}
+
+// Calling stdcall on os stack.
+#pragma textflag NOSPLIT
+static void*
+stdcall(void *fn)
+{
+	g->m->libcall.fn = (uintptr)fn;
+	if(g->m->profilehz != 0) {
+		// leave pc/sp for cpu profiler
+		g->m->libcallg = g;
+		g->m->libcallpc = (uintptr)runtime·getcallerpc(&fn);
+		// sp must be the last, because once async cpu profiler finds
+		// all three values to be non-zero, it will use them
+		g->m->libcallsp = (uintptr)runtime·getcallersp(&fn);
+	}
+	runtime·asmcgocall(runtime·asmstdcall, &g->m->libcall);
+	g->m->libcallsp = 0;
+	return (void*)g->m->libcall.r1;
+}
+
+#pragma textflag NOSPLIT
+void*
+runtime·stdcall0(void *fn)
+{
+	g->m->libcall.n = 0;
+	g->m->libcall.args = (uintptr)&fn;  // it's unused but must be non-nil, otherwise crashes
+	return stdcall(fn);
+}
+
+#pragma textflag NOSPLIT
+void*
+runtime·stdcall1(void *fn, uintptr a0)
+{
+	USED(a0);
+	g->m->libcall.n = 1;
+	g->m->libcall.args = (uintptr)&a0;
+	return stdcall(fn);
+}
+
+#pragma textflag NOSPLIT
+void*
+runtime·stdcall2(void *fn, uintptr a0, uintptr a1)
+{
+	USED(a0, a1);
+	g->m->libcall.n = 2;
+	g->m->libcall.args = (uintptr)&a0;
+	return stdcall(fn);
+}
+
+#pragma textflag NOSPLIT
+void*
+runtime·stdcall3(void *fn, uintptr a0, uintptr a1, uintptr a2)
+{
+	USED(a0, a1, a2);
+	g->m->libcall.n = 3;
+	g->m->libcall.args = (uintptr)&a0;
+	return stdcall(fn);
+}
+
+#pragma textflag NOSPLIT
+void*
+runtime·stdcall4(void *fn, uintptr a0, uintptr a1, uintptr a2, uintptr a3)
+{
+	USED(a0, a1, a2, a3);
+	g->m->libcall.n = 4;
+	g->m->libcall.args = (uintptr)&a0;
+	return stdcall(fn);
+}
+
+#pragma textflag NOSPLIT
+void*
+runtime·stdcall5(void *fn, uintptr a0, uintptr a1, uintptr a2, uintptr a3, uintptr a4)
+{
+	USED(a0, a1, a2, a3, a4);
+	g->m->libcall.n = 5;
+	g->m->libcall.args = (uintptr)&a0;
+	return stdcall(fn);
+}
+
+#pragma textflag NOSPLIT
+void*
+runtime·stdcall6(void *fn, uintptr a0, uintptr a1, uintptr a2, uintptr a3, uintptr a4, uintptr a5)
+{
+	USED(a0, a1, a2, a3, a4, a5);
+	g->m->libcall.n = 6;
+	g->m->libcall.args = (uintptr)&a0;
+	return stdcall(fn);
+}
+
+#pragma textflag NOSPLIT
+void*
+runtime·stdcall7(void *fn, uintptr a0, uintptr a1, uintptr a2, uintptr a3, uintptr a4, uintptr a5, uintptr a6)
+{
+	USED(a0, a1, a2, a3, a4, a5, a6);
+	g->m->libcall.n = 7;
+	g->m->libcall.args = (uintptr)&a0;
+	return stdcall(fn);
+}
+
+extern void runtime·usleep1(uint32);
+
+#pragma textflag NOSPLIT
+void
+runtime·osyield(void)
+{
+	runtime·usleep1(1);
+}
+
+#pragma textflag NOSPLIT
+void
+runtime·usleep(uint32 us)
+{
+	// Have 1us units; want 100ns units.
+	runtime·usleep1(10*us);
+}
+
+uint32
+runtime·issigpanic(uint32 code)
+{
+	switch(code) {
+	case EXCEPTION_ACCESS_VIOLATION:
+	case EXCEPTION_INT_DIVIDE_BY_ZERO:
+	case EXCEPTION_INT_OVERFLOW:
+	case EXCEPTION_FLT_DENORMAL_OPERAND:
+	case EXCEPTION_FLT_DIVIDE_BY_ZERO:
+	case EXCEPTION_FLT_INEXACT_RESULT:
+	case EXCEPTION_FLT_OVERFLOW:
+	case EXCEPTION_FLT_UNDERFLOW:
+	case EXCEPTION_BREAKPOINT:
+		return 1;
+	}
+	return 0;
+}
+
+void
+runtime·initsig(void)
+{
+	// following line keeps these functions alive at link stage
+	// if there's a better way please write it here
+	void *e = runtime·exceptiontramp;
+	void *f = runtime·firstcontinuetramp;
+	void *l = runtime·lastcontinuetramp;
+	USED(e);
+	USED(f);
+	USED(l);
+}
+
+uint32
+runtime·ctrlhandler1(uint32 type)
+{
+	int32 s;
+
+	switch(type) {
+	case CTRL_C_EVENT:
+	case CTRL_BREAK_EVENT:
+		s = SIGINT;
+		break;
+	default:
+		return 0;
+	}
+
+	if(runtime·sigsend(s))
+		return 1;
+	runtime·exit(2);	// SIGINT, SIGTERM, etc
+	return 0;
+}
+
+extern void runtime·dosigprof(Context *r, G *gp, M *mp);
+extern void runtime·profileloop(void);
+#pragma dataflag NOPTR
+static void *profiletimer;
+
+static void
+profilem(M *mp)
+{
+	extern M runtime·m0;
+	extern uint32 runtime·tls0[];
+	byte rbuf[sizeof(Context)+15];
+	Context *r;
+	void *tls;
+	G *gp;
+
+	tls = mp->tls;
+	if(mp == &runtime·m0)
+		tls = runtime·tls0;
+	gp = *(G**)tls;
+
+	// align Context to 16 bytes
+	r = (Context*)((uintptr)(&rbuf[15]) & ~15);
+	r->ContextFlags = CONTEXT_CONTROL;
+	runtime·stdcall2(runtime·GetThreadContext, (uintptr)mp->thread, (uintptr)r);
+	runtime·dosigprof(r, gp, mp);
+}
+
+void
+runtime·profileloop1(void)
+{
+	M *mp, *allm;
+	uintptr thread;
+
+	runtime·stdcall2(runtime·SetThreadPriority, -2, THREAD_PRIORITY_HIGHEST);
+
+	for(;;) {
+		runtime·stdcall2(runtime·WaitForSingleObject, (uintptr)profiletimer, -1);
+		allm = runtime·atomicloadp(&runtime·allm);
+		for(mp = allm; mp != nil; mp = mp->alllink) {
+			thread = runtime·atomicloaduintptr(&mp->thread);
+			// Do not profile threads blocked on Notes,
+			// this includes idle worker threads,
+			// idle timer thread, idle heap scavenger, etc.
+			if(thread == 0 || mp->profilehz == 0 || mp->blocked)
+				continue;
+			runtime·stdcall1(runtime·SuspendThread, (uintptr)thread);
+			if(mp->profilehz != 0 && !mp->blocked)
+				profilem(mp);
+			runtime·stdcall1(runtime·ResumeThread, (uintptr)thread);
+		}
+	}
+}
+
+void
+runtime·resetcpuprofiler(int32 hz)
+{
+	static Mutex lock;
+	void *timer, *thread;
+	int32 ms;
+	int64 due;
+
+	runtime·lock(&lock);
+	if(profiletimer == nil) {
+		timer = runtime·stdcall3(runtime·CreateWaitableTimer, (uintptr)nil, (uintptr)nil, (uintptr)nil);
+		runtime·atomicstorep(&profiletimer, timer);
+		thread = runtime·stdcall6(runtime·CreateThread,
+			(uintptr)nil, (uintptr)nil, (uintptr)runtime·profileloop, (uintptr)nil, (uintptr)nil, (uintptr)nil);
+		runtime·stdcall2(runtime·SetThreadPriority, (uintptr)thread, THREAD_PRIORITY_HIGHEST);
+		runtime·stdcall1(runtime·CloseHandle, (uintptr)thread);
+	}
+	runtime·unlock(&lock);
+
+	ms = 0;
+	due = 1LL<<63;
+	if(hz > 0) {
+		ms = 1000 / hz;
+		if(ms == 0)
+			ms = 1;
+		due = ms * -10000;
+	}
+	runtime·stdcall6(runtime·SetWaitableTimer,
+		(uintptr)profiletimer, (uintptr)&due, ms, (uintptr)nil, (uintptr)nil, (uintptr)nil);
+	runtime·atomicstore((uint32*)&g->m->profilehz, hz);
+}
+
+uintptr
+runtime·memlimit(void)
+{
+	return 0;
+}
+
+#pragma dataflag NOPTR
+int8 runtime·badsignalmsg[] = "runtime: signal received on thread not created by Go.\n";
+int32 runtime·badsignallen = sizeof runtime·badsignalmsg - 1;
+
+void
+runtime·crash(void)
+{
+	// TODO: This routine should do whatever is needed
+	// to make the Windows program abort/crash as it
+	// would if Go was not intercepting signals.
+	// On Unix the routine would remove the custom signal
+	// handler and then raise a signal (like SIGABRT).
+	// Something like that should happen here.
+	// It's okay to leave this empty for now: if crash returns
+	// the ordinary exit-after-panic happens.
+}
diff --git a/src/runtime/os_windows.go b/src/runtime/os_windows.go
new file mode 100644
index 0000000..1528d2f
--- /dev/null
+++ b/src/runtime/os_windows.go
@@ -0,0 +1,58 @@
+// 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 runtime
+
+import "unsafe"
+
+type stdFunction *byte
+
+func stdcall0(fn stdFunction) uintptr
+func stdcall1(fn stdFunction, a0 uintptr) uintptr
+func stdcall2(fn stdFunction, a0, a1 uintptr) uintptr
+func stdcall3(fn stdFunction, a0, a1, a2 uintptr) uintptr
+func stdcall4(fn stdFunction, a0, a1, a2, a3 uintptr) uintptr
+func stdcall5(fn stdFunction, a0, a1, a2, a3, a4 uintptr) uintptr
+func stdcall6(fn stdFunction, a0, a1, a2, a3, a4, a5 uintptr) uintptr
+func stdcall7(fn stdFunction, a0, a1, a2, a3, a4, a5, a6 uintptr) uintptr
+
+func asmstdcall(fn unsafe.Pointer)
+func getlasterror() uint32
+func setlasterror(err uint32)
+func usleep1(usec uint32)
+func netpollinit()
+func netpollopen(fd uintptr, pd *pollDesc) int32
+func netpollclose(fd uintptr) int32
+func netpollarm(pd *pollDesc, mode int)
+
+func os_sigpipe() {
+	gothrow("too many writes on closed pipe")
+}
+
+func sigpanic() {
+	g := getg()
+	if !canpanic(g) {
+		gothrow("unexpected signal during runtime execution")
+	}
+
+	switch uint32(g.sig) {
+	case _EXCEPTION_ACCESS_VIOLATION:
+		if g.sigcode1 < 0x1000 || g.paniconfault {
+			panicmem()
+		}
+		print("unexpected fault address ", hex(g.sigcode1), "\n")
+		gothrow("fault")
+	case _EXCEPTION_INT_DIVIDE_BY_ZERO:
+		panicdivide()
+	case _EXCEPTION_INT_OVERFLOW:
+		panicoverflow()
+	case _EXCEPTION_FLT_DENORMAL_OPERAND,
+		_EXCEPTION_FLT_DIVIDE_BY_ZERO,
+		_EXCEPTION_FLT_INEXACT_RESULT,
+		_EXCEPTION_FLT_OVERFLOW,
+		_EXCEPTION_FLT_UNDERFLOW:
+		panicfloat()
+	}
+	gothrow("fault")
+}
diff --git a/src/runtime/os_windows.h b/src/runtime/os_windows.h
new file mode 100644
index 0000000..d5d168d
--- /dev/null
+++ b/src/runtime/os_windows.h
@@ -0,0 +1,42 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+extern void *runtime·LoadLibrary;
+extern void *runtime·GetProcAddress;
+extern void *runtime·GetQueuedCompletionStatusEx;
+
+// Call a Windows function with stdcall conventions,
+// and switch to os stack during the call.
+void runtime·asmstdcall(void *c);
+void *runtime·stdcall0(void *fn);
+void *runtime·stdcall1(void *fn, uintptr a0);
+void *runtime·stdcall2(void *fn, uintptr a0, uintptr a1);
+void *runtime·stdcall3(void *fn, uintptr a0, uintptr a1, uintptr a2);
+void *runtime·stdcall4(void *fn, uintptr a0, uintptr a1, uintptr a2, uintptr a3);
+void *runtime·stdcall5(void *fn, uintptr a0, uintptr a1, uintptr a2, uintptr a3, uintptr a4);
+void *runtime·stdcall6(void *fn, uintptr a0, uintptr a1, uintptr a2, uintptr a3, uintptr a4, uintptr a5);
+void *runtime·stdcall7(void *fn, uintptr a0, uintptr a1, uintptr a2, uintptr a3, uintptr a4, uintptr a5, uintptr a6);
+
+uint32 runtime·getlasterror(void);
+void runtime·setlasterror(uint32 err);
+
+// Function to be called by windows CreateThread
+// to start new os thread.
+uint32 runtime·tstart_stdcall(M *newm);
+
+uint32 runtime·issigpanic(uint32);
+void runtime·sigpanic(void);
+uint32 runtime·ctrlhandler(uint32 type);
+
+// Windows dll function to go callback entry.
+byte *runtime·compilecallback(Eface fn, bool cleanstack);
+void *runtime·callbackasm(void);
+
+void runtime·install_exception_handler(void);
+void runtime·remove_exception_handler(void);
+
+// TODO(brainman): should not need those
+enum {
+	NSIG = 65,
+};
diff --git a/src/runtime/os_windows_386.c b/src/runtime/os_windows_386.c
new file mode 100644
index 0000000..9962f0d
--- /dev/null
+++ b/src/runtime/os_windows_386.c
@@ -0,0 +1,128 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "runtime.h"
+#include "defs_GOOS_GOARCH.h"
+#include "os_GOOS.h"
+
+void
+runtime·dumpregs(Context *r)
+{
+	runtime·printf("eax     %x\n", r->Eax);
+	runtime·printf("ebx     %x\n", r->Ebx);
+	runtime·printf("ecx     %x\n", r->Ecx);
+	runtime·printf("edx     %x\n", r->Edx);
+	runtime·printf("edi     %x\n", r->Edi);
+	runtime·printf("esi     %x\n", r->Esi);
+	runtime·printf("ebp     %x\n", r->Ebp);
+	runtime·printf("esp     %x\n", r->Esp);
+	runtime·printf("eip     %x\n", r->Eip);
+	runtime·printf("eflags  %x\n", r->EFlags);
+	runtime·printf("cs      %x\n", r->SegCs);
+	runtime·printf("fs      %x\n", r->SegFs);
+	runtime·printf("gs      %x\n", r->SegGs);
+}
+
+bool
+runtime·isgoexception(ExceptionRecord *info, Context *r)
+{
+	extern byte runtime·text[], runtime·etext[];
+
+	// Only handle exception if executing instructions in Go binary
+	// (not Windows library code). 
+	if(r->Eip < (uint32)runtime·text || (uint32)runtime·etext < r->Eip)
+		return false;
+
+	if(!runtime·issigpanic(info->ExceptionCode))
+		return false;
+
+	return true;
+}
+
+// Called by sigtramp from Windows VEH handler.
+// Return value signals whether the exception has been handled (EXCEPTION_CONTINUE_EXECUTION)
+// or should be made available to other handlers in the chain (EXCEPTION_CONTINUE_SEARCH).
+uint32
+runtime·exceptionhandler(ExceptionRecord *info, Context *r, G *gp)
+{
+	uintptr *sp;
+
+	if(!runtime·isgoexception(info, r))
+		return EXCEPTION_CONTINUE_SEARCH;
+
+	// Make it look like a call to the signal func.
+	// Have to pass arguments out of band since
+	// augmenting the stack frame would break
+	// the unwinding code.
+	gp->sig = info->ExceptionCode;
+	gp->sigcode0 = info->ExceptionInformation[0];
+	gp->sigcode1 = info->ExceptionInformation[1];
+	gp->sigpc = r->Eip;
+
+	// Only push runtime·sigpanic if r->eip != 0.
+	// If r->eip == 0, probably panicked because of a
+	// call to a nil func.  Not pushing that onto sp will
+	// make the trace look like a call to runtime·sigpanic instead.
+	// (Otherwise the trace will end at runtime·sigpanic and we
+	// won't get to see who faulted.)
+	if(r->Eip != 0) {
+		sp = (uintptr*)r->Esp;
+		*--sp = r->Eip;
+		r->Esp = (uintptr)sp;
+	}
+	r->Eip = (uintptr)runtime·sigpanic;
+	return EXCEPTION_CONTINUE_EXECUTION;
+}
+
+// lastcontinuehandler is reached, because runtime cannot handle
+// current exception. lastcontinuehandler will print crash info and exit.
+uint32
+runtime·lastcontinuehandler(ExceptionRecord *info, Context *r, G *gp)
+{
+	bool crash;
+
+	if(runtime·panicking)	// traceback already printed
+		runtime·exit(2);
+	runtime·panicking = 1;
+
+	runtime·printf("Exception %x %p %p %p\n", info->ExceptionCode,
+		(uintptr)info->ExceptionInformation[0], (uintptr)info->ExceptionInformation[1], (uintptr)r->Eip);
+
+	runtime·printf("PC=%x\n", r->Eip);
+	if(g->m->lockedg != nil && g->m->ncgo > 0 && gp == g->m->g0) {
+		runtime·printf("signal arrived during cgo execution\n");
+		gp = g->m->lockedg;
+	}
+	runtime·printf("\n");
+
+	if(runtime·gotraceback(&crash)){
+		runtime·tracebacktrap(r->Eip, r->Esp, 0, gp);
+		runtime·tracebackothers(gp);
+		runtime·dumpregs(r);
+	}
+	
+	if(crash)
+		runtime·crash();
+
+	runtime·exit(2);
+	return 0; // not reached
+}
+
+void
+runtime·sigenable(uint32 sig)
+{
+	USED(sig);
+}
+
+void
+runtime·sigdisable(uint32 sig)
+{
+	USED(sig);
+}
+
+void
+runtime·dosigprof(Context *r, G *gp, M *mp)
+{
+	runtime·sigprof((uint8*)r->Eip, (uint8*)r->Esp, nil, gp, mp);
+}
diff --git a/src/runtime/os_windows_386.go b/src/runtime/os_windows_386.go
new file mode 100644
index 0000000..86a1906
--- /dev/null
+++ b/src/runtime/os_windows_386.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 runtime
+
+// contextPC returns the EIP (program counter) register from the context.
+func contextPC(r *context) uintptr { return uintptr(r.eip) }
+
+// contextSP returns the ESP (stack pointer) register from the context.
+func contextSP(r *context) uintptr { return uintptr(r.esp) }
diff --git a/src/runtime/os_windows_amd64.c b/src/runtime/os_windows_amd64.c
new file mode 100644
index 0000000..e4617e4
--- /dev/null
+++ b/src/runtime/os_windows_amd64.c
@@ -0,0 +1,150 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "runtime.h"
+#include "defs_GOOS_GOARCH.h"
+#include "os_GOOS.h"
+
+void
+runtime·dumpregs(Context *r)
+{
+	runtime·printf("rax     %X\n", r->Rax);
+	runtime·printf("rbx     %X\n", r->Rbx);
+	runtime·printf("rcx     %X\n", r->Rcx);
+	runtime·printf("rdx     %X\n", r->Rdx);
+	runtime·printf("rdi     %X\n", r->Rdi);
+	runtime·printf("rsi     %X\n", r->Rsi);
+	runtime·printf("rbp     %X\n", r->Rbp);
+	runtime·printf("rsp     %X\n", r->Rsp);
+	runtime·printf("r8      %X\n", r->R8 );
+	runtime·printf("r9      %X\n", r->R9 );
+	runtime·printf("r10     %X\n", r->R10);
+	runtime·printf("r11     %X\n", r->R11);
+	runtime·printf("r12     %X\n", r->R12);
+	runtime·printf("r13     %X\n", r->R13);
+	runtime·printf("r14     %X\n", r->R14);
+	runtime·printf("r15     %X\n", r->R15);
+	runtime·printf("rip     %X\n", r->Rip);
+	runtime·printf("rflags  %X\n", r->EFlags);
+	runtime·printf("cs      %X\n", (uint64)r->SegCs);
+	runtime·printf("fs      %X\n", (uint64)r->SegFs);
+	runtime·printf("gs      %X\n", (uint64)r->SegGs);
+}
+
+bool
+runtime·isgoexception(ExceptionRecord *info, Context *r)
+{
+	extern byte runtime·text[], runtime·etext[];
+
+	// Only handle exception if executing instructions in Go binary
+	// (not Windows library code). 
+	if(r->Rip < (uint64)runtime·text || (uint64)runtime·etext < r->Rip)
+		return false;
+
+	if(!runtime·issigpanic(info->ExceptionCode))
+		return false;
+
+	return true;
+}
+
+// Called by sigtramp from Windows VEH handler.
+// Return value signals whether the exception has been handled (EXCEPTION_CONTINUE_EXECUTION)
+// or should be made available to other handlers in the chain (EXCEPTION_CONTINUE_SEARCH).
+uint32
+runtime·exceptionhandler(ExceptionRecord *info, Context *r, G *gp)
+{
+	uintptr *sp;
+
+	if(!runtime·isgoexception(info, r))
+		return EXCEPTION_CONTINUE_SEARCH;
+
+	// Make it look like a call to the signal func.
+	// Have to pass arguments out of band since
+	// augmenting the stack frame would break
+	// the unwinding code.
+	gp->sig = info->ExceptionCode;
+	gp->sigcode0 = info->ExceptionInformation[0];
+	gp->sigcode1 = info->ExceptionInformation[1];
+	gp->sigpc = r->Rip;
+
+	// Only push runtime·sigpanic if r->rip != 0.
+	// If r->rip == 0, probably panicked because of a
+	// call to a nil func.  Not pushing that onto sp will
+	// make the trace look like a call to runtime·sigpanic instead.
+	// (Otherwise the trace will end at runtime·sigpanic and we
+	// won't get to see who faulted.)
+	if(r->Rip != 0) {
+		sp = (uintptr*)r->Rsp;
+		*--sp = r->Rip;
+		r->Rsp = (uintptr)sp;
+	}
+	r->Rip = (uintptr)runtime·sigpanic;
+	return EXCEPTION_CONTINUE_EXECUTION;
+}
+
+// It seems Windows searches ContinueHandler's list even
+// if ExceptionHandler returns EXCEPTION_CONTINUE_EXECUTION.
+// firstcontinuehandler will stop that search,
+// if exceptionhandler did the same earlier.
+uint32
+runtime·firstcontinuehandler(ExceptionRecord *info, Context *r, G *gp)
+{
+	USED(gp);
+	if(!runtime·isgoexception(info, r))
+		return EXCEPTION_CONTINUE_SEARCH;
+	return EXCEPTION_CONTINUE_EXECUTION;
+}
+
+// lastcontinuehandler is reached, because runtime cannot handle
+// current exception. lastcontinuehandler will print crash info and exit.
+uint32
+runtime·lastcontinuehandler(ExceptionRecord *info, Context *r, G *gp)
+{
+	bool crash;
+
+	if(runtime·panicking)	// traceback already printed
+		runtime·exit(2);
+	runtime·panicking = 1;
+
+	runtime·printf("Exception %x %p %p %p\n", info->ExceptionCode,
+		info->ExceptionInformation[0], info->ExceptionInformation[1], r->Rip);
+
+
+	runtime·printf("PC=%X\n", r->Rip);
+	if(g->m->lockedg != nil && g->m->ncgo > 0 && gp == g->m->g0) {
+		runtime·printf("signal arrived during cgo execution\n");
+		gp = g->m->lockedg;
+	}
+	runtime·printf("\n");
+
+	if(runtime·gotraceback(&crash)){
+		runtime·tracebacktrap(r->Rip, r->Rsp, 0, gp);
+		runtime·tracebackothers(gp);
+		runtime·dumpregs(r);
+	}
+	
+	if(crash)
+		runtime·crash();
+
+	runtime·exit(2);
+	return 0; // not reached
+}
+
+void
+runtime·sigenable(uint32 sig)
+{
+	USED(sig);
+}
+
+void
+runtime·sigdisable(uint32 sig)
+{
+	USED(sig);
+}
+
+void
+runtime·dosigprof(Context *r, G *gp, M *mp)
+{
+	runtime·sigprof((uint8*)r->Rip, (uint8*)r->Rsp, nil, gp, mp);
+}
diff --git a/src/runtime/os_windows_amd64.go b/src/runtime/os_windows_amd64.go
new file mode 100644
index 0000000..3f4d4d0
--- /dev/null
+++ b/src/runtime/os_windows_amd64.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 runtime
+
+// contextPC returns the RIP (program counter) register from the context.
+func contextPC(r *context) uintptr { return uintptr(r.rip) }
+
+// contextSP returns the RSP (stack pointer) register from the context.
+func contextSP(r *context) uintptr { return uintptr(r.rsp) }
diff --git a/src/runtime/panic.c b/src/runtime/panic.c
new file mode 100644
index 0000000..24eb6db
--- /dev/null
+++ b/src/runtime/panic.c
@@ -0,0 +1,200 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "runtime.h"
+#include "arch_GOARCH.h"
+#include "stack.h"
+#include "malloc.h"
+#include "textflag.h"
+
+// Code related to defer, panic and recover.
+
+// TODO: remove once code is moved to Go
+extern Defer* runtime·newdefer(int32 siz);
+extern runtime·freedefer(Defer *d);
+
+uint32 runtime·panicking;
+static Mutex paniclk;
+
+void
+runtime·deferproc_m(void)
+{
+	int32 siz;
+	FuncVal *fn;
+	uintptr argp;
+	uintptr callerpc;
+	Defer *d;
+
+	siz = g->m->scalararg[0];
+	fn = g->m->ptrarg[0];
+	argp = g->m->scalararg[1];
+	callerpc = g->m->scalararg[2];
+	g->m->ptrarg[0] = nil;
+	g->m->scalararg[1] = 0;
+
+	d = runtime·newdefer(siz);
+	if(d->panic != nil)
+		runtime·throw("deferproc: d->panic != nil after newdefer");
+	d->fn = fn;
+	d->pc = callerpc;
+	d->argp = argp;
+	runtime·memmove(d+1, (void*)argp, siz);
+}
+
+// Unwind the stack after a deferred function calls recover
+// after a panic.  Then arrange to continue running as though
+// the caller of the deferred function returned normally.
+void
+runtime·recovery_m(G *gp)
+{
+	void *argp;
+	uintptr pc;
+	
+	// Info about defer passed in G struct.
+	argp = (void*)gp->sigcode0;
+	pc = (uintptr)gp->sigcode1;
+
+	// d's arguments need to be in the stack.
+	if(argp != nil && ((uintptr)argp < gp->stack.lo || gp->stack.hi < (uintptr)argp)) {
+		runtime·printf("recover: %p not in [%p, %p]\n", argp, gp->stack.lo, gp->stack.hi);
+		runtime·throw("bad recovery");
+	}
+
+	// Make the deferproc for this d return again,
+	// this time returning 1.  The calling function will
+	// jump to the standard return epilogue.
+	// The -2*sizeof(uintptr) makes up for the
+	// two extra words that are on the stack at
+	// each call to deferproc.
+	// (The pc we're returning to does pop pop
+	// before it tests the return value.)
+	// On the arm there are 2 saved LRs mixed in too.
+	if(thechar == '5')
+		gp->sched.sp = (uintptr)argp - 4*sizeof(uintptr);
+	else
+		gp->sched.sp = (uintptr)argp - 2*sizeof(uintptr);
+	gp->sched.pc = pc;
+	gp->sched.lr = 0;
+	gp->sched.ret = 1;
+	runtime·gogo(&gp->sched);
+}
+
+void
+runtime·startpanic_m(void)
+{
+	if(runtime·mheap.cachealloc.size == 0) { // very early
+		runtime·printf("runtime: panic before malloc heap initialized\n");
+		g->m->mallocing = 1; // tell rest of panic not to try to malloc
+	} else if(g->m->mcache == nil) // can happen if called from signal handler or throw
+		g->m->mcache = runtime·allocmcache();
+	switch(g->m->dying) {
+	case 0:
+		g->m->dying = 1;
+		if(g != nil) {
+			g->writebuf.array = nil;
+			g->writebuf.len = 0;
+			g->writebuf.cap = 0;
+		}
+		runtime·xadd(&runtime·panicking, 1);
+		runtime·lock(&paniclk);
+		if(runtime·debug.schedtrace > 0 || runtime·debug.scheddetail > 0)
+			runtime·schedtrace(true);
+		runtime·freezetheworld();
+		return;
+	case 1:
+		// Something failed while panicing, probably the print of the
+		// argument to panic().  Just print a stack trace and exit.
+		g->m->dying = 2;
+		runtime·printf("panic during panic\n");
+		runtime·dopanic(0);
+		runtime·exit(3);
+	case 2:
+		// This is a genuine bug in the runtime, we couldn't even
+		// print the stack trace successfully.
+		g->m->dying = 3;
+		runtime·printf("stack trace unavailable\n");
+		runtime·exit(4);
+	default:
+		// Can't even print!  Just exit.
+		runtime·exit(5);
+	}
+}
+
+void
+runtime·dopanic_m(void)
+{
+	G *gp;
+	uintptr sp, pc;
+	static bool didothers;
+	bool crash;
+	int32 t;
+
+	gp = g->m->ptrarg[0];
+	g->m->ptrarg[0] = nil;
+	pc = g->m->scalararg[0];
+	sp = g->m->scalararg[1];
+	g->m->scalararg[1] = 0;
+	if(gp->sig != 0)
+		runtime·printf("[signal %x code=%p addr=%p pc=%p]\n",
+			gp->sig, gp->sigcode0, gp->sigcode1, gp->sigpc);
+
+	if((t = runtime·gotraceback(&crash)) > 0){
+		if(gp != gp->m->g0) {
+			runtime·printf("\n");
+			runtime·goroutineheader(gp);
+			runtime·traceback(pc, sp, 0, gp);
+		} else if(t >= 2 || g->m->throwing > 0) {
+			runtime·printf("\nruntime stack:\n");
+			runtime·traceback(pc, sp, 0, gp);
+		}
+		if(!didothers) {
+			didothers = true;
+			runtime·tracebackothers(gp);
+		}
+	}
+	runtime·unlock(&paniclk);
+	if(runtime·xadd(&runtime·panicking, -1) != 0) {
+		// Some other m is panicking too.
+		// Let it print what it needs to print.
+		// Wait forever without chewing up cpu.
+		// It will exit when it's done.
+		static Mutex deadlock;
+		runtime·lock(&deadlock);
+		runtime·lock(&deadlock);
+	}
+	
+	if(crash)
+		runtime·crash();
+
+	runtime·exit(2);
+}
+
+#pragma textflag NOSPLIT
+bool
+runtime·canpanic(G *gp)
+{
+	M *m;
+	uint32 status;
+
+	// Note that g is m->gsignal, different from gp.
+	// Note also that g->m can change at preemption, so m can go stale
+	// if this function ever makes a function call.
+	m = g->m;
+
+	// Is it okay for gp to panic instead of crashing the program?
+	// Yes, as long as it is running Go code, not runtime code,
+	// and not stuck in a system call.
+	if(gp == nil || gp != m->curg)
+		return false;
+	if(m->locks-m->softfloat != 0 || m->mallocing != 0 || m->throwing != 0 || m->gcing != 0 || m->dying != 0)
+		return false;
+	status = runtime·readgstatus(gp);
+	if((status&~Gscan) != Grunning || gp->syscallsp != 0)
+		return false;
+#ifdef GOOS_windows
+	if(m->libcallsp != 0)
+		return false;
+#endif
+	return true;
+}
diff --git a/src/runtime/panic.go b/src/runtime/panic.go
new file mode 100644
index 0000000..685ff5c
--- /dev/null
+++ b/src/runtime/panic.go
@@ -0,0 +1,505 @@
+// 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 runtime
+
+import "unsafe"
+
+var indexError = error(errorString("index out of range"))
+
+func panicindex() {
+	panic(indexError)
+}
+
+var sliceError = error(errorString("slice bounds out of range"))
+
+func panicslice() {
+	panic(sliceError)
+}
+
+var divideError = error(errorString("integer divide by zero"))
+
+func panicdivide() {
+	panic(divideError)
+}
+
+var overflowError = error(errorString("integer overflow"))
+
+func panicoverflow() {
+	panic(overflowError)
+}
+
+var floatError = error(errorString("floating point error"))
+
+func panicfloat() {
+	panic(floatError)
+}
+
+var memoryError = error(errorString("invalid memory address or nil pointer dereference"))
+
+func panicmem() {
+	panic(memoryError)
+}
+
+func throwreturn() {
+	gothrow("no return at end of a typed function - compiler is broken")
+}
+
+func throwinit() {
+	gothrow("recursive call during initialization - linker skew")
+}
+
+// Create a new deferred function fn with siz bytes of arguments.
+// The compiler turns a defer statement into a call to this.
+//go:nosplit
+func deferproc(siz int32, fn *funcval) { // arguments of fn follow fn
+	// the arguments of fn are in a perilous state.  The stack map
+	// for deferproc does not describe them.  So we can't let garbage
+	// collection or stack copying trigger until we've copied them out
+	// to somewhere safe.  deferproc_m does that.  Until deferproc_m,
+	// we can only call nosplit routines.
+	argp := uintptr(unsafe.Pointer(&fn))
+	argp += unsafe.Sizeof(fn)
+	if GOARCH == "arm" {
+		argp += ptrSize // skip caller's saved link register
+	}
+	mp := acquirem()
+	mp.scalararg[0] = uintptr(siz)
+	mp.ptrarg[0] = unsafe.Pointer(fn)
+	mp.scalararg[1] = argp
+	mp.scalararg[2] = getcallerpc(unsafe.Pointer(&siz))
+
+	if mp.curg != getg() {
+		// go code on the m stack can't defer
+		gothrow("defer on m")
+	}
+
+	onM(deferproc_m)
+
+	releasem(mp)
+
+	// deferproc returns 0 normally.
+	// a deferred func that stops a panic
+	// makes the deferproc return 1.
+	// the code the compiler generates always
+	// checks the return value and jumps to the
+	// end of the function if deferproc returns != 0.
+	return0()
+	// No code can go here - the C return register has
+	// been set and must not be clobbered.
+}
+
+// Small malloc size classes >= 16 are the multiples of 16: 16, 32, 48, 64, 80, 96, 112, 128, 144, ...
+// Each P holds a pool for defers with small arg sizes.
+// Assign defer allocations to pools by rounding to 16, to match malloc size classes.
+
+const (
+	deferHeaderSize = unsafe.Sizeof(_defer{})
+	minDeferAlloc   = (deferHeaderSize + 15) &^ 15
+	minDeferArgs    = minDeferAlloc - deferHeaderSize
+)
+
+// defer size class for arg size sz
+//go:nosplit
+func deferclass(siz uintptr) uintptr {
+	if siz <= minDeferArgs {
+		return 0
+	}
+	return (siz - minDeferArgs + 15) / 16
+}
+
+// total size of memory block for defer with arg size sz
+func totaldefersize(siz uintptr) uintptr {
+	if siz <= minDeferArgs {
+		return minDeferAlloc
+	}
+	return deferHeaderSize + siz
+}
+
+// Ensure that defer arg sizes that map to the same defer size class
+// also map to the same malloc size class.
+func testdefersizes() {
+	var m [len(p{}.deferpool)]int32
+
+	for i := range m {
+		m[i] = -1
+	}
+	for i := uintptr(0); ; i++ {
+		defersc := deferclass(i)
+		if defersc >= uintptr(len(m)) {
+			break
+		}
+		siz := goroundupsize(totaldefersize(i))
+		if m[defersc] < 0 {
+			m[defersc] = int32(siz)
+			continue
+		}
+		if m[defersc] != int32(siz) {
+			print("bad defer size class: i=", i, " siz=", siz, " defersc=", defersc, "\n")
+			gothrow("bad defer size class")
+		}
+	}
+}
+
+// The arguments associated with a deferred call are stored
+// immediately after the _defer header in memory.
+//go:nosplit
+func deferArgs(d *_defer) unsafe.Pointer {
+	return add(unsafe.Pointer(d), unsafe.Sizeof(*d))
+}
+
+var deferType *_type // type of _defer struct
+
+func init() {
+	var x interface{}
+	x = (*_defer)(nil)
+	deferType = (*(**ptrtype)(unsafe.Pointer(&x))).elem
+}
+
+// Allocate a Defer, usually using per-P pool.
+// Each defer must be released with freedefer.
+// Note: runs on M stack
+func newdefer(siz int32) *_defer {
+	var d *_defer
+	sc := deferclass(uintptr(siz))
+	mp := acquirem()
+	if sc < uintptr(len(p{}.deferpool)) {
+		pp := mp.p
+		d = pp.deferpool[sc]
+		if d != nil {
+			pp.deferpool[sc] = d.link
+		}
+	}
+	if d == nil {
+		// Allocate new defer+args.
+		total := goroundupsize(totaldefersize(uintptr(siz)))
+		d = (*_defer)(mallocgc(total, deferType, 0))
+	}
+	d.siz = siz
+	gp := mp.curg
+	d.link = gp._defer
+	gp._defer = d
+	releasem(mp)
+	return d
+}
+
+// Free the given defer.
+// The defer cannot be used after this call.
+//go:nosplit
+func freedefer(d *_defer) {
+	if d._panic != nil {
+		freedeferpanic()
+	}
+	if d.fn != nil {
+		freedeferfn()
+	}
+	sc := deferclass(uintptr(d.siz))
+	if sc < uintptr(len(p{}.deferpool)) {
+		mp := acquirem()
+		pp := mp.p
+		*d = _defer{}
+		d.link = pp.deferpool[sc]
+		pp.deferpool[sc] = d
+		releasem(mp)
+	}
+}
+
+// Separate function so that it can split stack.
+// Windows otherwise runs out of stack space.
+func freedeferpanic() {
+	// _panic must be cleared before d is unlinked from gp.
+	gothrow("freedefer with d._panic != nil")
+}
+
+func freedeferfn() {
+	// fn must be cleared before d is unlinked from gp.
+	gothrow("freedefer with d.fn != nil")
+}
+
+// Run a deferred function if there is one.
+// The compiler inserts a call to this at the end of any
+// function which calls defer.
+// If there is a deferred function, this will call runtime·jmpdefer,
+// which will jump to the deferred function such that it appears
+// to have been called by the caller of deferreturn at the point
+// just before deferreturn was called.  The effect is that deferreturn
+// is called again and again until there are no more deferred functions.
+// Cannot split the stack because we reuse the caller's frame to
+// call the deferred function.
+
+// The single argument isn't actually used - it just has its address
+// taken so it can be matched against pending defers.
+//go:nosplit
+func deferreturn(arg0 uintptr) {
+	gp := getg()
+	d := gp._defer
+	if d == nil {
+		return
+	}
+	argp := uintptr(unsafe.Pointer(&arg0))
+	if d.argp != argp {
+		return
+	}
+
+	// Moving arguments around.
+	// Do not allow preemption here, because the garbage collector
+	// won't know the form of the arguments until the jmpdefer can
+	// flip the PC over to fn.
+	mp := acquirem()
+	memmove(unsafe.Pointer(argp), deferArgs(d), uintptr(d.siz))
+	fn := d.fn
+	d.fn = nil
+	gp._defer = d.link
+	freedefer(d)
+	releasem(mp)
+	jmpdefer(fn, argp)
+}
+
+// Goexit terminates the goroutine that calls it.  No other goroutine is affected.
+// Goexit runs all deferred calls before terminating the goroutine.  Because Goexit
+// is not panic, however, any recover calls in those deferred functions will return nil.
+//
+// Calling Goexit from the main goroutine terminates that goroutine
+// without func main returning. Since func main has not returned,
+// the program continues execution of other goroutines.
+// If all other goroutines exit, the program crashes.
+func Goexit() {
+	// Run all deferred functions for the current goroutine.
+	// This code is similar to gopanic, see that implementation
+	// for detailed comments.
+	gp := getg()
+	for {
+		d := gp._defer
+		if d == nil {
+			break
+		}
+		if d.started {
+			if d._panic != nil {
+				d._panic.aborted = true
+				d._panic = nil
+			}
+			d.fn = nil
+			gp._defer = d.link
+			freedefer(d)
+			continue
+		}
+		d.started = true
+		reflectcall(unsafe.Pointer(d.fn), deferArgs(d), uint32(d.siz), uint32(d.siz))
+		if gp._defer != d {
+			gothrow("bad defer entry in Goexit")
+		}
+		d._panic = nil
+		d.fn = nil
+		gp._defer = d.link
+		freedefer(d)
+		// Note: we ignore recovers here because Goexit isn't a panic
+	}
+	goexit()
+}
+
+func canpanic(*g) bool
+
+// Print all currently active panics.  Used when crashing.
+func printpanics(p *_panic) {
+	if p.link != nil {
+		printpanics(p.link)
+		print("\t")
+	}
+	print("panic: ")
+	printany(p.arg)
+	if p.recovered {
+		print(" [recovered]")
+	}
+	print("\n")
+}
+
+// The implementation of the predeclared function panic.
+func gopanic(e interface{}) {
+	gp := getg()
+	if gp.m.curg != gp {
+		gothrow("panic on m stack")
+	}
+
+	// m.softfloat is set during software floating point.
+	// It increments m.locks to avoid preemption.
+	// We moved the memory loads out, so there shouldn't be
+	// any reason for it to panic anymore.
+	if gp.m.softfloat != 0 {
+		gp.m.locks--
+		gp.m.softfloat = 0
+		gothrow("panic during softfloat")
+	}
+	if gp.m.mallocing != 0 {
+		print("panic: ")
+		printany(e)
+		print("\n")
+		gothrow("panic during malloc")
+	}
+	if gp.m.gcing != 0 {
+		print("panic: ")
+		printany(e)
+		print("\n")
+		gothrow("panic during gc")
+	}
+	if gp.m.locks != 0 {
+		print("panic: ")
+		printany(e)
+		print("\n")
+		gothrow("panic holding locks")
+	}
+
+	var p _panic
+	p.arg = e
+	p.link = gp._panic
+	gp._panic = (*_panic)(noescape(unsafe.Pointer(&p)))
+
+	for {
+		d := gp._defer
+		if d == nil {
+			break
+		}
+
+		// If defer was started by earlier panic or Goexit (and, since we're back here, that triggered a new panic),
+		// take defer off list. The earlier panic or Goexit will not continue running.
+		if d.started {
+			if d._panic != nil {
+				d._panic.aborted = true
+			}
+			d._panic = nil
+			d.fn = nil
+			gp._defer = d.link
+			freedefer(d)
+			continue
+		}
+
+		// Mark defer as started, but keep on list, so that traceback
+		// can find and update the defer's argument frame if stack growth
+		// or a garbage collection hapens before reflectcall starts executing d.fn.
+		d.started = true
+
+		// Record the panic that is running the defer.
+		// If there is a new panic during the deferred call, that panic
+		// will find d in the list and will mark d._panic (this panic) aborted.
+		d._panic = (*_panic)(noescape((unsafe.Pointer)(&p)))
+
+		p.argp = unsafe.Pointer(getargp(0))
+		reflectcall(unsafe.Pointer(d.fn), deferArgs(d), uint32(d.siz), uint32(d.siz))
+		p.argp = nil
+
+		// reflectcall did not panic. Remove d.
+		if gp._defer != d {
+			gothrow("bad defer entry in panic")
+		}
+		d._panic = nil
+		d.fn = nil
+		gp._defer = d.link
+
+		// trigger shrinkage to test stack copy.  See stack_test.go:TestStackPanic
+		//GC()
+
+		pc := d.pc
+		argp := unsafe.Pointer(d.argp) // must be pointer so it gets adjusted during stack copy
+		freedefer(d)
+		if p.recovered {
+			gp._panic = p.link
+			// Aborted panics are marked but remain on the g.panic list.
+			// Remove them from the list.
+			for gp._panic != nil && gp._panic.aborted {
+				gp._panic = gp._panic.link
+			}
+			if gp._panic == nil { // must be done with signal
+				gp.sig = 0
+			}
+			// Pass information about recovering frame to recovery.
+			gp.sigcode0 = uintptr(argp)
+			gp.sigcode1 = pc
+			mcall(recovery_m)
+			gothrow("recovery failed") // mcall should not return
+		}
+	}
+
+	// ran out of deferred calls - old-school panic now
+	startpanic()
+	printpanics(gp._panic)
+	dopanic(0)       // should not return
+	*(*int)(nil) = 0 // not reached
+}
+
+// getargp returns the location where the caller
+// writes outgoing function call arguments.
+//go:nosplit
+func getargp(x int) uintptr {
+	// x is an argument mainly so that we can return its address.
+	// However, we need to make the function complex enough
+	// that it won't be inlined. We always pass x = 0, so this code
+	// does nothing other than keep the compiler from thinking
+	// the function is simple enough to inline.
+	if x > 0 {
+		return getcallersp(unsafe.Pointer(&x)) * 0
+	}
+	return uintptr(noescape(unsafe.Pointer(&x)))
+}
+
+// The implementation of the predeclared function recover.
+// Cannot split the stack because it needs to reliably
+// find the stack segment of its caller.
+//
+// TODO(rsc): Once we commit to CopyStackAlways,
+// this doesn't need to be nosplit.
+//go:nosplit
+func gorecover(argp uintptr) interface{} {
+	// Must be in a function running as part of a deferred call during the panic.
+	// Must be called from the topmost function of the call
+	// (the function used in the defer statement).
+	// p.argp is the argument pointer of that topmost deferred function call.
+	// Compare against argp reported by caller.
+	// If they match, the caller is the one who can recover.
+	gp := getg()
+	p := gp._panic
+	if p != nil && !p.recovered && argp == uintptr(p.argp) {
+		p.recovered = true
+		return p.arg
+	}
+	return nil
+}
+
+//go:nosplit
+func startpanic() {
+	onM_signalok(startpanic_m)
+}
+
+//go:nosplit
+func dopanic(unused int) {
+	gp := getg()
+	mp := acquirem()
+	mp.ptrarg[0] = unsafe.Pointer(gp)
+	mp.scalararg[0] = getcallerpc((unsafe.Pointer)(&unused))
+	mp.scalararg[1] = getcallersp((unsafe.Pointer)(&unused))
+	onM_signalok(dopanic_m) // should never return
+	*(*int)(nil) = 0
+}
+
+//go:nosplit
+func throw(s *byte) {
+	gp := getg()
+	if gp.m.throwing == 0 {
+		gp.m.throwing = 1
+	}
+	startpanic()
+	print("fatal error: ", gostringnocopy(s), "\n")
+	dopanic(0)
+	*(*int)(nil) = 0 // not reached
+}
+
+//go:nosplit
+func gothrow(s string) {
+	gp := getg()
+	if gp.m.throwing == 0 {
+		gp.m.throwing = 1
+	}
+	startpanic()
+	print("fatal error: ", s, "\n")
+	dopanic(0)
+	*(*int)(nil) = 0 // not reached
+}
diff --git a/src/runtime/parfor.c b/src/runtime/parfor.c
new file mode 100644
index 0000000..e449568
--- /dev/null
+++ b/src/runtime/parfor.c
@@ -0,0 +1,226 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Parallel for algorithm.
+
+#include "runtime.h"
+#include "arch_GOARCH.h"
+#include "malloc.h"
+
+struct ParForThread
+{
+	// the thread's iteration space [32lsb, 32msb)
+	uint64 pos;
+	// stats
+	uint64 nsteal;
+	uint64 nstealcnt;
+	uint64 nprocyield;
+	uint64 nosyield;
+	uint64 nsleep;
+	byte pad[CacheLineSize];
+};
+
+void
+runtime·parforsetup(ParFor *desc, uint32 nthr, uint32 n, void *ctx, bool wait, void (*body)(ParFor*, uint32))
+{
+	uint32 i, begin, end;
+	uint64 *pos;
+
+	if(desc == nil || nthr == 0 || nthr > desc->nthrmax || body == nil) {
+		runtime·printf("desc=%p nthr=%d count=%d body=%p\n", desc, nthr, n, body);
+		runtime·throw("parfor: invalid args");
+	}
+
+	desc->body = body;
+	desc->done = 0;
+	desc->nthr = nthr;
+	desc->thrseq = 0;
+	desc->cnt = n;
+	desc->ctx = ctx;
+	desc->wait = wait;
+	desc->nsteal = 0;
+	desc->nstealcnt = 0;
+	desc->nprocyield = 0;
+	desc->nosyield = 0;
+	desc->nsleep = 0;
+	for(i=0; i<nthr; i++) {
+		begin = (uint64)n*i / nthr;
+		end = (uint64)n*(i+1) / nthr;
+		pos = &desc->thr[i].pos;
+		if(((uintptr)pos & 7) != 0)
+			runtime·throw("parforsetup: pos is not aligned");
+		*pos = (uint64)begin | (((uint64)end)<<32);
+	}
+}
+
+void
+runtime·parfordo(ParFor *desc)
+{
+	ParForThread *me;
+	uint32 tid, begin, end, begin2, try, victim, i;
+	uint64 *mypos, *victimpos, pos, newpos;
+	void (*body)(ParFor*, uint32);
+	bool idle;
+
+	// Obtain 0-based thread index.
+	tid = runtime·xadd(&desc->thrseq, 1) - 1;
+	if(tid >= desc->nthr) {
+		runtime·printf("tid=%d nthr=%d\n", tid, desc->nthr);
+		runtime·throw("parfor: invalid tid");
+	}
+
+	// If single-threaded, just execute the for serially.
+	if(desc->nthr==1) {
+		for(i=0; i<desc->cnt; i++)
+			desc->body(desc, i);
+		return;
+	}
+
+	body = desc->body;
+	me = &desc->thr[tid];
+	mypos = &me->pos;
+	for(;;) {
+		for(;;) {
+			// While there is local work,
+			// bump low index and execute the iteration.
+			pos = runtime·xadd64(mypos, 1);
+			begin = (uint32)pos-1;
+			end = (uint32)(pos>>32);
+			if(begin < end) {
+				body(desc, begin);
+				continue;
+			}
+			break;
+		}
+
+		// Out of work, need to steal something.
+		idle = false;
+		for(try=0;; try++) {
+			// If we don't see any work for long enough,
+			// increment the done counter...
+			if(try > desc->nthr*4 && !idle) {
+				idle = true;
+				runtime·xadd(&desc->done, 1);
+			}
+			// ...if all threads have incremented the counter,
+			// we are done.
+			if(desc->done + !idle == desc->nthr) {
+				if(!idle)
+					runtime·xadd(&desc->done, 1);
+				goto exit;
+			}
+			// Choose a random victim for stealing.
+			victim = runtime·fastrand1() % (desc->nthr-1);
+			if(victim >= tid)
+				victim++;
+			victimpos = &desc->thr[victim].pos;
+			for(;;) {
+				// See if it has any work.
+				pos = runtime·atomicload64(victimpos);
+				begin = (uint32)pos;
+				end = (uint32)(pos>>32);
+				if(begin+1 >= end) {
+					begin = end = 0;
+					break;
+				}
+				if(idle) {
+					runtime·xadd(&desc->done, -1);
+					idle = false;
+				}
+				begin2 = begin + (end-begin)/2;
+				newpos = (uint64)begin | (uint64)begin2<<32;
+				if(runtime·cas64(victimpos, pos, newpos)) {
+					begin = begin2;
+					break;
+				}
+			}
+			if(begin < end) {
+				// Has successfully stolen some work.
+				if(idle)
+					runtime·throw("parfor: should not be idle");
+				runtime·atomicstore64(mypos, (uint64)begin | (uint64)end<<32);
+				me->nsteal++;
+				me->nstealcnt += end-begin;
+				break;
+			}
+			// Backoff.
+			if(try < desc->nthr) {
+				// nothing
+			} else if (try < 4*desc->nthr) {
+				me->nprocyield++;
+				runtime·procyield(20);
+			// If a caller asked not to wait for the others, exit now
+			// (assume that most work is already done at this point).
+			} else if (!desc->wait) {
+				if(!idle)
+					runtime·xadd(&desc->done, 1);
+				goto exit;
+			} else if (try < 6*desc->nthr) {
+				me->nosyield++;
+				runtime·osyield();
+			} else {
+				me->nsleep++;
+				runtime·usleep(1);
+			}
+		}
+	}
+exit:
+	runtime·xadd64(&desc->nsteal, me->nsteal);
+	runtime·xadd64(&desc->nstealcnt, me->nstealcnt);
+	runtime·xadd64(&desc->nprocyield, me->nprocyield);
+	runtime·xadd64(&desc->nosyield, me->nosyield);
+	runtime·xadd64(&desc->nsleep, me->nsleep);
+	me->nsteal = 0;
+	me->nstealcnt = 0;
+	me->nprocyield = 0;
+	me->nosyield = 0;
+	me->nsleep = 0;
+}
+
+// For testing from Go.
+void
+runtime·newparfor_m(void)
+{
+	g->m->ptrarg[0] = runtime·parforalloc(g->m->scalararg[0]);
+}
+
+void
+runtime·parforsetup_m(void)
+{
+	ParFor *desc;
+	void *ctx;
+	void (*body)(ParFor*, uint32);
+
+	desc = g->m->ptrarg[0];
+	g->m->ptrarg[0] = nil;
+	ctx = g->m->ptrarg[1];
+	g->m->ptrarg[1] = nil;
+	body = g->m->ptrarg[2];
+	g->m->ptrarg[2] = nil;
+
+	runtime·parforsetup(desc, g->m->scalararg[0], g->m->scalararg[1], ctx, g->m->scalararg[2], body);
+}
+
+void
+runtime·parfordo_m(void)
+{
+	ParFor *desc;
+
+	desc = g->m->ptrarg[0];
+	g->m->ptrarg[0] = nil;
+	runtime·parfordo(desc);
+}
+
+void
+runtime·parforiters_m(void)
+{
+	ParFor *desc;
+	uintptr tid;
+
+	desc = g->m->ptrarg[0];
+	g->m->ptrarg[0] = nil;
+	tid = g->m->scalararg[0];
+	g->m->scalararg[0] = desc->thr[tid].pos;
+	g->m->scalararg[1] = desc->thr[tid].pos>>32;
+}
diff --git a/src/pkg/runtime/parfor_test.go b/src/runtime/parfor_test.go
similarity index 100%
rename from src/pkg/runtime/parfor_test.go
rename to src/runtime/parfor_test.go
diff --git a/src/runtime/pprof/mprof_test.go b/src/runtime/pprof/mprof_test.go
new file mode 100644
index 0000000..ebf53dd
--- /dev/null
+++ b/src/runtime/pprof/mprof_test.go
@@ -0,0 +1,99 @@
+// 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 pprof_test
+
+import (
+	"bytes"
+	"fmt"
+	"regexp"
+	"runtime"
+	. "runtime/pprof"
+	"testing"
+	"unsafe"
+)
+
+var memSink interface{}
+
+func allocateTransient1M() {
+	for i := 0; i < 1024; i++ {
+		memSink = &struct{ x [1024]byte }{}
+	}
+}
+
+func allocateTransient2M() {
+	// prevent inlining
+	if memSink == nil {
+		panic("bad")
+	}
+	memSink = make([]byte, 2<<20)
+}
+
+type Obj32 struct {
+	link *Obj32
+	pad  [32 - unsafe.Sizeof(uintptr(0))]byte
+}
+
+var persistentMemSink *Obj32
+
+func allocatePersistent1K() {
+	for i := 0; i < 32; i++ {
+		// Can't use slice because that will introduce implicit allocations.
+		obj := &Obj32{link: persistentMemSink}
+		persistentMemSink = obj
+	}
+}
+
+var memoryProfilerRun = 0
+
+func TestMemoryProfiler(t *testing.T) {
+	// Disable sampling, otherwise it's difficult to assert anything.
+	oldRate := runtime.MemProfileRate
+	runtime.MemProfileRate = 1
+	defer func() {
+		runtime.MemProfileRate = oldRate
+	}()
+
+	// Allocate a meg to ensure that mcache.next_sample is updated to 1.
+	for i := 0; i < 1024; i++ {
+		memSink = make([]byte, 1024)
+	}
+
+	// Do the interesting allocations.
+	allocateTransient1M()
+	allocateTransient2M()
+	allocatePersistent1K()
+	memSink = nil
+
+	runtime.GC() // materialize stats
+	var buf bytes.Buffer
+	if err := Lookup("heap").WriteTo(&buf, 1); err != nil {
+		t.Fatalf("failed to write heap profile: %v", err)
+	}
+
+	memoryProfilerRun++
+
+	tests := []string{
+		fmt.Sprintf(`%v: %v \[%v: %v\] @ 0x[0-9,a-f]+ 0x[0-9,a-f]+ 0x[0-9,a-f]+ 0x[0-9,a-f]+
+#	0x[0-9,a-f]+	runtime/pprof_test\.allocatePersistent1K\+0x[0-9,a-f]+	.*/runtime/pprof/mprof_test\.go:43
+#	0x[0-9,a-f]+	runtime/pprof_test\.TestMemoryProfiler\+0x[0-9,a-f]+	.*/runtime/pprof/mprof_test\.go:66
+`, 32*memoryProfilerRun, 1024*memoryProfilerRun, 32*memoryProfilerRun, 1024*memoryProfilerRun),
+
+		fmt.Sprintf(`0: 0 \[%v: %v\] @ 0x[0-9,a-f]+ 0x[0-9,a-f]+ 0x[0-9,a-f]+ 0x[0-9,a-f]+
+#	0x[0-9,a-f]+	runtime/pprof_test\.allocateTransient1M\+0x[0-9,a-f]+	.*/runtime/pprof/mprof_test.go:21
+#	0x[0-9,a-f]+	runtime/pprof_test\.TestMemoryProfiler\+0x[0-9,a-f]+	.*/runtime/pprof/mprof_test.go:64
+`, (1<<10)*memoryProfilerRun, (1<<20)*memoryProfilerRun),
+
+		fmt.Sprintf(`0: 0 \[%v: %v\] @ 0x[0-9,a-f]+ 0x[0-9,a-f]+ 0x[0-9,a-f]+ 0x[0-9,a-f]+ 0x[0-9,a-f]+
+#	0x[0-9,a-f]+	runtime/pprof_test\.allocateTransient2M\+0x[0-9,a-f]+	.*/runtime/pprof/mprof_test.go:30
+#	0x[0-9,a-f]+	runtime/pprof_test\.TestMemoryProfiler\+0x[0-9,a-f]+	.*/runtime/pprof/mprof_test.go:65
+`, memoryProfilerRun, (2<<20)*memoryProfilerRun),
+	}
+
+	for _, test := range tests {
+		if !regexp.MustCompile(test).Match(buf.Bytes()) {
+			t.Fatalf("The entry did not match:\n%v\n\nProfile:\n%v\n", test, buf.String())
+		}
+	}
+}
diff --git a/src/runtime/pprof/pprof.go b/src/runtime/pprof/pprof.go
new file mode 100644
index 0000000..236de54
--- /dev/null
+++ b/src/runtime/pprof/pprof.go
@@ -0,0 +1,673 @@
+// Copyright 2010 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package pprof writes runtime profiling data in the format expected
+// by the pprof visualization tool.
+// For more information about pprof, see
+// http://code.google.com/p/google-perftools/.
+package pprof
+
+import (
+	"bufio"
+	"bytes"
+	"fmt"
+	"io"
+	"runtime"
+	"sort"
+	"strings"
+	"sync"
+	"text/tabwriter"
+)
+
+// BUG(rsc): Profiles are incomplete and inaccurate on NetBSD and OS X.
+// See http://golang.org/issue/6047 for details.
+
+// A Profile is a collection of stack traces showing the call sequences
+// that led to instances of a particular event, such as allocation.
+// Packages can create and maintain their own profiles; the most common
+// use is for tracking resources that must be explicitly closed, such as files
+// or network connections.
+//
+// A Profile's methods can be called from multiple goroutines simultaneously.
+//
+// Each Profile has a unique name.  A few profiles are predefined:
+//
+//	goroutine    - stack traces of all current goroutines
+//	heap         - a sampling of all heap allocations
+//	threadcreate - stack traces that led to the creation of new OS threads
+//	block        - stack traces that led to blocking on synchronization primitives
+//
+// These predefined profiles maintain themselves and panic on an explicit
+// Add or Remove method call.
+//
+// The CPU profile is not available as a Profile.  It has a special API,
+// the StartCPUProfile and StopCPUProfile functions, because it streams
+// output to a writer during profiling.
+//
+type Profile struct {
+	name  string
+	mu    sync.Mutex
+	m     map[interface{}][]uintptr
+	count func() int
+	write func(io.Writer, int) error
+}
+
+// profiles records all registered profiles.
+var profiles struct {
+	mu sync.Mutex
+	m  map[string]*Profile
+}
+
+var goroutineProfile = &Profile{
+	name:  "goroutine",
+	count: countGoroutine,
+	write: writeGoroutine,
+}
+
+var threadcreateProfile = &Profile{
+	name:  "threadcreate",
+	count: countThreadCreate,
+	write: writeThreadCreate,
+}
+
+var heapProfile = &Profile{
+	name:  "heap",
+	count: countHeap,
+	write: writeHeap,
+}
+
+var blockProfile = &Profile{
+	name:  "block",
+	count: countBlock,
+	write: writeBlock,
+}
+
+func lockProfiles() {
+	profiles.mu.Lock()
+	if profiles.m == nil {
+		// Initial built-in profiles.
+		profiles.m = map[string]*Profile{
+			"goroutine":    goroutineProfile,
+			"threadcreate": threadcreateProfile,
+			"heap":         heapProfile,
+			"block":        blockProfile,
+		}
+	}
+}
+
+func unlockProfiles() {
+	profiles.mu.Unlock()
+}
+
+// NewProfile creates a new profile with the given name.
+// If a profile with that name already exists, NewProfile panics.
+// The convention is to use a 'import/path.' prefix to create
+// separate name spaces for each package.
+func NewProfile(name string) *Profile {
+	lockProfiles()
+	defer unlockProfiles()
+	if name == "" {
+		panic("pprof: NewProfile with empty name")
+	}
+	if profiles.m[name] != nil {
+		panic("pprof: NewProfile name already in use: " + name)
+	}
+	p := &Profile{
+		name: name,
+		m:    map[interface{}][]uintptr{},
+	}
+	profiles.m[name] = p
+	return p
+}
+
+// Lookup returns the profile with the given name, or nil if no such profile exists.
+func Lookup(name string) *Profile {
+	lockProfiles()
+	defer unlockProfiles()
+	return profiles.m[name]
+}
+
+// Profiles returns a slice of all the known profiles, sorted by name.
+func Profiles() []*Profile {
+	lockProfiles()
+	defer unlockProfiles()
+
+	var all []*Profile
+	for _, p := range profiles.m {
+		all = append(all, p)
+	}
+
+	sort.Sort(byName(all))
+	return all
+}
+
+type byName []*Profile
+
+func (x byName) Len() int           { return len(x) }
+func (x byName) Swap(i, j int)      { x[i], x[j] = x[j], x[i] }
+func (x byName) Less(i, j int) bool { return x[i].name < x[j].name }
+
+// Name returns this profile's name, which can be passed to Lookup to reobtain the profile.
+func (p *Profile) Name() string {
+	return p.name
+}
+
+// Count returns the number of execution stacks currently in the profile.
+func (p *Profile) Count() int {
+	p.mu.Lock()
+	defer p.mu.Unlock()
+	if p.count != nil {
+		return p.count()
+	}
+	return len(p.m)
+}
+
+// Add adds the current execution stack to the profile, associated with value.
+// Add stores value in an internal map, so value must be suitable for use as
+// a map key and will not be garbage collected until the corresponding
+// call to Remove.  Add panics if the profile already contains a stack for value.
+//
+// The skip parameter has the same meaning as runtime.Caller's skip
+// and controls where the stack trace begins.  Passing skip=0 begins the
+// trace in the function calling Add.  For example, given this
+// execution stack:
+//
+//	Add
+//	called from rpc.NewClient
+//	called from mypkg.Run
+//	called from main.main
+//
+// Passing skip=0 begins the stack trace at the call to Add inside rpc.NewClient.
+// Passing skip=1 begins the stack trace at the call to NewClient inside mypkg.Run.
+//
+func (p *Profile) Add(value interface{}, skip int) {
+	if p.name == "" {
+		panic("pprof: use of uninitialized Profile")
+	}
+	if p.write != nil {
+		panic("pprof: Add called on built-in Profile " + p.name)
+	}
+
+	stk := make([]uintptr, 32)
+	n := runtime.Callers(skip+1, stk[:])
+
+	p.mu.Lock()
+	defer p.mu.Unlock()
+	if p.m[value] != nil {
+		panic("pprof: Profile.Add of duplicate value")
+	}
+	p.m[value] = stk[:n]
+}
+
+// Remove removes the execution stack associated with value from the profile.
+// It is a no-op if the value is not in the profile.
+func (p *Profile) Remove(value interface{}) {
+	p.mu.Lock()
+	defer p.mu.Unlock()
+	delete(p.m, value)
+}
+
+// WriteTo writes a pprof-formatted snapshot of the profile to w.
+// If a write to w returns an error, WriteTo returns that error.
+// Otherwise, WriteTo returns nil.
+//
+// The debug parameter enables additional output.
+// Passing debug=0 prints only the hexadecimal addresses that pprof needs.
+// Passing debug=1 adds comments translating addresses to function names
+// and line numbers, so that a programmer can read the profile without tools.
+//
+// The predefined profiles may assign meaning to other debug values;
+// for example, when printing the "goroutine" profile, debug=2 means to
+// print the goroutine stacks in the same form that a Go program uses
+// when dying due to an unrecovered panic.
+func (p *Profile) WriteTo(w io.Writer, debug int) error {
+	if p.name == "" {
+		panic("pprof: use of zero Profile")
+	}
+	if p.write != nil {
+		return p.write(w, debug)
+	}
+
+	// Obtain consistent snapshot under lock; then process without lock.
+	var all [][]uintptr
+	p.mu.Lock()
+	for _, stk := range p.m {
+		all = append(all, stk)
+	}
+	p.mu.Unlock()
+
+	// Map order is non-deterministic; make output deterministic.
+	sort.Sort(stackProfile(all))
+
+	return printCountProfile(w, debug, p.name, stackProfile(all))
+}
+
+type stackProfile [][]uintptr
+
+func (x stackProfile) Len() int              { return len(x) }
+func (x stackProfile) Stack(i int) []uintptr { return x[i] }
+func (x stackProfile) Swap(i, j int)         { x[i], x[j] = x[j], x[i] }
+func (x stackProfile) Less(i, j int) bool {
+	t, u := x[i], x[j]
+	for k := 0; k < len(t) && k < len(u); k++ {
+		if t[k] != u[k] {
+			return t[k] < u[k]
+		}
+	}
+	return len(t) < len(u)
+}
+
+// A countProfile is a set of stack traces to be printed as counts
+// grouped by stack trace.  There are multiple implementations:
+// all that matters is that we can find out how many traces there are
+// and obtain each trace in turn.
+type countProfile interface {
+	Len() int
+	Stack(i int) []uintptr
+}
+
+// printCountProfile prints a countProfile at the specified debug level.
+func printCountProfile(w io.Writer, debug int, name string, p countProfile) error {
+	b := bufio.NewWriter(w)
+	var tw *tabwriter.Writer
+	w = b
+	if debug > 0 {
+		tw = tabwriter.NewWriter(w, 1, 8, 1, '\t', 0)
+		w = tw
+	}
+
+	fmt.Fprintf(w, "%s profile: total %d\n", name, p.Len())
+
+	// Build count of each stack.
+	var buf bytes.Buffer
+	key := func(stk []uintptr) string {
+		buf.Reset()
+		fmt.Fprintf(&buf, "@")
+		for _, pc := range stk {
+			fmt.Fprintf(&buf, " %#x", pc)
+		}
+		return buf.String()
+	}
+	m := map[string]int{}
+	n := p.Len()
+	for i := 0; i < n; i++ {
+		m[key(p.Stack(i))]++
+	}
+
+	// Print stacks, listing count on first occurrence of a unique stack.
+	for i := 0; i < n; i++ {
+		stk := p.Stack(i)
+		s := key(stk)
+		if count := m[s]; count != 0 {
+			fmt.Fprintf(w, "%d %s\n", count, s)
+			if debug > 0 {
+				printStackRecord(w, stk, false)
+			}
+			delete(m, s)
+		}
+	}
+
+	if tw != nil {
+		tw.Flush()
+	}
+	return b.Flush()
+}
+
+// printStackRecord prints the function + source line information
+// for a single stack trace.
+func printStackRecord(w io.Writer, stk []uintptr, allFrames bool) {
+	show := allFrames
+	wasPanic := false
+	for i, pc := range stk {
+		f := runtime.FuncForPC(pc)
+		if f == nil {
+			show = true
+			fmt.Fprintf(w, "#\t%#x\n", pc)
+			wasPanic = false
+		} else {
+			tracepc := pc
+			// Back up to call instruction.
+			if i > 0 && pc > f.Entry() && !wasPanic {
+				if runtime.GOARCH == "386" || runtime.GOARCH == "amd64" {
+					tracepc--
+				} else {
+					tracepc -= 4 // arm, etc
+				}
+			}
+			file, line := f.FileLine(tracepc)
+			name := f.Name()
+			// Hide runtime.goexit and any runtime functions at the beginning.
+			// This is useful mainly for allocation traces.
+			wasPanic = name == "runtime.panic"
+			if name == "runtime.goexit" || !show && strings.HasPrefix(name, "runtime.") {
+				continue
+			}
+			show = true
+			fmt.Fprintf(w, "#\t%#x\t%s+%#x\t%s:%d\n", pc, name, pc-f.Entry(), file, line)
+		}
+	}
+	if !show {
+		// We didn't print anything; do it again,
+		// and this time include runtime functions.
+		printStackRecord(w, stk, true)
+		return
+	}
+	fmt.Fprintf(w, "\n")
+}
+
+// Interface to system profiles.
+
+type byInUseBytes []runtime.MemProfileRecord
+
+func (x byInUseBytes) Len() int           { return len(x) }
+func (x byInUseBytes) Swap(i, j int)      { x[i], x[j] = x[j], x[i] }
+func (x byInUseBytes) Less(i, j int) bool { return x[i].InUseBytes() > x[j].InUseBytes() }
+
+// WriteHeapProfile is shorthand for Lookup("heap").WriteTo(w, 0).
+// It is preserved for backwards compatibility.
+func WriteHeapProfile(w io.Writer) error {
+	return writeHeap(w, 0)
+}
+
+// countHeap returns the number of records in the heap profile.
+func countHeap() int {
+	n, _ := runtime.MemProfile(nil, true)
+	return n
+}
+
+// writeHeap writes the current runtime heap profile to w.
+func writeHeap(w io.Writer, debug int) error {
+	// Find out how many records there are (MemProfile(nil, true)),
+	// allocate that many records, and get the data.
+	// There's a race—more records might be added between
+	// the two calls—so allocate a few extra records for safety
+	// and also try again if we're very unlucky.
+	// The loop should only execute one iteration in the common case.
+	var p []runtime.MemProfileRecord
+	n, ok := runtime.MemProfile(nil, true)
+	for {
+		// Allocate room for a slightly bigger profile,
+		// in case a few more entries have been added
+		// since the call to MemProfile.
+		p = make([]runtime.MemProfileRecord, n+50)
+		n, ok = runtime.MemProfile(p, true)
+		if ok {
+			p = p[0:n]
+			break
+		}
+		// Profile grew; try again.
+	}
+
+	sort.Sort(byInUseBytes(p))
+
+	b := bufio.NewWriter(w)
+	var tw *tabwriter.Writer
+	w = b
+	if debug > 0 {
+		tw = tabwriter.NewWriter(w, 1, 8, 1, '\t', 0)
+		w = tw
+	}
+
+	var total runtime.MemProfileRecord
+	for i := range p {
+		r := &p[i]
+		total.AllocBytes += r.AllocBytes
+		total.AllocObjects += r.AllocObjects
+		total.FreeBytes += r.FreeBytes
+		total.FreeObjects += r.FreeObjects
+	}
+
+	// Technically the rate is MemProfileRate not 2*MemProfileRate,
+	// but early versions of the C++ heap profiler reported 2*MemProfileRate,
+	// so that's what pprof has come to expect.
+	fmt.Fprintf(w, "heap profile: %d: %d [%d: %d] @ heap/%d\n",
+		total.InUseObjects(), total.InUseBytes(),
+		total.AllocObjects, total.AllocBytes,
+		2*runtime.MemProfileRate)
+
+	for i := range p {
+		r := &p[i]
+		fmt.Fprintf(w, "%d: %d [%d: %d] @",
+			r.InUseObjects(), r.InUseBytes(),
+			r.AllocObjects, r.AllocBytes)
+		for _, pc := range r.Stack() {
+			fmt.Fprintf(w, " %#x", pc)
+		}
+		fmt.Fprintf(w, "\n")
+		if debug > 0 {
+			printStackRecord(w, r.Stack(), false)
+		}
+	}
+
+	// Print memstats information too.
+	// Pprof will ignore, but useful for people
+	if debug > 0 {
+		s := new(runtime.MemStats)
+		runtime.ReadMemStats(s)
+		fmt.Fprintf(w, "\n# runtime.MemStats\n")
+		fmt.Fprintf(w, "# Alloc = %d\n", s.Alloc)
+		fmt.Fprintf(w, "# TotalAlloc = %d\n", s.TotalAlloc)
+		fmt.Fprintf(w, "# Sys = %d\n", s.Sys)
+		fmt.Fprintf(w, "# Lookups = %d\n", s.Lookups)
+		fmt.Fprintf(w, "# Mallocs = %d\n", s.Mallocs)
+		fmt.Fprintf(w, "# Frees = %d\n", s.Frees)
+
+		fmt.Fprintf(w, "# HeapAlloc = %d\n", s.HeapAlloc)
+		fmt.Fprintf(w, "# HeapSys = %d\n", s.HeapSys)
+		fmt.Fprintf(w, "# HeapIdle = %d\n", s.HeapIdle)
+		fmt.Fprintf(w, "# HeapInuse = %d\n", s.HeapInuse)
+		fmt.Fprintf(w, "# HeapReleased = %d\n", s.HeapReleased)
+		fmt.Fprintf(w, "# HeapObjects = %d\n", s.HeapObjects)
+
+		fmt.Fprintf(w, "# Stack = %d / %d\n", s.StackInuse, s.StackSys)
+		fmt.Fprintf(w, "# MSpan = %d / %d\n", s.MSpanInuse, s.MSpanSys)
+		fmt.Fprintf(w, "# MCache = %d / %d\n", s.MCacheInuse, s.MCacheSys)
+		fmt.Fprintf(w, "# BuckHashSys = %d\n", s.BuckHashSys)
+
+		fmt.Fprintf(w, "# NextGC = %d\n", s.NextGC)
+		fmt.Fprintf(w, "# PauseNs = %d\n", s.PauseNs)
+		fmt.Fprintf(w, "# NumGC = %d\n", s.NumGC)
+		fmt.Fprintf(w, "# EnableGC = %v\n", s.EnableGC)
+		fmt.Fprintf(w, "# DebugGC = %v\n", s.DebugGC)
+	}
+
+	if tw != nil {
+		tw.Flush()
+	}
+	return b.Flush()
+}
+
+// countThreadCreate returns the size of the current ThreadCreateProfile.
+func countThreadCreate() int {
+	n, _ := runtime.ThreadCreateProfile(nil)
+	return n
+}
+
+// writeThreadCreate writes the current runtime ThreadCreateProfile to w.
+func writeThreadCreate(w io.Writer, debug int) error {
+	return writeRuntimeProfile(w, debug, "threadcreate", runtime.ThreadCreateProfile)
+}
+
+// countGoroutine returns the number of goroutines.
+func countGoroutine() int {
+	return runtime.NumGoroutine()
+}
+
+// writeGoroutine writes the current runtime GoroutineProfile to w.
+func writeGoroutine(w io.Writer, debug int) error {
+	if debug >= 2 {
+		return writeGoroutineStacks(w)
+	}
+	return writeRuntimeProfile(w, debug, "goroutine", runtime.GoroutineProfile)
+}
+
+func writeGoroutineStacks(w io.Writer) error {
+	// We don't know how big the buffer needs to be to collect
+	// all the goroutines.  Start with 1 MB and try a few times, doubling each time.
+	// Give up and use a truncated trace if 64 MB is not enough.
+	buf := make([]byte, 1<<20)
+	for i := 0; ; i++ {
+		n := runtime.Stack(buf, true)
+		if n < len(buf) {
+			buf = buf[:n]
+			break
+		}
+		if len(buf) >= 64<<20 {
+			// Filled 64 MB - stop there.
+			break
+		}
+		buf = make([]byte, 2*len(buf))
+	}
+	_, err := w.Write(buf)
+	return err
+}
+
+func writeRuntimeProfile(w io.Writer, debug int, name string, fetch func([]runtime.StackRecord) (int, bool)) error {
+	// Find out how many records there are (fetch(nil)),
+	// allocate that many records, and get the data.
+	// There's a race—more records might be added between
+	// the two calls—so allocate a few extra records for safety
+	// and also try again if we're very unlucky.
+	// The loop should only execute one iteration in the common case.
+	var p []runtime.StackRecord
+	n, ok := fetch(nil)
+	for {
+		// Allocate room for a slightly bigger profile,
+		// in case a few more entries have been added
+		// since the call to ThreadProfile.
+		p = make([]runtime.StackRecord, n+10)
+		n, ok = fetch(p)
+		if ok {
+			p = p[0:n]
+			break
+		}
+		// Profile grew; try again.
+	}
+
+	return printCountProfile(w, debug, name, runtimeProfile(p))
+}
+
+type runtimeProfile []runtime.StackRecord
+
+func (p runtimeProfile) Len() int              { return len(p) }
+func (p runtimeProfile) Stack(i int) []uintptr { return p[i].Stack() }
+
+var cpu struct {
+	sync.Mutex
+	profiling bool
+	done      chan bool
+}
+
+// StartCPUProfile enables CPU profiling for the current process.
+// While profiling, the profile will be buffered and written to w.
+// StartCPUProfile returns an error if profiling is already enabled.
+func StartCPUProfile(w io.Writer) error {
+	// The runtime routines allow a variable profiling rate,
+	// but in practice operating systems cannot trigger signals
+	// at more than about 500 Hz, and our processing of the
+	// signal is not cheap (mostly getting the stack trace).
+	// 100 Hz is a reasonable choice: it is frequent enough to
+	// produce useful data, rare enough not to bog down the
+	// system, and a nice round number to make it easy to
+	// convert sample counts to seconds.  Instead of requiring
+	// each client to specify the frequency, we hard code it.
+	const hz = 100
+
+	cpu.Lock()
+	defer cpu.Unlock()
+	if cpu.done == nil {
+		cpu.done = make(chan bool)
+	}
+	// Double-check.
+	if cpu.profiling {
+		return fmt.Errorf("cpu profiling already in use")
+	}
+	cpu.profiling = true
+	runtime.SetCPUProfileRate(hz)
+	go profileWriter(w)
+	return nil
+}
+
+func profileWriter(w io.Writer) {
+	for {
+		data := runtime.CPUProfile()
+		if data == nil {
+			break
+		}
+		w.Write(data)
+	}
+	cpu.done <- true
+}
+
+// StopCPUProfile stops the current CPU profile, if any.
+// StopCPUProfile only returns after all the writes for the
+// profile have completed.
+func StopCPUProfile() {
+	cpu.Lock()
+	defer cpu.Unlock()
+
+	if !cpu.profiling {
+		return
+	}
+	cpu.profiling = false
+	runtime.SetCPUProfileRate(0)
+	<-cpu.done
+}
+
+type byCycles []runtime.BlockProfileRecord
+
+func (x byCycles) Len() int           { return len(x) }
+func (x byCycles) Swap(i, j int)      { x[i], x[j] = x[j], x[i] }
+func (x byCycles) Less(i, j int) bool { return x[i].Cycles > x[j].Cycles }
+
+// countBlock returns the number of records in the blocking profile.
+func countBlock() int {
+	n, _ := runtime.BlockProfile(nil)
+	return n
+}
+
+// writeBlock writes the current blocking profile to w.
+func writeBlock(w io.Writer, debug int) error {
+	var p []runtime.BlockProfileRecord
+	n, ok := runtime.BlockProfile(nil)
+	for {
+		p = make([]runtime.BlockProfileRecord, n+50)
+		n, ok = runtime.BlockProfile(p)
+		if ok {
+			p = p[:n]
+			break
+		}
+	}
+
+	sort.Sort(byCycles(p))
+
+	b := bufio.NewWriter(w)
+	var tw *tabwriter.Writer
+	w = b
+	if debug > 0 {
+		tw = tabwriter.NewWriter(w, 1, 8, 1, '\t', 0)
+		w = tw
+	}
+
+	fmt.Fprintf(w, "--- contention:\n")
+	fmt.Fprintf(w, "cycles/second=%v\n", runtime_cyclesPerSecond())
+	for i := range p {
+		r := &p[i]
+		fmt.Fprintf(w, "%v %v @", r.Cycles, r.Count)
+		for _, pc := range r.Stack() {
+			fmt.Fprintf(w, " %#x", pc)
+		}
+		fmt.Fprint(w, "\n")
+		if debug > 0 {
+			printStackRecord(w, r.Stack(), true)
+		}
+	}
+
+	if tw != nil {
+		tw.Flush()
+	}
+	return b.Flush()
+}
+
+func runtime_cyclesPerSecond() int64
diff --git a/src/runtime/pprof/pprof_test.go b/src/runtime/pprof/pprof_test.go
new file mode 100644
index 0000000..8677cb3
--- /dev/null
+++ b/src/runtime/pprof/pprof_test.go
@@ -0,0 +1,452 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !nacl
+
+package pprof_test
+
+import (
+	"bytes"
+	"fmt"
+	"math/big"
+	"os/exec"
+	"regexp"
+	"runtime"
+	. "runtime/pprof"
+	"strings"
+	"sync"
+	"testing"
+	"time"
+	"unsafe"
+)
+
+func cpuHogger(f func()) {
+	// We only need to get one 100 Hz clock tick, so we've got
+	// a 25x safety buffer.
+	// But do at least 500 iterations (which should take about 100ms),
+	// otherwise TestCPUProfileMultithreaded can fail if only one
+	// thread is scheduled during the 250ms period.
+	t0 := time.Now()
+	for i := 0; i < 500 || time.Since(t0) < 250*time.Millisecond; i++ {
+		f()
+	}
+}
+
+var (
+	salt1 = 0
+	salt2 = 0
+)
+
+// The actual CPU hogging function.
+// Must not call other functions nor access heap/globals in the loop,
+// otherwise under race detector the samples will be in the race runtime.
+func cpuHog1() {
+	foo := salt1
+	for i := 0; i < 1e5; i++ {
+		if foo > 0 {
+			foo *= foo
+		} else {
+			foo *= foo + 1
+		}
+	}
+	salt1 = foo
+}
+
+func cpuHog2() {
+	foo := salt2
+	for i := 0; i < 1e5; i++ {
+		if foo > 0 {
+			foo *= foo
+		} else {
+			foo *= foo + 2
+		}
+	}
+	salt2 = foo
+}
+
+func TestCPUProfile(t *testing.T) {
+	testCPUProfile(t, []string{"runtime/pprof_test.cpuHog1"}, func() {
+		cpuHogger(cpuHog1)
+	})
+}
+
+func TestCPUProfileMultithreaded(t *testing.T) {
+	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(2))
+	testCPUProfile(t, []string{"runtime/pprof_test.cpuHog1", "runtime/pprof_test.cpuHog2"}, func() {
+		c := make(chan int)
+		go func() {
+			cpuHogger(cpuHog1)
+			c <- 1
+		}()
+		cpuHogger(cpuHog2)
+		<-c
+	})
+}
+
+func parseProfile(t *testing.T, bytes []byte, f func(uintptr, []uintptr)) {
+	// Convert []byte to []uintptr.
+	l := len(bytes) / int(unsafe.Sizeof(uintptr(0)))
+	val := *(*[]uintptr)(unsafe.Pointer(&bytes))
+	val = val[:l]
+
+	// 5 for the header, 2 for the per-sample header on at least one sample, 3 for the trailer.
+	if l < 5+2+3 {
+		t.Logf("profile too short: %#x", val)
+		if badOS[runtime.GOOS] {
+			t.Skipf("ignoring failure on %s; see golang.org/issue/6047", runtime.GOOS)
+			return
+		}
+		t.FailNow()
+	}
+
+	hd, val, tl := val[:5], val[5:l-3], val[l-3:]
+	if hd[0] != 0 || hd[1] != 3 || hd[2] != 0 || hd[3] != 1e6/100 || hd[4] != 0 {
+		t.Fatalf("unexpected header %#x", hd)
+	}
+
+	if tl[0] != 0 || tl[1] != 1 || tl[2] != 0 {
+		t.Fatalf("malformed end-of-data marker %#x", tl)
+	}
+
+	for len(val) > 0 {
+		if len(val) < 2 || val[0] < 1 || val[1] < 1 || uintptr(len(val)) < 2+val[1] {
+			t.Fatalf("malformed profile.  leftover: %#x", val)
+		}
+		f(val[0], val[2:2+val[1]])
+		val = val[2+val[1]:]
+	}
+}
+
+func testCPUProfile(t *testing.T, need []string, f func()) {
+	switch runtime.GOOS {
+	case "darwin":
+		out, err := exec.Command("uname", "-a").CombinedOutput()
+		if err != nil {
+			t.Fatal(err)
+		}
+		vers := string(out)
+		t.Logf("uname -a: %v", vers)
+	case "plan9":
+		// unimplemented
+		return
+	}
+
+	var prof bytes.Buffer
+	if err := StartCPUProfile(&prof); err != nil {
+		t.Fatal(err)
+	}
+	f()
+	StopCPUProfile()
+
+	// Check that profile is well formed and contains need.
+	have := make([]uintptr, len(need))
+	parseProfile(t, prof.Bytes(), func(count uintptr, stk []uintptr) {
+		for _, pc := range stk {
+			f := runtime.FuncForPC(pc)
+			if f == nil {
+				continue
+			}
+			for i, name := range need {
+				if strings.Contains(f.Name(), name) {
+					have[i] += count
+				}
+			}
+		}
+	})
+
+	if len(need) == 0 {
+		return
+	}
+
+	var total uintptr
+	for i, name := range need {
+		total += have[i]
+		t.Logf("%s: %d\n", name, have[i])
+	}
+	ok := true
+	if total == 0 {
+		t.Logf("no CPU profile samples collected")
+		ok = false
+	}
+	// We'd like to check a reasonable minimum, like
+	// total / len(have) / smallconstant, but this test is
+	// pretty flaky (see bug 7095).  So we'll just test to
+	// make sure we got at least one sample.
+	min := uintptr(1)
+	for i, name := range need {
+		if have[i] < min {
+			t.Logf("%s has %d samples out of %d, want at least %d, ideally %d", name, have[i], total, min, total/uintptr(len(have)))
+			ok = false
+		}
+	}
+
+	if !ok {
+		if badOS[runtime.GOOS] {
+			t.Skipf("ignoring failure on %s; see golang.org/issue/6047", runtime.GOOS)
+			return
+		}
+		t.FailNow()
+	}
+}
+
+func TestCPUProfileWithFork(t *testing.T) {
+	// Fork can hang if preempted with signals frequently enough (see issue 5517).
+	// Ensure that we do not do this.
+	heap := 1 << 30
+	if testing.Short() {
+		heap = 100 << 20
+	}
+	// This makes fork slower.
+	garbage := make([]byte, heap)
+	// Need to touch the slice, otherwise it won't be paged in.
+	done := make(chan bool)
+	go func() {
+		for i := range garbage {
+			garbage[i] = 42
+		}
+		done <- true
+	}()
+	<-done
+
+	var prof bytes.Buffer
+	if err := StartCPUProfile(&prof); err != nil {
+		t.Fatal(err)
+	}
+	defer StopCPUProfile()
+
+	for i := 0; i < 10; i++ {
+		exec.Command("go").CombinedOutput()
+	}
+}
+
+// Test that profiler does not observe runtime.gogo as "user" goroutine execution.
+// If it did, it would see inconsistent state and would either record an incorrect stack
+// or crash because the stack was malformed.
+func TestGoroutineSwitch(t *testing.T) {
+	// How much to try. These defaults take about 1 seconds
+	// on a 2012 MacBook Pro. The ones in short mode take
+	// about 0.1 seconds.
+	tries := 10
+	count := 1000000
+	if testing.Short() {
+		tries = 1
+	}
+	for try := 0; try < tries; try++ {
+		var prof bytes.Buffer
+		if err := StartCPUProfile(&prof); err != nil {
+			t.Fatal(err)
+		}
+		for i := 0; i < count; i++ {
+			runtime.Gosched()
+		}
+		StopCPUProfile()
+
+		// Read profile to look for entries for runtime.gogo with an attempt at a traceback.
+		// The special entry
+		parseProfile(t, prof.Bytes(), func(count uintptr, stk []uintptr) {
+			// An entry with two frames with 'System' in its top frame
+			// exists to record a PC without a traceback. Those are okay.
+			if len(stk) == 2 {
+				f := runtime.FuncForPC(stk[1])
+				if f != nil && (f.Name() == "System" || f.Name() == "ExternalCode" || f.Name() == "GC") {
+					return
+				}
+			}
+
+			// Otherwise, should not see runtime.gogo.
+			// The place we'd see it would be the inner most frame.
+			f := runtime.FuncForPC(stk[0])
+			if f != nil && f.Name() == "runtime.gogo" {
+				var buf bytes.Buffer
+				for _, pc := range stk {
+					f := runtime.FuncForPC(pc)
+					if f == nil {
+						fmt.Fprintf(&buf, "%#x ?:0\n", pc)
+					} else {
+						file, line := f.FileLine(pc)
+						fmt.Fprintf(&buf, "%#x %s:%d\n", pc, file, line)
+					}
+				}
+				t.Fatalf("found profile entry for runtime.gogo:\n%s", buf.String())
+			}
+		})
+	}
+}
+
+// Test that profiling of division operations is okay, especially on ARM. See issue 6681.
+func TestMathBigDivide(t *testing.T) {
+	testCPUProfile(t, nil, func() {
+		t := time.After(5 * time.Second)
+		pi := new(big.Int)
+		for {
+			for i := 0; i < 100; i++ {
+				n := big.NewInt(2646693125139304345)
+				d := big.NewInt(842468587426513207)
+				pi.Div(n, d)
+			}
+			select {
+			case <-t:
+				return
+			default:
+			}
+		}
+	})
+}
+
+// Operating systems that are expected to fail the tests. See issue 6047.
+var badOS = map[string]bool{
+	"darwin": true,
+	"netbsd": true,
+	"plan9":  true,
+}
+
+func TestBlockProfile(t *testing.T) {
+	type TestCase struct {
+		name string
+		f    func()
+		re   string
+	}
+	tests := [...]TestCase{
+		{"chan recv", blockChanRecv, `
+[0-9]+ [0-9]+ @ 0x[0-9,a-f]+ 0x[0-9,a-f]+ 0x[0-9,a-f]+ 0x[0-9,a-f]+ 0x[0-9,a-f]+
+#	0x[0-9,a-f]+	runtime\.chanrecv1\+0x[0-9,a-f]+	.*/src/runtime/chan.go:[0-9]+
+#	0x[0-9,a-f]+	runtime/pprof_test\.blockChanRecv\+0x[0-9,a-f]+	.*/src/runtime/pprof/pprof_test.go:[0-9]+
+#	0x[0-9,a-f]+	runtime/pprof_test\.TestBlockProfile\+0x[0-9,a-f]+	.*/src/runtime/pprof/pprof_test.go:[0-9]+
+`},
+		{"chan send", blockChanSend, `
+[0-9]+ [0-9]+ @ 0x[0-9,a-f]+ 0x[0-9,a-f]+ 0x[0-9,a-f]+ 0x[0-9,a-f]+ 0x[0-9,a-f]+
+#	0x[0-9,a-f]+	runtime\.chansend1\+0x[0-9,a-f]+	.*/src/runtime/chan.go:[0-9]+
+#	0x[0-9,a-f]+	runtime/pprof_test\.blockChanSend\+0x[0-9,a-f]+	.*/src/runtime/pprof/pprof_test.go:[0-9]+
+#	0x[0-9,a-f]+	runtime/pprof_test\.TestBlockProfile\+0x[0-9,a-f]+	.*/src/runtime/pprof/pprof_test.go:[0-9]+
+`},
+		{"chan close", blockChanClose, `
+[0-9]+ [0-9]+ @ 0x[0-9,a-f]+ 0x[0-9,a-f]+ 0x[0-9,a-f]+ 0x[0-9,a-f]+ 0x[0-9,a-f]+
+#	0x[0-9,a-f]+	runtime\.chanrecv1\+0x[0-9,a-f]+	.*/src/runtime/chan.go:[0-9]+
+#	0x[0-9,a-f]+	runtime/pprof_test\.blockChanClose\+0x[0-9,a-f]+	.*/src/runtime/pprof/pprof_test.go:[0-9]+
+#	0x[0-9,a-f]+	runtime/pprof_test\.TestBlockProfile\+0x[0-9,a-f]+	.*/src/runtime/pprof/pprof_test.go:[0-9]+
+`},
+		{"select recv async", blockSelectRecvAsync, `
+[0-9]+ [0-9]+ @ 0x[0-9,a-f]+ 0x[0-9,a-f]+ 0x[0-9,a-f]+ 0x[0-9,a-f]+ 0x[0-9,a-f]+
+#	0x[0-9,a-f]+	runtime\.selectgo\+0x[0-9,a-f]+	.*/src/runtime/select.go:[0-9]+
+#	0x[0-9,a-f]+	runtime/pprof_test\.blockSelectRecvAsync\+0x[0-9,a-f]+	.*/src/runtime/pprof/pprof_test.go:[0-9]+
+#	0x[0-9,a-f]+	runtime/pprof_test\.TestBlockProfile\+0x[0-9,a-f]+	.*/src/runtime/pprof/pprof_test.go:[0-9]+
+`},
+		{"select send sync", blockSelectSendSync, `
+[0-9]+ [0-9]+ @ 0x[0-9,a-f]+ 0x[0-9,a-f]+ 0x[0-9,a-f]+ 0x[0-9,a-f]+ 0x[0-9,a-f]+
+#	0x[0-9,a-f]+	runtime\.selectgo\+0x[0-9,a-f]+	.*/src/runtime/select.go:[0-9]+
+#	0x[0-9,a-f]+	runtime/pprof_test\.blockSelectSendSync\+0x[0-9,a-f]+	.*/src/runtime/pprof/pprof_test.go:[0-9]+
+#	0x[0-9,a-f]+	runtime/pprof_test\.TestBlockProfile\+0x[0-9,a-f]+	.*/src/runtime/pprof/pprof_test.go:[0-9]+
+`},
+		{"mutex", blockMutex, `
+[0-9]+ [0-9]+ @ 0x[0-9,a-f]+ 0x[0-9,a-f]+ 0x[0-9,a-f]+ 0x[0-9,a-f]+ 0x[0-9,a-f]+
+#	0x[0-9,a-f]+	sync\.\(\*Mutex\)\.Lock\+0x[0-9,a-f]+	.*/src/sync/mutex\.go:[0-9]+
+#	0x[0-9,a-f]+	runtime/pprof_test\.blockMutex\+0x[0-9,a-f]+	.*/src/runtime/pprof/pprof_test.go:[0-9]+
+#	0x[0-9,a-f]+	runtime/pprof_test\.TestBlockProfile\+0x[0-9,a-f]+	.*/src/runtime/pprof/pprof_test.go:[0-9]+
+`},
+		{"cond", blockCond, `
+[0-9]+ [0-9]+ @ 0x[0-9,a-f]+ 0x[0-9,a-f]+ 0x[0-9,a-f]+ 0x[0-9,a-f]+ 0x[0-9,a-f]+
+#	0x[0-9,a-f]+	sync\.\(\*Cond\)\.Wait\+0x[0-9,a-f]+	.*/src/sync/cond\.go:[0-9]+
+#	0x[0-9,a-f]+	runtime/pprof_test\.blockCond\+0x[0-9,a-f]+	.*/src/runtime/pprof/pprof_test.go:[0-9]+
+#	0x[0-9,a-f]+	runtime/pprof_test\.TestBlockProfile\+0x[0-9,a-f]+	.*/src/runtime/pprof/pprof_test.go:[0-9]+
+`},
+	}
+
+	runtime.SetBlockProfileRate(1)
+	defer runtime.SetBlockProfileRate(0)
+	for _, test := range tests {
+		test.f()
+	}
+	var w bytes.Buffer
+	Lookup("block").WriteTo(&w, 1)
+	prof := w.String()
+
+	if !strings.HasPrefix(prof, "--- contention:\ncycles/second=") {
+		t.Fatalf("Bad profile header:\n%v", prof)
+	}
+
+	for _, test := range tests {
+		if !regexp.MustCompile(test.re).MatchString(prof) {
+			t.Fatalf("Bad %v entry, expect:\n%v\ngot:\n%v", test.name, test.re, prof)
+		}
+	}
+}
+
+const blockDelay = 10 * time.Millisecond
+
+func blockChanRecv() {
+	c := make(chan bool)
+	go func() {
+		time.Sleep(blockDelay)
+		c <- true
+	}()
+	<-c
+}
+
+func blockChanSend() {
+	c := make(chan bool)
+	go func() {
+		time.Sleep(blockDelay)
+		<-c
+	}()
+	c <- true
+}
+
+func blockChanClose() {
+	c := make(chan bool)
+	go func() {
+		time.Sleep(blockDelay)
+		close(c)
+	}()
+	<-c
+}
+
+func blockSelectRecvAsync() {
+	c := make(chan bool, 1)
+	c2 := make(chan bool, 1)
+	go func() {
+		time.Sleep(blockDelay)
+		c <- true
+	}()
+	select {
+	case <-c:
+	case <-c2:
+	}
+}
+
+func blockSelectSendSync() {
+	c := make(chan bool)
+	c2 := make(chan bool)
+	go func() {
+		time.Sleep(blockDelay)
+		<-c
+	}()
+	select {
+	case c <- true:
+	case c2 <- true:
+	}
+}
+
+func blockMutex() {
+	var mu sync.Mutex
+	mu.Lock()
+	go func() {
+		time.Sleep(blockDelay)
+		mu.Unlock()
+	}()
+	mu.Lock()
+}
+
+func blockCond() {
+	var mu sync.Mutex
+	c := sync.NewCond(&mu)
+	mu.Lock()
+	go func() {
+		time.Sleep(blockDelay)
+		mu.Lock()
+		c.Signal()
+		mu.Unlock()
+	}()
+	c.Wait()
+	mu.Unlock()
+}
diff --git a/src/runtime/print1.go b/src/runtime/print1.go
new file mode 100644
index 0000000..8f82688
--- /dev/null
+++ b/src/runtime/print1.go
@@ -0,0 +1,323 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package runtime
+
+import "unsafe"
+
+// The compiler knows that a print of a value of this type
+// should use printhex instead of printuint (decimal).
+type hex uint64
+
+func bytes(s string) (ret []byte) {
+	rp := (*slice)(unsafe.Pointer(&ret))
+	sp := (*_string)(noescape(unsafe.Pointer(&s)))
+	rp.array = sp.str
+	rp.len = uint(sp.len)
+	rp.cap = uint(sp.len)
+	return
+}
+
+// printf is only called from C code. It has no type information for the args,
+// but C stacks are ignored by the garbage collector anyway, so having
+// type information would not add anything.
+//go:nosplit
+func printf(s *byte) {
+	vprintf(gostringnocopy(s), add(unsafe.Pointer(&s), unsafe.Sizeof(s)))
+}
+
+// sprintf is only called from C code. It has no type information for the args,
+// but C stacks are ignored by the garbage collector anyway, so having
+// type information would not add anything.
+//go:nosplit
+func snprintf(dst *byte, n int32, s *byte) {
+	buf := (*[1 << 30]byte)(unsafe.Pointer(dst))[0:n:n]
+
+	gp := getg()
+	gp.writebuf = buf[0:0 : n-1] // leave room for NUL, this is called from C
+	vprintf(gostringnocopy(s), add(unsafe.Pointer(&s), unsafe.Sizeof(s)))
+	buf[len(gp.writebuf)] = '\x00'
+	gp.writebuf = nil
+}
+
+//var debuglock mutex
+
+// write to goroutine-local buffer if diverting output,
+// or else standard error.
+func gwrite(b []byte) {
+	if len(b) == 0 {
+		return
+	}
+	gp := getg()
+	if gp == nil || gp.writebuf == nil {
+		write(2, unsafe.Pointer(&b[0]), int32(len(b)))
+		return
+	}
+
+	n := copy(gp.writebuf[len(gp.writebuf):cap(gp.writebuf)], b)
+	gp.writebuf = gp.writebuf[:len(gp.writebuf)+n]
+}
+
+func prints(s *byte) {
+	b := (*[1 << 30]byte)(unsafe.Pointer(s))
+	for i := 0; ; i++ {
+		if b[i] == 0 {
+			gwrite(b[:i])
+			return
+		}
+	}
+}
+
+func printsp() {
+	print(" ")
+}
+
+func printnl() {
+	print("\n")
+}
+
+// Very simple printf.  Only for debugging prints.
+// Do not add to this without checking with Rob.
+func vprintf(str string, arg unsafe.Pointer) {
+	//lock(&debuglock);
+
+	s := bytes(str)
+	start := 0
+	i := 0
+	for ; i < len(s); i++ {
+		if s[i] != '%' {
+			continue
+		}
+		if i > start {
+			gwrite(s[start:i])
+		}
+		if i++; i >= len(s) {
+			break
+		}
+		var siz uintptr
+		switch s[i] {
+		case 't', 'c':
+			siz = 1
+		case 'd', 'x': // 32-bit
+			arg = roundup(arg, 4)
+			siz = 4
+		case 'D', 'U', 'X', 'f': // 64-bit
+			arg = roundup(arg, unsafe.Sizeof(uintreg(0)))
+			siz = 8
+		case 'C':
+			arg = roundup(arg, unsafe.Sizeof(uintreg(0)))
+			siz = 16
+		case 'p', 's': // pointer-sized
+			arg = roundup(arg, unsafe.Sizeof(uintptr(0)))
+			siz = unsafe.Sizeof(uintptr(0))
+		case 'S': // pointer-aligned but bigger
+			arg = roundup(arg, unsafe.Sizeof(uintptr(0)))
+			siz = unsafe.Sizeof(string(""))
+		case 'a': // pointer-aligned but bigger
+			arg = roundup(arg, unsafe.Sizeof(uintptr(0)))
+			siz = unsafe.Sizeof([]byte{})
+		case 'i', 'e': // pointer-aligned but bigger
+			arg = roundup(arg, unsafe.Sizeof(uintptr(0)))
+			siz = unsafe.Sizeof(interface{}(nil))
+		}
+		switch s[i] {
+		case 'a':
+			printslice(*(*[]byte)(arg))
+		case 'c':
+			printbyte(*(*byte)(arg))
+		case 'd':
+			printint(int64(*(*int32)(arg)))
+		case 'D':
+			printint(int64(*(*int64)(arg)))
+		case 'e':
+			printeface(*(*interface{})(arg))
+		case 'f':
+			printfloat(*(*float64)(arg))
+		case 'C':
+			printcomplex(*(*complex128)(arg))
+		case 'i':
+			printiface(*(*fInterface)(arg))
+		case 'p':
+			printpointer(*(*unsafe.Pointer)(arg))
+		case 's':
+			prints(*(**byte)(arg))
+		case 'S':
+			printstring(*(*string)(arg))
+		case 't':
+			printbool(*(*bool)(arg))
+		case 'U':
+			printuint(*(*uint64)(arg))
+		case 'x':
+			printhex(uint64(*(*uint32)(arg)))
+		case 'X':
+			printhex(*(*uint64)(arg))
+		}
+		arg = add(arg, siz)
+		start = i + 1
+	}
+	if start < i {
+		gwrite(s[start:i])
+	}
+
+	//unlock(&debuglock);
+}
+
+func printpc(p unsafe.Pointer) {
+	print("PC=", hex(uintptr(p)))
+}
+
+func printbool(v bool) {
+	if v {
+		print("true")
+	} else {
+		print("false")
+	}
+}
+
+func printbyte(c byte) {
+	gwrite((*[1]byte)(unsafe.Pointer(&c))[:])
+}
+
+func printfloat(v float64) {
+	switch {
+	case v != v:
+		print("NaN")
+		return
+	case v+v == v && v > 0:
+		print("+Inf")
+		return
+	case v+v == v && v < 0:
+		print("-Inf")
+		return
+	}
+
+	const n = 7 // digits printed
+	var buf [n + 7]byte
+	buf[0] = '+'
+	e := 0 // exp
+	if v == 0 {
+		if 1/v < 0 {
+			buf[0] = '-'
+		}
+	} else {
+		if v < 0 {
+			v = -v
+			buf[0] = '-'
+		}
+
+		// normalize
+		for v >= 10 {
+			e++
+			v /= 10
+		}
+		for v < 1 {
+			e--
+			v *= 10
+		}
+
+		// round
+		h := 5.0
+		for i := 0; i < n; i++ {
+			h /= 10
+		}
+		v += h
+		if v >= 10 {
+			e++
+			v /= 10
+		}
+	}
+
+	// format +d.dddd+edd
+	for i := 0; i < n; i++ {
+		s := int(v)
+		buf[i+2] = byte(s + '0')
+		v -= float64(s)
+		v *= 10
+	}
+	buf[1] = buf[2]
+	buf[2] = '.'
+
+	buf[n+2] = 'e'
+	buf[n+3] = '+'
+	if e < 0 {
+		e = -e
+		buf[n+3] = '-'
+	}
+
+	buf[n+4] = byte(e/100) + '0'
+	buf[n+5] = byte(e/10)%10 + '0'
+	buf[n+6] = byte(e%10) + '0'
+	gwrite(buf[:])
+}
+
+func printcomplex(c complex128) {
+	print("(", real(c), imag(c), "i)")
+}
+
+func printuint(v uint64) {
+	var buf [100]byte
+	i := len(buf)
+	for i--; i > 0; i-- {
+		buf[i] = byte(v%10 + '0')
+		if v < 10 {
+			break
+		}
+		v /= 10
+	}
+	gwrite(buf[i:])
+}
+
+func printint(v int64) {
+	if v < 0 {
+		print("-")
+		v = -v
+	}
+	printuint(uint64(v))
+}
+
+func printhex(v uint64) {
+	const dig = "0123456789abcdef"
+	var buf [100]byte
+	i := len(buf)
+	for i--; i > 0; i-- {
+		buf[i] = dig[v%16]
+		if v < 16 {
+			break
+		}
+		v /= 16
+	}
+	i--
+	buf[i] = 'x'
+	i--
+	buf[i] = '0'
+	gwrite(buf[i:])
+}
+
+func printpointer(p unsafe.Pointer) {
+	printhex(uint64(uintptr(p)))
+}
+
+func printstring(s string) {
+	if uintptr(len(s)) > maxstring {
+		gwrite(bytes("[string too long]"))
+		return
+	}
+	gwrite(bytes(s))
+}
+
+func printslice(s []byte) {
+	sp := (*slice)(unsafe.Pointer(&s))
+	print("[", len(s), "/", cap(s), "]")
+	printpointer(unsafe.Pointer(sp.array))
+}
+
+func printeface(e interface{}) {
+	ep := (*eface)(unsafe.Pointer(&e))
+	print("(", ep._type, ",", ep.data, ")")
+}
+
+func printiface(i fInterface) {
+	ip := (*iface)(unsafe.Pointer(&i))
+	print("(", ip.tab, ",", ip.data, ")")
+}
diff --git a/src/runtime/proc.c b/src/runtime/proc.c
new file mode 100644
index 0000000..8462c4b
--- /dev/null
+++ b/src/runtime/proc.c
@@ -0,0 +1,3521 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "runtime.h"
+#include "arch_GOARCH.h"
+#include "zaexperiment.h"
+#include "malloc.h"
+#include "stack.h"
+#include "race.h"
+#include "type.h"
+#include "mgc0.h"
+#include "textflag.h"
+
+// Goroutine scheduler
+// The scheduler's job is to distribute ready-to-run goroutines over worker threads.
+//
+// The main concepts are:
+// G - goroutine.
+// M - worker thread, or machine.
+// P - processor, a resource that is required to execute Go code.
+//     M must have an associated P to execute Go code, however it can be
+//     blocked or in a syscall w/o an associated P.
+//
+// Design doc at http://golang.org/s/go11sched.
+
+enum
+{
+	// Number of goroutine ids to grab from runtime·sched.goidgen to local per-P cache at once.
+	// 16 seems to provide enough amortization, but other than that it's mostly arbitrary number.
+	GoidCacheBatch = 16,
+};
+
+SchedT	runtime·sched;
+int32	runtime·gomaxprocs;
+uint32	runtime·needextram;
+bool	runtime·iscgo;
+M	runtime·m0;
+G	runtime·g0;	// idle goroutine for m0
+G*	runtime·lastg;
+M*	runtime·allm;
+M*	runtime·extram;
+P*	runtime·allp[MaxGomaxprocs+1];
+int8*	runtime·goos;
+int32	runtime·ncpu;
+int32	runtime·newprocs;
+
+Mutex runtime·allglock;	// the following vars are protected by this lock or by stoptheworld
+G**	runtime·allg;
+Slice	runtime·allgs;
+uintptr runtime·allglen;
+ForceGCState	runtime·forcegc;
+
+void runtime·mstart(void);
+static void runqput(P*, G*);
+static G* runqget(P*);
+static bool runqputslow(P*, G*, uint32, uint32);
+static G* runqsteal(P*, P*);
+static void mput(M*);
+static M* mget(void);
+static void mcommoninit(M*);
+static void schedule(void);
+static void procresize(int32);
+static void acquirep(P*);
+static P* releasep(void);
+static void newm(void(*)(void), P*);
+static void stopm(void);
+static void startm(P*, bool);
+static void handoffp(P*);
+static void wakep(void);
+static void stoplockedm(void);
+static void startlockedm(G*);
+static void sysmon(void);
+static uint32 retake(int64);
+static void incidlelocked(int32);
+static void checkdead(void);
+static void exitsyscall0(G*);
+void runtime·park_m(G*);
+static void goexit0(G*);
+static void gfput(P*, G*);
+static G* gfget(P*);
+static void gfpurge(P*);
+static void globrunqput(G*);
+static void globrunqputbatch(G*, G*, int32);
+static G* globrunqget(P*, int32);
+static P* pidleget(void);
+static void pidleput(P*);
+static void injectglist(G*);
+static bool preemptall(void);
+static bool preemptone(P*);
+static bool exitsyscallfast(void);
+static bool haveexperiment(int8*);
+void runtime·allgadd(G*);
+static void dropg(void);
+
+extern String runtime·buildVersion;
+
+// For cgo-using programs with external linking,
+// export "main" (defined in assembly) so that libc can handle basic
+// C runtime startup and call the Go program as if it were
+// the C main function.
+#pragma cgo_export_static main
+
+// Filled in by dynamic linker when Cgo is available.
+void (*_cgo_init)(void);
+void (*_cgo_malloc)(void);
+void (*_cgo_free)(void);
+
+// Copy for Go code.
+void* runtime·cgoMalloc;
+void* runtime·cgoFree;
+
+// The bootstrap sequence is:
+//
+//	call osinit
+//	call schedinit
+//	make & queue new G
+//	call runtime·mstart
+//
+// The new G calls runtime·main.
+void
+runtime·schedinit(void)
+{
+	int32 n, procs;
+	byte *p;
+
+	// raceinit must be the first call to race detector.
+	// In particular, it must be done before mallocinit below calls racemapshadow.
+	if(raceenabled)
+		g->racectx = runtime·raceinit();
+
+	runtime·sched.maxmcount = 10000;
+
+	runtime·tracebackinit();
+	runtime·symtabinit();
+	runtime·stackinit();
+	runtime·mallocinit();
+	mcommoninit(g->m);
+	
+	runtime·goargs();
+	runtime·goenvs();
+	runtime·parsedebugvars();
+	runtime·gcinit();
+
+	runtime·sched.lastpoll = runtime·nanotime();
+	procs = 1;
+	p = runtime·getenv("GOMAXPROCS");
+	if(p != nil && (n = runtime·atoi(p)) > 0) {
+		if(n > MaxGomaxprocs)
+			n = MaxGomaxprocs;
+		procs = n;
+	}
+	procresize(procs);
+
+	if(runtime·buildVersion.str == nil) {
+		// Condition should never trigger.  This code just serves
+		// to ensure runtime·buildVersion is kept in the resulting binary.
+		runtime·buildVersion.str = (uint8*)"unknown";
+		runtime·buildVersion.len = 7;
+	}
+
+	runtime·cgoMalloc = _cgo_malloc;
+	runtime·cgoFree = _cgo_free;
+}
+
+void
+runtime·newsysmon(void)
+{
+	newm(sysmon, nil);
+}
+
+static void
+dumpgstatus(G* gp)
+{
+	runtime·printf("runtime: gp: gp=%p, goid=%D, gp->atomicstatus=%x\n", gp, gp->goid, runtime·readgstatus(gp));
+	runtime·printf("runtime:  g:  g=%p, goid=%D,  g->atomicstatus=%x\n", g, g->goid, runtime·readgstatus(g));
+}
+
+static void
+checkmcount(void)
+{
+	// sched lock is held
+	if(runtime·sched.mcount > runtime·sched.maxmcount){
+		runtime·printf("runtime: program exceeds %d-thread limit\n", runtime·sched.maxmcount);
+		runtime·throw("thread exhaustion");
+	}
+}
+
+static void
+mcommoninit(M *mp)
+{
+	// g0 stack won't make sense for user (and is not necessary unwindable).
+	if(g != g->m->g0)
+		runtime·callers(1, mp->createstack, nelem(mp->createstack));
+
+	mp->fastrand = 0x49f6428aUL + mp->id + runtime·cputicks();
+
+	runtime·lock(&runtime·sched.lock);
+	mp->id = runtime·sched.mcount++;
+	checkmcount();
+	runtime·mpreinit(mp);
+	if(mp->gsignal)
+		mp->gsignal->stackguard1 = mp->gsignal->stack.lo + StackGuard;
+
+	// Add to runtime·allm so garbage collector doesn't free g->m
+	// when it is just in a register or thread-local storage.
+	mp->alllink = runtime·allm;
+	// runtime·NumCgoCall() iterates over allm w/o schedlock,
+	// so we need to publish it safely.
+	runtime·atomicstorep(&runtime·allm, mp);
+	runtime·unlock(&runtime·sched.lock);
+}
+
+// Mark gp ready to run.
+void
+runtime·ready(G *gp)
+{
+	uint32 status;
+
+	status = runtime·readgstatus(gp);
+	// Mark runnable.
+	g->m->locks++;  // disable preemption because it can be holding p in a local var
+	if((status&~Gscan) != Gwaiting){
+		dumpgstatus(gp);
+		runtime·throw("bad g->status in ready");
+	}
+	// status is Gwaiting or Gscanwaiting, make Grunnable and put on runq
+	runtime·casgstatus(gp, Gwaiting, Grunnable);
+	runqput(g->m->p, gp);
+	if(runtime·atomicload(&runtime·sched.npidle) != 0 && runtime·atomicload(&runtime·sched.nmspinning) == 0)  // TODO: fast atomic
+		wakep();
+	g->m->locks--;
+	if(g->m->locks == 0 && g->preempt)  // restore the preemption request in case we've cleared it in newstack
+		g->stackguard0 = StackPreempt;
+}
+
+void
+runtime·ready_m(void)
+{
+	G *gp;
+
+	gp = g->m->ptrarg[0];
+	g->m->ptrarg[0] = nil;
+	runtime·ready(gp);
+}
+
+int32
+runtime·gcprocs(void)
+{
+	int32 n;
+
+	// Figure out how many CPUs to use during GC.
+	// Limited by gomaxprocs, number of actual CPUs, and MaxGcproc.
+	runtime·lock(&runtime·sched.lock);
+	n = runtime·gomaxprocs;
+	if(n > runtime·ncpu)
+		n = runtime·ncpu;
+	if(n > MaxGcproc)
+		n = MaxGcproc;
+	if(n > runtime·sched.nmidle+1) // one M is currently running
+		n = runtime·sched.nmidle+1;
+	runtime·unlock(&runtime·sched.lock);
+	return n;
+}
+
+static bool
+needaddgcproc(void)
+{
+	int32 n;
+
+	runtime·lock(&runtime·sched.lock);
+	n = runtime·gomaxprocs;
+	if(n > runtime·ncpu)
+		n = runtime·ncpu;
+	if(n > MaxGcproc)
+		n = MaxGcproc;
+	n -= runtime·sched.nmidle+1; // one M is currently running
+	runtime·unlock(&runtime·sched.lock);
+	return n > 0;
+}
+
+void
+runtime·helpgc(int32 nproc)
+{
+	M *mp;
+	int32 n, pos;
+
+	runtime·lock(&runtime·sched.lock);
+	pos = 0;
+	for(n = 1; n < nproc; n++) {  // one M is currently running
+		if(runtime·allp[pos]->mcache == g->m->mcache)
+			pos++;
+		mp = mget();
+		if(mp == nil)
+			runtime·throw("runtime·gcprocs inconsistency");
+		mp->helpgc = n;
+		mp->mcache = runtime·allp[pos]->mcache;
+		pos++;
+		runtime·notewakeup(&mp->park);
+	}
+	runtime·unlock(&runtime·sched.lock);
+}
+
+// Similar to stoptheworld but best-effort and can be called several times.
+// There is no reverse operation, used during crashing.
+// This function must not lock any mutexes.
+void
+runtime·freezetheworld(void)
+{
+	int32 i;
+
+	if(runtime·gomaxprocs == 1)
+		return;
+	// stopwait and preemption requests can be lost
+	// due to races with concurrently executing threads,
+	// so try several times
+	for(i = 0; i < 5; i++) {
+		// this should tell the scheduler to not start any new goroutines
+		runtime·sched.stopwait = 0x7fffffff;
+		runtime·atomicstore((uint32*)&runtime·sched.gcwaiting, 1);
+		// this should stop running goroutines
+		if(!preemptall())
+			break;  // no running goroutines
+		runtime·usleep(1000);
+	}
+	// to be sure
+	runtime·usleep(1000);
+	preemptall();
+	runtime·usleep(1000);
+}
+
+static bool
+isscanstatus(uint32 status)
+{
+	if(status == Gscan)
+		runtime·throw("isscanstatus: Bad status Gscan");
+	return (status&Gscan) == Gscan;
+}
+
+// All reads and writes of g's status go through readgstatus, casgstatus
+// castogscanstatus, casfromgscanstatus.
+#pragma textflag NOSPLIT
+uint32
+runtime·readgstatus(G *gp)
+{
+	return runtime·atomicload(&gp->atomicstatus);
+}
+
+// The Gscanstatuses are acting like locks and this releases them.
+// If it proves to be a performance hit we should be able to make these
+// simple atomic stores but for now we are going to throw if
+// we see an inconsistent state.
+void
+runtime·casfromgscanstatus(G *gp, uint32 oldval, uint32 newval)
+{
+	bool success = false;
+
+	// Check that transition is valid.
+	switch(oldval) {
+	case Gscanrunnable:
+	case Gscanwaiting:
+	case Gscanrunning:
+	case Gscansyscall:
+		if(newval == (oldval&~Gscan))
+			success = runtime·cas(&gp->atomicstatus, oldval, newval);
+		break;
+	case Gscanenqueue:
+		if(newval == Gwaiting)
+			success = runtime·cas(&gp->atomicstatus, oldval, newval);
+		break;
+	}	
+	if(!success){
+		runtime·printf("runtime: casfromgscanstatus failed gp=%p, oldval=%d, newval=%d\n",  
+			gp, oldval, newval);
+		dumpgstatus(gp);
+		runtime·throw("casfromgscanstatus: gp->status is not in scan state");
+	}
+}
+
+// This will return false if the gp is not in the expected status and the cas fails. 
+// This acts like a lock acquire while the casfromgstatus acts like a lock release.
+bool
+runtime·castogscanstatus(G *gp, uint32 oldval, uint32 newval)
+{
+	switch(oldval) {
+	case Grunnable:
+	case Gwaiting:
+	case Gsyscall:
+		if(newval == (oldval|Gscan))
+			return runtime·cas(&gp->atomicstatus, oldval, newval);
+		break;
+	case Grunning:
+		if(newval == Gscanrunning || newval == Gscanenqueue)
+			return runtime·cas(&gp->atomicstatus, oldval, newval);
+		break;   
+	}
+
+	runtime·printf("runtime: castogscanstatus oldval=%d newval=%d\n", oldval, newval);
+	runtime·throw("castogscanstatus");
+	return false; // not reached
+}
+
+static void badcasgstatus(void);
+static void helpcasgstatus(void);
+static void badgstatusrunnable(void);
+
+// If asked to move to or from a Gscanstatus this will throw. Use the castogscanstatus
+// and casfromgscanstatus instead.
+// casgstatus will loop if the g->atomicstatus is in a Gscan status until the routine that 
+// put it in the Gscan state is finished.
+#pragma textflag NOSPLIT
+void
+runtime·casgstatus(G *gp, uint32 oldval, uint32 newval)
+{
+	void (*fn)(void);
+
+	if((oldval&Gscan) || (newval&Gscan) || oldval == newval) {
+		g->m->scalararg[0] = oldval;
+		g->m->scalararg[1] = newval;
+		fn = badcasgstatus;
+		runtime·onM(&fn);
+	}
+
+	// loop if gp->atomicstatus is in a scan state giving
+	// GC time to finish and change the state to oldval.
+	while(!runtime·cas(&gp->atomicstatus, oldval, newval)) {
+		if(oldval == Gwaiting && gp->atomicstatus == Grunnable) {
+			fn = badgstatusrunnable;
+			runtime·onM(&fn);
+		}
+		// Help GC if needed. 
+		if(gp->preemptscan && !gp->gcworkdone && (oldval == Grunning || oldval == Gsyscall)) {
+			gp->preemptscan = false;
+			g->m->ptrarg[0] = gp;
+			fn = helpcasgstatus;
+			runtime·onM(&fn);
+		}
+	}	
+}
+
+static void
+badgstatusrunnable(void)
+{
+	runtime·throw("casgstatus: waiting for Gwaiting but is Grunnable");
+}
+
+// casgstatus(gp, oldstatus, Gcopystack), assuming oldstatus is Gwaiting or Grunnable.
+// Returns old status. Cannot call casgstatus directly, because we are racing with an
+// async wakeup that might come in from netpoll. If we see Gwaiting from the readgstatus,
+// it might have become Grunnable by the time we get to the cas. If we called casgstatus,
+// it would loop waiting for the status to go back to Gwaiting, which it never will.
+#pragma textflag NOSPLIT
+uint32
+runtime·casgcopystack(G *gp)
+{
+	uint32 oldstatus;
+
+	for(;;) {
+		oldstatus = runtime·readgstatus(gp) & ~Gscan;
+		if(oldstatus != Gwaiting && oldstatus != Grunnable)
+			runtime·throw("copystack: bad status, not Gwaiting or Grunnable");
+		if(runtime·cas(&gp->atomicstatus, oldstatus, Gcopystack))
+			break;
+	}
+	return oldstatus;
+}
+
+static void
+badcasgstatus(void)
+{
+	uint32 oldval, newval;
+	
+	oldval = g->m->scalararg[0];
+	newval = g->m->scalararg[1];
+	g->m->scalararg[0] = 0;
+	g->m->scalararg[1] = 0;
+
+	runtime·printf("casgstatus: oldval=%d, newval=%d\n", oldval, newval);
+	runtime·throw("casgstatus: bad incoming values");
+}
+
+static void
+helpcasgstatus(void)
+{
+	G *gp;
+	
+	gp = g->m->ptrarg[0];
+	g->m->ptrarg[0] = 0;
+	runtime·gcphasework(gp);
+}
+
+// stopg ensures that gp is stopped at a GC safe point where its stack can be scanned
+// or in the context of a moving collector the pointers can be flipped from pointing 
+// to old object to pointing to new objects. 
+// If stopg returns true, the caller knows gp is at a GC safe point and will remain there until
+// the caller calls restartg.
+// If stopg returns false, the caller is not responsible for calling restartg. This can happen
+// if another thread, either the gp itself or another GC thread is taking the responsibility 
+// to do the GC work related to this thread.
+bool
+runtime·stopg(G *gp)
+{
+	uint32 s;
+
+	for(;;) {
+		if(gp->gcworkdone)
+			return false;
+
+		s = runtime·readgstatus(gp);
+		switch(s) {
+		default:
+			dumpgstatus(gp);
+			runtime·throw("stopg: gp->atomicstatus is not valid");
+
+		case Gdead:
+			return false;
+
+		case Gcopystack:
+			// Loop until a new stack is in place.
+			break;
+
+		case Grunnable:
+		case Gsyscall:
+		case Gwaiting:
+			// Claim goroutine by setting scan bit.
+			if(!runtime·castogscanstatus(gp, s, s|Gscan))
+				break;
+			// In scan state, do work.
+			runtime·gcphasework(gp);
+			return true;
+
+		case Gscanrunnable:
+		case Gscanwaiting:
+		case Gscansyscall:
+			// Goroutine already claimed by another GC helper.
+			return false;
+
+		case Grunning:
+			// Claim goroutine, so we aren't racing with a status
+			// transition away from Grunning.
+			if(!runtime·castogscanstatus(gp, Grunning, Gscanrunning))
+				break;
+
+			// Mark gp for preemption.
+			if(!gp->gcworkdone) {
+				gp->preemptscan = true;
+				gp->preempt = true;
+				gp->stackguard0 = StackPreempt;
+			}
+
+			// Unclaim.
+			runtime·casfromgscanstatus(gp, Gscanrunning, Grunning);
+			return false;
+		}
+	}
+	// Should not be here....
+}
+
+// The GC requests that this routine be moved from a scanmumble state to a mumble state.
+void 
+runtime·restartg (G *gp)
+{
+	uint32 s;
+
+	s = runtime·readgstatus(gp);
+	switch(s) {
+	default:
+		dumpgstatus(gp); 
+		runtime·throw("restartg: unexpected status");
+
+	case Gdead:
+		break;
+
+	case Gscanrunnable:
+	case Gscanwaiting:
+	case Gscansyscall:
+		runtime·casfromgscanstatus(gp, s, s&~Gscan);
+		break;
+
+	case Gscanenqueue:
+		// Scan is now completed.
+		// Goroutine now needs to be made runnable.
+		// We put it on the global run queue; ready blocks on the global scheduler lock.
+		runtime·casfromgscanstatus(gp, Gscanenqueue, Gwaiting);
+		if(gp != g->m->curg)
+			runtime·throw("processing Gscanenqueue on wrong m");
+		dropg();
+		runtime·ready(gp);
+		break;
+	}
+}
+
+static void
+stopscanstart(G* gp)
+{
+	if(g == gp)
+		runtime·throw("GC not moved to G0");
+	if(runtime·stopg(gp)) {
+		if(!isscanstatus(runtime·readgstatus(gp))) {
+			dumpgstatus(gp);
+			runtime·throw("GC not in scan state");
+		}
+		runtime·restartg(gp);
+	}
+}
+
+// Runs on g0 and does the actual work after putting the g back on the run queue.
+static void
+mquiesce(G *gpmaster)
+{
+	G* gp;
+	uint32 i;
+	uint32 status;
+	uint32 activeglen;
+
+	activeglen = runtime·allglen;
+	// enqueue the calling goroutine.
+	runtime·restartg(gpmaster);
+	for(i = 0; i < activeglen; i++) {
+		gp = runtime·allg[i];
+		if(runtime·readgstatus(gp) == Gdead) 
+			gp->gcworkdone = true; // noop scan.
+		else 
+			gp->gcworkdone = false; 
+		stopscanstart(gp); 
+	}
+
+	// Check that the G's gcwork (such as scanning) has been done. If not do it now. 
+	// You can end up doing work here if the page trap on a Grunning Goroutine has
+	// not been sprung or in some race situations. For example a runnable goes dead
+	// and is started up again with a gp->gcworkdone set to false.
+	for(i = 0; i < activeglen; i++) {
+		gp = runtime·allg[i];
+		while (!gp->gcworkdone) {
+			status = runtime·readgstatus(gp);
+			if(status == Gdead) {
+				gp->gcworkdone = true; // scan is a noop
+				break;
+				//do nothing, scan not needed. 
+			}
+			if(status == Grunning && gp->stackguard0 == (uintptr)StackPreempt && runtime·notetsleep(&runtime·sched.stopnote, 100*1000)) // nanosecond arg 
+				runtime·noteclear(&runtime·sched.stopnote);
+			else 
+				stopscanstart(gp);
+		}
+	}
+
+	for(i = 0; i < activeglen; i++) {
+		gp = runtime·allg[i];
+		status = runtime·readgstatus(gp);
+		if(isscanstatus(status)) {
+			runtime·printf("mstopandscang:bottom: post scan bad status gp=%p has status %x\n", gp, status);
+			dumpgstatus(gp);
+		}
+		if(!gp->gcworkdone && status != Gdead) {
+			runtime·printf("mstopandscang:bottom: post scan gp=%p->gcworkdone still false\n", gp);
+			dumpgstatus(gp);
+		}
+	}
+
+	schedule(); // Never returns.
+}
+
+// quiesce moves all the goroutines to a GC safepoint which for now is a at preemption point.
+// If the global runtime·gcphase is GCmark quiesce will ensure that all of the goroutine's stacks
+// have been scanned before it returns.
+void
+runtime·quiesce(G* mastergp)
+{
+	void (*fn)(G*);
+
+	runtime·castogscanstatus(mastergp, Grunning, Gscanenqueue);
+	// Now move this to the g0 (aka m) stack.
+	// g0 will potentially scan this thread and put mastergp on the runqueue 
+	fn = mquiesce;
+	runtime·mcall(&fn);
+}
+
+// This is used by the GC as well as the routines that do stack dumps. In the case
+// of GC all the routines can be reliably stopped. This is not always the case
+// when the system is in panic or being exited.
+void
+runtime·stoptheworld(void)
+{
+	int32 i;
+	uint32 s;
+	P *p;
+	bool wait;
+
+	// If we hold a lock, then we won't be able to stop another M
+	// that is blocked trying to acquire the lock.
+	if(g->m->locks > 0)
+		runtime·throw("stoptheworld: holding locks");
+
+	runtime·lock(&runtime·sched.lock);
+	runtime·sched.stopwait = runtime·gomaxprocs;
+	runtime·atomicstore((uint32*)&runtime·sched.gcwaiting, 1);
+	preemptall();
+	// stop current P
+	g->m->p->status = Pgcstop; // Pgcstop is only diagnostic.
+	runtime·sched.stopwait--;
+	// try to retake all P's in Psyscall status
+	for(i = 0; i < runtime·gomaxprocs; i++) {
+		p = runtime·allp[i];
+		s = p->status;
+		if(s == Psyscall && runtime·cas(&p->status, s, Pgcstop))
+			runtime·sched.stopwait--;
+	}
+	// stop idle P's
+	while(p = pidleget()) {
+		p->status = Pgcstop;
+		runtime·sched.stopwait--;
+	}
+	wait = runtime·sched.stopwait > 0;
+	runtime·unlock(&runtime·sched.lock);
+
+	// wait for remaining P's to stop voluntarily
+	if(wait) {
+		for(;;) {
+			// wait for 100us, then try to re-preempt in case of any races
+			if(runtime·notetsleep(&runtime·sched.stopnote, 100*1000)) {
+				runtime·noteclear(&runtime·sched.stopnote);
+				break;
+			}
+			preemptall();
+		}
+	}
+	if(runtime·sched.stopwait)
+		runtime·throw("stoptheworld: not stopped");
+	for(i = 0; i < runtime·gomaxprocs; i++) {
+		p = runtime·allp[i];
+		if(p->status != Pgcstop)
+			runtime·throw("stoptheworld: not stopped");
+	}
+}
+
+static void
+mhelpgc(void)
+{
+	g->m->helpgc = -1;
+}
+
+void
+runtime·starttheworld(void)
+{
+	P *p, *p1;
+	M *mp;
+	G *gp;
+	bool add;
+
+	g->m->locks++;  // disable preemption because it can be holding p in a local var
+	gp = runtime·netpoll(false);  // non-blocking
+	injectglist(gp);
+	add = needaddgcproc();
+	runtime·lock(&runtime·sched.lock);
+	if(runtime·newprocs) {
+		procresize(runtime·newprocs);
+		runtime·newprocs = 0;
+	} else
+		procresize(runtime·gomaxprocs);
+	runtime·sched.gcwaiting = 0;
+
+	p1 = nil;
+	while(p = pidleget()) {
+		// procresize() puts p's with work at the beginning of the list.
+		// Once we reach a p without a run queue, the rest don't have one either.
+		if(p->runqhead == p->runqtail) {
+			pidleput(p);
+			break;
+		}
+		p->m = mget();
+		p->link = p1;
+		p1 = p;
+	}
+	if(runtime·sched.sysmonwait) {
+		runtime·sched.sysmonwait = false;
+		runtime·notewakeup(&runtime·sched.sysmonnote);
+	}
+	runtime·unlock(&runtime·sched.lock);
+
+	while(p1) {
+		p = p1;
+		p1 = p1->link;
+		if(p->m) {
+			mp = p->m;
+			p->m = nil;
+			if(mp->nextp)
+				runtime·throw("starttheworld: inconsistent mp->nextp");
+			mp->nextp = p;
+			runtime·notewakeup(&mp->park);
+		} else {
+			// Start M to run P.  Do not start another M below.
+			newm(nil, p);
+			add = false;
+		}
+	}
+
+	if(add) {
+		// If GC could have used another helper proc, start one now,
+		// in the hope that it will be available next time.
+		// It would have been even better to start it before the collection,
+		// but doing so requires allocating memory, so it's tricky to
+		// coordinate.  This lazy approach works out in practice:
+		// we don't mind if the first couple gc rounds don't have quite
+		// the maximum number of procs.
+		newm(mhelpgc, nil);
+	}
+	g->m->locks--;
+	if(g->m->locks == 0 && g->preempt)  // restore the preemption request in case we've cleared it in newstack
+		g->stackguard0 = StackPreempt;
+}
+
+static void mstart(void);
+
+// Called to start an M.
+#pragma textflag NOSPLIT
+void
+runtime·mstart(void)
+{
+	uintptr x, size;
+	
+	if(g->stack.lo == 0) {
+		// Initialize stack bounds from system stack.
+		// Cgo may have left stack size in stack.hi.
+		size = g->stack.hi;
+		if(size == 0)
+			size = 8192;
+		g->stack.hi = (uintptr)&x;
+		g->stack.lo = g->stack.hi - size + 1024;
+	}
+	
+	// Initialize stack guards so that we can start calling
+	// both Go and C functions with stack growth prologues.
+	g->stackguard0 = g->stack.lo + StackGuard;
+	g->stackguard1 = g->stackguard0;
+	mstart();
+}
+
+static void
+mstart(void)
+{
+	if(g != g->m->g0)
+		runtime·throw("bad runtime·mstart");
+
+	// Record top of stack for use by mcall.
+	// Once we call schedule we're never coming back,
+	// so other calls can reuse this stack space.
+	runtime·gosave(&g->m->g0->sched);
+	g->m->g0->sched.pc = (uintptr)-1;  // make sure it is never used
+	runtime·asminit();
+	runtime·minit();
+
+	// Install signal handlers; after minit so that minit can
+	// prepare the thread to be able to handle the signals.
+	if(g->m == &runtime·m0)
+		runtime·initsig();
+	
+	if(g->m->mstartfn)
+		g->m->mstartfn();
+
+	if(g->m->helpgc) {
+		g->m->helpgc = 0;
+		stopm();
+	} else if(g->m != &runtime·m0) {
+		acquirep(g->m->nextp);
+		g->m->nextp = nil;
+	}
+	schedule();
+
+	// TODO(brainman): This point is never reached, because scheduler
+	// does not release os threads at the moment. But once this path
+	// is enabled, we must remove our seh here.
+}
+
+// When running with cgo, we call _cgo_thread_start
+// to start threads for us so that we can play nicely with
+// foreign code.
+void (*_cgo_thread_start)(void*);
+
+typedef struct CgoThreadStart CgoThreadStart;
+struct CgoThreadStart
+{
+	G *g;
+	uintptr *tls;
+	void (*fn)(void);
+};
+
+M *runtime·newM(void); // in proc.go
+
+// Allocate a new m unassociated with any thread.
+// Can use p for allocation context if needed.
+M*
+runtime·allocm(P *p)
+{
+	M *mp;
+
+	g->m->locks++;  // disable GC because it can be called from sysmon
+	if(g->m->p == nil)
+		acquirep(p);  // temporarily borrow p for mallocs in this function
+	mp = runtime·newM();
+	mcommoninit(mp);
+
+	// In case of cgo or Solaris, pthread_create will make us a stack.
+	// Windows and Plan 9 will layout sched stack on OS stack.
+	if(runtime·iscgo || Solaris || Windows || Plan9)
+		mp->g0 = runtime·malg(-1);
+	else
+		mp->g0 = runtime·malg(8192);
+	mp->g0->m = mp;
+
+	if(p == g->m->p)
+		releasep();
+	g->m->locks--;
+	if(g->m->locks == 0 && g->preempt)  // restore the preemption request in case we've cleared it in newstack
+		g->stackguard0 = StackPreempt;
+
+	return mp;
+}
+
+G *runtime·newG(void); // in proc.go
+
+static G*
+allocg(void)
+{
+	return runtime·newG();
+}
+
+static M* lockextra(bool nilokay);
+static void unlockextra(M*);
+
+// needm is called when a cgo callback happens on a
+// thread without an m (a thread not created by Go).
+// In this case, needm is expected to find an m to use
+// and return with m, g initialized correctly.
+// Since m and g are not set now (likely nil, but see below)
+// needm is limited in what routines it can call. In particular
+// it can only call nosplit functions (textflag 7) and cannot
+// do any scheduling that requires an m.
+//
+// In order to avoid needing heavy lifting here, we adopt
+// the following strategy: there is a stack of available m's
+// that can be stolen. Using compare-and-swap
+// to pop from the stack has ABA races, so we simulate
+// a lock by doing an exchange (via casp) to steal the stack
+// head and replace the top pointer with MLOCKED (1).
+// This serves as a simple spin lock that we can use even
+// without an m. The thread that locks the stack in this way
+// unlocks the stack by storing a valid stack head pointer.
+//
+// In order to make sure that there is always an m structure
+// available to be stolen, we maintain the invariant that there
+// is always one more than needed. At the beginning of the
+// program (if cgo is in use) the list is seeded with a single m.
+// If needm finds that it has taken the last m off the list, its job
+// is - once it has installed its own m so that it can do things like
+// allocate memory - to create a spare m and put it on the list.
+//
+// Each of these extra m's also has a g0 and a curg that are
+// pressed into service as the scheduling stack and current
+// goroutine for the duration of the cgo callback.
+//
+// When the callback is done with the m, it calls dropm to
+// put the m back on the list.
+#pragma textflag NOSPLIT
+void
+runtime·needm(byte x)
+{
+	M *mp;
+
+	if(runtime·needextram) {
+		// Can happen if C/C++ code calls Go from a global ctor.
+		// Can not throw, because scheduler is not initialized yet.
+		runtime·write(2, "fatal error: cgo callback before cgo call\n",
+			sizeof("fatal error: cgo callback before cgo call\n")-1);
+		runtime·exit(1);
+	}
+
+	// Lock extra list, take head, unlock popped list.
+	// nilokay=false is safe here because of the invariant above,
+	// that the extra list always contains or will soon contain
+	// at least one m.
+	mp = lockextra(false);
+
+	// Set needextram when we've just emptied the list,
+	// so that the eventual call into cgocallbackg will
+	// allocate a new m for the extra list. We delay the
+	// allocation until then so that it can be done
+	// after exitsyscall makes sure it is okay to be
+	// running at all (that is, there's no garbage collection
+	// running right now).
+	mp->needextram = mp->schedlink == nil;
+	unlockextra(mp->schedlink);
+
+	// Install g (= m->g0) and set the stack bounds
+	// to match the current stack. We don't actually know
+	// how big the stack is, like we don't know how big any
+	// scheduling stack is, but we assume there's at least 32 kB,
+	// which is more than enough for us.
+	runtime·setg(mp->g0);
+	g->stack.hi = (uintptr)(&x + 1024);
+	g->stack.lo = (uintptr)(&x - 32*1024);
+	g->stackguard0 = g->stack.lo + StackGuard;
+
+	// Initialize this thread to use the m.
+	runtime·asminit();
+	runtime·minit();
+}
+
+// newextram allocates an m and puts it on the extra list.
+// It is called with a working local m, so that it can do things
+// like call schedlock and allocate.
+void
+runtime·newextram(void)
+{
+	M *mp, *mnext;
+	G *gp;
+
+	// Create extra goroutine locked to extra m.
+	// The goroutine is the context in which the cgo callback will run.
+	// The sched.pc will never be returned to, but setting it to
+	// runtime.goexit makes clear to the traceback routines where
+	// the goroutine stack ends.
+	mp = runtime·allocm(nil);
+	gp = runtime·malg(4096);
+	gp->sched.pc = (uintptr)runtime·goexit + PCQuantum;
+	gp->sched.sp = gp->stack.hi;
+	gp->sched.sp -= 4*sizeof(uintreg); // extra space in case of reads slightly beyond frame
+	gp->sched.lr = 0;
+	gp->sched.g = gp;
+	gp->syscallpc = gp->sched.pc;
+	gp->syscallsp = gp->sched.sp;
+	// malg returns status as Gidle, change to Gsyscall before adding to allg
+	// where GC will see it.
+	runtime·casgstatus(gp, Gidle, Gsyscall);
+	gp->m = mp;
+	mp->curg = gp;
+	mp->locked = LockInternal;
+	mp->lockedg = gp;
+	gp->lockedm = mp;
+	gp->goid = runtime·xadd64(&runtime·sched.goidgen, 1);
+	if(raceenabled)
+		gp->racectx = runtime·racegostart(runtime·newextram);
+	// put on allg for garbage collector
+	runtime·allgadd(gp);
+
+	// Add m to the extra list.
+	mnext = lockextra(true);
+	mp->schedlink = mnext;
+	unlockextra(mp);
+}
+
+// dropm is called when a cgo callback has called needm but is now
+// done with the callback and returning back into the non-Go thread.
+// It puts the current m back onto the extra list.
+//
+// The main expense here is the call to signalstack to release the
+// m's signal stack, and then the call to needm on the next callback
+// from this thread. It is tempting to try to save the m for next time,
+// which would eliminate both these costs, but there might not be
+// a next time: the current thread (which Go does not control) might exit.
+// If we saved the m for that thread, there would be an m leak each time
+// such a thread exited. Instead, we acquire and release an m on each
+// call. These should typically not be scheduling operations, just a few
+// atomics, so the cost should be small.
+//
+// TODO(rsc): An alternative would be to allocate a dummy pthread per-thread
+// variable using pthread_key_create. Unlike the pthread keys we already use
+// on OS X, this dummy key would never be read by Go code. It would exist
+// only so that we could register at thread-exit-time destructor.
+// That destructor would put the m back onto the extra list.
+// This is purely a performance optimization. The current version,
+// in which dropm happens on each cgo call, is still correct too.
+// We may have to keep the current version on systems with cgo
+// but without pthreads, like Windows.
+void
+runtime·dropm(void)
+{
+	M *mp, *mnext;
+
+	// Undo whatever initialization minit did during needm.
+	runtime·unminit();
+
+	// Clear m and g, and return m to the extra list.
+	// After the call to setmg we can only call nosplit functions.
+	mp = g->m;
+	runtime·setg(nil);
+
+	mnext = lockextra(true);
+	mp->schedlink = mnext;
+	unlockextra(mp);
+}
+
+#define MLOCKED ((M*)1)
+
+// lockextra locks the extra list and returns the list head.
+// The caller must unlock the list by storing a new list head
+// to runtime.extram. If nilokay is true, then lockextra will
+// return a nil list head if that's what it finds. If nilokay is false,
+// lockextra will keep waiting until the list head is no longer nil.
+#pragma textflag NOSPLIT
+static M*
+lockextra(bool nilokay)
+{
+	M *mp;
+	void (*yield)(void);
+
+	for(;;) {
+		mp = runtime·atomicloadp(&runtime·extram);
+		if(mp == MLOCKED) {
+			yield = runtime·osyield;
+			yield();
+			continue;
+		}
+		if(mp == nil && !nilokay) {
+			runtime·usleep(1);
+			continue;
+		}
+		if(!runtime·casp(&runtime·extram, mp, MLOCKED)) {
+			yield = runtime·osyield;
+			yield();
+			continue;
+		}
+		break;
+	}
+	return mp;
+}
+
+#pragma textflag NOSPLIT
+static void
+unlockextra(M *mp)
+{
+	runtime·atomicstorep(&runtime·extram, mp);
+}
+
+
+// Create a new m.  It will start off with a call to fn, or else the scheduler.
+static void
+newm(void(*fn)(void), P *p)
+{
+	M *mp;
+
+	mp = runtime·allocm(p);
+	mp->nextp = p;
+	mp->mstartfn = fn;
+
+	if(runtime·iscgo) {
+		CgoThreadStart ts;
+
+		if(_cgo_thread_start == nil)
+			runtime·throw("_cgo_thread_start missing");
+		ts.g = mp->g0;
+		ts.tls = mp->tls;
+		ts.fn = runtime·mstart;
+		runtime·asmcgocall(_cgo_thread_start, &ts);
+		return;
+	}
+	runtime·newosproc(mp, (byte*)mp->g0->stack.hi);
+}
+
+// Stops execution of the current m until new work is available.
+// Returns with acquired P.
+static void
+stopm(void)
+{
+	if(g->m->locks)
+		runtime·throw("stopm holding locks");
+	if(g->m->p)
+		runtime·throw("stopm holding p");
+	if(g->m->spinning) {
+		g->m->spinning = false;
+		runtime·xadd(&runtime·sched.nmspinning, -1);
+	}
+
+retry:
+	runtime·lock(&runtime·sched.lock);
+	mput(g->m);
+	runtime·unlock(&runtime·sched.lock);
+	runtime·notesleep(&g->m->park);
+	runtime·noteclear(&g->m->park);
+	if(g->m->helpgc) {
+		runtime·gchelper();
+		g->m->helpgc = 0;
+		g->m->mcache = nil;
+		goto retry;
+	}
+	acquirep(g->m->nextp);
+	g->m->nextp = nil;
+}
+
+static void
+mspinning(void)
+{
+	g->m->spinning = true;
+}
+
+// Schedules some M to run the p (creates an M if necessary).
+// If p==nil, tries to get an idle P, if no idle P's does nothing.
+static void
+startm(P *p, bool spinning)
+{
+	M *mp;
+	void (*fn)(void);
+
+	runtime·lock(&runtime·sched.lock);
+	if(p == nil) {
+		p = pidleget();
+		if(p == nil) {
+			runtime·unlock(&runtime·sched.lock);
+			if(spinning)
+				runtime·xadd(&runtime·sched.nmspinning, -1);
+			return;
+		}
+	}
+	mp = mget();
+	runtime·unlock(&runtime·sched.lock);
+	if(mp == nil) {
+		fn = nil;
+		if(spinning)
+			fn = mspinning;
+		newm(fn, p);
+		return;
+	}
+	if(mp->spinning)
+		runtime·throw("startm: m is spinning");
+	if(mp->nextp)
+		runtime·throw("startm: m has p");
+	mp->spinning = spinning;
+	mp->nextp = p;
+	runtime·notewakeup(&mp->park);
+}
+
+// Hands off P from syscall or locked M.
+static void
+handoffp(P *p)
+{
+	// if it has local work, start it straight away
+	if(p->runqhead != p->runqtail || runtime·sched.runqsize) {
+		startm(p, false);
+		return;
+	}
+	// no local work, check that there are no spinning/idle M's,
+	// otherwise our help is not required
+	if(runtime·atomicload(&runtime·sched.nmspinning) + runtime·atomicload(&runtime·sched.npidle) == 0 &&  // TODO: fast atomic
+		runtime·cas(&runtime·sched.nmspinning, 0, 1)){
+		startm(p, true);
+		return;
+	}
+	runtime·lock(&runtime·sched.lock);
+	if(runtime·sched.gcwaiting) {
+		p->status = Pgcstop;
+		if(--runtime·sched.stopwait == 0)
+			runtime·notewakeup(&runtime·sched.stopnote);
+		runtime·unlock(&runtime·sched.lock);
+		return;
+	}
+	if(runtime·sched.runqsize) {
+		runtime·unlock(&runtime·sched.lock);
+		startm(p, false);
+		return;
+	}
+	// If this is the last running P and nobody is polling network,
+	// need to wakeup another M to poll network.
+	if(runtime·sched.npidle == runtime·gomaxprocs-1 && runtime·atomicload64(&runtime·sched.lastpoll) != 0) {
+		runtime·unlock(&runtime·sched.lock);
+		startm(p, false);
+		return;
+	}
+	pidleput(p);
+	runtime·unlock(&runtime·sched.lock);
+}
+
+// Tries to add one more P to execute G's.
+// Called when a G is made runnable (newproc, ready).
+static void
+wakep(void)
+{
+	// be conservative about spinning threads
+	if(!runtime·cas(&runtime·sched.nmspinning, 0, 1))
+		return;
+	startm(nil, true);
+}
+
+// Stops execution of the current m that is locked to a g until the g is runnable again.
+// Returns with acquired P.
+static void
+stoplockedm(void)
+{
+	P *p;
+	uint32 status;
+
+	if(g->m->lockedg == nil || g->m->lockedg->lockedm != g->m)
+		runtime·throw("stoplockedm: inconsistent locking");
+	if(g->m->p) {
+		// Schedule another M to run this p.
+		p = releasep();
+		handoffp(p);
+	}
+	incidlelocked(1);
+	// Wait until another thread schedules lockedg again.
+	runtime·notesleep(&g->m->park);
+	runtime·noteclear(&g->m->park);
+	status = runtime·readgstatus(g->m->lockedg);
+	if((status&~Gscan) != Grunnable){
+		runtime·printf("runtime:stoplockedm: g is not Grunnable or Gscanrunnable");
+		dumpgstatus(g);
+		runtime·throw("stoplockedm: not runnable");
+	}
+	acquirep(g->m->nextp);
+	g->m->nextp = nil;
+}
+
+// Schedules the locked m to run the locked gp.
+static void
+startlockedm(G *gp)
+{
+	M *mp;
+	P *p;
+
+	mp = gp->lockedm;
+	if(mp == g->m)
+		runtime·throw("startlockedm: locked to me");
+	if(mp->nextp)
+		runtime·throw("startlockedm: m has p");
+	// directly handoff current P to the locked m
+	incidlelocked(-1);
+	p = releasep();
+	mp->nextp = p;
+	runtime·notewakeup(&mp->park);
+	stopm();
+}
+
+// Stops the current m for stoptheworld.
+// Returns when the world is restarted.
+static void
+gcstopm(void)
+{
+	P *p;
+
+	if(!runtime·sched.gcwaiting)
+		runtime·throw("gcstopm: not waiting for gc");
+	if(g->m->spinning) {
+		g->m->spinning = false;
+		runtime·xadd(&runtime·sched.nmspinning, -1);
+	}
+	p = releasep();
+	runtime·lock(&runtime·sched.lock);
+	p->status = Pgcstop;
+	if(--runtime·sched.stopwait == 0)
+		runtime·notewakeup(&runtime·sched.stopnote);
+	runtime·unlock(&runtime·sched.lock);
+	stopm();
+}
+
+// Schedules gp to run on the current M.
+// Never returns.
+static void
+execute(G *gp)
+{
+	int32 hz;
+	
+	runtime·casgstatus(gp, Grunnable, Grunning);
+	gp->waitsince = 0;
+	gp->preempt = false;
+	gp->stackguard0 = gp->stack.lo + StackGuard;
+	g->m->p->schedtick++;
+	g->m->curg = gp;
+	gp->m = g->m;
+
+	// Check whether the profiler needs to be turned on or off.
+	hz = runtime·sched.profilehz;
+	if(g->m->profilehz != hz)
+		runtime·resetcpuprofiler(hz);
+
+	runtime·gogo(&gp->sched);
+}
+
+// Finds a runnable goroutine to execute.
+// Tries to steal from other P's, get g from global queue, poll network.
+static G*
+findrunnable(void)
+{
+	G *gp;
+	P *p;
+	int32 i;
+
+top:
+	if(runtime·sched.gcwaiting) {
+		gcstopm();
+		goto top;
+	}
+	if(runtime·fingwait && runtime·fingwake && (gp = runtime·wakefing()) != nil)
+		runtime·ready(gp);
+	// local runq
+	gp = runqget(g->m->p);
+	if(gp)
+		return gp;
+	// global runq
+	if(runtime·sched.runqsize) {
+		runtime·lock(&runtime·sched.lock);
+		gp = globrunqget(g->m->p, 0);
+		runtime·unlock(&runtime·sched.lock);
+		if(gp)
+			return gp;
+	}
+	// poll network
+	gp = runtime·netpoll(false);  // non-blocking
+	if(gp) {
+		injectglist(gp->schedlink);
+		runtime·casgstatus(gp, Gwaiting, Grunnable);
+		return gp;
+	}
+	// If number of spinning M's >= number of busy P's, block.
+	// This is necessary to prevent excessive CPU consumption
+	// when GOMAXPROCS>>1 but the program parallelism is low.
+	if(!g->m->spinning && 2 * runtime·atomicload(&runtime·sched.nmspinning) >= runtime·gomaxprocs - runtime·atomicload(&runtime·sched.npidle))  // TODO: fast atomic
+		goto stop;
+	if(!g->m->spinning) {
+		g->m->spinning = true;
+		runtime·xadd(&runtime·sched.nmspinning, 1);
+	}
+	// random steal from other P's
+	for(i = 0; i < 2*runtime·gomaxprocs; i++) {
+		if(runtime·sched.gcwaiting)
+			goto top;
+		p = runtime·allp[runtime·fastrand1()%runtime·gomaxprocs];
+		if(p == g->m->p)
+			gp = runqget(p);
+		else
+			gp = runqsteal(g->m->p, p);
+		if(gp)
+			return gp;
+	}
+stop:
+	// return P and block
+	runtime·lock(&runtime·sched.lock);
+	if(runtime·sched.gcwaiting) {
+		runtime·unlock(&runtime·sched.lock);
+		goto top;
+	}
+	if(runtime·sched.runqsize) {
+		gp = globrunqget(g->m->p, 0);
+		runtime·unlock(&runtime·sched.lock);
+		return gp;
+	}
+	p = releasep();
+	pidleput(p);
+	runtime·unlock(&runtime·sched.lock);
+	if(g->m->spinning) {
+		g->m->spinning = false;
+		runtime·xadd(&runtime·sched.nmspinning, -1);
+	}
+	// check all runqueues once again
+	for(i = 0; i < runtime·gomaxprocs; i++) {
+		p = runtime·allp[i];
+		if(p && p->runqhead != p->runqtail) {
+			runtime·lock(&runtime·sched.lock);
+			p = pidleget();
+			runtime·unlock(&runtime·sched.lock);
+			if(p) {
+				acquirep(p);
+				goto top;
+			}
+			break;
+		}
+	}
+	// poll network
+	if(runtime·xchg64(&runtime·sched.lastpoll, 0) != 0) {
+		if(g->m->p)
+			runtime·throw("findrunnable: netpoll with p");
+		if(g->m->spinning)
+			runtime·throw("findrunnable: netpoll with spinning");
+		gp = runtime·netpoll(true);  // block until new work is available
+		runtime·atomicstore64(&runtime·sched.lastpoll, runtime·nanotime());
+		if(gp) {
+			runtime·lock(&runtime·sched.lock);
+			p = pidleget();
+			runtime·unlock(&runtime·sched.lock);
+			if(p) {
+				acquirep(p);
+				injectglist(gp->schedlink);
+				runtime·casgstatus(gp, Gwaiting, Grunnable);
+				return gp;
+			}
+			injectglist(gp);
+		}
+	}
+	stopm();
+	goto top;
+}
+
+static void
+resetspinning(void)
+{
+	int32 nmspinning;
+
+	if(g->m->spinning) {
+		g->m->spinning = false;
+		nmspinning = runtime·xadd(&runtime·sched.nmspinning, -1);
+		if(nmspinning < 0)
+			runtime·throw("findrunnable: negative nmspinning");
+	} else
+		nmspinning = runtime·atomicload(&runtime·sched.nmspinning);
+
+	// M wakeup policy is deliberately somewhat conservative (see nmspinning handling),
+	// so see if we need to wakeup another P here.
+	if (nmspinning == 0 && runtime·atomicload(&runtime·sched.npidle) > 0)
+		wakep();
+}
+
+// Injects the list of runnable G's into the scheduler.
+// Can run concurrently with GC.
+static void
+injectglist(G *glist)
+{
+	int32 n;
+	G *gp;
+
+	if(glist == nil)
+		return;
+	runtime·lock(&runtime·sched.lock);
+	for(n = 0; glist; n++) {
+		gp = glist;
+		glist = gp->schedlink;
+		runtime·casgstatus(gp, Gwaiting, Grunnable); 
+		globrunqput(gp);
+	}
+	runtime·unlock(&runtime·sched.lock);
+
+	for(; n && runtime·sched.npidle; n--)
+		startm(nil, false);
+}
+
+// One round of scheduler: find a runnable goroutine and execute it.
+// Never returns.
+static void
+schedule(void)
+{
+	G *gp;
+	uint32 tick;
+
+	if(g->m->locks)
+		runtime·throw("schedule: holding locks");
+
+	if(g->m->lockedg) {
+		stoplockedm();
+		execute(g->m->lockedg);  // Never returns.
+	}
+
+top:
+	if(runtime·sched.gcwaiting) {
+		gcstopm();
+		goto top;
+	}
+
+	gp = nil;
+	// Check the global runnable queue once in a while to ensure fairness.
+	// Otherwise two goroutines can completely occupy the local runqueue
+	// by constantly respawning each other.
+	tick = g->m->p->schedtick;
+	// This is a fancy way to say tick%61==0,
+	// it uses 2 MUL instructions instead of a single DIV and so is faster on modern processors.
+	if(tick - (((uint64)tick*0x4325c53fu)>>36)*61 == 0 && runtime·sched.runqsize > 0) {
+		runtime·lock(&runtime·sched.lock);
+		gp = globrunqget(g->m->p, 1);
+		runtime·unlock(&runtime·sched.lock);
+		if(gp)
+			resetspinning();
+	}
+	if(gp == nil) {
+		gp = runqget(g->m->p);
+		if(gp && g->m->spinning)
+			runtime·throw("schedule: spinning with local work");
+	}
+	if(gp == nil) {
+		gp = findrunnable();  // blocks until work is available
+		resetspinning();
+	}
+
+	if(gp->lockedm) {
+		// Hands off own p to the locked m,
+		// then blocks waiting for a new p.
+		startlockedm(gp);
+		goto top;
+	}
+
+	execute(gp);
+}
+
+// dropg removes the association between m and the current goroutine m->curg (gp for short).
+// Typically a caller sets gp's status away from Grunning and then
+// immediately calls dropg to finish the job. The caller is also responsible
+// for arranging that gp will be restarted using runtime·ready at an
+// appropriate time. After calling dropg and arranging for gp to be
+// readied later, the caller can do other work but eventually should
+// call schedule to restart the scheduling of goroutines on this m.
+static void
+dropg(void)
+{
+	if(g->m->lockedg == nil) {
+		g->m->curg->m = nil;
+		g->m->curg = nil;
+	}
+}
+
+// Puts the current goroutine into a waiting state and calls unlockf.
+// If unlockf returns false, the goroutine is resumed.
+void
+runtime·park(bool(*unlockf)(G*, void*), void *lock, String reason)
+{
+	void (*fn)(G*);
+
+	g->m->waitlock = lock;
+	g->m->waitunlockf = unlockf;
+	g->waitreason = reason;
+	fn = runtime·park_m;
+	runtime·mcall(&fn);
+}
+
+bool
+runtime·parkunlock_c(G *gp, void *lock)
+{
+	USED(gp);
+	runtime·unlock(lock);
+	return true;
+}
+
+// Puts the current goroutine into a waiting state and unlocks the lock.
+// The goroutine can be made runnable again by calling runtime·ready(gp).
+void
+runtime·parkunlock(Mutex *lock, String reason)
+{
+	runtime·park(runtime·parkunlock_c, lock, reason);
+}
+
+// runtime·park continuation on g0.
+void
+runtime·park_m(G *gp)
+{
+	bool ok;
+
+	runtime·casgstatus(gp, Grunning, Gwaiting);
+	dropg();
+
+	if(g->m->waitunlockf) {
+		ok = g->m->waitunlockf(gp, g->m->waitlock);
+		g->m->waitunlockf = nil;
+		g->m->waitlock = nil;
+		if(!ok) {
+			runtime·casgstatus(gp, Gwaiting, Grunnable); 
+			execute(gp);  // Schedule it back, never returns.
+		}
+	}
+
+	schedule();
+}
+
+// Gosched continuation on g0.
+void
+runtime·gosched_m(G *gp)
+{
+	uint32 status;
+
+	status = runtime·readgstatus(gp);
+	if((status&~Gscan) != Grunning){
+		dumpgstatus(gp);
+		runtime·throw("bad g status");
+	}
+	runtime·casgstatus(gp, Grunning, Grunnable);
+	dropg();
+	runtime·lock(&runtime·sched.lock);
+	globrunqput(gp);
+	runtime·unlock(&runtime·sched.lock);
+
+	schedule();
+}
+
+// Finishes execution of the current goroutine.
+// Must be NOSPLIT because it is called from Go.
+#pragma textflag NOSPLIT
+void
+runtime·goexit1(void)
+{
+	void (*fn)(G*);
+
+	if(raceenabled)
+		runtime·racegoend();
+	fn = goexit0;
+	runtime·mcall(&fn);
+}
+
+// runtime·goexit continuation on g0.
+static void
+goexit0(G *gp)
+{
+	runtime·casgstatus(gp, Grunning, Gdead);
+	gp->m = nil;
+	gp->lockedm = nil;
+	g->m->lockedg = nil;
+	gp->paniconfault = 0;
+	gp->defer = nil; // should be true already but just in case.
+	gp->panic = nil; // non-nil for Goexit during panic. points at stack-allocated data.
+	gp->writebuf.array = nil;
+	gp->writebuf.len = 0;
+	gp->writebuf.cap = 0;
+	gp->waitreason.str = nil;
+	gp->waitreason.len = 0;
+	gp->param = nil;
+
+	dropg();
+
+	if(g->m->locked & ~LockExternal) {
+		runtime·printf("invalid m->locked = %d\n", g->m->locked);
+		runtime·throw("internal lockOSThread error");
+	}	
+	g->m->locked = 0;
+	gfput(g->m->p, gp);
+	schedule();
+}
+
+#pragma textflag NOSPLIT
+static void
+save(uintptr pc, uintptr sp)
+{
+	g->sched.pc = pc;
+	g->sched.sp = sp;
+	g->sched.lr = 0;
+	g->sched.ret = 0;
+	g->sched.ctxt = 0;
+	g->sched.g = g;
+}
+
+static void entersyscall_bad(void);
+static void entersyscall_sysmon(void);
+static void entersyscall_gcwait(void);
+
+// The goroutine g is about to enter a system call.
+// Record that it's not using the cpu anymore.
+// This is called only from the go syscall library and cgocall,
+// not from the low-level system calls used by the runtime.
+//
+// Entersyscall cannot split the stack: the runtime·gosave must
+// make g->sched refer to the caller's stack segment, because
+// entersyscall is going to return immediately after.
+//
+// Nothing entersyscall calls can split the stack either.
+// We cannot safely move the stack during an active call to syscall,
+// because we do not know which of the uintptr arguments are
+// really pointers (back into the stack).
+// In practice, this means that we make the fast path run through
+// entersyscall doing no-split things, and the slow path has to use onM
+// to run bigger things on the m stack.
+//
+// reentersyscall is the entry point used by cgo callbacks, where explicitly
+// saved SP and PC are restored. This is needed when exitsyscall will be called
+// from a function further up in the call stack than the parent, as g->syscallsp
+// must always point to a valid stack frame. entersyscall below is the normal
+// entry point for syscalls, which obtains the SP and PC from the caller.
+#pragma textflag NOSPLIT
+void
+runtime·reentersyscall(uintptr pc, uintptr sp)
+{
+	void (*fn)(void);
+
+	// Disable preemption because during this function g is in Gsyscall status,
+	// but can have inconsistent g->sched, do not let GC observe it.
+	g->m->locks++;
+	
+	// Entersyscall must not call any function that might split/grow the stack.
+	// (See details in comment above.)
+	// Catch calls that might, by replacing the stack guard with something that
+	// will trip any stack check and leaving a flag to tell newstack to die.
+	g->stackguard0 = StackPreempt;
+	g->throwsplit = 1;
+
+	// Leave SP around for GC and traceback.
+	save(pc, sp);
+	g->syscallsp = sp;
+	g->syscallpc = pc;
+	runtime·casgstatus(g, Grunning, Gsyscall);
+	if(g->syscallsp < g->stack.lo || g->stack.hi < g->syscallsp) {
+		fn = entersyscall_bad;
+		runtime·onM(&fn);
+	}
+
+	if(runtime·atomicload(&runtime·sched.sysmonwait)) {  // TODO: fast atomic
+		fn = entersyscall_sysmon;
+		runtime·onM(&fn);
+		save(pc, sp);
+	}
+
+	g->m->mcache = nil;
+	g->m->p->m = nil;
+	runtime·atomicstore(&g->m->p->status, Psyscall);
+	if(runtime·sched.gcwaiting) {
+		fn = entersyscall_gcwait;
+		runtime·onM(&fn);
+		save(pc, sp);
+	}
+
+	// Goroutines must not split stacks in Gsyscall status (it would corrupt g->sched).
+	// We set stackguard to StackPreempt so that first split stack check calls morestack.
+	// Morestack detects this case and throws.
+	g->stackguard0 = StackPreempt;
+	g->m->locks--;
+}
+
+// Standard syscall entry used by the go syscall library and normal cgo calls.
+#pragma textflag NOSPLIT
+void
+·entersyscall(int32 dummy)
+{
+	runtime·reentersyscall((uintptr)runtime·getcallerpc(&dummy), runtime·getcallersp(&dummy));
+}
+
+static void
+entersyscall_bad(void)
+{
+	G *gp;
+	
+	gp = g->m->curg;
+	runtime·printf("entersyscall inconsistent %p [%p,%p]\n",
+		gp->syscallsp, gp->stack.lo, gp->stack.hi);
+	runtime·throw("entersyscall");
+}
+
+static void
+entersyscall_sysmon(void)
+{
+	runtime·lock(&runtime·sched.lock);
+	if(runtime·atomicload(&runtime·sched.sysmonwait)) {
+		runtime·atomicstore(&runtime·sched.sysmonwait, 0);
+		runtime·notewakeup(&runtime·sched.sysmonnote);
+	}
+	runtime·unlock(&runtime·sched.lock);
+}
+
+static void
+entersyscall_gcwait(void)
+{
+	runtime·lock(&runtime·sched.lock);
+	if (runtime·sched.stopwait > 0 && runtime·cas(&g->m->p->status, Psyscall, Pgcstop)) {
+		if(--runtime·sched.stopwait == 0)
+			runtime·notewakeup(&runtime·sched.stopnote);
+	}
+	runtime·unlock(&runtime·sched.lock);
+}
+
+static void entersyscallblock_handoff(void);
+
+// The same as runtime·entersyscall(), but with a hint that the syscall is blocking.
+#pragma textflag NOSPLIT
+void
+·entersyscallblock(int32 dummy)
+{
+	void (*fn)(void);
+
+	g->m->locks++;  // see comment in entersyscall
+	g->throwsplit = 1;
+	g->stackguard0 = StackPreempt;  // see comment in entersyscall
+
+	// Leave SP around for GC and traceback.
+	save((uintptr)runtime·getcallerpc(&dummy), runtime·getcallersp(&dummy));
+	g->syscallsp = g->sched.sp;
+	g->syscallpc = g->sched.pc;
+	runtime·casgstatus(g, Grunning, Gsyscall);
+	if(g->syscallsp < g->stack.lo || g->stack.hi < g->syscallsp) {
+		fn = entersyscall_bad;
+		runtime·onM(&fn);
+	}
+	
+	fn = entersyscallblock_handoff;
+	runtime·onM(&fn);
+
+	// Resave for traceback during blocked call.
+	save((uintptr)runtime·getcallerpc(&dummy), runtime·getcallersp(&dummy));
+
+	g->m->locks--;
+}
+
+static void
+entersyscallblock_handoff(void)
+{
+	handoffp(releasep());
+}
+
+// The goroutine g exited its system call.
+// Arrange for it to run on a cpu again.
+// This is called only from the go syscall library, not
+// from the low-level system calls used by the runtime.
+#pragma textflag NOSPLIT
+void
+·exitsyscall(int32 dummy)
+{
+	void (*fn)(G*);
+
+	g->m->locks++;  // see comment in entersyscall
+
+	if(runtime·getcallersp(&dummy) > g->syscallsp)
+		runtime·throw("exitsyscall: syscall frame is no longer valid");
+
+	g->waitsince = 0;
+	if(exitsyscallfast()) {
+		// There's a cpu for us, so we can run.
+		g->m->p->syscalltick++;
+		// We need to cas the status and scan before resuming...
+		runtime·casgstatus(g, Gsyscall, Grunning);
+
+		// Garbage collector isn't running (since we are),
+		// so okay to clear syscallsp.
+		g->syscallsp = (uintptr)nil;
+		g->m->locks--;
+		if(g->preempt) {
+			// restore the preemption request in case we've cleared it in newstack
+			g->stackguard0 = StackPreempt;
+		} else {
+			// otherwise restore the real stackguard, we've spoiled it in entersyscall/entersyscallblock
+			g->stackguard0 = g->stack.lo + StackGuard;
+		}
+		g->throwsplit = 0;
+		return;
+	}
+
+	g->m->locks--;
+
+	// Call the scheduler.
+	fn = exitsyscall0;
+	runtime·mcall(&fn);
+
+	// Scheduler returned, so we're allowed to run now.
+	// Delete the syscallsp information that we left for
+	// the garbage collector during the system call.
+	// Must wait until now because until gosched returns
+	// we don't know for sure that the garbage collector
+	// is not running.
+	g->syscallsp = (uintptr)nil;
+	g->m->p->syscalltick++;
+	g->throwsplit = 0;
+}
+
+static void exitsyscallfast_pidle(void);
+
+#pragma textflag NOSPLIT
+static bool
+exitsyscallfast(void)
+{
+	void (*fn)(void);
+
+	// Freezetheworld sets stopwait but does not retake P's.
+	if(runtime·sched.stopwait) {
+		g->m->p = nil;
+		return false;
+	}
+
+	// Try to re-acquire the last P.
+	if(g->m->p && g->m->p->status == Psyscall && runtime·cas(&g->m->p->status, Psyscall, Prunning)) {
+		// There's a cpu for us, so we can run.
+		g->m->mcache = g->m->p->mcache;
+		g->m->p->m = g->m;
+		return true;
+	}
+	// Try to get any other idle P.
+	g->m->p = nil;
+	if(runtime·sched.pidle) {
+		fn = exitsyscallfast_pidle;
+		runtime·onM(&fn);
+		if(g->m->scalararg[0]) {
+			g->m->scalararg[0] = 0;
+			return true;
+		}
+	}
+	return false;
+}
+
+static void
+exitsyscallfast_pidle(void)
+{
+	P *p;
+
+	runtime·lock(&runtime·sched.lock);
+	p = pidleget();
+	if(p && runtime·atomicload(&runtime·sched.sysmonwait)) {
+		runtime·atomicstore(&runtime·sched.sysmonwait, 0);
+		runtime·notewakeup(&runtime·sched.sysmonnote);
+	}
+	runtime·unlock(&runtime·sched.lock);
+	if(p) {
+		acquirep(p);
+		g->m->scalararg[0] = 1;
+	} else
+		g->m->scalararg[0] = 0;
+}
+
+// runtime·exitsyscall slow path on g0.
+// Failed to acquire P, enqueue gp as runnable.
+static void
+exitsyscall0(G *gp)
+{
+	P *p;
+
+	runtime·casgstatus(gp, Gsyscall, Grunnable);
+	dropg();
+	runtime·lock(&runtime·sched.lock);
+	p = pidleget();
+	if(p == nil)
+		globrunqput(gp);
+	else if(runtime·atomicload(&runtime·sched.sysmonwait)) {
+		runtime·atomicstore(&runtime·sched.sysmonwait, 0);
+		runtime·notewakeup(&runtime·sched.sysmonnote);
+	}
+	runtime·unlock(&runtime·sched.lock);
+	if(p) {
+		acquirep(p);
+		execute(gp);  // Never returns.
+	}
+	if(g->m->lockedg) {
+		// Wait until another thread schedules gp and so m again.
+		stoplockedm();
+		execute(gp);  // Never returns.
+	}
+	stopm();
+	schedule();  // Never returns.
+}
+
+static void
+beforefork(void)
+{
+	G *gp;
+	
+	gp = g->m->curg;
+	// Fork can hang if preempted with signals frequently enough (see issue 5517).
+	// Ensure that we stay on the same M where we disable profiling.
+	gp->m->locks++;
+	if(gp->m->profilehz != 0)
+		runtime·resetcpuprofiler(0);
+
+	// This function is called before fork in syscall package.
+	// Code between fork and exec must not allocate memory nor even try to grow stack.
+	// Here we spoil g->stackguard to reliably detect any attempts to grow stack.
+	// runtime_AfterFork will undo this in parent process, but not in child.
+	gp->stackguard0 = StackFork;
+}
+
+// Called from syscall package before fork.
+#pragma textflag NOSPLIT
+void
+syscall·runtime_BeforeFork(void)
+{
+	void (*fn)(void);
+	
+	fn = beforefork;
+	runtime·onM(&fn);
+}
+
+static void
+afterfork(void)
+{
+	int32 hz;
+	G *gp;
+	
+	gp = g->m->curg;
+	// See the comment in runtime_BeforeFork.
+	gp->stackguard0 = gp->stack.lo + StackGuard;
+
+	hz = runtime·sched.profilehz;
+	if(hz != 0)
+		runtime·resetcpuprofiler(hz);
+	gp->m->locks--;
+}
+
+// Called from syscall package after fork in parent.
+#pragma textflag NOSPLIT
+void
+syscall·runtime_AfterFork(void)
+{
+	void (*fn)(void);
+	
+	fn = afterfork;
+	runtime·onM(&fn);
+}
+
+// Hook used by runtime·malg to call runtime·stackalloc on the
+// scheduler stack.  This exists because runtime·stackalloc insists
+// on being called on the scheduler stack, to avoid trying to grow
+// the stack while allocating a new stack segment.
+static void
+mstackalloc(G *gp)
+{
+	G *newg;
+	uintptr size;
+
+	newg = g->m->ptrarg[0];
+	size = g->m->scalararg[0];
+
+	newg->stack = runtime·stackalloc(size);
+
+	runtime·gogo(&gp->sched);
+}
+
+// Allocate a new g, with a stack big enough for stacksize bytes.
+G*
+runtime·malg(int32 stacksize)
+{
+	G *newg;
+	void (*fn)(G*);
+
+	newg = allocg();
+	if(stacksize >= 0) {
+		stacksize = runtime·round2(StackSystem + stacksize);
+		if(g == g->m->g0) {
+			// running on scheduler stack already.
+			newg->stack = runtime·stackalloc(stacksize);
+		} else {
+			// have to call stackalloc on scheduler stack.
+			g->m->scalararg[0] = stacksize;
+			g->m->ptrarg[0] = newg;
+			fn = mstackalloc;
+			runtime·mcall(&fn);
+			g->m->ptrarg[0] = nil;
+		}
+		newg->stackguard0 = newg->stack.lo + StackGuard;
+		newg->stackguard1 = ~(uintptr)0;
+	}
+	return newg;
+}
+
+static void
+newproc_m(void)
+{
+	byte *argp;
+	void *callerpc;
+	FuncVal *fn;
+	int32 siz;
+
+	siz = g->m->scalararg[0];
+	callerpc = (void*)g->m->scalararg[1];	
+	argp = g->m->ptrarg[0];
+	fn = (FuncVal*)g->m->ptrarg[1];
+
+	runtime·newproc1(fn, argp, siz, 0, callerpc);
+	g->m->ptrarg[0] = nil;
+	g->m->ptrarg[1] = nil;
+}
+
+// Create a new g running fn with siz bytes of arguments.
+// Put it on the queue of g's waiting to run.
+// The compiler turns a go statement into a call to this.
+// Cannot split the stack because it assumes that the arguments
+// are available sequentially after &fn; they would not be
+// copied if a stack split occurred.
+#pragma textflag NOSPLIT
+void
+runtime·newproc(int32 siz, FuncVal* fn, ...)
+{
+	byte *argp;
+	void (*mfn)(void);
+
+	if(thechar == '5')
+		argp = (byte*)(&fn+2);  // skip caller's saved LR
+	else
+		argp = (byte*)(&fn+1);
+
+	g->m->locks++;
+	g->m->scalararg[0] = siz;
+	g->m->scalararg[1] = (uintptr)runtime·getcallerpc(&siz);
+	g->m->ptrarg[0] = argp;
+	g->m->ptrarg[1] = fn;
+	mfn = newproc_m;
+	runtime·onM(&mfn);
+	g->m->locks--;
+}
+
+void runtime·main(void);
+
+// Create a new g running fn with narg bytes of arguments starting
+// at argp and returning nret bytes of results.  callerpc is the
+// address of the go statement that created this.  The new g is put
+// on the queue of g's waiting to run.
+G*
+runtime·newproc1(FuncVal *fn, byte *argp, int32 narg, int32 nret, void *callerpc)
+{
+	byte *sp;
+	G *newg;
+	P *p;
+	int32 siz;
+
+	if(fn == nil) {
+		g->m->throwing = -1;  // do not dump full stacks
+		runtime·throw("go of nil func value");
+	}
+	g->m->locks++;  // disable preemption because it can be holding p in a local var
+	siz = narg + nret;
+	siz = (siz+7) & ~7;
+
+	// We could allocate a larger initial stack if necessary.
+	// Not worth it: this is almost always an error.
+	// 4*sizeof(uintreg): extra space added below
+	// sizeof(uintreg): caller's LR (arm) or return address (x86, in gostartcall).
+	if(siz >= StackMin - 4*sizeof(uintreg) - sizeof(uintreg))
+		runtime·throw("runtime.newproc: function arguments too large for new goroutine");
+
+	p = g->m->p;
+	if((newg = gfget(p)) == nil) {
+		newg = runtime·malg(StackMin);
+		runtime·casgstatus(newg, Gidle, Gdead);
+		runtime·allgadd(newg); // publishes with a g->status of Gdead so GC scanner doesn't look at uninitialized stack.
+	}
+	if(newg->stack.hi == 0)
+		runtime·throw("newproc1: newg missing stack");
+
+	if(runtime·readgstatus(newg) != Gdead) 
+		runtime·throw("newproc1: new g is not Gdead");
+
+	sp = (byte*)newg->stack.hi;
+	sp -= 4*sizeof(uintreg); // extra space in case of reads slightly beyond frame
+	sp -= siz;
+	runtime·memmove(sp, argp, narg);
+	if(thechar == '5') {
+		// caller's LR
+		sp -= sizeof(void*);
+		*(void**)sp = nil;
+	}
+
+	runtime·memclr((byte*)&newg->sched, sizeof newg->sched);
+	newg->sched.sp = (uintptr)sp;
+	newg->sched.pc = (uintptr)runtime·goexit + PCQuantum; // +PCQuantum so that previous instruction is in same function
+	newg->sched.g = newg;
+	runtime·gostartcallfn(&newg->sched, fn);
+	newg->gopc = (uintptr)callerpc;
+	runtime·casgstatus(newg, Gdead, Grunnable);
+
+	if(p->goidcache == p->goidcacheend) {
+		// Sched.goidgen is the last allocated id,
+		// this batch must be [sched.goidgen+1, sched.goidgen+GoidCacheBatch].
+		// At startup sched.goidgen=0, so main goroutine receives goid=1.
+		p->goidcache = runtime·xadd64(&runtime·sched.goidgen, GoidCacheBatch);
+		p->goidcache -= GoidCacheBatch - 1;
+		p->goidcacheend = p->goidcache + GoidCacheBatch;
+	}
+	newg->goid = p->goidcache++;
+	if(raceenabled)
+		newg->racectx = runtime·racegostart((void*)callerpc);
+	runqput(p, newg);
+
+	if(runtime·atomicload(&runtime·sched.npidle) != 0 && runtime·atomicload(&runtime·sched.nmspinning) == 0 && fn->fn != runtime·main)  // TODO: fast atomic
+		wakep();
+	g->m->locks--;
+	if(g->m->locks == 0 && g->preempt)  // restore the preemption request in case we've cleared it in newstack
+		g->stackguard0 = StackPreempt;
+	return newg;
+}
+
+// Put on gfree list.
+// If local list is too long, transfer a batch to the global list.
+static void
+gfput(P *p, G *gp)
+{
+	uintptr stksize;
+
+	if(runtime·readgstatus(gp) != Gdead) 
+		runtime·throw("gfput: bad status (not Gdead)");
+
+	stksize = gp->stack.hi - gp->stack.lo;
+	
+	if(stksize != FixedStack) {
+		// non-standard stack size - free it.
+		runtime·stackfree(gp->stack);
+		gp->stack.lo = 0;
+		gp->stack.hi = 0;
+		gp->stackguard0 = 0;
+	}
+	gp->schedlink = p->gfree;
+	p->gfree = gp;
+	p->gfreecnt++;
+	if(p->gfreecnt >= 64) {
+		runtime·lock(&runtime·sched.gflock);
+		while(p->gfreecnt >= 32) {
+			p->gfreecnt--;
+			gp = p->gfree;
+			p->gfree = gp->schedlink;
+			gp->schedlink = runtime·sched.gfree;
+			runtime·sched.gfree = gp;
+			runtime·sched.ngfree++;
+		}
+		runtime·unlock(&runtime·sched.gflock);
+	}
+}
+
+// Get from gfree list.
+// If local list is empty, grab a batch from global list.
+static G*
+gfget(P *p)
+{
+	G *gp;
+	void (*fn)(G*);
+
+retry:
+	gp = p->gfree;
+	if(gp == nil && runtime·sched.gfree) {
+		runtime·lock(&runtime·sched.gflock);
+		while(p->gfreecnt < 32 && runtime·sched.gfree != nil) {
+			p->gfreecnt++;
+			gp = runtime·sched.gfree;
+			runtime·sched.gfree = gp->schedlink;
+			runtime·sched.ngfree--;
+			gp->schedlink = p->gfree;
+			p->gfree = gp;
+		}
+		runtime·unlock(&runtime·sched.gflock);
+		goto retry;
+	}
+	if(gp) {
+		p->gfree = gp->schedlink;
+		p->gfreecnt--;
+
+		if(gp->stack.lo == 0) {
+			// Stack was deallocated in gfput.  Allocate a new one.
+			if(g == g->m->g0) {
+				gp->stack = runtime·stackalloc(FixedStack);
+			} else {
+				g->m->scalararg[0] = FixedStack;
+				g->m->ptrarg[0] = gp;
+				fn = mstackalloc;
+				runtime·mcall(&fn);
+				g->m->ptrarg[0] = nil;
+			}
+			gp->stackguard0 = gp->stack.lo + StackGuard;
+		} else {
+			if(raceenabled)
+				runtime·racemalloc((void*)gp->stack.lo, gp->stack.hi - gp->stack.lo);
+		}
+	}
+	return gp;
+}
+
+// Purge all cached G's from gfree list to the global list.
+static void
+gfpurge(P *p)
+{
+	G *gp;
+
+	runtime·lock(&runtime·sched.gflock);
+	while(p->gfreecnt != 0) {
+		p->gfreecnt--;
+		gp = p->gfree;
+		p->gfree = gp->schedlink;
+		gp->schedlink = runtime·sched.gfree;
+		runtime·sched.gfree = gp;
+		runtime·sched.ngfree++;
+	}
+	runtime·unlock(&runtime·sched.gflock);
+}
+
+#pragma textflag NOSPLIT
+void
+runtime·Breakpoint(void)
+{
+	runtime·breakpoint();
+}
+
+// lockOSThread is called by runtime.LockOSThread and runtime.lockOSThread below
+// after they modify m->locked. Do not allow preemption during this call,
+// or else the m might be different in this function than in the caller.
+#pragma textflag NOSPLIT
+static void
+lockOSThread(void)
+{
+	g->m->lockedg = g;
+	g->lockedm = g->m;
+}
+
+#pragma textflag NOSPLIT
+void
+runtime·LockOSThread(void)
+{
+	g->m->locked |= LockExternal;
+	lockOSThread();
+}
+
+#pragma textflag NOSPLIT
+void
+runtime·lockOSThread(void)
+{
+	g->m->locked += LockInternal;
+	lockOSThread();
+}
+
+
+// unlockOSThread is called by runtime.UnlockOSThread and runtime.unlockOSThread below
+// after they update m->locked. Do not allow preemption during this call,
+// or else the m might be in different in this function than in the caller.
+#pragma textflag NOSPLIT
+static void
+unlockOSThread(void)
+{
+	if(g->m->locked != 0)
+		return;
+	g->m->lockedg = nil;
+	g->lockedm = nil;
+}
+
+#pragma textflag NOSPLIT
+void
+runtime·UnlockOSThread(void)
+{
+	g->m->locked &= ~LockExternal;
+	unlockOSThread();
+}
+
+static void badunlockOSThread(void);
+
+#pragma textflag NOSPLIT
+void
+runtime·unlockOSThread(void)
+{
+	void (*fn)(void);
+
+	if(g->m->locked < LockInternal) {
+		fn = badunlockOSThread;
+		runtime·onM(&fn);
+	}
+	g->m->locked -= LockInternal;
+	unlockOSThread();
+}
+
+static void
+badunlockOSThread(void)
+{
+	runtime·throw("runtime: internal error: misuse of lockOSThread/unlockOSThread");
+}
+
+#pragma textflag NOSPLIT
+int32
+runtime·gcount(void)
+{
+	P *p, **pp;
+	int32 n;
+
+	n = runtime·allglen - runtime·sched.ngfree;
+	for(pp=runtime·allp; p=*pp; pp++)
+		n -= p->gfreecnt;
+	// All these variables can be changed concurrently, so the result can be inconsistent.
+	// But at least the current goroutine is running.
+	if(n < 1)
+		n = 1;
+	return n;
+}
+
+int32
+runtime·mcount(void)
+{
+	return runtime·sched.mcount;
+}
+
+static struct ProfState {
+	uint32 lock;
+	int32 hz;
+} prof;
+
+static void System(void) { System(); }
+static void ExternalCode(void) { ExternalCode(); }
+static void GC(void) { GC(); }
+
+extern void runtime·cpuproftick(uintptr*, int32);
+extern byte runtime·etext[];
+
+// Called if we receive a SIGPROF signal.
+void
+runtime·sigprof(uint8 *pc, uint8 *sp, uint8 *lr, G *gp, M *mp)
+{
+	int32 n;
+	bool traceback;
+	// Do not use global m in this function, use mp instead.
+	// On windows one m is sending reports about all the g's, so m means a wrong thing.
+	byte m;
+	uintptr stk[100];
+
+	m = 0;
+	USED(m);
+
+	if(prof.hz == 0)
+		return;
+
+	// Profiling runs concurrently with GC, so it must not allocate.
+	mp->mallocing++;
+
+	// Define that a "user g" is a user-created goroutine, and a "system g"
+	// is one that is m->g0 or m->gsignal. We've only made sure that we
+	// can unwind user g's, so exclude the system g's.
+	//
+	// It is not quite as easy as testing gp == m->curg (the current user g)
+	// because we might be interrupted for profiling halfway through a
+	// goroutine switch. The switch involves updating three (or four) values:
+	// g, PC, SP, and (on arm) LR. The PC must be the last to be updated,
+	// because once it gets updated the new g is running.
+	//
+	// When switching from a user g to a system g, LR is not considered live,
+	// so the update only affects g, SP, and PC. Since PC must be last, there
+	// the possible partial transitions in ordinary execution are (1) g alone is updated,
+	// (2) both g and SP are updated, and (3) SP alone is updated.
+	// If g is updated, we'll see a system g and not look closer.
+	// If SP alone is updated, we can detect the partial transition by checking
+	// whether the SP is within g's stack bounds. (We could also require that SP
+	// be changed only after g, but the stack bounds check is needed by other
+	// cases, so there is no need to impose an additional requirement.)
+	//
+	// There is one exceptional transition to a system g, not in ordinary execution.
+	// When a signal arrives, the operating system starts the signal handler running
+	// with an updated PC and SP. The g is updated last, at the beginning of the
+	// handler. There are two reasons this is okay. First, until g is updated the
+	// g and SP do not match, so the stack bounds check detects the partial transition.
+	// Second, signal handlers currently run with signals disabled, so a profiling
+	// signal cannot arrive during the handler.
+	//
+	// When switching from a system g to a user g, there are three possibilities.
+	//
+	// First, it may be that the g switch has no PC update, because the SP
+	// either corresponds to a user g throughout (as in runtime.asmcgocall)
+	// or because it has been arranged to look like a user g frame
+	// (as in runtime.cgocallback_gofunc). In this case, since the entire
+	// transition is a g+SP update, a partial transition updating just one of 
+	// those will be detected by the stack bounds check.
+	//
+	// Second, when returning from a signal handler, the PC and SP updates
+	// are performed by the operating system in an atomic update, so the g
+	// update must be done before them. The stack bounds check detects
+	// the partial transition here, and (again) signal handlers run with signals
+	// disabled, so a profiling signal cannot arrive then anyway.
+	//
+	// Third, the common case: it may be that the switch updates g, SP, and PC
+	// separately, as in runtime.gogo.
+	//
+	// Because runtime.gogo is the only instance, we check whether the PC lies
+	// within that function, and if so, not ask for a traceback. This approach
+	// requires knowing the size of the runtime.gogo function, which we
+	// record in arch_*.h and check in runtime_test.go.
+	//
+	// There is another apparently viable approach, recorded here in case
+	// the "PC within runtime.gogo" check turns out not to be usable.
+	// It would be possible to delay the update of either g or SP until immediately
+	// before the PC update instruction. Then, because of the stack bounds check,
+	// the only problematic interrupt point is just before that PC update instruction,
+	// and the sigprof handler can detect that instruction and simulate stepping past
+	// it in order to reach a consistent state. On ARM, the update of g must be made
+	// in two places (in R10 and also in a TLS slot), so the delayed update would
+	// need to be the SP update. The sigprof handler must read the instruction at
+	// the current PC and if it was the known instruction (for example, JMP BX or 
+	// MOV R2, PC), use that other register in place of the PC value.
+	// The biggest drawback to this solution is that it requires that we can tell
+	// whether it's safe to read from the memory pointed at by PC.
+	// In a correct program, we can test PC == nil and otherwise read,
+	// but if a profiling signal happens at the instant that a program executes
+	// a bad jump (before the program manages to handle the resulting fault)
+	// the profiling handler could fault trying to read nonexistent memory.
+	//
+	// To recap, there are no constraints on the assembly being used for the
+	// transition. We simply require that g and SP match and that the PC is not
+	// in runtime.gogo.
+	traceback = true;
+	if(gp == nil || gp != mp->curg ||
+	   (uintptr)sp < gp->stack.lo || gp->stack.hi < (uintptr)sp ||
+	   ((uint8*)runtime·gogo <= pc && pc < (uint8*)runtime·gogo + RuntimeGogoBytes))
+		traceback = false;
+
+	n = 0;
+	if(traceback)
+		n = runtime·gentraceback((uintptr)pc, (uintptr)sp, (uintptr)lr, gp, 0, stk, nelem(stk), nil, nil, TraceTrap);
+	if(!traceback || n <= 0) {
+		// Normal traceback is impossible or has failed.
+		// See if it falls into several common cases.
+		n = 0;
+		if(mp->ncgo > 0 && mp->curg != nil &&
+			mp->curg->syscallpc != 0 && mp->curg->syscallsp != 0) {
+			// Cgo, we can't unwind and symbolize arbitrary C code,
+			// so instead collect Go stack that leads to the cgo call.
+			// This is especially important on windows, since all syscalls are cgo calls.
+			n = runtime·gentraceback(mp->curg->syscallpc, mp->curg->syscallsp, 0, mp->curg, 0, stk, nelem(stk), nil, nil, 0);
+		}
+#ifdef GOOS_windows
+		if(n == 0 && mp->libcallg != nil && mp->libcallpc != 0 && mp->libcallsp != 0) {
+			// Libcall, i.e. runtime syscall on windows.
+			// Collect Go stack that leads to the call.
+			n = runtime·gentraceback(mp->libcallpc, mp->libcallsp, 0, mp->libcallg, 0, stk, nelem(stk), nil, nil, 0);
+		}
+#endif
+		if(n == 0) {
+			// If all of the above has failed, account it against abstract "System" or "GC".
+			n = 2;
+			// "ExternalCode" is better than "etext".
+			if((uintptr)pc > (uintptr)runtime·etext)
+				pc = (byte*)ExternalCode + PCQuantum;
+			stk[0] = (uintptr)pc;
+			if(mp->gcing || mp->helpgc)
+				stk[1] = (uintptr)GC + PCQuantum;
+			else
+				stk[1] = (uintptr)System + PCQuantum;
+		}
+	}
+
+	if(prof.hz != 0) {
+		// Simple cas-lock to coordinate with setcpuprofilerate.
+		while(!runtime·cas(&prof.lock, 0, 1))
+			runtime·osyield();
+		if(prof.hz != 0)
+			runtime·cpuproftick(stk, n);
+		runtime·atomicstore(&prof.lock, 0);
+	}
+	mp->mallocing--;
+}
+
+// Arrange to call fn with a traceback hz times a second.
+void
+runtime·setcpuprofilerate_m(void)
+{
+	int32 hz;
+	
+	hz = g->m->scalararg[0];
+	g->m->scalararg[0] = 0;
+
+	// Force sane arguments.
+	if(hz < 0)
+		hz = 0;
+
+	// Disable preemption, otherwise we can be rescheduled to another thread
+	// that has profiling enabled.
+	g->m->locks++;
+
+	// Stop profiler on this thread so that it is safe to lock prof.
+	// if a profiling signal came in while we had prof locked,
+	// it would deadlock.
+	runtime·resetcpuprofiler(0);
+
+	while(!runtime·cas(&prof.lock, 0, 1))
+		runtime·osyield();
+	prof.hz = hz;
+	runtime·atomicstore(&prof.lock, 0);
+
+	runtime·lock(&runtime·sched.lock);
+	runtime·sched.profilehz = hz;
+	runtime·unlock(&runtime·sched.lock);
+
+	if(hz != 0)
+		runtime·resetcpuprofiler(hz);
+
+	g->m->locks--;
+}
+
+P *runtime·newP(void);
+
+// Change number of processors.  The world is stopped, sched is locked.
+static void
+procresize(int32 new)
+{
+	int32 i, old;
+	bool empty;
+	G *gp;
+	P *p;
+
+	old = runtime·gomaxprocs;
+	if(old < 0 || old > MaxGomaxprocs || new <= 0 || new >MaxGomaxprocs)
+		runtime·throw("procresize: invalid arg");
+	// initialize new P's
+	for(i = 0; i < new; i++) {
+		p = runtime·allp[i];
+		if(p == nil) {
+			p = runtime·newP();
+			p->id = i;
+			p->status = Pgcstop;
+			runtime·atomicstorep(&runtime·allp[i], p);
+		}
+		if(p->mcache == nil) {
+			if(old==0 && i==0)
+				p->mcache = g->m->mcache;  // bootstrap
+			else
+				p->mcache = runtime·allocmcache();
+		}
+	}
+
+	// redistribute runnable G's evenly
+	// collect all runnable goroutines in global queue preserving FIFO order
+	// FIFO order is required to ensure fairness even during frequent GCs
+	// see http://golang.org/issue/7126
+	empty = false;
+	while(!empty) {
+		empty = true;
+		for(i = 0; i < old; i++) {
+			p = runtime·allp[i];
+			if(p->runqhead == p->runqtail)
+				continue;
+			empty = false;
+			// pop from tail of local queue
+			p->runqtail--;
+			gp = p->runq[p->runqtail%nelem(p->runq)];
+			// push onto head of global queue
+			gp->schedlink = runtime·sched.runqhead;
+			runtime·sched.runqhead = gp;
+			if(runtime·sched.runqtail == nil)
+				runtime·sched.runqtail = gp;
+			runtime·sched.runqsize++;
+		}
+	}
+	// fill local queues with at most nelem(p->runq)/2 goroutines
+	// start at 1 because current M already executes some G and will acquire allp[0] below,
+	// so if we have a spare G we want to put it into allp[1].
+	for(i = 1; i < new * nelem(p->runq)/2 && runtime·sched.runqsize > 0; i++) {
+		gp = runtime·sched.runqhead;
+		runtime·sched.runqhead = gp->schedlink;
+		if(runtime·sched.runqhead == nil)
+			runtime·sched.runqtail = nil;
+		runtime·sched.runqsize--;
+		runqput(runtime·allp[i%new], gp);
+	}
+
+	// free unused P's
+	for(i = new; i < old; i++) {
+		p = runtime·allp[i];
+		runtime·freemcache(p->mcache);
+		p->mcache = nil;
+		gfpurge(p);
+		p->status = Pdead;
+		// can't free P itself because it can be referenced by an M in syscall
+	}
+
+	if(g->m->p)
+		g->m->p->m = nil;
+	g->m->p = nil;
+	g->m->mcache = nil;
+	p = runtime·allp[0];
+	p->m = nil;
+	p->status = Pidle;
+	acquirep(p);
+	for(i = new-1; i > 0; i--) {
+		p = runtime·allp[i];
+		p->status = Pidle;
+		pidleput(p);
+	}
+	runtime·atomicstore((uint32*)&runtime·gomaxprocs, new);
+}
+
+// Associate p and the current m.
+static void
+acquirep(P *p)
+{
+	if(g->m->p || g->m->mcache)
+		runtime·throw("acquirep: already in go");
+	if(p->m || p->status != Pidle) {
+		runtime·printf("acquirep: p->m=%p(%d) p->status=%d\n", p->m, p->m ? p->m->id : 0, p->status);
+		runtime·throw("acquirep: invalid p state");
+	}
+	g->m->mcache = p->mcache;
+	g->m->p = p;
+	p->m = g->m;
+	p->status = Prunning;
+}
+
+// Disassociate p and the current m.
+static P*
+releasep(void)
+{
+	P *p;
+
+	if(g->m->p == nil || g->m->mcache == nil)
+		runtime·throw("releasep: invalid arg");
+	p = g->m->p;
+	if(p->m != g->m || p->mcache != g->m->mcache || p->status != Prunning) {
+		runtime·printf("releasep: m=%p m->p=%p p->m=%p m->mcache=%p p->mcache=%p p->status=%d\n",
+			g->m, g->m->p, p->m, g->m->mcache, p->mcache, p->status);
+		runtime·throw("releasep: invalid p state");
+	}
+	g->m->p = nil;
+	g->m->mcache = nil;
+	p->m = nil;
+	p->status = Pidle;
+	return p;
+}
+
+static void
+incidlelocked(int32 v)
+{
+	runtime·lock(&runtime·sched.lock);
+	runtime·sched.nmidlelocked += v;
+	if(v > 0)
+		checkdead();
+	runtime·unlock(&runtime·sched.lock);
+}
+
+// Check for deadlock situation.
+// The check is based on number of running M's, if 0 -> deadlock.
+static void
+checkdead(void)
+{
+	G *gp;
+	P *p;
+	M *mp;
+	int32 run, grunning, s;
+	uintptr i;
+
+	// -1 for sysmon
+	run = runtime·sched.mcount - runtime·sched.nmidle - runtime·sched.nmidlelocked - 1;
+	if(run > 0)
+		return;
+	// If we are dying because of a signal caught on an already idle thread,
+	// freezetheworld will cause all running threads to block.
+	// And runtime will essentially enter into deadlock state,
+	// except that there is a thread that will call runtime·exit soon.
+	if(runtime·panicking > 0)
+		return;
+	if(run < 0) {
+		runtime·printf("runtime: checkdead: nmidle=%d nmidlelocked=%d mcount=%d\n",
+			runtime·sched.nmidle, runtime·sched.nmidlelocked, runtime·sched.mcount);
+		runtime·throw("checkdead: inconsistent counts");
+	}
+	grunning = 0;
+	runtime·lock(&runtime·allglock);
+	for(i = 0; i < runtime·allglen; i++) {
+		gp = runtime·allg[i];
+		if(gp->issystem)
+			continue;
+		s = runtime·readgstatus(gp);
+		switch(s&~Gscan) {
+		case Gwaiting:
+			grunning++;
+			break;
+		case Grunnable:
+		case Grunning:
+		case Gsyscall:
+			runtime·unlock(&runtime·allglock);
+			runtime·printf("runtime: checkdead: find g %D in status %d\n", gp->goid, s);
+			runtime·throw("checkdead: runnable g");
+			break;
+		}
+	}
+	runtime·unlock(&runtime·allglock);
+	if(grunning == 0)  // possible if main goroutine calls runtime·Goexit()
+		runtime·throw("no goroutines (main called runtime.Goexit) - deadlock!");
+
+	// Maybe jump time forward for playground.
+	if((gp = runtime·timejump()) != nil) {
+		runtime·casgstatus(gp, Gwaiting, Grunnable);
+		globrunqput(gp);
+ 		p = pidleget();
+ 		if(p == nil)
+ 			runtime·throw("checkdead: no p for timer");
+ 		mp = mget();
+ 		if(mp == nil)
+ 			newm(nil, p);
+ 		else {
+ 			mp->nextp = p;
+ 			runtime·notewakeup(&mp->park);
+ 		}
+ 		return;
+ 	}
+
+	g->m->throwing = -1;  // do not dump full stacks
+	runtime·throw("all goroutines are asleep - deadlock!");
+}
+
+static void
+sysmon(void)
+{
+	uint32 idle, delay, nscavenge;
+	int64 now, unixnow, lastpoll, lasttrace, lastgc;
+	int64 forcegcperiod, scavengelimit, lastscavenge, maxsleep;
+	G *gp;
+
+	// If we go two minutes without a garbage collection, force one to run.
+	forcegcperiod = 2*60*1e9;
+	// If a heap span goes unused for 5 minutes after a garbage collection,
+	// we hand it back to the operating system.
+	scavengelimit = 5*60*1e9;
+	if(runtime·debug.scavenge > 0) {
+		// Scavenge-a-lot for testing.
+		forcegcperiod = 10*1e6;
+		scavengelimit = 20*1e6;
+	}
+	lastscavenge = runtime·nanotime();
+	nscavenge = 0;
+	// Make wake-up period small enough for the sampling to be correct.
+	maxsleep = forcegcperiod/2;
+	if(scavengelimit < forcegcperiod)
+		maxsleep = scavengelimit/2;
+
+	lasttrace = 0;
+	idle = 0;  // how many cycles in succession we had not wokeup somebody
+	delay = 0;
+	for(;;) {
+		if(idle == 0)  // start with 20us sleep...
+			delay = 20;
+		else if(idle > 50)  // start doubling the sleep after 1ms...
+			delay *= 2;
+		if(delay > 10*1000)  // up to 10ms
+			delay = 10*1000;
+		runtime·usleep(delay);
+		if(runtime·debug.schedtrace <= 0 &&
+			(runtime·sched.gcwaiting || runtime·atomicload(&runtime·sched.npidle) == runtime·gomaxprocs)) {  // TODO: fast atomic
+			runtime·lock(&runtime·sched.lock);
+			if(runtime·atomicload(&runtime·sched.gcwaiting) || runtime·atomicload(&runtime·sched.npidle) == runtime·gomaxprocs) {
+				runtime·atomicstore(&runtime·sched.sysmonwait, 1);
+				runtime·unlock(&runtime·sched.lock);
+				runtime·notetsleep(&runtime·sched.sysmonnote, maxsleep);
+				runtime·lock(&runtime·sched.lock);
+				runtime·atomicstore(&runtime·sched.sysmonwait, 0);
+				runtime·noteclear(&runtime·sched.sysmonnote);
+				idle = 0;
+				delay = 20;
+			}
+			runtime·unlock(&runtime·sched.lock);
+		}
+		// poll network if not polled for more than 10ms
+		lastpoll = runtime·atomicload64(&runtime·sched.lastpoll);
+		now = runtime·nanotime();
+		unixnow = runtime·unixnanotime();
+		if(lastpoll != 0 && lastpoll + 10*1000*1000 < now) {
+			runtime·cas64(&runtime·sched.lastpoll, lastpoll, now);
+			gp = runtime·netpoll(false);  // non-blocking
+			if(gp) {
+				// Need to decrement number of idle locked M's
+				// (pretending that one more is running) before injectglist.
+				// Otherwise it can lead to the following situation:
+				// injectglist grabs all P's but before it starts M's to run the P's,
+				// another M returns from syscall, finishes running its G,
+				// observes that there is no work to do and no other running M's
+				// and reports deadlock.
+				incidlelocked(-1);
+				injectglist(gp);
+				incidlelocked(1);
+			}
+		}
+		// retake P's blocked in syscalls
+		// and preempt long running G's
+		if(retake(now))
+			idle = 0;
+		else
+			idle++;
+
+		// check if we need to force a GC
+		lastgc = runtime·atomicload64(&mstats.last_gc);
+		if(lastgc != 0 && unixnow - lastgc > forcegcperiod && runtime·atomicload(&runtime·forcegc.idle)) {
+			runtime·lock(&runtime·forcegc.lock);
+			runtime·forcegc.idle = 0;
+			runtime·forcegc.g->schedlink = nil;
+			injectglist(runtime·forcegc.g);
+			runtime·unlock(&runtime·forcegc.lock);
+		}
+
+		// scavenge heap once in a while
+		if(lastscavenge + scavengelimit/2 < now) {
+			runtime·MHeap_Scavenge(nscavenge, now, scavengelimit);
+			lastscavenge = now;
+			nscavenge++;
+		}
+
+		if(runtime·debug.schedtrace > 0 && lasttrace + runtime·debug.schedtrace*1000000ll <= now) {
+			lasttrace = now;
+			runtime·schedtrace(runtime·debug.scheddetail);
+		}
+	}
+}
+
+typedef struct Pdesc Pdesc;
+struct Pdesc
+{
+	uint32	schedtick;
+	int64	schedwhen;
+	uint32	syscalltick;
+	int64	syscallwhen;
+};
+#pragma dataflag NOPTR
+static Pdesc pdesc[MaxGomaxprocs];
+
+static uint32
+retake(int64 now)
+{
+	uint32 i, s, n;
+	int64 t;
+	P *p;
+	Pdesc *pd;
+
+	n = 0;
+	for(i = 0; i < runtime·gomaxprocs; i++) {
+		p = runtime·allp[i];
+		if(p==nil)
+			continue;
+		pd = &pdesc[i];
+		s = p->status;
+		if(s == Psyscall) {
+			// Retake P from syscall if it's there for more than 1 sysmon tick (at least 20us).
+			t = p->syscalltick;
+			if(pd->syscalltick != t) {
+				pd->syscalltick = t;
+				pd->syscallwhen = now;
+				continue;
+			}
+			// On the one hand we don't want to retake Ps if there is no other work to do,
+			// but on the other hand we want to retake them eventually
+			// because they can prevent the sysmon thread from deep sleep.
+			if(p->runqhead == p->runqtail &&
+				runtime·atomicload(&runtime·sched.nmspinning) + runtime·atomicload(&runtime·sched.npidle) > 0 &&
+				pd->syscallwhen + 10*1000*1000 > now)
+				continue;
+			// Need to decrement number of idle locked M's
+			// (pretending that one more is running) before the CAS.
+			// Otherwise the M from which we retake can exit the syscall,
+			// increment nmidle and report deadlock.
+			incidlelocked(-1);
+			if(runtime·cas(&p->status, s, Pidle)) {
+				n++;
+				handoffp(p);
+			}
+			incidlelocked(1);
+		} else if(s == Prunning) {
+			// Preempt G if it's running for more than 10ms.
+			t = p->schedtick;
+			if(pd->schedtick != t) {
+				pd->schedtick = t;
+				pd->schedwhen = now;
+				continue;
+			}
+			if(pd->schedwhen + 10*1000*1000 > now)
+				continue;
+			preemptone(p);
+		}
+	}
+	return n;
+}
+
+// Tell all goroutines that they have been preempted and they should stop.
+// This function is purely best-effort.  It can fail to inform a goroutine if a
+// processor just started running it.
+// No locks need to be held.
+// Returns true if preemption request was issued to at least one goroutine.
+static bool
+preemptall(void)
+{
+	P *p;
+	int32 i;
+	bool res;
+
+	res = false;
+	for(i = 0; i < runtime·gomaxprocs; i++) {
+		p = runtime·allp[i];
+		if(p == nil || p->status != Prunning)
+			continue;
+		res |= preemptone(p);
+	}
+	return res;
+}
+
+// Tell the goroutine running on processor P to stop.
+// This function is purely best-effort.  It can incorrectly fail to inform the
+// goroutine.  It can send inform the wrong goroutine.  Even if it informs the
+// correct goroutine, that goroutine might ignore the request if it is
+// simultaneously executing runtime·newstack.
+// No lock needs to be held.
+// Returns true if preemption request was issued.
+// The actual preemption will happen at some point in the future
+// and will be indicated by the gp->status no longer being
+// Grunning
+static bool
+preemptone(P *p)
+{
+	M *mp;
+	G *gp;
+
+	mp = p->m;
+	if(mp == nil || mp == g->m)
+		return false;
+	gp = mp->curg;
+	if(gp == nil || gp == mp->g0)
+		return false;
+	gp->preempt = true;
+	// Every call in a go routine checks for stack overflow by
+	// comparing the current stack pointer to gp->stackguard0.
+	// Setting gp->stackguard0 to StackPreempt folds
+	// preemption into the normal stack overflow check.
+	gp->stackguard0 = StackPreempt;
+	return true;
+}
+
+void
+runtime·schedtrace(bool detailed)
+{
+	static int64 starttime;
+	int64 now;
+	int64 id1, id2, id3;
+	int32 i, t, h;
+	uintptr gi;
+	int8 *fmt;
+	M *mp, *lockedm;
+	G *gp, *lockedg;
+	P *p;
+
+	now = runtime·nanotime();
+	if(starttime == 0)
+		starttime = now;
+
+	runtime·lock(&runtime·sched.lock);
+	runtime·printf("SCHED %Dms: gomaxprocs=%d idleprocs=%d threads=%d spinningthreads=%d idlethreads=%d runqueue=%d",
+		(now-starttime)/1000000, runtime·gomaxprocs, runtime·sched.npidle, runtime·sched.mcount,
+		runtime·sched.nmspinning, runtime·sched.nmidle, runtime·sched.runqsize);
+	if(detailed) {
+		runtime·printf(" gcwaiting=%d nmidlelocked=%d stopwait=%d sysmonwait=%d\n",
+			runtime·sched.gcwaiting, runtime·sched.nmidlelocked,
+			runtime·sched.stopwait, runtime·sched.sysmonwait);
+	}
+	// We must be careful while reading data from P's, M's and G's.
+	// Even if we hold schedlock, most data can be changed concurrently.
+	// E.g. (p->m ? p->m->id : -1) can crash if p->m changes from non-nil to nil.
+	for(i = 0; i < runtime·gomaxprocs; i++) {
+		p = runtime·allp[i];
+		if(p == nil)
+			continue;
+		mp = p->m;
+		h = runtime·atomicload(&p->runqhead);
+		t = runtime·atomicload(&p->runqtail);
+		if(detailed)
+			runtime·printf("  P%d: status=%d schedtick=%d syscalltick=%d m=%d runqsize=%d gfreecnt=%d\n",
+				i, p->status, p->schedtick, p->syscalltick, mp ? mp->id : -1, t-h, p->gfreecnt);
+		else {
+			// In non-detailed mode format lengths of per-P run queues as:
+			// [len1 len2 len3 len4]
+			fmt = " %d";
+			if(runtime·gomaxprocs == 1)
+				fmt = " [%d]\n";
+			else if(i == 0)
+				fmt = " [%d";
+			else if(i == runtime·gomaxprocs-1)
+				fmt = " %d]\n";
+			runtime·printf(fmt, t-h);
+		}
+	}
+	if(!detailed) {
+		runtime·unlock(&runtime·sched.lock);
+		return;
+	}
+	for(mp = runtime·allm; mp; mp = mp->alllink) {
+		p = mp->p;
+		gp = mp->curg;
+		lockedg = mp->lockedg;
+		id1 = -1;
+		if(p)
+			id1 = p->id;
+		id2 = -1;
+		if(gp)
+			id2 = gp->goid;
+		id3 = -1;
+		if(lockedg)
+			id3 = lockedg->goid;
+		runtime·printf("  M%d: p=%D curg=%D mallocing=%d throwing=%d gcing=%d"
+			" locks=%d dying=%d helpgc=%d spinning=%d blocked=%d lockedg=%D\n",
+			mp->id, id1, id2,
+			mp->mallocing, mp->throwing, mp->gcing, mp->locks, mp->dying, mp->helpgc,
+			mp->spinning, g->m->blocked, id3);
+	}
+	runtime·lock(&runtime·allglock);
+	for(gi = 0; gi < runtime·allglen; gi++) {
+		gp = runtime·allg[gi];
+		mp = gp->m;
+		lockedm = gp->lockedm;
+		runtime·printf("  G%D: status=%d(%S) m=%d lockedm=%d\n",
+			gp->goid, runtime·readgstatus(gp), gp->waitreason, mp ? mp->id : -1,
+			lockedm ? lockedm->id : -1);
+	}
+	runtime·unlock(&runtime·allglock);
+	runtime·unlock(&runtime·sched.lock);
+}
+
+// Put mp on midle list.
+// Sched must be locked.
+static void
+mput(M *mp)
+{
+	mp->schedlink = runtime·sched.midle;
+	runtime·sched.midle = mp;
+	runtime·sched.nmidle++;
+	checkdead();
+}
+
+// Try to get an m from midle list.
+// Sched must be locked.
+static M*
+mget(void)
+{
+	M *mp;
+
+	if((mp = runtime·sched.midle) != nil){
+		runtime·sched.midle = mp->schedlink;
+		runtime·sched.nmidle--;
+	}
+	return mp;
+}
+
+// Put gp on the global runnable queue.
+// Sched must be locked.
+static void
+globrunqput(G *gp)
+{
+	gp->schedlink = nil;
+	if(runtime·sched.runqtail)
+		runtime·sched.runqtail->schedlink = gp;
+	else
+		runtime·sched.runqhead = gp;
+	runtime·sched.runqtail = gp;
+	runtime·sched.runqsize++;
+}
+
+// Put a batch of runnable goroutines on the global runnable queue.
+// Sched must be locked.
+static void
+globrunqputbatch(G *ghead, G *gtail, int32 n)
+{
+	gtail->schedlink = nil;
+	if(runtime·sched.runqtail)
+		runtime·sched.runqtail->schedlink = ghead;
+	else
+		runtime·sched.runqhead = ghead;
+	runtime·sched.runqtail = gtail;
+	runtime·sched.runqsize += n;
+}
+
+// Try get a batch of G's from the global runnable queue.
+// Sched must be locked.
+static G*
+globrunqget(P *p, int32 max)
+{
+	G *gp, *gp1;
+	int32 n;
+
+	if(runtime·sched.runqsize == 0)
+		return nil;
+	n = runtime·sched.runqsize/runtime·gomaxprocs+1;
+	if(n > runtime·sched.runqsize)
+		n = runtime·sched.runqsize;
+	if(max > 0 && n > max)
+		n = max;
+	if(n > nelem(p->runq)/2)
+		n = nelem(p->runq)/2;
+	runtime·sched.runqsize -= n;
+	if(runtime·sched.runqsize == 0)
+		runtime·sched.runqtail = nil;
+	gp = runtime·sched.runqhead;
+	runtime·sched.runqhead = gp->schedlink;
+	n--;
+	while(n--) {
+		gp1 = runtime·sched.runqhead;
+		runtime·sched.runqhead = gp1->schedlink;
+		runqput(p, gp1);
+	}
+	return gp;
+}
+
+// Put p to on pidle list.
+// Sched must be locked.
+static void
+pidleput(P *p)
+{
+	p->link = runtime·sched.pidle;
+	runtime·sched.pidle = p;
+	runtime·xadd(&runtime·sched.npidle, 1);  // TODO: fast atomic
+}
+
+// Try get a p from pidle list.
+// Sched must be locked.
+static P*
+pidleget(void)
+{
+	P *p;
+
+	p = runtime·sched.pidle;
+	if(p) {
+		runtime·sched.pidle = p->link;
+		runtime·xadd(&runtime·sched.npidle, -1);  // TODO: fast atomic
+	}
+	return p;
+}
+
+// Try to put g on local runnable queue.
+// If it's full, put onto global queue.
+// Executed only by the owner P.
+static void
+runqput(P *p, G *gp)
+{
+	uint32 h, t;
+
+retry:
+	h = runtime·atomicload(&p->runqhead);  // load-acquire, synchronize with consumers
+	t = p->runqtail;
+	if(t - h < nelem(p->runq)) {
+		p->runq[t%nelem(p->runq)] = gp;
+		runtime·atomicstore(&p->runqtail, t+1);  // store-release, makes the item available for consumption
+		return;
+	}
+	if(runqputslow(p, gp, h, t))
+		return;
+	// the queue is not full, now the put above must suceed
+	goto retry;
+}
+
+// Put g and a batch of work from local runnable queue on global queue.
+// Executed only by the owner P.
+static bool
+runqputslow(P *p, G *gp, uint32 h, uint32 t)
+{
+	G *batch[nelem(p->runq)/2+1];
+	uint32 n, i;
+
+	// First, grab a batch from local queue.
+	n = t-h;
+	n = n/2;
+	if(n != nelem(p->runq)/2)
+		runtime·throw("runqputslow: queue is not full");
+	for(i=0; i<n; i++)
+		batch[i] = p->runq[(h+i)%nelem(p->runq)];
+	if(!runtime·cas(&p->runqhead, h, h+n))  // cas-release, commits consume
+		return false;
+	batch[n] = gp;
+	// Link the goroutines.
+	for(i=0; i<n; i++)
+		batch[i]->schedlink = batch[i+1];
+	// Now put the batch on global queue.
+	runtime·lock(&runtime·sched.lock);
+	globrunqputbatch(batch[0], batch[n], n+1);
+	runtime·unlock(&runtime·sched.lock);
+	return true;
+}
+
+// Get g from local runnable queue.
+// Executed only by the owner P.
+static G*
+runqget(P *p)
+{
+	G *gp;
+	uint32 t, h;
+
+	for(;;) {
+		h = runtime·atomicload(&p->runqhead);  // load-acquire, synchronize with other consumers
+		t = p->runqtail;
+		if(t == h)
+			return nil;
+		gp = p->runq[h%nelem(p->runq)];
+		if(runtime·cas(&p->runqhead, h, h+1))  // cas-release, commits consume
+			return gp;
+	}
+}
+
+// Grabs a batch of goroutines from local runnable queue.
+// batch array must be of size nelem(p->runq)/2. Returns number of grabbed goroutines.
+// Can be executed by any P.
+static uint32
+runqgrab(P *p, G **batch)
+{
+	uint32 t, h, n, i;
+
+	for(;;) {
+		h = runtime·atomicload(&p->runqhead);  // load-acquire, synchronize with other consumers
+		t = runtime·atomicload(&p->runqtail);  // load-acquire, synchronize with the producer
+		n = t-h;
+		n = n - n/2;
+		if(n == 0)
+			break;
+		if(n > nelem(p->runq)/2)  // read inconsistent h and t
+			continue;
+		for(i=0; i<n; i++)
+			batch[i] = p->runq[(h+i)%nelem(p->runq)];
+		if(runtime·cas(&p->runqhead, h, h+n))  // cas-release, commits consume
+			break;
+	}
+	return n;
+}
+
+// Steal half of elements from local runnable queue of p2
+// and put onto local runnable queue of p.
+// Returns one of the stolen elements (or nil if failed).
+static G*
+runqsteal(P *p, P *p2)
+{
+	G *gp;
+	G *batch[nelem(p->runq)/2];
+	uint32 t, h, n, i;
+
+	n = runqgrab(p2, batch);
+	if(n == 0)
+		return nil;
+	n--;
+	gp = batch[n];
+	if(n == 0)
+		return gp;
+	h = runtime·atomicload(&p->runqhead);  // load-acquire, synchronize with consumers
+	t = p->runqtail;
+	if(t - h + n >= nelem(p->runq))
+		runtime·throw("runqsteal: runq overflow");
+	for(i=0; i<n; i++, t++)
+		p->runq[t%nelem(p->runq)] = batch[i];
+	runtime·atomicstore(&p->runqtail, t);  // store-release, makes the item available for consumption
+	return gp;
+}
+
+void
+runtime·testSchedLocalQueue(void)
+{
+	P *p;
+	G *gs;
+	int32 i, j;
+
+	p = (P*)runtime·mallocgc(sizeof(*p), nil, FlagNoScan);
+	gs = (G*)runtime·mallocgc(nelem(p->runq)*sizeof(*gs), nil, FlagNoScan);
+
+	for(i = 0; i < nelem(p->runq); i++) {
+		if(runqget(p) != nil)
+			runtime·throw("runq is not empty initially");
+		for(j = 0; j < i; j++)
+			runqput(p, &gs[i]);
+		for(j = 0; j < i; j++) {
+			if(runqget(p) != &gs[i]) {
+				runtime·printf("bad element at iter %d/%d\n", i, j);
+				runtime·throw("bad element");
+			}
+		}
+		if(runqget(p) != nil)
+			runtime·throw("runq is not empty afterwards");
+	}
+}
+
+void
+runtime·testSchedLocalQueueSteal(void)
+{
+	P *p1, *p2;
+	G *gs, *gp;
+	int32 i, j, s;
+
+	p1 = (P*)runtime·mallocgc(sizeof(*p1), nil, FlagNoScan);
+	p2 = (P*)runtime·mallocgc(sizeof(*p2), nil, FlagNoScan);
+	gs = (G*)runtime·mallocgc(nelem(p1->runq)*sizeof(*gs), nil, FlagNoScan);
+
+	for(i = 0; i < nelem(p1->runq); i++) {
+		for(j = 0; j < i; j++) {
+			gs[j].sig = 0;
+			runqput(p1, &gs[j]);
+		}
+		gp = runqsteal(p2, p1);
+		s = 0;
+		if(gp) {
+			s++;
+			gp->sig++;
+		}
+		while(gp = runqget(p2)) {
+			s++;
+			gp->sig++;
+		}
+		while(gp = runqget(p1))
+			gp->sig++;
+		for(j = 0; j < i; j++) {
+			if(gs[j].sig != 1) {
+				runtime·printf("bad element %d(%d) at iter %d\n", j, gs[j].sig, i);
+				runtime·throw("bad element");
+			}
+		}
+		if(s != i/2 && s != i/2+1) {
+			runtime·printf("bad steal %d, want %d or %d, iter %d\n",
+				s, i/2, i/2+1, i);
+			runtime·throw("bad steal");
+		}
+	}
+}
+
+void
+runtime·setmaxthreads_m(void)
+{
+	int32 in;
+	int32 out;
+
+	in = g->m->scalararg[0];
+
+	runtime·lock(&runtime·sched.lock);
+	out = runtime·sched.maxmcount;
+	runtime·sched.maxmcount = in;
+	checkmcount();
+	runtime·unlock(&runtime·sched.lock);
+
+	g->m->scalararg[0] = out;
+}
+
+static int8 experiment[] = GOEXPERIMENT; // defined in zaexperiment.h
+
+static bool
+haveexperiment(int8 *name)
+{
+	int32 i, j;
+	
+	for(i=0; i<sizeof(experiment); i++) {
+		if((i == 0 || experiment[i-1] == ',') && experiment[i] == name[0]) {
+			for(j=0; name[j]; j++)
+				if(experiment[i+j] != name[j])
+					goto nomatch;
+			if(experiment[i+j] != '\0' && experiment[i+j] != ',')
+				goto nomatch;
+			return 1;
+		}
+	nomatch:;
+	}
+	return 0;
+}
+
+#pragma textflag NOSPLIT
+void
+sync·runtime_procPin(intptr p)
+{
+	M *mp;
+
+	mp = g->m;
+	// Disable preemption.
+	mp->locks++;
+	p = mp->p->id;
+	FLUSH(&p);
+}
+
+#pragma textflag NOSPLIT
+void
+sync·runtime_procUnpin()
+{
+	g->m->locks--;
+}
diff --git a/src/runtime/proc.go b/src/runtime/proc.go
new file mode 100644
index 0000000..517ca03
--- /dev/null
+++ b/src/runtime/proc.go
@@ -0,0 +1,246 @@
+// 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 runtime
+
+import "unsafe"
+
+func newsysmon()
+
+func runtime_init()
+func main_init()
+func main_main()
+
+// The main goroutine.
+func main() {
+	g := getg()
+
+	// Racectx of m0->g0 is used only as the parent of the main goroutine.
+	// It must not be used for anything else.
+	g.m.g0.racectx = 0
+
+	// Max stack size is 1 GB on 64-bit, 250 MB on 32-bit.
+	// Using decimal instead of binary GB and MB because
+	// they look nicer in the stack overflow failure message.
+	if ptrSize == 8 {
+		maxstacksize = 1000000000
+	} else {
+		maxstacksize = 250000000
+	}
+
+	onM(newsysmon)
+
+	// Lock the main goroutine onto this, the main OS thread,
+	// during initialization.  Most programs won't care, but a few
+	// do require certain calls to be made by the main thread.
+	// Those can arrange for main.main to run in the main thread
+	// by calling runtime.LockOSThread during initialization
+	// to preserve the lock.
+	lockOSThread()
+
+	if g.m != &m0 {
+		gothrow("runtime.main not on m0")
+	}
+
+	runtime_init() // must be before defer
+
+	// Defer unlock so that runtime.Goexit during init does the unlock too.
+	needUnlock := true
+	defer func() {
+		if needUnlock {
+			unlockOSThread()
+		}
+	}()
+
+	memstats.enablegc = true // now that runtime is initialized, GC is okay
+
+	main_init()
+
+	needUnlock = false
+	unlockOSThread()
+
+	main_main()
+	if raceenabled {
+		racefini()
+	}
+
+	// Make racy client program work: if panicking on
+	// another goroutine at the same time as main returns,
+	// let the other goroutine finish printing the panic trace.
+	// Once it does, it will exit. See issue 3934.
+	if panicking != 0 {
+		gopark(nil, nil, "panicwait")
+	}
+
+	exit(0)
+	for {
+		var x *int32
+		*x = 0
+	}
+}
+
+var parkunlock_c byte
+
+// start forcegc helper goroutine
+func init() {
+	go forcegchelper()
+}
+
+func forcegchelper() {
+	forcegc.g = getg()
+	forcegc.g.issystem = true
+	for {
+		lock(&forcegc.lock)
+		if forcegc.idle != 0 {
+			gothrow("forcegc: phase error")
+		}
+		atomicstore(&forcegc.idle, 1)
+		goparkunlock(&forcegc.lock, "force gc (idle)")
+		// this goroutine is explicitly resumed by sysmon
+		if debug.gctrace > 0 {
+			println("GC forced")
+		}
+		gogc(1)
+	}
+}
+
+//go:nosplit
+
+// Gosched yields the processor, allowing other goroutines to run.  It does not
+// suspend the current goroutine, so execution resumes automatically.
+func Gosched() {
+	mcall(gosched_m)
+}
+
+// Puts the current goroutine into a waiting state and calls unlockf.
+// If unlockf returns false, the goroutine is resumed.
+func gopark(unlockf unsafe.Pointer, lock unsafe.Pointer, reason string) {
+	mp := acquirem()
+	gp := mp.curg
+	status := readgstatus(gp)
+	if status != _Grunning && status != _Gscanrunning {
+		gothrow("gopark: bad g status")
+	}
+	mp.waitlock = lock
+	mp.waitunlockf = unlockf
+	gp.waitreason = reason
+	releasem(mp)
+	// can't do anything that might move the G between Ms here.
+	mcall(park_m)
+}
+
+// Puts the current goroutine into a waiting state and unlocks the lock.
+// The goroutine can be made runnable again by calling goready(gp).
+func goparkunlock(lock *mutex, reason string) {
+	gopark(unsafe.Pointer(&parkunlock_c), unsafe.Pointer(lock), reason)
+}
+
+func goready(gp *g) {
+	mp := acquirem()
+	mp.ptrarg[0] = unsafe.Pointer(gp)
+	onM(ready_m)
+	releasem(mp)
+}
+
+//go:nosplit
+func acquireSudog() *sudog {
+	c := gomcache()
+	s := c.sudogcache
+	if s != nil {
+		if s.elem != nil {
+			gothrow("acquireSudog: found s.elem != nil in cache")
+		}
+		c.sudogcache = s.next
+		s.next = nil
+		return s
+	}
+
+	// Delicate dance: the semaphore implementation calls
+	// acquireSudog, acquireSudog calls new(sudog),
+	// new calls malloc, malloc can call the garbage collector,
+	// and the garbage collector calls the semaphore implementation
+	// in stoptheworld.
+	// Break the cycle by doing acquirem/releasem around new(sudog).
+	// The acquirem/releasem increments m.locks during new(sudog),
+	// which keeps the garbage collector from being invoked.
+	mp := acquirem()
+	p := new(sudog)
+	releasem(mp)
+	return p
+}
+
+//go:nosplit
+func releaseSudog(s *sudog) {
+	if s.elem != nil {
+		gothrow("runtime: sudog with non-nil elem")
+	}
+	if s.selectdone != nil {
+		gothrow("runtime: sudog with non-nil selectdone")
+	}
+	if s.next != nil {
+		gothrow("runtime: sudog with non-nil next")
+	}
+	if s.prev != nil {
+		gothrow("runtime: sudog with non-nil prev")
+	}
+	if s.waitlink != nil {
+		gothrow("runtime: sudog with non-nil waitlink")
+	}
+	gp := getg()
+	if gp.param != nil {
+		gothrow("runtime: releaseSudog with non-nil gp.param")
+	}
+	c := gomcache()
+	s.next = c.sudogcache
+	c.sudogcache = s
+}
+
+// funcPC returns the entry PC of the function f.
+// It assumes that f is a func value. Otherwise the behavior is undefined.
+//go:nosplit
+func funcPC(f interface{}) uintptr {
+	return **(**uintptr)(add(unsafe.Pointer(&f), ptrSize))
+}
+
+// called from assembly
+func badmcall(fn func(*g)) {
+	gothrow("runtime: mcall called on m->g0 stack")
+}
+
+func badmcall2(fn func(*g)) {
+	gothrow("runtime: mcall function returned")
+}
+
+func badreflectcall() {
+	panic("runtime: arg size to reflect.call more than 1GB")
+}
+
+func lockedOSThread() bool {
+	gp := getg()
+	return gp.lockedm != nil && gp.m.lockedg != nil
+}
+
+func newP() *p {
+	return new(p)
+}
+
+func newM() *m {
+	return new(m)
+}
+
+func newG() *g {
+	return new(g)
+}
+
+func allgadd(gp *g) {
+	if readgstatus(gp) == _Gidle {
+		gothrow("allgadd: bad status Gidle")
+	}
+
+	lock(&allglock)
+	allgs = append(allgs, gp)
+	allg = &allgs[0]
+	allglen = uintptr(len(allgs))
+	unlock(&allglock)
+}
diff --git a/src/runtime/proc_test.go b/src/runtime/proc_test.go
new file mode 100644
index 0000000..aa9bc81
--- /dev/null
+++ b/src/runtime/proc_test.go
@@ -0,0 +1,480 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package runtime_test
+
+import (
+	"math"
+	"runtime"
+	"sync/atomic"
+	"syscall"
+	"testing"
+	"time"
+)
+
+var stop = make(chan bool, 1)
+
+func perpetuumMobile() {
+	select {
+	case <-stop:
+	default:
+		go perpetuumMobile()
+	}
+}
+
+func TestStopTheWorldDeadlock(t *testing.T) {
+	if testing.Short() {
+		t.Skip("skipping during short test")
+	}
+	maxprocs := runtime.GOMAXPROCS(3)
+	compl := make(chan bool, 2)
+	go func() {
+		for i := 0; i != 1000; i += 1 {
+			runtime.GC()
+		}
+		compl <- true
+	}()
+	go func() {
+		for i := 0; i != 1000; i += 1 {
+			runtime.GOMAXPROCS(3)
+		}
+		compl <- true
+	}()
+	go perpetuumMobile()
+	<-compl
+	<-compl
+	stop <- true
+	runtime.GOMAXPROCS(maxprocs)
+}
+
+func TestYieldProgress(t *testing.T) {
+	testYieldProgress(t, false)
+}
+
+func TestYieldLockedProgress(t *testing.T) {
+	testYieldProgress(t, true)
+}
+
+func testYieldProgress(t *testing.T, locked bool) {
+	c := make(chan bool)
+	cack := make(chan bool)
+	go func() {
+		if locked {
+			runtime.LockOSThread()
+		}
+		for {
+			select {
+			case <-c:
+				cack <- true
+				return
+			default:
+				runtime.Gosched()
+			}
+		}
+	}()
+	time.Sleep(10 * time.Millisecond)
+	c <- true
+	<-cack
+}
+
+func TestYieldLocked(t *testing.T) {
+	const N = 10
+	c := make(chan bool)
+	go func() {
+		runtime.LockOSThread()
+		for i := 0; i < N; i++ {
+			runtime.Gosched()
+			time.Sleep(time.Millisecond)
+		}
+		c <- true
+		// runtime.UnlockOSThread() is deliberately omitted
+	}()
+	<-c
+}
+
+func TestGoroutineParallelism(t *testing.T) {
+	P := 4
+	N := 10
+	if testing.Short() {
+		P = 3
+		N = 3
+	}
+	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(P))
+	// If runtime triggers a forced GC during this test then it will deadlock,
+	// since the goroutines can't be stopped/preempted.
+	// So give this test as much time as possible.
+	runtime.GC()
+	for try := 0; try < N; try++ {
+		done := make(chan bool)
+		x := uint32(0)
+		for p := 0; p < P; p++ {
+			// Test that all P goroutines are scheduled at the same time
+			go func(p int) {
+				for i := 0; i < 3; i++ {
+					expected := uint32(P*i + p)
+					for atomic.LoadUint32(&x) != expected {
+					}
+					atomic.StoreUint32(&x, expected+1)
+				}
+				done <- true
+			}(p)
+		}
+		for p := 0; p < P; p++ {
+			<-done
+		}
+	}
+}
+
+func TestBlockLocked(t *testing.T) {
+	const N = 10
+	c := make(chan bool)
+	go func() {
+		runtime.LockOSThread()
+		for i := 0; i < N; i++ {
+			c <- true
+		}
+		runtime.UnlockOSThread()
+	}()
+	for i := 0; i < N; i++ {
+		<-c
+	}
+}
+
+func TestTimerFairness(t *testing.T) {
+	done := make(chan bool)
+	c := make(chan bool)
+	for i := 0; i < 2; i++ {
+		go func() {
+			for {
+				select {
+				case c <- true:
+				case <-done:
+					return
+				}
+			}
+		}()
+	}
+
+	timer := time.After(20 * time.Millisecond)
+	for {
+		select {
+		case <-c:
+		case <-timer:
+			close(done)
+			return
+		}
+	}
+}
+
+func TestTimerFairness2(t *testing.T) {
+	done := make(chan bool)
+	c := make(chan bool)
+	for i := 0; i < 2; i++ {
+		go func() {
+			timer := time.After(20 * time.Millisecond)
+			var buf [1]byte
+			for {
+				syscall.Read(0, buf[0:0])
+				select {
+				case c <- true:
+				case <-c:
+				case <-timer:
+					done <- true
+					return
+				}
+			}
+		}()
+	}
+	<-done
+	<-done
+}
+
+// The function is used to test preemption at split stack checks.
+// Declaring a var avoids inlining at the call site.
+var preempt = func() int {
+	var a [128]int
+	sum := 0
+	for _, v := range a {
+		sum += v
+	}
+	return sum
+}
+
+func TestPreemption(t *testing.T) {
+	// Test that goroutines are preempted at function calls.
+	N := 5
+	if testing.Short() {
+		N = 2
+	}
+	c := make(chan bool)
+	var x uint32
+	for g := 0; g < 2; g++ {
+		go func(g int) {
+			for i := 0; i < N; i++ {
+				for atomic.LoadUint32(&x) != uint32(g) {
+					preempt()
+				}
+				atomic.StoreUint32(&x, uint32(1-g))
+			}
+			c <- true
+		}(g)
+	}
+	<-c
+	<-c
+}
+
+func TestPreemptionGC(t *testing.T) {
+	// Test that pending GC preempts running goroutines.
+	P := 5
+	N := 10
+	if testing.Short() {
+		P = 3
+		N = 2
+	}
+	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(P + 1))
+	var stop uint32
+	for i := 0; i < P; i++ {
+		go func() {
+			for atomic.LoadUint32(&stop) == 0 {
+				preempt()
+			}
+		}()
+	}
+	for i := 0; i < N; i++ {
+		runtime.Gosched()
+		runtime.GC()
+	}
+	atomic.StoreUint32(&stop, 1)
+}
+
+func TestGCFairness(t *testing.T) {
+	output := executeTest(t, testGCFairnessSource, nil)
+	want := "OK\n"
+	if output != want {
+		t.Fatalf("want %s, got %s\n", want, output)
+	}
+}
+
+const testGCFairnessSource = `
+package main
+
+import (
+	"fmt"
+	"os"
+	"runtime"
+	"time"
+)
+
+func main() {
+	runtime.GOMAXPROCS(1)
+	f, err := os.Open("/dev/null")
+	if os.IsNotExist(err) {
+		// This test tests what it is intended to test only if writes are fast.
+		// If there is no /dev/null, we just don't execute the test.
+		fmt.Println("OK")
+		return
+	}
+	if err != nil {
+		fmt.Println(err)
+		os.Exit(1)
+	}
+	for i := 0; i < 2; i++ {
+		go func() {
+			for {
+				f.Write([]byte("."))
+			}
+		}()
+	}
+	time.Sleep(10 * time.Millisecond)
+	fmt.Println("OK")
+}
+`
+
+func stackGrowthRecursive(i int) {
+	var pad [128]uint64
+	if i != 0 && pad[0] == 0 {
+		stackGrowthRecursive(i - 1)
+	}
+}
+
+func TestPreemptSplitBig(t *testing.T) {
+	if testing.Short() {
+		t.Skip("skipping in -short mode")
+	}
+	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(2))
+	stop := make(chan int)
+	go big(stop)
+	for i := 0; i < 3; i++ {
+		time.Sleep(10 * time.Microsecond) // let big start running
+		runtime.GC()
+	}
+	close(stop)
+}
+
+func big(stop chan int) int {
+	n := 0
+	for {
+		// delay so that gc is sure to have asked for a preemption
+		for i := 0; i < 1e9; i++ {
+			n++
+		}
+
+		// call bigframe, which used to miss the preemption in its prologue.
+		bigframe(stop)
+
+		// check if we've been asked to stop.
+		select {
+		case <-stop:
+			return n
+		}
+	}
+}
+
+func bigframe(stop chan int) int {
+	// not splitting the stack will overflow.
+	// small will notice that it needs a stack split and will
+	// catch the overflow.
+	var x [8192]byte
+	return small(stop, &x)
+}
+
+func small(stop chan int, x *[8192]byte) int {
+	for i := range x {
+		x[i] = byte(i)
+	}
+	sum := 0
+	for i := range x {
+		sum += int(x[i])
+	}
+
+	// keep small from being a leaf function, which might
+	// make it not do any stack check at all.
+	nonleaf(stop)
+
+	return sum
+}
+
+func nonleaf(stop chan int) bool {
+	// do something that won't be inlined:
+	select {
+	case <-stop:
+		return true
+	default:
+		return false
+	}
+}
+
+func TestSchedLocalQueue(t *testing.T) {
+	runtime.RunSchedLocalQueueTest()
+}
+
+func TestSchedLocalQueueSteal(t *testing.T) {
+	runtime.RunSchedLocalQueueStealTest()
+}
+
+func benchmarkStackGrowth(b *testing.B, rec int) {
+	b.RunParallel(func(pb *testing.PB) {
+		for pb.Next() {
+			stackGrowthRecursive(rec)
+		}
+	})
+}
+
+func BenchmarkStackGrowth(b *testing.B) {
+	benchmarkStackGrowth(b, 10)
+}
+
+func BenchmarkStackGrowthDeep(b *testing.B) {
+	benchmarkStackGrowth(b, 1024)
+}
+
+func BenchmarkCreateGoroutines(b *testing.B) {
+	benchmarkCreateGoroutines(b, 1)
+}
+
+func BenchmarkCreateGoroutinesParallel(b *testing.B) {
+	benchmarkCreateGoroutines(b, runtime.GOMAXPROCS(-1))
+}
+
+func benchmarkCreateGoroutines(b *testing.B, procs int) {
+	c := make(chan bool)
+	var f func(n int)
+	f = func(n int) {
+		if n == 0 {
+			c <- true
+			return
+		}
+		go f(n - 1)
+	}
+	for i := 0; i < procs; i++ {
+		go f(b.N / procs)
+	}
+	for i := 0; i < procs; i++ {
+		<-c
+	}
+}
+
+type Matrix [][]float64
+
+func BenchmarkMatmult(b *testing.B) {
+	b.StopTimer()
+	// matmult is O(N**3) but testing expects O(b.N),
+	// so we need to take cube root of b.N
+	n := int(math.Cbrt(float64(b.N))) + 1
+	A := makeMatrix(n)
+	B := makeMatrix(n)
+	C := makeMatrix(n)
+	b.StartTimer()
+	matmult(nil, A, B, C, 0, n, 0, n, 0, n, 8)
+}
+
+func makeMatrix(n int) Matrix {
+	m := make(Matrix, n)
+	for i := 0; i < n; i++ {
+		m[i] = make([]float64, n)
+		for j := 0; j < n; j++ {
+			m[i][j] = float64(i*n + j)
+		}
+	}
+	return m
+}
+
+func matmult(done chan<- struct{}, A, B, C Matrix, i0, i1, j0, j1, k0, k1, threshold int) {
+	di := i1 - i0
+	dj := j1 - j0
+	dk := k1 - k0
+	if di >= dj && di >= dk && di >= threshold {
+		// divide in two by y axis
+		mi := i0 + di/2
+		done1 := make(chan struct{}, 1)
+		go matmult(done1, A, B, C, i0, mi, j0, j1, k0, k1, threshold)
+		matmult(nil, A, B, C, mi, i1, j0, j1, k0, k1, threshold)
+		<-done1
+	} else if dj >= dk && dj >= threshold {
+		// divide in two by x axis
+		mj := j0 + dj/2
+		done1 := make(chan struct{}, 1)
+		go matmult(done1, A, B, C, i0, i1, j0, mj, k0, k1, threshold)
+		matmult(nil, A, B, C, i0, i1, mj, j1, k0, k1, threshold)
+		<-done1
+	} else if dk >= threshold {
+		// divide in two by "k" axis
+		// deliberately not parallel because of data races
+		mk := k0 + dk/2
+		matmult(nil, A, B, C, i0, i1, j0, j1, k0, mk, threshold)
+		matmult(nil, A, B, C, i0, i1, j0, j1, mk, k1, threshold)
+	} else {
+		// the matrices are small enough, compute directly
+		for i := i0; i < i1; i++ {
+			for j := j0; j < j1; j++ {
+				for k := k0; k < k1; k++ {
+					C[i][j] += A[i][k] * B[k][j]
+				}
+			}
+		}
+	}
+	if done != nil {
+		done <- struct{}{}
+	}
+}
diff --git a/src/runtime/race.c b/src/runtime/race.c
new file mode 100644
index 0000000..5b0d116
--- /dev/null
+++ b/src/runtime/race.c
@@ -0,0 +1,347 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Implementation of the race detector API.
+// +build race
+
+#include "runtime.h"
+#include "arch_GOARCH.h"
+#include "malloc.h"
+#include "race.h"
+#include "type.h"
+#include "typekind.h"
+#include "textflag.h"
+
+// Race runtime functions called via runtime·racecall.
+void __tsan_init(void);
+void __tsan_fini(void);
+void __tsan_map_shadow(void);
+void __tsan_finalizer_goroutine(void);
+void __tsan_go_start(void);
+void __tsan_go_end(void);
+void __tsan_malloc(void);
+void __tsan_acquire(void);
+void __tsan_release(void);
+void __tsan_release_merge(void);
+void __tsan_go_ignore_sync_begin(void);
+void __tsan_go_ignore_sync_end(void);
+
+// Mimic what cmd/cgo would do.
+#pragma cgo_import_static __tsan_init
+#pragma cgo_import_static __tsan_fini
+#pragma cgo_import_static __tsan_map_shadow
+#pragma cgo_import_static __tsan_finalizer_goroutine
+#pragma cgo_import_static __tsan_go_start
+#pragma cgo_import_static __tsan_go_end
+#pragma cgo_import_static __tsan_malloc
+#pragma cgo_import_static __tsan_acquire
+#pragma cgo_import_static __tsan_release
+#pragma cgo_import_static __tsan_release_merge
+#pragma cgo_import_static __tsan_go_ignore_sync_begin
+#pragma cgo_import_static __tsan_go_ignore_sync_end
+
+// These are called from race_amd64.s.
+#pragma cgo_import_static __tsan_read
+#pragma cgo_import_static __tsan_read_pc
+#pragma cgo_import_static __tsan_read_range
+#pragma cgo_import_static __tsan_write
+#pragma cgo_import_static __tsan_write_pc
+#pragma cgo_import_static __tsan_write_range
+#pragma cgo_import_static __tsan_func_enter
+#pragma cgo_import_static __tsan_func_exit
+
+#pragma cgo_import_static __tsan_go_atomic32_load
+#pragma cgo_import_static __tsan_go_atomic64_load
+#pragma cgo_import_static __tsan_go_atomic32_store
+#pragma cgo_import_static __tsan_go_atomic64_store
+#pragma cgo_import_static __tsan_go_atomic32_exchange
+#pragma cgo_import_static __tsan_go_atomic64_exchange
+#pragma cgo_import_static __tsan_go_atomic32_fetch_add
+#pragma cgo_import_static __tsan_go_atomic64_fetch_add
+#pragma cgo_import_static __tsan_go_atomic32_compare_exchange
+#pragma cgo_import_static __tsan_go_atomic64_compare_exchange
+
+extern byte runtime·noptrdata[];
+extern byte runtime·enoptrdata[];
+extern byte runtime·data[];
+extern byte runtime·edata[];
+extern byte runtime·bss[];
+extern byte runtime·ebss[];
+extern byte runtime·noptrbss[];
+extern byte runtime·enoptrbss[];
+
+// start/end of global data (data+bss).
+uintptr runtime·racedatastart;
+uintptr runtime·racedataend;
+// start/end of heap for race_amd64.s
+uintptr runtime·racearenastart;
+uintptr runtime·racearenaend;
+
+void runtime·racefuncenter(void *callpc);
+void runtime·racefuncexit(void);
+void runtime·racereadrangepc1(void *addr, uintptr sz, void *pc);
+void runtime·racewriterangepc1(void *addr, uintptr sz, void *pc);
+void runtime·racesymbolizethunk(void*);
+
+// racecall allows calling an arbitrary function f from C race runtime
+// with up to 4 uintptr arguments.
+void runtime·racecall(void(*f)(void), ...);
+
+// checks if the address has shadow (i.e. heap or data/bss)
+#pragma textflag NOSPLIT
+static bool
+isvalidaddr(uintptr addr)
+{
+	if(addr >= runtime·racearenastart && addr < runtime·racearenaend)
+		return true;
+	if(addr >= runtime·racedatastart && addr < runtime·racedataend)
+		return true;
+	return false;
+}
+
+#pragma textflag NOSPLIT
+uintptr
+runtime·raceinit(void)
+{
+	uintptr racectx, start, end, size;
+
+	// cgo is required to initialize libc, which is used by race runtime
+	if(!runtime·iscgo)
+		runtime·throw("raceinit: race build must use cgo");
+	runtime·racecall(__tsan_init, &racectx, runtime·racesymbolizethunk);
+	// Round data segment to page boundaries, because it's used in mmap().
+	// The relevant sections are noptrdata, data, bss, noptrbss.
+	// In external linking mode, there may be other non-Go data mixed in,
+	// and the sections may even occur out of order.
+	// Work out a conservative range of addresses.
+	start = ~(uintptr)0;
+	end = 0;
+	if(start > (uintptr)runtime·noptrdata)
+		start = (uintptr)runtime·noptrdata;
+	if(start > (uintptr)runtime·data)
+		start = (uintptr)runtime·data;
+	if(start > (uintptr)runtime·noptrbss)
+		start = (uintptr)runtime·noptrbss;
+	if(start > (uintptr)runtime·bss)
+		start = (uintptr)runtime·bss;
+	if(end < (uintptr)runtime·enoptrdata)
+		end = (uintptr)runtime·enoptrdata;
+	if(end < (uintptr)runtime·edata)
+		end = (uintptr)runtime·edata;
+	if(end < (uintptr)runtime·enoptrbss)
+		end = (uintptr)runtime·enoptrbss;
+	if(end < (uintptr)runtime·ebss)
+		end = (uintptr)runtime·ebss;
+	start = start & ~(PageSize-1);
+	size = ROUND(end - start, PageSize);
+	runtime·racecall(__tsan_map_shadow, start, size);
+	runtime·racedatastart = start;
+	runtime·racedataend = start + size;
+	return racectx;
+}
+
+#pragma textflag NOSPLIT
+void
+runtime·racefini(void)
+{
+	runtime·racecall(__tsan_fini);
+}
+
+#pragma textflag NOSPLIT
+void
+runtime·racemapshadow(void *addr, uintptr size)
+{
+	if(runtime·racearenastart == 0)
+		runtime·racearenastart = (uintptr)addr;
+	if(runtime·racearenaend < (uintptr)addr+size)
+		runtime·racearenaend = (uintptr)addr+size;
+	runtime·racecall(__tsan_map_shadow, addr, size);
+}
+
+#pragma textflag NOSPLIT
+void
+runtime·racemalloc(void *p, uintptr sz)
+{
+	runtime·racecall(__tsan_malloc, p, sz);
+}
+
+#pragma textflag NOSPLIT
+uintptr
+runtime·racegostart(void *pc)
+{
+	uintptr racectx;
+	G *spawng;
+
+	if(g->m->curg != nil)
+		spawng = g->m->curg;
+	else
+		spawng = g;
+
+	runtime·racecall(__tsan_go_start, spawng->racectx, &racectx, pc);
+	return racectx;
+}
+
+#pragma textflag NOSPLIT
+void
+runtime·racegoend(void)
+{
+	runtime·racecall(__tsan_go_end, g->racectx);
+}
+
+#pragma textflag NOSPLIT
+void
+runtime·racewriterangepc(void *addr, uintptr sz, void *callpc, void *pc)
+{
+	if(g != g->m->curg) {
+		// The call is coming from manual instrumentation of Go code running on g0/gsignal.
+		// Not interesting.
+		return;
+	}
+	if(callpc != nil)
+		runtime·racefuncenter(callpc);
+	runtime·racewriterangepc1(addr, sz, pc);
+	if(callpc != nil)
+		runtime·racefuncexit();
+}
+
+#pragma textflag NOSPLIT
+void
+runtime·racereadrangepc(void *addr, uintptr sz, void *callpc, void *pc)
+{
+	if(g != g->m->curg) {
+		// The call is coming from manual instrumentation of Go code running on g0/gsignal.
+		// Not interesting.
+		return;
+	}
+	if(callpc != nil)
+		runtime·racefuncenter(callpc);
+	runtime·racereadrangepc1(addr, sz, pc);
+	if(callpc != nil)
+		runtime·racefuncexit();
+}
+
+#pragma textflag NOSPLIT
+void
+runtime·racewriteobjectpc(void *addr, Type *t, void *callpc, void *pc)
+{
+	uint8 kind;
+
+	kind = t->kind & KindMask;
+	if(kind == KindArray || kind == KindStruct)
+		runtime·racewriterangepc(addr, t->size, callpc, pc);
+	else
+		runtime·racewritepc(addr, callpc, pc);
+}
+
+#pragma textflag NOSPLIT
+void
+runtime·racereadobjectpc(void *addr, Type *t, void *callpc, void *pc)
+{
+	uint8 kind;
+
+	kind = t->kind & KindMask;
+	if(kind == KindArray || kind == KindStruct)
+		runtime·racereadrangepc(addr, t->size, callpc, pc);
+	else
+		runtime·racereadpc(addr, callpc, pc);
+}
+
+#pragma textflag NOSPLIT
+void
+runtime·raceacquire(void *addr)
+{
+	runtime·raceacquireg(g, addr);
+}
+
+#pragma textflag NOSPLIT
+void
+runtime·raceacquireg(G *gp, void *addr)
+{
+	if(g->raceignore || !isvalidaddr((uintptr)addr))
+		return;
+	runtime·racecall(__tsan_acquire, gp->racectx, addr);
+}
+
+#pragma textflag NOSPLIT
+void
+runtime·racerelease(void *addr)
+{
+	if(g->raceignore || !isvalidaddr((uintptr)addr))
+		return;
+	runtime·racereleaseg(g, addr);
+}
+
+#pragma textflag NOSPLIT
+void
+runtime·racereleaseg(G *gp, void *addr)
+{
+	if(g->raceignore || !isvalidaddr((uintptr)addr))
+		return;
+	runtime·racecall(__tsan_release, gp->racectx, addr);
+}
+
+#pragma textflag NOSPLIT
+void
+runtime·racereleasemerge(void *addr)
+{
+	runtime·racereleasemergeg(g, addr);
+}
+
+#pragma textflag NOSPLIT
+void
+runtime·racereleasemergeg(G *gp, void *addr)
+{
+	if(g->raceignore || !isvalidaddr((uintptr)addr))
+		return;
+	runtime·racecall(__tsan_release_merge, gp->racectx, addr);
+}
+
+#pragma textflag NOSPLIT
+void
+runtime·racefingo(void)
+{
+	runtime·racecall(__tsan_finalizer_goroutine, g->racectx);
+}
+
+// func RaceAcquire(addr unsafe.Pointer)
+#pragma textflag NOSPLIT
+void
+runtime·RaceAcquire(void *addr)
+{
+	runtime·raceacquire(addr);
+}
+
+// func RaceRelease(addr unsafe.Pointer)
+#pragma textflag NOSPLIT
+void
+runtime·RaceRelease(void *addr)
+{
+	runtime·racerelease(addr);
+}
+
+// func RaceReleaseMerge(addr unsafe.Pointer)
+#pragma textflag NOSPLIT
+void
+runtime·RaceReleaseMerge(void *addr)
+{
+	runtime·racereleasemerge(addr);
+}
+
+// func RaceDisable()
+#pragma textflag NOSPLIT
+void
+runtime·RaceDisable(void)
+{
+	if(g->raceignore++ == 0)
+		runtime·racecall(__tsan_go_ignore_sync_begin, g->racectx);
+}
+
+// func RaceEnable()
+#pragma textflag NOSPLIT
+void
+runtime·RaceEnable(void)
+{
+	if(--g->raceignore == 0)
+		runtime·racecall(__tsan_go_ignore_sync_end, g->racectx);
+}
diff --git a/src/runtime/race.go b/src/runtime/race.go
new file mode 100644
index 0000000..bb0ee6d
--- /dev/null
+++ b/src/runtime/race.go
@@ -0,0 +1,127 @@
+// Copyright 2012 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build race
+
+// Public race detection API, present iff build with -race.
+
+package runtime
+
+import (
+	"unsafe"
+)
+
+func racefini()
+
+// RaceDisable disables handling of race events in the current goroutine.
+func RaceDisable()
+
+// RaceEnable re-enables handling of race events in the current goroutine.
+func RaceEnable()
+
+func RaceAcquire(addr unsafe.Pointer)
+func RaceRelease(addr unsafe.Pointer)
+func RaceReleaseMerge(addr unsafe.Pointer)
+
+func RaceRead(addr unsafe.Pointer)
+func RaceWrite(addr unsafe.Pointer)
+func RaceReadRange(addr unsafe.Pointer, len int)
+func RaceWriteRange(addr unsafe.Pointer, len int)
+
+func RaceSemacquire(s *uint32)
+func RaceSemrelease(s *uint32)
+
+// private interface for the runtime
+const raceenabled = true
+
+func raceReadObjectPC(t *_type, addr unsafe.Pointer, callerpc, pc uintptr) {
+	kind := t.kind & kindMask
+	if kind == kindArray || kind == kindStruct {
+		// for composite objects we have to read every address
+		// because a write might happen to any subobject.
+		racereadrangepc(addr, t.size, callerpc, pc)
+	} else {
+		// for non-composite objects we can read just the start
+		// address, as any write must write the first byte.
+		racereadpc(addr, callerpc, pc)
+	}
+}
+
+func raceWriteObjectPC(t *_type, addr unsafe.Pointer, callerpc, pc uintptr) {
+	kind := t.kind & kindMask
+	if kind == kindArray || kind == kindStruct {
+		// for composite objects we have to write every address
+		// because a write might happen to any subobject.
+		racewriterangepc(addr, t.size, callerpc, pc)
+	} else {
+		// for non-composite objects we can write just the start
+		// address, as any write must write the first byte.
+		racewritepc(addr, callerpc, pc)
+	}
+}
+
+//go:noescape
+func racereadpc(addr unsafe.Pointer, callpc, pc uintptr)
+
+//go:noescape
+func racewritepc(addr unsafe.Pointer, callpc, pc uintptr)
+
+//go:noescape
+func racereadrangepc(addr unsafe.Pointer, len uintptr, callpc, pc uintptr)
+
+//go:noescape
+func racewriterangepc(addr unsafe.Pointer, len uintptr, callpc, pc uintptr)
+
+//go:noescape
+func raceacquire(addr unsafe.Pointer)
+
+//go:noescape
+func racerelease(addr unsafe.Pointer)
+
+//go:noescape
+func raceacquireg(gp *g, addr unsafe.Pointer)
+
+//go:noescape
+func racereleaseg(gp *g, addr unsafe.Pointer)
+
+func racefingo()
+
+//go:noescape
+func racemalloc(p unsafe.Pointer, size uintptr)
+
+//go:noescape
+func racereleasemerge(addr unsafe.Pointer)
+
+type symbolizeContext struct {
+	pc   uintptr
+	fn   *byte
+	file *byte
+	line uintptr
+	off  uintptr
+	res  uintptr
+}
+
+var qq = [...]byte{'?', '?', 0}
+var dash = [...]byte{'-', 0}
+
+// Callback from C into Go, runs on g0.
+func racesymbolize(ctx *symbolizeContext) {
+	f := findfunc(ctx.pc)
+	if f == nil {
+		ctx.fn = &qq[0]
+		ctx.file = &dash[0]
+		ctx.line = 0
+		ctx.off = ctx.pc
+		ctx.res = 1
+		return
+	}
+
+	ctx.fn = funcname(f)
+	var file string
+	ctx.line = uintptr(funcline(f, ctx.pc, &file))
+	ctx.file = &bytes(file)[0] // assume NUL-terminated
+	ctx.off = ctx.pc - f.entry
+	ctx.res = 1
+	return
+}
diff --git a/src/pkg/runtime/race.h b/src/runtime/race.h
similarity index 100%
rename from src/pkg/runtime/race.h
rename to src/runtime/race.h
diff --git a/src/runtime/race/README b/src/runtime/race/README
new file mode 100644
index 0000000..7f18535
--- /dev/null
+++ b/src/runtime/race/README
@@ -0,0 +1,12 @@
+runtime/race package contains the data race detector runtime library.
+It is based on ThreadSanitizer race detector, that is currently a part of
+the LLVM project.
+
+To update the .syso files you need to:
+$ svn co http://llvm.org/svn/llvm-project/compiler-rt/trunk
+$ cd compiler-rt/lib/tsan/go
+$ ./buildgo.sh
+
+Tested with gcc 4.6.1 and 4.7.0.  On Windows it's built with 64-bit MinGW.
+
+Current runtime is built on rev 215000.
diff --git a/src/pkg/runtime/race/doc.go b/src/runtime/race/doc.go
similarity index 100%
rename from src/pkg/runtime/race/doc.go
rename to src/runtime/race/doc.go
diff --git a/src/pkg/runtime/race/output_test.go b/src/runtime/race/output_test.go
similarity index 100%
rename from src/pkg/runtime/race/output_test.go
rename to src/runtime/race/output_test.go
diff --git a/src/runtime/race/race.go b/src/runtime/race/race.go
new file mode 100644
index 0000000..31deedd
--- /dev/null
+++ b/src/runtime/race/race.go
@@ -0,0 +1,15 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build race,linux,amd64 race,freebsd,amd64 race,darwin,amd64 race,windows,amd64
+
+package race
+
+// This file merely ensures that we link in runtime/cgo in race build,
+// this is turn ensures that runtime uses pthread_create to create threads.
+// The prebuilt race runtime lives in race_GOOS_GOARCH.syso.
+// Calls to the runtime are done directly from src/runtime/race.c.
+
+// void __race_unused_func(void);
+import "C"
diff --git a/src/runtime/race/race_darwin_amd64.syso b/src/runtime/race/race_darwin_amd64.syso
new file mode 100644
index 0000000..81b48c6
Binary files /dev/null and b/src/runtime/race/race_darwin_amd64.syso differ
diff --git a/src/runtime/race/race_freebsd_amd64.syso b/src/runtime/race/race_freebsd_amd64.syso
new file mode 100644
index 0000000..5bbe322
Binary files /dev/null and b/src/runtime/race/race_freebsd_amd64.syso differ
diff --git a/src/runtime/race/race_linux_amd64.syso b/src/runtime/race/race_linux_amd64.syso
new file mode 100644
index 0000000..49bf08e
Binary files /dev/null and b/src/runtime/race/race_linux_amd64.syso differ
diff --git a/src/pkg/runtime/race/race_test.go b/src/runtime/race/race_test.go
similarity index 100%
rename from src/pkg/runtime/race/race_test.go
rename to src/runtime/race/race_test.go
diff --git a/src/runtime/race/race_unix_test.go b/src/runtime/race/race_unix_test.go
new file mode 100644
index 0000000..84f0ace
--- /dev/null
+++ b/src/runtime/race/race_unix_test.go
@@ -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.
+
+// +build race
+// +build darwin freebsd linux
+
+package race_test
+
+import (
+	"sync/atomic"
+	"syscall"
+	"testing"
+	"unsafe"
+)
+
+// Test that race detector does not crash when accessing non-Go allocated memory (issue 9136).
+func TestNonGoMemory(t *testing.T) {
+	data, err := syscall.Mmap(-1, 0, 4096, syscall.PROT_READ|syscall.PROT_WRITE, syscall.MAP_ANON|syscall.MAP_PRIVATE)
+	if err != nil {
+		t.Fatalf("failed to mmap memory: %v", err)
+	}
+	p := (*uint32)(unsafe.Pointer(&data[0]))
+	atomic.AddUint32(p, 1)
+	(*p)++
+	if *p != 2 {
+		t.Fatalf("data[0] = %v, expect 2", *p)
+	}
+	syscall.Munmap(data)
+}
diff --git a/src/runtime/race/race_windows_amd64.syso b/src/runtime/race/race_windows_amd64.syso
new file mode 100644
index 0000000..a4eae9b
Binary files /dev/null and b/src/runtime/race/race_windows_amd64.syso differ
diff --git a/src/runtime/race/testdata/atomic_test.go b/src/runtime/race/testdata/atomic_test.go
new file mode 100644
index 0000000..232744b
--- /dev/null
+++ b/src/runtime/race/testdata/atomic_test.go
@@ -0,0 +1,288 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package race_test
+
+import (
+	"runtime"
+	"sync"
+	"sync/atomic"
+	"testing"
+	"unsafe"
+)
+
+func TestNoRaceAtomicAddInt64(t *testing.T) {
+	var x1, x2 int8
+	var s int64
+	ch := make(chan bool, 2)
+	go func() {
+		x1 = 1
+		if atomic.AddInt64(&s, 1) == 2 {
+			x2 = 1
+		}
+		ch <- true
+	}()
+	go func() {
+		x2 = 1
+		if atomic.AddInt64(&s, 1) == 2 {
+			x1 = 1
+		}
+		ch <- true
+	}()
+	<-ch
+	<-ch
+}
+
+func TestRaceAtomicAddInt64(t *testing.T) {
+	var x1, x2 int8
+	var s int64
+	ch := make(chan bool, 2)
+	go func() {
+		x1 = 1
+		if atomic.AddInt64(&s, 1) == 1 {
+			x2 = 1
+		}
+		ch <- true
+	}()
+	go func() {
+		x2 = 1
+		if atomic.AddInt64(&s, 1) == 1 {
+			x1 = 1
+		}
+		ch <- true
+	}()
+	<-ch
+	<-ch
+}
+
+func TestNoRaceAtomicAddInt32(t *testing.T) {
+	var x1, x2 int8
+	var s int32
+	ch := make(chan bool, 2)
+	go func() {
+		x1 = 1
+		if atomic.AddInt32(&s, 1) == 2 {
+			x2 = 1
+		}
+		ch <- true
+	}()
+	go func() {
+		x2 = 1
+		if atomic.AddInt32(&s, 1) == 2 {
+			x1 = 1
+		}
+		ch <- true
+	}()
+	<-ch
+	<-ch
+}
+
+func TestNoRaceAtomicLoadAddInt32(t *testing.T) {
+	var x int64
+	var s int32
+	go func() {
+		x = 2
+		atomic.AddInt32(&s, 1)
+	}()
+	for atomic.LoadInt32(&s) != 1 {
+		runtime.Gosched()
+	}
+	x = 1
+}
+
+func TestNoRaceAtomicLoadStoreInt32(t *testing.T) {
+	var x int64
+	var s int32
+	go func() {
+		x = 2
+		atomic.StoreInt32(&s, 1)
+	}()
+	for atomic.LoadInt32(&s) != 1 {
+		runtime.Gosched()
+	}
+	x = 1
+}
+
+func TestNoRaceAtomicStoreCASInt32(t *testing.T) {
+	var x int64
+	var s int32
+	go func() {
+		x = 2
+		atomic.StoreInt32(&s, 1)
+	}()
+	for !atomic.CompareAndSwapInt32(&s, 1, 0) {
+		runtime.Gosched()
+	}
+	x = 1
+}
+
+func TestNoRaceAtomicCASLoadInt32(t *testing.T) {
+	var x int64
+	var s int32
+	go func() {
+		x = 2
+		if !atomic.CompareAndSwapInt32(&s, 0, 1) {
+			panic("")
+		}
+	}()
+	for atomic.LoadInt32(&s) != 1 {
+		runtime.Gosched()
+	}
+	x = 1
+}
+
+func TestNoRaceAtomicCASCASInt32(t *testing.T) {
+	var x int64
+	var s int32
+	go func() {
+		x = 2
+		if !atomic.CompareAndSwapInt32(&s, 0, 1) {
+			panic("")
+		}
+	}()
+	for !atomic.CompareAndSwapInt32(&s, 1, 0) {
+		runtime.Gosched()
+	}
+	x = 1
+}
+
+func TestNoRaceAtomicCASCASInt32_2(t *testing.T) {
+	var x1, x2 int8
+	var s int32
+	ch := make(chan bool, 2)
+	go func() {
+		x1 = 1
+		if !atomic.CompareAndSwapInt32(&s, 0, 1) {
+			x2 = 1
+		}
+		ch <- true
+	}()
+	go func() {
+		x2 = 1
+		if !atomic.CompareAndSwapInt32(&s, 0, 1) {
+			x1 = 1
+		}
+		ch <- true
+	}()
+	<-ch
+	<-ch
+}
+
+func TestNoRaceAtomicLoadInt64(t *testing.T) {
+	var x int32
+	var s int64
+	go func() {
+		x = 2
+		atomic.AddInt64(&s, 1)
+	}()
+	for atomic.LoadInt64(&s) != 1 {
+		runtime.Gosched()
+	}
+	x = 1
+}
+
+func TestNoRaceAtomicCASCASUInt64(t *testing.T) {
+	var x int64
+	var s uint64
+	go func() {
+		x = 2
+		if !atomic.CompareAndSwapUint64(&s, 0, 1) {
+			panic("")
+		}
+	}()
+	for !atomic.CompareAndSwapUint64(&s, 1, 0) {
+		runtime.Gosched()
+	}
+	x = 1
+}
+
+func TestNoRaceAtomicLoadStorePointer(t *testing.T) {
+	var x int64
+	var s unsafe.Pointer
+	var y int = 2
+	var p unsafe.Pointer = unsafe.Pointer(&y)
+	go func() {
+		x = 2
+		atomic.StorePointer(&s, p)
+	}()
+	for atomic.LoadPointer(&s) != p {
+		runtime.Gosched()
+	}
+	x = 1
+}
+
+func TestNoRaceAtomicStoreCASUint64(t *testing.T) {
+	var x int64
+	var s uint64
+	go func() {
+		x = 2
+		atomic.StoreUint64(&s, 1)
+	}()
+	for !atomic.CompareAndSwapUint64(&s, 1, 0) {
+		runtime.Gosched()
+	}
+	x = 1
+}
+
+func TestRaceAtomicStoreLoad(t *testing.T) {
+	c := make(chan bool)
+	var a uint64
+	go func() {
+		atomic.StoreUint64(&a, 1)
+		c <- true
+	}()
+	_ = a
+	<-c
+}
+
+func TestRaceAtomicLoadStore(t *testing.T) {
+	c := make(chan bool)
+	var a uint64
+	go func() {
+		_ = atomic.LoadUint64(&a)
+		c <- true
+	}()
+	a = 1
+	<-c
+}
+
+func TestRaceAtomicAddLoad(t *testing.T) {
+	c := make(chan bool)
+	var a uint64
+	go func() {
+		atomic.AddUint64(&a, 1)
+		c <- true
+	}()
+	_ = a
+	<-c
+}
+
+func TestRaceAtomicAddStore(t *testing.T) {
+	c := make(chan bool)
+	var a uint64
+	go func() {
+		atomic.AddUint64(&a, 1)
+		c <- true
+	}()
+	a = 42
+	<-c
+}
+
+// A nil pointer in an atomic operation should not deadlock
+// the rest of the program. Used to hang indefinitely.
+func TestNoRaceAtomicCrash(t *testing.T) {
+	var mutex sync.Mutex
+	var nilptr *int32
+	panics := 0
+	defer func() {
+		if x := recover(); x != nil {
+			mutex.Lock()
+			panics++
+			mutex.Unlock()
+		} else {
+			panic("no panic")
+		}
+	}()
+	atomic.AddInt32(nilptr, 1)
+}
diff --git a/src/pkg/runtime/race/testdata/cgo_test.go b/src/runtime/race/testdata/cgo_test.go
similarity index 100%
rename from src/pkg/runtime/race/testdata/cgo_test.go
rename to src/runtime/race/testdata/cgo_test.go
diff --git a/src/pkg/runtime/race/testdata/cgo_test_main.go b/src/runtime/race/testdata/cgo_test_main.go
similarity index 100%
rename from src/pkg/runtime/race/testdata/cgo_test_main.go
rename to src/runtime/race/testdata/cgo_test_main.go
diff --git a/src/runtime/race/testdata/chan_test.go b/src/runtime/race/testdata/chan_test.go
new file mode 100644
index 0000000..eabd81f
--- /dev/null
+++ b/src/runtime/race/testdata/chan_test.go
@@ -0,0 +1,659 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package race_test
+
+import (
+	"runtime"
+	"testing"
+	"time"
+)
+
+func TestNoRaceChanSync(t *testing.T) {
+	v := 0
+	c := make(chan int)
+	go func() {
+		v = 1
+		c <- 0
+	}()
+	<-c
+	v = 2
+}
+
+func TestNoRaceChanSyncRev(t *testing.T) {
+	v := 0
+	c := make(chan int)
+	go func() {
+		c <- 0
+		v = 2
+	}()
+	v = 1
+	<-c
+}
+
+func TestNoRaceChanAsync(t *testing.T) {
+	v := 0
+	c := make(chan int, 10)
+	go func() {
+		v = 1
+		c <- 0
+	}()
+	<-c
+	v = 2
+}
+
+func TestRaceChanAsyncRev(t *testing.T) {
+	v := 0
+	c := make(chan int, 10)
+	go func() {
+		c <- 0
+		v = 1
+	}()
+	v = 2
+	<-c
+}
+
+func TestNoRaceChanAsyncCloseRecv(t *testing.T) {
+	v := 0
+	c := make(chan int, 10)
+	go func() {
+		v = 1
+		close(c)
+	}()
+	func() {
+		defer func() {
+			recover()
+			v = 2
+		}()
+		<-c
+	}()
+}
+
+func TestNoRaceChanAsyncCloseRecv2(t *testing.T) {
+	v := 0
+	c := make(chan int, 10)
+	go func() {
+		v = 1
+		close(c)
+	}()
+	_, _ = <-c
+	v = 2
+}
+
+func TestNoRaceChanAsyncCloseRecv3(t *testing.T) {
+	v := 0
+	c := make(chan int, 10)
+	go func() {
+		v = 1
+		close(c)
+	}()
+	for range c {
+	}
+	v = 2
+}
+
+func TestNoRaceChanSyncCloseRecv(t *testing.T) {
+	v := 0
+	c := make(chan int)
+	go func() {
+		v = 1
+		close(c)
+	}()
+	func() {
+		defer func() {
+			recover()
+			v = 2
+		}()
+		<-c
+	}()
+}
+
+func TestNoRaceChanSyncCloseRecv2(t *testing.T) {
+	v := 0
+	c := make(chan int)
+	go func() {
+		v = 1
+		close(c)
+	}()
+	_, _ = <-c
+	v = 2
+}
+
+func TestNoRaceChanSyncCloseRecv3(t *testing.T) {
+	v := 0
+	c := make(chan int)
+	go func() {
+		v = 1
+		close(c)
+	}()
+	for range c {
+	}
+	v = 2
+}
+
+func TestRaceChanSyncCloseSend(t *testing.T) {
+	v := 0
+	c := make(chan int)
+	go func() {
+		v = 1
+		close(c)
+	}()
+	func() {
+		defer func() {
+			recover()
+		}()
+		c <- 0
+	}()
+	v = 2
+}
+
+func TestRaceChanAsyncCloseSend(t *testing.T) {
+	v := 0
+	c := make(chan int, 10)
+	go func() {
+		v = 1
+		close(c)
+	}()
+	func() {
+		defer func() {
+			recover()
+		}()
+		for {
+			c <- 0
+		}
+	}()
+	v = 2
+}
+
+func TestRaceChanCloseClose(t *testing.T) {
+	compl := make(chan bool, 2)
+	v1 := 0
+	v2 := 0
+	c := make(chan int)
+	go func() {
+		defer func() {
+			if recover() != nil {
+				v2 = 2
+			}
+			compl <- true
+		}()
+		v1 = 1
+		close(c)
+	}()
+	go func() {
+		defer func() {
+			if recover() != nil {
+				v1 = 2
+			}
+			compl <- true
+		}()
+		v2 = 1
+		close(c)
+	}()
+	<-compl
+	<-compl
+}
+
+func TestRaceChanSendLen(t *testing.T) {
+	v := 0
+	c := make(chan int, 10)
+	go func() {
+		v = 1
+		c <- 1
+	}()
+	for len(c) == 0 {
+		runtime.Gosched()
+	}
+	v = 2
+}
+
+func TestRaceChanRecvLen(t *testing.T) {
+	v := 0
+	c := make(chan int, 10)
+	c <- 1
+	go func() {
+		v = 1
+		<-c
+	}()
+	for len(c) != 0 {
+		runtime.Gosched()
+	}
+	v = 2
+}
+
+func TestRaceChanSendSend(t *testing.T) {
+	compl := make(chan bool, 2)
+	v1 := 0
+	v2 := 0
+	c := make(chan int, 1)
+	go func() {
+		v1 = 1
+		select {
+		case c <- 1:
+		default:
+			v2 = 2
+		}
+		compl <- true
+	}()
+	go func() {
+		v2 = 1
+		select {
+		case c <- 1:
+		default:
+			v1 = 2
+		}
+		compl <- true
+	}()
+	<-compl
+	<-compl
+}
+
+func TestNoRaceChanPtr(t *testing.T) {
+	type msg struct {
+		x int
+	}
+	c := make(chan *msg)
+	go func() {
+		c <- &msg{1}
+	}()
+	m := <-c
+	m.x = 2
+}
+
+func TestRaceChanWrongSend(t *testing.T) {
+	v1 := 0
+	v2 := 0
+	c := make(chan int, 2)
+	go func() {
+		v1 = 1
+		c <- 1
+	}()
+	go func() {
+		v2 = 2
+		c <- 2
+	}()
+	time.Sleep(1e7)
+	if <-c == 1 {
+		v2 = 3
+	} else {
+		v1 = 3
+	}
+}
+
+func TestRaceChanWrongClose(t *testing.T) {
+	v1 := 0
+	v2 := 0
+	c := make(chan int, 1)
+	go func() {
+		defer func() {
+			recover()
+		}()
+		v1 = 1
+		c <- 1
+	}()
+	go func() {
+		time.Sleep(1e7)
+		v2 = 2
+		close(c)
+	}()
+	time.Sleep(2e7)
+	if _, who := <-c; who {
+		v2 = 2
+	} else {
+		v1 = 2
+	}
+}
+
+func TestRaceChanSendClose(t *testing.T) {
+	compl := make(chan bool, 2)
+	c := make(chan int, 1)
+	go func() {
+		defer func() {
+			recover()
+			compl <- true
+		}()
+		c <- 1
+	}()
+	go func() {
+		time.Sleep(10 * time.Millisecond)
+		close(c)
+		compl <- true
+	}()
+	<-compl
+	<-compl
+}
+
+func TestRaceChanSendSelectClose(t *testing.T) {
+	compl := make(chan bool, 2)
+	c := make(chan int, 1)
+	c1 := make(chan int)
+	go func() {
+		defer func() {
+			recover()
+			compl <- true
+		}()
+		time.Sleep(10 * time.Millisecond)
+		select {
+		case c <- 1:
+		case <-c1:
+		}
+	}()
+	go func() {
+		close(c)
+		compl <- true
+	}()
+	<-compl
+	<-compl
+}
+
+func TestRaceSelectReadWriteAsync(t *testing.T) {
+	done := make(chan bool)
+	x := 0
+	c1 := make(chan int, 10)
+	c2 := make(chan int, 10)
+	c3 := make(chan int)
+	c2 <- 1
+	go func() {
+		select {
+		case c1 <- x: // read of x races with...
+		case c3 <- 1:
+		}
+		done <- true
+	}()
+	select {
+	case x = <-c2: // ... write to x here
+	case c3 <- 1:
+	}
+	<-done
+}
+
+func TestRaceSelectReadWriteSync(t *testing.T) {
+	done := make(chan bool)
+	x := 0
+	c1 := make(chan int)
+	c2 := make(chan int)
+	c3 := make(chan int)
+	// make c1 and c2 ready for communication
+	go func() {
+		<-c1
+	}()
+	go func() {
+		c2 <- 1
+	}()
+	go func() {
+		select {
+		case c1 <- x: // read of x races with...
+		case c3 <- 1:
+		}
+		done <- true
+	}()
+	select {
+	case x = <-c2: // ... write to x here
+	case c3 <- 1:
+	}
+	<-done
+}
+
+func TestNoRaceSelectReadWriteAsync(t *testing.T) {
+	done := make(chan bool)
+	x := 0
+	c1 := make(chan int)
+	c2 := make(chan int)
+	go func() {
+		select {
+		case c1 <- x: // read of x does not race with...
+		case c2 <- 1:
+		}
+		done <- true
+	}()
+	select {
+	case x = <-c1: // ... write to x here
+	case c2 <- 1:
+	}
+	<-done
+}
+
+func TestRaceChanReadWriteAsync(t *testing.T) {
+	done := make(chan bool)
+	c1 := make(chan int, 10)
+	c2 := make(chan int, 10)
+	c2 <- 10
+	x := 0
+	go func() {
+		c1 <- x // read of x races with...
+		done <- true
+	}()
+	x = <-c2 // ... write to x here
+	<-done
+}
+
+func TestRaceChanReadWriteSync(t *testing.T) {
+	done := make(chan bool)
+	c1 := make(chan int)
+	c2 := make(chan int)
+	// make c1 and c2 ready for communication
+	go func() {
+		<-c1
+	}()
+	go func() {
+		c2 <- 10
+	}()
+	x := 0
+	go func() {
+		c1 <- x // read of x races with...
+		done <- true
+	}()
+	x = <-c2 // ... write to x here
+	<-done
+}
+
+func TestNoRaceChanReadWriteAsync(t *testing.T) {
+	done := make(chan bool)
+	c1 := make(chan int, 10)
+	x := 0
+	go func() {
+		c1 <- x // read of x does not race with...
+		done <- true
+	}()
+	x = <-c1 // ... write to x here
+	<-done
+}
+
+func TestNoRaceProducerConsumerUnbuffered(t *testing.T) {
+	type Task struct {
+		f    func()
+		done chan bool
+	}
+
+	queue := make(chan Task)
+
+	go func() {
+		t := <-queue
+		t.f()
+		t.done <- true
+	}()
+
+	doit := func(f func()) {
+		done := make(chan bool, 1)
+		queue <- Task{f, done}
+		<-done
+	}
+
+	x := 0
+	doit(func() {
+		x = 1
+	})
+	_ = x
+}
+
+func TestRaceChanItselfSend(t *testing.T) {
+	compl := make(chan bool, 1)
+	c := make(chan int, 10)
+	go func() {
+		c <- 0
+		compl <- true
+	}()
+	c = make(chan int, 20)
+	<-compl
+}
+
+func TestRaceChanItselfRecv(t *testing.T) {
+	compl := make(chan bool, 1)
+	c := make(chan int, 10)
+	c <- 1
+	go func() {
+		<-c
+		compl <- true
+	}()
+	time.Sleep(1e7)
+	c = make(chan int, 20)
+	<-compl
+}
+
+func TestRaceChanItselfNil(t *testing.T) {
+	c := make(chan int, 10)
+	go func() {
+		c <- 0
+	}()
+	time.Sleep(1e7)
+	c = nil
+	_ = c
+}
+
+func TestRaceChanItselfClose(t *testing.T) {
+	compl := make(chan bool, 1)
+	c := make(chan int)
+	go func() {
+		close(c)
+		compl <- true
+	}()
+	c = make(chan int)
+	<-compl
+}
+
+func TestRaceChanItselfLen(t *testing.T) {
+	compl := make(chan bool, 1)
+	c := make(chan int)
+	go func() {
+		_ = len(c)
+		compl <- true
+	}()
+	c = make(chan int)
+	<-compl
+}
+
+func TestRaceChanItselfCap(t *testing.T) {
+	compl := make(chan bool, 1)
+	c := make(chan int)
+	go func() {
+		_ = cap(c)
+		compl <- true
+	}()
+	c = make(chan int)
+	<-compl
+}
+
+func TestRaceChanCloseLen(t *testing.T) {
+	v := 0
+	c := make(chan int, 10)
+	c <- 0
+	go func() {
+		v = 1
+		close(c)
+	}()
+	time.Sleep(1e7)
+	_ = len(c)
+	v = 2
+}
+
+func TestRaceChanCloseSend(t *testing.T) {
+	compl := make(chan bool, 1)
+	c := make(chan int, 10)
+	go func() {
+		close(c)
+		compl <- true
+	}()
+	c <- 0
+	<-compl
+}
+
+func TestNoRaceChanMutex(t *testing.T) {
+	done := make(chan struct{})
+	mtx := make(chan struct{}, 1)
+	data := 0
+	go func() {
+		mtx <- struct{}{}
+		data = 42
+		<-mtx
+		done <- struct{}{}
+	}()
+	mtx <- struct{}{}
+	data = 43
+	<-mtx
+	<-done
+}
+
+func TestNoRaceSelectMutex(t *testing.T) {
+	done := make(chan struct{})
+	mtx := make(chan struct{}, 1)
+	aux := make(chan bool)
+	data := 0
+	go func() {
+		select {
+		case mtx <- struct{}{}:
+		case <-aux:
+		}
+		data = 42
+		select {
+		case <-mtx:
+		case <-aux:
+		}
+		done <- struct{}{}
+	}()
+	select {
+	case mtx <- struct{}{}:
+	case <-aux:
+	}
+	data = 43
+	select {
+	case <-mtx:
+	case <-aux:
+	}
+	<-done
+}
+
+func TestRaceChanSem(t *testing.T) {
+	done := make(chan struct{})
+	mtx := make(chan bool, 2)
+	data := 0
+	go func() {
+		mtx <- true
+		data = 42
+		<-mtx
+		done <- struct{}{}
+	}()
+	mtx <- true
+	data = 43
+	<-mtx
+	<-done
+}
+
+func TestNoRaceChanWaitGroup(t *testing.T) {
+	const N = 10
+	chanWg := make(chan bool, N/2)
+	data := make([]int, N)
+	for i := 0; i < N; i++ {
+		chanWg <- true
+		go func(i int) {
+			data[i] = 42
+			<-chanWg
+		}(i)
+	}
+	for i := 0; i < cap(chanWg); i++ {
+		chanWg <- true
+	}
+	for i := 0; i < N; i++ {
+		_ = data[i]
+	}
+}
diff --git a/src/pkg/runtime/race/testdata/comp_test.go b/src/runtime/race/testdata/comp_test.go
similarity index 100%
rename from src/pkg/runtime/race/testdata/comp_test.go
rename to src/runtime/race/testdata/comp_test.go
diff --git a/src/pkg/runtime/race/testdata/finalizer_test.go b/src/runtime/race/testdata/finalizer_test.go
similarity index 100%
rename from src/pkg/runtime/race/testdata/finalizer_test.go
rename to src/runtime/race/testdata/finalizer_test.go
diff --git a/src/pkg/runtime/race/testdata/io_test.go b/src/runtime/race/testdata/io_test.go
similarity index 100%
rename from src/pkg/runtime/race/testdata/io_test.go
rename to src/runtime/race/testdata/io_test.go
diff --git a/src/runtime/race/testdata/map_test.go b/src/runtime/race/testdata/map_test.go
new file mode 100644
index 0000000..a8d8148
--- /dev/null
+++ b/src/runtime/race/testdata/map_test.go
@@ -0,0 +1,333 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package race_test
+
+import (
+	"testing"
+)
+
+func TestRaceMapRW(t *testing.T) {
+	m := make(map[int]int)
+	ch := make(chan bool, 1)
+	go func() {
+		_ = m[1]
+		ch <- true
+	}()
+	m[1] = 1
+	<-ch
+}
+
+func TestRaceMapRW2(t *testing.T) {
+	m := make(map[int]int)
+	ch := make(chan bool, 1)
+	go func() {
+		_, _ = m[1]
+		ch <- true
+	}()
+	m[1] = 1
+	<-ch
+}
+
+func TestRaceMapRWArray(t *testing.T) {
+	// Check instrumentation of unaddressable arrays (issue 4578).
+	m := make(map[int][2]int)
+	ch := make(chan bool, 1)
+	go func() {
+		_ = m[1][1]
+		ch <- true
+	}()
+	m[2] = [2]int{1, 2}
+	<-ch
+}
+
+func TestNoRaceMapRR(t *testing.T) {
+	m := make(map[int]int)
+	ch := make(chan bool, 1)
+	go func() {
+		_, _ = m[1]
+		ch <- true
+	}()
+	_ = m[1]
+	<-ch
+}
+
+func TestRaceMapRange(t *testing.T) {
+	m := make(map[int]int)
+	ch := make(chan bool, 1)
+	go func() {
+		for range m {
+		}
+		ch <- true
+	}()
+	m[1] = 1
+	<-ch
+}
+
+func TestRaceMapRange2(t *testing.T) {
+	m := make(map[int]int)
+	ch := make(chan bool, 1)
+	go func() {
+		for range m {
+		}
+		ch <- true
+	}()
+	m[1] = 1
+	<-ch
+}
+
+func TestNoRaceMapRangeRange(t *testing.T) {
+	m := make(map[int]int)
+	// now the map is not empty and range triggers an event
+	// should work without this (as in other tests)
+	// so it is suspicious if this test passes and others don't
+	m[0] = 0
+	ch := make(chan bool, 1)
+	go func() {
+		for range m {
+		}
+		ch <- true
+	}()
+	for range m {
+	}
+	<-ch
+}
+
+func TestRaceMapLen(t *testing.T) {
+	m := make(map[string]bool)
+	ch := make(chan bool, 1)
+	go func() {
+		_ = len(m)
+		ch <- true
+	}()
+	m[""] = true
+	<-ch
+}
+
+func TestRaceMapDelete(t *testing.T) {
+	m := make(map[string]bool)
+	ch := make(chan bool, 1)
+	go func() {
+		delete(m, "")
+		ch <- true
+	}()
+	m[""] = true
+	<-ch
+}
+
+func TestRaceMapLenDelete(t *testing.T) {
+	m := make(map[string]bool)
+	ch := make(chan bool, 1)
+	go func() {
+		delete(m, "a")
+		ch <- true
+	}()
+	_ = len(m)
+	<-ch
+}
+
+func TestRaceMapVariable(t *testing.T) {
+	ch := make(chan bool, 1)
+	m := make(map[int]int)
+	go func() {
+		m = make(map[int]int)
+		ch <- true
+	}()
+	m = make(map[int]int)
+	<-ch
+}
+
+func TestRaceMapVariable2(t *testing.T) {
+	ch := make(chan bool, 1)
+	m := make(map[int]int)
+	go func() {
+		m[1] = 1
+		ch <- true
+	}()
+	m = make(map[int]int)
+	<-ch
+}
+
+func TestRaceMapVariable3(t *testing.T) {
+	ch := make(chan bool, 1)
+	m := make(map[int]int)
+	go func() {
+		_ = m[1]
+		ch <- true
+	}()
+	m = make(map[int]int)
+	<-ch
+}
+
+type Big struct {
+	x [17]int32
+}
+
+func TestRaceMapLookupPartKey(t *testing.T) {
+	k := &Big{}
+	m := make(map[Big]bool)
+	ch := make(chan bool, 1)
+	go func() {
+		k.x[8] = 1
+		ch <- true
+	}()
+	_ = m[*k]
+	<-ch
+}
+
+func TestRaceMapLookupPartKey2(t *testing.T) {
+	k := &Big{}
+	m := make(map[Big]bool)
+	ch := make(chan bool, 1)
+	go func() {
+		k.x[8] = 1
+		ch <- true
+	}()
+	_, _ = m[*k]
+	<-ch
+}
+func TestRaceMapDeletePartKey(t *testing.T) {
+	k := &Big{}
+	m := make(map[Big]bool)
+	ch := make(chan bool, 1)
+	go func() {
+		k.x[8] = 1
+		ch <- true
+	}()
+	delete(m, *k)
+	<-ch
+}
+
+func TestRaceMapInsertPartKey(t *testing.T) {
+	k := &Big{}
+	m := make(map[Big]bool)
+	ch := make(chan bool, 1)
+	go func() {
+		k.x[8] = 1
+		ch <- true
+	}()
+	m[*k] = true
+	<-ch
+}
+
+func TestRaceMapInsertPartVal(t *testing.T) {
+	v := &Big{}
+	m := make(map[int]Big)
+	ch := make(chan bool, 1)
+	go func() {
+		v.x[8] = 1
+		ch <- true
+	}()
+	m[1] = *v
+	<-ch
+}
+
+// Test for issue 7561.
+func TestRaceMapAssignMultipleReturn(t *testing.T) {
+	connect := func() (int, error) { return 42, nil }
+	conns := make(map[int][]int)
+	conns[1] = []int{0}
+	ch := make(chan bool, 1)
+	var err error
+	go func() {
+		conns[1][0], err = connect()
+		ch <- true
+	}()
+	x := conns[1][0]
+	_ = x
+	<-ch
+}
+
+// BigKey and BigVal must be larger than 256 bytes,
+// so that compiler sets KindGCProg for them.
+type BigKey [1000]*int
+
+type BigVal struct {
+	x int
+	y [1000]*int
+}
+
+func TestRaceMapBigKeyAccess1(t *testing.T) {
+	m := make(map[BigKey]int)
+	var k BigKey
+	ch := make(chan bool, 1)
+	go func() {
+		_ = m[k]
+		ch <- true
+	}()
+	k[30] = new(int)
+	<-ch
+}
+
+func TestRaceMapBigKeyAccess2(t *testing.T) {
+	m := make(map[BigKey]int)
+	var k BigKey
+	ch := make(chan bool, 1)
+	go func() {
+		_, _ = m[k]
+		ch <- true
+	}()
+	k[30] = new(int)
+	<-ch
+}
+
+func TestRaceMapBigKeyInsert(t *testing.T) {
+	m := make(map[BigKey]int)
+	var k BigKey
+	ch := make(chan bool, 1)
+	go func() {
+		m[k] = 1
+		ch <- true
+	}()
+	k[30] = new(int)
+	<-ch
+}
+
+func TestRaceMapBigKeyDelete(t *testing.T) {
+	m := make(map[BigKey]int)
+	var k BigKey
+	ch := make(chan bool, 1)
+	go func() {
+		delete(m, k)
+		ch <- true
+	}()
+	k[30] = new(int)
+	<-ch
+}
+
+func TestRaceMapBigValInsert(t *testing.T) {
+	m := make(map[int]BigVal)
+	var v BigVal
+	ch := make(chan bool, 1)
+	go func() {
+		m[1] = v
+		ch <- true
+	}()
+	v.y[30] = new(int)
+	<-ch
+}
+
+func TestRaceMapBigValAccess1(t *testing.T) {
+	m := make(map[int]BigVal)
+	var v BigVal
+	ch := make(chan bool, 1)
+	go func() {
+		v = m[1]
+		ch <- true
+	}()
+	v.y[30] = new(int)
+	<-ch
+}
+
+func TestRaceMapBigValAccess2(t *testing.T) {
+	m := make(map[int]BigVal)
+	var v BigVal
+	ch := make(chan bool, 1)
+	go func() {
+		v, _ = m[1]
+		ch <- true
+	}()
+	v.y[30] = new(int)
+	<-ch
+}
diff --git a/src/runtime/race/testdata/mop_test.go b/src/runtime/race/testdata/mop_test.go
new file mode 100644
index 0000000..cb17a27
--- /dev/null
+++ b/src/runtime/race/testdata/mop_test.go
@@ -0,0 +1,1957 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package race_test
+
+import (
+	"bytes"
+	"crypto/sha1"
+	"errors"
+	"fmt"
+	"io"
+	"os"
+	"runtime"
+	"sync"
+	"testing"
+	"time"
+	"unsafe"
+)
+
+type Point struct {
+	x, y int
+}
+
+type NamedPoint struct {
+	name string
+	p    Point
+}
+
+type DummyWriter struct {
+	state int
+}
+type Writer interface {
+	Write(p []byte) (n int)
+}
+
+func (d DummyWriter) Write(p []byte) (n int) {
+	return 0
+}
+
+var GlobalX, GlobalY int = 0, 0
+var GlobalCh chan int = make(chan int, 2)
+
+func GlobalFunc1() {
+	GlobalY = GlobalX
+	GlobalCh <- 1
+}
+
+func GlobalFunc2() {
+	GlobalX = 1
+	GlobalCh <- 1
+}
+
+func TestRaceIntRWGlobalFuncs(t *testing.T) {
+	go GlobalFunc1()
+	go GlobalFunc2()
+	<-GlobalCh
+	<-GlobalCh
+}
+
+func TestRaceIntRWClosures(t *testing.T) {
+	var x, y int
+	ch := make(chan int, 2)
+
+	go func() {
+		y = x
+		ch <- 1
+	}()
+	go func() {
+		x = 1
+		ch <- 1
+	}()
+	<-ch
+	<-ch
+}
+
+func TestNoRaceIntRWClosures(t *testing.T) {
+	var x, y int
+	ch := make(chan int, 1)
+
+	go func() {
+		y = x
+		ch <- 1
+	}()
+	<-ch
+	go func() {
+		x = 1
+		ch <- 1
+	}()
+	<-ch
+
+}
+
+func TestRaceInt32RWClosures(t *testing.T) {
+	var x, y int32
+	ch := make(chan bool, 2)
+
+	go func() {
+		y = x
+		ch <- true
+	}()
+	go func() {
+		x = 1
+		ch <- true
+	}()
+	<-ch
+	<-ch
+}
+
+func TestNoRaceCase(t *testing.T) {
+	var y int
+	for x := -1; x <= 1; x++ {
+		switch {
+		case x < 0:
+			y = -1
+		case x == 0:
+			y = 0
+		case x > 0:
+			y = 1
+		}
+	}
+	y++
+}
+
+func TestRaceCaseCondition(t *testing.T) {
+	var x int = 0
+	ch := make(chan int, 2)
+
+	go func() {
+		x = 2
+		ch <- 1
+	}()
+	go func() {
+		switch x < 2 {
+		case true:
+			x = 1
+			//case false:
+			//	x = 5
+		}
+		ch <- 1
+	}()
+	<-ch
+	<-ch
+}
+
+func TestRaceCaseCondition2(t *testing.T) {
+	// switch body is rearranged by the compiler so the tests
+	// passes even if we don't instrument '<'
+	var x int = 0
+	ch := make(chan int, 2)
+
+	go func() {
+		x = 2
+		ch <- 1
+	}()
+	go func() {
+		switch x < 2 {
+		case true:
+			x = 1
+		case false:
+			x = 5
+		}
+		ch <- 1
+	}()
+	<-ch
+	<-ch
+}
+
+func TestRaceCaseBody(t *testing.T) {
+	var x, y int
+	ch := make(chan int, 2)
+
+	go func() {
+		y = x
+		ch <- 1
+	}()
+	go func() {
+		switch {
+		default:
+			x = 1
+		case x == 100:
+			x = -x
+		}
+		ch <- 1
+	}()
+	<-ch
+	<-ch
+}
+
+func TestNoRaceCaseFallthrough(t *testing.T) {
+	var x, y, z int
+	ch := make(chan int, 2)
+	z = 1
+
+	go func() {
+		y = x
+		ch <- 1
+	}()
+	go func() {
+		switch {
+		case z == 1:
+		case z == 2:
+			x = 2
+		}
+		ch <- 1
+	}()
+	<-ch
+	<-ch
+}
+
+func TestRaceCaseFallthrough(t *testing.T) {
+	var x, y, z int
+	ch := make(chan int, 2)
+	z = 1
+
+	go func() {
+		y = x
+		ch <- 1
+	}()
+	go func() {
+		switch {
+		case z == 1:
+			fallthrough
+		case z == 2:
+			x = 2
+		}
+		ch <- 1
+	}()
+
+	<-ch
+	<-ch
+}
+
+func TestRaceCaseIssue6418(t *testing.T) {
+	m := map[string]map[string]string{
+		"a": {
+			"b": "c",
+		},
+	}
+	ch := make(chan int)
+	go func() {
+		m["a"]["x"] = "y"
+		ch <- 1
+	}()
+	switch m["a"]["b"] {
+	}
+	<-ch
+}
+
+func TestRaceCaseType(t *testing.T) {
+	var x, y int
+	var i interface{} = x
+	c := make(chan int, 1)
+	go func() {
+		switch i.(type) {
+		case nil:
+		case int:
+		}
+		c <- 1
+	}()
+	i = y
+	<-c
+}
+
+func TestRaceCaseTypeBody(t *testing.T) {
+	var x, y int
+	var i interface{} = &x
+	c := make(chan int, 1)
+	go func() {
+		switch i := i.(type) {
+		case nil:
+		case *int:
+			*i = y
+		}
+		c <- 1
+	}()
+	x = y
+	<-c
+}
+
+func TestRaceCaseTypeIssue5890(t *testing.T) {
+	// spurious extra instrumentation of the initial interface
+	// value.
+	var x, y int
+	m := make(map[int]map[int]interface{})
+	m[0] = make(map[int]interface{})
+	c := make(chan int, 1)
+	go func() {
+		switch i := m[0][1].(type) {
+		case nil:
+		case *int:
+			*i = x
+		}
+		c <- 1
+	}()
+	m[0][1] = y
+	<-c
+}
+
+func TestNoRaceRange(t *testing.T) {
+	ch := make(chan int, 3)
+	a := [...]int{1, 2, 3}
+	for _, v := range a {
+		ch <- v
+	}
+	close(ch)
+}
+
+func TestNoRaceRangeIssue5446(t *testing.T) {
+	ch := make(chan int, 3)
+	a := []int{1, 2, 3}
+	b := []int{4}
+	// used to insert a spurious instrumentation of a[i]
+	// and crash.
+	i := 1
+	for i, a[i] = range b {
+		ch <- i
+	}
+	close(ch)
+}
+
+func TestRaceRange(t *testing.T) {
+	const N = 2
+	var a [N]int
+	var x, y int
+	done := make(chan bool, N)
+	for i, v := range a {
+		go func(i int) {
+			// we don't want a write-vs-write race
+			// so there is no array b here
+			if i == 0 {
+				x = v
+			} else {
+				y = v
+			}
+			done <- true
+		}(i)
+	}
+	for i := 0; i < N; i++ {
+		<-done
+	}
+}
+
+func TestRaceForInit(t *testing.T) {
+	c := make(chan int)
+	x := 0
+	go func() {
+		c <- x
+	}()
+	for x = 42; false; {
+	}
+	<-c
+}
+
+func TestNoRaceForInit(t *testing.T) {
+	done := make(chan bool)
+	c := make(chan bool)
+	x := 0
+	go func() {
+		for {
+			_, ok := <-c
+			if !ok {
+				done <- true
+				return
+			}
+			x++
+		}
+	}()
+	i := 0
+	for x = 42; i < 10; i++ {
+		c <- true
+	}
+	close(c)
+	<-done
+}
+
+func TestRaceForTest(t *testing.T) {
+	done := make(chan bool)
+	c := make(chan bool)
+	stop := false
+	go func() {
+		for {
+			_, ok := <-c
+			if !ok {
+				done <- true
+				return
+			}
+			stop = true
+		}
+	}()
+	for !stop {
+		c <- true
+	}
+	close(c)
+	<-done
+}
+
+func TestRaceForIncr(t *testing.T) {
+	done := make(chan bool)
+	c := make(chan bool)
+	x := 0
+	go func() {
+		for {
+			_, ok := <-c
+			if !ok {
+				done <- true
+				return
+			}
+			x++
+		}
+	}()
+	for i := 0; i < 10; x++ {
+		i++
+		c <- true
+	}
+	close(c)
+	<-done
+}
+
+func TestNoRaceForIncr(t *testing.T) {
+	done := make(chan bool)
+	x := 0
+	go func() {
+		x++
+		done <- true
+	}()
+	for i := 0; i < 0; x++ {
+	}
+	<-done
+}
+
+func TestRacePlus(t *testing.T) {
+	var x, y, z int
+	ch := make(chan int, 2)
+
+	go func() {
+		y = x + z
+		ch <- 1
+	}()
+	go func() {
+		y = x + z + z
+		ch <- 1
+	}()
+	<-ch
+	<-ch
+}
+
+func TestRacePlus2(t *testing.T) {
+	var x, y, z int
+	ch := make(chan int, 2)
+
+	go func() {
+		x = 1
+		ch <- 1
+	}()
+	go func() {
+		y = +x + z
+		ch <- 1
+	}()
+	<-ch
+	<-ch
+}
+
+func TestNoRacePlus(t *testing.T) {
+	var x, y, z, f int
+	ch := make(chan int, 2)
+
+	go func() {
+		y = x + z
+		ch <- 1
+	}()
+	go func() {
+		f = z + x
+		ch <- 1
+	}()
+	<-ch
+	<-ch
+}
+
+func TestRaceComplement(t *testing.T) {
+	var x, y, z int
+	ch := make(chan int, 2)
+
+	go func() {
+		x = ^y
+		ch <- 1
+	}()
+	go func() {
+		y = ^z
+		ch <- 1
+	}()
+	<-ch
+	<-ch
+}
+
+func TestRaceDiv(t *testing.T) {
+	var x, y, z int
+	ch := make(chan int, 2)
+
+	go func() {
+		x = y / (z + 1)
+		ch <- 1
+	}()
+	go func() {
+		y = z
+		ch <- 1
+	}()
+	<-ch
+	<-ch
+}
+
+func TestRaceDivConst(t *testing.T) {
+	var x, y, z uint32
+	ch := make(chan int, 2)
+
+	go func() {
+		x = y / 3 // involves only a HMUL node
+		ch <- 1
+	}()
+	go func() {
+		y = z
+		ch <- 1
+	}()
+	<-ch
+	<-ch
+}
+
+func TestRaceMod(t *testing.T) {
+	var x, y, z int
+	ch := make(chan int, 2)
+
+	go func() {
+		x = y % (z + 1)
+		ch <- 1
+	}()
+	go func() {
+		y = z
+		ch <- 1
+	}()
+	<-ch
+	<-ch
+}
+
+func TestRaceModConst(t *testing.T) {
+	var x, y, z int
+	ch := make(chan int, 2)
+
+	go func() {
+		x = y % 3
+		ch <- 1
+	}()
+	go func() {
+		y = z
+		ch <- 1
+	}()
+	<-ch
+	<-ch
+}
+
+func TestRaceRotate(t *testing.T) {
+	var x, y, z uint32
+	ch := make(chan int, 2)
+
+	go func() {
+		x = y<<12 | y>>20
+		ch <- 1
+	}()
+	go func() {
+		y = z
+		ch <- 1
+	}()
+	<-ch
+	<-ch
+}
+
+// May crash if the instrumentation is reckless.
+func TestNoRaceEnoughRegisters(t *testing.T) {
+	// from erf.go
+	const (
+		sa1 = 1
+		sa2 = 2
+		sa3 = 3
+		sa4 = 4
+		sa5 = 5
+		sa6 = 6
+		sa7 = 7
+		sa8 = 8
+	)
+	var s, S float64
+	s = 3.1415
+	S = 1 + s*(sa1+s*(sa2+s*(sa3+s*(sa4+s*(sa5+s*(sa6+s*(sa7+s*sa8)))))))
+	s = S
+}
+
+// emptyFunc should not be inlined.
+func emptyFunc(x int) {
+	if false {
+		fmt.Println(x)
+	}
+}
+
+func TestRaceFuncArgument(t *testing.T) {
+	var x int
+	ch := make(chan bool, 1)
+	go func() {
+		emptyFunc(x)
+		ch <- true
+	}()
+	x = 1
+	<-ch
+}
+
+func TestRaceFuncArgument2(t *testing.T) {
+	var x int
+	ch := make(chan bool, 2)
+	go func() {
+		x = 42
+		ch <- true
+	}()
+	go func(y int) {
+		ch <- true
+	}(x)
+	<-ch
+	<-ch
+}
+
+func TestRaceSprint(t *testing.T) {
+	var x int
+	ch := make(chan bool, 1)
+	go func() {
+		fmt.Sprint(x)
+		ch <- true
+	}()
+	x = 1
+	<-ch
+}
+
+func TestRaceArrayCopy(t *testing.T) {
+	ch := make(chan bool, 1)
+	var a [5]int
+	go func() {
+		a[3] = 1
+		ch <- true
+	}()
+	a = [5]int{1, 2, 3, 4, 5}
+	<-ch
+}
+
+// Blows up a naive compiler.
+func TestRaceNestedArrayCopy(t *testing.T) {
+	ch := make(chan bool, 1)
+	type (
+		Point32   [2][2][2][2][2]Point
+		Point1024 [2][2][2][2][2]Point32
+		Point32k  [2][2][2][2][2]Point1024
+		Point1M   [2][2][2][2][2]Point32k
+	)
+	var a, b Point1M
+	go func() {
+		a[0][1][0][1][0][1][0][1][0][1][0][1][0][1][0][1][0][1][0][1].y = 1
+		ch <- true
+	}()
+	a = b
+	<-ch
+}
+
+func TestRaceStructRW(t *testing.T) {
+	p := Point{0, 0}
+	ch := make(chan bool, 1)
+	go func() {
+		p = Point{1, 1}
+		ch <- true
+	}()
+	q := p
+	<-ch
+	p = q
+}
+
+func TestRaceStructFieldRW1(t *testing.T) {
+	p := Point{0, 0}
+	ch := make(chan bool, 1)
+	go func() {
+		p.x = 1
+		ch <- true
+	}()
+	_ = p.x
+	<-ch
+}
+
+func TestNoRaceStructFieldRW1(t *testing.T) {
+	// Same struct, different variables, no
+	// pointers. The layout is known (at compile time?) ->
+	// no read on p
+	// writes on x and y
+	p := Point{0, 0}
+	ch := make(chan bool, 1)
+	go func() {
+		p.x = 1
+		ch <- true
+	}()
+	p.y = 1
+	<-ch
+	_ = p
+}
+
+func TestNoRaceStructFieldRW2(t *testing.T) {
+	// Same as NoRaceStructFieldRW1
+	// but p is a pointer, so there is a read on p
+	p := Point{0, 0}
+	ch := make(chan bool, 1)
+	go func() {
+		p.x = 1
+		ch <- true
+	}()
+	p.y = 1
+	<-ch
+	_ = p
+}
+
+func TestRaceStructFieldRW2(t *testing.T) {
+	p := &Point{0, 0}
+	ch := make(chan bool, 1)
+	go func() {
+		p.x = 1
+		ch <- true
+	}()
+	_ = p.x
+	<-ch
+}
+
+func TestRaceStructFieldRW3(t *testing.T) {
+	p := NamedPoint{name: "a", p: Point{0, 0}}
+	ch := make(chan bool, 1)
+	go func() {
+		p.p.x = 1
+		ch <- true
+	}()
+	_ = p.p.x
+	<-ch
+}
+
+func TestRaceEfaceWW(t *testing.T) {
+	var a, b interface{}
+	ch := make(chan bool, 1)
+	go func() {
+		a = 1
+		ch <- true
+	}()
+	a = 2
+	<-ch
+	_, _ = a, b
+}
+
+func TestRaceIfaceWW(t *testing.T) {
+	var a, b Writer
+	ch := make(chan bool, 1)
+	go func() {
+		a = DummyWriter{1}
+		ch <- true
+	}()
+	a = DummyWriter{2}
+	<-ch
+	b = a
+	a = b
+}
+
+func TestRaceIfaceCmp(t *testing.T) {
+	var a, b Writer
+	a = DummyWriter{1}
+	ch := make(chan bool, 1)
+	go func() {
+		a = DummyWriter{1}
+		ch <- true
+	}()
+	_ = a == b
+	<-ch
+}
+
+func TestRaceIfaceCmpNil(t *testing.T) {
+	var a Writer
+	a = DummyWriter{1}
+	ch := make(chan bool, 1)
+	go func() {
+		a = DummyWriter{1}
+		ch <- true
+	}()
+	_ = a == nil
+	<-ch
+}
+
+func TestRaceEfaceConv(t *testing.T) {
+	c := make(chan bool)
+	v := 0
+	go func() {
+		go func(x interface{}) {
+		}(v)
+		c <- true
+	}()
+	v = 42
+	<-c
+}
+
+type OsFile struct{}
+
+func (*OsFile) Read() {
+}
+
+type IoReader interface {
+	Read()
+}
+
+func TestRaceIfaceConv(t *testing.T) {
+	c := make(chan bool)
+	f := &OsFile{}
+	go func() {
+		go func(x IoReader) {
+		}(f)
+		c <- true
+	}()
+	f = &OsFile{}
+	<-c
+}
+
+func TestRaceError(t *testing.T) {
+	ch := make(chan bool, 1)
+	var err error
+	go func() {
+		err = nil
+		ch <- true
+	}()
+	_ = err
+	<-ch
+}
+
+func TestRaceIntptrRW(t *testing.T) {
+	var x, y int
+	var p *int = &x
+	ch := make(chan bool, 1)
+	go func() {
+		*p = 5
+		ch <- true
+	}()
+	y = *p
+	x = y
+	<-ch
+}
+
+func TestRaceStringRW(t *testing.T) {
+	ch := make(chan bool, 1)
+	s := ""
+	go func() {
+		s = "abacaba"
+		ch <- true
+	}()
+	_ = s
+	<-ch
+}
+
+func TestRaceStringPtrRW(t *testing.T) {
+	ch := make(chan bool, 1)
+	var x string
+	p := &x
+	go func() {
+		*p = "a"
+		ch <- true
+	}()
+	_ = *p
+	<-ch
+}
+
+func TestRaceFloat64WW(t *testing.T) {
+	var x, y float64
+	ch := make(chan bool, 1)
+	go func() {
+		x = 1.0
+		ch <- true
+	}()
+	x = 2.0
+	<-ch
+
+	y = x
+	x = y
+}
+
+func TestRaceComplex128WW(t *testing.T) {
+	var x, y complex128
+	ch := make(chan bool, 1)
+	go func() {
+		x = 2 + 2i
+		ch <- true
+	}()
+	x = 4 + 4i
+	<-ch
+
+	y = x
+	x = y
+}
+
+func TestRaceUnsafePtrRW(t *testing.T) {
+	var x, y, z int
+	x, y, z = 1, 2, 3
+	var p unsafe.Pointer = unsafe.Pointer(&x)
+	ch := make(chan bool, 1)
+	go func() {
+		p = (unsafe.Pointer)(&z)
+		ch <- true
+	}()
+	y = *(*int)(p)
+	x = y
+	<-ch
+}
+
+func TestRaceFuncVariableRW(t *testing.T) {
+	var f func(x int) int
+	f = func(x int) int {
+		return x * x
+	}
+	ch := make(chan bool, 1)
+	go func() {
+		f = func(x int) int {
+			return x
+		}
+		ch <- true
+	}()
+	y := f(1)
+	<-ch
+	x := y
+	y = x
+}
+
+func TestRaceFuncVariableWW(t *testing.T) {
+	var f func(x int) int
+	ch := make(chan bool, 1)
+	go func() {
+		f = func(x int) int {
+			return x
+		}
+		ch <- true
+	}()
+	f = func(x int) int {
+		return x * x
+	}
+	<-ch
+}
+
+// This one should not belong to mop_test
+func TestRacePanic(t *testing.T) {
+	var x int
+	var zero int = 0
+	ch := make(chan bool, 2)
+	go func() {
+		defer func() {
+			err := recover()
+			if err == nil {
+				panic("should be panicking")
+			}
+			x = 1
+			ch <- true
+		}()
+		var y int = 1 / zero
+		zero = y
+	}()
+	go func() {
+		defer func() {
+			err := recover()
+			if err == nil {
+				panic("should be panicking")
+			}
+			x = 2
+			ch <- true
+		}()
+		var y int = 1 / zero
+		zero = y
+	}()
+
+	<-ch
+	<-ch
+	if zero != 0 {
+		panic("zero has changed")
+	}
+}
+
+func TestNoRaceBlank(t *testing.T) {
+	var a [5]int
+	ch := make(chan bool, 1)
+	go func() {
+		_, _ = a[0], a[1]
+		ch <- true
+	}()
+	_, _ = a[2], a[3]
+	<-ch
+	a[1] = a[0]
+}
+
+func TestRaceAppendRW(t *testing.T) {
+	a := make([]int, 10)
+	ch := make(chan bool)
+	go func() {
+		_ = append(a, 1)
+		ch <- true
+	}()
+	a[0] = 1
+	<-ch
+}
+
+func TestRaceAppendLenRW(t *testing.T) {
+	a := make([]int, 0)
+	ch := make(chan bool)
+	go func() {
+		a = append(a, 1)
+		ch <- true
+	}()
+	_ = len(a)
+	<-ch
+}
+
+func TestRaceAppendCapRW(t *testing.T) {
+	a := make([]int, 0)
+	ch := make(chan string)
+	go func() {
+		a = append(a, 1)
+		ch <- ""
+	}()
+	_ = cap(a)
+	<-ch
+}
+
+func TestNoRaceFuncArgsRW(t *testing.T) {
+	ch := make(chan byte, 1)
+	var x byte
+	go func(y byte) {
+		_ = y
+		ch <- 0
+	}(x)
+	x = 1
+	<-ch
+}
+
+func TestRaceFuncArgsRW(t *testing.T) {
+	ch := make(chan byte, 1)
+	var x byte
+	go func(y *byte) {
+		_ = *y
+		ch <- 0
+	}(&x)
+	x = 1
+	<-ch
+}
+
+// from the mailing list, slightly modified
+// unprotected concurrent access to seen[]
+func TestRaceCrawl(t *testing.T) {
+	url := "dummyurl"
+	depth := 3
+	seen := make(map[string]bool)
+	ch := make(chan int, 100)
+	var wg sync.WaitGroup
+	var crawl func(string, int)
+	crawl = func(u string, d int) {
+		nurl := 0
+		defer func() {
+			ch <- nurl
+		}()
+		seen[u] = true
+		if d <= 0 {
+			return
+		}
+		urls := [...]string{"a", "b", "c"}
+		for _, uu := range urls {
+			if _, ok := seen[uu]; !ok {
+				wg.Add(1)
+				go crawl(uu, d-1)
+				nurl++
+			}
+		}
+		wg.Done()
+	}
+	wg.Add(1)
+	go crawl(url, depth)
+	wg.Wait()
+}
+
+func TestRaceIndirection(t *testing.T) {
+	ch := make(chan struct{}, 1)
+	var y int
+	var x *int = &y
+	go func() {
+		*x = 1
+		ch <- struct{}{}
+	}()
+	*x = 2
+	<-ch
+	_ = *x
+}
+
+func TestRaceRune(t *testing.T) {
+	c := make(chan bool)
+	var x rune
+	go func() {
+		x = 1
+		c <- true
+	}()
+	_ = x
+	<-c
+}
+
+func TestRaceEmptyInterface1(t *testing.T) {
+	c := make(chan bool)
+	var x interface{}
+	go func() {
+		x = nil
+		c <- true
+	}()
+	_ = x
+	<-c
+}
+
+func TestRaceEmptyInterface2(t *testing.T) {
+	c := make(chan bool)
+	var x interface{}
+	go func() {
+		x = &Point{}
+		c <- true
+	}()
+	_ = x
+	<-c
+}
+
+func TestRaceTLS(t *testing.T) {
+	comm := make(chan *int)
+	done := make(chan bool, 2)
+	go func() {
+		var x int
+		comm <- &x
+		x = 1
+		x = *(<-comm)
+		done <- true
+	}()
+	go func() {
+		p := <-comm
+		*p = 2
+		comm <- p
+		done <- true
+	}()
+	<-done
+	<-done
+}
+
+func TestNoRaceHeapReallocation(t *testing.T) {
+	// It is possible that a future implementation
+	// of memory allocation will ruin this test.
+	// Increasing n might help in this case, so
+	// this test is a bit more generic than most of the
+	// others.
+	const n = 2
+	done := make(chan bool, n)
+	empty := func(p *int) {}
+	for i := 0; i < n; i++ {
+		ms := i
+		go func() {
+			<-time.After(time.Duration(ms) * time.Millisecond)
+			runtime.GC()
+			var x int
+			empty(&x) // x goes to the heap
+			done <- true
+		}()
+	}
+	for i := 0; i < n; i++ {
+		<-done
+	}
+}
+
+func TestRaceAnd(t *testing.T) {
+	c := make(chan bool)
+	x, y := 0, 0
+	go func() {
+		x = 1
+		c <- true
+	}()
+	if x == 1 && y == 1 {
+	}
+	<-c
+}
+
+func TestRaceAnd2(t *testing.T) {
+	c := make(chan bool)
+	x, y := 0, 0
+	go func() {
+		x = 1
+		c <- true
+	}()
+	if y == 0 && x == 1 {
+	}
+	<-c
+}
+
+func TestNoRaceAnd(t *testing.T) {
+	c := make(chan bool)
+	x, y := 0, 0
+	go func() {
+		x = 1
+		c <- true
+	}()
+	if y == 1 && x == 1 {
+	}
+	<-c
+}
+
+func TestRaceOr(t *testing.T) {
+	c := make(chan bool)
+	x, y := 0, 0
+	go func() {
+		x = 1
+		c <- true
+	}()
+	if x == 1 || y == 1 {
+	}
+	<-c
+}
+
+func TestRaceOr2(t *testing.T) {
+	c := make(chan bool)
+	x, y := 0, 0
+	go func() {
+		x = 1
+		c <- true
+	}()
+	if y == 1 || x == 1 {
+	}
+	<-c
+}
+
+func TestNoRaceOr(t *testing.T) {
+	c := make(chan bool)
+	x, y := 0, 0
+	go func() {
+		x = 1
+		c <- true
+	}()
+	if y == 0 || x == 1 {
+	}
+	<-c
+}
+
+func TestNoRaceShortCalc(t *testing.T) {
+	c := make(chan bool)
+	x, y := 0, 0
+	go func() {
+		y = 1
+		c <- true
+	}()
+	if x == 0 || y == 0 {
+	}
+	<-c
+}
+
+func TestNoRaceShortCalc2(t *testing.T) {
+	c := make(chan bool)
+	x, y := 0, 0
+	go func() {
+		y = 1
+		c <- true
+	}()
+	if x == 1 && y == 0 {
+	}
+	<-c
+}
+
+func TestRaceFuncItself(t *testing.T) {
+	c := make(chan bool)
+	f := func() {}
+	go func() {
+		f()
+		c <- true
+	}()
+	f = func() {}
+	<-c
+}
+
+func TestNoRaceFuncUnlock(t *testing.T) {
+	ch := make(chan bool, 1)
+	var mu sync.Mutex
+	x := 0
+	go func() {
+		mu.Lock()
+		x = 42
+		mu.Unlock()
+		ch <- true
+	}()
+	x = func(mu *sync.Mutex) int {
+		mu.Lock()
+		return 43
+	}(&mu)
+	mu.Unlock()
+	<-ch
+}
+
+func TestRaceStructInit(t *testing.T) {
+	type X struct {
+		x, y int
+	}
+	c := make(chan bool, 1)
+	y := 0
+	go func() {
+		y = 42
+		c <- true
+	}()
+	x := X{x: y}
+	_ = x
+	<-c
+}
+
+func TestRaceArrayInit(t *testing.T) {
+	c := make(chan bool, 1)
+	y := 0
+	go func() {
+		y = 42
+		c <- true
+	}()
+	x := []int{0, y, 42}
+	_ = x
+	<-c
+}
+
+func TestRaceMapInit(t *testing.T) {
+	c := make(chan bool, 1)
+	y := 0
+	go func() {
+		y = 42
+		c <- true
+	}()
+	x := map[int]int{0: 42, y: 42}
+	_ = x
+	<-c
+}
+
+func TestRaceMapInit2(t *testing.T) {
+	c := make(chan bool, 1)
+	y := 0
+	go func() {
+		y = 42
+		c <- true
+	}()
+	x := map[int]int{0: 42, 42: y}
+	_ = x
+	<-c
+}
+
+type Inter interface {
+	Foo(x int)
+}
+type InterImpl struct {
+	x, y int
+}
+
+func (p InterImpl) Foo(x int) {
+	// prevent inlining
+	z := 42
+	x = 85
+	y := x / z
+	z = y * z
+	x = z * y
+	_, _, _ = x, y, z
+}
+
+type InterImpl2 InterImpl
+
+func (p *InterImpl2) Foo(x int) {
+	if p == nil {
+		InterImpl{}.Foo(x)
+	}
+	InterImpl(*p).Foo(x)
+}
+
+func TestRaceInterCall(t *testing.T) {
+	c := make(chan bool, 1)
+	p := InterImpl{}
+	var x Inter = p
+	go func() {
+		p2 := InterImpl{}
+		x = p2
+		c <- true
+	}()
+	x.Foo(0)
+	<-c
+}
+
+func TestRaceInterCall2(t *testing.T) {
+	c := make(chan bool, 1)
+	p := InterImpl{}
+	var x Inter = p
+	z := 0
+	go func() {
+		z = 42
+		c <- true
+	}()
+	x.Foo(z)
+	<-c
+}
+
+func TestRaceFuncCall(t *testing.T) {
+	c := make(chan bool, 1)
+	f := func(x, y int) {}
+	x, y := 0, 0
+	go func() {
+		y = 42
+		c <- true
+	}()
+	f(x, y)
+	<-c
+}
+
+func TestRaceMethodCall(t *testing.T) {
+	c := make(chan bool, 1)
+	i := InterImpl{}
+	x := 0
+	go func() {
+		x = 42
+		c <- true
+	}()
+	i.Foo(x)
+	<-c
+}
+
+func TestRaceMethodCall2(t *testing.T) {
+	c := make(chan bool, 1)
+	i := &InterImpl{}
+	go func() {
+		i = &InterImpl{}
+		c <- true
+	}()
+	i.Foo(0)
+	<-c
+}
+
+// Method value with concrete value receiver.
+func TestRaceMethodValue(t *testing.T) {
+	c := make(chan bool, 1)
+	i := InterImpl{}
+	go func() {
+		i = InterImpl{}
+		c <- true
+	}()
+	_ = i.Foo
+	<-c
+}
+
+// Method value with interface receiver.
+func TestRaceMethodValue2(t *testing.T) {
+	c := make(chan bool, 1)
+	var i Inter = InterImpl{}
+	go func() {
+		i = InterImpl{}
+		c <- true
+	}()
+	_ = i.Foo
+	<-c
+}
+
+// Method value with implicit dereference.
+func TestRaceMethodValue3(t *testing.T) {
+	c := make(chan bool, 1)
+	i := &InterImpl{}
+	go func() {
+		*i = InterImpl{}
+		c <- true
+	}()
+	_ = i.Foo // dereferences i.
+	<-c
+}
+
+// Method value implicitly taking receiver address.
+func TestNoRaceMethodValue(t *testing.T) {
+	c := make(chan bool, 1)
+	i := InterImpl2{}
+	go func() {
+		i = InterImpl2{}
+		c <- true
+	}()
+	_ = i.Foo // takes the address of i only.
+	<-c
+}
+
+func TestRacePanicArg(t *testing.T) {
+	c := make(chan bool, 1)
+	err := errors.New("err")
+	go func() {
+		err = errors.New("err2")
+		c <- true
+	}()
+	defer func() {
+		recover()
+		<-c
+	}()
+	panic(err)
+}
+
+func TestRaceDeferArg(t *testing.T) {
+	c := make(chan bool, 1)
+	x := 0
+	go func() {
+		x = 42
+		c <- true
+	}()
+	func() {
+		defer func(x int) {
+		}(x)
+	}()
+	<-c
+}
+
+type DeferT int
+
+func (d DeferT) Foo() {
+}
+
+func TestRaceDeferArg2(t *testing.T) {
+	c := make(chan bool, 1)
+	var x DeferT
+	go func() {
+		var y DeferT
+		x = y
+		c <- true
+	}()
+	func() {
+		defer x.Foo()
+	}()
+	<-c
+}
+
+func TestNoRaceAddrExpr(t *testing.T) {
+	c := make(chan bool, 1)
+	x := 0
+	go func() {
+		x = 42
+		c <- true
+	}()
+	_ = &x
+	<-c
+}
+
+type AddrT struct {
+	_ [256]byte
+	x int
+}
+
+type AddrT2 struct {
+	_ [512]byte
+	p *AddrT
+}
+
+func TestRaceAddrExpr(t *testing.T) {
+	c := make(chan bool, 1)
+	a := AddrT2{p: &AddrT{x: 42}}
+	go func() {
+		a.p = &AddrT{x: 43}
+		c <- true
+	}()
+	_ = &a.p.x
+	<-c
+}
+
+func TestRaceTypeAssert(t *testing.T) {
+	c := make(chan bool, 1)
+	x := 0
+	var i interface{} = x
+	go func() {
+		y := 0
+		i = y
+		c <- true
+	}()
+	_ = i.(int)
+	<-c
+}
+
+func TestRaceBlockAs(t *testing.T) {
+	c := make(chan bool, 1)
+	var x, y int
+	go func() {
+		x = 42
+		c <- true
+	}()
+	x, y = y, x
+	<-c
+}
+
+func TestRaceSliceSlice(t *testing.T) {
+	c := make(chan bool, 1)
+	x := make([]int, 10)
+	go func() {
+		x = make([]int, 20)
+		c <- true
+	}()
+	_ = x[2:3]
+	<-c
+}
+
+func TestRaceSliceSlice2(t *testing.T) {
+	c := make(chan bool, 1)
+	x := make([]int, 10)
+	i := 2
+	go func() {
+		i = 3
+		c <- true
+	}()
+	_ = x[i:4]
+	<-c
+}
+
+func TestRaceSliceString(t *testing.T) {
+	c := make(chan bool, 1)
+	x := "hello"
+	go func() {
+		x = "world"
+		c <- true
+	}()
+	_ = x[2:3]
+	<-c
+}
+
+func TestRaceSliceStruct(t *testing.T) {
+	type X struct {
+		x, y int
+	}
+	c := make(chan bool, 1)
+	x := make([]X, 10)
+	go func() {
+		y := make([]X, 10)
+		copy(y, x)
+		c <- true
+	}()
+	x[1].y = 42
+	<-c
+}
+
+func TestRaceAppendSliceStruct(t *testing.T) {
+	type X struct {
+		x, y int
+	}
+	c := make(chan bool, 1)
+	x := make([]X, 10)
+	go func() {
+		y := make([]X, 0, 10)
+		y = append(y, x...)
+		c <- true
+	}()
+	x[1].y = 42
+	<-c
+}
+
+func TestRaceStructInd(t *testing.T) {
+	c := make(chan bool, 1)
+	type Item struct {
+		x, y int
+	}
+	i := Item{}
+	go func(p *Item) {
+		*p = Item{}
+		c <- true
+	}(&i)
+	i.y = 42
+	<-c
+}
+
+func TestRaceAsFunc1(t *testing.T) {
+	var s []byte
+	c := make(chan bool, 1)
+	go func() {
+		var err error
+		s, err = func() ([]byte, error) {
+			t := []byte("hello world")
+			return t, nil
+		}()
+		c <- true
+		_ = err
+	}()
+	_ = string(s)
+	<-c
+}
+
+func TestRaceAsFunc2(t *testing.T) {
+	c := make(chan bool, 1)
+	x := 0
+	go func() {
+		func(x int) {
+		}(x)
+		c <- true
+	}()
+	x = 42
+	<-c
+}
+
+func TestRaceAsFunc3(t *testing.T) {
+	c := make(chan bool, 1)
+	var mu sync.Mutex
+	x := 0
+	go func() {
+		func(x int) {
+			mu.Lock()
+		}(x) // Read of x must be outside of the mutex.
+		mu.Unlock()
+		c <- true
+	}()
+	mu.Lock()
+	x = 42
+	mu.Unlock()
+	<-c
+}
+
+func TestNoRaceAsFunc4(t *testing.T) {
+	c := make(chan bool, 1)
+	var mu sync.Mutex
+	x := 0
+	go func() {
+		x = func() int { // Write of x must be under the mutex.
+			mu.Lock()
+			return 42
+		}()
+		mu.Unlock()
+		c <- true
+	}()
+	mu.Lock()
+	x = 42
+	mu.Unlock()
+	<-c
+}
+
+func TestRaceHeapParam(t *testing.T) {
+	x := func() (x int) {
+		go func() {
+			x = 42
+		}()
+		return
+	}()
+	_ = x
+}
+
+func TestNoRaceEmptyStruct(t *testing.T) {
+	type Empty struct{}
+	type X struct {
+		y int64
+		Empty
+	}
+	type Y struct {
+		x X
+		y int64
+	}
+	c := make(chan X)
+	var y Y
+	go func() {
+		x := y.x
+		c <- x
+	}()
+	y.y = 42
+	<-c
+}
+
+func TestRaceNestedStruct(t *testing.T) {
+	type X struct {
+		x, y int
+	}
+	type Y struct {
+		x X
+	}
+	c := make(chan Y)
+	var y Y
+	go func() {
+		c <- y
+	}()
+	y.x.y = 42
+	<-c
+}
+
+func TestRaceIssue5567(t *testing.T) {
+	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4))
+	in := make(chan []byte)
+	res := make(chan error)
+	go func() {
+		var err error
+		defer func() {
+			close(in)
+			res <- err
+		}()
+		path := "mop_test.go"
+		f, err := os.Open(path)
+		if err != nil {
+			return
+		}
+		defer f.Close()
+		var n, total int
+		b := make([]byte, 17) // the race is on b buffer
+		for err == nil {
+			n, err = f.Read(b)
+			total += n
+			if n > 0 {
+				in <- b[:n]
+			}
+		}
+		if err == io.EOF {
+			err = nil
+		}
+	}()
+	h := sha1.New()
+	for b := range in {
+		h.Write(b)
+	}
+	_ = h.Sum(nil)
+	err := <-res
+	if err != nil {
+		t.Fatal(err)
+	}
+}
+
+func TestRaceIssue5654(t *testing.T) {
+	text := `Friends, Romans, countrymen, lend me your ears;
+I come to bury Caesar, not to praise him.
+The evil that men do lives after them;
+The good is oft interred with their bones;
+So let it be with Caesar. The noble Brutus
+Hath told you Caesar was ambitious:
+If it were so, it was a grievous fault,
+And grievously hath Caesar answer'd it.
+Here, under leave of Brutus and the rest -
+For Brutus is an honourable man;
+So are they all, all honourable men -
+Come I to speak in Caesar's funeral.
+He was my friend, faithful and just to me:
+But Brutus says he was ambitious;
+And Brutus is an honourable man.`
+
+	data := bytes.NewBufferString(text)
+	in := make(chan []byte)
+
+	go func() {
+		buf := make([]byte, 16)
+		var n int
+		var err error
+		for ; err == nil; n, err = data.Read(buf) {
+			in <- buf[:n]
+		}
+		close(in)
+	}()
+	res := ""
+	for s := range in {
+		res += string(s)
+	}
+	_ = res
+}
+
+type Base int
+
+func (b *Base) Foo() int {
+	return 42
+}
+
+func (b Base) Bar() int {
+	return int(b)
+}
+
+func TestNoRaceMethodThunk(t *testing.T) {
+	type Derived struct {
+		pad int
+		Base
+	}
+	var d Derived
+	done := make(chan bool)
+	go func() {
+		_ = d.Foo()
+		done <- true
+	}()
+	d = Derived{}
+	<-done
+}
+
+func TestRaceMethodThunk(t *testing.T) {
+	type Derived struct {
+		pad int
+		*Base
+	}
+	var d Derived
+	done := make(chan bool)
+	go func() {
+		_ = d.Foo()
+		done <- true
+	}()
+	d = Derived{}
+	<-done
+}
+
+func TestRaceMethodThunk2(t *testing.T) {
+	type Derived struct {
+		pad int
+		Base
+	}
+	var d Derived
+	done := make(chan bool)
+	go func() {
+		_ = d.Bar()
+		done <- true
+	}()
+	d = Derived{}
+	<-done
+}
+
+func TestRaceMethodThunk3(t *testing.T) {
+	type Derived struct {
+		pad int
+		*Base
+	}
+	var d Derived
+	d.Base = new(Base)
+	done := make(chan bool)
+	go func() {
+		_ = d.Bar()
+		done <- true
+	}()
+	d.Base = new(Base)
+	<-done
+}
+
+func TestRaceMethodThunk4(t *testing.T) {
+	type Derived struct {
+		pad int
+		*Base
+	}
+	var d Derived
+	d.Base = new(Base)
+	done := make(chan bool)
+	go func() {
+		_ = d.Bar()
+		done <- true
+	}()
+	*(*int)(d.Base) = 42
+	<-done
+}
+
+func TestNoRaceTinyAlloc(t *testing.T) {
+	const P = 4
+	const N = 1e6
+	var tinySink *byte
+	done := make(chan bool)
+	for p := 0; p < P; p++ {
+		go func() {
+			for i := 0; i < N; i++ {
+				var b byte
+				if b != 0 {
+					tinySink = &b // make it heap allocated
+				}
+				b = 42
+			}
+			done <- true
+		}()
+	}
+	for p := 0; p < P; p++ {
+		<-done
+	}
+}
diff --git a/src/pkg/runtime/race/testdata/mutex_test.go b/src/runtime/race/testdata/mutex_test.go
similarity index 100%
rename from src/pkg/runtime/race/testdata/mutex_test.go
rename to src/runtime/race/testdata/mutex_test.go
diff --git a/src/pkg/runtime/race/testdata/regression_test.go b/src/runtime/race/testdata/regression_test.go
similarity index 100%
rename from src/pkg/runtime/race/testdata/regression_test.go
rename to src/runtime/race/testdata/regression_test.go
diff --git a/src/pkg/runtime/race/testdata/rwmutex_test.go b/src/runtime/race/testdata/rwmutex_test.go
similarity index 100%
rename from src/pkg/runtime/race/testdata/rwmutex_test.go
rename to src/runtime/race/testdata/rwmutex_test.go
diff --git a/src/pkg/runtime/race/testdata/select_test.go b/src/runtime/race/testdata/select_test.go
similarity index 100%
rename from src/pkg/runtime/race/testdata/select_test.go
rename to src/runtime/race/testdata/select_test.go
diff --git a/src/runtime/race/testdata/slice_test.go b/src/runtime/race/testdata/slice_test.go
new file mode 100644
index 0000000..5702d1a
--- /dev/null
+++ b/src/runtime/race/testdata/slice_test.go
@@ -0,0 +1,485 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package race_test
+
+import (
+	"testing"
+)
+
+func TestRaceSliceRW(t *testing.T) {
+	ch := make(chan bool, 1)
+	a := make([]int, 2)
+	go func() {
+		a[1] = 1
+		ch <- true
+	}()
+	_ = a[1]
+	<-ch
+}
+
+func TestNoRaceSliceRW(t *testing.T) {
+	ch := make(chan bool, 1)
+	a := make([]int, 2)
+	go func() {
+		a[0] = 1
+		ch <- true
+	}()
+	_ = a[1]
+	<-ch
+}
+
+func TestRaceSliceWW(t *testing.T) {
+	a := make([]int, 10)
+	ch := make(chan bool, 1)
+	go func() {
+		a[1] = 1
+		ch <- true
+	}()
+	a[1] = 2
+	<-ch
+}
+
+func TestNoRaceArrayWW(t *testing.T) {
+	var a [5]int
+	ch := make(chan bool, 1)
+	go func() {
+		a[0] = 1
+		ch <- true
+	}()
+	a[1] = 2
+	<-ch
+}
+
+func TestRaceArrayWW(t *testing.T) {
+	var a [5]int
+	ch := make(chan bool, 1)
+	go func() {
+		a[1] = 1
+		ch <- true
+	}()
+	a[1] = 2
+	<-ch
+}
+
+func TestNoRaceSliceWriteLen(t *testing.T) {
+	ch := make(chan bool, 1)
+	a := make([]bool, 1)
+	go func() {
+		a[0] = true
+		ch <- true
+	}()
+	_ = len(a)
+	<-ch
+}
+
+func TestNoRaceSliceWriteCap(t *testing.T) {
+	ch := make(chan bool, 1)
+	a := make([]uint64, 100)
+	go func() {
+		a[50] = 123
+		ch <- true
+	}()
+	_ = cap(a)
+	<-ch
+}
+
+func TestRaceSliceCopyRead(t *testing.T) {
+	ch := make(chan bool, 1)
+	a := make([]int, 10)
+	b := make([]int, 10)
+	go func() {
+		_ = a[5]
+		ch <- true
+	}()
+	copy(a, b)
+	<-ch
+}
+
+func TestNoRaceSliceWriteCopy(t *testing.T) {
+	ch := make(chan bool, 1)
+	a := make([]int, 10)
+	b := make([]int, 10)
+	go func() {
+		a[5] = 1
+		ch <- true
+	}()
+	copy(a[:5], b[:5])
+	<-ch
+}
+
+func TestRaceSliceCopyWrite2(t *testing.T) {
+	ch := make(chan bool, 1)
+	a := make([]int, 10)
+	b := make([]int, 10)
+	go func() {
+		b[5] = 1
+		ch <- true
+	}()
+	copy(a, b)
+	<-ch
+}
+
+func TestRaceSliceCopyWrite3(t *testing.T) {
+	ch := make(chan bool, 1)
+	a := make([]byte, 10)
+	go func() {
+		a[7] = 1
+		ch <- true
+	}()
+	copy(a, "qwertyqwerty")
+	<-ch
+}
+
+func TestNoRaceSliceCopyRead(t *testing.T) {
+	ch := make(chan bool, 1)
+	a := make([]int, 10)
+	b := make([]int, 10)
+	go func() {
+		_ = b[5]
+		ch <- true
+	}()
+	copy(a, b)
+	<-ch
+}
+
+func TestNoRaceSliceWriteSlice2(t *testing.T) {
+	ch := make(chan bool, 1)
+	a := make([]float64, 10)
+	go func() {
+		a[2] = 1.0
+		ch <- true
+	}()
+	_ = a[0:5]
+	<-ch
+}
+
+func TestRaceSliceWriteSlice(t *testing.T) {
+	ch := make(chan bool, 1)
+	a := make([]float64, 10)
+	go func() {
+		a[2] = 1.0
+		ch <- true
+	}()
+	a = a[5:10]
+	<-ch
+}
+
+func TestNoRaceSliceWriteSlice(t *testing.T) {
+	ch := make(chan bool, 1)
+	a := make([]float64, 10)
+	go func() {
+		a[2] = 1.0
+		ch <- true
+	}()
+	_ = a[5:10]
+	<-ch
+}
+
+func TestNoRaceSliceLenCap(t *testing.T) {
+	ch := make(chan bool, 1)
+	a := make([]struct{}, 10)
+	go func() {
+		_ = len(a)
+		ch <- true
+	}()
+	_ = cap(a)
+	<-ch
+}
+
+func TestNoRaceStructSlicesRangeWrite(t *testing.T) {
+	type Str struct {
+		a []int
+		b []int
+	}
+	ch := make(chan bool, 1)
+	var s Str
+	s.a = make([]int, 10)
+	s.b = make([]int, 10)
+	go func() {
+		for range s.a {
+		}
+		ch <- true
+	}()
+	s.b[5] = 5
+	<-ch
+}
+
+func TestRaceSliceDifferent(t *testing.T) {
+	c := make(chan bool, 1)
+	s := make([]int, 10)
+	s2 := s
+	go func() {
+		s[3] = 3
+		c <- true
+	}()
+	// false negative because s2 is PAUTO w/o PHEAP
+	// so we do not instrument it
+	s2[3] = 3
+	<-c
+}
+
+func TestRaceSliceRangeWrite(t *testing.T) {
+	c := make(chan bool, 1)
+	s := make([]int, 10)
+	go func() {
+		s[3] = 3
+		c <- true
+	}()
+	for _, v := range s {
+		_ = v
+	}
+	<-c
+}
+
+func TestNoRaceSliceRangeWrite(t *testing.T) {
+	c := make(chan bool, 1)
+	s := make([]int, 10)
+	go func() {
+		s[3] = 3
+		c <- true
+	}()
+	for range s {
+	}
+	<-c
+}
+
+func TestRaceSliceRangeAppend(t *testing.T) {
+	c := make(chan bool, 1)
+	s := make([]int, 10)
+	go func() {
+		s = append(s, 3)
+		c <- true
+	}()
+	for range s {
+	}
+	<-c
+}
+
+func TestNoRaceSliceRangeAppend(t *testing.T) {
+	c := make(chan bool, 1)
+	s := make([]int, 10)
+	go func() {
+		_ = append(s, 3)
+		c <- true
+	}()
+	for range s {
+	}
+	<-c
+}
+
+func TestRaceSliceVarWrite(t *testing.T) {
+	c := make(chan bool, 1)
+	s := make([]int, 10)
+	go func() {
+		s[3] = 3
+		c <- true
+	}()
+	s = make([]int, 20)
+	<-c
+}
+
+func TestRaceSliceVarRead(t *testing.T) {
+	c := make(chan bool, 1)
+	s := make([]int, 10)
+	go func() {
+		_ = s[3]
+		c <- true
+	}()
+	s = make([]int, 20)
+	<-c
+}
+
+func TestRaceSliceVarRange(t *testing.T) {
+	c := make(chan bool, 1)
+	s := make([]int, 10)
+	go func() {
+		for range s {
+		}
+		c <- true
+	}()
+	s = make([]int, 20)
+	<-c
+}
+
+func TestRaceSliceVarAppend(t *testing.T) {
+	c := make(chan bool, 1)
+	s := make([]int, 10)
+	go func() {
+		_ = append(s, 10)
+		c <- true
+	}()
+	s = make([]int, 20)
+	<-c
+}
+
+func TestRaceSliceVarCopy(t *testing.T) {
+	c := make(chan bool, 1)
+	s := make([]int, 10)
+	go func() {
+		s2 := make([]int, 10)
+		copy(s, s2)
+		c <- true
+	}()
+	s = make([]int, 20)
+	<-c
+}
+
+func TestRaceSliceVarCopy2(t *testing.T) {
+	c := make(chan bool, 1)
+	s := make([]int, 10)
+	go func() {
+		s2 := make([]int, 10)
+		copy(s2, s)
+		c <- true
+	}()
+	s = make([]int, 20)
+	<-c
+}
+
+func TestRaceSliceAppend(t *testing.T) {
+	c := make(chan bool, 1)
+	s := make([]int, 10, 20)
+	go func() {
+		_ = append(s, 1)
+		c <- true
+	}()
+	_ = append(s, 2)
+	<-c
+}
+
+func TestRaceSliceAppendWrite(t *testing.T) {
+	c := make(chan bool, 1)
+	s := make([]int, 10)
+	go func() {
+		_ = append(s, 1)
+		c <- true
+	}()
+	s[0] = 42
+	<-c
+}
+
+func TestRaceSliceAppendSlice(t *testing.T) {
+	c := make(chan bool, 1)
+	s := make([]int, 10)
+	go func() {
+		s2 := make([]int, 10)
+		_ = append(s, s2...)
+		c <- true
+	}()
+	s[0] = 42
+	<-c
+}
+
+func TestRaceSliceAppendSlice2(t *testing.T) {
+	c := make(chan bool, 1)
+	s := make([]int, 10)
+	s2foobar := make([]int, 10)
+	go func() {
+		_ = append(s, s2foobar...)
+		c <- true
+	}()
+	s2foobar[5] = 42
+	<-c
+}
+
+func TestRaceSliceAppendString(t *testing.T) {
+	c := make(chan bool, 1)
+	s := make([]byte, 10)
+	go func() {
+		_ = append(s, "qwerty"...)
+		c <- true
+	}()
+	s[0] = 42
+	<-c
+}
+
+func TestNoRaceSliceIndexAccess(t *testing.T) {
+	c := make(chan bool, 1)
+	s := make([]int, 10)
+	v := 0
+	go func() {
+		_ = v
+		c <- true
+	}()
+	s[v] = 1
+	<-c
+}
+
+func TestNoRaceSliceIndexAccess2(t *testing.T) {
+	c := make(chan bool, 1)
+	s := make([]int, 10)
+	v := 0
+	go func() {
+		_ = v
+		c <- true
+	}()
+	_ = s[v]
+	<-c
+}
+
+func TestRaceSliceIndexAccess(t *testing.T) {
+	c := make(chan bool, 1)
+	s := make([]int, 10)
+	v := 0
+	go func() {
+		v = 1
+		c <- true
+	}()
+	s[v] = 1
+	<-c
+}
+
+func TestRaceSliceIndexAccess2(t *testing.T) {
+	c := make(chan bool, 1)
+	s := make([]int, 10)
+	v := 0
+	go func() {
+		v = 1
+		c <- true
+	}()
+	_ = s[v]
+	<-c
+}
+
+func TestRaceSliceByteToString(t *testing.T) {
+	c := make(chan string)
+	s := make([]byte, 10)
+	go func() {
+		c <- string(s)
+	}()
+	s[0] = 42
+	<-c
+}
+
+func TestRaceSliceRuneToString(t *testing.T) {
+	c := make(chan string)
+	s := make([]rune, 10)
+	go func() {
+		c <- string(s)
+	}()
+	s[9] = 42
+	<-c
+}
+
+func TestRaceConcatString(t *testing.T) {
+	s := "hello"
+	c := make(chan string, 1)
+	go func() {
+		c <- s + " world"
+	}()
+	s = "world"
+	<-c
+}
+
+func TestRaceCompareString(t *testing.T) {
+	s1 := "hello"
+	s2 := "world"
+	c := make(chan bool, 1)
+	go func() {
+		c <- s1 == s2
+	}()
+	s1 = s2
+	<-c
+}
diff --git a/src/pkg/runtime/race/testdata/sync_test.go b/src/runtime/race/testdata/sync_test.go
similarity index 100%
rename from src/pkg/runtime/race/testdata/sync_test.go
rename to src/runtime/race/testdata/sync_test.go
diff --git a/src/pkg/runtime/race/testdata/waitgroup_test.go b/src/runtime/race/testdata/waitgroup_test.go
similarity index 100%
rename from src/pkg/runtime/race/testdata/waitgroup_test.go
rename to src/runtime/race/testdata/waitgroup_test.go
diff --git a/src/runtime/race0.go b/src/runtime/race0.go
new file mode 100644
index 0000000..5d90cc8
--- /dev/null
+++ b/src/runtime/race0.go
@@ -0,0 +1,37 @@
+// 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.
+
+// +build !race
+
+// Dummy race detection API, used when not built with -race.
+
+package runtime
+
+import (
+	"unsafe"
+)
+
+const raceenabled = false
+
+// Because raceenabled is false, none of these functions should be called.
+
+func raceReadObjectPC(t *_type, addr unsafe.Pointer, callerpc, pc uintptr)  { gothrow("race") }
+func raceWriteObjectPC(t *_type, addr unsafe.Pointer, callerpc, pc uintptr) { gothrow("race") }
+func raceinit()                                                             { gothrow("race") }
+func racefini()                                                             { gothrow("race") }
+func racemapshadow(addr unsafe.Pointer, size uintptr)                       { gothrow("race") }
+func racewritepc(addr unsafe.Pointer, callerpc, pc uintptr)                 { gothrow("race") }
+func racereadpc(addr unsafe.Pointer, callerpc, pc uintptr)                  { gothrow("race") }
+func racereadrangepc(addr unsafe.Pointer, sz, callerpc, pc uintptr)         { gothrow("race") }
+func racewriterangepc(addr unsafe.Pointer, sz, callerpc, pc uintptr)        { gothrow("race") }
+func raceacquire(addr unsafe.Pointer)                                       { gothrow("race") }
+func raceacquireg(gp *g, addr unsafe.Pointer)                               { gothrow("race") }
+func racerelease(addr unsafe.Pointer)                                       { gothrow("race") }
+func racereleaseg(gp *g, addr unsafe.Pointer)                               { gothrow("race") }
+func racereleasemerge(addr unsafe.Pointer)                                  { gothrow("race") }
+func racereleasemergeg(gp *g, addr unsafe.Pointer)                          { gothrow("race") }
+func racefingo()                                                            { gothrow("race") }
+func racemalloc(p unsafe.Pointer, sz uintptr)                               { gothrow("race") }
+func racegostart(pc uintptr) uintptr                                        { gothrow("race"); return 0 }
+func racegoend()                                                            { gothrow("race") }
diff --git a/src/runtime/race_amd64.s b/src/runtime/race_amd64.s
new file mode 100644
index 0000000..a96d9de
--- /dev/null
+++ b/src/runtime/race_amd64.s
@@ -0,0 +1,414 @@
+// Copyright 2013 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build race
+
+#include "zasm_GOOS_GOARCH.h"
+#include "funcdata.h"
+#include "textflag.h"
+
+// The following thunks allow calling the gcc-compiled race runtime directly
+// from Go code without going all the way through cgo.
+// First, it's much faster (up to 50% speedup for real Go programs).
+// Second, it eliminates race-related special cases from cgocall and scheduler.
+// Third, in long-term it will allow to remove cyclic runtime/race dependency on cmd/go.
+
+// A brief recap of the amd64 calling convention.
+// Arguments are passed in DI, SI, DX, CX, R8, R9, the rest is on stack.
+// Callee-saved registers are: BX, BP, R12-R15.
+// SP must be 16-byte aligned.
+// On Windows:
+// Arguments are passed in CX, DX, R8, R9, the rest is on stack.
+// Callee-saved registers are: BX, BP, DI, SI, R12-R15.
+// SP must be 16-byte aligned. Windows also requires "stack-backing" for the 4 register arguments:
+// http://msdn.microsoft.com/en-us/library/ms235286.aspx
+// We do not do this, because it seems to be intended for vararg/unprototyped functions.
+// Gcc-compiled race runtime does not try to use that space.
+
+#ifdef GOOS_windows
+#define RARG0 CX
+#define RARG1 DX
+#define RARG2 R8
+#define RARG3 R9
+#else
+#define RARG0 DI
+#define RARG1 SI
+#define RARG2 DX
+#define RARG3 CX
+#endif
+
+// func runtime·raceread(addr uintptr)
+// Called from instrumented code.
+TEXT	runtime·raceread(SB), NOSPLIT, $0-8
+	MOVQ	addr+0(FP), RARG1
+	MOVQ	(SP), RARG2
+	// void __tsan_read(ThreadState *thr, void *addr, void *pc);
+	MOVQ	$__tsan_read(SB), AX
+	JMP	racecalladdr<>(SB)
+
+// func runtime·RaceRead(addr uintptr)
+TEXT	runtime·RaceRead(SB), NOSPLIT, $0-8
+	// This needs to be a tail call, because raceread reads caller pc.
+	JMP	runtime·raceread(SB)
+
+// void runtime·racereadpc(void *addr, void *callpc, void *pc)
+TEXT	runtime·racereadpc(SB), NOSPLIT, $0-24
+	MOVQ	addr+0(FP), RARG1
+	MOVQ	callpc+8(FP), RARG2
+	MOVQ	pc+16(FP), RARG3
+	// void __tsan_read_pc(ThreadState *thr, void *addr, void *callpc, void *pc);
+	MOVQ	$__tsan_read_pc(SB), AX
+	JMP	racecalladdr<>(SB)
+
+// func runtime·racewrite(addr uintptr)
+// Called from instrumented code.
+TEXT	runtime·racewrite(SB), NOSPLIT, $0-8
+	MOVQ	addr+0(FP), RARG1
+	MOVQ	(SP), RARG2
+	// void __tsan_write(ThreadState *thr, void *addr, void *pc);
+	MOVQ	$__tsan_write(SB), AX
+	JMP	racecalladdr<>(SB)
+
+// func runtime·RaceWrite(addr uintptr)
+TEXT	runtime·RaceWrite(SB), NOSPLIT, $0-8
+	// This needs to be a tail call, because racewrite reads caller pc.
+	JMP	runtime·racewrite(SB)
+
+// void runtime·racewritepc(void *addr, void *callpc, void *pc)
+TEXT	runtime·racewritepc(SB), NOSPLIT, $0-24
+	MOVQ	addr+0(FP), RARG1
+	MOVQ	callpc+8(FP), RARG2
+	MOVQ	pc+16(FP), RARG3
+	// void __tsan_write_pc(ThreadState *thr, void *addr, void *callpc, void *pc);
+	MOVQ	$__tsan_write_pc(SB), AX
+	JMP	racecalladdr<>(SB)
+
+// func runtime·racereadrange(addr, size uintptr)
+// Called from instrumented code.
+TEXT	runtime·racereadrange(SB), NOSPLIT, $0-16
+	MOVQ	addr+0(FP), RARG1
+	MOVQ	size+8(FP), RARG2
+	MOVQ	(SP), RARG3
+	// void __tsan_read_range(ThreadState *thr, void *addr, uintptr size, void *pc);
+	MOVQ	$__tsan_read_range(SB), AX
+	JMP	racecalladdr<>(SB)
+
+// func runtime·RaceReadRange(addr, size uintptr)
+TEXT	runtime·RaceReadRange(SB), NOSPLIT, $0-16
+	// This needs to be a tail call, because racereadrange reads caller pc.
+	JMP	runtime·racereadrange(SB)
+
+// void runtime·racereadrangepc1(void *addr, uintptr sz, void *pc)
+TEXT	runtime·racereadrangepc1(SB), NOSPLIT, $0-24
+	MOVQ	addr+0(FP), RARG1
+	MOVQ	size+8(FP), RARG2
+	MOVQ	pc+16(FP), RARG3
+	// void __tsan_read_range(ThreadState *thr, void *addr, uintptr size, void *pc);
+	MOVQ	$__tsan_read_range(SB), AX
+	JMP	racecalladdr<>(SB)
+
+// func runtime·racewriterange(addr, size uintptr)
+// Called from instrumented code.
+TEXT	runtime·racewriterange(SB), NOSPLIT, $0-16
+	MOVQ	addr+0(FP), RARG1
+	MOVQ	size+8(FP), RARG2
+	MOVQ	(SP), RARG3
+	// void __tsan_write_range(ThreadState *thr, void *addr, uintptr size, void *pc);
+	MOVQ	$__tsan_write_range(SB), AX
+	JMP	racecalladdr<>(SB)
+
+// func runtime·RaceWriteRange(addr, size uintptr)
+TEXT	runtime·RaceWriteRange(SB), NOSPLIT, $0-16
+	// This needs to be a tail call, because racewriterange reads caller pc.
+	JMP	runtime·racewriterange(SB)
+
+// void runtime·racewriterangepc1(void *addr, uintptr sz, void *pc)
+TEXT	runtime·racewriterangepc1(SB), NOSPLIT, $0-24
+	MOVQ	addr+0(FP), RARG1
+	MOVQ	size+8(FP), RARG2
+	MOVQ	pc+16(FP), RARG3
+	// void __tsan_write_range(ThreadState *thr, void *addr, uintptr size, void *pc);
+	MOVQ	$__tsan_write_range(SB), AX
+	JMP	racecalladdr<>(SB)
+
+// If addr (RARG1) is out of range, do nothing.
+// Otherwise, setup goroutine context and invoke racecall. Other arguments already set.
+TEXT	racecalladdr<>(SB), NOSPLIT, $0-0
+	get_tls(R12)
+	MOVQ	g(R12), R14
+	MOVQ	g_racectx(R14), RARG0	// goroutine context
+	// Check that addr is within [arenastart, arenaend) or within [racedatastart, racedataend).
+	CMPQ	RARG1, runtime·racearenastart(SB)
+	JB	racecalladdr_data
+	CMPQ	RARG1, runtime·racearenaend(SB)
+	JB	racecalladdr_call
+racecalladdr_data:
+	CMPQ	RARG1, runtime·racedatastart(SB)
+	JB	racecalladdr_ret
+	CMPQ	RARG1, runtime·racedataend(SB)
+	JAE	racecalladdr_ret
+racecalladdr_call:
+	MOVQ	AX, AX		// w/o this 6a miscompiles this function
+	JMP	racecall<>(SB)
+racecalladdr_ret:
+	RET
+
+// func runtime·racefuncenter(pc uintptr)
+// Called from instrumented code.
+TEXT	runtime·racefuncenter(SB), NOSPLIT, $0-8
+	MOVQ	DX, R15		// save function entry context (for closures)
+	get_tls(R12)
+	MOVQ	g(R12), R14
+	MOVQ	g_racectx(R14), RARG0	// goroutine context
+	MOVQ	callpc+0(FP), RARG1
+	// void __tsan_func_enter(ThreadState *thr, void *pc);
+	MOVQ	$__tsan_func_enter(SB), AX
+	// racecall<> preserves R15
+	CALL	racecall<>(SB)
+	MOVQ	R15, DX	// restore function entry context
+	RET
+
+// func runtime·racefuncexit()
+// Called from instrumented code.
+TEXT	runtime·racefuncexit(SB), NOSPLIT, $0-0
+	get_tls(R12)
+	MOVQ	g(R12), R14
+	MOVQ	g_racectx(R14), RARG0	// goroutine context
+	// void __tsan_func_exit(ThreadState *thr);
+	MOVQ	$__tsan_func_exit(SB), AX
+	JMP	racecall<>(SB)
+
+// Atomic operations for sync/atomic package.
+
+// Load
+TEXT	sync∕atomic·LoadInt32(SB), NOSPLIT, $0-0
+	MOVQ	$__tsan_go_atomic32_load(SB), AX
+	CALL	racecallatomic<>(SB)
+	RET
+
+TEXT	sync∕atomic·LoadInt64(SB), NOSPLIT, $0-0
+	MOVQ	$__tsan_go_atomic64_load(SB), AX
+	CALL	racecallatomic<>(SB)
+	RET
+
+TEXT	sync∕atomic·LoadUint32(SB), NOSPLIT, $0-0
+	JMP	sync∕atomic·LoadInt32(SB)
+
+TEXT	sync∕atomic·LoadUint64(SB), NOSPLIT, $0-0
+	JMP	sync∕atomic·LoadInt64(SB)
+
+TEXT	sync∕atomic·LoadUintptr(SB), NOSPLIT, $0-0
+	JMP	sync∕atomic·LoadInt64(SB)
+
+TEXT	sync∕atomic·LoadPointer(SB), NOSPLIT, $0-0
+	JMP	sync∕atomic·LoadInt64(SB)
+
+// Store
+TEXT	sync∕atomic·StoreInt32(SB), NOSPLIT, $0-0
+	MOVQ	$__tsan_go_atomic32_store(SB), AX
+	CALL	racecallatomic<>(SB)
+	RET
+
+TEXT	sync∕atomic·StoreInt64(SB), NOSPLIT, $0-0
+	MOVQ	$__tsan_go_atomic64_store(SB), AX
+	CALL	racecallatomic<>(SB)
+	RET
+
+TEXT	sync∕atomic·StoreUint32(SB), NOSPLIT, $0-0
+	JMP	sync∕atomic·StoreInt32(SB)
+
+TEXT	sync∕atomic·StoreUint64(SB), NOSPLIT, $0-0
+	JMP	sync∕atomic·StoreInt64(SB)
+
+TEXT	sync∕atomic·StoreUintptr(SB), NOSPLIT, $0-0
+	JMP	sync∕atomic·StoreInt64(SB)
+
+TEXT	sync∕atomic·StorePointer(SB), NOSPLIT, $0-0
+	JMP	sync∕atomic·StoreInt64(SB)
+
+// Swap
+TEXT	sync∕atomic·SwapInt32(SB), NOSPLIT, $0-0
+	MOVQ	$__tsan_go_atomic32_exchange(SB), AX
+	CALL	racecallatomic<>(SB)
+	RET
+
+TEXT	sync∕atomic·SwapInt64(SB), NOSPLIT, $0-0
+	MOVQ	$__tsan_go_atomic64_exchange(SB), AX
+	CALL	racecallatomic<>(SB)
+	RET
+
+TEXT	sync∕atomic·SwapUint32(SB), NOSPLIT, $0-0
+	JMP	sync∕atomic·SwapInt32(SB)
+
+TEXT	sync∕atomic·SwapUint64(SB), NOSPLIT, $0-0
+	JMP	sync∕atomic·SwapInt64(SB)
+
+TEXT	sync∕atomic·SwapUintptr(SB), NOSPLIT, $0-0
+	JMP	sync∕atomic·SwapInt64(SB)
+
+TEXT	sync∕atomic·SwapPointer(SB), NOSPLIT, $0-0
+	JMP	sync∕atomic·SwapInt64(SB)
+
+// Add
+TEXT	sync∕atomic·AddInt32(SB), NOSPLIT, $0-0
+	MOVQ	$__tsan_go_atomic32_fetch_add(SB), AX
+	CALL	racecallatomic<>(SB)
+	MOVL	add+8(FP), AX	// convert fetch_add to add_fetch
+	ADDL	AX, ret+16(FP)
+	RET
+
+TEXT	sync∕atomic·AddInt64(SB), NOSPLIT, $0-0
+	MOVQ	$__tsan_go_atomic64_fetch_add(SB), AX
+	CALL	racecallatomic<>(SB)
+	MOVQ	add+8(FP), AX	// convert fetch_add to add_fetch
+	ADDQ	AX, ret+16(FP)
+	RET
+
+TEXT	sync∕atomic·AddUint32(SB), NOSPLIT, $0-0
+	JMP	sync∕atomic·AddInt32(SB)
+
+TEXT	sync∕atomic·AddUint64(SB), NOSPLIT, $0-0
+	JMP	sync∕atomic·AddInt64(SB)
+
+TEXT	sync∕atomic·AddUintptr(SB), NOSPLIT, $0-0
+	JMP	sync∕atomic·AddInt64(SB)
+
+TEXT	sync∕atomic·AddPointer(SB), NOSPLIT, $0-0
+	JMP	sync∕atomic·AddInt64(SB)
+
+// CompareAndSwap
+TEXT	sync∕atomic·CompareAndSwapInt32(SB), NOSPLIT, $0-0
+	MOVQ	$__tsan_go_atomic32_compare_exchange(SB), AX
+	CALL	racecallatomic<>(SB)
+	RET
+
+TEXT	sync∕atomic·CompareAndSwapInt64(SB), NOSPLIT, $0-0
+	MOVQ	$__tsan_go_atomic64_compare_exchange(SB), AX
+	CALL	racecallatomic<>(SB)
+	RET
+
+TEXT	sync∕atomic·CompareAndSwapUint32(SB), NOSPLIT, $0-0
+	JMP	sync∕atomic·CompareAndSwapInt32(SB)
+
+TEXT	sync∕atomic·CompareAndSwapUint64(SB), NOSPLIT, $0-0
+	JMP	sync∕atomic·CompareAndSwapInt64(SB)
+
+TEXT	sync∕atomic·CompareAndSwapUintptr(SB), NOSPLIT, $0-0
+	JMP	sync∕atomic·CompareAndSwapInt64(SB)
+
+TEXT	sync∕atomic·CompareAndSwapPointer(SB), NOSPLIT, $0-0
+	JMP	sync∕atomic·CompareAndSwapInt64(SB)
+
+// Generic atomic operation implementation.
+// AX already contains target function.
+TEXT	racecallatomic<>(SB), NOSPLIT, $0-0
+	// Trigger SIGSEGV early.
+	MOVQ	16(SP), R12
+	MOVL	(R12), R13
+	// Check that addr is within [arenastart, arenaend) or within [racedatastart, racedataend).
+	CMPQ	R12, runtime·racearenastart(SB)
+	JB	racecallatomic_data
+	CMPQ	R12, runtime·racearenaend(SB)
+	JB	racecallatomic_ok
+racecallatomic_data:
+	CMPQ	R12, runtime·racedatastart(SB)
+	JB	racecallatomic_ignore
+	CMPQ	R12, runtime·racedataend(SB)
+	JAE	racecallatomic_ignore
+racecallatomic_ok:
+	// Addr is within the good range, call the atomic function.
+	get_tls(R12)
+	MOVQ	g(R12), R14
+	MOVQ	g_racectx(R14), RARG0	// goroutine context
+	MOVQ	8(SP), RARG1	// caller pc
+	MOVQ	(SP), RARG2	// pc
+	LEAQ	16(SP), RARG3	// arguments
+	JMP	racecall<>(SB)	// does not return
+racecallatomic_ignore:
+	// Addr is outside the good range.
+	// Call __tsan_go_ignore_sync_begin to ignore synchronization during the atomic op.
+	// An attempt to synchronize on the address would cause crash.
+	MOVQ	AX, R15	// remember the original function
+	MOVQ	$__tsan_go_ignore_sync_begin(SB), AX
+	MOVQ	g(R12), R14
+	MOVQ	g_racectx(R14), RARG0	// goroutine context
+	CALL	racecall<>(SB)
+	MOVQ	R15, AX	// restore the original function
+	// Call the atomic function.
+	MOVQ	g_racectx(R14), RARG0	// goroutine context
+	MOVQ	8(SP), RARG1	// caller pc
+	MOVQ	(SP), RARG2	// pc
+	LEAQ	16(SP), RARG3	// arguments
+	CALL	racecall<>(SB)
+	// Call __tsan_go_ignore_sync_end.
+	MOVQ	$__tsan_go_ignore_sync_end(SB), AX
+	MOVQ	g_racectx(R14), RARG0	// goroutine context
+	JMP	racecall<>(SB)
+
+// void runtime·racecall(void(*f)(...), ...)
+// Calls C function f from race runtime and passes up to 4 arguments to it.
+// The arguments are never heap-object-preserving pointers, so we pretend there are no arguments.
+TEXT	runtime·racecall(SB), NOSPLIT, $0-0
+	MOVQ	fn+0(FP), AX
+	MOVQ	arg0+8(FP), RARG0
+	MOVQ	arg1+16(FP), RARG1
+	MOVQ	arg2+24(FP), RARG2
+	MOVQ	arg3+32(FP), RARG3
+	JMP	racecall<>(SB)
+
+// Switches SP to g0 stack and calls (AX). Arguments already set.
+TEXT	racecall<>(SB), NOSPLIT, $0-0
+	get_tls(R12)
+	MOVQ	g(R12), R14
+	MOVQ	g_m(R14), R13
+	// Switch to g0 stack.
+	MOVQ	SP, R12		// callee-saved, preserved across the CALL
+	MOVQ	m_g0(R13), R10
+	CMPQ	R10, R14
+	JE	racecall_cont	// already on g0
+	MOVQ	(g_sched+gobuf_sp)(R10), SP
+racecall_cont:
+	ANDQ	$~15, SP	// alignment for gcc ABI
+	CALL	AX
+	MOVQ	R12, SP
+	RET
+
+// C->Go callback thunk that allows to call runtime·racesymbolize from C code.
+// Direct Go->C race call has only switched SP, finish g->g0 switch by setting correct g.
+// The overall effect of Go->C->Go call chain is similar to that of mcall.
+TEXT	runtime·racesymbolizethunk(SB), NOSPLIT, $56-8
+	// Save callee-saved registers (Go code won't respect that).
+	// This is superset of darwin/linux/windows registers.
+	PUSHQ	BX
+	PUSHQ	BP
+	PUSHQ	DI
+	PUSHQ	SI
+	PUSHQ	R12
+	PUSHQ	R13
+	PUSHQ	R14
+	PUSHQ	R15
+	// Set g = g0.
+	get_tls(R12)
+	MOVQ	g(R12), R13
+	MOVQ	g_m(R13), R13
+	MOVQ	m_g0(R13), R14
+	MOVQ	R14, g(R12)	// g = m->g0
+	MOVQ	RARG0, 0(SP)	// func arg
+	CALL	runtime·racesymbolize(SB)
+	// All registers are smashed after Go code, reload.
+	get_tls(R12)
+	MOVQ	g(R12), R13
+	MOVQ	g_m(R13), R13
+	MOVQ	m_curg(R13), R14
+	MOVQ	R14, g(R12)	// g = m->curg
+	// Restore callee-saved registers.
+	POPQ	R15
+	POPQ	R14
+	POPQ	R13
+	POPQ	R12
+	POPQ	SI
+	POPQ	DI
+	POPQ	BP
+	POPQ	BX
+	RET
diff --git a/src/runtime/rdebug.go b/src/runtime/rdebug.go
new file mode 100644
index 0000000..e5e6911
--- /dev/null
+++ b/src/runtime/rdebug.go
@@ -0,0 +1,37 @@
+// 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 runtime
+
+func setMaxStack(in int) (out int) {
+	out = int(maxstacksize)
+	maxstacksize = uintptr(in)
+	return out
+}
+
+func setGCPercent(in int32) (out int32) {
+	mp := acquirem()
+	mp.scalararg[0] = uintptr(int(in))
+	onM(setgcpercent_m)
+	out = int32(int(mp.scalararg[0]))
+	releasem(mp)
+	return out
+}
+
+func setPanicOnFault(new bool) (old bool) {
+	mp := acquirem()
+	old = mp.curg.paniconfault
+	mp.curg.paniconfault = new
+	releasem(mp)
+	return old
+}
+
+func setMaxThreads(in int) (out int) {
+	mp := acquirem()
+	mp.scalararg[0] = uintptr(in)
+	onM(setmaxthreads_m)
+	out = int(mp.scalararg[0])
+	releasem(mp)
+	return out
+}
diff --git a/src/runtime/rt0_android_arm.s b/src/runtime/rt0_android_arm.s
new file mode 100644
index 0000000..6b65fb4
--- /dev/null
+++ b/src/runtime/rt0_android_arm.s
@@ -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.
+
+#include "textflag.h"
+
+TEXT _rt0_arm_android(SB),NOSPLIT,$-4
+	MOVW		(R13), R0      // argc
+	MOVW		$4(R13), R1    // argv
+	MOVW		$_rt0_arm_linux1(SB), R4
+	B		(R4)
diff --git a/src/runtime/rt0_darwin_386.s b/src/runtime/rt0_darwin_386.s
new file mode 100644
index 0000000..4c8c92d
--- /dev/null
+++ b/src/runtime/rt0_darwin_386.s
@@ -0,0 +1,16 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+TEXT _rt0_386_darwin(SB),NOSPLIT,$8
+	MOVL	8(SP), AX
+	LEAL	12(SP), BX
+	MOVL	AX, 0(SP)
+	MOVL	BX, 4(SP)
+	CALL	main(SB)
+	INT	$3
+
+TEXT main(SB),NOSPLIT,$0
+	JMP	runtime·rt0_go(SB)
diff --git a/src/runtime/rt0_darwin_amd64.s b/src/runtime/rt0_darwin_amd64.s
new file mode 100644
index 0000000..452d854
--- /dev/null
+++ b/src/runtime/rt0_darwin_amd64.s
@@ -0,0 +1,15 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+TEXT _rt0_amd64_darwin(SB),NOSPLIT,$-8
+	LEAQ	8(SP), SI // argv
+	MOVQ	0(SP), DI // argc
+	MOVQ	$main(SB), AX
+	JMP	AX
+
+TEXT main(SB),NOSPLIT,$-8
+	MOVQ	$runtime·rt0_go(SB), AX
+	JMP	AX
diff --git a/src/runtime/rt0_dragonfly_386.s b/src/runtime/rt0_dragonfly_386.s
new file mode 100644
index 0000000..548ba79
--- /dev/null
+++ b/src/runtime/rt0_dragonfly_386.s
@@ -0,0 +1,16 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+TEXT _rt0_386_dragonfly(SB),NOSPLIT,$8
+	MOVL	8(SP), AX
+	LEAL	12(SP), BX
+	MOVL	AX, 0(SP)
+	MOVL	BX, 4(SP)
+	CALL	main(SB)
+	INT	$3
+
+TEXT main(SB),NOSPLIT,$0
+	JMP	runtime·rt0_go(SB)
diff --git a/src/runtime/rt0_dragonfly_amd64.s b/src/runtime/rt0_dragonfly_amd64.s
new file mode 100644
index 0000000..fb56618
--- /dev/null
+++ b/src/runtime/rt0_dragonfly_amd64.s
@@ -0,0 +1,15 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+TEXT _rt0_amd64_dragonfly(SB),NOSPLIT,$-8
+	LEAQ	8(DI), SI // argv
+	MOVQ	0(DI), DI // argc
+	MOVQ	$main(SB), AX
+	JMP	AX
+
+TEXT main(SB),NOSPLIT,$-8
+	MOVQ	$runtime·rt0_go(SB), AX
+	JMP	AX
diff --git a/src/runtime/rt0_freebsd_386.s b/src/runtime/rt0_freebsd_386.s
new file mode 100644
index 0000000..cd7a915
--- /dev/null
+++ b/src/runtime/rt0_freebsd_386.s
@@ -0,0 +1,16 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+TEXT _rt0_386_freebsd(SB),NOSPLIT,$8
+	MOVL	8(SP), AX
+	LEAL	12(SP), BX
+	MOVL	AX, 0(SP)
+	MOVL	BX, 4(SP)
+	CALL	main(SB)
+	INT	$3
+
+TEXT main(SB),NOSPLIT,$0
+	JMP	runtime·rt0_go(SB)
diff --git a/src/runtime/rt0_freebsd_amd64.s b/src/runtime/rt0_freebsd_amd64.s
new file mode 100644
index 0000000..7989f7c
--- /dev/null
+++ b/src/runtime/rt0_freebsd_amd64.s
@@ -0,0 +1,15 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+TEXT _rt0_amd64_freebsd(SB),NOSPLIT,$-8
+	LEAQ	8(DI), SI // argv
+	MOVQ	0(DI), DI // argc
+	MOVQ	$main(SB), AX
+	JMP	AX
+
+TEXT main(SB),NOSPLIT,$-8
+	MOVQ	$runtime·rt0_go(SB), AX
+	JMP	AX
diff --git a/src/runtime/rt0_freebsd_arm.s b/src/runtime/rt0_freebsd_arm.s
new file mode 100644
index 0000000..f312526
--- /dev/null
+++ b/src/runtime/rt0_freebsd_arm.s
@@ -0,0 +1,18 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+// FreeBSD and Linux use the same linkage to main
+
+TEXT _rt0_arm_freebsd(SB),NOSPLIT,$-4
+	MOVW	(R13), R0	// argc
+	MOVW	$4(R13), R1		// argv
+	MOVM.DB.W [R0-R1], (R13)
+	B	runtime·rt0_go(SB)
+
+TEXT main(SB),NOSPLIT,$-4
+	MOVM.DB.W [R0-R1], (R13)
+	MOVW	$runtime·rt0_go(SB), R4
+	B		(R4)
diff --git a/src/runtime/rt0_linux_386.s b/src/runtime/rt0_linux_386.s
new file mode 100644
index 0000000..352e594
--- /dev/null
+++ b/src/runtime/rt0_linux_386.s
@@ -0,0 +1,25 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+TEXT _rt0_386_linux(SB),NOSPLIT,$8
+	MOVL	8(SP), AX
+	LEAL	12(SP), BX
+	MOVL	AX, 0(SP)
+	MOVL	BX, 4(SP)
+	CALL	runtime·linux_setup_vdso(SB)
+	CALL	main(SB)
+	INT	$3
+
+TEXT main(SB),NOSPLIT,$0
+	JMP	runtime·rt0_go(SB)
+
+TEXT _fallback_vdso(SB),NOSPLIT,$0
+	INT	$0x80
+	RET
+
+DATA	runtime·_vdso(SB)/4, $_fallback_vdso(SB)
+GLOBL	runtime·_vdso(SB), NOPTR, $4
+
diff --git a/src/runtime/rt0_linux_amd64.s b/src/runtime/rt0_linux_amd64.s
new file mode 100644
index 0000000..985426a
--- /dev/null
+++ b/src/runtime/rt0_linux_amd64.s
@@ -0,0 +1,15 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+TEXT _rt0_amd64_linux(SB),NOSPLIT,$-8
+	LEAQ	8(SP), SI // argv
+	MOVQ	0(SP), DI // argc
+	MOVQ	$main(SB), AX
+	JMP	AX
+
+TEXT main(SB),NOSPLIT,$-8
+	MOVQ	$runtime·rt0_go(SB), AX
+	JMP	AX
diff --git a/src/runtime/rt0_linux_arm.s b/src/runtime/rt0_linux_arm.s
new file mode 100644
index 0000000..5f521d2
--- /dev/null
+++ b/src/runtime/rt0_linux_arm.s
@@ -0,0 +1,91 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+TEXT _rt0_arm_linux(SB),NOSPLIT,$-4
+	MOVW	(R13), R0	// argc
+	MOVW	$4(R13), R1		// argv
+	MOVW	$_rt0_arm_linux1(SB), R4
+	B		(R4)
+
+TEXT _rt0_arm_linux1(SB),NOSPLIT,$-4
+	// We first need to detect the kernel ABI, and warn the user
+	// if the system only supports OABI
+	// The strategy here is to call some EABI syscall to see if
+	// SIGILL is received.
+	// To catch SIGILL, we have to first setup sigaction, this is
+	// a chicken-and-egg problem, because we can't do syscall if
+	// we don't know the kernel ABI... Oh, not really, we can do
+	// syscall in Thumb mode.
+
+	// Save argc and argv
+	MOVM.DB.W [R0-R1], (R13)
+
+	// Thumb mode OABI check disabled because there are some
+	// EABI systems that do not support Thumb execution.
+	// We can run on them except for this check!
+
+	// // set up sa_handler
+	// MOVW	$bad_abi<>(SB), R0 // sa_handler
+	// MOVW	$0, R1 // sa_flags
+	// MOVW	$0, R2 // sa_restorer
+	// MOVW	$0, R3 // sa_mask
+	// MOVM.DB.W [R0-R3], (R13)
+	// MOVW	$4, R0 // SIGILL
+	// MOVW	R13, R1 // sa
+	// SUB	$16, R13
+	// MOVW	R13, R2 // old_sa
+	// MOVW	$8, R3 // c
+	// MOVW	$174, R7 // sys_sigaction
+	// BL	oabi_syscall<>(SB)
+
+	// do an EABI syscall
+	MOVW	$20, R7 // sys_getpid
+	SWI	$0 // this will trigger SIGILL on OABI systems
+	
+	// MOVW	$4, R0  // SIGILL
+	// MOVW	R13, R1 // sa
+	// MOVW	$0, R2 // old_sa
+	// MOVW	$8, R3 // c
+	// MOVW	$174, R7 // sys_sigaction
+	// SWI	$0 // restore signal handler
+	// ADD	$32, R13
+
+	SUB	$4, R13 // fake a stack frame for runtime·setup_auxv
+	BL	runtime·setup_auxv(SB)
+	ADD	$4, R13
+	B	runtime·rt0_go(SB)
+
+TEXT bad_abi<>(SB),NOSPLIT,$-4
+	// give diagnosis and exit
+	MOVW	$2, R0 // stderr
+	MOVW	$bad_abi_msg(SB), R1 // data
+	MOVW	$45, R2 // len
+	MOVW	$4, R7 // sys_write
+	BL	oabi_syscall<>(SB)
+	MOVW	$1, R0
+	MOVW	$1, R7 // sys_exit
+	BL	oabi_syscall<>(SB)
+	B  	0(PC)
+
+DATA bad_abi_msg+0x00(SB)/8, $"This pro"
+DATA bad_abi_msg+0x08(SB)/8, $"gram can"
+DATA bad_abi_msg+0x10(SB)/8, $" only be"
+DATA bad_abi_msg+0x18(SB)/8, $" run on "
+DATA bad_abi_msg+0x20(SB)/8, $"EABI ker"
+DATA bad_abi_msg+0x28(SB)/4, $"nels"
+DATA bad_abi_msg+0x2c(SB)/1, $0xa
+GLOBL bad_abi_msg(SB), RODATA, $45
+
+TEXT oabi_syscall<>(SB),NOSPLIT,$-4
+	ADD $1, PC, R4
+	WORD $0xe12fff14 //BX	(R4) // enter thumb mode
+	// TODO(minux): only supports little-endian CPUs
+	WORD $0x4770df01 // swi $1; bx lr
+
+TEXT main(SB),NOSPLIT,$-4
+	MOVW	$_rt0_arm_linux1(SB), R4
+	B		(R4)
+
diff --git a/src/runtime/rt0_nacl_386.s b/src/runtime/rt0_nacl_386.s
new file mode 100644
index 0000000..d4ba063
--- /dev/null
+++ b/src/runtime/rt0_nacl_386.s
@@ -0,0 +1,22 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+// NaCl entry has:
+//	0(FP) - arg block == SP+8
+//	4(FP) - cleanup function pointer, always 0
+//	8(FP) - envc
+//	12(FP) - argc
+//	16(FP) - argv, then 0, then envv, then 0, then auxv
+TEXT _rt0_386_nacl(SB),NOSPLIT,$8
+	MOVL	argc+12(FP), AX
+	LEAL	argv+16(FP), BX
+	MOVL	AX, 0(SP)
+	MOVL	BX, 4(SP)
+	CALL	main(SB)
+	INT	$3
+
+TEXT main(SB),NOSPLIT,$0
+	JMP	runtime·rt0_go(SB)
diff --git a/src/runtime/rt0_nacl_amd64p32.s b/src/runtime/rt0_nacl_amd64p32.s
new file mode 100644
index 0000000..54e4b1d
--- /dev/null
+++ b/src/runtime/rt0_nacl_amd64p32.s
@@ -0,0 +1,30 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+// NaCl entry on 32-bit x86 has DI pointing at the arg block, which contains:
+//
+//	0(DI) - cleanup function pointer, always 0
+//	4(DI) - envc
+//	8(DI) - argc
+//	12(DI) - argv, then 0, then envv, then 0, then auxv
+// NaCl entry here is almost the same, except that there
+// is no saved caller PC, so 0(FP) is -8(FP) and so on. 
+TEXT _rt0_amd64p32_nacl(SB),NOSPLIT,$16
+	MOVL	DI, 0(SP)
+	CALL	runtime·nacl_sysinfo(SB)
+	MOVL	0(SP), DI
+	MOVL	8(DI), AX
+	LEAL	12(DI), BX
+	MOVL	AX, 0(SP)
+	MOVL	BX, 4(SP)
+	CALL	main(SB)
+	INT	$3
+
+TEXT main(SB),NOSPLIT,$0
+	// Uncomment for fake time like on Go Playground.
+	//MOVQ	$1257894000000000000, AX
+	//MOVQ	AX, runtime·faketime(SB)
+	JMP	runtime·rt0_go(SB)
diff --git a/src/runtime/rt0_nacl_arm.s b/src/runtime/rt0_nacl_arm.s
new file mode 100644
index 0000000..eadb478
--- /dev/null
+++ b/src/runtime/rt0_nacl_arm.s
@@ -0,0 +1,20 @@
+// 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"
+
+// NaCl entry has:
+//	0(FP) - 0
+//	4(FP) - cleanup function pointer, always 0
+//	8(FP) - envc
+//	12(FP) - argc
+//	16(FP) - argv, then 0, then envv, then 0, then auxv
+TEXT _rt0_arm_nacl(SB),NOSPLIT,$-4
+	MOVW	8(R13), R0
+	MOVW	$12(R13), R1
+	MOVM.DB.W [R0-R1], (R13)
+	B	main(SB)
+
+TEXT main(SB),NOSPLIT,$0
+	B	runtime·rt0_go(SB)
diff --git a/src/runtime/rt0_netbsd_386.s b/src/runtime/rt0_netbsd_386.s
new file mode 100644
index 0000000..70b8532
--- /dev/null
+++ b/src/runtime/rt0_netbsd_386.s
@@ -0,0 +1,16 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+TEXT _rt0_386_netbsd(SB),NOSPLIT,$8
+	MOVL	8(SP), AX
+	LEAL	12(SP), BX
+	MOVL	AX, 0(SP)
+	MOVL	BX, 4(SP)
+	CALL	main(SB)
+	INT	$3
+
+TEXT main(SB),NOSPLIT,$0
+	JMP	runtime·rt0_go(SB)
diff --git a/src/runtime/rt0_netbsd_amd64.s b/src/runtime/rt0_netbsd_amd64.s
new file mode 100644
index 0000000..fad5661
--- /dev/null
+++ b/src/runtime/rt0_netbsd_amd64.s
@@ -0,0 +1,15 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+TEXT _rt0_amd64_netbsd(SB),NOSPLIT,$-8
+	LEAQ	8(SP), SI // argv
+	MOVQ	0(SP), DI // argc
+	MOVQ	$main(SB), AX
+	JMP	AX
+
+TEXT main(SB),NOSPLIT,$-8
+	MOVQ	$runtime·rt0_go(SB), AX
+	JMP	AX
diff --git a/src/runtime/rt0_netbsd_arm.s b/src/runtime/rt0_netbsd_arm.s
new file mode 100644
index 0000000..bad66e0
--- /dev/null
+++ b/src/runtime/rt0_netbsd_arm.s
@@ -0,0 +1,13 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+// FreeBSD/NetBSD and Linux use the same linkage to main
+
+TEXT _rt0_arm_netbsd(SB),NOSPLIT,$-4
+	MOVW	(R13), R0	// argc
+	MOVW	$4(R13), R1		// argv
+	MOVM.DB.W [R0-R1], (R13)
+	B runtime·rt0_go(SB)
diff --git a/src/runtime/rt0_openbsd_386.s b/src/runtime/rt0_openbsd_386.s
new file mode 100644
index 0000000..f25d2e1
--- /dev/null
+++ b/src/runtime/rt0_openbsd_386.s
@@ -0,0 +1,16 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+TEXT _rt0_386_openbsd(SB),NOSPLIT,$8
+	MOVL	8(SP), AX
+	LEAL	12(SP), BX
+	MOVL	AX, 0(SP)
+	MOVL	BX, 4(SP)
+	CALL	main(SB)
+	INT	$3
+
+TEXT main(SB),NOSPLIT,$0
+	JMP	runtime·rt0_go(SB)
diff --git a/src/runtime/rt0_openbsd_amd64.s b/src/runtime/rt0_openbsd_amd64.s
new file mode 100644
index 0000000..58fe666
--- /dev/null
+++ b/src/runtime/rt0_openbsd_amd64.s
@@ -0,0 +1,15 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+TEXT _rt0_amd64_openbsd(SB),NOSPLIT,$-8
+	LEAQ	8(SP), SI // argv
+	MOVQ	0(SP), DI // argc
+	MOVQ	$main(SB), AX
+	JMP	AX
+
+TEXT main(SB),NOSPLIT,$-8
+	MOVQ	$runtime·rt0_go(SB), AX
+	JMP	AX
diff --git a/src/runtime/rt0_plan9_386.s b/src/runtime/rt0_plan9_386.s
new file mode 100644
index 0000000..c451299
--- /dev/null
+++ b/src/runtime/rt0_plan9_386.s
@@ -0,0 +1,23 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+TEXT _rt0_386_plan9(SB),NOSPLIT,$12
+	MOVL	AX, _tos(SB)
+	LEAL	8(SP), AX
+	MOVL	AX, _privates(SB)
+	MOVL	$1, _nprivates(SB)
+	CALL	runtime·asminit(SB)
+	MOVL	inargc-4(FP), AX
+	MOVL	AX, 0(SP)
+	LEAL	inargv+0(FP), AX
+	MOVL	AX, 4(SP)
+	CALL	runtime·rt0_go(SB)
+
+DATA  runtime·isplan9(SB)/4, $1
+GLOBL runtime·isplan9(SB), NOPTR, $4
+GLOBL _tos(SB), NOPTR, $4
+GLOBL _privates(SB), NOPTR, $4
+GLOBL _nprivates(SB), NOPTR, $4
diff --git a/src/runtime/rt0_plan9_amd64.s b/src/runtime/rt0_plan9_amd64.s
new file mode 100644
index 0000000..ec2d9ec
--- /dev/null
+++ b/src/runtime/rt0_plan9_amd64.s
@@ -0,0 +1,21 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+TEXT _rt0_amd64_plan9(SB),NOSPLIT,$24
+	MOVQ	AX, _tos(SB)
+	LEAQ	16(SP), AX
+	MOVQ	AX, _privates(SB)
+	MOVL	$1, _nprivates(SB)
+	MOVL	inargc-8(FP), DI
+	LEAQ	inargv+0(FP), SI
+	MOVQ	$runtime·rt0_go(SB), AX
+	JMP	AX
+
+DATA runtime·isplan9(SB)/4, $1
+GLOBL runtime·isplan9(SB), NOPTR, $4
+GLOBL _tos(SB), NOPTR, $8
+GLOBL _privates(SB), NOPTR, $8
+GLOBL _nprivates(SB), NOPTR, $4
diff --git a/src/runtime/rt0_solaris_amd64.s b/src/runtime/rt0_solaris_amd64.s
new file mode 100644
index 0000000..5997cbf
--- /dev/null
+++ b/src/runtime/rt0_solaris_amd64.s
@@ -0,0 +1,18 @@
+// 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"
+
+TEXT _rt0_amd64_solaris(SB),NOSPLIT,$-8
+	LEAQ	8(SP), SI // argv
+	MOVQ	0(SP), DI // argc
+	MOVQ	$main(SB), AX
+	JMP	AX
+
+TEXT main(SB),NOSPLIT,$-8
+	MOVQ	$runtime·rt0_go(SB), AX
+	JMP	AX
+
+DATA runtime·issolaris(SB)/4, $1
+GLOBL runtime·issolaris(SB), NOPTR, $4
diff --git a/src/runtime/rt0_windows_386.s b/src/runtime/rt0_windows_386.s
new file mode 100644
index 0000000..3c2deda
--- /dev/null
+++ b/src/runtime/rt0_windows_386.s
@@ -0,0 +1,20 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+TEXT _rt0_386_windows(SB),NOSPLIT,$12
+	MOVL	12(SP), AX
+	LEAL	16(SP), BX
+	MOVL	AX, 4(SP)
+	MOVL	BX, 8(SP)
+	MOVL	$-1, 0(SP) // return PC for main
+	JMP	main(SB)
+
+TEXT main(SB),NOSPLIT,$0
+	JMP	runtime·rt0_go(SB)
+
+
+DATA  runtime·iswindows(SB)/4, $1
+GLOBL runtime·iswindows(SB), NOPTR, $4
diff --git a/src/runtime/rt0_windows_amd64.s b/src/runtime/rt0_windows_amd64.s
new file mode 100644
index 0000000..197f52e
--- /dev/null
+++ b/src/runtime/rt0_windows_amd64.s
@@ -0,0 +1,19 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "zasm_GOOS_GOARCH.h"
+#include "textflag.h"
+
+TEXT _rt0_amd64_windows(SB),NOSPLIT,$-8
+	LEAQ	8(SP), SI // argv
+	MOVQ	0(SP), DI // argc
+	MOVQ	$main(SB), AX
+	JMP	AX
+
+TEXT main(SB),NOSPLIT,$-8
+	MOVQ	$runtime·rt0_go(SB), AX
+	JMP	AX
+
+DATA  runtime·iswindows(SB)/4, $1
+GLOBL runtime·iswindows(SB), NOPTR, $4
diff --git a/src/runtime/rune.go b/src/runtime/rune.go
new file mode 100644
index 0000000..a9f6835
--- /dev/null
+++ b/src/runtime/rune.go
@@ -0,0 +1,219 @@
+/*
+ * The authors of this software are Rob Pike and Ken Thompson.
+ *              Copyright (c) 2002 by Lucent Technologies.
+ *              Portions Copyright 2009 The Go Authors. All rights reserved.
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose without fee is hereby granted, provided that this entire notice
+ * is included in all copies of any software which is or includes a copy
+ * or modification of this software and in all copies of the supporting
+ * documentation for such software.
+ * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
+ * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
+ * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
+ */
+
+/*
+ * This code is copied, with slight editing due to type differences,
+ * from a subset of ../lib9/utf/rune.c
+ */
+
+package runtime
+
+const (
+	bit1 = 7
+	bitx = 6
+	bit2 = 5
+	bit3 = 4
+	bit4 = 3
+	bit5 = 2
+
+	t1 = ((1 << (bit1 + 1)) - 1) ^ 0xFF /* 0000 0000 */
+	tx = ((1 << (bitx + 1)) - 1) ^ 0xFF /* 1000 0000 */
+	t2 = ((1 << (bit2 + 1)) - 1) ^ 0xFF /* 1100 0000 */
+	t3 = ((1 << (bit3 + 1)) - 1) ^ 0xFF /* 1110 0000 */
+	t4 = ((1 << (bit4 + 1)) - 1) ^ 0xFF /* 1111 0000 */
+	t5 = ((1 << (bit5 + 1)) - 1) ^ 0xFF /* 1111 1000 */
+
+	rune1 = (1 << (bit1 + 0*bitx)) - 1 /* 0000 0000 0111 1111 */
+	rune2 = (1 << (bit2 + 1*bitx)) - 1 /* 0000 0111 1111 1111 */
+	rune3 = (1 << (bit3 + 2*bitx)) - 1 /* 1111 1111 1111 1111 */
+	rune4 = (1 << (bit4 + 3*bitx)) - 1 /* 0001 1111 1111 1111 1111 1111 */
+
+	maskx = (1 << bitx) - 1 /* 0011 1111 */
+	testx = maskx ^ 0xFF    /* 1100 0000 */
+
+	runeerror = 0xFFFD
+	runeself  = 0x80
+
+	surrogateMin = 0xD800
+	surrogateMax = 0xDFFF
+
+	bad = runeerror
+
+	runemax = 0x10FFFF /* maximum rune value */
+)
+
+/*
+ * Modified by Wei-Hwa Huang, Google Inc., on 2004-09-24
+ * This is a slower but "safe" version of the old chartorune
+ * that works on strings that are not necessarily null-terminated.
+ *
+ * If you know for sure that your string is null-terminated,
+ * chartorune will be a bit faster.
+ *
+ * It is guaranteed not to attempt to access "length"
+ * past the incoming pointer.  This is to avoid
+ * possible access violations.  If the string appears to be
+ * well-formed but incomplete (i.e., to get the whole Rune
+ * we'd need to read past str+length) then we'll set the Rune
+ * to Bad and return 0.
+ *
+ * Note that if we have decoding problems for other
+ * reasons, we return 1 instead of 0.
+ */
+func charntorune(s string) (rune, int) {
+	/* When we're not allowed to read anything */
+	if len(s) <= 0 {
+		return bad, 1
+	}
+
+	/*
+	 * one character sequence (7-bit value)
+	 *	00000-0007F => T1
+	 */
+	c := s[0]
+	if c < tx {
+		return rune(c), 1
+	}
+
+	// If we can't read more than one character we must stop
+	if len(s) <= 1 {
+		return bad, 1
+	}
+
+	/*
+	 * two character sequence (11-bit value)
+	 *	0080-07FF => t2 tx
+	 */
+	c1 := s[1] ^ tx
+	if (c1 & testx) != 0 {
+		return bad, 1
+	}
+	if c < t3 {
+		if c < t2 {
+			return bad, 1
+		}
+		l := ((rune(c) << bitx) | rune(c1)) & rune2
+		if l <= rune1 {
+			return bad, 1
+		}
+		return l, 2
+	}
+
+	// If we can't read more than two characters we must stop
+	if len(s) <= 2 {
+		return bad, 1
+	}
+
+	/*
+	 * three character sequence (16-bit value)
+	 *	0800-FFFF => t3 tx tx
+	 */
+	c2 := s[2] ^ tx
+	if (c2 & testx) != 0 {
+		return bad, 1
+	}
+	if c < t4 {
+		l := ((((rune(c) << bitx) | rune(c1)) << bitx) | rune(c2)) & rune3
+		if l <= rune2 {
+			return bad, 1
+		}
+		if surrogateMin <= l && l <= surrogateMax {
+			return bad, 1
+		}
+		return l, 3
+	}
+
+	if len(s) <= 3 {
+		return bad, 1
+	}
+
+	/*
+	 * four character sequence (21-bit value)
+	 *	10000-1FFFFF => t4 tx tx tx
+	 */
+	c3 := s[3] ^ tx
+	if (c3 & testx) != 0 {
+		return bad, 1
+	}
+	if c < t5 {
+		l := ((((((rune(c) << bitx) | rune(c1)) << bitx) | rune(c2)) << bitx) | rune(c3)) & rune4
+		if l <= rune3 || l > runemax {
+			return bad, 1
+		}
+		return l, 4
+	}
+
+	// Support for 5-byte or longer UTF-8 would go here, but
+	// since we don't have that, we'll just return bad.
+	return bad, 1
+}
+
+// runetochar converts r to bytes and writes the result to str.
+// returns the number of bytes generated.
+func runetochar(str []byte, r rune) int {
+	/* runes are signed, so convert to unsigned for range check. */
+	c := uint32(r)
+	/*
+	 * one character sequence
+	 *	00000-0007F => 00-7F
+	 */
+	if c <= rune1 {
+		str[0] = byte(c)
+		return 1
+	}
+	/*
+	 * two character sequence
+	 *	0080-07FF => t2 tx
+	 */
+	if c <= rune2 {
+		str[0] = byte(t2 | (c >> (1 * bitx)))
+		str[1] = byte(tx | (c & maskx))
+		return 2
+	}
+
+	/*
+	 * If the rune is out of range or a surrogate half, convert it to the error rune.
+	 * Do this test here because the error rune encodes to three bytes.
+	 * Doing it earlier would duplicate work, since an out of range
+	 * rune wouldn't have fit in one or two bytes.
+	 */
+	if c > runemax {
+		c = runeerror
+	}
+	if surrogateMin <= c && c <= surrogateMax {
+		c = runeerror
+	}
+
+	/*
+	 * three character sequence
+	 *	0800-FFFF => t3 tx tx
+	 */
+	if c <= rune3 {
+		str[0] = byte(t3 | (c >> (2 * bitx)))
+		str[1] = byte(tx | ((c >> (1 * bitx)) & maskx))
+		str[2] = byte(tx | (c & maskx))
+		return 3
+	}
+
+	/*
+	 * four character sequence (21-bit value)
+	 *     10000-1FFFFF => t4 tx tx tx
+	 */
+	str[0] = byte(t4 | (c >> (3 * bitx)))
+	str[1] = byte(tx | ((c >> (2 * bitx)) & maskx))
+	str[2] = byte(tx | ((c >> (1 * bitx)) & maskx))
+	str[3] = byte(tx | (c & maskx))
+	return 4
+}
diff --git a/src/pkg/runtime/runtime-gdb.py b/src/runtime/runtime-gdb.py
similarity index 100%
rename from src/pkg/runtime/runtime-gdb.py
rename to src/runtime/runtime-gdb.py
diff --git a/src/runtime/runtime.c b/src/runtime/runtime.c
new file mode 100644
index 0000000..c823691
--- /dev/null
+++ b/src/runtime/runtime.c
@@ -0,0 +1,399 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "runtime.h"
+#include "stack.h"
+#include "arch_GOARCH.h"
+#include "textflag.h"
+#include "malloc.h"
+
+// Keep a cached value to make gotraceback fast,
+// since we call it on every call to gentraceback.
+// The cached value is a uint32 in which the low bit
+// is the "crash" setting and the top 31 bits are the
+// gotraceback value.
+static uint32 traceback_cache = 2<<1;
+
+// The GOTRACEBACK environment variable controls the
+// behavior of a Go program that is crashing and exiting.
+//	GOTRACEBACK=0   suppress all tracebacks
+//	GOTRACEBACK=1   default behavior - show tracebacks but exclude runtime frames
+//	GOTRACEBACK=2   show tracebacks including runtime frames
+//	GOTRACEBACK=crash   show tracebacks including runtime frames, then crash (core dump etc)
+#pragma textflag NOSPLIT
+int32
+runtime·gotraceback(bool *crash)
+{
+	if(crash != nil)
+		*crash = false;
+	if(g->m->traceback != 0)
+		return g->m->traceback;
+	if(crash != nil)
+		*crash = traceback_cache&1;
+	return traceback_cache>>1;
+}
+
+int32
+runtime·mcmp(byte *s1, byte *s2, uintptr n)
+{
+	uintptr i;
+	byte c1, c2;
+
+	for(i=0; i<n; i++) {
+		c1 = s1[i];
+		c2 = s2[i];
+		if(c1 < c2)
+			return -1;
+		if(c1 > c2)
+			return +1;
+	}
+	return 0;
+}
+
+
+byte*
+runtime·mchr(byte *p, byte c, byte *ep)
+{
+	for(; p < ep; p++)
+		if(*p == c)
+			return p;
+	return nil;
+}
+
+static int32	argc;
+
+#pragma dataflag NOPTR /* argv not a heap pointer */
+static uint8**	argv;
+
+extern Slice runtime·argslice;
+extern Slice runtime·envs;
+
+void (*runtime·sysargs)(int32, uint8**);
+
+void
+runtime·args(int32 c, uint8 **v)
+{
+	argc = c;
+	argv = v;
+	if(runtime·sysargs != nil)
+		runtime·sysargs(c, v);
+}
+
+int32 runtime·isplan9;
+int32 runtime·issolaris;
+int32 runtime·iswindows;
+
+// Information about what cpu features are available.
+// Set on startup in asm_{x86/amd64}.s.
+uint32 runtime·cpuid_ecx;
+uint32 runtime·cpuid_edx;
+
+void
+runtime·goargs(void)
+{
+	String *s;
+	int32 i;
+
+	// for windows implementation see "os" package
+	if(Windows)
+		return;
+
+	runtime·argslice = runtime·makeStringSlice(argc);
+	s = (String*)runtime·argslice.array;
+	for(i=0; i<argc; i++)
+		s[i] = runtime·gostringnocopy(argv[i]);
+}
+
+void
+runtime·goenvs_unix(void)
+{
+	String *s;
+	int32 i, n;
+
+	for(n=0; argv[argc+1+n] != 0; n++)
+		;
+
+	runtime·envs = runtime·makeStringSlice(n);
+	s = (String*)runtime·envs.array;
+	for(i=0; i<n; i++)
+		s[i] = runtime·gostringnocopy(argv[argc+1+i]);
+}
+
+#pragma textflag NOSPLIT
+Slice
+runtime·environ()
+{
+	return runtime·envs;
+}
+
+int32
+runtime·atoi(byte *p)
+{
+	int32 n;
+
+	n = 0;
+	while('0' <= *p && *p <= '9')
+		n = n*10 + *p++ - '0';
+	return n;
+}
+
+static void
+TestAtomic64(void)
+{
+	uint64 z64, x64;
+
+	z64 = 42;
+	x64 = 0;
+	PREFETCH(&z64);
+	if(runtime·cas64(&z64, x64, 1))
+		runtime·throw("cas64 failed");
+	if(x64 != 0)
+		runtime·throw("cas64 failed");
+	x64 = 42;
+	if(!runtime·cas64(&z64, x64, 1))
+		runtime·throw("cas64 failed");
+	if(x64 != 42 || z64 != 1)
+		runtime·throw("cas64 failed");
+	if(runtime·atomicload64(&z64) != 1)
+		runtime·throw("load64 failed");
+	runtime·atomicstore64(&z64, (1ull<<40)+1);
+	if(runtime·atomicload64(&z64) != (1ull<<40)+1)
+		runtime·throw("store64 failed");
+	if(runtime·xadd64(&z64, (1ull<<40)+1) != (2ull<<40)+2)
+		runtime·throw("xadd64 failed");
+	if(runtime·atomicload64(&z64) != (2ull<<40)+2)
+		runtime·throw("xadd64 failed");
+	if(runtime·xchg64(&z64, (3ull<<40)+3) != (2ull<<40)+2)
+		runtime·throw("xchg64 failed");
+	if(runtime·atomicload64(&z64) != (3ull<<40)+3)
+		runtime·throw("xchg64 failed");
+}
+
+void
+runtime·check(void)
+{
+	int8 a;
+	uint8 b;
+	int16 c;
+	uint16 d;
+	int32 e;
+	uint32 f;
+	int64 g;
+	uint64 h;
+	float32 i, i1;
+	float64 j, j1;
+	byte *k, *k1;
+	uint16* l;
+	struct x1 {
+		byte x;
+	};
+	struct y1 {
+		struct x1 x1;
+		byte y;
+	};
+
+	if(sizeof(a) != 1) runtime·throw("bad a");
+	if(sizeof(b) != 1) runtime·throw("bad b");
+	if(sizeof(c) != 2) runtime·throw("bad c");
+	if(sizeof(d) != 2) runtime·throw("bad d");
+	if(sizeof(e) != 4) runtime·throw("bad e");
+	if(sizeof(f) != 4) runtime·throw("bad f");
+	if(sizeof(g) != 8) runtime·throw("bad g");
+	if(sizeof(h) != 8) runtime·throw("bad h");
+	if(sizeof(i) != 4) runtime·throw("bad i");
+	if(sizeof(j) != 8) runtime·throw("bad j");
+	if(sizeof(k) != sizeof(uintptr)) runtime·throw("bad k");
+	if(sizeof(l) != sizeof(uintptr)) runtime·throw("bad l");
+	if(sizeof(struct x1) != 1) runtime·throw("bad sizeof x1");
+	if(offsetof(struct y1, y) != 1) runtime·throw("bad offsetof y1.y");
+	if(sizeof(struct y1) != 2) runtime·throw("bad sizeof y1");
+
+	if(runtime·timediv(12345LL*1000000000+54321, 1000000000, &e) != 12345 || e != 54321)
+		runtime·throw("bad timediv");
+
+	uint32 z;
+	z = 1;
+	if(!runtime·cas(&z, 1, 2))
+		runtime·throw("cas1");
+	if(z != 2)
+		runtime·throw("cas2");
+
+	z = 4;
+	if(runtime·cas(&z, 5, 6))
+		runtime·throw("cas3");
+	if(z != 4)
+		runtime·throw("cas4");
+
+	k = (byte*)0xfedcb123;
+	if(sizeof(void*) == 8)
+		k = (byte*)((uintptr)k<<10);
+	if(runtime·casp((void**)&k, nil, nil))
+		runtime·throw("casp1");
+	k1 = k+1;
+	if(!runtime·casp((void**)&k, k, k1))
+		runtime·throw("casp2");
+	if(k != k1)
+		runtime·throw("casp3");
+
+	*(uint64*)&j = ~0ULL;
+	if(j == j)
+		runtime·throw("float64nan");
+	if(!(j != j))
+		runtime·throw("float64nan1");
+
+	*(uint64*)&j1 = ~1ULL;
+	if(j == j1)
+		runtime·throw("float64nan2");
+	if(!(j != j1))
+		runtime·throw("float64nan3");
+
+	*(uint32*)&i = ~0UL;
+	if(i == i)
+		runtime·throw("float32nan");
+	if(!(i != i))
+		runtime·throw("float32nan1");
+
+	*(uint32*)&i1 = ~1UL;
+	if(i == i1)
+		runtime·throw("float32nan2");
+	if(!(i != i1))
+		runtime·throw("float32nan3");
+
+	TestAtomic64();
+
+	if(FixedStack != runtime·round2(FixedStack))
+		runtime·throw("FixedStack is not power-of-2");
+}
+
+#pragma dataflag NOPTR
+DebugVars	runtime·debug;
+
+typedef struct DbgVar DbgVar;
+struct DbgVar
+{
+	int8*	name;
+	int32*	value;
+};
+
+// Do we report invalid pointers found during stack or heap scans?
+int32 runtime·invalidptr = 1;
+
+#pragma dataflag NOPTR /* dbgvar has no heap pointers */
+static DbgVar dbgvar[] = {
+	{"allocfreetrace", &runtime·debug.allocfreetrace},
+	{"invalidptr", &runtime·invalidptr},
+	{"efence", &runtime·debug.efence},
+	{"gctrace", &runtime·debug.gctrace},
+	{"gcdead", &runtime·debug.gcdead},
+	{"scheddetail", &runtime·debug.scheddetail},
+	{"schedtrace", &runtime·debug.schedtrace},
+	{"scavenge", &runtime·debug.scavenge},
+};
+
+void
+runtime·parsedebugvars(void)
+{
+	byte *p;
+	intgo i, n;
+
+	p = runtime·getenv("GODEBUG");
+	if(p != nil){
+		for(;;) {
+			for(i=0; i<nelem(dbgvar); i++) {
+				n = runtime·findnull((byte*)dbgvar[i].name);
+				if(runtime·mcmp(p, (byte*)dbgvar[i].name, n) == 0 && p[n] == '=')
+					*dbgvar[i].value = runtime·atoi(p+n+1);
+			}
+			p = runtime·strstr(p, (byte*)",");
+			if(p == nil)
+				break;
+			p++;
+		}
+	}
+
+	p = runtime·getenv("GOTRACEBACK");
+	if(p == nil)
+		p = (byte*)"";
+	if(p[0] == '\0')
+		traceback_cache = 1<<1;
+	else if(runtime·strcmp(p, (byte*)"crash") == 0)
+		traceback_cache = (2<<1) | 1;
+	else
+		traceback_cache = runtime·atoi(p)<<1;	
+}
+
+// Poor mans 64-bit division.
+// This is a very special function, do not use it if you are not sure what you are doing.
+// int64 division is lowered into _divv() call on 386, which does not fit into nosplit functions.
+// Handles overflow in a time-specific manner.
+#pragma textflag NOSPLIT
+int32
+runtime·timediv(int64 v, int32 div, int32 *rem)
+{
+	int32 res, bit;
+
+	res = 0;
+	for(bit = 30; bit >= 0; bit--) {
+		if(v >= ((int64)div<<bit)) {
+			v = v - ((int64)div<<bit);
+			res += 1<<bit;
+		}
+	}
+	if(v >= (int64)div) {
+		if(rem != nil)
+			*rem = 0;
+		return 0x7fffffff;
+	}
+	if(rem != nil)
+		*rem = v;
+	return res;
+}
+
+// Helpers for Go. Must be NOSPLIT, must only call NOSPLIT functions, and must not block.
+
+#pragma textflag NOSPLIT
+G*
+runtime·getg(void)
+{
+	return g;
+}
+
+#pragma textflag NOSPLIT
+M*
+runtime·acquirem(void)
+{
+	g->m->locks++;
+	return g->m;
+}
+
+#pragma textflag NOSPLIT
+void
+runtime·releasem(M *mp)
+{
+	mp->locks--;
+	if(mp->locks == 0 && g->preempt) {
+		// restore the preemption request in case we've cleared it in newstack
+		g->stackguard0 = StackPreempt;
+	}
+}
+
+#pragma textflag NOSPLIT
+MCache*
+runtime·gomcache(void)
+{
+	return g->m->mcache;
+}
+
+#pragma textflag NOSPLIT
+Slice
+reflect·typelinks(void)
+{
+	extern Type *runtime·typelink[], *runtime·etypelink[];
+	Slice ret;
+
+	ret.array = (byte*)runtime·typelink;
+	ret.len = runtime·etypelink - runtime·typelink;
+	ret.cap = ret.len;
+	return ret;
+}
diff --git a/src/runtime/runtime.go b/src/runtime/runtime.go
new file mode 100644
index 0000000..4e4e1d1
--- /dev/null
+++ b/src/runtime/runtime.go
@@ -0,0 +1,60 @@
+// Copyright 2009 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package runtime
+
+var ticks struct {
+	lock mutex
+	val  uint64
+}
+
+var tls0 [8]uintptr // available storage for m0's TLS; not necessarily used; opaque to GC
+
+// Note: Called by runtime/pprof in addition to runtime code.
+func tickspersecond() int64 {
+	r := int64(atomicload64(&ticks.val))
+	if r != 0 {
+		return r
+	}
+	lock(&ticks.lock)
+	r = int64(ticks.val)
+	if r == 0 {
+		t0 := nanotime()
+		c0 := cputicks()
+		usleep(100 * 1000)
+		t1 := nanotime()
+		c1 := cputicks()
+		if t1 == t0 {
+			t1++
+		}
+		r = (c1 - c0) * 1000 * 1000 * 1000 / (t1 - t0)
+		if r == 0 {
+			r++
+		}
+		atomicstore64(&ticks.val, uint64(r))
+	}
+	unlock(&ticks.lock)
+	return r
+}
+
+func makeStringSlice(n int) []string {
+	return make([]string, n)
+}
+
+// TODO: Move to parfor.go when parfor.c becomes parfor.go.
+func parforalloc(nthrmax uint32) *parfor {
+	return &parfor{
+		thr:     &make([]parforthread, nthrmax)[0],
+		nthrmax: nthrmax,
+	}
+}
+
+var envs []string
+var argslice []string
+
+// called from syscall
+func runtime_envs() []string { return envs }
+
+// called from os
+func runtime_args() []string { return argslice }
diff --git a/src/runtime/runtime.h b/src/runtime/runtime.h
new file mode 100644
index 0000000..177a128
--- /dev/null
+++ b/src/runtime/runtime.h
@@ -0,0 +1,1132 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+/*
+ * basic types
+ */
+typedef	signed char		int8;
+typedef	unsigned char		uint8;
+typedef	signed short		int16;
+typedef	unsigned short		uint16;
+typedef	signed int		int32;
+typedef	unsigned int		uint32;
+typedef	signed long long int	int64;
+typedef	unsigned long long int	uint64;
+typedef	float			float32;
+typedef	double			float64;
+
+#ifdef _64BIT
+typedef	uint64		uintptr;
+typedef	int64		intptr;
+typedef	int64		intgo; // Go's int
+typedef	uint64		uintgo; // Go's uint
+#else
+typedef	uint32		uintptr;
+typedef	int32		intptr;
+typedef	int32		intgo; // Go's int
+typedef	uint32		uintgo; // Go's uint
+#endif
+
+#ifdef _64BITREG
+typedef	uint64		uintreg;
+#else
+typedef	uint32		uintreg;
+#endif
+
+/*
+ * get rid of C types
+ * the / / / forces a syntax error immediately,
+ * which will show "last name: XXunsigned".
+ */
+#define	unsigned		XXunsigned / / /
+#define	signed			XXsigned / / /
+#define	char			XXchar / / /
+#define	short			XXshort / / /
+#define	int			XXint / / /
+#define	long			XXlong / / /
+#define	float			XXfloat / / /
+#define	double			XXdouble / / /
+
+/*
+ * defined types
+ */
+typedef	uint8			bool;
+typedef	uint8			byte;
+typedef	struct	Func		Func;
+typedef	struct	G		G;
+typedef	struct	Gobuf		Gobuf;
+typedef	struct	SudoG		SudoG;
+typedef	struct	Mutex		Mutex;
+typedef	struct	M		M;
+typedef	struct	P		P;
+typedef	struct	SchedT	SchedT;
+typedef	struct	Note		Note;
+typedef	struct	Slice		Slice;
+typedef	struct	String		String;
+typedef	struct	FuncVal		FuncVal;
+typedef	struct	SigTab		SigTab;
+typedef	struct	MCache		MCache;
+typedef	struct	FixAlloc	FixAlloc;
+typedef	struct	Iface		Iface;
+typedef	struct	Itab		Itab;
+typedef	struct	InterfaceType	InterfaceType;
+typedef	struct	Eface		Eface;
+typedef	struct	Type		Type;
+typedef	struct	PtrType		PtrType;
+typedef	struct	ChanType	ChanType;
+typedef	struct	MapType		MapType;
+typedef	struct	Defer		Defer;
+typedef	struct	Panic		Panic;
+typedef	struct	Hmap		Hmap;
+typedef	struct	Hiter		Hiter;
+typedef	struct	Hchan		Hchan;
+typedef	struct	Complex64	Complex64;
+typedef	struct	Complex128	Complex128;
+typedef	struct	LibCall		LibCall;
+typedef	struct	WinCallbackContext	WinCallbackContext;
+typedef	struct	GCStats		GCStats;
+typedef	struct	LFNode		LFNode;
+typedef	struct	ParFor		ParFor;
+typedef	struct	ParForThread	ParForThread;
+typedef	struct	CgoMal		CgoMal;
+typedef	struct	PollDesc	PollDesc;
+typedef	struct	DebugVars	DebugVars;
+typedef	struct	ForceGCState	ForceGCState;
+typedef	struct	Stack		Stack;
+
+/*
+ * Per-CPU declaration.
+ *
+ * "extern register" is a special storage class implemented by 6c, 8c, etc.
+ * On the ARM, it is an actual register; elsewhere it is a slot in thread-
+ * local storage indexed by a pseudo-register TLS. See zasmhdr in
+ * src/cmd/dist/buildruntime.c for details, and be aware that the linker may
+ * make further OS-specific changes to the compiler's output. For example,
+ * 6l/linux rewrites 0(TLS) as -8(FS).
+ *
+ * Every C file linked into a Go program must include runtime.h so that the
+ * C compiler (6c, 8c, etc.) knows to avoid other uses of these dedicated
+ * registers. The Go compiler (6g, 8g, etc.) knows to avoid them.
+ */
+extern	register	G*	g;
+
+/*
+ * defined constants
+ */
+enum
+{
+	// G status
+	//
+	// If you add to this list, add to the list
+	// of "okay during garbage collection" status
+	// in mgc0.c too.
+	Gidle,                                 // 0
+	Grunnable,                             // 1 runnable and on a run queue
+	Grunning,                              // 2
+	Gsyscall,                              // 3
+	Gwaiting,                              // 4
+	Gmoribund_unused,                      // 5 currently unused, but hardcoded in gdb scripts
+	Gdead,                                 // 6
+	Genqueue,                              // 7 Only the Gscanenqueue is used.
+	Gcopystack,                            // 8 in this state when newstack is moving the stack
+	// the following encode that the GC is scanning the stack and what to do when it is done 
+	Gscan = 0x1000,                        // atomicstatus&~Gscan = the non-scan state,
+	// Gscanidle =     Gscan + Gidle,      // Not used. Gidle only used with newly malloced gs
+	Gscanrunnable = Gscan + Grunnable,     //  0x1001 When scanning complets make Grunnable (it is already on run queue)
+	Gscanrunning =  Gscan + Grunning,      //  0x1002 Used to tell preemption newstack routine to scan preempted stack.
+	Gscansyscall =  Gscan + Gsyscall,      //  0x1003 When scanning completes make is Gsyscall
+	Gscanwaiting =  Gscan + Gwaiting,      //  0x1004 When scanning completes make it Gwaiting
+	// Gscanmoribund_unused,               //  not possible
+	// Gscandead,                          //  not possible
+	Gscanenqueue = Gscan + Genqueue,       //  When scanning completes make it Grunnable and put on runqueue
+};
+enum
+{
+	// P status
+	Pidle,
+	Prunning,
+	Psyscall,
+	Pgcstop,
+	Pdead,
+};
+enum
+{
+	true	= 1,
+	false	= 0,
+};
+enum
+{
+	PtrSize = sizeof(void*),
+};
+/*
+ * structures
+ */
+struct	Mutex
+{
+	// Futex-based impl treats it as uint32 key,
+	// while sema-based impl as M* waitm.
+	// Used to be a union, but unions break precise GC.
+	uintptr	key;
+};
+struct	Note
+{
+	// Futex-based impl treats it as uint32 key,
+	// while sema-based impl as M* waitm.
+	// Used to be a union, but unions break precise GC.
+	uintptr	key;
+};
+struct String
+{
+	byte*	str;
+	intgo	len;
+};
+struct FuncVal
+{
+	void	(*fn)(void);
+	// variable-size, fn-specific data here
+};
+struct Iface
+{
+	Itab*	tab;
+	void*	data;
+};
+struct Eface
+{
+	Type*	type;
+	void*	data;
+};
+struct Complex64
+{
+	float32	real;
+	float32	imag;
+};
+struct Complex128
+{
+	float64	real;
+	float64	imag;
+};
+
+struct	Slice
+{				// must not move anything
+	byte*	array;		// actual data
+	uintgo	len;		// number of elements
+	uintgo	cap;		// allocated number of elements
+};
+struct	Gobuf
+{
+	// The offsets of sp, pc, and g are known to (hard-coded in) libmach.
+	uintptr	sp;
+	uintptr	pc;
+	G*	g;
+	void*	ctxt; // this has to be a pointer so that GC scans it
+	uintreg	ret;
+	uintptr	lr;
+};
+// Known to compiler.
+// Changes here must also be made in src/cmd/gc/select.c's selecttype.
+struct	SudoG
+{
+	G*	g;
+	uint32*	selectdone;
+	SudoG*	next;
+	SudoG*	prev;
+	void*	elem;		// data element
+	int64	releasetime;
+	int32	nrelease;	// -1 for acquire
+	SudoG*	waitlink;	// G.waiting list
+};
+struct	GCStats
+{
+	// the struct must consist of only uint64's,
+	// because it is casted to uint64[].
+	uint64	nhandoff;
+	uint64	nhandoffcnt;
+	uint64	nprocyield;
+	uint64	nosyield;
+	uint64	nsleep;
+};
+
+struct	LibCall
+{
+	uintptr	fn;
+	uintptr	n;	// number of parameters
+	uintptr	args;	// parameters
+	uintptr	r1;	// return values
+	uintptr	r2;
+	uintptr	err;	// error number
+};
+
+// describes how to handle callback
+struct	WinCallbackContext
+{
+	void*	gobody;		// Go function to call
+	uintptr	argsize;	// callback arguments size (in bytes)
+	uintptr	restorestack;	// adjust stack on return by (in bytes) (386 only)
+	bool	cleanstack;
+};
+
+// Stack describes a Go execution stack.
+// The bounds of the stack are exactly [lo, hi),
+// with no implicit data structures on either side.
+struct	Stack
+{
+	uintptr	lo;
+	uintptr	hi;
+};
+
+struct	G
+{
+	// Stack parameters.
+	// stack describes the actual stack memory: [stack.lo, stack.hi).
+	// stackguard0 is the stack pointer compared in the Go stack growth prologue.
+	// It is stack.lo+StackGuard normally, but can be StackPreempt to trigger a preemption.
+	// stackguard1 is the stack pointer compared in the C stack growth prologue.
+	// It is stack.lo+StackGuard on g0 and gsignal stacks.
+	// It is ~0 on other goroutine stacks, to trigger a call to morestackc (and crash).
+	Stack	stack;	// offset known to runtime/cgo
+	uintptr	stackguard0;	// offset known to liblink
+	uintptr	stackguard1;	// offset known to liblink
+
+	Panic*	panic;	// innermost panic - offset known to liblink
+	Defer*	defer;	// innermost defer
+	Gobuf	sched;
+	uintptr	syscallsp;	// if status==Gsyscall, syscallsp = sched.sp to use during gc
+	uintptr	syscallpc;	// if status==Gsyscall, syscallpc = sched.pc to use during gc
+	void*	param;		// passed parameter on wakeup
+	uint32	atomicstatus;
+	int64	goid;
+	int64	waitsince;	// approx time when the G become blocked
+	String	waitreason;	// if status==Gwaiting
+	G*	schedlink;
+	bool	issystem;	// do not output in stack dump, ignore in deadlock detector
+	bool	preempt;	// preemption signal, duplicates stackguard0 = StackPreempt
+	bool	paniconfault;	// panic (instead of crash) on unexpected fault address
+	bool	preemptscan;    // preempted g does scan for GC
+	bool	gcworkdone;     // debug: cleared at begining of gc work phase cycle, set by gcphasework, tested at end of cycle
+	bool	throwsplit; // must not split stack
+	int8	raceignore;	// ignore race detection events
+	M*	m;		// for debuggers, but offset not hard-coded
+	M*	lockedm;
+	int32	sig;
+	Slice	writebuf;
+	uintptr	sigcode0;
+	uintptr	sigcode1;
+	uintptr	sigpc;
+	uintptr	gopc;		// pc of go statement that created this goroutine
+	uintptr	racectx;
+	SudoG*	waiting;	// sudog structures this G is waiting on (that have a valid elem ptr)
+	uintptr	end[];
+};
+
+struct	M
+{
+	G*	g0;		// goroutine with scheduling stack
+	Gobuf	morebuf;	// gobuf arg to morestack
+
+	// Fields not known to debuggers.
+	uint64	procid;		// for debuggers, but offset not hard-coded
+	G*	gsignal;	// signal-handling G
+	uintptr	tls[4];		// thread-local storage (for x86 extern register)
+	void	(*mstartfn)(void);
+	G*	curg;		// current running goroutine
+	G*	caughtsig;	// goroutine running during fatal signal
+	P*	p;		// attached P for executing Go code (nil if not executing Go code)
+	P*	nextp;
+	int32	id;
+	int32	mallocing;
+	int32	throwing;
+	int32	gcing;
+	int32	locks;
+	int32	softfloat;
+	int32	dying;
+	int32	profilehz;
+	int32	helpgc;
+	bool	spinning;	// M is out of work and is actively looking for work
+	bool	blocked;	// M is blocked on a Note
+	uint32	fastrand;
+	uint64	ncgocall;	// number of cgo calls in total
+	int32	ncgo;		// number of cgo calls currently in progress
+	CgoMal*	cgomal;
+	Note	park;
+	M*	alllink;	// on allm
+	M*	schedlink;
+	uint32	machport;	// Return address for Mach IPC (OS X)
+	MCache*	mcache;
+	G*	lockedg;
+	uintptr	createstack[32];// Stack that created this thread.
+	uint32	freglo[16];	// D[i] lsb and F[i]
+	uint32	freghi[16];	// D[i] msb and F[i+16]
+	uint32	fflag;		// floating point compare flags
+	uint32	locked;		// tracking for LockOSThread
+	M*	nextwaitm;	// next M waiting for lock
+	uintptr	waitsema;	// semaphore for parking on locks
+	uint32	waitsemacount;
+	uint32	waitsemalock;
+	GCStats	gcstats;
+	bool	needextram;
+	uint8	traceback;
+	bool	(*waitunlockf)(G*, void*);
+	void*	waitlock;
+	uintptr scalararg[4];	// scalar argument/return for mcall
+	void*   ptrarg[4];	// pointer argument/return for mcall
+#ifdef GOOS_windows
+	uintptr	thread;		// thread handle
+	// these are here because they are too large to be on the stack
+	// of low-level NOSPLIT functions.
+	LibCall	libcall;
+	uintptr	libcallpc;	// for cpu profiler
+	uintptr	libcallsp;
+	G*	libcallg;
+#endif
+#ifdef GOOS_solaris
+	int32*	perrno; 	// pointer to TLS errno
+	// these are here because they are too large to be on the stack
+	// of low-level NOSPLIT functions.
+	LibCall	libcall;
+	struct MTs {
+		int64	tv_sec;
+		int64	tv_nsec;
+	} ts;
+	struct MScratch {
+		uintptr v[6];
+	} scratch;
+#endif
+#ifdef GOOS_plan9
+	int8*	notesig;
+	byte*	errstr;
+#endif
+	uintptr	end[];
+};
+
+struct P
+{
+	Mutex	lock;
+
+	int32	id;
+	uint32	status;		// one of Pidle/Prunning/...
+	P*	link;
+	uint32	schedtick;	// incremented on every scheduler call
+	uint32	syscalltick;	// incremented on every system call
+	M*	m;		// back-link to associated M (nil if idle)
+	MCache*	mcache;
+	Defer*	deferpool[5];	// pool of available Defer structs of different sizes (see panic.c)
+
+	// Cache of goroutine ids, amortizes accesses to runtime·sched.goidgen.
+	uint64	goidcache;
+	uint64	goidcacheend;
+
+	// Queue of runnable goroutines.
+	uint32	runqhead;
+	uint32	runqtail;
+	G*	runq[256];
+
+	// Available G's (status == Gdead)
+	G*	gfree;
+	int32	gfreecnt;
+
+	byte	pad[64];
+};
+
+enum {
+	// The max value of GOMAXPROCS.
+	// There are no fundamental restrictions on the value.
+	MaxGomaxprocs = 1<<8,
+};
+
+struct	SchedT
+{
+	Mutex	lock;
+
+	uint64	goidgen;
+
+	M*	midle;	 // idle m's waiting for work
+	int32	nmidle;	 // number of idle m's waiting for work
+	int32	nmidlelocked; // number of locked m's waiting for work
+	int32	mcount;	 // number of m's that have been created
+	int32	maxmcount;	// maximum number of m's allowed (or die)
+
+	P*	pidle;  // idle P's
+	uint32	npidle;
+	uint32	nmspinning;
+
+	// Global runnable queue.
+	G*	runqhead;
+	G*	runqtail;
+	int32	runqsize;
+
+	// Global cache of dead G's.
+	Mutex	gflock;
+	G*	gfree;
+	int32	ngfree;
+
+	uint32	gcwaiting;	// gc is waiting to run
+	int32	stopwait;
+	Note	stopnote;
+	uint32	sysmonwait;
+	Note	sysmonnote;
+	uint64	lastpoll;
+
+	int32	profilehz;	// cpu profiling rate
+};
+
+// The m->locked word holds two pieces of state counting active calls to LockOSThread/lockOSThread.
+// The low bit (LockExternal) is a boolean reporting whether any LockOSThread call is active.
+// External locks are not recursive; a second lock is silently ignored.
+// The upper bits of m->lockedcount record the nesting depth of calls to lockOSThread
+// (counting up by LockInternal), popped by unlockOSThread (counting down by LockInternal).
+// Internal locks can be recursive. For instance, a lock for cgo can occur while the main
+// goroutine is holding the lock during the initialization phase.
+enum
+{
+	LockExternal = 1,
+	LockInternal = 2,
+};
+
+struct	SigTab
+{
+	int32	flags;
+	int8	*name;
+};
+enum
+{
+	SigNotify = 1<<0,	// let signal.Notify have signal, even if from kernel
+	SigKill = 1<<1,		// if signal.Notify doesn't take it, exit quietly
+	SigThrow = 1<<2,	// if signal.Notify doesn't take it, exit loudly
+	SigPanic = 1<<3,	// if the signal is from the kernel, panic
+	SigDefault = 1<<4,	// if the signal isn't explicitly requested, don't monitor it
+	SigHandling = 1<<5,	// our signal handler is registered
+	SigIgnored = 1<<6,	// the signal was ignored before we registered for it
+	SigGoExit = 1<<7,	// cause all runtime procs to exit (only used on Plan 9).
+};
+
+// Layout of in-memory per-function information prepared by linker
+// See http://golang.org/s/go12symtab.
+// Keep in sync with linker and with ../../libmach/sym.c
+// and with package debug/gosym and with symtab.go in package runtime.
+struct	Func
+{
+	uintptr	entry;	// start pc
+	int32	nameoff;// function name
+	
+	int32	args;	// in/out args size
+	int32	frame;	// legacy frame size; use pcsp if possible
+
+	int32	pcsp;
+	int32	pcfile;
+	int32	pcln;
+	int32	npcdata;
+	int32	nfuncdata;
+};
+
+// layout of Itab known to compilers
+// allocated in non-garbage-collected memory
+struct	Itab
+{
+	InterfaceType*	inter;
+	Type*	type;
+	Itab*	link;
+	int32	bad;
+	int32	unused;
+	void	(*fun[])(void);
+};
+
+#ifdef GOOS_nacl
+enum {
+   NaCl = 1,
+};
+#else
+enum {
+   NaCl = 0,
+};
+#endif
+
+#ifdef GOOS_windows
+enum {
+   Windows = 1
+};
+#else
+enum {
+   Windows = 0
+};
+#endif
+#ifdef GOOS_solaris
+enum {
+   Solaris = 1
+};
+#else
+enum {
+   Solaris = 0
+};
+#endif
+#ifdef GOOS_plan9
+enum {
+   Plan9 = 1
+};
+#else
+enum {
+   Plan9 = 0
+};
+#endif
+
+// Lock-free stack node.
+struct LFNode
+{
+	LFNode	*next;
+	uintptr	pushcnt;
+};
+
+// Parallel for descriptor.
+struct ParFor
+{
+	void (*body)(ParFor*, uint32);	// executed for each element
+	uint32 done;			// number of idle threads
+	uint32 nthr;			// total number of threads
+	uint32 nthrmax;			// maximum number of threads
+	uint32 thrseq;			// thread id sequencer
+	uint32 cnt;			// iteration space [0, cnt)
+	void *ctx;			// arbitrary user context
+	bool wait;			// if true, wait while all threads finish processing,
+					// otherwise parfor may return while other threads are still working
+	ParForThread *thr;		// array of thread descriptors
+	uint32 pad;			// to align ParForThread.pos for 64-bit atomic operations
+	// stats
+	uint64 nsteal;
+	uint64 nstealcnt;
+	uint64 nprocyield;
+	uint64 nosyield;
+	uint64 nsleep;
+};
+
+// Track memory allocated by code not written in Go during a cgo call,
+// so that the garbage collector can see them.
+struct CgoMal
+{
+	CgoMal	*next;
+	void	*alloc;
+};
+
+// Holds variables parsed from GODEBUG env var.
+struct DebugVars
+{
+	int32	allocfreetrace;
+	int32	efence;
+	int32	gctrace;
+	int32	gcdead;
+	int32	scheddetail;
+	int32	schedtrace;
+	int32	scavenge;
+};
+
+// Indicates to write barrier and sychronization task to preform.
+enum
+{                   // Synchronization            Write barrier
+	GCoff,      // stop and start             nop
+	GCquiesce,  // stop and start             nop
+	GCstw,      // stop the ps                nop
+	GCmark,     // scan the stacks and start  no white to black
+	GCsweep,    // stop and start             nop
+};
+
+struct ForceGCState
+{
+	Mutex	lock;
+	G*	g;
+	uint32	idle;
+};
+
+extern uint32 runtime·gcphase;
+
+/*
+ * defined macros
+ *    you need super-gopher-guru privilege
+ *    to add this list.
+ */
+#define	nelem(x)	(sizeof(x)/sizeof((x)[0]))
+#define	nil		((void*)0)
+#define	offsetof(s,m)	(uint32)(&(((s*)0)->m))
+#define	ROUND(x, n)	(((x)+(n)-1)&~(uintptr)((n)-1)) /* all-caps to mark as macro: it evaluates n twice */
+
+/*
+ * known to compiler
+ */
+enum {
+	Structrnd = sizeof(uintreg),
+};
+
+byte*	runtime·startup_random_data;
+uint32	runtime·startup_random_data_len;
+
+int32	runtime·invalidptr;
+
+enum {
+	// hashinit wants this many random bytes
+	HashRandomBytes = 32
+};
+
+uint32  runtime·readgstatus(G*);
+void    runtime·casgstatus(G*, uint32, uint32);
+void    runtime·casgstatus(G*, uint32, uint32);
+uint32	runtime·casgcopystack(G*);
+void    runtime·quiesce(G*);
+bool    runtime·stopg(G*);
+void    runtime·restartg(G*);
+void    runtime·gcphasework(G*);
+
+/*
+ * deferred subroutine calls
+ */
+struct Defer
+{
+	int32	siz;
+	bool	started;
+	uintptr	argp;		// where args were copied from
+	uintptr	pc;
+	FuncVal*	fn;
+	Panic*	panic;	// panic that is running defer
+	Defer*	link;
+};
+
+// argp used in Defer structs when there is no argp.
+#define NoArgs ((uintptr)-1)
+
+/*
+ * panics
+ */
+struct Panic
+{
+	void*	argp;	// pointer to arguments of deferred call run during panic; cannot move - known to liblink
+	Eface	arg;		// argument to panic
+	Panic*	link;		// link to earlier panic
+	bool	recovered;	// whether this panic is over
+	bool	aborted;	// the panic was aborted
+};
+
+/*
+ * stack traces
+ */
+typedef struct Stkframe Stkframe;
+typedef struct BitVector BitVector;
+struct Stkframe
+{
+	Func*	fn;	// function being run
+	uintptr	pc;	// program counter within fn
+	uintptr	continpc;	// program counter where execution can continue, or 0 if not
+	uintptr	lr;	// program counter at caller aka link register
+	uintptr	sp;	// stack pointer at pc
+	uintptr	fp;	// stack pointer at caller aka frame pointer
+	uintptr	varp;	// top of local variables
+	uintptr	argp;	// pointer to function arguments
+	uintptr	arglen;	// number of bytes at argp
+	BitVector*	argmap;	// force use of this argmap
+};
+
+enum
+{
+	TraceRuntimeFrames = 1<<0, // include frames for internal runtime functions.
+	TraceTrap = 1<<1, // the initial PC, SP are from a trap, not a return PC from a call
+};
+intgo	runtime·gentraceback(uintptr, uintptr, uintptr, G*, intgo, uintptr*, intgo, bool(**)(Stkframe*, void*), void*, uintgo);
+void	runtime·tracebackdefers(G*, bool(**)(Stkframe*, void*), void*);
+void	runtime·traceback(uintptr pc, uintptr sp, uintptr lr, G* gp);
+void	runtime·tracebacktrap(uintptr pc, uintptr sp, uintptr lr, G* gp);
+void	runtime·tracebackothers(G*);
+bool	runtime·haszeroargs(uintptr pc);
+bool	runtime·topofstack(Func*);
+enum
+{
+	// The maximum number of frames we print for a traceback
+	TracebackMaxFrames = 100,
+};
+
+/*
+ * external data
+ */
+extern	String	runtime·emptystring;
+extern	G**	runtime·allg;
+extern	Slice	runtime·allgs; // []*G
+extern	uintptr runtime·allglen;
+extern	G*	runtime·lastg;
+extern	M*	runtime·allm;
+extern	P*	runtime·allp[MaxGomaxprocs+1];
+extern	int32	runtime·gomaxprocs;
+extern	uint32	runtime·needextram;
+extern	uint32	runtime·panicking;
+extern	int8*	runtime·goos;
+extern	int32	runtime·ncpu;
+extern	bool	runtime·iscgo;
+extern 	void	(*runtime·sysargs)(int32, uint8**);
+extern	uintptr	runtime·maxstring;
+extern	uint32	runtime·cpuid_ecx;
+extern	uint32	runtime·cpuid_edx;
+extern	DebugVars	runtime·debug;
+extern	uintptr	runtime·maxstacksize;
+extern	Note	runtime·signote;
+extern	ForceGCState	runtime·forcegc;
+extern	SchedT	runtime·sched;
+extern	int32		runtime·newprocs;
+
+/*
+ * common functions and data
+ */
+int32	runtime·strcmp(byte*, byte*);
+int32	runtime·strncmp(byte*, byte*, uintptr);
+byte*	runtime·strstr(byte*, byte*);
+intgo	runtime·findnull(byte*);
+intgo	runtime·findnullw(uint16*);
+void	runtime·dump(byte*, int32);
+int32	runtime·runetochar(byte*, int32);
+int32	runtime·charntorune(int32*, uint8*, int32);
+
+
+/*
+ * This macro is used when writing C functions
+ * called as if they were Go functions.
+ * Passed the address of a result before a return statement,
+ * it makes sure the result has been flushed to memory
+ * before the return.
+ *
+ * It is difficult to write such functions portably, because
+ * of the varying requirements on the alignment of the
+ * first output value. Almost all code should write such
+ * functions in .goc files, where goc2c (part of cmd/dist)
+ * can arrange the correct alignment for the target system.
+ * Goc2c also takes care of conveying to the garbage collector
+ * which parts of the argument list are inputs vs outputs.
+ *
+ * Therefore, do NOT use this macro if at all possible.
+ */ 
+#define FLUSH(x)	USED(x)
+
+/*
+ * GoOutput is a type with the same alignment requirements as the
+ * initial output argument from a Go function. Only for use in cases
+ * where using goc2c is not possible. See comment on FLUSH above.
+ */
+typedef uint64 GoOutput;
+
+void	runtime·gogo(Gobuf*);
+void	runtime·gostartcall(Gobuf*, void(*)(void), void*);
+void	runtime·gostartcallfn(Gobuf*, FuncVal*);
+void	runtime·gosave(Gobuf*);
+void	runtime·goargs(void);
+void	runtime·goenvs(void);
+void	runtime·goenvs_unix(void);
+void*	runtime·getu(void);
+void	runtime·throw(int8*);
+bool	runtime·canpanic(G*);
+void	runtime·prints(int8*);
+void	runtime·printf(int8*, ...);
+void	runtime·snprintf(byte*, int32, int8*, ...);
+byte*	runtime·mchr(byte*, byte, byte*);
+int32	runtime·mcmp(byte*, byte*, uintptr);
+void	runtime·memmove(void*, void*, uintptr);
+String	runtime·catstring(String, String);
+String	runtime·gostring(byte*);
+Slice	runtime·makeStringSlice(intgo);
+String  runtime·gostringn(byte*, intgo);
+Slice	runtime·gobytes(byte*, intgo);
+String	runtime·gostringnocopy(byte*);
+String	runtime·gostringw(uint16*);
+void	runtime·initsig(void);
+void	runtime·sigenable(uint32 sig);
+void	runtime·sigdisable(uint32 sig);
+int32	runtime·gotraceback(bool *crash);
+void	runtime·goroutineheader(G*);
+int32	runtime·open(int8*, int32, int32);
+int32	runtime·read(int32, void*, int32);
+int32	runtime·write(uintptr, void*, int32); // use uintptr to accommodate windows.
+int32	runtime·close(int32);
+int32	runtime·mincore(void*, uintptr, byte*);
+void	runtime·jmpdefer(FuncVal*, uintptr);
+void	runtime·exit1(int32);
+void	runtime·ready(G*);
+byte*	runtime·getenv(int8*);
+int32	runtime·atoi(byte*);
+void	runtime·newosproc(M *mp, void *stk);
+void	runtime·mstart(void);
+G*	runtime·malg(int32);
+void	runtime·asminit(void);
+void	runtime·mpreinit(M*);
+void	runtime·minit(void);
+void	runtime·unminit(void);
+void	runtime·signalstack(byte*, int32);
+void	runtime·tracebackinit(void);
+void	runtime·symtabinit(void);
+Func*	runtime·findfunc(uintptr);
+int32	runtime·funcline(Func*, uintptr, String*);
+int32	runtime·funcspdelta(Func*, uintptr);
+int8*	runtime·funcname(Func*);
+int32	runtime·pcdatavalue(Func*, int32, uintptr);
+void	runtime·stackinit(void);
+Stack	runtime·stackalloc(uint32);
+void	runtime·stackfree(Stack);
+void	runtime·shrinkstack(G*);
+void	runtime·shrinkfinish(void);
+MCache*	runtime·allocmcache(void);
+void	runtime·freemcache(MCache*);
+void	runtime·mallocinit(void);
+void	runtime·gcinit(void);
+void*	runtime·mallocgc(uintptr size, Type* typ, uint32 flag);
+void	runtime·runpanic(Panic*);
+uintptr	runtime·getcallersp(void*);
+int32	runtime·mcount(void);
+int32	runtime·gcount(void);
+void	runtime·mcall(void(**)(G*));
+void	runtime·onM(void(**)(void));
+void	runtime·onMsignal(void(**)(void));
+uint32	runtime·fastrand1(void);
+void	runtime·rewindmorestack(Gobuf*);
+int32	runtime·timediv(int64, int32, int32*);
+int32	runtime·round2(int32 x); // round x up to a power of 2.
+
+// atomic operations
+bool	runtime·cas(uint32*, uint32, uint32);
+bool	runtime·cas64(uint64*, uint64, uint64);
+bool	runtime·casp(void**, void*, void*);
+// Don't confuse with XADD x86 instruction,
+// this one is actually 'addx', that is, add-and-fetch.
+uint32	runtime·xadd(uint32 volatile*, int32);
+uint64	runtime·xadd64(uint64 volatile*, int64);
+uint32	runtime·xchg(uint32 volatile*, uint32);
+uint64	runtime·xchg64(uint64 volatile*, uint64);
+void*	runtime·xchgp(void* volatile*, void*);
+uint32	runtime·atomicload(uint32 volatile*);
+void	runtime·atomicstore(uint32 volatile*, uint32);
+void	runtime·atomicstore64(uint64 volatile*, uint64);
+uint64	runtime·atomicload64(uint64 volatile*);
+void*	runtime·atomicloadp(void* volatile*);
+uintptr	runtime·atomicloaduintptr(uintptr volatile*);
+void	runtime·atomicstorep(void* volatile*, void*);
+void	runtime·atomicstoreuintptr(uintptr volatile*, uintptr);
+void	runtime·atomicor8(byte volatile*, byte);
+
+void	runtime·setg(G*);
+void	runtime·newextram(void);
+void	runtime·exit(int32);
+void	runtime·breakpoint(void);
+void	runtime·gosched_m(G*);
+void	runtime·schedtrace(bool);
+void	runtime·park(bool(*)(G*, void*), void*, String);
+void	runtime·parkunlock(Mutex*, String);
+void	runtime·tsleep(int64, String);
+M*	runtime·newm(void);
+void	runtime·goexit(void);
+void	runtime·asmcgocall(void (*fn)(void*), void*);
+int32	runtime·asmcgocall_errno(void (*fn)(void*), void*);
+void	runtime·entersyscall(void);
+void	runtime·reentersyscall(uintptr, uintptr);
+void	runtime·entersyscallblock(void);
+void	runtime·exitsyscall(void);
+G*	runtime·newproc1(FuncVal*, byte*, int32, int32, void*);
+bool	runtime·sigsend(int32 sig);
+intgo	runtime·callers(intgo, uintptr*, intgo);
+intgo	runtime·gcallers(G*, intgo, uintptr*, intgo);
+int64	runtime·nanotime(void);	// monotonic time
+int64	runtime·unixnanotime(void); // real time, can skip
+void	runtime·dopanic(int32);
+void	runtime·startpanic(void);
+void	runtime·freezetheworld(void);
+void	runtime·sigprof(uint8 *pc, uint8 *sp, uint8 *lr, G *gp, M *mp);
+void	runtime·resetcpuprofiler(int32);
+void	runtime·setcpuprofilerate(int32);
+void	runtime·usleep(uint32);
+int64	runtime·cputicks(void);
+int64	runtime·tickspersecond(void);
+void	runtime·blockevent(int64, intgo);
+G*	runtime·netpoll(bool);
+void	runtime·netpollready(G**, PollDesc*, int32);
+uintptr	runtime·netpollfd(PollDesc*);
+void**	runtime·netpolluser(PollDesc*);
+bool	runtime·netpollclosing(PollDesc*);
+void	runtime·netpolllock(PollDesc*);
+void	runtime·netpollunlock(PollDesc*);
+void	runtime·crash(void);
+void	runtime·parsedebugvars(void);
+void*	runtime·funcdata(Func*, int32);
+void	runtime·setmaxthreads_m(void);
+G*	runtime·timejump(void);
+void	runtime·iterate_itabs(void (**callback)(Itab*));
+void	runtime·iterate_finq(void (*callback)(FuncVal*, byte*, uintptr, Type*, PtrType*));
+
+#pragma	varargck	argpos	runtime·printf	1
+#pragma	varargck	type	"c"	int32
+#pragma	varargck	type	"d"	int32
+#pragma	varargck	type	"d"	uint32
+#pragma	varargck	type	"D"	int64
+#pragma	varargck	type	"D"	uint64
+#pragma	varargck	type	"x"	int32
+#pragma	varargck	type	"x"	uint32
+#pragma	varargck	type	"X"	int64
+#pragma	varargck	type	"X"	uint64
+#pragma	varargck	type	"p"	void*
+#pragma	varargck	type	"p"	uintptr
+#pragma	varargck	type	"s"	int8*
+#pragma	varargck	type	"s"	uint8*
+#pragma	varargck	type	"S"	String
+
+void	runtime·stoptheworld(void);
+void	runtime·starttheworld(void);
+extern uint32 runtime·worldsema;
+
+/*
+ * mutual exclusion locks.  in the uncontended case,
+ * as fast as spin locks (just a few user-level instructions),
+ * but on the contention path they sleep in the kernel.
+ * a zeroed Mutex is unlocked (no need to initialize each lock).
+ */
+void	runtime·lock(Mutex*);
+void	runtime·unlock(Mutex*);
+
+/*
+ * sleep and wakeup on one-time events.
+ * before any calls to notesleep or notewakeup,
+ * must call noteclear to initialize the Note.
+ * then, exactly one thread can call notesleep
+ * and exactly one thread can call notewakeup (once).
+ * once notewakeup has been called, the notesleep
+ * will return.  future notesleep will return immediately.
+ * subsequent noteclear must be called only after
+ * previous notesleep has returned, e.g. it's disallowed
+ * to call noteclear straight after notewakeup.
+ *
+ * notetsleep is like notesleep but wakes up after
+ * a given number of nanoseconds even if the event
+ * has not yet happened.  if a goroutine uses notetsleep to
+ * wake up early, it must wait to call noteclear until it
+ * can be sure that no other goroutine is calling
+ * notewakeup.
+ *
+ * notesleep/notetsleep are generally called on g0,
+ * notetsleepg is similar to notetsleep but is called on user g.
+ */
+void	runtime·noteclear(Note*);
+void	runtime·notesleep(Note*);
+void	runtime·notewakeup(Note*);
+bool	runtime·notetsleep(Note*, int64);  // false - timeout
+bool	runtime·notetsleepg(Note*, int64);  // false - timeout
+
+/*
+ * low-level synchronization for implementing the above
+ */
+uintptr	runtime·semacreate(void);
+int32	runtime·semasleep(int64);
+void	runtime·semawakeup(M*);
+// or
+void	runtime·futexsleep(uint32*, uint32, int64);
+void	runtime·futexwakeup(uint32*, uint32);
+
+/*
+ * Mutex-free stack.
+ * Initialize uint64 head to 0, compare with 0 to test for emptiness.
+ * The stack does not keep pointers to nodes,
+ * so they can be garbage collected if there are no other pointers to nodes.
+ */
+void	runtime·lfstackpush(uint64 *head, LFNode *node);
+LFNode*	runtime·lfstackpop(uint64 *head);
+
+/*
+ * Parallel for over [0, n).
+ * body() is executed for each iteration.
+ * nthr - total number of worker threads.
+ * ctx - arbitrary user context.
+ * if wait=true, threads return from parfor() when all work is done;
+ * otherwise, threads can return while other threads are still finishing processing.
+ */
+ParFor*	runtime·parforalloc(uint32 nthrmax);
+void	runtime·parforsetup(ParFor *desc, uint32 nthr, uint32 n, void *ctx, bool wait, void (*body)(ParFor*, uint32));
+void	runtime·parfordo(ParFor *desc);
+void	runtime·parforiters(ParFor*, uintptr, uintptr*, uintptr*);
+
+/*
+ * low level C-called
+ */
+// for mmap, we only pass the lower 32 bits of file offset to the 
+// assembly routine; the higher bits (if required), should be provided
+// by the assembly routine as 0.
+uint8*	runtime·mmap(byte*, uintptr, int32, int32, int32, uint32);
+void	runtime·munmap(byte*, uintptr);
+void	runtime·madvise(byte*, uintptr, int32);
+void	runtime·memclr(byte*, uintptr);
+void	runtime·setcallerpc(void*, void*);
+void*	runtime·getcallerpc(void*);
+void	runtime·printbool(bool);
+void	runtime·printbyte(int8);
+void	runtime·printfloat(float64);
+void	runtime·printint(int64);
+void	runtime·printiface(Iface);
+void	runtime·printeface(Eface);
+void	runtime·printstring(String);
+void	runtime·printpc(void*);
+void	runtime·printpointer(void*);
+void	runtime·printuint(uint64);
+void	runtime·printhex(uint64);
+void	runtime·printslice(Slice);
+void	runtime·printcomplex(Complex128);
+
+/*
+ * runtime go-called
+ */
+void	runtime·gopanic(Eface);
+void	runtime·panicindex(void);
+void	runtime·panicslice(void);
+void	runtime·panicdivide(void);
+
+/*
+ * runtime c-called (but written in Go)
+ */
+void	runtime·printany(Eface);
+void	runtime·newTypeAssertionError(String*, String*, String*, String*, Eface*);
+void	runtime·fadd64c(uint64, uint64, uint64*);
+void	runtime·fsub64c(uint64, uint64, uint64*);
+void	runtime·fmul64c(uint64, uint64, uint64*);
+void	runtime·fdiv64c(uint64, uint64, uint64*);
+void	runtime·fneg64c(uint64, uint64*);
+void	runtime·f32to64c(uint32, uint64*);
+void	runtime·f64to32c(uint64, uint32*);
+void	runtime·fcmp64c(uint64, uint64, int32*, bool*);
+void	runtime·fintto64c(int64, uint64*);
+void	runtime·f64tointc(uint64, int64*, bool*);
+
+/*
+ * wrapped for go users
+ */
+float64	runtime·Inf(int32 sign);
+float64	runtime·NaN(void);
+float32	runtime·float32frombits(uint32 i);
+uint32	runtime·float32tobits(float32 f);
+float64	runtime·float64frombits(uint64 i);
+uint64	runtime·float64tobits(float64 f);
+float64	runtime·frexp(float64 d, int32 *ep);
+bool	runtime·isInf(float64 f, int32 sign);
+bool	runtime·isNaN(float64 f);
+float64	runtime·ldexp(float64 d, int32 e);
+float64	runtime·modf(float64 d, float64 *ip);
+void	runtime·semacquire(uint32*, bool);
+void	runtime·semrelease(uint32*);
+int32	runtime·gomaxprocsfunc(int32 n);
+void	runtime·procyield(uint32);
+void	runtime·osyield(void);
+void	runtime·lockOSThread(void);
+void	runtime·unlockOSThread(void);
+
+bool	runtime·showframe(Func*, G*);
+void	runtime·printcreatedby(G*);
+
+void	runtime·ifaceE2I(InterfaceType*, Eface, Iface*);
+bool	runtime·ifaceE2I2(InterfaceType*, Eface, Iface*);
+uintptr	runtime·memlimit(void);
+
+// float.c
+extern float64 runtime·nan;
+extern float64 runtime·posinf;
+extern float64 runtime·neginf;
+extern uint64 ·nan;
+extern uint64 ·posinf;
+extern uint64 ·neginf;
+#define ISNAN(f) ((f) != (f))
+
+enum
+{
+	UseSpanType = 1,
+};
diff --git a/src/pkg/runtime/runtime_linux_test.go b/src/runtime/runtime_linux_test.go
similarity index 100%
rename from src/pkg/runtime/runtime_linux_test.go
rename to src/runtime/runtime_linux_test.go
diff --git a/src/runtime/runtime_test.go b/src/runtime/runtime_test.go
new file mode 100644
index 0000000..1688364
--- /dev/null
+++ b/src/runtime/runtime_test.go
@@ -0,0 +1,249 @@
+// Copyright 2012 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package runtime_test
+
+import (
+	"io"
+	"io/ioutil"
+	"os"
+	"os/exec"
+	. "runtime"
+	"runtime/debug"
+	"strconv"
+	"strings"
+	"testing"
+	"unsafe"
+)
+
+var errf error
+
+func errfn() error {
+	return errf
+}
+
+func errfn1() error {
+	return io.EOF
+}
+
+func BenchmarkIfaceCmp100(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		for j := 0; j < 100; j++ {
+			if errfn() == io.EOF {
+				b.Fatal("bad comparison")
+			}
+		}
+	}
+}
+
+func BenchmarkIfaceCmpNil100(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		for j := 0; j < 100; j++ {
+			if errfn1() == nil {
+				b.Fatal("bad comparison")
+			}
+		}
+	}
+}
+
+func BenchmarkDefer(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		defer1()
+	}
+}
+
+func defer1() {
+	defer func(x, y, z int) {
+		if recover() != nil || x != 1 || y != 2 || z != 3 {
+			panic("bad recover")
+		}
+	}(1, 2, 3)
+	return
+}
+
+func BenchmarkDefer10(b *testing.B) {
+	for i := 0; i < b.N/10; i++ {
+		defer2()
+	}
+}
+
+func defer2() {
+	for i := 0; i < 10; i++ {
+		defer func(x, y, z int) {
+			if recover() != nil || x != 1 || y != 2 || z != 3 {
+				panic("bad recover")
+			}
+		}(1, 2, 3)
+	}
+}
+
+func BenchmarkDeferMany(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		defer func(x, y, z int) {
+			if recover() != nil || x != 1 || y != 2 || z != 3 {
+				panic("bad recover")
+			}
+		}(1, 2, 3)
+	}
+}
+
+// The profiling signal handler needs to know whether it is executing runtime.gogo.
+// The constant RuntimeGogoBytes in arch_*.h gives the size of the function;
+// we don't have a way to obtain it from the linker (perhaps someday).
+// Test that the constant matches the size determined by 'go tool nm -S'.
+// The value reported will include the padding between runtime.gogo and the
+// next function in memory. That's fine.
+func TestRuntimeGogoBytes(t *testing.T) {
+	switch GOOS {
+	case "android", "nacl":
+		t.Skipf("skipping on %s", GOOS)
+	}
+
+	dir, err := ioutil.TempDir("", "go-build")
+	if err != nil {
+		t.Fatalf("failed to create temp directory: %v", err)
+	}
+	defer os.RemoveAll(dir)
+
+	out, err := exec.Command("go", "build", "-o", dir+"/hello", "../../test/helloworld.go").CombinedOutput()
+	if err != nil {
+		t.Fatalf("building hello world: %v\n%s", err, out)
+	}
+
+	out, err = exec.Command("go", "tool", "nm", "-size", dir+"/hello").CombinedOutput()
+	if err != nil {
+		t.Fatalf("go tool nm: %v\n%s", err, out)
+	}
+
+	for _, line := range strings.Split(string(out), "\n") {
+		f := strings.Fields(line)
+		if len(f) == 4 && f[3] == "runtime.gogo" {
+			size, _ := strconv.Atoi(f[1])
+			if GogoBytes() != int32(size) {
+				t.Fatalf("RuntimeGogoBytes = %d, should be %d", GogoBytes(), size)
+			}
+			return
+		}
+	}
+
+	t.Fatalf("go tool nm did not report size for runtime.gogo")
+}
+
+// golang.org/issue/7063
+func TestStopCPUProfilingWithProfilerOff(t *testing.T) {
+	SetCPUProfileRate(0)
+}
+
+// Addresses to test for faulting behavior.
+// This is less a test of SetPanicOnFault and more a check that
+// the operating system and the runtime can process these faults
+// correctly. That is, we're indirectly testing that without SetPanicOnFault
+// these would manage to turn into ordinary crashes.
+// Note that these are truncated on 32-bit systems, so the bottom 32 bits
+// of the larger addresses must themselves be invalid addresses.
+// We might get unlucky and the OS might have mapped one of these
+// addresses, but probably not: they're all in the first page, very high
+// adderesses that normally an OS would reserve for itself, or malformed
+// addresses. Even so, we might have to remove one or two on different
+// systems. We will see.
+
+var faultAddrs = []uint64{
+	// low addresses
+	0,
+	1,
+	0xfff,
+	// high (kernel) addresses
+	// or else malformed.
+	0xffffffffffffffff,
+	0xfffffffffffff001,
+	0xffffffffffff0001,
+	0xfffffffffff00001,
+	0xffffffffff000001,
+	0xfffffffff0000001,
+	0xffffffff00000001,
+	0xfffffff000000001,
+	0xffffff0000000001,
+	0xfffff00000000001,
+	0xffff000000000001,
+	0xfff0000000000001,
+	0xff00000000000001,
+	0xf000000000000001,
+	0x8000000000000001,
+}
+
+func TestSetPanicOnFault(t *testing.T) {
+	// This currently results in a fault in the signal trampoline on
+	// dragonfly/386 - see issue 7421.
+	if GOOS == "dragonfly" && GOARCH == "386" {
+		t.Skip("skipping test on dragonfly/386")
+	}
+
+	old := debug.SetPanicOnFault(true)
+	defer debug.SetPanicOnFault(old)
+
+	nfault := 0
+	for _, addr := range faultAddrs {
+		testSetPanicOnFault(t, uintptr(addr), &nfault)
+	}
+	if nfault == 0 {
+		t.Fatalf("none of the addresses faulted")
+	}
+}
+
+func testSetPanicOnFault(t *testing.T, addr uintptr, nfault *int) {
+	if GOOS == "nacl" {
+		t.Skip("nacl doesn't seem to fault on high addresses")
+	}
+
+	defer func() {
+		if err := recover(); err != nil {
+			*nfault++
+		}
+	}()
+
+	// The read should fault, except that sometimes we hit
+	// addresses that have had C or kernel pages mapped there
+	// readable by user code. So just log the content.
+	// If no addresses fault, we'll fail the test.
+	v := *(*byte)(unsafe.Pointer(addr))
+	t.Logf("addr %#x: %#x\n", addr, v)
+}
+
+func eqstring_generic(s1, s2 string) bool {
+	if len(s1) != len(s2) {
+		return false
+	}
+	// optimization in assembly versions:
+	// if s1.str == s2.str { return true }
+	for i := 0; i < len(s1); i++ {
+		if s1[i] != s2[i] {
+			return false
+		}
+	}
+	return true
+}
+
+func TestEqString(t *testing.T) {
+	// This isn't really an exhaustive test of eqstring, it's
+	// just a convenient way of documenting (via eqstring_generic)
+	// what eqstring does.
+	s := []string{
+		"",
+		"a",
+		"c",
+		"aaa",
+		"ccc",
+		"cccc"[:3], // same contents, different string
+		"1234567890",
+	}
+	for _, s1 := range s {
+		for _, s2 := range s {
+			x := s1 == s2
+			y := eqstring_generic(s1, s2)
+			if x != y {
+				t.Errorf(`eqstring("%s","%s") = %t, want %t`, s1, s2, x, y)
+			}
+		}
+	}
+}
diff --git a/src/pkg/runtime/runtime_unix_test.go b/src/runtime/runtime_unix_test.go
similarity index 100%
rename from src/pkg/runtime/runtime_unix_test.go
rename to src/runtime/runtime_unix_test.go
diff --git a/src/runtime/select.go b/src/runtime/select.go
new file mode 100644
index 0000000..f735a71
--- /dev/null
+++ b/src/runtime/select.go
@@ -0,0 +1,651 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package runtime
+
+// This file contains the implementation of Go select statements.
+
+import "unsafe"
+
+const (
+	debugSelect = false
+)
+
+var (
+	chansendpc = funcPC(chansend)
+	chanrecvpc = funcPC(chanrecv)
+)
+
+func selectsize(size uintptr) uintptr {
+	selsize := unsafe.Sizeof(_select{}) +
+		(size-1)*unsafe.Sizeof(_select{}.scase[0]) +
+		size*unsafe.Sizeof(*_select{}.lockorder) +
+		size*unsafe.Sizeof(*_select{}.pollorder)
+	return round(selsize, _Int64Align)
+}
+
+func newselect(sel *_select, selsize int64, size int32) {
+	if selsize != int64(selectsize(uintptr(size))) {
+		print("runtime: bad select size ", selsize, ", want ", selectsize(uintptr(size)), "\n")
+		gothrow("bad select size")
+	}
+	sel.tcase = uint16(size)
+	sel.ncase = 0
+	sel.lockorder = (**hchan)(add(unsafe.Pointer(&sel.scase), uintptr(size)*unsafe.Sizeof(_select{}.scase[0])))
+	sel.pollorder = (*uint16)(add(unsafe.Pointer(sel.lockorder), uintptr(size)*unsafe.Sizeof(*_select{}.lockorder)))
+
+	if debugSelect {
+		print("newselect s=", sel, " size=", size, "\n")
+	}
+}
+
+//go:nosplit
+func selectsend(sel *_select, c *hchan, elem unsafe.Pointer) (selected bool) {
+	// nil cases do not compete
+	if c != nil {
+		selectsendImpl(sel, c, getcallerpc(unsafe.Pointer(&sel)), elem, uintptr(unsafe.Pointer(&selected))-uintptr(unsafe.Pointer(&sel)))
+	}
+	return
+}
+
+// cut in half to give stack a chance to split
+func selectsendImpl(sel *_select, c *hchan, pc uintptr, elem unsafe.Pointer, so uintptr) {
+	i := sel.ncase
+	if i >= sel.tcase {
+		gothrow("selectsend: too many cases")
+	}
+	sel.ncase = i + 1
+	cas := (*scase)(add(unsafe.Pointer(&sel.scase), uintptr(i)*unsafe.Sizeof(sel.scase[0])))
+
+	cas.pc = pc
+	cas._chan = c
+	cas.so = uint16(so)
+	cas.kind = _CaseSend
+	cas.elem = elem
+
+	if debugSelect {
+		print("selectsend s=", sel, " pc=", hex(cas.pc), " chan=", cas._chan, " so=", cas.so, "\n")
+	}
+}
+
+//go:nosplit
+func selectrecv(sel *_select, c *hchan, elem unsafe.Pointer) (selected bool) {
+	// nil cases do not compete
+	if c != nil {
+		selectrecvImpl(sel, c, getcallerpc(unsafe.Pointer(&sel)), elem, nil, uintptr(unsafe.Pointer(&selected))-uintptr(unsafe.Pointer(&sel)))
+	}
+	return
+}
+
+//go:nosplit
+func selectrecv2(sel *_select, c *hchan, elem unsafe.Pointer, received *bool) (selected bool) {
+	// nil cases do not compete
+	if c != nil {
+		selectrecvImpl(sel, c, getcallerpc(unsafe.Pointer(&sel)), elem, received, uintptr(unsafe.Pointer(&selected))-uintptr(unsafe.Pointer(&sel)))
+	}
+	return
+}
+
+func selectrecvImpl(sel *_select, c *hchan, pc uintptr, elem unsafe.Pointer, received *bool, so uintptr) {
+	i := sel.ncase
+	if i >= sel.tcase {
+		gothrow("selectrecv: too many cases")
+	}
+	sel.ncase = i + 1
+	cas := (*scase)(add(unsafe.Pointer(&sel.scase), uintptr(i)*unsafe.Sizeof(sel.scase[0])))
+	cas.pc = pc
+	cas._chan = c
+	cas.so = uint16(so)
+	cas.kind = _CaseRecv
+	cas.elem = elem
+	cas.receivedp = received
+
+	if debugSelect {
+		print("selectrecv s=", sel, " pc=", hex(cas.pc), " chan=", cas._chan, " so=", cas.so, "\n")
+	}
+}
+
+//go:nosplit
+func selectdefault(sel *_select) (selected bool) {
+	selectdefaultImpl(sel, getcallerpc(unsafe.Pointer(&sel)), uintptr(unsafe.Pointer(&selected))-uintptr(unsafe.Pointer(&sel)))
+	return
+}
+
+func selectdefaultImpl(sel *_select, callerpc uintptr, so uintptr) {
+	i := sel.ncase
+	if i >= sel.tcase {
+		gothrow("selectdefault: too many cases")
+	}
+	sel.ncase = i + 1
+	cas := (*scase)(add(unsafe.Pointer(&sel.scase), uintptr(i)*unsafe.Sizeof(sel.scase[0])))
+	cas.pc = callerpc
+	cas._chan = nil
+	cas.so = uint16(so)
+	cas.kind = _CaseDefault
+
+	if debugSelect {
+		print("selectdefault s=", sel, " pc=", hex(cas.pc), " so=", cas.so, "\n")
+	}
+}
+
+func sellock(sel *_select) {
+	lockslice := sliceStruct{unsafe.Pointer(sel.lockorder), int(sel.ncase), int(sel.ncase)}
+	lockorder := *(*[]*hchan)(unsafe.Pointer(&lockslice))
+	var c *hchan
+	for _, c0 := range lockorder {
+		if c0 != nil && c0 != c {
+			c = c0
+			lock(&c.lock)
+		}
+	}
+}
+
+func selunlock(sel *_select) {
+	// We must be very careful here to not touch sel after we have unlocked
+	// the last lock, because sel can be freed right after the last unlock.
+	// Consider the following situation.
+	// First M calls runtime·park() in runtime·selectgo() passing the sel.
+	// Once runtime·park() has unlocked the last lock, another M makes
+	// the G that calls select runnable again and schedules it for execution.
+	// When the G runs on another M, it locks all the locks and frees sel.
+	// Now if the first M touches sel, it will access freed memory.
+	n := int(sel.ncase)
+	r := 0
+	lockslice := sliceStruct{unsafe.Pointer(sel.lockorder), n, n}
+	lockorder := *(*[]*hchan)(unsafe.Pointer(&lockslice))
+	// skip the default case
+	if n > 0 && lockorder[0] == nil {
+		r = 1
+	}
+	for i := n - 1; i >= r; i-- {
+		c := lockorder[i]
+		if i > 0 && c == lockorder[i-1] {
+			continue // will unlock it on the next iteration
+		}
+		unlock(&c.lock)
+	}
+}
+
+func selparkcommit(gp *g, sel *_select) bool {
+	selunlock(sel)
+	return true
+}
+
+func block() {
+	gopark(nil, nil, "select (no cases)") // forever
+}
+
+// overwrites return pc on stack to signal which case of the select
+// to run, so cannot appear at the top of a split stack.
+//go:nosplit
+func selectgo(sel *_select) {
+	pc, offset := selectgoImpl(sel)
+	*(*bool)(add(unsafe.Pointer(&sel), uintptr(offset))) = true
+	setcallerpc(unsafe.Pointer(&sel), pc)
+}
+
+// selectgoImpl returns scase.pc and scase.so for the select
+// case which fired.
+func selectgoImpl(sel *_select) (uintptr, uint16) {
+	if debugSelect {
+		print("select: sel=", sel, "\n")
+	}
+
+	scaseslice := sliceStruct{unsafe.Pointer(&sel.scase), int(sel.ncase), int(sel.ncase)}
+	scases := *(*[]scase)(unsafe.Pointer(&scaseslice))
+
+	var t0 int64
+	if blockprofilerate > 0 {
+		t0 = cputicks()
+		for i := 0; i < int(sel.ncase); i++ {
+			scases[i].releasetime = -1
+		}
+	}
+
+	// The compiler rewrites selects that statically have
+	// only 0 or 1 cases plus default into simpler constructs.
+	// The only way we can end up with such small sel.ncase
+	// values here is for a larger select in which most channels
+	// have been nilled out.  The general code handles those
+	// cases correctly, and they are rare enough not to bother
+	// optimizing (and needing to test).
+
+	// generate permuted order
+	pollslice := sliceStruct{unsafe.Pointer(sel.pollorder), int(sel.ncase), int(sel.ncase)}
+	pollorder := *(*[]uint16)(unsafe.Pointer(&pollslice))
+	for i := 0; i < int(sel.ncase); i++ {
+		pollorder[i] = uint16(i)
+	}
+	for i := 1; i < int(sel.ncase); i++ {
+		o := pollorder[i]
+		j := int(fastrand1()) % (i + 1)
+		pollorder[i] = pollorder[j]
+		pollorder[j] = o
+	}
+
+	// sort the cases by Hchan address to get the locking order.
+	// simple heap sort, to guarantee n log n time and constant stack footprint.
+	lockslice := sliceStruct{unsafe.Pointer(sel.lockorder), int(sel.ncase), int(sel.ncase)}
+	lockorder := *(*[]*hchan)(unsafe.Pointer(&lockslice))
+	for i := 0; i < int(sel.ncase); i++ {
+		j := i
+		c := scases[j]._chan
+		for j > 0 && lockorder[(j-1)/2].sortkey() < c.sortkey() {
+			k := (j - 1) / 2
+			lockorder[j] = lockorder[k]
+			j = k
+		}
+		lockorder[j] = c
+	}
+	for i := int(sel.ncase) - 1; i >= 0; i-- {
+		c := lockorder[i]
+		lockorder[i] = lockorder[0]
+		j := 0
+		for {
+			k := j*2 + 1
+			if k >= i {
+				break
+			}
+			if k+1 < i && lockorder[k].sortkey() < lockorder[k+1].sortkey() {
+				k++
+			}
+			if c.sortkey() < lockorder[k].sortkey() {
+				lockorder[j] = lockorder[k]
+				j = k
+				continue
+			}
+			break
+		}
+		lockorder[j] = c
+	}
+	/*
+		for i := 0; i+1 < int(sel.ncase); i++ {
+			if lockorder[i].sortkey() > lockorder[i+1].sortkey() {
+				print("i=", i, " x=", lockorder[i], " y=", lockorder[i+1], "\n")
+				gothrow("select: broken sort")
+			}
+		}
+	*/
+
+	// lock all the channels involved in the select
+	sellock(sel)
+
+	var (
+		gp     *g
+		done   uint32
+		sg     *sudog
+		c      *hchan
+		k      *scase
+		sglist *sudog
+		sgnext *sudog
+	)
+
+loop:
+	// pass 1 - look for something already waiting
+	var dfl *scase
+	var cas *scase
+	for i := 0; i < int(sel.ncase); i++ {
+		cas = &scases[pollorder[i]]
+		c = cas._chan
+
+		switch cas.kind {
+		case _CaseRecv:
+			if c.dataqsiz > 0 {
+				if c.qcount > 0 {
+					goto asyncrecv
+				}
+			} else {
+				sg = c.sendq.dequeue()
+				if sg != nil {
+					goto syncrecv
+				}
+			}
+			if c.closed != 0 {
+				goto rclose
+			}
+
+		case _CaseSend:
+			if raceenabled {
+				racereadpc(unsafe.Pointer(c), cas.pc, chansendpc)
+			}
+			if c.closed != 0 {
+				goto sclose
+			}
+			if c.dataqsiz > 0 {
+				if c.qcount < c.dataqsiz {
+					goto asyncsend
+				}
+			} else {
+				sg = c.recvq.dequeue()
+				if sg != nil {
+					goto syncsend
+				}
+			}
+
+		case _CaseDefault:
+			dfl = cas
+		}
+	}
+
+	if dfl != nil {
+		selunlock(sel)
+		cas = dfl
+		goto retc
+	}
+
+	// pass 2 - enqueue on all chans
+	gp = getg()
+	done = 0
+	for i := 0; i < int(sel.ncase); i++ {
+		cas = &scases[pollorder[i]]
+		c = cas._chan
+		sg := acquireSudog()
+		sg.g = gp
+		// Note: selectdone is adjusted for stack copies in stack.c:adjustsudogs
+		sg.selectdone = (*uint32)(noescape(unsafe.Pointer(&done)))
+		sg.elem = cas.elem
+		sg.releasetime = 0
+		if t0 != 0 {
+			sg.releasetime = -1
+		}
+		sg.waitlink = gp.waiting
+		gp.waiting = sg
+
+		switch cas.kind {
+		case _CaseRecv:
+			c.recvq.enqueue(sg)
+
+		case _CaseSend:
+			c.sendq.enqueue(sg)
+		}
+	}
+
+	// wait for someone to wake us up
+	gp.param = nil
+	gopark(unsafe.Pointer(funcPC(selparkcommit)), unsafe.Pointer(sel), "select")
+
+	// someone woke us up
+	sellock(sel)
+	sg = (*sudog)(gp.param)
+	gp.param = nil
+
+	// pass 3 - dequeue from unsuccessful chans
+	// otherwise they stack up on quiet channels
+	// record the successful case, if any.
+	// We singly-linked up the SudoGs in case order, so when
+	// iterating through the linked list they are in reverse order.
+	cas = nil
+	sglist = gp.waiting
+	// Clear all selectdone and elem before unlinking from gp.waiting.
+	// They must be cleared before being put back into the sudog cache.
+	// Clear before unlinking, because if a stack copy happens after the unlink,
+	// they will not be updated, they will be left pointing to the old stack,
+	// which creates dangling pointers, which may be detected by the
+	// garbage collector.
+	for sg1 := gp.waiting; sg1 != nil; sg1 = sg1.waitlink {
+		sg1.selectdone = nil
+		sg1.elem = nil
+	}
+	gp.waiting = nil
+	for i := int(sel.ncase) - 1; i >= 0; i-- {
+		k = &scases[pollorder[i]]
+		if sglist.releasetime > 0 {
+			k.releasetime = sglist.releasetime
+		}
+		if sg == sglist {
+			cas = k
+		} else {
+			c = k._chan
+			if k.kind == _CaseSend {
+				c.sendq.dequeueSudoG(sglist)
+			} else {
+				c.recvq.dequeueSudoG(sglist)
+			}
+		}
+		sgnext = sglist.waitlink
+		sglist.waitlink = nil
+		releaseSudog(sglist)
+		sglist = sgnext
+	}
+
+	if cas == nil {
+		goto loop
+	}
+
+	c = cas._chan
+
+	if c.dataqsiz > 0 {
+		gothrow("selectgo: shouldn't happen")
+	}
+
+	if debugSelect {
+		print("wait-return: sel=", sel, " c=", c, " cas=", cas, " kind=", cas.kind, "\n")
+	}
+
+	if cas.kind == _CaseRecv {
+		if cas.receivedp != nil {
+			*cas.receivedp = true
+		}
+	}
+
+	if raceenabled {
+		if cas.kind == _CaseRecv && cas.elem != nil {
+			raceWriteObjectPC(c.elemtype, cas.elem, cas.pc, chanrecvpc)
+		} else if cas.kind == _CaseSend {
+			raceReadObjectPC(c.elemtype, cas.elem, cas.pc, chansendpc)
+		}
+	}
+
+	selunlock(sel)
+	goto retc
+
+asyncrecv:
+	// can receive from buffer
+	if raceenabled {
+		if cas.elem != nil {
+			raceWriteObjectPC(c.elemtype, cas.elem, cas.pc, chanrecvpc)
+		}
+		raceacquire(chanbuf(c, c.recvx))
+		racerelease(chanbuf(c, c.recvx))
+	}
+	if cas.receivedp != nil {
+		*cas.receivedp = true
+	}
+	if cas.elem != nil {
+		memmove(cas.elem, chanbuf(c, c.recvx), uintptr(c.elemsize))
+	}
+	memclr(chanbuf(c, c.recvx), uintptr(c.elemsize))
+	c.recvx++
+	if c.recvx == c.dataqsiz {
+		c.recvx = 0
+	}
+	c.qcount--
+	sg = c.sendq.dequeue()
+	if sg != nil {
+		gp = sg.g
+		selunlock(sel)
+		if sg.releasetime != 0 {
+			sg.releasetime = cputicks()
+		}
+		goready(gp)
+	} else {
+		selunlock(sel)
+	}
+	goto retc
+
+asyncsend:
+	// can send to buffer
+	if raceenabled {
+		raceacquire(chanbuf(c, c.sendx))
+		racerelease(chanbuf(c, c.sendx))
+		raceReadObjectPC(c.elemtype, cas.elem, cas.pc, chansendpc)
+	}
+	memmove(chanbuf(c, c.sendx), cas.elem, uintptr(c.elemsize))
+	c.sendx++
+	if c.sendx == c.dataqsiz {
+		c.sendx = 0
+	}
+	c.qcount++
+	sg = c.recvq.dequeue()
+	if sg != nil {
+		gp = sg.g
+		selunlock(sel)
+		if sg.releasetime != 0 {
+			sg.releasetime = cputicks()
+		}
+		goready(gp)
+	} else {
+		selunlock(sel)
+	}
+	goto retc
+
+syncrecv:
+	// can receive from sleeping sender (sg)
+	if raceenabled {
+		if cas.elem != nil {
+			raceWriteObjectPC(c.elemtype, cas.elem, cas.pc, chanrecvpc)
+		}
+		racesync(c, sg)
+	}
+	selunlock(sel)
+	if debugSelect {
+		print("syncrecv: sel=", sel, " c=", c, "\n")
+	}
+	if cas.receivedp != nil {
+		*cas.receivedp = true
+	}
+	if cas.elem != nil {
+		memmove(cas.elem, sg.elem, uintptr(c.elemsize))
+	}
+	sg.elem = nil
+	gp = sg.g
+	gp.param = unsafe.Pointer(sg)
+	if sg.releasetime != 0 {
+		sg.releasetime = cputicks()
+	}
+	goready(gp)
+	goto retc
+
+rclose:
+	// read at end of closed channel
+	selunlock(sel)
+	if cas.receivedp != nil {
+		*cas.receivedp = false
+	}
+	if cas.elem != nil {
+		memclr(cas.elem, uintptr(c.elemsize))
+	}
+	if raceenabled {
+		raceacquire(unsafe.Pointer(c))
+	}
+	goto retc
+
+syncsend:
+	// can send to sleeping receiver (sg)
+	if raceenabled {
+		raceReadObjectPC(c.elemtype, cas.elem, cas.pc, chansendpc)
+		racesync(c, sg)
+	}
+	selunlock(sel)
+	if debugSelect {
+		print("syncsend: sel=", sel, " c=", c, "\n")
+	}
+	if sg.elem != nil {
+		memmove(sg.elem, cas.elem, uintptr(c.elemsize))
+	}
+	sg.elem = nil
+	gp = sg.g
+	gp.param = unsafe.Pointer(sg)
+	if sg.releasetime != 0 {
+		sg.releasetime = cputicks()
+	}
+	goready(gp)
+
+retc:
+	if cas.releasetime > 0 {
+		blockevent(cas.releasetime-t0, 2)
+	}
+	return cas.pc, cas.so
+
+sclose:
+	// send on closed channel
+	selunlock(sel)
+	panic("send on closed channel")
+}
+
+func (c *hchan) sortkey() uintptr {
+	// TODO(khr): if we have a moving garbage collector, we'll need to
+	// change this function.
+	return uintptr(unsafe.Pointer(c))
+}
+
+// A runtimeSelect is a single case passed to rselect.
+// This must match ../reflect/value.go:/runtimeSelect
+type runtimeSelect struct {
+	dir selectDir
+	typ unsafe.Pointer // channel type (not used here)
+	ch  *hchan         // channel
+	val unsafe.Pointer // ptr to data (SendDir) or ptr to receive buffer (RecvDir)
+}
+
+// These values must match ../reflect/value.go:/SelectDir.
+type selectDir int
+
+const (
+	_             selectDir = iota
+	selectSend              // case Chan <- Send
+	selectRecv              // case <-Chan:
+	selectDefault           // default
+)
+
+func reflect_rselect(cases []runtimeSelect) (chosen int, recvOK bool) {
+	// flagNoScan is safe here, because all objects are also referenced from cases.
+	size := selectsize(uintptr(len(cases)))
+	sel := (*_select)(mallocgc(size, nil, flagNoScan))
+	newselect(sel, int64(size), int32(len(cases)))
+	r := new(bool)
+	for i := range cases {
+		rc := &cases[i]
+		switch rc.dir {
+		case selectDefault:
+			selectdefaultImpl(sel, uintptr(i), 0)
+		case selectSend:
+			if rc.ch == nil {
+				break
+			}
+			selectsendImpl(sel, rc.ch, uintptr(i), rc.val, 0)
+		case selectRecv:
+			if rc.ch == nil {
+				break
+			}
+			selectrecvImpl(sel, rc.ch, uintptr(i), rc.val, r, 0)
+		}
+	}
+
+	pc, _ := selectgoImpl(sel)
+	chosen = int(pc)
+	recvOK = *r
+	return
+}
+
+func (q *waitq) dequeueSudoG(s *sudog) {
+	var prevsgp *sudog
+	l := &q.first
+	for {
+		sgp := *l
+		if sgp == nil {
+			return
+		}
+		if sgp == s {
+			*l = sgp.next
+			if q.last == sgp {
+				q.last = prevsgp
+			}
+			s.next = nil
+			return
+		}
+		l = &sgp.next
+		prevsgp = sgp
+	}
+}
diff --git a/src/runtime/sema.go b/src/runtime/sema.go
new file mode 100644
index 0000000..26dbd30
--- /dev/null
+++ b/src/runtime/sema.go
@@ -0,0 +1,275 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Semaphore implementation exposed to Go.
+// Intended use is provide a sleep and wakeup
+// primitive that can be used in the contended case
+// of other synchronization primitives.
+// Thus it targets the same goal as Linux's futex,
+// but it has much simpler semantics.
+//
+// That is, don't think of these as semaphores.
+// Think of them as a way to implement sleep and wakeup
+// such that every sleep is paired with a single wakeup,
+// even if, due to races, the wakeup happens before the sleep.
+//
+// See Mullender and Cox, ``Semaphores in Plan 9,''
+// http://swtch.com/semaphore.pdf
+
+package runtime
+
+import "unsafe"
+
+// Asynchronous semaphore for sync.Mutex.
+
+type semaRoot struct {
+	lock  mutex
+	head  *sudog
+	tail  *sudog
+	nwait uint32 // Number of waiters. Read w/o the lock.
+}
+
+// Prime to not correlate with any user patterns.
+const semTabSize = 251
+
+var semtable [semTabSize]struct {
+	root semaRoot
+	pad  [_CacheLineSize - unsafe.Sizeof(semaRoot{})]byte
+}
+
+// Called from sync/net packages.
+func asyncsemacquire(addr *uint32) {
+	semacquire(addr, true)
+}
+
+func asyncsemrelease(addr *uint32) {
+	semrelease(addr)
+}
+
+// Called from runtime.
+func semacquire(addr *uint32, profile bool) {
+	gp := getg()
+	if gp != gp.m.curg {
+		gothrow("semacquire not on the G stack")
+	}
+
+	// Easy case.
+	if cansemacquire(addr) {
+		return
+	}
+
+	// Harder case:
+	//	increment waiter count
+	//	try cansemacquire one more time, return if succeeded
+	//	enqueue itself as a waiter
+	//	sleep
+	//	(waiter descriptor is dequeued by signaler)
+	s := acquireSudog()
+	root := semroot(addr)
+	t0 := int64(0)
+	s.releasetime = 0
+	if profile && blockprofilerate > 0 {
+		t0 = cputicks()
+		s.releasetime = -1
+	}
+	for {
+		lock(&root.lock)
+		// Add ourselves to nwait to disable "easy case" in semrelease.
+		xadd(&root.nwait, 1)
+		// Check cansemacquire to avoid missed wakeup.
+		if cansemacquire(addr) {
+			xadd(&root.nwait, -1)
+			unlock(&root.lock)
+			break
+		}
+		// Any semrelease after the cansemacquire knows we're waiting
+		// (we set nwait above), so go to sleep.
+		root.queue(addr, s)
+		goparkunlock(&root.lock, "semacquire")
+		if cansemacquire(addr) {
+			break
+		}
+	}
+	if s.releasetime > 0 {
+		blockevent(int64(s.releasetime)-t0, 3)
+	}
+	releaseSudog(s)
+}
+
+func semrelease(addr *uint32) {
+	root := semroot(addr)
+	xadd(addr, 1)
+
+	// Easy case: no waiters?
+	// This check must happen after the xadd, to avoid a missed wakeup
+	// (see loop in semacquire).
+	if atomicload(&root.nwait) == 0 {
+		return
+	}
+
+	// Harder case: search for a waiter and wake it.
+	lock(&root.lock)
+	if atomicload(&root.nwait) == 0 {
+		// The count is already consumed by another goroutine,
+		// so no need to wake up another goroutine.
+		unlock(&root.lock)
+		return
+	}
+	s := root.head
+	for ; s != nil; s = s.next {
+		if s.elem == unsafe.Pointer(addr) {
+			xadd(&root.nwait, -1)
+			root.dequeue(s)
+			break
+		}
+	}
+	unlock(&root.lock)
+	if s != nil {
+		if s.releasetime != 0 {
+			s.releasetime = cputicks()
+		}
+		goready(s.g)
+	}
+}
+
+func semroot(addr *uint32) *semaRoot {
+	return &semtable[(uintptr(unsafe.Pointer(addr))>>3)%semTabSize].root
+}
+
+func cansemacquire(addr *uint32) bool {
+	for {
+		v := atomicload(addr)
+		if v == 0 {
+			return false
+		}
+		if cas(addr, v, v-1) {
+			return true
+		}
+	}
+}
+
+func (root *semaRoot) queue(addr *uint32, s *sudog) {
+	s.g = getg()
+	s.elem = unsafe.Pointer(addr)
+	s.next = nil
+	s.prev = root.tail
+	if root.tail != nil {
+		root.tail.next = s
+	} else {
+		root.head = s
+	}
+	root.tail = s
+}
+
+func (root *semaRoot) dequeue(s *sudog) {
+	if s.next != nil {
+		s.next.prev = s.prev
+	} else {
+		root.tail = s.prev
+	}
+	if s.prev != nil {
+		s.prev.next = s.next
+	} else {
+		root.head = s.next
+	}
+	s.elem = nil
+	s.next = nil
+	s.prev = nil
+}
+
+// Synchronous semaphore for sync.Cond.
+type syncSema struct {
+	lock mutex
+	head *sudog
+	tail *sudog
+}
+
+// Syncsemacquire waits for a pairing syncsemrelease on the same semaphore s.
+func syncsemacquire(s *syncSema) {
+	lock(&s.lock)
+	if s.head != nil && s.head.nrelease > 0 {
+		// Have pending release, consume it.
+		var wake *sudog
+		s.head.nrelease--
+		if s.head.nrelease == 0 {
+			wake = s.head
+			s.head = wake.next
+			if s.head == nil {
+				s.tail = nil
+			}
+		}
+		unlock(&s.lock)
+		if wake != nil {
+			wake.next = nil
+			goready(wake.g)
+		}
+	} else {
+		// Enqueue itself.
+		w := acquireSudog()
+		w.g = getg()
+		w.nrelease = -1
+		w.next = nil
+		w.releasetime = 0
+		t0 := int64(0)
+		if blockprofilerate > 0 {
+			t0 = cputicks()
+			w.releasetime = -1
+		}
+		if s.tail == nil {
+			s.head = w
+		} else {
+			s.tail.next = w
+		}
+		s.tail = w
+		goparkunlock(&s.lock, "semacquire")
+		if t0 != 0 {
+			blockevent(int64(w.releasetime)-t0, 2)
+		}
+		releaseSudog(w)
+	}
+}
+
+// Syncsemrelease waits for n pairing syncsemacquire on the same semaphore s.
+func syncsemrelease(s *syncSema, n uint32) {
+	lock(&s.lock)
+	for n > 0 && s.head != nil && s.head.nrelease < 0 {
+		// Have pending acquire, satisfy it.
+		wake := s.head
+		s.head = wake.next
+		if s.head == nil {
+			s.tail = nil
+		}
+		if wake.releasetime != 0 {
+			wake.releasetime = cputicks()
+		}
+		wake.next = nil
+		goready(wake.g)
+		n--
+	}
+	if n > 0 {
+		// enqueue itself
+		w := acquireSudog()
+		w.g = getg()
+		w.nrelease = int32(n)
+		w.next = nil
+		w.releasetime = 0
+		if s.tail == nil {
+			s.head = w
+		} else {
+			s.tail.next = w
+		}
+		s.tail = w
+		goparkunlock(&s.lock, "semarelease")
+		releaseSudog(w)
+	} else {
+		unlock(&s.lock)
+	}
+}
+
+func syncsemcheck(sz uintptr) {
+	if sz != unsafe.Sizeof(syncSema{}) {
+		print("runtime: bad syncSema size - sync=", sz, " runtime=", unsafe.Sizeof(syncSema{}), "\n")
+		gothrow("bad syncSema size")
+	}
+}
diff --git a/src/runtime/signal.c b/src/runtime/signal.c
new file mode 100644
index 0000000..0674bfb
--- /dev/null
+++ b/src/runtime/signal.c
@@ -0,0 +1,25 @@
+// 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 "runtime.h"
+
+void
+runtime·sigenable_m(void)
+{
+	uint32 s;
+	
+	s = g->m->scalararg[0];
+	g->m->scalararg[0] = 0;
+	runtime·sigenable(s);
+}
+
+void
+runtime·sigdisable_m(void)
+{
+	uint32 s;
+	
+	s = g->m->scalararg[0];
+	g->m->scalararg[0] = 0;
+	runtime·sigdisable(s);
+}
diff --git a/src/runtime/signal_386.c b/src/runtime/signal_386.c
new file mode 100644
index 0000000..30a7488
--- /dev/null
+++ b/src/runtime/signal_386.c
@@ -0,0 +1,122 @@
+// Copyright 2013 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin dragonfly freebsd linux nacl netbsd openbsd
+
+#include "runtime.h"
+#include "defs_GOOS_GOARCH.h"
+#include "os_GOOS.h"
+#include "signal_GOOS_GOARCH.h"
+#include "signals_GOOS.h"
+
+void
+runtime·dumpregs(Siginfo *info, void *ctxt)
+{
+	USED(info);
+	USED(ctxt);
+	
+	runtime·printf("eax     %x\n", SIG_EAX(info, ctxt));
+	runtime·printf("ebx     %x\n", SIG_EBX(info, ctxt));
+	runtime·printf("ecx     %x\n", SIG_ECX(info, ctxt));
+	runtime·printf("edx     %x\n", SIG_EDX(info, ctxt));
+	runtime·printf("edi     %x\n", SIG_EDI(info, ctxt));
+	runtime·printf("esi     %x\n", SIG_ESI(info, ctxt));
+	runtime·printf("ebp     %x\n", SIG_EBP(info, ctxt));
+	runtime·printf("esp     %x\n", SIG_ESP(info, ctxt));
+	runtime·printf("eip     %x\n", SIG_EIP(info, ctxt));
+	runtime·printf("eflags  %x\n", SIG_EFLAGS(info, ctxt));
+	runtime·printf("cs      %x\n", SIG_CS(info, ctxt));
+	runtime·printf("fs      %x\n", SIG_FS(info, ctxt));
+	runtime·printf("gs      %x\n", SIG_GS(info, ctxt));
+}
+
+void
+runtime·sighandler(int32 sig, Siginfo *info, void *ctxt, G *gp)
+{
+	uintptr *sp;
+	SigTab *t;
+	bool crash;
+
+	if(sig == SIGPROF) {
+		runtime·sigprof((byte*)SIG_EIP(info, ctxt), (byte*)SIG_ESP(info, ctxt), nil, gp, g->m);
+		return;
+	}
+
+	t = &runtime·sigtab[sig];
+	if(SIG_CODE0(info, ctxt) != SI_USER && (t->flags & SigPanic)) {
+		// Make it look like a call to the signal func.
+		// Have to pass arguments out of band since
+		// augmenting the stack frame would break
+		// the unwinding code.
+		gp->sig = sig;
+		gp->sigcode0 = SIG_CODE0(info, ctxt);
+		gp->sigcode1 = SIG_CODE1(info, ctxt);
+		gp->sigpc = SIG_EIP(info, ctxt);
+
+#ifdef GOOS_darwin
+		// Work around Leopard bug that doesn't set FPE_INTDIV.
+		// Look at instruction to see if it is a divide.
+		// Not necessary in Snow Leopard (si_code will be != 0).
+		if(sig == SIGFPE && gp->sigcode0 == 0) {
+			byte *pc;
+			pc = (byte*)gp->sigpc;
+			if(pc[0] == 0x66)	// 16-bit instruction prefix
+				pc++;
+			if(pc[0] == 0xF6 || pc[0] == 0xF7)
+				gp->sigcode0 = FPE_INTDIV;
+		}
+#endif
+
+		// Only push runtime·sigpanic if eip != 0.
+		// If eip == 0, probably panicked because of a
+		// call to a nil func.  Not pushing that onto sp will
+		// make the trace look like a call to runtime·sigpanic instead.
+		// (Otherwise the trace will end at runtime·sigpanic and we
+		// won't get to see who faulted.)
+		if(SIG_EIP(info, ctxt) != 0) {
+			sp = (uintptr*)SIG_ESP(info, ctxt);
+			*--sp = SIG_EIP(info, ctxt);
+			SIG_ESP(info, ctxt) = (uintptr)sp;
+		}
+		SIG_EIP(info, ctxt) = (uintptr)runtime·sigpanic;
+		return;
+	}
+
+	if(SIG_CODE0(info, ctxt) == SI_USER || (t->flags & SigNotify))
+		if(runtime·sigsend(sig))
+			return;
+	if(t->flags & SigKill)
+		runtime·exit(2);
+	if(!(t->flags & SigThrow))
+		return;
+
+	g->m->throwing = 1;
+	g->m->caughtsig = gp;
+	runtime·startpanic();
+
+	if(sig < 0 || sig >= NSIG)
+		runtime·printf("Signal %d\n", sig);
+	else
+		runtime·printf("%s\n", runtime·sigtab[sig].name);
+
+	runtime·printf("PC=%x\n", SIG_EIP(info, ctxt));
+	if(g->m->lockedg != nil && g->m->ncgo > 0 && gp == g->m->g0) {
+		runtime·printf("signal arrived during cgo execution\n");
+		gp = g->m->lockedg;
+	}
+	runtime·printf("\n");
+
+	if(runtime·gotraceback(&crash)){
+		runtime·goroutineheader(gp);
+		runtime·tracebacktrap(SIG_EIP(info, ctxt), SIG_ESP(info, ctxt), 0, gp);
+		runtime·tracebackothers(gp);
+		runtime·printf("\n");
+		runtime·dumpregs(info, ctxt);
+	}
+	
+	if(crash)
+		runtime·crash();
+
+	runtime·exit(2);
+}
diff --git a/src/runtime/signal_amd64x.c b/src/runtime/signal_amd64x.c
new file mode 100644
index 0000000..feb4afc
--- /dev/null
+++ b/src/runtime/signal_amd64x.c
@@ -0,0 +1,156 @@
+// Copyright 2013 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build amd64 amd64p32
+// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris
+
+#include "runtime.h"
+#include "defs_GOOS_GOARCH.h"
+#include "os_GOOS.h"
+#include "signal_GOOS_GOARCH.h"
+#include "signals_GOOS.h"
+
+void
+runtime·dumpregs(Siginfo *info, void *ctxt)
+{
+	USED(info);
+	USED(ctxt);
+	
+	runtime·printf("rax     %X\n", SIG_RAX(info, ctxt));
+	runtime·printf("rbx     %X\n", SIG_RBX(info, ctxt));
+	runtime·printf("rcx     %X\n", SIG_RCX(info, ctxt));
+	runtime·printf("rdx     %X\n", SIG_RDX(info, ctxt));
+	runtime·printf("rdi     %X\n", SIG_RDI(info, ctxt));
+	runtime·printf("rsi     %X\n", SIG_RSI(info, ctxt));
+	runtime·printf("rbp     %X\n", SIG_RBP(info, ctxt));
+	runtime·printf("rsp     %X\n", SIG_RSP(info, ctxt));
+	runtime·printf("r8      %X\n", SIG_R8(info, ctxt) );
+	runtime·printf("r9      %X\n", SIG_R9(info, ctxt) );
+	runtime·printf("r10     %X\n", SIG_R10(info, ctxt));
+	runtime·printf("r11     %X\n", SIG_R11(info, ctxt));
+	runtime·printf("r12     %X\n", SIG_R12(info, ctxt));
+	runtime·printf("r13     %X\n", SIG_R13(info, ctxt));
+	runtime·printf("r14     %X\n", SIG_R14(info, ctxt));
+	runtime·printf("r15     %X\n", SIG_R15(info, ctxt));
+	runtime·printf("rip     %X\n", SIG_RIP(info, ctxt));
+	runtime·printf("rflags  %X\n", SIG_RFLAGS(info, ctxt));
+	runtime·printf("cs      %X\n", SIG_CS(info, ctxt));
+	runtime·printf("fs      %X\n", SIG_FS(info, ctxt));
+	runtime·printf("gs      %X\n", SIG_GS(info, ctxt));
+}
+
+void
+runtime·sighandler(int32 sig, Siginfo *info, void *ctxt, G *gp)
+{
+	uintptr *sp;
+	SigTab *t;
+	bool crash;
+
+	if(sig == SIGPROF) {
+		runtime·sigprof((byte*)SIG_RIP(info, ctxt), (byte*)SIG_RSP(info, ctxt), nil, gp, g->m);
+		return;
+	}
+
+#ifdef GOOS_darwin
+	// x86-64 has 48-bit virtual addresses. The top 16 bits must echo bit 47.
+	// The hardware delivers a different kind of fault for a malformed address
+	// than it does for an attempt to access a valid but unmapped address.
+	// OS X 10.9.2 mishandles the malformed address case, making it look like
+	// a user-generated signal (like someone ran kill -SEGV ourpid).
+	// We pass user-generated signals to os/signal, or else ignore them.
+	// Doing that here - and returning to the faulting code - results in an
+	// infinite loop. It appears the best we can do is rewrite what the kernel
+	// delivers into something more like the truth. The address used below
+	// has very little chance of being the one that caused the fault, but it is
+	// malformed, it is clearly not a real pointer, and if it does get printed
+	// in real life, people will probably search for it and find this code.
+	// There are no Google hits for b01dfacedebac1e or 0xb01dfacedebac1e
+	// as I type this comment.
+	if(sig == SIGSEGV && SIG_CODE0(info, ctxt) == SI_USER) {
+		SIG_CODE0(info, ctxt) = SI_USER+1;
+		info->si_addr = (void*)(uintptr)0xb01dfacedebac1eULL;
+	}
+#endif
+
+	t = &runtime·sigtab[sig];
+	if(SIG_CODE0(info, ctxt) != SI_USER && (t->flags & SigPanic)) {
+		// Make it look like a call to the signal func.
+		// Have to pass arguments out of band since
+		// augmenting the stack frame would break
+		// the unwinding code.
+		gp->sig = sig;
+		gp->sigcode0 = SIG_CODE0(info, ctxt);
+		gp->sigcode1 = SIG_CODE1(info, ctxt);
+		gp->sigpc = SIG_RIP(info, ctxt);
+
+#ifdef GOOS_darwin
+		// Work around Leopard bug that doesn't set FPE_INTDIV.
+		// Look at instruction to see if it is a divide.
+		// Not necessary in Snow Leopard (si_code will be != 0).
+		if(sig == SIGFPE && gp->sigcode0 == 0) {
+			byte *pc;
+			pc = (byte*)gp->sigpc;
+			if((pc[0]&0xF0) == 0x40)	// 64-bit REX prefix
+				pc++;
+			else if(pc[0] == 0x66)	// 16-bit instruction prefix
+				pc++;
+			if(pc[0] == 0xF6 || pc[0] == 0xF7)
+				gp->sigcode0 = FPE_INTDIV;
+		}
+#endif
+
+		// Only push runtime·sigpanic if rip != 0.
+		// If rip == 0, probably panicked because of a
+		// call to a nil func.  Not pushing that onto sp will
+		// make the trace look like a call to runtime·sigpanic instead.
+		// (Otherwise the trace will end at runtime·sigpanic and we
+		// won't get to see who faulted.)
+		if(SIG_RIP(info, ctxt) != 0) {
+			sp = (uintptr*)SIG_RSP(info, ctxt);
+			if(sizeof(uintreg) > sizeof(uintptr))
+				*--sp = 0;
+			*--sp = SIG_RIP(info, ctxt);
+			SIG_RSP(info, ctxt) = (uintptr)sp;
+		}
+		SIG_RIP(info, ctxt) = (uintptr)runtime·sigpanic;
+		return;
+	}
+
+	if(SIG_CODE0(info, ctxt) == SI_USER || (t->flags & SigNotify))
+		if(runtime·sigsend(sig))
+			return;
+	if(t->flags & SigKill)
+		runtime·exit(2);
+	if(!(t->flags & SigThrow))
+		return;
+
+	g->m->throwing = 1;
+	g->m->caughtsig = gp;
+	runtime·startpanic();
+
+	if(sig < 0 || sig >= NSIG)
+		runtime·printf("Signal %d\n", sig);
+	else
+		runtime·printf("%s\n", runtime·sigtab[sig].name);
+
+	runtime·printf("PC=%X\n", SIG_RIP(info, ctxt));
+	if(g->m->lockedg != nil && g->m->ncgo > 0 && gp == g->m->g0) {
+		runtime·printf("signal arrived during cgo execution\n");
+		gp = g->m->lockedg;
+	}
+	runtime·printf("\n");
+
+	if(runtime·gotraceback(&crash)){
+		runtime·goroutineheader(gp);
+		runtime·tracebacktrap(SIG_RIP(info, ctxt), SIG_RSP(info, ctxt), 0, gp);
+		runtime·tracebackothers(gp);
+		runtime·printf("\n");
+		runtime·dumpregs(info, ctxt);
+	}
+	
+	if(crash)
+		runtime·crash();
+
+	runtime·exit(2);
+}
diff --git a/src/runtime/signal_android_386.h b/src/runtime/signal_android_386.h
new file mode 100644
index 0000000..2a1bb4b
--- /dev/null
+++ b/src/runtime/signal_android_386.h
@@ -0,0 +1 @@
+#include "signal_linux_386.h"
diff --git a/src/runtime/signal_android_arm.h b/src/runtime/signal_android_arm.h
new file mode 100644
index 0000000..8a05e21
--- /dev/null
+++ b/src/runtime/signal_android_arm.h
@@ -0,0 +1 @@
+#include "signal_linux_arm.h"
diff --git a/src/runtime/signal_arm.c b/src/runtime/signal_arm.c
new file mode 100644
index 0000000..afad5e7
--- /dev/null
+++ b/src/runtime/signal_arm.c
@@ -0,0 +1,121 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin dragonfly freebsd linux nacl netbsd openbsd
+
+#include "runtime.h"
+#include "defs_GOOS_GOARCH.h"
+#include "os_GOOS.h"
+#include "signal_GOOS_GOARCH.h"
+#include "signals_GOOS.h"
+
+void
+runtime·dumpregs(Siginfo *info, void *ctxt)
+{
+	USED(info);
+	USED(ctxt);
+
+	runtime·printf("trap    %x\n", SIG_TRAP(info, ctxt));
+	runtime·printf("error   %x\n", SIG_ERROR(info, ctxt));
+	runtime·printf("oldmask %x\n", SIG_OLDMASK(info, ctxt));
+	runtime·printf("r0      %x\n", SIG_R0(info, ctxt));
+	runtime·printf("r1      %x\n", SIG_R1(info, ctxt));
+	runtime·printf("r2      %x\n", SIG_R2(info, ctxt));
+	runtime·printf("r3      %x\n", SIG_R3(info, ctxt));
+	runtime·printf("r4      %x\n", SIG_R4(info, ctxt));
+	runtime·printf("r5      %x\n", SIG_R5(info, ctxt));
+	runtime·printf("r6      %x\n", SIG_R6(info, ctxt));
+	runtime·printf("r7      %x\n", SIG_R7(info, ctxt));
+	runtime·printf("r8      %x\n", SIG_R8(info, ctxt));
+	runtime·printf("r9      %x\n", SIG_R9(info, ctxt));
+	runtime·printf("r10     %x\n", SIG_R10(info, ctxt));
+	runtime·printf("fp      %x\n", SIG_FP(info, ctxt));
+	runtime·printf("ip      %x\n", SIG_IP(info, ctxt));
+	runtime·printf("sp      %x\n", SIG_SP(info, ctxt));
+	runtime·printf("lr      %x\n", SIG_LR(info, ctxt));
+	runtime·printf("pc      %x\n", SIG_PC(info, ctxt));
+	runtime·printf("cpsr    %x\n", SIG_CPSR(info, ctxt));
+	runtime·printf("fault   %x\n", SIG_FAULT(info, ctxt));
+}
+
+void
+runtime·sighandler(int32 sig, Siginfo *info, void *ctxt, G *gp)
+{
+	SigTab *t;
+	bool crash;
+
+	if(sig == SIGPROF) {
+		runtime·sigprof((uint8*)SIG_PC(info, ctxt), (uint8*)SIG_SP(info, ctxt), (uint8*)SIG_LR(info, ctxt), gp, g->m);
+		return;
+	}
+
+	t = &runtime·sigtab[sig];
+	if(SIG_CODE0(info, ctxt) != SI_USER && (t->flags & SigPanic)) {
+		// Make it look like a call to the signal func.
+		// Have to pass arguments out of band since
+		// augmenting the stack frame would break
+		// the unwinding code.
+		gp->sig = sig;
+		gp->sigcode0 = SIG_CODE0(info, ctxt);
+		gp->sigcode1 = SIG_FAULT(info, ctxt);
+		gp->sigpc = SIG_PC(info, ctxt);
+
+		// We arrange lr, and pc to pretend the panicking
+		// function calls sigpanic directly.
+		// Always save LR to stack so that panics in leaf
+		// functions are correctly handled. This smashes
+		// the stack frame but we're not going back there
+		// anyway.
+		SIG_SP(info, ctxt) -= 4;
+		*(uint32*)SIG_SP(info, ctxt) = SIG_LR(info, ctxt);
+		// Don't bother saving PC if it's zero, which is
+		// probably a call to a nil func: the old link register
+		// is more useful in the stack trace.
+		if(gp->sigpc != 0)
+			SIG_LR(info, ctxt) = gp->sigpc;
+		// In case we are panicking from external C code
+		SIG_R10(info, ctxt) = (uintptr)gp;
+		SIG_PC(info, ctxt) = (uintptr)runtime·sigpanic;
+		return;
+	}
+
+	if(SIG_CODE0(info, ctxt) == SI_USER || (t->flags & SigNotify))
+		if(runtime·sigsend(sig))
+			return;
+	if(t->flags & SigKill)
+		runtime·exit(2);
+	if(!(t->flags & SigThrow))
+		return;
+
+	g->m->throwing = 1;
+	g->m->caughtsig = gp;
+	if(runtime·panicking)	// traceback already printed
+		runtime·exit(2);
+	runtime·panicking = 1;
+
+	if(sig < 0 || sig >= NSIG)
+		runtime·printf("Signal %d\n", sig);
+	else
+		runtime·printf("%s\n", runtime·sigtab[sig].name);
+
+	runtime·printf("PC=%x\n", SIG_PC(info, ctxt));
+	if(g->m->lockedg != nil && g->m->ncgo > 0 && gp == g->m->g0) {
+		runtime·printf("signal arrived during cgo execution\n");
+		gp = g->m->lockedg;
+	}
+	runtime·printf("\n");
+
+	if(runtime·gotraceback(&crash)){
+		runtime·goroutineheader(gp);
+		runtime·tracebacktrap(SIG_PC(info, ctxt), SIG_SP(info, ctxt), SIG_LR(info, ctxt), gp);
+		runtime·tracebackothers(gp);
+		runtime·printf("\n");
+		runtime·dumpregs(info, ctxt);
+	}
+	
+	if(crash)
+		runtime·crash();
+
+	runtime·exit(2);
+}
diff --git a/src/pkg/runtime/signal_darwin_386.h b/src/runtime/signal_darwin_386.h
similarity index 100%
rename from src/pkg/runtime/signal_darwin_386.h
rename to src/runtime/signal_darwin_386.h
diff --git a/src/pkg/runtime/signal_darwin_amd64.h b/src/runtime/signal_darwin_amd64.h
similarity index 100%
rename from src/pkg/runtime/signal_darwin_amd64.h
rename to src/runtime/signal_darwin_amd64.h
diff --git a/src/pkg/runtime/signal_dragonfly_386.h b/src/runtime/signal_dragonfly_386.h
similarity index 100%
rename from src/pkg/runtime/signal_dragonfly_386.h
rename to src/runtime/signal_dragonfly_386.h
diff --git a/src/pkg/runtime/signal_dragonfly_amd64.h b/src/runtime/signal_dragonfly_amd64.h
similarity index 100%
rename from src/pkg/runtime/signal_dragonfly_amd64.h
rename to src/runtime/signal_dragonfly_amd64.h
diff --git a/src/pkg/runtime/signal_freebsd_386.h b/src/runtime/signal_freebsd_386.h
similarity index 100%
rename from src/pkg/runtime/signal_freebsd_386.h
rename to src/runtime/signal_freebsd_386.h
diff --git a/src/pkg/runtime/signal_freebsd_amd64.h b/src/runtime/signal_freebsd_amd64.h
similarity index 100%
rename from src/pkg/runtime/signal_freebsd_amd64.h
rename to src/runtime/signal_freebsd_amd64.h
diff --git a/src/pkg/runtime/signal_freebsd_arm.h b/src/runtime/signal_freebsd_arm.h
similarity index 100%
rename from src/pkg/runtime/signal_freebsd_arm.h
rename to src/runtime/signal_freebsd_arm.h
diff --git a/src/pkg/runtime/signal_linux_386.h b/src/runtime/signal_linux_386.h
similarity index 100%
rename from src/pkg/runtime/signal_linux_386.h
rename to src/runtime/signal_linux_386.h
diff --git a/src/pkg/runtime/signal_linux_amd64.h b/src/runtime/signal_linux_amd64.h
similarity index 100%
rename from src/pkg/runtime/signal_linux_amd64.h
rename to src/runtime/signal_linux_amd64.h
diff --git a/src/pkg/runtime/signal_linux_arm.h b/src/runtime/signal_linux_arm.h
similarity index 100%
rename from src/pkg/runtime/signal_linux_arm.h
rename to src/runtime/signal_linux_arm.h
diff --git a/src/pkg/runtime/signal_nacl_386.h b/src/runtime/signal_nacl_386.h
similarity index 100%
rename from src/pkg/runtime/signal_nacl_386.h
rename to src/runtime/signal_nacl_386.h
diff --git a/src/runtime/signal_nacl_amd64p32.h b/src/runtime/signal_nacl_amd64p32.h
new file mode 100644
index 0000000..f62305c
--- /dev/null
+++ b/src/runtime/signal_nacl_amd64p32.h
@@ -0,0 +1,31 @@
+// Copyright 2013 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#define SIG_REGS(ctxt) (((ExcContext*)(ctxt))->regs.regs64)
+
+#define SIG_RAX(info, ctxt) (SIG_REGS(ctxt).rax)
+#define SIG_RBX(info, ctxt) (SIG_REGS(ctxt).rbx)
+#define SIG_RCX(info, ctxt) (SIG_REGS(ctxt).rcx)
+#define SIG_RDX(info, ctxt) (SIG_REGS(ctxt).rdx)
+#define SIG_RDI(info, ctxt) (SIG_REGS(ctxt).rdi)
+#define SIG_RSI(info, ctxt) (SIG_REGS(ctxt).rsi)
+#define SIG_RBP(info, ctxt) (SIG_REGS(ctxt).rbp)
+#define SIG_RSP(info, ctxt) (SIG_REGS(ctxt).rsp)
+#define SIG_R8(info, ctxt) (SIG_REGS(ctxt).r8)
+#define SIG_R9(info, ctxt) (SIG_REGS(ctxt).r9)
+#define SIG_R10(info, ctxt) (SIG_REGS(ctxt).r10)
+#define SIG_R11(info, ctxt) (SIG_REGS(ctxt).r11)
+#define SIG_R12(info, ctxt) (SIG_REGS(ctxt).r12)
+#define SIG_R13(info, ctxt) (SIG_REGS(ctxt).r13)
+#define SIG_R14(info, ctxt) (SIG_REGS(ctxt).r14)
+#define SIG_R15(info, ctxt) (SIG_REGS(ctxt).r15)
+#define SIG_RIP(info, ctxt) (SIG_REGS(ctxt).rip)
+#define SIG_RFLAGS(info, ctxt) (SIG_REGS(ctxt).rflags)
+
+#define SIG_CS(info, ctxt) (~0)
+#define SIG_FS(info, ctxt) (~0)
+#define SIG_GS(info, ctxt) (~0)
+
+#define SIG_CODE0(info, ctxt) (~0)
+#define SIG_CODE1(info, ctxt) (0)
diff --git a/src/runtime/signal_nacl_arm.h b/src/runtime/signal_nacl_arm.h
new file mode 100644
index 0000000..e5bbb21
--- /dev/null
+++ b/src/runtime/signal_nacl_arm.h
@@ -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.
+
+#define SIG_REGS(ctxt) (((ExcContext*)(ctxt))->regs)
+
+#define SIG_R0(info, ctxt) (SIG_REGS(ctxt).r0)
+#define SIG_R1(info, ctxt) (SIG_REGS(ctxt).r1)
+#define SIG_R2(info, ctxt) (SIG_REGS(ctxt).r2)
+#define SIG_R3(info, ctxt) (SIG_REGS(ctxt).r3)
+#define SIG_R4(info, ctxt) (SIG_REGS(ctxt).r4)
+#define SIG_R5(info, ctxt) (SIG_REGS(ctxt).r5)
+#define SIG_R6(info, ctxt) (SIG_REGS(ctxt).r6)
+#define SIG_R7(info, ctxt) (SIG_REGS(ctxt).r7)
+#define SIG_R8(info, ctxt) (SIG_REGS(ctxt).r8)
+#define SIG_R9(info, ctxt) (SIG_REGS(ctxt).r9)
+#define SIG_R10(info, ctxt) (SIG_REGS(ctxt).r10)
+#define SIG_FP(info, ctxt) (SIG_REGS(ctxt).r11)
+#define SIG_IP(info, ctxt) (SIG_REGS(ctxt).r12)
+#define SIG_SP(info, ctxt) (SIG_REGS(ctxt).sp)
+#define SIG_LR(info, ctxt) (SIG_REGS(ctxt).lr)
+#define SIG_PC(info, ctxt) (SIG_REGS(ctxt).pc)
+#define SIG_CPSR(info, ctxt) (SIG_REGS(ctxt).cpsr)
+#define SIG_FAULT(info, ctxt) (~0)
+#define SIG_TRAP(info, ctxt) (~0)
+#define SIG_ERROR(info, ctxt) (~0)
+#define SIG_OLDMASK(info, ctxt) (~0)
+#define SIG_CODE0(info, ctxt) (~0)
diff --git a/src/pkg/runtime/signal_netbsd_386.h b/src/runtime/signal_netbsd_386.h
similarity index 100%
rename from src/pkg/runtime/signal_netbsd_386.h
rename to src/runtime/signal_netbsd_386.h
diff --git a/src/pkg/runtime/signal_netbsd_amd64.h b/src/runtime/signal_netbsd_amd64.h
similarity index 100%
rename from src/pkg/runtime/signal_netbsd_amd64.h
rename to src/runtime/signal_netbsd_amd64.h
diff --git a/src/pkg/runtime/signal_netbsd_arm.h b/src/runtime/signal_netbsd_arm.h
similarity index 100%
rename from src/pkg/runtime/signal_netbsd_arm.h
rename to src/runtime/signal_netbsd_arm.h
diff --git a/src/pkg/runtime/signal_openbsd_386.h b/src/runtime/signal_openbsd_386.h
similarity index 100%
rename from src/pkg/runtime/signal_openbsd_386.h
rename to src/runtime/signal_openbsd_386.h
diff --git a/src/pkg/runtime/signal_openbsd_amd64.h b/src/runtime/signal_openbsd_amd64.h
similarity index 100%
rename from src/pkg/runtime/signal_openbsd_amd64.h
rename to src/runtime/signal_openbsd_amd64.h
diff --git a/src/pkg/runtime/signal_solaris_amd64.h b/src/runtime/signal_solaris_amd64.h
similarity index 100%
rename from src/pkg/runtime/signal_solaris_amd64.h
rename to src/runtime/signal_solaris_amd64.h
diff --git a/src/runtime/signal_unix.c b/src/runtime/signal_unix.c
new file mode 100644
index 0000000..0e33ece
--- /dev/null
+++ b/src/runtime/signal_unix.c
@@ -0,0 +1,119 @@
+// Copyright 2012 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin dragonfly freebsd linux netbsd openbsd solaris
+
+#include "runtime.h"
+#include "defs_GOOS_GOARCH.h"
+#include "os_GOOS.h"
+#include "signal_unix.h"
+
+extern SigTab runtime·sigtab[];
+
+void
+runtime·initsig(void)
+{
+	int32 i;
+	SigTab *t;
+
+	// First call: basic setup.
+	for(i = 0; i<NSIG; i++) {
+		t = &runtime·sigtab[i];
+		if((t->flags == 0) || (t->flags & SigDefault))
+			continue;
+
+		// For some signals, we respect an inherited SIG_IGN handler
+		// rather than insist on installing our own default handler.
+		// Even these signals can be fetched using the os/signal package.
+		switch(i) {
+		case SIGHUP:
+		case SIGINT:
+			if(runtime·getsig(i) == SIG_IGN) {
+				t->flags = SigNotify | SigIgnored;
+				continue;
+			}
+		}
+
+		t->flags |= SigHandling;
+		runtime·setsig(i, runtime·sighandler, true);
+	}
+}
+
+void
+runtime·sigenable(uint32 sig)
+{
+	SigTab *t;
+
+	if(sig >= NSIG)
+		return;
+
+	t = &runtime·sigtab[sig];
+	if((t->flags & SigNotify) && !(t->flags & SigHandling)) {
+		t->flags |= SigHandling;
+		if(runtime·getsig(sig) == SIG_IGN)
+			t->flags |= SigIgnored;
+		runtime·setsig(sig, runtime·sighandler, true);
+	}
+}
+
+void
+runtime·sigdisable(uint32 sig)
+{
+	SigTab *t;
+
+	if(sig >= NSIG)
+		return;
+
+	t = &runtime·sigtab[sig];
+	if((t->flags & SigNotify) && (t->flags & SigHandling)) {
+		t->flags &= ~SigHandling;
+		if(t->flags & SigIgnored)
+			runtime·setsig(sig, SIG_IGN, true);
+		else
+			runtime·setsig(sig, SIG_DFL, true);
+	}
+}
+
+void
+runtime·resetcpuprofiler(int32 hz)
+{
+	Itimerval it;
+
+	runtime·memclr((byte*)&it, sizeof it);
+	if(hz == 0) {
+		runtime·setitimer(ITIMER_PROF, &it, nil);
+	} else {
+		it.it_interval.tv_sec = 0;
+		it.it_interval.tv_usec = 1000000 / hz;
+		it.it_value = it.it_interval;
+		runtime·setitimer(ITIMER_PROF, &it, nil);
+	}
+	g->m->profilehz = hz;
+}
+
+void
+runtime·sigpipe(void)
+{
+	runtime·setsig(SIGPIPE, SIG_DFL, false);
+	runtime·raise(SIGPIPE);
+}
+
+void
+runtime·crash(void)
+{
+#ifdef GOOS_darwin
+	// OS X core dumps are linear dumps of the mapped memory,
+	// from the first virtual byte to the last, with zeros in the gaps.
+	// Because of the way we arrange the address space on 64-bit systems,
+	// this means the OS X core file will be >128 GB and even on a zippy
+	// workstation can take OS X well over an hour to write (uninterruptible).
+	// Save users from making that mistake.
+	if(sizeof(void*) == 8)
+		return;
+#endif
+
+	runtime·unblocksignals();
+	runtime·setsig(SIGABRT, SIG_DFL, false);
+	runtime·raise(SIGABRT);
+}
diff --git a/src/runtime/signal_unix.go b/src/runtime/signal_unix.go
new file mode 100644
index 0000000..ba77b6e
--- /dev/null
+++ b/src/runtime/signal_unix.go
@@ -0,0 +1,13 @@
+// Copyright 2012 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin dragonfly freebsd linux netbsd openbsd solaris
+
+package runtime
+
+func sigpipe()
+
+func os_sigpipe() {
+	onM(sigpipe)
+}
diff --git a/src/pkg/runtime/signal_unix.h b/src/runtime/signal_unix.h
similarity index 100%
rename from src/pkg/runtime/signal_unix.h
rename to src/runtime/signal_unix.h
diff --git a/src/runtime/signals_android.h b/src/runtime/signals_android.h
new file mode 100644
index 0000000..5140d8a
--- /dev/null
+++ b/src/runtime/signals_android.h
@@ -0,0 +1 @@
+#include "signals_linux.h"
diff --git a/src/runtime/signals_darwin.h b/src/runtime/signals_darwin.h
new file mode 100644
index 0000000..8761e1b
--- /dev/null
+++ b/src/runtime/signals_darwin.h
@@ -0,0 +1,53 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+#define N SigNotify
+#define K SigKill
+#define T SigThrow
+#define P SigPanic
+#define D SigDefault
+
+#pragma dataflag NOPTR
+SigTab runtime·sigtab[] = {
+	/* 0 */	0, "SIGNONE: no trap",
+	/* 1 */	N+K, "SIGHUP: terminal line hangup",
+	/* 2 */	N+K, "SIGINT: interrupt",
+	/* 3 */	N+T, "SIGQUIT: quit",
+	/* 4 */	T, "SIGILL: illegal instruction",
+	/* 5 */	T, "SIGTRAP: trace trap",
+	/* 6 */	N+T, "SIGABRT: abort",
+	/* 7 */	T, "SIGEMT: emulate instruction executed",
+	/* 8 */	P, "SIGFPE: floating-point exception",
+	/* 9 */	0, "SIGKILL: kill",
+	/* 10 */	P, "SIGBUS: bus error",
+	/* 11 */	P, "SIGSEGV: segmentation violation",
+	/* 12 */	T, "SIGSYS: bad system call",
+	/* 13 */	N, "SIGPIPE: write to broken pipe",
+	/* 14 */	N, "SIGALRM: alarm clock",
+	/* 15 */	N+K, "SIGTERM: termination",
+	/* 16 */	N, "SIGURG: urgent condition on socket",
+	/* 17 */	0, "SIGSTOP: stop",
+	/* 18 */	N+D, "SIGTSTP: keyboard stop",
+	/* 19 */	0, "SIGCONT: continue after stop",
+	/* 20 */	N, "SIGCHLD: child status has changed",
+	/* 21 */	N+D, "SIGTTIN: background read from tty",
+	/* 22 */	N+D, "SIGTTOU: background write to tty",
+	/* 23 */	N, "SIGIO: i/o now possible",
+	/* 24 */	N, "SIGXCPU: cpu limit exceeded",
+	/* 25 */	N, "SIGXFSZ: file size limit exceeded",
+	/* 26 */	N, "SIGVTALRM: virtual alarm clock",
+	/* 27 */	N, "SIGPROF: profiling alarm clock",
+	/* 28 */	N, "SIGWINCH: window size change",
+	/* 29 */	N, "SIGINFO: status request from keyboard",
+	/* 30 */	N, "SIGUSR1: user-defined signal 1",
+	/* 31 */	N, "SIGUSR2: user-defined signal 2",
+};
+
+#undef N
+#undef K
+#undef T
+#undef P
+#undef D
diff --git a/src/runtime/signals_dragonfly.h b/src/runtime/signals_dragonfly.h
new file mode 100644
index 0000000..07343a7
--- /dev/null
+++ b/src/runtime/signals_dragonfly.h
@@ -0,0 +1,54 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+#define N SigNotify
+#define K SigKill
+#define T SigThrow
+#define P SigPanic
+#define D SigDefault
+
+#pragma dataflag NOPTR
+SigTab runtime·sigtab[] = {
+	/* 0 */	0, "SIGNONE: no trap",
+	/* 1 */	N+K, "SIGHUP: terminal line hangup",
+	/* 2 */	N+K, "SIGINT: interrupt",
+	/* 3 */	N+T, "SIGQUIT: quit",
+	/* 4 */	T, "SIGILL: illegal instruction",
+	/* 5 */	T, "SIGTRAP: trace trap",
+	/* 6 */	N+T, "SIGABRT: abort",
+	/* 7 */	T, "SIGEMT: emulate instruction executed",
+	/* 8 */	P, "SIGFPE: floating-point exception",
+	/* 9 */	0, "SIGKILL: kill",
+	/* 10 */	P, "SIGBUS: bus error",
+	/* 11 */	P, "SIGSEGV: segmentation violation",
+	/* 12 */	T, "SIGSYS: bad system call",
+	/* 13 */	N, "SIGPIPE: write to broken pipe",
+	/* 14 */	N, "SIGALRM: alarm clock",
+	/* 15 */	N+K, "SIGTERM: termination",
+	/* 16 */	N, "SIGURG: urgent condition on socket",
+	/* 17 */	0, "SIGSTOP: stop",
+	/* 18 */	N+D, "SIGTSTP: keyboard stop",
+	/* 19 */	0, "SIGCONT: continue after stop",
+	/* 20 */	N, "SIGCHLD: child status has changed",
+	/* 21 */	N+D, "SIGTTIN: background read from tty",
+	/* 22 */	N+D, "SIGTTOU: background write to tty",
+	/* 23 */	N, "SIGIO: i/o now possible",
+	/* 24 */	N, "SIGXCPU: cpu limit exceeded",
+	/* 25 */	N, "SIGXFSZ: file size limit exceeded",
+	/* 26 */	N, "SIGVTALRM: virtual alarm clock",
+	/* 27 */	N, "SIGPROF: profiling alarm clock",
+	/* 28 */	N, "SIGWINCH: window size change",
+	/* 29 */	N, "SIGINFO: status request from keyboard",
+	/* 30 */	N, "SIGUSR1: user-defined signal 1",
+	/* 31 */	N, "SIGUSR2: user-defined signal 2",
+	/* 32 */	N, "SIGTHR: reserved",
+};
+
+#undef N
+#undef K
+#undef T
+#undef P
+#undef D
diff --git a/src/runtime/signals_freebsd.h b/src/runtime/signals_freebsd.h
new file mode 100644
index 0000000..39e0a94
--- /dev/null
+++ b/src/runtime/signals_freebsd.h
@@ -0,0 +1,54 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+#define N SigNotify
+#define K SigKill
+#define T SigThrow
+#define P SigPanic
+#define D SigDefault
+
+#pragma dataflag NOPTR
+SigTab runtime·sigtab[] = {
+	/* 0 */	0, "SIGNONE: no trap",
+	/* 1 */	N+K, "SIGHUP: terminal line hangup",
+	/* 2 */	N+K, "SIGINT: interrupt",
+	/* 3 */	N+T, "SIGQUIT: quit",
+	/* 4 */	T, "SIGILL: illegal instruction",
+	/* 5 */	T, "SIGTRAP: trace trap",
+	/* 6 */	N+T, "SIGABRT: abort",
+	/* 7 */	T, "SIGEMT: emulate instruction executed",
+	/* 8 */	P, "SIGFPE: floating-point exception",
+	/* 9 */	0, "SIGKILL: kill",
+	/* 10 */	P, "SIGBUS: bus error",
+	/* 11 */	P, "SIGSEGV: segmentation violation",
+	/* 12 */	N, "SIGSYS: bad system call",
+	/* 13 */	N, "SIGPIPE: write to broken pipe",
+	/* 14 */	N, "SIGALRM: alarm clock",
+	/* 15 */	N+K, "SIGTERM: termination",
+	/* 16 */	N, "SIGURG: urgent condition on socket",
+	/* 17 */	0, "SIGSTOP: stop",
+	/* 18 */	N+D, "SIGTSTP: keyboard stop",
+	/* 19 */	0, "SIGCONT: continue after stop",
+	/* 20 */	N, "SIGCHLD: child status has changed",
+	/* 21 */	N+D, "SIGTTIN: background read from tty",
+	/* 22 */	N+D, "SIGTTOU: background write to tty",
+	/* 23 */	N, "SIGIO: i/o now possible",
+	/* 24 */	N, "SIGXCPU: cpu limit exceeded",
+	/* 25 */	N, "SIGXFSZ: file size limit exceeded",
+	/* 26 */	N, "SIGVTALRM: virtual alarm clock",
+	/* 27 */	N, "SIGPROF: profiling alarm clock",
+	/* 28 */	N, "SIGWINCH: window size change",
+	/* 29 */	N, "SIGINFO: status request from keyboard",
+	/* 30 */	N, "SIGUSR1: user-defined signal 1",
+	/* 31 */	N, "SIGUSR2: user-defined signal 2",
+	/* 32 */	N, "SIGTHR: reserved",
+};
+
+#undef N
+#undef K
+#undef T
+#undef P
+#undef D
diff --git a/src/runtime/signals_linux.h b/src/runtime/signals_linux.h
new file mode 100644
index 0000000..3741076
--- /dev/null
+++ b/src/runtime/signals_linux.h
@@ -0,0 +1,86 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+#define N SigNotify
+#define K SigKill
+#define T SigThrow
+#define P SigPanic
+#define D SigDefault
+
+#pragma dataflag NOPTR
+SigTab runtime·sigtab[] = {
+	/* 0 */	0, "SIGNONE: no trap",
+	/* 1 */	N+K, "SIGHUP: terminal line hangup",
+	/* 2 */	N+K, "SIGINT: interrupt",
+	/* 3 */	N+T, "SIGQUIT: quit",
+	/* 4 */	T, "SIGILL: illegal instruction",
+	/* 5 */	T, "SIGTRAP: trace trap",
+	/* 6 */	N+T, "SIGABRT: abort",
+	/* 7 */	P, "SIGBUS: bus error",
+	/* 8 */	P, "SIGFPE: floating-point exception",
+	/* 9 */	0, "SIGKILL: kill",
+	/* 10 */	N, "SIGUSR1: user-defined signal 1",
+	/* 11 */	P, "SIGSEGV: segmentation violation",
+	/* 12 */	N, "SIGUSR2: user-defined signal 2",
+	/* 13 */	N, "SIGPIPE: write to broken pipe",
+	/* 14 */	N, "SIGALRM: alarm clock",
+	/* 15 */	N+K, "SIGTERM: termination",
+	/* 16 */	T, "SIGSTKFLT: stack fault",
+	/* 17 */	N, "SIGCHLD: child status has changed",
+	/* 18 */	0, "SIGCONT: continue",
+	/* 19 */	0, "SIGSTOP: stop, unblockable",
+	/* 20 */	N+D, "SIGTSTP: keyboard stop",
+	/* 21 */	N+D, "SIGTTIN: background read from tty",
+	/* 22 */	N+D, "SIGTTOU: background write to tty",
+	/* 23 */	N, "SIGURG: urgent condition on socket",
+	/* 24 */	N, "SIGXCPU: cpu limit exceeded",
+	/* 25 */	N, "SIGXFSZ: file size limit exceeded",
+	/* 26 */	N, "SIGVTALRM: virtual alarm clock",
+	/* 27 */	N, "SIGPROF: profiling alarm clock",
+	/* 28 */	N, "SIGWINCH: window size change",
+	/* 29 */	N, "SIGIO: i/o now possible",
+	/* 30 */	N, "SIGPWR: power failure restart",
+	/* 31 */	N, "SIGSYS: bad system call",
+	/* 32 */	0, "signal 32", /* SIGCANCEL; see issue 6997 */
+	/* 33 */	0, "signal 33", /* SIGSETXID; see issue 3871 */
+	/* 34 */	N, "signal 34",
+	/* 35 */	N, "signal 35",
+	/* 36 */	N, "signal 36",
+	/* 37 */	N, "signal 37",
+	/* 38 */	N, "signal 38",
+	/* 39 */	N, "signal 39",
+	/* 40 */	N, "signal 40",
+	/* 41 */	N, "signal 41",
+	/* 42 */	N, "signal 42",
+	/* 43 */	N, "signal 43",
+	/* 44 */	N, "signal 44",
+	/* 45 */	N, "signal 45",
+	/* 46 */	N, "signal 46",
+	/* 47 */	N, "signal 47",
+	/* 48 */	N, "signal 48",
+	/* 49 */	N, "signal 49",
+	/* 50 */	N, "signal 50",
+	/* 51 */	N, "signal 51",
+	/* 52 */	N, "signal 52",
+	/* 53 */	N, "signal 53",
+	/* 54 */	N, "signal 54",
+	/* 55 */	N, "signal 55",
+	/* 56 */	N, "signal 56",
+	/* 57 */	N, "signal 57",
+	/* 58 */	N, "signal 58",
+	/* 59 */	N, "signal 59",
+	/* 60 */	N, "signal 60",
+	/* 61 */	N, "signal 61",
+	/* 62 */	N, "signal 62",
+	/* 63 */	N, "signal 63",
+	/* 64 */	N, "signal 64",
+};
+
+#undef N
+#undef K
+#undef T
+#undef P
+#undef D
diff --git a/src/runtime/signals_nacl.h b/src/runtime/signals_nacl.h
new file mode 100644
index 0000000..8761e1b
--- /dev/null
+++ b/src/runtime/signals_nacl.h
@@ -0,0 +1,53 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+#define N SigNotify
+#define K SigKill
+#define T SigThrow
+#define P SigPanic
+#define D SigDefault
+
+#pragma dataflag NOPTR
+SigTab runtime·sigtab[] = {
+	/* 0 */	0, "SIGNONE: no trap",
+	/* 1 */	N+K, "SIGHUP: terminal line hangup",
+	/* 2 */	N+K, "SIGINT: interrupt",
+	/* 3 */	N+T, "SIGQUIT: quit",
+	/* 4 */	T, "SIGILL: illegal instruction",
+	/* 5 */	T, "SIGTRAP: trace trap",
+	/* 6 */	N+T, "SIGABRT: abort",
+	/* 7 */	T, "SIGEMT: emulate instruction executed",
+	/* 8 */	P, "SIGFPE: floating-point exception",
+	/* 9 */	0, "SIGKILL: kill",
+	/* 10 */	P, "SIGBUS: bus error",
+	/* 11 */	P, "SIGSEGV: segmentation violation",
+	/* 12 */	T, "SIGSYS: bad system call",
+	/* 13 */	N, "SIGPIPE: write to broken pipe",
+	/* 14 */	N, "SIGALRM: alarm clock",
+	/* 15 */	N+K, "SIGTERM: termination",
+	/* 16 */	N, "SIGURG: urgent condition on socket",
+	/* 17 */	0, "SIGSTOP: stop",
+	/* 18 */	N+D, "SIGTSTP: keyboard stop",
+	/* 19 */	0, "SIGCONT: continue after stop",
+	/* 20 */	N, "SIGCHLD: child status has changed",
+	/* 21 */	N+D, "SIGTTIN: background read from tty",
+	/* 22 */	N+D, "SIGTTOU: background write to tty",
+	/* 23 */	N, "SIGIO: i/o now possible",
+	/* 24 */	N, "SIGXCPU: cpu limit exceeded",
+	/* 25 */	N, "SIGXFSZ: file size limit exceeded",
+	/* 26 */	N, "SIGVTALRM: virtual alarm clock",
+	/* 27 */	N, "SIGPROF: profiling alarm clock",
+	/* 28 */	N, "SIGWINCH: window size change",
+	/* 29 */	N, "SIGINFO: status request from keyboard",
+	/* 30 */	N, "SIGUSR1: user-defined signal 1",
+	/* 31 */	N, "SIGUSR2: user-defined signal 2",
+};
+
+#undef N
+#undef K
+#undef T
+#undef P
+#undef D
diff --git a/src/runtime/signals_netbsd.h b/src/runtime/signals_netbsd.h
new file mode 100644
index 0000000..950a2fe
--- /dev/null
+++ b/src/runtime/signals_netbsd.h
@@ -0,0 +1,54 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+#define N SigNotify
+#define K SigKill
+#define T SigThrow
+#define P SigPanic
+#define D SigDefault
+
+#pragma dataflag NOPTR
+SigTab runtime·sigtab[] = {
+	/*  0 */	0, "SIGNONE: no trap",
+	/*  1 */	N+K, "SIGHUP: terminal line hangup",
+	/*  2 */	N+K, "SIGINT: interrupt",
+	/*  3 */	N+T, "SIGQUIT: quit",
+	/*  4 */	T, "SIGILL: illegal instruction",
+	/*  5 */	T, "SIGTRAP: trace trap",
+	/*  6 */	N+T, "SIGABRT: abort",
+	/*  7 */	T, "SIGEMT: emulate instruction executed",
+	/*  8 */	P, "SIGFPE: floating-point exception",
+	/*  9 */	0, "SIGKILL: kill",
+	/* 10 */	P, "SIGBUS: bus error",
+	/* 11 */	P, "SIGSEGV: segmentation violation",
+	/* 12 */	T, "SIGSYS: bad system call",
+	/* 13 */	N, "SIGPIPE: write to broken pipe",
+	/* 14 */	N, "SIGALRM: alarm clock",
+	/* 15 */	N+K, "SIGTERM: termination",
+	/* 16 */	N, "SIGURG: urgent condition on socket",
+	/* 17 */	0, "SIGSTOP: stop",
+	/* 18 */	N+D, "SIGTSTP: keyboard stop",
+	/* 19 */	0, "SIGCONT: continue after stop",
+	/* 20 */	N, "SIGCHLD: child status has changed",
+	/* 21 */	N+D, "SIGTTIN: background read from tty",
+	/* 22 */	N+D, "SIGTTOU: background write to tty",
+	/* 23 */	N, "SIGIO: i/o now possible",
+	/* 24 */	N, "SIGXCPU: cpu limit exceeded",
+	/* 25 */	N, "SIGXFSZ: file size limit exceeded",
+	/* 26 */	N, "SIGVTALRM: virtual alarm clock",
+	/* 27 */	N, "SIGPROF: profiling alarm clock",
+	/* 28 */	N, "SIGWINCH: window size change",
+	/* 29 */	N, "SIGINFO: status request from keyboard",
+	/* 30 */	N, "SIGUSR1: user-defined signal 1",
+	/* 31 */	N, "SIGUSR2: user-defined signal 2",
+	/* 32 */	N, "SIGTHR: reserved",
+};
+
+#undef N
+#undef K
+#undef T
+#undef P
+#undef D
diff --git a/src/runtime/signals_openbsd.h b/src/runtime/signals_openbsd.h
new file mode 100644
index 0000000..950a2fe
--- /dev/null
+++ b/src/runtime/signals_openbsd.h
@@ -0,0 +1,54 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+#define N SigNotify
+#define K SigKill
+#define T SigThrow
+#define P SigPanic
+#define D SigDefault
+
+#pragma dataflag NOPTR
+SigTab runtime·sigtab[] = {
+	/*  0 */	0, "SIGNONE: no trap",
+	/*  1 */	N+K, "SIGHUP: terminal line hangup",
+	/*  2 */	N+K, "SIGINT: interrupt",
+	/*  3 */	N+T, "SIGQUIT: quit",
+	/*  4 */	T, "SIGILL: illegal instruction",
+	/*  5 */	T, "SIGTRAP: trace trap",
+	/*  6 */	N+T, "SIGABRT: abort",
+	/*  7 */	T, "SIGEMT: emulate instruction executed",
+	/*  8 */	P, "SIGFPE: floating-point exception",
+	/*  9 */	0, "SIGKILL: kill",
+	/* 10 */	P, "SIGBUS: bus error",
+	/* 11 */	P, "SIGSEGV: segmentation violation",
+	/* 12 */	T, "SIGSYS: bad system call",
+	/* 13 */	N, "SIGPIPE: write to broken pipe",
+	/* 14 */	N, "SIGALRM: alarm clock",
+	/* 15 */	N+K, "SIGTERM: termination",
+	/* 16 */	N, "SIGURG: urgent condition on socket",
+	/* 17 */	0, "SIGSTOP: stop",
+	/* 18 */	N+D, "SIGTSTP: keyboard stop",
+	/* 19 */	0, "SIGCONT: continue after stop",
+	/* 20 */	N, "SIGCHLD: child status has changed",
+	/* 21 */	N+D, "SIGTTIN: background read from tty",
+	/* 22 */	N+D, "SIGTTOU: background write to tty",
+	/* 23 */	N, "SIGIO: i/o now possible",
+	/* 24 */	N, "SIGXCPU: cpu limit exceeded",
+	/* 25 */	N, "SIGXFSZ: file size limit exceeded",
+	/* 26 */	N, "SIGVTALRM: virtual alarm clock",
+	/* 27 */	N, "SIGPROF: profiling alarm clock",
+	/* 28 */	N, "SIGWINCH: window size change",
+	/* 29 */	N, "SIGINFO: status request from keyboard",
+	/* 30 */	N, "SIGUSR1: user-defined signal 1",
+	/* 31 */	N, "SIGUSR2: user-defined signal 2",
+	/* 32 */	N, "SIGTHR: reserved",
+};
+
+#undef N
+#undef K
+#undef T
+#undef P
+#undef D
diff --git a/src/runtime/signals_plan9.h b/src/runtime/signals_plan9.h
new file mode 100644
index 0000000..4ee8e54
--- /dev/null
+++ b/src/runtime/signals_plan9.h
@@ -0,0 +1,63 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+#define N SigNotify
+#define K SigKill
+#define T SigThrow
+#define P SigPanic
+#define E SigGoExit
+
+// Incoming notes are compared against this table using strncmp, so the
+// order matters: longer patterns must appear before their prefixes.
+// There are #defined SIG constants in os_plan9.h for the table index of
+// some of these.
+//
+// If you add entries to this table, you must respect the prefix ordering
+// and also update the constant values is os_plan9.h.
+
+#pragma dataflag NOPTR
+SigTab runtime·sigtab[] = {
+	// Traps that we cannot be recovered.
+	T,	"sys: trap: debug exception",
+	T,	"sys: trap: invalid opcode",
+
+	// We can recover from some memory errors in runtime·sigpanic.
+	P,	"sys: trap: fault read addr",	// SIGRFAULT
+	P,	"sys: trap: fault write addr",	// SIGWFAULT
+
+	// We can also recover from math errors.
+	P,	"sys: trap: divide error",	// SIGINTDIV
+	P,	"sys: fp:",	// SIGFLOAT
+
+	// All other traps are normally handled as if they were marked SigThrow.
+	// We mark them SigPanic here so that debug.SetPanicOnFault will work.
+	P,	"sys: trap:",	// SIGTRAP
+
+	// Writes to a closed pipe can be handled if desired, otherwise they're ignored.
+	N,	"sys: write on closed pipe",
+
+	// Other system notes are more serious and cannot be recovered.
+	T,	"sys:",
+
+	// Issued to all other procs when calling runtime·exit.
+	E,	"go: exit ",
+
+	// Kill is sent by external programs to cause an exit.
+	K,	"kill",
+
+	// Interrupts can be handled if desired, otherwise they cause an exit.
+	N+K,	"interrupt",
+	N+K,	"hangup",
+
+	// Alarms can be handled if desired, otherwise they're ignored.
+	N,	"alarm",
+};
+
+#undef N
+#undef K
+#undef T
+#undef P
+#undef E
diff --git a/src/runtime/signals_solaris.h b/src/runtime/signals_solaris.h
new file mode 100644
index 0000000..1f0a65e
--- /dev/null
+++ b/src/runtime/signals_solaris.h
@@ -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.
+
+#include "textflag.h"
+
+#define N SigNotify
+#define K SigKill
+#define T SigThrow
+#define P SigPanic
+#define D SigDefault
+
+#pragma dataflag NOPTR
+SigTab runtime·sigtab[] = {
+	/* 0 */		0, "SIGNONE: no trap",
+	/* 1 */		N+K, "SIGHUP: hangup",
+	/* 2 */		N+K, "SIGINT: interrupt (rubout)",
+	/* 3 */		N+T, "SIGQUIT: quit (ASCII FS)",
+	/* 4 */		T, "SIGILL: illegal instruction (not reset when caught)",
+	/* 5 */		T, "SIGTRAP: trace trap (not reset when caught)",
+	/* 6 */		N+T, "SIGABRT: used by abort, replace SIGIOT in the future",
+	/* 7 */		T, "SIGEMT: EMT instruction",
+	/* 8 */		P, "SIGFPE: floating point exception",
+	/* 9 */		0, "SIGKILL: kill (cannot be caught or ignored)",
+	/* 10 */	P, "SIGBUS: bus error",
+	/* 11 */	P, "SIGSEGV: segmentation violation",
+	/* 12 */	T, "SIGSYS: bad argument to system call",
+	/* 13 */	N, "SIGPIPE: write on a pipe with no one to read it",
+	/* 14 */	N, "SIGALRM: alarm clock",
+	/* 15 */	N+K, "SIGTERM: software termination signal from kill",
+	/* 16 */	N, "SIGUSR1: user defined signal 1",
+	/* 17 */	N, "SIGUSR2: user defined signal 2",
+	/* 18 */	N, "SIGCLD: child status change",
+	/* 18 */	N, "SIGCHLD: child status change alias (POSIX)",
+	/* 19 */	N, "SIGPWR: power-fail restart",
+	/* 20 */	N, "SIGWINCH: window size change",
+	/* 21 */	N, "SIGURG: urgent socket condition",
+	/* 22 */	N, "SIGPOLL: pollable event occured",
+	/* 23 */	N+D, "SIGSTOP: stop (cannot be caught or ignored)",
+	/* 24 */	0, "SIGTSTP: user stop requested from tty",
+	/* 25 */	0, "SIGCONT: stopped process has been continued",
+	/* 26 */	N+D, "SIGTTIN: background tty read attempted",
+	/* 27 */	N+D, "SIGTTOU: background tty write attempted",
+	/* 28 */	N, "SIGVTALRM: virtual timer expired",
+	/* 29 */	N, "SIGPROF: profiling timer expired",
+	/* 30 */	N, "SIGXCPU: exceeded cpu limit",
+	/* 31 */	N, "SIGXFSZ: exceeded file size limit",
+	/* 32 */	N, "SIGWAITING: reserved signal no longer used by",
+	/* 33 */	N, "SIGLWP: reserved signal no longer used by",
+	/* 34 */	N, "SIGFREEZE: special signal used by CPR",
+	/* 35 */	N, "SIGTHAW: special signal used by CPR",
+	/* 36 */	0, "SIGCANCEL: reserved signal for thread cancellation",
+	/* 37 */	N, "SIGLOST: resource lost (eg, record-lock lost)",
+	/* 38 */	N, "SIGXRES: resource control exceeded",
+	/* 39 */	N, "SIGJVM1: reserved signal for Java Virtual Machine",
+	/* 40 */	N, "SIGJVM2: reserved signal for Java Virtual Machine",
+
+	/* TODO(aram): what should be do about these signals? D or N? is this set static? */
+	/* 41 */	N, "real time signal",
+	/* 42 */	N, "real time signal",
+	/* 43 */	N, "real time signal",
+	/* 44 */	N, "real time signal",
+	/* 45 */	N, "real time signal",
+	/* 46 */	N, "real time signal",
+	/* 47 */	N, "real time signal",
+	/* 48 */	N, "real time signal",
+	/* 49 */	N, "real time signal",
+	/* 50 */	N, "real time signal",
+	/* 51 */	N, "real time signal",
+	/* 52 */	N, "real time signal",
+	/* 53 */	N, "real time signal",
+	/* 54 */	N, "real time signal",
+	/* 55 */	N, "real time signal",
+	/* 56 */	N, "real time signal",
+	/* 57 */	N, "real time signal",
+	/* 58 */	N, "real time signal",
+	/* 59 */	N, "real time signal",
+	/* 60 */	N, "real time signal",
+	/* 61 */	N, "real time signal",
+	/* 62 */	N, "real time signal",
+	/* 63 */	N, "real time signal",
+	/* 64 */	N, "real time signal",
+	/* 65 */	N, "real time signal",
+	/* 66 */	N, "real time signal",
+	/* 67 */	N, "real time signal",
+	/* 68 */	N, "real time signal",
+	/* 69 */	N, "real time signal",
+	/* 70 */	N, "real time signal",
+	/* 71 */	N, "real time signal",
+	/* 72 */	N, "real time signal",
+};
+
+#undef N
+#undef K
+#undef T
+#undef P
+#undef D
diff --git a/src/pkg/runtime/signals_windows.h b/src/runtime/signals_windows.h
similarity index 100%
rename from src/pkg/runtime/signals_windows.h
rename to src/runtime/signals_windows.h
diff --git a/src/runtime/sigpanic_unix.go b/src/runtime/sigpanic_unix.go
new file mode 100644
index 0000000..6807985
--- /dev/null
+++ b/src/runtime/sigpanic_unix.go
@@ -0,0 +1,40 @@
+// 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.
+
+// +build darwin dragonfly freebsd linux netbsd openbsd solaris
+
+package runtime
+
+func signame(int32) *byte
+
+func sigpanic() {
+	g := getg()
+	if !canpanic(g) {
+		gothrow("unexpected signal during runtime execution")
+	}
+
+	switch g.sig {
+	case _SIGBUS:
+		if g.sigcode0 == _BUS_ADRERR && g.sigcode1 < 0x1000 || g.paniconfault {
+			panicmem()
+		}
+		print("unexpected fault address ", hex(g.sigcode1), "\n")
+		gothrow("fault")
+	case _SIGSEGV:
+		if (g.sigcode0 == 0 || g.sigcode0 == _SEGV_MAPERR || g.sigcode0 == _SEGV_ACCERR) && g.sigcode1 < 0x1000 || g.paniconfault {
+			panicmem()
+		}
+		print("unexpected fault address ", hex(g.sigcode1), "\n")
+		gothrow("fault")
+	case _SIGFPE:
+		switch g.sigcode0 {
+		case _FPE_INTDIV:
+			panicdivide()
+		case _FPE_INTOVF:
+			panicoverflow()
+		}
+		panicfloat()
+	}
+	panic(errorString(gostringnocopy(signame(g.sig))))
+}
diff --git a/src/runtime/sigqueue.go b/src/runtime/sigqueue.go
new file mode 100644
index 0000000..2d9c24d
--- /dev/null
+++ b/src/runtime/sigqueue.go
@@ -0,0 +1,173 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file implements runtime support for signal handling.
+//
+// Most synchronization primitives are not available from
+// the signal handler (it cannot block, allocate memory, or use locks)
+// so the handler communicates with a processing goroutine
+// via struct sig, below.
+//
+// sigsend is called by the signal handler to queue a new signal.
+// signal_recv is called by the Go program to receive a newly queued signal.
+// Synchronization between sigsend and signal_recv is based on the sig.state
+// variable.  It can be in 3 states: sigIdle, sigReceiving and sigSending.
+// sigReceiving means that signal_recv is blocked on sig.Note and there are no
+// new pending signals.
+// sigSending means that sig.mask *may* contain new pending signals,
+// signal_recv can't be blocked in this state.
+// sigIdle means that there are no new pending signals and signal_recv is not blocked.
+// Transitions between states are done atomically with CAS.
+// When signal_recv is unblocked, it resets sig.Note and rechecks sig.mask.
+// If several sigsends and signal_recv execute concurrently, it can lead to
+// unnecessary rechecks of sig.mask, but it cannot lead to missed signals
+// nor deadlocks.
+
+package runtime
+
+import "unsafe"
+
+var sig struct {
+	note   note
+	mask   [(_NSIG + 31) / 32]uint32
+	wanted [(_NSIG + 31) / 32]uint32
+	recv   [(_NSIG + 31) / 32]uint32
+	state  uint32
+	inuse  bool
+}
+
+const (
+	sigIdle = iota
+	sigReceiving
+	sigSending
+)
+
+// Called from sighandler to send a signal back out of the signal handling thread.
+// Reports whether the signal was sent. If not, the caller typically crashes the program.
+func sigsend(s int32) bool {
+	bit := uint32(1) << uint(s&31)
+	if !sig.inuse || s < 0 || int(s) >= 32*len(sig.wanted) || sig.wanted[s/32]&bit == 0 {
+		return false
+	}
+
+	// Add signal to outgoing queue.
+	for {
+		mask := sig.mask[s/32]
+		if mask&bit != 0 {
+			return true // signal already in queue
+		}
+		if cas(&sig.mask[s/32], mask, mask|bit) {
+			break
+		}
+	}
+
+	// Notify receiver that queue has new bit.
+Send:
+	for {
+		switch atomicload(&sig.state) {
+		default:
+			gothrow("sigsend: inconsistent state")
+		case sigIdle:
+			if cas(&sig.state, sigIdle, sigSending) {
+				break Send
+			}
+		case sigSending:
+			// notification already pending
+			break Send
+		case sigReceiving:
+			if cas(&sig.state, sigReceiving, sigIdle) {
+				notewakeup(&sig.note)
+				break Send
+			}
+		}
+	}
+
+	return true
+}
+
+// Called to receive the next queued signal.
+// Must only be called from a single goroutine at a time.
+func signal_recv() uint32 {
+	for {
+		// Serve any signals from local copy.
+		for i := uint32(0); i < _NSIG; i++ {
+			if sig.recv[i/32]&(1<<(i&31)) != 0 {
+				sig.recv[i/32] &^= 1 << (i & 31)
+				return i
+			}
+		}
+
+		// Wait for updates to be available from signal sender.
+	Receive:
+		for {
+			switch atomicload(&sig.state) {
+			default:
+				gothrow("signal_recv: inconsistent state")
+			case sigIdle:
+				if cas(&sig.state, sigIdle, sigReceiving) {
+					notetsleepg(&sig.note, -1)
+					noteclear(&sig.note)
+					break Receive
+				}
+			case sigSending:
+				if cas(&sig.state, sigSending, sigIdle) {
+					break Receive
+				}
+			}
+		}
+
+		// Incorporate updates from sender into local copy.
+		for i := range sig.mask {
+			sig.recv[i] = xchg(&sig.mask[i], 0)
+		}
+	}
+}
+
+// Must only be called from a single goroutine at a time.
+func signal_enable(s uint32) {
+	if !sig.inuse {
+		// The first call to signal_enable is for us
+		// to use for initialization.  It does not pass
+		// signal information in m.
+		sig.inuse = true // enable reception of signals; cannot disable
+		noteclear(&sig.note)
+		return
+	}
+
+	if int(s) >= len(sig.wanted)*32 {
+		return
+	}
+	sig.wanted[s/32] |= 1 << (s & 31)
+	sigenable_go(s)
+}
+
+// Must only be called from a single goroutine at a time.
+func signal_disable(s uint32) {
+	if int(s) >= len(sig.wanted)*32 {
+		return
+	}
+	sig.wanted[s/32] &^= 1 << (s & 31)
+	sigdisable_go(s)
+}
+
+// This runs on a foreign stack, without an m or a g.  No stack split.
+//go:nosplit
+func badsignal(sig uintptr) {
+	cgocallback(unsafe.Pointer(funcPC(sigsend)), noescape(unsafe.Pointer(&sig)), unsafe.Sizeof(sig))
+}
+
+func sigenable_m()
+func sigdisable_m()
+
+func sigenable_go(s uint32) {
+	g := getg()
+	g.m.scalararg[0] = uintptr(s)
+	onM(sigenable_m)
+}
+
+func sigdisable_go(s uint32) {
+	g := getg()
+	g.m.scalararg[0] = uintptr(s)
+	onM(sigdisable_m)
+}
diff --git a/src/runtime/slice.go b/src/runtime/slice.go
new file mode 100644
index 0000000..171087d
--- /dev/null
+++ b/src/runtime/slice.go
@@ -0,0 +1,139 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package runtime
+
+import (
+	"unsafe"
+)
+
+type sliceStruct struct {
+	array unsafe.Pointer
+	len   int
+	cap   int
+}
+
+// TODO: take uintptrs instead of int64s?
+func makeslice(t *slicetype, len64 int64, cap64 int64) sliceStruct {
+	// NOTE: The len > MaxMem/elemsize check here is not strictly necessary,
+	// but it produces a 'len out of range' error instead of a 'cap out of range' error
+	// when someone does make([]T, bignumber). 'cap out of range' is true too,
+	// but since the cap is only being supplied implicitly, saying len is clearer.
+	// See issue 4085.
+	len := int(len64)
+	if len64 < 0 || int64(len) != len64 || t.elem.size > 0 && uintptr(len) > maxmem/uintptr(t.elem.size) {
+		panic(errorString("makeslice: len out of range"))
+	}
+	cap := int(cap64)
+	if cap < len || int64(cap) != cap64 || t.elem.size > 0 && uintptr(cap) > maxmem/uintptr(t.elem.size) {
+		panic(errorString("makeslice: cap out of range"))
+	}
+	p := newarray(t.elem, uintptr(cap))
+	return sliceStruct{p, len, cap}
+}
+
+// TODO: take uintptr instead of int64?
+func growslice(t *slicetype, old sliceStruct, n int64) sliceStruct {
+	if n < 1 {
+		panic(errorString("growslice: invalid n"))
+	}
+
+	cap64 := int64(old.cap) + n
+	cap := int(cap64)
+
+	if int64(cap) != cap64 || cap < old.cap || t.elem.size > 0 && uintptr(cap) > maxmem/uintptr(t.elem.size) {
+		panic(errorString("growslice: cap out of range"))
+	}
+
+	if raceenabled {
+		callerpc := getcallerpc(unsafe.Pointer(&t))
+		racereadrangepc(old.array, uintptr(old.len*int(t.elem.size)), callerpc, funcPC(growslice))
+	}
+
+	et := t.elem
+	if et.size == 0 {
+		return sliceStruct{old.array, old.len, cap}
+	}
+
+	newcap := old.cap
+	if newcap+newcap < cap {
+		newcap = cap
+	} else {
+		for {
+			if old.len < 1024 {
+				newcap += newcap
+			} else {
+				newcap += newcap / 4
+			}
+			if newcap >= cap {
+				break
+			}
+		}
+	}
+
+	if uintptr(newcap) >= maxmem/uintptr(et.size) {
+		panic(errorString("growslice: cap out of range"))
+	}
+	lenmem := uintptr(old.len) * uintptr(et.size)
+	capmem := goroundupsize(uintptr(newcap) * uintptr(et.size))
+	newcap = int(capmem / uintptr(et.size))
+	var p unsafe.Pointer
+	if et.kind&kindNoPointers != 0 {
+		p = rawmem(capmem)
+		memclr(add(p, lenmem), capmem-lenmem)
+	} else {
+		// Note: can't use rawmem (which avoids zeroing of memory), because then GC can scan unitialized memory
+		p = newarray(et, uintptr(newcap))
+	}
+	memmove(p, old.array, lenmem)
+
+	return sliceStruct{p, old.len, newcap}
+}
+
+func slicecopy(to sliceStruct, fm sliceStruct, width uintptr) int {
+	if fm.len == 0 || to.len == 0 || width == 0 {
+		return 0
+	}
+
+	n := fm.len
+	if to.len < n {
+		n = to.len
+	}
+
+	if raceenabled {
+		callerpc := getcallerpc(unsafe.Pointer(&to))
+		pc := funcPC(slicecopy)
+		racewriterangepc(to.array, uintptr(n*int(width)), callerpc, pc)
+		racereadrangepc(fm.array, uintptr(n*int(width)), callerpc, pc)
+	}
+
+	size := uintptr(n) * width
+	if size == 1 { // common case worth about 2x to do here
+		// TODO: is this still worth it with new memmove impl?
+		*(*byte)(to.array) = *(*byte)(fm.array) // known to be a byte pointer
+	} else {
+		memmove(to.array, fm.array, size)
+	}
+	return int(n)
+}
+
+func slicestringcopy(to []byte, fm string) int {
+	if len(fm) == 0 || len(to) == 0 {
+		return 0
+	}
+
+	n := len(fm)
+	if len(to) < n {
+		n = len(to)
+	}
+
+	if raceenabled {
+		callerpc := getcallerpc(unsafe.Pointer(&to))
+		pc := funcPC(slicestringcopy)
+		racewriterangepc(unsafe.Pointer(&to[0]), uintptr(n), callerpc, pc)
+	}
+
+	memmove(unsafe.Pointer(&to[0]), unsafe.Pointer((*stringStruct)(unsafe.Pointer(&fm)).str), uintptr(n))
+	return n
+}
diff --git a/src/pkg/runtime/softfloat64.go b/src/runtime/softfloat64.go
similarity index 100%
rename from src/pkg/runtime/softfloat64.go
rename to src/runtime/softfloat64.go
diff --git a/src/pkg/runtime/softfloat64_test.go b/src/runtime/softfloat64_test.go
similarity index 100%
rename from src/pkg/runtime/softfloat64_test.go
rename to src/runtime/softfloat64_test.go
diff --git a/src/runtime/softfloat_arm.c b/src/runtime/softfloat_arm.c
new file mode 100644
index 0000000..3f3f33a
--- /dev/null
+++ b/src/runtime/softfloat_arm.c
@@ -0,0 +1,687 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Software floating point interpretaton of ARM 7500 FP instructions.
+// The interpretation is not bit compatible with the 7500.
+// It uses true little-endian doubles, while the 7500 used mixed-endian.
+
+#include "runtime.h"
+#include "textflag.h"
+
+#define CPSR 14
+#define FLAGS_N (1U << 31)
+#define FLAGS_Z (1U << 30)
+#define FLAGS_C (1U << 29)
+#define FLAGS_V (1U << 28)
+
+void	runtime·abort(void);
+void	runtime·sqrtC(uint64, uint64*);
+
+static	uint32	trace = 0;
+
+static void
+fabort(void)
+{
+	if (1) {
+		runtime·printf("Unsupported floating point instruction\n");
+		runtime·abort();
+	}
+}
+
+static void
+putf(uint32 reg, uint32 val)
+{
+	g->m->freglo[reg] = val;
+}
+
+static void
+putd(uint32 reg, uint64 val)
+{
+	g->m->freglo[reg] = (uint32)val;
+	g->m->freghi[reg] = (uint32)(val>>32);
+}
+
+static uint64
+getd(uint32 reg)
+{
+	return (uint64)g->m->freglo[reg] | ((uint64)g->m->freghi[reg]<<32);
+}
+
+static void
+fprint(void)
+{
+	uint32 i;
+	for (i = 0; i < 16; i++) {
+		runtime·printf("\tf%d:\t%X %X\n", i, g->m->freghi[i], g->m->freglo[i]);
+	}
+}
+
+static uint32
+d2f(uint64 d)
+{
+	uint32 x;
+
+	runtime·f64to32c(d, &x);
+	return x;
+}
+
+static uint64
+f2d(uint32 f)
+{
+	uint64 x;
+
+	runtime·f32to64c(f, &x);
+	return x;
+}
+
+static uint32
+fstatus(bool nan, int32 cmp)
+{
+	if(nan)
+		return FLAGS_C | FLAGS_V;
+	if(cmp == 0)
+		return FLAGS_Z | FLAGS_C;
+	if(cmp < 0)
+		return FLAGS_N;
+	return FLAGS_C;
+}
+
+// conditions array record the required CPSR cond field for the
+// first 5 pairs of conditional execution opcodes
+// higher 4 bits are must set, lower 4 bits are must clear
+#pragma dataflag NOPTR
+static const uint8 conditions[10/2] = {
+	[0/2] = (FLAGS_Z >> 24) | 0, // 0: EQ (Z set), 1: NE (Z clear)
+	[2/2] = (FLAGS_C >> 24) | 0, // 2: CS/HS (C set), 3: CC/LO (C clear)
+	[4/2] = (FLAGS_N >> 24) | 0, // 4: MI (N set), 5: PL (N clear)
+	[6/2] = (FLAGS_V >> 24) | 0, // 6: VS (V set), 7: VC (V clear)
+	[8/2] = (FLAGS_C >> 24) | 
+	        (FLAGS_Z >> 28),     // 8: HI (C set and Z clear), 9: LS (C clear and Z set)
+};
+
+#define FAULT (0x80000000U) // impossible PC offset
+
+// returns number of words that the fp instruction
+// is occupying, 0 if next instruction isn't float.
+static uint32
+stepflt(uint32 *pc, uint32 *regs)
+{
+	uint32 i, opc, regd, regm, regn, cpsr;
+	int32 delta;
+	uint32 *addr;
+	uint64 uval;
+	int64 sval;
+	bool nan, ok;
+	int32 cmp;
+	M *m;
+
+	// m is locked in vlop_arm.s, so g->m cannot change during this function call,
+	// so caching it in a local variable is safe.
+	m = g->m;
+	i = *pc;
+
+	if(trace)
+		runtime·printf("stepflt %p %x (cpsr %x)\n", pc, i, regs[CPSR] >> 28);
+
+	opc = i >> 28;
+	if(opc == 14) // common case first
+		goto execute;
+	cpsr = regs[CPSR] >> 28;
+	switch(opc) {
+	case 0: case 1: case 2: case 3: case 4: 
+	case 5: case 6: case 7: case 8: case 9:
+		if(((cpsr & (conditions[opc/2] >> 4)) == (conditions[opc/2] >> 4)) &&
+		   ((cpsr & (conditions[opc/2] & 0xf)) == 0)) {
+			if(opc & 1) return 1;
+		} else {
+			if(!(opc & 1)) return 1;
+		}
+		break;
+	case 10: // GE (N == V)
+	case 11: // LT (N != V)
+		if((cpsr & (FLAGS_N >> 28)) == (cpsr & (FLAGS_V >> 28))) {
+			if(opc & 1) return 1;
+		} else {
+			if(!(opc & 1)) return 1;
+		}
+		break;
+	case 12: // GT (N == V and Z == 0)
+	case 13: // LE (N != V or Z == 1)
+		if((cpsr & (FLAGS_N >> 28)) == (cpsr & (FLAGS_V >> 28)) &&
+		   (cpsr & (FLAGS_Z >> 28)) == 0) {
+			if(opc & 1) return 1;
+		} else {
+			if(!(opc & 1)) return 1;
+		}
+		break;
+	case 14: // AL
+		break;
+	case 15: // shouldn't happen
+		return 0;
+	}
+	if(trace)
+		runtime·printf("conditional %x (cpsr %x) pass\n", opc, cpsr);
+	i = (0xeU << 28) | (i & 0xfffffff);
+
+execute:
+	// special cases
+	if((i&0xfffff000) == 0xe59fb000) {
+		// load r11 from pc-relative address.
+		// might be part of a floating point move
+		// (or might not, but no harm in simulating
+		// one instruction too many).
+		addr = (uint32*)((uint8*)pc + (i&0xfff) + 8);
+		regs[11] = addr[0];
+
+		if(trace)
+			runtime·printf("*** cpu R[%d] = *(%p) %x\n",
+				11, addr, regs[11]);
+		return 1;
+	}
+	if(i == 0xe08bb00d) {
+		// add sp to r11.
+		// might be part of a large stack offset address
+		// (or might not, but again no harm done).
+		regs[11] += regs[13];
+
+		if(trace)
+			runtime·printf("*** cpu R[%d] += R[%d] %x\n",
+				11, 13, regs[11]);
+		return 1;
+	}
+	if(i == 0xeef1fa10) {
+		regs[CPSR] = (regs[CPSR]&0x0fffffff) | m->fflag;
+
+		if(trace)
+			runtime·printf("*** fpsr R[CPSR] = F[CPSR] %x\n", regs[CPSR]);
+		return 1;
+	}
+	if((i&0xff000000) == 0xea000000) {
+		// unconditional branch
+		// can happen in the middle of floating point
+		// if the linker decides it is time to lay down
+		// a sequence of instruction stream constants.
+		delta = i&0xffffff;
+		delta = (delta<<8) >> 8;	// sign extend
+
+		if(trace)
+			runtime·printf("*** cpu PC += %x\n", (delta+2)*4);
+		return delta+2;
+	}
+
+	goto stage1;
+
+stage1:	// load/store regn is cpureg, regm is 8bit offset
+	regd = i>>12 & 0xf;
+	regn = i>>16 & 0xf;
+	regm = (i & 0xff) << 2;	// PLUS or MINUS ??
+
+	switch(i & 0xfff00f00) {
+	default:
+		goto stage2;
+
+	case 0xed900a00:	// single load
+		addr = (uint32*)(regs[regn] + regm);
+		if((uintptr)addr < 4096) {
+			if(trace)
+				runtime·printf("*** load @%p => fault\n", addr);
+			return FAULT;
+		}
+		m->freglo[regd] = addr[0];
+
+		if(trace)
+			runtime·printf("*** load F[%d] = %x\n",
+				regd, m->freglo[regd]);
+		break;
+
+	case 0xed900b00:	// double load
+		addr = (uint32*)(regs[regn] + regm);
+		if((uintptr)addr < 4096) {
+			if(trace)
+				runtime·printf("*** double load @%p => fault\n", addr);
+			return FAULT;
+		}
+		m->freglo[regd] = addr[0];
+		m->freghi[regd] = addr[1];
+
+		if(trace)
+			runtime·printf("*** load D[%d] = %x-%x\n",
+				regd, m->freghi[regd], m->freglo[regd]);
+		break;
+
+	case 0xed800a00:	// single store
+		addr = (uint32*)(regs[regn] + regm);
+		if((uintptr)addr < 4096) {
+			if(trace)
+				runtime·printf("*** store @%p => fault\n", addr);
+			return FAULT;
+		}
+		addr[0] = m->freglo[regd];
+
+		if(trace)
+			runtime·printf("*** *(%p) = %x\n",
+				addr, addr[0]);
+		break;
+
+	case 0xed800b00:	// double store
+		addr = (uint32*)(regs[regn] + regm);
+		if((uintptr)addr < 4096) {
+			if(trace)
+				runtime·printf("*** double store @%p => fault\n", addr);
+			return FAULT;
+		}
+		addr[0] = m->freglo[regd];
+		addr[1] = m->freghi[regd];
+
+		if(trace)
+			runtime·printf("*** *(%p) = %x-%x\n",
+				addr, addr[1], addr[0]);
+		break;
+	}
+	return 1;
+
+stage2:	// regd, regm, regn are 4bit variables
+	regm = i>>0 & 0xf;
+	switch(i & 0xfff00ff0) {
+	default:
+		goto stage3;
+
+	case 0xf3000110:	// veor
+		m->freglo[regd] = m->freglo[regm]^m->freglo[regn];
+		m->freghi[regd] = m->freghi[regm]^m->freghi[regn];
+
+		if(trace)
+			runtime·printf("*** veor D[%d] = %x-%x\n",
+				regd, m->freghi[regd], m->freglo[regd]);
+		break;
+
+	case 0xeeb00b00:	// D[regd] = const(regn,regm)
+		regn = (regn<<4) | regm;
+		regm = 0x40000000UL;
+		if(regn & 0x80)
+			regm |= 0x80000000UL;
+		if(regn & 0x40)
+			regm ^= 0x7fc00000UL;
+		regm |= (regn & 0x3f) << 16;
+		m->freglo[regd] = 0;
+		m->freghi[regd] = regm;
+
+		if(trace)
+			runtime·printf("*** immed D[%d] = %x-%x\n",
+				regd, m->freghi[regd], m->freglo[regd]);
+		break;
+
+	case 0xeeb00a00:	// F[regd] = const(regn,regm)
+		regn = (regn<<4) | regm;
+		regm = 0x40000000UL;
+		if(regn & 0x80)
+			regm |= 0x80000000UL;
+		if(regn & 0x40)
+			regm ^= 0x7e000000UL;
+		regm |= (regn & 0x3f) << 19;
+		m->freglo[regd] = regm;
+
+		if(trace)
+			runtime·printf("*** immed D[%d] = %x\n",
+				regd, m->freglo[regd]);
+		break;
+
+	case 0xee300b00:	// D[regd] = D[regn]+D[regm]
+		runtime·fadd64c(getd(regn), getd(regm), &uval);
+		putd(regd, uval);
+
+		if(trace)
+			runtime·printf("*** add D[%d] = D[%d]+D[%d] %x-%x\n",
+				regd, regn, regm, m->freghi[regd], m->freglo[regd]);
+		break;
+
+	case 0xee300a00:	// F[regd] = F[regn]+F[regm]
+		runtime·fadd64c(f2d(m->freglo[regn]), f2d(m->freglo[regm]), &uval);
+		m->freglo[regd] = d2f(uval);
+
+		if(trace)
+			runtime·printf("*** add F[%d] = F[%d]+F[%d] %x\n",
+				regd, regn, regm, m->freglo[regd]);
+		break;
+
+	case 0xee300b40:	// D[regd] = D[regn]-D[regm]
+		runtime·fsub64c(getd(regn), getd(regm), &uval);
+		putd(regd, uval);
+
+		if(trace)
+			runtime·printf("*** sub D[%d] = D[%d]-D[%d] %x-%x\n",
+				regd, regn, regm, m->freghi[regd], m->freglo[regd]);
+		break;
+
+	case 0xee300a40:	// F[regd] = F[regn]-F[regm]
+		runtime·fsub64c(f2d(m->freglo[regn]), f2d(m->freglo[regm]), &uval);
+		m->freglo[regd] = d2f(uval);
+
+		if(trace)
+			runtime·printf("*** sub F[%d] = F[%d]-F[%d] %x\n",
+				regd, regn, regm, m->freglo[regd]);
+		break;
+
+	case 0xee200b00:	// D[regd] = D[regn]*D[regm]
+		runtime·fmul64c(getd(regn), getd(regm), &uval);
+		putd(regd, uval);
+
+		if(trace)
+			runtime·printf("*** mul D[%d] = D[%d]*D[%d] %x-%x\n",
+				regd, regn, regm, m->freghi[regd], m->freglo[regd]);
+		break;
+
+	case 0xee200a00:	// F[regd] = F[regn]*F[regm]
+		runtime·fmul64c(f2d(m->freglo[regn]), f2d(m->freglo[regm]), &uval);
+		m->freglo[regd] = d2f(uval);
+
+		if(trace)
+			runtime·printf("*** mul F[%d] = F[%d]*F[%d] %x\n",
+				regd, regn, regm, m->freglo[regd]);
+		break;
+
+	case 0xee800b00:	// D[regd] = D[regn]/D[regm]
+		runtime·fdiv64c(getd(regn), getd(regm), &uval);
+		putd(regd, uval);
+
+		if(trace)
+			runtime·printf("*** div D[%d] = D[%d]/D[%d] %x-%x\n",
+				regd, regn, regm, m->freghi[regd], m->freglo[regd]);
+		break;
+
+	case 0xee800a00:	// F[regd] = F[regn]/F[regm]
+		runtime·fdiv64c(f2d(m->freglo[regn]), f2d(m->freglo[regm]), &uval);
+		m->freglo[regd] = d2f(uval);
+
+		if(trace)
+			runtime·printf("*** div F[%d] = F[%d]/F[%d] %x\n",
+				regd, regn, regm, m->freglo[regd]);
+		break;
+
+	case 0xee000b10:	// S[regn] = R[regd] (MOVW) (regm ignored)
+		m->freglo[regn] = regs[regd];
+
+		if(trace)
+			runtime·printf("*** cpy S[%d] = R[%d] %x\n",
+				regn, regd, m->freglo[regn]);
+		break;
+
+	case 0xee100b10:	// R[regd] = S[regn] (MOVW) (regm ignored)
+		regs[regd] = m->freglo[regn];
+
+		if(trace)
+			runtime·printf("*** cpy R[%d] = S[%d] %x\n",
+				regd, regn, regs[regd]);
+		break;
+	}
+	return 1;
+
+stage3:	// regd, regm are 4bit variables
+	switch(i & 0xffff0ff0) {
+	default:
+		goto done;
+
+	case 0xeeb00a40:	// F[regd] = F[regm] (MOVF)
+		m->freglo[regd] = m->freglo[regm];
+
+		if(trace)
+			runtime·printf("*** F[%d] = F[%d] %x\n",
+				regd, regm, m->freglo[regd]);
+		break;
+
+	case 0xeeb00b40:	// D[regd] = D[regm] (MOVD)
+		m->freglo[regd] = m->freglo[regm];
+		m->freghi[regd] = m->freghi[regm];
+
+		if(trace)
+			runtime·printf("*** D[%d] = D[%d] %x-%x\n",
+				regd, regm, m->freghi[regd], m->freglo[regd]);
+		break;
+
+	case 0xeeb10bc0:	// D[regd] = sqrt D[regm]
+		runtime·sqrtC(getd(regm), &uval);
+		putd(regd, uval);
+
+		if(trace)
+			runtime·printf("*** D[%d] = sqrt D[%d] %x-%x\n",
+				regd, regm, m->freghi[regd], m->freglo[regd]);
+		break;
+
+	case 0xeeb00bc0:	// D[regd] = abs D[regm]
+		m->freglo[regd] = m->freglo[regm];
+		m->freghi[regd] = m->freghi[regm] & ((1<<31)-1);
+
+		if(trace)
+			runtime·printf("*** D[%d] = abs D[%d] %x-%x\n",
+					regd, regm, m->freghi[regd], m->freglo[regd]);
+		break;
+
+	case 0xeeb00ac0:	// F[regd] = abs F[regm]
+		m->freglo[regd] = m->freglo[regm] & ((1<<31)-1);
+
+		if(trace)
+			runtime·printf("*** F[%d] = abs F[%d] %x\n",
+					regd, regm, m->freglo[regd]);
+		break;
+
+	case 0xeeb40bc0:	// D[regd] :: D[regm] (CMPD)
+		runtime·fcmp64c(getd(regd), getd(regm), &cmp, &nan);
+		m->fflag = fstatus(nan, cmp);
+
+		if(trace)
+			runtime·printf("*** cmp D[%d]::D[%d] %x\n",
+				regd, regm, m->fflag);
+		break;
+
+	case 0xeeb40ac0:	// F[regd] :: F[regm] (CMPF)
+		runtime·fcmp64c(f2d(m->freglo[regd]), f2d(m->freglo[regm]), &cmp, &nan);
+		m->fflag = fstatus(nan, cmp);
+
+		if(trace)
+			runtime·printf("*** cmp F[%d]::F[%d] %x\n",
+				regd, regm, m->fflag);
+		break;
+
+	case 0xeeb70ac0:	// D[regd] = F[regm] (MOVFD)
+		putd(regd, f2d(m->freglo[regm]));
+
+		if(trace)
+			runtime·printf("*** f2d D[%d]=F[%d] %x-%x\n",
+				regd, regm, m->freghi[regd], m->freglo[regd]);
+		break;
+
+	case 0xeeb70bc0:	// F[regd] = D[regm] (MOVDF)
+		m->freglo[regd] = d2f(getd(regm));
+
+		if(trace)
+			runtime·printf("*** d2f F[%d]=D[%d] %x-%x\n",
+				regd, regm, m->freghi[regd], m->freglo[regd]);
+		break;
+
+	case 0xeebd0ac0:	// S[regd] = F[regm] (MOVFW)
+		runtime·f64tointc(f2d(m->freglo[regm]), &sval, &ok);
+		if(!ok || (int32)sval != sval)
+			sval = 0;
+		m->freglo[regd] = sval;
+
+		if(trace)
+			runtime·printf("*** fix S[%d]=F[%d] %x\n",
+				regd, regm, m->freglo[regd]);
+		break;
+
+	case 0xeebc0ac0:	// S[regd] = F[regm] (MOVFW.U)
+		runtime·f64tointc(f2d(m->freglo[regm]), &sval, &ok);
+		if(!ok || (uint32)sval != sval)
+			sval = 0;
+		m->freglo[regd] = sval;
+
+		if(trace)
+			runtime·printf("*** fix unsigned S[%d]=F[%d] %x\n",
+				regd, regm, m->freglo[regd]);
+		break;
+
+	case 0xeebd0bc0:	// S[regd] = D[regm] (MOVDW)
+		runtime·f64tointc(getd(regm), &sval, &ok);
+		if(!ok || (int32)sval != sval)
+			sval = 0;
+		m->freglo[regd] = sval;
+
+		if(trace)
+			runtime·printf("*** fix S[%d]=D[%d] %x\n",
+				regd, regm, m->freglo[regd]);
+		break;
+
+	case 0xeebc0bc0:	// S[regd] = D[regm] (MOVDW.U)
+		runtime·f64tointc(getd(regm), &sval, &ok);
+		if(!ok || (uint32)sval != sval)
+			sval = 0;
+		m->freglo[regd] = sval;
+
+		if(trace)
+			runtime·printf("*** fix unsigned S[%d]=D[%d] %x\n",
+				regd, regm, m->freglo[regd]);
+		break;
+
+	case 0xeeb80ac0:	// D[regd] = S[regm] (MOVWF)
+		cmp = m->freglo[regm];
+		if(cmp < 0) {
+			runtime·fintto64c(-cmp, &uval);
+			putf(regd, d2f(uval));
+			m->freglo[regd] ^= 0x80000000;
+		} else {
+			runtime·fintto64c(cmp, &uval);
+			putf(regd, d2f(uval));
+		}
+
+		if(trace)
+			runtime·printf("*** float D[%d]=S[%d] %x-%x\n",
+				regd, regm, m->freghi[regd], m->freglo[regd]);
+		break;
+
+	case 0xeeb80a40:	// D[regd] = S[regm] (MOVWF.U)
+		runtime·fintto64c(m->freglo[regm], &uval);
+		putf(regd, d2f(uval));
+
+		if(trace)
+			runtime·printf("*** float unsigned D[%d]=S[%d] %x-%x\n",
+				regd, regm, m->freghi[regd], m->freglo[regd]);
+		break;
+
+	case 0xeeb80bc0:	// D[regd] = S[regm] (MOVWD)
+		cmp = m->freglo[regm];
+		if(cmp < 0) {
+			runtime·fintto64c(-cmp, &uval);
+			putd(regd, uval);
+			m->freghi[regd] ^= 0x80000000;
+		} else {
+			runtime·fintto64c(cmp, &uval);
+			putd(regd, uval);
+		}
+
+		if(trace)
+			runtime·printf("*** float D[%d]=S[%d] %x-%x\n",
+				regd, regm, m->freghi[regd], m->freglo[regd]);
+		break;
+
+	case 0xeeb80b40:	// D[regd] = S[regm] (MOVWD.U)
+		runtime·fintto64c(m->freglo[regm], &uval);
+		putd(regd, uval);
+
+		if(trace)
+			runtime·printf("*** float unsigned D[%d]=S[%d] %x-%x\n",
+				regd, regm, m->freghi[regd], m->freglo[regd]);
+		break;
+	}
+	return 1;
+
+done:
+	if((i&0xff000000) == 0xee000000 ||
+	   (i&0xff000000) == 0xed000000) {
+		runtime·printf("stepflt %p %x\n", pc, i);
+		fabort();
+	}
+	return 0;
+}
+
+typedef struct Sfregs Sfregs;
+
+// NOTE: These are all recorded as pointers because they are possibly live registers,
+// and we don't know what they contain. Recording them as pointers should be
+// safer than not.
+struct Sfregs
+{
+	uint32 *r0;
+	uint32 *r1;
+	uint32 *r2;
+	uint32 *r3;
+	uint32 *r4;
+	uint32 *r5;
+	uint32 *r6;
+	uint32 *r7;
+	uint32 *r8;
+	uint32 *r9;
+	uint32 *r10;
+	uint32 *r11;
+	uint32 *r12;
+	uint32 *r13;
+	uint32 cspr;
+};
+
+static void sfloat2(void);
+void _sfloatpanic(void);
+
+#pragma textflag NOSPLIT
+uint32*
+runtime·_sfloat2(uint32 *pc, Sfregs regs)
+{
+	void (*fn)(void);
+	
+	g->m->ptrarg[0] = pc;
+	g->m->ptrarg[1] = ®s;
+	fn = sfloat2;
+	runtime·onM(&fn);
+	pc = g->m->ptrarg[0];
+	g->m->ptrarg[0] = nil;
+	return pc;
+}
+
+static void
+sfloat2(void)
+{
+	uint32 *pc;
+	G *curg;
+	Sfregs *regs;
+	int32 skip;
+	bool first;
+	
+	pc = g->m->ptrarg[0];
+	regs = g->m->ptrarg[1];
+	g->m->ptrarg[0] = nil;
+	g->m->ptrarg[1] = nil;
+
+	first = true;
+	while(skip = stepflt(pc, (uint32*)&regs->r0)) {
+		first = false;
+		if(skip == FAULT) {
+			// Encountered bad address in store/load.
+			// Record signal information and return to assembly
+			// trampoline that fakes the call.
+			enum { SIGSEGV = 11 };
+			curg = g->m->curg;
+			curg->sig = SIGSEGV;
+			curg->sigcode0 = 0;
+			curg->sigcode1 = 0;
+			curg->sigpc = (uint32)pc;
+			pc = (uint32*)_sfloatpanic;
+			break;
+		}
+		pc += skip;
+	}
+	if(first) {
+		runtime·printf("sfloat2 %p %x\n", pc, *pc);
+		fabort(); // not ok to fail first instruction
+	}
+		
+	g->m->ptrarg[0] = pc;
+}
diff --git a/src/pkg/runtime/sqrt.go b/src/runtime/sqrt.go
similarity index 100%
rename from src/pkg/runtime/sqrt.go
rename to src/runtime/sqrt.go
diff --git a/src/runtime/stack.c b/src/runtime/stack.c
new file mode 100644
index 0000000..cb95572
--- /dev/null
+++ b/src/runtime/stack.c
@@ -0,0 +1,892 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "runtime.h"
+#include "arch_GOARCH.h"
+#include "malloc.h"
+#include "stack.h"
+#include "funcdata.h"
+#include "typekind.h"
+#include "type.h"
+#include "race.h"
+#include "mgc0.h"
+#include "textflag.h"
+
+enum
+{
+	// StackDebug == 0: no logging
+	//            == 1: logging of per-stack operations
+	//            == 2: logging of per-frame operations
+	//            == 3: logging of per-word updates
+	//            == 4: logging of per-word reads
+	StackDebug = 0,
+	StackFromSystem = 0,	// allocate stacks from system memory instead of the heap
+	StackFaultOnFree = 0,	// old stacks are mapped noaccess to detect use after free
+	StackPoisonCopy = 0,	// fill stack that should not be accessed with garbage, to detect bad dereferences during copy
+
+	StackCache = 1,
+};
+
+// Global pool of spans that have free stacks.
+// Stacks are assigned an order according to size.
+//     order = log_2(size/FixedStack)
+// There is a free list for each order.
+MSpan runtime·stackpool[NumStackOrders];
+Mutex runtime·stackpoolmu;
+// TODO: one lock per order?
+
+static Stack stackfreequeue;
+
+void
+runtime·stackinit(void)
+{
+	int32 i;
+
+	if((StackCacheSize & PageMask) != 0)
+		runtime·throw("cache size must be a multiple of page size");
+
+	for(i = 0; i < NumStackOrders; i++)
+		runtime·MSpanList_Init(&runtime·stackpool[i]);
+}
+
+// Allocates a stack from the free pool.  Must be called with
+// stackpoolmu held.
+static MLink*
+poolalloc(uint8 order)
+{
+	MSpan *list;
+	MSpan *s;
+	MLink *x;
+	uintptr i;
+
+	list = &runtime·stackpool[order];
+	s = list->next;
+	if(s == list) {
+		// no free stacks.  Allocate another span worth.
+		s = runtime·MHeap_AllocStack(&runtime·mheap, StackCacheSize >> PageShift);
+		if(s == nil)
+			runtime·throw("out of memory");
+		if(s->ref != 0)
+			runtime·throw("bad ref");
+		if(s->freelist != nil)
+			runtime·throw("bad freelist");
+		for(i = 0; i < StackCacheSize; i += FixedStack << order) {
+			x = (MLink*)((s->start << PageShift) + i);
+			x->next = s->freelist;
+			s->freelist = x;
+		}
+		runtime·MSpanList_Insert(list, s);
+	}
+	x = s->freelist;
+	if(x == nil)
+		runtime·throw("span has no free stacks");
+	s->freelist = x->next;
+	s->ref++;
+	if(s->freelist == nil) {
+		// all stacks in s are allocated.
+		runtime·MSpanList_Remove(s);
+	}
+	return x;
+}
+
+// Adds stack x to the free pool.  Must be called with stackpoolmu held.
+static void
+poolfree(MLink *x, uint8 order)
+{
+	MSpan *s;
+
+	s = runtime·MHeap_Lookup(&runtime·mheap, x);
+	if(s->state != MSpanStack)
+		runtime·throw("freeing stack not in a stack span");
+	if(s->freelist == nil) {
+		// s will now have a free stack
+		runtime·MSpanList_Insert(&runtime·stackpool[order], s);
+	}
+	x->next = s->freelist;
+	s->freelist = x;
+	s->ref--;
+	if(s->ref == 0) {
+		// span is completely free - return to heap
+		runtime·MSpanList_Remove(s);
+		s->freelist = nil;
+		runtime·MHeap_FreeStack(&runtime·mheap, s);
+	}
+}
+
+// stackcacherefill/stackcacherelease implement a global pool of stack segments.
+// The pool is required to prevent unlimited growth of per-thread caches.
+static void
+stackcacherefill(MCache *c, uint8 order)
+{
+	MLink *x, *list;
+	uintptr size;
+
+	if(StackDebug >= 1)
+		runtime·printf("stackcacherefill order=%d\n", order);
+
+	// Grab some stacks from the global cache.
+	// Grab half of the allowed capacity (to prevent thrashing).
+	list = nil;
+	size = 0;
+	runtime·lock(&runtime·stackpoolmu);
+	while(size < StackCacheSize/2) {
+		x = poolalloc(order);
+		x->next = list;
+		list = x;
+		size += FixedStack << order;
+	}
+	runtime·unlock(&runtime·stackpoolmu);
+
+	c->stackcache[order].list = list;
+	c->stackcache[order].size = size;
+}
+
+static void
+stackcacherelease(MCache *c, uint8 order)
+{
+	MLink *x, *y;
+	uintptr size;
+
+	if(StackDebug >= 1)
+		runtime·printf("stackcacherelease order=%d\n", order);
+	x = c->stackcache[order].list;
+	size = c->stackcache[order].size;
+	runtime·lock(&runtime·stackpoolmu);
+	while(size > StackCacheSize/2) {
+		y = x->next;
+		poolfree(x, order);
+		x = y;
+		size -= FixedStack << order;
+	}
+	runtime·unlock(&runtime·stackpoolmu);
+	c->stackcache[order].list = x;
+	c->stackcache[order].size = size;
+}
+
+void
+runtime·stackcache_clear(MCache *c)
+{
+	uint8 order;
+	MLink *x, *y;
+
+	if(StackDebug >= 1)
+		runtime·printf("stackcache clear\n");
+	runtime·lock(&runtime·stackpoolmu);
+	for(order = 0; order < NumStackOrders; order++) {
+		x = c->stackcache[order].list;
+		while(x != nil) {
+			y = x->next;
+			poolfree(x, order);
+			x = y;
+		}
+		c->stackcache[order].list = nil;
+		c->stackcache[order].size = 0;
+	}
+	runtime·unlock(&runtime·stackpoolmu);
+}
+
+Stack
+runtime·stackalloc(uint32 n)
+{
+	uint8 order;
+	uint32 n2;
+	void *v;
+	MLink *x;
+	MSpan *s;
+	MCache *c;
+
+	// Stackalloc must be called on scheduler stack, so that we
+	// never try to grow the stack during the code that stackalloc runs.
+	// Doing so would cause a deadlock (issue 1547).
+	if(g != g->m->g0)
+		runtime·throw("stackalloc not on scheduler stack");
+	if((n & (n-1)) != 0)
+		runtime·throw("stack size not a power of 2");
+	if(StackDebug >= 1)
+		runtime·printf("stackalloc %d\n", n);
+
+	if(runtime·debug.efence || StackFromSystem) {
+		v = runtime·sysAlloc(ROUND(n, PageSize), &mstats.stacks_sys);
+		if(v == nil)
+			runtime·throw("out of memory (stackalloc)");
+		return (Stack){(uintptr)v, (uintptr)v+n};
+	}
+
+	// Small stacks are allocated with a fixed-size free-list allocator.
+	// If we need a stack of a bigger size, we fall back on allocating
+	// a dedicated span.
+	if(StackCache && n < FixedStack << NumStackOrders && n < StackCacheSize) {
+		order = 0;
+		n2 = n;
+		while(n2 > FixedStack) {
+			order++;
+			n2 >>= 1;
+		}
+		c = g->m->mcache;
+		if(c == nil || g->m->gcing || g->m->helpgc) {
+			// c == nil can happen in the guts of exitsyscall or
+			// procresize. Just get a stack from the global pool.
+			// Also don't touch stackcache during gc
+			// as it's flushed concurrently.
+			runtime·lock(&runtime·stackpoolmu);
+			x = poolalloc(order);
+			runtime·unlock(&runtime·stackpoolmu);
+		} else {
+			x = c->stackcache[order].list;
+			if(x == nil) {
+				stackcacherefill(c, order);
+				x = c->stackcache[order].list;
+			}
+			c->stackcache[order].list = x->next;
+			c->stackcache[order].size -= n;
+		}
+		v = (byte*)x;
+	} else {
+		s = runtime·MHeap_AllocStack(&runtime·mheap, ROUND(n, PageSize) >> PageShift);
+		if(s == nil)
+			runtime·throw("out of memory");
+		v = (byte*)(s->start<<PageShift);
+	}
+	
+	if(raceenabled)
+		runtime·racemalloc(v, n);
+	if(StackDebug >= 1)
+		runtime·printf("  allocated %p\n", v);
+	return (Stack){(uintptr)v, (uintptr)v+n};
+}
+
+void
+runtime·stackfree(Stack stk)
+{
+	uint8 order;
+	uintptr n, n2;
+	MSpan *s;
+	MLink *x;
+	MCache *c;
+	void *v;
+	
+	n = stk.hi - stk.lo;
+	v = (void*)stk.lo;
+	if(n & (n-1))
+		runtime·throw("stack not a power of 2");
+	if(StackDebug >= 1) {
+		runtime·printf("stackfree %p %d\n", v, (int32)n);
+		runtime·memclr(v, n); // for testing, clobber stack data
+	}
+	if(runtime·debug.efence || StackFromSystem) {
+		if(runtime·debug.efence || StackFaultOnFree)
+			runtime·SysFault(v, n);
+		else
+			runtime·SysFree(v, n, &mstats.stacks_sys);
+		return;
+	}
+	if(StackCache && n < FixedStack << NumStackOrders && n < StackCacheSize) {
+		order = 0;
+		n2 = n;
+		while(n2 > FixedStack) {
+			order++;
+			n2 >>= 1;
+		}
+		x = (MLink*)v;
+		c = g->m->mcache;
+		if(c == nil || g->m->gcing || g->m->helpgc) {
+			runtime·lock(&runtime·stackpoolmu);
+			poolfree(x, order);
+			runtime·unlock(&runtime·stackpoolmu);
+		} else {
+			if(c->stackcache[order].size >= StackCacheSize)
+				stackcacherelease(c, order);
+			x->next = c->stackcache[order].list;
+			c->stackcache[order].list = x;
+			c->stackcache[order].size += n;
+		}
+	} else {
+		s = runtime·MHeap_Lookup(&runtime·mheap, v);
+		if(s->state != MSpanStack) {
+			runtime·printf("%p %p\n", s->start<<PageShift, v);
+			runtime·throw("bad span state");
+		}
+		runtime·MHeap_FreeStack(&runtime·mheap, s);
+	}
+}
+
+uintptr runtime·maxstacksize = 1<<20; // enough until runtime.main sets it for real
+
+static uint8*
+mapnames[] = {
+	(uint8*)"---",
+	(uint8*)"scalar",
+	(uint8*)"ptr",
+	(uint8*)"multi",
+};
+
+// Stack frame layout
+//
+// (x86)
+// +------------------+
+// | args from caller |
+// +------------------+ <- frame->argp
+// |  return address  |
+// +------------------+ <- frame->varp
+// |     locals       |
+// +------------------+
+// |  args to callee  |
+// +------------------+ <- frame->sp
+//
+// (arm)
+// +------------------+
+// | args from caller |
+// +------------------+ <- frame->argp
+// | caller's retaddr |
+// +------------------+ <- frame->varp
+// |     locals       |
+// +------------------+
+// |  args to callee  |
+// +------------------+
+// |  return address  |
+// +------------------+ <- frame->sp
+
+void runtime·main(void);
+void runtime·switchtoM(void(*)(void));
+
+typedef struct AdjustInfo AdjustInfo;
+struct AdjustInfo {
+	Stack old;
+	uintptr delta;  // ptr distance from old to new stack (newbase - oldbase)
+};
+
+// Adjustpointer checks whether *vpp is in the old stack described by adjinfo.
+// If so, it rewrites *vpp to point into the new stack.
+static void
+adjustpointer(AdjustInfo *adjinfo, void *vpp)
+{
+	byte **pp, *p;
+	
+	pp = vpp;
+	p = *pp;
+	if(StackDebug >= 4)
+		runtime·printf("        %p:%p\n", pp, p);
+	if(adjinfo->old.lo <= (uintptr)p && (uintptr)p < adjinfo->old.hi) {
+		*pp = p + adjinfo->delta;
+		if(StackDebug >= 3)
+			runtime·printf("        adjust ptr %p: %p -> %p\n", pp, p, *pp);
+	}
+}
+
+// bv describes the memory starting at address scanp.
+// Adjust any pointers contained therein.
+static void
+adjustpointers(byte **scanp, BitVector *bv, AdjustInfo *adjinfo, Func *f)
+{
+	uintptr delta;
+	int32 num, i;
+	byte *p, *minp, *maxp;
+	Type *t;
+	Itab *tab;
+	
+	minp = (byte*)adjinfo->old.lo;
+	maxp = (byte*)adjinfo->old.hi;
+	delta = adjinfo->delta;
+	num = bv->n / BitsPerPointer;
+	for(i = 0; i < num; i++) {
+		if(StackDebug >= 4)
+			runtime·printf("        %p:%s:%p\n", &scanp[i], mapnames[bv->bytedata[i / (8 / BitsPerPointer)] >> (i * BitsPerPointer & 7) & 3], scanp[i]);
+		switch(bv->bytedata[i / (8 / BitsPerPointer)] >> (i * BitsPerPointer & 7) & 3) {
+		case BitsDead:
+			if(runtime·debug.gcdead)
+				scanp[i] = (byte*)PoisonStack;
+			break;
+		case BitsScalar:
+			break;
+		case BitsPointer:
+			p = scanp[i];
+			if(f != nil && (byte*)0 < p && (p < (byte*)PageSize && runtime·invalidptr || (uintptr)p == PoisonGC || (uintptr)p == PoisonStack)) {
+				// Looks like a junk value in a pointer slot.
+				// Live analysis wrong?
+				g->m->traceback = 2;
+				runtime·printf("runtime: bad pointer in frame %s at %p: %p\n", runtime·funcname(f), &scanp[i], p);
+				runtime·throw("invalid stack pointer");
+			}
+			if(minp <= p && p < maxp) {
+				if(StackDebug >= 3)
+					runtime·printf("adjust ptr %p %s\n", p, runtime·funcname(f));
+				scanp[i] = p + delta;
+			}
+			break;
+		case BitsMultiWord:
+			switch(bv->bytedata[(i+1) / (8 / BitsPerPointer)] >> ((i+1) * BitsPerPointer & 7) & 3) {
+			default:
+				runtime·throw("unexpected garbage collection bits");
+			case BitsEface:
+				t = (Type*)scanp[i];
+				if(t != nil && ((t->kind & KindDirectIface) == 0 || (t->kind & KindNoPointers) == 0)) {
+					p = scanp[i+1];
+					if(minp <= p && p < maxp) {
+						if(StackDebug >= 3)
+							runtime·printf("adjust eface %p\n", p);
+						if(t->size > PtrSize) // currently we always allocate such objects on the heap
+							runtime·throw("large interface value found on stack");
+						scanp[i+1] = p + delta;
+					}
+				}
+				i++;
+				break;
+			case BitsIface:
+				tab = (Itab*)scanp[i];
+				if(tab != nil) {
+					t = tab->type;
+					//runtime·printf("          type=%p\n", t);
+					if((t->kind & KindDirectIface) == 0 || (t->kind & KindNoPointers) == 0) {
+						p = scanp[i+1];
+						if(minp <= p && p < maxp) {
+							if(StackDebug >= 3)
+								runtime·printf("adjust iface %p\n", p);
+							if(t->size > PtrSize) // currently we always allocate such objects on the heap
+								runtime·throw("large interface value found on stack");
+							scanp[i+1] = p + delta;
+						}
+					}
+				}
+				i++;
+				break;
+			}
+			break;
+		}
+	}
+}
+
+// Note: the argument/return area is adjusted by the callee.
+static bool
+adjustframe(Stkframe *frame, void *arg)
+{
+	AdjustInfo *adjinfo;
+	Func *f;
+	StackMap *stackmap;
+	int32 pcdata;
+	BitVector bv;
+	uintptr targetpc, size, minsize;
+
+	adjinfo = arg;
+	targetpc = frame->continpc;
+	if(targetpc == 0) {
+		// Frame is dead.
+		return true;
+	}
+	f = frame->fn;
+	if(StackDebug >= 2)
+		runtime·printf("    adjusting %s frame=[%p,%p] pc=%p continpc=%p\n", runtime·funcname(f), frame->sp, frame->fp, frame->pc, frame->continpc);
+	if(f->entry == (uintptr)runtime·switchtoM) {
+		// A special routine at the bottom of stack of a goroutine that does an onM call.
+		// We will allow it to be copied even though we don't
+		// have full GC info for it (because it is written in asm).
+		return true;
+	}
+	if(targetpc != f->entry)
+		targetpc--;
+	pcdata = runtime·pcdatavalue(f, PCDATA_StackMapIndex, targetpc);
+	if(pcdata == -1)
+		pcdata = 0; // in prologue
+
+	// Adjust local variables if stack frame has been allocated.
+	size = frame->varp - frame->sp;
+	if(thechar != '6' && thechar != '8')
+		minsize = sizeof(uintptr);
+	else
+		minsize = 0;
+	if(size > minsize) {
+		stackmap = runtime·funcdata(f, FUNCDATA_LocalsPointerMaps);
+		if(stackmap == nil || stackmap->n <= 0) {
+			runtime·printf("runtime: frame %s untyped locals %p+%p\n", runtime·funcname(f), (byte*)(frame->varp-size), size);
+			runtime·throw("missing stackmap");
+		}
+		// Locals bitmap information, scan just the pointers in locals.
+		if(pcdata < 0 || pcdata >= stackmap->n) {
+			// don't know where we are
+			runtime·printf("runtime: pcdata is %d and %d locals stack map entries for %s (targetpc=%p)\n",
+				pcdata, stackmap->n, runtime·funcname(f), targetpc);
+			runtime·throw("bad symbol table");
+		}
+		bv = runtime·stackmapdata(stackmap, pcdata);
+		size = (bv.n * PtrSize) / BitsPerPointer;
+		if(StackDebug >= 3)
+			runtime·printf("      locals\n");
+		adjustpointers((byte**)(frame->varp - size), &bv, adjinfo, f);
+	}
+	
+	// Adjust arguments.
+	if(frame->arglen > 0) {
+		if(frame->argmap != nil) {
+			bv = *frame->argmap;
+		} else {
+			stackmap = runtime·funcdata(f, FUNCDATA_ArgsPointerMaps);
+			if(stackmap == nil || stackmap->n <= 0) {
+				runtime·printf("runtime: frame %s untyped args %p+%p\n", runtime·funcname(f), frame->argp, (uintptr)frame->arglen);
+				runtime·throw("missing stackmap");
+			}
+			if(pcdata < 0 || pcdata >= stackmap->n) {
+				// don't know where we are
+				runtime·printf("runtime: pcdata is %d and %d args stack map entries for %s (targetpc=%p)\n",
+					pcdata, stackmap->n, runtime·funcname(f), targetpc);
+				runtime·throw("bad symbol table");
+			}
+			bv = runtime·stackmapdata(stackmap, pcdata);
+		}
+		if(StackDebug >= 3)
+			runtime·printf("      args\n");
+		adjustpointers((byte**)frame->argp, &bv, adjinfo, nil);
+	}
+	
+	return true;
+}
+
+static void
+adjustctxt(G *gp, AdjustInfo *adjinfo)
+{
+	adjustpointer(adjinfo, &gp->sched.ctxt);
+}
+
+static void
+adjustdefers(G *gp, AdjustInfo *adjinfo)
+{
+	Defer *d;
+	bool (*cb)(Stkframe*, void*);
+
+	// Adjust defer argument blocks the same way we adjust active stack frames.
+	cb = adjustframe;
+	runtime·tracebackdefers(gp, &cb, adjinfo);
+
+	// Adjust pointers in the Defer structs.
+	// Defer structs themselves are never on the stack.
+	for(d = gp->defer; d != nil; d = d->link) {
+		adjustpointer(adjinfo, &d->fn);
+		adjustpointer(adjinfo, &d->argp);
+		adjustpointer(adjinfo, &d->panic);
+	}
+}
+
+static void
+adjustpanics(G *gp, AdjustInfo *adjinfo)
+{
+	// Panics are on stack and already adjusted.
+	// Update pointer to head of list in G.
+	adjustpointer(adjinfo, &gp->panic);
+}
+
+static void
+adjustsudogs(G *gp, AdjustInfo *adjinfo)
+{
+	SudoG *s;
+
+	// the data elements pointed to by a SudoG structure
+	// might be in the stack.
+	for(s = gp->waiting; s != nil; s = s->waitlink) {
+		adjustpointer(adjinfo, &s->elem);
+		adjustpointer(adjinfo, &s->selectdone);
+	}
+}
+
+// Copies gp's stack to a new stack of a different size.
+static void
+copystack(G *gp, uintptr newsize)
+{
+	Stack old, new;
+	uintptr used;
+	AdjustInfo adjinfo;
+	uint32 oldstatus;
+	bool (*cb)(Stkframe*, void*);
+	byte *p, *ep;
+
+	if(gp->syscallsp != 0)
+		runtime·throw("stack growth not allowed in system call");
+	old = gp->stack;
+	if(old.lo == 0)
+		runtime·throw("nil stackbase");
+	used = old.hi - gp->sched.sp;
+
+	// allocate new stack
+	new = runtime·stackalloc(newsize);
+	if(StackPoisonCopy) {
+		p = (byte*)new.lo;
+		ep = (byte*)new.hi;
+		while(p < ep)
+			*p++ = 0xfd;
+	}
+
+	if(StackDebug >= 1)
+		runtime·printf("copystack gp=%p [%p %p %p]/%d -> [%p %p %p]/%d\n", gp, old.lo, old.hi-used, old.hi, (int32)(old.hi-old.lo), new.lo, new.hi-used, new.hi, (int32)newsize);
+	
+	// adjust pointers in the to-be-copied frames
+	adjinfo.old = old;
+	adjinfo.delta = new.hi - old.hi;
+	cb = adjustframe;
+	runtime·gentraceback(~(uintptr)0, ~(uintptr)0, 0, gp, 0, nil, 0x7fffffff, &cb, &adjinfo, 0);
+	
+	// adjust other miscellaneous things that have pointers into stacks.
+	adjustctxt(gp, &adjinfo);
+	adjustdefers(gp, &adjinfo);
+	adjustpanics(gp, &adjinfo);
+	adjustsudogs(gp, &adjinfo);
+	
+	// copy the stack to the new location
+	if(StackPoisonCopy) {
+		p = (byte*)new.lo;
+		ep = (byte*)new.hi;
+		while(p < ep)
+			*p++ = 0xfb;
+	}
+	runtime·memmove((byte*)new.hi - used, (byte*)old.hi - used, used);
+
+	oldstatus = runtime·casgcopystack(gp); // cas from Gwaiting or Grunnable to Gcopystack, return old status
+
+	// Swap out old stack for new one
+	gp->stack = new;
+	gp->stackguard0 = new.lo + StackGuard; // NOTE: might clobber a preempt request
+	gp->sched.sp = new.hi - used;
+
+	runtime·casgstatus(gp, Gcopystack, oldstatus); // oldstatus is Gwaiting or Grunnable
+
+	// free old stack
+	if(StackPoisonCopy) {
+		p = (byte*)old.lo;
+		ep = (byte*)old.hi;
+		while(p < ep)
+			*p++ = 0xfc;
+	}
+	if(newsize > old.hi-old.lo) {
+		// growing, free stack immediately
+		runtime·stackfree(old);
+	} else {
+		// shrinking, queue up free operation.  We can't actually free the stack
+		// just yet because we might run into the following situation:
+		// 1) GC starts, scans a SudoG but does not yet mark the SudoG.elem pointer
+		// 2) The stack that pointer points to is shrunk
+		// 3) The old stack is freed
+		// 4) The containing span is marked free
+		// 5) GC attempts to mark the SudoG.elem pointer.  The marking fails because
+		//    the pointer looks like a pointer into a free span.
+		// By not freeing, we prevent step #4 until GC is done.
+		runtime·lock(&runtime·stackpoolmu);
+		*(Stack*)old.lo = stackfreequeue;
+		stackfreequeue = old;
+		runtime·unlock(&runtime·stackpoolmu);
+	}
+}
+
+// round x up to a power of 2.
+int32
+runtime·round2(int32 x)
+{
+	int32 s;
+
+	s = 0;
+	while((1 << s) < x)
+		s++;
+	return 1 << s;
+}
+
+// Called from runtime·morestack when more stack is needed.
+// Allocate larger stack and relocate to new stack.
+// Stack growth is multiplicative, for constant amortized cost.
+//
+// g->atomicstatus will be Grunning or Gscanrunning upon entry. 
+// If the GC is trying to stop this g then it will set preemptscan to true.
+void
+runtime·newstack(void)
+{
+	int32 oldsize, newsize;
+	uintptr sp;
+	G *gp;
+	Gobuf morebuf;
+
+	if(g->m->morebuf.g->stackguard0 == (uintptr)StackFork)
+		runtime·throw("stack growth after fork");
+	if(g->m->morebuf.g != g->m->curg) {
+		runtime·printf("runtime: newstack called from g=%p\n"
+			"\tm=%p m->curg=%p m->g0=%p m->gsignal=%p\n",
+			g->m->morebuf.g, g->m, g->m->curg, g->m->g0, g->m->gsignal);
+		morebuf = g->m->morebuf;
+		runtime·traceback(morebuf.pc, morebuf.sp, morebuf.lr, morebuf.g);
+		runtime·throw("runtime: wrong goroutine in newstack");
+	}
+	if(g->m->curg->throwsplit)
+		runtime·throw("runtime: stack split at bad time");
+
+	// The goroutine must be executing in order to call newstack,
+	// so it must be Grunning or Gscanrunning.
+
+	gp = g->m->curg;
+	morebuf = g->m->morebuf;
+	g->m->morebuf.pc = (uintptr)nil;
+	g->m->morebuf.lr = (uintptr)nil;
+	g->m->morebuf.sp = (uintptr)nil;
+	g->m->morebuf.g = (G*)nil;
+
+	runtime·casgstatus(gp, Grunning, Gwaiting);
+	gp->waitreason = runtime·gostringnocopy((byte*)"stack growth");
+
+	runtime·rewindmorestack(&gp->sched);
+
+	if(gp->stack.lo == 0)
+		runtime·throw("missing stack in newstack");
+	sp = gp->sched.sp;
+	if(thechar == '6' || thechar == '8') {
+		// The call to morestack cost a word.
+		sp -= sizeof(uintreg);
+	}
+	if(StackDebug >= 1 || sp < gp->stack.lo) {
+		runtime·printf("runtime: newstack sp=%p stack=[%p, %p]\n"
+			"\tmorebuf={pc:%p sp:%p lr:%p}\n"
+			"\tsched={pc:%p sp:%p lr:%p ctxt:%p}\n",
+			sp, gp->stack.lo, gp->stack.hi,
+			g->m->morebuf.pc, g->m->morebuf.sp, g->m->morebuf.lr,
+			gp->sched.pc, gp->sched.sp, gp->sched.lr, gp->sched.ctxt);
+	}
+	if(sp < gp->stack.lo) {
+		runtime·printf("runtime: gp=%p, gp->status=%d\n ", (void*)gp, runtime·readgstatus(gp));
+		runtime·printf("runtime: split stack overflow: %p < %p\n", sp, gp->stack.lo);
+		runtime·throw("runtime: split stack overflow");
+	}
+
+	if(gp->stackguard0 == (uintptr)StackPreempt) {
+		if(gp == g->m->g0)
+			runtime·throw("runtime: preempt g0");
+		if(g->m->p == nil && g->m->locks == 0)
+			runtime·throw("runtime: g is running but p is not");
+		if(gp->preemptscan) {
+			runtime·gcphasework(gp);
+			runtime·casgstatus(gp, Gwaiting, Grunning);
+			gp->stackguard0 = gp->stack.lo + StackGuard;
+			gp->preempt = false; 
+			gp->preemptscan = false;        // Tells the GC premption was successful.
+			runtime·gogo(&gp->sched);	// never return 
+		}
+
+		// Be conservative about where we preempt.
+		// We are interested in preempting user Go code, not runtime code.
+		if(g->m->locks || g->m->mallocing || g->m->gcing || g->m->p->status != Prunning) {
+			// Let the goroutine keep running for now.
+			// gp->preempt is set, so it will be preempted next time.
+			gp->stackguard0 = gp->stack.lo + StackGuard;
+			runtime·casgstatus(gp, Gwaiting, Grunning);
+			runtime·gogo(&gp->sched);	// never return
+		}
+		// Act like goroutine called runtime.Gosched.
+		runtime·casgstatus(gp, Gwaiting, Grunning);
+		runtime·gosched_m(gp);	// never return
+	}
+
+	// Allocate a bigger segment and move the stack.
+	oldsize = gp->stack.hi - gp->stack.lo;
+	newsize = oldsize * 2;
+	if(newsize > runtime·maxstacksize) {
+		runtime·printf("runtime: goroutine stack exceeds %D-byte limit\n", (uint64)runtime·maxstacksize);
+		runtime·throw("stack overflow");
+	}
+
+	// Note that the concurrent GC might be scanning the stack as we try to replace it.
+	// copystack takes care of the appropriate coordination with the stack scanner.
+	copystack(gp, newsize);
+	if(StackDebug >= 1)
+		runtime·printf("stack grow done\n");
+	runtime·casgstatus(gp, Gwaiting, Grunning);
+	runtime·gogo(&gp->sched);
+}
+
+#pragma textflag NOSPLIT
+void
+runtime·nilfunc(void)
+{
+	*(byte*)0 = 0;
+}
+
+// adjust Gobuf as if it executed a call to fn
+// and then did an immediate gosave.
+void
+runtime·gostartcallfn(Gobuf *gobuf, FuncVal *fv)
+{
+	void *fn;
+
+	if(fv != nil)
+		fn = fv->fn;
+	else
+		fn = runtime·nilfunc;
+	runtime·gostartcall(gobuf, fn, fv);
+}
+
+// Maybe shrink the stack being used by gp.
+// Called at garbage collection time.
+void
+runtime·shrinkstack(G *gp)
+{
+	uintptr used, oldsize, newsize;
+
+	if(runtime·readgstatus(gp) == Gdead) {
+		if(gp->stack.lo != 0) {
+			// Free whole stack - it will get reallocated
+			// if G is used again.
+			runtime·stackfree(gp->stack);
+			gp->stack.lo = 0;
+			gp->stack.hi = 0;
+		}
+		return;
+	}
+	if(gp->stack.lo == 0)
+		runtime·throw("missing stack in shrinkstack");
+
+	oldsize = gp->stack.hi - gp->stack.lo;
+	newsize = oldsize / 2;
+	if(newsize < FixedStack)
+		return; // don't shrink below the minimum-sized stack
+	used = gp->stack.hi - gp->sched.sp;
+	if(used >= oldsize / 4)
+		return; // still using at least 1/4 of the segment.
+
+	// We can't copy the stack if we're in a syscall.
+	// The syscall might have pointers into the stack.
+	if(gp->syscallsp != 0)
+		return;
+
+#ifdef GOOS_windows
+	if(gp->m != nil && gp->m->libcallsp != 0)
+		return;
+#endif
+	if(StackDebug > 0)
+		runtime·printf("shrinking stack %D->%D\n", (uint64)oldsize, (uint64)newsize);
+	copystack(gp, newsize);
+}
+
+// Do any delayed stack freeing that was queued up during GC.
+void
+runtime·shrinkfinish(void)
+{
+	Stack s, t;
+
+	runtime·lock(&runtime·stackpoolmu);
+	s = stackfreequeue;
+	stackfreequeue = (Stack){0,0};
+	runtime·unlock(&runtime·stackpoolmu);
+	while(s.lo != 0) {
+		t = *(Stack*)s.lo;
+		runtime·stackfree(s);
+		s = t;
+	}
+}
+
+static void badc(void);
+
+#pragma textflag NOSPLIT
+void
+runtime·morestackc(void)
+{
+	void (*fn)(void);
+	
+	fn = badc;
+	runtime·onM(&fn);
+}
+
+static void
+badc(void)
+{
+	runtime·throw("attempt to execute C code on Go stack");
+}
diff --git a/src/runtime/stack.go b/src/runtime/stack.go
new file mode 100644
index 0000000..f1b7d32
--- /dev/null
+++ b/src/runtime/stack.go
@@ -0,0 +1,13 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package runtime
+
+const (
+	// Goroutine preemption request.
+	// Stored into g->stackguard0 to cause split stack check failure.
+	// Must be greater than any real sp.
+	// 0xfffffade in hex.
+	stackPreempt = ^uintptr(1313)
+)
diff --git a/src/runtime/stack.h b/src/runtime/stack.h
new file mode 100644
index 0000000..f97dc4e
--- /dev/null
+++ b/src/runtime/stack.h
@@ -0,0 +1,118 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+/*
+Stack layout parameters.
+Included both by runtime (compiled via 6c) and linkers (compiled via gcc).
+
+The per-goroutine g->stackguard is set to point StackGuard bytes
+above the bottom of the stack.  Each function compares its stack
+pointer against g->stackguard to check for overflow.  To cut one
+instruction from the check sequence for functions with tiny frames,
+the stack is allowed to protrude StackSmall bytes below the stack
+guard.  Functions with large frames don't bother with the check and
+always call morestack.  The sequences are (for amd64, others are
+similar):
+ 
+	guard = g->stackguard
+	frame = function's stack frame size
+	argsize = size of function arguments (call + return)
+
+	stack frame size <= StackSmall:
+		CMPQ guard, SP
+		JHI 3(PC)
+		MOVQ m->morearg, $(argsize << 32)
+		CALL morestack(SB)
+
+	stack frame size > StackSmall but < StackBig
+		LEAQ (frame-StackSmall)(SP), R0
+		CMPQ guard, R0
+		JHI 3(PC)
+		MOVQ m->morearg, $(argsize << 32)
+		CALL morestack(SB)
+
+	stack frame size >= StackBig:
+		MOVQ m->morearg, $((argsize << 32) | frame)
+		CALL morestack(SB)
+
+The bottom StackGuard - StackSmall bytes are important: there has
+to be enough room to execute functions that refuse to check for
+stack overflow, either because they need to be adjacent to the
+actual caller's frame (deferproc) or because they handle the imminent
+stack overflow (morestack).
+
+For example, deferproc might call malloc, which does one of the
+above checks (without allocating a full frame), which might trigger
+a call to morestack.  This sequence needs to fit in the bottom
+section of the stack.  On amd64, morestack's frame is 40 bytes, and
+deferproc's frame is 56 bytes.  That fits well within the
+StackGuard - StackSmall bytes at the bottom.  
+The linkers explore all possible call traces involving non-splitting
+functions to make sure that this limit cannot be violated.
+ */
+
+enum {
+	// StackSystem is a number of additional bytes to add
+	// to each stack below the usual guard area for OS-specific
+	// purposes like signal handling. Used on Windows and on
+	// Plan 9 because they do not use a separate stack.
+#ifdef GOOS_windows
+	StackSystem = 512 * sizeof(uintptr),
+#else
+#ifdef GOOS_plan9
+	// The size of the note handler frame varies among architectures,
+	// but 512 bytes should be enough for every implementation.
+	StackSystem = 512,
+#else
+	StackSystem = 0,
+#endif	// Plan 9
+#endif	// Windows
+
+	// The minimum size of stack used by Go code
+	StackMin = 2048,
+
+	// The minimum stack size to allocate.
+	// The hackery here rounds FixedStack0 up to a power of 2.
+	FixedStack0 = StackMin + StackSystem,
+	FixedStack1 = FixedStack0 - 1,
+	FixedStack2 = FixedStack1 | (FixedStack1 >> 1),
+	FixedStack3 = FixedStack2 | (FixedStack2 >> 2),
+	FixedStack4 = FixedStack3 | (FixedStack3 >> 4),
+	FixedStack5 = FixedStack4 | (FixedStack4 >> 8),
+	FixedStack6 = FixedStack5 | (FixedStack5 >> 16),
+	FixedStack = FixedStack6 + 1,
+
+	// Functions that need frames bigger than this use an extra
+	// instruction to do the stack split check, to avoid overflow
+	// in case SP - framesize wraps below zero.
+	// This value can be no bigger than the size of the unmapped
+	// space at zero.
+	StackBig = 4096,
+
+	// The stack guard is a pointer this many bytes above the
+	// bottom of the stack.
+	StackGuard = 512 + StackSystem,
+
+	// After a stack split check the SP is allowed to be this
+	// many bytes below the stack guard.  This saves an instruction
+	// in the checking sequence for tiny frames.
+	StackSmall = 128,
+
+	// The maximum number of bytes that a chain of NOSPLIT
+	// functions can use.
+	StackLimit = StackGuard - StackSystem - StackSmall,
+};
+
+// Goroutine preemption request.
+// Stored into g->stackguard0 to cause split stack check failure.
+// Must be greater than any real sp.
+// 0xfffffade in hex.
+#define StackPreempt ((uint64)-1314)
+/*c2go
+enum
+{
+	StackPreempt = -1314,
+};
+*/
+#define StackFork ((uint64)-1234)
diff --git a/src/runtime/stack_test.go b/src/runtime/stack_test.go
new file mode 100644
index 0000000..652c72e
--- /dev/null
+++ b/src/runtime/stack_test.go
@@ -0,0 +1,397 @@
+// Copyright 2012 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package runtime_test
+
+import (
+	. "runtime"
+	"strings"
+	"sync"
+	"testing"
+	"time"
+)
+
+// TestStackMem measures per-thread stack segment cache behavior.
+// The test consumed up to 500MB in the past.
+func TestStackMem(t *testing.T) {
+	const (
+		BatchSize      = 32
+		BatchCount     = 256
+		ArraySize      = 1024
+		RecursionDepth = 128
+	)
+	if testing.Short() {
+		return
+	}
+	defer GOMAXPROCS(GOMAXPROCS(BatchSize))
+	s0 := new(MemStats)
+	ReadMemStats(s0)
+	for b := 0; b < BatchCount; b++ {
+		c := make(chan bool, BatchSize)
+		for i := 0; i < BatchSize; i++ {
+			go func() {
+				var f func(k int, a [ArraySize]byte)
+				f = func(k int, a [ArraySize]byte) {
+					if k == 0 {
+						time.Sleep(time.Millisecond)
+						return
+					}
+					f(k-1, a)
+				}
+				f(RecursionDepth, [ArraySize]byte{})
+				c <- true
+			}()
+		}
+		for i := 0; i < BatchSize; i++ {
+			<-c
+		}
+
+		// The goroutines have signaled via c that they are ready to exit.
+		// Give them a chance to exit by sleeping. If we don't wait, we
+		// might not reuse them on the next batch.
+		time.Sleep(10 * time.Millisecond)
+	}
+	s1 := new(MemStats)
+	ReadMemStats(s1)
+	consumed := int64(s1.StackSys - s0.StackSys)
+	t.Logf("Consumed %vMB for stack mem", consumed>>20)
+	estimate := int64(8 * BatchSize * ArraySize * RecursionDepth) // 8 is to reduce flakiness.
+	if consumed > estimate {
+		t.Fatalf("Stack mem: want %v, got %v", estimate, consumed)
+	}
+	// Due to broken stack memory accounting (http://golang.org/issue/7468),
+	// StackInuse can decrease during function execution, so we cast the values to int64.
+	inuse := int64(s1.StackInuse) - int64(s0.StackInuse)
+	t.Logf("Inuse %vMB for stack mem", inuse>>20)
+	if inuse > 4<<20 {
+		t.Fatalf("Stack inuse: want %v, got %v", 4<<20, inuse)
+	}
+}
+
+// Test stack growing in different contexts.
+func TestStackGrowth(t *testing.T) {
+	t.Parallel()
+	var wg sync.WaitGroup
+
+	// in a normal goroutine
+	wg.Add(1)
+	go func() {
+		defer wg.Done()
+		growStack()
+	}()
+	wg.Wait()
+
+	// in locked goroutine
+	wg.Add(1)
+	go func() {
+		defer wg.Done()
+		LockOSThread()
+		growStack()
+		UnlockOSThread()
+	}()
+	wg.Wait()
+
+	// in finalizer
+	wg.Add(1)
+	go func() {
+		defer wg.Done()
+		done := make(chan bool)
+		go func() {
+			s := new(string)
+			SetFinalizer(s, func(ss *string) {
+				growStack()
+				done <- true
+			})
+			s = nil
+			done <- true
+		}()
+		<-done
+		GC()
+		select {
+		case <-done:
+		case <-time.After(20 * time.Second):
+			t.Fatal("finalizer did not run")
+		}
+	}()
+	wg.Wait()
+}
+
+// ... and in init
+//func init() {
+//	growStack()
+//}
+
+func growStack() {
+	n := 1 << 10
+	if testing.Short() {
+		n = 1 << 8
+	}
+	for i := 0; i < n; i++ {
+		x := 0
+		growStackIter(&x, i)
+		if x != i+1 {
+			panic("stack is corrupted")
+		}
+	}
+	GC()
+}
+
+// This function is not an anonymous func, so that the compiler can do escape
+// analysis and place x on stack (and subsequently stack growth update the pointer).
+func growStackIter(p *int, n int) {
+	if n == 0 {
+		*p = n + 1
+		GC()
+		return
+	}
+	*p = n + 1
+	x := 0
+	growStackIter(&x, n-1)
+	if x != n {
+		panic("stack is corrupted")
+	}
+}
+
+func TestStackGrowthCallback(t *testing.T) {
+	t.Parallel()
+	var wg sync.WaitGroup
+
+	// test stack growth at chan op
+	wg.Add(1)
+	go func() {
+		defer wg.Done()
+		c := make(chan int, 1)
+		growStackWithCallback(func() {
+			c <- 1
+			<-c
+		})
+	}()
+
+	// test stack growth at map op
+	wg.Add(1)
+	go func() {
+		defer wg.Done()
+		m := make(map[int]int)
+		growStackWithCallback(func() {
+			_, _ = m[1]
+			m[1] = 1
+		})
+	}()
+
+	// test stack growth at goroutine creation
+	wg.Add(1)
+	go func() {
+		defer wg.Done()
+		growStackWithCallback(func() {
+			done := make(chan bool)
+			go func() {
+				done <- true
+			}()
+			<-done
+		})
+	}()
+
+	wg.Wait()
+}
+
+func growStackWithCallback(cb func()) {
+	var f func(n int)
+	f = func(n int) {
+		if n == 0 {
+			cb()
+			return
+		}
+		f(n - 1)
+	}
+	for i := 0; i < 1<<10; i++ {
+		f(i)
+	}
+}
+
+// TestDeferPtrs tests the adjustment of Defer's argument pointers (p aka &y)
+// during a stack copy.
+func set(p *int, x int) {
+	*p = x
+}
+func TestDeferPtrs(t *testing.T) {
+	var y int
+
+	defer func() {
+		if y != 42 {
+			t.Errorf("defer's stack references were not adjusted appropriately")
+		}
+	}()
+	defer set(&y, 42)
+	growStack()
+}
+
+type bigBuf [4 * 1024]byte
+
+// TestDeferPtrsGoexit is like TestDeferPtrs but exercises the possibility that the
+// stack grows as part of starting the deferred function. It calls Goexit at various
+// stack depths, forcing the deferred function (with >4kB of args) to be run at
+// the bottom of the stack. The goal is to find a stack depth less than 4kB from
+// the end of the stack. Each trial runs in a different goroutine so that an earlier
+// stack growth does not invalidate a later attempt.
+func TestDeferPtrsGoexit(t *testing.T) {
+	for i := 0; i < 100; i++ {
+		c := make(chan int, 1)
+		go testDeferPtrsGoexit(c, i)
+		if n := <-c; n != 42 {
+			t.Fatalf("defer's stack references were not adjusted appropriately (i=%d n=%d)", i, n)
+		}
+	}
+}
+
+func testDeferPtrsGoexit(c chan int, i int) {
+	var y int
+	defer func() {
+		c <- y
+	}()
+	defer setBig(&y, 42, bigBuf{})
+	useStackAndCall(i, Goexit)
+}
+
+func setBig(p *int, x int, b bigBuf) {
+	*p = x
+}
+
+// TestDeferPtrsPanic is like TestDeferPtrsGoexit, but it's using panic instead
+// of Goexit to run the Defers. Those two are different execution paths
+// in the runtime.
+func TestDeferPtrsPanic(t *testing.T) {
+	for i := 0; i < 100; i++ {
+		c := make(chan int, 1)
+		go testDeferPtrsGoexit(c, i)
+		if n := <-c; n != 42 {
+			t.Fatalf("defer's stack references were not adjusted appropriately (i=%d n=%d)", i, n)
+		}
+	}
+}
+
+func testDeferPtrsPanic(c chan int, i int) {
+	var y int
+	defer func() {
+		if recover() == nil {
+			c <- -1
+			return
+		}
+		c <- y
+	}()
+	defer setBig(&y, 42, bigBuf{})
+	useStackAndCall(i, func() { panic(1) })
+}
+
+// TestPanicUseStack checks that a chain of Panic structs on the stack are
+// updated correctly if the stack grows during the deferred execution that
+// happens as a result of the panic.
+func TestPanicUseStack(t *testing.T) {
+	pc := make([]uintptr, 10000)
+	defer func() {
+		recover()
+		Callers(0, pc) // force stack walk
+		useStackAndCall(100, func() {
+			defer func() {
+				recover()
+				Callers(0, pc) // force stack walk
+				useStackAndCall(200, func() {
+					defer func() {
+						recover()
+						Callers(0, pc) // force stack walk
+					}()
+					panic(3)
+				})
+			}()
+			panic(2)
+		})
+	}()
+	panic(1)
+}
+
+// use about n KB of stack and call f
+func useStackAndCall(n int, f func()) {
+	if n == 0 {
+		f()
+		return
+	}
+	var b [1024]byte // makes frame about 1KB
+	useStackAndCall(n-1+int(b[99]), f)
+}
+
+func useStack(n int) {
+	useStackAndCall(n, func() {})
+}
+
+func growing(c chan int, done chan struct{}) {
+	for n := range c {
+		useStack(n)
+		done <- struct{}{}
+	}
+	done <- struct{}{}
+}
+
+func TestStackCache(t *testing.T) {
+	// Allocate a bunch of goroutines and grow their stacks.
+	// Repeat a few times to test the stack cache.
+	const (
+		R = 4
+		G = 200
+		S = 5
+	)
+	for i := 0; i < R; i++ {
+		var reqchans [G]chan int
+		done := make(chan struct{})
+		for j := 0; j < G; j++ {
+			reqchans[j] = make(chan int)
+			go growing(reqchans[j], done)
+		}
+		for s := 0; s < S; s++ {
+			for j := 0; j < G; j++ {
+				reqchans[j] <- 1 << uint(s)
+			}
+			for j := 0; j < G; j++ {
+				<-done
+			}
+		}
+		for j := 0; j < G; j++ {
+			close(reqchans[j])
+		}
+		for j := 0; j < G; j++ {
+			<-done
+		}
+	}
+}
+
+func TestStackOutput(t *testing.T) {
+	b := make([]byte, 1024)
+	stk := string(b[:Stack(b, false)])
+	if !strings.HasPrefix(stk, "goroutine ") {
+		t.Errorf("Stack (len %d):\n%s", len(stk), stk)
+		t.Errorf("Stack output should begin with \"goroutine \"")
+	}
+}
+
+func TestStackAllOutput(t *testing.T) {
+	b := make([]byte, 1024)
+	stk := string(b[:Stack(b, true)])
+	if !strings.HasPrefix(stk, "goroutine ") {
+		t.Errorf("Stack (len %d):\n%s", len(stk), stk)
+		t.Errorf("Stack output should begin with \"goroutine \"")
+	}
+}
+
+func TestStackPanic(t *testing.T) {
+	// Test that stack copying copies panics correctly.  This is difficult
+	// to test because it is very unlikely that the stack will be copied
+	// in the middle of gopanic.  But it can happen.
+	// To make this test effective, edit panic.go:gopanic and uncomment
+	// the GC() call just before freedefer(d).
+	defer func() {
+		if x := recover(); x == nil {
+			t.Errorf("recover failed")
+		}
+	}()
+	useStack(32)
+	panic("test panic")
+}
diff --git a/src/runtime/string.c b/src/runtime/string.c
new file mode 100644
index 0000000..ed5debc
--- /dev/null
+++ b/src/runtime/string.c
@@ -0,0 +1,226 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "runtime.h"
+#include "arch_GOARCH.h"
+#include "malloc.h"
+#include "race.h"
+#include "textflag.h"
+
+String	runtime·emptystring;
+
+#pragma textflag NOSPLIT
+intgo
+runtime·findnull(byte *s)
+{
+	intgo l;
+
+	if(s == nil)
+		return 0;
+	for(l=0; s[l]!=0; l++)
+		;
+	return l;
+}
+
+intgo
+runtime·findnullw(uint16 *s)
+{
+	intgo l;
+
+	if(s == nil)
+		return 0;
+	for(l=0; s[l]!=0; l++)
+		;
+	return l;
+}
+
+uintptr runtime·maxstring = 256; // a hint for print
+
+#pragma textflag NOSPLIT
+String
+runtime·gostringnocopy(byte *str)
+{
+	String s;
+	uintptr ms;
+	
+	s.str = str;
+	s.len = runtime·findnull(str);
+	while(true) {
+		ms = runtime·maxstring;
+		if(s.len <= ms || runtime·casp((void**)&runtime·maxstring, (void*)ms, (void*)s.len))
+			return s;
+	}
+}
+
+// TODO: move this elsewhere
+enum
+{
+	Bit1	= 7,
+	Bitx	= 6,
+	Bit2	= 5,
+	Bit3	= 4,
+	Bit4	= 3,
+	Bit5	= 2,
+
+	Tx	= ((1<<(Bitx+1))-1) ^ 0xFF,	/* 1000 0000 */
+	T2	= ((1<<(Bit2+1))-1) ^ 0xFF,	/* 1100 0000 */
+	T3	= ((1<<(Bit3+1))-1) ^ 0xFF,	/* 1110 0000 */
+	T4	= ((1<<(Bit4+1))-1) ^ 0xFF,	/* 1111 0000 */
+
+	Rune1	= (1<<(Bit1+0*Bitx))-1,		/* 0000 0000 0111 1111 */
+	Rune2	= (1<<(Bit2+1*Bitx))-1,		/* 0000 0111 1111 1111 */
+	Rune3	= (1<<(Bit3+2*Bitx))-1,		/* 1111 1111 1111 1111 */
+
+	Maskx	= (1<<Bitx)-1,			/* 0011 1111 */
+
+	Runeerror	= 0xFFFD,
+
+	SurrogateMin = 0xD800,
+	SurrogateMax = 0xDFFF,
+
+	Runemax	= 0x10FFFF,	/* maximum rune value */
+};
+
+static int32
+runetochar(byte *str, int32 rune)  /* note: in original, arg2 was pointer */
+{
+	/* Runes are signed, so convert to unsigned for range check. */
+	uint32 c;
+
+	/*
+	 * one character sequence
+	 *	00000-0007F => 00-7F
+	 */
+	c = rune;
+	if(c <= Rune1) {
+		str[0] = c;
+		return 1;
+	}
+
+	/*
+	 * two character sequence
+	 *	0080-07FF => T2 Tx
+	 */
+	if(c <= Rune2) {
+		str[0] = T2 | (c >> 1*Bitx);
+		str[1] = Tx | (c & Maskx);
+		return 2;
+	}
+
+	/*
+	 * If the Rune is out of range or a surrogate half, convert it to the error rune.
+	 * Do this test here because the error rune encodes to three bytes.
+	 * Doing it earlier would duplicate work, since an out of range
+	 * Rune wouldn't have fit in one or two bytes.
+	 */
+	if (c > Runemax)
+		c = Runeerror;
+	if (SurrogateMin <= c && c <= SurrogateMax)
+		c = Runeerror;
+
+	/*
+	 * three character sequence
+	 *	0800-FFFF => T3 Tx Tx
+	 */
+	if (c <= Rune3) {
+		str[0] = T3 |  (c >> 2*Bitx);
+		str[1] = Tx | ((c >> 1*Bitx) & Maskx);
+		str[2] = Tx |  (c & Maskx);
+		return 3;
+	}
+
+	/*
+	 * four character sequence (21-bit value)
+	 *     10000-1FFFFF => T4 Tx Tx Tx
+	 */
+	str[0] = T4 | (c >> 3*Bitx);
+	str[1] = Tx | ((c >> 2*Bitx) & Maskx);
+	str[2] = Tx | ((c >> 1*Bitx) & Maskx);
+	str[3] = Tx | (c & Maskx);
+	return 4;
+}
+
+String runtime·gostringsize(intgo);
+
+String
+runtime·gostringw(uint16 *str)
+{
+	intgo n1, n2, i;
+	byte buf[8];
+	String s;
+
+	n1 = 0;
+	for(i=0; str[i]; i++)
+		n1 += runetochar(buf, str[i]);
+	s = runtime·gostringsize(n1+4);
+	n2 = 0;
+	for(i=0; str[i]; i++) {
+		// check for race
+		if(n2 >= n1)
+			break;
+		n2 += runetochar(s.str+n2, str[i]);
+	}
+	s.len = n2;
+	s.str[s.len] = 0;
+	return s;
+}
+
+int32
+runtime·strcmp(byte *s1, byte *s2)
+{
+	uintptr i;
+	byte c1, c2;
+
+	for(i=0;; i++) {
+		c1 = s1[i];
+		c2 = s2[i];
+		if(c1 < c2)
+			return -1;
+		if(c1 > c2)
+			return +1;
+		if(c1 == 0)
+			return 0;
+	}
+}
+
+int32
+runtime·strncmp(byte *s1, byte *s2, uintptr n)
+{
+	uintptr i;
+	byte c1, c2;
+
+	for(i=0; i<n; i++) {
+		c1 = s1[i];
+		c2 = s2[i];
+		if(c1 < c2)
+			return -1;
+		if(c1 > c2)
+			return +1;
+		if(c1 == 0)
+			break;
+	}
+	return 0;
+}
+
+byte*
+runtime·strstr(byte *s1, byte *s2)
+{
+	byte *sp1, *sp2;
+
+	if(*s2 == 0)
+		return s1;
+	for(; *s1; s1++) {
+		if(*s1 != *s2)
+			continue;
+		sp1 = s1;
+		sp2 = s2;
+		for(;;) {
+			if(*sp2 == 0)
+				return s1;
+			if(*sp1++ != *sp2++)
+				break;
+		}
+	}
+	return nil;
+}
diff --git a/src/runtime/string.go b/src/runtime/string.go
new file mode 100644
index 0000000..0809f89
--- /dev/null
+++ b/src/runtime/string.go
@@ -0,0 +1,298 @@
+// 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 runtime
+
+import (
+	"unsafe"
+)
+
+func concatstrings(a []string) string {
+	idx := 0
+	l := 0
+	count := 0
+	for i, x := range a {
+		n := len(x)
+		if n == 0 {
+			continue
+		}
+		if l+n < l {
+			gothrow("string concatenation too long")
+		}
+		l += n
+		count++
+		idx = i
+	}
+	if count == 0 {
+		return ""
+	}
+	if count == 1 {
+		return a[idx]
+	}
+	s, b := rawstring(l)
+	l = 0
+	for _, x := range a {
+		copy(b[l:], x)
+		l += len(x)
+	}
+	return s
+}
+
+//go:nosplit
+func concatstring2(a [2]string) string {
+	return concatstrings(a[:])
+}
+
+//go:nosplit
+func concatstring3(a [3]string) string {
+	return concatstrings(a[:])
+}
+
+//go:nosplit
+func concatstring4(a [4]string) string {
+	return concatstrings(a[:])
+}
+
+//go:nosplit
+func concatstring5(a [5]string) string {
+	return concatstrings(a[:])
+}
+
+func slicebytetostring(b []byte) string {
+	if raceenabled && len(b) > 0 {
+		racereadrangepc(unsafe.Pointer(&b[0]),
+			uintptr(len(b)),
+			getcallerpc(unsafe.Pointer(&b)),
+			funcPC(slicebytetostring))
+	}
+	s, c := rawstring(len(b))
+	copy(c, b)
+	return s
+}
+
+func slicebytetostringtmp(b []byte) string {
+	// Return a "string" referring to the actual []byte bytes.
+	// This is only for use by internal compiler optimizations
+	// that know that the string form will be discarded before
+	// the calling goroutine could possibly modify the original
+	// slice or synchronize with another goroutine.
+	// Today, the only such case is a m[string(k)] lookup where
+	// m is a string-keyed map and k is a []byte.
+
+	if raceenabled && len(b) > 0 {
+		racereadrangepc(unsafe.Pointer(&b[0]),
+			uintptr(len(b)),
+			getcallerpc(unsafe.Pointer(&b)),
+			funcPC(slicebytetostringtmp))
+	}
+	return *(*string)(unsafe.Pointer(&b))
+}
+
+func stringtoslicebyte(s string) []byte {
+	b := rawbyteslice(len(s))
+	copy(b, s)
+	return b
+}
+
+func stringtoslicerune(s string) []rune {
+	// two passes.
+	// unlike slicerunetostring, no race because strings are immutable.
+	n := 0
+	t := s
+	for len(s) > 0 {
+		_, k := charntorune(s)
+		s = s[k:]
+		n++
+	}
+	a := rawruneslice(n)
+	n = 0
+	for len(t) > 0 {
+		r, k := charntorune(t)
+		t = t[k:]
+		a[n] = r
+		n++
+	}
+	return a
+}
+
+func slicerunetostring(a []rune) string {
+	if raceenabled && len(a) > 0 {
+		racereadrangepc(unsafe.Pointer(&a[0]),
+			uintptr(len(a))*unsafe.Sizeof(a[0]),
+			getcallerpc(unsafe.Pointer(&a)),
+			funcPC(slicerunetostring))
+	}
+	var dum [4]byte
+	size1 := 0
+	for _, r := range a {
+		size1 += runetochar(dum[:], r)
+	}
+	s, b := rawstring(size1 + 3)
+	size2 := 0
+	for _, r := range a {
+		// check for race
+		if size2 >= size1 {
+			break
+		}
+		size2 += runetochar(b[size2:], r)
+	}
+	return s[:size2]
+}
+
+type stringStruct struct {
+	str unsafe.Pointer
+	len int
+}
+
+func intstring(v int64) string {
+	s, b := rawstring(4)
+	n := runetochar(b, rune(v))
+	return s[:n]
+}
+
+// stringiter returns the index of the next
+// rune after the rune that starts at s[k].
+func stringiter(s string, k int) int {
+	if k >= len(s) {
+		// 0 is end of iteration
+		return 0
+	}
+
+	c := s[k]
+	if c < runeself {
+		return k + 1
+	}
+
+	// multi-char rune
+	_, n := charntorune(s[k:])
+	return k + n
+}
+
+// stringiter2 returns the rune that starts at s[k]
+// and the index where the next rune starts.
+func stringiter2(s string, k int) (int, rune) {
+	if k >= len(s) {
+		// 0 is end of iteration
+		return 0, 0
+	}
+
+	c := s[k]
+	if c < runeself {
+		return k + 1, rune(c)
+	}
+
+	// multi-char rune
+	r, n := charntorune(s[k:])
+	return k + n, r
+}
+
+// rawstring allocates storage for a new string. The returned
+// string and byte slice both refer to the same storage.
+// The storage is not zeroed. Callers should use
+// b to set the string contents and then drop b.
+func rawstring(size int) (s string, b []byte) {
+	p := mallocgc(uintptr(size), nil, flagNoScan|flagNoZero)
+
+	(*stringStruct)(unsafe.Pointer(&s)).str = p
+	(*stringStruct)(unsafe.Pointer(&s)).len = size
+
+	(*slice)(unsafe.Pointer(&b)).array = (*uint8)(p)
+	(*slice)(unsafe.Pointer(&b)).len = uint(size)
+	(*slice)(unsafe.Pointer(&b)).cap = uint(size)
+
+	for {
+		ms := maxstring
+		if uintptr(size) <= uintptr(ms) || casuintptr((*uintptr)(unsafe.Pointer(&maxstring)), uintptr(ms), uintptr(size)) {
+			return
+		}
+	}
+}
+
+// rawbyteslice allocates a new byte slice. The byte slice is not zeroed.
+func rawbyteslice(size int) (b []byte) {
+	cap := goroundupsize(uintptr(size))
+	p := mallocgc(cap, nil, flagNoScan|flagNoZero)
+	if cap != uintptr(size) {
+		memclr(add(p, uintptr(size)), cap-uintptr(size))
+	}
+
+	(*slice)(unsafe.Pointer(&b)).array = (*uint8)(p)
+	(*slice)(unsafe.Pointer(&b)).len = uint(size)
+	(*slice)(unsafe.Pointer(&b)).cap = uint(cap)
+	return
+}
+
+// rawruneslice allocates a new rune slice. The rune slice is not zeroed.
+func rawruneslice(size int) (b []rune) {
+	if uintptr(size) > maxmem/4 {
+		gothrow("out of memory")
+	}
+	mem := goroundupsize(uintptr(size) * 4)
+	p := mallocgc(mem, nil, flagNoScan|flagNoZero)
+	if mem != uintptr(size)*4 {
+		memclr(add(p, uintptr(size)*4), mem-uintptr(size)*4)
+	}
+
+	(*slice)(unsafe.Pointer(&b)).array = (*uint8)(p)
+	(*slice)(unsafe.Pointer(&b)).len = uint(size)
+	(*slice)(unsafe.Pointer(&b)).cap = uint(mem / 4)
+	return
+}
+
+// used by cmd/cgo
+func gobytes(p *byte, n int) []byte {
+	if n == 0 {
+		return make([]byte, 0)
+	}
+	x := make([]byte, n)
+	memmove(unsafe.Pointer(&x[0]), unsafe.Pointer(p), uintptr(n))
+	return x
+}
+
+func gostringsize(n int) string {
+	s, _ := rawstring(n)
+	return s
+}
+
+//go:noescape
+func findnull(*byte) int
+
+func gostring(p *byte) string {
+	l := findnull(p)
+	if l == 0 {
+		return ""
+	}
+	s, b := rawstring(l)
+	memmove(unsafe.Pointer(&b[0]), unsafe.Pointer(p), uintptr(l))
+	return s
+}
+
+func gostringn(p *byte, l int) string {
+	if l == 0 {
+		return ""
+	}
+	s, b := rawstring(l)
+	memmove(unsafe.Pointer(&b[0]), unsafe.Pointer(p), uintptr(l))
+	return s
+}
+
+func index(s, t string) int {
+	if len(t) == 0 {
+		return 0
+	}
+	for i := 0; i < len(s); i++ {
+		if s[i] == t[0] && hasprefix(s[i:], t) {
+			return i
+		}
+	}
+	return -1
+}
+
+func contains(s, t string) bool {
+	return index(s, t) >= 0
+}
+
+func hasprefix(s, t string) bool {
+	return len(s) >= len(t) && s[:len(t)] == t
+}
diff --git a/src/runtime/string_test.go b/src/runtime/string_test.go
new file mode 100644
index 0000000..1551ecc
--- /dev/null
+++ b/src/runtime/string_test.go
@@ -0,0 +1,160 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package runtime_test
+
+import (
+	"runtime"
+	"strings"
+	"testing"
+)
+
+func BenchmarkCompareStringEqual(b *testing.B) {
+	bytes := []byte("Hello Gophers!")
+	s1, s2 := string(bytes), string(bytes)
+	for i := 0; i < b.N; i++ {
+		if s1 != s2 {
+			b.Fatal("s1 != s2")
+		}
+	}
+}
+
+func BenchmarkCompareStringIdentical(b *testing.B) {
+	s1 := "Hello Gophers!"
+	s2 := s1
+	for i := 0; i < b.N; i++ {
+		if s1 != s2 {
+			b.Fatal("s1 != s2")
+		}
+	}
+}
+
+func BenchmarkCompareStringSameLength(b *testing.B) {
+	s1 := "Hello Gophers!"
+	s2 := "Hello, Gophers"
+	for i := 0; i < b.N; i++ {
+		if s1 == s2 {
+			b.Fatal("s1 == s2")
+		}
+	}
+}
+
+func BenchmarkCompareStringDifferentLength(b *testing.B) {
+	s1 := "Hello Gophers!"
+	s2 := "Hello, Gophers!"
+	for i := 0; i < b.N; i++ {
+		if s1 == s2 {
+			b.Fatal("s1 == s2")
+		}
+	}
+}
+
+func BenchmarkCompareStringBigUnaligned(b *testing.B) {
+	bytes := make([]byte, 0, 1<<20)
+	for len(bytes) < 1<<20 {
+		bytes = append(bytes, "Hello Gophers!"...)
+	}
+	s1, s2 := string(bytes), "hello"+string(bytes)
+	for i := 0; i < b.N; i++ {
+		if s1 != s2[len("hello"):] {
+			b.Fatal("s1 != s2")
+		}
+	}
+	b.SetBytes(int64(len(s1)))
+}
+
+func BenchmarkCompareStringBig(b *testing.B) {
+	bytes := make([]byte, 0, 1<<20)
+	for len(bytes) < 1<<20 {
+		bytes = append(bytes, "Hello Gophers!"...)
+	}
+	s1, s2 := string(bytes), string(bytes)
+	for i := 0; i < b.N; i++ {
+		if s1 != s2 {
+			b.Fatal("s1 != s2")
+		}
+	}
+	b.SetBytes(int64(len(s1)))
+}
+
+func BenchmarkRuneIterate(b *testing.B) {
+	bytes := make([]byte, 100)
+	for i := range bytes {
+		bytes[i] = byte('A')
+	}
+	s := string(bytes)
+	for i := 0; i < b.N; i++ {
+		for range s {
+		}
+	}
+}
+
+func BenchmarkRuneIterate2(b *testing.B) {
+	bytes := make([]byte, 100)
+	for i := range bytes {
+		bytes[i] = byte('A')
+	}
+	s := string(bytes)
+	for i := 0; i < b.N; i++ {
+		for range s {
+		}
+	}
+}
+
+func TestStringW(t *testing.T) {
+	strings := []string{
+		"hello",
+		"a\u5566\u7788b",
+	}
+
+	for _, s := range strings {
+		var b []uint16
+		for _, c := range s {
+			b = append(b, uint16(c))
+			if c != rune(uint16(c)) {
+				t.Errorf("bad test: stringW can't handle >16 bit runes")
+			}
+		}
+		b = append(b, 0)
+		r := runtime.GostringW(b)
+		if r != s {
+			t.Errorf("gostringW(%v) = %s, want %s", b, r, s)
+		}
+	}
+}
+
+func TestLargeStringConcat(t *testing.T) {
+	output := executeTest(t, largeStringConcatSource, nil)
+	want := "panic: " + strings.Repeat("0", 1<<10) + strings.Repeat("1", 1<<10) +
+		strings.Repeat("2", 1<<10) + strings.Repeat("3", 1<<10)
+	if !strings.HasPrefix(output, want) {
+		t.Fatalf("output does not start with %q:\n%s", want, output)
+	}
+}
+
+var largeStringConcatSource = `
+package main
+import "strings"
+func main() {
+	s0 := strings.Repeat("0", 1<<10)
+	s1 := strings.Repeat("1", 1<<10)
+	s2 := strings.Repeat("2", 1<<10)
+	s3 := strings.Repeat("3", 1<<10)
+	s := s0 + s1 + s2 + s3
+	panic(s)
+}
+`
+
+func TestGostringnocopy(t *testing.T) {
+	max := *runtime.Maxstring
+	b := make([]byte, max+10)
+	for i := uintptr(0); i < max+9; i++ {
+		b[i] = 'a'
+	}
+	_ = runtime.Gostringnocopy(&b[0])
+	newmax := *runtime.Maxstring
+	if newmax != max+9 {
+		t.Errorf("want %d, got %d", max+9, newmax)
+	}
+}
diff --git a/src/runtime/stubs.go b/src/runtime/stubs.go
new file mode 100644
index 0000000..fe8f9c9
--- /dev/null
+++ b/src/runtime/stubs.go
@@ -0,0 +1,316 @@
+// 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 runtime
+
+import "unsafe"
+
+// Declarations for runtime services implemented in C or assembly.
+
+const ptrSize = 4 << (^uintptr(0) >> 63) // unsafe.Sizeof(uintptr(0)) but an ideal const
+const regSize = 4 << (^uintreg(0) >> 63) // unsafe.Sizeof(uintreg(0)) but an ideal const
+
+// Should be a built-in for unsafe.Pointer?
+//go:nosplit
+func add(p unsafe.Pointer, x uintptr) unsafe.Pointer {
+	return unsafe.Pointer(uintptr(p) + x)
+}
+
+// n must be a power of 2
+func roundup(p unsafe.Pointer, n uintptr) unsafe.Pointer {
+	delta := -uintptr(p) & (n - 1)
+	return unsafe.Pointer(uintptr(p) + delta)
+}
+
+// in runtime.c
+func getg() *g
+func acquirem() *m
+func releasem(mp *m)
+func gomcache() *mcache
+func readgstatus(*g) uint32 // proc.c
+
+// mcall switches from the g to the g0 stack and invokes fn(g),
+// where g is the goroutine that made the call.
+// mcall saves g's current PC/SP in g->sched so that it can be restored later.
+// It is up to fn to arrange for that later execution, typically by recording
+// g in a data structure, causing something to call ready(g) later.
+// mcall returns to the original goroutine g later, when g has been rescheduled.
+// fn must not return at all; typically it ends by calling schedule, to let the m
+// run other goroutines.
+//
+// mcall can only be called from g stacks (not g0, not gsignal).
+//go:noescape
+func mcall(fn func(*g))
+
+// onM switches from the g to the g0 stack and invokes fn().
+// When fn returns, onM switches back to the g and returns,
+// continuing execution on the g stack.
+// If arguments must be passed to fn, they can be written to
+// g->m->ptrarg (pointers) and g->m->scalararg (non-pointers)
+// before the call and then consulted during fn.
+// Similarly, fn can pass return values back in those locations.
+// If fn is written in Go, it can be a closure, which avoids the need for
+// ptrarg and scalararg entirely.
+// After reading values out of ptrarg and scalararg it is conventional
+// to zero them to avoid (memory or information) leaks.
+//
+// If onM is called from a g0 stack, it invokes fn and returns,
+// without any stack switches.
+//
+// If onM is called from a gsignal stack, it crashes the program.
+// The implication is that functions used in signal handlers must
+// not use onM.
+//
+// NOTE(rsc): We could introduce a separate onMsignal that is
+// like onM but if called from a gsignal stack would just run fn on
+// that stack. The caller of onMsignal would be required to save the
+// old values of ptrarg/scalararg and restore them when the call
+// was finished, in case the signal interrupted an onM sequence
+// in progress on the g or g0 stacks. Until there is a clear need for this,
+// we just reject onM in signal handling contexts entirely.
+//
+//go:noescape
+func onM(fn func())
+
+// onMsignal is like onM but is allowed to be used in code that
+// might run on the gsignal stack. Code running on a signal stack
+// may be interrupting an onM sequence on the main stack, so
+// if the onMsignal calling sequence writes to ptrarg/scalararg,
+// it must first save the old values and then restore them when
+// finished. As an exception to the rule, it is fine not to save and
+// restore the values if the program is trying to crash rather than
+// return from the signal handler.
+// Once all the runtime is written in Go, there will be no ptrarg/scalararg
+// and the distinction between onM and onMsignal (and perhaps mcall)
+// can go away.
+//
+// If onMsignal is called from a gsignal stack, it invokes fn directly,
+// without a stack switch. Otherwise onMsignal behaves like onM.
+//
+//go:noescape
+func onM_signalok(fn func())
+
+func badonm() {
+	gothrow("onM called from signal goroutine")
+}
+
+// C functions that run on the M stack.
+// Call using mcall.
+func gosched_m(*g)
+func park_m(*g)
+func recovery_m(*g)
+
+// More C functions that run on the M stack.
+// Call using onM.
+func mcacheRefill_m()
+func largeAlloc_m()
+func gc_m()
+func scavenge_m()
+func setFinalizer_m()
+func removeFinalizer_m()
+func markallocated_m()
+func unrollgcprog_m()
+func unrollgcproginplace_m()
+func setgcpercent_m()
+func setmaxthreads_m()
+func ready_m()
+func deferproc_m()
+func goexit_m()
+func startpanic_m()
+func dopanic_m()
+func readmemstats_m()
+func writeheapdump_m()
+
+// memclr clears n bytes starting at ptr.
+// in memclr_*.s
+//go:noescape
+func memclr(ptr unsafe.Pointer, n uintptr)
+
+// memmove copies n bytes from "from" to "to".
+// in memmove_*.s
+//go:noescape
+func memmove(to unsafe.Pointer, from unsafe.Pointer, n uintptr)
+
+func starttheworld()
+func stoptheworld()
+func newextram()
+func lockOSThread()
+func unlockOSThread()
+
+// exported value for testing
+var hashLoad = loadFactor
+
+// in asm_*.s
+func fastrand1() uint32
+
+// in asm_*.s
+//go:noescape
+func memeq(a, b unsafe.Pointer, size uintptr) bool
+
+// noescape hides a pointer from escape analysis.  noescape is
+// the identity function but escape analysis doesn't think the
+// output depends on the input.  noescape is inlined and currently
+// compiles down to a single xor instruction.
+// USE CAREFULLY!
+//go:nosplit
+func noescape(p unsafe.Pointer) unsafe.Pointer {
+	x := uintptr(p)
+	return unsafe.Pointer(x ^ 0)
+}
+
+func entersyscall()
+func reentersyscall(pc uintptr, sp unsafe.Pointer)
+func entersyscallblock()
+func exitsyscall()
+
+func cgocallback(fn, frame unsafe.Pointer, framesize uintptr)
+func gogo(buf *gobuf)
+func gosave(buf *gobuf)
+func read(fd int32, p unsafe.Pointer, n int32) int32
+func close(fd int32) int32
+func mincore(addr unsafe.Pointer, n uintptr, dst *byte) int32
+
+//go:noescape
+func jmpdefer(fv *funcval, argp uintptr)
+func exit1(code int32)
+func asminit()
+func setg(gg *g)
+func exit(code int32)
+func breakpoint()
+func nanotime() int64
+func usleep(usec uint32)
+
+// careful: cputicks is not guaranteed to be monotonic!  In particular, we have
+// noticed drift between cpus on certain os/arch combinations.  See issue 8976.
+func cputicks() int64
+
+func mmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uint32) unsafe.Pointer
+func munmap(addr unsafe.Pointer, n uintptr)
+func madvise(addr unsafe.Pointer, n uintptr, flags int32)
+func reflectcall(fn, arg unsafe.Pointer, n uint32, retoffset uint32)
+func osyield()
+func procyield(cycles uint32)
+func cgocallback_gofunc(fv *funcval, frame unsafe.Pointer, framesize uintptr)
+func readgogc() int32
+func purgecachedstats(c *mcache)
+func gostringnocopy(b *byte) string
+func goexit()
+
+//go:noescape
+func write(fd uintptr, p unsafe.Pointer, n int32) int32
+
+//go:noescape
+func cas(ptr *uint32, old, new uint32) bool
+
+//go:noescape
+func casp(ptr *unsafe.Pointer, old, new unsafe.Pointer) bool
+
+//go:noescape
+func casuintptr(ptr *uintptr, old, new uintptr) bool
+
+//go:noescape
+func atomicstoreuintptr(ptr *uintptr, new uintptr)
+
+//go:noescape
+func atomicloaduintptr(ptr *uintptr) uintptr
+
+//go:noescape
+func atomicloaduint(ptr *uint) uint
+
+//go:noescape
+func setcallerpc(argp unsafe.Pointer, pc uintptr)
+
+// getcallerpc returns the program counter (PC) of its caller's caller.
+// getcallersp returns the stack pointer (SP) of its caller's caller.
+// For both, the argp must be a pointer to the caller's first function argument.
+// The implementation may or may not use argp, depending on
+// the architecture.
+//
+// For example:
+//
+//	func f(arg1, arg2, arg3 int) {
+//		pc := getcallerpc(unsafe.Pointer(&arg1))
+//		sp := getcallerpc(unsafe.Pointer(&arg2))
+//	}
+//
+// These two lines find the PC and SP immediately following
+// the call to f (where f will return).
+//
+// The call to getcallerpc and getcallersp must be done in the
+// frame being asked about. It would not be correct for f to pass &arg1
+// to another function g and let g call getcallerpc/getcallersp.
+// The call inside g might return information about g's caller or
+// information about f's caller or complete garbage.
+//
+// The result of getcallersp is correct at the time of the return,
+// but it may be invalidated by any subsequent call to a function
+// that might relocate the stack in order to grow or shrink it.
+// A general rule is that the result of getcallersp should be used
+// immediately and can only be passed to nosplit functions.
+
+//go:noescape
+func getcallerpc(argp unsafe.Pointer) uintptr
+
+//go:noescape
+func getcallersp(argp unsafe.Pointer) uintptr
+
+//go:noescape
+func asmcgocall(fn, arg unsafe.Pointer)
+
+//go:noescape
+func asmcgocall_errno(fn, arg unsafe.Pointer) int32
+
+//go:noescape
+func open(name *byte, mode, perm int32) int32
+
+//go:noescape
+func gotraceback(*bool) int32
+
+const _NoArgs = ^uintptr(0)
+
+func newstack()
+func newproc()
+func morestack()
+func mstart()
+func rt0_go()
+
+// return0 is a stub used to return 0 from deferproc.
+// It is called at the very end of deferproc to signal
+// the calling Go function that it should not jump
+// to deferreturn.
+// in asm_*.s
+func return0()
+
+// thunk to call time.now.
+func timenow() (sec int64, nsec int32)
+
+// in asm_*.s
+// not called directly; definitions here supply type information for traceback.
+func call16(fn, arg unsafe.Pointer, n, retoffset uint32)
+func call32(fn, arg unsafe.Pointer, n, retoffset uint32)
+func call64(fn, arg unsafe.Pointer, n, retoffset uint32)
+func call128(fn, arg unsafe.Pointer, n, retoffset uint32)
+func call256(fn, arg unsafe.Pointer, n, retoffset uint32)
+func call512(fn, arg unsafe.Pointer, n, retoffset uint32)
+func call1024(fn, arg unsafe.Pointer, n, retoffset uint32)
+func call2048(fn, arg unsafe.Pointer, n, retoffset uint32)
+func call4096(fn, arg unsafe.Pointer, n, retoffset uint32)
+func call8192(fn, arg unsafe.Pointer, n, retoffset uint32)
+func call16384(fn, arg unsafe.Pointer, n, retoffset uint32)
+func call32768(fn, arg unsafe.Pointer, n, retoffset uint32)
+func call65536(fn, arg unsafe.Pointer, n, retoffset uint32)
+func call131072(fn, arg unsafe.Pointer, n, retoffset uint32)
+func call262144(fn, arg unsafe.Pointer, n, retoffset uint32)
+func call524288(fn, arg unsafe.Pointer, n, retoffset uint32)
+func call1048576(fn, arg unsafe.Pointer, n, retoffset uint32)
+func call2097152(fn, arg unsafe.Pointer, n, retoffset uint32)
+func call4194304(fn, arg unsafe.Pointer, n, retoffset uint32)
+func call8388608(fn, arg unsafe.Pointer, n, retoffset uint32)
+func call16777216(fn, arg unsafe.Pointer, n, retoffset uint32)
+func call33554432(fn, arg unsafe.Pointer, n, retoffset uint32)
+func call67108864(fn, arg unsafe.Pointer, n, retoffset uint32)
+func call134217728(fn, arg unsafe.Pointer, n, retoffset uint32)
+func call268435456(fn, arg unsafe.Pointer, n, retoffset uint32)
+func call536870912(fn, arg unsafe.Pointer, n, retoffset uint32)
+func call1073741824(fn, arg unsafe.Pointer, n, retoffset uint32)
diff --git a/src/runtime/symtab.go b/src/runtime/symtab.go
new file mode 100644
index 0000000..45d107b
--- /dev/null
+++ b/src/runtime/symtab.go
@@ -0,0 +1,288 @@
+// 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 runtime
+
+import "unsafe"
+
+// NOTE: Func does not expose the actual unexported fields, because we return *Func
+// values to users, and we want to keep them from being able to overwrite the data
+// with (say) *f = Func{}.
+// All code operating on a *Func must call raw to get the *_func instead.
+
+// A Func represents a Go function in the running binary.
+type Func struct {
+	opaque struct{} // unexported field to disallow conversions
+}
+
+func (f *Func) raw() *_func {
+	return (*_func)(unsafe.Pointer(f))
+}
+
+// funcdata.h
+const (
+	_PCDATA_ArgSize             = 0
+	_PCDATA_StackMapIndex       = 1
+	_FUNCDATA_ArgsPointerMaps   = 0
+	_FUNCDATA_LocalsPointerMaps = 1
+	_FUNCDATA_DeadValueMaps     = 2
+	_ArgsSizeUnknown            = -0x80000000
+)
+
+var (
+	pclntable []byte
+	ftab      []functab
+	filetab   []uint32
+
+	pclntab, epclntab struct{} // linker symbols
+)
+
+type functab struct {
+	entry   uintptr
+	funcoff uintptr
+}
+
+func symtabinit() {
+	// See golang.org/s/go12symtab for header: 0xfffffffb,
+	// two zero bytes, a byte giving the PC quantum,
+	// and a byte giving the pointer width in bytes.
+	pcln := (*[8]byte)(unsafe.Pointer(&pclntab))
+	pcln32 := (*[2]uint32)(unsafe.Pointer(&pclntab))
+	if pcln32[0] != 0xfffffffb || pcln[4] != 0 || pcln[5] != 0 || pcln[6] != _PCQuantum || pcln[7] != ptrSize {
+		println("runtime: function symbol table header:", hex(pcln32[0]), hex(pcln[4]), hex(pcln[5]), hex(pcln[6]), hex(pcln[7]))
+		gothrow("invalid function symbol table\n")
+	}
+
+	// pclntable is all bytes of pclntab symbol.
+	sp := (*sliceStruct)(unsafe.Pointer(&pclntable))
+	sp.array = unsafe.Pointer(&pclntab)
+	sp.len = int(uintptr(unsafe.Pointer(&epclntab)) - uintptr(unsafe.Pointer(&pclntab)))
+	sp.cap = sp.len
+
+	// ftab is lookup table for function by program counter.
+	nftab := int(*(*uintptr)(add(unsafe.Pointer(pcln), 8)))
+	p := add(unsafe.Pointer(pcln), 8+ptrSize)
+	sp = (*sliceStruct)(unsafe.Pointer(&ftab))
+	sp.array = p
+	sp.len = nftab + 1
+	sp.cap = sp.len
+	for i := 0; i < nftab; i++ {
+		// NOTE: ftab[nftab].entry is legal; it is the address beyond the final function.
+		if ftab[i].entry > ftab[i+1].entry {
+			f1 := (*_func)(unsafe.Pointer(&pclntable[ftab[i].funcoff]))
+			f2 := (*_func)(unsafe.Pointer(&pclntable[ftab[i+1].funcoff]))
+			f2name := "end"
+			if i+1 < nftab {
+				f2name = gofuncname(f2)
+			}
+			println("function symbol table not sorted by program counter:", hex(ftab[i].entry), gofuncname(f1), ">", hex(ftab[i+1].entry), f2name)
+			for j := 0; j <= i; j++ {
+				print("\t", hex(ftab[j].entry), " ", gofuncname((*_func)(unsafe.Pointer(&pclntable[ftab[j].funcoff]))))
+			}
+			gothrow("invalid runtime symbol table")
+		}
+	}
+
+	// The ftab ends with a half functab consisting only of
+	// 'entry', followed by a uint32 giving the pcln-relative
+	// offset of the file table.
+	sp = (*sliceStruct)(unsafe.Pointer(&filetab))
+	end := unsafe.Pointer(&ftab[nftab].funcoff) // just beyond ftab
+	fileoffset := *(*uint32)(end)
+	sp.array = unsafe.Pointer(&pclntable[fileoffset])
+	// length is in first element of array.
+	// set len to 1 so we can get first element.
+	sp.len = 1
+	sp.cap = 1
+	sp.len = int(filetab[0])
+	sp.cap = sp.len
+}
+
+// FuncForPC returns a *Func describing the function that contains the
+// given program counter address, or else nil.
+func FuncForPC(pc uintptr) *Func {
+	return (*Func)(unsafe.Pointer(findfunc(pc)))
+}
+
+// Name returns the name of the function.
+func (f *Func) Name() string {
+	return gofuncname(f.raw())
+}
+
+// Entry returns the entry address of the function.
+func (f *Func) Entry() uintptr {
+	return f.raw().entry
+}
+
+// FileLine returns the file name and line number of the
+// source code corresponding to the program counter pc.
+// The result will not be accurate if pc is not a program
+// counter within f.
+func (f *Func) FileLine(pc uintptr) (file string, line int) {
+	// Pass strict=false here, because anyone can call this function,
+	// and they might just be wrong about targetpc belonging to f.
+	line = int(funcline1(f.raw(), pc, &file, false))
+	return file, line
+}
+
+func findfunc(pc uintptr) *_func {
+	if len(ftab) == 0 {
+		return nil
+	}
+
+	if pc < ftab[0].entry || pc >= ftab[len(ftab)-1].entry {
+		return nil
+	}
+
+	// binary search to find func with entry <= pc.
+	lo := 0
+	nf := len(ftab) - 1 // last entry is sentinel
+	for nf > 0 {
+		n := nf / 2
+		f := &ftab[lo+n]
+		if f.entry <= pc && pc < ftab[lo+n+1].entry {
+			return (*_func)(unsafe.Pointer(&pclntable[f.funcoff]))
+		} else if pc < f.entry {
+			nf = n
+		} else {
+			lo += n + 1
+			nf -= n + 1
+		}
+	}
+
+	gothrow("findfunc: binary search failed")
+	return nil
+}
+
+func pcvalue(f *_func, off int32, targetpc uintptr, strict bool) int32 {
+	if off == 0 {
+		return -1
+	}
+	p := pclntable[off:]
+	pc := f.entry
+	val := int32(-1)
+	for {
+		var ok bool
+		p, ok = step(p, &pc, &val, pc == f.entry)
+		if !ok {
+			break
+		}
+		if targetpc < pc {
+			return val
+		}
+	}
+
+	// If there was a table, it should have covered all program counters.
+	// If not, something is wrong.
+	if panicking != 0 || !strict {
+		return -1
+	}
+
+	print("runtime: invalid pc-encoded table f=", gofuncname(f), " pc=", hex(pc), " targetpc=", hex(targetpc), " tab=", p, "\n")
+
+	p = pclntable[off:]
+	pc = f.entry
+	val = -1
+	for {
+		var ok bool
+		p, ok = step(p, &pc, &val, pc == f.entry)
+		if !ok {
+			break
+		}
+		print("\tvalue=", val, " until pc=", hex(pc), "\n")
+	}
+
+	gothrow("invalid runtime symbol table")
+	return -1
+}
+
+func funcname(f *_func) *byte {
+	if f == nil || f.nameoff == 0 {
+		return nil
+	}
+	return (*byte)(unsafe.Pointer(&pclntable[f.nameoff]))
+}
+
+func gofuncname(f *_func) string {
+	return gostringnocopy(funcname(f))
+}
+
+func funcline1(f *_func, targetpc uintptr, file *string, strict bool) int32 {
+	*file = "?"
+	fileno := int(pcvalue(f, f.pcfile, targetpc, strict))
+	line := pcvalue(f, f.pcln, targetpc, strict)
+	if fileno == -1 || line == -1 || fileno >= len(filetab) {
+		// print("looking for ", hex(targetpc), " in ", gofuncname(f), " got file=", fileno, " line=", lineno, "\n")
+		return 0
+	}
+	*file = gostringnocopy(&pclntable[filetab[fileno]])
+	return line
+}
+
+func funcline(f *_func, targetpc uintptr, file *string) int32 {
+	return funcline1(f, targetpc, file, true)
+}
+
+func funcspdelta(f *_func, targetpc uintptr) int32 {
+	x := pcvalue(f, f.pcsp, targetpc, true)
+	if x&(ptrSize-1) != 0 {
+		print("invalid spdelta ", hex(f.entry), " ", hex(targetpc), " ", hex(f.pcsp), " ", x, "\n")
+	}
+	return x
+}
+
+func pcdatavalue(f *_func, table int32, targetpc uintptr) int32 {
+	if table < 0 || table >= f.npcdata {
+		return -1
+	}
+	off := *(*int32)(add(unsafe.Pointer(&f.nfuncdata), unsafe.Sizeof(f.nfuncdata)+uintptr(table)*4))
+	return pcvalue(f, off, targetpc, true)
+}
+
+func funcdata(f *_func, i int32) unsafe.Pointer {
+	if i < 0 || i >= f.nfuncdata {
+		return nil
+	}
+	p := add(unsafe.Pointer(&f.nfuncdata), unsafe.Sizeof(f.nfuncdata)+uintptr(f.npcdata)*4)
+	if ptrSize == 8 && uintptr(p)&4 != 0 {
+		if uintptr(unsafe.Pointer(f))&4 != 0 {
+			println("runtime: misaligned func", f)
+		}
+		p = add(p, 4)
+	}
+	return *(*unsafe.Pointer)(add(p, uintptr(i)*ptrSize))
+}
+
+// step advances to the next pc, value pair in the encoded table.
+func step(p []byte, pc *uintptr, val *int32, first bool) (newp []byte, ok bool) {
+	p, uvdelta := readvarint(p)
+	if uvdelta == 0 && !first {
+		return nil, false
+	}
+	if uvdelta&1 != 0 {
+		uvdelta = ^(uvdelta >> 1)
+	} else {
+		uvdelta >>= 1
+	}
+	vdelta := int32(uvdelta)
+	p, pcdelta := readvarint(p)
+	*pc += uintptr(pcdelta * _PCQuantum)
+	*val += vdelta
+	return p, true
+}
+
+// readvarint reads a varint from p.
+func readvarint(p []byte) (newp []byte, val uint32) {
+	var v, shift uint32
+	for {
+		b := p[0]
+		p = p[1:]
+		v |= (uint32(b) & 0x7F) << shift
+		if b&0x80 == 0 {
+			break
+		}
+		shift += 7
+	}
+	return p, v
+}
diff --git a/src/pkg/runtime/symtab_test.go b/src/runtime/symtab_test.go
similarity index 100%
rename from src/pkg/runtime/symtab_test.go
rename to src/runtime/symtab_test.go
diff --git a/src/pkg/runtime/sys_arm.c b/src/runtime/sys_arm.c
similarity index 100%
rename from src/pkg/runtime/sys_arm.c
rename to src/runtime/sys_arm.c
diff --git a/src/runtime/sys_darwin_386.s b/src/runtime/sys_darwin_386.s
new file mode 100644
index 0000000..a961c71
--- /dev/null
+++ b/src/runtime/sys_darwin_386.s
@@ -0,0 +1,541 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// System calls and other sys.stuff for 386, Darwin
+// See http://fxr.watson.org/fxr/source/bsd/kern/syscalls.c?v=xnu-1228
+// or /usr/include/sys/syscall.h (on a Mac) for system call numbers.
+
+#include "zasm_GOOS_GOARCH.h"
+#include "textflag.h"
+
+// Exit the entire program (like C exit)
+TEXT runtime·exit(SB),NOSPLIT,$0
+	MOVL	$1, AX
+	INT	$0x80
+	MOVL	$0xf1, 0xf1  // crash
+	RET
+
+// Exit this OS thread (like pthread_exit, which eventually
+// calls __bsdthread_terminate).
+TEXT runtime·exit1(SB),NOSPLIT,$0
+	MOVL	$361, AX
+	INT	$0x80
+	JAE 2(PC)
+	MOVL	$0xf1, 0xf1  // crash
+	RET
+
+TEXT runtime·open(SB),NOSPLIT,$0
+	MOVL	$5, AX
+	INT	$0x80
+	MOVL	AX, ret+12(FP)
+	RET
+
+TEXT runtime·close(SB),NOSPLIT,$0
+	MOVL	$6, AX
+	INT	$0x80
+	MOVL	AX, ret+4(FP)
+	RET
+
+TEXT runtime·read(SB),NOSPLIT,$0
+	MOVL	$3, AX
+	INT	$0x80
+	MOVL	AX, ret+12(FP)
+	RET
+
+TEXT runtime·write(SB),NOSPLIT,$0
+	MOVL	$4, AX
+	INT	$0x80
+	MOVL	AX, ret+12(FP)
+	RET
+
+TEXT runtime·raise(SB),NOSPLIT,$16
+	MOVL	$20, AX // getpid
+	INT	$0x80
+	MOVL	AX, 4(SP)	// pid
+	MOVL	sig+0(FP), AX
+	MOVL	AX, 8(SP)	// signal
+	MOVL	$1, 12(SP)	// posix
+	MOVL	$37, AX // kill
+	INT	$0x80
+	RET
+
+TEXT runtime·mmap(SB),NOSPLIT,$0
+	MOVL	$197, AX
+	INT	$0x80
+	MOVL	AX, ret+24(FP)
+	RET
+
+TEXT runtime·madvise(SB),NOSPLIT,$0
+	MOVL	$75, AX
+	INT	$0x80
+	// ignore failure - maybe pages are locked
+	RET
+
+TEXT runtime·munmap(SB),NOSPLIT,$0
+	MOVL	$73, AX
+	INT	$0x80
+	JAE	2(PC)
+	MOVL	$0xf1, 0xf1  // crash
+	RET
+
+TEXT runtime·setitimer(SB),NOSPLIT,$0
+	MOVL	$83, AX
+	INT	$0x80
+	RET
+
+// OS X comm page time offsets
+// http://www.opensource.apple.com/source/xnu/xnu-1699.26.8/osfmk/i386/cpu_capabilities.h
+#define	cpu_capabilities	0x20
+#define	nt_tsc_base	0x50
+#define	nt_scale	0x58
+#define	nt_shift	0x5c
+#define	nt_ns_base	0x60
+#define	nt_generation	0x68
+#define	gtod_generation	0x6c
+#define	gtod_ns_base	0x70
+#define	gtod_sec_base	0x78
+
+// called from assembly
+// 64-bit unix nanoseconds returned in DX:AX.
+// I'd much rather write this in C but we need
+// assembly for the 96-bit multiply and RDTSC.
+TEXT runtime·now(SB),NOSPLIT,$40
+	MOVL	$0xffff0000, BP /* comm page base */
+	
+	// Test for slow CPU. If so, the math is completely
+	// different, and unimplemented here, so use the
+	// system call.
+	MOVL	cpu_capabilities(BP), AX
+	TESTL	$0x4000, AX
+	JNZ	systime
+
+	// Loop trying to take a consistent snapshot
+	// of the time parameters.
+timeloop:
+	MOVL	gtod_generation(BP), BX
+	TESTL	BX, BX
+	JZ	systime
+	MOVL	nt_generation(BP), CX
+	TESTL	CX, CX
+	JZ	timeloop
+	RDTSC
+	MOVL	nt_tsc_base(BP), SI
+	MOVL	(nt_tsc_base+4)(BP), DI
+	MOVL	SI, 0(SP)
+	MOVL	DI, 4(SP)
+	MOVL	nt_scale(BP), SI
+	MOVL	SI, 8(SP)
+	MOVL	nt_ns_base(BP), SI
+	MOVL	(nt_ns_base+4)(BP), DI
+	MOVL	SI, 12(SP)
+	MOVL	DI, 16(SP)
+	CMPL	nt_generation(BP), CX
+	JNE	timeloop
+	MOVL	gtod_ns_base(BP), SI
+	MOVL	(gtod_ns_base+4)(BP), DI
+	MOVL	SI, 20(SP)
+	MOVL	DI, 24(SP)
+	MOVL	gtod_sec_base(BP), SI
+	MOVL	(gtod_sec_base+4)(BP), DI
+	MOVL	SI, 28(SP)
+	MOVL	DI, 32(SP)
+	CMPL	gtod_generation(BP), BX
+	JNE	timeloop
+
+	// Gathered all the data we need. Compute time.
+	//	((tsc - nt_tsc_base) * nt_scale) >> 32 + nt_ns_base - gtod_ns_base + gtod_sec_base*1e9
+	// The multiply and shift extracts the top 64 bits of the 96-bit product.
+	SUBL	0(SP), AX // DX:AX = (tsc - nt_tsc_base)
+	SBBL	4(SP), DX
+
+	// We have x = tsc - nt_tsc_base - DX:AX to be
+	// multiplied by y = nt_scale = 8(SP), keeping the top 64 bits of the 96-bit product.
+	// x*y = (x&0xffffffff)*y + (x&0xffffffff00000000)*y
+	// (x*y)>>32 = ((x&0xffffffff)*y)>>32 + (x>>32)*y
+	MOVL	DX, CX // SI = (x&0xffffffff)*y >> 32
+	MOVL	$0, DX
+	MULL	8(SP)
+	MOVL	DX, SI
+
+	MOVL	CX, AX // DX:AX = (x>>32)*y
+	MOVL	$0, DX
+	MULL	8(SP)
+
+	ADDL	SI, AX	// DX:AX += (x&0xffffffff)*y >> 32
+	ADCL	$0, DX
+	
+	// DX:AX is now ((tsc - nt_tsc_base) * nt_scale) >> 32.
+	ADDL	12(SP), AX	// DX:AX += nt_ns_base
+	ADCL	16(SP), DX
+	SUBL	20(SP), AX	// DX:AX -= gtod_ns_base
+	SBBL	24(SP), DX
+	MOVL	AX, SI	// DI:SI = DX:AX
+	MOVL	DX, DI
+	MOVL	28(SP), AX	// DX:AX = gtod_sec_base*1e9
+	MOVL	32(SP), DX
+	MOVL	$1000000000, CX
+	MULL	CX
+	ADDL	SI, AX	// DX:AX += DI:SI
+	ADCL	DI, DX
+	RET
+
+systime:
+	// Fall back to system call (usually first call in this thread)
+	LEAL	12(SP), AX	// must be non-nil, unused
+	MOVL	AX, 4(SP)
+	MOVL	$0, 8(SP)	// time zone pointer
+	MOVL	$116, AX
+	INT	$0x80
+	// sec is in AX, usec in DX
+	// convert to DX:AX nsec
+	MOVL	DX, BX
+	MOVL	$1000000000, CX
+	MULL	CX
+	IMULL	$1000, BX
+	ADDL	BX, AX
+	ADCL	$0, DX
+	RET
+
+// func now() (sec int64, nsec int32)
+TEXT time·now(SB),NOSPLIT,$0
+	CALL	runtime·now(SB)
+	MOVL	$1000000000, CX
+	DIVL	CX
+	MOVL	AX, sec+0(FP)
+	MOVL	$0, sec+4(FP)
+	MOVL	DX, nsec+8(FP)
+	RET
+
+// int64 nanotime(void) so really
+// void nanotime(int64 *nsec)
+TEXT runtime·nanotime(SB),NOSPLIT,$0
+	CALL	runtime·now(SB)
+	MOVL	AX, ret_lo+0(FP)
+	MOVL	DX, ret_hi+4(FP)
+	RET
+
+TEXT runtime·sigprocmask(SB),NOSPLIT,$0
+	MOVL	$329, AX  // pthread_sigmask (on OS X, sigprocmask==entire process)
+	INT	$0x80
+	JAE	2(PC)
+	MOVL	$0xf1, 0xf1  // crash
+	RET
+
+TEXT runtime·sigaction(SB),NOSPLIT,$0
+	MOVL	$46, AX
+	INT	$0x80
+	JAE	2(PC)
+	MOVL	$0xf1, 0xf1  // crash
+	RET
+
+// Sigtramp's job is to call the actual signal handler.
+// It is called with the following arguments on the stack:
+//	0(FP)	"return address" - ignored
+//	4(FP)	actual handler
+//	8(FP)	signal number
+//	12(FP)	siginfo style
+//	16(FP)	siginfo
+//	20(FP)	context
+TEXT runtime·sigtramp(SB),NOSPLIT,$40
+	get_tls(CX)
+	
+	// check that g exists
+	MOVL	g(CX), DI
+	CMPL	DI, $0
+	JNE	6(PC)
+	MOVL	sig+8(FP), BX
+	MOVL	BX, 0(SP)
+	MOVL	$runtime·badsignal(SB), AX
+	CALL	AX
+	JMP 	sigtramp_ret
+
+	// save g
+	MOVL	DI, 20(SP)
+
+	// g = m->gsignal
+	MOVL	g_m(DI), BP
+	MOVL	m_gsignal(BP), BP
+	MOVL	BP, g(CX)
+
+	// copy arguments to sighandler
+	MOVL	sig+8(FP), BX
+	MOVL	BX, 0(SP)
+	MOVL	info+12(FP), BX
+	MOVL	BX, 4(SP)
+	MOVL	context+16(FP), BX
+	MOVL	BX, 8(SP)
+	MOVL	DI, 12(SP)
+
+	MOVL	handler+0(FP), BX
+	CALL	BX
+
+	// restore g
+	get_tls(CX)
+	MOVL	20(SP), DI
+	MOVL	DI, g(CX)
+
+sigtramp_ret:
+	// call sigreturn
+	MOVL	context+16(FP), CX
+	MOVL	style+4(FP), BX
+	MOVL	$0, 0(SP)	// "caller PC" - ignored
+	MOVL	CX, 4(SP)
+	MOVL	BX, 8(SP)
+	MOVL	$184, AX	// sigreturn(ucontext, infostyle)
+	INT	$0x80
+	MOVL	$0xf1, 0xf1  // crash
+	RET
+
+TEXT runtime·sigaltstack(SB),NOSPLIT,$0
+	MOVL	$53, AX
+	INT	$0x80
+	JAE	2(PC)
+	MOVL	$0xf1, 0xf1  // crash
+	RET
+
+TEXT runtime·usleep(SB),NOSPLIT,$32
+	MOVL	$0, DX
+	MOVL	usec+0(FP), AX
+	MOVL	$1000000, CX
+	DIVL	CX
+	MOVL	AX, 24(SP)  // sec
+	MOVL	DX, 28(SP)  // usec
+
+	// select(0, 0, 0, 0, &tv)
+	MOVL	$0, 0(SP)  // "return PC" - ignored
+	MOVL	$0, 4(SP)
+	MOVL	$0, 8(SP)
+	MOVL	$0, 12(SP)
+	MOVL	$0, 16(SP)
+	LEAL	24(SP), AX
+	MOVL	AX, 20(SP)
+	MOVL	$93, AX
+	INT	$0x80
+	RET
+
+// void bsdthread_create(void *stk, M *mp, G *gp, void (*fn)(void))
+// System call args are: func arg stack pthread flags.
+TEXT runtime·bsdthread_create(SB),NOSPLIT,$32
+	MOVL	$360, AX
+	// 0(SP) is where the caller PC would be; kernel skips it
+	MOVL	fn+12(FP), BX
+	MOVL	BX, 4(SP)	// func
+	MOVL	mm+4(FP), BX
+	MOVL	BX, 8(SP)	// arg
+	MOVL	stk+0(FP), BX
+	MOVL	BX, 12(SP)	// stack
+	MOVL	gg+8(FP), BX
+	MOVL	BX, 16(SP)	// pthread
+	MOVL	$0x1000000, 20(SP)	// flags = PTHREAD_START_CUSTOM
+	INT	$0x80
+	JAE	4(PC)
+	NEGL	AX
+	MOVL	AX, ret+16(FP)
+	RET
+	MOVL	$0, AX
+	MOVL	AX, ret+16(FP)
+	RET
+
+// The thread that bsdthread_create creates starts executing here,
+// because we registered this function using bsdthread_register
+// at startup.
+//	AX = "pthread" (= g)
+//	BX = mach thread port
+//	CX = "func" (= fn)
+//	DX = "arg" (= m)
+//	DI = stack top
+//	SI = flags (= 0x1000000)
+//	SP = stack - C_32_STK_ALIGN
+TEXT runtime·bsdthread_start(SB),NOSPLIT,$0
+	// set up ldt 7+id to point at m->tls.
+	// m->tls is at m+40.  newosproc left
+	// the m->id in tls[0].
+	LEAL	m_tls(DX), BP
+	MOVL	0(BP), DI
+	ADDL	$7, DI	// m0 is LDT#7. count up.
+	// setldt(tls#, &tls, sizeof tls)
+	PUSHAL	// save registers
+	PUSHL	$32	// sizeof tls
+	PUSHL	BP	// &tls
+	PUSHL	DI	// tls #
+	CALL	runtime·setldt(SB)
+	POPL	AX
+	POPL	AX
+	POPL	AX
+	POPAL
+
+	// Now segment is established.  Initialize m, g.
+	get_tls(BP)
+	MOVL	AX, g(BP)
+	MOVL	DX, g_m(AX)
+	MOVL	BX, m_procid(DX)	// m->procid = thread port (for debuggers)
+	CALL	runtime·stackcheck(SB)		// smashes AX
+	CALL	CX	// fn()
+	CALL	runtime·exit1(SB)
+	RET
+
+// void bsdthread_register(void)
+// registers callbacks for threadstart (see bsdthread_create above
+// and wqthread and pthsize (not used).  returns 0 on success.
+TEXT runtime·bsdthread_register(SB),NOSPLIT,$40
+	MOVL	$366, AX
+	// 0(SP) is where kernel expects caller PC; ignored
+	MOVL	$runtime·bsdthread_start(SB), 4(SP)	// threadstart
+	MOVL	$0, 8(SP)	// wqthread, not used by us
+	MOVL	$0, 12(SP)	// pthsize, not used by us
+	MOVL	$0, 16(SP)	// dummy_value [sic]
+	MOVL	$0, 20(SP)	// targetconc_ptr
+	MOVL	$0, 24(SP)	// dispatchqueue_offset
+	INT	$0x80
+	JAE	4(PC)
+	NEGL	AX
+	MOVL	AX, ret+0(FP)
+	RET
+	MOVL	$0, AX
+	MOVL	AX, ret+0(FP)
+	RET
+
+// Invoke Mach system call.
+// Assumes system call number in AX,
+// caller PC on stack, caller's caller PC next,
+// and then the system call arguments.
+//
+// Can be used for BSD too, but we don't,
+// because if you use this interface the BSD
+// system call numbers need an extra field
+// in the high 16 bits that seems to be the
+// argument count in bytes but is not always.
+// INT $0x80 works fine for those.
+TEXT runtime·sysenter(SB),NOSPLIT,$0
+	POPL	DX
+	MOVL	SP, CX
+	BYTE $0x0F; BYTE $0x34;  // SYSENTER
+	// returns to DX with SP set to CX
+
+TEXT runtime·mach_msg_trap(SB),NOSPLIT,$0
+	MOVL	$-31, AX
+	CALL	runtime·sysenter(SB)
+	MOVL	AX, ret+28(FP)
+	RET
+
+TEXT runtime·mach_reply_port(SB),NOSPLIT,$0
+	MOVL	$-26, AX
+	CALL	runtime·sysenter(SB)
+	MOVL	AX, ret+0(FP)
+	RET
+
+TEXT runtime·mach_task_self(SB),NOSPLIT,$0
+	MOVL	$-28, AX
+	CALL	runtime·sysenter(SB)
+	MOVL	AX, ret+0(FP)
+	RET
+
+// Mach provides trap versions of the semaphore ops,
+// instead of requiring the use of RPC.
+
+// uint32 mach_semaphore_wait(uint32)
+TEXT runtime·mach_semaphore_wait(SB),NOSPLIT,$0
+	MOVL	$-36, AX
+	CALL	runtime·sysenter(SB)
+	MOVL	AX, ret+4(FP)
+	RET
+
+// uint32 mach_semaphore_timedwait(uint32, uint32, uint32)
+TEXT runtime·mach_semaphore_timedwait(SB),NOSPLIT,$0
+	MOVL	$-38, AX
+	CALL	runtime·sysenter(SB)
+	MOVL	AX, ret+12(FP)
+	RET
+
+// uint32 mach_semaphore_signal(uint32)
+TEXT runtime·mach_semaphore_signal(SB),NOSPLIT,$0
+	MOVL	$-33, AX
+	CALL	runtime·sysenter(SB)
+	MOVL	AX, ret+4(FP)
+	RET
+
+// uint32 mach_semaphore_signal_all(uint32)
+TEXT runtime·mach_semaphore_signal_all(SB),NOSPLIT,$0
+	MOVL	$-34, AX
+	CALL	runtime·sysenter(SB)
+	MOVL	AX, ret+4(FP)
+	RET
+
+// setldt(int entry, int address, int limit)
+// entry and limit are ignored.
+TEXT runtime·setldt(SB),NOSPLIT,$32
+	MOVL	address+4(FP), BX	// aka base
+
+	/*
+	 * When linking against the system libraries,
+	 * we use its pthread_create and let it set up %gs
+	 * for us.  When we do that, the private storage
+	 * we get is not at 0(GS) but at 0x468(GS).
+	 * 8l rewrites 0(TLS) into 0x468(GS) for us.
+	 * To accommodate that rewrite, we translate the
+	 * address and limit here so that 0x468(GS) maps to 0(address).
+	 *
+	 * See cgo/gcc_darwin_386.c:/468 for the derivation
+	 * of the constant.
+	 */
+	SUBL	$0x468, BX
+
+	/*
+	 * Must set up as USER_CTHREAD segment because
+	 * Darwin forces that value into %gs for signal handlers,
+	 * and if we don't set one up, we'll get a recursive
+	 * fault trying to get into the signal handler.
+	 * Since we have to set one up anyway, it might as
+	 * well be the value we want.  So don't bother with
+	 * i386_set_ldt.
+	 */
+	MOVL	BX, 4(SP)
+	MOVL	$3, AX	// thread_fast_set_cthread_self - machdep call #3
+	INT	$0x82	// sic: 0x82, not 0x80, for machdep call
+
+	XORL	AX, AX
+	MOVW	GS, AX
+	RET
+
+TEXT runtime·sysctl(SB),NOSPLIT,$0
+	MOVL	$202, AX
+	INT	$0x80
+	JAE	4(PC)
+	NEGL	AX
+	MOVL	AX, ret+24(FP)
+	RET
+	MOVL	$0, AX
+	MOVL	AX, ret+24(FP)
+	RET
+
+// int32 runtime·kqueue(void);
+TEXT runtime·kqueue(SB),NOSPLIT,$0
+	MOVL	$362, AX
+	INT	$0x80
+	JAE	2(PC)
+	NEGL	AX
+	MOVL	AX, ret+0(FP)
+	RET
+
+// int32 runtime·kevent(int kq, Kevent *changelist, int nchanges, Kevent *eventlist, int nevents, Timespec *timeout);
+TEXT runtime·kevent(SB),NOSPLIT,$0
+	MOVL	$363, AX
+	INT	$0x80
+	JAE	2(PC)
+	NEGL	AX
+	MOVL	AX, ret+24(FP)
+	RET
+
+// int32 runtime·closeonexec(int32 fd);
+TEXT runtime·closeonexec(SB),NOSPLIT,$32
+	MOVL	$92, AX  // fcntl
+	// 0(SP) is where the caller PC would be; kernel skips it
+	MOVL	fd+0(FP), BX
+	MOVL	BX, 4(SP)  // fd
+	MOVL	$2, 8(SP)  // F_SETFD
+	MOVL	$1, 12(SP)  // FD_CLOEXEC
+	INT	$0x80
+	JAE	2(PC)
+	NEGL	AX
+	RET
diff --git a/src/runtime/sys_darwin_amd64.s b/src/runtime/sys_darwin_amd64.s
new file mode 100644
index 0000000..bd397d7
--- /dev/null
+++ b/src/runtime/sys_darwin_amd64.s
@@ -0,0 +1,505 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//
+// System calls and other sys.stuff for AMD64, Darwin
+// See http://fxr.watson.org/fxr/source/bsd/kern/syscalls.c?v=xnu-1228
+// or /usr/include/sys/syscall.h (on a Mac) for system call numbers.
+//
+// The low 24 bits are the system call number.
+// The high 8 bits specify the kind of system call: 1=Mach, 2=BSD, 3=Machine-Dependent.
+//
+
+#include "zasm_GOOS_GOARCH.h"
+#include "textflag.h"
+
+// Exit the entire program (like C exit)
+TEXT runtime·exit(SB),NOSPLIT,$0
+	MOVL	code+0(FP), DI		// arg 1 exit status
+	MOVL	$(0x2000000+1), AX	// syscall entry
+	SYSCALL
+	MOVL	$0xf1, 0xf1  // crash
+	RET
+
+// Exit this OS thread (like pthread_exit, which eventually
+// calls __bsdthread_terminate).
+TEXT runtime·exit1(SB),NOSPLIT,$0
+	MOVL	code+0(FP), DI		// arg 1 exit status
+	MOVL	$(0x2000000+361), AX	// syscall entry
+	SYSCALL
+	MOVL	$0xf1, 0xf1  // crash
+	RET
+
+TEXT runtime·open(SB),NOSPLIT,$0
+	MOVQ	name+0(FP), DI		// arg 1 pathname
+	MOVL	mode+8(FP), SI		// arg 2 flags
+	MOVL	perm+12(FP), DX		// arg 3 mode
+	MOVL	$(0x2000000+5), AX	// syscall entry
+	SYSCALL
+	MOVL	AX, ret+16(FP)
+	RET
+
+TEXT runtime·close(SB),NOSPLIT,$0
+	MOVL	fd+0(FP), DI		// arg 1 fd
+	MOVL	$(0x2000000+6), AX	// syscall entry
+	SYSCALL
+	MOVL	AX, ret+8(FP)
+	RET
+
+TEXT runtime·read(SB),NOSPLIT,$0
+	MOVL	fd+0(FP), DI		// arg 1 fd
+	MOVQ	p+8(FP), SI		// arg 2 buf
+	MOVL	n+16(FP), DX		// arg 3 count
+	MOVL	$(0x2000000+3), AX	// syscall entry
+	SYSCALL
+	MOVL	AX, ret+24(FP)
+	RET
+
+TEXT runtime·write(SB),NOSPLIT,$0
+	MOVQ	fd+0(FP), DI		// arg 1 fd
+	MOVQ	p+8(FP), SI		// arg 2 buf
+	MOVL	n+16(FP), DX		// arg 3 count
+	MOVL	$(0x2000000+4), AX	// syscall entry
+	SYSCALL
+	MOVL	AX, ret+24(FP)
+	RET
+
+TEXT runtime·raise(SB),NOSPLIT,$24
+	MOVL	$(0x2000000+20), AX // getpid
+	SYSCALL
+	MOVQ	AX, DI	// arg 1 - pid
+	MOVL	sig+0(FP), SI	// arg 2 - signal
+	MOVL	$1, DX	// arg 3 - posix
+	MOVL	$(0x2000000+37), AX // kill
+	SYSCALL
+	RET
+
+TEXT runtime·setitimer(SB), NOSPLIT, $0
+	MOVL	mode+0(FP), DI
+	MOVQ	new+8(FP), SI
+	MOVQ	old+16(FP), DX
+	MOVL	$(0x2000000+83), AX	// syscall entry
+	SYSCALL
+	RET
+
+TEXT runtime·madvise(SB), NOSPLIT, $0
+	MOVQ	addr+0(FP), DI		// arg 1 addr
+	MOVQ	n+8(FP), SI		// arg 2 len
+	MOVL	flags+16(FP), DX		// arg 3 advice
+	MOVL	$(0x2000000+75), AX	// syscall entry madvise
+	SYSCALL
+	// ignore failure - maybe pages are locked
+	RET
+
+// OS X comm page time offsets
+// http://www.opensource.apple.com/source/xnu/xnu-1699.26.8/osfmk/i386/cpu_capabilities.h
+#define	nt_tsc_base	0x50
+#define	nt_scale	0x58
+#define	nt_shift	0x5c
+#define	nt_ns_base	0x60
+#define	nt_generation	0x68
+#define	gtod_generation	0x6c
+#define	gtod_ns_base	0x70
+#define	gtod_sec_base	0x78
+
+TEXT nanotime<>(SB), NOSPLIT, $32
+	MOVQ	$0x7fffffe00000, BP	/* comm page base */
+	// Loop trying to take a consistent snapshot
+	// of the time parameters.
+timeloop:
+	MOVL	gtod_generation(BP), R8
+	TESTL	R8, R8
+	JZ	systime
+	MOVL	nt_generation(BP), R9
+	TESTL	R9, R9
+	JZ	timeloop
+	RDTSC
+	MOVQ	nt_tsc_base(BP), R10
+	MOVL	nt_scale(BP), R11
+	MOVQ	nt_ns_base(BP), R12
+	CMPL	nt_generation(BP), R9
+	JNE	timeloop
+	MOVQ	gtod_ns_base(BP), R13
+	MOVQ	gtod_sec_base(BP), R14
+	CMPL	gtod_generation(BP), R8
+	JNE	timeloop
+
+	// Gathered all the data we need. Compute time.
+	//	((tsc - nt_tsc_base) * nt_scale) >> 32 + nt_ns_base - gtod_ns_base + gtod_sec_base*1e9
+	// The multiply and shift extracts the top 64 bits of the 96-bit product.
+	SHLQ	$32, DX
+	ADDQ	DX, AX
+	SUBQ	R10, AX
+	MULQ	R11
+	SHRQ	$32, AX:DX
+	ADDQ	R12, AX
+	SUBQ	R13, AX
+	IMULQ	$1000000000, R14
+	ADDQ	R14, AX
+	RET
+
+systime:
+	// Fall back to system call (usually first call in this thread).
+	MOVQ	SP, DI	// must be non-nil, unused
+	MOVQ	$0, SI
+	MOVL	$(0x2000000+116), AX
+	SYSCALL
+	// sec is in AX, usec in DX
+	// return nsec in AX
+	IMULQ	$1000000000, AX
+	IMULQ	$1000, DX
+	ADDQ	DX, AX
+	RET
+
+TEXT runtime·nanotime(SB),NOSPLIT,$0-8
+	CALL	nanotime<>(SB)
+	MOVQ	AX, ret+0(FP)
+	RET
+
+// func now() (sec int64, nsec int32)
+TEXT time·now(SB),NOSPLIT,$0-12
+	CALL	nanotime<>(SB)
+
+	// generated code for
+	//	func f(x uint64) (uint64, uint64) { return x/1000000000, x%100000000 }
+	// adapted to reduce duplication
+	MOVQ	AX, CX
+	MOVQ	$1360296554856532783, AX
+	MULQ	CX
+	ADDQ	CX, DX
+	RCRQ	$1, DX
+	SHRQ	$29, DX
+	MOVQ	DX, sec+0(FP)
+	IMULQ	$1000000000, DX
+	SUBQ	DX, CX
+	MOVL	CX, nsec+8(FP)
+	RET
+
+TEXT runtime·sigprocmask(SB),NOSPLIT,$0
+	MOVL	sig+0(FP), DI
+	MOVQ	new+8(FP), SI
+	MOVQ	old+16(FP), DX
+	MOVL	$(0x2000000+329), AX  // pthread_sigmask (on OS X, sigprocmask==entire process)
+	SYSCALL
+	JCC	2(PC)
+	MOVL	$0xf1, 0xf1  // crash
+	RET
+
+TEXT runtime·sigaction(SB),NOSPLIT,$0
+	MOVL	mode+0(FP), DI		// arg 1 sig
+	MOVQ	new+8(FP), SI		// arg 2 act
+	MOVQ	old+16(FP), DX		// arg 3 oact
+	MOVQ	old+16(FP), CX		// arg 3 oact
+	MOVQ	old+16(FP), R10		// arg 3 oact
+	MOVL	$(0x2000000+46), AX	// syscall entry
+	SYSCALL
+	JCC	2(PC)
+	MOVL	$0xf1, 0xf1  // crash
+	RET
+
+TEXT runtime·sigtramp(SB),NOSPLIT,$64
+	get_tls(BX)
+
+	MOVQ	R8, 32(SP)	// save ucontext
+	MOVQ	SI, 40(SP)	// save infostyle
+
+	// check that g exists
+	MOVQ	g(BX), R10
+	CMPQ	R10, $0
+	JNE	5(PC)
+	MOVL	DX, 0(SP)
+	MOVQ	$runtime·badsignal(SB), AX
+	CALL	AX
+	JMP 	sigtramp_ret
+
+	// save g
+	MOVQ	R10, 48(SP)
+
+	// g = m->gsignal
+	MOVQ	g_m(R10), BP
+	MOVQ	m_gsignal(BP), BP
+	MOVQ	BP, g(BX)
+
+	MOVL	DX, 0(SP)
+	MOVQ	CX, 8(SP)
+	MOVQ	R8, 16(SP)
+	MOVQ	R10, 24(SP)
+
+	CALL	DI
+
+	// restore g
+	get_tls(BX)
+	MOVQ	48(SP), R10
+	MOVQ	R10, g(BX)
+
+sigtramp_ret:
+	// call sigreturn
+	MOVL	$(0x2000000+184), AX	// sigreturn(ucontext, infostyle)
+	MOVQ	32(SP), DI	// saved ucontext
+	MOVQ	40(SP), SI	// saved infostyle
+	SYSCALL
+	INT $3	// not reached
+
+TEXT runtime·mmap(SB),NOSPLIT,$0
+	MOVQ	addr+0(FP), DI		// arg 1 addr
+	MOVQ	n+8(FP), SI		// arg 2 len
+	MOVL	prot+16(FP), DX		// arg 3 prot
+	MOVL	flags+20(FP), R10		// arg 4 flags
+	MOVL	fd+24(FP), R8		// arg 5 fid
+	MOVL	off+28(FP), R9		// arg 6 offset
+	MOVL	$(0x2000000+197), AX	// syscall entry
+	SYSCALL
+	MOVQ	AX, ret+32(FP)
+	RET
+
+TEXT runtime·munmap(SB),NOSPLIT,$0
+	MOVQ	addr+0(FP), DI		// arg 1 addr
+	MOVQ	n+8(FP), SI		// arg 2 len
+	MOVL	$(0x2000000+73), AX	// syscall entry
+	SYSCALL
+	JCC	2(PC)
+	MOVL	$0xf1, 0xf1  // crash
+	RET
+
+TEXT runtime·sigaltstack(SB),NOSPLIT,$0
+	MOVQ	new+8(SP), DI
+	MOVQ	old+16(SP), SI
+	MOVQ	$(0x2000000+53), AX
+	SYSCALL
+	JCC	2(PC)
+	MOVL	$0xf1, 0xf1  // crash
+	RET
+
+TEXT runtime·usleep(SB),NOSPLIT,$16
+	MOVL	$0, DX
+	MOVL	usec+0(FP), AX
+	MOVL	$1000000, CX
+	DIVL	CX
+	MOVQ	AX, 0(SP)  // sec
+	MOVL	DX, 8(SP)  // usec
+
+	// select(0, 0, 0, 0, &tv)
+	MOVL	$0, DI
+	MOVL	$0, SI
+	MOVL	$0, DX
+	MOVL	$0, R10
+	MOVQ	SP, R8
+	MOVL	$(0x2000000+93), AX
+	SYSCALL
+	RET
+
+// void bsdthread_create(void *stk, M *mp, G *gp, void (*fn)(void))
+TEXT runtime·bsdthread_create(SB),NOSPLIT,$0
+	// Set up arguments to bsdthread_create system call.
+	// The ones in quotes pass through to the thread callback
+	// uninterpreted, so we can put whatever we want there.
+	MOVQ	fn+32(SP), DI	// "func"
+	MOVQ	mm+16(SP), SI	// "arg"
+	MOVQ	stk+8(SP), DX	// stack
+	MOVQ	gg+24(SP), R10	// "pthread"
+	MOVQ	$0x01000000, R8	// flags = PTHREAD_START_CUSTOM
+	MOVQ	$0, R9	// paranoia
+	MOVQ	$(0x2000000+360), AX	// bsdthread_create
+	SYSCALL
+	JCC 4(PC)
+	NEGQ	AX
+	MOVL	AX, ret+32(FP)
+	RET
+	MOVL	$0, AX
+	MOVL	AX, ret+32(FP)
+	RET
+
+// The thread that bsdthread_create creates starts executing here,
+// because we registered this function using bsdthread_register
+// at startup.
+//	DI = "pthread"
+//	SI = mach thread port
+//	DX = "func" (= fn)
+//	CX = "arg" (= m)
+//	R8 = stack
+//	R9 = flags (= 0)
+//	SP = stack - C_64_REDZONE_LEN (= stack - 128)
+TEXT runtime·bsdthread_start(SB),NOSPLIT,$0
+	MOVQ	R8, SP		// empirically, SP is very wrong but R8 is right
+
+	PUSHQ	DX
+	PUSHQ	CX
+	PUSHQ	SI
+
+	// set up thread local storage pointing at m->tls.
+	LEAQ	m_tls(CX), DI
+	CALL	runtime·settls(SB)
+
+	POPQ	SI
+	POPQ	CX
+	POPQ	DX
+
+	get_tls(BX)
+	MOVQ	SI, m_procid(CX)	// thread port is m->procid
+	MOVQ	m_g0(CX), AX
+	MOVQ	AX, g(BX)
+	MOVQ	CX, g_m(AX)
+	CALL	runtime·stackcheck(SB)	// smashes AX, CX
+	CALL	DX	// fn
+	CALL	runtime·exit1(SB)
+	RET
+
+// void bsdthread_register(void)
+// registers callbacks for threadstart (see bsdthread_create above
+// and wqthread and pthsize (not used).  returns 0 on success.
+TEXT runtime·bsdthread_register(SB),NOSPLIT,$0
+	MOVQ	$runtime·bsdthread_start(SB), DI	// threadstart
+	MOVQ	$0, SI	// wqthread, not used by us
+	MOVQ	$0, DX	// pthsize, not used by us
+	MOVQ	$0, R10	// dummy_value [sic]
+	MOVQ	$0, R8	// targetconc_ptr
+	MOVQ	$0, R9	// dispatchqueue_offset
+	MOVQ	$(0x2000000+366), AX	// bsdthread_register
+	SYSCALL
+	JCC 4(PC)
+	NEGQ	AX
+	MOVL	AX, ret+0(FP)
+	RET
+	MOVL	$0, AX
+	MOVL	AX, ret+0(FP)
+	RET
+
+// Mach system calls use 0x1000000 instead of the BSD's 0x2000000.
+
+// uint32 mach_msg_trap(void*, uint32, uint32, uint32, uint32, uint32, uint32)
+TEXT runtime·mach_msg_trap(SB),NOSPLIT,$0
+	MOVQ	h+0(FP), DI
+	MOVL	op+8(FP), SI
+	MOVL	send_size+12(FP), DX
+	MOVL	rcv_size+16(FP), R10
+	MOVL	rcv_name+20(FP), R8
+	MOVL	timeout+24(FP), R9
+	MOVL	notify+28(FP), R11
+	PUSHQ	R11	// seventh arg, on stack
+	MOVL	$(0x1000000+31), AX	// mach_msg_trap
+	SYSCALL
+	POPQ	R11
+	MOVL	AX, ret+32(FP)
+	RET
+
+TEXT runtime·mach_task_self(SB),NOSPLIT,$0
+	MOVL	$(0x1000000+28), AX	// task_self_trap
+	SYSCALL
+	MOVL	AX, ret+0(FP)
+	RET
+
+TEXT runtime·mach_thread_self(SB),NOSPLIT,$0
+	MOVL	$(0x1000000+27), AX	// thread_self_trap
+	SYSCALL
+	MOVL	AX, ret+0(FP)
+	RET
+
+TEXT runtime·mach_reply_port(SB),NOSPLIT,$0
+	MOVL	$(0x1000000+26), AX	// mach_reply_port
+	SYSCALL
+	MOVL	AX, ret+0(FP)
+	RET
+
+// Mach provides trap versions of the semaphore ops,
+// instead of requiring the use of RPC.
+
+// uint32 mach_semaphore_wait(uint32)
+TEXT runtime·mach_semaphore_wait(SB),NOSPLIT,$0
+	MOVL	sema+0(FP), DI
+	MOVL	$(0x1000000+36), AX	// semaphore_wait_trap
+	SYSCALL
+	MOVL	AX, ret+8(FP)
+	RET
+
+// uint32 mach_semaphore_timedwait(uint32, uint32, uint32)
+TEXT runtime·mach_semaphore_timedwait(SB),NOSPLIT,$0
+	MOVL	sema+0(FP), DI
+	MOVL	sec+4(FP), SI
+	MOVL	nsec+8(FP), DX
+	MOVL	$(0x1000000+38), AX	// semaphore_timedwait_trap
+	SYSCALL
+	MOVL	AX, ret+16(FP)
+	RET
+
+// uint32 mach_semaphore_signal(uint32)
+TEXT runtime·mach_semaphore_signal(SB),NOSPLIT,$0
+	MOVL	sema+0(FP), DI
+	MOVL	$(0x1000000+33), AX	// semaphore_signal_trap
+	SYSCALL
+	MOVL	AX, ret+8(FP)
+	RET
+
+// uint32 mach_semaphore_signal_all(uint32)
+TEXT runtime·mach_semaphore_signal_all(SB),NOSPLIT,$0
+	MOVL	sema+0(FP), DI
+	MOVL	$(0x1000000+34), AX	// semaphore_signal_all_trap
+	SYSCALL
+	MOVL	AX, ret+8(FP)
+	RET
+
+// set tls base to DI
+TEXT runtime·settls(SB),NOSPLIT,$32
+	/*
+	* Same as in sys_darwin_386.s:/ugliness, different constant.
+	* See cgo/gcc_darwin_amd64.c for the derivation
+	* of the constant.
+	*/
+	SUBQ $0x8a0, DI
+
+	MOVL	$(0x3000000+3), AX	// thread_fast_set_cthread_self - machdep call #3
+	SYSCALL
+	RET
+
+TEXT runtime·sysctl(SB),NOSPLIT,$0
+	MOVQ	mib+0(FP), DI
+	MOVL	miblen+8(FP), SI
+	MOVQ	out+16(FP), DX
+	MOVQ	size+24(FP), R10
+	MOVQ	dst+32(FP), R8
+	MOVQ	ndst+40(FP), R9
+	MOVL	$(0x2000000+202), AX	// syscall entry
+	SYSCALL
+	JCC 4(PC)
+	NEGQ	AX
+	MOVL	AX, ret+48(FP)
+	RET
+	MOVL	$0, AX
+	MOVL	AX, ret+48(FP)
+	RET
+
+// int32 runtime·kqueue(void);
+TEXT runtime·kqueue(SB),NOSPLIT,$0
+	MOVQ    $0, DI
+	MOVQ    $0, SI
+	MOVQ    $0, DX
+	MOVL	$(0x2000000+362), AX
+	SYSCALL
+	JCC	2(PC)
+	NEGQ	AX
+	MOVL	AX, ret+0(FP)
+	RET
+
+// int32 runtime·kevent(int kq, Kevent *changelist, int nchanges, Kevent *eventlist, int nevents, Timespec *timeout);
+TEXT runtime·kevent(SB),NOSPLIT,$0
+	MOVL    fd+0(FP), DI
+	MOVQ    ev1+8(FP), SI
+	MOVL    nev1+16(FP), DX
+	MOVQ    ev2+24(FP), R10
+	MOVL    nev2+32(FP), R8
+	MOVQ    ts+40(FP), R9
+	MOVL	$(0x2000000+363), AX
+	SYSCALL
+	JCC	2(PC)
+	NEGQ	AX
+	MOVL	AX, ret+48(FP)
+	RET
+
+// void runtime·closeonexec(int32 fd);
+TEXT runtime·closeonexec(SB),NOSPLIT,$0
+	MOVL    fd+0(FP), DI  // fd
+	MOVQ    $2, SI  // F_SETFD
+	MOVQ    $1, DX  // FD_CLOEXEC
+	MOVL	$(0x2000000+92), AX  // fcntl
+	SYSCALL
+	RET
diff --git a/src/runtime/sys_dragonfly_386.s b/src/runtime/sys_dragonfly_386.s
new file mode 100644
index 0000000..161eaec
--- /dev/null
+++ b/src/runtime/sys_dragonfly_386.s
@@ -0,0 +1,381 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+//
+// System calls and other sys.stuff for 386, FreeBSD
+// /usr/src/sys/kern/syscalls.master for syscall numbers.
+//
+
+#include "zasm_GOOS_GOARCH.h"
+#include "textflag.h"
+	
+TEXT runtime·sys_umtx_sleep(SB),NOSPLIT,$-4
+	MOVL	$469, AX		// umtx_sleep
+	INT	$0x80
+	JAE	2(PC)
+	NEGL	AX
+	MOVL	AX, ret+12(FP)
+	RET
+
+TEXT runtime·sys_umtx_wakeup(SB),NOSPLIT,$-4
+	MOVL	$470, AX		// umtx_wakeup
+	INT	$0x80
+	JAE	2(PC)
+	NEGL	AX
+	MOVL	AX, ret+8(FP)
+	RET
+
+TEXT runtime·lwp_create(SB),NOSPLIT,$-4
+	MOVL	$495, AX		// lwp_create
+	INT	$0x80
+	MOVL	AX, ret+4(FP)
+	RET
+
+TEXT runtime·lwp_start(SB),NOSPLIT,$0
+
+	// Set GS to point at m->tls.
+	MOVL	mm+0(FP), BX
+	MOVL	m_g0(BX), DX
+	LEAL	m_tls(BX), BP
+	PUSHAL
+	PUSHL	BP
+	CALL	runtime·settls(SB)
+	POPL	AX
+	POPAL
+	
+	// Now segment is established.  Initialize m, g.
+	get_tls(CX)
+	MOVL	BX, g_m(DX)
+	MOVL	DX, g(CX)
+
+	CALL	runtime·stackcheck(SB)	// smashes AX, CX
+	MOVL	0(DX), DX		// paranoia; check they are not nil
+	MOVL	0(BX), BX
+
+	// More paranoia; check that stack splitting code works.
+	PUSHAL
+	CALL	runtime·emptyfunc(SB)
+	POPAL
+
+	CALL	runtime·mstart(SB)
+
+	CALL	runtime·exit1(SB)
+	MOVL	$0x1234, 0x1005
+	RET
+
+// Exit the entire program (like C exit)
+TEXT runtime·exit(SB),NOSPLIT,$-4
+	MOVL	$1, AX
+	INT	$0x80
+	MOVL	$0xf1, 0xf1  // crash
+	RET
+
+TEXT runtime·exit1(SB),NOSPLIT,$16
+	MOVL	$0, 0(SP)		// syscall gap
+	MOVL	$0x10000, 4(SP)		// arg 1 - how (EXTEXIT_LWP)
+	MOVL	$0, 8(SP)		// arg 2 - status
+	MOVL	$0, 12(SP)		// arg 3 - addr
+	MOVL	$494, AX
+	INT	$0x80
+	JAE	2(PC)
+	MOVL	$0xf1, 0xf1  // crash
+	RET
+
+TEXT runtime·open(SB),NOSPLIT,$-4
+	MOVL	$5, AX
+	INT	$0x80
+	MOVL	AX, ret+12(FP)
+	RET
+
+TEXT runtime·close(SB),NOSPLIT,$-4
+	MOVL	$6, AX
+	INT	$0x80
+	MOVL	AX, ret+4(FP)
+	RET
+
+TEXT runtime·read(SB),NOSPLIT,$-4
+	MOVL	$3, AX
+	INT	$0x80
+	MOVL	AX, ret+12(FP)
+	RET
+
+TEXT runtime·write(SB),NOSPLIT,$-4
+	MOVL	$4, AX
+	INT	$0x80
+	MOVL	AX, ret+12(FP)
+	RET
+
+TEXT runtime·getrlimit(SB),NOSPLIT,$-4
+	MOVL	$194, AX
+	INT	$0x80
+	MOVL	AX, ret+8(FP)
+	RET
+
+TEXT runtime·raise(SB),NOSPLIT,$16
+	MOVL	$496, AX		// lwp_gettid
+	INT	$0x80
+	MOVL	$0, 0(SP)
+	MOVL	$-1, 4(SP)		// arg 1 - pid
+	MOVL	AX, 8(SP)		// arg 2 - tid
+	MOVL	sig+0(FP), AX
+	MOVL	AX, 8(SP)		// arg 3 - signum
+	MOVL	$497, AX		// lwp_kill
+	INT	$0x80
+	RET
+
+TEXT runtime·mmap(SB),NOSPLIT,$36
+	LEAL	addr+0(FP), SI
+	LEAL	4(SP), DI
+	CLD
+	MOVSL				// arg 1 - addr
+	MOVSL				// arg 2 - len
+	MOVSL				// arg 3 - prot
+	MOVSL				// arg 4 - flags
+	MOVSL				// arg 5 - fd
+	MOVL	$0, AX
+	STOSL				// arg 6 - pad
+	MOVSL				// arg 7 - offset
+	MOVL	$0, AX			// top 32 bits of file offset
+	STOSL
+	MOVL	$197, AX		// sys_mmap
+	INT	$0x80
+	MOVL	AX, ret+24(FP)
+	RET
+
+TEXT runtime·munmap(SB),NOSPLIT,$-4
+	MOVL	$73, AX
+	INT	$0x80
+	JAE	2(PC)
+	MOVL	$0xf1, 0xf1  // crash
+	RET
+
+TEXT runtime·madvise(SB),NOSPLIT,$-4
+	MOVL	$75, AX	// madvise
+	INT	$0x80
+	// ignore failure - maybe pages are locked
+	RET
+
+TEXT runtime·setitimer(SB), NOSPLIT, $-4
+	MOVL	$83, AX
+	INT	$0x80
+	RET
+
+// func now() (sec int64, nsec int32)
+TEXT time·now(SB), NOSPLIT, $32
+	MOVL	$232, AX
+	LEAL	12(SP), BX
+	MOVL	$0, 4(SP)	// CLOCK_REALTIME
+	MOVL	BX, 8(SP)
+	INT	$0x80
+	MOVL	12(SP), AX	// sec
+	MOVL	16(SP), BX	// nsec
+
+	// sec is in AX, nsec in BX
+	MOVL	AX, sec+0(FP)
+	MOVL	$0, sec+4(FP)
+	MOVL	BX, nsec+8(FP)
+	RET
+
+// int64 nanotime(void) so really
+// void nanotime(int64 *nsec)
+TEXT runtime·nanotime(SB), NOSPLIT, $32
+	MOVL	$232, AX
+	LEAL	12(SP), BX
+	MOVL	$4, 4(SP)	// CLOCK_MONOTONIC
+	MOVL	BX, 8(SP)
+	INT	$0x80
+	MOVL	12(SP), AX	// sec
+	MOVL	16(SP), BX	// nsec
+
+	// sec is in AX, nsec in BX
+	// convert to DX:AX nsec
+	MOVL	$1000000000, CX
+	MULL	CX
+	ADDL	BX, AX
+	ADCL	$0, DX
+
+	MOVL	AX, ret_lo+0(FP)
+	MOVL	DX, ret_hi+4(FP)
+	RET
+
+
+TEXT runtime·sigaction(SB),NOSPLIT,$-4
+	MOVL	$342, AX
+	INT	$0x80
+	JAE	2(PC)
+	MOVL	$0xf1, 0xf1  // crash
+	RET
+
+TEXT runtime·sigtramp(SB),NOSPLIT,$44
+	get_tls(CX)
+
+	// check that g exists
+	MOVL	g(CX), DI
+	CMPL	DI, $0
+	JNE	6(PC)
+	MOVL	signo+0(FP), BX
+	MOVL	BX, 0(SP)
+	MOVL	$runtime·badsignal(SB), AX
+	CALL	AX
+	JMP 	sigtramp_ret
+
+	// save g
+	MOVL	DI, 20(SP)
+	
+	// g = m->gsignal
+	MOVL	g_m(DI), BX
+	MOVL	m_gsignal(BX), BX
+	MOVL	BX, g(CX)
+
+	// copy arguments for call to sighandler
+	MOVL	signo+0(FP), BX
+	MOVL	BX, 0(SP)
+	MOVL	info+4(FP), BX
+	MOVL	BX, 4(SP)
+	MOVL	context+8(FP), BX
+	MOVL	BX, 8(SP)
+	MOVL	DI, 12(SP)
+
+	CALL	runtime·sighandler(SB)
+
+	// restore g
+	get_tls(CX)
+	MOVL	20(SP), BX
+	MOVL	BX, g(CX)
+
+sigtramp_ret:
+	// call sigreturn
+	MOVL	context+8(FP), AX
+	MOVL	$0, 0(SP)	// syscall gap
+	MOVL	AX, 4(SP)
+	MOVL	$344, AX	// sigreturn(ucontext)
+	INT	$0x80
+	MOVL	$0xf1, 0xf1  // crash
+	RET
+
+TEXT runtime·sigaltstack(SB),NOSPLIT,$0
+	MOVL	$53, AX
+	INT	$0x80
+	JAE	2(PC)
+	MOVL	$0xf1, 0xf1  // crash
+	RET
+
+TEXT runtime·usleep(SB),NOSPLIT,$20
+	MOVL	$0, DX
+	MOVL	usec+0(FP), AX
+	MOVL	$1000000, CX
+	DIVL	CX
+	MOVL	AX, 12(SP)		// tv_sec
+	MOVL	$1000, AX
+	MULL	DX
+	MOVL	AX, 16(SP)		// tv_nsec
+
+	MOVL	$0, 0(SP)
+	LEAL	12(SP), AX
+	MOVL	AX, 4(SP)		// arg 1 - rqtp
+	MOVL	$0, 8(SP)		// arg 2 - rmtp
+	MOVL	$240, AX		// sys_nanosleep
+	INT	$0x80
+	RET
+
+TEXT runtime·setldt(SB),NOSPLIT,$4
+	// Under DragonFly we set the GS base instead of messing with the LDT.
+	MOVL	tls0+4(FP), AX
+	MOVL	AX, 0(SP)
+	CALL	runtime·settls(SB)
+	RET
+
+TEXT runtime·settls(SB),NOSPLIT,$24
+	// adjust for ELF: wants to use -8(GS) and -4(GS) for g and m
+	MOVL	tlsbase+0(FP), CX
+	ADDL	$8, CX
+
+	// Set up a struct tls_info - a size of -1 maps the whole address
+	// space and is required for direct-tls access of variable data
+	// via negative offsets.
+	LEAL	16(SP), BX
+	MOVL	CX, 16(SP)		// base
+	MOVL	$-1, 20(SP)		// size
+
+	// set_tls_area returns the descriptor that needs to be loaded into GS.
+	MOVL	$0, 0(SP)		// syscall gap
+	MOVL	$0, 4(SP)		// arg 1 - which
+	MOVL	BX, 8(SP)		// arg 2 - tls_info
+	MOVL	$8, 12(SP)		// arg 3 - infosize
+	MOVL    $472, AX                // set_tls_area
+	INT     $0x80
+	JCC     2(PC)
+	MOVL    $0xf1, 0xf1             // crash
+	MOVW	AX, GS
+	RET
+
+TEXT runtime·sysctl(SB),NOSPLIT,$28
+	LEAL	mib+0(FP), SI
+	LEAL	4(SP), DI
+	CLD
+	MOVSL				// arg 1 - name
+	MOVSL				// arg 2 - namelen
+	MOVSL				// arg 3 - oldp
+	MOVSL				// arg 4 - oldlenp
+	MOVSL				// arg 5 - newp
+	MOVSL				// arg 6 - newlen
+	MOVL	$202, AX		// sys___sysctl
+	INT	$0x80
+	JCC	4(PC)
+	NEGL	AX
+	MOVL	AX, ret+24(FP)
+	RET
+	MOVL	$0, AX
+	MOVL	AX, ret+24(FP)
+	RET
+
+TEXT runtime·osyield(SB),NOSPLIT,$-4
+	MOVL	$331, AX		// sys_sched_yield
+	INT	$0x80
+	RET
+
+TEXT runtime·sigprocmask(SB),NOSPLIT,$16
+	MOVL	$0, 0(SP)		// syscall gap
+	MOVL	$3, 4(SP)		// arg 1 - how (SIG_SETMASK)
+	MOVL	new+0(FP), AX
+	MOVL	AX, 8(SP)		// arg 2 - set
+	MOVL	old+4(FP), AX
+	MOVL	AX, 12(SP)		// arg 3 - oset
+	MOVL	$340, AX		// sys_sigprocmask
+	INT	$0x80
+	JAE	2(PC)
+	MOVL	$0xf1, 0xf1  // crash
+	RET
+
+// int32 runtime·kqueue(void);
+TEXT runtime·kqueue(SB),NOSPLIT,$0
+	MOVL	$362, AX
+	INT	$0x80
+	JAE	2(PC)
+	NEGL	AX
+	MOVL	AX, ret+0(FP)
+	RET
+
+// int32 runtime·kevent(int kq, Kevent *changelist, int nchanges, Kevent *eventlist, int nevents, Timespec *timeout);
+TEXT runtime·kevent(SB),NOSPLIT,$0
+	MOVL	$363, AX
+	INT	$0x80
+	JAE	2(PC)
+	NEGL	AX
+	MOVL	AX, ret+24(FP)
+	RET
+
+// int32 runtime·closeonexec(int32 fd);
+TEXT runtime·closeonexec(SB),NOSPLIT,$32
+	MOVL	$92, AX		// fcntl
+	// 0(SP) is where the caller PC would be; kernel skips it
+	MOVL	fd+0(FP), BX
+	MOVL	BX, 4(SP)	// fd
+	MOVL	$2, 8(SP)	// F_SETFD
+	MOVL	$1, 12(SP)	// FD_CLOEXEC
+	INT	$0x80
+	JAE	2(PC)
+	NEGL	AX
+	RET
+
+GLOBL runtime·tlsoffset(SB),NOPTR,$4
diff --git a/src/runtime/sys_dragonfly_amd64.s b/src/runtime/sys_dragonfly_amd64.s
new file mode 100644
index 0000000..2c75601
--- /dev/null
+++ b/src/runtime/sys_dragonfly_amd64.s
@@ -0,0 +1,344 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+//
+// System calls and other sys.stuff for AMD64, FreeBSD
+// /usr/src/sys/kern/syscalls.master for syscall numbers.
+//
+
+#include "zasm_GOOS_GOARCH.h"
+#include "textflag.h"
+	
+TEXT runtime·sys_umtx_sleep(SB),NOSPLIT,$0
+	MOVQ addr+0(FP), DI		// arg 1 - ptr
+	MOVL val+8(FP), SI		// arg 2 - value
+	MOVL timeout+12(FP), DX		// arg 3 - timeout
+	MOVL $469, AX		// umtx_sleep
+	SYSCALL
+	JCC	2(PC)
+	NEGQ	AX
+	MOVL	AX, ret+16(FP)
+	RET
+
+TEXT runtime·sys_umtx_wakeup(SB),NOSPLIT,$0
+	MOVQ addr+0(FP), DI		// arg 1 - ptr
+	MOVL val+8(FP), SI		// arg 2 - count
+	MOVL $470, AX		// umtx_wakeup
+	SYSCALL
+	JCC	2(PC)
+	NEGQ	AX
+	MOVL	AX, ret+16(FP)
+	RET
+
+TEXT runtime·lwp_create(SB),NOSPLIT,$0
+	MOVQ param+0(FP), DI		// arg 1 - params
+	MOVL $495, AX		// lwp_create
+	SYSCALL
+	MOVL	AX, ret+8(FP)
+	RET
+
+TEXT runtime·lwp_start(SB),NOSPLIT,$0
+	MOVQ	DI, R13 // m
+
+	// set up FS to point at m->tls
+	LEAQ	m_tls(R13), DI
+	CALL	runtime·settls(SB)	// smashes DI
+
+	// set up m, g
+	get_tls(CX)
+	MOVQ	m_g0(R13), DI
+	MOVQ	R13, g_m(DI)
+	MOVQ	DI, g(CX)
+
+	CALL	runtime·stackcheck(SB)
+	CALL	runtime·mstart(SB)
+
+	MOVQ 0, AX			// crash (not reached)
+
+// Exit the entire program (like C exit)
+TEXT runtime·exit(SB),NOSPLIT,$-8
+	MOVL	code+0(FP), DI		// arg 1 exit status
+	MOVL	$1, AX
+	SYSCALL
+	MOVL	$0xf1, 0xf1  // crash
+	RET
+
+TEXT runtime·exit1(SB),NOSPLIT,$-8
+	MOVL	code+0(FP), DI		// arg 1 exit status
+	MOVL	$431, AX
+	SYSCALL
+	MOVL	$0xf1, 0xf1  // crash
+	RET
+
+TEXT runtime·open(SB),NOSPLIT,$-8
+	MOVQ	name+0(FP), DI		// arg 1 pathname
+	MOVL	mode+8(FP), SI		// arg 2 flags
+	MOVL	perm+12(FP), DX		// arg 3 mode
+	MOVL	$5, AX
+	SYSCALL
+	MOVL	AX, ret+16(FP)
+	RET
+
+TEXT runtime·close(SB),NOSPLIT,$-8
+	MOVL	fd+0(FP), DI		// arg 1 fd
+	MOVL	$6, AX
+	SYSCALL
+	MOVL	AX, ret+8(FP)
+	RET
+
+TEXT runtime·read(SB),NOSPLIT,$-8
+	MOVL	fd+0(FP), DI		// arg 1 fd
+	MOVQ	p+8(FP), SI		// arg 2 buf
+	MOVL	n+16(FP), DX		// arg 3 count
+	MOVL	$3, AX
+	SYSCALL
+	MOVL	AX, ret+24(FP)
+	RET
+
+TEXT runtime·write(SB),NOSPLIT,$-8
+	MOVQ	fd+0(FP), DI		// arg 1 fd
+	MOVQ	p+8(FP), SI		// arg 2 buf
+	MOVL	n+16(FP), DX		// arg 3 count
+	MOVL	$4, AX
+	SYSCALL
+	MOVL	AX, ret+24(FP)
+	RET
+
+TEXT runtime·getrlimit(SB),NOSPLIT,$-8
+	MOVL	kind+0(FP), DI
+	MOVQ	limit+8(FP), SI
+	MOVL	$194, AX
+	SYSCALL
+	MOVL	AX, ret+16(FP)
+	RET
+
+TEXT runtime·raise(SB),NOSPLIT,$16
+	MOVL	$496, AX	// lwp_gettid
+	SYSCALL
+	MOVQ	$-1, DI		// arg 1 - pid
+	MOVQ	8(SP), DI	// arg 2 - tid
+	MOVL	sig+0(FP), SI	// arg 3 - signum
+	MOVL	$497, AX	// lwp_kill
+	SYSCALL
+	RET
+
+TEXT runtime·setitimer(SB), NOSPLIT, $-8
+	MOVL	mode+0(FP), DI
+	MOVQ	new+8(FP), SI
+	MOVQ	old+16(FP), DX
+	MOVL	$83, AX
+	SYSCALL
+	RET
+
+// func now() (sec int64, nsec int32)
+TEXT time·now(SB), NOSPLIT, $32
+	MOVL	$232, AX
+	MOVQ	$0, DI  	// CLOCK_REALTIME
+	LEAQ	8(SP), SI
+	SYSCALL
+	MOVQ	8(SP), AX	// sec
+	MOVQ	16(SP), DX	// nsec
+
+	// sec is in AX, nsec in DX
+	MOVQ	AX, sec+0(FP)
+	MOVL	DX, nsec+8(FP)
+	RET
+
+TEXT runtime·nanotime(SB), NOSPLIT, $32
+	MOVL	$232, AX
+	MOVQ	$4, DI  	// CLOCK_MONOTONIC
+	LEAQ	8(SP), SI
+	SYSCALL
+	MOVQ	8(SP), AX	// sec
+	MOVQ	16(SP), DX	// nsec
+
+	// sec is in AX, nsec in DX
+	// return nsec in AX
+	IMULQ	$1000000000, AX
+	ADDQ	DX, AX
+	MOVQ	AX, ret+0(FP)
+	RET
+
+TEXT runtime·sigaction(SB),NOSPLIT,$-8
+	MOVL	sig+0(FP), DI		// arg 1 sig
+	MOVQ	new+8(FP), SI		// arg 2 act
+	MOVQ	old+16(FP), DX		// arg 3 oact
+	MOVL	$342, AX
+	SYSCALL
+	JCC	2(PC)
+	MOVL	$0xf1, 0xf1  // crash
+	RET
+
+TEXT runtime·sigtramp(SB),NOSPLIT,$64
+	get_tls(BX)
+
+	// check that g exists
+	MOVQ	g(BX), R10
+	CMPQ	R10, $0
+	JNE	5(PC)
+	MOVQ	DI, 0(SP)
+	MOVQ	$runtime·badsignal(SB), AX
+	CALL	AX
+	RET
+
+	// save g
+	MOVQ	R10, 40(SP)
+	
+	// g = m->signal
+	MOVQ	g_m(R10), BP
+	MOVQ	m_gsignal(BP), BP
+	MOVQ	BP, g(BX)
+	
+	MOVQ	DI, 0(SP)
+	MOVQ	SI, 8(SP)
+	MOVQ	DX, 16(SP)
+	MOVQ	R10, 24(SP)
+
+	CALL	runtime·sighandler(SB)
+
+	// restore g
+	get_tls(BX)
+	MOVQ	40(SP), R10
+	MOVQ	R10, g(BX)
+	RET
+
+TEXT runtime·mmap(SB),NOSPLIT,$0
+	MOVQ	addr+0(FP), DI		// arg 1 - addr
+	MOVQ	n+8(FP), SI		// arg 2 - len
+	MOVL	prot+16(FP), DX		// arg 3 - prot
+	MOVL	flags+20(FP), R10		// arg 4 - flags
+	MOVL	fd+24(FP), R8		// arg 5 - fd
+	MOVL	off+28(FP), R9
+	SUBQ	$16, SP
+	MOVQ	R9, 8(SP)		// arg 7 - offset (passed on stack)
+	MOVQ	$0, R9			// arg 6 - pad
+	MOVL	$197, AX
+	SYSCALL
+	ADDQ	$16, SP
+	MOVQ	AX, ret+32(FP)
+	RET
+
+TEXT runtime·munmap(SB),NOSPLIT,$0
+	MOVQ	addr+0(FP), DI		// arg 1 addr
+	MOVQ	n+8(FP), SI		// arg 2 len
+	MOVL	$73, AX
+	SYSCALL
+	JCC	2(PC)
+	MOVL	$0xf1, 0xf1  // crash
+	RET
+
+TEXT runtime·madvise(SB),NOSPLIT,$0
+	MOVQ	addr+0(FP), DI
+	MOVQ	n+8(FP), SI
+	MOVL	flags+16(FP), DX
+	MOVQ	$75, AX	// madvise
+	SYSCALL
+	// ignore failure - maybe pages are locked
+	RET
+	
+TEXT runtime·sigaltstack(SB),NOSPLIT,$-8
+	MOVQ	new+8(SP), DI
+	MOVQ	old+16(SP), SI
+	MOVQ	$53, AX
+	SYSCALL
+	JCC	2(PC)
+	MOVL	$0xf1, 0xf1  // crash
+	RET
+
+TEXT runtime·usleep(SB),NOSPLIT,$16
+	MOVL	$0, DX
+	MOVL	usec+0(FP), AX
+	MOVL	$1000000, CX
+	DIVL	CX
+	MOVQ	AX, 0(SP)		// tv_sec
+	MOVL	$1000, AX
+	MULL	DX
+	MOVQ	AX, 8(SP)		// tv_nsec
+
+	MOVQ	SP, DI			// arg 1 - rqtp
+	MOVQ	$0, SI			// arg 2 - rmtp
+	MOVL	$240, AX		// sys_nanosleep
+	SYSCALL
+	RET
+
+// set tls base to DI
+TEXT runtime·settls(SB),NOSPLIT,$16
+	ADDQ	$16, DI	// adjust for ELF: wants to use -16(FS) and -8(FS) for g and m
+	MOVQ	DI, 0(SP)
+	MOVQ	$16, 8(SP)
+	MOVQ	$0, DI			// arg 1 - which
+	MOVQ	SP, SI			// arg 2 - tls_info
+	MOVQ	$16, DX			// arg 3 - infosize
+	MOVQ	$472, AX		// set_tls_area
+	SYSCALL
+	JCC	2(PC)
+	MOVL	$0xf1, 0xf1  // crash
+	RET
+
+TEXT runtime·sysctl(SB),NOSPLIT,$0
+	MOVQ	mib+0(FP), DI		// arg 1 - name
+	MOVL	miblen+8(FP), SI		// arg 2 - namelen
+	MOVQ	out+16(FP), DX		// arg 3 - oldp
+	MOVQ	size+24(FP), R10		// arg 4 - oldlenp
+	MOVQ	dst+32(FP), R8		// arg 5 - newp
+	MOVQ	ndst+40(FP), R9		// arg 6 - newlen
+	MOVQ	$202, AX		// sys___sysctl
+	SYSCALL
+	JCC 4(PC)
+	NEGQ	AX
+	MOVL	AX, ret+48(FP)
+	RET
+	MOVL	$0, AX
+	MOVL	AX, ret+48(FP)
+	RET
+
+TEXT runtime·osyield(SB),NOSPLIT,$-4
+	MOVL	$331, AX		// sys_sched_yield
+	SYSCALL
+	RET
+
+TEXT runtime·sigprocmask(SB),NOSPLIT,$0
+	MOVL	$3, DI			// arg 1 - how (SIG_SETMASK)
+	MOVQ	new+0(FP), SI		// arg 2 - set
+	MOVQ	old+8(FP), DX		// arg 3 - oset
+	MOVL	$340, AX		// sys_sigprocmask
+	SYSCALL
+	JAE	2(PC)
+	MOVL	$0xf1, 0xf1  // crash
+	RET
+
+// int32 runtime·kqueue(void);
+TEXT runtime·kqueue(SB),NOSPLIT,$0
+	MOVQ	$0, DI
+	MOVQ	$0, SI
+	MOVQ	$0, DX
+	MOVL	$362, AX
+	SYSCALL
+	JCC	2(PC)
+	NEGQ	AX
+	MOVL	AX, ret+0(FP)
+	RET
+
+// int32 runtime·kevent(int kq, Kevent *changelist, int nchanges, Kevent *eventlist, int nevents, Timespec *timeout);
+TEXT runtime·kevent(SB),NOSPLIT,$0
+	MOVL	fd+0(FP), DI
+	MOVQ	ev1+8(FP), SI
+	MOVL	nev1+16(FP), DX
+	MOVQ	ev2+24(FP), R10
+	MOVL	nev2+32(FP), R8
+	MOVQ	ts+40(FP), R9
+	MOVL	$363, AX
+	SYSCALL
+	JCC	2(PC)
+	NEGQ	AX
+	MOVL	AX, ret+48(FP)
+	RET
+
+// void runtime·closeonexec(int32 fd);
+TEXT runtime·closeonexec(SB),NOSPLIT,$0
+	MOVL	fd+0(FP), DI	// fd
+	MOVQ	$2, SI		// F_SETFD
+	MOVQ	$1, DX		// FD_CLOEXEC
+	MOVL	$92, AX		// fcntl
+	SYSCALL
+	RET
diff --git a/src/runtime/sys_freebsd_386.s b/src/runtime/sys_freebsd_386.s
new file mode 100644
index 0000000..2c40fc4
--- /dev/null
+++ b/src/runtime/sys_freebsd_386.s
@@ -0,0 +1,391 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+//
+// System calls and other sys.stuff for 386, FreeBSD
+// /usr/src/sys/kern/syscalls.master for syscall numbers.
+//
+
+#include "zasm_GOOS_GOARCH.h"
+#include "textflag.h"
+	
+TEXT runtime·sys_umtx_op(SB),NOSPLIT,$-4
+	MOVL	$454, AX
+	INT	$0x80
+	MOVL	AX, ret+20(FP)
+	RET
+
+TEXT runtime·thr_new(SB),NOSPLIT,$-4
+	MOVL	$455, AX
+	INT	$0x80
+	RET
+
+TEXT runtime·thr_start(SB),NOSPLIT,$0
+	MOVL	mm+0(FP), AX
+	MOVL	m_g0(AX), BX
+	LEAL	m_tls(AX), BP
+	MOVL	0(BP), DI
+	ADDL	$7, DI
+	PUSHAL
+	PUSHL	$32
+	PUSHL	BP
+	PUSHL	DI
+	CALL	runtime·setldt(SB)
+	POPL	AX
+	POPL	AX
+	POPL	AX
+	POPAL
+	get_tls(CX)
+	MOVL	BX, g(CX)
+	
+	MOVL	AX, g_m(BX)
+	CALL	runtime·stackcheck(SB)		// smashes AX
+	CALL	runtime·mstart(SB)
+
+	MOVL	0, AX			// crash (not reached)
+
+// Exit the entire program (like C exit)
+TEXT runtime·exit(SB),NOSPLIT,$-4
+	MOVL	$1, AX
+	INT	$0x80
+	MOVL	$0xf1, 0xf1  // crash
+	RET
+
+TEXT runtime·exit1(SB),NOSPLIT,$-4
+	MOVL	$431, AX
+	INT	$0x80
+	JAE	2(PC)
+	MOVL	$0xf1, 0xf1  // crash
+	RET
+
+TEXT runtime·open(SB),NOSPLIT,$-4
+	MOVL	$5, AX
+	INT	$0x80
+	MOVL	AX, ret+12(FP)
+	RET
+
+TEXT runtime·close(SB),NOSPLIT,$-4
+	MOVL	$6, AX
+	INT	$0x80
+	MOVL	AX, ret+4(FP)
+	RET
+
+TEXT runtime·read(SB),NOSPLIT,$-4
+	MOVL	$3, AX
+	INT	$0x80
+	MOVL	AX, ret+12(FP)
+	RET
+
+TEXT runtime·write(SB),NOSPLIT,$-4
+	MOVL	$4, AX
+	INT	$0x80
+	MOVL	AX, ret+12(FP)
+	RET
+
+TEXT runtime·getrlimit(SB),NOSPLIT,$-4
+	MOVL	$194, AX
+	INT	$0x80
+	MOVL	AX, ret+8(FP)
+	RET
+
+TEXT runtime·raise(SB),NOSPLIT,$16
+	// thr_self(&8(SP))
+	LEAL	8(SP), AX
+	MOVL	AX, 4(SP)
+	MOVL	$432, AX
+	INT	$0x80
+	// thr_kill(self, SIGPIPE)
+	MOVL	8(SP), AX
+	MOVL	AX, 4(SP)
+	MOVL	sig+0(FP), AX
+	MOVL	AX, 8(SP)
+	MOVL	$433, AX
+	INT	$0x80
+	RET
+
+TEXT runtime·mmap(SB),NOSPLIT,$32
+	LEAL addr+0(FP), SI
+	LEAL	4(SP), DI
+	CLD
+	MOVSL
+	MOVSL
+	MOVSL
+	MOVSL
+	MOVSL
+	MOVSL
+	MOVL	$0, AX	// top 32 bits of file offset
+	STOSL
+	MOVL	$477, AX
+	INT	$0x80
+	MOVL	AX, ret+24(FP)
+	RET
+
+TEXT runtime·munmap(SB),NOSPLIT,$-4
+	MOVL	$73, AX
+	INT	$0x80
+	JAE	2(PC)
+	MOVL	$0xf1, 0xf1  // crash
+	RET
+
+TEXT runtime·madvise(SB),NOSPLIT,$-4
+	MOVL	$75, AX	// madvise
+	INT	$0x80
+	// ignore failure - maybe pages are locked
+	RET
+
+TEXT runtime·setitimer(SB), NOSPLIT, $-4
+	MOVL	$83, AX
+	INT	$0x80
+	RET
+
+// func now() (sec int64, nsec int32)
+TEXT time·now(SB), NOSPLIT, $32
+	MOVL	$232, AX
+	LEAL	12(SP), BX
+	MOVL	$0, 4(SP)	// CLOCK_REALTIME
+	MOVL	BX, 8(SP)
+	INT	$0x80
+	MOVL	12(SP), AX	// sec
+	MOVL	16(SP), BX	// nsec
+
+	// sec is in AX, nsec in BX
+	MOVL	AX, sec+0(FP)
+	MOVL	$0, sec+4(FP)
+	MOVL	BX, nsec+8(FP)
+	RET
+
+// int64 nanotime(void) so really
+// void nanotime(int64 *nsec)
+TEXT runtime·nanotime(SB), NOSPLIT, $32
+	MOVL	$232, AX
+	LEAL	12(SP), BX
+	// We can use CLOCK_MONOTONIC_FAST here when we drop
+	// support for FreeBSD 8-STABLE.
+	MOVL	$4, 4(SP)	// CLOCK_MONOTONIC
+	MOVL	BX, 8(SP)
+	INT	$0x80
+	MOVL	12(SP), AX	// sec
+	MOVL	16(SP), BX	// nsec
+
+	// sec is in AX, nsec in BX
+	// convert to DX:AX nsec
+	MOVL	$1000000000, CX
+	MULL	CX
+	ADDL	BX, AX
+	ADCL	$0, DX
+
+	MOVL	AX, ret_lo+0(FP)
+	MOVL	DX, ret_hi+4(FP)
+	RET
+
+
+TEXT runtime·sigaction(SB),NOSPLIT,$-4
+	MOVL	$416, AX
+	INT	$0x80
+	JAE	2(PC)
+	MOVL	$0xf1, 0xf1  // crash
+	RET
+
+TEXT runtime·sigtramp(SB),NOSPLIT,$44
+	get_tls(CX)
+
+	// check that g exists
+	MOVL	g(CX), DI
+	CMPL	DI, $0
+	JNE	6(PC)
+	MOVL	signo+0(FP), BX
+	MOVL	BX, 0(SP)
+	MOVL	$runtime·badsignal(SB), AX
+	CALL	AX
+	JMP 	sigtramp_ret
+
+	// save g
+	MOVL	DI, 20(SP)
+	
+	// g = m->gsignal
+	MOVL	g_m(DI), BX
+	MOVL	m_gsignal(BX), BX
+	MOVL	BX, g(CX)
+
+	// copy arguments for call to sighandler
+	MOVL	signo+0(FP), BX
+	MOVL	BX, 0(SP)
+	MOVL	info+4(FP), BX
+	MOVL	BX, 4(SP)
+	MOVL	context+8(FP), BX
+	MOVL	BX, 8(SP)
+	MOVL	DI, 12(SP)
+
+	CALL	runtime·sighandler(SB)
+
+	// restore g
+	get_tls(CX)
+	MOVL	20(SP), BX
+	MOVL	BX, g(CX)
+
+sigtramp_ret:
+	// call sigreturn
+	MOVL	context+8(FP), AX
+	MOVL	$0, 0(SP)	// syscall gap
+	MOVL	AX, 4(SP)
+	MOVL	$417, AX	// sigreturn(ucontext)
+	INT	$0x80
+	MOVL	$0xf1, 0xf1  // crash
+	RET
+
+TEXT runtime·sigaltstack(SB),NOSPLIT,$0
+	MOVL	$53, AX
+	INT	$0x80
+	JAE	2(PC)
+	MOVL	$0xf1, 0xf1  // crash
+	RET
+
+TEXT runtime·usleep(SB),NOSPLIT,$20
+	MOVL	$0, DX
+	MOVL	usec+0(FP), AX
+	MOVL	$1000000, CX
+	DIVL	CX
+	MOVL	AX, 12(SP)		// tv_sec
+	MOVL	$1000, AX
+	MULL	DX
+	MOVL	AX, 16(SP)		// tv_nsec
+
+	MOVL	$0, 0(SP)
+	LEAL	12(SP), AX
+	MOVL	AX, 4(SP)		// arg 1 - rqtp
+	MOVL	$0, 8(SP)		// arg 2 - rmtp
+	MOVL	$240, AX		// sys_nanosleep
+	INT	$0x80
+	RET
+
+/*
+descriptor entry format for system call
+is the native machine format, ugly as it is:
+
+	2-byte limit
+	3-byte base
+	1-byte: 0x80=present, 0x60=dpl<<5, 0x1F=type
+	1-byte: 0x80=limit is *4k, 0x40=32-bit operand size,
+		0x0F=4 more bits of limit
+	1 byte: 8 more bits of base
+
+int i386_get_ldt(int, union ldt_entry *, int);
+int i386_set_ldt(int, const union ldt_entry *, int);
+
+*/
+
+// setldt(int entry, int address, int limit)
+TEXT runtime·setldt(SB),NOSPLIT,$32
+	MOVL	address+4(FP), BX	// aka base
+	// see comment in sys_linux_386.s; freebsd is similar
+	ADDL	$0x8, BX
+
+	// set up data_desc
+	LEAL	16(SP), AX	// struct data_desc
+	MOVL	$0, 0(AX)
+	MOVL	$0, 4(AX)
+
+	MOVW	BX, 2(AX)
+	SHRL	$16, BX
+	MOVB	BX, 4(AX)
+	SHRL	$8, BX
+	MOVB	BX, 7(AX)
+
+	MOVW	$0xffff, 0(AX)
+	MOVB	$0xCF, 6(AX)	// 32-bit operand, 4k limit unit, 4 more bits of limit
+
+	MOVB	$0xF2, 5(AX)	// r/w data descriptor, dpl=3, present
+
+	// call i386_set_ldt(entry, desc, 1)
+	MOVL	$0xffffffff, 0(SP)	// auto-allocate entry and return in AX
+	MOVL	AX, 4(SP)
+	MOVL	$1, 8(SP)
+	CALL	runtime·i386_set_ldt(SB)
+
+	// compute segment selector - (entry*8+7)
+	SHLL	$3, AX
+	ADDL	$7, AX
+	MOVW	AX, GS
+	RET
+
+TEXT runtime·i386_set_ldt(SB),NOSPLIT,$16
+	LEAL	args+0(FP), AX	// 0(FP) == 4(SP) before SP got moved
+	MOVL	$0, 0(SP)	// syscall gap
+	MOVL	$1, 4(SP)
+	MOVL	AX, 8(SP)
+	MOVL	$165, AX
+	INT	$0x80
+	JAE	2(PC)
+	INT	$3
+	RET
+
+TEXT runtime·sysctl(SB),NOSPLIT,$28
+	LEAL	mib+0(FP), SI
+	LEAL	4(SP), DI
+	CLD
+	MOVSL				// arg 1 - name
+	MOVSL				// arg 2 - namelen
+	MOVSL				// arg 3 - oldp
+	MOVSL				// arg 4 - oldlenp
+	MOVSL				// arg 5 - newp
+	MOVSL				// arg 6 - newlen
+	MOVL	$202, AX		// sys___sysctl
+	INT	$0x80
+	JAE	4(PC)
+	NEGL	AX
+	MOVL	AX, ret+24(FP)
+	RET
+	MOVL	$0, AX
+	MOVL	AX, ret+24(FP)
+	RET
+
+TEXT runtime·osyield(SB),NOSPLIT,$-4
+	MOVL	$331, AX		// sys_sched_yield
+	INT	$0x80
+	RET
+
+TEXT runtime·sigprocmask(SB),NOSPLIT,$16
+	MOVL	$0, 0(SP)		// syscall gap
+	MOVL	$3, 4(SP)		// arg 1 - how (SIG_SETMASK)
+	MOVL	new+0(FP), AX
+	MOVL	AX, 8(SP)		// arg 2 - set
+	MOVL	old+4(FP), AX
+	MOVL	AX, 12(SP)		// arg 3 - oset
+	MOVL	$340, AX		// sys_sigprocmask
+	INT	$0x80
+	JAE	2(PC)
+	MOVL	$0xf1, 0xf1  // crash
+	RET
+
+// int32 runtime·kqueue(void);
+TEXT runtime·kqueue(SB),NOSPLIT,$0
+	MOVL	$362, AX
+	INT	$0x80
+	JAE	2(PC)
+	NEGL	AX
+	MOVL	AX, ret+0(FP)
+	RET
+
+// int32 runtime·kevent(int kq, Kevent *changelist, int nchanges, Kevent *eventlist, int nevents, Timespec *timeout);
+TEXT runtime·kevent(SB),NOSPLIT,$0
+	MOVL	$363, AX
+	INT	$0x80
+	JAE	2(PC)
+	NEGL	AX
+	MOVL	AX, ret+24(FP)
+	RET
+
+// int32 runtime·closeonexec(int32 fd);
+TEXT runtime·closeonexec(SB),NOSPLIT,$32
+	MOVL	$92, AX		// fcntl
+	// 0(SP) is where the caller PC would be; kernel skips it
+	MOVL	fd+0(FP), BX
+	MOVL	BX, 4(SP)	// fd
+	MOVL	$2, 8(SP)	// F_SETFD
+	MOVL	$1, 12(SP)	// FD_CLOEXEC
+	INT	$0x80
+	JAE	2(PC)
+	NEGL	AX
+	RET
+
+GLOBL runtime·tlsoffset(SB),NOPTR,$4
diff --git a/src/runtime/sys_freebsd_amd64.s b/src/runtime/sys_freebsd_amd64.s
new file mode 100644
index 0000000..65f8c1a
--- /dev/null
+++ b/src/runtime/sys_freebsd_amd64.s
@@ -0,0 +1,357 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+//
+// System calls and other sys.stuff for AMD64, FreeBSD
+// /usr/src/sys/kern/syscalls.master for syscall numbers.
+//
+
+#include "zasm_GOOS_GOARCH.h"
+#include "textflag.h"
+
+// FreeBSD 8, FreeBSD 9, and older versions that I have checked
+// do not restore R10 on exit from a "restarted" system call
+// if you use the SYSCALL instruction. This means that, for example,
+// if a signal arrives while the wait4 system call is executing,
+// the wait4 internally returns ERESTART, which makes the kernel
+// back up the PC to execute the SYSCALL instruction a second time.
+// However, since the kernel does not restore R10, the fourth
+// argument to the system call has been lost. (FreeBSD 9 also fails
+// to restore the fifth and sixth arguments, R8 and R9, although
+// some earlier versions did restore those correctly.)
+// The broken code is in fast_syscall in FreeBSD's amd64/amd64/exception.S.
+// It restores only DI, SI, DX, AX, and RFLAGS on system call return.
+// http://fxr.watson.org/fxr/source/amd64/amd64/exception.S?v=FREEBSD91#L399
+//
+// The INT $0x80 system call path (int0x80_syscall in FreeBSD's 
+// amd64/ia32/ia32_exception.S) does not have this problem,
+// but it expects the third argument in R10. Instead of rewriting
+// all the assembly in this file, #define SYSCALL to a safe simulation
+// using INT $0x80.
+//
+// INT $0x80 is a little slower than SYSCALL, but correctness wins.
+//
+// See golang.org/issue/6372.
+#define SYSCALL MOVQ R10, CX; INT $0x80
+	
+TEXT runtime·sys_umtx_op(SB),NOSPLIT,$0
+	MOVQ addr+0(FP), DI
+	MOVL mode+8(FP), SI
+	MOVL val+12(FP), DX
+	MOVQ ptr2+16(FP), R10
+	MOVQ ts+24(FP), R8
+	MOVL $454, AX
+	SYSCALL
+	MOVL	AX, ret+32(FP)
+	RET
+
+TEXT runtime·thr_new(SB),NOSPLIT,$0
+	MOVQ param+0(FP), DI
+	MOVL size+8(FP), SI
+	MOVL $455, AX
+	SYSCALL
+	RET
+
+TEXT runtime·thr_start(SB),NOSPLIT,$0
+	MOVQ	DI, R13 // m
+
+	// set up FS to point at m->tls
+	LEAQ	m_tls(R13), DI
+	CALL	runtime·settls(SB)	// smashes DI
+
+	// set up m, g
+	get_tls(CX)
+	MOVQ	m_g0(R13), DI
+	MOVQ	R13, g_m(DI)
+	MOVQ	DI, g(CX)
+
+	CALL	runtime·stackcheck(SB)
+	CALL	runtime·mstart(SB)
+
+	MOVQ 0, AX			// crash (not reached)
+
+// Exit the entire program (like C exit)
+TEXT runtime·exit(SB),NOSPLIT,$-8
+	MOVL	code+0(FP), DI		// arg 1 exit status
+	MOVL	$1, AX
+	SYSCALL
+	MOVL	$0xf1, 0xf1  // crash
+	RET
+
+TEXT runtime·exit1(SB),NOSPLIT,$-8
+	MOVL	code+0(FP), DI		// arg 1 exit status
+	MOVL	$431, AX
+	SYSCALL
+	MOVL	$0xf1, 0xf1  // crash
+	RET
+
+TEXT runtime·open(SB),NOSPLIT,$-8
+	MOVQ	name+0(FP), DI		// arg 1 pathname
+	MOVL	mode+8(FP), SI		// arg 2 flags
+	MOVL	perm+12(FP), DX		// arg 3 mode
+	MOVL	$5, AX
+	SYSCALL
+	MOVL	AX, ret+16(FP)
+	RET
+
+TEXT runtime·close(SB),NOSPLIT,$-8
+	MOVL	fd+0(FP), DI		// arg 1 fd
+	MOVL	$6, AX
+	SYSCALL
+	MOVL	AX, ret+8(FP)
+	RET
+
+TEXT runtime·read(SB),NOSPLIT,$-8
+	MOVL	fd+0(FP), DI		// arg 1 fd
+	MOVQ	p+8(FP), SI		// arg 2 buf
+	MOVL	n+16(FP), DX		// arg 3 count
+	MOVL	$3, AX
+	SYSCALL
+	MOVL	AX, ret+24(FP)
+	RET
+
+TEXT runtime·write(SB),NOSPLIT,$-8
+	MOVQ	fd+0(FP), DI		// arg 1 fd
+	MOVQ	p+8(FP), SI		// arg 2 buf
+	MOVL	n+16(FP), DX		// arg 3 count
+	MOVL	$4, AX
+	SYSCALL
+	MOVL	AX, ret+24(FP)
+	RET
+
+TEXT runtime·getrlimit(SB),NOSPLIT,$-8
+	MOVL	kind+0(FP), DI
+	MOVQ	limit+8(FP), SI
+	MOVL	$194, AX
+	SYSCALL
+	MOVL	AX, ret+16(FP)
+	RET
+
+TEXT runtime·raise(SB),NOSPLIT,$16
+	// thr_self(&8(SP))
+	LEAQ	8(SP), DI	// arg 1 &8(SP)
+	MOVL	$432, AX
+	SYSCALL
+	// thr_kill(self, SIGPIPE)
+	MOVQ	8(SP), DI	// arg 1 id
+	MOVL	sig+0(FP), SI	// arg 2
+	MOVL	$433, AX
+	SYSCALL
+	RET
+
+TEXT runtime·setitimer(SB), NOSPLIT, $-8
+	MOVL	mode+0(FP), DI
+	MOVQ	new+8(FP), SI
+	MOVQ	old+16(FP), DX
+	MOVL	$83, AX
+	SYSCALL
+	RET
+
+// func now() (sec int64, nsec int32)
+TEXT time·now(SB), NOSPLIT, $32
+	MOVL	$232, AX
+	MOVQ	$0, DI		// CLOCK_REALTIME
+	LEAQ	8(SP), SI
+	SYSCALL
+	MOVQ	8(SP), AX	// sec
+	MOVQ	16(SP), DX	// nsec
+
+	// sec is in AX, nsec in DX
+	MOVQ	AX, sec+0(FP)
+	MOVL	DX, nsec+8(FP)
+	RET
+
+TEXT runtime·nanotime(SB), NOSPLIT, $32
+	MOVL	$232, AX
+	// We can use CLOCK_MONOTONIC_FAST here when we drop
+	// support for FreeBSD 8-STABLE.
+	MOVQ	$4, DI		// CLOCK_MONOTONIC
+	LEAQ	8(SP), SI
+	SYSCALL
+	MOVQ	8(SP), AX	// sec
+	MOVQ	16(SP), DX	// nsec
+
+	// sec is in AX, nsec in DX
+	// return nsec in AX
+	IMULQ	$1000000000, AX
+	ADDQ	DX, AX
+	MOVQ	AX, ret+0(FP)
+	RET
+
+TEXT runtime·sigaction(SB),NOSPLIT,$-8
+	MOVL	sig+0(FP), DI		// arg 1 sig
+	MOVQ	new+8(FP), SI		// arg 2 act
+	MOVQ	old+16(FP), DX		// arg 3 oact
+	MOVL	$416, AX
+	SYSCALL
+	JCC	2(PC)
+	MOVL	$0xf1, 0xf1  // crash
+	RET
+
+TEXT runtime·sigtramp(SB),NOSPLIT,$64
+	get_tls(BX)
+
+	// check that g exists
+	MOVQ	g(BX), R10
+	CMPQ	R10, $0
+	JNE	5(PC)
+	MOVQ	DI, 0(SP)
+	MOVQ	$runtime·badsignal(SB), AX
+	CALL	AX
+	RET
+
+	// save g
+	MOVQ	R10, 40(SP)
+	
+	// g = m->signal
+	MOVQ	g_m(R10), BP
+	MOVQ	m_gsignal(BP), BP
+	MOVQ	BP, g(BX)
+	
+	MOVQ	DI, 0(SP)
+	MOVQ	SI, 8(SP)
+	MOVQ	DX, 16(SP)
+	MOVQ	R10, 24(SP)
+
+	CALL	runtime·sighandler(SB)
+
+	// restore g
+	get_tls(BX)
+	MOVQ	40(SP), R10
+	MOVQ	R10, g(BX)
+	RET
+
+TEXT runtime·mmap(SB),NOSPLIT,$0
+	MOVQ	addr+0(FP), DI		// arg 1 addr
+	MOVQ	n+8(FP), SI		// arg 2 len
+	MOVL	prot+16(FP), DX		// arg 3 prot
+	MOVL	flags+20(FP), R10		// arg 4 flags
+	MOVL	fd+24(FP), R8		// arg 5 fid
+	MOVL	off+28(FP), R9		// arg 6 offset
+	MOVL	$477, AX
+	SYSCALL
+	MOVQ	AX, ret+32(FP)
+	RET
+
+TEXT runtime·munmap(SB),NOSPLIT,$0
+	MOVQ	addr+0(FP), DI		// arg 1 addr
+	MOVQ	n+8(FP), SI		// arg 2 len
+	MOVL	$73, AX
+	SYSCALL
+	JCC	2(PC)
+	MOVL	$0xf1, 0xf1  // crash
+	RET
+
+TEXT runtime·madvise(SB),NOSPLIT,$0
+	MOVQ	addr+0(FP), DI
+	MOVQ	n+8(FP), SI
+	MOVL	flags+16(FP), DX
+	MOVQ	$75, AX	// madvise
+	SYSCALL
+	// ignore failure - maybe pages are locked
+	RET
+	
+TEXT runtime·sigaltstack(SB),NOSPLIT,$-8
+	MOVQ	new+8(SP), DI
+	MOVQ	old+16(SP), SI
+	MOVQ	$53, AX
+	SYSCALL
+	JCC	2(PC)
+	MOVL	$0xf1, 0xf1  // crash
+	RET
+
+TEXT runtime·usleep(SB),NOSPLIT,$16
+	MOVL	$0, DX
+	MOVL	usec+0(FP), AX
+	MOVL	$1000000, CX
+	DIVL	CX
+	MOVQ	AX, 0(SP)		// tv_sec
+	MOVL	$1000, AX
+	MULL	DX
+	MOVQ	AX, 8(SP)		// tv_nsec
+
+	MOVQ	SP, DI			// arg 1 - rqtp
+	MOVQ	$0, SI			// arg 2 - rmtp
+	MOVL	$240, AX		// sys_nanosleep
+	SYSCALL
+	RET
+
+// set tls base to DI
+TEXT runtime·settls(SB),NOSPLIT,$8
+	ADDQ	$16, DI	// adjust for ELF: wants to use -16(FS) and -8(FS) for g and m
+	MOVQ	DI, 0(SP)
+	MOVQ	SP, SI
+	MOVQ	$129, DI	// AMD64_SET_FSBASE
+	MOVQ	$165, AX	// sysarch
+	SYSCALL
+	JCC	2(PC)
+	MOVL	$0xf1, 0xf1  // crash
+	RET
+
+TEXT runtime·sysctl(SB),NOSPLIT,$0
+	MOVQ	mib+0(FP), DI		// arg 1 - name
+	MOVL	miblen+8(FP), SI		// arg 2 - namelen
+	MOVQ	out+16(FP), DX		// arg 3 - oldp
+	MOVQ	size+24(FP), R10		// arg 4 - oldlenp
+	MOVQ	dst+32(FP), R8		// arg 5 - newp
+	MOVQ	ndst+40(FP), R9		// arg 6 - newlen
+	MOVQ	$202, AX		// sys___sysctl
+	SYSCALL
+	JCC 4(PC)
+	NEGQ	AX
+	MOVL	AX, ret+48(FP)
+	RET
+	MOVL	$0, AX
+	MOVL	AX, ret+48(FP)
+	RET
+
+TEXT runtime·osyield(SB),NOSPLIT,$-4
+	MOVL	$331, AX		// sys_sched_yield
+	SYSCALL
+	RET
+
+TEXT runtime·sigprocmask(SB),NOSPLIT,$0
+	MOVL	$3, DI			// arg 1 - how (SIG_SETMASK)
+	MOVQ	new+0(FP), SI		// arg 2 - set
+	MOVQ	old+8(FP), DX		// arg 3 - oset
+	MOVL	$340, AX		// sys_sigprocmask
+	SYSCALL
+	JAE	2(PC)
+	MOVL	$0xf1, 0xf1  // crash
+	RET
+
+// int32 runtime·kqueue(void);
+TEXT runtime·kqueue(SB),NOSPLIT,$0
+	MOVQ	$0, DI
+	MOVQ	$0, SI
+	MOVQ	$0, DX
+	MOVL	$362, AX
+	SYSCALL
+	JCC	2(PC)
+	NEGQ	AX
+	MOVL	AX, ret+0(FP)
+	RET
+
+// int32 runtime·kevent(int kq, Kevent *changelist, int nchanges, Kevent *eventlist, int nevents, Timespec *timeout);
+TEXT runtime·kevent(SB),NOSPLIT,$0
+	MOVL	fd+0(FP), DI
+	MOVQ	ev1+8(FP), SI
+	MOVL	nev1+16(FP), DX
+	MOVQ	ev2+24(FP), R10
+	MOVL	nev2+32(FP), R8
+	MOVQ	ts+40(FP), R9
+	MOVL	$363, AX
+	SYSCALL
+	JCC	2(PC)
+	NEGQ	AX
+	MOVL	AX, ret+48(FP)
+	RET
+
+// void runtime·closeonexec(int32 fd);
+TEXT runtime·closeonexec(SB),NOSPLIT,$0
+	MOVL	fd+0(FP), DI	// fd
+	MOVQ	$2, SI		// F_SETFD
+	MOVQ	$1, DX		// FD_CLOEXEC
+	MOVL	$92, AX		// fcntl
+	SYSCALL
+	RET
diff --git a/src/runtime/sys_freebsd_arm.s b/src/runtime/sys_freebsd_arm.s
new file mode 100644
index 0000000..d875138
--- /dev/null
+++ b/src/runtime/sys_freebsd_arm.s
@@ -0,0 +1,382 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+//
+// System calls and other sys.stuff for ARM, FreeBSD
+// /usr/src/sys/kern/syscalls.master for syscall numbers.
+//
+
+#include "zasm_GOOS_GOARCH.h"
+#include "textflag.h"
+
+// for EABI, as we don't support OABI
+#define SYS_BASE 0x0
+
+#define SYS_exit (SYS_BASE + 1)
+#define SYS_read (SYS_BASE + 3)
+#define SYS_write (SYS_BASE + 4)
+#define SYS_open (SYS_BASE + 5)
+#define SYS_close (SYS_BASE + 6)
+#define SYS_sigaltstack (SYS_BASE + 53)
+#define SYS_munmap (SYS_BASE + 73)
+#define SYS_madvise (SYS_BASE + 75)
+#define SYS_setitimer (SYS_BASE + 83)
+#define SYS_fcntl (SYS_BASE + 92)
+#define SYS_getrlimit (SYS_BASE + 194)
+#define SYS___sysctl (SYS_BASE + 202)
+#define SYS_nanosleep (SYS_BASE + 240)
+#define SYS_clock_gettime (SYS_BASE + 232)
+#define SYS_sched_yield (SYS_BASE + 331)
+#define SYS_sigprocmask (SYS_BASE + 340)
+#define SYS_kqueue (SYS_BASE + 362)
+#define SYS_kevent (SYS_BASE + 363)
+#define SYS_sigaction (SYS_BASE + 416)
+#define SYS_thr_exit (SYS_BASE + 431)
+#define SYS_thr_self (SYS_BASE + 432)
+#define SYS_thr_kill (SYS_BASE + 433)
+#define SYS__umtx_op (SYS_BASE + 454)
+#define SYS_thr_new (SYS_BASE + 455)
+#define SYS_mmap (SYS_BASE + 477) 
+	
+TEXT runtime·sys_umtx_op(SB),NOSPLIT,$0
+	MOVW 0(FP), R0
+	MOVW 4(FP), R1
+	MOVW 8(FP), R2
+	MOVW 12(FP), R3
+	ADD $20, R13 // arg 5 is passed on stack
+	MOVW $SYS__umtx_op, R7
+	SWI $0
+	SUB $20, R13
+	// BCS error
+	MOVW	R0, ret+20(FP)
+	RET
+
+TEXT runtime·thr_new(SB),NOSPLIT,$0
+	MOVW 0(FP), R0
+	MOVW 4(FP), R1
+	MOVW $SYS_thr_new, R7
+	SWI $0
+	RET
+
+TEXT runtime·thr_start(SB),NOSPLIT,$0
+	// set up g
+	MOVW m_g0(R0), g
+	MOVW R0, g_m(g)
+	BL runtime·emptyfunc(SB) // fault if stack check is wrong
+	BL runtime·mstart(SB)
+
+	MOVW $2, R8  // crash (not reached)
+	MOVW R8, (R8)
+	RET
+
+// Exit the entire program (like C exit)
+TEXT runtime·exit(SB),NOSPLIT,$-8
+	MOVW 0(FP), R0	// arg 1 exit status
+	MOVW $SYS_exit, R7
+	SWI $0
+	MOVW.CS $0, R8 // crash on syscall failure
+	MOVW.CS R8, (R8)
+	RET
+
+TEXT runtime·exit1(SB),NOSPLIT,$-8
+	MOVW 0(FP), R0	// arg 1 exit status
+	MOVW $SYS_thr_exit, R7	
+	SWI $0
+	MOVW.CS $0, R8 // crash on syscall failure
+	MOVW.CS R8, (R8)
+	RET
+
+TEXT runtime·open(SB),NOSPLIT,$-8
+	MOVW 0(FP), R0	// arg 1 name
+	MOVW 4(FP), R1	// arg 2 mode
+	MOVW 8(FP), R2	// arg 3 perm
+	MOVW $SYS_open, R7
+	SWI $0
+	MOVW	R0, ret+12(FP)
+	RET
+
+TEXT runtime·read(SB),NOSPLIT,$-8
+	MOVW 0(FP), R0	// arg 1 fd
+	MOVW 4(FP), R1	// arg 2 buf
+	MOVW 8(FP), R2	// arg 3 count
+	MOVW $SYS_read, R7
+	SWI $0
+	MOVW	R0, ret+12(FP)
+	RET
+
+TEXT runtime·write(SB),NOSPLIT,$-8
+	MOVW 0(FP), R0	// arg 1 fd
+	MOVW 4(FP), R1	// arg 2 buf
+	MOVW 8(FP), R2	// arg 3 count
+	MOVW $SYS_write, R7
+	SWI $0
+	MOVW	R0, ret+12(FP)
+	RET
+
+TEXT runtime·close(SB),NOSPLIT,$-8
+	MOVW 0(FP), R0	// arg 1 fd
+	MOVW $SYS_close, R7
+	SWI $0
+	MOVW	R0, ret+4(FP)
+	RET
+
+TEXT runtime·getrlimit(SB),NOSPLIT,$-8
+	MOVW 0(FP), R0
+	MOVW 4(FP), R1
+	MOVW $SYS_getrlimit, R7
+	SWI $0
+	MOVW	R0, ret+8(FP)
+	RET
+
+TEXT runtime·raise(SB),NOSPLIT,$8
+	// thr_self(&4(R13))
+	MOVW $4(R13), R0 // arg 1 &4(R13)
+	MOVW $SYS_thr_self, R7
+	SWI $0
+	// thr_kill(self, SIGPIPE)
+	MOVW 4(R13), R0	// arg 1 id
+	MOVW sig+0(FP), R1	// arg 2 - signal
+	MOVW $SYS_thr_kill, R7
+	SWI $0
+	RET
+
+TEXT runtime·setitimer(SB), NOSPLIT, $-8
+	MOVW 0(FP), R0
+	MOVW 4(FP), R1
+	MOVW 8(FP), R2
+	MOVW $SYS_setitimer, R7
+	SWI $0
+	RET
+
+// func now() (sec int64, nsec int32)
+TEXT time·now(SB), NOSPLIT, $32
+	MOVW $0, R0 // CLOCK_REALTIME
+	MOVW $8(R13), R1
+	MOVW $SYS_clock_gettime, R7
+	SWI $0
+
+	MOVW 8(R13), R0 // sec.low
+	MOVW 12(R13), R1 // sec.high
+	MOVW 16(R13), R2 // nsec
+
+	MOVW R0, 0(FP)
+	MOVW R1, 4(FP)
+	MOVW R2, 8(FP)
+	RET
+
+// int64 nanotime(void) so really
+// void nanotime(int64 *nsec)
+TEXT runtime·nanotime(SB), NOSPLIT, $32
+	// We can use CLOCK_MONOTONIC_FAST here when we drop
+	// support for FreeBSD 8-STABLE.
+	MOVW $4, R0 // CLOCK_MONOTONIC
+	MOVW $8(R13), R1
+	MOVW $SYS_clock_gettime, R7
+	SWI $0
+
+	MOVW 8(R13), R0 // sec.low
+	MOVW 12(R13), R4 // sec.high
+	MOVW 16(R13), R2 // nsec
+
+	MOVW $1000000000, R3
+	MULLU R0, R3, (R1, R0)
+	MUL R3, R4
+	ADD.S R2, R0
+	ADC R4, R1
+
+	MOVW R0, ret_lo+0(FP)
+	MOVW R1, ret_hi+4(FP)
+	RET
+
+TEXT runtime·sigaction(SB),NOSPLIT,$-8
+	MOVW 0(FP), R0		// arg 1 sig
+	MOVW 4(FP), R1		// arg 2 act
+	MOVW 8(FP), R2		// arg 3 oact
+	MOVW $SYS_sigaction, R7
+	SWI $0
+	MOVW.CS $0, R8 // crash on syscall failure
+	MOVW.CS R8, (R8)
+	RET
+
+TEXT runtime·sigtramp(SB),NOSPLIT,$24
+	// this might be called in external code context,
+	// where g is not set.
+	// first save R0, because runtime·load_g will clobber it
+	MOVW	R0, 4(R13) // signum
+	MOVB	runtime·iscgo(SB), R0
+	CMP 	$0, R0
+	BL.NE	runtime·load_g(SB)
+
+	CMP $0, g
+	BNE 4(PC)
+	// signal number is already prepared in 4(R13)
+	MOVW $runtime·badsignal(SB), R11
+	BL (R11)
+	RET
+
+	// save g
+	MOVW g, R4
+	MOVW g, 20(R13)
+
+	// g = m->signal
+	MOVW g_m(g), R8
+	MOVW m_gsignal(R8), g
+
+	// R0 is already saved
+	MOVW R1, 8(R13) // info
+	MOVW R2, 12(R13) // context
+	MOVW R4, 16(R13) // oldg
+
+	BL runtime·sighandler(SB)
+
+	// restore g
+	MOVW 20(R13), g
+	RET
+
+TEXT runtime·mmap(SB),NOSPLIT,$16
+	MOVW 0(FP), R0		// arg 1 addr
+	MOVW 4(FP), R1		// arg 2 len
+	MOVW 8(FP), R2		// arg 3 prot
+	MOVW 12(FP), R3		// arg 4 flags
+	// arg 5 (fid) and arg6 (offset_lo, offset_hi) are passed on stack
+	// note the C runtime only passes the 32-bit offset_lo to us
+	MOVW 16(FP), R4		// arg 5
+	MOVW R4, 4(R13)
+	MOVW 20(FP), R5		// arg 6 lower 32-bit
+	// the word at 8(R13) is skipped due to 64-bit argument alignment.
+	MOVW R5, 12(R13)
+	MOVW $0, R6 		// higher 32-bit for arg 6
+	MOVW R6, 16(R13)
+	ADD $4, R13
+	MOVW $SYS_mmap, R7
+	SWI $0
+	SUB $4, R13
+	// TODO(dfc) error checking ?
+	MOVW	R0, ret+24(FP)
+	RET
+
+TEXT runtime·munmap(SB),NOSPLIT,$0
+	MOVW 0(FP), R0		// arg 1 addr
+	MOVW 4(FP), R1		// arg 2 len
+	MOVW $SYS_munmap, R7
+	SWI $0
+	MOVW.CS $0, R8 // crash on syscall failure
+	MOVW.CS R8, (R8)
+	RET
+
+TEXT runtime·madvise(SB),NOSPLIT,$0
+	MOVW 0(FP), R0		// arg 1 addr
+	MOVW 4(FP), R1		// arg 2 len
+	MOVW 8(FP), R2		// arg 3 flags
+	MOVW $SYS_madvise, R7
+	SWI $0
+	// ignore failure - maybe pages are locked
+	RET
+	
+TEXT runtime·sigaltstack(SB),NOSPLIT,$-8
+	MOVW new+0(FP), R0
+	MOVW old+4(FP), R1
+	MOVW $SYS_sigaltstack, R7
+	SWI $0
+	MOVW.CS $0, R8 // crash on syscall failure
+	MOVW.CS R8, (R8)
+	RET
+
+TEXT runtime·usleep(SB),NOSPLIT,$16
+	MOVW usec+0(FP), R0
+	MOVW R0, R2
+	MOVW $1000000, R1
+	DIV R1, R0
+	// 0(R13) is the saved LR, don't use it
+	MOVW R0, 4(R13) // tv_sec.low
+	MOVW $0, R0
+	MOVW R0, 8(R13) // tv_sec.high
+	MOD R1, R2
+	MOVW $1000, R1
+	MUL R1, R2
+	MOVW R2, 12(R13) // tv_nsec
+
+	MOVW $4(R13), R0 // arg 1 - rqtp
+	MOVW $0, R1      // arg 2 - rmtp
+	MOVW $SYS_nanosleep, R7
+	SWI $0
+	RET
+
+TEXT runtime·sysctl(SB),NOSPLIT,$0
+	MOVW 0(FP), R0	// arg 1 - name
+	MOVW 4(FP), R1	// arg 2 - namelen
+	MOVW 8(FP), R2	// arg 3 - old
+	MOVW 12(FP), R3	// arg 4 - oldlenp
+	// arg 5 (newp) and arg 6 (newlen) are passed on stack
+	ADD $20, R13
+	MOVW $SYS___sysctl, R7
+	SWI $0
+	SUB.CS $0, R0, R0
+	SUB $20, R13
+	MOVW	R0, ret+24(FP)
+	RET
+
+TEXT runtime·osyield(SB),NOSPLIT,$-4
+	MOVW $SYS_sched_yield, R7
+	SWI $0
+	RET
+
+TEXT runtime·sigprocmask(SB),NOSPLIT,$0
+	MOVW $3, R0	// arg 1 - how (SIG_SETMASK)
+	MOVW 0(FP), R1	// arg 2 - set
+	MOVW 4(FP), R2	// arg 3 - oset
+	MOVW $SYS_sigprocmask, R7
+	SWI $0
+	MOVW.CS $0, R8 // crash on syscall failure
+	MOVW.CS R8, (R8)
+	RET
+
+// int32 runtime·kqueue(void)
+TEXT runtime·kqueue(SB),NOSPLIT,$0
+	MOVW $SYS_kqueue, R7
+	SWI $0
+	RSB.CS $0, R0
+	MOVW	R0, ret+0(FP)
+	RET
+
+// int32 runtime·kevent(int kq, Kevent *changelist, int nchanges, Kevent *eventlist, int nevents, Timespec *timeout)
+TEXT runtime·kevent(SB),NOSPLIT,$0
+	MOVW 0(FP), R0	// kq
+	MOVW 4(FP), R1	// changelist
+	MOVW 8(FP), R2	// nchanges
+	MOVW 12(FP), R3	// eventlist
+	ADD $20, R13	// pass arg 5 and 6 on stack
+	MOVW $SYS_kevent, R7
+	SWI $0
+	RSB.CS $0, R0
+	SUB $20, R13
+	MOVW	R0, ret+24(FP)
+	RET
+
+// void runtime·closeonexec(int32 fd)
+TEXT runtime·closeonexec(SB),NOSPLIT,$0
+	MOVW 0(FP), R0	// fd
+	MOVW $2, R1	// F_SETFD
+	MOVW $1, R2	// FD_CLOEXEC
+	MOVW $SYS_fcntl, R7
+	SWI $0
+	RET
+
+TEXT runtime·casp(SB),NOSPLIT,$0
+	B	runtime·cas(SB)
+
+// TODO(minux): this is only valid for ARMv6+
+// bool armcas(int32 *val, int32 old, int32 new)
+// Atomically:
+//	if(*val == old){
+//		*val = new;
+//		return 1;
+//	}else
+//		return 0;
+TEXT runtime·cas(SB),NOSPLIT,$0
+	B runtime·armcas(SB)
+
+// TODO(minux): this only supports ARMv6K+.
+TEXT runtime·read_tls_fallback(SB),NOSPLIT,$-4
+	WORD $0xee1d0f70 // mrc p15, 0, r0, c13, c0, 3
+	RET
diff --git a/src/runtime/sys_linux_386.s b/src/runtime/sys_linux_386.s
new file mode 100644
index 0000000..0f6d4bb
--- /dev/null
+++ b/src/runtime/sys_linux_386.s
@@ -0,0 +1,489 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//
+// System calls and other sys.stuff for 386, Linux
+//
+
+#include "zasm_GOOS_GOARCH.h"
+#include "textflag.h"
+
+TEXT runtime·exit(SB),NOSPLIT,$0
+	MOVL	$252, AX	// syscall number
+	MOVL	code+0(FP), BX
+	CALL	*runtime·_vdso(SB)
+	INT $3	// not reached
+	RET
+
+TEXT runtime·exit1(SB),NOSPLIT,$0
+	MOVL	$1, AX	// exit - exit the current os thread
+	MOVL	code+0(FP), BX
+	CALL	*runtime·_vdso(SB)
+	INT $3	// not reached
+	RET
+
+TEXT runtime·open(SB),NOSPLIT,$0
+	MOVL	$5, AX		// syscall - open
+	MOVL	name+0(FP), BX
+	MOVL	mode+4(FP), CX
+	MOVL	perm+8(FP), DX
+	CALL	*runtime·_vdso(SB)
+	MOVL	AX, ret+12(FP)
+	RET
+
+TEXT runtime·close(SB),NOSPLIT,$0
+	MOVL	$6, AX		// syscall - close
+	MOVL	fd+0(FP), BX
+	CALL	*runtime·_vdso(SB)
+	MOVL	AX, ret+4(FP)
+	RET
+
+TEXT runtime·write(SB),NOSPLIT,$0
+	MOVL	$4, AX		// syscall - write
+	MOVL	fd+0(FP), BX
+	MOVL	p+4(FP), CX
+	MOVL	n+8(FP), DX
+	CALL	*runtime·_vdso(SB)
+	MOVL	AX, ret+12(FP)
+	RET
+
+TEXT runtime·read(SB),NOSPLIT,$0
+	MOVL	$3, AX		// syscall - read
+	MOVL	fd+0(FP), BX
+	MOVL	p+4(FP), CX
+	MOVL	n+8(FP), DX
+	CALL	*runtime·_vdso(SB)
+	MOVL	AX, ret+12(FP)
+	RET
+
+TEXT runtime·getrlimit(SB),NOSPLIT,$0
+	MOVL	$191, AX		// syscall - ugetrlimit
+	MOVL	kind+0(FP), BX
+	MOVL	limit+4(FP), CX
+	CALL	*runtime·_vdso(SB)
+	MOVL	AX, ret+8(FP)
+	RET
+
+TEXT runtime·usleep(SB),NOSPLIT,$8
+	MOVL	$0, DX
+	MOVL	usec+0(FP), AX
+	MOVL	$1000000, CX
+	DIVL	CX
+	MOVL	AX, 0(SP)
+	MOVL	DX, 4(SP)
+
+	// select(0, 0, 0, 0, &tv)
+	MOVL	$142, AX
+	MOVL	$0, BX
+	MOVL	$0, CX
+	MOVL	$0, DX
+	MOVL	$0, SI
+	LEAL	0(SP), DI
+	CALL	*runtime·_vdso(SB)
+	RET
+
+TEXT runtime·raise(SB),NOSPLIT,$12
+	MOVL	$224, AX	// syscall - gettid
+	CALL	*runtime·_vdso(SB)
+	MOVL	AX, BX	// arg 1 tid
+	MOVL	sig+0(FP), CX	// arg 2 signal
+	MOVL	$238, AX	// syscall - tkill
+	CALL	*runtime·_vdso(SB)
+	RET
+
+TEXT runtime·setitimer(SB),NOSPLIT,$0-12
+	MOVL	$104, AX			// syscall - setitimer
+	MOVL	mode+0(FP), BX
+	MOVL	new+4(FP), CX
+	MOVL	old+8(FP), DX
+	CALL	*runtime·_vdso(SB)
+	RET
+
+TEXT runtime·mincore(SB),NOSPLIT,$0-16
+	MOVL	$218, AX			// syscall - mincore
+	MOVL	addr+0(FP), BX
+	MOVL	n+4(FP), CX
+	MOVL	dst+8(FP), DX
+	CALL	*runtime·_vdso(SB)
+	MOVL	AX, ret+12(FP)
+	RET
+
+// func now() (sec int64, nsec int32)
+TEXT time·now(SB), NOSPLIT, $32
+	MOVL	$265, AX			// syscall - clock_gettime
+	MOVL	$0, BX		// CLOCK_REALTIME
+	LEAL	8(SP), CX
+	MOVL	$0, DX
+	CALL	*runtime·_vdso(SB)
+	MOVL	8(SP), AX	// sec
+	MOVL	12(SP), BX	// nsec
+
+	// sec is in AX, nsec in BX
+	MOVL	AX, sec+0(FP)
+	MOVL	$0, sec+4(FP)
+	MOVL	BX, nsec+8(FP)
+	RET
+
+// int64 nanotime(void) so really
+// void nanotime(int64 *nsec)
+TEXT runtime·nanotime(SB), NOSPLIT, $32
+	MOVL	$265, AX			// syscall - clock_gettime
+	MOVL	$1, BX		// CLOCK_MONOTONIC
+	LEAL	8(SP), CX
+	MOVL	$0, DX
+	CALL	*runtime·_vdso(SB)
+	MOVL	8(SP), AX	// sec
+	MOVL	12(SP), BX	// nsec
+
+	// sec is in AX, nsec in BX
+	// convert to DX:AX nsec
+	MOVL	$1000000000, CX
+	MULL	CX
+	ADDL	BX, AX
+	ADCL	$0, DX
+
+	MOVL	AX, ret_lo+0(FP)
+	MOVL	DX, ret_hi+4(FP)
+	RET
+
+TEXT runtime·rtsigprocmask(SB),NOSPLIT,$0
+	MOVL	$175, AX		// syscall entry
+	MOVL	sig+0(FP), BX
+	MOVL	new+4(FP), CX
+	MOVL	old+8(FP), DX
+	MOVL	size+12(FP), SI
+	CALL	*runtime·_vdso(SB)
+	CMPL	AX, $0xfffff001
+	JLS	2(PC)
+	INT $3
+	RET
+
+TEXT runtime·rt_sigaction(SB),NOSPLIT,$0
+	MOVL	$174, AX		// syscall - rt_sigaction
+	MOVL	sig+0(FP), BX
+	MOVL	new+4(FP), CX
+	MOVL	old+8(FP), DX
+	MOVL	size+12(FP), SI
+	CALL	*runtime·_vdso(SB)
+	MOVL	AX, ret+16(FP)
+	RET
+
+TEXT runtime·sigtramp(SB),NOSPLIT,$44
+	get_tls(CX)
+
+	// check that g exists
+	MOVL	g(CX), DI
+	CMPL	DI, $0
+	JNE	6(PC)
+	MOVL	sig+0(FP), BX
+	MOVL	BX, 0(SP)
+	MOVL	$runtime·badsignal(SB), AX
+	CALL	AX
+	RET
+
+	// save g
+	MOVL	DI, 20(SP)
+
+	// g = m->gsignal
+	MOVL	g_m(DI), BX
+	MOVL	m_gsignal(BX), BX
+	MOVL	BX, g(CX)
+
+	// copy arguments for call to sighandler
+	MOVL	sig+0(FP), BX
+	MOVL	BX, 0(SP)
+	MOVL	info+4(FP), BX
+	MOVL	BX, 4(SP)
+	MOVL	context+8(FP), BX
+	MOVL	BX, 8(SP)
+	MOVL	DI, 12(SP)
+
+	CALL	runtime·sighandler(SB)
+
+	// restore g
+	get_tls(CX)
+	MOVL	20(SP), BX
+	MOVL	BX, g(CX)
+
+	RET
+
+TEXT runtime·sigreturn(SB),NOSPLIT,$0
+	MOVL	$173, AX	// rt_sigreturn
+	// Sigreturn expects same SP as signal handler,
+	// so cannot CALL *runtime._vsdo(SB) here.
+	INT	$0x80
+	INT $3	// not reached
+	RET
+
+TEXT runtime·mmap(SB),NOSPLIT,$0
+	MOVL	$192, AX	// mmap2
+	MOVL	addr+0(FP), BX
+	MOVL	n+4(FP), CX
+	MOVL	prot+8(FP), DX
+	MOVL	flags+12(FP), SI
+	MOVL	fd+16(FP), DI
+	MOVL	off+20(FP), BP
+	SHRL	$12, BP
+	CALL	*runtime·_vdso(SB)
+	CMPL	AX, $0xfffff001
+	JLS	3(PC)
+	NOTL	AX
+	INCL	AX
+	MOVL	AX, ret+24(FP)
+	RET
+
+TEXT runtime·munmap(SB),NOSPLIT,$0
+	MOVL	$91, AX	// munmap
+	MOVL	addr+0(FP), BX
+	MOVL	n+4(FP), CX
+	CALL	*runtime·_vdso(SB)
+	CMPL	AX, $0xfffff001
+	JLS	2(PC)
+	INT $3
+	RET
+
+TEXT runtime·madvise(SB),NOSPLIT,$0
+	MOVL	$219, AX	// madvise
+	MOVL	addr+0(FP), BX
+	MOVL	n+4(FP), CX
+	MOVL	flags+8(FP), DX
+	CALL	*runtime·_vdso(SB)
+	// ignore failure - maybe pages are locked
+	RET
+
+// int32 futex(int32 *uaddr, int32 op, int32 val,
+//	struct timespec *timeout, int32 *uaddr2, int32 val2);
+TEXT runtime·futex(SB),NOSPLIT,$0
+	MOVL	$240, AX	// futex
+	MOVL	addr+0(FP), BX
+	MOVL	op+4(FP), CX
+	MOVL	val+8(FP), DX
+	MOVL	ts+12(FP), SI
+	MOVL	addr2+16(FP), DI
+	MOVL	val3+20(FP), BP
+	CALL	*runtime·_vdso(SB)
+	MOVL	AX, ret+24(FP)
+	RET
+
+// int32 clone(int32 flags, void *stack, M *mp, G *gp, void (*fn)(void));
+TEXT runtime·clone(SB),NOSPLIT,$0
+	MOVL	$120, AX	// clone
+	MOVL	flags+4(SP), BX
+	MOVL	stack+8(SP), CX
+	MOVL	$0, DX	// parent tid ptr
+	MOVL	$0, DI	// child tid ptr
+
+	// Copy mp, gp, fn off parent stack for use by child.
+	SUBL	$16, CX
+	MOVL	mm+12(SP), SI
+	MOVL	SI, 0(CX)
+	MOVL	gg+16(SP), SI
+	MOVL	SI, 4(CX)
+	MOVL	fn+20(SP), SI
+	MOVL	SI, 8(CX)
+	MOVL	$1234, 12(CX)
+
+	// cannot use CALL *runtime·_vdso(SB) here, because
+	// the stack changes during the system call (after
+	// CALL *runtime·_vdso(SB), the child is still using
+	// the parent's stack when executing its RET instruction).
+	INT	$0x80
+
+	// In parent, return.
+	CMPL	AX, $0
+	JEQ	3(PC)
+	MOVL	AX, ret+20(FP)
+	RET
+
+	// Paranoia: check that SP is as we expect.
+	MOVL	mm+8(FP), BP
+	CMPL	BP, $1234
+	JEQ	2(PC)
+	INT	$3
+
+	// Initialize AX to Linux tid
+	MOVL	$224, AX
+	CALL	*runtime·_vdso(SB)
+
+	// In child on new stack.  Reload registers (paranoia).
+	MOVL	0(SP), BX	// m
+	MOVL	flags+0(FP), DX	// g
+	MOVL	stk+4(FP), SI	// fn
+
+	MOVL	AX, m_procid(BX)	// save tid as m->procid
+
+	// set up ldt 7+id to point at m->tls.
+	// newosproc left the id in tls[0].
+	LEAL	m_tls(BX), BP
+	MOVL	0(BP), DI
+	ADDL	$7, DI	// m0 is LDT#7. count up.
+	// setldt(tls#, &tls, sizeof tls)
+	PUSHAL	// save registers
+	PUSHL	$32	// sizeof tls
+	PUSHL	BP	// &tls
+	PUSHL	DI	// tls #
+	CALL	runtime·setldt(SB)
+	POPL	AX
+	POPL	AX
+	POPL	AX
+	POPAL
+
+	// Now segment is established.  Initialize m, g.
+	get_tls(AX)
+	MOVL	DX, g(AX)
+	MOVL	BX, g_m(DX)
+
+	CALL	runtime·stackcheck(SB)	// smashes AX, CX
+	MOVL	0(DX), DX	// paranoia; check they are not nil
+	MOVL	0(BX), BX
+
+	// more paranoia; check that stack splitting code works
+	PUSHAL
+	CALL	runtime·emptyfunc(SB)
+	POPAL
+
+	CALL	SI	// fn()
+	CALL	runtime·exit1(SB)
+	MOVL	$0x1234, 0x1005
+
+TEXT runtime·sigaltstack(SB),NOSPLIT,$-8
+	MOVL	$186, AX	// sigaltstack
+	MOVL	new+4(SP), BX
+	MOVL	old+8(SP), CX
+	CALL	*runtime·_vdso(SB)
+	CMPL	AX, $0xfffff001
+	JLS	2(PC)
+	INT	$3
+	RET
+
+// <asm-i386/ldt.h>
+// struct user_desc {
+//	unsigned int  entry_number;
+//	unsigned long base_addr;
+//	unsigned int  limit;
+//	unsigned int  seg_32bit:1;
+//	unsigned int  contents:2;
+//	unsigned int  read_exec_only:1;
+//	unsigned int  limit_in_pages:1;
+//	unsigned int  seg_not_present:1;
+//	unsigned int  useable:1;
+// };
+#define SEG_32BIT 0x01
+// contents are the 2 bits 0x02 and 0x04.
+#define CONTENTS_DATA 0x00
+#define CONTENTS_STACK 0x02
+#define CONTENTS_CODE 0x04
+#define READ_EXEC_ONLY 0x08
+#define LIMIT_IN_PAGES 0x10
+#define SEG_NOT_PRESENT 0x20
+#define USEABLE 0x40
+
+// setldt(int entry, int address, int limit)
+TEXT runtime·setldt(SB),NOSPLIT,$32
+	MOVL	entry+0(FP), BX	// entry
+	MOVL	address+4(FP), CX	// base address
+
+	/*
+	 * When linking against the system libraries,
+	 * we use its pthread_create and let it set up %gs
+	 * for us.  When we do that, the private storage
+	 * we get is not at 0(GS), 4(GS), but -8(GS), -4(GS).
+	 * To insulate the rest of the tool chain from this
+	 * ugliness, 8l rewrites 0(TLS) into -8(GS) for us.
+	 * To accommodate that rewrite, we translate
+	 * the address here and bump the limit to 0xffffffff (no limit)
+	 * so that -8(GS) maps to 0(address).
+	 * Also, the final 0(GS) (current 8(CX)) has to point
+	 * to itself, to mimic ELF.
+	 */
+	ADDL	$0x8, CX	// address
+	MOVL	CX, 0(CX)
+
+	// set up user_desc
+	LEAL	16(SP), AX	// struct user_desc
+	MOVL	BX, 0(AX)
+	MOVL	CX, 4(AX)
+	MOVL	$0xfffff, 8(AX)
+	MOVL	$(SEG_32BIT|LIMIT_IN_PAGES|USEABLE|CONTENTS_DATA), 12(AX)	// flag bits
+
+	// call modify_ldt
+	MOVL	$1, BX	// func = 1 (write)
+	MOVL	AX, CX	// user_desc
+	MOVL	$16, DX	// sizeof(user_desc)
+	MOVL	$123, AX	// syscall - modify_ldt
+	CALL	*runtime·_vdso(SB)
+
+	// breakpoint on error
+	CMPL AX, $0xfffff001
+	JLS 2(PC)
+	INT $3
+
+	// compute segment selector - (entry*8+7)
+	MOVL	entry+0(FP), AX
+	SHLL	$3, AX
+	ADDL	$7, AX
+	MOVW	AX, GS
+
+	RET
+
+TEXT runtime·osyield(SB),NOSPLIT,$0
+	MOVL	$158, AX
+	CALL	*runtime·_vdso(SB)
+	RET
+
+TEXT runtime·sched_getaffinity(SB),NOSPLIT,$0
+	MOVL	$242, AX		// syscall - sched_getaffinity
+	MOVL	pid+0(FP), BX
+	MOVL	len+4(FP), CX
+	MOVL	buf+8(FP), DX
+	CALL	*runtime·_vdso(SB)
+	MOVL	AX, ret+12(FP)
+	RET
+
+// int32 runtime·epollcreate(int32 size);
+TEXT runtime·epollcreate(SB),NOSPLIT,$0
+	MOVL    $254, AX
+	MOVL	size+0(FP), BX
+	CALL	*runtime·_vdso(SB)
+	MOVL	AX, ret+4(FP)
+	RET
+
+// int32 runtime·epollcreate1(int32 flags);
+TEXT runtime·epollcreate1(SB),NOSPLIT,$0
+	MOVL    $329, AX
+	MOVL	flags+0(FP), BX
+	CALL	*runtime·_vdso(SB)
+	MOVL	AX, ret+4(FP)
+	RET
+
+// func epollctl(epfd, op, fd int32, ev *epollEvent) int
+TEXT runtime·epollctl(SB),NOSPLIT,$0
+	MOVL	$255, AX
+	MOVL	epfd+0(FP), BX
+	MOVL	op+4(FP), CX
+	MOVL	fd+8(FP), DX
+	MOVL	ev+12(FP), SI
+	CALL	*runtime·_vdso(SB)
+	MOVL	AX, ret+16(FP)
+	RET
+
+// int32 runtime·epollwait(int32 epfd, EpollEvent *ev, int32 nev, int32 timeout);
+TEXT runtime·epollwait(SB),NOSPLIT,$0
+	MOVL	$256, AX
+	MOVL	epfd+0(FP), BX
+	MOVL	ev+4(FP), CX
+	MOVL	nev+8(FP), DX
+	MOVL	timeout+12(FP), SI
+	CALL	*runtime·_vdso(SB)
+	MOVL	AX, ret+16(FP)
+	RET
+
+// void runtime·closeonexec(int32 fd);
+TEXT runtime·closeonexec(SB),NOSPLIT,$0
+	MOVL	$55, AX  // fcntl
+	MOVL	fd+0(FP), BX  // fd
+	MOVL	$2, CX  // F_SETFD
+	MOVL	$1, DX  // FD_CLOEXEC
+	CALL	*runtime·_vdso(SB)
+	RET
diff --git a/src/runtime/sys_linux_amd64.s b/src/runtime/sys_linux_amd64.s
new file mode 100644
index 0000000..33b91e8
--- /dev/null
+++ b/src/runtime/sys_linux_amd64.s
@@ -0,0 +1,410 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//
+// System calls and other sys.stuff for AMD64, Linux
+//
+
+#include "zasm_GOOS_GOARCH.h"
+#include "textflag.h"
+
+TEXT runtime·exit(SB),NOSPLIT,$0-4
+	MOVL	code+0(FP), DI
+	MOVL	$231, AX	// exitgroup - force all os threads to exit
+	SYSCALL
+	RET
+
+TEXT runtime·exit1(SB),NOSPLIT,$0-4
+	MOVL	code+0(FP), DI
+	MOVL	$60, AX	// exit - exit the current os thread
+	SYSCALL
+	RET
+
+TEXT runtime·open(SB),NOSPLIT,$0-20
+	MOVQ	name+0(FP), DI
+	MOVL	mode+8(FP), SI
+	MOVL	perm+12(FP), DX
+	MOVL	$2, AX			// syscall entry
+	SYSCALL
+	MOVL	AX, ret+16(FP)
+	RET
+
+TEXT runtime·close(SB),NOSPLIT,$0-12
+	MOVL	fd+0(FP), DI
+	MOVL	$3, AX			// syscall entry
+	SYSCALL
+	MOVL	AX, ret+8(FP)
+	RET
+
+TEXT runtime·write(SB),NOSPLIT,$0-28
+	MOVQ	fd+0(FP), DI
+	MOVQ	p+8(FP), SI
+	MOVL	n+16(FP), DX
+	MOVL	$1, AX			// syscall entry
+	SYSCALL
+	MOVL	AX, ret+24(FP)
+	RET
+
+TEXT runtime·read(SB),NOSPLIT,$0-28
+	MOVL	fd+0(FP), DI
+	MOVQ	p+8(FP), SI
+	MOVL	n+16(FP), DX
+	MOVL	$0, AX			// syscall entry
+	SYSCALL
+	MOVL	AX, ret+24(FP)
+	RET
+
+TEXT runtime·getrlimit(SB),NOSPLIT,$0-20
+	MOVL	kind+0(FP), DI
+	MOVQ	limit+8(FP), SI
+	MOVL	$97, AX			// syscall entry
+	SYSCALL
+	MOVL	AX, ret+16(FP)
+	RET
+
+TEXT runtime·usleep(SB),NOSPLIT,$16
+	MOVL	$0, DX
+	MOVL	usec+0(FP), AX
+	MOVL	$1000000, CX
+	DIVL	CX
+	MOVQ	AX, 0(SP)
+	MOVQ	DX, 8(SP)
+
+	// select(0, 0, 0, 0, &tv)
+	MOVL	$0, DI
+	MOVL	$0, SI
+	MOVL	$0, DX
+	MOVL	$0, R10
+	MOVQ	SP, R8
+	MOVL	$23, AX
+	SYSCALL
+	RET
+
+TEXT runtime·raise(SB),NOSPLIT,$0
+	MOVL	$186, AX	// syscall - gettid
+	SYSCALL
+	MOVL	AX, DI	// arg 1 tid
+	MOVL	sig+0(FP), SI	// arg 2
+	MOVL	$200, AX	// syscall - tkill
+	SYSCALL
+	RET
+
+TEXT runtime·setitimer(SB),NOSPLIT,$0-24
+	MOVL	mode+0(FP), DI
+	MOVQ	new+8(FP), SI
+	MOVQ	old+16(FP), DX
+	MOVL	$38, AX			// syscall entry
+	SYSCALL
+	RET
+
+TEXT runtime·mincore(SB),NOSPLIT,$0-28
+	MOVQ	addr+0(FP), DI
+	MOVQ	n+8(FP), SI
+	MOVQ	dst+16(FP), DX
+	MOVL	$27, AX			// syscall entry
+	SYSCALL
+	MOVL	AX, ret+24(FP)
+	RET
+
+// func now() (sec int64, nsec int32)
+TEXT time·now(SB),NOSPLIT,$16
+	// Be careful. We're calling a function with gcc calling convention here.
+	// We're guaranteed 128 bytes on entry, and we've taken 16, and the
+	// call uses another 8.
+	// That leaves 104 for the gettime code to use. Hope that's enough!
+	MOVQ	runtime·__vdso_clock_gettime_sym(SB), AX
+	CMPQ	AX, $0
+	JEQ	fallback_gtod
+	MOVL	$0, DI // CLOCK_REALTIME
+	LEAQ	0(SP), SI
+	CALL	AX
+	MOVQ	0(SP), AX	// sec
+	MOVQ	8(SP), DX	// nsec
+	MOVQ	AX, sec+0(FP)
+	MOVL	DX, nsec+8(FP)
+	RET
+fallback_gtod:
+	LEAQ	0(SP), DI
+	MOVQ	$0, SI
+	MOVQ	runtime·__vdso_gettimeofday_sym(SB), AX
+	CALL	AX
+	MOVQ	0(SP), AX	// sec
+	MOVL	8(SP), DX	// usec
+	IMULQ	$1000, DX
+	MOVQ	AX, sec+0(FP)
+	MOVL	DX, nsec+8(FP)
+	RET
+
+TEXT runtime·nanotime(SB),NOSPLIT,$16
+	// Duplicate time.now here to avoid using up precious stack space.
+	// See comment above in time.now.
+	MOVQ	runtime·__vdso_clock_gettime_sym(SB), AX
+	CMPQ	AX, $0
+	JEQ	fallback_gtod_nt
+	MOVL	$1, DI // CLOCK_MONOTONIC
+	LEAQ	0(SP), SI
+	CALL	AX
+	MOVQ	0(SP), AX	// sec
+	MOVQ	8(SP), DX	// nsec
+	// sec is in AX, nsec in DX
+	// return nsec in AX
+	IMULQ	$1000000000, AX
+	ADDQ	DX, AX
+	MOVQ	AX, ret+0(FP)
+	RET
+fallback_gtod_nt:
+	LEAQ	0(SP), DI
+	MOVQ	$0, SI
+	MOVQ	runtime·__vdso_gettimeofday_sym(SB), AX
+	CALL	AX
+	MOVQ	0(SP), AX	// sec
+	MOVL	8(SP), DX	// usec
+	IMULQ	$1000, DX
+	// sec is in AX, nsec in DX
+	// return nsec in AX
+	IMULQ	$1000000000, AX
+	ADDQ	DX, AX
+	MOVQ	AX, ret+0(FP)
+	RET
+
+TEXT runtime·rtsigprocmask(SB),NOSPLIT,$0-28
+	MOVL	sig+0(FP), DI
+	MOVQ	new+8(FP), SI
+	MOVQ	old+16(FP), DX
+	MOVL	size+24(FP), R10
+	MOVL	$14, AX			// syscall entry
+	SYSCALL
+	CMPQ	AX, $0xfffffffffffff001
+	JLS	2(PC)
+	MOVL	$0xf1, 0xf1  // crash
+	RET
+
+TEXT runtime·rt_sigaction(SB),NOSPLIT,$0-36
+	MOVQ	sig+0(FP), DI
+	MOVQ	new+8(FP), SI
+	MOVQ	old+16(FP), DX
+	MOVQ	size+24(FP), R10
+	MOVL	$13, AX			// syscall entry
+	SYSCALL
+	MOVL	AX, ret+32(FP)
+	RET
+
+TEXT runtime·sigtramp(SB),NOSPLIT,$64
+	get_tls(BX)
+
+	// check that g exists
+	MOVQ	g(BX), R10
+	CMPQ	R10, $0
+	JNE	5(PC)
+	MOVQ	DI, 0(SP)
+	MOVQ	$runtime·badsignal(SB), AX
+	CALL	AX
+	RET
+
+	// save g
+	MOVQ	R10, 40(SP)
+
+	// g = m->gsignal
+	MOVQ	g_m(R10), BP
+	MOVQ	m_gsignal(BP), BP
+	MOVQ	BP, g(BX)
+
+	MOVQ	DI, 0(SP)
+	MOVQ	SI, 8(SP)
+	MOVQ	DX, 16(SP)
+	MOVQ	R10, 24(SP)
+
+	CALL	runtime·sighandler(SB)
+
+	// restore g
+	get_tls(BX)
+	MOVQ	40(SP), R10
+	MOVQ	R10, g(BX)
+	RET
+
+TEXT runtime·sigreturn(SB),NOSPLIT,$0
+	MOVL	$15, AX	// rt_sigreturn
+	SYSCALL
+	INT $3	// not reached
+
+TEXT runtime·mmap(SB),NOSPLIT,$0
+	MOVQ	addr+0(FP), DI
+	MOVQ	n+8(FP), SI
+	MOVL	prot+16(FP), DX
+	MOVL	flags+20(FP), R10
+	MOVL	fd+24(FP), R8
+	MOVL	off+28(FP), R9
+
+	MOVL	$9, AX			// mmap
+	SYSCALL
+	CMPQ	AX, $0xfffffffffffff001
+	JLS	3(PC)
+	NOTQ	AX
+	INCQ	AX
+	MOVQ	AX, ret+32(FP)
+	RET
+
+TEXT runtime·munmap(SB),NOSPLIT,$0
+	MOVQ	addr+0(FP), DI
+	MOVQ	n+8(FP), SI
+	MOVQ	$11, AX	// munmap
+	SYSCALL
+	CMPQ	AX, $0xfffffffffffff001
+	JLS	2(PC)
+	MOVL	$0xf1, 0xf1  // crash
+	RET
+
+TEXT runtime·madvise(SB),NOSPLIT,$0
+	MOVQ	addr+0(FP), DI
+	MOVQ	n+8(FP), SI
+	MOVL	flags+16(FP), DX
+	MOVQ	$28, AX	// madvise
+	SYSCALL
+	// ignore failure - maybe pages are locked
+	RET
+
+// int64 futex(int32 *uaddr, int32 op, int32 val,
+//	struct timespec *timeout, int32 *uaddr2, int32 val2);
+TEXT runtime·futex(SB),NOSPLIT,$0
+	MOVQ	addr+0(FP), DI
+	MOVL	op+8(FP), SI
+	MOVL	val+12(FP), DX
+	MOVQ	ts+16(FP), R10
+	MOVQ	addr2+24(FP), R8
+	MOVL	val3+32(FP), R9
+	MOVL	$202, AX
+	SYSCALL
+	MOVL	AX, ret+40(FP)
+	RET
+
+// int32 clone(int32 flags, void *stack, M *mp, G *gp, void (*fn)(void));
+TEXT runtime·clone(SB),NOSPLIT,$0
+	MOVL	flags+8(SP), DI
+	MOVQ	stack+16(SP), SI
+
+	// Copy mp, gp, fn off parent stack for use by child.
+	// Careful: Linux system call clobbers CX and R11.
+	MOVQ	mm+24(SP), R8
+	MOVQ	gg+32(SP), R9
+	MOVQ	fn+40(SP), R12
+
+	MOVL	$56, AX
+	SYSCALL
+
+	// In parent, return.
+	CMPQ	AX, $0
+	JEQ	3(PC)
+	MOVL	AX, ret+40(FP)
+	RET
+
+	// In child, on new stack.
+	MOVQ	SI, SP
+
+	// Initialize m->procid to Linux tid
+	MOVL	$186, AX	// gettid
+	SYSCALL
+	MOVQ	AX, m_procid(R8)
+
+	// Set FS to point at m->tls.
+	LEAQ	m_tls(R8), DI
+	CALL	runtime·settls(SB)
+
+	// In child, set up new stack
+	get_tls(CX)
+	MOVQ	R8, g_m(R9)
+	MOVQ	R9, g(CX)
+	CALL	runtime·stackcheck(SB)
+
+	// Call fn
+	CALL	R12
+
+	// It shouldn't return.  If it does, exit
+	MOVL	$111, DI
+	MOVL	$60, AX
+	SYSCALL
+	JMP	-3(PC)	// keep exiting
+
+TEXT runtime·sigaltstack(SB),NOSPLIT,$-8
+	MOVQ	new+8(SP), DI
+	MOVQ	old+16(SP), SI
+	MOVQ	$131, AX
+	SYSCALL
+	CMPQ	AX, $0xfffffffffffff001
+	JLS	2(PC)
+	MOVL	$0xf1, 0xf1  // crash
+	RET
+
+// set tls base to DI
+TEXT runtime·settls(SB),NOSPLIT,$32
+	ADDQ	$16, DI	// ELF wants to use -16(FS), -8(FS)
+
+	MOVQ	DI, SI
+	MOVQ	$0x1002, DI	// ARCH_SET_FS
+	MOVQ	$158, AX	// arch_prctl
+	SYSCALL
+	CMPQ	AX, $0xfffffffffffff001
+	JLS	2(PC)
+	MOVL	$0xf1, 0xf1  // crash
+	RET
+
+TEXT runtime·osyield(SB),NOSPLIT,$0
+	MOVL	$24, AX
+	SYSCALL
+	RET
+
+TEXT runtime·sched_getaffinity(SB),NOSPLIT,$0
+	MOVQ	pid+0(FP), DI
+	MOVQ	len+8(FP), SI
+	MOVQ	buf+16(FP), DX
+	MOVL	$204, AX			// syscall entry
+	SYSCALL
+	MOVL	AX, ret+24(FP)
+	RET
+
+// int32 runtime·epollcreate(int32 size);
+TEXT runtime·epollcreate(SB),NOSPLIT,$0
+	MOVL    size+0(FP), DI
+	MOVL    $213, AX                        // syscall entry
+	SYSCALL
+	MOVL	AX, ret+8(FP)
+	RET
+
+// int32 runtime·epollcreate1(int32 flags);
+TEXT runtime·epollcreate1(SB),NOSPLIT,$0
+	MOVL	flags+0(FP), DI
+	MOVL	$291, AX			// syscall entry
+	SYSCALL
+	MOVL	AX, ret+8(FP)
+	RET
+
+// func epollctl(epfd, op, fd int32, ev *epollEvent) int
+TEXT runtime·epollctl(SB),NOSPLIT,$0
+	MOVL	epfd+0(FP), DI
+	MOVL	op+4(FP), SI
+	MOVL	fd+8(FP), DX
+	MOVQ	ev+16(FP), R10
+	MOVL	$233, AX			// syscall entry
+	SYSCALL
+	MOVL	AX, ret+24(FP)
+	RET
+
+// int32 runtime·epollwait(int32 epfd, EpollEvent *ev, int32 nev, int32 timeout);
+TEXT runtime·epollwait(SB),NOSPLIT,$0
+	MOVL	epfd+0(FP), DI
+	MOVQ	ev+8(FP), SI
+	MOVL	nev+16(FP), DX
+	MOVL	timeout+20(FP), R10
+	MOVL	$232, AX			// syscall entry
+	SYSCALL
+	MOVL	AX, ret+24(FP)
+	RET
+
+// void runtime·closeonexec(int32 fd);
+TEXT runtime·closeonexec(SB),NOSPLIT,$0
+	MOVL    fd+0(FP), DI  // fd
+	MOVQ    $2, SI  // F_SETFD
+	MOVQ    $1, DX  // FD_CLOEXEC
+	MOVL	$72, AX  // fcntl
+	SYSCALL
+	RET
diff --git a/src/runtime/sys_linux_arm.s b/src/runtime/sys_linux_arm.s
new file mode 100644
index 0000000..bd285f3
--- /dev/null
+++ b/src/runtime/sys_linux_arm.s
@@ -0,0 +1,461 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//
+// System calls and other sys.stuff for arm, Linux
+//
+
+#include "zasm_GOOS_GOARCH.h"
+#include "textflag.h"
+
+// for EABI, as we don't support OABI
+#define SYS_BASE 0x0
+
+#define SYS_exit (SYS_BASE + 1)
+#define SYS_read (SYS_BASE + 3)
+#define SYS_write (SYS_BASE + 4)
+#define SYS_open (SYS_BASE + 5)
+#define SYS_close (SYS_BASE + 6)
+#define SYS_gettimeofday (SYS_BASE + 78)
+#define SYS_clone (SYS_BASE + 120)
+#define SYS_rt_sigreturn (SYS_BASE + 173)
+#define SYS_rt_sigaction (SYS_BASE + 174)
+#define SYS_rt_sigprocmask (SYS_BASE + 175)
+#define SYS_sigaltstack (SYS_BASE + 186)
+#define SYS_mmap2 (SYS_BASE + 192)
+#define SYS_futex (SYS_BASE + 240)
+#define SYS_exit_group (SYS_BASE + 248)
+#define SYS_munmap (SYS_BASE + 91)
+#define SYS_madvise (SYS_BASE + 220)
+#define SYS_setitimer (SYS_BASE + 104)
+#define SYS_mincore (SYS_BASE + 219)
+#define SYS_gettid (SYS_BASE + 224)
+#define SYS_tkill (SYS_BASE + 238)
+#define SYS_sched_yield (SYS_BASE + 158)
+#define SYS_select (SYS_BASE + 142) // newselect
+#define SYS_ugetrlimit (SYS_BASE + 191)
+#define SYS_sched_getaffinity (SYS_BASE + 242)
+#define SYS_clock_gettime (SYS_BASE + 263)
+#define SYS_epoll_create (SYS_BASE + 250)
+#define SYS_epoll_ctl (SYS_BASE + 251)
+#define SYS_epoll_wait (SYS_BASE + 252)
+#define SYS_epoll_create1 (SYS_BASE + 357)
+#define SYS_fcntl (SYS_BASE + 55)
+
+#define ARM_BASE (SYS_BASE + 0x0f0000)
+
+TEXT runtime·open(SB),NOSPLIT,$0
+	MOVW	0(FP), R0
+	MOVW	4(FP), R1
+	MOVW	8(FP), R2
+	MOVW	$SYS_open, R7
+	SWI	$0
+	MOVW	R0, ret+12(FP)
+	RET
+
+TEXT runtime·close(SB),NOSPLIT,$0
+	MOVW	0(FP), R0
+	MOVW	$SYS_close, R7
+	SWI	$0
+	MOVW	R0, ret+4(FP)
+	RET
+
+TEXT runtime·write(SB),NOSPLIT,$0
+	MOVW	0(FP), R0
+	MOVW	4(FP), R1
+	MOVW	8(FP), R2
+	MOVW	$SYS_write, R7
+	SWI	$0
+	MOVW	R0, ret+12(FP)
+	RET
+
+TEXT runtime·read(SB),NOSPLIT,$0
+	MOVW	0(FP), R0
+	MOVW	4(FP), R1
+	MOVW	8(FP), R2
+	MOVW	$SYS_read, R7
+	SWI	$0
+	MOVW	R0, ret+12(FP)
+	RET
+
+TEXT runtime·getrlimit(SB),NOSPLIT,$0
+	MOVW	0(FP), R0
+	MOVW	4(FP), R1
+	MOVW	$SYS_ugetrlimit, R7
+	SWI	$0
+	MOVW	R0, ret+8(FP)
+	RET
+
+TEXT runtime·exit(SB),NOSPLIT,$-4
+	MOVW	0(FP), R0
+	MOVW	$SYS_exit_group, R7
+	SWI	$0
+	MOVW	$1234, R0
+	MOVW	$1002, R1
+	MOVW	R0, (R1)	// fail hard
+
+TEXT runtime·exit1(SB),NOSPLIT,$-4
+	MOVW	0(FP), R0
+	MOVW	$SYS_exit, R7
+	SWI	$0
+	MOVW	$1234, R0
+	MOVW	$1003, R1
+	MOVW	R0, (R1)	// fail hard
+
+TEXT	runtime·raise(SB),NOSPLIT,$-4
+	MOVW	$SYS_gettid, R7
+	SWI	$0
+	// arg 1 tid already in R0 from gettid
+	MOVW	sig+0(FP), R1	// arg 2 - signal
+	MOVW	$SYS_tkill, R7
+	SWI	$0
+	RET
+
+TEXT runtime·mmap(SB),NOSPLIT,$0
+	MOVW	0(FP), R0
+	MOVW	4(FP), R1
+	MOVW	8(FP), R2
+	MOVW	12(FP), R3
+	MOVW	16(FP), R4
+	MOVW	20(FP), R5
+	MOVW	$SYS_mmap2, R7
+	SWI	$0
+	MOVW	$0xfffff001, R6
+	CMP		R6, R0
+	RSB.HI	$0, R0
+	MOVW	R0, ret+24(FP)
+	RET
+
+TEXT runtime·munmap(SB),NOSPLIT,$0
+	MOVW	0(FP), R0
+	MOVW	4(FP), R1
+	MOVW	$SYS_munmap, R7
+	SWI	$0
+	MOVW	$0xfffff001, R6
+	CMP 	R6, R0
+	MOVW.HI	$0, R8  // crash on syscall failure
+	MOVW.HI	R8, (R8)
+	RET
+
+TEXT runtime·madvise(SB),NOSPLIT,$0
+	MOVW	0(FP), R0
+	MOVW	4(FP), R1
+	MOVW	8(FP), R2
+	MOVW	$SYS_madvise, R7
+	SWI	$0
+	// ignore failure - maybe pages are locked
+	RET
+
+TEXT runtime·setitimer(SB),NOSPLIT,$0
+	MOVW	0(FP), R0
+	MOVW	4(FP), R1
+	MOVW	8(FP), R2
+	MOVW	$SYS_setitimer, R7
+	SWI	$0
+	RET
+
+TEXT runtime·mincore(SB),NOSPLIT,$0
+	MOVW	0(FP), R0
+	MOVW	4(FP), R1
+	MOVW	8(FP), R2
+	MOVW	$SYS_mincore, R7
+	SWI	$0
+	MOVW	R0, ret+12(FP)
+	RET
+
+TEXT time·now(SB), NOSPLIT, $32
+	MOVW	$0, R0  // CLOCK_REALTIME
+	MOVW	$8(R13), R1  // timespec
+	MOVW	$SYS_clock_gettime, R7
+	SWI	$0
+	
+	MOVW	8(R13), R0  // sec
+	MOVW	12(R13), R2  // nsec
+	
+	MOVW	R0, 0(FP)
+	MOVW	$0, R1
+	MOVW	R1, 4(FP)
+	MOVW	R2, 8(FP)
+	RET	
+
+// int64 nanotime(void)
+TEXT runtime·nanotime(SB),NOSPLIT,$32
+	MOVW	$1, R0  // CLOCK_MONOTONIC
+	MOVW	$8(R13), R1  // timespec
+	MOVW	$SYS_clock_gettime, R7
+	SWI	$0
+	
+	MOVW	8(R13), R0  // sec
+	MOVW	12(R13), R2  // nsec
+	
+	MOVW	$1000000000, R3
+	MULLU	R0, R3, (R1, R0)
+	MOVW	$0, R4
+	ADD.S	R2, R0
+	ADC	R4, R1
+
+	MOVW	R0, ret_lo+0(FP)
+	MOVW	R1, ret_hi+4(FP)
+	RET
+
+// int32 futex(int32 *uaddr, int32 op, int32 val,
+//	struct timespec *timeout, int32 *uaddr2, int32 val2);
+TEXT runtime·futex(SB),NOSPLIT,$0
+	MOVW	4(SP), R0
+	MOVW	8(SP), R1
+	MOVW	12(SP), R2
+	MOVW	16(SP), R3
+	MOVW	20(SP), R4
+	MOVW	24(SP), R5
+	MOVW	$SYS_futex, R7
+	SWI	$0
+	MOVW	R0, ret+24(FP)
+	RET
+
+
+// int32 clone(int32 flags, void *stack, M *mp, G *gp, void (*fn)(void));
+TEXT runtime·clone(SB),NOSPLIT,$0
+	MOVW	flags+0(FP), R0
+	MOVW	stk+4(FP), R1
+	MOVW	$0, R2	// parent tid ptr
+	MOVW	$0, R3	// tls_val
+	MOVW	$0, R4	// child tid ptr
+	MOVW	$0, R5
+
+	// Copy mp, gp, fn off parent stack for use by child.
+	// TODO(kaib): figure out which registers are clobbered by clone and avoid stack copying
+	MOVW	$-16(R1), R1
+	MOVW	mm+8(FP), R6
+	MOVW	R6, 0(R1)
+	MOVW	gg+12(FP), R6
+	MOVW	R6, 4(R1)
+	MOVW	fn+16(FP), R6
+	MOVW	R6, 8(R1)
+	MOVW	$1234, R6
+	MOVW	R6, 12(R1)
+
+	MOVW	$SYS_clone, R7
+	SWI	$0
+
+	// In parent, return.
+	CMP	$0, R0
+	BEQ	3(PC)
+	MOVW	R0, ret+20(FP)
+	RET
+
+	// Paranoia: check that SP is as we expect. Use R13 to avoid linker 'fixup'
+	MOVW	12(R13), R0
+	MOVW	$1234, R1
+	CMP	R0, R1
+	BEQ	2(PC)
+	BL	runtime·abort(SB)
+
+	MOVW	4(R13), g
+	MOVW	0(R13), R8
+	MOVW	R8, g_m(g)
+
+	// paranoia; check they are not nil
+	MOVW	0(R8), R0
+	MOVW	0(g), R0
+
+	BL	runtime·emptyfunc(SB)	// fault if stack check is wrong
+
+	// Initialize m->procid to Linux tid
+	MOVW	$SYS_gettid, R7
+	SWI	$0
+	MOVW	g_m(g), R8
+	MOVW	R0, m_procid(R8)
+
+	// Call fn
+	MOVW	8(R13), R0
+	MOVW	$16(R13), R13
+	BL	(R0)
+
+	MOVW	$0, R0
+	MOVW	R0, 4(R13)
+	BL	runtime·exit1(SB)
+
+	// It shouldn't return
+	MOVW	$1234, R0
+	MOVW	$1005, R1
+	MOVW	R0, (R1)
+
+TEXT runtime·sigaltstack(SB),NOSPLIT,$0
+	MOVW	0(FP), R0
+	MOVW	4(FP), R1
+	MOVW	$SYS_sigaltstack, R7
+	SWI	$0
+	MOVW	$0xfffff001, R6
+	CMP 	R6, R0
+	MOVW.HI	$0, R8  // crash on syscall failure
+	MOVW.HI	R8, (R8)
+	RET
+
+TEXT runtime·sigtramp(SB),NOSPLIT,$24
+	// this might be called in external code context,
+	// where g is not set.
+	// first save R0, because runtime·load_g will clobber it
+	MOVW	R0, 4(R13)
+	MOVB	runtime·iscgo(SB), R0
+	CMP 	$0, R0
+	BL.NE	runtime·load_g(SB)
+
+	CMP 	$0, g
+	BNE 	4(PC)
+	// signal number is already prepared in 4(R13)
+	MOVW  	$runtime·badsignal(SB), R11
+	BL	(R11)
+	RET
+
+	// save g
+	MOVW	g, R3
+	MOVW	g, 20(R13)
+
+	// g = m->gsignal
+	MOVW	g_m(g), R8
+	MOVW	m_gsignal(R8), g
+
+	// copy arguments for call to sighandler
+	// R0 is already saved above
+	MOVW	R1, 8(R13)
+	MOVW	R2, 12(R13)
+	MOVW	R3, 16(R13)
+
+	BL	runtime·sighandler(SB)
+
+	// restore g
+	MOVW	20(R13), g
+
+	RET
+
+TEXT runtime·rtsigprocmask(SB),NOSPLIT,$0
+	MOVW	0(FP), R0
+	MOVW	4(FP), R1
+	MOVW	8(FP), R2
+	MOVW	12(FP), R3
+	MOVW	$SYS_rt_sigprocmask, R7
+	SWI	$0
+	RET
+
+TEXT runtime·rt_sigaction(SB),NOSPLIT,$0
+	MOVW	0(FP), R0
+	MOVW	4(FP), R1
+	MOVW	8(FP), R2
+	MOVW	12(FP), R3
+	MOVW	$SYS_rt_sigaction, R7
+	SWI	$0
+	MOVW	R0, ret+16(FP)
+	RET
+
+TEXT runtime·usleep(SB),NOSPLIT,$12
+	MOVW	usec+0(FP), R0
+	MOVW	R0, R1
+	MOVW	$1000000, R2
+	DIV	R2, R0
+	MOD	R2, R1
+	MOVW	R0, 4(SP)
+	MOVW	R1, 8(SP)
+	MOVW	$0, R0
+	MOVW	$0, R1
+	MOVW	$0, R2
+	MOVW	$0, R3
+	MOVW	$4(SP), R4
+	MOVW	$SYS_select, R7
+	SWI	$0
+	RET
+
+// Use kernel version instead of native armcas in asm_arm.s.
+// See ../sync/atomic/asm_linux_arm.s for details.
+TEXT cas<>(SB),NOSPLIT,$0
+	MOVW	$0xffff0fc0, PC
+
+TEXT runtime·cas(SB),NOSPLIT,$0
+	MOVW	ptr+0(FP), R2
+	MOVW	old+4(FP), R0
+casagain:
+	MOVW	new+8(FP), R1
+	BL	cas<>(SB)
+	BCC	cascheck
+	MOVW	$1, R0
+	MOVB	R0, ret+12(FP)
+	RET
+cascheck:
+	// Kernel lies; double-check.
+	MOVW	ptr+0(FP), R2
+	MOVW	old+4(FP), R0
+	MOVW	0(R2), R3
+	CMP	R0, R3
+	BEQ	casagain
+	MOVW	$0, R0
+	MOVB	R0, ret+12(FP)
+	RET
+
+TEXT runtime·casp(SB),NOSPLIT,$0
+	B	runtime·cas(SB)
+
+TEXT runtime·osyield(SB),NOSPLIT,$0
+	MOVW	$SYS_sched_yield, R7
+	SWI	$0
+	RET
+
+TEXT runtime·sched_getaffinity(SB),NOSPLIT,$0
+	MOVW	0(FP), R0
+	MOVW	4(FP), R1
+	MOVW	8(FP), R2
+	MOVW	$SYS_sched_getaffinity, R7
+	SWI	$0
+	MOVW	R0, ret+12(FP)
+	RET
+
+// int32 runtime·epollcreate(int32 size)
+TEXT runtime·epollcreate(SB),NOSPLIT,$0
+	MOVW	0(FP), R0
+	MOVW	$SYS_epoll_create, R7
+	SWI	$0
+	MOVW	R0, ret+4(FP)
+	RET
+
+// int32 runtime·epollcreate1(int32 flags)
+TEXT runtime·epollcreate1(SB),NOSPLIT,$0
+	MOVW	0(FP), R0
+	MOVW	$SYS_epoll_create1, R7
+	SWI	$0
+	MOVW	R0, ret+4(FP)
+	RET
+
+// func epollctl(epfd, op, fd int32, ev *epollEvent) int
+TEXT runtime·epollctl(SB),NOSPLIT,$0
+	MOVW	epfd+0(FP), R0
+	MOVW	op+4(FP), R1
+	MOVW	fd+8(FP), R2
+	MOVW	ev+12(FP), R3
+	MOVW	$SYS_epoll_ctl, R7
+	SWI	$0
+	MOVW	R0, ret+16(FP)
+	RET
+
+// int32 runtime·epollwait(int32 epfd, EpollEvent *ev, int32 nev, int32 timeout)
+TEXT runtime·epollwait(SB),NOSPLIT,$0
+	MOVW	0(FP), R0
+	MOVW	4(FP), R1
+	MOVW	8(FP), R2
+	MOVW	12(FP), R3
+	MOVW	$SYS_epoll_wait, R7
+	SWI	$0
+	MOVW	R0, ret+16(FP)
+	RET
+
+// void runtime·closeonexec(int32 fd)
+TEXT runtime·closeonexec(SB),NOSPLIT,$0
+	MOVW	0(FP), R0	// fd
+	MOVW	$2, R1	// F_SETFD
+	MOVW	$1, R2	// FD_CLOEXEC
+	MOVW	$SYS_fcntl, R7
+	SWI	$0
+	RET
+
+// b __kuser_get_tls @ 0xffff0fe0
+TEXT runtime·read_tls_fallback(SB),NOSPLIT,$-4
+	MOVW	$0xffff0fe0, R0
+	B	(R0)
diff --git a/src/runtime/sys_nacl_386.s b/src/runtime/sys_nacl_386.s
new file mode 100644
index 0000000..47985f3
--- /dev/null
+++ b/src/runtime/sys_nacl_386.s
@@ -0,0 +1,363 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "zasm_GOOS_GOARCH.h"
+#include "textflag.h"
+#include "syscall_nacl.h"
+
+#define NACL_SYSCALL(code) \
+	MOVL $(0x10000 + ((code)<<5)), AX; CALL AX
+
+TEXT runtime·exit(SB),NOSPLIT,$4
+	MOVL code+0(FP), AX
+	MOVL AX, 0(SP)
+	NACL_SYSCALL(SYS_exit)
+	JMP 0(PC)
+
+TEXT runtime·exit1(SB),NOSPLIT,$4
+	MOVL code+0(FP), AX
+	MOVL AX, 0(SP)
+	NACL_SYSCALL(SYS_thread_exit)
+	RET
+
+TEXT runtime·open(SB),NOSPLIT,$12
+	MOVL name+0(FP), AX
+	MOVL AX, 0(SP)
+	MOVL mode+4(FP), AX
+	MOVL AX, 4(SP)
+	MOVL perm+8(FP), AX
+	MOVL AX, 8(SP)
+	NACL_SYSCALL(SYS_open)
+	MOVL AX, ret+12(FP)
+	RET
+
+TEXT runtime·close(SB),NOSPLIT,$4
+	MOVL fd+0(FP), AX
+	MOVL AX, 0(SP)
+	NACL_SYSCALL(SYS_close)
+	MOVL AX, ret+4(FP)
+	RET
+
+TEXT runtime·read(SB),NOSPLIT,$12
+	MOVL fd+0(FP), AX
+	MOVL AX, 0(SP)
+	MOVL p+4(FP), AX
+	MOVL AX, 4(SP)
+	MOVL n+8(FP), AX
+	MOVL AX, 8(SP)
+	NACL_SYSCALL(SYS_read)
+	MOVL AX, ret+12(FP)
+	RET
+
+TEXT syscall·naclWrite(SB), NOSPLIT, $16-16
+	MOVL arg1+0(FP), DI
+	MOVL arg2+4(FP), SI
+	MOVL arg3+8(FP), DX
+	MOVL DI, 0(SP)
+	MOVL SI, 4(SP)
+	MOVL DX, 8(SP)
+	CALL runtime·write(SB)
+	MOVL AX, ret+16(FP)
+	RET
+
+TEXT runtime·write(SB),NOSPLIT,$12
+	MOVL fd+0(FP), AX
+	MOVL AX, 0(SP)
+	MOVL p+4(FP), AX
+	MOVL AX, 4(SP)
+	MOVL n+8(FP), AX
+	MOVL AX, 8(SP)
+	NACL_SYSCALL(SYS_write)
+	MOVL AX, ret+12(FP)
+	RET
+
+TEXT runtime·nacl_exception_stack(SB),NOSPLIT,$8
+	MOVL p+0(FP), AX
+	MOVL AX, 0(SP)
+	MOVL size+4(FP), AX
+	MOVL AX, 4(SP)
+	NACL_SYSCALL(SYS_exception_stack)
+	MOVL AX, ret+8(FP)
+	RET
+
+TEXT runtime·nacl_exception_handler(SB),NOSPLIT,$8
+	MOVL fn+0(FP), AX
+	MOVL AX, 0(SP)
+	MOVL arg+4(FP), AX
+	MOVL AX, 4(SP)
+	NACL_SYSCALL(SYS_exception_handler)
+	MOVL AX, ret+8(FP)
+	RET
+
+TEXT runtime·nacl_sem_create(SB),NOSPLIT,$4
+	MOVL flag+0(FP), AX
+	MOVL AX, 0(SP)
+	NACL_SYSCALL(SYS_sem_create)
+	MOVL AX, ret+4(FP)
+	RET
+
+TEXT runtime·nacl_sem_wait(SB),NOSPLIT,$4
+	MOVL sem+0(FP), AX
+	MOVL AX, 0(SP)
+	NACL_SYSCALL(SYS_sem_wait)
+	MOVL AX, ret+4(FP)
+	RET
+
+TEXT runtime·nacl_sem_post(SB),NOSPLIT,$4
+	MOVL sem+0(FP), AX
+	MOVL AX, 0(SP)
+	NACL_SYSCALL(SYS_sem_post)
+	MOVL AX, ret+4(FP)
+	RET
+
+TEXT runtime·nacl_mutex_create(SB),NOSPLIT,$4
+	MOVL flag+0(FP), AX
+	MOVL AX, 0(SP)
+	NACL_SYSCALL(SYS_mutex_create)
+	MOVL AX, ret+4(FP)
+	RET
+
+TEXT runtime·nacl_mutex_lock(SB),NOSPLIT,$4
+	MOVL mutex+0(FP), AX
+	MOVL AX, 0(SP)
+	NACL_SYSCALL(SYS_mutex_lock)
+	MOVL AX, ret+4(FP)
+	RET
+
+TEXT runtime·nacl_mutex_trylock(SB),NOSPLIT,$4
+	MOVL mutex+0(FP), AX
+	MOVL AX, 0(SP)
+	NACL_SYSCALL(SYS_mutex_trylock)
+	MOVL AX, ret+4(FP)
+	RET
+
+TEXT runtime·nacl_mutex_unlock(SB),NOSPLIT,$4
+	MOVL mutex+0(FP), AX
+	MOVL AX, 0(SP)
+	NACL_SYSCALL(SYS_mutex_unlock)
+	MOVL AX, ret+4(FP)
+	RET
+
+TEXT runtime·nacl_cond_create(SB),NOSPLIT,$4
+	MOVL flag+0(FP), AX
+	MOVL AX, 0(SP)
+	NACL_SYSCALL(SYS_cond_create)
+	MOVL AX, ret+4(FP)
+	RET
+
+TEXT runtime·nacl_cond_wait(SB),NOSPLIT,$8
+	MOVL cond+0(FP), AX
+	MOVL AX, 0(SP)
+	MOVL n+4(FP), AX
+	MOVL AX, 4(SP)
+	NACL_SYSCALL(SYS_cond_wait)
+	MOVL AX, ret+8(FP)
+	RET
+
+TEXT runtime·nacl_cond_signal(SB),NOSPLIT,$4
+	MOVL cond+0(FP), AX
+	MOVL AX, 0(SP)
+	NACL_SYSCALL(SYS_cond_signal)
+	MOVL AX, ret+4(FP)
+	RET
+
+TEXT runtime·nacl_cond_broadcast(SB),NOSPLIT,$4
+	MOVL cond+0(FP), AX
+	MOVL AX, 0(SP)
+	NACL_SYSCALL(SYS_cond_broadcast)
+	MOVL AX, ret+4(FP)
+	RET
+
+TEXT runtime·nacl_cond_timed_wait_abs(SB),NOSPLIT,$12
+	MOVL cond+0(FP), AX
+	MOVL AX, 0(SP)
+	MOVL lock+4(FP), AX
+	MOVL AX, 4(SP)
+	MOVL ts+8(FP), AX
+	MOVL AX, 8(SP)
+	NACL_SYSCALL(SYS_cond_timed_wait_abs)
+	MOVL AX, ret+12(FP)
+	RET
+
+TEXT runtime·nacl_thread_create(SB),NOSPLIT,$16
+	MOVL fn+0(FP), AX
+	MOVL AX, 0(SP)
+	MOVL stk+4(FP), AX
+	MOVL AX, 4(SP)
+	MOVL tls+8(FP), AX
+	MOVL AX, 8(SP)
+	MOVL xx+12(FP), AX
+	MOVL AX, 12(SP)
+	NACL_SYSCALL(SYS_thread_create)
+	MOVL AX, ret+16(FP)
+	RET
+
+TEXT runtime·mstart_nacl(SB),NOSPLIT,$0
+	JMP runtime·mstart(SB)
+
+TEXT runtime·nacl_nanosleep(SB),NOSPLIT,$8
+	MOVL ts+0(FP), AX
+	MOVL AX, 0(SP)
+	MOVL extra+4(FP), AX
+	MOVL AX, 4(SP)
+	NACL_SYSCALL(SYS_nanosleep)
+	MOVL AX, ret+8(FP)
+	RET
+
+TEXT runtime·osyield(SB),NOSPLIT,$0
+	NACL_SYSCALL(SYS_sched_yield)
+	RET
+
+TEXT runtime·mmap(SB),NOSPLIT,$32
+	MOVL	addr+0(FP), AX
+	MOVL	AX, 0(SP)
+	MOVL	n+4(FP), AX
+	MOVL	AX, 4(SP)
+	MOVL	prot+8(FP), AX
+	MOVL	AX, 8(SP)
+	MOVL	flags+12(FP), AX
+	MOVL	AX, 12(SP)
+	MOVL	fd+16(FP), AX
+	MOVL	AX, 16(SP)
+	MOVL	off+20(FP), AX
+	MOVL	AX, 24(SP)
+	MOVL	$0, 28(SP)
+	LEAL	24(SP), AX
+	MOVL	AX, 20(SP)
+	NACL_SYSCALL(SYS_mmap)
+	MOVL	AX, ret+24(FP)
+	RET
+
+TEXT time·now(SB),NOSPLIT,$20
+	MOVL $0, 0(SP) // real time clock
+	LEAL 8(SP), AX
+	MOVL AX, 4(SP) // timespec
+	NACL_SYSCALL(SYS_clock_gettime)
+	MOVL 8(SP), AX // low 32 sec
+	MOVL 12(SP), CX // high 32 sec
+	MOVL 16(SP), BX // nsec
+
+	// sec is in AX, nsec in BX
+	MOVL	AX, sec+0(FP)
+	MOVL	CX, sec+4(FP)
+	MOVL	BX, nsec+8(FP)
+	RET
+
+TEXT syscall·now(SB),NOSPLIT,$0
+	JMP time·now(SB)
+
+TEXT runtime·nacl_clock_gettime(SB),NOSPLIT,$8
+	MOVL arg1+0(FP), AX
+	MOVL AX, 0(SP)
+	MOVL arg2+4(FP), AX
+	MOVL AX, 4(SP)
+	NACL_SYSCALL(SYS_clock_gettime)
+	MOVL AX, ret+8(FP)
+	RET
+	
+TEXT runtime·nanotime(SB),NOSPLIT,$20
+	MOVL $0, 0(SP) // real time clock
+	LEAL 8(SP), AX
+	MOVL AX, 4(SP) // timespec
+	NACL_SYSCALL(SYS_clock_gettime)
+	MOVL 8(SP), AX // low 32 sec
+	MOVL 16(SP), BX // nsec
+
+	// sec is in AX, nsec in BX
+	// convert to DX:AX nsec
+	MOVL	$1000000000, CX
+	MULL	CX
+	ADDL	BX, AX
+	ADCL	$0, DX
+
+	MOVL	AX, ret_lo+0(FP)
+	MOVL	DX, ret_hi+4(FP)
+	RET
+
+TEXT runtime·setldt(SB),NOSPLIT,$8
+	MOVL	addr+4(FP), BX // aka base
+	ADDL	$0x8, BX
+	MOVL	BX, 0(SP)
+	NACL_SYSCALL(SYS_tls_init)
+	RET
+
+TEXT runtime·sigtramp(SB),NOSPLIT,$0
+	get_tls(CX)
+
+	// check that g exists
+	MOVL	g(CX), DI
+	CMPL	DI, $0
+	JNE	6(PC)
+	MOVL	$11, BX
+	MOVL	$0, 0(SP)
+	MOVL	$runtime·badsignal(SB), AX
+	CALL	AX
+	JMP 	sigtramp_ret
+
+	// save g
+	MOVL	DI, 20(SP)
+	
+	// g = m->gsignal
+	MOVL	g_m(DI), BX
+	MOVL	m_gsignal(BX), BX
+	MOVL	BX, g(CX)
+	
+	// copy arguments for sighandler
+	MOVL	$11, 0(SP) // signal
+	MOVL	$0, 4(SP) // siginfo
+	LEAL	ctxt+4(FP), AX
+	MOVL	AX, 8(SP) // context
+	MOVL	DI, 12(SP) // g
+
+	CALL	runtime·sighandler(SB)
+
+	// restore g
+	get_tls(CX)
+	MOVL	20(SP), BX
+	MOVL	BX, g(CX)
+
+sigtramp_ret:
+	// Enable exceptions again.
+	NACL_SYSCALL(SYS_exception_clear_flag)
+
+	// NaCl has abidcated its traditional operating system responsibility
+	// and declined to implement 'sigreturn'. Instead the only way to return
+	// to the execution of our program is to restore the registers ourselves.
+	// Unfortunately, that is impossible to do with strict fidelity, because
+	// there is no way to do the final update of PC that ends the sequence
+	// without either (1) jumping to a register, in which case the register ends
+	// holding the PC value instead of its intended value or (2) storing the PC
+	// on the stack and using RET, which imposes the requirement that SP is
+	// valid and that is okay to smash the word below it. The second would
+	// normally be the lesser of the two evils, except that on NaCl, the linker
+	// must rewrite RET into "POP reg; AND $~31, reg; JMP reg", so either way
+	// we are going to lose a register as a result of the incoming signal.
+	// Similarly, there is no way to restore EFLAGS; the usual way is to use
+	// POPFL, but NaCl rejects that instruction. We could inspect the bits and
+	// execute a sequence of instructions designed to recreate those flag
+	// settings, but that's a lot of work.
+	//
+	// Thankfully, Go's signal handlers never try to return directly to the
+	// executing code, so all the registers and EFLAGS are dead and can be
+	// smashed. The only registers that matter are the ones that are setting
+	// up for the simulated call that the signal handler has created.
+	// Today those registers are just PC and SP, but in case additional registers
+	// are relevant in the future (for example DX is the Go func context register)
+	// we restore as many registers as possible.
+	// 
+	// We smash BP, because that's what the linker smashes during RET.
+	//
+	LEAL	ctxt+4(FP), BP
+	ADDL	$64, BP
+	MOVL	0(BP), AX
+	MOVL	4(BP), CX
+	MOVL	8(BP), DX
+	MOVL	12(BP), BX
+	MOVL	16(BP), SP
+	// 20(BP) is saved BP, never to be seen again
+	MOVL	24(BP), SI
+	MOVL	28(BP), DI
+	// 36(BP) is saved EFLAGS, never to be seen again
+	MOVL	32(BP), BP // saved PC
+	JMP	BP
diff --git a/src/runtime/sys_nacl_amd64p32.s b/src/runtime/sys_nacl_amd64p32.s
new file mode 100644
index 0000000..4eb4aac
--- /dev/null
+++ b/src/runtime/sys_nacl_amd64p32.s
@@ -0,0 +1,459 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "zasm_GOOS_GOARCH.h"
+#include "textflag.h"
+#include "syscall_nacl.h"
+
+#define NACL_SYSCALL(code) \
+	MOVL $(0x10000 + ((code)<<5)), AX; CALL AX
+
+TEXT runtime·settls(SB),NOSPLIT,$0
+	MOVL	DI, TLS // really BP
+	RET
+
+TEXT runtime·exit(SB),NOSPLIT,$0
+	MOVL code+0(FP), DI
+	NACL_SYSCALL(SYS_exit)
+	RET
+
+TEXT runtime·exit1(SB),NOSPLIT,$0
+	MOVL code+0(FP), DI
+	NACL_SYSCALL(SYS_thread_exit)
+	RET
+
+TEXT runtime·open(SB),NOSPLIT,$0
+	MOVL name+0(FP), DI
+	MOVL mode+4(FP), SI
+	MOVL perm+8(FP), DX
+	NACL_SYSCALL(SYS_open)
+	MOVL AX, ret+16(FP)
+	RET
+
+TEXT runtime·close(SB),NOSPLIT,$0
+	MOVL fd+0(FP), DI
+	NACL_SYSCALL(SYS_close)
+	MOVL AX, ret+8(FP)
+	RET
+
+TEXT runtime·read(SB),NOSPLIT,$0
+	MOVL fd+0(FP), DI
+	MOVL p+4(FP), SI
+	MOVL n+8(FP), DX
+	NACL_SYSCALL(SYS_read)
+	MOVL AX, ret+16(FP)
+	RET
+
+TEXT syscall·naclWrite(SB), NOSPLIT, $24-20
+	MOVL arg1+0(FP), DI
+	MOVL arg2+4(FP), SI
+	MOVL arg3+8(FP), DX
+	MOVL DI, 0(SP)
+	MOVL SI, 4(SP)
+	MOVL DX, 8(SP)
+	CALL runtime·write(SB)
+	MOVL 16(SP), AX
+	MOVL AX, ret+16(FP)
+	RET
+
+TEXT runtime·write(SB),NOSPLIT,$16-20
+	// If using fake time and writing to stdout or stderr,
+	// emit playback header before actual data.
+	MOVQ runtime·faketime(SB), AX
+	CMPQ AX, $0
+	JEQ write
+	MOVL fd+0(FP), DI
+	CMPL DI, $1
+	JEQ playback
+	CMPL DI, $2
+	JEQ playback
+
+write:
+	// Ordinary write.
+	MOVL fd+0(FP), DI
+	MOVL p+4(FP), SI
+	MOVL n+8(FP), DX
+	NACL_SYSCALL(SYS_write)
+	MOVL	AX, ret+16(FP)
+	RET
+
+	// Write with playback header.
+	// First, lock to avoid interleaving writes.
+playback:
+	MOVL $1, BX
+	XCHGL	runtime·writelock(SB), BX
+	CMPL BX, $0
+	JNE playback
+
+	// Playback header: 0 0 P B <8-byte time> <4-byte data length>
+	MOVL $(('B'<<24) | ('P'<<16)), 0(SP)
+	BSWAPQ AX
+	MOVQ AX, 4(SP)
+	MOVL n+8(FP), DX
+	BSWAPL DX
+	MOVL DX, 12(SP)
+	MOVL $1, DI // standard output
+	MOVL SP, SI
+	MOVL $16, DX
+	NACL_SYSCALL(SYS_write)
+
+	// Write actual data.
+	MOVL $1, DI // standard output
+	MOVL p+4(FP), SI
+	MOVL n+8(FP), DX
+	NACL_SYSCALL(SYS_write)
+
+	// Unlock.
+	MOVL	$0, runtime·writelock(SB)
+
+	MOVL	AX, ret+16(FP)
+	RET
+
+TEXT runtime·nacl_exception_stack(SB),NOSPLIT,$0
+	MOVL p+0(FP), DI
+	MOVL size+4(FP), SI
+	NACL_SYSCALL(SYS_exception_stack)
+	MOVL AX, ret+8(FP)
+	RET
+
+TEXT runtime·nacl_exception_handler(SB),NOSPLIT,$0
+	MOVL fn+0(FP), DI
+	MOVL arg+4(FP), SI
+	NACL_SYSCALL(SYS_exception_handler)
+	MOVL AX, ret+8(FP)
+	RET
+
+TEXT runtime·nacl_sem_create(SB),NOSPLIT,$0
+	MOVL flag+0(FP), DI
+	NACL_SYSCALL(SYS_sem_create)
+	MOVL AX, ret+8(FP)
+	RET
+
+TEXT runtime·nacl_sem_wait(SB),NOSPLIT,$0
+	MOVL sem+0(FP), DI
+	NACL_SYSCALL(SYS_sem_wait)
+	MOVL AX, ret+8(FP)
+	RET
+
+TEXT runtime·nacl_sem_post(SB),NOSPLIT,$0
+	MOVL sem+0(FP), DI
+	NACL_SYSCALL(SYS_sem_post)
+	MOVL AX, ret+8(FP)
+	RET
+
+TEXT runtime·nacl_mutex_create(SB),NOSPLIT,$0
+	MOVL flag+0(FP), DI
+	NACL_SYSCALL(SYS_mutex_create)
+	MOVL AX, ret+8(FP)
+	RET
+
+TEXT runtime·nacl_mutex_lock(SB),NOSPLIT,$0
+	MOVL mutex+0(FP), DI
+	NACL_SYSCALL(SYS_mutex_lock)
+	MOVL AX, ret+8(FP)
+	RET
+
+TEXT runtime·nacl_mutex_trylock(SB),NOSPLIT,$0
+	MOVL mutex+0(FP), DI
+	NACL_SYSCALL(SYS_mutex_trylock)
+	MOVL AX, ret+8(FP)
+	RET
+
+TEXT runtime·nacl_mutex_unlock(SB),NOSPLIT,$0
+	MOVL mutex+0(FP), DI
+	NACL_SYSCALL(SYS_mutex_unlock)
+	MOVL AX, ret+8(FP)
+	RET
+
+TEXT runtime·nacl_cond_create(SB),NOSPLIT,$0
+	MOVL flag+0(FP), DI
+	NACL_SYSCALL(SYS_cond_create)
+	MOVL AX, ret+8(FP)
+	RET
+
+TEXT runtime·nacl_cond_wait(SB),NOSPLIT,$0
+	MOVL cond+0(FP), DI
+	MOVL n+4(FP), SI
+	NACL_SYSCALL(SYS_cond_wait)
+	MOVL AX, ret+8(FP)
+	RET
+
+TEXT runtime·nacl_cond_signal(SB),NOSPLIT,$0
+	MOVL cond+0(FP), DI
+	NACL_SYSCALL(SYS_cond_signal)
+	MOVL AX, ret+8(FP)
+	RET
+
+TEXT runtime·nacl_cond_broadcast(SB),NOSPLIT,$0
+	MOVL cond+0(FP), DI
+	NACL_SYSCALL(SYS_cond_broadcast)
+	MOVL AX, ret+8(FP)
+	RET
+
+TEXT runtime·nacl_cond_timed_wait_abs(SB),NOSPLIT,$0
+	MOVL cond+0(FP), DI
+	MOVL lock+4(FP), SI
+	MOVL ts+8(FP), DX
+	NACL_SYSCALL(SYS_cond_timed_wait_abs)
+	MOVL AX, ret+16(FP)
+	RET
+
+TEXT runtime·nacl_thread_create(SB),NOSPLIT,$0
+	MOVL fn+0(FP), DI
+	MOVL stk+4(FP), SI
+	MOVL tls+8(FP), DX
+	MOVL xx+12(FP), CX
+	NACL_SYSCALL(SYS_thread_create)
+	MOVL AX, ret+16(FP)
+	RET
+
+TEXT runtime·mstart_nacl(SB),NOSPLIT,$0
+	NACL_SYSCALL(SYS_tls_get)
+	SUBL	$8, AX
+	MOVL	AX, TLS
+	JMP runtime·mstart(SB)
+
+TEXT runtime·nacl_nanosleep(SB),NOSPLIT,$0
+	MOVL ts+0(FP), DI
+	MOVL extra+4(FP), SI
+	NACL_SYSCALL(SYS_nanosleep)
+	MOVL AX, ret+8(FP)
+	RET
+
+TEXT runtime·osyield(SB),NOSPLIT,$0
+	NACL_SYSCALL(SYS_sched_yield)
+	RET
+
+TEXT runtime·mmap(SB),NOSPLIT,$8
+	MOVL addr+0(FP), DI
+	MOVL n+4(FP), SI
+	MOVL prot+8(FP), DX
+	MOVL flags+12(FP), CX
+	MOVL fd+16(FP), R8
+	MOVL off+20(FP), AX
+	MOVQ AX, 0(SP)
+	MOVL SP, R9
+	NACL_SYSCALL(SYS_mmap)
+	CMPL AX, $-4095
+	JNA 2(PC)
+	NEGL AX
+	MOVL	AX, ret+24(FP)
+	RET
+
+TEXT time·now(SB),NOSPLIT,$16
+	MOVQ runtime·faketime(SB), AX
+	CMPQ AX, $0
+	JEQ realtime
+	MOVQ $0, DX
+	MOVQ $1000000000, CX
+	DIVQ CX
+	MOVQ AX, sec+0(FP)
+	MOVL DX, nsec+8(FP)
+	RET
+realtime:
+	MOVL $0, DI // real time clock
+	LEAL 0(SP), AX
+	MOVL AX, SI // timespec
+	NACL_SYSCALL(SYS_clock_gettime)
+	MOVL 0(SP), AX // low 32 sec
+	MOVL 4(SP), CX // high 32 sec
+	MOVL 8(SP), BX // nsec
+
+	// sec is in AX, nsec in BX
+	MOVL	AX, sec+0(FP)
+	MOVL	CX, sec+4(FP)
+	MOVL	BX, nsec+8(FP)
+	RET
+
+TEXT syscall·now(SB),NOSPLIT,$0
+	JMP time·now(SB)
+
+TEXT runtime·nacl_clock_gettime(SB),NOSPLIT,$0
+	MOVL arg1+0(FP), DI
+	MOVL arg2+4(FP), SI
+	NACL_SYSCALL(SYS_clock_gettime)
+	MOVL AX, ret+8(FP)
+	RET
+
+TEXT runtime·nanotime(SB),NOSPLIT,$16
+	MOVQ runtime·faketime(SB), AX
+	CMPQ AX, $0
+	JEQ 3(PC)
+	MOVQ	AX, ret+0(FP)
+	RET
+	MOVL $0, DI // real time clock
+	LEAL 0(SP), AX
+	MOVL AX, SI // timespec
+	NACL_SYSCALL(SYS_clock_gettime)
+	MOVQ 0(SP), AX // sec
+	MOVL 8(SP), DX // nsec
+
+	// sec is in AX, nsec in DX
+	// return nsec in AX
+	IMULQ	$1000000000, AX
+	ADDQ	DX, AX
+	MOVQ	AX, ret+0(FP)
+	RET
+
+TEXT runtime·sigtramp(SB),NOSPLIT,$80
+	// restore TLS register at time of execution,
+	// in case it's been smashed.
+	// the TLS register is really BP, but for consistency
+	// with non-NaCl systems it is referred to here as TLS.
+	// NOTE: Cannot use SYS_tls_get here (like we do in mstart_nacl),
+	// because the main thread never calls tls_set.
+	LEAL ctxt+0(FP), AX
+	MOVL (16*4+5*8)(AX), AX
+	MOVL	AX, TLS
+
+	// check that g exists
+	get_tls(CX)
+	MOVL	g(CX), DI
+	
+	CMPL	DI, $0
+	JEQ	nog
+
+	// save g
+	MOVL	DI, 20(SP)
+	
+	// g = m->gsignal
+	MOVL	g_m(DI), BX
+	MOVL	m_gsignal(BX), BX
+	MOVL	BX, g(CX)
+
+//JMP debughandler
+
+	// copy arguments for sighandler
+	MOVL	$11, 0(SP) // signal
+	MOVL	$0, 4(SP) // siginfo
+	LEAL	ctxt+0(FP), AX
+	MOVL	AX, 8(SP) // context
+	MOVL	DI, 12(SP) // g
+
+	CALL	runtime·sighandler(SB)
+
+	// restore g
+	get_tls(CX)
+	MOVL	20(SP), BX
+	MOVL	BX, g(CX)
+
+sigtramp_ret:
+	// Enable exceptions again.
+	NACL_SYSCALL(SYS_exception_clear_flag)
+
+	// Restore registers as best we can. Impossible to do perfectly.
+	// See comment in sys_nacl_386.s for extended rationale.
+	LEAL	ctxt+0(FP), SI
+	ADDL	$64, SI
+	MOVQ	0(SI), AX
+	MOVQ	8(SI), CX
+	MOVQ	16(SI), DX
+	MOVQ	24(SI), BX
+	MOVL	32(SI), SP	// MOVL for SP sandboxing
+	// 40(SI) is saved BP aka TLS, already restored above
+	// 48(SI) is saved SI, never to be seen again
+	MOVQ	56(SI), DI
+	MOVQ	64(SI), R8
+	MOVQ	72(SI), R9
+	MOVQ	80(SI), R10
+	MOVQ	88(SI), R11
+	MOVQ	96(SI), R12
+	MOVQ	104(SI), R13
+	MOVQ	112(SI), R14
+	// 120(SI) is R15, which is owned by Native Client and must not be modified
+	MOVQ	128(SI), SI // saved PC
+	// 136(SI) is saved EFLAGS, never to be seen again
+	JMP	SI
+
+debughandler:
+	// print basic information
+	LEAL	ctxt+0(FP), DI
+	MOVL	$runtime·sigtrampf(SB), AX
+	MOVL	AX, 0(SP)
+	MOVQ	(16*4+16*8)(DI), BX // rip
+	MOVQ	BX, 8(SP)
+	MOVQ	(16*4+0*8)(DI), BX // rax
+	MOVQ	BX, 16(SP)
+	MOVQ	(16*4+1*8)(DI), BX // rcx
+	MOVQ	BX, 24(SP)
+	MOVQ	(16*4+2*8)(DI), BX // rdx
+	MOVQ	BX, 32(SP)
+	MOVQ	(16*4+3*8)(DI), BX // rbx
+	MOVQ	BX, 40(SP)
+	MOVQ	(16*4+7*8)(DI), BX // rdi
+	MOVQ	BX, 48(SP)
+	MOVQ	(16*4+15*8)(DI), BX // r15
+	MOVQ	BX, 56(SP)
+	MOVQ	(16*4+4*8)(DI), BX // rsp
+	MOVQ	0(BX), BX
+	MOVQ	BX, 64(SP)
+	CALL	runtime·printf(SB)
+	
+	LEAL	ctxt+0(FP), DI
+	MOVQ	(16*4+16*8)(DI), BX // rip
+	MOVL	BX, 0(SP)
+	MOVQ	(16*4+4*8)(DI), BX // rsp
+	MOVL	BX, 4(SP)
+	MOVL	$0, 8(SP)	// lr
+	get_tls(CX)
+	MOVL	g(CX), BX
+	MOVL	BX, 12(SP)	// gp
+	CALL	runtime·traceback(SB)
+
+notls:
+	MOVL	0, AX
+	RET
+
+nog:
+	MOVL	0, AX
+	RET
+
+// cannot do real signal handling yet, because gsignal has not been allocated.
+MOVL $1, DI; NACL_SYSCALL(SYS_exit)
+
+TEXT runtime·nacl_sysinfo(SB),NOSPLIT,$16
+/*
+	MOVL	di+0(FP), DI
+	LEAL	12(DI), BX
+	MOVL	8(DI), AX
+	ADDL	4(DI), AX
+	ADDL	$2, AX
+	LEAL	(BX)(AX*4), BX
+	MOVL	BX, runtime·nacl_irt_query(SB)
+auxloop:
+	MOVL	0(BX), DX
+	CMPL	DX, $0
+	JNE	2(PC)
+	RET
+	CMPL	DX, $32
+	JEQ	auxfound
+	ADDL	$8, BX
+	JMP	auxloop
+auxfound:
+	MOVL	4(BX), BX
+	MOVL	BX, runtime·nacl_irt_query(SB)
+
+	LEAL	runtime·nacl_irt_basic_v0_1_str(SB), DI
+	LEAL	runtime·nacl_irt_basic_v0_1(SB), SI
+	MOVL	runtime·nacl_irt_basic_v0_1_size(SB), DX
+	MOVL	runtime·nacl_irt_query(SB), BX
+	CALL	BX
+
+	LEAL	runtime·nacl_irt_memory_v0_3_str(SB), DI
+	LEAL	runtime·nacl_irt_memory_v0_3(SB), SI
+	MOVL	runtime·nacl_irt_memory_v0_3_size(SB), DX
+	MOVL	runtime·nacl_irt_query(SB), BX
+	CALL	BX
+
+	LEAL	runtime·nacl_irt_thread_v0_1_str(SB), DI
+	LEAL	runtime·nacl_irt_thread_v0_1(SB), SI
+	MOVL	runtime·nacl_irt_thread_v0_1_size(SB), DX
+	MOVL	runtime·nacl_irt_query(SB), BX
+	CALL	BX
+
+	// TODO: Once we have a NaCl SDK with futex syscall support,
+	// try switching to futex syscalls and here load the
+	// nacl-irt-futex-0.1 table.
+*/
+	RET
diff --git a/src/runtime/sys_nacl_arm.s b/src/runtime/sys_nacl_arm.s
new file mode 100644
index 0000000..d354ab4
--- /dev/null
+++ b/src/runtime/sys_nacl_arm.s
@@ -0,0 +1,320 @@
+// 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 "zasm_GOOS_GOARCH.h"
+#include "textflag.h"
+#include "syscall_nacl.h"
+
+#define NACL_SYSCALL(code) \
+	MOVW	$(0x10000 + ((code)<<5)), R8; BL (R8)
+
+TEXT runtime·exit(SB),NOSPLIT,$0
+	MOVW	code+0(FP), R0
+	NACL_SYSCALL(SYS_exit)
+	RET
+
+TEXT runtime·exit1(SB),NOSPLIT,$0
+	MOVW	code+0(FP), R0
+	NACL_SYSCALL(SYS_thread_exit)
+	RET
+
+TEXT runtime·open(SB),NOSPLIT,$0
+	MOVW	name+0(FP), R0
+	MOVW	name+0(FP), R1
+	MOVW	name+0(FP), R2
+	NACL_SYSCALL(SYS_open)
+	MOVW	R0, ret+12(FP)
+	RET
+
+TEXT runtime·close(SB),NOSPLIT,$0
+	MOVW	fd+0(FP), R0
+	NACL_SYSCALL(SYS_close)
+	MOVW	R0, ret+4(FP)
+	RET
+
+TEXT runtime·read(SB),NOSPLIT,$0
+	MOVW	fd+0(FP), R0
+	MOVW	p+4(FP), R1
+	MOVW	n+8(FP), R2
+	NACL_SYSCALL(SYS_read)
+	MOVW	R0, ret+12(FP)
+	RET
+
+// func naclWrite(fd int, b []byte) int
+TEXT syscall·naclWrite(SB),NOSPLIT,$0
+	MOVW	arg1+0(FP), R0
+	MOVW	arg2+4(FP), R1
+	MOVW	arg3+8(FP), R2
+	NACL_SYSCALL(SYS_write)
+	MOVW	R0, ret+16(FP)
+	RET
+
+TEXT runtime·write(SB),NOSPLIT,$0
+	MOVW	fd+0(FP), R0
+	MOVW	p+4(FP), R1
+	MOVW	n+8(FP), R2
+	NACL_SYSCALL(SYS_write)
+	MOVW	R0, ret+12(FP)
+	RET
+
+TEXT runtime·nacl_exception_stack(SB),NOSPLIT,$0
+	MOVW	p+0(FP), R0
+	MOVW	size+4(FP), R1
+	NACL_SYSCALL(SYS_exception_stack)
+	MOVW	R0, ret+8(FP)
+	RET
+
+TEXT runtime·nacl_exception_handler(SB),NOSPLIT,$0
+	MOVW	fn+0(FP), R0
+	MOVW	arg+4(FP), R1
+	NACL_SYSCALL(SYS_exception_handler)
+	MOVW	R0, ret+8(FP)
+	RET
+
+TEXT runtime·nacl_sem_create(SB),NOSPLIT,$0
+	MOVW	flag+0(FP), R0
+	NACL_SYSCALL(SYS_sem_create)
+	MOVW	R0, ret+4(FP)
+	RET
+
+TEXT runtime·nacl_sem_wait(SB),NOSPLIT,$0
+	MOVW	sem+0(FP), R0
+	NACL_SYSCALL(SYS_sem_wait)
+	MOVW	R0, ret+4(FP)
+	RET
+
+TEXT runtime·nacl_sem_post(SB),NOSPLIT,$0
+	MOVW	sem+0(FP), R0
+	NACL_SYSCALL(SYS_sem_post)
+	MOVW	R0, ret+4(FP)
+	RET
+
+TEXT runtime·nacl_mutex_create(SB),NOSPLIT,$0
+	MOVW	flag+0(FP), R0
+	NACL_SYSCALL(SYS_mutex_create)
+	MOVW	R0, ret+4(FP)
+	RET
+
+TEXT runtime·nacl_mutex_lock(SB),NOSPLIT,$0
+	MOVW	mutex+0(FP), R0
+	NACL_SYSCALL(SYS_mutex_lock)
+	MOVW	R0, ret+4(FP)
+	RET
+
+TEXT runtime·nacl_mutex_trylock(SB),NOSPLIT,$0
+	MOVW	mutex+0(FP), R0
+	NACL_SYSCALL(SYS_mutex_trylock)
+	MOVW	R0, ret+4(FP)
+	RET
+
+TEXT runtime·nacl_mutex_unlock(SB),NOSPLIT,$0
+	MOVW	mutex+0(FP), R0
+	NACL_SYSCALL(SYS_mutex_unlock)
+	MOVW	R0, ret+4(FP)
+	RET
+
+TEXT runtime·nacl_cond_create(SB),NOSPLIT,$0
+	MOVW	flag+0(FP), R0
+	NACL_SYSCALL(SYS_cond_create)
+	MOVW	R0, ret+4(FP)
+	RET
+
+TEXT runtime·nacl_cond_wait(SB),NOSPLIT,$0
+	MOVW	cond+0(FP), R0
+	MOVW	n+4(FP), R1
+	NACL_SYSCALL(SYS_cond_wait)
+	MOVW	R0, ret+8(FP)
+	RET
+
+TEXT runtime·nacl_cond_signal(SB),NOSPLIT,$0
+	MOVW	cond+0(FP), R0
+	NACL_SYSCALL(SYS_cond_signal)
+	MOVW	R0, ret+4(FP)
+	RET
+
+TEXT runtime·nacl_cond_broadcast(SB),NOSPLIT,$0
+	MOVW	cond+0(FP), R0
+	NACL_SYSCALL(SYS_cond_broadcast)
+	MOVW	R0, ret+4(FP)
+	RET
+
+TEXT runtime·nacl_cond_timed_wait_abs(SB),NOSPLIT,$0
+	MOVW	cond+0(FP), R0
+	MOVW	lock+4(FP), R1
+	MOVW	ts+8(FP), R2
+	NACL_SYSCALL(SYS_cond_timed_wait_abs)
+	MOVW	R0, ret+12(FP)
+	RET
+
+TEXT runtime·nacl_thread_create(SB),NOSPLIT,$0
+	MOVW	fn+0(FP), R0
+	MOVW	stk+4(FP), R1
+	MOVW	tls+8(FP), R2
+	MOVW	xx+12(FP), R3
+	NACL_SYSCALL(SYS_thread_create)
+	MOVW	R0, ret+16(FP)
+	RET
+
+TEXT runtime·mstart_nacl(SB),NOSPLIT,$0
+	MOVW	0(R9), R0 // TLS
+	MOVW	-8(R0), R1 // g
+	MOVW	-4(R0), R2 // m
+	MOVW	R2, g_m(R1)
+	MOVW	R1, g
+	B runtime·mstart(SB)
+
+TEXT runtime·nacl_nanosleep(SB),NOSPLIT,$0
+	MOVW	ts+0(FP), R0
+	MOVW	extra+4(FP), R1
+	NACL_SYSCALL(SYS_nanosleep)
+	MOVW	R0, ret+8(FP)
+	RET
+
+TEXT runtime·osyield(SB),NOSPLIT,$0
+	NACL_SYSCALL(SYS_sched_yield)
+	RET
+
+TEXT runtime·mmap(SB),NOSPLIT,$8
+	MOVW	addr+0(FP), R0
+	MOVW	n+4(FP), R1
+	MOVW	prot+8(FP), R2
+	MOVW	flags+12(FP), R3
+	MOVW	fd+16(FP), R4
+	// arg6:offset should be passed as a pointer (to int64)
+	MOVW	off+20(FP), R5
+	MOVW	R5, 4(R13)
+	MOVW	$0, R6
+	MOVW	R6, 8(R13)
+	MOVW	$4(R13), R5
+	MOVM.DB.W [R4,R5], (R13) // arg5 and arg6 are passed on stack
+	NACL_SYSCALL(SYS_mmap)
+	MOVM.IA.W (R13), [R4, R5]
+	CMP	$-4095, R0
+	RSB.HI	$0, R0
+	MOVW	R0, ret+24(FP)
+	RET
+
+TEXT time·now(SB),NOSPLIT,$16
+	MOVW	$0, R0 // real time clock
+	MOVW	$4(R13), R1
+	NACL_SYSCALL(SYS_clock_gettime)
+	MOVW	4(R13), R0 // low 32-bit sec
+	MOVW	8(R13), R1 // high 32-bit sec
+	MOVW	12(R13), R2 // nsec
+	MOVW	R0, sec+0(FP)
+	MOVW	R1, sec+4(FP)
+	MOVW	R2, sec+8(FP)
+	RET
+
+TEXT syscall·now(SB),NOSPLIT,$0
+	B time·now(SB)
+
+TEXT runtime·nacl_clock_gettime(SB),NOSPLIT,$0
+	MOVW	arg1+0(FP), R0
+	MOVW	arg2+4(FP), R1
+	NACL_SYSCALL(SYS_clock_gettime)
+	MOVW	R0, ret+8(FP)
+	RET
+
+// int64 nanotime(void) so really
+// void nanotime(int64 *nsec)
+TEXT runtime·nanotime(SB),NOSPLIT,$16
+	MOVW	$0, R0 // real time clock
+	MOVW	$4(R13), R1
+	NACL_SYSCALL(SYS_clock_gettime)
+	MOVW	4(R13), R0 // low 32-bit sec
+	MOVW	8(R13), R1 // high 32-bit sec (ignored for now)
+	MOVW	12(R13), R2 // nsec
+	MOVW	$1000000000, R3
+	MULLU	R0, R3, (R1, R0)
+	MOVW	$0, R4
+	ADD.S	R2, R0
+	ADC	R4, R1
+	MOVW	R0, ret_lo+0(FP)
+	MOVW	R1, ret_hi+4(FP)
+	RET
+
+TEXT runtime·sigtramp(SB),NOSPLIT,$80
+	// load g from thread context
+	MOVW	$ctxt+-4(FP), R0
+	MOVW	(16*4+10*4)(R0), g
+
+	// check that g exists
+	CMP	$0, g
+	BNE 	4(PC)
+	MOVW  	$runtime·badsignal2(SB), R11
+	BL	(R11)
+	RET
+
+	// save g
+	MOVW	g, R3
+	MOVW	g, 20(R13)
+
+	// g = m->gsignal
+	MOVW	g_m(g), R8
+	MOVW	m_gsignal(R8), g
+
+	// copy arguments for call to sighandler
+	MOVW	$11, R0
+	MOVW	R0, 4(R13) // signal
+	MOVW	$0, R0
+	MOVW	R0, 8(R13) // siginfo
+	MOVW	$ctxt+-4(FP), R0
+	MOVW	R0, 12(R13) // context
+	MOVW	R3, 16(R13) // g
+
+	BL	runtime·sighandler(SB)
+
+	// restore g
+	MOVW	20(R13), g
+
+sigtramp_ret:
+	// Enable exceptions again.
+	NACL_SYSCALL(SYS_exception_clear_flag)
+
+	// Restore registers as best we can. Impossible to do perfectly.
+	// See comment in sys_nacl_386.s for extended rationale.
+	MOVW	$ctxt+-4(FP), R1
+	ADD	$64, R1
+	MOVW	(0*4)(R1), R0
+	MOVW	(2*4)(R1), R2
+	MOVW	(3*4)(R1), R3
+	MOVW	(4*4)(R1), R4
+	MOVW	(5*4)(R1), R5
+	MOVW	(6*4)(R1), R6
+	MOVW	(7*4)(R1), R7
+	MOVW	(8*4)(R1), R8
+	// cannot write to R9
+	MOVW	(10*4)(R1), g
+	MOVW	(11*4)(R1), R11
+	MOVW	(12*4)(R1), R12
+	MOVW	(13*4)(R1), R13
+	MOVW	(14*4)(R1), R14
+	MOVW	(15*4)(R1), R1
+	B	(R1)
+
+nog:
+	MOVW	$0, R0
+	RET
+
+TEXT runtime·nacl_sysinfo(SB),NOSPLIT,$16
+	RET
+
+TEXT runtime·casp(SB),NOSPLIT,$0
+	B	runtime·cas(SB)
+
+// This is only valid for ARMv6+, however, NaCl/ARM is only defined
+// for ARMv7A anyway.
+// bool armcas(int32 *val, int32 old, int32 new)
+// AtomiBLy:
+//	if(*val == old){
+//		*val = new;
+//		return 1;
+//	}else
+//		return 0;
+TEXT runtime·cas(SB),NOSPLIT,$0
+	B runtime·armcas(SB)
+
+TEXT runtime·read_tls_fallback(SB),NOSPLIT,$-4
+	WORD $0xe7fedef0 // NACL_INSTR_ARM_ABORT_NOW (UDF #0xEDE0)
diff --git a/src/runtime/sys_netbsd_386.s b/src/runtime/sys_netbsd_386.s
new file mode 100644
index 0000000..23f2f6b
--- /dev/null
+++ b/src/runtime/sys_netbsd_386.s
@@ -0,0 +1,384 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+//
+// System calls and other sys.stuff for 386, NetBSD
+// /usr/src/sys/kern/syscalls.master for syscall numbers.
+//
+
+#include "zasm_GOOS_GOARCH.h"
+#include "textflag.h"
+
+// Exit the entire program (like C exit)
+TEXT runtime·exit(SB),NOSPLIT,$-4
+	MOVL	$1, AX
+	INT	$0x80
+	MOVL	$0xf1, 0xf1		// crash
+	RET
+
+TEXT runtime·exit1(SB),NOSPLIT,$-4
+	MOVL	$310, AX		// sys__lwp_exit
+	INT	$0x80
+	JAE	2(PC)
+	MOVL	$0xf1, 0xf1		// crash
+	RET
+
+TEXT runtime·open(SB),NOSPLIT,$-4
+	MOVL	$5, AX
+	INT	$0x80
+	MOVL	AX, ret+12(FP)
+	RET
+
+TEXT runtime·close(SB),NOSPLIT,$-4
+	MOVL	$6, AX
+	INT	$0x80
+	MOVL	AX, ret+4(FP)
+	RET
+
+TEXT runtime·read(SB),NOSPLIT,$-4
+	MOVL	$3, AX
+	INT	$0x80
+	MOVL	AX, ret+12(FP)
+	RET
+
+TEXT runtime·write(SB),NOSPLIT,$-4
+	MOVL	$4, AX			// sys_write
+	INT	$0x80
+	MOVL	AX, ret+12(FP)
+	RET
+
+TEXT runtime·usleep(SB),NOSPLIT,$24
+	MOVL	$0, DX
+	MOVL	usec+0(FP), AX
+	MOVL	$1000000, CX
+	DIVL	CX
+	MOVL	AX, 12(SP)		// tv_sec - l32
+	MOVL	$0, 16(SP)		// tv_sec - h32
+	MOVL	$1000, AX
+	MULL	DX
+	MOVL	AX, 20(SP)		// tv_nsec
+
+	MOVL	$0, 0(SP)
+	LEAL	12(SP), AX
+	MOVL	AX, 4(SP)		// arg 1 - rqtp
+	MOVL	$0, 8(SP)		// arg 2 - rmtp
+	MOVL	$430, AX		// sys_nanosleep
+	INT	$0x80
+	RET
+
+TEXT runtime·raise(SB),NOSPLIT,$12
+	MOVL	$311, AX		// sys__lwp_self
+	INT	$0x80
+	MOVL	$0, 0(SP)
+	MOVL	AX, 4(SP)		// arg 1 - target
+	MOVL	sig+0(FP), AX
+	MOVL	AX, 8(SP)		// arg 2 - signo
+	MOVL	$318, AX		// sys__lwp_kill
+	INT	$0x80
+	RET
+
+TEXT runtime·mmap(SB),NOSPLIT,$36
+	LEAL	addr+0(FP), SI
+	LEAL	4(SP), DI
+	CLD
+	MOVSL				// arg 1 - addr
+	MOVSL				// arg 2 - len
+	MOVSL				// arg 3 - prot
+	MOVSL				// arg 4 - flags
+	MOVSL				// arg 5 - fd
+	MOVL	$0, AX
+	STOSL				// arg 6 - pad
+	MOVSL				// arg 7 - offset
+	MOVL	$0, AX			// top 32 bits of file offset
+	STOSL
+	MOVL	$197, AX		// sys_mmap
+	INT	$0x80
+	MOVL	AX, ret+24(FP)
+	RET
+
+TEXT runtime·munmap(SB),NOSPLIT,$-4
+	MOVL	$73, AX			// sys_munmap
+	INT	$0x80
+	JAE	2(PC)
+	MOVL	$0xf1, 0xf1		// crash
+	RET
+
+TEXT runtime·madvise(SB),NOSPLIT,$-4
+	MOVL	$75, AX			// sys_madvise
+	INT	$0x80
+	// ignore failure - maybe pages are locked
+	RET
+
+TEXT runtime·setitimer(SB),NOSPLIT,$-4
+	MOVL	$425, AX		// sys_setitimer
+	INT	$0x80
+	RET
+
+// func now() (sec int64, nsec int32)
+TEXT time·now(SB), NOSPLIT, $32
+	LEAL	12(SP), BX
+	MOVL	$0, 4(SP)		// arg 1 - clock_id
+	MOVL	BX, 8(SP)		// arg 2 - tp
+	MOVL	$427, AX		// sys_clock_gettime
+	INT	$0x80
+
+	MOVL	12(SP), AX		// sec - l32
+	MOVL	AX, sec+0(FP)
+	MOVL	16(SP), AX		// sec - h32
+	MOVL	AX, sec+4(FP)
+
+	MOVL	20(SP), BX		// nsec
+	MOVL	BX, nsec+8(FP)
+	RET
+
+// int64 nanotime(void) so really
+// void nanotime(int64 *nsec)
+TEXT runtime·nanotime(SB),NOSPLIT,$32
+	LEAL	12(SP), BX
+	MOVL	$0, 4(SP)		// arg 1 - clock_id
+	MOVL	BX, 8(SP)		// arg 2 - tp
+	MOVL	$427, AX		// sys_clock_gettime
+	INT	$0x80
+
+	MOVL	16(SP), CX		// sec - h32
+	IMULL	$1000000000, CX
+
+	MOVL	12(SP), AX		// sec - l32
+	MOVL	$1000000000, BX
+	MULL	BX			// result in dx:ax
+
+	MOVL	20(SP), BX		// nsec
+	ADDL	BX, AX
+	ADCL	CX, DX			// add high bits with carry
+
+	MOVL	AX, ret_lo+0(FP)
+	MOVL	DX, ret_hi+4(FP)
+	RET
+
+TEXT runtime·getcontext(SB),NOSPLIT,$-4
+	MOVL	$307, AX		// sys_getcontext
+	INT	$0x80
+	JAE	2(PC)
+	MOVL	$0xf1, 0xf1		// crash
+	RET
+
+TEXT runtime·sigprocmask(SB),NOSPLIT,$-4
+	MOVL	$293, AX		// sys_sigprocmask
+	INT	$0x80
+	JAE	2(PC)
+	MOVL	$0xf1, 0xf1		// crash
+	RET
+
+TEXT runtime·sigreturn_tramp(SB),NOSPLIT,$0
+	LEAL	140(SP), AX		// Load address of ucontext
+	MOVL	AX, 4(SP)
+	MOVL	$308, AX		// sys_setcontext
+	INT	$0x80
+	MOVL	$-1, 4(SP)		// Something failed...
+	MOVL	$1, AX			// sys_exit
+	INT	$0x80
+
+TEXT runtime·sigaction(SB),NOSPLIT,$24
+	LEAL	sig+0(FP), SI
+	LEAL	4(SP), DI
+	CLD
+	MOVSL				// arg 1 - sig
+	MOVSL				// arg 2 - act
+	MOVSL				// arg 3 - oact
+	LEAL	runtime·sigreturn_tramp(SB), AX
+	STOSL				// arg 4 - tramp
+	MOVL	$2, AX
+	STOSL				// arg 5 - vers
+	MOVL	$340, AX		// sys___sigaction_sigtramp
+	INT	$0x80
+	JAE	2(PC)
+	MOVL	$0xf1, 0xf1		// crash
+	RET
+
+TEXT runtime·sigtramp(SB),NOSPLIT,$44
+	get_tls(CX)
+
+	// check that g exists
+	MOVL	g(CX), DI
+	CMPL	DI, $0
+	JNE	6(PC)
+	MOVL	signo+0(FP), BX
+	MOVL	BX, 0(SP)
+	MOVL	$runtime·badsignal(SB), AX
+	CALL	AX
+	RET
+
+	// save g
+	MOVL	DI, 20(SP)
+
+	// g = m->gsignal
+	MOVL	g_m(DI), BX
+	MOVL	m_gsignal(BX), BX
+	MOVL	BX, g(CX)
+
+	// copy arguments for call to sighandler
+	MOVL	signo+0(FP), BX
+	MOVL	BX, 0(SP)
+	MOVL	info+4(FP), BX
+	MOVL	BX, 4(SP)
+	MOVL	context+8(FP), BX
+	MOVL	BX, 8(SP)
+	MOVL	DI, 12(SP)
+
+	CALL	runtime·sighandler(SB)
+
+	// restore g
+	get_tls(CX)
+	MOVL	20(SP), BX
+	MOVL	BX, g(CX)
+	RET
+
+// int32 lwp_create(void *context, uintptr flags, void *lwpid);
+TEXT runtime·lwp_create(SB),NOSPLIT,$16
+	MOVL	$0, 0(SP)
+	MOVL	ctxt+0(FP), AX
+	MOVL	AX, 4(SP)		// arg 1 - context
+	MOVL	flags+4(FP), AX
+	MOVL	AX, 8(SP)		// arg 2 - flags
+	MOVL	lwpid+8(FP), AX
+	MOVL	AX, 12(SP)		// arg 3 - lwpid
+	MOVL	$309, AX		// sys__lwp_create
+	INT	$0x80
+	JCC	2(PC)
+	NEGL	AX
+	MOVL	AX, ret+12(FP)
+	RET
+
+TEXT runtime·lwp_tramp(SB),NOSPLIT,$0
+
+	// Set FS to point at m->tls
+	LEAL	m_tls(BX), BP
+	PUSHAL				// save registers
+	PUSHL	BP
+	CALL	runtime·settls(SB)
+	POPL	AX
+	POPAL
+
+	// Now segment is established.  Initialize m, g.
+	get_tls(AX)
+	MOVL	DX, g(AX)
+	MOVL	BX, g_m(DX)
+
+	CALL	runtime·stackcheck(SB)	// smashes AX, CX
+	MOVL	0(DX), DX		// paranoia; check they are not nil
+	MOVL	0(BX), BX
+
+	// more paranoia; check that stack splitting code works
+	PUSHAL
+	CALL	runtime·emptyfunc(SB)
+	POPAL
+
+	// Call fn
+	CALL	SI
+
+	CALL	runtime·exit1(SB)
+	MOVL	$0x1234, 0x1005
+	RET
+
+TEXT runtime·sigaltstack(SB),NOSPLIT,$-8
+	MOVL	$281, AX		// sys___sigaltstack14
+	MOVL	new+4(SP), BX
+	MOVL	old+8(SP), CX
+	INT	$0x80
+	CMPL	AX, $0xfffff001
+	JLS	2(PC)
+	INT	$3
+	RET
+
+TEXT runtime·setldt(SB),NOSPLIT,$8
+	// Under NetBSD we set the GS base instead of messing with the LDT.
+	MOVL	16(SP), AX		// tls0
+	MOVL	AX, 0(SP)
+	CALL	runtime·settls(SB)
+	RET
+
+TEXT runtime·settls(SB),NOSPLIT,$16
+	// adjust for ELF: wants to use -8(GS) and -4(GS) for g and m
+	MOVL	base+0(FP), CX
+	ADDL	$8, CX
+	MOVL	$0, 0(SP)		// syscall gap
+	MOVL	CX, 4(SP)		// arg 1 - ptr
+	MOVL	$317, AX		// sys__lwp_setprivate
+	INT	$0x80
+	JCC	2(PC)
+	MOVL	$0xf1, 0xf1		// crash
+	RET
+
+TEXT runtime·osyield(SB),NOSPLIT,$-4
+	MOVL	$350, AX		// sys_sched_yield
+	INT	$0x80
+	RET
+
+TEXT runtime·lwp_park(SB),NOSPLIT,$-4
+	MOVL	$434, AX		// sys__lwp_park
+	INT	$0x80
+	MOVL	AX, ret+16(FP)
+	RET
+
+TEXT runtime·lwp_unpark(SB),NOSPLIT,$-4
+	MOVL	$321, AX		// sys__lwp_unpark
+	INT	$0x80
+	MOVL	AX, ret+8(FP)
+	RET
+
+TEXT runtime·lwp_self(SB),NOSPLIT,$-4
+	MOVL	$311, AX		// sys__lwp_self
+	INT	$0x80
+	MOVL	AX, ret+0(FP)
+	RET
+
+TEXT runtime·sysctl(SB),NOSPLIT,$28
+	LEAL	mib+0(FP), SI
+	LEAL	4(SP), DI
+	CLD
+	MOVSL				// arg 1 - name
+	MOVSL				// arg 2 - namelen
+	MOVSL				// arg 3 - oldp
+	MOVSL				// arg 4 - oldlenp
+	MOVSL				// arg 5 - newp
+	MOVSL				// arg 6 - newlen
+	MOVL	$202, AX		// sys___sysctl
+	INT	$0x80
+	JCC	3(PC)
+	NEGL	AX
+	RET
+	MOVL	$0, AX
+	RET
+
+GLOBL runtime·tlsoffset(SB),NOPTR,$4
+
+// int32 runtime·kqueue(void)
+TEXT runtime·kqueue(SB),NOSPLIT,$0
+	MOVL	$344, AX
+	INT	$0x80
+	JAE	2(PC)
+	NEGL	AX
+	MOVL	AX, ret+0(FP)
+	RET
+
+// int32 runtime·kevent(int kq, Kevent *changelist, int nchanges, Kevent *eventlist, int nevents, Timespec *timeout)
+TEXT runtime·kevent(SB),NOSPLIT,$0
+	MOVL	$435, AX
+	INT	$0x80
+	JAE	2(PC)
+	NEGL	AX
+	MOVL	AX, ret+24(FP)
+	RET
+
+// int32 runtime·closeonexec(int32 fd)
+TEXT runtime·closeonexec(SB),NOSPLIT,$32
+	MOVL	$92, AX		// fcntl
+	// 0(SP) is where the caller PC would be; kernel skips it
+	MOVL	fd+0(FP), BX
+	MOVL	BX, 4(SP)	// fd
+	MOVL	$2, 8(SP)	// F_SETFD
+	MOVL	$1, 12(SP)	// FD_CLOEXEC
+	INT	$0x80
+	JAE	2(PC)
+	NEGL	AX
+	RET
diff --git a/src/runtime/sys_netbsd_amd64.s b/src/runtime/sys_netbsd_amd64.s
new file mode 100644
index 0000000..eb9766d
--- /dev/null
+++ b/src/runtime/sys_netbsd_amd64.s
@@ -0,0 +1,358 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+//
+// System calls and other sys.stuff for AMD64, NetBSD
+// /usr/src/sys/kern/syscalls.master for syscall numbers.
+//
+
+#include "zasm_GOOS_GOARCH.h"
+#include "textflag.h"
+
+// int32 lwp_create(void *context, uintptr flags, void *lwpid)
+TEXT runtime·lwp_create(SB),NOSPLIT,$0
+	MOVQ	ctxt+0(FP), DI
+	MOVQ	flags+8(FP), SI
+	MOVQ	lwpid+16(FP), DX
+	MOVL	$309, AX		// sys__lwp_create
+	SYSCALL
+	JCC	2(PC)
+	NEGQ	AX
+	MOVL	AX, ret+24(FP)
+	RET
+
+TEXT runtime·lwp_tramp(SB),NOSPLIT,$0
+	
+	// Set FS to point at m->tls.
+	LEAQ	m_tls(R8), DI
+	CALL	runtime·settls(SB)
+
+	// Set up new stack.
+	get_tls(CX)
+	MOVQ	R8, g_m(R9)
+	MOVQ	R9, g(CX)
+	CALL	runtime·stackcheck(SB)
+
+	// Call fn
+	CALL	R12
+
+	// It shouldn't return.  If it does, exit.
+	MOVL	$310, AX		// sys__lwp_exit
+	SYSCALL
+	JMP	-3(PC)			// keep exiting
+
+TEXT runtime·osyield(SB),NOSPLIT,$0
+	MOVL	$350, AX		// sys_sched_yield
+	SYSCALL
+	RET
+
+TEXT runtime·lwp_park(SB),NOSPLIT,$0
+	MOVQ	abstime+0(FP), DI		// arg 1 - abstime
+	MOVL	unpark+8(FP), SI		// arg 2 - unpark
+	MOVQ	hint+16(FP), DX		// arg 3 - hint
+	MOVQ	unparkhint+24(FP), R10		// arg 4 - unparkhint
+	MOVL	$434, AX		// sys__lwp_park
+	SYSCALL
+	MOVL	AX, ret+32(FP)
+	RET
+
+TEXT runtime·lwp_unpark(SB),NOSPLIT,$0
+	MOVL	lwp+0(FP), DI		// arg 1 - lwp
+	MOVQ	hint+8(FP), SI		// arg 2 - hint
+	MOVL	$321, AX		// sys__lwp_unpark
+	SYSCALL
+	MOVL	AX, ret+16(FP)
+	RET
+
+TEXT runtime·lwp_self(SB),NOSPLIT,$0
+	MOVL	$311, AX		// sys__lwp_self
+	SYSCALL
+	MOVL	AX, ret+0(FP)
+	RET
+
+// Exit the entire program (like C exit)
+TEXT runtime·exit(SB),NOSPLIT,$-8
+	MOVL	code+0(FP), DI		// arg 1 - exit status
+	MOVL	$1, AX			// sys_exit
+	SYSCALL
+	MOVL	$0xf1, 0xf1		// crash
+	RET
+
+TEXT runtime·exit1(SB),NOSPLIT,$-8
+	MOVL	$310, AX		// sys__lwp_exit
+	SYSCALL
+	MOVL	$0xf1, 0xf1		// crash
+	RET
+
+TEXT runtime·open(SB),NOSPLIT,$-8
+	MOVQ	name+0(FP), DI		// arg 1 pathname
+	MOVL	mode+8(FP), SI		// arg 2 flags
+	MOVL	perm+12(FP), DX		// arg 3 mode
+	MOVL	$5, AX
+	SYSCALL
+	MOVL	AX, ret+16(FP)
+	RET
+
+TEXT runtime·close(SB),NOSPLIT,$-8
+	MOVL	fd+0(FP), DI		// arg 1 fd
+	MOVL	$6, AX
+	SYSCALL
+	MOVL	AX, ret+8(FP)
+	RET
+
+TEXT runtime·read(SB),NOSPLIT,$-8
+	MOVL	fd+0(FP), DI		// arg 1 fd
+	MOVQ	p+8(FP), SI		// arg 2 buf
+	MOVL	n+16(FP), DX		// arg 3 count
+	MOVL	$3, AX
+	SYSCALL
+	MOVL	AX, ret+24(FP)
+	RET
+
+TEXT runtime·write(SB),NOSPLIT,$-8
+	MOVQ	fd+0(FP), DI		// arg 1 - fd
+	MOVQ	p+8(FP), SI		// arg 2 - buf
+	MOVL	n+16(FP), DX		// arg 3 - nbyte
+	MOVL	$4, AX			// sys_write
+	SYSCALL
+	MOVL	AX, ret+24(FP)
+	RET
+
+TEXT runtime·usleep(SB),NOSPLIT,$16
+	MOVL	$0, DX
+	MOVL	usec+0(FP), AX
+	MOVL	$1000000, CX
+	DIVL	CX
+	MOVQ	AX, 0(SP)		// tv_sec
+	MOVL	$1000, AX
+	MULL	DX
+	MOVQ	AX, 8(SP)		// tv_nsec
+
+	MOVQ	SP, DI			// arg 1 - rqtp
+	MOVQ	$0, SI			// arg 2 - rmtp
+	MOVL	$430, AX		// sys_nanosleep
+	SYSCALL
+	RET
+
+TEXT runtime·raise(SB),NOSPLIT,$16
+	MOVL	$311, AX		// sys__lwp_self
+	SYSCALL
+	MOVQ	AX, DI			// arg 1 - target
+	MOVL	sig+0(FP), SI		// arg 2 - signo
+	MOVL	$318, AX		// sys__lwp_kill
+	SYSCALL
+	RET
+
+TEXT runtime·setitimer(SB),NOSPLIT,$-8
+	MOVL	mode+0(FP), DI		// arg 1 - which
+	MOVQ	new+8(FP), SI		// arg 2 - itv
+	MOVQ	old+16(FP), DX		// arg 3 - oitv
+	MOVL	$425, AX		// sys_setitimer
+	SYSCALL
+	RET
+
+// func now() (sec int64, nsec int32)
+TEXT time·now(SB), NOSPLIT, $32
+	MOVQ	$0, DI			// arg 1 - clock_id
+	LEAQ	8(SP), SI		// arg 2 - tp
+	MOVL	$427, AX		// sys_clock_gettime
+	SYSCALL
+	MOVQ	8(SP), AX		// sec
+	MOVL	16(SP), DX		// nsec
+
+	// sec is in AX, nsec in DX
+	MOVQ	AX, sec+0(FP)
+	MOVL	DX, nsec+8(FP)
+	RET
+
+TEXT runtime·nanotime(SB),NOSPLIT,$32
+	MOVQ	$0, DI			// arg 1 - clock_id
+	LEAQ	8(SP), SI		// arg 2 - tp
+	MOVL	$427, AX		// sys_clock_gettime
+	SYSCALL
+	MOVQ	8(SP), AX		// sec
+	MOVL	16(SP), DX		// nsec
+
+	// sec is in AX, nsec in DX
+	// return nsec in AX
+	IMULQ	$1000000000, AX
+	ADDQ	DX, AX
+	MOVQ	AX, ret+0(FP)
+	RET
+
+TEXT runtime·getcontext(SB),NOSPLIT,$-8
+	MOVQ	ctxt+0(FP), DI		// arg 1 - context
+	MOVL	$307, AX		// sys_getcontext
+	SYSCALL
+	JCC	2(PC)
+	MOVL	$0xf1, 0xf1		// crash
+	RET
+
+TEXT runtime·sigprocmask(SB),NOSPLIT,$0
+	MOVL	mode+0(FP), DI		// arg 1 - how
+	MOVQ	new+8(FP), SI		// arg 2 - set
+	MOVQ	old+16(FP), DX		// arg 3 - oset
+	MOVL	$293, AX		// sys_sigprocmask
+	SYSCALL
+	JCC	2(PC)
+	MOVL	$0xf1, 0xf1		// crash
+	RET
+
+TEXT runtime·sigreturn_tramp(SB),NOSPLIT,$-8
+	MOVQ	R15, DI			// Load address of ucontext
+	MOVQ	$308, AX		// sys_setcontext
+	SYSCALL
+	MOVQ	$-1, DI			// Something failed...
+	MOVL	$1, AX			// sys_exit
+	SYSCALL
+
+TEXT runtime·sigaction(SB),NOSPLIT,$-8
+	MOVL	sig+0(FP), DI		// arg 1 - signum
+	MOVQ	new+8(FP), SI		// arg 2 - nsa
+	MOVQ	old+16(FP), DX		// arg 3 - osa
+					// arg 4 - tramp
+	LEAQ	runtime·sigreturn_tramp(SB), R10
+	MOVQ	$2, R8			// arg 5 - vers
+	MOVL	$340, AX		// sys___sigaction_sigtramp
+	SYSCALL
+	JCC	2(PC)
+	MOVL	$0xf1, 0xf1		// crash
+	RET
+
+TEXT runtime·sigtramp(SB),NOSPLIT,$64
+	get_tls(BX)
+
+	// check that g exists
+	MOVQ	g(BX), R10
+	CMPQ	R10, $0
+	JNE	5(PC)
+	MOVQ	DI, 0(SP)
+	MOVQ	$runtime·badsignal(SB), AX
+	CALL	AX
+	RET
+
+	// save g
+	MOVQ	R10, 40(SP)
+
+	// g = m->signal
+	MOVQ	g_m(R10), BP
+	MOVQ	m_gsignal(BP), BP
+	MOVQ	BP, g(BX)
+
+	MOVQ	DI, 0(SP)
+	MOVQ	SI, 8(SP)
+	MOVQ	DX, 16(SP)
+	MOVQ	R10, 24(SP)
+
+	CALL	runtime·sighandler(SB)
+
+	// restore g
+	get_tls(BX)
+	MOVQ	40(SP), R10
+	MOVQ	R10, g(BX)
+	RET
+
+TEXT runtime·mmap(SB),NOSPLIT,$0
+	MOVQ	addr+0(FP), DI		// arg 1 - addr
+	MOVQ	n+8(FP), SI		// arg 2 - len
+	MOVL	prot+16(FP), DX		// arg 3 - prot
+	MOVL	flags+20(FP), R10		// arg 4 - flags
+	MOVL	fd+24(FP), R8		// arg 5 - fd
+	MOVL	off+28(FP), R9
+	SUBQ	$16, SP
+	MOVQ	R9, 8(SP)		// arg 7 - offset (passed on stack)
+	MOVQ	$0, R9			// arg 6 - pad
+	MOVL	$197, AX		// sys_mmap
+	SYSCALL
+	ADDQ	$16, SP
+	MOVQ	AX, ret+32(FP)
+	RET
+
+TEXT runtime·munmap(SB),NOSPLIT,$0
+	MOVQ	addr+0(FP), DI		// arg 1 - addr
+	MOVQ	n+8(FP), SI		// arg 2 - len
+	MOVL	$73, AX			// sys_munmap
+	SYSCALL
+	JCC	2(PC)
+	MOVL	$0xf1, 0xf1		// crash
+	RET
+
+
+TEXT runtime·madvise(SB),NOSPLIT,$0
+	MOVQ	addr+0(FP), DI		// arg 1 - addr
+	MOVQ	n+8(FP), SI		// arg 2 - len
+	MOVL	flags+16(FP), DX	// arg 3 - behav
+	MOVQ	$75, AX			// sys_madvise
+	SYSCALL
+	// ignore failure - maybe pages are locked
+	RET
+
+TEXT runtime·sigaltstack(SB),NOSPLIT,$-8
+	MOVQ	new+8(SP), DI		// arg 1 - nss
+	MOVQ	old+16(SP), SI		// arg 2 - oss
+	MOVQ	$281, AX		// sys___sigaltstack14
+	SYSCALL
+	JCC	2(PC)
+	MOVL	$0xf1, 0xf1		// crash
+	RET
+
+// set tls base to DI
+TEXT runtime·settls(SB),NOSPLIT,$8
+	// adjust for ELF: wants to use -16(FS) and -8(FS) for g and m
+	ADDQ	$16, DI			// arg 1 - ptr
+	MOVQ	$317, AX		// sys__lwp_setprivate
+	SYSCALL
+	JCC	2(PC)
+	MOVL	$0xf1, 0xf1		// crash
+	RET
+
+TEXT runtime·sysctl(SB),NOSPLIT,$0
+	MOVQ	mib+0(FP), DI		// arg 1 - name
+	MOVL	miblen+8(FP), SI		// arg 2 - namelen
+	MOVQ	out+16(FP), DX		// arg 3 - oldp
+	MOVQ	size+24(FP), R10		// arg 4 - oldlenp
+	MOVQ	dst+32(FP), R8		// arg 5 - newp
+	MOVQ	ndst+40(FP), R9		// arg 6 - newlen
+	MOVQ	$202, AX		// sys___sysctl
+	SYSCALL
+	JCC 4(PC)
+	NEGQ	AX
+	MOVL	AX, ret+48(FP)
+	RET
+	MOVL	$0, AX
+	MOVL	AX, ret+48(FP)
+	RET
+
+// int32 runtime·kqueue(void)
+TEXT runtime·kqueue(SB),NOSPLIT,$0
+	MOVQ	$0, DI
+	MOVL	$344, AX
+	SYSCALL
+	JCC	2(PC)
+	NEGQ	AX
+	MOVL	AX, ret+0(FP)
+	RET
+
+// int32 runtime·kevent(int kq, Kevent *changelist, int nchanges, Kevent *eventlist, int nevents, Timespec *timeout)
+TEXT runtime·kevent(SB),NOSPLIT,$0
+	MOVL	fd+0(FP), DI
+	MOVQ	ev1+8(FP), SI
+	MOVL	nev1+16(FP), DX
+	MOVQ	ev2+24(FP), R10
+	MOVL	nev2+32(FP), R8
+	MOVQ	ts+40(FP), R9
+	MOVL	$435, AX
+	SYSCALL
+	JCC	2(PC)
+	NEGQ	AX
+	MOVL	AX, ret+48(FP)
+	RET
+
+// void runtime·closeonexec(int32 fd)
+TEXT runtime·closeonexec(SB),NOSPLIT,$0
+	MOVL	fd+0(FP), DI	// fd
+	MOVQ	$2, SI		// F_SETFD
+	MOVQ	$1, DX		// FD_CLOEXEC
+	MOVL	$92, AX		// fcntl
+	SYSCALL
+	RET
diff --git a/src/runtime/sys_netbsd_arm.s b/src/runtime/sys_netbsd_arm.s
new file mode 100644
index 0000000..039a083
--- /dev/null
+++ b/src/runtime/sys_netbsd_arm.s
@@ -0,0 +1,351 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+//
+// System calls and other sys.stuff for ARM, NetBSD
+// /usr/src/sys/kern/syscalls.master for syscall numbers.
+//
+
+#include "zasm_GOOS_GOARCH.h"
+#include "textflag.h"
+
+// Exit the entire program (like C exit)
+TEXT runtime·exit(SB),NOSPLIT,$-4
+	MOVW 0(FP), R0	// arg 1 exit status
+	SWI $0xa00001
+	MOVW.CS $0, R8	// crash on syscall failure
+	MOVW.CS R8, (R8)
+	RET
+
+TEXT runtime·exit1(SB),NOSPLIT,$-4
+	SWI $0xa00136	// sys__lwp_exit
+	MOVW $1, R8	// crash
+	MOVW R8, (R8)
+	RET
+	
+TEXT runtime·open(SB),NOSPLIT,$-8
+	MOVW 0(FP), R0
+	MOVW 4(FP), R1
+	MOVW 8(FP), R2
+	SWI $0xa00005
+	MOVW	R0, ret+12(FP)
+	RET
+
+TEXT runtime·close(SB),NOSPLIT,$-8
+	MOVW 0(FP), R0
+	SWI $0xa00006
+	MOVW	R0, ret+4(FP)
+	RET
+
+TEXT runtime·read(SB),NOSPLIT,$-8
+	MOVW 0(FP), R0
+	MOVW 4(FP), R1
+	MOVW 8(FP), R2
+	SWI $0xa00003
+	MOVW	R0, ret+12(FP)
+	RET
+
+TEXT runtime·write(SB),NOSPLIT,$-4
+	MOVW	0(FP), R0	// arg 1 - fd
+	MOVW	4(FP), R1	// arg 2 - buf
+	MOVW	8(FP), R2	// arg 3 - nbyte
+	SWI $0xa00004	// sys_write
+	MOVW	R0, ret+12(FP)
+	RET
+
+// int32 lwp_create(void *context, uintptr flags, void *lwpid)
+TEXT runtime·lwp_create(SB),NOSPLIT,$0
+	MOVW ctxt+0(FP), R0
+	MOVW flags+4(FP), R1
+	MOVW lwpid+8(FP), R2
+	SWI $0xa00135	// sys__lwp_create
+	MOVW	R0, ret+12(FP)
+	RET
+
+TEXT runtime·osyield(SB),NOSPLIT,$0
+	SWI $0xa0015e	// sys_sched_yield
+	RET
+
+TEXT runtime·lwp_park(SB),NOSPLIT,$0
+	MOVW 0(FP), R0	// arg 1 - abstime
+	MOVW 4(FP), R1	// arg 2 - unpark
+	MOVW 8(FP), R2	// arg 3 - hint
+	MOVW 12(FP), R3	// arg 4 - unparkhint
+	SWI $0xa001b2	// sys__lwp_park
+	MOVW	R0, ret+16(FP)
+	RET
+
+TEXT runtime·lwp_unpark(SB),NOSPLIT,$0
+	MOVW	0(FP), R0	// arg 1 - lwp
+	MOVW	4(FP), R1	// arg 2 - hint
+	SWI $0xa00141 // sys__lwp_unpark
+	MOVW	R0, ret+8(FP)
+	RET
+
+TEXT runtime·lwp_self(SB),NOSPLIT,$0
+	SWI $0xa00137	// sys__lwp_self
+	MOVW	R0, ret+0(FP)
+	RET
+
+TEXT runtime·lwp_tramp(SB),NOSPLIT,$0
+	MOVW R0, g_m(R1)
+	MOVW R1, g
+
+	BL runtime·emptyfunc(SB) // fault if stack check is wrong
+	BL (R2)
+	MOVW $2, R8  // crash (not reached)
+	MOVW R8, (R8)
+	RET
+
+TEXT runtime·usleep(SB),NOSPLIT,$16
+	MOVW usec+0(FP), R0
+	MOVW R0, R2
+	MOVW $1000000, R1
+	DIV R1, R0
+	// 0(R13) is the saved LR, don't use it
+	MOVW R0, 4(R13) // tv_sec.low
+	MOVW $0, R0
+	MOVW R0, 8(R13) // tv_sec.high
+	MOD R1, R2
+	MOVW $1000, R1
+	MUL R1, R2
+	MOVW R2, 12(R13) // tv_nsec
+
+	MOVW $4(R13), R0 // arg 1 - rqtp
+	MOVW $0, R1      // arg 2 - rmtp
+	SWI $0xa001ae	// sys_nanosleep
+	RET
+
+TEXT runtime·raise(SB),NOSPLIT,$16
+	SWI $0xa00137	// sys__lwp_self, the returned R0 is arg 1
+	MOVW	sig+0(FP), R1	// arg 2 - signal
+	SWI $0xa0013e	// sys__lwp_kill
+	RET
+
+TEXT runtime·setitimer(SB),NOSPLIT,$-4
+	MOVW 0(FP), R0	// arg 1 - which
+	MOVW 4(FP), R1	// arg 2 - itv
+	MOVW 8(FP), R2	// arg 3 - oitv
+	SWI $0xa001a9	// sys_setitimer
+	RET
+
+// func now() (sec int64, nsec int32)
+TEXT time·now(SB), NOSPLIT, $32
+	MOVW $0, R0	// CLOCK_REALTIME
+	MOVW $8(R13), R1
+	SWI $0xa001ab	// clock_gettime
+
+	MOVW 8(R13), R0	// sec.low
+	MOVW 12(R13), R1 // sec.high
+	MOVW 16(R13), R2 // nsec
+
+	MOVW R0, 0(FP)
+	MOVW R1, 4(FP)
+	MOVW R2, 8(FP)
+	RET
+
+// int64 nanotime(void) so really
+// void nanotime(int64 *nsec)
+TEXT runtime·nanotime(SB), NOSPLIT, $32
+	MOVW $0, R0 // CLOCK_REALTIME
+	MOVW $8(R13), R1
+	SWI $0xa001ab	// clock_gettime
+
+	MOVW 8(R13), R0 // sec.low
+	MOVW 12(R13), R4 // sec.high
+	MOVW 16(R13), R2 // nsec
+
+	MOVW $1000000000, R3
+	MULLU R0, R3, (R1, R0)
+	MUL R3, R4
+	ADD.S R2, R0
+	ADC R4, R1
+
+	MOVW R0, ret_lo+0(FP)
+	MOVW R1, ret_hi+4(FP)
+	RET
+
+TEXT runtime·getcontext(SB),NOSPLIT,$-4
+	MOVW 0(FP), R0	// arg 1 - context
+	SWI $0xa00133	// sys_getcontext
+	MOVW.CS $0, R8	// crash on syscall failure
+	MOVW.CS R8, (R8)
+	RET
+
+TEXT runtime·sigprocmask(SB),NOSPLIT,$0
+	MOVW 0(FP), R0	// arg 1 - how
+	MOVW 4(FP), R1	// arg 2 - set
+	MOVW 8(FP), R2	// arg 3 - oset
+	SWI $0xa00125	// sys_sigprocmask
+	MOVW.CS $0, R8	// crash on syscall failure
+	MOVW.CS R8, (R8)
+	RET
+
+TEXT runtime·sigreturn_tramp(SB),NOSPLIT,$-4
+	// on entry, SP points to siginfo, we add sizeof(ucontext)
+	// to SP to get a pointer to ucontext.
+	ADD $0x80, R13, R0 // 0x80 == sizeof(UcontextT)
+	SWI $0xa00134	// sys_setcontext
+	// something failed, we have to exit
+	MOVW $0x4242, R0 // magic return number
+	SWI $0xa00001	// sys_exit
+	B -2(PC)	// continue exit
+
+TEXT runtime·sigaction(SB),NOSPLIT,$4
+	MOVW 0(FP), R0	// arg 1 - signum
+	MOVW 4(FP), R1	// arg 2 - nsa
+	MOVW 8(FP), R2	// arg 3 - osa
+	MOVW $runtime·sigreturn_tramp(SB), R3	// arg 4 - tramp
+	MOVW $2, R4	// arg 5 - vers
+	MOVW R4, 4(R13)
+	ADD $4, R13	// pass arg 5 on stack
+	SWI $0xa00154	// sys___sigaction_sigtramp
+	SUB $4, R13
+	MOVW.CS $3, R8	// crash on syscall failure
+	MOVW.CS R8, (R8)
+	RET
+
+TEXT runtime·sigtramp(SB),NOSPLIT,$24
+	// this might be called in external code context,
+	// where g is not set.
+	// first save R0, because runtime·load_g will clobber it
+	MOVW	R0, 4(R13) // signum
+	MOVB	runtime·iscgo(SB), R0
+	CMP 	$0, R0
+	BL.NE	runtime·load_g(SB)
+
+	CMP $0, g
+	BNE 4(PC)
+	// signal number is already prepared in 4(R13)
+	MOVW $runtime·badsignal(SB), R11
+	BL (R11)
+	RET
+
+	// save g
+	MOVW g, R4
+	MOVW g, 20(R13)
+
+	// g = m->signal
+	MOVW g_m(g), R8
+	MOVW m_gsignal(R8), g
+
+	// R0 is already saved
+	MOVW R1, 8(R13) // info
+	MOVW R2, 12(R13) // context
+	MOVW R4, 16(R13) // gp
+
+	BL runtime·sighandler(SB)
+
+	// restore g
+	MOVW 20(R13), g
+	RET
+
+TEXT runtime·mmap(SB),NOSPLIT,$12
+	MOVW 0(FP), R0	// arg 1 - addr
+	MOVW 4(FP), R1	// arg 2 - len
+	MOVW 8(FP), R2	// arg 3 - prot
+	MOVW 12(FP), R3	// arg 4 - flags
+	// arg 5 (fid) and arg6 (offset_lo, offset_hi) are passed on stack
+	// note the C runtime only passes the 32-bit offset_lo to us
+	MOVW 16(FP), R4		// arg 5
+	MOVW R4, 4(R13)
+	MOVW 20(FP), R5		// arg 6 lower 32-bit
+	MOVW R5, 8(R13)
+	MOVW $0, R6 // higher 32-bit for arg 6
+	MOVW R6, 12(R13)
+	ADD $4, R13 // pass arg 5 and arg 6 on stack
+	SWI $0xa000c5	// sys_mmap
+	SUB $4, R13
+	MOVW	R0, ret+24(FP)
+	RET
+
+TEXT runtime·munmap(SB),NOSPLIT,$0
+	MOVW 0(FP), R0	// arg 1 - addr
+	MOVW 4(FP), R1	// arg 2 - len
+	SWI $0xa00049	// sys_munmap
+	MOVW.CS $0, R8	// crash on syscall failure
+	MOVW.CS R8, (R8)
+	RET
+
+TEXT runtime·madvise(SB),NOSPLIT,$0
+	MOVW 0(FP), R0	// arg 1 - addr
+	MOVW 4(FP), R1	// arg 2 - len
+	MOVW 8(FP), R2	// arg 3 - behav
+	SWI $0xa0004b	// sys_madvise
+	// ignore failure - maybe pages are locked
+	RET
+
+TEXT runtime·sigaltstack(SB),NOSPLIT,$-4
+	MOVW 0(FP), R0	// arg 1 - nss
+	MOVW 4(FP), R1	// arg 2 - oss
+	SWI $0xa00119	// sys___sigaltstack14
+	MOVW.CS $0, R8	// crash on syscall failure
+	MOVW.CS R8, (R8)
+	RET
+
+TEXT runtime·sysctl(SB),NOSPLIT,$8
+	MOVW 0(FP), R0	// arg 1 - name
+	MOVW 4(FP), R1	// arg 2 - namelen
+	MOVW 8(FP), R2	// arg 3 - oldp
+	MOVW 12(FP), R3	// arg 4 - oldlenp
+	MOVW 16(FP), R4	// arg 5 - newp
+	MOVW R4, 4(R13)
+	MOVW 20(FP), R4	// arg 6 - newlen
+	MOVW R4, 8(R13)
+	ADD $4, R13	// pass arg 5 and 6 on stack
+	SWI $0xa000ca	// sys___sysctl
+	SUB $4, R13
+	MOVW	R0, ret+24(FP)
+	RET
+
+// int32 runtime·kqueue(void)
+TEXT runtime·kqueue(SB),NOSPLIT,$0
+	SWI $0xa00158	// sys_kqueue
+	RSB.CS $0, R0
+	MOVW	R0, ret+0(FP)
+	RET
+
+// int32 runtime·kevent(int kq, Kevent *changelist, int nchanges, Kevent *eventlist, int nevents, Timespec *timeout)
+TEXT runtime·kevent(SB),NOSPLIT,$8
+	MOVW 0(FP), R0	// kq
+	MOVW 4(FP), R1	// changelist
+	MOVW 8(FP), R2	// nchanges
+	MOVW 12(FP), R3	// eventlist
+	MOVW 16(FP), R4	// nevents
+	MOVW R4, 4(R13)
+	MOVW 20(FP), R4	// timeout
+	MOVW R4, 8(R13)
+	ADD $4, R13	// pass arg 5 and 6 on stack
+	SWI $0xa001b3	// sys___kevent50
+	RSB.CS $0, R0
+	SUB $4, R13
+	MOVW	R0, ret+24(FP)
+	RET
+
+// void runtime·closeonexec(int32 fd)
+TEXT runtime·closeonexec(SB),NOSPLIT,$0
+	MOVW 0(FP), R0	// fd
+	MOVW $2, R1	// F_SETFD
+	MOVW $1, R2	// FD_CLOEXEC
+	SWI $0xa0005c	// sys_fcntl
+	RET
+
+TEXT runtime·casp(SB),NOSPLIT,$0
+	B	runtime·cas(SB)
+
+// TODO(minux): this is only valid for ARMv6+
+// bool armcas(int32 *val, int32 old, int32 new)
+// Atomically:
+//	if(*val == old){
+//		*val = new;
+//		return 1;
+//	}else
+//		return 0;
+TEXT runtime·cas(SB),NOSPLIT,$0
+	B runtime·armcas(SB)
+
+TEXT runtime·read_tls_fallback(SB),NOSPLIT,$-4
+	MOVM.WP [R1, R2, R3, R12], (R13)
+	SWI $0x00a0013c // _lwp_getprivate
+	MOVM.IAW    (R13), [R1, R2, R3, R12]
+	RET
diff --git a/src/runtime/sys_openbsd_386.s b/src/runtime/sys_openbsd_386.s
new file mode 100644
index 0000000..5cda776
--- /dev/null
+++ b/src/runtime/sys_openbsd_386.s
@@ -0,0 +1,398 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+//
+// System calls and other sys.stuff for 386, OpenBSD
+// /usr/src/sys/kern/syscalls.master for syscall numbers.
+//
+
+#include "zasm_GOOS_GOARCH.h"
+#include "textflag.h"
+
+#define	CLOCK_MONOTONIC	$3
+
+// Exit the entire program (like C exit)
+TEXT runtime·exit(SB),NOSPLIT,$-4
+	MOVL	$1, AX
+	INT	$0x80
+	MOVL	$0xf1, 0xf1		// crash
+	RET
+
+TEXT runtime·exit1(SB),NOSPLIT,$8
+	MOVL	$0, 0(SP)
+	MOVL	$0, 4(SP)		// arg 1 - notdead
+	MOVL	$302, AX		// sys___threxit
+	INT	$0x80
+	JAE	2(PC)
+	MOVL	$0xf1, 0xf1		// crash
+	RET
+
+TEXT runtime·open(SB),NOSPLIT,$-4
+	MOVL	$5, AX
+	INT	$0x80
+	MOVL	AX, ret+12(FP)
+	RET
+
+TEXT runtime·close(SB),NOSPLIT,$-4
+	MOVL	$6, AX
+	INT	$0x80
+	MOVL	AX, ret+4(FP)
+	RET
+
+TEXT runtime·read(SB),NOSPLIT,$-4
+	MOVL	$3, AX
+	INT	$0x80
+	MOVL	AX, ret+12(FP)
+	RET
+
+TEXT runtime·write(SB),NOSPLIT,$-4
+	MOVL	$4, AX			// sys_write
+	INT	$0x80
+	MOVL	AX, ret+12(FP)
+	RET
+
+TEXT runtime·usleep(SB),NOSPLIT,$24
+	MOVL	$0, DX
+	MOVL	usec+0(FP), AX
+	MOVL	$1000000, CX
+	DIVL	CX
+	MOVL	AX, 12(SP)		// tv_sec - l32
+	MOVL	$0, 16(SP)		// tv_sec - h32
+	MOVL	$1000, AX
+	MULL	DX
+	MOVL	AX, 20(SP)		// tv_nsec
+
+	MOVL	$0, 0(SP)
+	LEAL	12(SP), AX
+	MOVL	AX, 4(SP)		// arg 1 - rqtp
+	MOVL	$0, 8(SP)		// arg 2 - rmtp
+	MOVL	$91, AX			// sys_nanosleep
+	INT	$0x80
+	RET
+
+TEXT runtime·raise(SB),NOSPLIT,$12
+	MOVL	$299, AX		// sys_getthrid
+	INT	$0x80
+	MOVL	$0, 0(SP)
+	MOVL	AX, 4(SP)		// arg 1 - pid
+	MOVL	sig+0(FP), AX
+	MOVL	AX, 8(SP)		// arg 2 - signum
+	MOVL	$37, AX			// sys_kill
+	INT	$0x80
+	RET
+
+TEXT runtime·mmap(SB),NOSPLIT,$36
+	LEAL	addr+0(FP), SI
+	LEAL	4(SP), DI
+	CLD
+	MOVSL				// arg 1 - addr
+	MOVSL				// arg 2 - len
+	MOVSL				// arg 3 - prot
+	MOVSL				// arg 4 - flags
+	MOVSL				// arg 5 - fd
+	MOVL	$0, AX
+	STOSL				// arg 6 - pad
+	MOVSL				// arg 7 - offset
+	MOVL	$0, AX			// top 32 bits of file offset
+	STOSL
+	MOVL	$197, AX		// sys_mmap
+	INT	$0x80
+	MOVL	AX, ret+24(FP)
+	RET
+
+TEXT runtime·munmap(SB),NOSPLIT,$-4
+	MOVL	$73, AX			// sys_munmap
+	INT	$0x80
+	JAE	2(PC)
+	MOVL	$0xf1, 0xf1		// crash
+	RET
+
+TEXT runtime·madvise(SB),NOSPLIT,$-4
+	MOVL	$75, AX			// sys_madvise
+	INT	$0x80
+	JAE	2(PC)
+	MOVL	$0xf1, 0xf1		// crash
+	RET
+
+TEXT runtime·setitimer(SB),NOSPLIT,$-4
+	MOVL	$69, AX
+	INT	$0x80
+	RET
+
+// func now() (sec int64, nsec int32)
+TEXT time·now(SB), NOSPLIT, $32
+	LEAL	12(SP), BX
+	MOVL	$0, 4(SP)		// arg 1 - clock_id
+	MOVL	BX, 8(SP)		// arg 2 - tp
+	MOVL	$87, AX			// sys_clock_gettime
+	INT	$0x80
+
+	MOVL	12(SP), AX		// sec - l32
+	MOVL	AX, sec+0(FP)
+	MOVL	16(SP), AX		// sec - h32
+	MOVL	AX, sec+4(FP)
+
+	MOVL	20(SP), BX		// nsec
+	MOVL	BX, nsec+8(FP)
+	RET
+
+// int64 nanotime(void) so really
+// void nanotime(int64 *nsec)
+TEXT runtime·nanotime(SB),NOSPLIT,$32
+	LEAL	12(SP), BX
+	MOVL	CLOCK_MONOTONIC, 4(SP)	// arg 1 - clock_id
+	MOVL	BX, 8(SP)		// arg 2 - tp
+	MOVL	$87, AX			// sys_clock_gettime
+	INT	$0x80
+
+	MOVL    16(SP), CX		// sec - h32
+	IMULL   $1000000000, CX
+
+	MOVL    12(SP), AX		// sec - l32
+	MOVL    $1000000000, BX
+	MULL    BX			// result in dx:ax
+
+	MOVL	20(SP), BX		// nsec
+	ADDL	BX, AX
+	ADCL	CX, DX			// add high bits with carry
+
+	MOVL	AX, ret_lo+0(FP)
+	MOVL	DX, ret_hi+4(FP)
+	RET
+
+TEXT runtime·sigaction(SB),NOSPLIT,$-4
+	MOVL	$46, AX			// sys_sigaction
+	INT	$0x80
+	JAE	2(PC)
+	MOVL	$0xf1, 0xf1		// crash
+	RET
+
+TEXT runtime·sigprocmask(SB),NOSPLIT,$-4
+	MOVL	$48, AX			// sys_sigprocmask
+	INT	$0x80
+	JAE	2(PC)
+	MOVL	$0xf1, 0xf1		// crash
+	MOVL	AX, ret+8(FP)
+	RET
+
+TEXT runtime·sigtramp(SB),NOSPLIT,$44
+	get_tls(CX)
+
+	// check that g exists
+	MOVL	g(CX), DI
+	CMPL	DI, $0
+	JNE	6(PC)
+	MOVL	signo+0(FP), BX
+	MOVL	BX, 0(SP)
+	MOVL	$runtime·badsignal(SB), AX
+	CALL	AX
+	JMP 	sigtramp_ret
+
+	// save g
+	MOVL	DI, 20(SP)
+	
+	// g = m->gsignal
+	MOVL	g_m(DI), BX
+	MOVL	m_gsignal(BX), BX
+	MOVL	BX, g(CX)
+
+	// copy arguments for call to sighandler
+	MOVL	signo+0(FP), BX
+	MOVL	BX, 0(SP)
+	MOVL	info+4(FP), BX
+	MOVL	BX, 4(SP)
+	MOVL	context+8(FP), BX
+	MOVL	BX, 8(SP)
+	MOVL	DI, 12(SP)
+
+	CALL	runtime·sighandler(SB)
+
+	// restore g
+	get_tls(CX)
+	MOVL	20(SP), BX
+	MOVL	BX, g(CX)
+
+sigtramp_ret:
+	// call sigreturn
+	MOVL	context+8(FP), AX
+	MOVL	$0, 0(SP)		// syscall gap
+	MOVL	AX, 4(SP)		// arg 1 - sigcontext
+	MOVL	$103, AX		// sys_sigreturn
+	INT	$0x80
+	MOVL	$0xf1, 0xf1		// crash
+	RET
+
+// int32 tfork(void *param, uintptr psize, M *mp, G *gp, void (*fn)(void));
+TEXT runtime·tfork(SB),NOSPLIT,$12
+
+	// Copy mp, gp and fn from the parent stack onto the child stack.
+	MOVL	param+0(FP), AX
+	MOVL	8(AX), CX		// tf_stack
+	SUBL	$16, CX
+	MOVL	CX, 8(AX)
+	MOVL	mm+8(FP), SI
+	MOVL	SI, 0(CX)
+	MOVL	gg+12(FP), SI
+	MOVL	SI, 4(CX)
+	MOVL	fn+16(FP), SI
+	MOVL	SI, 8(CX)
+	MOVL	$1234, 12(CX)
+
+	MOVL	$0, 0(SP)		// syscall gap
+	MOVL	param+0(FP), AX
+	MOVL	AX, 4(SP)		// arg 1 - param
+	MOVL	psize+4(FP), AX
+	MOVL	AX, 8(SP)		// arg 2 - psize
+	MOVL	$8, AX			// sys___tfork
+	INT	$0x80
+
+	// Return if tfork syscall failed.
+	JCC	4(PC)
+	NEGL	AX
+	MOVL	AX, ret+20(FP)
+	RET
+
+	// In parent, return.
+	CMPL	AX, $0
+	JEQ	3(PC)
+	MOVL	AX, ret+20(FP)
+	RET
+
+	// Paranoia: check that SP is as we expect.
+	MOVL	12(SP), BP
+	CMPL	BP, $1234
+	JEQ	2(PC)
+	INT	$3
+
+	// Reload registers.
+	MOVL	0(SP), BX		// m
+	MOVL	4(SP), DX		// g
+	MOVL	8(SP), SI		// fn
+
+	// Set FS to point at m->tls.
+	LEAL	m_tls(BX), BP
+	PUSHAL				// save registers
+	PUSHL	BP
+	CALL	runtime·settls(SB)
+	POPL	AX
+	POPAL
+	
+	// Now segment is established.  Initialize m, g.
+	get_tls(AX)
+	MOVL	DX, g(AX)
+	MOVL	BX, g_m(DX)
+
+	CALL	runtime·stackcheck(SB)	// smashes AX, CX
+	MOVL	0(DX), DX		// paranoia; check they are not nil
+	MOVL	0(BX), BX
+
+	// More paranoia; check that stack splitting code works.
+	PUSHAL
+	CALL	runtime·emptyfunc(SB)
+	POPAL
+
+	// Call fn.
+	CALL	SI
+
+	CALL	runtime·exit1(SB)
+	MOVL	$0x1234, 0x1005
+	RET
+
+TEXT runtime·sigaltstack(SB),NOSPLIT,$-8
+	MOVL	$288, AX		// sys_sigaltstack
+	MOVL	new+4(SP), BX
+	MOVL	old+8(SP), CX
+	INT	$0x80
+	CMPL	AX, $0xfffff001
+	JLS	2(PC)
+	INT	$3
+	RET
+
+TEXT runtime·setldt(SB),NOSPLIT,$4
+	// Under OpenBSD we set the GS base instead of messing with the LDT.
+	MOVL	tls0+4(FP), AX
+	MOVL	AX, 0(SP)
+	CALL	runtime·settls(SB)
+	RET
+
+TEXT runtime·settls(SB),NOSPLIT,$8
+	// adjust for ELF: wants to use -8(GS) and -4(GS) for g and m
+	MOVL	tlsbase+0(FP), CX
+	ADDL	$8, CX
+	MOVL	$0, 0(SP)		// syscall gap
+	MOVL	CX, 4(SP)		// arg 1 - tcb
+	MOVL	$329, AX		// sys___set_tcb
+	INT	$0x80
+	JCC	2(PC)
+	MOVL	$0xf1, 0xf1		// crash
+	RET
+
+TEXT runtime·osyield(SB),NOSPLIT,$-4
+	MOVL	$298, AX		// sys_sched_yield
+	INT	$0x80
+	RET
+
+TEXT runtime·thrsleep(SB),NOSPLIT,$-4
+	MOVL	$94, AX			// sys___thrsleep
+	INT	$0x80
+	MOVL	AX, ret+20(FP)
+	RET
+
+TEXT runtime·thrwakeup(SB),NOSPLIT,$-4
+	MOVL	$301, AX		// sys___thrwakeup
+	INT	$0x80
+	MOVL	AX, ret+8(FP)
+	RET
+
+TEXT runtime·sysctl(SB),NOSPLIT,$28
+	LEAL	mib+0(FP), SI
+	LEAL	4(SP), DI
+	CLD
+	MOVSL				// arg 1 - name
+	MOVSL				// arg 2 - namelen
+	MOVSL				// arg 3 - oldp
+	MOVSL				// arg 4 - oldlenp
+	MOVSL				// arg 5 - newp
+	MOVSL				// arg 6 - newlen
+	MOVL	$202, AX		// sys___sysctl
+	INT	$0x80
+	JCC	4(PC)
+	NEGL	AX
+	MOVL	AX, ret+24(FP)
+	RET
+	MOVL	$0, AX
+	MOVL	AX, ret+24(FP)
+	RET
+
+// int32 runtime·kqueue(void);
+TEXT runtime·kqueue(SB),NOSPLIT,$0
+	MOVL	$269, AX
+	INT	$0x80
+	JAE	2(PC)
+	NEGL	AX
+	MOVL	AX, ret+0(FP)
+	RET
+
+// int32 runtime·kevent(int kq, Kevent *changelist, int nchanges, Kevent *eventlist, int nevents, Timespec *timeout);
+TEXT runtime·kevent(SB),NOSPLIT,$0
+	MOVL	$72, AX			// sys_kevent
+	INT	$0x80
+	JAE	2(PC)
+	NEGL	AX
+	MOVL	AX, ret+24(FP)
+	RET
+
+// int32 runtime·closeonexec(int32 fd);
+TEXT runtime·closeonexec(SB),NOSPLIT,$32
+	MOVL	$92, AX			// sys_fcntl
+	// 0(SP) is where the caller PC would be; kernel skips it
+	MOVL	fd+0(FP), BX
+	MOVL	BX, 4(SP)	// fd
+	MOVL	$2, 8(SP)	// F_SETFD
+	MOVL	$1, 12(SP)	// FD_CLOEXEC
+	INT	$0x80
+	JAE	2(PC)
+	NEGL	AX
+	RET
+
+GLOBL runtime·tlsoffset(SB),NOPTR,$4
diff --git a/src/runtime/sys_openbsd_amd64.s b/src/runtime/sys_openbsd_amd64.s
new file mode 100644
index 0000000..4e9db23
--- /dev/null
+++ b/src/runtime/sys_openbsd_amd64.s
@@ -0,0 +1,350 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+//
+// System calls and other sys.stuff for AMD64, OpenBSD
+// /usr/src/sys/kern/syscalls.master for syscall numbers.
+//
+
+#include "zasm_GOOS_GOARCH.h"
+#include "textflag.h"
+
+#define CLOCK_MONOTONIC	$3
+
+// int32 tfork(void *param, uintptr psize, M *mp, G *gp, void (*fn)(void));
+TEXT runtime·tfork(SB),NOSPLIT,$32
+
+	// Copy mp, gp and fn off parent stack for use by child.
+	MOVQ	mm+16(FP), R8
+	MOVQ	gg+24(FP), R9
+	MOVQ	fn+32(FP), R12
+
+	MOVQ	param+0(FP), DI
+	MOVQ	psize+8(FP), SI
+	MOVL	$8, AX			// sys___tfork
+	SYSCALL
+
+	// Return if tfork syscall failed.
+	JCC	4(PC)
+	NEGQ	AX
+	MOVL	AX, ret+40(FP)
+	RET
+
+	// In parent, return.
+	CMPL	AX, $0
+	JEQ	3(PC)
+	MOVL	AX, ret+40(FP)
+	RET
+
+	// Set FS to point at m->tls.
+	LEAQ	m_tls(R8), DI
+	CALL	runtime·settls(SB)
+
+	// In child, set up new stack.
+	get_tls(CX)
+	MOVQ	R8, g_m(R9)
+	MOVQ	R9, g(CX)
+	CALL	runtime·stackcheck(SB)
+
+	// Call fn
+	CALL	R12
+
+	// It shouldn't return.  If it does, exit
+	MOVQ	$0, DI			// arg 1 - notdead
+	MOVL	$302, AX		// sys___threxit
+	SYSCALL
+	JMP	-3(PC)			// keep exiting
+
+TEXT runtime·osyield(SB),NOSPLIT,$0
+	MOVL	$298, AX		// sys_sched_yield
+	SYSCALL
+	RET
+
+TEXT runtime·thrsleep(SB),NOSPLIT,$0
+	MOVQ	ident+0(FP), DI		// arg 1 - ident
+	MOVL	clock_id+8(FP), SI		// arg 2 - clock_id
+	MOVQ	tsp+16(FP), DX		// arg 3 - tp
+	MOVQ	lock+24(FP), R10		// arg 4 - lock
+	MOVQ	abort+32(FP), R8		// arg 5 - abort
+	MOVL	$94, AX			// sys___thrsleep
+	SYSCALL
+	MOVL	AX, ret+40(FP)
+	RET
+
+TEXT runtime·thrwakeup(SB),NOSPLIT,$0
+	MOVQ	ident+0(FP), DI		// arg 1 - ident
+	MOVL	n+8(FP), SI		// arg 2 - n
+	MOVL	$301, AX		// sys___thrwakeup
+	SYSCALL
+	MOVL	AX, ret+16(FP)
+	RET
+
+// Exit the entire program (like C exit)
+TEXT runtime·exit(SB),NOSPLIT,$-8
+	MOVL	code+0(FP), DI		// arg 1 - exit status
+	MOVL	$1, AX			// sys_exit
+	SYSCALL
+	MOVL	$0xf1, 0xf1		// crash
+	RET
+
+TEXT runtime·exit1(SB),NOSPLIT,$-8
+	MOVQ	$0, DI			// arg 1 - notdead
+	MOVL	$302, AX		// sys___threxit
+	SYSCALL
+	MOVL	$0xf1, 0xf1		// crash
+	RET
+
+TEXT runtime·open(SB),NOSPLIT,$-8
+	MOVQ	name+0(FP), DI		// arg 1 pathname
+	MOVL	mode+8(FP), SI		// arg 2 flags
+	MOVL	perm+12(FP), DX		// arg 3 mode
+	MOVL	$5, AX
+	SYSCALL
+	MOVL	AX, ret+16(FP)
+	RET
+
+TEXT runtime·close(SB),NOSPLIT,$-8
+	MOVL	fd+0(FP), DI		// arg 1 fd
+	MOVL	$6, AX
+	SYSCALL
+	MOVL	AX, ret+8(FP)
+	RET
+
+TEXT runtime·read(SB),NOSPLIT,$-8
+	MOVL	fd+0(FP), DI		// arg 1 fd
+	MOVQ	p+8(FP), SI		// arg 2 buf
+	MOVL	n+16(FP), DX		// arg 3 count
+	MOVL	$3, AX
+	SYSCALL
+	MOVL	AX, ret+24(FP)
+	RET
+
+TEXT runtime·write(SB),NOSPLIT,$-8
+	MOVQ	fd+0(FP), DI		// arg 1 - fd
+	MOVQ	p+8(FP), SI		// arg 2 - buf
+	MOVL	n+16(FP), DX		// arg 3 - nbyte
+	MOVL	$4, AX			// sys_write
+	SYSCALL
+	MOVL	AX, ret+24(FP)
+	RET
+
+TEXT runtime·usleep(SB),NOSPLIT,$16
+	MOVL	$0, DX
+	MOVL	usec+0(FP), AX
+	MOVL	$1000000, CX
+	DIVL	CX
+	MOVQ	AX, 0(SP)		// tv_sec
+	MOVL	$1000, AX
+	MULL	DX
+	MOVQ	AX, 8(SP)		// tv_nsec
+
+	MOVQ	SP, DI			// arg 1 - rqtp
+	MOVQ	$0, SI			// arg 2 - rmtp
+	MOVL	$91, AX			// sys_nanosleep
+	SYSCALL
+	RET
+
+TEXT runtime·raise(SB),NOSPLIT,$16
+	MOVL	$299, AX		// sys_getthrid
+	SYSCALL
+	MOVQ	AX, DI			// arg 1 - pid
+	MOVL	sig+0(FP), SI		// arg 2 - signum
+	MOVL	$37, AX			// sys_kill
+	SYSCALL
+	RET
+
+TEXT runtime·setitimer(SB),NOSPLIT,$-8
+	MOVL	mode+0(FP), DI		// arg 1 - which
+	MOVQ	new+8(FP), SI		// arg 2 - itv
+	MOVQ	old+16(FP), DX		// arg 3 - oitv
+	MOVL	$69, AX			// sys_setitimer
+	SYSCALL
+	RET
+
+// func now() (sec int64, nsec int32)
+TEXT time·now(SB), NOSPLIT, $32
+	MOVQ	$0, DI			// arg 1 - clock_id
+	LEAQ	8(SP), SI		// arg 2 - tp
+	MOVL	$87, AX			// sys_clock_gettime
+	SYSCALL
+	MOVQ	8(SP), AX		// sec
+	MOVQ	16(SP), DX		// nsec
+
+	// sec is in AX, nsec in DX
+	MOVQ	AX, sec+0(FP)
+	MOVL	DX, nsec+8(FP)
+	RET
+
+TEXT runtime·nanotime(SB),NOSPLIT,$24
+	MOVQ	CLOCK_MONOTONIC, DI	// arg 1 - clock_id
+	LEAQ	8(SP), SI		// arg 2 - tp
+	MOVL	$87, AX			// sys_clock_gettime
+	SYSCALL
+	MOVQ	8(SP), AX		// sec
+	MOVQ	16(SP), DX		// nsec
+
+	// sec is in AX, nsec in DX
+	// return nsec in AX
+	IMULQ	$1000000000, AX
+	ADDQ	DX, AX
+	MOVQ	AX, ret+0(FP)
+	RET
+
+TEXT runtime·sigaction(SB),NOSPLIT,$-8
+	MOVL	sig+0(FP), DI		// arg 1 - signum
+	MOVQ	new+8(FP), SI		// arg 2 - nsa
+	MOVQ	old+16(FP), DX		// arg 3 - osa
+	MOVL	$46, AX
+	SYSCALL
+	JCC	2(PC)
+	MOVL	$0xf1, 0xf1		// crash
+	RET
+
+TEXT runtime·sigprocmask(SB),NOSPLIT,$0
+	MOVL	mode+0(FP), DI		// arg 1 - how
+	MOVL	new+4(FP), SI		// arg 2 - set
+	MOVL	$48, AX			// sys_sigprocmask
+	SYSCALL
+	JCC	2(PC)
+	MOVL	$0xf1, 0xf1		// crash
+	MOVL	AX, ret+8(FP)
+	RET
+
+TEXT runtime·sigtramp(SB),NOSPLIT,$64
+	get_tls(BX)
+	
+	// check that g exists
+	MOVQ	g(BX), R10
+	CMPQ	R10, $0
+	JNE	5(PC)
+	MOVQ	DI, 0(SP)
+	MOVQ	$runtime·badsignal(SB), AX
+	CALL	AX
+	RET
+
+	// save g
+	MOVQ	R10, 40(SP)
+	
+	// g = m->signal
+	MOVQ	g_m(R10), BP
+	MOVQ	m_gsignal(BP), BP
+	MOVQ	BP, g(BX)
+	
+	MOVQ	DI, 0(SP)
+	MOVQ	SI, 8(SP)
+	MOVQ	DX, 16(SP)
+	MOVQ	R10, 24(SP)
+	
+	CALL	runtime·sighandler(SB)
+
+	// restore g
+	get_tls(BX)
+	MOVQ	40(SP), R10
+	MOVQ	R10, g(BX)
+	RET
+
+TEXT runtime·mmap(SB),NOSPLIT,$0
+	MOVQ	addr+0(FP), DI		// arg 1 - addr
+	MOVQ	n+8(FP), SI		// arg 2 - len
+	MOVL	prot+16(FP), DX		// arg 3 - prot
+	MOVL	flags+20(FP), R10		// arg 4 - flags
+	MOVL	fd+24(FP), R8		// arg 5 - fd
+	MOVL	off+28(FP), R9
+	SUBQ	$16, SP
+	MOVQ	R9, 8(SP)		// arg 7 - offset (passed on stack)
+	MOVQ	$0, R9			// arg 6 - pad
+	MOVL	$197, AX
+	SYSCALL
+	ADDQ	$16, SP
+	MOVQ	AX, ret+32(FP)
+	RET
+
+TEXT runtime·munmap(SB),NOSPLIT,$0
+	MOVQ	addr+0(FP), DI		// arg 1 - addr
+	MOVQ	n+8(FP), SI		// arg 2 - len
+	MOVL	$73, AX			// sys_munmap
+	SYSCALL
+	JCC	2(PC)
+	MOVL	$0xf1, 0xf1		// crash
+	RET
+
+TEXT runtime·madvise(SB),NOSPLIT,$0
+	MOVQ	addr+0(FP), DI		// arg 1 - addr
+	MOVQ	n+8(FP), SI		// arg 2 - len
+	MOVL	flags+16(FP), DX	// arg 3 - behav
+	MOVQ	$75, AX			// sys_madvise
+	SYSCALL
+	// ignore failure - maybe pages are locked
+	RET
+
+TEXT runtime·sigaltstack(SB),NOSPLIT,$-8
+	MOVQ	new+8(SP), DI		// arg 1 - nss
+	MOVQ	old+16(SP), SI		// arg 2 - oss
+	MOVQ	$288, AX		// sys_sigaltstack
+	SYSCALL
+	JCC	2(PC)
+	MOVL	$0xf1, 0xf1		// crash
+	RET
+
+// set tls base to DI
+TEXT runtime·settls(SB),NOSPLIT,$0
+	// adjust for ELF: wants to use -16(FS) and -8(FS) for g and m
+	ADDQ	$16, DI
+	MOVQ	$329, AX		// sys___settcb
+	SYSCALL
+	JCC	2(PC)
+	MOVL	$0xf1, 0xf1		// crash
+	RET
+
+TEXT runtime·sysctl(SB),NOSPLIT,$0
+	MOVQ	mib+0(FP), DI		// arg 1 - name
+	MOVL	miblen+8(FP), SI		// arg 2 - namelen
+	MOVQ	out+16(FP), DX		// arg 3 - oldp
+	MOVQ	size+24(FP), R10		// arg 4 - oldlenp
+	MOVQ	dst+32(FP), R8		// arg 5 - newp
+	MOVQ	ndst+40(FP), R9		// arg 6 - newlen
+	MOVQ	$202, AX		// sys___sysctl
+	SYSCALL
+	JCC	4(PC)
+	NEGQ	AX
+	MOVL	AX, ret+48(FP)
+	RET
+	MOVL	$0, AX
+	MOVL	AX, ret+48(FP)
+	RET
+
+// int32 runtime·kqueue(void);
+TEXT runtime·kqueue(SB),NOSPLIT,$0
+	MOVQ	$0, DI
+	MOVQ	$0, SI
+	MOVQ	$0, DX
+	MOVL	$269, AX
+	SYSCALL
+	JCC	2(PC)
+	NEGQ	AX
+	MOVL	AX, ret+0(FP)
+	RET
+
+// int32 runtime·kevent(int kq, Kevent *changelist, int nchanges, Kevent *eventlist, int nevents, Timespec *timeout);
+TEXT runtime·kevent(SB),NOSPLIT,$0
+	MOVL	fd+0(FP), DI
+	MOVQ	ev1+8(FP), SI
+	MOVL	nev1+16(FP), DX
+	MOVQ	ev2+24(FP), R10
+	MOVL	nev2+32(FP), R8
+	MOVQ	ts+40(FP), R9
+	MOVL	$72, AX
+	SYSCALL
+	JCC	2(PC)
+	NEGQ	AX
+	MOVL	AX, ret+48(FP)
+	RET
+
+// void runtime·closeonexec(int32 fd);
+TEXT runtime·closeonexec(SB),NOSPLIT,$0
+	MOVL	fd+0(FP), DI	// fd
+	MOVQ	$2, SI		// F_SETFD
+	MOVQ	$1, DX		// FD_CLOEXEC
+	MOVL	$92, AX		// fcntl
+	SYSCALL
+	RET
diff --git a/src/runtime/sys_plan9_386.s b/src/runtime/sys_plan9_386.s
new file mode 100644
index 0000000..a41b562
--- /dev/null
+++ b/src/runtime/sys_plan9_386.s
@@ -0,0 +1,249 @@
+// Copyright 2010 The Go 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 "zasm_GOOS_GOARCH.h"
+#include "textflag.h"
+
+// setldt(int entry, int address, int limit)
+TEXT runtime·setldt(SB),NOSPLIT,$0
+	RET
+
+TEXT runtime·open(SB),NOSPLIT,$0
+	MOVL    $14, AX
+	INT     $64
+	MOVL	AX, ret+12(FP)
+	RET
+
+TEXT runtime·pread(SB),NOSPLIT,$0
+	MOVL    $50, AX
+	INT     $64
+	MOVL	AX, ret+20(FP)
+	RET
+
+TEXT runtime·pwrite(SB),NOSPLIT,$0
+	MOVL    $51, AX
+	INT     $64
+	MOVL	AX, ret+20(FP)
+	RET
+
+// int32 _seek(int64*, int32, int64, int32)
+TEXT _seek<>(SB),NOSPLIT,$0
+	MOVL	$39, AX
+	INT	$64
+	RET
+
+TEXT runtime·seek(SB),NOSPLIT,$24
+	LEAL	ret+16(FP), AX
+	MOVL	fd+0(FP), BX
+	MOVL	offset_lo+4(FP), CX
+	MOVL	offset_hi+8(FP), DX
+	MOVL	whence+12(FP), SI
+	MOVL	AX, 0(SP)
+	MOVL	BX, 4(SP)
+	MOVL	CX, 8(SP)
+	MOVL	DX, 12(SP)
+	MOVL	SI, 16(SP)
+	CALL	_seek<>(SB)
+	CMPL	AX, $0
+	JGE	3(PC)
+	MOVL	$-1, ret_lo+16(FP)
+	MOVL	$-1, ret_hi+20(FP)
+	RET
+
+TEXT runtime·close(SB),NOSPLIT,$0
+	MOVL	$4, AX
+	INT	$64
+	MOVL	AX, ret+4(FP)
+	RET
+
+TEXT runtime·exits(SB),NOSPLIT,$0
+	MOVL    $8, AX
+	INT     $64
+	RET
+
+TEXT runtime·brk_(SB),NOSPLIT,$0
+	MOVL    $24, AX
+	INT     $64
+	MOVL	AX, ret+4(FP)
+	RET
+
+TEXT runtime·sleep(SB),NOSPLIT,$0
+	MOVL    $17, AX
+	INT     $64
+	MOVL	AX, ret+4(FP)
+	RET
+
+TEXT runtime·plan9_semacquire(SB),NOSPLIT,$0
+	MOVL	$37, AX
+	INT	$64
+	MOVL	AX, ret+8(FP)
+	RET
+
+TEXT runtime·plan9_tsemacquire(SB),NOSPLIT,$0
+	MOVL	$52, AX
+	INT	$64
+	MOVL	AX, ret+8(FP)
+	RET
+
+TEXT nsec<>(SB),NOSPLIT,$0
+	MOVL	$53, AX
+	INT	$64
+	RET
+
+TEXT runtime·nsec(SB),NOSPLIT,$8
+	LEAL	ret+4(FP), AX
+	MOVL	AX, 0(SP)
+	CALL	nsec<>(SB)
+	CMPL	AX, $0
+	JGE	3(PC)
+	MOVL	$-1, ret_lo+4(FP)
+	MOVL	$-1, ret_hi+8(FP)
+	RET
+
+// func now() (sec int64, nsec int32)
+TEXT time·now(SB),NOSPLIT,$8-12
+	CALL	runtime·nanotime(SB)
+	MOVL	0(SP), AX
+	MOVL	4(SP), DX
+
+	MOVL	$1000000000, CX
+	DIVL	CX
+	MOVL	AX, sec+0(FP)
+	MOVL	$0, sec+4(FP)
+	MOVL	DX, nsec+8(FP)
+	RET
+
+TEXT runtime·notify(SB),NOSPLIT,$0
+	MOVL	$28, AX
+	INT	$64
+	MOVL	AX, ret+4(FP)
+	RET
+
+TEXT runtime·noted(SB),NOSPLIT,$0
+	MOVL	$29, AX
+	INT	$64
+	MOVL	AX, ret+4(FP)
+	RET
+	
+TEXT runtime·plan9_semrelease(SB),NOSPLIT,$0
+	MOVL	$38, AX
+	INT	$64
+	MOVL	AX, ret+8(FP)
+	RET
+
+TEXT runtime·rfork(SB),NOSPLIT,$0
+	MOVL	$19, AX
+	INT	$64
+	MOVL	AX, ret+4(FP)
+	RET
+
+TEXT runtime·tstart_plan9(SB),NOSPLIT,$0
+	MOVL	newm+0(FP), CX
+	MOVL	m_g0(CX), DX
+
+	// Layout new m scheduler stack on os stack.
+	MOVL	SP, AX
+	MOVL	AX, (g_stack+stack_hi)(DX)
+	SUBL	$(64*1024), AX		// stack size
+	MOVL	AX, (g_stack+stack_lo)(DX)
+	MOVL	AX, g_stackguard0(DX)
+	MOVL	AX, g_stackguard1(DX)
+
+	// Initialize procid from TOS struct.
+	MOVL	_tos(SB), AX
+	MOVL	48(AX), AX
+	MOVL	AX, m_procid(CX)	// save pid as m->procid
+
+	// Finally, initialize g.
+	get_tls(BX)
+	MOVL	DX, g(BX)
+
+	CALL	runtime·stackcheck(SB)	// smashes AX, CX
+	CALL	runtime·mstart(SB)
+
+	MOVL	$0x1234, 0x1234		// not reached
+	RET
+
+// void sigtramp(void *ureg, int8 *note)
+TEXT runtime·sigtramp(SB),NOSPLIT,$0
+	get_tls(AX)
+
+	// check that g exists
+	MOVL	g(AX), BX
+	CMPL	BX, $0
+	JNE	3(PC)
+	CALL	runtime·badsignal2(SB) // will exit
+	RET
+
+	// save args
+	MOVL	ureg+4(SP), CX
+	MOVL	note+8(SP), DX
+
+	// change stack
+	MOVL	g_m(BX), BX
+	MOVL	m_gsignal(BX), BP
+	MOVL	(g_stack+stack_hi)(BP), BP
+	MOVL	BP, SP
+
+	// make room for args and g
+	SUBL	$24, SP
+
+	// save g
+	MOVL	g(AX), BP
+	MOVL	BP, 20(SP)
+
+	// g = m->gsignal
+	MOVL	m_gsignal(BX), DI
+	MOVL	DI, g(AX)
+
+	// load args and call sighandler
+	MOVL	CX, 0(SP)
+	MOVL	DX, 4(SP)
+	MOVL	BP, 8(SP)
+
+	CALL	runtime·sighandler(SB)
+	MOVL	12(SP), AX
+
+	// restore g
+	get_tls(BX)
+	MOVL	20(SP), BP
+	MOVL	BP, g(BX)
+
+	// call noted(AX)
+	MOVL	AX, 0(SP)
+	CALL	runtime·noted(SB)
+	RET
+
+// Only used by the 64-bit runtime.
+TEXT runtime·setfpmasks(SB),NOSPLIT,$0
+	RET
+
+#define ERRMAX 128	/* from os_plan9.h */
+
+// void errstr(int8 *buf, int32 len)
+TEXT errstr<>(SB),NOSPLIT,$0
+	MOVL    $41, AX
+	INT     $64
+	RET
+
+// func errstr() string
+// Only used by package syscall.
+// Grab error string due to a syscall made
+// in entersyscall mode, without going
+// through the allocator (issue 4994).
+// See ../syscall/asm_plan9_386.s:/·Syscall/
+TEXT runtime·errstr(SB),NOSPLIT,$8-8
+	get_tls(AX)
+	MOVL	g(AX), BX
+	MOVL	g_m(BX), BX
+	MOVL	m_errstr(BX), CX
+	MOVL	CX, 0(SP)
+	MOVL	$ERRMAX, 4(SP)
+	CALL	errstr<>(SB)
+	CALL	runtime·findnull(SB)
+	MOVL	4(SP), AX
+	MOVL	AX, ret_len+4(FP)
+	MOVL	0(SP), AX
+	MOVL	AX, ret_base+0(FP)
+	RET
diff --git a/src/runtime/sys_plan9_amd64.s b/src/runtime/sys_plan9_amd64.s
new file mode 100644
index 0000000..3a96c2b
--- /dev/null
+++ b/src/runtime/sys_plan9_amd64.s
@@ -0,0 +1,254 @@
+// Copyright 2010 The Go 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 "zasm_GOOS_GOARCH.h"
+#include "textflag.h"
+
+// setldt(int entry, int address, int limit)
+TEXT runtime·setldt(SB),NOSPLIT,$0
+	RET
+
+TEXT runtime·open(SB),NOSPLIT,$0
+	MOVQ	$14, BP
+	SYSCALL
+	MOVL	AX, ret+16(FP)
+	RET
+
+TEXT runtime·pread(SB),NOSPLIT,$0
+	MOVQ	$50, BP
+	SYSCALL
+	MOVL	AX, ret+32(FP)
+	RET
+
+TEXT runtime·pwrite(SB),NOSPLIT,$0
+	MOVQ	$51, BP
+	SYSCALL
+	MOVL	AX, ret+32(FP)
+	RET
+
+// int32 _seek(int64*, int32, int64, int32)
+TEXT _seek<>(SB),NOSPLIT,$0
+	MOVQ	$39, BP
+	SYSCALL
+	RET
+
+// int64 seek(int32, int64, int32)
+// Convenience wrapper around _seek, the actual system call.
+TEXT runtime·seek(SB),NOSPLIT,$32
+	LEAQ	ret+24(FP), AX
+	MOVL	fd+0(FP), BX
+	MOVQ	offset+8(FP), CX
+	MOVL	whence+16(FP), DX
+	MOVQ	AX, 0(SP)
+	MOVL	BX, 8(SP)
+	MOVQ	CX, 16(SP)
+	MOVL	DX, 24(SP)
+	CALL	_seek<>(SB)
+	CMPL	AX, $0
+	JGE	2(PC)
+	MOVQ	$-1, ret+24(FP)
+	RET
+
+TEXT runtime·close(SB),NOSPLIT,$0
+	MOVQ	$4, BP
+	SYSCALL
+	MOVL	AX, ret+8(FP)
+	RET
+
+TEXT runtime·exits(SB),NOSPLIT,$0
+	MOVQ	$8, BP
+	SYSCALL
+	RET
+
+TEXT runtime·brk_(SB),NOSPLIT,$0
+	MOVQ	$24, BP
+	SYSCALL
+	MOVQ	AX, ret+8(FP)
+	RET
+
+TEXT runtime·sleep(SB),NOSPLIT,$0
+	MOVQ	$17, BP
+	SYSCALL
+	MOVL	AX, ret+8(FP)
+	RET
+
+TEXT runtime·plan9_semacquire(SB),NOSPLIT,$0
+	MOVQ	$37, BP
+	SYSCALL
+	MOVL	AX, ret+16(FP)
+	RET
+
+TEXT runtime·plan9_tsemacquire(SB),NOSPLIT,$0
+	MOVQ	$52, BP
+	SYSCALL
+	MOVL	AX, ret+16(FP)
+	RET
+
+TEXT runtime·nsec(SB),NOSPLIT,$0
+	MOVQ	$53, BP
+	SYSCALL
+	MOVQ	AX, ret+8(FP)
+	RET
+
+// func now() (sec int64, nsec int32)
+TEXT time·now(SB),NOSPLIT,$8-12
+	CALL	runtime·nanotime(SB)
+	MOVQ	0(SP), AX
+
+	// generated code for
+	//	func f(x uint64) (uint64, uint64) { return x/1000000000, x%100000000 }
+	// adapted to reduce duplication
+	MOVQ	AX, CX
+	MOVQ	$1360296554856532783, AX
+	MULQ	CX
+	ADDQ	CX, DX
+	RCRQ	$1, DX
+	SHRQ	$29, DX
+	MOVQ	DX, sec+0(FP)
+	IMULQ	$1000000000, DX
+	SUBQ	DX, CX
+	MOVL	CX, nsec+8(FP)
+	RET
+
+TEXT runtime·notify(SB),NOSPLIT,$0
+	MOVQ	$28, BP
+	SYSCALL
+	MOVL	AX, ret+8(FP)
+	RET
+
+TEXT runtime·noted(SB),NOSPLIT,$0
+	MOVQ	$29, BP
+	SYSCALL
+	MOVL	AX, ret+8(FP)
+	RET
+	
+TEXT runtime·plan9_semrelease(SB),NOSPLIT,$0
+	MOVQ	$38, BP
+	SYSCALL
+	MOVL	AX, ret+16(FP)
+	RET
+
+TEXT runtime·rfork(SB),NOSPLIT,$0
+	MOVQ	$19, BP
+	SYSCALL
+	MOVL	AX, ret+8(FP)
+	RET
+
+TEXT runtime·tstart_plan9(SB),NOSPLIT,$0
+	MOVQ	newm+0(FP), CX
+	MOVQ	m_g0(CX), DX
+
+	// Layout new m scheduler stack on os stack.
+	MOVQ	SP, AX
+	MOVQ	AX, (g_stack+stack_hi)(DX)
+	SUBQ	$(64*1024), AX		// stack size
+	MOVQ	AX, (g_stack+stack_lo)(DX)
+	MOVQ	AX, g_stackguard0(DX)
+	MOVQ	AX, g_stackguard1(DX)
+
+	// Initialize procid from TOS struct.
+	MOVQ	_tos(SB), AX
+	MOVL	64(AX), AX
+	MOVQ	AX, m_procid(CX)	// save pid as m->procid
+
+	// Finally, initialize g.
+	get_tls(BX)
+	MOVQ	DX, g(BX)
+
+	CALL	runtime·stackcheck(SB)	// smashes AX, CX
+	CALL	runtime·mstart(SB)
+
+	MOVQ	$0x1234, 0x1234		// not reached
+	RET
+
+// This is needed by asm_amd64.s
+TEXT runtime·settls(SB),NOSPLIT,$0
+	RET
+
+// void sigtramp(void *ureg, int8 *note)
+TEXT runtime·sigtramp(SB),NOSPLIT,$0
+	get_tls(AX)
+
+	// check that g exists
+	MOVQ	g(AX), BX
+	CMPQ	BX, $0
+	JNE	3(PC)
+	CALL	runtime·badsignal2(SB) // will exit
+	RET
+
+	// save args
+	MOVQ	ureg+8(SP), CX
+	MOVQ	note+16(SP), DX
+
+	// change stack
+	MOVQ	g_m(BX), BX
+	MOVQ	m_gsignal(BX), R10
+	MOVQ	(g_stack+stack_hi)(R10), BP
+	MOVQ	BP, SP
+
+	// make room for args and g
+	SUBQ	$128, SP
+
+	// save g
+	MOVQ	g(AX), BP
+	MOVQ	BP, 32(SP)
+
+	// g = m->gsignal
+	MOVQ	R10, g(AX)
+
+	// load args and call sighandler
+	MOVQ	CX, 0(SP)
+	MOVQ	DX, 8(SP)
+	MOVQ	BP, 16(SP)
+
+	CALL	runtime·sighandler(SB)
+	MOVL	24(SP), AX
+
+	// restore g
+	get_tls(BX)
+	MOVQ	32(SP), R10
+	MOVQ	R10, g(BX)
+
+	// call noted(AX)
+	MOVQ	AX, 0(SP)
+	CALL	runtime·noted(SB)
+	RET
+
+TEXT runtime·setfpmasks(SB),NOSPLIT,$8
+	STMXCSR	0(SP)
+	MOVL	0(SP), AX
+	ANDL	$~0x3F, AX
+	ORL	$(0x3F<<7), AX
+	MOVL	AX, 0(SP)
+	LDMXCSR	0(SP)
+	RET
+
+#define ERRMAX 128	/* from os_plan9.h */
+
+// void errstr(int8 *buf, int32 len)
+TEXT errstr<>(SB),NOSPLIT,$0
+	MOVQ    $41, BP
+	SYSCALL
+	RET
+
+// func errstr() string
+// Only used by package syscall.
+// Grab error string due to a syscall made
+// in entersyscall mode, without going
+// through the allocator (issue 4994).
+// See ../syscall/asm_plan9_amd64.s:/·Syscall/
+TEXT runtime·errstr(SB),NOSPLIT,$16-16
+	get_tls(AX)
+	MOVQ	g(AX), BX
+	MOVQ	g_m(BX), BX
+	MOVQ	m_errstr(BX), CX
+	MOVQ	CX, 0(SP)
+	MOVQ	$ERRMAX, 8(SP)
+	CALL	errstr<>(SB)
+	CALL	runtime·findnull(SB)
+	MOVQ	8(SP), AX
+	MOVQ	AX, ret_len+8(FP)
+	MOVQ	0(SP), AX
+	MOVQ	AX, ret_base+0(FP)
+	RET
diff --git a/src/runtime/sys_solaris_amd64.s b/src/runtime/sys_solaris_amd64.s
new file mode 100644
index 0000000..0ebdab6
--- /dev/null
+++ b/src/runtime/sys_solaris_amd64.s
@@ -0,0 +1,351 @@
+// 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.
+//
+// System calls and other sys.stuff for AMD64, SunOS
+// /usr/include/sys/syscall.h for syscall numbers.
+//
+
+#include "zasm_GOOS_GOARCH.h"
+#include "textflag.h"
+
+// This is needed by asm_amd64.s
+TEXT runtime·settls(SB),NOSPLIT,$8
+	RET
+
+// void libc·miniterrno(void *(*___errno)(void));
+//
+// Set the TLS errno pointer in M.
+//
+// Called using runtime·asmcgocall from os_solaris.c:/minit.
+// NOT USING GO CALLING CONVENTION.
+TEXT runtime·miniterrno(SB),NOSPLIT,$0
+	// asmcgocall will put first argument into DI.
+	CALL	DI	// SysV ABI so returns in AX
+	get_tls(CX)
+	MOVQ	g(CX), BX
+	MOVQ	g_m(BX), BX
+	MOVQ	AX,	m_perrno(BX)
+	RET
+
+// int64 runtime·nanotime1(void);
+//
+// clock_gettime(3c) wrapper because Timespec is too large for
+// runtime·nanotime stack.
+//
+// Called using runtime·sysvicall6 from os_solaris.c:/nanotime.
+// NOT USING GO CALLING CONVENTION.
+TEXT runtime·nanotime1(SB),NOSPLIT,$0
+	// need space for the timespec argument.
+	SUBQ	$64, SP	// 16 bytes will do, but who knows in the future?
+	MOVQ	$3, DI	// CLOCK_REALTIME from <sys/time_impl.h>
+	MOVQ	SP, SI
+	MOVQ	libc·clock_gettime(SB), AX
+	CALL	AX
+	MOVQ	(SP), AX	// tv_sec from struct timespec
+	IMULQ	$1000000000, AX	// multiply into nanoseconds
+	ADDQ	8(SP), AX	// tv_nsec, offset should be stable.
+	ADDQ	$64, SP
+	RET
+
+// pipe(3c) wrapper that returns fds in AX, DX.
+// NOT USING GO CALLING CONVENTION.
+TEXT runtime·pipe1(SB),NOSPLIT,$0
+	SUBQ	$16, SP // 8 bytes will do, but stack has to be 16-byte alligned
+	MOVQ	SP, DI
+	MOVQ	libc·pipe(SB), AX
+	CALL	AX
+	MOVL	0(SP), AX
+	MOVL	4(SP), DX
+	ADDQ	$16, SP
+	RET
+
+// Call a library function with SysV calling conventions.
+// The called function can take a maximum of 6 INTEGER class arguments,
+// see 
+//   Michael Matz, Jan Hubicka, Andreas Jaeger, and Mark Mitchell
+//   System V Application Binary Interface 
+//   AMD64 Architecture Processor Supplement
+// section 3.2.3.
+//
+// Called by runtime·asmcgocall or runtime·cgocall.
+// NOT USING GO CALLING CONVENTION.
+TEXT runtime·asmsysvicall6(SB),NOSPLIT,$0
+	// asmcgocall will put first argument into DI.
+	PUSHQ	DI			// save for later
+	MOVQ	libcall_fn(DI), AX
+	MOVQ	libcall_args(DI), R11
+	MOVQ	libcall_n(DI), R10
+
+	get_tls(CX)
+	MOVQ	g(CX), BX
+	MOVQ	g_m(BX), BX
+	MOVQ	m_perrno(BX), DX
+	CMPQ	DX, $0
+	JEQ	skiperrno1
+	MOVL	$0, 0(DX)
+
+skiperrno1:
+	CMPQ	R11, $0
+	JEQ	skipargs
+	// Load 6 args into correspondent registers.
+	MOVQ	0(R11), DI
+	MOVQ	8(R11), SI
+	MOVQ	16(R11), DX
+	MOVQ	24(R11), CX
+	MOVQ	32(R11), R8
+	MOVQ	40(R11), R9
+skipargs:
+
+	// Call SysV function
+	CALL	AX
+
+	// Return result
+	POPQ	DI
+	MOVQ	AX, libcall_r1(DI)
+	MOVQ	DX, libcall_r2(DI)
+
+	get_tls(CX)
+	MOVQ	g(CX), BX
+	MOVQ	g_m(BX), BX
+	MOVQ	m_perrno(BX), AX
+	CMPQ	AX, $0
+	JEQ	skiperrno2
+	MOVL	0(AX), AX
+	MOVQ	AX, libcall_err(DI)
+
+skiperrno2:	
+	RET
+
+// uint32 tstart_sysvicall(M *newm);
+TEXT runtime·tstart_sysvicall(SB),NOSPLIT,$0
+	// DI contains first arg newm
+	MOVQ	m_g0(DI), DX		// g
+
+	// Make TLS entries point at g and m.
+	get_tls(BX)
+	MOVQ	DX, g(BX)
+	MOVQ	DI, g_m(DX)
+
+	// Layout new m scheduler stack on os stack.
+	MOVQ	SP, AX
+	MOVQ	AX, (g_stack+stack_hi)(DX)
+	SUBQ	$(0x100000), AX		// stack size
+	MOVQ	AX, (g_stack+stack_lo)(DX)
+	ADDQ	$const_StackGuard, AX
+	MOVQ	AX, g_stackguard0(DX)
+	MOVQ	AX, g_stackguard1(DX)
+
+	// Someday the convention will be D is always cleared.
+	CLD
+
+	CALL	runtime·stackcheck(SB)	// clobbers AX,CX
+	CALL	runtime·mstart(SB)
+
+	XORL	AX, AX			// return 0 == success
+	MOVL	AX, ret+8(FP)
+	RET
+
+// Careful, this is called by __sighndlr, a libc function. We must preserve
+// registers as per AMD 64 ABI.
+TEXT runtime·sigtramp(SB),NOSPLIT,$0
+	// Note that we are executing on altsigstack here, so we have
+	// more stack available than NOSPLIT would have us believe.
+	// To defeat the linker, we make our own stack frame with
+	// more space:
+	SUBQ    $184, SP
+
+	// save registers
+	MOVQ    BX, 32(SP)
+	MOVQ    BP, 40(SP)
+	MOVQ	R12, 48(SP)
+	MOVQ	R13, 56(SP)
+	MOVQ	R14, 64(SP)
+	MOVQ	R15, 72(SP)
+
+	get_tls(BX)
+	// check that g exists
+	MOVQ	g(BX), R10
+	CMPQ	R10, $0
+	JNE	allgood
+	MOVQ	DI, 0(SP)
+	MOVQ	$runtime·badsignal(SB), AX
+	CALL	AX
+	JMP	exit
+
+allgood:
+	// save g
+	MOVQ	R10, 80(SP)
+
+	// Save m->libcall and m->scratch. We need to do this because we
+	// might get interrupted by a signal in runtime·asmcgocall.
+
+	// save m->libcall 
+	MOVQ	g_m(R10), BP
+	LEAQ	m_libcall(BP), R11
+	MOVQ	libcall_fn(R11), R10
+	MOVQ	R10, 88(SP)
+	MOVQ	libcall_args(R11), R10
+	MOVQ	R10, 96(SP)
+	MOVQ	libcall_n(R11), R10
+	MOVQ	R10, 104(SP)
+	MOVQ    libcall_r1(R11), R10
+	MOVQ    R10, 168(SP)
+	MOVQ    libcall_r2(R11), R10
+	MOVQ    R10, 176(SP)
+
+	// save m->scratch
+	LEAQ	m_scratch(BP), R11
+	MOVQ	0(R11), R10
+	MOVQ	R10, 112(SP)
+	MOVQ	8(R11), R10
+	MOVQ	R10, 120(SP)
+	MOVQ	16(R11), R10
+	MOVQ	R10, 128(SP)
+	MOVQ	24(R11), R10
+	MOVQ	R10, 136(SP)
+	MOVQ	32(R11), R10
+	MOVQ	R10, 144(SP)
+	MOVQ	40(R11), R10
+	MOVQ	R10, 152(SP)
+
+	// save errno, it might be EINTR; stuff we do here might reset it.
+	MOVQ	m_perrno(BP), R10
+	MOVL	0(R10), R10
+	MOVQ	R10, 160(SP)
+
+	MOVQ	g(BX), R10
+	// g = m->gsignal
+	MOVQ	m_gsignal(BP), BP
+	MOVQ	BP, g(BX)
+
+	// prepare call
+	MOVQ	DI, 0(SP)
+	MOVQ	SI, 8(SP)
+	MOVQ	DX, 16(SP)
+	MOVQ	R10, 24(SP)
+	CALL	runtime·sighandler(SB)
+
+	get_tls(BX)
+	MOVQ	g(BX), BP
+	MOVQ	g_m(BP), BP
+	// restore libcall
+	LEAQ	m_libcall(BP), R11
+	MOVQ	88(SP), R10
+	MOVQ	R10, libcall_fn(R11)
+	MOVQ	96(SP), R10
+	MOVQ	R10, libcall_args(R11)
+	MOVQ	104(SP), R10
+	MOVQ	R10, libcall_n(R11)
+	MOVQ    168(SP), R10
+	MOVQ    R10, libcall_r1(R11)
+	MOVQ    176(SP), R10
+	MOVQ    R10, libcall_r2(R11)
+
+	// restore scratch
+	LEAQ	m_scratch(BP), R11
+	MOVQ	112(SP), R10
+	MOVQ	R10, 0(R11)
+	MOVQ	120(SP), R10
+	MOVQ	R10, 8(R11)
+	MOVQ	128(SP), R10
+	MOVQ	R10, 16(R11)
+	MOVQ	136(SP), R10
+	MOVQ	R10, 24(R11)
+	MOVQ	144(SP), R10
+	MOVQ	R10, 32(R11)
+	MOVQ	152(SP), R10
+	MOVQ	R10, 40(R11)
+
+	// restore errno
+	MOVQ	m_perrno(BP), R11
+	MOVQ	160(SP), R10
+	MOVL	R10, 0(R11)
+
+	// restore g
+	MOVQ	80(SP), R10
+	MOVQ	R10, g(BX)
+
+exit:
+	// restore registers
+	MOVQ	32(SP), BX
+	MOVQ	40(SP), BP
+	MOVQ	48(SP), R12
+	MOVQ	56(SP), R13
+	MOVQ	64(SP), R14
+	MOVQ	72(SP), R15
+
+	ADDQ    $184, SP
+	RET
+
+// Called from runtime·usleep (Go). Can be called on Go stack, on OS stack,
+// can also be called in cgo callback path without a g->m.
+TEXT runtime·usleep1(SB),NOSPLIT,$0
+	MOVL	usec+0(FP), DI
+	MOVQ	$runtime·usleep2(SB), AX // to hide from 6l
+
+	// Execute call on m->g0.
+	get_tls(R15)
+	CMPQ	R15, $0
+	JE	usleep1_noswitch
+
+	MOVQ	g(R15), R13
+	CMPQ	R13, $0
+	JE	usleep1_noswitch
+	MOVQ	g_m(R13), R13
+	CMPQ	R13, $0
+	JE	usleep1_noswitch
+	// TODO(aram): do something about the cpu profiler here.
+
+	MOVQ	m_g0(R13), R14
+	CMPQ	g(R15), R14
+	JNE	usleep1_switch
+	// executing on m->g0 already
+	CALL	AX
+	RET
+
+usleep1_switch:
+	// Switch to m->g0 stack and back.
+	MOVQ	(g_sched+gobuf_sp)(R14), R14
+	MOVQ	SP, -8(R14)
+	LEAQ	-8(R14), SP
+	CALL	AX
+	MOVQ	0(SP), SP
+	RET
+
+usleep1_noswitch:
+	// Not a Go-managed thread. Do not switch stack.
+	CALL	AX
+	RET
+
+// Runs on OS stack. duration (in µs units) is in DI.
+TEXT runtime·usleep2(SB),NOSPLIT,$0
+	MOVQ	libc·usleep(SB), AX
+	CALL	AX
+	RET
+
+// Runs on OS stack, called from runtime·osyield.
+TEXT runtime·osyield1(SB),NOSPLIT,$0
+	MOVQ	libc·sched_yield(SB), AX
+	CALL	AX
+	RET
+
+// func now() (sec int64, nsec int32)
+TEXT time·now(SB),NOSPLIT,$8-12
+	CALL	runtime·nanotime(SB)
+	MOVQ	0(SP), AX
+
+	// generated code for
+	//	func f(x uint64) (uint64, uint64) { return x/1000000000, x%100000000 }
+	// adapted to reduce duplication
+	MOVQ	AX, CX
+	MOVQ	$1360296554856532783, AX
+	MULQ	CX
+	ADDQ	CX, DX
+	RCRQ	$1, DX
+	SHRQ	$29, DX
+	MOVQ	DX, sec+0(FP)
+	IMULQ	$1000000000, DX
+	SUBQ	DX, CX
+	MOVL	CX, nsec+8(FP)
+	RET
diff --git a/src/runtime/sys_windows_386.s b/src/runtime/sys_windows_386.s
new file mode 100644
index 0000000..932fe9d
--- /dev/null
+++ b/src/runtime/sys_windows_386.s
@@ -0,0 +1,433 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "zasm_GOOS_GOARCH.h"
+#include "textflag.h"
+
+// void runtime·asmstdcall(void *c);
+TEXT runtime·asmstdcall(SB),NOSPLIT,$0
+	MOVL	fn+0(FP), BX
+
+	// SetLastError(0).
+	MOVL	$0, 0x34(FS)
+
+	// Copy args to the stack.
+	MOVL	SP, BP
+	MOVL	libcall_n(BX), CX	// words
+	MOVL	CX, AX
+	SALL	$2, AX
+	SUBL	AX, SP			// room for args
+	MOVL	SP, DI
+	MOVL	libcall_args(BX), SI
+	CLD
+	REP; MOVSL
+
+	// Call stdcall or cdecl function.
+	// DI SI BP BX are preserved, SP is not
+	CALL	libcall_fn(BX)
+	MOVL	BP, SP
+
+	// Return result.
+	MOVL	fn+0(FP), BX
+	MOVL	AX, libcall_r1(BX)
+	MOVL	DX, libcall_r2(BX)
+
+	// GetLastError().
+	MOVL	0x34(FS), AX
+	MOVL	AX, libcall_err(BX)
+
+	RET
+
+TEXT	runtime·badsignal2(SB),NOSPLIT,$24
+	// stderr
+	MOVL	$-12, 0(SP)
+	MOVL	SP, BP
+	CALL	*runtime·GetStdHandle(SB)
+	MOVL	BP, SP
+
+	MOVL	AX, 0(SP)	// handle
+	MOVL	$runtime·badsignalmsg(SB), DX // pointer
+	MOVL	DX, 4(SP)
+	MOVL	runtime·badsignallen(SB), DX // count
+	MOVL	DX, 8(SP)
+	LEAL	20(SP), DX  // written count
+	MOVL	$0, 0(DX)
+	MOVL	DX, 12(SP)
+	MOVL	$0, 16(SP) // overlapped
+	CALL	*runtime·WriteFile(SB)
+	MOVL	BP, SI
+	RET
+
+// faster get/set last error
+TEXT runtime·getlasterror(SB),NOSPLIT,$0
+	MOVL	0x34(FS), AX
+	MOVL	AX, ret+0(FP)
+	RET
+
+TEXT runtime·setlasterror(SB),NOSPLIT,$0
+	MOVL	err+0(FP), AX
+	MOVL	AX, 0x34(FS)
+	RET
+
+// Called by Windows as a Vectored Exception Handler (VEH).
+// First argument is pointer to struct containing
+// exception record and context pointers.
+// Handler function is stored in AX.
+// Return 0 for 'not handled', -1 for handled.
+TEXT runtime·sigtramp(SB),NOSPLIT,$0-0
+	MOVL	ptrs+0(FP), CX
+	SUBL	$40, SP
+
+	// save callee-saved registers
+	MOVL	BX, 28(SP)
+	MOVL	BP, 16(SP)
+	MOVL	SI, 20(SP)
+	MOVL	DI, 24(SP)
+
+	MOVL	AX, SI	// save handler address
+
+	// find g
+	get_tls(DX)
+	CMPL	DX, $0
+	JNE	3(PC)
+	MOVL	$0, AX // continue
+	JMP	done
+	MOVL	g(DX), DX
+	CMPL	DX, $0
+	JNE	2(PC)
+	CALL	runtime·badsignal2(SB)
+
+	// save g and SP in case of stack switch
+	MOVL	DX, 32(SP)	// g
+	MOVL	SP, 36(SP)
+
+	// do we need to switch to the g0 stack?
+	MOVL	g_m(DX), BX
+	MOVL	m_g0(BX), BX
+	CMPL	DX, BX
+	JEQ	sigtramp_g0
+
+	// switch to the g0 stack
+	get_tls(BP)
+	MOVL	BX, g(BP)
+	MOVL	(g_sched+gobuf_sp)(BX), DI
+	// make it look like mstart called us on g0, to stop traceback
+	SUBL	$4, DI
+	MOVL	$runtime·mstart(SB), 0(DI)
+	// traceback will think that we've done SUBL
+	// on this stack, so subtract them here to match.
+	// (we need room for sighandler arguments anyway).
+	// and re-save old SP for restoring later.
+	SUBL	$40, DI
+	MOVL	SP, 36(DI)
+	MOVL	DI, SP
+
+sigtramp_g0:
+	MOVL	0(CX), BX // ExceptionRecord*
+	MOVL	4(CX), CX // Context*
+	MOVL	BX, 0(SP)
+	MOVL	CX, 4(SP)
+	MOVL	DX, 8(SP)
+	CALL	SI	// call handler
+	// AX is set to report result back to Windows
+	MOVL	12(SP), AX
+
+	// switch back to original stack and g
+	// no-op if we never left.
+	MOVL	36(SP), SP
+	MOVL	32(SP), DX
+	get_tls(BP)
+	MOVL	DX, g(BP)
+
+done:
+	// restore callee-saved registers
+	MOVL	24(SP), DI
+	MOVL	20(SP), SI
+	MOVL	16(SP), BP
+	MOVL	28(SP), BX
+
+	ADDL	$40, SP
+	// RET 4 (return and pop 4 bytes parameters)
+	BYTE $0xC2; WORD $4
+	RET // unreached; make assembler happy
+ 
+TEXT runtime·exceptiontramp(SB),NOSPLIT,$0
+	MOVL	$runtime·exceptionhandler(SB), AX
+	JMP	runtime·sigtramp(SB)
+
+TEXT runtime·firstcontinuetramp(SB),NOSPLIT,$0-0
+	// is never called
+	INT	$3
+
+TEXT runtime·lastcontinuetramp(SB),NOSPLIT,$0-0
+	MOVL	$runtime·lastcontinuehandler(SB), AX
+	JMP	runtime·sigtramp(SB)
+
+TEXT runtime·ctrlhandler(SB),NOSPLIT,$0
+	PUSHL	$runtime·ctrlhandler1(SB)
+	CALL	runtime·externalthreadhandler(SB)
+	MOVL	4(SP), CX
+	ADDL	$12, SP
+	JMP	CX
+
+TEXT runtime·profileloop(SB),NOSPLIT,$0
+	PUSHL	$runtime·profileloop1(SB)
+	CALL	runtime·externalthreadhandler(SB)
+	MOVL	4(SP), CX
+	ADDL	$12, SP
+	JMP	CX
+
+TEXT runtime·externalthreadhandler(SB),NOSPLIT,$0
+	PUSHL	BP
+	MOVL	SP, BP
+	PUSHL	BX
+	PUSHL	SI
+	PUSHL	DI
+	PUSHL	0x14(FS)
+	MOVL	SP, DX
+
+	// setup dummy m, g
+	SUBL	$m_end, SP		// space for M
+	MOVL	SP, 0(SP)
+	MOVL	$m_end, 4(SP)
+	CALL	runtime·memclr(SB)	// smashes AX,BX,CX
+
+	LEAL	m_tls(SP), CX
+	MOVL	CX, 0x14(FS)
+	MOVL	SP, BX
+	SUBL	$g_end, SP		// space for G
+	MOVL	SP, g(CX)
+	MOVL	SP, m_g0(BX)
+
+	MOVL	SP, 0(SP)
+	MOVL	$g_end, 4(SP)
+	CALL	runtime·memclr(SB)	// smashes AX,BX,CX
+	LEAL	g_end(SP), BX
+	MOVL	BX, g_m(SP)
+	LEAL	-8192(SP), CX
+	MOVL	CX, (g_stack+stack_lo)(SP)
+	ADDL	$const_StackGuard, CX
+	MOVL	CX, g_stackguard0(SP)
+	MOVL	CX, g_stackguard1(SP)
+	MOVL	DX, (g_stack+stack_hi)(SP)
+
+	PUSHL	16(BP)			// arg for handler
+	CALL	8(BP)
+	POPL	CX
+
+	get_tls(CX)
+	MOVL	g(CX), CX
+	MOVL	(g_stack+stack_hi)(CX), SP
+	POPL	0x14(FS)
+	POPL	DI
+	POPL	SI
+	POPL	BX
+	POPL	BP
+	RET
+
+GLOBL runtime·cbctxts(SB), NOPTR, $4
+
+TEXT runtime·callbackasm1+0(SB),NOSPLIT,$0
+  	MOVL	0(SP), AX	// will use to find our callback context
+
+	// remove return address from stack, we are not returning there
+	ADDL	$4, SP
+
+	// address to callback parameters into CX
+	LEAL	4(SP), CX
+
+	// save registers as required for windows callback
+	PUSHL	DI
+	PUSHL	SI
+	PUSHL	BP
+	PUSHL	BX
+
+	// determine index into runtime·cbctxts table
+	SUBL	$runtime·callbackasm(SB), AX
+	MOVL	$0, DX
+	MOVL	$5, BX	// divide by 5 because each call instruction in runtime·callbacks is 5 bytes long
+	DIVL	BX,
+
+	// find correspondent runtime·cbctxts table entry
+	MOVL	runtime·cbctxts(SB), BX
+	MOVL	-4(BX)(AX*4), BX
+
+	// extract callback context
+	MOVL	cbctxt_gobody(BX), AX
+	MOVL	cbctxt_argsize(BX), DX
+
+	// preserve whatever's at the memory location that
+	// the callback will use to store the return value
+	PUSHL	0(CX)(DX*1)
+
+	// extend argsize by size of return value
+	ADDL	$4, DX
+
+	// remember how to restore stack on return
+	MOVL	cbctxt_restorestack(BX), BX
+	PUSHL	BX
+
+	// call target Go function
+	PUSHL	DX			// argsize (including return value)
+	PUSHL	CX			// callback parameters
+	PUSHL	AX			// address of target Go function
+	CLD
+	CALL	runtime·cgocallback_gofunc(SB)
+	POPL	AX
+	POPL	CX
+	POPL	DX
+
+	// how to restore stack on return
+	POPL	BX
+
+	// return value into AX (as per Windows spec)
+	// and restore previously preserved value
+	MOVL	-4(CX)(DX*1), AX
+	POPL	-4(CX)(DX*1)
+
+	MOVL	BX, CX			// cannot use BX anymore
+
+	// restore registers as required for windows callback
+	POPL	BX
+	POPL	BP
+	POPL	SI
+	POPL	DI
+
+	// remove callback parameters before return (as per Windows spec)
+	POPL	DX
+	ADDL	CX, SP
+	PUSHL	DX
+
+	CLD
+
+	RET
+
+// void tstart(M *newm);
+TEXT runtime·tstart(SB),NOSPLIT,$0
+	MOVL	newm+4(SP), CX		// m
+	MOVL	m_g0(CX), DX		// g
+
+	// Layout new m scheduler stack on os stack.
+	MOVL	SP, AX
+	MOVL	AX, (g_stack+stack_hi)(DX)
+	SUBL	$(64*1024), AX		// stack size
+	MOVL	AX, (g_stack+stack_lo)(DX)
+	ADDL	$const_StackGuard, AX
+	MOVL	AX, g_stackguard0(DX)
+	MOVL	AX, g_stackguard1(DX)
+
+	// Set up tls.
+	LEAL	m_tls(CX), SI
+	MOVL	SI, 0x14(FS)
+	MOVL	CX, g_m(DX)
+	MOVL	DX, g(SI)
+
+	// Someday the convention will be D is always cleared.
+	CLD
+
+	CALL	runtime·stackcheck(SB)	// clobbers AX,CX
+	CALL	runtime·mstart(SB)
+
+	RET
+
+// uint32 tstart_stdcall(M *newm);
+TEXT runtime·tstart_stdcall(SB),NOSPLIT,$0
+	MOVL	newm+4(SP), BX
+
+	PUSHL	BX
+	CALL	runtime·tstart(SB)
+	POPL	BX
+
+	// Adjust stack for stdcall to return properly.
+	MOVL	(SP), AX		// save return address
+	ADDL	$4, SP			// remove single parameter
+	MOVL	AX, (SP)		// restore return address
+
+	XORL	AX, AX			// return 0 == success
+
+	RET
+
+// setldt(int entry, int address, int limit)
+TEXT runtime·setldt(SB),NOSPLIT,$0
+	MOVL	address+4(FP), CX
+	MOVL	CX, 0x14(FS)
+	RET
+
+// Sleep duration is in 100ns units.
+TEXT runtime·usleep1(SB),NOSPLIT,$0
+	MOVL	usec+0(FP), BX
+	MOVL	$runtime·usleep2(SB), AX // to hide from 8l
+
+	// Execute call on m->g0 stack, in case we are not actually
+	// calling a system call wrapper, like when running under WINE.
+	get_tls(CX)
+	CMPL	CX, $0
+	JNE	3(PC)
+	// Not a Go-managed thread. Do not switch stack.
+	CALL	AX
+	RET
+
+	MOVL	g(CX), BP
+	MOVL	g_m(BP), BP
+
+	// leave pc/sp for cpu profiler
+	MOVL	(SP), SI
+	MOVL	SI, m_libcallpc(BP)
+	MOVL	g(CX), SI
+	MOVL	SI, m_libcallg(BP)
+	// sp must be the last, because once async cpu profiler finds
+	// all three values to be non-zero, it will use them
+	LEAL	usec+0(FP), SI
+	MOVL	SI, m_libcallsp(BP)
+
+	MOVL	m_g0(BP), SI
+	CMPL	g(CX), SI
+	JNE	usleep1_switch
+	// executing on m->g0 already
+	CALL	AX
+	JMP	usleep1_ret
+
+usleep1_switch:
+	// Switch to m->g0 stack and back.
+	MOVL	(g_sched+gobuf_sp)(SI), SI
+	MOVL	SP, -4(SI)
+	LEAL	-4(SI), SP
+	CALL	AX
+	MOVL	0(SP), SP
+
+usleep1_ret:
+	get_tls(CX)
+	MOVL	g(CX), BP
+	MOVL	g_m(BP), BP
+	MOVL	$0, m_libcallsp(BP)
+	RET
+
+// Runs on OS stack. duration (in 100ns units) is in BX.
+TEXT runtime·usleep2(SB),NOSPLIT,$20
+	// Want negative 100ns units.
+	NEGL	BX
+	MOVL	$-1, hi-4(SP)
+	MOVL	BX, lo-8(SP)
+	LEAL	lo-8(SP), BX
+	MOVL	BX, ptime-12(SP)
+	MOVL	$0, alertable-16(SP)
+	MOVL	$-1, handle-20(SP)
+	MOVL	SP, BP
+	MOVL	runtime·NtWaitForSingleObject(SB), AX
+	CALL	AX
+	MOVL	BP, SP
+	RET
+
+// func now() (sec int64, nsec int32)
+TEXT time·now(SB),NOSPLIT,$8-12
+	CALL	runtime·unixnano(SB)
+	MOVL	0(SP), AX
+	MOVL	4(SP), DX
+
+	MOVL	$1000000000, CX
+	DIVL	CX
+	MOVL	AX, sec+0(FP)
+	MOVL	$0, sec+4(FP)
+	MOVL	DX, nsec+8(FP)
+	RET
diff --git a/src/runtime/sys_windows_amd64.s b/src/runtime/sys_windows_amd64.s
new file mode 100644
index 0000000..e6190ce
--- /dev/null
+++ b/src/runtime/sys_windows_amd64.s
@@ -0,0 +1,462 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "zasm_GOOS_GOARCH.h"
+#include "textflag.h"
+
+// maxargs should be divisible by 2, as Windows stack
+// must be kept 16-byte aligned on syscall entry.
+#define maxargs 16
+
+// void runtime·asmstdcall(void *c);
+TEXT runtime·asmstdcall(SB),NOSPLIT,$0
+	// asmcgocall will put first argument into CX.
+	PUSHQ	CX			// save for later
+	MOVQ	libcall_fn(CX), AX
+	MOVQ	libcall_args(CX), SI
+	MOVQ	libcall_n(CX), CX
+
+	// SetLastError(0).
+	MOVQ	0x30(GS), DI
+	MOVL	$0, 0x68(DI)
+
+	SUBQ	$(maxargs*8), SP	// room for args
+
+	// Fast version, do not store args on the stack.
+	CMPL	CX, $4
+	JLE	loadregs
+
+	// Check we have enough room for args.
+	CMPL	CX, $maxargs
+	JLE	2(PC)
+	INT	$3			// not enough room -> crash
+
+	// Copy args to the stack.
+	MOVQ	SP, DI
+	CLD
+	REP; MOVSQ
+	MOVQ	SP, SI
+
+loadregs:
+	// Load first 4 args into correspondent registers.
+	MOVQ	0(SI), CX
+	MOVQ	8(SI), DX
+	MOVQ	16(SI), R8
+	MOVQ	24(SI), R9
+
+	// Call stdcall function.
+	CALL	AX
+
+	ADDQ	$(maxargs*8), SP
+
+	// Return result.
+	POPQ	CX
+	MOVQ	AX, libcall_r1(CX)
+
+	// GetLastError().
+	MOVQ	0x30(GS), DI
+	MOVL	0x68(DI), AX
+	MOVQ	AX, libcall_err(CX)
+
+	RET
+
+TEXT runtime·badsignal2(SB),NOSPLIT,$48
+	// stderr
+	MOVQ	$-12, CX // stderr
+	MOVQ	CX, 0(SP)
+	MOVQ	runtime·GetStdHandle(SB), AX
+	CALL	AX
+
+	MOVQ	AX, CX	// handle
+	MOVQ	CX, 0(SP)
+	MOVQ	$runtime·badsignalmsg(SB), DX // pointer
+	MOVQ	DX, 8(SP)
+	MOVL	$runtime·badsignallen(SB), R8 // count
+	MOVQ	R8, 16(SP)
+	LEAQ	40(SP), R9  // written count
+	MOVQ	$0, 0(R9)
+	MOVQ	R9, 24(SP)
+	MOVQ	$0, 32(SP)	// overlapped
+	MOVQ	runtime·WriteFile(SB), AX
+	CALL	AX
+	
+	RET
+
+// faster get/set last error
+TEXT runtime·getlasterror(SB),NOSPLIT,$0
+	MOVQ	0x30(GS), AX
+	MOVL	0x68(AX), AX
+	MOVL	AX, ret+0(FP)
+	RET
+
+TEXT runtime·setlasterror(SB),NOSPLIT,$0
+	MOVL	err+0(FP), AX
+	MOVQ	0x30(GS),	CX
+	MOVL	AX, 0x68(CX)
+	RET
+
+// Called by Windows as a Vectored Exception Handler (VEH).
+// First argument is pointer to struct containing
+// exception record and context pointers.
+// Handler function is stored in AX.
+// Return 0 for 'not handled', -1 for handled.
+TEXT runtime·sigtramp(SB),NOSPLIT,$0-0
+	// CX: PEXCEPTION_POINTERS ExceptionInfo
+
+	// DI SI BP BX R12 R13 R14 R15 registers and DF flag are preserved
+	// as required by windows callback convention.
+	PUSHFQ
+	SUBQ	$112, SP
+	MOVQ	DI, 80(SP)
+	MOVQ	SI, 72(SP)
+	MOVQ	BP, 64(SP)
+	MOVQ	BX, 56(SP)
+	MOVQ	R12, 48(SP)
+	MOVQ	R13, 40(SP)
+	MOVQ	R14, 32(SP)
+	MOVQ	R15, 88(SP)
+
+	MOVQ	AX, R15	// save handler address
+
+	// find g
+	get_tls(DX)
+	CMPQ	DX, $0
+	JNE	3(PC)
+	MOVQ	$0, AX // continue
+	JMP	done
+	MOVQ	g(DX), DX
+	CMPQ	DX, $0
+	JNE	2(PC)
+	CALL	runtime·badsignal2(SB)
+
+	// save g and SP in case of stack switch
+	MOVQ	DX, 96(SP) // g
+	MOVQ	SP, 104(SP)
+
+	// do we need to switch to the g0 stack?
+	MOVQ	g_m(DX), BX
+	MOVQ	m_g0(BX), BX
+	CMPQ	DX, BX
+	JEQ	sigtramp_g0
+
+	// switch to g0 stack
+	get_tls(BP)
+	MOVQ	BX, g(BP)
+	MOVQ	(g_sched+gobuf_sp)(BX), DI
+	// make it look like mstart called us on g0, to stop traceback
+	SUBQ	$8, DI
+	MOVQ	$runtime·mstart(SB), SI
+	MOVQ	SI, 0(DI)
+	// traceback will think that we've done PUSHFQ and SUBQ
+	// on this stack, so subtract them here to match.
+	// (we need room for sighandler arguments anyway).
+	// and re-save old SP for restoring later.
+	SUBQ	$(112+8), DI
+	// save g, save old stack pointer.
+	MOVQ	SP, 104(DI)
+	MOVQ	DI, SP
+
+sigtramp_g0:
+	MOVQ	0(CX), BX // ExceptionRecord*
+	MOVQ	8(CX), CX // Context*
+	MOVQ	BX, 0(SP)
+	MOVQ	CX, 8(SP)
+	MOVQ	DX, 16(SP)
+	CALL	R15	// call handler
+	// AX is set to report result back to Windows
+	MOVL	24(SP), AX
+
+	// switch back to original stack and g
+	// no-op if we never left.
+	MOVQ	104(SP), SP
+	MOVQ	96(SP), DX
+	get_tls(BP)
+	MOVQ	DX, g(BP)
+
+done:
+	// restore registers as required for windows callback
+	MOVQ	88(SP), R15
+	MOVQ	32(SP), R14
+	MOVQ	40(SP), R13
+	MOVQ	48(SP), R12
+	MOVQ	56(SP), BX
+	MOVQ	64(SP), BP
+	MOVQ	72(SP), SI
+	MOVQ	80(SP), DI
+	ADDQ	$112, SP
+	POPFQ
+
+	RET
+
+TEXT runtime·exceptiontramp(SB),NOSPLIT,$0
+	MOVQ	$runtime·exceptionhandler(SB), AX
+	JMP	runtime·sigtramp(SB)
+
+TEXT runtime·firstcontinuetramp(SB),NOSPLIT,$0-0
+	MOVQ	$runtime·firstcontinuehandler(SB), AX
+	JMP	runtime·sigtramp(SB)
+
+TEXT runtime·lastcontinuetramp(SB),NOSPLIT,$0-0
+	MOVQ	$runtime·lastcontinuehandler(SB), AX
+	JMP	runtime·sigtramp(SB)
+
+TEXT runtime·ctrlhandler(SB),NOSPLIT,$8
+	MOVQ	CX, 16(SP)		// spill
+	MOVQ	$runtime·ctrlhandler1(SB), CX
+	MOVQ	CX, 0(SP)
+	CALL	runtime·externalthreadhandler(SB)
+	RET
+
+TEXT runtime·profileloop(SB),NOSPLIT,$8
+	MOVQ	$runtime·profileloop1(SB), CX
+	MOVQ	CX, 0(SP)
+	CALL	runtime·externalthreadhandler(SB)
+	RET
+
+TEXT runtime·externalthreadhandler(SB),NOSPLIT,$0
+	PUSHQ	BP
+	MOVQ	SP, BP
+	PUSHQ	BX
+	PUSHQ	SI
+	PUSHQ	DI
+	PUSHQ	0x28(GS)
+	MOVQ	SP, DX
+
+	// setup dummy m, g
+	SUBQ	$m_end, SP		// space for M
+	MOVQ	SP, 0(SP)
+	MOVQ	$m_end, 8(SP)
+	CALL	runtime·memclr(SB)	// smashes AX,BX,CX
+
+	LEAQ	m_tls(SP), CX
+	MOVQ	CX, 0x28(GS)
+	MOVQ	SP, BX
+	SUBQ	$g_end, SP		// space for G
+	MOVQ	SP, g(CX)
+	MOVQ	SP, m_g0(BX)
+
+	MOVQ	SP, 0(SP)
+	MOVQ	$g_end, 8(SP)
+	CALL	runtime·memclr(SB)	// smashes AX,BX,CX
+	LEAQ	g_end(SP), BX
+	MOVQ	BX, g_m(SP)
+
+	LEAQ	-8192(SP), CX
+	MOVQ	CX, (g_stack+stack_lo)(SP)
+	ADDQ	$const_StackGuard, CX
+	MOVQ	CX, g_stackguard0(SP)
+	MOVQ	CX, g_stackguard1(SP)
+	MOVQ	DX, (g_stack+stack_hi)(SP)
+
+	PUSHQ	32(BP)			// arg for handler
+	CALL	16(BP)
+	POPQ	CX
+
+	get_tls(CX)
+	MOVQ	g(CX), CX
+	MOVQ	(g_stack+stack_hi)(CX), SP
+	POPQ	0x28(GS)
+	POPQ	DI
+	POPQ	SI
+	POPQ	BX
+	POPQ	BP
+	RET
+
+GLOBL runtime·cbctxts(SB), NOPTR, $8
+
+TEXT runtime·callbackasm1(SB),NOSPLIT,$0
+	// Construct args vector for cgocallback().
+	// By windows/amd64 calling convention first 4 args are in CX, DX, R8, R9
+	// args from the 5th on are on the stack.
+	// In any case, even if function has 0,1,2,3,4 args, there is reserved
+	// but uninitialized "shadow space" for the first 4 args.
+	// The values are in registers.
+  	MOVQ	CX, (16+0)(SP)
+  	MOVQ	DX, (16+8)(SP)
+  	MOVQ	R8, (16+16)(SP)
+  	MOVQ	R9, (16+24)(SP)
+
+	// remove return address from stack, we are not returning there
+  	MOVQ	0(SP), AX
+	ADDQ	$8, SP
+
+	// determine index into runtime·cbctxts table
+	MOVQ	$runtime·callbackasm(SB), DX
+	SUBQ	DX, AX
+	MOVQ	$0, DX
+	MOVQ	$5, CX	// divide by 5 because each call instruction in runtime·callbacks is 5 bytes long
+	DIVL	CX,
+
+	// find correspondent runtime·cbctxts table entry
+	MOVQ	runtime·cbctxts(SB), CX
+	MOVQ	-8(CX)(AX*8), AX
+
+	// extract callback context
+	MOVQ	cbctxt_argsize(AX), DX
+	MOVQ	cbctxt_gobody(AX), AX
+
+	// preserve whatever's at the memory location that
+	// the callback will use to store the return value
+	LEAQ	8(SP), CX       // args vector, skip return address
+	PUSHQ	0(CX)(DX*1)     // store 8 bytes from just after the args array
+	ADDQ	$8, DX          // extend argsize by size of return value
+
+	// DI SI BP BX R12 R13 R14 R15 registers and DF flag are preserved
+	// as required by windows callback convention.
+	PUSHFQ
+	SUBQ	$64, SP
+	MOVQ	DI, 56(SP)
+	MOVQ	SI, 48(SP)
+	MOVQ	BP, 40(SP)
+	MOVQ	BX, 32(SP)
+	MOVQ	R12, 24(SP)
+	MOVQ	R13, 16(SP)
+	MOVQ	R14, 8(SP)
+	MOVQ	R15, 0(SP)
+
+	// prepare call stack.  use SUBQ to hide from stack frame checks
+	// cgocallback(Go func, void *frame, uintptr framesize)
+	SUBQ	$24, SP
+	MOVQ	DX, 16(SP)	// argsize (including return value)
+	MOVQ	CX, 8(SP)	// callback parameters
+	MOVQ	AX, 0(SP)	// address of target Go function
+	CLD
+	CALL	runtime·cgocallback_gofunc(SB)
+	MOVQ	0(SP), AX
+	MOVQ	8(SP), CX
+	MOVQ	16(SP), DX
+	ADDQ	$24, SP
+
+	// restore registers as required for windows callback
+	MOVQ	0(SP), R15
+	MOVQ	8(SP), R14
+	MOVQ	16(SP), R13
+	MOVQ	24(SP), R12
+	MOVQ	32(SP), BX
+	MOVQ	40(SP), BP
+	MOVQ	48(SP), SI
+	MOVQ	56(SP), DI
+	ADDQ	$64, SP
+	POPFQ
+
+	MOVL	-8(CX)(DX*1), AX  // return value
+	POPQ	-8(CX)(DX*1)      // restore bytes just after the args
+	RET
+
+// uint32 tstart_stdcall(M *newm);
+TEXT runtime·tstart_stdcall(SB),NOSPLIT,$0
+	// CX contains first arg newm
+	MOVQ	m_g0(CX), DX		// g
+
+	// Layout new m scheduler stack on os stack.
+	MOVQ	SP, AX
+	MOVQ	AX, (g_stack+stack_hi)(DX)
+	SUBQ	$(64*1024), AX		// stack size
+	MOVQ	AX, (g_stack+stack_lo)(DX)
+	ADDQ	$const_StackGuard, AX
+	MOVQ	AX, g_stackguard0(DX)
+	MOVQ	AX, g_stackguard1(DX)
+
+	// Set up tls.
+	LEAQ	m_tls(CX), SI
+	MOVQ	SI, 0x28(GS)
+	MOVQ	CX, g_m(DX)
+	MOVQ	DX, g(SI)
+
+	// Someday the convention will be D is always cleared.
+	CLD
+
+	CALL	runtime·stackcheck(SB)	// clobbers AX,CX
+	CALL	runtime·mstart(SB)
+
+	XORL	AX, AX			// return 0 == success
+	RET
+
+// set tls base to DI
+TEXT runtime·settls(SB),NOSPLIT,$0
+	MOVQ	DI, 0x28(GS)
+	RET
+
+// Sleep duration is in 100ns units.
+TEXT runtime·usleep1(SB),NOSPLIT,$0
+	MOVL	usec+0(FP), BX
+	MOVQ	$runtime·usleep2(SB), AX // to hide from 6l
+
+	// Execute call on m->g0 stack, in case we are not actually
+	// calling a system call wrapper, like when running under WINE.
+	get_tls(R15)
+	CMPQ	R15, $0
+	JNE	3(PC)
+	// Not a Go-managed thread. Do not switch stack.
+	CALL	AX
+	RET
+
+	MOVQ	g(R15), R13
+	MOVQ	g_m(R13), R13
+
+	// leave pc/sp for cpu profiler
+	MOVQ	(SP), R12
+	MOVQ	R12, m_libcallpc(R13)
+	MOVQ	g(R15), R12
+	MOVQ	R12, m_libcallg(R13)
+	// sp must be the last, because once async cpu profiler finds
+	// all three values to be non-zero, it will use them
+	LEAQ	usec+0(FP), R12
+	MOVQ	R12, m_libcallsp(R13)
+
+	MOVQ	m_g0(R13), R14
+	CMPQ	g(R15), R14
+	JNE	usleep1_switch
+	// executing on m->g0 already
+	CALL	AX
+	JMP	usleep1_ret
+
+usleep1_switch:
+	// Switch to m->g0 stack and back.
+	MOVQ	(g_sched+gobuf_sp)(R14), R14
+	MOVQ	SP, -8(R14)
+	LEAQ	-8(R14), SP
+	CALL	AX
+	MOVQ	0(SP), SP
+
+usleep1_ret:
+	MOVQ	$0, m_libcallsp(R13)
+	RET
+
+// Runs on OS stack. duration (in 100ns units) is in BX.
+TEXT runtime·usleep2(SB),NOSPLIT,$16
+	MOVQ	SP, AX
+	ANDQ	$~15, SP	// alignment as per Windows requirement
+	MOVQ	AX, 8(SP)
+	// Want negative 100ns units.
+	NEGQ	BX
+	MOVQ	SP, R8 // ptime
+	MOVQ	BX, (R8)
+	MOVQ	$-1, CX // handle
+	MOVQ	$0, DX // alertable
+	MOVQ	runtime·NtWaitForSingleObject(SB), AX
+	CALL	AX
+	MOVQ	8(SP), SP
+	RET
+
+// func now() (sec int64, nsec int32)
+TEXT time·now(SB),NOSPLIT,$8-12
+	CALL	runtime·unixnano(SB)
+	MOVQ	0(SP), AX
+
+	// generated code for
+	//	func f(x uint64) (uint64, uint64) { return x/1000000000, x%100000000 }
+	// adapted to reduce duplication
+	MOVQ	AX, CX
+	MOVQ	$1360296554856532783, AX
+	MULQ	CX
+	ADDQ	CX, DX
+	RCRQ	$1, DX
+	SHRQ	$29, DX
+	MOVQ	DX, sec+0(FP)
+	IMULQ	$1000000000, DX
+	SUBQ	DX, CX
+	MOVL	CX, nsec+8(FP)
+	RET
+
diff --git a/src/pkg/runtime/sys_x86.c b/src/runtime/sys_x86.c
similarity index 100%
rename from src/pkg/runtime/sys_x86.c
rename to src/runtime/sys_x86.c
diff --git a/src/pkg/runtime/syscall_nacl.h b/src/runtime/syscall_nacl.h
similarity index 100%
rename from src/pkg/runtime/syscall_nacl.h
rename to src/runtime/syscall_nacl.h
diff --git a/src/runtime/syscall_solaris.c b/src/runtime/syscall_solaris.c
new file mode 100644
index 0000000..13ac31b
--- /dev/null
+++ b/src/runtime/syscall_solaris.c
@@ -0,0 +1,23 @@
+// 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.
+
+#pragma dynimport libc·chdir chdir "libc.so"
+#pragma dynimport libc·chroot chroot "libc.so"
+#pragma dynimport libc·close close "libc.so"
+#pragma dynimport libc·dlclose dlclose "libc.so"
+#pragma dynimport libc·dlopen dlopen "libc.so"
+#pragma dynimport libc·dlsym dlsym "libc.so"
+#pragma dynimport libc·execve execve "libc.so"
+#pragma dynimport libc·fcntl fcntl "libc.so"
+#pragma dynimport libc·gethostname gethostname "libc.so"
+#pragma dynimport libc·ioctl ioctl "libc.so"
+#pragma dynimport libc·pipe pipe "libc.so"
+#pragma dynimport libc·setgid setgid "libc.so"
+#pragma dynimport libc·setgroups setgroups "libc.so"
+#pragma dynimport libc·setsid setsid "libc.so"
+#pragma dynimport libc·setuid setuid "libc.so"
+#pragma dynimport libc·setpgid setsid "libc.so"
+#pragma dynimport libc·syscall syscall "libc.so"
+#pragma dynimport libc·forkx forkx "libc.so"
+#pragma dynimport libc·wait4 wait4 "libc.so"
diff --git a/src/runtime/syscall_solaris.go b/src/runtime/syscall_solaris.go
new file mode 100644
index 0000000..50d3a1d
--- /dev/null
+++ b/src/runtime/syscall_solaris.go
@@ -0,0 +1,322 @@
+// 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 runtime
+
+import "unsafe"
+
+var (
+	libc_chdir,
+	libc_chroot,
+	libc_close,
+	libc_dlopen,
+	libc_dlclose,
+	libc_dlsym,
+	libc_execve,
+	libc_exit,
+	libc_fcntl,
+	libc_forkx,
+	libc_gethostname,
+	libc_ioctl,
+	libc_pipe,
+	libc_setgid,
+	libc_setgroups,
+	libc_setsid,
+	libc_setuid,
+	libc_setpgid,
+	libc_syscall,
+	libc_wait4,
+	libc_write,
+	pipe1 libcFunc
+)
+
+//go:nosplit
+func syscall_sysvicall6(fn, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) {
+	call := libcall{
+		fn:   fn,
+		n:    nargs,
+		args: uintptr(unsafe.Pointer(&a1)),
+	}
+	entersyscallblock()
+	asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call))
+	exitsyscall()
+	return call.r1, call.r2, call.err
+}
+
+//go:nosplit
+func syscall_rawsysvicall6(fn, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) {
+	call := libcall{
+		fn:   fn,
+		n:    nargs,
+		args: uintptr(unsafe.Pointer(&a1)),
+	}
+	asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call))
+	return call.r1, call.r2, call.err
+}
+
+// TODO(aram): Once we remove all instances of C calling sysvicallN, make
+// sysvicallN return errors and replace the body of the following functions
+// with calls to sysvicallN.
+
+//go:nosplit
+func syscall_chdir(path uintptr) (err uintptr) {
+	call := libcall{
+		fn:   uintptr(unsafe.Pointer(&libc_chdir)),
+		n:    1,
+		args: uintptr(unsafe.Pointer(&path)),
+	}
+	asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call))
+	return call.err
+}
+
+//go:nosplit
+func syscall_chroot(path uintptr) (err uintptr) {
+	call := libcall{
+		fn:   uintptr(unsafe.Pointer(&libc_chroot)),
+		n:    1,
+		args: uintptr(unsafe.Pointer(&path)),
+	}
+	asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call))
+	return call.err
+}
+
+// like close, but must not split stack, for forkx.
+//go:nosplit
+func syscall_close(fd int32) int32 {
+	return int32(sysvicall1(&libc_close, uintptr(fd)))
+}
+
+func syscall_dlopen(name *byte, mode uintptr) (handle uintptr, err uintptr) {
+	call := libcall{
+		fn:   uintptr(unsafe.Pointer(&libc_dlopen)),
+		n:    2,
+		args: uintptr(unsafe.Pointer(&name)),
+	}
+	entersyscallblock()
+	asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call))
+	exitsyscall()
+	if call.r1 == 0 {
+		return call.r1, call.err
+	}
+	return call.r1, 0
+}
+
+func syscall_dlclose(handle uintptr) (err uintptr) {
+	call := libcall{
+		fn:   uintptr(unsafe.Pointer(&libc_dlclose)),
+		n:    1,
+		args: uintptr(unsafe.Pointer(&handle)),
+	}
+	entersyscallblock()
+	asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call))
+	exitsyscall()
+	return call.r1
+}
+
+func syscall_dlsym(handle uintptr, name *byte) (proc uintptr, err uintptr) {
+	call := libcall{
+		fn:   uintptr(unsafe.Pointer(&libc_dlsym)),
+		n:    2,
+		args: uintptr(unsafe.Pointer(&handle)),
+	}
+	entersyscallblock()
+	asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call))
+	exitsyscall()
+	if call.r1 == 0 {
+		return call.r1, call.err
+	}
+	return call.r1, 0
+}
+
+//go:nosplit
+func syscall_execve(path, argv, envp uintptr) (err uintptr) {
+	call := libcall{
+		fn:   uintptr(unsafe.Pointer(&libc_execve)),
+		n:    3,
+		args: uintptr(unsafe.Pointer(&path)),
+	}
+	asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call))
+	return call.err
+}
+
+// like exit, but must not split stack, for forkx.
+//go:nosplit
+func syscall_exit(code uintptr) {
+	sysvicall1(&libc_exit, code)
+}
+
+//go:nosplit
+func syscall_fcntl(fd, cmd, arg uintptr) (val, err uintptr) {
+	call := libcall{
+		fn:   uintptr(unsafe.Pointer(&libc_fcntl)),
+		n:    3,
+		args: uintptr(unsafe.Pointer(&fd)),
+	}
+	asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call))
+	return call.r1, call.err
+}
+
+//go:nosplit
+func syscall_forkx(flags uintptr) (pid uintptr, err uintptr) {
+	call := libcall{
+		fn:   uintptr(unsafe.Pointer(&libc_forkx)),
+		n:    1,
+		args: uintptr(unsafe.Pointer(&flags)),
+	}
+	asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call))
+	return call.r1, call.err
+}
+
+func syscall_gethostname() (name string, err uintptr) {
+	cname := new([_MAXHOSTNAMELEN]byte)
+	var args = [2]uintptr{uintptr(unsafe.Pointer(&cname[0])), _MAXHOSTNAMELEN}
+	call := libcall{
+		fn:   uintptr(unsafe.Pointer(&libc_gethostname)),
+		n:    2,
+		args: uintptr(unsafe.Pointer(&args[0])),
+	}
+	entersyscallblock()
+	asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call))
+	exitsyscall()
+	if call.r1 != 0 {
+		return "", call.err
+	}
+	cname[_MAXHOSTNAMELEN-1] = 0
+	return gostringnocopy(&cname[0]), 0
+}
+
+//go:nosplit
+func syscall_ioctl(fd, req, arg uintptr) (err uintptr) {
+	call := libcall{
+		fn:   uintptr(unsafe.Pointer(&libc_ioctl)),
+		n:    3,
+		args: uintptr(unsafe.Pointer(&fd)),
+	}
+	asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call))
+	return call.err
+}
+
+func syscall_pipe() (r, w, err uintptr) {
+	call := libcall{
+		fn:   uintptr(unsafe.Pointer(&pipe1)),
+		n:    0,
+		args: uintptr(unsafe.Pointer(&pipe1)), // it's unused but must be non-nil, otherwise crashes
+	}
+	entersyscallblock()
+	asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call))
+	exitsyscall()
+	return call.r1, call.r2, call.err
+}
+
+// This is syscall.RawSyscall, it exists to satisfy some build dependency,
+// but it doesn't work correctly.
+//
+// DO NOT USE!
+//
+// TODO(aram): make this panic once we stop calling fcntl(2) in net using it.
+func syscall_rawsyscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
+	call := libcall{
+		fn:   uintptr(unsafe.Pointer(&libc_syscall)),
+		n:    4,
+		args: uintptr(unsafe.Pointer(&trap)),
+	}
+	asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call))
+	return call.r1, call.r2, call.err
+}
+
+//go:nosplit
+func syscall_setgid(gid uintptr) (err uintptr) {
+	call := libcall{
+		fn:   uintptr(unsafe.Pointer(&libc_setgid)),
+		n:    1,
+		args: uintptr(unsafe.Pointer(&gid)),
+	}
+	asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call))
+	return call.err
+}
+
+//go:nosplit
+func syscall_setgroups(ngid, gid uintptr) (err uintptr) {
+	call := libcall{
+		fn:   uintptr(unsafe.Pointer(&libc_setgroups)),
+		n:    2,
+		args: uintptr(unsafe.Pointer(&ngid)),
+	}
+	asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call))
+	return call.err
+}
+
+//go:nosplit
+func syscall_setsid() (pid, err uintptr) {
+	call := libcall{
+		fn:   uintptr(unsafe.Pointer(&libc_setsid)),
+		n:    0,
+		args: uintptr(unsafe.Pointer(&libc_setsid)), // it's unused but must be non-nil, otherwise crashes
+	}
+	asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call))
+	return call.r1, call.err
+}
+
+//go:nosplit
+func syscall_setuid(uid uintptr) (err uintptr) {
+	call := libcall{
+		fn:   uintptr(unsafe.Pointer(&libc_setuid)),
+		n:    1,
+		args: uintptr(unsafe.Pointer(&uid)),
+	}
+	asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call))
+	return call.err
+}
+
+//go:nosplit
+func syscall_setpgid(pid, pgid uintptr) (err uintptr) {
+	call := libcall{
+		fn:   uintptr(unsafe.Pointer(&libc_setpgid)),
+		n:    2,
+		args: uintptr(unsafe.Pointer(&pid)),
+	}
+	asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call))
+	return call.err
+}
+
+// This is syscall.Syscall, it exists to satisfy some build dependency,
+// but it doesn't work correctly.
+//
+// DO NOT USE!
+//
+// TODO(aram): make this panic once we stop calling fcntl(2) in net using it.
+func syscall_syscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
+	call := libcall{
+		fn:   uintptr(unsafe.Pointer(&libc_syscall)),
+		n:    4,
+		args: uintptr(unsafe.Pointer(&trap)),
+	}
+	entersyscallblock()
+	asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call))
+	exitsyscall()
+	return call.r1, call.r2, call.err
+}
+
+func syscall_wait4(pid uintptr, wstatus *uint32, options uintptr, rusage unsafe.Pointer) (wpid int, err uintptr) {
+	call := libcall{
+		fn:   uintptr(unsafe.Pointer(&libc_wait4)),
+		n:    4,
+		args: uintptr(unsafe.Pointer(&pid)),
+	}
+	entersyscallblock()
+	asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call))
+	exitsyscall()
+	return int(call.r1), call.err
+}
+
+//go:nosplit
+func syscall_write(fd, buf, nbyte uintptr) (n, err uintptr) {
+	call := libcall{
+		fn:   uintptr(unsafe.Pointer(&libc_write)),
+		n:    3,
+		args: uintptr(unsafe.Pointer(&fd)),
+	}
+	asmcgocall(unsafe.Pointer(&asmsysvicall6), unsafe.Pointer(&call))
+	return call.r1, call.err
+}
diff --git a/src/runtime/syscall_windows.go b/src/runtime/syscall_windows.go
new file mode 100644
index 0000000..efbcab5
--- /dev/null
+++ b/src/runtime/syscall_windows.go
@@ -0,0 +1,170 @@
+// 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 runtime
+
+import (
+	"unsafe"
+)
+
+type callbacks struct {
+	lock mutex
+	ctxt [cb_max]*wincallbackcontext
+	n    int
+}
+
+func (c *wincallbackcontext) isCleanstack() bool {
+	return c.cleanstack
+}
+
+func (c *wincallbackcontext) setCleanstack(cleanstack bool) {
+	c.cleanstack = cleanstack
+}
+
+var (
+	cbs     callbacks
+	cbctxts **wincallbackcontext = &cbs.ctxt[0] // to simplify access to cbs.ctxt in sys_windows_*.s
+
+	callbackasm byte // type isn't really byte, it's code in runtime
+)
+
+// callbackasmAddr returns address of runtime.callbackasm
+// function adjusted by i.
+// runtime.callbackasm is just a series of CALL instructions
+// (each is 5 bytes long), and we want callback to arrive at
+// correspondent call instruction instead of start of
+// runtime.callbackasm.
+func callbackasmAddr(i int) uintptr {
+	return uintptr(add(unsafe.Pointer(&callbackasm), uintptr(i*5)))
+}
+
+func compileCallback(fn eface, cleanstack bool) (code uintptr) {
+	if fn._type == nil || (fn._type.kind&kindMask) != kindFunc {
+		panic("compilecallback: not a function")
+	}
+	ft := (*functype)(unsafe.Pointer(fn._type))
+	if len(ft.out) != 1 {
+		panic("compilecallback: function must have one output parameter")
+	}
+	uintptrSize := unsafe.Sizeof(uintptr(0))
+	if t := (**_type)(unsafe.Pointer(&ft.out[0])); (*t).size != uintptrSize {
+		panic("compilecallback: output parameter size is wrong")
+	}
+	argsize := uintptr(0)
+	for _, t := range (*[1024](*_type))(unsafe.Pointer(&ft.in[0]))[:len(ft.in)] {
+		if (*t).size > uintptrSize {
+			panic("compilecallback: input parameter size is wrong")
+		}
+		argsize += uintptrSize
+	}
+
+	lock(&cbs.lock)
+	defer unlock(&cbs.lock)
+
+	n := cbs.n
+	for i := 0; i < n; i++ {
+		if cbs.ctxt[i].gobody == fn.data && cbs.ctxt[i].isCleanstack() == cleanstack {
+			return callbackasmAddr(i)
+		}
+	}
+	if n >= cb_max {
+		gothrow("too many callback functions")
+	}
+
+	c := new(wincallbackcontext)
+	c.gobody = fn.data
+	c.argsize = argsize
+	c.setCleanstack(cleanstack)
+	if cleanstack && argsize != 0 {
+		c.restorestack = argsize
+	} else {
+		c.restorestack = 0
+	}
+	cbs.ctxt[n] = c
+	cbs.n++
+
+	return callbackasmAddr(n)
+}
+
+func getLoadLibrary() uintptr
+
+//go:nosplit
+func syscall_loadlibrary(filename *uint16) (handle, err uintptr) {
+	var c libcall
+	c.fn = getLoadLibrary()
+	c.n = 1
+	c.args = uintptr(unsafe.Pointer(&filename))
+	cgocall_errno(unsafe.Pointer(funcPC(asmstdcall)), unsafe.Pointer(&c))
+	handle = c.r1
+	if handle == 0 {
+		err = c.err
+	}
+	return
+}
+
+func getGetProcAddress() uintptr
+
+//go:nosplit
+func syscall_getprocaddress(handle uintptr, procname *byte) (outhandle, err uintptr) {
+	var c libcall
+	c.fn = getGetProcAddress()
+	c.n = 2
+	c.args = uintptr(unsafe.Pointer(&handle))
+	cgocall_errno(unsafe.Pointer(funcPC(asmstdcall)), unsafe.Pointer(&c))
+	outhandle = c.r1
+	if outhandle == 0 {
+		err = c.err
+	}
+	return
+}
+
+//go:nosplit
+func syscall_Syscall(fn, nargs, a1, a2, a3 uintptr) (r1, r2, err uintptr) {
+	var c libcall
+	c.fn = fn
+	c.n = nargs
+	c.args = uintptr(unsafe.Pointer(&a1))
+	cgocall_errno(unsafe.Pointer(funcPC(asmstdcall)), unsafe.Pointer(&c))
+	return c.r1, c.r2, c.err
+}
+
+//go:nosplit
+func syscall_Syscall6(fn, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr) {
+	var c libcall
+	c.fn = fn
+	c.n = nargs
+	c.args = uintptr(unsafe.Pointer(&a1))
+	cgocall_errno(unsafe.Pointer(funcPC(asmstdcall)), unsafe.Pointer(&c))
+	return c.r1, c.r2, c.err
+}
+
+//go:nosplit
+func syscall_Syscall9(fn, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2, err uintptr) {
+	var c libcall
+	c.fn = fn
+	c.n = nargs
+	c.args = uintptr(unsafe.Pointer(&a1))
+	cgocall_errno(unsafe.Pointer(funcPC(asmstdcall)), unsafe.Pointer(&c))
+	return c.r1, c.r2, c.err
+}
+
+//go:nosplit
+func syscall_Syscall12(fn, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12 uintptr) (r1, r2, err uintptr) {
+	var c libcall
+	c.fn = fn
+	c.n = nargs
+	c.args = uintptr(unsafe.Pointer(&a1))
+	cgocall_errno(unsafe.Pointer(funcPC(asmstdcall)), unsafe.Pointer(&c))
+	return c.r1, c.r2, c.err
+}
+
+//go:nosplit
+func syscall_Syscall15(fn, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15 uintptr) (r1, r2, err uintptr) {
+	var c libcall
+	c.fn = fn
+	c.n = nargs
+	c.args = uintptr(unsafe.Pointer(&a1))
+	cgocall_errno(unsafe.Pointer(funcPC(asmstdcall)), unsafe.Pointer(&c))
+	return c.r1, c.r2, c.err
+}
diff --git a/src/runtime/syscall_windows_test.go b/src/runtime/syscall_windows_test.go
new file mode 100644
index 0000000..ce8a9ec
--- /dev/null
+++ b/src/runtime/syscall_windows_test.go
@@ -0,0 +1,535 @@
+// Copyright 2010 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package runtime_test
+
+import (
+	"fmt"
+	"io/ioutil"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"runtime"
+	"strings"
+	"syscall"
+	"testing"
+	"unsafe"
+)
+
+type DLL struct {
+	*syscall.DLL
+	t *testing.T
+}
+
+func GetDLL(t *testing.T, name string) *DLL {
+	d, e := syscall.LoadDLL(name)
+	if e != nil {
+		t.Fatal(e)
+	}
+	return &DLL{DLL: d, t: t}
+}
+
+func (d *DLL) Proc(name string) *syscall.Proc {
+	p, e := d.FindProc(name)
+	if e != nil {
+		d.t.Fatal(e)
+	}
+	return p
+}
+
+func TestStdCall(t *testing.T) {
+	type Rect struct {
+		left, top, right, bottom int32
+	}
+	res := Rect{}
+	expected := Rect{1, 1, 40, 60}
+	a, _, _ := GetDLL(t, "user32.dll").Proc("UnionRect").Call(
+		uintptr(unsafe.Pointer(&res)),
+		uintptr(unsafe.Pointer(&Rect{10, 1, 14, 60})),
+		uintptr(unsafe.Pointer(&Rect{1, 2, 40, 50})))
+	if a != 1 || res.left != expected.left ||
+		res.top != expected.top ||
+		res.right != expected.right ||
+		res.bottom != expected.bottom {
+		t.Error("stdcall USER32.UnionRect returns", a, "res=", res)
+	}
+}
+
+func Test64BitReturnStdCall(t *testing.T) {
+
+	const (
+		VER_BUILDNUMBER      = 0x0000004
+		VER_MAJORVERSION     = 0x0000002
+		VER_MINORVERSION     = 0x0000001
+		VER_PLATFORMID       = 0x0000008
+		VER_PRODUCT_TYPE     = 0x0000080
+		VER_SERVICEPACKMAJOR = 0x0000020
+		VER_SERVICEPACKMINOR = 0x0000010
+		VER_SUITENAME        = 0x0000040
+
+		VER_EQUAL         = 1
+		VER_GREATER       = 2
+		VER_GREATER_EQUAL = 3
+		VER_LESS          = 4
+		VER_LESS_EQUAL    = 5
+
+		ERROR_OLD_WIN_VERSION syscall.Errno = 1150
+	)
+
+	type OSVersionInfoEx struct {
+		OSVersionInfoSize uint32
+		MajorVersion      uint32
+		MinorVersion      uint32
+		BuildNumber       uint32
+		PlatformId        uint32
+		CSDVersion        [128]uint16
+		ServicePackMajor  uint16
+		ServicePackMinor  uint16
+		SuiteMask         uint16
+		ProductType       byte
+		Reserve           byte
+	}
+
+	d := GetDLL(t, "kernel32.dll")
+
+	var m1, m2 uintptr
+	VerSetConditionMask := d.Proc("VerSetConditionMask")
+	m1, m2, _ = VerSetConditionMask.Call(m1, m2, VER_MAJORVERSION, VER_GREATER_EQUAL)
+	m1, m2, _ = VerSetConditionMask.Call(m1, m2, VER_MINORVERSION, VER_GREATER_EQUAL)
+	m1, m2, _ = VerSetConditionMask.Call(m1, m2, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL)
+	m1, m2, _ = VerSetConditionMask.Call(m1, m2, VER_SERVICEPACKMINOR, VER_GREATER_EQUAL)
+
+	vi := OSVersionInfoEx{
+		MajorVersion:     5,
+		MinorVersion:     1,
+		ServicePackMajor: 2,
+		ServicePackMinor: 0,
+	}
+	vi.OSVersionInfoSize = uint32(unsafe.Sizeof(vi))
+	r, _, e2 := d.Proc("VerifyVersionInfoW").Call(
+		uintptr(unsafe.Pointer(&vi)),
+		VER_MAJORVERSION|VER_MINORVERSION|VER_SERVICEPACKMAJOR|VER_SERVICEPACKMINOR,
+		m1, m2)
+	if r == 0 && e2 != ERROR_OLD_WIN_VERSION {
+		t.Errorf("VerifyVersionInfo failed: %s", e2)
+	}
+}
+
+func TestCDecl(t *testing.T) {
+	var buf [50]byte
+	fmtp, _ := syscall.BytePtrFromString("%d %d %d")
+	a, _, _ := GetDLL(t, "user32.dll").Proc("wsprintfA").Call(
+		uintptr(unsafe.Pointer(&buf[0])),
+		uintptr(unsafe.Pointer(fmtp)),
+		1000, 2000, 3000)
+	if string(buf[:a]) != "1000 2000 3000" {
+		t.Error("cdecl USER32.wsprintfA returns", a, "buf=", buf[:a])
+	}
+}
+
+func TestEnumWindows(t *testing.T) {
+	d := GetDLL(t, "user32.dll")
+	isWindows := d.Proc("IsWindow")
+	counter := 0
+	cb := syscall.NewCallback(func(hwnd syscall.Handle, lparam uintptr) uintptr {
+		if lparam != 888 {
+			t.Error("lparam was not passed to callback")
+		}
+		b, _, _ := isWindows.Call(uintptr(hwnd))
+		if b == 0 {
+			t.Error("USER32.IsWindow returns FALSE")
+		}
+		counter++
+		return 1 // continue enumeration
+	})
+	a, _, _ := d.Proc("EnumWindows").Call(cb, 888)
+	if a == 0 {
+		t.Error("USER32.EnumWindows returns FALSE")
+	}
+	if counter == 0 {
+		t.Error("Callback has been never called or your have no windows")
+	}
+}
+
+func callback(hwnd syscall.Handle, lparam uintptr) uintptr {
+	(*(*func())(unsafe.Pointer(&lparam)))()
+	return 0 // stop enumeration
+}
+
+// nestedCall calls into Windows, back into Go, and finally to f.
+func nestedCall(t *testing.T, f func()) {
+	c := syscall.NewCallback(callback)
+	d := GetDLL(t, "user32.dll")
+	defer d.Release()
+	d.Proc("EnumWindows").Call(c, uintptr(*(*unsafe.Pointer)(unsafe.Pointer(&f))))
+}
+
+func TestCallback(t *testing.T) {
+	var x = false
+	nestedCall(t, func() { x = true })
+	if !x {
+		t.Fatal("nestedCall did not call func")
+	}
+}
+
+func TestCallbackGC(t *testing.T) {
+	nestedCall(t, runtime.GC)
+}
+
+func TestCallbackPanicLocked(t *testing.T) {
+	runtime.LockOSThread()
+	defer runtime.UnlockOSThread()
+
+	if !runtime.LockedOSThread() {
+		t.Fatal("runtime.LockOSThread didn't")
+	}
+	defer func() {
+		s := recover()
+		if s == nil {
+			t.Fatal("did not panic")
+		}
+		if s.(string) != "callback panic" {
+			t.Fatal("wrong panic:", s)
+		}
+		if !runtime.LockedOSThread() {
+			t.Fatal("lost lock on OS thread after panic")
+		}
+	}()
+	nestedCall(t, func() { panic("callback panic") })
+	panic("nestedCall returned")
+}
+
+func TestCallbackPanic(t *testing.T) {
+	// Make sure panic during callback unwinds properly.
+	if runtime.LockedOSThread() {
+		t.Fatal("locked OS thread on entry to TestCallbackPanic")
+	}
+	defer func() {
+		s := recover()
+		if s == nil {
+			t.Fatal("did not panic")
+		}
+		if s.(string) != "callback panic" {
+			t.Fatal("wrong panic:", s)
+		}
+		if runtime.LockedOSThread() {
+			t.Fatal("locked OS thread on exit from TestCallbackPanic")
+		}
+	}()
+	nestedCall(t, func() { panic("callback panic") })
+	panic("nestedCall returned")
+}
+
+func TestCallbackPanicLoop(t *testing.T) {
+	// Make sure we don't blow out m->g0 stack.
+	for i := 0; i < 100000; i++ {
+		TestCallbackPanic(t)
+	}
+}
+
+func TestBlockingCallback(t *testing.T) {
+	c := make(chan int)
+	go func() {
+		for i := 0; i < 10; i++ {
+			c <- <-c
+		}
+	}()
+	nestedCall(t, func() {
+		for i := 0; i < 10; i++ {
+			c <- i
+			if j := <-c; j != i {
+				t.Errorf("out of sync %d != %d", j, i)
+			}
+		}
+	})
+}
+
+func TestCallbackInAnotherThread(t *testing.T) {
+	// TODO: test a function which calls back in another thread: QueueUserAPC() or CreateThread()
+}
+
+type cbDLLFunc int // int determines number of callback parameters
+
+func (f cbDLLFunc) stdcallName() string {
+	return fmt.Sprintf("stdcall%d", f)
+}
+
+func (f cbDLLFunc) cdeclName() string {
+	return fmt.Sprintf("cdecl%d", f)
+}
+
+func (f cbDLLFunc) buildOne(stdcall bool) string {
+	var funcname, attr string
+	if stdcall {
+		funcname = f.stdcallName()
+		attr = "__stdcall"
+	} else {
+		funcname = f.cdeclName()
+		attr = "__cdecl"
+	}
+	typename := "t" + funcname
+	p := make([]string, f)
+	for i := range p {
+		p[i] = "void*"
+	}
+	params := strings.Join(p, ",")
+	for i := range p {
+		p[i] = fmt.Sprintf("%d", i+1)
+	}
+	args := strings.Join(p, ",")
+	return fmt.Sprintf(`
+typedef void %s (*%s)(%s);
+void %s(%s f, void *n) {
+	int i;
+	for(i=0;i<(int)n;i++){
+		f(%s);
+	}
+}
+	`, attr, typename, params, funcname, typename, args)
+}
+
+func (f cbDLLFunc) build() string {
+	return f.buildOne(false) + f.buildOne(true)
+}
+
+var cbFuncs = [...]interface{}{
+	2: func(i1, i2 uintptr) uintptr {
+		if i1+i2 != 3 {
+			panic("bad input")
+		}
+		return 0
+	},
+	3: func(i1, i2, i3 uintptr) uintptr {
+		if i1+i2+i3 != 6 {
+			panic("bad input")
+		}
+		return 0
+	},
+	4: func(i1, i2, i3, i4 uintptr) uintptr {
+		if i1+i2+i3+i4 != 10 {
+			panic("bad input")
+		}
+		return 0
+	},
+	5: func(i1, i2, i3, i4, i5 uintptr) uintptr {
+		if i1+i2+i3+i4+i5 != 15 {
+			panic("bad input")
+		}
+		return 0
+	},
+	6: func(i1, i2, i3, i4, i5, i6 uintptr) uintptr {
+		if i1+i2+i3+i4+i5+i6 != 21 {
+			panic("bad input")
+		}
+		return 0
+	},
+	7: func(i1, i2, i3, i4, i5, i6, i7 uintptr) uintptr {
+		if i1+i2+i3+i4+i5+i6+i7 != 28 {
+			panic("bad input")
+		}
+		return 0
+	},
+	8: func(i1, i2, i3, i4, i5, i6, i7, i8 uintptr) uintptr {
+		if i1+i2+i3+i4+i5+i6+i7+i8 != 36 {
+			panic("bad input")
+		}
+		return 0
+	},
+	9: func(i1, i2, i3, i4, i5, i6, i7, i8, i9 uintptr) uintptr {
+		if i1+i2+i3+i4+i5+i6+i7+i8+i9 != 45 {
+			panic("bad input")
+		}
+		return 0
+	},
+}
+
+type cbDLL struct {
+	name      string
+	buildArgs func(out, src string) []string
+}
+
+func (d *cbDLL) buildSrc(t *testing.T, path string) {
+	f, err := os.Create(path)
+	if err != nil {
+		t.Fatalf("failed to create source file: %v", err)
+	}
+	defer f.Close()
+
+	for i := 2; i < 10; i++ {
+		fmt.Fprint(f, cbDLLFunc(i).build())
+	}
+}
+
+func (d *cbDLL) build(t *testing.T, dir string) string {
+	srcname := d.name + ".c"
+	d.buildSrc(t, filepath.Join(dir, srcname))
+	outname := d.name + ".dll"
+	args := d.buildArgs(outname, srcname)
+	cmd := exec.Command(args[0], args[1:]...)
+	cmd.Dir = dir
+	out, err := cmd.CombinedOutput()
+	if err != nil {
+		t.Fatalf("failed to build dll: %v - %v", err, string(out))
+	}
+	return filepath.Join(dir, outname)
+}
+
+var cbDLLs = []cbDLL{
+	{
+		"test",
+		func(out, src string) []string {
+			return []string{"gcc", "-shared", "-s", "-o", out, src}
+		},
+	},
+	{
+		"testO2",
+		func(out, src string) []string {
+			return []string{"gcc", "-shared", "-s", "-o", out, "-O2", src}
+		},
+	},
+}
+
+type cbTest struct {
+	n     int     // number of callback parameters
+	param uintptr // dll function parameter
+}
+
+func (test *cbTest) run(t *testing.T, dllpath string) {
+	dll := syscall.MustLoadDLL(dllpath)
+	defer dll.Release()
+	cb := cbFuncs[test.n]
+	stdcall := syscall.NewCallback(cb)
+	f := cbDLLFunc(test.n)
+	test.runOne(t, dll, f.stdcallName(), stdcall)
+	cdecl := syscall.NewCallbackCDecl(cb)
+	test.runOne(t, dll, f.cdeclName(), cdecl)
+}
+
+func (test *cbTest) runOne(t *testing.T, dll *syscall.DLL, proc string, cb uintptr) {
+	defer func() {
+		if r := recover(); r != nil {
+			t.Errorf("dll call %v(..., %d) failed: %v", proc, test.param, r)
+		}
+	}()
+	dll.MustFindProc(proc).Call(cb, test.param)
+}
+
+var cbTests = []cbTest{
+	{2, 1},
+	{2, 10000},
+	{3, 3},
+	{4, 5},
+	{4, 6},
+	{5, 2},
+	{6, 7},
+	{6, 8},
+	{7, 6},
+	{8, 1},
+	{9, 8},
+	{9, 10000},
+	{3, 4},
+	{5, 3},
+	{7, 7},
+	{8, 2},
+	{9, 9},
+}
+
+func TestStdcallAndCDeclCallbacks(t *testing.T) {
+	tmp, err := ioutil.TempDir("", "TestCDeclCallback")
+	if err != nil {
+		t.Fatal("TempDir failed: ", err)
+	}
+	defer os.RemoveAll(tmp)
+
+	for _, dll := range cbDLLs {
+		dllPath := dll.build(t, tmp)
+		for _, test := range cbTests {
+			test.run(t, dllPath)
+		}
+	}
+}
+
+func TestRegisterClass(t *testing.T) {
+	kernel32 := GetDLL(t, "kernel32.dll")
+	user32 := GetDLL(t, "user32.dll")
+	mh, _, _ := kernel32.Proc("GetModuleHandleW").Call(0)
+	cb := syscall.NewCallback(func(hwnd syscall.Handle, msg uint32, wparam, lparam uintptr) (rc uintptr) {
+		t.Fatal("callback should never get called")
+		return 0
+	})
+	type Wndclassex struct {
+		Size       uint32
+		Style      uint32
+		WndProc    uintptr
+		ClsExtra   int32
+		WndExtra   int32
+		Instance   syscall.Handle
+		Icon       syscall.Handle
+		Cursor     syscall.Handle
+		Background syscall.Handle
+		MenuName   *uint16
+		ClassName  *uint16
+		IconSm     syscall.Handle
+	}
+	name := syscall.StringToUTF16Ptr("test_window")
+	wc := Wndclassex{
+		WndProc:   cb,
+		Instance:  syscall.Handle(mh),
+		ClassName: name,
+	}
+	wc.Size = uint32(unsafe.Sizeof(wc))
+	a, _, err := user32.Proc("RegisterClassExW").Call(uintptr(unsafe.Pointer(&wc)))
+	if a == 0 {
+		t.Fatalf("RegisterClassEx failed: %v", err)
+	}
+	r, _, err := user32.Proc("UnregisterClassW").Call(uintptr(unsafe.Pointer(name)), 0)
+	if r == 0 {
+		t.Fatalf("UnregisterClass failed: %v", err)
+	}
+}
+
+func TestOutputDebugString(t *testing.T) {
+	d := GetDLL(t, "kernel32.dll")
+	p := syscall.StringToUTF16Ptr("testing OutputDebugString")
+	d.Proc("OutputDebugStringW").Call(uintptr(unsafe.Pointer(p)))
+}
+
+func TestRaiseException(t *testing.T) {
+	o := executeTest(t, raiseExceptionSource, nil)
+	if strings.Contains(o, "RaiseException should not return") {
+		t.Fatalf("RaiseException did not crash program: %v", o)
+	}
+	if !strings.Contains(o, "Exception 0xbad") {
+		t.Fatalf("No stack trace: %v", o)
+	}
+}
+
+const raiseExceptionSource = `
+package main
+import "syscall"
+func main() {
+	const EXCEPTION_NONCONTINUABLE = 1
+	mod := syscall.MustLoadDLL("kernel32.dll")
+	proc := mod.MustFindProc("RaiseException")
+	proc.Call(0xbad, EXCEPTION_NONCONTINUABLE, 0, 0)
+	println("RaiseException should not return")
+}
+`
+
+func TestZeroDivisionException(t *testing.T) {
+	o := executeTest(t, zeroDivisionExceptionSource, nil)
+	if !strings.Contains(o, "panic: runtime error: integer divide by zero") {
+		t.Fatalf("No stack trace: %v", o)
+	}
+}
+
+const zeroDivisionExceptionSource = `
+package main
+func main() {
+	x := 1
+	y := 0
+	z := x / y
+	println(z)
+}
+`
diff --git a/src/runtime/thunk.s b/src/runtime/thunk.s
new file mode 100644
index 0000000..0a0f147
--- /dev/null
+++ b/src/runtime/thunk.s
@@ -0,0 +1,183 @@
+// 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 file exposes various internal runtime functions to other packages in std lib.
+
+#include "zasm_GOOS_GOARCH.h"
+#include "textflag.h"
+
+#ifdef GOARCH_arm
+#define JMP B
+#endif
+
+TEXT net·runtimeNano(SB),NOSPLIT,$0-0
+	JMP	runtime·nanotime(SB)
+
+TEXT time·runtimeNano(SB),NOSPLIT,$0-0
+	JMP     runtime·nanotime(SB)
+
+TEXT time·Sleep(SB),NOSPLIT,$0-0
+	JMP     runtime·timeSleep(SB)
+
+TEXT time·startTimer(SB),NOSPLIT,$0-0
+	JMP     runtime·startTimer(SB)
+
+TEXT time·stopTimer(SB),NOSPLIT,$0-0
+	JMP     runtime·stopTimer(SB)
+
+TEXT sync·runtime_Syncsemacquire(SB),NOSPLIT,$0-0
+	JMP	runtime·syncsemacquire(SB)
+
+TEXT sync·runtime_Syncsemrelease(SB),NOSPLIT,$0-0
+	JMP	runtime·syncsemrelease(SB)
+
+TEXT sync·runtime_Syncsemcheck(SB),NOSPLIT,$0-0
+	JMP	runtime·syncsemcheck(SB)
+
+TEXT sync·runtime_Semacquire(SB),NOSPLIT,$0-0
+	JMP	runtime·asyncsemacquire(SB)
+
+TEXT sync·runtime_Semrelease(SB),NOSPLIT,$0-0
+	JMP	runtime·asyncsemrelease(SB)
+
+TEXT sync·runtime_registerPoolCleanup(SB),NOSPLIT,$0-0
+	JMP	runtime·registerPoolCleanup(SB)
+
+TEXT net·runtime_Semacquire(SB),NOSPLIT,$0-0
+	JMP	runtime·asyncsemacquire(SB)
+
+TEXT net·runtime_Semrelease(SB),NOSPLIT,$0-0
+	JMP	runtime·asyncsemrelease(SB)
+
+TEXT runtime∕pprof·runtime_cyclesPerSecond(SB),NOSPLIT,$0-0
+	JMP	runtime·tickspersecond(SB)
+
+TEXT bytes·Compare(SB),NOSPLIT,$0-0
+	JMP	runtime·cmpbytes(SB)
+
+TEXT reflect·call(SB), NOSPLIT, $0-0
+	JMP	runtime·reflectcall(SB)
+
+TEXT reflect·chanclose(SB), NOSPLIT, $0-0
+	JMP	runtime·closechan(SB)
+
+TEXT reflect·chanlen(SB), NOSPLIT, $0-0
+	JMP	runtime·reflect_chanlen(SB)
+
+TEXT reflect·chancap(SB), NOSPLIT, $0-0
+	JMP	runtime·reflect_chancap(SB)
+
+TEXT reflect·chansend(SB), NOSPLIT, $0-0
+	JMP	runtime·reflect_chansend(SB)
+
+TEXT reflect·chanrecv(SB), NOSPLIT, $0-0
+	JMP	runtime·reflect_chanrecv(SB)
+
+TEXT reflect·memmove(SB), NOSPLIT, $0-0
+	JMP	runtime·memmove(SB)
+
+TEXT runtime∕debug·freeOSMemory(SB), NOSPLIT, $0-0
+	JMP	runtime·freeOSMemory(SB)
+
+TEXT runtime∕debug·WriteHeapDump(SB), NOSPLIT, $0-0
+	JMP	runtime·writeHeapDump(SB)
+
+TEXT net·runtime_pollServerInit(SB),NOSPLIT,$0-0
+	JMP	runtime·netpollServerInit(SB)
+
+TEXT net·runtime_pollOpen(SB),NOSPLIT,$0-0
+	JMP	runtime·netpollOpen(SB)
+
+TEXT net·runtime_pollClose(SB),NOSPLIT,$0-0
+	JMP	runtime·netpollClose(SB)
+
+TEXT net·runtime_pollReset(SB),NOSPLIT,$0-0
+	JMP	runtime·netpollReset(SB)
+
+TEXT net·runtime_pollWait(SB),NOSPLIT,$0-0
+	JMP	runtime·netpollWait(SB)
+
+TEXT net·runtime_pollWaitCanceled(SB),NOSPLIT,$0-0
+	JMP	runtime·netpollWaitCanceled(SB)
+
+TEXT net·runtime_pollSetDeadline(SB),NOSPLIT,$0-0
+	JMP	runtime·netpollSetDeadline(SB)
+
+TEXT net·runtime_pollUnblock(SB),NOSPLIT,$0-0
+	JMP	runtime·netpollUnblock(SB)
+
+TEXT syscall·setenv_c(SB), NOSPLIT, $0-0
+	JMP	runtime·syscall_setenv_c(SB)
+
+TEXT syscall·unsetenv_c(SB), NOSPLIT, $0-0
+	JMP	runtime·syscall_unsetenv_c(SB)
+
+TEXT reflect·makemap(SB),NOSPLIT,$0-0
+	JMP	runtime·reflect_makemap(SB)
+
+TEXT reflect·mapaccess(SB),NOSPLIT,$0-0
+	JMP	runtime·reflect_mapaccess(SB)
+
+TEXT reflect·mapassign(SB),NOSPLIT,$0-0
+	JMP	runtime·reflect_mapassign(SB)
+
+TEXT reflect·mapdelete(SB),NOSPLIT,$0-0
+	JMP	runtime·reflect_mapdelete(SB)
+
+TEXT reflect·mapiterinit(SB),NOSPLIT,$0-0
+	JMP	runtime·reflect_mapiterinit(SB)
+
+TEXT reflect·mapiterkey(SB),NOSPLIT,$0-0
+	JMP	runtime·reflect_mapiterkey(SB)
+
+TEXT reflect·mapiternext(SB),NOSPLIT,$0-0
+	JMP	runtime·reflect_mapiternext(SB)
+
+TEXT reflect·maplen(SB),NOSPLIT,$0-0
+	JMP	runtime·reflect_maplen(SB)
+
+TEXT reflect·ismapkey(SB),NOSPLIT,$0-0
+	JMP	runtime·reflect_ismapkey(SB)
+
+TEXT reflect·ifaceE2I(SB),NOSPLIT,$0-0
+	JMP	runtime·reflect_ifaceE2I(SB)
+
+TEXT reflect·unsafe_New(SB),NOSPLIT,$0-0
+	JMP	runtime·newobject(SB)
+
+TEXT reflect·unsafe_NewArray(SB),NOSPLIT,$0-0
+	JMP	runtime·newarray(SB)
+
+TEXT reflect·makechan(SB),NOSPLIT,$0-0
+	JMP	runtime·makechan(SB)
+
+TEXT reflect·rselect(SB),NOSPLIT,$0-0
+	JMP	runtime·reflect_rselect(SB)
+
+TEXT os·sigpipe(SB),NOSPLIT,$0-0
+	JMP	runtime·os_sigpipe(SB)
+
+TEXT runtime·runtime_init(SB),NOSPLIT,$0-0
+	JMP	runtime·init(SB)
+
+TEXT runtime·main_init(SB),NOSPLIT,$0-0
+	JMP	main·init(SB)
+
+TEXT runtime·main_main(SB),NOSPLIT,$0-0
+	JMP	main·main(SB)
+
+TEXT runtime·timenow(SB),NOSPLIT,$0-0
+	JMP	time·now(SB)
+
+TEXT sync∕atomic·runtime_procPin(SB),NOSPLIT,$0-0
+	JMP     sync·runtime_procPin(SB)
+
+TEXT sync∕atomic·runtime_procUnpin(SB),NOSPLIT,$0-0
+	JMP     sync·runtime_procUnpin(SB)
+
+TEXT syscall·runtime_envs(SB),NOSPLIT,$0-0
+	JMP	runtime·runtime_envs(SB)
+
+TEXT os·runtime_args(SB),NOSPLIT,$0-0
+	JMP	runtime·runtime_args(SB)
diff --git a/src/runtime/thunk_solaris_amd64.s b/src/runtime/thunk_solaris_amd64.s
new file mode 100644
index 0000000..f61188c
--- /dev/null
+++ b/src/runtime/thunk_solaris_amd64.s
@@ -0,0 +1,88 @@
+// 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 file exposes various external library functions to Go code in the runtime.
+
+#include "zasm_GOOS_GOARCH.h"
+#include "textflag.h"
+
+TEXT runtime·libc_chdir(SB),NOSPLIT,$0
+	MOVQ	libc·chdir(SB), AX
+	JMP	AX
+
+TEXT runtime·libc_chroot(SB),NOSPLIT,$0
+	MOVQ	libc·chroot(SB), AX
+	JMP	AX
+
+TEXT runtime·libc_close(SB),NOSPLIT,$0
+	MOVQ	libc·close(SB), AX
+	JMP	AX
+
+TEXT runtime·libc_dlopen(SB),NOSPLIT,$0
+	MOVQ	libc·dlopen(SB), AX
+	JMP	AX
+
+TEXT runtime·libc_dlclose(SB),NOSPLIT,$0
+	MOVQ	libc·dlclose(SB), AX
+	JMP	AX
+
+TEXT runtime·libc_dlsym(SB),NOSPLIT,$0
+	MOVQ	libc·dlsym(SB), AX
+	JMP	AX
+
+TEXT runtime·libc_execve(SB),NOSPLIT,$0
+	MOVQ	libc·execve(SB), AX
+	JMP	AX
+
+TEXT runtime·libc_exit(SB),NOSPLIT,$0
+	MOVQ	libc·exit(SB), AX
+	JMP	AX
+
+TEXT runtime·libc_fcntl(SB),NOSPLIT,$0
+	MOVQ	libc·fcntl(SB), AX
+	JMP	AX
+
+TEXT runtime·libc_forkx(SB),NOSPLIT,$0
+	MOVQ	libc·forkx(SB), AX
+	JMP	AX
+
+TEXT runtime·libc_gethostname(SB),NOSPLIT,$0
+	MOVQ	libc·gethostname(SB), AX
+	JMP	AX
+
+TEXT runtime·libc_ioctl(SB),NOSPLIT,$0
+	MOVQ	libc·ioctl(SB), AX
+	JMP	AX
+
+TEXT runtime·libc_setgid(SB),NOSPLIT,$0
+	MOVQ	libc·setgid(SB), AX
+	JMP	AX
+
+TEXT runtime·libc_setgroups(SB),NOSPLIT,$0
+	MOVQ	libc·setgroups(SB), AX
+	JMP	AX
+
+TEXT runtime·libc_setsid(SB),NOSPLIT,$0
+	MOVQ	libc·setsid(SB), AX
+	JMP	AX
+
+TEXT runtime·libc_setuid(SB),NOSPLIT,$0
+	MOVQ	libc·setuid(SB), AX
+	JMP	AX
+
+TEXT runtime·libc_setpgid(SB),NOSPLIT,$0
+	MOVQ	libc·setpgid(SB), AX
+	JMP	AX
+
+TEXT runtime·libc_syscall(SB),NOSPLIT,$0
+	MOVQ	libc·syscall(SB), AX
+	JMP	AX
+
+TEXT runtime·libc_wait4(SB),NOSPLIT,$0
+	MOVQ	libc·wait4(SB), AX
+	JMP	AX
+
+TEXT runtime·libc_write(SB),NOSPLIT,$0
+	MOVQ	libc·write(SB), AX
+	JMP	AX
diff --git a/src/runtime/thunk_windows.s b/src/runtime/thunk_windows.s
new file mode 100644
index 0000000..7ccb98f
--- /dev/null
+++ b/src/runtime/thunk_windows.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.
+
+#include "zasm_GOOS_GOARCH.h"
+#include "textflag.h"
+
+TEXT syscall·Syscall(SB),NOSPLIT,$0-0
+	JMP	runtime·syscall_Syscall(SB)
+
+TEXT syscall·Syscall6(SB),NOSPLIT,$0-0
+	JMP	runtime·syscall_Syscall6(SB)
+
+TEXT syscall·Syscall9(SB),NOSPLIT,$0-0
+	JMP	runtime·syscall_Syscall9(SB)
+
+TEXT syscall·Syscall12(SB),NOSPLIT,$0-0
+	JMP	runtime·syscall_Syscall12(SB)
+
+TEXT syscall·Syscall15(SB),NOSPLIT,$0-0
+	JMP	runtime·syscall_Syscall15(SB)
+
+TEXT syscall·loadlibrary(SB),NOSPLIT,$0-0
+	JMP	runtime·syscall_loadlibrary(SB)
+
+TEXT syscall·getprocaddress(SB),NOSPLIT,$0-0
+	JMP	runtime·syscall_getprocaddress(SB)
+
+TEXT syscall·compileCallback(SB),NOSPLIT,$0
+	JMP	runtime·compileCallback(SB)
diff --git a/src/runtime/time.go b/src/runtime/time.go
new file mode 100644
index 0000000..11862c7
--- /dev/null
+++ b/src/runtime/time.go
@@ -0,0 +1,289 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Time-related runtime and pieces of package time.
+
+package runtime
+
+import "unsafe"
+
+// Package time knows the layout of this structure.
+// If this struct changes, adjust ../time/sleep.go:/runtimeTimer.
+// For GOOS=nacl, package syscall knows the layout of this structure.
+// If this struct changes, adjust ../syscall/net_nacl.go:/runtimeTimer.
+type timer struct {
+	i int // heap index
+
+	// Timer wakes up at when, and then at when+period, ... (period > 0 only)
+	// each time calling f(now, arg) in the timer goroutine, so f must be
+	// a well-behaved function and not block.
+	when   int64
+	period int64
+	f      func(interface{}, uintptr)
+	arg    interface{}
+	seq    uintptr
+}
+
+var timers struct {
+	lock         mutex
+	gp           *g
+	created      bool
+	sleeping     bool
+	rescheduling bool
+	waitnote     note
+	t            []*timer
+}
+
+// nacl fake time support - time in nanoseconds since 1970
+var faketime int64
+
+// Package time APIs.
+// Godoc uses the comments in package time, not these.
+
+// time.now is implemented in assembly.
+
+// Sleep puts the current goroutine to sleep for at least ns nanoseconds.
+func timeSleep(ns int64) {
+	if ns <= 0 {
+		return
+	}
+
+	t := new(timer)
+	t.when = nanotime() + ns
+	t.f = goroutineReady
+	t.arg = getg()
+	lock(&timers.lock)
+	addtimerLocked(t)
+	goparkunlock(&timers.lock, "sleep")
+}
+
+// startTimer adds t to the timer heap.
+func startTimer(t *timer) {
+	if raceenabled {
+		racerelease(unsafe.Pointer(t))
+	}
+	addtimer(t)
+}
+
+// stopTimer removes t from the timer heap if it is there.
+// It returns true if t was removed, false if t wasn't even there.
+func stopTimer(t *timer) bool {
+	return deltimer(t)
+}
+
+// Go runtime.
+
+// Ready the goroutine arg.
+func goroutineReady(arg interface{}, seq uintptr) {
+	goready(arg.(*g))
+}
+
+func addtimer(t *timer) {
+	lock(&timers.lock)
+	addtimerLocked(t)
+	unlock(&timers.lock)
+}
+
+// Add a timer to the heap and start or kick the timer proc.
+// If the new timer is earlier than any of the others.
+// Timers are locked.
+func addtimerLocked(t *timer) {
+	// when must never be negative; otherwise timerproc will overflow
+	// during its delta calculation and never expire other runtime·timers.
+	if t.when < 0 {
+		t.when = 1<<63 - 1
+	}
+	t.i = len(timers.t)
+	timers.t = append(timers.t, t)
+	siftupTimer(t.i)
+	if t.i == 0 {
+		// siftup moved to top: new earliest deadline.
+		if timers.sleeping {
+			timers.sleeping = false
+			notewakeup(&timers.waitnote)
+		}
+		if timers.rescheduling {
+			timers.rescheduling = false
+			goready(timers.gp)
+		}
+	}
+	if !timers.created {
+		timers.created = true
+		go timerproc()
+	}
+}
+
+// Delete timer t from the heap.
+// Do not need to update the timerproc: if it wakes up early, no big deal.
+func deltimer(t *timer) bool {
+	// Dereference t so that any panic happens before the lock is held.
+	// Discard result, because t might be moving in the heap.
+	_ = t.i
+
+	lock(&timers.lock)
+	// t may not be registered anymore and may have
+	// a bogus i (typically 0, if generated by Go).
+	// Verify it before proceeding.
+	i := t.i
+	last := len(timers.t) - 1
+	if i < 0 || i > last || timers.t[i] != t {
+		unlock(&timers.lock)
+		return false
+	}
+	if i != last {
+		timers.t[i] = timers.t[last]
+		timers.t[i].i = i
+	}
+	timers.t[last] = nil
+	timers.t = timers.t[:last]
+	if i != last {
+		siftupTimer(i)
+		siftdownTimer(i)
+	}
+	unlock(&timers.lock)
+	return true
+}
+
+// Timerproc runs the time-driven events.
+// It sleeps until the next event in the timers heap.
+// If addtimer inserts a new earlier event, addtimer1 wakes timerproc early.
+func timerproc() {
+	timers.gp = getg()
+	timers.gp.issystem = true
+	for {
+		lock(&timers.lock)
+		timers.sleeping = false
+		now := nanotime()
+		delta := int64(-1)
+		for {
+			if len(timers.t) == 0 {
+				delta = -1
+				break
+			}
+			t := timers.t[0]
+			delta = t.when - now
+			if delta > 0 {
+				break
+			}
+			if t.period > 0 {
+				// leave in heap but adjust next time to fire
+				t.when += t.period * (1 + -delta/t.period)
+				siftdownTimer(0)
+			} else {
+				// remove from heap
+				last := len(timers.t) - 1
+				if last > 0 {
+					timers.t[0] = timers.t[last]
+					timers.t[0].i = 0
+				}
+				timers.t[last] = nil
+				timers.t = timers.t[:last]
+				if last > 0 {
+					siftdownTimer(0)
+				}
+				t.i = -1 // mark as removed
+			}
+			f := t.f
+			arg := t.arg
+			seq := t.seq
+			unlock(&timers.lock)
+			if raceenabled {
+				raceacquire(unsafe.Pointer(t))
+			}
+			f(arg, seq)
+			lock(&timers.lock)
+		}
+		if delta < 0 || faketime > 0 {
+			// No timers left - put goroutine to sleep.
+			timers.rescheduling = true
+			goparkunlock(&timers.lock, "timer goroutine (idle)")
+			continue
+		}
+		// At least one timer pending.  Sleep until then.
+		timers.sleeping = true
+		noteclear(&timers.waitnote)
+		unlock(&timers.lock)
+		notetsleepg(&timers.waitnote, delta)
+	}
+}
+
+func timejump() *g {
+	if faketime == 0 {
+		return nil
+	}
+
+	lock(&timers.lock)
+	if !timers.created || len(timers.t) == 0 {
+		unlock(&timers.lock)
+		return nil
+	}
+
+	var gp *g
+	if faketime < timers.t[0].when {
+		faketime = timers.t[0].when
+		if timers.rescheduling {
+			timers.rescheduling = false
+			gp = timers.gp
+		}
+	}
+	unlock(&timers.lock)
+	return gp
+}
+
+// Heap maintenance algorithms.
+
+func siftupTimer(i int) {
+	t := timers.t
+	when := t[i].when
+	tmp := t[i]
+	for i > 0 {
+		p := (i - 1) / 4 // parent
+		if when >= t[p].when {
+			break
+		}
+		t[i] = t[p]
+		t[i].i = i
+		t[p] = tmp
+		t[p].i = p
+		i = p
+	}
+}
+
+func siftdownTimer(i int) {
+	t := timers.t
+	n := len(t)
+	when := t[i].when
+	tmp := t[i]
+	for {
+		c := i*4 + 1 // left child
+		c3 := c + 2  // mid child
+		if c >= n {
+			break
+		}
+		w := t[c].when
+		if c+1 < n && t[c+1].when < w {
+			w = t[c+1].when
+			c++
+		}
+		if c3 < n {
+			w3 := t[c3].when
+			if c3+1 < n && t[c3+1].when < w3 {
+				w3 = t[c3+1].when
+				c3++
+			}
+			if w3 < w {
+				w = w3
+				c = c3
+			}
+		}
+		if w >= when {
+			break
+		}
+		t[i] = t[c]
+		t[i].i = i
+		t[c] = tmp
+		t[c].i = c
+		i = c
+	}
+}
diff --git a/src/runtime/tls_arm.s b/src/runtime/tls_arm.s
new file mode 100644
index 0000000..85c3940
--- /dev/null
+++ b/src/runtime/tls_arm.s
@@ -0,0 +1,69 @@
+// 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 "zasm_GOOS_GOARCH.h"
+#include "funcdata.h"
+#include "textflag.h"
+
+// We have to resort to TLS variable to save g(R10).
+// One reason is that external code might trigger
+// SIGSEGV, and our runtime.sigtramp don't even know we
+// are in external code, and will continue to use R10,
+// this might as well result in another SIGSEGV.
+// Note: both functions will clobber R0 and R11 and
+// can be called from 5c ABI code.
+
+// On android, runtime.tlsg is a normal variable.
+// TLS offset is computed in x_cgo_inittls.
+
+// save_g saves the g register into pthread-provided
+// thread-local memory, so that we can call externally compiled
+// ARM code that will overwrite those registers.
+// NOTE: runtime.gogo assumes that R1 is preserved by this function.
+//       runtime.mcall assumes this function only clobbers R0 and R11.
+// Returns with g in R0.
+TEXT runtime·save_g(SB),NOSPLIT,$-4
+#ifdef GOOS_nacl
+	// nothing to do as nacl/arm does not use TLS at all.
+	MOVW	g, R0 // preserve R0 across call to setg<>
+	RET
+#endif
+	// If the host does not support MRC the linker will replace it with
+	// a call to runtime.read_tls_fallback which jumps to __kuser_get_tls.
+	// The replacement function saves LR in R11 over the call to read_tls_fallback.
+	MRC	15, 0, R0, C13, C0, 3 // fetch TLS base pointer
+	// $runtime.tlsg(SB) is a special linker symbol.
+	// It is the offset from the TLS base pointer to our
+	// thread-local storage for g.
+#ifdef GOOS_android
+	MOVW	runtime·tlsg(SB), R11
+#else
+	MOVW	$runtime·tlsg(SB), R11
+#endif
+	ADD	R11, R0
+	MOVW	g, 0(R0)
+	MOVW	g, R0 // preserve R0 across call to setg<>
+	RET
+
+// load_g loads the g register from pthread-provided
+// thread-local memory, for use after calling externally compiled
+// ARM code that overwrote those registers.
+TEXT runtime·load_g(SB),NOSPLIT,$0
+#ifdef GOOS_nacl
+	// nothing to do as nacl/arm does not use TLS at all.
+	RET
+#endif
+	// See save_g
+	MRC	15, 0, R0, C13, C0, 3 // fetch TLS base pointer
+	// $runtime.tlsg(SB) is a special linker symbol.
+	// It is the offset from the TLS base pointer to our
+	// thread-local storage for g.
+#ifdef GOOS_android
+	MOVW	runtime·tlsg(SB), R11
+#else
+	MOVW	$runtime·tlsg(SB), R11
+#endif
+	ADD	R11, R0
+	MOVW	0(R0), g
+	RET
diff --git a/src/runtime/traceback.go b/src/runtime/traceback.go
new file mode 100644
index 0000000..1c6ce6e
--- /dev/null
+++ b/src/runtime/traceback.go
@@ -0,0 +1,659 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package runtime
+
+import "unsafe"
+
+// The code in this file implements stack trace walking for all architectures.
+// The most important fact about a given architecture is whether it uses a link register.
+// On systems with link registers, the prologue for a non-leaf function stores the
+// incoming value of LR at the bottom of the newly allocated stack frame.
+// On systems without link registers, the architecture pushes a return PC during
+// the call instruction, so the return PC ends up above the stack frame.
+// In this file, the return PC is always called LR, no matter how it was found.
+//
+// To date, the opposite of a link register architecture is an x86 architecture.
+// This code may need to change if some other kind of non-link-register
+// architecture comes along.
+//
+// The other important fact is the size of a pointer: on 32-bit systems the LR
+// takes up only 4 bytes on the stack, while on 64-bit systems it takes up 8 bytes.
+// Typically this is ptrSize.
+//
+// As an exception, amd64p32 has ptrSize == 4 but the CALL instruction still
+// stores an 8-byte return PC onto the stack. To accommodate this, we use regSize
+// as the size of the architecture-pushed return PC.
+//
+// usesLR is defined below. ptrSize and regSize are defined in stubs.go.
+
+const usesLR = GOARCH != "amd64" && GOARCH != "amd64p32" && GOARCH != "386"
+
+var (
+	// initialized in tracebackinit
+	deferprocPC uintptr
+	goexitPC    uintptr
+	jmpdeferPC  uintptr
+	mcallPC     uintptr
+	morestackPC uintptr
+	mstartPC    uintptr
+	newprocPC   uintptr
+	rt0_goPC    uintptr
+	sigpanicPC  uintptr
+
+	externalthreadhandlerp uintptr // initialized elsewhere
+)
+
+func tracebackinit() {
+	// Go variable initialization happens late during runtime startup.
+	// Instead of initializing the variables above in the declarations,
+	// schedinit calls this function so that the variables are
+	// initialized and available earlier in the startup sequence.
+	deferprocPC = funcPC(deferproc)
+	goexitPC = funcPC(goexit)
+	jmpdeferPC = funcPC(jmpdefer)
+	mcallPC = funcPC(mcall)
+	morestackPC = funcPC(morestack)
+	mstartPC = funcPC(mstart)
+	newprocPC = funcPC(newproc)
+	rt0_goPC = funcPC(rt0_go)
+	sigpanicPC = funcPC(sigpanic)
+}
+
+// Traceback over the deferred function calls.
+// Report them like calls that have been invoked but not started executing yet.
+func tracebackdefers(gp *g, callback func(*stkframe, unsafe.Pointer) bool, v unsafe.Pointer) {
+	var frame stkframe
+	for d := gp._defer; d != nil; d = d.link {
+		fn := d.fn
+		if fn == nil {
+			// Defer of nil function. Args don't matter.
+			frame.pc = 0
+			frame.fn = nil
+			frame.argp = 0
+			frame.arglen = 0
+			frame.argmap = nil
+		} else {
+			frame.pc = uintptr(fn.fn)
+			f := findfunc(frame.pc)
+			if f == nil {
+				print("runtime: unknown pc in defer ", hex(frame.pc), "\n")
+				gothrow("unknown pc")
+			}
+			frame.fn = f
+			frame.argp = uintptr(deferArgs(d))
+			setArgInfo(&frame, f, true)
+		}
+		frame.continpc = frame.pc
+		if !callback((*stkframe)(noescape(unsafe.Pointer(&frame))), v) {
+			return
+		}
+	}
+}
+
+// Generic traceback.  Handles runtime stack prints (pcbuf == nil),
+// the runtime.Callers function (pcbuf != nil), as well as the garbage
+// collector (callback != nil).  A little clunky to merge these, but avoids
+// duplicating the code and all its subtlety.
+func gentraceback(pc0 uintptr, sp0 uintptr, lr0 uintptr, gp *g, skip int, pcbuf *uintptr, max int, callback func(*stkframe, unsafe.Pointer) bool, v unsafe.Pointer, flags uint) int {
+	if goexitPC == 0 {
+		gothrow("gentraceback before goexitPC initialization")
+	}
+	g := getg()
+	if g == gp && g == g.m.curg {
+		// The starting sp has been passed in as a uintptr, and the caller may
+		// have other uintptr-typed stack references as well.
+		// If during one of the calls that got us here or during one of the
+		// callbacks below the stack must be grown, all these uintptr references
+		// to the stack will not be updated, and gentraceback will continue
+		// to inspect the old stack memory, which may no longer be valid.
+		// Even if all the variables were updated correctly, it is not clear that
+		// we want to expose a traceback that begins on one stack and ends
+		// on another stack. That could confuse callers quite a bit.
+		// Instead, we require that gentraceback and any other function that
+		// accepts an sp for the current goroutine (typically obtained by
+		// calling getcallersp) must not run on that goroutine's stack but
+		// instead on the g0 stack.
+		gothrow("gentraceback cannot trace user goroutine on its own stack")
+	}
+	gotraceback := gotraceback(nil)
+	if pc0 == ^uintptr(0) && sp0 == ^uintptr(0) { // Signal to fetch saved values from gp.
+		if gp.syscallsp != 0 {
+			pc0 = gp.syscallpc
+			sp0 = gp.syscallsp
+			if usesLR {
+				lr0 = 0
+			}
+		} else {
+			pc0 = gp.sched.pc
+			sp0 = gp.sched.sp
+			if usesLR {
+				lr0 = gp.sched.lr
+			}
+		}
+	}
+
+	nprint := 0
+	var frame stkframe
+	frame.pc = pc0
+	frame.sp = sp0
+	if usesLR {
+		frame.lr = lr0
+	}
+	waspanic := false
+	wasnewproc := false
+	printing := pcbuf == nil && callback == nil
+	_defer := gp._defer
+
+	for _defer != nil && uintptr(_defer.argp) == _NoArgs {
+		_defer = _defer.link
+	}
+
+	// If the PC is zero, it's likely a nil function call.
+	// Start in the caller's frame.
+	if frame.pc == 0 {
+		if usesLR {
+			frame.pc = *(*uintptr)(unsafe.Pointer(frame.sp))
+			frame.lr = 0
+		} else {
+			frame.pc = uintptr(*(*uintreg)(unsafe.Pointer(frame.sp)))
+			frame.sp += regSize
+		}
+	}
+
+	f := findfunc(frame.pc)
+	if f == nil {
+		if callback != nil {
+			print("runtime: unknown pc ", hex(frame.pc), "\n")
+			gothrow("unknown pc")
+		}
+		return 0
+	}
+	frame.fn = f
+
+	n := 0
+	for n < max {
+		// Typically:
+		//	pc is the PC of the running function.
+		//	sp is the stack pointer at that program counter.
+		//	fp is the frame pointer (caller's stack pointer) at that program counter, or nil if unknown.
+		//	stk is the stack containing sp.
+		//	The caller's program counter is lr, unless lr is zero, in which case it is *(uintptr*)sp.
+		f = frame.fn
+
+		// Found an actual function.
+		// Derive frame pointer and link register.
+		if frame.fp == 0 {
+			frame.fp = frame.sp + uintptr(funcspdelta(f, frame.pc))
+			if !usesLR {
+				// On x86, call instruction pushes return PC before entering new function.
+				frame.fp += regSize
+			}
+		}
+		var flr *_func
+		if topofstack(f) {
+			frame.lr = 0
+			flr = nil
+		} else if usesLR && f.entry == jmpdeferPC {
+			// jmpdefer modifies SP/LR/PC non-atomically.
+			// If a profiling interrupt arrives during jmpdefer,
+			// the stack unwind may see a mismatched register set
+			// and get confused. Stop if we see PC within jmpdefer
+			// to avoid that confusion.
+			// See golang.org/issue/8153.
+			if callback != nil {
+				gothrow("traceback_arm: found jmpdefer when tracing with callback")
+			}
+			frame.lr = 0
+		} else {
+			if usesLR {
+				if n == 0 && frame.sp < frame.fp || frame.lr == 0 {
+					frame.lr = *(*uintptr)(unsafe.Pointer(frame.sp))
+				}
+			} else {
+				if frame.lr == 0 {
+					frame.lr = uintptr(*(*uintreg)(unsafe.Pointer(frame.fp - regSize)))
+				}
+			}
+			flr = findfunc(frame.lr)
+			if flr == nil {
+				// This happens if you get a profiling interrupt at just the wrong time.
+				// In that context it is okay to stop early.
+				// But if callback is set, we're doing a garbage collection and must
+				// get everything, so crash loudly.
+				if callback != nil {
+					print("runtime: unexpected return pc for ", gofuncname(f), " called from ", hex(frame.lr), "\n")
+					gothrow("unknown caller pc")
+				}
+			}
+		}
+
+		frame.varp = frame.fp
+		if !usesLR {
+			// On x86, call instruction pushes return PC before entering new function.
+			frame.varp -= regSize
+		}
+
+		// Derive size of arguments.
+		// Most functions have a fixed-size argument block,
+		// so we can use metadata about the function f.
+		// Not all, though: there are some variadic functions
+		// in package runtime and reflect, and for those we use call-specific
+		// metadata recorded by f's caller.
+		if callback != nil || printing {
+			frame.argp = frame.fp
+			if usesLR {
+				frame.argp += ptrSize
+			}
+			setArgInfo(&frame, f, callback != nil)
+		}
+
+		// Determine function SP where deferproc would find its arguments.
+		var sparg uintptr
+		if usesLR {
+			// On link register architectures, that's the standard bottom-of-stack plus 1 word
+			// for the saved LR. If the previous frame was a direct call to newproc/deferproc,
+			// however, the SP is three words lower than normal.
+			// If the function has no frame at all - perhaps it just started, or perhaps
+			// it is a leaf with no local variables - then we cannot possibly find its
+			// SP in a defer, and we might confuse its SP for its caller's SP, so
+			// leave sparg=0 in that case.
+			if frame.fp != frame.sp {
+				sparg = frame.sp + regSize
+				if wasnewproc {
+					sparg += 3 * regSize
+				}
+			}
+		} else {
+			// On x86 that's the standard bottom-of-stack, so SP exactly.
+			// If the previous frame was a direct call to newproc/deferproc, however,
+			// the SP is two words lower than normal.
+			sparg = frame.sp
+			if wasnewproc {
+				sparg += 2 * ptrSize
+			}
+		}
+
+		// Determine frame's 'continuation PC', where it can continue.
+		// Normally this is the return address on the stack, but if sigpanic
+		// is immediately below this function on the stack, then the frame
+		// stopped executing due to a trap, and frame.pc is probably not
+		// a safe point for looking up liveness information. In this panicking case,
+		// the function either doesn't return at all (if it has no defers or if the
+		// defers do not recover) or it returns from one of the calls to
+		// deferproc a second time (if the corresponding deferred func recovers).
+		// It suffices to assume that the most recent deferproc is the one that
+		// returns; everything live at earlier deferprocs is still live at that one.
+		frame.continpc = frame.pc
+		if waspanic {
+			if _defer != nil && _defer.argp == sparg {
+				frame.continpc = _defer.pc
+			} else {
+				frame.continpc = 0
+			}
+		}
+
+		// Unwind our local defer stack past this frame.
+		for _defer != nil && (_defer.argp == sparg || _defer.argp == _NoArgs) {
+			_defer = _defer.link
+		}
+
+		if skip > 0 {
+			skip--
+			goto skipped
+		}
+
+		if pcbuf != nil {
+			(*[1 << 20]uintptr)(unsafe.Pointer(pcbuf))[n] = frame.pc
+		}
+		if callback != nil {
+			if !callback((*stkframe)(noescape(unsafe.Pointer(&frame))), v) {
+				return n
+			}
+		}
+		if printing {
+			if (flags&_TraceRuntimeFrames) != 0 || showframe(f, gp) {
+				// Print during crash.
+				//	main(0x1, 0x2, 0x3)
+				//		/home/rsc/go/src/runtime/x.go:23 +0xf
+				//
+				tracepc := frame.pc // back up to CALL instruction for funcline.
+				if (n > 0 || flags&_TraceTrap == 0) && frame.pc > f.entry && !waspanic {
+					tracepc--
+				}
+				print(gofuncname(f), "(")
+				argp := (*[100]uintptr)(unsafe.Pointer(frame.argp))
+				for i := uintptr(0); i < frame.arglen/ptrSize; i++ {
+					if i >= 10 {
+						print(", ...")
+						break
+					}
+					if i != 0 {
+						print(", ")
+					}
+					print(hex(argp[i]))
+				}
+				print(")\n")
+				var file string
+				line := funcline(f, tracepc, &file)
+				print("\t", file, ":", line)
+				if frame.pc > f.entry {
+					print(" +", hex(frame.pc-f.entry))
+				}
+				if g.m.throwing > 0 && gp == g.m.curg || gotraceback >= 2 {
+					print(" fp=", hex(frame.fp), " sp=", hex(frame.sp))
+				}
+				print("\n")
+				nprint++
+			}
+		}
+		n++
+
+	skipped:
+		waspanic = f.entry == sigpanicPC
+		wasnewproc = f.entry == newprocPC || f.entry == deferprocPC
+
+		// Do not unwind past the bottom of the stack.
+		if flr == nil {
+			break
+		}
+
+		// Unwind to next frame.
+		frame.fn = flr
+		frame.pc = frame.lr
+		frame.lr = 0
+		frame.sp = frame.fp
+		frame.fp = 0
+		frame.argmap = nil
+
+		// On link register architectures, sighandler saves the LR on stack
+		// before faking a call to sigpanic.
+		if usesLR && waspanic {
+			x := *(*uintptr)(unsafe.Pointer(frame.sp))
+			frame.sp += ptrSize
+			f = findfunc(frame.pc)
+			frame.fn = f
+			if f == nil {
+				frame.pc = x
+			} else if f.frame == 0 {
+				frame.lr = x
+			}
+		}
+	}
+
+	if pcbuf == nil && callback == nil {
+		n = nprint
+	}
+
+	// If callback != nil, we're being called to gather stack information during
+	// garbage collection or stack growth. In that context, require that we used
+	// up the entire defer stack. If not, then there is a bug somewhere and the
+	// garbage collection or stack growth may not have seen the correct picture
+	// of the stack. Crash now instead of silently executing the garbage collection
+	// or stack copy incorrectly and setting up for a mysterious crash later.
+	//
+	// Note that panic != nil is okay here: there can be leftover panics,
+	// because the defers on the panic stack do not nest in frame order as
+	// they do on the defer stack. If you have:
+	//
+	//	frame 1 defers d1
+	//	frame 2 defers d2
+	//	frame 3 defers d3
+	//	frame 4 panics
+	//	frame 4's panic starts running defers
+	//	frame 5, running d3, defers d4
+	//	frame 5 panics
+	//	frame 5's panic starts running defers
+	//	frame 6, running d4, garbage collects
+	//	frame 6, running d2, garbage collects
+	//
+	// During the execution of d4, the panic stack is d4 -> d3, which
+	// is nested properly, and we'll treat frame 3 as resumable, because we
+	// can find d3. (And in fact frame 3 is resumable. If d4 recovers
+	// and frame 5 continues running, d3, d3 can recover and we'll
+	// resume execution in (returning from) frame 3.)
+	//
+	// During the execution of d2, however, the panic stack is d2 -> d3,
+	// which is inverted. The scan will match d2 to frame 2 but having
+	// d2 on the stack until then means it will not match d3 to frame 3.
+	// This is okay: if we're running d2, then all the defers after d2 have
+	// completed and their corresponding frames are dead. Not finding d3
+	// for frame 3 means we'll set frame 3's continpc == 0, which is correct
+	// (frame 3 is dead). At the end of the walk the panic stack can thus
+	// contain defers (d3 in this case) for dead frames. The inversion here
+	// always indicates a dead frame, and the effect of the inversion on the
+	// scan is to hide those dead frames, so the scan is still okay:
+	// what's left on the panic stack are exactly (and only) the dead frames.
+	//
+	// We require callback != nil here because only when callback != nil
+	// do we know that gentraceback is being called in a "must be correct"
+	// context as opposed to a "best effort" context. The tracebacks with
+	// callbacks only happen when everything is stopped nicely.
+	// At other times, such as when gathering a stack for a profiling signal
+	// or when printing a traceback during a crash, everything may not be
+	// stopped nicely, and the stack walk may not be able to complete.
+	// It's okay in those situations not to use up the entire defer stack:
+	// incomplete information then is still better than nothing.
+	if callback != nil && n < max && _defer != nil {
+		if _defer != nil {
+			print("runtime: g", gp.goid, ": leftover defer argp=", hex(_defer.argp), " pc=", hex(_defer.pc), "\n")
+		}
+		for _defer = gp._defer; _defer != nil; _defer = _defer.link {
+			print("\tdefer ", _defer, " argp=", hex(_defer.argp), " pc=", hex(_defer.pc), "\n")
+		}
+		gothrow("traceback has leftover defers")
+	}
+
+	return n
+}
+
+func setArgInfo(frame *stkframe, f *_func, needArgMap bool) {
+	frame.arglen = uintptr(f.args)
+	if needArgMap && f.args == _ArgsSizeUnknown {
+		// Extract argument bitmaps for reflect stubs from the calls they made to reflect.
+		switch gofuncname(f) {
+		case "reflect.makeFuncStub", "reflect.methodValueCall":
+			arg0 := frame.sp
+			if usesLR {
+				arg0 += ptrSize
+			}
+			fn := *(**[2]uintptr)(unsafe.Pointer(arg0))
+			if fn[0] != f.entry {
+				print("runtime: confused by ", gofuncname(f), "\n")
+				gothrow("reflect mismatch")
+			}
+			bv := (*bitvector)(unsafe.Pointer(fn[1]))
+			frame.arglen = uintptr(bv.n / 2 * ptrSize)
+			frame.argmap = bv
+		}
+	}
+}
+
+func printcreatedby(gp *g) {
+	// Show what created goroutine, except main goroutine (goid 1).
+	pc := gp.gopc
+	f := findfunc(pc)
+	if f != nil && showframe(f, gp) && gp.goid != 1 {
+		print("created by ", gofuncname(f), "\n")
+		tracepc := pc // back up to CALL instruction for funcline.
+		if pc > f.entry {
+			tracepc -= _PCQuantum
+		}
+		var file string
+		line := funcline(f, tracepc, &file)
+		print("\t", file, ":", line)
+		if pc > f.entry {
+			print(" +", hex(pc-f.entry))
+		}
+		print("\n")
+	}
+}
+
+func traceback(pc uintptr, sp uintptr, lr uintptr, gp *g) {
+	traceback1(pc, sp, lr, gp, 0)
+}
+
+// tracebacktrap is like traceback but expects that the PC and SP were obtained
+// from a trap, not from gp->sched or gp->syscallpc/gp->syscallsp or getcallerpc/getcallersp.
+// Because they are from a trap instead of from a saved pair,
+// the initial PC must not be rewound to the previous instruction.
+// (All the saved pairs record a PC that is a return address, so we
+// rewind it into the CALL instruction.)
+func tracebacktrap(pc uintptr, sp uintptr, lr uintptr, gp *g) {
+	traceback1(pc, sp, lr, gp, _TraceTrap)
+}
+
+func traceback1(pc uintptr, sp uintptr, lr uintptr, gp *g, flags uint) {
+	var n int
+	if readgstatus(gp)&^_Gscan == _Gsyscall {
+		// Override registers if blocked in system call.
+		pc = gp.syscallpc
+		sp = gp.syscallsp
+		flags &^= _TraceTrap
+	}
+	// Print traceback. By default, omits runtime frames.
+	// If that means we print nothing at all, repeat forcing all frames printed.
+	n = gentraceback(pc, sp, lr, gp, 0, nil, _TracebackMaxFrames, nil, nil, flags)
+	if n == 0 && (flags&_TraceRuntimeFrames) == 0 {
+		n = gentraceback(pc, sp, lr, gp, 0, nil, _TracebackMaxFrames, nil, nil, flags|_TraceRuntimeFrames)
+	}
+	if n == _TracebackMaxFrames {
+		print("...additional frames elided...\n")
+	}
+	printcreatedby(gp)
+}
+
+func callers(skip int, pcbuf *uintptr, m int) int {
+	sp := getcallersp(unsafe.Pointer(&skip))
+	pc := uintptr(getcallerpc(unsafe.Pointer(&skip)))
+	var n int
+	onM(func() {
+		n = gentraceback(pc, sp, 0, getg(), skip, pcbuf, m, nil, nil, 0)
+	})
+	return n
+}
+
+func gcallers(gp *g, skip int, pcbuf *uintptr, m int) int {
+	return gentraceback(^uintptr(0), ^uintptr(0), 0, gp, skip, pcbuf, m, nil, nil, 0)
+}
+
+func showframe(f *_func, gp *g) bool {
+	g := getg()
+	if g.m.throwing > 0 && gp != nil && (gp == g.m.curg || gp == g.m.caughtsig) {
+		return true
+	}
+	traceback := gotraceback(nil)
+	name := gostringnocopy(funcname(f))
+
+	// Special case: always show runtime.panic frame, so that we can
+	// see where a panic started in the middle of a stack trace.
+	// See golang.org/issue/5832.
+	if name == "runtime.panic" {
+		return true
+	}
+
+	return traceback > 1 || f != nil && contains(name, ".") && (!hasprefix(name, "runtime.") || isExportedRuntime(name))
+}
+
+// isExportedRuntime reports whether name is an exported runtime function.
+// It is only for runtime functions, so ASCII A-Z is fine.
+func isExportedRuntime(name string) bool {
+	const n = len("runtime.")
+	return len(name) > n && name[:n] == "runtime." && 'A' <= name[n] && name[n] <= 'Z'
+}
+
+var gStatusStrings = [...]string{
+	_Gidle:      "idle",
+	_Grunnable:  "runnable",
+	_Grunning:   "running",
+	_Gsyscall:   "syscall",
+	_Gwaiting:   "waiting",
+	_Gdead:      "dead",
+	_Genqueue:   "enqueue",
+	_Gcopystack: "copystack",
+}
+
+var gScanStatusStrings = [...]string{
+	0:          "scan",
+	_Grunnable: "scanrunnable",
+	_Grunning:  "scanrunning",
+	_Gsyscall:  "scansyscall",
+	_Gwaiting:  "scanwaiting",
+	_Gdead:     "scandead",
+	_Genqueue:  "scanenqueue",
+}
+
+func goroutineheader(gp *g) {
+	gpstatus := readgstatus(gp)
+
+	// Basic string status
+	var status string
+	if 0 <= gpstatus && gpstatus < uint32(len(gStatusStrings)) {
+		status = gStatusStrings[gpstatus]
+	} else if gpstatus&_Gscan != 0 && 0 <= gpstatus&^_Gscan && gpstatus&^_Gscan < uint32(len(gStatusStrings)) {
+		status = gStatusStrings[gpstatus&^_Gscan]
+	} else {
+		status = "???"
+	}
+
+	// Override.
+	if (gpstatus == _Gwaiting || gpstatus == _Gscanwaiting) && gp.waitreason != "" {
+		status = gp.waitreason
+	}
+
+	// approx time the G is blocked, in minutes
+	var waitfor int64
+	gpstatus &^= _Gscan // drop the scan bit
+	if (gpstatus == _Gwaiting || gpstatus == _Gsyscall) && gp.waitsince != 0 {
+		waitfor = (nanotime() - gp.waitsince) / 60e9
+	}
+	print("goroutine ", gp.goid, " [", status)
+	if waitfor >= 1 {
+		print(", ", waitfor, " minutes")
+	}
+	if gp.lockedm != nil {
+		print(", locked to thread")
+	}
+	print("]:\n")
+}
+
+func tracebackothers(me *g) {
+	level := gotraceback(nil)
+
+	// Show the current goroutine first, if we haven't already.
+	g := getg()
+	gp := g.m.curg
+	if gp != nil && gp != me {
+		print("\n")
+		goroutineheader(gp)
+		traceback(^uintptr(0), ^uintptr(0), 0, gp)
+	}
+
+	lock(&allglock)
+	for _, gp := range allgs {
+		if gp == me || gp == g.m.curg || readgstatus(gp) == _Gdead || gp.issystem && level < 2 {
+			continue
+		}
+		print("\n")
+		goroutineheader(gp)
+		if readgstatus(gp)&^_Gscan == _Grunning {
+			print("\tgoroutine running on other thread; stack unavailable\n")
+			printcreatedby(gp)
+		} else {
+			traceback(^uintptr(0), ^uintptr(0), 0, gp)
+		}
+	}
+	unlock(&allglock)
+}
+
+// Does f mark the top of a goroutine stack?
+func topofstack(f *_func) bool {
+	pc := f.entry
+	return pc == goexitPC ||
+		pc == mstartPC ||
+		pc == mcallPC ||
+		pc == morestackPC ||
+		pc == rt0_goPC ||
+		externalthreadhandlerp != 0 && pc == externalthreadhandlerp
+}
diff --git a/src/runtime/type.h b/src/runtime/type.h
new file mode 100644
index 0000000..f5b4f9d
--- /dev/null
+++ b/src/runtime/type.h
@@ -0,0 +1,113 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Runtime type representation.
+
+typedef struct Type Type;
+typedef struct UncommonType UncommonType;
+typedef struct InterfaceType InterfaceType;
+typedef struct Method Method;
+typedef struct IMethod IMethod;
+typedef struct SliceType SliceType;
+typedef struct FuncType FuncType;
+
+// Needs to be in sync with ../../cmd/ld/decodesym.c:/^commonsize and pkg/reflect/type.go:/type.
+struct Type
+{
+	uintptr size;
+	uint32 hash;
+	uint8 _unused;
+	uint8 align;
+	uint8 fieldAlign;
+	uint8 kind;
+	void* alg;
+	// gc stores type info required for garbage collector.
+	// If (kind&KindGCProg)==0, then gc[0] points at sparse GC bitmap
+	// (no indirection), 4 bits per word.
+	// If (kind&KindGCProg)!=0, then gc[1] points to a compiler-generated
+	// read-only GC program; and gc[0] points to BSS space for sparse GC bitmap.
+	// For huge types (>MaxGCMask), runtime unrolls the program directly into
+	// GC bitmap and gc[0] is not used. For moderately-sized types, runtime
+	// unrolls the program into gc[0] space on first use. The first byte of gc[0]
+	// (gc[0][0]) contains 'unroll' flag saying whether the program is already
+	// unrolled into gc[0] or not.
+	uintptr gc[2];
+	String *string;
+	UncommonType *x;
+	Type *ptrto;
+	byte *zero;  // ptr to the zero value for this type
+};
+
+struct Method
+{
+	String *name;
+	String *pkgPath;
+	Type	*mtyp;
+	Type *typ;
+	void (*ifn)(void);
+	void (*tfn)(void);
+};
+
+struct UncommonType
+{
+	String *name;
+	String *pkgPath;
+	Slice mhdr;
+	Method m[];
+};
+
+struct IMethod
+{
+	String *name;
+	String *pkgPath;
+	Type *type;
+};
+
+struct InterfaceType
+{
+	Type  typ;
+	Slice mhdr;
+	IMethod m[];
+};
+
+struct MapType
+{
+	Type typ;
+	Type *key;
+	Type *elem;
+	Type *bucket;		// internal type representing a hash bucket
+	Type *hmap;		// internal type representing a Hmap
+	uint8 keysize;		// size of key slot
+	bool indirectkey;	// store ptr to key instead of key itself
+	uint8 valuesize;	// size of value slot
+	bool indirectvalue;	// store ptr to value instead of value itself
+	uint16 bucketsize;	// size of bucket
+};
+
+struct ChanType
+{
+	Type typ;
+	Type *elem;
+	uintptr dir;
+};
+
+struct SliceType
+{
+	Type typ;
+	Type *elem;
+};
+
+struct FuncType
+{
+	Type typ;
+	bool dotdotdot;
+	Slice in;
+	Slice out;
+};
+
+struct PtrType
+{
+	Type typ;
+	Type *elem;
+};
diff --git a/src/runtime/typekind.go b/src/runtime/typekind.go
new file mode 100644
index 0000000..b64ec44
--- /dev/null
+++ b/src/runtime/typekind.go
@@ -0,0 +1,44 @@
+// 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 runtime
+
+const (
+	kindBool          = _KindBool
+	kindInt           = _KindInt
+	kindInt8          = _KindInt8
+	kindInt16         = _KindInt16
+	kindInt32         = _KindInt32
+	kindInt64         = _KindInt64
+	kindUint          = _KindUint
+	kindUint8         = _KindUint8
+	kindUint16        = _KindUint16
+	kindUint32        = _KindUint32
+	kindUint64        = _KindUint64
+	kindUintptr       = _KindUintptr
+	kindFloat32       = _KindFloat32
+	kindFloat64       = _KindFloat64
+	kindComplex64     = _KindComplex64
+	kindComplex128    = _KindComplex128
+	kindArray         = _KindArray
+	kindChan          = _KindChan
+	kindFunc          = _KindFunc
+	kindInterface     = _KindInterface
+	kindMap           = _KindMap
+	kindPtr           = _KindPtr
+	kindSlice         = _KindSlice
+	kindString        = _KindString
+	kindStruct        = _KindStruct
+	kindUnsafePointer = _KindUnsafePointer
+
+	kindDirectIface = _KindDirectIface
+	kindGCProg      = _KindGCProg
+	kindNoPointers  = _KindNoPointers
+	kindMask        = _KindMask
+)
+
+// isDirectIface reports whether t is stored directly in an interface value.
+func isDirectIface(t *_type) bool {
+	return t.kind&kindDirectIface != 0
+}
diff --git a/src/runtime/typekind.h b/src/runtime/typekind.h
new file mode 100644
index 0000000..e0fe177
--- /dev/null
+++ b/src/runtime/typekind.h
@@ -0,0 +1,38 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+enum {
+	KindBool = 1,
+	KindInt,
+	KindInt8,
+	KindInt16,
+	KindInt32,
+	KindInt64,
+	KindUint,
+	KindUint8,
+	KindUint16,
+	KindUint32,
+	KindUint64,
+	KindUintptr,
+	KindFloat32,
+	KindFloat64,
+	KindComplex64,
+	KindComplex128,
+	KindArray,
+	KindChan,
+	KindFunc,
+	KindInterface,
+	KindMap,
+	KindPtr,
+	KindSlice,
+	KindString,
+	KindStruct,
+	KindUnsafePointer,
+
+	KindDirectIface = 1<<5,
+	KindGCProg = 1<<6,	// Type.gc points to GC program
+	KindNoPointers = 1<<7,
+	KindMask = (1<<5)-1,
+};
+
diff --git a/src/runtime/vdso_linux_amd64.c b/src/runtime/vdso_linux_amd64.c
new file mode 100644
index 0000000..681340c
--- /dev/null
+++ b/src/runtime/vdso_linux_amd64.c
@@ -0,0 +1,371 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "runtime.h"
+#include "textflag.h"
+
+// Look up symbols in the Linux vDSO.
+
+// This code was originally based on the sample Linux vDSO parser at
+// https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/vDSO/parse_vdso.c
+
+// This implements the ELF dynamic linking spec at
+// http://sco.com/developers/gabi/latest/ch5.dynamic.html
+
+// The version section is documented at
+// http://refspecs.linuxfoundation.org/LSB_3.2.0/LSB-Core-generic/LSB-Core-generic/symversion.html
+
+#define AT_RANDOM 25
+#define AT_SYSINFO_EHDR 33
+#define AT_NULL	0    /* End of vector */
+#define PT_LOAD	1    /* Loadable program segment */
+#define PT_DYNAMIC 2 /* Dynamic linking information */
+#define DT_NULL 0    /* Marks end of dynamic section */
+#define DT_HASH 4    /* Dynamic symbol hash table */
+#define DT_STRTAB 5  /* Address of string table */
+#define DT_SYMTAB 6  /* Address of symbol table */
+#define DT_VERSYM 0x6ffffff0
+#define	DT_VERDEF 0x6ffffffc
+
+#define VER_FLG_BASE 0x1 /* Version definition of file itself */
+#define SHN_UNDEF 0      /* Undefined section */
+#define SHT_DYNSYM 11    /* Dynamic linker symbol table */
+#define STT_FUNC 2       /* Symbol is a code object */
+#define STB_GLOBAL 1     /* Global symbol */
+#define STB_WEAK 2       /* Weak symbol */
+
+/* How to extract and insert information held in the st_info field.  */
+#define ELF64_ST_BIND(val) (((byte) (val)) >> 4)
+#define ELF64_ST_TYPE(val) ((val) & 0xf)
+
+#define EI_NIDENT (16)
+
+typedef uint16 Elf64_Half;
+typedef uint32 Elf64_Word;
+typedef	int32  Elf64_Sword;
+typedef uint64 Elf64_Xword;
+typedef	int64  Elf64_Sxword;
+typedef uint64 Elf64_Addr;
+typedef uint64 Elf64_Off;
+typedef uint16 Elf64_Section;
+typedef Elf64_Half Elf64_Versym;
+
+
+typedef struct Elf64_Sym
+{
+	Elf64_Word st_name;
+	byte st_info;
+	byte st_other;
+	Elf64_Section st_shndx;
+	Elf64_Addr st_value;
+	Elf64_Xword st_size;
+} Elf64_Sym;
+
+typedef struct Elf64_Verdef
+{
+	Elf64_Half vd_version; /* Version revision */
+	Elf64_Half vd_flags;   /* Version information */
+	Elf64_Half vd_ndx;     /* Version Index */
+	Elf64_Half vd_cnt;     /* Number of associated aux entries */
+	Elf64_Word vd_hash;    /* Version name hash value */
+	Elf64_Word vd_aux;     /* Offset in bytes to verdaux array */
+	Elf64_Word vd_next;    /* Offset in bytes to next verdef entry */
+} Elf64_Verdef;
+
+typedef struct Elf64_Ehdr
+{
+	byte e_ident[EI_NIDENT]; /* Magic number and other info */
+	Elf64_Half e_type;       /* Object file type */
+	Elf64_Half e_machine;    /* Architecture */
+	Elf64_Word e_version;    /* Object file version */
+	Elf64_Addr e_entry;      /* Entry point virtual address */
+	Elf64_Off e_phoff;       /* Program header table file offset */
+	Elf64_Off e_shoff;       /* Section header table file offset */
+	Elf64_Word e_flags;      /* Processor-specific flags */
+	Elf64_Half e_ehsize;     /* ELF header size in bytes */
+	Elf64_Half e_phentsize;  /* Program header table entry size */
+	Elf64_Half e_phnum;      /* Program header table entry count */
+	Elf64_Half e_shentsize;  /* Section header table entry size */
+	Elf64_Half e_shnum;      /* Section header table entry count */
+	Elf64_Half e_shstrndx;   /* Section header string table index */
+} Elf64_Ehdr;
+
+typedef struct Elf64_Phdr
+{
+	Elf64_Word p_type;    /* Segment type */
+	Elf64_Word p_flags;   /* Segment flags */
+	Elf64_Off p_offset;   /* Segment file offset */
+	Elf64_Addr p_vaddr;   /* Segment virtual address */
+	Elf64_Addr p_paddr;   /* Segment physical address */
+	Elf64_Xword p_filesz; /* Segment size in file */
+	Elf64_Xword p_memsz;  /* Segment size in memory */
+	Elf64_Xword p_align;  /* Segment alignment */
+} Elf64_Phdr;
+
+typedef struct Elf64_Shdr
+{
+	Elf64_Word sh_name;       /* Section name (string tbl index) */
+	Elf64_Word sh_type;       /* Section type */
+	Elf64_Xword sh_flags;     /* Section flags */
+	Elf64_Addr sh_addr;       /* Section virtual addr at execution */
+	Elf64_Off sh_offset;      /* Section file offset */
+	Elf64_Xword sh_size;      /* Section size in bytes */
+	Elf64_Word sh_link;       /* Link to another section */
+	Elf64_Word sh_info;       /* Additional section information */
+	Elf64_Xword sh_addralign; /* Section alignment */
+	Elf64_Xword sh_entsize;   /* Entry size if section holds table */
+} Elf64_Shdr;
+
+typedef struct Elf64_Dyn
+{
+	Elf64_Sxword d_tag; /* Dynamic entry type */
+	union
+	{
+		Elf64_Xword d_val;  /* Integer value */
+		Elf64_Addr d_ptr;   /* Address value */
+	} d_un;
+} Elf64_Dyn;
+
+typedef struct Elf64_Verdaux
+{
+	Elf64_Word vda_name; /* Version or dependency names */
+	Elf64_Word vda_next; /* Offset in bytes to next verdaux entry */
+} Elf64_Verdaux;
+
+typedef struct Elf64_auxv_t
+{
+	uint64 a_type;        /* Entry type */
+	union
+	{
+		uint64 a_val; /* Integer value */
+	} a_un;
+} Elf64_auxv_t;
+
+
+typedef struct symbol_key {
+	byte* name;
+	int32 sym_hash;
+	void** var_ptr;
+} symbol_key;
+
+typedef struct version_key {
+	byte* version;
+	int32 ver_hash;
+} version_key;
+
+struct vdso_info {
+	bool valid;
+
+	/* Load information */
+	uintptr load_addr;
+	uintptr load_offset;  /* load_addr - recorded vaddr */
+
+	/* Symbol table */
+	Elf64_Sym *symtab;
+	const byte *symstrings;
+	Elf64_Word *bucket, *chain;
+	Elf64_Word nbucket, nchain;
+
+	/* Version table */
+	Elf64_Versym *versym;
+	Elf64_Verdef *verdef;
+};
+
+#pragma dataflag NOPTR
+static version_key linux26 = { (byte*)"LINUX_2.6", 0x3ae75f6 };
+
+// initialize with vsyscall fallbacks
+#pragma dataflag NOPTR
+void* runtime·__vdso_time_sym = (void*)0xffffffffff600400ULL;
+#pragma dataflag NOPTR
+void* runtime·__vdso_gettimeofday_sym = (void*)0xffffffffff600000ULL;
+#pragma dataflag NOPTR
+void* runtime·__vdso_clock_gettime_sym = (void*)0;
+
+#pragma dataflag NOPTR
+static symbol_key sym_keys[] = {
+	{ (byte*)"__vdso_time", 0xa33c485, &runtime·__vdso_time_sym },
+	{ (byte*)"__vdso_gettimeofday", 0x315ca59, &runtime·__vdso_gettimeofday_sym },
+	{ (byte*)"__vdso_clock_gettime", 0xd35ec75, &runtime·__vdso_clock_gettime_sym },
+};
+
+static void
+vdso_init_from_sysinfo_ehdr(struct vdso_info *vdso_info, Elf64_Ehdr* hdr)
+{
+	uint64 i;
+	bool found_vaddr = false;
+	Elf64_Phdr *pt;
+	Elf64_Dyn *dyn;
+	Elf64_Word *hash;
+
+	vdso_info->valid = false;
+	vdso_info->load_addr = (uintptr) hdr;
+
+	pt = (Elf64_Phdr*)(vdso_info->load_addr + hdr->e_phoff);
+	dyn = nil;
+
+	// We need two things from the segment table: the load offset
+	// and the dynamic table.
+	for(i=0; i<hdr->e_phnum; i++) {
+		if(pt[i].p_type == PT_LOAD && found_vaddr == false) {
+			found_vaddr = true;
+			vdso_info->load_offset =	(uintptr)hdr
+				+ (uintptr)pt[i].p_offset
+				- (uintptr)pt[i].p_vaddr;
+		} else if(pt[i].p_type == PT_DYNAMIC) {
+			dyn = (Elf64_Dyn*)((uintptr)hdr + pt[i].p_offset);
+		}
+	}
+
+	if(found_vaddr == false || dyn == nil)
+		return;  // Failed
+
+	// Fish out the useful bits of the dynamic table.
+	hash = nil;
+	vdso_info->symstrings = nil;
+	vdso_info->symtab = nil;
+	vdso_info->versym = nil;
+	vdso_info->verdef = nil;
+	for(i=0; dyn[i].d_tag!=DT_NULL; i++) {
+		switch(dyn[i].d_tag) {
+		case DT_STRTAB:
+			vdso_info->symstrings = (const byte *)
+				((uintptr)dyn[i].d_un.d_ptr
+				 + vdso_info->load_offset);
+			break;
+		case DT_SYMTAB:
+			vdso_info->symtab = (Elf64_Sym *)
+				((uintptr)dyn[i].d_un.d_ptr
+				 + vdso_info->load_offset);
+			break;
+		case DT_HASH:
+			hash = (Elf64_Word *)
+			  ((uintptr)dyn[i].d_un.d_ptr
+			   + vdso_info->load_offset);
+			break;
+		case DT_VERSYM:
+			vdso_info->versym = (Elf64_Versym *)
+				((uintptr)dyn[i].d_un.d_ptr
+				 + vdso_info->load_offset);
+			break;
+		case DT_VERDEF:
+			vdso_info->verdef = (Elf64_Verdef *)
+				((uintptr)dyn[i].d_un.d_ptr
+				 + vdso_info->load_offset);
+			break;
+		}
+	}
+	if(vdso_info->symstrings == nil || vdso_info->symtab == nil || hash == nil)
+		return;  // Failed
+
+	if(vdso_info->verdef == nil)
+		vdso_info->versym = 0;
+
+	// Parse the hash table header.
+	vdso_info->nbucket = hash[0];
+	vdso_info->nchain = hash[1];
+	vdso_info->bucket = &hash[2];
+	vdso_info->chain = &hash[vdso_info->nbucket + 2];
+
+	// That's all we need.
+	vdso_info->valid = true;
+}
+
+static int32
+vdso_find_version(struct vdso_info *vdso_info, version_key* ver)
+{
+	if(vdso_info->valid == false) {
+		return 0;
+	}
+	Elf64_Verdef *def = vdso_info->verdef;
+	while(true) {
+		if((def->vd_flags & VER_FLG_BASE) == 0) {
+			Elf64_Verdaux *aux = (Elf64_Verdaux*)((byte *)def + def->vd_aux);
+			if(def->vd_hash == ver->ver_hash &&
+				runtime·strcmp(ver->version, vdso_info->symstrings + aux->vda_name) == 0) {
+				return def->vd_ndx & 0x7fff;
+			}
+		}
+
+		if(def->vd_next == 0) {
+			break;
+		}
+		def = (Elf64_Verdef *)((byte *)def + def->vd_next);
+	}
+	return -1; // can not match any version
+}
+
+static void
+vdso_parse_symbols(struct vdso_info *vdso_info, int32 version)
+{
+	int32 i;
+	Elf64_Word chain;
+	Elf64_Sym *sym;
+
+	if(vdso_info->valid == false)
+		return;
+
+	for(i=0; i<nelem(sym_keys); i++) {
+		for(chain = vdso_info->bucket[sym_keys[i].sym_hash % vdso_info->nbucket];
+			chain != 0; chain = vdso_info->chain[chain]) {
+
+			sym = &vdso_info->symtab[chain];
+			if(ELF64_ST_TYPE(sym->st_info) != STT_FUNC)
+				continue;
+			if(ELF64_ST_BIND(sym->st_info) != STB_GLOBAL &&
+				 ELF64_ST_BIND(sym->st_info) != STB_WEAK)
+				continue;
+			if(sym->st_shndx == SHN_UNDEF)
+				continue;
+			if(runtime·strcmp(sym_keys[i].name, vdso_info->symstrings + sym->st_name) != 0)
+				continue;
+
+			// Check symbol version.
+			if(vdso_info->versym != nil && version != 0
+				&& vdso_info->versym[chain] & 0x7fff != version)
+				continue;
+
+			*sym_keys[i].var_ptr = (void *)(vdso_info->load_offset + sym->st_value);
+			break;
+		}
+	}
+}
+
+static void
+runtime·linux_setup_vdso(int32 argc, uint8** argv)
+{
+	struct vdso_info vdso_info;
+
+	// skip argvc
+	byte **p = argv;
+	p = &p[argc+1];
+
+	// skip envp to get to ELF auxiliary vector.
+	for(; *p!=0; p++) {}
+
+	// skip NULL separator
+	p++;
+
+	// now, p points to auxv
+	Elf64_auxv_t *elf_auxv = (Elf64_auxv_t*) p;
+
+	for(int32 i=0; elf_auxv[i].a_type!=AT_NULL; i++) {
+		if(elf_auxv[i].a_type == AT_SYSINFO_EHDR) {
+			if(elf_auxv[i].a_un.a_val == 0) {
+				// Something went wrong
+				continue;
+			}
+			vdso_init_from_sysinfo_ehdr(&vdso_info, (Elf64_Ehdr*)elf_auxv[i].a_un.a_val);
+			vdso_parse_symbols(&vdso_info, vdso_find_version(&vdso_info, &linux26));
+			continue;
+		}
+		if(elf_auxv[i].a_type == AT_RANDOM) {
+		        runtime·startup_random_data = (byte*)elf_auxv[i].a_un.a_val;
+		        runtime·startup_random_data_len = 16;
+			continue;
+		}
+	}
+}
+
+void (*runtime·sysargs)(int32, uint8**) = runtime·linux_setup_vdso;
diff --git a/src/runtime/vlop_386.s b/src/runtime/vlop_386.s
new file mode 100644
index 0000000..ce8e7d0
--- /dev/null
+++ b/src/runtime/vlop_386.s
@@ -0,0 +1,56 @@
+// Inferno's libkern/vlop-386.s
+// http://code.google.com/p/inferno-os/source/browse/libkern/vlop-386.s
+//
+//         Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
+//         Revisions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com).  All rights reserved.
+//         Portions Copyright 2009 The Go Authors. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#include "textflag.h"
+
+/*
+ * C runtime for 64-bit divide.
+ */
+
+// runtime·_mul64x32(r *uint64, a uint64, b uint32) uint32
+// sets *r = low 64 bits of 96-bit product a*b; returns high 32 bits.
+TEXT runtime·_mul64by32(SB), NOSPLIT, $0
+	MOVL	r+0(FP), CX
+	MOVL	a+4(FP), AX
+	MULL	b+12(FP)
+	MOVL	AX, 0(CX)
+	MOVL	DX, BX
+	MOVL	a+8(FP), AX
+	MULL	b+12(FP)
+	ADDL	AX, BX
+	ADCL	$0, DX
+	MOVL	BX, 4(CX)
+	MOVL	DX, AX
+	MOVL	AX, ret+16(FP)
+	RET
+
+TEXT runtime·_div64by32(SB), NOSPLIT, $0
+	MOVL	r+12(FP), CX
+	MOVL	a+0(FP), AX
+	MOVL	a+4(FP), DX
+	DIVL	b+8(FP)
+	MOVL	DX, 0(CX)
+	MOVL	AX, ret+16(FP)
+	RET
diff --git a/src/runtime/vlop_arm.s b/src/runtime/vlop_arm.s
new file mode 100644
index 0000000..b4b905b
--- /dev/null
+++ b/src/runtime/vlop_arm.s
@@ -0,0 +1,317 @@
+// Inferno's libkern/vlop-arm.s
+// http://code.google.com/p/inferno-os/source/browse/libkern/vlop-arm.s
+//
+//         Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
+//         Revisions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com).  All rights reserved.
+//         Portions Copyright 2009 The Go Authors. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#include "zasm_GOOS_GOARCH.h"
+#include "textflag.h"
+
+arg=0
+
+/* replaced use of R10 by R11 because the former can be the data segment base register */
+
+TEXT _mulv(SB), NOSPLIT, $0
+	MOVW	l0+0(FP), R2	/* l0 */
+	MOVW	h0+4(FP), R11	/* h0 */
+	MOVW	l1+8(FP), R4	/* l1 */
+	MOVW	h1+12(FP), R5	/* h1 */
+	MULLU	R4, R2, (R7,R6)
+	MUL	R11, R4, R8
+	ADD	R8, R7
+	MUL	R2, R5, R8
+	ADD	R8, R7
+	MOVW	R6, ret_lo+16(FP)
+	MOVW	R7, ret_hi+20(FP)
+	RET
+
+// trampoline for _sfloat2. passes LR as arg0 and
+// saves registers R0-R13 and CPSR on the stack. R0-R12 and CPSR flags can
+// be changed by _sfloat2.
+TEXT _sfloat(SB), NOSPLIT, $68-0 // 4 arg + 14*4 saved regs + cpsr + return value
+	MOVW	R14, 4(R13)
+	MOVW	R0, 8(R13)
+	MOVW	$12(R13), R0
+	MOVM.IA.W	[R1-R12], (R0)
+	MOVW	$72(R13), R1 // correct for frame size
+	MOVW	R1, 60(R13)
+	WORD	$0xe10f1000 // mrs r1, cpsr
+	MOVW	R1, 64(R13)
+	// Disable preemption of this goroutine during _sfloat2 by
+	// m->locks++ and m->locks-- around the call.
+	// Rescheduling this goroutine may cause the loss of the
+	// contents of the software floating point registers in 
+	// m->freghi, m->freglo, m->fflag, if the goroutine is moved
+	// to a different m or another goroutine runs on this m.
+	// Rescheduling at ordinary function calls is okay because
+	// all registers are caller save, but _sfloat2 and the things
+	// that it runs are simulating the execution of individual
+	// program instructions, and those instructions do not expect
+	// the floating point registers to be lost.
+	// An alternative would be to move the software floating point
+	// registers into G, but they do not need to be kept at the 
+	// usual places a goroutine reschedules (at function calls),
+	// so it would be a waste of 132 bytes per G.
+	MOVW	g_m(g), R8
+	MOVW	m_locks(R8), R1
+	ADD	$1, R1
+	MOVW	R1, m_locks(R8)
+	MOVW	$1, R1
+	MOVW	R1, m_softfloat(R8)
+	BL	runtime·_sfloat2(SB)
+	MOVW	68(R13), R0
+	MOVW	g_m(g), R8
+	MOVW	m_locks(R8), R1
+	SUB	$1, R1
+	MOVW	R1, m_locks(R8)
+	MOVW	$0, R1
+	MOVW	R1, m_softfloat(R8)
+	MOVW	R0, 0(R13)
+	MOVW	64(R13), R1
+	WORD	$0xe128f001	// msr cpsr_f, r1
+	MOVW	$12(R13), R0
+	// Restore R1-R12, R0.
+	MOVM.IA.W	(R0), [R1-R12]
+	MOVW	8(R13), R0
+	RET
+
+// trampoline for _sfloat2 panic.
+// _sfloat2 instructs _sfloat to return here.
+// We need to push a fake saved LR onto the stack,
+// load the signal fault address into LR, and jump
+// to the real sigpanic.
+// This simulates what sighandler does for a memory fault.
+TEXT _sfloatpanic(SB),NOSPLIT,$-4
+	MOVW	$0, R0
+	MOVW.W	R0, -4(R13)
+	MOVW	g_sigpc(g), LR
+	B	runtime·sigpanic(SB)
+
+// func udiv(n, d uint32) (q, r uint32)
+// Reference: 
+// Sloss, Andrew et. al; ARM System Developer's Guide: Designing and Optimizing System Software
+// Morgan Kaufmann; 1 edition (April 8, 2004), ISBN 978-1558608740
+q = 0 // input d, output q
+r = 1 // input n, output r
+s = 2 // three temporary variables
+M = 3
+a = 11
+// Be careful: R(a) == R11 will be used by the linker for synthesized instructions.
+TEXT udiv<>(SB),NOSPLIT,$-4
+	CLZ 	R(q), R(s) // find normalizing shift
+	MOVW.S	R(q)<<R(s), R(a)
+	MOVW	$fast_udiv_tab<>-64(SB), R(M)
+	ADD.NE	R(a)>>25, R(M), R(a) // index by most significant 7 bits of divisor
+	MOVBU.NE	(R(a)), R(a)
+
+	SUB.S	$7, R(s)
+	RSB 	$0, R(q), R(M) // M = -q
+	MOVW.PL	R(a)<<R(s), R(q)
+
+	// 1st Newton iteration
+	MUL.PL	R(M), R(q), R(a) // a = -q*d
+	BMI 	udiv_by_large_d
+	MULAWT	R(a), R(q), R(q), R(q) // q approx q-(q*q*d>>32)
+	TEQ 	R(M)->1, R(M) // check for d=0 or d=1
+
+	// 2nd Newton iteration
+	MUL.NE	R(M), R(q), R(a)
+	MOVW.NE	$0, R(s)
+	MULAL.NE R(q), R(a), (R(q),R(s))
+	BEQ 	udiv_by_0_or_1
+
+	// q now accurate enough for a remainder r, 0<=r<3*d
+	MULLU	R(q), R(r), (R(q),R(s)) // q = (r * q) >> 32	
+	ADD 	R(M), R(r), R(r) // r = n - d
+	MULA	R(M), R(q), R(r), R(r) // r = n - (q+1)*d
+
+	// since 0 <= n-q*d < 3*d; thus -d <= r < 2*d
+	CMN 	R(M), R(r) // t = r-d
+	SUB.CS	R(M), R(r), R(r) // if (t<-d || t>=0) r=r+d
+	ADD.CC	$1, R(q)
+	ADD.PL	R(M)<<1, R(r)
+	ADD.PL	$2, R(q)
+	RET
+
+udiv_by_large_d:
+	// at this point we know d>=2^(31-6)=2^25
+	SUB 	$4, R(a), R(a)
+	RSB 	$0, R(s), R(s)
+	MOVW	R(a)>>R(s), R(q)
+	MULLU	R(q), R(r), (R(q),R(s))
+	MULA	R(M), R(q), R(r), R(r)
+
+	// q now accurate enough for a remainder r, 0<=r<4*d
+	CMN 	R(r)>>1, R(M) // if(r/2 >= d)
+	ADD.CS	R(M)<<1, R(r)
+	ADD.CS	$2, R(q)
+	CMN 	R(r), R(M)
+	ADD.CS	R(M), R(r)
+	ADD.CS	$1, R(q)
+	RET
+
+udiv_by_0_or_1:
+	// carry set if d==1, carry clear if d==0
+	BCC udiv_by_0
+	MOVW	R(r), R(q)
+	MOVW	$0, R(r)
+	RET
+
+udiv_by_0:
+	// The ARM toolchain expects it can emit references to DIV and MOD
+	// instructions. The linker rewrites each pseudo-instruction into
+	// a sequence that pushes two values onto the stack and then calls
+	// _divu, _modu, _div, or _mod (below), all of which have a 16-byte
+	// frame plus the saved LR. The traceback routine knows the expanded
+	// stack frame size at the pseudo-instruction call site, but it
+	// doesn't know that the frame has a non-standard layout. In particular,
+	// it expects to find a saved LR in the bottom word of the frame.
+	// Unwind the stack back to the pseudo-instruction call site, copy the
+	// saved LR where the traceback routine will look for it, and make it
+	// appear that panicdivide was called from that PC.
+	MOVW	0(R13), LR
+	ADD	$20, R13
+	MOVW	8(R13), R1 // actual saved LR
+	MOVW	R1, 0(R13) // expected here for traceback
+	B 	runtime·panicdivide(SB)
+
+// var tab [64]byte
+// tab[0] = 255; for i := 1; i <= 63; i++ { tab[i] = (1<<14)/(64+i) }
+// laid out here as little-endian uint32s
+DATA fast_udiv_tab<>+0x00(SB)/4, $0xf4f8fcff
+DATA fast_udiv_tab<>+0x04(SB)/4, $0xe6eaedf0
+DATA fast_udiv_tab<>+0x08(SB)/4, $0xdadde0e3
+DATA fast_udiv_tab<>+0x0c(SB)/4, $0xcfd2d4d7
+DATA fast_udiv_tab<>+0x10(SB)/4, $0xc5c7cacc
+DATA fast_udiv_tab<>+0x14(SB)/4, $0xbcbec0c3
+DATA fast_udiv_tab<>+0x18(SB)/4, $0xb4b6b8ba
+DATA fast_udiv_tab<>+0x1c(SB)/4, $0xacaeb0b2
+DATA fast_udiv_tab<>+0x20(SB)/4, $0xa5a7a8aa
+DATA fast_udiv_tab<>+0x24(SB)/4, $0x9fa0a2a3
+DATA fast_udiv_tab<>+0x28(SB)/4, $0x999a9c9d
+DATA fast_udiv_tab<>+0x2c(SB)/4, $0x93949697
+DATA fast_udiv_tab<>+0x30(SB)/4, $0x8e8f9092
+DATA fast_udiv_tab<>+0x34(SB)/4, $0x898a8c8d
+DATA fast_udiv_tab<>+0x38(SB)/4, $0x85868788
+DATA fast_udiv_tab<>+0x3c(SB)/4, $0x81828384
+GLOBL fast_udiv_tab<>(SB), RODATA, $64
+
+// The linker will pass numerator in R(TMP), and it also
+// expects the result in R(TMP)
+TMP = 11
+
+TEXT _divu(SB), NOSPLIT, $16
+	MOVW	R(q), 4(R13)
+	MOVW	R(r), 8(R13)
+	MOVW	R(s), 12(R13)
+	MOVW	R(M), 16(R13)
+
+	MOVW	R(TMP), R(r)		/* numerator */
+	MOVW	0(FP), R(q) 		/* denominator */
+	BL  	udiv<>(SB)
+	MOVW	R(q), R(TMP)
+	MOVW	4(R13), R(q)
+	MOVW	8(R13), R(r)
+	MOVW	12(R13), R(s)
+	MOVW	16(R13), R(M)
+	RET
+
+TEXT _modu(SB), NOSPLIT, $16
+	MOVW	R(q), 4(R13)
+	MOVW	R(r), 8(R13)
+	MOVW	R(s), 12(R13)
+	MOVW	R(M), 16(R13)
+
+	MOVW	R(TMP), R(r)		/* numerator */
+	MOVW	0(FP), R(q) 		/* denominator */
+	BL  	udiv<>(SB)
+	MOVW	R(r), R(TMP)
+	MOVW	4(R13), R(q)
+	MOVW	8(R13), R(r)
+	MOVW	12(R13), R(s)
+	MOVW	16(R13), R(M)
+	RET
+
+TEXT _div(SB),NOSPLIT,$16
+	MOVW	R(q), 4(R13)
+	MOVW	R(r), 8(R13)
+	MOVW	R(s), 12(R13)
+	MOVW	R(M), 16(R13)
+	MOVW	R(TMP), R(r)		/* numerator */
+	MOVW	0(FP), R(q) 		/* denominator */
+	CMP 	$0, R(r)
+	BGE 	d1
+	RSB 	$0, R(r), R(r)
+	CMP 	$0, R(q)
+	BGE 	d2
+	RSB 	$0, R(q), R(q)
+d0:
+	BL  	udiv<>(SB)  		/* none/both neg */
+	MOVW	R(q), R(TMP)
+	B		out1
+d1:
+	CMP 	$0, R(q)
+	BGE 	d0
+	RSB 	$0, R(q), R(q)
+d2:
+	BL  	udiv<>(SB)  		/* one neg */
+	RSB		$0, R(q), R(TMP)
+out1:
+	MOVW	4(R13), R(q)
+	MOVW	8(R13), R(r)
+	MOVW	12(R13), R(s)
+	MOVW	16(R13), R(M)
+	RET
+
+TEXT _mod(SB),NOSPLIT,$16
+	MOVW	R(q), 4(R13)
+	MOVW	R(r), 8(R13)
+	MOVW	R(s), 12(R13)
+	MOVW	R(M), 16(R13)
+	MOVW	R(TMP), R(r)		/* numerator */
+	MOVW	0(FP), R(q) 		/* denominator */
+	CMP 	$0, R(q)
+	RSB.LT	$0, R(q), R(q)
+	CMP 	$0, R(r)
+	BGE 	m1
+	RSB 	$0, R(r), R(r)
+	BL  	udiv<>(SB)  		/* neg numerator */
+	RSB 	$0, R(r), R(TMP)
+	B   	out
+m1:
+	BL  	udiv<>(SB)  		/* pos numerator */
+	MOVW	R(r), R(TMP)
+out:
+	MOVW	4(R13), R(q)
+	MOVW	8(R13), R(r)
+	MOVW	12(R13), R(s)
+	MOVW	16(R13), R(M)
+	RET
+
+// _mul64by32 and _div64by32 not implemented on arm
+TEXT runtime·_mul64by32(SB), NOSPLIT, $0
+	MOVW	$0, R0
+	MOVW	(R0), R1 // crash
+
+TEXT runtime·_div64by32(SB), NOSPLIT, $0
+	MOVW	$0, R0
+	MOVW	(R0), R1 // crash
diff --git a/src/pkg/runtime/vlop_arm_test.go b/src/runtime/vlop_arm_test.go
similarity index 100%
rename from src/pkg/runtime/vlop_arm_test.go
rename to src/runtime/vlop_arm_test.go
diff --git a/src/runtime/vlrt.c b/src/runtime/vlrt.c
new file mode 100644
index 0000000..cb0d147
--- /dev/null
+++ b/src/runtime/vlrt.c
@@ -0,0 +1,914 @@
+// Inferno's libkern/vlrt-386.c
+// http://code.google.com/p/inferno-os/source/browse/libkern/vlrt-386.c
+//
+//         Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
+//         Revisions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com).  All rights reserved.
+//         Portions Copyright 2009 The Go Authors. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+// +build arm 386
+
+#include "textflag.h"
+
+/*
+ * C runtime for 64-bit divide, others.
+ *
+ * TODO(rsc): The simple functions are dregs--8c knows how
+ * to generate the code directly now.  Find and remove.
+ */
+
+void	runtime·panicdivide(void);
+
+typedef	unsigned long	ulong;
+typedef	unsigned int	uint;
+typedef	unsigned short	ushort;
+typedef	unsigned char	uchar;
+typedef	signed char	schar;
+
+#define	SIGN(n)	(1UL<<(n-1))
+
+typedef	struct	Vlong	Vlong;
+struct	Vlong
+{
+	ulong	lo;
+	ulong	hi;
+};
+
+typedef	union	Vlong64	Vlong64;
+union	Vlong64
+{
+	long long	v;
+	Vlong	v2;
+};
+
+void	runtime·abort(void);
+
+#pragma textflag NOSPLIT
+Vlong
+_addv(Vlong a, Vlong b)
+{
+	Vlong r;
+
+	r.lo = a.lo + b.lo;
+	r.hi = a.hi + b.hi;
+	if(r.lo < a.lo)
+		r.hi++;
+	return r;
+}
+
+#pragma textflag NOSPLIT
+Vlong
+_subv(Vlong a, Vlong b)
+{
+	Vlong r;
+
+	r.lo = a.lo - b.lo;
+	r.hi = a.hi - b.hi;
+	if(r.lo > a.lo)
+		r.hi--;
+	return r;
+}
+
+Vlong
+_d2v(double d)
+{
+	union { double d; Vlong vl; } x;
+	ulong xhi, xlo, ylo, yhi;
+	int sh;
+	Vlong y;
+
+	x.d = d;
+
+	xhi = (x.vl.hi & 0xfffff) | 0x100000;
+	xlo = x.vl.lo;
+	sh = 1075 - ((x.vl.hi >> 20) & 0x7ff);
+
+	ylo = 0;
+	yhi = 0;
+	if(sh >= 0) {
+		/* v = (hi||lo) >> sh */
+		if(sh < 32) {
+			if(sh == 0) {
+				ylo = xlo;
+				yhi = xhi;
+			} else {
+				ylo = (xlo >> sh) | (xhi << (32-sh));
+				yhi = xhi >> sh;
+			}
+		} else {
+			if(sh == 32) {
+				ylo = xhi;
+			} else
+			if(sh < 64) {
+				ylo = xhi >> (sh-32);
+			}
+		}
+	} else {
+		/* v = (hi||lo) << -sh */
+		sh = -sh;
+		if(sh <= 10) { /* NOTE: sh <= 11 on ARM??? */
+			ylo = xlo << sh;
+			yhi = (xhi << sh) | (xlo >> (32-sh));
+		} else {
+			/* overflow */
+			yhi = d;	/* causes something awful */
+		}
+	}
+	if(x.vl.hi & SIGN(32)) {
+		if(ylo != 0) {
+			ylo = -ylo;
+			yhi = ~yhi;
+		} else
+			yhi = -yhi;
+	}
+
+	y.hi = yhi;
+	y.lo = ylo;
+	return y;
+}
+
+Vlong
+_f2v(float f)
+{
+	return _d2v(f);
+}
+
+double
+_ul2d(ulong u)
+{
+	// compensate for bug in c
+	if(u & SIGN(32)) {
+		u ^= SIGN(32);
+		return 2147483648. + u;
+	}
+	return u;
+}
+
+double
+_v2d(Vlong x)
+{
+	if(x.hi & SIGN(32)) {
+		if(x.lo) {
+			x.lo = -x.lo;
+			x.hi = ~x.hi;
+		} else
+			x.hi = -x.hi;
+		return -(_ul2d(x.hi)*4294967296. + _ul2d(x.lo));
+	}
+	return (long)x.hi*4294967296. + x.lo;
+}
+
+float
+_v2f(Vlong x)
+{
+	return _v2d(x);
+}
+
+ulong	runtime·_div64by32(Vlong, ulong, ulong*);
+int	runtime·_mul64by32(Vlong*, Vlong, ulong);
+
+static void
+slowdodiv(Vlong num, Vlong den, Vlong *q, Vlong *r)
+{
+	ulong numlo, numhi, denhi, denlo, quohi, quolo, t;
+	int i;
+
+	numhi = num.hi;
+	numlo = num.lo;
+	denhi = den.hi;
+	denlo = den.lo;
+
+	/*
+	 * get a divide by zero
+	 */
+	if(denlo==0 && denhi==0) {
+		runtime·panicdivide();
+	}
+
+	/*
+	 * set up the divisor and find the number of iterations needed
+	 */
+	if(numhi >= SIGN(32)) {
+		quohi = SIGN(32);
+		quolo = 0;
+	} else {
+		quohi = numhi;
+		quolo = numlo;
+	}
+	i = 0;
+	while(denhi < quohi || (denhi == quohi && denlo < quolo)) {
+		denhi = (denhi<<1) | (denlo>>31);
+		denlo <<= 1;
+		i++;
+	}
+
+	quohi = 0;
+	quolo = 0;
+	for(; i >= 0; i--) {
+		quohi = (quohi<<1) | (quolo>>31);
+		quolo <<= 1;
+		if(numhi > denhi || (numhi == denhi && numlo >= denlo)) {
+			t = numlo;
+			numlo -= denlo;
+			if(numlo > t)
+				numhi--;
+			numhi -= denhi;
+			quolo |= 1;
+		}
+		denlo = (denlo>>1) | (denhi<<31);
+		denhi >>= 1;
+	}
+
+	if(q) {
+		q->lo = quolo;
+		q->hi = quohi;
+	}
+	if(r) {
+		r->lo = numlo;
+		r->hi = numhi;
+	}
+}
+
+#ifdef GOARCH_arm
+static void
+dodiv(Vlong num, Vlong den, Vlong *qp, Vlong *rp)
+{
+	slowdodiv(num, den, qp, rp);
+}
+#endif
+
+#ifdef GOARCH_386
+static void
+dodiv(Vlong num, Vlong den, Vlong *qp, Vlong *rp)
+{
+	ulong n;
+	Vlong x, q, r;
+	
+	if(den.hi > num.hi || (den.hi == num.hi && den.lo > num.lo)){
+		if(qp) {
+			qp->hi = 0;
+			qp->lo = 0;
+		}
+		if(rp) {
+			rp->hi = num.hi;
+			rp->lo = num.lo;
+		}
+		return;
+	}
+
+	if(den.hi != 0){
+		q.hi = 0;
+		n = num.hi/den.hi;
+		if(runtime·_mul64by32(&x, den, n) || x.hi > num.hi || (x.hi == num.hi && x.lo > num.lo))
+			slowdodiv(num, den, &q, &r);
+		else {
+			q.lo = n;
+			*(long long*)&r = *(long long*)&num - *(long long*)&x;
+		}
+	} else {
+		if(num.hi >= den.lo){
+			if(den.lo == 0)
+				runtime·panicdivide();
+			q.hi = n = num.hi/den.lo;
+			num.hi -= den.lo*n;
+		} else {
+			q.hi = 0;
+		}
+		q.lo = runtime·_div64by32(num, den.lo, &r.lo);
+		r.hi = 0;
+	}
+	if(qp) {
+		qp->lo = q.lo;
+		qp->hi = q.hi;
+	}
+	if(rp) {
+		rp->lo = r.lo;
+		rp->hi = r.hi;
+	}
+}
+#endif
+
+Vlong
+_divvu(Vlong n, Vlong d)
+{
+	Vlong q;
+
+	if(n.hi == 0 && d.hi == 0) {
+		if(d.lo == 0)
+			runtime·panicdivide();
+		q.hi = 0;
+		q.lo = n.lo / d.lo;
+		return q;
+	}
+	dodiv(n, d, &q, 0);
+	return q;
+}
+
+Vlong
+_modvu(Vlong n, Vlong d)
+{
+	Vlong r;
+
+	if(n.hi == 0 && d.hi == 0) {
+		if(d.lo == 0)
+			runtime·panicdivide();
+		r.hi = 0;
+		r.lo = n.lo % d.lo;
+		return r;
+	}
+	dodiv(n, d, 0, &r);
+	return r;
+}
+
+static void
+vneg(Vlong *v)
+{
+
+	if(v->lo == 0) {
+		v->hi = -v->hi;
+		return;
+	}
+	v->lo = -v->lo;
+	v->hi = ~v->hi;
+}
+
+Vlong
+_divv(Vlong n, Vlong d)
+{
+	long nneg, dneg;
+	Vlong q;
+
+	if(n.hi == (((long)n.lo)>>31) && d.hi == (((long)d.lo)>>31)) {
+		if((long)n.lo == -0x80000000 && (long)d.lo == -1) {
+			// special case: 32-bit -0x80000000 / -1 causes divide error,
+			// but it's okay in this 64-bit context.
+			q.lo = 0x80000000;
+			q.hi = 0;
+			return q;
+		}
+		if(d.lo == 0)
+			runtime·panicdivide();
+		q.lo = (long)n.lo / (long)d.lo;
+		q.hi = ((long)q.lo) >> 31;
+		return q;
+	}
+	nneg = n.hi >> 31;
+	if(nneg)
+		vneg(&n);
+	dneg = d.hi >> 31;
+	if(dneg)
+		vneg(&d);
+	dodiv(n, d, &q, 0);
+	if(nneg != dneg)
+		vneg(&q);
+	return q;
+}
+
+Vlong
+_modv(Vlong n, Vlong d)
+{
+	long nneg, dneg;
+	Vlong r;
+
+	if(n.hi == (((long)n.lo)>>31) && d.hi == (((long)d.lo)>>31)) {
+		if((long)n.lo == -0x80000000 && (long)d.lo == -1) {
+			// special case: 32-bit -0x80000000 % -1 causes divide error,
+			// but it's okay in this 64-bit context.
+			r.lo = 0;
+			r.hi = 0;
+			return r;
+		}
+		if(d.lo == 0)
+			runtime·panicdivide();
+		r.lo = (long)n.lo % (long)d.lo;
+		r.hi = ((long)r.lo) >> 31;
+		return r;
+	}
+	nneg = n.hi >> 31;
+	if(nneg)
+		vneg(&n);
+	dneg = d.hi >> 31;
+	if(dneg)
+		vneg(&d);
+	dodiv(n, d, 0, &r);
+	if(nneg)
+		vneg(&r);
+	return r;
+}
+
+#pragma textflag NOSPLIT
+Vlong
+_rshav(Vlong a, int b)
+{
+	long t;
+	Vlong r;
+
+	t = a.hi;
+	if(b >= 32) {
+		r.hi = t>>31;
+		if(b >= 64) {
+			/* this is illegal re C standard */
+			r.lo = t>>31;
+			return r;
+		}
+		r.lo = t >> (b-32);
+		return r;
+	}
+	if(b <= 0) {
+		r.hi = t;
+		r.lo = a.lo;
+		return r;
+	}
+	r.hi = t >> b;
+	r.lo = (t << (32-b)) | (a.lo >> b);
+	return r;
+}
+
+#pragma textflag NOSPLIT
+Vlong
+_rshlv(Vlong a, int b)
+{
+	ulong t;
+	Vlong r;
+
+	t = a.hi;
+	if(b >= 32) {
+		r.hi = 0;
+		if(b >= 64) {
+			/* this is illegal re C standard */
+			r.lo = 0;
+			return r;
+		}
+		r.lo = t >> (b-32);
+		return r;
+	}
+	if(b <= 0) {
+		r.hi = t;
+		r.lo = a.lo;
+		return r;
+	}
+	r.hi = t >> b;
+	r.lo = (t << (32-b)) | (a.lo >> b);
+	return r;
+}
+
+#pragma textflag NOSPLIT
+Vlong
+_lshv(Vlong a, int b)
+{
+	ulong t;
+
+	t = a.lo;
+	if(b >= 32) {
+		if(b >= 64) {
+			/* this is illegal re C standard */
+			return (Vlong){0, 0};
+		}
+		return (Vlong){0, t<<(b-32)};
+	}
+	if(b <= 0) {
+		return (Vlong){t, a.hi};
+	}
+	return (Vlong){t<<b, (t >> (32-b)) | (a.hi << b)};
+}
+
+#pragma textflag NOSPLIT
+Vlong
+_andv(Vlong a, Vlong b)
+{
+	Vlong r;
+
+	r.hi = a.hi & b.hi;
+	r.lo = a.lo & b.lo;
+	return r;
+}
+
+#pragma textflag NOSPLIT
+Vlong
+_orv(Vlong a, Vlong b)
+{
+	Vlong r;
+
+	r.hi = a.hi | b.hi;
+	r.lo = a.lo | b.lo;
+	return r;
+}
+
+#pragma textflag NOSPLIT
+Vlong
+_xorv(Vlong a, Vlong b)
+{
+	Vlong r;
+
+	r.hi = a.hi ^ b.hi;
+	r.lo = a.lo ^ b.lo;
+	return r;
+}
+
+Vlong
+_vpp(Vlong *r)
+{
+	Vlong l;
+
+	l = *r;
+	r->lo++;
+	if(r->lo == 0)
+		r->hi++;
+	return l;
+}
+
+#pragma textflag NOSPLIT
+Vlong
+_vmm(Vlong *r)
+{
+	Vlong l;
+
+	l = *r;
+	if(r->lo == 0)
+		r->hi--;
+	r->lo--;
+	return l;
+}
+
+#pragma textflag NOSPLIT
+Vlong
+_ppv(Vlong *r)
+{
+
+	r->lo++;
+	if(r->lo == 0)
+		r->hi++;
+	return *r;
+}
+
+#pragma textflag NOSPLIT
+Vlong
+_mmv(Vlong *r)
+{
+
+	if(r->lo == 0)
+		r->hi--;
+	r->lo--;
+	return *r;
+}
+
+#pragma textflag NOSPLIT
+Vlong
+_vasop(void *lv, Vlong fn(Vlong, Vlong), int type, Vlong rv)
+{
+	Vlong t, u;
+
+	u.lo = 0;
+	u.hi = 0;
+	switch(type) {
+	default:
+		runtime·abort();
+		break;
+
+	case 1:	/* schar */
+		t.lo = *(schar*)lv;
+		t.hi = t.lo >> 31;
+		u = fn(t, rv);
+		*(schar*)lv = u.lo;
+		break;
+
+	case 2:	/* uchar */
+		t.lo = *(uchar*)lv;
+		t.hi = 0;
+		u = fn(t, rv);
+		*(uchar*)lv = u.lo;
+		break;
+
+	case 3:	/* short */
+		t.lo = *(short*)lv;
+		t.hi = t.lo >> 31;
+		u = fn(t, rv);
+		*(short*)lv = u.lo;
+		break;
+
+	case 4:	/* ushort */
+		t.lo = *(ushort*)lv;
+		t.hi = 0;
+		u = fn(t, rv);
+		*(ushort*)lv = u.lo;
+		break;
+
+	case 9:	/* int */
+		t.lo = *(int*)lv;
+		t.hi = t.lo >> 31;
+		u = fn(t, rv);
+		*(int*)lv = u.lo;
+		break;
+
+	case 10:	/* uint */
+		t.lo = *(uint*)lv;
+		t.hi = 0;
+		u = fn(t, rv);
+		*(uint*)lv = u.lo;
+		break;
+
+	case 5:	/* long */
+		t.lo = *(long*)lv;
+		t.hi = t.lo >> 31;
+		u = fn(t, rv);
+		*(long*)lv = u.lo;
+		break;
+
+	case 6:	/* ulong */
+		t.lo = *(ulong*)lv;
+		t.hi = 0;
+		u = fn(t, rv);
+		*(ulong*)lv = u.lo;
+		break;
+
+	case 7:	/* vlong */
+	case 8:	/* uvlong */
+		if((void*)fn == _lshv || (void*)fn == _rshav || (void*)fn == _rshlv)
+			u = ((Vlong(*)(Vlong,int))fn)(*(Vlong*)lv, *(int*)&rv);
+		else
+			u = fn(*(Vlong*)lv, rv);
+		*(Vlong*)lv = u;
+		break;
+	}
+	return u;
+}
+
+#pragma textflag NOSPLIT
+Vlong
+_p2v(void *p)
+{
+	long t;
+	Vlong ret;
+
+	t = (ulong)p;
+	ret.lo = t;
+	ret.hi = 0;
+	return ret;
+}
+
+#pragma textflag NOSPLIT
+Vlong
+_sl2v(long sl)
+{
+	long t;
+	Vlong ret;
+
+	t = sl;
+	ret.lo = t;
+	ret.hi = t >> 31;
+	return ret;
+}
+
+#pragma textflag NOSPLIT
+Vlong
+_ul2v(ulong ul)
+{
+	long t;
+	Vlong ret;
+
+	t = ul;
+	ret.lo = t;
+	ret.hi = 0;
+	return ret;
+}
+
+#pragma textflag NOSPLIT
+Vlong
+_si2v(int si)
+{
+	return (Vlong){si, si>>31};
+}
+
+#pragma textflag NOSPLIT
+Vlong
+_ui2v(uint ui)
+{
+	long t;
+	Vlong ret;
+
+	t = ui;
+	ret.lo = t;
+	ret.hi = 0;
+	return ret;
+}
+
+#pragma textflag NOSPLIT
+Vlong
+_sh2v(long sh)
+{
+	long t;
+	Vlong ret;
+
+	t = (sh << 16) >> 16;
+	ret.lo = t;
+	ret.hi = t >> 31;
+	return ret;
+}
+
+#pragma textflag NOSPLIT
+Vlong
+_uh2v(ulong ul)
+{
+	long t;
+	Vlong ret;
+
+	t = ul & 0xffff;
+	ret.lo = t;
+	ret.hi = 0;
+	return ret;
+}
+
+#pragma textflag NOSPLIT
+Vlong
+_sc2v(long uc)
+{
+	long t;
+	Vlong ret;
+
+	t = (uc << 24) >> 24;
+	ret.lo = t;
+	ret.hi = t >> 31;
+	return ret;
+}
+
+#pragma textflag NOSPLIT
+Vlong
+_uc2v(ulong ul)
+{
+	long t;
+	Vlong ret;
+
+	t = ul & 0xff;
+	ret.lo = t;
+	ret.hi = 0;
+	return ret;
+}
+
+#pragma textflag NOSPLIT
+long
+_v2sc(Vlong rv)
+{
+	long t;
+
+	t = rv.lo & 0xff;
+	return (t << 24) >> 24;
+}
+
+#pragma textflag NOSPLIT
+long
+_v2uc(Vlong rv)
+{
+
+	return rv.lo & 0xff;
+}
+
+#pragma textflag NOSPLIT
+long
+_v2sh(Vlong rv)
+{
+	long t;
+
+	t = rv.lo & 0xffff;
+	return (t << 16) >> 16;
+}
+
+#pragma textflag NOSPLIT
+long
+_v2uh(Vlong rv)
+{
+
+	return rv.lo & 0xffff;
+}
+
+#pragma textflag NOSPLIT
+long
+_v2sl(Vlong rv)
+{
+
+	return rv.lo;
+}
+
+#pragma textflag NOSPLIT
+long
+_v2ul(Vlong rv)
+{
+
+	return rv.lo;
+}
+
+#pragma textflag NOSPLIT
+long
+_v2si(Vlong rv)
+{
+	return rv.lo;
+}
+
+#pragma textflag NOSPLIT
+long
+_v2ui(Vlong rv)
+{
+
+	return rv.lo;
+}
+
+#pragma textflag NOSPLIT
+int
+_testv(Vlong rv)
+{
+	return rv.lo || rv.hi;
+}
+
+#pragma textflag NOSPLIT
+int
+_eqv(Vlong lv, Vlong rv)
+{
+	return lv.lo == rv.lo && lv.hi == rv.hi;
+}
+
+#pragma textflag NOSPLIT
+int
+_nev(Vlong lv, Vlong rv)
+{
+	return lv.lo != rv.lo || lv.hi != rv.hi;
+}
+
+#pragma textflag NOSPLIT
+int
+_ltv(Vlong lv, Vlong rv)
+{
+	return (long)lv.hi < (long)rv.hi ||
+		(lv.hi == rv.hi && lv.lo < rv.lo);
+}
+
+#pragma textflag NOSPLIT
+int
+_lev(Vlong lv, Vlong rv)
+{
+	return (long)lv.hi < (long)rv.hi ||
+		(lv.hi == rv.hi && lv.lo <= rv.lo);
+}
+
+#pragma textflag NOSPLIT
+int
+_gtv(Vlong lv, Vlong rv)
+{
+	return (long)lv.hi > (long)rv.hi ||
+		(lv.hi == rv.hi && lv.lo > rv.lo);
+}
+
+#pragma textflag NOSPLIT
+int
+_gev(Vlong lv, Vlong rv)
+{
+	return (long)lv.hi > (long)rv.hi ||
+		(lv.hi == rv.hi && lv.lo >= rv.lo);
+}
+
+#pragma textflag NOSPLIT
+int
+_lov(Vlong lv, Vlong rv)
+{
+	return lv.hi < rv.hi ||
+		(lv.hi == rv.hi && lv.lo < rv.lo);
+}
+
+#pragma textflag NOSPLIT
+int
+_lsv(Vlong lv, Vlong rv)
+{
+	return lv.hi < rv.hi ||
+		(lv.hi == rv.hi && lv.lo <= rv.lo);
+}
+
+#pragma textflag NOSPLIT
+int
+_hiv(Vlong lv, Vlong rv)
+{
+	return lv.hi > rv.hi ||
+		(lv.hi == rv.hi && lv.lo > rv.lo);
+}
+
+#pragma textflag NOSPLIT
+int
+_hsv(Vlong lv, Vlong rv)
+{
+	return lv.hi > rv.hi ||
+		(lv.hi == rv.hi && lv.lo >= rv.lo);
+}
diff --git a/src/runtime/vlrt.go b/src/runtime/vlrt.go
new file mode 100644
index 0000000..6370732
--- /dev/null
+++ b/src/runtime/vlrt.go
@@ -0,0 +1,258 @@
+// Inferno's libkern/vlrt-arm.c
+// http://code.google.com/p/inferno-os/source/browse/libkern/vlrt-arm.c
+//
+//         Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
+//         Revisions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com).  All rights reserved.
+//         Portions Copyright 2009 The Go Authors. All rights reserved.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+// +build arm 386
+
+package runtime
+
+import "unsafe"
+
+const (
+	sign32 = 1 << (32 - 1)
+	sign64 = 1 << (64 - 1)
+)
+
+func float64toint64(d float64) (y uint64) {
+	_d2v(&y, d)
+	return
+}
+
+func float64touint64(d float64) (y uint64) {
+	_d2v(&y, d)
+	return
+}
+
+func int64tofloat64(y int64) float64 {
+	if y < 0 {
+		return -uint64tofloat64(-uint64(y))
+	}
+	return uint64tofloat64(uint64(y))
+}
+
+func uint64tofloat64(y uint64) float64 {
+	hi := float64(uint32(y >> 32))
+	lo := float64(uint32(y))
+	d := hi*(1<<32) + lo
+	return d
+}
+
+func _d2v(y *uint64, d float64) {
+	x := *(*uint64)(unsafe.Pointer(&d))
+
+	xhi := uint32(x>>32)&0xfffff | 0x100000
+	xlo := uint32(x)
+	sh := 1075 - int32(uint32(x>>52)&0x7ff)
+
+	var ylo, yhi uint32
+	if sh >= 0 {
+		sh := uint32(sh)
+		/* v = (hi||lo) >> sh */
+		if sh < 32 {
+			if sh == 0 {
+				ylo = xlo
+				yhi = xhi
+			} else {
+				ylo = xlo>>sh | xhi<<(32-sh)
+				yhi = xhi >> sh
+			}
+		} else {
+			if sh == 32 {
+				ylo = xhi
+			} else if sh < 64 {
+				ylo = xhi >> (sh - 32)
+			}
+		}
+	} else {
+		/* v = (hi||lo) << -sh */
+		sh := uint32(-sh)
+		if sh <= 11 {
+			ylo = xlo << sh
+			yhi = xhi<<sh | xlo>>(32-sh)
+		} else {
+			/* overflow */
+			yhi = uint32(d) /* causes something awful */
+		}
+	}
+	if x&sign64 != 0 {
+		if ylo != 0 {
+			ylo = -ylo
+			yhi = ^yhi
+		} else {
+			yhi = -yhi
+		}
+	}
+
+	*y = uint64(yhi)<<32 | uint64(ylo)
+}
+
+func uint64div(n, d uint64) uint64 {
+	// Check for 32 bit operands
+	if uint32(n>>32) == 0 && uint32(d>>32) == 0 {
+		if uint32(d) == 0 {
+			panicdivide()
+		}
+		return uint64(uint32(n) / uint32(d))
+	}
+	q, _ := dodiv(n, d)
+	return q
+}
+
+func uint64mod(n, d uint64) uint64 {
+	// Check for 32 bit operands
+	if uint32(n>>32) == 0 && uint32(d>>32) == 0 {
+		if uint32(d) == 0 {
+			panicdivide()
+		}
+		return uint64(uint32(n) % uint32(d))
+	}
+	_, r := dodiv(n, d)
+	return r
+}
+
+func int64div(n, d int64) int64 {
+	// Check for 32 bit operands
+	if int64(int32(n)) == n && int64(int32(d)) == d {
+		if int32(n) == -0x80000000 && int32(d) == -1 {
+			// special case: 32-bit -0x80000000 / -1 = -0x80000000,
+			// but 64-bit -0x80000000 / -1 = 0x80000000.
+			return 0x80000000
+		}
+		if int32(d) == 0 {
+			panicdivide()
+		}
+		return int64(int32(n) / int32(d))
+	}
+
+	nneg := n < 0
+	dneg := d < 0
+	if nneg {
+		n = -n
+	}
+	if dneg {
+		d = -d
+	}
+	uq, _ := dodiv(uint64(n), uint64(d))
+	q := int64(uq)
+	if nneg != dneg {
+		q = -q
+	}
+	return q
+}
+
+func int64mod(n, d int64) int64 {
+	// Check for 32 bit operands
+	if int64(int32(n)) == n && int64(int32(d)) == d {
+		if int32(d) == 0 {
+			panicdivide()
+		}
+		return int64(int32(n) % int32(d))
+	}
+
+	nneg := n < 0
+	if nneg {
+		n = -n
+	}
+	if d < 0 {
+		d = -d
+	}
+	_, ur := dodiv(uint64(n), uint64(d))
+	r := int64(ur)
+	if nneg {
+		r = -r
+	}
+	return r
+}
+
+//go:noescape
+func _mul64by32(lo64 *uint64, a uint64, b uint32) (hi32 uint32)
+
+//go:noescape
+func _div64by32(a uint64, b uint32, r *uint32) (q uint32)
+
+func dodiv(n, d uint64) (q, r uint64) {
+	if GOARCH == "arm" {
+		// arm doesn't have a division instruction, so
+		// slowdodiv is the best that we can do.
+		// TODO: revisit for arm64.
+		return slowdodiv(n, d)
+	}
+
+	if d > n {
+		return 0, n
+	}
+
+	if uint32(d>>32) != 0 {
+		t := uint32(n>>32) / uint32(d>>32)
+		var lo64 uint64
+		hi32 := _mul64by32(&lo64, d, t)
+		if hi32 != 0 || lo64 > n {
+			return slowdodiv(n, d)
+		}
+		return uint64(t), n - lo64
+	}
+
+	// d is 32 bit
+	var qhi uint32
+	if uint32(n>>32) >= uint32(d) {
+		if uint32(d) == 0 {
+			panicdivide()
+		}
+		qhi = uint32(n>>32) / uint32(d)
+		n -= uint64(uint32(d)*qhi) << 32
+	} else {
+		qhi = 0
+	}
+
+	var rlo uint32
+	qlo := _div64by32(n, uint32(d), &rlo)
+	return uint64(qhi)<<32 + uint64(qlo), uint64(rlo)
+}
+
+func slowdodiv(n, d uint64) (q, r uint64) {
+	if d == 0 {
+		panicdivide()
+	}
+
+	// Set up the divisor and find the number of iterations needed.
+	capn := n
+	if n >= sign64 {
+		capn = sign64
+	}
+	i := 0
+	for d < capn {
+		d <<= 1
+		i++
+	}
+
+	for ; i >= 0; i-- {
+		q <<= 1
+		if n >= d {
+			n -= d
+			q |= 1
+		}
+		d >>= 1
+	}
+	return q, n
+}
diff --git a/src/pkg/sort/example_interface_test.go b/src/sort/example_interface_test.go
similarity index 100%
rename from src/pkg/sort/example_interface_test.go
rename to src/sort/example_interface_test.go
diff --git a/src/pkg/sort/example_keys_test.go b/src/sort/example_keys_test.go
similarity index 100%
rename from src/pkg/sort/example_keys_test.go
rename to src/sort/example_keys_test.go
diff --git a/src/pkg/sort/example_multi_test.go b/src/sort/example_multi_test.go
similarity index 100%
rename from src/pkg/sort/example_multi_test.go
rename to src/sort/example_multi_test.go
diff --git a/src/pkg/sort/example_test.go b/src/sort/example_test.go
similarity index 100%
rename from src/pkg/sort/example_test.go
rename to src/sort/example_test.go
diff --git a/src/pkg/sort/example_wrapper_test.go b/src/sort/example_wrapper_test.go
similarity index 100%
rename from src/pkg/sort/example_wrapper_test.go
rename to src/sort/example_wrapper_test.go
diff --git a/src/pkg/sort/export_test.go b/src/sort/export_test.go
similarity index 100%
rename from src/pkg/sort/export_test.go
rename to src/sort/export_test.go
diff --git a/src/pkg/sort/search.go b/src/sort/search.go
similarity index 100%
rename from src/pkg/sort/search.go
rename to src/sort/search.go
diff --git a/src/pkg/sort/search_test.go b/src/sort/search_test.go
similarity index 100%
rename from src/pkg/sort/search_test.go
rename to src/sort/search_test.go
diff --git a/src/pkg/sort/sort.go b/src/sort/sort.go
similarity index 100%
rename from src/pkg/sort/sort.go
rename to src/sort/sort.go
diff --git a/src/pkg/sort/sort_test.go b/src/sort/sort_test.go
similarity index 100%
rename from src/pkg/sort/sort_test.go
rename to src/sort/sort_test.go
diff --git a/src/pkg/strconv/atob.go b/src/strconv/atob.go
similarity index 100%
rename from src/pkg/strconv/atob.go
rename to src/strconv/atob.go
diff --git a/src/pkg/strconv/atob_test.go b/src/strconv/atob_test.go
similarity index 100%
rename from src/pkg/strconv/atob_test.go
rename to src/strconv/atob_test.go
diff --git a/src/pkg/strconv/atof.go b/src/strconv/atof.go
similarity index 100%
rename from src/pkg/strconv/atof.go
rename to src/strconv/atof.go
diff --git a/src/pkg/strconv/atof_test.go b/src/strconv/atof_test.go
similarity index 100%
rename from src/pkg/strconv/atof_test.go
rename to src/strconv/atof_test.go
diff --git a/src/strconv/atoi.go b/src/strconv/atoi.go
new file mode 100644
index 0000000..9ecec5a
--- /dev/null
+++ b/src/strconv/atoi.go
@@ -0,0 +1,198 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package strconv
+
+import "errors"
+
+// ErrRange indicates that a value is out of range for the target type.
+var ErrRange = errors.New("value out of range")
+
+// ErrSyntax indicates that a value does not have the right syntax for the target type.
+var ErrSyntax = errors.New("invalid syntax")
+
+// A NumError records a failed conversion.
+type NumError struct {
+	Func string // the failing function (ParseBool, ParseInt, ParseUint, ParseFloat)
+	Num  string // the input
+	Err  error  // the reason the conversion failed (ErrRange, ErrSyntax)
+}
+
+func (e *NumError) Error() string {
+	return "strconv." + e.Func + ": " + "parsing " + Quote(e.Num) + ": " + e.Err.Error()
+}
+
+func syntaxError(fn, str string) *NumError {
+	return &NumError{fn, str, ErrSyntax}
+}
+
+func rangeError(fn, str string) *NumError {
+	return &NumError{fn, str, ErrRange}
+}
+
+const intSize = 32 << (^uint(0) >> 63)
+
+// IntSize is the size in bits of an int or uint value.
+const IntSize = intSize
+
+// Return the first number n such that n*base >= 1<<64.
+func cutoff64(base int) uint64 {
+	if base < 2 {
+		return 0
+	}
+	return (1<<64-1)/uint64(base) + 1
+}
+
+// ParseUint is like ParseInt but for unsigned numbers.
+func ParseUint(s string, base int, bitSize int) (n uint64, err error) {
+	var cutoff, maxVal uint64
+
+	if bitSize == 0 {
+		bitSize = int(IntSize)
+	}
+
+	s0 := s
+	switch {
+	case len(s) < 1:
+		err = ErrSyntax
+		goto Error
+
+	case 2 <= base && base <= 36:
+		// valid base; nothing to do
+
+	case base == 0:
+		// Look for octal, hex prefix.
+		switch {
+		case s[0] == '0' && len(s) > 1 && (s[1] == 'x' || s[1] == 'X'):
+			base = 16
+			s = s[2:]
+			if len(s) < 1 {
+				err = ErrSyntax
+				goto Error
+			}
+		case s[0] == '0':
+			base = 8
+		default:
+			base = 10
+		}
+
+	default:
+		err = errors.New("invalid base " + Itoa(base))
+		goto Error
+	}
+
+	n = 0
+	cutoff = cutoff64(base)
+	maxVal = 1<<uint(bitSize) - 1
+
+	for i := 0; i < len(s); i++ {
+		var v byte
+		d := s[i]
+		switch {
+		case '0' <= d && d <= '9':
+			v = d - '0'
+		case 'a' <= d && d <= 'z':
+			v = d - 'a' + 10
+		case 'A' <= d && d <= 'Z':
+			v = d - 'A' + 10
+		default:
+			n = 0
+			err = ErrSyntax
+			goto Error
+		}
+		if int(v) >= base {
+			n = 0
+			err = ErrSyntax
+			goto Error
+		}
+
+		if n >= cutoff {
+			// n*base overflows
+			n = 1<<64 - 1
+			err = ErrRange
+			goto Error
+		}
+		n *= uint64(base)
+
+		n1 := n + uint64(v)
+		if n1 < n || n1 > maxVal {
+			// n+v overflows
+			n = 1<<64 - 1
+			err = ErrRange
+			goto Error
+		}
+		n = n1
+	}
+
+	return n, nil
+
+Error:
+	return n, &NumError{"ParseUint", s0, err}
+}
+
+// ParseInt interprets a string s in the given base (2 to 36) and
+// returns the corresponding value i.  If base == 0, the base is
+// implied by the string's prefix: base 16 for "0x", base 8 for
+// "0", and base 10 otherwise.
+//
+// The bitSize argument specifies the integer type
+// that the result must fit into.  Bit sizes 0, 8, 16, 32, and 64
+// correspond to int, int8, int16, int32, and int64.
+//
+// The errors that ParseInt returns have concrete type *NumError
+// and include err.Num = s.  If s is empty or contains invalid
+// digits, err.Err = ErrSyntax and the returned value is 0;
+// if the value corresponding to s cannot be represented by a
+// signed integer of the given size, err.Err = ErrRange and the
+// returned value is the maximum magnitude integer of the
+// appropriate bitSize and sign.
+func ParseInt(s string, base int, bitSize int) (i int64, err error) {
+	const fnParseInt = "ParseInt"
+
+	if bitSize == 0 {
+		bitSize = int(IntSize)
+	}
+
+	// Empty string bad.
+	if len(s) == 0 {
+		return 0, syntaxError(fnParseInt, s)
+	}
+
+	// Pick off leading sign.
+	s0 := s
+	neg := false
+	if s[0] == '+' {
+		s = s[1:]
+	} else if s[0] == '-' {
+		neg = true
+		s = s[1:]
+	}
+
+	// Convert unsigned and check range.
+	var un uint64
+	un, err = ParseUint(s, base, bitSize)
+	if err != nil && err.(*NumError).Err != ErrRange {
+		err.(*NumError).Func = fnParseInt
+		err.(*NumError).Num = s0
+		return 0, err
+	}
+	cutoff := uint64(1 << uint(bitSize-1))
+	if !neg && un >= cutoff {
+		return int64(cutoff - 1), rangeError(fnParseInt, s0)
+	}
+	if neg && un > cutoff {
+		return -int64(cutoff), rangeError(fnParseInt, s0)
+	}
+	n := int64(un)
+	if neg {
+		n = -n
+	}
+	return n, nil
+}
+
+// Atoi is shorthand for ParseInt(s, 10, 0).
+func Atoi(s string) (i int, err error) {
+	i64, err := ParseInt(s, 10, 0)
+	return int(i64), err
+}
diff --git a/src/pkg/strconv/atoi_test.go b/src/strconv/atoi_test.go
similarity index 100%
rename from src/pkg/strconv/atoi_test.go
rename to src/strconv/atoi_test.go
diff --git a/src/pkg/strconv/decimal.go b/src/strconv/decimal.go
similarity index 100%
rename from src/pkg/strconv/decimal.go
rename to src/strconv/decimal.go
diff --git a/src/pkg/strconv/decimal_test.go b/src/strconv/decimal_test.go
similarity index 100%
rename from src/pkg/strconv/decimal_test.go
rename to src/strconv/decimal_test.go
diff --git a/src/pkg/strconv/extfloat.go b/src/strconv/extfloat.go
similarity index 100%
rename from src/pkg/strconv/extfloat.go
rename to src/strconv/extfloat.go
diff --git a/src/pkg/strconv/fp_test.go b/src/strconv/fp_test.go
similarity index 100%
rename from src/pkg/strconv/fp_test.go
rename to src/strconv/fp_test.go
diff --git a/src/pkg/strconv/ftoa.go b/src/strconv/ftoa.go
similarity index 100%
rename from src/pkg/strconv/ftoa.go
rename to src/strconv/ftoa.go
diff --git a/src/pkg/strconv/ftoa_test.go b/src/strconv/ftoa_test.go
similarity index 100%
rename from src/pkg/strconv/ftoa_test.go
rename to src/strconv/ftoa_test.go
diff --git a/src/pkg/strconv/internal_test.go b/src/strconv/internal_test.go
similarity index 100%
rename from src/pkg/strconv/internal_test.go
rename to src/strconv/internal_test.go
diff --git a/src/strconv/isprint.go b/src/strconv/isprint.go
new file mode 100644
index 0000000..80738ed
--- /dev/null
+++ b/src/strconv/isprint.go
@@ -0,0 +1,624 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// DO NOT EDIT.  GENERATED BY
+//     go run makeisprint.go -output isprint.go
+
+package strconv
+
+// (468+138+67)*2 + (326)*4 = 2650 bytes
+
+var isPrint16 = []uint16{
+	0x0020, 0x007e,
+	0x00a1, 0x0377,
+	0x037a, 0x037f,
+	0x0384, 0x0556,
+	0x0559, 0x058a,
+	0x058d, 0x05c7,
+	0x05d0, 0x05ea,
+	0x05f0, 0x05f4,
+	0x0606, 0x061b,
+	0x061e, 0x070d,
+	0x0710, 0x074a,
+	0x074d, 0x07b1,
+	0x07c0, 0x07fa,
+	0x0800, 0x082d,
+	0x0830, 0x085b,
+	0x085e, 0x085e,
+	0x08a0, 0x08b2,
+	0x08e4, 0x098c,
+	0x098f, 0x0990,
+	0x0993, 0x09b2,
+	0x09b6, 0x09b9,
+	0x09bc, 0x09c4,
+	0x09c7, 0x09c8,
+	0x09cb, 0x09ce,
+	0x09d7, 0x09d7,
+	0x09dc, 0x09e3,
+	0x09e6, 0x09fb,
+	0x0a01, 0x0a0a,
+	0x0a0f, 0x0a10,
+	0x0a13, 0x0a39,
+	0x0a3c, 0x0a42,
+	0x0a47, 0x0a48,
+	0x0a4b, 0x0a4d,
+	0x0a51, 0x0a51,
+	0x0a59, 0x0a5e,
+	0x0a66, 0x0a75,
+	0x0a81, 0x0ab9,
+	0x0abc, 0x0acd,
+	0x0ad0, 0x0ad0,
+	0x0ae0, 0x0ae3,
+	0x0ae6, 0x0af1,
+	0x0b01, 0x0b0c,
+	0x0b0f, 0x0b10,
+	0x0b13, 0x0b39,
+	0x0b3c, 0x0b44,
+	0x0b47, 0x0b48,
+	0x0b4b, 0x0b4d,
+	0x0b56, 0x0b57,
+	0x0b5c, 0x0b63,
+	0x0b66, 0x0b77,
+	0x0b82, 0x0b8a,
+	0x0b8e, 0x0b95,
+	0x0b99, 0x0b9f,
+	0x0ba3, 0x0ba4,
+	0x0ba8, 0x0baa,
+	0x0bae, 0x0bb9,
+	0x0bbe, 0x0bc2,
+	0x0bc6, 0x0bcd,
+	0x0bd0, 0x0bd0,
+	0x0bd7, 0x0bd7,
+	0x0be6, 0x0bfa,
+	0x0c00, 0x0c39,
+	0x0c3d, 0x0c4d,
+	0x0c55, 0x0c59,
+	0x0c60, 0x0c63,
+	0x0c66, 0x0c6f,
+	0x0c78, 0x0cb9,
+	0x0cbc, 0x0ccd,
+	0x0cd5, 0x0cd6,
+	0x0cde, 0x0ce3,
+	0x0ce6, 0x0cf2,
+	0x0d01, 0x0d3a,
+	0x0d3d, 0x0d4e,
+	0x0d57, 0x0d57,
+	0x0d60, 0x0d63,
+	0x0d66, 0x0d75,
+	0x0d79, 0x0d7f,
+	0x0d82, 0x0d96,
+	0x0d9a, 0x0dbd,
+	0x0dc0, 0x0dc6,
+	0x0dca, 0x0dca,
+	0x0dcf, 0x0ddf,
+	0x0de6, 0x0def,
+	0x0df2, 0x0df4,
+	0x0e01, 0x0e3a,
+	0x0e3f, 0x0e5b,
+	0x0e81, 0x0e84,
+	0x0e87, 0x0e8a,
+	0x0e8d, 0x0e8d,
+	0x0e94, 0x0ea7,
+	0x0eaa, 0x0ebd,
+	0x0ec0, 0x0ecd,
+	0x0ed0, 0x0ed9,
+	0x0edc, 0x0edf,
+	0x0f00, 0x0f6c,
+	0x0f71, 0x0fda,
+	0x1000, 0x10c7,
+	0x10cd, 0x10cd,
+	0x10d0, 0x124d,
+	0x1250, 0x125d,
+	0x1260, 0x128d,
+	0x1290, 0x12b5,
+	0x12b8, 0x12c5,
+	0x12c8, 0x1315,
+	0x1318, 0x135a,
+	0x135d, 0x137c,
+	0x1380, 0x1399,
+	0x13a0, 0x13f4,
+	0x1400, 0x169c,
+	0x16a0, 0x16f8,
+	0x1700, 0x1714,
+	0x1720, 0x1736,
+	0x1740, 0x1753,
+	0x1760, 0x1773,
+	0x1780, 0x17dd,
+	0x17e0, 0x17e9,
+	0x17f0, 0x17f9,
+	0x1800, 0x180d,
+	0x1810, 0x1819,
+	0x1820, 0x1877,
+	0x1880, 0x18aa,
+	0x18b0, 0x18f5,
+	0x1900, 0x192b,
+	0x1930, 0x193b,
+	0x1940, 0x1940,
+	0x1944, 0x196d,
+	0x1970, 0x1974,
+	0x1980, 0x19ab,
+	0x19b0, 0x19c9,
+	0x19d0, 0x19da,
+	0x19de, 0x1a1b,
+	0x1a1e, 0x1a7c,
+	0x1a7f, 0x1a89,
+	0x1a90, 0x1a99,
+	0x1aa0, 0x1aad,
+	0x1ab0, 0x1abe,
+	0x1b00, 0x1b4b,
+	0x1b50, 0x1b7c,
+	0x1b80, 0x1bf3,
+	0x1bfc, 0x1c37,
+	0x1c3b, 0x1c49,
+	0x1c4d, 0x1c7f,
+	0x1cc0, 0x1cc7,
+	0x1cd0, 0x1cf9,
+	0x1d00, 0x1df5,
+	0x1dfc, 0x1f15,
+	0x1f18, 0x1f1d,
+	0x1f20, 0x1f45,
+	0x1f48, 0x1f4d,
+	0x1f50, 0x1f7d,
+	0x1f80, 0x1fd3,
+	0x1fd6, 0x1fef,
+	0x1ff2, 0x1ffe,
+	0x2010, 0x2027,
+	0x2030, 0x205e,
+	0x2070, 0x2071,
+	0x2074, 0x209c,
+	0x20a0, 0x20bd,
+	0x20d0, 0x20f0,
+	0x2100, 0x2189,
+	0x2190, 0x23fa,
+	0x2400, 0x2426,
+	0x2440, 0x244a,
+	0x2460, 0x2b73,
+	0x2b76, 0x2b95,
+	0x2b98, 0x2bb9,
+	0x2bbd, 0x2bd1,
+	0x2c00, 0x2cf3,
+	0x2cf9, 0x2d27,
+	0x2d2d, 0x2d2d,
+	0x2d30, 0x2d67,
+	0x2d6f, 0x2d70,
+	0x2d7f, 0x2d96,
+	0x2da0, 0x2e42,
+	0x2e80, 0x2ef3,
+	0x2f00, 0x2fd5,
+	0x2ff0, 0x2ffb,
+	0x3001, 0x3096,
+	0x3099, 0x30ff,
+	0x3105, 0x312d,
+	0x3131, 0x31ba,
+	0x31c0, 0x31e3,
+	0x31f0, 0x4db5,
+	0x4dc0, 0x9fcc,
+	0xa000, 0xa48c,
+	0xa490, 0xa4c6,
+	0xa4d0, 0xa62b,
+	0xa640, 0xa6f7,
+	0xa700, 0xa7ad,
+	0xa7b0, 0xa7b1,
+	0xa7f7, 0xa82b,
+	0xa830, 0xa839,
+	0xa840, 0xa877,
+	0xa880, 0xa8c4,
+	0xa8ce, 0xa8d9,
+	0xa8e0, 0xa8fb,
+	0xa900, 0xa953,
+	0xa95f, 0xa97c,
+	0xa980, 0xa9d9,
+	0xa9de, 0xaa36,
+	0xaa40, 0xaa4d,
+	0xaa50, 0xaa59,
+	0xaa5c, 0xaac2,
+	0xaadb, 0xaaf6,
+	0xab01, 0xab06,
+	0xab09, 0xab0e,
+	0xab11, 0xab16,
+	0xab20, 0xab5f,
+	0xab64, 0xab65,
+	0xabc0, 0xabed,
+	0xabf0, 0xabf9,
+	0xac00, 0xd7a3,
+	0xd7b0, 0xd7c6,
+	0xd7cb, 0xd7fb,
+	0xf900, 0xfa6d,
+	0xfa70, 0xfad9,
+	0xfb00, 0xfb06,
+	0xfb13, 0xfb17,
+	0xfb1d, 0xfbc1,
+	0xfbd3, 0xfd3f,
+	0xfd50, 0xfd8f,
+	0xfd92, 0xfdc7,
+	0xfdf0, 0xfdfd,
+	0xfe00, 0xfe19,
+	0xfe20, 0xfe2d,
+	0xfe30, 0xfe6b,
+	0xfe70, 0xfefc,
+	0xff01, 0xffbe,
+	0xffc2, 0xffc7,
+	0xffca, 0xffcf,
+	0xffd2, 0xffd7,
+	0xffda, 0xffdc,
+	0xffe0, 0xffee,
+	0xfffc, 0xfffd,
+}
+
+var isNotPrint16 = []uint16{
+	0x00ad,
+	0x038b,
+	0x038d,
+	0x03a2,
+	0x0530,
+	0x0560,
+	0x0588,
+	0x0590,
+	0x06dd,
+	0x083f,
+	0x0984,
+	0x09a9,
+	0x09b1,
+	0x09de,
+	0x0a04,
+	0x0a29,
+	0x0a31,
+	0x0a34,
+	0x0a37,
+	0x0a3d,
+	0x0a5d,
+	0x0a84,
+	0x0a8e,
+	0x0a92,
+	0x0aa9,
+	0x0ab1,
+	0x0ab4,
+	0x0ac6,
+	0x0aca,
+	0x0b04,
+	0x0b29,
+	0x0b31,
+	0x0b34,
+	0x0b5e,
+	0x0b84,
+	0x0b91,
+	0x0b9b,
+	0x0b9d,
+	0x0bc9,
+	0x0c04,
+	0x0c0d,
+	0x0c11,
+	0x0c29,
+	0x0c45,
+	0x0c49,
+	0x0c57,
+	0x0c80,
+	0x0c84,
+	0x0c8d,
+	0x0c91,
+	0x0ca9,
+	0x0cb4,
+	0x0cc5,
+	0x0cc9,
+	0x0cdf,
+	0x0cf0,
+	0x0d04,
+	0x0d0d,
+	0x0d11,
+	0x0d45,
+	0x0d49,
+	0x0d84,
+	0x0db2,
+	0x0dbc,
+	0x0dd5,
+	0x0dd7,
+	0x0e83,
+	0x0e89,
+	0x0e98,
+	0x0ea0,
+	0x0ea4,
+	0x0ea6,
+	0x0eac,
+	0x0eba,
+	0x0ec5,
+	0x0ec7,
+	0x0f48,
+	0x0f98,
+	0x0fbd,
+	0x0fcd,
+	0x10c6,
+	0x1249,
+	0x1257,
+	0x1259,
+	0x1289,
+	0x12b1,
+	0x12bf,
+	0x12c1,
+	0x12d7,
+	0x1311,
+	0x1680,
+	0x170d,
+	0x176d,
+	0x1771,
+	0x191f,
+	0x1a5f,
+	0x1cf7,
+	0x1f58,
+	0x1f5a,
+	0x1f5c,
+	0x1f5e,
+	0x1fb5,
+	0x1fc5,
+	0x1fdc,
+	0x1ff5,
+	0x208f,
+	0x2bc9,
+	0x2c2f,
+	0x2c5f,
+	0x2d26,
+	0x2da7,
+	0x2daf,
+	0x2db7,
+	0x2dbf,
+	0x2dc7,
+	0x2dcf,
+	0x2dd7,
+	0x2ddf,
+	0x2e9a,
+	0x3040,
+	0x318f,
+	0x321f,
+	0x32ff,
+	0xa69e,
+	0xa78f,
+	0xa9ce,
+	0xa9ff,
+	0xab27,
+	0xab2f,
+	0xfb37,
+	0xfb3d,
+	0xfb3f,
+	0xfb42,
+	0xfb45,
+	0xfe53,
+	0xfe67,
+	0xfe75,
+	0xffe7,
+}
+
+var isPrint32 = []uint32{
+	0x010000, 0x01004d,
+	0x010050, 0x01005d,
+	0x010080, 0x0100fa,
+	0x010100, 0x010102,
+	0x010107, 0x010133,
+	0x010137, 0x01018c,
+	0x010190, 0x01019b,
+	0x0101a0, 0x0101a0,
+	0x0101d0, 0x0101fd,
+	0x010280, 0x01029c,
+	0x0102a0, 0x0102d0,
+	0x0102e0, 0x0102fb,
+	0x010300, 0x010323,
+	0x010330, 0x01034a,
+	0x010350, 0x01037a,
+	0x010380, 0x0103c3,
+	0x0103c8, 0x0103d5,
+	0x010400, 0x01049d,
+	0x0104a0, 0x0104a9,
+	0x010500, 0x010527,
+	0x010530, 0x010563,
+	0x01056f, 0x01056f,
+	0x010600, 0x010736,
+	0x010740, 0x010755,
+	0x010760, 0x010767,
+	0x010800, 0x010805,
+	0x010808, 0x010838,
+	0x01083c, 0x01083c,
+	0x01083f, 0x01089e,
+	0x0108a7, 0x0108af,
+	0x010900, 0x01091b,
+	0x01091f, 0x010939,
+	0x01093f, 0x01093f,
+	0x010980, 0x0109b7,
+	0x0109be, 0x0109bf,
+	0x010a00, 0x010a06,
+	0x010a0c, 0x010a33,
+	0x010a38, 0x010a3a,
+	0x010a3f, 0x010a47,
+	0x010a50, 0x010a58,
+	0x010a60, 0x010a9f,
+	0x010ac0, 0x010ae6,
+	0x010aeb, 0x010af6,
+	0x010b00, 0x010b35,
+	0x010b39, 0x010b55,
+	0x010b58, 0x010b72,
+	0x010b78, 0x010b91,
+	0x010b99, 0x010b9c,
+	0x010ba9, 0x010baf,
+	0x010c00, 0x010c48,
+	0x010e60, 0x010e7e,
+	0x011000, 0x01104d,
+	0x011052, 0x01106f,
+	0x01107f, 0x0110c1,
+	0x0110d0, 0x0110e8,
+	0x0110f0, 0x0110f9,
+	0x011100, 0x011143,
+	0x011150, 0x011176,
+	0x011180, 0x0111c8,
+	0x0111cd, 0x0111cd,
+	0x0111d0, 0x0111da,
+	0x0111e1, 0x0111f4,
+	0x011200, 0x01123d,
+	0x0112b0, 0x0112ea,
+	0x0112f0, 0x0112f9,
+	0x011301, 0x01130c,
+	0x01130f, 0x011310,
+	0x011313, 0x011339,
+	0x01133c, 0x011344,
+	0x011347, 0x011348,
+	0x01134b, 0x01134d,
+	0x011357, 0x011357,
+	0x01135d, 0x011363,
+	0x011366, 0x01136c,
+	0x011370, 0x011374,
+	0x011480, 0x0114c7,
+	0x0114d0, 0x0114d9,
+	0x011580, 0x0115b5,
+	0x0115b8, 0x0115c9,
+	0x011600, 0x011644,
+	0x011650, 0x011659,
+	0x011680, 0x0116b7,
+	0x0116c0, 0x0116c9,
+	0x0118a0, 0x0118f2,
+	0x0118ff, 0x0118ff,
+	0x011ac0, 0x011af8,
+	0x012000, 0x012398,
+	0x012400, 0x012474,
+	0x013000, 0x01342e,
+	0x016800, 0x016a38,
+	0x016a40, 0x016a69,
+	0x016a6e, 0x016a6f,
+	0x016ad0, 0x016aed,
+	0x016af0, 0x016af5,
+	0x016b00, 0x016b45,
+	0x016b50, 0x016b77,
+	0x016b7d, 0x016b8f,
+	0x016f00, 0x016f44,
+	0x016f50, 0x016f7e,
+	0x016f8f, 0x016f9f,
+	0x01b000, 0x01b001,
+	0x01bc00, 0x01bc6a,
+	0x01bc70, 0x01bc7c,
+	0x01bc80, 0x01bc88,
+	0x01bc90, 0x01bc99,
+	0x01bc9c, 0x01bc9f,
+	0x01d000, 0x01d0f5,
+	0x01d100, 0x01d126,
+	0x01d129, 0x01d172,
+	0x01d17b, 0x01d1dd,
+	0x01d200, 0x01d245,
+	0x01d300, 0x01d356,
+	0x01d360, 0x01d371,
+	0x01d400, 0x01d49f,
+	0x01d4a2, 0x01d4a2,
+	0x01d4a5, 0x01d4a6,
+	0x01d4a9, 0x01d50a,
+	0x01d50d, 0x01d546,
+	0x01d54a, 0x01d6a5,
+	0x01d6a8, 0x01d7cb,
+	0x01d7ce, 0x01d7ff,
+	0x01e800, 0x01e8c4,
+	0x01e8c7, 0x01e8d6,
+	0x01ee00, 0x01ee24,
+	0x01ee27, 0x01ee3b,
+	0x01ee42, 0x01ee42,
+	0x01ee47, 0x01ee54,
+	0x01ee57, 0x01ee64,
+	0x01ee67, 0x01ee9b,
+	0x01eea1, 0x01eebb,
+	0x01eef0, 0x01eef1,
+	0x01f000, 0x01f02b,
+	0x01f030, 0x01f093,
+	0x01f0a0, 0x01f0ae,
+	0x01f0b1, 0x01f0f5,
+	0x01f100, 0x01f10c,
+	0x01f110, 0x01f16b,
+	0x01f170, 0x01f19a,
+	0x01f1e6, 0x01f202,
+	0x01f210, 0x01f23a,
+	0x01f240, 0x01f248,
+	0x01f250, 0x01f251,
+	0x01f300, 0x01f32c,
+	0x01f330, 0x01f37d,
+	0x01f380, 0x01f3ce,
+	0x01f3d4, 0x01f3f7,
+	0x01f400, 0x01f54a,
+	0x01f550, 0x01f642,
+	0x01f645, 0x01f6cf,
+	0x01f6e0, 0x01f6ec,
+	0x01f6f0, 0x01f6f3,
+	0x01f700, 0x01f773,
+	0x01f780, 0x01f7d4,
+	0x01f800, 0x01f80b,
+	0x01f810, 0x01f847,
+	0x01f850, 0x01f859,
+	0x01f860, 0x01f887,
+	0x01f890, 0x01f8ad,
+	0x020000, 0x02a6d6,
+	0x02a700, 0x02b734,
+	0x02b740, 0x02b81d,
+	0x02f800, 0x02fa1d,
+	0x0e0100, 0x0e01ef,
+}
+
+var isNotPrint32 = []uint16{ // add 0x10000 to each entry
+	0x000c,
+	0x0027,
+	0x003b,
+	0x003e,
+	0x039e,
+	0x0809,
+	0x0836,
+	0x0856,
+	0x0a04,
+	0x0a14,
+	0x0a18,
+	0x10bd,
+	0x1135,
+	0x1212,
+	0x1304,
+	0x1329,
+	0x1331,
+	0x1334,
+	0x246f,
+	0x6a5f,
+	0x6b5a,
+	0x6b62,
+	0xd455,
+	0xd49d,
+	0xd4ad,
+	0xd4ba,
+	0xd4bc,
+	0xd4c4,
+	0xd506,
+	0xd515,
+	0xd51d,
+	0xd53a,
+	0xd53f,
+	0xd545,
+	0xd551,
+	0xee04,
+	0xee20,
+	0xee23,
+	0xee28,
+	0xee33,
+	0xee38,
+	0xee3a,
+	0xee48,
+	0xee4a,
+	0xee4c,
+	0xee50,
+	0xee53,
+	0xee58,
+	0xee5a,
+	0xee5c,
+	0xee5e,
+	0xee60,
+	0xee63,
+	0xee6b,
+	0xee73,
+	0xee78,
+	0xee7d,
+	0xee7f,
+	0xee8a,
+	0xeea4,
+	0xeeaa,
+	0xf0c0,
+	0xf0d0,
+	0xf12f,
+	0xf4ff,
+	0xf57a,
+	0xf5a4,
+}
diff --git a/src/pkg/strconv/itoa.go b/src/strconv/itoa.go
similarity index 100%
rename from src/pkg/strconv/itoa.go
rename to src/strconv/itoa.go
diff --git a/src/pkg/strconv/itoa_test.go b/src/strconv/itoa_test.go
similarity index 100%
rename from src/pkg/strconv/itoa_test.go
rename to src/strconv/itoa_test.go
diff --git a/src/strconv/makeisprint.go b/src/strconv/makeisprint.go
new file mode 100644
index 0000000..588d0a0
--- /dev/null
+++ b/src/strconv/makeisprint.go
@@ -0,0 +1,187 @@
+// Copyright 2012 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build ignore
+
+//
+// usage:
+//
+// go run makeisprint.go -output isprint.go
+//
+
+package main
+
+import (
+	"bytes"
+	"flag"
+	"fmt"
+	"go/format"
+	"io/ioutil"
+	"log"
+	"unicode"
+)
+
+var filename = flag.String("output", "isprint.go", "output file name")
+
+var (
+	range16  []uint16
+	except16 []uint16
+	range32  []uint32
+	except32 []uint32
+)
+
+// bsearch16 returns the smallest i such that a[i] >= x.
+// If there is no such i, bsearch16 returns len(a).
+func bsearch16(a []uint16, x uint16) int {
+	i, j := 0, len(a)
+	for i < j {
+		h := i + (j-i)/2
+		if a[h] < x {
+			i = h + 1
+		} else {
+			j = h
+		}
+	}
+	return i
+}
+
+// bsearch32 returns the smallest i such that a[i] >= x.
+// If there is no such i, bsearch32 returns len(a).
+func bsearch32(a []uint32, x uint32) int {
+	i, j := 0, len(a)
+	for i < j {
+		h := i + (j-i)/2
+		if a[h] < x {
+			i = h + 1
+		} else {
+			j = h
+		}
+	}
+	return i
+}
+
+func isPrint(r rune) bool {
+	// Same algorithm, either on uint16 or uint32 value.
+	// First, find first i such that rang[i] >= x.
+	// This is the index of either the start or end of a pair that might span x.
+	// The start is even (rang[i&^1]) and the end is odd (rang[i|1]).
+	// If we find x in a range, make sure x is not in exception list.
+
+	if 0 <= r && r < 1<<16 {
+		rr, rang, except := uint16(r), range16, except16
+		i := bsearch16(rang, rr)
+		if i >= len(rang) || rr < rang[i&^1] || rang[i|1] < rr {
+			return false
+		}
+		j := bsearch16(except, rr)
+		return j >= len(except) || except[j] != rr
+	}
+
+	rr, rang, except := uint32(r), range32, except32
+	i := bsearch32(rang, rr)
+	if i >= len(rang) || rr < rang[i&^1] || rang[i|1] < rr {
+		return false
+	}
+	j := bsearch32(except, rr)
+	return j >= len(except) || except[j] != rr
+}
+
+func scan(min, max rune) (rang, except []uint32) {
+	lo := rune(-1)
+	for i := min; ; i++ {
+		if (i > max || !unicode.IsPrint(i)) && lo >= 0 {
+			// End range, but avoid flip flop.
+			if i+1 <= max && unicode.IsPrint(i+1) {
+				except = append(except, uint32(i))
+				continue
+			}
+			rang = append(rang, uint32(lo), uint32(i-1))
+			lo = -1
+		}
+		if i > max {
+			break
+		}
+		if lo < 0 && unicode.IsPrint(i) {
+			lo = i
+		}
+	}
+	return
+}
+
+func to16(x []uint32) []uint16 {
+	var y []uint16
+	for _, v := range x {
+		if uint32(uint16(v)) != v {
+			panic("bad 32->16 conversion")
+		}
+		y = append(y, uint16(v))
+	}
+	return y
+}
+
+func main() {
+	flag.Parse()
+
+	rang, except := scan(0, 0xFFFF)
+	range16 = to16(rang)
+	except16 = to16(except)
+	range32, except32 = scan(0x10000, unicode.MaxRune)
+
+	for i := rune(0); i <= unicode.MaxRune; i++ {
+		if isPrint(i) != unicode.IsPrint(i) {
+			log.Fatalf("%U: isPrint=%v, want %v\n", i, isPrint(i), unicode.IsPrint(i))
+		}
+	}
+
+	var buf bytes.Buffer
+
+	fmt.Fprintf(&buf, `// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.`+"\n\n")
+	fmt.Fprintf(&buf, "// DO NOT EDIT.  GENERATED BY\n")
+	fmt.Fprintf(&buf, "//     go run makeisprint.go -output isprint.go\n\n")
+	fmt.Fprintf(&buf, "package strconv\n\n")
+
+	fmt.Fprintf(&buf, "// (%d+%d+%d)*2 + (%d)*4 = %d bytes\n\n",
+		len(range16), len(except16), len(except32),
+		len(range32),
+		(len(range16)+len(except16)+len(except32))*2+
+			(len(range32))*4)
+
+	fmt.Fprintf(&buf, "var isPrint16 = []uint16{\n")
+	for i := 0; i < len(range16); i += 2 {
+		fmt.Fprintf(&buf, "\t%#04x, %#04x,\n", range16[i], range16[i+1])
+	}
+	fmt.Fprintf(&buf, "}\n\n")
+
+	fmt.Fprintf(&buf, "var isNotPrint16 = []uint16{\n")
+	for _, r := range except16 {
+		fmt.Fprintf(&buf, "\t%#04x,\n", r)
+	}
+	fmt.Fprintf(&buf, "}\n\n")
+
+	fmt.Fprintf(&buf, "var isPrint32 = []uint32{\n")
+	for i := 0; i < len(range32); i += 2 {
+		fmt.Fprintf(&buf, "\t%#06x, %#06x,\n", range32[i], range32[i+1])
+	}
+	fmt.Fprintf(&buf, "}\n\n")
+
+	fmt.Fprintf(&buf, "var isNotPrint32 = []uint16{ // add 0x10000 to each entry\n")
+	for _, r := range except32 {
+		if r >= 0x20000 {
+			log.Fatalf("%U too big for isNotPrint32\n", r)
+		}
+		fmt.Fprintf(&buf, "\t%#04x,\n", r-0x10000)
+	}
+	fmt.Fprintf(&buf, "}\n")
+
+	data, err := format.Source(buf.Bytes())
+	if err != nil {
+		log.Fatal(err)
+	}
+	err = ioutil.WriteFile(*filename, data, 0644)
+	if err != nil {
+		log.Fatal(err)
+	}
+}
diff --git a/src/strconv/quote.go b/src/strconv/quote.go
new file mode 100644
index 0000000..53d51b5
--- /dev/null
+++ b/src/strconv/quote.go
@@ -0,0 +1,455 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:generate go run makeisprint.go -output isprint.go
+
+package strconv
+
+import (
+	"unicode/utf8"
+)
+
+const lowerhex = "0123456789abcdef"
+
+func quoteWith(s string, quote byte, ASCIIonly bool) string {
+	var runeTmp [utf8.UTFMax]byte
+	buf := make([]byte, 0, 3*len(s)/2) // Try to avoid more allocations.
+	buf = append(buf, quote)
+	for width := 0; len(s) > 0; s = s[width:] {
+		r := rune(s[0])
+		width = 1
+		if r >= utf8.RuneSelf {
+			r, width = utf8.DecodeRuneInString(s)
+		}
+		if width == 1 && r == utf8.RuneError {
+			buf = append(buf, `\x`...)
+			buf = append(buf, lowerhex[s[0]>>4])
+			buf = append(buf, lowerhex[s[0]&0xF])
+			continue
+		}
+		if r == rune(quote) || r == '\\' { // always backslashed
+			buf = append(buf, '\\')
+			buf = append(buf, byte(r))
+			continue
+		}
+		if ASCIIonly {
+			if r < utf8.RuneSelf && IsPrint(r) {
+				buf = append(buf, byte(r))
+				continue
+			}
+		} else if IsPrint(r) {
+			n := utf8.EncodeRune(runeTmp[:], r)
+			buf = append(buf, runeTmp[:n]...)
+			continue
+		}
+		switch r {
+		case '\a':
+			buf = append(buf, `\a`...)
+		case '\b':
+			buf = append(buf, `\b`...)
+		case '\f':
+			buf = append(buf, `\f`...)
+		case '\n':
+			buf = append(buf, `\n`...)
+		case '\r':
+			buf = append(buf, `\r`...)
+		case '\t':
+			buf = append(buf, `\t`...)
+		case '\v':
+			buf = append(buf, `\v`...)
+		default:
+			switch {
+			case r < ' ':
+				buf = append(buf, `\x`...)
+				buf = append(buf, lowerhex[s[0]>>4])
+				buf = append(buf, lowerhex[s[0]&0xF])
+			case r > utf8.MaxRune:
+				r = 0xFFFD
+				fallthrough
+			case r < 0x10000:
+				buf = append(buf, `\u`...)
+				for s := 12; s >= 0; s -= 4 {
+					buf = append(buf, lowerhex[r>>uint(s)&0xF])
+				}
+			default:
+				buf = append(buf, `\U`...)
+				for s := 28; s >= 0; s -= 4 {
+					buf = append(buf, lowerhex[r>>uint(s)&0xF])
+				}
+			}
+		}
+	}
+	buf = append(buf, quote)
+	return string(buf)
+
+}
+
+// Quote returns a double-quoted Go string literal representing s.  The
+// returned string uses Go escape sequences (\t, \n, \xFF, \u0100) for
+// control characters and non-printable characters as defined by
+// IsPrint.
+func Quote(s string) string {
+	return quoteWith(s, '"', false)
+}
+
+// AppendQuote appends a double-quoted Go string literal representing s,
+// as generated by Quote, to dst and returns the extended buffer.
+func AppendQuote(dst []byte, s string) []byte {
+	return append(dst, Quote(s)...)
+}
+
+// QuoteToASCII returns a double-quoted Go string literal representing s.
+// The returned string uses Go escape sequences (\t, \n, \xFF, \u0100) for
+// non-ASCII characters and non-printable characters as defined by IsPrint.
+func QuoteToASCII(s string) string {
+	return quoteWith(s, '"', true)
+}
+
+// AppendQuoteToASCII appends a double-quoted Go string literal representing s,
+// as generated by QuoteToASCII, to dst and returns the extended buffer.
+func AppendQuoteToASCII(dst []byte, s string) []byte {
+	return append(dst, QuoteToASCII(s)...)
+}
+
+// QuoteRune returns a single-quoted Go character literal representing the
+// rune.  The returned string uses Go escape sequences (\t, \n, \xFF, \u0100)
+// for control characters and non-printable characters as defined by IsPrint.
+func QuoteRune(r rune) string {
+	// TODO: avoid the allocation here.
+	return quoteWith(string(r), '\'', false)
+}
+
+// AppendQuoteRune appends a single-quoted Go character literal representing the rune,
+// as generated by QuoteRune, to dst and returns the extended buffer.
+func AppendQuoteRune(dst []byte, r rune) []byte {
+	return append(dst, QuoteRune(r)...)
+}
+
+// QuoteRuneToASCII returns a single-quoted Go character literal representing
+// the rune.  The returned string uses Go escape sequences (\t, \n, \xFF,
+// \u0100) for non-ASCII characters and non-printable characters as defined
+// by IsPrint.
+func QuoteRuneToASCII(r rune) string {
+	// TODO: avoid the allocation here.
+	return quoteWith(string(r), '\'', true)
+}
+
+// AppendQuoteRuneToASCII appends a single-quoted Go character literal representing the rune,
+// as generated by QuoteRuneToASCII, to dst and returns the extended buffer.
+func AppendQuoteRuneToASCII(dst []byte, r rune) []byte {
+	return append(dst, QuoteRuneToASCII(r)...)
+}
+
+// CanBackquote reports whether the string s can be represented
+// unchanged as a single-line backquoted string without control
+// characters other than tab.
+func CanBackquote(s string) bool {
+	for len(s) > 0 {
+		r, wid := utf8.DecodeRuneInString(s)
+		s = s[wid:]
+		if wid > 1 {
+			if r == '\ufeff' {
+				return false // BOMs are invisible and should not be quoted.
+			}
+			continue // All other multibyte runes are correctly encoded and assumed printable.
+		}
+		if r == utf8.RuneError {
+			return false
+		}
+		if (r < ' ' && r != '\t') || r == '`' || r == '\u007F' {
+			return false
+		}
+	}
+	return true
+}
+
+func unhex(b byte) (v rune, ok bool) {
+	c := rune(b)
+	switch {
+	case '0' <= c && c <= '9':
+		return c - '0', true
+	case 'a' <= c && c <= 'f':
+		return c - 'a' + 10, true
+	case 'A' <= c && c <= 'F':
+		return c - 'A' + 10, true
+	}
+	return
+}
+
+// UnquoteChar decodes the first character or byte in the escaped string
+// or character literal represented by the string s.
+// It returns four values:
+//
+//	1) value, the decoded Unicode code point or byte value;
+//	2) multibyte, a boolean indicating whether the decoded character requires a multibyte UTF-8 representation;
+//	3) tail, the remainder of the string after the character; and
+//	4) an error that will be nil if the character is syntactically valid.
+//
+// The second argument, quote, specifies the type of literal being parsed
+// and therefore which escaped quote character is permitted.
+// If set to a single quote, it permits the sequence \' and disallows unescaped '.
+// If set to a double quote, it permits \" and disallows unescaped ".
+// If set to zero, it does not permit either escape and allows both quote characters to appear unescaped.
+func UnquoteChar(s string, quote byte) (value rune, multibyte bool, tail string, err error) {
+	// easy cases
+	switch c := s[0]; {
+	case c == quote && (quote == '\'' || quote == '"'):
+		err = ErrSyntax
+		return
+	case c >= utf8.RuneSelf:
+		r, size := utf8.DecodeRuneInString(s)
+		return r, true, s[size:], nil
+	case c != '\\':
+		return rune(s[0]), false, s[1:], nil
+	}
+
+	// hard case: c is backslash
+	if len(s) <= 1 {
+		err = ErrSyntax
+		return
+	}
+	c := s[1]
+	s = s[2:]
+
+	switch c {
+	case 'a':
+		value = '\a'
+	case 'b':
+		value = '\b'
+	case 'f':
+		value = '\f'
+	case 'n':
+		value = '\n'
+	case 'r':
+		value = '\r'
+	case 't':
+		value = '\t'
+	case 'v':
+		value = '\v'
+	case 'x', 'u', 'U':
+		n := 0
+		switch c {
+		case 'x':
+			n = 2
+		case 'u':
+			n = 4
+		case 'U':
+			n = 8
+		}
+		var v rune
+		if len(s) < n {
+			err = ErrSyntax
+			return
+		}
+		for j := 0; j < n; j++ {
+			x, ok := unhex(s[j])
+			if !ok {
+				err = ErrSyntax
+				return
+			}
+			v = v<<4 | x
+		}
+		s = s[n:]
+		if c == 'x' {
+			// single-byte string, possibly not UTF-8
+			value = v
+			break
+		}
+		if v > utf8.MaxRune {
+			err = ErrSyntax
+			return
+		}
+		value = v
+		multibyte = true
+	case '0', '1', '2', '3', '4', '5', '6', '7':
+		v := rune(c) - '0'
+		if len(s) < 2 {
+			err = ErrSyntax
+			return
+		}
+		for j := 0; j < 2; j++ { // one digit already; two more
+			x := rune(s[j]) - '0'
+			if x < 0 || x > 7 {
+				err = ErrSyntax
+				return
+			}
+			v = (v << 3) | x
+		}
+		s = s[2:]
+		if v > 255 {
+			err = ErrSyntax
+			return
+		}
+		value = v
+	case '\\':
+		value = '\\'
+	case '\'', '"':
+		if c != quote {
+			err = ErrSyntax
+			return
+		}
+		value = rune(c)
+	default:
+		err = ErrSyntax
+		return
+	}
+	tail = s
+	return
+}
+
+// Unquote interprets s as a single-quoted, double-quoted,
+// or backquoted Go string literal, returning the string value
+// that s quotes.  (If s is single-quoted, it would be a Go
+// character literal; Unquote returns the corresponding
+// one-character string.)
+func Unquote(s string) (t string, err error) {
+	n := len(s)
+	if n < 2 {
+		return "", ErrSyntax
+	}
+	quote := s[0]
+	if quote != s[n-1] {
+		return "", ErrSyntax
+	}
+	s = s[1 : n-1]
+
+	if quote == '`' {
+		if contains(s, '`') {
+			return "", ErrSyntax
+		}
+		return s, nil
+	}
+	if quote != '"' && quote != '\'' {
+		return "", ErrSyntax
+	}
+	if contains(s, '\n') {
+		return "", ErrSyntax
+	}
+
+	// Is it trivial?  Avoid allocation.
+	if !contains(s, '\\') && !contains(s, quote) {
+		switch quote {
+		case '"':
+			return s, nil
+		case '\'':
+			r, size := utf8.DecodeRuneInString(s)
+			if size == len(s) && (r != utf8.RuneError || size != 1) {
+				return s, nil
+			}
+		}
+	}
+
+	var runeTmp [utf8.UTFMax]byte
+	buf := make([]byte, 0, 3*len(s)/2) // Try to avoid more allocations.
+	for len(s) > 0 {
+		c, multibyte, ss, err := UnquoteChar(s, quote)
+		if err != nil {
+			return "", err
+		}
+		s = ss
+		if c < utf8.RuneSelf || !multibyte {
+			buf = append(buf, byte(c))
+		} else {
+			n := utf8.EncodeRune(runeTmp[:], c)
+			buf = append(buf, runeTmp[:n]...)
+		}
+		if quote == '\'' && len(s) != 0 {
+			// single-quoted must be single character
+			return "", ErrSyntax
+		}
+	}
+	return string(buf), nil
+}
+
+// contains reports whether the string contains the byte c.
+func contains(s string, c byte) bool {
+	for i := 0; i < len(s); i++ {
+		if s[i] == c {
+			return true
+		}
+	}
+	return false
+}
+
+// bsearch16 returns the smallest i such that a[i] >= x.
+// If there is no such i, bsearch16 returns len(a).
+func bsearch16(a []uint16, x uint16) int {
+	i, j := 0, len(a)
+	for i < j {
+		h := i + (j-i)/2
+		if a[h] < x {
+			i = h + 1
+		} else {
+			j = h
+		}
+	}
+	return i
+}
+
+// bsearch32 returns the smallest i such that a[i] >= x.
+// If there is no such i, bsearch32 returns len(a).
+func bsearch32(a []uint32, x uint32) int {
+	i, j := 0, len(a)
+	for i < j {
+		h := i + (j-i)/2
+		if a[h] < x {
+			i = h + 1
+		} else {
+			j = h
+		}
+	}
+	return i
+}
+
+// TODO: IsPrint is a local implementation of unicode.IsPrint, verified by the tests
+// to give the same answer. It allows this package not to depend on unicode,
+// and therefore not pull in all the Unicode tables. If the linker were better
+// at tossing unused tables, we could get rid of this implementation.
+// That would be nice.
+
+// IsPrint reports whether the rune is defined as printable by Go, with
+// the same definition as unicode.IsPrint: letters, numbers, punctuation,
+// symbols and ASCII space.
+func IsPrint(r rune) bool {
+	// Fast check for Latin-1
+	if r <= 0xFF {
+		if 0x20 <= r && r <= 0x7E {
+			// All the ASCII is printable from space through DEL-1.
+			return true
+		}
+		if 0xA1 <= r && r <= 0xFF {
+			// Similarly for ¡ through ÿ...
+			return r != 0xAD // ...except for the bizarre soft hyphen.
+		}
+		return false
+	}
+
+	// Same algorithm, either on uint16 or uint32 value.
+	// First, find first i such that isPrint[i] >= x.
+	// This is the index of either the start or end of a pair that might span x.
+	// The start is even (isPrint[i&^1]) and the end is odd (isPrint[i|1]).
+	// If we find x in a range, make sure x is not in isNotPrint list.
+
+	if 0 <= r && r < 1<<16 {
+		rr, isPrint, isNotPrint := uint16(r), isPrint16, isNotPrint16
+		i := bsearch16(isPrint, rr)
+		if i >= len(isPrint) || rr < isPrint[i&^1] || isPrint[i|1] < rr {
+			return false
+		}
+		j := bsearch16(isNotPrint, rr)
+		return j >= len(isNotPrint) || isNotPrint[j] != rr
+	}
+
+	rr, isPrint, isNotPrint := uint32(r), isPrint32, isNotPrint32
+	i := bsearch32(isPrint, rr)
+	if i >= len(isPrint) || rr < isPrint[i&^1] || isPrint[i|1] < rr {
+		return false
+	}
+	if r >= 0x20000 {
+		return true
+	}
+	r -= 0x10000
+	j := bsearch16(isNotPrint, uint16(r))
+	return j >= len(isNotPrint) || isNotPrint[j] != uint16(r)
+}
diff --git a/src/pkg/strconv/quote_example_test.go b/src/strconv/quote_example_test.go
similarity index 100%
rename from src/pkg/strconv/quote_example_test.go
rename to src/strconv/quote_example_test.go
diff --git a/src/strconv/quote_test.go b/src/strconv/quote_test.go
new file mode 100644
index 0000000..3bf162f
--- /dev/null
+++ b/src/strconv/quote_test.go
@@ -0,0 +1,266 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package strconv_test
+
+import (
+	. "strconv"
+	"testing"
+	"unicode"
+)
+
+// Verify that our isPrint agrees with unicode.IsPrint
+func TestIsPrint(t *testing.T) {
+	n := 0
+	for r := rune(0); r <= unicode.MaxRune; r++ {
+		if IsPrint(r) != unicode.IsPrint(r) {
+			t.Errorf("IsPrint(%U)=%t incorrect", r, IsPrint(r))
+			n++
+			if n > 10 {
+				return
+			}
+		}
+	}
+}
+
+type quoteTest struct {
+	in    string
+	out   string
+	ascii string
+}
+
+var quotetests = []quoteTest{
+	{"\a\b\f\r\n\t\v", `"\a\b\f\r\n\t\v"`, `"\a\b\f\r\n\t\v"`},
+	{"\\", `"\\"`, `"\\"`},
+	{"abc\xffdef", `"abc\xffdef"`, `"abc\xffdef"`},
+	{"\u263a", `"☺"`, `"\u263a"`},
+	{"\U0010ffff", `"\U0010ffff"`, `"\U0010ffff"`},
+	{"\x04", `"\x04"`, `"\x04"`},
+}
+
+func TestQuote(t *testing.T) {
+	for _, tt := range quotetests {
+		if out := Quote(tt.in); out != tt.out {
+			t.Errorf("Quote(%s) = %s, want %s", tt.in, out, tt.out)
+		}
+		if out := AppendQuote([]byte("abc"), tt.in); string(out) != "abc"+tt.out {
+			t.Errorf("AppendQuote(%q, %s) = %s, want %s", "abc", tt.in, out, "abc"+tt.out)
+		}
+	}
+}
+
+func TestQuoteToASCII(t *testing.T) {
+	for _, tt := range quotetests {
+		if out := QuoteToASCII(tt.in); out != tt.ascii {
+			t.Errorf("QuoteToASCII(%s) = %s, want %s", tt.in, out, tt.ascii)
+		}
+		if out := AppendQuoteToASCII([]byte("abc"), tt.in); string(out) != "abc"+tt.ascii {
+			t.Errorf("AppendQuoteToASCII(%q, %s) = %s, want %s", "abc", tt.in, out, "abc"+tt.ascii)
+		}
+	}
+}
+
+type quoteRuneTest struct {
+	in    rune
+	out   string
+	ascii string
+}
+
+var quoterunetests = []quoteRuneTest{
+	{'a', `'a'`, `'a'`},
+	{'\a', `'\a'`, `'\a'`},
+	{'\\', `'\\'`, `'\\'`},
+	{0xFF, `'ÿ'`, `'\u00ff'`},
+	{0x263a, `'☺'`, `'\u263a'`},
+	{0xfffd, `'�'`, `'\ufffd'`},
+	{0x0010ffff, `'\U0010ffff'`, `'\U0010ffff'`},
+	{0x0010ffff + 1, `'�'`, `'\ufffd'`},
+	{0x04, `'\x04'`, `'\x04'`},
+}
+
+func TestQuoteRune(t *testing.T) {
+	for _, tt := range quoterunetests {
+		if out := QuoteRune(tt.in); out != tt.out {
+			t.Errorf("QuoteRune(%U) = %s, want %s", tt.in, out, tt.out)
+		}
+		if out := AppendQuoteRune([]byte("abc"), tt.in); string(out) != "abc"+tt.out {
+			t.Errorf("AppendQuoteRune(%q, %U) = %s, want %s", "abc", tt.in, out, "abc"+tt.out)
+		}
+	}
+}
+
+func TestQuoteRuneToASCII(t *testing.T) {
+	for _, tt := range quoterunetests {
+		if out := QuoteRuneToASCII(tt.in); out != tt.ascii {
+			t.Errorf("QuoteRuneToASCII(%U) = %s, want %s", tt.in, out, tt.ascii)
+		}
+		if out := AppendQuoteRuneToASCII([]byte("abc"), tt.in); string(out) != "abc"+tt.ascii {
+			t.Errorf("AppendQuoteRuneToASCII(%q, %U) = %s, want %s", "abc", tt.in, out, "abc"+tt.ascii)
+		}
+	}
+}
+
+type canBackquoteTest struct {
+	in  string
+	out bool
+}
+
+var canbackquotetests = []canBackquoteTest{
+	{"`", false},
+	{string(0), false},
+	{string(1), false},
+	{string(2), false},
+	{string(3), false},
+	{string(4), false},
+	{string(5), false},
+	{string(6), false},
+	{string(7), false},
+	{string(8), false},
+	{string(9), true}, // \t
+	{string(10), false},
+	{string(11), false},
+	{string(12), false},
+	{string(13), false},
+	{string(14), false},
+	{string(15), false},
+	{string(16), false},
+	{string(17), false},
+	{string(18), false},
+	{string(19), false},
+	{string(20), false},
+	{string(21), false},
+	{string(22), false},
+	{string(23), false},
+	{string(24), false},
+	{string(25), false},
+	{string(26), false},
+	{string(27), false},
+	{string(28), false},
+	{string(29), false},
+	{string(30), false},
+	{string(31), false},
+	{string(0x7F), false},
+	{`' !"#$%&'()*+,-./:;<=>?@[\]^_{|}~`, true},
+	{`0123456789`, true},
+	{`ABCDEFGHIJKLMNOPQRSTUVWXYZ`, true},
+	{`abcdefghijklmnopqrstuvwxyz`, true},
+	{`☺`, true},
+	{"\x80", false},
+	{"a\xe0\xa0z", false},
+	{"\ufeffabc", false},
+	{"a\ufeffz", false},
+}
+
+func TestCanBackquote(t *testing.T) {
+	for _, tt := range canbackquotetests {
+		if out := CanBackquote(tt.in); out != tt.out {
+			t.Errorf("CanBackquote(%q) = %v, want %v", tt.in, out, tt.out)
+		}
+	}
+}
+
+type unQuoteTest struct {
+	in  string
+	out string
+}
+
+var unquotetests = []unQuoteTest{
+	{`""`, ""},
+	{`"a"`, "a"},
+	{`"abc"`, "abc"},
+	{`"☺"`, "☺"},
+	{`"hello world"`, "hello world"},
+	{`"\xFF"`, "\xFF"},
+	{`"\377"`, "\377"},
+	{`"\u1234"`, "\u1234"},
+	{`"\U00010111"`, "\U00010111"},
+	{`"\U0001011111"`, "\U0001011111"},
+	{`"\a\b\f\n\r\t\v\\\""`, "\a\b\f\n\r\t\v\\\""},
+	{`"'"`, "'"},
+
+	{`'a'`, "a"},
+	{`'☹'`, "☹"},
+	{`'\a'`, "\a"},
+	{`'\x10'`, "\x10"},
+	{`'\377'`, "\377"},
+	{`'\u1234'`, "\u1234"},
+	{`'\U00010111'`, "\U00010111"},
+	{`'\t'`, "\t"},
+	{`' '`, " "},
+	{`'\''`, "'"},
+	{`'"'`, "\""},
+
+	{"``", ``},
+	{"`a`", `a`},
+	{"`abc`", `abc`},
+	{"`☺`", `☺`},
+	{"`hello world`", `hello world`},
+	{"`\\xFF`", `\xFF`},
+	{"`\\377`", `\377`},
+	{"`\\`", `\`},
+	{"`\n`", "\n"},
+	{"`	`", `	`},
+	{"` `", ` `},
+}
+
+var misquoted = []string{
+	``,
+	`"`,
+	`"a`,
+	`"'`,
+	`b"`,
+	`"\"`,
+	`"\9"`,
+	`"\19"`,
+	`"\129"`,
+	`'\'`,
+	`'\9'`,
+	`'\19'`,
+	`'\129'`,
+	`'ab'`,
+	`"\x1!"`,
+	`"\U12345678"`,
+	`"\z"`,
+	"`",
+	"`xxx",
+	"`\"",
+	`"\'"`,
+	`'\"'`,
+	"\"\n\"",
+	"\"\\n\n\"",
+	"'\n'",
+}
+
+func TestUnquote(t *testing.T) {
+	for _, tt := range unquotetests {
+		if out, err := Unquote(tt.in); err != nil && out != tt.out {
+			t.Errorf("Unquote(%#q) = %q, %v want %q, nil", tt.in, out, err, tt.out)
+		}
+	}
+
+	// run the quote tests too, backward
+	for _, tt := range quotetests {
+		if in, err := Unquote(tt.out); in != tt.in {
+			t.Errorf("Unquote(%#q) = %q, %v, want %q, nil", tt.out, in, err, tt.in)
+		}
+	}
+
+	for _, s := range misquoted {
+		if out, err := Unquote(s); out != "" || err != ErrSyntax {
+			t.Errorf("Unquote(%#q) = %q, %v want %q, %v", s, out, err, "", ErrSyntax)
+		}
+	}
+}
+
+func BenchmarkUnquoteEasy(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		Unquote(`"Give me a rock, paper and scissors and I will move the world."`)
+	}
+}
+
+func BenchmarkUnquoteHard(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		Unquote(`"\x47ive me a \x72ock, \x70aper and \x73cissors and \x49 will move the world."`)
+	}
+}
diff --git a/src/pkg/strconv/strconv_test.go b/src/strconv/strconv_test.go
similarity index 100%
rename from src/pkg/strconv/strconv_test.go
rename to src/strconv/strconv_test.go
diff --git a/src/pkg/strconv/testdata/testfp.txt b/src/strconv/testdata/testfp.txt
similarity index 100%
rename from src/pkg/strconv/testdata/testfp.txt
rename to src/strconv/testdata/testfp.txt
diff --git a/src/pkg/strings/example_test.go b/src/strings/example_test.go
similarity index 100%
rename from src/pkg/strings/example_test.go
rename to src/strings/example_test.go
diff --git a/src/pkg/strings/export_test.go b/src/strings/export_test.go
similarity index 100%
rename from src/pkg/strings/export_test.go
rename to src/strings/export_test.go
diff --git a/src/pkg/strings/reader.go b/src/strings/reader.go
similarity index 100%
rename from src/pkg/strings/reader.go
rename to src/strings/reader.go
diff --git a/src/pkg/strings/reader_test.go b/src/strings/reader_test.go
similarity index 100%
rename from src/pkg/strings/reader_test.go
rename to src/strings/reader_test.go
diff --git a/src/strings/replace.go b/src/strings/replace.go
new file mode 100644
index 0000000..4752641
--- /dev/null
+++ b/src/strings/replace.go
@@ -0,0 +1,518 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package strings
+
+import "io"
+
+// Replacer replaces a list of strings with replacements.
+// It is safe for concurrent use by multiple goroutines.
+type Replacer struct {
+	r replacer
+}
+
+// replacer is the interface that a replacement algorithm needs to implement.
+type replacer interface {
+	Replace(s string) string
+	WriteString(w io.Writer, s string) (n int, err error)
+}
+
+// NewReplacer returns a new Replacer from a list of old, new string pairs.
+// Replacements are performed in order, without overlapping matches.
+func NewReplacer(oldnew ...string) *Replacer {
+	if len(oldnew)%2 == 1 {
+		panic("strings.NewReplacer: odd argument count")
+	}
+
+	if len(oldnew) == 2 && len(oldnew[0]) > 1 {
+		return &Replacer{r: makeSingleStringReplacer(oldnew[0], oldnew[1])}
+	}
+
+	allNewBytes := true
+	for i := 0; i < len(oldnew); i += 2 {
+		if len(oldnew[i]) != 1 {
+			return &Replacer{r: makeGenericReplacer(oldnew)}
+		}
+		if len(oldnew[i+1]) != 1 {
+			allNewBytes = false
+		}
+	}
+
+	if allNewBytes {
+		r := byteReplacer{}
+		for i := range r {
+			r[i] = byte(i)
+		}
+		// The first occurrence of old->new map takes precedence
+		// over the others with the same old string.
+		for i := len(oldnew) - 2; i >= 0; i -= 2 {
+			o := oldnew[i][0]
+			n := oldnew[i+1][0]
+			r[o] = n
+		}
+		return &Replacer{r: &r}
+	}
+
+	r := byteStringReplacer{}
+	// The first occurrence of old->new map takes precedence
+	// over the others with the same old string.
+	for i := len(oldnew) - 2; i >= 0; i -= 2 {
+		o := oldnew[i][0]
+		n := oldnew[i+1]
+		r[o] = []byte(n)
+	}
+	return &Replacer{r: &r}
+}
+
+// Replace returns a copy of s with all replacements performed.
+func (r *Replacer) Replace(s string) string {
+	return r.r.Replace(s)
+}
+
+// WriteString writes s to w with all replacements performed.
+func (r *Replacer) WriteString(w io.Writer, s string) (n int, err error) {
+	return r.r.WriteString(w, s)
+}
+
+// trieNode is a node in a lookup trie for prioritized key/value pairs. Keys
+// and values may be empty. For example, the trie containing keys "ax", "ay",
+// "bcbc", "x" and "xy" could have eight nodes:
+//
+//  n0  -
+//  n1  a-
+//  n2  .x+
+//  n3  .y+
+//  n4  b-
+//  n5  .cbc+
+//  n6  x+
+//  n7  .y+
+//
+// n0 is the root node, and its children are n1, n4 and n6; n1's children are
+// n2 and n3; n4's child is n5; n6's child is n7. Nodes n0, n1 and n4 (marked
+// with a trailing "-") are partial keys, and nodes n2, n3, n5, n6 and n7
+// (marked with a trailing "+") are complete keys.
+type trieNode struct {
+	// value is the value of the trie node's key/value pair. It is empty if
+	// this node is not a complete key.
+	value string
+	// priority is the priority (higher is more important) of the trie node's
+	// key/value pair; keys are not necessarily matched shortest- or longest-
+	// first. Priority is positive if this node is a complete key, and zero
+	// otherwise. In the example above, positive/zero priorities are marked
+	// with a trailing "+" or "-".
+	priority int
+
+	// A trie node may have zero, one or more child nodes:
+	//  * if the remaining fields are zero, there are no children.
+	//  * if prefix and next are non-zero, there is one child in next.
+	//  * if table is non-zero, it defines all the children.
+	//
+	// Prefixes are preferred over tables when there is one child, but the
+	// root node always uses a table for lookup efficiency.
+
+	// prefix is the difference in keys between this trie node and the next.
+	// In the example above, node n4 has prefix "cbc" and n4's next node is n5.
+	// Node n5 has no children and so has zero prefix, next and table fields.
+	prefix string
+	next   *trieNode
+
+	// table is a lookup table indexed by the next byte in the key, after
+	// remapping that byte through genericReplacer.mapping to create a dense
+	// index. In the example above, the keys only use 'a', 'b', 'c', 'x' and
+	// 'y', which remap to 0, 1, 2, 3 and 4. All other bytes remap to 5, and
+	// genericReplacer.tableSize will be 5. Node n0's table will be
+	// []*trieNode{ 0:n1, 1:n4, 3:n6 }, where the 0, 1 and 3 are the remapped
+	// 'a', 'b' and 'x'.
+	table []*trieNode
+}
+
+func (t *trieNode) add(key, val string, priority int, r *genericReplacer) {
+	if key == "" {
+		if t.priority == 0 {
+			t.value = val
+			t.priority = priority
+		}
+		return
+	}
+
+	if t.prefix != "" {
+		// Need to split the prefix among multiple nodes.
+		var n int // length of the longest common prefix
+		for ; n < len(t.prefix) && n < len(key); n++ {
+			if t.prefix[n] != key[n] {
+				break
+			}
+		}
+		if n == len(t.prefix) {
+			t.next.add(key[n:], val, priority, r)
+		} else if n == 0 {
+			// First byte differs, start a new lookup table here. Looking up
+			// what is currently t.prefix[0] will lead to prefixNode, and
+			// looking up key[0] will lead to keyNode.
+			var prefixNode *trieNode
+			if len(t.prefix) == 1 {
+				prefixNode = t.next
+			} else {
+				prefixNode = &trieNode{
+					prefix: t.prefix[1:],
+					next:   t.next,
+				}
+			}
+			keyNode := new(trieNode)
+			t.table = make([]*trieNode, r.tableSize)
+			t.table[r.mapping[t.prefix[0]]] = prefixNode
+			t.table[r.mapping[key[0]]] = keyNode
+			t.prefix = ""
+			t.next = nil
+			keyNode.add(key[1:], val, priority, r)
+		} else {
+			// Insert new node after the common section of the prefix.
+			next := &trieNode{
+				prefix: t.prefix[n:],
+				next:   t.next,
+			}
+			t.prefix = t.prefix[:n]
+			t.next = next
+			next.add(key[n:], val, priority, r)
+		}
+	} else if t.table != nil {
+		// Insert into existing table.
+		m := r.mapping[key[0]]
+		if t.table[m] == nil {
+			t.table[m] = new(trieNode)
+		}
+		t.table[m].add(key[1:], val, priority, r)
+	} else {
+		t.prefix = key
+		t.next = new(trieNode)
+		t.next.add("", val, priority, r)
+	}
+}
+
+func (r *genericReplacer) lookup(s string, ignoreRoot bool) (val string, keylen int, found bool) {
+	// Iterate down the trie to the end, and grab the value and keylen with
+	// the highest priority.
+	bestPriority := 0
+	node := &r.root
+	n := 0
+	for node != nil {
+		if node.priority > bestPriority && !(ignoreRoot && node == &r.root) {
+			bestPriority = node.priority
+			val = node.value
+			keylen = n
+			found = true
+		}
+
+		if s == "" {
+			break
+		}
+		if node.table != nil {
+			index := r.mapping[s[0]]
+			if int(index) == r.tableSize {
+				break
+			}
+			node = node.table[index]
+			s = s[1:]
+			n++
+		} else if node.prefix != "" && HasPrefix(s, node.prefix) {
+			n += len(node.prefix)
+			s = s[len(node.prefix):]
+			node = node.next
+		} else {
+			break
+		}
+	}
+	return
+}
+
+// genericReplacer is the fully generic algorithm.
+// It's used as a fallback when nothing faster can be used.
+type genericReplacer struct {
+	root trieNode
+	// tableSize is the size of a trie node's lookup table. It is the number
+	// of unique key bytes.
+	tableSize int
+	// mapping maps from key bytes to a dense index for trieNode.table.
+	mapping [256]byte
+}
+
+func makeGenericReplacer(oldnew []string) *genericReplacer {
+	r := new(genericReplacer)
+	// Find each byte used, then assign them each an index.
+	for i := 0; i < len(oldnew); i += 2 {
+		key := oldnew[i]
+		for j := 0; j < len(key); j++ {
+			r.mapping[key[j]] = 1
+		}
+	}
+
+	for _, b := range r.mapping {
+		r.tableSize += int(b)
+	}
+
+	var index byte
+	for i, b := range r.mapping {
+		if b == 0 {
+			r.mapping[i] = byte(r.tableSize)
+		} else {
+			r.mapping[i] = index
+			index++
+		}
+	}
+	// Ensure root node uses a lookup table (for performance).
+	r.root.table = make([]*trieNode, r.tableSize)
+
+	for i := 0; i < len(oldnew); i += 2 {
+		r.root.add(oldnew[i], oldnew[i+1], len(oldnew)-i, r)
+	}
+	return r
+}
+
+type appendSliceWriter []byte
+
+// Write writes to the buffer to satisfy io.Writer.
+func (w *appendSliceWriter) Write(p []byte) (int, error) {
+	*w = append(*w, p...)
+	return len(p), nil
+}
+
+// WriteString writes to the buffer without string->[]byte->string allocations.
+func (w *appendSliceWriter) WriteString(s string) (int, error) {
+	*w = append(*w, s...)
+	return len(s), nil
+}
+
+type stringWriterIface interface {
+	WriteString(string) (int, error)
+}
+
+type stringWriter struct {
+	w io.Writer
+}
+
+func (w stringWriter) WriteString(s string) (int, error) {
+	return w.w.Write([]byte(s))
+}
+
+func getStringWriter(w io.Writer) stringWriterIface {
+	sw, ok := w.(stringWriterIface)
+	if !ok {
+		sw = stringWriter{w}
+	}
+	return sw
+}
+
+func (r *genericReplacer) Replace(s string) string {
+	buf := make(appendSliceWriter, 0, len(s))
+	r.WriteString(&buf, s)
+	return string(buf)
+}
+
+func (r *genericReplacer) WriteString(w io.Writer, s string) (n int, err error) {
+	sw := getStringWriter(w)
+	var last, wn int
+	var prevMatchEmpty bool
+	for i := 0; i <= len(s); {
+		// Fast path: s[i] is not a prefix of any pattern.
+		if i != len(s) && r.root.priority == 0 {
+			index := int(r.mapping[s[i]])
+			if index == r.tableSize || r.root.table[index] == nil {
+				i++
+				continue
+			}
+		}
+
+		// Ignore the empty match iff the previous loop found the empty match.
+		val, keylen, match := r.lookup(s[i:], prevMatchEmpty)
+		prevMatchEmpty = match && keylen == 0
+		if match {
+			wn, err = sw.WriteString(s[last:i])
+			n += wn
+			if err != nil {
+				return
+			}
+			wn, err = sw.WriteString(val)
+			n += wn
+			if err != nil {
+				return
+			}
+			i += keylen
+			last = i
+			continue
+		}
+		i++
+	}
+	if last != len(s) {
+		wn, err = sw.WriteString(s[last:])
+		n += wn
+	}
+	return
+}
+
+// singleStringReplacer is the implementation that's used when there is only
+// one string to replace (and that string has more than one byte).
+type singleStringReplacer struct {
+	finder *stringFinder
+	// value is the new string that replaces that pattern when it's found.
+	value string
+}
+
+func makeSingleStringReplacer(pattern string, value string) *singleStringReplacer {
+	return &singleStringReplacer{finder: makeStringFinder(pattern), value: value}
+}
+
+func (r *singleStringReplacer) Replace(s string) string {
+	var buf []byte
+	i, matched := 0, false
+	for {
+		match := r.finder.next(s[i:])
+		if match == -1 {
+			break
+		}
+		matched = true
+		buf = append(buf, s[i:i+match]...)
+		buf = append(buf, r.value...)
+		i += match + len(r.finder.pattern)
+	}
+	if !matched {
+		return s
+	}
+	buf = append(buf, s[i:]...)
+	return string(buf)
+}
+
+func (r *singleStringReplacer) WriteString(w io.Writer, s string) (n int, err error) {
+	sw := getStringWriter(w)
+	var i, wn int
+	for {
+		match := r.finder.next(s[i:])
+		if match == -1 {
+			break
+		}
+		wn, err = sw.WriteString(s[i : i+match])
+		n += wn
+		if err != nil {
+			return
+		}
+		wn, err = sw.WriteString(r.value)
+		n += wn
+		if err != nil {
+			return
+		}
+		i += match + len(r.finder.pattern)
+	}
+	wn, err = sw.WriteString(s[i:])
+	n += wn
+	return
+}
+
+// byteReplacer is the implementation that's used when all the "old"
+// and "new" values are single ASCII bytes.
+// The array contains replacement bytes indexed by old byte.
+type byteReplacer [256]byte
+
+func (r *byteReplacer) Replace(s string) string {
+	var buf []byte // lazily allocated
+	for i := 0; i < len(s); i++ {
+		b := s[i]
+		if r[b] != b {
+			if buf == nil {
+				buf = []byte(s)
+			}
+			buf[i] = r[b]
+		}
+	}
+	if buf == nil {
+		return s
+	}
+	return string(buf)
+}
+
+func (r *byteReplacer) WriteString(w io.Writer, s string) (n int, err error) {
+	// TODO(bradfitz): use io.WriteString with slices of s, avoiding allocation.
+	bufsize := 32 << 10
+	if len(s) < bufsize {
+		bufsize = len(s)
+	}
+	buf := make([]byte, bufsize)
+
+	for len(s) > 0 {
+		ncopy := copy(buf, s[:])
+		s = s[ncopy:]
+		for i, b := range buf[:ncopy] {
+			buf[i] = r[b]
+		}
+		wn, err := w.Write(buf[:ncopy])
+		n += wn
+		if err != nil {
+			return n, err
+		}
+	}
+	return n, nil
+}
+
+// byteStringReplacer is the implementation that's used when all the
+// "old" values are single ASCII bytes but the "new" values vary in size.
+// The array contains replacement byte slices indexed by old byte.
+// A nil []byte means that the old byte should not be replaced.
+type byteStringReplacer [256][]byte
+
+func (r *byteStringReplacer) Replace(s string) string {
+	newSize := len(s)
+	anyChanges := false
+	for i := 0; i < len(s); i++ {
+		b := s[i]
+		if r[b] != nil {
+			anyChanges = true
+			// The -1 is because we are replacing 1 byte with len(r[b]) bytes.
+			newSize += len(r[b]) - 1
+		}
+	}
+	if !anyChanges {
+		return s
+	}
+	buf := make([]byte, newSize)
+	bi := buf
+	for i := 0; i < len(s); i++ {
+		b := s[i]
+		if r[b] != nil {
+			n := copy(bi, r[b])
+			bi = bi[n:]
+		} else {
+			bi[0] = b
+			bi = bi[1:]
+		}
+	}
+	return string(buf)
+}
+
+func (r *byteStringReplacer) WriteString(w io.Writer, s string) (n int, err error) {
+	sw := getStringWriter(w)
+	last := 0
+	for i := 0; i < len(s); i++ {
+		b := s[i]
+		if r[b] == nil {
+			continue
+		}
+		if last != i {
+			nw, err := sw.WriteString(s[last:i])
+			n += nw
+			if err != nil {
+				return n, err
+			}
+		}
+		last = i + 1
+		nw, err := w.Write(r[b])
+		n += nw
+		if err != nil {
+			return n, err
+		}
+	}
+	if last != len(s) {
+		var nw int
+		nw, err = sw.WriteString(s[last:])
+		n += nw
+	}
+	return
+}
diff --git a/src/strings/replace_test.go b/src/strings/replace_test.go
new file mode 100644
index 0000000..77e48b9
--- /dev/null
+++ b/src/strings/replace_test.go
@@ -0,0 +1,542 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package strings_test
+
+import (
+	"bytes"
+	"fmt"
+	. "strings"
+	"testing"
+)
+
+var htmlEscaper = NewReplacer(
+	"&", "&",
+	"<", "<",
+	">", ">",
+	`"`, """,
+	"'", "'",
+)
+
+var htmlUnescaper = NewReplacer(
+	"&", "&",
+	"<", "<",
+	">", ">",
+	""", `"`,
+	"'", "'",
+)
+
+// The http package's old HTML escaping function.
+func oldHTMLEscape(s string) string {
+	s = Replace(s, "&", "&", -1)
+	s = Replace(s, "<", "<", -1)
+	s = Replace(s, ">", ">", -1)
+	s = Replace(s, `"`, """, -1)
+	s = Replace(s, "'", "'", -1)
+	return s
+}
+
+var capitalLetters = NewReplacer("a", "A", "b", "B")
+
+// TestReplacer tests the replacer implementations.
+func TestReplacer(t *testing.T) {
+	type testCase struct {
+		r       *Replacer
+		in, out string
+	}
+	var testCases []testCase
+
+	// str converts 0xff to "\xff". This isn't just string(b) since that converts to UTF-8.
+	str := func(b byte) string {
+		return string([]byte{b})
+	}
+	var s []string
+
+	// inc maps "\x00"->"\x01", ..., "a"->"b", "b"->"c", ..., "\xff"->"\x00".
+	s = nil
+	for i := 0; i < 256; i++ {
+		s = append(s, str(byte(i)), str(byte(i+1)))
+	}
+	inc := NewReplacer(s...)
+
+	// Test cases with 1-byte old strings, 1-byte new strings.
+	testCases = append(testCases,
+		testCase{capitalLetters, "brad", "BrAd"},
+		testCase{capitalLetters, Repeat("a", (32<<10)+123), Repeat("A", (32<<10)+123)},
+		testCase{capitalLetters, "", ""},
+
+		testCase{inc, "brad", "csbe"},
+		testCase{inc, "\x00\xff", "\x01\x00"},
+		testCase{inc, "", ""},
+
+		testCase{NewReplacer("a", "1", "a", "2"), "brad", "br1d"},
+	)
+
+	// repeat maps "a"->"a", "b"->"bb", "c"->"ccc", ...
+	s = nil
+	for i := 0; i < 256; i++ {
+		n := i + 1 - 'a'
+		if n < 1 {
+			n = 1
+		}
+		s = append(s, str(byte(i)), Repeat(str(byte(i)), n))
+	}
+	repeat := NewReplacer(s...)
+
+	// Test cases with 1-byte old strings, variable length new strings.
+	testCases = append(testCases,
+		testCase{htmlEscaper, "No changes", "No changes"},
+		testCase{htmlEscaper, "I <3 escaping & stuff", "I <3 escaping & stuff"},
+		testCase{htmlEscaper, "&&&", "&&&"},
+		testCase{htmlEscaper, "", ""},
+
+		testCase{repeat, "brad", "bbrrrrrrrrrrrrrrrrrradddd"},
+		testCase{repeat, "abba", "abbbba"},
+		testCase{repeat, "", ""},
+
+		testCase{NewReplacer("a", "11", "a", "22"), "brad", "br11d"},
+	)
+
+	// The remaining test cases have variable length old strings.
+
+	testCases = append(testCases,
+		testCase{htmlUnescaper, "&amp;", "&"},
+		testCase{htmlUnescaper, "<b>HTML's neat</b>", "<b>HTML's neat</b>"},
+		testCase{htmlUnescaper, "", ""},
+
+		testCase{NewReplacer("a", "1", "a", "2", "xxx", "xxx"), "brad", "br1d"},
+
+		testCase{NewReplacer("a", "1", "aa", "2", "aaa", "3"), "aaaa", "1111"},
+
+		testCase{NewReplacer("aaa", "3", "aa", "2", "a", "1"), "aaaa", "31"},
+	)
+
+	// gen1 has multiple old strings of variable length. There is no
+	// overall non-empty common prefix, but some pairwise common prefixes.
+	gen1 := NewReplacer(
+		"aaa", "3[aaa]",
+		"aa", "2[aa]",
+		"a", "1[a]",
+		"i", "i",
+		"longerst", "most long",
+		"longer", "medium",
+		"long", "short",
+		"xx", "xx",
+		"x", "X",
+		"X", "Y",
+		"Y", "Z",
+	)
+	testCases = append(testCases,
+		testCase{gen1, "fooaaabar", "foo3[aaa]b1[a]r"},
+		testCase{gen1, "long, longerst, longer", "short, most long, medium"},
+		testCase{gen1, "xxxxx", "xxxxX"},
+		testCase{gen1, "XiX", "YiY"},
+		testCase{gen1, "", ""},
+	)
+
+	// gen2 has multiple old strings with no pairwise common prefix.
+	gen2 := NewReplacer(
+		"roses", "red",
+		"violets", "blue",
+		"sugar", "sweet",
+	)
+	testCases = append(testCases,
+		testCase{gen2, "roses are red, violets are blue...", "red are red, blue are blue..."},
+		testCase{gen2, "", ""},
+	)
+
+	// gen3 has multiple old strings with an overall common prefix.
+	gen3 := NewReplacer(
+		"abracadabra", "poof",
+		"abracadabrakazam", "splat",
+		"abraham", "lincoln",
+		"abrasion", "scrape",
+		"abraham", "isaac",
+	)
+	testCases = append(testCases,
+		testCase{gen3, "abracadabrakazam abraham", "poofkazam lincoln"},
+		testCase{gen3, "abrasion abracad", "scrape abracad"},
+		testCase{gen3, "abba abram abrasive", "abba abram abrasive"},
+		testCase{gen3, "", ""},
+	)
+
+	// foo{1,2,3,4} have multiple old strings with an overall common prefix
+	// and 1- or 2- byte extensions from the common prefix.
+	foo1 := NewReplacer(
+		"foo1", "A",
+		"foo2", "B",
+		"foo3", "C",
+	)
+	foo2 := NewReplacer(
+		"foo1", "A",
+		"foo2", "B",
+		"foo31", "C",
+		"foo32", "D",
+	)
+	foo3 := NewReplacer(
+		"foo11", "A",
+		"foo12", "B",
+		"foo31", "C",
+		"foo32", "D",
+	)
+	foo4 := NewReplacer(
+		"foo12", "B",
+		"foo32", "D",
+	)
+	testCases = append(testCases,
+		testCase{foo1, "fofoofoo12foo32oo", "fofooA2C2oo"},
+		testCase{foo1, "", ""},
+
+		testCase{foo2, "fofoofoo12foo32oo", "fofooA2Doo"},
+		testCase{foo2, "", ""},
+
+		testCase{foo3, "fofoofoo12foo32oo", "fofooBDoo"},
+		testCase{foo3, "", ""},
+
+		testCase{foo4, "fofoofoo12foo32oo", "fofooBDoo"},
+		testCase{foo4, "", ""},
+	)
+
+	// genAll maps "\x00\x01\x02...\xfe\xff" to "[all]", amongst other things.
+	allBytes := make([]byte, 256)
+	for i := range allBytes {
+		allBytes[i] = byte(i)
+	}
+	allString := string(allBytes)
+	genAll := NewReplacer(
+		allString, "[all]",
+		"\xff", "[ff]",
+		"\x00", "[00]",
+	)
+	testCases = append(testCases,
+		testCase{genAll, allString, "[all]"},
+		testCase{genAll, "a\xff" + allString + "\x00", "a[ff][all][00]"},
+		testCase{genAll, "", ""},
+	)
+
+	// Test cases with empty old strings.
+
+	blankToX1 := NewReplacer("", "X")
+	blankToX2 := NewReplacer("", "X", "", "")
+	blankHighPriority := NewReplacer("", "X", "o", "O")
+	blankLowPriority := NewReplacer("o", "O", "", "X")
+	blankNoOp1 := NewReplacer("", "")
+	blankNoOp2 := NewReplacer("", "", "", "A")
+	blankFoo := NewReplacer("", "X", "foobar", "R", "foobaz", "Z")
+	testCases = append(testCases,
+		testCase{blankToX1, "foo", "XfXoXoX"},
+		testCase{blankToX1, "", "X"},
+
+		testCase{blankToX2, "foo", "XfXoXoX"},
+		testCase{blankToX2, "", "X"},
+
+		testCase{blankHighPriority, "oo", "XOXOX"},
+		testCase{blankHighPriority, "ii", "XiXiX"},
+		testCase{blankHighPriority, "oiio", "XOXiXiXOX"},
+		testCase{blankHighPriority, "iooi", "XiXOXOXiX"},
+		testCase{blankHighPriority, "", "X"},
+
+		testCase{blankLowPriority, "oo", "OOX"},
+		testCase{blankLowPriority, "ii", "XiXiX"},
+		testCase{blankLowPriority, "oiio", "OXiXiOX"},
+		testCase{blankLowPriority, "iooi", "XiOOXiX"},
+		testCase{blankLowPriority, "", "X"},
+
+		testCase{blankNoOp1, "foo", "foo"},
+		testCase{blankNoOp1, "", ""},
+
+		testCase{blankNoOp2, "foo", "foo"},
+		testCase{blankNoOp2, "", ""},
+
+		testCase{blankFoo, "foobarfoobaz", "XRXZX"},
+		testCase{blankFoo, "foobar-foobaz", "XRX-XZX"},
+		testCase{blankFoo, "", "X"},
+	)
+
+	// single string replacer
+
+	abcMatcher := NewReplacer("abc", "[match]")
+
+	testCases = append(testCases,
+		testCase{abcMatcher, "", ""},
+		testCase{abcMatcher, "ab", "ab"},
+		testCase{abcMatcher, "abc", "[match]"},
+		testCase{abcMatcher, "abcd", "[match]d"},
+		testCase{abcMatcher, "cabcabcdabca", "c[match][match]d[match]a"},
+	)
+
+	// Issue 6659 cases (more single string replacer)
+
+	noHello := NewReplacer("Hello", "")
+	testCases = append(testCases,
+		testCase{noHello, "Hello", ""},
+		testCase{noHello, "Hellox", "x"},
+		testCase{noHello, "xHello", "x"},
+		testCase{noHello, "xHellox", "xx"},
+	)
+
+	// No-arg test cases.
+
+	nop := NewReplacer()
+	testCases = append(testCases,
+		testCase{nop, "abc", "abc"},
+		testCase{nop, "", ""},
+	)
+
+	// Run the test cases.
+
+	for i, tc := range testCases {
+		if s := tc.r.Replace(tc.in); s != tc.out {
+			t.Errorf("%d. Replace(%q) = %q, want %q", i, tc.in, s, tc.out)
+		}
+		var buf bytes.Buffer
+		n, err := tc.r.WriteString(&buf, tc.in)
+		if err != nil {
+			t.Errorf("%d. WriteString: %v", i, err)
+			continue
+		}
+		got := buf.String()
+		if got != tc.out {
+			t.Errorf("%d. WriteString(%q) wrote %q, want %q", i, tc.in, got, tc.out)
+			continue
+		}
+		if n != len(tc.out) {
+			t.Errorf("%d. WriteString(%q) wrote correct string but reported %d bytes; want %d (%q)",
+				i, tc.in, n, len(tc.out), tc.out)
+		}
+	}
+}
+
+var algorithmTestCases = []struct {
+	r    *Replacer
+	want string
+}{
+	{capitalLetters, "*strings.byteReplacer"},
+	{htmlEscaper, "*strings.byteStringReplacer"},
+	{NewReplacer("12", "123"), "*strings.singleStringReplacer"},
+	{NewReplacer("1", "12"), "*strings.byteStringReplacer"},
+	{NewReplacer("", "X"), "*strings.genericReplacer"},
+	{NewReplacer("a", "1", "b", "12", "cde", "123"), "*strings.genericReplacer"},
+}
+
+// TestPickAlgorithm tests that NewReplacer picks the correct algorithm.
+func TestPickAlgorithm(t *testing.T) {
+	for i, tc := range algorithmTestCases {
+		got := fmt.Sprintf("%T", tc.r.Replacer())
+		if got != tc.want {
+			t.Errorf("%d. algorithm = %s, want %s", i, got, tc.want)
+		}
+	}
+}
+
+type errWriter struct{}
+
+func (errWriter) Write(p []byte) (n int, err error) {
+	return 0, fmt.Errorf("unwritable")
+}
+
+// TestWriteStringError tests that WriteString returns an error
+// received from the underlying io.Writer.
+func TestWriteStringError(t *testing.T) {
+	for i, tc := range algorithmTestCases {
+		n, err := tc.r.WriteString(errWriter{}, "abc")
+		if n != 0 || err == nil || err.Error() != "unwritable" {
+			t.Errorf("%d. WriteStringError = %d, %v, want 0, unwritable", i, n, err)
+		}
+	}
+}
+
+// TestGenericTrieBuilding verifies the structure of the generated trie. There
+// is one node per line, and the key ending with the current line is in the
+// trie if it ends with a "+".
+func TestGenericTrieBuilding(t *testing.T) {
+	testCases := []struct{ in, out string }{
+		{"abc;abdef;abdefgh;xx;xy;z", `-
+			a-
+			.b-
+			..c+
+			..d-
+			...ef+
+			.....gh+
+			x-
+			.x+
+			.y+
+			z+
+			`},
+		{"abracadabra;abracadabrakazam;abraham;abrasion", `-
+			a-
+			.bra-
+			....c-
+			.....adabra+
+			...........kazam+
+			....h-
+			.....am+
+			....s-
+			.....ion+
+			`},
+		{"aaa;aa;a;i;longerst;longer;long;xx;x;X;Y", `-
+			X+
+			Y+
+			a+
+			.a+
+			..a+
+			i+
+			l-
+			.ong+
+			....er+
+			......st+
+			x+
+			.x+
+			`},
+		{"foo;;foo;foo1", `+
+			f-
+			.oo+
+			...1+
+			`},
+	}
+
+	for _, tc := range testCases {
+		keys := Split(tc.in, ";")
+		args := make([]string, len(keys)*2)
+		for i, key := range keys {
+			args[i*2] = key
+		}
+
+		got := NewReplacer(args...).PrintTrie()
+		// Remove tabs from tc.out
+		wantbuf := make([]byte, 0, len(tc.out))
+		for i := 0; i < len(tc.out); i++ {
+			if tc.out[i] != '\t' {
+				wantbuf = append(wantbuf, tc.out[i])
+			}
+		}
+		want := string(wantbuf)
+
+		if got != want {
+			t.Errorf("PrintTrie(%q)\ngot\n%swant\n%s", tc.in, got, want)
+		}
+	}
+}
+
+func BenchmarkGenericNoMatch(b *testing.B) {
+	str := Repeat("A", 100) + Repeat("B", 100)
+	generic := NewReplacer("a", "A", "b", "B", "12", "123") // varying lengths forces generic
+	for i := 0; i < b.N; i++ {
+		generic.Replace(str)
+	}
+}
+
+func BenchmarkGenericMatch1(b *testing.B) {
+	str := Repeat("a", 100) + Repeat("b", 100)
+	generic := NewReplacer("a", "A", "b", "B", "12", "123")
+	for i := 0; i < b.N; i++ {
+		generic.Replace(str)
+	}
+}
+
+func BenchmarkGenericMatch2(b *testing.B) {
+	str := Repeat("It's <b>HTML</b>!", 100)
+	for i := 0; i < b.N; i++ {
+		htmlUnescaper.Replace(str)
+	}
+}
+
+func benchmarkSingleString(b *testing.B, pattern, text string) {
+	r := NewReplacer(pattern, "[match]")
+	b.SetBytes(int64(len(text)))
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		r.Replace(text)
+	}
+}
+
+func BenchmarkSingleMaxSkipping(b *testing.B) {
+	benchmarkSingleString(b, Repeat("b", 25), Repeat("a", 10000))
+}
+
+func BenchmarkSingleLongSuffixFail(b *testing.B) {
+	benchmarkSingleString(b, "b"+Repeat("a", 500), Repeat("a", 1002))
+}
+
+func BenchmarkSingleMatch(b *testing.B) {
+	benchmarkSingleString(b, "abcdef", Repeat("abcdefghijklmno", 1000))
+}
+
+func BenchmarkByteByteNoMatch(b *testing.B) {
+	str := Repeat("A", 100) + Repeat("B", 100)
+	for i := 0; i < b.N; i++ {
+		capitalLetters.Replace(str)
+	}
+}
+
+func BenchmarkByteByteMatch(b *testing.B) {
+	str := Repeat("a", 100) + Repeat("b", 100)
+	for i := 0; i < b.N; i++ {
+		capitalLetters.Replace(str)
+	}
+}
+
+func BenchmarkByteStringMatch(b *testing.B) {
+	str := "<" + Repeat("a", 99) + Repeat("b", 99) + ">"
+	for i := 0; i < b.N; i++ {
+		htmlEscaper.Replace(str)
+	}
+}
+
+func BenchmarkHTMLEscapeNew(b *testing.B) {
+	str := "I <3 to escape HTML & other text too."
+	for i := 0; i < b.N; i++ {
+		htmlEscaper.Replace(str)
+	}
+}
+
+func BenchmarkHTMLEscapeOld(b *testing.B) {
+	str := "I <3 to escape HTML & other text too."
+	for i := 0; i < b.N; i++ {
+		oldHTMLEscape(str)
+	}
+}
+
+func BenchmarkByteStringReplacerWriteString(b *testing.B) {
+	str := Repeat("I <3 to escape HTML & other text too.", 100)
+	buf := new(bytes.Buffer)
+	for i := 0; i < b.N; i++ {
+		htmlEscaper.WriteString(buf, str)
+		buf.Reset()
+	}
+}
+
+func BenchmarkByteReplacerWriteString(b *testing.B) {
+	str := Repeat("abcdefghijklmnopqrstuvwxyz", 100)
+	buf := new(bytes.Buffer)
+	for i := 0; i < b.N; i++ {
+		capitalLetters.WriteString(buf, str)
+		buf.Reset()
+	}
+}
+
+// BenchmarkByteByteReplaces compares byteByteImpl against multiple Replaces.
+func BenchmarkByteByteReplaces(b *testing.B) {
+	str := Repeat("a", 100) + Repeat("b", 100)
+	for i := 0; i < b.N; i++ {
+		Replace(Replace(str, "a", "A", -1), "b", "B", -1)
+	}
+}
+
+// BenchmarkByteByteMap compares byteByteImpl against Map.
+func BenchmarkByteByteMap(b *testing.B) {
+	str := Repeat("a", 100) + Repeat("b", 100)
+	fn := func(r rune) rune {
+		switch r {
+		case 'a':
+			return 'A'
+		case 'b':
+			return 'B'
+		}
+		return r
+	}
+	for i := 0; i < b.N; i++ {
+		Map(fn, str)
+	}
+}
diff --git a/src/pkg/strings/search.go b/src/strings/search.go
similarity index 100%
rename from src/pkg/strings/search.go
rename to src/strings/search.go
diff --git a/src/pkg/strings/search_test.go b/src/strings/search_test.go
similarity index 100%
rename from src/pkg/strings/search_test.go
rename to src/strings/search_test.go
diff --git a/src/strings/strings.go b/src/strings/strings.go
new file mode 100644
index 0000000..27d3849
--- /dev/null
+++ b/src/strings/strings.go
@@ -0,0 +1,762 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package strings implements simple functions to manipulate strings.
+package strings
+
+import (
+	"unicode"
+	"unicode/utf8"
+)
+
+// explode splits s into an array of UTF-8 sequences, one per Unicode character (still strings) up to a maximum of n (n < 0 means no limit).
+// Invalid UTF-8 sequences become correct encodings of U+FFF8.
+func explode(s string, n int) []string {
+	if n == 0 {
+		return nil
+	}
+	l := utf8.RuneCountInString(s)
+	if n <= 0 || n > l {
+		n = l
+	}
+	a := make([]string, n)
+	var size int
+	var ch rune
+	i, cur := 0, 0
+	for ; i+1 < n; i++ {
+		ch, size = utf8.DecodeRuneInString(s[cur:])
+		if ch == utf8.RuneError {
+			a[i] = string(utf8.RuneError)
+		} else {
+			a[i] = s[cur : cur+size]
+		}
+		cur += size
+	}
+	// add the rest, if there is any
+	if cur < len(s) {
+		a[i] = s[cur:]
+	}
+	return a
+}
+
+// primeRK is the prime base used in Rabin-Karp algorithm.
+const primeRK = 16777619
+
+// hashStr returns the hash and the appropriate multiplicative
+// factor for use in Rabin-Karp algorithm.
+func hashStr(sep string) (uint32, uint32) {
+	hash := uint32(0)
+	for i := 0; i < len(sep); i++ {
+		hash = hash*primeRK + uint32(sep[i])
+	}
+	var pow, sq uint32 = 1, primeRK
+	for i := len(sep); i > 0; i >>= 1 {
+		if i&1 != 0 {
+			pow *= sq
+		}
+		sq *= sq
+	}
+	return hash, pow
+}
+
+// hashStrRev returns the hash of the reverse of sep and the
+// appropriate multiplicative factor for use in Rabin-Karp algorithm.
+func hashStrRev(sep string) (uint32, uint32) {
+	hash := uint32(0)
+	for i := len(sep) - 1; i >= 0; i-- {
+		hash = hash*primeRK + uint32(sep[i])
+	}
+	var pow, sq uint32 = 1, primeRK
+	for i := len(sep); i > 0; i >>= 1 {
+		if i&1 != 0 {
+			pow *= sq
+		}
+		sq *= sq
+	}
+	return hash, pow
+}
+
+// Count counts the number of non-overlapping instances of sep in s.
+func Count(s, sep string) int {
+	n := 0
+	// special cases
+	switch {
+	case len(sep) == 0:
+		return utf8.RuneCountInString(s) + 1
+	case len(sep) == 1:
+		// special case worth making fast
+		c := sep[0]
+		for i := 0; i < len(s); i++ {
+			if s[i] == c {
+				n++
+			}
+		}
+		return n
+	case len(sep) > len(s):
+		return 0
+	case len(sep) == len(s):
+		if sep == s {
+			return 1
+		}
+		return 0
+	}
+	// Rabin-Karp search
+	hashsep, pow := hashStr(sep)
+	h := uint32(0)
+	for i := 0; i < len(sep); i++ {
+		h = h*primeRK + uint32(s[i])
+	}
+	lastmatch := 0
+	if h == hashsep && s[:len(sep)] == sep {
+		n++
+		lastmatch = len(sep)
+	}
+	for i := len(sep); i < len(s); {
+		h *= primeRK
+		h += uint32(s[i])
+		h -= pow * uint32(s[i-len(sep)])
+		i++
+		if h == hashsep && lastmatch <= i-len(sep) && s[i-len(sep):i] == sep {
+			n++
+			lastmatch = i
+		}
+	}
+	return n
+}
+
+// Contains returns true if substr is within s.
+func Contains(s, substr string) bool {
+	return Index(s, substr) >= 0
+}
+
+// ContainsAny returns true if any Unicode code points in chars are within s.
+func ContainsAny(s, chars string) bool {
+	return IndexAny(s, chars) >= 0
+}
+
+// ContainsRune returns true if the Unicode code point r is within s.
+func ContainsRune(s string, r rune) bool {
+	return IndexRune(s, r) >= 0
+}
+
+// Index returns the index of the first instance of sep in s, or -1 if sep is not present in s.
+func Index(s, sep string) int {
+	n := len(sep)
+	switch {
+	case n == 0:
+		return 0
+	case n == 1:
+		return IndexByte(s, sep[0])
+	case n == len(s):
+		if sep == s {
+			return 0
+		}
+		return -1
+	case n > len(s):
+		return -1
+	}
+	// Rabin-Karp search
+	hashsep, pow := hashStr(sep)
+	var h uint32
+	for i := 0; i < n; i++ {
+		h = h*primeRK + uint32(s[i])
+	}
+	if h == hashsep && s[:n] == sep {
+		return 0
+	}
+	for i := n; i < len(s); {
+		h *= primeRK
+		h += uint32(s[i])
+		h -= pow * uint32(s[i-n])
+		i++
+		if h == hashsep && s[i-n:i] == sep {
+			return i - n
+		}
+	}
+	return -1
+}
+
+// LastIndex returns the index of the last instance of sep in s, or -1 if sep is not present in s.
+func LastIndex(s, sep string) int {
+	n := len(sep)
+	switch {
+	case n == 0:
+		return len(s)
+	case n == 1:
+		// special case worth making fast
+		c := sep[0]
+		for i := len(s) - 1; i >= 0; i-- {
+			if s[i] == c {
+				return i
+			}
+		}
+		return -1
+	case n == len(s):
+		if sep == s {
+			return 0
+		}
+		return -1
+	case n > len(s):
+		return -1
+	}
+	// Rabin-Karp search from the end of the string
+	hashsep, pow := hashStrRev(sep)
+	last := len(s) - n
+	var h uint32
+	for i := len(s) - 1; i >= last; i-- {
+		h = h*primeRK + uint32(s[i])
+	}
+	if h == hashsep && s[last:] == sep {
+		return last
+	}
+	for i := last - 1; i >= 0; i-- {
+		h *= primeRK
+		h += uint32(s[i])
+		h -= pow * uint32(s[i+n])
+		if h == hashsep && s[i:i+n] == sep {
+			return i
+		}
+	}
+	return -1
+}
+
+// IndexRune returns the index of the first instance of the Unicode code point
+// r, or -1 if rune is not present in s.
+func IndexRune(s string, r rune) int {
+	switch {
+	case r < utf8.RuneSelf:
+		return IndexByte(s, byte(r))
+	default:
+		for i, c := range s {
+			if c == r {
+				return i
+			}
+		}
+	}
+	return -1
+}
+
+// IndexAny returns the index of the first instance of any Unicode code point
+// from chars in s, or -1 if no Unicode code point from chars is present in s.
+func IndexAny(s, chars string) int {
+	if len(chars) > 0 {
+		for i, c := range s {
+			for _, m := range chars {
+				if c == m {
+					return i
+				}
+			}
+		}
+	}
+	return -1
+}
+
+// LastIndexAny returns the index of the last instance of any Unicode code
+// point from chars in s, or -1 if no Unicode code point from chars is
+// present in s.
+func LastIndexAny(s, chars string) int {
+	if len(chars) > 0 {
+		for i := len(s); i > 0; {
+			rune, size := utf8.DecodeLastRuneInString(s[0:i])
+			i -= size
+			for _, m := range chars {
+				if rune == m {
+					return i
+				}
+			}
+		}
+	}
+	return -1
+}
+
+// Generic split: splits after each instance of sep,
+// including sepSave bytes of sep in the subarrays.
+func genSplit(s, sep string, sepSave, n int) []string {
+	if n == 0 {
+		return nil
+	}
+	if sep == "" {
+		return explode(s, n)
+	}
+	if n < 0 {
+		n = Count(s, sep) + 1
+	}
+	c := sep[0]
+	start := 0
+	a := make([]string, n)
+	na := 0
+	for i := 0; i+len(sep) <= len(s) && na+1 < n; i++ {
+		if s[i] == c && (len(sep) == 1 || s[i:i+len(sep)] == sep) {
+			a[na] = s[start : i+sepSave]
+			na++
+			start = i + len(sep)
+			i += len(sep) - 1
+		}
+	}
+	a[na] = s[start:]
+	return a[0 : na+1]
+}
+
+// SplitN slices s into substrings separated by sep and returns a slice of
+// the substrings between those separators.
+// If sep is empty, SplitN splits after each UTF-8 sequence.
+// The count determines the number of substrings to return:
+//   n > 0: at most n substrings; the last substring will be the unsplit remainder.
+//   n == 0: the result is nil (zero substrings)
+//   n < 0: all substrings
+func SplitN(s, sep string, n int) []string { return genSplit(s, sep, 0, n) }
+
+// SplitAfterN slices s into substrings after each instance of sep and
+// returns a slice of those substrings.
+// If sep is empty, SplitAfterN splits after each UTF-8 sequence.
+// The count determines the number of substrings to return:
+//   n > 0: at most n substrings; the last substring will be the unsplit remainder.
+//   n == 0: the result is nil (zero substrings)
+//   n < 0: all substrings
+func SplitAfterN(s, sep string, n int) []string {
+	return genSplit(s, sep, len(sep), n)
+}
+
+// Split slices s into all substrings separated by sep and returns a slice of
+// the substrings between those separators.
+// If sep is empty, Split splits after each UTF-8 sequence.
+// It is equivalent to SplitN with a count of -1.
+func Split(s, sep string) []string { return genSplit(s, sep, 0, -1) }
+
+// SplitAfter slices s into all substrings after each instance of sep and
+// returns a slice of those substrings.
+// If sep is empty, SplitAfter splits after each UTF-8 sequence.
+// It is equivalent to SplitAfterN with a count of -1.
+func SplitAfter(s, sep string) []string {
+	return genSplit(s, sep, len(sep), -1)
+}
+
+// Fields splits the string s around each instance of one or more consecutive white space
+// characters, as defined by unicode.IsSpace, returning an array of substrings of s or an
+// empty list if s contains only white space.
+func Fields(s string) []string {
+	return FieldsFunc(s, unicode.IsSpace)
+}
+
+// FieldsFunc splits the string s at each run of Unicode code points c satisfying f(c)
+// and returns an array of slices of s. If all code points in s satisfy f(c) or the
+// string is empty, an empty slice is returned.
+// FieldsFunc makes no guarantees about the order in which it calls f(c).
+// If f does not return consistent results for a given c, FieldsFunc may crash.
+func FieldsFunc(s string, f func(rune) bool) []string {
+	// First count the fields.
+	n := 0
+	inField := false
+	for _, rune := range s {
+		wasInField := inField
+		inField = !f(rune)
+		if inField && !wasInField {
+			n++
+		}
+	}
+
+	// Now create them.
+	a := make([]string, n)
+	na := 0
+	fieldStart := -1 // Set to -1 when looking for start of field.
+	for i, rune := range s {
+		if f(rune) {
+			if fieldStart >= 0 {
+				a[na] = s[fieldStart:i]
+				na++
+				fieldStart = -1
+			}
+		} else if fieldStart == -1 {
+			fieldStart = i
+		}
+	}
+	if fieldStart >= 0 { // Last field might end at EOF.
+		a[na] = s[fieldStart:]
+	}
+	return a
+}
+
+// Join concatenates the elements of a to create a single string.   The separator string
+// sep is placed between elements in the resulting string.
+func Join(a []string, sep string) string {
+	if len(a) == 0 {
+		return ""
+	}
+	if len(a) == 1 {
+		return a[0]
+	}
+	n := len(sep) * (len(a) - 1)
+	for i := 0; i < len(a); i++ {
+		n += len(a[i])
+	}
+
+	b := make([]byte, n)
+	bp := copy(b, a[0])
+	for _, s := range a[1:] {
+		bp += copy(b[bp:], sep)
+		bp += copy(b[bp:], s)
+	}
+	return string(b)
+}
+
+// HasPrefix tests whether the string s begins with prefix.
+func HasPrefix(s, prefix string) bool {
+	return len(s) >= len(prefix) && s[0:len(prefix)] == prefix
+}
+
+// HasSuffix tests whether the string s ends with suffix.
+func HasSuffix(s, suffix string) bool {
+	return len(s) >= len(suffix) && s[len(s)-len(suffix):] == suffix
+}
+
+// Map returns a copy of the string s with all its characters modified
+// according to the mapping function. If mapping returns a negative value, the character is
+// dropped from the string with no replacement.
+func Map(mapping func(rune) rune, s string) string {
+	// In the worst case, the string can grow when mapped, making
+	// things unpleasant.  But it's so rare we barge in assuming it's
+	// fine.  It could also shrink but that falls out naturally.
+	maxbytes := len(s) // length of b
+	nbytes := 0        // number of bytes encoded in b
+	// The output buffer b is initialized on demand, the first
+	// time a character differs.
+	var b []byte
+
+	for i, c := range s {
+		r := mapping(c)
+		if b == nil {
+			if r == c {
+				continue
+			}
+			b = make([]byte, maxbytes)
+			nbytes = copy(b, s[:i])
+		}
+		if r >= 0 {
+			wid := 1
+			if r >= utf8.RuneSelf {
+				wid = utf8.RuneLen(r)
+			}
+			if nbytes+wid > maxbytes {
+				// Grow the buffer.
+				maxbytes = maxbytes*2 + utf8.UTFMax
+				nb := make([]byte, maxbytes)
+				copy(nb, b[0:nbytes])
+				b = nb
+			}
+			nbytes += utf8.EncodeRune(b[nbytes:maxbytes], r)
+		}
+	}
+	if b == nil {
+		return s
+	}
+	return string(b[0:nbytes])
+}
+
+// Repeat returns a new string consisting of count copies of the string s.
+func Repeat(s string, count int) string {
+	b := make([]byte, len(s)*count)
+	bp := copy(b, s)
+	for bp < len(b) {
+		copy(b[bp:], b[:bp])
+		bp *= 2
+	}
+	return string(b)
+}
+
+// ToUpper returns a copy of the string s with all Unicode letters mapped to their upper case.
+func ToUpper(s string) string { return Map(unicode.ToUpper, s) }
+
+// ToLower returns a copy of the string s with all Unicode letters mapped to their lower case.
+func ToLower(s string) string { return Map(unicode.ToLower, s) }
+
+// ToTitle returns a copy of the string s with all Unicode letters mapped to their title case.
+func ToTitle(s string) string { return Map(unicode.ToTitle, s) }
+
+// ToUpperSpecial returns a copy of the string s with all Unicode letters mapped to their
+// upper case, giving priority to the special casing rules.
+func ToUpperSpecial(_case unicode.SpecialCase, s string) string {
+	return Map(func(r rune) rune { return _case.ToUpper(r) }, s)
+}
+
+// ToLowerSpecial returns a copy of the string s with all Unicode letters mapped to their
+// lower case, giving priority to the special casing rules.
+func ToLowerSpecial(_case unicode.SpecialCase, s string) string {
+	return Map(func(r rune) rune { return _case.ToLower(r) }, s)
+}
+
+// ToTitleSpecial returns a copy of the string s with all Unicode letters mapped to their
+// title case, giving priority to the special casing rules.
+func ToTitleSpecial(_case unicode.SpecialCase, s string) string {
+	return Map(func(r rune) rune { return _case.ToTitle(r) }, s)
+}
+
+// isSeparator reports whether the rune could mark a word boundary.
+// TODO: update when package unicode captures more of the properties.
+func isSeparator(r rune) bool {
+	// ASCII alphanumerics and underscore are not separators
+	if r <= 0x7F {
+		switch {
+		case '0' <= r && r <= '9':
+			return false
+		case 'a' <= r && r <= 'z':
+			return false
+		case 'A' <= r && r <= 'Z':
+			return false
+		case r == '_':
+			return false
+		}
+		return true
+	}
+	// Letters and digits are not separators
+	if unicode.IsLetter(r) || unicode.IsDigit(r) {
+		return false
+	}
+	// Otherwise, all we can do for now is treat spaces as separators.
+	return unicode.IsSpace(r)
+}
+
+// Title returns a copy of the string s with all Unicode letters that begin words
+// mapped to their title case.
+//
+// BUG: The rule Title uses for word boundaries does not handle Unicode punctuation properly.
+func Title(s string) string {
+	// Use a closure here to remember state.
+	// Hackish but effective. Depends on Map scanning in order and calling
+	// the closure once per rune.
+	prev := ' '
+	return Map(
+		func(r rune) rune {
+			if isSeparator(prev) {
+				prev = r
+				return unicode.ToTitle(r)
+			}
+			prev = r
+			return r
+		},
+		s)
+}
+
+// TrimLeftFunc returns a slice of the string s with all leading
+// Unicode code points c satisfying f(c) removed.
+func TrimLeftFunc(s string, f func(rune) bool) string {
+	i := indexFunc(s, f, false)
+	if i == -1 {
+		return ""
+	}
+	return s[i:]
+}
+
+// TrimRightFunc returns a slice of the string s with all trailing
+// Unicode code points c satisfying f(c) removed.
+func TrimRightFunc(s string, f func(rune) bool) string {
+	i := lastIndexFunc(s, f, false)
+	if i >= 0 && s[i] >= utf8.RuneSelf {
+		_, wid := utf8.DecodeRuneInString(s[i:])
+		i += wid
+	} else {
+		i++
+	}
+	return s[0:i]
+}
+
+// TrimFunc returns a slice of the string s with all leading
+// and trailing Unicode code points c satisfying f(c) removed.
+func TrimFunc(s string, f func(rune) bool) string {
+	return TrimRightFunc(TrimLeftFunc(s, f), f)
+}
+
+// IndexFunc returns the index into s of the first Unicode
+// code point satisfying f(c), or -1 if none do.
+func IndexFunc(s string, f func(rune) bool) int {
+	return indexFunc(s, f, true)
+}
+
+// LastIndexFunc returns the index into s of the last
+// Unicode code point satisfying f(c), or -1 if none do.
+func LastIndexFunc(s string, f func(rune) bool) int {
+	return lastIndexFunc(s, f, true)
+}
+
+// indexFunc is the same as IndexFunc except that if
+// truth==false, the sense of the predicate function is
+// inverted.
+func indexFunc(s string, f func(rune) bool, truth bool) int {
+	start := 0
+	for start < len(s) {
+		wid := 1
+		r := rune(s[start])
+		if r >= utf8.RuneSelf {
+			r, wid = utf8.DecodeRuneInString(s[start:])
+		}
+		if f(r) == truth {
+			return start
+		}
+		start += wid
+	}
+	return -1
+}
+
+// lastIndexFunc is the same as LastIndexFunc except that if
+// truth==false, the sense of the predicate function is
+// inverted.
+func lastIndexFunc(s string, f func(rune) bool, truth bool) int {
+	for i := len(s); i > 0; {
+		r, size := utf8.DecodeLastRuneInString(s[0:i])
+		i -= size
+		if f(r) == truth {
+			return i
+		}
+	}
+	return -1
+}
+
+func makeCutsetFunc(cutset string) func(rune) bool {
+	return func(r rune) bool { return IndexRune(cutset, r) >= 0 }
+}
+
+// Trim returns a slice of the string s with all leading and
+// trailing Unicode code points contained in cutset removed.
+func Trim(s string, cutset string) string {
+	if s == "" || cutset == "" {
+		return s
+	}
+	return TrimFunc(s, makeCutsetFunc(cutset))
+}
+
+// TrimLeft returns a slice of the string s with all leading
+// Unicode code points contained in cutset removed.
+func TrimLeft(s string, cutset string) string {
+	if s == "" || cutset == "" {
+		return s
+	}
+	return TrimLeftFunc(s, makeCutsetFunc(cutset))
+}
+
+// TrimRight returns a slice of the string s, with all trailing
+// Unicode code points contained in cutset removed.
+func TrimRight(s string, cutset string) string {
+	if s == "" || cutset == "" {
+		return s
+	}
+	return TrimRightFunc(s, makeCutsetFunc(cutset))
+}
+
+// TrimSpace returns a slice of the string s, with all leading
+// and trailing white space removed, as defined by Unicode.
+func TrimSpace(s string) string {
+	return TrimFunc(s, unicode.IsSpace)
+}
+
+// TrimPrefix returns s without the provided leading prefix string.
+// If s doesn't start with prefix, s is returned unchanged.
+func TrimPrefix(s, prefix string) string {
+	if HasPrefix(s, prefix) {
+		return s[len(prefix):]
+	}
+	return s
+}
+
+// TrimSuffix returns s without the provided trailing suffix string.
+// If s doesn't end with suffix, s is returned unchanged.
+func TrimSuffix(s, suffix string) string {
+	if HasSuffix(s, suffix) {
+		return s[:len(s)-len(suffix)]
+	}
+	return s
+}
+
+// Replace returns a copy of the string s with the first n
+// non-overlapping instances of old replaced by new.
+// If old is empty, it matches at the beginning of the string
+// and after each UTF-8 sequence, yielding up to k+1 replacements
+// for a k-rune string.
+// If n < 0, there is no limit on the number of replacements.
+func Replace(s, old, new string, n int) string {
+	if old == new || n == 0 {
+		return s // avoid allocation
+	}
+
+	// Compute number of replacements.
+	if m := Count(s, old); m == 0 {
+		return s // avoid allocation
+	} else if n < 0 || m < n {
+		n = m
+	}
+
+	// Apply replacements to buffer.
+	t := make([]byte, len(s)+n*(len(new)-len(old)))
+	w := 0
+	start := 0
+	for i := 0; i < n; i++ {
+		j := start
+		if len(old) == 0 {
+			if i > 0 {
+				_, wid := utf8.DecodeRuneInString(s[start:])
+				j += wid
+			}
+		} else {
+			j += Index(s[start:], old)
+		}
+		w += copy(t[w:], s[start:j])
+		w += copy(t[w:], new)
+		start = j + len(old)
+	}
+	w += copy(t[w:], s[start:])
+	return string(t[0:w])
+}
+
+// EqualFold reports whether s and t, interpreted as UTF-8 strings,
+// are equal under Unicode case-folding.
+func EqualFold(s, t string) bool {
+	for s != "" && t != "" {
+		// Extract first rune from each string.
+		var sr, tr rune
+		if s[0] < utf8.RuneSelf {
+			sr, s = rune(s[0]), s[1:]
+		} else {
+			r, size := utf8.DecodeRuneInString(s)
+			sr, s = r, s[size:]
+		}
+		if t[0] < utf8.RuneSelf {
+			tr, t = rune(t[0]), t[1:]
+		} else {
+			r, size := utf8.DecodeRuneInString(t)
+			tr, t = r, t[size:]
+		}
+
+		// If they match, keep going; if not, return false.
+
+		// Easy case.
+		if tr == sr {
+			continue
+		}
+
+		// Make sr < tr to simplify what follows.
+		if tr < sr {
+			tr, sr = sr, tr
+		}
+		// Fast check for ASCII.
+		if tr < utf8.RuneSelf && 'A' <= sr && sr <= 'Z' {
+			// ASCII, and sr is upper case.  tr must be lower case.
+			if tr == sr+'a'-'A' {
+				continue
+			}
+			return false
+		}
+
+		// General case.  SimpleFold(x) returns the next equivalent rune > x
+		// or wraps around to smaller values.
+		r := unicode.SimpleFold(sr)
+		for r != sr && r < tr {
+			r = unicode.SimpleFold(r)
+		}
+		if r == tr {
+			continue
+		}
+		return false
+	}
+
+	// One string is empty.  Are both?
+	return s == t
+}
diff --git a/src/pkg/strings/strings.s b/src/strings/strings.s
similarity index 100%
rename from src/pkg/strings/strings.s
rename to src/strings/strings.s
diff --git a/src/pkg/strings/strings_decl.go b/src/strings/strings_decl.go
similarity index 100%
rename from src/pkg/strings/strings_decl.go
rename to src/strings/strings_decl.go
diff --git a/src/strings/strings_test.go b/src/strings/strings_test.go
new file mode 100644
index 0000000..7bb81ef
--- /dev/null
+++ b/src/strings/strings_test.go
@@ -0,0 +1,1204 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package strings_test
+
+import (
+	"bytes"
+	"io"
+	"math/rand"
+	"reflect"
+	. "strings"
+	"testing"
+	"unicode"
+	"unicode/utf8"
+	"unsafe"
+)
+
+func eq(a, b []string) bool {
+	if len(a) != len(b) {
+		return false
+	}
+	for i := 0; i < len(a); i++ {
+		if a[i] != b[i] {
+			return false
+		}
+	}
+	return true
+}
+
+var abcd = "abcd"
+var faces = "☺☻☹"
+var commas = "1,2,3,4"
+var dots = "1....2....3....4"
+
+type IndexTest struct {
+	s   string
+	sep string
+	out int
+}
+
+var indexTests = []IndexTest{
+	{"", "", 0},
+	{"", "a", -1},
+	{"", "foo", -1},
+	{"fo", "foo", -1},
+	{"foo", "foo", 0},
+	{"oofofoofooo", "f", 2},
+	{"oofofoofooo", "foo", 4},
+	{"barfoobarfoo", "foo", 3},
+	{"foo", "", 0},
+	{"foo", "o", 1},
+	{"abcABCabc", "A", 3},
+	// cases with one byte strings - test special case in Index()
+	{"", "a", -1},
+	{"x", "a", -1},
+	{"x", "x", 0},
+	{"abc", "a", 0},
+	{"abc", "b", 1},
+	{"abc", "c", 2},
+	{"abc", "x", -1},
+}
+
+var lastIndexTests = []IndexTest{
+	{"", "", 0},
+	{"", "a", -1},
+	{"", "foo", -1},
+	{"fo", "foo", -1},
+	{"foo", "foo", 0},
+	{"foo", "f", 0},
+	{"oofofoofooo", "f", 7},
+	{"oofofoofooo", "foo", 7},
+	{"barfoobarfoo", "foo", 9},
+	{"foo", "", 3},
+	{"foo", "o", 2},
+	{"abcABCabc", "A", 3},
+	{"abcABCabc", "a", 6},
+}
+
+var indexAnyTests = []IndexTest{
+	{"", "", -1},
+	{"", "a", -1},
+	{"", "abc", -1},
+	{"a", "", -1},
+	{"a", "a", 0},
+	{"aaa", "a", 0},
+	{"abc", "xyz", -1},
+	{"abc", "xcz", 2},
+	{"a☺b☻c☹d", "uvw☻xyz", 2 + len("☺")},
+	{"aRegExp*", ".(|)*+?^$[]", 7},
+	{dots + dots + dots, " ", -1},
+}
+var lastIndexAnyTests = []IndexTest{
+	{"", "", -1},
+	{"", "a", -1},
+	{"", "abc", -1},
+	{"a", "", -1},
+	{"a", "a", 0},
+	{"aaa", "a", 2},
+	{"abc", "xyz", -1},
+	{"abc", "ab", 1},
+	{"a☺b☻c☹d", "uvw☻xyz", 2 + len("☺")},
+	{"a.RegExp*", ".(|)*+?^$[]", 8},
+	{dots + dots + dots, " ", -1},
+}
+
+// Execute f on each test case.  funcName should be the name of f; it's used
+// in failure reports.
+func runIndexTests(t *testing.T, f func(s, sep string) int, funcName string, testCases []IndexTest) {
+	for _, test := range testCases {
+		actual := f(test.s, test.sep)
+		if actual != test.out {
+			t.Errorf("%s(%q,%q) = %v; want %v", funcName, test.s, test.sep, actual, test.out)
+		}
+	}
+}
+
+func TestIndex(t *testing.T)        { runIndexTests(t, Index, "Index", indexTests) }
+func TestLastIndex(t *testing.T)    { runIndexTests(t, LastIndex, "LastIndex", lastIndexTests) }
+func TestIndexAny(t *testing.T)     { runIndexTests(t, IndexAny, "IndexAny", indexAnyTests) }
+func TestLastIndexAny(t *testing.T) { runIndexTests(t, LastIndexAny, "LastIndexAny", lastIndexAnyTests) }
+
+var indexRuneTests = []struct {
+	s    string
+	rune rune
+	out  int
+}{
+	{"a A x", 'A', 2},
+	{"some_text=some_value", '=', 9},
+	{"☺a", 'a', 3},
+	{"a☻☺b", '☺', 4},
+}
+
+func TestIndexRune(t *testing.T) {
+	for _, test := range indexRuneTests {
+		if actual := IndexRune(test.s, test.rune); actual != test.out {
+			t.Errorf("IndexRune(%q,%d)= %v; want %v", test.s, test.rune, actual, test.out)
+		}
+	}
+}
+
+const benchmarkString = "some_text=some☺value"
+
+func BenchmarkIndexRune(b *testing.B) {
+	if got := IndexRune(benchmarkString, '☺'); got != 14 {
+		b.Fatalf("wrong index: expected 14, got=%d", got)
+	}
+	for i := 0; i < b.N; i++ {
+		IndexRune(benchmarkString, '☺')
+	}
+}
+
+func BenchmarkIndexRuneFastPath(b *testing.B) {
+	if got := IndexRune(benchmarkString, 'v'); got != 17 {
+		b.Fatalf("wrong index: expected 17, got=%d", got)
+	}
+	for i := 0; i < b.N; i++ {
+		IndexRune(benchmarkString, 'v')
+	}
+}
+
+func BenchmarkIndex(b *testing.B) {
+	if got := Index(benchmarkString, "v"); got != 17 {
+		b.Fatalf("wrong index: expected 17, got=%d", got)
+	}
+	for i := 0; i < b.N; i++ {
+		Index(benchmarkString, "v")
+	}
+}
+
+func BenchmarkLastIndex(b *testing.B) {
+	if got := Index(benchmarkString, "v"); got != 17 {
+		b.Fatalf("wrong index: expected 17, got=%d", got)
+	}
+	for i := 0; i < b.N; i++ {
+		LastIndex(benchmarkString, "v")
+	}
+}
+
+func BenchmarkIndexByte(b *testing.B) {
+	if got := IndexByte(benchmarkString, 'v'); got != 17 {
+		b.Fatalf("wrong index: expected 17, got=%d", got)
+	}
+	for i := 0; i < b.N; i++ {
+		IndexByte(benchmarkString, 'v')
+	}
+}
+
+var explodetests = []struct {
+	s string
+	n int
+	a []string
+}{
+	{"", -1, []string{}},
+	{abcd, 4, []string{"a", "b", "c", "d"}},
+	{faces, 3, []string{"☺", "☻", "☹"}},
+	{abcd, 2, []string{"a", "bcd"}},
+}
+
+func TestExplode(t *testing.T) {
+	for _, tt := range explodetests {
+		a := SplitN(tt.s, "", tt.n)
+		if !eq(a, tt.a) {
+			t.Errorf("explode(%q, %d) = %v; want %v", tt.s, tt.n, a, tt.a)
+			continue
+		}
+		s := Join(a, "")
+		if s != tt.s {
+			t.Errorf(`Join(explode(%q, %d), "") = %q`, tt.s, tt.n, s)
+		}
+	}
+}
+
+type SplitTest struct {
+	s   string
+	sep string
+	n   int
+	a   []string
+}
+
+var splittests = []SplitTest{
+	{abcd, "a", 0, nil},
+	{abcd, "a", -1, []string{"", "bcd"}},
+	{abcd, "z", -1, []string{"abcd"}},
+	{abcd, "", -1, []string{"a", "b", "c", "d"}},
+	{commas, ",", -1, []string{"1", "2", "3", "4"}},
+	{dots, "...", -1, []string{"1", ".2", ".3", ".4"}},
+	{faces, "☹", -1, []string{"☺☻", ""}},
+	{faces, "~", -1, []string{faces}},
+	{faces, "", -1, []string{"☺", "☻", "☹"}},
+	{"1 2 3 4", " ", 3, []string{"1", "2", "3 4"}},
+	{"1 2", " ", 3, []string{"1", "2"}},
+	{"123", "", 2, []string{"1", "23"}},
+	{"123", "", 17, []string{"1", "2", "3"}},
+}
+
+func TestSplit(t *testing.T) {
+	for _, tt := range splittests {
+		a := SplitN(tt.s, tt.sep, tt.n)
+		if !eq(a, tt.a) {
+			t.Errorf("Split(%q, %q, %d) = %v; want %v", tt.s, tt.sep, tt.n, a, tt.a)
+			continue
+		}
+		if tt.n == 0 {
+			continue
+		}
+		s := Join(a, tt.sep)
+		if s != tt.s {
+			t.Errorf("Join(Split(%q, %q, %d), %q) = %q", tt.s, tt.sep, tt.n, tt.sep, s)
+		}
+		if tt.n < 0 {
+			b := Split(tt.s, tt.sep)
+			if !reflect.DeepEqual(a, b) {
+				t.Errorf("Split disagrees with SplitN(%q, %q, %d) = %v; want %v", tt.s, tt.sep, tt.n, b, a)
+			}
+		}
+	}
+}
+
+var splitaftertests = []SplitTest{
+	{abcd, "a", -1, []string{"a", "bcd"}},
+	{abcd, "z", -1, []string{"abcd"}},
+	{abcd, "", -1, []string{"a", "b", "c", "d"}},
+	{commas, ",", -1, []string{"1,", "2,", "3,", "4"}},
+	{dots, "...", -1, []string{"1...", ".2...", ".3...", ".4"}},
+	{faces, "☹", -1, []string{"☺☻☹", ""}},
+	{faces, "~", -1, []string{faces}},
+	{faces, "", -1, []string{"☺", "☻", "☹"}},
+	{"1 2 3 4", " ", 3, []string{"1 ", "2 ", "3 4"}},
+	{"1 2 3", " ", 3, []string{"1 ", "2 ", "3"}},
+	{"1 2", " ", 3, []string{"1 ", "2"}},
+	{"123", "", 2, []string{"1", "23"}},
+	{"123", "", 17, []string{"1", "2", "3"}},
+}
+
+func TestSplitAfter(t *testing.T) {
+	for _, tt := range splitaftertests {
+		a := SplitAfterN(tt.s, tt.sep, tt.n)
+		if !eq(a, tt.a) {
+			t.Errorf(`Split(%q, %q, %d) = %v; want %v`, tt.s, tt.sep, tt.n, a, tt.a)
+			continue
+		}
+		s := Join(a, "")
+		if s != tt.s {
+			t.Errorf(`Join(Split(%q, %q, %d), %q) = %q`, tt.s, tt.sep, tt.n, tt.sep, s)
+		}
+		if tt.n < 0 {
+			b := SplitAfter(tt.s, tt.sep)
+			if !reflect.DeepEqual(a, b) {
+				t.Errorf("SplitAfter disagrees with SplitAfterN(%q, %q, %d) = %v; want %v", tt.s, tt.sep, tt.n, b, a)
+			}
+		}
+	}
+}
+
+type FieldsTest struct {
+	s string
+	a []string
+}
+
+var fieldstests = []FieldsTest{
+	{"", []string{}},
+	{" ", []string{}},
+	{" \t ", []string{}},
+	{"  abc  ", []string{"abc"}},
+	{"1 2 3 4", []string{"1", "2", "3", "4"}},
+	{"1  2  3  4", []string{"1", "2", "3", "4"}},
+	{"1\t\t2\t\t3\t4", []string{"1", "2", "3", "4"}},
+	{"1\u20002\u20013\u20024", []string{"1", "2", "3", "4"}},
+	{"\u2000\u2001\u2002", []string{}},
+	{"\n™\t™\n", []string{"™", "™"}},
+	{faces, []string{faces}},
+}
+
+func TestFields(t *testing.T) {
+	for _, tt := range fieldstests {
+		a := Fields(tt.s)
+		if !eq(a, tt.a) {
+			t.Errorf("Fields(%q) = %v; want %v", tt.s, a, tt.a)
+			continue
+		}
+	}
+}
+
+var FieldsFuncTests = []FieldsTest{
+	{"", []string{}},
+	{"XX", []string{}},
+	{"XXhiXXX", []string{"hi"}},
+	{"aXXbXXXcX", []string{"a", "b", "c"}},
+}
+
+func TestFieldsFunc(t *testing.T) {
+	for _, tt := range fieldstests {
+		a := FieldsFunc(tt.s, unicode.IsSpace)
+		if !eq(a, tt.a) {
+			t.Errorf("FieldsFunc(%q, unicode.IsSpace) = %v; want %v", tt.s, a, tt.a)
+			continue
+		}
+	}
+	pred := func(c rune) bool { return c == 'X' }
+	for _, tt := range FieldsFuncTests {
+		a := FieldsFunc(tt.s, pred)
+		if !eq(a, tt.a) {
+			t.Errorf("FieldsFunc(%q) = %v, want %v", tt.s, a, tt.a)
+		}
+	}
+}
+
+// Test case for any function which accepts and returns a single string.
+type StringTest struct {
+	in, out string
+}
+
+// Execute f on each test case.  funcName should be the name of f; it's used
+// in failure reports.
+func runStringTests(t *testing.T, f func(string) string, funcName string, testCases []StringTest) {
+	for _, tc := range testCases {
+		actual := f(tc.in)
+		if actual != tc.out {
+			t.Errorf("%s(%q) = %q; want %q", funcName, tc.in, actual, tc.out)
+		}
+	}
+}
+
+var upperTests = []StringTest{
+	{"", ""},
+	{"abc", "ABC"},
+	{"AbC123", "ABC123"},
+	{"azAZ09_", "AZAZ09_"},
+	{"\u0250\u0250\u0250\u0250\u0250", "\u2C6F\u2C6F\u2C6F\u2C6F\u2C6F"}, // grows one byte per char
+}
+
+var lowerTests = []StringTest{
+	{"", ""},
+	{"abc", "abc"},
+	{"AbC123", "abc123"},
+	{"azAZ09_", "azaz09_"},
+	{"\u2C6D\u2C6D\u2C6D\u2C6D\u2C6D", "\u0251\u0251\u0251\u0251\u0251"}, // shrinks one byte per char
+}
+
+const space = "\t\v\r\f\n\u0085\u00a0\u2000\u3000"
+
+var trimSpaceTests = []StringTest{
+	{"", ""},
+	{"abc", "abc"},
+	{space + "abc" + space, "abc"},
+	{" ", ""},
+	{" \t\r\n \t\t\r\r\n\n ", ""},
+	{" \t\r\n x\t\t\r\r\n\n ", "x"},
+	{" \u2000\t\r\n x\t\t\r\r\ny\n \u3000", "x\t\t\r\r\ny"},
+	{"1 \t\r\n2", "1 \t\r\n2"},
+	{" x\x80", "x\x80"},
+	{" x\xc0", "x\xc0"},
+	{"x \xc0\xc0 ", "x \xc0\xc0"},
+	{"x \xc0", "x \xc0"},
+	{"x \xc0 ", "x \xc0"},
+	{"x \xc0\xc0 ", "x \xc0\xc0"},
+	{"x ☺\xc0\xc0 ", "x ☺\xc0\xc0"},
+	{"x ☺ ", "x ☺"},
+}
+
+func tenRunes(ch rune) string {
+	r := make([]rune, 10)
+	for i := range r {
+		r[i] = ch
+	}
+	return string(r)
+}
+
+// User-defined self-inverse mapping function
+func rot13(r rune) rune {
+	step := rune(13)
+	if r >= 'a' && r <= 'z' {
+		return ((r - 'a' + step) % 26) + 'a'
+	}
+	if r >= 'A' && r <= 'Z' {
+		return ((r - 'A' + step) % 26) + 'A'
+	}
+	return r
+}
+
+func TestMap(t *testing.T) {
+	// Run a couple of awful growth/shrinkage tests
+	a := tenRunes('a')
+	// 1.  Grow.  This triggers two reallocations in Map.
+	maxRune := func(rune) rune { return unicode.MaxRune }
+	m := Map(maxRune, a)
+	expect := tenRunes(unicode.MaxRune)
+	if m != expect {
+		t.Errorf("growing: expected %q got %q", expect, m)
+	}
+
+	// 2. Shrink
+	minRune := func(rune) rune { return 'a' }
+	m = Map(minRune, tenRunes(unicode.MaxRune))
+	expect = a
+	if m != expect {
+		t.Errorf("shrinking: expected %q got %q", expect, m)
+	}
+
+	// 3. Rot13
+	m = Map(rot13, "a to zed")
+	expect = "n gb mrq"
+	if m != expect {
+		t.Errorf("rot13: expected %q got %q", expect, m)
+	}
+
+	// 4. Rot13^2
+	m = Map(rot13, Map(rot13, "a to zed"))
+	expect = "a to zed"
+	if m != expect {
+		t.Errorf("rot13: expected %q got %q", expect, m)
+	}
+
+	// 5. Drop
+	dropNotLatin := func(r rune) rune {
+		if unicode.Is(unicode.Latin, r) {
+			return r
+		}
+		return -1
+	}
+	m = Map(dropNotLatin, "Hello, 세계")
+	expect = "Hello"
+	if m != expect {
+		t.Errorf("drop: expected %q got %q", expect, m)
+	}
+
+	// 6. Identity
+	identity := func(r rune) rune {
+		return r
+	}
+	orig := "Input string that we expect not to be copied."
+	m = Map(identity, orig)
+	if (*reflect.StringHeader)(unsafe.Pointer(&orig)).Data !=
+		(*reflect.StringHeader)(unsafe.Pointer(&m)).Data {
+		t.Error("unexpected copy during identity map")
+	}
+}
+
+func TestToUpper(t *testing.T) { runStringTests(t, ToUpper, "ToUpper", upperTests) }
+
+func TestToLower(t *testing.T) { runStringTests(t, ToLower, "ToLower", lowerTests) }
+
+func BenchmarkMapNoChanges(b *testing.B) {
+	identity := func(r rune) rune {
+		return r
+	}
+	for i := 0; i < b.N; i++ {
+		Map(identity, "Some string that won't be modified.")
+	}
+}
+
+func TestSpecialCase(t *testing.T) {
+	lower := "abcçdefgğhıijklmnoöprsştuüvyz"
+	upper := "ABCÇDEFGĞHIİJKLMNOÖPRSŞTUÜVYZ"
+	u := ToUpperSpecial(unicode.TurkishCase, upper)
+	if u != upper {
+		t.Errorf("Upper(upper) is %s not %s", u, upper)
+	}
+	u = ToUpperSpecial(unicode.TurkishCase, lower)
+	if u != upper {
+		t.Errorf("Upper(lower) is %s not %s", u, upper)
+	}
+	l := ToLowerSpecial(unicode.TurkishCase, lower)
+	if l != lower {
+		t.Errorf("Lower(lower) is %s not %s", l, lower)
+	}
+	l = ToLowerSpecial(unicode.TurkishCase, upper)
+	if l != lower {
+		t.Errorf("Lower(upper) is %s not %s", l, lower)
+	}
+}
+
+func TestTrimSpace(t *testing.T) { runStringTests(t, TrimSpace, "TrimSpace", trimSpaceTests) }
+
+var trimTests = []struct {
+	f            string
+	in, arg, out string
+}{
+	{"Trim", "abba", "a", "bb"},
+	{"Trim", "abba", "ab", ""},
+	{"TrimLeft", "abba", "ab", ""},
+	{"TrimRight", "abba", "ab", ""},
+	{"TrimLeft", "abba", "a", "bba"},
+	{"TrimRight", "abba", "a", "abb"},
+	{"Trim", "<tag>", "<>", "tag"},
+	{"Trim", "* listitem", " *", "listitem"},
+	{"Trim", `"quote"`, `"`, "quote"},
+	{"Trim", "\u2C6F\u2C6F\u0250\u0250\u2C6F\u2C6F", "\u2C6F", "\u0250\u0250"},
+	//empty string tests
+	{"Trim", "abba", "", "abba"},
+	{"Trim", "", "123", ""},
+	{"Trim", "", "", ""},
+	{"TrimLeft", "abba", "", "abba"},
+	{"TrimLeft", "", "123", ""},
+	{"TrimLeft", "", "", ""},
+	{"TrimRight", "abba", "", "abba"},
+	{"TrimRight", "", "123", ""},
+	{"TrimRight", "", "", ""},
+	{"TrimRight", "☺\xc0", "☺", "☺\xc0"},
+	{"TrimPrefix", "aabb", "a", "abb"},
+	{"TrimPrefix", "aabb", "b", "aabb"},
+	{"TrimSuffix", "aabb", "a", "aabb"},
+	{"TrimSuffix", "aabb", "b", "aab"},
+}
+
+func TestTrim(t *testing.T) {
+	for _, tc := range trimTests {
+		name := tc.f
+		var f func(string, string) string
+		switch name {
+		case "Trim":
+			f = Trim
+		case "TrimLeft":
+			f = TrimLeft
+		case "TrimRight":
+			f = TrimRight
+		case "TrimPrefix":
+			f = TrimPrefix
+		case "TrimSuffix":
+			f = TrimSuffix
+		default:
+			t.Errorf("Undefined trim function %s", name)
+		}
+		actual := f(tc.in, tc.arg)
+		if actual != tc.out {
+			t.Errorf("%s(%q, %q) = %q; want %q", name, tc.in, tc.arg, actual, tc.out)
+		}
+	}
+}
+
+type predicate struct {
+	f    func(rune) bool
+	name string
+}
+
+var isSpace = predicate{unicode.IsSpace, "IsSpace"}
+var isDigit = predicate{unicode.IsDigit, "IsDigit"}
+var isUpper = predicate{unicode.IsUpper, "IsUpper"}
+var isValidRune = predicate{
+	func(r rune) bool {
+		return r != utf8.RuneError
+	},
+	"IsValidRune",
+}
+
+func not(p predicate) predicate {
+	return predicate{
+		func(r rune) bool {
+			return !p.f(r)
+		},
+		"not " + p.name,
+	}
+}
+
+var trimFuncTests = []struct {
+	f       predicate
+	in, out string
+}{
+	{isSpace, space + " hello " + space, "hello"},
+	{isDigit, "\u0e50\u0e5212hello34\u0e50\u0e51", "hello"},
+	{isUpper, "\u2C6F\u2C6F\u2C6F\u2C6FABCDhelloEF\u2C6F\u2C6FGH\u2C6F\u2C6F", "hello"},
+	{not(isSpace), "hello" + space + "hello", space},
+	{not(isDigit), "hello\u0e50\u0e521234\u0e50\u0e51helo", "\u0e50\u0e521234\u0e50\u0e51"},
+	{isValidRune, "ab\xc0a\xc0cd", "\xc0a\xc0"},
+	{not(isValidRune), "\xc0a\xc0", "a"},
+}
+
+func TestTrimFunc(t *testing.T) {
+	for _, tc := range trimFuncTests {
+		actual := TrimFunc(tc.in, tc.f.f)
+		if actual != tc.out {
+			t.Errorf("TrimFunc(%q, %q) = %q; want %q", tc.in, tc.f.name, actual, tc.out)
+		}
+	}
+}
+
+var indexFuncTests = []struct {
+	in          string
+	f           predicate
+	first, last int
+}{
+	{"", isValidRune, -1, -1},
+	{"abc", isDigit, -1, -1},
+	{"0123", isDigit, 0, 3},
+	{"a1b", isDigit, 1, 1},
+	{space, isSpace, 0, len(space) - 3}, // last rune in space is 3 bytes
+	{"\u0e50\u0e5212hello34\u0e50\u0e51", isDigit, 0, 18},
+	{"\u2C6F\u2C6F\u2C6F\u2C6FABCDhelloEF\u2C6F\u2C6FGH\u2C6F\u2C6F", isUpper, 0, 34},
+	{"12\u0e50\u0e52hello34\u0e50\u0e51", not(isDigit), 8, 12},
+
+	// tests of invalid UTF-8
+	{"\x801", isDigit, 1, 1},
+	{"\x80abc", isDigit, -1, -1},
+	{"\xc0a\xc0", isValidRune, 1, 1},
+	{"\xc0a\xc0", not(isValidRune), 0, 2},
+	{"\xc0☺\xc0", not(isValidRune), 0, 4},
+	{"\xc0☺\xc0\xc0", not(isValidRune), 0, 5},
+	{"ab\xc0a\xc0cd", not(isValidRune), 2, 4},
+	{"a\xe0\x80cd", not(isValidRune), 1, 2},
+	{"\x80\x80\x80\x80", not(isValidRune), 0, 3},
+}
+
+func TestIndexFunc(t *testing.T) {
+	for _, tc := range indexFuncTests {
+		first := IndexFunc(tc.in, tc.f.f)
+		if first != tc.first {
+			t.Errorf("IndexFunc(%q, %s) = %d; want %d", tc.in, tc.f.name, first, tc.first)
+		}
+		last := LastIndexFunc(tc.in, tc.f.f)
+		if last != tc.last {
+			t.Errorf("LastIndexFunc(%q, %s) = %d; want %d", tc.in, tc.f.name, last, tc.last)
+		}
+	}
+}
+
+func equal(m string, s1, s2 string, t *testing.T) bool {
+	if s1 == s2 {
+		return true
+	}
+	e1 := Split(s1, "")
+	e2 := Split(s2, "")
+	for i, c1 := range e1 {
+		if i >= len(e2) {
+			break
+		}
+		r1, _ := utf8.DecodeRuneInString(c1)
+		r2, _ := utf8.DecodeRuneInString(e2[i])
+		if r1 != r2 {
+			t.Errorf("%s diff at %d: U+%04X U+%04X", m, i, r1, r2)
+		}
+	}
+	return false
+}
+
+func TestCaseConsistency(t *testing.T) {
+	// Make a string of all the runes.
+	numRunes := int(unicode.MaxRune + 1)
+	if testing.Short() {
+		numRunes = 1000
+	}
+	a := make([]rune, numRunes)
+	for i := range a {
+		a[i] = rune(i)
+	}
+	s := string(a)
+	// convert the cases.
+	upper := ToUpper(s)
+	lower := ToLower(s)
+
+	// Consistency checks
+	if n := utf8.RuneCountInString(upper); n != numRunes {
+		t.Error("rune count wrong in upper:", n)
+	}
+	if n := utf8.RuneCountInString(lower); n != numRunes {
+		t.Error("rune count wrong in lower:", n)
+	}
+	if !equal("ToUpper(upper)", ToUpper(upper), upper, t) {
+		t.Error("ToUpper(upper) consistency fail")
+	}
+	if !equal("ToLower(lower)", ToLower(lower), lower, t) {
+		t.Error("ToLower(lower) consistency fail")
+	}
+	/*
+		  These fail because of non-one-to-oneness of the data, such as multiple
+		  upper case 'I' mapping to 'i'.  We comment them out but keep them for
+		  interest.
+		  For instance: CAPITAL LETTER I WITH DOT ABOVE:
+			unicode.ToUpper(unicode.ToLower('\u0130')) != '\u0130'
+
+		if !equal("ToUpper(lower)", ToUpper(lower), upper, t) {
+			t.Error("ToUpper(lower) consistency fail");
+		}
+		if !equal("ToLower(upper)", ToLower(upper), lower, t) {
+			t.Error("ToLower(upper) consistency fail");
+		}
+	*/
+}
+
+var RepeatTests = []struct {
+	in, out string
+	count   int
+}{
+	{"", "", 0},
+	{"", "", 1},
+	{"", "", 2},
+	{"-", "", 0},
+	{"-", "-", 1},
+	{"-", "----------", 10},
+	{"abc ", "abc abc abc ", 3},
+}
+
+func TestRepeat(t *testing.T) {
+	for _, tt := range RepeatTests {
+		a := Repeat(tt.in, tt.count)
+		if !equal("Repeat(s)", a, tt.out, t) {
+			t.Errorf("Repeat(%v, %d) = %v; want %v", tt.in, tt.count, a, tt.out)
+			continue
+		}
+	}
+}
+
+func runesEqual(a, b []rune) bool {
+	if len(a) != len(b) {
+		return false
+	}
+	for i, r := range a {
+		if r != b[i] {
+			return false
+		}
+	}
+	return true
+}
+
+var RunesTests = []struct {
+	in    string
+	out   []rune
+	lossy bool
+}{
+	{"", []rune{}, false},
+	{" ", []rune{32}, false},
+	{"ABC", []rune{65, 66, 67}, false},
+	{"abc", []rune{97, 98, 99}, false},
+	{"\u65e5\u672c\u8a9e", []rune{26085, 26412, 35486}, false},
+	{"ab\x80c", []rune{97, 98, 0xFFFD, 99}, true},
+	{"ab\xc0c", []rune{97, 98, 0xFFFD, 99}, true},
+}
+
+func TestRunes(t *testing.T) {
+	for _, tt := range RunesTests {
+		a := []rune(tt.in)
+		if !runesEqual(a, tt.out) {
+			t.Errorf("[]rune(%q) = %v; want %v", tt.in, a, tt.out)
+			continue
+		}
+		if !tt.lossy {
+			// can only test reassembly if we didn't lose information
+			s := string(a)
+			if s != tt.in {
+				t.Errorf("string([]rune(%q)) = %x; want %x", tt.in, s, tt.in)
+			}
+		}
+	}
+}
+
+func TestReadByte(t *testing.T) {
+	testStrings := []string{"", abcd, faces, commas}
+	for _, s := range testStrings {
+		reader := NewReader(s)
+		if e := reader.UnreadByte(); e == nil {
+			t.Errorf("Unreading %q at beginning: expected error", s)
+		}
+		var res bytes.Buffer
+		for {
+			b, e := reader.ReadByte()
+			if e == io.EOF {
+				break
+			}
+			if e != nil {
+				t.Errorf("Reading %q: %s", s, e)
+				break
+			}
+			res.WriteByte(b)
+			// unread and read again
+			e = reader.UnreadByte()
+			if e != nil {
+				t.Errorf("Unreading %q: %s", s, e)
+				break
+			}
+			b1, e := reader.ReadByte()
+			if e != nil {
+				t.Errorf("Reading %q after unreading: %s", s, e)
+				break
+			}
+			if b1 != b {
+				t.Errorf("Reading %q after unreading: want byte %q, got %q", s, b, b1)
+				break
+			}
+		}
+		if res.String() != s {
+			t.Errorf("Reader(%q).ReadByte() produced %q", s, res.String())
+		}
+	}
+}
+
+func TestReadRune(t *testing.T) {
+	testStrings := []string{"", abcd, faces, commas}
+	for _, s := range testStrings {
+		reader := NewReader(s)
+		if e := reader.UnreadRune(); e == nil {
+			t.Errorf("Unreading %q at beginning: expected error", s)
+		}
+		res := ""
+		for {
+			r, z, e := reader.ReadRune()
+			if e == io.EOF {
+				break
+			}
+			if e != nil {
+				t.Errorf("Reading %q: %s", s, e)
+				break
+			}
+			res += string(r)
+			// unread and read again
+			e = reader.UnreadRune()
+			if e != nil {
+				t.Errorf("Unreading %q: %s", s, e)
+				break
+			}
+			r1, z1, e := reader.ReadRune()
+			if e != nil {
+				t.Errorf("Reading %q after unreading: %s", s, e)
+				break
+			}
+			if r1 != r {
+				t.Errorf("Reading %q after unreading: want rune %q, got %q", s, r, r1)
+				break
+			}
+			if z1 != z {
+				t.Errorf("Reading %q after unreading: want size %d, got %d", s, z, z1)
+				break
+			}
+		}
+		if res != s {
+			t.Errorf("Reader(%q).ReadRune() produced %q", s, res)
+		}
+	}
+}
+
+var UnreadRuneErrorTests = []struct {
+	name string
+	f    func(*Reader)
+}{
+	{"Read", func(r *Reader) { r.Read([]byte{0}) }},
+	{"ReadByte", func(r *Reader) { r.ReadByte() }},
+	{"UnreadRune", func(r *Reader) { r.UnreadRune() }},
+	{"Seek", func(r *Reader) { r.Seek(0, 1) }},
+	{"WriteTo", func(r *Reader) { r.WriteTo(&bytes.Buffer{}) }},
+}
+
+func TestUnreadRuneError(t *testing.T) {
+	for _, tt := range UnreadRuneErrorTests {
+		reader := NewReader("0123456789")
+		if _, _, err := reader.ReadRune(); err != nil {
+			// should not happen
+			t.Fatal(err)
+		}
+		tt.f(reader)
+		err := reader.UnreadRune()
+		if err == nil {
+			t.Errorf("Unreading after %s: expected error", tt.name)
+		}
+	}
+}
+
+var ReplaceTests = []struct {
+	in       string
+	old, new string
+	n        int
+	out      string
+}{
+	{"hello", "l", "L", 0, "hello"},
+	{"hello", "l", "L", -1, "heLLo"},
+	{"hello", "x", "X", -1, "hello"},
+	{"", "x", "X", -1, ""},
+	{"radar", "r", "<r>", -1, "<r>ada<r>"},
+	{"", "", "<>", -1, "<>"},
+	{"banana", "a", "<>", -1, "b<>n<>n<>"},
+	{"banana", "a", "<>", 1, "b<>nana"},
+	{"banana", "a", "<>", 1000, "b<>n<>n<>"},
+	{"banana", "an", "<>", -1, "b<><>a"},
+	{"banana", "ana", "<>", -1, "b<>na"},
+	{"banana", "", "<>", -1, "<>b<>a<>n<>a<>n<>a<>"},
+	{"banana", "", "<>", 10, "<>b<>a<>n<>a<>n<>a<>"},
+	{"banana", "", "<>", 6, "<>b<>a<>n<>a<>n<>a"},
+	{"banana", "", "<>", 5, "<>b<>a<>n<>a<>na"},
+	{"banana", "", "<>", 1, "<>banana"},
+	{"banana", "a", "a", -1, "banana"},
+	{"banana", "a", "a", 1, "banana"},
+	{"☺☻☹", "", "<>", -1, "<>☺<>☻<>☹<>"},
+}
+
+func TestReplace(t *testing.T) {
+	for _, tt := range ReplaceTests {
+		if s := Replace(tt.in, tt.old, tt.new, tt.n); s != tt.out {
+			t.Errorf("Replace(%q, %q, %q, %d) = %q, want %q", tt.in, tt.old, tt.new, tt.n, s, tt.out)
+		}
+	}
+}
+
+var TitleTests = []struct {
+	in, out string
+}{
+	{"", ""},
+	{"a", "A"},
+	{" aaa aaa aaa ", " Aaa Aaa Aaa "},
+	{" Aaa Aaa Aaa ", " Aaa Aaa Aaa "},
+	{"123a456", "123a456"},
+	{"double-blind", "Double-Blind"},
+	{"ÿøû", "Ÿøû"},
+	{"with_underscore", "With_underscore"},
+	{"unicode \xe2\x80\xa8 line separator", "Unicode \xe2\x80\xa8 Line Separator"},
+}
+
+func TestTitle(t *testing.T) {
+	for _, tt := range TitleTests {
+		if s := Title(tt.in); s != tt.out {
+			t.Errorf("Title(%q) = %q, want %q", tt.in, s, tt.out)
+		}
+	}
+}
+
+var ContainsTests = []struct {
+	str, substr string
+	expected    bool
+}{
+	{"abc", "bc", true},
+	{"abc", "bcd", false},
+	{"abc", "", true},
+	{"", "a", false},
+}
+
+func TestContains(t *testing.T) {
+	for _, ct := range ContainsTests {
+		if Contains(ct.str, ct.substr) != ct.expected {
+			t.Errorf("Contains(%s, %s) = %v, want %v",
+				ct.str, ct.substr, !ct.expected, ct.expected)
+		}
+	}
+}
+
+var ContainsAnyTests = []struct {
+	str, substr string
+	expected    bool
+}{
+	{"", "", false},
+	{"", "a", false},
+	{"", "abc", false},
+	{"a", "", false},
+	{"a", "a", true},
+	{"aaa", "a", true},
+	{"abc", "xyz", false},
+	{"abc", "xcz", true},
+	{"a☺b☻c☹d", "uvw☻xyz", true},
+	{"aRegExp*", ".(|)*+?^$[]", true},
+	{dots + dots + dots, " ", false},
+}
+
+func TestContainsAny(t *testing.T) {
+	for _, ct := range ContainsAnyTests {
+		if ContainsAny(ct.str, ct.substr) != ct.expected {
+			t.Errorf("ContainsAny(%s, %s) = %v, want %v",
+				ct.str, ct.substr, !ct.expected, ct.expected)
+		}
+	}
+}
+
+var ContainsRuneTests = []struct {
+	str      string
+	r        rune
+	expected bool
+}{
+	{"", 'a', false},
+	{"a", 'a', true},
+	{"aaa", 'a', true},
+	{"abc", 'y', false},
+	{"abc", 'c', true},
+	{"a☺b☻c☹d", 'x', false},
+	{"a☺b☻c☹d", '☻', true},
+	{"aRegExp*", '*', true},
+}
+
+func TestContainsRune(t *testing.T) {
+	for _, ct := range ContainsRuneTests {
+		if ContainsRune(ct.str, ct.r) != ct.expected {
+			t.Errorf("ContainsRune(%q, %q) = %v, want %v",
+				ct.str, ct.r, !ct.expected, ct.expected)
+		}
+	}
+}
+
+var EqualFoldTests = []struct {
+	s, t string
+	out  bool
+}{
+	{"abc", "abc", true},
+	{"ABcd", "ABcd", true},
+	{"123abc", "123ABC", true},
+	{"αβδ", "ΑΒΔ", true},
+	{"abc", "xyz", false},
+	{"abc", "XYZ", false},
+	{"abcdefghijk", "abcdefghijX", false},
+	{"abcdefghijk", "abcdefghij\u212A", true},
+	{"abcdefghijK", "abcdefghij\u212A", true},
+	{"abcdefghijkz", "abcdefghij\u212Ay", false},
+	{"abcdefghijKz", "abcdefghij\u212Ay", false},
+}
+
+func TestEqualFold(t *testing.T) {
+	for _, tt := range EqualFoldTests {
+		if out := EqualFold(tt.s, tt.t); out != tt.out {
+			t.Errorf("EqualFold(%#q, %#q) = %v, want %v", tt.s, tt.t, out, tt.out)
+		}
+		if out := EqualFold(tt.t, tt.s); out != tt.out {
+			t.Errorf("EqualFold(%#q, %#q) = %v, want %v", tt.t, tt.s, out, tt.out)
+		}
+	}
+}
+
+var CountTests = []struct {
+	s, sep string
+	num    int
+}{
+	{"", "", 1},
+	{"", "notempty", 0},
+	{"notempty", "", 9},
+	{"smaller", "not smaller", 0},
+	{"12345678987654321", "6", 2},
+	{"611161116", "6", 3},
+	{"notequal", "NotEqual", 0},
+	{"equal", "equal", 1},
+	{"abc1231231123q", "123", 3},
+	{"11111", "11", 2},
+}
+
+func TestCount(t *testing.T) {
+	for _, tt := range CountTests {
+		if num := Count(tt.s, tt.sep); num != tt.num {
+			t.Errorf("Count(\"%s\", \"%s\") = %d, want %d", tt.s, tt.sep, num, tt.num)
+		}
+	}
+}
+
+func makeBenchInputHard() string {
+	tokens := [...]string{
+		"<a>", "<p>", "<b>", "<strong>",
+		"</a>", "</p>", "</b>", "</strong>",
+		"hello", "world",
+	}
+	x := make([]byte, 0, 1<<20)
+	for {
+		i := rand.Intn(len(tokens))
+		if len(x)+len(tokens[i]) >= 1<<20 {
+			break
+		}
+		x = append(x, tokens[i]...)
+	}
+	return string(x)
+}
+
+var benchInputHard = makeBenchInputHard()
+
+func benchmarkIndexHard(b *testing.B, sep string) {
+	for i := 0; i < b.N; i++ {
+		Index(benchInputHard, sep)
+	}
+}
+
+func benchmarkLastIndexHard(b *testing.B, sep string) {
+	for i := 0; i < b.N; i++ {
+		LastIndex(benchInputHard, sep)
+	}
+}
+
+func benchmarkCountHard(b *testing.B, sep string) {
+	for i := 0; i < b.N; i++ {
+		Count(benchInputHard, sep)
+	}
+}
+
+func BenchmarkIndexHard1(b *testing.B) { benchmarkIndexHard(b, "<>") }
+func BenchmarkIndexHard2(b *testing.B) { benchmarkIndexHard(b, "</pre>") }
+func BenchmarkIndexHard3(b *testing.B) { benchmarkIndexHard(b, "<b>hello world</b>") }
+
+func BenchmarkLastIndexHard1(b *testing.B) { benchmarkLastIndexHard(b, "<>") }
+func BenchmarkLastIndexHard2(b *testing.B) { benchmarkLastIndexHard(b, "</pre>") }
+func BenchmarkLastIndexHard3(b *testing.B) { benchmarkLastIndexHard(b, "<b>hello world</b>") }
+
+func BenchmarkCountHard1(b *testing.B) { benchmarkCountHard(b, "<>") }
+func BenchmarkCountHard2(b *testing.B) { benchmarkCountHard(b, "</pre>") }
+func BenchmarkCountHard3(b *testing.B) { benchmarkCountHard(b, "<b>hello world</b>") }
+
+var benchInputTorture = Repeat("ABC", 1<<10) + "123" + Repeat("ABC", 1<<10)
+var benchNeedleTorture = Repeat("ABC", 1<<10+1)
+
+func BenchmarkIndexTorture(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		Index(benchInputTorture, benchNeedleTorture)
+	}
+}
+
+func BenchmarkCountTorture(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		Count(benchInputTorture, benchNeedleTorture)
+	}
+}
+
+func BenchmarkCountTortureOverlapping(b *testing.B) {
+	A := Repeat("ABC", 1<<20)
+	B := Repeat("ABC", 1<<10)
+	for i := 0; i < b.N; i++ {
+		Count(A, B)
+	}
+}
+
+var makeFieldsInput = func() string {
+	x := make([]byte, 1<<20)
+	// Input is ~10% space, ~10% 2-byte UTF-8, rest ASCII non-space.
+	for i := range x {
+		switch rand.Intn(10) {
+		case 0:
+			x[i] = ' '
+		case 1:
+			if i > 0 && x[i-1] == 'x' {
+				copy(x[i-1:], "χ")
+				break
+			}
+			fallthrough
+		default:
+			x[i] = 'x'
+		}
+	}
+	return string(x)
+}
+
+var fieldsInput = makeFieldsInput()
+
+func BenchmarkFields(b *testing.B) {
+	b.SetBytes(int64(len(fieldsInput)))
+	for i := 0; i < b.N; i++ {
+		Fields(fieldsInput)
+	}
+}
+
+func BenchmarkFieldsFunc(b *testing.B) {
+	b.SetBytes(int64(len(fieldsInput)))
+	for i := 0; i < b.N; i++ {
+		FieldsFunc(fieldsInput, unicode.IsSpace)
+	}
+}
+
+func BenchmarkSplit1(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		Split(benchInputHard, "")
+	}
+}
+
+func BenchmarkSplit2(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		Split(benchInputHard, "/")
+	}
+}
+
+func BenchmarkSplit3(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		Split(benchInputHard, "hello")
+	}
+}
+
+func BenchmarkRepeat(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		Repeat("-", 80)
+	}
+}
diff --git a/src/sync/atomic/64bit_arm.go b/src/sync/atomic/64bit_arm.go
new file mode 100644
index 0000000..b98e608
--- /dev/null
+++ b/src/sync/atomic/64bit_arm.go
@@ -0,0 +1,58 @@
+// Copyright 2012 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package atomic
+
+func loadUint64(addr *uint64) (val uint64) {
+	for {
+		val = *addr
+		if CompareAndSwapUint64(addr, val, val) {
+			break
+		}
+	}
+	return
+}
+
+func storeUint64(addr *uint64, val uint64) {
+	for {
+		old := *addr
+		if CompareAndSwapUint64(addr, old, val) {
+			break
+		}
+	}
+	return
+}
+
+func addUint64(val *uint64, delta uint64) (new uint64) {
+	for {
+		old := *val
+		new = old + delta
+		if CompareAndSwapUint64(val, old, new) {
+			break
+		}
+	}
+	return
+}
+
+func swapUint64(addr *uint64, new uint64) (old uint64) {
+	for {
+		old = *addr
+		if CompareAndSwapUint64(addr, old, new) {
+			break
+		}
+	}
+	return
+}
+
+// Additional ARM-specific assembly routines.
+// Declaration here to give assembly routines correct stack maps for arguments.
+func armCompareAndSwapUint32(addr *uint32, old, new uint32) (swapped bool)
+func armCompareAndSwapUint64(addr *uint64, old, new uint64) (swapped bool)
+func generalCAS64(addr *uint64, old, new uint64) (swapped bool)
+func armAddUint32(addr *uint32, delta uint32) (new uint32)
+func armAddUint64(addr *uint64, delta uint64) (new uint64)
+func armSwapUint32(addr *uint32, new uint32) (old uint32)
+func armSwapUint64(addr *uint64, new uint64) (old uint64)
+func armLoadUint64(addr *uint64) (val uint64)
+func armStoreUint64(addr *uint64, val uint64)
diff --git a/src/sync/atomic/asm_386.s b/src/sync/atomic/asm_386.s
new file mode 100644
index 0000000..740dfe7
--- /dev/null
+++ b/src/sync/atomic/asm_386.s
@@ -0,0 +1,214 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !race
+
+#include "textflag.h"
+
+TEXT ·SwapInt32(SB),NOSPLIT,$0-12
+	JMP	·SwapUint32(SB)
+
+TEXT ·SwapUint32(SB),NOSPLIT,$0-12
+	MOVL	addr+0(FP), BP
+	MOVL	new+4(FP), AX
+	XCHGL	AX, 0(BP)
+	MOVL	AX, old+8(FP)
+	RET
+
+TEXT ·SwapInt64(SB),NOSPLIT,$0-20
+	JMP	·SwapUint64(SB)
+
+TEXT ·SwapUint64(SB),NOSPLIT,$0-20
+	// no XCHGQ so use CMPXCHG8B loop
+	MOVL	addr+0(FP), BP
+	TESTL	$7, BP
+	JZ	2(PC)
+	MOVL	0, AX // crash with nil ptr deref
+	// CX:BX = new
+	MOVL	new_lo+4(FP), BX
+	MOVL	new_hi+8(FP), CX
+	// DX:AX = *addr
+	MOVL	0(BP), AX
+	MOVL	4(BP), DX
+swaploop:
+	// if *addr == DX:AX
+	//	*addr = CX:BX
+	// else
+	//	DX:AX = *addr
+	// all in one instruction
+	LOCK
+	CMPXCHG8B	0(BP)
+	JNZ	swaploop
+
+	// success
+	// return DX:AX
+	MOVL	AX, old_lo+12(FP)
+	MOVL	DX, old_hi+16(FP)
+	RET
+
+TEXT ·SwapUintptr(SB),NOSPLIT,$0-12
+	JMP	·SwapUint32(SB)
+
+TEXT ·SwapPointer(SB),NOSPLIT,$0-12
+	JMP	·SwapUint32(SB)
+
+TEXT ·CompareAndSwapInt32(SB),NOSPLIT,$0-13
+	JMP	·CompareAndSwapUint32(SB)
+
+TEXT ·CompareAndSwapUint32(SB),NOSPLIT,$0-13
+	MOVL	addr+0(FP), BP
+	MOVL	old+4(FP), AX
+	MOVL	new+8(FP), CX
+	// CMPXCHGL was introduced on the 486.
+	LOCK
+	CMPXCHGL	CX, 0(BP)
+	SETEQ	swapped+12(FP)
+	RET
+
+TEXT ·CompareAndSwapUintptr(SB),NOSPLIT,$0-13
+	JMP	·CompareAndSwapUint32(SB)
+
+TEXT ·CompareAndSwapPointer(SB),NOSPLIT,$0-13
+	JMP	·CompareAndSwapUint32(SB)
+
+TEXT ·CompareAndSwapInt64(SB),NOSPLIT,$0-21
+	JMP	·CompareAndSwapUint64(SB)
+
+TEXT ·CompareAndSwapUint64(SB),NOSPLIT,$0-21
+	MOVL	addr+0(FP), BP
+	TESTL	$7, BP
+	JZ	2(PC)
+	MOVL	0, AX // crash with nil ptr deref
+	MOVL	old_lo+4(FP), AX
+	MOVL	old_hi+8(FP), DX
+	MOVL	new_lo+12(FP), BX
+	MOVL	new_hi+16(FP), CX
+	// CMPXCHG8B was introduced on the Pentium.
+	LOCK
+	CMPXCHG8B	0(BP)
+	SETEQ	swapped+20(FP)
+	RET
+
+TEXT ·AddInt32(SB),NOSPLIT,$0-12
+	JMP	·AddUint32(SB)
+
+TEXT ·AddUint32(SB),NOSPLIT,$0-12
+	MOVL	addr+0(FP), BP
+	MOVL	delta+4(FP), AX
+	MOVL	AX, CX
+	// XADD was introduced on the 486.
+	LOCK
+	XADDL	AX, 0(BP)
+	ADDL	AX, CX
+	MOVL	CX, new+8(FP)
+	RET
+
+TEXT ·AddUintptr(SB),NOSPLIT,$0-12
+	JMP	·AddUint32(SB)
+
+TEXT ·AddInt64(SB),NOSPLIT,$0-20
+	JMP	·AddUint64(SB)
+
+TEXT ·AddUint64(SB),NOSPLIT,$0-20
+	// no XADDQ so use CMPXCHG8B loop
+	MOVL	addr+0(FP), BP
+	TESTL	$7, BP
+	JZ	2(PC)
+	MOVL	0, AX // crash with nil ptr deref
+	// DI:SI = delta
+	MOVL	delta_lo+4(FP), SI
+	MOVL	delta_hi+8(FP), DI
+	// DX:AX = *addr
+	MOVL	0(BP), AX
+	MOVL	4(BP), DX
+addloop:
+	// CX:BX = DX:AX (*addr) + DI:SI (delta)
+	MOVL	AX, BX
+	MOVL	DX, CX
+	ADDL	SI, BX
+	ADCL	DI, CX
+
+	// if *addr == DX:AX {
+	//	*addr = CX:BX
+	// } else {
+	//	DX:AX = *addr
+	// }
+	// all in one instruction
+	LOCK
+	CMPXCHG8B	0(BP)
+
+	JNZ	addloop
+
+	// success
+	// return CX:BX
+	MOVL	BX, new_lo+12(FP)
+	MOVL	CX, new_hi+16(FP)
+	RET
+
+TEXT ·LoadInt32(SB),NOSPLIT,$0-8
+	JMP	·LoadUint32(SB)
+
+TEXT ·LoadUint32(SB),NOSPLIT,$0-8
+	MOVL	addr+0(FP), AX
+	MOVL	0(AX), AX
+	MOVL	AX, val+4(FP)
+	RET
+
+TEXT ·LoadInt64(SB),NOSPLIT,$0-12
+	JMP	·LoadUint64(SB)
+
+TEXT ·LoadUint64(SB),NOSPLIT,$0-12
+	MOVL	addr+0(FP), AX
+	TESTL	$7, AX
+	JZ	2(PC)
+	MOVL	0, AX // crash with nil ptr deref
+	// MOVQ and EMMS were introduced on the Pentium MMX.
+	// MOVQ (%EAX), %MM0
+	BYTE $0x0f; BYTE $0x6f; BYTE $0x00
+	// MOVQ %MM0, 0x8(%ESP)
+	BYTE $0x0f; BYTE $0x7f; BYTE $0x44; BYTE $0x24; BYTE $0x08
+	EMMS
+	RET
+
+TEXT ·LoadUintptr(SB),NOSPLIT,$0-8
+	JMP	·LoadUint32(SB)
+
+TEXT ·LoadPointer(SB),NOSPLIT,$0-8
+	JMP	·LoadUint32(SB)
+
+TEXT ·StoreInt32(SB),NOSPLIT,$0-8
+	JMP	·StoreUint32(SB)
+
+TEXT ·StoreUint32(SB),NOSPLIT,$0-8
+	MOVL	addr+0(FP), BP
+	MOVL	val+4(FP), AX
+	XCHGL	AX, 0(BP)
+	RET
+
+TEXT ·StoreInt64(SB),NOSPLIT,$0-12
+	JMP	·StoreUint64(SB)
+
+TEXT ·StoreUint64(SB),NOSPLIT,$0-12
+	MOVL	addr+0(FP), AX
+	TESTL	$7, AX
+	JZ	2(PC)
+	MOVL	0, AX // crash with nil ptr deref
+	// MOVQ and EMMS were introduced on the Pentium MMX.
+	// MOVQ 0x8(%ESP), %MM0
+	BYTE $0x0f; BYTE $0x6f; BYTE $0x44; BYTE $0x24; BYTE $0x08
+	// MOVQ %MM0, (%EAX)
+	BYTE $0x0f; BYTE $0x7f; BYTE $0x00 
+	EMMS
+	// This is essentially a no-op, but it provides required memory fencing.
+	// It can be replaced with MFENCE, but MFENCE was introduced only on the Pentium4 (SSE2).
+	XORL	AX, AX
+	LOCK
+	XADDL	AX, (SP)
+	RET
+
+TEXT ·StoreUintptr(SB),NOSPLIT,$0-8
+	JMP	·StoreUint32(SB)
+
+TEXT ·StorePointer(SB),NOSPLIT,$0-8
+	JMP	·StoreUint32(SB)
diff --git a/src/sync/atomic/asm_amd64.s b/src/sync/atomic/asm_amd64.s
new file mode 100644
index 0000000..6e53ebe
--- /dev/null
+++ b/src/sync/atomic/asm_amd64.s
@@ -0,0 +1,146 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !race
+
+#include "textflag.h"
+
+TEXT ·SwapInt32(SB),NOSPLIT,$0-20
+	JMP	·SwapUint32(SB)
+
+TEXT ·SwapUint32(SB),NOSPLIT,$0-20
+	MOVQ	addr+0(FP), BP
+	MOVL	new+8(FP), AX
+	XCHGL	AX, 0(BP)
+	MOVL	AX, old+16(FP)
+	RET
+
+TEXT ·SwapInt64(SB),NOSPLIT,$0-24
+	JMP	·SwapUint64(SB)
+
+TEXT ·SwapUint64(SB),NOSPLIT,$0-24
+	MOVQ	addr+0(FP), BP
+	MOVQ	new+8(FP), AX
+	XCHGQ	AX, 0(BP)
+	MOVQ	AX, old+16(FP)
+	RET
+
+TEXT ·SwapUintptr(SB),NOSPLIT,$0-24
+	JMP	·SwapUint64(SB)
+
+TEXT ·SwapPointer(SB),NOSPLIT,$0-24
+	JMP	·SwapUint64(SB)
+
+TEXT ·CompareAndSwapInt32(SB),NOSPLIT,$0-17
+	JMP	·CompareAndSwapUint32(SB)
+
+TEXT ·CompareAndSwapUint32(SB),NOSPLIT,$0-17
+	MOVQ	addr+0(FP), BP
+	MOVL	old+8(FP), AX
+	MOVL	new+12(FP), CX
+	LOCK
+	CMPXCHGL	CX, 0(BP)
+	SETEQ	swapped+16(FP)
+	RET
+
+TEXT ·CompareAndSwapUintptr(SB),NOSPLIT,$0-25
+	JMP	·CompareAndSwapUint64(SB)
+
+TEXT ·CompareAndSwapPointer(SB),NOSPLIT,$0-25
+	JMP	·CompareAndSwapUint64(SB)
+
+TEXT ·CompareAndSwapInt64(SB),NOSPLIT,$0-25
+	JMP	·CompareAndSwapUint64(SB)
+
+TEXT ·CompareAndSwapUint64(SB),NOSPLIT,$0-25
+	MOVQ	addr+0(FP), BP
+	MOVQ	old+8(FP), AX
+	MOVQ	new+16(FP), CX
+	LOCK
+	CMPXCHGQ	CX, 0(BP)
+	SETEQ	swapped+24(FP)
+	RET
+
+TEXT ·AddInt32(SB),NOSPLIT,$0-20
+	JMP	·AddUint32(SB)
+
+TEXT ·AddUint32(SB),NOSPLIT,$0-20
+	MOVQ	addr+0(FP), BP
+	MOVL	delta+8(FP), AX
+	MOVL	AX, CX
+	LOCK
+	XADDL	AX, 0(BP)
+	ADDL	AX, CX
+	MOVL	CX, new+16(FP)
+	RET
+
+TEXT ·AddUintptr(SB),NOSPLIT,$0-24
+	JMP	·AddUint64(SB)
+
+TEXT ·AddInt64(SB),NOSPLIT,$0-24
+	JMP	·AddUint64(SB)
+
+TEXT ·AddUint64(SB),NOSPLIT,$0-24
+	MOVQ	addr+0(FP), BP
+	MOVQ	delta+8(FP), AX
+	MOVQ	AX, CX
+	LOCK
+	XADDQ	AX, 0(BP)
+	ADDQ	AX, CX
+	MOVQ	CX, new+16(FP)
+	RET
+
+TEXT ·LoadInt32(SB),NOSPLIT,$0-12
+	JMP	·LoadUint32(SB)
+
+TEXT ·LoadUint32(SB),NOSPLIT,$0-12
+	MOVQ	addr+0(FP), AX
+	MOVL	0(AX), AX
+	MOVL	AX, val+8(FP)
+	RET
+
+TEXT ·LoadInt64(SB),NOSPLIT,$0-16
+	JMP	·LoadUint64(SB)
+
+TEXT ·LoadUint64(SB),NOSPLIT,$0-16
+	MOVQ	addr+0(FP), AX
+	MOVQ	0(AX), AX
+	MOVQ	AX, val+8(FP)
+	RET
+
+TEXT ·LoadUintptr(SB),NOSPLIT,$0-16
+	JMP	·LoadPointer(SB)
+
+TEXT ·LoadPointer(SB),NOSPLIT,$0-16
+	MOVQ	addr+0(FP), AX
+	MOVQ	0(AX), AX
+	MOVQ	AX, val+8(FP)
+	RET
+
+TEXT ·StoreInt32(SB),NOSPLIT,$0-12
+	JMP	·StoreUint32(SB)
+
+TEXT ·StoreUint32(SB),NOSPLIT,$0-12
+	MOVQ	addr+0(FP), BP
+	MOVL	val+8(FP), AX
+	XCHGL	AX, 0(BP)
+	RET
+
+TEXT ·StoreInt64(SB),NOSPLIT,$0-16
+	JMP	·StoreUint64(SB)
+
+TEXT ·StoreUint64(SB),NOSPLIT,$0-16
+	MOVQ	addr+0(FP), BP
+	MOVQ	val+8(FP), AX
+	XCHGQ	AX, 0(BP)
+	RET
+
+TEXT ·StoreUintptr(SB),NOSPLIT,$0-16
+	JMP	·StorePointer(SB)
+
+TEXT ·StorePointer(SB),NOSPLIT,$0-16
+	MOVQ	addr+0(FP), BP
+	MOVQ	val+8(FP), AX
+	XCHGQ	AX, 0(BP)
+	RET
diff --git a/src/sync/atomic/asm_amd64p32.s b/src/sync/atomic/asm_amd64p32.s
new file mode 100644
index 0000000..d77cc2c
--- /dev/null
+++ b/src/sync/atomic/asm_amd64p32.s
@@ -0,0 +1,159 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+TEXT ·SwapInt32(SB),NOSPLIT,$0-12
+	JMP	·SwapUint32(SB)
+
+TEXT ·SwapUint32(SB),NOSPLIT,$0-12
+	MOVL	addr+0(FP), BX
+	MOVL	new+4(FP), AX
+	XCHGL	AX, 0(BX)
+	MOVL	AX, old+8(FP)
+	RET
+
+TEXT ·SwapInt64(SB),NOSPLIT,$0-24
+	JMP	·SwapUint64(SB)
+
+TEXT ·SwapUint64(SB),NOSPLIT,$0-24
+	MOVL	addr+0(FP), BX
+	TESTL	$7, BX
+	JZ	2(PC)
+	MOVL	0, BX // crash with nil ptr deref
+	MOVQ	new+8(FP), AX
+	XCHGQ	AX, 0(BX)
+	MOVQ	AX, old+16(FP)
+	RET
+
+TEXT ·SwapUintptr(SB),NOSPLIT,$0-12
+	JMP	·SwapUint32(SB)
+
+TEXT ·SwapPointer(SB),NOSPLIT,$0-12
+	JMP	·SwapUint32(SB)
+
+TEXT ·CompareAndSwapInt32(SB),NOSPLIT,$0-17
+	JMP	·CompareAndSwapUint32(SB)
+
+TEXT ·CompareAndSwapUint32(SB),NOSPLIT,$0-17
+	MOVL	addr+0(FP), BX
+	MOVL	old+4(FP), AX
+	MOVL	new+8(FP), CX
+	LOCK
+	CMPXCHGL	CX, 0(BX)
+	SETEQ	swapped+16(FP)
+	RET
+
+TEXT ·CompareAndSwapUintptr(SB),NOSPLIT,$0-17
+	JMP	·CompareAndSwapUint32(SB)
+
+TEXT ·CompareAndSwapPointer(SB),NOSPLIT,$0-17
+	JMP	·CompareAndSwapUint32(SB)
+
+TEXT ·CompareAndSwapInt64(SB),NOSPLIT,$0-25
+	JMP	·CompareAndSwapUint64(SB)
+
+TEXT ·CompareAndSwapUint64(SB),NOSPLIT,$0-25
+	MOVL	addr+0(FP), BX
+	TESTL	$7, BX
+	JZ	2(PC)
+	MOVL	0, BX // crash with nil ptr deref
+	MOVQ	old+8(FP), AX
+	MOVQ	new+16(FP), CX
+	LOCK
+	CMPXCHGQ	CX, 0(BX)
+	SETEQ	swapped+24(FP)
+	RET
+
+TEXT ·AddInt32(SB),NOSPLIT,$0-12
+	JMP	·AddUint32(SB)
+
+TEXT ·AddUint32(SB),NOSPLIT,$0-12
+	MOVL	addr+0(FP), BX
+	MOVL	delta+4(FP), AX
+	MOVL	AX, CX
+	LOCK
+	XADDL	AX, 0(BX)
+	ADDL	AX, CX
+	MOVL	CX, new+8(FP)
+	RET
+
+TEXT ·AddUintptr(SB),NOSPLIT,$0-12
+	JMP	·AddUint32(SB)
+
+TEXT ·AddInt64(SB),NOSPLIT,$0-24
+	JMP	·AddUint64(SB)
+
+TEXT ·AddUint64(SB),NOSPLIT,$0-24
+	MOVL	addr+0(FP), BX
+	TESTL	$7, BX
+	JZ	2(PC)
+	MOVL	0, BX // crash with nil ptr deref
+	MOVQ	delta+8(FP), AX
+	MOVQ	AX, CX
+	LOCK
+	XADDQ	AX, 0(BX)
+	ADDQ	AX, CX
+	MOVQ	CX, new+16(FP)
+	RET
+
+TEXT ·LoadInt32(SB),NOSPLIT,$0-12
+	JMP	·LoadUint32(SB)
+
+TEXT ·LoadUint32(SB),NOSPLIT,$0-12
+	MOVL	addr+0(FP), AX
+	MOVL	0(AX), AX
+	MOVL	AX, val+8(FP)
+	RET
+
+TEXT ·LoadInt64(SB),NOSPLIT,$0-16
+	JMP	·LoadUint64(SB)
+
+TEXT ·LoadUint64(SB),NOSPLIT,$0-16
+	MOVL	addr+0(FP), AX
+	TESTL	$7, AX
+	JZ	2(PC)
+	MOVL	0, AX // crash with nil ptr deref
+	MOVQ	0(AX), AX
+	MOVQ	AX, val+8(FP)
+	RET
+
+TEXT ·LoadUintptr(SB),NOSPLIT,$0-12
+	JMP	·LoadPointer(SB)
+
+TEXT ·LoadPointer(SB),NOSPLIT,$0-12
+	MOVL	addr+0(FP), AX
+	MOVL	0(AX), AX
+	MOVL	AX, val+8(FP)
+	RET
+
+TEXT ·StoreInt32(SB),NOSPLIT,$0-8
+	JMP	·StoreUint32(SB)
+
+TEXT ·StoreUint32(SB),NOSPLIT,$0-8
+	MOVL	addr+0(FP), BX
+	MOVL	val+4(FP), AX
+	XCHGL	AX, 0(BX)
+	RET
+
+TEXT ·StoreInt64(SB),NOSPLIT,$0-16
+	JMP	·StoreUint64(SB)
+
+TEXT ·StoreUint64(SB),NOSPLIT,$0-16
+	MOVL	addr+0(FP), BX
+	TESTL	$7, BX
+	JZ	2(PC)
+	MOVL	0, BX // crash with nil ptr deref
+	MOVQ	val+8(FP), AX
+	XCHGQ	AX, 0(BX)
+	RET
+
+TEXT ·StoreUintptr(SB),NOSPLIT,$0-8
+	JMP	·StorePointer(SB)
+
+TEXT ·StorePointer(SB),NOSPLIT,$0-8
+	MOVL	addr+0(FP), BX
+	MOVL	val+4(FP), AX
+	XCHGL	AX, 0(BX)
+	RET
diff --git a/src/sync/atomic/asm_arm.s b/src/sync/atomic/asm_arm.s
new file mode 100644
index 0000000..8a85273
--- /dev/null
+++ b/src/sync/atomic/asm_arm.s
@@ -0,0 +1,197 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !race
+
+#include "textflag.h"
+
+// ARM atomic operations, for use by asm_$(GOOS)_arm.s.
+
+TEXT ·armCompareAndSwapUint32(SB),NOSPLIT,$0-13
+	MOVW	addr+0(FP), R1
+	MOVW	old+4(FP), R2
+	MOVW	new+8(FP), R3
+casloop:
+	// LDREX and STREX were introduced in ARMv6.
+	LDREX	(R1), R0
+	CMP	R0, R2
+	BNE	casfail
+	STREX	R3, (R1), R0
+	CMP	$0, R0
+	BNE	casloop
+	MOVW	$1, R0
+	MOVBU	R0, ret+12(FP)
+	RET
+casfail:
+	MOVW	$0, R0
+	MOVBU	R0, ret+12(FP)
+	RET
+
+TEXT ·armCompareAndSwapUint64(SB),NOSPLIT,$0-21
+	BL	fastCheck64<>(SB)
+	MOVW	addr+0(FP), R1
+	// make unaligned atomic access panic
+	AND.S	$7, R1, R2
+	BEQ 	2(PC)
+	MOVW	R2, (R2)
+	MOVW	oldlo+4(FP), R2
+	MOVW	oldhi+8(FP), R3
+	MOVW	newlo+12(FP), R4
+	MOVW	newhi+16(FP), R5
+cas64loop:
+	// LDREXD and STREXD were introduced in ARMv6k.
+	LDREXD	(R1), R6  // loads R6 and R7
+	CMP	R2, R6
+	BNE	cas64fail
+	CMP	R3, R7
+	BNE	cas64fail
+	STREXD	R4, (R1), R0	// stores R4 and R5
+	CMP	$0, R0
+	BNE	cas64loop
+	MOVW	$1, R0
+	MOVBU	R0, ret+20(FP)
+	RET
+cas64fail:
+	MOVW	$0, R0
+	MOVBU	R0, ret+20(FP)
+	RET
+
+TEXT ·armAddUint32(SB),NOSPLIT,$0-12
+	MOVW	addr+0(FP), R1
+	MOVW	delta+4(FP), R2
+addloop:
+	// LDREX and STREX were introduced in ARMv6.
+	LDREX	(R1), R3
+	ADD	R2, R3
+	STREX	R3, (R1), R0
+	CMP	$0, R0
+	BNE	addloop
+	MOVW	R3, ret+8(FP)
+	RET
+
+TEXT ·armAddUint64(SB),NOSPLIT,$0-20
+	BL	fastCheck64<>(SB)
+	MOVW	addr+0(FP), R1
+	// make unaligned atomic access panic
+	AND.S	$7, R1, R2
+	BEQ 	2(PC)
+	MOVW	R2, (R2)
+	MOVW	deltalo+4(FP), R2
+	MOVW	deltahi+8(FP), R3
+add64loop:
+	// LDREXD and STREXD were introduced in ARMv6k.
+	LDREXD	(R1), R4	// loads R4 and R5
+	ADD.S	R2, R4
+	ADC	R3, R5
+	STREXD	R4, (R1), R0	// stores R4 and R5
+	CMP	$0, R0
+	BNE	add64loop
+	MOVW	R4, retlo+12(FP)
+	MOVW	R5, rethi+16(FP)
+	RET
+
+TEXT ·armSwapUint32(SB),NOSPLIT,$0-12
+	MOVW	addr+0(FP), R1
+	MOVW	new+4(FP), R2
+swaploop:
+	// LDREX and STREX were introduced in ARMv6.
+	LDREX	(R1), R3
+	STREX	R2, (R1), R0
+	CMP	$0, R0
+	BNE	swaploop
+	MOVW	R3, old+8(FP)
+	RET
+
+TEXT ·armSwapUint64(SB),NOSPLIT,$0-20
+	BL	fastCheck64<>(SB)
+	MOVW	addr+0(FP), R1
+	// make unaligned atomic access panic
+	AND.S	$7, R1, R2
+	BEQ 	2(PC)
+	MOVW	R2, (R2)
+	MOVW	newlo+4(FP), R2
+	MOVW	newhi+8(FP), R3
+swap64loop:
+	// LDREXD and STREXD were introduced in ARMv6k.
+	LDREXD	(R1), R4	// loads R4 and R5
+	STREXD	R2, (R1), R0	// stores R2 and R3
+	CMP	$0, R0
+	BNE	swap64loop
+	MOVW	R4, oldlo+12(FP)
+	MOVW	R5, oldhi+16(FP)
+	RET
+
+TEXT ·armLoadUint64(SB),NOSPLIT,$0-12
+	BL	fastCheck64<>(SB)
+	MOVW	addr+0(FP), R1
+	// make unaligned atomic access panic
+	AND.S	$7, R1, R2
+	BEQ 	2(PC)
+	MOVW	R2, (R2)
+load64loop:
+	LDREXD	(R1), R2	// loads R2 and R3
+	STREXD	R2, (R1), R0	// stores R2 and R3
+	CMP	$0, R0
+	BNE	load64loop
+	MOVW	R2, vallo+4(FP)
+	MOVW	R3, valhi+8(FP)
+	RET
+
+TEXT ·armStoreUint64(SB),NOSPLIT,$0-12
+	BL	fastCheck64<>(SB)
+	MOVW	addr+0(FP), R1
+	// make unaligned atomic access panic
+	AND.S	$7, R1, R2
+	BEQ 	2(PC)
+	MOVW	R2, (R2)
+	MOVW	vallo+4(FP), R2
+	MOVW	valhi+8(FP), R3
+store64loop:
+	LDREXD	(R1), R4	// loads R4 and R5
+	STREXD	R2, (R1), R0	// stores R2 and R3
+	CMP	$0, R0
+	BNE	store64loop
+	RET
+
+// Check for broken 64-bit LDREXD as found in QEMU.
+// LDREXD followed by immediate STREXD should succeed.
+// If it fails, try a few times just to be sure (maybe our thread got
+// rescheduled between the two instructions) and then panic.
+// A bug in some copies of QEMU makes STREXD never succeed,
+// which will make uses of the 64-bit atomic operations loop forever.
+// If things are working, set okLDREXD to avoid future checks.
+// https://bugs.launchpad.net/qemu/+bug/670883.
+TEXT	check64<>(SB),NOSPLIT,$16-0
+	MOVW	$10, R1
+	// 8-aligned stack address scratch space.
+	MOVW	$8(R13), R5
+	AND	$~7, R5
+loop:
+	LDREXD	(R5), R2
+	STREXD	R2, (R5), R0
+	CMP	$0, R0
+	BEQ	ok
+	SUB	$1, R1
+	CMP	$0, R1
+	BNE	loop
+	// Must be buggy QEMU.
+	BL	·panic64(SB)
+ok:
+	RET
+
+// Fast, cached version of check.  No frame, just MOVW CMP RET after first time.
+TEXT	fastCheck64<>(SB),NOSPLIT,$-4
+	MOVW	ok64<>(SB), R0
+	CMP	$0, R0	// have we been here before?
+	RET.NE
+	B	slowCheck64<>(SB)
+
+TEXT slowCheck64<>(SB),NOSPLIT,$0-0
+	BL	check64<>(SB)
+	// Still here, must be okay.
+	MOVW	$1, R0
+	MOVW	R0, ok64<>(SB)
+	RET
+
+GLOBL ok64<>(SB), NOPTR, $4
diff --git a/src/sync/atomic/asm_freebsd_arm.s b/src/sync/atomic/asm_freebsd_arm.s
new file mode 100644
index 0000000..06b975e
--- /dev/null
+++ b/src/sync/atomic/asm_freebsd_arm.s
@@ -0,0 +1,109 @@
+// Copyright 2012 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+// FreeBSD/ARM atomic operations.
+// TODO(minux): this only supports ARMv6K or higher.
+
+TEXT ·CompareAndSwapInt32(SB),NOSPLIT,$0
+	B ·CompareAndSwapUint32(SB)
+
+TEXT ·CompareAndSwapUint32(SB),NOSPLIT,$0
+	B ·armCompareAndSwapUint32(SB)
+
+TEXT ·CompareAndSwapUintptr(SB),NOSPLIT,$0
+	B ·CompareAndSwapUint32(SB)
+
+TEXT ·CompareAndSwapPointer(SB),NOSPLIT,$0
+	B ·CompareAndSwapUint32(SB)
+
+TEXT ·AddInt32(SB),NOSPLIT,$0
+	B ·AddUint32(SB)
+
+TEXT ·AddUint32(SB),NOSPLIT,$0
+	B ·armAddUint32(SB)
+
+TEXT ·AddUintptr(SB),NOSPLIT,$0
+	B ·AddUint32(SB)
+
+TEXT ·SwapInt32(SB),NOSPLIT,$0
+	B ·SwapUint32(SB)
+
+TEXT ·SwapUint32(SB),NOSPLIT,$0
+	B ·armSwapUint32(SB)
+
+TEXT ·SwapUintptr(SB),NOSPLIT,$0
+	B ·SwapUint32(SB)
+
+TEXT ·SwapPointer(SB),NOSPLIT,$0
+	B ·SwapUint32(SB)
+
+TEXT ·CompareAndSwapInt64(SB),NOSPLIT,$0
+	B ·CompareAndSwapUint64(SB)
+
+TEXT ·CompareAndSwapUint64(SB),NOSPLIT,$-4
+	B ·armCompareAndSwapUint64(SB)
+
+TEXT ·AddInt64(SB),NOSPLIT,$0
+	B ·addUint64(SB)
+
+TEXT ·AddUint64(SB),NOSPLIT,$0
+	B ·addUint64(SB)
+
+TEXT ·SwapInt64(SB),NOSPLIT,$0
+	B ·swapUint64(SB)
+
+TEXT ·SwapUint64(SB),NOSPLIT,$0
+	B ·swapUint64(SB)
+
+TEXT ·LoadInt32(SB),NOSPLIT,$0
+	B ·LoadUint32(SB)
+
+TEXT ·LoadUint32(SB),NOSPLIT,$0-8
+	MOVW addr+0(FP), R1
+load32loop:
+	LDREX (R1), R2		// loads R2
+	STREX R2, (R1), R0	// stores R2
+	CMP $0, R0
+	BNE load32loop
+	MOVW R2, val+4(FP)
+	RET
+
+TEXT ·LoadInt64(SB),NOSPLIT,$0
+	B ·loadUint64(SB)
+
+TEXT ·LoadUint64(SB),NOSPLIT,$0
+	B ·loadUint64(SB)
+
+TEXT ·LoadUintptr(SB),NOSPLIT,$0
+	B ·LoadUint32(SB)
+
+TEXT ·LoadPointer(SB),NOSPLIT,$0
+	B ·LoadUint32(SB)
+
+TEXT ·StoreInt32(SB),NOSPLIT,$0
+	B ·StoreUint32(SB)
+
+TEXT ·StoreUint32(SB),NOSPLIT,$0-8
+	MOVW addr+0(FP), R1
+	MOVW val+4(FP), R2
+storeloop:
+	LDREX (R1), R4		// loads R4
+	STREX R2, (R1), R0	// stores R2
+	CMP $0, R0
+	BNE storeloop
+	RET
+
+TEXT ·StoreInt64(SB),NOSPLIT,$0
+	B ·storeUint64(SB)
+
+TEXT ·StoreUint64(SB),NOSPLIT,$0
+	B ·storeUint64(SB)
+
+TEXT ·StoreUintptr(SB),NOSPLIT,$0
+	B ·StoreUint32(SB)
+
+TEXT ·StorePointer(SB),NOSPLIT,$0
+	B ·StoreUint32(SB)
diff --git a/src/sync/atomic/asm_linux_arm.s b/src/sync/atomic/asm_linux_arm.s
new file mode 100644
index 0000000..9447584
--- /dev/null
+++ b/src/sync/atomic/asm_linux_arm.s
@@ -0,0 +1,216 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !race
+
+#include "textflag.h"
+
+// Linux/ARM atomic operations.
+
+// Because there is so much variation in ARM devices,
+// the Linux kernel provides an appropriate compare-and-swap
+// implementation at address 0xffff0fc0.  Caller sets:
+//	R0 = old value
+//	R1 = new value
+//	R2 = addr
+//	LR = return address
+// The function returns with CS true if the swap happened.
+// http://lxr.linux.no/linux+v2.6.37.2/arch/arm/kernel/entry-armv.S#L850
+// On older kernels (before 2.6.24) the function can incorrectly
+// report a conflict, so we have to double-check the compare ourselves
+// and retry if necessary.
+//
+// http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=b49c0f24cf6744a3f4fd09289fe7cade349dead5
+//
+TEXT cas<>(SB),NOSPLIT,$0
+	MOVW	$0xffff0fc0, PC
+
+TEXT ·CompareAndSwapInt32(SB),NOSPLIT,$0
+	B	·CompareAndSwapUint32(SB)
+
+// Implement using kernel cas for portability.
+TEXT ·CompareAndSwapUint32(SB),NOSPLIT,$0-13
+	MOVW	addr+0(FP), R2
+	// trigger potential paging fault here,
+	// because we don't know how to traceback through __kuser_cmpxchg
+	MOVW	(R2), R0
+	MOVW	old+4(FP), R0
+casagain:
+	MOVW	new+8(FP), R1
+	BL	cas<>(SB)
+	BCC	cascheck
+	MOVW	$1, R0
+casret:
+	MOVB	R0, swapped+12(FP)
+	RET
+cascheck:
+	// Kernel lies; double-check.
+	MOVW	addr+0(FP), R2
+	MOVW	old+4(FP), R0
+	MOVW	0(R2), R3
+	CMP	R0, R3
+	BEQ	casagain
+	MOVW	$0, R0
+	B	casret
+
+TEXT ·CompareAndSwapUintptr(SB),NOSPLIT,$0
+	B	·CompareAndSwapUint32(SB)
+
+TEXT ·CompareAndSwapPointer(SB),NOSPLIT,$0
+	B	·CompareAndSwapUint32(SB)
+
+TEXT ·AddInt32(SB),NOSPLIT,$0
+	B	·AddUint32(SB)
+
+// Implement using kernel cas for portability.
+TEXT ·AddUint32(SB),NOSPLIT,$0-12
+	MOVW	addr+0(FP), R2
+	MOVW	delta+4(FP), R4
+addloop1:
+	MOVW	0(R2), R0
+	MOVW	R0, R1
+	ADD	R4, R1
+	BL	cas<>(SB)
+	BCC	addloop1
+	MOVW	R1, new+8(FP)
+	RET
+
+TEXT ·AddUintptr(SB),NOSPLIT,$0
+	B	·AddUint32(SB)
+
+TEXT ·SwapInt32(SB),NOSPLIT,$0
+	B	·SwapUint32(SB)
+
+// Implement using kernel cas for portability.
+TEXT ·SwapUint32(SB),NOSPLIT,$0-12
+	MOVW	addr+0(FP), R2
+	MOVW	new+4(FP), R1
+swaploop1:
+	MOVW	0(R2), R0
+	MOVW	R0, R4 // cas smashes R0
+	BL	cas<>(SB)
+	BCC	swaploop1
+	MOVW	R4, old+8(FP)
+	RET
+
+TEXT ·SwapUintptr(SB),NOSPLIT,$0
+	B	·SwapUint32(SB)
+
+TEXT ·SwapPointer(SB),NOSPLIT,$0
+	B	·SwapUint32(SB)
+
+TEXT cas64<>(SB),NOSPLIT,$0
+	MOVW	$0xffff0f60, PC // __kuser_cmpxchg64: Linux-3.1 and above
+
+TEXT kernelCAS64<>(SB),NOSPLIT,$0-21
+	// int (*__kuser_cmpxchg64_t)(const int64_t *oldval, const int64_t *newval, volatile int64_t *ptr);
+	MOVW	addr+0(FP), R2 // ptr
+	// trigger potential paging fault here,
+	// because we don't know how to traceback through __kuser_cmpxchg64
+	MOVW	(R2), R0
+	// make unaligned atomic access panic
+	AND.S	$7, R2, R1
+	BEQ 	2(PC)
+	MOVW	R1, (R1)
+	MOVW	$4(FP), R0 // oldval
+	MOVW	$12(FP), R1 // newval
+	BL	cas64<>(SB)
+	MOVW.CS	$1, R0 // C is set if the kernel has changed *ptr
+	MOVW.CC	$0, R0
+	MOVW	R0, 20(FP)
+	RET
+
+TEXT ·generalCAS64(SB),NOSPLIT,$0-21
+	B  	runtime·cas64(SB)
+
+GLOBL armCAS64(SB), NOPTR, $4
+
+TEXT setupAndCallCAS64<>(SB),NOSPLIT,$-4-21
+	MOVW	$0xffff0ffc, R0 // __kuser_helper_version
+	MOVW	(R0), R0
+	// __kuser_cmpxchg64 only present if helper version >= 5
+	CMP 	$5, R0
+	MOVW.CS	$kernelCAS64<>(SB), R1
+	MOVW.CS	R1, armCAS64(SB)
+	MOVW.CS	R1, PC
+	MOVB	runtime·armArch(SB), R0
+	// LDREXD, STREXD only present on ARMv6K or higher
+	CMP	$6, R0 // TODO(minux): how to differentiate ARMv6 with ARMv6K?
+	MOVW.CS	$·armCompareAndSwapUint64(SB), R1
+	MOVW.CS	R1, armCAS64(SB)
+	MOVW.CS	R1, PC
+	// we are out of luck, can only use runtime's emulated 64-bit cas
+	MOVW	$·generalCAS64(SB), R1
+	MOVW	R1, armCAS64(SB)
+	MOVW	R1, PC
+
+TEXT ·CompareAndSwapInt64(SB),NOSPLIT,$0
+	B   	·CompareAndSwapUint64(SB)
+
+TEXT ·CompareAndSwapUint64(SB),NOSPLIT,$-4-21
+	MOVW	armCAS64(SB), R0
+	CMP 	$0, R0
+	MOVW.NE	R0, PC
+	B	setupAndCallCAS64<>(SB)
+
+TEXT ·AddInt64(SB),NOSPLIT,$0
+	B	·addUint64(SB)
+
+TEXT ·AddUint64(SB),NOSPLIT,$0
+	B	·addUint64(SB)
+
+TEXT ·SwapInt64(SB),NOSPLIT,$0
+	B	·swapUint64(SB)
+
+TEXT ·SwapUint64(SB),NOSPLIT,$0
+	B	·swapUint64(SB)
+
+TEXT ·LoadInt32(SB),NOSPLIT,$0
+	B	·LoadUint32(SB)
+
+TEXT ·LoadUint32(SB),NOSPLIT,$0-8
+	MOVW	addr+0(FP), R2
+loadloop1:
+	MOVW	0(R2), R0
+	MOVW	R0, R1
+	BL	cas<>(SB)
+	BCC	loadloop1
+	MOVW	R1, val+4(FP)
+	RET
+
+TEXT ·LoadInt64(SB),NOSPLIT,$0
+	B	·loadUint64(SB)
+
+TEXT ·LoadUint64(SB),NOSPLIT,$0
+	B	·loadUint64(SB)
+
+TEXT ·LoadUintptr(SB),NOSPLIT,$0
+	B	·LoadUint32(SB)
+
+TEXT ·LoadPointer(SB),NOSPLIT,$0
+	B	·LoadUint32(SB)
+
+TEXT ·StoreInt32(SB),NOSPLIT,$0
+	B	·StoreUint32(SB)
+
+TEXT ·StoreUint32(SB),NOSPLIT,$0-8
+	MOVW	addr+0(FP), R2
+	MOVW	val+4(FP), R1
+storeloop1:
+	MOVW	0(R2), R0
+	BL	cas<>(SB)
+	BCC	storeloop1
+	RET
+
+TEXT ·StoreInt64(SB),NOSPLIT,$0
+	B	·storeUint64(SB)
+
+TEXT ·StoreUint64(SB),NOSPLIT,$0
+	B	·storeUint64(SB)
+
+TEXT ·StoreUintptr(SB),NOSPLIT,$0
+	B	·StoreUint32(SB)
+
+TEXT ·StorePointer(SB),NOSPLIT,$0
+	B	·StoreUint32(SB)
diff --git a/src/sync/atomic/asm_nacl_arm.s b/src/sync/atomic/asm_nacl_arm.s
new file mode 100644
index 0000000..76f6233
--- /dev/null
+++ b/src/sync/atomic/asm_nacl_arm.s
@@ -0,0 +1,109 @@
+// 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"
+
+// NaCl/ARM atomic operations.
+// NaCl/ARM explicitly targets ARMv7A.
+
+TEXT ·CompareAndSwapInt32(SB),NOSPLIT,$0
+	B ·CompareAndSwapUint32(SB)
+
+TEXT ·CompareAndSwapUint32(SB),NOSPLIT,$0
+	B ·armCompareAndSwapUint32(SB)
+
+TEXT ·CompareAndSwapUintptr(SB),NOSPLIT,$0
+	B ·CompareAndSwapUint32(SB)
+
+TEXT ·CompareAndSwapPointer(SB),NOSPLIT,$0
+	B ·CompareAndSwapUint32(SB)
+
+TEXT ·AddInt32(SB),NOSPLIT,$0
+	B ·AddUint32(SB)
+
+TEXT ·AddUint32(SB),NOSPLIT,$0
+	B ·armAddUint32(SB)
+
+TEXT ·AddUintptr(SB),NOSPLIT,$0
+	B ·AddUint32(SB)
+
+TEXT ·SwapInt32(SB),NOSPLIT,$0
+	B ·SwapUint32(SB)
+
+TEXT ·SwapUint32(SB),NOSPLIT,$0
+	B ·armSwapUint32(SB)
+
+TEXT ·SwapUintptr(SB),NOSPLIT,$0
+	B ·SwapUint32(SB)
+
+TEXT ·SwapPointer(SB),NOSPLIT,$0
+	B ·SwapUint32(SB)
+
+TEXT ·CompareAndSwapInt64(SB),NOSPLIT,$0
+	B ·CompareAndSwapUint64(SB)
+
+TEXT ·CompareAndSwapUint64(SB),NOSPLIT,$-4
+	B ·armCompareAndSwapUint64(SB)
+
+TEXT ·AddInt64(SB),NOSPLIT,$0
+	B ·addUint64(SB)
+
+TEXT ·AddUint64(SB),NOSPLIT,$0
+	B ·addUint64(SB)
+
+TEXT ·SwapInt64(SB),NOSPLIT,$0
+	B ·swapUint64(SB)
+
+TEXT ·SwapUint64(SB),NOSPLIT,$0
+	B ·swapUint64(SB)
+
+TEXT ·LoadInt32(SB),NOSPLIT,$0
+	B ·LoadUint32(SB)
+
+TEXT ·LoadUint32(SB),NOSPLIT,$0-8
+	MOVW addr+0(FP), R1
+load32loop:
+	LDREX (R1), R2		// loads R2
+	STREX R2, (R1), R0	// stores R2
+	CMP $0, R0
+	BNE load32loop
+	MOVW R2, val+4(FP)
+	RET
+
+TEXT ·LoadInt64(SB),NOSPLIT,$0
+	B ·loadUint64(SB)
+
+TEXT ·LoadUint64(SB),NOSPLIT,$0
+	B ·loadUint64(SB)
+
+TEXT ·LoadUintptr(SB),NOSPLIT,$0
+	B ·LoadUint32(SB)
+
+TEXT ·LoadPointer(SB),NOSPLIT,$0
+	B ·LoadUint32(SB)
+
+TEXT ·StoreInt32(SB),NOSPLIT,$0
+	B ·StoreUint32(SB)
+
+TEXT ·StoreUint32(SB),NOSPLIT,$0-8
+	MOVW addr+0(FP), R1
+	MOVW val+4(FP), R2
+storeloop:
+	LDREX (R1), R4		// loads R4
+	STREX R2, (R1), R0	// stores R2
+	CMP $0, R0
+	BNE storeloop
+	RET
+
+TEXT ·StoreInt64(SB),NOSPLIT,$0
+	B ·storeUint64(SB)
+
+TEXT ·StoreUint64(SB),NOSPLIT,$0
+	B ·storeUint64(SB)
+
+TEXT ·StoreUintptr(SB),NOSPLIT,$0
+	B ·StoreUint32(SB)
+
+TEXT ·StorePointer(SB),NOSPLIT,$0
+	B ·StoreUint32(SB)
diff --git a/src/sync/atomic/asm_netbsd_arm.s b/src/sync/atomic/asm_netbsd_arm.s
new file mode 100644
index 0000000..dbe8089
--- /dev/null
+++ b/src/sync/atomic/asm_netbsd_arm.s
@@ -0,0 +1,109 @@
+// Copyright 2013 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+// NetBSD/ARM atomic operations.
+// TODO(minux): this only supports ARMv6K or higher.
+
+TEXT ·CompareAndSwapInt32(SB),NOSPLIT,$0
+	B ·CompareAndSwapUint32(SB)
+
+TEXT ·CompareAndSwapUint32(SB),NOSPLIT,$0
+	B ·armCompareAndSwapUint32(SB)
+
+TEXT ·CompareAndSwapUintptr(SB),NOSPLIT,$0
+	B ·CompareAndSwapUint32(SB)
+
+TEXT ·CompareAndSwapPointer(SB),NOSPLIT,$0
+	B ·CompareAndSwapUint32(SB)
+
+TEXT ·AddInt32(SB),NOSPLIT,$0
+	B ·AddUint32(SB)
+
+TEXT ·AddUint32(SB),NOSPLIT,$0
+	B ·armAddUint32(SB)
+
+TEXT ·AddUintptr(SB),NOSPLIT,$0
+	B ·AddUint32(SB)
+
+TEXT ·SwapInt32(SB),NOSPLIT,$0
+	B ·SwapUint32(SB)
+
+TEXT ·SwapUint32(SB),NOSPLIT,$0
+	B ·armSwapUint32(SB)
+
+TEXT ·SwapUintptr(SB),NOSPLIT,$0
+	B ·SwapUint32(SB)
+
+TEXT ·SwapPointer(SB),NOSPLIT,$0
+	B ·SwapUint32(SB)
+
+TEXT ·CompareAndSwapInt64(SB),NOSPLIT,$0
+	B ·CompareAndSwapUint64(SB)
+
+TEXT ·CompareAndSwapUint64(SB),NOSPLIT,$-4
+	B ·armCompareAndSwapUint64(SB)
+
+TEXT ·AddInt64(SB),NOSPLIT,$0
+	B ·addUint64(SB)
+
+TEXT ·AddUint64(SB),NOSPLIT,$0
+	B ·addUint64(SB)
+
+TEXT ·SwapInt64(SB),NOSPLIT,$0
+	B ·swapUint64(SB)
+
+TEXT ·SwapUint64(SB),NOSPLIT,$0
+	B ·swapUint64(SB)
+
+TEXT ·LoadInt32(SB),NOSPLIT,$0
+	B ·LoadUint32(SB)
+
+TEXT ·LoadUint32(SB),NOSPLIT,$0-8
+	MOVW addr+0(FP), R1
+load32loop:
+	LDREX (R1), R2		// loads R2
+	STREX R2, (R1), R0	// stores R2
+	CMP $0, R0
+	BNE load32loop
+	MOVW R2, val+4(FP)
+	RET
+
+TEXT ·LoadInt64(SB),NOSPLIT,$0
+	B ·loadUint64(SB)
+
+TEXT ·LoadUint64(SB),NOSPLIT,$0
+	B ·loadUint64(SB)
+
+TEXT ·LoadUintptr(SB),NOSPLIT,$0
+	B ·LoadUint32(SB)
+
+TEXT ·LoadPointer(SB),NOSPLIT,$0
+	B ·LoadUint32(SB)
+
+TEXT ·StoreInt32(SB),NOSPLIT,$0
+	B ·StoreUint32(SB)
+
+TEXT ·StoreUint32(SB),NOSPLIT,$0-8
+	MOVW addr+0(FP), R1
+	MOVW val+4(FP), R2
+storeloop:
+	LDREX (R1), R4		// loads R4
+	STREX R2, (R1), R0	// stores R2
+	CMP $0, R0
+	BNE storeloop
+	RET
+
+TEXT ·StoreInt64(SB),NOSPLIT,$0
+	B ·storeUint64(SB)
+
+TEXT ·StoreUint64(SB),NOSPLIT,$0
+	B ·storeUint64(SB)
+
+TEXT ·StoreUintptr(SB),NOSPLIT,$0
+	B ·StoreUint32(SB)
+
+TEXT ·StorePointer(SB),NOSPLIT,$0
+	B ·StoreUint32(SB)
diff --git a/src/pkg/sync/atomic/atomic_linux_arm_test.go b/src/sync/atomic/atomic_linux_arm_test.go
similarity index 100%
rename from src/pkg/sync/atomic/atomic_linux_arm_test.go
rename to src/sync/atomic/atomic_linux_arm_test.go
diff --git a/src/sync/atomic/atomic_test.go b/src/sync/atomic/atomic_test.go
new file mode 100644
index 0000000..9f13af4
--- /dev/null
+++ b/src/sync/atomic/atomic_test.go
@@ -0,0 +1,1509 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package atomic_test
+
+import (
+	"fmt"
+	"runtime"
+	"strings"
+	. "sync/atomic"
+	"testing"
+	"unsafe"
+)
+
+// Tests of correct behavior, without contention.
+// (Does the function work as advertised?)
+//
+// Test that the Add functions add correctly.
+// Test that the CompareAndSwap functions actually
+// do the comparison and the swap correctly.
+//
+// The loop over power-of-two values is meant to
+// ensure that the operations apply to the full word size.
+// The struct fields x.before and x.after check that the
+// operations do not extend past the full word size.
+
+const (
+	magic32 = 0xdedbeef
+	magic64 = 0xdeddeadbeefbeef
+)
+
+// Do the 64-bit functions panic?  If so, don't bother testing.
+var test64err = func() (err interface{}) {
+	defer func() {
+		err = recover()
+	}()
+	var x int64
+	AddInt64(&x, 1)
+	return nil
+}()
+
+func TestSwapInt32(t *testing.T) {
+	var x struct {
+		before int32
+		i      int32
+		after  int32
+	}
+	x.before = magic32
+	x.after = magic32
+	var j int32
+	for delta := int32(1); delta+delta > delta; delta += delta {
+		k := SwapInt32(&x.i, delta)
+		if x.i != delta || k != j {
+			t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i, j, k)
+		}
+		j = delta
+	}
+	if x.before != magic32 || x.after != magic32 {
+		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32)
+	}
+}
+
+func TestSwapUint32(t *testing.T) {
+	var x struct {
+		before uint32
+		i      uint32
+		after  uint32
+	}
+	x.before = magic32
+	x.after = magic32
+	var j uint32
+	for delta := uint32(1); delta+delta > delta; delta += delta {
+		k := SwapUint32(&x.i, delta)
+		if x.i != delta || k != j {
+			t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i, j, k)
+		}
+		j = delta
+	}
+	if x.before != magic32 || x.after != magic32 {
+		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32)
+	}
+}
+
+func TestSwapInt64(t *testing.T) {
+	if test64err != nil {
+		t.Skipf("Skipping 64-bit tests: %v", test64err)
+	}
+	var x struct {
+		before int64
+		i      int64
+		after  int64
+	}
+	x.before = magic64
+	x.after = magic64
+	var j int64
+	for delta := int64(1); delta+delta > delta; delta += delta {
+		k := SwapInt64(&x.i, delta)
+		if x.i != delta || k != j {
+			t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i, j, k)
+		}
+		j = delta
+	}
+	if x.before != magic64 || x.after != magic64 {
+		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, uint64(magic64), uint64(magic64))
+	}
+}
+
+func TestSwapUint64(t *testing.T) {
+	if test64err != nil {
+		t.Skipf("Skipping 64-bit tests: %v", test64err)
+	}
+	var x struct {
+		before uint64
+		i      uint64
+		after  uint64
+	}
+	x.before = magic64
+	x.after = magic64
+	var j uint64
+	for delta := uint64(1); delta+delta > delta; delta += delta {
+		k := SwapUint64(&x.i, delta)
+		if x.i != delta || k != j {
+			t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i, j, k)
+		}
+		j = delta
+	}
+	if x.before != magic64 || x.after != magic64 {
+		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, uint64(magic64), uint64(magic64))
+	}
+}
+
+func TestSwapUintptr(t *testing.T) {
+	var x struct {
+		before uintptr
+		i      uintptr
+		after  uintptr
+	}
+	var m uint64 = magic64
+	magicptr := uintptr(m)
+	x.before = magicptr
+	x.after = magicptr
+	var j uintptr
+	for delta := uintptr(1); delta+delta > delta; delta += delta {
+		k := SwapUintptr(&x.i, delta)
+		if x.i != delta || k != j {
+			t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i, j, k)
+		}
+		j = delta
+	}
+	if x.before != magicptr || x.after != magicptr {
+		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magicptr, magicptr)
+	}
+}
+
+func TestSwapPointer(t *testing.T) {
+	var x struct {
+		before uintptr
+		i      unsafe.Pointer
+		after  uintptr
+	}
+	var m uint64 = magic64
+	magicptr := uintptr(m)
+	x.before = magicptr
+	x.after = magicptr
+	var j uintptr
+	for delta := uintptr(1); delta+delta > delta; delta += delta {
+		k := SwapPointer(&x.i, unsafe.Pointer(delta))
+		if uintptr(x.i) != delta || uintptr(k) != j {
+			t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i, j, k)
+		}
+		j = delta
+	}
+	if x.before != magicptr || x.after != magicptr {
+		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magicptr, magicptr)
+	}
+}
+
+func TestAddInt32(t *testing.T) {
+	var x struct {
+		before int32
+		i      int32
+		after  int32
+	}
+	x.before = magic32
+	x.after = magic32
+	var j int32
+	for delta := int32(1); delta+delta > delta; delta += delta {
+		k := AddInt32(&x.i, delta)
+		j += delta
+		if x.i != j || k != j {
+			t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i, j, k)
+		}
+	}
+	if x.before != magic32 || x.after != magic32 {
+		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32)
+	}
+}
+
+func TestAddUint32(t *testing.T) {
+	var x struct {
+		before uint32
+		i      uint32
+		after  uint32
+	}
+	x.before = magic32
+	x.after = magic32
+	var j uint32
+	for delta := uint32(1); delta+delta > delta; delta += delta {
+		k := AddUint32(&x.i, delta)
+		j += delta
+		if x.i != j || k != j {
+			t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i, j, k)
+		}
+	}
+	if x.before != magic32 || x.after != magic32 {
+		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32)
+	}
+}
+
+func TestAddInt64(t *testing.T) {
+	if test64err != nil {
+		t.Skipf("Skipping 64-bit tests: %v", test64err)
+	}
+	var x struct {
+		before int64
+		i      int64
+		after  int64
+	}
+	x.before = magic64
+	x.after = magic64
+	var j int64
+	for delta := int64(1); delta+delta > delta; delta += delta {
+		k := AddInt64(&x.i, delta)
+		j += delta
+		if x.i != j || k != j {
+			t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i, j, k)
+		}
+	}
+	if x.before != magic64 || x.after != magic64 {
+		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, int64(magic64), int64(magic64))
+	}
+}
+
+func TestAddUint64(t *testing.T) {
+	if test64err != nil {
+		t.Skipf("Skipping 64-bit tests: %v", test64err)
+	}
+	var x struct {
+		before uint64
+		i      uint64
+		after  uint64
+	}
+	x.before = magic64
+	x.after = magic64
+	var j uint64
+	for delta := uint64(1); delta+delta > delta; delta += delta {
+		k := AddUint64(&x.i, delta)
+		j += delta
+		if x.i != j || k != j {
+			t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i, j, k)
+		}
+	}
+	if x.before != magic64 || x.after != magic64 {
+		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, uint64(magic64), uint64(magic64))
+	}
+}
+
+func TestAddUintptr(t *testing.T) {
+	var x struct {
+		before uintptr
+		i      uintptr
+		after  uintptr
+	}
+	var m uint64 = magic64
+	magicptr := uintptr(m)
+	x.before = magicptr
+	x.after = magicptr
+	var j uintptr
+	for delta := uintptr(1); delta+delta > delta; delta += delta {
+		k := AddUintptr(&x.i, delta)
+		j += delta
+		if x.i != j || k != j {
+			t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i, j, k)
+		}
+	}
+	if x.before != magicptr || x.after != magicptr {
+		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magicptr, magicptr)
+	}
+}
+
+func TestCompareAndSwapInt32(t *testing.T) {
+	var x struct {
+		before int32
+		i      int32
+		after  int32
+	}
+	x.before = magic32
+	x.after = magic32
+	for val := int32(1); val+val > val; val += val {
+		x.i = val
+		if !CompareAndSwapInt32(&x.i, val, val+1) {
+			t.Fatalf("should have swapped %#x %#x", val, val+1)
+		}
+		if x.i != val+1 {
+			t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i, val+1)
+		}
+		x.i = val + 1
+		if CompareAndSwapInt32(&x.i, val, val+2) {
+			t.Fatalf("should not have swapped %#x %#x", val, val+2)
+		}
+		if x.i != val+1 {
+			t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i, val+1)
+		}
+	}
+	if x.before != magic32 || x.after != magic32 {
+		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32)
+	}
+}
+
+func TestCompareAndSwapUint32(t *testing.T) {
+	var x struct {
+		before uint32
+		i      uint32
+		after  uint32
+	}
+	x.before = magic32
+	x.after = magic32
+	for val := uint32(1); val+val > val; val += val {
+		x.i = val
+		if !CompareAndSwapUint32(&x.i, val, val+1) {
+			t.Fatalf("should have swapped %#x %#x", val, val+1)
+		}
+		if x.i != val+1 {
+			t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i, val+1)
+		}
+		x.i = val + 1
+		if CompareAndSwapUint32(&x.i, val, val+2) {
+			t.Fatalf("should not have swapped %#x %#x", val, val+2)
+		}
+		if x.i != val+1 {
+			t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i, val+1)
+		}
+	}
+	if x.before != magic32 || x.after != magic32 {
+		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32)
+	}
+}
+
+func TestCompareAndSwapInt64(t *testing.T) {
+	if test64err != nil {
+		t.Skipf("Skipping 64-bit tests: %v", test64err)
+	}
+	var x struct {
+		before int64
+		i      int64
+		after  int64
+	}
+	x.before = magic64
+	x.after = magic64
+	for val := int64(1); val+val > val; val += val {
+		x.i = val
+		if !CompareAndSwapInt64(&x.i, val, val+1) {
+			t.Fatalf("should have swapped %#x %#x", val, val+1)
+		}
+		if x.i != val+1 {
+			t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i, val+1)
+		}
+		x.i = val + 1
+		if CompareAndSwapInt64(&x.i, val, val+2) {
+			t.Fatalf("should not have swapped %#x %#x", val, val+2)
+		}
+		if x.i != val+1 {
+			t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i, val+1)
+		}
+	}
+	if x.before != magic64 || x.after != magic64 {
+		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, uint64(magic64), uint64(magic64))
+	}
+}
+
+func testCompareAndSwapUint64(t *testing.T, cas func(*uint64, uint64, uint64) bool) {
+	if test64err != nil {
+		t.Skipf("Skipping 64-bit tests: %v", test64err)
+	}
+	var x struct {
+		before uint64
+		i      uint64
+		after  uint64
+	}
+	x.before = magic64
+	x.after = magic64
+	for val := uint64(1); val+val > val; val += val {
+		x.i = val
+		if !cas(&x.i, val, val+1) {
+			t.Fatalf("should have swapped %#x %#x", val, val+1)
+		}
+		if x.i != val+1 {
+			t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i, val+1)
+		}
+		x.i = val + 1
+		if cas(&x.i, val, val+2) {
+			t.Fatalf("should not have swapped %#x %#x", val, val+2)
+		}
+		if x.i != val+1 {
+			t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i, val+1)
+		}
+	}
+	if x.before != magic64 || x.after != magic64 {
+		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, uint64(magic64), uint64(magic64))
+	}
+}
+
+func TestCompareAndSwapUint64(t *testing.T) {
+	testCompareAndSwapUint64(t, CompareAndSwapUint64)
+}
+
+func TestCompareAndSwapUintptr(t *testing.T) {
+	var x struct {
+		before uintptr
+		i      uintptr
+		after  uintptr
+	}
+	var m uint64 = magic64
+	magicptr := uintptr(m)
+	x.before = magicptr
+	x.after = magicptr
+	for val := uintptr(1); val+val > val; val += val {
+		x.i = val
+		if !CompareAndSwapUintptr(&x.i, val, val+1) {
+			t.Fatalf("should have swapped %#x %#x", val, val+1)
+		}
+		if x.i != val+1 {
+			t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i, val+1)
+		}
+		x.i = val + 1
+		if CompareAndSwapUintptr(&x.i, val, val+2) {
+			t.Fatalf("should not have swapped %#x %#x", val, val+2)
+		}
+		if x.i != val+1 {
+			t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i, val+1)
+		}
+	}
+	if x.before != magicptr || x.after != magicptr {
+		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magicptr, magicptr)
+	}
+}
+
+func TestCompareAndSwapPointer(t *testing.T) {
+	var x struct {
+		before uintptr
+		i      unsafe.Pointer
+		after  uintptr
+	}
+	var m uint64 = magic64
+	magicptr := uintptr(m)
+	x.before = magicptr
+	x.after = magicptr
+	for val := uintptr(1); val+val > val; val += val {
+		x.i = unsafe.Pointer(val)
+		if !CompareAndSwapPointer(&x.i, unsafe.Pointer(val), unsafe.Pointer(val+1)) {
+			t.Fatalf("should have swapped %#x %#x", val, val+1)
+		}
+		if x.i != unsafe.Pointer(val+1) {
+			t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i, val+1)
+		}
+		x.i = unsafe.Pointer(val + 1)
+		if CompareAndSwapPointer(&x.i, unsafe.Pointer(val), unsafe.Pointer(val+2)) {
+			t.Fatalf("should not have swapped %#x %#x", val, val+2)
+		}
+		if x.i != unsafe.Pointer(val+1) {
+			t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i, val+1)
+		}
+	}
+	if x.before != magicptr || x.after != magicptr {
+		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magicptr, magicptr)
+	}
+}
+
+func TestLoadInt32(t *testing.T) {
+	var x struct {
+		before int32
+		i      int32
+		after  int32
+	}
+	x.before = magic32
+	x.after = magic32
+	for delta := int32(1); delta+delta > delta; delta += delta {
+		k := LoadInt32(&x.i)
+		if k != x.i {
+			t.Fatalf("delta=%d i=%d k=%d", delta, x.i, k)
+		}
+		x.i += delta
+	}
+	if x.before != magic32 || x.after != magic32 {
+		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32)
+	}
+}
+
+func TestLoadUint32(t *testing.T) {
+	var x struct {
+		before uint32
+		i      uint32
+		after  uint32
+	}
+	x.before = magic32
+	x.after = magic32
+	for delta := uint32(1); delta+delta > delta; delta += delta {
+		k := LoadUint32(&x.i)
+		if k != x.i {
+			t.Fatalf("delta=%d i=%d k=%d", delta, x.i, k)
+		}
+		x.i += delta
+	}
+	if x.before != magic32 || x.after != magic32 {
+		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32)
+	}
+}
+
+func TestLoadInt64(t *testing.T) {
+	if test64err != nil {
+		t.Skipf("Skipping 64-bit tests: %v", test64err)
+	}
+	var x struct {
+		before int64
+		i      int64
+		after  int64
+	}
+	x.before = magic64
+	x.after = magic64
+	for delta := int64(1); delta+delta > delta; delta += delta {
+		k := LoadInt64(&x.i)
+		if k != x.i {
+			t.Fatalf("delta=%d i=%d k=%d", delta, x.i, k)
+		}
+		x.i += delta
+	}
+	if x.before != magic64 || x.after != magic64 {
+		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, uint64(magic64), uint64(magic64))
+	}
+}
+
+func TestLoadUint64(t *testing.T) {
+	if test64err != nil {
+		t.Skipf("Skipping 64-bit tests: %v", test64err)
+	}
+	var x struct {
+		before uint64
+		i      uint64
+		after  uint64
+	}
+	x.before = magic64
+	x.after = magic64
+	for delta := uint64(1); delta+delta > delta; delta += delta {
+		k := LoadUint64(&x.i)
+		if k != x.i {
+			t.Fatalf("delta=%d i=%d k=%d", delta, x.i, k)
+		}
+		x.i += delta
+	}
+	if x.before != magic64 || x.after != magic64 {
+		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, uint64(magic64), uint64(magic64))
+	}
+}
+
+func TestLoadUintptr(t *testing.T) {
+	var x struct {
+		before uintptr
+		i      uintptr
+		after  uintptr
+	}
+	var m uint64 = magic64
+	magicptr := uintptr(m)
+	x.before = magicptr
+	x.after = magicptr
+	for delta := uintptr(1); delta+delta > delta; delta += delta {
+		k := LoadUintptr(&x.i)
+		if k != x.i {
+			t.Fatalf("delta=%d i=%d k=%d", delta, x.i, k)
+		}
+		x.i += delta
+	}
+	if x.before != magicptr || x.after != magicptr {
+		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magicptr, magicptr)
+	}
+}
+
+func TestLoadPointer(t *testing.T) {
+	var x struct {
+		before uintptr
+		i      unsafe.Pointer
+		after  uintptr
+	}
+	var m uint64 = magic64
+	magicptr := uintptr(m)
+	x.before = magicptr
+	x.after = magicptr
+	for delta := uintptr(1); delta+delta > delta; delta += delta {
+		k := LoadPointer(&x.i)
+		if k != x.i {
+			t.Fatalf("delta=%d i=%d k=%d", delta, x.i, k)
+		}
+		x.i = unsafe.Pointer(uintptr(x.i) + delta)
+	}
+	if x.before != magicptr || x.after != magicptr {
+		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magicptr, magicptr)
+	}
+}
+
+func TestStoreInt32(t *testing.T) {
+	var x struct {
+		before int32
+		i      int32
+		after  int32
+	}
+	x.before = magic32
+	x.after = magic32
+	v := int32(0)
+	for delta := int32(1); delta+delta > delta; delta += delta {
+		StoreInt32(&x.i, v)
+		if x.i != v {
+			t.Fatalf("delta=%d i=%d v=%d", delta, x.i, v)
+		}
+		v += delta
+	}
+	if x.before != magic32 || x.after != magic32 {
+		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32)
+	}
+}
+
+func TestStoreUint32(t *testing.T) {
+	var x struct {
+		before uint32
+		i      uint32
+		after  uint32
+	}
+	x.before = magic32
+	x.after = magic32
+	v := uint32(0)
+	for delta := uint32(1); delta+delta > delta; delta += delta {
+		StoreUint32(&x.i, v)
+		if x.i != v {
+			t.Fatalf("delta=%d i=%d v=%d", delta, x.i, v)
+		}
+		v += delta
+	}
+	if x.before != magic32 || x.after != magic32 {
+		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32)
+	}
+}
+
+func TestStoreInt64(t *testing.T) {
+	if test64err != nil {
+		t.Skipf("Skipping 64-bit tests: %v", test64err)
+	}
+	var x struct {
+		before int64
+		i      int64
+		after  int64
+	}
+	x.before = magic64
+	x.after = magic64
+	v := int64(0)
+	for delta := int64(1); delta+delta > delta; delta += delta {
+		StoreInt64(&x.i, v)
+		if x.i != v {
+			t.Fatalf("delta=%d i=%d v=%d", delta, x.i, v)
+		}
+		v += delta
+	}
+	if x.before != magic64 || x.after != magic64 {
+		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, uint64(magic64), uint64(magic64))
+	}
+}
+
+func TestStoreUint64(t *testing.T) {
+	if test64err != nil {
+		t.Skipf("Skipping 64-bit tests: %v", test64err)
+	}
+	var x struct {
+		before uint64
+		i      uint64
+		after  uint64
+	}
+	x.before = magic64
+	x.after = magic64
+	v := uint64(0)
+	for delta := uint64(1); delta+delta > delta; delta += delta {
+		StoreUint64(&x.i, v)
+		if x.i != v {
+			t.Fatalf("delta=%d i=%d v=%d", delta, x.i, v)
+		}
+		v += delta
+	}
+	if x.before != magic64 || x.after != magic64 {
+		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, uint64(magic64), uint64(magic64))
+	}
+}
+
+func TestStoreUintptr(t *testing.T) {
+	var x struct {
+		before uintptr
+		i      uintptr
+		after  uintptr
+	}
+	var m uint64 = magic64
+	magicptr := uintptr(m)
+	x.before = magicptr
+	x.after = magicptr
+	v := uintptr(0)
+	for delta := uintptr(1); delta+delta > delta; delta += delta {
+		StoreUintptr(&x.i, v)
+		if x.i != v {
+			t.Fatalf("delta=%d i=%d v=%d", delta, x.i, v)
+		}
+		v += delta
+	}
+	if x.before != magicptr || x.after != magicptr {
+		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magicptr, magicptr)
+	}
+}
+
+func TestStorePointer(t *testing.T) {
+	var x struct {
+		before uintptr
+		i      unsafe.Pointer
+		after  uintptr
+	}
+	var m uint64 = magic64
+	magicptr := uintptr(m)
+	x.before = magicptr
+	x.after = magicptr
+	v := unsafe.Pointer(uintptr(0))
+	for delta := uintptr(1); delta+delta > delta; delta += delta {
+		StorePointer(&x.i, unsafe.Pointer(v))
+		if x.i != v {
+			t.Fatalf("delta=%d i=%d v=%d", delta, x.i, v)
+		}
+		v = unsafe.Pointer(uintptr(v) + delta)
+	}
+	if x.before != magicptr || x.after != magicptr {
+		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magicptr, magicptr)
+	}
+}
+
+// Tests of correct behavior, with contention.
+// (Is the function atomic?)
+//
+// For each function, we write a "hammer" function that repeatedly
+// uses the atomic operation to add 1 to a value.  After running
+// multiple hammers in parallel, check that we end with the correct
+// total.
+// Swap can't add 1, so it uses a different scheme.
+// The functions repeatedly generate a pseudo-random number such that
+// low bits are equal to high bits, swap, check that the old value
+// has low and high bits equal.
+
+var hammer32 = map[string]func(*uint32, int){
+	"SwapInt32":             hammerSwapInt32,
+	"SwapUint32":            hammerSwapUint32,
+	"SwapUintptr":           hammerSwapUintptr32,
+	"SwapPointer":           hammerSwapPointer32,
+	"AddInt32":              hammerAddInt32,
+	"AddUint32":             hammerAddUint32,
+	"AddUintptr":            hammerAddUintptr32,
+	"CompareAndSwapInt32":   hammerCompareAndSwapInt32,
+	"CompareAndSwapUint32":  hammerCompareAndSwapUint32,
+	"CompareAndSwapUintptr": hammerCompareAndSwapUintptr32,
+	"CompareAndSwapPointer": hammerCompareAndSwapPointer32,
+}
+
+func init() {
+	var v uint64 = 1 << 50
+	if uintptr(v) != 0 {
+		// 64-bit system; clear uintptr tests
+		delete(hammer32, "SwapUintptr")
+		delete(hammer32, "SwapPointer")
+		delete(hammer32, "AddUintptr")
+		delete(hammer32, "CompareAndSwapUintptr")
+		delete(hammer32, "CompareAndSwapPointer")
+	}
+}
+
+func hammerSwapInt32(uaddr *uint32, count int) {
+	addr := (*int32)(unsafe.Pointer(uaddr))
+	seed := int(uintptr(unsafe.Pointer(&count)))
+	for i := 0; i < count; i++ {
+		new := uint32(seed+i)<<16 | uint32(seed+i)<<16>>16
+		old := uint32(SwapInt32(addr, int32(new)))
+		if old>>16 != old<<16>>16 {
+			panic(fmt.Sprintf("SwapInt32 is not atomic: %v", old))
+		}
+	}
+}
+
+func hammerSwapUint32(addr *uint32, count int) {
+	seed := int(uintptr(unsafe.Pointer(&count)))
+	for i := 0; i < count; i++ {
+		new := uint32(seed+i)<<16 | uint32(seed+i)<<16>>16
+		old := SwapUint32(addr, new)
+		if old>>16 != old<<16>>16 {
+			panic(fmt.Sprintf("SwapUint32 is not atomic: %v", old))
+		}
+	}
+}
+
+func hammerSwapUintptr32(uaddr *uint32, count int) {
+	// only safe when uintptr is 32-bit.
+	// not called on 64-bit systems.
+	addr := (*uintptr)(unsafe.Pointer(uaddr))
+	seed := int(uintptr(unsafe.Pointer(&count)))
+	for i := 0; i < count; i++ {
+		new := uintptr(seed+i)<<16 | uintptr(seed+i)<<16>>16
+		old := SwapUintptr(addr, new)
+		if old>>16 != old<<16>>16 {
+			panic(fmt.Sprintf("SwapUintptr is not atomic: %#08x", old))
+		}
+	}
+}
+
+func hammerSwapPointer32(uaddr *uint32, count int) {
+	// only safe when uintptr is 32-bit.
+	// not called on 64-bit systems.
+	addr := (*unsafe.Pointer)(unsafe.Pointer(uaddr))
+	seed := int(uintptr(unsafe.Pointer(&count)))
+	for i := 0; i < count; i++ {
+		new := uintptr(seed+i)<<16 | uintptr(seed+i)<<16>>16
+		old := uintptr(SwapPointer(addr, unsafe.Pointer(new)))
+		if old>>16 != old<<16>>16 {
+			panic(fmt.Sprintf("SwapPointer is not atomic: %#08x", old))
+		}
+	}
+}
+
+func hammerAddInt32(uaddr *uint32, count int) {
+	addr := (*int32)(unsafe.Pointer(uaddr))
+	for i := 0; i < count; i++ {
+		AddInt32(addr, 1)
+	}
+}
+
+func hammerAddUint32(addr *uint32, count int) {
+	for i := 0; i < count; i++ {
+		AddUint32(addr, 1)
+	}
+}
+
+func hammerAddUintptr32(uaddr *uint32, count int) {
+	// only safe when uintptr is 32-bit.
+	// not called on 64-bit systems.
+	addr := (*uintptr)(unsafe.Pointer(uaddr))
+	for i := 0; i < count; i++ {
+		AddUintptr(addr, 1)
+	}
+}
+
+func hammerCompareAndSwapInt32(uaddr *uint32, count int) {
+	addr := (*int32)(unsafe.Pointer(uaddr))
+	for i := 0; i < count; i++ {
+		for {
+			v := LoadInt32(addr)
+			if CompareAndSwapInt32(addr, v, v+1) {
+				break
+			}
+		}
+	}
+}
+
+func hammerCompareAndSwapUint32(addr *uint32, count int) {
+	for i := 0; i < count; i++ {
+		for {
+			v := LoadUint32(addr)
+			if CompareAndSwapUint32(addr, v, v+1) {
+				break
+			}
+		}
+	}
+}
+
+func hammerCompareAndSwapUintptr32(uaddr *uint32, count int) {
+	// only safe when uintptr is 32-bit.
+	// not called on 64-bit systems.
+	addr := (*uintptr)(unsafe.Pointer(uaddr))
+	for i := 0; i < count; i++ {
+		for {
+			v := LoadUintptr(addr)
+			if CompareAndSwapUintptr(addr, v, v+1) {
+				break
+			}
+		}
+	}
+}
+
+func hammerCompareAndSwapPointer32(uaddr *uint32, count int) {
+	// only safe when uintptr is 32-bit.
+	// not called on 64-bit systems.
+	addr := (*unsafe.Pointer)(unsafe.Pointer(uaddr))
+	for i := 0; i < count; i++ {
+		for {
+			v := LoadPointer(addr)
+			if CompareAndSwapPointer(addr, v, unsafe.Pointer(uintptr(v)+1)) {
+				break
+			}
+		}
+	}
+}
+
+func TestHammer32(t *testing.T) {
+	const p = 4
+	n := 100000
+	if testing.Short() {
+		n = 1000
+	}
+	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(p))
+
+	for name, testf := range hammer32 {
+		c := make(chan int)
+		var val uint32
+		for i := 0; i < p; i++ {
+			go func() {
+				defer func() {
+					if err := recover(); err != nil {
+						t.Error(err.(string))
+					}
+					c <- 1
+				}()
+				testf(&val, n)
+			}()
+		}
+		for i := 0; i < p; i++ {
+			<-c
+		}
+		if !strings.HasPrefix(name, "Swap") && val != uint32(n)*p {
+			t.Fatalf("%s: val=%d want %d", name, val, n*p)
+		}
+	}
+}
+
+var hammer64 = map[string]func(*uint64, int){
+	"SwapInt64":             hammerSwapInt64,
+	"SwapUint64":            hammerSwapUint64,
+	"SwapUintptr":           hammerSwapUintptr64,
+	"SwapPointer":           hammerSwapPointer64,
+	"AddInt64":              hammerAddInt64,
+	"AddUint64":             hammerAddUint64,
+	"AddUintptr":            hammerAddUintptr64,
+	"CompareAndSwapInt64":   hammerCompareAndSwapInt64,
+	"CompareAndSwapUint64":  hammerCompareAndSwapUint64,
+	"CompareAndSwapUintptr": hammerCompareAndSwapUintptr64,
+	"CompareAndSwapPointer": hammerCompareAndSwapPointer64,
+}
+
+func init() {
+	var v uint64 = 1 << 50
+	if uintptr(v) == 0 {
+		// 32-bit system; clear uintptr tests
+		delete(hammer64, "SwapUintptr")
+		delete(hammer64, "SwapPointer")
+		delete(hammer64, "AddUintptr")
+		delete(hammer64, "CompareAndSwapUintptr")
+		delete(hammer64, "CompareAndSwapPointer")
+	}
+}
+
+func hammerSwapInt64(uaddr *uint64, count int) {
+	addr := (*int64)(unsafe.Pointer(uaddr))
+	seed := int(uintptr(unsafe.Pointer(&count)))
+	for i := 0; i < count; i++ {
+		new := uint64(seed+i)<<32 | uint64(seed+i)<<32>>32
+		old := uint64(SwapInt64(addr, int64(new)))
+		if old>>32 != old<<32>>32 {
+			panic(fmt.Sprintf("SwapInt64 is not atomic: %v", old))
+		}
+	}
+}
+
+func hammerSwapUint64(addr *uint64, count int) {
+	seed := int(uintptr(unsafe.Pointer(&count)))
+	for i := 0; i < count; i++ {
+		new := uint64(seed+i)<<32 | uint64(seed+i)<<32>>32
+		old := SwapUint64(addr, new)
+		if old>>32 != old<<32>>32 {
+			panic(fmt.Sprintf("SwapUint64 is not atomic: %v", old))
+		}
+	}
+}
+
+func hammerSwapUintptr64(uaddr *uint64, count int) {
+	// only safe when uintptr is 64-bit.
+	// not called on 32-bit systems.
+	addr := (*uintptr)(unsafe.Pointer(uaddr))
+	seed := int(uintptr(unsafe.Pointer(&count)))
+	for i := 0; i < count; i++ {
+		new := uintptr(seed+i)<<32 | uintptr(seed+i)<<32>>32
+		old := SwapUintptr(addr, new)
+		if old>>32 != old<<32>>32 {
+			panic(fmt.Sprintf("SwapUintptr is not atomic: %v", old))
+		}
+	}
+}
+
+func hammerSwapPointer64(uaddr *uint64, count int) {
+	// only safe when uintptr is 64-bit.
+	// not called on 32-bit systems.
+	addr := (*unsafe.Pointer)(unsafe.Pointer(uaddr))
+	seed := int(uintptr(unsafe.Pointer(&count)))
+	for i := 0; i < count; i++ {
+		new := uintptr(seed+i)<<32 | uintptr(seed+i)<<32>>32
+		old := uintptr(SwapPointer(addr, unsafe.Pointer(new)))
+		if old>>32 != old<<32>>32 {
+			panic(fmt.Sprintf("SwapPointer is not atomic: %v", old))
+		}
+	}
+}
+
+func hammerAddInt64(uaddr *uint64, count int) {
+	addr := (*int64)(unsafe.Pointer(uaddr))
+	for i := 0; i < count; i++ {
+		AddInt64(addr, 1)
+	}
+}
+
+func hammerAddUint64(addr *uint64, count int) {
+	for i := 0; i < count; i++ {
+		AddUint64(addr, 1)
+	}
+}
+
+func hammerAddUintptr64(uaddr *uint64, count int) {
+	// only safe when uintptr is 64-bit.
+	// not called on 32-bit systems.
+	addr := (*uintptr)(unsafe.Pointer(uaddr))
+	for i := 0; i < count; i++ {
+		AddUintptr(addr, 1)
+	}
+}
+
+func hammerCompareAndSwapInt64(uaddr *uint64, count int) {
+	addr := (*int64)(unsafe.Pointer(uaddr))
+	for i := 0; i < count; i++ {
+		for {
+			v := LoadInt64(addr)
+			if CompareAndSwapInt64(addr, v, v+1) {
+				break
+			}
+		}
+	}
+}
+
+func hammerCompareAndSwapUint64(addr *uint64, count int) {
+	for i := 0; i < count; i++ {
+		for {
+			v := LoadUint64(addr)
+			if CompareAndSwapUint64(addr, v, v+1) {
+				break
+			}
+		}
+	}
+}
+
+func hammerCompareAndSwapUintptr64(uaddr *uint64, count int) {
+	// only safe when uintptr is 64-bit.
+	// not called on 32-bit systems.
+	addr := (*uintptr)(unsafe.Pointer(uaddr))
+	for i := 0; i < count; i++ {
+		for {
+			v := LoadUintptr(addr)
+			if CompareAndSwapUintptr(addr, v, v+1) {
+				break
+			}
+		}
+	}
+}
+
+func hammerCompareAndSwapPointer64(uaddr *uint64, count int) {
+	// only safe when uintptr is 64-bit.
+	// not called on 32-bit systems.
+	addr := (*unsafe.Pointer)(unsafe.Pointer(uaddr))
+	for i := 0; i < count; i++ {
+		for {
+			v := LoadPointer(addr)
+			if CompareAndSwapPointer(addr, v, unsafe.Pointer(uintptr(v)+1)) {
+				break
+			}
+		}
+	}
+}
+
+func TestHammer64(t *testing.T) {
+	if test64err != nil {
+		t.Skipf("Skipping 64-bit tests: %v", test64err)
+	}
+	const p = 4
+	n := 100000
+	if testing.Short() {
+		n = 1000
+	}
+	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(p))
+
+	for name, testf := range hammer64 {
+		c := make(chan int)
+		var val uint64
+		for i := 0; i < p; i++ {
+			go func() {
+				defer func() {
+					if err := recover(); err != nil {
+						t.Error(err.(string))
+					}
+					c <- 1
+				}()
+				testf(&val, n)
+			}()
+		}
+		for i := 0; i < p; i++ {
+			<-c
+		}
+		if !strings.HasPrefix(name, "Swap") && val != uint64(n)*p {
+			t.Fatalf("%s: val=%d want %d", name, val, n*p)
+		}
+	}
+}
+
+func hammerStoreLoadInt32(t *testing.T, paddr unsafe.Pointer) {
+	addr := (*int32)(paddr)
+	v := LoadInt32(addr)
+	vlo := v & ((1 << 16) - 1)
+	vhi := v >> 16
+	if vlo != vhi {
+		t.Fatalf("Int32: %#x != %#x", vlo, vhi)
+	}
+	new := v + 1 + 1<<16
+	if vlo == 1e4 {
+		new = 0
+	}
+	StoreInt32(addr, new)
+}
+
+func hammerStoreLoadUint32(t *testing.T, paddr unsafe.Pointer) {
+	addr := (*uint32)(paddr)
+	v := LoadUint32(addr)
+	vlo := v & ((1 << 16) - 1)
+	vhi := v >> 16
+	if vlo != vhi {
+		t.Fatalf("Uint32: %#x != %#x", vlo, vhi)
+	}
+	new := v + 1 + 1<<16
+	if vlo == 1e4 {
+		new = 0
+	}
+	StoreUint32(addr, new)
+}
+
+func hammerStoreLoadInt64(t *testing.T, paddr unsafe.Pointer) {
+	addr := (*int64)(paddr)
+	v := LoadInt64(addr)
+	vlo := v & ((1 << 32) - 1)
+	vhi := v >> 32
+	if vlo != vhi {
+		t.Fatalf("Int64: %#x != %#x", vlo, vhi)
+	}
+	new := v + 1 + 1<<32
+	StoreInt64(addr, new)
+}
+
+func hammerStoreLoadUint64(t *testing.T, paddr unsafe.Pointer) {
+	addr := (*uint64)(paddr)
+	v := LoadUint64(addr)
+	vlo := v & ((1 << 32) - 1)
+	vhi := v >> 32
+	if vlo != vhi {
+		t.Fatalf("Uint64: %#x != %#x", vlo, vhi)
+	}
+	new := v + 1 + 1<<32
+	StoreUint64(addr, new)
+}
+
+func hammerStoreLoadUintptr(t *testing.T, paddr unsafe.Pointer) {
+	addr := (*uintptr)(paddr)
+	var test64 uint64 = 1 << 50
+	arch32 := uintptr(test64) == 0
+	v := LoadUintptr(addr)
+	new := v
+	if arch32 {
+		vlo := v & ((1 << 16) - 1)
+		vhi := v >> 16
+		if vlo != vhi {
+			t.Fatalf("Uintptr: %#x != %#x", vlo, vhi)
+		}
+		new = v + 1 + 1<<16
+		if vlo == 1e4 {
+			new = 0
+		}
+	} else {
+		vlo := v & ((1 << 32) - 1)
+		vhi := v >> 32
+		if vlo != vhi {
+			t.Fatalf("Uintptr: %#x != %#x", vlo, vhi)
+		}
+		inc := uint64(1 + 1<<32)
+		new = v + uintptr(inc)
+	}
+	StoreUintptr(addr, new)
+}
+
+func hammerStoreLoadPointer(t *testing.T, paddr unsafe.Pointer) {
+	addr := (*unsafe.Pointer)(paddr)
+	var test64 uint64 = 1 << 50
+	arch32 := uintptr(test64) == 0
+	v := uintptr(LoadPointer(addr))
+	new := v
+	if arch32 {
+		vlo := v & ((1 << 16) - 1)
+		vhi := v >> 16
+		if vlo != vhi {
+			t.Fatalf("Pointer: %#x != %#x", vlo, vhi)
+		}
+		new = v + 1 + 1<<16
+		if vlo == 1e4 {
+			new = 0
+		}
+	} else {
+		vlo := v & ((1 << 32) - 1)
+		vhi := v >> 32
+		if vlo != vhi {
+			t.Fatalf("Pointer: %#x != %#x", vlo, vhi)
+		}
+		inc := uint64(1 + 1<<32)
+		new = v + uintptr(inc)
+	}
+	StorePointer(addr, unsafe.Pointer(new))
+}
+
+func TestHammerStoreLoad(t *testing.T) {
+	var tests []func(*testing.T, unsafe.Pointer)
+	tests = append(tests, hammerStoreLoadInt32, hammerStoreLoadUint32,
+		hammerStoreLoadUintptr, hammerStoreLoadPointer)
+	if test64err == nil {
+		tests = append(tests, hammerStoreLoadInt64, hammerStoreLoadUint64)
+	}
+	n := int(1e6)
+	if testing.Short() {
+		n = int(1e4)
+	}
+	const procs = 8
+	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(procs))
+	for _, tt := range tests {
+		c := make(chan int)
+		var val uint64
+		for p := 0; p < procs; p++ {
+			go func() {
+				for i := 0; i < n; i++ {
+					tt(t, unsafe.Pointer(&val))
+				}
+				c <- 1
+			}()
+		}
+		for p := 0; p < procs; p++ {
+			<-c
+		}
+	}
+}
+
+func TestStoreLoadSeqCst32(t *testing.T) {
+	if runtime.NumCPU() == 1 {
+		t.Skipf("Skipping test on %v processor machine", runtime.NumCPU())
+	}
+	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4))
+	N := int32(1e3)
+	if testing.Short() {
+		N = int32(1e2)
+	}
+	c := make(chan bool, 2)
+	X := [2]int32{}
+	ack := [2][3]int32{{-1, -1, -1}, {-1, -1, -1}}
+	for p := 0; p < 2; p++ {
+		go func(me int) {
+			he := 1 - me
+			for i := int32(1); i < N; i++ {
+				StoreInt32(&X[me], i)
+				my := LoadInt32(&X[he])
+				StoreInt32(&ack[me][i%3], my)
+				for w := 1; LoadInt32(&ack[he][i%3]) == -1; w++ {
+					if w%1000 == 0 {
+						runtime.Gosched()
+					}
+				}
+				his := LoadInt32(&ack[he][i%3])
+				if (my != i && my != i-1) || (his != i && his != i-1) {
+					t.Fatalf("invalid values: %d/%d (%d)", my, his, i)
+				}
+				if my != i && his != i {
+					t.Fatalf("store/load are not sequentially consistent: %d/%d (%d)", my, his, i)
+				}
+				StoreInt32(&ack[me][(i-1)%3], -1)
+			}
+			c <- true
+		}(p)
+	}
+	<-c
+	<-c
+}
+
+func TestStoreLoadSeqCst64(t *testing.T) {
+	if runtime.NumCPU() == 1 {
+		t.Skipf("Skipping test on %v processor machine", runtime.NumCPU())
+	}
+	if test64err != nil {
+		t.Skipf("Skipping 64-bit tests: %v", test64err)
+	}
+	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4))
+	N := int64(1e3)
+	if testing.Short() {
+		N = int64(1e2)
+	}
+	c := make(chan bool, 2)
+	X := [2]int64{}
+	ack := [2][3]int64{{-1, -1, -1}, {-1, -1, -1}}
+	for p := 0; p < 2; p++ {
+		go func(me int) {
+			he := 1 - me
+			for i := int64(1); i < N; i++ {
+				StoreInt64(&X[me], i)
+				my := LoadInt64(&X[he])
+				StoreInt64(&ack[me][i%3], my)
+				for w := 1; LoadInt64(&ack[he][i%3]) == -1; w++ {
+					if w%1000 == 0 {
+						runtime.Gosched()
+					}
+				}
+				his := LoadInt64(&ack[he][i%3])
+				if (my != i && my != i-1) || (his != i && his != i-1) {
+					t.Fatalf("invalid values: %d/%d (%d)", my, his, i)
+				}
+				if my != i && his != i {
+					t.Fatalf("store/load are not sequentially consistent: %d/%d (%d)", my, his, i)
+				}
+				StoreInt64(&ack[me][(i-1)%3], -1)
+			}
+			c <- true
+		}(p)
+	}
+	<-c
+	<-c
+}
+
+func TestStoreLoadRelAcq32(t *testing.T) {
+	if runtime.NumCPU() == 1 {
+		t.Skipf("Skipping test on %v processor machine", runtime.NumCPU())
+	}
+	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4))
+	N := int32(1e3)
+	if testing.Short() {
+		N = int32(1e2)
+	}
+	c := make(chan bool, 2)
+	type Data struct {
+		signal int32
+		pad1   [128]int8
+		data1  int32
+		pad2   [128]int8
+		data2  float32
+	}
+	var X Data
+	for p := int32(0); p < 2; p++ {
+		go func(p int32) {
+			for i := int32(1); i < N; i++ {
+				if (i+p)%2 == 0 {
+					X.data1 = i
+					X.data2 = float32(i)
+					StoreInt32(&X.signal, i)
+				} else {
+					for w := 1; LoadInt32(&X.signal) != i; w++ {
+						if w%1000 == 0 {
+							runtime.Gosched()
+						}
+					}
+					d1 := X.data1
+					d2 := X.data2
+					if d1 != i || d2 != float32(i) {
+						t.Fatalf("incorrect data: %d/%g (%d)", d1, d2, i)
+					}
+				}
+			}
+			c <- true
+		}(p)
+	}
+	<-c
+	<-c
+}
+
+func TestStoreLoadRelAcq64(t *testing.T) {
+	if runtime.NumCPU() == 1 {
+		t.Skipf("Skipping test on %v processor machine", runtime.NumCPU())
+	}
+	if test64err != nil {
+		t.Skipf("Skipping 64-bit tests: %v", test64err)
+	}
+	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4))
+	N := int64(1e3)
+	if testing.Short() {
+		N = int64(1e2)
+	}
+	c := make(chan bool, 2)
+	type Data struct {
+		signal int64
+		pad1   [128]int8
+		data1  int64
+		pad2   [128]int8
+		data2  float64
+	}
+	var X Data
+	for p := int64(0); p < 2; p++ {
+		go func(p int64) {
+			for i := int64(1); i < N; i++ {
+				if (i+p)%2 == 0 {
+					X.data1 = i
+					X.data2 = float64(i)
+					StoreInt64(&X.signal, i)
+				} else {
+					for w := 1; LoadInt64(&X.signal) != i; w++ {
+						if w%1000 == 0 {
+							runtime.Gosched()
+						}
+					}
+					d1 := X.data1
+					d2 := X.data2
+					if d1 != i || d2 != float64(i) {
+						t.Fatalf("incorrect data: %d/%g (%d)", d1, d2, i)
+					}
+				}
+			}
+			c <- true
+		}(p)
+	}
+	<-c
+	<-c
+}
+
+func shouldPanic(t *testing.T, name string, f func()) {
+	defer func() {
+		if recover() == nil {
+			t.Errorf("%s did not panic", name)
+		}
+	}()
+	f()
+}
+
+func TestUnaligned64(t *testing.T) {
+	// Unaligned 64-bit atomics on 32-bit systems are
+	// a continual source of pain. Test that on 32-bit systems they crash
+	// instead of failing silently.
+	if unsafe.Sizeof(int(0)) != 4 {
+		t.Skip("test only runs on 32-bit systems")
+	}
+
+	x := make([]uint32, 4)
+	p := (*uint64)(unsafe.Pointer(&x[1])) // misaligned
+
+	shouldPanic(t, "LoadUint64", func() { LoadUint64(p) })
+	shouldPanic(t, "StoreUint64", func() { StoreUint64(p, 1) })
+	shouldPanic(t, "CompareAndSwapUint64", func() { CompareAndSwapUint64(p, 1, 2) })
+	shouldPanic(t, "AddUint64", func() { AddUint64(p, 3) })
+}
+
+func TestNilDeref(t *testing.T) {
+	if p := runtime.GOOS + "/" + runtime.GOARCH; p == "freebsd/arm" || p == "netbsd/arm" {
+		t.Skipf("issue 7338: skipping test on %q", p)
+	}
+	funcs := [...]func(){
+		func() { CompareAndSwapInt32(nil, 0, 0) },
+		func() { CompareAndSwapInt64(nil, 0, 0) },
+		func() { CompareAndSwapUint32(nil, 0, 0) },
+		func() { CompareAndSwapUint64(nil, 0, 0) },
+		func() { CompareAndSwapUintptr(nil, 0, 0) },
+		func() { CompareAndSwapPointer(nil, nil, nil) },
+		func() { SwapInt32(nil, 0) },
+		func() { SwapUint32(nil, 0) },
+		func() { SwapInt64(nil, 0) },
+		func() { SwapUint64(nil, 0) },
+		func() { SwapUintptr(nil, 0) },
+		func() { SwapPointer(nil, nil) },
+		func() { AddInt32(nil, 0) },
+		func() { AddUint32(nil, 0) },
+		func() { AddInt64(nil, 0) },
+		func() { AddUint64(nil, 0) },
+		func() { AddUintptr(nil, 0) },
+		func() { LoadInt32(nil) },
+		func() { LoadInt64(nil) },
+		func() { LoadUint32(nil) },
+		func() { LoadUint64(nil) },
+		func() { LoadUintptr(nil) },
+		func() { LoadPointer(nil) },
+		func() { StoreInt32(nil, 0) },
+		func() { StoreInt64(nil, 0) },
+		func() { StoreUint32(nil, 0) },
+		func() { StoreUint64(nil, 0) },
+		func() { StoreUintptr(nil, 0) },
+		func() { StorePointer(nil, nil) },
+	}
+	for _, f := range funcs {
+		func() {
+			defer func() {
+				runtime.GC()
+				recover()
+			}()
+			f()
+		}()
+	}
+}
diff --git a/src/sync/atomic/doc.go b/src/sync/atomic/doc.go
new file mode 100644
index 0000000..10fb8c9
--- /dev/null
+++ b/src/sync/atomic/doc.go
@@ -0,0 +1,149 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package atomic provides low-level atomic memory primitives
+// useful for implementing synchronization algorithms.
+//
+// These functions require great care to be used correctly.
+// Except for special, low-level applications, synchronization is better
+// done with channels or the facilities of the sync package.
+// Share memory by communicating;
+// don't communicate by sharing memory.
+//
+// The swap operation, implemented by the SwapT functions, is the atomic
+// equivalent of:
+//
+//	old = *addr
+//	*addr = new
+//	return old
+//
+// The compare-and-swap operation, implemented by the CompareAndSwapT
+// functions, is the atomic equivalent of:
+//
+//	if *addr == old {
+//		*addr = new
+//		return true
+//	}
+//	return false
+//
+// The add operation, implemented by the AddT functions, is the atomic
+// equivalent of:
+//
+//	*addr += delta
+//	return *addr
+//
+// The load and store operations, implemented by the LoadT and StoreT
+// functions, are the atomic equivalents of "return *addr" and
+// "*addr = val".
+//
+package atomic
+
+import (
+	"unsafe"
+)
+
+// BUG(rsc): On x86-32, the 64-bit functions use instructions unavailable before the Pentium MMX.
+//
+// On non-Linux ARM, the 64-bit functions use instructions unavailable before the ARMv6k core.
+//
+// On both ARM and x86-32, it is the caller's responsibility to arrange for 64-bit
+// alignment of 64-bit words accessed atomically. The first word in a global
+// variable or in an allocated struct or slice can be relied upon to be
+// 64-bit aligned.
+
+// SwapInt32 atomically stores new into *addr and returns the previous *addr value.
+func SwapInt32(addr *int32, new int32) (old int32)
+
+// SwapInt64 atomically stores new into *addr and returns the previous *addr value.
+func SwapInt64(addr *int64, new int64) (old int64)
+
+// SwapUint32 atomically stores new into *addr and returns the previous *addr value.
+func SwapUint32(addr *uint32, new uint32) (old uint32)
+
+// SwapUint64 atomically stores new into *addr and returns the previous *addr value.
+func SwapUint64(addr *uint64, new uint64) (old uint64)
+
+// SwapUintptr atomically stores new into *addr and returns the previous *addr value.
+func SwapUintptr(addr *uintptr, new uintptr) (old uintptr)
+
+// SwapPointer atomically stores new into *addr and returns the previous *addr value.
+func SwapPointer(addr *unsafe.Pointer, new unsafe.Pointer) (old unsafe.Pointer)
+
+// CompareAndSwapInt32 executes the compare-and-swap operation for an int32 value.
+func CompareAndSwapInt32(addr *int32, old, new int32) (swapped bool)
+
+// CompareAndSwapInt64 executes the compare-and-swap operation for an int64 value.
+func CompareAndSwapInt64(addr *int64, old, new int64) (swapped bool)
+
+// CompareAndSwapUint32 executes the compare-and-swap operation for a uint32 value.
+func CompareAndSwapUint32(addr *uint32, old, new uint32) (swapped bool)
+
+// CompareAndSwapUint64 executes the compare-and-swap operation for a uint64 value.
+func CompareAndSwapUint64(addr *uint64, old, new uint64) (swapped bool)
+
+// CompareAndSwapUintptr executes the compare-and-swap operation for a uintptr value.
+func CompareAndSwapUintptr(addr *uintptr, old, new uintptr) (swapped bool)
+
+// CompareAndSwapPointer executes the compare-and-swap operation for a unsafe.Pointer value.
+func CompareAndSwapPointer(addr *unsafe.Pointer, old, new unsafe.Pointer) (swapped bool)
+
+// AddInt32 atomically adds delta to *addr and returns the new value.
+func AddInt32(addr *int32, delta int32) (new int32)
+
+// AddUint32 atomically adds delta to *addr and returns the new value.
+// To subtract a signed positive constant value c from x, do AddUint32(&x, ^uint32(c-1)).
+// In particular, to decrement x, do AddUint32(&x, ^uint32(0)).
+func AddUint32(addr *uint32, delta uint32) (new uint32)
+
+// AddInt64 atomically adds delta to *addr and returns the new value.
+func AddInt64(addr *int64, delta int64) (new int64)
+
+// AddUint64 atomically adds delta to *addr and returns the new value.
+// To subtract a signed positive constant value c from x, do AddUint64(&x, ^uint64(c-1)).
+// In particular, to decrement x, do AddUint64(&x, ^uint64(0)).
+func AddUint64(addr *uint64, delta uint64) (new uint64)
+
+// AddUintptr atomically adds delta to *addr and returns the new value.
+func AddUintptr(addr *uintptr, delta uintptr) (new uintptr)
+
+// LoadInt32 atomically loads *addr.
+func LoadInt32(addr *int32) (val int32)
+
+// LoadInt64 atomically loads *addr.
+func LoadInt64(addr *int64) (val int64)
+
+// LoadUint32 atomically loads *addr.
+func LoadUint32(addr *uint32) (val uint32)
+
+// LoadUint64 atomically loads *addr.
+func LoadUint64(addr *uint64) (val uint64)
+
+// LoadUintptr atomically loads *addr.
+func LoadUintptr(addr *uintptr) (val uintptr)
+
+// LoadPointer atomically loads *addr.
+func LoadPointer(addr *unsafe.Pointer) (val unsafe.Pointer)
+
+// StoreInt32 atomically stores val into *addr.
+func StoreInt32(addr *int32, val int32)
+
+// StoreInt64 atomically stores val into *addr.
+func StoreInt64(addr *int64, val int64)
+
+// StoreUint32 atomically stores val into *addr.
+func StoreUint32(addr *uint32, val uint32)
+
+// StoreUint64 atomically stores val into *addr.
+func StoreUint64(addr *uint64, val uint64)
+
+// StoreUintptr atomically stores val into *addr.
+func StoreUintptr(addr *uintptr, val uintptr)
+
+// StorePointer atomically stores val into *addr.
+func StorePointer(addr *unsafe.Pointer, val unsafe.Pointer)
+
+// Helper for ARM.  Linker will discard on other systems
+func panic64() {
+	panic("sync/atomic: broken 64-bit atomic operations (buggy QEMU)")
+}
diff --git a/src/sync/atomic/export_linux_arm_test.go b/src/sync/atomic/export_linux_arm_test.go
new file mode 100644
index 0000000..9f0c856
--- /dev/null
+++ b/src/sync/atomic/export_linux_arm_test.go
@@ -0,0 +1,7 @@
+// Copyright 2013 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package atomic
+
+var GeneralCAS64 = generalCAS64
diff --git a/src/sync/atomic/race.s b/src/sync/atomic/race.s
new file mode 100644
index 0000000..bdce766
--- /dev/null
+++ b/src/sync/atomic/race.s
@@ -0,0 +1,8 @@
+// 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.
+
+// +build race
+
+// This file is here only to allow external functions.
+// The operations are implemented in src/runtime/race_amd64.s
diff --git a/src/sync/atomic/value.go b/src/sync/atomic/value.go
new file mode 100644
index 0000000..ab3aa11
--- /dev/null
+++ b/src/sync/atomic/value.go
@@ -0,0 +1,85 @@
+// 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 atomic
+
+import (
+	"unsafe"
+)
+
+// A Value provides an atomic load and store of a consistently typed value.
+// Values can be created as part of other data structures.
+// The zero value for a Value returns nil from Load.
+// Once Store has been called, a Value must not be copied.
+type Value struct {
+	v interface{}
+}
+
+// ifaceWords is interface{} internal representation.
+type ifaceWords struct {
+	typ  unsafe.Pointer
+	data unsafe.Pointer
+}
+
+// Load returns the value set by the most recent Store.
+// It returns nil if there has been no call to Store for this Value.
+func (v *Value) Load() (x interface{}) {
+	vp := (*ifaceWords)(unsafe.Pointer(v))
+	typ := LoadPointer(&vp.typ)
+	if typ == nil || uintptr(typ) == ^uintptr(0) {
+		// First store not yet completed.
+		return nil
+	}
+	data := LoadPointer(&vp.data)
+	xp := (*ifaceWords)(unsafe.Pointer(&x))
+	xp.typ = typ
+	xp.data = data
+	return
+}
+
+// Store sets the value of the Value to x.
+// All calls to Store for a given Value must use values of the same concrete type.
+// Store of an inconsistent type panics, as does Store(nil).
+func (v *Value) Store(x interface{}) {
+	if x == nil {
+		panic("sync/atomic: store of nil value into Value")
+	}
+	vp := (*ifaceWords)(unsafe.Pointer(v))
+	xp := (*ifaceWords)(unsafe.Pointer(&x))
+	for {
+		typ := LoadPointer(&vp.typ)
+		if typ == nil {
+			// Attempt to start first store.
+			// Disable preemption so that other goroutines can use
+			// active spin wait to wait for completion; and so that
+			// GC does not see the fake type accidentally.
+			runtime_procPin()
+			if !CompareAndSwapPointer(&vp.typ, nil, unsafe.Pointer(^uintptr(0))) {
+				runtime_procUnpin()
+				continue
+			}
+			// Complete first store.
+			StorePointer(&vp.data, xp.data)
+			StorePointer(&vp.typ, xp.typ)
+			runtime_procUnpin()
+			return
+		}
+		if uintptr(typ) == ^uintptr(0) {
+			// First store in progress. Wait.
+			// Since we disable preemption around the first store,
+			// we can wait with active spinning.
+			continue
+		}
+		// First store completed. Check type and overwrite data.
+		if typ != xp.typ {
+			panic("sync/atomic: store of inconsistently typed value into Value")
+		}
+		StorePointer(&vp.data, xp.data)
+		return
+	}
+}
+
+// Disable/enable preemption, implemented in runtime.
+func runtime_procPin()
+func runtime_procUnpin()
diff --git a/src/sync/atomic/value_test.go b/src/sync/atomic/value_test.go
new file mode 100644
index 0000000..382dc68
--- /dev/null
+++ b/src/sync/atomic/value_test.go
@@ -0,0 +1,195 @@
+// 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 atomic_test
+
+import (
+	"math/rand"
+	"runtime"
+	"sync"
+	. "sync/atomic"
+	"testing"
+	"time"
+)
+
+func TestValue(t *testing.T) {
+	var v Value
+	if v.Load() != nil {
+		t.Fatal("initial Value is not nil")
+	}
+	v.Store(42)
+	x := v.Load()
+	if xx, ok := x.(int); !ok || xx != 42 {
+		t.Fatalf("wrong value: got %+v, want 42", x)
+	}
+	v.Store(84)
+	x = v.Load()
+	if xx, ok := x.(int); !ok || xx != 84 {
+		t.Fatalf("wrong value: got %+v, want 84", x)
+	}
+}
+
+func TestValueLarge(t *testing.T) {
+	var v Value
+	v.Store("foo")
+	x := v.Load()
+	if xx, ok := x.(string); !ok || xx != "foo" {
+		t.Fatalf("wrong value: got %+v, want foo", x)
+	}
+	v.Store("barbaz")
+	x = v.Load()
+	if xx, ok := x.(string); !ok || xx != "barbaz" {
+		t.Fatalf("wrong value: got %+v, want barbaz", x)
+	}
+}
+
+func TestValuePanic(t *testing.T) {
+	const nilErr = "sync/atomic: store of nil value into Value"
+	const badErr = "sync/atomic: store of inconsistently typed value into Value"
+	var v Value
+	func() {
+		defer func() {
+			err := recover()
+			if err != nilErr {
+				t.Fatalf("inconsistent store panic: got '%v', want '%v'", err, nilErr)
+			}
+		}()
+		v.Store(nil)
+	}()
+	v.Store(42)
+	func() {
+		defer func() {
+			err := recover()
+			if err != badErr {
+				t.Fatalf("inconsistent store panic: got '%v', want '%v'", err, badErr)
+			}
+		}()
+		v.Store("foo")
+	}()
+	func() {
+		defer func() {
+			err := recover()
+			if err != nilErr {
+				t.Fatalf("inconsistent store panic: got '%v', want '%v'", err, nilErr)
+			}
+		}()
+		v.Store(nil)
+	}()
+}
+
+func TestValueConcurrent(t *testing.T) {
+	tests := [][]interface{}{
+		{uint16(0), ^uint16(0), uint16(1 + 2<<8), uint16(3 + 4<<8)},
+		{uint32(0), ^uint32(0), uint32(1 + 2<<16), uint32(3 + 4<<16)},
+		{uint64(0), ^uint64(0), uint64(1 + 2<<32), uint64(3 + 4<<32)},
+		{complex(0, 0), complex(1, 2), complex(3, 4), complex(5, 6)},
+	}
+	p := 4 * runtime.GOMAXPROCS(0)
+	for _, test := range tests {
+		var v Value
+		done := make(chan bool)
+		for i := 0; i < p; i++ {
+			go func() {
+				r := rand.New(rand.NewSource(rand.Int63()))
+			loop:
+				for j := 0; j < 1e5; j++ {
+					x := test[r.Intn(len(test))]
+					v.Store(x)
+					x = v.Load()
+					for _, x1 := range test {
+						if x == x1 {
+							continue loop
+						}
+					}
+					t.Logf("loaded unexpected value %+v, want %+v", x, test)
+					done <- false
+				}
+				done <- true
+			}()
+		}
+		for i := 0; i < p; i++ {
+			if !<-done {
+				t.FailNow()
+			}
+		}
+	}
+}
+
+func BenchmarkValueRead(b *testing.B) {
+	var v Value
+	v.Store(new(int))
+	b.RunParallel(func(pb *testing.PB) {
+		for pb.Next() {
+			x := v.Load().(*int)
+			if *x != 0 {
+				b.Fatalf("wrong value: got %v, want 0", *x)
+			}
+		}
+	})
+}
+
+// The following example shows how to use Value for periodic program config updates
+// and propagation of the changes to worker goroutines.
+func ExampleValue_config() {
+	var config Value // holds current server configuration
+	// Create initial config value and store into config.
+	config.Store(loadConfig())
+	go func() {
+		// Reload config every 10 seconds
+		// and update config value with the new version.
+		for {
+			time.Sleep(10 * time.Second)
+			config.Store(loadConfig())
+		}
+	}()
+	// Create worker goroutines that handle incoming requests
+	// using the latest config value.
+	for i := 0; i < 10; i++ {
+		go func() {
+			for r := range requests() {
+				c := config.Load()
+				// Handle request r using config c.
+				_, _ = r, c
+			}
+		}()
+	}
+}
+
+func loadConfig() map[string]string {
+	return make(map[string]string)
+}
+
+func requests() chan int {
+	return make(chan int)
+}
+
+// The following example shows how to maintain a scalable frequently read,
+// but infrequently updated data structure using copy-on-write idiom.
+func ExampleValue_readMostly() {
+	type Map map[string]string
+	var m Value
+	m.Store(make(Map))
+	var mu sync.Mutex // used only by writers
+	// read function can be used to read the data without further synchronization
+	read := func(key string) (val string) {
+		m1 := m.Load().(Map)
+		return m1[key]
+	}
+	// insert function can be used to update the data without further synchronization
+	insert := func(key, val string) {
+		mu.Lock() // synchronize with other potential writers
+		defer mu.Unlock()
+		m1 := m.Load().(Map) // load current value of the data structure
+		m2 := make(Map)      // create a new value
+		for k, v := range m1 {
+			m2[k] = v // copy all data from the current object to the new one
+		}
+		m2[key] = val // do the update that we need
+		m.Store(m2)   // atomically replace the current object with the new one
+		// At this point all new readers start working with the new version.
+		// The old version will be garbage collected once the existing readers
+		// (if any) are done with it.
+	}
+	_, _ = read, insert
+}
diff --git a/src/pkg/sync/cond.go b/src/sync/cond.go
similarity index 100%
rename from src/pkg/sync/cond.go
rename to src/sync/cond.go
diff --git a/src/pkg/sync/cond_test.go b/src/sync/cond_test.go
similarity index 100%
rename from src/pkg/sync/cond_test.go
rename to src/sync/cond_test.go
diff --git a/src/pkg/sync/example_test.go b/src/sync/example_test.go
similarity index 100%
rename from src/pkg/sync/example_test.go
rename to src/sync/example_test.go
diff --git a/src/pkg/sync/export_test.go b/src/sync/export_test.go
similarity index 100%
rename from src/pkg/sync/export_test.go
rename to src/sync/export_test.go
diff --git a/src/pkg/sync/mutex.go b/src/sync/mutex.go
similarity index 100%
rename from src/pkg/sync/mutex.go
rename to src/sync/mutex.go
diff --git a/src/pkg/sync/mutex_test.go b/src/sync/mutex_test.go
similarity index 100%
rename from src/pkg/sync/mutex_test.go
rename to src/sync/mutex_test.go
diff --git a/src/sync/once.go b/src/sync/once.go
new file mode 100644
index 0000000..10b42fd
--- /dev/null
+++ b/src/sync/once.go
@@ -0,0 +1,46 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package sync
+
+import (
+	"sync/atomic"
+)
+
+// Once is an object that will perform exactly one action.
+type Once struct {
+	m    Mutex
+	done uint32
+}
+
+// Do calls the function f if and only if Do is being called for the
+// first time for this instance of Once. In other words, given
+// 	var once Once
+// if once.Do(f) is called multiple times, only the first call will invoke f,
+// even if f has a different value in each invocation.  A new instance of
+// Once is required for each function to execute.
+//
+// Do is intended for initialization that must be run exactly once.  Since f
+// is niladic, it may be necessary to use a function literal to capture the
+// arguments to a function to be invoked by Do:
+// 	config.once.Do(func() { config.init(filename) })
+//
+// Because no call to Do returns until the one call to f returns, if f causes
+// Do to be called, it will deadlock.
+//
+// If f panics, Do considers it to have returned; future calls of Do return
+// without calling f.
+//
+func (o *Once) Do(f func()) {
+	if atomic.LoadUint32(&o.done) == 1 {
+		return
+	}
+	// Slow-path.
+	o.m.Lock()
+	defer o.m.Unlock()
+	if o.done == 0 {
+		defer atomic.StoreUint32(&o.done, 1)
+		f()
+	}
+}
diff --git a/src/sync/once_test.go b/src/sync/once_test.go
new file mode 100644
index 0000000..1eec8d1
--- /dev/null
+++ b/src/sync/once_test.go
@@ -0,0 +1,68 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package sync_test
+
+import (
+	. "sync"
+	"testing"
+)
+
+type one int
+
+func (o *one) Increment() {
+	*o++
+}
+
+func run(t *testing.T, once *Once, o *one, c chan bool) {
+	once.Do(func() { o.Increment() })
+	if v := *o; v != 1 {
+		t.Errorf("once failed inside run: %d is not 1", v)
+	}
+	c <- true
+}
+
+func TestOnce(t *testing.T) {
+	o := new(one)
+	once := new(Once)
+	c := make(chan bool)
+	const N = 10
+	for i := 0; i < N; i++ {
+		go run(t, once, o, c)
+	}
+	for i := 0; i < N; i++ {
+		<-c
+	}
+	if *o != 1 {
+		t.Errorf("once failed outside run: %d is not 1", *o)
+	}
+}
+
+func TestOncePanic(t *testing.T) {
+	var once Once
+	func() {
+		defer func() {
+			if r := recover(); r == nil {
+				t.Fatalf("Once.Do did not panic")
+			}
+		}()
+		once.Do(func() {
+			panic("failed")
+		})
+	}()
+
+	once.Do(func() {
+		t.Fatalf("Once.Do called twice")
+	})
+}
+
+func BenchmarkOnce(b *testing.B) {
+	var once Once
+	f := func() {}
+	b.RunParallel(func(pb *testing.PB) {
+		for pb.Next() {
+			once.Do(f)
+		}
+	})
+}
diff --git a/src/sync/pool.go b/src/sync/pool.go
new file mode 100644
index 0000000..0cf0637
--- /dev/null
+++ b/src/sync/pool.go
@@ -0,0 +1,225 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package sync
+
+import (
+	"runtime"
+	"sync/atomic"
+	"unsafe"
+)
+
+// A Pool is a set of temporary objects that may be individually saved and
+// retrieved.
+//
+// Any item stored in the Pool may be removed automatically at any time without
+// notification. If the Pool holds the only reference when this happens, the
+// item might be deallocated.
+//
+// A Pool is safe for use by multiple goroutines simultaneously.
+//
+// Pool's purpose is to cache allocated but unused items for later reuse,
+// relieving pressure on the garbage collector. That is, it makes it easy to
+// build efficient, thread-safe free lists. However, it is not suitable for all
+// free lists.
+//
+// An appropriate use of a Pool is to manage a group of temporary items
+// silently shared among and potentially reused by concurrent independent
+// clients of a package. Pool provides a way to amortize allocation overhead
+// across many clients.
+//
+// An example of good use of a Pool is in the fmt package, which maintains a
+// dynamically-sized store of temporary output buffers. The store scales under
+// load (when many goroutines are actively printing) and shrinks when
+// quiescent.
+//
+// On the other hand, a free list maintained as part of a short-lived object is
+// not a suitable use for a Pool, since the overhead does not amortize well in
+// that scenario. It is more efficient to have such objects implement their own
+// free list.
+//
+type Pool struct {
+	local     unsafe.Pointer // local fixed-size per-P pool, actual type is [P]poolLocal
+	localSize uintptr        // size of the local array
+
+	// New optionally specifies a function to generate
+	// a value when Get would otherwise return nil.
+	// It may not be changed concurrently with calls to Get.
+	New func() interface{}
+}
+
+// Local per-P Pool appendix.
+type poolLocal struct {
+	private interface{}   // Can be used only by the respective P.
+	shared  []interface{} // Can be used by any P.
+	Mutex                 // Protects shared.
+	pad     [128]byte     // Prevents false sharing.
+}
+
+// Put adds x to the pool.
+func (p *Pool) Put(x interface{}) {
+	if raceenabled {
+		// Under race detector the Pool degenerates into no-op.
+		// It's conforming, simple and does not introduce excessive
+		// happens-before edges between unrelated goroutines.
+		return
+	}
+	if x == nil {
+		return
+	}
+	l := p.pin()
+	if l.private == nil {
+		l.private = x
+		x = nil
+	}
+	runtime_procUnpin()
+	if x == nil {
+		return
+	}
+	l.Lock()
+	l.shared = append(l.shared, x)
+	l.Unlock()
+}
+
+// Get selects an arbitrary item from the Pool, removes it from the
+// Pool, and returns it to the caller.
+// Get may choose to ignore the pool and treat it as empty.
+// Callers should not assume any relation between values passed to Put and
+// the values returned by Get.
+//
+// If Get would otherwise return nil and p.New is non-nil, Get returns
+// the result of calling p.New.
+func (p *Pool) Get() interface{} {
+	if raceenabled {
+		if p.New != nil {
+			return p.New()
+		}
+		return nil
+	}
+	l := p.pin()
+	x := l.private
+	l.private = nil
+	runtime_procUnpin()
+	if x != nil {
+		return x
+	}
+	l.Lock()
+	last := len(l.shared) - 1
+	if last >= 0 {
+		x = l.shared[last]
+		l.shared = l.shared[:last]
+	}
+	l.Unlock()
+	if x != nil {
+		return x
+	}
+	return p.getSlow()
+}
+
+func (p *Pool) getSlow() (x interface{}) {
+	// See the comment in pin regarding ordering of the loads.
+	size := atomic.LoadUintptr(&p.localSize) // load-acquire
+	local := p.local                         // load-consume
+	// Try to steal one element from other procs.
+	pid := runtime_procPin()
+	runtime_procUnpin()
+	for i := 0; i < int(size); i++ {
+		l := indexLocal(local, (pid+i+1)%int(size))
+		l.Lock()
+		last := len(l.shared) - 1
+		if last >= 0 {
+			x = l.shared[last]
+			l.shared = l.shared[:last]
+			l.Unlock()
+			break
+		}
+		l.Unlock()
+	}
+
+	if x == nil && p.New != nil {
+		x = p.New()
+	}
+	return x
+}
+
+// pin pins the current goroutine to P, disables preemption and returns poolLocal pool for the P.
+// Caller must call runtime_procUnpin() when done with the pool.
+func (p *Pool) pin() *poolLocal {
+	pid := runtime_procPin()
+	// In pinSlow we store to localSize and then to local, here we load in opposite order.
+	// Since we've disabled preemption, GC can not happen in between.
+	// Thus here we must observe local at least as large localSize.
+	// We can observe a newer/larger local, it is fine (we must observe its zero-initialized-ness).
+	s := atomic.LoadUintptr(&p.localSize) // load-acquire
+	l := p.local                          // load-consume
+	if uintptr(pid) < s {
+		return indexLocal(l, pid)
+	}
+	return p.pinSlow()
+}
+
+func (p *Pool) pinSlow() *poolLocal {
+	// Retry under the mutex.
+	// Can not lock the mutex while pinned.
+	runtime_procUnpin()
+	allPoolsMu.Lock()
+	defer allPoolsMu.Unlock()
+	pid := runtime_procPin()
+	// poolCleanup won't be called while we are pinned.
+	s := p.localSize
+	l := p.local
+	if uintptr(pid) < s {
+		return indexLocal(l, pid)
+	}
+	if p.local == nil {
+		allPools = append(allPools, p)
+	}
+	// If GOMAXPROCS changes between GCs, we re-allocate the array and lose the old one.
+	size := runtime.GOMAXPROCS(0)
+	local := make([]poolLocal, size)
+	atomic.StorePointer((*unsafe.Pointer)(&p.local), unsafe.Pointer(&local[0])) // store-release
+	atomic.StoreUintptr(&p.localSize, uintptr(size))                            // store-release
+	return &local[pid]
+}
+
+func poolCleanup() {
+	// This function is called with the world stopped, at the beginning of a garbage collection.
+	// It must not allocate and probably should not call any runtime functions.
+	// Defensively zero out everything, 2 reasons:
+	// 1. To prevent false retention of whole Pools.
+	// 2. If GC happens while a goroutine works with l.shared in Put/Get,
+	//    it will retain whole Pool. So next cycle memory consumption would be doubled.
+	for i, p := range allPools {
+		allPools[i] = nil
+		for i := 0; i < int(p.localSize); i++ {
+			l := indexLocal(p.local, i)
+			l.private = nil
+			for j := range l.shared {
+				l.shared[j] = nil
+			}
+			l.shared = nil
+		}
+		p.local = nil
+		p.localSize = 0
+	}
+	allPools = []*Pool{}
+}
+
+var (
+	allPoolsMu Mutex
+	allPools   []*Pool
+)
+
+func init() {
+	runtime_registerPoolCleanup(poolCleanup)
+}
+
+func indexLocal(l unsafe.Pointer, i int) *poolLocal {
+	return &(*[1000000]poolLocal)(l)[i]
+}
+
+// Implemented in runtime.
+func runtime_registerPoolCleanup(cleanup func())
+func runtime_procPin() int
+func runtime_procUnpin()
diff --git a/src/sync/pool_test.go b/src/sync/pool_test.go
new file mode 100644
index 0000000..fa1a27b
--- /dev/null
+++ b/src/sync/pool_test.go
@@ -0,0 +1,163 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Pool is no-op under race detector, so all these tests do not work.
+// +build !race
+
+package sync_test
+
+import (
+	"runtime"
+	"runtime/debug"
+	. "sync"
+	"sync/atomic"
+	"testing"
+	"time"
+)
+
+func TestPool(t *testing.T) {
+	// disable GC so we can control when it happens.
+	defer debug.SetGCPercent(debug.SetGCPercent(-1))
+	var p Pool
+	if p.Get() != nil {
+		t.Fatal("expected empty")
+	}
+	p.Put("a")
+	p.Put("b")
+	if g := p.Get(); g != "a" {
+		t.Fatalf("got %#v; want a", g)
+	}
+	if g := p.Get(); g != "b" {
+		t.Fatalf("got %#v; want b", g)
+	}
+	if g := p.Get(); g != nil {
+		t.Fatalf("got %#v; want nil", g)
+	}
+
+	p.Put("c")
+	debug.SetGCPercent(100) // to allow following GC to actually run
+	runtime.GC()
+	if g := p.Get(); g != nil {
+		t.Fatalf("got %#v; want nil after GC", g)
+	}
+}
+
+func TestPoolNew(t *testing.T) {
+	// disable GC so we can control when it happens.
+	defer debug.SetGCPercent(debug.SetGCPercent(-1))
+
+	i := 0
+	p := Pool{
+		New: func() interface{} {
+			i++
+			return i
+		},
+	}
+	if v := p.Get(); v != 1 {
+		t.Fatalf("got %v; want 1", v)
+	}
+	if v := p.Get(); v != 2 {
+		t.Fatalf("got %v; want 2", v)
+	}
+	p.Put(42)
+	if v := p.Get(); v != 42 {
+		t.Fatalf("got %v; want 42", v)
+	}
+	if v := p.Get(); v != 3 {
+		t.Fatalf("got %v; want 3", v)
+	}
+}
+
+// Test that Pool does not hold pointers to previously cached resources.
+func TestPoolGC(t *testing.T) {
+	testPool(t, true)
+}
+
+// Test that Pool releases resources on GC.
+func TestPoolRelease(t *testing.T) {
+	testPool(t, false)
+}
+
+func testPool(t *testing.T, drain bool) {
+	var p Pool
+	const N = 100
+loop:
+	for try := 0; try < 3; try++ {
+		var fin, fin1 uint32
+		for i := 0; i < N; i++ {
+			v := new(string)
+			runtime.SetFinalizer(v, func(vv *string) {
+				atomic.AddUint32(&fin, 1)
+			})
+			p.Put(v)
+		}
+		if drain {
+			for i := 0; i < N; i++ {
+				p.Get()
+			}
+		}
+		for i := 0; i < 5; i++ {
+			runtime.GC()
+			time.Sleep(time.Duration(i*100+10) * time.Millisecond)
+			// 1 pointer can remain on stack or elsewhere
+			if fin1 = atomic.LoadUint32(&fin); fin1 >= N-1 {
+				continue loop
+			}
+		}
+		t.Fatalf("only %v out of %v resources are finalized on try %v", fin1, N, try)
+	}
+}
+
+func TestPoolStress(t *testing.T) {
+	const P = 10
+	N := int(1e6)
+	if testing.Short() {
+		N /= 100
+	}
+	var p Pool
+	done := make(chan bool)
+	for i := 0; i < P; i++ {
+		go func() {
+			var v interface{} = 0
+			for j := 0; j < N; j++ {
+				if v == nil {
+					v = 0
+				}
+				p.Put(v)
+				v = p.Get()
+				if v != nil && v.(int) != 0 {
+					t.Fatalf("expect 0, got %v", v)
+				}
+			}
+			done <- true
+		}()
+	}
+	for i := 0; i < P; i++ {
+		<-done
+	}
+}
+
+func BenchmarkPool(b *testing.B) {
+	var p Pool
+	b.RunParallel(func(pb *testing.PB) {
+		for pb.Next() {
+			p.Put(1)
+			p.Get()
+		}
+	})
+}
+
+func BenchmarkPoolOverflow(b *testing.B) {
+	var p Pool
+	b.RunParallel(func(pb *testing.PB) {
+		for pb.Next() {
+			for b := 0; b < 100; b++ {
+				p.Put(1)
+			}
+			for b := 0; b < 100; b++ {
+				p.Get()
+			}
+		}
+	})
+}
diff --git a/src/pkg/sync/race.go b/src/sync/race.go
similarity index 100%
rename from src/pkg/sync/race.go
rename to src/sync/race.go
diff --git a/src/pkg/sync/race0.go b/src/sync/race0.go
similarity index 100%
rename from src/pkg/sync/race0.go
rename to src/sync/race0.go
diff --git a/src/sync/runtime.go b/src/sync/runtime.go
new file mode 100644
index 0000000..3b86630
--- /dev/null
+++ b/src/sync/runtime.go
@@ -0,0 +1,40 @@
+// Copyright 2012 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package sync
+
+import "unsafe"
+
+// defined in package runtime
+
+// Semacquire waits until *s > 0 and then atomically decrements it.
+// It is intended as a simple sleep primitive for use by the synchronization
+// library and should not be used directly.
+func runtime_Semacquire(s *uint32)
+
+// Semrelease atomically increments *s and notifies a waiting goroutine
+// if one is blocked in Semacquire.
+// It is intended as a simple wakeup primitive for use by the synchronization
+// library and should not be used directly.
+func runtime_Semrelease(s *uint32)
+
+// Approximation of syncSema in runtime/sema.go.
+type syncSema struct {
+	lock uintptr
+	head unsafe.Pointer
+	tail unsafe.Pointer
+}
+
+// Syncsemacquire waits for a pairing Syncsemrelease on the same semaphore s.
+func runtime_Syncsemacquire(s *syncSema)
+
+// Syncsemrelease waits for n pairing Syncsemacquire on the same semaphore s.
+func runtime_Syncsemrelease(s *syncSema, n uint32)
+
+// Ensure that sync and runtime agree on size of syncSema.
+func runtime_Syncsemcheck(size uintptr)
+func init() {
+	var s syncSema
+	runtime_Syncsemcheck(unsafe.Sizeof(s))
+}
diff --git a/src/pkg/sync/runtime_sema_test.go b/src/sync/runtime_sema_test.go
similarity index 100%
rename from src/pkg/sync/runtime_sema_test.go
rename to src/sync/runtime_sema_test.go
diff --git a/src/sync/rwmutex.go b/src/sync/rwmutex.go
new file mode 100644
index 0000000..0e8a58e
--- /dev/null
+++ b/src/sync/rwmutex.go
@@ -0,0 +1,136 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package sync
+
+import (
+	"sync/atomic"
+	"unsafe"
+)
+
+// An RWMutex is a reader/writer mutual exclusion lock.
+// The lock can be held by an arbitrary number of readers
+// or a single writer.
+// RWMutexes can be created as part of other
+// structures; the zero value for a RWMutex is
+// an unlocked mutex.
+type RWMutex struct {
+	w           Mutex  // held if there are pending writers
+	writerSem   uint32 // semaphore for writers to wait for completing readers
+	readerSem   uint32 // semaphore for readers to wait for completing writers
+	readerCount int32  // number of pending readers
+	readerWait  int32  // number of departing readers
+}
+
+const rwmutexMaxReaders = 1 << 30
+
+// RLock locks rw for reading.
+func (rw *RWMutex) RLock() {
+	if raceenabled {
+		_ = rw.w.state
+		raceDisable()
+	}
+	if atomic.AddInt32(&rw.readerCount, 1) < 0 {
+		// A writer is pending, wait for it.
+		runtime_Semacquire(&rw.readerSem)
+	}
+	if raceenabled {
+		raceEnable()
+		raceAcquire(unsafe.Pointer(&rw.readerSem))
+	}
+}
+
+// RUnlock undoes a single RLock call;
+// it does not affect other simultaneous readers.
+// It is a run-time error if rw is not locked for reading
+// on entry to RUnlock.
+func (rw *RWMutex) RUnlock() {
+	if raceenabled {
+		_ = rw.w.state
+		raceReleaseMerge(unsafe.Pointer(&rw.writerSem))
+		raceDisable()
+	}
+	if r := atomic.AddInt32(&rw.readerCount, -1); r < 0 {
+		if r+1 == 0 || r+1 == -rwmutexMaxReaders {
+			raceEnable()
+			panic("sync: RUnlock of unlocked RWMutex")
+		}
+		// A writer is pending.
+		if atomic.AddInt32(&rw.readerWait, -1) == 0 {
+			// The last reader unblocks the writer.
+			runtime_Semrelease(&rw.writerSem)
+		}
+	}
+	if raceenabled {
+		raceEnable()
+	}
+}
+
+// Lock locks rw for writing.
+// If the lock is already locked for reading or writing,
+// Lock blocks until the lock is available.
+// To ensure that the lock eventually becomes available,
+// a blocked Lock call excludes new readers from acquiring
+// the lock.
+func (rw *RWMutex) Lock() {
+	if raceenabled {
+		_ = rw.w.state
+		raceDisable()
+	}
+	// First, resolve competition with other writers.
+	rw.w.Lock()
+	// Announce to readers there is a pending writer.
+	r := atomic.AddInt32(&rw.readerCount, -rwmutexMaxReaders) + rwmutexMaxReaders
+	// Wait for active readers.
+	if r != 0 && atomic.AddInt32(&rw.readerWait, r) != 0 {
+		runtime_Semacquire(&rw.writerSem)
+	}
+	if raceenabled {
+		raceEnable()
+		raceAcquire(unsafe.Pointer(&rw.readerSem))
+		raceAcquire(unsafe.Pointer(&rw.writerSem))
+	}
+}
+
+// Unlock unlocks rw for writing.  It is a run-time error if rw is
+// not locked for writing on entry to Unlock.
+//
+// As with Mutexes, a locked RWMutex is not associated with a particular
+// goroutine.  One goroutine may RLock (Lock) an RWMutex and then
+// arrange for another goroutine to RUnlock (Unlock) it.
+func (rw *RWMutex) Unlock() {
+	if raceenabled {
+		_ = rw.w.state
+		raceRelease(unsafe.Pointer(&rw.readerSem))
+		raceRelease(unsafe.Pointer(&rw.writerSem))
+		raceDisable()
+	}
+
+	// Announce to readers there is no active writer.
+	r := atomic.AddInt32(&rw.readerCount, rwmutexMaxReaders)
+	if r >= rwmutexMaxReaders {
+		raceEnable()
+		panic("sync: Unlock of unlocked RWMutex")
+	}
+	// Unblock blocked readers, if any.
+	for i := 0; i < int(r); i++ {
+		runtime_Semrelease(&rw.readerSem)
+	}
+	// Allow other writers to proceed.
+	rw.w.Unlock()
+	if raceenabled {
+		raceEnable()
+	}
+}
+
+// RLocker returns a Locker interface that implements
+// the Lock and Unlock methods by calling rw.RLock and rw.RUnlock.
+func (rw *RWMutex) RLocker() Locker {
+	return (*rlocker)(rw)
+}
+
+type rlocker RWMutex
+
+func (r *rlocker) Lock()   { (*RWMutex)(r).RLock() }
+func (r *rlocker) Unlock() { (*RWMutex)(r).RUnlock() }
diff --git a/src/sync/rwmutex_test.go b/src/sync/rwmutex_test.go
new file mode 100644
index 0000000..f625bc3
--- /dev/null
+++ b/src/sync/rwmutex_test.go
@@ -0,0 +1,254 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// GOMAXPROCS=10 go test
+
+package sync_test
+
+import (
+	"fmt"
+	"runtime"
+	. "sync"
+	"sync/atomic"
+	"testing"
+)
+
+func parallelReader(m *RWMutex, clocked, cunlock, cdone chan bool) {
+	m.RLock()
+	clocked <- true
+	<-cunlock
+	m.RUnlock()
+	cdone <- true
+}
+
+func doTestParallelReaders(numReaders, gomaxprocs int) {
+	runtime.GOMAXPROCS(gomaxprocs)
+	var m RWMutex
+	clocked := make(chan bool)
+	cunlock := make(chan bool)
+	cdone := make(chan bool)
+	for i := 0; i < numReaders; i++ {
+		go parallelReader(&m, clocked, cunlock, cdone)
+	}
+	// Wait for all parallel RLock()s to succeed.
+	for i := 0; i < numReaders; i++ {
+		<-clocked
+	}
+	for i := 0; i < numReaders; i++ {
+		cunlock <- true
+	}
+	// Wait for the goroutines to finish.
+	for i := 0; i < numReaders; i++ {
+		<-cdone
+	}
+}
+
+func TestParallelReaders(t *testing.T) {
+	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(-1))
+	doTestParallelReaders(1, 4)
+	doTestParallelReaders(3, 4)
+	doTestParallelReaders(4, 2)
+}
+
+func reader(rwm *RWMutex, num_iterations int, activity *int32, cdone chan bool) {
+	for i := 0; i < num_iterations; i++ {
+		rwm.RLock()
+		n := atomic.AddInt32(activity, 1)
+		if n < 1 || n >= 10000 {
+			panic(fmt.Sprintf("wlock(%d)\n", n))
+		}
+		for i := 0; i < 100; i++ {
+		}
+		atomic.AddInt32(activity, -1)
+		rwm.RUnlock()
+	}
+	cdone <- true
+}
+
+func writer(rwm *RWMutex, num_iterations int, activity *int32, cdone chan bool) {
+	for i := 0; i < num_iterations; i++ {
+		rwm.Lock()
+		n := atomic.AddInt32(activity, 10000)
+		if n != 10000 {
+			panic(fmt.Sprintf("wlock(%d)\n", n))
+		}
+		for i := 0; i < 100; i++ {
+		}
+		atomic.AddInt32(activity, -10000)
+		rwm.Unlock()
+	}
+	cdone <- true
+}
+
+func HammerRWMutex(gomaxprocs, numReaders, num_iterations int) {
+	runtime.GOMAXPROCS(gomaxprocs)
+	// Number of active readers + 10000 * number of active writers.
+	var activity int32
+	var rwm RWMutex
+	cdone := make(chan bool)
+	go writer(&rwm, num_iterations, &activity, cdone)
+	var i int
+	for i = 0; i < numReaders/2; i++ {
+		go reader(&rwm, num_iterations, &activity, cdone)
+	}
+	go writer(&rwm, num_iterations, &activity, cdone)
+	for ; i < numReaders; i++ {
+		go reader(&rwm, num_iterations, &activity, cdone)
+	}
+	// Wait for the 2 writers and all readers to finish.
+	for i := 0; i < 2+numReaders; i++ {
+		<-cdone
+	}
+}
+
+func TestRWMutex(t *testing.T) {
+	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(-1))
+	n := 1000
+	if testing.Short() {
+		n = 5
+	}
+	HammerRWMutex(1, 1, n)
+	HammerRWMutex(1, 3, n)
+	HammerRWMutex(1, 10, n)
+	HammerRWMutex(4, 1, n)
+	HammerRWMutex(4, 3, n)
+	HammerRWMutex(4, 10, n)
+	HammerRWMutex(10, 1, n)
+	HammerRWMutex(10, 3, n)
+	HammerRWMutex(10, 10, n)
+	HammerRWMutex(10, 5, n)
+}
+
+func TestRLocker(t *testing.T) {
+	var wl RWMutex
+	var rl Locker
+	wlocked := make(chan bool, 1)
+	rlocked := make(chan bool, 1)
+	rl = wl.RLocker()
+	n := 10
+	go func() {
+		for i := 0; i < n; i++ {
+			rl.Lock()
+			rl.Lock()
+			rlocked <- true
+			wl.Lock()
+			wlocked <- true
+		}
+	}()
+	for i := 0; i < n; i++ {
+		<-rlocked
+		rl.Unlock()
+		select {
+		case <-wlocked:
+			t.Fatal("RLocker() didn't read-lock it")
+		default:
+		}
+		rl.Unlock()
+		<-wlocked
+		select {
+		case <-rlocked:
+			t.Fatal("RLocker() didn't respect the write lock")
+		default:
+		}
+		wl.Unlock()
+	}
+}
+
+func TestUnlockPanic(t *testing.T) {
+	defer func() {
+		if recover() == nil {
+			t.Fatalf("unlock of unlocked RWMutex did not panic")
+		}
+	}()
+	var mu RWMutex
+	mu.Unlock()
+}
+
+func TestUnlockPanic2(t *testing.T) {
+	defer func() {
+		if recover() == nil {
+			t.Fatalf("unlock of unlocked RWMutex did not panic")
+		}
+	}()
+	var mu RWMutex
+	mu.RLock()
+	mu.Unlock()
+}
+
+func TestRUnlockPanic(t *testing.T) {
+	defer func() {
+		if recover() == nil {
+			t.Fatalf("read unlock of unlocked RWMutex did not panic")
+		}
+	}()
+	var mu RWMutex
+	mu.RUnlock()
+}
+
+func TestRUnlockPanic2(t *testing.T) {
+	defer func() {
+		if recover() == nil {
+			t.Fatalf("read unlock of unlocked RWMutex did not panic")
+		}
+	}()
+	var mu RWMutex
+	mu.Lock()
+	mu.RUnlock()
+}
+
+func BenchmarkRWMutexUncontended(b *testing.B) {
+	type PaddedRWMutex struct {
+		RWMutex
+		pad [32]uint32
+	}
+	b.RunParallel(func(pb *testing.PB) {
+		var rwm PaddedRWMutex
+		for pb.Next() {
+			rwm.RLock()
+			rwm.RLock()
+			rwm.RUnlock()
+			rwm.RUnlock()
+			rwm.Lock()
+			rwm.Unlock()
+		}
+	})
+}
+
+func benchmarkRWMutex(b *testing.B, localWork, writeRatio int) {
+	var rwm RWMutex
+	b.RunParallel(func(pb *testing.PB) {
+		foo := 0
+		for pb.Next() {
+			foo++
+			if foo%writeRatio == 0 {
+				rwm.Lock()
+				rwm.Unlock()
+			} else {
+				rwm.RLock()
+				for i := 0; i != localWork; i += 1 {
+					foo *= 2
+					foo /= 2
+				}
+				rwm.RUnlock()
+			}
+		}
+		_ = foo
+	})
+}
+
+func BenchmarkRWMutexWrite100(b *testing.B) {
+	benchmarkRWMutex(b, 0, 100)
+}
+
+func BenchmarkRWMutexWrite10(b *testing.B) {
+	benchmarkRWMutex(b, 0, 10)
+}
+
+func BenchmarkRWMutexWorkWrite100(b *testing.B) {
+	benchmarkRWMutex(b, 100, 100)
+}
+
+func BenchmarkRWMutexWorkWrite10(b *testing.B) {
+	benchmarkRWMutex(b, 100, 10)
+}
diff --git a/src/sync/waitgroup.go b/src/sync/waitgroup.go
new file mode 100644
index 0000000..92cc57d
--- /dev/null
+++ b/src/sync/waitgroup.go
@@ -0,0 +1,137 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package sync
+
+import (
+	"sync/atomic"
+	"unsafe"
+)
+
+// A WaitGroup waits for a collection of goroutines to finish.
+// The main goroutine calls Add to set the number of
+// goroutines to wait for.  Then each of the goroutines
+// runs and calls Done when finished.  At the same time,
+// Wait can be used to block until all goroutines have finished.
+type WaitGroup struct {
+	m       Mutex
+	counter int32
+	waiters int32
+	sema    *uint32
+}
+
+// WaitGroup creates a new semaphore each time the old semaphore
+// is released. This is to avoid the following race:
+//
+// G1: Add(1)
+// G1: go G2()
+// G1: Wait() // Context switch after Unlock() and before Semacquire().
+// G2: Done() // Release semaphore: sema == 1, waiters == 0. G1 doesn't run yet.
+// G3: Wait() // Finds counter == 0, waiters == 0, doesn't block.
+// G3: Add(1) // Makes counter == 1, waiters == 0.
+// G3: go G4()
+// G3: Wait() // G1 still hasn't run, G3 finds sema == 1, unblocked! Bug.
+
+// Add adds delta, which may be negative, to the WaitGroup counter.
+// If the counter becomes zero, all goroutines blocked on Wait are released.
+// If the counter goes negative, Add panics.
+//
+// Note that calls with a positive delta that occur when the counter is zero
+// must happen before a Wait. Calls with a negative delta, or calls with a
+// positive delta that start when the counter is greater than zero, may happen
+// at any time.
+// Typically this means the calls to Add should execute before the statement
+// creating the goroutine or other event to be waited for.
+// See the WaitGroup example.
+func (wg *WaitGroup) Add(delta int) {
+	if raceenabled {
+		_ = wg.m.state // trigger nil deref early
+		if delta < 0 {
+			// Synchronize decrements with Wait.
+			raceReleaseMerge(unsafe.Pointer(wg))
+		}
+		raceDisable()
+		defer raceEnable()
+	}
+	v := atomic.AddInt32(&wg.counter, int32(delta))
+	if raceenabled {
+		if delta > 0 && v == int32(delta) {
+			// The first increment must be synchronized with Wait.
+			// Need to model this as a read, because there can be
+			// several concurrent wg.counter transitions from 0.
+			raceRead(unsafe.Pointer(&wg.sema))
+		}
+	}
+	if v < 0 {
+		panic("sync: negative WaitGroup counter")
+	}
+	if v > 0 || atomic.LoadInt32(&wg.waiters) == 0 {
+		return
+	}
+	wg.m.Lock()
+	if atomic.LoadInt32(&wg.counter) == 0 {
+		for i := int32(0); i < wg.waiters; i++ {
+			runtime_Semrelease(wg.sema)
+		}
+		wg.waiters = 0
+		wg.sema = nil
+	}
+	wg.m.Unlock()
+}
+
+// Done decrements the WaitGroup counter.
+func (wg *WaitGroup) Done() {
+	wg.Add(-1)
+}
+
+// Wait blocks until the WaitGroup counter is zero.
+func (wg *WaitGroup) Wait() {
+	if raceenabled {
+		_ = wg.m.state // trigger nil deref early
+		raceDisable()
+	}
+	if atomic.LoadInt32(&wg.counter) == 0 {
+		if raceenabled {
+			raceEnable()
+			raceAcquire(unsafe.Pointer(wg))
+		}
+		return
+	}
+	wg.m.Lock()
+	w := atomic.AddInt32(&wg.waiters, 1)
+	// This code is racing with the unlocked path in Add above.
+	// The code above modifies counter and then reads waiters.
+	// We must modify waiters and then read counter (the opposite order)
+	// to avoid missing an Add.
+	if atomic.LoadInt32(&wg.counter) == 0 {
+		atomic.AddInt32(&wg.waiters, -1)
+		if raceenabled {
+			raceEnable()
+			raceAcquire(unsafe.Pointer(wg))
+			raceDisable()
+		}
+		wg.m.Unlock()
+		if raceenabled {
+			raceEnable()
+		}
+		return
+	}
+	if raceenabled && w == 1 {
+		// Wait must be synchronized with the first Add.
+		// Need to model this is as a write to race with the read in Add.
+		// As a consequence, can do the write only for the first waiter,
+		// otherwise concurrent Waits will race with each other.
+		raceWrite(unsafe.Pointer(&wg.sema))
+	}
+	if wg.sema == nil {
+		wg.sema = new(uint32)
+	}
+	s := wg.sema
+	wg.m.Unlock()
+	runtime_Semacquire(s)
+	if raceenabled {
+		raceEnable()
+		raceAcquire(unsafe.Pointer(wg))
+	}
+}
diff --git a/src/pkg/sync/waitgroup_test.go b/src/sync/waitgroup_test.go
similarity index 100%
rename from src/pkg/sync/waitgroup_test.go
rename to src/sync/waitgroup_test.go
diff --git a/src/syscall/asm.s b/src/syscall/asm.s
new file mode 100644
index 0000000..d4ca868
--- /dev/null
+++ b/src/syscall/asm.s
@@ -0,0 +1,8 @@
+// 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"
+
+TEXT ·use(SB),NOSPLIT,$0
+	RET
diff --git a/src/syscall/asm_darwin_386.s b/src/syscall/asm_darwin_386.s
new file mode 100644
index 0000000..7205deb
--- /dev/null
+++ b/src/syscall/asm_darwin_386.s
@@ -0,0 +1,143 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// TODO(rsc): Rewrite all nn(SP) references into name+(nn-8)(FP)
+// so that go vet can check that they are correct.
+
+#include "textflag.h"
+#include "funcdata.h"
+
+//
+// System call support for 386, Darwin
+//
+
+// func Syscall(trap int32, a1, a2, a3 int32) (r1, r2, err int32);
+// func Syscall6(trap int32, a1, a2, a3, a4, a5, a6 int32) (r1, r2, err int32);
+// Trap # in AX, args on stack above caller pc.
+
+TEXT	·Syscall(SB),NOSPLIT,$0-28
+	CALL	runtime·entersyscall(SB)
+	MOVL	4(SP), AX	// syscall entry
+	// slide args down on top of system call number
+	LEAL		8(SP), SI
+	LEAL		4(SP), DI
+	CLD
+	MOVSL
+	MOVSL
+	MOVSL
+	INT	$0x80
+	JAE	ok
+	MOVL	$-1, 20(SP)	// r1
+	MOVL	$-1, 24(SP)	// r2
+	MOVL	AX, 28(SP)		// errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+ok:
+	MOVL	AX, 20(SP)	// r1
+	MOVL	DX, 24(SP)	// r2
+	MOVL	$0, 28(SP)	// errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+
+TEXT	·Syscall6(SB),NOSPLIT,$0-40
+	CALL	runtime·entersyscall(SB)
+	MOVL	4(SP), AX	// syscall entry
+	// slide args down on top of system call number
+	LEAL		8(SP), SI
+	LEAL		4(SP), DI
+	CLD
+	MOVSL
+	MOVSL
+	MOVSL
+	MOVSL
+	MOVSL
+	MOVSL
+	INT	$0x80
+	JAE	ok6
+	MOVL	$-1, 32(SP)	// r1
+	MOVL	$-1, 36(SP)	// r2
+	MOVL	AX, 40(SP)		// errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+ok6:
+	MOVL	AX, 32(SP)	// r1
+	MOVL	DX, 36(SP)	// r2
+	MOVL	$0, 40(SP)	// errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+
+TEXT	·Syscall9(SB),NOSPLIT,$0-52
+	CALL	runtime·entersyscall(SB)
+	MOVL	4(SP), AX	// syscall entry
+	// slide args down on top of system call number
+	LEAL		8(SP), SI
+	LEAL		4(SP), DI
+	CLD
+	MOVSL
+	MOVSL
+	MOVSL
+	MOVSL
+	MOVSL
+	MOVSL
+	MOVSL
+	MOVSL
+	MOVSL
+	INT	$0x80
+	JAE	ok9
+	MOVL	$-1, 44(SP)	// r1
+	MOVL	$-1, 48(SP)	// r2
+	MOVL	AX, 52(SP)		// errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+ok9:
+	MOVL	AX, 44(SP)	// r1
+	MOVL	DX, 48(SP)	// r2
+	MOVL	$0, 52(SP)	// errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+
+TEXT ·RawSyscall(SB),NOSPLIT,$0-28
+	MOVL	4(SP), AX	// syscall entry
+	// slide args down on top of system call number
+	LEAL		8(SP), SI
+	LEAL		4(SP), DI
+	CLD
+	MOVSL
+	MOVSL
+	MOVSL
+	INT	$0x80
+	JAE	ok1
+	MOVL	$-1, 20(SP)	// r1
+	MOVL	$-1, 24(SP)	// r2
+	MOVL	AX, 28(SP)		// errno
+	RET
+ok1:
+	MOVL	AX, 20(SP)	// r1
+	MOVL	DX, 24(SP)	// r2
+	MOVL	$0, 28(SP)	// errno
+	RET
+
+TEXT	·RawSyscall6(SB),NOSPLIT,$0-40
+	MOVL	4(SP), AX	// syscall entry
+	// slide args down on top of system call number
+	LEAL		8(SP), SI
+	LEAL		4(SP), DI
+	CLD
+	MOVSL
+	MOVSL
+	MOVSL
+	MOVSL
+	MOVSL
+	MOVSL
+	INT	$0x80
+	JAE	ok2
+	MOVL	$-1, 32(SP)	// r1
+	MOVL	$-1, 36(SP)	// r2
+	MOVL	AX, 40(SP)		// errno
+	RET
+ok2:
+	MOVL	AX, 32(SP)	// r1
+	MOVL	DX, 36(SP)	// r2
+	MOVL	$0, 40(SP)	// errno
+	RET
diff --git a/src/syscall/asm_darwin_amd64.s b/src/syscall/asm_darwin_amd64.s
new file mode 100644
index 0000000..e57199d
--- /dev/null
+++ b/src/syscall/asm_darwin_amd64.s
@@ -0,0 +1,107 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// TODO(rsc): Rewrite all nn(SP) references into name+(nn-8)(FP)
+// so that go vet can check that they are correct.
+
+#include "textflag.h"
+#include "funcdata.h"
+
+//
+// System call support for AMD64, Darwin
+//
+
+// func Syscall(trap int64, a1, a2, a3 int64) (r1, r2, err int64);
+// func Syscall6(trap int64, a1, a2, a3, a4, a5, a6 int64) (r1, r2, err int64);
+// Trap # in AX, args in DI SI DX, return in AX DX
+
+TEXT	·Syscall(SB),NOSPLIT,$0-56
+	CALL	runtime·entersyscall(SB)
+	MOVQ	16(SP), DI
+	MOVQ	24(SP), SI
+	MOVQ	32(SP), DX
+	MOVQ	$0, R10
+	MOVQ	$0, R8
+	MOVQ	$0, R9
+	MOVQ	8(SP), AX	// syscall entry
+	ADDQ	$0x2000000, AX
+	SYSCALL
+	JCC	ok
+	MOVQ	$-1, 40(SP)	// r1
+	MOVQ	$0, 48(SP)	// r2
+	MOVQ	AX, 56(SP)  // errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+ok:
+	MOVQ	AX, 40(SP)	// r1
+	MOVQ	DX, 48(SP)	// r2
+	MOVQ	$0, 56(SP)	// errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+
+TEXT	·Syscall6(SB),NOSPLIT,$0-80
+	CALL	runtime·entersyscall(SB)
+	MOVQ	16(SP), DI
+	MOVQ	24(SP), SI
+	MOVQ	32(SP), DX
+	MOVQ	40(SP), R10
+	MOVQ	48(SP), R8
+	MOVQ	56(SP), R9
+	MOVQ	8(SP), AX	// syscall entry
+	ADDQ	$0x2000000, AX
+	SYSCALL
+	JCC	ok6
+	MOVQ	$-1, 64(SP)	// r1
+	MOVQ	$0, 72(SP)	// r2
+	MOVQ	AX, 80(SP)  // errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+ok6:
+	MOVQ	AX, 64(SP)	// r1
+	MOVQ	DX, 72(SP)	// r2
+	MOVQ	$0, 80(SP)	// errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+
+TEXT ·RawSyscall(SB),NOSPLIT,$0-56
+	MOVQ	16(SP), DI
+	MOVQ	24(SP), SI
+	MOVQ	32(SP), DX
+	MOVQ	$0, R10
+	MOVQ	$0, R8
+	MOVQ	$0, R9
+	MOVQ	8(SP), AX	// syscall entry
+	ADDQ	$0x2000000, AX
+	SYSCALL
+	JCC	ok1
+	MOVQ	$-1, 40(SP)	// r1
+	MOVQ	$0, 48(SP)	// r2
+	MOVQ	AX, 56(SP)  // errno
+	RET
+ok1:
+	MOVQ	AX, 40(SP)	// r1
+	MOVQ	DX, 48(SP)	// r2
+	MOVQ	$0, 56(SP)	// errno
+	RET
+
+TEXT	·RawSyscall6(SB),NOSPLIT,$0-80
+	MOVQ	16(SP), DI
+	MOVQ	24(SP), SI
+	MOVQ	32(SP), DX
+	MOVQ	40(SP), R10
+	MOVQ	48(SP), R8
+	MOVQ	56(SP), R9
+	MOVQ	8(SP), AX	// syscall entry
+	ADDQ	$0x2000000, AX
+	SYSCALL
+	JCC	ok2
+	MOVQ	$-1, 64(SP)	// r1
+	MOVQ	$0, 72(SP)	// r2
+	MOVQ	AX, 80(SP)  // errno
+	RET
+ok2:
+	MOVQ	AX, 64(SP)	// r1
+	MOVQ	DX, 72(SP)	// r2
+	MOVQ	$0, 80(SP)	// errno
+	RET
diff --git a/src/syscall/asm_dragonfly_386.s b/src/syscall/asm_dragonfly_386.s
new file mode 100644
index 0000000..7012d23
--- /dev/null
+++ b/src/syscall/asm_dragonfly_386.s
@@ -0,0 +1,140 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+#include "funcdata.h"
+
+//
+// System call support for 386, FreeBSD
+//
+
+// func Syscall(trap int32, a1, a2, a3 int32) (r1, r2, err int32);
+// func Syscall6(trap int32, a1, a2, a3, a4, a5, a6 int32) (r1, r2, err int32);
+// Trap # in AX, args on stack above caller pc.
+
+TEXT	·Syscall(SB),NOSPLIT,$0-32
+	CALL	runtime·entersyscall(SB)
+	MOVL	4(SP), AX	// syscall entry
+	// slide args down on top of system call number
+	LEAL		8(SP), SI
+	LEAL		4(SP), DI
+	CLD
+	MOVSL
+	MOVSL
+	MOVSL
+	INT	$0x80
+	JAE	ok
+	MOVL	$-1, 20(SP)	// r1
+	MOVL	$-1, 24(SP)	// r2
+	MOVL	AX, 28(SP)		// errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+ok:
+	MOVL	AX, 20(SP)	// r1
+	MOVL	DX, 24(SP)	// r2
+	MOVL	$0, 28(SP)	// errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+
+TEXT	·Syscall6(SB),NOSPLIT,$0-44
+	CALL	runtime·entersyscall(SB)
+	MOVL	4(SP), AX	// syscall entry
+	// slide args down on top of system call number
+	LEAL		8(SP), SI
+	LEAL		4(SP), DI
+	CLD
+	MOVSL
+	MOVSL
+	MOVSL
+	MOVSL
+	MOVSL
+	MOVSL
+	INT	$0x80
+	JAE	ok6
+	MOVL	$-1, 32(SP)	// r1
+	MOVL	$-1, 36(SP)	// r2
+	MOVL	AX, 40(SP)		// errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+ok6:
+	MOVL	AX, 32(SP)	// r1
+	MOVL	DX, 36(SP)	// r2
+	MOVL	$0, 40(SP)	// errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+
+TEXT	·Syscall9(SB),NOSPLIT,$0-56
+	CALL	runtime·entersyscall(SB)
+	MOVL	4(SP), AX	// syscall entry
+	// slide args down on top of system call number
+	LEAL		8(SP), SI
+	LEAL		4(SP), DI
+	CLD
+	MOVSL
+	MOVSL
+	MOVSL
+	MOVSL
+	MOVSL
+	MOVSL
+	MOVSL
+	MOVSL
+	MOVSL
+	INT	$0x80
+	JAE	ok9
+	MOVL	$-1, 44(SP)	// r1
+	MOVL	$-1, 48(SP)	// r2
+	MOVL	AX, 52(SP)		// errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+ok9:
+	MOVL	AX, 44(SP)	// r1
+	MOVL	DX, 48(SP)	// r2
+	MOVL	$0, 52(SP)	// errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+
+TEXT ·RawSyscall(SB),NOSPLIT,$0-32
+	MOVL	4(SP), AX	// syscall entry
+	// slide args down on top of system call number
+	LEAL		8(SP), SI
+	LEAL		4(SP), DI
+	CLD
+	MOVSL
+	MOVSL
+	MOVSL
+	INT	$0x80
+	JAE	ok1
+	MOVL	$-1, 20(SP)	// r1
+	MOVL	$-1, 24(SP)	// r2
+	MOVL	AX, 28(SP)		// errno
+	RET
+ok1:
+	MOVL	AX, 20(SP)	// r1
+	MOVL	DX, 24(SP)	// r2
+	MOVL	$0, 28(SP)	// errno
+	RET
+
+TEXT	·RawSyscall6(SB),NOSPLIT,$0-44
+	MOVL	4(SP), AX	// syscall entry
+	// slide args down on top of system call number
+	LEAL		8(SP), SI
+	LEAL		4(SP), DI
+	CLD
+	MOVSL
+	MOVSL
+	MOVSL
+	MOVSL
+	MOVSL
+	MOVSL
+	INT	$0x80
+	JAE	ok2
+	MOVL	$-1, 32(SP)	// r1
+	MOVL	$-1, 36(SP)	// r2
+	MOVL	AX, 40(SP)		// errno
+	RET
+ok2:
+	MOVL	AX, 32(SP)	// r1
+	MOVL	DX, 36(SP)	// r2
+	MOVL	$0, 40(SP)	// errno
+	RET
diff --git a/src/syscall/asm_dragonfly_amd64.s b/src/syscall/asm_dragonfly_amd64.s
new file mode 100644
index 0000000..004d360
--- /dev/null
+++ b/src/syscall/asm_dragonfly_amd64.s
@@ -0,0 +1,134 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+#include "funcdata.h"
+
+//
+// System call support for AMD64, DragonFly
+//
+
+// func Syscall(trap int64, a1, a2, a3 int64) (r1, r2, err int64);
+// func Syscall6(trap int64, a1, a2, a3, a4, a5, a6 int64) (r1, r2, err int64);
+// func Syscall9(trap int64, a1, a2, a3, a4, a5, a6, a7, a8, a9 int64) (r1, r2, err int64)
+// Trap # in AX, args in DI SI DX, return in AX DX
+
+TEXT	·Syscall(SB),NOSPLIT,$0-64
+	CALL	runtime·entersyscall(SB)
+	MOVQ	16(SP), DI
+	MOVQ	24(SP), SI
+	MOVQ	32(SP), DX
+	MOVQ	$0, R10
+	MOVQ	$0, R8
+	MOVQ	$0, R9
+	MOVQ	8(SP), AX	// syscall entry
+	SYSCALL
+	JCC	ok
+	MOVQ	$-1, 40(SP)	// r1
+	MOVQ	$0, 48(SP)	// r2
+	MOVQ	AX, 56(SP)  // errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+ok:
+	MOVQ	AX, 40(SP)	// r1
+	MOVQ	DX, 48(SP)	// r2
+	MOVQ	$0, 56(SP)	// errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+
+TEXT	·Syscall6(SB),NOSPLIT,$0-88
+	CALL	runtime·entersyscall(SB)
+	MOVQ	16(SP), DI
+	MOVQ	24(SP), SI
+	MOVQ	32(SP), DX
+	MOVQ	40(SP), R10
+	MOVQ	48(SP), R8
+	MOVQ	56(SP), R9
+	MOVQ	8(SP), AX	// syscall entry
+	SYSCALL
+	JCC	ok6
+	MOVQ	$-1, 64(SP)	// r1
+	MOVQ	$0, 72(SP)	// r2
+	MOVQ	AX, 80(SP)  // errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+ok6:
+	MOVQ	AX, 64(SP)	// r1
+	MOVQ	DX, 72(SP)	// r2
+	MOVQ	$0, 80(SP)	// errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+
+TEXT	·Syscall9(SB),NOSPLIT,$0-112
+	CALL	runtime·entersyscall(SB)
+	MOVQ	8(SP), AX
+	MOVQ	16(SP), DI
+	MOVQ	24(SP), SI
+	MOVQ	32(SP), DX
+	MOVQ	40(SP),	R10
+	MOVQ	48(SP), R8
+	MOVQ	56(SP), R9
+
+	// shift around the last three arguments so they're at the
+	// top of the stack when the syscall is called.
+	MOVQ	64(SP), R11 // arg 7
+	MOVQ	R11, 8(SP)
+	MOVQ	72(SP), R11 // arg 8
+	MOVQ	R11, 16(SP)
+	MOVQ	80(SP), R11 // arg 9
+	MOVQ	R11, 24(SP)
+
+	SYSCALL
+	JCC	ok9
+	MOVQ	$-1, 88(SP)	// r1
+	MOVQ	$0, 96(SP)	// r2
+	MOVQ	AX, 104(SP)  // errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+ok9:
+	MOVQ	AX, 88(SP)	// r1
+	MOVQ	DX, 96(SP)	// r2
+	MOVQ	$0, 104(SP)	// errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+
+TEXT ·RawSyscall(SB),NOSPLIT,$0-64
+	MOVQ	16(SP), DI
+	MOVQ	24(SP), SI
+	MOVQ	32(SP), DX
+	MOVQ	$0, R10
+	MOVQ	$0, R8
+	MOVQ	$0, R9
+	MOVQ	8(SP), AX	// syscall entry
+	SYSCALL
+	JCC	ok1
+	MOVQ	$-1, 40(SP)	// r1
+	MOVQ	$0, 48(SP)	// r2
+	MOVQ	AX, 56(SP)  // errno
+	RET
+ok1:
+	MOVQ	AX, 40(SP)	// r1
+	MOVQ	DX, 48(SP)	// r2
+	MOVQ	$0, 56(SP)	// errno
+	RET
+
+TEXT	·RawSyscall6(SB),NOSPLIT,$0-88
+	MOVQ	16(SP), DI
+	MOVQ	24(SP), SI
+	MOVQ	32(SP), DX
+	MOVQ	40(SP), R10
+	MOVQ	48(SP), R8
+	MOVQ	56(SP), R9
+	MOVQ	8(SP), AX	// syscall entry
+	SYSCALL
+	JCC	ok2
+	MOVQ	$-1, 64(SP)	// r1
+	MOVQ	$0, 72(SP)	// r2
+	MOVQ	AX, 80(SP)  // errno
+	RET
+ok2:
+	MOVQ	AX, 64(SP)	// r1
+	MOVQ	DX, 72(SP)	// r2
+	MOVQ	$0, 80(SP)	// errno
+	RET
diff --git a/src/syscall/asm_freebsd_386.s b/src/syscall/asm_freebsd_386.s
new file mode 100644
index 0000000..1400d5f
--- /dev/null
+++ b/src/syscall/asm_freebsd_386.s
@@ -0,0 +1,143 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// TODO(rsc): Rewrite all nn(SP) references into name+(nn-8)(FP)
+// so that go vet can check that they are correct.
+
+#include "textflag.h"
+#include "funcdata.h"
+
+//
+// System call support for 386, FreeBSD
+//
+
+// func Syscall(trap int32, a1, a2, a3 int32) (r1, r2, err int32);
+// func Syscall6(trap int32, a1, a2, a3, a4, a5, a6 int32) (r1, r2, err int32);
+// Trap # in AX, args on stack above caller pc.
+
+TEXT	·Syscall(SB),NOSPLIT,$0-28
+	CALL	runtime·entersyscall(SB)
+	MOVL	4(SP), AX	// syscall entry
+	// slide args down on top of system call number
+	LEAL		8(SP), SI
+	LEAL		4(SP), DI
+	CLD
+	MOVSL
+	MOVSL
+	MOVSL
+	INT	$0x80
+	JAE	ok
+	MOVL	$-1, 20(SP)	// r1
+	MOVL	$-1, 24(SP)	// r2
+	MOVL	AX, 28(SP)		// errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+ok:
+	MOVL	AX, 20(SP)	// r1
+	MOVL	DX, 24(SP)	// r2
+	MOVL	$0, 28(SP)	// errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+
+TEXT	·Syscall6(SB),NOSPLIT,$0-40
+	CALL	runtime·entersyscall(SB)
+	MOVL	4(SP), AX	// syscall entry
+	// slide args down on top of system call number
+	LEAL		8(SP), SI
+	LEAL		4(SP), DI
+	CLD
+	MOVSL
+	MOVSL
+	MOVSL
+	MOVSL
+	MOVSL
+	MOVSL
+	INT	$0x80
+	JAE	ok6
+	MOVL	$-1, 32(SP)	// r1
+	MOVL	$-1, 36(SP)	// r2
+	MOVL	AX, 40(SP)		// errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+ok6:
+	MOVL	AX, 32(SP)	// r1
+	MOVL	DX, 36(SP)	// r2
+	MOVL	$0, 40(SP)	// errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+
+TEXT	·Syscall9(SB),NOSPLIT,$0-52
+	CALL	runtime·entersyscall(SB)
+	MOVL	4(SP), AX	// syscall entry
+	// slide args down on top of system call number
+	LEAL		8(SP), SI
+	LEAL		4(SP), DI
+	CLD
+	MOVSL
+	MOVSL
+	MOVSL
+	MOVSL
+	MOVSL
+	MOVSL
+	MOVSL
+	MOVSL
+	MOVSL
+	INT	$0x80
+	JAE	ok9
+	MOVL	$-1, 44(SP)	// r1
+	MOVL	$-1, 48(SP)	// r2
+	MOVL	AX, 52(SP)		// errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+ok9:
+	MOVL	AX, 44(SP)	// r1
+	MOVL	DX, 48(SP)	// r2
+	MOVL	$0, 52(SP)	// errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+
+TEXT ·RawSyscall(SB),NOSPLIT,$0-28
+	MOVL	4(SP), AX	// syscall entry
+	// slide args down on top of system call number
+	LEAL		8(SP), SI
+	LEAL		4(SP), DI
+	CLD
+	MOVSL
+	MOVSL
+	MOVSL
+	INT	$0x80
+	JAE	ok1
+	MOVL	$-1, 20(SP)	// r1
+	MOVL	$-1, 24(SP)	// r2
+	MOVL	AX, 28(SP)		// errno
+	RET
+ok1:
+	MOVL	AX, 20(SP)	// r1
+	MOVL	DX, 24(SP)	// r2
+	MOVL	$0, 28(SP)	// errno
+	RET
+
+TEXT	·RawSyscall6(SB),NOSPLIT,$0-40
+	MOVL	4(SP), AX	// syscall entry
+	// slide args down on top of system call number
+	LEAL		8(SP), SI
+	LEAL		4(SP), DI
+	CLD
+	MOVSL
+	MOVSL
+	MOVSL
+	MOVSL
+	MOVSL
+	MOVSL
+	INT	$0x80
+	JAE	ok2
+	MOVL	$-1, 32(SP)	// r1
+	MOVL	$-1, 36(SP)	// r2
+	MOVL	AX, 40(SP)		// errno
+	RET
+ok2:
+	MOVL	AX, 32(SP)	// r1
+	MOVL	DX, 36(SP)	// r2
+	MOVL	$0, 40(SP)	// errno
+	RET
diff --git a/src/syscall/asm_freebsd_amd64.s b/src/syscall/asm_freebsd_amd64.s
new file mode 100644
index 0000000..c525190
--- /dev/null
+++ b/src/syscall/asm_freebsd_amd64.s
@@ -0,0 +1,142 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// TODO(rsc): Rewrite all nn(SP) references into name+(nn-8)(FP)
+// so that go vet can check that they are correct.
+
+#include "textflag.h"
+#include "funcdata.h"
+
+//
+// System call support for AMD64, FreeBSD
+//
+
+// The SYSCALL variant for invoking system calls is broken in FreeBSD.
+// See comment at top of ../runtime/sys_freebsd_amd64.c and
+// golang.org/issue/6372.
+#define SYSCALL MOVQ R10, CX; INT $0x80
+
+// func Syscall(trap int64, a1, a2, a3 int64) (r1, r2, err int64);
+// func Syscall6(trap int64, a1, a2, a3, a4, a5, a6 int64) (r1, r2, err int64);
+// func Syscall9(trap int64, a1, a2, a3, a4, a5, a6, a7, a8, a9 int64) (r1, r2, err int64)
+// Trap # in AX, args in DI SI DX, return in AX DX
+
+TEXT	·Syscall(SB),NOSPLIT,$0-56
+	CALL	runtime·entersyscall(SB)
+	MOVQ	16(SP), DI
+	MOVQ	24(SP), SI
+	MOVQ	32(SP), DX
+	MOVQ	$0, R10
+	MOVQ	$0, R8
+	MOVQ	$0, R9
+	MOVQ	8(SP), AX	// syscall entry
+	SYSCALL
+	JCC	ok
+	MOVQ	$-1, 40(SP)	// r1
+	MOVQ	$0, 48(SP)	// r2
+	MOVQ	AX, 56(SP)  // errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+ok:
+	MOVQ	AX, 40(SP)	// r1
+	MOVQ	DX, 48(SP)	// r2
+	MOVQ	$0, 56(SP)	// errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+
+TEXT	·Syscall6(SB),NOSPLIT,$0-80
+	CALL	runtime·entersyscall(SB)
+	MOVQ	16(SP), DI
+	MOVQ	24(SP), SI
+	MOVQ	32(SP), DX
+	MOVQ	40(SP), R10
+	MOVQ	48(SP), R8
+	MOVQ	56(SP), R9
+	MOVQ	8(SP), AX	// syscall entry
+	SYSCALL
+	JCC	ok6
+	MOVQ	$-1, 64(SP)	// r1
+	MOVQ	$0, 72(SP)	// r2
+	MOVQ	AX, 80(SP)  // errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+ok6:
+	MOVQ	AX, 64(SP)	// r1
+	MOVQ	DX, 72(SP)	// r2
+	MOVQ	$0, 80(SP)	// errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+
+TEXT	·Syscall9(SB),NOSPLIT,$0-104
+	CALL	runtime·entersyscall(SB)
+	MOVQ	8(SP), AX
+	MOVQ	16(SP), DI
+	MOVQ	24(SP), SI
+	MOVQ	32(SP), DX
+	MOVQ	40(SP),	R10
+	MOVQ	48(SP), R8
+	MOVQ	56(SP), R9
+
+	// shift around the last three arguments so they're at the
+	// top of the stack when the syscall is called.
+	MOVQ	64(SP), R11 // arg 7
+	MOVQ	R11, 8(SP)
+	MOVQ	72(SP), R11 // arg 8
+	MOVQ	R11, 16(SP)
+	MOVQ	80(SP), R11 // arg 9
+	MOVQ	R11, 24(SP)
+
+	SYSCALL
+	JCC	ok9
+	MOVQ	$-1, 88(SP)	// r1
+	MOVQ	$0, 96(SP)	// r2
+	MOVQ	AX, 104(SP)  // errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+ok9:
+	MOVQ	AX, 88(SP)	// r1
+	MOVQ	DX, 96(SP)	// r2
+	MOVQ	$0, 104(SP)	// errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+
+TEXT ·RawSyscall(SB),NOSPLIT,$0-56
+	MOVQ	16(SP), DI
+	MOVQ	24(SP), SI
+	MOVQ	32(SP), DX
+	MOVQ	$0, R10
+	MOVQ	$0, R8
+	MOVQ	$0, R9
+	MOVQ	8(SP), AX	// syscall entry
+	SYSCALL
+	JCC	ok1
+	MOVQ	$-1, 40(SP)	// r1
+	MOVQ	$0, 48(SP)	// r2
+	MOVQ	AX, 56(SP)  // errno
+	RET
+ok1:
+	MOVQ	AX, 40(SP)	// r1
+	MOVQ	DX, 48(SP)	// r2
+	MOVQ	$0, 56(SP)	// errno
+	RET
+
+TEXT	·RawSyscall6(SB),NOSPLIT,$0-80
+	MOVQ	16(SP), DI
+	MOVQ	24(SP), SI
+	MOVQ	32(SP), DX
+	MOVQ	40(SP), R10
+	MOVQ	48(SP), R8
+	MOVQ	56(SP), R9
+	MOVQ	8(SP), AX	// syscall entry
+	SYSCALL
+	JCC	ok2
+	MOVQ	$-1, 64(SP)	// r1
+	MOVQ	$0, 72(SP)	// r2
+	MOVQ	AX, 80(SP)  // errno
+	RET
+ok2:
+	MOVQ	AX, 64(SP)	// r1
+	MOVQ	DX, 72(SP)	// r2
+	MOVQ	$0, 80(SP)	// errno
+	RET
diff --git a/src/syscall/asm_freebsd_arm.s b/src/syscall/asm_freebsd_arm.s
new file mode 100644
index 0000000..6b0c182
--- /dev/null
+++ b/src/syscall/asm_freebsd_arm.s
@@ -0,0 +1,130 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+#include "funcdata.h"
+
+//
+// System call support for ARM, FreeBSD
+//
+
+// func Syscall(trap, a1, a2, a3 uintptr) (r1, r2, errno uintptr);
+// func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, errno uintptr);
+// func Syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2, errno uintptr)
+
+TEXT	·Syscall(SB),NOSPLIT,$0-28
+	BL runtime·entersyscall(SB)
+	MOVW 0(FP), R7 // syscall number
+	MOVW 4(FP), R0 // a1
+	MOVW 8(FP), R1 // a2
+	MOVW 12(FP), R2 // a3
+	SWI $0 // syscall
+	MOVW $0, R2
+	BCS error
+	MOVW R0, 16(FP) // r1
+	MOVW R1, 20(FP) // r2
+	MOVW R2, 24(FP) // errno
+	BL runtime·exitsyscall(SB)
+	RET
+error:
+	MOVW $-1, R3
+	MOVW R3, 16(FP) // r1
+	MOVW R2, 20(FP) // r2
+	MOVW R0, 24(FP) // errno
+	BL runtime·exitsyscall(SB)
+	RET
+
+TEXT	·Syscall6(SB),NOSPLIT,$0-40
+	BL runtime·entersyscall(SB)
+	MOVW 0(FP), R7 // syscall number
+	MOVW 4(FP), R0 // a1
+	MOVW 8(FP), R1 // a2
+	MOVW 12(FP), R2 // a3
+	MOVW 16(FP), R3 // a4
+	MOVW R13, R4
+	MOVW $20(FP), R13 // a5 to a6 are passed on stack
+	SWI $0 // syscall
+	MOVW R4, R13
+	MOVW $0, R2
+	BCS error6
+	MOVW R0, 28(FP) // r1
+	MOVW R1, 32(FP) // r2
+	MOVW R2, 36(FP) // errno
+	BL runtime·exitsyscall(SB)
+	RET
+error6:
+	MOVW $-1, R3
+	MOVW R3, 28(FP) // r1
+	MOVW R2, 32(FP) // r2
+	MOVW R0, 36(FP) // errno
+	BL runtime·exitsyscall(SB)
+	RET
+
+TEXT	·Syscall9(SB),NOSPLIT,$0-52
+	BL runtime·entersyscall(SB)
+	MOVW 0(FP), R7 // syscall number
+	MOVW 4(FP), R0 // a1
+	MOVW 8(FP), R1 // a2
+	MOVW 12(FP), R2 // a3
+	MOVW 16(FP), R3 // a4
+	MOVW R13, R4
+	MOVW $20(FP), R13 // a5 to a9 are passed on stack
+	SWI $0 // syscall
+	MOVW R4, R13
+	MOVW $0, R2
+	BCS error9
+	MOVW R0, 40(FP) // r1
+	MOVW R1, 44(FP) // r2
+	MOVW R2, 48(FP) // errno
+	BL runtime·exitsyscall(SB)
+	RET
+error9:
+	MOVW $-1, R3
+	MOVW R3, 40(FP) // r1
+	MOVW R2, 44(FP) // r2
+	MOVW R0, 48(FP) // errno
+	BL runtime·exitsyscall(SB)
+	RET
+
+TEXT	·RawSyscall(SB),NOSPLIT,$0-28
+	MOVW 0(FP), R7 // syscall number
+	MOVW 4(FP), R0 // a1
+	MOVW 8(FP), R1 // a2
+	MOVW 12(FP), R2 // a3
+	SWI $0 // syscall
+	MOVW $0, R2
+	BCS errorr
+	MOVW R0, 16(FP) // r1
+	MOVW R1, 20(FP) // r2
+	MOVW R2, 24(FP) // errno
+	RET
+errorr:
+	MOVW $-1, R3
+	MOVW R3, 16(FP) // r1
+	MOVW R2, 20(FP) // r2
+	MOVW R0, 24(FP) // errno
+	RET
+
+TEXT	·RawSyscall6(SB),NOSPLIT,$0-40
+	MOVW 0(FP), R7 // syscall number
+	MOVW 4(FP), R0 // a1
+	MOVW 8(FP), R1 // a2
+	MOVW 12(FP), R2 // a3
+	MOVW 16(FP), R3 // a4
+	MOVW R13, R4
+	MOVW $20(FP), R13 // a5 to a6 are passed on stack
+	SWI $0 // syscall
+	MOVW R4, R13
+	MOVW $0, R2
+	BCS errorr6
+	MOVW R0, 28(FP) // r1
+	MOVW R1, 32(FP) // r2
+	MOVW R2, 36(FP) // errno
+	RET
+errorr6:
+	MOVW $-1, R3
+	MOVW R3, 28(FP) // r1
+	MOVW R2, 32(FP) // r2
+	MOVW R0, 36(FP) // errno
+	RET
diff --git a/src/syscall/asm_linux_386.s b/src/syscall/asm_linux_386.s
new file mode 100644
index 0000000..fa1b371
--- /dev/null
+++ b/src/syscall/asm_linux_386.s
@@ -0,0 +1,187 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// TODO(rsc): Rewrite all nn(SP) references into name+(nn-8)(FP)
+// so that go vet can check that they are correct.
+
+#include "textflag.h"
+#include "funcdata.h"
+
+//
+// System calls for 386, Linux
+//
+
+// func Syscall(trap uintptr, a1, a2, a3 uintptr) (r1, r2, err uintptr);
+// Trap # in AX, args in BX CX DX SI DI, return in AX
+
+TEXT	·Syscall(SB),NOSPLIT,$0-28
+	CALL	runtime·entersyscall(SB)
+	MOVL	4(SP), AX	// syscall entry
+	MOVL	8(SP), BX
+	MOVL	12(SP), CX
+	MOVL	16(SP), DX
+	MOVL	$0, SI
+	MOVL	$0,  DI
+	CALL	*runtime·_vdso(SB)
+	CMPL	AX, $0xfffff001
+	JLS	ok
+	MOVL	$-1, 20(SP)	// r1
+	MOVL	$0, 24(SP)	// r2
+	NEGL	AX
+	MOVL	AX, 28(SP)  // errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+ok:
+	MOVL	AX, 20(SP)	// r1
+	MOVL	DX, 24(SP)	// r2
+	MOVL	$0, 28(SP)	// errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+
+// func Syscall6(trap uintptr, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr);
+TEXT	·Syscall6(SB),NOSPLIT,$0-40
+	CALL	runtime·entersyscall(SB)
+	MOVL	4(SP), AX	// syscall entry
+	MOVL	8(SP), BX
+	MOVL	12(SP), CX
+	MOVL	16(SP), DX
+	MOVL	20(SP), SI
+	MOVL	24(SP), DI
+	MOVL	28(SP), BP
+	CALL	*runtime·_vdso(SB)
+	CMPL	AX, $0xfffff001
+	JLS	ok6
+	MOVL	$-1, 32(SP)	// r1
+	MOVL	$0, 36(SP)	// r2
+	NEGL	AX
+	MOVL	AX, 40(SP)  // errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+ok6:
+	MOVL	AX, 32(SP)	// r1
+	MOVL	DX, 36(SP)	// r2
+	MOVL	$0, 40(SP)	// errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+
+// func RawSyscall(trap uintptr, a1, a2, a3 uintptr) (r1, r2, err uintptr);
+TEXT ·RawSyscall(SB),NOSPLIT,$0-28
+	MOVL	4(SP), AX	// syscall entry
+	MOVL	8(SP), BX
+	MOVL	12(SP), CX
+	MOVL	16(SP), DX
+	MOVL	$0, SI
+	MOVL	$0,  DI
+	CALL	*runtime·_vdso(SB)
+	CMPL	AX, $0xfffff001
+	JLS	ok1
+	MOVL	$-1, 20(SP)	// r1
+	MOVL	$0, 24(SP)	// r2
+	NEGL	AX
+	MOVL	AX, 28(SP)  // errno
+	RET
+ok1:
+	MOVL	AX, 20(SP)	// r1
+	MOVL	DX, 24(SP)	// r2
+	MOVL	$0, 28(SP)	// errno
+	RET
+
+// func RawSyscall6(trap uintptr, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr);
+TEXT	·RawSyscall6(SB),NOSPLIT,$0-40
+	MOVL	4(SP), AX	// syscall entry
+	MOVL	8(SP), BX
+	MOVL	12(SP), CX
+	MOVL	16(SP), DX
+	MOVL	20(SP), SI
+	MOVL	24(SP), DI
+	MOVL	28(SP), BP
+	CALL	*runtime·_vdso(SB)
+	CMPL	AX, $0xfffff001
+	JLS	ok2
+	MOVL	$-1, 32(SP)	// r1
+	MOVL	$0, 36(SP)	// r2
+	NEGL	AX
+	MOVL	AX, 40(SP)  // errno
+	RET
+ok2:
+	MOVL	AX, 32(SP)	// r1
+	MOVL	DX, 36(SP)	// r2
+	MOVL	$0, 40(SP)	// errno
+	RET
+
+#define SYS_SOCKETCALL 102	/* from zsysnum_linux_386.go */
+
+// func socketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (n int, errno int)
+// Kernel interface gets call sub-number and pointer to a0.
+TEXT ·socketcall(SB),NOSPLIT,$0-36
+	CALL	runtime·entersyscall(SB)
+	MOVL	$SYS_SOCKETCALL, AX	// syscall entry
+	MOVL	4(SP), BX	// socket call number
+	LEAL		8(SP), CX	// pointer to call arguments
+	MOVL	$0, DX
+	MOVL	$0, SI
+	MOVL	$0,  DI
+	CALL	*runtime·_vdso(SB)
+	CMPL	AX, $0xfffff001
+	JLS	oksock
+	MOVL	$-1, 32(SP)	// n
+	NEGL	AX
+	MOVL	AX, 36(SP)  // errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+oksock:
+	MOVL	AX, 32(SP)	// n
+	MOVL	$0, 36(SP)	// errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+
+// func rawsocketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (n int, errno int)
+// Kernel interface gets call sub-number and pointer to a0.
+TEXT ·rawsocketcall(SB),NOSPLIT,$0-36
+	MOVL	$SYS_SOCKETCALL, AX	// syscall entry
+	MOVL	4(SP), BX	// socket call number
+	LEAL		8(SP), CX	// pointer to call arguments
+	MOVL	$0, DX
+	MOVL	$0, SI
+	MOVL	$0,  DI
+	CALL	*runtime·_vdso(SB)
+	CMPL	AX, $0xfffff001
+	JLS	oksock1
+	MOVL	$-1, 32(SP)	// n
+	NEGL	AX
+	MOVL	AX, 36(SP)  // errno
+	RET
+oksock1:
+	MOVL	AX, 32(SP)	// n
+	MOVL	$0, 36(SP)	// errno
+	RET
+
+#define SYS__LLSEEK 140	/* from zsysnum_linux_386.go */
+// func Seek(fd int, offset int64, whence int) (newoffset int64, errno int)
+// Implemented in assembly to avoid allocation when
+// taking the address of the return value newoffset.
+// Underlying system call is
+//	llseek(int fd, int offhi, int offlo, int64 *result, int whence)
+TEXT ·seek(SB),NOSPLIT,$0-28
+	CALL	runtime·entersyscall(SB)
+	MOVL	$SYS__LLSEEK, AX	// syscall entry
+	MOVL	4(SP), BX	// fd
+	MOVL	12(SP), CX	// offset-high
+	MOVL	8(SP), DX	// offset-low
+	LEAL	20(SP), SI	// result pointer
+	MOVL	16(SP),  DI	// whence
+	CALL	*runtime·_vdso(SB)
+	CMPL	AX, $0xfffff001
+	JLS	okseek
+	MOVL	$-1, 20(SP)	// newoffset low
+	MOVL	$-1, 24(SP)	// newoffset high
+	NEGL	AX
+	MOVL	AX, 28(SP)  // errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+okseek:
+	// system call filled in newoffset already
+	MOVL	$0, 28(SP)	// errno
+	CALL	runtime·exitsyscall(SB)
+	RET
diff --git a/src/syscall/asm_linux_amd64.s b/src/syscall/asm_linux_amd64.s
new file mode 100644
index 0000000..b3ce216
--- /dev/null
+++ b/src/syscall/asm_linux_amd64.s
@@ -0,0 +1,127 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// TODO(rsc): Rewrite all nn(SP) references into name+(nn-8)(FP)
+// so that go vet can check that they are correct.
+
+#include "textflag.h"
+#include "funcdata.h"
+
+//
+// System calls for AMD64, Linux
+//
+
+// func Syscall(trap int64, a1, a2, a3 int64) (r1, r2, err int64);
+// Trap # in AX, args in DI SI DX R10 R8 R9, return in AX DX
+// Note that this differs from "standard" ABI convention, which
+// would pass 4th arg in CX, not R10.
+
+TEXT	·Syscall(SB),NOSPLIT,$0-56
+	CALL	runtime·entersyscall(SB)
+	MOVQ	16(SP), DI
+	MOVQ	24(SP), SI
+	MOVQ	32(SP), DX
+	MOVQ	$0, R10
+	MOVQ	$0, R8
+	MOVQ	$0, R9
+	MOVQ	8(SP), AX	// syscall entry
+	SYSCALL
+	CMPQ	AX, $0xfffffffffffff001
+	JLS	ok
+	MOVQ	$-1, 40(SP)	// r1
+	MOVQ	$0, 48(SP)	// r2
+	NEGQ	AX
+	MOVQ	AX, 56(SP)  // errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+ok:
+	MOVQ	AX, 40(SP)	// r1
+	MOVQ	DX, 48(SP)	// r2
+	MOVQ	$0, 56(SP)	// errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+
+TEXT ·Syscall6(SB),NOSPLIT,$0-80
+	CALL	runtime·entersyscall(SB)
+	MOVQ	16(SP), DI
+	MOVQ	24(SP), SI
+	MOVQ	32(SP), DX
+	MOVQ	40(SP), R10
+	MOVQ	48(SP), R8
+	MOVQ	56(SP), R9
+	MOVQ	8(SP), AX	// syscall entry
+	SYSCALL
+	CMPQ	AX, $0xfffffffffffff001
+	JLS	ok6
+	MOVQ	$-1, 64(SP)	// r1
+	MOVQ	$0, 72(SP)	// r2
+	NEGQ	AX
+	MOVQ	AX, 80(SP)  // errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+ok6:
+	MOVQ	AX, 64(SP)	// r1
+	MOVQ	DX, 72(SP)	// r2
+	MOVQ	$0, 80(SP)	// errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+
+TEXT ·RawSyscall(SB),NOSPLIT,$0-56
+	MOVQ	16(SP), DI
+	MOVQ	24(SP), SI
+	MOVQ	32(SP), DX
+	MOVQ	$0, R10
+	MOVQ	$0, R8
+	MOVQ	$0, R9
+	MOVQ	8(SP), AX	// syscall entry
+	SYSCALL
+	CMPQ	AX, $0xfffffffffffff001
+	JLS	ok1
+	MOVQ	$-1, 40(SP)	// r1
+	MOVQ	$0, 48(SP)	// r2
+	NEGQ	AX
+	MOVQ	AX, 56(SP)  // errno
+	RET
+ok1:
+	MOVQ	AX, 40(SP)	// r1
+	MOVQ	DX, 48(SP)	// r2
+	MOVQ	$0, 56(SP)	// errno
+	RET
+
+TEXT ·RawSyscall6(SB),NOSPLIT,$0-80
+	MOVQ	16(SP), DI
+	MOVQ	24(SP), SI
+	MOVQ	32(SP), DX
+	MOVQ	40(SP), R10
+	MOVQ	48(SP), R8
+	MOVQ	56(SP), R9
+	MOVQ	8(SP), AX	// syscall entry
+	SYSCALL
+	CMPQ	AX, $0xfffffffffffff001
+	JLS	ok2
+	MOVQ	$-1, 64(SP)	// r1
+	MOVQ	$0, 72(SP)	// r2
+	NEGQ	AX
+	MOVQ	AX, 80(SP)  // errno
+	RET
+ok2:
+	MOVQ	AX, 64(SP)	// r1
+	MOVQ	DX, 72(SP)	// r2
+	MOVQ	$0, 80(SP)	// errno
+	RET
+
+TEXT ·gettimeofday(SB),NOSPLIT,$0-16
+	MOVQ	8(SP), DI
+	MOVQ	$0, SI
+	MOVQ	runtime·__vdso_gettimeofday_sym(SB), AX
+	CALL	AX
+
+	CMPQ	AX, $0xfffffffffffff001
+	JLS	ok7
+	NEGQ	AX
+	MOVQ	AX, 16(SP)  // errno
+	RET
+ok7:
+	MOVQ	$0, 16(SP)  // errno
+	RET
diff --git a/src/syscall/asm_linux_arm.s b/src/syscall/asm_linux_arm.s
new file mode 100644
index 0000000..3526533
--- /dev/null
+++ b/src/syscall/asm_linux_arm.s
@@ -0,0 +1,159 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+#include "funcdata.h"
+
+//
+// System calls for arm, Linux
+//
+
+// TODO(kaib): handle error returns
+
+// func Syscall(syscall uintptr, a1, a2, a3 uintptr) (r1, r2, err uintptr);
+
+TEXT	·Syscall(SB),NOSPLIT,$0-28
+	BL		runtime·entersyscall(SB)
+	MOVW	4(SP), R7
+	MOVW	8(SP), R0
+	MOVW	12(SP), R1
+	MOVW	16(SP), R2
+	MOVW	$0, R3
+	MOVW	$0, R4
+	MOVW	$0, R5
+	SWI		$0
+	MOVW	$0xfffff001, R1
+	CMP		R1, R0
+	BLS		ok
+	MOVW	$-1, R1
+	MOVW	R1, 20(SP)	// r1
+	MOVW	$0, R2
+	MOVW	R2, 24(SP)	// r2
+	RSB		$0, R0, R0
+	MOVW	R0, 28(SP)	// errno
+	BL		runtime·exitsyscall(SB)
+	RET
+ok:
+	MOVW	R0, 20(SP) // r1
+	MOVW	$0, R0
+	MOVW	R0, 24(SP)	// r2
+	MOVW	R0, 28(SP)	// errno
+	BL		runtime·exitsyscall(SB)
+	RET
+
+// func Syscall6(trap uintptr, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr);
+// Actually Syscall5 but the rest of the code expects it to be named Syscall6.
+TEXT	·Syscall6(SB),NOSPLIT,$0-40
+	BL		runtime·entersyscall(SB)
+	MOVW	4(SP), R7	// syscall entry
+	MOVW	8(SP), R0
+	MOVW	12(SP), R1
+	MOVW	16(SP), R2
+	MOVW	20(SP), R3
+	MOVW	24(SP), R4
+	MOVW	28(SP), R5
+	SWI		$0
+	MOVW	$0xfffff001, R6
+	CMP		R6, R0
+	BLS		ok6
+	MOVW	$-1, R1
+	MOVW	R1, 32(SP)	// r1
+	MOVW	$0, R2
+	MOVW	R2, 36(SP)	// r2
+	RSB		$0, R0, R0
+	MOVW	R0, 40(SP)	// errno
+	BL		runtime·exitsyscall(SB)
+	RET
+ok6:
+	MOVW	R0, 32(SP) // r1
+	MOVW	R1, 36(SP)	// r2
+	MOVW	$0, R0
+	MOVW	R0, 40(SP)	// errno
+	BL		runtime·exitsyscall(SB)
+	RET
+
+// func RawSyscall6(trap uintptr, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr);
+// Actually RawSyscall5 but the rest of the code expects it to be named RawSyscall6.
+TEXT	·RawSyscall6(SB),NOSPLIT,$0-40
+	MOVW	4(SP), R7	// syscall entry
+	MOVW	8(SP), R0
+	MOVW	12(SP), R1
+	MOVW	16(SP), R2
+	MOVW	20(SP), R3
+	MOVW	24(SP), R4
+	MOVW	28(SP), R5
+	SWI		$0
+	MOVW	$0xfffff001, R6
+	CMP		R6, R0
+	BLS		ok2
+	MOVW	$-1, R1
+	MOVW	R1, 32(SP)	// r1
+	MOVW	$0, R2
+	MOVW	R2, 36(SP)	// r2
+	RSB		$0, R0, R0
+	MOVW	R0, 40(SP)	// errno
+	RET
+ok2:
+	MOVW	R0, 32(SP) // r1
+	MOVW	R1, 36(SP)	// r2
+	MOVW	$0, R0
+	MOVW	R0, 40(SP)	// errno
+	RET
+
+#define SYS__LLSEEK 140  /* from zsysnum_linux_arm.go */
+// func seek(fd int, offset int64, whence int) (newoffset int64, errno int)
+// Implemented in assembly to avoid allocation when
+// taking the address of the return value newoffset.
+// Underlying system call is
+//	llseek(int fd, int offhi, int offlo, int64 *result, int whence)
+TEXT ·seek(SB),NOSPLIT,$0-32
+	BL	runtime·entersyscall(SB)
+	MOVW	$SYS__LLSEEK, R7	// syscall entry
+	MOVW	4(SP), R0	// fd
+	MOVW	12(SP), R1	// offset-high
+	MOVW	8(SP), R2	// offset-low
+	MOVW	$20(SP), R3
+	MOVW	16(SP), R4	// whence
+	SWI	$0
+	MOVW	$0xfffff001, R6
+	CMP	R6, R0
+	BLS	okseek
+	MOVW	$0, R1
+	MOVW	R1, 20(SP)
+	MOVW	R1, 24(SP)
+	RSB	$0, R0, R0
+	MOVW	R0, 28(SP)	// errno
+	BL	runtime·exitsyscall(SB)
+	RET
+okseek:
+	// system call filled in newoffset already
+	MOVW	$0, R0
+	MOVW	R0, 28(SP)	// errno
+	BL	runtime·exitsyscall(SB)
+	RET	
+
+// func RawSyscall(trap uintptr, a1, a2, a3 uintptr) (r1, r2, err uintptr);
+TEXT ·RawSyscall(SB),NOSPLIT,$0-28
+	MOVW	4(SP), R7	// syscall entry
+	MOVW	8(SP), R0
+	MOVW	12(SP), R1
+	MOVW	16(SP), R2
+	SWI		$0
+	MOVW	$0xfffff001, R1
+	CMP		R1, R0
+	BLS		ok1
+	MOVW	$-1, R1
+	MOVW	R1, 20(SP)	// r1
+	MOVW	$0, R2
+	MOVW	R2, 24(SP)	// r2
+	RSB		$0, R0, R0
+	MOVW	R0, 28(SP)	// errno
+	RET
+ok1:
+	MOVW	R0, 20(SP) // r1
+	MOVW	$0, R0
+	MOVW	R0, 24(SP)	// r2
+	MOVW	R0, 28(SP)	// errno
+	RET
+
diff --git a/src/syscall/asm_nacl_386.s b/src/syscall/asm_nacl_386.s
new file mode 100644
index 0000000..cb6fb44
--- /dev/null
+++ b/src/syscall/asm_nacl_386.s
@@ -0,0 +1,44 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+#include "funcdata.h"
+#include "../runtime/syscall_nacl.h"
+
+//
+// System call support for 386, Native Client
+//
+
+#define NACL_SYSCALL(code) \
+	MOVL $(0x10000 + ((code)<<5)), AX; CALL AX
+
+#define NACL_SYSJMP(code) \
+	MOVL $(0x10000 + ((code)<<5)), AX; JMP AX
+
+TEXT syscall·Syscall(SB),NOSPLIT,$12-28
+	CALL	runtime·entersyscall(SB)
+	MOVL	trap+0(FP), AX
+	MOVL	a1+4(FP), BX
+	MOVL	BX, 0(SP)
+	MOVL	a2+8(FP), BX
+	MOVL	BX, 4(SP)
+	MOVL	a3+12(FP), BX
+	MOVL	BX, 8(SP)
+	SHLL	$5, AX
+	ADDL	$0x10000, AX
+	CALL	AX
+	CMPL	AX, $0
+	JGE	ok
+	MOVL	$-1, r1+16(FP)
+	MOVL	$-1, r2+20(FP)
+	NEGL	AX
+	MOVL	AX, err+24(FP)
+	CALL	runtime·exitsyscall(SB)
+	RET
+ok:
+	MOVL	AX, r1+16(FP)
+	MOVL	DX, r2+20(FP)
+	MOVL	$0, err+24(FP)
+	CALL	runtime·exitsyscall(SB)
+	RET	
diff --git a/src/syscall/asm_nacl_amd64p32.s b/src/syscall/asm_nacl_amd64p32.s
new file mode 100644
index 0000000..72391c4
--- /dev/null
+++ b/src/syscall/asm_nacl_amd64p32.s
@@ -0,0 +1,42 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+#include "funcdata.h"
+#include "../runtime/syscall_nacl.h"
+
+//
+// System call support for amd64, Native Client
+//
+
+#define NACL_SYSCALL(code) \
+	MOVL $(0x10000 + ((code)<<5)), AX; CALL AX
+
+#define NACL_SYSJMP(code) \
+	MOVL $(0x10000 + ((code)<<5)), AX; JMP AX
+
+TEXT syscall·Syscall(SB),NOSPLIT,$0-28
+	CALL	runtime·entersyscall(SB)
+	MOVL	trap+0(FP), AX
+	MOVL	a1+4(FP), DI
+	MOVL	a2+8(FP), SI
+	MOVL	a3+12(FP), DX
+	// more args would use CX, R8, R9
+	SHLL	$5, AX
+	ADDL	$0x10000, AX
+	CALL	AX
+	CMPL	AX, $0
+	JGE	ok
+	MOVL	$-1, r1+16(FP)
+	MOVL	$-1, r2+20(FP)
+	NEGL	AX
+	MOVL	AX, err+24(FP)
+	CALL	runtime·exitsyscall(SB)
+	RET
+ok:
+	MOVL	AX, r1+16(FP)
+	MOVL	DX, r2+20(FP)
+	MOVL	$0, err+24(FP)
+	CALL	runtime·exitsyscall(SB)
+	RET	
diff --git a/src/syscall/asm_nacl_arm.s b/src/syscall/asm_nacl_arm.s
new file mode 100644
index 0000000..78e10bf
--- /dev/null
+++ b/src/syscall/asm_nacl_arm.s
@@ -0,0 +1,44 @@
+// 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"
+#include "funcdata.h"
+#include "../runtime/syscall_nacl.h"
+
+//
+// System call support for ARM, Native Client
+//
+
+#define NACL_SYSCALL(code) \
+	MOVW $(0x10000 + ((code)<<5)), R8; BL (R8)
+
+#define NACL_SYSJMP(code) \
+	MOVW $(0x10000 + ((code)<<5)), R8; B (R8)
+
+TEXT syscall·Syscall(SB),NOSPLIT,$0-28
+	BL	runtime·entersyscall(SB)
+	MOVW	trap+0(FP), R8
+	MOVW	a1+4(FP), R0
+	MOVW	a2+8(FP), R1
+	MOVW	a3+12(FP), R2
+	// more args would use R3, and then stack.
+	MOVW	$0x10000, R7
+	ADD	R8<<5, R7
+	BL	(R7)
+	CMP	$0, R0
+	BGE	ok
+	MOVW	$-1, R1
+	MOVW	R1, r1+16(FP)
+	MOVW	R1, r2+20(FP)
+	RSB	$0, R0
+	MOVW	R0, err+24(FP)
+	BL	runtime·exitsyscall(SB)
+	RET
+ok:
+	MOVW	R0, r1+16(FP)
+	MOVW	R1, r2+20(FP)
+	MOVW	$0, R2
+	MOVW	R2, err+24(FP)
+	BL	runtime·exitsyscall(SB)
+	RET	
diff --git a/src/syscall/asm_netbsd_386.s b/src/syscall/asm_netbsd_386.s
new file mode 100644
index 0000000..a8c4849
--- /dev/null
+++ b/src/syscall/asm_netbsd_386.s
@@ -0,0 +1,143 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// TODO(rsc): Rewrite all nn(SP) references into name+(nn-8)(FP)
+// so that go vet can check that they are correct.
+
+#include "textflag.h"
+#include "funcdata.h"
+
+//
+// System call support for 386, NetBSD
+//
+
+// func Syscall(trap int32, a1, a2, a3 int32) (r1, r2, err int32);
+// func Syscall6(trap int32, a1, a2, a3, a4, a5, a6 int32) (r1, r2, err int32);
+// Trap # in AX, args on stack above caller pc.
+
+TEXT	·Syscall(SB),NOSPLIT,$0-28
+	CALL	runtime·entersyscall(SB)
+	MOVL	4(SP), AX	// syscall entry
+	// slide args down on top of system call number
+	LEAL		8(SP), SI
+	LEAL		4(SP), DI
+	CLD
+	MOVSL
+	MOVSL
+	MOVSL
+	INT	$0x80
+	JAE	ok
+	MOVL	$-1, 20(SP)	// r1
+	MOVL	$-1, 24(SP)	// r2
+	MOVL	AX, 28(SP)		// errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+ok:
+	MOVL	AX, 20(SP)	// r1
+	MOVL	DX, 24(SP)	// r2
+	MOVL	$0, 28(SP)	// errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+
+TEXT	·Syscall6(SB),NOSPLIT,$0-40
+	CALL	runtime·entersyscall(SB)
+	MOVL	4(SP), AX	// syscall entry
+	// slide args down on top of system call number
+	LEAL		8(SP), SI
+	LEAL		4(SP), DI
+	CLD
+	MOVSL
+	MOVSL
+	MOVSL
+	MOVSL
+	MOVSL
+	MOVSL
+	INT	$0x80
+	JAE	ok6
+	MOVL	$-1, 32(SP)	// r1
+	MOVL	$-1, 36(SP)	// r2
+	MOVL	AX, 40(SP)		// errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+ok6:
+	MOVL	AX, 32(SP)	// r1
+	MOVL	DX, 36(SP)	// r2
+	MOVL	$0, 40(SP)	// errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+
+TEXT	·Syscall9(SB),NOSPLIT,$0-52
+	CALL	runtime·entersyscall(SB)
+	MOVL	4(SP), AX	// syscall entry
+	// slide args down on top of system call number
+	LEAL		8(SP), SI
+	LEAL		4(SP), DI
+	CLD
+	MOVSL
+	MOVSL
+	MOVSL
+	MOVSL
+	MOVSL
+	MOVSL
+	MOVSL
+	MOVSL
+	MOVSL
+	INT	$0x80
+	JAE	ok9
+	MOVL	$-1, 44(SP)	// r1
+	MOVL	$-1, 48(SP)	// r2
+	MOVL	AX, 52(SP)		// errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+ok9:
+	MOVL	AX, 44(SP)	// r1
+	MOVL	DX, 48(SP)	// r2
+	MOVL	$0, 52(SP)	// errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+
+TEXT ·RawSyscall(SB),NOSPLIT,$0-28
+	MOVL	4(SP), AX	// syscall entry
+	// slide args down on top of system call number
+	LEAL		8(SP), SI
+	LEAL		4(SP), DI
+	CLD
+	MOVSL
+	MOVSL
+	MOVSL
+	INT	$0x80
+	JAE	ok1
+	MOVL	$-1, 20(SP)	// r1
+	MOVL	$-1, 24(SP)	// r2
+	MOVL	AX, 28(SP)		// errno
+	RET
+ok1:
+	MOVL	AX, 20(SP)	// r1
+	MOVL	DX, 24(SP)	// r2
+	MOVL	$0, 28(SP)	// errno
+	RET
+
+TEXT	·RawSyscall6(SB),NOSPLIT,$0-40
+	MOVL	4(SP), AX	// syscall entry
+	// slide args down on top of system call number
+	LEAL		8(SP), SI
+	LEAL		4(SP), DI
+	CLD
+	MOVSL
+	MOVSL
+	MOVSL
+	MOVSL
+	MOVSL
+	MOVSL
+	INT	$0x80
+	JAE	ok2
+	MOVL	$-1, 32(SP)	// r1
+	MOVL	$-1, 36(SP)	// r2
+	MOVL	AX, 40(SP)		// errno
+	RET
+ok2:
+	MOVL	AX, 32(SP)	// r1
+	MOVL	DX, 36(SP)	// r2
+	MOVL	$0, 40(SP)	// errno
+	RET
diff --git a/src/syscall/asm_netbsd_amd64.s b/src/syscall/asm_netbsd_amd64.s
new file mode 100644
index 0000000..b300148
--- /dev/null
+++ b/src/syscall/asm_netbsd_amd64.s
@@ -0,0 +1,136 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// TODO(rsc): Rewrite all nn(SP) references into name+(nn-8)(FP)
+// so that go vet can check that they are correct.
+
+#include "textflag.h"
+#include "funcdata.h"
+
+//
+// System call support for AMD64, NetBSD
+//
+
+// func Syscall(trap int64, a1, a2, a3 int64) (r1, r2, err int64);
+// func Syscall6(trap int64, a1, a2, a3, a4, a5, a6 int64) (r1, r2, err int64);
+// func Syscall9(trap int64, a1, a2, a3, a4, a5, a6, a7, a8, a9 int64) (r1, r2, err int64);
+// Trap # in AX, args in DI SI DX, return in AX DX
+
+TEXT	·Syscall(SB),NOSPLIT,$0-56
+	CALL	runtime·entersyscall(SB)
+	MOVQ	8(SP), AX	// syscall entry
+	MOVQ	16(SP), DI
+	MOVQ	24(SP), SI
+	MOVQ	32(SP), DX
+	MOVQ	$0, R10
+	MOVQ	$0, R8
+	MOVQ	$0, R9
+	SYSCALL
+	JCC	ok
+	MOVQ	$-1, 40(SP)	// r1
+	MOVQ	$0, 48(SP)	// r2
+	MOVQ	AX, 56(SP)	// errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+ok:
+	MOVQ	AX, 40(SP)	// r1
+	MOVQ	DX, 48(SP)	// r2
+	MOVQ	$0, 56(SP)	// errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+
+TEXT	·Syscall6(SB),NOSPLIT,$0-80
+	CALL	runtime·entersyscall(SB)
+	MOVQ	8(SP), AX	// syscall entry
+	MOVQ	16(SP), DI
+	MOVQ	24(SP), SI
+	MOVQ	32(SP), DX
+	MOVQ	40(SP), R10
+	MOVQ	48(SP), R8
+	MOVQ	56(SP), R9
+	SYSCALL
+	JCC	ok6
+	MOVQ	$-1, 64(SP)	// r1
+	MOVQ	$0, 72(SP)	// r2
+	MOVQ	AX, 80(SP)  	// errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+ok6:
+	MOVQ	AX, 64(SP)	// r1
+	MOVQ	DX, 72(SP)	// r2
+	MOVQ	$0, 80(SP)	// errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+
+TEXT	·Syscall9(SB),NOSPLIT,$0-104
+	CALL	runtime·entersyscall(SB)
+	MOVQ	8(SP), AX	// syscall entry
+	MOVQ	16(SP), DI
+	MOVQ	24(SP), SI
+	MOVQ	32(SP), DX
+	MOVQ	40(SP), R10
+	MOVQ	48(SP), R8
+	MOVQ	56(SP), R9
+	MOVQ	64(SP), R11
+	MOVQ	72(SP), R12
+	MOVQ	80(SP), R13
+	SUBQ    $32, SP
+	MOVQ	R11, 8(SP)	// arg 7
+	MOVQ	R12, 16(SP)	// arg 8
+	MOVQ	R13, 24(SP)	// arg 9
+	SYSCALL
+	JCC	ok9
+	ADDQ    $32, SP
+	MOVQ	$-1, 88(SP)	// r1
+	MOVQ	$0, 96(SP)	// r2
+	MOVQ	AX, 104(SP)	// errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+ok9:
+	ADDQ    $32, SP
+	MOVQ	AX, 88(SP)	// r1
+	MOVQ	DX, 96(SP)	// r2
+	MOVQ	$0, 104(SP)	// errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+
+TEXT	·RawSyscall(SB),NOSPLIT,$0-56
+	MOVQ	16(SP), DI
+	MOVQ	24(SP), SI
+	MOVQ	32(SP), DX
+	MOVQ	$0, R10
+	MOVQ	$0, R8
+	MOVQ	$0, R9
+	MOVQ	8(SP), AX	// syscall entry
+	SYSCALL
+	JCC	ok1
+	MOVQ	$-1, 40(SP)	// r1
+	MOVQ	$0, 48(SP)	// r2
+	MOVQ	AX, 56(SP)	// errno
+	RET
+ok1:
+	MOVQ	AX, 40(SP)	// r1
+	MOVQ	DX, 48(SP)	// r2
+	MOVQ	$0, 56(SP)	// errno
+	RET
+
+TEXT	·RawSyscall6(SB),NOSPLIT,$0-80
+	MOVQ	16(SP), DI
+	MOVQ	24(SP), SI
+	MOVQ	32(SP), DX
+	MOVQ	40(SP), R10
+	MOVQ	48(SP), R8
+	MOVQ	56(SP), R9
+	MOVQ	8(SP), AX	// syscall entry
+	SYSCALL
+	JCC	ok2
+	MOVQ	$-1, 64(SP)	// r1
+	MOVQ	$0, 72(SP)	// r2
+	MOVQ	AX, 80(SP)	// errno
+	RET
+ok2:
+	MOVQ	AX, 64(SP)	// r1
+	MOVQ	DX, 72(SP)	// r2
+	MOVQ	$0, 80(SP)	// errno
+	RET
diff --git a/src/syscall/asm_netbsd_arm.s b/src/syscall/asm_netbsd_arm.s
new file mode 100644
index 0000000..290bb58
--- /dev/null
+++ b/src/syscall/asm_netbsd_arm.s
@@ -0,0 +1,127 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+#include "funcdata.h"
+
+//
+// System call support for ARM, NetBSD
+//
+
+// func Syscall(trap int32, a1, a2, a3 int32) (r1, r2, err int32);
+// func Syscall6(trap int32, a1, a2, a3, a4, a5, a6 int32) (r1, r2, err int32);
+// func Syscall9(trap int32, a1, a2, a3, a4, a5, a6, a7, a8, a9 int64) (r1, r2, err int32)
+
+TEXT	·Syscall(SB),NOSPLIT,$0-28
+	BL runtime·entersyscall(SB)
+	MOVW 0(FP), R0 // sigcall num
+	MOVW 4(FP), R1 // a1
+	MOVW 8(FP), R2 // a2
+	MOVW 12(FP), R3 // a3
+	SWI $0 // syscall
+	MOVW $0, R2
+	BCS error
+	MOVW R0, 16(FP) // r1
+	MOVW R1, 20(FP) // r2
+	MOVW R2, 24(FP) // err
+	BL runtime·exitsyscall(SB)
+	RET
+error:
+	MOVW $-1, R3
+	MOVW R3, 16(FP) // r1
+	MOVW R2, 20(FP) // r2
+	MOVW R0, 24(FP) // err
+	BL runtime·exitsyscall(SB)
+	RET
+
+TEXT	·Syscall6(SB),NOSPLIT,$0-40
+	BL runtime·entersyscall(SB)
+	MOVW 0(FP), R0 // sigcall num
+	MOVW 4(FP), R1 // a1
+	MOVW 8(FP), R2 // a2
+	MOVW 12(FP), R3 // a3
+	MOVW R13, R4
+	MOVW $16(FP), R13 // a4 to a6 are passed on stack
+	SWI $0 // syscall
+	MOVW R4, R13
+	MOVW $0, R2
+	BCS error6
+	MOVW R0, 28(FP) // r1
+	MOVW R1, 32(FP) // r2
+	MOVW R2, 36(FP) // err
+	BL runtime·exitsyscall(SB)
+	RET
+error6:
+	MOVW $-1, R3
+	MOVW R3, 28(FP) // r1
+	MOVW R2, 32(FP) // r2
+	MOVW R0, 36(FP) // err
+	BL runtime·exitsyscall(SB)
+	RET
+
+TEXT	·Syscall9(SB),NOSPLIT,$0-52
+	BL runtime·entersyscall(SB)
+	MOVW 0(FP), R0 // sigcall num
+	MOVW 4(FP), R1 // a1
+	MOVW 8(FP), R2 // a2
+	MOVW 12(FP), R3 // a3
+	MOVW R13, R4
+	MOVW $16(FP), R13 // a4 to a9 are passed on stack
+	SWI $0 // syscall
+	MOVW R4, R13
+	MOVW $0, R2
+	BCS error9
+	MOVW R0, 40(FP) // r1
+	MOVW R1, 44(FP) // r2
+	MOVW R2, 48(FP) // err
+	BL runtime·exitsyscall(SB)
+	RET
+error9:
+	MOVW $-1, R3
+	MOVW R3, 40(FP) // r1
+	MOVW R2, 44(FP) // r2
+	MOVW R0, 48(FP) // err
+	BL runtime·exitsyscall(SB)
+	RET
+
+TEXT	·RawSyscall(SB),NOSPLIT,$0-28
+	MOVW 0(FP), R0 // sigcall num
+	MOVW 4(FP), R1 // a1
+	MOVW 8(FP), R2 // a2
+	MOVW 12(FP), R3 // a3
+	SWI $0 // syscall
+	MOVW $0, R2
+	BCS errorr
+	MOVW R0, 16(FP) // r1
+	MOVW R1, 20(FP) // r2
+	MOVW R2, 24(FP) // err
+	RET
+errorr:
+	MOVW $-1, R3
+	MOVW R3, 16(FP) // r1
+	MOVW R2, 20(FP) // r2
+	MOVW R0, 24(FP) // err
+	RET
+
+TEXT	·RawSyscall6(SB),NOSPLIT,$0-40
+	MOVW 0(FP), R0 // sigcall num
+	MOVW 4(FP), R1 // a1
+	MOVW 8(FP), R2 // a2
+	MOVW 12(FP), R3 // a3
+	MOVW R13, R4
+	MOVW $16(FP), R13 // a4 to a9 are passed on stack
+	SWI $0 // syscall
+	MOVW R4, R13
+	MOVW $0, R2
+	BCS errorr6
+	MOVW R0, 28(FP) // r1
+	MOVW R1, 32(FP) // r2
+	MOVW R2, 36(FP) // err
+	RET
+errorr6:
+	MOVW $-1, R3
+	MOVW R3, 28(FP) // r1
+	MOVW R2, 32(FP) // r2
+	MOVW R0, 36(FP) // err
+	RET
diff --git a/src/syscall/asm_openbsd_386.s b/src/syscall/asm_openbsd_386.s
new file mode 100644
index 0000000..6458bdf
--- /dev/null
+++ b/src/syscall/asm_openbsd_386.s
@@ -0,0 +1,143 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// TODO(rsc): Rewrite all nn(SP) references into name+(nn-8)(FP)
+// so that go vet can check that they are correct.
+
+#include "textflag.h"
+#include "funcdata.h"
+
+//
+// System call support for 386, OpenBSD
+//
+
+// func Syscall(trap int32, a1, a2, a3 int32) (r1, r2, err int32);
+// func Syscall6(trap int32, a1, a2, a3, a4, a5, a6 int32) (r1, r2, err int32);
+// Trap # in AX, args on stack above caller pc.
+
+TEXT	·Syscall(SB),NOSPLIT,$0-28
+	CALL	runtime·entersyscall(SB)
+	MOVL	4(SP), AX	// syscall entry
+	// slide args down on top of system call number
+	LEAL		8(SP), SI
+	LEAL		4(SP), DI
+	CLD
+	MOVSL
+	MOVSL
+	MOVSL
+	INT	$0x80
+	JAE	ok
+	MOVL	$-1, 20(SP)	// r1
+	MOVL	$-1, 24(SP)	// r2
+	MOVL	AX, 28(SP)		// errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+ok:
+	MOVL	AX, 20(SP)	// r1
+	MOVL	DX, 24(SP)	// r2
+	MOVL	$0, 28(SP)	// errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+
+TEXT	·Syscall6(SB),NOSPLIT,$0-40
+	CALL	runtime·entersyscall(SB)
+	MOVL	4(SP), AX	// syscall entry
+	// slide args down on top of system call number
+	LEAL		8(SP), SI
+	LEAL		4(SP), DI
+	CLD
+	MOVSL
+	MOVSL
+	MOVSL
+	MOVSL
+	MOVSL
+	MOVSL
+	INT	$0x80
+	JAE	ok6
+	MOVL	$-1, 32(SP)	// r1
+	MOVL	$-1, 36(SP)	// r2
+	MOVL	AX, 40(SP)		// errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+ok6:
+	MOVL	AX, 32(SP)	// r1
+	MOVL	DX, 36(SP)	// r2
+	MOVL	$0, 40(SP)	// errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+
+TEXT	·Syscall9(SB),NOSPLIT,$0-52
+	CALL	runtime·entersyscall(SB)
+	MOVL	4(SP), AX	// syscall entry
+	// slide args down on top of system call number
+	LEAL		8(SP), SI
+	LEAL		4(SP), DI
+	CLD
+	MOVSL
+	MOVSL
+	MOVSL
+	MOVSL
+	MOVSL
+	MOVSL
+	MOVSL
+	MOVSL
+	MOVSL
+	INT	$0x80
+	JAE	ok9
+	MOVL	$-1, 44(SP)	// r1
+	MOVL	$-1, 48(SP)	// r2
+	MOVL	AX, 52(SP)		// errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+ok9:
+	MOVL	AX, 44(SP)	// r1
+	MOVL	DX, 48(SP)	// r2
+	MOVL	$0, 52(SP)	// errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+
+TEXT ·RawSyscall(SB),NOSPLIT,$0-28
+	MOVL	4(SP), AX	// syscall entry
+	// slide args down on top of system call number
+	LEAL		8(SP), SI
+	LEAL		4(SP), DI
+	CLD
+	MOVSL
+	MOVSL
+	MOVSL
+	INT	$0x80
+	JAE	ok1
+	MOVL	$-1, 20(SP)	// r1
+	MOVL	$-1, 24(SP)	// r2
+	MOVL	AX, 28(SP)		// errno
+	RET
+ok1:
+	MOVL	AX, 20(SP)	// r1
+	MOVL	DX, 24(SP)	// r2
+	MOVL	$0, 28(SP)	// errno
+	RET
+
+TEXT	·RawSyscall6(SB),NOSPLIT,$0-40
+	MOVL	4(SP), AX	// syscall entry
+	// slide args down on top of system call number
+	LEAL		8(SP), SI
+	LEAL		4(SP), DI
+	CLD
+	MOVSL
+	MOVSL
+	MOVSL
+	MOVSL
+	MOVSL
+	MOVSL
+	INT	$0x80
+	JAE	ok2
+	MOVL	$-1, 32(SP)	// r1
+	MOVL	$-1, 36(SP)	// r2
+	MOVL	AX, 40(SP)		// errno
+	RET
+ok2:
+	MOVL	AX, 32(SP)	// r1
+	MOVL	DX, 36(SP)	// r2
+	MOVL	$0, 40(SP)	// errno
+	RET
diff --git a/src/syscall/asm_openbsd_amd64.s b/src/syscall/asm_openbsd_amd64.s
new file mode 100644
index 0000000..1e981fc
--- /dev/null
+++ b/src/syscall/asm_openbsd_amd64.s
@@ -0,0 +1,136 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// TODO(rsc): Rewrite all nn(SP) references into name+(nn-8)(FP)
+// so that go vet can check that they are correct.
+
+#include "textflag.h"
+#include "funcdata.h"
+
+//
+// System call support for AMD64, OpenBSD
+//
+
+// func Syscall(trap int64, a1, a2, a3 int64) (r1, r2, err int64);
+// func Syscall6(trap int64, a1, a2, a3, a4, a5, a6 int64) (r1, r2, err int64);
+// func Syscall9(trap int64, a1, a2, a3, a4, a5, a6, a7, a8, a9 int64) (r1, r2, err int64);
+// Trap # in AX, args in DI SI DX, return in AX DX
+
+TEXT	·Syscall(SB),NOSPLIT,$0-56
+	CALL	runtime·entersyscall(SB)
+	MOVQ	8(SP), AX	// syscall entry
+	MOVQ	16(SP), DI
+	MOVQ	24(SP), SI
+	MOVQ	32(SP), DX
+	MOVQ	$0, R10
+	MOVQ	$0, R8
+	MOVQ	$0, R9
+	SYSCALL
+	JCC	ok
+	MOVQ	$-1, 40(SP)	// r1
+	MOVQ	$0, 48(SP)	// r2
+	MOVQ	AX, 56(SP)	// errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+ok:
+	MOVQ	AX, 40(SP)	// r1
+	MOVQ	DX, 48(SP)	// r2
+	MOVQ	$0, 56(SP)	// errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+
+TEXT	·Syscall6(SB),NOSPLIT,$0-80
+	CALL	runtime·entersyscall(SB)
+	MOVQ	8(SP), AX	// syscall entry
+	MOVQ	16(SP), DI
+	MOVQ	24(SP), SI
+	MOVQ	32(SP), DX
+	MOVQ	40(SP), R10
+	MOVQ	48(SP), R8
+	MOVQ	56(SP), R9
+	SYSCALL
+	JCC	ok6
+	MOVQ	$-1, 64(SP)	// r1
+	MOVQ	$0, 72(SP)	// r2
+	MOVQ	AX, 80(SP)  	// errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+ok6:
+	MOVQ	AX, 64(SP)	// r1
+	MOVQ	DX, 72(SP)	// r2
+	MOVQ	$0, 80(SP)	// errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+
+TEXT	·Syscall9(SB),NOSPLIT,$0-104
+	CALL	runtime·entersyscall(SB)
+	MOVQ	8(SP), AX	// syscall entry
+	MOVQ	16(SP), DI
+	MOVQ	24(SP), SI
+	MOVQ	32(SP), DX
+	MOVQ	40(SP), R10
+	MOVQ	48(SP), R8
+	MOVQ	56(SP), R9
+	MOVQ	64(SP), R11
+	MOVQ	72(SP), R12
+	MOVQ	80(SP), R13
+	SUBQ    $32, SP
+	MOVQ	R11, 8(SP)	// arg 7
+	MOVQ	R12, 16(SP)	// arg 8
+	MOVQ	R13, 24(SP)	// arg 9
+	SYSCALL
+	JCC	ok9
+	ADDQ    $32, SP
+	MOVQ	$-1, 88(SP)	// r1
+	MOVQ	$0, 96(SP)	// r2
+	MOVQ	AX, 104(SP)	// errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+ok9:
+	ADDQ    $32, SP
+	MOVQ	AX, 88(SP)	// r1
+	MOVQ	DX, 96(SP)	// r2
+	MOVQ	$0, 104(SP)	// errno
+	CALL	runtime·exitsyscall(SB)
+	RET
+
+TEXT	·RawSyscall(SB),NOSPLIT,$0-56
+	MOVQ	16(SP), DI
+	MOVQ	24(SP), SI
+	MOVQ	32(SP), DX
+	MOVQ	$0, R10
+	MOVQ	$0, R8
+	MOVQ	$0, R9
+	MOVQ	8(SP), AX	// syscall entry
+	SYSCALL
+	JCC	ok1
+	MOVQ	$-1, 40(SP)	// r1
+	MOVQ	$0, 48(SP)	// r2
+	MOVQ	AX, 56(SP)	// errno
+	RET
+ok1:
+	MOVQ	AX, 40(SP)	// r1
+	MOVQ	DX, 48(SP)	// r2
+	MOVQ	$0, 56(SP)	// errno
+	RET
+
+TEXT	·RawSyscall6(SB),NOSPLIT,$0-80
+	MOVQ	16(SP), DI
+	MOVQ	24(SP), SI
+	MOVQ	32(SP), DX
+	MOVQ	40(SP), R10
+	MOVQ	48(SP), R8
+	MOVQ	56(SP), R9
+	MOVQ	8(SP), AX	// syscall entry
+	SYSCALL
+	JCC	ok2
+	MOVQ	$-1, 64(SP)	// r1
+	MOVQ	$0, 72(SP)	// r2
+	MOVQ	AX, 80(SP)	// errno
+	RET
+ok2:
+	MOVQ	AX, 64(SP)	// r1
+	MOVQ	DX, 72(SP)	// r2
+	MOVQ	$0, 80(SP)	// errno
+	RET
diff --git a/src/syscall/asm_plan9_386.s b/src/syscall/asm_plan9_386.s
new file mode 100644
index 0000000..fc13640
--- /dev/null
+++ b/src/syscall/asm_plan9_386.s
@@ -0,0 +1,166 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// TODO(rsc): Rewrite all nn(SP) references into name+(nn-8)(FP)
+// so that go vet can check that they are correct.
+
+#include "textflag.h"
+#include "funcdata.h"
+
+//
+// System call support for 386, Plan 9
+//
+
+//func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err string)
+//func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err string)
+//func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr)
+//func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr)
+
+// Trap # in AX, args on stack above caller pc.
+TEXT	·Syscall(SB),NOSPLIT,$0-32
+	CALL	runtime·entersyscall(SB)
+	MOVL	4(SP), AX	// syscall entry
+	// slide args down on top of system call number
+	LEAL		8(SP), SI
+	LEAL		4(SP), DI
+	CLD
+	MOVSL
+	MOVSL
+	MOVSL
+	INT	$64
+	MOVL	AX, r1+20(SP)
+	MOVL	$0, r2+24(SP)
+	CMPL	AX, $-1
+	JNE	ok3
+
+	SUBL	$8, SP
+	CALL	runtime·errstr(SB)
+	MOVL	SP, SI
+	ADDL	$8, SP
+	JMP	copyresult3
+	
+ok3:
+	LEAL	runtime·emptystring(SB), SI	
+	
+copyresult3:
+	LEAL	err+28(SP), DI
+
+	CLD
+	MOVSL
+	MOVSL
+
+	CALL	runtime·exitsyscall(SB)
+	RET
+
+TEXT	·Syscall6(SB),NOSPLIT,$0-44
+	CALL	runtime·entersyscall(SB)
+	MOVL	4(SP), AX	// syscall entry
+	// slide args down on top of system call number
+	LEAL		8(SP), SI
+	LEAL		4(SP), DI
+	CLD
+	MOVSL
+	MOVSL
+	MOVSL
+	MOVSL
+	MOVSL
+	MOVSL
+	INT	$64
+	MOVL	AX, r1+32(SP)
+	MOVL	$0, r2+36(SP)
+	CMPL	AX, $-1
+	JNE	ok4
+	
+	SUBL	$8, SP
+	CALL	runtime·errstr(SB)
+	MOVL	SP, SI
+	ADDL	$8, SP
+	JMP	copyresult4
+	
+ok4:
+	LEAL	runtime·emptystring(SB), SI
+	
+copyresult4:
+	LEAL	err+40(SP), DI
+
+	CLD
+	MOVSL
+	MOVSL
+
+	CALL	runtime·exitsyscall(SB)
+	RET
+
+TEXT ·RawSyscall(SB),NOSPLIT,$0-28
+	MOVL	4(SP), AX	// syscall entry
+	// slide args down on top of system call number
+	LEAL		8(SP), SI
+	LEAL		4(SP), DI
+	CLD
+	MOVSL
+	MOVSL
+	MOVSL
+	INT	$64
+	MOVL	AX, r1+20(SP)
+	MOVL	AX, r2+24(SP)
+	MOVL	AX, err+28(SP)
+	RET
+
+TEXT	·RawSyscall6(SB),NOSPLIT,$0-40
+	MOVL	4(SP), AX	// syscall entry
+	// slide args down on top of system call number
+	LEAL		8(SP), SI
+	LEAL		4(SP), DI
+	CLD
+	MOVSL
+	MOVSL
+	MOVSL
+	MOVSL
+	MOVSL
+	MOVSL
+	INT	$64
+	MOVL	AX, r1+32(SP)
+	MOVL	AX, r2+36(SP)
+	MOVL	AX, err+40(SP)		
+	RET
+
+#define SYS_SEEK 39	/* from zsysnum_plan9_386.go */
+
+//func seek(placeholder uintptr, fd int, offset int64, whence int) (newoffset int64, err string)
+TEXT ·seek(SB),NOSPLIT,$0-36
+	LEAL	newoffset+24(SP), AX
+	MOVL	AX, placeholder+4(SP)
+	
+	MOVL	$SYS_SEEK, AX	// syscall entry
+	INT	$64
+	
+	CMPL	AX, $-1
+	JNE	ok6
+	MOVL	AX, 24(SP)	// newoffset low
+	MOVL	AX, 28(SP)	// newoffset high
+	
+	SUBL	$8, SP
+	CALL	syscall·errstr(SB)
+	MOVL	SP, SI
+	ADDL	$8, SP	
+	JMP	copyresult6
+	
+ok6:
+	LEAL	runtime·emptystring(SB), SI
+	
+copyresult6:
+	LEAL	err+32(SP), DI
+
+	CLD
+	MOVSL
+	MOVSL
+	RET
+
+//func exit(code int)
+// Import runtime·exit for cleanly exiting.
+TEXT ·exit(SB),NOSPLIT,$4-4
+	NO_LOCAL_POINTERS
+	MOVL	code+0(FP), AX
+	MOVL	AX, 0(SP)
+	CALL	runtime·exit(SB)
+	RET
diff --git a/src/syscall/asm_plan9_amd64.s b/src/syscall/asm_plan9_amd64.s
new file mode 100644
index 0000000..92419b7
--- /dev/null
+++ b/src/syscall/asm_plan9_amd64.s
@@ -0,0 +1,164 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// TODO(rsc): Rewrite all nn(SP) references into name+(nn-8)(FP)
+// so that go vet can check that they are correct.
+
+#include "textflag.h"
+#include "funcdata.h"
+
+//
+// System call support for Plan 9
+//
+
+//func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err string)
+//func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err string)
+//func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr)
+//func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr)
+
+TEXT	·Syscall(SB),NOSPLIT,$0-64
+	CALL	runtime·entersyscall(SB)
+	MOVQ	8(SP), BP	// syscall entry
+	// slide args down on top of system call number
+	LEAQ	16(SP), SI
+	LEAQ	8(SP), DI
+	CLD
+	MOVSQ
+	MOVSQ
+	MOVSQ
+	SYSCALL
+	MOVQ	AX, r1+40(SP)
+	MOVQ	$0, r2+48(SP)
+	CMPL	AX, $-1
+	JNE	ok3
+
+	SUBQ	$16, SP
+	CALL	runtime·errstr(SB)
+	MOVQ	SP, SI
+	ADDQ	$16, SP
+	JMP	copyresult3
+	
+ok3:
+	LEAQ	runtime·emptystring(SB), SI	
+	
+copyresult3:
+	LEAQ	err+56(SP), DI
+
+	CLD
+	MOVSQ
+	MOVSQ
+
+	CALL	runtime·exitsyscall(SB)
+	RET
+
+TEXT	·Syscall6(SB),NOSPLIT,$0-88
+	CALL	runtime·entersyscall(SB)
+	MOVQ	8(SP), BP	// syscall entry
+	// slide args down on top of system call number
+	LEAQ		16(SP), SI
+	LEAQ		8(SP), DI
+	CLD
+	MOVSQ
+	MOVSQ
+	MOVSQ
+	MOVSQ
+	MOVSQ
+	MOVSQ
+	SYSCALL
+	MOVQ	AX, r1+64(SP)
+	MOVQ	$0, r2+72(SP)
+	CMPL	AX, $-1
+	JNE	ok4
+	
+	SUBQ	$16, SP
+	CALL	runtime·errstr(SB)
+	MOVQ	SP, SI
+	ADDQ	$16, SP
+	JMP	copyresult4
+	
+ok4:
+	LEAQ	runtime·emptystring(SB), SI
+	
+copyresult4:
+	LEAQ	err+80(SP), DI
+
+	CLD
+	MOVSQ
+	MOVSQ
+
+	CALL	runtime·exitsyscall(SB)
+	RET
+
+TEXT ·RawSyscall(SB),NOSPLIT,$0-56
+	MOVQ	8(SP), BP	// syscall entry
+	// slide args down on top of system call number
+	LEAQ		16(SP), SI
+	LEAQ		8(SP), DI
+	CLD
+	MOVSQ
+	MOVSQ
+	MOVSQ
+	SYSCALL
+	MOVQ	AX, r1+40(SP)
+	MOVQ	AX, r2+48(SP)
+	MOVQ	AX, err+56(SP)
+	RET
+
+TEXT	·RawSyscall6(SB),NOSPLIT,$0-80
+	MOVQ	8(SP), BP	// syscall entry
+	// slide args down on top of system call number
+	LEAQ		16(SP), SI
+	LEAQ		8(SP), DI
+	CLD
+	MOVSQ
+	MOVSQ
+	MOVSQ
+	MOVSQ
+	MOVSQ
+	MOVSQ
+	SYSCALL
+	MOVQ	AX, r1+64(SP)
+	MOVQ	AX, r2+72(SP)
+	MOVQ	AX, err+80(SP)		
+	RET
+
+#define SYS_SEEK 39	/* from zsysnum_plan9_amd64.go */
+
+//func seek(placeholder uintptr, fd int, offset int64, whence int) (newoffset int64, err string)
+TEXT ·seek(SB),NOSPLIT,$0-56
+	LEAQ	newoffset+40(SP), AX
+	MOVQ	AX, placeholder+8(SP)
+	
+	MOVQ	$SYS_SEEK, BP	// syscall entry
+	SYSCALL
+	
+	CMPL	AX, $-1
+	JNE	ok6
+	MOVQ	$-1, newoffset+40(SP)
+	
+	SUBQ	$16, SP
+	CALL	syscall·errstr(SB)
+	MOVQ	SP, SI
+	ADDQ	$16, SP	
+	JMP	copyresult6
+	
+ok6:
+	LEAQ	runtime·emptystring(SB), SI
+	
+copyresult6:
+	LEAQ	err+48(SP), DI
+
+	CLD
+	MOVSQ
+	MOVSQ
+	RET
+
+//func exit(code int)
+// Import runtime·exit for cleanly exiting.
+TEXT ·exit(SB),NOSPLIT,$8-8
+	NO_LOCAL_POINTERS
+	MOVQ	code+0(FP), AX
+	MOVQ	AX, 0(SP)
+	CALL	runtime·exit(SB)
+	RET
diff --git a/src/syscall/asm_solaris_amd64.s b/src/syscall/asm_solaris_amd64.s
new file mode 100644
index 0000000..d0d271c
--- /dev/null
+++ b/src/syscall/asm_solaris_amd64.s
@@ -0,0 +1,81 @@
+// 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"
+
+//
+// System calls for solaris/amd64 are implemented in ../runtime/syscall_solaris.go
+//
+
+TEXT ·sysvicall6(SB),NOSPLIT,$0
+	JMP	runtime·syscall_sysvicall6(SB)
+
+TEXT ·rawSysvicall6(SB),NOSPLIT,$0
+	JMP	runtime·syscall_rawsysvicall6(SB)
+
+TEXT ·chdir(SB),NOSPLIT,$0
+	JMP	runtime·syscall_chdir(SB)
+
+TEXT ·chroot1(SB),NOSPLIT,$0
+	JMP	runtime·syscall_chroot(SB)
+
+TEXT ·close(SB),NOSPLIT,$0
+	JMP	runtime·syscall_close(SB)
+
+TEXT ·dlopen(SB),NOSPLIT,$0
+	JMP	runtime·syscall_dlopen(SB)
+
+TEXT ·dlclose(SB),NOSPLIT,$0
+	JMP	runtime·syscall_dlclose(SB)
+
+TEXT ·dlsym(SB),NOSPLIT,$0
+	JMP	runtime·syscall_dlsym(SB)
+
+TEXT ·execve(SB),NOSPLIT,$0
+	JMP	runtime·syscall_execve(SB)
+
+TEXT ·exit(SB),NOSPLIT,$0
+	JMP	runtime·syscall_exit(SB)
+
+TEXT ·fcntl1(SB),NOSPLIT,$0
+	JMP	runtime·syscall_fcntl(SB)
+
+TEXT ·forkx(SB),NOSPLIT,$0
+	JMP	runtime·syscall_forkx(SB)
+
+TEXT ·gethostname(SB),NOSPLIT,$0
+	JMP	runtime·syscall_gethostname(SB)
+
+TEXT ·ioctl(SB),NOSPLIT,$0
+	JMP	runtime·syscall_ioctl(SB)
+
+TEXT ·pipe(SB),NOSPLIT,$0
+	JMP	runtime·syscall_pipe(SB)
+
+TEXT ·RawSyscall(SB),NOSPLIT,$0
+	JMP	runtime·syscall_rawsyscall(SB)
+
+TEXT ·setgid(SB),NOSPLIT,$0
+	JMP	runtime·syscall_setgid(SB)
+
+TEXT ·setgroups1(SB),NOSPLIT,$0
+	JMP	runtime·syscall_setgroups(SB)
+
+TEXT ·setsid(SB),NOSPLIT,$0
+	JMP	runtime·syscall_setsid(SB)
+
+TEXT ·setuid(SB),NOSPLIT,$0
+	JMP	runtime·syscall_setuid(SB)
+
+TEXT ·setpgid(SB),NOSPLIT,$0
+	JMP	runtime·syscall_setpgid(SB)
+
+TEXT ·Syscall(SB),NOSPLIT,$0
+	JMP	runtime·syscall_syscall(SB)
+
+TEXT ·wait4(SB),NOSPLIT,$0
+	JMP	runtime·syscall_wait4(SB)
+
+TEXT ·write1(SB),NOSPLIT,$0
+	JMP	runtime·syscall_write(SB)
diff --git a/src/pkg/syscall/bpf_bsd.go b/src/syscall/bpf_bsd.go
similarity index 100%
rename from src/pkg/syscall/bpf_bsd.go
rename to src/syscall/bpf_bsd.go
diff --git a/src/pkg/syscall/creds_test.go b/src/syscall/creds_test.go
similarity index 100%
rename from src/pkg/syscall/creds_test.go
rename to src/syscall/creds_test.go
diff --git a/src/pkg/syscall/dir_plan9.go b/src/syscall/dir_plan9.go
similarity index 100%
rename from src/pkg/syscall/dir_plan9.go
rename to src/syscall/dir_plan9.go
diff --git a/src/syscall/dll_windows.go b/src/syscall/dll_windows.go
new file mode 100644
index 0000000..18663b4
--- /dev/null
+++ b/src/syscall/dll_windows.go
@@ -0,0 +1,280 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package syscall
+
+import (
+	"sync"
+	"sync/atomic"
+	"unsafe"
+)
+
+// DLLError describes reasons for DLL load failures.
+type DLLError struct {
+	Err     error
+	ObjName string
+	Msg     string
+}
+
+func (e *DLLError) Error() string { return e.Msg }
+
+// Implemented in ../runtime/syscall_windows.go.
+func Syscall(trap, nargs, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
+func Syscall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
+func Syscall9(trap, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err Errno)
+func Syscall12(trap, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12 uintptr) (r1, r2 uintptr, err Errno)
+func Syscall15(trap, nargs, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15 uintptr) (r1, r2 uintptr, err Errno)
+func loadlibrary(filename *uint16) (handle uintptr, err Errno)
+func getprocaddress(handle uintptr, procname *uint8) (proc uintptr, err Errno)
+
+// A DLL implements access to a single DLL.
+type DLL struct {
+	Name   string
+	Handle Handle
+}
+
+// LoadDLL loads DLL file into memory.
+func LoadDLL(name string) (dll *DLL, err error) {
+	namep, err := UTF16PtrFromString(name)
+	if err != nil {
+		return nil, err
+	}
+	h, e := loadlibrary(namep)
+	if e != 0 {
+		return nil, &DLLError{
+			Err:     e,
+			ObjName: name,
+			Msg:     "Failed to load " + name + ": " + e.Error(),
+		}
+	}
+	d := &DLL{
+		Name:   name,
+		Handle: Handle(h),
+	}
+	return d, nil
+}
+
+// MustLoadDLL is like LoadDLL but panics if load operation failes.
+func MustLoadDLL(name string) *DLL {
+	d, e := LoadDLL(name)
+	if e != nil {
+		panic(e)
+	}
+	return d
+}
+
+// FindProc searches DLL d for procedure named name and returns *Proc
+// if found. It returns an error if search fails.
+func (d *DLL) FindProc(name string) (proc *Proc, err error) {
+	namep, err := BytePtrFromString(name)
+	if err != nil {
+		return nil, err
+	}
+	a, e := getprocaddress(uintptr(d.Handle), namep)
+	use(unsafe.Pointer(namep))
+	if e != 0 {
+		return nil, &DLLError{
+			Err:     e,
+			ObjName: name,
+			Msg:     "Failed to find " + name + " procedure in " + d.Name + ": " + e.Error(),
+		}
+	}
+	p := &Proc{
+		Dll:  d,
+		Name: name,
+		addr: a,
+	}
+	return p, nil
+}
+
+// MustFindProc is like FindProc but panics if search fails.
+func (d *DLL) MustFindProc(name string) *Proc {
+	p, e := d.FindProc(name)
+	if e != nil {
+		panic(e)
+	}
+	return p
+}
+
+// Release unloads DLL d from memory.
+func (d *DLL) Release() (err error) {
+	return FreeLibrary(d.Handle)
+}
+
+// A Proc implements access to a procedure inside a DLL.
+type Proc struct {
+	Dll  *DLL
+	Name string
+	addr uintptr
+}
+
+// Addr returns the address of the procedure represented by p.
+// The return value can be passed to Syscall to run the procedure.
+func (p *Proc) Addr() uintptr {
+	return p.addr
+}
+
+// Call executes procedure p with arguments a. It will panic, if more then 15 arguments
+// are supplied.
+//
+// The returned error is always non-nil, constructed from the result of GetLastError.
+// Callers must inspect the primary return value to decide whether an error occurred
+// (according to the semantics of the specific function being called) before consulting
+// the error. The error will be guaranteed to contain syscall.Errno.
+func (p *Proc) Call(a ...uintptr) (r1, r2 uintptr, lastErr error) {
+	switch len(a) {
+	case 0:
+		return Syscall(p.Addr(), uintptr(len(a)), 0, 0, 0)
+	case 1:
+		return Syscall(p.Addr(), uintptr(len(a)), a[0], 0, 0)
+	case 2:
+		return Syscall(p.Addr(), uintptr(len(a)), a[0], a[1], 0)
+	case 3:
+		return Syscall(p.Addr(), uintptr(len(a)), a[0], a[1], a[2])
+	case 4:
+		return Syscall6(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], 0, 0)
+	case 5:
+		return Syscall6(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], 0)
+	case 6:
+		return Syscall6(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5])
+	case 7:
+		return Syscall9(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], 0, 0)
+	case 8:
+		return Syscall9(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], 0)
+	case 9:
+		return Syscall9(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8])
+	case 10:
+		return Syscall12(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], 0, 0)
+	case 11:
+		return Syscall12(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], 0)
+	case 12:
+		return Syscall12(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11])
+	case 13:
+		return Syscall15(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], 0, 0)
+	case 14:
+		return Syscall15(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], 0)
+	case 15:
+		return Syscall15(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14])
+	default:
+		panic("Call " + p.Name + " with too many arguments " + itoa(len(a)) + ".")
+	}
+	return
+}
+
+// A LazyDLL implements access to a single DLL.
+// It will delay the load of the DLL until the first
+// call to its Handle method or to one of its
+// LazyProc's Addr method.
+type LazyDLL struct {
+	mu   sync.Mutex
+	dll  *DLL // non nil once DLL is loaded
+	Name string
+}
+
+// Load loads DLL file d.Name into memory. It returns an error if fails.
+// Load will not try to load DLL, if it is already loaded into memory.
+func (d *LazyDLL) Load() error {
+	// Non-racy version of:
+	// if d.dll == nil {
+	if atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(&d.dll))) == nil {
+		d.mu.Lock()
+		defer d.mu.Unlock()
+		if d.dll == nil {
+			dll, e := LoadDLL(d.Name)
+			if e != nil {
+				return e
+			}
+			// Non-racy version of:
+			// d.dll = dll
+			atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(&d.dll)), unsafe.Pointer(dll))
+		}
+	}
+	return nil
+}
+
+// mustLoad is like Load but panics if search fails.
+func (d *LazyDLL) mustLoad() {
+	e := d.Load()
+	if e != nil {
+		panic(e)
+	}
+}
+
+// Handle returns d's module handle.
+func (d *LazyDLL) Handle() uintptr {
+	d.mustLoad()
+	return uintptr(d.dll.Handle)
+}
+
+// NewProc returns a LazyProc for accessing the named procedure in the DLL d.
+func (d *LazyDLL) NewProc(name string) *LazyProc {
+	return &LazyProc{l: d, Name: name}
+}
+
+// NewLazyDLL creates new LazyDLL associated with DLL file.
+func NewLazyDLL(name string) *LazyDLL {
+	return &LazyDLL{Name: name}
+}
+
+// A LazyProc implements access to a procedure inside a LazyDLL.
+// It delays the lookup until the Addr method is called.
+type LazyProc struct {
+	mu   sync.Mutex
+	Name string
+	l    *LazyDLL
+	proc *Proc
+}
+
+// Find searches DLL for procedure named p.Name. It returns
+// an error if search fails. Find will not search procedure,
+// if it is already found and loaded into memory.
+func (p *LazyProc) Find() error {
+	// Non-racy version of:
+	// if p.proc == nil {
+	if atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(&p.proc))) == nil {
+		p.mu.Lock()
+		defer p.mu.Unlock()
+		if p.proc == nil {
+			e := p.l.Load()
+			if e != nil {
+				return e
+			}
+			proc, e := p.l.dll.FindProc(p.Name)
+			if e != nil {
+				return e
+			}
+			// Non-racy version of:
+			// p.proc = proc
+			atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(&p.proc)), unsafe.Pointer(proc))
+		}
+	}
+	return nil
+}
+
+// mustFind is like Find but panics if search fails.
+func (p *LazyProc) mustFind() {
+	e := p.Find()
+	if e != nil {
+		panic(e)
+	}
+}
+
+// Addr returns the address of the procedure represented by p.
+// The return value can be passed to Syscall to run the procedure.
+func (p *LazyProc) Addr() uintptr {
+	p.mustFind()
+	return p.proc.Addr()
+}
+
+// Call executes procedure p with arguments a. It will panic, if more then 15 arguments
+// are supplied.
+//
+// The returned error is always non-nil, constructed from the result of GetLastError.
+// Callers must inspect the primary return value to decide whether an error occurred
+// (according to the semantics of the specific function being called) before consulting
+// the error. The error will be guaranteed to contain syscall.Errno.
+func (p *LazyProc) Call(a ...uintptr) (r1, r2 uintptr, lastErr error) {
+	p.mustFind()
+	return p.proc.Call(a...)
+}
diff --git a/src/syscall/env_plan9.go b/src/syscall/env_plan9.go
new file mode 100644
index 0000000..9ea36c8
--- /dev/null
+++ b/src/syscall/env_plan9.go
@@ -0,0 +1,108 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Plan 9 environment variables.
+
+package syscall
+
+import (
+	"errors"
+)
+
+var (
+	errZeroLengthKey = errors.New("zero length key")
+	errShortWrite    = errors.New("i/o count too small")
+)
+
+func readenv(key string) (string, error) {
+	fd, err := Open("/env/"+key, O_RDONLY)
+	if err != nil {
+		return "", err
+	}
+	defer Close(fd)
+	l, _ := Seek(fd, 0, 2)
+	Seek(fd, 0, 0)
+	buf := make([]byte, l)
+	n, err := Read(fd, buf)
+	if err != nil {
+		return "", err
+	}
+	if n > 0 && buf[n-1] == 0 {
+		buf = buf[:n-1]
+	}
+	return string(buf), nil
+}
+
+func writeenv(key, value string) error {
+	fd, err := Create("/env/"+key, O_RDWR, 0666)
+	if err != nil {
+		return err
+	}
+	defer Close(fd)
+	b := []byte(value)
+	n, err := Write(fd, b)
+	if err != nil {
+		return err
+	}
+	if n != len(b) {
+		return errShortWrite
+	}
+	return nil
+}
+
+func Getenv(key string) (value string, found bool) {
+	if len(key) == 0 {
+		return "", false
+	}
+	v, err := readenv(key)
+	if err != nil {
+		return "", false
+	}
+	return v, true
+}
+
+func Setenv(key, value string) error {
+	if len(key) == 0 {
+		return errZeroLengthKey
+	}
+	err := writeenv(key, value)
+	if err != nil {
+		return err
+	}
+	return nil
+}
+
+func Clearenv() {
+	RawSyscall(SYS_RFORK, RFCENVG, 0, 0)
+}
+
+func Unsetenv(key string) error {
+	if len(key) == 0 {
+		return errZeroLengthKey
+	}
+	Remove("/env/" + key)
+	return nil
+}
+
+func Environ() []string {
+	fd, err := Open("/env", O_RDONLY)
+	if err != nil {
+		return nil
+	}
+	defer Close(fd)
+	files, err := readdirnames(fd)
+	if err != nil {
+		return nil
+	}
+	ret := make([]string, 0, len(files))
+
+	for _, key := range files {
+		v, err := readenv(key)
+		if err != nil {
+			continue
+		}
+		ret = append(ret, key+"="+v)
+	}
+	return ret
+}
diff --git a/src/syscall/env_unix.go b/src/syscall/env_unix.go
new file mode 100644
index 0000000..b5ded9c
--- /dev/null
+++ b/src/syscall/env_unix.go
@@ -0,0 +1,149 @@
+// Copyright 2010 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris
+
+// Unix environment variables.
+
+package syscall
+
+import "sync"
+
+var (
+	// envOnce guards initialization by copyenv, which populates env.
+	envOnce sync.Once
+
+	// envLock guards env and envs.
+	envLock sync.RWMutex
+
+	// env maps from an environment variable to its first occurrence in envs.
+	env map[string]int
+
+	// envs is provided by the runtime. elements are expected to
+	// be of the form "key=value". An empty string means deleted
+	// (or a duplicate to be ignored).
+	envs []string = runtime_envs()
+)
+
+func runtime_envs() []string // in package runtime
+
+// setenv_c and unsetenv_c are provided by the runtime but are no-ops
+// if cgo isn't loaded.
+func setenv_c(k, v string)
+func unsetenv_c(k string)
+
+func copyenv() {
+	env = make(map[string]int)
+	for i, s := range envs {
+		for j := 0; j < len(s); j++ {
+			if s[j] == '=' {
+				key := s[:j]
+				if _, ok := env[key]; !ok {
+					env[key] = i // first mention of key
+				} else {
+					// Clear duplicate keys. This permits Unsetenv to
+					// safely delete only the first item without
+					// worrying about unshadowing a later one,
+					// which might be a security problem.
+					envs[i] = ""
+				}
+				break
+			}
+		}
+	}
+}
+
+func Unsetenv(key string) error {
+	envOnce.Do(copyenv)
+
+	envLock.Lock()
+	defer envLock.Unlock()
+
+	if i, ok := env[key]; ok {
+		envs[i] = ""
+		delete(env, key)
+	}
+	unsetenv_c(key)
+	return nil
+}
+
+func Getenv(key string) (value string, found bool) {
+	envOnce.Do(copyenv)
+	if len(key) == 0 {
+		return "", false
+	}
+
+	envLock.RLock()
+	defer envLock.RUnlock()
+
+	i, ok := env[key]
+	if !ok {
+		return "", false
+	}
+	s := envs[i]
+	for i := 0; i < len(s); i++ {
+		if s[i] == '=' {
+			return s[i+1:], true
+		}
+	}
+	return "", false
+}
+
+func Setenv(key, value string) error {
+	envOnce.Do(copyenv)
+	if len(key) == 0 {
+		return EINVAL
+	}
+	for i := 0; i < len(key); i++ {
+		if key[i] == '=' || key[i] == 0 {
+			return EINVAL
+		}
+	}
+	for i := 0; i < len(value); i++ {
+		if value[i] == 0 {
+			return EINVAL
+		}
+	}
+
+	envLock.Lock()
+	defer envLock.Unlock()
+
+	i, ok := env[key]
+	kv := key + "=" + value
+	if ok {
+		envs[i] = kv
+	} else {
+		i = len(envs)
+		envs = append(envs, kv)
+	}
+	env[key] = i
+	setenv_c(key, value)
+	return nil
+}
+
+func Clearenv() {
+	envOnce.Do(copyenv) // prevent copyenv in Getenv/Setenv
+
+	envLock.Lock()
+	defer envLock.Unlock()
+
+	for k := range env {
+		unsetenv_c(k)
+	}
+	env = make(map[string]int)
+	envs = []string{}
+}
+
+func Environ() []string {
+	envOnce.Do(copyenv)
+	envLock.RLock()
+	defer envLock.RUnlock()
+	a := make([]string, 0, len(envs))
+	for _, env := range envs {
+		if env != "" {
+			a = append(a, env)
+		}
+	}
+	return a
+}
diff --git a/src/syscall/env_windows.go b/src/syscall/env_windows.go
new file mode 100644
index 0000000..bc21690
--- /dev/null
+++ b/src/syscall/env_windows.go
@@ -0,0 +1,90 @@
+// Copyright 2010 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Windows environment variables.
+
+package syscall
+
+import (
+	"unicode/utf16"
+	"unsafe"
+)
+
+func Getenv(key string) (value string, found bool) {
+	keyp, err := UTF16PtrFromString(key)
+	if err != nil {
+		return "", false
+	}
+	b := make([]uint16, 100)
+	n, e := GetEnvironmentVariable(keyp, &b[0], uint32(len(b)))
+	if n == 0 && e == ERROR_ENVVAR_NOT_FOUND {
+		return "", false
+	}
+	if n > uint32(len(b)) {
+		b = make([]uint16, n)
+		n, e = GetEnvironmentVariable(keyp, &b[0], uint32(len(b)))
+		if n > uint32(len(b)) {
+			n = 0
+		}
+	}
+	return string(utf16.Decode(b[0:n])), true
+}
+
+func Setenv(key, value string) error {
+	v, err := UTF16PtrFromString(value)
+	if err != nil {
+		return err
+	}
+	keyp, err := UTF16PtrFromString(key)
+	if err != nil {
+		return err
+	}
+	e := SetEnvironmentVariable(keyp, v)
+	if e != nil {
+		return e
+	}
+	return nil
+}
+
+func Unsetenv(key string) error {
+	keyp, err := UTF16PtrFromString(key)
+	if err != nil {
+		return err
+	}
+	return SetEnvironmentVariable(keyp, nil)
+}
+
+func Clearenv() {
+	for _, s := range Environ() {
+		// Environment variables can begin with =
+		// so start looking for the separator = at j=1.
+		// http://blogs.msdn.com/b/oldnewthing/archive/2010/05/06/10008132.aspx
+		for j := 1; j < len(s); j++ {
+			if s[j] == '=' {
+				Setenv(s[0:j], "")
+				break
+			}
+		}
+	}
+}
+
+func Environ() []string {
+	s, e := GetEnvironmentStrings()
+	if e != nil {
+		return nil
+	}
+	defer FreeEnvironmentStrings(s)
+	r := make([]string, 0, 50) // Empty with room to grow.
+	for from, i, p := 0, 0, (*[1 << 24]uint16)(unsafe.Pointer(s)); true; i++ {
+		if p[i] == 0 {
+			// empty string marks the end
+			if i <= from {
+				break
+			}
+			r = append(r, string(utf16.Decode(p[from:i])))
+			from = i + 1
+		}
+	}
+	return r
+}
diff --git a/src/pkg/syscall/exec_bsd.go b/src/syscall/exec_bsd.go
similarity index 100%
rename from src/pkg/syscall/exec_bsd.go
rename to src/syscall/exec_bsd.go
diff --git a/src/syscall/exec_linux.go b/src/syscall/exec_linux.go
new file mode 100644
index 0000000..042c20a
--- /dev/null
+++ b/src/syscall/exec_linux.go
@@ -0,0 +1,363 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build linux
+
+package syscall
+
+import (
+	"unsafe"
+)
+
+// SysProcIDMap holds Container ID to Host ID mappings used for User Namespaces in Linux.
+// See user_namespaces(7).
+type SysProcIDMap struct {
+	ContainerID int // Container ID.
+	HostID      int // Host ID.
+	Size        int // Size.
+}
+
+type SysProcAttr struct {
+	Chroot      string         // Chroot.
+	Credential  *Credential    // Credential.
+	Ptrace      bool           // Enable tracing.
+	Setsid      bool           // Create session.
+	Setpgid     bool           // Set process group ID to new pid (SYSV setpgrp)
+	Setctty     bool           // Set controlling terminal to fd Ctty (only meaningful if Setsid is set)
+	Noctty      bool           // Detach fd 0 from controlling terminal
+	Ctty        int            // Controlling TTY fd (Linux only)
+	Pdeathsig   Signal         // Signal that the process will get when its parent dies (Linux only)
+	Cloneflags  uintptr        // Flags for clone calls (Linux only)
+	UidMappings []SysProcIDMap // User ID mappings for user namespaces.
+	GidMappings []SysProcIDMap // Group ID mappings for user namespaces.
+}
+
+// Implemented in runtime package.
+func runtime_BeforeFork()
+func runtime_AfterFork()
+
+// Fork, dup fd onto 0..len(fd), and exec(argv0, argvv, envv) in child.
+// If a dup or exec fails, write the errno error to pipe.
+// (Pipe is close-on-exec so if exec succeeds, it will be closed.)
+// In the child, this function must not acquire any locks, because
+// they might have been locked at the time of the fork.  This means
+// no rescheduling, no malloc calls, and no new stack segments.
+// For the same reason compiler does not race instrument it.
+// The calls to RawSyscall are okay because they are assembly
+// functions that do not grow the stack.
+func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr *ProcAttr, sys *SysProcAttr, pipe int) (pid int, err Errno) {
+	// Declare all variables at top in case any
+	// declarations require heap allocation (e.g., err1).
+	var (
+		r1     uintptr
+		err1   Errno
+		err2   Errno
+		nextfd int
+		i      int
+		p      [2]int
+	)
+
+	// Guard against side effects of shuffling fds below.
+	// Make sure that nextfd is beyond any currently open files so
+	// that we can't run the risk of overwriting any of them.
+	fd := make([]int, len(attr.Files))
+	nextfd = len(attr.Files)
+	for i, ufd := range attr.Files {
+		if nextfd < int(ufd) {
+			nextfd = int(ufd)
+		}
+		fd[i] = int(ufd)
+	}
+	nextfd++
+
+	// Allocate another pipe for parent to child communication for
+	// synchronizing writing of User ID/Group ID mappings.
+	if sys.UidMappings != nil || sys.GidMappings != nil {
+		if err := forkExecPipe(p[:]); err != nil {
+			return 0, err.(Errno)
+		}
+	}
+
+	// About to call fork.
+	// No more allocation or calls of non-assembly functions.
+	runtime_BeforeFork()
+	r1, _, err1 = RawSyscall6(SYS_CLONE, uintptr(SIGCHLD)|sys.Cloneflags, 0, 0, 0, 0, 0)
+	if err1 != 0 {
+		runtime_AfterFork()
+		return 0, err1
+	}
+
+	if r1 != 0 {
+		// parent; return PID
+		runtime_AfterFork()
+		pid = int(r1)
+
+		if sys.UidMappings != nil || sys.GidMappings != nil {
+			Close(p[0])
+			err := writeUidGidMappings(pid, sys)
+			if err != nil {
+				err2 = err.(Errno)
+			}
+			RawSyscall(SYS_WRITE, uintptr(p[1]), uintptr(unsafe.Pointer(&err2)), unsafe.Sizeof(err2))
+			Close(p[1])
+		}
+
+		return pid, 0
+	}
+
+	// Fork succeeded, now in child.
+
+	// Wait for User ID/Group ID mappings to be written.
+	if sys.UidMappings != nil || sys.GidMappings != nil {
+		if _, _, err1 = RawSyscall(SYS_CLOSE, uintptr(p[1]), 0, 0); err1 != 0 {
+			goto childerror
+		}
+		r1, _, err1 = RawSyscall(SYS_READ, uintptr(p[0]), uintptr(unsafe.Pointer(&err2)), unsafe.Sizeof(err2))
+		if err1 != 0 {
+			goto childerror
+		}
+		if r1 != unsafe.Sizeof(err2) {
+			err1 = EINVAL
+			goto childerror
+		}
+		if err2 != 0 {
+			err1 = err2
+			goto childerror
+		}
+	}
+
+	// Parent death signal
+	if sys.Pdeathsig != 0 {
+		_, _, err1 = RawSyscall6(SYS_PRCTL, PR_SET_PDEATHSIG, uintptr(sys.Pdeathsig), 0, 0, 0, 0)
+		if err1 != 0 {
+			goto childerror
+		}
+
+		// Signal self if parent is already dead. This might cause a
+		// duplicate signal in rare cases, but it won't matter when
+		// using SIGKILL.
+		r1, _, _ = RawSyscall(SYS_GETPPID, 0, 0, 0)
+		if r1 == 1 {
+			pid, _, _ := RawSyscall(SYS_GETPID, 0, 0, 0)
+			_, _, err1 := RawSyscall(SYS_KILL, pid, uintptr(sys.Pdeathsig), 0)
+			if err1 != 0 {
+				goto childerror
+			}
+		}
+	}
+
+	// Enable tracing if requested.
+	if sys.Ptrace {
+		_, _, err1 = RawSyscall(SYS_PTRACE, uintptr(PTRACE_TRACEME), 0, 0)
+		if err1 != 0 {
+			goto childerror
+		}
+	}
+
+	// Session ID
+	if sys.Setsid {
+		_, _, err1 = RawSyscall(SYS_SETSID, 0, 0, 0)
+		if err1 != 0 {
+			goto childerror
+		}
+	}
+
+	// Set process group
+	if sys.Setpgid {
+		_, _, err1 = RawSyscall(SYS_SETPGID, 0, 0, 0)
+		if err1 != 0 {
+			goto childerror
+		}
+	}
+
+	// Chroot
+	if chroot != nil {
+		_, _, err1 = RawSyscall(SYS_CHROOT, uintptr(unsafe.Pointer(chroot)), 0, 0)
+		if err1 != 0 {
+			goto childerror
+		}
+	}
+
+	// User and groups
+	if cred := sys.Credential; cred != nil {
+		ngroups := uintptr(len(cred.Groups))
+		var groups unsafe.Pointer
+		if ngroups > 0 {
+			groups = unsafe.Pointer(&cred.Groups[0])
+		}
+		_, _, err1 = RawSyscall(SYS_SETGROUPS, ngroups, uintptr(groups), 0)
+		if err1 != 0 {
+			goto childerror
+		}
+		_, _, err1 = RawSyscall(SYS_SETGID, uintptr(cred.Gid), 0, 0)
+		if err1 != 0 {
+			goto childerror
+		}
+		_, _, err1 = RawSyscall(SYS_SETUID, uintptr(cred.Uid), 0, 0)
+		if err1 != 0 {
+			goto childerror
+		}
+	}
+
+	// Chdir
+	if dir != nil {
+		_, _, err1 = RawSyscall(SYS_CHDIR, uintptr(unsafe.Pointer(dir)), 0, 0)
+		if err1 != 0 {
+			goto childerror
+		}
+	}
+
+	// Pass 1: look for fd[i] < i and move those up above len(fd)
+	// so that pass 2 won't stomp on an fd it needs later.
+	if pipe < nextfd {
+		_, _, err1 = RawSyscall(SYS_DUP2, uintptr(pipe), uintptr(nextfd), 0)
+		if err1 != 0 {
+			goto childerror
+		}
+		RawSyscall(SYS_FCNTL, uintptr(nextfd), F_SETFD, FD_CLOEXEC)
+		pipe = nextfd
+		nextfd++
+	}
+	for i = 0; i < len(fd); i++ {
+		if fd[i] >= 0 && fd[i] < int(i) {
+			_, _, err1 = RawSyscall(SYS_DUP2, uintptr(fd[i]), uintptr(nextfd), 0)
+			if err1 != 0 {
+				goto childerror
+			}
+			RawSyscall(SYS_FCNTL, uintptr(nextfd), F_SETFD, FD_CLOEXEC)
+			fd[i] = nextfd
+			nextfd++
+			if nextfd == pipe { // don't stomp on pipe
+				nextfd++
+			}
+		}
+	}
+
+	// Pass 2: dup fd[i] down onto i.
+	for i = 0; i < len(fd); i++ {
+		if fd[i] == -1 {
+			RawSyscall(SYS_CLOSE, uintptr(i), 0, 0)
+			continue
+		}
+		if fd[i] == int(i) {
+			// dup2(i, i) won't clear close-on-exec flag on Linux,
+			// probably not elsewhere either.
+			_, _, err1 = RawSyscall(SYS_FCNTL, uintptr(fd[i]), F_SETFD, 0)
+			if err1 != 0 {
+				goto childerror
+			}
+			continue
+		}
+		// The new fd is created NOT close-on-exec,
+		// which is exactly what we want.
+		_, _, err1 = RawSyscall(SYS_DUP2, uintptr(fd[i]), uintptr(i), 0)
+		if err1 != 0 {
+			goto childerror
+		}
+	}
+
+	// By convention, we don't close-on-exec the fds we are
+	// started with, so if len(fd) < 3, close 0, 1, 2 as needed.
+	// Programs that know they inherit fds >= 3 will need
+	// to set them close-on-exec.
+	for i = len(fd); i < 3; i++ {
+		RawSyscall(SYS_CLOSE, uintptr(i), 0, 0)
+	}
+
+	// Detach fd 0 from tty
+	if sys.Noctty {
+		_, _, err1 = RawSyscall(SYS_IOCTL, 0, uintptr(TIOCNOTTY), 0)
+		if err1 != 0 {
+			goto childerror
+		}
+	}
+
+	// Set the controlling TTY to Ctty
+	if sys.Setctty && sys.Ctty >= 0 {
+		_, _, err1 = RawSyscall(SYS_IOCTL, uintptr(sys.Ctty), uintptr(TIOCSCTTY), 0)
+		if err1 != 0 {
+			goto childerror
+		}
+	}
+
+	// Time to exec.
+	_, _, err1 = RawSyscall(SYS_EXECVE,
+		uintptr(unsafe.Pointer(argv0)),
+		uintptr(unsafe.Pointer(&argv[0])),
+		uintptr(unsafe.Pointer(&envv[0])))
+
+childerror:
+	// send error code on pipe
+	RawSyscall(SYS_WRITE, uintptr(pipe), uintptr(unsafe.Pointer(&err1)), unsafe.Sizeof(err1))
+	for {
+		RawSyscall(SYS_EXIT, 253, 0, 0)
+	}
+}
+
+// Try to open a pipe with O_CLOEXEC set on both file descriptors.
+func forkExecPipe(p []int) (err error) {
+	err = Pipe2(p, O_CLOEXEC)
+	// pipe2 was added in 2.6.27 and our minimum requirement is 2.6.23, so it
+	// might not be implemented.
+	if err == ENOSYS {
+		if err = Pipe(p); err != nil {
+			return
+		}
+		if _, err = fcntl(p[0], F_SETFD, FD_CLOEXEC); err != nil {
+			return
+		}
+		_, err = fcntl(p[1], F_SETFD, FD_CLOEXEC)
+	}
+	return
+}
+
+// writeIDMappings writes the user namespace User ID or Group ID mappings to the specified path.
+func writeIDMappings(path string, idMap []SysProcIDMap) error {
+	fd, err := Open(path, O_RDWR, 0)
+	if err != nil {
+		return err
+	}
+
+	data := ""
+	for _, im := range idMap {
+		data = data + itoa(im.ContainerID) + " " + itoa(im.HostID) + " " + itoa(im.Size) + "\n"
+	}
+
+	bytes, err := ByteSliceFromString(data)
+	if err != nil {
+		Close(fd)
+		return err
+	}
+
+	if _, err := Write(fd, bytes); err != nil {
+		Close(fd)
+		return err
+	}
+
+	if err := Close(fd); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+// writeUidGidMappings writes User ID and Group ID mappings for user namespaces
+// for a process and it is called from the parent process.
+func writeUidGidMappings(pid int, sys *SysProcAttr) error {
+	if sys.UidMappings != nil {
+		uidf := "/proc/" + itoa(pid) + "/uid_map"
+		if err := writeIDMappings(uidf, sys.UidMappings); err != nil {
+			return err
+		}
+	}
+
+	if sys.GidMappings != nil {
+		gidf := "/proc/" + itoa(pid) + "/gid_map"
+		if err := writeIDMappings(gidf, sys.GidMappings); err != nil {
+			return err
+		}
+	}
+
+	return nil
+}
diff --git a/src/pkg/syscall/exec_plan9.go b/src/syscall/exec_plan9.go
similarity index 100%
rename from src/pkg/syscall/exec_plan9.go
rename to src/syscall/exec_plan9.go
diff --git a/src/pkg/syscall/exec_solaris.go b/src/syscall/exec_solaris.go
similarity index 100%
rename from src/pkg/syscall/exec_solaris.go
rename to src/syscall/exec_solaris.go
diff --git a/src/pkg/syscall/exec_unix.go b/src/syscall/exec_unix.go
similarity index 100%
rename from src/pkg/syscall/exec_unix.go
rename to src/syscall/exec_unix.go
diff --git a/src/syscall/exec_windows.go b/src/syscall/exec_windows.go
new file mode 100644
index 0000000..936aeb5
--- /dev/null
+++ b/src/syscall/exec_windows.go
@@ -0,0 +1,340 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Fork, exec, wait, etc.
+
+package syscall
+
+import (
+	"sync"
+	"unicode/utf16"
+	"unsafe"
+)
+
+var ForkLock sync.RWMutex
+
+// EscapeArg rewrites command line argument s as prescribed
+// in http://msdn.microsoft.com/en-us/library/ms880421.
+// This function returns "" (2 double quotes) if s is empty.
+// Alternatively, these transformations are done:
+// - every back slash (\) is doubled, but only if immediately
+//   followed by double quote (");
+// - every double quote (") is escaped by back slash (\);
+// - finally, s is wrapped with double quotes (arg -> "arg"),
+//   but only if there is space or tab inside s.
+func EscapeArg(s string) string {
+	if len(s) == 0 {
+		return "\"\""
+	}
+	n := len(s)
+	hasSpace := false
+	for i := 0; i < len(s); i++ {
+		switch s[i] {
+		case '"', '\\':
+			n++
+		case ' ', '\t':
+			hasSpace = true
+		}
+	}
+	if hasSpace {
+		n += 2
+	}
+	if n == len(s) {
+		return s
+	}
+
+	qs := make([]byte, n)
+	j := 0
+	if hasSpace {
+		qs[j] = '"'
+		j++
+	}
+	slashes := 0
+	for i := 0; i < len(s); i++ {
+		switch s[i] {
+		default:
+			slashes = 0
+			qs[j] = s[i]
+		case '\\':
+			slashes++
+			qs[j] = s[i]
+		case '"':
+			for ; slashes > 0; slashes-- {
+				qs[j] = '\\'
+				j++
+			}
+			qs[j] = '\\'
+			j++
+			qs[j] = s[i]
+		}
+		j++
+	}
+	if hasSpace {
+		for ; slashes > 0; slashes-- {
+			qs[j] = '\\'
+			j++
+		}
+		qs[j] = '"'
+		j++
+	}
+	return string(qs[:j])
+}
+
+// makeCmdLine builds a command line out of args by escaping "special"
+// characters and joining the arguments with spaces.
+func makeCmdLine(args []string) string {
+	var s string
+	for _, v := range args {
+		if s != "" {
+			s += " "
+		}
+		s += EscapeArg(v)
+	}
+	return s
+}
+
+// createEnvBlock converts an array of environment strings into
+// the representation required by CreateProcess: a sequence of NUL
+// terminated strings followed by a nil.
+// Last bytes are two UCS-2 NULs, or four NUL bytes.
+func createEnvBlock(envv []string) *uint16 {
+	if len(envv) == 0 {
+		return &utf16.Encode([]rune("\x00\x00"))[0]
+	}
+	length := 0
+	for _, s := range envv {
+		length += len(s) + 1
+	}
+	length += 1
+
+	b := make([]byte, length)
+	i := 0
+	for _, s := range envv {
+		l := len(s)
+		copy(b[i:i+l], []byte(s))
+		copy(b[i+l:i+l+1], []byte{0})
+		i = i + l + 1
+	}
+	copy(b[i:i+1], []byte{0})
+
+	return &utf16.Encode([]rune(string(b)))[0]
+}
+
+func CloseOnExec(fd Handle) {
+	SetHandleInformation(Handle(fd), HANDLE_FLAG_INHERIT, 0)
+}
+
+func SetNonblock(fd Handle, nonblocking bool) (err error) {
+	return nil
+}
+
+// FullPath retrieves the full path of the specified file.
+func FullPath(name string) (path string, err error) {
+	p, err := UTF16PtrFromString(name)
+	if err != nil {
+		return "", err
+	}
+	buf := make([]uint16, 100)
+	n, err := GetFullPathName(p, uint32(len(buf)), &buf[0], nil)
+	if err != nil {
+		return "", err
+	}
+	if n > uint32(len(buf)) {
+		// Windows is asking for bigger buffer.
+		buf = make([]uint16, n)
+		n, err = GetFullPathName(p, uint32(len(buf)), &buf[0], nil)
+		if err != nil {
+			return "", err
+		}
+		if n > uint32(len(buf)) {
+			return "", EINVAL
+		}
+	}
+	return UTF16ToString(buf[:n]), nil
+}
+
+func isSlash(c uint8) bool {
+	return c == '\\' || c == '/'
+}
+
+func normalizeDir(dir string) (name string, err error) {
+	ndir, err := FullPath(dir)
+	if err != nil {
+		return "", err
+	}
+	if len(ndir) > 2 && isSlash(ndir[0]) && isSlash(ndir[1]) {
+		// dir cannot have \\server\share\path form
+		return "", EINVAL
+	}
+	return ndir, nil
+}
+
+func volToUpper(ch int) int {
+	if 'a' <= ch && ch <= 'z' {
+		ch += 'A' - 'a'
+	}
+	return ch
+}
+
+func joinExeDirAndFName(dir, p string) (name string, err error) {
+	if len(p) == 0 {
+		return "", EINVAL
+	}
+	if len(p) > 2 && isSlash(p[0]) && isSlash(p[1]) {
+		// \\server\share\path form
+		return p, nil
+	}
+	if len(p) > 1 && p[1] == ':' {
+		// has drive letter
+		if len(p) == 2 {
+			return "", EINVAL
+		}
+		if isSlash(p[2]) {
+			return p, nil
+		} else {
+			d, err := normalizeDir(dir)
+			if err != nil {
+				return "", err
+			}
+			if volToUpper(int(p[0])) == volToUpper(int(d[0])) {
+				return FullPath(d + "\\" + p[2:])
+			} else {
+				return FullPath(p)
+			}
+		}
+	} else {
+		// no drive letter
+		d, err := normalizeDir(dir)
+		if err != nil {
+			return "", err
+		}
+		if isSlash(p[0]) {
+			return FullPath(d[:2] + p)
+		} else {
+			return FullPath(d + "\\" + p)
+		}
+	}
+	// we shouldn't be here
+	return "", EINVAL
+}
+
+type ProcAttr struct {
+	Dir   string
+	Env   []string
+	Files []uintptr
+	Sys   *SysProcAttr
+}
+
+type SysProcAttr struct {
+	HideWindow    bool
+	CmdLine       string // used if non-empty, else the windows command line is built by escaping the arguments passed to StartProcess
+	CreationFlags uint32
+}
+
+var zeroProcAttr ProcAttr
+var zeroSysProcAttr SysProcAttr
+
+func StartProcess(argv0 string, argv []string, attr *ProcAttr) (pid int, handle uintptr, err error) {
+	if len(argv0) == 0 {
+		return 0, 0, EWINDOWS
+	}
+	if attr == nil {
+		attr = &zeroProcAttr
+	}
+	sys := attr.Sys
+	if sys == nil {
+		sys = &zeroSysProcAttr
+	}
+
+	if len(attr.Files) > 3 {
+		return 0, 0, EWINDOWS
+	}
+
+	if len(attr.Dir) != 0 {
+		// StartProcess assumes that argv0 is relative to attr.Dir,
+		// because it implies Chdir(attr.Dir) before executing argv0.
+		// Windows CreateProcess assumes the opposite: it looks for
+		// argv0 relative to the current directory, and, only once the new
+		// process is started, it does Chdir(attr.Dir). We are adjusting
+		// for that difference here by making argv0 absolute.
+		var err error
+		argv0, err = joinExeDirAndFName(attr.Dir, argv0)
+		if err != nil {
+			return 0, 0, err
+		}
+	}
+	argv0p, err := UTF16PtrFromString(argv0)
+	if err != nil {
+		return 0, 0, err
+	}
+
+	var cmdline string
+	// Windows CreateProcess takes the command line as a single string:
+	// use attr.CmdLine if set, else build the command line by escaping
+	// and joining each argument with spaces
+	if sys.CmdLine != "" {
+		cmdline = sys.CmdLine
+	} else {
+		cmdline = makeCmdLine(argv)
+	}
+
+	var argvp *uint16
+	if len(cmdline) != 0 {
+		argvp, err = UTF16PtrFromString(cmdline)
+		if err != nil {
+			return 0, 0, err
+		}
+	}
+
+	var dirp *uint16
+	if len(attr.Dir) != 0 {
+		dirp, err = UTF16PtrFromString(attr.Dir)
+		if err != nil {
+			return 0, 0, err
+		}
+	}
+
+	// Acquire the fork lock so that no other threads
+	// create new fds that are not yet close-on-exec
+	// before we fork.
+	ForkLock.Lock()
+	defer ForkLock.Unlock()
+
+	p, _ := GetCurrentProcess()
+	fd := make([]Handle, len(attr.Files))
+	for i := range attr.Files {
+		if attr.Files[i] > 0 {
+			err := DuplicateHandle(p, Handle(attr.Files[i]), p, &fd[i], 0, true, DUPLICATE_SAME_ACCESS)
+			if err != nil {
+				return 0, 0, err
+			}
+			defer CloseHandle(Handle(fd[i]))
+		}
+	}
+	si := new(StartupInfo)
+	si.Cb = uint32(unsafe.Sizeof(*si))
+	si.Flags = STARTF_USESTDHANDLES
+	if sys.HideWindow {
+		si.Flags |= STARTF_USESHOWWINDOW
+		si.ShowWindow = SW_HIDE
+	}
+	si.StdInput = fd[0]
+	si.StdOutput = fd[1]
+	si.StdErr = fd[2]
+
+	pi := new(ProcessInformation)
+
+	flags := sys.CreationFlags | CREATE_UNICODE_ENVIRONMENT
+	err = CreateProcess(argv0p, argvp, nil, nil, true, flags, createEnvBlock(attr.Env), dirp, si, pi)
+	if err != nil {
+		return 0, 0, err
+	}
+	defer CloseHandle(Handle(pi.Thread))
+
+	return int(pi.ProcessId), uintptr(pi.Process), nil
+}
+
+func Exec(argv0 string, argv []string, envv []string) (err error) {
+	return EWINDOWS
+}
diff --git a/src/syscall/export_test.go b/src/syscall/export_test.go
new file mode 100644
index 0000000..c977462
--- /dev/null
+++ b/src/syscall/export_test.go
@@ -0,0 +1,7 @@
+// Copyright 2014 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package syscall
+
+var Itoa = itoa
diff --git a/src/pkg/syscall/fd_nacl.go b/src/syscall/fd_nacl.go
similarity index 100%
rename from src/pkg/syscall/fd_nacl.go
rename to src/syscall/fd_nacl.go
diff --git a/src/pkg/syscall/flock.go b/src/syscall/flock.go
similarity index 100%
rename from src/pkg/syscall/flock.go
rename to src/syscall/flock.go
diff --git a/src/pkg/syscall/flock_linux_32bit.go b/src/syscall/flock_linux_32bit.go
similarity index 100%
rename from src/pkg/syscall/flock_linux_32bit.go
rename to src/syscall/flock_linux_32bit.go
diff --git a/src/syscall/fs_nacl.go b/src/syscall/fs_nacl.go
new file mode 100644
index 0000000..6e6ce2a
--- /dev/null
+++ b/src/syscall/fs_nacl.go
@@ -0,0 +1,838 @@
+// Copyright 2013 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// A simulated Unix-like file system for use within NaCl.
+//
+// The simulation is not particularly tied to NaCl other than the reuse
+// of NaCl's definition for the Stat_t structure.
+//
+// The file system need never be written to disk, so it is represented as
+// in-memory Go data structures, never in a serialized form.
+//
+// TODO: Perhaps support symlinks, although they muck everything up.
+
+package syscall
+
+import (
+	"sync"
+	"unsafe"
+)
+
+// Provided by package runtime.
+func now() (sec int64, nsec int32)
+
+// An fsys is a file system.
+// Since there is no I/O (everything is in memory),
+// the global lock mu protects the whole file system state,
+// and that's okay.
+type fsys struct {
+	mu   sync.Mutex
+	root *inode                    // root directory
+	cwd  *inode                    // process current directory
+	inum uint64                    // number of inodes created
+	dev  []func() (devFile, error) // table for opening devices
+}
+
+// A devFile is the implementation required of device files
+// like /dev/null or /dev/random.
+type devFile interface {
+	pread([]byte, int64) (int, error)
+	pwrite([]byte, int64) (int, error)
+}
+
+// An inode is a (possibly special) file in the file system.
+type inode struct {
+	Stat_t
+	data []byte
+	dir  []dirent
+}
+
+// A dirent describes a single directory entry.
+type dirent struct {
+	name  string
+	inode *inode
+}
+
+// An fsysFile is the fileImpl implementation backed by the file system.
+type fsysFile struct {
+	defaultFileImpl
+	fsys     *fsys
+	inode    *inode
+	openmode int
+	offset   int64
+	dev      devFile
+}
+
+// newFsys creates a new file system.
+func newFsys() *fsys {
+	fs := &fsys{}
+	fs.mu.Lock()
+	defer fs.mu.Unlock()
+	ip := fs.newInode()
+	ip.Mode = 0555 | S_IFDIR
+	fs.dirlink(ip, ".", ip)
+	fs.dirlink(ip, "..", ip)
+	fs.cwd = ip
+	fs.root = ip
+	return fs
+}
+
+var fs = newFsys()
+var fsinit = func() {}
+
+func init() {
+	// do not trigger loading of zipped file system here
+	oldFsinit := fsinit
+	defer func() { fsinit = oldFsinit }()
+	fsinit = func() {}
+	Mkdir("/dev", 0555)
+	Mkdir("/tmp", 0777)
+	mkdev("/dev/null", 0666, openNull)
+	mkdev("/dev/random", 0444, openRandom)
+	mkdev("/dev/urandom", 0444, openRandom)
+	mkdev("/dev/zero", 0666, openZero)
+	chdirEnv()
+}
+
+func chdirEnv() {
+	pwd, ok := Getenv("NACLPWD")
+	if ok {
+		chdir(pwd)
+	}
+}
+
+// Except where indicated otherwise, unexported methods on fsys
+// expect fs.mu to have been locked by the caller.
+
+// newInode creates a new inode.
+func (fs *fsys) newInode() *inode {
+	fs.inum++
+	ip := &inode{
+		Stat_t: Stat_t{
+			Ino:     fs.inum,
+			Blksize: 512,
+		},
+	}
+	return ip
+}
+
+// atime sets ip.Atime to the current time.
+func (fs *fsys) atime(ip *inode) {
+	sec, nsec := now()
+	ip.Atime, ip.AtimeNsec = sec, int64(nsec)
+}
+
+// mtime sets ip.Mtime to the current time.
+func (fs *fsys) mtime(ip *inode) {
+	sec, nsec := now()
+	ip.Mtime, ip.MtimeNsec = sec, int64(nsec)
+}
+
+// dirlookup looks for an entry in the directory dp with the given name.
+// It returns the directory entry and its index within the directory.
+func (fs *fsys) dirlookup(dp *inode, name string) (de *dirent, index int, err error) {
+	fs.atime(dp)
+	for i := range dp.dir {
+		de := &dp.dir[i]
+		if de.name == name {
+			fs.atime(de.inode)
+			return de, i, nil
+		}
+	}
+	return nil, 0, ENOENT
+}
+
+// dirlink adds to the directory dp an entry for name pointing at the inode ip.
+// If dp already contains an entry for name, that entry is overwritten.
+func (fs *fsys) dirlink(dp *inode, name string, ip *inode) {
+	fs.mtime(dp)
+	fs.atime(ip)
+	ip.Nlink++
+	for i := range dp.dir {
+		if dp.dir[i].name == name {
+			dp.dir[i] = dirent{name, ip}
+			return
+		}
+	}
+	dp.dir = append(dp.dir, dirent{name, ip})
+	dp.dirSize()
+}
+
+func (dp *inode) dirSize() {
+	dp.Size = int64(len(dp.dir)) * (8 + 8 + 2 + 256) // Dirent
+}
+
+// skipelem splits path into the first element and the remainder.
+// the returned first element contains no slashes, and the returned
+// remainder does not begin with a slash.
+func skipelem(path string) (elem, rest string) {
+	for len(path) > 0 && path[0] == '/' {
+		path = path[1:]
+	}
+	if len(path) == 0 {
+		return "", ""
+	}
+	i := 0
+	for i < len(path) && path[i] != '/' {
+		i++
+	}
+	elem, path = path[:i], path[i:]
+	for len(path) > 0 && path[0] == '/' {
+		path = path[1:]
+	}
+	return elem, path
+}
+
+// namei translates a file system path name into an inode.
+// If parent is false, the returned ip corresponds to the given name, and elem is the empty string.
+// If parent is true, the walk stops at the next-to-last element in the name,
+// so that ip is the parent directory and elem is the final element in the path.
+func (fs *fsys) namei(path string, parent bool) (ip *inode, elem string, err error) {
+	// Reject NUL in name.
+	for i := 0; i < len(path); i++ {
+		if path[i] == '\x00' {
+			return nil, "", EINVAL
+		}
+	}
+
+	// Reject empty name.
+	if path == "" {
+		return nil, "", EINVAL
+	}
+
+	if path[0] == '/' {
+		ip = fs.root
+	} else {
+		ip = fs.cwd
+	}
+
+	for len(path) > 0 && path[len(path)-1] == '/' {
+		path = path[:len(path)-1]
+	}
+
+	for {
+		elem, rest := skipelem(path)
+		if elem == "" {
+			if parent && ip.Mode&S_IFMT == S_IFDIR {
+				return ip, ".", nil
+			}
+			break
+		}
+		if ip.Mode&S_IFMT != S_IFDIR {
+			return nil, "", ENOTDIR
+		}
+		if len(elem) >= 256 {
+			return nil, "", ENAMETOOLONG
+		}
+		if parent && rest == "" {
+			// Stop one level early.
+			return ip, elem, nil
+		}
+		de, _, err := fs.dirlookup(ip, elem)
+		if err != nil {
+			return nil, "", err
+		}
+		ip = de.inode
+		path = rest
+	}
+	if parent {
+		return nil, "", ENOTDIR
+	}
+	return ip, "", nil
+}
+
+// open opens or creates a file with the given name, open mode,
+// and permission mode bits.
+func (fs *fsys) open(name string, openmode int, mode uint32) (fileImpl, error) {
+	dp, elem, err := fs.namei(name, true)
+	if err != nil {
+		return nil, err
+	}
+	var (
+		ip  *inode
+		dev devFile
+	)
+	de, _, err := fs.dirlookup(dp, elem)
+	if err != nil {
+		if openmode&O_CREATE == 0 {
+			return nil, err
+		}
+		ip = fs.newInode()
+		ip.Mode = mode
+		fs.dirlink(dp, elem, ip)
+		if ip.Mode&S_IFMT == S_IFDIR {
+			fs.dirlink(ip, ".", ip)
+			fs.dirlink(ip, "..", dp)
+		}
+	} else {
+		ip = de.inode
+		if openmode&(O_CREATE|O_EXCL) == O_CREATE|O_EXCL {
+			return nil, EEXIST
+		}
+		if openmode&O_TRUNC != 0 {
+			if ip.Mode&S_IFMT == S_IFDIR {
+				return nil, EISDIR
+			}
+			ip.data = nil
+		}
+		if ip.Mode&S_IFMT == S_IFCHR {
+			if ip.Rdev < 0 || ip.Rdev >= int64(len(fs.dev)) || fs.dev[ip.Rdev] == nil {
+				return nil, ENODEV
+			}
+			dev, err = fs.dev[ip.Rdev]()
+			if err != nil {
+				return nil, err
+			}
+		}
+	}
+
+	switch openmode & O_ACCMODE {
+	case O_WRONLY, O_RDWR:
+		if ip.Mode&S_IFMT == S_IFDIR {
+			return nil, EISDIR
+		}
+	}
+
+	switch ip.Mode & S_IFMT {
+	case S_IFDIR:
+		if openmode&O_ACCMODE != O_RDONLY {
+			return nil, EISDIR
+		}
+
+	case S_IFREG:
+		// ok
+
+	case S_IFCHR:
+		// handled above
+
+	default:
+		// TODO: some kind of special file
+		return nil, EPERM
+	}
+
+	f := &fsysFile{
+		fsys:     fs,
+		inode:    ip,
+		openmode: openmode,
+		dev:      dev,
+	}
+	if openmode&O_APPEND != 0 {
+		f.offset = ip.Size
+	}
+	return f, nil
+}
+
+// fsysFile methods to implement fileImpl.
+
+func (f *fsysFile) stat(st *Stat_t) error {
+	f.fsys.mu.Lock()
+	defer f.fsys.mu.Unlock()
+	*st = f.inode.Stat_t
+	return nil
+}
+
+func (f *fsysFile) read(b []byte) (int, error) {
+	f.fsys.mu.Lock()
+	defer f.fsys.mu.Unlock()
+	n, err := f.preadLocked(b, f.offset)
+	f.offset += int64(n)
+	return n, err
+}
+
+func ReadDirent(fd int, buf []byte) (int, error) {
+	f, err := fdToFsysFile(fd)
+	if err != nil {
+		return 0, err
+	}
+	f.fsys.mu.Lock()
+	defer f.fsys.mu.Unlock()
+	if f.inode.Mode&S_IFMT != S_IFDIR {
+		return 0, EINVAL
+	}
+	n, err := f.preadLocked(buf, f.offset)
+	f.offset += int64(n)
+	return n, err
+}
+
+func (f *fsysFile) write(b []byte) (int, error) {
+	f.fsys.mu.Lock()
+	defer f.fsys.mu.Unlock()
+	n, err := f.pwriteLocked(b, f.offset)
+	f.offset += int64(n)
+	return n, err
+}
+
+func (f *fsysFile) seek(offset int64, whence int) (int64, error) {
+	f.fsys.mu.Lock()
+	defer f.fsys.mu.Unlock()
+	switch whence {
+	case 1:
+		offset += f.offset
+	case 2:
+		offset += f.inode.Size
+	}
+	if offset < 0 {
+		return 0, EINVAL
+	}
+	if offset > f.inode.Size {
+		return 0, EINVAL
+	}
+	f.offset = offset
+	return offset, nil
+}
+
+func (f *fsysFile) pread(b []byte, offset int64) (int, error) {
+	f.fsys.mu.Lock()
+	defer f.fsys.mu.Unlock()
+	return f.preadLocked(b, offset)
+}
+
+func (f *fsysFile) pwrite(b []byte, offset int64) (int, error) {
+	f.fsys.mu.Lock()
+	defer f.fsys.mu.Unlock()
+	return f.pwriteLocked(b, offset)
+}
+
+func (f *fsysFile) preadLocked(b []byte, offset int64) (int, error) {
+	if f.openmode&O_ACCMODE == O_WRONLY {
+		return 0, EINVAL
+	}
+	if offset < 0 {
+		return 0, EINVAL
+	}
+	if f.dev != nil {
+		f.fsys.atime(f.inode)
+		f.fsys.mu.Unlock()
+		defer f.fsys.mu.Lock()
+		return f.dev.pread(b, offset)
+	}
+	if offset > f.inode.Size {
+		return 0, nil
+	}
+	if int64(len(b)) > f.inode.Size-offset {
+		b = b[:f.inode.Size-offset]
+	}
+
+	if f.inode.Mode&S_IFMT == S_IFDIR {
+		if offset%direntSize != 0 || len(b) != 0 && len(b) < direntSize {
+			return 0, EINVAL
+		}
+		fs.atime(f.inode)
+		n := 0
+		for len(b) >= direntSize {
+			src := f.inode.dir[int(offset/direntSize)]
+			dst := (*Dirent)(unsafe.Pointer(&b[0]))
+			dst.Ino = int64(src.inode.Ino)
+			dst.Off = offset
+			dst.Reclen = direntSize
+			for i := range dst.Name {
+				dst.Name[i] = 0
+			}
+			copy(dst.Name[:], src.name)
+			n += direntSize
+			offset += direntSize
+			b = b[direntSize:]
+		}
+		return n, nil
+	}
+
+	fs.atime(f.inode)
+	n := copy(b, f.inode.data[offset:])
+	return n, nil
+}
+
+func (f *fsysFile) pwriteLocked(b []byte, offset int64) (int, error) {
+	if f.openmode&O_ACCMODE == O_RDONLY {
+		return 0, EINVAL
+	}
+	if offset < 0 {
+		return 0, EINVAL
+	}
+	if f.dev != nil {
+		f.fsys.atime(f.inode)
+		f.fsys.mu.Unlock()
+		defer f.fsys.mu.Lock()
+		return f.dev.pwrite(b, offset)
+	}
+	if offset > f.inode.Size {
+		return 0, EINVAL
+	}
+	f.fsys.mtime(f.inode)
+	n := copy(f.inode.data[offset:], b)
+	if n < len(b) {
+		f.inode.data = append(f.inode.data, b[n:]...)
+		f.inode.Size = int64(len(f.inode.data))
+	}
+	return len(b), nil
+}
+
+// Standard Unix system calls.
+
+func Open(path string, openmode int, perm uint32) (fd int, err error) {
+	fsinit()
+	fs.mu.Lock()
+	defer fs.mu.Unlock()
+	f, err := fs.open(path, openmode, perm&0777|S_IFREG)
+	if err != nil {
+		return -1, err
+	}
+	return newFD(f), nil
+}
+
+func Mkdir(path string, perm uint32) error {
+	fs.mu.Lock()
+	defer fs.mu.Unlock()
+	_, err := fs.open(path, O_CREATE|O_EXCL, perm&0777|S_IFDIR)
+	return err
+}
+
+func Getcwd(buf []byte) (n int, err error) {
+	// Force package os to default to the old algorithm using .. and directory reads.
+	return 0, ENOSYS
+}
+
+func Stat(path string, st *Stat_t) error {
+	fsinit()
+	fs.mu.Lock()
+	defer fs.mu.Unlock()
+	ip, _, err := fs.namei(path, false)
+	if err != nil {
+		return err
+	}
+	*st = ip.Stat_t
+	return nil
+}
+
+func Lstat(path string, st *Stat_t) error {
+	return Stat(path, st)
+}
+
+func unlink(path string, isdir bool) error {
+	fsinit()
+	fs.mu.Lock()
+	defer fs.mu.Unlock()
+	dp, elem, err := fs.namei(path, true)
+	if err != nil {
+		return err
+	}
+	if elem == "." || elem == ".." {
+		return EINVAL
+	}
+	de, _, err := fs.dirlookup(dp, elem)
+	if err != nil {
+		return err
+	}
+	if isdir {
+		if de.inode.Mode&S_IFMT != S_IFDIR {
+			return ENOTDIR
+		}
+		if len(de.inode.dir) != 2 {
+			return ENOTEMPTY
+		}
+	} else {
+		if de.inode.Mode&S_IFMT == S_IFDIR {
+			return EISDIR
+		}
+	}
+	de.inode.Nlink--
+	*de = dp.dir[len(dp.dir)-1]
+	dp.dir = dp.dir[:len(dp.dir)-1]
+	dp.dirSize()
+	return nil
+}
+
+func Unlink(path string) error {
+	return unlink(path, false)
+}
+
+func Rmdir(path string) error {
+	return unlink(path, true)
+}
+
+func Chmod(path string, mode uint32) error {
+	fsinit()
+	fs.mu.Lock()
+	defer fs.mu.Unlock()
+	ip, _, err := fs.namei(path, false)
+	if err != nil {
+		return err
+	}
+	ip.Mode = ip.Mode&^0777 | mode&0777
+	return nil
+}
+
+func Fchmod(fd int, mode uint32) error {
+	f, err := fdToFsysFile(fd)
+	if err != nil {
+		return err
+	}
+	f.fsys.mu.Lock()
+	defer f.fsys.mu.Unlock()
+	f.inode.Mode = f.inode.Mode&^0777 | mode&0777
+	return nil
+}
+
+func Chown(path string, uid, gid int) error {
+	fsinit()
+	fs.mu.Lock()
+	defer fs.mu.Unlock()
+	ip, _, err := fs.namei(path, false)
+	if err != nil {
+		return err
+	}
+	ip.Uid = uint32(uid)
+	ip.Gid = uint32(gid)
+	return nil
+}
+
+func Fchown(fd int, uid, gid int) error {
+	fs.mu.Lock()
+	defer fs.mu.Unlock()
+	f, err := fdToFsysFile(fd)
+	if err != nil {
+		return err
+	}
+	f.fsys.mu.Lock()
+	defer f.fsys.mu.Unlock()
+	f.inode.Uid = uint32(uid)
+	f.inode.Gid = uint32(gid)
+	return nil
+}
+
+func Lchown(path string, uid, gid int) error {
+	return Chown(path, uid, gid)
+}
+
+func UtimesNano(path string, ts []Timespec) error {
+	if len(ts) != 2 {
+		return EINVAL
+	}
+	fsinit()
+	fs.mu.Lock()
+	defer fs.mu.Unlock()
+	ip, _, err := fs.namei(path, false)
+	if err != nil {
+		return err
+	}
+	ip.Atime = ts[0].Sec
+	ip.AtimeNsec = int64(ts[0].Nsec)
+	ip.Mtime = ts[1].Sec
+	ip.MtimeNsec = int64(ts[1].Nsec)
+	return nil
+}
+
+func Link(path, link string) error {
+	fsinit()
+	ip, _, err := fs.namei(path, false)
+	if err != nil {
+		return err
+	}
+	dp, elem, err := fs.namei(link, true)
+	if err != nil {
+		return err
+	}
+	if ip.Mode&S_IFMT == S_IFDIR {
+		return EPERM
+	}
+	fs.dirlink(dp, elem, ip)
+	return nil
+}
+
+func Rename(from, to string) error {
+	fsinit()
+	fdp, felem, err := fs.namei(from, true)
+	if err != nil {
+		return err
+	}
+	fde, _, err := fs.dirlookup(fdp, felem)
+	if err != nil {
+		return err
+	}
+	tdp, telem, err := fs.namei(to, true)
+	if err != nil {
+		return err
+	}
+	fs.dirlink(tdp, telem, fde.inode)
+	fde.inode.Nlink--
+	*fde = fdp.dir[len(fdp.dir)-1]
+	fdp.dir = fdp.dir[:len(fdp.dir)-1]
+	fdp.dirSize()
+	return nil
+}
+
+func (fs *fsys) truncate(ip *inode, length int64) error {
+	if length > 1e9 || ip.Mode&S_IFMT != S_IFREG {
+		return EINVAL
+	}
+	if length < int64(len(ip.data)) {
+		ip.data = ip.data[:length]
+	} else {
+		data := make([]byte, length)
+		copy(data, ip.data)
+		ip.data = data
+	}
+	ip.Size = int64(len(ip.data))
+	return nil
+}
+
+func Truncate(path string, length int64) error {
+	fsinit()
+	fs.mu.Lock()
+	defer fs.mu.Unlock()
+	ip, _, err := fs.namei(path, false)
+	if err != nil {
+		return err
+	}
+	return fs.truncate(ip, length)
+}
+
+func Ftruncate(fd int, length int64) error {
+	f, err := fdToFsysFile(fd)
+	if err != nil {
+		return err
+	}
+	f.fsys.mu.Lock()
+	defer f.fsys.mu.Unlock()
+	return f.fsys.truncate(f.inode, length)
+}
+
+func Chdir(path string) error {
+	fsinit()
+	return chdir(path)
+}
+
+func chdir(path string) error {
+	fs.mu.Lock()
+	defer fs.mu.Unlock()
+	ip, _, err := fs.namei(path, false)
+	if err != nil {
+		return err
+	}
+	fs.cwd = ip
+	return nil
+}
+
+func Fchdir(fd int) error {
+	f, err := fdToFsysFile(fd)
+	if err != nil {
+		return err
+	}
+	f.fsys.mu.Lock()
+	defer f.fsys.mu.Unlock()
+	if f.inode.Mode&S_IFMT != S_IFDIR {
+		return ENOTDIR
+	}
+	fs.cwd = f.inode
+	return nil
+}
+
+func Readlink(path string, buf []byte) (n int, err error) {
+	return 0, ENOSYS
+}
+
+func Symlink(path, link string) error {
+	return ENOSYS
+}
+
+func Fsync(fd int) error {
+	return nil
+}
+
+// Special devices.
+
+func mkdev(path string, mode uint32, open func() (devFile, error)) error {
+	f, err := fs.open(path, O_CREATE|O_RDONLY|O_EXCL, S_IFCHR|mode)
+	if err != nil {
+		return err
+	}
+	ip := f.(*fsysFile).inode
+	ip.Rdev = int64(len(fs.dev))
+	fs.dev = append(fs.dev, open)
+	return nil
+}
+
+type nullFile struct{}
+
+func openNull() (devFile, error)                               { return &nullFile{}, nil }
+func (f *nullFile) close() error                               { return nil }
+func (f *nullFile) pread(b []byte, offset int64) (int, error)  { return 0, nil }
+func (f *nullFile) pwrite(b []byte, offset int64) (int, error) { return len(b), nil }
+
+type zeroFile struct{}
+
+func openZero() (devFile, error)                               { return &zeroFile{}, nil }
+func (f *zeroFile) close() error                               { return nil }
+func (f *zeroFile) pwrite(b []byte, offset int64) (int, error) { return len(b), nil }
+
+func (f *zeroFile) pread(b []byte, offset int64) (int, error) {
+	for i := range b {
+		b[i] = 0
+	}
+	return len(b), nil
+}
+
+type randomFile struct {
+	naclFD int
+}
+
+func openRandom() (devFile, error) {
+	fd, err := openNamedService("SecureRandom", O_RDONLY)
+	if err != nil {
+		return nil, err
+	}
+	return &randomFile{naclFD: fd}, nil
+}
+
+func (f *randomFile) close() error {
+	naclClose(f.naclFD)
+	f.naclFD = -1
+	return nil
+}
+
+func (f *randomFile) pread(b []byte, offset int64) (int, error) {
+	return naclRead(f.naclFD, b)
+}
+
+func (f *randomFile) pwrite(b []byte, offset int64) (int, error) {
+	return 0, EPERM
+}
+
+func fdToFsysFile(fd int) (*fsysFile, error) {
+	f, err := fdToFile(fd)
+	if err != nil {
+		return nil, err
+	}
+	impl := f.impl
+	fsysf, ok := impl.(*fsysFile)
+	if !ok {
+		return nil, EINVAL
+	}
+	return fsysf, nil
+}
+
+// create creates a file in the file system with the given name, mode, time, and data.
+// It is meant to be called when initializing the file system image.
+func create(name string, mode uint32, sec int64, data []byte) error {
+	fs.mu.Lock()
+	fs.mu.Unlock()
+	f, err := fs.open(name, O_CREATE|O_EXCL, mode)
+	if err != nil {
+		if mode&S_IFMT == S_IFDIR {
+			ip, _, err := fs.namei(name, false)
+			if err == nil && (ip.Mode&S_IFMT) == S_IFDIR {
+				return nil // directory already exists
+			}
+		}
+		return err
+	}
+	ip := f.(*fsysFile).inode
+	ip.Atime = sec
+	ip.Mtime = sec
+	ip.Ctime = sec
+	if len(data) > 0 {
+		ip.Size = int64(len(data))
+		ip.data = data
+	}
+	return nil
+}
diff --git a/src/pkg/syscall/lsf_linux.go b/src/syscall/lsf_linux.go
similarity index 100%
rename from src/pkg/syscall/lsf_linux.go
rename to src/syscall/lsf_linux.go
diff --git a/src/syscall/mkall.sh b/src/syscall/mkall.sh
new file mode 100755
index 0000000..9cb82a6
--- /dev/null
+++ b/src/syscall/mkall.sh
@@ -0,0 +1,263 @@
+#!/usr/bin/env bash
+# Copyright 2009 The Go Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file.
+
+# The syscall package provides access to the raw system call
+# interface of the underlying operating system.  Porting Go to
+# a new architecture/operating system combination requires
+# some manual effort, though there are tools that automate
+# much of the process.  The auto-generated files have names
+# beginning with z.
+#
+# This script runs or (given -n) prints suggested commands to generate z files
+# for the current system.  Running those commands is not automatic.
+# This script is documentation more than anything else.
+#
+# * asm_${GOOS}_${GOARCH}.s
+#
+# This hand-written assembly file implements system call dispatch.
+# There are three entry points:
+#
+# 	func Syscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr);
+# 	func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr);
+# 	func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr);
+#
+# The first and second are the standard ones; they differ only in
+# how many arguments can be passed to the kernel.
+# The third is for low-level use by the ForkExec wrapper;
+# unlike the first two, it does not call into the scheduler to
+# let it know that a system call is running.
+#
+# * syscall_${GOOS}.go
+#
+# This hand-written Go file implements system calls that need
+# special handling and lists "//sys" comments giving prototypes
+# for ones that can be auto-generated.  Mksyscall reads those
+# comments to generate the stubs.
+#
+# * syscall_${GOOS}_${GOARCH}.go
+#
+# Same as syscall_${GOOS}.go except that it contains code specific
+# to ${GOOS} on one particular architecture.
+#
+# * types_${GOOS}.c
+#
+# This hand-written C file includes standard C headers and then
+# creates typedef or enum names beginning with a dollar sign
+# (use of $ in variable names is a gcc extension).  The hardest
+# part about preparing this file is figuring out which headers to
+# include and which symbols need to be #defined to get the
+# actual data structures that pass through to the kernel system calls.
+# Some C libraries present alternate versions for binary compatibility
+# and translate them on the way in and out of system calls, but
+# there is almost always a #define that can get the real ones.
+# See types_darwin.c and types_linux.c for examples.
+#
+# * zerror_${GOOS}_${GOARCH}.go
+#
+# This machine-generated file defines the system's error numbers,
+# error strings, and signal numbers.  The generator is "mkerrors.sh".
+# Usually no arguments are needed, but mkerrors.sh will pass its
+# arguments on to godefs.
+#
+# * zsyscall_${GOOS}_${GOARCH}.go
+#
+# Generated by mksyscall.pl; see syscall_${GOOS}.go above.
+#
+# * zsysnum_${GOOS}_${GOARCH}.go
+#
+# Generated by mksysnum_${GOOS}.
+#
+# * ztypes_${GOOS}_${GOARCH}.go
+#
+# Generated by godefs; see types_${GOOS}.c above.
+
+GOOSARCH="${GOOS}_${GOARCH}"
+
+# defaults
+mksyscall="./mksyscall.pl"
+mkerrors="./mkerrors.sh"
+zerrors="zerrors_$GOOSARCH.go"
+mksysctl=""
+zsysctl="zsysctl_$GOOSARCH.go"
+mksysnum=
+mktypes=
+run="sh"
+
+case "$1" in
+-syscalls)
+	for i in zsyscall*go
+	do
+		sed 1q $i | sed 's;^// ;;' | sh > _$i && gofmt < _$i > $i
+		rm _$i
+	done
+	exit 0
+	;;
+-n)
+	run="cat"
+	shift
+esac
+
+case "$#" in
+0)
+	;;
+*)
+	echo 'usage: mkall.sh [-n]' 1>&2
+	exit 2
+esac
+
+case "$GOOSARCH" in
+_* | *_ | _)
+	echo 'undefined $GOOS_$GOARCH:' "$GOOSARCH" 1>&2
+	exit 1
+	;;
+darwin_386)
+	mkerrors="$mkerrors -m32"
+	mksyscall="./mksyscall.pl -l32"
+	mksysnum="./mksysnum_darwin.pl /usr/include/sys/syscall.h"
+	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
+	;;
+darwin_amd64)
+	mkerrors="$mkerrors -m64"
+	mksysnum="./mksysnum_darwin.pl /usr/include/sys/syscall.h"
+	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
+	;;
+dragonfly_386)
+	mkerrors="$mkerrors -m32"
+	mksyscall="./mksyscall.pl -l32 -dragonfly"
+	mksysnum="curl -s 'http://gitweb.dragonflybsd.org/dragonfly.git/blob_plain/HEAD:/sys/kern/syscalls.master' | ./mksysnum_dragonfly.pl"
+	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
+	;;
+dragonfly_amd64)
+	mkerrors="$mkerrors -m64"
+	mksyscall="./mksyscall.pl -dragonfly"
+	mksysnum="curl -s 'http://gitweb.dragonflybsd.org/dragonfly.git/blob_plain/HEAD:/sys/kern/syscalls.master' | ./mksysnum_dragonfly.pl"
+	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
+	;;
+freebsd_386)
+	mkerrors="$mkerrors -m32"
+	mksyscall="./mksyscall.pl -l32"
+	mksysnum="curl -s 'http://svn.freebsd.org/base/stable/10/sys/kern/syscalls.master' | ./mksysnum_freebsd.pl"
+	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
+	;;
+freebsd_amd64)
+	mkerrors="$mkerrors -m64"
+	mksysnum="curl -s 'http://svn.freebsd.org/base/stable/10/sys/kern/syscalls.master' | ./mksysnum_freebsd.pl"
+	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
+	;;
+freebsd_arm)
+	mkerrors="$mkerrors"
+	mksyscall="./mksyscall.pl -l32 -arm"
+	mksysnum="curl -s 'http://svn.freebsd.org/base/stable/10/sys/kern/syscalls.master' | ./mksysnum_freebsd.pl"
+	# Let the type of C char be singed for making the bare syscall
+	# API consistent across over platforms.
+	mktypes="GOARCH=$GOARCH go tool cgo -godefs -- -fsigned-char"
+	;;
+linux_386)
+	mkerrors="$mkerrors -m32"
+	mksyscall="./mksyscall.pl -l32"
+	mksysnum="./mksysnum_linux.pl /usr/include/asm/unistd_32.h"
+	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
+	;;
+linux_amd64)
+	unistd_h=$(ls -1 /usr/include/asm/unistd_64.h /usr/include/x86_64-linux-gnu/asm/unistd_64.h 2>/dev/null | head -1)
+	if [ "$unistd_h" = "" ]; then
+		echo >&2 cannot find unistd_64.h
+		exit 1
+	fi
+	mkerrors="$mkerrors -m64"
+	mksysnum="./mksysnum_linux.pl $unistd_h"
+	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
+	;;
+linux_arm)
+	mkerrors="$mkerrors"
+	mksyscall="./mksyscall.pl -l32 -arm"
+	mksysnum="curl -s 'http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/plain/arch/arm/include/uapi/asm/unistd.h' | ./mksysnum_linux.pl"
+	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
+	;;
+nacl_386)
+	mkerrors=""
+	mksyscall="./mksyscall.pl -l32 -nacl"
+	mksysnum=""
+	mktypes=""
+	;;
+nacl_amd64p32)
+	mkerrors=""
+	mksyscall="./mksyscall.pl -nacl"
+	mksysnum=""
+	mktypes=""
+	;;
+netbsd_386)
+	mkerrors="$mkerrors -m32"
+	mksyscall="./mksyscall.pl -l32 -netbsd"
+	mksysnum="curl -s 'http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_netbsd.pl"
+	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
+	;;
+netbsd_amd64)
+	mkerrors="$mkerrors -m64"
+	mksyscall="./mksyscall.pl -netbsd"
+	mksysnum="curl -s 'http://cvsweb.netbsd.org/bsdweb.cgi/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_netbsd.pl"
+	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
+	;;
+openbsd_386)
+	mkerrors="$mkerrors -m32"
+	mksyscall="./mksyscall.pl -l32 -openbsd"
+	mksysctl="./mksysctl_openbsd.pl"
+	zsysctl="zsysctl_openbsd.go"
+	mksysnum="curl -s 'http://www.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_openbsd.pl"
+	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
+	;;
+openbsd_amd64)
+	mkerrors="$mkerrors -m64"
+	mksyscall="./mksyscall.pl -openbsd"
+	mksysctl="./mksysctl_openbsd.pl"
+	zsysctl="zsysctl_openbsd.go"
+	mksysnum="curl -s 'http://www.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/syscalls.master' | ./mksysnum_openbsd.pl"
+	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
+	;;
+plan9_386)
+	mkerrors=
+	mksyscall="./mksyscall.pl -l32 -plan9"
+	mksysnum="./mksysnum_plan9.sh /n/sources/plan9/sys/src/libc/9syscall/sys.h"
+	mktypes="XXX"
+	;;
+solaris_amd64)
+	mksyscall="./mksyscall_solaris.pl"
+	mkerrors="$mkerrors -m64"
+	mksysnum=
+	mktypes="GOARCH=$GOARCH go tool cgo -godefs"
+	;;
+windows_*)
+	mksyscall=
+	mkerrors=
+	zerrors=
+	;;
+*)
+	echo 'unrecognized $GOOS_$GOARCH: ' "$GOOSARCH" 1>&2
+	exit 1
+	;;
+esac
+
+(
+	if [ -n "$mkerrors" ]; then echo "$mkerrors |gofmt >$zerrors"; fi
+	case "$GOOS" in
+	windows)
+		echo "GOOS= GOARCH= go build mksyscall_windows.go"
+		echo "./mksyscall_windows syscall_windows.go security_windows.go |gofmt >zsyscall_windows.go"
+		echo "rm -f ./mksyscall_windows"
+		;;
+	*)
+		syscall_goos="syscall_$GOOS.go"
+		case "$GOOS" in
+		darwin | dragonfly | freebsd | netbsd | openbsd)
+			syscall_goos="syscall_bsd.go $syscall_goos"
+			;;
+		esac
+		if [ -n "$mksyscall" ]; then echo "$mksyscall $syscall_goos syscall_$GOOSARCH.go |gofmt >zsyscall_$GOOSARCH.go"; fi
+		;;
+	esac
+	if [ -n "$mksysctl" ]; then echo "$mksysctl |gofmt >$zsysctl"; fi
+	if [ -n "$mksysnum" ]; then echo "$mksysnum |gofmt >zsysnum_$GOOSARCH.go"; fi
+	if [ -n "$mktypes" ]; then echo "$mktypes types_$GOOS.go |gofmt >ztypes_$GOOSARCH.go"; fi
+) | $run
diff --git a/src/syscall/mkall_windows.bat b/src/syscall/mkall_windows.bat
new file mode 100644
index 0000000..0f3a98b
--- /dev/null
+++ b/src/syscall/mkall_windows.bat
@@ -0,0 +1,15 @@
+:: Copyright 2013 The Go Authors. All rights reserved.
+:: Use of this source code is governed by a BSD-style
+:: license that can be found in the LICENSE file.
+ at echo off
+
+if exist mkall.sh goto dirok
+echo mkall_windows.bat must be run from src\syscall directory
+goto :end
+:dirok
+
+go build mksyscall_windows.go
+.\mksyscall_windows syscall_windows.go security_windows.go |gofmt >zsyscall_windows.go
+del mksyscall_windows.exe
+
+:end
diff --git a/src/pkg/syscall/mkerrors.sh b/src/syscall/mkerrors.sh
similarity index 100%
rename from src/pkg/syscall/mkerrors.sh
rename to src/syscall/mkerrors.sh
diff --git a/src/syscall/mksyscall.pl b/src/syscall/mksyscall.pl
new file mode 100755
index 0000000..dff9138
--- /dev/null
+++ b/src/syscall/mksyscall.pl
@@ -0,0 +1,319 @@
+#!/usr/bin/env perl
+# Copyright 2009 The Go Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file.
+
+# This program reads a file containing function prototypes
+# (like syscall_darwin.go) and generates system call bodies.
+# The prototypes are marked by lines beginning with "//sys"
+# and read like func declarations if //sys is replaced by func, but:
+#	* The parameter lists must give a name for each argument.
+#	  This includes return parameters.
+#	* The parameter lists must give a type for each argument:
+#	  the (x, y, z int) shorthand is not allowed.
+#	* If the return parameter is an error number, it must be named errno.
+
+# A line beginning with //sysnb is like //sys, except that the
+# goroutine will not be suspended during the execution of the system
+# call.  This must only be used for system calls which can never
+# block, as otherwise the system call could cause all goroutines to
+# hang.
+
+use strict;
+
+my $cmdline = "mksyscall.pl " . join(' ', @ARGV);
+my $errors = 0;
+my $_32bit = "";
+my $plan9 = 0;
+my $openbsd = 0;
+my $netbsd = 0;
+my $dragonfly = 0;
+my $nacl = 0;
+my $arm = 0; # 64-bit value should use (even, odd)-pair
+
+if($ARGV[0] eq "-b32") {
+	$_32bit = "big-endian";
+	shift;
+} elsif($ARGV[0] eq "-l32") {
+	$_32bit = "little-endian";
+	shift;
+}
+if($ARGV[0] eq "-plan9") {
+	$plan9 = 1;
+	shift;
+}
+if($ARGV[0] eq "-openbsd") {
+	$openbsd = 1;
+	shift;
+}
+if($ARGV[0] eq "-netbsd") {
+	$netbsd = 1;
+	shift;
+}
+if($ARGV[0] eq "-dragonfly") {
+	$dragonfly = 1;
+	shift;
+}
+if($ARGV[0] eq "-nacl") {
+	$nacl = 1;
+	shift;
+}
+if($ARGV[0] eq "-arm") {
+	$arm = 1;
+	shift;
+}
+
+if($ARGV[0] =~ /^-/) {
+	print STDERR "usage: mksyscall.pl [-b32 | -l32] [file ...]\n";
+	exit 1;
+}
+
+sub parseparamlist($) {
+	my ($list) = @_;
+	$list =~ s/^\s*//;
+	$list =~ s/\s*$//;
+	if($list eq "") {
+		return ();
+	}
+	return split(/\s*,\s*/, $list);
+}
+
+sub parseparam($) {
+	my ($p) = @_;
+	if($p !~ /^(\S*) (\S*)$/) {
+		print STDERR "$ARGV:$.: malformed parameter: $p\n";
+		$errors = 1;
+		return ("xx", "int");
+	}
+	return ($1, $2);
+}
+
+my $text = "";
+while(<>) {
+	chomp;
+	s/\s+/ /g;
+	s/^\s+//;
+	s/\s+$//;
+	my $nonblock = /^\/\/sysnb /;
+	next if !/^\/\/sys / && !$nonblock;
+
+	# 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_]+))?$/) {
+		print STDERR "$ARGV:$.: malformed //sys declaration\n";
+		$errors = 1;
+		next;
+	}
+	my ($func, $in, $out, $sysname) = ($2, $3, $4, $5);
+
+	# Split argument lists on comma.
+	my @in = parseparamlist($in);
+	my @out = parseparamlist($out);
+
+	# Try in vain to keep people from editing this file.
+	# The theory is that they jump into the middle of the file
+	# without reading the header.
+	$text .= "// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\n";
+
+	# Go function header.
+	my $out_decl = @out ? sprintf(" (%s)", join(', ', @out)) : "";
+	$text .= sprintf "func %s(%s)%s {\n", $func, join(', ', @in), $out_decl;
+
+	# Check if err return available
+	my $errvar = "";
+	foreach my $p (@out) {
+		my ($name, $type) = parseparam($p);
+		if($type eq "error") {
+			$errvar = $name;
+			last;
+		}
+	}
+
+	# Prepare arguments to Syscall.
+	my @args = ();
+	my @uses = ();
+	my $n = 0;
+	foreach my $p (@in) {
+		my ($name, $type) = parseparam($p);
+		if($type =~ /^\*/) {
+			push @args, "uintptr(unsafe.Pointer($name))";
+		} elsif($type eq "string" && $errvar ne "") {
+			$text .= "\tvar _p$n *byte\n";
+			$text .= "\t_p$n, $errvar = BytePtrFromString($name)\n";
+			$text .= "\tif $errvar != nil {\n\t\treturn\n\t}\n";
+			push @args, "uintptr(unsafe.Pointer(_p$n))";
+			push @uses, "use(unsafe.Pointer(_p$n))";
+			$n++;
+		} elsif($type eq "string") {
+			print STDERR "$ARGV:$.: $func uses string arguments, but has no error return\n";
+			$text .= "\tvar _p$n *byte\n";
+			$text .= "\t_p$n, _ = BytePtrFromString($name)\n";
+			push @args, "uintptr(unsafe.Pointer(_p$n))";
+			push @uses, "use(unsafe.Pointer(_p$n))";
+			$n++;
+		} elsif($type =~ /^\[\](.*)/) {
+			# Convert slice into pointer, length.
+			# Have to be careful not to take address of &a[0] if len == 0:
+			# pass dummy pointer in that case.
+			# Used to pass nil, but some OSes or simulators reject write(fd, nil, 0).
+			$text .= "\tvar _p$n unsafe.Pointer\n";
+			$text .= "\tif len($name) > 0 {\n\t\t_p$n = unsafe.Pointer(\&${name}[0])\n\t}";
+			$text .= " else {\n\t\t_p$n = unsafe.Pointer(&_zero)\n\t}";
+			$text .= "\n";
+			push @args, "uintptr(_p$n)", "uintptr(len($name))";
+			$n++;
+		} elsif($type eq "int64" && ($openbsd || $netbsd)) {
+			push @args, "0";
+			if($_32bit eq "big-endian") {
+				push @args, "uintptr($name>>32)", "uintptr($name)";
+			} elsif($_32bit eq "little-endian") {
+				push @args, "uintptr($name)", "uintptr($name>>32)";
+			} else {
+				push @args, "uintptr($name)";
+			}
+		} elsif($type eq "int64" && $dragonfly) {
+			if ($func !~ /^extp(read|write)/i) {
+				push @args, "0";
+			}
+			if($_32bit eq "big-endian") {
+				push @args, "uintptr($name>>32)", "uintptr($name)";
+			} elsif($_32bit eq "little-endian") {
+				push @args, "uintptr($name)", "uintptr($name>>32)";
+			} else {
+				push @args, "uintptr($name)";
+			}
+		} elsif($type eq "int64" && $_32bit ne "") {
+			if(@args % 2 && $arm) {
+				# arm abi specifies 64-bit argument uses 
+				# (even, odd) pair
+				push @args, "0"
+			}
+			if($_32bit eq "big-endian") {
+				push @args, "uintptr($name>>32)", "uintptr($name)";
+			} else {
+				push @args, "uintptr($name)", "uintptr($name>>32)";
+			}
+		} else {
+			push @args, "uintptr($name)";
+		}
+	}
+
+	# Determine which form to use; pad args with zeros.
+	my $asm = "Syscall";
+	if ($nonblock) {
+		$asm = "RawSyscall";
+	}
+	if(@args <= 3) {
+		while(@args < 3) {
+			push @args, "0";
+		}
+	} elsif(@args <= 6) {
+		$asm .= "6";
+		while(@args < 6) {
+			push @args, "0";
+		}
+	} elsif(@args <= 9) {
+		$asm .= "9";
+		while(@args < 9) {
+			push @args, "0";
+		}
+	} else {
+		print STDERR "$ARGV:$.: too many arguments to system call\n";
+	}
+
+	# System call number.
+	if($sysname eq "") {
+		$sysname = "SYS_$func";
+		$sysname =~ s/([a-z])([A-Z])/${1}_$2/g;	# turn FooBar into Foo_Bar
+		$sysname =~ y/a-z/A-Z/;
+		if($nacl) {
+			$sysname =~ y/A-Z/a-z/;
+		}
+	}
+
+	# Actual call.
+	my $args = join(', ', @args);
+	my $call = "$asm($sysname, $args)";
+
+	# Assign return values.
+	my $body = "";
+	my @ret = ("_", "_", "_");
+	my $do_errno = 0;
+	for(my $i=0; $i<@out; $i++) {
+		my $p = $out[$i];
+		my ($name, $type) = parseparam($p);
+		my $reg = "";
+		if($name eq "err" && !$plan9) {
+			$reg = "e1";
+			$ret[2] = $reg;
+			$do_errno = 1;
+		} elsif($name eq "err" && $plan9) {
+			$ret[0] = "r0";
+			$ret[2] = "e1";
+			next;
+		} else {
+			$reg = sprintf("r%d", $i);
+			$ret[$i] = $reg;
+		}
+		if($type eq "bool") {
+			$reg = "$reg != 0";
+		}
+		if($type eq "int64" && $_32bit ne "") {
+			# 64-bit number in r1:r0 or r0:r1.
+			if($i+2 > @out) {
+				print STDERR "$ARGV:$.: not enough registers for int64 return\n";
+			}
+			if($_32bit eq "big-endian") {
+				$reg = sprintf("int64(r%d)<<32 | int64(r%d)", $i, $i+1);
+			} else {
+				$reg = sprintf("int64(r%d)<<32 | int64(r%d)", $i+1, $i);
+			}
+			$ret[$i] = sprintf("r%d", $i);
+			$ret[$i+1] = sprintf("r%d", $i+1);
+		}
+		if($reg ne "e1" || $plan9) {
+			$body .= "\t$name = $type($reg)\n";
+		}
+	}
+	if ($ret[0] eq "_" && $ret[1] eq "_" && $ret[2] eq "_") {
+		$text .= "\t$call\n";
+	} else {
+		$text .= "\t$ret[0], $ret[1], $ret[2] := $call\n";
+	}
+	foreach my $use (@uses) {
+		$text .= "\t$use\n";
+	}
+	$text .= $body;
+	
+	if ($plan9 && $ret[2] eq "e1") {
+		$text .= "\tif int32(r0) == -1 {\n";
+		$text .= "\t\terr = e1\n";
+		$text .= "\t}\n";
+	} elsif ($do_errno) {
+		$text .= "\tif e1 != 0 {\n";
+		$text .= "\t\terr = e1\n";
+		$text .= "\t}\n";
+	}
+	$text .= "\treturn\n";
+	$text .= "}\n\n";
+}
+
+chomp $text;
+chomp $text;
+
+if($errors) {
+	exit 1;
+}
+
+print <<EOF;
+// $cmdline
+// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
+
+package syscall
+
+import "unsafe"
+
+$text
+EOF
+exit 0;
diff --git a/src/syscall/mksyscall_solaris.pl b/src/syscall/mksyscall_solaris.pl
new file mode 100755
index 0000000..e72a4d1
--- /dev/null
+++ b/src/syscall/mksyscall_solaris.pl
@@ -0,0 +1,283 @@
+#!/usr/bin/env perl
+# Copyright 2009 The Go Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file.
+
+# This program reads a file containing function prototypes
+# (like syscall_solaris.go) and generates system call bodies.
+# The prototypes are marked by lines beginning with "//sys"
+# and read like func declarations if //sys is replaced by func, but:
+#	* The parameter lists must give a name for each argument.
+#	  This includes return parameters.
+#	* The parameter lists must give a type for each argument:
+#	  the (x, y, z int) shorthand is not allowed.
+#	* If the return parameter is an error number, it must be named err.
+#	* If go func name needs to be different than its libc name, 
+#	* or the function is not in libc, name could be specified
+#	* at the end, after "=" sign, like
+#	  //sys getsockopt(s int, level int, name int, val uintptr, vallen *_Socklen) (err error) = libsocket.getsockopt
+
+use strict;
+
+my $cmdline = "mksyscall_solaris.pl " . join(' ', @ARGV);
+my $errors = 0;
+my $_32bit = "";
+
+binmode STDOUT;
+
+if($ARGV[0] eq "-b32") {
+	$_32bit = "big-endian";
+	shift;
+} elsif($ARGV[0] eq "-l32") {
+	$_32bit = "little-endian";
+	shift;
+}
+
+if($ARGV[0] =~ /^-/) {
+	print STDERR "usage: mksyscall_solaris.pl [-b32 | -l32] [file ...]\n";
+	exit 1;
+}
+
+sub parseparamlist($) {
+	my ($list) = @_;
+	$list =~ s/^\s*//;
+	$list =~ s/\s*$//;
+	if($list eq "") {
+		return ();
+	}
+	return split(/\s*,\s*/, $list);
+}
+
+sub parseparam($) {
+	my ($p) = @_;
+	if($p !~ /^(\S*) (\S*)$/) {
+		print STDERR "$ARGV:$.: malformed parameter: $p\n";
+		$errors = 1;
+		return ("xx", "int");
+	}
+	return ($1, $2);
+}
+
+my $package = "";
+my $text = "";
+my $vars = "";
+my $mods = "";
+my $modnames = "";
+while(<>) {
+	chomp;
+	s/\s+/ /g;
+	s/^\s+//;
+	s/\s+$//;
+	$package = $1 if !$package && /^package (\S+)$/;
+	my $nonblock = /^\/\/sysnb /;
+	next if !/^\/\/sys / && !$nonblock;
+
+	my $syscalldot = "";
+	$syscalldot = "syscall." if $package ne "syscall";
+
+	# Line must be of the form
+	#	func Open(path string, mode int, perm int) (fd int, err error)
+	# Split into name, in params, out params.
+	if(!/^\/\/sys(nb)? (\w+)\(([^()]*)\)\s*(?:\(([^()]+)\))?\s*(?:=\s*(?:(\w*)\.)?(\w*))?$/) {
+		print STDERR "$ARGV:$.: malformed //sys declaration\n";
+		$errors = 1;
+		next;
+	}
+	my ($nb, $func, $in, $out, $modname, $sysname) = ($1, $2, $3, $4, $5, $6);
+
+	# Split argument lists on comma.
+	my @in = parseparamlist($in);
+	my @out = parseparamlist($out);
+
+	# So file name.
+	if($modname eq "") {
+		$modname = "libc";
+	}
+	my $modvname = "mod$modname";
+	if($modnames !~ /$modname/) {
+		$modnames .= ".$modname";
+		$mods .= "\t$modvname = ${syscalldot}newLazySO(\"$modname.so\")\n";
+	}
+
+	# System call name.
+	if($sysname eq "") {
+		$sysname = "$func";
+	}
+
+	# System call pointer variable name.
+	my $sysvarname = "proc$sysname";
+
+	my $strconvfunc = "BytePtrFromString";
+	my $strconvtype = "*byte";
+
+	# Library proc address variable.
+	$sysname =~ y/A-Z/a-z/; # All libc functions are lowercase.
+	$vars .= "\t$sysvarname = $modvname.NewProc(\"$sysname\")\n";
+
+	# Go function header.
+	$out = join(', ', @out);
+	if($out ne "") {
+		$out = " ($out)";
+	}
+	if($text ne "") {
+		$text .= "\n"
+	}
+	$text .= sprintf "func %s(%s)%s {\n", $func, join(', ', @in), $out;
+
+	# Check if err return available
+	my $errvar = "";
+	foreach my $p (@out) {
+		my ($name, $type) = parseparam($p);
+		if($type eq "error") {
+			$errvar = $name;
+			last;
+		}
+	}
+
+	# Prepare arguments to Syscall.
+	my @args = ();
+	my @uses = ();
+	my $n = 0;
+	foreach my $p (@in) {
+		my ($name, $type) = parseparam($p);
+		if($type =~ /^\*/) {
+			push @args, "uintptr(unsafe.Pointer($name))";
+		} elsif($type eq "string" && $errvar ne "") {
+			$text .= "\tvar _p$n $strconvtype\n";
+			$text .= "\t_p$n, $errvar = $strconvfunc($name)\n";
+			$text .= "\tif $errvar != nil {\n\t\treturn\n\t}\n";
+			push @args, "uintptr(unsafe.Pointer(_p$n))";
+			push @uses, "use(unsafe.Pointer(_p$n))";
+			$n++;
+		} elsif($type eq "string") {
+			print STDERR "$ARGV:$.: $func uses string arguments, but has no error return\n";
+			$text .= "\tvar _p$n $strconvtype\n";
+			$text .= "\t_p$n, _ = $strconvfunc($name)\n";
+			push @args, "uintptr(unsafe.Pointer(_p$n))";
+			push @uses, "use(unsafe.Pointer(_p$n))";
+			$n++;
+		} elsif($type =~ /^\[\](.*)/) {
+			# Convert slice into pointer, length.
+			# Have to be careful not to take address of &a[0] if len == 0:
+			# pass nil in that case.
+			$text .= "\tvar _p$n *$1\n";
+			$text .= "\tif len($name) > 0 {\n\t\t_p$n = \&$name\[0]\n\t}\n";
+			push @args, "uintptr(unsafe.Pointer(_p$n))", "uintptr(len($name))";
+			$n++;
+		} elsif($type eq "int64" && $_32bit ne "") {
+			if($_32bit eq "big-endian") {
+				push @args, "uintptr($name >> 32)", "uintptr($name)";
+			} else {
+				push @args, "uintptr($name)", "uintptr($name >> 32)";
+			}
+		} elsif($type eq "bool") {
+ 			$text .= "\tvar _p$n uint32\n";
+			$text .= "\tif $name {\n\t\t_p$n = 1\n\t} else {\n\t\t_p$n = 0\n\t}\n";
+			push @args, "uintptr(_p$n)";
+			$n++;
+		} else {
+			push @args, "uintptr($name)";
+		}
+	}
+	my $nargs = @args;
+
+	# Determine which form to use; pad args with zeros.
+	my $asm = "${syscalldot}sysvicall6";
+	if ($nonblock) {
+		$asm = "${syscalldot}rawSysvicall6";
+	}
+	if(@args <= 6) {
+		while(@args < 6) {
+			push @args, "0";
+		}
+	} else {
+		print STDERR "$ARGV:$.: too many arguments to system call\n";
+	}
+
+	# Actual call.
+	my $args = join(', ', @args);
+	my $call = "$asm($sysvarname.Addr(), $nargs, $args)";
+
+	# Assign return values.
+	my $body = "";
+	my $failexpr = "";
+	my @ret = ("_", "_", "_");
+	my @pout= ();
+	my $do_errno = 0;
+	for(my $i=0; $i<@out; $i++) {
+		my $p = $out[$i];
+		my ($name, $type) = parseparam($p);
+		my $reg = "";
+		if($name eq "err") {
+			$reg = "e1";
+			$ret[2] = $reg;
+			$do_errno = 1;
+		} else {
+			$reg = sprintf("r%d", $i);
+			$ret[$i] = $reg;
+		}
+		if($type eq "bool") {
+			$reg = "$reg != 0";
+		}
+		if($type eq "int64" && $_32bit ne "") {
+			# 64-bit number in r1:r0 or r0:r1.
+			if($i+2 > @out) {
+				print STDERR "$ARGV:$.: not enough registers for int64 return\n";
+			}
+			if($_32bit eq "big-endian") {
+				$reg = sprintf("int64(r%d)<<32 | int64(r%d)", $i, $i+1);
+			} else {
+				$reg = sprintf("int64(r%d)<<32 | int64(r%d)", $i+1, $i);
+			}
+			$ret[$i] = sprintf("r%d", $i);
+			$ret[$i+1] = sprintf("r%d", $i+1);
+		}
+		if($reg ne "e1") {
+			$body .= "\t$name = $type($reg)\n";
+		}
+	}
+	if ($ret[0] eq "_" && $ret[1] eq "_" && $ret[2] eq "_") {
+		$text .= "\t$call\n";
+	} else {
+		$text .= "\t$ret[0], $ret[1], $ret[2] := $call\n";
+	}
+	foreach my $use (@uses) {
+		$text .= "\t$use\n";
+	}
+	$text .= $body;
+
+	if ($do_errno) {
+		$text .= "\tif e1 != 0 {\n";
+		$text .= "\t\terr = e1\n";
+		$text .= "\t}\n";
+	}
+	$text .= "\treturn\n";
+	$text .= "}\n";
+}
+
+if($errors) {
+	exit 1;
+}
+
+print <<EOF;
+// $cmdline
+// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
+
+package $package
+
+import "unsafe"
+EOF
+
+print "import \"syscall\"\n" if $package ne "syscall";
+
+print <<EOF;
+
+var (
+$mods
+$vars
+)
+
+$text
+
+EOF
+exit 0;
diff --git a/src/syscall/mksyscall_windows.go b/src/syscall/mksyscall_windows.go
new file mode 100644
index 0000000..316e88d
--- /dev/null
+++ b/src/syscall/mksyscall_windows.go
@@ -0,0 +1,759 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build ignore
+
+/*
+mksyscall_windows generates windows system call bodies
+
+It parses all files specified on command line containing function
+prototypes (like syscall_windows.go) and prints system call bodies
+to standard output.
+
+The prototypes are marked by lines beginning with "//sys" and read
+like func declarations if //sys is replaced by func, but:
+
+* The parameter lists must give a name for each argument. This
+  includes return parameters.
+
+* The parameter lists must give a type for each argument:
+  the (x, y, z int) shorthand is not allowed.
+
+* If the return parameter is an error number, it must be named err.
+
+* If go func name needs to be different from it's winapi dll name,
+  the winapi name could be specified at the end, after "=" sign, like
+  //sys LoadLibrary(libname string) (handle uint32, err error) = LoadLibraryA
+
+* Each function that returns err needs to supply a condition, that
+  return value of winapi will be tested against to detect failure.
+  This would set err to windows "last-error", otherwise it will be nil.
+  The value can be provided at end of //sys declaration, like
+  //sys LoadLibrary(libname string) (handle uint32, err error) [failretval==-1] = LoadLibraryA
+  and is [failretval==0] by default.
+
+Usage:
+	mksyscall_windows [flags] [path ...]
+
+The flags are:
+	-trace
+		Generate print statement after every syscall.
+*/
+package main
+
+import (
+	"bufio"
+	"errors"
+	"flag"
+	"fmt"
+	"go/parser"
+	"go/token"
+	"io"
+	"log"
+	"os"
+	"strconv"
+	"strings"
+	"text/template"
+)
+
+var PrintTraceFlag = flag.Bool("trace", false, "generate print statement after every syscall")
+
+func trim(s string) string {
+	return strings.Trim(s, " \t")
+}
+
+var packageName string
+
+func packagename() string {
+	return packageName
+}
+
+func syscalldot() string {
+	if packageName == "syscall" {
+		return ""
+	}
+	return "syscall."
+}
+
+// Param is function parameter
+type Param struct {
+	Name      string
+	Type      string
+	fn        *Fn
+	tmpVarIdx int
+}
+
+// tmpVar returns temp variable name that will be used to represent p during syscall.
+func (p *Param) tmpVar() string {
+	if p.tmpVarIdx < 0 {
+		p.tmpVarIdx = p.fn.curTmpVarIdx
+		p.fn.curTmpVarIdx++
+	}
+	return fmt.Sprintf("_p%d", p.tmpVarIdx)
+}
+
+// BoolTmpVarCode returns source code for bool temp variable.
+func (p *Param) BoolTmpVarCode() string {
+	const code = `var %s uint32
+	if %s {
+		%s = 1
+	} else {
+		%s = 0
+	}`
+	tmp := p.tmpVar()
+	return fmt.Sprintf(code, tmp, p.Name, tmp, tmp)
+}
+
+// SliceTmpVarCode returns source code for slice temp variable.
+func (p *Param) SliceTmpVarCode() string {
+	const code = `var %s *%s
+	if len(%s) > 0 {
+		%s = &%s[0]
+	}`
+	tmp := p.tmpVar()
+	return fmt.Sprintf(code, tmp, p.Type[2:], p.Name, tmp, p.Name)
+}
+
+// StringTmpVarCode returns source code for string temp variable.
+func (p *Param) StringTmpVarCode() string {
+	errvar := p.fn.Rets.ErrorVarName()
+	if errvar == "" {
+		errvar = "_"
+	}
+	tmp := p.tmpVar()
+	const code = `var %s %s
+	%s, %s = %s(%s)`
+	s := fmt.Sprintf(code, tmp, p.fn.StrconvType(), tmp, errvar, p.fn.StrconvFunc(), p.Name)
+	if errvar == "-" {
+		return s
+	}
+	const morecode = `
+	if %s != nil {
+		return
+	}`
+	return s + fmt.Sprintf(morecode, errvar)
+}
+
+// TmpVarCode returns source code for temp variable.
+func (p *Param) TmpVarCode() string {
+	switch {
+	case p.Type == "bool":
+		return p.BoolTmpVarCode()
+	case strings.HasPrefix(p.Type, "[]"):
+		return p.SliceTmpVarCode()
+	default:
+		return ""
+	}
+}
+
+// TmpVarHelperCode returns source code for helper's temp variable.
+func (p *Param) TmpVarHelperCode() string {
+	if p.Type != "string" {
+		return ""
+	}
+	return p.StringTmpVarCode()
+}
+
+// SyscallArgList returns source code fragments representing p parameter
+// in syscall. Slices are translated into 2 syscall parameters: pointer to
+// the first element and length.
+func (p *Param) SyscallArgList() []string {
+	t := p.HelperType()
+	var s string
+	switch {
+	case t[0] == '*':
+		s = fmt.Sprintf("unsafe.Pointer(%s)", p.Name)
+	case t == "bool":
+		s = p.tmpVar()
+	case strings.HasPrefix(t, "[]"):
+		return []string{
+			fmt.Sprintf("uintptr(unsafe.Pointer(%s))", p.tmpVar()),
+			fmt.Sprintf("uintptr(len(%s))", p.Name),
+		}
+	default:
+		s = p.Name
+	}
+	return []string{fmt.Sprintf("uintptr(%s)", s)}
+}
+
+// IsError determines if p parameter is used to return error.
+func (p *Param) IsError() bool {
+	return p.Name == "err" && p.Type == "error"
+}
+
+// HelperType returns type of parameter p used in helper function.
+func (p *Param) HelperType() string {
+	if p.Type == "string" {
+		return p.fn.StrconvType()
+	}
+	return p.Type
+}
+
+// join concatenates parameters ps into a string with sep separator.
+// Each parameter is converted into string by applying fn to it
+// before conversion.
+func join(ps []*Param, fn func(*Param) string, sep string) string {
+	if len(ps) == 0 {
+		return ""
+	}
+	a := make([]string, 0)
+	for _, p := range ps {
+		a = append(a, fn(p))
+	}
+	return strings.Join(a, sep)
+}
+
+// Rets describes function return parameters.
+type Rets struct {
+	Name         string
+	Type         string
+	ReturnsError bool
+	FailCond     string
+}
+
+// ErrorVarName returns error variable name for r.
+func (r *Rets) ErrorVarName() string {
+	if r.ReturnsError {
+		return "err"
+	}
+	if r.Type == "error" {
+		return r.Name
+	}
+	return ""
+}
+
+// ToParams converts r into slice of *Param.
+func (r *Rets) ToParams() []*Param {
+	ps := make([]*Param, 0)
+	if len(r.Name) > 0 {
+		ps = append(ps, &Param{Name: r.Name, Type: r.Type})
+	}
+	if r.ReturnsError {
+		ps = append(ps, &Param{Name: "err", Type: "error"})
+	}
+	return ps
+}
+
+// List returns source code of syscall return parameters.
+func (r *Rets) List() string {
+	s := join(r.ToParams(), func(p *Param) string { return p.Name + " " + p.Type }, ", ")
+	if len(s) > 0 {
+		s = "(" + s + ")"
+	}
+	return s
+}
+
+// PrintList returns source code of trace printing part correspondent
+// to syscall return values.
+func (r *Rets) PrintList() string {
+	return join(r.ToParams(), func(p *Param) string { return fmt.Sprintf(`"%s=", %s, `, p.Name, p.Name) }, `", ", `)
+}
+
+// SetReturnValuesCode returns source code that accepts syscall return values.
+func (r *Rets) SetReturnValuesCode() string {
+	if r.Name == "" && !r.ReturnsError {
+		return ""
+	}
+	retvar := "r0"
+	if r.Name == "" {
+		retvar = "r1"
+	}
+	errvar := "_"
+	if r.ReturnsError {
+		errvar = "e1"
+	}
+	return fmt.Sprintf("%s, _, %s := ", retvar, errvar)
+}
+
+func (r *Rets) useLongHandleErrorCode(retvar string) string {
+	const code = `if %s {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = %sEINVAL
+		}
+	}`
+	cond := retvar + " == 0"
+	if r.FailCond != "" {
+		cond = strings.Replace(r.FailCond, "failretval", retvar, 1)
+	}
+	return fmt.Sprintf(code, cond, syscalldot())
+}
+
+// SetErrorCode returns source code that sets return parameters.
+func (r *Rets) SetErrorCode() string {
+	const code = `if r0 != 0 {
+		%s = %sErrno(r0)
+	}`
+	if r.Name == "" && !r.ReturnsError {
+		return ""
+	}
+	if r.Name == "" {
+		return r.useLongHandleErrorCode("r1")
+	}
+	if r.Type == "error" {
+		return fmt.Sprintf(code, r.Name, syscalldot())
+	}
+	s := ""
+	switch {
+	case r.Type[0] == '*':
+		s = fmt.Sprintf("%s = (%s)(unsafe.Pointer(r0))", r.Name, r.Type)
+	case r.Type == "bool":
+		s = fmt.Sprintf("%s = r0 != 0", r.Name)
+	default:
+		s = fmt.Sprintf("%s = %s(r0)", r.Name, r.Type)
+	}
+	if !r.ReturnsError {
+		return s
+	}
+	return s + "\n\t" + r.useLongHandleErrorCode(r.Name)
+}
+
+// Fn describes syscall function.
+type Fn struct {
+	Name        string
+	Params      []*Param
+	Rets        *Rets
+	PrintTrace  bool
+	dllname     string
+	dllfuncname string
+	src         string
+	// TODO: get rid of this field and just use parameter index instead
+	curTmpVarIdx int // insure tmp variables have uniq names
+}
+
+// extractParams parses s to extract function parameters.
+func extractParams(s string, f *Fn) ([]*Param, error) {
+	s = trim(s)
+	if s == "" {
+		return nil, nil
+	}
+	a := strings.Split(s, ",")
+	ps := make([]*Param, len(a))
+	for i := range ps {
+		s2 := trim(a[i])
+		b := strings.Split(s2, " ")
+		if len(b) != 2 {
+			b = strings.Split(s2, "\t")
+			if len(b) != 2 {
+				return nil, errors.New("Could not extract function parameter from \"" + s2 + "\"")
+			}
+		}
+		ps[i] = &Param{
+			Name:      trim(b[0]),
+			Type:      trim(b[1]),
+			fn:        f,
+			tmpVarIdx: -1,
+		}
+	}
+	return ps, nil
+}
+
+// extractSection extracts text out of string s starting after start
+// and ending just before end. found return value will indicate success,
+// and prefix, body and suffix will contain correspondent parts of string s.
+func extractSection(s string, start, end rune) (prefix, body, suffix string, found bool) {
+	s = trim(s)
+	if strings.HasPrefix(s, string(start)) {
+		// no prefix
+		body = s[1:]
+	} else {
+		a := strings.SplitN(s, string(start), 2)
+		if len(a) != 2 {
+			return "", "", s, false
+		}
+		prefix = a[0]
+		body = a[1]
+	}
+	a := strings.SplitN(body, string(end), 2)
+	if len(a) != 2 {
+		return "", "", "", false
+	}
+	return prefix, a[0], a[1], true
+}
+
+// newFn parses string s and return created function Fn.
+func newFn(s string) (*Fn, error) {
+	s = trim(s)
+	f := &Fn{
+		Rets:       &Rets{},
+		src:        s,
+		PrintTrace: *PrintTraceFlag,
+	}
+	// function name and args
+	prefix, body, s, found := extractSection(s, '(', ')')
+	if !found || prefix == "" {
+		return nil, errors.New("Could not extract function name and parameters from \"" + f.src + "\"")
+	}
+	f.Name = prefix
+	var err error
+	f.Params, err = extractParams(body, f)
+	if err != nil {
+		return nil, err
+	}
+	// return values
+	_, body, s, found = extractSection(s, '(', ')')
+	if found {
+		r, err := extractParams(body, f)
+		if err != nil {
+			return nil, err
+		}
+		switch len(r) {
+		case 0:
+		case 1:
+			if r[0].IsError() {
+				f.Rets.ReturnsError = true
+			} else {
+				f.Rets.Name = r[0].Name
+				f.Rets.Type = r[0].Type
+			}
+		case 2:
+			if !r[1].IsError() {
+				return nil, errors.New("Only last windows error is allowed as second return value in \"" + f.src + "\"")
+			}
+			f.Rets.ReturnsError = true
+			f.Rets.Name = r[0].Name
+			f.Rets.Type = r[0].Type
+		default:
+			return nil, errors.New("Too many return values in \"" + f.src + "\"")
+		}
+	}
+	// fail condition
+	_, body, s, found = extractSection(s, '[', ']')
+	if found {
+		f.Rets.FailCond = body
+	}
+	// dll and dll function names
+	s = trim(s)
+	if s == "" {
+		return f, nil
+	}
+	if !strings.HasPrefix(s, "=") {
+		return nil, errors.New("Could not extract dll name from \"" + f.src + "\"")
+	}
+	s = trim(s[1:])
+	a := strings.Split(s, ".")
+	switch len(a) {
+	case 1:
+		f.dllfuncname = a[0]
+	case 2:
+		f.dllname = a[0]
+		f.dllfuncname = a[1]
+	default:
+		return nil, errors.New("Could not extract dll name from \"" + f.src + "\"")
+	}
+	return f, nil
+}
+
+// DLLName returns DLL name for function f.
+func (f *Fn) DLLName() string {
+	if f.dllname == "" {
+		return "kernel32"
+	}
+	return f.dllname
+}
+
+// DLLName returns DLL function name for function f.
+func (f *Fn) DLLFuncName() string {
+	if f.dllfuncname == "" {
+		return f.Name
+	}
+	return f.dllfuncname
+}
+
+// ParamList returns source code for function f parameters.
+func (f *Fn) ParamList() string {
+	return join(f.Params, func(p *Param) string { return p.Name + " " + p.Type }, ", ")
+}
+
+// HelperParamList returns source code for helper function f parameters.
+func (f *Fn) HelperParamList() string {
+	return join(f.Params, func(p *Param) string { return p.Name + " " + p.HelperType() }, ", ")
+}
+
+// ParamPrintList returns source code of trace printing part correspondent
+// to syscall input parameters.
+func (f *Fn) ParamPrintList() string {
+	return join(f.Params, func(p *Param) string { return fmt.Sprintf(`"%s=", %s, `, p.Name, p.Name) }, `", ", `)
+}
+
+// ParamCount return number of syscall parameters for function f.
+func (f *Fn) ParamCount() int {
+	n := 0
+	for _, p := range f.Params {
+		n += len(p.SyscallArgList())
+	}
+	return n
+}
+
+// SyscallParamCount determines which version of Syscall/Syscall6/Syscall9/...
+// to use. It returns parameter count for correspondent SyscallX function.
+func (f *Fn) SyscallParamCount() int {
+	n := f.ParamCount()
+	switch {
+	case n <= 3:
+		return 3
+	case n <= 6:
+		return 6
+	case n <= 9:
+		return 9
+	case n <= 12:
+		return 12
+	case n <= 15:
+		return 15
+	default:
+		panic("too many arguments to system call")
+	}
+}
+
+// Syscall determines which SyscallX function to use for function f.
+func (f *Fn) Syscall() string {
+	c := f.SyscallParamCount()
+	if c == 3 {
+		return syscalldot() + "Syscall"
+	}
+	return syscalldot() + "Syscall" + strconv.Itoa(c)
+}
+
+// SyscallParamList returns source code for SyscallX parameters for function f.
+func (f *Fn) SyscallParamList() string {
+	a := make([]string, 0)
+	for _, p := range f.Params {
+		a = append(a, p.SyscallArgList()...)
+	}
+	for len(a) < f.SyscallParamCount() {
+		a = append(a, "0")
+	}
+	return strings.Join(a, ", ")
+}
+
+// HelperCallParamList returns source code of call into function f helper.
+func (f *Fn) HelperCallParamList() string {
+	a := make([]string, 0, len(f.Params))
+	for _, p := range f.Params {
+		s := p.Name
+		if p.Type == "string" {
+			s = p.tmpVar()
+		}
+		a = append(a, s)
+	}
+	return strings.Join(a, ", ")
+}
+
+// IsUTF16 is true, if f is W (utf16) function. It is false
+// for all A (ascii) functions.
+func (f *Fn) IsUTF16() bool {
+	s := f.DLLFuncName()
+	return s[len(s)-1] == 'W'
+}
+
+// StrconvFunc returns name of Go string to OS string function for f.
+func (f *Fn) StrconvFunc() string {
+	if f.IsUTF16() {
+		return syscalldot() + "UTF16PtrFromString"
+	}
+	return syscalldot() + "BytePtrFromString"
+}
+
+// StrconvType returns Go type name used for OS string for f.
+func (f *Fn) StrconvType() string {
+	if f.IsUTF16() {
+		return "*uint16"
+	}
+	return "*byte"
+}
+
+// HasStringParam is true, if f has at least one string parameter.
+// Otherwise it is false.
+func (f *Fn) HasStringParam() bool {
+	for _, p := range f.Params {
+		if p.Type == "string" {
+			return true
+		}
+	}
+	return false
+}
+
+// HelperName returns name of function f helper.
+func (f *Fn) HelperName() string {
+	if !f.HasStringParam() {
+		return f.Name
+	}
+	return "_" + f.Name
+}
+
+// Source files and functions.
+type Source struct {
+	Funcs []*Fn
+	Files []string
+}
+
+// ParseFiles parses files listed in fs and extracts all syscall
+// functions listed in  sys comments. It returns source files
+// and functions collection *Source if successful.
+func ParseFiles(fs []string) (*Source, error) {
+	src := &Source{
+		Funcs: make([]*Fn, 0),
+		Files: make([]string, 0),
+	}
+	for _, file := range fs {
+		if err := src.ParseFile(file); err != nil {
+			return nil, err
+		}
+	}
+	return src, nil
+}
+
+// DLLs return dll names for a source set src.
+func (src *Source) DLLs() []string {
+	uniq := make(map[string]bool)
+	r := make([]string, 0)
+	for _, f := range src.Funcs {
+		name := f.DLLName()
+		if _, found := uniq[name]; !found {
+			uniq[name] = true
+			r = append(r, name)
+		}
+	}
+	return r
+}
+
+// ParseFile adds adition file path to a source set src.
+func (src *Source) ParseFile(path string) error {
+	file, err := os.Open(path)
+	if err != nil {
+		return err
+	}
+	defer file.Close()
+
+	s := bufio.NewScanner(file)
+	for s.Scan() {
+		t := trim(s.Text())
+		if len(t) < 7 {
+			continue
+		}
+		if !strings.HasPrefix(t, "//sys") {
+			continue
+		}
+		t = t[5:]
+		if !(t[0] == ' ' || t[0] == '\t') {
+			continue
+		}
+		f, err := newFn(t[1:])
+		if err != nil {
+			return err
+		}
+		src.Funcs = append(src.Funcs, f)
+	}
+	if err := s.Err(); err != nil {
+		return err
+	}
+	src.Files = append(src.Files, path)
+
+	// get package name
+	fset := token.NewFileSet()
+	_, err = file.Seek(0, 0)
+	if err != nil {
+		return err
+	}
+	pkg, err := parser.ParseFile(fset, "", file, parser.PackageClauseOnly)
+	if err != nil {
+		return err
+	}
+	packageName = pkg.Name.Name
+
+	return nil
+}
+
+// Generate output source file from a source set src.
+func (src *Source) Generate(w io.Writer) error {
+	funcMap := template.FuncMap{
+		"syscalldot":  syscalldot,
+		"packagename": packagename,
+	}
+	t := template.Must(template.New("main").Funcs(funcMap).Parse(srcTemplate))
+	err := t.Execute(w, src)
+	if err != nil {
+		return errors.New("Failed to execute template: " + err.Error())
+	}
+	return nil
+}
+
+func usage() {
+	fmt.Fprintf(os.Stderr, "usage: mksyscall_windows [flags] [path ...]\n")
+	flag.PrintDefaults()
+	os.Exit(1)
+}
+
+func main() {
+	flag.Usage = usage
+	flag.Parse()
+	if len(os.Args) <= 1 {
+		fmt.Fprintf(os.Stderr, "no files to parse provided\n")
+		usage()
+	}
+	src, err := ParseFiles(os.Args[1:])
+	if err != nil {
+		log.Fatal(err)
+	}
+	if err := src.Generate(os.Stdout); err != nil {
+		log.Fatal(err)
+	}
+}
+
+// TODO: use println instead to print in the following template
+const srcTemplate = `
+
+{{define "main"}}// go build mksyscall_windows.go && ./mksyscall_windows{{range .Files}} {{.}}{{end}}
+// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
+
+package {{packagename}}
+
+import "unsafe"{{if syscalldot}}
+import "syscall"{{end}}
+
+var (
+{{template "dlls" .}}
+{{template "funcnames" .}})
+{{range .Funcs}}{{if .HasStringParam}}{{template "helperbody" .}}{{end}}{{template "funcbody" .}}{{end}}
+{{end}}
+
+{{/* help functions */}}
+
+{{define "dlls"}}{{range .DLLs}}	mod{{.}} = {{syscalldot}}NewLazyDLL("{{.}}.dll")
+{{end}}{{end}}
+
+{{define "funcnames"}}{{range .Funcs}}	proc{{.DLLFuncName}} = mod{{.DLLName}}.NewProc("{{.DLLFuncName}}")
+{{end}}{{end}}
+
+{{define "helperbody"}}
+func {{.Name}}({{.ParamList}}) {{template "results" .}}{
+{{template "helpertmpvars" .}}	return {{.HelperName}}({{.HelperCallParamList}})
+}
+{{end}}
+
+{{define "funcbody"}}
+func {{.HelperName}}({{.HelperParamList}}) {{template "results" .}}{
+{{template "tmpvars" .}}	{{template "syscall" .}}
+{{template "seterror" .}}{{template "printtrace" .}}	return
+}
+{{end}}
+
+{{define "helpertmpvars"}}{{range .Params}}{{if .TmpVarHelperCode}}	{{.TmpVarHelperCode}}
+{{end}}{{end}}{{end}}
+
+{{define "tmpvars"}}{{range .Params}}{{if .TmpVarCode}}	{{.TmpVarCode}}
+{{end}}{{end}}{{end}}
+
+{{define "results"}}{{if .Rets.List}}{{.Rets.List}} {{end}}{{end}}
+
+{{define "syscall"}}{{.Rets.SetReturnValuesCode}}{{.Syscall}}(proc{{.DLLFuncName}}.Addr(), {{.ParamCount}}, {{.SyscallParamList}}){{end}}
+
+{{define "seterror"}}{{if .Rets.SetErrorCode}}	{{.Rets.SetErrorCode}}
+{{end}}{{end}}
+
+{{define "printtrace"}}{{if .PrintTrace}}	print("SYSCALL: {{.Name}}(", {{.ParamPrintList}}") (", {{.Rets.PrintList}}")\n")
+{{end}}{{end}}
+
+`
diff --git a/src/pkg/syscall/mksysctl_openbsd.pl b/src/syscall/mksysctl_openbsd.pl
similarity index 100%
rename from src/pkg/syscall/mksysctl_openbsd.pl
rename to src/syscall/mksysctl_openbsd.pl
diff --git a/src/pkg/syscall/mksysnum_darwin.pl b/src/syscall/mksysnum_darwin.pl
similarity index 100%
rename from src/pkg/syscall/mksysnum_darwin.pl
rename to src/syscall/mksysnum_darwin.pl
diff --git a/src/pkg/syscall/mksysnum_dragonfly.pl b/src/syscall/mksysnum_dragonfly.pl
similarity index 100%
rename from src/pkg/syscall/mksysnum_dragonfly.pl
rename to src/syscall/mksysnum_dragonfly.pl
diff --git a/src/pkg/syscall/mksysnum_freebsd.pl b/src/syscall/mksysnum_freebsd.pl
similarity index 100%
rename from src/pkg/syscall/mksysnum_freebsd.pl
rename to src/syscall/mksysnum_freebsd.pl
diff --git a/src/pkg/syscall/mksysnum_linux.pl b/src/syscall/mksysnum_linux.pl
similarity index 100%
rename from src/pkg/syscall/mksysnum_linux.pl
rename to src/syscall/mksysnum_linux.pl
diff --git a/src/pkg/syscall/mksysnum_netbsd.pl b/src/syscall/mksysnum_netbsd.pl
similarity index 100%
rename from src/pkg/syscall/mksysnum_netbsd.pl
rename to src/syscall/mksysnum_netbsd.pl
diff --git a/src/pkg/syscall/mksysnum_openbsd.pl b/src/syscall/mksysnum_openbsd.pl
similarity index 100%
rename from src/pkg/syscall/mksysnum_openbsd.pl
rename to src/syscall/mksysnum_openbsd.pl
diff --git a/src/pkg/syscall/mksysnum_plan9.sh b/src/syscall/mksysnum_plan9.sh
similarity index 100%
rename from src/pkg/syscall/mksysnum_plan9.sh
rename to src/syscall/mksysnum_plan9.sh
diff --git a/src/pkg/syscall/mmap_unix_test.go b/src/syscall/mmap_unix_test.go
similarity index 100%
rename from src/pkg/syscall/mmap_unix_test.go
rename to src/syscall/mmap_unix_test.go
diff --git a/src/syscall/net_nacl.go b/src/syscall/net_nacl.go
new file mode 100644
index 0000000..b5cb530
--- /dev/null
+++ b/src/syscall/net_nacl.go
@@ -0,0 +1,913 @@
+// Copyright 2013 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// A simulated network for use within NaCl.
+// The simulation is not particularly tied to NaCl,
+// but other systems have real networks.
+
+package syscall
+
+import (
+	"sync"
+	"sync/atomic"
+)
+
+// Interface to timers implemented in package runtime.
+// Must be in sync with ../runtime/runtime.h:/^struct.Timer$
+// Really for use by package time, but we cannot import time here.
+
+type runtimeTimer struct {
+	i      int
+	when   int64
+	period int64
+	f      func(interface{}, uintptr) // NOTE: must not be closure
+	arg    interface{}
+	seq    uintptr
+}
+
+func startTimer(*runtimeTimer)
+func stopTimer(*runtimeTimer) bool
+
+type timer struct {
+	expired bool
+	q       *queue
+	r       runtimeTimer
+}
+
+func (t *timer) start(q *queue, deadline int64) {
+	if deadline == 0 {
+		return
+	}
+	t.q = q
+	t.r.when = deadline
+	t.r.f = timerExpired
+	t.r.arg = t
+	startTimer(&t.r)
+}
+
+func (t *timer) stop() {
+	stopTimer(&t.r)
+}
+
+func timerExpired(i interface{}, seq uintptr) {
+	t := i.(*timer)
+	go func() {
+		t.q.Lock()
+		defer t.q.Unlock()
+		t.expired = true
+		t.q.canRead.Broadcast()
+		t.q.canWrite.Broadcast()
+	}()
+}
+
+// Network constants and data structures. These match the traditional values.
+
+const (
+	AF_UNSPEC = iota
+	AF_UNIX
+	AF_INET
+	AF_INET6
+)
+
+const (
+	SHUT_RD = iota
+	SHUT_WR
+	SHUT_RDWR
+)
+
+const (
+	SOCK_STREAM = 1 + iota
+	SOCK_DGRAM
+	SOCK_RAW
+	SOCK_SEQPACKET
+)
+
+const (
+	IPPROTO_IP   = 0
+	IPPROTO_IPV4 = 4
+	IPPROTO_IPV6 = 0x29
+	IPPROTO_TCP  = 6
+	IPPROTO_UDP  = 0x11
+)
+
+// Misc constants expected by package net but not supported.
+const (
+	_ = iota
+	SOL_SOCKET
+	SO_TYPE
+	NET_RT_IFLIST
+	IFNAMSIZ
+	IFF_UP
+	IFF_BROADCAST
+	IFF_LOOPBACK
+	IFF_POINTOPOINT
+	IFF_MULTICAST
+	IPV6_V6ONLY
+	SOMAXCONN
+	F_DUPFD_CLOEXEC
+	SO_BROADCAST
+	SO_REUSEADDR
+	SO_REUSEPORT
+	SO_RCVBUF
+	SO_SNDBUF
+	SO_KEEPALIVE
+	SO_LINGER
+	SO_ERROR
+	IP_PORTRANGE
+	IP_PORTRANGE_DEFAULT
+	IP_PORTRANGE_LOW
+	IP_PORTRANGE_HIGH
+	IP_MULTICAST_IF
+	IP_MULTICAST_LOOP
+	IP_ADD_MEMBERSHIP
+	IPV6_PORTRANGE
+	IPV6_PORTRANGE_DEFAULT
+	IPV6_PORTRANGE_LOW
+	IPV6_PORTRANGE_HIGH
+	IPV6_MULTICAST_IF
+	IPV6_MULTICAST_LOOP
+	IPV6_JOIN_GROUP
+	TCP_NODELAY
+	TCP_KEEPINTVL
+	TCP_KEEPIDLE
+
+	SYS_FCNTL = 500 // unsupported
+)
+
+var SocketDisableIPv6 bool
+
+// A Sockaddr is one of the SockaddrXxx structs.
+type Sockaddr interface {
+	// copy returns a copy of the underlying data.
+	copy() Sockaddr
+
+	// key returns the value of the underlying data,
+	// for comparison as a map key.
+	key() interface{}
+}
+
+type SockaddrInet4 struct {
+	Port int
+	Addr [4]byte
+}
+
+func (sa *SockaddrInet4) copy() Sockaddr {
+	sa1 := *sa
+	return &sa1
+}
+
+func (sa *SockaddrInet4) key() interface{} { return *sa }
+
+type SockaddrInet6 struct {
+	Port   int
+	ZoneId uint32
+	Addr   [16]byte
+}
+
+func (sa *SockaddrInet6) copy() Sockaddr {
+	sa1 := *sa
+	return &sa1
+}
+
+func (sa *SockaddrInet6) key() interface{} { return *sa }
+
+type SockaddrUnix struct {
+	Name string
+}
+
+func (sa *SockaddrUnix) copy() Sockaddr {
+	sa1 := *sa
+	return &sa1
+}
+
+func (sa *SockaddrUnix) key() interface{} { return *sa }
+
+type SockaddrDatalink struct {
+	Len    uint8
+	Family uint8
+	Index  uint16
+	Type   uint8
+	Nlen   uint8
+	Alen   uint8
+	Slen   uint8
+	Data   [12]int8
+}
+
+func (sa *SockaddrDatalink) copy() Sockaddr {
+	sa1 := *sa
+	return &sa1
+}
+
+func (sa *SockaddrDatalink) key() interface{} { return *sa }
+
+// RoutingMessage represents a routing message.
+type RoutingMessage interface {
+	unimplemented()
+}
+
+type IPMreq struct {
+	Multiaddr [4]byte /* in_addr */
+	Interface [4]byte /* in_addr */
+}
+
+type IPv6Mreq struct {
+	Multiaddr [16]byte /* in6_addr */
+	Interface uint32
+}
+
+type Linger struct {
+	Onoff  int32
+	Linger int32
+}
+
+type ICMPv6Filter struct {
+	Filt [8]uint32
+}
+
+// A queue is the bookkeeping for a synchronized buffered queue.
+// We do not use channels because we need to be able to handle
+// writes after and during close, and because a chan byte would
+// require too many send and receive operations in real use.
+type queue struct {
+	sync.Mutex
+	canRead  sync.Cond
+	canWrite sync.Cond
+	r        int // total read index
+	w        int // total write index
+	m        int // index mask
+	closed   bool
+}
+
+func (q *queue) init(size int) {
+	if size&(size-1) != 0 {
+		panic("invalid queue size - must be power of two")
+	}
+	q.canRead.L = &q.Mutex
+	q.canWrite.L = &q.Mutex
+	q.m = size - 1
+}
+
+func past(deadline int64) bool {
+	sec, nsec := now()
+	return deadline > 0 && deadline < sec*1e9+int64(nsec)
+}
+
+func (q *queue) waitRead(n int, deadline int64) (int, error) {
+	if past(deadline) {
+		return 0, EAGAIN
+	}
+	var t timer
+	t.start(q, deadline)
+	for q.w-q.r == 0 && !q.closed && !t.expired {
+		q.canRead.Wait()
+	}
+	t.stop()
+	m := q.w - q.r
+	if m == 0 && t.expired {
+		return 0, EAGAIN
+	}
+	if m > n {
+		m = n
+		q.canRead.Signal() // wake up next reader too
+	}
+	q.canWrite.Signal()
+	return m, nil
+}
+
+func (q *queue) waitWrite(n int, deadline int64) (int, error) {
+	if past(deadline) {
+		return 0, EAGAIN
+	}
+	var t timer
+	t.start(q, deadline)
+	for q.w-q.r > q.m && !q.closed && !t.expired {
+		q.canWrite.Wait()
+	}
+	t.stop()
+	m := q.m + 1 - (q.w - q.r)
+	if m == 0 && t.expired {
+		return 0, EAGAIN
+	}
+	if m == 0 {
+		return 0, EAGAIN
+	}
+	if m > n {
+		m = n
+		q.canWrite.Signal() // wake up next writer too
+	}
+	q.canRead.Signal()
+	return m, nil
+}
+
+func (q *queue) close() {
+	q.Lock()
+	defer q.Unlock()
+	q.closed = true
+	q.canRead.Broadcast()
+	q.canWrite.Broadcast()
+}
+
+// A byteq is a byte queue.
+type byteq struct {
+	queue
+	data []byte
+}
+
+func newByteq() *byteq {
+	q := &byteq{
+		data: make([]byte, 4096),
+	}
+	q.init(len(q.data))
+	return q
+}
+
+func (q *byteq) read(b []byte, deadline int64) (int, error) {
+	q.Lock()
+	defer q.Unlock()
+	n, err := q.waitRead(len(b), deadline)
+	if err != nil {
+		return 0, err
+	}
+	b = b[:n]
+	for len(b) > 0 {
+		m := copy(b, q.data[q.r&q.m:])
+		q.r += m
+		b = b[m:]
+	}
+	return n, nil
+}
+
+func (q *byteq) write(b []byte, deadline int64) (n int, err error) {
+	q.Lock()
+	defer q.Unlock()
+	for n < len(b) {
+		nn, err := q.waitWrite(len(b[n:]), deadline)
+		if err != nil {
+			return n, err
+		}
+		bb := b[n : n+nn]
+		n += nn
+		for len(bb) > 0 {
+			m := copy(q.data[q.w&q.m:], bb)
+			q.w += m
+			bb = bb[m:]
+		}
+	}
+	return n, nil
+}
+
+// A msgq is a queue of messages.
+type msgq struct {
+	queue
+	data []interface{}
+}
+
+func newMsgq() *msgq {
+	q := &msgq{
+		data: make([]interface{}, 32),
+	}
+	q.init(len(q.data))
+	return q
+}
+
+func (q *msgq) read(deadline int64) (interface{}, error) {
+	q.Lock()
+	defer q.Unlock()
+	n, err := q.waitRead(1, deadline)
+	if err != nil {
+		return nil, err
+	}
+	if n == 0 {
+		return nil, nil
+	}
+	m := q.data[q.r&q.m]
+	q.r++
+	return m, nil
+}
+
+func (q *msgq) write(m interface{}, deadline int64) error {
+	q.Lock()
+	defer q.Unlock()
+	_, err := q.waitWrite(1, deadline)
+	if err != nil {
+		return err
+	}
+	q.data[q.w&q.m] = m
+	q.w++
+	return nil
+}
+
+// An addr is a sequence of bytes uniquely identifying a network address.
+// It is not human-readable.
+type addr string
+
+// A conn is one side of a stream-based network connection.
+// That is, a stream-based network connection is a pair of cross-connected conns.
+type conn struct {
+	rd     *byteq
+	wr     *byteq
+	local  addr
+	remote addr
+}
+
+// A pktconn is one side of a packet-based network connection.
+// That is, a packet-based network connection is a pair of cross-connected pktconns.
+type pktconn struct {
+	rd     *msgq
+	wr     *msgq
+	local  addr
+	remote addr
+}
+
+// A listener accepts incoming stream-based network connections.
+type listener struct {
+	rd    *msgq
+	local addr
+}
+
+// A netFile is an open network file.
+type netFile struct {
+	defaultFileImpl
+	proto      *netproto
+	sotype     int
+	listener   *msgq
+	packet     *msgq
+	rd         *byteq
+	wr         *byteq
+	rddeadline int64
+	wrdeadline int64
+	addr       Sockaddr
+	raddr      Sockaddr
+}
+
+// A netAddr is a network address in the global listener map.
+// All the fields must have defined == operations.
+type netAddr struct {
+	proto  *netproto
+	sotype int
+	addr   interface{}
+}
+
+// net records the state of the network.
+// It maps a network address to the listener on that address.
+var net = struct {
+	sync.Mutex
+	listener map[netAddr]*netFile
+}{
+	listener: make(map[netAddr]*netFile),
+}
+
+// TODO(rsc): Some day, do a better job with port allocation.
+// For playground programs, incrementing is fine.
+var nextport = 2
+
+// A netproto contains protocol-specific functionality
+// (one for AF_INET, one for AF_INET6 and so on).
+// It is a struct instead of an interface because the
+// implementation needs no state, and I expect to
+// add some data fields at some point.
+type netproto struct {
+	bind func(*netFile, Sockaddr) error
+}
+
+var netprotoAF_INET = &netproto{
+	bind: func(f *netFile, sa Sockaddr) error {
+		if sa == nil {
+			f.addr = &SockaddrInet4{
+				Port: nextport,
+				Addr: [4]byte{127, 0, 0, 1},
+			}
+			nextport++
+			return nil
+		}
+		addr, ok := sa.(*SockaddrInet4)
+		if !ok {
+			return EINVAL
+		}
+		addr = addr.copy().(*SockaddrInet4)
+		if addr.Port == 0 {
+			addr.Port = nextport
+			nextport++
+		}
+		f.addr = addr
+		return nil
+	},
+}
+
+var netprotos = map[int]*netproto{
+	AF_INET: netprotoAF_INET,
+}
+
+// These functions implement the usual BSD socket operations.
+
+func (f *netFile) bind(sa Sockaddr) error {
+	if f.addr != nil {
+		return EISCONN
+	}
+	if err := f.proto.bind(f, sa); err != nil {
+		return err
+	}
+	if f.sotype == SOCK_DGRAM {
+		_, ok := net.listener[netAddr{f.proto, f.sotype, f.addr.key()}]
+		if ok {
+			f.addr = nil
+			return EADDRINUSE
+		}
+		net.listener[netAddr{f.proto, f.sotype, f.addr.key()}] = f
+		f.packet = newMsgq()
+	}
+	return nil
+}
+
+func (f *netFile) listen(backlog int) error {
+	net.Lock()
+	defer net.Unlock()
+	if f.listener != nil {
+		return EINVAL
+	}
+	_, ok := net.listener[netAddr{f.proto, f.sotype, f.addr.key()}]
+	if ok {
+		return EADDRINUSE
+	}
+	net.listener[netAddr{f.proto, f.sotype, f.addr.key()}] = f
+	f.listener = newMsgq()
+	return nil
+}
+
+func (f *netFile) accept() (fd int, sa Sockaddr, err error) {
+	msg, err := f.listener.read(f.readDeadline())
+	if err != nil {
+		return -1, nil, err
+	}
+	newf, ok := msg.(*netFile)
+	if !ok {
+		// must be eof
+		return -1, nil, EAGAIN
+	}
+	return newFD(newf), newf.raddr.copy(), nil
+}
+
+func (f *netFile) connect(sa Sockaddr) error {
+	if past(f.writeDeadline()) {
+		return EAGAIN
+	}
+	if f.addr == nil {
+		if err := f.bind(nil); err != nil {
+			return err
+		}
+	}
+	net.Lock()
+	if sa == nil {
+		net.Unlock()
+		return EINVAL
+	}
+	sa = sa.copy()
+	if f.raddr != nil {
+		net.Unlock()
+		return EISCONN
+	}
+	if f.sotype == SOCK_DGRAM {
+		net.Unlock()
+		f.raddr = sa
+		return nil
+	}
+	if f.listener != nil {
+		net.Unlock()
+		return EISCONN
+	}
+	l, ok := net.listener[netAddr{f.proto, f.sotype, sa.key()}]
+	if !ok {
+		net.Unlock()
+		return ECONNREFUSED
+	}
+	f.raddr = sa
+	f.rd = newByteq()
+	f.wr = newByteq()
+	newf := &netFile{
+		proto:  f.proto,
+		sotype: f.sotype,
+		addr:   f.raddr,
+		raddr:  f.addr,
+		rd:     f.wr,
+		wr:     f.rd,
+	}
+	net.Unlock()
+	l.listener.write(newf, f.writeDeadline())
+	return nil
+}
+
+func (f *netFile) read(b []byte) (int, error) {
+	if f.rd == nil {
+		if f.raddr != nil {
+			n, _, err := f.recvfrom(b, 0)
+			return n, err
+		}
+		return 0, ENOTCONN
+	}
+	return f.rd.read(b, f.readDeadline())
+}
+
+func (f *netFile) write(b []byte) (int, error) {
+	if f.wr == nil {
+		if f.raddr != nil {
+			err := f.sendto(b, 0, f.raddr)
+			var n int
+			if err == nil {
+				n = len(b)
+			}
+			return n, err
+		}
+		return 0, ENOTCONN
+	}
+	return f.wr.write(b, f.writeDeadline())
+}
+
+type pktmsg struct {
+	buf  []byte
+	addr Sockaddr
+}
+
+func (f *netFile) recvfrom(p []byte, flags int) (n int, from Sockaddr, err error) {
+	if f.sotype != SOCK_DGRAM {
+		return 0, nil, EINVAL
+	}
+	if f.packet == nil {
+		return 0, nil, ENOTCONN
+	}
+	msg1, err := f.packet.read(f.readDeadline())
+	if err != nil {
+		return 0, nil, err
+	}
+	msg, ok := msg1.(*pktmsg)
+	if !ok {
+		return 0, nil, EAGAIN
+	}
+	return copy(p, msg.buf), msg.addr, nil
+}
+
+func (f *netFile) sendto(p []byte, flags int, to Sockaddr) error {
+	if f.sotype != SOCK_DGRAM {
+		return EINVAL
+	}
+	if f.packet == nil {
+		if err := f.bind(nil); err != nil {
+			return err
+		}
+	}
+	net.Lock()
+	if to == nil {
+		net.Unlock()
+		return EINVAL
+	}
+	to = to.copy()
+	l, ok := net.listener[netAddr{f.proto, f.sotype, to.key()}]
+	if !ok || l.packet == nil {
+		net.Unlock()
+		return ECONNREFUSED
+	}
+	net.Unlock()
+	msg := &pktmsg{
+		buf:  make([]byte, len(p)),
+		addr: f.addr,
+	}
+	copy(msg.buf, p)
+	l.packet.write(msg, f.writeDeadline())
+	return nil
+}
+
+func (f *netFile) close() error {
+	if f.listener != nil {
+		f.listener.close()
+	}
+	if f.packet != nil {
+		f.packet.close()
+	}
+	if f.rd != nil {
+		f.rd.close()
+	}
+	if f.wr != nil {
+		f.wr.close()
+	}
+	return nil
+}
+
+func fdToNetFile(fd int) (*netFile, error) {
+	f, err := fdToFile(fd)
+	if err != nil {
+		return nil, err
+	}
+	impl := f.impl
+	netf, ok := impl.(*netFile)
+	if !ok {
+		return nil, EINVAL
+	}
+	return netf, nil
+}
+
+func Socket(proto, sotype, unused int) (fd int, err error) {
+	p := netprotos[proto]
+	if p == nil {
+		return -1, EPROTONOSUPPORT
+	}
+	if sotype != SOCK_STREAM && sotype != SOCK_DGRAM {
+		return -1, ESOCKTNOSUPPORT
+	}
+	f := &netFile{
+		proto:  p,
+		sotype: sotype,
+	}
+	return newFD(f), nil
+}
+
+func Bind(fd int, sa Sockaddr) error {
+	f, err := fdToNetFile(fd)
+	if err != nil {
+		return err
+	}
+	return f.bind(sa)
+}
+
+func StopIO(fd int) error {
+	f, err := fdToNetFile(fd)
+	if err != nil {
+		return err
+	}
+	f.close()
+	return nil
+}
+
+func Listen(fd int, backlog int) error {
+	f, err := fdToNetFile(fd)
+	if err != nil {
+		return err
+	}
+	return f.listen(backlog)
+}
+
+func Accept(fd int) (newfd int, sa Sockaddr, err error) {
+	f, err := fdToNetFile(fd)
+	if err != nil {
+		return 0, nil, err
+	}
+	return f.accept()
+}
+
+func Getsockname(fd int) (sa Sockaddr, err error) {
+	f, err := fdToNetFile(fd)
+	if err != nil {
+		return nil, err
+	}
+	if f.addr == nil {
+		return nil, ENOTCONN
+	}
+	return f.addr.copy(), nil
+}
+
+func Getpeername(fd int) (sa Sockaddr, err error) {
+	f, err := fdToNetFile(fd)
+	if err != nil {
+		return nil, err
+	}
+	if f.raddr == nil {
+		return nil, ENOTCONN
+	}
+	return f.raddr.copy(), nil
+}
+
+func Connect(fd int, sa Sockaddr) error {
+	f, err := fdToNetFile(fd)
+	if err != nil {
+		return err
+	}
+	return f.connect(sa)
+}
+
+func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, err error) {
+	f, err := fdToNetFile(fd)
+	if err != nil {
+		return 0, nil, err
+	}
+	return f.recvfrom(p, flags)
+}
+
+func Sendto(fd int, p []byte, flags int, to Sockaddr) error {
+	f, err := fdToNetFile(fd)
+	if err != nil {
+		return err
+	}
+	return f.sendto(p, flags, to)
+}
+
+func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn, recvflags int, from Sockaddr, err error) {
+	f, err := fdToNetFile(fd)
+	if err != nil {
+		return
+	}
+	n, from, err = f.recvfrom(p, flags)
+	return
+}
+
+func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) error {
+	_, err := SendmsgN(fd, p, oob, to, flags)
+	return err
+}
+
+func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) {
+	f, err := fdToNetFile(fd)
+	if err != nil {
+		return 0, err
+	}
+	switch f.sotype {
+	case SOCK_STREAM:
+		n, err = f.write(p)
+	case SOCK_DGRAM:
+		n = len(p)
+		err = f.sendto(p, flags, to)
+	}
+	if err != nil {
+		return 0, err
+	}
+	return n, nil
+}
+
+func GetsockoptInt(fd, level, opt int) (value int, err error) {
+	f, err := fdToNetFile(fd)
+	if err != nil {
+		return 0, err
+	}
+	switch {
+	case level == SOL_SOCKET && opt == SO_TYPE:
+		return f.sotype, nil
+	}
+	return 0, ENOTSUP
+}
+
+func SetsockoptInt(fd, level, opt int, value int) error {
+	return nil
+}
+
+func SetsockoptByte(fd, level, opt int, value byte) error {
+	_, err := fdToNetFile(fd)
+	if err != nil {
+		return err
+	}
+	return ENOTSUP
+}
+
+func SetsockoptLinger(fd, level, opt int, l *Linger) error {
+	return nil
+}
+
+func SetReadDeadline(fd int, t int64) error {
+	f, err := fdToNetFile(fd)
+	if err != nil {
+		return err
+	}
+	atomic.StoreInt64(&f.rddeadline, t)
+	return nil
+}
+
+func (f *netFile) readDeadline() int64 {
+	return atomic.LoadInt64(&f.rddeadline)
+}
+
+func SetWriteDeadline(fd int, t int64) error {
+	f, err := fdToNetFile(fd)
+	if err != nil {
+		return err
+	}
+	atomic.StoreInt64(&f.wrdeadline, t)
+	return nil
+}
+
+func (f *netFile) writeDeadline() int64 {
+	return atomic.LoadInt64(&f.wrdeadline)
+}
+
+func Shutdown(fd int, how int) error {
+	f, err := fdToNetFile(fd)
+	if err != nil {
+		return err
+	}
+	switch how {
+	case SHUT_RD:
+		f.rd.close()
+	case SHUT_WR:
+		f.wr.close()
+	case SHUT_RDWR:
+		f.rd.close()
+		f.wr.close()
+	}
+	return nil
+}
+
+func SetsockoptICMPv6Filter(fd, level, opt int, filter *ICMPv6Filter) error { panic("SetsockoptICMPv") }
+func SetsockoptIPMreq(fd, level, opt int, mreq *IPMreq) error               { panic("SetsockoptIPMreq") }
+func SetsockoptIPv6Mreq(fd, level, opt int, mreq *IPv6Mreq) error           { panic("SetsockoptIPv") }
+func SetsockoptInet4Addr(fd, level, opt int, value [4]byte) error           { panic("SetsockoptInet") }
+func SetsockoptString(fd, level, opt int, s string) error                   { panic("SetsockoptString") }
+func SetsockoptTimeval(fd, level, opt int, tv *Timeval) error               { panic("SetsockoptTimeval") }
+func Socketpair(domain, typ, proto int) (fd [2]int, err error)              { panic("Socketpair") }
+
+func SetNonblock(fd int, nonblocking bool) error { return nil }
diff --git a/src/syscall/netlink_linux.go b/src/syscall/netlink_linux.go
new file mode 100644
index 0000000..1b73dce
--- /dev/null
+++ b/src/syscall/netlink_linux.go
@@ -0,0 +1,178 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Netlink sockets and messages
+
+package syscall
+
+import "unsafe"
+
+// Round the length of a netlink message up to align it properly.
+func nlmAlignOf(msglen int) int {
+	return (msglen + NLMSG_ALIGNTO - 1) & ^(NLMSG_ALIGNTO - 1)
+}
+
+// Round the length of a netlink route attribute up to align it
+// properly.
+func rtaAlignOf(attrlen int) int {
+	return (attrlen + RTA_ALIGNTO - 1) & ^(RTA_ALIGNTO - 1)
+}
+
+// NetlinkRouteRequest represents a request message to receive routing
+// and link states from the kernel.
+type NetlinkRouteRequest struct {
+	Header NlMsghdr
+	Data   RtGenmsg
+}
+
+func (rr *NetlinkRouteRequest) toWireFormat() []byte {
+	b := make([]byte, rr.Header.Len)
+	*(*uint32)(unsafe.Pointer(&b[0:4][0])) = rr.Header.Len
+	*(*uint16)(unsafe.Pointer(&b[4:6][0])) = rr.Header.Type
+	*(*uint16)(unsafe.Pointer(&b[6:8][0])) = rr.Header.Flags
+	*(*uint32)(unsafe.Pointer(&b[8:12][0])) = rr.Header.Seq
+	*(*uint32)(unsafe.Pointer(&b[12:16][0])) = rr.Header.Pid
+	b[16] = byte(rr.Data.Family)
+	return b
+}
+
+func newNetlinkRouteRequest(proto, seq, family int) []byte {
+	rr := &NetlinkRouteRequest{}
+	rr.Header.Len = uint32(NLMSG_HDRLEN + SizeofRtGenmsg)
+	rr.Header.Type = uint16(proto)
+	rr.Header.Flags = NLM_F_DUMP | NLM_F_REQUEST
+	rr.Header.Seq = uint32(seq)
+	rr.Data.Family = uint8(family)
+	return rr.toWireFormat()
+}
+
+// NetlinkRIB returns routing information base, as known as RIB, which
+// consists of network facility information, states and parameters.
+func NetlinkRIB(proto, family int) ([]byte, error) {
+	s, err := Socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE)
+	if err != nil {
+		return nil, err
+	}
+	defer Close(s)
+	lsa := &SockaddrNetlink{Family: AF_NETLINK}
+	if err := Bind(s, lsa); err != nil {
+		return nil, err
+	}
+	wb := newNetlinkRouteRequest(proto, 1, family)
+	if err := Sendto(s, wb, 0, lsa); err != nil {
+		return nil, err
+	}
+	var tab []byte
+	rbNew := make([]byte, Getpagesize())
+done:
+	for {
+		rb := rbNew
+		nr, _, err := Recvfrom(s, rb, 0)
+		if err != nil {
+			return nil, err
+		}
+		if nr < NLMSG_HDRLEN {
+			return nil, EINVAL
+		}
+		rb = rb[:nr]
+		tab = append(tab, rb...)
+		msgs, err := ParseNetlinkMessage(rb)
+		if err != nil {
+			return nil, err
+		}
+		for _, m := range msgs {
+			lsa, err := Getsockname(s)
+			if err != nil {
+				return nil, err
+			}
+			switch v := lsa.(type) {
+			case *SockaddrNetlink:
+				if m.Header.Seq != 1 || m.Header.Pid != v.Pid {
+					return nil, EINVAL
+				}
+			default:
+				return nil, EINVAL
+			}
+			if m.Header.Type == NLMSG_DONE {
+				break done
+			}
+			if m.Header.Type == NLMSG_ERROR {
+				return nil, EINVAL
+			}
+		}
+	}
+	return tab, nil
+}
+
+// NetlinkMessage represents a netlink message.
+type NetlinkMessage struct {
+	Header NlMsghdr
+	Data   []byte
+}
+
+// ParseNetlinkMessage parses b as an array of netlink messages and
+// returns the slice containing the NetlinkMessage structures.
+func ParseNetlinkMessage(b []byte) ([]NetlinkMessage, error) {
+	var msgs []NetlinkMessage
+	for len(b) >= NLMSG_HDRLEN {
+		h, dbuf, dlen, err := netlinkMessageHeaderAndData(b)
+		if err != nil {
+			return nil, err
+		}
+		m := NetlinkMessage{Header: *h, Data: dbuf[:int(h.Len)-NLMSG_HDRLEN]}
+		msgs = append(msgs, m)
+		b = b[dlen:]
+	}
+	return msgs, nil
+}
+
+func netlinkMessageHeaderAndData(b []byte) (*NlMsghdr, []byte, int, error) {
+	h := (*NlMsghdr)(unsafe.Pointer(&b[0]))
+	if int(h.Len) < NLMSG_HDRLEN || int(h.Len) > len(b) {
+		return nil, nil, 0, EINVAL
+	}
+	return h, b[NLMSG_HDRLEN:], nlmAlignOf(int(h.Len)), nil
+}
+
+// NetlinkRouteAttr represents a netlink route attribute.
+type NetlinkRouteAttr struct {
+	Attr  RtAttr
+	Value []byte
+}
+
+// ParseNetlinkRouteAttr parses m's payload as an array of netlink
+// route attributes and returns the slice containing the
+// NetlinkRouteAttr structures.
+func ParseNetlinkRouteAttr(m *NetlinkMessage) ([]NetlinkRouteAttr, error) {
+	var b []byte
+	switch m.Header.Type {
+	case RTM_NEWLINK, RTM_DELLINK:
+		b = m.Data[SizeofIfInfomsg:]
+	case RTM_NEWADDR, RTM_DELADDR:
+		b = m.Data[SizeofIfAddrmsg:]
+	case RTM_NEWROUTE, RTM_DELROUTE:
+		b = m.Data[SizeofRtMsg:]
+	default:
+		return nil, EINVAL
+	}
+	var attrs []NetlinkRouteAttr
+	for len(b) >= SizeofRtAttr {
+		a, vbuf, alen, err := netlinkRouteAttrAndValue(b)
+		if err != nil {
+			return nil, err
+		}
+		ra := NetlinkRouteAttr{Attr: *a, Value: vbuf[:int(a.Len)-SizeofRtAttr]}
+		attrs = append(attrs, ra)
+		b = b[alen:]
+	}
+	return attrs, nil
+}
+
+func netlinkRouteAttrAndValue(b []byte) (*RtAttr, []byte, int, error) {
+	a := (*RtAttr)(unsafe.Pointer(&b[0]))
+	if int(a.Len) < SizeofRtAttr || int(a.Len) > len(b) {
+		return nil, nil, 0, EINVAL
+	}
+	return a, b[SizeofRtAttr:], rtaAlignOf(int(a.Len)), nil
+}
diff --git a/src/pkg/syscall/race.go b/src/syscall/race.go
similarity index 100%
rename from src/pkg/syscall/race.go
rename to src/syscall/race.go
diff --git a/src/pkg/syscall/race0.go b/src/syscall/race0.go
similarity index 100%
rename from src/pkg/syscall/race0.go
rename to src/syscall/race0.go
diff --git a/src/syscall/route_bsd.go b/src/syscall/route_bsd.go
new file mode 100644
index 0000000..1dabe42
--- /dev/null
+++ b/src/syscall/route_bsd.go
@@ -0,0 +1,224 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin dragonfly freebsd netbsd openbsd
+
+// Routing sockets and messages
+
+package syscall
+
+import "unsafe"
+
+// Round the length of a raw sockaddr up to align it properly.
+func rsaAlignOf(salen int) int {
+	salign := sizeofPtr
+	// NOTE: It seems like 64-bit Darwin kernel still requires
+	// 32-bit aligned access to BSD subsystem. Also NetBSD 6
+	// kernel and beyond require 64-bit aligned access to routing
+	// facilities.
+	if darwin64Bit {
+		salign = 4
+	} else if netbsd32Bit {
+		salign = 8
+	}
+	if salen == 0 {
+		return salign
+	}
+	return (salen + salign - 1) & ^(salign - 1)
+}
+
+// RouteRIB returns routing information base, as known as RIB,
+// which consists of network facility information, states and
+// parameters.
+func RouteRIB(facility, param int) ([]byte, error) {
+	mib := []_C_int{CTL_NET, AF_ROUTE, 0, 0, _C_int(facility), _C_int(param)}
+	// Find size.
+	n := uintptr(0)
+	if err := sysctl(mib, nil, &n, nil, 0); err != nil {
+		return nil, err
+	}
+	if n == 0 {
+		return nil, nil
+	}
+	tab := make([]byte, n)
+	if err := sysctl(mib, &tab[0], &n, nil, 0); err != nil {
+		return nil, err
+	}
+	return tab[:n], nil
+}
+
+// RoutingMessage represents a routing message.
+type RoutingMessage interface {
+	sockaddr() []Sockaddr
+}
+
+const anyMessageLen = int(unsafe.Sizeof(anyMessage{}))
+
+type anyMessage struct {
+	Msglen  uint16
+	Version uint8
+	Type    uint8
+}
+
+// RouteMessage represents a routing message containing routing
+// entries.
+type RouteMessage struct {
+	Header RtMsghdr
+	Data   []byte
+}
+
+const rtaRtMask = RTA_DST | RTA_GATEWAY | RTA_NETMASK | RTA_GENMASK
+
+func (m *RouteMessage) sockaddr() []Sockaddr {
+	var (
+		af  int
+		sas [4]Sockaddr
+	)
+	b := m.Data[:]
+	for i := uint(0); i < RTAX_MAX; i++ {
+		if m.Header.Addrs&rtaRtMask&(1<<i) == 0 {
+			continue
+		}
+		rsa := (*RawSockaddr)(unsafe.Pointer(&b[0]))
+		switch i {
+		case RTAX_DST, RTAX_GATEWAY:
+			sa, err := anyToSockaddr((*RawSockaddrAny)(unsafe.Pointer(rsa)))
+			if err != nil {
+				return nil
+			}
+			if i == RTAX_DST {
+				af = int(rsa.Family)
+			}
+			sas[i] = sa
+		case RTAX_NETMASK, RTAX_GENMASK:
+			switch af {
+			case AF_INET:
+				rsa4 := (*RawSockaddrInet4)(unsafe.Pointer(&b[0]))
+				sa := new(SockaddrInet4)
+				for j := 0; rsa4.Len > 0 && j < int(rsa4.Len)-int(unsafe.Offsetof(rsa4.Addr)); j++ {
+					sa.Addr[j] = rsa4.Addr[j]
+				}
+				sas[i] = sa
+			case AF_INET6:
+				rsa6 := (*RawSockaddrInet6)(unsafe.Pointer(&b[0]))
+				sa := new(SockaddrInet6)
+				for j := 0; rsa6.Len > 0 && j < int(rsa6.Len)-int(unsafe.Offsetof(rsa6.Addr)); j++ {
+					sa.Addr[j] = rsa6.Addr[j]
+				}
+				sas[i] = sa
+			}
+		}
+		b = b[rsaAlignOf(int(rsa.Len)):]
+	}
+	return sas[:]
+}
+
+// InterfaceMessage represents a routing message containing
+// network interface entries.
+type InterfaceMessage struct {
+	Header IfMsghdr
+	Data   []byte
+}
+
+func (m *InterfaceMessage) sockaddr() (sas []Sockaddr) {
+	if m.Header.Addrs&RTA_IFP == 0 {
+		return nil
+	}
+	sa, err := anyToSockaddr((*RawSockaddrAny)(unsafe.Pointer(&m.Data[0])))
+	if err != nil {
+		return nil
+	}
+	return append(sas, sa)
+}
+
+// InterfaceAddrMessage represents a routing message containing
+// network interface address entries.
+type InterfaceAddrMessage struct {
+	Header IfaMsghdr
+	Data   []byte
+}
+
+const rtaIfaMask = RTA_IFA | RTA_NETMASK | RTA_BRD
+
+func (m *InterfaceAddrMessage) sockaddr() (sas []Sockaddr) {
+	if m.Header.Addrs&rtaIfaMask == 0 {
+		return nil
+	}
+	b := m.Data[:]
+	// We still see AF_UNSPEC in socket addresses on some
+	// platforms. To identify each address family correctly, we
+	// will use the address family of RTAX_NETMASK as a preferred
+	// one on the 32-bit NetBSD kernel, also use the length of
+	// RTAX_NETMASK socket address on the FreeBSD kernel.
+	preferredFamily := uint8(AF_UNSPEC)
+	for i := uint(0); i < RTAX_MAX; i++ {
+		if m.Header.Addrs&(1<<i) == 0 {
+			continue
+		}
+		rsa := (*RawSockaddr)(unsafe.Pointer(&b[0]))
+		switch i {
+		case RTAX_IFA:
+			if rsa.Family == AF_UNSPEC {
+				rsa.Family = preferredFamily
+			}
+			sa, err := anyToSockaddr((*RawSockaddrAny)(unsafe.Pointer(rsa)))
+			if err != nil {
+				return nil
+			}
+			sas = append(sas, sa)
+		case RTAX_NETMASK:
+			switch rsa.Family {
+			case AF_UNSPEC:
+				switch rsa.Len {
+				case SizeofSockaddrInet4:
+					rsa.Family = AF_INET
+				case SizeofSockaddrInet6:
+					rsa.Family = AF_INET6
+				default:
+					rsa.Family = AF_INET // an old fashion, AF_UNSPEC means AF_INET
+				}
+			case AF_INET, AF_INET6:
+				preferredFamily = rsa.Family
+			default:
+				return nil
+			}
+			sa, err := anyToSockaddr((*RawSockaddrAny)(unsafe.Pointer(rsa)))
+			if err != nil {
+				return nil
+			}
+			sas = append(sas, sa)
+		case RTAX_BRD:
+			// nothing to do
+		}
+		b = b[rsaAlignOf(int(rsa.Len)):]
+	}
+	return sas
+}
+
+// ParseRoutingMessage parses b as routing messages and returns the
+// slice containing the RoutingMessage interfaces.
+func ParseRoutingMessage(b []byte) (msgs []RoutingMessage, err error) {
+	msgCount := 0
+	for len(b) >= anyMessageLen {
+		msgCount++
+		any := (*anyMessage)(unsafe.Pointer(&b[0]))
+		if any.Version != RTM_VERSION {
+			b = b[any.Msglen:]
+			continue
+		}
+		msgs = append(msgs, any.toRoutingMessage(b))
+		b = b[any.Msglen:]
+	}
+	// We failed to parse any of the messages - version mismatch?
+	if msgCount > 0 && len(msgs) == 0 {
+		return nil, EINVAL
+	}
+	return msgs, nil
+}
+
+// ParseRoutingMessage parses msg's payload as raw sockaddrs and
+// returns the slice containing the Sockaddr interfaces.
+func ParseRoutingSockaddr(msg RoutingMessage) (sas []Sockaddr, err error) {
+	return append(sas, msg.sockaddr()...), nil
+}
diff --git a/src/pkg/syscall/route_darwin.go b/src/syscall/route_darwin.go
similarity index 100%
rename from src/pkg/syscall/route_darwin.go
rename to src/syscall/route_darwin.go
diff --git a/src/pkg/syscall/route_dragonfly.go b/src/syscall/route_dragonfly.go
similarity index 100%
rename from src/pkg/syscall/route_dragonfly.go
rename to src/syscall/route_dragonfly.go
diff --git a/src/pkg/syscall/route_freebsd.go b/src/syscall/route_freebsd.go
similarity index 100%
rename from src/pkg/syscall/route_freebsd.go
rename to src/syscall/route_freebsd.go
diff --git a/src/pkg/syscall/route_freebsd_32bit.go b/src/syscall/route_freebsd_32bit.go
similarity index 100%
rename from src/pkg/syscall/route_freebsd_32bit.go
rename to src/syscall/route_freebsd_32bit.go
diff --git a/src/pkg/syscall/route_freebsd_64bit.go b/src/syscall/route_freebsd_64bit.go
similarity index 100%
rename from src/pkg/syscall/route_freebsd_64bit.go
rename to src/syscall/route_freebsd_64bit.go
diff --git a/src/pkg/syscall/route_netbsd.go b/src/syscall/route_netbsd.go
similarity index 100%
rename from src/pkg/syscall/route_netbsd.go
rename to src/syscall/route_netbsd.go
diff --git a/src/pkg/syscall/route_openbsd.go b/src/syscall/route_openbsd.go
similarity index 100%
rename from src/pkg/syscall/route_openbsd.go
rename to src/syscall/route_openbsd.go
diff --git a/src/pkg/syscall/security_windows.go b/src/syscall/security_windows.go
similarity index 100%
rename from src/pkg/syscall/security_windows.go
rename to src/syscall/security_windows.go
diff --git a/src/syscall/so_solaris.go b/src/syscall/so_solaris.go
new file mode 100644
index 0000000..8b1980f
--- /dev/null
+++ b/src/syscall/so_solaris.go
@@ -0,0 +1,262 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package syscall
+
+import (
+	"sync"
+	"sync/atomic"
+	"unsafe"
+)
+
+// soError describes reasons for shared library load failures.
+type soError struct {
+	Err     error
+	ObjName string
+	Msg     string
+}
+
+func (e *soError) Error() string { return e.Msg }
+
+// Implemented in asm_solaris_amd64.s.
+func rawSysvicall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
+func sysvicall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
+func dlclose(handle uintptr) (err Errno)
+func dlopen(name *uint8, mode uintptr) (handle uintptr, err Errno)
+func dlsym(handle uintptr, name *uint8) (proc uintptr, err Errno)
+
+// A so implements access to a single shared library object.
+type so struct {
+	Name   string
+	Handle uintptr
+}
+
+// loadSO loads shared library file into memory.
+func loadSO(name string) (*so, error) {
+	namep, err := BytePtrFromString(name)
+	if err != nil {
+		return nil, err
+	}
+	h, e := dlopen(namep, 1) // RTLD_LAZY
+	use(unsafe.Pointer(namep))
+	if e != 0 {
+		return nil, &soError{
+			Err:     e,
+			ObjName: name,
+			Msg:     "Failed to load " + name + ": " + e.Error(),
+		}
+	}
+	d := &so{
+		Name:   name,
+		Handle: uintptr(h),
+	}
+	return d, nil
+}
+
+// mustLoadSO is like loadSO but panics if load operation fails.
+func mustLoadSO(name string) *so {
+	d, e := loadSO(name)
+	if e != nil {
+		panic(e)
+	}
+	return d
+}
+
+// FindProc searches shared library d for procedure named name and returns
+// *proc if found. It returns an error if the search fails.
+func (d *so) FindProc(name string) (*proc, error) {
+	namep, err := BytePtrFromString(name)
+	if err != nil {
+		return nil, err
+	}
+	a, _ := dlsym(uintptr(d.Handle), namep)
+	use(unsafe.Pointer(namep))
+	if a == 0 {
+		return nil, &soError{
+			Err:     ENOSYS,
+			ObjName: name,
+			Msg:     "Failed to find " + name + " procedure in " + d.Name,
+		}
+	}
+	p := &proc{
+		SO:   d,
+		Name: name,
+		addr: a,
+	}
+	return p, nil
+}
+
+// MustFindProc is like FindProc but panics if search fails.
+func (d *so) MustFindProc(name string) *proc {
+	p, e := d.FindProc(name)
+	if e != nil {
+		panic(e)
+	}
+	return p
+}
+
+// Release unloads shared library d from memory.
+func (d *so) Release() (err error) {
+	return dlclose(d.Handle)
+}
+
+// A proc implements access to a procedure inside a shared library.
+type proc struct {
+	SO   *so
+	Name string
+	addr uintptr
+}
+
+// Addr returns the address of the procedure represented by p.
+// The return value can be passed to Syscall to run the procedure.
+func (p *proc) Addr() uintptr {
+	return p.addr
+}
+
+// Call executes procedure p with arguments a. It will panic, if more then
+// 6 arguments are supplied.
+//
+// The returned error is always non-nil, constructed from the result of
+// GetLastError.  Callers must inspect the primary return value to decide
+// whether an error occurred (according to the semantics of the specific
+// function being called) before consulting the error. The error will be
+// guaranteed to contain syscall.Errno.
+func (p *proc) Call(a ...uintptr) (r1, r2 uintptr, lastErr error) {
+	switch len(a) {
+	case 0:
+		return sysvicall6(p.Addr(), uintptr(len(a)), 0, 0, 0, 0, 0, 0)
+	case 1:
+		return sysvicall6(p.Addr(), uintptr(len(a)), a[0], 0, 0, 0, 0, 0)
+	case 2:
+		return sysvicall6(p.Addr(), uintptr(len(a)), a[0], a[1], 0, 0, 0, 0)
+	case 3:
+		return sysvicall6(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], 0, 0, 0)
+	case 4:
+		return sysvicall6(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], 0, 0)
+	case 5:
+		return sysvicall6(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], 0)
+	case 6:
+		return sysvicall6(p.Addr(), uintptr(len(a)), a[0], a[1], a[2], a[3], a[4], a[5])
+	default:
+		panic("Call " + p.Name + " with too many arguments " + itoa(len(a)) + ".")
+	}
+	return
+}
+
+// A lazySO implements access to a single shared library.  It will delay
+// the load of the shared library until the first call to its Handle method
+// or to one of its lazyProc's Addr method.
+type lazySO struct {
+	mu   sync.Mutex
+	so   *so // non nil once SO is loaded
+	Name string
+}
+
+// Load loads single shared file d.Name into memory. It returns an error if
+// fails.  Load will not try to load SO, if it is already loaded into memory.
+func (d *lazySO) Load() error {
+	// Non-racy version of:
+	// if d.so == nil {
+	if atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(&d.so))) == nil {
+		d.mu.Lock()
+		defer d.mu.Unlock()
+		if d.so == nil {
+			so, e := loadSO(d.Name)
+			if e != nil {
+				return e
+			}
+			// Non-racy version of:
+			// d.so = so
+			atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(&d.so)), unsafe.Pointer(so))
+		}
+	}
+	return nil
+}
+
+// mustLoad is like Load but panics if search fails.
+func (d *lazySO) mustLoad() {
+	e := d.Load()
+	if e != nil {
+		panic(e)
+	}
+}
+
+// Handle returns d's module handle.
+func (d *lazySO) Handle() uintptr {
+	d.mustLoad()
+	return uintptr(d.so.Handle)
+}
+
+// NewProc returns a lazyProc for accessing the named procedure in the SO d.
+func (d *lazySO) NewProc(name string) *lazyProc {
+	return &lazyProc{l: d, Name: name}
+}
+
+// newLazySO creates new lazySO associated with SO file.
+func newLazySO(name string) *lazySO {
+	return &lazySO{Name: name}
+}
+
+// A lazyProc implements access to a procedure inside a lazySO.
+// It delays the lookup until the Addr method is called.
+type lazyProc struct {
+	mu   sync.Mutex
+	Name string
+	l    *lazySO
+	proc *proc
+}
+
+// Find searches the shared library for procedure named p.Name. It returns an
+// error if search fails. Find will not search procedure, if it is already
+// found and loaded into memory.
+func (p *lazyProc) Find() error {
+	// Non-racy version of:
+	// if p.proc == nil {
+	if atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(&p.proc))) == nil {
+		p.mu.Lock()
+		defer p.mu.Unlock()
+		if p.proc == nil {
+			e := p.l.Load()
+			if e != nil {
+				return e
+			}
+			proc, e := p.l.so.FindProc(p.Name)
+			if e != nil {
+				return e
+			}
+			// Non-racy version of:
+			// p.proc = proc
+			atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(&p.proc)), unsafe.Pointer(proc))
+		}
+	}
+	return nil
+}
+
+// mustFind is like Find but panics if search fails.
+func (p *lazyProc) mustFind() {
+	e := p.Find()
+	if e != nil {
+		panic(e)
+	}
+}
+
+// Addr returns the address of the procedure represented by p.
+// The return value can be passed to Syscall to run the procedure.
+func (p *lazyProc) Addr() uintptr {
+	p.mustFind()
+	return p.proc.Addr()
+}
+
+// Call executes procedure p with arguments a. It will panic, if more then
+// 6 arguments are supplied.
+//
+// The returned error is always non-nil, constructed from the result of
+// GetLastError.  Callers must inspect the primary return value to decide
+// whether an error occurred (according to the semantics of the specific
+// function being called) before consulting the error. The error will be
+// guaranteed to contain syscall.Errno.
+func (p *lazyProc) Call(a ...uintptr) (r1, r2 uintptr, lastErr error) {
+	p.mustFind()
+	return p.proc.Call(a...)
+}
diff --git a/src/pkg/syscall/sockcmsg_linux.go b/src/syscall/sockcmsg_linux.go
similarity index 100%
rename from src/pkg/syscall/sockcmsg_linux.go
rename to src/syscall/sockcmsg_linux.go
diff --git a/src/pkg/syscall/sockcmsg_unix.go b/src/syscall/sockcmsg_unix.go
similarity index 100%
rename from src/pkg/syscall/sockcmsg_unix.go
rename to src/syscall/sockcmsg_unix.go
diff --git a/src/pkg/syscall/srpc_nacl.go b/src/syscall/srpc_nacl.go
similarity index 100%
rename from src/pkg/syscall/srpc_nacl.go
rename to src/syscall/srpc_nacl.go
diff --git a/src/syscall/str.go b/src/syscall/str.go
new file mode 100644
index 0000000..2ddf04b
--- /dev/null
+++ b/src/syscall/str.go
@@ -0,0 +1,24 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package syscall
+
+func itoa(val int) string { // do it here rather than with fmt to avoid dependency
+	if val < 0 {
+		return "-" + uitoa(uint(-val))
+	}
+	return uitoa(uint(val))
+}
+
+func uitoa(val uint) string {
+	var buf [32]byte // big enough for int64
+	i := len(buf) - 1
+	for val >= 10 {
+		buf[i] = byte(val%10 + '0')
+		i--
+		val /= 10
+	}
+	buf[i] = byte(val + '0')
+	return string(buf[i:])
+}
diff --git a/src/syscall/syscall.go b/src/syscall/syscall.go
new file mode 100644
index 0000000..1f209ec
--- /dev/null
+++ b/src/syscall/syscall.go
@@ -0,0 +1,95 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package syscall contains an interface to the low-level operating system
+// primitives.  The details vary depending on the underlying system, and
+// by default, godoc will display the syscall documentation for the current
+// system.  If you want godoc to display syscall documentation for another
+// system, set $GOOS and $GOARCH to the desired system.  For example, if
+// you want to view documentation for freebsd/arm on linux/amd64, set $GOOS
+// to freebsd and $GOARCH to arm.
+// The primary use of syscall is inside other packages that provide a more
+// portable interface to the system, such as "os", "time" and "net".  Use
+// those packages rather than this one if you can.
+// For details of the functions and data types in this package consult
+// the manuals for the appropriate operating system.
+// These calls return err == nil to indicate success; otherwise
+// err is an operating system error describing the failure.
+// On most systems, that error has type syscall.Errno.
+//
+// NOTE: This package is locked down. Code outside the standard
+// Go repository should be migrated to use the corresponding
+// package in the go.sys subrepository. That is also where updates
+// required by new systems or versions should be applied.
+// See https://golang.org/s/go1.4-syscall for more information.
+//
+package syscall
+
+import "unsafe"
+
+// StringByteSlice is deprecated. Use ByteSliceFromString instead.
+// If s contains a NUL byte this function panics instead of
+// returning an error.
+func StringByteSlice(s string) []byte {
+	a, err := ByteSliceFromString(s)
+	if err != nil {
+		panic("syscall: string with NUL passed to StringByteSlice")
+	}
+	return a
+}
+
+// ByteSliceFromString returns a NUL-terminated slice of bytes
+// containing the text of s. If s contains a NUL byte at any
+// location, it returns (nil, EINVAL).
+func ByteSliceFromString(s string) ([]byte, error) {
+	for i := 0; i < len(s); i++ {
+		if s[i] == 0 {
+			return nil, EINVAL
+		}
+	}
+	a := make([]byte, len(s)+1)
+	copy(a, s)
+	return a, nil
+}
+
+// StringBytePtr is deprecated. Use BytePtrFromString instead.
+// If s contains a NUL byte this function panics instead of
+// returning an error.
+func StringBytePtr(s string) *byte { return &StringByteSlice(s)[0] }
+
+// BytePtrFromString returns a pointer to a NUL-terminated array of
+// bytes containing the text of s. If s contains a NUL byte at any
+// location, it returns (nil, EINVAL).
+func BytePtrFromString(s string) (*byte, error) {
+	a, err := ByteSliceFromString(s)
+	if err != nil {
+		return nil, err
+	}
+	return &a[0], nil
+}
+
+// Single-word zero for use when we need a valid pointer to 0 bytes.
+// See mksyscall.pl.
+var _zero uintptr
+
+func (ts *Timespec) Unix() (sec int64, nsec int64) {
+	return int64(ts.Sec), int64(ts.Nsec)
+}
+
+func (tv *Timeval) Unix() (sec int64, nsec int64) {
+	return int64(tv.Sec), int64(tv.Usec) * 1000
+}
+
+func (ts *Timespec) Nano() int64 {
+	return int64(ts.Sec)*1e9 + int64(ts.Nsec)
+}
+
+func (tv *Timeval) Nano() int64 {
+	return int64(tv.Sec)*1e9 + int64(tv.Usec)*1000
+}
+
+// use is a no-op, but the compiler cannot see that it is.
+// Calling use(p) ensures that p is kept live until that point.
+//go:noescape
+func use(p unsafe.Pointer)
diff --git a/src/syscall/syscall_bsd.go b/src/syscall/syscall_bsd.go
new file mode 100644
index 0000000..2556fa8
--- /dev/null
+++ b/src/syscall/syscall_bsd.go
@@ -0,0 +1,588 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin dragonfly freebsd netbsd openbsd
+
+// BSD system call wrappers shared by *BSD based systems
+// including OS X (Darwin) and FreeBSD.  Like the other
+// syscall_*.go files it is compiled as Go code but also
+// used as input to mksyscall which parses the //sys
+// lines and generates system call stubs.
+
+package syscall
+
+import (
+	"runtime"
+	"unsafe"
+)
+
+/*
+ * Wrapped
+ */
+
+//sysnb	getgroups(ngid int, gid *_Gid_t) (n int, err error)
+//sysnb	setgroups(ngid int, gid *_Gid_t) (err error)
+
+func Getgroups() (gids []int, err error) {
+	n, err := getgroups(0, nil)
+	if err != nil {
+		return nil, err
+	}
+	if n == 0 {
+		return nil, nil
+	}
+
+	// Sanity check group count.  Max is 16 on BSD.
+	if n < 0 || n > 1000 {
+		return nil, EINVAL
+	}
+
+	a := make([]_Gid_t, n)
+	n, err = getgroups(n, &a[0])
+	if err != nil {
+		return nil, err
+	}
+	gids = make([]int, n)
+	for i, v := range a[0:n] {
+		gids[i] = int(v)
+	}
+	return
+}
+
+func Setgroups(gids []int) (err error) {
+	if len(gids) == 0 {
+		return setgroups(0, nil)
+	}
+
+	a := make([]_Gid_t, len(gids))
+	for i, v := range gids {
+		a[i] = _Gid_t(v)
+	}
+	return setgroups(len(a), &a[0])
+}
+
+func ReadDirent(fd int, buf []byte) (n int, err error) {
+	// Final argument is (basep *uintptr) and the syscall doesn't take nil.
+	// 64 bits should be enough. (32 bits isn't even on 386). Since the
+	// actual system call is getdirentries64, 64 is a good guess.
+	// TODO(rsc): Can we use a single global basep for all calls?
+	var base = (*uintptr)(unsafe.Pointer(new(uint64)))
+	n, err = Getdirentries(fd, buf, base)
+
+	// On OS X 10.10 Yosemite, if you have a directory that can be returned
+	// in a single getdirentries64 call (for example, a directory with one file),
+	// and you read from the directory at EOF twice, you get EOF both times:
+	//	fd = open("dir")
+	//	getdirentries64(fd) // returns data
+	//	getdirentries64(fd) // returns 0 (EOF)
+	//	getdirentries64(fd) // returns 0 (EOF)
+	//
+	// But if you remove the file in the middle between the two calls, the
+	// second call returns an error instead.
+	//	fd = open("dir")
+	//	getdirentries64(fd) // returns data
+	//	getdirentries64(fd) // returns 0 (EOF)
+	//	remove("dir/file")
+	//	getdirentries64(fd) // returns ENOENT/EINVAL
+	//
+	// Whether you get ENOENT or EINVAL depends on exactly what was
+	// in the directory. It is deterministic, just data-dependent.
+	//
+	// This only happens in small directories. A directory containing more data
+	// than fits in a 4k getdirentries64 call will return EOF correctly.
+	// (It's not clear if the criteria is that the directory be split across multiple
+	// getdirentries64 calls or that it be split across multiple file system blocks.)
+	//
+	// We could change package os to avoid the second read at EOF,
+	// and maybe we should, but that's a bit involved.
+	// For now, treat the EINVAL/ENOENT as EOF.
+	if runtime.GOOS == "darwin" && (err == EINVAL || err == ENOENT) {
+		err = nil
+	}
+
+	return
+}
+
+// Wait status is 7 bits at bottom, either 0 (exited),
+// 0x7F (stopped), or a signal number that caused an exit.
+// The 0x80 bit is whether there was a core dump.
+// An extra number (exit code, signal causing a stop)
+// is in the high bits.
+
+type WaitStatus uint32
+
+const (
+	mask  = 0x7F
+	core  = 0x80
+	shift = 8
+
+	exited  = 0
+	stopped = 0x7F
+)
+
+func (w WaitStatus) Exited() bool { return w&mask == exited }
+
+func (w WaitStatus) ExitStatus() int {
+	if w&mask != exited {
+		return -1
+	}
+	return int(w >> shift)
+}
+
+func (w WaitStatus) Signaled() bool { return w&mask != stopped && w&mask != 0 }
+
+func (w WaitStatus) Signal() Signal {
+	sig := Signal(w & mask)
+	if sig == stopped || sig == 0 {
+		return -1
+	}
+	return sig
+}
+
+func (w WaitStatus) CoreDump() bool { return w.Signaled() && w&core != 0 }
+
+func (w WaitStatus) Stopped() bool { return w&mask == stopped && Signal(w>>shift) != SIGSTOP }
+
+func (w WaitStatus) Continued() bool { return w&mask == stopped && Signal(w>>shift) == SIGSTOP }
+
+func (w WaitStatus) StopSignal() Signal {
+	if !w.Stopped() {
+		return -1
+	}
+	return Signal(w>>shift) & 0xFF
+}
+
+func (w WaitStatus) TrapCause() int { return -1 }
+
+//sys	wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error)
+
+func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {
+	var status _C_int
+	wpid, err = wait4(pid, &status, options, rusage)
+	if wstatus != nil {
+		*wstatus = WaitStatus(status)
+	}
+	return
+}
+
+//sys	accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error)
+//sys	bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
+//sys	connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
+//sysnb	socket(domain int, typ int, proto int) (fd int, err error)
+//sys	getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error)
+//sys	setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error)
+//sysnb	getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)
+//sysnb	getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)
+//sys	Shutdown(s int, how int) (err error)
+
+func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) {
+	if sa.Port < 0 || sa.Port > 0xFFFF {
+		return nil, 0, EINVAL
+	}
+	sa.raw.Len = SizeofSockaddrInet4
+	sa.raw.Family = AF_INET
+	p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
+	p[0] = byte(sa.Port >> 8)
+	p[1] = byte(sa.Port)
+	for i := 0; i < len(sa.Addr); i++ {
+		sa.raw.Addr[i] = sa.Addr[i]
+	}
+	return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil
+}
+
+func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, _Socklen, error) {
+	if sa.Port < 0 || sa.Port > 0xFFFF {
+		return nil, 0, EINVAL
+	}
+	sa.raw.Len = SizeofSockaddrInet6
+	sa.raw.Family = AF_INET6
+	p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
+	p[0] = byte(sa.Port >> 8)
+	p[1] = byte(sa.Port)
+	sa.raw.Scope_id = sa.ZoneId
+	for i := 0; i < len(sa.Addr); i++ {
+		sa.raw.Addr[i] = sa.Addr[i]
+	}
+	return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil
+}
+
+func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, _Socklen, error) {
+	name := sa.Name
+	n := len(name)
+	if n >= len(sa.raw.Path) || n == 0 {
+		return nil, 0, EINVAL
+	}
+	sa.raw.Len = byte(3 + n) // 2 for Family, Len; 1 for NUL
+	sa.raw.Family = AF_UNIX
+	for i := 0; i < n; i++ {
+		sa.raw.Path[i] = int8(name[i])
+	}
+	return unsafe.Pointer(&sa.raw), _Socklen(sa.raw.Len), nil
+}
+
+func (sa *SockaddrDatalink) sockaddr() (unsafe.Pointer, _Socklen, error) {
+	if sa.Index == 0 {
+		return nil, 0, EINVAL
+	}
+	sa.raw.Len = sa.Len
+	sa.raw.Family = AF_LINK
+	sa.raw.Index = sa.Index
+	sa.raw.Type = sa.Type
+	sa.raw.Nlen = sa.Nlen
+	sa.raw.Alen = sa.Alen
+	sa.raw.Slen = sa.Slen
+	for i := 0; i < len(sa.raw.Data); i++ {
+		sa.raw.Data[i] = sa.Data[i]
+	}
+	return unsafe.Pointer(&sa.raw), SizeofSockaddrDatalink, nil
+}
+
+func anyToSockaddr(rsa *RawSockaddrAny) (Sockaddr, error) {
+	switch rsa.Addr.Family {
+	case AF_LINK:
+		pp := (*RawSockaddrDatalink)(unsafe.Pointer(rsa))
+		sa := new(SockaddrDatalink)
+		sa.Len = pp.Len
+		sa.Family = pp.Family
+		sa.Index = pp.Index
+		sa.Type = pp.Type
+		sa.Nlen = pp.Nlen
+		sa.Alen = pp.Alen
+		sa.Slen = pp.Slen
+		for i := 0; i < len(sa.Data); i++ {
+			sa.Data[i] = pp.Data[i]
+		}
+		return sa, nil
+
+	case AF_UNIX:
+		pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa))
+		if pp.Len < 2 || pp.Len > SizeofSockaddrUnix {
+			return nil, EINVAL
+		}
+		sa := new(SockaddrUnix)
+
+		// Some BSDs include the trailing NUL in the length, whereas
+		// others do not. Work around this by subtracting the leading
+		// family and len. The path is then scanned to see if a NUL
+		// terminator still exists within the length.
+		n := int(pp.Len) - 2 // subtract leading Family, Len
+		for i := 0; i < n; i++ {
+			if pp.Path[i] == 0 {
+				// found early NUL; assume Len included the NUL
+				// or was overestimating.
+				n = i
+				break
+			}
+		}
+		bytes := (*[10000]byte)(unsafe.Pointer(&pp.Path[0]))[0:n]
+		sa.Name = string(bytes)
+		return sa, nil
+
+	case AF_INET:
+		pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))
+		sa := new(SockaddrInet4)
+		p := (*[2]byte)(unsafe.Pointer(&pp.Port))
+		sa.Port = int(p[0])<<8 + int(p[1])
+		for i := 0; i < len(sa.Addr); i++ {
+			sa.Addr[i] = pp.Addr[i]
+		}
+		return sa, nil
+
+	case AF_INET6:
+		pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa))
+		sa := new(SockaddrInet6)
+		p := (*[2]byte)(unsafe.Pointer(&pp.Port))
+		sa.Port = int(p[0])<<8 + int(p[1])
+		sa.ZoneId = pp.Scope_id
+		for i := 0; i < len(sa.Addr); i++ {
+			sa.Addr[i] = pp.Addr[i]
+		}
+		return sa, nil
+	}
+	return nil, EAFNOSUPPORT
+}
+
+func Accept(fd int) (nfd int, sa Sockaddr, err error) {
+	var rsa RawSockaddrAny
+	var len _Socklen = SizeofSockaddrAny
+	nfd, err = accept(fd, &rsa, &len)
+	if err != nil {
+		return
+	}
+	if runtime.GOOS == "darwin" && len == 0 {
+		// Accepted socket has no address.
+		// This is likely due to a bug in xnu kernels,
+		// where instead of ECONNABORTED error socket
+		// is accepted, but has no address.
+		Close(nfd)
+		return 0, nil, ECONNABORTED
+	}
+	sa, err = anyToSockaddr(&rsa)
+	if err != nil {
+		Close(nfd)
+		nfd = 0
+	}
+	return
+}
+
+func Getsockname(fd int) (sa Sockaddr, err error) {
+	var rsa RawSockaddrAny
+	var len _Socklen = SizeofSockaddrAny
+	if err = getsockname(fd, &rsa, &len); err != nil {
+		return
+	}
+	// TODO(jsing): DragonFly has a "bug" (see issue 3349), which should be
+	// reported upstream.
+	if runtime.GOOS == "dragonfly" && rsa.Addr.Family == AF_UNSPEC && rsa.Addr.Len == 0 {
+		rsa.Addr.Family = AF_UNIX
+		rsa.Addr.Len = SizeofSockaddrUnix
+	}
+	return anyToSockaddr(&rsa)
+}
+
+//sysnb socketpair(domain int, typ int, proto int, fd *[2]int32) (err error)
+
+func GetsockoptByte(fd, level, opt int) (value byte, err error) {
+	var n byte
+	vallen := _Socklen(1)
+	err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen)
+	return n, err
+}
+
+func GetsockoptInet4Addr(fd, level, opt int) (value [4]byte, err error) {
+	vallen := _Socklen(4)
+	err = getsockopt(fd, level, opt, unsafe.Pointer(&value[0]), &vallen)
+	return value, err
+}
+
+func GetsockoptIPMreq(fd, level, opt int) (*IPMreq, error) {
+	var value IPMreq
+	vallen := _Socklen(SizeofIPMreq)
+	err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
+	return &value, err
+}
+
+func GetsockoptIPv6Mreq(fd, level, opt int) (*IPv6Mreq, error) {
+	var value IPv6Mreq
+	vallen := _Socklen(SizeofIPv6Mreq)
+	err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
+	return &value, err
+}
+
+func GetsockoptIPv6MTUInfo(fd, level, opt int) (*IPv6MTUInfo, error) {
+	var value IPv6MTUInfo
+	vallen := _Socklen(SizeofIPv6MTUInfo)
+	err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
+	return &value, err
+}
+
+func GetsockoptICMPv6Filter(fd, level, opt int) (*ICMPv6Filter, error) {
+	var value ICMPv6Filter
+	vallen := _Socklen(SizeofICMPv6Filter)
+	err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
+	return &value, err
+}
+
+//sys   recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error)
+//sys   sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error)
+//sys	recvmsg(s int, msg *Msghdr, flags int) (n int, err error)
+
+func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) {
+	var msg Msghdr
+	var rsa RawSockaddrAny
+	msg.Name = (*byte)(unsafe.Pointer(&rsa))
+	msg.Namelen = uint32(SizeofSockaddrAny)
+	var iov Iovec
+	if len(p) > 0 {
+		iov.Base = (*byte)(unsafe.Pointer(&p[0]))
+		iov.SetLen(len(p))
+	}
+	var dummy byte
+	if len(oob) > 0 {
+		// receive at least one normal byte
+		if len(p) == 0 {
+			iov.Base = &dummy
+			iov.SetLen(1)
+		}
+		msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
+		msg.SetControllen(len(oob))
+	}
+	msg.Iov = &iov
+	msg.Iovlen = 1
+	if n, err = recvmsg(fd, &msg, flags); err != nil {
+		return
+	}
+	oobn = int(msg.Controllen)
+	recvflags = int(msg.Flags)
+	// source address is only specified if the socket is unconnected
+	if rsa.Addr.Family != AF_UNSPEC {
+		from, err = anyToSockaddr(&rsa)
+	}
+	return
+}
+
+//sys	sendmsg(s int, msg *Msghdr, flags int) (n int, err error)
+
+func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) {
+	_, err = SendmsgN(fd, p, oob, to, flags)
+	return
+}
+
+func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) {
+	var ptr unsafe.Pointer
+	var salen _Socklen
+	if to != nil {
+		ptr, salen, err = to.sockaddr()
+		if err != nil {
+			return 0, err
+		}
+	}
+	var msg Msghdr
+	msg.Name = (*byte)(unsafe.Pointer(ptr))
+	msg.Namelen = uint32(salen)
+	var iov Iovec
+	if len(p) > 0 {
+		iov.Base = (*byte)(unsafe.Pointer(&p[0]))
+		iov.SetLen(len(p))
+	}
+	var dummy byte
+	if len(oob) > 0 {
+		// send at least one normal byte
+		if len(p) == 0 {
+			iov.Base = &dummy
+			iov.SetLen(1)
+		}
+		msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
+		msg.SetControllen(len(oob))
+	}
+	msg.Iov = &iov
+	msg.Iovlen = 1
+	if n, err = sendmsg(fd, &msg, flags); err != nil {
+		return 0, err
+	}
+	if len(oob) > 0 && len(p) == 0 {
+		n = 0
+	}
+	return n, nil
+}
+
+//sys	kevent(kq int, change unsafe.Pointer, nchange int, event unsafe.Pointer, nevent int, timeout *Timespec) (n int, err error)
+
+func Kevent(kq int, changes, events []Kevent_t, timeout *Timespec) (n int, err error) {
+	var change, event unsafe.Pointer
+	if len(changes) > 0 {
+		change = unsafe.Pointer(&changes[0])
+	}
+	if len(events) > 0 {
+		event = unsafe.Pointer(&events[0])
+	}
+	return kevent(kq, change, len(changes), event, len(events), timeout)
+}
+
+//sys	sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) = SYS___SYSCTL
+
+func Sysctl(name string) (value string, err error) {
+	// Translate name to mib number.
+	mib, err := nametomib(name)
+	if err != nil {
+		return "", err
+	}
+
+	// Find size.
+	n := uintptr(0)
+	if err = sysctl(mib, nil, &n, nil, 0); err != nil {
+		return "", err
+	}
+	if n == 0 {
+		return "", nil
+	}
+
+	// Read into buffer of that size.
+	buf := make([]byte, n)
+	if err = sysctl(mib, &buf[0], &n, nil, 0); err != nil {
+		return "", err
+	}
+
+	// Throw away terminating NUL.
+	if n > 0 && buf[n-1] == '\x00' {
+		n--
+	}
+	return string(buf[0:n]), nil
+}
+
+func SysctlUint32(name string) (value uint32, err error) {
+	// Translate name to mib number.
+	mib, err := nametomib(name)
+	if err != nil {
+		return 0, err
+	}
+
+	// Read into buffer of that size.
+	n := uintptr(4)
+	buf := make([]byte, 4)
+	if err = sysctl(mib, &buf[0], &n, nil, 0); err != nil {
+		return 0, err
+	}
+	if n != 4 {
+		return 0, EIO
+	}
+	return *(*uint32)(unsafe.Pointer(&buf[0])), nil
+}
+
+//sys	utimes(path string, timeval *[2]Timeval) (err error)
+
+func Utimes(path string, tv []Timeval) (err error) {
+	if len(tv) != 2 {
+		return EINVAL
+	}
+	return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
+}
+
+func UtimesNano(path string, ts []Timespec) error {
+	// TODO: The BSDs can do utimensat with SYS_UTIMENSAT but it
+	// isn't supported by darwin so this uses utimes instead
+	if len(ts) != 2 {
+		return EINVAL
+	}
+	// Not as efficient as it could be because Timespec and
+	// Timeval have different types in the different OSes
+	tv := [2]Timeval{
+		NsecToTimeval(TimespecToNsec(ts[0])),
+		NsecToTimeval(TimespecToNsec(ts[1])),
+	}
+	return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
+}
+
+//sys	futimes(fd int, timeval *[2]Timeval) (err error)
+
+func Futimes(fd int, tv []Timeval) (err error) {
+	if len(tv) != 2 {
+		return EINVAL
+	}
+	return futimes(fd, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
+}
+
+//sys	fcntl(fd int, cmd int, arg int) (val int, err error)
+
+// TODO: wrap
+//	Acct(name nil-string) (err error)
+//	Gethostuuid(uuid *byte, timeout *Timespec) (err error)
+//	Madvise(addr *byte, len int, behav int) (err error)
+//	Mprotect(addr *byte, len int, prot int) (err error)
+//	Msync(addr *byte, len int, flags int) (err error)
+//	Ptrace(req int, pid int, addr uintptr, data int) (ret uintptr, err error)
+
+var mapper = &mmapper{
+	active: make(map[*byte][]byte),
+	mmap:   mmap,
+	munmap: munmap,
+}
+
+func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
+	return mapper.Mmap(fd, offset, length, prot, flags)
+}
+
+func Munmap(b []byte) (err error) {
+	return mapper.Munmap(b)
+}
diff --git a/src/pkg/syscall/syscall_bsd_test.go b/src/syscall/syscall_bsd_test.go
similarity index 100%
rename from src/pkg/syscall/syscall_bsd_test.go
rename to src/syscall/syscall_bsd_test.go
diff --git a/src/syscall/syscall_darwin.go b/src/syscall/syscall_darwin.go
new file mode 100644
index 0000000..f026a56
--- /dev/null
+++ b/src/syscall/syscall_darwin.go
@@ -0,0 +1,509 @@
+// Copyright 2009,2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Darwin system calls.
+// This file is compiled as ordinary Go code,
+// but it is also input to mksyscall,
+// which parses the //sys lines and generates system call stubs.
+// Note that sometimes we use a lowercase //sys name and wrap
+// it in our own nicer implementation, either here or in
+// syscall_bsd.go or syscall_unix.go.
+
+package syscall
+
+import (
+	errorspkg "errors"
+	"unsafe"
+)
+
+const ImplementsGetwd = true
+
+func Getwd() (string, error) {
+	buf := make([]byte, 2048)
+	attrs, err := getAttrList(".", attrList{CommonAttr: attrCmnFullpath}, buf, 0)
+	if err == nil && len(attrs) == 1 && len(attrs[0]) >= 2 {
+		wd := string(attrs[0])
+		// Sanity check that it's an absolute path and ends
+		// in a null byte, which we then strip.
+		if wd[0] == '/' && wd[len(wd)-1] == 0 {
+			return wd[:len(wd)-1], nil
+		}
+	}
+	// If pkg/os/getwd.go gets ENOTSUP, it will fall back to the
+	// slow algorithm.
+	return "", ENOTSUP
+}
+
+type SockaddrDatalink struct {
+	Len    uint8
+	Family uint8
+	Index  uint16
+	Type   uint8
+	Nlen   uint8
+	Alen   uint8
+	Slen   uint8
+	Data   [12]int8
+	raw    RawSockaddrDatalink
+}
+
+// Translate "kern.hostname" to []_C_int{0,1,2,3}.
+func nametomib(name string) (mib []_C_int, err error) {
+	const siz = unsafe.Sizeof(mib[0])
+
+	// NOTE(rsc): It seems strange to set the buffer to have
+	// size CTL_MAXNAME+2 but use only CTL_MAXNAME
+	// as the size.  I don't know why the +2 is here, but the
+	// kernel uses +2 for its own implementation of this function.
+	// I am scared that if we don't include the +2 here, the kernel
+	// will silently write 2 words farther than we specify
+	// and we'll get memory corruption.
+	var buf [CTL_MAXNAME + 2]_C_int
+	n := uintptr(CTL_MAXNAME) * siz
+
+	p := (*byte)(unsafe.Pointer(&buf[0]))
+	bytes, err := ByteSliceFromString(name)
+	if err != nil {
+		return nil, err
+	}
+
+	// Magic sysctl: "setting" 0.3 to a string name
+	// lets you read back the array of integers form.
+	if err = sysctl([]_C_int{0, 3}, p, &n, &bytes[0], uintptr(len(name))); err != nil {
+		return nil, err
+	}
+	return buf[0 : n/siz], nil
+}
+
+// ParseDirent parses up to max directory entries in buf,
+// appending the names to names.  It returns the number
+// bytes consumed from buf, the number of entries added
+// to names, and the new names slice.
+func ParseDirent(buf []byte, max int, names []string) (consumed int, count int, newnames []string) {
+	origlen := len(buf)
+	for max != 0 && len(buf) > 0 {
+		dirent := (*Dirent)(unsafe.Pointer(&buf[0]))
+		if dirent.Reclen == 0 {
+			buf = nil
+			break
+		}
+		buf = buf[dirent.Reclen:]
+		if dirent.Ino == 0 { // File absent in directory.
+			continue
+		}
+		bytes := (*[10000]byte)(unsafe.Pointer(&dirent.Name[0]))
+		var name = string(bytes[0:dirent.Namlen])
+		if name == "." || name == ".." { // Useless names
+			continue
+		}
+		max--
+		count++
+		names = append(names, name)
+	}
+	return origlen - len(buf), count, names
+}
+
+//sys   ptrace(request int, pid int, addr uintptr, data uintptr) (err error)
+func PtraceAttach(pid int) (err error) { return ptrace(PT_ATTACH, pid, 0, 0) }
+func PtraceDetach(pid int) (err error) { return ptrace(PT_DETACH, pid, 0, 0) }
+
+const (
+	attrBitMapCount = 5
+	attrCmnFullpath = 0x08000000
+)
+
+type attrList struct {
+	bitmapCount uint16
+	_           uint16
+	CommonAttr  uint32
+	VolAttr     uint32
+	DirAttr     uint32
+	FileAttr    uint32
+	Forkattr    uint32
+}
+
+func getAttrList(path string, attrList attrList, attrBuf []byte, options uint) (attrs [][]byte, err error) {
+	if len(attrBuf) < 4 {
+		return nil, errorspkg.New("attrBuf too small")
+	}
+	attrList.bitmapCount = attrBitMapCount
+
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return nil, err
+	}
+
+	_, _, e1 := Syscall6(
+		SYS_GETATTRLIST,
+		uintptr(unsafe.Pointer(_p0)),
+		uintptr(unsafe.Pointer(&attrList)),
+		uintptr(unsafe.Pointer(&attrBuf[0])),
+		uintptr(len(attrBuf)),
+		uintptr(options),
+		0,
+	)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		return nil, e1
+	}
+	size := *(*uint32)(unsafe.Pointer(&attrBuf[0]))
+
+	// dat is the section of attrBuf that contains valid data,
+	// without the 4 byte length header. All attribute offsets
+	// are relative to dat.
+	dat := attrBuf
+	if int(size) < len(attrBuf) {
+		dat = dat[:size]
+	}
+	dat = dat[4:] // remove length prefix
+
+	for i := uint32(0); int(i) < len(dat); {
+		header := dat[i:]
+		if len(header) < 8 {
+			return attrs, errorspkg.New("truncated attribute header")
+		}
+		datOff := *(*int32)(unsafe.Pointer(&header[0]))
+		attrLen := *(*uint32)(unsafe.Pointer(&header[4]))
+		if datOff < 0 || uint32(datOff)+attrLen > uint32(len(dat)) {
+			return attrs, errorspkg.New("truncated results; attrBuf too small")
+		}
+		end := uint32(datOff) + attrLen
+		attrs = append(attrs, dat[datOff:end])
+		i = end
+		if r := i % 4; r != 0 {
+			i += (4 - r)
+		}
+	}
+	return
+}
+
+//sysnb pipe() (r int, w int, err error)
+
+func Pipe(p []int) (err error) {
+	if len(p) != 2 {
+		return EINVAL
+	}
+	p[0], p[1], err = pipe()
+	return
+}
+
+func Getfsstat(buf []Statfs_t, flags int) (n int, err error) {
+	var _p0 unsafe.Pointer
+	var bufsize uintptr
+	if len(buf) > 0 {
+		_p0 = unsafe.Pointer(&buf[0])
+		bufsize = unsafe.Sizeof(Statfs_t{}) * uintptr(len(buf))
+	}
+	r0, _, e1 := Syscall(SYS_GETFSSTAT64, uintptr(_p0), bufsize, uintptr(flags))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+/*
+ * Wrapped
+ */
+
+//sys	kill(pid int, signum int, posix int) (err error)
+
+func Kill(pid int, signum Signal) (err error) { return kill(pid, int(signum), 1) }
+
+/*
+ * Exposed directly
+ */
+//sys	Access(path string, mode uint32) (err error)
+//sys	Adjtime(delta *Timeval, olddelta *Timeval) (err error)
+//sys	Chdir(path string) (err error)
+//sys	Chflags(path string, flags int) (err error)
+//sys	Chmod(path string, mode uint32) (err error)
+//sys	Chown(path string, uid int, gid int) (err error)
+//sys	Chroot(path string) (err error)
+//sys	Close(fd int) (err error)
+//sysnb	Dup(fd int) (nfd int, err error)
+//sysnb	Dup2(from int, to int) (err error)
+//sys	Exchangedata(path1 string, path2 string, options int) (err error)
+//sys	Exit(code int)
+//sys	Fchdir(fd int) (err error)
+//sys	Fchflags(fd int, flags int) (err error)
+//sys	Fchmod(fd int, mode uint32) (err error)
+//sys	Fchown(fd int, uid int, gid int) (err error)
+//sys	Flock(fd int, how int) (err error)
+//sys	Fpathconf(fd int, name int) (val int, err error)
+//sys	Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64
+//sys	Fstatfs(fd int, stat *Statfs_t) (err error) = SYS_FSTATFS64
+//sys	Fsync(fd int) (err error)
+//sys	Ftruncate(fd int, length int64) (err error)
+//sys	Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) = SYS_GETDIRENTRIES64
+//sys	Getdtablesize() (size int)
+//sysnb	Getegid() (egid int)
+//sysnb	Geteuid() (uid int)
+//sysnb	Getgid() (gid int)
+//sysnb	Getpgid(pid int) (pgid int, err error)
+//sysnb	Getpgrp() (pgrp int)
+//sysnb	Getpid() (pid int)
+//sysnb	Getppid() (ppid int)
+//sys	Getpriority(which int, who int) (prio int, err error)
+//sysnb	Getrlimit(which int, lim *Rlimit) (err error)
+//sysnb	Getrusage(who int, rusage *Rusage) (err error)
+//sysnb	Getsid(pid int) (sid int, err error)
+//sysnb	Getuid() (uid int)
+//sysnb	Issetugid() (tainted bool)
+//sys	Kqueue() (fd int, err error)
+//sys	Lchown(path string, uid int, gid int) (err error)
+//sys	Link(path string, link string) (err error)
+//sys	Listen(s int, backlog int) (err error)
+//sys	Lstat(path string, stat *Stat_t) (err error) = SYS_LSTAT64
+//sys	Mkdir(path string, mode uint32) (err error)
+//sys	Mkfifo(path string, mode uint32) (err error)
+//sys	Mknod(path string, mode uint32, dev int) (err error)
+//sys	Mlock(b []byte) (err error)
+//sys	Mlockall(flags int) (err error)
+//sys	Mprotect(b []byte, prot int) (err error)
+//sys	Munlock(b []byte) (err error)
+//sys	Munlockall() (err error)
+//sys	Open(path string, mode int, perm uint32) (fd int, err error)
+//sys	Pathconf(path string, name int) (val int, err error)
+//sys	Pread(fd int, p []byte, offset int64) (n int, err error)
+//sys	Pwrite(fd int, p []byte, offset int64) (n int, err error)
+//sys	read(fd int, p []byte) (n int, err error)
+//sys	Readlink(path string, buf []byte) (n int, err error)
+//sys	Rename(from string, to string) (err error)
+//sys	Revoke(path string) (err error)
+//sys	Rmdir(path string) (err error)
+//sys	Seek(fd int, offset int64, whence int) (newoffset int64, err error) = SYS_LSEEK
+//sys	Select(n int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (err error)
+//sys	Setegid(egid int) (err error)
+//sysnb	Seteuid(euid int) (err error)
+//sysnb	Setgid(gid int) (err error)
+//sys	Setlogin(name string) (err error)
+//sysnb	Setpgid(pid int, pgid int) (err error)
+//sys	Setpriority(which int, who int, prio int) (err error)
+//sys	Setprivexec(flag int) (err error)
+//sysnb	Setregid(rgid int, egid int) (err error)
+//sysnb	Setreuid(ruid int, euid int) (err error)
+//sysnb	Setrlimit(which int, lim *Rlimit) (err error)
+//sysnb	Setsid() (pid int, err error)
+//sysnb	Settimeofday(tp *Timeval) (err error)
+//sysnb	Setuid(uid int) (err error)
+//sys	Stat(path string, stat *Stat_t) (err error) = SYS_STAT64
+//sys	Statfs(path string, stat *Statfs_t) (err error) = SYS_STATFS64
+//sys	Symlink(path string, link string) (err error)
+//sys	Sync() (err error)
+//sys	Truncate(path string, length int64) (err error)
+//sys	Umask(newmask int) (oldmask int)
+//sys	Undelete(path string) (err error)
+//sys	Unlink(path string) (err error)
+//sys	Unmount(path string, flags int) (err error)
+//sys	write(fd int, p []byte) (n int, err error)
+//sys   mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error)
+//sys   munmap(addr uintptr, length uintptr) (err error)
+//sys	readlen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_READ
+//sys	writelen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_WRITE
+
+/*
+ * Unimplemented
+ */
+// Profil
+// Sigaction
+// Sigprocmask
+// Getlogin
+// Sigpending
+// Sigaltstack
+// Ioctl
+// Reboot
+// Execve
+// Vfork
+// Sbrk
+// Sstk
+// Ovadvise
+// Mincore
+// Setitimer
+// Swapon
+// Select
+// Sigsuspend
+// Readv
+// Writev
+// Nfssvc
+// Getfh
+// Quotactl
+// Mount
+// Csops
+// Waitid
+// Add_profil
+// Kdebug_trace
+// Sigreturn
+// Mmap
+// Mlock
+// Munlock
+// Atsocket
+// Kqueue_from_portset_np
+// Kqueue_portset
+// Getattrlist
+// Setattrlist
+// Getdirentriesattr
+// Searchfs
+// Delete
+// Copyfile
+// Poll
+// Watchevent
+// Waitevent
+// Modwatch
+// Getxattr
+// Fgetxattr
+// Setxattr
+// Fsetxattr
+// Removexattr
+// Fremovexattr
+// Listxattr
+// Flistxattr
+// Fsctl
+// Initgroups
+// Posix_spawn
+// Nfsclnt
+// Fhopen
+// Minherit
+// Semsys
+// Msgsys
+// Shmsys
+// Semctl
+// Semget
+// Semop
+// Msgctl
+// Msgget
+// Msgsnd
+// Msgrcv
+// Shmat
+// Shmctl
+// Shmdt
+// Shmget
+// Shm_open
+// Shm_unlink
+// Sem_open
+// Sem_close
+// Sem_unlink
+// Sem_wait
+// Sem_trywait
+// Sem_post
+// Sem_getvalue
+// Sem_init
+// Sem_destroy
+// Open_extended
+// Umask_extended
+// Stat_extended
+// Lstat_extended
+// Fstat_extended
+// Chmod_extended
+// Fchmod_extended
+// Access_extended
+// Settid
+// Gettid
+// Setsgroups
+// Getsgroups
+// Setwgroups
+// Getwgroups
+// Mkfifo_extended
+// Mkdir_extended
+// Identitysvc
+// Shared_region_check_np
+// Shared_region_map_np
+// __pthread_mutex_destroy
+// __pthread_mutex_init
+// __pthread_mutex_lock
+// __pthread_mutex_trylock
+// __pthread_mutex_unlock
+// __pthread_cond_init
+// __pthread_cond_destroy
+// __pthread_cond_broadcast
+// __pthread_cond_signal
+// Setsid_with_pid
+// __pthread_cond_timedwait
+// Aio_fsync
+// Aio_return
+// Aio_suspend
+// Aio_cancel
+// Aio_error
+// Aio_read
+// Aio_write
+// Lio_listio
+// __pthread_cond_wait
+// Iopolicysys
+// Mlockall
+// Munlockall
+// __pthread_kill
+// __pthread_sigmask
+// __sigwait
+// __disable_threadsignal
+// __pthread_markcancel
+// __pthread_canceled
+// __semwait_signal
+// Proc_info
+// sendfile
+// Stat64_extended
+// Lstat64_extended
+// Fstat64_extended
+// __pthread_chdir
+// __pthread_fchdir
+// Audit
+// Auditon
+// Getauid
+// Setauid
+// Getaudit
+// Setaudit
+// Getaudit_addr
+// Setaudit_addr
+// Auditctl
+// Bsdthread_create
+// Bsdthread_terminate
+// Stack_snapshot
+// Bsdthread_register
+// Workq_open
+// Workq_ops
+// __mac_execve
+// __mac_syscall
+// __mac_get_file
+// __mac_set_file
+// __mac_get_link
+// __mac_set_link
+// __mac_get_proc
+// __mac_set_proc
+// __mac_get_fd
+// __mac_set_fd
+// __mac_get_pid
+// __mac_get_lcid
+// __mac_get_lctx
+// __mac_set_lctx
+// Setlcid
+// Read_nocancel
+// Write_nocancel
+// Open_nocancel
+// Close_nocancel
+// Wait4_nocancel
+// Recvmsg_nocancel
+// Sendmsg_nocancel
+// Recvfrom_nocancel
+// Accept_nocancel
+// Msync_nocancel
+// Fcntl_nocancel
+// Select_nocancel
+// Fsync_nocancel
+// Connect_nocancel
+// Sigsuspend_nocancel
+// Readv_nocancel
+// Writev_nocancel
+// Sendto_nocancel
+// Pread_nocancel
+// Pwrite_nocancel
+// Waitid_nocancel
+// Poll_nocancel
+// Msgsnd_nocancel
+// Msgrcv_nocancel
+// Sem_wait_nocancel
+// Aio_suspend_nocancel
+// __sigwait_nocancel
+// __semwait_signal_nocancel
+// __mac_mount
+// __mac_get_mount
+// __mac_getfsstat
diff --git a/src/pkg/syscall/syscall_darwin_386.go b/src/syscall/syscall_darwin_386.go
similarity index 100%
rename from src/pkg/syscall/syscall_darwin_386.go
rename to src/syscall/syscall_darwin_386.go
diff --git a/src/pkg/syscall/syscall_darwin_amd64.go b/src/syscall/syscall_darwin_amd64.go
similarity index 100%
rename from src/pkg/syscall/syscall_darwin_amd64.go
rename to src/syscall/syscall_darwin_amd64.go
diff --git a/src/pkg/syscall/syscall_dragonfly.go b/src/syscall/syscall_dragonfly.go
similarity index 100%
rename from src/pkg/syscall/syscall_dragonfly.go
rename to src/syscall/syscall_dragonfly.go
diff --git a/src/pkg/syscall/syscall_dragonfly_386.go b/src/syscall/syscall_dragonfly_386.go
similarity index 100%
rename from src/pkg/syscall/syscall_dragonfly_386.go
rename to src/syscall/syscall_dragonfly_386.go
diff --git a/src/pkg/syscall/syscall_dragonfly_amd64.go b/src/syscall/syscall_dragonfly_amd64.go
similarity index 100%
rename from src/pkg/syscall/syscall_dragonfly_amd64.go
rename to src/syscall/syscall_dragonfly_amd64.go
diff --git a/src/pkg/syscall/syscall_freebsd.go b/src/syscall/syscall_freebsd.go
similarity index 100%
rename from src/pkg/syscall/syscall_freebsd.go
rename to src/syscall/syscall_freebsd.go
diff --git a/src/pkg/syscall/syscall_freebsd_386.go b/src/syscall/syscall_freebsd_386.go
similarity index 100%
rename from src/pkg/syscall/syscall_freebsd_386.go
rename to src/syscall/syscall_freebsd_386.go
diff --git a/src/pkg/syscall/syscall_freebsd_amd64.go b/src/syscall/syscall_freebsd_amd64.go
similarity index 100%
rename from src/pkg/syscall/syscall_freebsd_amd64.go
rename to src/syscall/syscall_freebsd_amd64.go
diff --git a/src/pkg/syscall/syscall_freebsd_arm.go b/src/syscall/syscall_freebsd_arm.go
similarity index 100%
rename from src/pkg/syscall/syscall_freebsd_arm.go
rename to src/syscall/syscall_freebsd_arm.go
diff --git a/src/syscall/syscall_linux.go b/src/syscall/syscall_linux.go
new file mode 100644
index 0000000..c40c718
--- /dev/null
+++ b/src/syscall/syscall_linux.go
@@ -0,0 +1,1042 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Linux system calls.
+// This file is compiled as ordinary Go code,
+// but it is also input to mksyscall,
+// which parses the //sys lines and generates system call stubs.
+// Note that sometimes we use a lowercase //sys name and
+// wrap it in our own nicer implementation.
+
+package syscall
+
+import "unsafe"
+
+/*
+ * Wrapped
+ */
+
+//sys	open(path string, mode int, perm uint32) (fd int, err error)
+
+func Open(path string, mode int, perm uint32) (fd int, err error) {
+	return open(path, mode|O_LARGEFILE, perm)
+}
+
+//sys	openat(dirfd int, path string, flags int, mode uint32) (fd int, err error)
+
+func Openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) {
+	return openat(dirfd, path, flags|O_LARGEFILE, mode)
+}
+
+//sysnb	pipe(p *[2]_C_int) (err error)
+
+func Pipe(p []int) (err error) {
+	if len(p) != 2 {
+		return EINVAL
+	}
+	var pp [2]_C_int
+	err = pipe(&pp)
+	p[0] = int(pp[0])
+	p[1] = int(pp[1])
+	return
+}
+
+//sysnb pipe2(p *[2]_C_int, flags int) (err error)
+
+func Pipe2(p []int, flags int) (err error) {
+	if len(p) != 2 {
+		return EINVAL
+	}
+	var pp [2]_C_int
+	err = pipe2(&pp, flags)
+	p[0] = int(pp[0])
+	p[1] = int(pp[1])
+	return
+}
+
+//sys	utimes(path string, times *[2]Timeval) (err error)
+
+func Utimes(path string, tv []Timeval) (err error) {
+	if len(tv) != 2 {
+		return EINVAL
+	}
+	return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
+}
+
+//sys	utimensat(dirfd int, path string, times *[2]Timespec) (err error)
+
+func UtimesNano(path string, ts []Timespec) (err error) {
+	if len(ts) != 2 {
+		return EINVAL
+	}
+	err = utimensat(_AT_FDCWD, path, (*[2]Timespec)(unsafe.Pointer(&ts[0])))
+	if err != ENOSYS {
+		return err
+	}
+	// If the utimensat syscall isn't available (utimensat was added to Linux
+	// in 2.6.22, Released, 8 July 2007) then fall back to utimes
+	var tv [2]Timeval
+	for i := 0; i < 2; i++ {
+		tv[i].Sec = ts[i].Sec
+		tv[i].Usec = ts[i].Nsec / 1000
+	}
+	return utimes(path, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
+}
+
+//sys	futimesat(dirfd int, path *byte, times *[2]Timeval) (err error)
+
+func Futimesat(dirfd int, path string, tv []Timeval) (err error) {
+	if len(tv) != 2 {
+		return EINVAL
+	}
+	pathp, err := BytePtrFromString(path)
+	if err != nil {
+		return err
+	}
+	err = futimesat(dirfd, pathp, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
+	use(unsafe.Pointer(pathp))
+	return err
+}
+
+func Futimes(fd int, tv []Timeval) (err error) {
+	// Believe it or not, this is the best we can do on Linux
+	// (and is what glibc does).
+	return Utimes("/proc/self/fd/"+itoa(fd), tv)
+}
+
+const ImplementsGetwd = true
+
+//sys	Getcwd(buf []byte) (n int, err error)
+
+func Getwd() (wd string, err error) {
+	var buf [PathMax]byte
+	n, err := Getcwd(buf[0:])
+	if err != nil {
+		return "", err
+	}
+	// Getcwd returns the number of bytes written to buf, including the NUL.
+	if n < 1 || n > len(buf) || buf[n-1] != 0 {
+		return "", EINVAL
+	}
+	return string(buf[0 : n-1]), nil
+}
+
+func Getgroups() (gids []int, err error) {
+	n, err := getgroups(0, nil)
+	if err != nil {
+		return nil, err
+	}
+	if n == 0 {
+		return nil, nil
+	}
+
+	// Sanity check group count.  Max is 1<<16 on Linux.
+	if n < 0 || n > 1<<20 {
+		return nil, EINVAL
+	}
+
+	a := make([]_Gid_t, n)
+	n, err = getgroups(n, &a[0])
+	if err != nil {
+		return nil, err
+	}
+	gids = make([]int, n)
+	for i, v := range a[0:n] {
+		gids[i] = int(v)
+	}
+	return
+}
+
+func Setgroups(gids []int) (err error) {
+	if len(gids) == 0 {
+		return setgroups(0, nil)
+	}
+
+	a := make([]_Gid_t, len(gids))
+	for i, v := range gids {
+		a[i] = _Gid_t(v)
+	}
+	return setgroups(len(a), &a[0])
+}
+
+type WaitStatus uint32
+
+// Wait status is 7 bits at bottom, either 0 (exited),
+// 0x7F (stopped), or a signal number that caused an exit.
+// The 0x80 bit is whether there was a core dump.
+// An extra number (exit code, signal causing a stop)
+// is in the high bits.  At least that's the idea.
+// There are various irregularities.  For example, the
+// "continued" status is 0xFFFF, distinguishing itself
+// from stopped via the core dump bit.
+
+const (
+	mask    = 0x7F
+	core    = 0x80
+	exited  = 0x00
+	stopped = 0x7F
+	shift   = 8
+)
+
+func (w WaitStatus) Exited() bool { return w&mask == exited }
+
+func (w WaitStatus) Signaled() bool { return w&mask != stopped && w&mask != exited }
+
+func (w WaitStatus) Stopped() bool { return w&0xFF == stopped }
+
+func (w WaitStatus) Continued() bool { return w == 0xFFFF }
+
+func (w WaitStatus) CoreDump() bool { return w.Signaled() && w&core != 0 }
+
+func (w WaitStatus) ExitStatus() int {
+	if !w.Exited() {
+		return -1
+	}
+	return int(w>>shift) & 0xFF
+}
+
+func (w WaitStatus) Signal() Signal {
+	if !w.Signaled() {
+		return -1
+	}
+	return Signal(w & mask)
+}
+
+func (w WaitStatus) StopSignal() Signal {
+	if !w.Stopped() {
+		return -1
+	}
+	return Signal(w>>shift) & 0xFF
+}
+
+func (w WaitStatus) TrapCause() int {
+	if w.StopSignal() != SIGTRAP {
+		return -1
+	}
+	return int(w>>shift) >> 8
+}
+
+//sys	wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error)
+
+func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {
+	var status _C_int
+	wpid, err = wait4(pid, &status, options, rusage)
+	if wstatus != nil {
+		*wstatus = WaitStatus(status)
+	}
+	return
+}
+
+func Mkfifo(path string, mode uint32) (err error) {
+	return Mknod(path, mode|S_IFIFO, 0)
+}
+
+func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, _Socklen, error) {
+	if sa.Port < 0 || sa.Port > 0xFFFF {
+		return nil, 0, EINVAL
+	}
+	sa.raw.Family = AF_INET
+	p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
+	p[0] = byte(sa.Port >> 8)
+	p[1] = byte(sa.Port)
+	for i := 0; i < len(sa.Addr); i++ {
+		sa.raw.Addr[i] = sa.Addr[i]
+	}
+	return unsafe.Pointer(&sa.raw), SizeofSockaddrInet4, nil
+}
+
+func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, _Socklen, error) {
+	if sa.Port < 0 || sa.Port > 0xFFFF {
+		return nil, 0, EINVAL
+	}
+	sa.raw.Family = AF_INET6
+	p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
+	p[0] = byte(sa.Port >> 8)
+	p[1] = byte(sa.Port)
+	sa.raw.Scope_id = sa.ZoneId
+	for i := 0; i < len(sa.Addr); i++ {
+		sa.raw.Addr[i] = sa.Addr[i]
+	}
+	return unsafe.Pointer(&sa.raw), SizeofSockaddrInet6, nil
+}
+
+func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, _Socklen, error) {
+	name := sa.Name
+	n := len(name)
+	if n >= len(sa.raw.Path) {
+		return nil, 0, EINVAL
+	}
+	sa.raw.Family = AF_UNIX
+	for i := 0; i < n; i++ {
+		sa.raw.Path[i] = int8(name[i])
+	}
+	// length is family (uint16), name, NUL.
+	sl := _Socklen(2)
+	if n > 0 {
+		sl += _Socklen(n) + 1
+	}
+	if sa.raw.Path[0] == '@' {
+		sa.raw.Path[0] = 0
+		// Don't count trailing NUL for abstract address.
+		sl--
+	}
+
+	return unsafe.Pointer(&sa.raw), sl, nil
+}
+
+type SockaddrLinklayer struct {
+	Protocol uint16
+	Ifindex  int
+	Hatype   uint16
+	Pkttype  uint8
+	Halen    uint8
+	Addr     [8]byte
+	raw      RawSockaddrLinklayer
+}
+
+func (sa *SockaddrLinklayer) sockaddr() (unsafe.Pointer, _Socklen, error) {
+	if sa.Ifindex < 0 || sa.Ifindex > 0x7fffffff {
+		return nil, 0, EINVAL
+	}
+	sa.raw.Family = AF_PACKET
+	sa.raw.Protocol = sa.Protocol
+	sa.raw.Ifindex = int32(sa.Ifindex)
+	sa.raw.Hatype = sa.Hatype
+	sa.raw.Pkttype = sa.Pkttype
+	sa.raw.Halen = sa.Halen
+	for i := 0; i < len(sa.Addr); i++ {
+		sa.raw.Addr[i] = sa.Addr[i]
+	}
+	return unsafe.Pointer(&sa.raw), SizeofSockaddrLinklayer, nil
+}
+
+type SockaddrNetlink struct {
+	Family uint16
+	Pad    uint16
+	Pid    uint32
+	Groups uint32
+	raw    RawSockaddrNetlink
+}
+
+func (sa *SockaddrNetlink) sockaddr() (unsafe.Pointer, _Socklen, error) {
+	sa.raw.Family = AF_NETLINK
+	sa.raw.Pad = sa.Pad
+	sa.raw.Pid = sa.Pid
+	sa.raw.Groups = sa.Groups
+	return unsafe.Pointer(&sa.raw), SizeofSockaddrNetlink, nil
+}
+
+func anyToSockaddr(rsa *RawSockaddrAny) (Sockaddr, error) {
+	switch rsa.Addr.Family {
+	case AF_NETLINK:
+		pp := (*RawSockaddrNetlink)(unsafe.Pointer(rsa))
+		sa := new(SockaddrNetlink)
+		sa.Family = pp.Family
+		sa.Pad = pp.Pad
+		sa.Pid = pp.Pid
+		sa.Groups = pp.Groups
+		return sa, nil
+
+	case AF_PACKET:
+		pp := (*RawSockaddrLinklayer)(unsafe.Pointer(rsa))
+		sa := new(SockaddrLinklayer)
+		sa.Protocol = pp.Protocol
+		sa.Ifindex = int(pp.Ifindex)
+		sa.Hatype = pp.Hatype
+		sa.Pkttype = pp.Pkttype
+		sa.Halen = pp.Halen
+		for i := 0; i < len(sa.Addr); i++ {
+			sa.Addr[i] = pp.Addr[i]
+		}
+		return sa, nil
+
+	case AF_UNIX:
+		pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa))
+		sa := new(SockaddrUnix)
+		if pp.Path[0] == 0 {
+			// "Abstract" Unix domain socket.
+			// Rewrite leading NUL as @ for textual display.
+			// (This is the standard convention.)
+			// Not friendly to overwrite in place,
+			// but the callers below don't care.
+			pp.Path[0] = '@'
+		}
+
+		// Assume path ends at NUL.
+		// This is not technically the Linux semantics for
+		// abstract Unix domain sockets--they are supposed
+		// to be uninterpreted fixed-size binary blobs--but
+		// everyone uses this convention.
+		n := 0
+		for n < len(pp.Path) && pp.Path[n] != 0 {
+			n++
+		}
+		bytes := (*[10000]byte)(unsafe.Pointer(&pp.Path[0]))[0:n]
+		sa.Name = string(bytes)
+		return sa, nil
+
+	case AF_INET:
+		pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))
+		sa := new(SockaddrInet4)
+		p := (*[2]byte)(unsafe.Pointer(&pp.Port))
+		sa.Port = int(p[0])<<8 + int(p[1])
+		for i := 0; i < len(sa.Addr); i++ {
+			sa.Addr[i] = pp.Addr[i]
+		}
+		return sa, nil
+
+	case AF_INET6:
+		pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa))
+		sa := new(SockaddrInet6)
+		p := (*[2]byte)(unsafe.Pointer(&pp.Port))
+		sa.Port = int(p[0])<<8 + int(p[1])
+		sa.ZoneId = pp.Scope_id
+		for i := 0; i < len(sa.Addr); i++ {
+			sa.Addr[i] = pp.Addr[i]
+		}
+		return sa, nil
+	}
+	return nil, EAFNOSUPPORT
+}
+
+func Accept(fd int) (nfd int, sa Sockaddr, err error) {
+	var rsa RawSockaddrAny
+	var len _Socklen = SizeofSockaddrAny
+	nfd, err = accept(fd, &rsa, &len)
+	if err != nil {
+		return
+	}
+	sa, err = anyToSockaddr(&rsa)
+	if err != nil {
+		Close(nfd)
+		nfd = 0
+	}
+	return
+}
+
+func Accept4(fd int, flags int) (nfd int, sa Sockaddr, err error) {
+	var rsa RawSockaddrAny
+	var len _Socklen = SizeofSockaddrAny
+	nfd, err = accept4(fd, &rsa, &len, flags)
+	if err != nil {
+		return
+	}
+	if len > SizeofSockaddrAny {
+		panic("RawSockaddrAny too small")
+	}
+	sa, err = anyToSockaddr(&rsa)
+	if err != nil {
+		Close(nfd)
+		nfd = 0
+	}
+	return
+}
+
+func Getsockname(fd int) (sa Sockaddr, err error) {
+	var rsa RawSockaddrAny
+	var len _Socklen = SizeofSockaddrAny
+	if err = getsockname(fd, &rsa, &len); err != nil {
+		return
+	}
+	return anyToSockaddr(&rsa)
+}
+
+func GetsockoptInet4Addr(fd, level, opt int) (value [4]byte, err error) {
+	vallen := _Socklen(4)
+	err = getsockopt(fd, level, opt, unsafe.Pointer(&value[0]), &vallen)
+	return value, err
+}
+
+func GetsockoptIPMreq(fd, level, opt int) (*IPMreq, error) {
+	var value IPMreq
+	vallen := _Socklen(SizeofIPMreq)
+	err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
+	return &value, err
+}
+
+func GetsockoptIPMreqn(fd, level, opt int) (*IPMreqn, error) {
+	var value IPMreqn
+	vallen := _Socklen(SizeofIPMreqn)
+	err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
+	return &value, err
+}
+
+func GetsockoptIPv6Mreq(fd, level, opt int) (*IPv6Mreq, error) {
+	var value IPv6Mreq
+	vallen := _Socklen(SizeofIPv6Mreq)
+	err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
+	return &value, err
+}
+
+func GetsockoptIPv6MTUInfo(fd, level, opt int) (*IPv6MTUInfo, error) {
+	var value IPv6MTUInfo
+	vallen := _Socklen(SizeofIPv6MTUInfo)
+	err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
+	return &value, err
+}
+
+func GetsockoptICMPv6Filter(fd, level, opt int) (*ICMPv6Filter, error) {
+	var value ICMPv6Filter
+	vallen := _Socklen(SizeofICMPv6Filter)
+	err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
+	return &value, err
+}
+
+func GetsockoptUcred(fd, level, opt int) (*Ucred, error) {
+	var value Ucred
+	vallen := _Socklen(SizeofUcred)
+	err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
+	return &value, err
+}
+
+func SetsockoptIPMreqn(fd, level, opt int, mreq *IPMreqn) (err error) {
+	return setsockopt(fd, level, opt, unsafe.Pointer(mreq), unsafe.Sizeof(*mreq))
+}
+
+func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) {
+	var msg Msghdr
+	var rsa RawSockaddrAny
+	msg.Name = (*byte)(unsafe.Pointer(&rsa))
+	msg.Namelen = uint32(SizeofSockaddrAny)
+	var iov Iovec
+	if len(p) > 0 {
+		iov.Base = (*byte)(unsafe.Pointer(&p[0]))
+		iov.SetLen(len(p))
+	}
+	var dummy byte
+	if len(oob) > 0 {
+		// receive at least one normal byte
+		if len(p) == 0 {
+			iov.Base = &dummy
+			iov.SetLen(1)
+		}
+		msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
+		msg.SetControllen(len(oob))
+	}
+	msg.Iov = &iov
+	msg.Iovlen = 1
+	if n, err = recvmsg(fd, &msg, flags); err != nil {
+		return
+	}
+	oobn = int(msg.Controllen)
+	recvflags = int(msg.Flags)
+	// source address is only specified if the socket is unconnected
+	if rsa.Addr.Family != AF_UNSPEC {
+		from, err = anyToSockaddr(&rsa)
+	}
+	return
+}
+
+func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) {
+	_, err = SendmsgN(fd, p, oob, to, flags)
+	return
+}
+
+func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) {
+	var ptr unsafe.Pointer
+	var salen _Socklen
+	if to != nil {
+		var err error
+		ptr, salen, err = to.sockaddr()
+		if err != nil {
+			return 0, err
+		}
+	}
+	var msg Msghdr
+	msg.Name = (*byte)(unsafe.Pointer(ptr))
+	msg.Namelen = uint32(salen)
+	var iov Iovec
+	if len(p) > 0 {
+		iov.Base = (*byte)(unsafe.Pointer(&p[0]))
+		iov.SetLen(len(p))
+	}
+	var dummy byte
+	if len(oob) > 0 {
+		// send at least one normal byte
+		if len(p) == 0 {
+			iov.Base = &dummy
+			iov.SetLen(1)
+		}
+		msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
+		msg.SetControllen(len(oob))
+	}
+	msg.Iov = &iov
+	msg.Iovlen = 1
+	if n, err = sendmsg(fd, &msg, flags); err != nil {
+		return 0, err
+	}
+	if len(oob) > 0 && len(p) == 0 {
+		n = 0
+	}
+	return n, nil
+}
+
+// BindToDevice binds the socket associated with fd to device.
+func BindToDevice(fd int, device string) (err error) {
+	return SetsockoptString(fd, SOL_SOCKET, SO_BINDTODEVICE, device)
+}
+
+//sys	ptrace(request int, pid int, addr uintptr, data uintptr) (err error)
+
+func ptracePeek(req int, pid int, addr uintptr, out []byte) (count int, err error) {
+	// The peek requests are machine-size oriented, so we wrap it
+	// to retrieve arbitrary-length data.
+
+	// The ptrace syscall differs from glibc's ptrace.
+	// Peeks returns the word in *data, not as the return value.
+
+	var buf [sizeofPtr]byte
+
+	// Leading edge.  PEEKTEXT/PEEKDATA don't require aligned
+	// access (PEEKUSER warns that it might), but if we don't
+	// align our reads, we might straddle an unmapped page
+	// boundary and not get the bytes leading up to the page
+	// boundary.
+	n := 0
+	if addr%sizeofPtr != 0 {
+		err = ptrace(req, pid, addr-addr%sizeofPtr, uintptr(unsafe.Pointer(&buf[0])))
+		if err != nil {
+			return 0, err
+		}
+		n += copy(out, buf[addr%sizeofPtr:])
+		out = out[n:]
+	}
+
+	// Remainder.
+	for len(out) > 0 {
+		// We use an internal buffer to guarantee alignment.
+		// It's not documented if this is necessary, but we're paranoid.
+		err = ptrace(req, pid, addr+uintptr(n), uintptr(unsafe.Pointer(&buf[0])))
+		if err != nil {
+			return n, err
+		}
+		copied := copy(out, buf[0:])
+		n += copied
+		out = out[copied:]
+	}
+
+	return n, nil
+}
+
+func PtracePeekText(pid int, addr uintptr, out []byte) (count int, err error) {
+	return ptracePeek(PTRACE_PEEKTEXT, pid, addr, out)
+}
+
+func PtracePeekData(pid int, addr uintptr, out []byte) (count int, err error) {
+	return ptracePeek(PTRACE_PEEKDATA, pid, addr, out)
+}
+
+func ptracePoke(pokeReq int, peekReq int, pid int, addr uintptr, data []byte) (count int, err error) {
+	// As for ptracePeek, we need to align our accesses to deal
+	// with the possibility of straddling an invalid page.
+
+	// Leading edge.
+	n := 0
+	if addr%sizeofPtr != 0 {
+		var buf [sizeofPtr]byte
+		err = ptrace(peekReq, pid, addr-addr%sizeofPtr, uintptr(unsafe.Pointer(&buf[0])))
+		if err != nil {
+			return 0, err
+		}
+		n += copy(buf[addr%sizeofPtr:], data)
+		word := *((*uintptr)(unsafe.Pointer(&buf[0])))
+		err = ptrace(pokeReq, pid, addr-addr%sizeofPtr, word)
+		if err != nil {
+			return 0, err
+		}
+		data = data[n:]
+	}
+
+	// Interior.
+	for len(data) > sizeofPtr {
+		word := *((*uintptr)(unsafe.Pointer(&data[0])))
+		err = ptrace(pokeReq, pid, addr+uintptr(n), word)
+		if err != nil {
+			return n, err
+		}
+		n += sizeofPtr
+		data = data[sizeofPtr:]
+	}
+
+	// Trailing edge.
+	if len(data) > 0 {
+		var buf [sizeofPtr]byte
+		err = ptrace(peekReq, pid, addr+uintptr(n), uintptr(unsafe.Pointer(&buf[0])))
+		if err != nil {
+			return n, err
+		}
+		copy(buf[0:], data)
+		word := *((*uintptr)(unsafe.Pointer(&buf[0])))
+		err = ptrace(pokeReq, pid, addr+uintptr(n), word)
+		if err != nil {
+			return n, err
+		}
+		n += len(data)
+	}
+
+	return n, nil
+}
+
+func PtracePokeText(pid int, addr uintptr, data []byte) (count int, err error) {
+	return ptracePoke(PTRACE_POKETEXT, PTRACE_PEEKTEXT, pid, addr, data)
+}
+
+func PtracePokeData(pid int, addr uintptr, data []byte) (count int, err error) {
+	return ptracePoke(PTRACE_POKEDATA, PTRACE_PEEKDATA, pid, addr, data)
+}
+
+func PtraceGetRegs(pid int, regsout *PtraceRegs) (err error) {
+	return ptrace(PTRACE_GETREGS, pid, 0, uintptr(unsafe.Pointer(regsout)))
+}
+
+func PtraceSetRegs(pid int, regs *PtraceRegs) (err error) {
+	return ptrace(PTRACE_SETREGS, pid, 0, uintptr(unsafe.Pointer(regs)))
+}
+
+func PtraceSetOptions(pid int, options int) (err error) {
+	return ptrace(PTRACE_SETOPTIONS, pid, 0, uintptr(options))
+}
+
+func PtraceGetEventMsg(pid int) (msg uint, err error) {
+	var data _C_long
+	err = ptrace(PTRACE_GETEVENTMSG, pid, 0, uintptr(unsafe.Pointer(&data)))
+	msg = uint(data)
+	return
+}
+
+func PtraceCont(pid int, signal int) (err error) {
+	return ptrace(PTRACE_CONT, pid, 0, uintptr(signal))
+}
+
+func PtraceSyscall(pid int, signal int) (err error) {
+	return ptrace(PTRACE_SYSCALL, pid, 0, uintptr(signal))
+}
+
+func PtraceSingleStep(pid int) (err error) { return ptrace(PTRACE_SINGLESTEP, pid, 0, 0) }
+
+func PtraceAttach(pid int) (err error) { return ptrace(PTRACE_ATTACH, pid, 0, 0) }
+
+func PtraceDetach(pid int) (err error) { return ptrace(PTRACE_DETACH, pid, 0, 0) }
+
+//sys	reboot(magic1 uint, magic2 uint, cmd int, arg string) (err error)
+
+func Reboot(cmd int) (err error) {
+	return reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, cmd, "")
+}
+
+func clen(n []byte) int {
+	for i := 0; i < len(n); i++ {
+		if n[i] == 0 {
+			return i
+		}
+	}
+	return len(n)
+}
+
+func ReadDirent(fd int, buf []byte) (n int, err error) {
+	return Getdents(fd, buf)
+}
+
+func ParseDirent(buf []byte, max int, names []string) (consumed int, count int, newnames []string) {
+	origlen := len(buf)
+	count = 0
+	for max != 0 && len(buf) > 0 {
+		dirent := (*Dirent)(unsafe.Pointer(&buf[0]))
+		buf = buf[dirent.Reclen:]
+		if dirent.Ino == 0 { // File absent in directory.
+			continue
+		}
+		bytes := (*[10000]byte)(unsafe.Pointer(&dirent.Name[0]))
+		var name = string(bytes[0:clen(bytes[:])])
+		if name == "." || name == ".." { // Useless names
+			continue
+		}
+		max--
+		count++
+		names = append(names, name)
+	}
+	return origlen - len(buf), count, names
+}
+
+//sys	mount(source string, target string, fstype string, flags uintptr, data *byte) (err error)
+
+func Mount(source string, target string, fstype string, flags uintptr, data string) (err error) {
+	// Certain file systems get rather angry and EINVAL if you give
+	// them an empty string of data, rather than NULL.
+	if data == "" {
+		return mount(source, target, fstype, flags, nil)
+	}
+	datap, err := BytePtrFromString(data)
+	if err != nil {
+		return err
+	}
+	err = mount(source, target, fstype, flags, datap)
+	use(unsafe.Pointer(datap))
+	return err
+}
+
+// Sendto
+// Recvfrom
+// Socketpair
+
+/*
+ * Direct access
+ */
+//sys	Access(path string, mode uint32) (err error)
+//sys	Acct(path string) (err error)
+//sys	Adjtimex(buf *Timex) (state int, err error)
+//sys	Chdir(path string) (err error)
+//sys	Chmod(path string, mode uint32) (err error)
+//sys	Chroot(path string) (err error)
+//sys	Close(fd int) (err error)
+//sys	Creat(path string, mode uint32) (fd int, err error)
+//sysnb	Dup(oldfd int) (fd int, err error)
+//sysnb	Dup2(oldfd int, newfd int) (err error)
+//sysnb	Dup3(oldfd int, newfd int, flags int) (err error)
+//sysnb	EpollCreate(size int) (fd int, err error)
+//sysnb	EpollCreate1(flag int) (fd int, err error)
+//sysnb	EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error)
+//sys	EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error)
+//sys	Exit(code int) = SYS_EXIT_GROUP
+//sys	Faccessat(dirfd int, path string, mode uint32, flags int) (err error)
+//sys	Fallocate(fd int, mode uint32, off int64, len int64) (err error)
+//sys	Fchdir(fd int) (err error)
+//sys	Fchmod(fd int, mode uint32) (err error)
+//sys	Fchmodat(dirfd int, path string, mode uint32, flags int) (err error)
+//sys	Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error)
+//sys	fcntl(fd int, cmd int, arg int) (val int, err error)
+//sys	Fdatasync(fd int) (err error)
+//sys	Flock(fd int, how int) (err error)
+//sys	Fsync(fd int) (err error)
+//sys	Getdents(fd int, buf []byte) (n int, err error) = SYS_GETDENTS64
+//sysnb	Getpgid(pid int) (pgid int, err error)
+//sysnb	Getpgrp() (pid int)
+//sysnb	Getpid() (pid int)
+//sysnb	Getppid() (ppid int)
+//sys	Getpriority(which int, who int) (prio int, err error)
+//sysnb	Getrusage(who int, rusage *Rusage) (err error)
+//sysnb	Gettid() (tid int)
+//sys	Getxattr(path string, attr string, dest []byte) (sz int, err error)
+//sys	InotifyAddWatch(fd int, pathname string, mask uint32) (watchdesc int, err error)
+//sysnb	InotifyInit() (fd int, err error)
+//sysnb	InotifyInit1(flags int) (fd int, err error)
+//sysnb	InotifyRmWatch(fd int, watchdesc uint32) (success int, err error)
+//sysnb	Kill(pid int, sig Signal) (err error)
+//sys	Klogctl(typ int, buf []byte) (n int, err error) = SYS_SYSLOG
+//sys	Link(oldpath string, newpath string) (err error)
+//sys	Listxattr(path string, dest []byte) (sz int, err error)
+//sys	Mkdir(path string, mode uint32) (err error)
+//sys	Mkdirat(dirfd int, path string, mode uint32) (err error)
+//sys	Mknod(path string, mode uint32, dev int) (err error)
+//sys	Mknodat(dirfd int, path string, mode uint32, dev int) (err error)
+//sys	Nanosleep(time *Timespec, leftover *Timespec) (err error)
+//sys	Pause() (err error)
+//sys	PivotRoot(newroot string, putold string) (err error) = SYS_PIVOT_ROOT
+//sysnb prlimit(pid int, resource int, old *Rlimit, newlimit *Rlimit) (err error) = SYS_PRLIMIT64
+//sys	read(fd int, p []byte) (n int, err error)
+//sys	Readlink(path string, buf []byte) (n int, err error)
+//sys	Removexattr(path string, attr string) (err error)
+//sys	Rename(oldpath string, newpath string) (err error)
+//sys	Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error)
+//sys	Rmdir(path string) (err error)
+//sys	Setdomainname(p []byte) (err error)
+//sys	Sethostname(p []byte) (err error)
+//sysnb	Setpgid(pid int, pgid int) (err error)
+//sysnb	Setsid() (pid int, err error)
+//sysnb	Settimeofday(tv *Timeval) (err error)
+
+// issue 1435.
+// On linux Setuid and Setgid only affects the current thread, not the process.
+// This does not match what most callers expect so we must return an error
+// here rather than letting the caller think that the call succeeded.
+
+func Setuid(uid int) (err error) {
+	return EOPNOTSUPP
+}
+
+func Setgid(uid int) (err error) {
+	return EOPNOTSUPP
+}
+
+//sys	Setpriority(which int, who int, prio int) (err error)
+//sys	Setxattr(path string, attr string, data []byte, flags int) (err error)
+//sys	Symlink(oldpath string, newpath string) (err error)
+//sys	Sync()
+//sysnb	Sysinfo(info *Sysinfo_t) (err error)
+//sys	Tee(rfd int, wfd int, len int, flags int) (n int64, err error)
+//sysnb	Tgkill(tgid int, tid int, sig Signal) (err error)
+//sysnb	Times(tms *Tms) (ticks uintptr, err error)
+//sysnb	Umask(mask int) (oldmask int)
+//sysnb	Uname(buf *Utsname) (err error)
+//sys	Unlink(path string) (err error)
+//sys	Unlinkat(dirfd int, path string) (err error)
+//sys	Unmount(target string, flags int) (err error) = SYS_UMOUNT2
+//sys	Unshare(flags int) (err error)
+//sys	Ustat(dev int, ubuf *Ustat_t) (err error)
+//sys	Utime(path string, buf *Utimbuf) (err error)
+//sys	write(fd int, p []byte) (n int, err error)
+//sys	exitThread(code int) (err error) = SYS_EXIT
+//sys	readlen(fd int, p *byte, np int) (n int, err error) = SYS_READ
+//sys	writelen(fd int, p *byte, np int) (n int, err error) = SYS_WRITE
+
+// mmap varies by architecture; see syscall_linux_*.go.
+//sys	munmap(addr uintptr, length uintptr) (err error)
+
+var mapper = &mmapper{
+	active: make(map[*byte][]byte),
+	mmap:   mmap,
+	munmap: munmap,
+}
+
+func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
+	return mapper.Mmap(fd, offset, length, prot, flags)
+}
+
+func Munmap(b []byte) (err error) {
+	return mapper.Munmap(b)
+}
+
+//sys	Madvise(b []byte, advice int) (err error)
+//sys	Mprotect(b []byte, prot int) (err error)
+//sys	Mlock(b []byte) (err error)
+//sys	Munlock(b []byte) (err error)
+//sys	Mlockall(flags int) (err error)
+//sys	Munlockall() (err error)
+
+/*
+ * Unimplemented
+ */
+// AddKey
+// AfsSyscall
+// Alarm
+// ArchPrctl
+// Brk
+// Capget
+// Capset
+// ClockGetres
+// ClockGettime
+// ClockNanosleep
+// ClockSettime
+// Clone
+// CreateModule
+// DeleteModule
+// EpollCtlOld
+// EpollPwait
+// EpollWaitOld
+// Eventfd
+// Execve
+// Fadvise64
+// Fgetxattr
+// Flistxattr
+// Fork
+// Fremovexattr
+// Fsetxattr
+// Futex
+// GetKernelSyms
+// GetMempolicy
+// GetRobustList
+// GetThreadArea
+// Getitimer
+// Getpmsg
+// IoCancel
+// IoDestroy
+// IoGetevents
+// IoSetup
+// IoSubmit
+// Ioctl
+// IoprioGet
+// IoprioSet
+// KexecLoad
+// Keyctl
+// Lgetxattr
+// Llistxattr
+// LookupDcookie
+// Lremovexattr
+// Lsetxattr
+// Mbind
+// MigratePages
+// Mincore
+// ModifyLdt
+// Mount
+// MovePages
+// Mprotect
+// MqGetsetattr
+// MqNotify
+// MqOpen
+// MqTimedreceive
+// MqTimedsend
+// MqUnlink
+// Mremap
+// Msgctl
+// Msgget
+// Msgrcv
+// Msgsnd
+// Msync
+// Newfstatat
+// Nfsservctl
+// Personality
+// Poll
+// Ppoll
+// Prctl
+// Pselect6
+// Ptrace
+// Putpmsg
+// QueryModule
+// Quotactl
+// Readahead
+// Readv
+// RemapFilePages
+// RequestKey
+// RestartSyscall
+// RtSigaction
+// RtSigpending
+// RtSigprocmask
+// RtSigqueueinfo
+// RtSigreturn
+// RtSigsuspend
+// RtSigtimedwait
+// SchedGetPriorityMax
+// SchedGetPriorityMin
+// SchedGetaffinity
+// SchedGetparam
+// SchedGetscheduler
+// SchedRrGetInterval
+// SchedSetaffinity
+// SchedSetparam
+// SchedYield
+// Security
+// Semctl
+// Semget
+// Semop
+// Semtimedop
+// SetMempolicy
+// SetRobustList
+// SetThreadArea
+// SetTidAddress
+// Shmat
+// Shmctl
+// Shmdt
+// Shmget
+// Sigaltstack
+// Signalfd
+// Swapoff
+// Swapon
+// Sysfs
+// TimerCreate
+// TimerDelete
+// TimerGetoverrun
+// TimerGettime
+// TimerSettime
+// Timerfd
+// Tkill (obsolete)
+// Tuxcall
+// Umount2
+// Uselib
+// Utimensat
+// Vfork
+// Vhangup
+// Vmsplice
+// Vserver
+// Waitid
+// _Sysctl
diff --git a/src/syscall/syscall_linux_386.go b/src/syscall/syscall_linux_386.go
new file mode 100644
index 0000000..8278750
--- /dev/null
+++ b/src/syscall/syscall_linux_386.go
@@ -0,0 +1,356 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// TODO(rsc): Rewrite all nn(SP) references into name+(nn-8)(FP)
+// so that go vet can check that they are correct.
+
+package syscall
+
+import "unsafe"
+
+func Getpagesize() int { return 4096 }
+
+func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
+
+func NsecToTimespec(nsec int64) (ts Timespec) {
+	ts.Sec = int32(nsec / 1e9)
+	ts.Nsec = int32(nsec % 1e9)
+	return
+}
+
+func TimevalToNsec(tv Timeval) int64 { return int64(tv.Sec)*1e9 + int64(tv.Usec)*1e3 }
+
+func NsecToTimeval(nsec int64) (tv Timeval) {
+	nsec += 999 // round up to microsecond
+	tv.Sec = int32(nsec / 1e9)
+	tv.Usec = int32(nsec % 1e9 / 1e3)
+	return
+}
+
+// 64-bit file system and 32-bit uid calls
+// (386 default is 32-bit file system and 16-bit uid).
+//sys	Chown(path string, uid int, gid int) (err error) = SYS_CHOWN32
+//sys	Fchown(fd int, uid int, gid int) (err error) = SYS_FCHOWN32
+//sys	Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64
+//sys	Ftruncate(fd int, length int64) (err error) = SYS_FTRUNCATE64
+//sysnb	Getegid() (egid int) = SYS_GETEGID32
+//sysnb	Geteuid() (euid int) = SYS_GETEUID32
+//sysnb	Getgid() (gid int) = SYS_GETGID32
+//sysnb	Getuid() (uid int) = SYS_GETUID32
+//sys	Ioperm(from int, num int, on int) (err error)
+//sys	Iopl(level int) (err error)
+//sys	Lchown(path string, uid int, gid int) (err error) = SYS_LCHOWN32
+//sys	Lstat(path string, stat *Stat_t) (err error) = SYS_LSTAT64
+//sys	Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
+//sys	Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
+//sys	sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) = SYS_SENDFILE64
+//sys	Setfsgid(gid int) (err error) = SYS_SETFSGID32
+//sys	Setfsuid(uid int) (err error) = SYS_SETFSUID32
+//sysnb	Setregid(rgid int, egid int) (err error) = SYS_SETREGID32
+//sysnb	Setresgid(rgid int, egid int, sgid int) (err error) = SYS_SETRESGID32
+//sysnb	Setresuid(ruid int, euid int, suid int) (err error) = SYS_SETRESUID32
+//sysnb	Setreuid(ruid int, euid int) (err error) = SYS_SETREUID32
+//sys	Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error)
+//sys	Stat(path string, stat *Stat_t) (err error) = SYS_STAT64
+//sys	SyncFileRange(fd int, off int64, n int64, flags int) (err error)
+//sys	Truncate(path string, length int64) (err error) = SYS_TRUNCATE64
+//sysnb	getgroups(n int, list *_Gid_t) (nn int, err error) = SYS_GETGROUPS32
+//sysnb	setgroups(n int, list *_Gid_t) (err error) = SYS_SETGROUPS32
+//sys	Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) = SYS__NEWSELECT
+
+//sys	mmap2(addr uintptr, length uintptr, prot int, flags int, fd int, pageOffset uintptr) (xaddr uintptr, err error)
+
+func mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) {
+	page := uintptr(offset / 4096)
+	if offset != int64(page)*4096 {
+		return 0, EINVAL
+	}
+	return mmap2(addr, length, prot, flags, fd, page)
+}
+
+type rlimit32 struct {
+	Cur uint32
+	Max uint32
+}
+
+//sysnb getrlimit(resource int, rlim *rlimit32) (err error) = SYS_GETRLIMIT
+
+const rlimInf32 = ^uint32(0)
+const rlimInf64 = ^uint64(0)
+
+func Getrlimit(resource int, rlim *Rlimit) (err error) {
+	err = prlimit(0, resource, nil, rlim)
+	if err != ENOSYS {
+		return err
+	}
+
+	rl := rlimit32{}
+	err = getrlimit(resource, &rl)
+	if err != nil {
+		return
+	}
+
+	if rl.Cur == rlimInf32 {
+		rlim.Cur = rlimInf64
+	} else {
+		rlim.Cur = uint64(rl.Cur)
+	}
+
+	if rl.Max == rlimInf32 {
+		rlim.Max = rlimInf64
+	} else {
+		rlim.Max = uint64(rl.Max)
+	}
+	return
+}
+
+//sysnb setrlimit(resource int, rlim *rlimit32) (err error) = SYS_SETRLIMIT
+
+func Setrlimit(resource int, rlim *Rlimit) (err error) {
+	err = prlimit(0, resource, rlim, nil)
+	if err != ENOSYS {
+		return err
+	}
+
+	rl := rlimit32{}
+	if rlim.Cur == rlimInf64 {
+		rl.Cur = rlimInf32
+	} else if rlim.Cur < uint64(rlimInf32) {
+		rl.Cur = uint32(rlim.Cur)
+	} else {
+		return EINVAL
+	}
+	if rlim.Max == rlimInf64 {
+		rl.Max = rlimInf32
+	} else if rlim.Max < uint64(rlimInf32) {
+		rl.Max = uint32(rlim.Max)
+	} else {
+		return EINVAL
+	}
+
+	return setrlimit(resource, &rl)
+}
+
+// Underlying system call writes to newoffset via pointer.
+// Implemented in assembly to avoid allocation.
+func seek(fd int, offset int64, whence int) (newoffset int64, err Errno)
+
+func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
+	newoffset, errno := seek(fd, offset, whence)
+	if errno != 0 {
+		return 0, errno
+	}
+	return newoffset, nil
+}
+
+// Vsyscalls on amd64.
+//sysnb	Gettimeofday(tv *Timeval) (err error)
+//sysnb	Time(t *Time_t) (tt Time_t, err error)
+
+// On x86 Linux, all the socket calls go through an extra indirection,
+// I think because the 5-register system call interface can't handle
+// the 6-argument calls like sendto and recvfrom.  Instead the
+// arguments to the underlying system call are the number below
+// and a pointer to an array of uintptr.  We hide the pointer in the
+// socketcall assembly to avoid allocation on every system call.
+
+const (
+	// see linux/net.h
+	_SOCKET      = 1
+	_BIND        = 2
+	_CONNECT     = 3
+	_LISTEN      = 4
+	_ACCEPT      = 5
+	_GETSOCKNAME = 6
+	_GETPEERNAME = 7
+	_SOCKETPAIR  = 8
+	_SEND        = 9
+	_RECV        = 10
+	_SENDTO      = 11
+	_RECVFROM    = 12
+	_SHUTDOWN    = 13
+	_SETSOCKOPT  = 14
+	_GETSOCKOPT  = 15
+	_SENDMSG     = 16
+	_RECVMSG     = 17
+	_ACCEPT4     = 18
+	_RECVMMSG    = 19
+	_SENDMMSG    = 20
+)
+
+func socketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (n int, err Errno)
+func rawsocketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (n int, err Errno)
+
+func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
+	fd, e := socketcall(_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), 0, 0, 0)
+	if e != 0 {
+		err = e
+	}
+	return
+}
+
+func accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) {
+	fd, e := socketcall(_ACCEPT4, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0)
+	if e != 0 {
+		err = e
+	}
+	return
+}
+
+func getsockname(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
+	_, e := rawsocketcall(_GETSOCKNAME, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), 0, 0, 0)
+	if e != 0 {
+		err = e
+	}
+	return
+}
+
+func getpeername(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
+	_, e := rawsocketcall(_GETPEERNAME, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), 0, 0, 0)
+	if e != 0 {
+		err = e
+	}
+	return
+}
+
+func socketpair(domain int, typ int, flags int, fd *[2]int32) (err error) {
+	_, e := rawsocketcall(_SOCKETPAIR, uintptr(domain), uintptr(typ), uintptr(flags), uintptr(unsafe.Pointer(fd)), 0, 0)
+	if e != 0 {
+		err = e
+	}
+	return
+}
+
+func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
+	_, e := socketcall(_BIND, uintptr(s), uintptr(addr), uintptr(addrlen), 0, 0, 0)
+	if e != 0 {
+		err = e
+	}
+	return
+}
+
+func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
+	_, e := socketcall(_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen), 0, 0, 0)
+	if e != 0 {
+		err = e
+	}
+	return
+}
+
+func socket(domain int, typ int, proto int) (fd int, err error) {
+	fd, e := rawsocketcall(_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto), 0, 0, 0)
+	if e != 0 {
+		err = e
+	}
+	return
+}
+
+func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) {
+	_, e := socketcall(_GETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
+	if e != 0 {
+		err = e
+	}
+	return
+}
+
+func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) {
+	_, e := socketcall(_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), vallen, 0)
+	if e != 0 {
+		err = e
+	}
+	return
+}
+
+func recvfrom(s int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) {
+	var base uintptr
+	if len(p) > 0 {
+		base = uintptr(unsafe.Pointer(&p[0]))
+	}
+	n, e := socketcall(_RECVFROM, uintptr(s), base, uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
+	if e != 0 {
+		err = e
+	}
+	return
+}
+
+func sendto(s int, p []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) {
+	var base uintptr
+	if len(p) > 0 {
+		base = uintptr(unsafe.Pointer(&p[0]))
+	}
+	_, e := socketcall(_SENDTO, uintptr(s), base, uintptr(len(p)), uintptr(flags), uintptr(to), uintptr(addrlen))
+	if e != 0 {
+		err = e
+	}
+	return
+}
+
+func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
+	n, e := socketcall(_RECVMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags), 0, 0, 0)
+	if e != 0 {
+		err = e
+	}
+	return
+}
+
+func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
+	n, e := socketcall(_SENDMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags), 0, 0, 0)
+	if e != 0 {
+		err = e
+	}
+	return
+}
+
+func Listen(s int, n int) (err error) {
+	_, e := socketcall(_LISTEN, uintptr(s), uintptr(n), 0, 0, 0, 0)
+	if e != 0 {
+		err = e
+	}
+	return
+}
+
+func Shutdown(s, how int) (err error) {
+	_, e := socketcall(_SHUTDOWN, uintptr(s), uintptr(how), 0, 0, 0, 0)
+	if e != 0 {
+		err = e
+	}
+	return
+}
+
+func Fstatfs(fd int, buf *Statfs_t) (err error) {
+	_, _, e := Syscall(SYS_FSTATFS64, uintptr(fd), unsafe.Sizeof(*buf), uintptr(unsafe.Pointer(buf)))
+	if e != 0 {
+		err = e
+	}
+	return
+}
+
+func Statfs(path string, buf *Statfs_t) (err error) {
+	pathp, err := BytePtrFromString(path)
+	if err != nil {
+		return err
+	}
+	_, _, e := Syscall(SYS_STATFS64, uintptr(unsafe.Pointer(pathp)), unsafe.Sizeof(*buf), uintptr(unsafe.Pointer(buf)))
+	use(unsafe.Pointer(pathp))
+	if e != 0 {
+		err = e
+	}
+	return
+}
+
+func (r *PtraceRegs) PC() uint64 { return uint64(uint32(r.Eip)) }
+
+func (r *PtraceRegs) SetPC(pc uint64) { r.Eip = int32(pc) }
+
+func (iov *Iovec) SetLen(length int) {
+	iov.Len = uint32(length)
+}
+
+func (msghdr *Msghdr) SetControllen(length int) {
+	msghdr.Controllen = uint32(length)
+}
+
+func (cmsg *Cmsghdr) SetLen(length int) {
+	cmsg.Len = uint32(length)
+}
diff --git a/src/syscall/syscall_linux_amd64.go b/src/syscall/syscall_linux_amd64.go
new file mode 100644
index 0000000..74a89fb
--- /dev/null
+++ b/src/syscall/syscall_linux_amd64.go
@@ -0,0 +1,114 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package syscall
+
+//sys	Chown(path string, uid int, gid int) (err error)
+//sys	Fchown(fd int, uid int, gid int) (err error)
+//sys	Fstat(fd int, stat *Stat_t) (err error)
+//sys	Fstatfs(fd int, buf *Statfs_t) (err error)
+//sys	Ftruncate(fd int, length int64) (err error)
+//sysnb	Getegid() (egid int)
+//sysnb	Geteuid() (euid int)
+//sysnb	Getgid() (gid int)
+//sysnb	Getrlimit(resource int, rlim *Rlimit) (err error)
+//sysnb	Getuid() (uid int)
+//sys	Ioperm(from int, num int, on int) (err error)
+//sys	Iopl(level int) (err error)
+//sys	Lchown(path string, uid int, gid int) (err error)
+//sys	Listen(s int, n int) (err error)
+//sys	Lstat(path string, stat *Stat_t) (err error)
+//sys	Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
+//sys	Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
+//sys	Seek(fd int, offset int64, whence int) (off int64, err error) = SYS_LSEEK
+//sys	Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error)
+//sys	sendfile(outfd int, infd int, offset *int64, count int) (written int, err error)
+//sys	Setfsgid(gid int) (err error)
+//sys	Setfsuid(uid int) (err error)
+//sysnb	Setregid(rgid int, egid int) (err error)
+//sysnb	Setresgid(rgid int, egid int, sgid int) (err error)
+//sysnb	Setresuid(ruid int, euid int, suid int) (err error)
+//sysnb	Setrlimit(resource int, rlim *Rlimit) (err error)
+//sysnb	Setreuid(ruid int, euid int) (err error)
+//sys	Shutdown(fd int, how int) (err error)
+//sys	Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error)
+//sys	Stat(path string, stat *Stat_t) (err error)
+//sys	Statfs(path string, buf *Statfs_t) (err error)
+//sys	SyncFileRange(fd int, off int64, n int64, flags int) (err error)
+//sys	Truncate(path string, length int64) (err error)
+//sys	accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error)
+//sys	accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error)
+//sys	bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
+//sys	connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
+//sysnb	getgroups(n int, list *_Gid_t) (nn int, err error)
+//sysnb	setgroups(n int, list *_Gid_t) (err error)
+//sys	getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error)
+//sys	setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error)
+//sysnb	socket(domain int, typ int, proto int) (fd int, err error)
+//sysnb	socketpair(domain int, typ int, proto int, fd *[2]int32) (err error)
+//sysnb	getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)
+//sysnb	getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)
+//sys	recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error)
+//sys	sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error)
+//sys	recvmsg(s int, msg *Msghdr, flags int) (n int, err error)
+//sys	sendmsg(s int, msg *Msghdr, flags int) (n int, err error)
+//sys	mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error)
+
+func Getpagesize() int { return 4096 }
+
+//go:noescape
+func gettimeofday(tv *Timeval) (err Errno)
+
+func Gettimeofday(tv *Timeval) (err error) {
+	errno := gettimeofday(tv)
+	if errno != 0 {
+		return errno
+	}
+	return nil
+}
+
+func Time(t *Time_t) (tt Time_t, err error) {
+	var tv Timeval
+	errno := gettimeofday(&tv)
+	if errno != 0 {
+		return 0, errno
+	}
+	if t != nil {
+		*t = Time_t(tv.Sec)
+	}
+	return Time_t(tv.Sec), nil
+}
+
+func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
+
+func NsecToTimespec(nsec int64) (ts Timespec) {
+	ts.Sec = nsec / 1e9
+	ts.Nsec = nsec % 1e9
+	return
+}
+
+func TimevalToNsec(tv Timeval) int64 { return int64(tv.Sec)*1e9 + int64(tv.Usec)*1e3 }
+
+func NsecToTimeval(nsec int64) (tv Timeval) {
+	nsec += 999 // round up to microsecond
+	tv.Sec = nsec / 1e9
+	tv.Usec = nsec % 1e9 / 1e3
+	return
+}
+
+func (r *PtraceRegs) PC() uint64 { return r.Rip }
+
+func (r *PtraceRegs) SetPC(pc uint64) { r.Rip = pc }
+
+func (iov *Iovec) SetLen(length int) {
+	iov.Len = uint64(length)
+}
+
+func (msghdr *Msghdr) SetControllen(length int) {
+	msghdr.Controllen = uint64(length)
+}
+
+func (cmsg *Cmsghdr) SetLen(length int) {
+	cmsg.Len = uint64(length)
+}
diff --git a/src/syscall/syscall_linux_arm.go b/src/syscall/syscall_linux_arm.go
new file mode 100644
index 0000000..b127345
--- /dev/null
+++ b/src/syscall/syscall_linux_arm.go
@@ -0,0 +1,196 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package syscall
+
+import "unsafe"
+
+func Getpagesize() int { return 4096 }
+
+func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
+
+func NsecToTimespec(nsec int64) (ts Timespec) {
+	ts.Sec = int32(nsec / 1e9)
+	ts.Nsec = int32(nsec % 1e9)
+	return
+}
+
+func NsecToTimeval(nsec int64) (tv Timeval) {
+	nsec += 999 // round up to microsecond
+	tv.Sec = int32(nsec / 1e9)
+	tv.Usec = int32(nsec % 1e9 / 1e3)
+	return
+}
+
+// Underlying system call writes to newoffset via pointer.
+// Implemented in assembly to avoid allocation.
+func seek(fd int, offset int64, whence int) (newoffset int64, err Errno)
+
+func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
+	newoffset, errno := seek(fd, offset, whence)
+	if errno != 0 {
+		return 0, errno
+	}
+	return newoffset, nil
+}
+
+//sys	accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error)
+//sys	accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error)
+//sys	bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
+//sys	connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
+//sysnb	getgroups(n int, list *_Gid_t) (nn int, err error) = SYS_GETGROUPS32
+//sysnb	setgroups(n int, list *_Gid_t) (err error) = SYS_SETGROUPS32
+//sys	getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error)
+//sys	setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error)
+//sysnb	socket(domain int, typ int, proto int) (fd int, err error)
+//sysnb	getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)
+//sysnb	getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error)
+//sys	recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error)
+//sys	sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error)
+//sysnb	socketpair(domain int, typ int, flags int, fd *[2]int32) (err error)
+//sys	recvmsg(s int, msg *Msghdr, flags int) (n int, err error)
+//sys	sendmsg(s int, msg *Msghdr, flags int) (n int, err error)
+
+// 64-bit file system and 32-bit uid calls
+// (16-bit uid calls are not always supported in newer kernels)
+//sys	Chown(path string, uid int, gid int) (err error) = SYS_CHOWN32
+//sys	Fchown(fd int, uid int, gid int) (err error) = SYS_FCHOWN32
+//sys	Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64
+//sysnb	Getegid() (egid int) = SYS_GETEGID32
+//sysnb	Geteuid() (euid int) = SYS_GETEUID32
+//sysnb	Getgid() (gid int) = SYS_GETGID32
+//sysnb	Getuid() (uid int) = SYS_GETUID32
+//sys	Lchown(path string, uid int, gid int) (err error) = SYS_LCHOWN32
+//sys	Listen(s int, n int) (err error)
+//sys	Lstat(path string, stat *Stat_t) (err error) = SYS_LSTAT64
+//sys	sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) = SYS_SENDFILE64
+//sys	Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) = SYS__NEWSELECT
+//sys	Setfsgid(gid int) (err error) = SYS_SETFSGID32
+//sys	Setfsuid(uid int) (err error) = SYS_SETFSUID32
+//sysnb	Setregid(rgid int, egid int) (err error) = SYS_SETREGID32
+//sysnb	Setresgid(rgid int, egid int, sgid int) (err error) = SYS_SETRESGID32
+//sysnb	Setresuid(ruid int, euid int, suid int) (err error) = SYS_SETRESUID32
+//sysnb	Setreuid(ruid int, euid int) (err error) = SYS_SETREUID32
+//sys	Shutdown(fd int, how int) (err error)
+//sys	Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error)
+//sys	Stat(path string, stat *Stat_t) (err error) = SYS_STAT64
+
+// Vsyscalls on amd64.
+//sysnb	Gettimeofday(tv *Timeval) (err error)
+//sysnb	Time(t *Time_t) (tt Time_t, err error)
+
+//sys   Pread(fd int, p []byte, offset int64) (n int, err error) = SYS_PREAD64
+//sys   Pwrite(fd int, p []byte, offset int64) (n int, err error) = SYS_PWRITE64
+//sys	Truncate(path string, length int64) (err error) = SYS_TRUNCATE64
+//sys	Ftruncate(fd int, length int64) (err error) = SYS_FTRUNCATE64
+
+//sys	mmap2(addr uintptr, length uintptr, prot int, flags int, fd int, pageOffset uintptr) (xaddr uintptr, err error)
+
+func Fstatfs(fd int, buf *Statfs_t) (err error) {
+	_, _, e := Syscall(SYS_FSTATFS64, uintptr(fd), unsafe.Sizeof(*buf), uintptr(unsafe.Pointer(buf)))
+	if e != 0 {
+		err = e
+	}
+	return
+}
+
+func Statfs(path string, buf *Statfs_t) (err error) {
+	pathp, err := BytePtrFromString(path)
+	if err != nil {
+		return err
+	}
+	_, _, e := Syscall(SYS_STATFS64, uintptr(unsafe.Pointer(pathp)), unsafe.Sizeof(*buf), uintptr(unsafe.Pointer(buf)))
+	use(unsafe.Pointer(pathp))
+	if e != 0 {
+		err = e
+	}
+	return
+}
+
+func mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) {
+	page := uintptr(offset / 4096)
+	if offset != int64(page)*4096 {
+		return 0, EINVAL
+	}
+	return mmap2(addr, length, prot, flags, fd, page)
+}
+
+type rlimit32 struct {
+	Cur uint32
+	Max uint32
+}
+
+//sysnb getrlimit(resource int, rlim *rlimit32) (err error) = SYS_GETRLIMIT
+
+const rlimInf32 = ^uint32(0)
+const rlimInf64 = ^uint64(0)
+
+func Getrlimit(resource int, rlim *Rlimit) (err error) {
+	err = prlimit(0, resource, nil, rlim)
+	if err != ENOSYS {
+		return err
+	}
+
+	rl := rlimit32{}
+	err = getrlimit(resource, &rl)
+	if err != nil {
+		return
+	}
+
+	if rl.Cur == rlimInf32 {
+		rlim.Cur = rlimInf64
+	} else {
+		rlim.Cur = uint64(rl.Cur)
+	}
+
+	if rl.Max == rlimInf32 {
+		rlim.Max = rlimInf64
+	} else {
+		rlim.Max = uint64(rl.Max)
+	}
+	return
+}
+
+//sysnb setrlimit(resource int, rlim *rlimit32) (err error) = SYS_SETRLIMIT
+
+func Setrlimit(resource int, rlim *Rlimit) (err error) {
+	err = prlimit(0, resource, rlim, nil)
+	if err != ENOSYS {
+		return err
+	}
+
+	rl := rlimit32{}
+	if rlim.Cur == rlimInf64 {
+		rl.Cur = rlimInf32
+	} else if rlim.Cur < uint64(rlimInf32) {
+		rl.Cur = uint32(rlim.Cur)
+	} else {
+		return EINVAL
+	}
+	if rlim.Max == rlimInf64 {
+		rl.Max = rlimInf32
+	} else if rlim.Max < uint64(rlimInf32) {
+		rl.Max = uint32(rlim.Max)
+	} else {
+		return EINVAL
+	}
+
+	return setrlimit(resource, &rl)
+}
+
+func (r *PtraceRegs) PC() uint64 { return uint64(r.Uregs[15]) }
+
+func (r *PtraceRegs) SetPC(pc uint64) { r.Uregs[15] = uint32(pc) }
+
+func (iov *Iovec) SetLen(length int) {
+	iov.Len = uint32(length)
+}
+
+func (msghdr *Msghdr) SetControllen(length int) {
+	msghdr.Controllen = uint32(length)
+}
+
+func (cmsg *Cmsghdr) SetLen(length int) {
+	cmsg.Len = uint32(length)
+}
diff --git a/src/pkg/syscall/syscall_nacl.go b/src/syscall/syscall_nacl.go
similarity index 100%
rename from src/pkg/syscall/syscall_nacl.go
rename to src/syscall/syscall_nacl.go
diff --git a/src/pkg/syscall/syscall_nacl_386.go b/src/syscall/syscall_nacl_386.go
similarity index 100%
rename from src/pkg/syscall/syscall_nacl_386.go
rename to src/syscall/syscall_nacl_386.go
diff --git a/src/pkg/syscall/syscall_nacl_amd64p32.go b/src/syscall/syscall_nacl_amd64p32.go
similarity index 100%
rename from src/pkg/syscall/syscall_nacl_amd64p32.go
rename to src/syscall/syscall_nacl_amd64p32.go
diff --git a/src/syscall/syscall_nacl_arm.go b/src/syscall/syscall_nacl_arm.go
new file mode 100644
index 0000000..fc0cdda
--- /dev/null
+++ b/src/syscall/syscall_nacl_arm.go
@@ -0,0 +1,32 @@
+// Copyright 2014 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package syscall
+
+type Timespec struct {
+	Sec  int64
+	Nsec int32
+}
+
+type Timeval struct {
+	Sec  int64
+	Usec int32
+}
+
+func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
+
+func NsecToTimespec(nsec int64) (ts Timespec) {
+	ts.Sec = int64(nsec / 1e9)
+	ts.Nsec = int32(nsec % 1e9)
+	return
+}
+
+func TimevalToNsec(tv Timeval) int64 { return int64(tv.Sec)*1e9 + int64(tv.Usec)*1e3 }
+
+func NsecToTimeval(nsec int64) (tv Timeval) {
+	nsec += 999 // round up to microsecond
+	tv.Usec = int32(nsec % 1e9 / 1e3)
+	tv.Sec = int64(nsec / 1e9)
+	return
+}
diff --git a/src/pkg/syscall/syscall_netbsd.go b/src/syscall/syscall_netbsd.go
similarity index 100%
rename from src/pkg/syscall/syscall_netbsd.go
rename to src/syscall/syscall_netbsd.go
diff --git a/src/pkg/syscall/syscall_netbsd_386.go b/src/syscall/syscall_netbsd_386.go
similarity index 100%
rename from src/pkg/syscall/syscall_netbsd_386.go
rename to src/syscall/syscall_netbsd_386.go
diff --git a/src/pkg/syscall/syscall_netbsd_amd64.go b/src/syscall/syscall_netbsd_amd64.go
similarity index 100%
rename from src/pkg/syscall/syscall_netbsd_amd64.go
rename to src/syscall/syscall_netbsd_amd64.go
diff --git a/src/pkg/syscall/syscall_netbsd_arm.go b/src/syscall/syscall_netbsd_arm.go
similarity index 100%
rename from src/pkg/syscall/syscall_netbsd_arm.go
rename to src/syscall/syscall_netbsd_arm.go
diff --git a/src/pkg/syscall/syscall_no_getwd.go b/src/syscall/syscall_no_getwd.go
similarity index 100%
rename from src/pkg/syscall/syscall_no_getwd.go
rename to src/syscall/syscall_no_getwd.go
diff --git a/src/pkg/syscall/syscall_openbsd.go b/src/syscall/syscall_openbsd.go
similarity index 100%
rename from src/pkg/syscall/syscall_openbsd.go
rename to src/syscall/syscall_openbsd.go
diff --git a/src/pkg/syscall/syscall_openbsd_386.go b/src/syscall/syscall_openbsd_386.go
similarity index 100%
rename from src/pkg/syscall/syscall_openbsd_386.go
rename to src/syscall/syscall_openbsd_386.go
diff --git a/src/pkg/syscall/syscall_openbsd_amd64.go b/src/syscall/syscall_openbsd_amd64.go
similarity index 100%
rename from src/pkg/syscall/syscall_openbsd_amd64.go
rename to src/syscall/syscall_openbsd_amd64.go
diff --git a/src/syscall/syscall_plan9.go b/src/syscall/syscall_plan9.go
new file mode 100644
index 0000000..618e02c
--- /dev/null
+++ b/src/syscall/syscall_plan9.go
@@ -0,0 +1,341 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Plan 9 system calls.
+// This file is compiled as ordinary Go code,
+// but it is also input to mksyscall,
+// which parses the //sys lines and generates system call stubs.
+// Note that sometimes we use a lowercase //sys name and
+// wrap it in our own nicer implementation.
+
+package syscall
+
+import "unsafe"
+
+const ImplementsGetwd = true
+
+// ErrorString implements Error's String method by returning itself.
+type ErrorString string
+
+func (e ErrorString) Error() string { return string(e) }
+
+// NewError converts s to an ErrorString, which satisfies the Error interface.
+func NewError(s string) error { return ErrorString(s) }
+
+func (e ErrorString) Temporary() bool {
+	return e == EINTR || e == EMFILE || e.Timeout()
+}
+
+func (e ErrorString) Timeout() bool {
+	return e == EBUSY || e == ETIMEDOUT
+}
+
+// A Note is a string describing a process note.
+// It implements the os.Signal interface.
+type Note string
+
+func (n Note) Signal() {}
+
+func (n Note) String() string {
+	return string(n)
+}
+
+var (
+	Stdin  = 0
+	Stdout = 1
+	Stderr = 2
+)
+
+// For testing: clients can set this flag to force
+// creation of IPv6 sockets to return EAFNOSUPPORT.
+var SocketDisableIPv6 bool
+
+func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err ErrorString)
+func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err ErrorString)
+func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2, err uintptr)
+func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr)
+
+func atoi(b []byte) (n uint) {
+	n = 0
+	for i := 0; i < len(b); i++ {
+		n = n*10 + uint(b[i]-'0')
+	}
+	return
+}
+
+func cstring(s []byte) string {
+	for i := range s {
+		if s[i] == 0 {
+			return string(s[0:i])
+		}
+	}
+	return string(s)
+}
+
+func errstr() string {
+	var buf [ERRMAX]byte
+
+	RawSyscall(SYS_ERRSTR, uintptr(unsafe.Pointer(&buf[0])), uintptr(len(buf)), 0)
+
+	buf[len(buf)-1] = 0
+	return cstring(buf[:])
+}
+
+// Implemented in assembly to import from runtime.
+func exit(code int)
+
+func Exit(code int) { exit(code) }
+
+func readnum(path string) (uint, error) {
+	var b [12]byte
+
+	fd, e := Open(path, O_RDONLY)
+	if e != nil {
+		return 0, e
+	}
+	defer Close(fd)
+
+	n, e := Pread(fd, b[:], 0)
+
+	if e != nil {
+		return 0, e
+	}
+
+	m := 0
+	for ; m < n && b[m] == ' '; m++ {
+	}
+
+	return atoi(b[m : n-1]), nil
+}
+
+func Getpid() (pid int) {
+	n, _ := readnum("#c/pid")
+	return int(n)
+}
+
+func Getppid() (ppid int) {
+	n, _ := readnum("#c/ppid")
+	return int(n)
+}
+
+func Read(fd int, p []byte) (n int, err error) {
+	return Pread(fd, p, -1)
+}
+
+func Write(fd int, p []byte) (n int, err error) {
+	return Pwrite(fd, p, -1)
+}
+
+var ioSync int64
+
+func Getwd() (wd string, err error) {
+	fd, e := Open(".", O_RDONLY)
+
+	if e != nil {
+		return "", e
+	}
+	defer Close(fd)
+
+	return Fd2path(fd)
+}
+
+//sys	fd2path(fd int, buf []byte) (err error)
+func Fd2path(fd int) (path string, err error) {
+	var buf [512]byte
+
+	e := fd2path(fd, buf[:])
+	if e != nil {
+		return "", e
+	}
+	return cstring(buf[:]), nil
+}
+
+//sys	pipe(p *[2]_C_int) (err error)
+func Pipe(p []int) (err error) {
+	if len(p) != 2 {
+		return NewError("bad arg in system call")
+	}
+	var pp [2]_C_int
+	err = pipe(&pp)
+	p[0] = int(pp[0])
+	p[1] = int(pp[1])
+	return
+}
+
+// Underlying system call writes to newoffset via pointer.
+// Implemented in assembly to avoid allocation.
+func seek(placeholder uintptr, fd int, offset int64, whence int) (newoffset int64, err string)
+
+func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
+	newoffset, e := seek(0, fd, offset, whence)
+
+	if newoffset == -1 {
+		err = NewError(e)
+	}
+	return
+}
+
+func Mkdir(path string, mode uint32) (err error) {
+	fd, err := Create(path, O_RDONLY, DMDIR|mode)
+
+	if fd != -1 {
+		Close(fd)
+	}
+
+	return
+}
+
+type Waitmsg struct {
+	Pid  int
+	Time [3]uint32
+	Msg  string
+}
+
+func (w Waitmsg) Exited() bool   { return true }
+func (w Waitmsg) Signaled() bool { return false }
+
+func (w Waitmsg) ExitStatus() int {
+	if len(w.Msg) == 0 {
+		// a normal exit returns no message
+		return 0
+	}
+	return 1
+}
+
+//sys	await(s []byte) (n int, err error)
+func Await(w *Waitmsg) (err error) {
+	var buf [512]byte
+	var f [5][]byte
+
+	n, err := await(buf[:])
+
+	if err != nil || w == nil {
+		return
+	}
+
+	nf := 0
+	p := 0
+	for i := 0; i < n && nf < len(f)-1; i++ {
+		if buf[i] == ' ' {
+			f[nf] = buf[p:i]
+			p = i + 1
+			nf++
+		}
+	}
+	f[nf] = buf[p:]
+	nf++
+
+	if nf != len(f) {
+		return NewError("invalid wait message")
+	}
+	w.Pid = int(atoi(f[0]))
+	w.Time[0] = uint32(atoi(f[1]))
+	w.Time[1] = uint32(atoi(f[2]))
+	w.Time[2] = uint32(atoi(f[3]))
+	w.Msg = cstring(f[4])
+	if w.Msg == "''" {
+		// await() returns '' for no error
+		w.Msg = ""
+	}
+	return
+}
+
+func Unmount(name, old string) (err error) {
+	oldp, err := BytePtrFromString(old)
+	if err != nil {
+		return err
+	}
+	oldptr := uintptr(unsafe.Pointer(oldp))
+
+	var r0 uintptr
+	var e ErrorString
+
+	// bind(2) man page: If name is zero, everything bound or mounted upon old is unbound or unmounted.
+	if name == "" {
+		r0, _, e = Syscall(SYS_UNMOUNT, _zero, oldptr, 0)
+	} else {
+		namep, err := BytePtrFromString(name)
+		if err != nil {
+			return err
+		}
+		r0, _, e = Syscall(SYS_UNMOUNT, uintptr(unsafe.Pointer(namep)), oldptr, 0)
+		use(unsafe.Pointer(namep))
+	}
+	use(unsafe.Pointer(oldp))
+
+	if int32(r0) == -1 {
+		err = e
+	}
+	return
+}
+
+func Fchdir(fd int) (err error) {
+	path, err := Fd2path(fd)
+
+	if err != nil {
+		return
+	}
+
+	return Chdir(path)
+}
+
+type Timespec struct {
+	Sec  int32
+	Nsec int32
+}
+
+type Timeval struct {
+	Sec  int32
+	Usec int32
+}
+
+func NsecToTimeval(nsec int64) (tv Timeval) {
+	nsec += 999 // round up to microsecond
+	tv.Usec = int32(nsec % 1e9 / 1e3)
+	tv.Sec = int32(nsec / 1e9)
+	return
+}
+
+func nsec() int64 {
+	var scratch int64
+
+	r0, _, _ := Syscall(SYS_NSEC, uintptr(unsafe.Pointer(&scratch)), 0, 0)
+	// TODO(aram): remove hack after I fix _nsec in the pc64 kernel.
+	if r0 == 0 {
+		return scratch
+	}
+	return int64(r0)
+}
+
+func Gettimeofday(tv *Timeval) error {
+	nsec := nsec()
+	*tv = NsecToTimeval(nsec)
+	return nil
+}
+
+func Getpagesize() int { return 0x1000 }
+
+func Getegid() (egid int) { return -1 }
+func Geteuid() (euid int) { return -1 }
+func Getgid() (gid int)   { return -1 }
+func Getuid() (uid int)   { return -1 }
+
+func Getgroups() (gids []int, err error) {
+	return make([]int, 0), nil
+}
+
+//sys	Dup(oldfd int, newfd int) (fd int, err error)
+//sys	Open(path string, mode int) (fd int, err error)
+//sys	Create(path string, mode int, perm uint32) (fd int, err error)
+//sys	Remove(path string) (err error)
+//sys	Pread(fd int, p []byte, offset int64) (n int, err error)
+//sys	Pwrite(fd int, p []byte, offset int64) (n int, err error)
+//sys	Close(fd int) (err error)
+//sys	Chdir(path string) (err error)
+//sys	Bind(name string, old string, flag int) (err error)
+//sys	Mount(fd int, afd int, old string, flag int, aname string) (err error)
+//sys	Stat(path string, edir []byte) (n int, err error)
+//sys	Fstat(fd int, edir []byte) (n int, err error)
+//sys	Wstat(path string, edir []byte) (err error)
+//sys	Fwstat(fd int, edir []byte) (err error)
diff --git a/src/pkg/syscall/syscall_solaris.go b/src/syscall/syscall_solaris.go
similarity index 100%
rename from src/pkg/syscall/syscall_solaris.go
rename to src/syscall/syscall_solaris.go
diff --git a/src/pkg/syscall/syscall_solaris_amd64.go b/src/syscall/syscall_solaris_amd64.go
similarity index 100%
rename from src/pkg/syscall/syscall_solaris_amd64.go
rename to src/syscall/syscall_solaris_amd64.go
diff --git a/src/syscall/syscall_test.go b/src/syscall/syscall_test.go
new file mode 100644
index 0000000..846c487
--- /dev/null
+++ b/src/syscall/syscall_test.go
@@ -0,0 +1,47 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package syscall_test
+
+import (
+	"fmt"
+	"syscall"
+	"testing"
+)
+
+func testSetGetenv(t *testing.T, key, value string) {
+	err := syscall.Setenv(key, value)
+	if err != nil {
+		t.Fatalf("Setenv failed to set %q: %v", value, err)
+	}
+	newvalue, found := syscall.Getenv(key)
+	if !found {
+		t.Fatalf("Getenv failed to find %v variable (want value %q)", key, value)
+	}
+	if newvalue != value {
+		t.Fatalf("Getenv(%v) = %q; want %q", key, newvalue, value)
+	}
+}
+
+func TestEnv(t *testing.T) {
+	testSetGetenv(t, "TESTENV", "AVALUE")
+	// make sure TESTENV gets set to "", not deleted
+	testSetGetenv(t, "TESTENV", "")
+}
+
+func TestItoa(t *testing.T) {
+	// Make most negative integer: 0x8000...
+	i := 1
+	for i<<1 != 0 {
+		i <<= 1
+	}
+	if i >= 0 {
+		t.Fatal("bad math")
+	}
+	s := syscall.Itoa(i)
+	f := fmt.Sprint(i)
+	if s != f {
+		t.Fatalf("itoa(%d) = %s, want %s", i, s, f)
+	}
+}
diff --git a/src/syscall/syscall_unix.go b/src/syscall/syscall_unix.go
new file mode 100644
index 0000000..a06bd7d
--- /dev/null
+++ b/src/syscall/syscall_unix.go
@@ -0,0 +1,299 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin dragonfly freebsd linux netbsd openbsd solaris
+
+package syscall
+
+import (
+	"runtime"
+	"sync"
+	"unsafe"
+)
+
+var (
+	Stdin  = 0
+	Stdout = 1
+	Stderr = 2
+)
+
+const (
+	darwin64Bit    = runtime.GOOS == "darwin" && sizeofPtr == 8
+	dragonfly64Bit = runtime.GOOS == "dragonfly" && sizeofPtr == 8
+	netbsd32Bit    = runtime.GOOS == "netbsd" && sizeofPtr == 4
+)
+
+func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
+func Syscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
+func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
+func RawSyscall6(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)
+
+// Mmap manager, for use by operating system-specific implementations.
+
+type mmapper struct {
+	sync.Mutex
+	active map[*byte][]byte // active mappings; key is last byte in mapping
+	mmap   func(addr, length uintptr, prot, flags, fd int, offset int64) (uintptr, error)
+	munmap func(addr uintptr, length uintptr) error
+}
+
+func (m *mmapper) Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
+	if length <= 0 {
+		return nil, EINVAL
+	}
+
+	// Map the requested memory.
+	addr, errno := m.mmap(0, uintptr(length), prot, flags, fd, offset)
+	if errno != nil {
+		return nil, errno
+	}
+
+	// Slice memory layout
+	var sl = struct {
+		addr uintptr
+		len  int
+		cap  int
+	}{addr, length, length}
+
+	// Use unsafe to turn sl into a []byte.
+	b := *(*[]byte)(unsafe.Pointer(&sl))
+
+	// Register mapping in m and return it.
+	p := &b[cap(b)-1]
+	m.Lock()
+	defer m.Unlock()
+	m.active[p] = b
+	return b, nil
+}
+
+func (m *mmapper) Munmap(data []byte) (err error) {
+	if len(data) == 0 || len(data) != cap(data) {
+		return EINVAL
+	}
+
+	// Find the base of the mapping.
+	p := &data[cap(data)-1]
+	m.Lock()
+	defer m.Unlock()
+	b := m.active[p]
+	if b == nil || &b[0] != &data[0] {
+		return EINVAL
+	}
+
+	// Unmap the memory and update m.
+	if errno := m.munmap(uintptr(unsafe.Pointer(&b[0])), uintptr(len(b))); errno != nil {
+		return errno
+	}
+	delete(m.active, p)
+	return nil
+}
+
+// An Errno is an unsigned number describing an error condition.
+// It implements the error interface.  The zero Errno is by convention
+// a non-error, so code to convert from Errno to error should use:
+//	err = nil
+//	if errno != 0 {
+//		err = errno
+//	}
+type Errno uintptr
+
+func (e Errno) Error() string {
+	if 0 <= int(e) && int(e) < len(errors) {
+		s := errors[e]
+		if s != "" {
+			return s
+		}
+	}
+	return "errno " + itoa(int(e))
+}
+
+func (e Errno) Temporary() bool {
+	return e == EINTR || e == EMFILE || e == ECONNRESET || e == ECONNABORTED || e.Timeout()
+}
+
+func (e Errno) Timeout() bool {
+	return e == EAGAIN || e == EWOULDBLOCK || e == ETIMEDOUT
+}
+
+// A Signal is a number describing a process signal.
+// It implements the os.Signal interface.
+type Signal int
+
+func (s Signal) Signal() {}
+
+func (s Signal) String() string {
+	if 0 <= s && int(s) < len(signals) {
+		str := signals[s]
+		if str != "" {
+			return str
+		}
+	}
+	return "signal " + itoa(int(s))
+}
+
+func Read(fd int, p []byte) (n int, err error) {
+	n, err = read(fd, p)
+	if raceenabled {
+		if n > 0 {
+			raceWriteRange(unsafe.Pointer(&p[0]), n)
+		}
+		if err == nil {
+			raceAcquire(unsafe.Pointer(&ioSync))
+		}
+	}
+	return
+}
+
+func Write(fd int, p []byte) (n int, err error) {
+	if raceenabled {
+		raceReleaseMerge(unsafe.Pointer(&ioSync))
+	}
+	n, err = write(fd, p)
+	if raceenabled && n > 0 {
+		raceReadRange(unsafe.Pointer(&p[0]), n)
+	}
+	return
+}
+
+// For testing: clients can set this flag to force
+// creation of IPv6 sockets to return EAFNOSUPPORT.
+var SocketDisableIPv6 bool
+
+type Sockaddr interface {
+	sockaddr() (ptr unsafe.Pointer, len _Socklen, err error) // lowercase; only we can define Sockaddrs
+}
+
+type SockaddrInet4 struct {
+	Port int
+	Addr [4]byte
+	raw  RawSockaddrInet4
+}
+
+type SockaddrInet6 struct {
+	Port   int
+	ZoneId uint32
+	Addr   [16]byte
+	raw    RawSockaddrInet6
+}
+
+type SockaddrUnix struct {
+	Name string
+	raw  RawSockaddrUnix
+}
+
+func Bind(fd int, sa Sockaddr) (err error) {
+	ptr, n, err := sa.sockaddr()
+	if err != nil {
+		return err
+	}
+	return bind(fd, ptr, n)
+}
+
+func Connect(fd int, sa Sockaddr) (err error) {
+	ptr, n, err := sa.sockaddr()
+	if err != nil {
+		return err
+	}
+	return connect(fd, ptr, n)
+}
+
+func Getpeername(fd int) (sa Sockaddr, err error) {
+	var rsa RawSockaddrAny
+	var len _Socklen = SizeofSockaddrAny
+	if err = getpeername(fd, &rsa, &len); err != nil {
+		return
+	}
+	return anyToSockaddr(&rsa)
+}
+
+func GetsockoptInt(fd, level, opt int) (value int, err error) {
+	var n int32
+	vallen := _Socklen(4)
+	err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen)
+	return int(n), err
+}
+
+func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, err error) {
+	var rsa RawSockaddrAny
+	var len _Socklen = SizeofSockaddrAny
+	if n, err = recvfrom(fd, p, flags, &rsa, &len); err != nil {
+		return
+	}
+	if rsa.Addr.Family != AF_UNSPEC {
+		from, err = anyToSockaddr(&rsa)
+	}
+	return
+}
+
+func Sendto(fd int, p []byte, flags int, to Sockaddr) (err error) {
+	ptr, n, err := to.sockaddr()
+	if err != nil {
+		return err
+	}
+	return sendto(fd, p, flags, ptr, n)
+}
+
+func SetsockoptByte(fd, level, opt int, value byte) (err error) {
+	return setsockopt(fd, level, opt, unsafe.Pointer(&value), 1)
+}
+
+func SetsockoptInt(fd, level, opt int, value int) (err error) {
+	var n = int32(value)
+	return setsockopt(fd, level, opt, unsafe.Pointer(&n), 4)
+}
+
+func SetsockoptInet4Addr(fd, level, opt int, value [4]byte) (err error) {
+	return setsockopt(fd, level, opt, unsafe.Pointer(&value[0]), 4)
+}
+
+func SetsockoptIPMreq(fd, level, opt int, mreq *IPMreq) (err error) {
+	return setsockopt(fd, level, opt, unsafe.Pointer(mreq), SizeofIPMreq)
+}
+
+func SetsockoptIPv6Mreq(fd, level, opt int, mreq *IPv6Mreq) (err error) {
+	return setsockopt(fd, level, opt, unsafe.Pointer(mreq), SizeofIPv6Mreq)
+}
+
+func SetsockoptICMPv6Filter(fd, level, opt int, filter *ICMPv6Filter) error {
+	return setsockopt(fd, level, opt, unsafe.Pointer(filter), SizeofICMPv6Filter)
+}
+
+func SetsockoptLinger(fd, level, opt int, l *Linger) (err error) {
+	return setsockopt(fd, level, opt, unsafe.Pointer(l), SizeofLinger)
+}
+
+func SetsockoptString(fd, level, opt int, s string) (err error) {
+	return setsockopt(fd, level, opt, unsafe.Pointer(&[]byte(s)[0]), uintptr(len(s)))
+}
+
+func SetsockoptTimeval(fd, level, opt int, tv *Timeval) (err error) {
+	return setsockopt(fd, level, opt, unsafe.Pointer(tv), unsafe.Sizeof(*tv))
+}
+
+func Socket(domain, typ, proto int) (fd int, err error) {
+	if domain == AF_INET6 && SocketDisableIPv6 {
+		return -1, EAFNOSUPPORT
+	}
+	fd, err = socket(domain, typ, proto)
+	return
+}
+
+func Socketpair(domain, typ, proto int) (fd [2]int, err error) {
+	var fdx [2]int32
+	err = socketpair(domain, typ, proto, &fdx)
+	if err == nil {
+		fd[0] = int(fdx[0])
+		fd[1] = int(fdx[1])
+	}
+	return
+}
+
+func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
+	if raceenabled {
+		raceReleaseMerge(unsafe.Pointer(&ioSync))
+	}
+	return sendfile(outfd, infd, offset, count)
+}
+
+var ioSync int64
diff --git a/src/pkg/syscall/syscall_unix_test.go b/src/syscall/syscall_unix_test.go
similarity index 100%
rename from src/pkg/syscall/syscall_unix_test.go
rename to src/syscall/syscall_unix_test.go
diff --git a/src/syscall/syscall_windows.go b/src/syscall/syscall_windows.go
new file mode 100644
index 0000000..e89fd09
--- /dev/null
+++ b/src/syscall/syscall_windows.go
@@ -0,0 +1,1013 @@
+// Copyright 2009 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Windows system calls.
+
+package syscall
+
+import (
+	errorspkg "errors"
+	"sync"
+	"unicode/utf16"
+	"unsafe"
+)
+
+type Handle uintptr
+
+const InvalidHandle = ^Handle(0)
+
+// StringToUTF16 is deprecated. Use UTF16FromString instead.
+// If s contains a NUL byte this function panics instead of
+// returning an error.
+func StringToUTF16(s string) []uint16 {
+	a, err := UTF16FromString(s)
+	if err != nil {
+		panic("syscall: string with NUL passed to StringToUTF16")
+	}
+	return a
+}
+
+// UTF16FromString returns the UTF-16 encoding of the UTF-8 string
+// s, with a terminating NUL added. If s contains a NUL byte at any
+// location, it returns (nil, EINVAL).
+func UTF16FromString(s string) ([]uint16, error) {
+	for i := 0; i < len(s); i++ {
+		if s[i] == 0 {
+			return nil, EINVAL
+		}
+	}
+	return utf16.Encode([]rune(s + "\x00")), nil
+}
+
+// UTF16ToString returns the UTF-8 encoding of the UTF-16 sequence s,
+// with a terminating NUL removed.
+func UTF16ToString(s []uint16) string {
+	for i, v := range s {
+		if v == 0 {
+			s = s[0:i]
+			break
+		}
+	}
+	return string(utf16.Decode(s))
+}
+
+// StringToUTF16Ptr is deprecated. Use UTF16PtrFromString instead.
+// If s contains a NUL byte this function panics instead of
+// returning an error.
+func StringToUTF16Ptr(s string) *uint16 { return &StringToUTF16(s)[0] }
+
+// UTF16PtrFromString returns pointer to the UTF-16 encoding of
+// the UTF-8 string s, with a terminating NUL added. If s
+// contains a NUL byte at any location, it returns (nil, EINVAL).
+func UTF16PtrFromString(s string) (*uint16, error) {
+	a, err := UTF16FromString(s)
+	if err != nil {
+		return nil, err
+	}
+	return &a[0], nil
+}
+
+func Getpagesize() int { return 4096 }
+
+// Errno is the Windows error number.
+type Errno uintptr
+
+func langid(pri, sub uint16) uint32 { return uint32(sub)<<10 | uint32(pri) }
+
+func (e Errno) Error() string {
+	// deal with special go errors
+	idx := int(e - APPLICATION_ERROR)
+	if 0 <= idx && idx < len(errors) {
+		return errors[idx]
+	}
+	// ask windows for the remaining errors
+	var flags uint32 = FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ARGUMENT_ARRAY | FORMAT_MESSAGE_IGNORE_INSERTS
+	b := make([]uint16, 300)
+	n, err := FormatMessage(flags, 0, uint32(e), langid(LANG_ENGLISH, SUBLANG_ENGLISH_US), b, nil)
+	if err != nil {
+		n, err = FormatMessage(flags, 0, uint32(e), 0, b, nil)
+		if err != nil {
+			return "winapi error #" + itoa(int(e))
+		}
+	}
+	// trim terminating \r and \n
+	for ; n > 0 && (b[n-1] == '\n' || b[n-1] == '\r'); n-- {
+	}
+	return string(utf16.Decode(b[:n]))
+}
+
+func (e Errno) Temporary() bool {
+	return e == EINTR || e == EMFILE || e.Timeout()
+}
+
+func (e Errno) Timeout() bool {
+	return e == EAGAIN || e == EWOULDBLOCK || e == ETIMEDOUT
+}
+
+// Implemented in asm_windows.s
+func compileCallback(fn interface{}, cleanstack bool) uintptr
+
+// Converts a Go function to a function pointer conforming
+// to the stdcall calling convention. This is useful when
+// interoperating with Windows code requiring callbacks.
+func NewCallback(fn interface{}) uintptr {
+	return compileCallback(fn, true)
+}
+
+// Converts a Go function to a function pointer conforming
+// to the cdecl calling convention. This is useful when
+// interoperating with Windows code requiring callbacks.
+func NewCallbackCDecl(fn interface{}) uintptr {
+	return compileCallback(fn, false)
+}
+
+// windows api calls
+
+//sys	GetLastError() (lasterr error)
+//sys	LoadLibrary(libname string) (handle Handle, err error) = LoadLibraryW
+//sys	FreeLibrary(handle Handle) (err error)
+//sys	GetProcAddress(module Handle, procname string) (proc uintptr, err error)
+//sys	GetVersion() (ver uint32, err error)
+//sys	FormatMessage(flags uint32, msgsrc uint32, msgid uint32, langid uint32, buf []uint16, args *byte) (n uint32, err error) = FormatMessageW
+//sys	ExitProcess(exitcode uint32)
+//sys	CreateFile(name *uint16, access uint32, mode uint32, sa *SecurityAttributes, createmode uint32, attrs uint32, templatefile int32) (handle Handle, err error) [failretval==InvalidHandle] = CreateFileW
+//sys	ReadFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) (err error)
+//sys	WriteFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) (err error)
+//sys	SetFilePointer(handle Handle, lowoffset int32, highoffsetptr *int32, whence uint32) (newlowoffset uint32, err error) [failretval==0xffffffff]
+//sys	CloseHandle(handle Handle) (err error)
+//sys	GetStdHandle(stdhandle int) (handle Handle, err error) [failretval==InvalidHandle]
+//sys	findFirstFile1(name *uint16, data *win32finddata1) (handle Handle, err error) [failretval==InvalidHandle] = FindFirstFileW
+//sys	findNextFile1(handle Handle, data *win32finddata1) (err error) = FindNextFileW
+//sys	FindClose(handle Handle) (err error)
+//sys	GetFileInformationByHandle(handle Handle, data *ByHandleFileInformation) (err error)
+//sys	GetCurrentDirectory(buflen uint32, buf *uint16) (n uint32, err error) = GetCurrentDirectoryW
+//sys	SetCurrentDirectory(path *uint16) (err error) = SetCurrentDirectoryW
+//sys	CreateDirectory(path *uint16, sa *SecurityAttributes) (err error) = CreateDirectoryW
+//sys	RemoveDirectory(path *uint16) (err error) = RemoveDirectoryW
+//sys	DeleteFile(path *uint16) (err error) = DeleteFileW
+//sys	MoveFile(from *uint16, to *uint16) (err error) = MoveFileW
+//sys	GetComputerName(buf *uint16, n *uint32) (err error) = GetComputerNameW
+//sys	SetEndOfFile(handle Handle) (err error)
+//sys	GetSystemTimeAsFileTime(time *Filetime)
+//sys	GetTimeZoneInformation(tzi *Timezoneinformation) (rc uint32, err error) [failretval==0xffffffff]
+//sys	CreateIoCompletionPort(filehandle Handle, cphandle Handle, key uint32, threadcnt uint32) (handle Handle, err error)
+//sys	GetQueuedCompletionStatus(cphandle Handle, qty *uint32, key *uint32, overlapped **Overlapped, timeout uint32) (err error)
+//sys	PostQueuedCompletionStatus(cphandle Handle, qty uint32, key uint32, overlapped *Overlapped) (err error)
+//sys	CancelIo(s Handle) (err error)
+//sys	CancelIoEx(s Handle, o *Overlapped) (err error)
+//sys	CreateProcess(appName *uint16, commandLine *uint16, procSecurity *SecurityAttributes, threadSecurity *SecurityAttributes, inheritHandles bool, creationFlags uint32, env *uint16, currentDir *uint16, startupInfo *StartupInfo, outProcInfo *ProcessInformation) (err error) = CreateProcessW
+//sys	OpenProcess(da uint32, inheritHandle bool, pid uint32) (handle Handle, err error)
+//sys	TerminateProcess(handle Handle, exitcode uint32) (err error)
+//sys	GetExitCodeProcess(handle Handle, exitcode *uint32) (err error)
+//sys	GetStartupInfo(startupInfo *StartupInfo) (err error) = GetStartupInfoW
+//sys	GetCurrentProcess() (pseudoHandle Handle, err error)
+//sys	GetProcessTimes(handle Handle, creationTime *Filetime, exitTime *Filetime, kernelTime *Filetime, userTime *Filetime) (err error)
+//sys	DuplicateHandle(hSourceProcessHandle Handle, hSourceHandle Handle, hTargetProcessHandle Handle, lpTargetHandle *Handle, dwDesiredAccess uint32, bInheritHandle bool, dwOptions uint32) (err error)
+//sys	WaitForSingleObject(handle Handle, waitMilliseconds uint32) (event uint32, err error) [failretval==0xffffffff]
+//sys	GetTempPath(buflen uint32, buf *uint16) (n uint32, err error) = GetTempPathW
+//sys	CreatePipe(readhandle *Handle, writehandle *Handle, sa *SecurityAttributes, size uint32) (err error)
+//sys	GetFileType(filehandle Handle) (n uint32, err error)
+//sys	CryptAcquireContext(provhandle *Handle, container *uint16, provider *uint16, provtype uint32, flags uint32) (err error) = advapi32.CryptAcquireContextW
+//sys	CryptReleaseContext(provhandle Handle, flags uint32) (err error) = advapi32.CryptReleaseContext
+//sys	CryptGenRandom(provhandle Handle, buflen uint32, buf *byte) (err error) = advapi32.CryptGenRandom
+//sys	GetEnvironmentStrings() (envs *uint16, err error) [failretval==nil] = kernel32.GetEnvironmentStringsW
+//sys	FreeEnvironmentStrings(envs *uint16) (err error) = kernel32.FreeEnvironmentStringsW
+//sys	GetEnvironmentVariable(name *uint16, buffer *uint16, size uint32) (n uint32, err error) = kernel32.GetEnvironmentVariableW
+//sys	SetEnvironmentVariable(name *uint16, value *uint16) (err error) = kernel32.SetEnvironmentVariableW
+//sys	SetFileTime(handle Handle, ctime *Filetime, atime *Filetime, wtime *Filetime) (err error)
+//sys	GetFileAttributes(name *uint16) (attrs uint32, err error) [failretval==INVALID_FILE_ATTRIBUTES] = kernel32.GetFileAttributesW
+//sys	SetFileAttributes(name *uint16, attrs uint32) (err error) = kernel32.SetFileAttributesW
+//sys	GetFileAttributesEx(name *uint16, level uint32, info *byte) (err error) = kernel32.GetFileAttributesExW
+//sys	GetCommandLine() (cmd *uint16) = kernel32.GetCommandLineW
+//sys	CommandLineToArgv(cmd *uint16, argc *int32) (argv *[8192]*[8192]uint16, err error) [failretval==nil] = shell32.CommandLineToArgvW
+//sys	LocalFree(hmem Handle) (handle Handle, err error) [failretval!=0]
+//sys	SetHandleInformation(handle Handle, mask uint32, flags uint32) (err error)
+//sys	FlushFileBuffers(handle Handle) (err error)
+//sys	GetFullPathName(path *uint16, buflen uint32, buf *uint16, fname **uint16) (n uint32, err error) = kernel32.GetFullPathNameW
+//sys	GetLongPathName(path *uint16, buf *uint16, buflen uint32) (n uint32, err error) = kernel32.GetLongPathNameW
+//sys	GetShortPathName(longpath *uint16, shortpath *uint16, buflen uint32) (n uint32, err error) = kernel32.GetShortPathNameW
+//sys	CreateFileMapping(fhandle Handle, sa *SecurityAttributes, prot uint32, maxSizeHigh uint32, maxSizeLow uint32, name *uint16) (handle Handle, err error) = kernel32.CreateFileMappingW
+//sys	MapViewOfFile(handle Handle, access uint32, offsetHigh uint32, offsetLow uint32, length uintptr) (addr uintptr, err error)
+//sys	UnmapViewOfFile(addr uintptr) (err error)
+//sys	FlushViewOfFile(addr uintptr, length uintptr) (err error)
+//sys	VirtualLock(addr uintptr, length uintptr) (err error)
+//sys	VirtualUnlock(addr uintptr, length uintptr) (err error)
+//sys	TransmitFile(s Handle, handle Handle, bytesToWrite uint32, bytsPerSend uint32, overlapped *Overlapped, transmitFileBuf *TransmitFileBuffers, flags uint32) (err error) = mswsock.TransmitFile
+//sys	ReadDirectoryChanges(handle Handle, buf *byte, buflen uint32, watchSubTree bool, mask uint32, retlen *uint32, overlapped *Overlapped, completionRoutine uintptr) (err error) = kernel32.ReadDirectoryChangesW
+//sys	CertOpenSystemStore(hprov Handle, name *uint16) (store Handle, err error) = crypt32.CertOpenSystemStoreW
+//sys   CertOpenStore(storeProvider uintptr, msgAndCertEncodingType uint32, cryptProv uintptr, flags uint32, para uintptr) (handle Handle, err error) [failretval==InvalidHandle] = crypt32.CertOpenStore
+//sys	CertEnumCertificatesInStore(store Handle, prevContext *CertContext) (context *CertContext, err error) [failretval==nil] = crypt32.CertEnumCertificatesInStore
+//sys   CertAddCertificateContextToStore(store Handle, certContext *CertContext, addDisposition uint32, storeContext **CertContext) (err error) = crypt32.CertAddCertificateContextToStore
+//sys	CertCloseStore(store Handle, flags uint32) (err error) = crypt32.CertCloseStore
+//sys   CertGetCertificateChain(engine Handle, leaf *CertContext, time *Filetime, additionalStore Handle, para *CertChainPara, flags uint32, reserved uintptr, chainCtx **CertChainContext) (err error) = crypt32.CertGetCertificateChain
+//sys   CertFreeCertificateChain(ctx *CertChainContext) = crypt32.CertFreeCertificateChain
+//sys   CertCreateCertificateContext(certEncodingType uint32, certEncoded *byte, encodedLen uint32) (context *CertContext, err error) [failretval==nil] = crypt32.CertCreateCertificateContext
+//sys   CertFreeCertificateContext(ctx *CertContext) (err error) = crypt32.CertFreeCertificateContext
+//sys   CertVerifyCertificateChainPolicy(policyOID uintptr, chain *CertChainContext, para *CertChainPolicyPara, status *CertChainPolicyStatus) (err error) = crypt32.CertVerifyCertificateChainPolicy
+//sys	RegOpenKeyEx(key Handle, subkey *uint16, options uint32, desiredAccess uint32, result *Handle) (regerrno error) = advapi32.RegOpenKeyExW
+//sys	RegCloseKey(key Handle) (regerrno error) = advapi32.RegCloseKey
+//sys	RegQueryInfoKey(key Handle, class *uint16, classLen *uint32, reserved *uint32, subkeysLen *uint32, maxSubkeyLen *uint32, maxClassLen *uint32, valuesLen *uint32, maxValueNameLen *uint32, maxValueLen *uint32, saLen *uint32, lastWriteTime *Filetime) (regerrno error) = advapi32.RegQueryInfoKeyW
+//sys	RegEnumKeyEx(key Handle, index uint32, name *uint16, nameLen *uint32, reserved *uint32, class *uint16, classLen *uint32, lastWriteTime *Filetime) (regerrno error) = advapi32.RegEnumKeyExW
+//sys	RegQueryValueEx(key Handle, name *uint16, reserved *uint32, valtype *uint32, buf *byte, buflen *uint32) (regerrno error) = advapi32.RegQueryValueExW
+//sys	getCurrentProcessId() (pid uint32) = kernel32.GetCurrentProcessId
+//sys	GetConsoleMode(console Handle, mode *uint32) (err error) = kernel32.GetConsoleMode
+//sys	WriteConsole(console Handle, buf *uint16, towrite uint32, written *uint32, reserved *byte) (err error) = kernel32.WriteConsoleW
+//sys	ReadConsole(console Handle, buf *uint16, toread uint32, read *uint32, inputControl *byte) (err error) = kernel32.ReadConsoleW
+//sys	CreateToolhelp32Snapshot(flags uint32, processId uint32) (handle Handle, err error) [failretval==InvalidHandle] = kernel32.CreateToolhelp32Snapshot
+//sys	Process32First(snapshot Handle, procEntry *ProcessEntry32) (err error) = kernel32.Process32FirstW
+//sys	Process32Next(snapshot Handle, procEntry *ProcessEntry32) (err error) = kernel32.Process32NextW
+//sys	DeviceIoControl(handle Handle, ioControlCode uint32, inBuffer *byte, inBufferSize uint32, outBuffer *byte, outBufferSize uint32, bytesReturned *uint32, overlapped *Overlapped) (err error)
+// This function returns 1 byte BOOLEAN rather than the 4 byte BOOL.
+//sys	CreateSymbolicLink(symlinkfilename *uint16, targetfilename *uint16, flags uint32) (err error) [failretval&0xff==0] = CreateSymbolicLinkW
+//sys	CreateHardLink(filename *uint16, existingfilename *uint16, reserved uintptr) (err error) [failretval&0xff==0] = CreateHardLinkW
+
+// syscall interface implementation for other packages
+
+func Exit(code int) { ExitProcess(uint32(code)) }
+
+func makeInheritSa() *SecurityAttributes {
+	var sa SecurityAttributes
+	sa.Length = uint32(unsafe.Sizeof(sa))
+	sa.InheritHandle = 1
+	return &sa
+}
+
+func Open(path string, mode int, perm uint32) (fd Handle, err error) {
+	if len(path) == 0 {
+		return InvalidHandle, ERROR_FILE_NOT_FOUND
+	}
+	pathp, err := UTF16PtrFromString(path)
+	if err != nil {
+		return InvalidHandle, err
+	}
+	var access uint32
+	switch mode & (O_RDONLY | O_WRONLY | O_RDWR) {
+	case O_RDONLY:
+		access = GENERIC_READ
+	case O_WRONLY:
+		access = GENERIC_WRITE
+	case O_RDWR:
+		access = GENERIC_READ | GENERIC_WRITE
+	}
+	if mode&O_CREAT != 0 {
+		access |= GENERIC_WRITE
+	}
+	if mode&O_APPEND != 0 {
+		access &^= GENERIC_WRITE
+		access |= FILE_APPEND_DATA
+	}
+	sharemode := uint32(FILE_SHARE_READ | FILE_SHARE_WRITE)
+	var sa *SecurityAttributes
+	if mode&O_CLOEXEC == 0 {
+		sa = makeInheritSa()
+	}
+	var createmode uint32
+	switch {
+	case mode&(O_CREAT|O_EXCL) == (O_CREAT | O_EXCL):
+		createmode = CREATE_NEW
+	case mode&(O_CREAT|O_TRUNC) == (O_CREAT | O_TRUNC):
+		createmode = CREATE_ALWAYS
+	case mode&O_CREAT == O_CREAT:
+		createmode = OPEN_ALWAYS
+	case mode&O_TRUNC == O_TRUNC:
+		createmode = TRUNCATE_EXISTING
+	default:
+		createmode = OPEN_EXISTING
+	}
+	h, e := CreateFile(pathp, access, sharemode, sa, createmode, FILE_ATTRIBUTE_NORMAL, 0)
+	return h, e
+}
+
+func Read(fd Handle, p []byte) (n int, err error) {
+	var done uint32
+	e := ReadFile(fd, p, &done, nil)
+	if e != nil {
+		if e == ERROR_BROKEN_PIPE {
+			// NOTE(brainman): work around ERROR_BROKEN_PIPE is returned on reading EOF from stdin
+			return 0, nil
+		}
+		return 0, e
+	}
+	if raceenabled {
+		if done > 0 {
+			raceWriteRange(unsafe.Pointer(&p[0]), int(done))
+		}
+		raceAcquire(unsafe.Pointer(&ioSync))
+	}
+	return int(done), nil
+}
+
+func Write(fd Handle, p []byte) (n int, err error) {
+	if raceenabled {
+		raceReleaseMerge(unsafe.Pointer(&ioSync))
+	}
+	var done uint32
+	e := WriteFile(fd, p, &done, nil)
+	if e != nil {
+		return 0, e
+	}
+	if raceenabled && done > 0 {
+		raceReadRange(unsafe.Pointer(&p[0]), int(done))
+	}
+	return int(done), nil
+}
+
+var ioSync int64
+
+func Seek(fd Handle, offset int64, whence int) (newoffset int64, err error) {
+	var w uint32
+	switch whence {
+	case 0:
+		w = FILE_BEGIN
+	case 1:
+		w = FILE_CURRENT
+	case 2:
+		w = FILE_END
+	}
+	hi := int32(offset >> 32)
+	lo := int32(offset)
+	// use GetFileType to check pipe, pipe can't do seek
+	ft, _ := GetFileType(fd)
+	if ft == FILE_TYPE_PIPE {
+		return 0, EPIPE
+	}
+	rlo, e := SetFilePointer(fd, lo, &hi, w)
+	if e != nil {
+		return 0, e
+	}
+	return int64(hi)<<32 + int64(rlo), nil
+}
+
+func Close(fd Handle) (err error) {
+	return CloseHandle(fd)
+}
+
+var (
+	Stdin  = getStdHandle(STD_INPUT_HANDLE)
+	Stdout = getStdHandle(STD_OUTPUT_HANDLE)
+	Stderr = getStdHandle(STD_ERROR_HANDLE)
+)
+
+func getStdHandle(h int) (fd Handle) {
+	r, _ := GetStdHandle(h)
+	CloseOnExec(r)
+	return r
+}
+
+const ImplementsGetwd = true
+
+func Getwd() (wd string, err error) {
+	b := make([]uint16, 300)
+	n, e := GetCurrentDirectory(uint32(len(b)), &b[0])
+	if e != nil {
+		return "", e
+	}
+	return string(utf16.Decode(b[0:n])), nil
+}
+
+func Chdir(path string) (err error) {
+	pathp, err := UTF16PtrFromString(path)
+	if err != nil {
+		return err
+	}
+	return SetCurrentDirectory(pathp)
+}
+
+func Mkdir(path string, mode uint32) (err error) {
+	pathp, err := UTF16PtrFromString(path)
+	if err != nil {
+		return err
+	}
+	return CreateDirectory(pathp, nil)
+}
+
+func Rmdir(path string) (err error) {
+	pathp, err := UTF16PtrFromString(path)
+	if err != nil {
+		return err
+	}
+	return RemoveDirectory(pathp)
+}
+
+func Unlink(path string) (err error) {
+	pathp, err := UTF16PtrFromString(path)
+	if err != nil {
+		return err
+	}
+	return DeleteFile(pathp)
+}
+
+func Rename(oldpath, newpath string) (err error) {
+	from, err := UTF16PtrFromString(oldpath)
+	if err != nil {
+		return err
+	}
+	to, err := UTF16PtrFromString(newpath)
+	if err != nil {
+		return err
+	}
+	return MoveFile(from, to)
+}
+
+func ComputerName() (name string, err error) {
+	var n uint32 = MAX_COMPUTERNAME_LENGTH + 1
+	b := make([]uint16, n)
+	e := GetComputerName(&b[0], &n)
+	if e != nil {
+		return "", e
+	}
+	return string(utf16.Decode(b[0:n])), nil
+}
+
+func Ftruncate(fd Handle, length int64) (err error) {
+	curoffset, e := Seek(fd, 0, 1)
+	if e != nil {
+		return e
+	}
+	defer Seek(fd, curoffset, 0)
+	_, e = Seek(fd, length, 0)
+	if e != nil {
+		return e
+	}
+	e = SetEndOfFile(fd)
+	if e != nil {
+		return e
+	}
+	return nil
+}
+
+func Gettimeofday(tv *Timeval) (err error) {
+	var ft Filetime
+	GetSystemTimeAsFileTime(&ft)
+	*tv = NsecToTimeval(ft.Nanoseconds())
+	return nil
+}
+
+func Pipe(p []Handle) (err error) {
+	if len(p) != 2 {
+		return EINVAL
+	}
+	var r, w Handle
+	e := CreatePipe(&r, &w, makeInheritSa(), 0)
+	if e != nil {
+		return e
+	}
+	p[0] = r
+	p[1] = w
+	return nil
+}
+
+func Utimes(path string, tv []Timeval) (err error) {
+	if len(tv) != 2 {
+		return EINVAL
+	}
+	pathp, e := UTF16PtrFromString(path)
+	if e != nil {
+		return e
+	}
+	h, e := CreateFile(pathp,
+		FILE_WRITE_ATTRIBUTES, FILE_SHARE_WRITE, nil,
+		OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0)
+	if e != nil {
+		return e
+	}
+	defer Close(h)
+	a := NsecToFiletime(tv[0].Nanoseconds())
+	w := NsecToFiletime(tv[1].Nanoseconds())
+	return SetFileTime(h, nil, &a, &w)
+}
+
+func UtimesNano(path string, ts []Timespec) (err error) {
+	if len(ts) != 2 {
+		return EINVAL
+	}
+	pathp, e := UTF16PtrFromString(path)
+	if e != nil {
+		return e
+	}
+	h, e := CreateFile(pathp,
+		FILE_WRITE_ATTRIBUTES, FILE_SHARE_WRITE, nil,
+		OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0)
+	if e != nil {
+		return e
+	}
+	defer Close(h)
+	a := NsecToFiletime(TimespecToNsec(ts[0]))
+	w := NsecToFiletime(TimespecToNsec(ts[1]))
+	return SetFileTime(h, nil, &a, &w)
+}
+
+func Fsync(fd Handle) (err error) {
+	return FlushFileBuffers(fd)
+}
+
+func Chmod(path string, mode uint32) (err error) {
+	if mode == 0 {
+		return EINVAL
+	}
+	p, e := UTF16PtrFromString(path)
+	if e != nil {
+		return e
+	}
+	attrs, e := GetFileAttributes(p)
+	if e != nil {
+		return e
+	}
+	if mode&S_IWRITE != 0 {
+		attrs &^= FILE_ATTRIBUTE_READONLY
+	} else {
+		attrs |= FILE_ATTRIBUTE_READONLY
+	}
+	return SetFileAttributes(p, attrs)
+}
+
+func LoadCancelIoEx() error {
+	return procCancelIoEx.Find()
+}
+
+func LoadSetFileCompletionNotificationModes() error {
+	return procSetFileCompletionNotificationModes.Find()
+}
+
+// net api calls
+
+const socket_error = uintptr(^uint32(0))
+
+//sys	WSAStartup(verreq uint32, data *WSAData) (sockerr error) = ws2_32.WSAStartup
+//sys	WSACleanup() (err error) [failretval==socket_error] = ws2_32.WSACleanup
+//sys	WSAIoctl(s Handle, iocc uint32, inbuf *byte, cbif uint32, outbuf *byte, cbob uint32, cbbr *uint32, overlapped *Overlapped, completionRoutine uintptr) (err error) [failretval==socket_error] = ws2_32.WSAIoctl
+//sys	socket(af int32, typ int32, protocol int32) (handle Handle, err error) [failretval==InvalidHandle] = ws2_32.socket
+//sys	Setsockopt(s Handle, level int32, optname int32, optval *byte, optlen int32) (err error) [failretval==socket_error] = ws2_32.setsockopt
+//sys	Getsockopt(s Handle, level int32, optname int32, optval *byte, optlen *int32) (err error) [failretval==socket_error] = ws2_32.getsockopt
+//sys	bind(s Handle, name unsafe.Pointer, namelen int32) (err error) [failretval==socket_error] = ws2_32.bind
+//sys	connect(s Handle, name unsafe.Pointer, namelen int32) (err error) [failretval==socket_error] = ws2_32.connect
+//sys	getsockname(s Handle, rsa *RawSockaddrAny, addrlen *int32) (err error) [failretval==socket_error] = ws2_32.getsockname
+//sys	getpeername(s Handle, rsa *RawSockaddrAny, addrlen *int32) (err error) [failretval==socket_error] = ws2_32.getpeername
+//sys	listen(s Handle, backlog int32) (err error) [failretval==socket_error] = ws2_32.listen
+//sys	shutdown(s Handle, how int32) (err error) [failretval==socket_error] = ws2_32.shutdown
+//sys	Closesocket(s Handle) (err error) [failretval==socket_error] = ws2_32.closesocket
+//sys	AcceptEx(ls Handle, as Handle, buf *byte, rxdatalen uint32, laddrlen uint32, raddrlen uint32, recvd *uint32, overlapped *Overlapped) (err error) = mswsock.AcceptEx
+//sys	GetAcceptExSockaddrs(buf *byte, rxdatalen uint32, laddrlen uint32, raddrlen uint32, lrsa **RawSockaddrAny, lrsalen *int32, rrsa **RawSockaddrAny, rrsalen *int32) = mswsock.GetAcceptExSockaddrs
+//sys	WSARecv(s Handle, bufs *WSABuf, bufcnt uint32, recvd *uint32, flags *uint32, overlapped *Overlapped, croutine *byte) (err error) [failretval==socket_error] = ws2_32.WSARecv
+//sys	WSASend(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, overlapped *Overlapped, croutine *byte) (err error) [failretval==socket_error] = ws2_32.WSASend
+//sys	WSARecvFrom(s Handle, bufs *WSABuf, bufcnt uint32, recvd *uint32, flags *uint32,  from *RawSockaddrAny, fromlen *int32, overlapped *Overlapped, croutine *byte) (err error) [failretval==socket_error] = ws2_32.WSARecvFrom
+//sys	WSASendTo(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, to *RawSockaddrAny, tolen int32,  overlapped *Overlapped, croutine *byte) (err error) [failretval==socket_error] = ws2_32.WSASendTo
+//sys	GetHostByName(name string) (h *Hostent, err error) [failretval==nil] = ws2_32.gethostbyname
+//sys	GetServByName(name string, proto string) (s *Servent, err error) [failretval==nil] = ws2_32.getservbyname
+//sys	Ntohs(netshort uint16) (u uint16) = ws2_32.ntohs
+//sys	GetProtoByName(name string) (p *Protoent, err error) [failretval==nil] = ws2_32.getprotobyname
+//sys	DnsQuery(name string, qtype uint16, options uint32, extra *byte, qrs **DNSRecord, pr *byte) (status error) = dnsapi.DnsQuery_W
+//sys	DnsRecordListFree(rl *DNSRecord, freetype uint32) = dnsapi.DnsRecordListFree
+//sys	DnsNameCompare(name1 *uint16, name2 *uint16) (same bool) = dnsapi.DnsNameCompare_W
+//sys	GetAddrInfoW(nodename *uint16, servicename *uint16, hints *AddrinfoW, result **AddrinfoW) (sockerr error) = ws2_32.GetAddrInfoW
+//sys	FreeAddrInfoW(addrinfo *AddrinfoW) = ws2_32.FreeAddrInfoW
+//sys	GetIfEntry(pIfRow *MibIfRow) (errcode error) = iphlpapi.GetIfEntry
+//sys	GetAdaptersInfo(ai *IpAdapterInfo, ol *uint32) (errcode error) = iphlpapi.GetAdaptersInfo
+//sys	SetFileCompletionNotificationModes(handle Handle, flags uint8) (err error) = kernel32.SetFileCompletionNotificationModes
+//sys	WSAEnumProtocols(protocols *int32, protocolBuffer *WSAProtocolInfo, bufferLength *uint32) (n int32, err error) [failretval==-1] = ws2_32.WSAEnumProtocolsW
+
+// For testing: clients can set this flag to force
+// creation of IPv6 sockets to return EAFNOSUPPORT.
+var SocketDisableIPv6 bool
+
+type RawSockaddrInet4 struct {
+	Family uint16
+	Port   uint16
+	Addr   [4]byte /* in_addr */
+	Zero   [8]uint8
+}
+
+type RawSockaddrInet6 struct {
+	Family   uint16
+	Port     uint16
+	Flowinfo uint32
+	Addr     [16]byte /* in6_addr */
+	Scope_id uint32
+}
+
+type RawSockaddr struct {
+	Family uint16
+	Data   [14]int8
+}
+
+type RawSockaddrAny struct {
+	Addr RawSockaddr
+	Pad  [96]int8
+}
+
+type Sockaddr interface {
+	sockaddr() (ptr unsafe.Pointer, len int32, err error) // lowercase; only we can define Sockaddrs
+}
+
+type SockaddrInet4 struct {
+	Port int
+	Addr [4]byte
+	raw  RawSockaddrInet4
+}
+
+func (sa *SockaddrInet4) sockaddr() (unsafe.Pointer, int32, error) {
+	if sa.Port < 0 || sa.Port > 0xFFFF {
+		return nil, 0, EINVAL
+	}
+	sa.raw.Family = AF_INET
+	p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
+	p[0] = byte(sa.Port >> 8)
+	p[1] = byte(sa.Port)
+	for i := 0; i < len(sa.Addr); i++ {
+		sa.raw.Addr[i] = sa.Addr[i]
+	}
+	return unsafe.Pointer(&sa.raw), int32(unsafe.Sizeof(sa.raw)), nil
+}
+
+type SockaddrInet6 struct {
+	Port   int
+	ZoneId uint32
+	Addr   [16]byte
+	raw    RawSockaddrInet6
+}
+
+func (sa *SockaddrInet6) sockaddr() (unsafe.Pointer, int32, error) {
+	if sa.Port < 0 || sa.Port > 0xFFFF {
+		return nil, 0, EINVAL
+	}
+	sa.raw.Family = AF_INET6
+	p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
+	p[0] = byte(sa.Port >> 8)
+	p[1] = byte(sa.Port)
+	sa.raw.Scope_id = sa.ZoneId
+	for i := 0; i < len(sa.Addr); i++ {
+		sa.raw.Addr[i] = sa.Addr[i]
+	}
+	return unsafe.Pointer(&sa.raw), int32(unsafe.Sizeof(sa.raw)), nil
+}
+
+type SockaddrUnix struct {
+	Name string
+}
+
+func (sa *SockaddrUnix) sockaddr() (unsafe.Pointer, int32, error) {
+	// TODO(brainman): implement SockaddrUnix.sockaddr()
+	return nil, 0, EWINDOWS
+}
+
+func (rsa *RawSockaddrAny) Sockaddr() (Sockaddr, error) {
+	switch rsa.Addr.Family {
+	case AF_UNIX:
+		return nil, EWINDOWS
+
+	case AF_INET:
+		pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))
+		sa := new(SockaddrInet4)
+		p := (*[2]byte)(unsafe.Pointer(&pp.Port))
+		sa.Port = int(p[0])<<8 + int(p[1])
+		for i := 0; i < len(sa.Addr); i++ {
+			sa.Addr[i] = pp.Addr[i]
+		}
+		return sa, nil
+
+	case AF_INET6:
+		pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa))
+		sa := new(SockaddrInet6)
+		p := (*[2]byte)(unsafe.Pointer(&pp.Port))
+		sa.Port = int(p[0])<<8 + int(p[1])
+		sa.ZoneId = pp.Scope_id
+		for i := 0; i < len(sa.Addr); i++ {
+			sa.Addr[i] = pp.Addr[i]
+		}
+		return sa, nil
+	}
+	return nil, EAFNOSUPPORT
+}
+
+func Socket(domain, typ, proto int) (fd Handle, err error) {
+	if domain == AF_INET6 && SocketDisableIPv6 {
+		return InvalidHandle, EAFNOSUPPORT
+	}
+	return socket(int32(domain), int32(typ), int32(proto))
+}
+
+func SetsockoptInt(fd Handle, level, opt int, value int) (err error) {
+	v := int32(value)
+	return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(&v)), int32(unsafe.Sizeof(v)))
+}
+
+func Bind(fd Handle, sa Sockaddr) (err error) {
+	ptr, n, err := sa.sockaddr()
+	if err != nil {
+		return err
+	}
+	return bind(fd, ptr, n)
+}
+
+func Connect(fd Handle, sa Sockaddr) (err error) {
+	ptr, n, err := sa.sockaddr()
+	if err != nil {
+		return err
+	}
+	return connect(fd, ptr, n)
+}
+
+func Getsockname(fd Handle) (sa Sockaddr, err error) {
+	var rsa RawSockaddrAny
+	l := int32(unsafe.Sizeof(rsa))
+	if err = getsockname(fd, &rsa, &l); err != nil {
+		return
+	}
+	return rsa.Sockaddr()
+}
+
+func Getpeername(fd Handle) (sa Sockaddr, err error) {
+	var rsa RawSockaddrAny
+	l := int32(unsafe.Sizeof(rsa))
+	if err = getpeername(fd, &rsa, &l); err != nil {
+		return
+	}
+	return rsa.Sockaddr()
+}
+
+func Listen(s Handle, n int) (err error) {
+	return listen(s, int32(n))
+}
+
+func Shutdown(fd Handle, how int) (err error) {
+	return shutdown(fd, int32(how))
+}
+
+func WSASendto(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, to Sockaddr, overlapped *Overlapped, croutine *byte) (err error) {
+	rsa, l, err := to.sockaddr()
+	if err != nil {
+		return err
+	}
+	return WSASendTo(s, bufs, bufcnt, sent, flags, (*RawSockaddrAny)(unsafe.Pointer(rsa)), l, overlapped, croutine)
+}
+
+func LoadGetAddrInfo() error {
+	return procGetAddrInfoW.Find()
+}
+
+var connectExFunc struct {
+	once sync.Once
+	addr uintptr
+	err  error
+}
+
+func LoadConnectEx() error {
+	connectExFunc.once.Do(func() {
+		var s Handle
+		s, connectExFunc.err = Socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)
+		if connectExFunc.err != nil {
+			return
+		}
+		defer CloseHandle(s)
+		var n uint32
+		connectExFunc.err = WSAIoctl(s,
+			SIO_GET_EXTENSION_FUNCTION_POINTER,
+			(*byte)(unsafe.Pointer(&WSAID_CONNECTEX)),
+			uint32(unsafe.Sizeof(WSAID_CONNECTEX)),
+			(*byte)(unsafe.Pointer(&connectExFunc.addr)),
+			uint32(unsafe.Sizeof(connectExFunc.addr)),
+			&n, nil, 0)
+	})
+	return connectExFunc.err
+}
+
+func connectEx(s Handle, name unsafe.Pointer, namelen int32, sendBuf *byte, sendDataLen uint32, bytesSent *uint32, overlapped *Overlapped) (err error) {
+	r1, _, e1 := Syscall9(connectExFunc.addr, 7, uintptr(s), uintptr(name), uintptr(namelen), uintptr(unsafe.Pointer(sendBuf)), uintptr(sendDataLen), uintptr(unsafe.Pointer(bytesSent)), uintptr(unsafe.Pointer(overlapped)), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func ConnectEx(fd Handle, sa Sockaddr, sendBuf *byte, sendDataLen uint32, bytesSent *uint32, overlapped *Overlapped) error {
+	err := LoadConnectEx()
+	if err != nil {
+		return errorspkg.New("failed to find ConnectEx: " + err.Error())
+	}
+	ptr, n, err := sa.sockaddr()
+	if err != nil {
+		return err
+	}
+	return connectEx(fd, ptr, n, sendBuf, sendDataLen, bytesSent, overlapped)
+}
+
+// Invented structures to support what package os expects.
+type Rusage struct {
+	CreationTime Filetime
+	ExitTime     Filetime
+	KernelTime   Filetime
+	UserTime     Filetime
+}
+
+type WaitStatus struct {
+	ExitCode uint32
+}
+
+func (w WaitStatus) Exited() bool { return true }
+
+func (w WaitStatus) ExitStatus() int { return int(w.ExitCode) }
+
+func (w WaitStatus) Signal() Signal { return -1 }
+
+func (w WaitStatus) CoreDump() bool { return false }
+
+func (w WaitStatus) Stopped() bool { return false }
+
+func (w WaitStatus) Continued() bool { return false }
+
+func (w WaitStatus) StopSignal() Signal { return -1 }
+
+func (w WaitStatus) Signaled() bool { return false }
+
+func (w WaitStatus) TrapCause() int { return -1 }
+
+// Timespec is an invented structure on Windows, but here for
+// consistency with the syscall package for other operating systems.
+type Timespec struct {
+	Sec  int64
+	Nsec int64
+}
+
+func TimespecToNsec(ts Timespec) int64 { return int64(ts.Sec)*1e9 + int64(ts.Nsec) }
+
+func NsecToTimespec(nsec int64) (ts Timespec) {
+	ts.Sec = nsec / 1e9
+	ts.Nsec = nsec % 1e9
+	return
+}
+
+// TODO(brainman): fix all needed for net
+
+func Accept(fd Handle) (nfd Handle, sa Sockaddr, err error) { return 0, nil, EWINDOWS }
+func Recvfrom(fd Handle, p []byte, flags int) (n int, from Sockaddr, err error) {
+	return 0, nil, EWINDOWS
+}
+func Sendto(fd Handle, p []byte, flags int, to Sockaddr) (err error)       { return EWINDOWS }
+func SetsockoptTimeval(fd Handle, level, opt int, tv *Timeval) (err error) { return EWINDOWS }
+
+// The Linger struct is wrong but we only noticed after Go 1.
+// sysLinger is the real system call structure.
+
+// BUG(brainman): The definition of Linger is not appropriate for direct use
+// with Setsockopt and Getsockopt.
+// Use SetsockoptLinger instead.
+
+type Linger struct {
+	Onoff  int32
+	Linger int32
+}
+
+type sysLinger struct {
+	Onoff  uint16
+	Linger uint16
+}
+
+type IPMreq struct {
+	Multiaddr [4]byte /* in_addr */
+	Interface [4]byte /* in_addr */
+}
+
+type IPv6Mreq struct {
+	Multiaddr [16]byte /* in6_addr */
+	Interface uint32
+}
+
+func GetsockoptInt(fd Handle, level, opt int) (int, error) { return -1, EWINDOWS }
+
+func SetsockoptLinger(fd Handle, level, opt int, l *Linger) (err error) {
+	sys := sysLinger{Onoff: uint16(l.Onoff), Linger: uint16(l.Linger)}
+	return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(&sys)), int32(unsafe.Sizeof(sys)))
+}
+
+func SetsockoptInet4Addr(fd Handle, level, opt int, value [4]byte) (err error) {
+	return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(&value[0])), 4)
+}
+func SetsockoptIPMreq(fd Handle, level, opt int, mreq *IPMreq) (err error) {
+	return Setsockopt(fd, int32(level), int32(opt), (*byte)(unsafe.Pointer(mreq)), int32(unsafe.Sizeof(*mreq)))
+}
+func SetsockoptIPv6Mreq(fd Handle, level, opt int, mreq *IPv6Mreq) (err error) { return EWINDOWS }
+
+func Getpid() (pid int) { return int(getCurrentProcessId()) }
+
+func FindFirstFile(name *uint16, data *Win32finddata) (handle Handle, err error) {
+	// NOTE(rsc): The Win32finddata struct is wrong for the system call:
+	// the two paths are each one uint16 short. Use the correct struct,
+	// a win32finddata1, and then copy the results out.
+	// There is no loss of expressivity here, because the final
+	// uint16, if it is used, is supposed to be a NUL, and Go doesn't need that.
+	// For Go 1.1, we might avoid the allocation of win32finddata1 here
+	// by adding a final Bug [2]uint16 field to the struct and then
+	// adjusting the fields in the result directly.
+	var data1 win32finddata1
+	handle, err = findFirstFile1(name, &data1)
+	if err == nil {
+		copyFindData(data, &data1)
+	}
+	return
+}
+
+func FindNextFile(handle Handle, data *Win32finddata) (err error) {
+	var data1 win32finddata1
+	err = findNextFile1(handle, &data1)
+	if err == nil {
+		copyFindData(data, &data1)
+	}
+	return
+}
+
+func getProcessEntry(pid int) (*ProcessEntry32, error) {
+	snapshot, err := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
+	if err != nil {
+		return nil, err
+	}
+	defer CloseHandle(snapshot)
+	var procEntry ProcessEntry32
+	procEntry.Size = uint32(unsafe.Sizeof(procEntry))
+	if err = Process32First(snapshot, &procEntry); err != nil {
+		return nil, err
+	}
+	for {
+		if procEntry.ProcessID == uint32(pid) {
+			return &procEntry, nil
+		}
+		err = Process32Next(snapshot, &procEntry)
+		if err != nil {
+			return nil, err
+		}
+	}
+}
+
+func Getppid() (ppid int) {
+	pe, err := getProcessEntry(Getpid())
+	if err != nil {
+		return -1
+	}
+	return int(pe.ParentProcessID)
+}
+
+// TODO(brainman): fix all needed for os
+func Fchdir(fd Handle) (err error)             { return EWINDOWS }
+func Link(oldpath, newpath string) (err error) { return EWINDOWS }
+func Symlink(path, link string) (err error)    { return EWINDOWS }
+
+func Fchmod(fd Handle, mode uint32) (err error)        { return EWINDOWS }
+func Chown(path string, uid int, gid int) (err error)  { return EWINDOWS }
+func Lchown(path string, uid int, gid int) (err error) { return EWINDOWS }
+func Fchown(fd Handle, uid int, gid int) (err error)   { return EWINDOWS }
+
+func Getuid() (uid int)                  { return -1 }
+func Geteuid() (euid int)                { return -1 }
+func Getgid() (gid int)                  { return -1 }
+func Getegid() (egid int)                { return -1 }
+func Getgroups() (gids []int, err error) { return nil, EWINDOWS }
+
+type Signal int
+
+func (s Signal) Signal() {}
+
+func (s Signal) String() string {
+	if 0 <= s && int(s) < len(signals) {
+		str := signals[s]
+		if str != "" {
+			return str
+		}
+	}
+	return "signal " + itoa(int(s))
+}
+
+func LoadCreateSymbolicLink() error {
+	return procCreateSymbolicLinkW.Find()
+}
+
+// Readlink returns the destination of the named symbolic link.
+func Readlink(path string, buf []byte) (n int, err error) {
+	fd, err := CreateFile(StringToUTF16Ptr(path), GENERIC_READ, 0, nil, OPEN_EXISTING,
+		FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS, 0)
+	if err != nil {
+		return -1, err
+	}
+	defer CloseHandle(fd)
+
+	rdbbuf := make([]byte, MAXIMUM_REPARSE_DATA_BUFFER_SIZE)
+	var bytesReturned uint32
+	err = DeviceIoControl(fd, FSCTL_GET_REPARSE_POINT, nil, 0, &rdbbuf[0], uint32(len(rdbbuf)), &bytesReturned, nil)
+	if err != nil {
+		return -1, err
+	}
+
+	rdb := (*reparseDataBuffer)(unsafe.Pointer(&rdbbuf[0]))
+	if uintptr(bytesReturned) < unsafe.Sizeof(*rdb) ||
+		rdb.ReparseTag != IO_REPARSE_TAG_SYMLINK {
+		// the path is not a symlink but another type of reparse point
+		return -1, ENOENT
+	}
+
+	s := UTF16ToString((*[0xffff]uint16)(unsafe.Pointer(&rdb.PathBuffer[0]))[:rdb.PrintNameLength/2])
+	n = copy(buf, []byte(s))
+	return n, nil
+}
diff --git a/src/pkg/syscall/syscall_windows_386.go b/src/syscall/syscall_windows_386.go
similarity index 100%
rename from src/pkg/syscall/syscall_windows_386.go
rename to src/syscall/syscall_windows_386.go
diff --git a/src/pkg/syscall/syscall_windows_amd64.go b/src/syscall/syscall_windows_amd64.go
similarity index 100%
rename from src/pkg/syscall/syscall_windows_amd64.go
rename to src/syscall/syscall_windows_amd64.go
diff --git a/src/pkg/syscall/syscall_windows_test.go b/src/syscall/syscall_windows_test.go
similarity index 100%
rename from src/pkg/syscall/syscall_windows_test.go
rename to src/syscall/syscall_windows_test.go
diff --git a/src/pkg/syscall/tables_nacl.go b/src/syscall/tables_nacl.go
similarity index 100%
rename from src/pkg/syscall/tables_nacl.go
rename to src/syscall/tables_nacl.go
diff --git a/src/syscall/time_nacl_386.s b/src/syscall/time_nacl_386.s
new file mode 100644
index 0000000..c0c89dc
--- /dev/null
+++ b/src/syscall/time_nacl_386.s
@@ -0,0 +1,11 @@
+// Copyright 2013 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+TEXT ·startTimer(SB),NOSPLIT,$0
+	JMP time·startTimer(SB)
+
+TEXT ·stopTimer(SB),NOSPLIT,$0
+	JMP time·stopTimer(SB)
diff --git a/src/syscall/time_nacl_amd64p32.s b/src/syscall/time_nacl_amd64p32.s
new file mode 100644
index 0000000..c0c89dc
--- /dev/null
+++ b/src/syscall/time_nacl_amd64p32.s
@@ -0,0 +1,11 @@
+// Copyright 2013 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "textflag.h"
+
+TEXT ·startTimer(SB),NOSPLIT,$0
+	JMP time·startTimer(SB)
+
+TEXT ·stopTimer(SB),NOSPLIT,$0
+	JMP time·stopTimer(SB)
diff --git a/src/syscall/time_nacl_arm.s b/src/syscall/time_nacl_arm.s
new file mode 100644
index 0000000..4f4b4d8
--- /dev/null
+++ b/src/syscall/time_nacl_arm.s
@@ -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.
+
+#include "textflag.h"
+
+TEXT ·startTimer(SB),NOSPLIT,$0
+	B time·startTimer(SB)
+
+TEXT ·stopTimer(SB),NOSPLIT,$0
+	B time·stopTimer(SB)
diff --git a/src/pkg/syscall/types_darwin.go b/src/syscall/types_darwin.go
similarity index 100%
rename from src/pkg/syscall/types_darwin.go
rename to src/syscall/types_darwin.go
diff --git a/src/pkg/syscall/types_dragonfly.go b/src/syscall/types_dragonfly.go
similarity index 100%
rename from src/pkg/syscall/types_dragonfly.go
rename to src/syscall/types_dragonfly.go
diff --git a/src/pkg/syscall/types_freebsd.go b/src/syscall/types_freebsd.go
similarity index 100%
rename from src/pkg/syscall/types_freebsd.go
rename to src/syscall/types_freebsd.go
diff --git a/src/pkg/syscall/types_linux.go b/src/syscall/types_linux.go
similarity index 100%
rename from src/pkg/syscall/types_linux.go
rename to src/syscall/types_linux.go
diff --git a/src/pkg/syscall/types_netbsd.go b/src/syscall/types_netbsd.go
similarity index 100%
rename from src/pkg/syscall/types_netbsd.go
rename to src/syscall/types_netbsd.go
diff --git a/src/pkg/syscall/types_openbsd.go b/src/syscall/types_openbsd.go
similarity index 100%
rename from src/pkg/syscall/types_openbsd.go
rename to src/syscall/types_openbsd.go
diff --git a/src/pkg/syscall/types_plan9.c b/src/syscall/types_plan9.c
similarity index 100%
rename from src/pkg/syscall/types_plan9.c
rename to src/syscall/types_plan9.c
diff --git a/src/pkg/syscall/types_solaris.go b/src/syscall/types_solaris.go
similarity index 100%
rename from src/pkg/syscall/types_solaris.go
rename to src/syscall/types_solaris.go
diff --git a/src/pkg/syscall/unzip_nacl.go b/src/syscall/unzip_nacl.go
similarity index 100%
rename from src/pkg/syscall/unzip_nacl.go
rename to src/syscall/unzip_nacl.go
diff --git a/src/pkg/syscall/zerrors_darwin_386.go b/src/syscall/zerrors_darwin_386.go
similarity index 100%
rename from src/pkg/syscall/zerrors_darwin_386.go
rename to src/syscall/zerrors_darwin_386.go
diff --git a/src/pkg/syscall/zerrors_darwin_amd64.go b/src/syscall/zerrors_darwin_amd64.go
similarity index 100%
rename from src/pkg/syscall/zerrors_darwin_amd64.go
rename to src/syscall/zerrors_darwin_amd64.go
diff --git a/src/pkg/syscall/zerrors_dragonfly_386.go b/src/syscall/zerrors_dragonfly_386.go
similarity index 100%
rename from src/pkg/syscall/zerrors_dragonfly_386.go
rename to src/syscall/zerrors_dragonfly_386.go
diff --git a/src/pkg/syscall/zerrors_dragonfly_amd64.go b/src/syscall/zerrors_dragonfly_amd64.go
similarity index 100%
rename from src/pkg/syscall/zerrors_dragonfly_amd64.go
rename to src/syscall/zerrors_dragonfly_amd64.go
diff --git a/src/pkg/syscall/zerrors_freebsd_386.go b/src/syscall/zerrors_freebsd_386.go
similarity index 100%
rename from src/pkg/syscall/zerrors_freebsd_386.go
rename to src/syscall/zerrors_freebsd_386.go
diff --git a/src/pkg/syscall/zerrors_freebsd_amd64.go b/src/syscall/zerrors_freebsd_amd64.go
similarity index 100%
rename from src/pkg/syscall/zerrors_freebsd_amd64.go
rename to src/syscall/zerrors_freebsd_amd64.go
diff --git a/src/pkg/syscall/zerrors_freebsd_arm.go b/src/syscall/zerrors_freebsd_arm.go
similarity index 100%
rename from src/pkg/syscall/zerrors_freebsd_arm.go
rename to src/syscall/zerrors_freebsd_arm.go
diff --git a/src/pkg/syscall/zerrors_linux_386.go b/src/syscall/zerrors_linux_386.go
similarity index 100%
rename from src/pkg/syscall/zerrors_linux_386.go
rename to src/syscall/zerrors_linux_386.go
diff --git a/src/pkg/syscall/zerrors_linux_amd64.go b/src/syscall/zerrors_linux_amd64.go
similarity index 100%
rename from src/pkg/syscall/zerrors_linux_amd64.go
rename to src/syscall/zerrors_linux_amd64.go
diff --git a/src/pkg/syscall/zerrors_linux_arm.go b/src/syscall/zerrors_linux_arm.go
similarity index 100%
rename from src/pkg/syscall/zerrors_linux_arm.go
rename to src/syscall/zerrors_linux_arm.go
diff --git a/src/pkg/syscall/zerrors_netbsd_386.go b/src/syscall/zerrors_netbsd_386.go
similarity index 100%
rename from src/pkg/syscall/zerrors_netbsd_386.go
rename to src/syscall/zerrors_netbsd_386.go
diff --git a/src/pkg/syscall/zerrors_netbsd_amd64.go b/src/syscall/zerrors_netbsd_amd64.go
similarity index 100%
rename from src/pkg/syscall/zerrors_netbsd_amd64.go
rename to src/syscall/zerrors_netbsd_amd64.go
diff --git a/src/pkg/syscall/zerrors_netbsd_arm.go b/src/syscall/zerrors_netbsd_arm.go
similarity index 100%
rename from src/pkg/syscall/zerrors_netbsd_arm.go
rename to src/syscall/zerrors_netbsd_arm.go
diff --git a/src/pkg/syscall/zerrors_openbsd_386.go b/src/syscall/zerrors_openbsd_386.go
similarity index 100%
rename from src/pkg/syscall/zerrors_openbsd_386.go
rename to src/syscall/zerrors_openbsd_386.go
diff --git a/src/pkg/syscall/zerrors_openbsd_amd64.go b/src/syscall/zerrors_openbsd_amd64.go
similarity index 100%
rename from src/pkg/syscall/zerrors_openbsd_amd64.go
rename to src/syscall/zerrors_openbsd_amd64.go
diff --git a/src/pkg/syscall/zerrors_plan9_386.go b/src/syscall/zerrors_plan9_386.go
similarity index 100%
rename from src/pkg/syscall/zerrors_plan9_386.go
rename to src/syscall/zerrors_plan9_386.go
diff --git a/src/pkg/syscall/zerrors_plan9_amd64.go b/src/syscall/zerrors_plan9_amd64.go
similarity index 100%
rename from src/pkg/syscall/zerrors_plan9_amd64.go
rename to src/syscall/zerrors_plan9_amd64.go
diff --git a/src/pkg/syscall/zerrors_solaris_amd64.go b/src/syscall/zerrors_solaris_amd64.go
similarity index 100%
rename from src/pkg/syscall/zerrors_solaris_amd64.go
rename to src/syscall/zerrors_solaris_amd64.go
diff --git a/src/pkg/syscall/zerrors_windows.go b/src/syscall/zerrors_windows.go
similarity index 100%
rename from src/pkg/syscall/zerrors_windows.go
rename to src/syscall/zerrors_windows.go
diff --git a/src/pkg/syscall/zerrors_windows_386.go b/src/syscall/zerrors_windows_386.go
similarity index 100%
rename from src/pkg/syscall/zerrors_windows_386.go
rename to src/syscall/zerrors_windows_386.go
diff --git a/src/pkg/syscall/zerrors_windows_amd64.go b/src/syscall/zerrors_windows_amd64.go
similarity index 100%
rename from src/pkg/syscall/zerrors_windows_amd64.go
rename to src/syscall/zerrors_windows_amd64.go
diff --git a/src/syscall/zsyscall_darwin_386.go b/src/syscall/zsyscall_darwin_386.go
new file mode 100644
index 0000000..934565f
--- /dev/null
+++ b/src/syscall/zsyscall_darwin_386.go
@@ -0,0 +1,1419 @@
+// mksyscall.pl -l32 syscall_bsd.go syscall_darwin.go syscall_darwin_386.go
+// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
+
+package syscall
+
+import "unsafe"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getgroups(ngid int, gid *_Gid_t) (n int, err error) {
+	r0, _, e1 := RawSyscall(SYS_GETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func setgroups(ngid int, gid *_Gid_t) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) {
+	r0, _, e1 := Syscall6(SYS_WAIT4, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0)
+	wpid = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
+	r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
+	_, _, e1 := Syscall(SYS_BIND, uintptr(s), uintptr(addr), uintptr(addrlen))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
+	_, _, e1 := Syscall(SYS_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func socket(domain int, typ int, proto int) (fd int, err error) {
+	r0, _, e1 := RawSyscall(SYS_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto))
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) {
+	_, _, e1 := Syscall6(SYS_GETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) {
+	_, _, e1 := Syscall6(SYS_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETPEERNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETSOCKNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Shutdown(s int, how int) (err error) {
+	_, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(s), uintptr(how), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) {
+	_, _, e1 := RawSyscall6(SYS_SOCKETPAIR, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_RECVFROM, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) {
+	var _p0 unsafe.Pointer
+	if len(buf) > 0 {
+		_p0 = unsafe.Pointer(&buf[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall6(SYS_SENDTO, uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
+	r0, _, e1 := Syscall(SYS_RECVMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
+	r0, _, e1 := Syscall(SYS_SENDMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func kevent(kq int, change unsafe.Pointer, nchange int, event unsafe.Pointer, nevent int, timeout *Timespec) (n int, err error) {
+	r0, _, e1 := Syscall6(SYS_KEVENT, uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout)))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) {
+	var _p0 unsafe.Pointer
+	if len(mib) > 0 {
+		_p0 = unsafe.Pointer(&mib[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall6(SYS___SYSCTL, uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func utimes(path string, timeval *[2]Timeval) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(timeval)), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func futimes(fd int, timeval *[2]Timeval) (err error) {
+	_, _, e1 := Syscall(SYS_FUTIMES, uintptr(fd), uintptr(unsafe.Pointer(timeval)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func fcntl(fd int, cmd int, arg int) (val int, err error) {
+	r0, _, e1 := Syscall(SYS_FCNTL, uintptr(fd), uintptr(cmd), uintptr(arg))
+	val = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func ptrace(request int, pid int, addr uintptr, data uintptr) (err error) {
+	_, _, e1 := Syscall6(SYS_PTRACE, uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func pipe() (r int, w int, err error) {
+	r0, r1, e1 := RawSyscall(SYS_PIPE, 0, 0, 0)
+	r = int(r0)
+	w = int(r1)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func kill(pid int, signum int, posix int) (err error) {
+	_, _, e1 := Syscall(SYS_KILL, uintptr(pid), uintptr(signum), uintptr(posix))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Access(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_ACCESS, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Adjtime(delta *Timeval, olddelta *Timeval) (err error) {
+	_, _, e1 := Syscall(SYS_ADJTIME, uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chdir(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chflags(path string, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHFLAGS, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chmod(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHMOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chown(path string, uid int, gid int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chroot(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHROOT, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Close(fd int) (err error) {
+	_, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Dup(fd int) (nfd int, err error) {
+	r0, _, e1 := RawSyscall(SYS_DUP, uintptr(fd), 0, 0)
+	nfd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Dup2(from int, to int) (err error) {
+	_, _, e1 := RawSyscall(SYS_DUP2, uintptr(from), uintptr(to), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Exchangedata(path1 string, path2 string, options int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path1)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(path2)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_EXCHANGEDATA, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(options))
+	use(unsafe.Pointer(_p0))
+	use(unsafe.Pointer(_p1))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Exit(code int) {
+	Syscall(SYS_EXIT, uintptr(code), 0, 0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchdir(fd int) (err error) {
+	_, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchflags(fd int, flags int) (err error) {
+	_, _, e1 := Syscall(SYS_FCHFLAGS, uintptr(fd), uintptr(flags), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchmod(fd int, mode uint32) (err error) {
+	_, _, e1 := Syscall(SYS_FCHMOD, uintptr(fd), uintptr(mode), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchown(fd int, uid int, gid int) (err error) {
+	_, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Flock(fd int, how int) (err error) {
+	_, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fpathconf(fd int, name int) (val int, err error) {
+	r0, _, e1 := Syscall(SYS_FPATHCONF, uintptr(fd), uintptr(name), 0)
+	val = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fstat(fd int, stat *Stat_t) (err error) {
+	_, _, e1 := Syscall(SYS_FSTAT64, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fstatfs(fd int, stat *Statfs_t) (err error) {
+	_, _, e1 := Syscall(SYS_FSTATFS64, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fsync(fd int) (err error) {
+	_, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Ftruncate(fd int, length int64) (err error) {
+	_, _, e1 := Syscall(SYS_FTRUNCATE, uintptr(fd), uintptr(length), uintptr(length>>32))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(buf) > 0 {
+		_p0 = unsafe.Pointer(&buf[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_GETDIRENTRIES64, uintptr(fd), uintptr(_p0), uintptr(len(buf)), uintptr(unsafe.Pointer(basep)), 0, 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getdtablesize() (size int) {
+	r0, _, _ := Syscall(SYS_GETDTABLESIZE, 0, 0, 0)
+	size = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getegid() (egid int) {
+	r0, _, _ := RawSyscall(SYS_GETEGID, 0, 0, 0)
+	egid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Geteuid() (uid int) {
+	r0, _, _ := RawSyscall(SYS_GETEUID, 0, 0, 0)
+	uid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getgid() (gid int) {
+	r0, _, _ := RawSyscall(SYS_GETGID, 0, 0, 0)
+	gid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpgid(pid int) (pgid int, err error) {
+	r0, _, e1 := RawSyscall(SYS_GETPGID, uintptr(pid), 0, 0)
+	pgid = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpgrp() (pgrp int) {
+	r0, _, _ := RawSyscall(SYS_GETPGRP, 0, 0, 0)
+	pgrp = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpid() (pid int) {
+	r0, _, _ := RawSyscall(SYS_GETPID, 0, 0, 0)
+	pid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getppid() (ppid int) {
+	r0, _, _ := RawSyscall(SYS_GETPPID, 0, 0, 0)
+	ppid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpriority(which int, who int) (prio int, err error) {
+	r0, _, e1 := Syscall(SYS_GETPRIORITY, uintptr(which), uintptr(who), 0)
+	prio = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getrlimit(which int, lim *Rlimit) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getrusage(who int, rusage *Rusage) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETRUSAGE, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getsid(pid int) (sid int, err error) {
+	r0, _, e1 := RawSyscall(SYS_GETSID, uintptr(pid), 0, 0)
+	sid = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getuid() (uid int) {
+	r0, _, _ := RawSyscall(SYS_GETUID, 0, 0, 0)
+	uid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Issetugid() (tainted bool) {
+	r0, _, _ := RawSyscall(SYS_ISSETUGID, 0, 0, 0)
+	tainted = bool(r0 != 0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Kqueue() (fd int, err error) {
+	r0, _, e1 := Syscall(SYS_KQUEUE, 0, 0, 0)
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Lchown(path string, uid int, gid int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_LCHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Link(path string, link string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(link)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_LINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	use(unsafe.Pointer(_p0))
+	use(unsafe.Pointer(_p1))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Listen(s int, backlog int) (err error) {
+	_, _, e1 := Syscall(SYS_LISTEN, uintptr(s), uintptr(backlog), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Lstat(path string, stat *Stat_t) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_LSTAT64, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mkdir(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_MKDIR, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mkfifo(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_MKFIFO, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mknod(path string, mode uint32, dev int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_MKNOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mlock(b []byte) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mlockall(flags int) (err error) {
+	_, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mprotect(b []byte, prot int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Munlock(b []byte) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Munlockall() (err error) {
+	_, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Open(path string, mode int, perm uint32) (fd int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
+	use(unsafe.Pointer(_p0))
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pathconf(path string, name int) (val int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall(SYS_PATHCONF, uintptr(unsafe.Pointer(_p0)), uintptr(name), 0)
+	use(unsafe.Pointer(_p0))
+	val = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pread(fd int, p []byte, offset int64) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_PREAD, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), uintptr(offset>>32), 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_PWRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), uintptr(offset>>32), 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func read(fd int, p []byte) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(_p0), uintptr(len(p)))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Readlink(path string, buf []byte) (n int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 unsafe.Pointer
+	if len(buf) > 0 {
+		_p1 = unsafe.Pointer(&buf[0])
+	} else {
+		_p1 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_READLINK, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
+	use(unsafe.Pointer(_p0))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Rename(from string, to string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(from)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(to)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_RENAME, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	use(unsafe.Pointer(_p0))
+	use(unsafe.Pointer(_p1))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Revoke(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_REVOKE, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Rmdir(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_RMDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
+	r0, r1, e1 := Syscall6(SYS_LSEEK, uintptr(fd), uintptr(offset), uintptr(offset>>32), uintptr(whence), 0, 0)
+	newoffset = int64(int64(r1)<<32 | int64(r0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Select(n int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (err error) {
+	_, _, e1 := Syscall6(SYS_SELECT, uintptr(n), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setegid(egid int) (err error) {
+	_, _, e1 := Syscall(SYS_SETEGID, uintptr(egid), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Seteuid(euid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETEUID, uintptr(euid), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setgid(gid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETGID, uintptr(gid), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setlogin(name string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(name)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_SETLOGIN, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setpgid(pid int, pgid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETPGID, uintptr(pid), uintptr(pgid), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setpriority(which int, who int, prio int) (err error) {
+	_, _, e1 := Syscall(SYS_SETPRIORITY, uintptr(which), uintptr(who), uintptr(prio))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setprivexec(flag int) (err error) {
+	_, _, e1 := Syscall(SYS_SETPRIVEXEC, uintptr(flag), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setregid(rgid int, egid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setreuid(ruid int, euid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setrlimit(which int, lim *Rlimit) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setsid() (pid int, err error) {
+	r0, _, e1 := RawSyscall(SYS_SETSID, 0, 0, 0)
+	pid = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Settimeofday(tp *Timeval) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETTIMEOFDAY, uintptr(unsafe.Pointer(tp)), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setuid(uid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETUID, uintptr(uid), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Stat(path string, stat *Stat_t) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_STAT64, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Statfs(path string, stat *Statfs_t) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_STATFS64, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Symlink(path string, link string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(link)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_SYMLINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	use(unsafe.Pointer(_p0))
+	use(unsafe.Pointer(_p1))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Sync() (err error) {
+	_, _, e1 := Syscall(SYS_SYNC, 0, 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Truncate(path string, length int64) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_TRUNCATE, uintptr(unsafe.Pointer(_p0)), uintptr(length), uintptr(length>>32))
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Umask(newmask int) (oldmask int) {
+	r0, _, _ := Syscall(SYS_UMASK, uintptr(newmask), 0, 0)
+	oldmask = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Undelete(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UNDELETE, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Unlink(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UNLINK, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Unmount(path string, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UNMOUNT, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func write(fd int, p []byte) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) {
+	r0, _, e1 := Syscall9(SYS_MMAP, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), uintptr(pos), uintptr(pos>>32), 0, 0)
+	ret = uintptr(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func munmap(addr uintptr, length uintptr) (err error) {
+	_, _, e1 := Syscall(SYS_MUNMAP, uintptr(addr), uintptr(length), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func readlen(fd int, buf *byte, nbuf int) (n int, err error) {
+	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func writelen(fd int, buf *byte, nbuf int) (n int, err error) {
+	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func gettimeofday(tp *Timeval) (sec int32, usec int32, err error) {
+	r0, r1, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tp)), 0, 0)
+	sec = int32(r0)
+	usec = int32(r1)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
diff --git a/src/syscall/zsyscall_darwin_amd64.go b/src/syscall/zsyscall_darwin_amd64.go
new file mode 100644
index 0000000..75cf251
--- /dev/null
+++ b/src/syscall/zsyscall_darwin_amd64.go
@@ -0,0 +1,1419 @@
+// mksyscall.pl syscall_bsd.go syscall_darwin.go syscall_darwin_amd64.go
+// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
+
+package syscall
+
+import "unsafe"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getgroups(ngid int, gid *_Gid_t) (n int, err error) {
+	r0, _, e1 := RawSyscall(SYS_GETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func setgroups(ngid int, gid *_Gid_t) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) {
+	r0, _, e1 := Syscall6(SYS_WAIT4, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0)
+	wpid = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
+	r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
+	_, _, e1 := Syscall(SYS_BIND, uintptr(s), uintptr(addr), uintptr(addrlen))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
+	_, _, e1 := Syscall(SYS_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func socket(domain int, typ int, proto int) (fd int, err error) {
+	r0, _, e1 := RawSyscall(SYS_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto))
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) {
+	_, _, e1 := Syscall6(SYS_GETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) {
+	_, _, e1 := Syscall6(SYS_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETPEERNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETSOCKNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Shutdown(s int, how int) (err error) {
+	_, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(s), uintptr(how), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) {
+	_, _, e1 := RawSyscall6(SYS_SOCKETPAIR, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_RECVFROM, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) {
+	var _p0 unsafe.Pointer
+	if len(buf) > 0 {
+		_p0 = unsafe.Pointer(&buf[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall6(SYS_SENDTO, uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
+	r0, _, e1 := Syscall(SYS_RECVMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
+	r0, _, e1 := Syscall(SYS_SENDMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func kevent(kq int, change unsafe.Pointer, nchange int, event unsafe.Pointer, nevent int, timeout *Timespec) (n int, err error) {
+	r0, _, e1 := Syscall6(SYS_KEVENT, uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout)))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) {
+	var _p0 unsafe.Pointer
+	if len(mib) > 0 {
+		_p0 = unsafe.Pointer(&mib[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall6(SYS___SYSCTL, uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func utimes(path string, timeval *[2]Timeval) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(timeval)), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func futimes(fd int, timeval *[2]Timeval) (err error) {
+	_, _, e1 := Syscall(SYS_FUTIMES, uintptr(fd), uintptr(unsafe.Pointer(timeval)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func fcntl(fd int, cmd int, arg int) (val int, err error) {
+	r0, _, e1 := Syscall(SYS_FCNTL, uintptr(fd), uintptr(cmd), uintptr(arg))
+	val = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func ptrace(request int, pid int, addr uintptr, data uintptr) (err error) {
+	_, _, e1 := Syscall6(SYS_PTRACE, uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func pipe() (r int, w int, err error) {
+	r0, r1, e1 := RawSyscall(SYS_PIPE, 0, 0, 0)
+	r = int(r0)
+	w = int(r1)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func kill(pid int, signum int, posix int) (err error) {
+	_, _, e1 := Syscall(SYS_KILL, uintptr(pid), uintptr(signum), uintptr(posix))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Access(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_ACCESS, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Adjtime(delta *Timeval, olddelta *Timeval) (err error) {
+	_, _, e1 := Syscall(SYS_ADJTIME, uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chdir(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chflags(path string, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHFLAGS, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chmod(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHMOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chown(path string, uid int, gid int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chroot(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHROOT, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Close(fd int) (err error) {
+	_, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Dup(fd int) (nfd int, err error) {
+	r0, _, e1 := RawSyscall(SYS_DUP, uintptr(fd), 0, 0)
+	nfd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Dup2(from int, to int) (err error) {
+	_, _, e1 := RawSyscall(SYS_DUP2, uintptr(from), uintptr(to), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Exchangedata(path1 string, path2 string, options int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path1)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(path2)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_EXCHANGEDATA, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(options))
+	use(unsafe.Pointer(_p0))
+	use(unsafe.Pointer(_p1))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Exit(code int) {
+	Syscall(SYS_EXIT, uintptr(code), 0, 0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchdir(fd int) (err error) {
+	_, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchflags(fd int, flags int) (err error) {
+	_, _, e1 := Syscall(SYS_FCHFLAGS, uintptr(fd), uintptr(flags), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchmod(fd int, mode uint32) (err error) {
+	_, _, e1 := Syscall(SYS_FCHMOD, uintptr(fd), uintptr(mode), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchown(fd int, uid int, gid int) (err error) {
+	_, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Flock(fd int, how int) (err error) {
+	_, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fpathconf(fd int, name int) (val int, err error) {
+	r0, _, e1 := Syscall(SYS_FPATHCONF, uintptr(fd), uintptr(name), 0)
+	val = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fstat(fd int, stat *Stat_t) (err error) {
+	_, _, e1 := Syscall(SYS_FSTAT64, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fstatfs(fd int, stat *Statfs_t) (err error) {
+	_, _, e1 := Syscall(SYS_FSTATFS64, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fsync(fd int) (err error) {
+	_, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Ftruncate(fd int, length int64) (err error) {
+	_, _, e1 := Syscall(SYS_FTRUNCATE, uintptr(fd), uintptr(length), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(buf) > 0 {
+		_p0 = unsafe.Pointer(&buf[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_GETDIRENTRIES64, uintptr(fd), uintptr(_p0), uintptr(len(buf)), uintptr(unsafe.Pointer(basep)), 0, 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getdtablesize() (size int) {
+	r0, _, _ := Syscall(SYS_GETDTABLESIZE, 0, 0, 0)
+	size = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getegid() (egid int) {
+	r0, _, _ := RawSyscall(SYS_GETEGID, 0, 0, 0)
+	egid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Geteuid() (uid int) {
+	r0, _, _ := RawSyscall(SYS_GETEUID, 0, 0, 0)
+	uid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getgid() (gid int) {
+	r0, _, _ := RawSyscall(SYS_GETGID, 0, 0, 0)
+	gid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpgid(pid int) (pgid int, err error) {
+	r0, _, e1 := RawSyscall(SYS_GETPGID, uintptr(pid), 0, 0)
+	pgid = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpgrp() (pgrp int) {
+	r0, _, _ := RawSyscall(SYS_GETPGRP, 0, 0, 0)
+	pgrp = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpid() (pid int) {
+	r0, _, _ := RawSyscall(SYS_GETPID, 0, 0, 0)
+	pid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getppid() (ppid int) {
+	r0, _, _ := RawSyscall(SYS_GETPPID, 0, 0, 0)
+	ppid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpriority(which int, who int) (prio int, err error) {
+	r0, _, e1 := Syscall(SYS_GETPRIORITY, uintptr(which), uintptr(who), 0)
+	prio = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getrlimit(which int, lim *Rlimit) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getrusage(who int, rusage *Rusage) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETRUSAGE, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getsid(pid int) (sid int, err error) {
+	r0, _, e1 := RawSyscall(SYS_GETSID, uintptr(pid), 0, 0)
+	sid = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getuid() (uid int) {
+	r0, _, _ := RawSyscall(SYS_GETUID, 0, 0, 0)
+	uid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Issetugid() (tainted bool) {
+	r0, _, _ := RawSyscall(SYS_ISSETUGID, 0, 0, 0)
+	tainted = bool(r0 != 0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Kqueue() (fd int, err error) {
+	r0, _, e1 := Syscall(SYS_KQUEUE, 0, 0, 0)
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Lchown(path string, uid int, gid int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_LCHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Link(path string, link string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(link)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_LINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	use(unsafe.Pointer(_p0))
+	use(unsafe.Pointer(_p1))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Listen(s int, backlog int) (err error) {
+	_, _, e1 := Syscall(SYS_LISTEN, uintptr(s), uintptr(backlog), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Lstat(path string, stat *Stat_t) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_LSTAT64, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mkdir(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_MKDIR, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mkfifo(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_MKFIFO, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mknod(path string, mode uint32, dev int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_MKNOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mlock(b []byte) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mlockall(flags int) (err error) {
+	_, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mprotect(b []byte, prot int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Munlock(b []byte) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Munlockall() (err error) {
+	_, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Open(path string, mode int, perm uint32) (fd int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
+	use(unsafe.Pointer(_p0))
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pathconf(path string, name int) (val int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall(SYS_PATHCONF, uintptr(unsafe.Pointer(_p0)), uintptr(name), 0)
+	use(unsafe.Pointer(_p0))
+	val = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pread(fd int, p []byte, offset int64) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_PREAD, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_PWRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func read(fd int, p []byte) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(_p0), uintptr(len(p)))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Readlink(path string, buf []byte) (n int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 unsafe.Pointer
+	if len(buf) > 0 {
+		_p1 = unsafe.Pointer(&buf[0])
+	} else {
+		_p1 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_READLINK, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
+	use(unsafe.Pointer(_p0))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Rename(from string, to string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(from)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(to)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_RENAME, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	use(unsafe.Pointer(_p0))
+	use(unsafe.Pointer(_p1))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Revoke(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_REVOKE, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Rmdir(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_RMDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
+	r0, _, e1 := Syscall(SYS_LSEEK, uintptr(fd), uintptr(offset), uintptr(whence))
+	newoffset = int64(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Select(n int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (err error) {
+	_, _, e1 := Syscall6(SYS_SELECT, uintptr(n), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setegid(egid int) (err error) {
+	_, _, e1 := Syscall(SYS_SETEGID, uintptr(egid), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Seteuid(euid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETEUID, uintptr(euid), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setgid(gid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETGID, uintptr(gid), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setlogin(name string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(name)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_SETLOGIN, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setpgid(pid int, pgid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETPGID, uintptr(pid), uintptr(pgid), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setpriority(which int, who int, prio int) (err error) {
+	_, _, e1 := Syscall(SYS_SETPRIORITY, uintptr(which), uintptr(who), uintptr(prio))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setprivexec(flag int) (err error) {
+	_, _, e1 := Syscall(SYS_SETPRIVEXEC, uintptr(flag), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setregid(rgid int, egid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setreuid(ruid int, euid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setrlimit(which int, lim *Rlimit) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setsid() (pid int, err error) {
+	r0, _, e1 := RawSyscall(SYS_SETSID, 0, 0, 0)
+	pid = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Settimeofday(tp *Timeval) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETTIMEOFDAY, uintptr(unsafe.Pointer(tp)), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setuid(uid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETUID, uintptr(uid), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Stat(path string, stat *Stat_t) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_STAT64, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Statfs(path string, stat *Statfs_t) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_STATFS64, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Symlink(path string, link string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(link)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_SYMLINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	use(unsafe.Pointer(_p0))
+	use(unsafe.Pointer(_p1))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Sync() (err error) {
+	_, _, e1 := Syscall(SYS_SYNC, 0, 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Truncate(path string, length int64) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_TRUNCATE, uintptr(unsafe.Pointer(_p0)), uintptr(length), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Umask(newmask int) (oldmask int) {
+	r0, _, _ := Syscall(SYS_UMASK, uintptr(newmask), 0, 0)
+	oldmask = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Undelete(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UNDELETE, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Unlink(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UNLINK, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Unmount(path string, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UNMOUNT, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func write(fd int, p []byte) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) {
+	r0, _, e1 := Syscall6(SYS_MMAP, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), uintptr(pos))
+	ret = uintptr(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func munmap(addr uintptr, length uintptr) (err error) {
+	_, _, e1 := Syscall(SYS_MUNMAP, uintptr(addr), uintptr(length), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func readlen(fd int, buf *byte, nbuf int) (n int, err error) {
+	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func writelen(fd int, buf *byte, nbuf int) (n int, err error) {
+	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func gettimeofday(tp *Timeval) (sec int64, usec int32, err error) {
+	r0, r1, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tp)), 0, 0)
+	sec = int64(r0)
+	usec = int32(r1)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
diff --git a/src/syscall/zsyscall_dragonfly_386.go b/src/syscall/zsyscall_dragonfly_386.go
new file mode 100644
index 0000000..01b0819
--- /dev/null
+++ b/src/syscall/zsyscall_dragonfly_386.go
@@ -0,0 +1,1317 @@
+// mksyscall.pl -l32 -dragonfly syscall_bsd.go syscall_dragonfly.go syscall_dragonfly_386.go
+// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
+
+package syscall
+
+import "unsafe"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getgroups(ngid int, gid *_Gid_t) (n int, err error) {
+	r0, _, e1 := RawSyscall(SYS_GETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func setgroups(ngid int, gid *_Gid_t) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) {
+	r0, _, e1 := Syscall6(SYS_WAIT4, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0)
+	wpid = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
+	r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
+	_, _, e1 := Syscall(SYS_BIND, uintptr(s), uintptr(addr), uintptr(addrlen))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
+	_, _, e1 := Syscall(SYS_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func socket(domain int, typ int, proto int) (fd int, err error) {
+	r0, _, e1 := RawSyscall(SYS_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto))
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) {
+	_, _, e1 := Syscall6(SYS_GETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) {
+	_, _, e1 := Syscall6(SYS_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETPEERNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETSOCKNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Shutdown(s int, how int) (err error) {
+	_, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(s), uintptr(how), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) {
+	_, _, e1 := RawSyscall6(SYS_SOCKETPAIR, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_RECVFROM, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) {
+	var _p0 unsafe.Pointer
+	if len(buf) > 0 {
+		_p0 = unsafe.Pointer(&buf[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall6(SYS_SENDTO, uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
+	r0, _, e1 := Syscall(SYS_RECVMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
+	r0, _, e1 := Syscall(SYS_SENDMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func kevent(kq int, change unsafe.Pointer, nchange int, event unsafe.Pointer, nevent int, timeout *Timespec) (n int, err error) {
+	r0, _, e1 := Syscall6(SYS_KEVENT, uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout)))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) {
+	var _p0 unsafe.Pointer
+	if len(mib) > 0 {
+		_p0 = unsafe.Pointer(&mib[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall6(SYS___SYSCTL, uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func utimes(path string, timeval *[2]Timeval) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(timeval)), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func futimes(fd int, timeval *[2]Timeval) (err error) {
+	_, _, e1 := Syscall(SYS_FUTIMES, uintptr(fd), uintptr(unsafe.Pointer(timeval)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func fcntl(fd int, cmd int, arg int) (val int, err error) {
+	r0, _, e1 := Syscall(SYS_FCNTL, uintptr(fd), uintptr(cmd), uintptr(arg))
+	val = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func pipe() (r int, w int, err error) {
+	r0, r1, e1 := RawSyscall(SYS_PIPE, 0, 0, 0)
+	r = int(r0)
+	w = int(r1)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func extpread(fd int, p []byte, flags int, offset int64) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_EXTPREAD, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(offset), uintptr(offset>>32))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func extpwrite(fd int, p []byte, flags int, offset int64) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_EXTPWRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(offset), uintptr(offset>>32))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Access(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_ACCESS, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Adjtime(delta *Timeval, olddelta *Timeval) (err error) {
+	_, _, e1 := Syscall(SYS_ADJTIME, uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chdir(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chflags(path string, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHFLAGS, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chmod(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHMOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chown(path string, uid int, gid int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chroot(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHROOT, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Close(fd int) (err error) {
+	_, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Dup(fd int) (nfd int, err error) {
+	r0, _, e1 := RawSyscall(SYS_DUP, uintptr(fd), 0, 0)
+	nfd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Dup2(from int, to int) (err error) {
+	_, _, e1 := RawSyscall(SYS_DUP2, uintptr(from), uintptr(to), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Exit(code int) {
+	Syscall(SYS_EXIT, uintptr(code), 0, 0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchdir(fd int) (err error) {
+	_, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchflags(fd int, flags int) (err error) {
+	_, _, e1 := Syscall(SYS_FCHFLAGS, uintptr(fd), uintptr(flags), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchmod(fd int, mode uint32) (err error) {
+	_, _, e1 := Syscall(SYS_FCHMOD, uintptr(fd), uintptr(mode), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchown(fd int, uid int, gid int) (err error) {
+	_, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Flock(fd int, how int) (err error) {
+	_, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fpathconf(fd int, name int) (val int, err error) {
+	r0, _, e1 := Syscall(SYS_FPATHCONF, uintptr(fd), uintptr(name), 0)
+	val = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fstat(fd int, stat *Stat_t) (err error) {
+	_, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fstatfs(fd int, stat *Statfs_t) (err error) {
+	_, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fsync(fd int) (err error) {
+	_, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Ftruncate(fd int, length int64) (err error) {
+	_, _, e1 := Syscall6(SYS_FTRUNCATE, uintptr(fd), 0, uintptr(length), uintptr(length>>32), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(buf) > 0 {
+		_p0 = unsafe.Pointer(&buf[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_GETDIRENTRIES, uintptr(fd), uintptr(_p0), uintptr(len(buf)), uintptr(unsafe.Pointer(basep)), 0, 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getdtablesize() (size int) {
+	r0, _, _ := Syscall(SYS_GETDTABLESIZE, 0, 0, 0)
+	size = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getegid() (egid int) {
+	r0, _, _ := RawSyscall(SYS_GETEGID, 0, 0, 0)
+	egid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Geteuid() (uid int) {
+	r0, _, _ := RawSyscall(SYS_GETEUID, 0, 0, 0)
+	uid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getgid() (gid int) {
+	r0, _, _ := RawSyscall(SYS_GETGID, 0, 0, 0)
+	gid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpgid(pid int) (pgid int, err error) {
+	r0, _, e1 := RawSyscall(SYS_GETPGID, uintptr(pid), 0, 0)
+	pgid = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpgrp() (pgrp int) {
+	r0, _, _ := RawSyscall(SYS_GETPGRP, 0, 0, 0)
+	pgrp = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpid() (pid int) {
+	r0, _, _ := RawSyscall(SYS_GETPID, 0, 0, 0)
+	pid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getppid() (ppid int) {
+	r0, _, _ := RawSyscall(SYS_GETPPID, 0, 0, 0)
+	ppid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpriority(which int, who int) (prio int, err error) {
+	r0, _, e1 := Syscall(SYS_GETPRIORITY, uintptr(which), uintptr(who), 0)
+	prio = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getrlimit(which int, lim *Rlimit) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getrusage(who int, rusage *Rusage) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETRUSAGE, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getsid(pid int) (sid int, err error) {
+	r0, _, e1 := RawSyscall(SYS_GETSID, uintptr(pid), 0, 0)
+	sid = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Gettimeofday(tv *Timeval) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getuid() (uid int) {
+	r0, _, _ := RawSyscall(SYS_GETUID, 0, 0, 0)
+	uid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Issetugid() (tainted bool) {
+	r0, _, _ := Syscall(SYS_ISSETUGID, 0, 0, 0)
+	tainted = bool(r0 != 0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Kill(pid int, signum Signal) (err error) {
+	_, _, e1 := Syscall(SYS_KILL, uintptr(pid), uintptr(signum), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Kqueue() (fd int, err error) {
+	r0, _, e1 := Syscall(SYS_KQUEUE, 0, 0, 0)
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Lchown(path string, uid int, gid int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_LCHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Link(path string, link string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(link)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_LINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	use(unsafe.Pointer(_p0))
+	use(unsafe.Pointer(_p1))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Listen(s int, backlog int) (err error) {
+	_, _, e1 := Syscall(SYS_LISTEN, uintptr(s), uintptr(backlog), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Lstat(path string, stat *Stat_t) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_LSTAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mkdir(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_MKDIR, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mkfifo(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_MKFIFO, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mknod(path string, mode uint32, dev int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_MKNOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Nanosleep(time *Timespec, leftover *Timespec) (err error) {
+	_, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Open(path string, mode int, perm uint32) (fd int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
+	use(unsafe.Pointer(_p0))
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pathconf(path string, name int) (val int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall(SYS_PATHCONF, uintptr(unsafe.Pointer(_p0)), uintptr(name), 0)
+	use(unsafe.Pointer(_p0))
+	val = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func read(fd int, p []byte) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(_p0), uintptr(len(p)))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Readlink(path string, buf []byte) (n int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 unsafe.Pointer
+	if len(buf) > 0 {
+		_p1 = unsafe.Pointer(&buf[0])
+	} else {
+		_p1 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_READLINK, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
+	use(unsafe.Pointer(_p0))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Rename(from string, to string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(from)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(to)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_RENAME, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	use(unsafe.Pointer(_p0))
+	use(unsafe.Pointer(_p1))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Revoke(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_REVOKE, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Rmdir(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_RMDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
+	r0, r1, e1 := Syscall6(SYS_LSEEK, uintptr(fd), 0, uintptr(offset), uintptr(offset>>32), uintptr(whence), 0)
+	newoffset = int64(int64(r1)<<32 | int64(r0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Select(n int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (err error) {
+	_, _, e1 := Syscall6(SYS_SELECT, uintptr(n), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setegid(egid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETEGID, uintptr(egid), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Seteuid(euid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETEUID, uintptr(euid), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setgid(gid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETGID, uintptr(gid), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setlogin(name string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(name)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_SETLOGIN, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setpgid(pid int, pgid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETPGID, uintptr(pid), uintptr(pgid), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setpriority(which int, who int, prio int) (err error) {
+	_, _, e1 := Syscall(SYS_SETPRIORITY, uintptr(which), uintptr(who), uintptr(prio))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setregid(rgid int, egid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setreuid(ruid int, euid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setrlimit(which int, lim *Rlimit) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setsid() (pid int, err error) {
+	r0, _, e1 := RawSyscall(SYS_SETSID, 0, 0, 0)
+	pid = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Settimeofday(tp *Timeval) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETTIMEOFDAY, uintptr(unsafe.Pointer(tp)), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setuid(uid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETUID, uintptr(uid), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Stat(path string, stat *Stat_t) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Statfs(path string, stat *Statfs_t) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_STATFS, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Symlink(path string, link string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(link)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_SYMLINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	use(unsafe.Pointer(_p0))
+	use(unsafe.Pointer(_p1))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Sync() (err error) {
+	_, _, e1 := Syscall(SYS_SYNC, 0, 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Truncate(path string, length int64) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_TRUNCATE, uintptr(unsafe.Pointer(_p0)), 0, uintptr(length), uintptr(length>>32), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Umask(newmask int) (oldmask int) {
+	r0, _, _ := Syscall(SYS_UMASK, uintptr(newmask), 0, 0)
+	oldmask = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Undelete(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UNDELETE, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Unlink(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UNLINK, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Unmount(path string, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UNMOUNT, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func write(fd int, p []byte) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) {
+	r0, _, e1 := Syscall9(SYS_MMAP, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), 0, uintptr(pos), uintptr(pos>>32), 0)
+	ret = uintptr(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func munmap(addr uintptr, length uintptr) (err error) {
+	_, _, e1 := Syscall(SYS_MUNMAP, uintptr(addr), uintptr(length), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func readlen(fd int, buf *byte, nbuf int) (n int, err error) {
+	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func writelen(fd int, buf *byte, nbuf int) (n int, err error) {
+	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
diff --git a/src/syscall/zsyscall_dragonfly_amd64.go b/src/syscall/zsyscall_dragonfly_amd64.go
new file mode 100644
index 0000000..0121374
--- /dev/null
+++ b/src/syscall/zsyscall_dragonfly_amd64.go
@@ -0,0 +1,1317 @@
+// mksyscall.pl -dragonfly syscall_bsd.go syscall_dragonfly.go syscall_dragonfly_amd64.go
+// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
+
+package syscall
+
+import "unsafe"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getgroups(ngid int, gid *_Gid_t) (n int, err error) {
+	r0, _, e1 := RawSyscall(SYS_GETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func setgroups(ngid int, gid *_Gid_t) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) {
+	r0, _, e1 := Syscall6(SYS_WAIT4, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0)
+	wpid = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
+	r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
+	_, _, e1 := Syscall(SYS_BIND, uintptr(s), uintptr(addr), uintptr(addrlen))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
+	_, _, e1 := Syscall(SYS_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func socket(domain int, typ int, proto int) (fd int, err error) {
+	r0, _, e1 := RawSyscall(SYS_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto))
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) {
+	_, _, e1 := Syscall6(SYS_GETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) {
+	_, _, e1 := Syscall6(SYS_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETPEERNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETSOCKNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Shutdown(s int, how int) (err error) {
+	_, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(s), uintptr(how), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) {
+	_, _, e1 := RawSyscall6(SYS_SOCKETPAIR, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_RECVFROM, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) {
+	var _p0 unsafe.Pointer
+	if len(buf) > 0 {
+		_p0 = unsafe.Pointer(&buf[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall6(SYS_SENDTO, uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
+	r0, _, e1 := Syscall(SYS_RECVMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
+	r0, _, e1 := Syscall(SYS_SENDMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func kevent(kq int, change unsafe.Pointer, nchange int, event unsafe.Pointer, nevent int, timeout *Timespec) (n int, err error) {
+	r0, _, e1 := Syscall6(SYS_KEVENT, uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout)))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) {
+	var _p0 unsafe.Pointer
+	if len(mib) > 0 {
+		_p0 = unsafe.Pointer(&mib[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall6(SYS___SYSCTL, uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func utimes(path string, timeval *[2]Timeval) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(timeval)), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func futimes(fd int, timeval *[2]Timeval) (err error) {
+	_, _, e1 := Syscall(SYS_FUTIMES, uintptr(fd), uintptr(unsafe.Pointer(timeval)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func fcntl(fd int, cmd int, arg int) (val int, err error) {
+	r0, _, e1 := Syscall(SYS_FCNTL, uintptr(fd), uintptr(cmd), uintptr(arg))
+	val = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func pipe() (r int, w int, err error) {
+	r0, r1, e1 := RawSyscall(SYS_PIPE, 0, 0, 0)
+	r = int(r0)
+	w = int(r1)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func extpread(fd int, p []byte, flags int, offset int64) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_EXTPREAD, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(offset), 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func extpwrite(fd int, p []byte, flags int, offset int64) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_EXTPWRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(offset), 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Access(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_ACCESS, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Adjtime(delta *Timeval, olddelta *Timeval) (err error) {
+	_, _, e1 := Syscall(SYS_ADJTIME, uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chdir(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chflags(path string, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHFLAGS, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chmod(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHMOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chown(path string, uid int, gid int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chroot(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHROOT, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Close(fd int) (err error) {
+	_, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Dup(fd int) (nfd int, err error) {
+	r0, _, e1 := RawSyscall(SYS_DUP, uintptr(fd), 0, 0)
+	nfd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Dup2(from int, to int) (err error) {
+	_, _, e1 := RawSyscall(SYS_DUP2, uintptr(from), uintptr(to), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Exit(code int) {
+	Syscall(SYS_EXIT, uintptr(code), 0, 0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchdir(fd int) (err error) {
+	_, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchflags(fd int, flags int) (err error) {
+	_, _, e1 := Syscall(SYS_FCHFLAGS, uintptr(fd), uintptr(flags), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchmod(fd int, mode uint32) (err error) {
+	_, _, e1 := Syscall(SYS_FCHMOD, uintptr(fd), uintptr(mode), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchown(fd int, uid int, gid int) (err error) {
+	_, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Flock(fd int, how int) (err error) {
+	_, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fpathconf(fd int, name int) (val int, err error) {
+	r0, _, e1 := Syscall(SYS_FPATHCONF, uintptr(fd), uintptr(name), 0)
+	val = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fstat(fd int, stat *Stat_t) (err error) {
+	_, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fstatfs(fd int, stat *Statfs_t) (err error) {
+	_, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fsync(fd int) (err error) {
+	_, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Ftruncate(fd int, length int64) (err error) {
+	_, _, e1 := Syscall(SYS_FTRUNCATE, uintptr(fd), 0, uintptr(length))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(buf) > 0 {
+		_p0 = unsafe.Pointer(&buf[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_GETDIRENTRIES, uintptr(fd), uintptr(_p0), uintptr(len(buf)), uintptr(unsafe.Pointer(basep)), 0, 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getdtablesize() (size int) {
+	r0, _, _ := Syscall(SYS_GETDTABLESIZE, 0, 0, 0)
+	size = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getegid() (egid int) {
+	r0, _, _ := RawSyscall(SYS_GETEGID, 0, 0, 0)
+	egid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Geteuid() (uid int) {
+	r0, _, _ := RawSyscall(SYS_GETEUID, 0, 0, 0)
+	uid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getgid() (gid int) {
+	r0, _, _ := RawSyscall(SYS_GETGID, 0, 0, 0)
+	gid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpgid(pid int) (pgid int, err error) {
+	r0, _, e1 := RawSyscall(SYS_GETPGID, uintptr(pid), 0, 0)
+	pgid = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpgrp() (pgrp int) {
+	r0, _, _ := RawSyscall(SYS_GETPGRP, 0, 0, 0)
+	pgrp = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpid() (pid int) {
+	r0, _, _ := RawSyscall(SYS_GETPID, 0, 0, 0)
+	pid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getppid() (ppid int) {
+	r0, _, _ := RawSyscall(SYS_GETPPID, 0, 0, 0)
+	ppid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpriority(which int, who int) (prio int, err error) {
+	r0, _, e1 := Syscall(SYS_GETPRIORITY, uintptr(which), uintptr(who), 0)
+	prio = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getrlimit(which int, lim *Rlimit) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getrusage(who int, rusage *Rusage) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETRUSAGE, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getsid(pid int) (sid int, err error) {
+	r0, _, e1 := RawSyscall(SYS_GETSID, uintptr(pid), 0, 0)
+	sid = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Gettimeofday(tv *Timeval) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getuid() (uid int) {
+	r0, _, _ := RawSyscall(SYS_GETUID, 0, 0, 0)
+	uid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Issetugid() (tainted bool) {
+	r0, _, _ := Syscall(SYS_ISSETUGID, 0, 0, 0)
+	tainted = bool(r0 != 0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Kill(pid int, signum Signal) (err error) {
+	_, _, e1 := Syscall(SYS_KILL, uintptr(pid), uintptr(signum), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Kqueue() (fd int, err error) {
+	r0, _, e1 := Syscall(SYS_KQUEUE, 0, 0, 0)
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Lchown(path string, uid int, gid int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_LCHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Link(path string, link string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(link)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_LINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	use(unsafe.Pointer(_p0))
+	use(unsafe.Pointer(_p1))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Listen(s int, backlog int) (err error) {
+	_, _, e1 := Syscall(SYS_LISTEN, uintptr(s), uintptr(backlog), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Lstat(path string, stat *Stat_t) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_LSTAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mkdir(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_MKDIR, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mkfifo(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_MKFIFO, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mknod(path string, mode uint32, dev int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_MKNOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Nanosleep(time *Timespec, leftover *Timespec) (err error) {
+	_, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Open(path string, mode int, perm uint32) (fd int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
+	use(unsafe.Pointer(_p0))
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pathconf(path string, name int) (val int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall(SYS_PATHCONF, uintptr(unsafe.Pointer(_p0)), uintptr(name), 0)
+	use(unsafe.Pointer(_p0))
+	val = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func read(fd int, p []byte) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(_p0), uintptr(len(p)))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Readlink(path string, buf []byte) (n int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 unsafe.Pointer
+	if len(buf) > 0 {
+		_p1 = unsafe.Pointer(&buf[0])
+	} else {
+		_p1 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_READLINK, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
+	use(unsafe.Pointer(_p0))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Rename(from string, to string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(from)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(to)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_RENAME, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	use(unsafe.Pointer(_p0))
+	use(unsafe.Pointer(_p1))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Revoke(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_REVOKE, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Rmdir(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_RMDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
+	r0, _, e1 := Syscall6(SYS_LSEEK, uintptr(fd), 0, uintptr(offset), uintptr(whence), 0, 0)
+	newoffset = int64(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Select(n int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (err error) {
+	_, _, e1 := Syscall6(SYS_SELECT, uintptr(n), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setegid(egid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETEGID, uintptr(egid), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Seteuid(euid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETEUID, uintptr(euid), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setgid(gid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETGID, uintptr(gid), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setlogin(name string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(name)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_SETLOGIN, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setpgid(pid int, pgid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETPGID, uintptr(pid), uintptr(pgid), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setpriority(which int, who int, prio int) (err error) {
+	_, _, e1 := Syscall(SYS_SETPRIORITY, uintptr(which), uintptr(who), uintptr(prio))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setregid(rgid int, egid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setreuid(ruid int, euid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setrlimit(which int, lim *Rlimit) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setsid() (pid int, err error) {
+	r0, _, e1 := RawSyscall(SYS_SETSID, 0, 0, 0)
+	pid = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Settimeofday(tp *Timeval) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETTIMEOFDAY, uintptr(unsafe.Pointer(tp)), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setuid(uid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETUID, uintptr(uid), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Stat(path string, stat *Stat_t) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Statfs(path string, stat *Statfs_t) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_STATFS, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Symlink(path string, link string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(link)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_SYMLINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	use(unsafe.Pointer(_p0))
+	use(unsafe.Pointer(_p1))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Sync() (err error) {
+	_, _, e1 := Syscall(SYS_SYNC, 0, 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Truncate(path string, length int64) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_TRUNCATE, uintptr(unsafe.Pointer(_p0)), 0, uintptr(length))
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Umask(newmask int) (oldmask int) {
+	r0, _, _ := Syscall(SYS_UMASK, uintptr(newmask), 0, 0)
+	oldmask = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Undelete(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UNDELETE, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Unlink(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UNLINK, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Unmount(path string, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UNMOUNT, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func write(fd int, p []byte) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) {
+	r0, _, e1 := Syscall9(SYS_MMAP, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), 0, uintptr(pos), 0, 0)
+	ret = uintptr(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func munmap(addr uintptr, length uintptr) (err error) {
+	_, _, e1 := Syscall(SYS_MUNMAP, uintptr(addr), uintptr(length), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func readlen(fd int, buf *byte, nbuf int) (n int, err error) {
+	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func writelen(fd int, buf *byte, nbuf int) (n int, err error) {
+	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
diff --git a/src/syscall/zsyscall_freebsd_386.go b/src/syscall/zsyscall_freebsd_386.go
new file mode 100644
index 0000000..c8c636f
--- /dev/null
+++ b/src/syscall/zsyscall_freebsd_386.go
@@ -0,0 +1,1328 @@
+// mksyscall.pl -l32 syscall_bsd.go syscall_freebsd.go syscall_freebsd_386.go
+// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
+
+package syscall
+
+import "unsafe"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getgroups(ngid int, gid *_Gid_t) (n int, err error) {
+	r0, _, e1 := RawSyscall(SYS_GETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func setgroups(ngid int, gid *_Gid_t) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) {
+	r0, _, e1 := Syscall6(SYS_WAIT4, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0)
+	wpid = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
+	r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
+	_, _, e1 := Syscall(SYS_BIND, uintptr(s), uintptr(addr), uintptr(addrlen))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
+	_, _, e1 := Syscall(SYS_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func socket(domain int, typ int, proto int) (fd int, err error) {
+	r0, _, e1 := RawSyscall(SYS_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto))
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) {
+	_, _, e1 := Syscall6(SYS_GETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) {
+	_, _, e1 := Syscall6(SYS_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETPEERNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETSOCKNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Shutdown(s int, how int) (err error) {
+	_, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(s), uintptr(how), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) {
+	_, _, e1 := RawSyscall6(SYS_SOCKETPAIR, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_RECVFROM, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) {
+	var _p0 unsafe.Pointer
+	if len(buf) > 0 {
+		_p0 = unsafe.Pointer(&buf[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall6(SYS_SENDTO, uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
+	r0, _, e1 := Syscall(SYS_RECVMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
+	r0, _, e1 := Syscall(SYS_SENDMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func kevent(kq int, change unsafe.Pointer, nchange int, event unsafe.Pointer, nevent int, timeout *Timespec) (n int, err error) {
+	r0, _, e1 := Syscall6(SYS_KEVENT, uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout)))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) {
+	var _p0 unsafe.Pointer
+	if len(mib) > 0 {
+		_p0 = unsafe.Pointer(&mib[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall6(SYS___SYSCTL, uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func utimes(path string, timeval *[2]Timeval) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(timeval)), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func futimes(fd int, timeval *[2]Timeval) (err error) {
+	_, _, e1 := Syscall(SYS_FUTIMES, uintptr(fd), uintptr(unsafe.Pointer(timeval)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func fcntl(fd int, cmd int, arg int) (val int, err error) {
+	r0, _, e1 := Syscall(SYS_FCNTL, uintptr(fd), uintptr(cmd), uintptr(arg))
+	val = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func pipe() (r int, w int, err error) {
+	r0, r1, e1 := RawSyscall(SYS_PIPE, 0, 0, 0)
+	r = int(r0)
+	w = int(r1)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Access(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_ACCESS, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Adjtime(delta *Timeval, olddelta *Timeval) (err error) {
+	_, _, e1 := Syscall(SYS_ADJTIME, uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chdir(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chflags(path string, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHFLAGS, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chmod(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHMOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chown(path string, uid int, gid int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chroot(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHROOT, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Close(fd int) (err error) {
+	_, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Dup(fd int) (nfd int, err error) {
+	r0, _, e1 := RawSyscall(SYS_DUP, uintptr(fd), 0, 0)
+	nfd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Dup2(from int, to int) (err error) {
+	_, _, e1 := RawSyscall(SYS_DUP2, uintptr(from), uintptr(to), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Exit(code int) {
+	Syscall(SYS_EXIT, uintptr(code), 0, 0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchdir(fd int) (err error) {
+	_, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchflags(fd int, flags int) (err error) {
+	_, _, e1 := Syscall(SYS_FCHFLAGS, uintptr(fd), uintptr(flags), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchmod(fd int, mode uint32) (err error) {
+	_, _, e1 := Syscall(SYS_FCHMOD, uintptr(fd), uintptr(mode), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchown(fd int, uid int, gid int) (err error) {
+	_, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Flock(fd int, how int) (err error) {
+	_, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fpathconf(fd int, name int) (val int, err error) {
+	r0, _, e1 := Syscall(SYS_FPATHCONF, uintptr(fd), uintptr(name), 0)
+	val = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fstat(fd int, stat *Stat_t) (err error) {
+	_, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fstatfs(fd int, stat *Statfs_t) (err error) {
+	_, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fsync(fd int) (err error) {
+	_, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Ftruncate(fd int, length int64) (err error) {
+	_, _, e1 := Syscall(SYS_FTRUNCATE, uintptr(fd), uintptr(length), uintptr(length>>32))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(buf) > 0 {
+		_p0 = unsafe.Pointer(&buf[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_GETDIRENTRIES, uintptr(fd), uintptr(_p0), uintptr(len(buf)), uintptr(unsafe.Pointer(basep)), 0, 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getdtablesize() (size int) {
+	r0, _, _ := Syscall(SYS_GETDTABLESIZE, 0, 0, 0)
+	size = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getegid() (egid int) {
+	r0, _, _ := RawSyscall(SYS_GETEGID, 0, 0, 0)
+	egid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Geteuid() (uid int) {
+	r0, _, _ := RawSyscall(SYS_GETEUID, 0, 0, 0)
+	uid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getgid() (gid int) {
+	r0, _, _ := RawSyscall(SYS_GETGID, 0, 0, 0)
+	gid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpgid(pid int) (pgid int, err error) {
+	r0, _, e1 := RawSyscall(SYS_GETPGID, uintptr(pid), 0, 0)
+	pgid = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpgrp() (pgrp int) {
+	r0, _, _ := RawSyscall(SYS_GETPGRP, 0, 0, 0)
+	pgrp = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpid() (pid int) {
+	r0, _, _ := RawSyscall(SYS_GETPID, 0, 0, 0)
+	pid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getppid() (ppid int) {
+	r0, _, _ := RawSyscall(SYS_GETPPID, 0, 0, 0)
+	ppid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpriority(which int, who int) (prio int, err error) {
+	r0, _, e1 := Syscall(SYS_GETPRIORITY, uintptr(which), uintptr(who), 0)
+	prio = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getrlimit(which int, lim *Rlimit) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getrusage(who int, rusage *Rusage) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETRUSAGE, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getsid(pid int) (sid int, err error) {
+	r0, _, e1 := RawSyscall(SYS_GETSID, uintptr(pid), 0, 0)
+	sid = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Gettimeofday(tv *Timeval) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getuid() (uid int) {
+	r0, _, _ := RawSyscall(SYS_GETUID, 0, 0, 0)
+	uid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Issetugid() (tainted bool) {
+	r0, _, _ := Syscall(SYS_ISSETUGID, 0, 0, 0)
+	tainted = bool(r0 != 0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Kill(pid int, signum Signal) (err error) {
+	_, _, e1 := Syscall(SYS_KILL, uintptr(pid), uintptr(signum), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Kqueue() (fd int, err error) {
+	r0, _, e1 := Syscall(SYS_KQUEUE, 0, 0, 0)
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Lchown(path string, uid int, gid int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_LCHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Link(path string, link string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(link)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_LINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	use(unsafe.Pointer(_p0))
+	use(unsafe.Pointer(_p1))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Listen(s int, backlog int) (err error) {
+	_, _, e1 := Syscall(SYS_LISTEN, uintptr(s), uintptr(backlog), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Lstat(path string, stat *Stat_t) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_LSTAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mkdir(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_MKDIR, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mkfifo(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_MKFIFO, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mknod(path string, mode uint32, dev int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_MKNOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Nanosleep(time *Timespec, leftover *Timespec) (err error) {
+	_, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Open(path string, mode int, perm uint32) (fd int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
+	use(unsafe.Pointer(_p0))
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pathconf(path string, name int) (val int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall(SYS_PATHCONF, uintptr(unsafe.Pointer(_p0)), uintptr(name), 0)
+	use(unsafe.Pointer(_p0))
+	val = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pread(fd int, p []byte, offset int64) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_PREAD, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), uintptr(offset>>32), 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_PWRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), uintptr(offset>>32), 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func read(fd int, p []byte) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(_p0), uintptr(len(p)))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Readlink(path string, buf []byte) (n int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 unsafe.Pointer
+	if len(buf) > 0 {
+		_p1 = unsafe.Pointer(&buf[0])
+	} else {
+		_p1 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_READLINK, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
+	use(unsafe.Pointer(_p0))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Rename(from string, to string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(from)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(to)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_RENAME, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	use(unsafe.Pointer(_p0))
+	use(unsafe.Pointer(_p1))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Revoke(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_REVOKE, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Rmdir(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_RMDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
+	r0, r1, e1 := Syscall6(SYS_LSEEK, uintptr(fd), uintptr(offset), uintptr(offset>>32), uintptr(whence), 0, 0)
+	newoffset = int64(int64(r1)<<32 | int64(r0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Select(n int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (err error) {
+	_, _, e1 := Syscall6(SYS_SELECT, uintptr(n), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setegid(egid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETEGID, uintptr(egid), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Seteuid(euid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETEUID, uintptr(euid), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setgid(gid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETGID, uintptr(gid), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setlogin(name string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(name)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_SETLOGIN, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setpgid(pid int, pgid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETPGID, uintptr(pid), uintptr(pgid), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setpriority(which int, who int, prio int) (err error) {
+	_, _, e1 := Syscall(SYS_SETPRIORITY, uintptr(which), uintptr(who), uintptr(prio))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setregid(rgid int, egid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setreuid(ruid int, euid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setrlimit(which int, lim *Rlimit) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setsid() (pid int, err error) {
+	r0, _, e1 := RawSyscall(SYS_SETSID, 0, 0, 0)
+	pid = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Settimeofday(tp *Timeval) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETTIMEOFDAY, uintptr(unsafe.Pointer(tp)), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setuid(uid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETUID, uintptr(uid), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Stat(path string, stat *Stat_t) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Statfs(path string, stat *Statfs_t) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_STATFS, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Symlink(path string, link string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(link)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_SYMLINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	use(unsafe.Pointer(_p0))
+	use(unsafe.Pointer(_p1))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Sync() (err error) {
+	_, _, e1 := Syscall(SYS_SYNC, 0, 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Truncate(path string, length int64) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_TRUNCATE, uintptr(unsafe.Pointer(_p0)), uintptr(length), uintptr(length>>32))
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Umask(newmask int) (oldmask int) {
+	r0, _, _ := Syscall(SYS_UMASK, uintptr(newmask), 0, 0)
+	oldmask = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Undelete(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UNDELETE, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Unlink(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UNLINK, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Unmount(path string, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UNMOUNT, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func write(fd int, p []byte) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) {
+	r0, _, e1 := Syscall9(SYS_MMAP, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), uintptr(pos), uintptr(pos>>32), 0, 0)
+	ret = uintptr(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func munmap(addr uintptr, length uintptr) (err error) {
+	_, _, e1 := Syscall(SYS_MUNMAP, uintptr(addr), uintptr(length), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func readlen(fd int, buf *byte, nbuf int) (n int, err error) {
+	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func writelen(fd int, buf *byte, nbuf int) (n int, err error) {
+	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func accept4(fd int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (nfd int, err error) {
+	r0, _, e1 := Syscall6(SYS_ACCEPT4, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0)
+	nfd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
diff --git a/src/syscall/zsyscall_freebsd_amd64.go b/src/syscall/zsyscall_freebsd_amd64.go
new file mode 100644
index 0000000..026b560
--- /dev/null
+++ b/src/syscall/zsyscall_freebsd_amd64.go
@@ -0,0 +1,1328 @@
+// mksyscall.pl syscall_bsd.go syscall_freebsd.go syscall_freebsd_amd64.go
+// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
+
+package syscall
+
+import "unsafe"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getgroups(ngid int, gid *_Gid_t) (n int, err error) {
+	r0, _, e1 := RawSyscall(SYS_GETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func setgroups(ngid int, gid *_Gid_t) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) {
+	r0, _, e1 := Syscall6(SYS_WAIT4, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0)
+	wpid = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
+	r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
+	_, _, e1 := Syscall(SYS_BIND, uintptr(s), uintptr(addr), uintptr(addrlen))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
+	_, _, e1 := Syscall(SYS_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func socket(domain int, typ int, proto int) (fd int, err error) {
+	r0, _, e1 := RawSyscall(SYS_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto))
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) {
+	_, _, e1 := Syscall6(SYS_GETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) {
+	_, _, e1 := Syscall6(SYS_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETPEERNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETSOCKNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Shutdown(s int, how int) (err error) {
+	_, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(s), uintptr(how), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) {
+	_, _, e1 := RawSyscall6(SYS_SOCKETPAIR, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_RECVFROM, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) {
+	var _p0 unsafe.Pointer
+	if len(buf) > 0 {
+		_p0 = unsafe.Pointer(&buf[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall6(SYS_SENDTO, uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
+	r0, _, e1 := Syscall(SYS_RECVMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
+	r0, _, e1 := Syscall(SYS_SENDMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func kevent(kq int, change unsafe.Pointer, nchange int, event unsafe.Pointer, nevent int, timeout *Timespec) (n int, err error) {
+	r0, _, e1 := Syscall6(SYS_KEVENT, uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout)))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) {
+	var _p0 unsafe.Pointer
+	if len(mib) > 0 {
+		_p0 = unsafe.Pointer(&mib[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall6(SYS___SYSCTL, uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func utimes(path string, timeval *[2]Timeval) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(timeval)), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func futimes(fd int, timeval *[2]Timeval) (err error) {
+	_, _, e1 := Syscall(SYS_FUTIMES, uintptr(fd), uintptr(unsafe.Pointer(timeval)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func fcntl(fd int, cmd int, arg int) (val int, err error) {
+	r0, _, e1 := Syscall(SYS_FCNTL, uintptr(fd), uintptr(cmd), uintptr(arg))
+	val = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func pipe() (r int, w int, err error) {
+	r0, r1, e1 := RawSyscall(SYS_PIPE, 0, 0, 0)
+	r = int(r0)
+	w = int(r1)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Access(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_ACCESS, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Adjtime(delta *Timeval, olddelta *Timeval) (err error) {
+	_, _, e1 := Syscall(SYS_ADJTIME, uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chdir(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chflags(path string, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHFLAGS, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chmod(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHMOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chown(path string, uid int, gid int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chroot(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHROOT, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Close(fd int) (err error) {
+	_, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Dup(fd int) (nfd int, err error) {
+	r0, _, e1 := RawSyscall(SYS_DUP, uintptr(fd), 0, 0)
+	nfd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Dup2(from int, to int) (err error) {
+	_, _, e1 := RawSyscall(SYS_DUP2, uintptr(from), uintptr(to), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Exit(code int) {
+	Syscall(SYS_EXIT, uintptr(code), 0, 0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchdir(fd int) (err error) {
+	_, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchflags(fd int, flags int) (err error) {
+	_, _, e1 := Syscall(SYS_FCHFLAGS, uintptr(fd), uintptr(flags), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchmod(fd int, mode uint32) (err error) {
+	_, _, e1 := Syscall(SYS_FCHMOD, uintptr(fd), uintptr(mode), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchown(fd int, uid int, gid int) (err error) {
+	_, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Flock(fd int, how int) (err error) {
+	_, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fpathconf(fd int, name int) (val int, err error) {
+	r0, _, e1 := Syscall(SYS_FPATHCONF, uintptr(fd), uintptr(name), 0)
+	val = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fstat(fd int, stat *Stat_t) (err error) {
+	_, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fstatfs(fd int, stat *Statfs_t) (err error) {
+	_, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fsync(fd int) (err error) {
+	_, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Ftruncate(fd int, length int64) (err error) {
+	_, _, e1 := Syscall(SYS_FTRUNCATE, uintptr(fd), uintptr(length), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(buf) > 0 {
+		_p0 = unsafe.Pointer(&buf[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_GETDIRENTRIES, uintptr(fd), uintptr(_p0), uintptr(len(buf)), uintptr(unsafe.Pointer(basep)), 0, 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getdtablesize() (size int) {
+	r0, _, _ := Syscall(SYS_GETDTABLESIZE, 0, 0, 0)
+	size = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getegid() (egid int) {
+	r0, _, _ := RawSyscall(SYS_GETEGID, 0, 0, 0)
+	egid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Geteuid() (uid int) {
+	r0, _, _ := RawSyscall(SYS_GETEUID, 0, 0, 0)
+	uid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getgid() (gid int) {
+	r0, _, _ := RawSyscall(SYS_GETGID, 0, 0, 0)
+	gid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpgid(pid int) (pgid int, err error) {
+	r0, _, e1 := RawSyscall(SYS_GETPGID, uintptr(pid), 0, 0)
+	pgid = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpgrp() (pgrp int) {
+	r0, _, _ := RawSyscall(SYS_GETPGRP, 0, 0, 0)
+	pgrp = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpid() (pid int) {
+	r0, _, _ := RawSyscall(SYS_GETPID, 0, 0, 0)
+	pid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getppid() (ppid int) {
+	r0, _, _ := RawSyscall(SYS_GETPPID, 0, 0, 0)
+	ppid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpriority(which int, who int) (prio int, err error) {
+	r0, _, e1 := Syscall(SYS_GETPRIORITY, uintptr(which), uintptr(who), 0)
+	prio = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getrlimit(which int, lim *Rlimit) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getrusage(who int, rusage *Rusage) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETRUSAGE, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getsid(pid int) (sid int, err error) {
+	r0, _, e1 := RawSyscall(SYS_GETSID, uintptr(pid), 0, 0)
+	sid = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Gettimeofday(tv *Timeval) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getuid() (uid int) {
+	r0, _, _ := RawSyscall(SYS_GETUID, 0, 0, 0)
+	uid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Issetugid() (tainted bool) {
+	r0, _, _ := Syscall(SYS_ISSETUGID, 0, 0, 0)
+	tainted = bool(r0 != 0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Kill(pid int, signum Signal) (err error) {
+	_, _, e1 := Syscall(SYS_KILL, uintptr(pid), uintptr(signum), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Kqueue() (fd int, err error) {
+	r0, _, e1 := Syscall(SYS_KQUEUE, 0, 0, 0)
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Lchown(path string, uid int, gid int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_LCHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Link(path string, link string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(link)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_LINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	use(unsafe.Pointer(_p0))
+	use(unsafe.Pointer(_p1))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Listen(s int, backlog int) (err error) {
+	_, _, e1 := Syscall(SYS_LISTEN, uintptr(s), uintptr(backlog), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Lstat(path string, stat *Stat_t) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_LSTAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mkdir(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_MKDIR, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mkfifo(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_MKFIFO, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mknod(path string, mode uint32, dev int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_MKNOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Nanosleep(time *Timespec, leftover *Timespec) (err error) {
+	_, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Open(path string, mode int, perm uint32) (fd int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
+	use(unsafe.Pointer(_p0))
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pathconf(path string, name int) (val int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall(SYS_PATHCONF, uintptr(unsafe.Pointer(_p0)), uintptr(name), 0)
+	use(unsafe.Pointer(_p0))
+	val = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pread(fd int, p []byte, offset int64) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_PREAD, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_PWRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func read(fd int, p []byte) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(_p0), uintptr(len(p)))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Readlink(path string, buf []byte) (n int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 unsafe.Pointer
+	if len(buf) > 0 {
+		_p1 = unsafe.Pointer(&buf[0])
+	} else {
+		_p1 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_READLINK, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
+	use(unsafe.Pointer(_p0))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Rename(from string, to string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(from)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(to)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_RENAME, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	use(unsafe.Pointer(_p0))
+	use(unsafe.Pointer(_p1))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Revoke(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_REVOKE, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Rmdir(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_RMDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
+	r0, _, e1 := Syscall(SYS_LSEEK, uintptr(fd), uintptr(offset), uintptr(whence))
+	newoffset = int64(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Select(n int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (err error) {
+	_, _, e1 := Syscall6(SYS_SELECT, uintptr(n), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setegid(egid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETEGID, uintptr(egid), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Seteuid(euid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETEUID, uintptr(euid), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setgid(gid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETGID, uintptr(gid), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setlogin(name string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(name)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_SETLOGIN, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setpgid(pid int, pgid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETPGID, uintptr(pid), uintptr(pgid), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setpriority(which int, who int, prio int) (err error) {
+	_, _, e1 := Syscall(SYS_SETPRIORITY, uintptr(which), uintptr(who), uintptr(prio))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setregid(rgid int, egid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setreuid(ruid int, euid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setrlimit(which int, lim *Rlimit) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setsid() (pid int, err error) {
+	r0, _, e1 := RawSyscall(SYS_SETSID, 0, 0, 0)
+	pid = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Settimeofday(tp *Timeval) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETTIMEOFDAY, uintptr(unsafe.Pointer(tp)), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setuid(uid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETUID, uintptr(uid), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Stat(path string, stat *Stat_t) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Statfs(path string, stat *Statfs_t) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_STATFS, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Symlink(path string, link string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(link)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_SYMLINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	use(unsafe.Pointer(_p0))
+	use(unsafe.Pointer(_p1))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Sync() (err error) {
+	_, _, e1 := Syscall(SYS_SYNC, 0, 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Truncate(path string, length int64) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_TRUNCATE, uintptr(unsafe.Pointer(_p0)), uintptr(length), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Umask(newmask int) (oldmask int) {
+	r0, _, _ := Syscall(SYS_UMASK, uintptr(newmask), 0, 0)
+	oldmask = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Undelete(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UNDELETE, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Unlink(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UNLINK, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Unmount(path string, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UNMOUNT, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func write(fd int, p []byte) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) {
+	r0, _, e1 := Syscall6(SYS_MMAP, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), uintptr(pos))
+	ret = uintptr(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func munmap(addr uintptr, length uintptr) (err error) {
+	_, _, e1 := Syscall(SYS_MUNMAP, uintptr(addr), uintptr(length), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func readlen(fd int, buf *byte, nbuf int) (n int, err error) {
+	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func writelen(fd int, buf *byte, nbuf int) (n int, err error) {
+	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func accept4(fd int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (nfd int, err error) {
+	r0, _, e1 := Syscall6(SYS_ACCEPT4, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0)
+	nfd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
diff --git a/src/syscall/zsyscall_freebsd_arm.go b/src/syscall/zsyscall_freebsd_arm.go
new file mode 100644
index 0000000..0c349cb
--- /dev/null
+++ b/src/syscall/zsyscall_freebsd_arm.go
@@ -0,0 +1,1328 @@
+// mksyscall.pl -l32 -arm syscall_bsd.go syscall_freebsd.go syscall_freebsd_arm.go
+// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
+
+package syscall
+
+import "unsafe"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getgroups(ngid int, gid *_Gid_t) (n int, err error) {
+	r0, _, e1 := RawSyscall(SYS_GETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func setgroups(ngid int, gid *_Gid_t) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) {
+	r0, _, e1 := Syscall6(SYS_WAIT4, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0)
+	wpid = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
+	r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
+	_, _, e1 := Syscall(SYS_BIND, uintptr(s), uintptr(addr), uintptr(addrlen))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
+	_, _, e1 := Syscall(SYS_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func socket(domain int, typ int, proto int) (fd int, err error) {
+	r0, _, e1 := RawSyscall(SYS_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto))
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) {
+	_, _, e1 := Syscall6(SYS_GETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) {
+	_, _, e1 := Syscall6(SYS_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETPEERNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETSOCKNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Shutdown(s int, how int) (err error) {
+	_, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(s), uintptr(how), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) {
+	_, _, e1 := RawSyscall6(SYS_SOCKETPAIR, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_RECVFROM, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) {
+	var _p0 unsafe.Pointer
+	if len(buf) > 0 {
+		_p0 = unsafe.Pointer(&buf[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall6(SYS_SENDTO, uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
+	r0, _, e1 := Syscall(SYS_RECVMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
+	r0, _, e1 := Syscall(SYS_SENDMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func kevent(kq int, change unsafe.Pointer, nchange int, event unsafe.Pointer, nevent int, timeout *Timespec) (n int, err error) {
+	r0, _, e1 := Syscall6(SYS_KEVENT, uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout)))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) {
+	var _p0 unsafe.Pointer
+	if len(mib) > 0 {
+		_p0 = unsafe.Pointer(&mib[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall6(SYS___SYSCTL, uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func utimes(path string, timeval *[2]Timeval) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(timeval)), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func futimes(fd int, timeval *[2]Timeval) (err error) {
+	_, _, e1 := Syscall(SYS_FUTIMES, uintptr(fd), uintptr(unsafe.Pointer(timeval)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func fcntl(fd int, cmd int, arg int) (val int, err error) {
+	r0, _, e1 := Syscall(SYS_FCNTL, uintptr(fd), uintptr(cmd), uintptr(arg))
+	val = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func pipe() (r int, w int, err error) {
+	r0, r1, e1 := RawSyscall(SYS_PIPE, 0, 0, 0)
+	r = int(r0)
+	w = int(r1)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Access(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_ACCESS, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Adjtime(delta *Timeval, olddelta *Timeval) (err error) {
+	_, _, e1 := Syscall(SYS_ADJTIME, uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chdir(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chflags(path string, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHFLAGS, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chmod(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHMOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chown(path string, uid int, gid int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chroot(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHROOT, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Close(fd int) (err error) {
+	_, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Dup(fd int) (nfd int, err error) {
+	r0, _, e1 := RawSyscall(SYS_DUP, uintptr(fd), 0, 0)
+	nfd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Dup2(from int, to int) (err error) {
+	_, _, e1 := RawSyscall(SYS_DUP2, uintptr(from), uintptr(to), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Exit(code int) {
+	Syscall(SYS_EXIT, uintptr(code), 0, 0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchdir(fd int) (err error) {
+	_, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchflags(fd int, flags int) (err error) {
+	_, _, e1 := Syscall(SYS_FCHFLAGS, uintptr(fd), uintptr(flags), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchmod(fd int, mode uint32) (err error) {
+	_, _, e1 := Syscall(SYS_FCHMOD, uintptr(fd), uintptr(mode), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchown(fd int, uid int, gid int) (err error) {
+	_, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Flock(fd int, how int) (err error) {
+	_, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fpathconf(fd int, name int) (val int, err error) {
+	r0, _, e1 := Syscall(SYS_FPATHCONF, uintptr(fd), uintptr(name), 0)
+	val = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fstat(fd int, stat *Stat_t) (err error) {
+	_, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fstatfs(fd int, stat *Statfs_t) (err error) {
+	_, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fsync(fd int) (err error) {
+	_, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Ftruncate(fd int, length int64) (err error) {
+	_, _, e1 := Syscall6(SYS_FTRUNCATE, uintptr(fd), 0, uintptr(length), uintptr(length>>32), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(buf) > 0 {
+		_p0 = unsafe.Pointer(&buf[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_GETDIRENTRIES, uintptr(fd), uintptr(_p0), uintptr(len(buf)), uintptr(unsafe.Pointer(basep)), 0, 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getdtablesize() (size int) {
+	r0, _, _ := Syscall(SYS_GETDTABLESIZE, 0, 0, 0)
+	size = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getegid() (egid int) {
+	r0, _, _ := RawSyscall(SYS_GETEGID, 0, 0, 0)
+	egid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Geteuid() (uid int) {
+	r0, _, _ := RawSyscall(SYS_GETEUID, 0, 0, 0)
+	uid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getgid() (gid int) {
+	r0, _, _ := RawSyscall(SYS_GETGID, 0, 0, 0)
+	gid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpgid(pid int) (pgid int, err error) {
+	r0, _, e1 := RawSyscall(SYS_GETPGID, uintptr(pid), 0, 0)
+	pgid = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpgrp() (pgrp int) {
+	r0, _, _ := RawSyscall(SYS_GETPGRP, 0, 0, 0)
+	pgrp = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpid() (pid int) {
+	r0, _, _ := RawSyscall(SYS_GETPID, 0, 0, 0)
+	pid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getppid() (ppid int) {
+	r0, _, _ := RawSyscall(SYS_GETPPID, 0, 0, 0)
+	ppid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpriority(which int, who int) (prio int, err error) {
+	r0, _, e1 := Syscall(SYS_GETPRIORITY, uintptr(which), uintptr(who), 0)
+	prio = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getrlimit(which int, lim *Rlimit) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getrusage(who int, rusage *Rusage) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETRUSAGE, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getsid(pid int) (sid int, err error) {
+	r0, _, e1 := RawSyscall(SYS_GETSID, uintptr(pid), 0, 0)
+	sid = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Gettimeofday(tv *Timeval) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getuid() (uid int) {
+	r0, _, _ := RawSyscall(SYS_GETUID, 0, 0, 0)
+	uid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Issetugid() (tainted bool) {
+	r0, _, _ := Syscall(SYS_ISSETUGID, 0, 0, 0)
+	tainted = bool(r0 != 0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Kill(pid int, signum Signal) (err error) {
+	_, _, e1 := Syscall(SYS_KILL, uintptr(pid), uintptr(signum), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Kqueue() (fd int, err error) {
+	r0, _, e1 := Syscall(SYS_KQUEUE, 0, 0, 0)
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Lchown(path string, uid int, gid int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_LCHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Link(path string, link string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(link)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_LINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	use(unsafe.Pointer(_p0))
+	use(unsafe.Pointer(_p1))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Listen(s int, backlog int) (err error) {
+	_, _, e1 := Syscall(SYS_LISTEN, uintptr(s), uintptr(backlog), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Lstat(path string, stat *Stat_t) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_LSTAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mkdir(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_MKDIR, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mkfifo(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_MKFIFO, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mknod(path string, mode uint32, dev int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_MKNOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Nanosleep(time *Timespec, leftover *Timespec) (err error) {
+	_, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Open(path string, mode int, perm uint32) (fd int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
+	use(unsafe.Pointer(_p0))
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pathconf(path string, name int) (val int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall(SYS_PATHCONF, uintptr(unsafe.Pointer(_p0)), uintptr(name), 0)
+	use(unsafe.Pointer(_p0))
+	val = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pread(fd int, p []byte, offset int64) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_PREAD, uintptr(fd), uintptr(_p0), uintptr(len(p)), 0, uintptr(offset), uintptr(offset>>32))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_PWRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)), 0, uintptr(offset), uintptr(offset>>32))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func read(fd int, p []byte) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(_p0), uintptr(len(p)))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Readlink(path string, buf []byte) (n int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 unsafe.Pointer
+	if len(buf) > 0 {
+		_p1 = unsafe.Pointer(&buf[0])
+	} else {
+		_p1 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_READLINK, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
+	use(unsafe.Pointer(_p0))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Rename(from string, to string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(from)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(to)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_RENAME, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	use(unsafe.Pointer(_p0))
+	use(unsafe.Pointer(_p1))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Revoke(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_REVOKE, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Rmdir(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_RMDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
+	r0, r1, e1 := Syscall6(SYS_LSEEK, uintptr(fd), 0, uintptr(offset), uintptr(offset>>32), uintptr(whence), 0)
+	newoffset = int64(int64(r1)<<32 | int64(r0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Select(n int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (err error) {
+	_, _, e1 := Syscall6(SYS_SELECT, uintptr(n), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setegid(egid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETEGID, uintptr(egid), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Seteuid(euid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETEUID, uintptr(euid), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setgid(gid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETGID, uintptr(gid), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setlogin(name string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(name)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_SETLOGIN, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setpgid(pid int, pgid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETPGID, uintptr(pid), uintptr(pgid), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setpriority(which int, who int, prio int) (err error) {
+	_, _, e1 := Syscall(SYS_SETPRIORITY, uintptr(which), uintptr(who), uintptr(prio))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setregid(rgid int, egid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setreuid(ruid int, euid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setrlimit(which int, lim *Rlimit) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setsid() (pid int, err error) {
+	r0, _, e1 := RawSyscall(SYS_SETSID, 0, 0, 0)
+	pid = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Settimeofday(tp *Timeval) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETTIMEOFDAY, uintptr(unsafe.Pointer(tp)), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setuid(uid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETUID, uintptr(uid), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Stat(path string, stat *Stat_t) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Statfs(path string, stat *Statfs_t) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_STATFS, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Symlink(path string, link string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(link)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_SYMLINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	use(unsafe.Pointer(_p0))
+	use(unsafe.Pointer(_p1))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Sync() (err error) {
+	_, _, e1 := Syscall(SYS_SYNC, 0, 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Truncate(path string, length int64) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_TRUNCATE, uintptr(unsafe.Pointer(_p0)), 0, uintptr(length), uintptr(length>>32), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Umask(newmask int) (oldmask int) {
+	r0, _, _ := Syscall(SYS_UMASK, uintptr(newmask), 0, 0)
+	oldmask = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Undelete(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UNDELETE, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Unlink(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UNLINK, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Unmount(path string, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UNMOUNT, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func write(fd int, p []byte) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) {
+	r0, _, e1 := Syscall9(SYS_MMAP, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), 0, uintptr(pos), uintptr(pos>>32), 0)
+	ret = uintptr(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func munmap(addr uintptr, length uintptr) (err error) {
+	_, _, e1 := Syscall(SYS_MUNMAP, uintptr(addr), uintptr(length), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func readlen(fd int, buf *byte, nbuf int) (n int, err error) {
+	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func writelen(fd int, buf *byte, nbuf int) (n int, err error) {
+	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func accept4(fd int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (nfd int, err error) {
+	r0, _, e1 := Syscall6(SYS_ACCEPT4, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0)
+	nfd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
diff --git a/src/syscall/zsyscall_linux_386.go b/src/syscall/zsyscall_linux_386.go
new file mode 100644
index 0000000..dee8343
--- /dev/null
+++ b/src/syscall/zsyscall_linux_386.go
@@ -0,0 +1,1767 @@
+// mksyscall.pl -l32 syscall_linux.go syscall_linux_386.go
+// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
+
+package syscall
+
+import "unsafe"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func open(path string, mode int, perm uint32) (fd int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
+	use(unsafe.Pointer(_p0))
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall6(SYS_OPENAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), uintptr(mode), 0, 0)
+	use(unsafe.Pointer(_p0))
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func pipe(p *[2]_C_int) (err error) {
+	_, _, e1 := RawSyscall(SYS_PIPE, uintptr(unsafe.Pointer(p)), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func pipe2(p *[2]_C_int, flags int) (err error) {
+	_, _, e1 := RawSyscall(SYS_PIPE2, uintptr(unsafe.Pointer(p)), uintptr(flags), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func utimes(path string, times *[2]Timeval) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func utimensat(dirfd int, path string, times *[2]Timespec) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)))
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func futimesat(dirfd int, path *byte, times *[2]Timeval) (err error) {
+	_, _, e1 := Syscall(SYS_FUTIMESAT, uintptr(dirfd), uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(times)))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getcwd(buf []byte) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(buf) > 0 {
+		_p0 = unsafe.Pointer(&buf[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_GETCWD, uintptr(_p0), uintptr(len(buf)), 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) {
+	r0, _, e1 := Syscall6(SYS_WAIT4, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0)
+	wpid = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func ptrace(request int, pid int, addr uintptr, data uintptr) (err error) {
+	_, _, e1 := Syscall6(SYS_PTRACE, uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func reboot(magic1 uint, magic2 uint, cmd int, arg string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(arg)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_REBOOT, uintptr(magic1), uintptr(magic2), uintptr(cmd), uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func mount(source string, target string, fstype string, flags uintptr, data *byte) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(source)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(target)
+	if err != nil {
+		return
+	}
+	var _p2 *byte
+	_p2, err = BytePtrFromString(fstype)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_MOUNT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(unsafe.Pointer(_p2)), uintptr(flags), uintptr(unsafe.Pointer(data)), 0)
+	use(unsafe.Pointer(_p0))
+	use(unsafe.Pointer(_p1))
+	use(unsafe.Pointer(_p2))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Access(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_ACCESS, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Acct(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_ACCT, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Adjtimex(buf *Timex) (state int, err error) {
+	r0, _, e1 := Syscall(SYS_ADJTIMEX, uintptr(unsafe.Pointer(buf)), 0, 0)
+	state = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chdir(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chmod(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHMOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chroot(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHROOT, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Close(fd int) (err error) {
+	_, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Creat(path string, mode uint32) (fd int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall(SYS_CREAT, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	use(unsafe.Pointer(_p0))
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Dup(oldfd int) (fd int, err error) {
+	r0, _, e1 := RawSyscall(SYS_DUP, uintptr(oldfd), 0, 0)
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Dup2(oldfd int, newfd int) (err error) {
+	_, _, e1 := RawSyscall(SYS_DUP2, uintptr(oldfd), uintptr(newfd), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Dup3(oldfd int, newfd int, flags int) (err error) {
+	_, _, e1 := RawSyscall(SYS_DUP3, uintptr(oldfd), uintptr(newfd), uintptr(flags))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func EpollCreate(size int) (fd int, err error) {
+	r0, _, e1 := RawSyscall(SYS_EPOLL_CREATE, uintptr(size), 0, 0)
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func EpollCreate1(flag int) (fd int, err error) {
+	r0, _, e1 := RawSyscall(SYS_EPOLL_CREATE1, uintptr(flag), 0, 0)
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error) {
+	_, _, e1 := RawSyscall6(SYS_EPOLL_CTL, uintptr(epfd), uintptr(op), uintptr(fd), uintptr(unsafe.Pointer(event)), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(events) > 0 {
+		_p0 = unsafe.Pointer(&events[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_EPOLL_WAIT, uintptr(epfd), uintptr(_p0), uintptr(len(events)), uintptr(msec), 0, 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Exit(code int) {
+	Syscall(SYS_EXIT_GROUP, uintptr(code), 0, 0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_FACCESSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fallocate(fd int, mode uint32, off int64, len int64) (err error) {
+	_, _, e1 := Syscall6(SYS_FALLOCATE, uintptr(fd), uintptr(mode), uintptr(off), uintptr(off>>32), uintptr(len), uintptr(len>>32))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchdir(fd int) (err error) {
+	_, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchmod(fd int, mode uint32) (err error) {
+	_, _, e1 := Syscall(SYS_FCHMOD, uintptr(fd), uintptr(mode), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_FCHMODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_FCHOWNAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid), uintptr(flags), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func fcntl(fd int, cmd int, arg int) (val int, err error) {
+	r0, _, e1 := Syscall(SYS_FCNTL, uintptr(fd), uintptr(cmd), uintptr(arg))
+	val = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fdatasync(fd int) (err error) {
+	_, _, e1 := Syscall(SYS_FDATASYNC, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Flock(fd int, how int) (err error) {
+	_, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fsync(fd int) (err error) {
+	_, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getdents(fd int, buf []byte) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(buf) > 0 {
+		_p0 = unsafe.Pointer(&buf[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_GETDENTS64, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpgid(pid int) (pgid int, err error) {
+	r0, _, e1 := RawSyscall(SYS_GETPGID, uintptr(pid), 0, 0)
+	pgid = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpgrp() (pid int) {
+	r0, _, _ := RawSyscall(SYS_GETPGRP, 0, 0, 0)
+	pid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpid() (pid int) {
+	r0, _, _ := RawSyscall(SYS_GETPID, 0, 0, 0)
+	pid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getppid() (ppid int) {
+	r0, _, _ := RawSyscall(SYS_GETPPID, 0, 0, 0)
+	ppid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpriority(which int, who int) (prio int, err error) {
+	r0, _, e1 := Syscall(SYS_GETPRIORITY, uintptr(which), uintptr(who), 0)
+	prio = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getrusage(who int, rusage *Rusage) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETRUSAGE, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Gettid() (tid int) {
+	r0, _, _ := RawSyscall(SYS_GETTID, 0, 0, 0)
+	tid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getxattr(path string, attr string, dest []byte) (sz int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(attr)
+	if err != nil {
+		return
+	}
+	var _p2 unsafe.Pointer
+	if len(dest) > 0 {
+		_p2 = unsafe.Pointer(&dest[0])
+	} else {
+		_p2 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_GETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(_p2), uintptr(len(dest)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	use(unsafe.Pointer(_p1))
+	sz = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func InotifyAddWatch(fd int, pathname string, mask uint32) (watchdesc int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(pathname)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall(SYS_INOTIFY_ADD_WATCH, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(mask))
+	use(unsafe.Pointer(_p0))
+	watchdesc = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func InotifyInit() (fd int, err error) {
+	r0, _, e1 := RawSyscall(SYS_INOTIFY_INIT, 0, 0, 0)
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func InotifyInit1(flags int) (fd int, err error) {
+	r0, _, e1 := RawSyscall(SYS_INOTIFY_INIT1, uintptr(flags), 0, 0)
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func InotifyRmWatch(fd int, watchdesc uint32) (success int, err error) {
+	r0, _, e1 := RawSyscall(SYS_INOTIFY_RM_WATCH, uintptr(fd), uintptr(watchdesc), 0)
+	success = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Kill(pid int, sig Signal) (err error) {
+	_, _, e1 := RawSyscall(SYS_KILL, uintptr(pid), uintptr(sig), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Klogctl(typ int, buf []byte) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(buf) > 0 {
+		_p0 = unsafe.Pointer(&buf[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_SYSLOG, uintptr(typ), uintptr(_p0), uintptr(len(buf)))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Link(oldpath string, newpath string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(oldpath)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(newpath)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_LINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	use(unsafe.Pointer(_p0))
+	use(unsafe.Pointer(_p1))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Listxattr(path string, dest []byte) (sz int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 unsafe.Pointer
+	if len(dest) > 0 {
+		_p1 = unsafe.Pointer(&dest[0])
+	} else {
+		_p1 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_LISTXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(dest)))
+	use(unsafe.Pointer(_p0))
+	sz = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mkdir(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_MKDIR, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mkdirat(dirfd int, path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_MKDIRAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode))
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mknod(path string, mode uint32, dev int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_MKNOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mknodat(dirfd int, path string, mode uint32, dev int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_MKNODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Nanosleep(time *Timespec, leftover *Timespec) (err error) {
+	_, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pause() (err error) {
+	_, _, e1 := Syscall(SYS_PAUSE, 0, 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func PivotRoot(newroot string, putold string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(newroot)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(putold)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_PIVOT_ROOT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	use(unsafe.Pointer(_p0))
+	use(unsafe.Pointer(_p1))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func prlimit(pid int, resource int, old *Rlimit, newlimit *Rlimit) (err error) {
+	_, _, e1 := RawSyscall6(SYS_PRLIMIT64, uintptr(pid), uintptr(resource), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(newlimit)), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func read(fd int, p []byte) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(_p0), uintptr(len(p)))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Readlink(path string, buf []byte) (n int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 unsafe.Pointer
+	if len(buf) > 0 {
+		_p1 = unsafe.Pointer(&buf[0])
+	} else {
+		_p1 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_READLINK, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
+	use(unsafe.Pointer(_p0))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Removexattr(path string, attr string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(attr)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_REMOVEXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	use(unsafe.Pointer(_p0))
+	use(unsafe.Pointer(_p1))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Rename(oldpath string, newpath string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(oldpath)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(newpath)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_RENAME, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	use(unsafe.Pointer(_p0))
+	use(unsafe.Pointer(_p1))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(oldpath)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(newpath)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_RENAMEAT, uintptr(olddirfd), uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	use(unsafe.Pointer(_p1))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Rmdir(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_RMDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setdomainname(p []byte) (err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_SETDOMAINNAME, uintptr(_p0), uintptr(len(p)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Sethostname(p []byte) (err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_SETHOSTNAME, uintptr(_p0), uintptr(len(p)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setpgid(pid int, pgid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETPGID, uintptr(pid), uintptr(pgid), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setsid() (pid int, err error) {
+	r0, _, e1 := RawSyscall(SYS_SETSID, 0, 0, 0)
+	pid = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Settimeofday(tv *Timeval) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setpriority(which int, who int, prio int) (err error) {
+	_, _, e1 := Syscall(SYS_SETPRIORITY, uintptr(which), uintptr(who), uintptr(prio))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setxattr(path string, attr string, data []byte, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(attr)
+	if err != nil {
+		return
+	}
+	var _p2 unsafe.Pointer
+	if len(data) > 0 {
+		_p2 = unsafe.Pointer(&data[0])
+	} else {
+		_p2 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall6(SYS_SETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(_p2), uintptr(len(data)), uintptr(flags), 0)
+	use(unsafe.Pointer(_p0))
+	use(unsafe.Pointer(_p1))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Symlink(oldpath string, newpath string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(oldpath)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(newpath)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_SYMLINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	use(unsafe.Pointer(_p0))
+	use(unsafe.Pointer(_p1))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Sync() {
+	Syscall(SYS_SYNC, 0, 0, 0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Sysinfo(info *Sysinfo_t) (err error) {
+	_, _, e1 := RawSyscall(SYS_SYSINFO, uintptr(unsafe.Pointer(info)), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Tee(rfd int, wfd int, len int, flags int) (n int64, err error) {
+	r0, r1, e1 := Syscall6(SYS_TEE, uintptr(rfd), uintptr(wfd), uintptr(len), uintptr(flags), 0, 0)
+	n = int64(int64(r1)<<32 | int64(r0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Tgkill(tgid int, tid int, sig Signal) (err error) {
+	_, _, e1 := RawSyscall(SYS_TGKILL, uintptr(tgid), uintptr(tid), uintptr(sig))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Times(tms *Tms) (ticks uintptr, err error) {
+	r0, _, e1 := RawSyscall(SYS_TIMES, uintptr(unsafe.Pointer(tms)), 0, 0)
+	ticks = uintptr(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Umask(mask int) (oldmask int) {
+	r0, _, _ := RawSyscall(SYS_UMASK, uintptr(mask), 0, 0)
+	oldmask = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Uname(buf *Utsname) (err error) {
+	_, _, e1 := RawSyscall(SYS_UNAME, uintptr(unsafe.Pointer(buf)), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Unlink(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UNLINK, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Unlinkat(dirfd int, path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UNLINKAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Unmount(target string, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(target)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UMOUNT2, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Unshare(flags int) (err error) {
+	_, _, e1 := Syscall(SYS_UNSHARE, uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Ustat(dev int, ubuf *Ustat_t) (err error) {
+	_, _, e1 := Syscall(SYS_USTAT, uintptr(dev), uintptr(unsafe.Pointer(ubuf)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Utime(path string, buf *Utimbuf) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UTIME, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(buf)), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func write(fd int, p []byte) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func exitThread(code int) (err error) {
+	_, _, e1 := Syscall(SYS_EXIT, uintptr(code), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func readlen(fd int, p *byte, np int) (n int, err error) {
+	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(p)), uintptr(np))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func writelen(fd int, p *byte, np int) (n int, err error) {
+	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(p)), uintptr(np))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func munmap(addr uintptr, length uintptr) (err error) {
+	_, _, e1 := Syscall(SYS_MUNMAP, uintptr(addr), uintptr(length), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Madvise(b []byte, advice int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MADVISE, uintptr(_p0), uintptr(len(b)), uintptr(advice))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mprotect(b []byte, prot int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mlock(b []byte) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Munlock(b []byte) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mlockall(flags int) (err error) {
+	_, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Munlockall() (err error) {
+	_, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chown(path string, uid int, gid int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHOWN32, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchown(fd int, uid int, gid int) (err error) {
+	_, _, e1 := Syscall(SYS_FCHOWN32, uintptr(fd), uintptr(uid), uintptr(gid))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fstat(fd int, stat *Stat_t) (err error) {
+	_, _, e1 := Syscall(SYS_FSTAT64, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Ftruncate(fd int, length int64) (err error) {
+	_, _, e1 := Syscall(SYS_FTRUNCATE64, uintptr(fd), uintptr(length), uintptr(length>>32))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getegid() (egid int) {
+	r0, _, _ := RawSyscall(SYS_GETEGID32, 0, 0, 0)
+	egid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Geteuid() (euid int) {
+	r0, _, _ := RawSyscall(SYS_GETEUID32, 0, 0, 0)
+	euid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getgid() (gid int) {
+	r0, _, _ := RawSyscall(SYS_GETGID32, 0, 0, 0)
+	gid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getuid() (uid int) {
+	r0, _, _ := RawSyscall(SYS_GETUID32, 0, 0, 0)
+	uid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Ioperm(from int, num int, on int) (err error) {
+	_, _, e1 := Syscall(SYS_IOPERM, uintptr(from), uintptr(num), uintptr(on))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Iopl(level int) (err error) {
+	_, _, e1 := Syscall(SYS_IOPL, uintptr(level), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Lchown(path string, uid int, gid int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_LCHOWN32, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Lstat(path string, stat *Stat_t) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_LSTAT64, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pread(fd int, p []byte, offset int64) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_PREAD64, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), uintptr(offset>>32), 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_PWRITE64, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), uintptr(offset>>32), 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
+	r0, _, e1 := Syscall6(SYS_SENDFILE64, uintptr(outfd), uintptr(infd), uintptr(unsafe.Pointer(offset)), uintptr(count), 0, 0)
+	written = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setfsgid(gid int) (err error) {
+	_, _, e1 := Syscall(SYS_SETFSGID32, uintptr(gid), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setfsuid(uid int) (err error) {
+	_, _, e1 := Syscall(SYS_SETFSUID32, uintptr(uid), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setregid(rgid int, egid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETREGID32, uintptr(rgid), uintptr(egid), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setresgid(rgid int, egid int, sgid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETRESGID32, uintptr(rgid), uintptr(egid), uintptr(sgid))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setresuid(ruid int, euid int, suid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETRESUID32, uintptr(ruid), uintptr(euid), uintptr(suid))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setreuid(ruid int, euid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETREUID32, uintptr(ruid), uintptr(euid), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error) {
+	r0, _, e1 := Syscall6(SYS_SPLICE, uintptr(rfd), uintptr(unsafe.Pointer(roff)), uintptr(wfd), uintptr(unsafe.Pointer(woff)), uintptr(len), uintptr(flags))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Stat(path string, stat *Stat_t) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_STAT64, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func SyncFileRange(fd int, off int64, n int64, flags int) (err error) {
+	_, _, e1 := Syscall6(SYS_SYNC_FILE_RANGE, uintptr(fd), uintptr(off), uintptr(off>>32), uintptr(n), uintptr(n>>32), uintptr(flags))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Truncate(path string, length int64) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_TRUNCATE64, uintptr(unsafe.Pointer(_p0)), uintptr(length), uintptr(length>>32))
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getgroups(n int, list *_Gid_t) (nn int, err error) {
+	r0, _, e1 := RawSyscall(SYS_GETGROUPS32, uintptr(n), uintptr(unsafe.Pointer(list)), 0)
+	nn = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func setgroups(n int, list *_Gid_t) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETGROUPS32, uintptr(n), uintptr(unsafe.Pointer(list)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) {
+	r0, _, e1 := Syscall6(SYS__NEWSELECT, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func mmap2(addr uintptr, length uintptr, prot int, flags int, fd int, pageOffset uintptr) (xaddr uintptr, err error) {
+	r0, _, e1 := Syscall6(SYS_MMAP2, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flags), uintptr(fd), uintptr(pageOffset))
+	xaddr = uintptr(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getrlimit(resource int, rlim *rlimit32) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETRLIMIT, uintptr(resource), uintptr(unsafe.Pointer(rlim)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func setrlimit(resource int, rlim *rlimit32) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(resource), uintptr(unsafe.Pointer(rlim)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Gettimeofday(tv *Timeval) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Time(t *Time_t) (tt Time_t, err error) {
+	r0, _, e1 := RawSyscall(SYS_TIME, uintptr(unsafe.Pointer(t)), 0, 0)
+	tt = Time_t(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
diff --git a/src/syscall/zsyscall_linux_amd64.go b/src/syscall/zsyscall_linux_amd64.go
new file mode 100644
index 0000000..ed3afd4
--- /dev/null
+++ b/src/syscall/zsyscall_linux_amd64.go
@@ -0,0 +1,1961 @@
+// mksyscall.pl syscall_linux.go syscall_linux_amd64.go
+// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
+
+package syscall
+
+import "unsafe"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func open(path string, mode int, perm uint32) (fd int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
+	use(unsafe.Pointer(_p0))
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall6(SYS_OPENAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), uintptr(mode), 0, 0)
+	use(unsafe.Pointer(_p0))
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func pipe(p *[2]_C_int) (err error) {
+	_, _, e1 := RawSyscall(SYS_PIPE, uintptr(unsafe.Pointer(p)), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func pipe2(p *[2]_C_int, flags int) (err error) {
+	_, _, e1 := RawSyscall(SYS_PIPE2, uintptr(unsafe.Pointer(p)), uintptr(flags), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func utimes(path string, times *[2]Timeval) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func utimensat(dirfd int, path string, times *[2]Timespec) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)))
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func futimesat(dirfd int, path *byte, times *[2]Timeval) (err error) {
+	_, _, e1 := Syscall(SYS_FUTIMESAT, uintptr(dirfd), uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(times)))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getcwd(buf []byte) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(buf) > 0 {
+		_p0 = unsafe.Pointer(&buf[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_GETCWD, uintptr(_p0), uintptr(len(buf)), 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) {
+	r0, _, e1 := Syscall6(SYS_WAIT4, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0)
+	wpid = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func ptrace(request int, pid int, addr uintptr, data uintptr) (err error) {
+	_, _, e1 := Syscall6(SYS_PTRACE, uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func reboot(magic1 uint, magic2 uint, cmd int, arg string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(arg)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_REBOOT, uintptr(magic1), uintptr(magic2), uintptr(cmd), uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func mount(source string, target string, fstype string, flags uintptr, data *byte) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(source)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(target)
+	if err != nil {
+		return
+	}
+	var _p2 *byte
+	_p2, err = BytePtrFromString(fstype)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_MOUNT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(unsafe.Pointer(_p2)), uintptr(flags), uintptr(unsafe.Pointer(data)), 0)
+	use(unsafe.Pointer(_p0))
+	use(unsafe.Pointer(_p1))
+	use(unsafe.Pointer(_p2))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Access(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_ACCESS, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Acct(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_ACCT, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Adjtimex(buf *Timex) (state int, err error) {
+	r0, _, e1 := Syscall(SYS_ADJTIMEX, uintptr(unsafe.Pointer(buf)), 0, 0)
+	state = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chdir(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chmod(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHMOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chroot(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHROOT, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Close(fd int) (err error) {
+	_, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Creat(path string, mode uint32) (fd int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall(SYS_CREAT, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	use(unsafe.Pointer(_p0))
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Dup(oldfd int) (fd int, err error) {
+	r0, _, e1 := RawSyscall(SYS_DUP, uintptr(oldfd), 0, 0)
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Dup2(oldfd int, newfd int) (err error) {
+	_, _, e1 := RawSyscall(SYS_DUP2, uintptr(oldfd), uintptr(newfd), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Dup3(oldfd int, newfd int, flags int) (err error) {
+	_, _, e1 := RawSyscall(SYS_DUP3, uintptr(oldfd), uintptr(newfd), uintptr(flags))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func EpollCreate(size int) (fd int, err error) {
+	r0, _, e1 := RawSyscall(SYS_EPOLL_CREATE, uintptr(size), 0, 0)
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func EpollCreate1(flag int) (fd int, err error) {
+	r0, _, e1 := RawSyscall(SYS_EPOLL_CREATE1, uintptr(flag), 0, 0)
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error) {
+	_, _, e1 := RawSyscall6(SYS_EPOLL_CTL, uintptr(epfd), uintptr(op), uintptr(fd), uintptr(unsafe.Pointer(event)), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(events) > 0 {
+		_p0 = unsafe.Pointer(&events[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_EPOLL_WAIT, uintptr(epfd), uintptr(_p0), uintptr(len(events)), uintptr(msec), 0, 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Exit(code int) {
+	Syscall(SYS_EXIT_GROUP, uintptr(code), 0, 0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_FACCESSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fallocate(fd int, mode uint32, off int64, len int64) (err error) {
+	_, _, e1 := Syscall6(SYS_FALLOCATE, uintptr(fd), uintptr(mode), uintptr(off), uintptr(len), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchdir(fd int) (err error) {
+	_, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchmod(fd int, mode uint32) (err error) {
+	_, _, e1 := Syscall(SYS_FCHMOD, uintptr(fd), uintptr(mode), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_FCHMODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_FCHOWNAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid), uintptr(flags), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func fcntl(fd int, cmd int, arg int) (val int, err error) {
+	r0, _, e1 := Syscall(SYS_FCNTL, uintptr(fd), uintptr(cmd), uintptr(arg))
+	val = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fdatasync(fd int) (err error) {
+	_, _, e1 := Syscall(SYS_FDATASYNC, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Flock(fd int, how int) (err error) {
+	_, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fsync(fd int) (err error) {
+	_, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getdents(fd int, buf []byte) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(buf) > 0 {
+		_p0 = unsafe.Pointer(&buf[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_GETDENTS64, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpgid(pid int) (pgid int, err error) {
+	r0, _, e1 := RawSyscall(SYS_GETPGID, uintptr(pid), 0, 0)
+	pgid = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpgrp() (pid int) {
+	r0, _, _ := RawSyscall(SYS_GETPGRP, 0, 0, 0)
+	pid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpid() (pid int) {
+	r0, _, _ := RawSyscall(SYS_GETPID, 0, 0, 0)
+	pid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getppid() (ppid int) {
+	r0, _, _ := RawSyscall(SYS_GETPPID, 0, 0, 0)
+	ppid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpriority(which int, who int) (prio int, err error) {
+	r0, _, e1 := Syscall(SYS_GETPRIORITY, uintptr(which), uintptr(who), 0)
+	prio = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getrusage(who int, rusage *Rusage) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETRUSAGE, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Gettid() (tid int) {
+	r0, _, _ := RawSyscall(SYS_GETTID, 0, 0, 0)
+	tid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getxattr(path string, attr string, dest []byte) (sz int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(attr)
+	if err != nil {
+		return
+	}
+	var _p2 unsafe.Pointer
+	if len(dest) > 0 {
+		_p2 = unsafe.Pointer(&dest[0])
+	} else {
+		_p2 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_GETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(_p2), uintptr(len(dest)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	use(unsafe.Pointer(_p1))
+	sz = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func InotifyAddWatch(fd int, pathname string, mask uint32) (watchdesc int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(pathname)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall(SYS_INOTIFY_ADD_WATCH, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(mask))
+	use(unsafe.Pointer(_p0))
+	watchdesc = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func InotifyInit() (fd int, err error) {
+	r0, _, e1 := RawSyscall(SYS_INOTIFY_INIT, 0, 0, 0)
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func InotifyInit1(flags int) (fd int, err error) {
+	r0, _, e1 := RawSyscall(SYS_INOTIFY_INIT1, uintptr(flags), 0, 0)
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func InotifyRmWatch(fd int, watchdesc uint32) (success int, err error) {
+	r0, _, e1 := RawSyscall(SYS_INOTIFY_RM_WATCH, uintptr(fd), uintptr(watchdesc), 0)
+	success = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Kill(pid int, sig Signal) (err error) {
+	_, _, e1 := RawSyscall(SYS_KILL, uintptr(pid), uintptr(sig), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Klogctl(typ int, buf []byte) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(buf) > 0 {
+		_p0 = unsafe.Pointer(&buf[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_SYSLOG, uintptr(typ), uintptr(_p0), uintptr(len(buf)))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Link(oldpath string, newpath string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(oldpath)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(newpath)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_LINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	use(unsafe.Pointer(_p0))
+	use(unsafe.Pointer(_p1))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Listxattr(path string, dest []byte) (sz int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 unsafe.Pointer
+	if len(dest) > 0 {
+		_p1 = unsafe.Pointer(&dest[0])
+	} else {
+		_p1 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_LISTXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(dest)))
+	use(unsafe.Pointer(_p0))
+	sz = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mkdir(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_MKDIR, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mkdirat(dirfd int, path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_MKDIRAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode))
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mknod(path string, mode uint32, dev int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_MKNOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mknodat(dirfd int, path string, mode uint32, dev int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_MKNODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Nanosleep(time *Timespec, leftover *Timespec) (err error) {
+	_, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pause() (err error) {
+	_, _, e1 := Syscall(SYS_PAUSE, 0, 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func PivotRoot(newroot string, putold string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(newroot)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(putold)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_PIVOT_ROOT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	use(unsafe.Pointer(_p0))
+	use(unsafe.Pointer(_p1))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func prlimit(pid int, resource int, old *Rlimit, newlimit *Rlimit) (err error) {
+	_, _, e1 := RawSyscall6(SYS_PRLIMIT64, uintptr(pid), uintptr(resource), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(newlimit)), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func read(fd int, p []byte) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(_p0), uintptr(len(p)))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Readlink(path string, buf []byte) (n int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 unsafe.Pointer
+	if len(buf) > 0 {
+		_p1 = unsafe.Pointer(&buf[0])
+	} else {
+		_p1 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_READLINK, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
+	use(unsafe.Pointer(_p0))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Removexattr(path string, attr string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(attr)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_REMOVEXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	use(unsafe.Pointer(_p0))
+	use(unsafe.Pointer(_p1))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Rename(oldpath string, newpath string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(oldpath)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(newpath)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_RENAME, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	use(unsafe.Pointer(_p0))
+	use(unsafe.Pointer(_p1))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(oldpath)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(newpath)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_RENAMEAT, uintptr(olddirfd), uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	use(unsafe.Pointer(_p1))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Rmdir(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_RMDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setdomainname(p []byte) (err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_SETDOMAINNAME, uintptr(_p0), uintptr(len(p)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Sethostname(p []byte) (err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_SETHOSTNAME, uintptr(_p0), uintptr(len(p)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setpgid(pid int, pgid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETPGID, uintptr(pid), uintptr(pgid), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setsid() (pid int, err error) {
+	r0, _, e1 := RawSyscall(SYS_SETSID, 0, 0, 0)
+	pid = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Settimeofday(tv *Timeval) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setpriority(which int, who int, prio int) (err error) {
+	_, _, e1 := Syscall(SYS_SETPRIORITY, uintptr(which), uintptr(who), uintptr(prio))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setxattr(path string, attr string, data []byte, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(attr)
+	if err != nil {
+		return
+	}
+	var _p2 unsafe.Pointer
+	if len(data) > 0 {
+		_p2 = unsafe.Pointer(&data[0])
+	} else {
+		_p2 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall6(SYS_SETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(_p2), uintptr(len(data)), uintptr(flags), 0)
+	use(unsafe.Pointer(_p0))
+	use(unsafe.Pointer(_p1))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Symlink(oldpath string, newpath string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(oldpath)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(newpath)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_SYMLINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	use(unsafe.Pointer(_p0))
+	use(unsafe.Pointer(_p1))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Sync() {
+	Syscall(SYS_SYNC, 0, 0, 0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Sysinfo(info *Sysinfo_t) (err error) {
+	_, _, e1 := RawSyscall(SYS_SYSINFO, uintptr(unsafe.Pointer(info)), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Tee(rfd int, wfd int, len int, flags int) (n int64, err error) {
+	r0, _, e1 := Syscall6(SYS_TEE, uintptr(rfd), uintptr(wfd), uintptr(len), uintptr(flags), 0, 0)
+	n = int64(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Tgkill(tgid int, tid int, sig Signal) (err error) {
+	_, _, e1 := RawSyscall(SYS_TGKILL, uintptr(tgid), uintptr(tid), uintptr(sig))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Times(tms *Tms) (ticks uintptr, err error) {
+	r0, _, e1 := RawSyscall(SYS_TIMES, uintptr(unsafe.Pointer(tms)), 0, 0)
+	ticks = uintptr(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Umask(mask int) (oldmask int) {
+	r0, _, _ := RawSyscall(SYS_UMASK, uintptr(mask), 0, 0)
+	oldmask = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Uname(buf *Utsname) (err error) {
+	_, _, e1 := RawSyscall(SYS_UNAME, uintptr(unsafe.Pointer(buf)), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Unlink(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UNLINK, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Unlinkat(dirfd int, path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UNLINKAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Unmount(target string, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(target)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UMOUNT2, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Unshare(flags int) (err error) {
+	_, _, e1 := Syscall(SYS_UNSHARE, uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Ustat(dev int, ubuf *Ustat_t) (err error) {
+	_, _, e1 := Syscall(SYS_USTAT, uintptr(dev), uintptr(unsafe.Pointer(ubuf)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Utime(path string, buf *Utimbuf) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UTIME, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(buf)), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func write(fd int, p []byte) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func exitThread(code int) (err error) {
+	_, _, e1 := Syscall(SYS_EXIT, uintptr(code), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func readlen(fd int, p *byte, np int) (n int, err error) {
+	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(p)), uintptr(np))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func writelen(fd int, p *byte, np int) (n int, err error) {
+	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(p)), uintptr(np))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func munmap(addr uintptr, length uintptr) (err error) {
+	_, _, e1 := Syscall(SYS_MUNMAP, uintptr(addr), uintptr(length), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Madvise(b []byte, advice int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MADVISE, uintptr(_p0), uintptr(len(b)), uintptr(advice))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mprotect(b []byte, prot int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mlock(b []byte) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Munlock(b []byte) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mlockall(flags int) (err error) {
+	_, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Munlockall() (err error) {
+	_, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chown(path string, uid int, gid int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchown(fd int, uid int, gid int) (err error) {
+	_, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fstat(fd int, stat *Stat_t) (err error) {
+	_, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fstatfs(fd int, buf *Statfs_t) (err error) {
+	_, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(buf)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Ftruncate(fd int, length int64) (err error) {
+	_, _, e1 := Syscall(SYS_FTRUNCATE, uintptr(fd), uintptr(length), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getegid() (egid int) {
+	r0, _, _ := RawSyscall(SYS_GETEGID, 0, 0, 0)
+	egid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Geteuid() (euid int) {
+	r0, _, _ := RawSyscall(SYS_GETEUID, 0, 0, 0)
+	euid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getgid() (gid int) {
+	r0, _, _ := RawSyscall(SYS_GETGID, 0, 0, 0)
+	gid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getrlimit(resource int, rlim *Rlimit) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETRLIMIT, uintptr(resource), uintptr(unsafe.Pointer(rlim)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getuid() (uid int) {
+	r0, _, _ := RawSyscall(SYS_GETUID, 0, 0, 0)
+	uid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Ioperm(from int, num int, on int) (err error) {
+	_, _, e1 := Syscall(SYS_IOPERM, uintptr(from), uintptr(num), uintptr(on))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Iopl(level int) (err error) {
+	_, _, e1 := Syscall(SYS_IOPL, uintptr(level), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Lchown(path string, uid int, gid int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_LCHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Listen(s int, n int) (err error) {
+	_, _, e1 := Syscall(SYS_LISTEN, uintptr(s), uintptr(n), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Lstat(path string, stat *Stat_t) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_LSTAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pread(fd int, p []byte, offset int64) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_PREAD64, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_PWRITE64, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), 0, 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Seek(fd int, offset int64, whence int) (off int64, err error) {
+	r0, _, e1 := Syscall(SYS_LSEEK, uintptr(fd), uintptr(offset), uintptr(whence))
+	off = int64(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) {
+	r0, _, e1 := Syscall6(SYS_SELECT, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
+	r0, _, e1 := Syscall6(SYS_SENDFILE, uintptr(outfd), uintptr(infd), uintptr(unsafe.Pointer(offset)), uintptr(count), 0, 0)
+	written = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setfsgid(gid int) (err error) {
+	_, _, e1 := Syscall(SYS_SETFSGID, uintptr(gid), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setfsuid(uid int) (err error) {
+	_, _, e1 := Syscall(SYS_SETFSUID, uintptr(uid), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setregid(rgid int, egid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setresgid(rgid int, egid int, sgid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETRESGID, uintptr(rgid), uintptr(egid), uintptr(sgid))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setresuid(ruid int, euid int, suid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETRESUID, uintptr(ruid), uintptr(euid), uintptr(suid))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setrlimit(resource int, rlim *Rlimit) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(resource), uintptr(unsafe.Pointer(rlim)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setreuid(ruid int, euid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Shutdown(fd int, how int) (err error) {
+	_, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(fd), uintptr(how), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int64, err error) {
+	r0, _, e1 := Syscall6(SYS_SPLICE, uintptr(rfd), uintptr(unsafe.Pointer(roff)), uintptr(wfd), uintptr(unsafe.Pointer(woff)), uintptr(len), uintptr(flags))
+	n = int64(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Stat(path string, stat *Stat_t) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Statfs(path string, buf *Statfs_t) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_STATFS, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(buf)), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func SyncFileRange(fd int, off int64, n int64, flags int) (err error) {
+	_, _, e1 := Syscall6(SYS_SYNC_FILE_RANGE, uintptr(fd), uintptr(off), uintptr(n), uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Truncate(path string, length int64) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_TRUNCATE, uintptr(unsafe.Pointer(_p0)), uintptr(length), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
+	r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) {
+	r0, _, e1 := Syscall6(SYS_ACCEPT4, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0)
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
+	_, _, e1 := Syscall(SYS_BIND, uintptr(s), uintptr(addr), uintptr(addrlen))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
+	_, _, e1 := Syscall(SYS_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getgroups(n int, list *_Gid_t) (nn int, err error) {
+	r0, _, e1 := RawSyscall(SYS_GETGROUPS, uintptr(n), uintptr(unsafe.Pointer(list)), 0)
+	nn = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func setgroups(n int, list *_Gid_t) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETGROUPS, uintptr(n), uintptr(unsafe.Pointer(list)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) {
+	_, _, e1 := Syscall6(SYS_GETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) {
+	_, _, e1 := Syscall6(SYS_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func socket(domain int, typ int, proto int) (fd int, err error) {
+	r0, _, e1 := RawSyscall(SYS_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto))
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) {
+	_, _, e1 := RawSyscall6(SYS_SOCKETPAIR, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETPEERNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETSOCKNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_RECVFROM, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) {
+	var _p0 unsafe.Pointer
+	if len(buf) > 0 {
+		_p0 = unsafe.Pointer(&buf[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall6(SYS_SENDTO, uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
+	r0, _, e1 := Syscall(SYS_RECVMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
+	r0, _, e1 := Syscall(SYS_SENDMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func mmap(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error) {
+	r0, _, e1 := Syscall6(SYS_MMAP, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flags), uintptr(fd), uintptr(offset))
+	xaddr = uintptr(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
diff --git a/src/syscall/zsyscall_linux_arm.go b/src/syscall/zsyscall_linux_arm.go
new file mode 100644
index 0000000..fbf6935
--- /dev/null
+++ b/src/syscall/zsyscall_linux_arm.go
@@ -0,0 +1,1915 @@
+// mksyscall.pl -l32 -arm syscall_linux.go syscall_linux_arm.go
+// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
+
+package syscall
+
+import "unsafe"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func open(path string, mode int, perm uint32) (fd int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
+	use(unsafe.Pointer(_p0))
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall6(SYS_OPENAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), uintptr(mode), 0, 0)
+	use(unsafe.Pointer(_p0))
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func pipe(p *[2]_C_int) (err error) {
+	_, _, e1 := RawSyscall(SYS_PIPE, uintptr(unsafe.Pointer(p)), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func pipe2(p *[2]_C_int, flags int) (err error) {
+	_, _, e1 := RawSyscall(SYS_PIPE2, uintptr(unsafe.Pointer(p)), uintptr(flags), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func utimes(path string, times *[2]Timeval) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func utimensat(dirfd int, path string, times *[2]Timespec) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UTIMENSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)))
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func futimesat(dirfd int, path *byte, times *[2]Timeval) (err error) {
+	_, _, e1 := Syscall(SYS_FUTIMESAT, uintptr(dirfd), uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(times)))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getcwd(buf []byte) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(buf) > 0 {
+		_p0 = unsafe.Pointer(&buf[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_GETCWD, uintptr(_p0), uintptr(len(buf)), 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) {
+	r0, _, e1 := Syscall6(SYS_WAIT4, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0)
+	wpid = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func ptrace(request int, pid int, addr uintptr, data uintptr) (err error) {
+	_, _, e1 := Syscall6(SYS_PTRACE, uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func reboot(magic1 uint, magic2 uint, cmd int, arg string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(arg)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_REBOOT, uintptr(magic1), uintptr(magic2), uintptr(cmd), uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func mount(source string, target string, fstype string, flags uintptr, data *byte) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(source)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(target)
+	if err != nil {
+		return
+	}
+	var _p2 *byte
+	_p2, err = BytePtrFromString(fstype)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_MOUNT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(unsafe.Pointer(_p2)), uintptr(flags), uintptr(unsafe.Pointer(data)), 0)
+	use(unsafe.Pointer(_p0))
+	use(unsafe.Pointer(_p1))
+	use(unsafe.Pointer(_p2))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Access(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_ACCESS, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Acct(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_ACCT, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Adjtimex(buf *Timex) (state int, err error) {
+	r0, _, e1 := Syscall(SYS_ADJTIMEX, uintptr(unsafe.Pointer(buf)), 0, 0)
+	state = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chdir(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chmod(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHMOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chroot(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHROOT, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Close(fd int) (err error) {
+	_, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Creat(path string, mode uint32) (fd int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall(SYS_CREAT, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	use(unsafe.Pointer(_p0))
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Dup(oldfd int) (fd int, err error) {
+	r0, _, e1 := RawSyscall(SYS_DUP, uintptr(oldfd), 0, 0)
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Dup2(oldfd int, newfd int) (err error) {
+	_, _, e1 := RawSyscall(SYS_DUP2, uintptr(oldfd), uintptr(newfd), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Dup3(oldfd int, newfd int, flags int) (err error) {
+	_, _, e1 := RawSyscall(SYS_DUP3, uintptr(oldfd), uintptr(newfd), uintptr(flags))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func EpollCreate(size int) (fd int, err error) {
+	r0, _, e1 := RawSyscall(SYS_EPOLL_CREATE, uintptr(size), 0, 0)
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func EpollCreate1(flag int) (fd int, err error) {
+	r0, _, e1 := RawSyscall(SYS_EPOLL_CREATE1, uintptr(flag), 0, 0)
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func EpollCtl(epfd int, op int, fd int, event *EpollEvent) (err error) {
+	_, _, e1 := RawSyscall6(SYS_EPOLL_CTL, uintptr(epfd), uintptr(op), uintptr(fd), uintptr(unsafe.Pointer(event)), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(events) > 0 {
+		_p0 = unsafe.Pointer(&events[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_EPOLL_WAIT, uintptr(epfd), uintptr(_p0), uintptr(len(events)), uintptr(msec), 0, 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Exit(code int) {
+	Syscall(SYS_EXIT_GROUP, uintptr(code), 0, 0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_FACCESSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fallocate(fd int, mode uint32, off int64, len int64) (err error) {
+	_, _, e1 := Syscall6(SYS_FALLOCATE, uintptr(fd), uintptr(mode), uintptr(off), uintptr(off>>32), uintptr(len), uintptr(len>>32))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchdir(fd int) (err error) {
+	_, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchmod(fd int, mode uint32) (err error) {
+	_, _, e1 := Syscall(SYS_FCHMOD, uintptr(fd), uintptr(mode), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_FCHMODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_FCHOWNAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid), uintptr(flags), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func fcntl(fd int, cmd int, arg int) (val int, err error) {
+	r0, _, e1 := Syscall(SYS_FCNTL, uintptr(fd), uintptr(cmd), uintptr(arg))
+	val = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fdatasync(fd int) (err error) {
+	_, _, e1 := Syscall(SYS_FDATASYNC, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Flock(fd int, how int) (err error) {
+	_, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fsync(fd int) (err error) {
+	_, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getdents(fd int, buf []byte) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(buf) > 0 {
+		_p0 = unsafe.Pointer(&buf[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_GETDENTS64, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpgid(pid int) (pgid int, err error) {
+	r0, _, e1 := RawSyscall(SYS_GETPGID, uintptr(pid), 0, 0)
+	pgid = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpgrp() (pid int) {
+	r0, _, _ := RawSyscall(SYS_GETPGRP, 0, 0, 0)
+	pid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpid() (pid int) {
+	r0, _, _ := RawSyscall(SYS_GETPID, 0, 0, 0)
+	pid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getppid() (ppid int) {
+	r0, _, _ := RawSyscall(SYS_GETPPID, 0, 0, 0)
+	ppid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpriority(which int, who int) (prio int, err error) {
+	r0, _, e1 := Syscall(SYS_GETPRIORITY, uintptr(which), uintptr(who), 0)
+	prio = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getrusage(who int, rusage *Rusage) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETRUSAGE, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Gettid() (tid int) {
+	r0, _, _ := RawSyscall(SYS_GETTID, 0, 0, 0)
+	tid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getxattr(path string, attr string, dest []byte) (sz int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(attr)
+	if err != nil {
+		return
+	}
+	var _p2 unsafe.Pointer
+	if len(dest) > 0 {
+		_p2 = unsafe.Pointer(&dest[0])
+	} else {
+		_p2 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_GETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(_p2), uintptr(len(dest)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	use(unsafe.Pointer(_p1))
+	sz = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func InotifyAddWatch(fd int, pathname string, mask uint32) (watchdesc int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(pathname)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall(SYS_INOTIFY_ADD_WATCH, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(mask))
+	use(unsafe.Pointer(_p0))
+	watchdesc = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func InotifyInit() (fd int, err error) {
+	r0, _, e1 := RawSyscall(SYS_INOTIFY_INIT, 0, 0, 0)
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func InotifyInit1(flags int) (fd int, err error) {
+	r0, _, e1 := RawSyscall(SYS_INOTIFY_INIT1, uintptr(flags), 0, 0)
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func InotifyRmWatch(fd int, watchdesc uint32) (success int, err error) {
+	r0, _, e1 := RawSyscall(SYS_INOTIFY_RM_WATCH, uintptr(fd), uintptr(watchdesc), 0)
+	success = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Kill(pid int, sig Signal) (err error) {
+	_, _, e1 := RawSyscall(SYS_KILL, uintptr(pid), uintptr(sig), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Klogctl(typ int, buf []byte) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(buf) > 0 {
+		_p0 = unsafe.Pointer(&buf[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_SYSLOG, uintptr(typ), uintptr(_p0), uintptr(len(buf)))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Link(oldpath string, newpath string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(oldpath)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(newpath)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_LINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	use(unsafe.Pointer(_p0))
+	use(unsafe.Pointer(_p1))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Listxattr(path string, dest []byte) (sz int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 unsafe.Pointer
+	if len(dest) > 0 {
+		_p1 = unsafe.Pointer(&dest[0])
+	} else {
+		_p1 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_LISTXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(dest)))
+	use(unsafe.Pointer(_p0))
+	sz = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mkdir(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_MKDIR, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mkdirat(dirfd int, path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_MKDIRAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode))
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mknod(path string, mode uint32, dev int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_MKNOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mknodat(dirfd int, path string, mode uint32, dev int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_MKNODAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Nanosleep(time *Timespec, leftover *Timespec) (err error) {
+	_, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pause() (err error) {
+	_, _, e1 := Syscall(SYS_PAUSE, 0, 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func PivotRoot(newroot string, putold string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(newroot)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(putold)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_PIVOT_ROOT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	use(unsafe.Pointer(_p0))
+	use(unsafe.Pointer(_p1))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func prlimit(pid int, resource int, old *Rlimit, newlimit *Rlimit) (err error) {
+	_, _, e1 := RawSyscall6(SYS_PRLIMIT64, uintptr(pid), uintptr(resource), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(newlimit)), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func read(fd int, p []byte) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(_p0), uintptr(len(p)))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Readlink(path string, buf []byte) (n int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 unsafe.Pointer
+	if len(buf) > 0 {
+		_p1 = unsafe.Pointer(&buf[0])
+	} else {
+		_p1 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_READLINK, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
+	use(unsafe.Pointer(_p0))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Removexattr(path string, attr string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(attr)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_REMOVEXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	use(unsafe.Pointer(_p0))
+	use(unsafe.Pointer(_p1))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Rename(oldpath string, newpath string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(oldpath)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(newpath)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_RENAME, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	use(unsafe.Pointer(_p0))
+	use(unsafe.Pointer(_p1))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(oldpath)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(newpath)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_RENAMEAT, uintptr(olddirfd), uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	use(unsafe.Pointer(_p1))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Rmdir(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_RMDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setdomainname(p []byte) (err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_SETDOMAINNAME, uintptr(_p0), uintptr(len(p)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Sethostname(p []byte) (err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_SETHOSTNAME, uintptr(_p0), uintptr(len(p)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setpgid(pid int, pgid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETPGID, uintptr(pid), uintptr(pgid), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setsid() (pid int, err error) {
+	r0, _, e1 := RawSyscall(SYS_SETSID, 0, 0, 0)
+	pid = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Settimeofday(tv *Timeval) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setpriority(which int, who int, prio int) (err error) {
+	_, _, e1 := Syscall(SYS_SETPRIORITY, uintptr(which), uintptr(who), uintptr(prio))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setxattr(path string, attr string, data []byte, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(attr)
+	if err != nil {
+		return
+	}
+	var _p2 unsafe.Pointer
+	if len(data) > 0 {
+		_p2 = unsafe.Pointer(&data[0])
+	} else {
+		_p2 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall6(SYS_SETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(_p2), uintptr(len(data)), uintptr(flags), 0)
+	use(unsafe.Pointer(_p0))
+	use(unsafe.Pointer(_p1))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Symlink(oldpath string, newpath string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(oldpath)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(newpath)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_SYMLINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	use(unsafe.Pointer(_p0))
+	use(unsafe.Pointer(_p1))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Sync() {
+	Syscall(SYS_SYNC, 0, 0, 0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Sysinfo(info *Sysinfo_t) (err error) {
+	_, _, e1 := RawSyscall(SYS_SYSINFO, uintptr(unsafe.Pointer(info)), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Tee(rfd int, wfd int, len int, flags int) (n int64, err error) {
+	r0, r1, e1 := Syscall6(SYS_TEE, uintptr(rfd), uintptr(wfd), uintptr(len), uintptr(flags), 0, 0)
+	n = int64(int64(r1)<<32 | int64(r0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Tgkill(tgid int, tid int, sig Signal) (err error) {
+	_, _, e1 := RawSyscall(SYS_TGKILL, uintptr(tgid), uintptr(tid), uintptr(sig))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Times(tms *Tms) (ticks uintptr, err error) {
+	r0, _, e1 := RawSyscall(SYS_TIMES, uintptr(unsafe.Pointer(tms)), 0, 0)
+	ticks = uintptr(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Umask(mask int) (oldmask int) {
+	r0, _, _ := RawSyscall(SYS_UMASK, uintptr(mask), 0, 0)
+	oldmask = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Uname(buf *Utsname) (err error) {
+	_, _, e1 := RawSyscall(SYS_UNAME, uintptr(unsafe.Pointer(buf)), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Unlink(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UNLINK, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Unlinkat(dirfd int, path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UNLINKAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Unmount(target string, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(target)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UMOUNT2, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Unshare(flags int) (err error) {
+	_, _, e1 := Syscall(SYS_UNSHARE, uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Ustat(dev int, ubuf *Ustat_t) (err error) {
+	_, _, e1 := Syscall(SYS_USTAT, uintptr(dev), uintptr(unsafe.Pointer(ubuf)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Utime(path string, buf *Utimbuf) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UTIME, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(buf)), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func write(fd int, p []byte) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func exitThread(code int) (err error) {
+	_, _, e1 := Syscall(SYS_EXIT, uintptr(code), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func readlen(fd int, p *byte, np int) (n int, err error) {
+	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(p)), uintptr(np))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func writelen(fd int, p *byte, np int) (n int, err error) {
+	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(p)), uintptr(np))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func munmap(addr uintptr, length uintptr) (err error) {
+	_, _, e1 := Syscall(SYS_MUNMAP, uintptr(addr), uintptr(length), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Madvise(b []byte, advice int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MADVISE, uintptr(_p0), uintptr(len(b)), uintptr(advice))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mprotect(b []byte, prot int) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MPROTECT, uintptr(_p0), uintptr(len(b)), uintptr(prot))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mlock(b []byte) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MLOCK, uintptr(_p0), uintptr(len(b)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Munlock(b []byte) (err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall(SYS_MUNLOCK, uintptr(_p0), uintptr(len(b)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mlockall(flags int) (err error) {
+	_, _, e1 := Syscall(SYS_MLOCKALL, uintptr(flags), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Munlockall() (err error) {
+	_, _, e1 := Syscall(SYS_MUNLOCKALL, 0, 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
+	r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) {
+	r0, _, e1 := Syscall6(SYS_ACCEPT4, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0)
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
+	_, _, e1 := Syscall(SYS_BIND, uintptr(s), uintptr(addr), uintptr(addrlen))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
+	_, _, e1 := Syscall(SYS_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getgroups(n int, list *_Gid_t) (nn int, err error) {
+	r0, _, e1 := RawSyscall(SYS_GETGROUPS32, uintptr(n), uintptr(unsafe.Pointer(list)), 0)
+	nn = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func setgroups(n int, list *_Gid_t) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETGROUPS32, uintptr(n), uintptr(unsafe.Pointer(list)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) {
+	_, _, e1 := Syscall6(SYS_GETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) {
+	_, _, e1 := Syscall6(SYS_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func socket(domain int, typ int, proto int) (fd int, err error) {
+	r0, _, e1 := RawSyscall(SYS_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto))
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETPEERNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETSOCKNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_RECVFROM, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) {
+	var _p0 unsafe.Pointer
+	if len(buf) > 0 {
+		_p0 = unsafe.Pointer(&buf[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall6(SYS_SENDTO, uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func socketpair(domain int, typ int, flags int, fd *[2]int32) (err error) {
+	_, _, e1 := RawSyscall6(SYS_SOCKETPAIR, uintptr(domain), uintptr(typ), uintptr(flags), uintptr(unsafe.Pointer(fd)), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
+	r0, _, e1 := Syscall(SYS_RECVMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
+	r0, _, e1 := Syscall(SYS_SENDMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chown(path string, uid int, gid int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHOWN32, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchown(fd int, uid int, gid int) (err error) {
+	_, _, e1 := Syscall(SYS_FCHOWN32, uintptr(fd), uintptr(uid), uintptr(gid))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fstat(fd int, stat *Stat_t) (err error) {
+	_, _, e1 := Syscall(SYS_FSTAT64, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getegid() (egid int) {
+	r0, _, _ := RawSyscall(SYS_GETEGID32, 0, 0, 0)
+	egid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Geteuid() (euid int) {
+	r0, _, _ := RawSyscall(SYS_GETEUID32, 0, 0, 0)
+	euid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getgid() (gid int) {
+	r0, _, _ := RawSyscall(SYS_GETGID32, 0, 0, 0)
+	gid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getuid() (uid int) {
+	r0, _, _ := RawSyscall(SYS_GETUID32, 0, 0, 0)
+	uid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Lchown(path string, uid int, gid int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_LCHOWN32, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Listen(s int, n int) (err error) {
+	_, _, e1 := Syscall(SYS_LISTEN, uintptr(s), uintptr(n), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Lstat(path string, stat *Stat_t) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_LSTAT64, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sendfile(outfd int, infd int, offset *int64, count int) (written int, err error) {
+	r0, _, e1 := Syscall6(SYS_SENDFILE64, uintptr(outfd), uintptr(infd), uintptr(unsafe.Pointer(offset)), uintptr(count), 0, 0)
+	written = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err error) {
+	r0, _, e1 := Syscall6(SYS__NEWSELECT, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setfsgid(gid int) (err error) {
+	_, _, e1 := Syscall(SYS_SETFSGID32, uintptr(gid), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setfsuid(uid int) (err error) {
+	_, _, e1 := Syscall(SYS_SETFSUID32, uintptr(uid), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setregid(rgid int, egid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETREGID32, uintptr(rgid), uintptr(egid), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setresgid(rgid int, egid int, sgid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETRESGID32, uintptr(rgid), uintptr(egid), uintptr(sgid))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setresuid(ruid int, euid int, suid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETRESUID32, uintptr(ruid), uintptr(euid), uintptr(suid))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setreuid(ruid int, euid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETREUID32, uintptr(ruid), uintptr(euid), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Shutdown(fd int, how int) (err error) {
+	_, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(fd), uintptr(how), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Splice(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error) {
+	r0, _, e1 := Syscall6(SYS_SPLICE, uintptr(rfd), uintptr(unsafe.Pointer(roff)), uintptr(wfd), uintptr(unsafe.Pointer(woff)), uintptr(len), uintptr(flags))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Stat(path string, stat *Stat_t) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_STAT64, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Gettimeofday(tv *Timeval) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Time(t *Time_t) (tt Time_t, err error) {
+	r0, _, e1 := RawSyscall(SYS_TIME, uintptr(unsafe.Pointer(t)), 0, 0)
+	tt = Time_t(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pread(fd int, p []byte, offset int64) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_PREAD64, uintptr(fd), uintptr(_p0), uintptr(len(p)), 0, uintptr(offset), uintptr(offset>>32))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_PWRITE64, uintptr(fd), uintptr(_p0), uintptr(len(p)), 0, uintptr(offset), uintptr(offset>>32))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Truncate(path string, length int64) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_TRUNCATE64, uintptr(unsafe.Pointer(_p0)), 0, uintptr(length), uintptr(length>>32), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Ftruncate(fd int, length int64) (err error) {
+	_, _, e1 := Syscall6(SYS_FTRUNCATE64, uintptr(fd), 0, uintptr(length), uintptr(length>>32), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func mmap2(addr uintptr, length uintptr, prot int, flags int, fd int, pageOffset uintptr) (xaddr uintptr, err error) {
+	r0, _, e1 := Syscall6(SYS_MMAP2, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flags), uintptr(fd), uintptr(pageOffset))
+	xaddr = uintptr(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getrlimit(resource int, rlim *rlimit32) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETRLIMIT, uintptr(resource), uintptr(unsafe.Pointer(rlim)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func setrlimit(resource int, rlim *rlimit32) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(resource), uintptr(unsafe.Pointer(rlim)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
diff --git a/src/pkg/syscall/zsyscall_nacl_386.go b/src/syscall/zsyscall_nacl_386.go
similarity index 100%
rename from src/pkg/syscall/zsyscall_nacl_386.go
rename to src/syscall/zsyscall_nacl_386.go
diff --git a/src/pkg/syscall/zsyscall_nacl_amd64p32.go b/src/syscall/zsyscall_nacl_amd64p32.go
similarity index 100%
rename from src/pkg/syscall/zsyscall_nacl_amd64p32.go
rename to src/syscall/zsyscall_nacl_amd64p32.go
diff --git a/src/syscall/zsyscall_nacl_arm.go b/src/syscall/zsyscall_nacl_arm.go
new file mode 100644
index 0000000..adbaed0
--- /dev/null
+++ b/src/syscall/zsyscall_nacl_arm.go
@@ -0,0 +1,63 @@
+// mksyscall.pl -l32 -nacl -arm syscall_nacl.go syscall_nacl_arm.go
+// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
+
+package syscall
+
+import "unsafe"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func naclClose(fd int) (err error) {
+	_, _, e1 := Syscall(sys_close, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Exit(code int) (err error) {
+	_, _, e1 := Syscall(sys_exit, uintptr(code), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func naclFstat(fd int, stat *Stat_t) (err error) {
+	_, _, e1 := Syscall(sys_fstat, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func naclRead(fd int, b []byte) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(b) > 0 {
+		_p0 = unsafe.Pointer(&b[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(sys_read, uintptr(fd), uintptr(_p0), uintptr(len(b)))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func naclSeek(fd int, off *int64, whence int) (err error) {
+	_, _, e1 := Syscall(sys_lseek, uintptr(fd), uintptr(unsafe.Pointer(off)), uintptr(whence))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
diff --git a/src/syscall/zsyscall_netbsd_386.go b/src/syscall/zsyscall_netbsd_386.go
new file mode 100644
index 0000000..e9bd3d0
--- /dev/null
+++ b/src/syscall/zsyscall_netbsd_386.go
@@ -0,0 +1,1251 @@
+// mksyscall.pl -l32 -netbsd syscall_bsd.go syscall_netbsd.go syscall_netbsd_386.go
+// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
+
+package syscall
+
+import "unsafe"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getgroups(ngid int, gid *_Gid_t) (n int, err error) {
+	r0, _, e1 := RawSyscall(SYS_GETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func setgroups(ngid int, gid *_Gid_t) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) {
+	r0, _, e1 := Syscall6(SYS_WAIT4, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0)
+	wpid = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
+	r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
+	_, _, e1 := Syscall(SYS_BIND, uintptr(s), uintptr(addr), uintptr(addrlen))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
+	_, _, e1 := Syscall(SYS_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func socket(domain int, typ int, proto int) (fd int, err error) {
+	r0, _, e1 := RawSyscall(SYS_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto))
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) {
+	_, _, e1 := Syscall6(SYS_GETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) {
+	_, _, e1 := Syscall6(SYS_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETPEERNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETSOCKNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Shutdown(s int, how int) (err error) {
+	_, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(s), uintptr(how), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) {
+	_, _, e1 := RawSyscall6(SYS_SOCKETPAIR, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_RECVFROM, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) {
+	var _p0 unsafe.Pointer
+	if len(buf) > 0 {
+		_p0 = unsafe.Pointer(&buf[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall6(SYS_SENDTO, uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
+	r0, _, e1 := Syscall(SYS_RECVMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
+	r0, _, e1 := Syscall(SYS_SENDMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func kevent(kq int, change unsafe.Pointer, nchange int, event unsafe.Pointer, nevent int, timeout *Timespec) (n int, err error) {
+	r0, _, e1 := Syscall6(SYS_KEVENT, uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout)))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) {
+	var _p0 unsafe.Pointer
+	if len(mib) > 0 {
+		_p0 = unsafe.Pointer(&mib[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall6(SYS___SYSCTL, uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func utimes(path string, timeval *[2]Timeval) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(timeval)), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func futimes(fd int, timeval *[2]Timeval) (err error) {
+	_, _, e1 := Syscall(SYS_FUTIMES, uintptr(fd), uintptr(unsafe.Pointer(timeval)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func fcntl(fd int, cmd int, arg int) (val int, err error) {
+	r0, _, e1 := Syscall(SYS_FCNTL, uintptr(fd), uintptr(cmd), uintptr(arg))
+	val = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func pipe() (fd1 int, fd2 int, err error) {
+	r0, r1, e1 := RawSyscall(SYS_PIPE, 0, 0, 0)
+	fd1 = int(r0)
+	fd2 = int(r1)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getdents(fd int, buf []byte) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(buf) > 0 {
+		_p0 = unsafe.Pointer(&buf[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_GETDENTS, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Access(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_ACCESS, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Adjtime(delta *Timeval, olddelta *Timeval) (err error) {
+	_, _, e1 := Syscall(SYS_ADJTIME, uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chdir(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chflags(path string, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHFLAGS, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chmod(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHMOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chown(path string, uid int, gid int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chroot(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHROOT, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Close(fd int) (err error) {
+	_, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Dup(fd int) (nfd int, err error) {
+	r0, _, e1 := RawSyscall(SYS_DUP, uintptr(fd), 0, 0)
+	nfd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Dup2(from int, to int) (err error) {
+	_, _, e1 := RawSyscall(SYS_DUP2, uintptr(from), uintptr(to), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Exit(code int) {
+	Syscall(SYS_EXIT, uintptr(code), 0, 0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchdir(fd int) (err error) {
+	_, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchflags(fd int, flags int) (err error) {
+	_, _, e1 := Syscall(SYS_FCHFLAGS, uintptr(fd), uintptr(flags), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchmod(fd int, mode uint32) (err error) {
+	_, _, e1 := Syscall(SYS_FCHMOD, uintptr(fd), uintptr(mode), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchown(fd int, uid int, gid int) (err error) {
+	_, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Flock(fd int, how int) (err error) {
+	_, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fpathconf(fd int, name int) (val int, err error) {
+	r0, _, e1 := Syscall(SYS_FPATHCONF, uintptr(fd), uintptr(name), 0)
+	val = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fstat(fd int, stat *Stat_t) (err error) {
+	_, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fsync(fd int) (err error) {
+	_, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Ftruncate(fd int, length int64) (err error) {
+	_, _, e1 := Syscall6(SYS_FTRUNCATE, uintptr(fd), 0, uintptr(length), uintptr(length>>32), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getegid() (egid int) {
+	r0, _, _ := RawSyscall(SYS_GETEGID, 0, 0, 0)
+	egid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Geteuid() (uid int) {
+	r0, _, _ := RawSyscall(SYS_GETEUID, 0, 0, 0)
+	uid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getgid() (gid int) {
+	r0, _, _ := RawSyscall(SYS_GETGID, 0, 0, 0)
+	gid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpgid(pid int) (pgid int, err error) {
+	r0, _, e1 := RawSyscall(SYS_GETPGID, uintptr(pid), 0, 0)
+	pgid = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpgrp() (pgrp int) {
+	r0, _, _ := RawSyscall(SYS_GETPGRP, 0, 0, 0)
+	pgrp = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpid() (pid int) {
+	r0, _, _ := RawSyscall(SYS_GETPID, 0, 0, 0)
+	pid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getppid() (ppid int) {
+	r0, _, _ := RawSyscall(SYS_GETPPID, 0, 0, 0)
+	ppid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpriority(which int, who int) (prio int, err error) {
+	r0, _, e1 := Syscall(SYS_GETPRIORITY, uintptr(which), uintptr(who), 0)
+	prio = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getrlimit(which int, lim *Rlimit) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getrusage(who int, rusage *Rusage) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETRUSAGE, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getsid(pid int) (sid int, err error) {
+	r0, _, e1 := RawSyscall(SYS_GETSID, uintptr(pid), 0, 0)
+	sid = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Gettimeofday(tv *Timeval) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getuid() (uid int) {
+	r0, _, _ := RawSyscall(SYS_GETUID, 0, 0, 0)
+	uid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Issetugid() (tainted bool) {
+	r0, _, _ := Syscall(SYS_ISSETUGID, 0, 0, 0)
+	tainted = bool(r0 != 0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Kill(pid int, signum Signal) (err error) {
+	_, _, e1 := Syscall(SYS_KILL, uintptr(pid), uintptr(signum), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Kqueue() (fd int, err error) {
+	r0, _, e1 := Syscall(SYS_KQUEUE, 0, 0, 0)
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Lchown(path string, uid int, gid int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_LCHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Link(path string, link string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(link)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_LINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	use(unsafe.Pointer(_p0))
+	use(unsafe.Pointer(_p1))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Listen(s int, backlog int) (err error) {
+	_, _, e1 := Syscall(SYS_LISTEN, uintptr(s), uintptr(backlog), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Lstat(path string, stat *Stat_t) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_LSTAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mkdir(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_MKDIR, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mkfifo(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_MKFIFO, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mknod(path string, mode uint32, dev int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_MKNOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Nanosleep(time *Timespec, leftover *Timespec) (err error) {
+	_, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Open(path string, mode int, perm uint32) (fd int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
+	use(unsafe.Pointer(_p0))
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pathconf(path string, name int) (val int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall(SYS_PATHCONF, uintptr(unsafe.Pointer(_p0)), uintptr(name), 0)
+	use(unsafe.Pointer(_p0))
+	val = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pread(fd int, p []byte, offset int64) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_PREAD, uintptr(fd), uintptr(_p0), uintptr(len(p)), 0, uintptr(offset), uintptr(offset>>32))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_PWRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)), 0, uintptr(offset), uintptr(offset>>32))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func read(fd int, p []byte) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(_p0), uintptr(len(p)))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Readlink(path string, buf []byte) (n int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 unsafe.Pointer
+	if len(buf) > 0 {
+		_p1 = unsafe.Pointer(&buf[0])
+	} else {
+		_p1 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_READLINK, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
+	use(unsafe.Pointer(_p0))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Rename(from string, to string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(from)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(to)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_RENAME, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	use(unsafe.Pointer(_p0))
+	use(unsafe.Pointer(_p1))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Revoke(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_REVOKE, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Rmdir(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_RMDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
+	r0, r1, e1 := Syscall6(SYS_LSEEK, uintptr(fd), 0, uintptr(offset), uintptr(offset>>32), uintptr(whence), 0)
+	newoffset = int64(int64(r1)<<32 | int64(r0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Select(n int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (err error) {
+	_, _, e1 := Syscall6(SYS_SELECT, uintptr(n), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setegid(egid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETEGID, uintptr(egid), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Seteuid(euid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETEUID, uintptr(euid), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setgid(gid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETGID, uintptr(gid), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setpgid(pid int, pgid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETPGID, uintptr(pid), uintptr(pgid), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setpriority(which int, who int, prio int) (err error) {
+	_, _, e1 := Syscall(SYS_SETPRIORITY, uintptr(which), uintptr(who), uintptr(prio))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setregid(rgid int, egid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setreuid(ruid int, euid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setrlimit(which int, lim *Rlimit) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setsid() (pid int, err error) {
+	r0, _, e1 := RawSyscall(SYS_SETSID, 0, 0, 0)
+	pid = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Settimeofday(tp *Timeval) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETTIMEOFDAY, uintptr(unsafe.Pointer(tp)), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setuid(uid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETUID, uintptr(uid), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Stat(path string, stat *Stat_t) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Symlink(path string, link string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(link)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_SYMLINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	use(unsafe.Pointer(_p0))
+	use(unsafe.Pointer(_p1))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Sync() (err error) {
+	_, _, e1 := Syscall(SYS_SYNC, 0, 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Truncate(path string, length int64) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_TRUNCATE, uintptr(unsafe.Pointer(_p0)), 0, uintptr(length), uintptr(length>>32), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Umask(newmask int) (oldmask int) {
+	r0, _, _ := Syscall(SYS_UMASK, uintptr(newmask), 0, 0)
+	oldmask = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Unlink(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UNLINK, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Unmount(path string, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UNMOUNT, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func write(fd int, p []byte) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) {
+	r0, _, e1 := Syscall9(SYS_MMAP, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), 0, uintptr(pos), uintptr(pos>>32), 0)
+	ret = uintptr(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func munmap(addr uintptr, length uintptr) (err error) {
+	_, _, e1 := Syscall(SYS_MUNMAP, uintptr(addr), uintptr(length), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func readlen(fd int, buf *byte, nbuf int) (n int, err error) {
+	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func writelen(fd int, buf *byte, nbuf int) (n int, err error) {
+	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
diff --git a/src/syscall/zsyscall_netbsd_amd64.go b/src/syscall/zsyscall_netbsd_amd64.go
new file mode 100644
index 0000000..1acd7c2
--- /dev/null
+++ b/src/syscall/zsyscall_netbsd_amd64.go
@@ -0,0 +1,1251 @@
+// mksyscall.pl -netbsd syscall_bsd.go syscall_netbsd.go syscall_netbsd_amd64.go
+// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
+
+package syscall
+
+import "unsafe"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getgroups(ngid int, gid *_Gid_t) (n int, err error) {
+	r0, _, e1 := RawSyscall(SYS_GETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func setgroups(ngid int, gid *_Gid_t) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) {
+	r0, _, e1 := Syscall6(SYS_WAIT4, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0)
+	wpid = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
+	r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
+	_, _, e1 := Syscall(SYS_BIND, uintptr(s), uintptr(addr), uintptr(addrlen))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
+	_, _, e1 := Syscall(SYS_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func socket(domain int, typ int, proto int) (fd int, err error) {
+	r0, _, e1 := RawSyscall(SYS_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto))
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) {
+	_, _, e1 := Syscall6(SYS_GETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) {
+	_, _, e1 := Syscall6(SYS_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETPEERNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETSOCKNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Shutdown(s int, how int) (err error) {
+	_, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(s), uintptr(how), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) {
+	_, _, e1 := RawSyscall6(SYS_SOCKETPAIR, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_RECVFROM, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) {
+	var _p0 unsafe.Pointer
+	if len(buf) > 0 {
+		_p0 = unsafe.Pointer(&buf[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall6(SYS_SENDTO, uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
+	r0, _, e1 := Syscall(SYS_RECVMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
+	r0, _, e1 := Syscall(SYS_SENDMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func kevent(kq int, change unsafe.Pointer, nchange int, event unsafe.Pointer, nevent int, timeout *Timespec) (n int, err error) {
+	r0, _, e1 := Syscall6(SYS_KEVENT, uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout)))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) {
+	var _p0 unsafe.Pointer
+	if len(mib) > 0 {
+		_p0 = unsafe.Pointer(&mib[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall6(SYS___SYSCTL, uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func utimes(path string, timeval *[2]Timeval) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(timeval)), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func futimes(fd int, timeval *[2]Timeval) (err error) {
+	_, _, e1 := Syscall(SYS_FUTIMES, uintptr(fd), uintptr(unsafe.Pointer(timeval)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func fcntl(fd int, cmd int, arg int) (val int, err error) {
+	r0, _, e1 := Syscall(SYS_FCNTL, uintptr(fd), uintptr(cmd), uintptr(arg))
+	val = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func pipe() (fd1 int, fd2 int, err error) {
+	r0, r1, e1 := RawSyscall(SYS_PIPE, 0, 0, 0)
+	fd1 = int(r0)
+	fd2 = int(r1)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getdents(fd int, buf []byte) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(buf) > 0 {
+		_p0 = unsafe.Pointer(&buf[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_GETDENTS, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Access(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_ACCESS, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Adjtime(delta *Timeval, olddelta *Timeval) (err error) {
+	_, _, e1 := Syscall(SYS_ADJTIME, uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chdir(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chflags(path string, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHFLAGS, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chmod(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHMOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chown(path string, uid int, gid int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chroot(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHROOT, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Close(fd int) (err error) {
+	_, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Dup(fd int) (nfd int, err error) {
+	r0, _, e1 := RawSyscall(SYS_DUP, uintptr(fd), 0, 0)
+	nfd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Dup2(from int, to int) (err error) {
+	_, _, e1 := RawSyscall(SYS_DUP2, uintptr(from), uintptr(to), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Exit(code int) {
+	Syscall(SYS_EXIT, uintptr(code), 0, 0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchdir(fd int) (err error) {
+	_, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchflags(fd int, flags int) (err error) {
+	_, _, e1 := Syscall(SYS_FCHFLAGS, uintptr(fd), uintptr(flags), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchmod(fd int, mode uint32) (err error) {
+	_, _, e1 := Syscall(SYS_FCHMOD, uintptr(fd), uintptr(mode), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchown(fd int, uid int, gid int) (err error) {
+	_, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Flock(fd int, how int) (err error) {
+	_, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fpathconf(fd int, name int) (val int, err error) {
+	r0, _, e1 := Syscall(SYS_FPATHCONF, uintptr(fd), uintptr(name), 0)
+	val = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fstat(fd int, stat *Stat_t) (err error) {
+	_, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fsync(fd int) (err error) {
+	_, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Ftruncate(fd int, length int64) (err error) {
+	_, _, e1 := Syscall(SYS_FTRUNCATE, uintptr(fd), 0, uintptr(length))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getegid() (egid int) {
+	r0, _, _ := RawSyscall(SYS_GETEGID, 0, 0, 0)
+	egid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Geteuid() (uid int) {
+	r0, _, _ := RawSyscall(SYS_GETEUID, 0, 0, 0)
+	uid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getgid() (gid int) {
+	r0, _, _ := RawSyscall(SYS_GETGID, 0, 0, 0)
+	gid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpgid(pid int) (pgid int, err error) {
+	r0, _, e1 := RawSyscall(SYS_GETPGID, uintptr(pid), 0, 0)
+	pgid = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpgrp() (pgrp int) {
+	r0, _, _ := RawSyscall(SYS_GETPGRP, 0, 0, 0)
+	pgrp = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpid() (pid int) {
+	r0, _, _ := RawSyscall(SYS_GETPID, 0, 0, 0)
+	pid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getppid() (ppid int) {
+	r0, _, _ := RawSyscall(SYS_GETPPID, 0, 0, 0)
+	ppid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpriority(which int, who int) (prio int, err error) {
+	r0, _, e1 := Syscall(SYS_GETPRIORITY, uintptr(which), uintptr(who), 0)
+	prio = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getrlimit(which int, lim *Rlimit) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getrusage(who int, rusage *Rusage) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETRUSAGE, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getsid(pid int) (sid int, err error) {
+	r0, _, e1 := RawSyscall(SYS_GETSID, uintptr(pid), 0, 0)
+	sid = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Gettimeofday(tv *Timeval) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getuid() (uid int) {
+	r0, _, _ := RawSyscall(SYS_GETUID, 0, 0, 0)
+	uid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Issetugid() (tainted bool) {
+	r0, _, _ := Syscall(SYS_ISSETUGID, 0, 0, 0)
+	tainted = bool(r0 != 0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Kill(pid int, signum Signal) (err error) {
+	_, _, e1 := Syscall(SYS_KILL, uintptr(pid), uintptr(signum), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Kqueue() (fd int, err error) {
+	r0, _, e1 := Syscall(SYS_KQUEUE, 0, 0, 0)
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Lchown(path string, uid int, gid int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_LCHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Link(path string, link string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(link)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_LINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	use(unsafe.Pointer(_p0))
+	use(unsafe.Pointer(_p1))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Listen(s int, backlog int) (err error) {
+	_, _, e1 := Syscall(SYS_LISTEN, uintptr(s), uintptr(backlog), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Lstat(path string, stat *Stat_t) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_LSTAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mkdir(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_MKDIR, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mkfifo(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_MKFIFO, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mknod(path string, mode uint32, dev int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_MKNOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Nanosleep(time *Timespec, leftover *Timespec) (err error) {
+	_, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Open(path string, mode int, perm uint32) (fd int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
+	use(unsafe.Pointer(_p0))
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pathconf(path string, name int) (val int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall(SYS_PATHCONF, uintptr(unsafe.Pointer(_p0)), uintptr(name), 0)
+	use(unsafe.Pointer(_p0))
+	val = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pread(fd int, p []byte, offset int64) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_PREAD, uintptr(fd), uintptr(_p0), uintptr(len(p)), 0, uintptr(offset), 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_PWRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)), 0, uintptr(offset), 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func read(fd int, p []byte) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(_p0), uintptr(len(p)))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Readlink(path string, buf []byte) (n int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 unsafe.Pointer
+	if len(buf) > 0 {
+		_p1 = unsafe.Pointer(&buf[0])
+	} else {
+		_p1 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_READLINK, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
+	use(unsafe.Pointer(_p0))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Rename(from string, to string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(from)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(to)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_RENAME, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	use(unsafe.Pointer(_p0))
+	use(unsafe.Pointer(_p1))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Revoke(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_REVOKE, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Rmdir(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_RMDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
+	r0, _, e1 := Syscall6(SYS_LSEEK, uintptr(fd), 0, uintptr(offset), uintptr(whence), 0, 0)
+	newoffset = int64(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Select(n int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (err error) {
+	_, _, e1 := Syscall6(SYS_SELECT, uintptr(n), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setegid(egid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETEGID, uintptr(egid), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Seteuid(euid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETEUID, uintptr(euid), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setgid(gid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETGID, uintptr(gid), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setpgid(pid int, pgid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETPGID, uintptr(pid), uintptr(pgid), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setpriority(which int, who int, prio int) (err error) {
+	_, _, e1 := Syscall(SYS_SETPRIORITY, uintptr(which), uintptr(who), uintptr(prio))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setregid(rgid int, egid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setreuid(ruid int, euid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setrlimit(which int, lim *Rlimit) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setsid() (pid int, err error) {
+	r0, _, e1 := RawSyscall(SYS_SETSID, 0, 0, 0)
+	pid = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Settimeofday(tp *Timeval) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETTIMEOFDAY, uintptr(unsafe.Pointer(tp)), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setuid(uid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETUID, uintptr(uid), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Stat(path string, stat *Stat_t) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Symlink(path string, link string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(link)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_SYMLINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	use(unsafe.Pointer(_p0))
+	use(unsafe.Pointer(_p1))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Sync() (err error) {
+	_, _, e1 := Syscall(SYS_SYNC, 0, 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Truncate(path string, length int64) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_TRUNCATE, uintptr(unsafe.Pointer(_p0)), 0, uintptr(length))
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Umask(newmask int) (oldmask int) {
+	r0, _, _ := Syscall(SYS_UMASK, uintptr(newmask), 0, 0)
+	oldmask = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Unlink(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UNLINK, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Unmount(path string, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UNMOUNT, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func write(fd int, p []byte) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) {
+	r0, _, e1 := Syscall9(SYS_MMAP, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), 0, uintptr(pos), 0, 0)
+	ret = uintptr(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func munmap(addr uintptr, length uintptr) (err error) {
+	_, _, e1 := Syscall(SYS_MUNMAP, uintptr(addr), uintptr(length), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func readlen(fd int, buf *byte, nbuf int) (n int, err error) {
+	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func writelen(fd int, buf *byte, nbuf int) (n int, err error) {
+	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
diff --git a/src/syscall/zsyscall_netbsd_arm.go b/src/syscall/zsyscall_netbsd_arm.go
new file mode 100644
index 0000000..898e0ce
--- /dev/null
+++ b/src/syscall/zsyscall_netbsd_arm.go
@@ -0,0 +1,1251 @@
+// mksyscall.pl -l32 -arm syscall_bsd.go syscall_netbsd.go syscall_netbsd_arm.go
+// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
+
+package syscall
+
+import "unsafe"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getgroups(ngid int, gid *_Gid_t) (n int, err error) {
+	r0, _, e1 := RawSyscall(SYS_GETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func setgroups(ngid int, gid *_Gid_t) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) {
+	r0, _, e1 := Syscall6(SYS_WAIT4, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0)
+	wpid = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
+	r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
+	_, _, e1 := Syscall(SYS_BIND, uintptr(s), uintptr(addr), uintptr(addrlen))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
+	_, _, e1 := Syscall(SYS_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func socket(domain int, typ int, proto int) (fd int, err error) {
+	r0, _, e1 := RawSyscall(SYS_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto))
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) {
+	_, _, e1 := Syscall6(SYS_GETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) {
+	_, _, e1 := Syscall6(SYS_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETPEERNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETSOCKNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Shutdown(s int, how int) (err error) {
+	_, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(s), uintptr(how), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) {
+	_, _, e1 := RawSyscall6(SYS_SOCKETPAIR, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_RECVFROM, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) {
+	var _p0 unsafe.Pointer
+	if len(buf) > 0 {
+		_p0 = unsafe.Pointer(&buf[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall6(SYS_SENDTO, uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
+	r0, _, e1 := Syscall(SYS_RECVMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
+	r0, _, e1 := Syscall(SYS_SENDMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func kevent(kq int, change unsafe.Pointer, nchange int, event unsafe.Pointer, nevent int, timeout *Timespec) (n int, err error) {
+	r0, _, e1 := Syscall6(SYS_KEVENT, uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout)))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) {
+	var _p0 unsafe.Pointer
+	if len(mib) > 0 {
+		_p0 = unsafe.Pointer(&mib[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall6(SYS___SYSCTL, uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func utimes(path string, timeval *[2]Timeval) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(timeval)), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func futimes(fd int, timeval *[2]Timeval) (err error) {
+	_, _, e1 := Syscall(SYS_FUTIMES, uintptr(fd), uintptr(unsafe.Pointer(timeval)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func fcntl(fd int, cmd int, arg int) (val int, err error) {
+	r0, _, e1 := Syscall(SYS_FCNTL, uintptr(fd), uintptr(cmd), uintptr(arg))
+	val = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func pipe() (fd1 int, fd2 int, err error) {
+	r0, r1, e1 := RawSyscall(SYS_PIPE, 0, 0, 0)
+	fd1 = int(r0)
+	fd2 = int(r1)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getdents(fd int, buf []byte) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(buf) > 0 {
+		_p0 = unsafe.Pointer(&buf[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_GETDENTS, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Access(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_ACCESS, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Adjtime(delta *Timeval, olddelta *Timeval) (err error) {
+	_, _, e1 := Syscall(SYS_ADJTIME, uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chdir(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chflags(path string, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHFLAGS, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chmod(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHMOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chown(path string, uid int, gid int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chroot(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHROOT, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Close(fd int) (err error) {
+	_, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Dup(fd int) (nfd int, err error) {
+	r0, _, e1 := RawSyscall(SYS_DUP, uintptr(fd), 0, 0)
+	nfd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Dup2(from int, to int) (err error) {
+	_, _, e1 := RawSyscall(SYS_DUP2, uintptr(from), uintptr(to), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Exit(code int) {
+	Syscall(SYS_EXIT, uintptr(code), 0, 0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchdir(fd int) (err error) {
+	_, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchflags(fd int, flags int) (err error) {
+	_, _, e1 := Syscall(SYS_FCHFLAGS, uintptr(fd), uintptr(flags), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchmod(fd int, mode uint32) (err error) {
+	_, _, e1 := Syscall(SYS_FCHMOD, uintptr(fd), uintptr(mode), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchown(fd int, uid int, gid int) (err error) {
+	_, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Flock(fd int, how int) (err error) {
+	_, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fpathconf(fd int, name int) (val int, err error) {
+	r0, _, e1 := Syscall(SYS_FPATHCONF, uintptr(fd), uintptr(name), 0)
+	val = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fstat(fd int, stat *Stat_t) (err error) {
+	_, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fsync(fd int) (err error) {
+	_, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Ftruncate(fd int, length int64) (err error) {
+	_, _, e1 := Syscall6(SYS_FTRUNCATE, uintptr(fd), 0, uintptr(length), uintptr(length>>32), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getegid() (egid int) {
+	r0, _, _ := RawSyscall(SYS_GETEGID, 0, 0, 0)
+	egid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Geteuid() (uid int) {
+	r0, _, _ := RawSyscall(SYS_GETEUID, 0, 0, 0)
+	uid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getgid() (gid int) {
+	r0, _, _ := RawSyscall(SYS_GETGID, 0, 0, 0)
+	gid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpgid(pid int) (pgid int, err error) {
+	r0, _, e1 := RawSyscall(SYS_GETPGID, uintptr(pid), 0, 0)
+	pgid = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpgrp() (pgrp int) {
+	r0, _, _ := RawSyscall(SYS_GETPGRP, 0, 0, 0)
+	pgrp = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpid() (pid int) {
+	r0, _, _ := RawSyscall(SYS_GETPID, 0, 0, 0)
+	pid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getppid() (ppid int) {
+	r0, _, _ := RawSyscall(SYS_GETPPID, 0, 0, 0)
+	ppid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpriority(which int, who int) (prio int, err error) {
+	r0, _, e1 := Syscall(SYS_GETPRIORITY, uintptr(which), uintptr(who), 0)
+	prio = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getrlimit(which int, lim *Rlimit) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getrusage(who int, rusage *Rusage) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETRUSAGE, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getsid(pid int) (sid int, err error) {
+	r0, _, e1 := RawSyscall(SYS_GETSID, uintptr(pid), 0, 0)
+	sid = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Gettimeofday(tv *Timeval) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getuid() (uid int) {
+	r0, _, _ := RawSyscall(SYS_GETUID, 0, 0, 0)
+	uid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Issetugid() (tainted bool) {
+	r0, _, _ := Syscall(SYS_ISSETUGID, 0, 0, 0)
+	tainted = bool(r0 != 0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Kill(pid int, signum Signal) (err error) {
+	_, _, e1 := Syscall(SYS_KILL, uintptr(pid), uintptr(signum), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Kqueue() (fd int, err error) {
+	r0, _, e1 := Syscall(SYS_KQUEUE, 0, 0, 0)
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Lchown(path string, uid int, gid int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_LCHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Link(path string, link string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(link)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_LINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	use(unsafe.Pointer(_p0))
+	use(unsafe.Pointer(_p1))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Listen(s int, backlog int) (err error) {
+	_, _, e1 := Syscall(SYS_LISTEN, uintptr(s), uintptr(backlog), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Lstat(path string, stat *Stat_t) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_LSTAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mkdir(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_MKDIR, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mkfifo(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_MKFIFO, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mknod(path string, mode uint32, dev int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_MKNOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Nanosleep(time *Timespec, leftover *Timespec) (err error) {
+	_, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Open(path string, mode int, perm uint32) (fd int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
+	use(unsafe.Pointer(_p0))
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pathconf(path string, name int) (val int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall(SYS_PATHCONF, uintptr(unsafe.Pointer(_p0)), uintptr(name), 0)
+	use(unsafe.Pointer(_p0))
+	val = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pread(fd int, p []byte, offset int64) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_PREAD, uintptr(fd), uintptr(_p0), uintptr(len(p)), 0, uintptr(offset), uintptr(offset>>32))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_PWRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)), 0, uintptr(offset), uintptr(offset>>32))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func read(fd int, p []byte) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(_p0), uintptr(len(p)))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Readlink(path string, buf []byte) (n int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 unsafe.Pointer
+	if len(buf) > 0 {
+		_p1 = unsafe.Pointer(&buf[0])
+	} else {
+		_p1 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_READLINK, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
+	use(unsafe.Pointer(_p0))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Rename(from string, to string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(from)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(to)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_RENAME, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	use(unsafe.Pointer(_p0))
+	use(unsafe.Pointer(_p1))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Revoke(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_REVOKE, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Rmdir(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_RMDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
+	r0, r1, e1 := Syscall6(SYS_LSEEK, uintptr(fd), 0, uintptr(offset), uintptr(offset>>32), uintptr(whence), 0)
+	newoffset = int64(int64(r1)<<32 | int64(r0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Select(n int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (err error) {
+	_, _, e1 := Syscall6(SYS_SELECT, uintptr(n), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setegid(egid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETEGID, uintptr(egid), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Seteuid(euid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETEUID, uintptr(euid), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setgid(gid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETGID, uintptr(gid), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setpgid(pid int, pgid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETPGID, uintptr(pid), uintptr(pgid), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setpriority(which int, who int, prio int) (err error) {
+	_, _, e1 := Syscall(SYS_SETPRIORITY, uintptr(which), uintptr(who), uintptr(prio))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setregid(rgid int, egid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setreuid(ruid int, euid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setrlimit(which int, lim *Rlimit) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setsid() (pid int, err error) {
+	r0, _, e1 := RawSyscall(SYS_SETSID, 0, 0, 0)
+	pid = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Settimeofday(tp *Timeval) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETTIMEOFDAY, uintptr(unsafe.Pointer(tp)), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setuid(uid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETUID, uintptr(uid), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Stat(path string, stat *Stat_t) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Symlink(path string, link string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(link)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_SYMLINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	use(unsafe.Pointer(_p0))
+	use(unsafe.Pointer(_p1))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Sync() (err error) {
+	_, _, e1 := Syscall(SYS_SYNC, 0, 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Truncate(path string, length int64) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_TRUNCATE, uintptr(unsafe.Pointer(_p0)), 0, uintptr(length), uintptr(length>>32), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Umask(newmask int) (oldmask int) {
+	r0, _, _ := Syscall(SYS_UMASK, uintptr(newmask), 0, 0)
+	oldmask = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Unlink(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UNLINK, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Unmount(path string, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UNMOUNT, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func write(fd int, p []byte) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) {
+	r0, _, e1 := Syscall9(SYS_MMAP, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), 0, uintptr(pos), uintptr(pos>>32), 0)
+	ret = uintptr(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func munmap(addr uintptr, length uintptr) (err error) {
+	_, _, e1 := Syscall(SYS_MUNMAP, uintptr(addr), uintptr(length), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func readlen(fd int, buf *byte, nbuf int) (n int, err error) {
+	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func writelen(fd int, buf *byte, nbuf int) (n int, err error) {
+	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
diff --git a/src/syscall/zsyscall_openbsd_386.go b/src/syscall/zsyscall_openbsd_386.go
new file mode 100644
index 0000000..5b005d2
--- /dev/null
+++ b/src/syscall/zsyscall_openbsd_386.go
@@ -0,0 +1,1291 @@
+// mksyscall.pl -l32 -openbsd syscall_bsd.go syscall_openbsd.go syscall_openbsd_386.go
+// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
+
+package syscall
+
+import "unsafe"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getgroups(ngid int, gid *_Gid_t) (n int, err error) {
+	r0, _, e1 := RawSyscall(SYS_GETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func setgroups(ngid int, gid *_Gid_t) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) {
+	r0, _, e1 := Syscall6(SYS_WAIT4, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0)
+	wpid = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
+	r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
+	_, _, e1 := Syscall(SYS_BIND, uintptr(s), uintptr(addr), uintptr(addrlen))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
+	_, _, e1 := Syscall(SYS_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func socket(domain int, typ int, proto int) (fd int, err error) {
+	r0, _, e1 := RawSyscall(SYS_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto))
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) {
+	_, _, e1 := Syscall6(SYS_GETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) {
+	_, _, e1 := Syscall6(SYS_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETPEERNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETSOCKNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Shutdown(s int, how int) (err error) {
+	_, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(s), uintptr(how), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) {
+	_, _, e1 := RawSyscall6(SYS_SOCKETPAIR, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_RECVFROM, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) {
+	var _p0 unsafe.Pointer
+	if len(buf) > 0 {
+		_p0 = unsafe.Pointer(&buf[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall6(SYS_SENDTO, uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
+	r0, _, e1 := Syscall(SYS_RECVMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
+	r0, _, e1 := Syscall(SYS_SENDMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func kevent(kq int, change unsafe.Pointer, nchange int, event unsafe.Pointer, nevent int, timeout *Timespec) (n int, err error) {
+	r0, _, e1 := Syscall6(SYS_KEVENT, uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout)))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) {
+	var _p0 unsafe.Pointer
+	if len(mib) > 0 {
+		_p0 = unsafe.Pointer(&mib[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall6(SYS___SYSCTL, uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func utimes(path string, timeval *[2]Timeval) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(timeval)), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func futimes(fd int, timeval *[2]Timeval) (err error) {
+	_, _, e1 := Syscall(SYS_FUTIMES, uintptr(fd), uintptr(unsafe.Pointer(timeval)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func fcntl(fd int, cmd int, arg int) (val int, err error) {
+	r0, _, e1 := Syscall(SYS_FCNTL, uintptr(fd), uintptr(cmd), uintptr(arg))
+	val = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func pipe(p *[2]_C_int) (err error) {
+	_, _, e1 := RawSyscall(SYS_PIPE, uintptr(unsafe.Pointer(p)), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getdents(fd int, buf []byte) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(buf) > 0 {
+		_p0 = unsafe.Pointer(&buf[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_GETDENTS, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Access(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_ACCESS, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Adjtime(delta *Timeval, olddelta *Timeval) (err error) {
+	_, _, e1 := Syscall(SYS_ADJTIME, uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chdir(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chflags(path string, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHFLAGS, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chmod(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHMOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chown(path string, uid int, gid int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chroot(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHROOT, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Close(fd int) (err error) {
+	_, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Dup(fd int) (nfd int, err error) {
+	r0, _, e1 := RawSyscall(SYS_DUP, uintptr(fd), 0, 0)
+	nfd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Dup2(from int, to int) (err error) {
+	_, _, e1 := RawSyscall(SYS_DUP2, uintptr(from), uintptr(to), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Exit(code int) {
+	Syscall(SYS_EXIT, uintptr(code), 0, 0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchdir(fd int) (err error) {
+	_, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchflags(fd int, flags int) (err error) {
+	_, _, e1 := Syscall(SYS_FCHFLAGS, uintptr(fd), uintptr(flags), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchmod(fd int, mode uint32) (err error) {
+	_, _, e1 := Syscall(SYS_FCHMOD, uintptr(fd), uintptr(mode), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchown(fd int, uid int, gid int) (err error) {
+	_, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Flock(fd int, how int) (err error) {
+	_, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fpathconf(fd int, name int) (val int, err error) {
+	r0, _, e1 := Syscall(SYS_FPATHCONF, uintptr(fd), uintptr(name), 0)
+	val = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fstat(fd int, stat *Stat_t) (err error) {
+	_, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fstatfs(fd int, stat *Statfs_t) (err error) {
+	_, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fsync(fd int) (err error) {
+	_, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Ftruncate(fd int, length int64) (err error) {
+	_, _, e1 := Syscall6(SYS_FTRUNCATE, uintptr(fd), 0, uintptr(length), uintptr(length>>32), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getegid() (egid int) {
+	r0, _, _ := RawSyscall(SYS_GETEGID, 0, 0, 0)
+	egid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Geteuid() (uid int) {
+	r0, _, _ := RawSyscall(SYS_GETEUID, 0, 0, 0)
+	uid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getgid() (gid int) {
+	r0, _, _ := RawSyscall(SYS_GETGID, 0, 0, 0)
+	gid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpgid(pid int) (pgid int, err error) {
+	r0, _, e1 := RawSyscall(SYS_GETPGID, uintptr(pid), 0, 0)
+	pgid = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpgrp() (pgrp int) {
+	r0, _, _ := RawSyscall(SYS_GETPGRP, 0, 0, 0)
+	pgrp = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpid() (pid int) {
+	r0, _, _ := RawSyscall(SYS_GETPID, 0, 0, 0)
+	pid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getppid() (ppid int) {
+	r0, _, _ := RawSyscall(SYS_GETPPID, 0, 0, 0)
+	ppid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpriority(which int, who int) (prio int, err error) {
+	r0, _, e1 := Syscall(SYS_GETPRIORITY, uintptr(which), uintptr(who), 0)
+	prio = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getrlimit(which int, lim *Rlimit) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getrusage(who int, rusage *Rusage) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETRUSAGE, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getsid(pid int) (sid int, err error) {
+	r0, _, e1 := RawSyscall(SYS_GETSID, uintptr(pid), 0, 0)
+	sid = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Gettimeofday(tv *Timeval) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getuid() (uid int) {
+	r0, _, _ := RawSyscall(SYS_GETUID, 0, 0, 0)
+	uid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Issetugid() (tainted bool) {
+	r0, _, _ := Syscall(SYS_ISSETUGID, 0, 0, 0)
+	tainted = bool(r0 != 0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Kill(pid int, signum Signal) (err error) {
+	_, _, e1 := Syscall(SYS_KILL, uintptr(pid), uintptr(signum), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Kqueue() (fd int, err error) {
+	r0, _, e1 := Syscall(SYS_KQUEUE, 0, 0, 0)
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Lchown(path string, uid int, gid int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_LCHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Link(path string, link string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(link)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_LINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	use(unsafe.Pointer(_p0))
+	use(unsafe.Pointer(_p1))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Listen(s int, backlog int) (err error) {
+	_, _, e1 := Syscall(SYS_LISTEN, uintptr(s), uintptr(backlog), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Lstat(path string, stat *Stat_t) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_LSTAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mkdir(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_MKDIR, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mkfifo(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_MKFIFO, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mknod(path string, mode uint32, dev int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_MKNOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Nanosleep(time *Timespec, leftover *Timespec) (err error) {
+	_, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Open(path string, mode int, perm uint32) (fd int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
+	use(unsafe.Pointer(_p0))
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pathconf(path string, name int) (val int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall(SYS_PATHCONF, uintptr(unsafe.Pointer(_p0)), uintptr(name), 0)
+	use(unsafe.Pointer(_p0))
+	val = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pread(fd int, p []byte, offset int64) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_PREAD, uintptr(fd), uintptr(_p0), uintptr(len(p)), 0, uintptr(offset), uintptr(offset>>32))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_PWRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)), 0, uintptr(offset), uintptr(offset>>32))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func read(fd int, p []byte) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(_p0), uintptr(len(p)))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Readlink(path string, buf []byte) (n int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 unsafe.Pointer
+	if len(buf) > 0 {
+		_p1 = unsafe.Pointer(&buf[0])
+	} else {
+		_p1 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_READLINK, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
+	use(unsafe.Pointer(_p0))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Rename(from string, to string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(from)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(to)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_RENAME, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	use(unsafe.Pointer(_p0))
+	use(unsafe.Pointer(_p1))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Revoke(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_REVOKE, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Rmdir(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_RMDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
+	r0, r1, e1 := Syscall6(SYS_LSEEK, uintptr(fd), 0, uintptr(offset), uintptr(offset>>32), uintptr(whence), 0)
+	newoffset = int64(int64(r1)<<32 | int64(r0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Select(n int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (err error) {
+	_, _, e1 := Syscall6(SYS_SELECT, uintptr(n), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setegid(egid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETEGID, uintptr(egid), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Seteuid(euid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETEUID, uintptr(euid), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setgid(gid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETGID, uintptr(gid), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setlogin(name string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(name)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_SETLOGIN, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setpgid(pid int, pgid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETPGID, uintptr(pid), uintptr(pgid), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setpriority(which int, who int, prio int) (err error) {
+	_, _, e1 := Syscall(SYS_SETPRIORITY, uintptr(which), uintptr(who), uintptr(prio))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setregid(rgid int, egid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setreuid(ruid int, euid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setrlimit(which int, lim *Rlimit) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setsid() (pid int, err error) {
+	r0, _, e1 := RawSyscall(SYS_SETSID, 0, 0, 0)
+	pid = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Settimeofday(tp *Timeval) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETTIMEOFDAY, uintptr(unsafe.Pointer(tp)), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setuid(uid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETUID, uintptr(uid), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Stat(path string, stat *Stat_t) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Statfs(path string, stat *Statfs_t) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_STATFS, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Symlink(path string, link string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(link)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_SYMLINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	use(unsafe.Pointer(_p0))
+	use(unsafe.Pointer(_p1))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Sync() (err error) {
+	_, _, e1 := Syscall(SYS_SYNC, 0, 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Truncate(path string, length int64) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall6(SYS_TRUNCATE, uintptr(unsafe.Pointer(_p0)), 0, uintptr(length), uintptr(length>>32), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Umask(newmask int) (oldmask int) {
+	r0, _, _ := Syscall(SYS_UMASK, uintptr(newmask), 0, 0)
+	oldmask = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Unlink(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UNLINK, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Unmount(path string, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UNMOUNT, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func write(fd int, p []byte) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) {
+	r0, _, e1 := Syscall9(SYS_MMAP, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), 0, uintptr(pos), uintptr(pos>>32), 0)
+	ret = uintptr(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func munmap(addr uintptr, length uintptr) (err error) {
+	_, _, e1 := Syscall(SYS_MUNMAP, uintptr(addr), uintptr(length), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func readlen(fd int, buf *byte, nbuf int) (n int, err error) {
+	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func writelen(fd int, buf *byte, nbuf int) (n int, err error) {
+	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
diff --git a/src/syscall/zsyscall_openbsd_amd64.go b/src/syscall/zsyscall_openbsd_amd64.go
new file mode 100644
index 0000000..ce9397b
--- /dev/null
+++ b/src/syscall/zsyscall_openbsd_amd64.go
@@ -0,0 +1,1291 @@
+// mksyscall.pl -openbsd syscall_bsd.go syscall_openbsd.go syscall_openbsd_amd64.go
+// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
+
+package syscall
+
+import "unsafe"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getgroups(ngid int, gid *_Gid_t) (n int, err error) {
+	r0, _, e1 := RawSyscall(SYS_GETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func setgroups(ngid int, gid *_Gid_t) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETGROUPS, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error) {
+	r0, _, e1 := Syscall6(SYS_WAIT4, uintptr(pid), uintptr(unsafe.Pointer(wstatus)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0)
+	wpid = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
+	r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
+	_, _, e1 := Syscall(SYS_BIND, uintptr(s), uintptr(addr), uintptr(addrlen))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
+	_, _, e1 := Syscall(SYS_CONNECT, uintptr(s), uintptr(addr), uintptr(addrlen))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func socket(domain int, typ int, proto int) (fd int, err error) {
+	r0, _, e1 := RawSyscall(SYS_SOCKET, uintptr(domain), uintptr(typ), uintptr(proto))
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) {
+	_, _, e1 := Syscall6(SYS_GETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) {
+	_, _, e1 := Syscall6(SYS_SETSOCKOPT, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETPEERNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETSOCKNAME, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Shutdown(s int, how int) (err error) {
+	_, _, e1 := Syscall(SYS_SHUTDOWN, uintptr(s), uintptr(how), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) {
+	_, _, e1 := RawSyscall6(SYS_SOCKETPAIR, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_RECVFROM, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) {
+	var _p0 unsafe.Pointer
+	if len(buf) > 0 {
+		_p0 = unsafe.Pointer(&buf[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall6(SYS_SENDTO, uintptr(s), uintptr(_p0), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
+	r0, _, e1 := Syscall(SYS_RECVMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
+	r0, _, e1 := Syscall(SYS_SENDMSG, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func kevent(kq int, change unsafe.Pointer, nchange int, event unsafe.Pointer, nevent int, timeout *Timespec) (n int, err error) {
+	r0, _, e1 := Syscall6(SYS_KEVENT, uintptr(kq), uintptr(change), uintptr(nchange), uintptr(event), uintptr(nevent), uintptr(unsafe.Pointer(timeout)))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) {
+	var _p0 unsafe.Pointer
+	if len(mib) > 0 {
+		_p0 = unsafe.Pointer(&mib[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	_, _, e1 := Syscall6(SYS___SYSCTL, uintptr(_p0), uintptr(len(mib)), uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)), uintptr(unsafe.Pointer(new)), uintptr(newlen))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func utimes(path string, timeval *[2]Timeval) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UTIMES, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(timeval)), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func futimes(fd int, timeval *[2]Timeval) (err error) {
+	_, _, e1 := Syscall(SYS_FUTIMES, uintptr(fd), uintptr(unsafe.Pointer(timeval)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func fcntl(fd int, cmd int, arg int) (val int, err error) {
+	r0, _, e1 := Syscall(SYS_FCNTL, uintptr(fd), uintptr(cmd), uintptr(arg))
+	val = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func pipe(p *[2]_C_int) (err error) {
+	_, _, e1 := RawSyscall(SYS_PIPE, uintptr(unsafe.Pointer(p)), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func getdents(fd int, buf []byte) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(buf) > 0 {
+		_p0 = unsafe.Pointer(&buf[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_GETDENTS, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Access(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_ACCESS, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Adjtime(delta *Timeval, olddelta *Timeval) (err error) {
+	_, _, e1 := Syscall(SYS_ADJTIME, uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chdir(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chflags(path string, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHFLAGS, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chmod(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHMOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chown(path string, uid int, gid int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chroot(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_CHROOT, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Close(fd int) (err error) {
+	_, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Dup(fd int) (nfd int, err error) {
+	r0, _, e1 := RawSyscall(SYS_DUP, uintptr(fd), 0, 0)
+	nfd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Dup2(from int, to int) (err error) {
+	_, _, e1 := RawSyscall(SYS_DUP2, uintptr(from), uintptr(to), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Exit(code int) {
+	Syscall(SYS_EXIT, uintptr(code), 0, 0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchdir(fd int) (err error) {
+	_, _, e1 := Syscall(SYS_FCHDIR, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchflags(fd int, flags int) (err error) {
+	_, _, e1 := Syscall(SYS_FCHFLAGS, uintptr(fd), uintptr(flags), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchmod(fd int, mode uint32) (err error) {
+	_, _, e1 := Syscall(SYS_FCHMOD, uintptr(fd), uintptr(mode), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fchown(fd int, uid int, gid int) (err error) {
+	_, _, e1 := Syscall(SYS_FCHOWN, uintptr(fd), uintptr(uid), uintptr(gid))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Flock(fd int, how int) (err error) {
+	_, _, e1 := Syscall(SYS_FLOCK, uintptr(fd), uintptr(how), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fpathconf(fd int, name int) (val int, err error) {
+	r0, _, e1 := Syscall(SYS_FPATHCONF, uintptr(fd), uintptr(name), 0)
+	val = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fstat(fd int, stat *Stat_t) (err error) {
+	_, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fstatfs(fd int, stat *Statfs_t) (err error) {
+	_, _, e1 := Syscall(SYS_FSTATFS, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fsync(fd int) (err error) {
+	_, _, e1 := Syscall(SYS_FSYNC, uintptr(fd), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Ftruncate(fd int, length int64) (err error) {
+	_, _, e1 := Syscall(SYS_FTRUNCATE, uintptr(fd), 0, uintptr(length))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getegid() (egid int) {
+	r0, _, _ := RawSyscall(SYS_GETEGID, 0, 0, 0)
+	egid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Geteuid() (uid int) {
+	r0, _, _ := RawSyscall(SYS_GETEUID, 0, 0, 0)
+	uid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getgid() (gid int) {
+	r0, _, _ := RawSyscall(SYS_GETGID, 0, 0, 0)
+	gid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpgid(pid int) (pgid int, err error) {
+	r0, _, e1 := RawSyscall(SYS_GETPGID, uintptr(pid), 0, 0)
+	pgid = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpgrp() (pgrp int) {
+	r0, _, _ := RawSyscall(SYS_GETPGRP, 0, 0, 0)
+	pgrp = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpid() (pid int) {
+	r0, _, _ := RawSyscall(SYS_GETPID, 0, 0, 0)
+	pid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getppid() (ppid int) {
+	r0, _, _ := RawSyscall(SYS_GETPPID, 0, 0, 0)
+	ppid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getpriority(which int, who int) (prio int, err error) {
+	r0, _, e1 := Syscall(SYS_GETPRIORITY, uintptr(which), uintptr(who), 0)
+	prio = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getrlimit(which int, lim *Rlimit) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getrusage(who int, rusage *Rusage) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETRUSAGE, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getsid(pid int) (sid int, err error) {
+	r0, _, e1 := RawSyscall(SYS_GETSID, uintptr(pid), 0, 0)
+	sid = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Gettimeofday(tv *Timeval) (err error) {
+	_, _, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tv)), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Getuid() (uid int) {
+	r0, _, _ := RawSyscall(SYS_GETUID, 0, 0, 0)
+	uid = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Issetugid() (tainted bool) {
+	r0, _, _ := Syscall(SYS_ISSETUGID, 0, 0, 0)
+	tainted = bool(r0 != 0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Kill(pid int, signum Signal) (err error) {
+	_, _, e1 := Syscall(SYS_KILL, uintptr(pid), uintptr(signum), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Kqueue() (fd int, err error) {
+	r0, _, e1 := Syscall(SYS_KQUEUE, 0, 0, 0)
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Lchown(path string, uid int, gid int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_LCHOWN, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid))
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Link(path string, link string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(link)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_LINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	use(unsafe.Pointer(_p0))
+	use(unsafe.Pointer(_p1))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Listen(s int, backlog int) (err error) {
+	_, _, e1 := Syscall(SYS_LISTEN, uintptr(s), uintptr(backlog), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Lstat(path string, stat *Stat_t) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_LSTAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mkdir(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_MKDIR, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mkfifo(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_MKFIFO, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mknod(path string, mode uint32, dev int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_MKNOD, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev))
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Nanosleep(time *Timespec, leftover *Timespec) (err error) {
+	_, _, e1 := Syscall(SYS_NANOSLEEP, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Open(path string, mode int, perm uint32) (fd int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
+	use(unsafe.Pointer(_p0))
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pathconf(path string, name int) (val int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall(SYS_PATHCONF, uintptr(unsafe.Pointer(_p0)), uintptr(name), 0)
+	use(unsafe.Pointer(_p0))
+	val = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pread(fd int, p []byte, offset int64) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_PREAD, uintptr(fd), uintptr(_p0), uintptr(len(p)), 0, uintptr(offset), 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_PWRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)), 0, uintptr(offset), 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func read(fd int, p []byte) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(_p0), uintptr(len(p)))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Readlink(path string, buf []byte) (n int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 unsafe.Pointer
+	if len(buf) > 0 {
+		_p1 = unsafe.Pointer(&buf[0])
+	} else {
+		_p1 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_READLINK, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(buf)))
+	use(unsafe.Pointer(_p0))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Rename(from string, to string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(from)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(to)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_RENAME, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	use(unsafe.Pointer(_p0))
+	use(unsafe.Pointer(_p1))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Revoke(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_REVOKE, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Rmdir(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_RMDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
+	r0, _, e1 := Syscall6(SYS_LSEEK, uintptr(fd), 0, uintptr(offset), uintptr(whence), 0, 0)
+	newoffset = int64(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Select(n int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (err error) {
+	_, _, e1 := Syscall6(SYS_SELECT, uintptr(n), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setegid(egid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETEGID, uintptr(egid), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Seteuid(euid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETEUID, uintptr(euid), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setgid(gid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETGID, uintptr(gid), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setlogin(name string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(name)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_SETLOGIN, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setpgid(pid int, pgid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETPGID, uintptr(pid), uintptr(pgid), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setpriority(which int, who int, prio int) (err error) {
+	_, _, e1 := Syscall(SYS_SETPRIORITY, uintptr(which), uintptr(who), uintptr(prio))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setregid(rgid int, egid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETREGID, uintptr(rgid), uintptr(egid), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setreuid(ruid int, euid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETREUID, uintptr(ruid), uintptr(euid), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setrlimit(which int, lim *Rlimit) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETRLIMIT, uintptr(which), uintptr(unsafe.Pointer(lim)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setsid() (pid int, err error) {
+	r0, _, e1 := RawSyscall(SYS_SETSID, 0, 0, 0)
+	pid = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Settimeofday(tp *Timeval) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETTIMEOFDAY, uintptr(unsafe.Pointer(tp)), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Setuid(uid int) (err error) {
+	_, _, e1 := RawSyscall(SYS_SETUID, uintptr(uid), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Stat(path string, stat *Stat_t) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Statfs(path string, stat *Statfs_t) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_STATFS, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Symlink(path string, link string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(link)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_SYMLINK, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0)
+	use(unsafe.Pointer(_p0))
+	use(unsafe.Pointer(_p1))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Sync() (err error) {
+	_, _, e1 := Syscall(SYS_SYNC, 0, 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Truncate(path string, length int64) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_TRUNCATE, uintptr(unsafe.Pointer(_p0)), 0, uintptr(length))
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Umask(newmask int) (oldmask int) {
+	r0, _, _ := Syscall(SYS_UMASK, uintptr(newmask), 0, 0)
+	oldmask = int(r0)
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Unlink(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UNLINK, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Unmount(path string, flags int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := Syscall(SYS_UNMOUNT, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func write(fd int, p []byte) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) {
+	r0, _, e1 := Syscall9(SYS_MMAP, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), 0, uintptr(pos), 0, 0)
+	ret = uintptr(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func munmap(addr uintptr, length uintptr) (err error) {
+	_, _, e1 := Syscall(SYS_MUNMAP, uintptr(addr), uintptr(length), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func readlen(fd int, buf *byte, nbuf int) (n int, err error) {
+	r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func writelen(fd int, buf *byte, nbuf int) (n int, err error) {
+	r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
diff --git a/src/syscall/zsyscall_plan9_386.go b/src/syscall/zsyscall_plan9_386.go
new file mode 100644
index 0000000..44b74d7
--- /dev/null
+++ b/src/syscall/zsyscall_plan9_386.go
@@ -0,0 +1,292 @@
+// mksyscall.pl -l32 -plan9 syscall_plan9.go
+// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
+
+package syscall
+
+import "unsafe"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func fd2path(fd int, buf []byte) (err error) {
+	var _p0 unsafe.Pointer
+	if len(buf) > 0 {
+		_p0 = unsafe.Pointer(&buf[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_FD2PATH, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func pipe(p *[2]_C_int) (err error) {
+	r0, _, e1 := Syscall(SYS_PIPE, uintptr(unsafe.Pointer(p)), 0, 0)
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func await(s []byte) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(s) > 0 {
+		_p0 = unsafe.Pointer(&s[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_AWAIT, uintptr(_p0), uintptr(len(s)), 0)
+	n = int(r0)
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Dup(oldfd int, newfd int) (fd int, err error) {
+	r0, _, e1 := Syscall(SYS_DUP, uintptr(oldfd), uintptr(newfd), 0)
+	fd = int(r0)
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Open(path string, mode int) (fd int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	use(unsafe.Pointer(_p0))
+	fd = int(r0)
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Create(path string, mode int, perm uint32) (fd int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall(SYS_CREATE, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
+	use(unsafe.Pointer(_p0))
+	fd = int(r0)
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Remove(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall(SYS_REMOVE, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pread(fd int, p []byte, offset int64) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_PREAD, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), uintptr(offset>>32), 0)
+	n = int(r0)
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_PWRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), uintptr(offset>>32), 0)
+	n = int(r0)
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Close(fd int) (err error) {
+	r0, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0)
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chdir(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Bind(name string, old string, flag int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(name)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(old)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall(SYS_BIND, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(flag))
+	use(unsafe.Pointer(_p0))
+	use(unsafe.Pointer(_p1))
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mount(fd int, afd int, old string, flag int, aname string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(old)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(aname)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall6(SYS_MOUNT, uintptr(fd), uintptr(afd), uintptr(unsafe.Pointer(_p0)), uintptr(flag), uintptr(unsafe.Pointer(_p1)), 0)
+	use(unsafe.Pointer(_p0))
+	use(unsafe.Pointer(_p1))
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Stat(path string, edir []byte) (n int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 unsafe.Pointer
+	if len(edir) > 0 {
+		_p1 = unsafe.Pointer(&edir[0])
+	} else {
+		_p1 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(edir)))
+	use(unsafe.Pointer(_p0))
+	n = int(r0)
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fstat(fd int, edir []byte) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(edir) > 0 {
+		_p0 = unsafe.Pointer(&edir[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(_p0), uintptr(len(edir)))
+	n = int(r0)
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Wstat(path string, edir []byte) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 unsafe.Pointer
+	if len(edir) > 0 {
+		_p1 = unsafe.Pointer(&edir[0])
+	} else {
+		_p1 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_WSTAT, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(edir)))
+	use(unsafe.Pointer(_p0))
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fwstat(fd int, edir []byte) (err error) {
+	var _p0 unsafe.Pointer
+	if len(edir) > 0 {
+		_p0 = unsafe.Pointer(&edir[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_FWSTAT, uintptr(fd), uintptr(_p0), uintptr(len(edir)))
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
diff --git a/src/syscall/zsyscall_plan9_amd64.go b/src/syscall/zsyscall_plan9_amd64.go
new file mode 100644
index 0000000..44b74d7
--- /dev/null
+++ b/src/syscall/zsyscall_plan9_amd64.go
@@ -0,0 +1,292 @@
+// mksyscall.pl -l32 -plan9 syscall_plan9.go
+// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
+
+package syscall
+
+import "unsafe"
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func fd2path(fd int, buf []byte) (err error) {
+	var _p0 unsafe.Pointer
+	if len(buf) > 0 {
+		_p0 = unsafe.Pointer(&buf[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_FD2PATH, uintptr(fd), uintptr(_p0), uintptr(len(buf)))
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func pipe(p *[2]_C_int) (err error) {
+	r0, _, e1 := Syscall(SYS_PIPE, uintptr(unsafe.Pointer(p)), 0, 0)
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func await(s []byte) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(s) > 0 {
+		_p0 = unsafe.Pointer(&s[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_AWAIT, uintptr(_p0), uintptr(len(s)), 0)
+	n = int(r0)
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Dup(oldfd int, newfd int) (fd int, err error) {
+	r0, _, e1 := Syscall(SYS_DUP, uintptr(oldfd), uintptr(newfd), 0)
+	fd = int(r0)
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Open(path string, mode int) (fd int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall(SYS_OPEN, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0)
+	use(unsafe.Pointer(_p0))
+	fd = int(r0)
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Create(path string, mode int, perm uint32) (fd int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall(SYS_CREATE, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm))
+	use(unsafe.Pointer(_p0))
+	fd = int(r0)
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Remove(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall(SYS_REMOVE, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pread(fd int, p []byte, offset int64) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_PREAD, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), uintptr(offset>>32), 0)
+	n = int(r0)
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(p) > 0 {
+		_p0 = unsafe.Pointer(&p[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall6(SYS_PWRITE, uintptr(fd), uintptr(_p0), uintptr(len(p)), uintptr(offset), uintptr(offset>>32), 0)
+	n = int(r0)
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Close(fd int) (err error) {
+	r0, _, e1 := Syscall(SYS_CLOSE, uintptr(fd), 0, 0)
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Chdir(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall(SYS_CHDIR, uintptr(unsafe.Pointer(_p0)), 0, 0)
+	use(unsafe.Pointer(_p0))
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Bind(name string, old string, flag int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(name)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(old)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall(SYS_BIND, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(flag))
+	use(unsafe.Pointer(_p0))
+	use(unsafe.Pointer(_p1))
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Mount(fd int, afd int, old string, flag int, aname string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(old)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(aname)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := Syscall6(SYS_MOUNT, uintptr(fd), uintptr(afd), uintptr(unsafe.Pointer(_p0)), uintptr(flag), uintptr(unsafe.Pointer(_p1)), 0)
+	use(unsafe.Pointer(_p0))
+	use(unsafe.Pointer(_p1))
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Stat(path string, edir []byte) (n int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 unsafe.Pointer
+	if len(edir) > 0 {
+		_p1 = unsafe.Pointer(&edir[0])
+	} else {
+		_p1 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_STAT, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(edir)))
+	use(unsafe.Pointer(_p0))
+	n = int(r0)
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fstat(fd int, edir []byte) (n int, err error) {
+	var _p0 unsafe.Pointer
+	if len(edir) > 0 {
+		_p0 = unsafe.Pointer(&edir[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_FSTAT, uintptr(fd), uintptr(_p0), uintptr(len(edir)))
+	n = int(r0)
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Wstat(path string, edir []byte) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 unsafe.Pointer
+	if len(edir) > 0 {
+		_p1 = unsafe.Pointer(&edir[0])
+	} else {
+		_p1 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_WSTAT, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(edir)))
+	use(unsafe.Pointer(_p0))
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
+func Fwstat(fd int, edir []byte) (err error) {
+	var _p0 unsafe.Pointer
+	if len(edir) > 0 {
+		_p0 = unsafe.Pointer(&edir[0])
+	} else {
+		_p0 = unsafe.Pointer(&_zero)
+	}
+	r0, _, e1 := Syscall(SYS_FWSTAT, uintptr(fd), uintptr(_p0), uintptr(len(edir)))
+	if int32(r0) == -1 {
+		err = e1
+	}
+	return
+}
diff --git a/src/syscall/zsyscall_solaris_amd64.go b/src/syscall/zsyscall_solaris_amd64.go
new file mode 100644
index 0000000..43b224a
--- /dev/null
+++ b/src/syscall/zsyscall_solaris_amd64.go
@@ -0,0 +1,906 @@
+// mksyscall_solaris.pl syscall_solaris.go syscall_solaris_amd64.go
+// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
+
+package syscall
+
+import "unsafe"
+
+var (
+	modlibc      = newLazySO("libc.so")
+	modlibsocket = newLazySO("libsocket.so")
+
+	procgetgroups    = modlibc.NewProc("getgroups")
+	procsetgroups    = modlibc.NewProc("setgroups")
+	procfcntl        = modlibc.NewProc("fcntl")
+	procaccept       = modlibsocket.NewProc("accept")
+	procsendmsg      = modlibsocket.NewProc("sendmsg")
+	procAccess       = modlibc.NewProc("access")
+	procAdjtime      = modlibc.NewProc("adjtime")
+	procChdir        = modlibc.NewProc("chdir")
+	procChmod        = modlibc.NewProc("chmod")
+	procChown        = modlibc.NewProc("chown")
+	procChroot       = modlibc.NewProc("chroot")
+	procClose        = modlibc.NewProc("close")
+	procDup          = modlibc.NewProc("dup")
+	procExit         = modlibc.NewProc("exit")
+	procFchdir       = modlibc.NewProc("fchdir")
+	procFchmod       = modlibc.NewProc("fchmod")
+	procFchown       = modlibc.NewProc("fchown")
+	procFpathconf    = modlibc.NewProc("fpathconf")
+	procFstat        = modlibc.NewProc("fstat")
+	procGetdents     = modlibc.NewProc("getdents")
+	procGetgid       = modlibc.NewProc("getgid")
+	procGetpid       = modlibc.NewProc("getpid")
+	procGeteuid      = modlibc.NewProc("geteuid")
+	procGetegid      = modlibc.NewProc("getegid")
+	procGetppid      = modlibc.NewProc("getppid")
+	procGetpriority  = modlibc.NewProc("getpriority")
+	procGetrlimit    = modlibc.NewProc("getrlimit")
+	procGettimeofday = modlibc.NewProc("gettimeofday")
+	procGetuid       = modlibc.NewProc("getuid")
+	procKill         = modlibc.NewProc("kill")
+	procLchown       = modlibc.NewProc("lchown")
+	procLink         = modlibc.NewProc("link")
+	proclisten       = modlibsocket.NewProc("listen")
+	procLstat        = modlibc.NewProc("lstat")
+	procMkdir        = modlibc.NewProc("mkdir")
+	procMknod        = modlibc.NewProc("mknod")
+	procNanosleep    = modlibc.NewProc("nanosleep")
+	procOpen         = modlibc.NewProc("open")
+	procPathconf     = modlibc.NewProc("pathconf")
+	procPread        = modlibc.NewProc("pread")
+	procPwrite       = modlibc.NewProc("pwrite")
+	procread         = modlibc.NewProc("read")
+	procReadlink     = modlibc.NewProc("readlink")
+	procRename       = modlibc.NewProc("rename")
+	procRmdir        = modlibc.NewProc("rmdir")
+	proclseek        = modlibc.NewProc("lseek")
+	procSetegid      = modlibc.NewProc("setegid")
+	procSeteuid      = modlibc.NewProc("seteuid")
+	procSetgid       = modlibc.NewProc("setgid")
+	procSetpgid      = modlibc.NewProc("setpgid")
+	procSetpriority  = modlibc.NewProc("setpriority")
+	procSetregid     = modlibc.NewProc("setregid")
+	procSetreuid     = modlibc.NewProc("setreuid")
+	procSetrlimit    = modlibc.NewProc("setrlimit")
+	procSetsid       = modlibc.NewProc("setsid")
+	procSetuid       = modlibc.NewProc("setuid")
+	procshutdown     = modlibsocket.NewProc("shutdown")
+	procStat         = modlibc.NewProc("stat")
+	procSymlink      = modlibc.NewProc("symlink")
+	procSync         = modlibc.NewProc("sync")
+	procTruncate     = modlibc.NewProc("truncate")
+	procFsync        = modlibc.NewProc("fsync")
+	procFtruncate    = modlibc.NewProc("ftruncate")
+	procUmask        = modlibc.NewProc("umask")
+	procUnlink       = modlibc.NewProc("unlink")
+	procUtimes       = modlibc.NewProc("utimes")
+	procbind         = modlibsocket.NewProc("bind")
+	procconnect      = modlibsocket.NewProc("connect")
+	procmmap         = modlibc.NewProc("mmap")
+	procmunmap       = modlibc.NewProc("munmap")
+	procsendto       = modlibsocket.NewProc("sendto")
+	procsocket       = modlibsocket.NewProc("socket")
+	procsocketpair   = modlibsocket.NewProc("socketpair")
+	procwrite        = modlibc.NewProc("write")
+	procgetsockopt   = modlibsocket.NewProc("getsockopt")
+	procgetpeername  = modlibsocket.NewProc("getpeername")
+	procgetsockname  = modlibsocket.NewProc("getsockname")
+	procsetsockopt   = modlibsocket.NewProc("setsockopt")
+	procrecvfrom     = modlibsocket.NewProc("recvfrom")
+	procrecvmsg      = modlibsocket.NewProc("recvmsg")
+)
+
+func getgroups(ngid int, gid *_Gid_t) (n int, err error) {
+	r0, _, e1 := rawSysvicall6(procgetgroups.Addr(), 2, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0, 0, 0, 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func setgroups(ngid int, gid *_Gid_t) (err error) {
+	_, _, e1 := rawSysvicall6(procsetgroups.Addr(), 2, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0, 0, 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func fcntl(fd int, cmd int, arg int) (val int, err error) {
+	r0, _, e1 := sysvicall6(procfcntl.Addr(), 3, uintptr(fd), uintptr(cmd), uintptr(arg), 0, 0, 0)
+	val = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
+	r0, _, e1 := sysvicall6(procaccept.Addr(), 3, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), 0, 0, 0)
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) {
+	r0, _, e1 := sysvicall6(procsendmsg.Addr(), 3, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags), 0, 0, 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func Access(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := sysvicall6(procAccess.Addr(), 2, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0, 0, 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func Adjtime(delta *Timeval, olddelta *Timeval) (err error) {
+	_, _, e1 := sysvicall6(procAdjtime.Addr(), 2, uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0, 0, 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func Chdir(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := sysvicall6(procChdir.Addr(), 1, uintptr(unsafe.Pointer(_p0)), 0, 0, 0, 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func Chmod(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := sysvicall6(procChmod.Addr(), 2, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0, 0, 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func Chown(path string, uid int, gid int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := sysvicall6(procChown.Addr(), 3, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid), 0, 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func Chroot(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := sysvicall6(procChroot.Addr(), 1, uintptr(unsafe.Pointer(_p0)), 0, 0, 0, 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func Close(fd int) (err error) {
+	_, _, e1 := sysvicall6(procClose.Addr(), 1, uintptr(fd), 0, 0, 0, 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func Dup(fd int) (nfd int, err error) {
+	r0, _, e1 := sysvicall6(procDup.Addr(), 1, uintptr(fd), 0, 0, 0, 0, 0)
+	nfd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func Exit(code int) {
+	sysvicall6(procExit.Addr(), 1, uintptr(code), 0, 0, 0, 0, 0)
+	return
+}
+
+func Fchdir(fd int) (err error) {
+	_, _, e1 := sysvicall6(procFchdir.Addr(), 1, uintptr(fd), 0, 0, 0, 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func Fchmod(fd int, mode uint32) (err error) {
+	_, _, e1 := sysvicall6(procFchmod.Addr(), 2, uintptr(fd), uintptr(mode), 0, 0, 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func Fchown(fd int, uid int, gid int) (err error) {
+	_, _, e1 := sysvicall6(procFchown.Addr(), 3, uintptr(fd), uintptr(uid), uintptr(gid), 0, 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func Fpathconf(fd int, name int) (val int, err error) {
+	r0, _, e1 := sysvicall6(procFpathconf.Addr(), 2, uintptr(fd), uintptr(name), 0, 0, 0, 0)
+	val = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func Fstat(fd int, stat *Stat_t) (err error) {
+	_, _, e1 := sysvicall6(procFstat.Addr(), 2, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0, 0, 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func Getdents(fd int, buf []byte, basep *uintptr) (n int, err error) {
+	var _p0 *byte
+	if len(buf) > 0 {
+		_p0 = &buf[0]
+	}
+	r0, _, e1 := sysvicall6(procGetdents.Addr(), 4, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(unsafe.Pointer(basep)), 0, 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func Getgid() (gid int) {
+	r0, _, _ := rawSysvicall6(procGetgid.Addr(), 0, 0, 0, 0, 0, 0, 0)
+	gid = int(r0)
+	return
+}
+
+func Getpid() (pid int) {
+	r0, _, _ := rawSysvicall6(procGetpid.Addr(), 0, 0, 0, 0, 0, 0, 0)
+	pid = int(r0)
+	return
+}
+
+func Geteuid() (euid int) {
+	r0, _, _ := sysvicall6(procGeteuid.Addr(), 0, 0, 0, 0, 0, 0, 0)
+	euid = int(r0)
+	return
+}
+
+func Getegid() (egid int) {
+	r0, _, _ := sysvicall6(procGetegid.Addr(), 0, 0, 0, 0, 0, 0, 0)
+	egid = int(r0)
+	return
+}
+
+func Getppid() (ppid int) {
+	r0, _, _ := sysvicall6(procGetppid.Addr(), 0, 0, 0, 0, 0, 0, 0)
+	ppid = int(r0)
+	return
+}
+
+func Getpriority(which int, who int) (n int, err error) {
+	r0, _, e1 := sysvicall6(procGetpriority.Addr(), 2, uintptr(which), uintptr(who), 0, 0, 0, 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func Getrlimit(which int, lim *Rlimit) (err error) {
+	_, _, e1 := rawSysvicall6(procGetrlimit.Addr(), 2, uintptr(which), uintptr(unsafe.Pointer(lim)), 0, 0, 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func Gettimeofday(tv *Timeval) (err error) {
+	_, _, e1 := rawSysvicall6(procGettimeofday.Addr(), 1, uintptr(unsafe.Pointer(tv)), 0, 0, 0, 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func Getuid() (uid int) {
+	r0, _, _ := rawSysvicall6(procGetuid.Addr(), 0, 0, 0, 0, 0, 0, 0)
+	uid = int(r0)
+	return
+}
+
+func Kill(pid int, signum Signal) (err error) {
+	_, _, e1 := sysvicall6(procKill.Addr(), 2, uintptr(pid), uintptr(signum), 0, 0, 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func Lchown(path string, uid int, gid int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := sysvicall6(procLchown.Addr(), 3, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid), 0, 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func Link(path string, link string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(link)
+	if err != nil {
+		return
+	}
+	_, _, e1 := sysvicall6(procLink.Addr(), 2, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0, 0, 0, 0)
+	use(unsafe.Pointer(_p0))
+	use(unsafe.Pointer(_p1))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func Listen(s int, backlog int) (err error) {
+	_, _, e1 := sysvicall6(proclisten.Addr(), 2, uintptr(s), uintptr(backlog), 0, 0, 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func Lstat(path string, stat *Stat_t) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := sysvicall6(procLstat.Addr(), 2, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0, 0, 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func Mkdir(path string, mode uint32) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := sysvicall6(procMkdir.Addr(), 2, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0, 0, 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func Mknod(path string, mode uint32, dev int) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := sysvicall6(procMknod.Addr(), 3, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev), 0, 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func Nanosleep(time *Timespec, leftover *Timespec) (err error) {
+	_, _, e1 := sysvicall6(procNanosleep.Addr(), 2, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0, 0, 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func Open(path string, mode int, perm uint32) (fd int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := sysvicall6(procOpen.Addr(), 3, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm), 0, 0, 0)
+	use(unsafe.Pointer(_p0))
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func Pathconf(path string, name int) (val int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	r0, _, e1 := sysvicall6(procPathconf.Addr(), 2, uintptr(unsafe.Pointer(_p0)), uintptr(name), 0, 0, 0, 0)
+	use(unsafe.Pointer(_p0))
+	val = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func Pread(fd int, p []byte, offset int64) (n int, err error) {
+	var _p0 *byte
+	if len(p) > 0 {
+		_p0 = &p[0]
+	}
+	r0, _, e1 := sysvicall6(procPread.Addr(), 4, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(len(p)), uintptr(offset), 0, 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func Pwrite(fd int, p []byte, offset int64) (n int, err error) {
+	var _p0 *byte
+	if len(p) > 0 {
+		_p0 = &p[0]
+	}
+	r0, _, e1 := sysvicall6(procPwrite.Addr(), 4, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(len(p)), uintptr(offset), 0, 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func read(fd int, p []byte) (n int, err error) {
+	var _p0 *byte
+	if len(p) > 0 {
+		_p0 = &p[0]
+	}
+	r0, _, e1 := sysvicall6(procread.Addr(), 3, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(len(p)), 0, 0, 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func Readlink(path string, buf []byte) (n int, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	if len(buf) > 0 {
+		_p1 = &buf[0]
+	}
+	r0, _, e1 := sysvicall6(procReadlink.Addr(), 3, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(len(buf)), 0, 0, 0)
+	use(unsafe.Pointer(_p0))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func Rename(from string, to string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(from)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(to)
+	if err != nil {
+		return
+	}
+	_, _, e1 := sysvicall6(procRename.Addr(), 2, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0, 0, 0, 0)
+	use(unsafe.Pointer(_p0))
+	use(unsafe.Pointer(_p1))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func Rmdir(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := sysvicall6(procRmdir.Addr(), 1, uintptr(unsafe.Pointer(_p0)), 0, 0, 0, 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
+	r0, _, e1 := sysvicall6(proclseek.Addr(), 3, uintptr(fd), uintptr(offset), uintptr(whence), 0, 0, 0)
+	newoffset = int64(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func Setegid(egid int) (err error) {
+	_, _, e1 := rawSysvicall6(procSetegid.Addr(), 1, uintptr(egid), 0, 0, 0, 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func Seteuid(euid int) (err error) {
+	_, _, e1 := rawSysvicall6(procSeteuid.Addr(), 1, uintptr(euid), 0, 0, 0, 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func Setgid(gid int) (err error) {
+	_, _, e1 := rawSysvicall6(procSetgid.Addr(), 1, uintptr(gid), 0, 0, 0, 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func Setpgid(pid int, pgid int) (err error) {
+	_, _, e1 := rawSysvicall6(procSetpgid.Addr(), 2, uintptr(pid), uintptr(pgid), 0, 0, 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func Setpriority(which int, who int, prio int) (err error) {
+	_, _, e1 := sysvicall6(procSetpriority.Addr(), 3, uintptr(which), uintptr(who), uintptr(prio), 0, 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func Setregid(rgid int, egid int) (err error) {
+	_, _, e1 := rawSysvicall6(procSetregid.Addr(), 2, uintptr(rgid), uintptr(egid), 0, 0, 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func Setreuid(ruid int, euid int) (err error) {
+	_, _, e1 := rawSysvicall6(procSetreuid.Addr(), 2, uintptr(ruid), uintptr(euid), 0, 0, 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func Setrlimit(which int, lim *Rlimit) (err error) {
+	_, _, e1 := rawSysvicall6(procSetrlimit.Addr(), 2, uintptr(which), uintptr(unsafe.Pointer(lim)), 0, 0, 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func Setsid() (pid int, err error) {
+	r0, _, e1 := rawSysvicall6(procSetsid.Addr(), 0, 0, 0, 0, 0, 0, 0)
+	pid = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func Setuid(uid int) (err error) {
+	_, _, e1 := rawSysvicall6(procSetuid.Addr(), 1, uintptr(uid), 0, 0, 0, 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func Shutdown(s int, how int) (err error) {
+	_, _, e1 := sysvicall6(procshutdown.Addr(), 2, uintptr(s), uintptr(how), 0, 0, 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func Stat(path string, stat *Stat_t) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := sysvicall6(procStat.Addr(), 2, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0, 0, 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func Symlink(path string, link string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(link)
+	if err != nil {
+		return
+	}
+	_, _, e1 := sysvicall6(procSymlink.Addr(), 2, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0, 0, 0, 0)
+	use(unsafe.Pointer(_p0))
+	use(unsafe.Pointer(_p1))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func Sync() (err error) {
+	_, _, e1 := sysvicall6(procSync.Addr(), 0, 0, 0, 0, 0, 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func Truncate(path string, length int64) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := sysvicall6(procTruncate.Addr(), 2, uintptr(unsafe.Pointer(_p0)), uintptr(length), 0, 0, 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func Fsync(fd int) (err error) {
+	_, _, e1 := sysvicall6(procFsync.Addr(), 1, uintptr(fd), 0, 0, 0, 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func Ftruncate(fd int, length int64) (err error) {
+	_, _, e1 := sysvicall6(procFtruncate.Addr(), 2, uintptr(fd), uintptr(length), 0, 0, 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func Umask(newmask int) (oldmask int) {
+	r0, _, _ := sysvicall6(procUmask.Addr(), 1, uintptr(newmask), 0, 0, 0, 0, 0)
+	oldmask = int(r0)
+	return
+}
+
+func Unlink(path string) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := sysvicall6(procUnlink.Addr(), 1, uintptr(unsafe.Pointer(_p0)), 0, 0, 0, 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func Utimes(path string, times *[2]Timeval) (err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(path)
+	if err != nil {
+		return
+	}
+	_, _, e1 := sysvicall6(procUtimes.Addr(), 2, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), 0, 0, 0, 0)
+	use(unsafe.Pointer(_p0))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
+	_, _, e1 := sysvicall6(procbind.Addr(), 3, uintptr(s), uintptr(addr), uintptr(addrlen), 0, 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) {
+	_, _, e1 := sysvicall6(procconnect.Addr(), 3, uintptr(s), uintptr(addr), uintptr(addrlen), 0, 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) {
+	r0, _, e1 := sysvicall6(procmmap.Addr(), 6, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), uintptr(pos))
+	ret = uintptr(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func munmap(addr uintptr, length uintptr) (err error) {
+	_, _, e1 := sysvicall6(procmunmap.Addr(), 2, uintptr(addr), uintptr(length), 0, 0, 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) (err error) {
+	var _p0 *byte
+	if len(buf) > 0 {
+		_p0 = &buf[0]
+	}
+	_, _, e1 := sysvicall6(procsendto.Addr(), 6, uintptr(s), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen))
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func socket(domain int, typ int, proto int) (fd int, err error) {
+	r0, _, e1 := sysvicall6(procsocket.Addr(), 3, uintptr(domain), uintptr(typ), uintptr(proto), 0, 0, 0)
+	fd = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) {
+	_, _, e1 := rawSysvicall6(procsocketpair.Addr(), 4, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func write(fd int, p []byte) (n int, err error) {
+	var _p0 *byte
+	if len(p) > 0 {
+		_p0 = &p[0]
+	}
+	r0, _, e1 := sysvicall6(procwrite.Addr(), 3, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(len(p)), 0, 0, 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) {
+	_, _, e1 := sysvicall6(procgetsockopt.Addr(), 5, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
+	_, _, e1 := rawSysvicall6(procgetpeername.Addr(), 3, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), 0, 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) {
+	_, _, e1 := sysvicall6(procgetsockname.Addr(), 3, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), 0, 0, 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) {
+	_, _, e1 := sysvicall6(procsetsockopt.Addr(), 5, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) {
+	var _p0 *byte
+	if len(p) > 0 {
+		_p0 = &p[0]
+	}
+	r0, _, e1 := sysvicall6(procrecvfrom.Addr(), 6, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
+func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) {
+	r0, _, e1 := sysvicall6(procrecvmsg.Addr(), 3, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags), 0, 0, 0)
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
diff --git a/src/syscall/zsyscall_windows.go b/src/syscall/zsyscall_windows.go
new file mode 100644
index 0000000..afc28f9
--- /dev/null
+++ b/src/syscall/zsyscall_windows.go
@@ -0,0 +1,1870 @@
+// go build mksyscall_windows.go && ./mksyscall_windows syscall_windows.go security_windows.go
+// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
+
+package syscall
+
+import "unsafe"
+
+var (
+	modkernel32 = NewLazyDLL("kernel32.dll")
+	modadvapi32 = NewLazyDLL("advapi32.dll")
+	modshell32  = NewLazyDLL("shell32.dll")
+	modmswsock  = NewLazyDLL("mswsock.dll")
+	modcrypt32  = NewLazyDLL("crypt32.dll")
+	modws2_32   = NewLazyDLL("ws2_32.dll")
+	moddnsapi   = NewLazyDLL("dnsapi.dll")
+	modiphlpapi = NewLazyDLL("iphlpapi.dll")
+	modsecur32  = NewLazyDLL("secur32.dll")
+	modnetapi32 = NewLazyDLL("netapi32.dll")
+	moduserenv  = NewLazyDLL("userenv.dll")
+
+	procGetLastError                       = modkernel32.NewProc("GetLastError")
+	procLoadLibraryW                       = modkernel32.NewProc("LoadLibraryW")
+	procFreeLibrary                        = modkernel32.NewProc("FreeLibrary")
+	procGetProcAddress                     = modkernel32.NewProc("GetProcAddress")
+	procGetVersion                         = modkernel32.NewProc("GetVersion")
+	procFormatMessageW                     = modkernel32.NewProc("FormatMessageW")
+	procExitProcess                        = modkernel32.NewProc("ExitProcess")
+	procCreateFileW                        = modkernel32.NewProc("CreateFileW")
+	procReadFile                           = modkernel32.NewProc("ReadFile")
+	procWriteFile                          = modkernel32.NewProc("WriteFile")
+	procSetFilePointer                     = modkernel32.NewProc("SetFilePointer")
+	procCloseHandle                        = modkernel32.NewProc("CloseHandle")
+	procGetStdHandle                       = modkernel32.NewProc("GetStdHandle")
+	procFindFirstFileW                     = modkernel32.NewProc("FindFirstFileW")
+	procFindNextFileW                      = modkernel32.NewProc("FindNextFileW")
+	procFindClose                          = modkernel32.NewProc("FindClose")
+	procGetFileInformationByHandle         = modkernel32.NewProc("GetFileInformationByHandle")
+	procGetCurrentDirectoryW               = modkernel32.NewProc("GetCurrentDirectoryW")
+	procSetCurrentDirectoryW               = modkernel32.NewProc("SetCurrentDirectoryW")
+	procCreateDirectoryW                   = modkernel32.NewProc("CreateDirectoryW")
+	procRemoveDirectoryW                   = modkernel32.NewProc("RemoveDirectoryW")
+	procDeleteFileW                        = modkernel32.NewProc("DeleteFileW")
+	procMoveFileW                          = modkernel32.NewProc("MoveFileW")
+	procGetComputerNameW                   = modkernel32.NewProc("GetComputerNameW")
+	procSetEndOfFile                       = modkernel32.NewProc("SetEndOfFile")
+	procGetSystemTimeAsFileTime            = modkernel32.NewProc("GetSystemTimeAsFileTime")
+	procGetTimeZoneInformation             = modkernel32.NewProc("GetTimeZoneInformation")
+	procCreateIoCompletionPort             = modkernel32.NewProc("CreateIoCompletionPort")
+	procGetQueuedCompletionStatus          = modkernel32.NewProc("GetQueuedCompletionStatus")
+	procPostQueuedCompletionStatus         = modkernel32.NewProc("PostQueuedCompletionStatus")
+	procCancelIo                           = modkernel32.NewProc("CancelIo")
+	procCancelIoEx                         = modkernel32.NewProc("CancelIoEx")
+	procCreateProcessW                     = modkernel32.NewProc("CreateProcessW")
+	procOpenProcess                        = modkernel32.NewProc("OpenProcess")
+	procTerminateProcess                   = modkernel32.NewProc("TerminateProcess")
+	procGetExitCodeProcess                 = modkernel32.NewProc("GetExitCodeProcess")
+	procGetStartupInfoW                    = modkernel32.NewProc("GetStartupInfoW")
+	procGetCurrentProcess                  = modkernel32.NewProc("GetCurrentProcess")
+	procGetProcessTimes                    = modkernel32.NewProc("GetProcessTimes")
+	procDuplicateHandle                    = modkernel32.NewProc("DuplicateHandle")
+	procWaitForSingleObject                = modkernel32.NewProc("WaitForSingleObject")
+	procGetTempPathW                       = modkernel32.NewProc("GetTempPathW")
+	procCreatePipe                         = modkernel32.NewProc("CreatePipe")
+	procGetFileType                        = modkernel32.NewProc("GetFileType")
+	procCryptAcquireContextW               = modadvapi32.NewProc("CryptAcquireContextW")
+	procCryptReleaseContext                = modadvapi32.NewProc("CryptReleaseContext")
+	procCryptGenRandom                     = modadvapi32.NewProc("CryptGenRandom")
+	procGetEnvironmentStringsW             = modkernel32.NewProc("GetEnvironmentStringsW")
+	procFreeEnvironmentStringsW            = modkernel32.NewProc("FreeEnvironmentStringsW")
+	procGetEnvironmentVariableW            = modkernel32.NewProc("GetEnvironmentVariableW")
+	procSetEnvironmentVariableW            = modkernel32.NewProc("SetEnvironmentVariableW")
+	procSetFileTime                        = modkernel32.NewProc("SetFileTime")
+	procGetFileAttributesW                 = modkernel32.NewProc("GetFileAttributesW")
+	procSetFileAttributesW                 = modkernel32.NewProc("SetFileAttributesW")
+	procGetFileAttributesExW               = modkernel32.NewProc("GetFileAttributesExW")
+	procGetCommandLineW                    = modkernel32.NewProc("GetCommandLineW")
+	procCommandLineToArgvW                 = modshell32.NewProc("CommandLineToArgvW")
+	procLocalFree                          = modkernel32.NewProc("LocalFree")
+	procSetHandleInformation               = modkernel32.NewProc("SetHandleInformation")
+	procFlushFileBuffers                   = modkernel32.NewProc("FlushFileBuffers")
+	procGetFullPathNameW                   = modkernel32.NewProc("GetFullPathNameW")
+	procGetLongPathNameW                   = modkernel32.NewProc("GetLongPathNameW")
+	procGetShortPathNameW                  = modkernel32.NewProc("GetShortPathNameW")
+	procCreateFileMappingW                 = modkernel32.NewProc("CreateFileMappingW")
+	procMapViewOfFile                      = modkernel32.NewProc("MapViewOfFile")
+	procUnmapViewOfFile                    = modkernel32.NewProc("UnmapViewOfFile")
+	procFlushViewOfFile                    = modkernel32.NewProc("FlushViewOfFile")
+	procVirtualLock                        = modkernel32.NewProc("VirtualLock")
+	procVirtualUnlock                      = modkernel32.NewProc("VirtualUnlock")
+	procTransmitFile                       = modmswsock.NewProc("TransmitFile")
+	procReadDirectoryChangesW              = modkernel32.NewProc("ReadDirectoryChangesW")
+	procCertOpenSystemStoreW               = modcrypt32.NewProc("CertOpenSystemStoreW")
+	procCertOpenStore                      = modcrypt32.NewProc("CertOpenStore")
+	procCertEnumCertificatesInStore        = modcrypt32.NewProc("CertEnumCertificatesInStore")
+	procCertAddCertificateContextToStore   = modcrypt32.NewProc("CertAddCertificateContextToStore")
+	procCertCloseStore                     = modcrypt32.NewProc("CertCloseStore")
+	procCertGetCertificateChain            = modcrypt32.NewProc("CertGetCertificateChain")
+	procCertFreeCertificateChain           = modcrypt32.NewProc("CertFreeCertificateChain")
+	procCertCreateCertificateContext       = modcrypt32.NewProc("CertCreateCertificateContext")
+	procCertFreeCertificateContext         = modcrypt32.NewProc("CertFreeCertificateContext")
+	procCertVerifyCertificateChainPolicy   = modcrypt32.NewProc("CertVerifyCertificateChainPolicy")
+	procRegOpenKeyExW                      = modadvapi32.NewProc("RegOpenKeyExW")
+	procRegCloseKey                        = modadvapi32.NewProc("RegCloseKey")
+	procRegQueryInfoKeyW                   = modadvapi32.NewProc("RegQueryInfoKeyW")
+	procRegEnumKeyExW                      = modadvapi32.NewProc("RegEnumKeyExW")
+	procRegQueryValueExW                   = modadvapi32.NewProc("RegQueryValueExW")
+	procGetCurrentProcessId                = modkernel32.NewProc("GetCurrentProcessId")
+	procGetConsoleMode                     = modkernel32.NewProc("GetConsoleMode")
+	procWriteConsoleW                      = modkernel32.NewProc("WriteConsoleW")
+	procReadConsoleW                       = modkernel32.NewProc("ReadConsoleW")
+	procCreateToolhelp32Snapshot           = modkernel32.NewProc("CreateToolhelp32Snapshot")
+	procProcess32FirstW                    = modkernel32.NewProc("Process32FirstW")
+	procProcess32NextW                     = modkernel32.NewProc("Process32NextW")
+	procDeviceIoControl                    = modkernel32.NewProc("DeviceIoControl")
+	procCreateSymbolicLinkW                = modkernel32.NewProc("CreateSymbolicLinkW")
+	procCreateHardLinkW                    = modkernel32.NewProc("CreateHardLinkW")
+	procWSAStartup                         = modws2_32.NewProc("WSAStartup")
+	procWSACleanup                         = modws2_32.NewProc("WSACleanup")
+	procWSAIoctl                           = modws2_32.NewProc("WSAIoctl")
+	procsocket                             = modws2_32.NewProc("socket")
+	procsetsockopt                         = modws2_32.NewProc("setsockopt")
+	procgetsockopt                         = modws2_32.NewProc("getsockopt")
+	procbind                               = modws2_32.NewProc("bind")
+	procconnect                            = modws2_32.NewProc("connect")
+	procgetsockname                        = modws2_32.NewProc("getsockname")
+	procgetpeername                        = modws2_32.NewProc("getpeername")
+	proclisten                             = modws2_32.NewProc("listen")
+	procshutdown                           = modws2_32.NewProc("shutdown")
+	procclosesocket                        = modws2_32.NewProc("closesocket")
+	procAcceptEx                           = modmswsock.NewProc("AcceptEx")
+	procGetAcceptExSockaddrs               = modmswsock.NewProc("GetAcceptExSockaddrs")
+	procWSARecv                            = modws2_32.NewProc("WSARecv")
+	procWSASend                            = modws2_32.NewProc("WSASend")
+	procWSARecvFrom                        = modws2_32.NewProc("WSARecvFrom")
+	procWSASendTo                          = modws2_32.NewProc("WSASendTo")
+	procgethostbyname                      = modws2_32.NewProc("gethostbyname")
+	procgetservbyname                      = modws2_32.NewProc("getservbyname")
+	procntohs                              = modws2_32.NewProc("ntohs")
+	procgetprotobyname                     = modws2_32.NewProc("getprotobyname")
+	procDnsQuery_W                         = moddnsapi.NewProc("DnsQuery_W")
+	procDnsRecordListFree                  = moddnsapi.NewProc("DnsRecordListFree")
+	procDnsNameCompare_W                   = moddnsapi.NewProc("DnsNameCompare_W")
+	procGetAddrInfoW                       = modws2_32.NewProc("GetAddrInfoW")
+	procFreeAddrInfoW                      = modws2_32.NewProc("FreeAddrInfoW")
+	procGetIfEntry                         = modiphlpapi.NewProc("GetIfEntry")
+	procGetAdaptersInfo                    = modiphlpapi.NewProc("GetAdaptersInfo")
+	procSetFileCompletionNotificationModes = modkernel32.NewProc("SetFileCompletionNotificationModes")
+	procWSAEnumProtocolsW                  = modws2_32.NewProc("WSAEnumProtocolsW")
+	procTranslateNameW                     = modsecur32.NewProc("TranslateNameW")
+	procGetUserNameExW                     = modsecur32.NewProc("GetUserNameExW")
+	procNetUserGetInfo                     = modnetapi32.NewProc("NetUserGetInfo")
+	procNetGetJoinInformation              = modnetapi32.NewProc("NetGetJoinInformation")
+	procNetApiBufferFree                   = modnetapi32.NewProc("NetApiBufferFree")
+	procLookupAccountSidW                  = modadvapi32.NewProc("LookupAccountSidW")
+	procLookupAccountNameW                 = modadvapi32.NewProc("LookupAccountNameW")
+	procConvertSidToStringSidW             = modadvapi32.NewProc("ConvertSidToStringSidW")
+	procConvertStringSidToSidW             = modadvapi32.NewProc("ConvertStringSidToSidW")
+	procGetLengthSid                       = modadvapi32.NewProc("GetLengthSid")
+	procCopySid                            = modadvapi32.NewProc("CopySid")
+	procOpenProcessToken                   = modadvapi32.NewProc("OpenProcessToken")
+	procGetTokenInformation                = modadvapi32.NewProc("GetTokenInformation")
+	procGetUserProfileDirectoryW           = moduserenv.NewProc("GetUserProfileDirectoryW")
+)
+
+func GetLastError() (lasterr error) {
+	r0, _, _ := Syscall(procGetLastError.Addr(), 0, 0, 0, 0)
+	if r0 != 0 {
+		lasterr = Errno(r0)
+	}
+	return
+}
+
+func LoadLibrary(libname string) (handle Handle, err error) {
+	var _p0 *uint16
+	_p0, err = UTF16PtrFromString(libname)
+	if err != nil {
+		return
+	}
+	return _LoadLibrary(_p0)
+}
+
+func _LoadLibrary(libname *uint16) (handle Handle, err error) {
+	r0, _, e1 := Syscall(procLoadLibraryW.Addr(), 1, uintptr(unsafe.Pointer(libname)), 0, 0)
+	handle = Handle(r0)
+	if handle == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func FreeLibrary(handle Handle) (err error) {
+	r1, _, e1 := Syscall(procFreeLibrary.Addr(), 1, uintptr(handle), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func GetProcAddress(module Handle, procname string) (proc uintptr, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(procname)
+	if err != nil {
+		return
+	}
+	return _GetProcAddress(module, _p0)
+}
+
+func _GetProcAddress(module Handle, procname *byte) (proc uintptr, err error) {
+	r0, _, e1 := Syscall(procGetProcAddress.Addr(), 2, uintptr(module), uintptr(unsafe.Pointer(procname)), 0)
+	proc = uintptr(r0)
+	if proc == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func GetVersion() (ver uint32, err error) {
+	r0, _, e1 := Syscall(procGetVersion.Addr(), 0, 0, 0, 0)
+	ver = uint32(r0)
+	if ver == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func FormatMessage(flags uint32, msgsrc uint32, msgid uint32, langid uint32, buf []uint16, args *byte) (n uint32, err error) {
+	var _p0 *uint16
+	if len(buf) > 0 {
+		_p0 = &buf[0]
+	}
+	r0, _, e1 := Syscall9(procFormatMessageW.Addr(), 7, uintptr(flags), uintptr(msgsrc), uintptr(msgid), uintptr(langid), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(unsafe.Pointer(args)), 0, 0)
+	n = uint32(r0)
+	if n == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func ExitProcess(exitcode uint32) {
+	Syscall(procExitProcess.Addr(), 1, uintptr(exitcode), 0, 0)
+	return
+}
+
+func CreateFile(name *uint16, access uint32, mode uint32, sa *SecurityAttributes, createmode uint32, attrs uint32, templatefile int32) (handle Handle, err error) {
+	r0, _, e1 := Syscall9(procCreateFileW.Addr(), 7, uintptr(unsafe.Pointer(name)), uintptr(access), uintptr(mode), uintptr(unsafe.Pointer(sa)), uintptr(createmode), uintptr(attrs), uintptr(templatefile), 0, 0)
+	handle = Handle(r0)
+	if handle == InvalidHandle {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func ReadFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) (err error) {
+	var _p0 *byte
+	if len(buf) > 0 {
+		_p0 = &buf[0]
+	}
+	r1, _, e1 := Syscall6(procReadFile.Addr(), 5, uintptr(handle), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(unsafe.Pointer(done)), uintptr(unsafe.Pointer(overlapped)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func WriteFile(handle Handle, buf []byte, done *uint32, overlapped *Overlapped) (err error) {
+	var _p0 *byte
+	if len(buf) > 0 {
+		_p0 = &buf[0]
+	}
+	r1, _, e1 := Syscall6(procWriteFile.Addr(), 5, uintptr(handle), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(unsafe.Pointer(done)), uintptr(unsafe.Pointer(overlapped)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func SetFilePointer(handle Handle, lowoffset int32, highoffsetptr *int32, whence uint32) (newlowoffset uint32, err error) {
+	r0, _, e1 := Syscall6(procSetFilePointer.Addr(), 4, uintptr(handle), uintptr(lowoffset), uintptr(unsafe.Pointer(highoffsetptr)), uintptr(whence), 0, 0)
+	newlowoffset = uint32(r0)
+	if newlowoffset == 0xffffffff {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func CloseHandle(handle Handle) (err error) {
+	r1, _, e1 := Syscall(procCloseHandle.Addr(), 1, uintptr(handle), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func GetStdHandle(stdhandle int) (handle Handle, err error) {
+	r0, _, e1 := Syscall(procGetStdHandle.Addr(), 1, uintptr(stdhandle), 0, 0)
+	handle = Handle(r0)
+	if handle == InvalidHandle {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func findFirstFile1(name *uint16, data *win32finddata1) (handle Handle, err error) {
+	r0, _, e1 := Syscall(procFindFirstFileW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(data)), 0)
+	handle = Handle(r0)
+	if handle == InvalidHandle {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func findNextFile1(handle Handle, data *win32finddata1) (err error) {
+	r1, _, e1 := Syscall(procFindNextFileW.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(data)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func FindClose(handle Handle) (err error) {
+	r1, _, e1 := Syscall(procFindClose.Addr(), 1, uintptr(handle), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func GetFileInformationByHandle(handle Handle, data *ByHandleFileInformation) (err error) {
+	r1, _, e1 := Syscall(procGetFileInformationByHandle.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(data)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func GetCurrentDirectory(buflen uint32, buf *uint16) (n uint32, err error) {
+	r0, _, e1 := Syscall(procGetCurrentDirectoryW.Addr(), 2, uintptr(buflen), uintptr(unsafe.Pointer(buf)), 0)
+	n = uint32(r0)
+	if n == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func SetCurrentDirectory(path *uint16) (err error) {
+	r1, _, e1 := Syscall(procSetCurrentDirectoryW.Addr(), 1, uintptr(unsafe.Pointer(path)), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func CreateDirectory(path *uint16, sa *SecurityAttributes) (err error) {
+	r1, _, e1 := Syscall(procCreateDirectoryW.Addr(), 2, uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(sa)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func RemoveDirectory(path *uint16) (err error) {
+	r1, _, e1 := Syscall(procRemoveDirectoryW.Addr(), 1, uintptr(unsafe.Pointer(path)), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func DeleteFile(path *uint16) (err error) {
+	r1, _, e1 := Syscall(procDeleteFileW.Addr(), 1, uintptr(unsafe.Pointer(path)), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func MoveFile(from *uint16, to *uint16) (err error) {
+	r1, _, e1 := Syscall(procMoveFileW.Addr(), 2, uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(to)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func GetComputerName(buf *uint16, n *uint32) (err error) {
+	r1, _, e1 := Syscall(procGetComputerNameW.Addr(), 2, uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(n)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func SetEndOfFile(handle Handle) (err error) {
+	r1, _, e1 := Syscall(procSetEndOfFile.Addr(), 1, uintptr(handle), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func GetSystemTimeAsFileTime(time *Filetime) {
+	Syscall(procGetSystemTimeAsFileTime.Addr(), 1, uintptr(unsafe.Pointer(time)), 0, 0)
+	return
+}
+
+func GetTimeZoneInformation(tzi *Timezoneinformation) (rc uint32, err error) {
+	r0, _, e1 := Syscall(procGetTimeZoneInformation.Addr(), 1, uintptr(unsafe.Pointer(tzi)), 0, 0)
+	rc = uint32(r0)
+	if rc == 0xffffffff {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func CreateIoCompletionPort(filehandle Handle, cphandle Handle, key uint32, threadcnt uint32) (handle Handle, err error) {
+	r0, _, e1 := Syscall6(procCreateIoCompletionPort.Addr(), 4, uintptr(filehandle), uintptr(cphandle), uintptr(key), uintptr(threadcnt), 0, 0)
+	handle = Handle(r0)
+	if handle == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func GetQueuedCompletionStatus(cphandle Handle, qty *uint32, key *uint32, overlapped **Overlapped, timeout uint32) (err error) {
+	r1, _, e1 := Syscall6(procGetQueuedCompletionStatus.Addr(), 5, uintptr(cphandle), uintptr(unsafe.Pointer(qty)), uintptr(unsafe.Pointer(key)), uintptr(unsafe.Pointer(overlapped)), uintptr(timeout), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func PostQueuedCompletionStatus(cphandle Handle, qty uint32, key uint32, overlapped *Overlapped) (err error) {
+	r1, _, e1 := Syscall6(procPostQueuedCompletionStatus.Addr(), 4, uintptr(cphandle), uintptr(qty), uintptr(key), uintptr(unsafe.Pointer(overlapped)), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func CancelIo(s Handle) (err error) {
+	r1, _, e1 := Syscall(procCancelIo.Addr(), 1, uintptr(s), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func CancelIoEx(s Handle, o *Overlapped) (err error) {
+	r1, _, e1 := Syscall(procCancelIoEx.Addr(), 2, uintptr(s), uintptr(unsafe.Pointer(o)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func CreateProcess(appName *uint16, commandLine *uint16, procSecurity *SecurityAttributes, threadSecurity *SecurityAttributes, inheritHandles bool, creationFlags uint32, env *uint16, currentDir *uint16, startupInfo *StartupInfo, outProcInfo *ProcessInformation) (err error) {
+	var _p0 uint32
+	if inheritHandles {
+		_p0 = 1
+	} else {
+		_p0 = 0
+	}
+	r1, _, e1 := Syscall12(procCreateProcessW.Addr(), 10, uintptr(unsafe.Pointer(appName)), uintptr(unsafe.Pointer(commandLine)), uintptr(unsafe.Pointer(procSecurity)), uintptr(unsafe.Pointer(threadSecurity)), uintptr(_p0), uintptr(creationFlags), uintptr(unsafe.Pointer(env)), uintptr(unsafe.Pointer(currentDir)), uintptr(unsafe.Pointer(startupInfo)), uintptr(unsafe.Pointer(outProcInfo)), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func OpenProcess(da uint32, inheritHandle bool, pid uint32) (handle Handle, err error) {
+	var _p0 uint32
+	if inheritHandle {
+		_p0 = 1
+	} else {
+		_p0 = 0
+	}
+	r0, _, e1 := Syscall(procOpenProcess.Addr(), 3, uintptr(da), uintptr(_p0), uintptr(pid))
+	handle = Handle(r0)
+	if handle == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func TerminateProcess(handle Handle, exitcode uint32) (err error) {
+	r1, _, e1 := Syscall(procTerminateProcess.Addr(), 2, uintptr(handle), uintptr(exitcode), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func GetExitCodeProcess(handle Handle, exitcode *uint32) (err error) {
+	r1, _, e1 := Syscall(procGetExitCodeProcess.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(exitcode)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func GetStartupInfo(startupInfo *StartupInfo) (err error) {
+	r1, _, e1 := Syscall(procGetStartupInfoW.Addr(), 1, uintptr(unsafe.Pointer(startupInfo)), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func GetCurrentProcess() (pseudoHandle Handle, err error) {
+	r0, _, e1 := Syscall(procGetCurrentProcess.Addr(), 0, 0, 0, 0)
+	pseudoHandle = Handle(r0)
+	if pseudoHandle == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func GetProcessTimes(handle Handle, creationTime *Filetime, exitTime *Filetime, kernelTime *Filetime, userTime *Filetime) (err error) {
+	r1, _, e1 := Syscall6(procGetProcessTimes.Addr(), 5, uintptr(handle), uintptr(unsafe.Pointer(creationTime)), uintptr(unsafe.Pointer(exitTime)), uintptr(unsafe.Pointer(kernelTime)), uintptr(unsafe.Pointer(userTime)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func DuplicateHandle(hSourceProcessHandle Handle, hSourceHandle Handle, hTargetProcessHandle Handle, lpTargetHandle *Handle, dwDesiredAccess uint32, bInheritHandle bool, dwOptions uint32) (err error) {
+	var _p0 uint32
+	if bInheritHandle {
+		_p0 = 1
+	} else {
+		_p0 = 0
+	}
+	r1, _, e1 := Syscall9(procDuplicateHandle.Addr(), 7, uintptr(hSourceProcessHandle), uintptr(hSourceHandle), uintptr(hTargetProcessHandle), uintptr(unsafe.Pointer(lpTargetHandle)), uintptr(dwDesiredAccess), uintptr(_p0), uintptr(dwOptions), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func WaitForSingleObject(handle Handle, waitMilliseconds uint32) (event uint32, err error) {
+	r0, _, e1 := Syscall(procWaitForSingleObject.Addr(), 2, uintptr(handle), uintptr(waitMilliseconds), 0)
+	event = uint32(r0)
+	if event == 0xffffffff {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func GetTempPath(buflen uint32, buf *uint16) (n uint32, err error) {
+	r0, _, e1 := Syscall(procGetTempPathW.Addr(), 2, uintptr(buflen), uintptr(unsafe.Pointer(buf)), 0)
+	n = uint32(r0)
+	if n == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func CreatePipe(readhandle *Handle, writehandle *Handle, sa *SecurityAttributes, size uint32) (err error) {
+	r1, _, e1 := Syscall6(procCreatePipe.Addr(), 4, uintptr(unsafe.Pointer(readhandle)), uintptr(unsafe.Pointer(writehandle)), uintptr(unsafe.Pointer(sa)), uintptr(size), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func GetFileType(filehandle Handle) (n uint32, err error) {
+	r0, _, e1 := Syscall(procGetFileType.Addr(), 1, uintptr(filehandle), 0, 0)
+	n = uint32(r0)
+	if n == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func CryptAcquireContext(provhandle *Handle, container *uint16, provider *uint16, provtype uint32, flags uint32) (err error) {
+	r1, _, e1 := Syscall6(procCryptAcquireContextW.Addr(), 5, uintptr(unsafe.Pointer(provhandle)), uintptr(unsafe.Pointer(container)), uintptr(unsafe.Pointer(provider)), uintptr(provtype), uintptr(flags), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func CryptReleaseContext(provhandle Handle, flags uint32) (err error) {
+	r1, _, e1 := Syscall(procCryptReleaseContext.Addr(), 2, uintptr(provhandle), uintptr(flags), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func CryptGenRandom(provhandle Handle, buflen uint32, buf *byte) (err error) {
+	r1, _, e1 := Syscall(procCryptGenRandom.Addr(), 3, uintptr(provhandle), uintptr(buflen), uintptr(unsafe.Pointer(buf)))
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func GetEnvironmentStrings() (envs *uint16, err error) {
+	r0, _, e1 := Syscall(procGetEnvironmentStringsW.Addr(), 0, 0, 0, 0)
+	envs = (*uint16)(unsafe.Pointer(r0))
+	if envs == nil {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func FreeEnvironmentStrings(envs *uint16) (err error) {
+	r1, _, e1 := Syscall(procFreeEnvironmentStringsW.Addr(), 1, uintptr(unsafe.Pointer(envs)), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func GetEnvironmentVariable(name *uint16, buffer *uint16, size uint32) (n uint32, err error) {
+	r0, _, e1 := Syscall(procGetEnvironmentVariableW.Addr(), 3, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(buffer)), uintptr(size))
+	n = uint32(r0)
+	if n == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func SetEnvironmentVariable(name *uint16, value *uint16) (err error) {
+	r1, _, e1 := Syscall(procSetEnvironmentVariableW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(value)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func SetFileTime(handle Handle, ctime *Filetime, atime *Filetime, wtime *Filetime) (err error) {
+	r1, _, e1 := Syscall6(procSetFileTime.Addr(), 4, uintptr(handle), uintptr(unsafe.Pointer(ctime)), uintptr(unsafe.Pointer(atime)), uintptr(unsafe.Pointer(wtime)), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func GetFileAttributes(name *uint16) (attrs uint32, err error) {
+	r0, _, e1 := Syscall(procGetFileAttributesW.Addr(), 1, uintptr(unsafe.Pointer(name)), 0, 0)
+	attrs = uint32(r0)
+	if attrs == INVALID_FILE_ATTRIBUTES {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func SetFileAttributes(name *uint16, attrs uint32) (err error) {
+	r1, _, e1 := Syscall(procSetFileAttributesW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(attrs), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func GetFileAttributesEx(name *uint16, level uint32, info *byte) (err error) {
+	r1, _, e1 := Syscall(procGetFileAttributesExW.Addr(), 3, uintptr(unsafe.Pointer(name)), uintptr(level), uintptr(unsafe.Pointer(info)))
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func GetCommandLine() (cmd *uint16) {
+	r0, _, _ := Syscall(procGetCommandLineW.Addr(), 0, 0, 0, 0)
+	cmd = (*uint16)(unsafe.Pointer(r0))
+	return
+}
+
+func CommandLineToArgv(cmd *uint16, argc *int32) (argv *[8192]*[8192]uint16, err error) {
+	r0, _, e1 := Syscall(procCommandLineToArgvW.Addr(), 2, uintptr(unsafe.Pointer(cmd)), uintptr(unsafe.Pointer(argc)), 0)
+	argv = (*[8192]*[8192]uint16)(unsafe.Pointer(r0))
+	if argv == nil {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func LocalFree(hmem Handle) (handle Handle, err error) {
+	r0, _, e1 := Syscall(procLocalFree.Addr(), 1, uintptr(hmem), 0, 0)
+	handle = Handle(r0)
+	if handle != 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func SetHandleInformation(handle Handle, mask uint32, flags uint32) (err error) {
+	r1, _, e1 := Syscall(procSetHandleInformation.Addr(), 3, uintptr(handle), uintptr(mask), uintptr(flags))
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func FlushFileBuffers(handle Handle) (err error) {
+	r1, _, e1 := Syscall(procFlushFileBuffers.Addr(), 1, uintptr(handle), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func GetFullPathName(path *uint16, buflen uint32, buf *uint16, fname **uint16) (n uint32, err error) {
+	r0, _, e1 := Syscall6(procGetFullPathNameW.Addr(), 4, uintptr(unsafe.Pointer(path)), uintptr(buflen), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(fname)), 0, 0)
+	n = uint32(r0)
+	if n == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func GetLongPathName(path *uint16, buf *uint16, buflen uint32) (n uint32, err error) {
+	r0, _, e1 := Syscall(procGetLongPathNameW.Addr(), 3, uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(buf)), uintptr(buflen))
+	n = uint32(r0)
+	if n == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func GetShortPathName(longpath *uint16, shortpath *uint16, buflen uint32) (n uint32, err error) {
+	r0, _, e1 := Syscall(procGetShortPathNameW.Addr(), 3, uintptr(unsafe.Pointer(longpath)), uintptr(unsafe.Pointer(shortpath)), uintptr(buflen))
+	n = uint32(r0)
+	if n == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func CreateFileMapping(fhandle Handle, sa *SecurityAttributes, prot uint32, maxSizeHigh uint32, maxSizeLow uint32, name *uint16) (handle Handle, err error) {
+	r0, _, e1 := Syscall6(procCreateFileMappingW.Addr(), 6, uintptr(fhandle), uintptr(unsafe.Pointer(sa)), uintptr(prot), uintptr(maxSizeHigh), uintptr(maxSizeLow), uintptr(unsafe.Pointer(name)))
+	handle = Handle(r0)
+	if handle == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func MapViewOfFile(handle Handle, access uint32, offsetHigh uint32, offsetLow uint32, length uintptr) (addr uintptr, err error) {
+	r0, _, e1 := Syscall6(procMapViewOfFile.Addr(), 5, uintptr(handle), uintptr(access), uintptr(offsetHigh), uintptr(offsetLow), uintptr(length), 0)
+	addr = uintptr(r0)
+	if addr == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func UnmapViewOfFile(addr uintptr) (err error) {
+	r1, _, e1 := Syscall(procUnmapViewOfFile.Addr(), 1, uintptr(addr), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func FlushViewOfFile(addr uintptr, length uintptr) (err error) {
+	r1, _, e1 := Syscall(procFlushViewOfFile.Addr(), 2, uintptr(addr), uintptr(length), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func VirtualLock(addr uintptr, length uintptr) (err error) {
+	r1, _, e1 := Syscall(procVirtualLock.Addr(), 2, uintptr(addr), uintptr(length), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func VirtualUnlock(addr uintptr, length uintptr) (err error) {
+	r1, _, e1 := Syscall(procVirtualUnlock.Addr(), 2, uintptr(addr), uintptr(length), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func TransmitFile(s Handle, handle Handle, bytesToWrite uint32, bytsPerSend uint32, overlapped *Overlapped, transmitFileBuf *TransmitFileBuffers, flags uint32) (err error) {
+	r1, _, e1 := Syscall9(procTransmitFile.Addr(), 7, uintptr(s), uintptr(handle), uintptr(bytesToWrite), uintptr(bytsPerSend), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(transmitFileBuf)), uintptr(flags), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func ReadDirectoryChanges(handle Handle, buf *byte, buflen uint32, watchSubTree bool, mask uint32, retlen *uint32, overlapped *Overlapped, completionRoutine uintptr) (err error) {
+	var _p0 uint32
+	if watchSubTree {
+		_p0 = 1
+	} else {
+		_p0 = 0
+	}
+	r1, _, e1 := Syscall9(procReadDirectoryChangesW.Addr(), 8, uintptr(handle), uintptr(unsafe.Pointer(buf)), uintptr(buflen), uintptr(_p0), uintptr(mask), uintptr(unsafe.Pointer(retlen)), uintptr(unsafe.Pointer(overlapped)), uintptr(completionRoutine), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func CertOpenSystemStore(hprov Handle, name *uint16) (store Handle, err error) {
+	r0, _, e1 := Syscall(procCertOpenSystemStoreW.Addr(), 2, uintptr(hprov), uintptr(unsafe.Pointer(name)), 0)
+	store = Handle(r0)
+	if store == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func CertOpenStore(storeProvider uintptr, msgAndCertEncodingType uint32, cryptProv uintptr, flags uint32, para uintptr) (handle Handle, err error) {
+	r0, _, e1 := Syscall6(procCertOpenStore.Addr(), 5, uintptr(storeProvider), uintptr(msgAndCertEncodingType), uintptr(cryptProv), uintptr(flags), uintptr(para), 0)
+	handle = Handle(r0)
+	if handle == InvalidHandle {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func CertEnumCertificatesInStore(store Handle, prevContext *CertContext) (context *CertContext, err error) {
+	r0, _, e1 := Syscall(procCertEnumCertificatesInStore.Addr(), 2, uintptr(store), uintptr(unsafe.Pointer(prevContext)), 0)
+	context = (*CertContext)(unsafe.Pointer(r0))
+	if context == nil {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func CertAddCertificateContextToStore(store Handle, certContext *CertContext, addDisposition uint32, storeContext **CertContext) (err error) {
+	r1, _, e1 := Syscall6(procCertAddCertificateContextToStore.Addr(), 4, uintptr(store), uintptr(unsafe.Pointer(certContext)), uintptr(addDisposition), uintptr(unsafe.Pointer(storeContext)), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func CertCloseStore(store Handle, flags uint32) (err error) {
+	r1, _, e1 := Syscall(procCertCloseStore.Addr(), 2, uintptr(store), uintptr(flags), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func CertGetCertificateChain(engine Handle, leaf *CertContext, time *Filetime, additionalStore Handle, para *CertChainPara, flags uint32, reserved uintptr, chainCtx **CertChainContext) (err error) {
+	r1, _, e1 := Syscall9(procCertGetCertificateChain.Addr(), 8, uintptr(engine), uintptr(unsafe.Pointer(leaf)), uintptr(unsafe.Pointer(time)), uintptr(additionalStore), uintptr(unsafe.Pointer(para)), uintptr(flags), uintptr(reserved), uintptr(unsafe.Pointer(chainCtx)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func CertFreeCertificateChain(ctx *CertChainContext) {
+	Syscall(procCertFreeCertificateChain.Addr(), 1, uintptr(unsafe.Pointer(ctx)), 0, 0)
+	return
+}
+
+func CertCreateCertificateContext(certEncodingType uint32, certEncoded *byte, encodedLen uint32) (context *CertContext, err error) {
+	r0, _, e1 := Syscall(procCertCreateCertificateContext.Addr(), 3, uintptr(certEncodingType), uintptr(unsafe.Pointer(certEncoded)), uintptr(encodedLen))
+	context = (*CertContext)(unsafe.Pointer(r0))
+	if context == nil {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func CertFreeCertificateContext(ctx *CertContext) (err error) {
+	r1, _, e1 := Syscall(procCertFreeCertificateContext.Addr(), 1, uintptr(unsafe.Pointer(ctx)), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func CertVerifyCertificateChainPolicy(policyOID uintptr, chain *CertChainContext, para *CertChainPolicyPara, status *CertChainPolicyStatus) (err error) {
+	r1, _, e1 := Syscall6(procCertVerifyCertificateChainPolicy.Addr(), 4, uintptr(policyOID), uintptr(unsafe.Pointer(chain)), uintptr(unsafe.Pointer(para)), uintptr(unsafe.Pointer(status)), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func RegOpenKeyEx(key Handle, subkey *uint16, options uint32, desiredAccess uint32, result *Handle) (regerrno error) {
+	r0, _, _ := Syscall6(procRegOpenKeyExW.Addr(), 5, uintptr(key), uintptr(unsafe.Pointer(subkey)), uintptr(options), uintptr(desiredAccess), uintptr(unsafe.Pointer(result)), 0)
+	if r0 != 0 {
+		regerrno = Errno(r0)
+	}
+	return
+}
+
+func RegCloseKey(key Handle) (regerrno error) {
+	r0, _, _ := Syscall(procRegCloseKey.Addr(), 1, uintptr(key), 0, 0)
+	if r0 != 0 {
+		regerrno = Errno(r0)
+	}
+	return
+}
+
+func RegQueryInfoKey(key Handle, class *uint16, classLen *uint32, reserved *uint32, subkeysLen *uint32, maxSubkeyLen *uint32, maxClassLen *uint32, valuesLen *uint32, maxValueNameLen *uint32, maxValueLen *uint32, saLen *uint32, lastWriteTime *Filetime) (regerrno error) {
+	r0, _, _ := Syscall12(procRegQueryInfoKeyW.Addr(), 12, uintptr(key), uintptr(unsafe.Pointer(class)), uintptr(unsafe.Pointer(classLen)), uintptr(unsafe.Pointer(reserved)), uintptr(unsafe.Pointer(subkeysLen)), uintptr(unsafe.Pointer(maxSubkeyLen)), uintptr(unsafe.Pointer(maxClassLen)), uintptr(unsafe.Pointer(valuesLen)), uintptr(unsafe.Pointer(maxValueNameLen)), uintptr(unsafe.Pointer(maxValueLen)), uintptr(unsafe.Pointer(saLen)), uintptr(unsafe.Pointer(lastWriteTime)))
+	if r0 != 0 {
+		regerrno = Errno(r0)
+	}
+	return
+}
+
+func RegEnumKeyEx(key Handle, index uint32, name *uint16, nameLen *uint32, reserved *uint32, class *uint16, classLen *uint32, lastWriteTime *Filetime) (regerrno error) {
+	r0, _, _ := Syscall9(procRegEnumKeyExW.Addr(), 8, uintptr(key), uintptr(index), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(nameLen)), uintptr(unsafe.Pointer(reserved)), uintptr(unsafe.Pointer(class)), uintptr(unsafe.Pointer(classLen)), uintptr(unsafe.Pointer(lastWriteTime)), 0)
+	if r0 != 0 {
+		regerrno = Errno(r0)
+	}
+	return
+}
+
+func RegQueryValueEx(key Handle, name *uint16, reserved *uint32, valtype *uint32, buf *byte, buflen *uint32) (regerrno error) {
+	r0, _, _ := Syscall6(procRegQueryValueExW.Addr(), 6, uintptr(key), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(reserved)), uintptr(unsafe.Pointer(valtype)), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(buflen)))
+	if r0 != 0 {
+		regerrno = Errno(r0)
+	}
+	return
+}
+
+func getCurrentProcessId() (pid uint32) {
+	r0, _, _ := Syscall(procGetCurrentProcessId.Addr(), 0, 0, 0, 0)
+	pid = uint32(r0)
+	return
+}
+
+func GetConsoleMode(console Handle, mode *uint32) (err error) {
+	r1, _, e1 := Syscall(procGetConsoleMode.Addr(), 2, uintptr(console), uintptr(unsafe.Pointer(mode)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func WriteConsole(console Handle, buf *uint16, towrite uint32, written *uint32, reserved *byte) (err error) {
+	r1, _, e1 := Syscall6(procWriteConsoleW.Addr(), 5, uintptr(console), uintptr(unsafe.Pointer(buf)), uintptr(towrite), uintptr(unsafe.Pointer(written)), uintptr(unsafe.Pointer(reserved)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func ReadConsole(console Handle, buf *uint16, toread uint32, read *uint32, inputControl *byte) (err error) {
+	r1, _, e1 := Syscall6(procReadConsoleW.Addr(), 5, uintptr(console), uintptr(unsafe.Pointer(buf)), uintptr(toread), uintptr(unsafe.Pointer(read)), uintptr(unsafe.Pointer(inputControl)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func CreateToolhelp32Snapshot(flags uint32, processId uint32) (handle Handle, err error) {
+	r0, _, e1 := Syscall(procCreateToolhelp32Snapshot.Addr(), 2, uintptr(flags), uintptr(processId), 0)
+	handle = Handle(r0)
+	if handle == InvalidHandle {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func Process32First(snapshot Handle, procEntry *ProcessEntry32) (err error) {
+	r1, _, e1 := Syscall(procProcess32FirstW.Addr(), 2, uintptr(snapshot), uintptr(unsafe.Pointer(procEntry)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func Process32Next(snapshot Handle, procEntry *ProcessEntry32) (err error) {
+	r1, _, e1 := Syscall(procProcess32NextW.Addr(), 2, uintptr(snapshot), uintptr(unsafe.Pointer(procEntry)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func DeviceIoControl(handle Handle, ioControlCode uint32, inBuffer *byte, inBufferSize uint32, outBuffer *byte, outBufferSize uint32, bytesReturned *uint32, overlapped *Overlapped) (err error) {
+	r1, _, e1 := Syscall9(procDeviceIoControl.Addr(), 8, uintptr(handle), uintptr(ioControlCode), uintptr(unsafe.Pointer(inBuffer)), uintptr(inBufferSize), uintptr(unsafe.Pointer(outBuffer)), uintptr(outBufferSize), uintptr(unsafe.Pointer(bytesReturned)), uintptr(unsafe.Pointer(overlapped)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func CreateSymbolicLink(symlinkfilename *uint16, targetfilename *uint16, flags uint32) (err error) {
+	r1, _, e1 := Syscall(procCreateSymbolicLinkW.Addr(), 3, uintptr(unsafe.Pointer(symlinkfilename)), uintptr(unsafe.Pointer(targetfilename)), uintptr(flags))
+	if r1&0xff == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func CreateHardLink(filename *uint16, existingfilename *uint16, reserved uintptr) (err error) {
+	r1, _, e1 := Syscall(procCreateHardLinkW.Addr(), 3, uintptr(unsafe.Pointer(filename)), uintptr(unsafe.Pointer(existingfilename)), uintptr(reserved))
+	if r1&0xff == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func WSAStartup(verreq uint32, data *WSAData) (sockerr error) {
+	r0, _, _ := Syscall(procWSAStartup.Addr(), 2, uintptr(verreq), uintptr(unsafe.Pointer(data)), 0)
+	if r0 != 0 {
+		sockerr = Errno(r0)
+	}
+	return
+}
+
+func WSACleanup() (err error) {
+	r1, _, e1 := Syscall(procWSACleanup.Addr(), 0, 0, 0, 0)
+	if r1 == socket_error {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func WSAIoctl(s Handle, iocc uint32, inbuf *byte, cbif uint32, outbuf *byte, cbob uint32, cbbr *uint32, overlapped *Overlapped, completionRoutine uintptr) (err error) {
+	r1, _, e1 := Syscall9(procWSAIoctl.Addr(), 9, uintptr(s), uintptr(iocc), uintptr(unsafe.Pointer(inbuf)), uintptr(cbif), uintptr(unsafe.Pointer(outbuf)), uintptr(cbob), uintptr(unsafe.Pointer(cbbr)), uintptr(unsafe.Pointer(overlapped)), uintptr(completionRoutine))
+	if r1 == socket_error {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func socket(af int32, typ int32, protocol int32) (handle Handle, err error) {
+	r0, _, e1 := Syscall(procsocket.Addr(), 3, uintptr(af), uintptr(typ), uintptr(protocol))
+	handle = Handle(r0)
+	if handle == InvalidHandle {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func Setsockopt(s Handle, level int32, optname int32, optval *byte, optlen int32) (err error) {
+	r1, _, e1 := Syscall6(procsetsockopt.Addr(), 5, uintptr(s), uintptr(level), uintptr(optname), uintptr(unsafe.Pointer(optval)), uintptr(optlen), 0)
+	if r1 == socket_error {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func Getsockopt(s Handle, level int32, optname int32, optval *byte, optlen *int32) (err error) {
+	r1, _, e1 := Syscall6(procgetsockopt.Addr(), 5, uintptr(s), uintptr(level), uintptr(optname), uintptr(unsafe.Pointer(optval)), uintptr(unsafe.Pointer(optlen)), 0)
+	if r1 == socket_error {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func bind(s Handle, name unsafe.Pointer, namelen int32) (err error) {
+	r1, _, e1 := Syscall(procbind.Addr(), 3, uintptr(s), uintptr(name), uintptr(namelen))
+	if r1 == socket_error {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func connect(s Handle, name unsafe.Pointer, namelen int32) (err error) {
+	r1, _, e1 := Syscall(procconnect.Addr(), 3, uintptr(s), uintptr(name), uintptr(namelen))
+	if r1 == socket_error {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func getsockname(s Handle, rsa *RawSockaddrAny, addrlen *int32) (err error) {
+	r1, _, e1 := Syscall(procgetsockname.Addr(), 3, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	if r1 == socket_error {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func getpeername(s Handle, rsa *RawSockaddrAny, addrlen *int32) (err error) {
+	r1, _, e1 := Syscall(procgetpeername.Addr(), 3, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+	if r1 == socket_error {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func listen(s Handle, backlog int32) (err error) {
+	r1, _, e1 := Syscall(proclisten.Addr(), 2, uintptr(s), uintptr(backlog), 0)
+	if r1 == socket_error {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func shutdown(s Handle, how int32) (err error) {
+	r1, _, e1 := Syscall(procshutdown.Addr(), 2, uintptr(s), uintptr(how), 0)
+	if r1 == socket_error {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func Closesocket(s Handle) (err error) {
+	r1, _, e1 := Syscall(procclosesocket.Addr(), 1, uintptr(s), 0, 0)
+	if r1 == socket_error {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func AcceptEx(ls Handle, as Handle, buf *byte, rxdatalen uint32, laddrlen uint32, raddrlen uint32, recvd *uint32, overlapped *Overlapped) (err error) {
+	r1, _, e1 := Syscall9(procAcceptEx.Addr(), 8, uintptr(ls), uintptr(as), uintptr(unsafe.Pointer(buf)), uintptr(rxdatalen), uintptr(laddrlen), uintptr(raddrlen), uintptr(unsafe.Pointer(recvd)), uintptr(unsafe.Pointer(overlapped)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func GetAcceptExSockaddrs(buf *byte, rxdatalen uint32, laddrlen uint32, raddrlen uint32, lrsa **RawSockaddrAny, lrsalen *int32, rrsa **RawSockaddrAny, rrsalen *int32) {
+	Syscall9(procGetAcceptExSockaddrs.Addr(), 8, uintptr(unsafe.Pointer(buf)), uintptr(rxdatalen), uintptr(laddrlen), uintptr(raddrlen), uintptr(unsafe.Pointer(lrsa)), uintptr(unsafe.Pointer(lrsalen)), uintptr(unsafe.Pointer(rrsa)), uintptr(unsafe.Pointer(rrsalen)), 0)
+	return
+}
+
+func WSARecv(s Handle, bufs *WSABuf, bufcnt uint32, recvd *uint32, flags *uint32, overlapped *Overlapped, croutine *byte) (err error) {
+	r1, _, e1 := Syscall9(procWSARecv.Addr(), 7, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(recvd)), uintptr(unsafe.Pointer(flags)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)), 0, 0)
+	if r1 == socket_error {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func WSASend(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, overlapped *Overlapped, croutine *byte) (err error) {
+	r1, _, e1 := Syscall9(procWSASend.Addr(), 7, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(sent)), uintptr(flags), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)), 0, 0)
+	if r1 == socket_error {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func WSARecvFrom(s Handle, bufs *WSABuf, bufcnt uint32, recvd *uint32, flags *uint32, from *RawSockaddrAny, fromlen *int32, overlapped *Overlapped, croutine *byte) (err error) {
+	r1, _, e1 := Syscall9(procWSARecvFrom.Addr(), 9, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(recvd)), uintptr(unsafe.Pointer(flags)), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)))
+	if r1 == socket_error {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func WSASendTo(s Handle, bufs *WSABuf, bufcnt uint32, sent *uint32, flags uint32, to *RawSockaddrAny, tolen int32, overlapped *Overlapped, croutine *byte) (err error) {
+	r1, _, e1 := Syscall9(procWSASendTo.Addr(), 9, uintptr(s), uintptr(unsafe.Pointer(bufs)), uintptr(bufcnt), uintptr(unsafe.Pointer(sent)), uintptr(flags), uintptr(unsafe.Pointer(to)), uintptr(tolen), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(croutine)))
+	if r1 == socket_error {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func GetHostByName(name string) (h *Hostent, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(name)
+	if err != nil {
+		return
+	}
+	return _GetHostByName(_p0)
+}
+
+func _GetHostByName(name *byte) (h *Hostent, err error) {
+	r0, _, e1 := Syscall(procgethostbyname.Addr(), 1, uintptr(unsafe.Pointer(name)), 0, 0)
+	h = (*Hostent)(unsafe.Pointer(r0))
+	if h == nil {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func GetServByName(name string, proto string) (s *Servent, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(name)
+	if err != nil {
+		return
+	}
+	var _p1 *byte
+	_p1, err = BytePtrFromString(proto)
+	if err != nil {
+		return
+	}
+	return _GetServByName(_p0, _p1)
+}
+
+func _GetServByName(name *byte, proto *byte) (s *Servent, err error) {
+	r0, _, e1 := Syscall(procgetservbyname.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(proto)), 0)
+	s = (*Servent)(unsafe.Pointer(r0))
+	if s == nil {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func Ntohs(netshort uint16) (u uint16) {
+	r0, _, _ := Syscall(procntohs.Addr(), 1, uintptr(netshort), 0, 0)
+	u = uint16(r0)
+	return
+}
+
+func GetProtoByName(name string) (p *Protoent, err error) {
+	var _p0 *byte
+	_p0, err = BytePtrFromString(name)
+	if err != nil {
+		return
+	}
+	return _GetProtoByName(_p0)
+}
+
+func _GetProtoByName(name *byte) (p *Protoent, err error) {
+	r0, _, e1 := Syscall(procgetprotobyname.Addr(), 1, uintptr(unsafe.Pointer(name)), 0, 0)
+	p = (*Protoent)(unsafe.Pointer(r0))
+	if p == nil {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func DnsQuery(name string, qtype uint16, options uint32, extra *byte, qrs **DNSRecord, pr *byte) (status error) {
+	var _p0 *uint16
+	_p0, status = UTF16PtrFromString(name)
+	if status != nil {
+		return
+	}
+	return _DnsQuery(_p0, qtype, options, extra, qrs, pr)
+}
+
+func _DnsQuery(name *uint16, qtype uint16, options uint32, extra *byte, qrs **DNSRecord, pr *byte) (status error) {
+	r0, _, _ := Syscall6(procDnsQuery_W.Addr(), 6, uintptr(unsafe.Pointer(name)), uintptr(qtype), uintptr(options), uintptr(unsafe.Pointer(extra)), uintptr(unsafe.Pointer(qrs)), uintptr(unsafe.Pointer(pr)))
+	if r0 != 0 {
+		status = Errno(r0)
+	}
+	return
+}
+
+func DnsRecordListFree(rl *DNSRecord, freetype uint32) {
+	Syscall(procDnsRecordListFree.Addr(), 2, uintptr(unsafe.Pointer(rl)), uintptr(freetype), 0)
+	return
+}
+
+func DnsNameCompare(name1 *uint16, name2 *uint16) (same bool) {
+	r0, _, _ := Syscall(procDnsNameCompare_W.Addr(), 2, uintptr(unsafe.Pointer(name1)), uintptr(unsafe.Pointer(name2)), 0)
+	same = r0 != 0
+	return
+}
+
+func GetAddrInfoW(nodename *uint16, servicename *uint16, hints *AddrinfoW, result **AddrinfoW) (sockerr error) {
+	r0, _, _ := Syscall6(procGetAddrInfoW.Addr(), 4, uintptr(unsafe.Pointer(nodename)), uintptr(unsafe.Pointer(servicename)), uintptr(unsafe.Pointer(hints)), uintptr(unsafe.Pointer(result)), 0, 0)
+	if r0 != 0 {
+		sockerr = Errno(r0)
+	}
+	return
+}
+
+func FreeAddrInfoW(addrinfo *AddrinfoW) {
+	Syscall(procFreeAddrInfoW.Addr(), 1, uintptr(unsafe.Pointer(addrinfo)), 0, 0)
+	return
+}
+
+func GetIfEntry(pIfRow *MibIfRow) (errcode error) {
+	r0, _, _ := Syscall(procGetIfEntry.Addr(), 1, uintptr(unsafe.Pointer(pIfRow)), 0, 0)
+	if r0 != 0 {
+		errcode = Errno(r0)
+	}
+	return
+}
+
+func GetAdaptersInfo(ai *IpAdapterInfo, ol *uint32) (errcode error) {
+	r0, _, _ := Syscall(procGetAdaptersInfo.Addr(), 2, uintptr(unsafe.Pointer(ai)), uintptr(unsafe.Pointer(ol)), 0)
+	if r0 != 0 {
+		errcode = Errno(r0)
+	}
+	return
+}
+
+func SetFileCompletionNotificationModes(handle Handle, flags uint8) (err error) {
+	r1, _, e1 := Syscall(procSetFileCompletionNotificationModes.Addr(), 2, uintptr(handle), uintptr(flags), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func WSAEnumProtocols(protocols *int32, protocolBuffer *WSAProtocolInfo, bufferLength *uint32) (n int32, err error) {
+	r0, _, e1 := Syscall(procWSAEnumProtocolsW.Addr(), 3, uintptr(unsafe.Pointer(protocols)), uintptr(unsafe.Pointer(protocolBuffer)), uintptr(unsafe.Pointer(bufferLength)))
+	n = int32(r0)
+	if n == -1 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func TranslateName(accName *uint16, accNameFormat uint32, desiredNameFormat uint32, translatedName *uint16, nSize *uint32) (err error) {
+	r1, _, e1 := Syscall6(procTranslateNameW.Addr(), 5, uintptr(unsafe.Pointer(accName)), uintptr(accNameFormat), uintptr(desiredNameFormat), uintptr(unsafe.Pointer(translatedName)), uintptr(unsafe.Pointer(nSize)), 0)
+	if r1&0xff == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func GetUserNameEx(nameFormat uint32, nameBuffre *uint16, nSize *uint32) (err error) {
+	r1, _, e1 := Syscall(procGetUserNameExW.Addr(), 3, uintptr(nameFormat), uintptr(unsafe.Pointer(nameBuffre)), uintptr(unsafe.Pointer(nSize)))
+	if r1&0xff == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func NetUserGetInfo(serverName *uint16, userName *uint16, level uint32, buf **byte) (neterr error) {
+	r0, _, _ := Syscall6(procNetUserGetInfo.Addr(), 4, uintptr(unsafe.Pointer(serverName)), uintptr(unsafe.Pointer(userName)), uintptr(level), uintptr(unsafe.Pointer(buf)), 0, 0)
+	if r0 != 0 {
+		neterr = Errno(r0)
+	}
+	return
+}
+
+func NetGetJoinInformation(server *uint16, name **uint16, bufType *uint32) (neterr error) {
+	r0, _, _ := Syscall(procNetGetJoinInformation.Addr(), 3, uintptr(unsafe.Pointer(server)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(bufType)))
+	if r0 != 0 {
+		neterr = Errno(r0)
+	}
+	return
+}
+
+func NetApiBufferFree(buf *byte) (neterr error) {
+	r0, _, _ := Syscall(procNetApiBufferFree.Addr(), 1, uintptr(unsafe.Pointer(buf)), 0, 0)
+	if r0 != 0 {
+		neterr = Errno(r0)
+	}
+	return
+}
+
+func LookupAccountSid(systemName *uint16, sid *SID, name *uint16, nameLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) {
+	r1, _, e1 := Syscall9(procLookupAccountSidW.Addr(), 7, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(nameLen)), uintptr(unsafe.Pointer(refdDomainName)), uintptr(unsafe.Pointer(refdDomainNameLen)), uintptr(unsafe.Pointer(use)), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func LookupAccountName(systemName *uint16, accountName *uint16, sid *SID, sidLen *uint32, refdDomainName *uint16, refdDomainNameLen *uint32, use *uint32) (err error) {
+	r1, _, e1 := Syscall9(procLookupAccountNameW.Addr(), 7, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(accountName)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(sidLen)), uintptr(unsafe.Pointer(refdDomainName)), uintptr(unsafe.Pointer(refdDomainNameLen)), uintptr(unsafe.Pointer(use)), 0, 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func ConvertSidToStringSid(sid *SID, stringSid **uint16) (err error) {
+	r1, _, e1 := Syscall(procConvertSidToStringSidW.Addr(), 2, uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(stringSid)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func ConvertStringSidToSid(stringSid *uint16, sid **SID) (err error) {
+	r1, _, e1 := Syscall(procConvertStringSidToSidW.Addr(), 2, uintptr(unsafe.Pointer(stringSid)), uintptr(unsafe.Pointer(sid)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func GetLengthSid(sid *SID) (len uint32) {
+	r0, _, _ := Syscall(procGetLengthSid.Addr(), 1, uintptr(unsafe.Pointer(sid)), 0, 0)
+	len = uint32(r0)
+	return
+}
+
+func CopySid(destSidLen uint32, destSid *SID, srcSid *SID) (err error) {
+	r1, _, e1 := Syscall(procCopySid.Addr(), 3, uintptr(destSidLen), uintptr(unsafe.Pointer(destSid)), uintptr(unsafe.Pointer(srcSid)))
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func OpenProcessToken(h Handle, access uint32, token *Token) (err error) {
+	r1, _, e1 := Syscall(procOpenProcessToken.Addr(), 3, uintptr(h), uintptr(access), uintptr(unsafe.Pointer(token)))
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func GetTokenInformation(t Token, infoClass uint32, info *byte, infoLen uint32, returnedLen *uint32) (err error) {
+	r1, _, e1 := Syscall6(procGetTokenInformation.Addr(), 5, uintptr(t), uintptr(infoClass), uintptr(unsafe.Pointer(info)), uintptr(infoLen), uintptr(unsafe.Pointer(returnedLen)), 0)
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
+
+func GetUserProfileDirectory(t Token, dir *uint16, dirLen *uint32) (err error) {
+	r1, _, e1 := Syscall(procGetUserProfileDirectoryW.Addr(), 3, uintptr(t), uintptr(unsafe.Pointer(dir)), uintptr(unsafe.Pointer(dirLen)))
+	if r1 == 0 {
+		if e1 != 0 {
+			err = error(e1)
+		} else {
+			err = EINVAL
+		}
+	}
+	return
+}
diff --git a/src/pkg/syscall/zsysctl_openbsd.go b/src/syscall/zsysctl_openbsd.go
similarity index 100%
rename from src/pkg/syscall/zsysctl_openbsd.go
rename to src/syscall/zsysctl_openbsd.go
diff --git a/src/pkg/syscall/zsysnum_darwin_386.go b/src/syscall/zsysnum_darwin_386.go
similarity index 100%
rename from src/pkg/syscall/zsysnum_darwin_386.go
rename to src/syscall/zsysnum_darwin_386.go
diff --git a/src/pkg/syscall/zsysnum_darwin_amd64.go b/src/syscall/zsysnum_darwin_amd64.go
similarity index 100%
rename from src/pkg/syscall/zsysnum_darwin_amd64.go
rename to src/syscall/zsysnum_darwin_amd64.go
diff --git a/src/pkg/syscall/zsysnum_dragonfly_386.go b/src/syscall/zsysnum_dragonfly_386.go
similarity index 100%
rename from src/pkg/syscall/zsysnum_dragonfly_386.go
rename to src/syscall/zsysnum_dragonfly_386.go
diff --git a/src/pkg/syscall/zsysnum_dragonfly_amd64.go b/src/syscall/zsysnum_dragonfly_amd64.go
similarity index 100%
rename from src/pkg/syscall/zsysnum_dragonfly_amd64.go
rename to src/syscall/zsysnum_dragonfly_amd64.go
diff --git a/src/pkg/syscall/zsysnum_freebsd_386.go b/src/syscall/zsysnum_freebsd_386.go
similarity index 100%
rename from src/pkg/syscall/zsysnum_freebsd_386.go
rename to src/syscall/zsysnum_freebsd_386.go
diff --git a/src/pkg/syscall/zsysnum_freebsd_amd64.go b/src/syscall/zsysnum_freebsd_amd64.go
similarity index 100%
rename from src/pkg/syscall/zsysnum_freebsd_amd64.go
rename to src/syscall/zsysnum_freebsd_amd64.go
diff --git a/src/pkg/syscall/zsysnum_freebsd_arm.go b/src/syscall/zsysnum_freebsd_arm.go
similarity index 100%
rename from src/pkg/syscall/zsysnum_freebsd_arm.go
rename to src/syscall/zsysnum_freebsd_arm.go
diff --git a/src/pkg/syscall/zsysnum_linux_386.go b/src/syscall/zsysnum_linux_386.go
similarity index 100%
rename from src/pkg/syscall/zsysnum_linux_386.go
rename to src/syscall/zsysnum_linux_386.go
diff --git a/src/pkg/syscall/zsysnum_linux_amd64.go b/src/syscall/zsysnum_linux_amd64.go
similarity index 100%
rename from src/pkg/syscall/zsysnum_linux_amd64.go
rename to src/syscall/zsysnum_linux_amd64.go
diff --git a/src/pkg/syscall/zsysnum_linux_arm.go b/src/syscall/zsysnum_linux_arm.go
similarity index 100%
rename from src/pkg/syscall/zsysnum_linux_arm.go
rename to src/syscall/zsysnum_linux_arm.go
diff --git a/src/pkg/syscall/zsysnum_netbsd_386.go b/src/syscall/zsysnum_netbsd_386.go
similarity index 100%
rename from src/pkg/syscall/zsysnum_netbsd_386.go
rename to src/syscall/zsysnum_netbsd_386.go
diff --git a/src/pkg/syscall/zsysnum_netbsd_amd64.go b/src/syscall/zsysnum_netbsd_amd64.go
similarity index 100%
rename from src/pkg/syscall/zsysnum_netbsd_amd64.go
rename to src/syscall/zsysnum_netbsd_amd64.go
diff --git a/src/pkg/syscall/zsysnum_netbsd_arm.go b/src/syscall/zsysnum_netbsd_arm.go
similarity index 100%
rename from src/pkg/syscall/zsysnum_netbsd_arm.go
rename to src/syscall/zsysnum_netbsd_arm.go
diff --git a/src/pkg/syscall/zsysnum_openbsd_386.go b/src/syscall/zsysnum_openbsd_386.go
similarity index 100%
rename from src/pkg/syscall/zsysnum_openbsd_386.go
rename to src/syscall/zsysnum_openbsd_386.go
diff --git a/src/pkg/syscall/zsysnum_openbsd_amd64.go b/src/syscall/zsysnum_openbsd_amd64.go
similarity index 100%
rename from src/pkg/syscall/zsysnum_openbsd_amd64.go
rename to src/syscall/zsysnum_openbsd_amd64.go
diff --git a/src/syscall/zsysnum_plan9_386.go b/src/syscall/zsysnum_plan9_386.go
new file mode 100644
index 0000000..07498c4
--- /dev/null
+++ b/src/syscall/zsysnum_plan9_386.go
@@ -0,0 +1,49 @@
+// mksysnum_plan9.sh /media/sys/src/libc/9syscall/sys.h
+// MACHINE GENERATED BY THE ABOVE COMMAND; DO NOT EDIT
+
+package syscall
+
+const (
+	SYS_SYSR1       = 0
+	SYS_BIND        = 2
+	SYS_CHDIR       = 3
+	SYS_CLOSE       = 4
+	SYS_DUP         = 5
+	SYS_ALARM       = 6
+	SYS_EXEC        = 7
+	SYS_EXITS       = 8
+	SYS_FAUTH       = 10
+	SYS_SEGBRK      = 12
+	SYS_OPEN        = 14
+	SYS_OSEEK       = 16
+	SYS_SLEEP       = 17
+	SYS_RFORK       = 19
+	SYS_PIPE        = 21
+	SYS_CREATE      = 22
+	SYS_FD2PATH     = 23
+	SYS_BRK_        = 24
+	SYS_REMOVE      = 25
+	SYS_NOTIFY      = 28
+	SYS_NOTED       = 29
+	SYS_SEGATTACH   = 30
+	SYS_SEGDETACH   = 31
+	SYS_SEGFREE     = 32
+	SYS_SEGFLUSH    = 33
+	SYS_RENDEZVOUS  = 34
+	SYS_UNMOUNT     = 35
+	SYS_SEMACQUIRE  = 37
+	SYS_SEMRELEASE  = 38
+	SYS_SEEK        = 39
+	SYS_FVERSION    = 40
+	SYS_ERRSTR      = 41
+	SYS_STAT        = 42
+	SYS_FSTAT       = 43
+	SYS_WSTAT       = 44
+	SYS_FWSTAT      = 45
+	SYS_MOUNT       = 46
+	SYS_AWAIT       = 47
+	SYS_PREAD       = 50
+	SYS_PWRITE      = 51
+	SYS_TSEMACQUIRE = 52
+	SYS_NSEC        = 53
+)
diff --git a/src/syscall/zsysnum_plan9_amd64.go b/src/syscall/zsysnum_plan9_amd64.go
new file mode 100644
index 0000000..07498c4
--- /dev/null
+++ b/src/syscall/zsysnum_plan9_amd64.go
@@ -0,0 +1,49 @@
+// mksysnum_plan9.sh /media/sys/src/libc/9syscall/sys.h
+// MACHINE GENERATED BY THE ABOVE COMMAND; DO NOT EDIT
+
+package syscall
+
+const (
+	SYS_SYSR1       = 0
+	SYS_BIND        = 2
+	SYS_CHDIR       = 3
+	SYS_CLOSE       = 4
+	SYS_DUP         = 5
+	SYS_ALARM       = 6
+	SYS_EXEC        = 7
+	SYS_EXITS       = 8
+	SYS_FAUTH       = 10
+	SYS_SEGBRK      = 12
+	SYS_OPEN        = 14
+	SYS_OSEEK       = 16
+	SYS_SLEEP       = 17
+	SYS_RFORK       = 19
+	SYS_PIPE        = 21
+	SYS_CREATE      = 22
+	SYS_FD2PATH     = 23
+	SYS_BRK_        = 24
+	SYS_REMOVE      = 25
+	SYS_NOTIFY      = 28
+	SYS_NOTED       = 29
+	SYS_SEGATTACH   = 30
+	SYS_SEGDETACH   = 31
+	SYS_SEGFREE     = 32
+	SYS_SEGFLUSH    = 33
+	SYS_RENDEZVOUS  = 34
+	SYS_UNMOUNT     = 35
+	SYS_SEMACQUIRE  = 37
+	SYS_SEMRELEASE  = 38
+	SYS_SEEK        = 39
+	SYS_FVERSION    = 40
+	SYS_ERRSTR      = 41
+	SYS_STAT        = 42
+	SYS_FSTAT       = 43
+	SYS_WSTAT       = 44
+	SYS_FWSTAT      = 45
+	SYS_MOUNT       = 46
+	SYS_AWAIT       = 47
+	SYS_PREAD       = 50
+	SYS_PWRITE      = 51
+	SYS_TSEMACQUIRE = 52
+	SYS_NSEC        = 53
+)
diff --git a/src/pkg/syscall/zsysnum_solaris_amd64.go b/src/syscall/zsysnum_solaris_amd64.go
similarity index 100%
rename from src/pkg/syscall/zsysnum_solaris_amd64.go
rename to src/syscall/zsysnum_solaris_amd64.go
diff --git a/src/pkg/syscall/zsysnum_windows_386.go b/src/syscall/zsysnum_windows_386.go
similarity index 100%
rename from src/pkg/syscall/zsysnum_windows_386.go
rename to src/syscall/zsysnum_windows_386.go
diff --git a/src/pkg/syscall/zsysnum_windows_amd64.go b/src/syscall/zsysnum_windows_amd64.go
similarity index 100%
rename from src/pkg/syscall/zsysnum_windows_amd64.go
rename to src/syscall/zsysnum_windows_amd64.go
diff --git a/src/pkg/syscall/ztypes_darwin_386.go b/src/syscall/ztypes_darwin_386.go
similarity index 100%
rename from src/pkg/syscall/ztypes_darwin_386.go
rename to src/syscall/ztypes_darwin_386.go
diff --git a/src/pkg/syscall/ztypes_darwin_amd64.go b/src/syscall/ztypes_darwin_amd64.go
similarity index 100%
rename from src/pkg/syscall/ztypes_darwin_amd64.go
rename to src/syscall/ztypes_darwin_amd64.go
diff --git a/src/pkg/syscall/ztypes_dragonfly_386.go b/src/syscall/ztypes_dragonfly_386.go
similarity index 100%
rename from src/pkg/syscall/ztypes_dragonfly_386.go
rename to src/syscall/ztypes_dragonfly_386.go
diff --git a/src/pkg/syscall/ztypes_dragonfly_amd64.go b/src/syscall/ztypes_dragonfly_amd64.go
similarity index 100%
rename from src/pkg/syscall/ztypes_dragonfly_amd64.go
rename to src/syscall/ztypes_dragonfly_amd64.go
diff --git a/src/pkg/syscall/ztypes_freebsd_386.go b/src/syscall/ztypes_freebsd_386.go
similarity index 100%
rename from src/pkg/syscall/ztypes_freebsd_386.go
rename to src/syscall/ztypes_freebsd_386.go
diff --git a/src/pkg/syscall/ztypes_freebsd_amd64.go b/src/syscall/ztypes_freebsd_amd64.go
similarity index 100%
rename from src/pkg/syscall/ztypes_freebsd_amd64.go
rename to src/syscall/ztypes_freebsd_amd64.go
diff --git a/src/pkg/syscall/ztypes_freebsd_arm.go b/src/syscall/ztypes_freebsd_arm.go
similarity index 100%
rename from src/pkg/syscall/ztypes_freebsd_arm.go
rename to src/syscall/ztypes_freebsd_arm.go
diff --git a/src/pkg/syscall/ztypes_linux_386.go b/src/syscall/ztypes_linux_386.go
similarity index 100%
rename from src/pkg/syscall/ztypes_linux_386.go
rename to src/syscall/ztypes_linux_386.go
diff --git a/src/pkg/syscall/ztypes_linux_amd64.go b/src/syscall/ztypes_linux_amd64.go
similarity index 100%
rename from src/pkg/syscall/ztypes_linux_amd64.go
rename to src/syscall/ztypes_linux_amd64.go
diff --git a/src/pkg/syscall/ztypes_linux_arm.go b/src/syscall/ztypes_linux_arm.go
similarity index 100%
rename from src/pkg/syscall/ztypes_linux_arm.go
rename to src/syscall/ztypes_linux_arm.go
diff --git a/src/pkg/syscall/ztypes_netbsd_386.go b/src/syscall/ztypes_netbsd_386.go
similarity index 100%
rename from src/pkg/syscall/ztypes_netbsd_386.go
rename to src/syscall/ztypes_netbsd_386.go
diff --git a/src/pkg/syscall/ztypes_netbsd_amd64.go b/src/syscall/ztypes_netbsd_amd64.go
similarity index 100%
rename from src/pkg/syscall/ztypes_netbsd_amd64.go
rename to src/syscall/ztypes_netbsd_amd64.go
diff --git a/src/pkg/syscall/ztypes_netbsd_arm.go b/src/syscall/ztypes_netbsd_arm.go
similarity index 100%
rename from src/pkg/syscall/ztypes_netbsd_arm.go
rename to src/syscall/ztypes_netbsd_arm.go
diff --git a/src/pkg/syscall/ztypes_openbsd_386.go b/src/syscall/ztypes_openbsd_386.go
similarity index 100%
rename from src/pkg/syscall/ztypes_openbsd_386.go
rename to src/syscall/ztypes_openbsd_386.go
diff --git a/src/pkg/syscall/ztypes_openbsd_amd64.go b/src/syscall/ztypes_openbsd_amd64.go
similarity index 100%
rename from src/pkg/syscall/ztypes_openbsd_amd64.go
rename to src/syscall/ztypes_openbsd_amd64.go
diff --git a/src/pkg/syscall/ztypes_plan9_386.go b/src/syscall/ztypes_plan9_386.go
similarity index 100%
rename from src/pkg/syscall/ztypes_plan9_386.go
rename to src/syscall/ztypes_plan9_386.go
diff --git a/src/pkg/syscall/ztypes_plan9_amd64.go b/src/syscall/ztypes_plan9_amd64.go
similarity index 100%
rename from src/pkg/syscall/ztypes_plan9_amd64.go
rename to src/syscall/ztypes_plan9_amd64.go
diff --git a/src/pkg/syscall/ztypes_solaris_amd64.go b/src/syscall/ztypes_solaris_amd64.go
similarity index 100%
rename from src/pkg/syscall/ztypes_solaris_amd64.go
rename to src/syscall/ztypes_solaris_amd64.go
diff --git a/src/syscall/ztypes_windows.go b/src/syscall/ztypes_windows.go
new file mode 100644
index 0000000..4c8a99a
--- /dev/null
+++ b/src/syscall/ztypes_windows.go
@@ -0,0 +1,1105 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package syscall
+
+const (
+	// Windows errors.
+	ERROR_FILE_NOT_FOUND      Errno = 2
+	ERROR_PATH_NOT_FOUND      Errno = 3
+	ERROR_ACCESS_DENIED       Errno = 5
+	ERROR_NO_MORE_FILES       Errno = 18
+	ERROR_HANDLE_EOF          Errno = 38
+	ERROR_NETNAME_DELETED     Errno = 64
+	ERROR_FILE_EXISTS         Errno = 80
+	ERROR_BROKEN_PIPE         Errno = 109
+	ERROR_BUFFER_OVERFLOW     Errno = 111
+	ERROR_INSUFFICIENT_BUFFER Errno = 122
+	ERROR_MOD_NOT_FOUND       Errno = 126
+	ERROR_PROC_NOT_FOUND      Errno = 127
+	ERROR_ALREADY_EXISTS      Errno = 183
+	ERROR_ENVVAR_NOT_FOUND    Errno = 203
+	ERROR_MORE_DATA           Errno = 234
+	ERROR_OPERATION_ABORTED   Errno = 995
+	ERROR_IO_PENDING          Errno = 997
+	ERROR_NOT_FOUND           Errno = 1168
+	ERROR_PRIVILEGE_NOT_HELD  Errno = 1314
+	WSAEACCES                 Errno = 10013
+	WSAECONNRESET             Errno = 10054
+)
+
+const (
+	// Invented values to support what package os expects.
+	O_RDONLY   = 0x00000
+	O_WRONLY   = 0x00001
+	O_RDWR     = 0x00002
+	O_CREAT    = 0x00040
+	O_EXCL     = 0x00080
+	O_NOCTTY   = 0x00100
+	O_TRUNC    = 0x00200
+	O_NONBLOCK = 0x00800
+	O_APPEND   = 0x00400
+	O_SYNC     = 0x01000
+	O_ASYNC    = 0x02000
+	O_CLOEXEC  = 0x80000
+)
+
+const (
+	// More invented values for signals
+	SIGHUP  = Signal(0x1)
+	SIGINT  = Signal(0x2)
+	SIGQUIT = Signal(0x3)
+	SIGILL  = Signal(0x4)
+	SIGTRAP = Signal(0x5)
+	SIGABRT = Signal(0x6)
+	SIGBUS  = Signal(0x7)
+	SIGFPE  = Signal(0x8)
+	SIGKILL = Signal(0x9)
+	SIGSEGV = Signal(0xb)
+	SIGPIPE = Signal(0xd)
+	SIGALRM = Signal(0xe)
+	SIGTERM = Signal(0xf)
+)
+
+var signals = [...]string{
+	1:  "hangup",
+	2:  "interrupt",
+	3:  "quit",
+	4:  "illegal instruction",
+	5:  "trace/breakpoint trap",
+	6:  "aborted",
+	7:  "bus error",
+	8:  "floating point exception",
+	9:  "killed",
+	10: "user defined signal 1",
+	11: "segmentation fault",
+	12: "user defined signal 2",
+	13: "broken pipe",
+	14: "alarm clock",
+	15: "terminated",
+}
+
+const (
+	GENERIC_READ    = 0x80000000
+	GENERIC_WRITE   = 0x40000000
+	GENERIC_EXECUTE = 0x20000000
+	GENERIC_ALL     = 0x10000000
+
+	FILE_LIST_DIRECTORY   = 0x00000001
+	FILE_APPEND_DATA      = 0x00000004
+	FILE_WRITE_ATTRIBUTES = 0x00000100
+
+	FILE_SHARE_READ              = 0x00000001
+	FILE_SHARE_WRITE             = 0x00000002
+	FILE_SHARE_DELETE            = 0x00000004
+	FILE_ATTRIBUTE_READONLY      = 0x00000001
+	FILE_ATTRIBUTE_HIDDEN        = 0x00000002
+	FILE_ATTRIBUTE_SYSTEM        = 0x00000004
+	FILE_ATTRIBUTE_DIRECTORY     = 0x00000010
+	FILE_ATTRIBUTE_ARCHIVE       = 0x00000020
+	FILE_ATTRIBUTE_NORMAL        = 0x00000080
+	FILE_ATTRIBUTE_REPARSE_POINT = 0x00000400
+
+	INVALID_FILE_ATTRIBUTES = 0xffffffff
+
+	CREATE_NEW        = 1
+	CREATE_ALWAYS     = 2
+	OPEN_EXISTING     = 3
+	OPEN_ALWAYS       = 4
+	TRUNCATE_EXISTING = 5
+
+	FILE_FLAG_OPEN_REPARSE_POINT = 0x00200000
+	FILE_FLAG_BACKUP_SEMANTICS   = 0x02000000
+	FILE_FLAG_OVERLAPPED         = 0x40000000
+
+	HANDLE_FLAG_INHERIT    = 0x00000001
+	STARTF_USESTDHANDLES   = 0x00000100
+	STARTF_USESHOWWINDOW   = 0x00000001
+	DUPLICATE_CLOSE_SOURCE = 0x00000001
+	DUPLICATE_SAME_ACCESS  = 0x00000002
+
+	STD_INPUT_HANDLE  = -10
+	STD_OUTPUT_HANDLE = -11
+	STD_ERROR_HANDLE  = -12
+
+	FILE_BEGIN   = 0
+	FILE_CURRENT = 1
+	FILE_END     = 2
+
+	LANG_ENGLISH       = 0x09
+	SUBLANG_ENGLISH_US = 0x01
+
+	FORMAT_MESSAGE_ALLOCATE_BUFFER = 256
+	FORMAT_MESSAGE_IGNORE_INSERTS  = 512
+	FORMAT_MESSAGE_FROM_STRING     = 1024
+	FORMAT_MESSAGE_FROM_HMODULE    = 2048
+	FORMAT_MESSAGE_FROM_SYSTEM     = 4096
+	FORMAT_MESSAGE_ARGUMENT_ARRAY  = 8192
+	FORMAT_MESSAGE_MAX_WIDTH_MASK  = 255
+
+	MAX_PATH      = 260
+	MAX_LONG_PATH = 32768
+
+	MAX_COMPUTERNAME_LENGTH = 15
+
+	TIME_ZONE_ID_UNKNOWN  = 0
+	TIME_ZONE_ID_STANDARD = 1
+
+	TIME_ZONE_ID_DAYLIGHT = 2
+	IGNORE                = 0
+	INFINITE              = 0xffffffff
+
+	WAIT_TIMEOUT   = 258
+	WAIT_ABANDONED = 0x00000080
+	WAIT_OBJECT_0  = 0x00000000
+	WAIT_FAILED    = 0xFFFFFFFF
+
+	CREATE_NEW_PROCESS_GROUP   = 0x00000200
+	CREATE_UNICODE_ENVIRONMENT = 0x00000400
+
+	PROCESS_TERMINATE         = 1
+	PROCESS_QUERY_INFORMATION = 0x00000400
+	SYNCHRONIZE               = 0x00100000
+
+	PAGE_READONLY          = 0x02
+	PAGE_READWRITE         = 0x04
+	PAGE_WRITECOPY         = 0x08
+	PAGE_EXECUTE_READ      = 0x20
+	PAGE_EXECUTE_READWRITE = 0x40
+	PAGE_EXECUTE_WRITECOPY = 0x80
+
+	FILE_MAP_COPY    = 0x01
+	FILE_MAP_WRITE   = 0x02
+	FILE_MAP_READ    = 0x04
+	FILE_MAP_EXECUTE = 0x20
+
+	CTRL_C_EVENT     = 0
+	CTRL_BREAK_EVENT = 1
+)
+
+const (
+	// flags for CreateToolhelp32Snapshot
+	TH32CS_SNAPHEAPLIST = 0x01
+	TH32CS_SNAPPROCESS  = 0x02
+	TH32CS_SNAPTHREAD   = 0x04
+	TH32CS_SNAPMODULE   = 0x08
+	TH32CS_SNAPMODULE32 = 0x10
+	TH32CS_SNAPALL      = TH32CS_SNAPHEAPLIST | TH32CS_SNAPMODULE | TH32CS_SNAPPROCESS | TH32CS_SNAPTHREAD
+	TH32CS_INHERIT      = 0x80000000
+)
+
+const (
+	// do not reorder
+	FILE_NOTIFY_CHANGE_FILE_NAME = 1 << iota
+	FILE_NOTIFY_CHANGE_DIR_NAME
+	FILE_NOTIFY_CHANGE_ATTRIBUTES
+	FILE_NOTIFY_CHANGE_SIZE
+	FILE_NOTIFY_CHANGE_LAST_WRITE
+	FILE_NOTIFY_CHANGE_LAST_ACCESS
+	FILE_NOTIFY_CHANGE_CREATION
+)
+
+const (
+	// do not reorder
+	FILE_ACTION_ADDED = iota + 1
+	FILE_ACTION_REMOVED
+	FILE_ACTION_MODIFIED
+	FILE_ACTION_RENAMED_OLD_NAME
+	FILE_ACTION_RENAMED_NEW_NAME
+)
+
+const (
+	// wincrypt.h
+	PROV_RSA_FULL                    = 1
+	PROV_RSA_SIG                     = 2
+	PROV_DSS                         = 3
+	PROV_FORTEZZA                    = 4
+	PROV_MS_EXCHANGE                 = 5
+	PROV_SSL                         = 6
+	PROV_RSA_SCHANNEL                = 12
+	PROV_DSS_DH                      = 13
+	PROV_EC_ECDSA_SIG                = 14
+	PROV_EC_ECNRA_SIG                = 15
+	PROV_EC_ECDSA_FULL               = 16
+	PROV_EC_ECNRA_FULL               = 17
+	PROV_DH_SCHANNEL                 = 18
+	PROV_SPYRUS_LYNKS                = 20
+	PROV_RNG                         = 21
+	PROV_INTEL_SEC                   = 22
+	PROV_REPLACE_OWF                 = 23
+	PROV_RSA_AES                     = 24
+	CRYPT_VERIFYCONTEXT              = 0xF0000000
+	CRYPT_NEWKEYSET                  = 0x00000008
+	CRYPT_DELETEKEYSET               = 0x00000010
+	CRYPT_MACHINE_KEYSET             = 0x00000020
+	CRYPT_SILENT                     = 0x00000040
+	CRYPT_DEFAULT_CONTAINER_OPTIONAL = 0x00000080
+
+	USAGE_MATCH_TYPE_AND = 0
+	USAGE_MATCH_TYPE_OR  = 1
+
+	X509_ASN_ENCODING   = 0x00000001
+	PKCS_7_ASN_ENCODING = 0x00010000
+
+	CERT_STORE_PROV_MEMORY = 2
+
+	CERT_STORE_ADD_ALWAYS = 4
+
+	CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG = 0x00000004
+
+	CERT_TRUST_NO_ERROR                          = 0x00000000
+	CERT_TRUST_IS_NOT_TIME_VALID                 = 0x00000001
+	CERT_TRUST_IS_REVOKED                        = 0x00000004
+	CERT_TRUST_IS_NOT_SIGNATURE_VALID            = 0x00000008
+	CERT_TRUST_IS_NOT_VALID_FOR_USAGE            = 0x00000010
+	CERT_TRUST_IS_UNTRUSTED_ROOT                 = 0x00000020
+	CERT_TRUST_REVOCATION_STATUS_UNKNOWN         = 0x00000040
+	CERT_TRUST_IS_CYCLIC                         = 0x00000080
+	CERT_TRUST_INVALID_EXTENSION                 = 0x00000100
+	CERT_TRUST_INVALID_POLICY_CONSTRAINTS        = 0x00000200
+	CERT_TRUST_INVALID_BASIC_CONSTRAINTS         = 0x00000400
+	CERT_TRUST_INVALID_NAME_CONSTRAINTS          = 0x00000800
+	CERT_TRUST_HAS_NOT_SUPPORTED_NAME_CONSTRAINT = 0x00001000
+	CERT_TRUST_HAS_NOT_DEFINED_NAME_CONSTRAINT   = 0x00002000
+	CERT_TRUST_HAS_NOT_PERMITTED_NAME_CONSTRAINT = 0x00004000
+	CERT_TRUST_HAS_EXCLUDED_NAME_CONSTRAINT      = 0x00008000
+	CERT_TRUST_IS_OFFLINE_REVOCATION             = 0x01000000
+	CERT_TRUST_NO_ISSUANCE_CHAIN_POLICY          = 0x02000000
+	CERT_TRUST_IS_EXPLICIT_DISTRUST              = 0x04000000
+	CERT_TRUST_HAS_NOT_SUPPORTED_CRITICAL_EXT    = 0x08000000
+
+	CERT_CHAIN_POLICY_BASE              = 1
+	CERT_CHAIN_POLICY_AUTHENTICODE      = 2
+	CERT_CHAIN_POLICY_AUTHENTICODE_TS   = 3
+	CERT_CHAIN_POLICY_SSL               = 4
+	CERT_CHAIN_POLICY_BASIC_CONSTRAINTS = 5
+	CERT_CHAIN_POLICY_NT_AUTH           = 6
+	CERT_CHAIN_POLICY_MICROSOFT_ROOT    = 7
+	CERT_CHAIN_POLICY_EV                = 8
+
+	CERT_E_EXPIRED       = 0x800B0101
+	CERT_E_ROLE          = 0x800B0103
+	CERT_E_PURPOSE       = 0x800B0106
+	CERT_E_UNTRUSTEDROOT = 0x800B0109
+	CERT_E_CN_NO_MATCH   = 0x800B010F
+
+	AUTHTYPE_CLIENT = 1
+	AUTHTYPE_SERVER = 2
+)
+
+var (
+	OID_PKIX_KP_SERVER_AUTH = []byte("1.3.6.1.5.5.7.3.1\x00")
+	OID_SERVER_GATED_CRYPTO = []byte("1.3.6.1.4.1.311.10.3.3\x00")
+	OID_SGC_NETSCAPE        = []byte("2.16.840.1.113730.4.1\x00")
+)
+
+// Invented values to support what package os expects.
+type Timeval struct {
+	Sec  int32
+	Usec int32
+}
+
+func (tv *Timeval) Nanoseconds() int64 {
+	return (int64(tv.Sec)*1e6 + int64(tv.Usec)) * 1e3
+}
+
+func NsecToTimeval(nsec int64) (tv Timeval) {
+	tv.Sec = int32(nsec / 1e9)
+	tv.Usec = int32(nsec % 1e9 / 1e3)
+	return
+}
+
+type SecurityAttributes struct {
+	Length             uint32
+	SecurityDescriptor uintptr
+	InheritHandle      uint32
+}
+
+type Overlapped struct {
+	Internal     uintptr
+	InternalHigh uintptr
+	Offset       uint32
+	OffsetHigh   uint32
+	HEvent       Handle
+}
+
+type FileNotifyInformation struct {
+	NextEntryOffset uint32
+	Action          uint32
+	FileNameLength  uint32
+	FileName        uint16
+}
+
+type Filetime struct {
+	LowDateTime  uint32
+	HighDateTime uint32
+}
+
+// Nanoseconds returns Filetime ft in nanoseconds
+// since Epoch (00:00:00 UTC, January 1, 1970).
+func (ft *Filetime) Nanoseconds() int64 {
+	// 100-nanosecond intervals since January 1, 1601
+	nsec := int64(ft.HighDateTime)<<32 + int64(ft.LowDateTime)
+	// change starting time to the Epoch (00:00:00 UTC, January 1, 1970)
+	nsec -= 116444736000000000
+	// convert into nanoseconds
+	nsec *= 100
+	return nsec
+}
+
+func NsecToFiletime(nsec int64) (ft Filetime) {
+	// convert into 100-nanosecond
+	nsec /= 100
+	// change starting time to January 1, 1601
+	nsec += 116444736000000000
+	// split into high / low
+	ft.LowDateTime = uint32(nsec & 0xffffffff)
+	ft.HighDateTime = uint32(nsec >> 32 & 0xffffffff)
+	return ft
+}
+
+type Win32finddata struct {
+	FileAttributes    uint32
+	CreationTime      Filetime
+	LastAccessTime    Filetime
+	LastWriteTime     Filetime
+	FileSizeHigh      uint32
+	FileSizeLow       uint32
+	Reserved0         uint32
+	Reserved1         uint32
+	FileName          [MAX_PATH - 1]uint16
+	AlternateFileName [13]uint16
+}
+
+// This is the actual system call structure.
+// Win32finddata is what we committed to in Go 1.
+type win32finddata1 struct {
+	FileAttributes    uint32
+	CreationTime      Filetime
+	LastAccessTime    Filetime
+	LastWriteTime     Filetime
+	FileSizeHigh      uint32
+	FileSizeLow       uint32
+	Reserved0         uint32
+	Reserved1         uint32
+	FileName          [MAX_PATH]uint16
+	AlternateFileName [14]uint16
+}
+
+func copyFindData(dst *Win32finddata, src *win32finddata1) {
+	dst.FileAttributes = src.FileAttributes
+	dst.CreationTime = src.CreationTime
+	dst.LastAccessTime = src.LastAccessTime
+	dst.LastWriteTime = src.LastWriteTime
+	dst.FileSizeHigh = src.FileSizeHigh
+	dst.FileSizeLow = src.FileSizeLow
+	dst.Reserved0 = src.Reserved0
+	dst.Reserved1 = src.Reserved1
+
+	// The src is 1 element bigger than dst, but it must be NUL.
+	copy(dst.FileName[:], src.FileName[:])
+	copy(dst.AlternateFileName[:], src.AlternateFileName[:])
+}
+
+type ByHandleFileInformation struct {
+	FileAttributes     uint32
+	CreationTime       Filetime
+	LastAccessTime     Filetime
+	LastWriteTime      Filetime
+	VolumeSerialNumber uint32
+	FileSizeHigh       uint32
+	FileSizeLow        uint32
+	NumberOfLinks      uint32
+	FileIndexHigh      uint32
+	FileIndexLow       uint32
+}
+
+const (
+	GetFileExInfoStandard = 0
+	GetFileExMaxInfoLevel = 1
+)
+
+type Win32FileAttributeData struct {
+	FileAttributes uint32
+	CreationTime   Filetime
+	LastAccessTime Filetime
+	LastWriteTime  Filetime
+	FileSizeHigh   uint32
+	FileSizeLow    uint32
+}
+
+// ShowWindow constants
+const (
+	// winuser.h
+	SW_HIDE            = 0
+	SW_NORMAL          = 1
+	SW_SHOWNORMAL      = 1
+	SW_SHOWMINIMIZED   = 2
+	SW_SHOWMAXIMIZED   = 3
+	SW_MAXIMIZE        = 3
+	SW_SHOWNOACTIVATE  = 4
+	SW_SHOW            = 5
+	SW_MINIMIZE        = 6
+	SW_SHOWMINNOACTIVE = 7
+	SW_SHOWNA          = 8
+	SW_RESTORE         = 9
+	SW_SHOWDEFAULT     = 10
+	SW_FORCEMINIMIZE   = 11
+)
+
+type StartupInfo struct {
+	Cb            uint32
+	_             *uint16
+	Desktop       *uint16
+	Title         *uint16
+	X             uint32
+	Y             uint32
+	XSize         uint32
+	YSize         uint32
+	XCountChars   uint32
+	YCountChars   uint32
+	FillAttribute uint32
+	Flags         uint32
+	ShowWindow    uint16
+	_             uint16
+	_             *byte
+	StdInput      Handle
+	StdOutput     Handle
+	StdErr        Handle
+}
+
+type ProcessInformation struct {
+	Process   Handle
+	Thread    Handle
+	ProcessId uint32
+	ThreadId  uint32
+}
+
+type ProcessEntry32 struct {
+	Size            uint32
+	Usage           uint32
+	ProcessID       uint32
+	DefaultHeapID   uintptr
+	ModuleID        uint32
+	Threads         uint32
+	ParentProcessID uint32
+	PriClassBase    int32
+	Flags           uint32
+	ExeFile         [MAX_PATH]uint16
+}
+
+type Systemtime struct {
+	Year         uint16
+	Month        uint16
+	DayOfWeek    uint16
+	Day          uint16
+	Hour         uint16
+	Minute       uint16
+	Second       uint16
+	Milliseconds uint16
+}
+
+type Timezoneinformation struct {
+	Bias         int32
+	StandardName [32]uint16
+	StandardDate Systemtime
+	StandardBias int32
+	DaylightName [32]uint16
+	DaylightDate Systemtime
+	DaylightBias int32
+}
+
+// Socket related.
+
+const (
+	AF_UNSPEC  = 0
+	AF_UNIX    = 1
+	AF_INET    = 2
+	AF_INET6   = 23
+	AF_NETBIOS = 17
+
+	SOCK_STREAM    = 1
+	SOCK_DGRAM     = 2
+	SOCK_RAW       = 3
+	SOCK_SEQPACKET = 5
+
+	IPPROTO_IP   = 0
+	IPPROTO_IPV6 = 0x29
+	IPPROTO_TCP  = 6
+	IPPROTO_UDP  = 17
+
+	SOL_SOCKET                = 0xffff
+	SO_REUSEADDR              = 4
+	SO_KEEPALIVE              = 8
+	SO_DONTROUTE              = 16
+	SO_BROADCAST              = 32
+	SO_LINGER                 = 128
+	SO_RCVBUF                 = 0x1002
+	SO_SNDBUF                 = 0x1001
+	SO_UPDATE_ACCEPT_CONTEXT  = 0x700b
+	SO_UPDATE_CONNECT_CONTEXT = 0x7010
+
+	IOC_OUT                            = 0x40000000
+	IOC_IN                             = 0x80000000
+	IOC_VENDOR                         = 0x18000000
+	IOC_INOUT                          = IOC_IN | IOC_OUT
+	IOC_WS2                            = 0x08000000
+	SIO_GET_EXTENSION_FUNCTION_POINTER = IOC_INOUT | IOC_WS2 | 6
+	SIO_KEEPALIVE_VALS                 = IOC_IN | IOC_VENDOR | 4
+	SIO_UDP_CONNRESET                  = IOC_IN | IOC_VENDOR | 12
+
+	// cf. http://support.microsoft.com/default.aspx?scid=kb;en-us;257460
+
+	IP_TOS             = 0x3
+	IP_TTL             = 0x4
+	IP_MULTICAST_IF    = 0x9
+	IP_MULTICAST_TTL   = 0xa
+	IP_MULTICAST_LOOP  = 0xb
+	IP_ADD_MEMBERSHIP  = 0xc
+	IP_DROP_MEMBERSHIP = 0xd
+
+	IPV6_V6ONLY         = 0x1b
+	IPV6_UNICAST_HOPS   = 0x4
+	IPV6_MULTICAST_IF   = 0x9
+	IPV6_MULTICAST_HOPS = 0xa
+	IPV6_MULTICAST_LOOP = 0xb
+	IPV6_JOIN_GROUP     = 0xc
+	IPV6_LEAVE_GROUP    = 0xd
+
+	SOMAXCONN = 0x7fffffff
+
+	TCP_NODELAY = 1
+
+	SHUT_RD   = 0
+	SHUT_WR   = 1
+	SHUT_RDWR = 2
+
+	WSADESCRIPTION_LEN = 256
+	WSASYS_STATUS_LEN  = 128
+)
+
+type WSABuf struct {
+	Len uint32
+	Buf *byte
+}
+
+// Invented values to support what package os expects.
+const (
+	S_IFMT   = 0x1f000
+	S_IFIFO  = 0x1000
+	S_IFCHR  = 0x2000
+	S_IFDIR  = 0x4000
+	S_IFBLK  = 0x6000
+	S_IFREG  = 0x8000
+	S_IFLNK  = 0xa000
+	S_IFSOCK = 0xc000
+	S_ISUID  = 0x800
+	S_ISGID  = 0x400
+	S_ISVTX  = 0x200
+	S_IRUSR  = 0x100
+	S_IWRITE = 0x80
+	S_IWUSR  = 0x80
+	S_IXUSR  = 0x40
+)
+
+const (
+	FILE_TYPE_CHAR    = 0x0002
+	FILE_TYPE_DISK    = 0x0001
+	FILE_TYPE_PIPE    = 0x0003
+	FILE_TYPE_REMOTE  = 0x8000
+	FILE_TYPE_UNKNOWN = 0x0000
+)
+
+type Hostent struct {
+	Name     *byte
+	Aliases  **byte
+	AddrType uint16
+	Length   uint16
+	AddrList **byte
+}
+
+type Protoent struct {
+	Name    *byte
+	Aliases **byte
+	Proto   uint16
+}
+
+const (
+	DNS_TYPE_A       = 0x0001
+	DNS_TYPE_NS      = 0x0002
+	DNS_TYPE_MD      = 0x0003
+	DNS_TYPE_MF      = 0x0004
+	DNS_TYPE_CNAME   = 0x0005
+	DNS_TYPE_SOA     = 0x0006
+	DNS_TYPE_MB      = 0x0007
+	DNS_TYPE_MG      = 0x0008
+	DNS_TYPE_MR      = 0x0009
+	DNS_TYPE_NULL    = 0x000a
+	DNS_TYPE_WKS     = 0x000b
+	DNS_TYPE_PTR     = 0x000c
+	DNS_TYPE_HINFO   = 0x000d
+	DNS_TYPE_MINFO   = 0x000e
+	DNS_TYPE_MX      = 0x000f
+	DNS_TYPE_TEXT    = 0x0010
+	DNS_TYPE_RP      = 0x0011
+	DNS_TYPE_AFSDB   = 0x0012
+	DNS_TYPE_X25     = 0x0013
+	DNS_TYPE_ISDN    = 0x0014
+	DNS_TYPE_RT      = 0x0015
+	DNS_TYPE_NSAP    = 0x0016
+	DNS_TYPE_NSAPPTR = 0x0017
+	DNS_TYPE_SIG     = 0x0018
+	DNS_TYPE_KEY     = 0x0019
+	DNS_TYPE_PX      = 0x001a
+	DNS_TYPE_GPOS    = 0x001b
+	DNS_TYPE_AAAA    = 0x001c
+	DNS_TYPE_LOC     = 0x001d
+	DNS_TYPE_NXT     = 0x001e
+	DNS_TYPE_EID     = 0x001f
+	DNS_TYPE_NIMLOC  = 0x0020
+	DNS_TYPE_SRV     = 0x0021
+	DNS_TYPE_ATMA    = 0x0022
+	DNS_TYPE_NAPTR   = 0x0023
+	DNS_TYPE_KX      = 0x0024
+	DNS_TYPE_CERT    = 0x0025
+	DNS_TYPE_A6      = 0x0026
+	DNS_TYPE_DNAME   = 0x0027
+	DNS_TYPE_SINK    = 0x0028
+	DNS_TYPE_OPT     = 0x0029
+	DNS_TYPE_DS      = 0x002B
+	DNS_TYPE_RRSIG   = 0x002E
+	DNS_TYPE_NSEC    = 0x002F
+	DNS_TYPE_DNSKEY  = 0x0030
+	DNS_TYPE_DHCID   = 0x0031
+	DNS_TYPE_UINFO   = 0x0064
+	DNS_TYPE_UID     = 0x0065
+	DNS_TYPE_GID     = 0x0066
+	DNS_TYPE_UNSPEC  = 0x0067
+	DNS_TYPE_ADDRS   = 0x00f8
+	DNS_TYPE_TKEY    = 0x00f9
+	DNS_TYPE_TSIG    = 0x00fa
+	DNS_TYPE_IXFR    = 0x00fb
+	DNS_TYPE_AXFR    = 0x00fc
+	DNS_TYPE_MAILB   = 0x00fd
+	DNS_TYPE_MAILA   = 0x00fe
+	DNS_TYPE_ALL     = 0x00ff
+	DNS_TYPE_ANY     = 0x00ff
+	DNS_TYPE_WINS    = 0xff01
+	DNS_TYPE_WINSR   = 0xff02
+	DNS_TYPE_NBSTAT  = 0xff01
+)
+
+const (
+	DNS_INFO_NO_RECORDS = 0x251D
+)
+
+const (
+	// flags inside DNSRecord.Dw
+	DnsSectionQuestion   = 0x0000
+	DnsSectionAnswer     = 0x0001
+	DnsSectionAuthority  = 0x0002
+	DnsSectionAdditional = 0x0003
+)
+
+type DNSSRVData struct {
+	Target   *uint16
+	Priority uint16
+	Weight   uint16
+	Port     uint16
+	Pad      uint16
+}
+
+type DNSPTRData struct {
+	Host *uint16
+}
+
+type DNSMXData struct {
+	NameExchange *uint16
+	Preference   uint16
+	Pad          uint16
+}
+
+type DNSTXTData struct {
+	StringCount uint16
+	StringArray [1]*uint16
+}
+
+type DNSRecord struct {
+	Next     *DNSRecord
+	Name     *uint16
+	Type     uint16
+	Length   uint16
+	Dw       uint32
+	Ttl      uint32
+	Reserved uint32
+	Data     [40]byte
+}
+
+const (
+	TF_DISCONNECT         = 1
+	TF_REUSE_SOCKET       = 2
+	TF_WRITE_BEHIND       = 4
+	TF_USE_DEFAULT_WORKER = 0
+	TF_USE_SYSTEM_THREAD  = 16
+	TF_USE_KERNEL_APC     = 32
+)
+
+type TransmitFileBuffers struct {
+	Head       uintptr
+	HeadLength uint32
+	Tail       uintptr
+	TailLength uint32
+}
+
+const (
+	IFF_UP           = 1
+	IFF_BROADCAST    = 2
+	IFF_LOOPBACK     = 4
+	IFF_POINTTOPOINT = 8
+	IFF_MULTICAST    = 16
+)
+
+const SIO_GET_INTERFACE_LIST = 0x4004747F
+
+// TODO(mattn): SockaddrGen is union of sockaddr/sockaddr_in/sockaddr_in6_old.
+// will be fixed to change variable type as suitable.
+
+type SockaddrGen [24]byte
+
+type InterfaceInfo struct {
+	Flags            uint32
+	Address          SockaddrGen
+	BroadcastAddress SockaddrGen
+	Netmask          SockaddrGen
+}
+
+type IpAddressString struct {
+	String [16]byte
+}
+
+type IpMaskString IpAddressString
+
+type IpAddrString struct {
+	Next      *IpAddrString
+	IpAddress IpAddressString
+	IpMask    IpMaskString
+	Context   uint32
+}
+
+const MAX_ADAPTER_NAME_LENGTH = 256
+const MAX_ADAPTER_DESCRIPTION_LENGTH = 128
+const MAX_ADAPTER_ADDRESS_LENGTH = 8
+
+type IpAdapterInfo struct {
+	Next                *IpAdapterInfo
+	ComboIndex          uint32
+	AdapterName         [MAX_ADAPTER_NAME_LENGTH + 4]byte
+	Description         [MAX_ADAPTER_DESCRIPTION_LENGTH + 4]byte
+	AddressLength       uint32
+	Address             [MAX_ADAPTER_ADDRESS_LENGTH]byte
+	Index               uint32
+	Type                uint32
+	DhcpEnabled         uint32
+	CurrentIpAddress    *IpAddrString
+	IpAddressList       IpAddrString
+	GatewayList         IpAddrString
+	DhcpServer          IpAddrString
+	HaveWins            bool
+	PrimaryWinsServer   IpAddrString
+	SecondaryWinsServer IpAddrString
+	LeaseObtained       int64
+	LeaseExpires        int64
+}
+
+const MAXLEN_PHYSADDR = 8
+const MAX_INTERFACE_NAME_LEN = 256
+const MAXLEN_IFDESCR = 256
+
+type MibIfRow struct {
+	Name            [MAX_INTERFACE_NAME_LEN]uint16
+	Index           uint32
+	Type            uint32
+	Mtu             uint32
+	Speed           uint32
+	PhysAddrLen     uint32
+	PhysAddr        [MAXLEN_PHYSADDR]byte
+	AdminStatus     uint32
+	OperStatus      uint32
+	LastChange      uint32
+	InOctets        uint32
+	InUcastPkts     uint32
+	InNUcastPkts    uint32
+	InDiscards      uint32
+	InErrors        uint32
+	InUnknownProtos uint32
+	OutOctets       uint32
+	OutUcastPkts    uint32
+	OutNUcastPkts   uint32
+	OutDiscards     uint32
+	OutErrors       uint32
+	OutQLen         uint32
+	DescrLen        uint32
+	Descr           [MAXLEN_IFDESCR]byte
+}
+
+type CertContext struct {
+	EncodingType uint32
+	EncodedCert  *byte
+	Length       uint32
+	CertInfo     uintptr
+	Store        Handle
+}
+
+type CertChainContext struct {
+	Size                       uint32
+	TrustStatus                CertTrustStatus
+	ChainCount                 uint32
+	Chains                     **CertSimpleChain
+	LowerQualityChainCount     uint32
+	LowerQualityChains         **CertChainContext
+	HasRevocationFreshnessTime uint32
+	RevocationFreshnessTime    uint32
+}
+
+type CertSimpleChain struct {
+	Size                       uint32
+	TrustStatus                CertTrustStatus
+	NumElements                uint32
+	Elements                   **CertChainElement
+	TrustListInfo              uintptr
+	HasRevocationFreshnessTime uint32
+	RevocationFreshnessTime    uint32
+}
+
+type CertChainElement struct {
+	Size              uint32
+	CertContext       *CertContext
+	TrustStatus       CertTrustStatus
+	RevocationInfo    *CertRevocationInfo
+	IssuanceUsage     *CertEnhKeyUsage
+	ApplicationUsage  *CertEnhKeyUsage
+	ExtendedErrorInfo *uint16
+}
+
+type CertRevocationInfo struct {
+	Size             uint32
+	RevocationResult uint32
+	RevocationOid    *byte
+	OidSpecificInfo  uintptr
+	HasFreshnessTime uint32
+	FreshnessTime    uint32
+	CrlInfo          uintptr // *CertRevocationCrlInfo
+}
+
+type CertTrustStatus struct {
+	ErrorStatus uint32
+	InfoStatus  uint32
+}
+
+type CertUsageMatch struct {
+	Type  uint32
+	Usage CertEnhKeyUsage
+}
+
+type CertEnhKeyUsage struct {
+	Length           uint32
+	UsageIdentifiers **byte
+}
+
+type CertChainPara struct {
+	Size                         uint32
+	RequestedUsage               CertUsageMatch
+	RequstedIssuancePolicy       CertUsageMatch
+	URLRetrievalTimeout          uint32
+	CheckRevocationFreshnessTime uint32
+	RevocationFreshnessTime      uint32
+	CacheResync                  *Filetime
+}
+
+type CertChainPolicyPara struct {
+	Size            uint32
+	Flags           uint32
+	ExtraPolicyPara uintptr
+}
+
+type SSLExtraCertChainPolicyPara struct {
+	Size       uint32
+	AuthType   uint32
+	Checks     uint32
+	ServerName *uint16
+}
+
+type CertChainPolicyStatus struct {
+	Size              uint32
+	Error             uint32
+	ChainIndex        uint32
+	ElementIndex      uint32
+	ExtraPolicyStatus uintptr
+}
+
+const (
+	// do not reorder
+	HKEY_CLASSES_ROOT = 0x80000000 + iota
+	HKEY_CURRENT_USER
+	HKEY_LOCAL_MACHINE
+	HKEY_USERS
+	HKEY_PERFORMANCE_DATA
+	HKEY_CURRENT_CONFIG
+	HKEY_DYN_DATA
+
+	KEY_QUERY_VALUE        = 1
+	KEY_SET_VALUE          = 2
+	KEY_CREATE_SUB_KEY     = 4
+	KEY_ENUMERATE_SUB_KEYS = 8
+	KEY_NOTIFY             = 16
+	KEY_CREATE_LINK        = 32
+	KEY_WRITE              = 0x20006
+	KEY_EXECUTE            = 0x20019
+	KEY_READ               = 0x20019
+	KEY_WOW64_64KEY        = 0x0100
+	KEY_WOW64_32KEY        = 0x0200
+	KEY_ALL_ACCESS         = 0xf003f
+)
+
+const (
+	// do not reorder
+	REG_NONE = iota
+	REG_SZ
+	REG_EXPAND_SZ
+	REG_BINARY
+	REG_DWORD_LITTLE_ENDIAN
+	REG_DWORD_BIG_ENDIAN
+	REG_LINK
+	REG_MULTI_SZ
+	REG_RESOURCE_LIST
+	REG_FULL_RESOURCE_DESCRIPTOR
+	REG_RESOURCE_REQUIREMENTS_LIST
+	REG_QWORD_LITTLE_ENDIAN
+	REG_DWORD = REG_DWORD_LITTLE_ENDIAN
+	REG_QWORD = REG_QWORD_LITTLE_ENDIAN
+)
+
+type AddrinfoW struct {
+	Flags     int32
+	Family    int32
+	Socktype  int32
+	Protocol  int32
+	Addrlen   uintptr
+	Canonname *uint16
+	Addr      uintptr
+	Next      *AddrinfoW
+}
+
+const (
+	AI_PASSIVE     = 1
+	AI_CANONNAME   = 2
+	AI_NUMERICHOST = 4
+)
+
+type GUID struct {
+	Data1 uint32
+	Data2 uint16
+	Data3 uint16
+	Data4 [8]byte
+}
+
+var WSAID_CONNECTEX = GUID{
+	0x25a207b9,
+	0xddf3,
+	0x4660,
+	[8]byte{0x8e, 0xe9, 0x76, 0xe5, 0x8c, 0x74, 0x06, 0x3e},
+}
+
+const (
+	FILE_SKIP_COMPLETION_PORT_ON_SUCCESS = 1
+	FILE_SKIP_SET_EVENT_ON_HANDLE        = 2
+)
+
+const (
+	WSAPROTOCOL_LEN    = 255
+	MAX_PROTOCOL_CHAIN = 7
+	BASE_PROTOCOL      = 1
+	LAYERED_PROTOCOL   = 0
+
+	XP1_CONNECTIONLESS           = 0x00000001
+	XP1_GUARANTEED_DELIVERY      = 0x00000002
+	XP1_GUARANTEED_ORDER         = 0x00000004
+	XP1_MESSAGE_ORIENTED         = 0x00000008
+	XP1_PSEUDO_STREAM            = 0x00000010
+	XP1_GRACEFUL_CLOSE           = 0x00000020
+	XP1_EXPEDITED_DATA           = 0x00000040
+	XP1_CONNECT_DATA             = 0x00000080
+	XP1_DISCONNECT_DATA          = 0x00000100
+	XP1_SUPPORT_BROADCAST        = 0x00000200
+	XP1_SUPPORT_MULTIPOINT       = 0x00000400
+	XP1_MULTIPOINT_CONTROL_PLANE = 0x00000800
+	XP1_MULTIPOINT_DATA_PLANE    = 0x00001000
+	XP1_QOS_SUPPORTED            = 0x00002000
+	XP1_UNI_SEND                 = 0x00008000
+	XP1_UNI_RECV                 = 0x00010000
+	XP1_IFS_HANDLES              = 0x00020000
+	XP1_PARTIAL_MESSAGE          = 0x00040000
+	XP1_SAN_SUPPORT_SDP          = 0x00080000
+
+	PFL_MULTIPLE_PROTO_ENTRIES  = 0x00000001
+	PFL_RECOMMENDED_PROTO_ENTRY = 0x00000002
+	PFL_HIDDEN                  = 0x00000004
+	PFL_MATCHES_PROTOCOL_ZERO   = 0x00000008
+	PFL_NETWORKDIRECT_PROVIDER  = 0x00000010
+)
+
+type WSAProtocolInfo struct {
+	ServiceFlags1     uint32
+	ServiceFlags2     uint32
+	ServiceFlags3     uint32
+	ServiceFlags4     uint32
+	ProviderFlags     uint32
+	ProviderId        GUID
+	CatalogEntryId    uint32
+	ProtocolChain     WSAProtocolChain
+	Version           int32
+	AddressFamily     int32
+	MaxSockAddr       int32
+	MinSockAddr       int32
+	SocketType        int32
+	Protocol          int32
+	ProtocolMaxOffset int32
+	NetworkByteOrder  int32
+	SecurityScheme    int32
+	MessageSize       uint32
+	ProviderReserved  uint32
+	ProtocolName      [WSAPROTOCOL_LEN + 1]uint16
+}
+
+type WSAProtocolChain struct {
+	ChainLen     int32
+	ChainEntries [MAX_PROTOCOL_CHAIN]uint32
+}
+
+type TCPKeepalive struct {
+	OnOff    uint32
+	Time     uint32
+	Interval uint32
+}
+
+type reparseDataBuffer struct {
+	ReparseTag        uint32
+	ReparseDataLength uint16
+	Reserved          uint16
+
+	// SymbolicLinkReparseBuffer
+	SubstituteNameOffset uint16
+	SubstituteNameLength uint16
+	PrintNameOffset      uint16
+	PrintNameLength      uint16
+	Flags                uint32
+	PathBuffer           [1]uint16
+}
+
+const (
+	FSCTL_GET_REPARSE_POINT          = 0x900A8
+	MAXIMUM_REPARSE_DATA_BUFFER_SIZE = 16 * 1024
+	IO_REPARSE_TAG_SYMLINK           = 0xA000000C
+	SYMBOLIC_LINK_FLAG_DIRECTORY     = 0x1
+)
diff --git a/src/pkg/syscall/ztypes_windows_386.go b/src/syscall/ztypes_windows_386.go
similarity index 100%
rename from src/pkg/syscall/ztypes_windows_386.go
rename to src/syscall/ztypes_windows_386.go
diff --git a/src/pkg/syscall/ztypes_windows_amd64.go b/src/syscall/ztypes_windows_amd64.go
similarity index 100%
rename from src/pkg/syscall/ztypes_windows_amd64.go
rename to src/syscall/ztypes_windows_amd64.go
diff --git a/src/pkg/testing/allocs.go b/src/testing/allocs.go
similarity index 100%
rename from src/pkg/testing/allocs.go
rename to src/testing/allocs.go
diff --git a/src/testing/allocs_test.go b/src/testing/allocs_test.go
new file mode 100644
index 0000000..ec17daa
--- /dev/null
+++ b/src/testing/allocs_test.go
@@ -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.
+
+package testing_test
+
+import "testing"
+
+var global interface{}
+
+var allocsPerRunTests = []struct {
+	name   string
+	fn     func()
+	allocs float64
+}{
+	{"alloc *byte", func() { global = new(*byte) }, 1},
+	{"alloc complex128", func() { global = new(complex128) }, 1},
+	{"alloc float64", func() { global = new(float64) }, 1},
+	{"alloc int32", func() { global = new(int32) }, 1},
+	{"alloc byte", func() { global = new(byte) }, 1},
+}
+
+func TestAllocsPerRun(t *testing.T) {
+	for _, tt := range allocsPerRunTests {
+		if allocs := testing.AllocsPerRun(100, tt.fn); allocs != tt.allocs {
+			t.Errorf("AllocsPerRun(100, %s) = %v, want %v", tt.name, allocs, tt.allocs)
+		}
+	}
+}
diff --git a/src/testing/benchmark.go b/src/testing/benchmark.go
new file mode 100644
index 0000000..ffd5376
--- /dev/null
+++ b/src/testing/benchmark.go
@@ -0,0 +1,446 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package testing
+
+import (
+	"flag"
+	"fmt"
+	"os"
+	"runtime"
+	"sync"
+	"sync/atomic"
+	"time"
+)
+
+var matchBenchmarks = flag.String("test.bench", "", "regular expression to select benchmarks to run")
+var benchTime = flag.Duration("test.benchtime", 1*time.Second, "approximate run time for each benchmark")
+var benchmarkMemory = flag.Bool("test.benchmem", false, "print memory allocations for benchmarks")
+
+// Global lock to ensure only one benchmark runs at a time.
+var benchmarkLock sync.Mutex
+
+// Used for every benchmark for measuring memory.
+var memStats runtime.MemStats
+
+// An internal type but exported because it is cross-package; part of the implementation
+// of the "go test" command.
+type InternalBenchmark struct {
+	Name string
+	F    func(b *B)
+}
+
+// B is a type passed to Benchmark functions to manage benchmark
+// timing and to specify the number of iterations to run.
+type B struct {
+	common
+	N                int
+	previousN        int           // number of iterations in the previous run
+	previousDuration time.Duration // total duration of the previous run
+	benchmark        InternalBenchmark
+	bytes            int64
+	timerOn          bool
+	showAllocResult  bool
+	result           BenchmarkResult
+	parallelism      int // RunParallel creates parallelism*GOMAXPROCS goroutines
+	// The initial states of memStats.Mallocs and memStats.TotalAlloc.
+	startAllocs uint64
+	startBytes  uint64
+	// The net total of this test after being run.
+	netAllocs uint64
+	netBytes  uint64
+}
+
+// StartTimer starts timing a test.  This function is called automatically
+// before a benchmark starts, but it can also used to resume timing after
+// a call to StopTimer.
+func (b *B) StartTimer() {
+	if !b.timerOn {
+		runtime.ReadMemStats(&memStats)
+		b.startAllocs = memStats.Mallocs
+		b.startBytes = memStats.TotalAlloc
+		b.start = time.Now()
+		b.timerOn = true
+	}
+}
+
+// StopTimer stops timing a test.  This can be used to pause the timer
+// while performing complex initialization that you don't
+// want to measure.
+func (b *B) StopTimer() {
+	if b.timerOn {
+		b.duration += time.Now().Sub(b.start)
+		runtime.ReadMemStats(&memStats)
+		b.netAllocs += memStats.Mallocs - b.startAllocs
+		b.netBytes += memStats.TotalAlloc - b.startBytes
+		b.timerOn = false
+	}
+}
+
+// ResetTimer zeros the elapsed benchmark time and memory allocation counters.
+// It does not affect whether the timer is running.
+func (b *B) ResetTimer() {
+	if b.timerOn {
+		runtime.ReadMemStats(&memStats)
+		b.startAllocs = memStats.Mallocs
+		b.startBytes = memStats.TotalAlloc
+		b.start = time.Now()
+	}
+	b.duration = 0
+	b.netAllocs = 0
+	b.netBytes = 0
+}
+
+// SetBytes records the number of bytes processed in a single operation.
+// If this is called, the benchmark will report ns/op and MB/s.
+func (b *B) SetBytes(n int64) { b.bytes = n }
+
+// ReportAllocs enables malloc statistics for this benchmark.
+// It is equivalent to setting -test.benchmem, but it only affects the
+// benchmark function that calls ReportAllocs.
+func (b *B) ReportAllocs() {
+	b.showAllocResult = true
+}
+
+func (b *B) nsPerOp() int64 {
+	if b.N <= 0 {
+		return 0
+	}
+	return b.duration.Nanoseconds() / int64(b.N)
+}
+
+// runN runs a single benchmark for the specified number of iterations.
+func (b *B) runN(n int) {
+	benchmarkLock.Lock()
+	defer benchmarkLock.Unlock()
+	// Try to get a comparable environment for each run
+	// by clearing garbage from previous runs.
+	runtime.GC()
+	b.N = n
+	b.parallelism = 1
+	b.ResetTimer()
+	b.StartTimer()
+	b.benchmark.F(b)
+	b.StopTimer()
+	b.previousN = n
+	b.previousDuration = b.duration
+}
+
+func min(x, y int) int {
+	if x > y {
+		return y
+	}
+	return x
+}
+
+func max(x, y int) int {
+	if x < y {
+		return y
+	}
+	return x
+}
+
+// roundDown10 rounds a number down to the nearest power of 10.
+func roundDown10(n int) int {
+	var tens = 0
+	// tens = floor(log_10(n))
+	for n >= 10 {
+		n = n / 10
+		tens++
+	}
+	// result = 10^tens
+	result := 1
+	for i := 0; i < tens; i++ {
+		result *= 10
+	}
+	return result
+}
+
+// roundUp rounds x up to a number of the form [1eX, 2eX, 3eX, 5eX].
+func roundUp(n int) int {
+	base := roundDown10(n)
+	switch {
+	case n <= base:
+		return base
+	case n <= (2 * base):
+		return 2 * base
+	case n <= (3 * base):
+		return 3 * base
+	case n <= (5 * base):
+		return 5 * base
+	default:
+		return 10 * base
+	}
+}
+
+// run times the benchmark function in a separate goroutine.
+func (b *B) run() BenchmarkResult {
+	go b.launch()
+	<-b.signal
+	return b.result
+}
+
+// launch launches the benchmark function.  It gradually increases the number
+// of benchmark iterations until the benchmark runs for the requested benchtime.
+// It prints timing information in this form
+//		testing.BenchmarkHello	100000		19 ns/op
+// launch is run by the run function as a separate goroutine.
+func (b *B) launch() {
+	// Run the benchmark for a single iteration in case it's expensive.
+	n := 1
+
+	// Signal that we're done whether we return normally
+	// or by FailNow's runtime.Goexit.
+	defer func() {
+		b.signal <- b
+	}()
+
+	b.runN(n)
+	// Run the benchmark for at least the specified amount of time.
+	d := *benchTime
+	for !b.failed && b.duration < d && n < 1e9 {
+		last := n
+		// Predict required iterations.
+		if b.nsPerOp() == 0 {
+			n = 1e9
+		} else {
+			n = int(d.Nanoseconds() / b.nsPerOp())
+		}
+		// Run more iterations than we think we'll need (1.2x).
+		// Don't grow too fast in case we had timing errors previously.
+		// Be sure to run at least one more than last time.
+		n = max(min(n+n/5, 100*last), last+1)
+		// Round up to something easy to read.
+		n = roundUp(n)
+		b.runN(n)
+	}
+	b.result = BenchmarkResult{b.N, b.duration, b.bytes, b.netAllocs, b.netBytes}
+}
+
+// The results of a benchmark run.
+type BenchmarkResult struct {
+	N         int           // The number of iterations.
+	T         time.Duration // The total time taken.
+	Bytes     int64         // Bytes processed in one iteration.
+	MemAllocs uint64        // The total number of memory allocations.
+	MemBytes  uint64        // The total number of bytes allocated.
+}
+
+func (r BenchmarkResult) NsPerOp() int64 {
+	if r.N <= 0 {
+		return 0
+	}
+	return r.T.Nanoseconds() / int64(r.N)
+}
+
+func (r BenchmarkResult) mbPerSec() float64 {
+	if r.Bytes <= 0 || r.T <= 0 || r.N <= 0 {
+		return 0
+	}
+	return (float64(r.Bytes) * float64(r.N) / 1e6) / r.T.Seconds()
+}
+
+func (r BenchmarkResult) AllocsPerOp() int64 {
+	if r.N <= 0 {
+		return 0
+	}
+	return int64(r.MemAllocs) / int64(r.N)
+}
+
+func (r BenchmarkResult) AllocedBytesPerOp() int64 {
+	if r.N <= 0 {
+		return 0
+	}
+	return int64(r.MemBytes) / int64(r.N)
+}
+
+func (r BenchmarkResult) String() string {
+	mbs := r.mbPerSec()
+	mb := ""
+	if mbs != 0 {
+		mb = fmt.Sprintf("\t%7.2f MB/s", mbs)
+	}
+	nsop := r.NsPerOp()
+	ns := fmt.Sprintf("%10d ns/op", nsop)
+	if r.N > 0 && nsop < 100 {
+		// The format specifiers here make sure that
+		// the ones digits line up for all three possible formats.
+		if nsop < 10 {
+			ns = fmt.Sprintf("%13.2f ns/op", float64(r.T.Nanoseconds())/float64(r.N))
+		} else {
+			ns = fmt.Sprintf("%12.1f ns/op", float64(r.T.Nanoseconds())/float64(r.N))
+		}
+	}
+	return fmt.Sprintf("%8d\t%s%s", r.N, ns, mb)
+}
+
+func (r BenchmarkResult) MemString() string {
+	return fmt.Sprintf("%8d B/op\t%8d allocs/op",
+		r.AllocedBytesPerOp(), r.AllocsPerOp())
+}
+
+// An internal function but exported because it is cross-package; part of the implementation
+// of the "go test" command.
+func RunBenchmarks(matchString func(pat, str string) (bool, error), benchmarks []InternalBenchmark) {
+	// If no flag was specified, don't run benchmarks.
+	if len(*matchBenchmarks) == 0 {
+		return
+	}
+	for _, Benchmark := range benchmarks {
+		matched, err := matchString(*matchBenchmarks, Benchmark.Name)
+		if err != nil {
+			fmt.Fprintf(os.Stderr, "testing: invalid regexp for -test.bench: %s\n", err)
+			os.Exit(1)
+		}
+		if !matched {
+			continue
+		}
+		for _, procs := range cpuList {
+			runtime.GOMAXPROCS(procs)
+			b := &B{
+				common: common{
+					signal: make(chan interface{}),
+				},
+				benchmark: Benchmark,
+			}
+			benchName := Benchmark.Name
+			if procs != 1 {
+				benchName = fmt.Sprintf("%s-%d", Benchmark.Name, procs)
+			}
+			fmt.Printf("%s\t", benchName)
+			r := b.run()
+			if b.failed {
+				// The output could be very long here, but probably isn't.
+				// We print it all, regardless, because we don't want to trim the reason
+				// the benchmark failed.
+				fmt.Printf("--- FAIL: %s\n%s", benchName, b.output)
+				continue
+			}
+			results := r.String()
+			if *benchmarkMemory || b.showAllocResult {
+				results += "\t" + r.MemString()
+			}
+			fmt.Println(results)
+			// Unlike with tests, we ignore the -chatty flag and always print output for
+			// benchmarks since the output generation time will skew the results.
+			if len(b.output) > 0 {
+				b.trimOutput()
+				fmt.Printf("--- BENCH: %s\n%s", benchName, b.output)
+			}
+			if p := runtime.GOMAXPROCS(-1); p != procs {
+				fmt.Fprintf(os.Stderr, "testing: %s left GOMAXPROCS set to %d\n", benchName, p)
+			}
+		}
+	}
+}
+
+// trimOutput shortens the output from a benchmark, which can be very long.
+func (b *B) trimOutput() {
+	// The output is likely to appear multiple times because the benchmark
+	// is run multiple times, but at least it will be seen. This is not a big deal
+	// because benchmarks rarely print, but just in case, we trim it if it's too long.
+	const maxNewlines = 10
+	for nlCount, j := 0, 0; j < len(b.output); j++ {
+		if b.output[j] == '\n' {
+			nlCount++
+			if nlCount >= maxNewlines {
+				b.output = append(b.output[:j], "\n\t... [output truncated]\n"...)
+				break
+			}
+		}
+	}
+}
+
+// A PB is used by RunParallel for running parallel benchmarks.
+type PB struct {
+	globalN *uint64 // shared between all worker goroutines iteration counter
+	grain   uint64  // acquire that many iterations from globalN at once
+	cache   uint64  // local cache of acquired iterations
+	bN      uint64  // total number of iterations to execute (b.N)
+}
+
+// Next reports whether there are more iterations to execute.
+func (pb *PB) Next() bool {
+	if pb.cache == 0 {
+		n := atomic.AddUint64(pb.globalN, pb.grain)
+		if n <= pb.bN {
+			pb.cache = pb.grain
+		} else if n < pb.bN+pb.grain {
+			pb.cache = pb.bN + pb.grain - n
+		} else {
+			return false
+		}
+	}
+	pb.cache--
+	return true
+}
+
+// RunParallel runs a benchmark in parallel.
+// It creates multiple goroutines and distributes b.N iterations among them.
+// The number of goroutines defaults to GOMAXPROCS. To increase parallelism for
+// non-CPU-bound benchmarks, call SetParallelism before RunParallel.
+// RunParallel is usually used with the go test -cpu flag.
+//
+// The body function will be run in each goroutine. It should set up any
+// goroutine-local state and then iterate until pb.Next returns false.
+// It should not use the StartTimer, StopTimer, or ResetTimer functions,
+// because they have global effect.
+func (b *B) RunParallel(body func(*PB)) {
+	// Calculate grain size as number of iterations that take ~100µs.
+	// 100µs is enough to amortize the overhead and provide sufficient
+	// dynamic load balancing.
+	grain := uint64(0)
+	if b.previousN > 0 && b.previousDuration > 0 {
+		grain = 1e5 * uint64(b.previousN) / uint64(b.previousDuration)
+	}
+	if grain < 1 {
+		grain = 1
+	}
+	// We expect the inner loop and function call to take at least 10ns,
+	// so do not do more than 100µs/10ns=1e4 iterations.
+	if grain > 1e4 {
+		grain = 1e4
+	}
+
+	n := uint64(0)
+	numProcs := b.parallelism * runtime.GOMAXPROCS(0)
+	var wg sync.WaitGroup
+	wg.Add(numProcs)
+	for p := 0; p < numProcs; p++ {
+		go func() {
+			defer wg.Done()
+			pb := &PB{
+				globalN: &n,
+				grain:   grain,
+				bN:      uint64(b.N),
+			}
+			body(pb)
+		}()
+	}
+	wg.Wait()
+	if n <= uint64(b.N) && !b.Failed() {
+		b.Fatal("RunParallel: body exited without pb.Next() == false")
+	}
+}
+
+// SetParallelism sets the number of goroutines used by RunParallel to p*GOMAXPROCS.
+// There is usually no need to call SetParallelism for CPU-bound benchmarks.
+// If p is less than 1, this call will have no effect.
+func (b *B) SetParallelism(p int) {
+	if p >= 1 {
+		b.parallelism = p
+	}
+}
+
+// Benchmark benchmarks a single function. Useful for creating
+// custom benchmarks that do not use the "go test" command.
+func Benchmark(f func(b *B)) BenchmarkResult {
+	b := &B{
+		common: common{
+			signal: make(chan interface{}),
+		},
+		benchmark: InternalBenchmark{"", f},
+	}
+	return b.run()
+}
diff --git a/src/testing/benchmark_test.go b/src/testing/benchmark_test.go
new file mode 100644
index 0000000..431bb53
--- /dev/null
+++ b/src/testing/benchmark_test.go
@@ -0,0 +1,113 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package testing_test
+
+import (
+	"bytes"
+	"runtime"
+	"sync/atomic"
+	"testing"
+	"text/template"
+)
+
+var roundDownTests = []struct {
+	v, expected int
+}{
+	{1, 1},
+	{9, 1},
+	{10, 10},
+	{11, 10},
+	{100, 100},
+	{101, 100},
+	{999, 100},
+	{1000, 1000},
+	{1001, 1000},
+}
+
+func TestRoundDown10(t *testing.T) {
+	for _, tt := range roundDownTests {
+		actual := testing.RoundDown10(tt.v)
+		if tt.expected != actual {
+			t.Errorf("roundDown10(%d): expected %d, actual %d", tt.v, tt.expected, actual)
+		}
+	}
+}
+
+var roundUpTests = []struct {
+	v, expected int
+}{
+	{0, 1},
+	{1, 1},
+	{2, 2},
+	{3, 3},
+	{5, 5},
+	{9, 10},
+	{999, 1000},
+	{1000, 1000},
+	{1400, 2000},
+	{1700, 2000},
+	{2700, 3000},
+	{4999, 5000},
+	{5000, 5000},
+	{5001, 10000},
+}
+
+func TestRoundUp(t *testing.T) {
+	for _, tt := range roundUpTests {
+		actual := testing.RoundUp(tt.v)
+		if tt.expected != actual {
+			t.Errorf("roundUp(%d): expected %d, actual %d", tt.v, tt.expected, actual)
+		}
+	}
+}
+
+func TestRunParallel(t *testing.T) {
+	testing.Benchmark(func(b *testing.B) {
+		procs := uint32(0)
+		iters := uint64(0)
+		b.SetParallelism(3)
+		b.RunParallel(func(pb *testing.PB) {
+			atomic.AddUint32(&procs, 1)
+			for pb.Next() {
+				atomic.AddUint64(&iters, 1)
+			}
+		})
+		if want := uint32(3 * runtime.GOMAXPROCS(0)); procs != want {
+			t.Errorf("got %v procs, want %v", procs, want)
+		}
+		if iters != uint64(b.N) {
+			t.Errorf("got %v iters, want %v", iters, b.N)
+		}
+	})
+}
+
+func TestRunParallelFail(t *testing.T) {
+	testing.Benchmark(func(b *testing.B) {
+		b.RunParallel(func(pb *testing.PB) {
+			// The function must be able to log/abort
+			// w/o crashing/deadlocking the whole benchmark.
+			b.Log("log")
+			b.Error("error")
+		})
+	})
+}
+
+func ExampleB_RunParallel() {
+	// Parallel benchmark for text/template.Template.Execute on a single object.
+	testing.Benchmark(func(b *testing.B) {
+		templ := template.Must(template.New("test").Parse("Hello, {{.}}!"))
+		// RunParallel will create GOMAXPROCS goroutines
+		// and distribute work among them.
+		b.RunParallel(func(pb *testing.PB) {
+			// Each goroutine has its own bytes.Buffer.
+			var buf bytes.Buffer
+			for pb.Next() {
+				// The loop body is executed b.N times total across all goroutines.
+				buf.Reset()
+				templ.Execute(&buf, "World")
+			}
+		})
+	})
+}
diff --git a/src/testing/cover.go b/src/testing/cover.go
new file mode 100644
index 0000000..a4ce37f
--- /dev/null
+++ b/src/testing/cover.go
@@ -0,0 +1,112 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Support for test coverage.
+
+package testing
+
+import (
+	"fmt"
+	"os"
+	"sync/atomic"
+)
+
+// CoverBlock records the coverage data for a single basic block.
+// NOTE: This struct is internal to the testing infrastructure and may change.
+// It is not covered (yet) by the Go 1 compatibility guidelines.
+type CoverBlock struct {
+	Line0 uint32
+	Col0  uint16
+	Line1 uint32
+	Col1  uint16
+	Stmts uint16
+}
+
+var cover Cover
+
+// Cover records information about test coverage checking.
+// NOTE: This struct is internal to the testing infrastructure and may change.
+// It is not covered (yet) by the Go 1 compatibility guidelines.
+type Cover struct {
+	Mode            string
+	Counters        map[string][]uint32
+	Blocks          map[string][]CoverBlock
+	CoveredPackages string
+}
+
+// Coverage reports the current code coverage as a fraction in the range [0, 1].
+// If coverage is not enabled, Coverage returns 0.
+//
+// When running a large set of sequential test cases, checking Coverage after each one
+// can be useful for identifying which test cases exercise new code paths.
+// It is not a replacement for the reports generated by 'go test -cover' and
+// 'go tool cover'.
+func Coverage() float64 {
+	var n, d int64
+	for _, counters := range cover.Counters {
+		for i := range counters {
+			if atomic.LoadUint32(&counters[i]) > 0 {
+				n++
+			}
+			d++
+		}
+	}
+	if d == 0 {
+		return 0
+	}
+	return float64(n) / float64(d)
+}
+
+// RegisterCover records the coverage data accumulators for the tests.
+// NOTE: This function is internal to the testing infrastructure and may change.
+// It is not covered (yet) by the Go 1 compatibility guidelines.
+func RegisterCover(c Cover) {
+	cover = c
+}
+
+// mustBeNil checks the error and, if present, reports it and exits.
+func mustBeNil(err error) {
+	if err != nil {
+		fmt.Fprintf(os.Stderr, "testing: %s\n", err)
+		os.Exit(2)
+	}
+}
+
+// coverReport reports the coverage percentage and writes a coverage profile if requested.
+func coverReport() {
+	var f *os.File
+	var err error
+	if *coverProfile != "" {
+		f, err = os.Create(toOutputDir(*coverProfile))
+		mustBeNil(err)
+		fmt.Fprintf(f, "mode: %s\n", cover.Mode)
+		defer func() { mustBeNil(f.Close()) }()
+	}
+
+	var active, total int64
+	var count uint32
+	for name, counts := range cover.Counters {
+		blocks := cover.Blocks[name]
+		for i := range counts {
+			stmts := int64(blocks[i].Stmts)
+			total += stmts
+			count = atomic.LoadUint32(&counts[i]) // For -mode=atomic.
+			if count > 0 {
+				active += stmts
+			}
+			if f != nil {
+				_, err := fmt.Fprintf(f, "%s:%d.%d,%d.%d %d %d\n", name,
+					blocks[i].Line0, blocks[i].Col0,
+					blocks[i].Line1, blocks[i].Col1,
+					stmts,
+					count)
+				mustBeNil(err)
+			}
+		}
+	}
+	if total == 0 {
+		total = 1
+	}
+	fmt.Printf("coverage: %.1f%% of statements%s\n", 100*float64(active)/float64(total), cover.CoveredPackages)
+}
diff --git a/src/testing/example.go b/src/testing/example.go
new file mode 100644
index 0000000..f5762e4
--- /dev/null
+++ b/src/testing/example.go
@@ -0,0 +1,100 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package testing
+
+import (
+	"bytes"
+	"fmt"
+	"io"
+	"os"
+	"strings"
+	"time"
+)
+
+type InternalExample struct {
+	Name   string
+	F      func()
+	Output string
+}
+
+func RunExamples(matchString func(pat, str string) (bool, error), examples []InternalExample) (ok bool) {
+	ok = true
+
+	var eg InternalExample
+
+	for _, eg = range examples {
+		matched, err := matchString(*match, eg.Name)
+		if err != nil {
+			fmt.Fprintf(os.Stderr, "testing: invalid regexp for -test.run: %s\n", err)
+			os.Exit(1)
+		}
+		if !matched {
+			continue
+		}
+		if !runExample(eg) {
+			ok = false
+		}
+	}
+
+	return
+}
+
+func runExample(eg InternalExample) (ok bool) {
+	if *chatty {
+		fmt.Printf("=== RUN: %s\n", eg.Name)
+	}
+
+	// Capture stdout.
+	stdout := os.Stdout
+	r, w, err := os.Pipe()
+	if err != nil {
+		fmt.Fprintln(os.Stderr, err)
+		os.Exit(1)
+	}
+	os.Stdout = w
+	outC := make(chan string)
+	go func() {
+		buf := new(bytes.Buffer)
+		_, err := io.Copy(buf, r)
+		r.Close()
+		if err != nil {
+			fmt.Fprintf(os.Stderr, "testing: copying pipe: %v\n", err)
+			os.Exit(1)
+		}
+		outC <- buf.String()
+	}()
+
+	start := time.Now()
+	ok = true
+
+	// Clean up in a deferred call so we can recover if the example panics.
+	defer func() {
+		dstr := fmtDuration(time.Now().Sub(start))
+
+		// Close pipe, restore stdout, get output.
+		w.Close()
+		os.Stdout = stdout
+		out := <-outC
+
+		var fail string
+		err := recover()
+		if g, e := strings.TrimSpace(out), strings.TrimSpace(eg.Output); g != e && err == nil {
+			fail = fmt.Sprintf("got:\n%s\nwant:\n%s\n", g, e)
+		}
+		if fail != "" || err != nil {
+			fmt.Printf("--- FAIL: %s (%s)\n%s", eg.Name, dstr, fail)
+			ok = false
+		} else if *chatty {
+			fmt.Printf("--- PASS: %s (%s)\n", eg.Name, dstr)
+		}
+		if err != nil {
+			panic(err)
+		}
+	}()
+
+	// Run example.
+	eg.F()
+	return
+}
diff --git a/src/pkg/testing/export_test.go b/src/testing/export_test.go
similarity index 100%
rename from src/pkg/testing/export_test.go
rename to src/testing/export_test.go
diff --git a/src/pkg/testing/iotest/logger.go b/src/testing/iotest/logger.go
similarity index 100%
rename from src/pkg/testing/iotest/logger.go
rename to src/testing/iotest/logger.go
diff --git a/src/pkg/testing/iotest/reader.go b/src/testing/iotest/reader.go
similarity index 100%
rename from src/pkg/testing/iotest/reader.go
rename to src/testing/iotest/reader.go
diff --git a/src/pkg/testing/iotest/writer.go b/src/testing/iotest/writer.go
similarity index 100%
rename from src/pkg/testing/iotest/writer.go
rename to src/testing/iotest/writer.go
diff --git a/src/testing/quick/quick.go b/src/testing/quick/quick.go
new file mode 100644
index 0000000..909c65f
--- /dev/null
+++ b/src/testing/quick/quick.go
@@ -0,0 +1,358 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package quick implements utility functions to help with black box testing.
+package quick
+
+import (
+	"flag"
+	"fmt"
+	"math"
+	"math/rand"
+	"reflect"
+	"strings"
+)
+
+var defaultMaxCount *int = flag.Int("quickchecks", 100, "The default number of iterations for each check")
+
+// A Generator can generate random values of its own type.
+type Generator interface {
+	// Generate returns a random instance of the type on which it is a
+	// method using the size as a size hint.
+	Generate(rand *rand.Rand, size int) reflect.Value
+}
+
+// randFloat32 generates a random float taking the full range of a float32.
+func randFloat32(rand *rand.Rand) float32 {
+	f := rand.Float64() * math.MaxFloat32
+	if rand.Int()&1 == 1 {
+		f = -f
+	}
+	return float32(f)
+}
+
+// randFloat64 generates a random float taking the full range of a float64.
+func randFloat64(rand *rand.Rand) float64 {
+	f := rand.Float64() * math.MaxFloat64
+	if rand.Int()&1 == 1 {
+		f = -f
+	}
+	return f
+}
+
+// randInt64 returns a random integer taking half the range of an int64.
+func randInt64(rand *rand.Rand) int64 { return rand.Int63() - 1<<62 }
+
+// complexSize is the maximum length of arbitrary values that contain other
+// values.
+const complexSize = 50
+
+// Value returns an arbitrary value of the given type.
+// If the type implements the Generator interface, that will be used.
+// Note: To create arbitrary values for structs, all the fields must be exported.
+func Value(t reflect.Type, rand *rand.Rand) (value reflect.Value, ok bool) {
+	if m, ok := reflect.Zero(t).Interface().(Generator); ok {
+		return m.Generate(rand, complexSize), true
+	}
+
+	v := reflect.New(t).Elem()
+	switch concrete := t; concrete.Kind() {
+	case reflect.Bool:
+		v.SetBool(rand.Int()&1 == 0)
+	case reflect.Float32:
+		v.SetFloat(float64(randFloat32(rand)))
+	case reflect.Float64:
+		v.SetFloat(randFloat64(rand))
+	case reflect.Complex64:
+		v.SetComplex(complex(float64(randFloat32(rand)), float64(randFloat32(rand))))
+	case reflect.Complex128:
+		v.SetComplex(complex(randFloat64(rand), randFloat64(rand)))
+	case reflect.Int16:
+		v.SetInt(randInt64(rand))
+	case reflect.Int32:
+		v.SetInt(randInt64(rand))
+	case reflect.Int64:
+		v.SetInt(randInt64(rand))
+	case reflect.Int8:
+		v.SetInt(randInt64(rand))
+	case reflect.Int:
+		v.SetInt(randInt64(rand))
+	case reflect.Uint16:
+		v.SetUint(uint64(randInt64(rand)))
+	case reflect.Uint32:
+		v.SetUint(uint64(randInt64(rand)))
+	case reflect.Uint64:
+		v.SetUint(uint64(randInt64(rand)))
+	case reflect.Uint8:
+		v.SetUint(uint64(randInt64(rand)))
+	case reflect.Uint:
+		v.SetUint(uint64(randInt64(rand)))
+	case reflect.Uintptr:
+		v.SetUint(uint64(randInt64(rand)))
+	case reflect.Map:
+		numElems := rand.Intn(complexSize)
+		v.Set(reflect.MakeMap(concrete))
+		for i := 0; i < numElems; i++ {
+			key, ok1 := Value(concrete.Key(), rand)
+			value, ok2 := Value(concrete.Elem(), rand)
+			if !ok1 || !ok2 {
+				return reflect.Value{}, false
+			}
+			v.SetMapIndex(key, value)
+		}
+	case reflect.Ptr:
+		elem, ok := Value(concrete.Elem(), rand)
+		if !ok {
+			return reflect.Value{}, false
+		}
+		v.Set(reflect.New(concrete.Elem()))
+		v.Elem().Set(elem)
+	case reflect.Slice:
+		numElems := rand.Intn(complexSize)
+		v.Set(reflect.MakeSlice(concrete, numElems, numElems))
+		for i := 0; i < numElems; i++ {
+			elem, ok := Value(concrete.Elem(), rand)
+			if !ok {
+				return reflect.Value{}, false
+			}
+			v.Index(i).Set(elem)
+		}
+	case reflect.String:
+		numChars := rand.Intn(complexSize)
+		codePoints := make([]rune, numChars)
+		for i := 0; i < numChars; i++ {
+			codePoints[i] = rune(rand.Intn(0x10ffff))
+		}
+		v.SetString(string(codePoints))
+	case reflect.Struct:
+		for i := 0; i < v.NumField(); i++ {
+			elem, ok := Value(concrete.Field(i).Type, rand)
+			if !ok {
+				return reflect.Value{}, false
+			}
+			v.Field(i).Set(elem)
+		}
+	default:
+		return reflect.Value{}, false
+	}
+
+	return v, true
+}
+
+// A Config structure contains options for running a test.
+type Config struct {
+	// MaxCount sets the maximum number of iterations. If zero,
+	// MaxCountScale is used.
+	MaxCount int
+	// MaxCountScale is a non-negative scale factor applied to the default
+	// maximum. If zero, the default is unchanged.
+	MaxCountScale float64
+	// If non-nil, rand is a source of random numbers. Otherwise a default
+	// pseudo-random source will be used.
+	Rand *rand.Rand
+	// If non-nil, the Values function generates a slice of arbitrary
+	// reflect.Values that are congruent with the arguments to the function
+	// being tested. Otherwise, the top-level Values function is used
+	// to generate them.
+	Values func([]reflect.Value, *rand.Rand)
+}
+
+var defaultConfig Config
+
+// getRand returns the *rand.Rand to use for a given Config.
+func (c *Config) getRand() *rand.Rand {
+	if c.Rand == nil {
+		return rand.New(rand.NewSource(0))
+	}
+	return c.Rand
+}
+
+// getMaxCount returns the maximum number of iterations to run for a given
+// Config.
+func (c *Config) getMaxCount() (maxCount int) {
+	maxCount = c.MaxCount
+	if maxCount == 0 {
+		if c.MaxCountScale != 0 {
+			maxCount = int(c.MaxCountScale * float64(*defaultMaxCount))
+		} else {
+			maxCount = *defaultMaxCount
+		}
+	}
+
+	return
+}
+
+// A SetupError is the result of an error in the way that check is being
+// used, independent of the functions being tested.
+type SetupError string
+
+func (s SetupError) Error() string { return string(s) }
+
+// A CheckError is the result of Check finding an error.
+type CheckError struct {
+	Count int
+	In    []interface{}
+}
+
+func (s *CheckError) Error() string {
+	return fmt.Sprintf("#%d: failed on input %s", s.Count, toString(s.In))
+}
+
+// A CheckEqualError is the result CheckEqual finding an error.
+type CheckEqualError struct {
+	CheckError
+	Out1 []interface{}
+	Out2 []interface{}
+}
+
+func (s *CheckEqualError) Error() string {
+	return fmt.Sprintf("#%d: failed on input %s. Output 1: %s. Output 2: %s", s.Count, toString(s.In), toString(s.Out1), toString(s.Out2))
+}
+
+// Check looks for an input to f, any function that returns bool,
+// such that f returns false.  It calls f repeatedly, with arbitrary
+// values for each argument.  If f returns false on a given input,
+// Check returns that input as a *CheckError.
+// For example:
+//
+// 	func TestOddMultipleOfThree(t *testing.T) {
+// 		f := func(x int) bool {
+// 			y := OddMultipleOfThree(x)
+// 			return y%2 == 1 && y%3 == 0
+// 		}
+// 		if err := quick.Check(f, nil); err != nil {
+// 			t.Error(err)
+// 		}
+// 	}
+func Check(f interface{}, config *Config) (err error) {
+	if config == nil {
+		config = &defaultConfig
+	}
+
+	fVal, fType, ok := functionAndType(f)
+	if !ok {
+		err = SetupError("argument is not a function")
+		return
+	}
+
+	if fType.NumOut() != 1 {
+		err = SetupError("function returns more than one value.")
+		return
+	}
+	if fType.Out(0).Kind() != reflect.Bool {
+		err = SetupError("function does not return a bool")
+		return
+	}
+
+	arguments := make([]reflect.Value, fType.NumIn())
+	rand := config.getRand()
+	maxCount := config.getMaxCount()
+
+	for i := 0; i < maxCount; i++ {
+		err = arbitraryValues(arguments, fType, config, rand)
+		if err != nil {
+			return
+		}
+
+		if !fVal.Call(arguments)[0].Bool() {
+			err = &CheckError{i + 1, toInterfaces(arguments)}
+			return
+		}
+	}
+
+	return
+}
+
+// CheckEqual looks for an input on which f and g return different results.
+// It calls f and g repeatedly with arbitrary values for each argument.
+// If f and g return different answers, CheckEqual returns a *CheckEqualError
+// describing the input and the outputs.
+func CheckEqual(f, g interface{}, config *Config) (err error) {
+	if config == nil {
+		config = &defaultConfig
+	}
+
+	x, xType, ok := functionAndType(f)
+	if !ok {
+		err = SetupError("f is not a function")
+		return
+	}
+	y, yType, ok := functionAndType(g)
+	if !ok {
+		err = SetupError("g is not a function")
+		return
+	}
+
+	if xType != yType {
+		err = SetupError("functions have different types")
+		return
+	}
+
+	arguments := make([]reflect.Value, xType.NumIn())
+	rand := config.getRand()
+	maxCount := config.getMaxCount()
+
+	for i := 0; i < maxCount; i++ {
+		err = arbitraryValues(arguments, xType, config, rand)
+		if err != nil {
+			return
+		}
+
+		xOut := toInterfaces(x.Call(arguments))
+		yOut := toInterfaces(y.Call(arguments))
+
+		if !reflect.DeepEqual(xOut, yOut) {
+			err = &CheckEqualError{CheckError{i + 1, toInterfaces(arguments)}, xOut, yOut}
+			return
+		}
+	}
+
+	return
+}
+
+// arbitraryValues writes Values to args such that args contains Values
+// suitable for calling f.
+func arbitraryValues(args []reflect.Value, f reflect.Type, config *Config, rand *rand.Rand) (err error) {
+	if config.Values != nil {
+		config.Values(args, rand)
+		return
+	}
+
+	for j := 0; j < len(args); j++ {
+		var ok bool
+		args[j], ok = Value(f.In(j), rand)
+		if !ok {
+			err = SetupError(fmt.Sprintf("cannot create arbitrary value of type %s for argument %d", f.In(j), j))
+			return
+		}
+	}
+
+	return
+}
+
+func functionAndType(f interface{}) (v reflect.Value, t reflect.Type, ok bool) {
+	v = reflect.ValueOf(f)
+	ok = v.Kind() == reflect.Func
+	if !ok {
+		return
+	}
+	t = v.Type()
+	return
+}
+
+func toInterfaces(values []reflect.Value) []interface{} {
+	ret := make([]interface{}, len(values))
+	for i, v := range values {
+		ret[i] = v.Interface()
+	}
+	return ret
+}
+
+func toString(interfaces []interface{}) string {
+	s := make([]string, len(interfaces))
+	for i, v := range interfaces {
+		s[i] = fmt.Sprintf("%#v", v)
+	}
+	return strings.Join(s, ", ")
+}
diff --git a/src/pkg/testing/quick/quick_test.go b/src/testing/quick/quick_test.go
similarity index 100%
rename from src/pkg/testing/quick/quick_test.go
rename to src/testing/quick/quick_test.go
diff --git a/src/testing/testing.go b/src/testing/testing.go
new file mode 100644
index 0000000..e54a3b8
--- /dev/null
+++ b/src/testing/testing.go
@@ -0,0 +1,709 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package testing provides support for automated testing of Go packages.
+// It is intended to be used in concert with the ``go test'' command, which automates
+// execution of any function of the form
+//     func TestXxx(*testing.T)
+// where Xxx can be any alphanumeric string (but the first letter must not be in
+// [a-z]) and serves to identify the test routine.
+//
+// Within these functions, use the Error, Fail or related methods to signal failure.
+//
+// To write a new test suite, create a file whose name ends _test.go that
+// contains the TestXxx functions as described here. Put the file in the same
+// package as the one being tested. The file will be excluded from regular
+// package builds but will be included when the ``go test'' command is run.
+// For more detail, run ``go help test'' and ``go help testflag''.
+//
+// Tests and benchmarks may be skipped if not applicable with a call to
+// the Skip method of *T and *B:
+//     func TestTimeConsuming(t *testing.T) {
+//         if testing.Short() {
+//             t.Skip("skipping test in short mode.")
+//         }
+//         ...
+//     }
+//
+// Benchmarks
+//
+// Functions of the form
+//     func BenchmarkXxx(*testing.B)
+// are considered benchmarks, and are executed by the "go test" command when
+// its -bench flag is provided. Benchmarks are run sequentially.
+//
+// For a description of the testing flags, see
+// http://golang.org/cmd/go/#hdr-Description_of_testing_flags.
+//
+// A sample benchmark function looks like this:
+//     func BenchmarkHello(b *testing.B) {
+//         for i := 0; i < b.N; i++ {
+//             fmt.Sprintf("hello")
+//         }
+//     }
+//
+// The benchmark function must run the target code b.N times.
+// During benchark execution, b.N is adjusted until the benchmark function lasts
+// long enough to be timed reliably.  The output
+//     BenchmarkHello    10000000    282 ns/op
+// means that the loop ran 10000000 times at a speed of 282 ns per loop.
+//
+// If a benchmark needs some expensive setup before running, the timer
+// may be reset:
+//
+//     func BenchmarkBigLen(b *testing.B) {
+//         big := NewBig()
+//         b.ResetTimer()
+//         for i := 0; i < b.N; i++ {
+//             big.Len()
+//         }
+//     }
+//
+// If a benchmark needs to test performance in a parallel setting, it may use
+// the RunParallel helper function; such benchmarks are intended to be used with
+// the go test -cpu flag:
+//
+//     func BenchmarkTemplateParallel(b *testing.B) {
+//         templ := template.Must(template.New("test").Parse("Hello, {{.}}!"))
+//         b.RunParallel(func(pb *testing.PB) {
+//             var buf bytes.Buffer
+//             for pb.Next() {
+//                 buf.Reset()
+//                 templ.Execute(&buf, "World")
+//             }
+//         })
+//     }
+//
+// Examples
+//
+// The package also runs and verifies example code. Example functions may
+// include a concluding line comment that begins with "Output:" and is compared with
+// the standard output of the function when the tests are run. (The comparison
+// ignores leading and trailing space.) These are examples of an example:
+//
+//     func ExampleHello() {
+//             fmt.Println("hello")
+//             // Output: hello
+//     }
+//
+//     func ExampleSalutations() {
+//             fmt.Println("hello, and")
+//             fmt.Println("goodbye")
+//             // Output:
+//             // hello, and
+//             // goodbye
+//     }
+//
+// Example functions without output comments are compiled but not executed.
+//
+// The naming convention to declare examples for the package, a function F, a type T and
+// method M on type T are:
+//
+//     func Example() { ... }
+//     func ExampleF() { ... }
+//     func ExampleT() { ... }
+//     func ExampleT_M() { ... }
+//
+// Multiple example functions for a package/type/function/method may be provided by
+// appending a distinct suffix to the name. The suffix must start with a
+// lower-case letter.
+//
+//     func Example_suffix() { ... }
+//     func ExampleF_suffix() { ... }
+//     func ExampleT_suffix() { ... }
+//     func ExampleT_M_suffix() { ... }
+//
+// The entire test file is presented as the example when it contains a single
+// example function, at least one other function, type, variable, or constant
+// declaration, and no test or benchmark functions.
+//
+// Main
+//
+// It is sometimes necessary for a test program to do extra setup or teardown
+// before or after testing. It is also sometimes necessary for a test to control
+// which code runs on the main thread. To support these and other cases,
+// if a test file contains a function:
+//
+//	func TestMain(m *testing.M)
+//
+// then the generated test will call TestMain(m) instead of running the tests
+// directly. TestMain runs in the main goroutine and can do whatever setup
+// and teardown is necessary around a call to m.Run. It should then call
+// os.Exit with the result of m.Run.
+//
+// The minimal implementation of TestMain is:
+//
+//	func TestMain(m *testing.M) { os.Exit(m.Run()) }
+//
+// In effect, that is the implementation used when no TestMain is explicitly defined.
+package testing
+
+import (
+	"bytes"
+	"flag"
+	"fmt"
+	"os"
+	"runtime"
+	"runtime/pprof"
+	"strconv"
+	"strings"
+	"sync"
+	"time"
+)
+
+var (
+	// The short flag requests that tests run more quickly, but its functionality
+	// is provided by test writers themselves.  The testing package is just its
+	// home.  The all.bash installation script sets it to make installation more
+	// efficient, but by default the flag is off so a plain "go test" will do a
+	// full test of the package.
+	short = flag.Bool("test.short", false, "run smaller test suite to save time")
+
+	// The directory in which to create profile files and the like. When run from
+	// "go test", the binary always runs in the source directory for the package;
+	// this flag lets "go test" tell the binary to write the files in the directory where
+	// the "go test" command is run.
+	outputDir = flag.String("test.outputdir", "", "directory in which to write profiles")
+
+	// Report as tests are run; default is silent for success.
+	chatty           = flag.Bool("test.v", false, "verbose: print additional output")
+	coverProfile     = flag.String("test.coverprofile", "", "write a coverage profile to the named file after execution")
+	match            = flag.String("test.run", "", "regular expression to select tests and examples to run")
+	memProfile       = flag.String("test.memprofile", "", "write a memory profile to the named file after execution")
+	memProfileRate   = flag.Int("test.memprofilerate", 0, "if >=0, sets runtime.MemProfileRate")
+	cpuProfile       = flag.String("test.cpuprofile", "", "write a cpu profile to the named file during execution")
+	blockProfile     = flag.String("test.blockprofile", "", "write a goroutine blocking profile to the named file after execution")
+	blockProfileRate = flag.Int("test.blockprofilerate", 1, "if >= 0, calls runtime.SetBlockProfileRate()")
+	timeout          = flag.Duration("test.timeout", 0, "if positive, sets an aggregate time limit for all tests")
+	cpuListStr       = flag.String("test.cpu", "", "comma-separated list of number of CPUs to use for each test")
+	parallel         = flag.Int("test.parallel", runtime.GOMAXPROCS(0), "maximum test parallelism")
+
+	haveExamples bool // are there examples?
+
+	cpuList []int
+)
+
+// common holds the elements common between T and B and
+// captures common methods such as Errorf.
+type common struct {
+	mu       sync.RWMutex // guards output and failed
+	output   []byte       // Output generated by test or benchmark.
+	failed   bool         // Test or benchmark has failed.
+	skipped  bool         // Test of benchmark has been skipped.
+	finished bool
+
+	start    time.Time // Time test or benchmark started
+	duration time.Duration
+	self     interface{}      // To be sent on signal channel when done.
+	signal   chan interface{} // Output for serial tests.
+}
+
+// Short reports whether the -test.short flag is set.
+func Short() bool {
+	return *short
+}
+
+// Verbose reports whether the -test.v flag is set.
+func Verbose() bool {
+	return *chatty
+}
+
+// decorate prefixes the string with the file and line of the call site
+// and inserts the final newline if needed and indentation tabs for formatting.
+func decorate(s string) string {
+	_, file, line, ok := runtime.Caller(3) // decorate + log + public function.
+	if ok {
+		// Truncate file name at last file name separator.
+		if index := strings.LastIndex(file, "/"); index >= 0 {
+			file = file[index+1:]
+		} else if index = strings.LastIndex(file, "\\"); index >= 0 {
+			file = file[index+1:]
+		}
+	} else {
+		file = "???"
+		line = 1
+	}
+	buf := new(bytes.Buffer)
+	// Every line is indented at least one tab.
+	buf.WriteByte('\t')
+	fmt.Fprintf(buf, "%s:%d: ", file, line)
+	lines := strings.Split(s, "\n")
+	if l := len(lines); l > 1 && lines[l-1] == "" {
+		lines = lines[:l-1]
+	}
+	for i, line := range lines {
+		if i > 0 {
+			// Second and subsequent lines are indented an extra tab.
+			buf.WriteString("\n\t\t")
+		}
+		buf.WriteString(line)
+	}
+	buf.WriteByte('\n')
+	return buf.String()
+}
+
+// fmtDuration returns a string representing d in the form "87.00s".
+func fmtDuration(d time.Duration) string {
+	return fmt.Sprintf("%.2fs", d.Seconds())
+}
+
+// TB is the interface common to T and B.
+type TB interface {
+	Error(args ...interface{})
+	Errorf(format string, args ...interface{})
+	Fail()
+	FailNow()
+	Failed() bool
+	Fatal(args ...interface{})
+	Fatalf(format string, args ...interface{})
+	Log(args ...interface{})
+	Logf(format string, args ...interface{})
+	Skip(args ...interface{})
+	SkipNow()
+	Skipf(format string, args ...interface{})
+	Skipped() bool
+
+	// A private method to prevent users implementing the
+	// interface and so future additions to it will not
+	// violate Go 1 compatibility.
+	private()
+}
+
+var _ TB = (*T)(nil)
+var _ TB = (*B)(nil)
+
+// T is a type passed to Test functions to manage test state and support formatted test logs.
+// Logs are accumulated during execution and dumped to standard error when done.
+type T struct {
+	common
+	name          string    // Name of test.
+	startParallel chan bool // Parallel tests will wait on this.
+}
+
+func (c *common) private() {}
+
+// Fail marks the function as having failed but continues execution.
+func (c *common) Fail() {
+	c.mu.Lock()
+	defer c.mu.Unlock()
+	c.failed = true
+}
+
+// Failed reports whether the function has failed.
+func (c *common) Failed() bool {
+	c.mu.RLock()
+	defer c.mu.RUnlock()
+	return c.failed
+}
+
+// FailNow marks the function as having failed and stops its execution.
+// Execution will continue at the next test or benchmark.
+// FailNow must be called from the goroutine running the
+// test or benchmark function, not from other goroutines
+// created during the test. Calling FailNow does not stop
+// those other goroutines.
+func (c *common) FailNow() {
+	c.Fail()
+
+	// Calling runtime.Goexit will exit the goroutine, which
+	// will run the deferred functions in this goroutine,
+	// which will eventually run the deferred lines in tRunner,
+	// which will signal to the test loop that this test is done.
+	//
+	// A previous version of this code said:
+	//
+	//	c.duration = ...
+	//	c.signal <- c.self
+	//	runtime.Goexit()
+	//
+	// This previous version duplicated code (those lines are in
+	// tRunner no matter what), but worse the goroutine teardown
+	// implicit in runtime.Goexit was not guaranteed to complete
+	// before the test exited.  If a test deferred an important cleanup
+	// function (like removing temporary files), there was no guarantee
+	// it would run on a test failure.  Because we send on c.signal during
+	// a top-of-stack deferred function now, we know that the send
+	// only happens after any other stacked defers have completed.
+	c.finished = true
+	runtime.Goexit()
+}
+
+// log generates the output. It's always at the same stack depth.
+func (c *common) log(s string) {
+	c.mu.Lock()
+	defer c.mu.Unlock()
+	c.output = append(c.output, decorate(s)...)
+}
+
+// Log formats its arguments using default formatting, analogous to Println,
+// and records the text in the error log. The text will be printed only if
+// the test fails or the -test.v flag is set.
+func (c *common) Log(args ...interface{}) { c.log(fmt.Sprintln(args...)) }
+
+// Logf formats its arguments according to the format, analogous to Printf,
+// and records the text in the error log. The text will be printed only if
+// the test fails or the -test.v flag is set.
+func (c *common) Logf(format string, args ...interface{}) { c.log(fmt.Sprintf(format, args...)) }
+
+// Error is equivalent to Log followed by Fail.
+func (c *common) Error(args ...interface{}) {
+	c.log(fmt.Sprintln(args...))
+	c.Fail()
+}
+
+// Errorf is equivalent to Logf followed by Fail.
+func (c *common) Errorf(format string, args ...interface{}) {
+	c.log(fmt.Sprintf(format, args...))
+	c.Fail()
+}
+
+// Fatal is equivalent to Log followed by FailNow.
+func (c *common) Fatal(args ...interface{}) {
+	c.log(fmt.Sprintln(args...))
+	c.FailNow()
+}
+
+// Fatalf is equivalent to Logf followed by FailNow.
+func (c *common) Fatalf(format string, args ...interface{}) {
+	c.log(fmt.Sprintf(format, args...))
+	c.FailNow()
+}
+
+// Skip is equivalent to Log followed by SkipNow.
+func (c *common) Skip(args ...interface{}) {
+	c.log(fmt.Sprintln(args...))
+	c.SkipNow()
+}
+
+// Skipf is equivalent to Logf followed by SkipNow.
+func (c *common) Skipf(format string, args ...interface{}) {
+	c.log(fmt.Sprintf(format, args...))
+	c.SkipNow()
+}
+
+// SkipNow marks the test as having been skipped and stops its execution.
+// Execution will continue at the next test or benchmark. See also FailNow.
+// SkipNow must be called from the goroutine running the test, not from
+// other goroutines created during the test. Calling SkipNow does not stop
+// those other goroutines.
+func (c *common) SkipNow() {
+	c.skip()
+	c.finished = true
+	runtime.Goexit()
+}
+
+func (c *common) skip() {
+	c.mu.Lock()
+	defer c.mu.Unlock()
+	c.skipped = true
+}
+
+// Skipped reports whether the test was skipped.
+func (c *common) Skipped() bool {
+	c.mu.RLock()
+	defer c.mu.RUnlock()
+	return c.skipped
+}
+
+// Parallel signals that this test is to be run in parallel with (and only with)
+// other parallel tests.
+func (t *T) Parallel() {
+	t.signal <- (*T)(nil) // Release main testing loop
+	<-t.startParallel     // Wait for serial tests to finish
+	// Assuming Parallel is the first thing a test does, which is reasonable,
+	// reinitialize the test's start time because it's actually starting now.
+	t.start = time.Now()
+}
+
+// An internal type but exported because it is cross-package; part of the implementation
+// of the "go test" command.
+type InternalTest struct {
+	Name string
+	F    func(*T)
+}
+
+func tRunner(t *T, test *InternalTest) {
+	// When this goroutine is done, either because test.F(t)
+	// returned normally or because a test failure triggered
+	// a call to runtime.Goexit, record the duration and send
+	// a signal saying that the test is done.
+	defer func() {
+		t.duration = time.Now().Sub(t.start)
+		// If the test panicked, print any test output before dying.
+		err := recover()
+		if !t.finished && err == nil {
+			err = fmt.Errorf("test executed panic(nil) or runtime.Goexit")
+		}
+		if err != nil {
+			t.Fail()
+			t.report()
+			panic(err)
+		}
+		t.signal <- t
+	}()
+
+	t.start = time.Now()
+	test.F(t)
+	t.finished = true
+}
+
+// An internal function but exported because it is cross-package; part of the implementation
+// of the "go test" command.
+func Main(matchString func(pat, str string) (bool, error), tests []InternalTest, benchmarks []InternalBenchmark, examples []InternalExample) {
+	os.Exit(MainStart(matchString, tests, benchmarks, examples).Run())
+}
+
+// M is a type passed to a TestMain function to run the actual tests.
+type M struct {
+	matchString func(pat, str string) (bool, error)
+	tests       []InternalTest
+	benchmarks  []InternalBenchmark
+	examples    []InternalExample
+}
+
+// MainStart is meant for use by tests generated by 'go test'.
+// It is not meant to be called directly and is not subject to the Go 1 compatibility document.
+// It may change signature from release to release.
+func MainStart(matchString func(pat, str string) (bool, error), tests []InternalTest, benchmarks []InternalBenchmark, examples []InternalExample) *M {
+	return &M{
+		matchString: matchString,
+		tests:       tests,
+		benchmarks:  benchmarks,
+		examples:    examples,
+	}
+}
+
+// Run runs the tests. It returns an exit code to pass to os.Exit.
+func (m *M) Run() int {
+	flag.Parse()
+	parseCpuList()
+
+	before()
+	startAlarm()
+	haveExamples = len(m.examples) > 0
+	testOk := RunTests(m.matchString, m.tests)
+	exampleOk := RunExamples(m.matchString, m.examples)
+	stopAlarm()
+	if !testOk || !exampleOk {
+		fmt.Println("FAIL")
+		after()
+		return 1
+	}
+	fmt.Println("PASS")
+	RunBenchmarks(m.matchString, m.benchmarks)
+	after()
+	return 0
+}
+
+func (t *T) report() {
+	dstr := fmtDuration(t.duration)
+	format := "--- %s: %s (%s)\n%s"
+	if t.Failed() {
+		fmt.Printf(format, "FAIL", t.name, dstr, t.output)
+	} else if *chatty {
+		if t.Skipped() {
+			fmt.Printf(format, "SKIP", t.name, dstr, t.output)
+		} else {
+			fmt.Printf(format, "PASS", t.name, dstr, t.output)
+		}
+	}
+}
+
+func RunTests(matchString func(pat, str string) (bool, error), tests []InternalTest) (ok bool) {
+	ok = true
+	if len(tests) == 0 && !haveExamples {
+		fmt.Fprintln(os.Stderr, "testing: warning: no tests to run")
+		return
+	}
+	for _, procs := range cpuList {
+		runtime.GOMAXPROCS(procs)
+		// We build a new channel tree for each run of the loop.
+		// collector merges in one channel all the upstream signals from parallel tests.
+		// If all tests pump to the same channel, a bug can occur where a test
+		// kicks off a goroutine that Fails, yet the test still delivers a completion signal,
+		// which skews the counting.
+		var collector = make(chan interface{})
+
+		numParallel := 0
+		startParallel := make(chan bool)
+
+		for i := 0; i < len(tests); i++ {
+			matched, err := matchString(*match, tests[i].Name)
+			if err != nil {
+				fmt.Fprintf(os.Stderr, "testing: invalid regexp for -test.run: %s\n", err)
+				os.Exit(1)
+			}
+			if !matched {
+				continue
+			}
+			testName := tests[i].Name
+			if procs != 1 {
+				testName = fmt.Sprintf("%s-%d", tests[i].Name, procs)
+			}
+			t := &T{
+				common: common{
+					signal: make(chan interface{}),
+				},
+				name:          testName,
+				startParallel: startParallel,
+			}
+			t.self = t
+			if *chatty {
+				fmt.Printf("=== RUN %s\n", t.name)
+			}
+			go tRunner(t, &tests[i])
+			out := (<-t.signal).(*T)
+			if out == nil { // Parallel run.
+				go func() {
+					collector <- <-t.signal
+				}()
+				numParallel++
+				continue
+			}
+			t.report()
+			ok = ok && !out.Failed()
+		}
+
+		running := 0
+		for numParallel+running > 0 {
+			if running < *parallel && numParallel > 0 {
+				startParallel <- true
+				running++
+				numParallel--
+				continue
+			}
+			t := (<-collector).(*T)
+			t.report()
+			ok = ok && !t.Failed()
+			running--
+		}
+	}
+	return
+}
+
+// before runs before all testing.
+func before() {
+	if *memProfileRate > 0 {
+		runtime.MemProfileRate = *memProfileRate
+	}
+	if *cpuProfile != "" {
+		f, err := os.Create(toOutputDir(*cpuProfile))
+		if err != nil {
+			fmt.Fprintf(os.Stderr, "testing: %s", err)
+			return
+		}
+		if err := pprof.StartCPUProfile(f); err != nil {
+			fmt.Fprintf(os.Stderr, "testing: can't start cpu profile: %s", err)
+			f.Close()
+			return
+		}
+		// Could save f so after can call f.Close; not worth the effort.
+	}
+	if *blockProfile != "" && *blockProfileRate >= 0 {
+		runtime.SetBlockProfileRate(*blockProfileRate)
+	}
+	if *coverProfile != "" && cover.Mode == "" {
+		fmt.Fprintf(os.Stderr, "testing: cannot use -test.coverprofile because test binary was not built with coverage enabled\n")
+		os.Exit(2)
+	}
+}
+
+// after runs after all testing.
+func after() {
+	if *cpuProfile != "" {
+		pprof.StopCPUProfile() // flushes profile to disk
+	}
+	if *memProfile != "" {
+		f, err := os.Create(toOutputDir(*memProfile))
+		if err != nil {
+			fmt.Fprintf(os.Stderr, "testing: %s\n", err)
+			os.Exit(2)
+		}
+		runtime.GC() // materialize all statistics
+		if err = pprof.WriteHeapProfile(f); err != nil {
+			fmt.Fprintf(os.Stderr, "testing: can't write %s: %s\n", *memProfile, err)
+			os.Exit(2)
+		}
+		f.Close()
+	}
+	if *blockProfile != "" && *blockProfileRate >= 0 {
+		f, err := os.Create(toOutputDir(*blockProfile))
+		if err != nil {
+			fmt.Fprintf(os.Stderr, "testing: %s\n", err)
+			os.Exit(2)
+		}
+		if err = pprof.Lookup("block").WriteTo(f, 0); err != nil {
+			fmt.Fprintf(os.Stderr, "testing: can't write %s: %s\n", *blockProfile, err)
+			os.Exit(2)
+		}
+		f.Close()
+	}
+	if cover.Mode != "" {
+		coverReport()
+	}
+}
+
+// toOutputDir returns the file name relocated, if required, to outputDir.
+// Simple implementation to avoid pulling in path/filepath.
+func toOutputDir(path string) string {
+	if *outputDir == "" || path == "" {
+		return path
+	}
+	if runtime.GOOS == "windows" {
+		// On Windows, it's clumsy, but we can be almost always correct
+		// by just looking for a drive letter and a colon.
+		// Absolute paths always have a drive letter (ignoring UNC).
+		// Problem: if path == "C:A" and outputdir == "C:\Go" it's unclear
+		// what to do, but even then path/filepath doesn't help.
+		// TODO: Worth doing better? Probably not, because we're here only
+		// under the management of go test.
+		if len(path) >= 2 {
+			letter, colon := path[0], path[1]
+			if ('a' <= letter && letter <= 'z' || 'A' <= letter && letter <= 'Z') && colon == ':' {
+				// If path starts with a drive letter we're stuck with it regardless.
+				return path
+			}
+		}
+	}
+	if os.IsPathSeparator(path[0]) {
+		return path
+	}
+	return fmt.Sprintf("%s%c%s", *outputDir, os.PathSeparator, path)
+}
+
+var timer *time.Timer
+
+// startAlarm starts an alarm if requested.
+func startAlarm() {
+	if *timeout > 0 {
+		timer = time.AfterFunc(*timeout, func() {
+			panic(fmt.Sprintf("test timed out after %v", *timeout))
+		})
+	}
+}
+
+// stopAlarm turns off the alarm.
+func stopAlarm() {
+	if *timeout > 0 {
+		timer.Stop()
+	}
+}
+
+func parseCpuList() {
+	for _, val := range strings.Split(*cpuListStr, ",") {
+		val = strings.TrimSpace(val)
+		if val == "" {
+			continue
+		}
+		cpu, err := strconv.Atoi(val)
+		if err != nil || cpu <= 0 {
+			fmt.Fprintf(os.Stderr, "testing: invalid value %q for -test.cpu\n", val)
+			os.Exit(1)
+		}
+		cpuList = append(cpuList, cpu)
+	}
+	if cpuList == nil {
+		cpuList = append(cpuList, runtime.GOMAXPROCS(-1))
+	}
+}
diff --git a/src/testing/testing_test.go b/src/testing/testing_test.go
new file mode 100644
index 0000000..87a5c16
--- /dev/null
+++ b/src/testing/testing_test.go
@@ -0,0 +1,18 @@
+// 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 testing_test
+
+import (
+	"os"
+	"testing"
+)
+
+// This is exactly what a test would do without a TestMain.
+// It's here only so that there is at least one package in the
+// standard library with a TestMain, so that code is executed.
+
+func TestMain(m *testing.M) {
+	os.Exit(m.Run())
+}
diff --git a/src/text/scanner/scanner.go b/src/text/scanner/scanner.go
new file mode 100644
index 0000000..5199ee4
--- /dev/null
+++ b/src/text/scanner/scanner.go
@@ -0,0 +1,693 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package scanner provides a scanner and tokenizer for UTF-8-encoded text.
+// It takes an io.Reader providing the source, which then can be tokenized
+// through repeated calls to the Scan function.  For compatibility with
+// existing tools, the NUL character is not allowed. If the first character
+// in the source is a UTF-8 encoded byte order mark (BOM), it is discarded.
+//
+// By default, a Scanner skips white space and Go comments and recognizes all
+// literals as defined by the Go language specification.  It may be
+// customized to recognize only a subset of those literals and to recognize
+// different identifier and white space characters.
+//
+// Basic usage pattern:
+//
+//	var s scanner.Scanner
+//	s.Init(src)
+//	tok := s.Scan()
+//	for tok != scanner.EOF {
+//		// do something with tok
+//		tok = s.Scan()
+//	}
+//
+package scanner
+
+import (
+	"bytes"
+	"fmt"
+	"io"
+	"os"
+	"unicode"
+	"unicode/utf8"
+)
+
+// A source position is represented by a Position value.
+// A position is valid if Line > 0.
+type Position struct {
+	Filename string // filename, if any
+	Offset   int    // byte offset, starting at 0
+	Line     int    // line number, starting at 1
+	Column   int    // column number, starting at 1 (character count per line)
+}
+
+// IsValid returns true if the position is valid.
+func (pos *Position) IsValid() bool { return pos.Line > 0 }
+
+func (pos Position) String() string {
+	s := pos.Filename
+	if pos.IsValid() {
+		if s != "" {
+			s += ":"
+		}
+		s += fmt.Sprintf("%d:%d", pos.Line, pos.Column)
+	}
+	if s == "" {
+		s = "???"
+	}
+	return s
+}
+
+// Predefined mode bits to control recognition of tokens. For instance,
+// to configure a Scanner such that it only recognizes (Go) identifiers,
+// integers, and skips comments, set the Scanner's Mode field to:
+//
+//	ScanIdents | ScanInts | SkipComments
+//
+// With the exceptions of comments, which are skipped if SkipComments is
+// set, unrecognized tokens are not ignored. Instead, the scanner simply
+// returns the respective individual characters (or possibly sub-tokens).
+// For instance, if the mode is ScanIdents (not ScanStrings), the string
+// "foo" is scanned as the token sequence '"' Ident '"'.
+//
+const (
+	ScanIdents     = 1 << -Ident
+	ScanInts       = 1 << -Int
+	ScanFloats     = 1 << -Float // includes Ints
+	ScanChars      = 1 << -Char
+	ScanStrings    = 1 << -String
+	ScanRawStrings = 1 << -RawString
+	ScanComments   = 1 << -Comment
+	SkipComments   = 1 << -skipComment // if set with ScanComments, comments become white space
+	GoTokens       = ScanIdents | ScanFloats | ScanChars | ScanStrings | ScanRawStrings | ScanComments | SkipComments
+)
+
+// The result of Scan is one of the following tokens or a Unicode character.
+const (
+	EOF = -(iota + 1)
+	Ident
+	Int
+	Float
+	Char
+	String
+	RawString
+	Comment
+	skipComment
+)
+
+var tokenString = map[rune]string{
+	EOF:       "EOF",
+	Ident:     "Ident",
+	Int:       "Int",
+	Float:     "Float",
+	Char:      "Char",
+	String:    "String",
+	RawString: "RawString",
+	Comment:   "Comment",
+}
+
+// TokenString returns a printable string for a token or Unicode character.
+func TokenString(tok rune) string {
+	if s, found := tokenString[tok]; found {
+		return s
+	}
+	return fmt.Sprintf("%q", string(tok))
+}
+
+// GoWhitespace is the default value for the Scanner's Whitespace field.
+// Its value selects Go's white space characters.
+const GoWhitespace = 1<<'\t' | 1<<'\n' | 1<<'\r' | 1<<' '
+
+const bufLen = 1024 // at least utf8.UTFMax
+
+// A Scanner implements reading of Unicode characters and tokens from an io.Reader.
+type Scanner struct {
+	// Input
+	src io.Reader
+
+	// Source buffer
+	srcBuf [bufLen + 1]byte // +1 for sentinel for common case of s.next()
+	srcPos int              // reading position (srcBuf index)
+	srcEnd int              // source end (srcBuf index)
+
+	// Source position
+	srcBufOffset int // byte offset of srcBuf[0] in source
+	line         int // line count
+	column       int // character count
+	lastLineLen  int // length of last line in characters (for correct column reporting)
+	lastCharLen  int // length of last character in bytes
+
+	// Token text buffer
+	// Typically, token text is stored completely in srcBuf, but in general
+	// the token text's head may be buffered in tokBuf while the token text's
+	// tail is stored in srcBuf.
+	tokBuf bytes.Buffer // token text head that is not in srcBuf anymore
+	tokPos int          // token text tail position (srcBuf index); valid if >= 0
+	tokEnd int          // token text tail end (srcBuf index)
+
+	// One character look-ahead
+	ch rune // character before current srcPos
+
+	// Error is called for each error encountered. If no Error
+	// function is set, the error is reported to os.Stderr.
+	Error func(s *Scanner, msg string)
+
+	// ErrorCount is incremented by one for each error encountered.
+	ErrorCount int
+
+	// The Mode field controls which tokens are recognized. For instance,
+	// to recognize Ints, set the ScanInts bit in Mode. The field may be
+	// changed at any time.
+	Mode uint
+
+	// The Whitespace field controls which characters are recognized
+	// as white space. To recognize a character ch <= ' ' as white space,
+	// set the ch'th bit in Whitespace (the Scanner's behavior is undefined
+	// for values ch > ' '). The field may be changed at any time.
+	Whitespace uint64
+
+	// IsIdentRune is a predicate controlling the characters accepted
+	// as the ith rune in an identifier. The set of valid characters
+	// must not intersect with the set of white space characters.
+	// If no IsIdentRune function is set, regular Go identifiers are
+	// accepted instead. The field may be changed at any time.
+	IsIdentRune func(ch rune, i int) bool
+
+	// Start position of most recently scanned token; set by Scan.
+	// Calling Init or Next invalidates the position (Line == 0).
+	// The Filename field is always left untouched by the Scanner.
+	// If an error is reported (via Error) and Position is invalid,
+	// the scanner is not inside a token. Call Pos to obtain an error
+	// position in that case.
+	Position
+}
+
+// Init initializes a Scanner with a new source and returns s.
+// Error is set to nil, ErrorCount is set to 0, Mode is set to GoTokens,
+// and Whitespace is set to GoWhitespace.
+func (s *Scanner) Init(src io.Reader) *Scanner {
+	s.src = src
+
+	// initialize source buffer
+	// (the first call to next() will fill it by calling src.Read)
+	s.srcBuf[0] = utf8.RuneSelf // sentinel
+	s.srcPos = 0
+	s.srcEnd = 0
+
+	// initialize source position
+	s.srcBufOffset = 0
+	s.line = 1
+	s.column = 0
+	s.lastLineLen = 0
+	s.lastCharLen = 0
+
+	// initialize token text buffer
+	// (required for first call to next()).
+	s.tokPos = -1
+
+	// initialize one character look-ahead
+	s.ch = -1 // no char read yet
+
+	// initialize public fields
+	s.Error = nil
+	s.ErrorCount = 0
+	s.Mode = GoTokens
+	s.Whitespace = GoWhitespace
+	s.Line = 0 // invalidate token position
+
+	return s
+}
+
+// next reads and returns the next Unicode character. It is designed such
+// that only a minimal amount of work needs to be done in the common ASCII
+// case (one test to check for both ASCII and end-of-buffer, and one test
+// to check for newlines).
+func (s *Scanner) next() rune {
+	ch, width := rune(s.srcBuf[s.srcPos]), 1
+
+	if ch >= utf8.RuneSelf {
+		// uncommon case: not ASCII or not enough bytes
+		for s.srcPos+utf8.UTFMax > s.srcEnd && !utf8.FullRune(s.srcBuf[s.srcPos:s.srcEnd]) {
+			// not enough bytes: read some more, but first
+			// save away token text if any
+			if s.tokPos >= 0 {
+				s.tokBuf.Write(s.srcBuf[s.tokPos:s.srcPos])
+				s.tokPos = 0
+				// s.tokEnd is set by Scan()
+			}
+			// move unread bytes to beginning of buffer
+			copy(s.srcBuf[0:], s.srcBuf[s.srcPos:s.srcEnd])
+			s.srcBufOffset += s.srcPos
+			// read more bytes
+			// (an io.Reader must return io.EOF when it reaches
+			// the end of what it is reading - simply returning
+			// n == 0 will make this loop retry forever; but the
+			// error is in the reader implementation in that case)
+			i := s.srcEnd - s.srcPos
+			n, err := s.src.Read(s.srcBuf[i:bufLen])
+			s.srcPos = 0
+			s.srcEnd = i + n
+			s.srcBuf[s.srcEnd] = utf8.RuneSelf // sentinel
+			if err != nil {
+				if err != io.EOF {
+					s.error(err.Error())
+				}
+				if s.srcEnd == 0 {
+					if s.lastCharLen > 0 {
+						// previous character was not EOF
+						s.column++
+					}
+					s.lastCharLen = 0
+					return EOF
+				}
+				// If err == EOF, we won't be getting more
+				// bytes; break to avoid infinite loop. If
+				// err is something else, we don't know if
+				// we can get more bytes; thus also break.
+				break
+			}
+		}
+		// at least one byte
+		ch = rune(s.srcBuf[s.srcPos])
+		if ch >= utf8.RuneSelf {
+			// uncommon case: not ASCII
+			ch, width = utf8.DecodeRune(s.srcBuf[s.srcPos:s.srcEnd])
+			if ch == utf8.RuneError && width == 1 {
+				// advance for correct error position
+				s.srcPos += width
+				s.lastCharLen = width
+				s.column++
+				s.error("illegal UTF-8 encoding")
+				return ch
+			}
+		}
+	}
+
+	// advance
+	s.srcPos += width
+	s.lastCharLen = width
+	s.column++
+
+	// special situations
+	switch ch {
+	case 0:
+		// for compatibility with other tools
+		s.error("illegal character NUL")
+	case '\n':
+		s.line++
+		s.lastLineLen = s.column
+		s.column = 0
+	}
+
+	return ch
+}
+
+// Next reads and returns the next Unicode character.
+// It returns EOF at the end of the source. It reports
+// a read error by calling s.Error, if not nil; otherwise
+// it prints an error message to os.Stderr. Next does not
+// update the Scanner's Position field; use Pos() to
+// get the current position.
+func (s *Scanner) Next() rune {
+	s.tokPos = -1 // don't collect token text
+	s.Line = 0    // invalidate token position
+	ch := s.Peek()
+	s.ch = s.next()
+	return ch
+}
+
+// Peek returns the next Unicode character in the source without advancing
+// the scanner. It returns EOF if the scanner's position is at the last
+// character of the source.
+func (s *Scanner) Peek() rune {
+	if s.ch < 0 {
+		// this code is only run for the very first character
+		s.ch = s.next()
+		if s.ch == '\uFEFF' {
+			s.ch = s.next() // ignore BOM
+		}
+	}
+	return s.ch
+}
+
+func (s *Scanner) error(msg string) {
+	s.ErrorCount++
+	if s.Error != nil {
+		s.Error(s, msg)
+		return
+	}
+	pos := s.Position
+	if !pos.IsValid() {
+		pos = s.Pos()
+	}
+	fmt.Fprintf(os.Stderr, "%s: %s\n", pos, msg)
+}
+
+func (s *Scanner) isIdentRune(ch rune, i int) bool {
+	if s.IsIdentRune != nil {
+		return s.IsIdentRune(ch, i)
+	}
+	return ch == '_' || unicode.IsLetter(ch) || unicode.IsDigit(ch) && i > 0
+}
+
+func (s *Scanner) scanIdentifier() rune {
+	// we know the zero'th rune is OK; start scanning at the next one
+	ch := s.next()
+	for i := 1; s.isIdentRune(ch, i); i++ {
+		ch = s.next()
+	}
+	return ch
+}
+
+func digitVal(ch rune) int {
+	switch {
+	case '0' <= ch && ch <= '9':
+		return int(ch - '0')
+	case 'a' <= ch && ch <= 'f':
+		return int(ch - 'a' + 10)
+	case 'A' <= ch && ch <= 'F':
+		return int(ch - 'A' + 10)
+	}
+	return 16 // larger than any legal digit val
+}
+
+func isDecimal(ch rune) bool { return '0' <= ch && ch <= '9' }
+
+func (s *Scanner) scanMantissa(ch rune) rune {
+	for isDecimal(ch) {
+		ch = s.next()
+	}
+	return ch
+}
+
+func (s *Scanner) scanFraction(ch rune) rune {
+	if ch == '.' {
+		ch = s.scanMantissa(s.next())
+	}
+	return ch
+}
+
+func (s *Scanner) scanExponent(ch rune) rune {
+	if ch == 'e' || ch == 'E' {
+		ch = s.next()
+		if ch == '-' || ch == '+' {
+			ch = s.next()
+		}
+		ch = s.scanMantissa(ch)
+	}
+	return ch
+}
+
+func (s *Scanner) scanNumber(ch rune) (rune, rune) {
+	// isDecimal(ch)
+	if ch == '0' {
+		// int or float
+		ch = s.next()
+		if ch == 'x' || ch == 'X' {
+			// hexadecimal int
+			ch = s.next()
+			hasMantissa := false
+			for digitVal(ch) < 16 {
+				ch = s.next()
+				hasMantissa = true
+			}
+			if !hasMantissa {
+				s.error("illegal hexadecimal number")
+			}
+		} else {
+			// octal int or float
+			has8or9 := false
+			for isDecimal(ch) {
+				if ch > '7' {
+					has8or9 = true
+				}
+				ch = s.next()
+			}
+			if s.Mode&ScanFloats != 0 && (ch == '.' || ch == 'e' || ch == 'E') {
+				// float
+				ch = s.scanFraction(ch)
+				ch = s.scanExponent(ch)
+				return Float, ch
+			}
+			// octal int
+			if has8or9 {
+				s.error("illegal octal number")
+			}
+		}
+		return Int, ch
+	}
+	// decimal int or float
+	ch = s.scanMantissa(ch)
+	if s.Mode&ScanFloats != 0 && (ch == '.' || ch == 'e' || ch == 'E') {
+		// float
+		ch = s.scanFraction(ch)
+		ch = s.scanExponent(ch)
+		return Float, ch
+	}
+	return Int, ch
+}
+
+func (s *Scanner) scanDigits(ch rune, base, n int) rune {
+	for n > 0 && digitVal(ch) < base {
+		ch = s.next()
+		n--
+	}
+	if n > 0 {
+		s.error("illegal char escape")
+	}
+	return ch
+}
+
+func (s *Scanner) scanEscape(quote rune) rune {
+	ch := s.next() // read character after '/'
+	switch ch {
+	case 'a', 'b', 'f', 'n', 'r', 't', 'v', '\\', quote:
+		// nothing to do
+		ch = s.next()
+	case '0', '1', '2', '3', '4', '5', '6', '7':
+		ch = s.scanDigits(ch, 8, 3)
+	case 'x':
+		ch = s.scanDigits(s.next(), 16, 2)
+	case 'u':
+		ch = s.scanDigits(s.next(), 16, 4)
+	case 'U':
+		ch = s.scanDigits(s.next(), 16, 8)
+	default:
+		s.error("illegal char escape")
+	}
+	return ch
+}
+
+func (s *Scanner) scanString(quote rune) (n int) {
+	ch := s.next() // read character after quote
+	for ch != quote {
+		if ch == '\n' || ch < 0 {
+			s.error("literal not terminated")
+			return
+		}
+		if ch == '\\' {
+			ch = s.scanEscape(quote)
+		} else {
+			ch = s.next()
+		}
+		n++
+	}
+	return
+}
+
+func (s *Scanner) scanRawString() {
+	ch := s.next() // read character after '`'
+	for ch != '`' {
+		if ch < 0 {
+			s.error("literal not terminated")
+			return
+		}
+		ch = s.next()
+	}
+}
+
+func (s *Scanner) scanChar() {
+	if s.scanString('\'') != 1 {
+		s.error("illegal char literal")
+	}
+}
+
+func (s *Scanner) scanComment(ch rune) rune {
+	// ch == '/' || ch == '*'
+	if ch == '/' {
+		// line comment
+		ch = s.next() // read character after "//"
+		for ch != '\n' && ch >= 0 {
+			ch = s.next()
+		}
+		return ch
+	}
+
+	// general comment
+	ch = s.next() // read character after "/*"
+	for {
+		if ch < 0 {
+			s.error("comment not terminated")
+			break
+		}
+		ch0 := ch
+		ch = s.next()
+		if ch0 == '*' && ch == '/' {
+			ch = s.next()
+			break
+		}
+	}
+	return ch
+}
+
+// Scan reads the next token or Unicode character from source and returns it.
+// It only recognizes tokens t for which the respective Mode bit (1<<-t) is set.
+// It returns EOF at the end of the source. It reports scanner errors (read and
+// token errors) by calling s.Error, if not nil; otherwise it prints an error
+// message to os.Stderr.
+func (s *Scanner) Scan() rune {
+	ch := s.Peek()
+
+	// reset token text position
+	s.tokPos = -1
+	s.Line = 0
+
+redo:
+	// skip white space
+	for s.Whitespace&(1<<uint(ch)) != 0 {
+		ch = s.next()
+	}
+
+	// start collecting token text
+	s.tokBuf.Reset()
+	s.tokPos = s.srcPos - s.lastCharLen
+
+	// set token position
+	// (this is a slightly optimized version of the code in Pos())
+	s.Offset = s.srcBufOffset + s.tokPos
+	if s.column > 0 {
+		// common case: last character was not a '\n'
+		s.Line = s.line
+		s.Column = s.column
+	} else {
+		// last character was a '\n'
+		// (we cannot be at the beginning of the source
+		// since we have called next() at least once)
+		s.Line = s.line - 1
+		s.Column = s.lastLineLen
+	}
+
+	// determine token value
+	tok := ch
+	switch {
+	case s.isIdentRune(ch, 0):
+		if s.Mode&ScanIdents != 0 {
+			tok = Ident
+			ch = s.scanIdentifier()
+		} else {
+			ch = s.next()
+		}
+	case isDecimal(ch):
+		if s.Mode&(ScanInts|ScanFloats) != 0 {
+			tok, ch = s.scanNumber(ch)
+		} else {
+			ch = s.next()
+		}
+	default:
+		switch ch {
+		case '"':
+			if s.Mode&ScanStrings != 0 {
+				s.scanString('"')
+				tok = String
+			}
+			ch = s.next()
+		case '\'':
+			if s.Mode&ScanChars != 0 {
+				s.scanChar()
+				tok = Char
+			}
+			ch = s.next()
+		case '.':
+			ch = s.next()
+			if isDecimal(ch) && s.Mode&ScanFloats != 0 {
+				tok = Float
+				ch = s.scanMantissa(ch)
+				ch = s.scanExponent(ch)
+			}
+		case '/':
+			ch = s.next()
+			if (ch == '/' || ch == '*') && s.Mode&ScanComments != 0 {
+				if s.Mode&SkipComments != 0 {
+					s.tokPos = -1 // don't collect token text
+					ch = s.scanComment(ch)
+					goto redo
+				}
+				ch = s.scanComment(ch)
+				tok = Comment
+			}
+		case '`':
+			if s.Mode&ScanRawStrings != 0 {
+				s.scanRawString()
+				tok = String
+			}
+			ch = s.next()
+		default:
+			ch = s.next()
+		}
+	}
+
+	// end of token text
+	s.tokEnd = s.srcPos - s.lastCharLen
+
+	s.ch = ch
+	return tok
+}
+
+// Pos returns the position of the character immediately after
+// the character or token returned by the last call to Next or Scan.
+func (s *Scanner) Pos() (pos Position) {
+	pos.Filename = s.Filename
+	pos.Offset = s.srcBufOffset + s.srcPos - s.lastCharLen
+	switch {
+	case s.column > 0:
+		// common case: last character was not a '\n'
+		pos.Line = s.line
+		pos.Column = s.column
+	case s.lastLineLen > 0:
+		// last character was a '\n'
+		pos.Line = s.line - 1
+		pos.Column = s.lastLineLen
+	default:
+		// at the beginning of the source
+		pos.Line = 1
+		pos.Column = 1
+	}
+	return
+}
+
+// TokenText returns the string corresponding to the most recently scanned token.
+// Valid after calling Scan().
+func (s *Scanner) TokenText() string {
+	if s.tokPos < 0 {
+		// no token text
+		return ""
+	}
+
+	if s.tokEnd < 0 {
+		// if EOF was reached, s.tokEnd is set to -1 (s.srcPos == 0)
+		s.tokEnd = s.tokPos
+	}
+
+	if s.tokBuf.Len() == 0 {
+		// common case: the entire token text is still in srcBuf
+		return string(s.srcBuf[s.tokPos:s.tokEnd])
+	}
+
+	// part of the token text was saved in tokBuf: save the rest in
+	// tokBuf as well and return its content
+	s.tokBuf.Write(s.srcBuf[s.tokPos:s.tokEnd])
+	s.tokPos = s.tokEnd // ensure idempotency of TokenText() call
+	return s.tokBuf.String()
+}
diff --git a/src/text/scanner/scanner_test.go b/src/text/scanner/scanner_test.go
new file mode 100644
index 0000000..702fac2
--- /dev/null
+++ b/src/text/scanner/scanner_test.go
@@ -0,0 +1,618 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package scanner
+
+import (
+	"bytes"
+	"fmt"
+	"io"
+	"strings"
+	"testing"
+	"unicode/utf8"
+)
+
+// A StringReader delivers its data one string segment at a time via Read.
+type StringReader struct {
+	data []string
+	step int
+}
+
+func (r *StringReader) Read(p []byte) (n int, err error) {
+	if r.step < len(r.data) {
+		s := r.data[r.step]
+		n = copy(p, s)
+		r.step++
+	} else {
+		err = io.EOF
+	}
+	return
+}
+
+func readRuneSegments(t *testing.T, segments []string) {
+	got := ""
+	want := strings.Join(segments, "")
+	s := new(Scanner).Init(&StringReader{data: segments})
+	for {
+		ch := s.Next()
+		if ch == EOF {
+			break
+		}
+		got += string(ch)
+	}
+	if got != want {
+		t.Errorf("segments=%v got=%s want=%s", segments, got, want)
+	}
+}
+
+var segmentList = [][]string{
+	{},
+	{""},
+	{"日", "本語"},
+	{"\u65e5", "\u672c", "\u8a9e"},
+	{"\U000065e5", " ", "\U0000672c", "\U00008a9e"},
+	{"\xe6", "\x97\xa5\xe6", "\x9c\xac\xe8\xaa\x9e"},
+	{"Hello", ", ", "World", "!"},
+	{"Hello", ", ", "", "World", "!"},
+}
+
+func TestNext(t *testing.T) {
+	for _, s := range segmentList {
+		readRuneSegments(t, s)
+	}
+}
+
+type token struct {
+	tok  rune
+	text string
+}
+
+var f100 = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
+
+var tokenList = []token{
+	{Comment, "// line comments"},
+	{Comment, "//"},
+	{Comment, "////"},
+	{Comment, "// comment"},
+	{Comment, "// /* comment */"},
+	{Comment, "// // comment //"},
+	{Comment, "//" + f100},
+
+	{Comment, "// general comments"},
+	{Comment, "/**/"},
+	{Comment, "/***/"},
+	{Comment, "/* comment */"},
+	{Comment, "/* // comment */"},
+	{Comment, "/* /* comment */"},
+	{Comment, "/*\n comment\n*/"},
+	{Comment, "/*" + f100 + "*/"},
+
+	{Comment, "// identifiers"},
+	{Ident, "a"},
+	{Ident, "a0"},
+	{Ident, "foobar"},
+	{Ident, "abc123"},
+	{Ident, "LGTM"},
+	{Ident, "_"},
+	{Ident, "_abc123"},
+	{Ident, "abc123_"},
+	{Ident, "_abc_123_"},
+	{Ident, "_äöü"},
+	{Ident, "_本"},
+	{Ident, "äöü"},
+	{Ident, "本"},
+	{Ident, "a۰۱۸"},
+	{Ident, "foo६४"},
+	{Ident, "bar9876"},
+	{Ident, f100},
+
+	{Comment, "// decimal ints"},
+	{Int, "0"},
+	{Int, "1"},
+	{Int, "9"},
+	{Int, "42"},
+	{Int, "1234567890"},
+
+	{Comment, "// octal ints"},
+	{Int, "00"},
+	{Int, "01"},
+	{Int, "07"},
+	{Int, "042"},
+	{Int, "01234567"},
+
+	{Comment, "// hexadecimal ints"},
+	{Int, "0x0"},
+	{Int, "0x1"},
+	{Int, "0xf"},
+	{Int, "0x42"},
+	{Int, "0x123456789abcDEF"},
+	{Int, "0x" + f100},
+	{Int, "0X0"},
+	{Int, "0X1"},
+	{Int, "0XF"},
+	{Int, "0X42"},
+	{Int, "0X123456789abcDEF"},
+	{Int, "0X" + f100},
+
+	{Comment, "// floats"},
+	{Float, "0."},
+	{Float, "1."},
+	{Float, "42."},
+	{Float, "01234567890."},
+	{Float, ".0"},
+	{Float, ".1"},
+	{Float, ".42"},
+	{Float, ".0123456789"},
+	{Float, "0.0"},
+	{Float, "1.0"},
+	{Float, "42.0"},
+	{Float, "01234567890.0"},
+	{Float, "0e0"},
+	{Float, "1e0"},
+	{Float, "42e0"},
+	{Float, "01234567890e0"},
+	{Float, "0E0"},
+	{Float, "1E0"},
+	{Float, "42E0"},
+	{Float, "01234567890E0"},
+	{Float, "0e+10"},
+	{Float, "1e-10"},
+	{Float, "42e+10"},
+	{Float, "01234567890e-10"},
+	{Float, "0E+10"},
+	{Float, "1E-10"},
+	{Float, "42E+10"},
+	{Float, "01234567890E-10"},
+
+	{Comment, "// chars"},
+	{Char, `' '`},
+	{Char, `'a'`},
+	{Char, `'本'`},
+	{Char, `'\a'`},
+	{Char, `'\b'`},
+	{Char, `'\f'`},
+	{Char, `'\n'`},
+	{Char, `'\r'`},
+	{Char, `'\t'`},
+	{Char, `'\v'`},
+	{Char, `'\''`},
+	{Char, `'\000'`},
+	{Char, `'\777'`},
+	{Char, `'\x00'`},
+	{Char, `'\xff'`},
+	{Char, `'\u0000'`},
+	{Char, `'\ufA16'`},
+	{Char, `'\U00000000'`},
+	{Char, `'\U0000ffAB'`},
+
+	{Comment, "// strings"},
+	{String, `" "`},
+	{String, `"a"`},
+	{String, `"本"`},
+	{String, `"\a"`},
+	{String, `"\b"`},
+	{String, `"\f"`},
+	{String, `"\n"`},
+	{String, `"\r"`},
+	{String, `"\t"`},
+	{String, `"\v"`},
+	{String, `"\""`},
+	{String, `"\000"`},
+	{String, `"\777"`},
+	{String, `"\x00"`},
+	{String, `"\xff"`},
+	{String, `"\u0000"`},
+	{String, `"\ufA16"`},
+	{String, `"\U00000000"`},
+	{String, `"\U0000ffAB"`},
+	{String, `"` + f100 + `"`},
+
+	{Comment, "// raw strings"},
+	{String, "``"},
+	{String, "`\\`"},
+	{String, "`" + "\n\n/* foobar */\n\n" + "`"},
+	{String, "`" + f100 + "`"},
+
+	{Comment, "// individual characters"},
+	// NUL character is not allowed
+	{'\x01', "\x01"},
+	{' ' - 1, string(' ' - 1)},
+	{'+', "+"},
+	{'/', "/"},
+	{'.', "."},
+	{'~', "~"},
+	{'(', "("},
+}
+
+func makeSource(pattern string) *bytes.Buffer {
+	var buf bytes.Buffer
+	for _, k := range tokenList {
+		fmt.Fprintf(&buf, pattern, k.text)
+	}
+	return &buf
+}
+
+func checkTok(t *testing.T, s *Scanner, line int, got, want rune, text string) {
+	if got != want {
+		t.Fatalf("tok = %s, want %s for %q", TokenString(got), TokenString(want), text)
+	}
+	if s.Line != line {
+		t.Errorf("line = %d, want %d for %q", s.Line, line, text)
+	}
+	stext := s.TokenText()
+	if stext != text {
+		t.Errorf("text = %q, want %q", stext, text)
+	} else {
+		// check idempotency of TokenText() call
+		stext = s.TokenText()
+		if stext != text {
+			t.Errorf("text = %q, want %q (idempotency check)", stext, text)
+		}
+	}
+}
+
+func countNewlines(s string) int {
+	n := 0
+	for _, ch := range s {
+		if ch == '\n' {
+			n++
+		}
+	}
+	return n
+}
+
+func testScan(t *testing.T, mode uint) {
+	s := new(Scanner).Init(makeSource(" \t%s\n"))
+	s.Mode = mode
+	tok := s.Scan()
+	line := 1
+	for _, k := range tokenList {
+		if mode&SkipComments == 0 || k.tok != Comment {
+			checkTok(t, s, line, tok, k.tok, k.text)
+			tok = s.Scan()
+		}
+		line += countNewlines(k.text) + 1 // each token is on a new line
+	}
+	checkTok(t, s, line, tok, EOF, "")
+}
+
+func TestScan(t *testing.T) {
+	testScan(t, GoTokens)
+	testScan(t, GoTokens&^SkipComments)
+}
+
+func TestPosition(t *testing.T) {
+	src := makeSource("\t\t\t\t%s\n")
+	s := new(Scanner).Init(src)
+	s.Mode = GoTokens &^ SkipComments
+	s.Scan()
+	pos := Position{"", 4, 1, 5}
+	for _, k := range tokenList {
+		if s.Offset != pos.Offset {
+			t.Errorf("offset = %d, want %d for %q", s.Offset, pos.Offset, k.text)
+		}
+		if s.Line != pos.Line {
+			t.Errorf("line = %d, want %d for %q", s.Line, pos.Line, k.text)
+		}
+		if s.Column != pos.Column {
+			t.Errorf("column = %d, want %d for %q", s.Column, pos.Column, k.text)
+		}
+		pos.Offset += 4 + len(k.text) + 1     // 4 tabs + token bytes + newline
+		pos.Line += countNewlines(k.text) + 1 // each token is on a new line
+		s.Scan()
+	}
+	// make sure there were no token-internal errors reported by scanner
+	if s.ErrorCount != 0 {
+		t.Errorf("%d errors", s.ErrorCount)
+	}
+}
+
+func TestScanZeroMode(t *testing.T) {
+	src := makeSource("%s\n")
+	str := src.String()
+	s := new(Scanner).Init(src)
+	s.Mode = 0       // don't recognize any token classes
+	s.Whitespace = 0 // don't skip any whitespace
+	tok := s.Scan()
+	for i, ch := range str {
+		if tok != ch {
+			t.Fatalf("%d. tok = %s, want %s", i, TokenString(tok), TokenString(ch))
+		}
+		tok = s.Scan()
+	}
+	if tok != EOF {
+		t.Fatalf("tok = %s, want EOF", TokenString(tok))
+	}
+	if s.ErrorCount != 0 {
+		t.Errorf("%d errors", s.ErrorCount)
+	}
+}
+
+func testScanSelectedMode(t *testing.T, mode uint, class rune) {
+	src := makeSource("%s\n")
+	s := new(Scanner).Init(src)
+	s.Mode = mode
+	tok := s.Scan()
+	for tok != EOF {
+		if tok < 0 && tok != class {
+			t.Fatalf("tok = %s, want %s", TokenString(tok), TokenString(class))
+		}
+		tok = s.Scan()
+	}
+	if s.ErrorCount != 0 {
+		t.Errorf("%d errors", s.ErrorCount)
+	}
+}
+
+func TestScanSelectedMask(t *testing.T) {
+	testScanSelectedMode(t, 0, 0)
+	testScanSelectedMode(t, ScanIdents, Ident)
+	// Don't test ScanInts and ScanNumbers since some parts of
+	// the floats in the source look like (illegal) octal ints
+	// and ScanNumbers may return either Int or Float.
+	testScanSelectedMode(t, ScanChars, Char)
+	testScanSelectedMode(t, ScanStrings, String)
+	testScanSelectedMode(t, SkipComments, 0)
+	testScanSelectedMode(t, ScanComments, Comment)
+}
+
+func TestScanCustomIdent(t *testing.T) {
+	const src = "faab12345 a12b123 a12 3b"
+	s := new(Scanner).Init(strings.NewReader(src))
+	// ident = ( 'a' | 'b' ) { digit } .
+	// digit = '0' .. '3' .
+	// with a maximum length of 4
+	s.IsIdentRune = func(ch rune, i int) bool {
+		return i == 0 && (ch == 'a' || ch == 'b') || 0 < i && i < 4 && '0' <= ch && ch <= '3'
+	}
+	checkTok(t, s, 1, s.Scan(), 'f', "f")
+	checkTok(t, s, 1, s.Scan(), Ident, "a")
+	checkTok(t, s, 1, s.Scan(), Ident, "a")
+	checkTok(t, s, 1, s.Scan(), Ident, "b123")
+	checkTok(t, s, 1, s.Scan(), Int, "45")
+	checkTok(t, s, 1, s.Scan(), Ident, "a12")
+	checkTok(t, s, 1, s.Scan(), Ident, "b123")
+	checkTok(t, s, 1, s.Scan(), Ident, "a12")
+	checkTok(t, s, 1, s.Scan(), Int, "3")
+	checkTok(t, s, 1, s.Scan(), Ident, "b")
+	checkTok(t, s, 1, s.Scan(), EOF, "")
+}
+
+func TestScanNext(t *testing.T) {
+	const BOM = '\uFEFF'
+	BOMs := string(BOM)
+	s := new(Scanner).Init(strings.NewReader(BOMs + "if a == bcd /* com" + BOMs + "ment */ {\n\ta += c\n}" + BOMs + "// line comment ending in eof"))
+	checkTok(t, s, 1, s.Scan(), Ident, "if") // the first BOM is ignored
+	checkTok(t, s, 1, s.Scan(), Ident, "a")
+	checkTok(t, s, 1, s.Scan(), '=', "=")
+	checkTok(t, s, 0, s.Next(), '=', "")
+	checkTok(t, s, 0, s.Next(), ' ', "")
+	checkTok(t, s, 0, s.Next(), 'b', "")
+	checkTok(t, s, 1, s.Scan(), Ident, "cd")
+	checkTok(t, s, 1, s.Scan(), '{', "{")
+	checkTok(t, s, 2, s.Scan(), Ident, "a")
+	checkTok(t, s, 2, s.Scan(), '+', "+")
+	checkTok(t, s, 0, s.Next(), '=', "")
+	checkTok(t, s, 2, s.Scan(), Ident, "c")
+	checkTok(t, s, 3, s.Scan(), '}', "}")
+	checkTok(t, s, 3, s.Scan(), BOM, BOMs)
+	checkTok(t, s, 3, s.Scan(), -1, "")
+	if s.ErrorCount != 0 {
+		t.Errorf("%d errors", s.ErrorCount)
+	}
+}
+
+func TestScanWhitespace(t *testing.T) {
+	var buf bytes.Buffer
+	var ws uint64
+	// start at 1, NUL character is not allowed
+	for ch := byte(1); ch < ' '; ch++ {
+		buf.WriteByte(ch)
+		ws |= 1 << ch
+	}
+	const orig = 'x'
+	buf.WriteByte(orig)
+
+	s := new(Scanner).Init(&buf)
+	s.Mode = 0
+	s.Whitespace = ws
+	tok := s.Scan()
+	if tok != orig {
+		t.Errorf("tok = %s, want %s", TokenString(tok), TokenString(orig))
+	}
+}
+
+func testError(t *testing.T, src, pos, msg string, tok rune) {
+	s := new(Scanner).Init(strings.NewReader(src))
+	errorCalled := false
+	s.Error = func(s *Scanner, m string) {
+		if !errorCalled {
+			// only look at first error
+			if p := s.Pos().String(); p != pos {
+				t.Errorf("pos = %q, want %q for %q", p, pos, src)
+			}
+			if m != msg {
+				t.Errorf("msg = %q, want %q for %q", m, msg, src)
+			}
+			errorCalled = true
+		}
+	}
+	tk := s.Scan()
+	if tk != tok {
+		t.Errorf("tok = %s, want %s for %q", TokenString(tk), TokenString(tok), src)
+	}
+	if !errorCalled {
+		t.Errorf("error handler not called for %q", src)
+	}
+	if s.ErrorCount == 0 {
+		t.Errorf("count = %d, want > 0 for %q", s.ErrorCount, src)
+	}
+}
+
+func TestError(t *testing.T) {
+	testError(t, "\x00", "1:1", "illegal character NUL", 0)
+	testError(t, "\x80", "1:1", "illegal UTF-8 encoding", utf8.RuneError)
+	testError(t, "\xff", "1:1", "illegal UTF-8 encoding", utf8.RuneError)
+
+	testError(t, "a\x00", "1:2", "illegal character NUL", Ident)
+	testError(t, "ab\x80", "1:3", "illegal UTF-8 encoding", Ident)
+	testError(t, "abc\xff", "1:4", "illegal UTF-8 encoding", Ident)
+
+	testError(t, `"a`+"\x00", "1:3", "illegal character NUL", String)
+	testError(t, `"ab`+"\x80", "1:4", "illegal UTF-8 encoding", String)
+	testError(t, `"abc`+"\xff", "1:5", "illegal UTF-8 encoding", String)
+
+	testError(t, "`a"+"\x00", "1:3", "illegal character NUL", String)
+	testError(t, "`ab"+"\x80", "1:4", "illegal UTF-8 encoding", String)
+	testError(t, "`abc"+"\xff", "1:5", "illegal UTF-8 encoding", String)
+
+	testError(t, `'\"'`, "1:3", "illegal char escape", Char)
+	testError(t, `"\'"`, "1:3", "illegal char escape", String)
+
+	testError(t, `01238`, "1:6", "illegal octal number", Int)
+	testError(t, `01238123`, "1:9", "illegal octal number", Int)
+	testError(t, `0x`, "1:3", "illegal hexadecimal number", Int)
+	testError(t, `0xg`, "1:3", "illegal hexadecimal number", Int)
+	testError(t, `'aa'`, "1:4", "illegal char literal", Char)
+
+	testError(t, `'`, "1:2", "literal not terminated", Char)
+	testError(t, `'`+"\n", "1:2", "literal not terminated", Char)
+	testError(t, `"abc`, "1:5", "literal not terminated", String)
+	testError(t, `"abc`+"\n", "1:5", "literal not terminated", String)
+	testError(t, "`abc\n", "2:1", "literal not terminated", String)
+	testError(t, `/*/`, "1:4", "comment not terminated", EOF)
+}
+
+// An errReader returns (0, err) where err is not io.EOF.
+type errReader struct{}
+
+func (errReader) Read(b []byte) (int, error) {
+	return 0, io.ErrNoProgress // some error that is not io.EOF
+}
+
+func TestIOError(t *testing.T) {
+	s := new(Scanner).Init(errReader{})
+	errorCalled := false
+	s.Error = func(s *Scanner, msg string) {
+		if !errorCalled {
+			if want := io.ErrNoProgress.Error(); msg != want {
+				t.Errorf("msg = %q, want %q", msg, want)
+			}
+			errorCalled = true
+		}
+	}
+	tok := s.Scan()
+	if tok != EOF {
+		t.Errorf("tok = %s, want EOF", TokenString(tok))
+	}
+	if !errorCalled {
+		t.Errorf("error handler not called")
+	}
+}
+
+func checkPos(t *testing.T, got, want Position) {
+	if got.Offset != want.Offset || got.Line != want.Line || got.Column != want.Column {
+		t.Errorf("got offset, line, column = %d, %d, %d; want %d, %d, %d",
+			got.Offset, got.Line, got.Column, want.Offset, want.Line, want.Column)
+	}
+}
+
+func checkNextPos(t *testing.T, s *Scanner, offset, line, column int, char rune) {
+	if ch := s.Next(); ch != char {
+		t.Errorf("ch = %s, want %s", TokenString(ch), TokenString(char))
+	}
+	want := Position{Offset: offset, Line: line, Column: column}
+	checkPos(t, s.Pos(), want)
+}
+
+func checkScanPos(t *testing.T, s *Scanner, offset, line, column int, char rune) {
+	want := Position{Offset: offset, Line: line, Column: column}
+	checkPos(t, s.Pos(), want)
+	if ch := s.Scan(); ch != char {
+		t.Errorf("ch = %s, want %s", TokenString(ch), TokenString(char))
+		if string(ch) != s.TokenText() {
+			t.Errorf("tok = %q, want %q", s.TokenText(), string(ch))
+		}
+	}
+	checkPos(t, s.Position, want)
+}
+
+func TestPos(t *testing.T) {
+	// corner case: empty source
+	s := new(Scanner).Init(strings.NewReader(""))
+	checkPos(t, s.Pos(), Position{Offset: 0, Line: 1, Column: 1})
+	s.Peek() // peek doesn't affect the position
+	checkPos(t, s.Pos(), Position{Offset: 0, Line: 1, Column: 1})
+
+	// corner case: source with only a newline
+	s = new(Scanner).Init(strings.NewReader("\n"))
+	checkPos(t, s.Pos(), Position{Offset: 0, Line: 1, Column: 1})
+	checkNextPos(t, s, 1, 2, 1, '\n')
+	// after EOF position doesn't change
+	for i := 10; i > 0; i-- {
+		checkScanPos(t, s, 1, 2, 1, EOF)
+	}
+	if s.ErrorCount != 0 {
+		t.Errorf("%d errors", s.ErrorCount)
+	}
+
+	// corner case: source with only a single character
+	s = new(Scanner).Init(strings.NewReader("本"))
+	checkPos(t, s.Pos(), Position{Offset: 0, Line: 1, Column: 1})
+	checkNextPos(t, s, 3, 1, 2, '本')
+	// after EOF position doesn't change
+	for i := 10; i > 0; i-- {
+		checkScanPos(t, s, 3, 1, 2, EOF)
+	}
+	if s.ErrorCount != 0 {
+		t.Errorf("%d errors", s.ErrorCount)
+	}
+
+	// positions after calling Next
+	s = new(Scanner).Init(strings.NewReader("  foo६४  \n\n本語\n"))
+	checkNextPos(t, s, 1, 1, 2, ' ')
+	s.Peek() // peek doesn't affect the position
+	checkNextPos(t, s, 2, 1, 3, ' ')
+	checkNextPos(t, s, 3, 1, 4, 'f')
+	checkNextPos(t, s, 4, 1, 5, 'o')
+	checkNextPos(t, s, 5, 1, 6, 'o')
+	checkNextPos(t, s, 8, 1, 7, '६')
+	checkNextPos(t, s, 11, 1, 8, '४')
+	checkNextPos(t, s, 12, 1, 9, ' ')
+	checkNextPos(t, s, 13, 1, 10, ' ')
+	checkNextPos(t, s, 14, 2, 1, '\n')
+	checkNextPos(t, s, 15, 3, 1, '\n')
+	checkNextPos(t, s, 18, 3, 2, '本')
+	checkNextPos(t, s, 21, 3, 3, '語')
+	checkNextPos(t, s, 22, 4, 1, '\n')
+	// after EOF position doesn't change
+	for i := 10; i > 0; i-- {
+		checkScanPos(t, s, 22, 4, 1, EOF)
+	}
+	if s.ErrorCount != 0 {
+		t.Errorf("%d errors", s.ErrorCount)
+	}
+
+	// positions after calling Scan
+	s = new(Scanner).Init(strings.NewReader("abc\n本語\n\nx"))
+	s.Mode = 0
+	s.Whitespace = 0
+	checkScanPos(t, s, 0, 1, 1, 'a')
+	s.Peek() // peek doesn't affect the position
+	checkScanPos(t, s, 1, 1, 2, 'b')
+	checkScanPos(t, s, 2, 1, 3, 'c')
+	checkScanPos(t, s, 3, 1, 4, '\n')
+	checkScanPos(t, s, 4, 2, 1, '本')
+	checkScanPos(t, s, 7, 2, 2, '語')
+	checkScanPos(t, s, 10, 2, 3, '\n')
+	checkScanPos(t, s, 11, 3, 1, '\n')
+	checkScanPos(t, s, 12, 4, 1, 'x')
+	// after EOF position doesn't change
+	for i := 10; i > 0; i-- {
+		checkScanPos(t, s, 13, 4, 2, EOF)
+	}
+	if s.ErrorCount != 0 {
+		t.Errorf("%d errors", s.ErrorCount)
+	}
+}
diff --git a/src/pkg/text/tabwriter/example_test.go b/src/text/tabwriter/example_test.go
similarity index 100%
rename from src/pkg/text/tabwriter/example_test.go
rename to src/text/tabwriter/example_test.go
diff --git a/src/pkg/text/tabwriter/tabwriter.go b/src/text/tabwriter/tabwriter.go
similarity index 100%
rename from src/pkg/text/tabwriter/tabwriter.go
rename to src/text/tabwriter/tabwriter.go
diff --git a/src/pkg/text/tabwriter/tabwriter_test.go b/src/text/tabwriter/tabwriter_test.go
similarity index 100%
rename from src/pkg/text/tabwriter/tabwriter_test.go
rename to src/text/tabwriter/tabwriter_test.go
diff --git a/src/text/template/doc.go b/src/text/template/doc.go
new file mode 100644
index 0000000..223c595
--- /dev/null
+++ b/src/text/template/doc.go
@@ -0,0 +1,406 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+/*
+Package template implements data-driven templates for generating textual output.
+
+To generate HTML output, see package html/template, which has the same interface
+as this package but automatically secures HTML output against certain attacks.
+
+Templates are executed by applying them to a data structure. Annotations in the
+template refer to elements of the data structure (typically a field of a struct
+or a key in a map) to control execution and derive values to be displayed.
+Execution of the template walks the structure and sets the cursor, represented
+by a period '.' and called "dot", to the value at the current location in the
+structure as execution proceeds.
+
+The input text for a template is UTF-8-encoded text in any format.
+"Actions"--data evaluations or control structures--are delimited by
+"{{" and "}}"; all text outside actions is copied to the output unchanged.
+Actions may not span newlines, although comments can.
+
+Once parsed, a template may be executed safely in parallel.
+
+Here is a trivial example that prints "17 items are made of wool".
+
+	type Inventory struct {
+		Material string
+		Count    uint
+	}
+	sweaters := Inventory{"wool", 17}
+	tmpl, err := template.New("test").Parse("{{.Count}} items are made of {{.Material}}")
+	if err != nil { panic(err) }
+	err = tmpl.Execute(os.Stdout, sweaters)
+	if err != nil { panic(err) }
+
+More intricate examples appear below.
+
+Actions
+
+Here is the list of actions. "Arguments" and "pipelines" are evaluations of
+data, defined in detail below.
+
+*/
+//	{{/* a comment */}}
+//		A comment; discarded. May contain newlines.
+//		Comments do not nest and must start and end at the
+//		delimiters, as shown here.
+/*
+
+	{{pipeline}}
+		The default textual representation of the value of the pipeline
+		is copied to the output.
+
+	{{if pipeline}} T1 {{end}}
+		If the value of the pipeline is empty, no output is generated;
+		otherwise, T1 is executed.  The empty values are false, 0, any
+		nil pointer or interface value, and any array, slice, map, or
+		string of length zero.
+		Dot is unaffected.
+
+	{{if pipeline}} T1 {{else}} T0 {{end}}
+		If the value of the pipeline is empty, T0 is executed;
+		otherwise, T1 is executed.  Dot is unaffected.
+
+	{{if pipeline}} T1 {{else if pipeline}} T0 {{end}}
+		To simplify the appearance of if-else chains, the else action
+		of an if may include another if directly; the effect is exactly
+		the same as writing
+			{{if pipeline}} T1 {{else}}{{if pipeline}} T0 {{end}}{{end}}
+
+	{{range pipeline}} T1 {{end}}
+		The value of the pipeline must be an array, slice, map, or channel.
+		If the value of the pipeline has length zero, nothing is output;
+		otherwise, dot is set to the successive elements of the array,
+		slice, or map and T1 is executed. If the value is a map and the
+		keys are of basic type with a defined order ("comparable"), the
+		elements will be visited in sorted key order.
+
+	{{range pipeline}} T1 {{else}} T0 {{end}}
+		The value of the pipeline must be an array, slice, map, or channel.
+		If the value of the pipeline has length zero, dot is unaffected and
+		T0 is executed; otherwise, dot is set to the successive elements
+		of the array, slice, or map and T1 is executed.
+
+	{{template "name"}}
+		The template with the specified name is executed with nil data.
+
+	{{template "name" pipeline}}
+		The template with the specified name is executed with dot set
+		to the value of the pipeline.
+
+	{{with pipeline}} T1 {{end}}
+		If the value of the pipeline is empty, no output is generated;
+		otherwise, dot is set to the value of the pipeline and T1 is
+		executed.
+
+	{{with pipeline}} T1 {{else}} T0 {{end}}
+		If the value of the pipeline is empty, dot is unaffected and T0
+		is executed; otherwise, dot is set to the value of the pipeline
+		and T1 is executed.
+
+Arguments
+
+An argument is a simple value, denoted by one of the following.
+
+	- A boolean, string, character, integer, floating-point, imaginary
+	  or complex constant in Go syntax. These behave like Go's untyped
+	  constants, although raw strings may not span newlines.
+	- The keyword nil, representing an untyped Go nil.
+	- The character '.' (period):
+		.
+	  The result is the value of dot.
+	- A variable name, which is a (possibly empty) alphanumeric string
+	  preceded by a dollar sign, such as
+		$piOver2
+	  or
+		$
+	  The result is the value of the variable.
+	  Variables are described below.
+	- The name of a field of the data, which must be a struct, preceded
+	  by a period, such as
+		.Field
+	  The result is the value of the field. Field invocations may be
+	  chained:
+	    .Field1.Field2
+	  Fields can also be evaluated on variables, including chaining:
+	    $x.Field1.Field2
+	- The name of a key of the data, which must be a map, preceded
+	  by a period, such as
+		.Key
+	  The result is the map element value indexed by the key.
+	  Key invocations may be chained and combined with fields to any
+	  depth:
+	    .Field1.Key1.Field2.Key2
+	  Although the key must be an alphanumeric identifier, unlike with
+	  field names they do not need to start with an upper case letter.
+	  Keys can also be evaluated on variables, including chaining:
+	    $x.key1.key2
+	- The name of a niladic method of the data, preceded by a period,
+	  such as
+		.Method
+	  The result is the value of invoking the method with dot as the
+	  receiver, dot.Method(). Such a method must have one return value (of
+	  any type) or two return values, the second of which is an error.
+	  If it has two and the returned error is non-nil, execution terminates
+	  and an error is returned to the caller as the value of Execute.
+	  Method invocations may be chained and combined with fields and keys
+	  to any depth:
+	    .Field1.Key1.Method1.Field2.Key2.Method2
+	  Methods can also be evaluated on variables, including chaining:
+	    $x.Method1.Field
+	- The name of a niladic function, such as
+		fun
+	  The result is the value of invoking the function, fun(). The return
+	  types and values behave as in methods. Functions and function
+	  names are described below.
+	- A parenthesized instance of one the above, for grouping. The result
+	  may be accessed by a field or map key invocation.
+		print (.F1 arg1) (.F2 arg2)
+		(.StructValuedMethod "arg").Field
+
+Arguments may evaluate to any type; if they are pointers the implementation
+automatically indirects to the base type when required.
+If an evaluation yields a function value, such as a function-valued
+field of a struct, the function is not invoked automatically, but it
+can be used as a truth value for an if action and the like. To invoke
+it, use the call function, defined below.
+
+A pipeline is a possibly chained sequence of "commands". A command is a simple
+value (argument) or a function or method call, possibly with multiple arguments:
+
+	Argument
+		The result is the value of evaluating the argument.
+	.Method [Argument...]
+		The method can be alone or the last element of a chain but,
+		unlike methods in the middle of a chain, it can take arguments.
+		The result is the value of calling the method with the
+		arguments:
+			dot.Method(Argument1, etc.)
+	functionName [Argument...]
+		The result is the value of calling the function associated
+		with the name:
+			function(Argument1, etc.)
+		Functions and function names are described below.
+
+Pipelines
+
+A pipeline may be "chained" by separating a sequence of commands with pipeline
+characters '|'. In a chained pipeline, the result of the each command is
+passed as the last argument of the following command. The output of the final
+command in the pipeline is the value of the pipeline.
+
+The output of a command will be either one value or two values, the second of
+which has type error. If that second value is present and evaluates to
+non-nil, execution terminates and the error is returned to the caller of
+Execute.
+
+Variables
+
+A pipeline inside an action may initialize a variable to capture the result.
+The initialization has syntax
+
+	$variable := pipeline
+
+where $variable is the name of the variable. An action that declares a
+variable produces no output.
+
+If a "range" action initializes a variable, the variable is set to the
+successive elements of the iteration.  Also, a "range" may declare two
+variables, separated by a comma:
+
+	range $index, $element := pipeline
+
+in which case $index and $element are set to the successive values of the
+array/slice index or map key and element, respectively.  Note that if there is
+only one variable, it is assigned the element; this is opposite to the
+convention in Go range clauses.
+
+A variable's scope extends to the "end" action of the control structure ("if",
+"with", or "range") in which it is declared, or to the end of the template if
+there is no such control structure.  A template invocation does not inherit
+variables from the point of its invocation.
+
+When execution begins, $ is set to the data argument passed to Execute, that is,
+to the starting value of dot.
+
+Examples
+
+Here are some example one-line templates demonstrating pipelines and variables.
+All produce the quoted word "output":
+
+	{{"\"output\""}}
+		A string constant.
+	{{`"output"`}}
+		A raw string constant.
+	{{printf "%q" "output"}}
+		A function call.
+	{{"output" | printf "%q"}}
+		A function call whose final argument comes from the previous
+		command.
+	{{printf "%q" (print "out" "put")}}
+		A parenthesized argument.
+	{{"put" | printf "%s%s" "out" | printf "%q"}}
+		A more elaborate call.
+	{{"output" | printf "%s" | printf "%q"}}
+		A longer chain.
+	{{with "output"}}{{printf "%q" .}}{{end}}
+		A with action using dot.
+	{{with $x := "output" | printf "%q"}}{{$x}}{{end}}
+		A with action that creates and uses a variable.
+	{{with $x := "output"}}{{printf "%q" $x}}{{end}}
+		A with action that uses the variable in another action.
+	{{with $x := "output"}}{{$x | printf "%q"}}{{end}}
+		The same, but pipelined.
+
+Functions
+
+During execution functions are found in two function maps: first in the
+template, then in the global function map. By default, no functions are defined
+in the template but the Funcs method can be used to add them.
+
+Predefined global functions are named as follows.
+
+	and
+		Returns the boolean AND of its arguments by returning the
+		first empty argument or the last argument, that is,
+		"and x y" behaves as "if x then y else x". All the
+		arguments are evaluated.
+	call
+		Returns the result of calling the first argument, which
+		must be a function, with the remaining arguments as parameters.
+		Thus "call .X.Y 1 2" is, in Go notation, dot.X.Y(1, 2) where
+		Y is a func-valued field, map entry, or the like.
+		The first argument must be the result of an evaluation
+		that yields a value of function type (as distinct from
+		a predefined function such as print). The function must
+		return either one or two result values, the second of which
+		is of type error. If the arguments don't match the function
+		or the returned error value is non-nil, execution stops.
+	html
+		Returns the escaped HTML equivalent of the textual
+		representation of its arguments.
+	index
+		Returns the result of indexing its first argument by the
+		following arguments. Thus "index x 1 2 3" is, in Go syntax,
+		x[1][2][3]. Each indexed item must be a map, slice, or array.
+	js
+		Returns the escaped JavaScript equivalent of the textual
+		representation of its arguments.
+	len
+		Returns the integer length of its argument.
+	not
+		Returns the boolean negation of its single argument.
+	or
+		Returns the boolean OR of its arguments by returning the
+		first non-empty argument or the last argument, that is,
+		"or x y" behaves as "if x then x else y". All the
+		arguments are evaluated.
+	print
+		An alias for fmt.Sprint
+	printf
+		An alias for fmt.Sprintf
+	println
+		An alias for fmt.Sprintln
+	urlquery
+		Returns the escaped value of the textual representation of
+		its arguments in a form suitable for embedding in a URL query.
+
+The boolean functions take any zero value to be false and a non-zero
+value to be true.
+
+There is also a set of binary comparison operators defined as
+functions:
+
+	eq
+		Returns the boolean truth of arg1 == arg2
+	ne
+		Returns the boolean truth of arg1 != arg2
+	lt
+		Returns the boolean truth of arg1 < arg2
+	le
+		Returns the boolean truth of arg1 <= arg2
+	gt
+		Returns the boolean truth of arg1 > arg2
+	ge
+		Returns the boolean truth of arg1 >= arg2
+
+For simpler multi-way equality tests, eq (only) accepts two or more
+arguments and compares the second and subsequent to the first,
+returning in effect
+
+	arg1==arg2 || arg1==arg3 || arg1==arg4 ...
+
+(Unlike with || in Go, however, eq is a function call and all the
+arguments will be evaluated.)
+
+The comparison functions work on basic types only (or named basic
+types, such as "type Celsius float32"). They implement the Go rules
+for comparison of values, except that size and exact type are
+ignored, so any integer value, signed or unsigned, may be compared
+with any other integer value. (The arithmetic value is compared,
+not the bit pattern, so all negative integers are less than all
+unsigned integers.) However, as usual, one may not compare an int
+with a float32 and so on.
+
+Associated templates
+
+Each template is named by a string specified when it is created. Also, each
+template is associated with zero or more other templates that it may invoke by
+name; such associations are transitive and form a name space of templates.
+
+A template may use a template invocation to instantiate another associated
+template; see the explanation of the "template" action above. The name must be
+that of a template associated with the template that contains the invocation.
+
+Nested template definitions
+
+When parsing a template, another template may be defined and associated with the
+template being parsed. Template definitions must appear at the top level of the
+template, much like global variables in a Go program.
+
+The syntax of such definitions is to surround each template declaration with a
+"define" and "end" action.
+
+The define action names the template being created by providing a string
+constant. Here is a simple example:
+
+	`{{define "T1"}}ONE{{end}}
+	{{define "T2"}}TWO{{end}}
+	{{define "T3"}}{{template "T1"}} {{template "T2"}}{{end}}
+	{{template "T3"}}`
+
+This defines two templates, T1 and T2, and a third T3 that invokes the other two
+when it is executed. Finally it invokes T3. If executed this template will
+produce the text
+
+	ONE TWO
+
+By construction, a template may reside in only one association. If it's
+necessary to have a template addressable from multiple associations, the
+template definition must be parsed multiple times to create distinct *Template
+values, or must be copied with the Clone or AddParseTree method.
+
+Parse may be called multiple times to assemble the various associated templates;
+see the ParseFiles and ParseGlob functions and methods for simple ways to parse
+related templates stored in files.
+
+A template may be executed directly or through ExecuteTemplate, which executes
+an associated template identified by name. To invoke our example above, we
+might write,
+
+	err := tmpl.Execute(os.Stdout, "no data needed")
+	if err != nil {
+		log.Fatalf("execution failed: %s", err)
+	}
+
+or to invoke a particular template explicitly by name,
+
+	err := tmpl.ExecuteTemplate(os.Stdout, "T2", "no data needed")
+	if err != nil {
+		log.Fatalf("execution failed: %s", err)
+	}
+
+*/
+package template
diff --git a/src/pkg/text/template/example_test.go b/src/text/template/example_test.go
similarity index 100%
rename from src/pkg/text/template/example_test.go
rename to src/text/template/example_test.go
diff --git a/src/pkg/text/template/examplefiles_test.go b/src/text/template/examplefiles_test.go
similarity index 100%
rename from src/pkg/text/template/examplefiles_test.go
rename to src/text/template/examplefiles_test.go
diff --git a/src/pkg/text/template/examplefunc_test.go b/src/text/template/examplefunc_test.go
similarity index 100%
rename from src/pkg/text/template/examplefunc_test.go
rename to src/text/template/examplefunc_test.go
diff --git a/src/text/template/exec.go b/src/text/template/exec.go
new file mode 100644
index 0000000..b00e10c
--- /dev/null
+++ b/src/text/template/exec.go
@@ -0,0 +1,844 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package template
+
+import (
+	"bytes"
+	"fmt"
+	"io"
+	"reflect"
+	"runtime"
+	"sort"
+	"strings"
+	"text/template/parse"
+)
+
+// state represents the state of an execution. It's not part of the
+// template so that multiple executions of the same template
+// can execute in parallel.
+type state struct {
+	tmpl *Template
+	wr   io.Writer
+	node parse.Node // current node, for errors
+	vars []variable // push-down stack of variable values.
+}
+
+// variable holds the dynamic value of a variable such as $, $x etc.
+type variable struct {
+	name  string
+	value reflect.Value
+}
+
+// push pushes a new variable on the stack.
+func (s *state) push(name string, value reflect.Value) {
+	s.vars = append(s.vars, variable{name, value})
+}
+
+// mark returns the length of the variable stack.
+func (s *state) mark() int {
+	return len(s.vars)
+}
+
+// pop pops the variable stack up to the mark.
+func (s *state) pop(mark int) {
+	s.vars = s.vars[0:mark]
+}
+
+// setVar overwrites the top-nth variable on the stack. Used by range iterations.
+func (s *state) setVar(n int, value reflect.Value) {
+	s.vars[len(s.vars)-n].value = value
+}
+
+// varValue returns the value of the named variable.
+func (s *state) varValue(name string) reflect.Value {
+	for i := s.mark() - 1; i >= 0; i-- {
+		if s.vars[i].name == name {
+			return s.vars[i].value
+		}
+	}
+	s.errorf("undefined variable: %s", name)
+	return zero
+}
+
+var zero reflect.Value
+
+// at marks the state to be on node n, for error reporting.
+func (s *state) at(node parse.Node) {
+	s.node = node
+}
+
+// doublePercent returns the string with %'s replaced by %%, if necessary,
+// so it can be used safely inside a Printf format string.
+func doublePercent(str string) string {
+	if strings.Contains(str, "%") {
+		str = strings.Replace(str, "%", "%%", -1)
+	}
+	return str
+}
+
+// errorf formats the error and terminates processing.
+func (s *state) errorf(format string, args ...interface{}) {
+	name := doublePercent(s.tmpl.Name())
+	if s.node == nil {
+		format = fmt.Sprintf("template: %s: %s", name, format)
+	} else {
+		location, context := s.tmpl.ErrorContext(s.node)
+		format = fmt.Sprintf("template: %s: executing %q at <%s>: %s", location, name, doublePercent(context), format)
+	}
+	panic(fmt.Errorf(format, args...))
+}
+
+// errRecover is the handler that turns panics into returns from the top
+// level of Parse.
+func errRecover(errp *error) {
+	e := recover()
+	if e != nil {
+		switch err := e.(type) {
+		case runtime.Error:
+			panic(e)
+		case error:
+			*errp = err
+		default:
+			panic(e)
+		}
+	}
+}
+
+// ExecuteTemplate applies the template associated with t that has the given name
+// to the specified data object and writes the output to wr.
+// If an error occurs executing the template or writing its output,
+// execution stops, but partial results may already have been written to
+// the output writer.
+// A template may be executed safely in parallel.
+func (t *Template) ExecuteTemplate(wr io.Writer, name string, data interface{}) error {
+	tmpl := t.tmpl[name]
+	if tmpl == nil {
+		return fmt.Errorf("template: no template %q associated with template %q", name, t.name)
+	}
+	return tmpl.Execute(wr, data)
+}
+
+// Execute applies a parsed template to the specified data object,
+// and writes the output to wr.
+// If an error occurs executing the template or writing its output,
+// execution stops, but partial results may already have been written to
+// the output writer.
+// A template may be executed safely in parallel.
+func (t *Template) Execute(wr io.Writer, data interface{}) (err error) {
+	defer errRecover(&err)
+	value := reflect.ValueOf(data)
+	state := &state{
+		tmpl: t,
+		wr:   wr,
+		vars: []variable{{"$", value}},
+	}
+	t.init()
+	if t.Tree == nil || t.Root == nil {
+		var b bytes.Buffer
+		for name, tmpl := range t.tmpl {
+			if tmpl.Tree == nil || tmpl.Root == nil {
+				continue
+			}
+			if b.Len() > 0 {
+				b.WriteString(", ")
+			}
+			fmt.Fprintf(&b, "%q", name)
+		}
+		var s string
+		if b.Len() > 0 {
+			s = "; defined templates are: " + b.String()
+		}
+		state.errorf("%q is an incomplete or empty template%s", t.Name(), s)
+	}
+	state.walk(value, t.Root)
+	return
+}
+
+// Walk functions step through the major pieces of the template structure,
+// generating output as they go.
+func (s *state) walk(dot reflect.Value, node parse.Node) {
+	s.at(node)
+	switch node := node.(type) {
+	case *parse.ActionNode:
+		// Do not pop variables so they persist until next end.
+		// Also, if the action declares variables, don't print the result.
+		val := s.evalPipeline(dot, node.Pipe)
+		if len(node.Pipe.Decl) == 0 {
+			s.printValue(node, val)
+		}
+	case *parse.IfNode:
+		s.walkIfOrWith(parse.NodeIf, dot, node.Pipe, node.List, node.ElseList)
+	case *parse.ListNode:
+		for _, node := range node.Nodes {
+			s.walk(dot, node)
+		}
+	case *parse.RangeNode:
+		s.walkRange(dot, node)
+	case *parse.TemplateNode:
+		s.walkTemplate(dot, node)
+	case *parse.TextNode:
+		if _, err := s.wr.Write(node.Text); err != nil {
+			s.errorf("%s", err)
+		}
+	case *parse.WithNode:
+		s.walkIfOrWith(parse.NodeWith, dot, node.Pipe, node.List, node.ElseList)
+	default:
+		s.errorf("unknown node: %s", node)
+	}
+}
+
+// walkIfOrWith walks an 'if' or 'with' node. The two control structures
+// are identical in behavior except that 'with' sets dot.
+func (s *state) walkIfOrWith(typ parse.NodeType, dot reflect.Value, pipe *parse.PipeNode, list, elseList *parse.ListNode) {
+	defer s.pop(s.mark())
+	val := s.evalPipeline(dot, pipe)
+	truth, ok := isTrue(val)
+	if !ok {
+		s.errorf("if/with can't use %v", val)
+	}
+	if truth {
+		if typ == parse.NodeWith {
+			s.walk(val, list)
+		} else {
+			s.walk(dot, list)
+		}
+	} else if elseList != nil {
+		s.walk(dot, elseList)
+	}
+}
+
+// isTrue reports whether the value is 'true', in the sense of not the zero of its type,
+// and whether the value has a meaningful truth value.
+func isTrue(val reflect.Value) (truth, ok bool) {
+	if !val.IsValid() {
+		// Something like var x interface{}, never set. It's a form of nil.
+		return false, true
+	}
+	switch val.Kind() {
+	case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
+		truth = val.Len() > 0
+	case reflect.Bool:
+		truth = val.Bool()
+	case reflect.Complex64, reflect.Complex128:
+		truth = val.Complex() != 0
+	case reflect.Chan, reflect.Func, reflect.Ptr, reflect.Interface:
+		truth = !val.IsNil()
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		truth = val.Int() != 0
+	case reflect.Float32, reflect.Float64:
+		truth = val.Float() != 0
+	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+		truth = val.Uint() != 0
+	case reflect.Struct:
+		truth = true // Struct values are always true.
+	default:
+		return
+	}
+	return truth, true
+}
+
+func (s *state) walkRange(dot reflect.Value, r *parse.RangeNode) {
+	s.at(r)
+	defer s.pop(s.mark())
+	val, _ := indirect(s.evalPipeline(dot, r.Pipe))
+	// mark top of stack before any variables in the body are pushed.
+	mark := s.mark()
+	oneIteration := func(index, elem reflect.Value) {
+		// Set top var (lexically the second if there are two) to the element.
+		if len(r.Pipe.Decl) > 0 {
+			s.setVar(1, elem)
+		}
+		// Set next var (lexically the first if there are two) to the index.
+		if len(r.Pipe.Decl) > 1 {
+			s.setVar(2, index)
+		}
+		s.walk(elem, r.List)
+		s.pop(mark)
+	}
+	switch val.Kind() {
+	case reflect.Array, reflect.Slice:
+		if val.Len() == 0 {
+			break
+		}
+		for i := 0; i < val.Len(); i++ {
+			oneIteration(reflect.ValueOf(i), val.Index(i))
+		}
+		return
+	case reflect.Map:
+		if val.Len() == 0 {
+			break
+		}
+		for _, key := range sortKeys(val.MapKeys()) {
+			oneIteration(key, val.MapIndex(key))
+		}
+		return
+	case reflect.Chan:
+		if val.IsNil() {
+			break
+		}
+		i := 0
+		for ; ; i++ {
+			elem, ok := val.Recv()
+			if !ok {
+				break
+			}
+			oneIteration(reflect.ValueOf(i), elem)
+		}
+		if i == 0 {
+			break
+		}
+		return
+	case reflect.Invalid:
+		break // An invalid value is likely a nil map, etc. and acts like an empty map.
+	default:
+		s.errorf("range can't iterate over %v", val)
+	}
+	if r.ElseList != nil {
+		s.walk(dot, r.ElseList)
+	}
+}
+
+func (s *state) walkTemplate(dot reflect.Value, t *parse.TemplateNode) {
+	s.at(t)
+	tmpl := s.tmpl.tmpl[t.Name]
+	if tmpl == nil {
+		s.errorf("template %q not defined", t.Name)
+	}
+	// Variables declared by the pipeline persist.
+	dot = s.evalPipeline(dot, t.Pipe)
+	newState := *s
+	newState.tmpl = tmpl
+	// No dynamic scoping: template invocations inherit no variables.
+	newState.vars = []variable{{"$", dot}}
+	newState.walk(dot, tmpl.Root)
+}
+
+// Eval functions evaluate pipelines, commands, and their elements and extract
+// values from the data structure by examining fields, calling methods, and so on.
+// The printing of those values happens only through walk functions.
+
+// evalPipeline returns the value acquired by evaluating a pipeline. If the
+// pipeline has a variable declaration, the variable will be pushed on the
+// stack. Callers should therefore pop the stack after they are finished
+// executing commands depending on the pipeline value.
+func (s *state) evalPipeline(dot reflect.Value, pipe *parse.PipeNode) (value reflect.Value) {
+	if pipe == nil {
+		return
+	}
+	s.at(pipe)
+	for _, cmd := range pipe.Cmds {
+		value = s.evalCommand(dot, cmd, value) // previous value is this one's final arg.
+		// If the object has type interface{}, dig down one level to the thing inside.
+		if value.Kind() == reflect.Interface && value.Type().NumMethod() == 0 {
+			value = reflect.ValueOf(value.Interface()) // lovely!
+		}
+	}
+	for _, variable := range pipe.Decl {
+		s.push(variable.Ident[0], value)
+	}
+	return value
+}
+
+func (s *state) notAFunction(args []parse.Node, final reflect.Value) {
+	if len(args) > 1 || final.IsValid() {
+		s.errorf("can't give argument to non-function %s", args[0])
+	}
+}
+
+func (s *state) evalCommand(dot reflect.Value, cmd *parse.CommandNode, final reflect.Value) reflect.Value {
+	firstWord := cmd.Args[0]
+	switch n := firstWord.(type) {
+	case *parse.FieldNode:
+		return s.evalFieldNode(dot, n, cmd.Args, final)
+	case *parse.ChainNode:
+		return s.evalChainNode(dot, n, cmd.Args, final)
+	case *parse.IdentifierNode:
+		// Must be a function.
+		return s.evalFunction(dot, n, cmd, cmd.Args, final)
+	case *parse.PipeNode:
+		// Parenthesized pipeline. The arguments are all inside the pipeline; final is ignored.
+		return s.evalPipeline(dot, n)
+	case *parse.VariableNode:
+		return s.evalVariableNode(dot, n, cmd.Args, final)
+	}
+	s.at(firstWord)
+	s.notAFunction(cmd.Args, final)
+	switch word := firstWord.(type) {
+	case *parse.BoolNode:
+		return reflect.ValueOf(word.True)
+	case *parse.DotNode:
+		return dot
+	case *parse.NilNode:
+		s.errorf("nil is not a command")
+	case *parse.NumberNode:
+		return s.idealConstant(word)
+	case *parse.StringNode:
+		return reflect.ValueOf(word.Text)
+	}
+	s.errorf("can't evaluate command %q", firstWord)
+	panic("not reached")
+}
+
+// idealConstant is called to return the value of a number in a context where
+// we don't know the type. In that case, the syntax of the number tells us
+// its type, and we use Go rules to resolve.  Note there is no such thing as
+// a uint ideal constant in this situation - the value must be of int type.
+func (s *state) idealConstant(constant *parse.NumberNode) reflect.Value {
+	// These are ideal constants but we don't know the type
+	// and we have no context.  (If it was a method argument,
+	// we'd know what we need.) The syntax guides us to some extent.
+	s.at(constant)
+	switch {
+	case constant.IsComplex:
+		return reflect.ValueOf(constant.Complex128) // incontrovertible.
+	case constant.IsFloat && !isHexConstant(constant.Text) && strings.IndexAny(constant.Text, ".eE") >= 0:
+		return reflect.ValueOf(constant.Float64)
+	case constant.IsInt:
+		n := int(constant.Int64)
+		if int64(n) != constant.Int64 {
+			s.errorf("%s overflows int", constant.Text)
+		}
+		return reflect.ValueOf(n)
+	case constant.IsUint:
+		s.errorf("%s overflows int", constant.Text)
+	}
+	return zero
+}
+
+func isHexConstant(s string) bool {
+	return len(s) > 2 && s[0] == '0' && (s[1] == 'x' || s[1] == 'X')
+}
+
+func (s *state) evalFieldNode(dot reflect.Value, field *parse.FieldNode, args []parse.Node, final reflect.Value) reflect.Value {
+	s.at(field)
+	return s.evalFieldChain(dot, dot, field, field.Ident, args, final)
+}
+
+func (s *state) evalChainNode(dot reflect.Value, chain *parse.ChainNode, args []parse.Node, final reflect.Value) reflect.Value {
+	s.at(chain)
+	// (pipe).Field1.Field2 has pipe as .Node, fields as .Field. Eval the pipeline, then the fields.
+	pipe := s.evalArg(dot, nil, chain.Node)
+	if len(chain.Field) == 0 {
+		s.errorf("internal error: no fields in evalChainNode")
+	}
+	return s.evalFieldChain(dot, pipe, chain, chain.Field, args, final)
+}
+
+func (s *state) evalVariableNode(dot reflect.Value, variable *parse.VariableNode, args []parse.Node, final reflect.Value) reflect.Value {
+	// $x.Field has $x as the first ident, Field as the second. Eval the var, then the fields.
+	s.at(variable)
+	value := s.varValue(variable.Ident[0])
+	if len(variable.Ident) == 1 {
+		s.notAFunction(args, final)
+		return value
+	}
+	return s.evalFieldChain(dot, value, variable, variable.Ident[1:], args, final)
+}
+
+// evalFieldChain evaluates .X.Y.Z possibly followed by arguments.
+// dot is the environment in which to evaluate arguments, while
+// receiver is the value being walked along the chain.
+func (s *state) evalFieldChain(dot, receiver reflect.Value, node parse.Node, ident []string, args []parse.Node, final reflect.Value) reflect.Value {
+	n := len(ident)
+	for i := 0; i < n-1; i++ {
+		receiver = s.evalField(dot, ident[i], node, nil, zero, receiver)
+	}
+	// Now if it's a method, it gets the arguments.
+	return s.evalField(dot, ident[n-1], node, args, final, receiver)
+}
+
+func (s *state) evalFunction(dot reflect.Value, node *parse.IdentifierNode, cmd parse.Node, args []parse.Node, final reflect.Value) reflect.Value {
+	s.at(node)
+	name := node.Ident
+	function, ok := findFunction(name, s.tmpl)
+	if !ok {
+		s.errorf("%q is not a defined function", name)
+	}
+	return s.evalCall(dot, function, cmd, name, args, final)
+}
+
+// evalField evaluates an expression like (.Field) or (.Field arg1 arg2).
+// The 'final' argument represents the return value from the preceding
+// value of the pipeline, if any.
+func (s *state) evalField(dot reflect.Value, fieldName string, node parse.Node, args []parse.Node, final, receiver reflect.Value) reflect.Value {
+	if !receiver.IsValid() {
+		return zero
+	}
+	typ := receiver.Type()
+	receiver, _ = indirect(receiver)
+	// Unless it's an interface, need to get to a value of type *T to guarantee
+	// we see all methods of T and *T.
+	ptr := receiver
+	if ptr.Kind() != reflect.Interface && ptr.CanAddr() {
+		ptr = ptr.Addr()
+	}
+	if method := ptr.MethodByName(fieldName); method.IsValid() {
+		return s.evalCall(dot, method, node, fieldName, args, final)
+	}
+	hasArgs := len(args) > 1 || final.IsValid()
+	// It's not a method; must be a field of a struct or an element of a map. The receiver must not be nil.
+	receiver, isNil := indirect(receiver)
+	if isNil {
+		s.errorf("nil pointer evaluating %s.%s", typ, fieldName)
+	}
+	switch receiver.Kind() {
+	case reflect.Struct:
+		tField, ok := receiver.Type().FieldByName(fieldName)
+		if ok {
+			field := receiver.FieldByIndex(tField.Index)
+			if tField.PkgPath != "" { // field is unexported
+				s.errorf("%s is an unexported field of struct type %s", fieldName, typ)
+			}
+			// If it's a function, we must call it.
+			if hasArgs {
+				s.errorf("%s has arguments but cannot be invoked as function", fieldName)
+			}
+			return field
+		}
+		s.errorf("%s is not a field of struct type %s", fieldName, typ)
+	case reflect.Map:
+		// If it's a map, attempt to use the field name as a key.
+		nameVal := reflect.ValueOf(fieldName)
+		if nameVal.Type().AssignableTo(receiver.Type().Key()) {
+			if hasArgs {
+				s.errorf("%s is not a method but has arguments", fieldName)
+			}
+			return receiver.MapIndex(nameVal)
+		}
+	}
+	s.errorf("can't evaluate field %s in type %s", fieldName, typ)
+	panic("not reached")
+}
+
+var (
+	errorType       = reflect.TypeOf((*error)(nil)).Elem()
+	fmtStringerType = reflect.TypeOf((*fmt.Stringer)(nil)).Elem()
+)
+
+// evalCall executes a function or method call. If it's a method, fun already has the receiver bound, so
+// it looks just like a function call.  The arg list, if non-nil, includes (in the manner of the shell), arg[0]
+// as the function itself.
+func (s *state) evalCall(dot, fun reflect.Value, node parse.Node, name string, args []parse.Node, final reflect.Value) reflect.Value {
+	if args != nil {
+		args = args[1:] // Zeroth arg is function name/node; not passed to function.
+	}
+	typ := fun.Type()
+	numIn := len(args)
+	if final.IsValid() {
+		numIn++
+	}
+	numFixed := len(args)
+	if typ.IsVariadic() {
+		numFixed = typ.NumIn() - 1 // last arg is the variadic one.
+		if numIn < numFixed {
+			s.errorf("wrong number of args for %s: want at least %d got %d", name, typ.NumIn()-1, len(args))
+		}
+	} else if numIn < typ.NumIn()-1 || !typ.IsVariadic() && numIn != typ.NumIn() {
+		s.errorf("wrong number of args for %s: want %d got %d", name, typ.NumIn(), len(args))
+	}
+	if !goodFunc(typ) {
+		// TODO: This could still be a confusing error; maybe goodFunc should provide info.
+		s.errorf("can't call method/function %q with %d results", name, typ.NumOut())
+	}
+	// Build the arg list.
+	argv := make([]reflect.Value, numIn)
+	// Args must be evaluated. Fixed args first.
+	i := 0
+	for ; i < numFixed && i < len(args); i++ {
+		argv[i] = s.evalArg(dot, typ.In(i), args[i])
+	}
+	// Now the ... args.
+	if typ.IsVariadic() {
+		argType := typ.In(typ.NumIn() - 1).Elem() // Argument is a slice.
+		for ; i < len(args); i++ {
+			argv[i] = s.evalArg(dot, argType, args[i])
+		}
+	}
+	// Add final value if necessary.
+	if final.IsValid() {
+		t := typ.In(typ.NumIn() - 1)
+		if typ.IsVariadic() {
+			t = t.Elem()
+		}
+		argv[i] = s.validateType(final, t)
+	}
+	result := fun.Call(argv)
+	// If we have an error that is not nil, stop execution and return that error to the caller.
+	if len(result) == 2 && !result[1].IsNil() {
+		s.at(node)
+		s.errorf("error calling %s: %s", name, result[1].Interface().(error))
+	}
+	return result[0]
+}
+
+// canBeNil reports whether an untyped nil can be assigned to the type. See reflect.Zero.
+func canBeNil(typ reflect.Type) bool {
+	switch typ.Kind() {
+	case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
+		return true
+	}
+	return false
+}
+
+// validateType guarantees that the value is valid and assignable to the type.
+func (s *state) validateType(value reflect.Value, typ reflect.Type) reflect.Value {
+	if !value.IsValid() {
+		if typ == nil || canBeNil(typ) {
+			// An untyped nil interface{}. Accept as a proper nil value.
+			return reflect.Zero(typ)
+		}
+		s.errorf("invalid value; expected %s", typ)
+	}
+	if typ != nil && !value.Type().AssignableTo(typ) {
+		if value.Kind() == reflect.Interface && !value.IsNil() {
+			value = value.Elem()
+			if value.Type().AssignableTo(typ) {
+				return value
+			}
+			// fallthrough
+		}
+		// Does one dereference or indirection work? We could do more, as we
+		// do with method receivers, but that gets messy and method receivers
+		// are much more constrained, so it makes more sense there than here.
+		// Besides, one is almost always all you need.
+		switch {
+		case value.Kind() == reflect.Ptr && value.Type().Elem().AssignableTo(typ):
+			value = value.Elem()
+			if !value.IsValid() {
+				s.errorf("dereference of nil pointer of type %s", typ)
+			}
+		case reflect.PtrTo(value.Type()).AssignableTo(typ) && value.CanAddr():
+			value = value.Addr()
+		default:
+			s.errorf("wrong type for value; expected %s; got %s", typ, value.Type())
+		}
+	}
+	return value
+}
+
+func (s *state) evalArg(dot reflect.Value, typ reflect.Type, n parse.Node) reflect.Value {
+	s.at(n)
+	switch arg := n.(type) {
+	case *parse.DotNode:
+		return s.validateType(dot, typ)
+	case *parse.NilNode:
+		if canBeNil(typ) {
+			return reflect.Zero(typ)
+		}
+		s.errorf("cannot assign nil to %s", typ)
+	case *parse.FieldNode:
+		return s.validateType(s.evalFieldNode(dot, arg, []parse.Node{n}, zero), typ)
+	case *parse.VariableNode:
+		return s.validateType(s.evalVariableNode(dot, arg, nil, zero), typ)
+	case *parse.PipeNode:
+		return s.validateType(s.evalPipeline(dot, arg), typ)
+	case *parse.IdentifierNode:
+		return s.evalFunction(dot, arg, arg, nil, zero)
+	case *parse.ChainNode:
+		return s.validateType(s.evalChainNode(dot, arg, nil, zero), typ)
+	}
+	switch typ.Kind() {
+	case reflect.Bool:
+		return s.evalBool(typ, n)
+	case reflect.Complex64, reflect.Complex128:
+		return s.evalComplex(typ, n)
+	case reflect.Float32, reflect.Float64:
+		return s.evalFloat(typ, n)
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		return s.evalInteger(typ, n)
+	case reflect.Interface:
+		if typ.NumMethod() == 0 {
+			return s.evalEmptyInterface(dot, n)
+		}
+	case reflect.String:
+		return s.evalString(typ, n)
+	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+		return s.evalUnsignedInteger(typ, n)
+	}
+	s.errorf("can't handle %s for arg of type %s", n, typ)
+	panic("not reached")
+}
+
+func (s *state) evalBool(typ reflect.Type, n parse.Node) reflect.Value {
+	s.at(n)
+	if n, ok := n.(*parse.BoolNode); ok {
+		value := reflect.New(typ).Elem()
+		value.SetBool(n.True)
+		return value
+	}
+	s.errorf("expected bool; found %s", n)
+	panic("not reached")
+}
+
+func (s *state) evalString(typ reflect.Type, n parse.Node) reflect.Value {
+	s.at(n)
+	if n, ok := n.(*parse.StringNode); ok {
+		value := reflect.New(typ).Elem()
+		value.SetString(n.Text)
+		return value
+	}
+	s.errorf("expected string; found %s", n)
+	panic("not reached")
+}
+
+func (s *state) evalInteger(typ reflect.Type, n parse.Node) reflect.Value {
+	s.at(n)
+	if n, ok := n.(*parse.NumberNode); ok && n.IsInt {
+		value := reflect.New(typ).Elem()
+		value.SetInt(n.Int64)
+		return value
+	}
+	s.errorf("expected integer; found %s", n)
+	panic("not reached")
+}
+
+func (s *state) evalUnsignedInteger(typ reflect.Type, n parse.Node) reflect.Value {
+	s.at(n)
+	if n, ok := n.(*parse.NumberNode); ok && n.IsUint {
+		value := reflect.New(typ).Elem()
+		value.SetUint(n.Uint64)
+		return value
+	}
+	s.errorf("expected unsigned integer; found %s", n)
+	panic("not reached")
+}
+
+func (s *state) evalFloat(typ reflect.Type, n parse.Node) reflect.Value {
+	s.at(n)
+	if n, ok := n.(*parse.NumberNode); ok && n.IsFloat {
+		value := reflect.New(typ).Elem()
+		value.SetFloat(n.Float64)
+		return value
+	}
+	s.errorf("expected float; found %s", n)
+	panic("not reached")
+}
+
+func (s *state) evalComplex(typ reflect.Type, n parse.Node) reflect.Value {
+	if n, ok := n.(*parse.NumberNode); ok && n.IsComplex {
+		value := reflect.New(typ).Elem()
+		value.SetComplex(n.Complex128)
+		return value
+	}
+	s.errorf("expected complex; found %s", n)
+	panic("not reached")
+}
+
+func (s *state) evalEmptyInterface(dot reflect.Value, n parse.Node) reflect.Value {
+	s.at(n)
+	switch n := n.(type) {
+	case *parse.BoolNode:
+		return reflect.ValueOf(n.True)
+	case *parse.DotNode:
+		return dot
+	case *parse.FieldNode:
+		return s.evalFieldNode(dot, n, nil, zero)
+	case *parse.IdentifierNode:
+		return s.evalFunction(dot, n, n, nil, zero)
+	case *parse.NilNode:
+		// NilNode is handled in evalArg, the only place that calls here.
+		s.errorf("evalEmptyInterface: nil (can't happen)")
+	case *parse.NumberNode:
+		return s.idealConstant(n)
+	case *parse.StringNode:
+		return reflect.ValueOf(n.Text)
+	case *parse.VariableNode:
+		return s.evalVariableNode(dot, n, nil, zero)
+	case *parse.PipeNode:
+		return s.evalPipeline(dot, n)
+	}
+	s.errorf("can't handle assignment of %s to empty interface argument", n)
+	panic("not reached")
+}
+
+// indirect returns the item at the end of indirection, and a bool to indicate if it's nil.
+// We indirect through pointers and empty interfaces (only) because
+// non-empty interfaces have methods we might need.
+func indirect(v reflect.Value) (rv reflect.Value, isNil bool) {
+	for ; v.Kind() == reflect.Ptr || v.Kind() == reflect.Interface; v = v.Elem() {
+		if v.IsNil() {
+			return v, true
+		}
+		if v.Kind() == reflect.Interface && v.NumMethod() > 0 {
+			break
+		}
+	}
+	return v, false
+}
+
+// printValue writes the textual representation of the value to the output of
+// the template.
+func (s *state) printValue(n parse.Node, v reflect.Value) {
+	s.at(n)
+	iface, ok := printableValue(v)
+	if !ok {
+		s.errorf("can't print %s of type %s", n, v.Type())
+	}
+	fmt.Fprint(s.wr, iface)
+}
+
+// printableValue returns the, possibly indirected, interface value inside v that
+// is best for a call to formatted printer.
+func printableValue(v reflect.Value) (interface{}, bool) {
+	if v.Kind() == reflect.Ptr {
+		v, _ = indirect(v) // fmt.Fprint handles nil.
+	}
+	if !v.IsValid() {
+		return "<no value>", true
+	}
+
+	if !v.Type().Implements(errorType) && !v.Type().Implements(fmtStringerType) {
+		if v.CanAddr() && (reflect.PtrTo(v.Type()).Implements(errorType) || reflect.PtrTo(v.Type()).Implements(fmtStringerType)) {
+			v = v.Addr()
+		} else {
+			switch v.Kind() {
+			case reflect.Chan, reflect.Func:
+				return nil, false
+			}
+		}
+	}
+	return v.Interface(), true
+}
+
+// Types to help sort the keys in a map for reproducible output.
+
+type rvs []reflect.Value
+
+func (x rvs) Len() int      { return len(x) }
+func (x rvs) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
+
+type rvInts struct{ rvs }
+
+func (x rvInts) Less(i, j int) bool { return x.rvs[i].Int() < x.rvs[j].Int() }
+
+type rvUints struct{ rvs }
+
+func (x rvUints) Less(i, j int) bool { return x.rvs[i].Uint() < x.rvs[j].Uint() }
+
+type rvFloats struct{ rvs }
+
+func (x rvFloats) Less(i, j int) bool { return x.rvs[i].Float() < x.rvs[j].Float() }
+
+type rvStrings struct{ rvs }
+
+func (x rvStrings) Less(i, j int) bool { return x.rvs[i].String() < x.rvs[j].String() }
+
+// sortKeys sorts (if it can) the slice of reflect.Values, which is a slice of map keys.
+func sortKeys(v []reflect.Value) []reflect.Value {
+	if len(v) <= 1 {
+		return v
+	}
+	switch v[0].Kind() {
+	case reflect.Float32, reflect.Float64:
+		sort.Sort(rvFloats{v})
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		sort.Sort(rvInts{v})
+	case reflect.String:
+		sort.Sort(rvStrings{v})
+	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+		sort.Sort(rvUints{v})
+	}
+	return v
+}
diff --git a/src/text/template/exec_test.go b/src/text/template/exec_test.go
new file mode 100644
index 0000000..69c213e
--- /dev/null
+++ b/src/text/template/exec_test.go
@@ -0,0 +1,1044 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package template
+
+import (
+	"bytes"
+	"errors"
+	"flag"
+	"fmt"
+	"reflect"
+	"strings"
+	"testing"
+)
+
+var debug = flag.Bool("debug", false, "show the errors produced by the tests")
+
+// T has lots of interesting pieces to use to test execution.
+type T struct {
+	// Basics
+	True        bool
+	I           int
+	U16         uint16
+	X           string
+	FloatZero   float64
+	ComplexZero complex128
+	// Nested structs.
+	U *U
+	// Struct with String method.
+	V0     V
+	V1, V2 *V
+	// Struct with Error method.
+	W0     W
+	W1, W2 *W
+	// Slices
+	SI      []int
+	SIEmpty []int
+	SB      []bool
+	// Maps
+	MSI      map[string]int
+	MSIone   map[string]int // one element, for deterministic output
+	MSIEmpty map[string]int
+	MXI      map[interface{}]int
+	MII      map[int]int
+	SMSI     []map[string]int
+	// Empty interfaces; used to see if we can dig inside one.
+	Empty0 interface{} // nil
+	Empty1 interface{}
+	Empty2 interface{}
+	Empty3 interface{}
+	Empty4 interface{}
+	// Non-empty interface.
+	NonEmptyInterface I
+	// Stringer.
+	Str fmt.Stringer
+	Err error
+	// Pointers
+	PI  *int
+	PS  *string
+	PSI *[]int
+	NIL *int
+	// Function (not method)
+	BinaryFunc      func(string, string) string
+	VariadicFunc    func(...string) string
+	VariadicFuncInt func(int, ...string) string
+	NilOKFunc       func(*int) bool
+	ErrFunc         func() (string, error)
+	// Template to test evaluation of templates.
+	Tmpl *Template
+	// Unexported field; cannot be accessed by template.
+	unexported int
+}
+
+type U struct {
+	V string
+}
+
+type V struct {
+	j int
+}
+
+func (v *V) String() string {
+	if v == nil {
+		return "nilV"
+	}
+	return fmt.Sprintf("<%d>", v.j)
+}
+
+type W struct {
+	k int
+}
+
+func (w *W) Error() string {
+	if w == nil {
+		return "nilW"
+	}
+	return fmt.Sprintf("[%d]", w.k)
+}
+
+var tVal = &T{
+	True:   true,
+	I:      17,
+	U16:    16,
+	X:      "x",
+	U:      &U{"v"},
+	V0:     V{6666},
+	V1:     &V{7777}, // leave V2 as nil
+	W0:     W{888},
+	W1:     &W{999}, // leave W2 as nil
+	SI:     []int{3, 4, 5},
+	SB:     []bool{true, false},
+	MSI:    map[string]int{"one": 1, "two": 2, "three": 3},
+	MSIone: map[string]int{"one": 1},
+	MXI:    map[interface{}]int{"one": 1},
+	MII:    map[int]int{1: 1},
+	SMSI: []map[string]int{
+		{"one": 1, "two": 2},
+		{"eleven": 11, "twelve": 12},
+	},
+	Empty1:            3,
+	Empty2:            "empty2",
+	Empty3:            []int{7, 8},
+	Empty4:            &U{"UinEmpty"},
+	NonEmptyInterface: new(T),
+	Str:               bytes.NewBuffer([]byte("foozle")),
+	Err:               errors.New("erroozle"),
+	PI:                newInt(23),
+	PS:                newString("a string"),
+	PSI:               newIntSlice(21, 22, 23),
+	BinaryFunc:        func(a, b string) string { return fmt.Sprintf("[%s=%s]", a, b) },
+	VariadicFunc:      func(s ...string) string { return fmt.Sprint("<", strings.Join(s, "+"), ">") },
+	VariadicFuncInt:   func(a int, s ...string) string { return fmt.Sprint(a, "=<", strings.Join(s, "+"), ">") },
+	NilOKFunc:         func(s *int) bool { return s == nil },
+	ErrFunc:           func() (string, error) { return "bla", nil },
+	Tmpl:              Must(New("x").Parse("test template")), // "x" is the value of .X
+}
+
+// A non-empty interface.
+type I interface {
+	Method0() string
+}
+
+var iVal I = tVal
+
+// Helpers for creation.
+func newInt(n int) *int {
+	return &n
+}
+
+func newString(s string) *string {
+	return &s
+}
+
+func newIntSlice(n ...int) *[]int {
+	p := new([]int)
+	*p = make([]int, len(n))
+	copy(*p, n)
+	return p
+}
+
+// Simple methods with and without arguments.
+func (t *T) Method0() string {
+	return "M0"
+}
+
+func (t *T) Method1(a int) int {
+	return a
+}
+
+func (t *T) Method2(a uint16, b string) string {
+	return fmt.Sprintf("Method2: %d %s", a, b)
+}
+
+func (t *T) Method3(v interface{}) string {
+	return fmt.Sprintf("Method3: %v", v)
+}
+
+func (t *T) Copy() *T {
+	n := new(T)
+	*n = *t
+	return n
+}
+
+func (t *T) MAdd(a int, b []int) []int {
+	v := make([]int, len(b))
+	for i, x := range b {
+		v[i] = x + a
+	}
+	return v
+}
+
+var myError = errors.New("my error")
+
+// MyError returns a value and an error according to its argument.
+func (t *T) MyError(error bool) (bool, error) {
+	if error {
+		return true, myError
+	}
+	return false, nil
+}
+
+// A few methods to test chaining.
+func (t *T) GetU() *U {
+	return t.U
+}
+
+func (u *U) TrueFalse(b bool) string {
+	if b {
+		return "true"
+	}
+	return ""
+}
+
+func typeOf(arg interface{}) string {
+	return fmt.Sprintf("%T", arg)
+}
+
+type execTest struct {
+	name   string
+	input  string
+	output string
+	data   interface{}
+	ok     bool
+}
+
+// bigInt and bigUint are hex string representing numbers either side
+// of the max int boundary.
+// We do it this way so the test doesn't depend on ints being 32 bits.
+var (
+	bigInt  = fmt.Sprintf("0x%x", int(1<<uint(reflect.TypeOf(0).Bits()-1)-1))
+	bigUint = fmt.Sprintf("0x%x", uint(1<<uint(reflect.TypeOf(0).Bits()-1)))
+)
+
+var execTests = []execTest{
+	// Trivial cases.
+	{"empty", "", "", nil, true},
+	{"text", "some text", "some text", nil, true},
+	{"nil action", "{{nil}}", "", nil, false},
+
+	// Ideal constants.
+	{"ideal int", "{{typeOf 3}}", "int", 0, true},
+	{"ideal float", "{{typeOf 1.0}}", "float64", 0, true},
+	{"ideal exp float", "{{typeOf 1e1}}", "float64", 0, true},
+	{"ideal complex", "{{typeOf 1i}}", "complex128", 0, true},
+	{"ideal int", "{{typeOf " + bigInt + "}}", "int", 0, true},
+	{"ideal too big", "{{typeOf " + bigUint + "}}", "", 0, false},
+	{"ideal nil without type", "{{nil}}", "", 0, false},
+
+	// Fields of structs.
+	{".X", "-{{.X}}-", "-x-", tVal, true},
+	{".U.V", "-{{.U.V}}-", "-v-", tVal, true},
+	{".unexported", "{{.unexported}}", "", tVal, false},
+
+	// Fields on maps.
+	{"map .one", "{{.MSI.one}}", "1", tVal, true},
+	{"map .two", "{{.MSI.two}}", "2", tVal, true},
+	{"map .NO", "{{.MSI.NO}}", "<no value>", tVal, true},
+	{"map .one interface", "{{.MXI.one}}", "1", tVal, true},
+	{"map .WRONG args", "{{.MSI.one 1}}", "", tVal, false},
+	{"map .WRONG type", "{{.MII.one}}", "", tVal, false},
+
+	// Dots of all kinds to test basic evaluation.
+	{"dot int", "<{{.}}>", "<13>", 13, true},
+	{"dot uint", "<{{.}}>", "<14>", uint(14), true},
+	{"dot float", "<{{.}}>", "<15.1>", 15.1, true},
+	{"dot bool", "<{{.}}>", "<true>", true, true},
+	{"dot complex", "<{{.}}>", "<(16.2-17i)>", 16.2 - 17i, true},
+	{"dot string", "<{{.}}>", "<hello>", "hello", true},
+	{"dot slice", "<{{.}}>", "<[-1 -2 -3]>", []int{-1, -2, -3}, true},
+	{"dot map", "<{{.}}>", "<map[two:22]>", map[string]int{"two": 22}, true},
+	{"dot struct", "<{{.}}>", "<{7 seven}>", struct {
+		a int
+		b string
+	}{7, "seven"}, true},
+
+	// Variables.
+	{"$ int", "{{$}}", "123", 123, true},
+	{"$.I", "{{$.I}}", "17", tVal, true},
+	{"$.U.V", "{{$.U.V}}", "v", tVal, true},
+	{"declare in action", "{{$x := $.U.V}}{{$x}}", "v", tVal, true},
+
+	// Type with String method.
+	{"V{6666}.String()", "-{{.V0}}-", "-<6666>-", tVal, true},
+	{"&V{7777}.String()", "-{{.V1}}-", "-<7777>-", tVal, true},
+	{"(*V)(nil).String()", "-{{.V2}}-", "-nilV-", tVal, true},
+
+	// Type with Error method.
+	{"W{888}.Error()", "-{{.W0}}-", "-[888]-", tVal, true},
+	{"&W{999}.Error()", "-{{.W1}}-", "-[999]-", tVal, true},
+	{"(*W)(nil).Error()", "-{{.W2}}-", "-nilW-", tVal, true},
+
+	// Pointers.
+	{"*int", "{{.PI}}", "23", tVal, true},
+	{"*string", "{{.PS}}", "a string", tVal, true},
+	{"*[]int", "{{.PSI}}", "[21 22 23]", tVal, true},
+	{"*[]int[1]", "{{index .PSI 1}}", "22", tVal, true},
+	{"NIL", "{{.NIL}}", "<nil>", tVal, true},
+
+	// Empty interfaces holding values.
+	{"empty nil", "{{.Empty0}}", "<no value>", tVal, true},
+	{"empty with int", "{{.Empty1}}", "3", tVal, true},
+	{"empty with string", "{{.Empty2}}", "empty2", tVal, true},
+	{"empty with slice", "{{.Empty3}}", "[7 8]", tVal, true},
+	{"empty with struct", "{{.Empty4}}", "{UinEmpty}", tVal, true},
+	{"empty with struct, field", "{{.Empty4.V}}", "UinEmpty", tVal, true},
+
+	// Method calls.
+	{".Method0", "-{{.Method0}}-", "-M0-", tVal, true},
+	{".Method1(1234)", "-{{.Method1 1234}}-", "-1234-", tVal, true},
+	{".Method1(.I)", "-{{.Method1 .I}}-", "-17-", tVal, true},
+	{".Method2(3, .X)", "-{{.Method2 3 .X}}-", "-Method2: 3 x-", tVal, true},
+	{".Method2(.U16, `str`)", "-{{.Method2 .U16 `str`}}-", "-Method2: 16 str-", tVal, true},
+	{".Method2(.U16, $x)", "{{if $x := .X}}-{{.Method2 .U16 $x}}{{end}}-", "-Method2: 16 x-", tVal, true},
+	{".Method3(nil constant)", "-{{.Method3 nil}}-", "-Method3: <nil>-", tVal, true},
+	{".Method3(nil value)", "-{{.Method3 .MXI.unset}}-", "-Method3: <nil>-", tVal, true},
+	{"method on var", "{{if $x := .}}-{{$x.Method2 .U16 $x.X}}{{end}}-", "-Method2: 16 x-", tVal, true},
+	{"method on chained var",
+		"{{range .MSIone}}{{if $.U.TrueFalse $.True}}{{$.U.TrueFalse $.True}}{{else}}WRONG{{end}}{{end}}",
+		"true", tVal, true},
+	{"chained method",
+		"{{range .MSIone}}{{if $.GetU.TrueFalse $.True}}{{$.U.TrueFalse $.True}}{{else}}WRONG{{end}}{{end}}",
+		"true", tVal, true},
+	{"chained method on variable",
+		"{{with $x := .}}{{with .SI}}{{$.GetU.TrueFalse $.True}}{{end}}{{end}}",
+		"true", tVal, true},
+	{".NilOKFunc not nil", "{{call .NilOKFunc .PI}}", "false", tVal, true},
+	{".NilOKFunc nil", "{{call .NilOKFunc nil}}", "true", tVal, true},
+
+	// Function call builtin.
+	{".BinaryFunc", "{{call .BinaryFunc `1` `2`}}", "[1=2]", tVal, true},
+	{".VariadicFunc0", "{{call .VariadicFunc}}", "<>", tVal, true},
+	{".VariadicFunc2", "{{call .VariadicFunc `he` `llo`}}", "<he+llo>", tVal, true},
+	{".VariadicFuncInt", "{{call .VariadicFuncInt 33 `he` `llo`}}", "33=<he+llo>", tVal, true},
+	{"if .BinaryFunc call", "{{ if .BinaryFunc}}{{call .BinaryFunc `1` `2`}}{{end}}", "[1=2]", tVal, true},
+	{"if not .BinaryFunc call", "{{ if not .BinaryFunc}}{{call .BinaryFunc `1` `2`}}{{else}}No{{end}}", "No", tVal, true},
+	{"Interface Call", `{{stringer .S}}`, "foozle", map[string]interface{}{"S": bytes.NewBufferString("foozle")}, true},
+	{".ErrFunc", "{{call .ErrFunc}}", "bla", tVal, true},
+
+	// Erroneous function calls (check args).
+	{".BinaryFuncTooFew", "{{call .BinaryFunc `1`}}", "", tVal, false},
+	{".BinaryFuncTooMany", "{{call .BinaryFunc `1` `2` `3`}}", "", tVal, false},
+	{".BinaryFuncBad0", "{{call .BinaryFunc 1 3}}", "", tVal, false},
+	{".BinaryFuncBad1", "{{call .BinaryFunc `1` 3}}", "", tVal, false},
+	{".VariadicFuncBad0", "{{call .VariadicFunc 3}}", "", tVal, false},
+	{".VariadicFuncIntBad0", "{{call .VariadicFuncInt}}", "", tVal, false},
+	{".VariadicFuncIntBad`", "{{call .VariadicFuncInt `x`}}", "", tVal, false},
+	{".VariadicFuncNilBad", "{{call .VariadicFunc nil}}", "", tVal, false},
+
+	// Pipelines.
+	{"pipeline", "-{{.Method0 | .Method2 .U16}}-", "-Method2: 16 M0-", tVal, true},
+	{"pipeline func", "-{{call .VariadicFunc `llo` | call .VariadicFunc `he` }}-", "-<he+<llo>>-", tVal, true},
+
+	// Parenthesized expressions
+	{"parens in pipeline", "{{printf `%d %d %d` (1) (2 | add 3) (add 4 (add 5 6))}}", "1 5 15", tVal, true},
+
+	// Parenthesized expressions with field accesses
+	{"parens: $ in paren", "{{($).X}}", "x", tVal, true},
+	{"parens: $.GetU in paren", "{{($.GetU).V}}", "v", tVal, true},
+	{"parens: $ in paren in pipe", "{{($ | echo).X}}", "x", tVal, true},
+	{"parens: spaces and args", `{{(makemap "up" "down" "left" "right").left}}`, "right", tVal, true},
+
+	// If.
+	{"if true", "{{if true}}TRUE{{end}}", "TRUE", tVal, true},
+	{"if false", "{{if false}}TRUE{{else}}FALSE{{end}}", "FALSE", tVal, true},
+	{"if nil", "{{if nil}}TRUE{{end}}", "", tVal, false},
+	{"if 1", "{{if 1}}NON-ZERO{{else}}ZERO{{end}}", "NON-ZERO", tVal, true},
+	{"if 0", "{{if 0}}NON-ZERO{{else}}ZERO{{end}}", "ZERO", tVal, true},
+	{"if 1.5", "{{if 1.5}}NON-ZERO{{else}}ZERO{{end}}", "NON-ZERO", tVal, true},
+	{"if 0.0", "{{if .FloatZero}}NON-ZERO{{else}}ZERO{{end}}", "ZERO", tVal, true},
+	{"if 1.5i", "{{if 1.5i}}NON-ZERO{{else}}ZERO{{end}}", "NON-ZERO", tVal, true},
+	{"if 0.0i", "{{if .ComplexZero}}NON-ZERO{{else}}ZERO{{end}}", "ZERO", tVal, true},
+	{"if emptystring", "{{if ``}}NON-EMPTY{{else}}EMPTY{{end}}", "EMPTY", tVal, true},
+	{"if string", "{{if `notempty`}}NON-EMPTY{{else}}EMPTY{{end}}", "NON-EMPTY", tVal, true},
+	{"if emptyslice", "{{if .SIEmpty}}NON-EMPTY{{else}}EMPTY{{end}}", "EMPTY", tVal, true},
+	{"if slice", "{{if .SI}}NON-EMPTY{{else}}EMPTY{{end}}", "NON-EMPTY", tVal, true},
+	{"if emptymap", "{{if .MSIEmpty}}NON-EMPTY{{else}}EMPTY{{end}}", "EMPTY", tVal, true},
+	{"if map", "{{if .MSI}}NON-EMPTY{{else}}EMPTY{{end}}", "NON-EMPTY", tVal, true},
+	{"if map unset", "{{if .MXI.none}}NON-ZERO{{else}}ZERO{{end}}", "ZERO", tVal, true},
+	{"if map not unset", "{{if not .MXI.none}}ZERO{{else}}NON-ZERO{{end}}", "ZERO", tVal, true},
+	{"if $x with $y int", "{{if $x := true}}{{with $y := .I}}{{$x}},{{$y}}{{end}}{{end}}", "true,17", tVal, true},
+	{"if $x with $x int", "{{if $x := true}}{{with $x := .I}}{{$x}},{{end}}{{$x}}{{end}}", "17,true", tVal, true},
+	{"if else if", "{{if false}}FALSE{{else if true}}TRUE{{end}}", "TRUE", tVal, true},
+	{"if else chain", "{{if eq 1 3}}1{{else if eq 2 3}}2{{else if eq 3 3}}3{{end}}", "3", tVal, true},
+
+	// Print etc.
+	{"print", `{{print "hello, print"}}`, "hello, print", tVal, true},
+	{"print 123", `{{print 1 2 3}}`, "1 2 3", tVal, true},
+	{"print nil", `{{print nil}}`, "<nil>", tVal, true},
+	{"println", `{{println 1 2 3}}`, "1 2 3\n", tVal, true},
+	{"printf int", `{{printf "%04x" 127}}`, "007f", tVal, true},
+	{"printf float", `{{printf "%g" 3.5}}`, "3.5", tVal, true},
+	{"printf complex", `{{printf "%g" 1+7i}}`, "(1+7i)", tVal, true},
+	{"printf string", `{{printf "%s" "hello"}}`, "hello", tVal, true},
+	{"printf function", `{{printf "%#q" zeroArgs}}`, "`zeroArgs`", tVal, true},
+	{"printf field", `{{printf "%s" .U.V}}`, "v", tVal, true},
+	{"printf method", `{{printf "%s" .Method0}}`, "M0", tVal, true},
+	{"printf dot", `{{with .I}}{{printf "%d" .}}{{end}}`, "17", tVal, true},
+	{"printf var", `{{with $x := .I}}{{printf "%d" $x}}{{end}}`, "17", tVal, true},
+	{"printf lots", `{{printf "%d %s %g %s" 127 "hello" 7-3i .Method0}}`, "127 hello (7-3i) M0", tVal, true},
+
+	// HTML.
+	{"html", `{{html "<script>alert(\"XSS\");</script>"}}`,
+		"<script>alert("XSS");</script>", nil, true},
+	{"html pipeline", `{{printf "<script>alert(\"XSS\");</script>" | html}}`,
+		"<script>alert("XSS");</script>", nil, true},
+	{"html", `{{html .PS}}`, "a string", tVal, true},
+
+	// JavaScript.
+	{"js", `{{js .}}`, `It\'d be nice.`, `It'd be nice.`, true},
+
+	// URL query.
+	{"urlquery", `{{"http://www.example.org/"|urlquery}}`, "http%3A%2F%2Fwww.example.org%2F", nil, true},
+
+	// Booleans
+	{"not", "{{not true}} {{not false}}", "false true", nil, true},
+	{"and", "{{and false 0}} {{and 1 0}} {{and 0 true}} {{and 1 1}}", "false 0 0 1", nil, true},
+	{"or", "{{or 0 0}} {{or 1 0}} {{or 0 true}} {{or 1 1}}", "0 1 true 1", nil, true},
+	{"boolean if", "{{if and true 1 `hi`}}TRUE{{else}}FALSE{{end}}", "TRUE", tVal, true},
+	{"boolean if not", "{{if and true 1 `hi` | not}}TRUE{{else}}FALSE{{end}}", "FALSE", nil, true},
+
+	// Indexing.
+	{"slice[0]", "{{index .SI 0}}", "3", tVal, true},
+	{"slice[1]", "{{index .SI 1}}", "4", tVal, true},
+	{"slice[HUGE]", "{{index .SI 10}}", "", tVal, false},
+	{"slice[WRONG]", "{{index .SI `hello`}}", "", tVal, false},
+	{"map[one]", "{{index .MSI `one`}}", "1", tVal, true},
+	{"map[two]", "{{index .MSI `two`}}", "2", tVal, true},
+	{"map[NO]", "{{index .MSI `XXX`}}", "0", tVal, true},
+	{"map[nil]", "{{index .MSI nil}}", "0", tVal, true},
+	{"map[WRONG]", "{{index .MSI 10}}", "", tVal, false},
+	{"double index", "{{index .SMSI 1 `eleven`}}", "11", tVal, true},
+
+	// Len.
+	{"slice", "{{len .SI}}", "3", tVal, true},
+	{"map", "{{len .MSI }}", "3", tVal, true},
+	{"len of int", "{{len 3}}", "", tVal, false},
+	{"len of nothing", "{{len .Empty0}}", "", tVal, false},
+
+	// With.
+	{"with true", "{{with true}}{{.}}{{end}}", "true", tVal, true},
+	{"with false", "{{with false}}{{.}}{{else}}FALSE{{end}}", "FALSE", tVal, true},
+	{"with 1", "{{with 1}}{{.}}{{else}}ZERO{{end}}", "1", tVal, true},
+	{"with 0", "{{with 0}}{{.}}{{else}}ZERO{{end}}", "ZERO", tVal, true},
+	{"with 1.5", "{{with 1.5}}{{.}}{{else}}ZERO{{end}}", "1.5", tVal, true},
+	{"with 0.0", "{{with .FloatZero}}{{.}}{{else}}ZERO{{end}}", "ZERO", tVal, true},
+	{"with 1.5i", "{{with 1.5i}}{{.}}{{else}}ZERO{{end}}", "(0+1.5i)", tVal, true},
+	{"with 0.0i", "{{with .ComplexZero}}{{.}}{{else}}ZERO{{end}}", "ZERO", tVal, true},
+	{"with emptystring", "{{with ``}}{{.}}{{else}}EMPTY{{end}}", "EMPTY", tVal, true},
+	{"with string", "{{with `notempty`}}{{.}}{{else}}EMPTY{{end}}", "notempty", tVal, true},
+	{"with emptyslice", "{{with .SIEmpty}}{{.}}{{else}}EMPTY{{end}}", "EMPTY", tVal, true},
+	{"with slice", "{{with .SI}}{{.}}{{else}}EMPTY{{end}}", "[3 4 5]", tVal, true},
+	{"with emptymap", "{{with .MSIEmpty}}{{.}}{{else}}EMPTY{{end}}", "EMPTY", tVal, true},
+	{"with map", "{{with .MSIone}}{{.}}{{else}}EMPTY{{end}}", "map[one:1]", tVal, true},
+	{"with empty interface, struct field", "{{with .Empty4}}{{.V}}{{end}}", "UinEmpty", tVal, true},
+	{"with $x int", "{{with $x := .I}}{{$x}}{{end}}", "17", tVal, true},
+	{"with $x struct.U.V", "{{with $x := $}}{{$x.U.V}}{{end}}", "v", tVal, true},
+	{"with variable and action", "{{with $x := $}}{{$y := $.U.V}}{{$y}}{{end}}", "v", tVal, true},
+
+	// Range.
+	{"range []int", "{{range .SI}}-{{.}}-{{end}}", "-3--4--5-", tVal, true},
+	{"range empty no else", "{{range .SIEmpty}}-{{.}}-{{end}}", "", tVal, true},
+	{"range []int else", "{{range .SI}}-{{.}}-{{else}}EMPTY{{end}}", "-3--4--5-", tVal, true},
+	{"range empty else", "{{range .SIEmpty}}-{{.}}-{{else}}EMPTY{{end}}", "EMPTY", tVal, true},
+	{"range []bool", "{{range .SB}}-{{.}}-{{end}}", "-true--false-", tVal, true},
+	{"range []int method", "{{range .SI | .MAdd .I}}-{{.}}-{{end}}", "-20--21--22-", tVal, true},
+	{"range map", "{{range .MSI}}-{{.}}-{{end}}", "-1--3--2-", tVal, true},
+	{"range empty map no else", "{{range .MSIEmpty}}-{{.}}-{{end}}", "", tVal, true},
+	{"range map else", "{{range .MSI}}-{{.}}-{{else}}EMPTY{{end}}", "-1--3--2-", tVal, true},
+	{"range empty map else", "{{range .MSIEmpty}}-{{.}}-{{else}}EMPTY{{end}}", "EMPTY", tVal, true},
+	{"range empty interface", "{{range .Empty3}}-{{.}}-{{else}}EMPTY{{end}}", "-7--8-", tVal, true},
+	{"range empty nil", "{{range .Empty0}}-{{.}}-{{end}}", "", tVal, true},
+	{"range $x SI", "{{range $x := .SI}}<{{$x}}>{{end}}", "<3><4><5>", tVal, true},
+	{"range $x $y SI", "{{range $x, $y := .SI}}<{{$x}}={{$y}}>{{end}}", "<0=3><1=4><2=5>", tVal, true},
+	{"range $x MSIone", "{{range $x := .MSIone}}<{{$x}}>{{end}}", "<1>", tVal, true},
+	{"range $x $y MSIone", "{{range $x, $y := .MSIone}}<{{$x}}={{$y}}>{{end}}", "<one=1>", tVal, true},
+	{"range $x PSI", "{{range $x := .PSI}}<{{$x}}>{{end}}", "<21><22><23>", tVal, true},
+	{"declare in range", "{{range $x := .PSI}}<{{$foo:=$x}}{{$x}}>{{end}}", "<21><22><23>", tVal, true},
+	{"range count", `{{range $i, $x := count 5}}[{{$i}}]{{$x}}{{end}}`, "[0]a[1]b[2]c[3]d[4]e", tVal, true},
+	{"range nil count", `{{range $i, $x := count 0}}{{else}}empty{{end}}`, "empty", tVal, true},
+
+	// Cute examples.
+	{"or as if true", `{{or .SI "slice is empty"}}`, "[3 4 5]", tVal, true},
+	{"or as if false", `{{or .SIEmpty "slice is empty"}}`, "slice is empty", tVal, true},
+
+	// Error handling.
+	{"error method, error", "{{.MyError true}}", "", tVal, false},
+	{"error method, no error", "{{.MyError false}}", "false", tVal, true},
+
+	// Fixed bugs.
+	// Must separate dot and receiver; otherwise args are evaluated with dot set to variable.
+	{"bug0", "{{range .MSIone}}{{if $.Method1 .}}X{{end}}{{end}}", "X", tVal, true},
+	// Do not loop endlessly in indirect for non-empty interfaces.
+	// The bug appears with *interface only; looped forever.
+	{"bug1", "{{.Method0}}", "M0", &iVal, true},
+	// Was taking address of interface field, so method set was empty.
+	{"bug2", "{{$.NonEmptyInterface.Method0}}", "M0", tVal, true},
+	// Struct values were not legal in with - mere oversight.
+	{"bug3", "{{with $}}{{.Method0}}{{end}}", "M0", tVal, true},
+	// Nil interface values in if.
+	{"bug4", "{{if .Empty0}}non-nil{{else}}nil{{end}}", "nil", tVal, true},
+	// Stringer.
+	{"bug5", "{{.Str}}", "foozle", tVal, true},
+	{"bug5a", "{{.Err}}", "erroozle", tVal, true},
+	// Args need to be indirected and dereferenced sometimes.
+	{"bug6a", "{{vfunc .V0 .V1}}", "vfunc", tVal, true},
+	{"bug6b", "{{vfunc .V0 .V0}}", "vfunc", tVal, true},
+	{"bug6c", "{{vfunc .V1 .V0}}", "vfunc", tVal, true},
+	{"bug6d", "{{vfunc .V1 .V1}}", "vfunc", tVal, true},
+	// Legal parse but illegal execution: non-function should have no arguments.
+	{"bug7a", "{{3 2}}", "", tVal, false},
+	{"bug7b", "{{$x := 1}}{{$x 2}}", "", tVal, false},
+	{"bug7c", "{{$x := 1}}{{3 | $x}}", "", tVal, false},
+	// Pipelined arg was not being type-checked.
+	{"bug8a", "{{3|oneArg}}", "", tVal, false},
+	{"bug8b", "{{4|dddArg 3}}", "", tVal, false},
+	// A bug was introduced that broke map lookups for lower-case names.
+	{"bug9", "{{.cause}}", "neglect", map[string]string{"cause": "neglect"}, true},
+	// Field chain starting with function did not work.
+	{"bug10", "{{mapOfThree.three}}-{{(mapOfThree).three}}", "3-3", 0, true},
+	// Dereferencing nil pointer while evaluating function arguments should not panic. Issue 7333.
+	{"bug11", "{{valueString .PS}}", "", T{}, false},
+	// 0xef gave constant type float64. Issue 8622.
+	{"bug12xe", "{{printf `%T` 0xef}}", "int", T{}, true},
+	{"bug12xE", "{{printf `%T` 0xEE}}", "int", T{}, true},
+	{"bug12Xe", "{{printf `%T` 0Xef}}", "int", T{}, true},
+	{"bug12XE", "{{printf `%T` 0XEE}}", "int", T{}, true},
+	// Chained nodes did not work as arguments. Issue 8473.
+	{"bug13", "{{print (.Copy).I}}", "17", tVal, true},
+}
+
+func zeroArgs() string {
+	return "zeroArgs"
+}
+
+func oneArg(a string) string {
+	return "oneArg=" + a
+}
+
+func dddArg(a int, b ...string) string {
+	return fmt.Sprintln(a, b)
+}
+
+// count returns a channel that will deliver n sequential 1-letter strings starting at "a"
+func count(n int) chan string {
+	if n == 0 {
+		return nil
+	}
+	c := make(chan string)
+	go func() {
+		for i := 0; i < n; i++ {
+			c <- "abcdefghijklmnop"[i : i+1]
+		}
+		close(c)
+	}()
+	return c
+}
+
+// vfunc takes a *V and a V
+func vfunc(V, *V) string {
+	return "vfunc"
+}
+
+// valueString takes a string, not a pointer.
+func valueString(v string) string {
+	return "value is ignored"
+}
+
+func add(args ...int) int {
+	sum := 0
+	for _, x := range args {
+		sum += x
+	}
+	return sum
+}
+
+func echo(arg interface{}) interface{} {
+	return arg
+}
+
+func makemap(arg ...string) map[string]string {
+	if len(arg)%2 != 0 {
+		panic("bad makemap")
+	}
+	m := make(map[string]string)
+	for i := 0; i < len(arg); i += 2 {
+		m[arg[i]] = arg[i+1]
+	}
+	return m
+}
+
+func stringer(s fmt.Stringer) string {
+	return s.String()
+}
+
+func mapOfThree() interface{} {
+	return map[string]int{"three": 3}
+}
+
+func testExecute(execTests []execTest, template *Template, t *testing.T) {
+	b := new(bytes.Buffer)
+	funcs := FuncMap{
+		"add":         add,
+		"count":       count,
+		"dddArg":      dddArg,
+		"echo":        echo,
+		"makemap":     makemap,
+		"mapOfThree":  mapOfThree,
+		"oneArg":      oneArg,
+		"stringer":    stringer,
+		"typeOf":      typeOf,
+		"valueString": valueString,
+		"vfunc":       vfunc,
+		"zeroArgs":    zeroArgs,
+	}
+	for _, test := range execTests {
+		var tmpl *Template
+		var err error
+		if template == nil {
+			tmpl, err = New(test.name).Funcs(funcs).Parse(test.input)
+		} else {
+			tmpl, err = template.New(test.name).Funcs(funcs).Parse(test.input)
+		}
+		if err != nil {
+			t.Errorf("%s: parse error: %s", test.name, err)
+			continue
+		}
+		b.Reset()
+		err = tmpl.Execute(b, test.data)
+		switch {
+		case !test.ok && err == nil:
+			t.Errorf("%s: expected error; got none", test.name)
+			continue
+		case test.ok && err != nil:
+			t.Errorf("%s: unexpected execute error: %s", test.name, err)
+			continue
+		case !test.ok && err != nil:
+			// expected error, got one
+			if *debug {
+				fmt.Printf("%s: %s\n\t%s\n", test.name, test.input, err)
+			}
+		}
+		result := b.String()
+		if result != test.output {
+			t.Errorf("%s: expected\n\t%q\ngot\n\t%q", test.name, test.output, result)
+		}
+	}
+}
+
+func TestExecute(t *testing.T) {
+	testExecute(execTests, nil, t)
+}
+
+var delimPairs = []string{
+	"", "", // default
+	"{{", "}}", // same as default
+	"<<", ">>", // distinct
+	"|", "|", // same
+	"(日)", "(本)", // peculiar
+}
+
+func TestDelims(t *testing.T) {
+	const hello = "Hello, world"
+	var value = struct{ Str string }{hello}
+	for i := 0; i < len(delimPairs); i += 2 {
+		text := ".Str"
+		left := delimPairs[i+0]
+		trueLeft := left
+		right := delimPairs[i+1]
+		trueRight := right
+		if left == "" { // default case
+			trueLeft = "{{"
+		}
+		if right == "" { // default case
+			trueRight = "}}"
+		}
+		text = trueLeft + text + trueRight
+		// Now add a comment
+		text += trueLeft + "/*comment*/" + trueRight
+		// Now add  an action containing a string.
+		text += trueLeft + `"` + trueLeft + `"` + trueRight
+		// At this point text looks like `{{.Str}}{{/*comment*/}}{{"{{"}}`.
+		tmpl, err := New("delims").Delims(left, right).Parse(text)
+		if err != nil {
+			t.Fatalf("delim %q text %q parse err %s", left, text, err)
+		}
+		var b = new(bytes.Buffer)
+		err = tmpl.Execute(b, value)
+		if err != nil {
+			t.Fatalf("delim %q exec err %s", left, err)
+		}
+		if b.String() != hello+trueLeft {
+			t.Errorf("expected %q got %q", hello+trueLeft, b.String())
+		}
+	}
+}
+
+// Check that an error from a method flows back to the top.
+func TestExecuteError(t *testing.T) {
+	b := new(bytes.Buffer)
+	tmpl := New("error")
+	_, err := tmpl.Parse("{{.MyError true}}")
+	if err != nil {
+		t.Fatalf("parse error: %s", err)
+	}
+	err = tmpl.Execute(b, tVal)
+	if err == nil {
+		t.Errorf("expected error; got none")
+	} else if !strings.Contains(err.Error(), myError.Error()) {
+		if *debug {
+			fmt.Printf("test execute error: %s\n", err)
+		}
+		t.Errorf("expected myError; got %s", err)
+	}
+}
+
+const execErrorText = `line 1
+line 2
+line 3
+{{template "one" .}}
+{{define "one"}}{{template "two" .}}{{end}}
+{{define "two"}}{{template "three" .}}{{end}}
+{{define "three"}}{{index "hi" $}}{{end}}`
+
+// Check that an error from a nested template contains all the relevant information.
+func TestExecError(t *testing.T) {
+	tmpl, err := New("top").Parse(execErrorText)
+	if err != nil {
+		t.Fatal("parse error:", err)
+	}
+	var b bytes.Buffer
+	err = tmpl.Execute(&b, 5) // 5 is out of range indexing "hi"
+	if err == nil {
+		t.Fatal("expected error")
+	}
+	const want = `template: top:7:20: executing "three" at <index "hi" $>: error calling index: index out of range: 5`
+	got := err.Error()
+	if got != want {
+		t.Errorf("expected\n%q\ngot\n%q", want, got)
+	}
+}
+
+func TestJSEscaping(t *testing.T) {
+	testCases := []struct {
+		in, exp string
+	}{
+		{`a`, `a`},
+		{`'foo`, `\'foo`},
+		{`Go "jump" \`, `Go \"jump\" \\`},
+		{`Yukihiro says "今日は世界"`, `Yukihiro says \"今日は世界\"`},
+		{"unprintable \uFDFF", `unprintable \uFDFF`},
+		{`<html>`, `\x3Chtml\x3E`},
+	}
+	for _, tc := range testCases {
+		s := JSEscapeString(tc.in)
+		if s != tc.exp {
+			t.Errorf("JS escaping [%s] got [%s] want [%s]", tc.in, s, tc.exp)
+		}
+	}
+}
+
+// A nice example: walk a binary tree.
+
+type Tree struct {
+	Val         int
+	Left, Right *Tree
+}
+
+// Use different delimiters to test Set.Delims.
+const treeTemplate = `
+	(define "tree")
+	[
+		(.Val)
+		(with .Left)
+			(template "tree" .)
+		(end)
+		(with .Right)
+			(template "tree" .)
+		(end)
+	]
+	(end)
+`
+
+func TestTree(t *testing.T) {
+	var tree = &Tree{
+		1,
+		&Tree{
+			2, &Tree{
+				3,
+				&Tree{
+					4, nil, nil,
+				},
+				nil,
+			},
+			&Tree{
+				5,
+				&Tree{
+					6, nil, nil,
+				},
+				nil,
+			},
+		},
+		&Tree{
+			7,
+			&Tree{
+				8,
+				&Tree{
+					9, nil, nil,
+				},
+				nil,
+			},
+			&Tree{
+				10,
+				&Tree{
+					11, nil, nil,
+				},
+				nil,
+			},
+		},
+	}
+	tmpl, err := New("root").Delims("(", ")").Parse(treeTemplate)
+	if err != nil {
+		t.Fatal("parse error:", err)
+	}
+	var b bytes.Buffer
+	stripSpace := func(r rune) rune {
+		if r == '\t' || r == '\n' {
+			return -1
+		}
+		return r
+	}
+	const expect = "[1[2[3[4]][5[6]]][7[8[9]][10[11]]]]"
+	// First by looking up the template.
+	err = tmpl.Lookup("tree").Execute(&b, tree)
+	if err != nil {
+		t.Fatal("exec error:", err)
+	}
+	result := strings.Map(stripSpace, b.String())
+	if result != expect {
+		t.Errorf("expected %q got %q", expect, result)
+	}
+	// Then direct to execution.
+	b.Reset()
+	err = tmpl.ExecuteTemplate(&b, "tree", tree)
+	if err != nil {
+		t.Fatal("exec error:", err)
+	}
+	result = strings.Map(stripSpace, b.String())
+	if result != expect {
+		t.Errorf("expected %q got %q", expect, result)
+	}
+}
+
+func TestExecuteOnNewTemplate(t *testing.T) {
+	// This is issue 3872.
+	_ = New("Name").Templates()
+}
+
+const testTemplates = `{{define "one"}}one{{end}}{{define "two"}}two{{end}}`
+
+func TestMessageForExecuteEmpty(t *testing.T) {
+	// Test a truly empty template.
+	tmpl := New("empty")
+	var b bytes.Buffer
+	err := tmpl.Execute(&b, 0)
+	if err == nil {
+		t.Fatal("expected initial error")
+	}
+	got := err.Error()
+	want := `template: empty: "empty" is an incomplete or empty template`
+	if got != want {
+		t.Errorf("expected error %s got %s", want, got)
+	}
+	// Add a non-empty template to check that the error is helpful.
+	tests, err := New("").Parse(testTemplates)
+	if err != nil {
+		t.Fatal(err)
+	}
+	tmpl.AddParseTree("secondary", tests.Tree)
+	err = tmpl.Execute(&b, 0)
+	if err == nil {
+		t.Fatal("expected second error")
+	}
+	got = err.Error()
+	want = `template: empty: "empty" is an incomplete or empty template; defined templates are: "secondary"`
+	if got != want {
+		t.Errorf("expected error %s got %s", want, got)
+	}
+	// Make sure we can execute the secondary.
+	err = tmpl.ExecuteTemplate(&b, "secondary", 0)
+	if err != nil {
+		t.Fatal(err)
+	}
+}
+
+func TestFinalForPrintf(t *testing.T) {
+	tmpl, err := New("").Parse(`{{"x" | printf}}`)
+	if err != nil {
+		t.Fatal(err)
+	}
+	var b bytes.Buffer
+	err = tmpl.Execute(&b, 0)
+	if err != nil {
+		t.Fatal(err)
+	}
+}
+
+type cmpTest struct {
+	expr  string
+	truth string
+	ok    bool
+}
+
+var cmpTests = []cmpTest{
+	{"eq true true", "true", true},
+	{"eq true false", "false", true},
+	{"eq 1+2i 1+2i", "true", true},
+	{"eq 1+2i 1+3i", "false", true},
+	{"eq 1.5 1.5", "true", true},
+	{"eq 1.5 2.5", "false", true},
+	{"eq 1 1", "true", true},
+	{"eq 1 2", "false", true},
+	{"eq `xy` `xy`", "true", true},
+	{"eq `xy` `xyz`", "false", true},
+	{"eq .Uthree .Uthree", "true", true},
+	{"eq .Uthree .Ufour", "false", true},
+	{"eq 3 4 5 6 3", "true", true},
+	{"eq 3 4 5 6 7", "false", true},
+	{"ne true true", "false", true},
+	{"ne true false", "true", true},
+	{"ne 1+2i 1+2i", "false", true},
+	{"ne 1+2i 1+3i", "true", true},
+	{"ne 1.5 1.5", "false", true},
+	{"ne 1.5 2.5", "true", true},
+	{"ne 1 1", "false", true},
+	{"ne 1 2", "true", true},
+	{"ne `xy` `xy`", "false", true},
+	{"ne `xy` `xyz`", "true", true},
+	{"ne .Uthree .Uthree", "false", true},
+	{"ne .Uthree .Ufour", "true", true},
+	{"lt 1.5 1.5", "false", true},
+	{"lt 1.5 2.5", "true", true},
+	{"lt 1 1", "false", true},
+	{"lt 1 2", "true", true},
+	{"lt `xy` `xy`", "false", true},
+	{"lt `xy` `xyz`", "true", true},
+	{"lt .Uthree .Uthree", "false", true},
+	{"lt .Uthree .Ufour", "true", true},
+	{"le 1.5 1.5", "true", true},
+	{"le 1.5 2.5", "true", true},
+	{"le 2.5 1.5", "false", true},
+	{"le 1 1", "true", true},
+	{"le 1 2", "true", true},
+	{"le 2 1", "false", true},
+	{"le `xy` `xy`", "true", true},
+	{"le `xy` `xyz`", "true", true},
+	{"le `xyz` `xy`", "false", true},
+	{"le .Uthree .Uthree", "true", true},
+	{"le .Uthree .Ufour", "true", true},
+	{"le .Ufour .Uthree", "false", true},
+	{"gt 1.5 1.5", "false", true},
+	{"gt 1.5 2.5", "false", true},
+	{"gt 1 1", "false", true},
+	{"gt 2 1", "true", true},
+	{"gt 1 2", "false", true},
+	{"gt `xy` `xy`", "false", true},
+	{"gt `xy` `xyz`", "false", true},
+	{"gt .Uthree .Uthree", "false", true},
+	{"gt .Uthree .Ufour", "false", true},
+	{"gt .Ufour .Uthree", "true", true},
+	{"ge 1.5 1.5", "true", true},
+	{"ge 1.5 2.5", "false", true},
+	{"ge 2.5 1.5", "true", true},
+	{"ge 1 1", "true", true},
+	{"ge 1 2", "false", true},
+	{"ge 2 1", "true", true},
+	{"ge `xy` `xy`", "true", true},
+	{"ge `xy` `xyz`", "false", true},
+	{"ge `xyz` `xy`", "true", true},
+	{"ge .Uthree .Uthree", "true", true},
+	{"ge .Uthree .Ufour", "false", true},
+	{"ge .Ufour .Uthree", "true", true},
+	// Mixing signed and unsigned integers.
+	{"eq .Uthree .Three", "true", true},
+	{"eq .Three .Uthree", "true", true},
+	{"le .Uthree .Three", "true", true},
+	{"le .Three .Uthree", "true", true},
+	{"ge .Uthree .Three", "true", true},
+	{"ge .Three .Uthree", "true", true},
+	{"lt .Uthree .Three", "false", true},
+	{"lt .Three .Uthree", "false", true},
+	{"gt .Uthree .Three", "false", true},
+	{"gt .Three .Uthree", "false", true},
+	{"eq .Ufour .Three", "false", true},
+	{"lt .Ufour .Three", "false", true},
+	{"gt .Ufour .Three", "true", true},
+	{"eq .NegOne .Uthree", "false", true},
+	{"eq .Uthree .NegOne", "false", true},
+	{"ne .NegOne .Uthree", "true", true},
+	{"ne .Uthree .NegOne", "true", true},
+	{"lt .NegOne .Uthree", "true", true},
+	{"lt .Uthree .NegOne", "false", true},
+	{"le .NegOne .Uthree", "true", true},
+	{"le .Uthree .NegOne", "false", true},
+	{"gt .NegOne .Uthree", "false", true},
+	{"gt .Uthree .NegOne", "true", true},
+	{"ge .NegOne .Uthree", "false", true},
+	{"ge .Uthree .NegOne", "true", true},
+	{"eq (index `x` 0) 'x'", "true", true}, // The example that triggered this rule.
+	{"eq (index `x` 0) 'y'", "false", true},
+	// Errors
+	{"eq `xy` 1", "", false},    // Different types.
+	{"eq 2 2.0", "", false},     // Different types.
+	{"lt true true", "", false}, // Unordered types.
+	{"lt 1+0i 1+0i", "", false}, // Unordered types.
+}
+
+func TestComparison(t *testing.T) {
+	b := new(bytes.Buffer)
+	var cmpStruct = struct {
+		Uthree, Ufour uint
+		NegOne, Three int
+	}{3, 4, -1, 3}
+	for _, test := range cmpTests {
+		text := fmt.Sprintf("{{if %s}}true{{else}}false{{end}}", test.expr)
+		tmpl, err := New("empty").Parse(text)
+		if err != nil {
+			t.Fatalf("%q: %s", test.expr, err)
+		}
+		b.Reset()
+		err = tmpl.Execute(b, &cmpStruct)
+		if test.ok && err != nil {
+			t.Errorf("%s errored incorrectly: %s", test.expr, err)
+			continue
+		}
+		if !test.ok && err == nil {
+			t.Errorf("%s did not error", test.expr)
+			continue
+		}
+		if b.String() != test.truth {
+			t.Errorf("%s: want %s; got %s", test.expr, test.truth, b.String())
+		}
+	}
+}
diff --git a/src/text/template/funcs.go b/src/text/template/funcs.go
new file mode 100644
index 0000000..39ee5ed
--- /dev/null
+++ b/src/text/template/funcs.go
@@ -0,0 +1,598 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package template
+
+import (
+	"bytes"
+	"errors"
+	"fmt"
+	"io"
+	"net/url"
+	"reflect"
+	"strings"
+	"unicode"
+	"unicode/utf8"
+)
+
+// FuncMap is the type of the map defining the mapping from names to functions.
+// Each function must have either a single return value, or two return values of
+// which the second has type error. In that case, if the second (error)
+// return value evaluates to non-nil during execution, execution terminates and
+// Execute returns that error.
+type FuncMap map[string]interface{}
+
+var builtins = FuncMap{
+	"and":      and,
+	"call":     call,
+	"html":     HTMLEscaper,
+	"index":    index,
+	"js":       JSEscaper,
+	"len":      length,
+	"not":      not,
+	"or":       or,
+	"print":    fmt.Sprint,
+	"printf":   fmt.Sprintf,
+	"println":  fmt.Sprintln,
+	"urlquery": URLQueryEscaper,
+
+	// Comparisons
+	"eq": eq, // ==
+	"ge": ge, // >=
+	"gt": gt, // >
+	"le": le, // <=
+	"lt": lt, // <
+	"ne": ne, // !=
+}
+
+var builtinFuncs = createValueFuncs(builtins)
+
+// createValueFuncs turns a FuncMap into a map[string]reflect.Value
+func createValueFuncs(funcMap FuncMap) map[string]reflect.Value {
+	m := make(map[string]reflect.Value)
+	addValueFuncs(m, funcMap)
+	return m
+}
+
+// addValueFuncs adds to values the functions in funcs, converting them to reflect.Values.
+func addValueFuncs(out map[string]reflect.Value, in FuncMap) {
+	for name, fn := range in {
+		v := reflect.ValueOf(fn)
+		if v.Kind() != reflect.Func {
+			panic("value for " + name + " not a function")
+		}
+		if !goodFunc(v.Type()) {
+			panic(fmt.Errorf("can't install method/function %q with %d results", name, v.Type().NumOut()))
+		}
+		out[name] = v
+	}
+}
+
+// addFuncs adds to values the functions in funcs. It does no checking of the input -
+// call addValueFuncs first.
+func addFuncs(out, in FuncMap) {
+	for name, fn := range in {
+		out[name] = fn
+	}
+}
+
+// goodFunc checks that the function or method has the right result signature.
+func goodFunc(typ reflect.Type) bool {
+	// We allow functions with 1 result or 2 results where the second is an error.
+	switch {
+	case typ.NumOut() == 1:
+		return true
+	case typ.NumOut() == 2 && typ.Out(1) == errorType:
+		return true
+	}
+	return false
+}
+
+// findFunction looks for a function in the template, and global map.
+func findFunction(name string, tmpl *Template) (reflect.Value, bool) {
+	if tmpl != nil && tmpl.common != nil {
+		if fn := tmpl.execFuncs[name]; fn.IsValid() {
+			return fn, true
+		}
+	}
+	if fn := builtinFuncs[name]; fn.IsValid() {
+		return fn, true
+	}
+	return reflect.Value{}, false
+}
+
+// Indexing.
+
+// index returns the result of indexing its first argument by the following
+// arguments.  Thus "index x 1 2 3" is, in Go syntax, x[1][2][3]. Each
+// indexed item must be a map, slice, or array.
+func index(item interface{}, indices ...interface{}) (interface{}, error) {
+	v := reflect.ValueOf(item)
+	for _, i := range indices {
+		index := reflect.ValueOf(i)
+		var isNil bool
+		if v, isNil = indirect(v); isNil {
+			return nil, fmt.Errorf("index of nil pointer")
+		}
+		switch v.Kind() {
+		case reflect.Array, reflect.Slice, reflect.String:
+			var x int64
+			switch index.Kind() {
+			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+				x = index.Int()
+			case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+				x = int64(index.Uint())
+			default:
+				return nil, fmt.Errorf("cannot index slice/array with type %s", index.Type())
+			}
+			if x < 0 || x >= int64(v.Len()) {
+				return nil, fmt.Errorf("index out of range: %d", x)
+			}
+			v = v.Index(int(x))
+		case reflect.Map:
+			if !index.IsValid() {
+				index = reflect.Zero(v.Type().Key())
+			}
+			if !index.Type().AssignableTo(v.Type().Key()) {
+				return nil, fmt.Errorf("%s is not index type for %s", index.Type(), v.Type())
+			}
+			if x := v.MapIndex(index); x.IsValid() {
+				v = x
+			} else {
+				v = reflect.Zero(v.Type().Elem())
+			}
+		default:
+			return nil, fmt.Errorf("can't index item of type %s", v.Type())
+		}
+	}
+	return v.Interface(), nil
+}
+
+// Length
+
+// length returns the length of the item, with an error if it has no defined length.
+func length(item interface{}) (int, error) {
+	v, isNil := indirect(reflect.ValueOf(item))
+	if isNil {
+		return 0, fmt.Errorf("len of nil pointer")
+	}
+	switch v.Kind() {
+	case reflect.Array, reflect.Chan, reflect.Map, reflect.Slice, reflect.String:
+		return v.Len(), nil
+	}
+	return 0, fmt.Errorf("len of type %s", v.Type())
+}
+
+// Function invocation
+
+// call returns the result of evaluating the first argument as a function.
+// The function must return 1 result, or 2 results, the second of which is an error.
+func call(fn interface{}, args ...interface{}) (interface{}, error) {
+	v := reflect.ValueOf(fn)
+	typ := v.Type()
+	if typ.Kind() != reflect.Func {
+		return nil, fmt.Errorf("non-function of type %s", typ)
+	}
+	if !goodFunc(typ) {
+		return nil, fmt.Errorf("function called with %d args; should be 1 or 2", typ.NumOut())
+	}
+	numIn := typ.NumIn()
+	var dddType reflect.Type
+	if typ.IsVariadic() {
+		if len(args) < numIn-1 {
+			return nil, fmt.Errorf("wrong number of args: got %d want at least %d", len(args), numIn-1)
+		}
+		dddType = typ.In(numIn - 1).Elem()
+	} else {
+		if len(args) != numIn {
+			return nil, fmt.Errorf("wrong number of args: got %d want %d", len(args), numIn)
+		}
+	}
+	argv := make([]reflect.Value, len(args))
+	for i, arg := range args {
+		value := reflect.ValueOf(arg)
+		// Compute the expected type. Clumsy because of variadics.
+		var argType reflect.Type
+		if !typ.IsVariadic() || i < numIn-1 {
+			argType = typ.In(i)
+		} else {
+			argType = dddType
+		}
+		if !value.IsValid() && canBeNil(argType) {
+			value = reflect.Zero(argType)
+		}
+		if !value.Type().AssignableTo(argType) {
+			return nil, fmt.Errorf("arg %d has type %s; should be %s", i, value.Type(), argType)
+		}
+		argv[i] = value
+	}
+	result := v.Call(argv)
+	if len(result) == 2 && !result[1].IsNil() {
+		return result[0].Interface(), result[1].Interface().(error)
+	}
+	return result[0].Interface(), nil
+}
+
+// Boolean logic.
+
+func truth(a interface{}) bool {
+	t, _ := isTrue(reflect.ValueOf(a))
+	return t
+}
+
+// and computes the Boolean AND of its arguments, returning
+// the first false argument it encounters, or the last argument.
+func and(arg0 interface{}, args ...interface{}) interface{} {
+	if !truth(arg0) {
+		return arg0
+	}
+	for i := range args {
+		arg0 = args[i]
+		if !truth(arg0) {
+			break
+		}
+	}
+	return arg0
+}
+
+// or computes the Boolean OR of its arguments, returning
+// the first true argument it encounters, or the last argument.
+func or(arg0 interface{}, args ...interface{}) interface{} {
+	if truth(arg0) {
+		return arg0
+	}
+	for i := range args {
+		arg0 = args[i]
+		if truth(arg0) {
+			break
+		}
+	}
+	return arg0
+}
+
+// not returns the Boolean negation of its argument.
+func not(arg interface{}) (truth bool) {
+	truth, _ = isTrue(reflect.ValueOf(arg))
+	return !truth
+}
+
+// Comparison.
+
+// TODO: Perhaps allow comparison between signed and unsigned integers.
+
+var (
+	errBadComparisonType = errors.New("invalid type for comparison")
+	errBadComparison     = errors.New("incompatible types for comparison")
+	errNoComparison      = errors.New("missing argument for comparison")
+)
+
+type kind int
+
+const (
+	invalidKind kind = iota
+	boolKind
+	complexKind
+	intKind
+	floatKind
+	integerKind
+	stringKind
+	uintKind
+)
+
+func basicKind(v reflect.Value) (kind, error) {
+	switch v.Kind() {
+	case reflect.Bool:
+		return boolKind, nil
+	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+		return intKind, nil
+	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+		return uintKind, nil
+	case reflect.Float32, reflect.Float64:
+		return floatKind, nil
+	case reflect.Complex64, reflect.Complex128:
+		return complexKind, nil
+	case reflect.String:
+		return stringKind, nil
+	}
+	return invalidKind, errBadComparisonType
+}
+
+// eq evaluates the comparison a == b || a == c || ...
+func eq(arg1 interface{}, arg2 ...interface{}) (bool, error) {
+	v1 := reflect.ValueOf(arg1)
+	k1, err := basicKind(v1)
+	if err != nil {
+		return false, err
+	}
+	if len(arg2) == 0 {
+		return false, errNoComparison
+	}
+	for _, arg := range arg2 {
+		v2 := reflect.ValueOf(arg)
+		k2, err := basicKind(v2)
+		if err != nil {
+			return false, err
+		}
+		truth := false
+		if k1 != k2 {
+			// Special case: Can compare integer values regardless of type's sign.
+			switch {
+			case k1 == intKind && k2 == uintKind:
+				truth = v1.Int() >= 0 && uint64(v1.Int()) == v2.Uint()
+			case k1 == uintKind && k2 == intKind:
+				truth = v2.Int() >= 0 && v1.Uint() == uint64(v2.Int())
+			default:
+				return false, errBadComparison
+			}
+		} else {
+			switch k1 {
+			case boolKind:
+				truth = v1.Bool() == v2.Bool()
+			case complexKind:
+				truth = v1.Complex() == v2.Complex()
+			case floatKind:
+				truth = v1.Float() == v2.Float()
+			case intKind:
+				truth = v1.Int() == v2.Int()
+			case stringKind:
+				truth = v1.String() == v2.String()
+			case uintKind:
+				truth = v1.Uint() == v2.Uint()
+			default:
+				panic("invalid kind")
+			}
+		}
+		if truth {
+			return true, nil
+		}
+	}
+	return false, nil
+}
+
+// ne evaluates the comparison a != b.
+func ne(arg1, arg2 interface{}) (bool, error) {
+	// != is the inverse of ==.
+	equal, err := eq(arg1, arg2)
+	return !equal, err
+}
+
+// lt evaluates the comparison a < b.
+func lt(arg1, arg2 interface{}) (bool, error) {
+	v1 := reflect.ValueOf(arg1)
+	k1, err := basicKind(v1)
+	if err != nil {
+		return false, err
+	}
+	v2 := reflect.ValueOf(arg2)
+	k2, err := basicKind(v2)
+	if err != nil {
+		return false, err
+	}
+	truth := false
+	if k1 != k2 {
+		// Special case: Can compare integer values regardless of type's sign.
+		switch {
+		case k1 == intKind && k2 == uintKind:
+			truth = v1.Int() < 0 || uint64(v1.Int()) < v2.Uint()
+		case k1 == uintKind && k2 == intKind:
+			truth = v2.Int() >= 0 && v1.Uint() < uint64(v2.Int())
+		default:
+			return false, errBadComparison
+		}
+	} else {
+		switch k1 {
+		case boolKind, complexKind:
+			return false, errBadComparisonType
+		case floatKind:
+			truth = v1.Float() < v2.Float()
+		case intKind:
+			truth = v1.Int() < v2.Int()
+		case stringKind:
+			truth = v1.String() < v2.String()
+		case uintKind:
+			truth = v1.Uint() < v2.Uint()
+		default:
+			panic("invalid kind")
+		}
+	}
+	return truth, nil
+}
+
+// le evaluates the comparison <= b.
+func le(arg1, arg2 interface{}) (bool, error) {
+	// <= is < or ==.
+	lessThan, err := lt(arg1, arg2)
+	if lessThan || err != nil {
+		return lessThan, err
+	}
+	return eq(arg1, arg2)
+}
+
+// gt evaluates the comparison a > b.
+func gt(arg1, arg2 interface{}) (bool, error) {
+	// > is the inverse of <=.
+	lessOrEqual, err := le(arg1, arg2)
+	if err != nil {
+		return false, err
+	}
+	return !lessOrEqual, nil
+}
+
+// ge evaluates the comparison a >= b.
+func ge(arg1, arg2 interface{}) (bool, error) {
+	// >= is the inverse of <.
+	lessThan, err := lt(arg1, arg2)
+	if err != nil {
+		return false, err
+	}
+	return !lessThan, nil
+}
+
+// HTML escaping.
+
+var (
+	htmlQuot = []byte(""") // shorter than """
+	htmlApos = []byte("'") // shorter than "'" and apos was not in HTML until HTML5
+	htmlAmp  = []byte("&")
+	htmlLt   = []byte("<")
+	htmlGt   = []byte(">")
+)
+
+// HTMLEscape writes to w the escaped HTML equivalent of the plain text data b.
+func HTMLEscape(w io.Writer, b []byte) {
+	last := 0
+	for i, c := range b {
+		var html []byte
+		switch c {
+		case '"':
+			html = htmlQuot
+		case '\'':
+			html = htmlApos
+		case '&':
+			html = htmlAmp
+		case '<':
+			html = htmlLt
+		case '>':
+			html = htmlGt
+		default:
+			continue
+		}
+		w.Write(b[last:i])
+		w.Write(html)
+		last = i + 1
+	}
+	w.Write(b[last:])
+}
+
+// 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 {
+		return s
+	}
+	var b bytes.Buffer
+	HTMLEscape(&b, []byte(s))
+	return b.String()
+}
+
+// HTMLEscaper returns the escaped HTML equivalent of the textual
+// representation of its arguments.
+func HTMLEscaper(args ...interface{}) string {
+	return HTMLEscapeString(evalArgs(args))
+}
+
+// JavaScript escaping.
+
+var (
+	jsLowUni = []byte(`\u00`)
+	hex      = []byte("0123456789ABCDEF")
+
+	jsBackslash = []byte(`\\`)
+	jsApos      = []byte(`\'`)
+	jsQuot      = []byte(`\"`)
+	jsLt        = []byte(`\x3C`)
+	jsGt        = []byte(`\x3E`)
+)
+
+// JSEscape writes to w the escaped JavaScript equivalent of the plain text data b.
+func JSEscape(w io.Writer, b []byte) {
+	last := 0
+	for i := 0; i < len(b); i++ {
+		c := b[i]
+
+		if !jsIsSpecial(rune(c)) {
+			// fast path: nothing to do
+			continue
+		}
+		w.Write(b[last:i])
+
+		if c < utf8.RuneSelf {
+			// Quotes, slashes and angle brackets get quoted.
+			// Control characters get written as \u00XX.
+			switch c {
+			case '\\':
+				w.Write(jsBackslash)
+			case '\'':
+				w.Write(jsApos)
+			case '"':
+				w.Write(jsQuot)
+			case '<':
+				w.Write(jsLt)
+			case '>':
+				w.Write(jsGt)
+			default:
+				w.Write(jsLowUni)
+				t, b := c>>4, c&0x0f
+				w.Write(hex[t : t+1])
+				w.Write(hex[b : b+1])
+			}
+		} else {
+			// Unicode rune.
+			r, size := utf8.DecodeRune(b[i:])
+			if unicode.IsPrint(r) {
+				w.Write(b[i : i+size])
+			} else {
+				fmt.Fprintf(w, "\\u%04X", r)
+			}
+			i += size - 1
+		}
+		last = i + 1
+	}
+	w.Write(b[last:])
+}
+
+// JSEscapeString returns the escaped JavaScript equivalent of the plain text data s.
+func JSEscapeString(s string) string {
+	// Avoid allocation if we can.
+	if strings.IndexFunc(s, jsIsSpecial) < 0 {
+		return s
+	}
+	var b bytes.Buffer
+	JSEscape(&b, []byte(s))
+	return b.String()
+}
+
+func jsIsSpecial(r rune) bool {
+	switch r {
+	case '\\', '\'', '"', '<', '>':
+		return true
+	}
+	return r < ' ' || utf8.RuneSelf <= r
+}
+
+// JSEscaper returns the escaped JavaScript equivalent of the textual
+// representation of its arguments.
+func JSEscaper(args ...interface{}) string {
+	return JSEscapeString(evalArgs(args))
+}
+
+// URLQueryEscaper returns the escaped value of the textual representation of
+// its arguments in a form suitable for embedding in a URL query.
+func URLQueryEscaper(args ...interface{}) string {
+	return url.QueryEscape(evalArgs(args))
+}
+
+// evalArgs formats the list of arguments into a string. It is therefore equivalent to
+//	fmt.Sprint(args...)
+// except that each argument is indirected (if a pointer), as required,
+// using the same rules as the default string evaluation during template
+// execution.
+func evalArgs(args []interface{}) string {
+	ok := false
+	var s string
+	// Fast path for simple common case.
+	if len(args) == 1 {
+		s, ok = args[0].(string)
+	}
+	if !ok {
+		for i, arg := range args {
+			a, ok := printableValue(reflect.ValueOf(arg))
+			if ok {
+				args[i] = a
+			} // else left fmt do its thing
+		}
+		s = fmt.Sprint(args...)
+	}
+	return s
+}
diff --git a/src/pkg/text/template/helper.go b/src/text/template/helper.go
similarity index 100%
rename from src/pkg/text/template/helper.go
rename to src/text/template/helper.go
diff --git a/src/pkg/text/template/multi_test.go b/src/text/template/multi_test.go
similarity index 100%
rename from src/pkg/text/template/multi_test.go
rename to src/text/template/multi_test.go
diff --git a/src/pkg/text/template/parse/lex.go b/src/text/template/parse/lex.go
similarity index 100%
rename from src/pkg/text/template/parse/lex.go
rename to src/text/template/parse/lex.go
diff --git a/src/pkg/text/template/parse/lex_test.go b/src/text/template/parse/lex_test.go
similarity index 100%
rename from src/pkg/text/template/parse/lex_test.go
rename to src/text/template/parse/lex_test.go
diff --git a/src/text/template/parse/node.go b/src/text/template/parse/node.go
new file mode 100644
index 0000000..55c37f6
--- /dev/null
+++ b/src/text/template/parse/node.go
@@ -0,0 +1,834 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Parse nodes.
+
+package parse
+
+import (
+	"bytes"
+	"fmt"
+	"strconv"
+	"strings"
+)
+
+var textFormat = "%s" // Changed to "%q" in tests for better error messages.
+
+// A Node is an element in the parse tree. The interface is trivial.
+// The interface contains an unexported method so that only
+// types local to this package can satisfy it.
+type Node interface {
+	Type() NodeType
+	String() string
+	// Copy does a deep copy of the Node and all its components.
+	// To avoid type assertions, some XxxNodes also have specialized
+	// CopyXxx methods that return *XxxNode.
+	Copy() Node
+	Position() Pos // byte position of start of node in full original input string
+	// tree returns the containing *Tree.
+	// It is unexported so all implementations of Node are in this package.
+	tree() *Tree
+}
+
+// NodeType identifies the type of a parse tree node.
+type NodeType int
+
+// Pos represents a byte position in the original input text from which
+// this template was parsed.
+type Pos int
+
+func (p Pos) Position() Pos {
+	return p
+}
+
+// Type returns itself and provides an easy default implementation
+// for embedding in a Node. Embedded in all non-trivial Nodes.
+func (t NodeType) Type() NodeType {
+	return t
+}
+
+const (
+	NodeText       NodeType = iota // Plain text.
+	NodeAction                     // A non-control action such as a field evaluation.
+	NodeBool                       // A boolean constant.
+	NodeChain                      // A sequence of field accesses.
+	NodeCommand                    // An element of a pipeline.
+	NodeDot                        // The cursor, dot.
+	nodeElse                       // An else action. Not added to tree.
+	nodeEnd                        // An end action. Not added to tree.
+	NodeField                      // A field or method name.
+	NodeIdentifier                 // An identifier; always a function name.
+	NodeIf                         // An if action.
+	NodeList                       // A list of Nodes.
+	NodeNil                        // An untyped nil constant.
+	NodeNumber                     // A numerical constant.
+	NodePipe                       // A pipeline of commands.
+	NodeRange                      // A range action.
+	NodeString                     // A string constant.
+	NodeTemplate                   // A template invocation action.
+	NodeVariable                   // A $ variable.
+	NodeWith                       // A with action.
+)
+
+// Nodes.
+
+// ListNode holds a sequence of nodes.
+type ListNode struct {
+	NodeType
+	Pos
+	tr    *Tree
+	Nodes []Node // The element nodes in lexical order.
+}
+
+func (t *Tree) newList(pos Pos) *ListNode {
+	return &ListNode{tr: t, NodeType: NodeList, Pos: pos}
+}
+
+func (l *ListNode) append(n Node) {
+	l.Nodes = append(l.Nodes, n)
+}
+
+func (l *ListNode) tree() *Tree {
+	return l.tr
+}
+
+func (l *ListNode) String() string {
+	b := new(bytes.Buffer)
+	for _, n := range l.Nodes {
+		fmt.Fprint(b, n)
+	}
+	return b.String()
+}
+
+func (l *ListNode) CopyList() *ListNode {
+	if l == nil {
+		return l
+	}
+	n := l.tr.newList(l.Pos)
+	for _, elem := range l.Nodes {
+		n.append(elem.Copy())
+	}
+	return n
+}
+
+func (l *ListNode) Copy() Node {
+	return l.CopyList()
+}
+
+// TextNode holds plain text.
+type TextNode struct {
+	NodeType
+	Pos
+	tr   *Tree
+	Text []byte // The text; may span newlines.
+}
+
+func (t *Tree) newText(pos Pos, text string) *TextNode {
+	return &TextNode{tr: t, NodeType: NodeText, Pos: pos, Text: []byte(text)}
+}
+
+func (t *TextNode) String() string {
+	return fmt.Sprintf(textFormat, t.Text)
+}
+
+func (t *TextNode) tree() *Tree {
+	return t.tr
+}
+
+func (t *TextNode) Copy() Node {
+	return &TextNode{tr: t.tr, NodeType: NodeText, Pos: t.Pos, Text: append([]byte{}, t.Text...)}
+}
+
+// PipeNode holds a pipeline with optional declaration
+type PipeNode struct {
+	NodeType
+	Pos
+	tr   *Tree
+	Line int             // The line number in the input (deprecated; kept for compatibility)
+	Decl []*VariableNode // Variable declarations in lexical order.
+	Cmds []*CommandNode  // The commands in lexical order.
+}
+
+func (t *Tree) newPipeline(pos Pos, line int, decl []*VariableNode) *PipeNode {
+	return &PipeNode{tr: t, NodeType: NodePipe, Pos: pos, Line: line, Decl: decl}
+}
+
+func (p *PipeNode) append(command *CommandNode) {
+	p.Cmds = append(p.Cmds, command)
+}
+
+func (p *PipeNode) String() string {
+	s := ""
+	if len(p.Decl) > 0 {
+		for i, v := range p.Decl {
+			if i > 0 {
+				s += ", "
+			}
+			s += v.String()
+		}
+		s += " := "
+	}
+	for i, c := range p.Cmds {
+		if i > 0 {
+			s += " | "
+		}
+		s += c.String()
+	}
+	return s
+}
+
+func (p *PipeNode) tree() *Tree {
+	return p.tr
+}
+
+func (p *PipeNode) CopyPipe() *PipeNode {
+	if p == nil {
+		return p
+	}
+	var decl []*VariableNode
+	for _, d := range p.Decl {
+		decl = append(decl, d.Copy().(*VariableNode))
+	}
+	n := p.tr.newPipeline(p.Pos, p.Line, decl)
+	for _, c := range p.Cmds {
+		n.append(c.Copy().(*CommandNode))
+	}
+	return n
+}
+
+func (p *PipeNode) Copy() Node {
+	return p.CopyPipe()
+}
+
+// ActionNode holds an action (something bounded by delimiters).
+// Control actions have their own nodes; ActionNode represents simple
+// ones such as field evaluations and parenthesized pipelines.
+type ActionNode struct {
+	NodeType
+	Pos
+	tr   *Tree
+	Line int       // The line number in the input (deprecated; kept for compatibility)
+	Pipe *PipeNode // The pipeline in the action.
+}
+
+func (t *Tree) newAction(pos Pos, line int, pipe *PipeNode) *ActionNode {
+	return &ActionNode{tr: t, NodeType: NodeAction, Pos: pos, Line: line, Pipe: pipe}
+}
+
+func (a *ActionNode) String() string {
+	return fmt.Sprintf("{{%s}}", a.Pipe)
+
+}
+
+func (a *ActionNode) tree() *Tree {
+	return a.tr
+}
+
+func (a *ActionNode) Copy() Node {
+	return a.tr.newAction(a.Pos, a.Line, a.Pipe.CopyPipe())
+
+}
+
+// CommandNode holds a command (a pipeline inside an evaluating action).
+type CommandNode struct {
+	NodeType
+	Pos
+	tr   *Tree
+	Args []Node // Arguments in lexical order: Identifier, field, or constant.
+}
+
+func (t *Tree) newCommand(pos Pos) *CommandNode {
+	return &CommandNode{tr: t, NodeType: NodeCommand, Pos: pos}
+}
+
+func (c *CommandNode) append(arg Node) {
+	c.Args = append(c.Args, arg)
+}
+
+func (c *CommandNode) String() string {
+	s := ""
+	for i, arg := range c.Args {
+		if i > 0 {
+			s += " "
+		}
+		if arg, ok := arg.(*PipeNode); ok {
+			s += "(" + arg.String() + ")"
+			continue
+		}
+		s += arg.String()
+	}
+	return s
+}
+
+func (c *CommandNode) tree() *Tree {
+	return c.tr
+}
+
+func (c *CommandNode) Copy() Node {
+	if c == nil {
+		return c
+	}
+	n := c.tr.newCommand(c.Pos)
+	for _, c := range c.Args {
+		n.append(c.Copy())
+	}
+	return n
+}
+
+// IdentifierNode holds an identifier.
+type IdentifierNode struct {
+	NodeType
+	Pos
+	tr    *Tree
+	Ident string // The identifier's name.
+}
+
+// NewIdentifier returns a new IdentifierNode with the given identifier name.
+func NewIdentifier(ident string) *IdentifierNode {
+	return &IdentifierNode{NodeType: NodeIdentifier, Ident: ident}
+}
+
+// SetPos sets the position. NewIdentifier is a public method so we can't modify its signature.
+// Chained for convenience.
+// TODO: fix one day?
+func (i *IdentifierNode) SetPos(pos Pos) *IdentifierNode {
+	i.Pos = pos
+	return i
+}
+
+// SetTree sets the parent tree for the node. NewIdentifier is a public method so we can't modify its signature.
+// Chained for convenience.
+// TODO: fix one day?
+func (i *IdentifierNode) SetTree(t *Tree) *IdentifierNode {
+	i.tr = t
+	return i
+}
+
+func (i *IdentifierNode) String() string {
+	return i.Ident
+}
+
+func (i *IdentifierNode) tree() *Tree {
+	return i.tr
+}
+
+func (i *IdentifierNode) Copy() Node {
+	return NewIdentifier(i.Ident).SetTree(i.tr).SetPos(i.Pos)
+}
+
+// VariableNode holds a list of variable names, possibly with chained field
+// accesses. The dollar sign is part of the (first) name.
+type VariableNode struct {
+	NodeType
+	Pos
+	tr    *Tree
+	Ident []string // Variable name and fields in lexical order.
+}
+
+func (t *Tree) newVariable(pos Pos, ident string) *VariableNode {
+	return &VariableNode{tr: t, NodeType: NodeVariable, Pos: pos, Ident: strings.Split(ident, ".")}
+}
+
+func (v *VariableNode) String() string {
+	s := ""
+	for i, id := range v.Ident {
+		if i > 0 {
+			s += "."
+		}
+		s += id
+	}
+	return s
+}
+
+func (v *VariableNode) tree() *Tree {
+	return v.tr
+}
+
+func (v *VariableNode) Copy() Node {
+	return &VariableNode{tr: v.tr, NodeType: NodeVariable, Pos: v.Pos, Ident: append([]string{}, v.Ident...)}
+}
+
+// DotNode holds the special identifier '.'.
+type DotNode struct {
+	NodeType
+	Pos
+	tr *Tree
+}
+
+func (t *Tree) newDot(pos Pos) *DotNode {
+	return &DotNode{tr: t, NodeType: NodeDot, Pos: pos}
+}
+
+func (d *DotNode) Type() NodeType {
+	// Override method on embedded NodeType for API compatibility.
+	// TODO: Not really a problem; could change API without effect but
+	// api tool complains.
+	return NodeDot
+}
+
+func (d *DotNode) String() string {
+	return "."
+}
+
+func (d *DotNode) tree() *Tree {
+	return d.tr
+}
+
+func (d *DotNode) Copy() Node {
+	return d.tr.newDot(d.Pos)
+}
+
+// NilNode holds the special identifier 'nil' representing an untyped nil constant.
+type NilNode struct {
+	NodeType
+	Pos
+	tr *Tree
+}
+
+func (t *Tree) newNil(pos Pos) *NilNode {
+	return &NilNode{tr: t, NodeType: NodeNil, Pos: pos}
+}
+
+func (n *NilNode) Type() NodeType {
+	// Override method on embedded NodeType for API compatibility.
+	// TODO: Not really a problem; could change API without effect but
+	// api tool complains.
+	return NodeNil
+}
+
+func (n *NilNode) String() string {
+	return "nil"
+}
+
+func (n *NilNode) tree() *Tree {
+	return n.tr
+}
+
+func (n *NilNode) Copy() Node {
+	return n.tr.newNil(n.Pos)
+}
+
+// FieldNode holds a field (identifier starting with '.').
+// The names may be chained ('.x.y').
+// The period is dropped from each ident.
+type FieldNode struct {
+	NodeType
+	Pos
+	tr    *Tree
+	Ident []string // The identifiers in lexical order.
+}
+
+func (t *Tree) newField(pos Pos, ident string) *FieldNode {
+	return &FieldNode{tr: t, NodeType: NodeField, Pos: pos, Ident: strings.Split(ident[1:], ".")} // [1:] to drop leading period
+}
+
+func (f *FieldNode) String() string {
+	s := ""
+	for _, id := range f.Ident {
+		s += "." + id
+	}
+	return s
+}
+
+func (f *FieldNode) tree() *Tree {
+	return f.tr
+}
+
+func (f *FieldNode) Copy() Node {
+	return &FieldNode{tr: f.tr, NodeType: NodeField, Pos: f.Pos, Ident: append([]string{}, f.Ident...)}
+}
+
+// ChainNode holds a term followed by a chain of field accesses (identifier starting with '.').
+// The names may be chained ('.x.y').
+// The periods are dropped from each ident.
+type ChainNode struct {
+	NodeType
+	Pos
+	tr    *Tree
+	Node  Node
+	Field []string // The identifiers in lexical order.
+}
+
+func (t *Tree) newChain(pos Pos, node Node) *ChainNode {
+	return &ChainNode{tr: t, NodeType: NodeChain, Pos: pos, Node: node}
+}
+
+// Add adds the named field (which should start with a period) to the end of the chain.
+func (c *ChainNode) Add(field string) {
+	if len(field) == 0 || field[0] != '.' {
+		panic("no dot in field")
+	}
+	field = field[1:] // Remove leading dot.
+	if field == "" {
+		panic("empty field")
+	}
+	c.Field = append(c.Field, field)
+}
+
+func (c *ChainNode) String() string {
+	s := c.Node.String()
+	if _, ok := c.Node.(*PipeNode); ok {
+		s = "(" + s + ")"
+	}
+	for _, field := range c.Field {
+		s += "." + field
+	}
+	return s
+}
+
+func (c *ChainNode) tree() *Tree {
+	return c.tr
+}
+
+func (c *ChainNode) Copy() Node {
+	return &ChainNode{tr: c.tr, NodeType: NodeChain, Pos: c.Pos, Node: c.Node, Field: append([]string{}, c.Field...)}
+}
+
+// BoolNode holds a boolean constant.
+type BoolNode struct {
+	NodeType
+	Pos
+	tr   *Tree
+	True bool // The value of the boolean constant.
+}
+
+func (t *Tree) newBool(pos Pos, true bool) *BoolNode {
+	return &BoolNode{tr: t, NodeType: NodeBool, Pos: pos, True: true}
+}
+
+func (b *BoolNode) String() string {
+	if b.True {
+		return "true"
+	}
+	return "false"
+}
+
+func (b *BoolNode) tree() *Tree {
+	return b.tr
+}
+
+func (b *BoolNode) Copy() Node {
+	return b.tr.newBool(b.Pos, b.True)
+}
+
+// NumberNode holds a number: signed or unsigned integer, float, or complex.
+// The value is parsed and stored under all the types that can represent the value.
+// This simulates in a small amount of code the behavior of Go's ideal constants.
+type NumberNode struct {
+	NodeType
+	Pos
+	tr         *Tree
+	IsInt      bool       // Number has an integral value.
+	IsUint     bool       // Number has an unsigned integral value.
+	IsFloat    bool       // Number has a floating-point value.
+	IsComplex  bool       // Number is complex.
+	Int64      int64      // The signed integer value.
+	Uint64     uint64     // The unsigned integer value.
+	Float64    float64    // The floating-point value.
+	Complex128 complex128 // The complex value.
+	Text       string     // The original textual representation from the input.
+}
+
+func (t *Tree) newNumber(pos Pos, text string, typ itemType) (*NumberNode, error) {
+	n := &NumberNode{tr: t, NodeType: NodeNumber, Pos: pos, Text: text}
+	switch typ {
+	case itemCharConstant:
+		rune, _, tail, err := strconv.UnquoteChar(text[1:], text[0])
+		if err != nil {
+			return nil, err
+		}
+		if tail != "'" {
+			return nil, fmt.Errorf("malformed character constant: %s", text)
+		}
+		n.Int64 = int64(rune)
+		n.IsInt = true
+		n.Uint64 = uint64(rune)
+		n.IsUint = true
+		n.Float64 = float64(rune) // odd but those are the rules.
+		n.IsFloat = true
+		return n, nil
+	case itemComplex:
+		// fmt.Sscan can parse the pair, so let it do the work.
+		if _, err := fmt.Sscan(text, &n.Complex128); err != nil {
+			return nil, err
+		}
+		n.IsComplex = true
+		n.simplifyComplex()
+		return n, nil
+	}
+	// Imaginary constants can only be complex unless they are zero.
+	if len(text) > 0 && text[len(text)-1] == 'i' {
+		f, err := strconv.ParseFloat(text[:len(text)-1], 64)
+		if err == nil {
+			n.IsComplex = true
+			n.Complex128 = complex(0, f)
+			n.simplifyComplex()
+			return n, nil
+		}
+	}
+	// Do integer test first so we get 0x123 etc.
+	u, err := strconv.ParseUint(text, 0, 64) // will fail for -0; fixed below.
+	if err == nil {
+		n.IsUint = true
+		n.Uint64 = u
+	}
+	i, err := strconv.ParseInt(text, 0, 64)
+	if err == nil {
+		n.IsInt = true
+		n.Int64 = i
+		if i == 0 {
+			n.IsUint = true // in case of -0.
+			n.Uint64 = u
+		}
+	}
+	// If an integer extraction succeeded, promote the float.
+	if n.IsInt {
+		n.IsFloat = true
+		n.Float64 = float64(n.Int64)
+	} else if n.IsUint {
+		n.IsFloat = true
+		n.Float64 = float64(n.Uint64)
+	} else {
+		f, err := strconv.ParseFloat(text, 64)
+		if err == nil {
+			n.IsFloat = true
+			n.Float64 = f
+			// If a floating-point extraction succeeded, extract the int if needed.
+			if !n.IsInt && float64(int64(f)) == f {
+				n.IsInt = true
+				n.Int64 = int64(f)
+			}
+			if !n.IsUint && float64(uint64(f)) == f {
+				n.IsUint = true
+				n.Uint64 = uint64(f)
+			}
+		}
+	}
+	if !n.IsInt && !n.IsUint && !n.IsFloat {
+		return nil, fmt.Errorf("illegal number syntax: %q", text)
+	}
+	return n, nil
+}
+
+// simplifyComplex pulls out any other types that are represented by the complex number.
+// These all require that the imaginary part be zero.
+func (n *NumberNode) simplifyComplex() {
+	n.IsFloat = imag(n.Complex128) == 0
+	if n.IsFloat {
+		n.Float64 = real(n.Complex128)
+		n.IsInt = float64(int64(n.Float64)) == n.Float64
+		if n.IsInt {
+			n.Int64 = int64(n.Float64)
+		}
+		n.IsUint = float64(uint64(n.Float64)) == n.Float64
+		if n.IsUint {
+			n.Uint64 = uint64(n.Float64)
+		}
+	}
+}
+
+func (n *NumberNode) String() string {
+	return n.Text
+}
+
+func (n *NumberNode) tree() *Tree {
+	return n.tr
+}
+
+func (n *NumberNode) Copy() Node {
+	nn := new(NumberNode)
+	*nn = *n // Easy, fast, correct.
+	return nn
+}
+
+// StringNode holds a string constant. The value has been "unquoted".
+type StringNode struct {
+	NodeType
+	Pos
+	tr     *Tree
+	Quoted string // The original text of the string, with quotes.
+	Text   string // The string, after quote processing.
+}
+
+func (t *Tree) newString(pos Pos, orig, text string) *StringNode {
+	return &StringNode{tr: t, NodeType: NodeString, Pos: pos, Quoted: orig, Text: text}
+}
+
+func (s *StringNode) String() string {
+	return s.Quoted
+}
+
+func (s *StringNode) tree() *Tree {
+	return s.tr
+}
+
+func (s *StringNode) Copy() Node {
+	return s.tr.newString(s.Pos, s.Quoted, s.Text)
+}
+
+// endNode represents an {{end}} action.
+// It does not appear in the final parse tree.
+type endNode struct {
+	NodeType
+	Pos
+	tr *Tree
+}
+
+func (t *Tree) newEnd(pos Pos) *endNode {
+	return &endNode{tr: t, NodeType: nodeEnd, Pos: pos}
+}
+
+func (e *endNode) String() string {
+	return "{{end}}"
+}
+
+func (e *endNode) tree() *Tree {
+	return e.tr
+}
+
+func (e *endNode) Copy() Node {
+	return e.tr.newEnd(e.Pos)
+}
+
+// elseNode represents an {{else}} action. Does not appear in the final tree.
+type elseNode struct {
+	NodeType
+	Pos
+	tr   *Tree
+	Line int // The line number in the input (deprecated; kept for compatibility)
+}
+
+func (t *Tree) newElse(pos Pos, line int) *elseNode {
+	return &elseNode{tr: t, NodeType: nodeElse, Pos: pos, Line: line}
+}
+
+func (e *elseNode) Type() NodeType {
+	return nodeElse
+}
+
+func (e *elseNode) String() string {
+	return "{{else}}"
+}
+
+func (e *elseNode) tree() *Tree {
+	return e.tr
+}
+
+func (e *elseNode) Copy() Node {
+	return e.tr.newElse(e.Pos, e.Line)
+}
+
+// BranchNode is the common representation of if, range, and with.
+type BranchNode struct {
+	NodeType
+	Pos
+	tr       *Tree
+	Line     int       // The line number in the input (deprecated; kept for compatibility)
+	Pipe     *PipeNode // The pipeline to be evaluated.
+	List     *ListNode // What to execute if the value is non-empty.
+	ElseList *ListNode // What to execute if the value is empty (nil if absent).
+}
+
+func (b *BranchNode) String() string {
+	name := ""
+	switch b.NodeType {
+	case NodeIf:
+		name = "if"
+	case NodeRange:
+		name = "range"
+	case NodeWith:
+		name = "with"
+	default:
+		panic("unknown branch type")
+	}
+	if b.ElseList != nil {
+		return fmt.Sprintf("{{%s %s}}%s{{else}}%s{{end}}", name, b.Pipe, b.List, b.ElseList)
+	}
+	return fmt.Sprintf("{{%s %s}}%s{{end}}", name, b.Pipe, b.List)
+}
+
+func (b *BranchNode) tree() *Tree {
+	return b.tr
+}
+
+func (b *BranchNode) Copy() Node {
+	switch b.NodeType {
+	case NodeIf:
+		return b.tr.newIf(b.Pos, b.Line, b.Pipe, b.List, b.ElseList)
+	case NodeRange:
+		return b.tr.newRange(b.Pos, b.Line, b.Pipe, b.List, b.ElseList)
+	case NodeWith:
+		return b.tr.newWith(b.Pos, b.Line, b.Pipe, b.List, b.ElseList)
+	default:
+		panic("unknown branch type")
+	}
+}
+
+// IfNode represents an {{if}} action and its commands.
+type IfNode struct {
+	BranchNode
+}
+
+func (t *Tree) newIf(pos Pos, line int, pipe *PipeNode, list, elseList *ListNode) *IfNode {
+	return &IfNode{BranchNode{tr: t, NodeType: NodeIf, Pos: pos, Line: line, Pipe: pipe, List: list, ElseList: elseList}}
+}
+
+func (i *IfNode) Copy() Node {
+	return i.tr.newIf(i.Pos, i.Line, i.Pipe.CopyPipe(), i.List.CopyList(), i.ElseList.CopyList())
+}
+
+// RangeNode represents a {{range}} action and its commands.
+type RangeNode struct {
+	BranchNode
+}
+
+func (t *Tree) newRange(pos Pos, line int, pipe *PipeNode, list, elseList *ListNode) *RangeNode {
+	return &RangeNode{BranchNode{tr: t, NodeType: NodeRange, Pos: pos, Line: line, Pipe: pipe, List: list, ElseList: elseList}}
+}
+
+func (r *RangeNode) Copy() Node {
+	return r.tr.newRange(r.Pos, r.Line, r.Pipe.CopyPipe(), r.List.CopyList(), r.ElseList.CopyList())
+}
+
+// WithNode represents a {{with}} action and its commands.
+type WithNode struct {
+	BranchNode
+}
+
+func (t *Tree) newWith(pos Pos, line int, pipe *PipeNode, list, elseList *ListNode) *WithNode {
+	return &WithNode{BranchNode{tr: t, NodeType: NodeWith, Pos: pos, Line: line, Pipe: pipe, List: list, ElseList: elseList}}
+}
+
+func (w *WithNode) Copy() Node {
+	return w.tr.newWith(w.Pos, w.Line, w.Pipe.CopyPipe(), w.List.CopyList(), w.ElseList.CopyList())
+}
+
+// TemplateNode represents a {{template}} action.
+type TemplateNode struct {
+	NodeType
+	Pos
+	tr   *Tree
+	Line int       // The line number in the input (deprecated; kept for compatibility)
+	Name string    // The name of the template (unquoted).
+	Pipe *PipeNode // The command to evaluate as dot for the template.
+}
+
+func (t *Tree) newTemplate(pos Pos, line int, name string, pipe *PipeNode) *TemplateNode {
+	return &TemplateNode{tr: t, NodeType: NodeTemplate, Pos: pos, Line: line, Name: name, Pipe: pipe}
+}
+
+func (t *TemplateNode) String() string {
+	if t.Pipe == nil {
+		return fmt.Sprintf("{{template %q}}", t.Name)
+	}
+	return fmt.Sprintf("{{template %q %s}}", t.Name, t.Pipe)
+}
+
+func (t *TemplateNode) tree() *Tree {
+	return t.tr
+}
+
+func (t *TemplateNode) Copy() Node {
+	return t.tr.newTemplate(t.Pos, t.Line, t.Name, t.Pipe.CopyPipe())
+}
diff --git a/src/text/template/parse/parse.go b/src/text/template/parse/parse.go
new file mode 100644
index 0000000..af33880
--- /dev/null
+++ b/src/text/template/parse/parse.go
@@ -0,0 +1,677 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package parse builds parse trees for templates as defined by text/template
+// and html/template. Clients should use those packages to construct templates
+// rather than this one, which provides shared internal data structures not
+// intended for general use.
+package parse
+
+import (
+	"bytes"
+	"fmt"
+	"runtime"
+	"strconv"
+	"strings"
+)
+
+// Tree is the representation of a single parsed template.
+type Tree struct {
+	Name      string    // name of the template represented by the tree.
+	ParseName string    // name of the top-level template during parsing, for error messages.
+	Root      *ListNode // top-level root of the tree.
+	text      string    // text parsed to create the template (or its parent)
+	// Parsing only; cleared after parse.
+	funcs     []map[string]interface{}
+	lex       *lexer
+	token     [3]item // three-token lookahead for parser.
+	peekCount int
+	vars      []string // variables defined at the moment.
+}
+
+// Copy returns a copy of the Tree. Any parsing state is discarded.
+func (t *Tree) Copy() *Tree {
+	if t == nil {
+		return nil
+	}
+	return &Tree{
+		Name:      t.Name,
+		ParseName: t.ParseName,
+		Root:      t.Root.CopyList(),
+		text:      t.text,
+	}
+}
+
+// Parse returns a map from template name to parse.Tree, created by parsing the
+// templates described in the argument string. The top-level template will be
+// given the specified name. If an error is encountered, parsing stops and an
+// empty map is returned with the error.
+func Parse(name, text, leftDelim, rightDelim string, funcs ...map[string]interface{}) (treeSet map[string]*Tree, err error) {
+	treeSet = make(map[string]*Tree)
+	t := New(name)
+	t.text = text
+	_, err = t.Parse(text, leftDelim, rightDelim, treeSet, funcs...)
+	return
+}
+
+// next returns the next token.
+func (t *Tree) next() item {
+	if t.peekCount > 0 {
+		t.peekCount--
+	} else {
+		t.token[0] = t.lex.nextItem()
+	}
+	return t.token[t.peekCount]
+}
+
+// backup backs the input stream up one token.
+func (t *Tree) backup() {
+	t.peekCount++
+}
+
+// backup2 backs the input stream up two tokens.
+// The zeroth token is already there.
+func (t *Tree) backup2(t1 item) {
+	t.token[1] = t1
+	t.peekCount = 2
+}
+
+// backup3 backs the input stream up three tokens
+// The zeroth token is already there.
+func (t *Tree) backup3(t2, t1 item) { // Reverse order: we're pushing back.
+	t.token[1] = t1
+	t.token[2] = t2
+	t.peekCount = 3
+}
+
+// peek returns but does not consume the next token.
+func (t *Tree) peek() item {
+	if t.peekCount > 0 {
+		return t.token[t.peekCount-1]
+	}
+	t.peekCount = 1
+	t.token[0] = t.lex.nextItem()
+	return t.token[0]
+}
+
+// nextNonSpace returns the next non-space token.
+func (t *Tree) nextNonSpace() (token item) {
+	for {
+		token = t.next()
+		if token.typ != itemSpace {
+			break
+		}
+	}
+	return token
+}
+
+// peekNonSpace returns but does not consume the next non-space token.
+func (t *Tree) peekNonSpace() (token item) {
+	for {
+		token = t.next()
+		if token.typ != itemSpace {
+			break
+		}
+	}
+	t.backup()
+	return token
+}
+
+// Parsing.
+
+// New allocates a new parse tree with the given name.
+func New(name string, funcs ...map[string]interface{}) *Tree {
+	return &Tree{
+		Name:  name,
+		funcs: funcs,
+	}
+}
+
+// ErrorContext returns a textual representation of the location of the node in the input text.
+// The receiver is only used when the node does not have a pointer to the tree inside,
+// which can occur in old code.
+func (t *Tree) ErrorContext(n Node) (location, context string) {
+	pos := int(n.Position())
+	tree := n.tree()
+	if tree == nil {
+		tree = t
+	}
+	text := tree.text[:pos]
+	byteNum := strings.LastIndex(text, "\n")
+	if byteNum == -1 {
+		byteNum = pos // On first line.
+	} else {
+		byteNum++ // After the newline.
+		byteNum = pos - byteNum
+	}
+	lineNum := 1 + strings.Count(text, "\n")
+	context = n.String()
+	if len(context) > 20 {
+		context = fmt.Sprintf("%.20s...", context)
+	}
+	return fmt.Sprintf("%s:%d:%d", tree.ParseName, lineNum, byteNum), context
+}
+
+// errorf formats the error and terminates processing.
+func (t *Tree) errorf(format string, args ...interface{}) {
+	t.Root = nil
+	format = fmt.Sprintf("template: %s:%d: %s", t.ParseName, t.lex.lineNumber(), format)
+	panic(fmt.Errorf(format, args...))
+}
+
+// error terminates processing.
+func (t *Tree) error(err error) {
+	t.errorf("%s", err)
+}
+
+// expect consumes the next token and guarantees it has the required type.
+func (t *Tree) expect(expected itemType, context string) item {
+	token := t.nextNonSpace()
+	if token.typ != expected {
+		t.unexpected(token, context)
+	}
+	return token
+}
+
+// expectOneOf consumes the next token and guarantees it has one of the required types.
+func (t *Tree) expectOneOf(expected1, expected2 itemType, context string) item {
+	token := t.nextNonSpace()
+	if token.typ != expected1 && token.typ != expected2 {
+		t.unexpected(token, context)
+	}
+	return token
+}
+
+// unexpected complains about the token and terminates processing.
+func (t *Tree) unexpected(token item, context string) {
+	t.errorf("unexpected %s in %s", token, context)
+}
+
+// recover is the handler that turns panics into returns from the top level of Parse.
+func (t *Tree) recover(errp *error) {
+	e := recover()
+	if e != nil {
+		if _, ok := e.(runtime.Error); ok {
+			panic(e)
+		}
+		if t != nil {
+			t.stopParse()
+		}
+		*errp = e.(error)
+	}
+	return
+}
+
+// startParse initializes the parser, using the lexer.
+func (t *Tree) startParse(funcs []map[string]interface{}, lex *lexer) {
+	t.Root = nil
+	t.lex = lex
+	t.vars = []string{"$"}
+	t.funcs = funcs
+}
+
+// stopParse terminates parsing.
+func (t *Tree) stopParse() {
+	t.lex = nil
+	t.vars = nil
+	t.funcs = nil
+}
+
+// Parse parses the template definition string to construct a representation of
+// the template for execution. If either action delimiter string is empty, the
+// default ("{{" or "}}") is used. Embedded template definitions are added to
+// the treeSet map.
+func (t *Tree) Parse(text, leftDelim, rightDelim string, treeSet map[string]*Tree, funcs ...map[string]interface{}) (tree *Tree, err error) {
+	defer t.recover(&err)
+	t.ParseName = t.Name
+	t.startParse(funcs, lex(t.Name, text, leftDelim, rightDelim))
+	t.text = text
+	t.parse(treeSet)
+	t.add(treeSet)
+	t.stopParse()
+	return t, nil
+}
+
+// add adds tree to the treeSet.
+func (t *Tree) add(treeSet map[string]*Tree) {
+	tree := treeSet[t.Name]
+	if tree == nil || IsEmptyTree(tree.Root) {
+		treeSet[t.Name] = t
+		return
+	}
+	if !IsEmptyTree(t.Root) {
+		t.errorf("template: multiple definition of template %q", t.Name)
+	}
+}
+
+// IsEmptyTree reports whether this tree (node) is empty of everything but space.
+func IsEmptyTree(n Node) bool {
+	switch n := n.(type) {
+	case nil:
+		return true
+	case *ActionNode:
+	case *IfNode:
+	case *ListNode:
+		for _, node := range n.Nodes {
+			if !IsEmptyTree(node) {
+				return false
+			}
+		}
+		return true
+	case *RangeNode:
+	case *TemplateNode:
+	case *TextNode:
+		return len(bytes.TrimSpace(n.Text)) == 0
+	case *WithNode:
+	default:
+		panic("unknown node: " + n.String())
+	}
+	return false
+}
+
+// parse is the top-level parser for a template, essentially the same
+// as itemList except it also parses {{define}} actions.
+// It runs to EOF.
+func (t *Tree) parse(treeSet map[string]*Tree) (next Node) {
+	t.Root = t.newList(t.peek().pos)
+	for t.peek().typ != itemEOF {
+		if t.peek().typ == itemLeftDelim {
+			delim := t.next()
+			if t.nextNonSpace().typ == itemDefine {
+				newT := New("definition") // name will be updated once we know it.
+				newT.text = t.text
+				newT.ParseName = t.ParseName
+				newT.startParse(t.funcs, t.lex)
+				newT.parseDefinition(treeSet)
+				continue
+			}
+			t.backup2(delim)
+		}
+		n := t.textOrAction()
+		if n.Type() == nodeEnd {
+			t.errorf("unexpected %s", n)
+		}
+		t.Root.append(n)
+	}
+	return nil
+}
+
+// parseDefinition parses a {{define}} ...  {{end}} template definition and
+// installs the definition in the treeSet map.  The "define" keyword has already
+// been scanned.
+func (t *Tree) parseDefinition(treeSet map[string]*Tree) {
+	const context = "define clause"
+	name := t.expectOneOf(itemString, itemRawString, context)
+	var err error
+	t.Name, err = strconv.Unquote(name.val)
+	if err != nil {
+		t.error(err)
+	}
+	t.expect(itemRightDelim, context)
+	var end Node
+	t.Root, end = t.itemList()
+	if end.Type() != nodeEnd {
+		t.errorf("unexpected %s in %s", end, context)
+	}
+	t.add(treeSet)
+	t.stopParse()
+}
+
+// itemList:
+//	textOrAction*
+// Terminates at {{end}} or {{else}}, returned separately.
+func (t *Tree) itemList() (list *ListNode, next Node) {
+	list = t.newList(t.peekNonSpace().pos)
+	for t.peekNonSpace().typ != itemEOF {
+		n := t.textOrAction()
+		switch n.Type() {
+		case nodeEnd, nodeElse:
+			return list, n
+		}
+		list.append(n)
+	}
+	t.errorf("unexpected EOF")
+	return
+}
+
+// textOrAction:
+//	text | action
+func (t *Tree) textOrAction() Node {
+	switch token := t.nextNonSpace(); token.typ {
+	case itemText:
+		return t.newText(token.pos, token.val)
+	case itemLeftDelim:
+		return t.action()
+	default:
+		t.unexpected(token, "input")
+	}
+	return nil
+}
+
+// Action:
+//	control
+//	command ("|" command)*
+// Left delim is past. Now get actions.
+// First word could be a keyword such as range.
+func (t *Tree) action() (n Node) {
+	switch token := t.nextNonSpace(); token.typ {
+	case itemElse:
+		return t.elseControl()
+	case itemEnd:
+		return t.endControl()
+	case itemIf:
+		return t.ifControl()
+	case itemRange:
+		return t.rangeControl()
+	case itemTemplate:
+		return t.templateControl()
+	case itemWith:
+		return t.withControl()
+	}
+	t.backup()
+	// Do not pop variables; they persist until "end".
+	return t.newAction(t.peek().pos, t.lex.lineNumber(), t.pipeline("command"))
+}
+
+// Pipeline:
+//	declarations? command ('|' command)*
+func (t *Tree) pipeline(context string) (pipe *PipeNode) {
+	var decl []*VariableNode
+	pos := t.peekNonSpace().pos
+	// Are there declarations?
+	for {
+		if v := t.peekNonSpace(); v.typ == itemVariable {
+			t.next()
+			// Since space is a token, we need 3-token look-ahead here in the worst case:
+			// in "$x foo" we need to read "foo" (as opposed to ":=") to know that $x is an
+			// argument variable rather than a declaration. So remember the token
+			// adjacent to the variable so we can push it back if necessary.
+			tokenAfterVariable := t.peek()
+			if next := t.peekNonSpace(); next.typ == itemColonEquals || (next.typ == itemChar && next.val == ",") {
+				t.nextNonSpace()
+				variable := t.newVariable(v.pos, v.val)
+				decl = append(decl, variable)
+				t.vars = append(t.vars, v.val)
+				if next.typ == itemChar && next.val == "," {
+					if context == "range" && len(decl) < 2 {
+						continue
+					}
+					t.errorf("too many declarations in %s", context)
+				}
+			} else if tokenAfterVariable.typ == itemSpace {
+				t.backup3(v, tokenAfterVariable)
+			} else {
+				t.backup2(v)
+			}
+		}
+		break
+	}
+	pipe = t.newPipeline(pos, t.lex.lineNumber(), decl)
+	for {
+		switch token := t.nextNonSpace(); token.typ {
+		case itemRightDelim, itemRightParen:
+			if len(pipe.Cmds) == 0 {
+				t.errorf("missing value for %s", context)
+			}
+			if token.typ == itemRightParen {
+				t.backup()
+			}
+			return
+		case itemBool, itemCharConstant, itemComplex, itemDot, itemField, itemIdentifier,
+			itemNumber, itemNil, itemRawString, itemString, itemVariable, itemLeftParen:
+			t.backup()
+			pipe.append(t.command())
+		default:
+			t.unexpected(token, context)
+		}
+	}
+}
+
+func (t *Tree) parseControl(allowElseIf bool, context string) (pos Pos, line int, pipe *PipeNode, list, elseList *ListNode) {
+	defer t.popVars(len(t.vars))
+	line = t.lex.lineNumber()
+	pipe = t.pipeline(context)
+	var next Node
+	list, next = t.itemList()
+	switch next.Type() {
+	case nodeEnd: //done
+	case nodeElse:
+		if allowElseIf {
+			// Special case for "else if". If the "else" is followed immediately by an "if",
+			// the elseControl will have left the "if" token pending. Treat
+			//	{{if a}}_{{else if b}}_{{end}}
+			// as
+			//	{{if a}}_{{else}}{{if b}}_{{end}}{{end}}.
+			// To do this, parse the if as usual and stop at it {{end}}; the subsequent{{end}}
+			// is assumed. This technique works even for long if-else-if chains.
+			// TODO: Should we allow else-if in with and range?
+			if t.peek().typ == itemIf {
+				t.next() // Consume the "if" token.
+				elseList = t.newList(next.Position())
+				elseList.append(t.ifControl())
+				// Do not consume the next item - only one {{end}} required.
+				break
+			}
+		}
+		elseList, next = t.itemList()
+		if next.Type() != nodeEnd {
+			t.errorf("expected end; found %s", next)
+		}
+	}
+	return pipe.Position(), line, pipe, list, elseList
+}
+
+// If:
+//	{{if pipeline}} itemList {{end}}
+//	{{if pipeline}} itemList {{else}} itemList {{end}}
+// If keyword is past.
+func (t *Tree) ifControl() Node {
+	return t.newIf(t.parseControl(true, "if"))
+}
+
+// Range:
+//	{{range pipeline}} itemList {{end}}
+//	{{range pipeline}} itemList {{else}} itemList {{end}}
+// Range keyword is past.
+func (t *Tree) rangeControl() Node {
+	return t.newRange(t.parseControl(false, "range"))
+}
+
+// With:
+//	{{with pipeline}} itemList {{end}}
+//	{{with pipeline}} itemList {{else}} itemList {{end}}
+// If keyword is past.
+func (t *Tree) withControl() Node {
+	return t.newWith(t.parseControl(false, "with"))
+}
+
+// End:
+//	{{end}}
+// End keyword is past.
+func (t *Tree) endControl() Node {
+	return t.newEnd(t.expect(itemRightDelim, "end").pos)
+}
+
+// Else:
+//	{{else}}
+// Else keyword is past.
+func (t *Tree) elseControl() Node {
+	// Special case for "else if".
+	peek := t.peekNonSpace()
+	if peek.typ == itemIf {
+		// We see "{{else if ... " but in effect rewrite it to {{else}}{{if ... ".
+		return t.newElse(peek.pos, t.lex.lineNumber())
+	}
+	return t.newElse(t.expect(itemRightDelim, "else").pos, t.lex.lineNumber())
+}
+
+// Template:
+//	{{template stringValue pipeline}}
+// Template keyword is past.  The name must be something that can evaluate
+// to a string.
+func (t *Tree) templateControl() Node {
+	var name string
+	token := t.nextNonSpace()
+	switch token.typ {
+	case itemString, itemRawString:
+		s, err := strconv.Unquote(token.val)
+		if err != nil {
+			t.error(err)
+		}
+		name = s
+	default:
+		t.unexpected(token, "template invocation")
+	}
+	var pipe *PipeNode
+	if t.nextNonSpace().typ != itemRightDelim {
+		t.backup()
+		// Do not pop variables; they persist until "end".
+		pipe = t.pipeline("template")
+	}
+	return t.newTemplate(token.pos, t.lex.lineNumber(), name, pipe)
+}
+
+// command:
+//	operand (space operand)*
+// space-separated arguments up to a pipeline character or right delimiter.
+// we consume the pipe character but leave the right delim to terminate the action.
+func (t *Tree) command() *CommandNode {
+	cmd := t.newCommand(t.peekNonSpace().pos)
+	for {
+		t.peekNonSpace() // skip leading spaces.
+		operand := t.operand()
+		if operand != nil {
+			cmd.append(operand)
+		}
+		switch token := t.next(); token.typ {
+		case itemSpace:
+			continue
+		case itemError:
+			t.errorf("%s", token.val)
+		case itemRightDelim, itemRightParen:
+			t.backup()
+		case itemPipe:
+		default:
+			t.errorf("unexpected %s in operand; missing space?", token)
+		}
+		break
+	}
+	if len(cmd.Args) == 0 {
+		t.errorf("empty command")
+	}
+	return cmd
+}
+
+// operand:
+//	term .Field*
+// An operand is a space-separated component of a command,
+// a term possibly followed by field accesses.
+// A nil return means the next item is not an operand.
+func (t *Tree) operand() Node {
+	node := t.term()
+	if node == nil {
+		return nil
+	}
+	if t.peek().typ == itemField {
+		chain := t.newChain(t.peek().pos, node)
+		for t.peek().typ == itemField {
+			chain.Add(t.next().val)
+		}
+		// Compatibility with original API: If the term is of type NodeField
+		// or NodeVariable, just put more fields on the original.
+		// Otherwise, keep the Chain node.
+		// TODO: Switch to Chains always when we can.
+		switch node.Type() {
+		case NodeField:
+			node = t.newField(chain.Position(), chain.String())
+		case NodeVariable:
+			node = t.newVariable(chain.Position(), chain.String())
+		default:
+			node = chain
+		}
+	}
+	return node
+}
+
+// term:
+//	literal (number, string, nil, boolean)
+//	function (identifier)
+//	.
+//	.Field
+//	$
+//	'(' pipeline ')'
+// A term is a simple "expression".
+// A nil return means the next item is not a term.
+func (t *Tree) term() Node {
+	switch token := t.nextNonSpace(); token.typ {
+	case itemError:
+		t.errorf("%s", token.val)
+	case itemIdentifier:
+		if !t.hasFunction(token.val) {
+			t.errorf("function %q not defined", token.val)
+		}
+		return NewIdentifier(token.val).SetTree(t).SetPos(token.pos)
+	case itemDot:
+		return t.newDot(token.pos)
+	case itemNil:
+		return t.newNil(token.pos)
+	case itemVariable:
+		return t.useVar(token.pos, token.val)
+	case itemField:
+		return t.newField(token.pos, token.val)
+	case itemBool:
+		return t.newBool(token.pos, token.val == "true")
+	case itemCharConstant, itemComplex, itemNumber:
+		number, err := t.newNumber(token.pos, token.val, token.typ)
+		if err != nil {
+			t.error(err)
+		}
+		return number
+	case itemLeftParen:
+		pipe := t.pipeline("parenthesized pipeline")
+		if token := t.next(); token.typ != itemRightParen {
+			t.errorf("unclosed right paren: unexpected %s", token)
+		}
+		return pipe
+	case itemString, itemRawString:
+		s, err := strconv.Unquote(token.val)
+		if err != nil {
+			t.error(err)
+		}
+		return t.newString(token.pos, token.val, s)
+	}
+	t.backup()
+	return nil
+}
+
+// hasFunction reports if a function name exists in the Tree's maps.
+func (t *Tree) hasFunction(name string) bool {
+	for _, funcMap := range t.funcs {
+		if funcMap == nil {
+			continue
+		}
+		if funcMap[name] != nil {
+			return true
+		}
+	}
+	return false
+}
+
+// popVars trims the variable list to the specified length
+func (t *Tree) popVars(n int) {
+	t.vars = t.vars[:n]
+}
+
+// useVar returns a node for a variable reference. It errors if the
+// variable is not defined.
+func (t *Tree) useVar(pos Pos, name string) Node {
+	v := t.newVariable(pos, name)
+	for _, varName := range t.vars {
+		if varName == v.Ident[0] {
+			return v
+		}
+	}
+	t.errorf("undefined variable %q", v.Ident[0])
+	return nil
+}
diff --git a/src/text/template/parse/parse_test.go b/src/text/template/parse/parse_test.go
new file mode 100644
index 0000000..4a504fa
--- /dev/null
+++ b/src/text/template/parse/parse_test.go
@@ -0,0 +1,423 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package parse
+
+import (
+	"flag"
+	"fmt"
+	"strings"
+	"testing"
+)
+
+var debug = flag.Bool("debug", false, "show the errors produced by the main tests")
+
+type numberTest struct {
+	text      string
+	isInt     bool
+	isUint    bool
+	isFloat   bool
+	isComplex bool
+	int64
+	uint64
+	float64
+	complex128
+}
+
+var numberTests = []numberTest{
+	// basics
+	{"0", true, true, true, false, 0, 0, 0, 0},
+	{"-0", true, true, true, false, 0, 0, 0, 0}, // check that -0 is a uint.
+	{"73", true, true, true, false, 73, 73, 73, 0},
+	{"073", true, true, true, false, 073, 073, 073, 0},
+	{"0x73", true, true, true, false, 0x73, 0x73, 0x73, 0},
+	{"-73", true, false, true, false, -73, 0, -73, 0},
+	{"+73", true, false, true, false, 73, 0, 73, 0},
+	{"100", true, true, true, false, 100, 100, 100, 0},
+	{"1e9", true, true, true, false, 1e9, 1e9, 1e9, 0},
+	{"-1e9", true, false, true, false, -1e9, 0, -1e9, 0},
+	{"-1.2", false, false, true, false, 0, 0, -1.2, 0},
+	{"1e19", false, true, true, false, 0, 1e19, 1e19, 0},
+	{"-1e19", false, false, true, false, 0, 0, -1e19, 0},
+	{"4i", false, false, false, true, 0, 0, 0, 4i},
+	{"-1.2+4.2i", false, false, false, true, 0, 0, 0, -1.2 + 4.2i},
+	{"073i", false, false, false, true, 0, 0, 0, 73i}, // not octal!
+	// complex with 0 imaginary are float (and maybe integer)
+	{"0i", true, true, true, true, 0, 0, 0, 0},
+	{"-1.2+0i", false, false, true, true, 0, 0, -1.2, -1.2},
+	{"-12+0i", true, false, true, true, -12, 0, -12, -12},
+	{"13+0i", true, true, true, true, 13, 13, 13, 13},
+	// funny bases
+	{"0123", true, true, true, false, 0123, 0123, 0123, 0},
+	{"-0x0", true, true, true, false, 0, 0, 0, 0},
+	{"0xdeadbeef", true, true, true, false, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0},
+	// character constants
+	{`'a'`, true, true, true, false, 'a', 'a', 'a', 0},
+	{`'\n'`, true, true, true, false, '\n', '\n', '\n', 0},
+	{`'\\'`, true, true, true, false, '\\', '\\', '\\', 0},
+	{`'\''`, true, true, true, false, '\'', '\'', '\'', 0},
+	{`'\xFF'`, true, true, true, false, 0xFF, 0xFF, 0xFF, 0},
+	{`'パ'`, true, true, true, false, 0x30d1, 0x30d1, 0x30d1, 0},
+	{`'\u30d1'`, true, true, true, false, 0x30d1, 0x30d1, 0x30d1, 0},
+	{`'\U000030d1'`, true, true, true, false, 0x30d1, 0x30d1, 0x30d1, 0},
+	// some broken syntax
+	{text: "+-2"},
+	{text: "0x123."},
+	{text: "1e."},
+	{text: "0xi."},
+	{text: "1+2."},
+	{text: "'x"},
+	{text: "'xx'"},
+	// Issue 8622 - 0xe parsed as floating point. Very embarrassing.
+	{"0xef", true, true, true, false, 0xef, 0xef, 0xef, 0},
+}
+
+func TestNumberParse(t *testing.T) {
+	for _, test := range numberTests {
+		// If fmt.Sscan thinks it's complex, it's complex.  We can't trust the output
+		// because imaginary comes out as a number.
+		var c complex128
+		typ := itemNumber
+		var tree *Tree
+		if test.text[0] == '\'' {
+			typ = itemCharConstant
+		} else {
+			_, err := fmt.Sscan(test.text, &c)
+			if err == nil {
+				typ = itemComplex
+			}
+		}
+		n, err := tree.newNumber(0, test.text, typ)
+		ok := test.isInt || test.isUint || test.isFloat || test.isComplex
+		if ok && err != nil {
+			t.Errorf("unexpected error for %q: %s", test.text, err)
+			continue
+		}
+		if !ok && err == nil {
+			t.Errorf("expected error for %q", test.text)
+			continue
+		}
+		if !ok {
+			if *debug {
+				fmt.Printf("%s\n\t%s\n", test.text, err)
+			}
+			continue
+		}
+		if n.IsComplex != test.isComplex {
+			t.Errorf("complex incorrect for %q; should be %t", test.text, test.isComplex)
+		}
+		if test.isInt {
+			if !n.IsInt {
+				t.Errorf("expected integer for %q", test.text)
+			}
+			if n.Int64 != test.int64 {
+				t.Errorf("int64 for %q should be %d Is %d", test.text, test.int64, n.Int64)
+			}
+		} else if n.IsInt {
+			t.Errorf("did not expect integer for %q", test.text)
+		}
+		if test.isUint {
+			if !n.IsUint {
+				t.Errorf("expected unsigned integer for %q", test.text)
+			}
+			if n.Uint64 != test.uint64 {
+				t.Errorf("uint64 for %q should be %d Is %d", test.text, test.uint64, n.Uint64)
+			}
+		} else if n.IsUint {
+			t.Errorf("did not expect unsigned integer for %q", test.text)
+		}
+		if test.isFloat {
+			if !n.IsFloat {
+				t.Errorf("expected float for %q", test.text)
+			}
+			if n.Float64 != test.float64 {
+				t.Errorf("float64 for %q should be %g Is %g", test.text, test.float64, n.Float64)
+			}
+		} else if n.IsFloat {
+			t.Errorf("did not expect float for %q", test.text)
+		}
+		if test.isComplex {
+			if !n.IsComplex {
+				t.Errorf("expected complex for %q", test.text)
+			}
+			if n.Complex128 != test.complex128 {
+				t.Errorf("complex128 for %q should be %g Is %g", test.text, test.complex128, n.Complex128)
+			}
+		} else if n.IsComplex {
+			t.Errorf("did not expect complex for %q", test.text)
+		}
+	}
+}
+
+type parseTest struct {
+	name   string
+	input  string
+	ok     bool
+	result string // what the user would see in an error message.
+}
+
+const (
+	noError  = true
+	hasError = false
+)
+
+var parseTests = []parseTest{
+	{"empty", "", noError,
+		``},
+	{"comment", "{{/*\n\n\n*/}}", noError,
+		``},
+	{"spaces", " \t\n", noError,
+		`" \t\n"`},
+	{"text", "some text", noError,
+		`"some text"`},
+	{"emptyAction", "{{}}", hasError,
+		`{{}}`},
+	{"field", "{{.X}}", noError,
+		`{{.X}}`},
+	{"simple command", "{{printf}}", noError,
+		`{{printf}}`},
+	{"$ invocation", "{{$}}", noError,
+		"{{$}}"},
+	{"variable invocation", "{{with $x := 3}}{{$x 23}}{{end}}", noError,
+		"{{with $x := 3}}{{$x 23}}{{end}}"},
+	{"variable with fields", "{{$.I}}", noError,
+		"{{$.I}}"},
+	{"multi-word command", "{{printf `%d` 23}}", noError,
+		"{{printf `%d` 23}}"},
+	{"pipeline", "{{.X|.Y}}", noError,
+		`{{.X | .Y}}`},
+	{"pipeline with decl", "{{$x := .X|.Y}}", noError,
+		`{{$x := .X | .Y}}`},
+	{"nested pipeline", "{{.X (.Y .Z) (.A | .B .C) (.E)}}", noError,
+		`{{.X (.Y .Z) (.A | .B .C) (.E)}}`},
+	{"field applied to parentheses", "{{(.Y .Z).Field}}", noError,
+		`{{(.Y .Z).Field}}`},
+	{"simple if", "{{if .X}}hello{{end}}", noError,
+		`{{if .X}}"hello"{{end}}`},
+	{"if with else", "{{if .X}}true{{else}}false{{end}}", noError,
+		`{{if .X}}"true"{{else}}"false"{{end}}`},
+	{"if with else if", "{{if .X}}true{{else if .Y}}false{{end}}", noError,
+		`{{if .X}}"true"{{else}}{{if .Y}}"false"{{end}}{{end}}`},
+	{"if else chain", "+{{if .X}}X{{else if .Y}}Y{{else if .Z}}Z{{end}}+", noError,
+		`"+"{{if .X}}"X"{{else}}{{if .Y}}"Y"{{else}}{{if .Z}}"Z"{{end}}{{end}}{{end}}"+"`},
+	{"simple range", "{{range .X}}hello{{end}}", noError,
+		`{{range .X}}"hello"{{end}}`},
+	{"chained field range", "{{range .X.Y.Z}}hello{{end}}", noError,
+		`{{range .X.Y.Z}}"hello"{{end}}`},
+	{"nested range", "{{range .X}}hello{{range .Y}}goodbye{{end}}{{end}}", noError,
+		`{{range .X}}"hello"{{range .Y}}"goodbye"{{end}}{{end}}`},
+	{"range with else", "{{range .X}}true{{else}}false{{end}}", noError,
+		`{{range .X}}"true"{{else}}"false"{{end}}`},
+	{"range over pipeline", "{{range .X|.M}}true{{else}}false{{end}}", noError,
+		`{{range .X | .M}}"true"{{else}}"false"{{end}}`},
+	{"range []int", "{{range .SI}}{{.}}{{end}}", noError,
+		`{{range .SI}}{{.}}{{end}}`},
+	{"range 1 var", "{{range $x := .SI}}{{.}}{{end}}", noError,
+		`{{range $x := .SI}}{{.}}{{end}}`},
+	{"range 2 vars", "{{range $x, $y := .SI}}{{.}}{{end}}", noError,
+		`{{range $x, $y := .SI}}{{.}}{{end}}`},
+	{"constants", "{{range .SI 1 -3.2i true false 'a' nil}}{{end}}", noError,
+		`{{range .SI 1 -3.2i true false 'a' nil}}{{end}}`},
+	{"template", "{{template `x`}}", noError,
+		`{{template "x"}}`},
+	{"template with arg", "{{template `x` .Y}}", noError,
+		`{{template "x" .Y}}`},
+	{"with", "{{with .X}}hello{{end}}", noError,
+		`{{with .X}}"hello"{{end}}`},
+	{"with with else", "{{with .X}}hello{{else}}goodbye{{end}}", noError,
+		`{{with .X}}"hello"{{else}}"goodbye"{{end}}`},
+	// Errors.
+	{"unclosed action", "hello{{range", hasError, ""},
+	{"unmatched end", "{{end}}", hasError, ""},
+	{"missing end", "hello{{range .x}}", hasError, ""},
+	{"missing end after else", "hello{{range .x}}{{else}}", hasError, ""},
+	{"undefined function", "hello{{undefined}}", hasError, ""},
+	{"undefined variable", "{{$x}}", hasError, ""},
+	{"variable undefined after end", "{{with $x := 4}}{{end}}{{$x}}", hasError, ""},
+	{"variable undefined in template", "{{template $v}}", hasError, ""},
+	{"declare with field", "{{with $x.Y := 4}}{{end}}", hasError, ""},
+	{"template with field ref", "{{template .X}}", hasError, ""},
+	{"template with var", "{{template $v}}", hasError, ""},
+	{"invalid punctuation", "{{printf 3, 4}}", hasError, ""},
+	{"multidecl outside range", "{{with $v, $u := 3}}{{end}}", hasError, ""},
+	{"too many decls in range", "{{range $u, $v, $w := 3}}{{end}}", hasError, ""},
+	{"dot applied to parentheses", "{{printf (printf .).}}", hasError, ""},
+	{"adjacent args", "{{printf 3`x`}}", hasError, ""},
+	{"adjacent args with .", "{{printf `x`.}}", hasError, ""},
+	{"extra end after if", "{{if .X}}a{{else if .Y}}b{{end}}{{end}}", hasError, ""},
+	// Equals (and other chars) do not assignments make (yet).
+	{"bug0a", "{{$x := 0}}{{$x}}", noError, "{{$x := 0}}{{$x}}"},
+	{"bug0b", "{{$x = 1}}{{$x}}", hasError, ""},
+	{"bug0c", "{{$x ! 2}}{{$x}}", hasError, ""},
+	{"bug0d", "{{$x % 3}}{{$x}}", hasError, ""},
+	// Check the parse fails for := rather than comma.
+	{"bug0e", "{{range $x := $y := 3}}{{end}}", hasError, ""},
+	// Another bug: variable read must ignore following punctuation.
+	{"bug1a", "{{$x:=.}}{{$x!2}}", hasError, ""},                     // ! is just illegal here.
+	{"bug1b", "{{$x:=.}}{{$x+2}}", hasError, ""},                     // $x+2 should not parse as ($x) (+2).
+	{"bug1c", "{{$x:=.}}{{$x +2}}", noError, "{{$x := .}}{{$x +2}}"}, // It's OK with a space.
+}
+
+var builtins = map[string]interface{}{
+	"printf": fmt.Sprintf,
+}
+
+func testParse(doCopy bool, t *testing.T) {
+	textFormat = "%q"
+	defer func() { textFormat = "%s" }()
+	for _, test := range parseTests {
+		tmpl, err := New(test.name).Parse(test.input, "", "", make(map[string]*Tree), builtins)
+		switch {
+		case err == nil && !test.ok:
+			t.Errorf("%q: expected error; got none", test.name)
+			continue
+		case err != nil && test.ok:
+			t.Errorf("%q: unexpected error: %v", test.name, err)
+			continue
+		case err != nil && !test.ok:
+			// expected error, got one
+			if *debug {
+				fmt.Printf("%s: %s\n\t%s\n", test.name, test.input, err)
+			}
+			continue
+		}
+		var result string
+		if doCopy {
+			result = tmpl.Root.Copy().String()
+		} else {
+			result = tmpl.Root.String()
+		}
+		if result != test.result {
+			t.Errorf("%s=(%q): got\n\t%v\nexpected\n\t%v", test.name, test.input, result, test.result)
+		}
+	}
+}
+
+func TestParse(t *testing.T) {
+	testParse(false, t)
+}
+
+// Same as TestParse, but we copy the node first
+func TestParseCopy(t *testing.T) {
+	testParse(true, t)
+}
+
+type isEmptyTest struct {
+	name  string
+	input string
+	empty bool
+}
+
+var isEmptyTests = []isEmptyTest{
+	{"empty", ``, true},
+	{"nonempty", `hello`, false},
+	{"spaces only", " \t\n \t\n", true},
+	{"definition", `{{define "x"}}something{{end}}`, true},
+	{"definitions and space", "{{define `x`}}something{{end}}\n\n{{define `y`}}something{{end}}\n\n", true},
+	{"definitions and text", "{{define `x`}}something{{end}}\nx\n{{define `y`}}something{{end}}\ny\n", false},
+	{"definition and action", "{{define `x`}}something{{end}}{{if 3}}foo{{end}}", false},
+}
+
+func TestIsEmpty(t *testing.T) {
+	if !IsEmptyTree(nil) {
+		t.Errorf("nil tree is not empty")
+	}
+	for _, test := range isEmptyTests {
+		tree, err := New("root").Parse(test.input, "", "", make(map[string]*Tree), nil)
+		if err != nil {
+			t.Errorf("%q: unexpected error: %v", test.name, err)
+			continue
+		}
+		if empty := IsEmptyTree(tree.Root); empty != test.empty {
+			t.Errorf("%q: expected %t got %t", test.name, test.empty, empty)
+		}
+	}
+}
+
+func TestErrorContextWithTreeCopy(t *testing.T) {
+	tree, err := New("root").Parse("{{if true}}{{end}}", "", "", make(map[string]*Tree), nil)
+	if err != nil {
+		t.Fatalf("unexpected tree parse failure: %v", err)
+	}
+	treeCopy := tree.Copy()
+	wantLocation, wantContext := tree.ErrorContext(tree.Root.Nodes[0])
+	gotLocation, gotContext := treeCopy.ErrorContext(treeCopy.Root.Nodes[0])
+	if wantLocation != gotLocation {
+		t.Errorf("wrong error location want %q got %q", wantLocation, gotLocation)
+	}
+	if wantContext != gotContext {
+		t.Errorf("wrong error location want %q got %q", wantContext, gotContext)
+	}
+}
+
+// All failures, and the result is a string that must appear in the error message.
+var errorTests = []parseTest{
+	// Check line numbers are accurate.
+	{"unclosed1",
+		"line1\n{{",
+		hasError, `unclosed1:2: unexpected unclosed action in command`},
+	{"unclosed2",
+		"line1\n{{define `x`}}line2\n{{",
+		hasError, `unclosed2:3: unexpected unclosed action in command`},
+	// Specific errors.
+	{"function",
+		"{{foo}}",
+		hasError, `function "foo" not defined`},
+	{"comment",
+		"{{/*}}",
+		hasError, `unclosed comment`},
+	{"lparen",
+		"{{.X (1 2 3}}",
+		hasError, `unclosed left paren`},
+	{"rparen",
+		"{{.X 1 2 3)}}",
+		hasError, `unexpected ")"`},
+	{"space",
+		"{{`x`3}}",
+		hasError, `missing space?`},
+	{"idchar",
+		"{{a#}}",
+		hasError, `'#'`},
+	{"charconst",
+		"{{'a}}",
+		hasError, `unterminated character constant`},
+	{"stringconst",
+		`{{"a}}`,
+		hasError, `unterminated quoted string`},
+	{"rawstringconst",
+		"{{`a}}",
+		hasError, `unterminated raw quoted string`},
+	{"number",
+		"{{0xi}}",
+		hasError, `number syntax`},
+	{"multidefine",
+		"{{define `a`}}a{{end}}{{define `a`}}b{{end}}",
+		hasError, `multiple definition of template`},
+	{"eof",
+		"{{range .X}}",
+		hasError, `unexpected EOF`},
+	{"variable",
+		// Declare $x so it's defined, to avoid that error, and then check we don't parse a declaration.
+		"{{$x := 23}}{{with $x.y := 3}}{{$x 23}}{{end}}",
+		hasError, `unexpected ":="`},
+	{"multidecl",
+		"{{$a,$b,$c := 23}}",
+		hasError, `too many declarations`},
+	{"undefvar",
+		"{{$a}}",
+		hasError, `undefined variable`},
+}
+
+func TestErrors(t *testing.T) {
+	for _, test := range errorTests {
+		_, err := New(test.name).Parse(test.input, "", "", make(map[string]*Tree))
+		if err == nil {
+			t.Errorf("%q: expected error", test.name)
+			continue
+		}
+		if !strings.Contains(err.Error(), test.result) {
+			t.Errorf("%q: error %q does not contain %q", test.name, err, test.result)
+		}
+	}
+}
diff --git a/src/pkg/text/template/template.go b/src/text/template/template.go
similarity index 100%
rename from src/pkg/text/template/template.go
rename to src/text/template/template.go
diff --git a/src/pkg/text/template/testdata/file1.tmpl b/src/text/template/testdata/file1.tmpl
similarity index 100%
rename from src/pkg/text/template/testdata/file1.tmpl
rename to src/text/template/testdata/file1.tmpl
diff --git a/src/pkg/text/template/testdata/file2.tmpl b/src/text/template/testdata/file2.tmpl
similarity index 100%
rename from src/pkg/text/template/testdata/file2.tmpl
rename to src/text/template/testdata/file2.tmpl
diff --git a/src/pkg/text/template/testdata/tmpl1.tmpl b/src/text/template/testdata/tmpl1.tmpl
similarity index 100%
rename from src/pkg/text/template/testdata/tmpl1.tmpl
rename to src/text/template/testdata/tmpl1.tmpl
diff --git a/src/pkg/text/template/testdata/tmpl2.tmpl b/src/text/template/testdata/tmpl2.tmpl
similarity index 100%
rename from src/pkg/text/template/testdata/tmpl2.tmpl
rename to src/text/template/testdata/tmpl2.tmpl
diff --git a/src/time/example_test.go b/src/time/example_test.go
new file mode 100644
index 0000000..a37e8b8
--- /dev/null
+++ b/src/time/example_test.go
@@ -0,0 +1,160 @@
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package time_test
+
+import (
+	"fmt"
+	"time"
+)
+
+func expensiveCall() {}
+
+func ExampleDuration() {
+	t0 := time.Now()
+	expensiveCall()
+	t1 := time.Now()
+	fmt.Printf("The call took %v to run.\n", t1.Sub(t0))
+}
+
+var c chan int
+
+func handle(int) {}
+
+func ExampleAfter() {
+	select {
+	case m := <-c:
+		handle(m)
+	case <-time.After(5 * time.Minute):
+		fmt.Println("timed out")
+	}
+}
+
+func ExampleSleep() {
+	time.Sleep(100 * time.Millisecond)
+}
+
+func statusUpdate() string { return "" }
+
+func ExampleTick() {
+	c := time.Tick(1 * time.Minute)
+	for now := range c {
+		fmt.Printf("%v %s\n", now, statusUpdate())
+	}
+}
+
+func ExampleMonth() {
+	_, month, day := time.Now().Date()
+	if month == time.November && day == 10 {
+		fmt.Println("Happy Go day!")
+	}
+}
+
+func ExampleDate() {
+	t := time.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC)
+	fmt.Printf("Go launched at %s\n", t.Local())
+	// Output: Go launched at 2009-11-10 15:00:00 -0800 PST
+}
+
+func ExampleTime_Format() {
+	// layout shows by example how the reference time should be represented.
+	const layout = "Jan 2, 2006 at 3:04pm (MST)"
+	t := time.Date(2009, time.November, 10, 15, 0, 0, 0, time.Local)
+	fmt.Println(t.Format(layout))
+	fmt.Println(t.UTC().Format(layout))
+	// Output:
+	// Nov 10, 2009 at 3:00pm (PST)
+	// Nov 10, 2009 at 11:00pm (UTC)
+}
+
+func ExampleParse() {
+	// longForm shows by example how the reference time would be represented in
+	// the desired layout.
+	const longForm = "Jan 2, 2006 at 3:04pm (MST)"
+	t, _ := time.Parse(longForm, "Feb 3, 2013 at 7:54pm (PST)")
+	fmt.Println(t)
+
+	// shortForm is another way the reference time would be represented
+	// in the desired layout; it has no time zone present.
+	// Note: without explicit zone, returns time in UTC.
+	const shortForm = "2006-Jan-02"
+	t, _ = time.Parse(shortForm, "2013-Feb-03")
+	fmt.Println(t)
+
+	// Output:
+	// 2013-02-03 19:54:00 -0800 PST
+	// 2013-02-03 00:00:00 +0000 UTC
+}
+
+func ExampleParseInLocation() {
+	loc, _ := time.LoadLocation("Europe/Berlin")
+
+	const longForm = "Jan 2, 2006 at 3:04pm (MST)"
+	t, _ := time.ParseInLocation(longForm, "Jul 9, 2012 at 5:02am (CEST)", loc)
+	fmt.Println(t)
+
+	// Note: without explicit zone, returns time in given location.
+	const shortForm = "2006-Jan-02"
+	t, _ = time.ParseInLocation(shortForm, "2012-Jul-09", loc)
+	fmt.Println(t)
+
+	// Output:
+	// 2012-07-09 05:02:00 +0200 CEST
+	// 2012-07-09 00:00:00 +0200 CEST
+}
+
+func ExampleTime_Round() {
+	t := time.Date(0, 0, 0, 12, 15, 30, 918273645, time.UTC)
+	round := []time.Duration{
+		time.Nanosecond,
+		time.Microsecond,
+		time.Millisecond,
+		time.Second,
+		2 * time.Second,
+		time.Minute,
+		10 * time.Minute,
+		time.Hour,
+	}
+
+	for _, d := range round {
+		fmt.Printf("t.Round(%6s) = %s\n", d, t.Round(d).Format("15:04:05.999999999"))
+	}
+	// Output:
+	// t.Round(   1ns) = 12:15:30.918273645
+	// t.Round(   1µs) = 12:15:30.918274
+	// t.Round(   1ms) = 12:15:30.918
+	// t.Round(    1s) = 12:15:31
+	// t.Round(    2s) = 12:15:30
+	// t.Round(  1m0s) = 12:16:00
+	// t.Round( 10m0s) = 12:20:00
+	// t.Round(1h0m0s) = 12:00:00
+}
+
+func ExampleTime_Truncate() {
+	t, _ := time.Parse("2006 Jan 02 15:04:05", "2012 Dec 07 12:15:30.918273645")
+	trunc := []time.Duration{
+		time.Nanosecond,
+		time.Microsecond,
+		time.Millisecond,
+		time.Second,
+		2 * time.Second,
+		time.Minute,
+		10 * time.Minute,
+		time.Hour,
+	}
+
+	for _, d := range trunc {
+		fmt.Printf("t.Truncate(%6s) = %s\n", d, t.Truncate(d).Format("15:04:05.999999999"))
+	}
+
+	// Output:
+	// t.Truncate(   1ns) = 12:15:30.918273645
+	// t.Truncate(   1µs) = 12:15:30.918273
+	// t.Truncate(   1ms) = 12:15:30.918
+	// t.Truncate(    1s) = 12:15:30
+	// t.Truncate(    2s) = 12:15:30
+	// t.Truncate(  1m0s) = 12:15:00
+	// t.Truncate( 10m0s) = 12:10:00
+	// t.Truncate(1h0m0s) = 12:00:00
+}
diff --git a/src/pkg/time/export_test.go b/src/time/export_test.go
similarity index 100%
rename from src/pkg/time/export_test.go
rename to src/time/export_test.go
diff --git a/src/pkg/time/export_windows_test.go b/src/time/export_windows_test.go
similarity index 100%
rename from src/pkg/time/export_windows_test.go
rename to src/time/export_windows_test.go
diff --git a/src/time/format.go b/src/time/format.go
new file mode 100644
index 0000000..04e79f3
--- /dev/null
+++ b/src/time/format.go
@@ -0,0 +1,1248 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package time
+
+import "errors"
+
+// These are predefined layouts for use in Time.Format and Time.Parse.
+// The reference time used in the layouts is the specific time:
+//	Mon Jan 2 15:04:05 MST 2006
+// which is Unix time 1136239445. Since MST is GMT-0700,
+// the reference time can be thought of as
+//	01/02 03:04:05PM '06 -0700
+// To define your own format, write down what the reference time would look
+// like formatted your way; see the values of constants like ANSIC,
+// StampMicro or Kitchen for examples. The model is to demonstrate what the
+// reference time looks like so that the Format and Parse methods can apply
+// the same transformation to a general time value.
+//
+// Within the format string, an underscore _ represents a space that may be
+// replaced by a digit if the following number (a day) has two digits; for
+// compatibility with fixed-width Unix time formats.
+//
+// A decimal point followed by one or more zeros represents a fractional
+// second, printed to the given number of decimal places.  A decimal point
+// followed by one or more nines represents a fractional second, printed to
+// the given number of decimal places, with trailing zeros removed.
+// When parsing (only), the input may contain a fractional second
+// field immediately after the seconds field, even if the layout does not
+// signify its presence. In that case a decimal point followed by a maximal
+// series of digits is parsed as a fractional second.
+//
+// Numeric time zone offsets format as follows:
+//	-0700  ±hhmm
+//	-07:00 ±hh:mm
+// Replacing the sign in the format with a Z triggers
+// the ISO 8601 behavior of printing Z instead of an
+// offset for the UTC zone.  Thus:
+//	Z0700  Z or ±hhmm
+//	Z07:00 Z or ±hh:mm
+const (
+	ANSIC       = "Mon Jan _2 15:04:05 2006"
+	UnixDate    = "Mon Jan _2 15:04:05 MST 2006"
+	RubyDate    = "Mon Jan 02 15:04:05 -0700 2006"
+	RFC822      = "02 Jan 06 15:04 MST"
+	RFC822Z     = "02 Jan 06 15:04 -0700" // RFC822 with numeric zone
+	RFC850      = "Monday, 02-Jan-06 15:04:05 MST"
+	RFC1123     = "Mon, 02 Jan 2006 15:04:05 MST"
+	RFC1123Z    = "Mon, 02 Jan 2006 15:04:05 -0700" // RFC1123 with numeric zone
+	RFC3339     = "2006-01-02T15:04:05Z07:00"
+	RFC3339Nano = "2006-01-02T15:04:05.999999999Z07:00"
+	Kitchen     = "3:04PM"
+	// Handy time stamps.
+	Stamp      = "Jan _2 15:04:05"
+	StampMilli = "Jan _2 15:04:05.000"
+	StampMicro = "Jan _2 15:04:05.000000"
+	StampNano  = "Jan _2 15:04:05.000000000"
+)
+
+const (
+	_                        = iota
+	stdLongMonth             = iota + stdNeedDate  // "January"
+	stdMonth                                       // "Jan"
+	stdNumMonth                                    // "1"
+	stdZeroMonth                                   // "01"
+	stdLongWeekDay                                 // "Monday"
+	stdWeekDay                                     // "Mon"
+	stdDay                                         // "2"
+	stdUnderDay                                    // "_2"
+	stdZeroDay                                     // "02"
+	stdHour                  = iota + stdNeedClock // "15"
+	stdHour12                                      // "3"
+	stdZeroHour12                                  // "03"
+	stdMinute                                      // "4"
+	stdZeroMinute                                  // "04"
+	stdSecond                                      // "5"
+	stdZeroSecond                                  // "05"
+	stdLongYear              = iota + stdNeedDate  // "2006"
+	stdYear                                        // "06"
+	stdPM                    = iota + stdNeedClock // "PM"
+	stdpm                                          // "pm"
+	stdTZ                    = iota                // "MST"
+	stdISO8601TZ                                   // "Z0700"  // prints Z for UTC
+	stdISO8601SecondsTZ                            // "Z070000"
+	stdISO8601ColonTZ                              // "Z07:00" // prints Z for UTC
+	stdISO8601ColonSecondsTZ                       // "Z07:00:00"
+	stdNumTZ                                       // "-0700"  // always numeric
+	stdNumSecondsTz                                // "-070000"
+	stdNumShortTZ                                  // "-07"    // always numeric
+	stdNumColonTZ                                  // "-07:00" // always numeric
+	stdNumColonSecondsTZ                           // "-07:00:00"
+	stdFracSecond0                                 // ".0", ".00", ... , trailing zeros included
+	stdFracSecond9                                 // ".9", ".99", ..., trailing zeros omitted
+
+	stdNeedDate  = 1 << 8             // need month, day, year
+	stdNeedClock = 2 << 8             // need hour, minute, second
+	stdArgShift  = 16                 // extra argument in high bits, above low stdArgShift
+	stdMask      = 1<<stdArgShift - 1 // mask out argument
+)
+
+// std0x records the std values for "01", "02", ..., "06".
+var std0x = [...]int{stdZeroMonth, stdZeroDay, stdZeroHour12, stdZeroMinute, stdZeroSecond, stdYear}
+
+// startsWithLowerCase reports whether the string has a lower-case letter at the beginning.
+// Its purpose is to prevent matching strings like "Month" when looking for "Mon".
+func startsWithLowerCase(str string) bool {
+	if len(str) == 0 {
+		return false
+	}
+	c := str[0]
+	return 'a' <= c && c <= 'z'
+}
+
+// nextStdChunk finds the first occurrence of a std string in
+// layout and returns the text before, the std string, and the text after.
+func nextStdChunk(layout string) (prefix string, std int, suffix string) {
+	for i := 0; i < len(layout); i++ {
+		switch c := int(layout[i]); c {
+		case 'J': // January, Jan
+			if len(layout) >= i+3 && layout[i:i+3] == "Jan" {
+				if len(layout) >= i+7 && layout[i:i+7] == "January" {
+					return layout[0:i], stdLongMonth, layout[i+7:]
+				}
+				if !startsWithLowerCase(layout[i+3:]) {
+					return layout[0:i], stdMonth, layout[i+3:]
+				}
+			}
+
+		case 'M': // Monday, Mon, MST
+			if len(layout) >= i+3 {
+				if layout[i:i+3] == "Mon" {
+					if len(layout) >= i+6 && layout[i:i+6] == "Monday" {
+						return layout[0:i], stdLongWeekDay, layout[i+6:]
+					}
+					if !startsWithLowerCase(layout[i+3:]) {
+						return layout[0:i], stdWeekDay, layout[i+3:]
+					}
+				}
+				if layout[i:i+3] == "MST" {
+					return layout[0:i], stdTZ, layout[i+3:]
+				}
+			}
+
+		case '0': // 01, 02, 03, 04, 05, 06
+			if len(layout) >= i+2 && '1' <= layout[i+1] && layout[i+1] <= '6' {
+				return layout[0:i], std0x[layout[i+1]-'1'], layout[i+2:]
+			}
+
+		case '1': // 15, 1
+			if len(layout) >= i+2 && layout[i+1] == '5' {
+				return layout[0:i], stdHour, layout[i+2:]
+			}
+			return layout[0:i], stdNumMonth, layout[i+1:]
+
+		case '2': // 2006, 2
+			if len(layout) >= i+4 && layout[i:i+4] == "2006" {
+				return layout[0:i], stdLongYear, layout[i+4:]
+			}
+			return layout[0:i], stdDay, layout[i+1:]
+
+		case '_': // _2
+			if len(layout) >= i+2 && layout[i+1] == '2' {
+				return layout[0:i], stdUnderDay, layout[i+2:]
+			}
+
+		case '3':
+			return layout[0:i], stdHour12, layout[i+1:]
+
+		case '4':
+			return layout[0:i], stdMinute, layout[i+1:]
+
+		case '5':
+			return layout[0:i], stdSecond, layout[i+1:]
+
+		case 'P': // PM
+			if len(layout) >= i+2 && layout[i+1] == 'M' {
+				return layout[0:i], stdPM, layout[i+2:]
+			}
+
+		case 'p': // pm
+			if len(layout) >= i+2 && layout[i+1] == 'm' {
+				return layout[0:i], stdpm, layout[i+2:]
+			}
+
+		case '-': // -070000, -07:00:00, -0700, -07:00, -07
+			if len(layout) >= i+7 && layout[i:i+7] == "-070000" {
+				return layout[0:i], stdNumSecondsTz, layout[i+7:]
+			}
+			if len(layout) >= i+9 && layout[i:i+9] == "-07:00:00" {
+				return layout[0:i], stdNumColonSecondsTZ, layout[i+9:]
+			}
+			if len(layout) >= i+5 && layout[i:i+5] == "-0700" {
+				return layout[0:i], stdNumTZ, layout[i+5:]
+			}
+			if len(layout) >= i+6 && layout[i:i+6] == "-07:00" {
+				return layout[0:i], stdNumColonTZ, layout[i+6:]
+			}
+			if len(layout) >= i+3 && layout[i:i+3] == "-07" {
+				return layout[0:i], stdNumShortTZ, layout[i+3:]
+			}
+
+		case 'Z': // Z070000, Z07:00:00, Z0700, Z07:00,
+			if len(layout) >= i+7 && layout[i:i+7] == "Z070000" {
+				return layout[0:i], stdISO8601SecondsTZ, layout[i+7:]
+			}
+			if len(layout) >= i+9 && layout[i:i+9] == "Z07:00:00" {
+				return layout[0:i], stdISO8601ColonSecondsTZ, layout[i+9:]
+			}
+			if len(layout) >= i+5 && layout[i:i+5] == "Z0700" {
+				return layout[0:i], stdISO8601TZ, layout[i+5:]
+			}
+			if len(layout) >= i+6 && layout[i:i+6] == "Z07:00" {
+				return layout[0:i], stdISO8601ColonTZ, layout[i+6:]
+			}
+
+		case '.': // .000 or .999 - repeated digits for fractional seconds.
+			if i+1 < len(layout) && (layout[i+1] == '0' || layout[i+1] == '9') {
+				ch := layout[i+1]
+				j := i + 1
+				for j < len(layout) && layout[j] == ch {
+					j++
+				}
+				// String of digits must end here - only fractional second is all digits.
+				if !isDigit(layout, j) {
+					std := stdFracSecond0
+					if layout[i+1] == '9' {
+						std = stdFracSecond9
+					}
+					std |= (j - (i + 1)) << stdArgShift
+					return layout[0:i], std, layout[j:]
+				}
+			}
+		}
+	}
+	return layout, 0, ""
+}
+
+var longDayNames = []string{
+	"Sunday",
+	"Monday",
+	"Tuesday",
+	"Wednesday",
+	"Thursday",
+	"Friday",
+	"Saturday",
+}
+
+var shortDayNames = []string{
+	"Sun",
+	"Mon",
+	"Tue",
+	"Wed",
+	"Thu",
+	"Fri",
+	"Sat",
+}
+
+var shortMonthNames = []string{
+	"---",
+	"Jan",
+	"Feb",
+	"Mar",
+	"Apr",
+	"May",
+	"Jun",
+	"Jul",
+	"Aug",
+	"Sep",
+	"Oct",
+	"Nov",
+	"Dec",
+}
+
+var longMonthNames = []string{
+	"---",
+	"January",
+	"February",
+	"March",
+	"April",
+	"May",
+	"June",
+	"July",
+	"August",
+	"September",
+	"October",
+	"November",
+	"December",
+}
+
+// match returns true if s1 and s2 match ignoring case.
+// It is assumed s1 and s2 are the same length.
+func match(s1, s2 string) bool {
+	for i := 0; i < len(s1); i++ {
+		c1 := s1[i]
+		c2 := s2[i]
+		if c1 != c2 {
+			// Switch to lower-case; 'a'-'A' is known to be a single bit.
+			c1 |= 'a' - 'A'
+			c2 |= 'a' - 'A'
+			if c1 != c2 || c1 < 'a' || c1 > 'z' {
+				return false
+			}
+		}
+	}
+	return true
+}
+
+func lookup(tab []string, val string) (int, string, error) {
+	for i, v := range tab {
+		if len(val) >= len(v) && match(val[0:len(v)], v) {
+			return i, val[len(v):], nil
+		}
+	}
+	return -1, val, errBad
+}
+
+// appendUint appends the decimal form of x to b and returns the result.
+// If x is a single-digit number and pad != 0, appendUint inserts the pad byte
+// before the digit.
+// Duplicates functionality in strconv, but avoids dependency.
+func appendUint(b []byte, x uint, pad byte) []byte {
+	if x < 10 {
+		if pad != 0 {
+			b = append(b, pad)
+		}
+		return append(b, byte('0'+x))
+	}
+	if x < 100 {
+		b = append(b, byte('0'+x/10))
+		b = append(b, byte('0'+x%10))
+		return b
+	}
+
+	var buf [32]byte
+	n := len(buf)
+	if x == 0 {
+		return append(b, '0')
+	}
+	for x >= 10 {
+		n--
+		buf[n] = byte(x%10 + '0')
+		x /= 10
+	}
+	n--
+	buf[n] = byte(x + '0')
+	return append(b, buf[n:]...)
+}
+
+// Never printed, just needs to be non-nil for return by atoi.
+var atoiError = errors.New("time: invalid number")
+
+// Duplicates functionality in strconv, but avoids dependency.
+func atoi(s string) (x int, err error) {
+	neg := false
+	if s != "" && (s[0] == '-' || s[0] == '+') {
+		neg = s[0] == '-'
+		s = s[1:]
+	}
+	q, rem, err := leadingInt(s)
+	x = int(q)
+	if err != nil || rem != "" {
+		return 0, atoiError
+	}
+	if neg {
+		x = -x
+	}
+	return x, nil
+}
+
+// formatNano appends a fractional second, as nanoseconds, to b
+// and returns the result.
+func formatNano(b []byte, nanosec uint, n int, trim bool) []byte {
+	u := nanosec
+	var buf [9]byte
+	for start := len(buf); start > 0; {
+		start--
+		buf[start] = byte(u%10 + '0')
+		u /= 10
+	}
+
+	if n > 9 {
+		n = 9
+	}
+	if trim {
+		for n > 0 && buf[n-1] == '0' {
+			n--
+		}
+		if n == 0 {
+			return b
+		}
+	}
+	b = append(b, '.')
+	return append(b, buf[:n]...)
+}
+
+// String returns the time formatted using the format string
+//	"2006-01-02 15:04:05.999999999 -0700 MST"
+func (t Time) String() string {
+	return t.Format("2006-01-02 15:04:05.999999999 -0700 MST")
+}
+
+// Format returns a textual representation of the time value formatted
+// according to layout, which defines the format by showing how the reference
+// time, defined to be
+//	Mon Jan 2 15:04:05 -0700 MST 2006
+// would be displayed if it were the value; it serves as an example of the
+// desired output. The same display rules will then be applied to the time
+// value.
+// Predefined layouts ANSIC, UnixDate, RFC3339 and others describe standard
+// and convenient representations of the reference time. For more information
+// about the formats and the definition of the reference time, see the
+// documentation for ANSIC and the other constants defined by this package.
+func (t Time) Format(layout string) string {
+	var (
+		name, offset, abs = t.locabs()
+
+		year  int = -1
+		month Month
+		day   int
+		hour  int = -1
+		min   int
+		sec   int
+
+		b   []byte
+		buf [64]byte
+	)
+	max := len(layout) + 10
+	if max <= len(buf) {
+		b = buf[:0]
+	} else {
+		b = make([]byte, 0, max)
+	}
+	// Each iteration generates one std value.
+	for layout != "" {
+		prefix, std, suffix := nextStdChunk(layout)
+		if prefix != "" {
+			b = append(b, prefix...)
+		}
+		if std == 0 {
+			break
+		}
+		layout = suffix
+
+		// Compute year, month, day if needed.
+		if year < 0 && std&stdNeedDate != 0 {
+			year, month, day, _ = absDate(abs, true)
+		}
+
+		// Compute hour, minute, second if needed.
+		if hour < 0 && std&stdNeedClock != 0 {
+			hour, min, sec = absClock(abs)
+		}
+
+		switch std & stdMask {
+		case stdYear:
+			y := year
+			if y < 0 {
+				y = -y
+			}
+			b = appendUint(b, uint(y%100), '0')
+		case stdLongYear:
+			// Pad year to at least 4 digits.
+			y := year
+			switch {
+			case year <= -1000:
+				b = append(b, '-')
+				y = -y
+			case year <= -100:
+				b = append(b, "-0"...)
+				y = -y
+			case year <= -10:
+				b = append(b, "-00"...)
+				y = -y
+			case year < 0:
+				b = append(b, "-000"...)
+				y = -y
+			case year < 10:
+				b = append(b, "000"...)
+			case year < 100:
+				b = append(b, "00"...)
+			case year < 1000:
+				b = append(b, '0')
+			}
+			b = appendUint(b, uint(y), 0)
+		case stdMonth:
+			b = append(b, month.String()[:3]...)
+		case stdLongMonth:
+			m := month.String()
+			b = append(b, m...)
+		case stdNumMonth:
+			b = appendUint(b, uint(month), 0)
+		case stdZeroMonth:
+			b = appendUint(b, uint(month), '0')
+		case stdWeekDay:
+			b = append(b, absWeekday(abs).String()[:3]...)
+		case stdLongWeekDay:
+			s := absWeekday(abs).String()
+			b = append(b, s...)
+		case stdDay:
+			b = appendUint(b, uint(day), 0)
+		case stdUnderDay:
+			b = appendUint(b, uint(day), ' ')
+		case stdZeroDay:
+			b = appendUint(b, uint(day), '0')
+		case stdHour:
+			b = appendUint(b, uint(hour), '0')
+		case stdHour12:
+			// Noon is 12PM, midnight is 12AM.
+			hr := hour % 12
+			if hr == 0 {
+				hr = 12
+			}
+			b = appendUint(b, uint(hr), 0)
+		case stdZeroHour12:
+			// Noon is 12PM, midnight is 12AM.
+			hr := hour % 12
+			if hr == 0 {
+				hr = 12
+			}
+			b = appendUint(b, uint(hr), '0')
+		case stdMinute:
+			b = appendUint(b, uint(min), 0)
+		case stdZeroMinute:
+			b = appendUint(b, uint(min), '0')
+		case stdSecond:
+			b = appendUint(b, uint(sec), 0)
+		case stdZeroSecond:
+			b = appendUint(b, uint(sec), '0')
+		case stdPM:
+			if hour >= 12 {
+				b = append(b, "PM"...)
+			} else {
+				b = append(b, "AM"...)
+			}
+		case stdpm:
+			if hour >= 12 {
+				b = append(b, "pm"...)
+			} else {
+				b = append(b, "am"...)
+			}
+		case stdISO8601TZ, stdISO8601ColonTZ, stdISO8601SecondsTZ, stdISO8601ColonSecondsTZ, stdNumTZ, stdNumColonTZ, stdNumSecondsTz, stdNumColonSecondsTZ:
+			// Ugly special case.  We cheat and take the "Z" variants
+			// to mean "the time zone as formatted for ISO 8601".
+			if offset == 0 && (std == stdISO8601TZ || std == stdISO8601ColonTZ || std == stdISO8601SecondsTZ || std == stdISO8601ColonSecondsTZ) {
+				b = append(b, 'Z')
+				break
+			}
+			zone := offset / 60 // convert to minutes
+			absoffset := offset
+			if zone < 0 {
+				b = append(b, '-')
+				zone = -zone
+				absoffset = -absoffset
+			} else {
+				b = append(b, '+')
+			}
+			b = appendUint(b, uint(zone/60), '0')
+			if std == stdISO8601ColonTZ || std == stdNumColonTZ || std == stdISO8601ColonSecondsTZ || std == stdNumColonSecondsTZ {
+				b = append(b, ':')
+			}
+			b = appendUint(b, uint(zone%60), '0')
+
+			// append seconds if appropriate
+			if std == stdISO8601SecondsTZ || std == stdNumSecondsTz || std == stdNumColonSecondsTZ || std == stdISO8601ColonSecondsTZ {
+				if std == stdNumColonSecondsTZ || std == stdISO8601ColonSecondsTZ {
+					b = append(b, ':')
+				}
+				b = appendUint(b, uint(absoffset%60), '0')
+			}
+
+		case stdTZ:
+			if name != "" {
+				b = append(b, name...)
+				break
+			}
+			// No time zone known for this time, but we must print one.
+			// Use the -0700 format.
+			zone := offset / 60 // convert to minutes
+			if zone < 0 {
+				b = append(b, '-')
+				zone = -zone
+			} else {
+				b = append(b, '+')
+			}
+			b = appendUint(b, uint(zone/60), '0')
+			b = appendUint(b, uint(zone%60), '0')
+		case stdFracSecond0, stdFracSecond9:
+			b = formatNano(b, uint(t.Nanosecond()), std>>stdArgShift, std&stdMask == stdFracSecond9)
+		}
+	}
+	return string(b)
+}
+
+var errBad = errors.New("bad value for field") // placeholder not passed to user
+
+// ParseError describes a problem parsing a time string.
+type ParseError struct {
+	Layout     string
+	Value      string
+	LayoutElem string
+	ValueElem  string
+	Message    string
+}
+
+func quote(s string) string {
+	return "\"" + s + "\""
+}
+
+// Error returns the string representation of a ParseError.
+func (e *ParseError) Error() string {
+	if e.Message == "" {
+		return "parsing time " +
+			quote(e.Value) + " as " +
+			quote(e.Layout) + ": cannot parse " +
+			quote(e.ValueElem) + " as " +
+			quote(e.LayoutElem)
+	}
+	return "parsing time " +
+		quote(e.Value) + e.Message
+}
+
+// isDigit returns true if s[i] is a decimal digit, false if not or
+// if s[i] is out of range.
+func isDigit(s string, i int) bool {
+	if len(s) <= i {
+		return false
+	}
+	c := s[i]
+	return '0' <= c && c <= '9'
+}
+
+// getnum parses s[0:1] or s[0:2] (fixed forces the latter)
+// as a decimal integer and returns the integer and the
+// remainder of the string.
+func getnum(s string, fixed bool) (int, string, error) {
+	if !isDigit(s, 0) {
+		return 0, s, errBad
+	}
+	if !isDigit(s, 1) {
+		if fixed {
+			return 0, s, errBad
+		}
+		return int(s[0] - '0'), s[1:], nil
+	}
+	return int(s[0]-'0')*10 + int(s[1]-'0'), s[2:], nil
+}
+
+func cutspace(s string) string {
+	for len(s) > 0 && s[0] == ' ' {
+		s = s[1:]
+	}
+	return s
+}
+
+// skip removes the given prefix from value,
+// treating runs of space characters as equivalent.
+func skip(value, prefix string) (string, error) {
+	for len(prefix) > 0 {
+		if prefix[0] == ' ' {
+			if len(value) > 0 && value[0] != ' ' {
+				return value, errBad
+			}
+			prefix = cutspace(prefix)
+			value = cutspace(value)
+			continue
+		}
+		if len(value) == 0 || value[0] != prefix[0] {
+			return value, errBad
+		}
+		prefix = prefix[1:]
+		value = value[1:]
+	}
+	return value, nil
+}
+
+// Parse parses a formatted string and returns the time value it represents.
+// The layout  defines the format by showing how the reference time,
+// defined to be
+//	Mon Jan 2 15:04:05 -0700 MST 2006
+// would be interpreted if it were the value; it serves as an example of
+// the input format. The same interpretation will then be made to the
+// input string.
+// Predefined layouts ANSIC, UnixDate, RFC3339 and others describe standard
+// and convenient representations of the reference time. For more information
+// about the formats and the definition of the reference time, see the
+// documentation for ANSIC and the other constants defined by this package.
+//
+// Elements omitted from the value are assumed to be zero or, when
+// zero is impossible, one, so parsing "3:04pm" returns the time
+// corresponding to Jan 1, year 0, 15:04:00 UTC (note that because the year is
+// 0, this time is before the zero Time).
+// Years must be in the range 0000..9999. The day of the week is checked
+// for syntax but it is otherwise ignored.
+//
+// In the absence of a time zone indicator, Parse returns a time in UTC.
+//
+// When parsing a time with a zone offset like -0700, if the offset corresponds
+// to a time zone used by the current location (Local), then Parse uses that
+// location and zone in the returned time. Otherwise it records the time as
+// being in a fabricated location with time fixed at the given zone offset.
+//
+// When parsing a time with a zone abbreviation like MST, if the zone abbreviation
+// has a defined offset in the current location, then that offset is used.
+// The zone abbreviation "UTC" is recognized as UTC regardless of location.
+// If the zone abbreviation is unknown, Parse records the time as being
+// in a fabricated location with the given zone abbreviation and a zero offset.
+// This choice means that such a time can be parsed and reformatted with the
+// same layout losslessly, but the exact instant used in the representation will
+// differ by the actual zone offset. To avoid such problems, prefer time layouts
+// that use a numeric zone offset, or use ParseInLocation.
+func Parse(layout, value string) (Time, error) {
+	return parse(layout, value, UTC, Local)
+}
+
+// ParseInLocation is like Parse but differs in two important ways.
+// First, in the absence of time zone information, Parse interprets a time as UTC;
+// ParseInLocation interprets the time as in the given location.
+// Second, when given a zone offset or abbreviation, Parse tries to match it
+// against the Local location; ParseInLocation uses the given location.
+func ParseInLocation(layout, value string, loc *Location) (Time, error) {
+	return parse(layout, value, loc, loc)
+}
+
+func parse(layout, value string, defaultLocation, local *Location) (Time, error) {
+	alayout, avalue := layout, value
+	rangeErrString := "" // set if a value is out of range
+	amSet := false       // do we need to subtract 12 from the hour for midnight?
+	pmSet := false       // do we need to add 12 to the hour?
+
+	// Time being constructed.
+	var (
+		year       int
+		month      int = 1 // January
+		day        int = 1
+		hour       int
+		min        int
+		sec        int
+		nsec       int
+		z          *Location
+		zoneOffset int = -1
+		zoneName   string
+	)
+
+	// Each iteration processes one std value.
+	for {
+		var err error
+		prefix, std, suffix := nextStdChunk(layout)
+		stdstr := layout[len(prefix) : len(layout)-len(suffix)]
+		value, err = skip(value, prefix)
+		if err != nil {
+			return Time{}, &ParseError{alayout, avalue, prefix, value, ""}
+		}
+		if std == 0 {
+			if len(value) != 0 {
+				return Time{}, &ParseError{alayout, avalue, "", value, ": extra text: " + value}
+			}
+			break
+		}
+		layout = suffix
+		var p string
+		switch std & stdMask {
+		case stdYear:
+			if len(value) < 2 {
+				err = errBad
+				break
+			}
+			p, value = value[0:2], value[2:]
+			year, err = atoi(p)
+			if year >= 69 { // Unix time starts Dec 31 1969 in some time zones
+				year += 1900
+			} else {
+				year += 2000
+			}
+		case stdLongYear:
+			if len(value) < 4 || !isDigit(value, 0) {
+				err = errBad
+				break
+			}
+			p, value = value[0:4], value[4:]
+			year, err = atoi(p)
+		case stdMonth:
+			month, value, err = lookup(shortMonthNames, value)
+		case stdLongMonth:
+			month, value, err = lookup(longMonthNames, value)
+		case stdNumMonth, stdZeroMonth:
+			month, value, err = getnum(value, std == stdZeroMonth)
+			if month <= 0 || 12 < month {
+				rangeErrString = "month"
+			}
+		case stdWeekDay:
+			// Ignore weekday except for error checking.
+			_, value, err = lookup(shortDayNames, value)
+		case stdLongWeekDay:
+			_, value, err = lookup(longDayNames, value)
+		case stdDay, stdUnderDay, stdZeroDay:
+			if std == stdUnderDay && len(value) > 0 && value[0] == ' ' {
+				value = value[1:]
+			}
+			day, value, err = getnum(value, std == stdZeroDay)
+			if day < 0 || 31 < day {
+				rangeErrString = "day"
+			}
+		case stdHour:
+			hour, value, err = getnum(value, false)
+			if hour < 0 || 24 <= hour {
+				rangeErrString = "hour"
+			}
+		case stdHour12, stdZeroHour12:
+			hour, value, err = getnum(value, std == stdZeroHour12)
+			if hour < 0 || 12 < hour {
+				rangeErrString = "hour"
+			}
+		case stdMinute, stdZeroMinute:
+			min, value, err = getnum(value, std == stdZeroMinute)
+			if min < 0 || 60 <= min {
+				rangeErrString = "minute"
+			}
+		case stdSecond, stdZeroSecond:
+			sec, value, err = getnum(value, std == stdZeroSecond)
+			if sec < 0 || 60 <= sec {
+				rangeErrString = "second"
+			}
+			// Special case: do we have a fractional second but no
+			// fractional second in the format?
+			if len(value) >= 2 && value[0] == '.' && isDigit(value, 1) {
+				_, std, _ = nextStdChunk(layout)
+				std &= stdMask
+				if std == stdFracSecond0 || std == stdFracSecond9 {
+					// Fractional second in the layout; proceed normally
+					break
+				}
+				// No fractional second in the layout but we have one in the input.
+				n := 2
+				for ; n < len(value) && isDigit(value, n); n++ {
+				}
+				nsec, rangeErrString, err = parseNanoseconds(value, n)
+				value = value[n:]
+			}
+		case stdPM:
+			if len(value) < 2 {
+				err = errBad
+				break
+			}
+			p, value = value[0:2], value[2:]
+			switch p {
+			case "PM":
+				pmSet = true
+			case "AM":
+				amSet = true
+			default:
+				err = errBad
+			}
+		case stdpm:
+			if len(value) < 2 {
+				err = errBad
+				break
+			}
+			p, value = value[0:2], value[2:]
+			switch p {
+			case "pm":
+				pmSet = true
+			case "am":
+				amSet = true
+			default:
+				err = errBad
+			}
+		case stdISO8601TZ, stdISO8601ColonTZ, stdISO8601SecondsTZ, stdISO8601ColonSecondsTZ, stdNumTZ, stdNumShortTZ, stdNumColonTZ, stdNumSecondsTz, stdNumColonSecondsTZ:
+			if (std == stdISO8601TZ || std == stdISO8601ColonTZ) && len(value) >= 1 && value[0] == 'Z' {
+				value = value[1:]
+				z = UTC
+				break
+			}
+			var sign, hour, min, seconds string
+			if std == stdISO8601ColonTZ || std == stdNumColonTZ {
+				if len(value) < 6 {
+					err = errBad
+					break
+				}
+				if value[3] != ':' {
+					err = errBad
+					break
+				}
+				sign, hour, min, seconds, value = value[0:1], value[1:3], value[4:6], "00", value[6:]
+			} else if std == stdNumShortTZ {
+				if len(value) < 3 {
+					err = errBad
+					break
+				}
+				sign, hour, min, seconds, value = value[0:1], value[1:3], "00", "00", value[3:]
+			} else if std == stdISO8601ColonSecondsTZ || std == stdNumColonSecondsTZ {
+				if len(value) < 9 {
+					err = errBad
+					break
+				}
+				if value[3] != ':' || value[6] != ':' {
+					err = errBad
+					break
+				}
+				sign, hour, min, seconds, value = value[0:1], value[1:3], value[4:6], value[7:9], value[9:]
+			} else if std == stdISO8601SecondsTZ || std == stdNumSecondsTz {
+				if len(value) < 7 {
+					err = errBad
+					break
+				}
+				sign, hour, min, seconds, value = value[0:1], value[1:3], value[3:5], value[5:7], value[7:]
+			} else {
+				if len(value) < 5 {
+					err = errBad
+					break
+				}
+				sign, hour, min, seconds, value = value[0:1], value[1:3], value[3:5], "00", value[5:]
+			}
+			var hr, mm, ss int
+			hr, err = atoi(hour)
+			if err == nil {
+				mm, err = atoi(min)
+			}
+			if err == nil {
+				ss, err = atoi(seconds)
+			}
+			zoneOffset = (hr*60+mm)*60 + ss // offset is in seconds
+			switch sign[0] {
+			case '+':
+			case '-':
+				zoneOffset = -zoneOffset
+			default:
+				err = errBad
+			}
+		case stdTZ:
+			// Does it look like a time zone?
+			if len(value) >= 3 && value[0:3] == "UTC" {
+				z = UTC
+				value = value[3:]
+				break
+			}
+			n, ok := parseTimeZone(value)
+			if !ok {
+				err = errBad
+				break
+			}
+			zoneName, value = value[:n], value[n:]
+
+		case stdFracSecond0:
+			// stdFracSecond0 requires the exact number of digits as specified in
+			// the layout.
+			ndigit := 1 + (std >> stdArgShift)
+			if len(value) < ndigit {
+				err = errBad
+				break
+			}
+			nsec, rangeErrString, err = parseNanoseconds(value, ndigit)
+			value = value[ndigit:]
+
+		case stdFracSecond9:
+			if len(value) < 2 || value[0] != '.' || value[1] < '0' || '9' < value[1] {
+				// Fractional second omitted.
+				break
+			}
+			// Take any number of digits, even more than asked for,
+			// because it is what the stdSecond case would do.
+			i := 0
+			for i < 9 && i+1 < len(value) && '0' <= value[i+1] && value[i+1] <= '9' {
+				i++
+			}
+			nsec, rangeErrString, err = parseNanoseconds(value, 1+i)
+			value = value[1+i:]
+		}
+		if rangeErrString != "" {
+			return Time{}, &ParseError{alayout, avalue, stdstr, value, ": " + rangeErrString + " out of range"}
+		}
+		if err != nil {
+			return Time{}, &ParseError{alayout, avalue, stdstr, value, ""}
+		}
+	}
+	if pmSet && hour < 12 {
+		hour += 12
+	} else if amSet && hour == 12 {
+		hour = 0
+	}
+
+	if z != nil {
+		return Date(year, Month(month), day, hour, min, sec, nsec, z), nil
+	}
+
+	if zoneOffset != -1 {
+		t := Date(year, Month(month), day, hour, min, sec, nsec, UTC)
+		t.sec -= int64(zoneOffset)
+
+		// Look for local zone with the given offset.
+		// If that zone was in effect at the given time, use it.
+		name, offset, _, _, _ := local.lookup(t.sec + internalToUnix)
+		if offset == zoneOffset && (zoneName == "" || name == zoneName) {
+			t.loc = local
+			return t, nil
+		}
+
+		// Otherwise create fake zone to record offset.
+		t.loc = FixedZone(zoneName, zoneOffset)
+		return t, nil
+	}
+
+	if zoneName != "" {
+		t := Date(year, Month(month), day, hour, min, sec, nsec, UTC)
+		// Look for local zone with the given offset.
+		// If that zone was in effect at the given time, use it.
+		offset, _, ok := local.lookupName(zoneName, t.sec+internalToUnix)
+		if ok {
+			t.sec -= int64(offset)
+			t.loc = local
+			return t, nil
+		}
+
+		// Otherwise, create fake zone with unknown offset.
+		if len(zoneName) > 3 && zoneName[:3] == "GMT" {
+			offset, _ = atoi(zoneName[3:]) // Guaranteed OK by parseGMT.
+			offset *= 3600
+		}
+		t.loc = FixedZone(zoneName, offset)
+		return t, nil
+	}
+
+	// Otherwise, fall back to default.
+	return Date(year, Month(month), day, hour, min, sec, nsec, defaultLocation), nil
+}
+
+// parseTimeZone parses a time zone string and returns its length. Time zones
+// are human-generated and unpredictable. We can't do precise error checking.
+// On the other hand, for a correct parse there must be a time zone at the
+// beginning of the string, so it's almost always true that there's one
+// there. We look at the beginning of the string for a run of upper-case letters.
+// If there are more than 5, it's an error.
+// If there are 4 or 5 and the last is a T, it's a time zone.
+// If there are 3, it's a time zone.
+// Otherwise, other than special cases, it's not a time zone.
+// GMT is special because it can have an hour offset.
+func parseTimeZone(value string) (length int, ok bool) {
+	if len(value) < 3 {
+		return 0, false
+	}
+	// Special case 1: ChST and MeST are the only zones with a lower-case letter.
+	if len(value) >= 4 && (value[:4] == "ChST" || value[:4] == "MeST") {
+		return 4, true
+	}
+	// Special case 2: GMT may have an hour offset; treat it specially.
+	if value[:3] == "GMT" {
+		length = parseGMT(value)
+		return length, true
+	}
+	// How many upper-case letters are there? Need at least three, at most five.
+	var nUpper int
+	for nUpper = 0; nUpper < 6; nUpper++ {
+		if nUpper >= len(value) {
+			break
+		}
+		if c := value[nUpper]; c < 'A' || 'Z' < c {
+			break
+		}
+	}
+	switch nUpper {
+	case 0, 1, 2, 6:
+		return 0, false
+	case 5: // Must end in T to match.
+		if value[4] == 'T' {
+			return 5, true
+		}
+	case 4: // Must end in T to match.
+		if value[3] == 'T' {
+			return 4, true
+		}
+	case 3:
+		return 3, true
+	}
+	return 0, false
+}
+
+// parseGMT parses a GMT time zone. The input string is known to start "GMT".
+// The function checks whether that is followed by a sign and a number in the
+// range -14 through 12 excluding zero.
+func parseGMT(value string) int {
+	value = value[3:]
+	if len(value) == 0 {
+		return 3
+	}
+	sign := value[0]
+	if sign != '-' && sign != '+' {
+		return 3
+	}
+	x, rem, err := leadingInt(value[1:])
+	if err != nil {
+		return 3
+	}
+	if sign == '-' {
+		x = -x
+	}
+	if x == 0 || x < -14 || 12 < x {
+		return 3
+	}
+	return 3 + len(value) - len(rem)
+}
+
+func parseNanoseconds(value string, nbytes int) (ns int, rangeErrString string, err error) {
+	if value[0] != '.' {
+		err = errBad
+		return
+	}
+	if ns, err = atoi(value[1:nbytes]); err != nil {
+		return
+	}
+	if ns < 0 || 1e9 <= ns {
+		rangeErrString = "fractional second"
+		return
+	}
+	// We need nanoseconds, which means scaling by the number
+	// of missing digits in the format, maximum length 10. If it's
+	// longer than 10, we won't scale.
+	scaleDigits := 10 - nbytes
+	for i := 0; i < scaleDigits; i++ {
+		ns *= 10
+	}
+	return
+}
+
+var errLeadingInt = errors.New("time: bad [0-9]*") // never printed
+
+// leadingInt consumes the leading [0-9]* from s.
+func leadingInt(s string) (x int64, rem string, err error) {
+	i := 0
+	for ; i < len(s); i++ {
+		c := s[i]
+		if c < '0' || c > '9' {
+			break
+		}
+		if x >= (1<<63-10)/10 {
+			// overflow
+			return 0, "", errLeadingInt
+		}
+		x = x*10 + int64(c) - '0'
+	}
+	return x, s[i:], nil
+}
+
+var unitMap = map[string]float64{
+	"ns": float64(Nanosecond),
+	"us": float64(Microsecond),
+	"µs": float64(Microsecond), // U+00B5 = micro symbol
+	"μs": float64(Microsecond), // U+03BC = Greek letter mu
+	"ms": float64(Millisecond),
+	"s":  float64(Second),
+	"m":  float64(Minute),
+	"h":  float64(Hour),
+}
+
+// ParseDuration parses a duration string.
+// A duration string is a possibly signed sequence of
+// decimal numbers, each with optional fraction and a unit suffix,
+// such as "300ms", "-1.5h" or "2h45m".
+// Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".
+func ParseDuration(s string) (Duration, error) {
+	// [-+]?([0-9]*(\.[0-9]*)?[a-z]+)+
+	orig := s
+	f := float64(0)
+	neg := false
+
+	// Consume [-+]?
+	if s != "" {
+		c := s[0]
+		if c == '-' || c == '+' {
+			neg = c == '-'
+			s = s[1:]
+		}
+	}
+	// Special case: if all that is left is "0", this is zero.
+	if s == "0" {
+		return 0, nil
+	}
+	if s == "" {
+		return 0, errors.New("time: invalid duration " + orig)
+	}
+	for s != "" {
+		g := float64(0) // this element of the sequence
+
+		var x int64
+		var err error
+
+		// The next character must be [0-9.]
+		if !(s[0] == '.' || ('0' <= s[0] && s[0] <= '9')) {
+			return 0, errors.New("time: invalid duration " + orig)
+		}
+		// Consume [0-9]*
+		pl := len(s)
+		x, s, err = leadingInt(s)
+		if err != nil {
+			return 0, errors.New("time: invalid duration " + orig)
+		}
+		g = float64(x)
+		pre := pl != len(s) // whether we consumed anything before a period
+
+		// Consume (\.[0-9]*)?
+		post := false
+		if s != "" && s[0] == '.' {
+			s = s[1:]
+			pl := len(s)
+			x, s, err = leadingInt(s)
+			if err != nil {
+				return 0, errors.New("time: invalid duration " + orig)
+			}
+			scale := 1.0
+			for n := pl - len(s); n > 0; n-- {
+				scale *= 10
+			}
+			g += float64(x) / scale
+			post = pl != len(s)
+		}
+		if !pre && !post {
+			// no digits (e.g. ".s" or "-.s")
+			return 0, errors.New("time: invalid duration " + orig)
+		}
+
+		// Consume unit.
+		i := 0
+		for ; i < len(s); i++ {
+			c := s[i]
+			if c == '.' || ('0' <= c && c <= '9') {
+				break
+			}
+		}
+		if i == 0 {
+			return 0, errors.New("time: missing unit in duration " + orig)
+		}
+		u := s[:i]
+		s = s[i:]
+		unit, ok := unitMap[u]
+		if !ok {
+			return 0, errors.New("time: unknown unit " + u + " in duration " + orig)
+		}
+
+		f += g * unit
+	}
+
+	if neg {
+		f = -f
+	}
+	if f < float64(-1<<63) || f > float64(1<<63-1) {
+		return 0, errors.New("time: overflow parsing duration")
+	}
+	return Duration(f), nil
+}
diff --git a/src/time/format_test.go b/src/time/format_test.go
new file mode 100644
index 0000000..ecc5c8f
--- /dev/null
+++ b/src/time/format_test.go
@@ -0,0 +1,518 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package time_test
+
+import (
+	"fmt"
+	"strconv"
+	"strings"
+	"testing"
+	"testing/quick"
+	. "time"
+)
+
+type TimeFormatTest struct {
+	time           Time
+	formattedValue string
+}
+
+var rfc3339Formats = []TimeFormatTest{
+	{Date(2008, 9, 17, 20, 4, 26, 0, UTC), "2008-09-17T20:04:26Z"},
+	{Date(1994, 9, 17, 20, 4, 26, 0, FixedZone("EST", -18000)), "1994-09-17T20:04:26-05:00"},
+	{Date(2000, 12, 26, 1, 15, 6, 0, FixedZone("OTO", 15600)), "2000-12-26T01:15:06+04:20"},
+}
+
+func TestRFC3339Conversion(t *testing.T) {
+	for _, f := range rfc3339Formats {
+		if f.time.Format(RFC3339) != f.formattedValue {
+			t.Error("RFC3339:")
+			t.Errorf("  want=%+v", f.formattedValue)
+			t.Errorf("  have=%+v", f.time.Format(RFC3339))
+		}
+	}
+}
+
+type FormatTest struct {
+	name   string
+	format string
+	result string
+}
+
+var formatTests = []FormatTest{
+	{"ANSIC", ANSIC, "Wed Feb  4 21:00:57 2009"},
+	{"UnixDate", UnixDate, "Wed Feb  4 21:00:57 PST 2009"},
+	{"RubyDate", RubyDate, "Wed Feb 04 21:00:57 -0800 2009"},
+	{"RFC822", RFC822, "04 Feb 09 21:00 PST"},
+	{"RFC850", RFC850, "Wednesday, 04-Feb-09 21:00:57 PST"},
+	{"RFC1123", RFC1123, "Wed, 04 Feb 2009 21:00:57 PST"},
+	{"RFC1123Z", RFC1123Z, "Wed, 04 Feb 2009 21:00:57 -0800"},
+	{"RFC3339", RFC3339, "2009-02-04T21:00:57-08:00"},
+	{"RFC3339Nano", RFC3339Nano, "2009-02-04T21:00:57.0123456-08:00"},
+	{"Kitchen", Kitchen, "9:00PM"},
+	{"am/pm", "3pm", "9pm"},
+	{"AM/PM", "3PM", "9PM"},
+	{"two-digit year", "06 01 02", "09 02 04"},
+	// Three-letter months and days must not be followed by lower-case letter.
+	{"Janet", "Hi Janet, the Month is January", "Hi Janet, the Month is February"},
+	// Time stamps, Fractional seconds.
+	{"Stamp", Stamp, "Feb  4 21:00:57"},
+	{"StampMilli", StampMilli, "Feb  4 21:00:57.012"},
+	{"StampMicro", StampMicro, "Feb  4 21:00:57.012345"},
+	{"StampNano", StampNano, "Feb  4 21:00:57.012345600"},
+}
+
+func TestFormat(t *testing.T) {
+	// The numeric time represents Thu Feb  4 21:00:57.012345600 PST 2010
+	time := Unix(0, 1233810057012345600)
+	for _, test := range formatTests {
+		result := time.Format(test.format)
+		if result != test.result {
+			t.Errorf("%s expected %q got %q", test.name, test.result, result)
+		}
+	}
+}
+
+func TestFormatShortYear(t *testing.T) {
+	years := []int{
+		-100001, -100000, -99999,
+		-10001, -10000, -9999,
+		-1001, -1000, -999,
+		-101, -100, -99,
+		-11, -10, -9,
+		-1, 0, 1,
+		9, 10, 11,
+		99, 100, 101,
+		999, 1000, 1001,
+		9999, 10000, 10001,
+		99999, 100000, 100001,
+	}
+
+	for _, y := range years {
+		time := Date(y, January, 1, 0, 0, 0, 0, UTC)
+		result := time.Format("2006.01.02")
+		var want string
+		if y < 0 {
+			// The 4 in %04d counts the - sign, so print -y instead
+			// and introduce our own - sign.
+			want = fmt.Sprintf("-%04d.%02d.%02d", -y, 1, 1)
+		} else {
+			want = fmt.Sprintf("%04d.%02d.%02d", y, 1, 1)
+		}
+		if result != want {
+			t.Errorf("(jan 1 %d).Format(\"2006.01.02\") = %q, want %q", y, result, want)
+		}
+	}
+}
+
+type ParseTest struct {
+	name       string
+	format     string
+	value      string
+	hasTZ      bool // contains a time zone
+	hasWD      bool // contains a weekday
+	yearSign   int  // sign of year, -1 indicates the year is not present in the format
+	fracDigits int  // number of digits of fractional second
+}
+
+var parseTests = []ParseTest{
+	{"ANSIC", ANSIC, "Thu Feb  4 21:00:57 2010", false, true, 1, 0},
+	{"UnixDate", UnixDate, "Thu Feb  4 21:00:57 PST 2010", true, true, 1, 0},
+	{"RubyDate", RubyDate, "Thu Feb 04 21:00:57 -0800 2010", true, true, 1, 0},
+	{"RFC850", RFC850, "Thursday, 04-Feb-10 21:00:57 PST", true, true, 1, 0},
+	{"RFC1123", RFC1123, "Thu, 04 Feb 2010 21:00:57 PST", true, true, 1, 0},
+	{"RFC1123", RFC1123, "Thu, 04 Feb 2010 22:00:57 PDT", true, true, 1, 0},
+	{"RFC1123Z", RFC1123Z, "Thu, 04 Feb 2010 21:00:57 -0800", true, true, 1, 0},
+	{"RFC3339", RFC3339, "2010-02-04T21:00:57-08:00", true, false, 1, 0},
+	{"custom: \"2006-01-02 15:04:05-07\"", "2006-01-02 15:04:05-07", "2010-02-04 21:00:57-08", true, false, 1, 0},
+	// Optional fractional seconds.
+	{"ANSIC", ANSIC, "Thu Feb  4 21:00:57.0 2010", false, true, 1, 1},
+	{"UnixDate", UnixDate, "Thu Feb  4 21:00:57.01 PST 2010", true, true, 1, 2},
+	{"RubyDate", RubyDate, "Thu Feb 04 21:00:57.012 -0800 2010", true, true, 1, 3},
+	{"RFC850", RFC850, "Thursday, 04-Feb-10 21:00:57.0123 PST", true, true, 1, 4},
+	{"RFC1123", RFC1123, "Thu, 04 Feb 2010 21:00:57.01234 PST", true, true, 1, 5},
+	{"RFC1123Z", RFC1123Z, "Thu, 04 Feb 2010 21:00:57.01234 -0800", true, true, 1, 5},
+	{"RFC3339", RFC3339, "2010-02-04T21:00:57.012345678-08:00", true, false, 1, 9},
+	{"custom: \"2006-01-02 15:04:05\"", "2006-01-02 15:04:05", "2010-02-04 21:00:57.0", false, false, 1, 0},
+	// Amount of white space should not matter.
+	{"ANSIC", ANSIC, "Thu Feb 4 21:00:57 2010", false, true, 1, 0},
+	{"ANSIC", ANSIC, "Thu      Feb     4     21:00:57     2010", false, true, 1, 0},
+	// Case should not matter
+	{"ANSIC", ANSIC, "THU FEB 4 21:00:57 2010", false, true, 1, 0},
+	{"ANSIC", ANSIC, "thu feb 4 21:00:57 2010", false, true, 1, 0},
+	// Fractional seconds.
+	{"millisecond", "Mon Jan _2 15:04:05.000 2006", "Thu Feb  4 21:00:57.012 2010", false, true, 1, 3},
+	{"microsecond", "Mon Jan _2 15:04:05.000000 2006", "Thu Feb  4 21:00:57.012345 2010", false, true, 1, 6},
+	{"nanosecond", "Mon Jan _2 15:04:05.000000000 2006", "Thu Feb  4 21:00:57.012345678 2010", false, true, 1, 9},
+	// Leading zeros in other places should not be taken as fractional seconds.
+	{"zero1", "2006.01.02.15.04.05.0", "2010.02.04.21.00.57.0", false, false, 1, 1},
+	{"zero2", "2006.01.02.15.04.05.00", "2010.02.04.21.00.57.01", false, false, 1, 2},
+	// Month and day names only match when not followed by a lower-case letter.
+	{"Janet", "Hi Janet, the Month is January: Jan _2 15:04:05 2006", "Hi Janet, the Month is February: Feb  4 21:00:57 2010", false, true, 1, 0},
+
+	// GMT with offset.
+	{"GMT-8", UnixDate, "Fri Feb  5 05:00:57 GMT-8 2010", true, true, 1, 0},
+
+	// Accept any number of fractional second digits (including none) for .999...
+	// In Go 1, .999... was completely ignored in the format, meaning the first two
+	// cases would succeed, but the next four would not. Go 1.1 accepts all six.
+	{"", "2006-01-02 15:04:05.9999 -0700 MST", "2010-02-04 21:00:57 -0800 PST", true, false, 1, 0},
+	{"", "2006-01-02 15:04:05.999999999 -0700 MST", "2010-02-04 21:00:57 -0800 PST", true, false, 1, 0},
+	{"", "2006-01-02 15:04:05.9999 -0700 MST", "2010-02-04 21:00:57.0123 -0800 PST", true, false, 1, 4},
+	{"", "2006-01-02 15:04:05.999999999 -0700 MST", "2010-02-04 21:00:57.0123 -0800 PST", true, false, 1, 4},
+	{"", "2006-01-02 15:04:05.9999 -0700 MST", "2010-02-04 21:00:57.012345678 -0800 PST", true, false, 1, 9},
+	{"", "2006-01-02 15:04:05.999999999 -0700 MST", "2010-02-04 21:00:57.012345678 -0800 PST", true, false, 1, 9},
+
+	// issue 4502.
+	{"", StampNano, "Feb  4 21:00:57.012345678", false, false, -1, 9},
+	{"", "Jan _2 15:04:05.999", "Feb  4 21:00:57.012300000", false, false, -1, 4},
+	{"", "Jan _2 15:04:05.999", "Feb  4 21:00:57.012345678", false, false, -1, 9},
+	{"", "Jan _2 15:04:05.999999999", "Feb  4 21:00:57.0123", false, false, -1, 4},
+	{"", "Jan _2 15:04:05.999999999", "Feb  4 21:00:57.012345678", false, false, -1, 9},
+}
+
+func TestParse(t *testing.T) {
+	for _, test := range parseTests {
+		time, err := Parse(test.format, test.value)
+		if err != nil {
+			t.Errorf("%s error: %v", test.name, err)
+		} else {
+			checkTime(time, &test, t)
+		}
+	}
+}
+
+func TestParseInLocation(t *testing.T) {
+	// Check that Parse (and ParseInLocation) understand that
+	// Feb 01 AST (Arabia Standard Time) and Feb 01 AST (Atlantic Standard Time)
+	// are in different time zones even though both are called AST
+
+	baghdad, err := LoadLocation("Asia/Baghdad")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	t1, err := ParseInLocation("Jan 02 2006 MST", "Feb 01 2013 AST", baghdad)
+	if err != nil {
+		t.Fatal(err)
+	}
+	t2 := Date(2013, February, 1, 00, 00, 00, 0, baghdad)
+	if t1 != t2 {
+		t.Fatalf("ParseInLocation(Feb 01 2013 AST, Baghdad) = %v, want %v", t1, t2)
+	}
+	_, offset := t1.Zone()
+	if offset != 3*60*60 {
+		t.Fatalf("ParseInLocation(Feb 01 2013 AST, Baghdad).Zone = _, %d, want _, %d", offset, 3*60*60)
+	}
+
+	blancSablon, err := LoadLocation("America/Blanc-Sablon")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	t1, err = ParseInLocation("Jan 02 2006 MST", "Feb 01 2013 AST", blancSablon)
+	if err != nil {
+		t.Fatal(err)
+	}
+	t2 = Date(2013, February, 1, 00, 00, 00, 0, blancSablon)
+	if t1 != t2 {
+		t.Fatalf("ParseInLocation(Feb 01 2013 AST, Blanc-Sablon) = %v, want %v", t1, t2)
+	}
+	_, offset = t1.Zone()
+	if offset != -4*60*60 {
+		t.Fatalf("ParseInLocation(Feb 01 2013 AST, Blanc-Sablon).Zone = _, %d, want _, %d", offset, -4*60*60)
+	}
+}
+
+func TestLoadLocationZipFile(t *testing.T) {
+	ForceZipFileForTesting(true)
+	defer ForceZipFileForTesting(false)
+
+	_, err := LoadLocation("Australia/Sydney")
+	if err != nil {
+		t.Fatal(err)
+	}
+}
+
+var rubyTests = []ParseTest{
+	{"RubyDate", RubyDate, "Thu Feb 04 21:00:57 -0800 2010", true, true, 1, 0},
+	// Ignore the time zone in the test. If it parses, it'll be OK.
+	{"RubyDate", RubyDate, "Thu Feb 04 21:00:57 -0000 2010", false, true, 1, 0},
+	{"RubyDate", RubyDate, "Thu Feb 04 21:00:57 +0000 2010", false, true, 1, 0},
+	{"RubyDate", RubyDate, "Thu Feb 04 21:00:57 +1130 2010", false, true, 1, 0},
+}
+
+// Problematic time zone format needs special tests.
+func TestRubyParse(t *testing.T) {
+	for _, test := range rubyTests {
+		time, err := Parse(test.format, test.value)
+		if err != nil {
+			t.Errorf("%s error: %v", test.name, err)
+		} else {
+			checkTime(time, &test, t)
+		}
+	}
+}
+
+func checkTime(time Time, test *ParseTest, t *testing.T) {
+	// The time should be Thu Feb  4 21:00:57 PST 2010
+	if test.yearSign >= 0 && test.yearSign*time.Year() != 2010 {
+		t.Errorf("%s: bad year: %d not %d", test.name, time.Year(), 2010)
+	}
+	if time.Month() != February {
+		t.Errorf("%s: bad month: %s not %s", test.name, time.Month(), February)
+	}
+	if time.Day() != 4 {
+		t.Errorf("%s: bad day: %d not %d", test.name, time.Day(), 4)
+	}
+	if time.Hour() != 21 {
+		t.Errorf("%s: bad hour: %d not %d", test.name, time.Hour(), 21)
+	}
+	if time.Minute() != 0 {
+		t.Errorf("%s: bad minute: %d not %d", test.name, time.Minute(), 0)
+	}
+	if time.Second() != 57 {
+		t.Errorf("%s: bad second: %d not %d", test.name, time.Second(), 57)
+	}
+	// Nanoseconds must be checked against the precision of the input.
+	nanosec, err := strconv.ParseUint("012345678"[:test.fracDigits]+"000000000"[:9-test.fracDigits], 10, 0)
+	if err != nil {
+		panic(err)
+	}
+	if time.Nanosecond() != int(nanosec) {
+		t.Errorf("%s: bad nanosecond: %d not %d", test.name, time.Nanosecond(), nanosec)
+	}
+	name, offset := time.Zone()
+	if test.hasTZ && offset != -28800 {
+		t.Errorf("%s: bad tz offset: %s %d not %d", test.name, name, offset, -28800)
+	}
+	if test.hasWD && time.Weekday() != Thursday {
+		t.Errorf("%s: bad weekday: %s not %s", test.name, time.Weekday(), Thursday)
+	}
+}
+
+func TestFormatAndParse(t *testing.T) {
+	const fmt = "Mon MST " + RFC3339 // all fields
+	f := func(sec int64) bool {
+		t1 := Unix(sec, 0)
+		if t1.Year() < 1000 || t1.Year() > 9999 {
+			// not required to work
+			return true
+		}
+		t2, err := Parse(fmt, t1.Format(fmt))
+		if err != nil {
+			t.Errorf("error: %s", err)
+			return false
+		}
+		if t1.Unix() != t2.Unix() || t1.Nanosecond() != t2.Nanosecond() {
+			t.Errorf("FormatAndParse %d: %q(%d) %q(%d)", sec, t1, t1.Unix(), t2, t2.Unix())
+			return false
+		}
+		return true
+	}
+	f32 := func(sec int32) bool { return f(int64(sec)) }
+	cfg := &quick.Config{MaxCount: 10000}
+
+	// Try a reasonable date first, then the huge ones.
+	if err := quick.Check(f32, cfg); err != nil {
+		t.Fatal(err)
+	}
+	if err := quick.Check(f, cfg); err != nil {
+		t.Fatal(err)
+	}
+}
+
+type ParseTimeZoneTest struct {
+	value  string
+	length int
+	ok     bool
+}
+
+var parseTimeZoneTests = []ParseTimeZoneTest{
+	{"gmt hi there", 0, false},
+	{"GMT hi there", 3, true},
+	{"GMT+12 hi there", 6, true},
+	{"GMT+00 hi there", 3, true}, // 0 or 00 is not a legal offset.
+	{"GMT-5 hi there", 5, true},
+	{"GMT-51 hi there", 3, true},
+	{"ChST hi there", 4, true},
+	{"MeST hi there", 4, true},
+	{"MSDx", 3, true},
+	{"MSDY", 0, false}, // four letters must end in T.
+	{"ESAST hi", 5, true},
+	{"ESASTT hi", 0, false}, // run of upper-case letters too long.
+	{"ESATY hi", 0, false},  // five letters must end in T.
+}
+
+func TestParseTimeZone(t *testing.T) {
+	for _, test := range parseTimeZoneTests {
+		length, ok := ParseTimeZone(test.value)
+		if ok != test.ok {
+			t.Errorf("expected %t for %q got %t", test.ok, test.value, ok)
+		} else if length != test.length {
+			t.Errorf("expected %d for %q got %d", test.length, test.value, length)
+		}
+	}
+}
+
+type ParseErrorTest struct {
+	format string
+	value  string
+	expect string // must appear within the error
+}
+
+var parseErrorTests = []ParseErrorTest{
+	{ANSIC, "Feb  4 21:00:60 2010", "cannot parse"}, // cannot parse Feb as Mon
+	{ANSIC, "Thu Feb  4 21:00:57 @2010", "cannot parse"},
+	{ANSIC, "Thu Feb  4 21:00:60 2010", "second out of range"},
+	{ANSIC, "Thu Feb  4 21:61:57 2010", "minute out of range"},
+	{ANSIC, "Thu Feb  4 24:00:60 2010", "hour out of range"},
+	{"Mon Jan _2 15:04:05.000 2006", "Thu Feb  4 23:00:59x01 2010", "cannot parse"},
+	{"Mon Jan _2 15:04:05.000 2006", "Thu Feb  4 23:00:59.xxx 2010", "cannot parse"},
+	{"Mon Jan _2 15:04:05.000 2006", "Thu Feb  4 23:00:59.-123 2010", "fractional second out of range"},
+	// issue 4502. StampNano requires exactly 9 digits of precision.
+	{StampNano, "Dec  7 11:22:01.000000", `cannot parse ".000000" as ".000000000"`},
+	{StampNano, "Dec  7 11:22:01.0000000000", "extra text: 0"},
+	// issue 4493. Helpful errors.
+	{RFC3339, "2006-01-02T15:04:05Z07:00", `parsing time "2006-01-02T15:04:05Z07:00": extra text: 07:00`},
+	{RFC3339, "2006-01-02T15:04_abc", `parsing time "2006-01-02T15:04_abc" as "2006-01-02T15:04:05Z07:00": cannot parse "_abc" as ":"`},
+	{RFC3339, "2006-01-02T15:04:05_abc", `parsing time "2006-01-02T15:04:05_abc" as "2006-01-02T15:04:05Z07:00": cannot parse "_abc" as "Z07:00"`},
+	{RFC3339, "2006-01-02T15:04:05Z_abc", `parsing time "2006-01-02T15:04:05Z_abc": extra text: _abc`},
+}
+
+func TestParseErrors(t *testing.T) {
+	for _, test := range parseErrorTests {
+		_, 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 {
+			t.Errorf("expected error with %q for %q %q; got %s", test.expect, test.format, test.value, err)
+		}
+	}
+}
+
+func TestNoonIs12PM(t *testing.T) {
+	noon := Date(0, January, 1, 12, 0, 0, 0, UTC)
+	const expect = "12:00PM"
+	got := noon.Format("3:04PM")
+	if got != expect {
+		t.Errorf("got %q; expect %q", got, expect)
+	}
+	got = noon.Format("03:04PM")
+	if got != expect {
+		t.Errorf("got %q; expect %q", got, expect)
+	}
+}
+
+func TestMidnightIs12AM(t *testing.T) {
+	midnight := Date(0, January, 1, 0, 0, 0, 0, UTC)
+	expect := "12:00AM"
+	got := midnight.Format("3:04PM")
+	if got != expect {
+		t.Errorf("got %q; expect %q", got, expect)
+	}
+	got = midnight.Format("03:04PM")
+	if got != expect {
+		t.Errorf("got %q; expect %q", got, expect)
+	}
+}
+
+func Test12PMIsNoon(t *testing.T) {
+	noon, err := Parse("3:04PM", "12:00PM")
+	if err != nil {
+		t.Fatal("error parsing date:", err)
+	}
+	if noon.Hour() != 12 {
+		t.Errorf("got %d; expect 12", noon.Hour())
+	}
+	noon, err = Parse("03:04PM", "12:00PM")
+	if err != nil {
+		t.Fatal("error parsing date:", err)
+	}
+	if noon.Hour() != 12 {
+		t.Errorf("got %d; expect 12", noon.Hour())
+	}
+}
+
+func Test12AMIsMidnight(t *testing.T) {
+	midnight, err := Parse("3:04PM", "12:00AM")
+	if err != nil {
+		t.Fatal("error parsing date:", err)
+	}
+	if midnight.Hour() != 0 {
+		t.Errorf("got %d; expect 0", midnight.Hour())
+	}
+	midnight, err = Parse("03:04PM", "12:00AM")
+	if err != nil {
+		t.Fatal("error parsing date:", err)
+	}
+	if midnight.Hour() != 0 {
+		t.Errorf("got %d; expect 0", midnight.Hour())
+	}
+}
+
+// Check that a time without a Zone still produces a (numeric) time zone
+// when formatted with MST as a requested zone.
+func TestMissingZone(t *testing.T) {
+	time, err := Parse(RubyDate, "Thu Feb 02 16:10:03 -0500 2006")
+	if err != nil {
+		t.Fatal("error parsing date:", err)
+	}
+	expect := "Thu Feb  2 16:10:03 -0500 2006" // -0500 not EST
+	str := time.Format(UnixDate)               // uses MST as its time zone
+	if str != expect {
+		t.Errorf("got %s; expect %s", str, expect)
+	}
+}
+
+func TestMinutesInTimeZone(t *testing.T) {
+	time, err := Parse(RubyDate, "Mon Jan 02 15:04:05 +0123 2006")
+	if err != nil {
+		t.Fatal("error parsing date:", err)
+	}
+	expected := (1*60 + 23) * 60
+	_, offset := time.Zone()
+	if offset != expected {
+		t.Errorf("ZoneOffset = %d, want %d", offset, expected)
+	}
+}
+
+type SecondsTimeZoneOffsetTest struct {
+	format         string
+	value          string
+	expectedoffset int
+}
+
+var secondsTimeZoneOffsetTests = []SecondsTimeZoneOffsetTest{
+	{"2006-01-02T15:04:05-070000", "1871-01-01T05:33:02-003408", -(34*60 + 8)},
+	{"2006-01-02T15:04:05-07:00:00", "1871-01-01T05:33:02-00:34:08", -(34*60 + 8)},
+	{"2006-01-02T15:04:05-070000", "1871-01-01T05:33:02+003408", 34*60 + 8},
+	{"2006-01-02T15:04:05-07:00:00", "1871-01-01T05:33:02+00:34:08", 34*60 + 8},
+	{"2006-01-02T15:04:05Z070000", "1871-01-01T05:33:02-003408", -(34*60 + 8)},
+	{"2006-01-02T15:04:05Z07:00:00", "1871-01-01T05:33:02+00:34:08", 34*60 + 8},
+}
+
+func TestParseSecondsInTimeZone(t *testing.T) {
+	// should accept timezone offsets with seconds like: Zone America/New_York   -4:56:02 -      LMT     1883 Nov 18 12:03:58
+	for _, test := range secondsTimeZoneOffsetTests {
+		time, err := Parse(test.format, test.value)
+		if err != nil {
+			t.Fatal("error parsing date:", err)
+		}
+		_, offset := time.Zone()
+		if offset != test.expectedoffset {
+			t.Errorf("ZoneOffset = %d, want %d", offset, test.expectedoffset)
+		}
+	}
+}
+
+func TestFormatSecondsInTimeZone(t *testing.T) {
+	for _, test := range secondsTimeZoneOffsetTests {
+		d := Date(1871, 1, 1, 5, 33, 2, 0, FixedZone("LMT", test.expectedoffset))
+		timestr := d.Format(test.format)
+		if timestr != test.value {
+			t.Errorf("Format = %s, want %s", timestr, test.value)
+		}
+	}
+}
diff --git a/src/time/genzabbrs.go b/src/time/genzabbrs.go
new file mode 100644
index 0000000..9eb0728
--- /dev/null
+++ b/src/time/genzabbrs.go
@@ -0,0 +1,159 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build ignore
+
+//
+// usage:
+//
+// go run genzabbrs.go -output zoneinfo_abbrs_windows.go
+//
+
+package main
+
+import (
+	"bytes"
+	"encoding/xml"
+	"flag"
+	"go/format"
+	"io/ioutil"
+	"log"
+	"net/http"
+	"sort"
+	"text/template"
+	"time"
+)
+
+var filename = flag.String("output", "zoneinfo_abbrs_windows.go", "output file name")
+
+// getAbbrs finds timezone abbreviations (standard and daylight saving time)
+// for location l.
+func getAbbrs(l *time.Location) (st, dt string) {
+	t := time.Date(time.Now().Year(), 0, 0, 0, 0, 0, 0, l)
+	abbr1, off1 := t.Zone()
+	for i := 0; i < 12; i++ {
+		t = t.AddDate(0, 1, 0)
+		abbr2, off2 := t.Zone()
+		if abbr1 != abbr2 {
+			if off2-off1 < 0 { // southern hemisphere
+				abbr1, abbr2 = abbr2, abbr1
+			}
+			return abbr1, abbr2
+		}
+	}
+	return abbr1, abbr1
+}
+
+type zone struct {
+	WinName  string
+	UnixName string
+	StTime   string
+	DSTime   string
+}
+
+type zones []*zone
+
+func (zs zones) Len() int           { return len(zs) }
+func (zs zones) Swap(i, j int)      { zs[i], zs[j] = zs[j], zs[i] }
+func (zs zones) Less(i, j int) bool { return zs[i].UnixName < zs[j].UnixName }
+
+const wzURL = "http://unicode.org/cldr/data/common/supplemental/windowsZones.xml"
+
+type MapZone struct {
+	Other     string `xml:"other,attr"`
+	Territory string `xml:"territory,attr"`
+	Type      string `xml:"type,attr"`
+}
+
+type SupplementalData struct {
+	Zones []MapZone `xml:"windowsZones>mapTimezones>mapZone"`
+}
+
+func readWindowsZones() (zones, error) {
+	r, err := http.Get(wzURL)
+	if err != nil {
+		return nil, err
+	}
+	defer r.Body.Close()
+
+	data, err := ioutil.ReadAll(r.Body)
+	if err != nil {
+		return nil, err
+	}
+
+	var sd SupplementalData
+	err = xml.Unmarshal(data, &sd)
+	if err != nil {
+		return nil, err
+	}
+	zs := make(zones, 0)
+	for _, z := range sd.Zones {
+		if z.Territory != "001" {
+			// to avoid dups. I don't know why.
+			continue
+		}
+		l, err := time.LoadLocation(z.Type)
+		if err != nil {
+			return nil, err
+		}
+		st, dt := getAbbrs(l)
+		zs = append(zs, &zone{
+			WinName:  z.Other,
+			UnixName: z.Type,
+			StTime:   st,
+			DSTime:   dt,
+		})
+	}
+	return zs, nil
+}
+
+func main() {
+	flag.Parse()
+	zs, err := readWindowsZones()
+	if err != nil {
+		log.Fatal(err)
+	}
+	sort.Sort(zs)
+	var v = struct {
+		URL string
+		Zs  zones
+	}{
+		wzURL,
+		zs,
+	}
+	var buf bytes.Buffer
+	err = template.Must(template.New("prog").Parse(prog)).Execute(&buf, v)
+	if err != nil {
+		log.Fatal(err)
+	}
+	data, err := format.Source(buf.Bytes())
+	if err != nil {
+		log.Fatal(err)
+	}
+	err = ioutil.WriteFile(*filename, data, 0644)
+	if err != nil {
+		log.Fatal(err)
+	}
+}
+
+const prog = `
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// generated by genzabbrs.go from
+// {{.URL}}
+
+package time
+
+type abbr struct {
+	std string
+	dst string
+}
+
+var abbrs = map[string]abbr{
+{{range .Zs}}	"{{.WinName}}": {"{{.StTime}}", "{{.DSTime}}"}, // {{.UnixName}}
+{{end}}}
+
+`
diff --git a/src/time/internal_test.go b/src/time/internal_test.go
new file mode 100644
index 0000000..edd523b
--- /dev/null
+++ b/src/time/internal_test.go
@@ -0,0 +1,59 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package time
+
+func init() {
+	// force US/Pacific for time zone tests
+	ForceUSPacificForTesting()
+}
+
+var Interrupt = interrupt
+var DaysIn = daysIn
+
+func empty(arg interface{}, seq uintptr) {}
+
+// Test that a runtimeTimer with a duration so large it overflows
+// does not cause other timers to hang.
+//
+// This test has to be in internal_test.go since it fiddles with
+// unexported data structures.
+func CheckRuntimeTimerOverflow() {
+	// We manually create a runtimeTimer to bypass the overflow
+	// detection logic in NewTimer: we're testing the underlying
+	// runtime.addtimer function.
+	r := &runtimeTimer{
+		when: runtimeNano() + (1<<63 - 1),
+		f:    empty,
+		arg:  nil,
+	}
+	startTimer(r)
+
+	// Start a goroutine that should send on t.C right away.
+	t := NewTimer(1)
+
+	defer func() {
+		// Subsequent tests won't work correctly if we don't stop the
+		// overflow timer and kick the timer proc back into service.
+		//
+		// The timer proc is now sleeping and can only be awoken by
+		// adding a timer to the *beginning* of the heap. We can't
+		// wake it up by calling NewTimer since other tests may have
+		// left timers running that should have expired before ours.
+		// Instead we zero the overflow timer duration and start it
+		// once more.
+		stopTimer(r)
+		t.Stop()
+		r.when = 0
+		startTimer(r)
+	}()
+
+	// If the test fails, we will hang here until the timeout in the testing package
+	// fires, which is 10 minutes. It would be nice to catch the problem sooner,
+	// but there is no reliable way to guarantee that timerproc schedules without
+	// doing something involving timerproc itself. Previous failed attempts have
+	// tried calling runtime.Gosched and runtime.GC, but neither is reliable.
+	// So we fall back to hope: We hope we don't hang here.
+	<-t.C
+}
diff --git a/src/time/sleep.go b/src/time/sleep.go
new file mode 100644
index 0000000..e7a2ee2
--- /dev/null
+++ b/src/time/sleep.go
@@ -0,0 +1,130 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package time
+
+// Sleep pauses the current goroutine for at least the duration d.
+// A negative or zero duration causes Sleep to return immediately.
+func Sleep(d Duration)
+
+// runtimeNano returns the current value of the runtime clock in nanoseconds.
+func runtimeNano() int64
+
+// Interface to timers implemented in package runtime.
+// Must be in sync with ../runtime/runtime.h:/^struct.Timer$
+type runtimeTimer struct {
+	i      int
+	when   int64
+	period int64
+	f      func(interface{}, uintptr) // NOTE: must not be closure
+	arg    interface{}
+	seq    uintptr
+}
+
+// when is a helper function for setting the 'when' field of a runtimeTimer.
+// It returns what the time will be, in nanoseconds, Duration d in the future.
+// If d is negative, it is ignored.  If the returned value would be less than
+// zero because of an overflow, MaxInt64 is returned.
+func when(d Duration) int64 {
+	if d <= 0 {
+		return runtimeNano()
+	}
+	t := runtimeNano() + int64(d)
+	if t < 0 {
+		t = 1<<63 - 1 // math.MaxInt64
+	}
+	return t
+}
+
+func startTimer(*runtimeTimer)
+func stopTimer(*runtimeTimer) bool
+
+// The Timer type represents a single event.
+// When the Timer expires, the current time will be sent on C,
+// unless the Timer was created by AfterFunc.
+// A Timer must be created with NewTimer or AfterFunc.
+type Timer struct {
+	C <-chan Time
+	r runtimeTimer
+}
+
+// Stop prevents the Timer from firing.
+// It returns true if the call stops the timer, false if the timer has already
+// expired or been stopped.
+// Stop does not close the channel, to prevent a read from the channel succeeding
+// incorrectly.
+func (t *Timer) Stop() bool {
+	if t.r.f == nil {
+		panic("time: Stop called on uninitialized Timer")
+	}
+	return stopTimer(&t.r)
+}
+
+// NewTimer creates a new Timer that will send
+// the current time on its channel after at least duration d.
+func NewTimer(d Duration) *Timer {
+	c := make(chan Time, 1)
+	t := &Timer{
+		C: c,
+		r: runtimeTimer{
+			when: when(d),
+			f:    sendTime,
+			arg:  c,
+		},
+	}
+	startTimer(&t.r)
+	return t
+}
+
+// Reset changes the timer to expire after duration d.
+// It returns true if the timer had been active, false if the timer had
+// expired or been stopped.
+func (t *Timer) Reset(d Duration) bool {
+	if t.r.f == nil {
+		panic("time: Reset called on uninitialized Timer")
+	}
+	w := when(d)
+	active := stopTimer(&t.r)
+	t.r.when = w
+	startTimer(&t.r)
+	return active
+}
+
+func sendTime(c interface{}, seq uintptr) {
+	// Non-blocking send of time on c.
+	// Used in NewTimer, it cannot block anyway (buffer).
+	// Used in NewTicker, dropping sends on the floor is
+	// the desired behavior when the reader gets behind,
+	// because the sends are periodic.
+	select {
+	case c.(chan Time) <- Now():
+	default:
+	}
+}
+
+// After waits for the duration to elapse and then sends the current time
+// on the returned channel.
+// It is equivalent to NewTimer(d).C.
+func After(d Duration) <-chan Time {
+	return NewTimer(d).C
+}
+
+// AfterFunc waits for the duration to elapse and then calls f
+// in its own goroutine. It returns a Timer that can
+// be used to cancel the call using its Stop method.
+func AfterFunc(d Duration, f func()) *Timer {
+	t := &Timer{
+		r: runtimeTimer{
+			when: when(d),
+			f:    goFunc,
+			arg:  f,
+		},
+	}
+	startTimer(&t.r)
+	return t
+}
+
+func goFunc(arg interface{}, seq uintptr) {
+	go arg.(func())()
+}
diff --git a/src/time/sleep_test.go b/src/time/sleep_test.go
new file mode 100644
index 0000000..c9b2956
--- /dev/null
+++ b/src/time/sleep_test.go
@@ -0,0 +1,430 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package time_test
+
+import (
+	"errors"
+	"fmt"
+	"runtime"
+	"sort"
+	"strings"
+	"sync"
+	"sync/atomic"
+	"testing"
+	. "time"
+)
+
+// Go runtime uses different Windows timers for time.Now and sleeping.
+// These can tick at different frequencies and can arrive out of sync.
+// The effect can be seen, for example, as time.Sleep(100ms) is actually
+// shorter then 100ms when measured as difference between time.Now before and
+// after time.Sleep call. This was observed on Windows XP SP3 (windows/386).
+// windowsInaccuracy is to ignore such errors.
+const windowsInaccuracy = 17 * Millisecond
+
+func TestSleep(t *testing.T) {
+	const delay = 100 * Millisecond
+	go func() {
+		Sleep(delay / 2)
+		Interrupt()
+	}()
+	start := Now()
+	Sleep(delay)
+	delayadj := delay
+	if runtime.GOOS == "windows" {
+		delayadj -= windowsInaccuracy
+	}
+	duration := Now().Sub(start)
+	if duration < delayadj {
+		t.Fatalf("Sleep(%s) slept for only %s", delay, duration)
+	}
+}
+
+// Test the basic function calling behavior. Correct queueing
+// behavior is tested elsewhere, since After and AfterFunc share
+// the same code.
+func TestAfterFunc(t *testing.T) {
+	i := 10
+	c := make(chan bool)
+	var f func()
+	f = func() {
+		i--
+		if i >= 0 {
+			AfterFunc(0, f)
+			Sleep(1 * Second)
+		} else {
+			c <- true
+		}
+	}
+
+	AfterFunc(0, f)
+	<-c
+}
+
+func TestAfterStress(t *testing.T) {
+	stop := uint32(0)
+	go func() {
+		for atomic.LoadUint32(&stop) == 0 {
+			runtime.GC()
+			// Yield so that the OS can wake up the timer thread,
+			// so that it can generate channel sends for the main goroutine,
+			// which will eventually set stop = 1 for us.
+			Sleep(Nanosecond)
+		}
+	}()
+	ticker := NewTicker(1)
+	for i := 0; i < 100; i++ {
+		<-ticker.C
+	}
+	ticker.Stop()
+	atomic.StoreUint32(&stop, 1)
+}
+
+func benchmark(b *testing.B, bench func(n int)) {
+	garbage := make([]*Timer, 1<<17)
+	for i := 0; i < len(garbage); i++ {
+		garbage[i] = AfterFunc(Hour, nil)
+	}
+	b.ResetTimer()
+
+	b.RunParallel(func(pb *testing.PB) {
+		for pb.Next() {
+			bench(1000)
+		}
+	})
+
+	b.StopTimer()
+	for i := 0; i < len(garbage); i++ {
+		garbage[i].Stop()
+	}
+}
+
+func BenchmarkAfterFunc(b *testing.B) {
+	benchmark(b, func(n int) {
+		c := make(chan bool)
+		var f func()
+		f = func() {
+			n--
+			if n >= 0 {
+				AfterFunc(0, f)
+			} else {
+				c <- true
+			}
+		}
+
+		AfterFunc(0, f)
+		<-c
+	})
+}
+
+func BenchmarkAfter(b *testing.B) {
+	benchmark(b, func(n int) {
+		for i := 0; i < n; i++ {
+			<-After(1)
+		}
+	})
+}
+
+func BenchmarkStop(b *testing.B) {
+	benchmark(b, func(n int) {
+		for i := 0; i < n; i++ {
+			NewTimer(1 * Second).Stop()
+		}
+	})
+}
+
+func BenchmarkSimultaneousAfterFunc(b *testing.B) {
+	benchmark(b, func(n int) {
+		var wg sync.WaitGroup
+		wg.Add(n)
+		for i := 0; i < n; i++ {
+			AfterFunc(0, wg.Done)
+		}
+		wg.Wait()
+	})
+}
+
+func BenchmarkStartStop(b *testing.B) {
+	benchmark(b, func(n int) {
+		timers := make([]*Timer, n)
+		for i := 0; i < n; i++ {
+			timers[i] = AfterFunc(Hour, nil)
+		}
+
+		for i := 0; i < n; i++ {
+			timers[i].Stop()
+		}
+	})
+}
+
+func TestAfter(t *testing.T) {
+	const delay = 100 * Millisecond
+	start := Now()
+	end := <-After(delay)
+	delayadj := delay
+	if runtime.GOOS == "windows" {
+		delayadj -= windowsInaccuracy
+	}
+	if duration := Now().Sub(start); duration < delayadj {
+		t.Fatalf("After(%s) slept for only %d ns", delay, duration)
+	}
+	if min := start.Add(delayadj); end.Before(min) {
+		t.Fatalf("After(%s) expect >= %s, got %s", delay, min, end)
+	}
+}
+
+func TestAfterTick(t *testing.T) {
+	const Count = 10
+	Delta := 100 * Millisecond
+	if testing.Short() {
+		Delta = 10 * Millisecond
+	}
+	t0 := Now()
+	for i := 0; i < Count; i++ {
+		<-After(Delta)
+	}
+	t1 := Now()
+	d := t1.Sub(t0)
+	target := Delta * Count
+	if d < target*9/10 {
+		t.Fatalf("%d ticks of %s too fast: took %s, expected %s", Count, Delta, d, target)
+	}
+	if !testing.Short() && d > target*30/10 {
+		t.Fatalf("%d ticks of %s too slow: took %s, expected %s", Count, Delta, d, target)
+	}
+}
+
+func TestAfterStop(t *testing.T) {
+	AfterFunc(100*Millisecond, func() {})
+	t0 := NewTimer(50 * Millisecond)
+	c1 := make(chan bool, 1)
+	t1 := AfterFunc(150*Millisecond, func() { c1 <- true })
+	c2 := After(200 * Millisecond)
+	if !t0.Stop() {
+		t.Fatalf("failed to stop event 0")
+	}
+	if !t1.Stop() {
+		t.Fatalf("failed to stop event 1")
+	}
+	<-c2
+	select {
+	case <-t0.C:
+		t.Fatalf("event 0 was not stopped")
+	case <-c1:
+		t.Fatalf("event 1 was not stopped")
+	default:
+	}
+	if t1.Stop() {
+		t.Fatalf("Stop returned true twice")
+	}
+}
+
+func TestAfterQueuing(t *testing.T) {
+	// This test flakes out on some systems,
+	// so we'll try it a few times before declaring it a failure.
+	const attempts = 3
+	err := errors.New("!=nil")
+	for i := 0; i < attempts && err != nil; i++ {
+		if err = testAfterQueuing(t); err != nil {
+			t.Logf("attempt %v failed: %v", i, err)
+		}
+	}
+	if err != nil {
+		t.Fatal(err)
+	}
+}
+
+var slots = []int{5, 3, 6, 6, 6, 1, 1, 2, 7, 9, 4, 8, 0}
+
+type afterResult struct {
+	slot int
+	t    Time
+}
+
+func await(slot int, result chan<- afterResult, ac <-chan Time) {
+	result <- afterResult{slot, <-ac}
+}
+
+func testAfterQueuing(t *testing.T) error {
+	Delta := 100 * Millisecond
+	if testing.Short() {
+		Delta = 20 * Millisecond
+	}
+	// make the result channel buffered because we don't want
+	// to depend on channel queueing semantics that might
+	// possibly change in the future.
+	result := make(chan afterResult, len(slots))
+
+	t0 := Now()
+	for _, slot := range slots {
+		go await(slot, result, After(Duration(slot)*Delta))
+	}
+	sort.Ints(slots)
+	for _, slot := range slots {
+		r := <-result
+		if r.slot != slot {
+			return fmt.Errorf("after slot %d, expected %d", r.slot, slot)
+		}
+		dt := r.t.Sub(t0)
+		target := Duration(slot) * Delta
+		if dt < target-Delta/2 || dt > target+Delta*10 {
+			return fmt.Errorf("After(%s) arrived at %s, expected [%s,%s]", target, dt, target-Delta/2, target+Delta*10)
+		}
+	}
+	return nil
+}
+
+func TestTimerStopStress(t *testing.T) {
+	if testing.Short() {
+		return
+	}
+	for i := 0; i < 100; i++ {
+		go func(i int) {
+			timer := AfterFunc(2*Second, func() {
+				t.Fatalf("timer %d was not stopped", i)
+			})
+			Sleep(1 * Second)
+			timer.Stop()
+		}(i)
+	}
+	Sleep(3 * Second)
+}
+
+func TestSleepZeroDeadlock(t *testing.T) {
+	// Sleep(0) used to hang, the sequence of events was as follows.
+	// Sleep(0) sets G's status to Gwaiting, but then immediately returns leaving the status.
+	// Then the goroutine calls e.g. new and falls down into the scheduler due to pending GC.
+	// After the GC nobody wakes up the goroutine from Gwaiting status.
+	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4))
+	c := make(chan bool)
+	go func() {
+		for i := 0; i < 100; i++ {
+			runtime.GC()
+		}
+		c <- true
+	}()
+	for i := 0; i < 100; i++ {
+		Sleep(0)
+		tmp := make(chan bool, 1)
+		tmp <- true
+		<-tmp
+	}
+	<-c
+}
+
+func testReset(d Duration) error {
+	t0 := NewTimer(2 * d)
+	Sleep(d)
+	if t0.Reset(3*d) != true {
+		return errors.New("resetting unfired timer returned false")
+	}
+	Sleep(2 * d)
+	select {
+	case <-t0.C:
+		return errors.New("timer fired early")
+	default:
+	}
+	Sleep(2 * d)
+	select {
+	case <-t0.C:
+	default:
+		return errors.New("reset timer did not fire")
+	}
+
+	if t0.Reset(50*Millisecond) != false {
+		return errors.New("resetting expired timer returned true")
+	}
+	return nil
+}
+
+func TestReset(t *testing.T) {
+	// We try to run this test with increasingly larger multiples
+	// until one works so slow, loaded hardware isn't as flaky,
+	// but without slowing down fast machines unnecessarily.
+	const unit = 25 * Millisecond
+	tries := []Duration{
+		1 * unit,
+		3 * unit,
+		7 * unit,
+		15 * unit,
+	}
+	var err error
+	for _, d := range tries {
+		err = testReset(d)
+		if err == nil {
+			t.Logf("passed using duration %v", d)
+			return
+		}
+	}
+	t.Error(err)
+}
+
+// Test that sleeping for an interval so large it overflows does not
+// result in a short sleep duration.
+func TestOverflowSleep(t *testing.T) {
+	const big = Duration(int64(1<<63 - 1))
+	select {
+	case <-After(big):
+		t.Fatalf("big timeout fired")
+	case <-After(25 * Millisecond):
+		// OK
+	}
+	const neg = Duration(-1 << 63)
+	select {
+	case <-After(neg):
+		// OK
+	case <-After(1 * Second):
+		t.Fatalf("negative timeout didn't fire")
+	}
+}
+
+// Test that a panic while deleting a timer does not leave
+// the timers mutex held, deadlocking a ticker.Stop in a defer.
+func TestIssue5745(t *testing.T) {
+	ticker := NewTicker(Hour)
+	defer func() {
+		// would deadlock here before the fix due to
+		// lock taken before the segfault.
+		ticker.Stop()
+
+		if r := recover(); r == nil {
+			t.Error("Expected panic, but none happened.")
+		}
+	}()
+
+	// cause a panic due to a segfault
+	var timer *Timer
+	timer.Stop()
+	t.Error("Should be unreachable.")
+}
+
+func TestOverflowRuntimeTimer(t *testing.T) {
+	if testing.Short() {
+		t.Skip("skipping in short mode, see issue 6874")
+	}
+	// This may hang forever if timers are broken. See comment near
+	// the end of CheckRuntimeTimerOverflow in internal_test.go.
+	CheckRuntimeTimerOverflow()
+}
+
+func checkZeroPanicString(t *testing.T) {
+	e := recover()
+	s, _ := e.(string)
+	if want := "called on uninitialized Timer"; !strings.Contains(s, want) {
+		t.Errorf("panic = %v; want substring %q", e, want)
+	}
+}
+
+func TestZeroTimerResetPanics(t *testing.T) {
+	defer checkZeroPanicString(t)
+	var tr Timer
+	tr.Reset(1)
+}
+
+func TestZeroTimerStopPanics(t *testing.T) {
+	defer checkZeroPanicString(t)
+	var tr Timer
+	tr.Stop()
+}
diff --git a/src/pkg/time/sys_plan9.go b/src/time/sys_plan9.go
similarity index 100%
rename from src/pkg/time/sys_plan9.go
rename to src/time/sys_plan9.go
diff --git a/src/pkg/time/sys_unix.go b/src/time/sys_unix.go
similarity index 100%
rename from src/pkg/time/sys_unix.go
rename to src/time/sys_unix.go
diff --git a/src/pkg/time/sys_windows.go b/src/time/sys_windows.go
similarity index 100%
rename from src/pkg/time/sys_windows.go
rename to src/time/sys_windows.go
diff --git a/src/pkg/time/tick.go b/src/time/tick.go
similarity index 100%
rename from src/pkg/time/tick.go
rename to src/time/tick.go
diff --git a/src/pkg/time/tick_test.go b/src/time/tick_test.go
similarity index 100%
rename from src/pkg/time/tick_test.go
rename to src/time/tick_test.go
diff --git a/src/time/time.go b/src/time/time.go
new file mode 100644
index 0000000..0300e84
--- /dev/null
+++ b/src/time/time.go
@@ -0,0 +1,1203 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package time provides functionality for measuring and displaying time.
+//
+// The calendrical calculations always assume a Gregorian calendar.
+package time
+
+import "errors"
+
+// A Time represents an instant in time with nanosecond precision.
+//
+// Programs using times should typically store and pass them as values,
+// not pointers.  That is, time variables and struct fields should be of
+// type time.Time, not *time.Time.  A Time value can be used by
+// multiple goroutines simultaneously.
+//
+// Time instants can be compared using the Before, After, and Equal methods.
+// The Sub method subtracts two instants, producing a Duration.
+// The Add method adds a Time and a Duration, producing a Time.
+//
+// The zero value of type Time is January 1, year 1, 00:00:00.000000000 UTC.
+// As this time is unlikely to come up in practice, the IsZero method gives
+// a simple way of detecting a time that has not been initialized explicitly.
+//
+// Each Time has associated with it a Location, consulted when computing the
+// presentation form of the time, such as in the Format, Hour, and Year methods.
+// The methods Local, UTC, and In return a Time with a specific location.
+// Changing the location in this way changes only the presentation; it does not
+// change the instant in time being denoted and therefore does not affect the
+// computations described in earlier paragraphs.
+//
+// Note that the Go == operator compares not just the time instant but also the
+// Location. Therefore, Time values should not be used as map or database keys
+// without first guaranteeing that the identical Location has been set for all
+// values, which can be achieved through use of the UTC or Local method.
+//
+type Time struct {
+	// sec gives the number of seconds elapsed since
+	// January 1, year 1 00:00:00 UTC.
+	sec int64
+
+	// nsec specifies a non-negative nanosecond
+	// offset within the second named by Seconds.
+	// It must be in the range [0, 999999999].
+	nsec int32
+
+	// loc specifies the Location that should be used to
+	// determine the minute, hour, month, day, and year
+	// that correspond to this Time.
+	// Only the zero Time has a nil Location.
+	// In that case it is interpreted to mean UTC.
+	loc *Location
+}
+
+// After reports whether the time instant t is after u.
+func (t Time) After(u Time) bool {
+	return t.sec > u.sec || t.sec == u.sec && t.nsec > u.nsec
+}
+
+// Before reports whether the time instant t is before u.
+func (t Time) Before(u Time) bool {
+	return t.sec < u.sec || t.sec == u.sec && t.nsec < u.nsec
+}
+
+// Equal reports whether t and u represent the same time instant.
+// Two times can be equal even if they are in different locations.
+// For example, 6:00 +0200 CEST and 4:00 UTC are Equal.
+// This comparison is different from using t == u, which also compares
+// the locations.
+func (t Time) Equal(u Time) bool {
+	return t.sec == u.sec && t.nsec == u.nsec
+}
+
+// A Month specifies a month of the year (January = 1, ...).
+type Month int
+
+const (
+	January Month = 1 + iota
+	February
+	March
+	April
+	May
+	June
+	July
+	August
+	September
+	October
+	November
+	December
+)
+
+var months = [...]string{
+	"January",
+	"February",
+	"March",
+	"April",
+	"May",
+	"June",
+	"July",
+	"August",
+	"September",
+	"October",
+	"November",
+	"December",
+}
+
+// String returns the English name of the month ("January", "February", ...).
+func (m Month) String() string { return months[m-1] }
+
+// A Weekday specifies a day of the week (Sunday = 0, ...).
+type Weekday int
+
+const (
+	Sunday Weekday = iota
+	Monday
+	Tuesday
+	Wednesday
+	Thursday
+	Friday
+	Saturday
+)
+
+var days = [...]string{
+	"Sunday",
+	"Monday",
+	"Tuesday",
+	"Wednesday",
+	"Thursday",
+	"Friday",
+	"Saturday",
+}
+
+// String returns the English name of the day ("Sunday", "Monday", ...).
+func (d Weekday) String() string { return days[d] }
+
+// Computations on time.
+//
+// The zero value for a Time is defined to be
+//	January 1, year 1, 00:00:00.000000000 UTC
+// which (1) looks like a zero, or as close as you can get in a date
+// (1-1-1 00:00:00 UTC), (2) is unlikely enough to arise in practice to
+// be a suitable "not set" sentinel, unlike Jan 1 1970, and (3) has a
+// non-negative year even in time zones west of UTC, unlike 1-1-0
+// 00:00:00 UTC, which would be 12-31-(-1) 19:00:00 in New York.
+//
+// The zero Time value does not force a specific epoch for the time
+// representation.  For example, to use the Unix epoch internally, we
+// could define that to distinguish a zero value from Jan 1 1970, that
+// time would be represented by sec=-1, nsec=1e9.  However, it does
+// suggest a representation, namely using 1-1-1 00:00:00 UTC as the
+// epoch, and that's what we do.
+//
+// The Add and Sub computations are oblivious to the choice of epoch.
+//
+// The presentation computations - year, month, minute, and so on - all
+// rely heavily on division and modulus by positive constants.  For
+// calendrical calculations we want these divisions to round down, even
+// for negative values, so that the remainder is always positive, but
+// Go's division (like most hardware division instructions) rounds to
+// zero.  We can still do those computations and then adjust the result
+// for a negative numerator, but it's annoying to write the adjustment
+// over and over.  Instead, we can change to a different epoch so long
+// ago that all the times we care about will be positive, and then round
+// to zero and round down coincide.  These presentation routines already
+// have to add the zone offset, so adding the translation to the
+// alternate epoch is cheap.  For example, having a non-negative time t
+// means that we can write
+//
+//	sec = t % 60
+//
+// instead of
+//
+//	sec = t % 60
+//	if sec < 0 {
+//		sec += 60
+//	}
+//
+// everywhere.
+//
+// The calendar runs on an exact 400 year cycle: a 400-year calendar
+// printed for 1970-2469 will apply as well to 2470-2869.  Even the days
+// of the week match up.  It simplifies the computations to choose the
+// cycle boundaries so that the exceptional years are always delayed as
+// long as possible.  That means choosing a year equal to 1 mod 400, so
+// that the first leap year is the 4th year, the first missed leap year
+// is the 100th year, and the missed missed leap year is the 400th year.
+// So we'd prefer instead to print a calendar for 2001-2400 and reuse it
+// for 2401-2800.
+//
+// Finally, it's convenient if the delta between the Unix epoch and
+// long-ago epoch is representable by an int64 constant.
+//
+// These three considerations—choose an epoch as early as possible, that
+// uses a year equal to 1 mod 400, and that is no more than 2⁶³ seconds
+// earlier than 1970—bring us to the year -292277022399.  We refer to
+// this year as the absolute zero year, and to times measured as a uint64
+// seconds since this year as absolute times.
+//
+// Times measured as an int64 seconds since the year 1—the representation
+// used for Time's sec field—are called internal times.
+//
+// Times measured as an int64 seconds since the year 1970 are called Unix
+// times.
+//
+// It is tempting to just use the year 1 as the absolute epoch, defining
+// that the routines are only valid for years >= 1.  However, the
+// routines would then be invalid when displaying the epoch in time zones
+// west of UTC, since it is year 0.  It doesn't seem tenable to say that
+// printing the zero time correctly isn't supported in half the time
+// zones.  By comparison, it's reasonable to mishandle some times in
+// the year -292277022399.
+//
+// All this is opaque to clients of the API and can be changed if a
+// better implementation presents itself.
+
+const (
+	// The unsigned zero year for internal calculations.
+	// Must be 1 mod 400, and times before it will not compute correctly,
+	// but otherwise can be changed at will.
+	absoluteZeroYear = -292277022399
+
+	// The year of the zero Time.
+	// Assumed by the unixToInternal computation below.
+	internalYear = 1
+
+	// The year of the zero Unix time.
+	unixYear = 1970
+
+	// Offsets to convert between internal and absolute or Unix times.
+	absoluteToInternal int64 = (absoluteZeroYear - internalYear) * 365.2425 * secondsPerDay
+	internalToAbsolute       = -absoluteToInternal
+
+	unixToInternal int64 = (1969*365 + 1969/4 - 1969/100 + 1969/400) * secondsPerDay
+	internalToUnix int64 = -unixToInternal
+)
+
+// IsZero reports whether t represents the zero time instant,
+// January 1, year 1, 00:00:00 UTC.
+func (t Time) IsZero() bool {
+	return t.sec == 0 && t.nsec == 0
+}
+
+// abs returns the time t as an absolute time, adjusted by the zone offset.
+// It is called when computing a presentation property like Month or Hour.
+func (t Time) abs() uint64 {
+	l := t.loc
+	// Avoid function calls when possible.
+	if l == nil || l == &localLoc {
+		l = l.get()
+	}
+	sec := t.sec + internalToUnix
+	if l != &utcLoc {
+		if l.cacheZone != nil && l.cacheStart <= sec && sec < l.cacheEnd {
+			sec += int64(l.cacheZone.offset)
+		} else {
+			_, offset, _, _, _ := l.lookup(sec)
+			sec += int64(offset)
+		}
+	}
+	return uint64(sec + (unixToInternal + internalToAbsolute))
+}
+
+// locabs is a combination of the Zone and abs methods,
+// extracting both return values from a single zone lookup.
+func (t Time) locabs() (name string, offset int, abs uint64) {
+	l := t.loc
+	if l == nil || l == &localLoc {
+		l = l.get()
+	}
+	// Avoid function call if we hit the local time cache.
+	sec := t.sec + internalToUnix
+	if l != &utcLoc {
+		if l.cacheZone != nil && l.cacheStart <= sec && sec < l.cacheEnd {
+			name = l.cacheZone.name
+			offset = l.cacheZone.offset
+		} else {
+			name, offset, _, _, _ = l.lookup(sec)
+		}
+		sec += int64(offset)
+	} else {
+		name = "UTC"
+	}
+	abs = uint64(sec + (unixToInternal + internalToAbsolute))
+	return
+}
+
+// Date returns the year, month, and day in which t occurs.
+func (t Time) Date() (year int, month Month, day int) {
+	year, month, day, _ = t.date(true)
+	return
+}
+
+// Year returns the year in which t occurs.
+func (t Time) Year() int {
+	year, _, _, _ := t.date(false)
+	return year
+}
+
+// Month returns the month of the year specified by t.
+func (t Time) Month() Month {
+	_, month, _, _ := t.date(true)
+	return month
+}
+
+// Day returns the day of the month specified by t.
+func (t Time) Day() int {
+	_, _, day, _ := t.date(true)
+	return day
+}
+
+// Weekday returns the day of the week specified by t.
+func (t Time) Weekday() Weekday {
+	return absWeekday(t.abs())
+}
+
+// absWeekday is like Weekday but operates on an absolute time.
+func absWeekday(abs uint64) Weekday {
+	// January 1 of the absolute year, like January 1 of 2001, was a Monday.
+	sec := (abs + uint64(Monday)*secondsPerDay) % secondsPerWeek
+	return Weekday(int(sec) / secondsPerDay)
+}
+
+// ISOWeek returns the ISO 8601 year and week number in which t occurs.
+// Week ranges from 1 to 53. Jan 01 to Jan 03 of year n might belong to
+// week 52 or 53 of year n-1, and Dec 29 to Dec 31 might belong to week 1
+// of year n+1.
+func (t Time) ISOWeek() (year, week int) {
+	year, month, day, yday := t.date(true)
+	wday := int(t.Weekday()+6) % 7 // weekday but Monday = 0.
+	const (
+		Mon int = iota
+		Tue
+		Wed
+		Thu
+		Fri
+		Sat
+		Sun
+	)
+
+	// Calculate week as number of Mondays in year up to
+	// and including today, plus 1 because the first week is week 0.
+	// Putting the + 1 inside the numerator as a + 7 keeps the
+	// numerator from being negative, which would cause it to
+	// round incorrectly.
+	week = (yday - wday + 7) / 7
+
+	// The week number is now correct under the assumption
+	// that the first Monday of the year is in week 1.
+	// If Jan 1 is a Tuesday, Wednesday, or Thursday, the first Monday
+	// is actually in week 2.
+	jan1wday := (wday - yday + 7*53) % 7
+	if Tue <= jan1wday && jan1wday <= Thu {
+		week++
+	}
+
+	// If the week number is still 0, we're in early January but in
+	// the last week of last year.
+	if week == 0 {
+		year--
+		week = 52
+		// A year has 53 weeks when Jan 1 or Dec 31 is a Thursday,
+		// meaning Jan 1 of the next year is a Friday
+		// or it was a leap year and Jan 1 of the next year is a Saturday.
+		if jan1wday == Fri || (jan1wday == Sat && isLeap(year)) {
+			week++
+		}
+	}
+
+	// December 29 to 31 are in week 1 of next year if
+	// they are after the last Thursday of the year and
+	// December 31 is a Monday, Tuesday, or Wednesday.
+	if month == December && day >= 29 && wday < Thu {
+		if dec31wday := (wday + 31 - day) % 7; Mon <= dec31wday && dec31wday <= Wed {
+			year++
+			week = 1
+		}
+	}
+
+	return
+}
+
+// Clock returns the hour, minute, and second within the day specified by t.
+func (t Time) Clock() (hour, min, sec int) {
+	return absClock(t.abs())
+}
+
+// absClock is like clock but operates on an absolute time.
+func absClock(abs uint64) (hour, min, sec int) {
+	sec = int(abs % secondsPerDay)
+	hour = sec / secondsPerHour
+	sec -= hour * secondsPerHour
+	min = sec / secondsPerMinute
+	sec -= min * secondsPerMinute
+	return
+}
+
+// Hour returns the hour within the day specified by t, in the range [0, 23].
+func (t Time) Hour() int {
+	return int(t.abs()%secondsPerDay) / secondsPerHour
+}
+
+// Minute returns the minute offset within the hour specified by t, in the range [0, 59].
+func (t Time) Minute() int {
+	return int(t.abs()%secondsPerHour) / secondsPerMinute
+}
+
+// Second returns the second offset within the minute specified by t, in the range [0, 59].
+func (t Time) Second() int {
+	return int(t.abs() % secondsPerMinute)
+}
+
+// Nanosecond returns the nanosecond offset within the second specified by t,
+// in the range [0, 999999999].
+func (t Time) Nanosecond() int {
+	return int(t.nsec)
+}
+
+// YearDay returns the day of the year specified by t, in the range [1,365] for non-leap years,
+// and [1,366] in leap years.
+func (t Time) YearDay() int {
+	_, _, _, yday := t.date(false)
+	return yday + 1
+}
+
+// A Duration represents the elapsed time between two instants
+// as an int64 nanosecond count.  The representation limits the
+// largest representable duration to approximately 290 years.
+type Duration int64
+
+const (
+	minDuration Duration = -1 << 63
+	maxDuration Duration = 1<<63 - 1
+)
+
+// Common durations.  There is no definition for units of Day or larger
+// to avoid confusion across daylight savings time zone transitions.
+//
+// To count the number of units in a Duration, divide:
+//	second := time.Second
+//	fmt.Print(int64(second/time.Millisecond)) // prints 1000
+//
+// To convert an integer number of units to a Duration, multiply:
+//	seconds := 10
+//	fmt.Print(time.Duration(seconds)*time.Second) // prints 10s
+//
+const (
+	Nanosecond  Duration = 1
+	Microsecond          = 1000 * Nanosecond
+	Millisecond          = 1000 * Microsecond
+	Second               = 1000 * Millisecond
+	Minute               = 60 * Second
+	Hour                 = 60 * Minute
+)
+
+// String returns a string representing the duration in the form "72h3m0.5s".
+// Leading zero units are omitted.  As a special case, durations less than one
+// second format use a smaller unit (milli-, micro-, or nanoseconds) to ensure
+// that the leading digit is non-zero.  The zero duration formats as 0,
+// with no unit.
+func (d Duration) String() string {
+	// Largest time is 2540400h10m10.000000000s
+	var buf [32]byte
+	w := len(buf)
+
+	u := uint64(d)
+	neg := d < 0
+	if neg {
+		u = -u
+	}
+
+	if u < uint64(Second) {
+		// Special case: if duration is smaller than a second,
+		// use smaller units, like 1.2ms
+		var prec int
+		w--
+		buf[w] = 's'
+		w--
+		switch {
+		case u == 0:
+			return "0"
+		case u < uint64(Microsecond):
+			// print nanoseconds
+			prec = 0
+			buf[w] = 'n'
+		case u < uint64(Millisecond):
+			// print microseconds
+			prec = 3
+			// U+00B5 'µ' micro sign == 0xC2 0xB5
+			w-- // Need room for two bytes.
+			copy(buf[w:], "µ")
+		default:
+			// print milliseconds
+			prec = 6
+			buf[w] = 'm'
+		}
+		w, u = fmtFrac(buf[:w], u, prec)
+		w = fmtInt(buf[:w], u)
+	} else {
+		w--
+		buf[w] = 's'
+
+		w, u = fmtFrac(buf[:w], u, 9)
+
+		// u is now integer seconds
+		w = fmtInt(buf[:w], u%60)
+		u /= 60
+
+		// u is now integer minutes
+		if u > 0 {
+			w--
+			buf[w] = 'm'
+			w = fmtInt(buf[:w], u%60)
+			u /= 60
+
+			// u is now integer hours
+			// Stop at hours because days can be different lengths.
+			if u > 0 {
+				w--
+				buf[w] = 'h'
+				w = fmtInt(buf[:w], u)
+			}
+		}
+	}
+
+	if neg {
+		w--
+		buf[w] = '-'
+	}
+
+	return string(buf[w:])
+}
+
+// fmtFrac formats the fraction of v/10**prec (e.g., ".12345") into the
+// tail of buf, omitting trailing zeros.  it omits the decimal
+// point too when the fraction is 0.  It returns the index where the
+// output bytes begin and the value v/10**prec.
+func fmtFrac(buf []byte, v uint64, prec int) (nw int, nv uint64) {
+	// Omit trailing zeros up to and including decimal point.
+	w := len(buf)
+	print := false
+	for i := 0; i < prec; i++ {
+		digit := v % 10
+		print = print || digit != 0
+		if print {
+			w--
+			buf[w] = byte(digit) + '0'
+		}
+		v /= 10
+	}
+	if print {
+		w--
+		buf[w] = '.'
+	}
+	return w, v
+}
+
+// fmtInt formats v into the tail of buf.
+// It returns the index where the output begins.
+func fmtInt(buf []byte, v uint64) int {
+	w := len(buf)
+	if v == 0 {
+		w--
+		buf[w] = '0'
+	} else {
+		for v > 0 {
+			w--
+			buf[w] = byte(v%10) + '0'
+			v /= 10
+		}
+	}
+	return w
+}
+
+// Nanoseconds returns the duration as an integer nanosecond count.
+func (d Duration) Nanoseconds() int64 { return int64(d) }
+
+// These methods return float64 because the dominant
+// use case is for printing a floating point number like 1.5s, and
+// a truncation to integer would make them not useful in those cases.
+// Splitting the integer and fraction ourselves guarantees that
+// converting the returned float64 to an integer rounds the same
+// way that a pure integer conversion would have, even in cases
+// where, say, float64(d.Nanoseconds())/1e9 would have rounded
+// differently.
+
+// Seconds returns the duration as a floating point number of seconds.
+func (d Duration) Seconds() float64 {
+	sec := d / Second
+	nsec := d % Second
+	return float64(sec) + float64(nsec)*1e-9
+}
+
+// Minutes returns the duration as a floating point number of minutes.
+func (d Duration) Minutes() float64 {
+	min := d / Minute
+	nsec := d % Minute
+	return float64(min) + float64(nsec)*(1e-9/60)
+}
+
+// Hours returns the duration as a floating point number of hours.
+func (d Duration) Hours() float64 {
+	hour := d / Hour
+	nsec := d % Hour
+	return float64(hour) + float64(nsec)*(1e-9/60/60)
+}
+
+// Add returns the time t+d.
+func (t Time) Add(d Duration) Time {
+	t.sec += int64(d / 1e9)
+	nsec := int32(t.nsec) + int32(d%1e9)
+	if nsec >= 1e9 {
+		t.sec++
+		nsec -= 1e9
+	} else if nsec < 0 {
+		t.sec--
+		nsec += 1e9
+	}
+	t.nsec = nsec
+	return t
+}
+
+// Sub returns the duration t-u. If the result exceeds the maximum (or minimum)
+// value that can be stored in a Duration, the maximum (or minimum) duration
+// will be returned.
+// To compute t-d for a duration d, use t.Add(-d).
+func (t Time) Sub(u Time) Duration {
+	d := Duration(t.sec-u.sec)*Second + Duration(int32(t.nsec)-int32(u.nsec))
+	// Check for overflow or underflow.
+	switch {
+	case u.Add(d).Equal(t):
+		return d // d is correct
+	case t.Before(u):
+		return minDuration // t - u is negative out of range
+	default:
+		return maxDuration // t - u is positive out of range
+	}
+}
+
+// Since returns the time elapsed since t.
+// It is shorthand for time.Now().Sub(t).
+func Since(t Time) Duration {
+	return Now().Sub(t)
+}
+
+// AddDate returns the time corresponding to adding the
+// given number of years, months, and days to t.
+// For example, AddDate(-1, 2, 3) applied to January 1, 2011
+// returns March 4, 2010.
+//
+// AddDate normalizes its result in the same way that Date does,
+// so, for example, adding one month to October 31 yields
+// December 1, the normalized form for November 31.
+func (t Time) AddDate(years int, months int, days int) Time {
+	year, month, day := t.Date()
+	hour, min, sec := t.Clock()
+	return Date(year+years, month+Month(months), day+days, hour, min, sec, int(t.nsec), t.loc)
+}
+
+const (
+	secondsPerMinute = 60
+	secondsPerHour   = 60 * 60
+	secondsPerDay    = 24 * secondsPerHour
+	secondsPerWeek   = 7 * secondsPerDay
+	daysPer400Years  = 365*400 + 97
+	daysPer100Years  = 365*100 + 24
+	daysPer4Years    = 365*4 + 1
+)
+
+// date computes the year, day of year, and when full=true,
+// the month and day in which t occurs.
+func (t Time) date(full bool) (year int, month Month, day int, yday int) {
+	return absDate(t.abs(), full)
+}
+
+// absDate is like date but operates on an absolute time.
+func absDate(abs uint64, full bool) (year int, month Month, day int, yday int) {
+	// Split into time and day.
+	d := abs / secondsPerDay
+
+	// Account for 400 year cycles.
+	n := d / daysPer400Years
+	y := 400 * n
+	d -= daysPer400Years * n
+
+	// Cut off 100-year cycles.
+	// The last cycle has one extra leap year, so on the last day
+	// of that year, day / daysPer100Years will be 4 instead of 3.
+	// Cut it back down to 3 by subtracting n>>2.
+	n = d / daysPer100Years
+	n -= n >> 2
+	y += 100 * n
+	d -= daysPer100Years * n
+
+	// Cut off 4-year cycles.
+	// The last cycle has a missing leap year, which does not
+	// affect the computation.
+	n = d / daysPer4Years
+	y += 4 * n
+	d -= daysPer4Years * n
+
+	// Cut off years within a 4-year cycle.
+	// The last year is a leap year, so on the last day of that year,
+	// day / 365 will be 4 instead of 3.  Cut it back down to 3
+	// by subtracting n>>2.
+	n = d / 365
+	n -= n >> 2
+	y += n
+	d -= 365 * n
+
+	year = int(int64(y) + absoluteZeroYear)
+	yday = int(d)
+
+	if !full {
+		return
+	}
+
+	day = yday
+	if isLeap(year) {
+		// Leap year
+		switch {
+		case day > 31+29-1:
+			// After leap day; pretend it wasn't there.
+			day--
+		case day == 31+29-1:
+			// Leap day.
+			month = February
+			day = 29
+			return
+		}
+	}
+
+	// Estimate month on assumption that every month has 31 days.
+	// The estimate may be too low by at most one month, so adjust.
+	month = Month(day / 31)
+	end := int(daysBefore[month+1])
+	var begin int
+	if day >= end {
+		month++
+		begin = end
+	} else {
+		begin = int(daysBefore[month])
+	}
+
+	month++ // because January is 1
+	day = day - begin + 1
+	return
+}
+
+// daysBefore[m] counts the number of days in a non-leap year
+// before month m begins.  There is an entry for m=12, counting
+// the number of days before January of next year (365).
+var daysBefore = [...]int32{
+	0,
+	31,
+	31 + 28,
+	31 + 28 + 31,
+	31 + 28 + 31 + 30,
+	31 + 28 + 31 + 30 + 31,
+	31 + 28 + 31 + 30 + 31 + 30,
+	31 + 28 + 31 + 30 + 31 + 30 + 31,
+	31 + 28 + 31 + 30 + 31 + 30 + 31 + 31,
+	31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30,
+	31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31,
+	31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30,
+	31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + 31,
+}
+
+func daysIn(m Month, year int) int {
+	if m == February && isLeap(year) {
+		return 29
+	}
+	return int(daysBefore[m] - daysBefore[m-1])
+}
+
+// Provided by package runtime.
+func now() (sec int64, nsec int32)
+
+// Now returns the current local time.
+func Now() Time {
+	sec, nsec := now()
+	return Time{sec + unixToInternal, nsec, Local}
+}
+
+// UTC returns t with the location set to UTC.
+func (t Time) UTC() Time {
+	t.loc = UTC
+	return t
+}
+
+// Local returns t with the location set to local time.
+func (t Time) Local() Time {
+	t.loc = Local
+	return t
+}
+
+// In returns t with the location information set to loc.
+//
+// In panics if loc is nil.
+func (t Time) In(loc *Location) Time {
+	if loc == nil {
+		panic("time: missing Location in call to Time.In")
+	}
+	t.loc = loc
+	return t
+}
+
+// Location returns the time zone information associated with t.
+func (t Time) Location() *Location {
+	l := t.loc
+	if l == nil {
+		l = UTC
+	}
+	return l
+}
+
+// Zone computes the time zone in effect at time t, returning the abbreviated
+// name of the zone (such as "CET") and its offset in seconds east of UTC.
+func (t Time) Zone() (name string, offset int) {
+	name, offset, _, _, _ = t.loc.lookup(t.sec + internalToUnix)
+	return
+}
+
+// Unix returns t as a Unix time, the number of seconds elapsed
+// since January 1, 1970 UTC.
+func (t Time) Unix() int64 {
+	return t.sec + internalToUnix
+}
+
+// UnixNano returns t as a Unix time, the number of nanoseconds elapsed
+// since January 1, 1970 UTC. The result is undefined if the Unix time
+// in nanoseconds cannot be represented by an int64. Note that this
+// means the result of calling UnixNano on the zero Time is undefined.
+func (t Time) UnixNano() int64 {
+	return (t.sec+internalToUnix)*1e9 + int64(t.nsec)
+}
+
+const timeBinaryVersion byte = 1
+
+// MarshalBinary implements the encoding.BinaryMarshaler interface.
+func (t Time) MarshalBinary() ([]byte, error) {
+	var offsetMin int16 // minutes east of UTC. -1 is UTC.
+
+	if t.Location() == &utcLoc {
+		offsetMin = -1
+	} else {
+		_, offset := t.Zone()
+		if offset%60 != 0 {
+			return nil, errors.New("Time.MarshalBinary: zone offset has fractional minute")
+		}
+		offset /= 60
+		if offset < -32768 || offset == -1 || offset > 32767 {
+			return nil, errors.New("Time.MarshalBinary: unexpected zone offset")
+		}
+		offsetMin = int16(offset)
+	}
+
+	enc := []byte{
+		timeBinaryVersion, // byte 0 : version
+		byte(t.sec >> 56), // bytes 1-8: seconds
+		byte(t.sec >> 48),
+		byte(t.sec >> 40),
+		byte(t.sec >> 32),
+		byte(t.sec >> 24),
+		byte(t.sec >> 16),
+		byte(t.sec >> 8),
+		byte(t.sec),
+		byte(t.nsec >> 24), // bytes 9-12: nanoseconds
+		byte(t.nsec >> 16),
+		byte(t.nsec >> 8),
+		byte(t.nsec),
+		byte(offsetMin >> 8), // bytes 13-14: zone offset in minutes
+		byte(offsetMin),
+	}
+
+	return enc, nil
+}
+
+// UnmarshalBinary implements the encoding.BinaryUnmarshaler interface.
+func (t *Time) UnmarshalBinary(data []byte) error {
+	buf := data
+	if len(buf) == 0 {
+		return errors.New("Time.UnmarshalBinary: no data")
+	}
+
+	if buf[0] != timeBinaryVersion {
+		return errors.New("Time.UnmarshalBinary: unsupported version")
+	}
+
+	if len(buf) != /*version*/ 1+ /*sec*/ 8+ /*nsec*/ 4+ /*zone offset*/ 2 {
+		return errors.New("Time.UnmarshalBinary: invalid length")
+	}
+
+	buf = buf[1:]
+	t.sec = int64(buf[7]) | int64(buf[6])<<8 | int64(buf[5])<<16 | int64(buf[4])<<24 |
+		int64(buf[3])<<32 | int64(buf[2])<<40 | int64(buf[1])<<48 | int64(buf[0])<<56
+
+	buf = buf[8:]
+	t.nsec = int32(buf[3]) | int32(buf[2])<<8 | int32(buf[1])<<16 | int32(buf[0])<<24
+
+	buf = buf[4:]
+	offset := int(int16(buf[1])|int16(buf[0])<<8) * 60
+
+	if offset == -1*60 {
+		t.loc = &utcLoc
+	} else if _, localoff, _, _, _ := Local.lookup(t.sec + internalToUnix); offset == localoff {
+		t.loc = Local
+	} else {
+		t.loc = FixedZone("", offset)
+	}
+
+	return nil
+}
+
+// TODO(rsc): Remove GobEncoder, GobDecoder, MarshalJSON, UnmarshalJSON in Go 2.
+// The same semantics will be provided by the generic MarshalBinary, MarshalText,
+// UnmarshalBinary, UnmarshalText.
+
+// GobEncode implements the gob.GobEncoder interface.
+func (t Time) GobEncode() ([]byte, error) {
+	return t.MarshalBinary()
+}
+
+// GobDecode implements the gob.GobDecoder interface.
+func (t *Time) GobDecode(data []byte) error {
+	return t.UnmarshalBinary(data)
+}
+
+// MarshalJSON implements the json.Marshaler interface.
+// The time is a quoted string in RFC 3339 format, with sub-second precision added if present.
+func (t Time) MarshalJSON() ([]byte, error) {
+	if y := t.Year(); y < 0 || y >= 10000 {
+		// RFC 3339 is clear that years are 4 digits exactly.
+		// See golang.org/issue/4556#c15 for more discussion.
+		return nil, errors.New("Time.MarshalJSON: year outside of range [0,9999]")
+	}
+	return []byte(t.Format(`"` + RFC3339Nano + `"`)), nil
+}
+
+// UnmarshalJSON implements the json.Unmarshaler interface.
+// The time is expected to be a quoted string in RFC 3339 format.
+func (t *Time) UnmarshalJSON(data []byte) (err error) {
+	// Fractional seconds are handled implicitly by Parse.
+	*t, err = Parse(`"`+RFC3339+`"`, string(data))
+	return
+}
+
+// MarshalText implements the encoding.TextMarshaler interface.
+// The time is formatted in RFC 3339 format, with sub-second precision added if present.
+func (t Time) MarshalText() ([]byte, error) {
+	if y := t.Year(); y < 0 || y >= 10000 {
+		return nil, errors.New("Time.MarshalText: year outside of range [0,9999]")
+	}
+	return []byte(t.Format(RFC3339Nano)), nil
+}
+
+// UnmarshalText implements the encoding.TextUnmarshaler interface.
+// The time is expected to be in RFC 3339 format.
+func (t *Time) UnmarshalText(data []byte) (err error) {
+	// Fractional seconds are handled implicitly by Parse.
+	*t, err = Parse(RFC3339, string(data))
+	return
+}
+
+// Unix returns the local Time corresponding to the given Unix time,
+// sec seconds and nsec nanoseconds since January 1, 1970 UTC.
+// It is valid to pass nsec outside the range [0, 999999999].
+func Unix(sec int64, nsec int64) Time {
+	if nsec < 0 || nsec >= 1e9 {
+		n := nsec / 1e9
+		sec += n
+		nsec -= n * 1e9
+		if nsec < 0 {
+			nsec += 1e9
+			sec--
+		}
+	}
+	return Time{sec + unixToInternal, int32(nsec), Local}
+}
+
+func isLeap(year int) bool {
+	return year%4 == 0 && (year%100 != 0 || year%400 == 0)
+}
+
+// norm returns nhi, nlo such that
+//	hi * base + lo == nhi * base + nlo
+//	0 <= nlo < base
+func norm(hi, lo, base int) (nhi, nlo int) {
+	if lo < 0 {
+		n := (-lo-1)/base + 1
+		hi -= n
+		lo += n * base
+	}
+	if lo >= base {
+		n := lo / base
+		hi += n
+		lo -= n * base
+	}
+	return hi, lo
+}
+
+// Date returns the Time corresponding to
+//	yyyy-mm-dd hh:mm:ss + nsec nanoseconds
+// in the appropriate zone for that time in the given location.
+//
+// The month, day, hour, min, sec, and nsec values may be outside
+// their usual ranges and will be normalized during the conversion.
+// For example, October 32 converts to November 1.
+//
+// A daylight savings time transition skips or repeats times.
+// For example, in the United States, March 13, 2011 2:15am never occurred,
+// while November 6, 2011 1:15am occurred twice.  In such cases, the
+// choice of time zone, and therefore the time, is not well-defined.
+// Date returns a time that is correct in one of the two zones involved
+// in the transition, but it does not guarantee which.
+//
+// Date panics if loc is nil.
+func Date(year int, month Month, day, hour, min, sec, nsec int, loc *Location) Time {
+	if loc == nil {
+		panic("time: missing Location in call to Date")
+	}
+
+	// Normalize month, overflowing into year.
+	m := int(month) - 1
+	year, m = norm(year, m, 12)
+	month = Month(m) + 1
+
+	// Normalize nsec, sec, min, hour, overflowing into day.
+	sec, nsec = norm(sec, nsec, 1e9)
+	min, sec = norm(min, sec, 60)
+	hour, min = norm(hour, min, 60)
+	day, hour = norm(day, hour, 24)
+
+	y := uint64(int64(year) - absoluteZeroYear)
+
+	// Compute days since the absolute epoch.
+
+	// Add in days from 400-year cycles.
+	n := y / 400
+	y -= 400 * n
+	d := daysPer400Years * n
+
+	// Add in 100-year cycles.
+	n = y / 100
+	y -= 100 * n
+	d += daysPer100Years * n
+
+	// Add in 4-year cycles.
+	n = y / 4
+	y -= 4 * n
+	d += daysPer4Years * n
+
+	// Add in non-leap years.
+	n = y
+	d += 365 * n
+
+	// Add in days before this month.
+	d += uint64(daysBefore[month-1])
+	if isLeap(year) && month >= March {
+		d++ // February 29
+	}
+
+	// Add in days before today.
+	d += uint64(day - 1)
+
+	// Add in time elapsed today.
+	abs := d * secondsPerDay
+	abs += uint64(hour*secondsPerHour + min*secondsPerMinute + sec)
+
+	unix := int64(abs) + (absoluteToInternal + internalToUnix)
+
+	// Look for zone offset for t, so we can adjust to UTC.
+	// The lookup function expects UTC, so we pass t in the
+	// hope that it will not be too close to a zone transition,
+	// and then adjust if it is.
+	_, offset, _, start, end := loc.lookup(unix)
+	if offset != 0 {
+		switch utc := unix - int64(offset); {
+		case utc < start:
+			_, offset, _, _, _ = loc.lookup(start - 1)
+		case utc >= end:
+			_, offset, _, _, _ = loc.lookup(end)
+		}
+		unix -= int64(offset)
+	}
+
+	return Time{unix + unixToInternal, int32(nsec), loc}
+}
+
+// Truncate returns the result of rounding t down to a multiple of d (since the zero time).
+// If d <= 0, Truncate returns t unchanged.
+func (t Time) Truncate(d Duration) Time {
+	if d <= 0 {
+		return t
+	}
+	_, r := div(t, d)
+	return t.Add(-r)
+}
+
+// Round returns the result of rounding t to the nearest multiple of d (since the zero time).
+// The rounding behavior for halfway values is to round up.
+// If d <= 0, Round returns t unchanged.
+func (t Time) Round(d Duration) Time {
+	if d <= 0 {
+		return t
+	}
+	_, r := div(t, d)
+	if r+r < d {
+		return t.Add(-r)
+	}
+	return t.Add(d - r)
+}
+
+// div divides t by d and returns the quotient parity and remainder.
+// We don't use the quotient parity anymore (round half up instead of round to even)
+// but it's still here in case we change our minds.
+func div(t Time, d Duration) (qmod2 int, r Duration) {
+	neg := false
+	nsec := int32(t.nsec)
+	if t.sec < 0 {
+		// Operate on absolute value.
+		neg = true
+		t.sec = -t.sec
+		nsec = -nsec
+		if nsec < 0 {
+			nsec += 1e9
+			t.sec-- // t.sec >= 1 before the -- so safe
+		}
+	}
+
+	switch {
+	// Special case: 2d divides 1 second.
+	case d < Second && Second%(d+d) == 0:
+		qmod2 = int(nsec/int32(d)) & 1
+		r = Duration(nsec % int32(d))
+
+	// Special case: d is a multiple of 1 second.
+	case d%Second == 0:
+		d1 := int64(d / Second)
+		qmod2 = int(t.sec/d1) & 1
+		r = Duration(t.sec%d1)*Second + Duration(nsec)
+
+	// General case.
+	// This could be faster if more cleverness were applied,
+	// but it's really only here to avoid special case restrictions in the API.
+	// No one will care about these cases.
+	default:
+		// Compute nanoseconds as 128-bit number.
+		sec := uint64(t.sec)
+		tmp := (sec >> 32) * 1e9
+		u1 := tmp >> 32
+		u0 := tmp << 32
+		tmp = uint64(sec&0xFFFFFFFF) * 1e9
+		u0x, u0 := u0, u0+tmp
+		if u0 < u0x {
+			u1++
+		}
+		u0x, u0 = u0, u0+uint64(nsec)
+		if u0 < u0x {
+			u1++
+		}
+
+		// Compute remainder by subtracting r<<k for decreasing k.
+		// Quotient parity is whether we subtract on last round.
+		d1 := uint64(d)
+		for d1>>63 != 1 {
+			d1 <<= 1
+		}
+		d0 := uint64(0)
+		for {
+			qmod2 = 0
+			if u1 > d1 || u1 == d1 && u0 >= d0 {
+				// subtract
+				qmod2 = 1
+				u0x, u0 = u0, u0-d0
+				if u0 > u0x {
+					u1--
+				}
+				u1 -= d1
+			}
+			if d1 == 0 && d0 == uint64(d) {
+				break
+			}
+			d0 >>= 1
+			d0 |= (d1 & 1) << 63
+			d1 >>= 1
+		}
+		r = Duration(u0)
+	}
+
+	if neg && r != 0 {
+		// If input was negative and not an exact multiple of d, we computed q, r such that
+		//	q*d + r = -t
+		// But the right answers are given by -(q-1), d-r:
+		//	q*d + r = -t
+		//	-q*d - r = t
+		//	-(q-1)*d + (d - r) = t
+		qmod2 ^= 1
+		r = d - r
+	}
+	return
+}
diff --git a/src/time/time_test.go b/src/time/time_test.go
new file mode 100644
index 0000000..7e31dd7
--- /dev/null
+++ b/src/time/time_test.go
@@ -0,0 +1,1081 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package time_test
+
+import (
+	"bytes"
+	"encoding/gob"
+	"encoding/json"
+	"fmt"
+	"math/big"
+	"math/rand"
+	"runtime"
+	"testing"
+	"testing/quick"
+	. "time"
+)
+
+// We should be in PST/PDT, but if the time zone files are missing we
+// won't be. The purpose of this test is to at least explain why some of
+// the subsequent tests fail.
+func TestZoneData(t *testing.T) {
+	lt := Now()
+	// PST is 8 hours west, PDT is 7 hours west.  We could use the name but it's not unique.
+	if name, off := lt.Zone(); off != -8*60*60 && off != -7*60*60 {
+		t.Errorf("Unable to find US Pacific time zone data for testing; time zone is %q offset %d", name, off)
+		t.Error("Likely problem: the time zone files have not been installed.")
+	}
+}
+
+// parsedTime is the struct representing a parsed time value.
+type parsedTime struct {
+	Year                 int
+	Month                Month
+	Day                  int
+	Hour, Minute, Second int // 15:04:05 is 15, 4, 5.
+	Nanosecond           int // Fractional second.
+	Weekday              Weekday
+	ZoneOffset           int    // seconds east of UTC, e.g. -7*60*60 for -0700
+	Zone                 string // e.g., "MST"
+}
+
+type TimeTest struct {
+	seconds int64
+	golden  parsedTime
+}
+
+var utctests = []TimeTest{
+	{0, parsedTime{1970, January, 1, 0, 0, 0, 0, Thursday, 0, "UTC"}},
+	{1221681866, parsedTime{2008, September, 17, 20, 4, 26, 0, Wednesday, 0, "UTC"}},
+	{-1221681866, parsedTime{1931, April, 16, 3, 55, 34, 0, Thursday, 0, "UTC"}},
+	{-11644473600, parsedTime{1601, January, 1, 0, 0, 0, 0, Monday, 0, "UTC"}},
+	{599529660, parsedTime{1988, December, 31, 0, 1, 0, 0, Saturday, 0, "UTC"}},
+	{978220860, parsedTime{2000, December, 31, 0, 1, 0, 0, Sunday, 0, "UTC"}},
+}
+
+var nanoutctests = []TimeTest{
+	{0, parsedTime{1970, January, 1, 0, 0, 0, 1e8, Thursday, 0, "UTC"}},
+	{1221681866, parsedTime{2008, September, 17, 20, 4, 26, 2e8, Wednesday, 0, "UTC"}},
+}
+
+var localtests = []TimeTest{
+	{0, parsedTime{1969, December, 31, 16, 0, 0, 0, Wednesday, -8 * 60 * 60, "PST"}},
+	{1221681866, parsedTime{2008, September, 17, 13, 4, 26, 0, Wednesday, -7 * 60 * 60, "PDT"}},
+}
+
+var nanolocaltests = []TimeTest{
+	{0, parsedTime{1969, December, 31, 16, 0, 0, 1e8, Wednesday, -8 * 60 * 60, "PST"}},
+	{1221681866, parsedTime{2008, September, 17, 13, 4, 26, 3e8, Wednesday, -7 * 60 * 60, "PDT"}},
+}
+
+func same(t Time, u *parsedTime) bool {
+	// Check aggregates.
+	year, month, day := t.Date()
+	hour, min, sec := t.Clock()
+	name, offset := t.Zone()
+	if year != u.Year || month != u.Month || day != u.Day ||
+		hour != u.Hour || min != u.Minute || sec != u.Second ||
+		name != u.Zone || offset != u.ZoneOffset {
+		return false
+	}
+	// Check individual entries.
+	return t.Year() == u.Year &&
+		t.Month() == u.Month &&
+		t.Day() == u.Day &&
+		t.Hour() == u.Hour &&
+		t.Minute() == u.Minute &&
+		t.Second() == u.Second &&
+		t.Nanosecond() == u.Nanosecond &&
+		t.Weekday() == u.Weekday
+}
+
+func TestSecondsToUTC(t *testing.T) {
+	for _, test := range utctests {
+		sec := test.seconds
+		golden := &test.golden
+		tm := Unix(sec, 0).UTC()
+		newsec := tm.Unix()
+		if newsec != sec {
+			t.Errorf("SecondsToUTC(%d).Seconds() = %d", sec, newsec)
+		}
+		if !same(tm, golden) {
+			t.Errorf("SecondsToUTC(%d):  // %#v", sec, tm)
+			t.Errorf("  want=%+v", *golden)
+			t.Errorf("  have=%v", tm.Format(RFC3339+" MST"))
+		}
+	}
+}
+
+func TestNanosecondsToUTC(t *testing.T) {
+	for _, test := range nanoutctests {
+		golden := &test.golden
+		nsec := test.seconds*1e9 + int64(golden.Nanosecond)
+		tm := Unix(0, nsec).UTC()
+		newnsec := tm.Unix()*1e9 + int64(tm.Nanosecond())
+		if newnsec != nsec {
+			t.Errorf("NanosecondsToUTC(%d).Nanoseconds() = %d", nsec, newnsec)
+		}
+		if !same(tm, golden) {
+			t.Errorf("NanosecondsToUTC(%d):", nsec)
+			t.Errorf("  want=%+v", *golden)
+			t.Errorf("  have=%+v", tm.Format(RFC3339+" MST"))
+		}
+	}
+}
+
+func TestSecondsToLocalTime(t *testing.T) {
+	for _, test := range localtests {
+		sec := test.seconds
+		golden := &test.golden
+		tm := Unix(sec, 0)
+		newsec := tm.Unix()
+		if newsec != sec {
+			t.Errorf("SecondsToLocalTime(%d).Seconds() = %d", sec, newsec)
+		}
+		if !same(tm, golden) {
+			t.Errorf("SecondsToLocalTime(%d):", sec)
+			t.Errorf("  want=%+v", *golden)
+			t.Errorf("  have=%+v", tm.Format(RFC3339+" MST"))
+		}
+	}
+}
+
+func TestNanosecondsToLocalTime(t *testing.T) {
+	for _, test := range nanolocaltests {
+		golden := &test.golden
+		nsec := test.seconds*1e9 + int64(golden.Nanosecond)
+		tm := Unix(0, nsec)
+		newnsec := tm.Unix()*1e9 + int64(tm.Nanosecond())
+		if newnsec != nsec {
+			t.Errorf("NanosecondsToLocalTime(%d).Seconds() = %d", nsec, newnsec)
+		}
+		if !same(tm, golden) {
+			t.Errorf("NanosecondsToLocalTime(%d):", nsec)
+			t.Errorf("  want=%+v", *golden)
+			t.Errorf("  have=%+v", tm.Format(RFC3339+" MST"))
+		}
+	}
+}
+
+func TestSecondsToUTCAndBack(t *testing.T) {
+	f := func(sec int64) bool { return Unix(sec, 0).UTC().Unix() == sec }
+	f32 := func(sec int32) bool { return f(int64(sec)) }
+	cfg := &quick.Config{MaxCount: 10000}
+
+	// Try a reasonable date first, then the huge ones.
+	if err := quick.Check(f32, cfg); err != nil {
+		t.Fatal(err)
+	}
+	if err := quick.Check(f, cfg); err != nil {
+		t.Fatal(err)
+	}
+}
+
+func TestNanosecondsToUTCAndBack(t *testing.T) {
+	f := func(nsec int64) bool {
+		t := Unix(0, nsec).UTC()
+		ns := t.Unix()*1e9 + int64(t.Nanosecond())
+		return ns == nsec
+	}
+	f32 := func(nsec int32) bool { return f(int64(nsec)) }
+	cfg := &quick.Config{MaxCount: 10000}
+
+	// Try a small date first, then the large ones. (The span is only a few hundred years
+	// for nanoseconds in an int64.)
+	if err := quick.Check(f32, cfg); err != nil {
+		t.Fatal(err)
+	}
+	if err := quick.Check(f, cfg); err != nil {
+		t.Fatal(err)
+	}
+}
+
+// The time routines provide no way to get absolute time
+// (seconds since zero), but we need it to compute the right
+// answer for bizarre roundings like "to the nearest 3 ns".
+// Compute as t - year1 = (t - 1970) + (1970 - 2001) + (2001 - 1).
+// t - 1970 is returned by Unix and Nanosecond.
+// 1970 - 2001 is -(31*365+8)*86400 = -978307200 seconds.
+// 2001 - 1 is 2000*365.2425*86400 = 63113904000 seconds.
+const unixToZero = -978307200 + 63113904000
+
+// abs returns the absolute time stored in t, as seconds and nanoseconds.
+func abs(t Time) (sec, nsec int64) {
+	unix := t.Unix()
+	nano := t.Nanosecond()
+	return unix + unixToZero, int64(nano)
+}
+
+// absString returns abs as a decimal string.
+func absString(t Time) string {
+	sec, nsec := abs(t)
+	if sec < 0 {
+		sec = -sec
+		nsec = -nsec
+		if nsec < 0 {
+			nsec += 1e9
+			sec--
+		}
+		return fmt.Sprintf("-%d%09d", sec, nsec)
+	}
+	return fmt.Sprintf("%d%09d", sec, nsec)
+}
+
+var truncateRoundTests = []struct {
+	t Time
+	d Duration
+}{
+	{Date(-1, January, 1, 12, 15, 30, 5e8, UTC), 3},
+	{Date(-1, January, 1, 12, 15, 31, 5e8, UTC), 3},
+	{Date(2012, January, 1, 12, 15, 30, 5e8, UTC), Second},
+	{Date(2012, January, 1, 12, 15, 31, 5e8, UTC), Second},
+}
+
+func TestTruncateRound(t *testing.T) {
+	var (
+		bsec  = new(big.Int)
+		bnsec = new(big.Int)
+		bd    = new(big.Int)
+		bt    = new(big.Int)
+		br    = new(big.Int)
+		bq    = new(big.Int)
+		b1e9  = new(big.Int)
+	)
+
+	b1e9.SetInt64(1e9)
+
+	testOne := func(ti, tns, di int64) bool {
+		t0 := Unix(ti, int64(tns)).UTC()
+		d := Duration(di)
+		if d < 0 {
+			d = -d
+		}
+		if d <= 0 {
+			d = 1
+		}
+
+		// Compute bt = absolute nanoseconds.
+		sec, nsec := abs(t0)
+		bsec.SetInt64(sec)
+		bnsec.SetInt64(nsec)
+		bt.Mul(bsec, b1e9)
+		bt.Add(bt, bnsec)
+
+		// Compute quotient and remainder mod d.
+		bd.SetInt64(int64(d))
+		bq.DivMod(bt, bd, br)
+
+		// To truncate, subtract remainder.
+		// br is < d, so it fits in an int64.
+		r := br.Int64()
+		t1 := t0.Add(-Duration(r))
+
+		// Check that time.Truncate works.
+		if trunc := t0.Truncate(d); trunc != t1 {
+			t.Errorf("Time.Truncate(%s, %s) = %s, want %s\n"+
+				"%v trunc %v =\n%v want\n%v",
+				t0.Format(RFC3339Nano), d, trunc, t1.Format(RFC3339Nano),
+				absString(t0), int64(d), absString(trunc), absString(t1))
+			return false
+		}
+
+		// To round, add d back if remainder r > d/2 or r == exactly d/2.
+		// The commented out code would round half to even instead of up,
+		// but that makes it time-zone dependent, which is a bit strange.
+		if r > int64(d)/2 || r+r == int64(d) /*&& bq.Bit(0) == 1*/ {
+			t1 = t1.Add(Duration(d))
+		}
+
+		// Check that time.Round works.
+		if rnd := t0.Round(d); rnd != t1 {
+			t.Errorf("Time.Round(%s, %s) = %s, want %s\n"+
+				"%v round %v =\n%v want\n%v",
+				t0.Format(RFC3339Nano), d, rnd, t1.Format(RFC3339Nano),
+				absString(t0), int64(d), absString(rnd), absString(t1))
+			return false
+		}
+		return true
+	}
+
+	// manual test cases
+	for _, tt := range truncateRoundTests {
+		testOne(tt.t.Unix(), int64(tt.t.Nanosecond()), int64(tt.d))
+	}
+
+	// exhaustive near 0
+	for i := 0; i < 100; i++ {
+		for j := 1; j < 100; j++ {
+			testOne(unixToZero, int64(i), int64(j))
+			testOne(unixToZero, -int64(i), int64(j))
+			if t.Failed() {
+				return
+			}
+		}
+	}
+
+	if t.Failed() {
+		return
+	}
+
+	// randomly generated test cases
+	cfg := &quick.Config{MaxCount: 100000}
+	if testing.Short() {
+		cfg.MaxCount = 1000
+	}
+
+	// divisors of Second
+	f1 := func(ti int64, tns int32, logdi int32) bool {
+		d := Duration(1)
+		a, b := uint(logdi%9), (logdi>>16)%9
+		d <<= a
+		for i := 0; i < int(b); i++ {
+			d *= 5
+		}
+		return testOne(ti, int64(tns), int64(d))
+	}
+	quick.Check(f1, cfg)
+
+	// multiples of Second
+	f2 := func(ti int64, tns int32, di int32) bool {
+		d := Duration(di) * Second
+		if d < 0 {
+			d = -d
+		}
+		return testOne(ti, int64(tns), int64(d))
+	}
+	quick.Check(f2, cfg)
+
+	// halfway cases
+	f3 := func(tns, di int64) bool {
+		di &= 0xfffffffe
+		if di == 0 {
+			di = 2
+		}
+		tns -= tns % di
+		if tns < 0 {
+			tns += di / 2
+		} else {
+			tns -= di / 2
+		}
+		return testOne(0, tns, di)
+	}
+	quick.Check(f3, cfg)
+
+	// full generality
+	f4 := func(ti int64, tns int32, di int64) bool {
+		return testOne(ti, int64(tns), di)
+	}
+	quick.Check(f4, cfg)
+}
+
+type ISOWeekTest struct {
+	year       int // year
+	month, day int // month and day
+	yex        int // expected year
+	wex        int // expected week
+}
+
+var isoWeekTests = []ISOWeekTest{
+	{1981, 1, 1, 1981, 1}, {1982, 1, 1, 1981, 53}, {1983, 1, 1, 1982, 52},
+	{1984, 1, 1, 1983, 52}, {1985, 1, 1, 1985, 1}, {1986, 1, 1, 1986, 1},
+	{1987, 1, 1, 1987, 1}, {1988, 1, 1, 1987, 53}, {1989, 1, 1, 1988, 52},
+	{1990, 1, 1, 1990, 1}, {1991, 1, 1, 1991, 1}, {1992, 1, 1, 1992, 1},
+	{1993, 1, 1, 1992, 53}, {1994, 1, 1, 1993, 52}, {1995, 1, 2, 1995, 1},
+	{1996, 1, 1, 1996, 1}, {1996, 1, 7, 1996, 1}, {1996, 1, 8, 1996, 2},
+	{1997, 1, 1, 1997, 1}, {1998, 1, 1, 1998, 1}, {1999, 1, 1, 1998, 53},
+	{2000, 1, 1, 1999, 52}, {2001, 1, 1, 2001, 1}, {2002, 1, 1, 2002, 1},
+	{2003, 1, 1, 2003, 1}, {2004, 1, 1, 2004, 1}, {2005, 1, 1, 2004, 53},
+	{2006, 1, 1, 2005, 52}, {2007, 1, 1, 2007, 1}, {2008, 1, 1, 2008, 1},
+	{2009, 1, 1, 2009, 1}, {2010, 1, 1, 2009, 53}, {2010, 1, 1, 2009, 53},
+	{2011, 1, 1, 2010, 52}, {2011, 1, 2, 2010, 52}, {2011, 1, 3, 2011, 1},
+	{2011, 1, 4, 2011, 1}, {2011, 1, 5, 2011, 1}, {2011, 1, 6, 2011, 1},
+	{2011, 1, 7, 2011, 1}, {2011, 1, 8, 2011, 1}, {2011, 1, 9, 2011, 1},
+	{2011, 1, 10, 2011, 2}, {2011, 1, 11, 2011, 2}, {2011, 6, 12, 2011, 23},
+	{2011, 6, 13, 2011, 24}, {2011, 12, 25, 2011, 51}, {2011, 12, 26, 2011, 52},
+	{2011, 12, 27, 2011, 52}, {2011, 12, 28, 2011, 52}, {2011, 12, 29, 2011, 52},
+	{2011, 12, 30, 2011, 52}, {2011, 12, 31, 2011, 52}, {1995, 1, 1, 1994, 52},
+	{2012, 1, 1, 2011, 52}, {2012, 1, 2, 2012, 1}, {2012, 1, 8, 2012, 1},
+	{2012, 1, 9, 2012, 2}, {2012, 12, 23, 2012, 51}, {2012, 12, 24, 2012, 52},
+	{2012, 12, 30, 2012, 52}, {2012, 12, 31, 2013, 1}, {2013, 1, 1, 2013, 1},
+	{2013, 1, 6, 2013, 1}, {2013, 1, 7, 2013, 2}, {2013, 12, 22, 2013, 51},
+	{2013, 12, 23, 2013, 52}, {2013, 12, 29, 2013, 52}, {2013, 12, 30, 2014, 1},
+	{2014, 1, 1, 2014, 1}, {2014, 1, 5, 2014, 1}, {2014, 1, 6, 2014, 2},
+	{2015, 1, 1, 2015, 1}, {2016, 1, 1, 2015, 53}, {2017, 1, 1, 2016, 52},
+	{2018, 1, 1, 2018, 1}, {2019, 1, 1, 2019, 1}, {2020, 1, 1, 2020, 1},
+	{2021, 1, 1, 2020, 53}, {2022, 1, 1, 2021, 52}, {2023, 1, 1, 2022, 52},
+	{2024, 1, 1, 2024, 1}, {2025, 1, 1, 2025, 1}, {2026, 1, 1, 2026, 1},
+	{2027, 1, 1, 2026, 53}, {2028, 1, 1, 2027, 52}, {2029, 1, 1, 2029, 1},
+	{2030, 1, 1, 2030, 1}, {2031, 1, 1, 2031, 1}, {2032, 1, 1, 2032, 1},
+	{2033, 1, 1, 2032, 53}, {2034, 1, 1, 2033, 52}, {2035, 1, 1, 2035, 1},
+	{2036, 1, 1, 2036, 1}, {2037, 1, 1, 2037, 1}, {2038, 1, 1, 2037, 53},
+	{2039, 1, 1, 2038, 52}, {2040, 1, 1, 2039, 52},
+}
+
+func TestISOWeek(t *testing.T) {
+	// Selected dates and corner cases
+	for _, wt := range isoWeekTests {
+		dt := Date(wt.year, Month(wt.month), wt.day, 0, 0, 0, 0, UTC)
+		y, w := dt.ISOWeek()
+		if w != wt.wex || y != wt.yex {
+			t.Errorf("got %d/%d; expected %d/%d for %d-%02d-%02d",
+				y, w, wt.yex, wt.wex, wt.year, wt.month, wt.day)
+		}
+	}
+
+	// The only real invariant: Jan 04 is in week 1
+	for year := 1950; year < 2100; year++ {
+		if y, w := Date(year, January, 4, 0, 0, 0, 0, UTC).ISOWeek(); y != year || w != 1 {
+			t.Errorf("got %d/%d; expected %d/1 for Jan 04", y, w, year)
+		}
+	}
+}
+
+type YearDayTest struct {
+	year, month, day int
+	yday             int
+}
+
+// Test YearDay in several different scenarios
+// and corner cases
+var yearDayTests = []YearDayTest{
+	// Non-leap-year tests
+	{2007, 1, 1, 1},
+	{2007, 1, 15, 15},
+	{2007, 2, 1, 32},
+	{2007, 2, 15, 46},
+	{2007, 3, 1, 60},
+	{2007, 3, 15, 74},
+	{2007, 4, 1, 91},
+	{2007, 12, 31, 365},
+
+	// Leap-year tests
+	{2008, 1, 1, 1},
+	{2008, 1, 15, 15},
+	{2008, 2, 1, 32},
+	{2008, 2, 15, 46},
+	{2008, 3, 1, 61},
+	{2008, 3, 15, 75},
+	{2008, 4, 1, 92},
+	{2008, 12, 31, 366},
+
+	// Looks like leap-year (but isn't) tests
+	{1900, 1, 1, 1},
+	{1900, 1, 15, 15},
+	{1900, 2, 1, 32},
+	{1900, 2, 15, 46},
+	{1900, 3, 1, 60},
+	{1900, 3, 15, 74},
+	{1900, 4, 1, 91},
+	{1900, 12, 31, 365},
+
+	// Year one tests (non-leap)
+	{1, 1, 1, 1},
+	{1, 1, 15, 15},
+	{1, 2, 1, 32},
+	{1, 2, 15, 46},
+	{1, 3, 1, 60},
+	{1, 3, 15, 74},
+	{1, 4, 1, 91},
+	{1, 12, 31, 365},
+
+	// Year minus one tests (non-leap)
+	{-1, 1, 1, 1},
+	{-1, 1, 15, 15},
+	{-1, 2, 1, 32},
+	{-1, 2, 15, 46},
+	{-1, 3, 1, 60},
+	{-1, 3, 15, 74},
+	{-1, 4, 1, 91},
+	{-1, 12, 31, 365},
+
+	// 400 BC tests (leap-year)
+	{-400, 1, 1, 1},
+	{-400, 1, 15, 15},
+	{-400, 2, 1, 32},
+	{-400, 2, 15, 46},
+	{-400, 3, 1, 61},
+	{-400, 3, 15, 75},
+	{-400, 4, 1, 92},
+	{-400, 12, 31, 366},
+
+	// Special Cases
+
+	// Gregorian calendar change (no effect)
+	{1582, 10, 4, 277},
+	{1582, 10, 15, 288},
+}
+
+// Check to see if YearDay is location sensitive
+var yearDayLocations = []*Location{
+	FixedZone("UTC-8", -8*60*60),
+	FixedZone("UTC-4", -4*60*60),
+	UTC,
+	FixedZone("UTC+4", 4*60*60),
+	FixedZone("UTC+8", 8*60*60),
+}
+
+func TestYearDay(t *testing.T) {
+	for _, loc := range yearDayLocations {
+		for _, ydt := range yearDayTests {
+			dt := Date(ydt.year, Month(ydt.month), ydt.day, 0, 0, 0, 0, loc)
+			yday := dt.YearDay()
+			if yday != ydt.yday {
+				t.Errorf("got %d, expected %d for %d-%02d-%02d in %v",
+					yday, ydt.yday, ydt.year, ydt.month, ydt.day, loc)
+			}
+		}
+	}
+}
+
+var durationTests = []struct {
+	str string
+	d   Duration
+}{
+	{"0", 0},
+	{"1ns", 1 * Nanosecond},
+	{"1.1µs", 1100 * Nanosecond},
+	{"2.2ms", 2200 * Microsecond},
+	{"3.3s", 3300 * Millisecond},
+	{"4m5s", 4*Minute + 5*Second},
+	{"4m5.001s", 4*Minute + 5001*Millisecond},
+	{"5h6m7.001s", 5*Hour + 6*Minute + 7001*Millisecond},
+	{"8m0.000000001s", 8*Minute + 1*Nanosecond},
+	{"2562047h47m16.854775807s", 1<<63 - 1},
+	{"-2562047h47m16.854775808s", -1 << 63},
+}
+
+func TestDurationString(t *testing.T) {
+	for _, tt := range durationTests {
+		if str := tt.d.String(); str != tt.str {
+			t.Errorf("Duration(%d).String() = %s, want %s", int64(tt.d), str, tt.str)
+		}
+		if tt.d > 0 {
+			if str := (-tt.d).String(); str != "-"+tt.str {
+				t.Errorf("Duration(%d).String() = %s, want %s", int64(-tt.d), str, "-"+tt.str)
+			}
+		}
+	}
+}
+
+var dateTests = []struct {
+	year, month, day, hour, min, sec, nsec int
+	z                                      *Location
+	unix                                   int64
+}{
+	{2011, 11, 6, 1, 0, 0, 0, Local, 1320566400},   // 1:00:00 PDT
+	{2011, 11, 6, 1, 59, 59, 0, Local, 1320569999}, // 1:59:59 PDT
+	{2011, 11, 6, 2, 0, 0, 0, Local, 1320573600},   // 2:00:00 PST
+
+	{2011, 3, 13, 1, 0, 0, 0, Local, 1300006800},   // 1:00:00 PST
+	{2011, 3, 13, 1, 59, 59, 0, Local, 1300010399}, // 1:59:59 PST
+	{2011, 3, 13, 3, 0, 0, 0, Local, 1300010400},   // 3:00:00 PDT
+	{2011, 3, 13, 2, 30, 0, 0, Local, 1300008600},  // 2:30:00 PDT ≡ 1:30 PST
+
+	// Many names for Fri Nov 18 7:56:35 PST 2011
+	{2011, 11, 18, 7, 56, 35, 0, Local, 1321631795},                 // Nov 18 7:56:35
+	{2011, 11, 19, -17, 56, 35, 0, Local, 1321631795},               // Nov 19 -17:56:35
+	{2011, 11, 17, 31, 56, 35, 0, Local, 1321631795},                // Nov 17 31:56:35
+	{2011, 11, 18, 6, 116, 35, 0, Local, 1321631795},                // Nov 18 6:116:35
+	{2011, 10, 49, 7, 56, 35, 0, Local, 1321631795},                 // Oct 49 7:56:35
+	{2011, 11, 18, 7, 55, 95, 0, Local, 1321631795},                 // Nov 18 7:55:95
+	{2011, 11, 18, 7, 56, 34, 1e9, Local, 1321631795},               // Nov 18 7:56:34 + 10⁹ns
+	{2011, 12, -12, 7, 56, 35, 0, Local, 1321631795},                // Dec -21 7:56:35
+	{2012, 1, -43, 7, 56, 35, 0, Local, 1321631795},                 // Jan -52 7:56:35 2012
+	{2012, int(January - 2), 18, 7, 56, 35, 0, Local, 1321631795},   // (Jan-2) 18 7:56:35 2012
+	{2010, int(December + 11), 18, 7, 56, 35, 0, Local, 1321631795}, // (Dec+11) 18 7:56:35 2010
+}
+
+func TestDate(t *testing.T) {
+	for _, tt := range dateTests {
+		time := Date(tt.year, Month(tt.month), tt.day, tt.hour, tt.min, tt.sec, tt.nsec, tt.z)
+		want := Unix(tt.unix, 0)
+		if !time.Equal(want) {
+			t.Errorf("Date(%d, %d, %d, %d, %d, %d, %d, %s) = %v, want %v",
+				tt.year, tt.month, tt.day, tt.hour, tt.min, tt.sec, tt.nsec, tt.z,
+				time, want)
+		}
+	}
+}
+
+// Several ways of getting from
+// Fri Nov 18 7:56:35 PST 2011
+// to
+// Thu Mar 19 7:56:35 PST 2016
+var addDateTests = []struct {
+	years, months, days int
+}{
+	{4, 4, 1},
+	{3, 16, 1},
+	{3, 15, 30},
+	{5, -6, -18 - 30 - 12},
+}
+
+func TestAddDate(t *testing.T) {
+	t0 := Date(2011, 11, 18, 7, 56, 35, 0, UTC)
+	t1 := Date(2016, 3, 19, 7, 56, 35, 0, UTC)
+	for _, at := range addDateTests {
+		time := t0.AddDate(at.years, at.months, at.days)
+		if !time.Equal(t1) {
+			t.Errorf("AddDate(%d, %d, %d) = %v, want %v",
+				at.years, at.months, at.days,
+				time, t1)
+		}
+	}
+}
+
+var daysInTests = []struct {
+	year, month, di int
+}{
+	{2011, 1, 31},  // January, first month, 31 days
+	{2011, 2, 28},  // February, non-leap year, 28 days
+	{2012, 2, 29},  // February, leap year, 29 days
+	{2011, 6, 30},  // June, 30 days
+	{2011, 12, 31}, // December, last month, 31 days
+}
+
+func TestDaysIn(t *testing.T) {
+	// The daysIn function is not exported.
+	// Test the daysIn function via the `var DaysIn = daysIn`
+	// statement in the internal_test.go file.
+	for _, tt := range daysInTests {
+		di := DaysIn(Month(tt.month), tt.year)
+		if di != tt.di {
+			t.Errorf("got %d; expected %d for %d-%02d",
+				di, tt.di, tt.year, tt.month)
+		}
+	}
+}
+
+func TestAddToExactSecond(t *testing.T) {
+	// Add an amount to the current time to round it up to the next exact second.
+	// This test checks that the nsec field still lies within the range [0, 999999999].
+	t1 := Now()
+	t2 := t1.Add(Second - Duration(t1.Nanosecond()))
+	sec := (t1.Second() + 1) % 60
+	if t2.Second() != sec || t2.Nanosecond() != 0 {
+		t.Errorf("sec = %d, nsec = %d, want sec = %d, nsec = 0", t2.Second(), t2.Nanosecond(), sec)
+	}
+}
+
+func equalTimeAndZone(a, b Time) bool {
+	aname, aoffset := a.Zone()
+	bname, boffset := b.Zone()
+	return a.Equal(b) && aoffset == boffset && aname == bname
+}
+
+var gobTests = []Time{
+	Date(0, 1, 2, 3, 4, 5, 6, UTC),
+	Date(7, 8, 9, 10, 11, 12, 13, FixedZone("", 0)),
+	Unix(81985467080890095, 0x76543210), // Time.sec: 0x0123456789ABCDEF
+	{}, // nil location
+	Date(1, 2, 3, 4, 5, 6, 7, FixedZone("", 32767*60)),
+	Date(1, 2, 3, 4, 5, 6, 7, FixedZone("", -32768*60)),
+}
+
+func TestTimeGob(t *testing.T) {
+	var b bytes.Buffer
+	enc := gob.NewEncoder(&b)
+	dec := gob.NewDecoder(&b)
+	for _, tt := range gobTests {
+		var gobtt Time
+		if err := enc.Encode(&tt); err != nil {
+			t.Errorf("%v gob Encode error = %q, want nil", tt, err)
+		} else if err := dec.Decode(&gobtt); err != nil {
+			t.Errorf("%v gob Decode error = %q, want nil", tt, err)
+		} else if !equalTimeAndZone(gobtt, tt) {
+			t.Errorf("Decoded time = %v, want %v", gobtt, tt)
+		}
+		b.Reset()
+	}
+}
+
+var invalidEncodingTests = []struct {
+	bytes []byte
+	want  string
+}{
+	{[]byte{}, "Time.UnmarshalBinary: no data"},
+	{[]byte{0, 2, 3}, "Time.UnmarshalBinary: unsupported version"},
+	{[]byte{1, 2, 3}, "Time.UnmarshalBinary: invalid length"},
+}
+
+func TestInvalidTimeGob(t *testing.T) {
+	for _, tt := range invalidEncodingTests {
+		var ignored Time
+		err := ignored.GobDecode(tt.bytes)
+		if err == nil || err.Error() != tt.want {
+			t.Errorf("time.GobDecode(%#v) error = %v, want %v", tt.bytes, err, tt.want)
+		}
+		err = ignored.UnmarshalBinary(tt.bytes)
+		if err == nil || err.Error() != tt.want {
+			t.Errorf("time.UnmarshalBinary(%#v) error = %v, want %v", tt.bytes, err, tt.want)
+		}
+	}
+}
+
+var notEncodableTimes = []struct {
+	time Time
+	want string
+}{
+	{Date(0, 1, 2, 3, 4, 5, 6, FixedZone("", 1)), "Time.MarshalBinary: zone offset has fractional minute"},
+	{Date(0, 1, 2, 3, 4, 5, 6, FixedZone("", -1*60)), "Time.MarshalBinary: unexpected zone offset"},
+	{Date(0, 1, 2, 3, 4, 5, 6, FixedZone("", -32769*60)), "Time.MarshalBinary: unexpected zone offset"},
+	{Date(0, 1, 2, 3, 4, 5, 6, FixedZone("", 32768*60)), "Time.MarshalBinary: unexpected zone offset"},
+}
+
+func TestNotGobEncodableTime(t *testing.T) {
+	for _, tt := range notEncodableTimes {
+		_, err := tt.time.GobEncode()
+		if err == nil || err.Error() != tt.want {
+			t.Errorf("%v GobEncode error = %v, want %v", tt.time, err, tt.want)
+		}
+		_, err = tt.time.MarshalBinary()
+		if err == nil || err.Error() != tt.want {
+			t.Errorf("%v MarshalBinary error = %v, want %v", tt.time, err, tt.want)
+		}
+	}
+}
+
+var jsonTests = []struct {
+	time Time
+	json string
+}{
+	{Date(9999, 4, 12, 23, 20, 50, 520*1e6, UTC), `"9999-04-12T23:20:50.52Z"`},
+	{Date(1996, 12, 19, 16, 39, 57, 0, Local), `"1996-12-19T16:39:57-08:00"`},
+	{Date(0, 1, 1, 0, 0, 0, 1, FixedZone("", 1*60)), `"0000-01-01T00:00:00.000000001+00:01"`},
+}
+
+func TestTimeJSON(t *testing.T) {
+	for _, tt := range jsonTests {
+		var jsonTime Time
+
+		if jsonBytes, err := json.Marshal(tt.time); err != nil {
+			t.Errorf("%v json.Marshal error = %v, want nil", tt.time, err)
+		} else if string(jsonBytes) != tt.json {
+			t.Errorf("%v JSON = %#q, want %#q", tt.time, string(jsonBytes), tt.json)
+		} else if err = json.Unmarshal(jsonBytes, &jsonTime); err != nil {
+			t.Errorf("%v json.Unmarshal error = %v, want nil", tt.time, err)
+		} else if !equalTimeAndZone(jsonTime, tt.time) {
+			t.Errorf("Unmarshaled time = %v, want %v", jsonTime, tt.time)
+		}
+	}
+}
+
+func TestInvalidTimeJSON(t *testing.T) {
+	var tt Time
+	err := json.Unmarshal([]byte(`{"now is the time":"buddy"}`), &tt)
+	_, isParseErr := err.(*ParseError)
+	if !isParseErr {
+		t.Errorf("expected *time.ParseError unmarshaling JSON, got %v", err)
+	}
+}
+
+var notJSONEncodableTimes = []struct {
+	time Time
+	want string
+}{
+	{Date(10000, 1, 1, 0, 0, 0, 0, UTC), "Time.MarshalJSON: year outside of range [0,9999]"},
+	{Date(-1, 1, 1, 0, 0, 0, 0, UTC), "Time.MarshalJSON: year outside of range [0,9999]"},
+}
+
+func TestNotJSONEncodableTime(t *testing.T) {
+	for _, tt := range notJSONEncodableTimes {
+		_, err := tt.time.MarshalJSON()
+		if err == nil || err.Error() != tt.want {
+			t.Errorf("%v MarshalJSON error = %v, want %v", tt.time, err, tt.want)
+		}
+	}
+}
+
+var parseDurationTests = []struct {
+	in   string
+	ok   bool
+	want Duration
+}{
+	// simple
+	{"0", true, 0},
+	{"5s", true, 5 * Second},
+	{"30s", true, 30 * Second},
+	{"1478s", true, 1478 * Second},
+	// sign
+	{"-5s", true, -5 * Second},
+	{"+5s", true, 5 * Second},
+	{"-0", true, 0},
+	{"+0", true, 0},
+	// decimal
+	{"5.0s", true, 5 * Second},
+	{"5.6s", true, 5*Second + 600*Millisecond},
+	{"5.s", true, 5 * Second},
+	{".5s", true, 500 * Millisecond},
+	{"1.0s", true, 1 * Second},
+	{"1.00s", true, 1 * Second},
+	{"1.004s", true, 1*Second + 4*Millisecond},
+	{"1.0040s", true, 1*Second + 4*Millisecond},
+	{"100.00100s", true, 100*Second + 1*Millisecond},
+	// different units
+	{"10ns", true, 10 * Nanosecond},
+	{"11us", true, 11 * Microsecond},
+	{"12µs", true, 12 * Microsecond}, // U+00B5
+	{"12μs", true, 12 * Microsecond}, // U+03BC
+	{"13ms", true, 13 * Millisecond},
+	{"14s", true, 14 * Second},
+	{"15m", true, 15 * Minute},
+	{"16h", true, 16 * Hour},
+	// composite durations
+	{"3h30m", true, 3*Hour + 30*Minute},
+	{"10.5s4m", true, 4*Minute + 10*Second + 500*Millisecond},
+	{"-2m3.4s", true, -(2*Minute + 3*Second + 400*Millisecond)},
+	{"1h2m3s4ms5us6ns", true, 1*Hour + 2*Minute + 3*Second + 4*Millisecond + 5*Microsecond + 6*Nanosecond},
+	{"39h9m14.425s", true, 39*Hour + 9*Minute + 14*Second + 425*Millisecond},
+	// large value
+	{"52763797000ns", true, 52763797000 * Nanosecond},
+	// more than 9 digits after decimal point, see http://golang.org/issue/6617
+	{"0.3333333333333333333h", true, 20 * Minute},
+
+	// errors
+	{"", false, 0},
+	{"3", false, 0},
+	{"-", false, 0},
+	{"s", false, 0},
+	{".", false, 0},
+	{"-.", false, 0},
+	{".s", false, 0},
+	{"+.s", false, 0},
+	{"3000000h", false, 0}, // overflow
+}
+
+func TestParseDuration(t *testing.T) {
+	for _, tc := range parseDurationTests {
+		d, err := ParseDuration(tc.in)
+		if tc.ok && (err != nil || d != tc.want) {
+			t.Errorf("ParseDuration(%q) = %v, %v, want %v, nil", tc.in, d, err, tc.want)
+		} else if !tc.ok && err == nil {
+			t.Errorf("ParseDuration(%q) = _, nil, want _, non-nil", tc.in)
+		}
+	}
+}
+
+func TestParseDurationRoundTrip(t *testing.T) {
+	for i := 0; i < 100; i++ {
+		// Resolutions finer than milliseconds will result in
+		// imprecise round-trips.
+		d0 := Duration(rand.Int31()) * Millisecond
+		s := d0.String()
+		d1, err := ParseDuration(s)
+		if err != nil || d0 != d1 {
+			t.Errorf("round-trip failed: %d => %q => %d, %v", d0, s, d1, err)
+		}
+	}
+}
+
+// golang.org/issue/4622
+func TestLocationRace(t *testing.T) {
+	ResetLocalOnceForTest() // reset the Once to trigger the race
+
+	c := make(chan string, 1)
+	go func() {
+		c <- Now().String()
+	}()
+	Now().String()
+	<-c
+	Sleep(100 * Millisecond)
+
+	// Back to Los Angeles for subsequent tests:
+	ForceUSPacificForTesting()
+}
+
+var (
+	t Time
+	u int64
+)
+
+var mallocTest = []struct {
+	count int
+	desc  string
+	fn    func()
+}{
+	{0, `time.Now()`, func() { t = Now() }},
+	{0, `time.Now().UnixNano()`, func() { u = Now().UnixNano() }},
+}
+
+func TestCountMallocs(t *testing.T) {
+	if testing.Short() {
+		t.Skip("skipping malloc count in short mode")
+	}
+	if runtime.GOMAXPROCS(0) > 1 {
+		t.Skip("skipping; GOMAXPROCS>1")
+	}
+	for _, mt := range mallocTest {
+		allocs := int(testing.AllocsPerRun(100, mt.fn))
+		if allocs > mt.count {
+			t.Errorf("%s: %d allocs, want %d", mt.desc, allocs, mt.count)
+		}
+	}
+}
+
+func TestLoadFixed(t *testing.T) {
+	// Issue 4064: handle locations without any zone transitions.
+	loc, err := LoadLocation("Etc/GMT+1")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	// The tzdata name Etc/GMT+1 uses "east is negative",
+	// but Go and most other systems use "east is positive".
+	// So GMT+1 corresponds to -3600 in the Go zone, not +3600.
+	name, offset := Now().In(loc).Zone()
+	if name != "GMT+1" || offset != -1*60*60 {
+		t.Errorf("Now().In(loc).Zone() = %q, %d, want %q, %d", name, offset, "GMT+1", -1*60*60)
+	}
+}
+
+const (
+	minDuration Duration = -1 << 63
+	maxDuration Duration = 1<<63 - 1
+)
+
+var subTests = []struct {
+	t Time
+	u Time
+	d Duration
+}{
+	{Time{}, Time{}, Duration(0)},
+	{Date(2009, 11, 23, 0, 0, 0, 1, UTC), Date(2009, 11, 23, 0, 0, 0, 0, UTC), Duration(1)},
+	{Date(2009, 11, 23, 0, 0, 0, 0, UTC), Date(2009, 11, 24, 0, 0, 0, 0, UTC), -24 * Hour},
+	{Date(2009, 11, 24, 0, 0, 0, 0, UTC), Date(2009, 11, 23, 0, 0, 0, 0, UTC), 24 * Hour},
+	{Date(-2009, 11, 24, 0, 0, 0, 0, UTC), Date(-2009, 11, 23, 0, 0, 0, 0, UTC), 24 * Hour},
+	{Time{}, Date(2109, 11, 23, 0, 0, 0, 0, UTC), Duration(minDuration)},
+	{Date(2109, 11, 23, 0, 0, 0, 0, UTC), Time{}, Duration(maxDuration)},
+	{Time{}, Date(-2109, 11, 23, 0, 0, 0, 0, UTC), Duration(maxDuration)},
+	{Date(-2109, 11, 23, 0, 0, 0, 0, UTC), Time{}, Duration(minDuration)},
+	{Date(2290, 1, 1, 0, 0, 0, 0, UTC), Date(2000, 1, 1, 0, 0, 0, 0, UTC), 290*365*24*Hour + 71*24*Hour},
+	{Date(2300, 1, 1, 0, 0, 0, 0, UTC), Date(2000, 1, 1, 0, 0, 0, 0, UTC), Duration(maxDuration)},
+	{Date(2000, 1, 1, 0, 0, 0, 0, UTC), Date(2290, 1, 1, 0, 0, 0, 0, UTC), -290*365*24*Hour - 71*24*Hour},
+	{Date(2000, 1, 1, 0, 0, 0, 0, UTC), Date(2300, 1, 1, 0, 0, 0, 0, UTC), Duration(minDuration)},
+}
+
+func TestSub(t *testing.T) {
+	for i, st := range subTests {
+		got := st.t.Sub(st.u)
+		if got != st.d {
+			t.Errorf("#%d: Sub(%v, %v): got %v; want %v", i, st.t, st.u, got, st.d)
+		}
+	}
+}
+
+var nsDurationTests = []struct {
+	d    Duration
+	want int64
+}{
+	{Duration(-1000), -1000},
+	{Duration(-1), -1},
+	{Duration(1), 1},
+	{Duration(1000), 1000},
+}
+
+func TestDurationNanoseconds(t *testing.T) {
+	for _, tt := range nsDurationTests {
+		if got := tt.d.Nanoseconds(); got != tt.want {
+			t.Errorf("d.Nanoseconds() = %d; want: %d", got, tt.want)
+		}
+	}
+}
+
+var minDurationTests = []struct {
+	d    Duration
+	want float64
+}{
+	{Duration(-60000000000), -1},
+	{Duration(-1), -1 / 60e9},
+	{Duration(1), 1 / 60e9},
+	{Duration(60000000000), 1},
+}
+
+func TestDurationMinutes(t *testing.T) {
+	for _, tt := range minDurationTests {
+		if got := tt.d.Minutes(); got != tt.want {
+			t.Errorf("d.Minutes() = %g; want: %g", got, tt.want)
+		}
+	}
+}
+
+var hourDurationTests = []struct {
+	d    Duration
+	want float64
+}{
+	{Duration(-3600000000000), -1},
+	{Duration(-1), -1 / 3600e9},
+	{Duration(1), 1 / 3600e9},
+	{Duration(3600000000000), 1},
+}
+
+func TestDurationHours(t *testing.T) {
+	for _, tt := range hourDurationTests {
+		if got := tt.d.Hours(); got != tt.want {
+			t.Errorf("d.Hours() = %g; want: %g", got, tt.want)
+		}
+	}
+}
+
+func BenchmarkNow(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		t = Now()
+	}
+}
+
+func BenchmarkNowUnixNano(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		u = Now().UnixNano()
+	}
+}
+
+func BenchmarkFormat(b *testing.B) {
+	t := Unix(1265346057, 0)
+	for i := 0; i < b.N; i++ {
+		t.Format("Mon Jan  2 15:04:05 2006")
+	}
+}
+
+func BenchmarkFormatNow(b *testing.B) {
+	// Like BenchmarkFormat, but easier, because the time zone
+	// lookup cache is optimized for the present.
+	t := Now()
+	for i := 0; i < b.N; i++ {
+		t.Format("Mon Jan  2 15:04:05 2006")
+	}
+}
+
+func BenchmarkParse(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		Parse(ANSIC, "Mon Jan  2 15:04:05 2006")
+	}
+}
+
+func BenchmarkHour(b *testing.B) {
+	t := Now()
+	for i := 0; i < b.N; i++ {
+		_ = t.Hour()
+	}
+}
+
+func BenchmarkSecond(b *testing.B) {
+	t := Now()
+	for i := 0; i < b.N; i++ {
+		_ = t.Second()
+	}
+}
+
+func BenchmarkYear(b *testing.B) {
+	t := Now()
+	for i := 0; i < b.N; i++ {
+		_ = t.Year()
+	}
+}
+
+func BenchmarkDay(b *testing.B) {
+	t := Now()
+	for i := 0; i < b.N; i++ {
+		_ = t.Day()
+	}
+}
diff --git a/src/pkg/time/zoneinfo.go b/src/time/zoneinfo.go
similarity index 100%
rename from src/pkg/time/zoneinfo.go
rename to src/time/zoneinfo.go
diff --git a/src/time/zoneinfo_abbrs_windows.go b/src/time/zoneinfo_abbrs_windows.go
new file mode 100644
index 0000000..51a1a2f
--- /dev/null
+++ b/src/time/zoneinfo_abbrs_windows.go
@@ -0,0 +1,116 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// generated by genzabbrs.go from
+// http://unicode.org/cldr/data/common/supplemental/windowsZones.xml
+
+package time
+
+type abbr struct {
+	std string
+	dst string
+}
+
+var abbrs = map[string]abbr{
+	"Egypt Standard Time":             {"EET", "EET"},    // Africa/Cairo
+	"Morocco Standard Time":           {"WET", "WEST"},   // Africa/Casablanca
+	"South Africa Standard Time":      {"SAST", "SAST"},  // Africa/Johannesburg
+	"W. Central Africa Standard Time": {"WAT", "WAT"},    // Africa/Lagos
+	"E. Africa Standard Time":         {"EAT", "EAT"},    // Africa/Nairobi
+	"Libya Standard Time":             {"EET", "EET"},    // Africa/Tripoli
+	"Namibia Standard Time":           {"WAT", "WAST"},   // Africa/Windhoek
+	"Alaskan Standard Time":           {"AKST", "AKDT"},  // America/Anchorage
+	"Paraguay Standard Time":          {"PYT", "PYST"},   // America/Asuncion
+	"Bahia Standard Time":             {"BRT", "BRST"},   // America/Bahia
+	"SA Pacific Standard Time":        {"COT", "COT"},    // America/Bogota
+	"Argentina Standard Time":         {"ART", "ART"},    // America/Buenos_Aires
+	"Venezuela Standard Time":         {"VET", "VET"},    // America/Caracas
+	"SA Eastern Standard Time":        {"GFT", "GFT"},    // America/Cayenne
+	"Central Standard Time":           {"CST", "CDT"},    // America/Chicago
+	"Mountain Standard Time (Mexico)": {"MST", "MDT"},    // America/Chihuahua
+	"Central Brazilian Standard Time": {"AMT", "AMST"},   // America/Cuiaba
+	"Mountain Standard Time":          {"MST", "MDT"},    // America/Denver
+	"Greenland Standard Time":         {"WGT", "WGST"},   // America/Godthab
+	"Central America Standard Time":   {"CST", "CST"},    // America/Guatemala
+	"Atlantic Standard Time":          {"AST", "ADT"},    // America/Halifax
+	"US Eastern Standard Time":        {"EST", "EDT"},    // America/Indianapolis
+	"SA Western Standard Time":        {"BOT", "BOT"},    // America/La_Paz
+	"Pacific Standard Time":           {"PST", "PDT"},    // America/Los_Angeles
+	"Central Standard Time (Mexico)":  {"CST", "CDT"},    // America/Mexico_City
+	"Montevideo Standard Time":        {"UYT", "UYST"},   // America/Montevideo
+	"Eastern Standard Time":           {"EST", "EDT"},    // America/New_York
+	"US Mountain Standard Time":       {"MST", "MST"},    // America/Phoenix
+	"Canada Central Standard Time":    {"CST", "CST"},    // America/Regina
+	"Pacific Standard Time (Mexico)":  {"PST", "PDT"},    // America/Santa_Isabel
+	"Pacific SA Standard Time":        {"CLT", "CLST"},   // America/Santiago
+	"E. South America Standard Time":  {"BRT", "BRST"},   // America/Sao_Paulo
+	"Newfoundland Standard Time":      {"NST", "NDT"},    // America/St_Johns
+	"Central Asia Standard Time":      {"ALMT", "ALMT"},  // Asia/Almaty
+	"Jordan Standard Time":            {"EET", "EEST"},   // Asia/Amman
+	"Arabic Standard Time":            {"AST", "AST"},    // Asia/Baghdad
+	"Azerbaijan Standard Time":        {"AZT", "AZST"},   // Asia/Baku
+	"SE Asia Standard Time":           {"ICT", "ICT"},    // Asia/Bangkok
+	"Middle East Standard Time":       {"EET", "EEST"},   // Asia/Beirut
+	"India Standard Time":             {"IST", "IST"},    // Asia/Calcutta
+	"Sri Lanka Standard Time":         {"IST", "IST"},    // Asia/Colombo
+	"Syria Standard Time":             {"EET", "EEST"},   // Asia/Damascus
+	"Bangladesh Standard Time":        {"BDT", "BDT"},    // Asia/Dhaka
+	"Arabian Standard Time":           {"GST", "GST"},    // Asia/Dubai
+	"North Asia East Standard Time":   {"IRKT", "IRKT"},  // Asia/Irkutsk
+	"Israel Standard Time":            {"IST", "IDT"},    // Asia/Jerusalem
+	"Afghanistan Standard Time":       {"AFT", "AFT"},    // Asia/Kabul
+	"Pakistan Standard Time":          {"PKT", "PKT"},    // Asia/Karachi
+	"Nepal Standard Time":             {"NPT", "NPT"},    // Asia/Katmandu
+	"North Asia Standard Time":        {"KRAT", "KRAT"},  // Asia/Krasnoyarsk
+	"Magadan Standard Time":           {"MAGT", "MAGT"},  // Asia/Magadan
+	"N. Central Asia Standard Time":   {"NOVT", "NOVT"},  // Asia/Novosibirsk
+	"Myanmar Standard Time":           {"MMT", "MMT"},    // Asia/Rangoon
+	"Arab Standard Time":              {"AST", "AST"},    // Asia/Riyadh
+	"Korea Standard Time":             {"KST", "KST"},    // Asia/Seoul
+	"China Standard Time":             {"CST", "CST"},    // Asia/Shanghai
+	"Singapore Standard Time":         {"SGT", "SGT"},    // Asia/Singapore
+	"Taipei Standard Time":            {"CST", "CST"},    // Asia/Taipei
+	"West Asia Standard Time":         {"UZT", "UZT"},    // Asia/Tashkent
+	"Georgian Standard Time":          {"GET", "GET"},    // Asia/Tbilisi
+	"Iran Standard Time":              {"IRST", "IRDT"},  // Asia/Tehran
+	"Tokyo Standard Time":             {"JST", "JST"},    // Asia/Tokyo
+	"Ulaanbaatar Standard Time":       {"ULAT", "ULAT"},  // Asia/Ulaanbaatar
+	"Vladivostok Standard Time":       {"VLAT", "VLAT"},  // Asia/Vladivostok
+	"Yakutsk Standard Time":           {"YAKT", "YAKT"},  // Asia/Yakutsk
+	"Ekaterinburg Standard Time":      {"YEKT", "YEKT"},  // Asia/Yekaterinburg
+	"Caucasus Standard Time":          {"AMT", "AMT"},    // Asia/Yerevan
+	"Azores Standard Time":            {"AZOT", "AZOST"}, // Atlantic/Azores
+	"Cape Verde Standard Time":        {"CVT", "CVT"},    // Atlantic/Cape_Verde
+	"Greenwich Standard Time":         {"GMT", "GMT"},    // Atlantic/Reykjavik
+	"Cen. Australia Standard Time":    {"CST", "CST"},    // Australia/Adelaide
+	"E. Australia Standard Time":      {"EST", "EST"},    // Australia/Brisbane
+	"AUS Central Standard Time":       {"CST", "CST"},    // Australia/Darwin
+	"Tasmania Standard Time":          {"EST", "EST"},    // Australia/Hobart
+	"W. Australia Standard Time":      {"WST", "WST"},    // Australia/Perth
+	"AUS Eastern Standard Time":       {"EST", "EST"},    // Australia/Sydney
+	"UTC":                            {"GMT", "GMT"},       // Etc/GMT
+	"UTC-11":                         {"GMT+11", "GMT+11"}, // Etc/GMT+11
+	"Dateline Standard Time":         {"GMT+12", "GMT+12"}, // Etc/GMT+12
+	"UTC-02":                         {"GMT+2", "GMT+2"},   // Etc/GMT+2
+	"UTC+12":                         {"GMT-12", "GMT-12"}, // Etc/GMT-12
+	"W. Europe Standard Time":        {"CET", "CEST"},      // Europe/Berlin
+	"GTB Standard Time":              {"EET", "EEST"},      // Europe/Bucharest
+	"Central Europe Standard Time":   {"CET", "CEST"},      // Europe/Budapest
+	"Turkey Standard Time":           {"EET", "EEST"},      // Europe/Istanbul
+	"Kaliningrad Standard Time":      {"FET", "FET"},       // Europe/Kaliningrad
+	"FLE Standard Time":              {"EET", "EEST"},      // Europe/Kiev
+	"GMT Standard Time":              {"GMT", "BST"},       // Europe/London
+	"Russian Standard Time":          {"MSK", "MSK"},       // Europe/Moscow
+	"Romance Standard Time":          {"CET", "CEST"},      // Europe/Paris
+	"Central European Standard Time": {"CET", "CEST"},      // Europe/Warsaw
+	"Mauritius Standard Time":        {"MUT", "MUT"},       // Indian/Mauritius
+	"Samoa Standard Time":            {"WST", "WST"},       // Pacific/Apia
+	"New Zealand Standard Time":      {"NZST", "NZDT"},     // Pacific/Auckland
+	"Fiji Standard Time":             {"FJT", "FJT"},       // Pacific/Fiji
+	"Central Pacific Standard Time":  {"SBT", "SBT"},       // Pacific/Guadalcanal
+	"Hawaiian Standard Time":         {"HST", "HST"},       // Pacific/Honolulu
+	"Line Islands Standard Time":     {"LINT", "LINT"},     // Pacific/Kiritimati
+	"West Pacific Standard Time":     {"PGT", "PGT"},       // Pacific/Port_Moresby
+	"Tonga Standard Time":            {"TOT", "TOT"},       // Pacific/Tongatapu
+}
diff --git a/src/pkg/time/zoneinfo_plan9.go b/src/time/zoneinfo_plan9.go
similarity index 100%
rename from src/pkg/time/zoneinfo_plan9.go
rename to src/time/zoneinfo_plan9.go
diff --git a/src/pkg/time/zoneinfo_read.go b/src/time/zoneinfo_read.go
similarity index 100%
rename from src/pkg/time/zoneinfo_read.go
rename to src/time/zoneinfo_read.go
diff --git a/src/pkg/time/zoneinfo_test.go b/src/time/zoneinfo_test.go
similarity index 100%
rename from src/pkg/time/zoneinfo_test.go
rename to src/time/zoneinfo_test.go
diff --git a/src/pkg/time/zoneinfo_unix.go b/src/time/zoneinfo_unix.go
similarity index 100%
rename from src/pkg/time/zoneinfo_unix.go
rename to src/time/zoneinfo_unix.go
diff --git a/src/time/zoneinfo_windows.go b/src/time/zoneinfo_windows.go
new file mode 100644
index 0000000..02d8e0e
--- /dev/null
+++ b/src/time/zoneinfo_windows.go
@@ -0,0 +1,272 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package time
+
+import (
+	"errors"
+	"runtime"
+	"syscall"
+	"unsafe"
+)
+
+//go:generate go run genzabbrs.go -output zoneinfo_abbrs_windows.go
+
+// TODO(rsc): Fall back to copy of zoneinfo files.
+
+// BUG(brainman,rsc): On Windows, the operating system does not provide complete
+// time zone information.
+// The implementation assumes that this year's rules for daylight savings
+// time apply to all previous and future years as well.
+
+// getKeyValue retrieves the string value kname associated with the open registry key kh.
+func getKeyValue(kh syscall.Handle, kname string) (string, error) {
+	var buf [50]uint16 // buf needs to be large enough to fit zone descriptions
+	var typ uint32
+	n := uint32(len(buf) * 2) // RegQueryValueEx's signature expects array of bytes, not uint16
+	p, _ := syscall.UTF16PtrFromString(kname)
+	if err := syscall.RegQueryValueEx(kh, p, nil, &typ, (*byte)(unsafe.Pointer(&buf[0])), &n); err != nil {
+		return "", err
+	}
+	if typ != syscall.REG_SZ { // null terminated strings only
+		return "", errors.New("Key is not string")
+	}
+	return syscall.UTF16ToString(buf[:]), nil
+}
+
+// matchZoneKey checks if stdname and dstname match the corresponding "Std"
+// and "Dlt" key values in the kname key stored under the open registry key zones.
+func matchZoneKey(zones syscall.Handle, kname string, stdname, dstname string) (matched bool, err2 error) {
+	var h syscall.Handle
+	p, _ := syscall.UTF16PtrFromString(kname)
+	if err := syscall.RegOpenKeyEx(zones, p, 0, syscall.KEY_READ, &h); err != nil {
+		return false, err
+	}
+	defer syscall.RegCloseKey(h)
+
+	s, err := getKeyValue(h, "Std")
+	if err != nil {
+		return false, err
+	}
+	if s != stdname {
+		return false, nil
+	}
+	s, err = getKeyValue(h, "Dlt")
+	if err != nil {
+		return false, err
+	}
+	if s != dstname && dstname != stdname {
+		return false, nil
+	}
+	return true, nil
+}
+
+// toEnglishName searches the registry for an English name of a time zone
+// whose zone names are stdname and dstname and returns the English name.
+func toEnglishName(stdname, dstname string) (string, error) {
+	var zones syscall.Handle
+	p, _ := syscall.UTF16PtrFromString(`SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones`)
+	if err := syscall.RegOpenKeyEx(syscall.HKEY_LOCAL_MACHINE, p, 0, syscall.KEY_READ, &zones); err != nil {
+		return "", err
+	}
+	defer syscall.RegCloseKey(zones)
+
+	var count uint32
+	if err := syscall.RegQueryInfoKey(zones, nil, nil, nil, &count, nil, nil, nil, nil, nil, nil, nil); err != nil {
+		return "", err
+	}
+
+	var buf [50]uint16 // buf needs to be large enough to fit zone descriptions
+	for i := uint32(0); i < count; i++ {
+		n := uint32(len(buf))
+		if syscall.RegEnumKeyEx(zones, i, &buf[0], &n, nil, nil, nil, nil) != nil {
+			continue
+		}
+		kname := syscall.UTF16ToString(buf[:])
+		matched, err := matchZoneKey(zones, kname, stdname, dstname)
+		if err == nil && matched {
+			return kname, nil
+		}
+	}
+	return "", errors.New(`English name for time zone "` + stdname + `" not found in registry`)
+}
+
+// extractCAPS extracts capital letters from description desc.
+func extractCAPS(desc string) string {
+	var short []rune
+	for _, c := range desc {
+		if 'A' <= c && c <= 'Z' {
+			short = append(short, rune(c))
+		}
+	}
+	return string(short)
+}
+
+// abbrev returns the abbreviations to use for the given zone z.
+func abbrev(z *syscall.Timezoneinformation) (std, dst string) {
+	stdName := syscall.UTF16ToString(z.StandardName[:])
+	a, ok := abbrs[stdName]
+	if !ok {
+		dstName := syscall.UTF16ToString(z.DaylightName[:])
+		// Perhaps stdName is not English. Try to convert it.
+		englishName, err := toEnglishName(stdName, dstName)
+		if err == nil {
+			a, ok = abbrs[englishName]
+			if ok {
+				return a.std, a.dst
+			}
+		}
+		// fallback to using capital letters
+		return extractCAPS(stdName), extractCAPS(dstName)
+	}
+	return a.std, a.dst
+}
+
+// pseudoUnix returns the pseudo-Unix time (seconds since Jan 1 1970 *LOCAL TIME*)
+// denoted by the system date+time d in the given year.
+// It is up to the caller to convert this local time into a UTC-based time.
+func pseudoUnix(year int, d *syscall.Systemtime) int64 {
+	// Windows specifies daylight savings information in "day in month" format:
+	// d.Month is month number (1-12)
+	// d.DayOfWeek is appropriate weekday (Sunday=0 to Saturday=6)
+	// d.Day is week within the month (1 to 5, where 5 is last week of the month)
+	// d.Hour, d.Minute and d.Second are absolute time
+	day := 1
+	t := Date(year, Month(d.Month), day, int(d.Hour), int(d.Minute), int(d.Second), 0, UTC)
+	i := int(d.DayOfWeek) - int(t.Weekday())
+	if i < 0 {
+		i += 7
+	}
+	day += i
+	if week := int(d.Day) - 1; week < 4 {
+		day += week * 7
+	} else {
+		// "Last" instance of the day.
+		day += 4 * 7
+		if day > daysIn(Month(d.Month), year) {
+			day -= 7
+		}
+	}
+	return t.sec + int64(day-1)*secondsPerDay + internalToUnix
+}
+
+func initLocalFromTZI(i *syscall.Timezoneinformation) {
+	l := &localLoc
+
+	nzone := 1
+	if i.StandardDate.Month > 0 {
+		nzone++
+	}
+	l.zone = make([]zone, nzone)
+
+	stdname, dstname := abbrev(i)
+
+	std := &l.zone[0]
+	std.name = stdname
+	if nzone == 1 {
+		// No daylight savings.
+		std.offset = -int(i.Bias) * 60
+		l.cacheStart = alpha
+		l.cacheEnd = omega
+		l.cacheZone = std
+		l.tx = make([]zoneTrans, 1)
+		l.tx[0].when = l.cacheStart
+		l.tx[0].index = 0
+		return
+	}
+
+	// StandardBias must be ignored if StandardDate is not set,
+	// so this computation is delayed until after the nzone==1
+	// return above.
+	std.offset = -int(i.Bias+i.StandardBias) * 60
+
+	dst := &l.zone[1]
+	dst.name = dstname
+	dst.offset = -int(i.Bias+i.DaylightBias) * 60
+	dst.isDST = true
+
+	// Arrange so that d0 is first transition date, d1 second,
+	// i0 is index of zone after first transition, i1 second.
+	d0 := &i.StandardDate
+	d1 := &i.DaylightDate
+	i0 := 0
+	i1 := 1
+	if d0.Month > d1.Month {
+		d0, d1 = d1, d0
+		i0, i1 = i1, i0
+	}
+
+	// 2 tx per year, 100 years on each side of this year
+	l.tx = make([]zoneTrans, 400)
+
+	t := Now().UTC()
+	year := t.Year()
+	txi := 0
+	for y := year - 100; y < year+100; y++ {
+		tx := &l.tx[txi]
+		tx.when = pseudoUnix(y, d0) - int64(l.zone[i1].offset)
+		tx.index = uint8(i0)
+		txi++
+
+		tx = &l.tx[txi]
+		tx.when = pseudoUnix(y, d1) - int64(l.zone[i0].offset)
+		tx.index = uint8(i1)
+		txi++
+	}
+}
+
+var usPacific = syscall.Timezoneinformation{
+	Bias: 8 * 60,
+	StandardName: [32]uint16{
+		'P', 'a', 'c', 'i', 'f', 'i', 'c', ' ', 'S', 't', 'a', 'n', 'd', 'a', 'r', 'd', ' ', 'T', 'i', 'm', 'e',
+	},
+	StandardDate: syscall.Systemtime{Month: 11, Day: 1, Hour: 2},
+	DaylightName: [32]uint16{
+		'P', 'a', 'c', 'i', 'f', 'i', 'c', ' ', 'D', 'a', 'y', 'l', 'i', 'g', 'h', 't', ' ', 'T', 'i', 'm', 'e',
+	},
+	DaylightDate: syscall.Systemtime{Month: 3, Day: 2, Hour: 2},
+	DaylightBias: -60,
+}
+
+var aus = syscall.Timezoneinformation{
+	Bias: -10 * 60,
+	StandardName: [32]uint16{
+		'A', 'U', 'S', ' ', 'E', 'a', 's', 't', 'e', 'r', 'n', ' ', 'S', 't', 'a', 'n', 'd', 'a', 'r', 'd', ' ', 'T', 'i', 'm', 'e',
+	},
+	StandardDate: syscall.Systemtime{Month: 4, Day: 1, Hour: 3},
+	DaylightName: [32]uint16{
+		'A', 'U', 'S', ' ', 'E', 'a', 's', 't', 'e', 'r', 'n', ' ', 'D', 'a', 'y', 'l', 'i', 'g', 'h', 't', ' ', 'T', 'i', 'm', 'e',
+	},
+	DaylightDate: syscall.Systemtime{Month: 10, Day: 1, Hour: 2},
+	DaylightBias: -60,
+}
+
+func initTestingZone() {
+	initLocalFromTZI(&usPacific)
+}
+
+func initAusTestingZone() {
+	initLocalFromTZI(&aus)
+}
+
+func initLocal() {
+	var i syscall.Timezoneinformation
+	if _, err := syscall.GetTimeZoneInformation(&i); err != nil {
+		localLoc.name = "UTC"
+		return
+	}
+	initLocalFromTZI(&i)
+}
+
+func loadLocation(name string) (*Location, error) {
+	if z, err := loadZoneFile(runtime.GOROOT()+`\lib\time\zoneinfo.zip`, name); err == nil {
+		z.name = name
+		return z, nil
+	}
+	return nil, errors.New("unknown time zone " + name)
+}
+
+func forceZipFileForTesting(zipOnly bool) {
+	// We only use the zip file anyway.
+}
diff --git a/src/pkg/time/zoneinfo_windows_test.go b/src/time/zoneinfo_windows_test.go
similarity index 100%
rename from src/pkg/time/zoneinfo_windows_test.go
rename to src/time/zoneinfo_windows_test.go
diff --git a/src/pkg/unicode/casetables.go b/src/unicode/casetables.go
similarity index 100%
rename from src/pkg/unicode/casetables.go
rename to src/unicode/casetables.go
diff --git a/src/pkg/unicode/digit.go b/src/unicode/digit.go
similarity index 100%
rename from src/pkg/unicode/digit.go
rename to src/unicode/digit.go
diff --git a/src/pkg/unicode/digit_test.go b/src/unicode/digit_test.go
similarity index 100%
rename from src/pkg/unicode/digit_test.go
rename to src/unicode/digit_test.go
diff --git a/src/pkg/unicode/graphic.go b/src/unicode/graphic.go
similarity index 100%
rename from src/pkg/unicode/graphic.go
rename to src/unicode/graphic.go
diff --git a/src/pkg/unicode/graphic_test.go b/src/unicode/graphic_test.go
similarity index 100%
rename from src/pkg/unicode/graphic_test.go
rename to src/unicode/graphic_test.go
diff --git a/src/unicode/letter.go b/src/unicode/letter.go
new file mode 100644
index 0000000..7fe4241
--- /dev/null
+++ b/src/unicode/letter.go
@@ -0,0 +1,357 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package unicode provides data and functions to test some properties of
+// Unicode code points.
+package unicode
+
+// Tables are regenerated each time we update the Unicode version.
+//go:generate go run maketables.go -tables=all -output tables.go
+
+const (
+	MaxRune         = '\U0010FFFF' // Maximum valid Unicode code point.
+	ReplacementChar = '\uFFFD'     // Represents invalid code points.
+	MaxASCII        = '\u007F'     // maximum ASCII value.
+	MaxLatin1       = '\u00FF'     // maximum Latin-1 value.
+)
+
+// RangeTable defines a set of Unicode code points by listing the ranges of
+// code points within the set. The ranges are listed in two slices
+// to save space: a slice of 16-bit ranges and a slice of 32-bit ranges.
+// The two slices must be in sorted order and non-overlapping.
+// Also, R32 should contain only values >= 0x10000 (1<<16).
+type RangeTable struct {
+	R16         []Range16
+	R32         []Range32
+	LatinOffset int // number of entries in R16 with Hi <= MaxLatin1
+}
+
+// Range16 represents of a range of 16-bit Unicode code points.  The range runs from Lo to Hi
+// inclusive and has the specified stride.
+type Range16 struct {
+	Lo     uint16
+	Hi     uint16
+	Stride uint16
+}
+
+// Range32 represents of a range of Unicode code points and is used when one or
+// more of the values will not fit in 16 bits.  The range runs from Lo to Hi
+// inclusive and has the specified stride. Lo and Hi must always be >= 1<<16.
+type Range32 struct {
+	Lo     uint32
+	Hi     uint32
+	Stride uint32
+}
+
+// CaseRange represents a range of Unicode code points for simple (one
+// code point to one code point) case conversion.
+// The range runs from Lo to Hi inclusive, with a fixed stride of 1.  Deltas
+// are the number to add to the code point to reach the code point for a
+// different case for that character.  They may be negative.  If zero, it
+// means the character is in the corresponding case. There is a special
+// case representing sequences of alternating corresponding Upper and Lower
+// pairs.  It appears with a fixed Delta of
+//	{UpperLower, UpperLower, UpperLower}
+// The constant UpperLower has an otherwise impossible delta value.
+type CaseRange struct {
+	Lo    uint32
+	Hi    uint32
+	Delta d
+}
+
+// SpecialCase represents language-specific case mappings such as Turkish.
+// Methods of SpecialCase customize (by overriding) the standard mappings.
+type SpecialCase []CaseRange
+
+// BUG(r): There is no mechanism for full case folding, that is, for
+// characters that involve multiple runes in the input or output.
+
+// Indices into the Delta arrays inside CaseRanges for case mapping.
+const (
+	UpperCase = iota
+	LowerCase
+	TitleCase
+	MaxCase
+)
+
+type d [MaxCase]rune // to make the CaseRanges text shorter
+
+// If the Delta field of a CaseRange is UpperLower, it means
+// this CaseRange represents a sequence of the form (say)
+// Upper Lower Upper Lower.
+const (
+	UpperLower = MaxRune + 1 // (Cannot be a valid delta.)
+)
+
+// linearMax is the maximum size table for linear search for non-Latin1 rune.
+// Derived by running 'go test -calibrate'.
+const linearMax = 18
+
+// is16 reports whether r is in the sorted slice of 16-bit ranges.
+func is16(ranges []Range16, r uint16) bool {
+	if len(ranges) <= linearMax || r <= MaxLatin1 {
+		for i := range ranges {
+			range_ := &ranges[i]
+			if r < range_.Lo {
+				return false
+			}
+			if r <= range_.Hi {
+				return (r-range_.Lo)%range_.Stride == 0
+			}
+		}
+		return false
+	}
+
+	// binary search over ranges
+	lo := 0
+	hi := len(ranges)
+	for lo < hi {
+		m := lo + (hi-lo)/2
+		range_ := &ranges[m]
+		if range_.Lo <= r && r <= range_.Hi {
+			return (r-range_.Lo)%range_.Stride == 0
+		}
+		if r < range_.Lo {
+			hi = m
+		} else {
+			lo = m + 1
+		}
+	}
+	return false
+}
+
+// is32 reports whether r is in the sorted slice of 32-bit ranges.
+func is32(ranges []Range32, r uint32) bool {
+	if len(ranges) <= linearMax {
+		for i := range ranges {
+			range_ := &ranges[i]
+			if r < range_.Lo {
+				return false
+			}
+			if r <= range_.Hi {
+				return (r-range_.Lo)%range_.Stride == 0
+			}
+		}
+		return false
+	}
+
+	// binary search over ranges
+	lo := 0
+	hi := len(ranges)
+	for lo < hi {
+		m := lo + (hi-lo)/2
+		range_ := ranges[m]
+		if range_.Lo <= r && r <= range_.Hi {
+			return (r-range_.Lo)%range_.Stride == 0
+		}
+		if r < range_.Lo {
+			hi = m
+		} else {
+			lo = m + 1
+		}
+	}
+	return false
+}
+
+// Is reports whether the rune is in the specified table of ranges.
+func Is(rangeTab *RangeTable, r rune) bool {
+	r16 := rangeTab.R16
+	if len(r16) > 0 && r <= rune(r16[len(r16)-1].Hi) {
+		return is16(r16, uint16(r))
+	}
+	r32 := rangeTab.R32
+	if len(r32) > 0 && r >= rune(r32[0].Lo) {
+		return is32(r32, uint32(r))
+	}
+	return false
+}
+
+func isExcludingLatin(rangeTab *RangeTable, r rune) bool {
+	r16 := rangeTab.R16
+	if off := rangeTab.LatinOffset; len(r16) > off && r <= rune(r16[len(r16)-1].Hi) {
+		return is16(r16[off:], uint16(r))
+	}
+	r32 := rangeTab.R32
+	if len(r32) > 0 && r >= rune(r32[0].Lo) {
+		return is32(r32, uint32(r))
+	}
+	return false
+}
+
+// IsUpper reports whether the rune is an upper case letter.
+func IsUpper(r rune) bool {
+	// See comment in IsGraphic.
+	if uint32(r) <= MaxLatin1 {
+		return properties[uint8(r)]&pLmask == pLu
+	}
+	return isExcludingLatin(Upper, r)
+}
+
+// IsLower reports whether the rune is a lower case letter.
+func IsLower(r rune) bool {
+	// See comment in IsGraphic.
+	if uint32(r) <= MaxLatin1 {
+		return properties[uint8(r)]&pLmask == pLl
+	}
+	return isExcludingLatin(Lower, r)
+}
+
+// IsTitle reports whether the rune is a title case letter.
+func IsTitle(r rune) bool {
+	if r <= MaxLatin1 {
+		return false
+	}
+	return isExcludingLatin(Title, r)
+}
+
+// to maps the rune using the specified case mapping.
+func to(_case int, r rune, caseRange []CaseRange) rune {
+	if _case < 0 || MaxCase <= _case {
+		return ReplacementChar // as reasonable an error as any
+	}
+	// binary search over ranges
+	lo := 0
+	hi := len(caseRange)
+	for lo < hi {
+		m := lo + (hi-lo)/2
+		cr := caseRange[m]
+		if rune(cr.Lo) <= r && r <= rune(cr.Hi) {
+			delta := rune(cr.Delta[_case])
+			if delta > MaxRune {
+				// In an Upper-Lower sequence, which always starts with
+				// an UpperCase letter, the real deltas always look like:
+				//	{0, 1, 0}    UpperCase (Lower is next)
+				//	{-1, 0, -1}  LowerCase (Upper, Title are previous)
+				// The characters at even offsets from the beginning of the
+				// sequence are upper case; the ones at odd offsets are lower.
+				// The correct mapping can be done by clearing or setting the low
+				// bit in the sequence offset.
+				// The constants UpperCase and TitleCase are even while LowerCase
+				// is odd so we take the low bit from _case.
+				return rune(cr.Lo) + ((r-rune(cr.Lo))&^1 | rune(_case&1))
+			}
+			return r + delta
+		}
+		if r < rune(cr.Lo) {
+			hi = m
+		} else {
+			lo = m + 1
+		}
+	}
+	return r
+}
+
+// To maps the rune to the specified case: UpperCase, LowerCase, or TitleCase.
+func To(_case int, r rune) rune {
+	return to(_case, r, CaseRanges)
+}
+
+// ToUpper maps the rune to upper case.
+func ToUpper(r rune) rune {
+	if r <= MaxASCII {
+		if 'a' <= r && r <= 'z' {
+			r -= 'a' - 'A'
+		}
+		return r
+	}
+	return To(UpperCase, r)
+}
+
+// ToLower maps the rune to lower case.
+func ToLower(r rune) rune {
+	if r <= MaxASCII {
+		if 'A' <= r && r <= 'Z' {
+			r += 'a' - 'A'
+		}
+		return r
+	}
+	return To(LowerCase, r)
+}
+
+// ToTitle maps the rune to title case.
+func ToTitle(r rune) rune {
+	if r <= MaxASCII {
+		if 'a' <= r && r <= 'z' { // title case is upper case for ASCII
+			r -= 'a' - 'A'
+		}
+		return r
+	}
+	return To(TitleCase, r)
+}
+
+// ToUpper maps the rune to upper case giving priority to the special mapping.
+func (special SpecialCase) ToUpper(r rune) rune {
+	r1 := to(UpperCase, r, []CaseRange(special))
+	if r1 == r {
+		r1 = ToUpper(r)
+	}
+	return r1
+}
+
+// ToTitle maps the rune to title case giving priority to the special mapping.
+func (special SpecialCase) ToTitle(r rune) rune {
+	r1 := to(TitleCase, r, []CaseRange(special))
+	if r1 == r {
+		r1 = ToTitle(r)
+	}
+	return r1
+}
+
+// ToLower maps the rune to lower case giving priority to the special mapping.
+func (special SpecialCase) ToLower(r rune) rune {
+	r1 := to(LowerCase, r, []CaseRange(special))
+	if r1 == r {
+		r1 = ToLower(r)
+	}
+	return r1
+}
+
+// caseOrbit is defined in tables.go as []foldPair.  Right now all the
+// entries fit in uint16, so use uint16.  If that changes, compilation
+// will fail (the constants in the composite literal will not fit in uint16)
+// and the types here can change to uint32.
+type foldPair struct {
+	From uint16
+	To   uint16
+}
+
+// SimpleFold iterates over Unicode code points equivalent under
+// the Unicode-defined simple case folding.  Among the code points
+// equivalent to rune (including rune itself), SimpleFold returns the
+// smallest rune > r if one exists, or else the smallest rune >= 0.
+//
+// For example:
+//	SimpleFold('A') = 'a'
+//	SimpleFold('a') = 'A'
+//
+//	SimpleFold('K') = 'k'
+//	SimpleFold('k') = '\u212A' (Kelvin symbol, K)
+//	SimpleFold('\u212A') = 'K'
+//
+//	SimpleFold('1') = '1'
+//
+func SimpleFold(r rune) rune {
+	// Consult caseOrbit table for special cases.
+	lo := 0
+	hi := len(caseOrbit)
+	for lo < hi {
+		m := lo + (hi-lo)/2
+		if rune(caseOrbit[m].From) < r {
+			lo = m + 1
+		} else {
+			hi = m
+		}
+	}
+	if lo < len(caseOrbit) && rune(caseOrbit[lo].From) == r {
+		return rune(caseOrbit[lo].To)
+	}
+
+	// No folding specified.  This is a one- or two-element
+	// equivalence class containing rune and ToLower(rune)
+	// and ToUpper(rune) if they are different from rune.
+	if l := ToLower(r); l != r {
+		return l
+	}
+	return ToUpper(r)
+}
diff --git a/src/pkg/unicode/letter_test.go b/src/unicode/letter_test.go
similarity index 100%
rename from src/pkg/unicode/letter_test.go
rename to src/unicode/letter_test.go
diff --git a/src/unicode/maketables.go b/src/unicode/maketables.go
new file mode 100644
index 0000000..d1c9aa0
--- /dev/null
+++ b/src/unicode/maketables.go
@@ -0,0 +1,1376 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build ignore
+
+// Unicode table generator.
+// Data read from the web.
+
+package main
+
+import (
+	"bufio"
+	"flag"
+	"fmt"
+	"io"
+	"log"
+	"net/http"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"regexp"
+	"sort"
+	"strconv"
+	"strings"
+	"unicode"
+)
+
+func main() {
+	flag.Parse()
+	setupOutput()
+	loadChars() // always needed
+	loadCasefold()
+	printCategories()
+	printScriptOrProperty(false)
+	printScriptOrProperty(true)
+	printCases()
+	printLatinProperties()
+	printCasefold()
+	printSizes()
+	flushOutput()
+}
+
+var dataURL = flag.String("data", "", "full URL for UnicodeData.txt; defaults to --url/UnicodeData.txt")
+var casefoldingURL = flag.String("casefolding", "", "full URL for CaseFolding.txt; defaults to --url/CaseFolding.txt")
+var url = flag.String("url",
+	"http://www.unicode.org/Public/7.0.0/ucd/",
+	"URL of Unicode database directory")
+var tablelist = flag.String("tables",
+	"all",
+	"comma-separated list of which tables to generate; can be letter")
+var scriptlist = flag.String("scripts",
+	"all",
+	"comma-separated list of which script tables to generate")
+var proplist = flag.String("props",
+	"all",
+	"comma-separated list of which property tables to generate")
+var cases = flag.Bool("cases",
+	true,
+	"generate case tables")
+var test = flag.Bool("test",
+	false,
+	"test existing tables; can be used to compare web data with package data")
+var localFiles = flag.Bool("local",
+	false,
+	"data files have been copied to current directory; for debugging only")
+var outputFile = flag.String("output",
+	"",
+	"output file for generated tables; default stdout")
+
+var scriptRe = regexp.MustCompile(`^([0-9A-F]+)(\.\.[0-9A-F]+)? *; ([A-Za-z_]+)$`)
+var logger = log.New(os.Stderr, "", log.Lshortfile)
+
+var output *bufio.Writer // points to os.Stdout or to "gofmt > outputFile"
+
+func setupOutput() {
+	output = bufio.NewWriter(startGofmt())
+}
+
+// startGofmt connects output to a gofmt process if -output is set.
+func startGofmt() io.Writer {
+	if *outputFile == "" {
+		return os.Stdout
+	}
+	stdout, err := os.Create(*outputFile)
+	if err != nil {
+		logger.Fatal(err)
+	}
+	// Pipe output to gofmt.
+	gofmt := exec.Command("gofmt")
+	fd, err := gofmt.StdinPipe()
+	if err != nil {
+		logger.Fatal(err)
+	}
+	gofmt.Stdout = stdout
+	gofmt.Stderr = os.Stderr
+	err = gofmt.Start()
+	if err != nil {
+		logger.Fatal(err)
+	}
+	return fd
+}
+
+func flushOutput() {
+	err := output.Flush()
+	if err != nil {
+		logger.Fatal(err)
+	}
+}
+
+func printf(format string, args ...interface{}) {
+	fmt.Fprintf(output, format, args...)
+}
+
+func print(args ...interface{}) {
+	fmt.Fprint(output, args...)
+}
+
+func println(args ...interface{}) {
+	fmt.Fprintln(output, args...)
+}
+
+type reader struct {
+	*bufio.Reader
+	fd   *os.File
+	resp *http.Response
+}
+
+func open(url string) *reader {
+	file := filepath.Base(url)
+	if *localFiles {
+		fd, err := os.Open(file)
+		if err != nil {
+			logger.Fatal(err)
+		}
+		return &reader{bufio.NewReader(fd), fd, nil}
+	}
+	resp, err := http.Get(url)
+	if err != nil {
+		logger.Fatal(err)
+	}
+	if resp.StatusCode != 200 {
+		logger.Fatalf("bad GET status for %s: %d", file, resp.Status)
+	}
+	return &reader{bufio.NewReader(resp.Body), nil, resp}
+
+}
+
+func (r *reader) close() {
+	if r.fd != nil {
+		r.fd.Close()
+	} else {
+		r.resp.Body.Close()
+	}
+}
+
+var category = map[string]bool{
+	// Nd Lu etc.
+	// We use one-character names to identify merged categories
+	"L": true, // Lu Ll Lt Lm Lo
+	"P": true, // Pc Pd Ps Pe Pu Pf Po
+	"M": true, // Mn Mc Me
+	"N": true, // Nd Nl No
+	"S": true, // Sm Sc Sk So
+	"Z": true, // Zs Zl Zp
+	"C": true, // Cc Cf Cs Co Cn
+}
+
+// UnicodeData.txt has form:
+//	0037;DIGIT SEVEN;Nd;0;EN;;7;7;7;N;;;;;
+//	007A;LATIN SMALL LETTER Z;Ll;0;L;;;;;N;;;005A;;005A
+// See http://www.unicode.org/reports/tr44/ for a full explanation
+// The fields:
+const (
+	FCodePoint = iota
+	FName
+	FGeneralCategory
+	FCanonicalCombiningClass
+	FBidiClass
+	FDecompositionTypeAndMapping
+	FNumericType
+	FNumericDigit // If a decimal digit.
+	FNumericValue // Includes non-decimal, e.g. U+2155=1/5
+	FBidiMirrored
+	FUnicode1Name
+	FISOComment
+	FSimpleUppercaseMapping
+	FSimpleLowercaseMapping
+	FSimpleTitlecaseMapping
+	NumField
+
+	MaxChar = 0x10FFFF // anything above this shouldn't exist
+)
+
+var fieldName = []string{
+	FCodePoint:                   "CodePoint",
+	FName:                        "Name",
+	FGeneralCategory:             "GeneralCategory",
+	FCanonicalCombiningClass:     "CanonicalCombiningClass",
+	FBidiClass:                   "BidiClass",
+	FDecompositionTypeAndMapping: "DecompositionTypeAndMapping",
+	FNumericType:                 "NumericType",
+	FNumericDigit:                "NumericDigit",
+	FNumericValue:                "NumericValue",
+	FBidiMirrored:                "BidiMirrored",
+	FUnicode1Name:                "Unicode1Name",
+	FISOComment:                  "ISOComment",
+	FSimpleUppercaseMapping:      "SimpleUppercaseMapping",
+	FSimpleLowercaseMapping:      "SimpleLowercaseMapping",
+	FSimpleTitlecaseMapping:      "SimpleTitlecaseMapping",
+}
+
+// This contains only the properties we're interested in.
+type Char struct {
+	field     []string // debugging only; could be deleted if we take out char.dump()
+	codePoint rune     // if zero, this index is not a valid code point.
+	category  string
+	upperCase rune
+	lowerCase rune
+	titleCase rune
+	foldCase  rune // simple case folding
+	caseOrbit rune // next in simple case folding orbit
+}
+
+// Scripts.txt has form:
+//	A673          ; Cyrillic # Po       SLAVONIC ASTERISK
+//	A67C..A67D    ; Cyrillic # Mn   [2] COMBINING CYRILLIC KAVYKA..COMBINING CYRILLIC PAYEROK
+// See http://www.unicode.org/Public/5.1.0/ucd/UCD.html for full explanation
+
+type Script struct {
+	lo, hi uint32 // range of code points
+	script string
+}
+
+var chars = make([]Char, MaxChar+1)
+var scripts = make(map[string][]Script)
+var props = make(map[string][]Script) // a property looks like a script; can share the format
+
+var lastChar rune = 0
+
+// In UnicodeData.txt, some ranges are marked like this:
+//	3400;<CJK Ideograph Extension A, First>;Lo;0;L;;;;;N;;;;;
+//	4DB5;<CJK Ideograph Extension A, Last>;Lo;0;L;;;;;N;;;;;
+// parseCategory returns a state variable indicating the weirdness.
+type State int
+
+const (
+	SNormal State = iota // known to be zero for the type
+	SFirst
+	SLast
+	SMissing
+)
+
+func parseCategory(line string) (state State) {
+	field := strings.Split(line, ";")
+	if len(field) != NumField {
+		logger.Fatalf("%5s: %d fields (expected %d)\n", line, len(field), NumField)
+	}
+	point, err := strconv.ParseUint(field[FCodePoint], 16, 64)
+	if err != nil {
+		logger.Fatalf("%.5s...: %s", line, err)
+	}
+	lastChar = rune(point)
+	if point == 0 {
+		return // not interesting and we use 0 as unset
+	}
+	if point > MaxChar {
+		return
+	}
+	char := &chars[point]
+	char.field = field
+	if char.codePoint != 0 {
+		logger.Fatalf("point %U reused", point)
+	}
+	char.codePoint = lastChar
+	char.category = field[FGeneralCategory]
+	category[char.category] = true
+	switch char.category {
+	case "Nd":
+		// Decimal digit
+		_, err := strconv.Atoi(field[FNumericValue])
+		if err != nil {
+			logger.Fatalf("%U: bad numeric field: %s", point, err)
+		}
+	case "Lu":
+		char.letter(field[FCodePoint], field[FSimpleLowercaseMapping], field[FSimpleTitlecaseMapping])
+	case "Ll":
+		char.letter(field[FSimpleUppercaseMapping], field[FCodePoint], field[FSimpleTitlecaseMapping])
+	case "Lt":
+		char.letter(field[FSimpleUppercaseMapping], field[FSimpleLowercaseMapping], field[FCodePoint])
+	default:
+		char.letter(field[FSimpleUppercaseMapping], field[FSimpleLowercaseMapping], field[FSimpleTitlecaseMapping])
+	}
+	switch {
+	case strings.Index(field[FName], ", First>") > 0:
+		state = SFirst
+	case strings.Index(field[FName], ", Last>") > 0:
+		state = SLast
+	}
+	return
+}
+
+func (char *Char) dump(s string) {
+	print(s, " ")
+	for i := 0; i < len(char.field); i++ {
+		printf("%s:%q ", fieldName[i], char.field[i])
+	}
+	print("\n")
+}
+
+func (char *Char) letter(u, l, t string) {
+	char.upperCase = char.letterValue(u, "U")
+	char.lowerCase = char.letterValue(l, "L")
+	char.titleCase = char.letterValue(t, "T")
+}
+
+func (char *Char) letterValue(s string, cas string) rune {
+	if s == "" {
+		return 0
+	}
+	v, err := strconv.ParseUint(s, 16, 64)
+	if err != nil {
+		char.dump(cas)
+		logger.Fatalf("%U: bad letter(%s): %s", char.codePoint, s, err)
+	}
+	return rune(v)
+}
+
+func allCategories() []string {
+	a := make([]string, 0, len(category))
+	for k := range category {
+		a = append(a, k)
+	}
+	sort.Strings(a)
+	return a
+}
+
+func all(scripts map[string][]Script) []string {
+	a := make([]string, 0, len(scripts))
+	for k := range scripts {
+		a = append(a, k)
+	}
+	sort.Strings(a)
+	return a
+}
+
+func allCatFold(m map[string]map[rune]bool) []string {
+	a := make([]string, 0, len(m))
+	for k := range m {
+		a = append(a, k)
+	}
+	sort.Strings(a)
+	return a
+}
+
+// Extract the version number from the URL
+func version() string {
+	// Break on slashes and look for the first numeric field
+	fields := strings.Split(*url, "/")
+	for _, f := range fields {
+		if len(f) > 0 && '0' <= f[0] && f[0] <= '9' {
+			return f
+		}
+	}
+	logger.Fatal("unknown version")
+	return "Unknown"
+}
+
+func categoryOp(code rune, class uint8) bool {
+	category := chars[code].category
+	return len(category) > 0 && category[0] == class
+}
+
+func loadChars() {
+	if *dataURL == "" {
+		flag.Set("data", *url+"UnicodeData.txt")
+	}
+	input := open(*dataURL)
+	defer input.close()
+	scanner := bufio.NewScanner(input)
+	var first rune = 0
+	for scanner.Scan() {
+		switch parseCategory(scanner.Text()) {
+		case SNormal:
+			if first != 0 {
+				logger.Fatalf("bad state normal at %U", lastChar)
+			}
+		case SFirst:
+			if first != 0 {
+				logger.Fatalf("bad state first at %U", lastChar)
+			}
+			first = lastChar
+		case SLast:
+			if first == 0 {
+				logger.Fatalf("bad state last at %U", lastChar)
+			}
+			for i := first + 1; i <= lastChar; i++ {
+				chars[i] = chars[first]
+				chars[i].codePoint = i
+			}
+			first = 0
+		}
+	}
+	if scanner.Err() != nil {
+		logger.Fatal(scanner.Err())
+	}
+}
+
+func loadCasefold() {
+	if *casefoldingURL == "" {
+		flag.Set("casefolding", *url+"CaseFolding.txt")
+	}
+	input := open(*casefoldingURL)
+	defer input.close()
+	scanner := bufio.NewScanner(input)
+	for scanner.Scan() {
+		line := scanner.Text()
+		if len(line) == 0 || line[0] == '#' || len(strings.TrimSpace(line)) == 0 {
+			continue
+		}
+		field := strings.Split(line, "; ")
+		if len(field) != 4 {
+			logger.Fatalf("CaseFolding.txt %.5s...: %d fields (expected %d)\n", line, len(field), 4)
+		}
+		kind := field[1]
+		if kind != "C" && kind != "S" {
+			// Only care about 'common' and 'simple' foldings.
+			continue
+		}
+		p1, err := strconv.ParseUint(field[0], 16, 64)
+		if err != nil {
+			logger.Fatalf("CaseFolding.txt %.5s...: %s", line, err)
+		}
+		p2, err := strconv.ParseUint(field[2], 16, 64)
+		if err != nil {
+			logger.Fatalf("CaseFolding.txt %.5s...: %s", line, err)
+		}
+		chars[p1].foldCase = rune(p2)
+	}
+	if scanner.Err() != nil {
+		logger.Fatal(scanner.Err())
+	}
+}
+
+const progHeader = `// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Generated by running
+//	maketables --tables=%s --data=%s --casefolding=%s
+// DO NOT EDIT
+
+package unicode
+
+`
+
+func printCategories() {
+	if *tablelist == "" {
+		return
+	}
+	// Find out which categories to dump
+	list := strings.Split(*tablelist, ",")
+	if *tablelist == "all" {
+		list = allCategories()
+	}
+	if *test {
+		fullCategoryTest(list)
+		return
+	}
+	printf(progHeader, *tablelist, *dataURL, *casefoldingURL)
+
+	println("// Version is the Unicode edition from which the tables are derived.")
+	printf("const Version = %q\n\n", version())
+
+	if *tablelist == "all" {
+		println("// Categories is the set of Unicode category tables.")
+		println("var Categories = map[string] *RangeTable {")
+		for _, k := range allCategories() {
+			printf("\t%q: %s,\n", k, k)
+		}
+		print("}\n\n")
+	}
+
+	decl := make(sort.StringSlice, len(list))
+	ndecl := 0
+	for _, name := range list {
+		if _, ok := category[name]; !ok {
+			logger.Fatal("unknown category", name)
+		}
+		// We generate an UpperCase name to serve as concise documentation and an _UnderScored
+		// name to store the data.  This stops godoc dumping all the tables but keeps them
+		// available to clients.
+		// Cases deserving special comments
+		varDecl := ""
+		switch name {
+		case "C":
+			varDecl = "\tOther = _C;	// Other/C is the set of Unicode control and special characters, category C.\n"
+			varDecl += "\tC = _C\n"
+		case "L":
+			varDecl = "\tLetter = _L;	// Letter/L is the set of Unicode letters, category L.\n"
+			varDecl += "\tL = _L\n"
+		case "M":
+			varDecl = "\tMark = _M;	// Mark/M is the set of Unicode mark characters, category M.\n"
+			varDecl += "\tM = _M\n"
+		case "N":
+			varDecl = "\tNumber = _N;	// Number/N is the set of Unicode number characters, category N.\n"
+			varDecl += "\tN = _N\n"
+		case "P":
+			varDecl = "\tPunct = _P;	// Punct/P is the set of Unicode punctuation characters, category P.\n"
+			varDecl += "\tP = _P\n"
+		case "S":
+			varDecl = "\tSymbol = _S;	// Symbol/S is the set of Unicode symbol characters, category S.\n"
+			varDecl += "\tS = _S\n"
+		case "Z":
+			varDecl = "\tSpace = _Z;	// Space/Z is the set of Unicode space characters, category Z.\n"
+			varDecl += "\tZ = _Z\n"
+		case "Nd":
+			varDecl = "\tDigit = _Nd;	// Digit is the set of Unicode characters with the \"decimal digit\" property.\n"
+		case "Lu":
+			varDecl = "\tUpper = _Lu;	// Upper is the set of Unicode upper case letters.\n"
+		case "Ll":
+			varDecl = "\tLower = _Ll;	// Lower is the set of Unicode lower case letters.\n"
+		case "Lt":
+			varDecl = "\tTitle = _Lt;	// Title is the set of Unicode title case letters.\n"
+		}
+		if len(name) > 1 {
+			varDecl += fmt.Sprintf(
+				"\t%s = _%s;	// %s is the set of Unicode characters in category %s.\n",
+				name, name, name, name)
+		}
+		decl[ndecl] = varDecl
+		ndecl++
+		if len(name) == 1 { // unified categories
+			decl := fmt.Sprintf("var _%s = &RangeTable{\n", name)
+			dumpRange(
+				decl,
+				func(code rune) bool { return categoryOp(code, name[0]) })
+			continue
+		}
+		dumpRange(
+			fmt.Sprintf("var _%s = &RangeTable{\n", name),
+			func(code rune) bool { return chars[code].category == name })
+	}
+	decl.Sort()
+	println("// These variables have type *RangeTable.")
+	println("var (")
+	for _, d := range decl {
+		print(d)
+	}
+	print(")\n\n")
+}
+
+type Op func(code rune) bool
+
+const format = "\t\t{0x%04x, 0x%04x, %d},\n"
+
+func dumpRange(header string, inCategory Op) {
+	print(header)
+	next := rune(0)
+	latinOffset := 0
+	print("\tR16: []Range16{\n")
+	// one Range for each iteration
+	count := &range16Count
+	size := 16
+	for {
+		// look for start of range
+		for next < rune(len(chars)) && !inCategory(next) {
+			next++
+		}
+		if next >= rune(len(chars)) {
+			// no characters remain
+			break
+		}
+
+		// start of range
+		lo := next
+		hi := next
+		stride := rune(1)
+		// accept lo
+		next++
+		// look for another character to set the stride
+		for next < rune(len(chars)) && !inCategory(next) {
+			next++
+		}
+		if next >= rune(len(chars)) {
+			// no more characters
+			printf(format, lo, hi, stride)
+			break
+		}
+		// set stride
+		stride = next - lo
+		// check for length of run. next points to first jump in stride
+		for i := next; i < rune(len(chars)); i++ {
+			if inCategory(i) == (((i - lo) % stride) == 0) {
+				// accept
+				if inCategory(i) {
+					hi = i
+				}
+			} else {
+				// no more characters in this run
+				break
+			}
+		}
+		if uint32(hi) <= unicode.MaxLatin1 {
+			latinOffset++
+		}
+		size, count = printRange(uint32(lo), uint32(hi), uint32(stride), size, count)
+		// next range: start looking where this range ends
+		next = hi + 1
+	}
+	print("\t},\n")
+	if latinOffset > 0 {
+		printf("\tLatinOffset: %d,\n", latinOffset)
+	}
+	print("}\n\n")
+}
+
+func printRange(lo, hi, stride uint32, size int, count *int) (int, *int) {
+	if size == 16 && hi >= 1<<16 {
+		if lo < 1<<16 {
+			if lo+stride != hi {
+				logger.Fatalf("unexpected straddle: %U %U %d", lo, hi, stride)
+			}
+			// No range contains U+FFFF as an instance, so split
+			// the range into two entries. That way we can maintain
+			// the invariant that R32 contains only >= 1<<16.
+			printf(format, lo, lo, 1)
+			lo = hi
+			stride = 1
+			*count++
+		}
+		print("\t},\n")
+		print("\tR32: []Range32{\n")
+		size = 32
+		count = &range32Count
+	}
+	printf(format, lo, hi, stride)
+	*count++
+	return size, count
+}
+
+func fullCategoryTest(list []string) {
+	for _, name := range list {
+		if _, ok := category[name]; !ok {
+			logger.Fatal("unknown category", name)
+		}
+		r, ok := unicode.Categories[name]
+		if !ok && len(name) > 1 {
+			logger.Fatalf("unknown table %q", name)
+		}
+		if len(name) == 1 {
+			verifyRange(name, func(code rune) bool { return categoryOp(code, name[0]) }, r)
+		} else {
+			verifyRange(
+				name,
+				func(code rune) bool { return chars[code].category == name },
+				r)
+		}
+	}
+}
+
+func verifyRange(name string, inCategory Op, table *unicode.RangeTable) {
+	count := 0
+	for j := range chars {
+		i := rune(j)
+		web := inCategory(i)
+		pkg := unicode.Is(table, i)
+		if web != pkg {
+			fmt.Fprintf(os.Stderr, "%s: %U: web=%t pkg=%t\n", name, i, web, pkg)
+			count++
+			if count > 10 {
+				break
+			}
+		}
+	}
+}
+
+func parseScript(line string, scripts map[string][]Script) {
+	comment := strings.Index(line, "#")
+	if comment >= 0 {
+		line = line[0:comment]
+	}
+	line = strings.TrimSpace(line)
+	if len(line) == 0 {
+		return
+	}
+	field := strings.Split(line, ";")
+	if len(field) != 2 {
+		logger.Fatalf("%s: %d fields (expected 2)\n", line, len(field))
+	}
+	matches := scriptRe.FindStringSubmatch(line)
+	if len(matches) != 4 {
+		logger.Fatalf("%s: %d matches (expected 3)\n", line, len(matches))
+	}
+	lo, err := strconv.ParseUint(matches[1], 16, 64)
+	if err != nil {
+		logger.Fatalf("%.5s...: %s", line, err)
+	}
+	hi := lo
+	if len(matches[2]) > 2 { // ignore leading ..
+		hi, err = strconv.ParseUint(matches[2][2:], 16, 64)
+		if err != nil {
+			logger.Fatalf("%.5s...: %s", line, err)
+		}
+	}
+	name := matches[3]
+	scripts[name] = append(scripts[name], Script{uint32(lo), uint32(hi), name})
+}
+
+// The script tables have a lot of adjacent elements. Fold them together.
+func foldAdjacent(r []Script) []unicode.Range32 {
+	s := make([]unicode.Range32, 0, len(r))
+	j := 0
+	for i := 0; i < len(r); i++ {
+		if j > 0 && r[i].lo == s[j-1].Hi+1 {
+			s[j-1].Hi = r[i].hi
+		} else {
+			s = s[0 : j+1]
+			s[j] = unicode.Range32{
+				Lo:     uint32(r[i].lo),
+				Hi:     uint32(r[i].hi),
+				Stride: 1,
+			}
+			j++
+		}
+	}
+	return s
+}
+
+func fullScriptTest(list []string, installed map[string]*unicode.RangeTable, scripts map[string][]Script) {
+	for _, name := range list {
+		if _, ok := scripts[name]; !ok {
+			logger.Fatal("unknown script", name)
+		}
+		_, ok := installed[name]
+		if !ok {
+			logger.Fatal("unknown table", name)
+		}
+		for _, script := range scripts[name] {
+			for r := script.lo; r <= script.hi; r++ {
+				if !unicode.Is(installed[name], rune(r)) {
+					fmt.Fprintf(os.Stderr, "%U: not in script %s\n", r, name)
+				}
+			}
+		}
+	}
+}
+
+// PropList.txt has the same format as Scripts.txt so we can share its parser.
+func printScriptOrProperty(doProps bool) {
+	flag := "scripts"
+	flaglist := *scriptlist
+	file := "Scripts.txt"
+	table := scripts
+	installed := unicode.Scripts
+	if doProps {
+		flag = "props"
+		flaglist = *proplist
+		file = "PropList.txt"
+		table = props
+		installed = unicode.Properties
+	}
+	if flaglist == "" {
+		return
+	}
+	input := open(*url + file)
+	scanner := bufio.NewScanner(input)
+	for scanner.Scan() {
+		parseScript(scanner.Text(), table)
+	}
+	if scanner.Err() != nil {
+		logger.Fatal(scanner.Err())
+	}
+	input.close()
+
+	// Find out which scripts to dump
+	list := strings.Split(flaglist, ",")
+	if flaglist == "all" {
+		list = all(table)
+	}
+	if *test {
+		fullScriptTest(list, installed, table)
+		return
+	}
+
+	printf(
+		"// Generated by running\n"+
+			"//	maketables --%s=%s --url=%s\n"+
+			"// DO NOT EDIT\n\n",
+		flag,
+		flaglist,
+		*url)
+	if flaglist == "all" {
+		if doProps {
+			println("// Properties is the set of Unicode property tables.")
+			println("var Properties = map[string] *RangeTable{")
+		} else {
+			println("// Scripts is the set of Unicode script tables.")
+			println("var Scripts = map[string] *RangeTable{")
+		}
+		for _, k := range all(table) {
+			printf("\t%q: %s,\n", k, k)
+		}
+		print("}\n\n")
+	}
+
+	decl := make(sort.StringSlice, len(list))
+	ndecl := 0
+	for _, name := range list {
+		if doProps {
+			decl[ndecl] = fmt.Sprintf(
+				"\t%s = _%s;\t// %s is the set of Unicode characters with property %s.\n",
+				name, name, name, name)
+		} else {
+			decl[ndecl] = fmt.Sprintf(
+				"\t%s = _%s;\t// %s is the set of Unicode characters in script %s.\n",
+				name, name, name, name)
+		}
+		ndecl++
+		printf("var _%s = &RangeTable {\n", name)
+		ranges := foldAdjacent(table[name])
+		print("\tR16: []Range16{\n")
+		size := 16
+		count := &range16Count
+		for _, s := range ranges {
+			size, count = printRange(s.Lo, s.Hi, s.Stride, size, count)
+		}
+		print("\t},\n")
+		if off := findLatinOffset(ranges); off > 0 {
+			printf("\tLatinOffset: %d,\n", off)
+		}
+		print("}\n\n")
+	}
+	decl.Sort()
+	println("// These variables have type *RangeTable.")
+	println("var (")
+	for _, d := range decl {
+		print(d)
+	}
+	print(")\n\n")
+}
+
+func findLatinOffset(ranges []unicode.Range32) int {
+	i := 0
+	for i < len(ranges) && ranges[i].Hi <= unicode.MaxLatin1 {
+		i++
+	}
+	return i
+}
+
+const (
+	CaseUpper = 1 << iota
+	CaseLower
+	CaseTitle
+	CaseNone    = 0  // must be zero
+	CaseMissing = -1 // character not present; not a valid case state
+)
+
+type caseState struct {
+	point        rune
+	_case        int
+	deltaToUpper rune
+	deltaToLower rune
+	deltaToTitle rune
+}
+
+// Is d a continuation of the state of c?
+func (c *caseState) adjacent(d *caseState) bool {
+	if d.point < c.point {
+		c, d = d, c
+	}
+	switch {
+	case d.point != c.point+1: // code points not adjacent (shouldn't happen)
+		return false
+	case d._case != c._case: // different cases
+		return c.upperLowerAdjacent(d)
+	case c._case == CaseNone:
+		return false
+	case c._case == CaseMissing:
+		return false
+	case d.deltaToUpper != c.deltaToUpper:
+		return false
+	case d.deltaToLower != c.deltaToLower:
+		return false
+	case d.deltaToTitle != c.deltaToTitle:
+		return false
+	}
+	return true
+}
+
+// Is d the same as c, but opposite in upper/lower case? this would make it
+// an element of an UpperLower sequence.
+func (c *caseState) upperLowerAdjacent(d *caseState) bool {
+	// check they're a matched case pair.  we know they have adjacent values
+	switch {
+	case c._case == CaseUpper && d._case != CaseLower:
+		return false
+	case c._case == CaseLower && d._case != CaseUpper:
+		return false
+	}
+	// matched pair (at least in upper/lower).  make the order Upper Lower
+	if c._case == CaseLower {
+		c, d = d, c
+	}
+	// for an Upper Lower sequence the deltas have to be in order
+	//	c: 0 1 0
+	//	d: -1 0 -1
+	switch {
+	case c.deltaToUpper != 0:
+		return false
+	case c.deltaToLower != 1:
+		return false
+	case c.deltaToTitle != 0:
+		return false
+	case d.deltaToUpper != -1:
+		return false
+	case d.deltaToLower != 0:
+		return false
+	case d.deltaToTitle != -1:
+		return false
+	}
+	return true
+}
+
+// Does this character start an UpperLower sequence?
+func (c *caseState) isUpperLower() bool {
+	// for an Upper Lower sequence the deltas have to be in order
+	//	c: 0 1 0
+	switch {
+	case c.deltaToUpper != 0:
+		return false
+	case c.deltaToLower != 1:
+		return false
+	case c.deltaToTitle != 0:
+		return false
+	}
+	return true
+}
+
+// Does this character start a LowerUpper sequence?
+func (c *caseState) isLowerUpper() bool {
+	// for an Upper Lower sequence the deltas have to be in order
+	//	c: -1 0 -1
+	switch {
+	case c.deltaToUpper != -1:
+		return false
+	case c.deltaToLower != 0:
+		return false
+	case c.deltaToTitle != -1:
+		return false
+	}
+	return true
+}
+
+func getCaseState(i rune) (c *caseState) {
+	c = &caseState{point: i, _case: CaseNone}
+	ch := &chars[i]
+	switch ch.codePoint {
+	case 0:
+		c._case = CaseMissing // Will get NUL wrong but that doesn't matter
+		return
+	case ch.upperCase:
+		c._case = CaseUpper
+	case ch.lowerCase:
+		c._case = CaseLower
+	case ch.titleCase:
+		c._case = CaseTitle
+	}
+	// Some things such as roman numeral U+2161 don't describe themselves
+	// as upper case, but have a lower case.  Second-guess them.
+	if c._case == CaseNone && ch.lowerCase != 0 {
+		c._case = CaseUpper
+	}
+	// Same in the other direction.
+	if c._case == CaseNone && ch.upperCase != 0 {
+		c._case = CaseLower
+	}
+
+	if ch.upperCase != 0 {
+		c.deltaToUpper = ch.upperCase - i
+	}
+	if ch.lowerCase != 0 {
+		c.deltaToLower = ch.lowerCase - i
+	}
+	if ch.titleCase != 0 {
+		c.deltaToTitle = ch.titleCase - i
+	}
+	return
+}
+
+func printCases() {
+	if !*cases {
+		return
+	}
+	if *test {
+		fullCaseTest()
+		return
+	}
+	printf(
+		"// Generated by running\n"+
+			"//	maketables --data=%s --casefolding=%s\n"+
+			"// DO NOT EDIT\n\n"+
+			"// CaseRanges is the table describing case mappings for all letters with\n"+
+			"// non-self mappings.\n"+
+			"var CaseRanges = _CaseRanges\n"+
+			"var _CaseRanges = []CaseRange {\n",
+		*dataURL, *casefoldingURL)
+
+	var startState *caseState    // the start of a run; nil for not active
+	var prevState = &caseState{} // the state of the previous character
+	for i := range chars {
+		state := getCaseState(rune(i))
+		if state.adjacent(prevState) {
+			prevState = state
+			continue
+		}
+		// end of run (possibly)
+		printCaseRange(startState, prevState)
+		startState = nil
+		if state._case != CaseMissing && state._case != CaseNone {
+			startState = state
+		}
+		prevState = state
+	}
+	print("}\n")
+}
+
+func printCaseRange(lo, hi *caseState) {
+	if lo == nil {
+		return
+	}
+	if lo.deltaToUpper == 0 && lo.deltaToLower == 0 && lo.deltaToTitle == 0 {
+		// character represents itself in all cases - no need to mention it
+		return
+	}
+	switch {
+	case hi.point > lo.point && lo.isUpperLower():
+		printf("\t{0x%04X, 0x%04X, d{UpperLower, UpperLower, UpperLower}},\n",
+			lo.point, hi.point)
+	case hi.point > lo.point && lo.isLowerUpper():
+		logger.Fatalf("LowerUpper sequence: should not happen: %U.  If it's real, need to fix To()", lo.point)
+		printf("\t{0x%04X, 0x%04X, d{LowerUpper, LowerUpper, LowerUpper}},\n",
+			lo.point, hi.point)
+	default:
+		printf("\t{0x%04X, 0x%04X, d{%d, %d, %d}},\n",
+			lo.point, hi.point,
+			lo.deltaToUpper, lo.deltaToLower, lo.deltaToTitle)
+	}
+}
+
+// If the cased value in the Char is 0, it means use the rune itself.
+func caseIt(r, cased rune) rune {
+	if cased == 0 {
+		return r
+	}
+	return cased
+}
+
+func fullCaseTest() {
+	for j, c := range chars {
+		i := rune(j)
+		lower := unicode.ToLower(i)
+		want := caseIt(i, c.lowerCase)
+		if lower != want {
+			fmt.Fprintf(os.Stderr, "lower %U should be %U is %U\n", i, want, lower)
+		}
+		upper := unicode.ToUpper(i)
+		want = caseIt(i, c.upperCase)
+		if upper != want {
+			fmt.Fprintf(os.Stderr, "upper %U should be %U is %U\n", i, want, upper)
+		}
+		title := unicode.ToTitle(i)
+		want = caseIt(i, c.titleCase)
+		if title != want {
+			fmt.Fprintf(os.Stderr, "title %U should be %U is %U\n", i, want, title)
+		}
+	}
+}
+
+func printLatinProperties() {
+	if *test {
+		return
+	}
+	println("var properties = [MaxLatin1+1]uint8{")
+	for code := 0; code <= unicode.MaxLatin1; code++ {
+		var property string
+		switch chars[code].category {
+		case "Cc", "": // NUL has no category.
+			property = "pC"
+		case "Cf": // soft hyphen, unique category, not printable.
+			property = "0"
+		case "Ll":
+			property = "pLl | pp"
+		case "Lo":
+			property = "pLo | pp"
+		case "Lu":
+			property = "pLu | pp"
+		case "Nd", "No":
+			property = "pN | pp"
+		case "Pc", "Pd", "Pe", "Pf", "Pi", "Po", "Ps":
+			property = "pP | pp"
+		case "Sc", "Sk", "Sm", "So":
+			property = "pS | pp"
+		case "Zs":
+			property = "pZ"
+		default:
+			logger.Fatalf("%U has unknown category %q", code, chars[code].category)
+		}
+		// Special case
+		if code == ' ' {
+			property = "pZ | pp"
+		}
+		printf("\t0x%02X: %s, // %q\n", code, property, code)
+	}
+	printf("}\n\n")
+}
+
+type runeSlice []rune
+
+func (p runeSlice) Len() int           { return len(p) }
+func (p runeSlice) Less(i, j int) bool { return p[i] < p[j] }
+func (p runeSlice) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
+
+func printCasefold() {
+	// Build list of case-folding groups attached to each canonical folded char (typically lower case).
+	var caseOrbit = make([][]rune, MaxChar+1)
+	for j := range chars {
+		i := rune(j)
+		c := &chars[i]
+		if c.foldCase == 0 {
+			continue
+		}
+		orb := caseOrbit[c.foldCase]
+		if orb == nil {
+			orb = append(orb, c.foldCase)
+		}
+		caseOrbit[c.foldCase] = append(orb, i)
+	}
+
+	// Insert explicit 1-element groups when assuming [lower, upper] would be wrong.
+	for j := range chars {
+		i := rune(j)
+		c := &chars[i]
+		f := c.foldCase
+		if f == 0 {
+			f = i
+		}
+		orb := caseOrbit[f]
+		if orb == nil && (c.upperCase != 0 && c.upperCase != i || c.lowerCase != 0 && c.lowerCase != i) {
+			// Default assumption of [upper, lower] is wrong.
+			caseOrbit[i] = []rune{i}
+		}
+	}
+
+	// Delete the groups for which assuming [lower, upper] is right.
+	for i, orb := range caseOrbit {
+		if len(orb) == 2 && chars[orb[0]].upperCase == orb[1] && chars[orb[1]].lowerCase == orb[0] {
+			caseOrbit[i] = nil
+		}
+	}
+
+	// Record orbit information in chars.
+	for _, orb := range caseOrbit {
+		if orb == nil {
+			continue
+		}
+		sort.Sort(runeSlice(orb))
+		c := orb[len(orb)-1]
+		for _, d := range orb {
+			chars[c].caseOrbit = d
+			c = d
+		}
+	}
+
+	printCaseOrbit()
+
+	// Tables of category and script folding exceptions: code points
+	// that must be added when interpreting a particular category/script
+	// in a case-folding context.
+	cat := make(map[string]map[rune]bool)
+	for name := range category {
+		if x := foldExceptions(inCategory(name)); len(x) > 0 {
+			cat[name] = x
+		}
+	}
+
+	scr := make(map[string]map[rune]bool)
+	for name := range scripts {
+		if x := foldExceptions(inScript(name)); len(x) > 0 {
+			cat[name] = x
+		}
+	}
+
+	printCatFold("FoldCategory", cat)
+	printCatFold("FoldScript", scr)
+}
+
+// inCategory returns a list of all the runes in the category.
+func inCategory(name string) []rune {
+	var x []rune
+	for j := range chars {
+		i := rune(j)
+		c := &chars[i]
+		if c.category == name || len(name) == 1 && len(c.category) > 1 && c.category[0] == name[0] {
+			x = append(x, i)
+		}
+	}
+	return x
+}
+
+// inScript returns a list of all the runes in the script.
+func inScript(name string) []rune {
+	var x []rune
+	for _, s := range scripts[name] {
+		for c := s.lo; c <= s.hi; c++ {
+			x = append(x, rune(c))
+		}
+	}
+	return x
+}
+
+// foldExceptions returns a list of all the runes fold-equivalent
+// to runes in class but not in class themselves.
+func foldExceptions(class []rune) map[rune]bool {
+	// Create map containing class and all fold-equivalent chars.
+	m := make(map[rune]bool)
+	for _, r := range class {
+		c := &chars[r]
+		if c.caseOrbit == 0 {
+			// Just upper and lower.
+			if u := c.upperCase; u != 0 {
+				m[u] = true
+			}
+			if l := c.lowerCase; l != 0 {
+				m[l] = true
+			}
+			m[r] = true
+			continue
+		}
+		// Otherwise walk orbit.
+		r0 := r
+		for {
+			m[r] = true
+			r = chars[r].caseOrbit
+			if r == r0 {
+				break
+			}
+		}
+	}
+
+	// Remove class itself.
+	for _, r := range class {
+		delete(m, r)
+	}
+
+	// What's left is the exceptions.
+	return m
+}
+
+var comment = map[string]string{
+	"FoldCategory": "// FoldCategory maps a category name to a table of\n" +
+		"// code points outside the category that are equivalent under\n" +
+		"// simple case folding to code points inside the category.\n" +
+		"// If there is no entry for a category name, there are no such points.\n",
+
+	"FoldScript": "// FoldScript maps a script name to a table of\n" +
+		"// code points outside the script that are equivalent under\n" +
+		"// simple case folding to code points inside the script.\n" +
+		"// If there is no entry for a script name, there are no such points.\n",
+}
+
+func printCaseOrbit() {
+	if *test {
+		for j := range chars {
+			i := rune(j)
+			c := &chars[i]
+			f := c.caseOrbit
+			if f == 0 {
+				if c.lowerCase != i && c.lowerCase != 0 {
+					f = c.lowerCase
+				} else if c.upperCase != i && c.upperCase != 0 {
+					f = c.upperCase
+				} else {
+					f = i
+				}
+			}
+			if g := unicode.SimpleFold(i); g != f {
+				fmt.Fprintf(os.Stderr, "unicode.SimpleFold(%#U) = %#U, want %#U\n", i, g, f)
+			}
+		}
+		return
+	}
+
+	printf("var caseOrbit = []foldPair{\n")
+	for i := range chars {
+		c := &chars[i]
+		if c.caseOrbit != 0 {
+			printf("\t{0x%04X, 0x%04X},\n", i, c.caseOrbit)
+			foldPairCount++
+		}
+	}
+	printf("}\n\n")
+}
+
+func printCatFold(name string, m map[string]map[rune]bool) {
+	if *test {
+		var pkgMap map[string]*unicode.RangeTable
+		if name == "FoldCategory" {
+			pkgMap = unicode.FoldCategory
+		} else {
+			pkgMap = unicode.FoldScript
+		}
+		if len(pkgMap) != len(m) {
+			fmt.Fprintf(os.Stderr, "unicode.%s has %d elements, want %d\n", name, len(pkgMap), len(m))
+			return
+		}
+		for k, v := range m {
+			t, ok := pkgMap[k]
+			if !ok {
+				fmt.Fprintf(os.Stderr, "unicode.%s[%q] missing\n", name, k)
+				continue
+			}
+			n := 0
+			for _, r := range t.R16 {
+				for c := rune(r.Lo); c <= rune(r.Hi); c += rune(r.Stride) {
+					if !v[c] {
+						fmt.Fprintf(os.Stderr, "unicode.%s[%q] contains %#U, should not\n", name, k, c)
+					}
+					n++
+				}
+			}
+			for _, r := range t.R32 {
+				for c := rune(r.Lo); c <= rune(r.Hi); c += rune(r.Stride) {
+					if !v[c] {
+						fmt.Fprintf(os.Stderr, "unicode.%s[%q] contains %#U, should not\n", name, k, c)
+					}
+					n++
+				}
+			}
+			if n != len(v) {
+				fmt.Fprintf(os.Stderr, "unicode.%s[%q] has %d code points, want %d\n", name, k, n, len(v))
+			}
+		}
+		return
+	}
+
+	print(comment[name])
+	printf("var %s = map[string]*RangeTable{\n", name)
+	for _, name := range allCatFold(m) {
+		printf("\t%q: fold%s,\n", name, name)
+	}
+	printf("}\n\n")
+	for _, name := range allCatFold(m) {
+		class := m[name]
+		dumpRange(
+			fmt.Sprintf("var fold%s = &RangeTable{\n", name),
+			func(code rune) bool { return class[code] })
+	}
+}
+
+var range16Count = 0  // Number of entries in the 16-bit range tables.
+var range32Count = 0  // Number of entries in the 32-bit range tables.
+var foldPairCount = 0 // Number of fold pairs in the exception tables.
+
+func printSizes() {
+	if *test {
+		return
+	}
+	println()
+	printf("// Range entries: %d 16-bit, %d 32-bit, %d total.\n", range16Count, range32Count, range16Count+range32Count)
+	range16Bytes := range16Count * 3 * 2
+	range32Bytes := range32Count * 3 * 4
+	printf("// Range bytes: %d 16-bit, %d 32-bit, %d total.\n", range16Bytes, range32Bytes, range16Bytes+range32Bytes)
+	println()
+	printf("// Fold orbit bytes: %d pairs, %d bytes\n", foldPairCount, foldPairCount*2*2)
+}
diff --git a/src/unicode/script_test.go b/src/unicode/script_test.go
new file mode 100644
index 0000000..795cb4e
--- /dev/null
+++ b/src/unicode/script_test.go
@@ -0,0 +1,287 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package unicode_test
+
+import (
+	"testing"
+	. "unicode"
+)
+
+type T struct {
+	rune   rune
+	script string
+}
+
+// Hand-chosen tests from Unicode 5.1.0, 6.0.0, 6.2.0, 6.3.0 and 7.0.0 mostly to
+// discover when new scripts and categories arise.
+var inTest = []T{
+	{0x06e2, "Arabic"},
+	{0x0567, "Armenian"},
+	{0x10b20, "Avestan"},
+	{0x1b37, "Balinese"},
+	{0xa6af, "Bamum"},
+	{0x16ada, "Bassa_Vah"},
+	{0x1be1, "Batak"},
+	{0x09c2, "Bengali"},
+	{0x3115, "Bopomofo"},
+	{0x282d, "Braille"},
+	{0x1a1a, "Buginese"},
+	{0x1747, "Buhid"},
+	{0x11011, "Brahmi"},
+	{0x156d, "Canadian_Aboriginal"},
+	{0x102a9, "Carian"},
+	{0x10563, "Caucasian_Albanian"},
+	{0x11111, "Chakma"},
+	{0xaa4d, "Cham"},
+	{0x13c2, "Cherokee"},
+	{0x0020, "Common"},
+	{0x1d4a5, "Common"},
+	{0x2cfc, "Coptic"},
+	{0x12420, "Cuneiform"},
+	{0x1080c, "Cypriot"},
+	{0xa663, "Cyrillic"},
+	{0x10430, "Deseret"},
+	{0x094a, "Devanagari"},
+	{0x1BC00, "Duployan"},
+	{0x13001, "Egyptian_Hieroglyphs"},
+	{0x10500, "Elbasan"},
+	{0x1271, "Ethiopic"},
+	{0x10fc, "Georgian"},
+	{0x2c40, "Glagolitic"},
+	{0x10347, "Gothic"},
+	{0x11303, "Grantha"},
+	{0x03ae, "Greek"},
+	{0x0abf, "Gujarati"},
+	{0x0a24, "Gurmukhi"},
+	{0x3028, "Han"},
+	{0x11b8, "Hangul"},
+	{0x1727, "Hanunoo"},
+	{0x05a0, "Hebrew"},
+	{0x3058, "Hiragana"},
+	{0x10841, "Imperial_Aramaic"},
+	{0x20e6, "Inherited"},
+	{0x10b70, "Inscriptional_Pahlavi"},
+	{0x10b5a, "Inscriptional_Parthian"},
+	{0xa9d0, "Javanese"},
+	{0x1109f, "Kaithi"},
+	{0x0cbd, "Kannada"},
+	{0x30a6, "Katakana"},
+	{0xa928, "Kayah_Li"},
+	{0x10a11, "Kharoshthi"},
+	{0x17c6, "Khmer"},
+	{0x11211, "Khojki"},
+	{0x112df, "Khudawadi"},
+	{0x0eaa, "Lao"},
+	{0x1d79, "Latin"},
+	{0x1c10, "Lepcha"},
+	{0x1930, "Limbu"},
+	{0x10755, "Linear_A"},
+	{0x1003c, "Linear_B"},
+	{0xa4e1, "Lisu"},
+	{0x10290, "Lycian"},
+	{0x10930, "Lydian"},
+	{0x11173, "Mahajani"},
+	{0x0d42, "Malayalam"},
+	{0x0843, "Mandaic"},
+	{0x10ac8, "Manichaean"},
+	{0xabd0, "Meetei_Mayek"},
+	{0x1e800, "Mende_Kikakui"},
+	{0x1099f, "Meroitic_Hieroglyphs"},
+	{0x109a0, "Meroitic_Cursive"},
+	{0x16f00, "Miao"},
+	{0x11611, "Modi"},
+	{0x1822, "Mongolian"},
+	{0x16a60, "Mro"},
+	{0x104c, "Myanmar"},
+	{0x10880, "Nabataean"},
+	{0x19c3, "New_Tai_Lue"},
+	{0x07f8, "Nko"},
+	{0x169b, "Ogham"},
+	{0x1c6a, "Ol_Chiki"},
+	{0x10310, "Old_Italic"},
+	{0x10a80, "Old_North_Arabian"},
+	{0x10350, "Old_Permic"},
+	{0x103c9, "Old_Persian"},
+	{0x10a6f, "Old_South_Arabian"},
+	{0x10c20, "Old_Turkic"},
+	{0x0b3e, "Oriya"},
+	{0x10491, "Osmanya"},
+	{0x16b2b, "Pahawh_Hmong"},
+	{0x10876, "Palmyrene"},
+	{0x11ACE, "Pau_Cin_Hau"},
+	{0xa860, "Phags_Pa"},
+	{0x10918, "Phoenician"},
+	{0x10baf, "Psalter_Pahlavi"},
+	{0xa949, "Rejang"},
+	{0x16c0, "Runic"},
+	{0x081d, "Samaritan"},
+	{0xa892, "Saurashtra"},
+	{0x111a0, "Sharada"},
+	{0x10463, "Shavian"},
+	{0x115c1, "Siddham"},
+	{0x0dbd, "Sinhala"},
+	{0x110d0, "Sora_Sompeng"},
+	{0x1ba3, "Sundanese"},
+	{0xa803, "Syloti_Nagri"},
+	{0x070f, "Syriac"},
+	{0x170f, "Tagalog"},
+	{0x176f, "Tagbanwa"},
+	{0x1972, "Tai_Le"},
+	{0x1a62, "Tai_Tham"},
+	{0xaadc, "Tai_Viet"},
+	{0x116c9, "Takri"},
+	{0x0bbf, "Tamil"},
+	{0x0c55, "Telugu"},
+	{0x07a7, "Thaana"},
+	{0x0e46, "Thai"},
+	{0x0f36, "Tibetan"},
+	{0x2d55, "Tifinagh"},
+	{0x114d9, "Tirhuta"},
+	{0x10388, "Ugaritic"},
+	{0xa60e, "Vai"},
+	{0x118ff, "Warang_Citi"},
+	{0xa216, "Yi"},
+}
+
+var outTest = []T{ // not really worth being thorough
+	{0x20, "Telugu"},
+}
+
+var inCategoryTest = []T{
+	{0x0081, "Cc"},
+	{0x200B, "Cf"},
+	{0xf0000, "Co"},
+	{0xdb80, "Cs"},
+	{0x0236, "Ll"},
+	{0x1d9d, "Lm"},
+	{0x07cf, "Lo"},
+	{0x1f8a, "Lt"},
+	{0x03ff, "Lu"},
+	{0x0bc1, "Mc"},
+	{0x20df, "Me"},
+	{0x07f0, "Mn"},
+	{0x1bb2, "Nd"},
+	{0x10147, "Nl"},
+	{0x2478, "No"},
+	{0xfe33, "Pc"},
+	{0x2011, "Pd"},
+	{0x301e, "Pe"},
+	{0x2e03, "Pf"},
+	{0x2e02, "Pi"},
+	{0x0022, "Po"},
+	{0x2770, "Ps"},
+	{0x00a4, "Sc"},
+	{0xa711, "Sk"},
+	{0x25f9, "Sm"},
+	{0x2108, "So"},
+	{0x2028, "Zl"},
+	{0x2029, "Zp"},
+	{0x202f, "Zs"},
+	// Unifieds.
+	{0x04aa, "L"},
+	{0x0009, "C"},
+	{0x1712, "M"},
+	{0x0031, "N"},
+	{0x00bb, "P"},
+	{0x00a2, "S"},
+	{0x00a0, "Z"},
+}
+
+var inPropTest = []T{
+	{0x0046, "ASCII_Hex_Digit"},
+	{0x200F, "Bidi_Control"},
+	{0x2212, "Dash"},
+	{0xE0001, "Deprecated"},
+	{0x00B7, "Diacritic"},
+	{0x30FE, "Extender"},
+	{0xFF46, "Hex_Digit"},
+	{0x2E17, "Hyphen"},
+	{0x2FFB, "IDS_Binary_Operator"},
+	{0x2FF3, "IDS_Trinary_Operator"},
+	{0xFA6A, "Ideographic"},
+	{0x200D, "Join_Control"},
+	{0x0EC4, "Logical_Order_Exception"},
+	{0x2FFFF, "Noncharacter_Code_Point"},
+	{0x065E, "Other_Alphabetic"},
+	{0x2065, "Other_Default_Ignorable_Code_Point"},
+	{0x0BD7, "Other_Grapheme_Extend"},
+	{0x0387, "Other_ID_Continue"},
+	{0x212E, "Other_ID_Start"},
+	{0x2094, "Other_Lowercase"},
+	{0x2040, "Other_Math"},
+	{0x216F, "Other_Uppercase"},
+	{0x0027, "Pattern_Syntax"},
+	{0x0020, "Pattern_White_Space"},
+	{0x300D, "Quotation_Mark"},
+	{0x2EF3, "Radical"},
+	{0x061F, "STerm"},
+	{0x2071, "Soft_Dotted"},
+	{0x003A, "Terminal_Punctuation"},
+	{0x9FC3, "Unified_Ideograph"},
+	{0xFE0F, "Variation_Selector"},
+	{0x0020, "White_Space"},
+}
+
+func TestScripts(t *testing.T) {
+	notTested := make(map[string]bool)
+	for k := range Scripts {
+		notTested[k] = true
+	}
+	for _, test := range inTest {
+		if _, ok := Scripts[test.script]; !ok {
+			t.Fatal(test.script, "not a known script")
+		}
+		if !Is(Scripts[test.script], test.rune) {
+			t.Errorf("IsScript(%U, %s) = false, want true", test.rune, test.script)
+		}
+		delete(notTested, test.script)
+	}
+	for _, test := range outTest {
+		if Is(Scripts[test.script], test.rune) {
+			t.Errorf("IsScript(%U, %s) = true, want false", test.rune, test.script)
+		}
+	}
+	for k := range notTested {
+		t.Error("script not tested:", k)
+	}
+}
+
+func TestCategories(t *testing.T) {
+	notTested := make(map[string]bool)
+	for k := range Categories {
+		notTested[k] = true
+	}
+	for _, test := range inCategoryTest {
+		if _, ok := Categories[test.script]; !ok {
+			t.Fatal(test.script, "not a known category")
+		}
+		if !Is(Categories[test.script], test.rune) {
+			t.Errorf("IsCategory(%U, %s) = false, want true", test.rune, test.script)
+		}
+		delete(notTested, test.script)
+	}
+	for k := range notTested {
+		t.Error("category not tested:", k)
+	}
+}
+
+func TestProperties(t *testing.T) {
+	notTested := make(map[string]bool)
+	for k := range Properties {
+		notTested[k] = true
+	}
+	for _, test := range inPropTest {
+		if _, ok := Properties[test.script]; !ok {
+			t.Fatal(test.script, "not a known prop")
+		}
+		if !Is(Properties[test.script], test.rune) {
+			t.Errorf("IsCategory(%U, %s) = false, want true", test.rune, test.script)
+		}
+		delete(notTested, test.script)
+	}
+	for k := range notTested {
+		t.Error("property not tested:", k)
+	}
+}
diff --git a/src/unicode/tables.go b/src/unicode/tables.go
new file mode 100644
index 0000000..8b77dd6
--- /dev/null
+++ b/src/unicode/tables.go
@@ -0,0 +1,7029 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Generated by running
+//	maketables --tables=all --data=http://www.unicode.org/Public/7.0.0/ucd/UnicodeData.txt --casefolding=http://www.unicode.org/Public/7.0.0/ucd/CaseFolding.txt
+// DO NOT EDIT
+
+package unicode
+
+// Version is the Unicode edition from which the tables are derived.
+const Version = "7.0.0"
+
+// Categories is the set of Unicode category tables.
+var Categories = map[string]*RangeTable{
+	"C":  C,
+	"Cc": Cc,
+	"Cf": Cf,
+	"Co": Co,
+	"Cs": Cs,
+	"L":  L,
+	"Ll": Ll,
+	"Lm": Lm,
+	"Lo": Lo,
+	"Lt": Lt,
+	"Lu": Lu,
+	"M":  M,
+	"Mc": Mc,
+	"Me": Me,
+	"Mn": Mn,
+	"N":  N,
+	"Nd": Nd,
+	"Nl": Nl,
+	"No": No,
+	"P":  P,
+	"Pc": Pc,
+	"Pd": Pd,
+	"Pe": Pe,
+	"Pf": Pf,
+	"Pi": Pi,
+	"Po": Po,
+	"Ps": Ps,
+	"S":  S,
+	"Sc": Sc,
+	"Sk": Sk,
+	"Sm": Sm,
+	"So": So,
+	"Z":  Z,
+	"Zl": Zl,
+	"Zp": Zp,
+	"Zs": Zs,
+}
+
+var _C = &RangeTable{
+	R16: []Range16{
+		{0x0001, 0x001f, 1},
+		{0x007f, 0x009f, 1},
+		{0x00ad, 0x0600, 1363},
+		{0x0601, 0x0605, 1},
+		{0x061c, 0x06dd, 193},
+		{0x070f, 0x180e, 4351},
+		{0x200b, 0x200f, 1},
+		{0x202a, 0x202e, 1},
+		{0x2060, 0x2064, 1},
+		{0x2066, 0x206f, 1},
+		{0xd800, 0xf8ff, 1},
+		{0xfeff, 0xfff9, 250},
+		{0xfffa, 0xfffb, 1},
+	},
+	R32: []Range32{
+		{0x110bd, 0x1bca0, 44003},
+		{0x1bca1, 0x1bca3, 1},
+		{0x1d173, 0x1d17a, 1},
+		{0xe0001, 0xe0020, 31},
+		{0xe0021, 0xe007f, 1},
+		{0xf0000, 0xffffd, 1},
+		{0x100000, 0x10fffd, 1},
+	},
+	LatinOffset: 2,
+}
+
+var _Cc = &RangeTable{
+	R16: []Range16{
+		{0x0001, 0x001f, 1},
+		{0x007f, 0x009f, 1},
+	},
+	LatinOffset: 2,
+}
+
+var _Cf = &RangeTable{
+	R16: []Range16{
+		{0x00ad, 0x0600, 1363},
+		{0x0601, 0x0605, 1},
+		{0x061c, 0x06dd, 193},
+		{0x070f, 0x180e, 4351},
+		{0x200b, 0x200f, 1},
+		{0x202a, 0x202e, 1},
+		{0x2060, 0x2064, 1},
+		{0x2066, 0x206f, 1},
+		{0xfeff, 0xfff9, 250},
+		{0xfffa, 0xfffb, 1},
+	},
+	R32: []Range32{
+		{0x110bd, 0x1bca0, 44003},
+		{0x1bca1, 0x1bca3, 1},
+		{0x1d173, 0x1d17a, 1},
+		{0xe0001, 0xe0020, 31},
+		{0xe0021, 0xe007f, 1},
+	},
+}
+
+var _Co = &RangeTable{
+	R16: []Range16{
+		{0xe000, 0xf8ff, 1},
+	},
+	R32: []Range32{
+		{0xf0000, 0xffffd, 1},
+		{0x100000, 0x10fffd, 1},
+	},
+}
+
+var _Cs = &RangeTable{
+	R16: []Range16{
+		{0xd800, 0xdfff, 1},
+	},
+}
+
+var _L = &RangeTable{
+	R16: []Range16{
+		{0x0041, 0x005a, 1},
+		{0x0061, 0x007a, 1},
+		{0x00aa, 0x00b5, 11},
+		{0x00ba, 0x00c0, 6},
+		{0x00c1, 0x00d6, 1},
+		{0x00d8, 0x00f6, 1},
+		{0x00f8, 0x02c1, 1},
+		{0x02c6, 0x02d1, 1},
+		{0x02e0, 0x02e4, 1},
+		{0x02ec, 0x02ee, 2},
+		{0x0370, 0x0374, 1},
+		{0x0376, 0x0377, 1},
+		{0x037a, 0x037d, 1},
+		{0x037f, 0x0386, 7},
+		{0x0388, 0x038a, 1},
+		{0x038c, 0x038e, 2},
+		{0x038f, 0x03a1, 1},
+		{0x03a3, 0x03f5, 1},
+		{0x03f7, 0x0481, 1},
+		{0x048a, 0x052f, 1},
+		{0x0531, 0x0556, 1},
+		{0x0559, 0x0561, 8},
+		{0x0562, 0x0587, 1},
+		{0x05d0, 0x05ea, 1},
+		{0x05f0, 0x05f2, 1},
+		{0x0620, 0x064a, 1},
+		{0x066e, 0x066f, 1},
+		{0x0671, 0x06d3, 1},
+		{0x06d5, 0x06e5, 16},
+		{0x06e6, 0x06ee, 8},
+		{0x06ef, 0x06fa, 11},
+		{0x06fb, 0x06fc, 1},
+		{0x06ff, 0x0710, 17},
+		{0x0712, 0x072f, 1},
+		{0x074d, 0x07a5, 1},
+		{0x07b1, 0x07ca, 25},
+		{0x07cb, 0x07ea, 1},
+		{0x07f4, 0x07f5, 1},
+		{0x07fa, 0x0800, 6},
+		{0x0801, 0x0815, 1},
+		{0x081a, 0x0824, 10},
+		{0x0828, 0x0840, 24},
+		{0x0841, 0x0858, 1},
+		{0x08a0, 0x08b2, 1},
+		{0x0904, 0x0939, 1},
+		{0x093d, 0x0950, 19},
+		{0x0958, 0x0961, 1},
+		{0x0971, 0x0980, 1},
+		{0x0985, 0x098c, 1},
+		{0x098f, 0x0990, 1},
+		{0x0993, 0x09a8, 1},
+		{0x09aa, 0x09b0, 1},
+		{0x09b2, 0x09b6, 4},
+		{0x09b7, 0x09b9, 1},
+		{0x09bd, 0x09ce, 17},
+		{0x09dc, 0x09dd, 1},
+		{0x09df, 0x09e1, 1},
+		{0x09f0, 0x09f1, 1},
+		{0x0a05, 0x0a0a, 1},
+		{0x0a0f, 0x0a10, 1},
+		{0x0a13, 0x0a28, 1},
+		{0x0a2a, 0x0a30, 1},
+		{0x0a32, 0x0a33, 1},
+		{0x0a35, 0x0a36, 1},
+		{0x0a38, 0x0a39, 1},
+		{0x0a59, 0x0a5c, 1},
+		{0x0a5e, 0x0a72, 20},
+		{0x0a73, 0x0a74, 1},
+		{0x0a85, 0x0a8d, 1},
+		{0x0a8f, 0x0a91, 1},
+		{0x0a93, 0x0aa8, 1},
+		{0x0aaa, 0x0ab0, 1},
+		{0x0ab2, 0x0ab3, 1},
+		{0x0ab5, 0x0ab9, 1},
+		{0x0abd, 0x0ad0, 19},
+		{0x0ae0, 0x0ae1, 1},
+		{0x0b05, 0x0b0c, 1},
+		{0x0b0f, 0x0b10, 1},
+		{0x0b13, 0x0b28, 1},
+		{0x0b2a, 0x0b30, 1},
+		{0x0b32, 0x0b33, 1},
+		{0x0b35, 0x0b39, 1},
+		{0x0b3d, 0x0b5c, 31},
+		{0x0b5d, 0x0b5f, 2},
+		{0x0b60, 0x0b61, 1},
+		{0x0b71, 0x0b83, 18},
+		{0x0b85, 0x0b8a, 1},
+		{0x0b8e, 0x0b90, 1},
+		{0x0b92, 0x0b95, 1},
+		{0x0b99, 0x0b9a, 1},
+		{0x0b9c, 0x0b9e, 2},
+		{0x0b9f, 0x0ba3, 4},
+		{0x0ba4, 0x0ba8, 4},
+		{0x0ba9, 0x0baa, 1},
+		{0x0bae, 0x0bb9, 1},
+		{0x0bd0, 0x0c05, 53},
+		{0x0c06, 0x0c0c, 1},
+		{0x0c0e, 0x0c10, 1},
+		{0x0c12, 0x0c28, 1},
+		{0x0c2a, 0x0c39, 1},
+		{0x0c3d, 0x0c58, 27},
+		{0x0c59, 0x0c60, 7},
+		{0x0c61, 0x0c85, 36},
+		{0x0c86, 0x0c8c, 1},
+		{0x0c8e, 0x0c90, 1},
+		{0x0c92, 0x0ca8, 1},
+		{0x0caa, 0x0cb3, 1},
+		{0x0cb5, 0x0cb9, 1},
+		{0x0cbd, 0x0cde, 33},
+		{0x0ce0, 0x0ce1, 1},
+		{0x0cf1, 0x0cf2, 1},
+		{0x0d05, 0x0d0c, 1},
+		{0x0d0e, 0x0d10, 1},
+		{0x0d12, 0x0d3a, 1},
+		{0x0d3d, 0x0d4e, 17},
+		{0x0d60, 0x0d61, 1},
+		{0x0d7a, 0x0d7f, 1},
+		{0x0d85, 0x0d96, 1},
+		{0x0d9a, 0x0db1, 1},
+		{0x0db3, 0x0dbb, 1},
+		{0x0dbd, 0x0dc0, 3},
+		{0x0dc1, 0x0dc6, 1},
+		{0x0e01, 0x0e30, 1},
+		{0x0e32, 0x0e33, 1},
+		{0x0e40, 0x0e46, 1},
+		{0x0e81, 0x0e82, 1},
+		{0x0e84, 0x0e87, 3},
+		{0x0e88, 0x0e8a, 2},
+		{0x0e8d, 0x0e94, 7},
+		{0x0e95, 0x0e97, 1},
+		{0x0e99, 0x0e9f, 1},
+		{0x0ea1, 0x0ea3, 1},
+		{0x0ea5, 0x0ea7, 2},
+		{0x0eaa, 0x0eab, 1},
+		{0x0ead, 0x0eb0, 1},
+		{0x0eb2, 0x0eb3, 1},
+		{0x0ebd, 0x0ec0, 3},
+		{0x0ec1, 0x0ec4, 1},
+		{0x0ec6, 0x0edc, 22},
+		{0x0edd, 0x0edf, 1},
+		{0x0f00, 0x0f40, 64},
+		{0x0f41, 0x0f47, 1},
+		{0x0f49, 0x0f6c, 1},
+		{0x0f88, 0x0f8c, 1},
+		{0x1000, 0x102a, 1},
+		{0x103f, 0x1050, 17},
+		{0x1051, 0x1055, 1},
+		{0x105a, 0x105d, 1},
+		{0x1061, 0x1065, 4},
+		{0x1066, 0x106e, 8},
+		{0x106f, 0x1070, 1},
+		{0x1075, 0x1081, 1},
+		{0x108e, 0x10a0, 18},
+		{0x10a1, 0x10c5, 1},
+		{0x10c7, 0x10cd, 6},
+		{0x10d0, 0x10fa, 1},
+		{0x10fc, 0x1248, 1},
+		{0x124a, 0x124d, 1},
+		{0x1250, 0x1256, 1},
+		{0x1258, 0x125a, 2},
+		{0x125b, 0x125d, 1},
+		{0x1260, 0x1288, 1},
+		{0x128a, 0x128d, 1},
+		{0x1290, 0x12b0, 1},
+		{0x12b2, 0x12b5, 1},
+		{0x12b8, 0x12be, 1},
+		{0x12c0, 0x12c2, 2},
+		{0x12c3, 0x12c5, 1},
+		{0x12c8, 0x12d6, 1},
+		{0x12d8, 0x1310, 1},
+		{0x1312, 0x1315, 1},
+		{0x1318, 0x135a, 1},
+		{0x1380, 0x138f, 1},
+		{0x13a0, 0x13f4, 1},
+		{0x1401, 0x166c, 1},
+		{0x166f, 0x167f, 1},
+		{0x1681, 0x169a, 1},
+		{0x16a0, 0x16ea, 1},
+		{0x16f1, 0x16f8, 1},
+		{0x1700, 0x170c, 1},
+		{0x170e, 0x1711, 1},
+		{0x1720, 0x1731, 1},
+		{0x1740, 0x1751, 1},
+		{0x1760, 0x176c, 1},
+		{0x176e, 0x1770, 1},
+		{0x1780, 0x17b3, 1},
+		{0x17d7, 0x17dc, 5},
+		{0x1820, 0x1877, 1},
+		{0x1880, 0x18a8, 1},
+		{0x18aa, 0x18b0, 6},
+		{0x18b1, 0x18f5, 1},
+		{0x1900, 0x191e, 1},
+		{0x1950, 0x196d, 1},
+		{0x1970, 0x1974, 1},
+		{0x1980, 0x19ab, 1},
+		{0x19c1, 0x19c7, 1},
+		{0x1a00, 0x1a16, 1},
+		{0x1a20, 0x1a54, 1},
+		{0x1aa7, 0x1b05, 94},
+		{0x1b06, 0x1b33, 1},
+		{0x1b45, 0x1b4b, 1},
+		{0x1b83, 0x1ba0, 1},
+		{0x1bae, 0x1baf, 1},
+		{0x1bba, 0x1be5, 1},
+		{0x1c00, 0x1c23, 1},
+		{0x1c4d, 0x1c4f, 1},
+		{0x1c5a, 0x1c7d, 1},
+		{0x1ce9, 0x1cec, 1},
+		{0x1cee, 0x1cf1, 1},
+		{0x1cf5, 0x1cf6, 1},
+		{0x1d00, 0x1dbf, 1},
+		{0x1e00, 0x1f15, 1},
+		{0x1f18, 0x1f1d, 1},
+		{0x1f20, 0x1f45, 1},
+		{0x1f48, 0x1f4d, 1},
+		{0x1f50, 0x1f57, 1},
+		{0x1f59, 0x1f5f, 2},
+		{0x1f60, 0x1f7d, 1},
+		{0x1f80, 0x1fb4, 1},
+		{0x1fb6, 0x1fbc, 1},
+		{0x1fbe, 0x1fc2, 4},
+		{0x1fc3, 0x1fc4, 1},
+		{0x1fc6, 0x1fcc, 1},
+		{0x1fd0, 0x1fd3, 1},
+		{0x1fd6, 0x1fdb, 1},
+		{0x1fe0, 0x1fec, 1},
+		{0x1ff2, 0x1ff4, 1},
+		{0x1ff6, 0x1ffc, 1},
+		{0x2071, 0x207f, 14},
+		{0x2090, 0x209c, 1},
+		{0x2102, 0x2107, 5},
+		{0x210a, 0x2113, 1},
+		{0x2115, 0x2119, 4},
+		{0x211a, 0x211d, 1},
+		{0x2124, 0x212a, 2},
+		{0x212b, 0x212d, 1},
+		{0x212f, 0x2139, 1},
+		{0x213c, 0x213f, 1},
+		{0x2145, 0x2149, 1},
+		{0x214e, 0x2183, 53},
+		{0x2184, 0x2c00, 2684},
+		{0x2c01, 0x2c2e, 1},
+		{0x2c30, 0x2c5e, 1},
+		{0x2c60, 0x2ce4, 1},
+		{0x2ceb, 0x2cee, 1},
+		{0x2cf2, 0x2cf3, 1},
+		{0x2d00, 0x2d25, 1},
+		{0x2d27, 0x2d2d, 6},
+		{0x2d30, 0x2d67, 1},
+		{0x2d6f, 0x2d80, 17},
+		{0x2d81, 0x2d96, 1},
+		{0x2da0, 0x2da6, 1},
+		{0x2da8, 0x2dae, 1},
+		{0x2db0, 0x2db6, 1},
+		{0x2db8, 0x2dbe, 1},
+		{0x2dc0, 0x2dc6, 1},
+		{0x2dc8, 0x2dce, 1},
+		{0x2dd0, 0x2dd6, 1},
+		{0x2dd8, 0x2dde, 1},
+		{0x2e2f, 0x3005, 470},
+		{0x3006, 0x3031, 43},
+		{0x3032, 0x3035, 1},
+		{0x303b, 0x303c, 1},
+		{0x3041, 0x3096, 1},
+		{0x309d, 0x309f, 1},
+		{0x30a1, 0x30fa, 1},
+		{0x30fc, 0x30ff, 1},
+		{0x3105, 0x312d, 1},
+		{0x3131, 0x318e, 1},
+		{0x31a0, 0x31ba, 1},
+		{0x31f0, 0x31ff, 1},
+		{0x3400, 0x4db5, 1},
+		{0x4e00, 0x9fcc, 1},
+		{0xa000, 0xa48c, 1},
+		{0xa4d0, 0xa4fd, 1},
+		{0xa500, 0xa60c, 1},
+		{0xa610, 0xa61f, 1},
+		{0xa62a, 0xa62b, 1},
+		{0xa640, 0xa66e, 1},
+		{0xa67f, 0xa69d, 1},
+		{0xa6a0, 0xa6e5, 1},
+		{0xa717, 0xa71f, 1},
+		{0xa722, 0xa788, 1},
+		{0xa78b, 0xa78e, 1},
+		{0xa790, 0xa7ad, 1},
+		{0xa7b0, 0xa7b1, 1},
+		{0xa7f7, 0xa801, 1},
+		{0xa803, 0xa805, 1},
+		{0xa807, 0xa80a, 1},
+		{0xa80c, 0xa822, 1},
+		{0xa840, 0xa873, 1},
+		{0xa882, 0xa8b3, 1},
+		{0xa8f2, 0xa8f7, 1},
+		{0xa8fb, 0xa90a, 15},
+		{0xa90b, 0xa925, 1},
+		{0xa930, 0xa946, 1},
+		{0xa960, 0xa97c, 1},
+		{0xa984, 0xa9b2, 1},
+		{0xa9cf, 0xa9e0, 17},
+		{0xa9e1, 0xa9e4, 1},
+		{0xa9e6, 0xa9ef, 1},
+		{0xa9fa, 0xa9fe, 1},
+		{0xaa00, 0xaa28, 1},
+		{0xaa40, 0xaa42, 1},
+		{0xaa44, 0xaa4b, 1},
+		{0xaa60, 0xaa76, 1},
+		{0xaa7a, 0xaa7e, 4},
+		{0xaa7f, 0xaaaf, 1},
+		{0xaab1, 0xaab5, 4},
+		{0xaab6, 0xaab9, 3},
+		{0xaaba, 0xaabd, 1},
+		{0xaac0, 0xaac2, 2},
+		{0xaadb, 0xaadd, 1},
+		{0xaae0, 0xaaea, 1},
+		{0xaaf2, 0xaaf4, 1},
+		{0xab01, 0xab06, 1},
+		{0xab09, 0xab0e, 1},
+		{0xab11, 0xab16, 1},
+		{0xab20, 0xab26, 1},
+		{0xab28, 0xab2e, 1},
+		{0xab30, 0xab5a, 1},
+		{0xab5c, 0xab5f, 1},
+		{0xab64, 0xab65, 1},
+		{0xabc0, 0xabe2, 1},
+		{0xac00, 0xd7a3, 1},
+		{0xd7b0, 0xd7c6, 1},
+		{0xd7cb, 0xd7fb, 1},
+		{0xf900, 0xfa6d, 1},
+		{0xfa70, 0xfad9, 1},
+		{0xfb00, 0xfb06, 1},
+		{0xfb13, 0xfb17, 1},
+		{0xfb1d, 0xfb1f, 2},
+		{0xfb20, 0xfb28, 1},
+		{0xfb2a, 0xfb36, 1},
+		{0xfb38, 0xfb3c, 1},
+		{0xfb3e, 0xfb40, 2},
+		{0xfb41, 0xfb43, 2},
+		{0xfb44, 0xfb46, 2},
+		{0xfb47, 0xfbb1, 1},
+		{0xfbd3, 0xfd3d, 1},
+		{0xfd50, 0xfd8f, 1},
+		{0xfd92, 0xfdc7, 1},
+		{0xfdf0, 0xfdfb, 1},
+		{0xfe70, 0xfe74, 1},
+		{0xfe76, 0xfefc, 1},
+		{0xff21, 0xff3a, 1},
+		{0xff41, 0xff5a, 1},
+		{0xff66, 0xffbe, 1},
+		{0xffc2, 0xffc7, 1},
+		{0xffca, 0xffcf, 1},
+		{0xffd2, 0xffd7, 1},
+		{0xffda, 0xffdc, 1},
+	},
+	R32: []Range32{
+		{0x10000, 0x1000b, 1},
+		{0x1000d, 0x10026, 1},
+		{0x10028, 0x1003a, 1},
+		{0x1003c, 0x1003d, 1},
+		{0x1003f, 0x1004d, 1},
+		{0x10050, 0x1005d, 1},
+		{0x10080, 0x100fa, 1},
+		{0x10280, 0x1029c, 1},
+		{0x102a0, 0x102d0, 1},
+		{0x10300, 0x1031f, 1},
+		{0x10330, 0x10340, 1},
+		{0x10342, 0x10349, 1},
+		{0x10350, 0x10375, 1},
+		{0x10380, 0x1039d, 1},
+		{0x103a0, 0x103c3, 1},
+		{0x103c8, 0x103cf, 1},
+		{0x10400, 0x1049d, 1},
+		{0x10500, 0x10527, 1},
+		{0x10530, 0x10563, 1},
+		{0x10600, 0x10736, 1},
+		{0x10740, 0x10755, 1},
+		{0x10760, 0x10767, 1},
+		{0x10800, 0x10805, 1},
+		{0x10808, 0x1080a, 2},
+		{0x1080b, 0x10835, 1},
+		{0x10837, 0x10838, 1},
+		{0x1083c, 0x1083f, 3},
+		{0x10840, 0x10855, 1},
+		{0x10860, 0x10876, 1},
+		{0x10880, 0x1089e, 1},
+		{0x10900, 0x10915, 1},
+		{0x10920, 0x10939, 1},
+		{0x10980, 0x109b7, 1},
+		{0x109be, 0x109bf, 1},
+		{0x10a00, 0x10a10, 16},
+		{0x10a11, 0x10a13, 1},
+		{0x10a15, 0x10a17, 1},
+		{0x10a19, 0x10a33, 1},
+		{0x10a60, 0x10a7c, 1},
+		{0x10a80, 0x10a9c, 1},
+		{0x10ac0, 0x10ac7, 1},
+		{0x10ac9, 0x10ae4, 1},
+		{0x10b00, 0x10b35, 1},
+		{0x10b40, 0x10b55, 1},
+		{0x10b60, 0x10b72, 1},
+		{0x10b80, 0x10b91, 1},
+		{0x10c00, 0x10c48, 1},
+		{0x11003, 0x11037, 1},
+		{0x11083, 0x110af, 1},
+		{0x110d0, 0x110e8, 1},
+		{0x11103, 0x11126, 1},
+		{0x11150, 0x11172, 1},
+		{0x11176, 0x11183, 13},
+		{0x11184, 0x111b2, 1},
+		{0x111c1, 0x111c4, 1},
+		{0x111da, 0x11200, 38},
+		{0x11201, 0x11211, 1},
+		{0x11213, 0x1122b, 1},
+		{0x112b0, 0x112de, 1},
+		{0x11305, 0x1130c, 1},
+		{0x1130f, 0x11310, 1},
+		{0x11313, 0x11328, 1},
+		{0x1132a, 0x11330, 1},
+		{0x11332, 0x11333, 1},
+		{0x11335, 0x11339, 1},
+		{0x1133d, 0x1135d, 32},
+		{0x1135e, 0x11361, 1},
+		{0x11480, 0x114af, 1},
+		{0x114c4, 0x114c5, 1},
+		{0x114c7, 0x11580, 185},
+		{0x11581, 0x115ae, 1},
+		{0x11600, 0x1162f, 1},
+		{0x11644, 0x11680, 60},
+		{0x11681, 0x116aa, 1},
+		{0x118a0, 0x118df, 1},
+		{0x118ff, 0x11ac0, 449},
+		{0x11ac1, 0x11af8, 1},
+		{0x12000, 0x12398, 1},
+		{0x13000, 0x1342e, 1},
+		{0x16800, 0x16a38, 1},
+		{0x16a40, 0x16a5e, 1},
+		{0x16ad0, 0x16aed, 1},
+		{0x16b00, 0x16b2f, 1},
+		{0x16b40, 0x16b43, 1},
+		{0x16b63, 0x16b77, 1},
+		{0x16b7d, 0x16b8f, 1},
+		{0x16f00, 0x16f44, 1},
+		{0x16f50, 0x16f93, 67},
+		{0x16f94, 0x16f9f, 1},
+		{0x1b000, 0x1b001, 1},
+		{0x1bc00, 0x1bc6a, 1},
+		{0x1bc70, 0x1bc7c, 1},
+		{0x1bc80, 0x1bc88, 1},
+		{0x1bc90, 0x1bc99, 1},
+		{0x1d400, 0x1d454, 1},
+		{0x1d456, 0x1d49c, 1},
+		{0x1d49e, 0x1d49f, 1},
+		{0x1d4a2, 0x1d4a5, 3},
+		{0x1d4a6, 0x1d4a9, 3},
+		{0x1d4aa, 0x1d4ac, 1},
+		{0x1d4ae, 0x1d4b9, 1},
+		{0x1d4bb, 0x1d4bd, 2},
+		{0x1d4be, 0x1d4c3, 1},
+		{0x1d4c5, 0x1d505, 1},
+		{0x1d507, 0x1d50a, 1},
+		{0x1d50d, 0x1d514, 1},
+		{0x1d516, 0x1d51c, 1},
+		{0x1d51e, 0x1d539, 1},
+		{0x1d53b, 0x1d53e, 1},
+		{0x1d540, 0x1d544, 1},
+		{0x1d546, 0x1d54a, 4},
+		{0x1d54b, 0x1d550, 1},
+		{0x1d552, 0x1d6a5, 1},
+		{0x1d6a8, 0x1d6c0, 1},
+		{0x1d6c2, 0x1d6da, 1},
+		{0x1d6dc, 0x1d6fa, 1},
+		{0x1d6fc, 0x1d714, 1},
+		{0x1d716, 0x1d734, 1},
+		{0x1d736, 0x1d74e, 1},
+		{0x1d750, 0x1d76e, 1},
+		{0x1d770, 0x1d788, 1},
+		{0x1d78a, 0x1d7a8, 1},
+		{0x1d7aa, 0x1d7c2, 1},
+		{0x1d7c4, 0x1d7cb, 1},
+		{0x1e800, 0x1e8c4, 1},
+		{0x1ee00, 0x1ee03, 1},
+		{0x1ee05, 0x1ee1f, 1},
+		{0x1ee21, 0x1ee22, 1},
+		{0x1ee24, 0x1ee27, 3},
+		{0x1ee29, 0x1ee32, 1},
+		{0x1ee34, 0x1ee37, 1},
+		{0x1ee39, 0x1ee3b, 2},
+		{0x1ee42, 0x1ee47, 5},
+		{0x1ee49, 0x1ee4d, 2},
+		{0x1ee4e, 0x1ee4f, 1},
+		{0x1ee51, 0x1ee52, 1},
+		{0x1ee54, 0x1ee57, 3},
+		{0x1ee59, 0x1ee61, 2},
+		{0x1ee62, 0x1ee64, 2},
+		{0x1ee67, 0x1ee6a, 1},
+		{0x1ee6c, 0x1ee72, 1},
+		{0x1ee74, 0x1ee77, 1},
+		{0x1ee79, 0x1ee7c, 1},
+		{0x1ee7e, 0x1ee80, 2},
+		{0x1ee81, 0x1ee89, 1},
+		{0x1ee8b, 0x1ee9b, 1},
+		{0x1eea1, 0x1eea3, 1},
+		{0x1eea5, 0x1eea9, 1},
+		{0x1eeab, 0x1eebb, 1},
+		{0x20000, 0x2a6d6, 1},
+		{0x2a700, 0x2b734, 1},
+		{0x2b740, 0x2b81d, 1},
+		{0x2f800, 0x2fa1d, 1},
+	},
+	LatinOffset: 6,
+}
+
+var _Ll = &RangeTable{
+	R16: []Range16{
+		{0x0061, 0x007a, 1},
+		{0x00b5, 0x00df, 42},
+		{0x00e0, 0x00f6, 1},
+		{0x00f8, 0x00ff, 1},
+		{0x0101, 0x0137, 2},
+		{0x0138, 0x0148, 2},
+		{0x0149, 0x0177, 2},
+		{0x017a, 0x017e, 2},
+		{0x017f, 0x0180, 1},
+		{0x0183, 0x0185, 2},
+		{0x0188, 0x018c, 4},
+		{0x018d, 0x0192, 5},
+		{0x0195, 0x0199, 4},
+		{0x019a, 0x019b, 1},
+		{0x019e, 0x01a1, 3},
+		{0x01a3, 0x01a5, 2},
+		{0x01a8, 0x01aa, 2},
+		{0x01ab, 0x01ad, 2},
+		{0x01b0, 0x01b4, 4},
+		{0x01b6, 0x01b9, 3},
+		{0x01ba, 0x01bd, 3},
+		{0x01be, 0x01bf, 1},
+		{0x01c6, 0x01cc, 3},
+		{0x01ce, 0x01dc, 2},
+		{0x01dd, 0x01ef, 2},
+		{0x01f0, 0x01f3, 3},
+		{0x01f5, 0x01f9, 4},
+		{0x01fb, 0x0233, 2},
+		{0x0234, 0x0239, 1},
+		{0x023c, 0x023f, 3},
+		{0x0240, 0x0242, 2},
+		{0x0247, 0x024f, 2},
+		{0x0250, 0x0293, 1},
+		{0x0295, 0x02af, 1},
+		{0x0371, 0x0373, 2},
+		{0x0377, 0x037b, 4},
+		{0x037c, 0x037d, 1},
+		{0x0390, 0x03ac, 28},
+		{0x03ad, 0x03ce, 1},
+		{0x03d0, 0x03d1, 1},
+		{0x03d5, 0x03d7, 1},
+		{0x03d9, 0x03ef, 2},
+		{0x03f0, 0x03f3, 1},
+		{0x03f5, 0x03fb, 3},
+		{0x03fc, 0x0430, 52},
+		{0x0431, 0x045f, 1},
+		{0x0461, 0x0481, 2},
+		{0x048b, 0x04bf, 2},
+		{0x04c2, 0x04ce, 2},
+		{0x04cf, 0x052f, 2},
+		{0x0561, 0x0587, 1},
+		{0x1d00, 0x1d2b, 1},
+		{0x1d6b, 0x1d77, 1},
+		{0x1d79, 0x1d9a, 1},
+		{0x1e01, 0x1e95, 2},
+		{0x1e96, 0x1e9d, 1},
+		{0x1e9f, 0x1eff, 2},
+		{0x1f00, 0x1f07, 1},
+		{0x1f10, 0x1f15, 1},
+		{0x1f20, 0x1f27, 1},
+		{0x1f30, 0x1f37, 1},
+		{0x1f40, 0x1f45, 1},
+		{0x1f50, 0x1f57, 1},
+		{0x1f60, 0x1f67, 1},
+		{0x1f70, 0x1f7d, 1},
+		{0x1f80, 0x1f87, 1},
+		{0x1f90, 0x1f97, 1},
+		{0x1fa0, 0x1fa7, 1},
+		{0x1fb0, 0x1fb4, 1},
+		{0x1fb6, 0x1fb7, 1},
+		{0x1fbe, 0x1fc2, 4},
+		{0x1fc3, 0x1fc4, 1},
+		{0x1fc6, 0x1fc7, 1},
+		{0x1fd0, 0x1fd3, 1},
+		{0x1fd6, 0x1fd7, 1},
+		{0x1fe0, 0x1fe7, 1},
+		{0x1ff2, 0x1ff4, 1},
+		{0x1ff6, 0x1ff7, 1},
+		{0x210a, 0x210e, 4},
+		{0x210f, 0x2113, 4},
+		{0x212f, 0x2139, 5},
+		{0x213c, 0x213d, 1},
+		{0x2146, 0x2149, 1},
+		{0x214e, 0x2184, 54},
+		{0x2c30, 0x2c5e, 1},
+		{0x2c61, 0x2c65, 4},
+		{0x2c66, 0x2c6c, 2},
+		{0x2c71, 0x2c73, 2},
+		{0x2c74, 0x2c76, 2},
+		{0x2c77, 0x2c7b, 1},
+		{0x2c81, 0x2ce3, 2},
+		{0x2ce4, 0x2cec, 8},
+		{0x2cee, 0x2cf3, 5},
+		{0x2d00, 0x2d25, 1},
+		{0x2d27, 0x2d2d, 6},
+		{0xa641, 0xa66d, 2},
+		{0xa681, 0xa69b, 2},
+		{0xa723, 0xa72f, 2},
+		{0xa730, 0xa731, 1},
+		{0xa733, 0xa771, 2},
+		{0xa772, 0xa778, 1},
+		{0xa77a, 0xa77c, 2},
+		{0xa77f, 0xa787, 2},
+		{0xa78c, 0xa78e, 2},
+		{0xa791, 0xa793, 2},
+		{0xa794, 0xa795, 1},
+		{0xa797, 0xa7a9, 2},
+		{0xa7fa, 0xab30, 822},
+		{0xab31, 0xab5a, 1},
+		{0xab64, 0xab65, 1},
+		{0xfb00, 0xfb06, 1},
+		{0xfb13, 0xfb17, 1},
+		{0xff41, 0xff5a, 1},
+	},
+	R32: []Range32{
+		{0x10428, 0x1044f, 1},
+		{0x118c0, 0x118df, 1},
+		{0x1d41a, 0x1d433, 1},
+		{0x1d44e, 0x1d454, 1},
+		{0x1d456, 0x1d467, 1},
+		{0x1d482, 0x1d49b, 1},
+		{0x1d4b6, 0x1d4b9, 1},
+		{0x1d4bb, 0x1d4bd, 2},
+		{0x1d4be, 0x1d4c3, 1},
+		{0x1d4c5, 0x1d4cf, 1},
+		{0x1d4ea, 0x1d503, 1},
+		{0x1d51e, 0x1d537, 1},
+		{0x1d552, 0x1d56b, 1},
+		{0x1d586, 0x1d59f, 1},
+		{0x1d5ba, 0x1d5d3, 1},
+		{0x1d5ee, 0x1d607, 1},
+		{0x1d622, 0x1d63b, 1},
+		{0x1d656, 0x1d66f, 1},
+		{0x1d68a, 0x1d6a5, 1},
+		{0x1d6c2, 0x1d6da, 1},
+		{0x1d6dc, 0x1d6e1, 1},
+		{0x1d6fc, 0x1d714, 1},
+		{0x1d716, 0x1d71b, 1},
+		{0x1d736, 0x1d74e, 1},
+		{0x1d750, 0x1d755, 1},
+		{0x1d770, 0x1d788, 1},
+		{0x1d78a, 0x1d78f, 1},
+		{0x1d7aa, 0x1d7c2, 1},
+		{0x1d7c4, 0x1d7c9, 1},
+		{0x1d7cb, 0x1d7cb, 1},
+	},
+	LatinOffset: 4,
+}
+
+var _Lm = &RangeTable{
+	R16: []Range16{
+		{0x02b0, 0x02c1, 1},
+		{0x02c6, 0x02d1, 1},
+		{0x02e0, 0x02e4, 1},
+		{0x02ec, 0x02ee, 2},
+		{0x0374, 0x037a, 6},
+		{0x0559, 0x0640, 231},
+		{0x06e5, 0x06e6, 1},
+		{0x07f4, 0x07f5, 1},
+		{0x07fa, 0x081a, 32},
+		{0x0824, 0x0828, 4},
+		{0x0971, 0x0e46, 1237},
+		{0x0ec6, 0x10fc, 566},
+		{0x17d7, 0x1843, 108},
+		{0x1aa7, 0x1c78, 465},
+		{0x1c79, 0x1c7d, 1},
+		{0x1d2c, 0x1d6a, 1},
+		{0x1d78, 0x1d9b, 35},
+		{0x1d9c, 0x1dbf, 1},
+		{0x2071, 0x207f, 14},
+		{0x2090, 0x209c, 1},
+		{0x2c7c, 0x2c7d, 1},
+		{0x2d6f, 0x2e2f, 192},
+		{0x3005, 0x3031, 44},
+		{0x3032, 0x3035, 1},
+		{0x303b, 0x309d, 98},
+		{0x309e, 0x30fc, 94},
+		{0x30fd, 0x30fe, 1},
+		{0xa015, 0xa4f8, 1251},
+		{0xa4f9, 0xa4fd, 1},
+		{0xa60c, 0xa67f, 115},
+		{0xa69c, 0xa69d, 1},
+		{0xa717, 0xa71f, 1},
+		{0xa770, 0xa788, 24},
+		{0xa7f8, 0xa7f9, 1},
+		{0xa9cf, 0xa9e6, 23},
+		{0xaa70, 0xaadd, 109},
+		{0xaaf3, 0xaaf4, 1},
+		{0xab5c, 0xab5f, 1},
+		{0xff70, 0xff9e, 46},
+		{0xff9f, 0xff9f, 1},
+	},
+	R32: []Range32{
+		{0x16b40, 0x16b40, 1},
+		{0x16b41, 0x16b43, 1},
+		{0x16f93, 0x16f9f, 1},
+	},
+}
+
+var _Lo = &RangeTable{
+	R16: []Range16{
+		{0x00aa, 0x00ba, 16},
+		{0x01bb, 0x01c0, 5},
+		{0x01c1, 0x01c3, 1},
+		{0x0294, 0x05d0, 828},
+		{0x05d1, 0x05ea, 1},
+		{0x05f0, 0x05f2, 1},
+		{0x0620, 0x063f, 1},
+		{0x0641, 0x064a, 1},
+		{0x066e, 0x066f, 1},
+		{0x0671, 0x06d3, 1},
+		{0x06d5, 0x06ee, 25},
+		{0x06ef, 0x06fa, 11},
+		{0x06fb, 0x06fc, 1},
+		{0x06ff, 0x0710, 17},
+		{0x0712, 0x072f, 1},
+		{0x074d, 0x07a5, 1},
+		{0x07b1, 0x07ca, 25},
+		{0x07cb, 0x07ea, 1},
+		{0x0800, 0x0815, 1},
+		{0x0840, 0x0858, 1},
+		{0x08a0, 0x08b2, 1},
+		{0x0904, 0x0939, 1},
+		{0x093d, 0x0950, 19},
+		{0x0958, 0x0961, 1},
+		{0x0972, 0x0980, 1},
+		{0x0985, 0x098c, 1},
+		{0x098f, 0x0990, 1},
+		{0x0993, 0x09a8, 1},
+		{0x09aa, 0x09b0, 1},
+		{0x09b2, 0x09b6, 4},
+		{0x09b7, 0x09b9, 1},
+		{0x09bd, 0x09ce, 17},
+		{0x09dc, 0x09dd, 1},
+		{0x09df, 0x09e1, 1},
+		{0x09f0, 0x09f1, 1},
+		{0x0a05, 0x0a0a, 1},
+		{0x0a0f, 0x0a10, 1},
+		{0x0a13, 0x0a28, 1},
+		{0x0a2a, 0x0a30, 1},
+		{0x0a32, 0x0a33, 1},
+		{0x0a35, 0x0a36, 1},
+		{0x0a38, 0x0a39, 1},
+		{0x0a59, 0x0a5c, 1},
+		{0x0a5e, 0x0a72, 20},
+		{0x0a73, 0x0a74, 1},
+		{0x0a85, 0x0a8d, 1},
+		{0x0a8f, 0x0a91, 1},
+		{0x0a93, 0x0aa8, 1},
+		{0x0aaa, 0x0ab0, 1},
+		{0x0ab2, 0x0ab3, 1},
+		{0x0ab5, 0x0ab9, 1},
+		{0x0abd, 0x0ad0, 19},
+		{0x0ae0, 0x0ae1, 1},
+		{0x0b05, 0x0b0c, 1},
+		{0x0b0f, 0x0b10, 1},
+		{0x0b13, 0x0b28, 1},
+		{0x0b2a, 0x0b30, 1},
+		{0x0b32, 0x0b33, 1},
+		{0x0b35, 0x0b39, 1},
+		{0x0b3d, 0x0b5c, 31},
+		{0x0b5d, 0x0b5f, 2},
+		{0x0b60, 0x0b61, 1},
+		{0x0b71, 0x0b83, 18},
+		{0x0b85, 0x0b8a, 1},
+		{0x0b8e, 0x0b90, 1},
+		{0x0b92, 0x0b95, 1},
+		{0x0b99, 0x0b9a, 1},
+		{0x0b9c, 0x0b9e, 2},
+		{0x0b9f, 0x0ba3, 4},
+		{0x0ba4, 0x0ba8, 4},
+		{0x0ba9, 0x0baa, 1},
+		{0x0bae, 0x0bb9, 1},
+		{0x0bd0, 0x0c05, 53},
+		{0x0c06, 0x0c0c, 1},
+		{0x0c0e, 0x0c10, 1},
+		{0x0c12, 0x0c28, 1},
+		{0x0c2a, 0x0c39, 1},
+		{0x0c3d, 0x0c58, 27},
+		{0x0c59, 0x0c60, 7},
+		{0x0c61, 0x0c85, 36},
+		{0x0c86, 0x0c8c, 1},
+		{0x0c8e, 0x0c90, 1},
+		{0x0c92, 0x0ca8, 1},
+		{0x0caa, 0x0cb3, 1},
+		{0x0cb5, 0x0cb9, 1},
+		{0x0cbd, 0x0cde, 33},
+		{0x0ce0, 0x0ce1, 1},
+		{0x0cf1, 0x0cf2, 1},
+		{0x0d05, 0x0d0c, 1},
+		{0x0d0e, 0x0d10, 1},
+		{0x0d12, 0x0d3a, 1},
+		{0x0d3d, 0x0d4e, 17},
+		{0x0d60, 0x0d61, 1},
+		{0x0d7a, 0x0d7f, 1},
+		{0x0d85, 0x0d96, 1},
+		{0x0d9a, 0x0db1, 1},
+		{0x0db3, 0x0dbb, 1},
+		{0x0dbd, 0x0dc0, 3},
+		{0x0dc1, 0x0dc6, 1},
+		{0x0e01, 0x0e30, 1},
+		{0x0e32, 0x0e33, 1},
+		{0x0e40, 0x0e45, 1},
+		{0x0e81, 0x0e82, 1},
+		{0x0e84, 0x0e87, 3},
+		{0x0e88, 0x0e8a, 2},
+		{0x0e8d, 0x0e94, 7},
+		{0x0e95, 0x0e97, 1},
+		{0x0e99, 0x0e9f, 1},
+		{0x0ea1, 0x0ea3, 1},
+		{0x0ea5, 0x0ea7, 2},
+		{0x0eaa, 0x0eab, 1},
+		{0x0ead, 0x0eb0, 1},
+		{0x0eb2, 0x0eb3, 1},
+		{0x0ebd, 0x0ec0, 3},
+		{0x0ec1, 0x0ec4, 1},
+		{0x0edc, 0x0edf, 1},
+		{0x0f00, 0x0f40, 64},
+		{0x0f41, 0x0f47, 1},
+		{0x0f49, 0x0f6c, 1},
+		{0x0f88, 0x0f8c, 1},
+		{0x1000, 0x102a, 1},
+		{0x103f, 0x1050, 17},
+		{0x1051, 0x1055, 1},
+		{0x105a, 0x105d, 1},
+		{0x1061, 0x1065, 4},
+		{0x1066, 0x106e, 8},
+		{0x106f, 0x1070, 1},
+		{0x1075, 0x1081, 1},
+		{0x108e, 0x10d0, 66},
+		{0x10d1, 0x10fa, 1},
+		{0x10fd, 0x1248, 1},
+		{0x124a, 0x124d, 1},
+		{0x1250, 0x1256, 1},
+		{0x1258, 0x125a, 2},
+		{0x125b, 0x125d, 1},
+		{0x1260, 0x1288, 1},
+		{0x128a, 0x128d, 1},
+		{0x1290, 0x12b0, 1},
+		{0x12b2, 0x12b5, 1},
+		{0x12b8, 0x12be, 1},
+		{0x12c0, 0x12c2, 2},
+		{0x12c3, 0x12c5, 1},
+		{0x12c8, 0x12d6, 1},
+		{0x12d8, 0x1310, 1},
+		{0x1312, 0x1315, 1},
+		{0x1318, 0x135a, 1},
+		{0x1380, 0x138f, 1},
+		{0x13a0, 0x13f4, 1},
+		{0x1401, 0x166c, 1},
+		{0x166f, 0x167f, 1},
+		{0x1681, 0x169a, 1},
+		{0x16a0, 0x16ea, 1},
+		{0x16f1, 0x16f8, 1},
+		{0x1700, 0x170c, 1},
+		{0x170e, 0x1711, 1},
+		{0x1720, 0x1731, 1},
+		{0x1740, 0x1751, 1},
+		{0x1760, 0x176c, 1},
+		{0x176e, 0x1770, 1},
+		{0x1780, 0x17b3, 1},
+		{0x17dc, 0x1820, 68},
+		{0x1821, 0x1842, 1},
+		{0x1844, 0x1877, 1},
+		{0x1880, 0x18a8, 1},
+		{0x18aa, 0x18b0, 6},
+		{0x18b1, 0x18f5, 1},
+		{0x1900, 0x191e, 1},
+		{0x1950, 0x196d, 1},
+		{0x1970, 0x1974, 1},
+		{0x1980, 0x19ab, 1},
+		{0x19c1, 0x19c7, 1},
+		{0x1a00, 0x1a16, 1},
+		{0x1a20, 0x1a54, 1},
+		{0x1b05, 0x1b33, 1},
+		{0x1b45, 0x1b4b, 1},
+		{0x1b83, 0x1ba0, 1},
+		{0x1bae, 0x1baf, 1},
+		{0x1bba, 0x1be5, 1},
+		{0x1c00, 0x1c23, 1},
+		{0x1c4d, 0x1c4f, 1},
+		{0x1c5a, 0x1c77, 1},
+		{0x1ce9, 0x1cec, 1},
+		{0x1cee, 0x1cf1, 1},
+		{0x1cf5, 0x1cf6, 1},
+		{0x2135, 0x2138, 1},
+		{0x2d30, 0x2d67, 1},
+		{0x2d80, 0x2d96, 1},
+		{0x2da0, 0x2da6, 1},
+		{0x2da8, 0x2dae, 1},
+		{0x2db0, 0x2db6, 1},
+		{0x2db8, 0x2dbe, 1},
+		{0x2dc0, 0x2dc6, 1},
+		{0x2dc8, 0x2dce, 1},
+		{0x2dd0, 0x2dd6, 1},
+		{0x2dd8, 0x2dde, 1},
+		{0x3006, 0x303c, 54},
+		{0x3041, 0x3096, 1},
+		{0x309f, 0x30a1, 2},
+		{0x30a2, 0x30fa, 1},
+		{0x30ff, 0x3105, 6},
+		{0x3106, 0x312d, 1},
+		{0x3131, 0x318e, 1},
+		{0x31a0, 0x31ba, 1},
+		{0x31f0, 0x31ff, 1},
+		{0x3400, 0x4db5, 1},
+		{0x4e00, 0x9fcc, 1},
+		{0xa000, 0xa014, 1},
+		{0xa016, 0xa48c, 1},
+		{0xa4d0, 0xa4f7, 1},
+		{0xa500, 0xa60b, 1},
+		{0xa610, 0xa61f, 1},
+		{0xa62a, 0xa62b, 1},
+		{0xa66e, 0xa6a0, 50},
+		{0xa6a1, 0xa6e5, 1},
+		{0xa7f7, 0xa7fb, 4},
+		{0xa7fc, 0xa801, 1},
+		{0xa803, 0xa805, 1},
+		{0xa807, 0xa80a, 1},
+		{0xa80c, 0xa822, 1},
+		{0xa840, 0xa873, 1},
+		{0xa882, 0xa8b3, 1},
+		{0xa8f2, 0xa8f7, 1},
+		{0xa8fb, 0xa90a, 15},
+		{0xa90b, 0xa925, 1},
+		{0xa930, 0xa946, 1},
+		{0xa960, 0xa97c, 1},
+		{0xa984, 0xa9b2, 1},
+		{0xa9e0, 0xa9e4, 1},
+		{0xa9e7, 0xa9ef, 1},
+		{0xa9fa, 0xa9fe, 1},
+		{0xaa00, 0xaa28, 1},
+		{0xaa40, 0xaa42, 1},
+		{0xaa44, 0xaa4b, 1},
+		{0xaa60, 0xaa6f, 1},
+		{0xaa71, 0xaa76, 1},
+		{0xaa7a, 0xaa7e, 4},
+		{0xaa7f, 0xaaaf, 1},
+		{0xaab1, 0xaab5, 4},
+		{0xaab6, 0xaab9, 3},
+		{0xaaba, 0xaabd, 1},
+		{0xaac0, 0xaac2, 2},
+		{0xaadb, 0xaadc, 1},
+		{0xaae0, 0xaaea, 1},
+		{0xaaf2, 0xab01, 15},
+		{0xab02, 0xab06, 1},
+		{0xab09, 0xab0e, 1},
+		{0xab11, 0xab16, 1},
+		{0xab20, 0xab26, 1},
+		{0xab28, 0xab2e, 1},
+		{0xabc0, 0xabe2, 1},
+		{0xac00, 0xd7a3, 1},
+		{0xd7b0, 0xd7c6, 1},
+		{0xd7cb, 0xd7fb, 1},
+		{0xf900, 0xfa6d, 1},
+		{0xfa70, 0xfad9, 1},
+		{0xfb1d, 0xfb1f, 2},
+		{0xfb20, 0xfb28, 1},
+		{0xfb2a, 0xfb36, 1},
+		{0xfb38, 0xfb3c, 1},
+		{0xfb3e, 0xfb40, 2},
+		{0xfb41, 0xfb43, 2},
+		{0xfb44, 0xfb46, 2},
+		{0xfb47, 0xfbb1, 1},
+		{0xfbd3, 0xfd3d, 1},
+		{0xfd50, 0xfd8f, 1},
+		{0xfd92, 0xfdc7, 1},
+		{0xfdf0, 0xfdfb, 1},
+		{0xfe70, 0xfe74, 1},
+		{0xfe76, 0xfefc, 1},
+		{0xff66, 0xff6f, 1},
+		{0xff71, 0xff9d, 1},
+		{0xffa0, 0xffbe, 1},
+		{0xffc2, 0xffc7, 1},
+		{0xffca, 0xffcf, 1},
+		{0xffd2, 0xffd7, 1},
+		{0xffda, 0xffdc, 1},
+	},
+	R32: []Range32{
+		{0x10000, 0x1000b, 1},
+		{0x1000d, 0x10026, 1},
+		{0x10028, 0x1003a, 1},
+		{0x1003c, 0x1003d, 1},
+		{0x1003f, 0x1004d, 1},
+		{0x10050, 0x1005d, 1},
+		{0x10080, 0x100fa, 1},
+		{0x10280, 0x1029c, 1},
+		{0x102a0, 0x102d0, 1},
+		{0x10300, 0x1031f, 1},
+		{0x10330, 0x10340, 1},
+		{0x10342, 0x10349, 1},
+		{0x10350, 0x10375, 1},
+		{0x10380, 0x1039d, 1},
+		{0x103a0, 0x103c3, 1},
+		{0x103c8, 0x103cf, 1},
+		{0x10450, 0x1049d, 1},
+		{0x10500, 0x10527, 1},
+		{0x10530, 0x10563, 1},
+		{0x10600, 0x10736, 1},
+		{0x10740, 0x10755, 1},
+		{0x10760, 0x10767, 1},
+		{0x10800, 0x10805, 1},
+		{0x10808, 0x1080a, 2},
+		{0x1080b, 0x10835, 1},
+		{0x10837, 0x10838, 1},
+		{0x1083c, 0x1083f, 3},
+		{0x10840, 0x10855, 1},
+		{0x10860, 0x10876, 1},
+		{0x10880, 0x1089e, 1},
+		{0x10900, 0x10915, 1},
+		{0x10920, 0x10939, 1},
+		{0x10980, 0x109b7, 1},
+		{0x109be, 0x109bf, 1},
+		{0x10a00, 0x10a10, 16},
+		{0x10a11, 0x10a13, 1},
+		{0x10a15, 0x10a17, 1},
+		{0x10a19, 0x10a33, 1},
+		{0x10a60, 0x10a7c, 1},
+		{0x10a80, 0x10a9c, 1},
+		{0x10ac0, 0x10ac7, 1},
+		{0x10ac9, 0x10ae4, 1},
+		{0x10b00, 0x10b35, 1},
+		{0x10b40, 0x10b55, 1},
+		{0x10b60, 0x10b72, 1},
+		{0x10b80, 0x10b91, 1},
+		{0x10c00, 0x10c48, 1},
+		{0x11003, 0x11037, 1},
+		{0x11083, 0x110af, 1},
+		{0x110d0, 0x110e8, 1},
+		{0x11103, 0x11126, 1},
+		{0x11150, 0x11172, 1},
+		{0x11176, 0x11183, 13},
+		{0x11184, 0x111b2, 1},
+		{0x111c1, 0x111c4, 1},
+		{0x111da, 0x11200, 38},
+		{0x11201, 0x11211, 1},
+		{0x11213, 0x1122b, 1},
+		{0x112b0, 0x112de, 1},
+		{0x11305, 0x1130c, 1},
+		{0x1130f, 0x11310, 1},
+		{0x11313, 0x11328, 1},
+		{0x1132a, 0x11330, 1},
+		{0x11332, 0x11333, 1},
+		{0x11335, 0x11339, 1},
+		{0x1133d, 0x1135d, 32},
+		{0x1135e, 0x11361, 1},
+		{0x11480, 0x114af, 1},
+		{0x114c4, 0x114c5, 1},
+		{0x114c7, 0x11580, 185},
+		{0x11581, 0x115ae, 1},
+		{0x11600, 0x1162f, 1},
+		{0x11644, 0x11680, 60},
+		{0x11681, 0x116aa, 1},
+		{0x118ff, 0x11ac0, 449},
+		{0x11ac1, 0x11af8, 1},
+		{0x12000, 0x12398, 1},
+		{0x13000, 0x1342e, 1},
+		{0x16800, 0x16a38, 1},
+		{0x16a40, 0x16a5e, 1},
+		{0x16ad0, 0x16aed, 1},
+		{0x16b00, 0x16b2f, 1},
+		{0x16b63, 0x16b77, 1},
+		{0x16b7d, 0x16b8f, 1},
+		{0x16f00, 0x16f44, 1},
+		{0x16f50, 0x1b000, 16560},
+		{0x1b001, 0x1bc00, 3071},
+		{0x1bc01, 0x1bc6a, 1},
+		{0x1bc70, 0x1bc7c, 1},
+		{0x1bc80, 0x1bc88, 1},
+		{0x1bc90, 0x1bc99, 1},
+		{0x1e800, 0x1e8c4, 1},
+		{0x1ee00, 0x1ee03, 1},
+		{0x1ee05, 0x1ee1f, 1},
+		{0x1ee21, 0x1ee22, 1},
+		{0x1ee24, 0x1ee27, 3},
+		{0x1ee29, 0x1ee32, 1},
+		{0x1ee34, 0x1ee37, 1},
+		{0x1ee39, 0x1ee3b, 2},
+		{0x1ee42, 0x1ee47, 5},
+		{0x1ee49, 0x1ee4d, 2},
+		{0x1ee4e, 0x1ee4f, 1},
+		{0x1ee51, 0x1ee52, 1},
+		{0x1ee54, 0x1ee57, 3},
+		{0x1ee59, 0x1ee61, 2},
+		{0x1ee62, 0x1ee64, 2},
+		{0x1ee67, 0x1ee6a, 1},
+		{0x1ee6c, 0x1ee72, 1},
+		{0x1ee74, 0x1ee77, 1},
+		{0x1ee79, 0x1ee7c, 1},
+		{0x1ee7e, 0x1ee80, 2},
+		{0x1ee81, 0x1ee89, 1},
+		{0x1ee8b, 0x1ee9b, 1},
+		{0x1eea1, 0x1eea3, 1},
+		{0x1eea5, 0x1eea9, 1},
+		{0x1eeab, 0x1eebb, 1},
+		{0x20000, 0x2a6d6, 1},
+		{0x2a700, 0x2b734, 1},
+		{0x2b740, 0x2b81d, 1},
+		{0x2f800, 0x2fa1d, 1},
+	},
+	LatinOffset: 1,
+}
+
+var _Lt = &RangeTable{
+	R16: []Range16{
+		{0x01c5, 0x01cb, 3},
+		{0x01f2, 0x1f88, 7574},
+		{0x1f89, 0x1f8f, 1},
+		{0x1f98, 0x1f9f, 1},
+		{0x1fa8, 0x1faf, 1},
+		{0x1fbc, 0x1fcc, 16},
+		{0x1ffc, 0x1ffc, 1},
+	},
+}
+
+var _Lu = &RangeTable{
+	R16: []Range16{
+		{0x0041, 0x005a, 1},
+		{0x00c0, 0x00d6, 1},
+		{0x00d8, 0x00de, 1},
+		{0x0100, 0x0136, 2},
+		{0x0139, 0x0147, 2},
+		{0x014a, 0x0178, 2},
+		{0x0179, 0x017d, 2},
+		{0x0181, 0x0182, 1},
+		{0x0184, 0x0186, 2},
+		{0x0187, 0x0189, 2},
+		{0x018a, 0x018b, 1},
+		{0x018e, 0x0191, 1},
+		{0x0193, 0x0194, 1},
+		{0x0196, 0x0198, 1},
+		{0x019c, 0x019d, 1},
+		{0x019f, 0x01a0, 1},
+		{0x01a2, 0x01a6, 2},
+		{0x01a7, 0x01a9, 2},
+		{0x01ac, 0x01ae, 2},
+		{0x01af, 0x01b1, 2},
+		{0x01b2, 0x01b3, 1},
+		{0x01b5, 0x01b7, 2},
+		{0x01b8, 0x01bc, 4},
+		{0x01c4, 0x01cd, 3},
+		{0x01cf, 0x01db, 2},
+		{0x01de, 0x01ee, 2},
+		{0x01f1, 0x01f4, 3},
+		{0x01f6, 0x01f8, 1},
+		{0x01fa, 0x0232, 2},
+		{0x023a, 0x023b, 1},
+		{0x023d, 0x023e, 1},
+		{0x0241, 0x0243, 2},
+		{0x0244, 0x0246, 1},
+		{0x0248, 0x024e, 2},
+		{0x0370, 0x0372, 2},
+		{0x0376, 0x037f, 9},
+		{0x0386, 0x0388, 2},
+		{0x0389, 0x038a, 1},
+		{0x038c, 0x038e, 2},
+		{0x038f, 0x0391, 2},
+		{0x0392, 0x03a1, 1},
+		{0x03a3, 0x03ab, 1},
+		{0x03cf, 0x03d2, 3},
+		{0x03d3, 0x03d4, 1},
+		{0x03d8, 0x03ee, 2},
+		{0x03f4, 0x03f7, 3},
+		{0x03f9, 0x03fa, 1},
+		{0x03fd, 0x042f, 1},
+		{0x0460, 0x0480, 2},
+		{0x048a, 0x04c0, 2},
+		{0x04c1, 0x04cd, 2},
+		{0x04d0, 0x052e, 2},
+		{0x0531, 0x0556, 1},
+		{0x10a0, 0x10c5, 1},
+		{0x10c7, 0x10cd, 6},
+		{0x1e00, 0x1e94, 2},
+		{0x1e9e, 0x1efe, 2},
+		{0x1f08, 0x1f0f, 1},
+		{0x1f18, 0x1f1d, 1},
+		{0x1f28, 0x1f2f, 1},
+		{0x1f38, 0x1f3f, 1},
+		{0x1f48, 0x1f4d, 1},
+		{0x1f59, 0x1f5f, 2},
+		{0x1f68, 0x1f6f, 1},
+		{0x1fb8, 0x1fbb, 1},
+		{0x1fc8, 0x1fcb, 1},
+		{0x1fd8, 0x1fdb, 1},
+		{0x1fe8, 0x1fec, 1},
+		{0x1ff8, 0x1ffb, 1},
+		{0x2102, 0x2107, 5},
+		{0x210b, 0x210d, 1},
+		{0x2110, 0x2112, 1},
+		{0x2115, 0x2119, 4},
+		{0x211a, 0x211d, 1},
+		{0x2124, 0x212a, 2},
+		{0x212b, 0x212d, 1},
+		{0x2130, 0x2133, 1},
+		{0x213e, 0x213f, 1},
+		{0x2145, 0x2183, 62},
+		{0x2c00, 0x2c2e, 1},
+		{0x2c60, 0x2c62, 2},
+		{0x2c63, 0x2c64, 1},
+		{0x2c67, 0x2c6d, 2},
+		{0x2c6e, 0x2c70, 1},
+		{0x2c72, 0x2c75, 3},
+		{0x2c7e, 0x2c80, 1},
+		{0x2c82, 0x2ce2, 2},
+		{0x2ceb, 0x2ced, 2},
+		{0x2cf2, 0xa640, 31054},
+		{0xa642, 0xa66c, 2},
+		{0xa680, 0xa69a, 2},
+		{0xa722, 0xa72e, 2},
+		{0xa732, 0xa76e, 2},
+		{0xa779, 0xa77d, 2},
+		{0xa77e, 0xa786, 2},
+		{0xa78b, 0xa78d, 2},
+		{0xa790, 0xa792, 2},
+		{0xa796, 0xa7aa, 2},
+		{0xa7ab, 0xa7ad, 1},
+		{0xa7b0, 0xa7b1, 1},
+		{0xff21, 0xff3a, 1},
+	},
+	R32: []Range32{
+		{0x10400, 0x10427, 1},
+		{0x118a0, 0x118bf, 1},
+		{0x1d400, 0x1d419, 1},
+		{0x1d434, 0x1d44d, 1},
+		{0x1d468, 0x1d481, 1},
+		{0x1d49c, 0x1d49e, 2},
+		{0x1d49f, 0x1d4a5, 3},
+		{0x1d4a6, 0x1d4a9, 3},
+		{0x1d4aa, 0x1d4ac, 1},
+		{0x1d4ae, 0x1d4b5, 1},
+		{0x1d4d0, 0x1d4e9, 1},
+		{0x1d504, 0x1d505, 1},
+		{0x1d507, 0x1d50a, 1},
+		{0x1d50d, 0x1d514, 1},
+		{0x1d516, 0x1d51c, 1},
+		{0x1d538, 0x1d539, 1},
+		{0x1d53b, 0x1d53e, 1},
+		{0x1d540, 0x1d544, 1},
+		{0x1d546, 0x1d54a, 4},
+		{0x1d54b, 0x1d550, 1},
+		{0x1d56c, 0x1d585, 1},
+		{0x1d5a0, 0x1d5b9, 1},
+		{0x1d5d4, 0x1d5ed, 1},
+		{0x1d608, 0x1d621, 1},
+		{0x1d63c, 0x1d655, 1},
+		{0x1d670, 0x1d689, 1},
+		{0x1d6a8, 0x1d6c0, 1},
+		{0x1d6e2, 0x1d6fa, 1},
+		{0x1d71c, 0x1d734, 1},
+		{0x1d756, 0x1d76e, 1},
+		{0x1d790, 0x1d7a8, 1},
+		{0x1d7ca, 0x1d7ca, 1},
+	},
+	LatinOffset: 3,
+}
+
+var _M = &RangeTable{
+	R16: []Range16{
+		{0x0300, 0x036f, 1},
+		{0x0483, 0x0489, 1},
+		{0x0591, 0x05bd, 1},
+		{0x05bf, 0x05c1, 2},
+		{0x05c2, 0x05c4, 2},
+		{0x05c5, 0x05c7, 2},
+		{0x0610, 0x061a, 1},
+		{0x064b, 0x065f, 1},
+		{0x0670, 0x06d6, 102},
+		{0x06d7, 0x06dc, 1},
+		{0x06df, 0x06e4, 1},
+		{0x06e7, 0x06e8, 1},
+		{0x06ea, 0x06ed, 1},
+		{0x0711, 0x0730, 31},
+		{0x0731, 0x074a, 1},
+		{0x07a6, 0x07b0, 1},
+		{0x07eb, 0x07f3, 1},
+		{0x0816, 0x0819, 1},
+		{0x081b, 0x0823, 1},
+		{0x0825, 0x0827, 1},
+		{0x0829, 0x082d, 1},
+		{0x0859, 0x085b, 1},
+		{0x08e4, 0x0903, 1},
+		{0x093a, 0x093c, 1},
+		{0x093e, 0x094f, 1},
+		{0x0951, 0x0957, 1},
+		{0x0962, 0x0963, 1},
+		{0x0981, 0x0983, 1},
+		{0x09bc, 0x09be, 2},
+		{0x09bf, 0x09c4, 1},
+		{0x09c7, 0x09c8, 1},
+		{0x09cb, 0x09cd, 1},
+		{0x09d7, 0x09e2, 11},
+		{0x09e3, 0x0a01, 30},
+		{0x0a02, 0x0a03, 1},
+		{0x0a3c, 0x0a3e, 2},
+		{0x0a3f, 0x0a42, 1},
+		{0x0a47, 0x0a48, 1},
+		{0x0a4b, 0x0a4d, 1},
+		{0x0a51, 0x0a70, 31},
+		{0x0a71, 0x0a75, 4},
+		{0x0a81, 0x0a83, 1},
+		{0x0abc, 0x0abe, 2},
+		{0x0abf, 0x0ac5, 1},
+		{0x0ac7, 0x0ac9, 1},
+		{0x0acb, 0x0acd, 1},
+		{0x0ae2, 0x0ae3, 1},
+		{0x0b01, 0x0b03, 1},
+		{0x0b3c, 0x0b3e, 2},
+		{0x0b3f, 0x0b44, 1},
+		{0x0b47, 0x0b48, 1},
+		{0x0b4b, 0x0b4d, 1},
+		{0x0b56, 0x0b57, 1},
+		{0x0b62, 0x0b63, 1},
+		{0x0b82, 0x0bbe, 60},
+		{0x0bbf, 0x0bc2, 1},
+		{0x0bc6, 0x0bc8, 1},
+		{0x0bca, 0x0bcd, 1},
+		{0x0bd7, 0x0c00, 41},
+		{0x0c01, 0x0c03, 1},
+		{0x0c3e, 0x0c44, 1},
+		{0x0c46, 0x0c48, 1},
+		{0x0c4a, 0x0c4d, 1},
+		{0x0c55, 0x0c56, 1},
+		{0x0c62, 0x0c63, 1},
+		{0x0c81, 0x0c83, 1},
+		{0x0cbc, 0x0cbe, 2},
+		{0x0cbf, 0x0cc4, 1},
+		{0x0cc6, 0x0cc8, 1},
+		{0x0cca, 0x0ccd, 1},
+		{0x0cd5, 0x0cd6, 1},
+		{0x0ce2, 0x0ce3, 1},
+		{0x0d01, 0x0d03, 1},
+		{0x0d3e, 0x0d44, 1},
+		{0x0d46, 0x0d48, 1},
+		{0x0d4a, 0x0d4d, 1},
+		{0x0d57, 0x0d62, 11},
+		{0x0d63, 0x0d82, 31},
+		{0x0d83, 0x0dca, 71},
+		{0x0dcf, 0x0dd4, 1},
+		{0x0dd6, 0x0dd8, 2},
+		{0x0dd9, 0x0ddf, 1},
+		{0x0df2, 0x0df3, 1},
+		{0x0e31, 0x0e34, 3},
+		{0x0e35, 0x0e3a, 1},
+		{0x0e47, 0x0e4e, 1},
+		{0x0eb1, 0x0eb4, 3},
+		{0x0eb5, 0x0eb9, 1},
+		{0x0ebb, 0x0ebc, 1},
+		{0x0ec8, 0x0ecd, 1},
+		{0x0f18, 0x0f19, 1},
+		{0x0f35, 0x0f39, 2},
+		{0x0f3e, 0x0f3f, 1},
+		{0x0f71, 0x0f84, 1},
+		{0x0f86, 0x0f87, 1},
+		{0x0f8d, 0x0f97, 1},
+		{0x0f99, 0x0fbc, 1},
+		{0x0fc6, 0x102b, 101},
+		{0x102c, 0x103e, 1},
+		{0x1056, 0x1059, 1},
+		{0x105e, 0x1060, 1},
+		{0x1062, 0x1064, 1},
+		{0x1067, 0x106d, 1},
+		{0x1071, 0x1074, 1},
+		{0x1082, 0x108d, 1},
+		{0x108f, 0x109a, 11},
+		{0x109b, 0x109d, 1},
+		{0x135d, 0x135f, 1},
+		{0x1712, 0x1714, 1},
+		{0x1732, 0x1734, 1},
+		{0x1752, 0x1753, 1},
+		{0x1772, 0x1773, 1},
+		{0x17b4, 0x17d3, 1},
+		{0x17dd, 0x180b, 46},
+		{0x180c, 0x180d, 1},
+		{0x18a9, 0x1920, 119},
+		{0x1921, 0x192b, 1},
+		{0x1930, 0x193b, 1},
+		{0x19b0, 0x19c0, 1},
+		{0x19c8, 0x19c9, 1},
+		{0x1a17, 0x1a1b, 1},
+		{0x1a55, 0x1a5e, 1},
+		{0x1a60, 0x1a7c, 1},
+		{0x1a7f, 0x1ab0, 49},
+		{0x1ab1, 0x1abe, 1},
+		{0x1b00, 0x1b04, 1},
+		{0x1b34, 0x1b44, 1},
+		{0x1b6b, 0x1b73, 1},
+		{0x1b80, 0x1b82, 1},
+		{0x1ba1, 0x1bad, 1},
+		{0x1be6, 0x1bf3, 1},
+		{0x1c24, 0x1c37, 1},
+		{0x1cd0, 0x1cd2, 1},
+		{0x1cd4, 0x1ce8, 1},
+		{0x1ced, 0x1cf2, 5},
+		{0x1cf3, 0x1cf4, 1},
+		{0x1cf8, 0x1cf9, 1},
+		{0x1dc0, 0x1df5, 1},
+		{0x1dfc, 0x1dff, 1},
+		{0x20d0, 0x20f0, 1},
+		{0x2cef, 0x2cf1, 1},
+		{0x2d7f, 0x2de0, 97},
+		{0x2de1, 0x2dff, 1},
+		{0x302a, 0x302f, 1},
+		{0x3099, 0x309a, 1},
+		{0xa66f, 0xa672, 1},
+		{0xa674, 0xa67d, 1},
+		{0xa69f, 0xa6f0, 81},
+		{0xa6f1, 0xa802, 273},
+		{0xa806, 0xa80b, 5},
+		{0xa823, 0xa827, 1},
+		{0xa880, 0xa881, 1},
+		{0xa8b4, 0xa8c4, 1},
+		{0xa8e0, 0xa8f1, 1},
+		{0xa926, 0xa92d, 1},
+		{0xa947, 0xa953, 1},
+		{0xa980, 0xa983, 1},
+		{0xa9b3, 0xa9c0, 1},
+		{0xa9e5, 0xaa29, 68},
+		{0xaa2a, 0xaa36, 1},
+		{0xaa43, 0xaa4c, 9},
+		{0xaa4d, 0xaa7b, 46},
+		{0xaa7c, 0xaa7d, 1},
+		{0xaab0, 0xaab2, 2},
+		{0xaab3, 0xaab4, 1},
+		{0xaab7, 0xaab8, 1},
+		{0xaabe, 0xaabf, 1},
+		{0xaac1, 0xaaeb, 42},
+		{0xaaec, 0xaaef, 1},
+		{0xaaf5, 0xaaf6, 1},
+		{0xabe3, 0xabea, 1},
+		{0xabec, 0xabed, 1},
+		{0xfb1e, 0xfe00, 738},
+		{0xfe01, 0xfe0f, 1},
+		{0xfe20, 0xfe2d, 1},
+	},
+	R32: []Range32{
+		{0x101fd, 0x102e0, 227},
+		{0x10376, 0x1037a, 1},
+		{0x10a01, 0x10a03, 1},
+		{0x10a05, 0x10a06, 1},
+		{0x10a0c, 0x10a0f, 1},
+		{0x10a38, 0x10a3a, 1},
+		{0x10a3f, 0x10ae5, 166},
+		{0x10ae6, 0x11000, 1306},
+		{0x11001, 0x11002, 1},
+		{0x11038, 0x11046, 1},
+		{0x1107f, 0x11082, 1},
+		{0x110b0, 0x110ba, 1},
+		{0x11100, 0x11102, 1},
+		{0x11127, 0x11134, 1},
+		{0x11173, 0x11180, 13},
+		{0x11181, 0x11182, 1},
+		{0x111b3, 0x111c0, 1},
+		{0x1122c, 0x11237, 1},
+		{0x112df, 0x112ea, 1},
+		{0x11301, 0x11303, 1},
+		{0x1133c, 0x1133e, 2},
+		{0x1133f, 0x11344, 1},
+		{0x11347, 0x11348, 1},
+		{0x1134b, 0x1134d, 1},
+		{0x11357, 0x11362, 11},
+		{0x11363, 0x11366, 3},
+		{0x11367, 0x1136c, 1},
+		{0x11370, 0x11374, 1},
+		{0x114b0, 0x114c3, 1},
+		{0x115af, 0x115b5, 1},
+		{0x115b8, 0x115c0, 1},
+		{0x11630, 0x11640, 1},
+		{0x116ab, 0x116b7, 1},
+		{0x16af0, 0x16af4, 1},
+		{0x16b30, 0x16b36, 1},
+		{0x16f51, 0x16f7e, 1},
+		{0x16f8f, 0x16f92, 1},
+		{0x1bc9d, 0x1bc9e, 1},
+		{0x1d165, 0x1d169, 1},
+		{0x1d16d, 0x1d172, 1},
+		{0x1d17b, 0x1d182, 1},
+		{0x1d185, 0x1d18b, 1},
+		{0x1d1aa, 0x1d1ad, 1},
+		{0x1d242, 0x1d244, 1},
+		{0x1e8d0, 0x1e8d6, 1},
+		{0xe0100, 0xe01ef, 1},
+	},
+}
+
+var _Mc = &RangeTable{
+	R16: []Range16{
+		{0x0903, 0x093b, 56},
+		{0x093e, 0x0940, 1},
+		{0x0949, 0x094c, 1},
+		{0x094e, 0x094f, 1},
+		{0x0982, 0x0983, 1},
+		{0x09be, 0x09c0, 1},
+		{0x09c7, 0x09c8, 1},
+		{0x09cb, 0x09cc, 1},
+		{0x09d7, 0x0a03, 44},
+		{0x0a3e, 0x0a40, 1},
+		{0x0a83, 0x0abe, 59},
+		{0x0abf, 0x0ac0, 1},
+		{0x0ac9, 0x0acb, 2},
+		{0x0acc, 0x0b02, 54},
+		{0x0b03, 0x0b3e, 59},
+		{0x0b40, 0x0b47, 7},
+		{0x0b48, 0x0b4b, 3},
+		{0x0b4c, 0x0b57, 11},
+		{0x0bbe, 0x0bbf, 1},
+		{0x0bc1, 0x0bc2, 1},
+		{0x0bc6, 0x0bc8, 1},
+		{0x0bca, 0x0bcc, 1},
+		{0x0bd7, 0x0c01, 42},
+		{0x0c02, 0x0c03, 1},
+		{0x0c41, 0x0c44, 1},
+		{0x0c82, 0x0c83, 1},
+		{0x0cbe, 0x0cc0, 2},
+		{0x0cc1, 0x0cc4, 1},
+		{0x0cc7, 0x0cc8, 1},
+		{0x0cca, 0x0ccb, 1},
+		{0x0cd5, 0x0cd6, 1},
+		{0x0d02, 0x0d03, 1},
+		{0x0d3e, 0x0d40, 1},
+		{0x0d46, 0x0d48, 1},
+		{0x0d4a, 0x0d4c, 1},
+		{0x0d57, 0x0d82, 43},
+		{0x0d83, 0x0dcf, 76},
+		{0x0dd0, 0x0dd1, 1},
+		{0x0dd8, 0x0ddf, 1},
+		{0x0df2, 0x0df3, 1},
+		{0x0f3e, 0x0f3f, 1},
+		{0x0f7f, 0x102b, 172},
+		{0x102c, 0x1031, 5},
+		{0x1038, 0x103b, 3},
+		{0x103c, 0x1056, 26},
+		{0x1057, 0x1062, 11},
+		{0x1063, 0x1064, 1},
+		{0x1067, 0x106d, 1},
+		{0x1083, 0x1084, 1},
+		{0x1087, 0x108c, 1},
+		{0x108f, 0x109a, 11},
+		{0x109b, 0x109c, 1},
+		{0x17b6, 0x17be, 8},
+		{0x17bf, 0x17c5, 1},
+		{0x17c7, 0x17c8, 1},
+		{0x1923, 0x1926, 1},
+		{0x1929, 0x192b, 1},
+		{0x1930, 0x1931, 1},
+		{0x1933, 0x1938, 1},
+		{0x19b0, 0x19c0, 1},
+		{0x19c8, 0x19c9, 1},
+		{0x1a19, 0x1a1a, 1},
+		{0x1a55, 0x1a57, 2},
+		{0x1a61, 0x1a63, 2},
+		{0x1a64, 0x1a6d, 9},
+		{0x1a6e, 0x1a72, 1},
+		{0x1b04, 0x1b35, 49},
+		{0x1b3b, 0x1b3d, 2},
+		{0x1b3e, 0x1b41, 1},
+		{0x1b43, 0x1b44, 1},
+		{0x1b82, 0x1ba1, 31},
+		{0x1ba6, 0x1ba7, 1},
+		{0x1baa, 0x1be7, 61},
+		{0x1bea, 0x1bec, 1},
+		{0x1bee, 0x1bf2, 4},
+		{0x1bf3, 0x1c24, 49},
+		{0x1c25, 0x1c2b, 1},
+		{0x1c34, 0x1c35, 1},
+		{0x1ce1, 0x1cf2, 17},
+		{0x1cf3, 0x302e, 4923},
+		{0x302f, 0xa823, 30708},
+		{0xa824, 0xa827, 3},
+		{0xa880, 0xa881, 1},
+		{0xa8b4, 0xa8c3, 1},
+		{0xa952, 0xa953, 1},
+		{0xa983, 0xa9b4, 49},
+		{0xa9b5, 0xa9ba, 5},
+		{0xa9bb, 0xa9bd, 2},
+		{0xa9be, 0xa9c0, 1},
+		{0xaa2f, 0xaa30, 1},
+		{0xaa33, 0xaa34, 1},
+		{0xaa4d, 0xaa7b, 46},
+		{0xaa7d, 0xaaeb, 110},
+		{0xaaee, 0xaaef, 1},
+		{0xaaf5, 0xabe3, 238},
+		{0xabe4, 0xabe6, 2},
+		{0xabe7, 0xabe9, 2},
+		{0xabea, 0xabec, 2},
+	},
+	R32: []Range32{
+		{0x11000, 0x11002, 2},
+		{0x11082, 0x110b0, 46},
+		{0x110b1, 0x110b2, 1},
+		{0x110b7, 0x110b8, 1},
+		{0x1112c, 0x11182, 86},
+		{0x111b3, 0x111b5, 1},
+		{0x111bf, 0x111c0, 1},
+		{0x1122c, 0x1122e, 1},
+		{0x11232, 0x11233, 1},
+		{0x11235, 0x112e0, 171},
+		{0x112e1, 0x112e2, 1},
+		{0x11302, 0x11303, 1},
+		{0x1133e, 0x1133f, 1},
+		{0x11341, 0x11344, 1},
+		{0x11347, 0x11348, 1},
+		{0x1134b, 0x1134d, 1},
+		{0x11357, 0x11362, 11},
+		{0x11363, 0x114b0, 333},
+		{0x114b1, 0x114b2, 1},
+		{0x114b9, 0x114bb, 2},
+		{0x114bc, 0x114be, 1},
+		{0x114c1, 0x115af, 238},
+		{0x115b0, 0x115b1, 1},
+		{0x115b8, 0x115bb, 1},
+		{0x115be, 0x11630, 114},
+		{0x11631, 0x11632, 1},
+		{0x1163b, 0x1163c, 1},
+		{0x1163e, 0x116ac, 110},
+		{0x116ae, 0x116af, 1},
+		{0x116b6, 0x16f51, 22683},
+		{0x16f52, 0x16f7e, 1},
+		{0x1d165, 0x1d166, 1},
+		{0x1d16d, 0x1d172, 1},
+	},
+}
+
+var _Me = &RangeTable{
+	R16: []Range16{
+		{0x0488, 0x0489, 1},
+		{0x1abe, 0x20dd, 1567},
+		{0x20de, 0x20e0, 1},
+		{0x20e2, 0x20e4, 1},
+		{0xa670, 0xa672, 1},
+	},
+}
+
+var _Mn = &RangeTable{
+	R16: []Range16{
+		{0x0300, 0x036f, 1},
+		{0x0483, 0x0487, 1},
+		{0x0591, 0x05bd, 1},
+		{0x05bf, 0x05c1, 2},
+		{0x05c2, 0x05c4, 2},
+		{0x05c5, 0x05c7, 2},
+		{0x0610, 0x061a, 1},
+		{0x064b, 0x065f, 1},
+		{0x0670, 0x06d6, 102},
+		{0x06d7, 0x06dc, 1},
+		{0x06df, 0x06e4, 1},
+		{0x06e7, 0x06e8, 1},
+		{0x06ea, 0x06ed, 1},
+		{0x0711, 0x0730, 31},
+		{0x0731, 0x074a, 1},
+		{0x07a6, 0x07b0, 1},
+		{0x07eb, 0x07f3, 1},
+		{0x0816, 0x0819, 1},
+		{0x081b, 0x0823, 1},
+		{0x0825, 0x0827, 1},
+		{0x0829, 0x082d, 1},
+		{0x0859, 0x085b, 1},
+		{0x08e4, 0x0902, 1},
+		{0x093a, 0x093c, 2},
+		{0x0941, 0x0948, 1},
+		{0x094d, 0x0951, 4},
+		{0x0952, 0x0957, 1},
+		{0x0962, 0x0963, 1},
+		{0x0981, 0x09bc, 59},
+		{0x09c1, 0x09c4, 1},
+		{0x09cd, 0x09e2, 21},
+		{0x09e3, 0x0a01, 30},
+		{0x0a02, 0x0a3c, 58},
+		{0x0a41, 0x0a42, 1},
+		{0x0a47, 0x0a48, 1},
+		{0x0a4b, 0x0a4d, 1},
+		{0x0a51, 0x0a70, 31},
+		{0x0a71, 0x0a75, 4},
+		{0x0a81, 0x0a82, 1},
+		{0x0abc, 0x0ac1, 5},
+		{0x0ac2, 0x0ac5, 1},
+		{0x0ac7, 0x0ac8, 1},
+		{0x0acd, 0x0ae2, 21},
+		{0x0ae3, 0x0b01, 30},
+		{0x0b3c, 0x0b3f, 3},
+		{0x0b41, 0x0b44, 1},
+		{0x0b4d, 0x0b56, 9},
+		{0x0b62, 0x0b63, 1},
+		{0x0b82, 0x0bc0, 62},
+		{0x0bcd, 0x0c00, 51},
+		{0x0c3e, 0x0c40, 1},
+		{0x0c46, 0x0c48, 1},
+		{0x0c4a, 0x0c4d, 1},
+		{0x0c55, 0x0c56, 1},
+		{0x0c62, 0x0c63, 1},
+		{0x0c81, 0x0cbc, 59},
+		{0x0cbf, 0x0cc6, 7},
+		{0x0ccc, 0x0ccd, 1},
+		{0x0ce2, 0x0ce3, 1},
+		{0x0d01, 0x0d41, 64},
+		{0x0d42, 0x0d44, 1},
+		{0x0d4d, 0x0d62, 21},
+		{0x0d63, 0x0dca, 103},
+		{0x0dd2, 0x0dd4, 1},
+		{0x0dd6, 0x0e31, 91},
+		{0x0e34, 0x0e3a, 1},
+		{0x0e47, 0x0e4e, 1},
+		{0x0eb1, 0x0eb4, 3},
+		{0x0eb5, 0x0eb9, 1},
+		{0x0ebb, 0x0ebc, 1},
+		{0x0ec8, 0x0ecd, 1},
+		{0x0f18, 0x0f19, 1},
+		{0x0f35, 0x0f39, 2},
+		{0x0f71, 0x0f7e, 1},
+		{0x0f80, 0x0f84, 1},
+		{0x0f86, 0x0f87, 1},
+		{0x0f8d, 0x0f97, 1},
+		{0x0f99, 0x0fbc, 1},
+		{0x0fc6, 0x102d, 103},
+		{0x102e, 0x1030, 1},
+		{0x1032, 0x1037, 1},
+		{0x1039, 0x103a, 1},
+		{0x103d, 0x103e, 1},
+		{0x1058, 0x1059, 1},
+		{0x105e, 0x1060, 1},
+		{0x1071, 0x1074, 1},
+		{0x1082, 0x1085, 3},
+		{0x1086, 0x108d, 7},
+		{0x109d, 0x135d, 704},
+		{0x135e, 0x135f, 1},
+		{0x1712, 0x1714, 1},
+		{0x1732, 0x1734, 1},
+		{0x1752, 0x1753, 1},
+		{0x1772, 0x1773, 1},
+		{0x17b4, 0x17b5, 1},
+		{0x17b7, 0x17bd, 1},
+		{0x17c6, 0x17c9, 3},
+		{0x17ca, 0x17d3, 1},
+		{0x17dd, 0x180b, 46},
+		{0x180c, 0x180d, 1},
+		{0x18a9, 0x1920, 119},
+		{0x1921, 0x1922, 1},
+		{0x1927, 0x1928, 1},
+		{0x1932, 0x1939, 7},
+		{0x193a, 0x193b, 1},
+		{0x1a17, 0x1a18, 1},
+		{0x1a1b, 0x1a56, 59},
+		{0x1a58, 0x1a5e, 1},
+		{0x1a60, 0x1a62, 2},
+		{0x1a65, 0x1a6c, 1},
+		{0x1a73, 0x1a7c, 1},
+		{0x1a7f, 0x1ab0, 49},
+		{0x1ab1, 0x1abd, 1},
+		{0x1b00, 0x1b03, 1},
+		{0x1b34, 0x1b36, 2},
+		{0x1b37, 0x1b3a, 1},
+		{0x1b3c, 0x1b42, 6},
+		{0x1b6b, 0x1b73, 1},
+		{0x1b80, 0x1b81, 1},
+		{0x1ba2, 0x1ba5, 1},
+		{0x1ba8, 0x1ba9, 1},
+		{0x1bab, 0x1bad, 1},
+		{0x1be6, 0x1be8, 2},
+		{0x1be9, 0x1bed, 4},
+		{0x1bef, 0x1bf1, 1},
+		{0x1c2c, 0x1c33, 1},
+		{0x1c36, 0x1c37, 1},
+		{0x1cd0, 0x1cd2, 1},
+		{0x1cd4, 0x1ce0, 1},
+		{0x1ce2, 0x1ce8, 1},
+		{0x1ced, 0x1cf4, 7},
+		{0x1cf8, 0x1cf9, 1},
+		{0x1dc0, 0x1df5, 1},
+		{0x1dfc, 0x1dff, 1},
+		{0x20d0, 0x20dc, 1},
+		{0x20e1, 0x20e5, 4},
+		{0x20e6, 0x20f0, 1},
+		{0x2cef, 0x2cf1, 1},
+		{0x2d7f, 0x2de0, 97},
+		{0x2de1, 0x2dff, 1},
+		{0x302a, 0x302d, 1},
+		{0x3099, 0x309a, 1},
+		{0xa66f, 0xa674, 5},
+		{0xa675, 0xa67d, 1},
+		{0xa69f, 0xa6f0, 81},
+		{0xa6f1, 0xa802, 273},
+		{0xa806, 0xa80b, 5},
+		{0xa825, 0xa826, 1},
+		{0xa8c4, 0xa8e0, 28},
+		{0xa8e1, 0xa8f1, 1},
+		{0xa926, 0xa92d, 1},
+		{0xa947, 0xa951, 1},
+		{0xa980, 0xa982, 1},
+		{0xa9b3, 0xa9b6, 3},
+		{0xa9b7, 0xa9b9, 1},
+		{0xa9bc, 0xa9e5, 41},
+		{0xaa29, 0xaa2e, 1},
+		{0xaa31, 0xaa32, 1},
+		{0xaa35, 0xaa36, 1},
+		{0xaa43, 0xaa4c, 9},
+		{0xaa7c, 0xaab0, 52},
+		{0xaab2, 0xaab4, 1},
+		{0xaab7, 0xaab8, 1},
+		{0xaabe, 0xaabf, 1},
+		{0xaac1, 0xaaec, 43},
+		{0xaaed, 0xaaf6, 9},
+		{0xabe5, 0xabe8, 3},
+		{0xabed, 0xfb1e, 20273},
+		{0xfe00, 0xfe0f, 1},
+		{0xfe20, 0xfe2d, 1},
+	},
+	R32: []Range32{
+		{0x101fd, 0x102e0, 227},
+		{0x10376, 0x1037a, 1},
+		{0x10a01, 0x10a03, 1},
+		{0x10a05, 0x10a06, 1},
+		{0x10a0c, 0x10a0f, 1},
+		{0x10a38, 0x10a3a, 1},
+		{0x10a3f, 0x10ae5, 166},
+		{0x10ae6, 0x11001, 1307},
+		{0x11038, 0x11046, 1},
+		{0x1107f, 0x11081, 1},
+		{0x110b3, 0x110b6, 1},
+		{0x110b9, 0x110ba, 1},
+		{0x11100, 0x11102, 1},
+		{0x11127, 0x1112b, 1},
+		{0x1112d, 0x11134, 1},
+		{0x11173, 0x11180, 13},
+		{0x11181, 0x111b6, 53},
+		{0x111b7, 0x111be, 1},
+		{0x1122f, 0x11231, 1},
+		{0x11234, 0x11236, 2},
+		{0x11237, 0x112df, 168},
+		{0x112e3, 0x112ea, 1},
+		{0x11301, 0x1133c, 59},
+		{0x11340, 0x11366, 38},
+		{0x11367, 0x1136c, 1},
+		{0x11370, 0x11374, 1},
+		{0x114b3, 0x114b8, 1},
+		{0x114ba, 0x114bf, 5},
+		{0x114c0, 0x114c2, 2},
+		{0x114c3, 0x115b2, 239},
+		{0x115b3, 0x115b5, 1},
+		{0x115bc, 0x115bd, 1},
+		{0x115bf, 0x115c0, 1},
+		{0x11633, 0x1163a, 1},
+		{0x1163d, 0x1163f, 2},
+		{0x11640, 0x116ab, 107},
+		{0x116ad, 0x116b0, 3},
+		{0x116b1, 0x116b5, 1},
+		{0x116b7, 0x16af0, 21561},
+		{0x16af1, 0x16af4, 1},
+		{0x16b30, 0x16b36, 1},
+		{0x16f8f, 0x16f92, 1},
+		{0x1bc9d, 0x1bc9e, 1},
+		{0x1d167, 0x1d169, 1},
+		{0x1d17b, 0x1d182, 1},
+		{0x1d185, 0x1d18b, 1},
+		{0x1d1aa, 0x1d1ad, 1},
+		{0x1d242, 0x1d244, 1},
+		{0x1e8d0, 0x1e8d6, 1},
+		{0xe0100, 0xe01ef, 1},
+	},
+}
+
+var _N = &RangeTable{
+	R16: []Range16{
+		{0x0030, 0x0039, 1},
+		{0x00b2, 0x00b3, 1},
+		{0x00b9, 0x00bc, 3},
+		{0x00bd, 0x00be, 1},
+		{0x0660, 0x0669, 1},
+		{0x06f0, 0x06f9, 1},
+		{0x07c0, 0x07c9, 1},
+		{0x0966, 0x096f, 1},
+		{0x09e6, 0x09ef, 1},
+		{0x09f4, 0x09f9, 1},
+		{0x0a66, 0x0a6f, 1},
+		{0x0ae6, 0x0aef, 1},
+		{0x0b66, 0x0b6f, 1},
+		{0x0b72, 0x0b77, 1},
+		{0x0be6, 0x0bf2, 1},
+		{0x0c66, 0x0c6f, 1},
+		{0x0c78, 0x0c7e, 1},
+		{0x0ce6, 0x0cef, 1},
+		{0x0d66, 0x0d75, 1},
+		{0x0de6, 0x0def, 1},
+		{0x0e50, 0x0e59, 1},
+		{0x0ed0, 0x0ed9, 1},
+		{0x0f20, 0x0f33, 1},
+		{0x1040, 0x1049, 1},
+		{0x1090, 0x1099, 1},
+		{0x1369, 0x137c, 1},
+		{0x16ee, 0x16f0, 1},
+		{0x17e0, 0x17e9, 1},
+		{0x17f0, 0x17f9, 1},
+		{0x1810, 0x1819, 1},
+		{0x1946, 0x194f, 1},
+		{0x19d0, 0x19da, 1},
+		{0x1a80, 0x1a89, 1},
+		{0x1a90, 0x1a99, 1},
+		{0x1b50, 0x1b59, 1},
+		{0x1bb0, 0x1bb9, 1},
+		{0x1c40, 0x1c49, 1},
+		{0x1c50, 0x1c59, 1},
+		{0x2070, 0x2074, 4},
+		{0x2075, 0x2079, 1},
+		{0x2080, 0x2089, 1},
+		{0x2150, 0x2182, 1},
+		{0x2185, 0x2189, 1},
+		{0x2460, 0x249b, 1},
+		{0x24ea, 0x24ff, 1},
+		{0x2776, 0x2793, 1},
+		{0x2cfd, 0x3007, 778},
+		{0x3021, 0x3029, 1},
+		{0x3038, 0x303a, 1},
+		{0x3192, 0x3195, 1},
+		{0x3220, 0x3229, 1},
+		{0x3248, 0x324f, 1},
+		{0x3251, 0x325f, 1},
+		{0x3280, 0x3289, 1},
+		{0x32b1, 0x32bf, 1},
+		{0xa620, 0xa629, 1},
+		{0xa6e6, 0xa6ef, 1},
+		{0xa830, 0xa835, 1},
+		{0xa8d0, 0xa8d9, 1},
+		{0xa900, 0xa909, 1},
+		{0xa9d0, 0xa9d9, 1},
+		{0xa9f0, 0xa9f9, 1},
+		{0xaa50, 0xaa59, 1},
+		{0xabf0, 0xabf9, 1},
+		{0xff10, 0xff19, 1},
+	},
+	R32: []Range32{
+		{0x10107, 0x10133, 1},
+		{0x10140, 0x10178, 1},
+		{0x1018a, 0x1018b, 1},
+		{0x102e1, 0x102fb, 1},
+		{0x10320, 0x10323, 1},
+		{0x10341, 0x1034a, 9},
+		{0x103d1, 0x103d5, 1},
+		{0x104a0, 0x104a9, 1},
+		{0x10858, 0x1085f, 1},
+		{0x10879, 0x1087f, 1},
+		{0x108a7, 0x108af, 1},
+		{0x10916, 0x1091b, 1},
+		{0x10a40, 0x10a47, 1},
+		{0x10a7d, 0x10a7e, 1},
+		{0x10a9d, 0x10a9f, 1},
+		{0x10aeb, 0x10aef, 1},
+		{0x10b58, 0x10b5f, 1},
+		{0x10b78, 0x10b7f, 1},
+		{0x10ba9, 0x10baf, 1},
+		{0x10e60, 0x10e7e, 1},
+		{0x11052, 0x1106f, 1},
+		{0x110f0, 0x110f9, 1},
+		{0x11136, 0x1113f, 1},
+		{0x111d0, 0x111d9, 1},
+		{0x111e1, 0x111f4, 1},
+		{0x112f0, 0x112f9, 1},
+		{0x114d0, 0x114d9, 1},
+		{0x11650, 0x11659, 1},
+		{0x116c0, 0x116c9, 1},
+		{0x118e0, 0x118f2, 1},
+		{0x12400, 0x1246e, 1},
+		{0x16a60, 0x16a69, 1},
+		{0x16b50, 0x16b59, 1},
+		{0x16b5b, 0x16b61, 1},
+		{0x1d360, 0x1d371, 1},
+		{0x1d7ce, 0x1d7ff, 1},
+		{0x1e8c7, 0x1e8cf, 1},
+		{0x1f100, 0x1f10c, 1},
+	},
+	LatinOffset: 4,
+}
+
+var _Nd = &RangeTable{
+	R16: []Range16{
+		{0x0030, 0x0039, 1},
+		{0x0660, 0x0669, 1},
+		{0x06f0, 0x06f9, 1},
+		{0x07c0, 0x07c9, 1},
+		{0x0966, 0x096f, 1},
+		{0x09e6, 0x09ef, 1},
+		{0x0a66, 0x0a6f, 1},
+		{0x0ae6, 0x0aef, 1},
+		{0x0b66, 0x0b6f, 1},
+		{0x0be6, 0x0bef, 1},
+		{0x0c66, 0x0c6f, 1},
+		{0x0ce6, 0x0cef, 1},
+		{0x0d66, 0x0d6f, 1},
+		{0x0de6, 0x0def, 1},
+		{0x0e50, 0x0e59, 1},
+		{0x0ed0, 0x0ed9, 1},
+		{0x0f20, 0x0f29, 1},
+		{0x1040, 0x1049, 1},
+		{0x1090, 0x1099, 1},
+		{0x17e0, 0x17e9, 1},
+		{0x1810, 0x1819, 1},
+		{0x1946, 0x194f, 1},
+		{0x19d0, 0x19d9, 1},
+		{0x1a80, 0x1a89, 1},
+		{0x1a90, 0x1a99, 1},
+		{0x1b50, 0x1b59, 1},
+		{0x1bb0, 0x1bb9, 1},
+		{0x1c40, 0x1c49, 1},
+		{0x1c50, 0x1c59, 1},
+		{0xa620, 0xa629, 1},
+		{0xa8d0, 0xa8d9, 1},
+		{0xa900, 0xa909, 1},
+		{0xa9d0, 0xa9d9, 1},
+		{0xa9f0, 0xa9f9, 1},
+		{0xaa50, 0xaa59, 1},
+		{0xabf0, 0xabf9, 1},
+		{0xff10, 0xff19, 1},
+	},
+	R32: []Range32{
+		{0x104a0, 0x104a9, 1},
+		{0x11066, 0x1106f, 1},
+		{0x110f0, 0x110f9, 1},
+		{0x11136, 0x1113f, 1},
+		{0x111d0, 0x111d9, 1},
+		{0x112f0, 0x112f9, 1},
+		{0x114d0, 0x114d9, 1},
+		{0x11650, 0x11659, 1},
+		{0x116c0, 0x116c9, 1},
+		{0x118e0, 0x118e9, 1},
+		{0x16a60, 0x16a69, 1},
+		{0x16b50, 0x16b59, 1},
+		{0x1d7ce, 0x1d7ff, 1},
+	},
+	LatinOffset: 1,
+}
+
+var _Nl = &RangeTable{
+	R16: []Range16{
+		{0x16ee, 0x16f0, 1},
+		{0x2160, 0x2182, 1},
+		{0x2185, 0x2188, 1},
+		{0x3007, 0x3021, 26},
+		{0x3022, 0x3029, 1},
+		{0x3038, 0x303a, 1},
+		{0xa6e6, 0xa6ef, 1},
+	},
+	R32: []Range32{
+		{0x10140, 0x10174, 1},
+		{0x10341, 0x1034a, 9},
+		{0x103d1, 0x103d5, 1},
+		{0x12400, 0x1246e, 1},
+	},
+}
+
+var _No = &RangeTable{
+	R16: []Range16{
+		{0x00b2, 0x00b3, 1},
+		{0x00b9, 0x00bc, 3},
+		{0x00bd, 0x00be, 1},
+		{0x09f4, 0x09f9, 1},
+		{0x0b72, 0x0b77, 1},
+		{0x0bf0, 0x0bf2, 1},
+		{0x0c78, 0x0c7e, 1},
+		{0x0d70, 0x0d75, 1},
+		{0x0f2a, 0x0f33, 1},
+		{0x1369, 0x137c, 1},
+		{0x17f0, 0x17f9, 1},
+		{0x19da, 0x2070, 1686},
+		{0x2074, 0x2079, 1},
+		{0x2080, 0x2089, 1},
+		{0x2150, 0x215f, 1},
+		{0x2189, 0x2460, 727},
+		{0x2461, 0x249b, 1},
+		{0x24ea, 0x24ff, 1},
+		{0x2776, 0x2793, 1},
+		{0x2cfd, 0x3192, 1173},
+		{0x3193, 0x3195, 1},
+		{0x3220, 0x3229, 1},
+		{0x3248, 0x324f, 1},
+		{0x3251, 0x325f, 1},
+		{0x3280, 0x3289, 1},
+		{0x32b1, 0x32bf, 1},
+		{0xa830, 0xa835, 1},
+	},
+	R32: []Range32{
+		{0x10107, 0x10133, 1},
+		{0x10175, 0x10178, 1},
+		{0x1018a, 0x1018b, 1},
+		{0x102e1, 0x102fb, 1},
+		{0x10320, 0x10323, 1},
+		{0x10858, 0x1085f, 1},
+		{0x10879, 0x1087f, 1},
+		{0x108a7, 0x108af, 1},
+		{0x10916, 0x1091b, 1},
+		{0x10a40, 0x10a47, 1},
+		{0x10a7d, 0x10a7e, 1},
+		{0x10a9d, 0x10a9f, 1},
+		{0x10aeb, 0x10aef, 1},
+		{0x10b58, 0x10b5f, 1},
+		{0x10b78, 0x10b7f, 1},
+		{0x10ba9, 0x10baf, 1},
+		{0x10e60, 0x10e7e, 1},
+		{0x11052, 0x11065, 1},
+		{0x111e1, 0x111f4, 1},
+		{0x118ea, 0x118f2, 1},
+		{0x16b5b, 0x16b61, 1},
+		{0x1d360, 0x1d371, 1},
+		{0x1e8c7, 0x1e8cf, 1},
+		{0x1f100, 0x1f10c, 1},
+	},
+	LatinOffset: 3,
+}
+
+var _P = &RangeTable{
+	R16: []Range16{
+		{0x0021, 0x0023, 1},
+		{0x0025, 0x002a, 1},
+		{0x002c, 0x002f, 1},
+		{0x003a, 0x003b, 1},
+		{0x003f, 0x0040, 1},
+		{0x005b, 0x005d, 1},
+		{0x005f, 0x007b, 28},
+		{0x007d, 0x00a1, 36},
+		{0x00a7, 0x00ab, 4},
+		{0x00b6, 0x00b7, 1},
+		{0x00bb, 0x00bf, 4},
+		{0x037e, 0x0387, 9},
+		{0x055a, 0x055f, 1},
+		{0x0589, 0x058a, 1},
+		{0x05be, 0x05c0, 2},
+		{0x05c3, 0x05c6, 3},
+		{0x05f3, 0x05f4, 1},
+		{0x0609, 0x060a, 1},
+		{0x060c, 0x060d, 1},
+		{0x061b, 0x061e, 3},
+		{0x061f, 0x066a, 75},
+		{0x066b, 0x066d, 1},
+		{0x06d4, 0x0700, 44},
+		{0x0701, 0x070d, 1},
+		{0x07f7, 0x07f9, 1},
+		{0x0830, 0x083e, 1},
+		{0x085e, 0x0964, 262},
+		{0x0965, 0x0970, 11},
+		{0x0af0, 0x0df4, 772},
+		{0x0e4f, 0x0e5a, 11},
+		{0x0e5b, 0x0f04, 169},
+		{0x0f05, 0x0f12, 1},
+		{0x0f14, 0x0f3a, 38},
+		{0x0f3b, 0x0f3d, 1},
+		{0x0f85, 0x0fd0, 75},
+		{0x0fd1, 0x0fd4, 1},
+		{0x0fd9, 0x0fda, 1},
+		{0x104a, 0x104f, 1},
+		{0x10fb, 0x1360, 613},
+		{0x1361, 0x1368, 1},
+		{0x1400, 0x166d, 621},
+		{0x166e, 0x169b, 45},
+		{0x169c, 0x16eb, 79},
+		{0x16ec, 0x16ed, 1},
+		{0x1735, 0x1736, 1},
+		{0x17d4, 0x17d6, 1},
+		{0x17d8, 0x17da, 1},
+		{0x1800, 0x180a, 1},
+		{0x1944, 0x1945, 1},
+		{0x1a1e, 0x1a1f, 1},
+		{0x1aa0, 0x1aa6, 1},
+		{0x1aa8, 0x1aad, 1},
+		{0x1b5a, 0x1b60, 1},
+		{0x1bfc, 0x1bff, 1},
+		{0x1c3b, 0x1c3f, 1},
+		{0x1c7e, 0x1c7f, 1},
+		{0x1cc0, 0x1cc7, 1},
+		{0x1cd3, 0x2010, 829},
+		{0x2011, 0x2027, 1},
+		{0x2030, 0x2043, 1},
+		{0x2045, 0x2051, 1},
+		{0x2053, 0x205e, 1},
+		{0x207d, 0x207e, 1},
+		{0x208d, 0x208e, 1},
+		{0x2308, 0x230b, 1},
+		{0x2329, 0x232a, 1},
+		{0x2768, 0x2775, 1},
+		{0x27c5, 0x27c6, 1},
+		{0x27e6, 0x27ef, 1},
+		{0x2983, 0x2998, 1},
+		{0x29d8, 0x29db, 1},
+		{0x29fc, 0x29fd, 1},
+		{0x2cf9, 0x2cfc, 1},
+		{0x2cfe, 0x2cff, 1},
+		{0x2d70, 0x2e00, 144},
+		{0x2e01, 0x2e2e, 1},
+		{0x2e30, 0x2e42, 1},
+		{0x3001, 0x3003, 1},
+		{0x3008, 0x3011, 1},
+		{0x3014, 0x301f, 1},
+		{0x3030, 0x303d, 13},
+		{0x30a0, 0x30fb, 91},
+		{0xa4fe, 0xa4ff, 1},
+		{0xa60d, 0xa60f, 1},
+		{0xa673, 0xa67e, 11},
+		{0xa6f2, 0xa6f7, 1},
+		{0xa874, 0xa877, 1},
+		{0xa8ce, 0xa8cf, 1},
+		{0xa8f8, 0xa8fa, 1},
+		{0xa92e, 0xa92f, 1},
+		{0xa95f, 0xa9c1, 98},
+		{0xa9c2, 0xa9cd, 1},
+		{0xa9de, 0xa9df, 1},
+		{0xaa5c, 0xaa5f, 1},
+		{0xaade, 0xaadf, 1},
+		{0xaaf0, 0xaaf1, 1},
+		{0xabeb, 0xfd3e, 20819},
+		{0xfd3f, 0xfe10, 209},
+		{0xfe11, 0xfe19, 1},
+		{0xfe30, 0xfe52, 1},
+		{0xfe54, 0xfe61, 1},
+		{0xfe63, 0xfe68, 5},
+		{0xfe6a, 0xfe6b, 1},
+		{0xff01, 0xff03, 1},
+		{0xff05, 0xff0a, 1},
+		{0xff0c, 0xff0f, 1},
+		{0xff1a, 0xff1b, 1},
+		{0xff1f, 0xff20, 1},
+		{0xff3b, 0xff3d, 1},
+		{0xff3f, 0xff5b, 28},
+		{0xff5d, 0xff5f, 2},
+		{0xff60, 0xff65, 1},
+	},
+	R32: []Range32{
+		{0x10100, 0x10102, 1},
+		{0x1039f, 0x103d0, 49},
+		{0x1056f, 0x10857, 744},
+		{0x1091f, 0x1093f, 32},
+		{0x10a50, 0x10a58, 1},
+		{0x10a7f, 0x10af0, 113},
+		{0x10af1, 0x10af6, 1},
+		{0x10b39, 0x10b3f, 1},
+		{0x10b99, 0x10b9c, 1},
+		{0x11047, 0x1104d, 1},
+		{0x110bb, 0x110bc, 1},
+		{0x110be, 0x110c1, 1},
+		{0x11140, 0x11143, 1},
+		{0x11174, 0x11175, 1},
+		{0x111c5, 0x111c8, 1},
+		{0x111cd, 0x11238, 107},
+		{0x11239, 0x1123d, 1},
+		{0x114c6, 0x115c1, 251},
+		{0x115c2, 0x115c9, 1},
+		{0x11641, 0x11643, 1},
+		{0x12470, 0x12474, 1},
+		{0x16a6e, 0x16a6f, 1},
+		{0x16af5, 0x16b37, 66},
+		{0x16b38, 0x16b3b, 1},
+		{0x16b44, 0x1bc9f, 20827},
+	},
+	LatinOffset: 11,
+}
+
+var _Pc = &RangeTable{
+	R16: []Range16{
+		{0x005f, 0x203f, 8160},
+		{0x2040, 0x2054, 20},
+		{0xfe33, 0xfe34, 1},
+		{0xfe4d, 0xfe4f, 1},
+		{0xff3f, 0xff3f, 1},
+	},
+}
+
+var _Pd = &RangeTable{
+	R16: []Range16{
+		{0x002d, 0x058a, 1373},
+		{0x05be, 0x1400, 3650},
+		{0x1806, 0x2010, 2058},
+		{0x2011, 0x2015, 1},
+		{0x2e17, 0x2e1a, 3},
+		{0x2e3a, 0x2e3b, 1},
+		{0x2e40, 0x301c, 476},
+		{0x3030, 0x30a0, 112},
+		{0xfe31, 0xfe32, 1},
+		{0xfe58, 0xfe63, 11},
+		{0xff0d, 0xff0d, 1},
+	},
+}
+
+var _Pe = &RangeTable{
+	R16: []Range16{
+		{0x0029, 0x005d, 52},
+		{0x007d, 0x0f3b, 3774},
+		{0x0f3d, 0x169c, 1887},
+		{0x2046, 0x207e, 56},
+		{0x208e, 0x2309, 635},
+		{0x230b, 0x232a, 31},
+		{0x2769, 0x2775, 2},
+		{0x27c6, 0x27e7, 33},
+		{0x27e9, 0x27ef, 2},
+		{0x2984, 0x2998, 2},
+		{0x29d9, 0x29db, 2},
+		{0x29fd, 0x2e23, 1062},
+		{0x2e25, 0x2e29, 2},
+		{0x3009, 0x3011, 2},
+		{0x3015, 0x301b, 2},
+		{0x301e, 0x301f, 1},
+		{0xfd3e, 0xfe18, 218},
+		{0xfe36, 0xfe44, 2},
+		{0xfe48, 0xfe5a, 18},
+		{0xfe5c, 0xfe5e, 2},
+		{0xff09, 0xff3d, 52},
+		{0xff5d, 0xff63, 3},
+	},
+	LatinOffset: 1,
+}
+
+var _Pf = &RangeTable{
+	R16: []Range16{
+		{0x00bb, 0x2019, 8030},
+		{0x201d, 0x203a, 29},
+		{0x2e03, 0x2e05, 2},
+		{0x2e0a, 0x2e0d, 3},
+		{0x2e1d, 0x2e21, 4},
+	},
+}
+
+var _Pi = &RangeTable{
+	R16: []Range16{
+		{0x00ab, 0x2018, 8045},
+		{0x201b, 0x201c, 1},
+		{0x201f, 0x2039, 26},
+		{0x2e02, 0x2e04, 2},
+		{0x2e09, 0x2e0c, 3},
+		{0x2e1c, 0x2e20, 4},
+	},
+}
+
+var _Po = &RangeTable{
+	R16: []Range16{
+		{0x0021, 0x0023, 1},
+		{0x0025, 0x0027, 1},
+		{0x002a, 0x002e, 2},
+		{0x002f, 0x003a, 11},
+		{0x003b, 0x003f, 4},
+		{0x0040, 0x005c, 28},
+		{0x00a1, 0x00a7, 6},
+		{0x00b6, 0x00b7, 1},
+		{0x00bf, 0x037e, 703},
+		{0x0387, 0x055a, 467},
+		{0x055b, 0x055f, 1},
+		{0x0589, 0x05c0, 55},
+		{0x05c3, 0x05c6, 3},
+		{0x05f3, 0x05f4, 1},
+		{0x0609, 0x060a, 1},
+		{0x060c, 0x060d, 1},
+		{0x061b, 0x061e, 3},
+		{0x061f, 0x066a, 75},
+		{0x066b, 0x066d, 1},
+		{0x06d4, 0x0700, 44},
+		{0x0701, 0x070d, 1},
+		{0x07f7, 0x07f9, 1},
+		{0x0830, 0x083e, 1},
+		{0x085e, 0x0964, 262},
+		{0x0965, 0x0970, 11},
+		{0x0af0, 0x0df4, 772},
+		{0x0e4f, 0x0e5a, 11},
+		{0x0e5b, 0x0f04, 169},
+		{0x0f05, 0x0f12, 1},
+		{0x0f14, 0x0f85, 113},
+		{0x0fd0, 0x0fd4, 1},
+		{0x0fd9, 0x0fda, 1},
+		{0x104a, 0x104f, 1},
+		{0x10fb, 0x1360, 613},
+		{0x1361, 0x1368, 1},
+		{0x166d, 0x166e, 1},
+		{0x16eb, 0x16ed, 1},
+		{0x1735, 0x1736, 1},
+		{0x17d4, 0x17d6, 1},
+		{0x17d8, 0x17da, 1},
+		{0x1800, 0x1805, 1},
+		{0x1807, 0x180a, 1},
+		{0x1944, 0x1945, 1},
+		{0x1a1e, 0x1a1f, 1},
+		{0x1aa0, 0x1aa6, 1},
+		{0x1aa8, 0x1aad, 1},
+		{0x1b5a, 0x1b60, 1},
+		{0x1bfc, 0x1bff, 1},
+		{0x1c3b, 0x1c3f, 1},
+		{0x1c7e, 0x1c7f, 1},
+		{0x1cc0, 0x1cc7, 1},
+		{0x1cd3, 0x2016, 835},
+		{0x2017, 0x2020, 9},
+		{0x2021, 0x2027, 1},
+		{0x2030, 0x2038, 1},
+		{0x203b, 0x203e, 1},
+		{0x2041, 0x2043, 1},
+		{0x2047, 0x2051, 1},
+		{0x2053, 0x2055, 2},
+		{0x2056, 0x205e, 1},
+		{0x2cf9, 0x2cfc, 1},
+		{0x2cfe, 0x2cff, 1},
+		{0x2d70, 0x2e00, 144},
+		{0x2e01, 0x2e06, 5},
+		{0x2e07, 0x2e08, 1},
+		{0x2e0b, 0x2e0e, 3},
+		{0x2e0f, 0x2e16, 1},
+		{0x2e18, 0x2e19, 1},
+		{0x2e1b, 0x2e1e, 3},
+		{0x2e1f, 0x2e2a, 11},
+		{0x2e2b, 0x2e2e, 1},
+		{0x2e30, 0x2e39, 1},
+		{0x2e3c, 0x2e3f, 1},
+		{0x2e41, 0x3001, 448},
+		{0x3002, 0x3003, 1},
+		{0x303d, 0x30fb, 190},
+		{0xa4fe, 0xa4ff, 1},
+		{0xa60d, 0xa60f, 1},
+		{0xa673, 0xa67e, 11},
+		{0xa6f2, 0xa6f7, 1},
+		{0xa874, 0xa877, 1},
+		{0xa8ce, 0xa8cf, 1},
+		{0xa8f8, 0xa8fa, 1},
+		{0xa92e, 0xa92f, 1},
+		{0xa95f, 0xa9c1, 98},
+		{0xa9c2, 0xa9cd, 1},
+		{0xa9de, 0xa9df, 1},
+		{0xaa5c, 0xaa5f, 1},
+		{0xaade, 0xaadf, 1},
+		{0xaaf0, 0xaaf1, 1},
+		{0xabeb, 0xfe10, 21029},
+		{0xfe11, 0xfe16, 1},
+		{0xfe19, 0xfe30, 23},
+		{0xfe45, 0xfe46, 1},
+		{0xfe49, 0xfe4c, 1},
+		{0xfe50, 0xfe52, 1},
+		{0xfe54, 0xfe57, 1},
+		{0xfe5f, 0xfe61, 1},
+		{0xfe68, 0xfe6a, 2},
+		{0xfe6b, 0xff01, 150},
+		{0xff02, 0xff03, 1},
+		{0xff05, 0xff07, 1},
+		{0xff0a, 0xff0e, 2},
+		{0xff0f, 0xff1a, 11},
+		{0xff1b, 0xff1f, 4},
+		{0xff20, 0xff3c, 28},
+		{0xff61, 0xff64, 3},
+		{0xff65, 0xff65, 1},
+	},
+	R32: []Range32{
+		{0x10100, 0x10100, 1},
+		{0x10101, 0x10102, 1},
+		{0x1039f, 0x103d0, 49},
+		{0x1056f, 0x10857, 744},
+		{0x1091f, 0x1093f, 32},
+		{0x10a50, 0x10a58, 1},
+		{0x10a7f, 0x10af0, 113},
+		{0x10af1, 0x10af6, 1},
+		{0x10b39, 0x10b3f, 1},
+		{0x10b99, 0x10b9c, 1},
+		{0x11047, 0x1104d, 1},
+		{0x110bb, 0x110bc, 1},
+		{0x110be, 0x110c1, 1},
+		{0x11140, 0x11143, 1},
+		{0x11174, 0x11175, 1},
+		{0x111c5, 0x111c8, 1},
+		{0x111cd, 0x11238, 107},
+		{0x11239, 0x1123d, 1},
+		{0x114c6, 0x115c1, 251},
+		{0x115c2, 0x115c9, 1},
+		{0x11641, 0x11643, 1},
+		{0x12470, 0x12474, 1},
+		{0x16a6e, 0x16a6f, 1},
+		{0x16af5, 0x16b37, 66},
+		{0x16b38, 0x16b3b, 1},
+		{0x16b44, 0x1bc9f, 20827},
+	},
+	LatinOffset: 8,
+}
+
+var _Ps = &RangeTable{
+	R16: []Range16{
+		{0x0028, 0x005b, 51},
+		{0x007b, 0x0f3a, 3775},
+		{0x0f3c, 0x169b, 1887},
+		{0x201a, 0x201e, 4},
+		{0x2045, 0x207d, 56},
+		{0x208d, 0x2308, 635},
+		{0x230a, 0x2329, 31},
+		{0x2768, 0x2774, 2},
+		{0x27c5, 0x27e6, 33},
+		{0x27e8, 0x27ee, 2},
+		{0x2983, 0x2997, 2},
+		{0x29d8, 0x29da, 2},
+		{0x29fc, 0x2e22, 1062},
+		{0x2e24, 0x2e28, 2},
+		{0x2e42, 0x3008, 454},
+		{0x300a, 0x3010, 2},
+		{0x3014, 0x301a, 2},
+		{0x301d, 0xfd3f, 52514},
+		{0xfe17, 0xfe35, 30},
+		{0xfe37, 0xfe43, 2},
+		{0xfe47, 0xfe59, 18},
+		{0xfe5b, 0xfe5d, 2},
+		{0xff08, 0xff3b, 51},
+		{0xff5b, 0xff5f, 4},
+		{0xff62, 0xff62, 1},
+	},
+	LatinOffset: 1,
+}
+
+var _S = &RangeTable{
+	R16: []Range16{
+		{0x0024, 0x002b, 7},
+		{0x003c, 0x003e, 1},
+		{0x005e, 0x0060, 2},
+		{0x007c, 0x007e, 2},
+		{0x00a2, 0x00a6, 1},
+		{0x00a8, 0x00a9, 1},
+		{0x00ac, 0x00ae, 2},
+		{0x00af, 0x00b1, 1},
+		{0x00b4, 0x00b8, 4},
+		{0x00d7, 0x00f7, 32},
+		{0x02c2, 0x02c5, 1},
+		{0x02d2, 0x02df, 1},
+		{0x02e5, 0x02eb, 1},
+		{0x02ed, 0x02ef, 2},
+		{0x02f0, 0x02ff, 1},
+		{0x0375, 0x0384, 15},
+		{0x0385, 0x03f6, 113},
+		{0x0482, 0x058d, 267},
+		{0x058e, 0x058f, 1},
+		{0x0606, 0x0608, 1},
+		{0x060b, 0x060e, 3},
+		{0x060f, 0x06de, 207},
+		{0x06e9, 0x06fd, 20},
+		{0x06fe, 0x07f6, 248},
+		{0x09f2, 0x09f3, 1},
+		{0x09fa, 0x09fb, 1},
+		{0x0af1, 0x0b70, 127},
+		{0x0bf3, 0x0bfa, 1},
+		{0x0c7f, 0x0d79, 250},
+		{0x0e3f, 0x0f01, 194},
+		{0x0f02, 0x0f03, 1},
+		{0x0f13, 0x0f15, 2},
+		{0x0f16, 0x0f17, 1},
+		{0x0f1a, 0x0f1f, 1},
+		{0x0f34, 0x0f38, 2},
+		{0x0fbe, 0x0fc5, 1},
+		{0x0fc7, 0x0fcc, 1},
+		{0x0fce, 0x0fcf, 1},
+		{0x0fd5, 0x0fd8, 1},
+		{0x109e, 0x109f, 1},
+		{0x1390, 0x1399, 1},
+		{0x17db, 0x1940, 357},
+		{0x19de, 0x19ff, 1},
+		{0x1b61, 0x1b6a, 1},
+		{0x1b74, 0x1b7c, 1},
+		{0x1fbd, 0x1fbf, 2},
+		{0x1fc0, 0x1fc1, 1},
+		{0x1fcd, 0x1fcf, 1},
+		{0x1fdd, 0x1fdf, 1},
+		{0x1fed, 0x1fef, 1},
+		{0x1ffd, 0x1ffe, 1},
+		{0x2044, 0x2052, 14},
+		{0x207a, 0x207c, 1},
+		{0x208a, 0x208c, 1},
+		{0x20a0, 0x20bd, 1},
+		{0x2100, 0x2101, 1},
+		{0x2103, 0x2106, 1},
+		{0x2108, 0x2109, 1},
+		{0x2114, 0x2116, 2},
+		{0x2117, 0x2118, 1},
+		{0x211e, 0x2123, 1},
+		{0x2125, 0x2129, 2},
+		{0x212e, 0x213a, 12},
+		{0x213b, 0x2140, 5},
+		{0x2141, 0x2144, 1},
+		{0x214a, 0x214d, 1},
+		{0x214f, 0x2190, 65},
+		{0x2191, 0x2307, 1},
+		{0x230c, 0x2328, 1},
+		{0x232b, 0x23fa, 1},
+		{0x2400, 0x2426, 1},
+		{0x2440, 0x244a, 1},
+		{0x249c, 0x24e9, 1},
+		{0x2500, 0x2767, 1},
+		{0x2794, 0x27c4, 1},
+		{0x27c7, 0x27e5, 1},
+		{0x27f0, 0x2982, 1},
+		{0x2999, 0x29d7, 1},
+		{0x29dc, 0x29fb, 1},
+		{0x29fe, 0x2b73, 1},
+		{0x2b76, 0x2b95, 1},
+		{0x2b98, 0x2bb9, 1},
+		{0x2bbd, 0x2bc8, 1},
+		{0x2bca, 0x2bd1, 1},
+		{0x2ce5, 0x2cea, 1},
+		{0x2e80, 0x2e99, 1},
+		{0x2e9b, 0x2ef3, 1},
+		{0x2f00, 0x2fd5, 1},
+		{0x2ff0, 0x2ffb, 1},
+		{0x3004, 0x3012, 14},
+		{0x3013, 0x3020, 13},
+		{0x3036, 0x3037, 1},
+		{0x303e, 0x303f, 1},
+		{0x309b, 0x309c, 1},
+		{0x3190, 0x3191, 1},
+		{0x3196, 0x319f, 1},
+		{0x31c0, 0x31e3, 1},
+		{0x3200, 0x321e, 1},
+		{0x322a, 0x3247, 1},
+		{0x3250, 0x3260, 16},
+		{0x3261, 0x327f, 1},
+		{0x328a, 0x32b0, 1},
+		{0x32c0, 0x32fe, 1},
+		{0x3300, 0x33ff, 1},
+		{0x4dc0, 0x4dff, 1},
+		{0xa490, 0xa4c6, 1},
+		{0xa700, 0xa716, 1},
+		{0xa720, 0xa721, 1},
+		{0xa789, 0xa78a, 1},
+		{0xa828, 0xa82b, 1},
+		{0xa836, 0xa839, 1},
+		{0xaa77, 0xaa79, 1},
+		{0xab5b, 0xfb29, 20430},
+		{0xfbb2, 0xfbc1, 1},
+		{0xfdfc, 0xfdfd, 1},
+		{0xfe62, 0xfe64, 2},
+		{0xfe65, 0xfe66, 1},
+		{0xfe69, 0xff04, 155},
+		{0xff0b, 0xff1c, 17},
+		{0xff1d, 0xff1e, 1},
+		{0xff3e, 0xff40, 2},
+		{0xff5c, 0xff5e, 2},
+		{0xffe0, 0xffe6, 1},
+		{0xffe8, 0xffee, 1},
+		{0xfffc, 0xfffd, 1},
+	},
+	R32: []Range32{
+		{0x10137, 0x1013f, 1},
+		{0x10179, 0x10189, 1},
+		{0x1018c, 0x10190, 4},
+		{0x10191, 0x1019b, 1},
+		{0x101a0, 0x101d0, 48},
+		{0x101d1, 0x101fc, 1},
+		{0x10877, 0x10878, 1},
+		{0x10ac8, 0x16b3c, 24692},
+		{0x16b3d, 0x16b3f, 1},
+		{0x16b45, 0x1bc9c, 20823},
+		{0x1d000, 0x1d0f5, 1},
+		{0x1d100, 0x1d126, 1},
+		{0x1d129, 0x1d164, 1},
+		{0x1d16a, 0x1d16c, 1},
+		{0x1d183, 0x1d184, 1},
+		{0x1d18c, 0x1d1a9, 1},
+		{0x1d1ae, 0x1d1dd, 1},
+		{0x1d200, 0x1d241, 1},
+		{0x1d245, 0x1d300, 187},
+		{0x1d301, 0x1d356, 1},
+		{0x1d6c1, 0x1d6db, 26},
+		{0x1d6fb, 0x1d715, 26},
+		{0x1d735, 0x1d74f, 26},
+		{0x1d76f, 0x1d789, 26},
+		{0x1d7a9, 0x1d7c3, 26},
+		{0x1eef0, 0x1eef1, 1},
+		{0x1f000, 0x1f02b, 1},
+		{0x1f030, 0x1f093, 1},
+		{0x1f0a0, 0x1f0ae, 1},
+		{0x1f0b1, 0x1f0bf, 1},
+		{0x1f0c1, 0x1f0cf, 1},
+		{0x1f0d1, 0x1f0f5, 1},
+		{0x1f110, 0x1f12e, 1},
+		{0x1f130, 0x1f16b, 1},
+		{0x1f170, 0x1f19a, 1},
+		{0x1f1e6, 0x1f202, 1},
+		{0x1f210, 0x1f23a, 1},
+		{0x1f240, 0x1f248, 1},
+		{0x1f250, 0x1f251, 1},
+		{0x1f300, 0x1f32c, 1},
+		{0x1f330, 0x1f37d, 1},
+		{0x1f380, 0x1f3ce, 1},
+		{0x1f3d4, 0x1f3f7, 1},
+		{0x1f400, 0x1f4fe, 1},
+		{0x1f500, 0x1f54a, 1},
+		{0x1f550, 0x1f579, 1},
+		{0x1f57b, 0x1f5a3, 1},
+		{0x1f5a5, 0x1f642, 1},
+		{0x1f645, 0x1f6cf, 1},
+		{0x1f6e0, 0x1f6ec, 1},
+		{0x1f6f0, 0x1f6f3, 1},
+		{0x1f700, 0x1f773, 1},
+		{0x1f780, 0x1f7d4, 1},
+		{0x1f800, 0x1f80b, 1},
+		{0x1f810, 0x1f847, 1},
+		{0x1f850, 0x1f859, 1},
+		{0x1f860, 0x1f887, 1},
+		{0x1f890, 0x1f8ad, 1},
+	},
+	LatinOffset: 10,
+}
+
+var _Sc = &RangeTable{
+	R16: []Range16{
+		{0x0024, 0x00a2, 126},
+		{0x00a3, 0x00a5, 1},
+		{0x058f, 0x060b, 124},
+		{0x09f2, 0x09f3, 1},
+		{0x09fb, 0x0af1, 246},
+		{0x0bf9, 0x0e3f, 582},
+		{0x17db, 0x20a0, 2245},
+		{0x20a1, 0x20bd, 1},
+		{0xa838, 0xfdfc, 21956},
+		{0xfe69, 0xff04, 155},
+		{0xffe0, 0xffe1, 1},
+		{0xffe5, 0xffe6, 1},
+	},
+	LatinOffset: 2,
+}
+
+var _Sk = &RangeTable{
+	R16: []Range16{
+		{0x005e, 0x0060, 2},
+		{0x00a8, 0x00af, 7},
+		{0x00b4, 0x00b8, 4},
+		{0x02c2, 0x02c5, 1},
+		{0x02d2, 0x02df, 1},
+		{0x02e5, 0x02eb, 1},
+		{0x02ed, 0x02ef, 2},
+		{0x02f0, 0x02ff, 1},
+		{0x0375, 0x0384, 15},
+		{0x0385, 0x1fbd, 7224},
+		{0x1fbf, 0x1fc1, 1},
+		{0x1fcd, 0x1fcf, 1},
+		{0x1fdd, 0x1fdf, 1},
+		{0x1fed, 0x1fef, 1},
+		{0x1ffd, 0x1ffe, 1},
+		{0x309b, 0x309c, 1},
+		{0xa700, 0xa716, 1},
+		{0xa720, 0xa721, 1},
+		{0xa789, 0xa78a, 1},
+		{0xab5b, 0xfbb2, 20567},
+		{0xfbb3, 0xfbc1, 1},
+		{0xff3e, 0xff40, 2},
+		{0xffe3, 0xffe3, 1},
+	},
+	LatinOffset: 3,
+}
+
+var _Sm = &RangeTable{
+	R16: []Range16{
+		{0x002b, 0x003c, 17},
+		{0x003d, 0x003e, 1},
+		{0x007c, 0x007e, 2},
+		{0x00ac, 0x00b1, 5},
+		{0x00d7, 0x00f7, 32},
+		{0x03f6, 0x0606, 528},
+		{0x0607, 0x0608, 1},
+		{0x2044, 0x2052, 14},
+		{0x207a, 0x207c, 1},
+		{0x208a, 0x208c, 1},
+		{0x2118, 0x2140, 40},
+		{0x2141, 0x2144, 1},
+		{0x214b, 0x2190, 69},
+		{0x2191, 0x2194, 1},
+		{0x219a, 0x219b, 1},
+		{0x21a0, 0x21a6, 3},
+		{0x21ae, 0x21ce, 32},
+		{0x21cf, 0x21d2, 3},
+		{0x21d4, 0x21f4, 32},
+		{0x21f5, 0x22ff, 1},
+		{0x2320, 0x2321, 1},
+		{0x237c, 0x239b, 31},
+		{0x239c, 0x23b3, 1},
+		{0x23dc, 0x23e1, 1},
+		{0x25b7, 0x25c1, 10},
+		{0x25f8, 0x25ff, 1},
+		{0x266f, 0x27c0, 337},
+		{0x27c1, 0x27c4, 1},
+		{0x27c7, 0x27e5, 1},
+		{0x27f0, 0x27ff, 1},
+		{0x2900, 0x2982, 1},
+		{0x2999, 0x29d7, 1},
+		{0x29dc, 0x29fb, 1},
+		{0x29fe, 0x2aff, 1},
+		{0x2b30, 0x2b44, 1},
+		{0x2b47, 0x2b4c, 1},
+		{0xfb29, 0xfe62, 825},
+		{0xfe64, 0xfe66, 1},
+		{0xff0b, 0xff1c, 17},
+		{0xff1d, 0xff1e, 1},
+		{0xff5c, 0xff5e, 2},
+		{0xffe2, 0xffe9, 7},
+		{0xffea, 0xffec, 1},
+	},
+	R32: []Range32{
+		{0x1d6c1, 0x1d6db, 26},
+		{0x1d6fb, 0x1d715, 26},
+		{0x1d735, 0x1d74f, 26},
+		{0x1d76f, 0x1d789, 26},
+		{0x1d7a9, 0x1d7c3, 26},
+		{0x1eef0, 0x1eef1, 1},
+	},
+	LatinOffset: 5,
+}
+
+var _So = &RangeTable{
+	R16: []Range16{
+		{0x00a6, 0x00a9, 3},
+		{0x00ae, 0x00b0, 2},
+		{0x0482, 0x058d, 267},
+		{0x058e, 0x060e, 128},
+		{0x060f, 0x06de, 207},
+		{0x06e9, 0x06fd, 20},
+		{0x06fe, 0x07f6, 248},
+		{0x09fa, 0x0b70, 374},
+		{0x0bf3, 0x0bf8, 1},
+		{0x0bfa, 0x0c7f, 133},
+		{0x0d79, 0x0f01, 392},
+		{0x0f02, 0x0f03, 1},
+		{0x0f13, 0x0f15, 2},
+		{0x0f16, 0x0f17, 1},
+		{0x0f1a, 0x0f1f, 1},
+		{0x0f34, 0x0f38, 2},
+		{0x0fbe, 0x0fc5, 1},
+		{0x0fc7, 0x0fcc, 1},
+		{0x0fce, 0x0fcf, 1},
+		{0x0fd5, 0x0fd8, 1},
+		{0x109e, 0x109f, 1},
+		{0x1390, 0x1399, 1},
+		{0x1940, 0x19de, 158},
+		{0x19df, 0x19ff, 1},
+		{0x1b61, 0x1b6a, 1},
+		{0x1b74, 0x1b7c, 1},
+		{0x2100, 0x2101, 1},
+		{0x2103, 0x2106, 1},
+		{0x2108, 0x2109, 1},
+		{0x2114, 0x2116, 2},
+		{0x2117, 0x211e, 7},
+		{0x211f, 0x2123, 1},
+		{0x2125, 0x2129, 2},
+		{0x212e, 0x213a, 12},
+		{0x213b, 0x214a, 15},
+		{0x214c, 0x214d, 1},
+		{0x214f, 0x2195, 70},
+		{0x2196, 0x2199, 1},
+		{0x219c, 0x219f, 1},
+		{0x21a1, 0x21a2, 1},
+		{0x21a4, 0x21a5, 1},
+		{0x21a7, 0x21ad, 1},
+		{0x21af, 0x21cd, 1},
+		{0x21d0, 0x21d1, 1},
+		{0x21d3, 0x21d5, 2},
+		{0x21d6, 0x21f3, 1},
+		{0x2300, 0x2307, 1},
+		{0x230c, 0x231f, 1},
+		{0x2322, 0x2328, 1},
+		{0x232b, 0x237b, 1},
+		{0x237d, 0x239a, 1},
+		{0x23b4, 0x23db, 1},
+		{0x23e2, 0x23fa, 1},
+		{0x2400, 0x2426, 1},
+		{0x2440, 0x244a, 1},
+		{0x249c, 0x24e9, 1},
+		{0x2500, 0x25b6, 1},
+		{0x25b8, 0x25c0, 1},
+		{0x25c2, 0x25f7, 1},
+		{0x2600, 0x266e, 1},
+		{0x2670, 0x2767, 1},
+		{0x2794, 0x27bf, 1},
+		{0x2800, 0x28ff, 1},
+		{0x2b00, 0x2b2f, 1},
+		{0x2b45, 0x2b46, 1},
+		{0x2b4d, 0x2b73, 1},
+		{0x2b76, 0x2b95, 1},
+		{0x2b98, 0x2bb9, 1},
+		{0x2bbd, 0x2bc8, 1},
+		{0x2bca, 0x2bd1, 1},
+		{0x2ce5, 0x2cea, 1},
+		{0x2e80, 0x2e99, 1},
+		{0x2e9b, 0x2ef3, 1},
+		{0x2f00, 0x2fd5, 1},
+		{0x2ff0, 0x2ffb, 1},
+		{0x3004, 0x3012, 14},
+		{0x3013, 0x3020, 13},
+		{0x3036, 0x3037, 1},
+		{0x303e, 0x303f, 1},
+		{0x3190, 0x3191, 1},
+		{0x3196, 0x319f, 1},
+		{0x31c0, 0x31e3, 1},
+		{0x3200, 0x321e, 1},
+		{0x322a, 0x3247, 1},
+		{0x3250, 0x3260, 16},
+		{0x3261, 0x327f, 1},
+		{0x328a, 0x32b0, 1},
+		{0x32c0, 0x32fe, 1},
+		{0x3300, 0x33ff, 1},
+		{0x4dc0, 0x4dff, 1},
+		{0xa490, 0xa4c6, 1},
+		{0xa828, 0xa82b, 1},
+		{0xa836, 0xa837, 1},
+		{0xa839, 0xaa77, 574},
+		{0xaa78, 0xaa79, 1},
+		{0xfdfd, 0xffe4, 487},
+		{0xffe8, 0xffed, 5},
+		{0xffee, 0xfffc, 14},
+		{0xfffd, 0xfffd, 1},
+	},
+	R32: []Range32{
+		{0x10137, 0x10137, 1},
+		{0x10138, 0x1013f, 1},
+		{0x10179, 0x10189, 1},
+		{0x1018c, 0x10190, 4},
+		{0x10191, 0x1019b, 1},
+		{0x101a0, 0x101d0, 48},
+		{0x101d1, 0x101fc, 1},
+		{0x10877, 0x10878, 1},
+		{0x10ac8, 0x16b3c, 24692},
+		{0x16b3d, 0x16b3f, 1},
+		{0x16b45, 0x1bc9c, 20823},
+		{0x1d000, 0x1d0f5, 1},
+		{0x1d100, 0x1d126, 1},
+		{0x1d129, 0x1d164, 1},
+		{0x1d16a, 0x1d16c, 1},
+		{0x1d183, 0x1d184, 1},
+		{0x1d18c, 0x1d1a9, 1},
+		{0x1d1ae, 0x1d1dd, 1},
+		{0x1d200, 0x1d241, 1},
+		{0x1d245, 0x1d300, 187},
+		{0x1d301, 0x1d356, 1},
+		{0x1f000, 0x1f02b, 1},
+		{0x1f030, 0x1f093, 1},
+		{0x1f0a0, 0x1f0ae, 1},
+		{0x1f0b1, 0x1f0bf, 1},
+		{0x1f0c1, 0x1f0cf, 1},
+		{0x1f0d1, 0x1f0f5, 1},
+		{0x1f110, 0x1f12e, 1},
+		{0x1f130, 0x1f16b, 1},
+		{0x1f170, 0x1f19a, 1},
+		{0x1f1e6, 0x1f202, 1},
+		{0x1f210, 0x1f23a, 1},
+		{0x1f240, 0x1f248, 1},
+		{0x1f250, 0x1f251, 1},
+		{0x1f300, 0x1f32c, 1},
+		{0x1f330, 0x1f37d, 1},
+		{0x1f380, 0x1f3ce, 1},
+		{0x1f3d4, 0x1f3f7, 1},
+		{0x1f400, 0x1f4fe, 1},
+		{0x1f500, 0x1f54a, 1},
+		{0x1f550, 0x1f579, 1},
+		{0x1f57b, 0x1f5a3, 1},
+		{0x1f5a5, 0x1f642, 1},
+		{0x1f645, 0x1f6cf, 1},
+		{0x1f6e0, 0x1f6ec, 1},
+		{0x1f6f0, 0x1f6f3, 1},
+		{0x1f700, 0x1f773, 1},
+		{0x1f780, 0x1f7d4, 1},
+		{0x1f800, 0x1f80b, 1},
+		{0x1f810, 0x1f847, 1},
+		{0x1f850, 0x1f859, 1},
+		{0x1f860, 0x1f887, 1},
+		{0x1f890, 0x1f8ad, 1},
+	},
+	LatinOffset: 2,
+}
+
+var _Z = &RangeTable{
+	R16: []Range16{
+		{0x0020, 0x00a0, 128},
+		{0x1680, 0x2000, 2432},
+		{0x2001, 0x200a, 1},
+		{0x2028, 0x2029, 1},
+		{0x202f, 0x205f, 48},
+		{0x3000, 0x3000, 1},
+	},
+	LatinOffset: 1,
+}
+
+var _Zl = &RangeTable{
+	R16: []Range16{
+		{0x2028, 0x2028, 1},
+	},
+}
+
+var _Zp = &RangeTable{
+	R16: []Range16{
+		{0x2029, 0x2029, 1},
+	},
+}
+
+var _Zs = &RangeTable{
+	R16: []Range16{
+		{0x0020, 0x00a0, 128},
+		{0x1680, 0x2000, 2432},
+		{0x2001, 0x200a, 1},
+		{0x202f, 0x205f, 48},
+		{0x3000, 0x3000, 1},
+	},
+	LatinOffset: 1,
+}
+
+// These variables have type *RangeTable.
+var (
+	Cc     = _Cc // Cc is the set of Unicode characters in category Cc.
+	Cf     = _Cf // Cf is the set of Unicode characters in category Cf.
+	Co     = _Co // Co is the set of Unicode characters in category Co.
+	Cs     = _Cs // Cs is the set of Unicode characters in category Cs.
+	Digit  = _Nd // Digit is the set of Unicode characters with the "decimal digit" property.
+	Nd     = _Nd // Nd is the set of Unicode characters in category Nd.
+	Letter = _L  // Letter/L is the set of Unicode letters, category L.
+	L      = _L
+	Lm     = _Lm // Lm is the set of Unicode characters in category Lm.
+	Lo     = _Lo // Lo is the set of Unicode characters in category Lo.
+	Lower  = _Ll // Lower is the set of Unicode lower case letters.
+	Ll     = _Ll // Ll is the set of Unicode characters in category Ll.
+	Mark   = _M  // Mark/M is the set of Unicode mark characters, category M.
+	M      = _M
+	Mc     = _Mc // Mc is the set of Unicode characters in category Mc.
+	Me     = _Me // Me is the set of Unicode characters in category Me.
+	Mn     = _Mn // Mn is the set of Unicode characters in category Mn.
+	Nl     = _Nl // Nl is the set of Unicode characters in category Nl.
+	No     = _No // No is the set of Unicode characters in category No.
+	Number = _N  // Number/N is the set of Unicode number characters, category N.
+	N      = _N
+	Other  = _C // Other/C is the set of Unicode control and special characters, category C.
+	C      = _C
+	Pc     = _Pc // Pc is the set of Unicode characters in category Pc.
+	Pd     = _Pd // Pd is the set of Unicode characters in category Pd.
+	Pe     = _Pe // Pe is the set of Unicode characters in category Pe.
+	Pf     = _Pf // Pf is the set of Unicode characters in category Pf.
+	Pi     = _Pi // Pi is the set of Unicode characters in category Pi.
+	Po     = _Po // Po is the set of Unicode characters in category Po.
+	Ps     = _Ps // Ps is the set of Unicode characters in category Ps.
+	Punct  = _P  // Punct/P is the set of Unicode punctuation characters, category P.
+	P      = _P
+	Sc     = _Sc // Sc is the set of Unicode characters in category Sc.
+	Sk     = _Sk // Sk is the set of Unicode characters in category Sk.
+	Sm     = _Sm // Sm is the set of Unicode characters in category Sm.
+	So     = _So // So is the set of Unicode characters in category So.
+	Space  = _Z  // Space/Z is the set of Unicode space characters, category Z.
+	Z      = _Z
+	Symbol = _S // Symbol/S is the set of Unicode symbol characters, category S.
+	S      = _S
+	Title  = _Lt // Title is the set of Unicode title case letters.
+	Lt     = _Lt // Lt is the set of Unicode characters in category Lt.
+	Upper  = _Lu // Upper is the set of Unicode upper case letters.
+	Lu     = _Lu // Lu is the set of Unicode characters in category Lu.
+	Zl     = _Zl // Zl is the set of Unicode characters in category Zl.
+	Zp     = _Zp // Zp is the set of Unicode characters in category Zp.
+	Zs     = _Zs // Zs is the set of Unicode characters in category Zs.
+)
+
+// Generated by running
+//	maketables --scripts=all --url=http://www.unicode.org/Public/7.0.0/ucd/
+// DO NOT EDIT
+
+// Scripts is the set of Unicode script tables.
+var Scripts = map[string]*RangeTable{
+	"Arabic":                 Arabic,
+	"Armenian":               Armenian,
+	"Avestan":                Avestan,
+	"Balinese":               Balinese,
+	"Bamum":                  Bamum,
+	"Bassa_Vah":              Bassa_Vah,
+	"Batak":                  Batak,
+	"Bengali":                Bengali,
+	"Bopomofo":               Bopomofo,
+	"Brahmi":                 Brahmi,
+	"Braille":                Braille,
+	"Buginese":               Buginese,
+	"Buhid":                  Buhid,
+	"Canadian_Aboriginal":    Canadian_Aboriginal,
+	"Carian":                 Carian,
+	"Caucasian_Albanian":     Caucasian_Albanian,
+	"Chakma":                 Chakma,
+	"Cham":                   Cham,
+	"Cherokee":               Cherokee,
+	"Common":                 Common,
+	"Coptic":                 Coptic,
+	"Cuneiform":              Cuneiform,
+	"Cypriot":                Cypriot,
+	"Cyrillic":               Cyrillic,
+	"Deseret":                Deseret,
+	"Devanagari":             Devanagari,
+	"Duployan":               Duployan,
+	"Egyptian_Hieroglyphs":   Egyptian_Hieroglyphs,
+	"Elbasan":                Elbasan,
+	"Ethiopic":               Ethiopic,
+	"Georgian":               Georgian,
+	"Glagolitic":             Glagolitic,
+	"Gothic":                 Gothic,
+	"Grantha":                Grantha,
+	"Greek":                  Greek,
+	"Gujarati":               Gujarati,
+	"Gurmukhi":               Gurmukhi,
+	"Han":                    Han,
+	"Hangul":                 Hangul,
+	"Hanunoo":                Hanunoo,
+	"Hebrew":                 Hebrew,
+	"Hiragana":               Hiragana,
+	"Imperial_Aramaic":       Imperial_Aramaic,
+	"Inherited":              Inherited,
+	"Inscriptional_Pahlavi":  Inscriptional_Pahlavi,
+	"Inscriptional_Parthian": Inscriptional_Parthian,
+	"Javanese":               Javanese,
+	"Kaithi":                 Kaithi,
+	"Kannada":                Kannada,
+	"Katakana":               Katakana,
+	"Kayah_Li":               Kayah_Li,
+	"Kharoshthi":             Kharoshthi,
+	"Khmer":                  Khmer,
+	"Khojki":                 Khojki,
+	"Khudawadi":              Khudawadi,
+	"Lao":                    Lao,
+	"Latin":                  Latin,
+	"Lepcha":                 Lepcha,
+	"Limbu":                  Limbu,
+	"Linear_A":               Linear_A,
+	"Linear_B":               Linear_B,
+	"Lisu":                   Lisu,
+	"Lycian":                 Lycian,
+	"Lydian":                 Lydian,
+	"Mahajani":               Mahajani,
+	"Malayalam":              Malayalam,
+	"Mandaic":                Mandaic,
+	"Manichaean":             Manichaean,
+	"Meetei_Mayek":           Meetei_Mayek,
+	"Mende_Kikakui":          Mende_Kikakui,
+	"Meroitic_Cursive":       Meroitic_Cursive,
+	"Meroitic_Hieroglyphs":   Meroitic_Hieroglyphs,
+	"Miao":                   Miao,
+	"Modi":                   Modi,
+	"Mongolian":              Mongolian,
+	"Mro":                    Mro,
+	"Myanmar":                Myanmar,
+	"Nabataean":              Nabataean,
+	"New_Tai_Lue":            New_Tai_Lue,
+	"Nko":                    Nko,
+	"Ogham":                  Ogham,
+	"Ol_Chiki":               Ol_Chiki,
+	"Old_Italic":             Old_Italic,
+	"Old_North_Arabian":      Old_North_Arabian,
+	"Old_Permic":             Old_Permic,
+	"Old_Persian":            Old_Persian,
+	"Old_South_Arabian":      Old_South_Arabian,
+	"Old_Turkic":             Old_Turkic,
+	"Oriya":                  Oriya,
+	"Osmanya":                Osmanya,
+	"Pahawh_Hmong":           Pahawh_Hmong,
+	"Palmyrene":              Palmyrene,
+	"Pau_Cin_Hau":            Pau_Cin_Hau,
+	"Phags_Pa":               Phags_Pa,
+	"Phoenician":             Phoenician,
+	"Psalter_Pahlavi":        Psalter_Pahlavi,
+	"Rejang":                 Rejang,
+	"Runic":                  Runic,
+	"Samaritan":              Samaritan,
+	"Saurashtra":             Saurashtra,
+	"Sharada":                Sharada,
+	"Shavian":                Shavian,
+	"Siddham":                Siddham,
+	"Sinhala":                Sinhala,
+	"Sora_Sompeng":           Sora_Sompeng,
+	"Sundanese":              Sundanese,
+	"Syloti_Nagri":           Syloti_Nagri,
+	"Syriac":                 Syriac,
+	"Tagalog":                Tagalog,
+	"Tagbanwa":               Tagbanwa,
+	"Tai_Le":                 Tai_Le,
+	"Tai_Tham":               Tai_Tham,
+	"Tai_Viet":               Tai_Viet,
+	"Takri":                  Takri,
+	"Tamil":                  Tamil,
+	"Telugu":                 Telugu,
+	"Thaana":                 Thaana,
+	"Thai":                   Thai,
+	"Tibetan":                Tibetan,
+	"Tifinagh":               Tifinagh,
+	"Tirhuta":                Tirhuta,
+	"Ugaritic":               Ugaritic,
+	"Vai":                    Vai,
+	"Warang_Citi":            Warang_Citi,
+	"Yi":                     Yi,
+}
+
+var _Arabic = &RangeTable{
+	R16: []Range16{
+		{0x0600, 0x0604, 1},
+		{0x0606, 0x060b, 1},
+		{0x060d, 0x061a, 1},
+		{0x061e, 0x061e, 1},
+		{0x0620, 0x063f, 1},
+		{0x0641, 0x064a, 1},
+		{0x0656, 0x065f, 1},
+		{0x066a, 0x066f, 1},
+		{0x0671, 0x06dc, 1},
+		{0x06de, 0x06ff, 1},
+		{0x0750, 0x077f, 1},
+		{0x08a0, 0x08b2, 1},
+		{0x08e4, 0x08ff, 1},
+		{0xfb50, 0xfbc1, 1},
+		{0xfbd3, 0xfd3d, 1},
+		{0xfd50, 0xfd8f, 1},
+		{0xfd92, 0xfdc7, 1},
+		{0xfdf0, 0xfdfd, 1},
+		{0xfe70, 0xfe74, 1},
+		{0xfe76, 0xfefc, 1},
+	},
+	R32: []Range32{
+		{0x10e60, 0x10e7e, 1},
+		{0x1ee00, 0x1ee03, 1},
+		{0x1ee05, 0x1ee1f, 1},
+		{0x1ee21, 0x1ee22, 1},
+		{0x1ee24, 0x1ee24, 1},
+		{0x1ee27, 0x1ee27, 1},
+		{0x1ee29, 0x1ee32, 1},
+		{0x1ee34, 0x1ee37, 1},
+		{0x1ee39, 0x1ee39, 1},
+		{0x1ee3b, 0x1ee3b, 1},
+		{0x1ee42, 0x1ee42, 1},
+		{0x1ee47, 0x1ee47, 1},
+		{0x1ee49, 0x1ee49, 1},
+		{0x1ee4b, 0x1ee4b, 1},
+		{0x1ee4d, 0x1ee4f, 1},
+		{0x1ee51, 0x1ee52, 1},
+		{0x1ee54, 0x1ee54, 1},
+		{0x1ee57, 0x1ee57, 1},
+		{0x1ee59, 0x1ee59, 1},
+		{0x1ee5b, 0x1ee5b, 1},
+		{0x1ee5d, 0x1ee5d, 1},
+		{0x1ee5f, 0x1ee5f, 1},
+		{0x1ee61, 0x1ee62, 1},
+		{0x1ee64, 0x1ee64, 1},
+		{0x1ee67, 0x1ee6a, 1},
+		{0x1ee6c, 0x1ee72, 1},
+		{0x1ee74, 0x1ee77, 1},
+		{0x1ee79, 0x1ee7c, 1},
+		{0x1ee7e, 0x1ee7e, 1},
+		{0x1ee80, 0x1ee89, 1},
+		{0x1ee8b, 0x1ee9b, 1},
+		{0x1eea1, 0x1eea3, 1},
+		{0x1eea5, 0x1eea9, 1},
+		{0x1eeab, 0x1eebb, 1},
+		{0x1eef0, 0x1eef1, 1},
+	},
+}
+
+var _Armenian = &RangeTable{
+	R16: []Range16{
+		{0x0531, 0x0556, 1},
+		{0x0559, 0x055f, 1},
+		{0x0561, 0x0587, 1},
+		{0x058a, 0x058a, 1},
+		{0x058d, 0x058f, 1},
+		{0xfb13, 0xfb17, 1},
+	},
+}
+
+var _Avestan = &RangeTable{
+	R16: []Range16{},
+	R32: []Range32{
+		{0x10b00, 0x10b35, 1},
+		{0x10b39, 0x10b3f, 1},
+	},
+}
+
+var _Balinese = &RangeTable{
+	R16: []Range16{
+		{0x1b00, 0x1b4b, 1},
+		{0x1b50, 0x1b7c, 1},
+	},
+}
+
+var _Bamum = &RangeTable{
+	R16: []Range16{
+		{0xa6a0, 0xa6f7, 1},
+	},
+	R32: []Range32{
+		{0x16800, 0x16a38, 1},
+	},
+}
+
+var _Bassa_Vah = &RangeTable{
+	R16: []Range16{},
+	R32: []Range32{
+		{0x16ad0, 0x16aed, 1},
+		{0x16af0, 0x16af5, 1},
+	},
+}
+
+var _Batak = &RangeTable{
+	R16: []Range16{
+		{0x1bc0, 0x1bf3, 1},
+		{0x1bfc, 0x1bff, 1},
+	},
+}
+
+var _Bengali = &RangeTable{
+	R16: []Range16{
+		{0x0980, 0x0983, 1},
+		{0x0985, 0x098c, 1},
+		{0x098f, 0x0990, 1},
+		{0x0993, 0x09a8, 1},
+		{0x09aa, 0x09b0, 1},
+		{0x09b2, 0x09b2, 1},
+		{0x09b6, 0x09b9, 1},
+		{0x09bc, 0x09c4, 1},
+		{0x09c7, 0x09c8, 1},
+		{0x09cb, 0x09ce, 1},
+		{0x09d7, 0x09d7, 1},
+		{0x09dc, 0x09dd, 1},
+		{0x09df, 0x09e3, 1},
+		{0x09e6, 0x09fb, 1},
+	},
+}
+
+var _Bopomofo = &RangeTable{
+	R16: []Range16{
+		{0x02ea, 0x02eb, 1},
+		{0x3105, 0x312d, 1},
+		{0x31a0, 0x31ba, 1},
+	},
+}
+
+var _Brahmi = &RangeTable{
+	R16: []Range16{},
+	R32: []Range32{
+		{0x11000, 0x1104d, 1},
+		{0x11052, 0x1106f, 1},
+		{0x1107f, 0x1107f, 1},
+	},
+}
+
+var _Braille = &RangeTable{
+	R16: []Range16{
+		{0x2800, 0x28ff, 1},
+	},
+}
+
+var _Buginese = &RangeTable{
+	R16: []Range16{
+		{0x1a00, 0x1a1b, 1},
+		{0x1a1e, 0x1a1f, 1},
+	},
+}
+
+var _Buhid = &RangeTable{
+	R16: []Range16{
+		{0x1740, 0x1753, 1},
+	},
+}
+
+var _Canadian_Aboriginal = &RangeTable{
+	R16: []Range16{
+		{0x1400, 0x167f, 1},
+		{0x18b0, 0x18f5, 1},
+	},
+}
+
+var _Carian = &RangeTable{
+	R16: []Range16{},
+	R32: []Range32{
+		{0x102a0, 0x102d0, 1},
+	},
+}
+
+var _Caucasian_Albanian = &RangeTable{
+	R16: []Range16{},
+	R32: []Range32{
+		{0x10530, 0x10563, 1},
+		{0x1056f, 0x1056f, 1},
+	},
+}
+
+var _Chakma = &RangeTable{
+	R16: []Range16{},
+	R32: []Range32{
+		{0x11100, 0x11134, 1},
+		{0x11136, 0x11143, 1},
+	},
+}
+
+var _Cham = &RangeTable{
+	R16: []Range16{
+		{0xaa00, 0xaa36, 1},
+		{0xaa40, 0xaa4d, 1},
+		{0xaa50, 0xaa59, 1},
+		{0xaa5c, 0xaa5f, 1},
+	},
+}
+
+var _Cherokee = &RangeTable{
+	R16: []Range16{
+		{0x13a0, 0x13f4, 1},
+	},
+}
+
+var _Common = &RangeTable{
+	R16: []Range16{
+		{0x0000, 0x0040, 1},
+		{0x005b, 0x0060, 1},
+		{0x007b, 0x00a9, 1},
+		{0x00ab, 0x00b9, 1},
+		{0x00bb, 0x00bf, 1},
+		{0x00d7, 0x00d7, 1},
+		{0x00f7, 0x00f7, 1},
+		{0x02b9, 0x02df, 1},
+		{0x02e5, 0x02e9, 1},
+		{0x02ec, 0x02ff, 1},
+		{0x0374, 0x0374, 1},
+		{0x037e, 0x037e, 1},
+		{0x0385, 0x0385, 1},
+		{0x0387, 0x0387, 1},
+		{0x0589, 0x0589, 1},
+		{0x0605, 0x0605, 1},
+		{0x060c, 0x060c, 1},
+		{0x061b, 0x061c, 1},
+		{0x061f, 0x061f, 1},
+		{0x0640, 0x0640, 1},
+		{0x0660, 0x0669, 1},
+		{0x06dd, 0x06dd, 1},
+		{0x0964, 0x0965, 1},
+		{0x0e3f, 0x0e3f, 1},
+		{0x0fd5, 0x0fd8, 1},
+		{0x10fb, 0x10fb, 1},
+		{0x16eb, 0x16ed, 1},
+		{0x1735, 0x1736, 1},
+		{0x1802, 0x1803, 1},
+		{0x1805, 0x1805, 1},
+		{0x1cd3, 0x1cd3, 1},
+		{0x1ce1, 0x1ce1, 1},
+		{0x1ce9, 0x1cec, 1},
+		{0x1cee, 0x1cf3, 1},
+		{0x1cf5, 0x1cf6, 1},
+		{0x2000, 0x200b, 1},
+		{0x200e, 0x2064, 1},
+		{0x2066, 0x2070, 1},
+		{0x2074, 0x207e, 1},
+		{0x2080, 0x208e, 1},
+		{0x20a0, 0x20bd, 1},
+		{0x2100, 0x2125, 1},
+		{0x2127, 0x2129, 1},
+		{0x212c, 0x2131, 1},
+		{0x2133, 0x214d, 1},
+		{0x214f, 0x215f, 1},
+		{0x2189, 0x2189, 1},
+		{0x2190, 0x23fa, 1},
+		{0x2400, 0x2426, 1},
+		{0x2440, 0x244a, 1},
+		{0x2460, 0x27ff, 1},
+		{0x2900, 0x2b73, 1},
+		{0x2b76, 0x2b95, 1},
+		{0x2b98, 0x2bb9, 1},
+		{0x2bbd, 0x2bc8, 1},
+		{0x2bca, 0x2bd1, 1},
+		{0x2e00, 0x2e42, 1},
+		{0x2ff0, 0x2ffb, 1},
+		{0x3000, 0x3004, 1},
+		{0x3006, 0x3006, 1},
+		{0x3008, 0x3020, 1},
+		{0x3030, 0x3037, 1},
+		{0x303c, 0x303f, 1},
+		{0x309b, 0x309c, 1},
+		{0x30a0, 0x30a0, 1},
+		{0x30fb, 0x30fc, 1},
+		{0x3190, 0x319f, 1},
+		{0x31c0, 0x31e3, 1},
+		{0x3220, 0x325f, 1},
+		{0x327f, 0x32cf, 1},
+		{0x3358, 0x33ff, 1},
+		{0x4dc0, 0x4dff, 1},
+		{0xa700, 0xa721, 1},
+		{0xa788, 0xa78a, 1},
+		{0xa830, 0xa839, 1},
+		{0xa92e, 0xa92e, 1},
+		{0xa9cf, 0xa9cf, 1},
+		{0xab5b, 0xab5b, 1},
+		{0xfd3e, 0xfd3f, 1},
+		{0xfe10, 0xfe19, 1},
+		{0xfe30, 0xfe52, 1},
+		{0xfe54, 0xfe66, 1},
+		{0xfe68, 0xfe6b, 1},
+		{0xfeff, 0xfeff, 1},
+		{0xff01, 0xff20, 1},
+		{0xff3b, 0xff40, 1},
+		{0xff5b, 0xff65, 1},
+		{0xff70, 0xff70, 1},
+		{0xff9e, 0xff9f, 1},
+		{0xffe0, 0xffe6, 1},
+		{0xffe8, 0xffee, 1},
+		{0xfff9, 0xfffd, 1},
+	},
+	R32: []Range32{
+		{0x10100, 0x10102, 1},
+		{0x10107, 0x10133, 1},
+		{0x10137, 0x1013f, 1},
+		{0x10190, 0x1019b, 1},
+		{0x101d0, 0x101fc, 1},
+		{0x102e1, 0x102fb, 1},
+		{0x1bca0, 0x1bca3, 1},
+		{0x1d000, 0x1d0f5, 1},
+		{0x1d100, 0x1d126, 1},
+		{0x1d129, 0x1d166, 1},
+		{0x1d16a, 0x1d17a, 1},
+		{0x1d183, 0x1d184, 1},
+		{0x1d18c, 0x1d1a9, 1},
+		{0x1d1ae, 0x1d1dd, 1},
+		{0x1d300, 0x1d356, 1},
+		{0x1d360, 0x1d371, 1},
+		{0x1d400, 0x1d454, 1},
+		{0x1d456, 0x1d49c, 1},
+		{0x1d49e, 0x1d49f, 1},
+		{0x1d4a2, 0x1d4a2, 1},
+		{0x1d4a5, 0x1d4a6, 1},
+		{0x1d4a9, 0x1d4ac, 1},
+		{0x1d4ae, 0x1d4b9, 1},
+		{0x1d4bb, 0x1d4bb, 1},
+		{0x1d4bd, 0x1d4c3, 1},
+		{0x1d4c5, 0x1d505, 1},
+		{0x1d507, 0x1d50a, 1},
+		{0x1d50d, 0x1d514, 1},
+		{0x1d516, 0x1d51c, 1},
+		{0x1d51e, 0x1d539, 1},
+		{0x1d53b, 0x1d53e, 1},
+		{0x1d540, 0x1d544, 1},
+		{0x1d546, 0x1d546, 1},
+		{0x1d54a, 0x1d550, 1},
+		{0x1d552, 0x1d6a5, 1},
+		{0x1d6a8, 0x1d7cb, 1},
+		{0x1d7ce, 0x1d7ff, 1},
+		{0x1f000, 0x1f02b, 1},
+		{0x1f030, 0x1f093, 1},
+		{0x1f0a0, 0x1f0ae, 1},
+		{0x1f0b1, 0x1f0bf, 1},
+		{0x1f0c1, 0x1f0cf, 1},
+		{0x1f0d1, 0x1f0f5, 1},
+		{0x1f100, 0x1f10c, 1},
+		{0x1f110, 0x1f12e, 1},
+		{0x1f130, 0x1f16b, 1},
+		{0x1f170, 0x1f19a, 1},
+		{0x1f1e6, 0x1f1ff, 1},
+		{0x1f201, 0x1f202, 1},
+		{0x1f210, 0x1f23a, 1},
+		{0x1f240, 0x1f248, 1},
+		{0x1f250, 0x1f251, 1},
+		{0x1f300, 0x1f32c, 1},
+		{0x1f330, 0x1f37d, 1},
+		{0x1f380, 0x1f3ce, 1},
+		{0x1f3d4, 0x1f3f7, 1},
+		{0x1f400, 0x1f4fe, 1},
+		{0x1f500, 0x1f54a, 1},
+		{0x1f550, 0x1f579, 1},
+		{0x1f57b, 0x1f5a3, 1},
+		{0x1f5a5, 0x1f642, 1},
+		{0x1f645, 0x1f6cf, 1},
+		{0x1f6e0, 0x1f6ec, 1},
+		{0x1f6f0, 0x1f6f3, 1},
+		{0x1f700, 0x1f773, 1},
+		{0x1f780, 0x1f7d4, 1},
+		{0x1f800, 0x1f80b, 1},
+		{0x1f810, 0x1f847, 1},
+		{0x1f850, 0x1f859, 1},
+		{0x1f860, 0x1f887, 1},
+		{0x1f890, 0x1f8ad, 1},
+		{0xe0001, 0xe0001, 1},
+		{0xe0020, 0xe007f, 1},
+	},
+	LatinOffset: 7,
+}
+
+var _Coptic = &RangeTable{
+	R16: []Range16{
+		{0x03e2, 0x03ef, 1},
+		{0x2c80, 0x2cf3, 1},
+		{0x2cf9, 0x2cff, 1},
+	},
+}
+
+var _Cuneiform = &RangeTable{
+	R16: []Range16{},
+	R32: []Range32{
+		{0x12000, 0x12398, 1},
+		{0x12400, 0x1246e, 1},
+		{0x12470, 0x12474, 1},
+	},
+}
+
+var _Cypriot = &RangeTable{
+	R16: []Range16{},
+	R32: []Range32{
+		{0x10800, 0x10805, 1},
+		{0x10808, 0x10808, 1},
+		{0x1080a, 0x10835, 1},
+		{0x10837, 0x10838, 1},
+		{0x1083c, 0x1083c, 1},
+		{0x1083f, 0x1083f, 1},
+	},
+}
+
+var _Cyrillic = &RangeTable{
+	R16: []Range16{
+		{0x0400, 0x0484, 1},
+		{0x0487, 0x052f, 1},
+		{0x1d2b, 0x1d2b, 1},
+		{0x1d78, 0x1d78, 1},
+		{0x2de0, 0x2dff, 1},
+		{0xa640, 0xa69d, 1},
+		{0xa69f, 0xa69f, 1},
+	},
+}
+
+var _Deseret = &RangeTable{
+	R16: []Range16{},
+	R32: []Range32{
+		{0x10400, 0x1044f, 1},
+	},
+}
+
+var _Devanagari = &RangeTable{
+	R16: []Range16{
+		{0x0900, 0x0950, 1},
+		{0x0953, 0x0963, 1},
+		{0x0966, 0x097f, 1},
+		{0xa8e0, 0xa8fb, 1},
+	},
+}
+
+var _Duployan = &RangeTable{
+	R16: []Range16{},
+	R32: []Range32{
+		{0x1bc00, 0x1bc6a, 1},
+		{0x1bc70, 0x1bc7c, 1},
+		{0x1bc80, 0x1bc88, 1},
+		{0x1bc90, 0x1bc99, 1},
+		{0x1bc9c, 0x1bc9f, 1},
+	},
+}
+
+var _Egyptian_Hieroglyphs = &RangeTable{
+	R16: []Range16{},
+	R32: []Range32{
+		{0x13000, 0x1342e, 1},
+	},
+}
+
+var _Elbasan = &RangeTable{
+	R16: []Range16{},
+	R32: []Range32{
+		{0x10500, 0x10527, 1},
+	},
+}
+
+var _Ethiopic = &RangeTable{
+	R16: []Range16{
+		{0x1200, 0x1248, 1},
+		{0x124a, 0x124d, 1},
+		{0x1250, 0x1256, 1},
+		{0x1258, 0x1258, 1},
+		{0x125a, 0x125d, 1},
+		{0x1260, 0x1288, 1},
+		{0x128a, 0x128d, 1},
+		{0x1290, 0x12b0, 1},
+		{0x12b2, 0x12b5, 1},
+		{0x12b8, 0x12be, 1},
+		{0x12c0, 0x12c0, 1},
+		{0x12c2, 0x12c5, 1},
+		{0x12c8, 0x12d6, 1},
+		{0x12d8, 0x1310, 1},
+		{0x1312, 0x1315, 1},
+		{0x1318, 0x135a, 1},
+		{0x135d, 0x137c, 1},
+		{0x1380, 0x1399, 1},
+		{0x2d80, 0x2d96, 1},
+		{0x2da0, 0x2da6, 1},
+		{0x2da8, 0x2dae, 1},
+		{0x2db0, 0x2db6, 1},
+		{0x2db8, 0x2dbe, 1},
+		{0x2dc0, 0x2dc6, 1},
+		{0x2dc8, 0x2dce, 1},
+		{0x2dd0, 0x2dd6, 1},
+		{0x2dd8, 0x2dde, 1},
+		{0xab01, 0xab06, 1},
+		{0xab09, 0xab0e, 1},
+		{0xab11, 0xab16, 1},
+		{0xab20, 0xab26, 1},
+		{0xab28, 0xab2e, 1},
+	},
+}
+
+var _Georgian = &RangeTable{
+	R16: []Range16{
+		{0x10a0, 0x10c5, 1},
+		{0x10c7, 0x10c7, 1},
+		{0x10cd, 0x10cd, 1},
+		{0x10d0, 0x10fa, 1},
+		{0x10fc, 0x10ff, 1},
+		{0x2d00, 0x2d25, 1},
+		{0x2d27, 0x2d27, 1},
+		{0x2d2d, 0x2d2d, 1},
+	},
+}
+
+var _Glagolitic = &RangeTable{
+	R16: []Range16{
+		{0x2c00, 0x2c2e, 1},
+		{0x2c30, 0x2c5e, 1},
+	},
+}
+
+var _Gothic = &RangeTable{
+	R16: []Range16{},
+	R32: []Range32{
+		{0x10330, 0x1034a, 1},
+	},
+}
+
+var _Grantha = &RangeTable{
+	R16: []Range16{},
+	R32: []Range32{
+		{0x11301, 0x11303, 1},
+		{0x11305, 0x1130c, 1},
+		{0x1130f, 0x11310, 1},
+		{0x11313, 0x11328, 1},
+		{0x1132a, 0x11330, 1},
+		{0x11332, 0x11333, 1},
+		{0x11335, 0x11339, 1},
+		{0x1133c, 0x11344, 1},
+		{0x11347, 0x11348, 1},
+		{0x1134b, 0x1134d, 1},
+		{0x11357, 0x11357, 1},
+		{0x1135d, 0x11363, 1},
+		{0x11366, 0x1136c, 1},
+		{0x11370, 0x11374, 1},
+	},
+}
+
+var _Greek = &RangeTable{
+	R16: []Range16{
+		{0x0370, 0x0373, 1},
+		{0x0375, 0x0377, 1},
+		{0x037a, 0x037d, 1},
+		{0x037f, 0x037f, 1},
+		{0x0384, 0x0384, 1},
+		{0x0386, 0x0386, 1},
+		{0x0388, 0x038a, 1},
+		{0x038c, 0x038c, 1},
+		{0x038e, 0x03a1, 1},
+		{0x03a3, 0x03e1, 1},
+		{0x03f0, 0x03ff, 1},
+		{0x1d26, 0x1d2a, 1},
+		{0x1d5d, 0x1d61, 1},
+		{0x1d66, 0x1d6a, 1},
+		{0x1dbf, 0x1dbf, 1},
+		{0x1f00, 0x1f15, 1},
+		{0x1f18, 0x1f1d, 1},
+		{0x1f20, 0x1f45, 1},
+		{0x1f48, 0x1f4d, 1},
+		{0x1f50, 0x1f57, 1},
+		{0x1f59, 0x1f59, 1},
+		{0x1f5b, 0x1f5b, 1},
+		{0x1f5d, 0x1f5d, 1},
+		{0x1f5f, 0x1f7d, 1},
+		{0x1f80, 0x1fb4, 1},
+		{0x1fb6, 0x1fc4, 1},
+		{0x1fc6, 0x1fd3, 1},
+		{0x1fd6, 0x1fdb, 1},
+		{0x1fdd, 0x1fef, 1},
+		{0x1ff2, 0x1ff4, 1},
+		{0x1ff6, 0x1ffe, 1},
+		{0x2126, 0x2126, 1},
+		{0xab65, 0xab65, 1},
+	},
+	R32: []Range32{
+		{0x10140, 0x1018c, 1},
+		{0x101a0, 0x101a0, 1},
+		{0x1d200, 0x1d245, 1},
+	},
+}
+
+var _Gujarati = &RangeTable{
+	R16: []Range16{
+		{0x0a81, 0x0a83, 1},
+		{0x0a85, 0x0a8d, 1},
+		{0x0a8f, 0x0a91, 1},
+		{0x0a93, 0x0aa8, 1},
+		{0x0aaa, 0x0ab0, 1},
+		{0x0ab2, 0x0ab3, 1},
+		{0x0ab5, 0x0ab9, 1},
+		{0x0abc, 0x0ac5, 1},
+		{0x0ac7, 0x0ac9, 1},
+		{0x0acb, 0x0acd, 1},
+		{0x0ad0, 0x0ad0, 1},
+		{0x0ae0, 0x0ae3, 1},
+		{0x0ae6, 0x0af1, 1},
+	},
+}
+
+var _Gurmukhi = &RangeTable{
+	R16: []Range16{
+		{0x0a01, 0x0a03, 1},
+		{0x0a05, 0x0a0a, 1},
+		{0x0a0f, 0x0a10, 1},
+		{0x0a13, 0x0a28, 1},
+		{0x0a2a, 0x0a30, 1},
+		{0x0a32, 0x0a33, 1},
+		{0x0a35, 0x0a36, 1},
+		{0x0a38, 0x0a39, 1},
+		{0x0a3c, 0x0a3c, 1},
+		{0x0a3e, 0x0a42, 1},
+		{0x0a47, 0x0a48, 1},
+		{0x0a4b, 0x0a4d, 1},
+		{0x0a51, 0x0a51, 1},
+		{0x0a59, 0x0a5c, 1},
+		{0x0a5e, 0x0a5e, 1},
+		{0x0a66, 0x0a75, 1},
+	},
+}
+
+var _Han = &RangeTable{
+	R16: []Range16{
+		{0x2e80, 0x2e99, 1},
+		{0x2e9b, 0x2ef3, 1},
+		{0x2f00, 0x2fd5, 1},
+		{0x3005, 0x3005, 1},
+		{0x3007, 0x3007, 1},
+		{0x3021, 0x3029, 1},
+		{0x3038, 0x303b, 1},
+		{0x3400, 0x4db5, 1},
+		{0x4e00, 0x9fcc, 1},
+		{0xf900, 0xfa6d, 1},
+		{0xfa70, 0xfad9, 1},
+	},
+	R32: []Range32{
+		{0x20000, 0x2a6d6, 1},
+		{0x2a700, 0x2b734, 1},
+		{0x2b740, 0x2b81d, 1},
+		{0x2f800, 0x2fa1d, 1},
+	},
+}
+
+var _Hangul = &RangeTable{
+	R16: []Range16{
+		{0x1100, 0x11ff, 1},
+		{0x302e, 0x302f, 1},
+		{0x3131, 0x318e, 1},
+		{0x3200, 0x321e, 1},
+		{0x3260, 0x327e, 1},
+		{0xa960, 0xa97c, 1},
+		{0xac00, 0xd7a3, 1},
+		{0xd7b0, 0xd7c6, 1},
+		{0xd7cb, 0xd7fb, 1},
+		{0xffa0, 0xffbe, 1},
+		{0xffc2, 0xffc7, 1},
+		{0xffca, 0xffcf, 1},
+		{0xffd2, 0xffd7, 1},
+		{0xffda, 0xffdc, 1},
+	},
+}
+
+var _Hanunoo = &RangeTable{
+	R16: []Range16{
+		{0x1720, 0x1734, 1},
+	},
+}
+
+var _Hebrew = &RangeTable{
+	R16: []Range16{
+		{0x0591, 0x05c7, 1},
+		{0x05d0, 0x05ea, 1},
+		{0x05f0, 0x05f4, 1},
+		{0xfb1d, 0xfb36, 1},
+		{0xfb38, 0xfb3c, 1},
+		{0xfb3e, 0xfb3e, 1},
+		{0xfb40, 0xfb41, 1},
+		{0xfb43, 0xfb44, 1},
+		{0xfb46, 0xfb4f, 1},
+	},
+}
+
+var _Hiragana = &RangeTable{
+	R16: []Range16{
+		{0x3041, 0x3096, 1},
+		{0x309d, 0x309f, 1},
+	},
+	R32: []Range32{
+		{0x1b001, 0x1b001, 1},
+		{0x1f200, 0x1f200, 1},
+	},
+}
+
+var _Imperial_Aramaic = &RangeTable{
+	R16: []Range16{},
+	R32: []Range32{
+		{0x10840, 0x10855, 1},
+		{0x10857, 0x1085f, 1},
+	},
+}
+
+var _Inherited = &RangeTable{
+	R16: []Range16{
+		{0x0300, 0x036f, 1},
+		{0x0485, 0x0486, 1},
+		{0x064b, 0x0655, 1},
+		{0x0670, 0x0670, 1},
+		{0x0951, 0x0952, 1},
+		{0x1ab0, 0x1abe, 1},
+		{0x1cd0, 0x1cd2, 1},
+		{0x1cd4, 0x1ce0, 1},
+		{0x1ce2, 0x1ce8, 1},
+		{0x1ced, 0x1ced, 1},
+		{0x1cf4, 0x1cf4, 1},
+		{0x1cf8, 0x1cf9, 1},
+		{0x1dc0, 0x1df5, 1},
+		{0x1dfc, 0x1dff, 1},
+		{0x200c, 0x200d, 1},
+		{0x20d0, 0x20f0, 1},
+		{0x302a, 0x302d, 1},
+		{0x3099, 0x309a, 1},
+		{0xfe00, 0xfe0f, 1},
+		{0xfe20, 0xfe2d, 1},
+	},
+	R32: []Range32{
+		{0x101fd, 0x101fd, 1},
+		{0x102e0, 0x102e0, 1},
+		{0x1d167, 0x1d169, 1},
+		{0x1d17b, 0x1d182, 1},
+		{0x1d185, 0x1d18b, 1},
+		{0x1d1aa, 0x1d1ad, 1},
+		{0xe0100, 0xe01ef, 1},
+	},
+}
+
+var _Inscriptional_Pahlavi = &RangeTable{
+	R16: []Range16{},
+	R32: []Range32{
+		{0x10b60, 0x10b72, 1},
+		{0x10b78, 0x10b7f, 1},
+	},
+}
+
+var _Inscriptional_Parthian = &RangeTable{
+	R16: []Range16{},
+	R32: []Range32{
+		{0x10b40, 0x10b55, 1},
+		{0x10b58, 0x10b5f, 1},
+	},
+}
+
+var _Javanese = &RangeTable{
+	R16: []Range16{
+		{0xa980, 0xa9cd, 1},
+		{0xa9d0, 0xa9d9, 1},
+		{0xa9de, 0xa9df, 1},
+	},
+}
+
+var _Kaithi = &RangeTable{
+	R16: []Range16{},
+	R32: []Range32{
+		{0x11080, 0x110c1, 1},
+	},
+}
+
+var _Kannada = &RangeTable{
+	R16: []Range16{
+		{0x0c81, 0x0c83, 1},
+		{0x0c85, 0x0c8c, 1},
+		{0x0c8e, 0x0c90, 1},
+		{0x0c92, 0x0ca8, 1},
+		{0x0caa, 0x0cb3, 1},
+		{0x0cb5, 0x0cb9, 1},
+		{0x0cbc, 0x0cc4, 1},
+		{0x0cc6, 0x0cc8, 1},
+		{0x0cca, 0x0ccd, 1},
+		{0x0cd5, 0x0cd6, 1},
+		{0x0cde, 0x0cde, 1},
+		{0x0ce0, 0x0ce3, 1},
+		{0x0ce6, 0x0cef, 1},
+		{0x0cf1, 0x0cf2, 1},
+	},
+}
+
+var _Katakana = &RangeTable{
+	R16: []Range16{
+		{0x30a1, 0x30fa, 1},
+		{0x30fd, 0x30ff, 1},
+		{0x31f0, 0x31ff, 1},
+		{0x32d0, 0x32fe, 1},
+		{0x3300, 0x3357, 1},
+		{0xff66, 0xff6f, 1},
+		{0xff71, 0xff9d, 1},
+	},
+	R32: []Range32{
+		{0x1b000, 0x1b000, 1},
+	},
+}
+
+var _Kayah_Li = &RangeTable{
+	R16: []Range16{
+		{0xa900, 0xa92d, 1},
+		{0xa92f, 0xa92f, 1},
+	},
+}
+
+var _Kharoshthi = &RangeTable{
+	R16: []Range16{},
+	R32: []Range32{
+		{0x10a00, 0x10a03, 1},
+		{0x10a05, 0x10a06, 1},
+		{0x10a0c, 0x10a13, 1},
+		{0x10a15, 0x10a17, 1},
+		{0x10a19, 0x10a33, 1},
+		{0x10a38, 0x10a3a, 1},
+		{0x10a3f, 0x10a47, 1},
+		{0x10a50, 0x10a58, 1},
+	},
+}
+
+var _Khmer = &RangeTable{
+	R16: []Range16{
+		{0x1780, 0x17dd, 1},
+		{0x17e0, 0x17e9, 1},
+		{0x17f0, 0x17f9, 1},
+		{0x19e0, 0x19ff, 1},
+	},
+}
+
+var _Khojki = &RangeTable{
+	R16: []Range16{},
+	R32: []Range32{
+		{0x11200, 0x11211, 1},
+		{0x11213, 0x1123d, 1},
+	},
+}
+
+var _Khudawadi = &RangeTable{
+	R16: []Range16{},
+	R32: []Range32{
+		{0x112b0, 0x112ea, 1},
+		{0x112f0, 0x112f9, 1},
+	},
+}
+
+var _Lao = &RangeTable{
+	R16: []Range16{
+		{0x0e81, 0x0e82, 1},
+		{0x0e84, 0x0e84, 1},
+		{0x0e87, 0x0e88, 1},
+		{0x0e8a, 0x0e8a, 1},
+		{0x0e8d, 0x0e8d, 1},
+		{0x0e94, 0x0e97, 1},
+		{0x0e99, 0x0e9f, 1},
+		{0x0ea1, 0x0ea3, 1},
+		{0x0ea5, 0x0ea5, 1},
+		{0x0ea7, 0x0ea7, 1},
+		{0x0eaa, 0x0eab, 1},
+		{0x0ead, 0x0eb9, 1},
+		{0x0ebb, 0x0ebd, 1},
+		{0x0ec0, 0x0ec4, 1},
+		{0x0ec6, 0x0ec6, 1},
+		{0x0ec8, 0x0ecd, 1},
+		{0x0ed0, 0x0ed9, 1},
+		{0x0edc, 0x0edf, 1},
+	},
+}
+
+var _Latin = &RangeTable{
+	R16: []Range16{
+		{0x0041, 0x005a, 1},
+		{0x0061, 0x007a, 1},
+		{0x00aa, 0x00aa, 1},
+		{0x00ba, 0x00ba, 1},
+		{0x00c0, 0x00d6, 1},
+		{0x00d8, 0x00f6, 1},
+		{0x00f8, 0x02b8, 1},
+		{0x02e0, 0x02e4, 1},
+		{0x1d00, 0x1d25, 1},
+		{0x1d2c, 0x1d5c, 1},
+		{0x1d62, 0x1d65, 1},
+		{0x1d6b, 0x1d77, 1},
+		{0x1d79, 0x1dbe, 1},
+		{0x1e00, 0x1eff, 1},
+		{0x2071, 0x2071, 1},
+		{0x207f, 0x207f, 1},
+		{0x2090, 0x209c, 1},
+		{0x212a, 0x212b, 1},
+		{0x2132, 0x2132, 1},
+		{0x214e, 0x214e, 1},
+		{0x2160, 0x2188, 1},
+		{0x2c60, 0x2c7f, 1},
+		{0xa722, 0xa787, 1},
+		{0xa78b, 0xa78e, 1},
+		{0xa790, 0xa7ad, 1},
+		{0xa7b0, 0xa7b1, 1},
+		{0xa7f7, 0xa7ff, 1},
+		{0xab30, 0xab5a, 1},
+		{0xab5c, 0xab5f, 1},
+		{0xab64, 0xab64, 1},
+		{0xfb00, 0xfb06, 1},
+		{0xff21, 0xff3a, 1},
+		{0xff41, 0xff5a, 1},
+	},
+	LatinOffset: 6,
+}
+
+var _Lepcha = &RangeTable{
+	R16: []Range16{
+		{0x1c00, 0x1c37, 1},
+		{0x1c3b, 0x1c49, 1},
+		{0x1c4d, 0x1c4f, 1},
+	},
+}
+
+var _Limbu = &RangeTable{
+	R16: []Range16{
+		{0x1900, 0x191e, 1},
+		{0x1920, 0x192b, 1},
+		{0x1930, 0x193b, 1},
+		{0x1940, 0x1940, 1},
+		{0x1944, 0x194f, 1},
+	},
+}
+
+var _Linear_A = &RangeTable{
+	R16: []Range16{},
+	R32: []Range32{
+		{0x10600, 0x10736, 1},
+		{0x10740, 0x10755, 1},
+		{0x10760, 0x10767, 1},
+	},
+}
+
+var _Linear_B = &RangeTable{
+	R16: []Range16{},
+	R32: []Range32{
+		{0x10000, 0x1000b, 1},
+		{0x1000d, 0x10026, 1},
+		{0x10028, 0x1003a, 1},
+		{0x1003c, 0x1003d, 1},
+		{0x1003f, 0x1004d, 1},
+		{0x10050, 0x1005d, 1},
+		{0x10080, 0x100fa, 1},
+	},
+}
+
+var _Lisu = &RangeTable{
+	R16: []Range16{
+		{0xa4d0, 0xa4ff, 1},
+	},
+}
+
+var _Lycian = &RangeTable{
+	R16: []Range16{},
+	R32: []Range32{
+		{0x10280, 0x1029c, 1},
+	},
+}
+
+var _Lydian = &RangeTable{
+	R16: []Range16{},
+	R32: []Range32{
+		{0x10920, 0x10939, 1},
+		{0x1093f, 0x1093f, 1},
+	},
+}
+
+var _Mahajani = &RangeTable{
+	R16: []Range16{},
+	R32: []Range32{
+		{0x11150, 0x11176, 1},
+	},
+}
+
+var _Malayalam = &RangeTable{
+	R16: []Range16{
+		{0x0d01, 0x0d03, 1},
+		{0x0d05, 0x0d0c, 1},
+		{0x0d0e, 0x0d10, 1},
+		{0x0d12, 0x0d3a, 1},
+		{0x0d3d, 0x0d44, 1},
+		{0x0d46, 0x0d48, 1},
+		{0x0d4a, 0x0d4e, 1},
+		{0x0d57, 0x0d57, 1},
+		{0x0d60, 0x0d63, 1},
+		{0x0d66, 0x0d75, 1},
+		{0x0d79, 0x0d7f, 1},
+	},
+}
+
+var _Mandaic = &RangeTable{
+	R16: []Range16{
+		{0x0840, 0x085b, 1},
+		{0x085e, 0x085e, 1},
+	},
+}
+
+var _Manichaean = &RangeTable{
+	R16: []Range16{},
+	R32: []Range32{
+		{0x10ac0, 0x10ae6, 1},
+		{0x10aeb, 0x10af6, 1},
+	},
+}
+
+var _Meetei_Mayek = &RangeTable{
+	R16: []Range16{
+		{0xaae0, 0xaaf6, 1},
+		{0xabc0, 0xabed, 1},
+		{0xabf0, 0xabf9, 1},
+	},
+}
+
+var _Mende_Kikakui = &RangeTable{
+	R16: []Range16{},
+	R32: []Range32{
+		{0x1e800, 0x1e8c4, 1},
+		{0x1e8c7, 0x1e8d6, 1},
+	},
+}
+
+var _Meroitic_Cursive = &RangeTable{
+	R16: []Range16{},
+	R32: []Range32{
+		{0x109a0, 0x109b7, 1},
+		{0x109be, 0x109bf, 1},
+	},
+}
+
+var _Meroitic_Hieroglyphs = &RangeTable{
+	R16: []Range16{},
+	R32: []Range32{
+		{0x10980, 0x1099f, 1},
+	},
+}
+
+var _Miao = &RangeTable{
+	R16: []Range16{},
+	R32: []Range32{
+		{0x16f00, 0x16f44, 1},
+		{0x16f50, 0x16f7e, 1},
+		{0x16f8f, 0x16f9f, 1},
+	},
+}
+
+var _Modi = &RangeTable{
+	R16: []Range16{},
+	R32: []Range32{
+		{0x11600, 0x11644, 1},
+		{0x11650, 0x11659, 1},
+	},
+}
+
+var _Mongolian = &RangeTable{
+	R16: []Range16{
+		{0x1800, 0x1801, 1},
+		{0x1804, 0x1804, 1},
+		{0x1806, 0x180e, 1},
+		{0x1810, 0x1819, 1},
+		{0x1820, 0x1877, 1},
+		{0x1880, 0x18aa, 1},
+	},
+}
+
+var _Mro = &RangeTable{
+	R16: []Range16{},
+	R32: []Range32{
+		{0x16a40, 0x16a5e, 1},
+		{0x16a60, 0x16a69, 1},
+		{0x16a6e, 0x16a6f, 1},
+	},
+}
+
+var _Myanmar = &RangeTable{
+	R16: []Range16{
+		{0x1000, 0x109f, 1},
+		{0xa9e0, 0xa9fe, 1},
+		{0xaa60, 0xaa7f, 1},
+	},
+}
+
+var _Nabataean = &RangeTable{
+	R16: []Range16{},
+	R32: []Range32{
+		{0x10880, 0x1089e, 1},
+		{0x108a7, 0x108af, 1},
+	},
+}
+
+var _New_Tai_Lue = &RangeTable{
+	R16: []Range16{
+		{0x1980, 0x19ab, 1},
+		{0x19b0, 0x19c9, 1},
+		{0x19d0, 0x19da, 1},
+		{0x19de, 0x19df, 1},
+	},
+}
+
+var _Nko = &RangeTable{
+	R16: []Range16{
+		{0x07c0, 0x07fa, 1},
+	},
+}
+
+var _Ogham = &RangeTable{
+	R16: []Range16{
+		{0x1680, 0x169c, 1},
+	},
+}
+
+var _Ol_Chiki = &RangeTable{
+	R16: []Range16{
+		{0x1c50, 0x1c7f, 1},
+	},
+}
+
+var _Old_Italic = &RangeTable{
+	R16: []Range16{},
+	R32: []Range32{
+		{0x10300, 0x10323, 1},
+	},
+}
+
+var _Old_North_Arabian = &RangeTable{
+	R16: []Range16{},
+	R32: []Range32{
+		{0x10a80, 0x10a9f, 1},
+	},
+}
+
+var _Old_Permic = &RangeTable{
+	R16: []Range16{},
+	R32: []Range32{
+		{0x10350, 0x1037a, 1},
+	},
+}
+
+var _Old_Persian = &RangeTable{
+	R16: []Range16{},
+	R32: []Range32{
+		{0x103a0, 0x103c3, 1},
+		{0x103c8, 0x103d5, 1},
+	},
+}
+
+var _Old_South_Arabian = &RangeTable{
+	R16: []Range16{},
+	R32: []Range32{
+		{0x10a60, 0x10a7f, 1},
+	},
+}
+
+var _Old_Turkic = &RangeTable{
+	R16: []Range16{},
+	R32: []Range32{
+		{0x10c00, 0x10c48, 1},
+	},
+}
+
+var _Oriya = &RangeTable{
+	R16: []Range16{
+		{0x0b01, 0x0b03, 1},
+		{0x0b05, 0x0b0c, 1},
+		{0x0b0f, 0x0b10, 1},
+		{0x0b13, 0x0b28, 1},
+		{0x0b2a, 0x0b30, 1},
+		{0x0b32, 0x0b33, 1},
+		{0x0b35, 0x0b39, 1},
+		{0x0b3c, 0x0b44, 1},
+		{0x0b47, 0x0b48, 1},
+		{0x0b4b, 0x0b4d, 1},
+		{0x0b56, 0x0b57, 1},
+		{0x0b5c, 0x0b5d, 1},
+		{0x0b5f, 0x0b63, 1},
+		{0x0b66, 0x0b77, 1},
+	},
+}
+
+var _Osmanya = &RangeTable{
+	R16: []Range16{},
+	R32: []Range32{
+		{0x10480, 0x1049d, 1},
+		{0x104a0, 0x104a9, 1},
+	},
+}
+
+var _Pahawh_Hmong = &RangeTable{
+	R16: []Range16{},
+	R32: []Range32{
+		{0x16b00, 0x16b45, 1},
+		{0x16b50, 0x16b59, 1},
+		{0x16b5b, 0x16b61, 1},
+		{0x16b63, 0x16b77, 1},
+		{0x16b7d, 0x16b8f, 1},
+	},
+}
+
+var _Palmyrene = &RangeTable{
+	R16: []Range16{},
+	R32: []Range32{
+		{0x10860, 0x1087f, 1},
+	},
+}
+
+var _Pau_Cin_Hau = &RangeTable{
+	R16: []Range16{},
+	R32: []Range32{
+		{0x11ac0, 0x11af8, 1},
+	},
+}
+
+var _Phags_Pa = &RangeTable{
+	R16: []Range16{
+		{0xa840, 0xa877, 1},
+	},
+}
+
+var _Phoenician = &RangeTable{
+	R16: []Range16{},
+	R32: []Range32{
+		{0x10900, 0x1091b, 1},
+		{0x1091f, 0x1091f, 1},
+	},
+}
+
+var _Psalter_Pahlavi = &RangeTable{
+	R16: []Range16{},
+	R32: []Range32{
+		{0x10b80, 0x10b91, 1},
+		{0x10b99, 0x10b9c, 1},
+		{0x10ba9, 0x10baf, 1},
+	},
+}
+
+var _Rejang = &RangeTable{
+	R16: []Range16{
+		{0xa930, 0xa953, 1},
+		{0xa95f, 0xa95f, 1},
+	},
+}
+
+var _Runic = &RangeTable{
+	R16: []Range16{
+		{0x16a0, 0x16ea, 1},
+		{0x16ee, 0x16f8, 1},
+	},
+}
+
+var _Samaritan = &RangeTable{
+	R16: []Range16{
+		{0x0800, 0x082d, 1},
+		{0x0830, 0x083e, 1},
+	},
+}
+
+var _Saurashtra = &RangeTable{
+	R16: []Range16{
+		{0xa880, 0xa8c4, 1},
+		{0xa8ce, 0xa8d9, 1},
+	},
+}
+
+var _Sharada = &RangeTable{
+	R16: []Range16{},
+	R32: []Range32{
+		{0x11180, 0x111c8, 1},
+		{0x111cd, 0x111cd, 1},
+		{0x111d0, 0x111da, 1},
+	},
+}
+
+var _Shavian = &RangeTable{
+	R16: []Range16{},
+	R32: []Range32{
+		{0x10450, 0x1047f, 1},
+	},
+}
+
+var _Siddham = &RangeTable{
+	R16: []Range16{},
+	R32: []Range32{
+		{0x11580, 0x115b5, 1},
+		{0x115b8, 0x115c9, 1},
+	},
+}
+
+var _Sinhala = &RangeTable{
+	R16: []Range16{
+		{0x0d82, 0x0d83, 1},
+		{0x0d85, 0x0d96, 1},
+		{0x0d9a, 0x0db1, 1},
+		{0x0db3, 0x0dbb, 1},
+		{0x0dbd, 0x0dbd, 1},
+		{0x0dc0, 0x0dc6, 1},
+		{0x0dca, 0x0dca, 1},
+		{0x0dcf, 0x0dd4, 1},
+		{0x0dd6, 0x0dd6, 1},
+		{0x0dd8, 0x0ddf, 1},
+		{0x0de6, 0x0def, 1},
+		{0x0df2, 0x0df4, 1},
+	},
+	R32: []Range32{
+		{0x111e1, 0x111f4, 1},
+	},
+}
+
+var _Sora_Sompeng = &RangeTable{
+	R16: []Range16{},
+	R32: []Range32{
+		{0x110d0, 0x110e8, 1},
+		{0x110f0, 0x110f9, 1},
+	},
+}
+
+var _Sundanese = &RangeTable{
+	R16: []Range16{
+		{0x1b80, 0x1bbf, 1},
+		{0x1cc0, 0x1cc7, 1},
+	},
+}
+
+var _Syloti_Nagri = &RangeTable{
+	R16: []Range16{
+		{0xa800, 0xa82b, 1},
+	},
+}
+
+var _Syriac = &RangeTable{
+	R16: []Range16{
+		{0x0700, 0x070d, 1},
+		{0x070f, 0x074a, 1},
+		{0x074d, 0x074f, 1},
+	},
+}
+
+var _Tagalog = &RangeTable{
+	R16: []Range16{
+		{0x1700, 0x170c, 1},
+		{0x170e, 0x1714, 1},
+	},
+}
+
+var _Tagbanwa = &RangeTable{
+	R16: []Range16{
+		{0x1760, 0x176c, 1},
+		{0x176e, 0x1770, 1},
+		{0x1772, 0x1773, 1},
+	},
+}
+
+var _Tai_Le = &RangeTable{
+	R16: []Range16{
+		{0x1950, 0x196d, 1},
+		{0x1970, 0x1974, 1},
+	},
+}
+
+var _Tai_Tham = &RangeTable{
+	R16: []Range16{
+		{0x1a20, 0x1a5e, 1},
+		{0x1a60, 0x1a7c, 1},
+		{0x1a7f, 0x1a89, 1},
+		{0x1a90, 0x1a99, 1},
+		{0x1aa0, 0x1aad, 1},
+	},
+}
+
+var _Tai_Viet = &RangeTable{
+	R16: []Range16{
+		{0xaa80, 0xaac2, 1},
+		{0xaadb, 0xaadf, 1},
+	},
+}
+
+var _Takri = &RangeTable{
+	R16: []Range16{},
+	R32: []Range32{
+		{0x11680, 0x116b7, 1},
+		{0x116c0, 0x116c9, 1},
+	},
+}
+
+var _Tamil = &RangeTable{
+	R16: []Range16{
+		{0x0b82, 0x0b83, 1},
+		{0x0b85, 0x0b8a, 1},
+		{0x0b8e, 0x0b90, 1},
+		{0x0b92, 0x0b95, 1},
+		{0x0b99, 0x0b9a, 1},
+		{0x0b9c, 0x0b9c, 1},
+		{0x0b9e, 0x0b9f, 1},
+		{0x0ba3, 0x0ba4, 1},
+		{0x0ba8, 0x0baa, 1},
+		{0x0bae, 0x0bb9, 1},
+		{0x0bbe, 0x0bc2, 1},
+		{0x0bc6, 0x0bc8, 1},
+		{0x0bca, 0x0bcd, 1},
+		{0x0bd0, 0x0bd0, 1},
+		{0x0bd7, 0x0bd7, 1},
+		{0x0be6, 0x0bfa, 1},
+	},
+}
+
+var _Telugu = &RangeTable{
+	R16: []Range16{
+		{0x0c00, 0x0c03, 1},
+		{0x0c05, 0x0c0c, 1},
+		{0x0c0e, 0x0c10, 1},
+		{0x0c12, 0x0c28, 1},
+		{0x0c2a, 0x0c39, 1},
+		{0x0c3d, 0x0c44, 1},
+		{0x0c46, 0x0c48, 1},
+		{0x0c4a, 0x0c4d, 1},
+		{0x0c55, 0x0c56, 1},
+		{0x0c58, 0x0c59, 1},
+		{0x0c60, 0x0c63, 1},
+		{0x0c66, 0x0c6f, 1},
+		{0x0c78, 0x0c7f, 1},
+	},
+}
+
+var _Thaana = &RangeTable{
+	R16: []Range16{
+		{0x0780, 0x07b1, 1},
+	},
+}
+
+var _Thai = &RangeTable{
+	R16: []Range16{
+		{0x0e01, 0x0e3a, 1},
+		{0x0e40, 0x0e5b, 1},
+	},
+}
+
+var _Tibetan = &RangeTable{
+	R16: []Range16{
+		{0x0f00, 0x0f47, 1},
+		{0x0f49, 0x0f6c, 1},
+		{0x0f71, 0x0f97, 1},
+		{0x0f99, 0x0fbc, 1},
+		{0x0fbe, 0x0fcc, 1},
+		{0x0fce, 0x0fd4, 1},
+		{0x0fd9, 0x0fda, 1},
+	},
+}
+
+var _Tifinagh = &RangeTable{
+	R16: []Range16{
+		{0x2d30, 0x2d67, 1},
+		{0x2d6f, 0x2d70, 1},
+		{0x2d7f, 0x2d7f, 1},
+	},
+}
+
+var _Tirhuta = &RangeTable{
+	R16: []Range16{},
+	R32: []Range32{
+		{0x11480, 0x114c7, 1},
+		{0x114d0, 0x114d9, 1},
+	},
+}
+
+var _Ugaritic = &RangeTable{
+	R16: []Range16{},
+	R32: []Range32{
+		{0x10380, 0x1039d, 1},
+		{0x1039f, 0x1039f, 1},
+	},
+}
+
+var _Vai = &RangeTable{
+	R16: []Range16{
+		{0xa500, 0xa62b, 1},
+	},
+}
+
+var _Warang_Citi = &RangeTable{
+	R16: []Range16{},
+	R32: []Range32{
+		{0x118a0, 0x118f2, 1},
+		{0x118ff, 0x118ff, 1},
+	},
+}
+
+var _Yi = &RangeTable{
+	R16: []Range16{
+		{0xa000, 0xa48c, 1},
+		{0xa490, 0xa4c6, 1},
+	},
+}
+
+// These variables have type *RangeTable.
+var (
+	Arabic                 = _Arabic                 // Arabic is the set of Unicode characters in script Arabic.
+	Armenian               = _Armenian               // Armenian is the set of Unicode characters in script Armenian.
+	Avestan                = _Avestan                // Avestan is the set of Unicode characters in script Avestan.
+	Balinese               = _Balinese               // Balinese is the set of Unicode characters in script Balinese.
+	Bamum                  = _Bamum                  // Bamum is the set of Unicode characters in script Bamum.
+	Bassa_Vah              = _Bassa_Vah              // Bassa_Vah is the set of Unicode characters in script Bassa_Vah.
+	Batak                  = _Batak                  // Batak is the set of Unicode characters in script Batak.
+	Bengali                = _Bengali                // Bengali is the set of Unicode characters in script Bengali.
+	Bopomofo               = _Bopomofo               // Bopomofo is the set of Unicode characters in script Bopomofo.
+	Brahmi                 = _Brahmi                 // Brahmi is the set of Unicode characters in script Brahmi.
+	Braille                = _Braille                // Braille is the set of Unicode characters in script Braille.
+	Buginese               = _Buginese               // Buginese is the set of Unicode characters in script Buginese.
+	Buhid                  = _Buhid                  // Buhid is the set of Unicode characters in script Buhid.
+	Canadian_Aboriginal    = _Canadian_Aboriginal    // Canadian_Aboriginal is the set of Unicode characters in script Canadian_Aboriginal.
+	Carian                 = _Carian                 // Carian is the set of Unicode characters in script Carian.
+	Caucasian_Albanian     = _Caucasian_Albanian     // Caucasian_Albanian is the set of Unicode characters in script Caucasian_Albanian.
+	Chakma                 = _Chakma                 // Chakma is the set of Unicode characters in script Chakma.
+	Cham                   = _Cham                   // Cham is the set of Unicode characters in script Cham.
+	Cherokee               = _Cherokee               // Cherokee is the set of Unicode characters in script Cherokee.
+	Common                 = _Common                 // Common is the set of Unicode characters in script Common.
+	Coptic                 = _Coptic                 // Coptic is the set of Unicode characters in script Coptic.
+	Cuneiform              = _Cuneiform              // Cuneiform is the set of Unicode characters in script Cuneiform.
+	Cypriot                = _Cypriot                // Cypriot is the set of Unicode characters in script Cypriot.
+	Cyrillic               = _Cyrillic               // Cyrillic is the set of Unicode characters in script Cyrillic.
+	Deseret                = _Deseret                // Deseret is the set of Unicode characters in script Deseret.
+	Devanagari             = _Devanagari             // Devanagari is the set of Unicode characters in script Devanagari.
+	Duployan               = _Duployan               // Duployan is the set of Unicode characters in script Duployan.
+	Egyptian_Hieroglyphs   = _Egyptian_Hieroglyphs   // Egyptian_Hieroglyphs is the set of Unicode characters in script Egyptian_Hieroglyphs.
+	Elbasan                = _Elbasan                // Elbasan is the set of Unicode characters in script Elbasan.
+	Ethiopic               = _Ethiopic               // Ethiopic is the set of Unicode characters in script Ethiopic.
+	Georgian               = _Georgian               // Georgian is the set of Unicode characters in script Georgian.
+	Glagolitic             = _Glagolitic             // Glagolitic is the set of Unicode characters in script Glagolitic.
+	Gothic                 = _Gothic                 // Gothic is the set of Unicode characters in script Gothic.
+	Grantha                = _Grantha                // Grantha is the set of Unicode characters in script Grantha.
+	Greek                  = _Greek                  // Greek is the set of Unicode characters in script Greek.
+	Gujarati               = _Gujarati               // Gujarati is the set of Unicode characters in script Gujarati.
+	Gurmukhi               = _Gurmukhi               // Gurmukhi is the set of Unicode characters in script Gurmukhi.
+	Han                    = _Han                    // Han is the set of Unicode characters in script Han.
+	Hangul                 = _Hangul                 // Hangul is the set of Unicode characters in script Hangul.
+	Hanunoo                = _Hanunoo                // Hanunoo is the set of Unicode characters in script Hanunoo.
+	Hebrew                 = _Hebrew                 // Hebrew is the set of Unicode characters in script Hebrew.
+	Hiragana               = _Hiragana               // Hiragana is the set of Unicode characters in script Hiragana.
+	Imperial_Aramaic       = _Imperial_Aramaic       // Imperial_Aramaic is the set of Unicode characters in script Imperial_Aramaic.
+	Inherited              = _Inherited              // Inherited is the set of Unicode characters in script Inherited.
+	Inscriptional_Pahlavi  = _Inscriptional_Pahlavi  // Inscriptional_Pahlavi is the set of Unicode characters in script Inscriptional_Pahlavi.
+	Inscriptional_Parthian = _Inscriptional_Parthian // Inscriptional_Parthian is the set of Unicode characters in script Inscriptional_Parthian.
+	Javanese               = _Javanese               // Javanese is the set of Unicode characters in script Javanese.
+	Kaithi                 = _Kaithi                 // Kaithi is the set of Unicode characters in script Kaithi.
+	Kannada                = _Kannada                // Kannada is the set of Unicode characters in script Kannada.
+	Katakana               = _Katakana               // Katakana is the set of Unicode characters in script Katakana.
+	Kayah_Li               = _Kayah_Li               // Kayah_Li is the set of Unicode characters in script Kayah_Li.
+	Kharoshthi             = _Kharoshthi             // Kharoshthi is the set of Unicode characters in script Kharoshthi.
+	Khmer                  = _Khmer                  // Khmer is the set of Unicode characters in script Khmer.
+	Khojki                 = _Khojki                 // Khojki is the set of Unicode characters in script Khojki.
+	Khudawadi              = _Khudawadi              // Khudawadi is the set of Unicode characters in script Khudawadi.
+	Lao                    = _Lao                    // Lao is the set of Unicode characters in script Lao.
+	Latin                  = _Latin                  // Latin is the set of Unicode characters in script Latin.
+	Lepcha                 = _Lepcha                 // Lepcha is the set of Unicode characters in script Lepcha.
+	Limbu                  = _Limbu                  // Limbu is the set of Unicode characters in script Limbu.
+	Linear_A               = _Linear_A               // Linear_A is the set of Unicode characters in script Linear_A.
+	Linear_B               = _Linear_B               // Linear_B is the set of Unicode characters in script Linear_B.
+	Lisu                   = _Lisu                   // Lisu is the set of Unicode characters in script Lisu.
+	Lycian                 = _Lycian                 // Lycian is the set of Unicode characters in script Lycian.
+	Lydian                 = _Lydian                 // Lydian is the set of Unicode characters in script Lydian.
+	Mahajani               = _Mahajani               // Mahajani is the set of Unicode characters in script Mahajani.
+	Malayalam              = _Malayalam              // Malayalam is the set of Unicode characters in script Malayalam.
+	Mandaic                = _Mandaic                // Mandaic is the set of Unicode characters in script Mandaic.
+	Manichaean             = _Manichaean             // Manichaean is the set of Unicode characters in script Manichaean.
+	Meetei_Mayek           = _Meetei_Mayek           // Meetei_Mayek is the set of Unicode characters in script Meetei_Mayek.
+	Mende_Kikakui          = _Mende_Kikakui          // Mende_Kikakui is the set of Unicode characters in script Mende_Kikakui.
+	Meroitic_Cursive       = _Meroitic_Cursive       // Meroitic_Cursive is the set of Unicode characters in script Meroitic_Cursive.
+	Meroitic_Hieroglyphs   = _Meroitic_Hieroglyphs   // Meroitic_Hieroglyphs is the set of Unicode characters in script Meroitic_Hieroglyphs.
+	Miao                   = _Miao                   // Miao is the set of Unicode characters in script Miao.
+	Modi                   = _Modi                   // Modi is the set of Unicode characters in script Modi.
+	Mongolian              = _Mongolian              // Mongolian is the set of Unicode characters in script Mongolian.
+	Mro                    = _Mro                    // Mro is the set of Unicode characters in script Mro.
+	Myanmar                = _Myanmar                // Myanmar is the set of Unicode characters in script Myanmar.
+	Nabataean              = _Nabataean              // Nabataean is the set of Unicode characters in script Nabataean.
+	New_Tai_Lue            = _New_Tai_Lue            // New_Tai_Lue is the set of Unicode characters in script New_Tai_Lue.
+	Nko                    = _Nko                    // Nko is the set of Unicode characters in script Nko.
+	Ogham                  = _Ogham                  // Ogham is the set of Unicode characters in script Ogham.
+	Ol_Chiki               = _Ol_Chiki               // Ol_Chiki is the set of Unicode characters in script Ol_Chiki.
+	Old_Italic             = _Old_Italic             // Old_Italic is the set of Unicode characters in script Old_Italic.
+	Old_North_Arabian      = _Old_North_Arabian      // Old_North_Arabian is the set of Unicode characters in script Old_North_Arabian.
+	Old_Permic             = _Old_Permic             // Old_Permic is the set of Unicode characters in script Old_Permic.
+	Old_Persian            = _Old_Persian            // Old_Persian is the set of Unicode characters in script Old_Persian.
+	Old_South_Arabian      = _Old_South_Arabian      // Old_South_Arabian is the set of Unicode characters in script Old_South_Arabian.
+	Old_Turkic             = _Old_Turkic             // Old_Turkic is the set of Unicode characters in script Old_Turkic.
+	Oriya                  = _Oriya                  // Oriya is the set of Unicode characters in script Oriya.
+	Osmanya                = _Osmanya                // Osmanya is the set of Unicode characters in script Osmanya.
+	Pahawh_Hmong           = _Pahawh_Hmong           // Pahawh_Hmong is the set of Unicode characters in script Pahawh_Hmong.
+	Palmyrene              = _Palmyrene              // Palmyrene is the set of Unicode characters in script Palmyrene.
+	Pau_Cin_Hau            = _Pau_Cin_Hau            // Pau_Cin_Hau is the set of Unicode characters in script Pau_Cin_Hau.
+	Phags_Pa               = _Phags_Pa               // Phags_Pa is the set of Unicode characters in script Phags_Pa.
+	Phoenician             = _Phoenician             // Phoenician is the set of Unicode characters in script Phoenician.
+	Psalter_Pahlavi        = _Psalter_Pahlavi        // Psalter_Pahlavi is the set of Unicode characters in script Psalter_Pahlavi.
+	Rejang                 = _Rejang                 // Rejang is the set of Unicode characters in script Rejang.
+	Runic                  = _Runic                  // Runic is the set of Unicode characters in script Runic.
+	Samaritan              = _Samaritan              // Samaritan is the set of Unicode characters in script Samaritan.
+	Saurashtra             = _Saurashtra             // Saurashtra is the set of Unicode characters in script Saurashtra.
+	Sharada                = _Sharada                // Sharada is the set of Unicode characters in script Sharada.
+	Shavian                = _Shavian                // Shavian is the set of Unicode characters in script Shavian.
+	Siddham                = _Siddham                // Siddham is the set of Unicode characters in script Siddham.
+	Sinhala                = _Sinhala                // Sinhala is the set of Unicode characters in script Sinhala.
+	Sora_Sompeng           = _Sora_Sompeng           // Sora_Sompeng is the set of Unicode characters in script Sora_Sompeng.
+	Sundanese              = _Sundanese              // Sundanese is the set of Unicode characters in script Sundanese.
+	Syloti_Nagri           = _Syloti_Nagri           // Syloti_Nagri is the set of Unicode characters in script Syloti_Nagri.
+	Syriac                 = _Syriac                 // Syriac is the set of Unicode characters in script Syriac.
+	Tagalog                = _Tagalog                // Tagalog is the set of Unicode characters in script Tagalog.
+	Tagbanwa               = _Tagbanwa               // Tagbanwa is the set of Unicode characters in script Tagbanwa.
+	Tai_Le                 = _Tai_Le                 // Tai_Le is the set of Unicode characters in script Tai_Le.
+	Tai_Tham               = _Tai_Tham               // Tai_Tham is the set of Unicode characters in script Tai_Tham.
+	Tai_Viet               = _Tai_Viet               // Tai_Viet is the set of Unicode characters in script Tai_Viet.
+	Takri                  = _Takri                  // Takri is the set of Unicode characters in script Takri.
+	Tamil                  = _Tamil                  // Tamil is the set of Unicode characters in script Tamil.
+	Telugu                 = _Telugu                 // Telugu is the set of Unicode characters in script Telugu.
+	Thaana                 = _Thaana                 // Thaana is the set of Unicode characters in script Thaana.
+	Thai                   = _Thai                   // Thai is the set of Unicode characters in script Thai.
+	Tibetan                = _Tibetan                // Tibetan is the set of Unicode characters in script Tibetan.
+	Tifinagh               = _Tifinagh               // Tifinagh is the set of Unicode characters in script Tifinagh.
+	Tirhuta                = _Tirhuta                // Tirhuta is the set of Unicode characters in script Tirhuta.
+	Ugaritic               = _Ugaritic               // Ugaritic is the set of Unicode characters in script Ugaritic.
+	Vai                    = _Vai                    // Vai is the set of Unicode characters in script Vai.
+	Warang_Citi            = _Warang_Citi            // Warang_Citi is the set of Unicode characters in script Warang_Citi.
+	Yi                     = _Yi                     // Yi is the set of Unicode characters in script Yi.
+)
+
+// Generated by running
+//	maketables --props=all --url=http://www.unicode.org/Public/7.0.0/ucd/
+// DO NOT EDIT
+
+// Properties is the set of Unicode property tables.
+var Properties = map[string]*RangeTable{
+	"ASCII_Hex_Digit":                    ASCII_Hex_Digit,
+	"Bidi_Control":                       Bidi_Control,
+	"Dash":                               Dash,
+	"Deprecated":                         Deprecated,
+	"Diacritic":                          Diacritic,
+	"Extender":                           Extender,
+	"Hex_Digit":                          Hex_Digit,
+	"Hyphen":                             Hyphen,
+	"IDS_Binary_Operator":                IDS_Binary_Operator,
+	"IDS_Trinary_Operator":               IDS_Trinary_Operator,
+	"Ideographic":                        Ideographic,
+	"Join_Control":                       Join_Control,
+	"Logical_Order_Exception":            Logical_Order_Exception,
+	"Noncharacter_Code_Point":            Noncharacter_Code_Point,
+	"Other_Alphabetic":                   Other_Alphabetic,
+	"Other_Default_Ignorable_Code_Point": Other_Default_Ignorable_Code_Point,
+	"Other_Grapheme_Extend":              Other_Grapheme_Extend,
+	"Other_ID_Continue":                  Other_ID_Continue,
+	"Other_ID_Start":                     Other_ID_Start,
+	"Other_Lowercase":                    Other_Lowercase,
+	"Other_Math":                         Other_Math,
+	"Other_Uppercase":                    Other_Uppercase,
+	"Pattern_Syntax":                     Pattern_Syntax,
+	"Pattern_White_Space":                Pattern_White_Space,
+	"Quotation_Mark":                     Quotation_Mark,
+	"Radical":                            Radical,
+	"STerm":                              STerm,
+	"Soft_Dotted":                        Soft_Dotted,
+	"Terminal_Punctuation":               Terminal_Punctuation,
+	"Unified_Ideograph":                  Unified_Ideograph,
+	"Variation_Selector":                 Variation_Selector,
+	"White_Space":                        White_Space,
+}
+
+var _ASCII_Hex_Digit = &RangeTable{
+	R16: []Range16{
+		{0x0030, 0x0039, 1},
+		{0x0041, 0x0046, 1},
+		{0x0061, 0x0066, 1},
+	},
+	LatinOffset: 3,
+}
+
+var _Bidi_Control = &RangeTable{
+	R16: []Range16{
+		{0x061c, 0x061c, 1},
+		{0x200e, 0x200f, 1},
+		{0x202a, 0x202e, 1},
+		{0x2066, 0x2069, 1},
+	},
+}
+
+var _Dash = &RangeTable{
+	R16: []Range16{
+		{0x002d, 0x002d, 1},
+		{0x058a, 0x058a, 1},
+		{0x05be, 0x05be, 1},
+		{0x1400, 0x1400, 1},
+		{0x1806, 0x1806, 1},
+		{0x2010, 0x2015, 1},
+		{0x2053, 0x2053, 1},
+		{0x207b, 0x207b, 1},
+		{0x208b, 0x208b, 1},
+		{0x2212, 0x2212, 1},
+		{0x2e17, 0x2e17, 1},
+		{0x2e1a, 0x2e1a, 1},
+		{0x2e3a, 0x2e3b, 1},
+		{0x2e40, 0x2e40, 1},
+		{0x301c, 0x301c, 1},
+		{0x3030, 0x3030, 1},
+		{0x30a0, 0x30a0, 1},
+		{0xfe31, 0xfe32, 1},
+		{0xfe58, 0xfe58, 1},
+		{0xfe63, 0xfe63, 1},
+		{0xff0d, 0xff0d, 1},
+	},
+	LatinOffset: 1,
+}
+
+var _Deprecated = &RangeTable{
+	R16: []Range16{
+		{0x0149, 0x0149, 1},
+		{0x0673, 0x0673, 1},
+		{0x0f77, 0x0f77, 1},
+		{0x0f79, 0x0f79, 1},
+		{0x17a3, 0x17a4, 1},
+		{0x206a, 0x206f, 1},
+		{0x2329, 0x232a, 1},
+	},
+	R32: []Range32{
+		{0xe0001, 0xe0001, 1},
+		{0xe0020, 0xe007f, 1},
+	},
+}
+
+var _Diacritic = &RangeTable{
+	R16: []Range16{
+		{0x005e, 0x005e, 1},
+		{0x0060, 0x0060, 1},
+		{0x00a8, 0x00a8, 1},
+		{0x00af, 0x00af, 1},
+		{0x00b4, 0x00b4, 1},
+		{0x00b7, 0x00b8, 1},
+		{0x02b0, 0x034e, 1},
+		{0x0350, 0x0357, 1},
+		{0x035d, 0x0362, 1},
+		{0x0374, 0x0375, 1},
+		{0x037a, 0x037a, 1},
+		{0x0384, 0x0385, 1},
+		{0x0483, 0x0487, 1},
+		{0x0559, 0x0559, 1},
+		{0x0591, 0x05a1, 1},
+		{0x05a3, 0x05bd, 1},
+		{0x05bf, 0x05bf, 1},
+		{0x05c1, 0x05c2, 1},
+		{0x05c4, 0x05c4, 1},
+		{0x064b, 0x0652, 1},
+		{0x0657, 0x0658, 1},
+		{0x06df, 0x06e0, 1},
+		{0x06e5, 0x06e6, 1},
+		{0x06ea, 0x06ec, 1},
+		{0x0730, 0x074a, 1},
+		{0x07a6, 0x07b0, 1},
+		{0x07eb, 0x07f5, 1},
+		{0x0818, 0x0819, 1},
+		{0x08e4, 0x08fe, 1},
+		{0x093c, 0x093c, 1},
+		{0x094d, 0x094d, 1},
+		{0x0951, 0x0954, 1},
+		{0x0971, 0x0971, 1},
+		{0x09bc, 0x09bc, 1},
+		{0x09cd, 0x09cd, 1},
+		{0x0a3c, 0x0a3c, 1},
+		{0x0a4d, 0x0a4d, 1},
+		{0x0abc, 0x0abc, 1},
+		{0x0acd, 0x0acd, 1},
+		{0x0b3c, 0x0b3c, 1},
+		{0x0b4d, 0x0b4d, 1},
+		{0x0bcd, 0x0bcd, 1},
+		{0x0c4d, 0x0c4d, 1},
+		{0x0cbc, 0x0cbc, 1},
+		{0x0ccd, 0x0ccd, 1},
+		{0x0d4d, 0x0d4d, 1},
+		{0x0dca, 0x0dca, 1},
+		{0x0e47, 0x0e4c, 1},
+		{0x0e4e, 0x0e4e, 1},
+		{0x0ec8, 0x0ecc, 1},
+		{0x0f18, 0x0f19, 1},
+		{0x0f35, 0x0f35, 1},
+		{0x0f37, 0x0f37, 1},
+		{0x0f39, 0x0f39, 1},
+		{0x0f3e, 0x0f3f, 1},
+		{0x0f82, 0x0f84, 1},
+		{0x0f86, 0x0f87, 1},
+		{0x0fc6, 0x0fc6, 1},
+		{0x1037, 0x1037, 1},
+		{0x1039, 0x103a, 1},
+		{0x1087, 0x108d, 1},
+		{0x108f, 0x108f, 1},
+		{0x109a, 0x109b, 1},
+		{0x17c9, 0x17d3, 1},
+		{0x17dd, 0x17dd, 1},
+		{0x1939, 0x193b, 1},
+		{0x1a75, 0x1a7c, 1},
+		{0x1a7f, 0x1a7f, 1},
+		{0x1ab0, 0x1abd, 1},
+		{0x1b34, 0x1b34, 1},
+		{0x1b44, 0x1b44, 1},
+		{0x1b6b, 0x1b73, 1},
+		{0x1baa, 0x1bab, 1},
+		{0x1c36, 0x1c37, 1},
+		{0x1c78, 0x1c7d, 1},
+		{0x1cd0, 0x1ce8, 1},
+		{0x1ced, 0x1ced, 1},
+		{0x1cf4, 0x1cf4, 1},
+		{0x1cf8, 0x1cf9, 1},
+		{0x1d2c, 0x1d6a, 1},
+		{0x1dc4, 0x1dcf, 1},
+		{0x1df5, 0x1df5, 1},
+		{0x1dfd, 0x1dff, 1},
+		{0x1fbd, 0x1fbd, 1},
+		{0x1fbf, 0x1fc1, 1},
+		{0x1fcd, 0x1fcf, 1},
+		{0x1fdd, 0x1fdf, 1},
+		{0x1fed, 0x1fef, 1},
+		{0x1ffd, 0x1ffe, 1},
+		{0x2cef, 0x2cf1, 1},
+		{0x2e2f, 0x2e2f, 1},
+		{0x302a, 0x302f, 1},
+		{0x3099, 0x309c, 1},
+		{0x30fc, 0x30fc, 1},
+		{0xa66f, 0xa66f, 1},
+		{0xa67c, 0xa67d, 1},
+		{0xa67f, 0xa67f, 1},
+		{0xa69c, 0xa69d, 1},
+		{0xa6f0, 0xa6f1, 1},
+		{0xa717, 0xa721, 1},
+		{0xa788, 0xa788, 1},
+		{0xa7f8, 0xa7f9, 1},
+		{0xa8c4, 0xa8c4, 1},
+		{0xa8e0, 0xa8f1, 1},
+		{0xa92b, 0xa92e, 1},
+		{0xa953, 0xa953, 1},
+		{0xa9b3, 0xa9b3, 1},
+		{0xa9c0, 0xa9c0, 1},
+		{0xa9e5, 0xa9e5, 1},
+		{0xaa7b, 0xaa7d, 1},
+		{0xaabf, 0xaac2, 1},
+		{0xaaf6, 0xaaf6, 1},
+		{0xab5b, 0xab5f, 1},
+		{0xabec, 0xabed, 1},
+		{0xfb1e, 0xfb1e, 1},
+		{0xfe20, 0xfe2d, 1},
+		{0xff3e, 0xff3e, 1},
+		{0xff40, 0xff40, 1},
+		{0xff70, 0xff70, 1},
+		{0xff9e, 0xff9f, 1},
+		{0xffe3, 0xffe3, 1},
+	},
+	R32: []Range32{
+		{0x102e0, 0x102e0, 1},
+		{0x10ae5, 0x10ae6, 1},
+		{0x110b9, 0x110ba, 1},
+		{0x11133, 0x11134, 1},
+		{0x11173, 0x11173, 1},
+		{0x111c0, 0x111c0, 1},
+		{0x11235, 0x11236, 1},
+		{0x112e9, 0x112ea, 1},
+		{0x1133c, 0x1133c, 1},
+		{0x1134d, 0x1134d, 1},
+		{0x11366, 0x1136c, 1},
+		{0x11370, 0x11374, 1},
+		{0x114c2, 0x114c3, 1},
+		{0x115bf, 0x115c0, 1},
+		{0x1163f, 0x1163f, 1},
+		{0x116b6, 0x116b7, 1},
+		{0x16af0, 0x16af4, 1},
+		{0x16f8f, 0x16f9f, 1},
+		{0x1d167, 0x1d169, 1},
+		{0x1d16d, 0x1d172, 1},
+		{0x1d17b, 0x1d182, 1},
+		{0x1d185, 0x1d18b, 1},
+		{0x1d1aa, 0x1d1ad, 1},
+		{0x1e8d0, 0x1e8d6, 1},
+	},
+	LatinOffset: 6,
+}
+
+var _Extender = &RangeTable{
+	R16: []Range16{
+		{0x00b7, 0x00b7, 1},
+		{0x02d0, 0x02d1, 1},
+		{0x0640, 0x0640, 1},
+		{0x07fa, 0x07fa, 1},
+		{0x0e46, 0x0e46, 1},
+		{0x0ec6, 0x0ec6, 1},
+		{0x180a, 0x180a, 1},
+		{0x1843, 0x1843, 1},
+		{0x1aa7, 0x1aa7, 1},
+		{0x1c36, 0x1c36, 1},
+		{0x1c7b, 0x1c7b, 1},
+		{0x3005, 0x3005, 1},
+		{0x3031, 0x3035, 1},
+		{0x309d, 0x309e, 1},
+		{0x30fc, 0x30fe, 1},
+		{0xa015, 0xa015, 1},
+		{0xa60c, 0xa60c, 1},
+		{0xa9cf, 0xa9cf, 1},
+		{0xa9e6, 0xa9e6, 1},
+		{0xaa70, 0xaa70, 1},
+		{0xaadd, 0xaadd, 1},
+		{0xaaf3, 0xaaf4, 1},
+		{0xff70, 0xff70, 1},
+	},
+	R32: []Range32{
+		{0x1135d, 0x1135d, 1},
+		{0x115c6, 0x115c8, 1},
+		{0x16b42, 0x16b43, 1},
+	},
+	LatinOffset: 1,
+}
+
+var _Hex_Digit = &RangeTable{
+	R16: []Range16{
+		{0x0030, 0x0039, 1},
+		{0x0041, 0x0046, 1},
+		{0x0061, 0x0066, 1},
+		{0xff10, 0xff19, 1},
+		{0xff21, 0xff26, 1},
+		{0xff41, 0xff46, 1},
+	},
+	LatinOffset: 3,
+}
+
+var _Hyphen = &RangeTable{
+	R16: []Range16{
+		{0x002d, 0x002d, 1},
+		{0x00ad, 0x00ad, 1},
+		{0x058a, 0x058a, 1},
+		{0x1806, 0x1806, 1},
+		{0x2010, 0x2011, 1},
+		{0x2e17, 0x2e17, 1},
+		{0x30fb, 0x30fb, 1},
+		{0xfe63, 0xfe63, 1},
+		{0xff0d, 0xff0d, 1},
+		{0xff65, 0xff65, 1},
+	},
+	LatinOffset: 2,
+}
+
+var _IDS_Binary_Operator = &RangeTable{
+	R16: []Range16{
+		{0x2ff0, 0x2ff1, 1},
+		{0x2ff4, 0x2ffb, 1},
+	},
+}
+
+var _IDS_Trinary_Operator = &RangeTable{
+	R16: []Range16{
+		{0x2ff2, 0x2ff3, 1},
+	},
+}
+
+var _Ideographic = &RangeTable{
+	R16: []Range16{
+		{0x3006, 0x3007, 1},
+		{0x3021, 0x3029, 1},
+		{0x3038, 0x303a, 1},
+		{0x3400, 0x4db5, 1},
+		{0x4e00, 0x9fcc, 1},
+		{0xf900, 0xfa6d, 1},
+		{0xfa70, 0xfad9, 1},
+	},
+	R32: []Range32{
+		{0x20000, 0x2a6d6, 1},
+		{0x2a700, 0x2b734, 1},
+		{0x2b740, 0x2b81d, 1},
+		{0x2f800, 0x2fa1d, 1},
+	},
+}
+
+var _Join_Control = &RangeTable{
+	R16: []Range16{
+		{0x200c, 0x200d, 1},
+	},
+}
+
+var _Logical_Order_Exception = &RangeTable{
+	R16: []Range16{
+		{0x0e40, 0x0e44, 1},
+		{0x0ec0, 0x0ec4, 1},
+		{0xaab5, 0xaab6, 1},
+		{0xaab9, 0xaab9, 1},
+		{0xaabb, 0xaabc, 1},
+	},
+}
+
+var _Noncharacter_Code_Point = &RangeTable{
+	R16: []Range16{
+		{0xfdd0, 0xfdef, 1},
+		{0xfffe, 0xffff, 1},
+	},
+	R32: []Range32{
+		{0x1fffe, 0x1ffff, 1},
+		{0x2fffe, 0x2ffff, 1},
+		{0x3fffe, 0x3ffff, 1},
+		{0x4fffe, 0x4ffff, 1},
+		{0x5fffe, 0x5ffff, 1},
+		{0x6fffe, 0x6ffff, 1},
+		{0x7fffe, 0x7ffff, 1},
+		{0x8fffe, 0x8ffff, 1},
+		{0x9fffe, 0x9ffff, 1},
+		{0xafffe, 0xaffff, 1},
+		{0xbfffe, 0xbffff, 1},
+		{0xcfffe, 0xcffff, 1},
+		{0xdfffe, 0xdffff, 1},
+		{0xefffe, 0xeffff, 1},
+		{0xffffe, 0xfffff, 1},
+		{0x10fffe, 0x10ffff, 1},
+	},
+}
+
+var _Other_Alphabetic = &RangeTable{
+	R16: []Range16{
+		{0x0345, 0x0345, 1},
+		{0x05b0, 0x05bd, 1},
+		{0x05bf, 0x05bf, 1},
+		{0x05c1, 0x05c2, 1},
+		{0x05c4, 0x05c5, 1},
+		{0x05c7, 0x05c7, 1},
+		{0x0610, 0x061a, 1},
+		{0x064b, 0x0657, 1},
+		{0x0659, 0x065f, 1},
+		{0x0670, 0x0670, 1},
+		{0x06d6, 0x06dc, 1},
+		{0x06e1, 0x06e4, 1},
+		{0x06e7, 0x06e8, 1},
+		{0x06ed, 0x06ed, 1},
+		{0x0711, 0x0711, 1},
+		{0x0730, 0x073f, 1},
+		{0x07a6, 0x07b0, 1},
+		{0x0816, 0x0817, 1},
+		{0x081b, 0x0823, 1},
+		{0x0825, 0x0827, 1},
+		{0x0829, 0x082c, 1},
+		{0x08e4, 0x08e9, 1},
+		{0x08f0, 0x0903, 1},
+		{0x093a, 0x093b, 1},
+		{0x093e, 0x094c, 1},
+		{0x094e, 0x094f, 1},
+		{0x0955, 0x0957, 1},
+		{0x0962, 0x0963, 1},
+		{0x0981, 0x0983, 1},
+		{0x09be, 0x09c4, 1},
+		{0x09c7, 0x09c8, 1},
+		{0x09cb, 0x09cc, 1},
+		{0x09d7, 0x09d7, 1},
+		{0x09e2, 0x09e3, 1},
+		{0x0a01, 0x0a03, 1},
+		{0x0a3e, 0x0a42, 1},
+		{0x0a47, 0x0a48, 1},
+		{0x0a4b, 0x0a4c, 1},
+		{0x0a51, 0x0a51, 1},
+		{0x0a70, 0x0a71, 1},
+		{0x0a75, 0x0a75, 1},
+		{0x0a81, 0x0a83, 1},
+		{0x0abe, 0x0ac5, 1},
+		{0x0ac7, 0x0ac9, 1},
+		{0x0acb, 0x0acc, 1},
+		{0x0ae2, 0x0ae3, 1},
+		{0x0b01, 0x0b03, 1},
+		{0x0b3e, 0x0b44, 1},
+		{0x0b47, 0x0b48, 1},
+		{0x0b4b, 0x0b4c, 1},
+		{0x0b56, 0x0b57, 1},
+		{0x0b62, 0x0b63, 1},
+		{0x0b82, 0x0b82, 1},
+		{0x0bbe, 0x0bc2, 1},
+		{0x0bc6, 0x0bc8, 1},
+		{0x0bca, 0x0bcc, 1},
+		{0x0bd7, 0x0bd7, 1},
+		{0x0c00, 0x0c03, 1},
+		{0x0c3e, 0x0c44, 1},
+		{0x0c46, 0x0c48, 1},
+		{0x0c4a, 0x0c4c, 1},
+		{0x0c55, 0x0c56, 1},
+		{0x0c62, 0x0c63, 1},
+		{0x0c81, 0x0c83, 1},
+		{0x0cbe, 0x0cc4, 1},
+		{0x0cc6, 0x0cc8, 1},
+		{0x0cca, 0x0ccc, 1},
+		{0x0cd5, 0x0cd6, 1},
+		{0x0ce2, 0x0ce3, 1},
+		{0x0d01, 0x0d03, 1},
+		{0x0d3e, 0x0d44, 1},
+		{0x0d46, 0x0d48, 1},
+		{0x0d4a, 0x0d4c, 1},
+		{0x0d57, 0x0d57, 1},
+		{0x0d62, 0x0d63, 1},
+		{0x0d82, 0x0d83, 1},
+		{0x0dcf, 0x0dd4, 1},
+		{0x0dd6, 0x0dd6, 1},
+		{0x0dd8, 0x0ddf, 1},
+		{0x0df2, 0x0df3, 1},
+		{0x0e31, 0x0e31, 1},
+		{0x0e34, 0x0e3a, 1},
+		{0x0e4d, 0x0e4d, 1},
+		{0x0eb1, 0x0eb1, 1},
+		{0x0eb4, 0x0eb9, 1},
+		{0x0ebb, 0x0ebc, 1},
+		{0x0ecd, 0x0ecd, 1},
+		{0x0f71, 0x0f81, 1},
+		{0x0f8d, 0x0f97, 1},
+		{0x0f99, 0x0fbc, 1},
+		{0x102b, 0x1036, 1},
+		{0x1038, 0x1038, 1},
+		{0x103b, 0x103e, 1},
+		{0x1056, 0x1059, 1},
+		{0x105e, 0x1060, 1},
+		{0x1062, 0x1062, 1},
+		{0x1067, 0x1068, 1},
+		{0x1071, 0x1074, 1},
+		{0x1082, 0x1086, 1},
+		{0x109c, 0x109d, 1},
+		{0x135f, 0x135f, 1},
+		{0x1712, 0x1713, 1},
+		{0x1732, 0x1733, 1},
+		{0x1752, 0x1753, 1},
+		{0x1772, 0x1773, 1},
+		{0x17b6, 0x17c8, 1},
+		{0x18a9, 0x18a9, 1},
+		{0x1920, 0x192b, 1},
+		{0x1930, 0x1938, 1},
+		{0x19b0, 0x19c0, 1},
+		{0x19c8, 0x19c9, 1},
+		{0x1a17, 0x1a1b, 1},
+		{0x1a55, 0x1a5e, 1},
+		{0x1a61, 0x1a74, 1},
+		{0x1b00, 0x1b04, 1},
+		{0x1b35, 0x1b43, 1},
+		{0x1b80, 0x1b82, 1},
+		{0x1ba1, 0x1ba9, 1},
+		{0x1bac, 0x1bad, 1},
+		{0x1be7, 0x1bf1, 1},
+		{0x1c24, 0x1c35, 1},
+		{0x1cf2, 0x1cf3, 1},
+		{0x1de7, 0x1df4, 1},
+		{0x24b6, 0x24e9, 1},
+		{0x2de0, 0x2dff, 1},
+		{0xa674, 0xa67b, 1},
+		{0xa69f, 0xa69f, 1},
+		{0xa823, 0xa827, 1},
+		{0xa880, 0xa881, 1},
+		{0xa8b4, 0xa8c3, 1},
+		{0xa926, 0xa92a, 1},
+		{0xa947, 0xa952, 1},
+		{0xa980, 0xa983, 1},
+		{0xa9b4, 0xa9bf, 1},
+		{0xaa29, 0xaa36, 1},
+		{0xaa43, 0xaa43, 1},
+		{0xaa4c, 0xaa4d, 1},
+		{0xaab0, 0xaab0, 1},
+		{0xaab2, 0xaab4, 1},
+		{0xaab7, 0xaab8, 1},
+		{0xaabe, 0xaabe, 1},
+		{0xaaeb, 0xaaef, 1},
+		{0xaaf5, 0xaaf5, 1},
+		{0xabe3, 0xabea, 1},
+		{0xfb1e, 0xfb1e, 1},
+	},
+	R32: []Range32{
+		{0x10376, 0x1037a, 1},
+		{0x10a01, 0x10a03, 1},
+		{0x10a05, 0x10a06, 1},
+		{0x10a0c, 0x10a0f, 1},
+		{0x11000, 0x11002, 1},
+		{0x11038, 0x11045, 1},
+		{0x11082, 0x11082, 1},
+		{0x110b0, 0x110b8, 1},
+		{0x11100, 0x11102, 1},
+		{0x11127, 0x11132, 1},
+		{0x11180, 0x11182, 1},
+		{0x111b3, 0x111bf, 1},
+		{0x1122c, 0x11234, 1},
+		{0x11237, 0x11237, 1},
+		{0x112df, 0x112e8, 1},
+		{0x11301, 0x11303, 1},
+		{0x1133e, 0x11344, 1},
+		{0x11347, 0x11348, 1},
+		{0x1134b, 0x1134c, 1},
+		{0x11357, 0x11357, 1},
+		{0x11362, 0x11363, 1},
+		{0x114b0, 0x114c1, 1},
+		{0x115af, 0x115b5, 1},
+		{0x115b8, 0x115be, 1},
+		{0x11630, 0x1163e, 1},
+		{0x11640, 0x11640, 1},
+		{0x116ab, 0x116b5, 1},
+		{0x16b30, 0x16b36, 1},
+		{0x16f51, 0x16f7e, 1},
+		{0x1bc9e, 0x1bc9e, 1},
+		{0x1f130, 0x1f149, 1},
+		{0x1f150, 0x1f169, 1},
+		{0x1f170, 0x1f189, 1},
+	},
+}
+
+var _Other_Default_Ignorable_Code_Point = &RangeTable{
+	R16: []Range16{
+		{0x034f, 0x034f, 1},
+		{0x115f, 0x1160, 1},
+		{0x17b4, 0x17b5, 1},
+		{0x2065, 0x2065, 1},
+		{0x3164, 0x3164, 1},
+		{0xffa0, 0xffa0, 1},
+		{0xfff0, 0xfff8, 1},
+	},
+	R32: []Range32{
+		{0xe0000, 0xe0000, 1},
+		{0xe0002, 0xe001f, 1},
+		{0xe0080, 0xe00ff, 1},
+		{0xe01f0, 0xe0fff, 1},
+	},
+}
+
+var _Other_Grapheme_Extend = &RangeTable{
+	R16: []Range16{
+		{0x09be, 0x09be, 1},
+		{0x09d7, 0x09d7, 1},
+		{0x0b3e, 0x0b3e, 1},
+		{0x0b57, 0x0b57, 1},
+		{0x0bbe, 0x0bbe, 1},
+		{0x0bd7, 0x0bd7, 1},
+		{0x0cc2, 0x0cc2, 1},
+		{0x0cd5, 0x0cd6, 1},
+		{0x0d3e, 0x0d3e, 1},
+		{0x0d57, 0x0d57, 1},
+		{0x0dcf, 0x0dcf, 1},
+		{0x0ddf, 0x0ddf, 1},
+		{0x200c, 0x200d, 1},
+		{0x302e, 0x302f, 1},
+		{0xff9e, 0xff9f, 1},
+	},
+	R32: []Range32{
+		{0x1133e, 0x1133e, 1},
+		{0x11357, 0x11357, 1},
+		{0x114b0, 0x114b0, 1},
+		{0x114bd, 0x114bd, 1},
+		{0x115af, 0x115af, 1},
+		{0x1d165, 0x1d165, 1},
+		{0x1d16e, 0x1d172, 1},
+	},
+}
+
+var _Other_ID_Continue = &RangeTable{
+	R16: []Range16{
+		{0x00b7, 0x00b7, 1},
+		{0x0387, 0x0387, 1},
+		{0x1369, 0x1371, 1},
+		{0x19da, 0x19da, 1},
+	},
+	LatinOffset: 1,
+}
+
+var _Other_ID_Start = &RangeTable{
+	R16: []Range16{
+		{0x2118, 0x2118, 1},
+		{0x212e, 0x212e, 1},
+		{0x309b, 0x309c, 1},
+	},
+}
+
+var _Other_Lowercase = &RangeTable{
+	R16: []Range16{
+		{0x00aa, 0x00aa, 1},
+		{0x00ba, 0x00ba, 1},
+		{0x02b0, 0x02b8, 1},
+		{0x02c0, 0x02c1, 1},
+		{0x02e0, 0x02e4, 1},
+		{0x0345, 0x0345, 1},
+		{0x037a, 0x037a, 1},
+		{0x1d2c, 0x1d6a, 1},
+		{0x1d78, 0x1d78, 1},
+		{0x1d9b, 0x1dbf, 1},
+		{0x2071, 0x2071, 1},
+		{0x207f, 0x207f, 1},
+		{0x2090, 0x209c, 1},
+		{0x2170, 0x217f, 1},
+		{0x24d0, 0x24e9, 1},
+		{0x2c7c, 0x2c7d, 1},
+		{0xa69c, 0xa69d, 1},
+		{0xa770, 0xa770, 1},
+		{0xa7f8, 0xa7f9, 1},
+		{0xab5c, 0xab5f, 1},
+	},
+	LatinOffset: 2,
+}
+
+var _Other_Math = &RangeTable{
+	R16: []Range16{
+		{0x005e, 0x005e, 1},
+		{0x03d0, 0x03d2, 1},
+		{0x03d5, 0x03d5, 1},
+		{0x03f0, 0x03f1, 1},
+		{0x03f4, 0x03f5, 1},
+		{0x2016, 0x2016, 1},
+		{0x2032, 0x2034, 1},
+		{0x2040, 0x2040, 1},
+		{0x2061, 0x2064, 1},
+		{0x207d, 0x207e, 1},
+		{0x208d, 0x208e, 1},
+		{0x20d0, 0x20dc, 1},
+		{0x20e1, 0x20e1, 1},
+		{0x20e5, 0x20e6, 1},
+		{0x20eb, 0x20ef, 1},
+		{0x2102, 0x2102, 1},
+		{0x2107, 0x2107, 1},
+		{0x210a, 0x2113, 1},
+		{0x2115, 0x2115, 1},
+		{0x2119, 0x211d, 1},
+		{0x2124, 0x2124, 1},
+		{0x2128, 0x2129, 1},
+		{0x212c, 0x212d, 1},
+		{0x212f, 0x2131, 1},
+		{0x2133, 0x2138, 1},
+		{0x213c, 0x213f, 1},
+		{0x2145, 0x2149, 1},
+		{0x2195, 0x2199, 1},
+		{0x219c, 0x219f, 1},
+		{0x21a1, 0x21a2, 1},
+		{0x21a4, 0x21a5, 1},
+		{0x21a7, 0x21a7, 1},
+		{0x21a9, 0x21ad, 1},
+		{0x21b0, 0x21b1, 1},
+		{0x21b6, 0x21b7, 1},
+		{0x21bc, 0x21cd, 1},
+		{0x21d0, 0x21d1, 1},
+		{0x21d3, 0x21d3, 1},
+		{0x21d5, 0x21db, 1},
+		{0x21dd, 0x21dd, 1},
+		{0x21e4, 0x21e5, 1},
+		{0x2308, 0x230b, 1},
+		{0x23b4, 0x23b5, 1},
+		{0x23b7, 0x23b7, 1},
+		{0x23d0, 0x23d0, 1},
+		{0x23e2, 0x23e2, 1},
+		{0x25a0, 0x25a1, 1},
+		{0x25ae, 0x25b6, 1},
+		{0x25bc, 0x25c0, 1},
+		{0x25c6, 0x25c7, 1},
+		{0x25ca, 0x25cb, 1},
+		{0x25cf, 0x25d3, 1},
+		{0x25e2, 0x25e2, 1},
+		{0x25e4, 0x25e4, 1},
+		{0x25e7, 0x25ec, 1},
+		{0x2605, 0x2606, 1},
+		{0x2640, 0x2640, 1},
+		{0x2642, 0x2642, 1},
+		{0x2660, 0x2663, 1},
+		{0x266d, 0x266e, 1},
+		{0x27c5, 0x27c6, 1},
+		{0x27e6, 0x27ef, 1},
+		{0x2983, 0x2998, 1},
+		{0x29d8, 0x29db, 1},
+		{0x29fc, 0x29fd, 1},
+		{0xfe61, 0xfe61, 1},
+		{0xfe63, 0xfe63, 1},
+		{0xfe68, 0xfe68, 1},
+		{0xff3c, 0xff3c, 1},
+		{0xff3e, 0xff3e, 1},
+	},
+	R32: []Range32{
+		{0x1d400, 0x1d454, 1},
+		{0x1d456, 0x1d49c, 1},
+		{0x1d49e, 0x1d49f, 1},
+		{0x1d4a2, 0x1d4a2, 1},
+		{0x1d4a5, 0x1d4a6, 1},
+		{0x1d4a9, 0x1d4ac, 1},
+		{0x1d4ae, 0x1d4b9, 1},
+		{0x1d4bb, 0x1d4bb, 1},
+		{0x1d4bd, 0x1d4c3, 1},
+		{0x1d4c5, 0x1d505, 1},
+		{0x1d507, 0x1d50a, 1},
+		{0x1d50d, 0x1d514, 1},
+		{0x1d516, 0x1d51c, 1},
+		{0x1d51e, 0x1d539, 1},
+		{0x1d53b, 0x1d53e, 1},
+		{0x1d540, 0x1d544, 1},
+		{0x1d546, 0x1d546, 1},
+		{0x1d54a, 0x1d550, 1},
+		{0x1d552, 0x1d6a5, 1},
+		{0x1d6a8, 0x1d6c0, 1},
+		{0x1d6c2, 0x1d6da, 1},
+		{0x1d6dc, 0x1d6fa, 1},
+		{0x1d6fc, 0x1d714, 1},
+		{0x1d716, 0x1d734, 1},
+		{0x1d736, 0x1d74e, 1},
+		{0x1d750, 0x1d76e, 1},
+		{0x1d770, 0x1d788, 1},
+		{0x1d78a, 0x1d7a8, 1},
+		{0x1d7aa, 0x1d7c2, 1},
+		{0x1d7c4, 0x1d7cb, 1},
+		{0x1d7ce, 0x1d7ff, 1},
+		{0x1ee00, 0x1ee03, 1},
+		{0x1ee05, 0x1ee1f, 1},
+		{0x1ee21, 0x1ee22, 1},
+		{0x1ee24, 0x1ee24, 1},
+		{0x1ee27, 0x1ee27, 1},
+		{0x1ee29, 0x1ee32, 1},
+		{0x1ee34, 0x1ee37, 1},
+		{0x1ee39, 0x1ee39, 1},
+		{0x1ee3b, 0x1ee3b, 1},
+		{0x1ee42, 0x1ee42, 1},
+		{0x1ee47, 0x1ee47, 1},
+		{0x1ee49, 0x1ee49, 1},
+		{0x1ee4b, 0x1ee4b, 1},
+		{0x1ee4d, 0x1ee4f, 1},
+		{0x1ee51, 0x1ee52, 1},
+		{0x1ee54, 0x1ee54, 1},
+		{0x1ee57, 0x1ee57, 1},
+		{0x1ee59, 0x1ee59, 1},
+		{0x1ee5b, 0x1ee5b, 1},
+		{0x1ee5d, 0x1ee5d, 1},
+		{0x1ee5f, 0x1ee5f, 1},
+		{0x1ee61, 0x1ee62, 1},
+		{0x1ee64, 0x1ee64, 1},
+		{0x1ee67, 0x1ee6a, 1},
+		{0x1ee6c, 0x1ee72, 1},
+		{0x1ee74, 0x1ee77, 1},
+		{0x1ee79, 0x1ee7c, 1},
+		{0x1ee7e, 0x1ee7e, 1},
+		{0x1ee80, 0x1ee89, 1},
+		{0x1ee8b, 0x1ee9b, 1},
+		{0x1eea1, 0x1eea3, 1},
+		{0x1eea5, 0x1eea9, 1},
+		{0x1eeab, 0x1eebb, 1},
+	},
+	LatinOffset: 1,
+}
+
+var _Other_Uppercase = &RangeTable{
+	R16: []Range16{
+		{0x2160, 0x216f, 1},
+		{0x24b6, 0x24cf, 1},
+	},
+	R32: []Range32{
+		{0x1f130, 0x1f149, 1},
+		{0x1f150, 0x1f169, 1},
+		{0x1f170, 0x1f189, 1},
+	},
+}
+
+var _Pattern_Syntax = &RangeTable{
+	R16: []Range16{
+		{0x0021, 0x002f, 1},
+		{0x003a, 0x0040, 1},
+		{0x005b, 0x005e, 1},
+		{0x0060, 0x0060, 1},
+		{0x007b, 0x007e, 1},
+		{0x00a1, 0x00a7, 1},
+		{0x00a9, 0x00a9, 1},
+		{0x00ab, 0x00ac, 1},
+		{0x00ae, 0x00ae, 1},
+		{0x00b0, 0x00b1, 1},
+		{0x00b6, 0x00b6, 1},
+		{0x00bb, 0x00bb, 1},
+		{0x00bf, 0x00bf, 1},
+		{0x00d7, 0x00d7, 1},
+		{0x00f7, 0x00f7, 1},
+		{0x2010, 0x2027, 1},
+		{0x2030, 0x203e, 1},
+		{0x2041, 0x2053, 1},
+		{0x2055, 0x205e, 1},
+		{0x2190, 0x245f, 1},
+		{0x2500, 0x2775, 1},
+		{0x2794, 0x2bff, 1},
+		{0x2e00, 0x2e7f, 1},
+		{0x3001, 0x3003, 1},
+		{0x3008, 0x3020, 1},
+		{0x3030, 0x3030, 1},
+		{0xfd3e, 0xfd3f, 1},
+		{0xfe45, 0xfe46, 1},
+	},
+	LatinOffset: 15,
+}
+
+var _Pattern_White_Space = &RangeTable{
+	R16: []Range16{
+		{0x0009, 0x000d, 1},
+		{0x0020, 0x0020, 1},
+		{0x0085, 0x0085, 1},
+		{0x200e, 0x200f, 1},
+		{0x2028, 0x2029, 1},
+	},
+	LatinOffset: 3,
+}
+
+var _Quotation_Mark = &RangeTable{
+	R16: []Range16{
+		{0x0022, 0x0022, 1},
+		{0x0027, 0x0027, 1},
+		{0x00ab, 0x00ab, 1},
+		{0x00bb, 0x00bb, 1},
+		{0x2018, 0x201f, 1},
+		{0x2039, 0x203a, 1},
+		{0x2e42, 0x2e42, 1},
+		{0x300c, 0x300f, 1},
+		{0x301d, 0x301f, 1},
+		{0xfe41, 0xfe44, 1},
+		{0xff02, 0xff02, 1},
+		{0xff07, 0xff07, 1},
+		{0xff62, 0xff63, 1},
+	},
+	LatinOffset: 4,
+}
+
+var _Radical = &RangeTable{
+	R16: []Range16{
+		{0x2e80, 0x2e99, 1},
+		{0x2e9b, 0x2ef3, 1},
+		{0x2f00, 0x2fd5, 1},
+	},
+}
+
+var _STerm = &RangeTable{
+	R16: []Range16{
+		{0x0021, 0x0021, 1},
+		{0x002e, 0x002e, 1},
+		{0x003f, 0x003f, 1},
+		{0x0589, 0x0589, 1},
+		{0x061f, 0x061f, 1},
+		{0x06d4, 0x06d4, 1},
+		{0x0700, 0x0702, 1},
+		{0x07f9, 0x07f9, 1},
+		{0x0964, 0x0965, 1},
+		{0x104a, 0x104b, 1},
+		{0x1362, 0x1362, 1},
+		{0x1367, 0x1368, 1},
+		{0x166e, 0x166e, 1},
+		{0x1735, 0x1736, 1},
+		{0x1803, 0x1803, 1},
+		{0x1809, 0x1809, 1},
+		{0x1944, 0x1945, 1},
+		{0x1aa8, 0x1aab, 1},
+		{0x1b5a, 0x1b5b, 1},
+		{0x1b5e, 0x1b5f, 1},
+		{0x1c3b, 0x1c3c, 1},
+		{0x1c7e, 0x1c7f, 1},
+		{0x203c, 0x203d, 1},
+		{0x2047, 0x2049, 1},
+		{0x2e2e, 0x2e2e, 1},
+		{0x2e3c, 0x2e3c, 1},
+		{0x3002, 0x3002, 1},
+		{0xa4ff, 0xa4ff, 1},
+		{0xa60e, 0xa60f, 1},
+		{0xa6f3, 0xa6f3, 1},
+		{0xa6f7, 0xa6f7, 1},
+		{0xa876, 0xa877, 1},
+		{0xa8ce, 0xa8cf, 1},
+		{0xa92f, 0xa92f, 1},
+		{0xa9c8, 0xa9c9, 1},
+		{0xaa5d, 0xaa5f, 1},
+		{0xaaf0, 0xaaf1, 1},
+		{0xabeb, 0xabeb, 1},
+		{0xfe52, 0xfe52, 1},
+		{0xfe56, 0xfe57, 1},
+		{0xff01, 0xff01, 1},
+		{0xff0e, 0xff0e, 1},
+		{0xff1f, 0xff1f, 1},
+		{0xff61, 0xff61, 1},
+	},
+	R32: []Range32{
+		{0x10a56, 0x10a57, 1},
+		{0x11047, 0x11048, 1},
+		{0x110be, 0x110c1, 1},
+		{0x11141, 0x11143, 1},
+		{0x111c5, 0x111c6, 1},
+		{0x111cd, 0x111cd, 1},
+		{0x11238, 0x11239, 1},
+		{0x1123b, 0x1123c, 1},
+		{0x115c2, 0x115c3, 1},
+		{0x115c9, 0x115c9, 1},
+		{0x11641, 0x11642, 1},
+		{0x16a6e, 0x16a6f, 1},
+		{0x16af5, 0x16af5, 1},
+		{0x16b37, 0x16b38, 1},
+		{0x16b44, 0x16b44, 1},
+		{0x1bc9f, 0x1bc9f, 1},
+	},
+	LatinOffset: 3,
+}
+
+var _Soft_Dotted = &RangeTable{
+	R16: []Range16{
+		{0x0069, 0x006a, 1},
+		{0x012f, 0x012f, 1},
+		{0x0249, 0x0249, 1},
+		{0x0268, 0x0268, 1},
+		{0x029d, 0x029d, 1},
+		{0x02b2, 0x02b2, 1},
+		{0x03f3, 0x03f3, 1},
+		{0x0456, 0x0456, 1},
+		{0x0458, 0x0458, 1},
+		{0x1d62, 0x1d62, 1},
+		{0x1d96, 0x1d96, 1},
+		{0x1da4, 0x1da4, 1},
+		{0x1da8, 0x1da8, 1},
+		{0x1e2d, 0x1e2d, 1},
+		{0x1ecb, 0x1ecb, 1},
+		{0x2071, 0x2071, 1},
+		{0x2148, 0x2149, 1},
+		{0x2c7c, 0x2c7c, 1},
+	},
+	R32: []Range32{
+		{0x1d422, 0x1d423, 1},
+		{0x1d456, 0x1d457, 1},
+		{0x1d48a, 0x1d48b, 1},
+		{0x1d4be, 0x1d4bf, 1},
+		{0x1d4f2, 0x1d4f3, 1},
+		{0x1d526, 0x1d527, 1},
+		{0x1d55a, 0x1d55b, 1},
+		{0x1d58e, 0x1d58f, 1},
+		{0x1d5c2, 0x1d5c3, 1},
+		{0x1d5f6, 0x1d5f7, 1},
+		{0x1d62a, 0x1d62b, 1},
+		{0x1d65e, 0x1d65f, 1},
+		{0x1d692, 0x1d693, 1},
+	},
+	LatinOffset: 1,
+}
+
+var _Terminal_Punctuation = &RangeTable{
+	R16: []Range16{
+		{0x0021, 0x0021, 1},
+		{0x002c, 0x002c, 1},
+		{0x002e, 0x002e, 1},
+		{0x003a, 0x003b, 1},
+		{0x003f, 0x003f, 1},
+		{0x037e, 0x037e, 1},
+		{0x0387, 0x0387, 1},
+		{0x0589, 0x0589, 1},
+		{0x05c3, 0x05c3, 1},
+		{0x060c, 0x060c, 1},
+		{0x061b, 0x061b, 1},
+		{0x061f, 0x061f, 1},
+		{0x06d4, 0x06d4, 1},
+		{0x0700, 0x070a, 1},
+		{0x070c, 0x070c, 1},
+		{0x07f8, 0x07f9, 1},
+		{0x0830, 0x083e, 1},
+		{0x085e, 0x085e, 1},
+		{0x0964, 0x0965, 1},
+		{0x0e5a, 0x0e5b, 1},
+		{0x0f08, 0x0f08, 1},
+		{0x0f0d, 0x0f12, 1},
+		{0x104a, 0x104b, 1},
+		{0x1361, 0x1368, 1},
+		{0x166d, 0x166e, 1},
+		{0x16eb, 0x16ed, 1},
+		{0x1735, 0x1736, 1},
+		{0x17d4, 0x17d6, 1},
+		{0x17da, 0x17da, 1},
+		{0x1802, 0x1805, 1},
+		{0x1808, 0x1809, 1},
+		{0x1944, 0x1945, 1},
+		{0x1aa8, 0x1aab, 1},
+		{0x1b5a, 0x1b5b, 1},
+		{0x1b5d, 0x1b5f, 1},
+		{0x1c3b, 0x1c3f, 1},
+		{0x1c7e, 0x1c7f, 1},
+		{0x203c, 0x203d, 1},
+		{0x2047, 0x2049, 1},
+		{0x2e2e, 0x2e2e, 1},
+		{0x2e3c, 0x2e3c, 1},
+		{0x2e41, 0x2e41, 1},
+		{0x3001, 0x3002, 1},
+		{0xa4fe, 0xa4ff, 1},
+		{0xa60d, 0xa60f, 1},
+		{0xa6f3, 0xa6f7, 1},
+		{0xa876, 0xa877, 1},
+		{0xa8ce, 0xa8cf, 1},
+		{0xa92f, 0xa92f, 1},
+		{0xa9c7, 0xa9c9, 1},
+		{0xaa5d, 0xaa5f, 1},
+		{0xaadf, 0xaadf, 1},
+		{0xaaf0, 0xaaf1, 1},
+		{0xabeb, 0xabeb, 1},
+		{0xfe50, 0xfe52, 1},
+		{0xfe54, 0xfe57, 1},
+		{0xff01, 0xff01, 1},
+		{0xff0c, 0xff0c, 1},
+		{0xff0e, 0xff0e, 1},
+		{0xff1a, 0xff1b, 1},
+		{0xff1f, 0xff1f, 1},
+		{0xff61, 0xff61, 1},
+		{0xff64, 0xff64, 1},
+	},
+	R32: []Range32{
+		{0x1039f, 0x1039f, 1},
+		{0x103d0, 0x103d0, 1},
+		{0x10857, 0x10857, 1},
+		{0x1091f, 0x1091f, 1},
+		{0x10a56, 0x10a57, 1},
+		{0x10af0, 0x10af5, 1},
+		{0x10b3a, 0x10b3f, 1},
+		{0x10b99, 0x10b9c, 1},
+		{0x11047, 0x1104d, 1},
+		{0x110be, 0x110c1, 1},
+		{0x11141, 0x11143, 1},
+		{0x111c5, 0x111c6, 1},
+		{0x111cd, 0x111cd, 1},
+		{0x11238, 0x1123c, 1},
+		{0x115c2, 0x115c5, 1},
+		{0x115c9, 0x115c9, 1},
+		{0x11641, 0x11642, 1},
+		{0x12470, 0x12474, 1},
+		{0x16a6e, 0x16a6f, 1},
+		{0x16af5, 0x16af5, 1},
+		{0x16b37, 0x16b39, 1},
+		{0x16b44, 0x16b44, 1},
+		{0x1bc9f, 0x1bc9f, 1},
+	},
+	LatinOffset: 5,
+}
+
+var _Unified_Ideograph = &RangeTable{
+	R16: []Range16{
+		{0x3400, 0x4db5, 1},
+		{0x4e00, 0x9fcc, 1},
+		{0xfa0e, 0xfa0f, 1},
+		{0xfa11, 0xfa11, 1},
+		{0xfa13, 0xfa14, 1},
+		{0xfa1f, 0xfa1f, 1},
+		{0xfa21, 0xfa21, 1},
+		{0xfa23, 0xfa24, 1},
+		{0xfa27, 0xfa29, 1},
+	},
+	R32: []Range32{
+		{0x20000, 0x2a6d6, 1},
+		{0x2a700, 0x2b734, 1},
+		{0x2b740, 0x2b81d, 1},
+	},
+}
+
+var _Variation_Selector = &RangeTable{
+	R16: []Range16{
+		{0x180b, 0x180d, 1},
+		{0xfe00, 0xfe0f, 1},
+	},
+	R32: []Range32{
+		{0xe0100, 0xe01ef, 1},
+	},
+}
+
+var _White_Space = &RangeTable{
+	R16: []Range16{
+		{0x0009, 0x000d, 1},
+		{0x0020, 0x0020, 1},
+		{0x0085, 0x0085, 1},
+		{0x00a0, 0x00a0, 1},
+		{0x1680, 0x1680, 1},
+		{0x2000, 0x200a, 1},
+		{0x2028, 0x2029, 1},
+		{0x202f, 0x202f, 1},
+		{0x205f, 0x205f, 1},
+		{0x3000, 0x3000, 1},
+	},
+	LatinOffset: 4,
+}
+
+// These variables have type *RangeTable.
+var (
+	ASCII_Hex_Digit                    = _ASCII_Hex_Digit                    // ASCII_Hex_Digit is the set of Unicode characters with property ASCII_Hex_Digit.
+	Bidi_Control                       = _Bidi_Control                       // Bidi_Control is the set of Unicode characters with property Bidi_Control.
+	Dash                               = _Dash                               // Dash is the set of Unicode characters with property Dash.
+	Deprecated                         = _Deprecated                         // Deprecated is the set of Unicode characters with property Deprecated.
+	Diacritic                          = _Diacritic                          // Diacritic is the set of Unicode characters with property Diacritic.
+	Extender                           = _Extender                           // Extender is the set of Unicode characters with property Extender.
+	Hex_Digit                          = _Hex_Digit                          // Hex_Digit is the set of Unicode characters with property Hex_Digit.
+	Hyphen                             = _Hyphen                             // Hyphen is the set of Unicode characters with property Hyphen.
+	IDS_Binary_Operator                = _IDS_Binary_Operator                // IDS_Binary_Operator is the set of Unicode characters with property IDS_Binary_Operator.
+	IDS_Trinary_Operator               = _IDS_Trinary_Operator               // IDS_Trinary_Operator is the set of Unicode characters with property IDS_Trinary_Operator.
+	Ideographic                        = _Ideographic                        // Ideographic is the set of Unicode characters with property Ideographic.
+	Join_Control                       = _Join_Control                       // Join_Control is the set of Unicode characters with property Join_Control.
+	Logical_Order_Exception            = _Logical_Order_Exception            // Logical_Order_Exception is the set of Unicode characters with property Logical_Order_Exception.
+	Noncharacter_Code_Point            = _Noncharacter_Code_Point            // Noncharacter_Code_Point is the set of Unicode characters with property Noncharacter_Code_Point.
+	Other_Alphabetic                   = _Other_Alphabetic                   // Other_Alphabetic is the set of Unicode characters with property Other_Alphabetic.
+	Other_Default_Ignorable_Code_Point = _Other_Default_Ignorable_Code_Point // Other_Default_Ignorable_Code_Point is the set of Unicode characters with property Other_Default_Ignorable_Code_Point.
+	Other_Grapheme_Extend              = _Other_Grapheme_Extend              // Other_Grapheme_Extend is the set of Unicode characters with property Other_Grapheme_Extend.
+	Other_ID_Continue                  = _Other_ID_Continue                  // Other_ID_Continue is the set of Unicode characters with property Other_ID_Continue.
+	Other_ID_Start                     = _Other_ID_Start                     // Other_ID_Start is the set of Unicode characters with property Other_ID_Start.
+	Other_Lowercase                    = _Other_Lowercase                    // Other_Lowercase is the set of Unicode characters with property Other_Lowercase.
+	Other_Math                         = _Other_Math                         // Other_Math is the set of Unicode characters with property Other_Math.
+	Other_Uppercase                    = _Other_Uppercase                    // Other_Uppercase is the set of Unicode characters with property Other_Uppercase.
+	Pattern_Syntax                     = _Pattern_Syntax                     // Pattern_Syntax is the set of Unicode characters with property Pattern_Syntax.
+	Pattern_White_Space                = _Pattern_White_Space                // Pattern_White_Space is the set of Unicode characters with property Pattern_White_Space.
+	Quotation_Mark                     = _Quotation_Mark                     // Quotation_Mark is the set of Unicode characters with property Quotation_Mark.
+	Radical                            = _Radical                            // Radical is the set of Unicode characters with property Radical.
+	STerm                              = _STerm                              // STerm is the set of Unicode characters with property STerm.
+	Soft_Dotted                        = _Soft_Dotted                        // Soft_Dotted is the set of Unicode characters with property Soft_Dotted.
+	Terminal_Punctuation               = _Terminal_Punctuation               // Terminal_Punctuation is the set of Unicode characters with property Terminal_Punctuation.
+	Unified_Ideograph                  = _Unified_Ideograph                  // Unified_Ideograph is the set of Unicode characters with property Unified_Ideograph.
+	Variation_Selector                 = _Variation_Selector                 // Variation_Selector is the set of Unicode characters with property Variation_Selector.
+	White_Space                        = _White_Space                        // White_Space is the set of Unicode characters with property White_Space.
+)
+
+// Generated by running
+//	maketables --data=http://www.unicode.org/Public/7.0.0/ucd/UnicodeData.txt --casefolding=http://www.unicode.org/Public/7.0.0/ucd/CaseFolding.txt
+// DO NOT EDIT
+
+// CaseRanges is the table describing case mappings for all letters with
+// non-self mappings.
+var CaseRanges = _CaseRanges
+var _CaseRanges = []CaseRange{
+	{0x0041, 0x005A, d{0, 32, 0}},
+	{0x0061, 0x007A, d{-32, 0, -32}},
+	{0x00B5, 0x00B5, d{743, 0, 743}},
+	{0x00C0, 0x00D6, d{0, 32, 0}},
+	{0x00D8, 0x00DE, d{0, 32, 0}},
+	{0x00E0, 0x00F6, d{-32, 0, -32}},
+	{0x00F8, 0x00FE, d{-32, 0, -32}},
+	{0x00FF, 0x00FF, d{121, 0, 121}},
+	{0x0100, 0x012F, d{UpperLower, UpperLower, UpperLower}},
+	{0x0130, 0x0130, d{0, -199, 0}},
+	{0x0131, 0x0131, d{-232, 0, -232}},
+	{0x0132, 0x0137, d{UpperLower, UpperLower, UpperLower}},
+	{0x0139, 0x0148, d{UpperLower, UpperLower, UpperLower}},
+	{0x014A, 0x0177, d{UpperLower, UpperLower, UpperLower}},
+	{0x0178, 0x0178, d{0, -121, 0}},
+	{0x0179, 0x017E, d{UpperLower, UpperLower, UpperLower}},
+	{0x017F, 0x017F, d{-300, 0, -300}},
+	{0x0180, 0x0180, d{195, 0, 195}},
+	{0x0181, 0x0181, d{0, 210, 0}},
+	{0x0182, 0x0185, d{UpperLower, UpperLower, UpperLower}},
+	{0x0186, 0x0186, d{0, 206, 0}},
+	{0x0187, 0x0188, d{UpperLower, UpperLower, UpperLower}},
+	{0x0189, 0x018A, d{0, 205, 0}},
+	{0x018B, 0x018C, d{UpperLower, UpperLower, UpperLower}},
+	{0x018E, 0x018E, d{0, 79, 0}},
+	{0x018F, 0x018F, d{0, 202, 0}},
+	{0x0190, 0x0190, d{0, 203, 0}},
+	{0x0191, 0x0192, d{UpperLower, UpperLower, UpperLower}},
+	{0x0193, 0x0193, d{0, 205, 0}},
+	{0x0194, 0x0194, d{0, 207, 0}},
+	{0x0195, 0x0195, d{97, 0, 97}},
+	{0x0196, 0x0196, d{0, 211, 0}},
+	{0x0197, 0x0197, d{0, 209, 0}},
+	{0x0198, 0x0199, d{UpperLower, UpperLower, UpperLower}},
+	{0x019A, 0x019A, d{163, 0, 163}},
+	{0x019C, 0x019C, d{0, 211, 0}},
+	{0x019D, 0x019D, d{0, 213, 0}},
+	{0x019E, 0x019E, d{130, 0, 130}},
+	{0x019F, 0x019F, d{0, 214, 0}},
+	{0x01A0, 0x01A5, d{UpperLower, UpperLower, UpperLower}},
+	{0x01A6, 0x01A6, d{0, 218, 0}},
+	{0x01A7, 0x01A8, d{UpperLower, UpperLower, UpperLower}},
+	{0x01A9, 0x01A9, d{0, 218, 0}},
+	{0x01AC, 0x01AD, d{UpperLower, UpperLower, UpperLower}},
+	{0x01AE, 0x01AE, d{0, 218, 0}},
+	{0x01AF, 0x01B0, d{UpperLower, UpperLower, UpperLower}},
+	{0x01B1, 0x01B2, d{0, 217, 0}},
+	{0x01B3, 0x01B6, d{UpperLower, UpperLower, UpperLower}},
+	{0x01B7, 0x01B7, d{0, 219, 0}},
+	{0x01B8, 0x01B9, d{UpperLower, UpperLower, UpperLower}},
+	{0x01BC, 0x01BD, d{UpperLower, UpperLower, UpperLower}},
+	{0x01BF, 0x01BF, d{56, 0, 56}},
+	{0x01C4, 0x01C4, d{0, 2, 1}},
+	{0x01C5, 0x01C5, d{-1, 1, 0}},
+	{0x01C6, 0x01C6, d{-2, 0, -1}},
+	{0x01C7, 0x01C7, d{0, 2, 1}},
+	{0x01C8, 0x01C8, d{-1, 1, 0}},
+	{0x01C9, 0x01C9, d{-2, 0, -1}},
+	{0x01CA, 0x01CA, d{0, 2, 1}},
+	{0x01CB, 0x01CB, d{-1, 1, 0}},
+	{0x01CC, 0x01CC, d{-2, 0, -1}},
+	{0x01CD, 0x01DC, d{UpperLower, UpperLower, UpperLower}},
+	{0x01DD, 0x01DD, d{-79, 0, -79}},
+	{0x01DE, 0x01EF, d{UpperLower, UpperLower, UpperLower}},
+	{0x01F1, 0x01F1, d{0, 2, 1}},
+	{0x01F2, 0x01F2, d{-1, 1, 0}},
+	{0x01F3, 0x01F3, d{-2, 0, -1}},
+	{0x01F4, 0x01F5, d{UpperLower, UpperLower, UpperLower}},
+	{0x01F6, 0x01F6, d{0, -97, 0}},
+	{0x01F7, 0x01F7, d{0, -56, 0}},
+	{0x01F8, 0x021F, d{UpperLower, UpperLower, UpperLower}},
+	{0x0220, 0x0220, d{0, -130, 0}},
+	{0x0222, 0x0233, d{UpperLower, UpperLower, UpperLower}},
+	{0x023A, 0x023A, d{0, 10795, 0}},
+	{0x023B, 0x023C, d{UpperLower, UpperLower, UpperLower}},
+	{0x023D, 0x023D, d{0, -163, 0}},
+	{0x023E, 0x023E, d{0, 10792, 0}},
+	{0x023F, 0x0240, d{10815, 0, 10815}},
+	{0x0241, 0x0242, d{UpperLower, UpperLower, UpperLower}},
+	{0x0243, 0x0243, d{0, -195, 0}},
+	{0x0244, 0x0244, d{0, 69, 0}},
+	{0x0245, 0x0245, d{0, 71, 0}},
+	{0x0246, 0x024F, d{UpperLower, UpperLower, UpperLower}},
+	{0x0250, 0x0250, d{10783, 0, 10783}},
+	{0x0251, 0x0251, d{10780, 0, 10780}},
+	{0x0252, 0x0252, d{10782, 0, 10782}},
+	{0x0253, 0x0253, d{-210, 0, -210}},
+	{0x0254, 0x0254, d{-206, 0, -206}},
+	{0x0256, 0x0257, d{-205, 0, -205}},
+	{0x0259, 0x0259, d{-202, 0, -202}},
+	{0x025B, 0x025B, d{-203, 0, -203}},
+	{0x025C, 0x025C, d{42319, 0, 42319}},
+	{0x0260, 0x0260, d{-205, 0, -205}},
+	{0x0261, 0x0261, d{42315, 0, 42315}},
+	{0x0263, 0x0263, d{-207, 0, -207}},
+	{0x0265, 0x0265, d{42280, 0, 42280}},
+	{0x0266, 0x0266, d{42308, 0, 42308}},
+	{0x0268, 0x0268, d{-209, 0, -209}},
+	{0x0269, 0x0269, d{-211, 0, -211}},
+	{0x026B, 0x026B, d{10743, 0, 10743}},
+	{0x026C, 0x026C, d{42305, 0, 42305}},
+	{0x026F, 0x026F, d{-211, 0, -211}},
+	{0x0271, 0x0271, d{10749, 0, 10749}},
+	{0x0272, 0x0272, d{-213, 0, -213}},
+	{0x0275, 0x0275, d{-214, 0, -214}},
+	{0x027D, 0x027D, d{10727, 0, 10727}},
+	{0x0280, 0x0280, d{-218, 0, -218}},
+	{0x0283, 0x0283, d{-218, 0, -218}},
+	{0x0287, 0x0287, d{42282, 0, 42282}},
+	{0x0288, 0x0288, d{-218, 0, -218}},
+	{0x0289, 0x0289, d{-69, 0, -69}},
+	{0x028A, 0x028B, d{-217, 0, -217}},
+	{0x028C, 0x028C, d{-71, 0, -71}},
+	{0x0292, 0x0292, d{-219, 0, -219}},
+	{0x029E, 0x029E, d{42258, 0, 42258}},
+	{0x0345, 0x0345, d{84, 0, 84}},
+	{0x0370, 0x0373, d{UpperLower, UpperLower, UpperLower}},
+	{0x0376, 0x0377, d{UpperLower, UpperLower, UpperLower}},
+	{0x037B, 0x037D, d{130, 0, 130}},
+	{0x037F, 0x037F, d{0, 116, 0}},
+	{0x0386, 0x0386, d{0, 38, 0}},
+	{0x0388, 0x038A, d{0, 37, 0}},
+	{0x038C, 0x038C, d{0, 64, 0}},
+	{0x038E, 0x038F, d{0, 63, 0}},
+	{0x0391, 0x03A1, d{0, 32, 0}},
+	{0x03A3, 0x03AB, d{0, 32, 0}},
+	{0x03AC, 0x03AC, d{-38, 0, -38}},
+	{0x03AD, 0x03AF, d{-37, 0, -37}},
+	{0x03B1, 0x03C1, d{-32, 0, -32}},
+	{0x03C2, 0x03C2, d{-31, 0, -31}},
+	{0x03C3, 0x03CB, d{-32, 0, -32}},
+	{0x03CC, 0x03CC, d{-64, 0, -64}},
+	{0x03CD, 0x03CE, d{-63, 0, -63}},
+	{0x03CF, 0x03CF, d{0, 8, 0}},
+	{0x03D0, 0x03D0, d{-62, 0, -62}},
+	{0x03D1, 0x03D1, d{-57, 0, -57}},
+	{0x03D5, 0x03D5, d{-47, 0, -47}},
+	{0x03D6, 0x03D6, d{-54, 0, -54}},
+	{0x03D7, 0x03D7, d{-8, 0, -8}},
+	{0x03D8, 0x03EF, d{UpperLower, UpperLower, UpperLower}},
+	{0x03F0, 0x03F0, d{-86, 0, -86}},
+	{0x03F1, 0x03F1, d{-80, 0, -80}},
+	{0x03F2, 0x03F2, d{7, 0, 7}},
+	{0x03F3, 0x03F3, d{-116, 0, -116}},
+	{0x03F4, 0x03F4, d{0, -60, 0}},
+	{0x03F5, 0x03F5, d{-96, 0, -96}},
+	{0x03F7, 0x03F8, d{UpperLower, UpperLower, UpperLower}},
+	{0x03F9, 0x03F9, d{0, -7, 0}},
+	{0x03FA, 0x03FB, d{UpperLower, UpperLower, UpperLower}},
+	{0x03FD, 0x03FF, d{0, -130, 0}},
+	{0x0400, 0x040F, d{0, 80, 0}},
+	{0x0410, 0x042F, d{0, 32, 0}},
+	{0x0430, 0x044F, d{-32, 0, -32}},
+	{0x0450, 0x045F, d{-80, 0, -80}},
+	{0x0460, 0x0481, d{UpperLower, UpperLower, UpperLower}},
+	{0x048A, 0x04BF, d{UpperLower, UpperLower, UpperLower}},
+	{0x04C0, 0x04C0, d{0, 15, 0}},
+	{0x04C1, 0x04CE, d{UpperLower, UpperLower, UpperLower}},
+	{0x04CF, 0x04CF, d{-15, 0, -15}},
+	{0x04D0, 0x052F, d{UpperLower, UpperLower, UpperLower}},
+	{0x0531, 0x0556, d{0, 48, 0}},
+	{0x0561, 0x0586, d{-48, 0, -48}},
+	{0x10A0, 0x10C5, d{0, 7264, 0}},
+	{0x10C7, 0x10C7, d{0, 7264, 0}},
+	{0x10CD, 0x10CD, d{0, 7264, 0}},
+	{0x1D79, 0x1D79, d{35332, 0, 35332}},
+	{0x1D7D, 0x1D7D, d{3814, 0, 3814}},
+	{0x1E00, 0x1E95, d{UpperLower, UpperLower, UpperLower}},
+	{0x1E9B, 0x1E9B, d{-59, 0, -59}},
+	{0x1E9E, 0x1E9E, d{0, -7615, 0}},
+	{0x1EA0, 0x1EFF, d{UpperLower, UpperLower, UpperLower}},
+	{0x1F00, 0x1F07, d{8, 0, 8}},
+	{0x1F08, 0x1F0F, d{0, -8, 0}},
+	{0x1F10, 0x1F15, d{8, 0, 8}},
+	{0x1F18, 0x1F1D, d{0, -8, 0}},
+	{0x1F20, 0x1F27, d{8, 0, 8}},
+	{0x1F28, 0x1F2F, d{0, -8, 0}},
+	{0x1F30, 0x1F37, d{8, 0, 8}},
+	{0x1F38, 0x1F3F, d{0, -8, 0}},
+	{0x1F40, 0x1F45, d{8, 0, 8}},
+	{0x1F48, 0x1F4D, d{0, -8, 0}},
+	{0x1F51, 0x1F51, d{8, 0, 8}},
+	{0x1F53, 0x1F53, d{8, 0, 8}},
+	{0x1F55, 0x1F55, d{8, 0, 8}},
+	{0x1F57, 0x1F57, d{8, 0, 8}},
+	{0x1F59, 0x1F59, d{0, -8, 0}},
+	{0x1F5B, 0x1F5B, d{0, -8, 0}},
+	{0x1F5D, 0x1F5D, d{0, -8, 0}},
+	{0x1F5F, 0x1F5F, d{0, -8, 0}},
+	{0x1F60, 0x1F67, d{8, 0, 8}},
+	{0x1F68, 0x1F6F, d{0, -8, 0}},
+	{0x1F70, 0x1F71, d{74, 0, 74}},
+	{0x1F72, 0x1F75, d{86, 0, 86}},
+	{0x1F76, 0x1F77, d{100, 0, 100}},
+	{0x1F78, 0x1F79, d{128, 0, 128}},
+	{0x1F7A, 0x1F7B, d{112, 0, 112}},
+	{0x1F7C, 0x1F7D, d{126, 0, 126}},
+	{0x1F80, 0x1F87, d{8, 0, 8}},
+	{0x1F88, 0x1F8F, d{0, -8, 0}},
+	{0x1F90, 0x1F97, d{8, 0, 8}},
+	{0x1F98, 0x1F9F, d{0, -8, 0}},
+	{0x1FA0, 0x1FA7, d{8, 0, 8}},
+	{0x1FA8, 0x1FAF, d{0, -8, 0}},
+	{0x1FB0, 0x1FB1, d{8, 0, 8}},
+	{0x1FB3, 0x1FB3, d{9, 0, 9}},
+	{0x1FB8, 0x1FB9, d{0, -8, 0}},
+	{0x1FBA, 0x1FBB, d{0, -74, 0}},
+	{0x1FBC, 0x1FBC, d{0, -9, 0}},
+	{0x1FBE, 0x1FBE, d{-7205, 0, -7205}},
+	{0x1FC3, 0x1FC3, d{9, 0, 9}},
+	{0x1FC8, 0x1FCB, d{0, -86, 0}},
+	{0x1FCC, 0x1FCC, d{0, -9, 0}},
+	{0x1FD0, 0x1FD1, d{8, 0, 8}},
+	{0x1FD8, 0x1FD9, d{0, -8, 0}},
+	{0x1FDA, 0x1FDB, d{0, -100, 0}},
+	{0x1FE0, 0x1FE1, d{8, 0, 8}},
+	{0x1FE5, 0x1FE5, d{7, 0, 7}},
+	{0x1FE8, 0x1FE9, d{0, -8, 0}},
+	{0x1FEA, 0x1FEB, d{0, -112, 0}},
+	{0x1FEC, 0x1FEC, d{0, -7, 0}},
+	{0x1FF3, 0x1FF3, d{9, 0, 9}},
+	{0x1FF8, 0x1FF9, d{0, -128, 0}},
+	{0x1FFA, 0x1FFB, d{0, -126, 0}},
+	{0x1FFC, 0x1FFC, d{0, -9, 0}},
+	{0x2126, 0x2126, d{0, -7517, 0}},
+	{0x212A, 0x212A, d{0, -8383, 0}},
+	{0x212B, 0x212B, d{0, -8262, 0}},
+	{0x2132, 0x2132, d{0, 28, 0}},
+	{0x214E, 0x214E, d{-28, 0, -28}},
+	{0x2160, 0x216F, d{0, 16, 0}},
+	{0x2170, 0x217F, d{-16, 0, -16}},
+	{0x2183, 0x2184, d{UpperLower, UpperLower, UpperLower}},
+	{0x24B6, 0x24CF, d{0, 26, 0}},
+	{0x24D0, 0x24E9, d{-26, 0, -26}},
+	{0x2C00, 0x2C2E, d{0, 48, 0}},
+	{0x2C30, 0x2C5E, d{-48, 0, -48}},
+	{0x2C60, 0x2C61, d{UpperLower, UpperLower, UpperLower}},
+	{0x2C62, 0x2C62, d{0, -10743, 0}},
+	{0x2C63, 0x2C63, d{0, -3814, 0}},
+	{0x2C64, 0x2C64, d{0, -10727, 0}},
+	{0x2C65, 0x2C65, d{-10795, 0, -10795}},
+	{0x2C66, 0x2C66, d{-10792, 0, -10792}},
+	{0x2C67, 0x2C6C, d{UpperLower, UpperLower, UpperLower}},
+	{0x2C6D, 0x2C6D, d{0, -10780, 0}},
+	{0x2C6E, 0x2C6E, d{0, -10749, 0}},
+	{0x2C6F, 0x2C6F, d{0, -10783, 0}},
+	{0x2C70, 0x2C70, d{0, -10782, 0}},
+	{0x2C72, 0x2C73, d{UpperLower, UpperLower, UpperLower}},
+	{0x2C75, 0x2C76, d{UpperLower, UpperLower, UpperLower}},
+	{0x2C7E, 0x2C7F, d{0, -10815, 0}},
+	{0x2C80, 0x2CE3, d{UpperLower, UpperLower, UpperLower}},
+	{0x2CEB, 0x2CEE, d{UpperLower, UpperLower, UpperLower}},
+	{0x2CF2, 0x2CF3, d{UpperLower, UpperLower, UpperLower}},
+	{0x2D00, 0x2D25, d{-7264, 0, -7264}},
+	{0x2D27, 0x2D27, d{-7264, 0, -7264}},
+	{0x2D2D, 0x2D2D, d{-7264, 0, -7264}},
+	{0xA640, 0xA66D, d{UpperLower, UpperLower, UpperLower}},
+	{0xA680, 0xA69B, d{UpperLower, UpperLower, UpperLower}},
+	{0xA722, 0xA72F, d{UpperLower, UpperLower, UpperLower}},
+	{0xA732, 0xA76F, d{UpperLower, UpperLower, UpperLower}},
+	{0xA779, 0xA77C, d{UpperLower, UpperLower, UpperLower}},
+	{0xA77D, 0xA77D, d{0, -35332, 0}},
+	{0xA77E, 0xA787, d{UpperLower, UpperLower, UpperLower}},
+	{0xA78B, 0xA78C, d{UpperLower, UpperLower, UpperLower}},
+	{0xA78D, 0xA78D, d{0, -42280, 0}},
+	{0xA790, 0xA793, d{UpperLower, UpperLower, UpperLower}},
+	{0xA796, 0xA7A9, d{UpperLower, UpperLower, UpperLower}},
+	{0xA7AA, 0xA7AA, d{0, -42308, 0}},
+	{0xA7AB, 0xA7AB, d{0, -42319, 0}},
+	{0xA7AC, 0xA7AC, d{0, -42315, 0}},
+	{0xA7AD, 0xA7AD, d{0, -42305, 0}},
+	{0xA7B0, 0xA7B0, d{0, -42258, 0}},
+	{0xA7B1, 0xA7B1, d{0, -42282, 0}},
+	{0xFF21, 0xFF3A, d{0, 32, 0}},
+	{0xFF41, 0xFF5A, d{-32, 0, -32}},
+	{0x10400, 0x10427, d{0, 40, 0}},
+	{0x10428, 0x1044F, d{-40, 0, -40}},
+	{0x118A0, 0x118BF, d{0, 32, 0}},
+	{0x118C0, 0x118DF, d{-32, 0, -32}},
+}
+var properties = [MaxLatin1 + 1]uint8{
+	0x00: pC,       // '\x00'
+	0x01: pC,       // '\x01'
+	0x02: pC,       // '\x02'
+	0x03: pC,       // '\x03'
+	0x04: pC,       // '\x04'
+	0x05: pC,       // '\x05'
+	0x06: pC,       // '\x06'
+	0x07: pC,       // '\a'
+	0x08: pC,       // '\b'
+	0x09: pC,       // '\t'
+	0x0A: pC,       // '\n'
+	0x0B: pC,       // '\v'
+	0x0C: pC,       // '\f'
+	0x0D: pC,       // '\r'
+	0x0E: pC,       // '\x0e'
+	0x0F: pC,       // '\x0f'
+	0x10: pC,       // '\x10'
+	0x11: pC,       // '\x11'
+	0x12: pC,       // '\x12'
+	0x13: pC,       // '\x13'
+	0x14: pC,       // '\x14'
+	0x15: pC,       // '\x15'
+	0x16: pC,       // '\x16'
+	0x17: pC,       // '\x17'
+	0x18: pC,       // '\x18'
+	0x19: pC,       // '\x19'
+	0x1A: pC,       // '\x1a'
+	0x1B: pC,       // '\x1b'
+	0x1C: pC,       // '\x1c'
+	0x1D: pC,       // '\x1d'
+	0x1E: pC,       // '\x1e'
+	0x1F: pC,       // '\x1f'
+	0x20: pZ | pp,  // ' '
+	0x21: pP | pp,  // '!'
+	0x22: pP | pp,  // '"'
+	0x23: pP | pp,  // '#'
+	0x24: pS | pp,  // '$'
+	0x25: pP | pp,  // '%'
+	0x26: pP | pp,  // '&'
+	0x27: pP | pp,  // '\''
+	0x28: pP | pp,  // '('
+	0x29: pP | pp,  // ')'
+	0x2A: pP | pp,  // '*'
+	0x2B: pS | pp,  // '+'
+	0x2C: pP | pp,  // ','
+	0x2D: pP | pp,  // '-'
+	0x2E: pP | pp,  // '.'
+	0x2F: pP | pp,  // '/'
+	0x30: pN | pp,  // '0'
+	0x31: pN | pp,  // '1'
+	0x32: pN | pp,  // '2'
+	0x33: pN | pp,  // '3'
+	0x34: pN | pp,  // '4'
+	0x35: pN | pp,  // '5'
+	0x36: pN | pp,  // '6'
+	0x37: pN | pp,  // '7'
+	0x38: pN | pp,  // '8'
+	0x39: pN | pp,  // '9'
+	0x3A: pP | pp,  // ':'
+	0x3B: pP | pp,  // ';'
+	0x3C: pS | pp,  // '<'
+	0x3D: pS | pp,  // '='
+	0x3E: pS | pp,  // '>'
+	0x3F: pP | pp,  // '?'
+	0x40: pP | pp,  // '@'
+	0x41: pLu | pp, // 'A'
+	0x42: pLu | pp, // 'B'
+	0x43: pLu | pp, // 'C'
+	0x44: pLu | pp, // 'D'
+	0x45: pLu | pp, // 'E'
+	0x46: pLu | pp, // 'F'
+	0x47: pLu | pp, // 'G'
+	0x48: pLu | pp, // 'H'
+	0x49: pLu | pp, // 'I'
+	0x4A: pLu | pp, // 'J'
+	0x4B: pLu | pp, // 'K'
+	0x4C: pLu | pp, // 'L'
+	0x4D: pLu | pp, // 'M'
+	0x4E: pLu | pp, // 'N'
+	0x4F: pLu | pp, // 'O'
+	0x50: pLu | pp, // 'P'
+	0x51: pLu | pp, // 'Q'
+	0x52: pLu | pp, // 'R'
+	0x53: pLu | pp, // 'S'
+	0x54: pLu | pp, // 'T'
+	0x55: pLu | pp, // 'U'
+	0x56: pLu | pp, // 'V'
+	0x57: pLu | pp, // 'W'
+	0x58: pLu | pp, // 'X'
+	0x59: pLu | pp, // 'Y'
+	0x5A: pLu | pp, // 'Z'
+	0x5B: pP | pp,  // '['
+	0x5C: pP | pp,  // '\\'
+	0x5D: pP | pp,  // ']'
+	0x5E: pS | pp,  // '^'
+	0x5F: pP | pp,  // '_'
+	0x60: pS | pp,  // '`'
+	0x61: pLl | pp, // 'a'
+	0x62: pLl | pp, // 'b'
+	0x63: pLl | pp, // 'c'
+	0x64: pLl | pp, // 'd'
+	0x65: pLl | pp, // 'e'
+	0x66: pLl | pp, // 'f'
+	0x67: pLl | pp, // 'g'
+	0x68: pLl | pp, // 'h'
+	0x69: pLl | pp, // 'i'
+	0x6A: pLl | pp, // 'j'
+	0x6B: pLl | pp, // 'k'
+	0x6C: pLl | pp, // 'l'
+	0x6D: pLl | pp, // 'm'
+	0x6E: pLl | pp, // 'n'
+	0x6F: pLl | pp, // 'o'
+	0x70: pLl | pp, // 'p'
+	0x71: pLl | pp, // 'q'
+	0x72: pLl | pp, // 'r'
+	0x73: pLl | pp, // 's'
+	0x74: pLl | pp, // 't'
+	0x75: pLl | pp, // 'u'
+	0x76: pLl | pp, // 'v'
+	0x77: pLl | pp, // 'w'
+	0x78: pLl | pp, // 'x'
+	0x79: pLl | pp, // 'y'
+	0x7A: pLl | pp, // 'z'
+	0x7B: pP | pp,  // '{'
+	0x7C: pS | pp,  // '|'
+	0x7D: pP | pp,  // '}'
+	0x7E: pS | pp,  // '~'
+	0x7F: pC,       // '\u007f'
+	0x80: pC,       // '\u0080'
+	0x81: pC,       // '\u0081'
+	0x82: pC,       // '\u0082'
+	0x83: pC,       // '\u0083'
+	0x84: pC,       // '\u0084'
+	0x85: pC,       // '\u0085'
+	0x86: pC,       // '\u0086'
+	0x87: pC,       // '\u0087'
+	0x88: pC,       // '\u0088'
+	0x89: pC,       // '\u0089'
+	0x8A: pC,       // '\u008a'
+	0x8B: pC,       // '\u008b'
+	0x8C: pC,       // '\u008c'
+	0x8D: pC,       // '\u008d'
+	0x8E: pC,       // '\u008e'
+	0x8F: pC,       // '\u008f'
+	0x90: pC,       // '\u0090'
+	0x91: pC,       // '\u0091'
+	0x92: pC,       // '\u0092'
+	0x93: pC,       // '\u0093'
+	0x94: pC,       // '\u0094'
+	0x95: pC,       // '\u0095'
+	0x96: pC,       // '\u0096'
+	0x97: pC,       // '\u0097'
+	0x98: pC,       // '\u0098'
+	0x99: pC,       // '\u0099'
+	0x9A: pC,       // '\u009a'
+	0x9B: pC,       // '\u009b'
+	0x9C: pC,       // '\u009c'
+	0x9D: pC,       // '\u009d'
+	0x9E: pC,       // '\u009e'
+	0x9F: pC,       // '\u009f'
+	0xA0: pZ,       // '\u00a0'
+	0xA1: pP | pp,  // '¡'
+	0xA2: pS | pp,  // '¢'
+	0xA3: pS | pp,  // '£'
+	0xA4: pS | pp,  // '¤'
+	0xA5: pS | pp,  // '¥'
+	0xA6: pS | pp,  // '¦'
+	0xA7: pP | pp,  // '§'
+	0xA8: pS | pp,  // '¨'
+	0xA9: pS | pp,  // '©'
+	0xAA: pLo | pp, // 'ª'
+	0xAB: pP | pp,  // '«'
+	0xAC: pS | pp,  // '¬'
+	0xAD: 0,        // '\u00ad'
+	0xAE: pS | pp,  // '®'
+	0xAF: pS | pp,  // '¯'
+	0xB0: pS | pp,  // '°'
+	0xB1: pS | pp,  // '±'
+	0xB2: pN | pp,  // '²'
+	0xB3: pN | pp,  // '³'
+	0xB4: pS | pp,  // '´'
+	0xB5: pLl | pp, // 'µ'
+	0xB6: pP | pp,  // '¶'
+	0xB7: pP | pp,  // '·'
+	0xB8: pS | pp,  // '¸'
+	0xB9: pN | pp,  // '¹'
+	0xBA: pLo | pp, // 'º'
+	0xBB: pP | pp,  // '»'
+	0xBC: pN | pp,  // '¼'
+	0xBD: pN | pp,  // '½'
+	0xBE: pN | pp,  // '¾'
+	0xBF: pP | pp,  // '¿'
+	0xC0: pLu | pp, // 'À'
+	0xC1: pLu | pp, // 'Á'
+	0xC2: pLu | pp, // 'Â'
+	0xC3: pLu | pp, // 'Ã'
+	0xC4: pLu | pp, // 'Ä'
+	0xC5: pLu | pp, // 'Å'
+	0xC6: pLu | pp, // 'Æ'
+	0xC7: pLu | pp, // 'Ç'
+	0xC8: pLu | pp, // 'È'
+	0xC9: pLu | pp, // 'É'
+	0xCA: pLu | pp, // 'Ê'
+	0xCB: pLu | pp, // 'Ë'
+	0xCC: pLu | pp, // 'Ì'
+	0xCD: pLu | pp, // 'Í'
+	0xCE: pLu | pp, // 'Î'
+	0xCF: pLu | pp, // 'Ï'
+	0xD0: pLu | pp, // 'Ð'
+	0xD1: pLu | pp, // 'Ñ'
+	0xD2: pLu | pp, // 'Ò'
+	0xD3: pLu | pp, // 'Ó'
+	0xD4: pLu | pp, // 'Ô'
+	0xD5: pLu | pp, // 'Õ'
+	0xD6: pLu | pp, // 'Ö'
+	0xD7: pS | pp,  // '×'
+	0xD8: pLu | pp, // 'Ø'
+	0xD9: pLu | pp, // 'Ù'
+	0xDA: pLu | pp, // 'Ú'
+	0xDB: pLu | pp, // 'Û'
+	0xDC: pLu | pp, // 'Ü'
+	0xDD: pLu | pp, // 'Ý'
+	0xDE: pLu | pp, // 'Þ'
+	0xDF: pLl | pp, // 'ß'
+	0xE0: pLl | pp, // 'à'
+	0xE1: pLl | pp, // 'á'
+	0xE2: pLl | pp, // 'â'
+	0xE3: pLl | pp, // 'ã'
+	0xE4: pLl | pp, // 'ä'
+	0xE5: pLl | pp, // 'å'
+	0xE6: pLl | pp, // 'æ'
+	0xE7: pLl | pp, // 'ç'
+	0xE8: pLl | pp, // 'è'
+	0xE9: pLl | pp, // 'é'
+	0xEA: pLl | pp, // 'ê'
+	0xEB: pLl | pp, // 'ë'
+	0xEC: pLl | pp, // 'ì'
+	0xED: pLl | pp, // 'í'
+	0xEE: pLl | pp, // 'î'
+	0xEF: pLl | pp, // 'ï'
+	0xF0: pLl | pp, // 'ð'
+	0xF1: pLl | pp, // 'ñ'
+	0xF2: pLl | pp, // 'ò'
+	0xF3: pLl | pp, // 'ó'
+	0xF4: pLl | pp, // 'ô'
+	0xF5: pLl | pp, // 'õ'
+	0xF6: pLl | pp, // 'ö'
+	0xF7: pS | pp,  // '÷'
+	0xF8: pLl | pp, // 'ø'
+	0xF9: pLl | pp, // 'ù'
+	0xFA: pLl | pp, // 'ú'
+	0xFB: pLl | pp, // 'û'
+	0xFC: pLl | pp, // 'ü'
+	0xFD: pLl | pp, // 'ý'
+	0xFE: pLl | pp, // 'þ'
+	0xFF: pLl | pp, // 'ÿ'
+}
+
+var caseOrbit = []foldPair{
+	{0x004B, 0x006B},
+	{0x0053, 0x0073},
+	{0x006B, 0x212A},
+	{0x0073, 0x017F},
+	{0x00B5, 0x039C},
+	{0x00C5, 0x00E5},
+	{0x00DF, 0x1E9E},
+	{0x00E5, 0x212B},
+	{0x0130, 0x0130},
+	{0x0131, 0x0131},
+	{0x017F, 0x0053},
+	{0x01C4, 0x01C5},
+	{0x01C5, 0x01C6},
+	{0x01C6, 0x01C4},
+	{0x01C7, 0x01C8},
+	{0x01C8, 0x01C9},
+	{0x01C9, 0x01C7},
+	{0x01CA, 0x01CB},
+	{0x01CB, 0x01CC},
+	{0x01CC, 0x01CA},
+	{0x01F1, 0x01F2},
+	{0x01F2, 0x01F3},
+	{0x01F3, 0x01F1},
+	{0x0345, 0x0399},
+	{0x0392, 0x03B2},
+	{0x0395, 0x03B5},
+	{0x0398, 0x03B8},
+	{0x0399, 0x03B9},
+	{0x039A, 0x03BA},
+	{0x039C, 0x03BC},
+	{0x03A0, 0x03C0},
+	{0x03A1, 0x03C1},
+	{0x03A3, 0x03C2},
+	{0x03A6, 0x03C6},
+	{0x03A9, 0x03C9},
+	{0x03B2, 0x03D0},
+	{0x03B5, 0x03F5},
+	{0x03B8, 0x03D1},
+	{0x03B9, 0x1FBE},
+	{0x03BA, 0x03F0},
+	{0x03BC, 0x00B5},
+	{0x03C0, 0x03D6},
+	{0x03C1, 0x03F1},
+	{0x03C2, 0x03C3},
+	{0x03C3, 0x03A3},
+	{0x03C6, 0x03D5},
+	{0x03C9, 0x2126},
+	{0x03D0, 0x0392},
+	{0x03D1, 0x03F4},
+	{0x03D5, 0x03A6},
+	{0x03D6, 0x03A0},
+	{0x03F0, 0x039A},
+	{0x03F1, 0x03A1},
+	{0x03F4, 0x0398},
+	{0x03F5, 0x0395},
+	{0x1E60, 0x1E61},
+	{0x1E61, 0x1E9B},
+	{0x1E9B, 0x1E60},
+	{0x1E9E, 0x00DF},
+	{0x1FBE, 0x0345},
+	{0x2126, 0x03A9},
+	{0x212A, 0x004B},
+	{0x212B, 0x00C5},
+}
+
+// FoldCategory maps a category name to a table of
+// code points outside the category that are equivalent under
+// simple case folding to code points inside the category.
+// If there is no entry for a category name, there are no such points.
+var FoldCategory = map[string]*RangeTable{
+	"Common":    foldCommon,
+	"Greek":     foldGreek,
+	"Inherited": foldInherited,
+	"L":         foldL,
+	"Ll":        foldLl,
+	"Lt":        foldLt,
+	"Lu":        foldLu,
+	"M":         foldM,
+	"Mn":        foldMn,
+}
+
+var foldCommon = &RangeTable{
+	R16: []Range16{
+		{0x039c, 0x03bc, 32},
+	},
+}
+
+var foldGreek = &RangeTable{
+	R16: []Range16{
+		{0x00b5, 0x0345, 656},
+	},
+}
+
+var foldInherited = &RangeTable{
+	R16: []Range16{
+		{0x0399, 0x03b9, 32},
+		{0x1fbe, 0x1fbe, 1},
+	},
+}
+
+var foldL = &RangeTable{
+	R16: []Range16{
+		{0x0345, 0x0345, 1},
+	},
+}
+
+var foldLl = &RangeTable{
+	R16: []Range16{
+		{0x0041, 0x005a, 1},
+		{0x00c0, 0x00d6, 1},
+		{0x00d8, 0x00de, 1},
+		{0x0100, 0x012e, 2},
+		{0x0132, 0x0136, 2},
+		{0x0139, 0x0147, 2},
+		{0x014a, 0x0178, 2},
+		{0x0179, 0x017d, 2},
+		{0x0181, 0x0182, 1},
+		{0x0184, 0x0186, 2},
+		{0x0187, 0x0189, 2},
+		{0x018a, 0x018b, 1},
+		{0x018e, 0x0191, 1},
+		{0x0193, 0x0194, 1},
+		{0x0196, 0x0198, 1},
+		{0x019c, 0x019d, 1},
+		{0x019f, 0x01a0, 1},
+		{0x01a2, 0x01a6, 2},
+		{0x01a7, 0x01a9, 2},
+		{0x01ac, 0x01ae, 2},
+		{0x01af, 0x01b1, 2},
+		{0x01b2, 0x01b3, 1},
+		{0x01b5, 0x01b7, 2},
+		{0x01b8, 0x01bc, 4},
+		{0x01c4, 0x01c5, 1},
+		{0x01c7, 0x01c8, 1},
+		{0x01ca, 0x01cb, 1},
+		{0x01cd, 0x01db, 2},
+		{0x01de, 0x01ee, 2},
+		{0x01f1, 0x01f2, 1},
+		{0x01f4, 0x01f6, 2},
+		{0x01f7, 0x01f8, 1},
+		{0x01fa, 0x0232, 2},
+		{0x023a, 0x023b, 1},
+		{0x023d, 0x023e, 1},
+		{0x0241, 0x0243, 2},
+		{0x0244, 0x0246, 1},
+		{0x0248, 0x024e, 2},
+		{0x0345, 0x0370, 43},
+		{0x0372, 0x0376, 4},
+		{0x037f, 0x0386, 7},
+		{0x0388, 0x038a, 1},
+		{0x038c, 0x038e, 2},
+		{0x038f, 0x0391, 2},
+		{0x0392, 0x03a1, 1},
+		{0x03a3, 0x03ab, 1},
+		{0x03cf, 0x03d8, 9},
+		{0x03da, 0x03ee, 2},
+		{0x03f4, 0x03f7, 3},
+		{0x03f9, 0x03fa, 1},
+		{0x03fd, 0x042f, 1},
+		{0x0460, 0x0480, 2},
+		{0x048a, 0x04c0, 2},
+		{0x04c1, 0x04cd, 2},
+		{0x04d0, 0x052e, 2},
+		{0x0531, 0x0556, 1},
+		{0x10a0, 0x10c5, 1},
+		{0x10c7, 0x10cd, 6},
+		{0x1e00, 0x1e94, 2},
+		{0x1e9e, 0x1efe, 2},
+		{0x1f08, 0x1f0f, 1},
+		{0x1f18, 0x1f1d, 1},
+		{0x1f28, 0x1f2f, 1},
+		{0x1f38, 0x1f3f, 1},
+		{0x1f48, 0x1f4d, 1},
+		{0x1f59, 0x1f5f, 2},
+		{0x1f68, 0x1f6f, 1},
+		{0x1f88, 0x1f8f, 1},
+		{0x1f98, 0x1f9f, 1},
+		{0x1fa8, 0x1faf, 1},
+		{0x1fb8, 0x1fbc, 1},
+		{0x1fc8, 0x1fcc, 1},
+		{0x1fd8, 0x1fdb, 1},
+		{0x1fe8, 0x1fec, 1},
+		{0x1ff8, 0x1ffc, 1},
+		{0x2126, 0x212a, 4},
+		{0x212b, 0x2132, 7},
+		{0x2183, 0x2c00, 2685},
+		{0x2c01, 0x2c2e, 1},
+		{0x2c60, 0x2c62, 2},
+		{0x2c63, 0x2c64, 1},
+		{0x2c67, 0x2c6d, 2},
+		{0x2c6e, 0x2c70, 1},
+		{0x2c72, 0x2c75, 3},
+		{0x2c7e, 0x2c80, 1},
+		{0x2c82, 0x2ce2, 2},
+		{0x2ceb, 0x2ced, 2},
+		{0x2cf2, 0xa640, 31054},
+		{0xa642, 0xa66c, 2},
+		{0xa680, 0xa69a, 2},
+		{0xa722, 0xa72e, 2},
+		{0xa732, 0xa76e, 2},
+		{0xa779, 0xa77d, 2},
+		{0xa77e, 0xa786, 2},
+		{0xa78b, 0xa78d, 2},
+		{0xa790, 0xa792, 2},
+		{0xa796, 0xa7aa, 2},
+		{0xa7ab, 0xa7ad, 1},
+		{0xa7b0, 0xa7b1, 1},
+		{0xff21, 0xff3a, 1},
+	},
+	R32: []Range32{
+		{0x10400, 0x10427, 1},
+		{0x118a0, 0x118bf, 1},
+	},
+	LatinOffset: 3,
+}
+
+var foldLt = &RangeTable{
+	R16: []Range16{
+		{0x01c4, 0x01c6, 2},
+		{0x01c7, 0x01c9, 2},
+		{0x01ca, 0x01cc, 2},
+		{0x01f1, 0x01f3, 2},
+		{0x1f80, 0x1f87, 1},
+		{0x1f90, 0x1f97, 1},
+		{0x1fa0, 0x1fa7, 1},
+		{0x1fb3, 0x1fc3, 16},
+		{0x1ff3, 0x1ff3, 1},
+	},
+}
+
+var foldLu = &RangeTable{
+	R16: []Range16{
+		{0x0061, 0x007a, 1},
+		{0x00b5, 0x00df, 42},
+		{0x00e0, 0x00f6, 1},
+		{0x00f8, 0x00ff, 1},
+		{0x0101, 0x012f, 2},
+		{0x0133, 0x0137, 2},
+		{0x013a, 0x0148, 2},
+		{0x014b, 0x0177, 2},
+		{0x017a, 0x017e, 2},
+		{0x017f, 0x0180, 1},
+		{0x0183, 0x0185, 2},
+		{0x0188, 0x018c, 4},
+		{0x0192, 0x0195, 3},
+		{0x0199, 0x019a, 1},
+		{0x019e, 0x01a1, 3},
+		{0x01a3, 0x01a5, 2},
+		{0x01a8, 0x01ad, 5},
+		{0x01b0, 0x01b4, 4},
+		{0x01b6, 0x01b9, 3},
+		{0x01bd, 0x01bf, 2},
+		{0x01c5, 0x01c6, 1},
+		{0x01c8, 0x01c9, 1},
+		{0x01cb, 0x01cc, 1},
+		{0x01ce, 0x01dc, 2},
+		{0x01dd, 0x01ef, 2},
+		{0x01f2, 0x01f3, 1},
+		{0x01f5, 0x01f9, 4},
+		{0x01fb, 0x021f, 2},
+		{0x0223, 0x0233, 2},
+		{0x023c, 0x023f, 3},
+		{0x0240, 0x0242, 2},
+		{0x0247, 0x024f, 2},
+		{0x0250, 0x0254, 1},
+		{0x0256, 0x0257, 1},
+		{0x0259, 0x025b, 2},
+		{0x025c, 0x0260, 4},
+		{0x0261, 0x0265, 2},
+		{0x0266, 0x0268, 2},
+		{0x0269, 0x026b, 2},
+		{0x026c, 0x026f, 3},
+		{0x0271, 0x0272, 1},
+		{0x0275, 0x027d, 8},
+		{0x0280, 0x0283, 3},
+		{0x0287, 0x028c, 1},
+		{0x0292, 0x029e, 12},
+		{0x0345, 0x0371, 44},
+		{0x0373, 0x037b, 4},
+		{0x037c, 0x037d, 1},
+		{0x03ac, 0x03af, 1},
+		{0x03b1, 0x03ce, 1},
+		{0x03d0, 0x03d1, 1},
+		{0x03d5, 0x03d7, 1},
+		{0x03d9, 0x03ef, 2},
+		{0x03f0, 0x03f3, 1},
+		{0x03f5, 0x03fb, 3},
+		{0x0430, 0x045f, 1},
+		{0x0461, 0x0481, 2},
+		{0x048b, 0x04bf, 2},
+		{0x04c2, 0x04ce, 2},
+		{0x04cf, 0x052f, 2},
+		{0x0561, 0x0586, 1},
+		{0x1d79, 0x1d7d, 4},
+		{0x1e01, 0x1e95, 2},
+		{0x1e9b, 0x1ea1, 6},
+		{0x1ea3, 0x1eff, 2},
+		{0x1f00, 0x1f07, 1},
+		{0x1f10, 0x1f15, 1},
+		{0x1f20, 0x1f27, 1},
+		{0x1f30, 0x1f37, 1},
+		{0x1f40, 0x1f45, 1},
+		{0x1f51, 0x1f57, 2},
+		{0x1f60, 0x1f67, 1},
+		{0x1f70, 0x1f7d, 1},
+		{0x1fb0, 0x1fb1, 1},
+		{0x1fbe, 0x1fd0, 18},
+		{0x1fd1, 0x1fe0, 15},
+		{0x1fe1, 0x1fe5, 4},
+		{0x214e, 0x2184, 54},
+		{0x2c30, 0x2c5e, 1},
+		{0x2c61, 0x2c65, 4},
+		{0x2c66, 0x2c6c, 2},
+		{0x2c73, 0x2c76, 3},
+		{0x2c81, 0x2ce3, 2},
+		{0x2cec, 0x2cee, 2},
+		{0x2cf3, 0x2d00, 13},
+		{0x2d01, 0x2d25, 1},
+		{0x2d27, 0x2d2d, 6},
+		{0xa641, 0xa66d, 2},
+		{0xa681, 0xa69b, 2},
+		{0xa723, 0xa72f, 2},
+		{0xa733, 0xa76f, 2},
+		{0xa77a, 0xa77c, 2},
+		{0xa77f, 0xa787, 2},
+		{0xa78c, 0xa791, 5},
+		{0xa793, 0xa797, 4},
+		{0xa799, 0xa7a9, 2},
+		{0xff41, 0xff5a, 1},
+	},
+	R32: []Range32{
+		{0x10428, 0x1044f, 1},
+		{0x118c0, 0x118df, 1},
+	},
+	LatinOffset: 4,
+}
+
+var foldM = &RangeTable{
+	R16: []Range16{
+		{0x0399, 0x03b9, 32},
+		{0x1fbe, 0x1fbe, 1},
+	},
+}
+
+var foldMn = &RangeTable{
+	R16: []Range16{
+		{0x0399, 0x03b9, 32},
+		{0x1fbe, 0x1fbe, 1},
+	},
+}
+
+// FoldScript maps a script name to a table of
+// code points outside the script that are equivalent under
+// simple case folding to code points inside the script.
+// If there is no entry for a script name, there are no such points.
+var FoldScript = map[string]*RangeTable{}
+
+// Range entries: 3532 16-bit, 1204 32-bit, 4736 total.
+// Range bytes: 21192 16-bit, 14448 32-bit, 35640 total.
+
+// Fold orbit bytes: 63 pairs, 252 bytes
diff --git a/src/pkg/unicode/utf16/export_test.go b/src/unicode/utf16/export_test.go
similarity index 100%
rename from src/pkg/unicode/utf16/export_test.go
rename to src/unicode/utf16/export_test.go
diff --git a/src/pkg/unicode/utf16/utf16.go b/src/unicode/utf16/utf16.go
similarity index 100%
rename from src/pkg/unicode/utf16/utf16.go
rename to src/unicode/utf16/utf16.go
diff --git a/src/pkg/unicode/utf16/utf16_test.go b/src/unicode/utf16/utf16_test.go
similarity index 100%
rename from src/pkg/unicode/utf16/utf16_test.go
rename to src/unicode/utf16/utf16_test.go
diff --git a/src/pkg/unicode/utf8/example_test.go b/src/unicode/utf8/example_test.go
similarity index 100%
rename from src/pkg/unicode/utf8/example_test.go
rename to src/unicode/utf8/example_test.go
diff --git a/src/unicode/utf8/utf8.go b/src/unicode/utf8/utf8.go
new file mode 100644
index 0000000..9ac3718
--- /dev/null
+++ b/src/unicode/utf8/utf8.go
@@ -0,0 +1,445 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package utf8 implements functions and constants to support text encoded in
+// UTF-8. It includes functions to translate between runes and UTF-8 byte sequences.
+package utf8
+
+// The conditions RuneError==unicode.ReplacementChar and
+// MaxRune==unicode.MaxRune are verified in the tests.
+// Defining them locally avoids this package depending on package unicode.
+
+// Numbers fundamental to the encoding.
+const (
+	RuneError = '\uFFFD'     // the "error" Rune or "Unicode replacement character"
+	RuneSelf  = 0x80         // characters below Runeself are represented as themselves in a single byte.
+	MaxRune   = '\U0010FFFF' // Maximum valid Unicode code point.
+	UTFMax    = 4            // maximum number of bytes of a UTF-8 encoded Unicode character.
+)
+
+// Code points in the surrogate range are not valid for UTF-8.
+const (
+	surrogateMin = 0xD800
+	surrogateMax = 0xDFFF
+)
+
+const (
+	t1 = 0x00 // 0000 0000
+	tx = 0x80 // 1000 0000
+	t2 = 0xC0 // 1100 0000
+	t3 = 0xE0 // 1110 0000
+	t4 = 0xF0 // 1111 0000
+	t5 = 0xF8 // 1111 1000
+
+	maskx = 0x3F // 0011 1111
+	mask2 = 0x1F // 0001 1111
+	mask3 = 0x0F // 0000 1111
+	mask4 = 0x07 // 0000 0111
+
+	rune1Max = 1<<7 - 1
+	rune2Max = 1<<11 - 1
+	rune3Max = 1<<16 - 1
+)
+
+func decodeRuneInternal(p []byte) (r rune, size int, short bool) {
+	n := len(p)
+	if n < 1 {
+		return RuneError, 0, true
+	}
+	c0 := p[0]
+
+	// 1-byte, 7-bit sequence?
+	if c0 < tx {
+		return rune(c0), 1, false
+	}
+
+	// unexpected continuation byte?
+	if c0 < t2 {
+		return RuneError, 1, false
+	}
+
+	// need first continuation byte
+	if n < 2 {
+		return RuneError, 1, true
+	}
+	c1 := p[1]
+	if c1 < tx || t2 <= c1 {
+		return RuneError, 1, false
+	}
+
+	// 2-byte, 11-bit sequence?
+	if c0 < t3 {
+		r = rune(c0&mask2)<<6 | rune(c1&maskx)
+		if r <= rune1Max {
+			return RuneError, 1, false
+		}
+		return r, 2, false
+	}
+
+	// need second continuation byte
+	if n < 3 {
+		return RuneError, 1, true
+	}
+	c2 := p[2]
+	if c2 < tx || t2 <= c2 {
+		return RuneError, 1, false
+	}
+
+	// 3-byte, 16-bit sequence?
+	if c0 < t4 {
+		r = rune(c0&mask3)<<12 | rune(c1&maskx)<<6 | rune(c2&maskx)
+		if r <= rune2Max {
+			return RuneError, 1, false
+		}
+		if surrogateMin <= r && r <= surrogateMax {
+			return RuneError, 1, false
+		}
+		return r, 3, false
+	}
+
+	// need third continuation byte
+	if n < 4 {
+		return RuneError, 1, true
+	}
+	c3 := p[3]
+	if c3 < tx || t2 <= c3 {
+		return RuneError, 1, false
+	}
+
+	// 4-byte, 21-bit sequence?
+	if c0 < t5 {
+		r = rune(c0&mask4)<<18 | rune(c1&maskx)<<12 | rune(c2&maskx)<<6 | rune(c3&maskx)
+		if r <= rune3Max || MaxRune < r {
+			return RuneError, 1, false
+		}
+		return r, 4, false
+	}
+
+	// error
+	return RuneError, 1, false
+}
+
+func decodeRuneInStringInternal(s string) (r rune, size int, short bool) {
+	n := len(s)
+	if n < 1 {
+		return RuneError, 0, true
+	}
+	c0 := s[0]
+
+	// 1-byte, 7-bit sequence?
+	if c0 < tx {
+		return rune(c0), 1, false
+	}
+
+	// unexpected continuation byte?
+	if c0 < t2 {
+		return RuneError, 1, false
+	}
+
+	// need first continuation byte
+	if n < 2 {
+		return RuneError, 1, true
+	}
+	c1 := s[1]
+	if c1 < tx || t2 <= c1 {
+		return RuneError, 1, false
+	}
+
+	// 2-byte, 11-bit sequence?
+	if c0 < t3 {
+		r = rune(c0&mask2)<<6 | rune(c1&maskx)
+		if r <= rune1Max {
+			return RuneError, 1, false
+		}
+		return r, 2, false
+	}
+
+	// need second continuation byte
+	if n < 3 {
+		return RuneError, 1, true
+	}
+	c2 := s[2]
+	if c2 < tx || t2 <= c2 {
+		return RuneError, 1, false
+	}
+
+	// 3-byte, 16-bit sequence?
+	if c0 < t4 {
+		r = rune(c0&mask3)<<12 | rune(c1&maskx)<<6 | rune(c2&maskx)
+		if r <= rune2Max {
+			return RuneError, 1, false
+		}
+		if surrogateMin <= r && r <= surrogateMax {
+			return RuneError, 1, false
+		}
+		return r, 3, false
+	}
+
+	// need third continuation byte
+	if n < 4 {
+		return RuneError, 1, true
+	}
+	c3 := s[3]
+	if c3 < tx || t2 <= c3 {
+		return RuneError, 1, false
+	}
+
+	// 4-byte, 21-bit sequence?
+	if c0 < t5 {
+		r = rune(c0&mask4)<<18 | rune(c1&maskx)<<12 | rune(c2&maskx)<<6 | rune(c3&maskx)
+		if r <= rune3Max || MaxRune < r {
+			return RuneError, 1, false
+		}
+		return r, 4, false
+	}
+
+	// error
+	return RuneError, 1, false
+}
+
+// FullRune reports whether the bytes in p begin with a full UTF-8 encoding of a rune.
+// An invalid encoding is considered a full Rune since it will convert as a width-1 error rune.
+func FullRune(p []byte) bool {
+	_, _, short := decodeRuneInternal(p)
+	return !short
+}
+
+// FullRuneInString is like FullRune but its input is a string.
+func FullRuneInString(s string) bool {
+	_, _, short := decodeRuneInStringInternal(s)
+	return !short
+}
+
+// DecodeRune unpacks the first UTF-8 encoding in p and returns the rune and
+// its width in bytes. If p is empty it returns (RuneError, 0). Otherwise, if
+// the encoding is invalid, it returns (RuneError, 1). Both are impossible
+// results for correct UTF-8.
+//
+// An encoding is invalid if it is incorrect UTF-8, encodes a rune that is
+// out of range, or is not the shortest possible UTF-8 encoding for the
+// value. No other validation is performed.
+func DecodeRune(p []byte) (r rune, size int) {
+	r, size, _ = decodeRuneInternal(p)
+	return
+}
+
+// DecodeRuneInString is like DecodeRune but its input is a string. If s is
+// empty it returns (RuneError, 0). Otherwise, if the encoding is invalid, it
+// returns (RuneError, 1). Both are impossible results for correct UTF-8.
+//
+// An encoding is invalid if it is incorrect UTF-8, encodes a rune that is
+// out of range, or is not the shortest possible UTF-8 encoding for the
+// value. No other validation is performed.
+func DecodeRuneInString(s string) (r rune, size int) {
+	r, size, _ = decodeRuneInStringInternal(s)
+	return
+}
+
+// DecodeLastRune unpacks the last UTF-8 encoding in p and returns the rune and
+// its width in bytes. If p is empty it returns (RuneError, 0). Otherwise, if
+// the encoding is invalid, it returns (RuneError, 1). Both are impossible
+// results for correct UTF-8.
+//
+// An encoding is invalid if it is incorrect UTF-8, encodes a rune that is
+// out of range, or is not the shortest possible UTF-8 encoding for the
+// value. No other validation is performed.
+func DecodeLastRune(p []byte) (r rune, size int) {
+	end := len(p)
+	if end == 0 {
+		return RuneError, 0
+	}
+	start := end - 1
+	r = rune(p[start])
+	if r < RuneSelf {
+		return r, 1
+	}
+	// guard against O(n^2) behavior when traversing
+	// backwards through strings with long sequences of
+	// invalid UTF-8.
+	lim := end - UTFMax
+	if lim < 0 {
+		lim = 0
+	}
+	for start--; start >= lim; start-- {
+		if RuneStart(p[start]) {
+			break
+		}
+	}
+	if start < 0 {
+		start = 0
+	}
+	r, size = DecodeRune(p[start:end])
+	if start+size != end {
+		return RuneError, 1
+	}
+	return r, size
+}
+
+// DecodeLastRuneInString is like DecodeLastRune but its input is a string. If
+// s is empty it returns (RuneError, 0). Otherwise, if the encoding is invalid,
+// it returns (RuneError, 1). Both are impossible results for correct UTF-8.
+//
+// An encoding is invalid if it is incorrect UTF-8, encodes a rune that is
+// out of range, or is not the shortest possible UTF-8 encoding for the
+// value. No other validation is performed.
+func DecodeLastRuneInString(s string) (r rune, size int) {
+	end := len(s)
+	if end == 0 {
+		return RuneError, 0
+	}
+	start := end - 1
+	r = rune(s[start])
+	if r < RuneSelf {
+		return r, 1
+	}
+	// guard against O(n^2) behavior when traversing
+	// backwards through strings with long sequences of
+	// invalid UTF-8.
+	lim := end - UTFMax
+	if lim < 0 {
+		lim = 0
+	}
+	for start--; start >= lim; start-- {
+		if RuneStart(s[start]) {
+			break
+		}
+	}
+	if start < 0 {
+		start = 0
+	}
+	r, size = DecodeRuneInString(s[start:end])
+	if start+size != end {
+		return RuneError, 1
+	}
+	return r, size
+}
+
+// RuneLen returns the number of bytes required to encode the rune.
+// It returns -1 if the rune is not a valid value to encode in UTF-8.
+func RuneLen(r rune) int {
+	switch {
+	case r < 0:
+		return -1
+	case r <= rune1Max:
+		return 1
+	case r <= rune2Max:
+		return 2
+	case surrogateMin <= r && r <= surrogateMax:
+		return -1
+	case r <= rune3Max:
+		return 3
+	case r <= MaxRune:
+		return 4
+	}
+	return -1
+}
+
+// EncodeRune writes into p (which must be large enough) the UTF-8 encoding of the rune.
+// It returns the number of bytes written.
+func EncodeRune(p []byte, r rune) int {
+	// Negative values are erroneous.  Making it unsigned addresses the problem.
+	switch i := uint32(r); {
+	case i <= rune1Max:
+		p[0] = byte(r)
+		return 1
+	case i <= rune2Max:
+		p[0] = t2 | byte(r>>6)
+		p[1] = tx | byte(r)&maskx
+		return 2
+	case i > MaxRune, surrogateMin <= i && i <= surrogateMax:
+		r = RuneError
+		fallthrough
+	case i <= rune3Max:
+		p[0] = t3 | byte(r>>12)
+		p[1] = tx | byte(r>>6)&maskx
+		p[2] = tx | byte(r)&maskx
+		return 3
+	default:
+		p[0] = t4 | byte(r>>18)
+		p[1] = tx | byte(r>>12)&maskx
+		p[2] = tx | byte(r>>6)&maskx
+		p[3] = tx | byte(r)&maskx
+		return 4
+	}
+}
+
+// RuneCount returns the number of runes in p.  Erroneous and short
+// encodings are treated as single runes of width 1 byte.
+func RuneCount(p []byte) int {
+	i := 0
+	var n int
+	for n = 0; i < len(p); n++ {
+		if p[i] < RuneSelf {
+			i++
+		} else {
+			_, size := DecodeRune(p[i:])
+			i += size
+		}
+	}
+	return n
+}
+
+// RuneCountInString is like RuneCount but its input is a string.
+func RuneCountInString(s string) (n int) {
+	for range s {
+		n++
+	}
+	return
+}
+
+// RuneStart reports whether the byte could be the first byte of
+// an encoded rune.  Second and subsequent bytes always have the top
+// two bits set to 10.
+func RuneStart(b byte) bool { return b&0xC0 != 0x80 }
+
+// Valid reports whether p consists entirely of valid UTF-8-encoded runes.
+func Valid(p []byte) bool {
+	i := 0
+	for i < len(p) {
+		if p[i] < RuneSelf {
+			i++
+		} else {
+			_, size := DecodeRune(p[i:])
+			if size == 1 {
+				// All valid runes of size 1 (those
+				// below RuneSelf) were handled above.
+				// This must be a RuneError.
+				return false
+			}
+			i += size
+		}
+	}
+	return true
+}
+
+// ValidString reports whether s consists entirely of valid UTF-8-encoded runes.
+func ValidString(s string) bool {
+	for i, r := range s {
+		if r == RuneError {
+			// The RuneError value can be an error
+			// sentinel value (if it's size 1) or the same
+			// value encoded properly. Decode it to see if
+			// it's the 1 byte sentinel value.
+			_, size := DecodeRuneInString(s[i:])
+			if size == 1 {
+				return false
+			}
+		}
+	}
+	return true
+}
+
+// ValidRune reports whether r can be legally encoded as UTF-8.
+// Code points that are out of range or a surrogate half are illegal.
+func ValidRune(r rune) bool {
+	switch {
+	case r < 0:
+		return false
+	case surrogateMin <= r && r <= surrogateMax:
+		return false
+	case r > MaxRune:
+		return false
+	}
+	return true
+}
diff --git a/src/pkg/unicode/utf8/utf8_test.go b/src/unicode/utf8/utf8_test.go
similarity index 100%
rename from src/pkg/unicode/utf8/utf8_test.go
rename to src/unicode/utf8/utf8_test.go
diff --git a/src/unsafe/unsafe.go b/src/unsafe/unsafe.go
new file mode 100644
index 0000000..79499b2
--- /dev/null
+++ b/src/unsafe/unsafe.go
@@ -0,0 +1,40 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+/*
+	Package unsafe contains operations that step around the type safety of Go programs.
+
+	Packages that import unsafe may be non-portable and are not protected by the
+	Go 1 compatibility guidelines.
+*/
+package unsafe
+
+// ArbitraryType is here for the purposes of documentation only and is not actually
+// part of the unsafe package.  It represents the type of an arbitrary Go expression.
+type ArbitraryType int
+
+// Pointer represents a pointer to an arbitrary type.  There are four special operations
+// available for type Pointer that are not available for other types.
+//	1) A pointer value of any type can be converted to a Pointer.
+//	2) A Pointer can be converted to a pointer value of any type.
+//	3) A uintptr can be converted to a Pointer.
+//	4) A Pointer can be converted to a uintptr.
+// Pointer therefore allows a program to defeat the type system and read and write
+// arbitrary memory. It should be used with extreme care.
+type Pointer *ArbitraryType
+
+// Sizeof returns the size in bytes occupied by the value v.  The size is that of the
+// "top level" of the value only.  For instance, if v is a slice, it returns the size of
+// the slice descriptor, not the size of the memory referenced by the slice.
+func Sizeof(v ArbitraryType) uintptr
+
+// Offsetof returns the offset within the struct of the field represented by v,
+// which must be of the form structValue.field.  In other words, it returns the
+// number of bytes between the start of the struct and the start of the field.
+func Offsetof(v ArbitraryType) uintptr
+
+// Alignof returns the alignment of the value v.  It is the maximum value m such
+// that the address of a variable with the type of v will always be zero mod m.
+// If v is of the form structValue.field, it returns the alignment of field f within struct object obj.
+func Alignof(v ArbitraryType) uintptr
diff --git a/test/assign.go b/test/assign.go
index da0192f..6611f8c 100644
--- a/test/assign.go
+++ b/test/assign.go
@@ -53,4 +53,16 @@ func main() {
 		_ = x
 		_ = y
 	}
+	{
+		var x = 1
+		{
+			x, x := 2, 3 // ERROR "x repeated on left side of :="
+			_ = x
+		}
+		_ = x
+	}
+	{
+		a, a := 1, 2 // ERROR "a repeated on left side of :="
+		_ = a
+	}
 }
diff --git a/test/bench/garbage/parser.go b/test/bench/garbage/parser.go
index d85110b..a685507 100644
--- a/test/bench/garbage/parser.go
+++ b/test/bench/garbage/parser.go
@@ -85,7 +85,7 @@ func main() {
 	var t0 time.Time
 	var numGC uint32
 	var pauseTotalNs uint64
-	pkgroot := runtime.GOROOT() + "/src/pkg/"
+	pkgroot := runtime.GOROOT() + "/src/"
 	for pass := 0; pass < 2; pass++ {
 		// Once the heap is grown to full size, reset counters.
 		// This hides the start-up pauses, which are much smaller
diff --git a/test/bench/shootout/chameneosredux.go b/test/bench/shootout/chameneosredux.go
index 3395798..72ce7dd 100644
--- a/test/bench/shootout/chameneosredux.go
+++ b/test/bench/shootout/chameneosredux.go
@@ -123,7 +123,7 @@ func pallmall(cols []int) {
 	fmt.Println(msg)
 	tot := 0
 	// wait for all results
-	for _ = range cols {
+	for range cols {
 		result := <-ended
 		tot += result.met
 		fmt.Printf("%v%v\n", result.met, spell(result.same, true))
diff --git a/test/chan/perm.go b/test/chan/perm.go
index 7e152c5..919fa30 100644
--- a/test/chan/perm.go
+++ b/test/chan/perm.go
@@ -56,6 +56,9 @@ func main() {
 	for _ = range cs {// ERROR "receive"
 	}
 
+	for range cs {// ERROR "receive"
+	}
+
 	close(c)
 	close(cs)
 	close(cr)  // ERROR "receive"
diff --git a/test/chan/select5.go b/test/chan/select5.go
index f72cfe4..1081cb2 100644
--- a/test/chan/select5.go
+++ b/test/chan/select5.go
@@ -27,16 +27,16 @@ func main() {
 	fmt.Fprintln(out, header)
 	a := new(arg)
 
-	// Generate each kind of test as a separate function to avoid
+	// Generate each test as a separate function to avoid
 	// hitting the 6g optimizer with one enormous function.
 	// If we name all the functions init we don't have to
 	// maintain a list of which ones to run.
 	do := func(t *template.Template) {
-		fmt.Fprintln(out, `func init() {`)
 		for ; next(); a.reset() {
+			fmt.Fprintln(out, `func init() {`)
 			run(t, a, out)
+			fmt.Fprintln(out, `}`)
 		}
-		fmt.Fprintln(out, `}`)
 	}
 
 	do(recv)
diff --git a/test/escape2.go b/test/escape2.go
index 28251aa..6a46ce8 100644
--- a/test/escape2.go
+++ b/test/escape2.go
@@ -7,6 +7,8 @@
 // Test, using compiler diagnostic flags, that the escape analysis is working.
 // Compiles but does not run.  Inlining is disabled.
 
+// escape2n.go contains all the same tests but compiles with -N.
+
 package foo
 
 import (
diff --git a/test/escape2n.go b/test/escape2n.go
new file mode 100644
index 0000000..002a78e
--- /dev/null
+++ b/test/escape2n.go
@@ -0,0 +1,1494 @@
+// errorcheck -0 -N -m -l
+
+// Copyright 2010 The Go 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, using compiler diagnostic flags, that the escape analysis is working.
+// Compiles but does not run.  Inlining is disabled.
+// Registerization is disabled too (-N), which should
+// have no effect on escape analysis.
+
+package foo
+
+import (
+	"fmt"
+	"unsafe"
+)
+
+var gxx *int
+
+func foo1(x int) { // ERROR "moved to heap: x"
+	gxx = &x // ERROR "&x escapes to heap"
+}
+
+func foo2(yy *int) { // ERROR "leaking param: yy"
+	gxx = yy
+}
+
+func foo3(x int) *int { // ERROR "moved to heap: x"
+	return &x // ERROR "&x escapes to heap"
+}
+
+type T *T
+
+func foo3b(t T) { // ERROR "leaking param: t"
+	*t = t
+}
+
+// xx isn't going anywhere, so use of yy is ok
+func foo4(xx, yy *int) { // ERROR "xx does not escape" "yy does not escape"
+	xx = yy
+}
+
+// xx isn't going anywhere, so taking address of yy is ok
+func foo5(xx **int, yy *int) { // ERROR "xx does not escape" "yy does not escape"
+	xx = &yy // ERROR "&yy does not escape"
+}
+
+func foo6(xx **int, yy *int) { // ERROR "xx does not escape" "leaking param: yy"
+	*xx = yy
+}
+
+func foo7(xx **int, yy *int) { // ERROR "xx does not escape" "yy does not escape"
+	**xx = *yy
+}
+
+func foo8(xx, yy *int) int { // ERROR "xx does not escape" "yy does not escape"
+	xx = yy
+	return *xx
+}
+
+func foo9(xx, yy *int) *int { // ERROR "leaking param: xx" "leaking param: yy"
+	xx = yy
+	return xx
+}
+
+func foo10(xx, yy *int) { // ERROR "xx does not escape" "yy does not escape"
+	*xx = *yy
+}
+
+func foo11() int {
+	x, y := 0, 42
+	xx := &x // ERROR "&x does not escape"
+	yy := &y // ERROR "&y does not escape"
+	*xx = *yy
+	return x
+}
+
+var xxx **int
+
+func foo12(yyy **int) { // ERROR "leaking param: yyy"
+	xxx = yyy
+}
+
+// Must treat yyy as leaking because *yyy leaks, and the escape analysis
+// summaries in exported metadata do not distinguish these two cases.
+func foo13(yyy **int) { // ERROR "leaking param: yyy"
+	*xxx = *yyy
+}
+
+func foo14(yyy **int) { // ERROR "yyy does not escape"
+	**xxx = **yyy
+}
+
+func foo15(yy *int) { // ERROR "moved to heap: yy"
+	xxx = &yy // ERROR "&yy escapes to heap"
+}
+
+func foo16(yy *int) { // ERROR "leaking param: yy"
+	*xxx = yy
+}
+
+func foo17(yy *int) { // ERROR "yy does not escape"
+	**xxx = *yy
+}
+
+func foo18(y int) { // ERROR "moved to heap: "y"
+	*xxx = &y // ERROR "&y escapes to heap"
+}
+
+func foo19(y int) {
+	**xxx = y
+}
+
+type Bar struct {
+	i  int
+	ii *int
+}
+
+func NewBar() *Bar {
+	return &Bar{42, nil} // ERROR "&Bar literal escapes to heap"
+}
+
+func NewBarp(x *int) *Bar { // ERROR "leaking param: x"
+	return &Bar{42, x} // ERROR "&Bar literal escapes to heap"
+}
+
+func NewBarp2(x *int) *Bar { // ERROR "x does not escape"
+	return &Bar{*x, nil} // ERROR "&Bar literal escapes to heap"
+}
+
+func (b *Bar) NoLeak() int { // ERROR "b does not escape"
+	return *(b.ii)
+}
+
+func (b *Bar) Leak() *int { // ERROR "leaking param: b"
+	return &b.i // ERROR "&b.i escapes to heap"
+}
+
+func (b *Bar) AlsoNoLeak() *int { // ERROR "leaking param b content to result ~r0"
+	return b.ii
+}
+
+func (b Bar) AlsoLeak() *int { // ERROR "leaking param: b"
+	return b.ii
+}
+
+func (b Bar) LeaksToo() *int { // ERROR "leaking param: b"
+	v := 0    // ERROR "moved to heap: v"
+	b.ii = &v // ERROR "&v escapes"
+	return b.ii
+}
+
+func (b *Bar) LeaksABit() *int { // ERROR "leaking param b content to result ~r0"
+	v := 0    // ERROR "moved to heap: v"
+	b.ii = &v // ERROR "&v escapes"
+	return b.ii
+}
+
+func (b Bar) StillNoLeak() int { // ERROR "b does not escape"
+	v := 0
+	b.ii = &v // ERROR "&v does not escape"
+	return b.i
+}
+
+func goLeak(b *Bar) { // ERROR "leaking param: b"
+	go b.NoLeak()
+}
+
+type Bar2 struct {
+	i  [12]int
+	ii []int
+}
+
+func NewBar2() *Bar2 {
+	return &Bar2{[12]int{42}, nil} // ERROR "&Bar2 literal escapes to heap"
+}
+
+func (b *Bar2) NoLeak() int { // ERROR "b does not escape"
+	return b.i[0]
+}
+
+func (b *Bar2) Leak() []int { // ERROR "leaking param: b"
+	return b.i[:] // ERROR "b.i escapes to heap"
+}
+
+func (b *Bar2) AlsoNoLeak() []int { // ERROR "leaking param b content to result ~r0"
+	return b.ii[0:1]
+}
+
+func (b Bar2) AgainNoLeak() [12]int { // ERROR "b does not escape"
+	return b.i
+}
+
+func (b *Bar2) LeakSelf() { // ERROR "leaking param: b"
+	b.ii = b.i[0:4] // ERROR "b.i escapes to heap"
+}
+
+func (b *Bar2) LeakSelf2() { // ERROR "leaking param: b"
+	var buf []int
+	buf = b.i[0:] // ERROR "b.i escapes to heap"
+	b.ii = buf
+}
+
+func foo21() func() int {
+	x := 42             // ERROR "moved to heap: x"
+	return func() int { // ERROR "func literal escapes to heap"
+		return x // ERROR "&x escapes to heap"
+	}
+}
+
+func foo22() int {
+	x := 42
+	return func() int { // ERROR "func literal does not escape"
+		return x
+	}()
+}
+
+func foo23(x int) func() int { // ERROR "moved to heap: x"
+	return func() int { // ERROR "func literal escapes to heap"
+		return x // ERROR "&x escapes to heap"
+	}
+}
+
+func foo23a(x int) func() int { // ERROR "moved to heap: x"
+	f := func() int { // ERROR "func literal escapes to heap"
+		return x // ERROR "&x escapes to heap"
+	}
+	return f
+}
+
+func foo23b(x int) *(func() int) { // ERROR "moved to heap: x"
+	f := func() int { return x } // ERROR "moved to heap: f" "func literal escapes to heap" "&x escapes to heap"
+	return &f                    // ERROR "&f escapes to heap"
+}
+
+func foo24(x int) int {
+	return func() int { // ERROR "func literal does not escape"
+		return x
+	}()
+}
+
+var x *int
+
+func fooleak(xx *int) int { // ERROR "leaking param: xx"
+	x = xx
+	return *x
+}
+
+func foonoleak(xx *int) int { // ERROR "xx does not escape"
+	return *x + *xx
+}
+
+func foo31(x int) int { // ERROR "moved to heap: x"
+	return fooleak(&x) // ERROR "&x escapes to heap"
+}
+
+func foo32(x int) int {
+	return foonoleak(&x) // ERROR "&x does not escape"
+}
+
+type Foo struct {
+	xx *int
+	x  int
+}
+
+var F Foo
+var pf *Foo
+
+func (f *Foo) fooleak() { // ERROR "leaking param: f"
+	pf = f
+}
+
+func (f *Foo) foonoleak() { // ERROR "f does not escape"
+	F.x = f.x
+}
+
+func (f *Foo) Leak() { // ERROR "leaking param: f"
+	f.fooleak()
+}
+
+func (f *Foo) NoLeak() { // ERROR "f does not escape"
+	f.foonoleak()
+}
+
+func foo41(x int) { // ERROR "moved to heap: x"
+	F.xx = &x // ERROR "&x escapes to heap"
+}
+
+func (f *Foo) foo42(x int) { // ERROR "f does not escape" "moved to heap: x"
+	f.xx = &x // ERROR "&x escapes to heap"
+}
+
+func foo43(f *Foo, x int) { // ERROR "f does not escape" "moved to heap: x"
+	f.xx = &x // ERROR "&x escapes to heap"
+}
+
+func foo44(yy *int) { // ERROR "leaking param: yy"
+	F.xx = yy
+}
+
+func (f *Foo) foo45() { // ERROR "f does not escape"
+	F.x = f.x
+}
+
+// See foo13 above for explanation of why f leaks.
+func (f *Foo) foo46() { // ERROR "leaking param: f"
+	F.xx = f.xx
+}
+
+func (f *Foo) foo47() { // ERROR "leaking param: f"
+	f.xx = &f.x // ERROR "&f.x escapes to heap"
+}
+
+var ptrSlice []*int
+
+func foo50(i *int) { // ERROR "leaking param: i"
+	ptrSlice[0] = i
+}
+
+var ptrMap map[*int]*int
+
+func foo51(i *int) { // ERROR "leaking param: i"
+	ptrMap[i] = i
+}
+
+func indaddr1(x int) *int { // ERROR "moved to heap: x"
+	return &x // ERROR "&x escapes to heap"
+}
+
+func indaddr2(x *int) *int { // ERROR "leaking param: x"
+	return *&x // ERROR "&x does not escape"
+}
+
+func indaddr3(x *int32) *int { // ERROR "leaking param: x"
+	return *(**int)(unsafe.Pointer(&x)) // ERROR "&x does not escape"
+}
+
+// From package math:
+
+func Float32bits(f float32) uint32 {
+	return *(*uint32)(unsafe.Pointer(&f)) // ERROR "&f does not escape"
+}
+
+func Float32frombits(b uint32) float32 {
+	return *(*float32)(unsafe.Pointer(&b)) // ERROR "&b does not escape"
+}
+
+func Float64bits(f float64) uint64 {
+	return *(*uint64)(unsafe.Pointer(&f)) // ERROR "&f does not escape"
+}
+
+func Float64frombits(b uint64) float64 {
+	return *(*float64)(unsafe.Pointer(&b)) // ERROR "&b does not escape"
+}
+
+// contrast with
+func float64bitsptr(f float64) *uint64 { // ERROR "moved to heap: f"
+	return (*uint64)(unsafe.Pointer(&f)) // ERROR "&f escapes to heap"
+}
+
+func float64ptrbitsptr(f *float64) *uint64 { // ERROR "leaking param: f"
+	return (*uint64)(unsafe.Pointer(f))
+}
+
+func typesw(i interface{}) *int { // ERROR "leaking param: i"
+	switch val := i.(type) {
+	case *int:
+		return val
+	case *int8:
+		v := int(*val) // ERROR "moved to heap: v"
+		return &v      // ERROR "&v escapes to heap"
+	}
+	return nil
+}
+
+func exprsw(i *int) *int { // ERROR "leaking param: i"
+	switch j := i; *j + 110 {
+	case 12:
+		return j
+	case 42:
+		return nil
+	}
+	return nil
+
+}
+
+// assigning to an array element is like assigning to the array
+func foo60(i *int) *int { // ERROR "leaking param: i"
+	var a [12]*int
+	a[0] = i
+	return a[1]
+}
+
+func foo60a(i *int) *int { // ERROR "i does not escape"
+	var a [12]*int
+	a[0] = i
+	return nil
+}
+
+// assigning to a struct field  is like assigning to the struct
+func foo61(i *int) *int { // ERROR "leaking param: i"
+	type S struct {
+		a, b *int
+	}
+	var s S
+	s.a = i
+	return s.b
+}
+
+func foo61a(i *int) *int { // ERROR "i does not escape"
+	type S struct {
+		a, b *int
+	}
+	var s S
+	s.a = i
+	return nil
+}
+
+// assigning to a struct field is like assigning to the struct but
+// here this subtlety is lost, since s.a counts as an assignment to a
+// track-losing dereference.
+func foo62(i *int) *int { // ERROR "leaking param: i"
+	type S struct {
+		a, b *int
+	}
+	s := new(S) // ERROR "new[(]S[)] does not escape"
+	s.a = i
+	return nil // s.b
+}
+
+type M interface {
+	M()
+}
+
+func foo63(m M) { // ERROR "m does not escape"
+}
+
+func foo64(m M) { // ERROR "leaking param: m"
+	m.M()
+}
+
+func foo64b(m M) { // ERROR "leaking param: m"
+	defer m.M()
+}
+
+type MV int
+
+func (MV) M() {}
+
+func foo65() {
+	var mv MV
+	foo63(&mv) // ERROR "&mv does not escape"
+}
+
+func foo66() {
+	var mv MV  // ERROR "moved to heap: mv"
+	foo64(&mv) // ERROR "&mv escapes to heap"
+}
+
+func foo67() {
+	var mv MV
+	foo63(mv)
+}
+
+func foo68() {
+	var mv MV
+	foo64(mv) // escapes but it's an int so irrelevant
+}
+
+func foo69(m M) { // ERROR "leaking param: m"
+	foo64(m)
+}
+
+func foo70(mv1 *MV, m M) { // ERROR "leaking param: mv1" "leaking param: m"
+	m = mv1
+	foo64(m)
+}
+
+func foo71(x *int) []*int { // ERROR "leaking param: x"
+	var y []*int
+	y = append(y, x)
+	return y
+}
+
+func foo71a(x int) []*int { // ERROR "moved to heap: x"
+	var y []*int
+	y = append(y, &x) // ERROR "&x escapes to heap"
+	return y
+}
+
+func foo72() {
+	var x int
+	var y [1]*int
+	y[0] = &x // ERROR "&x does not escape"
+}
+
+func foo72aa() [10]*int {
+	var x int // ERROR "moved to heap: x"
+	var y [10]*int
+	y[0] = &x // ERROR "&x escapes to heap"
+	return y
+}
+
+func foo72a() {
+	var y [10]*int
+	for i := 0; i < 10; i++ {
+		// escapes its scope
+		x := i    // ERROR "moved to heap: x"
+		y[i] = &x // ERROR "&x escapes to heap"
+	}
+	return
+}
+
+func foo72b() [10]*int {
+	var y [10]*int
+	for i := 0; i < 10; i++ {
+		x := i    // ERROR "moved to heap: x"
+		y[i] = &x // ERROR "&x escapes to heap"
+	}
+	return y
+}
+
+// issue 2145
+func foo73() {
+	s := []int{3, 2, 1} // ERROR "\[\]int literal does not escape"
+	for _, v := range s {
+		vv := v // ERROR "moved to heap: vv"
+		// actually just escapes its scope
+		defer func() { // ERROR "func literal escapes to heap"
+			println(vv) // ERROR "&vv escapes to heap"
+		}()
+	}
+}
+
+func foo74() {
+	s := []int{3, 2, 1} // ERROR "\[\]int literal does not escape"
+	for _, v := range s {
+		vv := v // ERROR "moved to heap: vv"
+		// actually just escapes its scope
+		fn := func() { // ERROR "func literal escapes to heap"
+			println(vv) // ERROR "&vv escapes to heap"
+		}
+		defer fn()
+	}
+}
+
+// issue 3975
+func foo74b() {
+	var array [3]func()
+	s := []int{3, 2, 1} // ERROR "\[\]int literal does not escape"
+	for i, v := range s {
+		vv := v // ERROR "moved to heap: vv"
+		// actually just escapes its scope
+		array[i] = func() { // ERROR "func literal escapes to heap"
+			println(vv) // ERROR "&vv escapes to heap"
+		}
+	}
+}
+
+func myprint(y *int, x ...interface{}) *int { // ERROR "x does not escape" "leaking param: y"
+	return y
+}
+
+func myprint1(y *int, x ...interface{}) *interface{} { // ERROR "y does not escape" "leaking param: x"
+	return &x[0] // ERROR "&x.0. escapes to heap"
+}
+
+func foo75(z *int) { // ERROR "z does not escape"
+	myprint(z, 1, 2, 3) // ERROR "[.][.][.] argument does not escape"
+}
+
+func foo75a(z *int) { // ERROR "z does not escape"
+	myprint1(z, 1, 2, 3) // ERROR "[.][.][.] argument does not escape"
+}
+
+func foo75esc(z *int) { // ERROR "leaking param: z"
+	gxx = myprint(z, 1, 2, 3) // ERROR "[.][.][.] argument does not escape"
+}
+
+func foo75aesc(z *int) { // ERROR "z does not escape"
+	var ppi **interface{}       // assignments to pointer dereferences lose track
+	*ppi = myprint1(z, 1, 2, 3) // ERROR "[.][.][.] argument escapes to heap"
+}
+
+func foo76(z *int) { // ERROR "leaking param: z"
+	myprint(nil, z) // ERROR "[.][.][.] argument does not escape"
+}
+
+func foo76a(z *int) { // ERROR "leaking param: z"
+	myprint1(nil, z) // ERROR "[.][.][.] argument does not escape"
+}
+
+func foo76b() {
+	myprint(nil, 1, 2, 3) // ERROR "[.][.][.] argument does not escape"
+}
+
+func foo76c() {
+	myprint1(nil, 1, 2, 3) // ERROR "[.][.][.] argument does not escape"
+}
+
+func foo76d() {
+	defer myprint(nil, 1, 2, 3) // ERROR "[.][.][.] argument does not escape"
+}
+
+func foo76e() {
+	defer myprint1(nil, 1, 2, 3) // ERROR "[.][.][.] argument does not escape"
+}
+
+func foo76f() {
+	for {
+		// TODO: This one really only escapes its scope, but we don't distinguish yet.
+		defer myprint(nil, 1, 2, 3) // ERROR "[.][.][.] argument escapes to heap"
+	}
+}
+
+func foo76g() {
+	for {
+		defer myprint1(nil, 1, 2, 3) // ERROR "[.][.][.] argument escapes to heap"
+	}
+}
+
+func foo77(z []interface{}) { // ERROR "z does not escape"
+	myprint(nil, z...) // z does not escape
+}
+
+func foo77a(z []interface{}) { // ERROR "z does not escape"
+	myprint1(nil, z...)
+}
+
+func foo77b(z []interface{}) { // ERROR "leaking param: z"
+	var ppi **interface{}
+	*ppi = myprint1(nil, z...)
+}
+
+func foo78(z int) *int { // ERROR "moved to heap: z"
+	return &z // ERROR "&z escapes to heap"
+}
+
+func foo78a(z int) *int { // ERROR "moved to heap: z"
+	y := &z   // ERROR "&z escapes to heap"
+	x := &y   // ERROR "&y does not escape"
+	return *x // really return y
+}
+
+func foo79() *int {
+	return new(int) // ERROR "new[(]int[)] escapes to heap"
+}
+
+func foo80() *int {
+	var z *int
+	for {
+		// Really just escapes its scope but we don't distinguish
+		z = new(int) // ERROR "new[(]int[)] escapes to heap"
+	}
+	_ = z
+	return nil
+}
+
+func foo81() *int {
+	for {
+		z := new(int) // ERROR "new[(]int[)] does not escape"
+		_ = z
+	}
+	return nil
+}
+
+func tee(p *int) (x, y *int) { return p, p } // ERROR "leaking param"
+
+func noop(x, y *int) {} // ERROR "does not escape"
+
+func foo82() {
+	var x, y, z int  // ERROR "moved to heap"
+	go noop(tee(&z)) // ERROR "&z escapes to heap"
+	go noop(&x, &y)  // ERROR "escapes to heap"
+	for {
+		var u, v, w int     // ERROR "moved to heap"
+		defer noop(tee(&u)) // ERROR "&u escapes to heap"
+		defer noop(&v, &w)  // ERROR "escapes to heap"
+	}
+}
+
+type Fooer interface {
+	Foo()
+}
+
+type LimitedFooer struct {
+	Fooer
+	N int64
+}
+
+func LimitFooer(r Fooer, n int64) Fooer { // ERROR "leaking param: r"
+	return &LimitedFooer{r, n} // ERROR "&LimitedFooer literal escapes to heap"
+}
+
+func foo90(x *int) map[*int]*int { // ERROR "leaking param: x"
+	return map[*int]*int{nil: x} // ERROR "map\[\*int\]\*int literal escapes to heap"
+}
+
+func foo91(x *int) map[*int]*int { // ERROR "leaking param: x"
+	return map[*int]*int{x: nil} // ERROR "map\[\*int\]\*int literal escapes to heap"
+}
+
+func foo92(x *int) [2]*int { // ERROR "leaking param: x"
+	return [2]*int{x, nil}
+}
+
+// does not leak c
+func foo93(c chan *int) *int { // ERROR "c does not escape"
+	for v := range c {
+		return v
+	}
+	return nil
+}
+
+// does not leak m
+func foo94(m map[*int]*int, b bool) *int { // ERROR "m does not escape"
+	for k, v := range m {
+		if b {
+			return k
+		}
+		return v
+	}
+	return nil
+}
+
+// does leak x
+func foo95(m map[*int]*int, x *int) { // ERROR "m does not escape" "leaking param: x"
+	m[x] = x
+}
+
+// does not leak m
+func foo96(m []*int) *int { // ERROR "m does not escape"
+	return m[0]
+}
+
+// does leak m
+func foo97(m [1]*int) *int { // ERROR "leaking param: m"
+	return m[0]
+}
+
+// does not leak m
+func foo98(m map[int]*int) *int { // ERROR "m does not escape"
+	return m[0]
+}
+
+// does leak m
+func foo99(m *[1]*int) []*int { // ERROR "leaking param: m"
+	return m[:]
+}
+
+// does not leak m
+func foo100(m []*int) *int { // ERROR "m does not escape"
+	for _, v := range m {
+		return v
+	}
+	return nil
+}
+
+// does leak m
+func foo101(m [1]*int) *int { // ERROR "leaking param: m"
+	for _, v := range m {
+		return v
+	}
+	return nil
+}
+
+// does not leak m
+func foo101a(m [1]*int) *int { // ERROR "m does not escape"
+	for i := range m { // ERROR "moved to heap: i"
+		return &i // ERROR "&i escapes to heap"
+	}
+	return nil
+}
+
+// does leak x
+func foo102(m []*int, x *int) { // ERROR "m does not escape" "leaking param: x"
+	m[0] = x
+}
+
+// does not leak x
+func foo103(m [1]*int, x *int) { // ERROR "m does not escape" "x does not escape"
+	m[0] = x
+}
+
+var y []*int
+
+// does not leak x
+func foo104(x []*int) { // ERROR "x does not escape"
+	copy(y, x)
+}
+
+// does not leak x
+func foo105(x []*int) { // ERROR "x does not escape"
+	_ = append(y, x...)
+}
+
+// does leak x
+func foo106(x *int) { // ERROR "leaking param: x"
+	_ = append(y, x)
+}
+
+func foo107(x *int) map[*int]*int { // ERROR "leaking param: x"
+	return map[*int]*int{x: nil} // ERROR "map.* literal escapes to heap"
+}
+
+func foo108(x *int) map[*int]*int { // ERROR "leaking param: x"
+	return map[*int]*int{nil: x} // ERROR "map.* literal escapes to heap"
+}
+
+func foo109(x *int) *int { // ERROR "leaking param: x"
+	m := map[*int]*int{x: nil} // ERROR "map.* literal does not escape"
+	for k, _ := range m {
+		return k
+	}
+	return nil
+}
+
+func foo110(x *int) *int { // ERROR "leaking param: x"
+	m := map[*int]*int{nil: x} // ERROR "map.* literal does not escape"
+	return m[nil]
+}
+
+func foo111(x *int) *int { // ERROR "leaking param: x"
+	m := []*int{x} // ERROR "\[\]\*int literal does not escape"
+	return m[0]
+}
+
+func foo112(x *int) *int { // ERROR "leaking param: x"
+	m := [1]*int{x}
+	return m[0]
+}
+
+func foo113(x *int) *int { // ERROR "leaking param: x"
+	m := Bar{ii: x}
+	return m.ii
+}
+
+func foo114(x *int) *int { // ERROR "leaking param: x"
+	m := &Bar{ii: x} // ERROR "&Bar literal does not escape"
+	return m.ii
+}
+
+func foo115(x *int) *int { // ERROR "leaking param: x"
+	return (*int)(unsafe.Pointer(uintptr(unsafe.Pointer(x)) + 1))
+}
+
+func foo116(b bool) *int {
+	if b {
+		x := 1    // ERROR "moved to heap: x"
+		return &x // ERROR "&x escapes to heap"
+	} else {
+		y := 1    // ERROR "moved to heap: y"
+		return &y // ERROR "&y escapes to heap"
+	}
+	return nil
+}
+
+func foo117(unknown func(interface{})) { // ERROR "unknown does not escape"
+	x := 1      // ERROR "moved to heap: x"
+	unknown(&x) // ERROR "&x escapes to heap"
+}
+
+func foo118(unknown func(*int)) { // ERROR "unknown does not escape"
+	x := 1      // ERROR "moved to heap: x"
+	unknown(&x) // ERROR "&x escapes to heap"
+}
+
+func external(*int)
+
+func foo119(x *int) { // ERROR "leaking param: x"
+	external(x)
+}
+
+func foo120() {
+	// formerly exponential time analysis
+L1:
+L2:
+L3:
+L4:
+L5:
+L6:
+L7:
+L8:
+L9:
+L10:
+L11:
+L12:
+L13:
+L14:
+L15:
+L16:
+L17:
+L18:
+L19:
+L20:
+L21:
+L22:
+L23:
+L24:
+L25:
+L26:
+L27:
+L28:
+L29:
+L30:
+L31:
+L32:
+L33:
+L34:
+L35:
+L36:
+L37:
+L38:
+L39:
+L40:
+L41:
+L42:
+L43:
+L44:
+L45:
+L46:
+L47:
+L48:
+L49:
+L50:
+L51:
+L52:
+L53:
+L54:
+L55:
+L56:
+L57:
+L58:
+L59:
+L60:
+L61:
+L62:
+L63:
+L64:
+L65:
+L66:
+L67:
+L68:
+L69:
+L70:
+L71:
+L72:
+L73:
+L74:
+L75:
+L76:
+L77:
+L78:
+L79:
+L80:
+L81:
+L82:
+L83:
+L84:
+L85:
+L86:
+L87:
+L88:
+L89:
+L90:
+L91:
+L92:
+L93:
+L94:
+L95:
+L96:
+L97:
+L98:
+L99:
+L100:
+	// use the labels to silence compiler errors
+	goto L1
+	goto L2
+	goto L3
+	goto L4
+	goto L5
+	goto L6
+	goto L7
+	goto L8
+	goto L9
+	goto L10
+	goto L11
+	goto L12
+	goto L13
+	goto L14
+	goto L15
+	goto L16
+	goto L17
+	goto L18
+	goto L19
+	goto L20
+	goto L21
+	goto L22
+	goto L23
+	goto L24
+	goto L25
+	goto L26
+	goto L27
+	goto L28
+	goto L29
+	goto L30
+	goto L31
+	goto L32
+	goto L33
+	goto L34
+	goto L35
+	goto L36
+	goto L37
+	goto L38
+	goto L39
+	goto L40
+	goto L41
+	goto L42
+	goto L43
+	goto L44
+	goto L45
+	goto L46
+	goto L47
+	goto L48
+	goto L49
+	goto L50
+	goto L51
+	goto L52
+	goto L53
+	goto L54
+	goto L55
+	goto L56
+	goto L57
+	goto L58
+	goto L59
+	goto L60
+	goto L61
+	goto L62
+	goto L63
+	goto L64
+	goto L65
+	goto L66
+	goto L67
+	goto L68
+	goto L69
+	goto L70
+	goto L71
+	goto L72
+	goto L73
+	goto L74
+	goto L75
+	goto L76
+	goto L77
+	goto L78
+	goto L79
+	goto L80
+	goto L81
+	goto L82
+	goto L83
+	goto L84
+	goto L85
+	goto L86
+	goto L87
+	goto L88
+	goto L89
+	goto L90
+	goto L91
+	goto L92
+	goto L93
+	goto L94
+	goto L95
+	goto L96
+	goto L97
+	goto L98
+	goto L99
+	goto L100
+}
+
+func foo121() {
+	for i := 0; i < 10; i++ {
+		defer myprint(nil, i) // ERROR "[.][.][.] argument escapes to heap"
+		go myprint(nil, i)    // ERROR "[.][.][.] argument escapes to heap"
+	}
+}
+
+// same as foo121 but check across import
+func foo121b() {
+	for i := 0; i < 10; i++ {
+		defer fmt.Printf("%d", i) // ERROR "[.][.][.] argument escapes to heap"
+		go fmt.Printf("%d", i)    // ERROR "[.][.][.] argument escapes to heap"
+	}
+}
+
+// a harmless forward jump
+func foo122() {
+	var i *int
+
+	goto L1
+L1:
+	i = new(int) // ERROR "new.int. does not escape"
+	_ = i
+}
+
+// a backward jump, increases loopdepth
+func foo123() {
+	var i *int
+
+L1:
+	i = new(int) // ERROR "new.int. escapes to heap"
+
+	goto L1
+	_ = i
+}
+
+func foo124(x **int) { // ERROR "x does not escape"
+	var i int // ERROR "moved to heap: i"
+	p := &i   // ERROR "&i escapes"
+	func() {  // ERROR "func literal does not escape"
+		*x = p // ERROR "leaking closure reference p"
+	}()
+}
+
+func foo125(ch chan *int) { // ERROR "does not escape"
+	var i int // ERROR "moved to heap"
+	p := &i   // ERROR "&i escapes to heap"
+	func() {  // ERROR "func literal does not escape"
+		ch <- p // ERROR "leaking closure reference p"
+	}()
+}
+
+func foo126() {
+	var px *int // loopdepth 0
+	for {
+		// loopdepth 1
+		var i int // ERROR "moved to heap"
+		func() {  // ERROR "func literal does not escape"
+			px = &i // ERROR "&i escapes"
+		}()
+	}
+	_ = px
+}
+
+var px *int
+
+func foo127() {
+	var i int // ERROR "moved to heap: i"
+	p := &i   // ERROR "&i escapes to heap"
+	q := p
+	px = q
+}
+
+func foo128() {
+	var i int
+	p := &i // ERROR "&i does not escape"
+	q := p
+	_ = q
+}
+
+func foo129() {
+	var i int // ERROR "moved to heap: i"
+	p := &i   // ERROR "&i escapes to heap"
+	func() {  // ERROR "func literal does not escape"
+		q := p   // ERROR "leaking closure reference p"
+		func() { // ERROR "func literal does not escape"
+			r := q // ERROR "leaking closure reference q"
+			px = r
+		}()
+	}()
+}
+
+func foo130() {
+	for {
+		var i int // ERROR "moved to heap"
+		func() {  // ERROR "func literal does not escape"
+			px = &i // ERROR "&i escapes" "leaking closure reference i"
+		}()
+	}
+}
+
+func foo131() {
+	var i int // ERROR "moved to heap"
+	func() {  // ERROR "func literal does not escape"
+		px = &i // ERROR "&i escapes" "leaking closure reference i"
+	}()
+}
+
+func foo132() {
+	var i int   // ERROR "moved to heap"
+	go func() { // ERROR "func literal escapes to heap"
+		px = &i // ERROR "&i escapes" "leaking closure reference i"
+	}()
+}
+
+func foo133() {
+	var i int      // ERROR "moved to heap"
+	defer func() { // ERROR "func literal does not escape"
+		px = &i // ERROR "&i escapes" "leaking closure reference i"
+	}()
+}
+
+func foo134() {
+	var i int
+	p := &i  // ERROR "&i does not escape"
+	func() { // ERROR "func literal does not escape"
+		q := p
+		func() { // ERROR "func literal does not escape"
+			r := q
+			_ = r
+		}()
+	}()
+}
+
+func foo135() {
+	var i int   // ERROR "moved to heap: i"
+	p := &i     // ERROR "&i escapes to heap" "moved to heap: p"
+	go func() { // ERROR "func literal escapes to heap"
+		q := p   // ERROR "&p escapes to heap"
+		func() { // ERROR "func literal does not escape"
+			r := q
+			_ = r
+		}()
+	}()
+}
+
+func foo136() {
+	var i int   // ERROR "moved to heap: i"
+	p := &i     // ERROR "&i escapes to heap" "moved to heap: p"
+	go func() { // ERROR "func literal escapes to heap"
+		q := p   // ERROR "&p escapes to heap" "leaking closure reference p"
+		func() { // ERROR "func literal does not escape"
+			r := q // ERROR "leaking closure reference q"
+			px = r
+		}()
+	}()
+}
+
+func foo137() {
+	var i int // ERROR "moved to heap: i"
+	p := &i   // ERROR "&i escapes to heap"
+	func() {  // ERROR "func literal does not escape"
+		q := p      // ERROR "leaking closure reference p" "moved to heap: q"
+		go func() { // ERROR "func literal escapes to heap"
+			r := q // ERROR "&q escapes to heap"
+			_ = r
+		}()
+	}()
+}
+
+func foo138() *byte {
+	type T struct {
+		x [1]byte
+	}
+	t := new(T)    // ERROR "new.T. escapes to heap"
+	return &t.x[0] // ERROR "&t.x.0. escapes to heap"
+}
+
+func foo139() *byte {
+	type T struct {
+		x struct {
+			y byte
+		}
+	}
+	t := new(T)   // ERROR "new.T. escapes to heap"
+	return &t.x.y // ERROR "&t.x.y escapes to heap"
+}
+
+// issue 4751
+func foo140() interface{} {
+	type T struct {
+		X string
+	}
+	type U struct {
+		X string
+		T *T
+	}
+	t := &T{} // ERROR "&T literal escapes to heap"
+	return U{
+		X: t.X,
+		T: t,
+	}
+}
+
+//go:noescape
+
+func F1([]byte)
+
+func F2([]byte)
+
+//go:noescape
+
+func F3(x []byte) // ERROR "F3 x does not escape"
+
+func F4(x []byte)
+
+func G() {
+	var buf1 [10]byte
+	F1(buf1[:]) // ERROR "buf1 does not escape"
+
+	var buf2 [10]byte // ERROR "moved to heap: buf2"
+	F2(buf2[:])       // ERROR "buf2 escapes to heap"
+
+	var buf3 [10]byte
+	F3(buf3[:]) // ERROR "buf3 does not escape"
+
+	var buf4 [10]byte // ERROR "moved to heap: buf4"
+	F4(buf4[:])       // ERROR "buf4 escapes to heap"
+}
+
+type Tm struct {
+	x int
+}
+
+func (t *Tm) M() { // ERROR "t does not escape"
+}
+
+func foo141() {
+	var f func()
+
+	t := new(Tm) // ERROR "escapes to heap"
+	f = t.M      // ERROR "t.M does not escape"
+	_ = f
+}
+
+var gf func()
+
+func foo142() {
+	t := new(Tm) // ERROR "escapes to heap"
+	gf = t.M     // ERROR "t.M escapes to heap"
+}
+
+// issue 3888.
+func foo143() {
+	for i := 0; i < 1000; i++ {
+		func() { // ERROR "func literal does not escape"
+			for i := 0; i < 1; i++ {
+				var t Tm
+				t.M() // ERROR "t does not escape"
+			}
+		}()
+	}
+}
+
+// issue 5773
+// Check that annotations take effect regardless of whether they
+// are before or after the use in the source code.
+
+//go:noescape
+
+func foo144a(*int)
+
+func foo144() {
+	var x int
+	foo144a(&x) // ERROR "&x does not escape"
+	var y int
+	foo144b(&y) // ERROR "&y does not escape"
+}
+
+//go:noescape
+
+func foo144b(*int)
+
+// issue 7313: for loop init should not be treated as "in loop"
+
+type List struct {
+	Next *List
+}
+
+func foo145(l List) { // ERROR "l does not escape"
+	var p *List
+	for p = &l; p.Next != nil; p = p.Next { // ERROR "&l does not escape"
+	}
+}
+
+func foo146(l List) { // ERROR "l does not escape"
+	var p *List
+	p = &l // ERROR "&l does not escape"
+	for ; p.Next != nil; p = p.Next {
+	}
+}
+
+func foo147(l List) { // ERROR "l does not escape"
+	var p *List
+	p = &l // ERROR "&l does not escape"
+	for p.Next != nil {
+		p = p.Next
+	}
+}
+
+func foo148(l List) { // ERROR " l does not escape"
+	for p := &l; p.Next != nil; p = p.Next { // ERROR "&l does not escape"
+	}
+}
+
+// related: address of variable should have depth of variable, not of loop
+
+func foo149(l List) { // ERROR " l does not escape"
+	var p *List
+	for {
+		for p = &l; p.Next != nil; p = p.Next { // ERROR "&l does not escape"
+		}
+	}
+}
+
+// issue 7934: missed ... if element type had no pointers
+
+var save150 []byte
+
+func foo150(x ...byte) { // ERROR "leaking param: x"
+	save150 = x
+}
+
+func bar150() {
+	foo150(1, 2, 3) // ERROR "[.][.][.] argument escapes to heap"
+}
+
+// issue 7931: bad handling of slice of array
+
+var save151 *int
+
+func foo151(x *int) { // ERROR "leaking param: x"
+	save151 = x
+}
+
+func bar151() {
+	var a [64]int // ERROR "moved to heap: a"
+	a[4] = 101
+	foo151(&(&a)[4:8][0]) // ERROR "&\(&a\)\[4:8\]\[0\] escapes to heap" "&a escapes to heap"
+}
+
+func bar151b() {
+	var a [10]int      // ERROR "moved to heap: a"
+	b := a[:]          // ERROR "a escapes to heap"
+	foo151(&b[4:8][0]) // ERROR "&b\[4:8\]\[0\] escapes to heap"
+}
+
+func bar151c() {
+	var a [64]int // ERROR "moved to heap: a"
+	a[4] = 101
+	foo151(&(&a)[4:8:8][0]) // ERROR "&\(&a\)\[4:8:8\]\[0\] escapes to heap" "&a escapes to heap"
+}
+
+func bar151d() {
+	var a [10]int        // ERROR "moved to heap: a"
+	b := a[:]            // ERROR "a escapes to heap"
+	foo151(&b[4:8:8][0]) // ERROR "&b\[4:8:8\]\[0\] escapes to heap"
+}
+
+// issue 8120
+
+type U struct {
+	s *string
+}
+
+func (u *U) String() *string { // ERROR "leaking param u content to result ~r0"
+	return u.s
+}
+
+type V struct {
+	s *string
+}
+
+func NewV(u U) *V { // ERROR "leaking param: u"
+	return &V{u.String()} // ERROR "&V literal escapes to heap" "u does not escape"
+}
+
+func foo152() {
+	a := "a"   // ERROR "moved to heap: a"
+	u := U{&a} // ERROR "&a escapes to heap"
+	v := NewV(u)
+	println(v)
+}
+
+// issue 8176 - &x in type switch body not marked as escaping
+
+func foo153(v interface{}) *int { // ERROR "leaking param: v"
+	switch x := v.(type) {
+	case int: // ERROR "moved to heap: x"
+		return &x // ERROR "&x escapes to heap"
+	}
+	panic(0)
+}
+
+// issue 8185 - &result escaping into result
+
+func f() (x int, y *int) { // ERROR "moved to heap: x"
+	y = &x // ERROR "&x escapes to heap"
+	return
+}
+
+func g() (x interface{}) { // ERROR "moved to heap: x"
+	x = &x // ERROR "&x escapes to heap"
+	return
+}
diff --git a/test/fixedbugs/bug173.go b/test/fixedbugs/bug173.go
index 6479bb2..3515c64 100644
--- a/test/fixedbugs/bug173.go
+++ b/test/fixedbugs/bug173.go
@@ -18,4 +18,6 @@ func main() {
 	}
 	for _ = range t {
 	}
+	for range t {
+	}
 }
diff --git a/test/fixedbugs/bug255.go b/test/fixedbugs/bug255.go
index acf4f23..65ed1b8 100644
--- a/test/fixedbugs/bug255.go
+++ b/test/fixedbugs/bug255.go
@@ -6,10 +6,15 @@
 
 package main
 
-var a [10]int	// ok
-var b [1e1]int	// ok
-var c [1.5]int	// ERROR "truncated"
-var d ["abc"]int	// ERROR "invalid array bound|not numeric"
-var e [nil]int	// ERROR "invalid array bound|not numeric"
-var f [e]int	// ERROR "invalid array bound|not constant"
-var g [1<<65]int	// ERROR "array bound is too large|overflows"
+var a [10]int      // ok
+var b [1e1]int     // ok
+var c [1.5]int     // ERROR "truncated"
+var d ["abc"]int   // ERROR "invalid array bound|not numeric"
+var e [nil]int     // ERROR "invalid array bound|not numeric"
+var f [e]int       // ERROR "invalid array bound|not constant"
+var g [1 << 65]int // ERROR "array bound is too large|overflows"
+var h [len(a)]int  // ok
+
+func ff() string
+
+var i [len([1]string{ff()})]int // ERROR "non-constant array bound|not constant"
diff --git a/test/fixedbugs/bug299.go b/test/fixedbugs/bug299.go
index 9646723..1067fd1 100644
--- a/test/fixedbugs/bug299.go
+++ b/test/fixedbugs/bug299.go
@@ -21,7 +21,9 @@ type T struct {
 // legal according to spec
 func (p T) m() {}
 
-// not legal according to spec
-func (p (T)) f() {}   // ERROR "parenthesize|expected"
-func (p *(T)) g() {}  // ERROR "parenthesize|expected"
-func (p (*T)) h() {}  // ERROR "parenthesize|expected"
+// now legal according to spec
+func (p (T)) f() {}
+func (p *(T)) g() {}
+func (p (*T)) h() {}
+func (p (*(T))) i() {}
+func ((T),) j() {}
diff --git a/test/fixedbugs/bug371.go b/test/fixedbugs/bug371.go
index 6329e96..86c73bf 100644
--- a/test/fixedbugs/bug371.go
+++ b/test/fixedbugs/bug371.go
@@ -8,10 +8,10 @@
 
 package main
 
-type T struct {}
+type T struct{}
 
 func (t *T) pm() {}
-func (t T) m() {}
+func (t T) m()   {}
 
 func main() {
 	p := &T{}
@@ -20,5 +20,5 @@ func main() {
 
 	q := &p
 	q.m()  // ERROR "requires explicit dereference"
-	q.pm()
+	q.pm() // ERROR "requires explicit dereference"
 }
diff --git a/test/fixedbugs/bug406.go b/test/fixedbugs/bug406.go
index c6f8534..6df3c5c 100644
--- a/test/fixedbugs/bug406.go
+++ b/test/fixedbugs/bug406.go
@@ -14,6 +14,8 @@ type matrix struct {
 func (a matrix) equal() bool {
 	for _ = range a.e {
 	}
+	for range a.e {
+	}
 	return true
 }
 
diff --git a/test/fixedbugs/bug486.go b/test/fixedbugs/bug486.go
new file mode 100644
index 0000000..c1a4723
--- /dev/null
+++ b/test/fixedbugs/bug486.go
@@ -0,0 +1,14 @@
+// compile
+
+// 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.
+
+// The gccgo lexer had a bug handling nested comments.
+// http://gcc.gnu.org/PR61746
+// http://code.google.com/p/gofrontend/issues/detail?id=35
+
+package main
+
+/*// comment
+*/
diff --git a/test/fixedbugs/bug487.go b/test/fixedbugs/bug487.go
new file mode 100644
index 0000000..eb1ad5e
--- /dev/null
+++ b/test/fixedbugs/bug487.go
@@ -0,0 +1,24 @@
+// errorcheck
+
+// 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.
+
+// The gccgo compiler did not reliably report mismatches between the
+// number of function results and the number of expected results.
+
+package p
+
+func G() (int, int, int) {
+	return 0, 0, 0
+}
+
+func F() {
+	a, b := G()	// ERROR "mismatch"
+	a, b = G()	// ERROR "mismatch"
+	_, _ = a, b
+}
+
+func H() (int, int) {
+	return G()	// ERROR "too many|mismatch"
+}
diff --git a/test/fixedbugs/bug488.dir/a.go b/test/fixedbugs/bug488.dir/a.go
new file mode 100644
index 0000000..94eaf7f
--- /dev/null
+++ b/test/fixedbugs/bug488.dir/a.go
@@ -0,0 +1,7 @@
+// Copyright 2014 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package a
+
+var p2 = Printf		// ERROR "undefined"
diff --git a/test/fixedbugs/bug488.dir/b.go b/test/fixedbugs/bug488.dir/b.go
new file mode 100644
index 0000000..21b4c5b
--- /dev/null
+++ b/test/fixedbugs/bug488.dir/b.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.
+
+package a
+
+import . "fmt"
+
+var p1 = Print
diff --git a/test/fixedbugs/bug488.go b/test/fixedbugs/bug488.go
new file mode 100644
index 0000000..63a601e
--- /dev/null
+++ b/test/fixedbugs/bug488.go
@@ -0,0 +1,12 @@
+// errorcheckdir
+
+// 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.
+
+// The gccgo compiler had a bug: if one file in a package did a dot
+// import, then an earlier file in the package would incorrectly
+// resolve to the imported names rather than reporting undefined
+// errors.
+
+package ignored
diff --git a/test/fixedbugs/bug489.go b/test/fixedbugs/bug489.go
new file mode 100644
index 0000000..4cf19e0
--- /dev/null
+++ b/test/fixedbugs/bug489.go
@@ -0,0 +1,22 @@
+// compile
+
+// 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.
+
+// The gccgo compiler had a bug: mentioning a function type in an
+// expression in a function literal messed up the list of variables
+// referenced in enclosing functions.
+
+package main
+
+func main() {
+	v1, v2 := 0, 0
+	f := func() {
+		a := v1
+		g := (func())(nil)
+		b := v2
+		_, _, _ = a, g, b
+	}
+	_, _, _ = v1, v2, f
+}
diff --git a/test/fixedbugs/bug490.go b/test/fixedbugs/bug490.go
new file mode 100644
index 0000000..7d05f39
--- /dev/null
+++ b/test/fixedbugs/bug490.go
@@ -0,0 +1,16 @@
+// compile
+
+// 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.
+
+// The gccgo compiler used to crash building a comparison between an
+// interface and an empty struct literal.
+
+package p
+ 
+type S struct{}
+
+func F(v interface{}) bool {
+	return v == S{}
+}
diff --git a/test/fixedbugs/bug491.go b/test/fixedbugs/bug491.go
new file mode 100644
index 0000000..f4b58af
--- /dev/null
+++ b/test/fixedbugs/bug491.go
@@ -0,0 +1,110 @@
+// run
+
+// 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 order of calls to builtin functions.
+// Discovered during CL 144530045 review.
+
+package main
+
+func main() {
+	// append
+	{
+		x := make([]int, 0)
+		f := func() int { x = make([]int, 2); return 2 }
+		a, b, c := append(x, 1), f(), append(x, 1)
+		if len(a) != 1 || len(c) != 3 {
+			bug()
+			println("append call not ordered:", len(a), b, len(c))
+		}
+	}
+
+	// cap
+	{
+		x := make([]int, 1)
+		f := func() int { x = make([]int, 3); return 2 }
+		a, b, c := cap(x), f(), cap(x)
+		if a != 1 || c != 3 {
+			bug()
+			println("cap call not ordered:", a, b, c)
+		}
+	}
+
+	// complex
+	{
+		x := 1.0
+		f := func() int { x = 3; return 2 }
+		a, b, c := complex(x, 0), f(), complex(x, 0)
+		if real(a) != 1 || real(c) != 3 {
+			bug()
+			println("complex call not ordered:", a, b, c)
+		}
+	}
+
+	// copy
+	{
+		tmp := make([]int, 100)
+		x := make([]int, 1)
+		f := func() int { x = make([]int, 3); return 2 }
+		a, b, c := copy(tmp, x), f(), copy(tmp, x)
+		if a != 1 || c != 3 {
+			bug()
+			println("copy call not ordered:", a, b, c)
+		}
+	}
+
+	// imag
+	{
+		x := 1i
+		f := func() int { x = 3i; return 2 }
+		a, b, c := imag(x), f(), imag(x)
+		if a != 1 || c != 3 {
+			bug()
+			println("imag call not ordered:", a, b, c)
+		}
+	}
+
+	// len
+	{
+		x := make([]int, 1)
+		f := func() int { x = make([]int, 3); return 2 }
+		a, b, c := len(x), f(), len(x)
+		if a != 1 || c != 3 {
+			bug()
+			println("len call not ordered:", a, b, c)
+		}
+	}
+
+	// make
+	{
+		x := 1
+		f := func() int { x = 3; return 2 }
+		a, b, c := make([]int, x), f(), make([]int, x)
+		if len(a) != 1 || len(c) != 3 {
+			bug()
+			println("make call not ordered:", len(a), b, len(c))
+		}
+	}
+
+	// real
+	{
+		x := 1 + 0i
+		f := func() int { x = 3; return 2 }
+		a, b, c := real(x), f(), real(x)
+		if a != 1 || c != 3 {
+			bug()
+			println("real call not ordered:", a, b, c)
+		}
+	}
+}
+
+var bugged = false
+
+func bug() {
+	if !bugged {
+		println("BUG")
+		bugged = true
+	}
+}
\ No newline at end of file
diff --git a/test/fixedbugs/issue4232.go b/test/fixedbugs/issue4232.go
index e5daa65..755b1b1 100644
--- a/test/fixedbugs/issue4232.go
+++ b/test/fixedbugs/issue4232.go
@@ -4,6 +4,9 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// issue 4232
+// issue 7200
+
 package p
 
 func f() {
@@ -12,22 +15,42 @@ func f() {
 	_ = a[-1:] // ERROR "invalid slice index -1|index out of bounds"
 	_ = a[:-1] // ERROR "invalid slice index -1|index out of bounds"
 	_ = a[10]  // ERROR "invalid array index 10|index out of bounds"
+	_ = a[9:10]
+	_ = a[10:10]
+	_ = a[9:12]            // ERROR "invalid slice index 12|index out of bounds"
+	_ = a[11:12]           // ERROR "invalid slice index 11|index out of bounds"
+	_ = a[1<<100 : 1<<110] // ERROR "overflows int" "invalid slice index 1 << 100|index out of bounds"
 
 	var s []int
 	_ = s[-1]  // ERROR "invalid slice index -1|index out of bounds"
 	_ = s[-1:] // ERROR "invalid slice index -1|index out of bounds"
 	_ = s[:-1] // ERROR "invalid slice index -1|index out of bounds"
 	_ = s[10]
+	_ = s[9:10]
+	_ = s[10:10]
+	_ = s[9:12]
+	_ = s[11:12]
+	_ = s[1<<100 : 1<<110] // ERROR "overflows int" "invalid slice index 1 << 100|index out of bounds"
 
-	const c = "foo"
+	const c = "foofoofoof"
 	_ = c[-1]  // ERROR "invalid string index -1|index out of bounds"
 	_ = c[-1:] // ERROR "invalid slice index -1|index out of bounds"
 	_ = c[:-1] // ERROR "invalid slice index -1|index out of bounds"
-	_ = c[3]   // ERROR "invalid string index 3|index out of bounds"
+	_ = c[10]  // ERROR "invalid string index 10|index out of bounds"
+	_ = c[9:10]
+	_ = c[10:10]
+	_ = c[9:12]            // ERROR "invalid slice index 12|index out of bounds"
+	_ = c[11:12]           // ERROR "invalid slice index 11|index out of bounds"
+	_ = c[1<<100 : 1<<110] // ERROR "overflows int" "invalid slice index 1 << 100|index out of bounds"
 
 	var t string
 	_ = t[-1]  // ERROR "invalid string index -1|index out of bounds"
 	_ = t[-1:] // ERROR "invalid slice index -1|index out of bounds"
 	_ = t[:-1] // ERROR "invalid slice index -1|index out of bounds"
-	_ = t[3]
+	_ = t[10]
+	_ = t[9:10]
+	_ = t[10:10]
+	_ = t[9:12]
+	_ = t[11:12]
+	_ = t[1<<100 : 1<<110] // ERROR "overflows int" "invalid slice index 1 << 100|index out of bounds"
 }
diff --git a/test/fixedbugs/issue4388.go b/test/fixedbugs/issue4388.go
index 2e052e1..b18c98b 100644
--- a/test/fixedbugs/issue4388.go
+++ b/test/fixedbugs/issue4388.go
@@ -17,18 +17,18 @@ type T struct {
 }
 
 func f1() {
-	// The 4 here and below depends on the number of internal runtime frames
+	// The 5 here and below depends on the number of internal runtime frames
 	// that sit between a deferred function called during panic and
 	// the original frame. If that changes, this test will start failing and
 	// the number here will need to be updated.
-	defer checkLine(4)
+	defer checkLine(5)
 	var t *T
 	var c io.Closer = t
 	c.Close()
 }
 
 func f2() {
-	defer checkLine(4)
+	defer checkLine(5)
 	var t T
 	var c io.Closer = t
 	c.Close()
diff --git a/test/fixedbugs/issue5856.go b/test/fixedbugs/issue5856.go
index 35cadf8..78ca3b9 100644
--- a/test/fixedbugs/issue5856.go
+++ b/test/fixedbugs/issue5856.go
@@ -29,7 +29,7 @@ func f() {
 }
 
 func g() {
-	_, file, line, _ := runtime.Caller(2)
+	_, file, line, _ := runtime.Caller(3)
 	if !strings.HasSuffix(file, "issue5856.go") || line != 28 {
 		fmt.Printf("BUG: defer called from %s:%d, want issue5856.go:28\n", file, line)
 		os.Exit(1)
diff --git a/test/fixedbugs/issue6703a.go b/test/fixedbugs/issue6703a.go
new file mode 100644
index 0000000..d4c008f
--- /dev/null
+++ b/test/fixedbugs/issue6703a.go
@@ -0,0 +1,16 @@
+// errorcheck
+
+// 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.
+
+// Check for cycles in a function value.
+
+package funcvalue
+
+func fx() int {
+	_ = x
+	return 0
+}
+
+var x = fx // ERROR "initialization loop|depends upon itself"
diff --git a/test/fixedbugs/issue6703b.go b/test/fixedbugs/issue6703b.go
new file mode 100644
index 0000000..326b583
--- /dev/null
+++ b/test/fixedbugs/issue6703b.go
@@ -0,0 +1,16 @@
+// errorcheck
+
+// 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.
+
+// Check for cycles in a function call.
+
+package funccall
+
+func fx() int {
+	_ = x
+	return 0
+}
+
+var x = fx() // ERROR "initialization loop|depends upon itself"
diff --git a/test/fixedbugs/issue6703c.go b/test/fixedbugs/issue6703c.go
new file mode 100644
index 0000000..4735764
--- /dev/null
+++ b/test/fixedbugs/issue6703c.go
@@ -0,0 +1,18 @@
+// errorcheck
+
+// 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.
+
+// Check for cycles in a method expression.
+
+package methexpr
+
+type T int
+
+func (T) m() int {
+	_ = x
+	return 0
+}
+
+var x = T.m // ERROR "initialization loop|depends upon itself"
diff --git a/test/fixedbugs/issue6703d.go b/test/fixedbugs/issue6703d.go
new file mode 100644
index 0000000..0a1952f
--- /dev/null
+++ b/test/fixedbugs/issue6703d.go
@@ -0,0 +1,18 @@
+// errorcheck
+
+// 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.
+
+// Check for cycles in a method expression call.
+
+package methexprcall
+
+type T int
+
+func (T) m() int {
+	_ = x
+	return 0
+}
+
+var x = T.m(0) // ERROR "initialization loop|depends upon itself"
diff --git a/test/fixedbugs/issue6703e.go b/test/fixedbugs/issue6703e.go
new file mode 100644
index 0000000..416066e
--- /dev/null
+++ b/test/fixedbugs/issue6703e.go
@@ -0,0 +1,18 @@
+// errorcheck
+
+// 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.
+
+// Check for cycles in the method value of a value literal.
+
+package litmethvalue
+
+type T int
+
+func (T) m() int {
+	_ = x
+	return 0
+}
+
+var x = T(0).m // ERROR "initialization loop|depends upon itself"
diff --git a/test/fixedbugs/issue6703f.go b/test/fixedbugs/issue6703f.go
new file mode 100644
index 0000000..3023829
--- /dev/null
+++ b/test/fixedbugs/issue6703f.go
@@ -0,0 +1,18 @@
+// errorcheck
+
+// 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.
+
+// Check for cycles in the method call of a value literal.
+
+package litmethcall
+
+type T int
+
+func (T) m() int {
+	_ = x
+	return 0
+}
+
+var x = T(0).m() // ERROR "initialization loop|depends upon itself"
diff --git a/test/fixedbugs/issue6703g.go b/test/fixedbugs/issue6703g.go
new file mode 100644
index 0000000..002b5a6
--- /dev/null
+++ b/test/fixedbugs/issue6703g.go
@@ -0,0 +1,20 @@
+// errorcheck
+
+// 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.
+
+// Check for cycles in an embedded method expression.
+
+package embedmethexpr
+
+type T int
+
+func (T) m() int {
+	_ = x
+	return 0
+}
+
+type E struct{ T }
+
+var x = E.m // ERROR "initialization loop|depends upon itself" 
diff --git a/test/fixedbugs/issue6703h.go b/test/fixedbugs/issue6703h.go
new file mode 100644
index 0000000..234ccb3
--- /dev/null
+++ b/test/fixedbugs/issue6703h.go
@@ -0,0 +1,20 @@
+// errorcheck
+
+// 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.
+
+// Check for cycles when calling an embedded method expression.
+
+package embedmethexprcall
+
+type T int
+
+func (T) m() int {
+	_ = x
+	return 0
+}
+
+type E struct{ T }
+
+var x = E.m(E{0}) // ERROR "initialization loop|depends upon itself" 
diff --git a/test/fixedbugs/issue6703i.go b/test/fixedbugs/issue6703i.go
new file mode 100644
index 0000000..78b4d49
--- /dev/null
+++ b/test/fixedbugs/issue6703i.go
@@ -0,0 +1,20 @@
+// errorcheck
+
+// 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.
+
+// Check for cycles in an embedded struct literal's method value.
+
+package embedlitmethvalue
+
+type T int
+
+func (T) m() int {
+	_ = x
+	return 0
+}
+
+type E struct{ T }
+
+var x = E{}.m // ERROR "initialization loop|depends upon itself" 
diff --git a/test/fixedbugs/issue6703j.go b/test/fixedbugs/issue6703j.go
new file mode 100644
index 0000000..a7f63f7
--- /dev/null
+++ b/test/fixedbugs/issue6703j.go
@@ -0,0 +1,20 @@
+// errorcheck
+
+// 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.
+
+// Check for cycles in an embedded struct literal's method call.
+
+package embedlitmethcall
+
+type T int
+
+func (T) m() int {
+	_ = x
+	return 0
+}
+
+type E struct{ T }
+
+var x = E{}.m() // ERROR "initialization loop|depends upon itself"
diff --git a/test/fixedbugs/issue6703k.go b/test/fixedbugs/issue6703k.go
new file mode 100644
index 0000000..19c6107
--- /dev/null
+++ b/test/fixedbugs/issue6703k.go
@@ -0,0 +1,21 @@
+// errorcheck
+
+// 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.
+
+// Check for cycles in a method value.
+
+package methvalue
+
+type T int
+
+func (T) m() int {
+	_ = x
+	return 0
+}
+
+var (
+	t T
+	x = t.m // ERROR "initialization loop|depends upon itself"
+)
diff --git a/test/fixedbugs/issue6703l.go b/test/fixedbugs/issue6703l.go
new file mode 100644
index 0000000..3f4ca31
--- /dev/null
+++ b/test/fixedbugs/issue6703l.go
@@ -0,0 +1,21 @@
+// errorcheck
+
+// 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.
+
+// Check for cycles in a method call.
+
+package methcall
+
+type T int
+
+func (T) m() int {
+	_ = x
+	return 0
+}
+
+var (
+	t T
+	x = t.m() // ERROR "initialization loop|depends upon itself"
+)
diff --git a/test/fixedbugs/issue6703m.go b/test/fixedbugs/issue6703m.go
new file mode 100644
index 0000000..d80959c
--- /dev/null
+++ b/test/fixedbugs/issue6703m.go
@@ -0,0 +1,25 @@
+// errorcheck
+
+// 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.
+
+// Check for cycles in the method value of a value returned from a function call.
+
+package funcmethvalue
+
+type T int
+
+func (T) m() int {
+	_ = x
+	return 0
+}
+
+func f() T {
+	return T(0)
+}
+
+var (
+	t T
+	x = f().m // ERROR "initialization loop|depends upon itself"
+)
diff --git a/test/fixedbugs/issue6703n.go b/test/fixedbugs/issue6703n.go
new file mode 100644
index 0000000..2c623f2
--- /dev/null
+++ b/test/fixedbugs/issue6703n.go
@@ -0,0 +1,25 @@
+// errorcheck
+
+// 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.
+
+// Check for cycles in the method call of a value returned from a function call.
+
+package funcmethcall
+
+type T int
+
+func (T) m() int {
+	_ = x
+	return 0
+}
+
+func f() T {
+	return T(0)
+}
+
+var (
+	t T
+	x = f().m() // ERROR "initialization loop|depends upon itself"
+)
diff --git a/test/fixedbugs/issue6703o.go b/test/fixedbugs/issue6703o.go
new file mode 100644
index 0000000..efc8947
--- /dev/null
+++ b/test/fixedbugs/issue6703o.go
@@ -0,0 +1,23 @@
+// errorcheck
+
+// 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.
+
+// Check for cycles in an embedded struct's method value.
+
+package embedmethvalue
+
+type T int
+
+func (T) m() int {
+	_ = x
+	return 0
+}
+
+type E struct{ T }
+
+var (
+	e E
+	x = e.m // ERROR "initialization loop|depends upon itself" 
+)
diff --git a/test/fixedbugs/issue6703p.go b/test/fixedbugs/issue6703p.go
new file mode 100644
index 0000000..dad88f6
--- /dev/null
+++ b/test/fixedbugs/issue6703p.go
@@ -0,0 +1,23 @@
+// errorcheck
+
+// 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.
+
+// Check for cycles in an embedded struct's method call.
+
+package embedmethcall
+
+type T int
+
+func (T) m() int {
+	_ = x
+	return 0
+}
+
+type E struct{ T }
+
+var (
+	e E
+	x = e.m() // ERROR "initialization loop|depends upon itself" 
+)
diff --git a/test/fixedbugs/issue6703q.go b/test/fixedbugs/issue6703q.go
new file mode 100644
index 0000000..7bd748a
--- /dev/null
+++ b/test/fixedbugs/issue6703q.go
@@ -0,0 +1,28 @@
+// errorcheck
+
+// 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.
+
+// Check for cycles in the method value of an embedded struct returned
+// from a function call.
+
+package funcembedmethvalue
+
+type T int
+
+func (T) m() int {
+	_ = x
+	return 0
+}
+
+func g() E {
+	return E{0}
+}
+
+type E struct{ T }
+
+var (
+	e E
+	x = g().m // ERROR "initialization loop|depends upon itself" 
+)
diff --git a/test/fixedbugs/issue6703r.go b/test/fixedbugs/issue6703r.go
new file mode 100644
index 0000000..6698462
--- /dev/null
+++ b/test/fixedbugs/issue6703r.go
@@ -0,0 +1,28 @@
+// errorcheck
+
+// 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.
+
+// Check for cycles in the method call of an embedded struct returned
+// from a function call.
+
+package funcembedmethcall
+
+type T int
+
+func (T) m() int {
+	_ = x
+	return 0
+}
+
+func g() E {
+	return E{0}
+}
+
+type E struct{ T }
+
+var (
+	e E
+	x = g().m() // ERROR "initialization loop|depends upon itself" 
+)
diff --git a/test/fixedbugs/issue6703s.go b/test/fixedbugs/issue6703s.go
new file mode 100644
index 0000000..6aa2848
--- /dev/null
+++ b/test/fixedbugs/issue6703s.go
@@ -0,0 +1,18 @@
+// errorcheck
+
+// 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.
+
+// Check for cycles in a pointer method expression.
+
+package ptrmethexpr
+
+type T int
+
+func (*T) pm() int {
+	_ = x
+	return 0
+}
+
+var x = (*T).pm // ERROR "initialization loop|depends upon itself"
diff --git a/test/fixedbugs/issue6703t.go b/test/fixedbugs/issue6703t.go
new file mode 100644
index 0000000..bad65ad
--- /dev/null
+++ b/test/fixedbugs/issue6703t.go
@@ -0,0 +1,18 @@
+// errorcheck
+
+// 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.
+
+// Check for cycles in the call of a pointer method expression.
+
+package ptrmethexprcall
+
+type T int
+
+func (*T) pm() int {
+	_ = x
+	return 0
+}
+
+var x = (*T).pm(nil) // ERROR "initialization loop|depends upon itself"
diff --git a/test/fixedbugs/issue6703u.go b/test/fixedbugs/issue6703u.go
new file mode 100644
index 0000000..b6813b7
--- /dev/null
+++ b/test/fixedbugs/issue6703u.go
@@ -0,0 +1,18 @@
+// errorcheck
+
+// 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.
+
+// Check for cycles in a pointer literal's method value.
+
+package ptrlitmethvalue
+
+type T int
+
+func (*T) pm() int {
+	_ = x
+	return 0
+}
+
+var x = (*T)(nil).pm // ERROR "initialization loop|depends upon itself"
diff --git a/test/fixedbugs/issue6703v.go b/test/fixedbugs/issue6703v.go
new file mode 100644
index 0000000..a1b3711
--- /dev/null
+++ b/test/fixedbugs/issue6703v.go
@@ -0,0 +1,18 @@
+// errorcheck
+
+// 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.
+
+// Check for cycles in a pointer literal's method call.
+
+package ptrlitmethcall
+
+type T int
+
+func (*T) pm() int {
+	_ = x
+	return 0
+}
+
+var x = (*T)(nil).pm() // ERROR "initialization loop|depends upon itself"
diff --git a/test/fixedbugs/issue6703w.go b/test/fixedbugs/issue6703w.go
new file mode 100644
index 0000000..d4733de
--- /dev/null
+++ b/test/fixedbugs/issue6703w.go
@@ -0,0 +1,21 @@
+// errorcheck
+
+// 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.
+
+// Check for cycles in a pointer value's method value.
+
+package ptrmethvalue
+
+type T int
+
+func (*T) pm() int {
+	_ = x
+	return 0
+}
+
+var (
+	p *T
+	x = p.pm // ERROR "initialization loop|depends upon itself"
+)
diff --git a/test/fixedbugs/issue6703x.go b/test/fixedbugs/issue6703x.go
new file mode 100644
index 0000000..8008b8c
--- /dev/null
+++ b/test/fixedbugs/issue6703x.go
@@ -0,0 +1,21 @@
+// errorcheck
+
+// 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.
+
+// Check for cycles in a pointer value's method call.
+
+package ptrmethcall
+
+type T int
+
+func (*T) pm() int {
+	_ = x
+	return 0
+}
+
+var (
+	p *T
+	x = p.pm() // ERROR "initialization loop|depends upon itself"
+)
diff --git a/test/fixedbugs/issue6703y.go b/test/fixedbugs/issue6703y.go
new file mode 100644
index 0000000..ac4526d
--- /dev/null
+++ b/test/fixedbugs/issue6703y.go
@@ -0,0 +1,23 @@
+// errorcheck
+
+// 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.
+
+// Check for cycles in the method value of a pointer value returned
+// from a function call.
+
+package funcptrmethvalue
+
+type T int
+
+func (*T) pm() int {
+	_ = x
+	return 0
+}
+
+func pf() *T {
+	return nil
+}
+
+var x = pf().pm // ERROR "initialization loop|depends upon itself" 
diff --git a/test/fixedbugs/issue6703z.go b/test/fixedbugs/issue6703z.go
new file mode 100644
index 0000000..d4c17e1
--- /dev/null
+++ b/test/fixedbugs/issue6703z.go
@@ -0,0 +1,23 @@
+// errorcheck
+
+// 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.
+
+// Check for cycles in the method call of a pointer value returned
+// from a function call.
+
+package funcptrmethcall
+
+type T int
+
+func (*T) pm() int {
+	_ = x
+	return 0
+}
+
+func pf() *T {
+	return nil
+}
+
+var x = pf().pm() // ERROR "initialization loop|depends upon itself" 
diff --git a/test/fixedbugs/issue7690.go b/test/fixedbugs/issue7690.go
new file mode 100644
index 0000000..4ad9e86
--- /dev/null
+++ b/test/fixedbugs/issue7690.go
@@ -0,0 +1,49 @@
+// run
+
+// 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.
+
+// issue 7690 - Stack and other routines did not back up initial PC
+// into CALL instruction, instead reporting line number of next instruction,
+// which might be on a different line.
+
+package main
+
+import (
+	"bytes"
+	"regexp"
+	"runtime"
+	"strconv"
+)
+
+func main() {
+	buf1 := make([]byte, 1000)
+	buf2 := make([]byte, 1000)
+
+	runtime.Stack(buf1, false)      // CALL is last instruction on this line
+	n := runtime.Stack(buf2, false) // CALL is followed by load of result from stack
+
+	buf1 = buf1[:bytes.IndexByte(buf1, 0)]
+	buf2 = buf2[:n]
+
+	re := regexp.MustCompile(`(?m)^main\.main\(\)\n.*/issue7690.go:([0-9]+)`)
+	m1 := re.FindStringSubmatch(string(buf1))
+	if m1 == nil {
+		println("BUG: cannot find main.main in first trace")
+		return
+	}
+	m2 := re.FindStringSubmatch(string(buf2))
+	if m2 == nil {
+		println("BUG: cannot find main.main in second trace")
+		return
+	}
+
+	n1, _ := strconv.Atoi(m1[1])
+	n2, _ := strconv.Atoi(m2[1])
+	if n1+1 != n2 {
+		println("BUG: expect runtime.Stack on back to back lines, have", n1, n2)
+		println(string(buf1))
+		println(string(buf2))
+	}
+}
diff --git a/test/fixedbugs/issue7760.go b/test/fixedbugs/issue7760.go
new file mode 100644
index 0000000..cccae48
--- /dev/null
+++ b/test/fixedbugs/issue7760.go
@@ -0,0 +1,25 @@
+// errorcheck
+
+// 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.
+
+// Verify that pointers can't be used as constants.
+
+package main
+
+import "unsafe"
+
+type myPointer unsafe.Pointer
+
+const _ = unsafe.Pointer(uintptr(1)) // ERROR "is not (a )?constant"
+const _ = myPointer(uintptr(1)) // ERROR "is not (a )?constant"
+
+const _ = (*int)(unsafe.Pointer(uintptr(1))) // ERROR "is not (a )?constant"
+const _ = (*int)(myPointer(uintptr(1))) // ERROR "is not (a )?constant"
+
+const _ = uintptr(unsafe.Pointer(uintptr(1))) // ERROR "is not (a )?constant"
+const _ = uintptr(myPointer(uintptr(1))) // ERROR "is not (a )?constant"
+
+const _ = []byte("") // ERROR "is not (a )?constant"
+const _ = []rune("") // ERROR "is not (a )?constant"
diff --git a/test/fixedbugs/issue8017.go b/test/fixedbugs/issue8017.go
new file mode 100644
index 0000000..22056e0
--- /dev/null
+++ b/test/fixedbugs/issue8017.go
@@ -0,0 +1,26 @@
+// compile
+
+// 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.
+
+// Issues 8017 and 8058: walk modifies nodes generated
+// by slicelit and causes an internal error afterwards
+// when gen_as_init parses it back.
+
+package main
+
+func F() {
+	var ch chan int
+	select {
+	case <-ch:
+	case <-make(chan int, len([2][]int{([][]int{})[len(ch)], []int{}})):
+	}
+}
+
+func G() {
+	select {
+	case <-([1][]chan int{[]chan int{}})[0][0]:
+	default:
+	}
+}
diff --git a/test/fixedbugs/issue8060.dir/a.go b/test/fixedbugs/issue8060.dir/a.go
new file mode 100644
index 0000000..22ba69e
--- /dev/null
+++ b/test/fixedbugs/issue8060.dir/a.go
@@ -0,0 +1,7 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package a
+
+var A = []*[2][1]float64{}
diff --git a/test/fixedbugs/issue8060.dir/b.go b/test/fixedbugs/issue8060.dir/b.go
new file mode 100644
index 0000000..85fb6ec
--- /dev/null
+++ b/test/fixedbugs/issue8060.dir/b.go
@@ -0,0 +1,13 @@
+// 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 b
+
+import "a"
+
+var X = a.A
+
+func b() {
+	_ = [3][1]float64{}
+}
diff --git a/test/fixedbugs/issue8060.go b/test/fixedbugs/issue8060.go
new file mode 100644
index 0000000..ec52659
--- /dev/null
+++ b/test/fixedbugs/issue8060.go
@@ -0,0 +1,9 @@
+// compiledir
+
+// 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.
+
+// Issue 8060: internal compiler error.
+
+package ignored
diff --git a/test/fixedbugs/issue8074.go b/test/fixedbugs/issue8074.go
new file mode 100644
index 0000000..aedab24
--- /dev/null
+++ b/test/fixedbugs/issue8074.go
@@ -0,0 +1,16 @@
+// compile
+
+// 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.
+
+// issue 8074.
+// was "cannot take the address of 1"
+
+package main
+
+func main() {
+	a := make([]byte, 10)
+	m := make(map[float64][]byte)
+	go copy(a, m[1.0])
+}
diff --git a/test/fixedbugs/issue8079.go b/test/fixedbugs/issue8079.go
new file mode 100644
index 0000000..994999b
--- /dev/null
+++ b/test/fixedbugs/issue8079.go
@@ -0,0 +1,11 @@
+// compile
+
+// 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.
+
+// Issue 8079: gccgo crashes when compiling interface with blank type name.
+
+package p
+
+type _ interface{}
diff --git a/test/fixedbugs/issue8280.dir/a.go b/test/fixedbugs/issue8280.dir/a.go
new file mode 100644
index 0000000..588536e
--- /dev/null
+++ b/test/fixedbugs/issue8280.dir/a.go
@@ -0,0 +1,3 @@
+package a
+
+var Bar = func() (_ int) { return 0 }
diff --git a/test/fixedbugs/issue8280.dir/b.go b/test/fixedbugs/issue8280.dir/b.go
new file mode 100644
index 0000000..c46c554
--- /dev/null
+++ b/test/fixedbugs/issue8280.dir/b.go
@@ -0,0 +1,5 @@
+package b
+
+import "./a"
+
+var foo = a.Bar
diff --git a/test/fixedbugs/issue8280.go b/test/fixedbugs/issue8280.go
new file mode 100644
index 0000000..91256c8
--- /dev/null
+++ b/test/fixedbugs/issue8280.go
@@ -0,0 +1,9 @@
+// compiledir
+
+// 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.
+
+// Issue 8280: cannot import package exporting a func var returning a result named _
+
+package ignored
diff --git a/test/fixedbugs/issue8311.go b/test/fixedbugs/issue8311.go
new file mode 100644
index 0000000..dd92856
--- /dev/null
+++ b/test/fixedbugs/issue8311.go
@@ -0,0 +1,16 @@
+// errorcheck
+
+// 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.
+
+// issue 8311.
+// error for x++ should say x++ not x += 1
+
+package p
+
+func f() {
+	var x []byte
+	x++ // ERROR "invalid operation: x[+][+]"
+
+}
diff --git a/test/fixedbugs/issue8336.go b/test/fixedbugs/issue8336.go
new file mode 100644
index 0000000..26bdeab
--- /dev/null
+++ b/test/fixedbugs/issue8336.go
@@ -0,0 +1,29 @@
+// run
+
+// 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.
+
+// Issue 8336. Order of evaluation of receive channels in select.
+
+package main
+
+type X struct {
+	c chan int
+}
+
+func main() {
+	defer func() {
+		recover()
+	}()
+	var x *X
+	select {
+	case <-x.c: // should fault and panic before foo is called
+	case <-foo():
+	}
+}
+
+func foo() chan int {
+	println("BUG: foo must not be called")
+	return make(chan int)
+}
diff --git a/test/fixedbugs/issue8347.go b/test/fixedbugs/issue8347.go
new file mode 100644
index 0000000..0828ccf
--- /dev/null
+++ b/test/fixedbugs/issue8347.go
@@ -0,0 +1,27 @@
+// run
+
+// 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
+
+func main() {
+	c := make(chan bool, 1)
+	ok := true
+	for i := 0; i < 12; i++ {
+		select {
+		case _, ok = <-c:
+			if i < 10 && !ok {
+				panic("BUG")
+			}
+		default:
+		}
+		if i < 10 && !ok {
+			panic("BUG")
+		}
+		if i >= 10 && ok {
+			close(c)
+		}
+	}
+}
diff --git a/test/fixedbugs/issue8475.go b/test/fixedbugs/issue8475.go
new file mode 100644
index 0000000..e697945
--- /dev/null
+++ b/test/fixedbugs/issue8475.go
@@ -0,0 +1,25 @@
+// build
+
+// 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.
+
+// Issue 8745: comma-ok assignments should produce untyped bool as 2nd result.
+
+package main
+
+type mybool bool
+
+func main() {
+	var ok mybool
+	_ = ok
+
+	var i interface{}
+	_, ok = i.(int)
+
+	var m map[int]int
+	_, ok = m[0]
+
+	var c chan int
+	_, ok = <-c
+}
diff --git a/test/fixedbugs/issue8507.go b/test/fixedbugs/issue8507.go
new file mode 100644
index 0000000..00a14aa
--- /dev/null
+++ b/test/fixedbugs/issue8507.go
@@ -0,0 +1,16 @@
+// errorcheck
+
+// 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.
+
+// issue 8507
+// used to call algtype on invalid recursive type and get into infinite recursion
+
+package p
+
+type T struct{ T } // ERROR "invalid recursive type T"
+
+func f() {
+	println(T{} == T{})
+}
diff --git a/test/fixedbugs/issue8612.go b/test/fixedbugs/issue8612.go
new file mode 100644
index 0000000..93370cf
--- /dev/null
+++ b/test/fixedbugs/issue8612.go
@@ -0,0 +1,34 @@
+//compile
+
+// 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.
+
+// Gccgo had a bug comparing a struct or array value with an interface
+// values, when the struct or array was not addressable.
+
+package p
+
+type A [10]int
+
+type S struct {
+	i int
+}
+
+func F1() S {
+	return S{0}
+}
+
+func F2() A {
+	return A{}
+}
+
+func Cmp(v interface{}) bool {
+	if F1() == v {
+		return true
+	}
+	if F2() == v {
+		return true
+	}
+	return false
+}
diff --git a/test/fixedbugs/issue8761.go b/test/fixedbugs/issue8761.go
new file mode 100644
index 0000000..badf639
--- /dev/null
+++ b/test/fixedbugs/issue8761.go
@@ -0,0 +1,26 @@
+// compile
+
+// 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.
+
+// issue 8761
+// used to confuse code generator into using temporary before initialization.
+// caused 'variable live at entry' error in liveness analysis.
+
+package p
+
+func _() {
+	type C chan int
+	_ = [1][]C{[]C{make(chan int)}}
+}
+
+func _() {
+	type C interface{}
+	_ = [1][]C{[]C{recover()}}
+}
+
+func _() {
+	type C *int
+	_ = [1][]C{[]C{new(int)}}
+}
diff --git a/test/fixedbugs/issue8947.go b/test/fixedbugs/issue8947.go
new file mode 100644
index 0000000..f40c02e
--- /dev/null
+++ b/test/fixedbugs/issue8947.go
@@ -0,0 +1,53 @@
+// run
+
+// 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.
+
+// Some uses of zeroed constants in non-assignment
+// expressions broke with our more aggressive zeroing
+// of assignments (internal compiler errors).
+
+package main
+
+func f1() {
+	type T [2]int
+	p := T{0, 1}
+	switch p {
+	case T{0, 0}:
+		panic("wrong1")
+	case T{0, 1}:
+		// ok
+	default:
+		panic("wrong2")
+	}
+
+	if p == (T{0, 0}) {
+		panic("wrong3")
+	} else if p == (T{0, 1}) {
+		// ok
+	} else {
+		panic("wrong4")
+	}
+}
+
+type T struct {
+	V int
+}
+
+var X = T{}.V
+
+func f2() {
+	var x = T{}.V
+	if x != 0 {
+		panic("wrongx")
+	}
+	if X != 0 {
+		panic("wrongX")
+	}
+}
+
+func main() {
+	f1()
+	f2()
+}
diff --git a/test/fixedbugs/issue8961.go b/test/fixedbugs/issue8961.go
new file mode 100644
index 0000000..fbfb7e6
--- /dev/null
+++ b/test/fixedbugs/issue8961.go
@@ -0,0 +1,20 @@
+// run
+
+// 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.
+
+// Issue 8961. Empty composite literals to small globals were not filled in
+package main
+
+type small struct { a int }
+var foo small
+
+func main() {
+	foo.a = 1
+	foo = small{}
+	if foo.a != 0 {
+		println("expected foo.a to be 0, was", foo.a)
+		panic("composite literal not filled in")
+	}
+}
diff --git a/test/fixedbugs/issue9006.go b/test/fixedbugs/issue9006.go
new file mode 100644
index 0000000..c559f58
--- /dev/null
+++ b/test/fixedbugs/issue9006.go
@@ -0,0 +1,37 @@
+// run
+
+// 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
+
+type T1 struct {
+	X int
+}
+
+func NewT1(x int) T1 { return T1{x} }
+
+type T2 int
+
+func NewT2(x int) T2 { return T2(x) }
+
+func main() {
+	switch (T1{}) {
+	case NewT1(1):
+		panic("bad1")
+	case NewT1(0):
+		// ok
+	default:
+		panic("bad2")
+	}
+
+	switch T2(0) {
+	case NewT2(2):
+		panic("bad3")
+	case NewT2(0):
+		// ok
+	default:
+		panic("bad4")
+	}
+}
diff --git a/test/fixedbugs/issue9110.go b/test/fixedbugs/issue9110.go
new file mode 100644
index 0000000..7294633
--- /dev/null
+++ b/test/fixedbugs/issue9110.go
@@ -0,0 +1,90 @@
+// run
+
+// 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.
+
+// Scenario that used to leak arbitrarily many SudoG structs.
+// See golang.org/issue/9110.
+
+package main
+
+import (
+	"runtime"
+	"runtime/debug"
+	"sync"
+	"time"
+)
+
+func main() {
+	debug.SetGCPercent(1000000) // only GC when we ask for GC
+
+	var stats, stats1, stats2 runtime.MemStats
+
+	release := func() {}
+	for i := 0; i < 20; i++ {
+		if i == 10 {
+			// Should be warmed up by now.
+			runtime.ReadMemStats(&stats1)
+		}
+
+		c := make(chan int)
+		for i := 0; i < 10; i++ {
+			go func() {
+				select {
+				case <-c:
+				case <-c:
+				case <-c:
+				}
+			}()
+		}
+		time.Sleep(1 * time.Millisecond)
+		release()
+
+		close(c) // let select put its sudog's into the cache
+		time.Sleep(1 * time.Millisecond)
+
+		// pick up top sudog
+		var cond1 sync.Cond
+		var mu1 sync.Mutex
+		cond1.L = &mu1
+		go func() {
+			mu1.Lock()
+			cond1.Wait()
+			mu1.Unlock()
+		}()
+		time.Sleep(1 * time.Millisecond)
+
+		// pick up next sudog
+		var cond2 sync.Cond
+		var mu2 sync.Mutex
+		cond2.L = &mu2
+		go func() {
+			mu2.Lock()
+			cond2.Wait()
+			mu2.Unlock()
+		}()
+		time.Sleep(1 * time.Millisecond)
+
+		// put top sudog back
+		cond1.Broadcast()
+		time.Sleep(1 * time.Millisecond)
+
+		// drop cache on floor
+		runtime.GC()
+
+		// release cond2 after select has gotten to run
+		release = func() {
+			cond2.Broadcast()
+			time.Sleep(1 * time.Millisecond)
+		}
+	}
+
+	runtime.GC()
+
+	runtime.ReadMemStats(&stats2)
+
+	if int(stats2.HeapObjects)-int(stats1.HeapObjects) > 20 { // normally at most 1 or 2; was 300 with leak
+		print("BUG: object leak: ", stats.HeapObjects, " -> ", stats1.HeapObjects, " -> ", stats2.HeapObjects, "\n")
+	}
+}
diff --git a/test/interface/explicit.go b/test/interface/explicit.go
index 36fa1a4..b10d02f 100644
--- a/test/interface/explicit.go
+++ b/test/interface/explicit.go
@@ -83,12 +83,12 @@ var m4 = M(jj) // ERROR "invalid|wrong type for M method"
 
 
 type B1 interface {
-	_()
+	_() // ERROR "methods must have a unique non-blank name"
 }
 
 type B2 interface {
 	M()
-	_()
+	_() // ERROR "methods must have a unique non-blank name"
 }
 
 type T2 struct{}
diff --git a/test/interface/fail.go b/test/interface/fail.go
index 81eb6cb..d40a151 100644
--- a/test/interface/fail.go
+++ b/test/interface/fail.go
@@ -14,7 +14,6 @@ type I interface {
 
 func main() {
 	shouldPanic(p1)
-	shouldPanic(p2)
 }
 
 func p1() {
@@ -30,19 +29,6 @@ type S struct{}
 
 func (s *S) _() {}
 
-type B interface {
-	_()
-}
-
-func p2() {
-	var s *S
-	var b B
-	var e interface{}
-	e = s
-	b = e.(B)
-	_ = b
-}
-
 func shouldPanic(f func()) {
 	defer func() {
 		if recover() == nil {
diff --git a/test/linkx.go b/test/linkx.go
index 12d446f..151b6db 100644
--- a/test/linkx.go
+++ b/test/linkx.go
@@ -1,20 +1,18 @@
-// $G $D/$F.go && $L -X main.tbd hello $F.$A && ./$A.out
-
-// NOTE: This test is not run by 'run.go' and so not run by all.bash.
-// To run this test you must use the ./run shell script.
+// skip
 
 // Copyright 2012 The Go Authors.  All rights reserved.
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
 // Test the -X facility of the gc linker (6l etc.).
+// This test is run by linkx_run.go.
 
 package main
 
 var tbd string
+var overwrite string = "dibs"
 
 func main() {
-	if tbd != "hello" {
-		println("BUG: test/linkx", len(tbd), tbd)
-	}
+	println(tbd)
+	println(overwrite)
 }
diff --git a/test/linkx_run.go b/test/linkx_run.go
new file mode 100644
index 0000000..5b67ce7
--- /dev/null
+++ b/test/linkx_run.go
@@ -0,0 +1,33 @@
+// +build !nacl
+// run
+
+// 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.
+
+// Run the linkx test.
+
+package main
+
+import (
+	"fmt"
+	"os"
+	"os/exec"
+)
+
+func main() {
+	cmd := exec.Command("go", "run", "-ldflags=-X main.tbd hello -X main.overwrite trumped", "linkx.go")
+	out, err := cmd.CombinedOutput()
+	if err != nil {
+		fmt.Println(string(out))
+		fmt.Println(err)
+		os.Exit(1)
+	}
+
+	want := "hello\ntrumped\n"
+	got := string(out)
+	if got != want {
+		fmt.Printf("got %q want %q\n", got, want)
+		os.Exit(1)
+	}
+}
diff --git a/test/live.go b/test/live.go
index b4cced4..f15bb74 100644
--- a/test/live.go
+++ b/test/live.go
@@ -1,4 +1,4 @@
-// errorcheck -0 -l -live
+// errorcheck -0 -l -live -wb=0
 
 // Copyright 2014 The Go Authors.  All rights reserved.
 // Use of this source code is governed by a BSD-style
@@ -118,7 +118,10 @@ var i9 interface{}
 func f9() bool {
 	g8()
 	x := i9
-	return x != 99
+	// using complex number in comparison so that
+	// there is always a convT2E, no matter what the
+	// interface rules are.
+	return x != 99.0i // ERROR "live at call to convT2E: x"
 }
 
 // liveness formerly confused by UNDEF followed by RET,
@@ -138,7 +141,7 @@ var b bool
 
 // this used to have a spurious "live at entry to f11a: ~r0"
 func f11a() *int {
-	select { // ERROR "live at call to selectgo: autotmp"
+	select { // ERROR "live at call to newselect: autotmp" "live at call to selectgo: autotmp"
 	case <-c: // ERROR "live at call to selectrecv: autotmp"
 		return nil
 	case <-c: // ERROR "live at call to selectrecv: autotmp"
@@ -153,7 +156,7 @@ func f11b() *int {
 		// get to the bottom of the function.
 		// This used to have a spurious "live at call to printint: p".
 		print(1) // nothing live here!
-		select { // ERROR "live at call to selectgo: autotmp"
+		select { // ERROR "live at call to newselect: autotmp" "live at call to selectgo: autotmp"
 		case <-c: // ERROR "live at call to selectrecv: autotmp"
 			return nil
 		case <-c: // ERROR "live at call to selectrecv: autotmp"
@@ -170,7 +173,7 @@ func f11c() *int {
 		// Unlike previous, the cases in this select fall through,
 		// so we can get to the println, so p is not dead.
 		print(1) // ERROR "live at call to printint: p"
-		select { // ERROR "live at call to newselect: p" "live at call to selectgo: autotmp.* p"
+		select { // ERROR "live at call to newselect: autotmp.* p" "live at call to selectgo: autotmp.* p"
 		case <-c: // ERROR "live at call to selectrecv: autotmp.* p"
 		case <-c: // ERROR "live at call to selectrecv: autotmp.* p"
 		}
@@ -184,7 +187,7 @@ func f11c() *int {
 
 func f12() *int {
 	if b {
-		select{}
+		select {}
 	} else {
 		return nil
 	}
@@ -215,7 +218,7 @@ func f15() {
 	var x string
 	_ = &x
 	x = g15() // ERROR "live at call to g15: x"
-	print(x) // ERROR "live at call to printstring: x"
+	print(x)  // ERROR "live at call to printstring: x"
 }
 
 func g15() string
@@ -287,7 +290,7 @@ var ch chan *byte
 func f19() {
 	// dest temporary for channel receive.
 	var z *byte
-	
+
 	if b {
 		z = <-ch // ERROR "live at call to chanrecv1: autotmp_[0-9]+$"
 	}
@@ -348,21 +351,21 @@ func f25(b bool) {
 	var x string
 	_ = &x
 	x = g15() // ERROR "live at call to g15: x"
-	print(x) // ERROR "live at call to printstring: x"
+	print(x)  // ERROR "live at call to printstring: x"
 } // ERROR "live at call to deferreturn: x"
 
 func g25()
-	
+
 // non-escaping ... slices passed to function call should die on return,
 // so that the temporaries do not stack and do not cause ambiguously
 // live variables.
 
 func f26(b bool) {
 	if b {
-		print26(1,2,3) // ERROR "live at call to print26: autotmp_[0-9]+$"
+		print26((*int)(nil), (*int)(nil), (*int)(nil)) // ERROR "live at call to print26: autotmp_[0-9]+$"
 	}
-	print26(4,5,6) // ERROR "live at call to print26: autotmp_[0-9]+$"
-	print26(7,8,9) // ERROR "live at call to print26: autotmp_[0-9]+$"
+	print26((*int)(nil), (*int)(nil), (*int)(nil)) // ERROR "live at call to print26: autotmp_[0-9]+$"
+	print26((*int)(nil), (*int)(nil), (*int)(nil)) // ERROR "live at call to print26: autotmp_[0-9]+$"
 	println()
 }
 
@@ -374,10 +377,10 @@ func print26(...interface{})
 func f27(b bool) {
 	x := 0
 	if b {
-		call27(func() {x++}) // ERROR "live at call to call27: autotmp_[0-9]+$"
+		call27(func() { x++ }) // ERROR "live at call to call27: autotmp_[0-9]+$"
 	}
-	call27(func() {x++}) // ERROR "live at call to call27: autotmp_[0-9]+$"
-	call27(func() {x++}) // ERROR "live at call to call27: autotmp_[0-9]+$"
+	call27(func() { x++ }) // ERROR "live at call to call27: autotmp_[0-9]+$"
+	call27(func() { x++ }) // ERROR "live at call to call27: autotmp_[0-9]+$"
 	println()
 }
 
@@ -386,10 +389,10 @@ func f27(b bool) {
 func f27defer(b bool) {
 	x := 0
 	if b {
-		defer call27(func() {x++}) // ERROR "live at call to deferproc: autotmp_[0-9]+$" "live at call to deferreturn: autotmp_[0-9]+$"
+		defer call27(func() { x++ }) // ERROR "live at call to deferproc: autotmp_[0-9]+$" "live at call to deferreturn: autotmp_[0-9]+$"
 	}
-	defer call27(func() {x++}) // ERROR "live at call to deferproc: autotmp_[0-9]+ autotmp_[0-9]+$" "live at call to deferreturn: autotmp_[0-9]+ autotmp_[0-9]+$" "ambiguously live"
-	println() // ERROR "live at call to printnl: autotmp_[0-9]+ autotmp_[0-9]+$"
+	defer call27(func() { x++ }) // ERROR "live at call to deferproc: autotmp_[0-9]+ autotmp_[0-9]+$" "live at call to deferreturn: autotmp_[0-9]+ autotmp_[0-9]+$" "ambiguously live"
+	println()                    // ERROR "live at call to printnl: autotmp_[0-9]+ autotmp_[0-9]+$"
 } // ERROR "live at call to deferreturn: autotmp_[0-9]+ autotmp_[0-9]+$"
 
 // and newproc (go) escapes to the heap
@@ -397,9 +400,9 @@ func f27defer(b bool) {
 func f27go(b bool) {
 	x := 0
 	if b {
-		go call27(func() {x++}) // ERROR "live at call to new: &x" "live at call to newproc: &x$"
+		go call27(func() { x++ }) // ERROR "live at call to newobject: &x" "live at call to newproc: &x$"
 	}
-	go call27(func() {x++}) // ERROR "live at call to new: &x"
+	go call27(func() { x++ }) // ERROR "live at call to newobject: &x"
 	println()
 }
 
@@ -412,11 +415,11 @@ var s1, s2, s3, s4, s5, s6, s7, s8, s9, s10 string
 
 func f28(b bool) {
 	if b {
-		print(s1+s2+s3+s4+s5+s6+s7+s8+s9+s10) // ERROR "live at call to concatstrings: autotmp_[0-9]+$" "live at call to printstring: autotmp_[0-9]+$"
+		print(s1 + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9 + s10) // ERROR "live at call to concatstrings: autotmp_[0-9]+$" "live at call to printstring: autotmp_[0-9]+$"
 	}
-	print(s1+s2+s3+s4+s5+s6+s7+s8+s9+s10) // ERROR "live at call to concatstrings: autotmp_[0-9]+$" "live at call to printstring: autotmp_[0-9]+$"
-	print(s1+s2+s3+s4+s5+s6+s7+s8+s9+s10) // ERROR "live at call to concatstrings: autotmp_[0-9]+$" "live at call to printstring: autotmp_[0-9]+$"
-}	
+	print(s1 + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9 + s10) // ERROR "live at call to concatstrings: autotmp_[0-9]+$" "live at call to printstring: autotmp_[0-9]+$"
+	print(s1 + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9 + s10) // ERROR "live at call to concatstrings: autotmp_[0-9]+$" "live at call to printstring: autotmp_[0-9]+$"
+}
 
 // map iterator should die on end of range loop
 
@@ -461,10 +464,10 @@ func f31(b1, b2, b3 bool) {
 		g31("a") // ERROR "live at call to convT2E: autotmp_[0-9]+$" "live at call to g31: autotmp_[0-9]+$"
 	}
 	if b2 {
-		h31("b") // ERROR "live at call to new: autotmp_[0-9]+$" "live at call to convT2E: autotmp_[0-9]+ autotmp_[0-9]+$" "live at call to h31: autotmp_[0-9]+$"
+		h31("b") // ERROR "live at call to newobject: autotmp_[0-9]+$" "live at call to convT2E: autotmp_[0-9]+ autotmp_[0-9]+$" "live at call to h31: autotmp_[0-9]+$"
 	}
 	if b3 {
-		panic("asdf") // ERROR "live at call to convT2E: autotmp_[0-9]+$" "live at call to panic: autotmp_[0-9]+$"
+		panic("asdf") // ERROR "live at call to convT2E: autotmp_[0-9]+$" "live at call to gopanic: autotmp_[0-9]+$"
 	}
 	print(b3)
 }
@@ -583,14 +586,16 @@ func f39a() (x []int) {
 }
 
 func f39b() (x [10]*int) {
-	x = [10]*int{new(int)} // ERROR "live at call to new: x"
-	println() // ERROR "live at call to printnl: x"
+	x = [10]*int{}
+	x[0] = new(int) // ERROR "live at call to newobject: x"
+	println()       // ERROR "live at call to printnl: x"
 	return x
 }
 
 func f39c() (x [10]*int) {
-	x = [10]*int{new(int)} // ERROR "live at call to new: x"
-	println() // ERROR "live at call to printnl: x"
+	x = [10]*int{}
+	x[0] = new(int) // ERROR "live at call to newobject: x"
+	println()       // ERROR "live at call to printnl: x"
 	return
 }
 
@@ -602,9 +607,8 @@ type T40 struct {
 }
 
 func newT40() *T40 {
-	ret := T40{ // ERROR "live at call to makemap: &ret"
-		make(map[int]int), 
-	}
+	ret := T40{}
+	ret.m = make(map[int]int) // ERROR "live at call to makemap: &ret"
 	return &ret
 }
 
@@ -615,9 +619,8 @@ func bad40() {
 }
 
 func good40() {
-	ret := T40{ // ERROR "live at call to makemap: ret"
-		make(map[int]int),
-	}
+	ret := T40{}
+	ret.m = make(map[int]int) // ERROR "live at call to makemap: ret"
 	t := &ret
 	println() // ERROR "live at call to printnl: ret"
 	_ = t
diff --git a/test/live2.go b/test/live2.go
index 1e32794..ef6ad99 100644
--- a/test/live2.go
+++ b/test/live2.go
@@ -1,4 +1,4 @@
-// errorcheck -0 -live
+// errorcheck -0 -live -wb=0
 
 // Copyright 2014 The Go Authors.  All rights reserved.
 // Use of this source code is governed by a BSD-style
@@ -17,9 +17,8 @@ type T40 struct {
 }
 
 func newT40() *T40 {
-	ret := T40{ // ERROR "live at call to makemap: &ret"
-		make(map[int]int),
-	}
+	ret := T40{}
+	ret.m = make(map[int]int) // ERROR "live at call to makemap: &ret"
 	return &ret
 }
 
@@ -30,9 +29,8 @@ func bad40() {
 }
 
 func good40() {
-	ret := T40{ // ERROR "live at call to makemap: ret"
-		make(map[int]int),
-	}
+	ret := T40{}
+	ret.m = make(map[int]int) // ERROR "live at call to makemap: ret"
 	t := &ret
 	println() // ERROR "live at call to printnl: ret"
 	_ = t
diff --git a/test/map.go b/test/map.go
index 485e743..2c1cf8a 100644
--- a/test/map.go
+++ b/test/map.go
@@ -5,7 +5,7 @@
 // license that can be found in the LICENSE file.
 
 // Test maps, almost exhaustively.
-// NaN complexity test is in mapnan.go.
+// Complexity (linearity) test is in maplinear.go.
 
 package main
 
diff --git a/test/maplinear.go b/test/maplinear.go
new file mode 100644
index 0000000..34d0914
--- /dev/null
+++ b/test/maplinear.go
@@ -0,0 +1,172 @@
+// +build darwin linux
+// run
+
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Test that maps don't go quadratic for NaNs and other values.
+
+package main
+
+import (
+	"fmt"
+	"math"
+	"time"
+)
+
+// checkLinear asserts that the running time of f(n) is in O(n).
+// tries is the initial number of iterations.
+func checkLinear(typ string, tries int, f func(n int)) {
+	// Depending on the machine and OS, this test might be too fast
+	// to measure with accurate enough granularity. On failure,
+	// make it run longer, hoping that the timing granularity
+	// is eventually sufficient.
+
+	timeF := func(n int) time.Duration {
+		t1 := time.Now()
+		f(n)
+		return time.Since(t1)
+	}
+
+	t0 := time.Now()
+
+	n := tries
+	fails := 0
+	for {
+		t1 := timeF(n)
+		t2 := timeF(2 * n)
+
+		// should be 2x (linear); allow up to 3x
+		if t2 < 3*t1 {
+			if false {
+				fmt.Println(typ, "\t", time.Since(t0))
+			}
+			return
+		}
+		// If n ops run in under a second and the ratio
+		// doesn't work out, make n bigger, trying to reduce
+		// the effect that a constant amount of overhead has
+		// on the computed ratio.
+		if t1 < 1*time.Second {
+			n *= 2
+			continue
+		}
+		// Once the test runs long enough for n ops,
+		// try to get the right ratio at least once.
+		// If five in a row all fail, give up.
+		if fails++; fails >= 5 {
+			panic(fmt.Sprintf("%s: too slow: %d inserts: %v; %d inserts: %v\n",
+				typ, n, t1, 2*n, t2))
+		}
+	}
+}
+
+type I interface {
+	f()
+}
+
+type C int
+
+func (C) f() {}
+
+func main() {
+	// NaNs. ~31ms on a 1.6GHz Zeon.
+	checkLinear("NaN", 30000, func(n int) {
+		m := map[float64]int{}
+		nan := math.NaN()
+		for i := 0; i < n; i++ {
+			m[nan] = 1
+		}
+		if len(m) != n {
+			panic("wrong size map after nan insertion")
+		}
+	})
+
+	// ~6ms on a 1.6GHz Zeon.
+	checkLinear("eface", 10000, func(n int) {
+		m := map[interface{}]int{}
+		for i := 0; i < n; i++ {
+			m[i] = 1
+		}
+	})
+
+	// ~7ms on a 1.6GHz Zeon.
+	// Regression test for CL 119360043.
+	checkLinear("iface", 10000, func(n int) {
+		m := map[I]int{}
+		for i := 0; i < n; i++ {
+			m[C(i)] = 1
+		}
+	})
+
+	// ~6ms on a 1.6GHz Zeon.
+	checkLinear("int", 10000, func(n int) {
+		m := map[int]int{}
+		for i := 0; i < n; i++ {
+			m[i] = 1
+		}
+	})
+
+	// ~18ms on a 1.6GHz Zeon.
+	checkLinear("string", 10000, func(n int) {
+		m := map[string]int{}
+		for i := 0; i < n; i++ {
+			m[fmt.Sprint(i)] = 1
+		}
+	})
+
+	// ~6ms on a 1.6GHz Zeon.
+	checkLinear("float32", 10000, func(n int) {
+		m := map[float32]int{}
+		for i := 0; i < n; i++ {
+			m[float32(i)] = 1
+		}
+	})
+
+	// ~6ms on a 1.6GHz Zeon.
+	checkLinear("float64", 10000, func(n int) {
+		m := map[float64]int{}
+		for i := 0; i < n; i++ {
+			m[float64(i)] = 1
+		}
+	})
+
+	// ~22ms on a 1.6GHz Zeon.
+	checkLinear("complex64", 10000, func(n int) {
+		m := map[complex64]int{}
+		for i := 0; i < n; i++ {
+			m[complex(float32(i), float32(i))] = 1
+		}
+	})
+
+	// ~32ms on a 1.6GHz Zeon.
+	checkLinear("complex128", 10000, func(n int) {
+		m := map[complex128]int{}
+		for i := 0; i < n; i++ {
+			m[complex(float64(i), float64(i))] = 1
+		}
+	})
+
+	// ~70ms on a 1.6GHz Zeon.
+	// The iterate/delete idiom currently takes expected
+	// O(n lg n) time.  Fortunately, the checkLinear test
+	// leaves enough wiggle room to include n lg n time
+	// (it actually tests for O(n^log_2(3)).
+	// To prevent false positives, average away variation
+	// by doing multiple rounds within a single run.
+	checkLinear("iterdelete", 2500, func(n int) {
+		for round := 0; round < 4; round++ {
+			m := map[int]int{}
+			for i := 0; i < n; i++ {
+				m[i] = i
+			}
+			for i := 0; i < n; i++ {
+				for k := range m {
+					delete(m, k)
+					break
+				}
+			}
+		}
+	})
+}
diff --git a/test/mapnan.go b/test/mapnan.go
deleted file mode 100644
index f081cab..0000000
--- a/test/mapnan.go
+++ /dev/null
@@ -1,56 +0,0 @@
-// +build darwin linux
-// run
-
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Test that NaNs in maps don't go quadratic.
-
-package main
-
-import (
-	"fmt"
-	"math"
-	"time"
-)
-
-func main() {
-
-	// Test that NaNs in maps don't go quadratic.
-	t := func(n int) time.Duration {
-		t1 := time.Now()
-		m := map[float64]int{}
-		nan := math.NaN()
-		for i := 0; i < n; i++ {
-			m[nan] = 1
-		}
-		if len(m) != n {
-			panic("wrong size map after nan insertion")
-		}
-		return time.Since(t1)
-	}
-
-	// Depending on the machine and OS, this test might be too fast
-	// to measure with accurate enough granularity. On failure,
-	// make it run longer, hoping that the timing granularity
-	// is eventually sufficient.
-
-	n := 30000 // ~8ms user time on a Mid 2011 MacBook Air (1.8 GHz Core i7)
-	fails := 0
-	for {
-		t1 := t(n)
-		t2 := t(2 * n)
-		// should be 2x (linear); allow up to 3x
-		if t2 < 3*t1 {
-			return
-		}
-		fails++
-		if fails == 6 {
-			panic(fmt.Sprintf("too slow: %d inserts: %v; %d inserts: %v\n", n, t1, 2*n, t2))
-		}
-		if fails < 4 {
-			n *= 2
-		}
-	}
-}
diff --git a/test/named1.go b/test/named1.go
index 62b874c..febad64 100644
--- a/test/named1.go
+++ b/test/named1.go
@@ -41,21 +41,21 @@ func main() {
 	asBool(1 != 2) // ok now
 	asBool(i < j)  // ok now
 
-	_, b = m[2] // ERROR "cannot .* bool.*type Bool"
+	_, b = m[2] // ok now
 
 	var inter interface{}
-	_, b = inter.(Map) // ERROR "cannot .* bool.*type Bool"
+	_, b = inter.(Map) // ok now
 	_ = b
 
 	var minter interface {
 		M()
 	}
-	_, b = minter.(Map) // ERROR "cannot .* bool.*type Bool"
+	_, b = minter.(Map) // ok now
 	_ = b
 
 	_, bb := <-c
 	asBool(bb) // ERROR "cannot use.*type bool.*as type Bool"
-	_, b = <-c // ERROR "cannot .* bool.*type Bool"
+	_, b = <-c // ok now
 	_ = b
 
 	asString(String(slice)) // ok
diff --git a/test/nosplit.go b/test/nosplit.go
index 35aa510..953a5bf 100644
--- a/test/nosplit.go
+++ b/test/nosplit.go
@@ -12,6 +12,7 @@ import (
 	"bytes"
 	"fmt"
 	"io/ioutil"
+	"log"
 	"os"
 	"os/exec"
 	"path/filepath"
@@ -190,7 +191,6 @@ func main() {
 		return
 	}
 	defer os.RemoveAll(dir)
-	ioutil.WriteFile(filepath.Join(dir, "main.go"), []byte("package main\nfunc main()\n"), 0666)
 
 	tests = strings.Replace(tests, "\t", " ", -1)
 	tests = commentRE.ReplaceAllString(tests, "")
@@ -230,6 +230,9 @@ TestCases:
 			continue
 		}
 
+		var gobuf bytes.Buffer
+		fmt.Fprintf(&gobuf, "package main\n")
+
 		var buf bytes.Buffer
 		if goarch == "arm" {
 			fmt.Fprintf(&buf, "#define CALL BL\n#define REGISTER (R0)\n")
@@ -242,7 +245,7 @@ TestCases:
 			if line == "" {
 				continue
 			}
-			for _, subline := range strings.Split(line, ";") {
+			for i, subline := range strings.Split(line, ";") {
 				subline = strings.TrimSpace(subline)
 				if subline == "" {
 					continue
@@ -255,6 +258,14 @@ TestCases:
 				}
 				name := m[1]
 				size, _ := strconv.Atoi(m[2])
+
+				// The limit was originally 128 but is now 384.
+				// Instead of rewriting the test cases above, adjust
+				// the first stack frame to use up the extra 32 bytes.
+				if i == 0 {
+					size += 384 - 128
+				}
+
 				if goarch == "amd64" && size%8 == 4 {
 					continue TestCases
 				}
@@ -269,11 +280,17 @@ TestCases:
 				body = callRE.ReplaceAllString(body, "CALL ·$1(SB);")
 				body = callindRE.ReplaceAllString(body, "CALL REGISTER;")
 
+				fmt.Fprintf(&gobuf, "func %s()\n", name)
 				fmt.Fprintf(&buf, "TEXT ·%s(SB)%s,$%d-0\n\t%s\n\tRET\n\n", name, nosplit, size, body)
 			}
 		}
 
-		ioutil.WriteFile(filepath.Join(dir, "asm.s"), buf.Bytes(), 0666)
+		if err := ioutil.WriteFile(filepath.Join(dir, "asm.s"), buf.Bytes(), 0666); err != nil {
+			log.Fatal(err)
+		}
+		if err := ioutil.WriteFile(filepath.Join(dir, "main.go"), gobuf.Bytes(), 0666); err != nil {
+			log.Fatal(err)
+		}
 
 		cmd := exec.Command("go", "build")
 		cmd.Dir = dir
diff --git a/test/print.go b/test/print.go
new file mode 100644
index 0000000..466e19f
--- /dev/null
+++ b/test/print.go
@@ -0,0 +1,42 @@
+// cmpout
+
+// 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 internal print routines that are generated
+// by the print builtin.  This test is not exhaustive,
+// we're just checking that the formatting is correct.
+
+package main
+
+func main() {
+	println((interface{})(nil)) // printeface
+	println((interface {        // printiface
+		f()
+	})(nil))
+	println((map[int]int)(nil)) // printpointer
+	println(([]int)(nil))       // printslice
+	println(int64(-7))          // printint
+	println(uint64(7))          // printuint
+	println(8.0)                // printfloat
+	println(complex(9.0, 10.0)) // printcomplex
+	println(true)               // printbool
+	println(false)              // printbool
+	println("hello")            // printstring
+	println("one", "two")       // printsp
+
+	// test goprintf
+	defer println((interface{})(nil))
+	defer println((interface{f()})(nil))
+	defer println((map[int]int)(nil))
+	defer println(([]int)(nil))
+	defer println(int64(-11))
+	defer println(uint64(12))
+	defer println(13.0)
+	defer println(complex(14.0, 15.0))
+	defer println(true)
+	defer println(false)
+	defer println("hello")
+	defer println("one", "two")
+}
diff --git a/test/print.out b/test/print.out
new file mode 100644
index 0000000..266fe5d
--- /dev/null
+++ b/test/print.out
@@ -0,0 +1,24 @@
+(0x0,0x0)
+(0x0,0x0)
+0x0
+[0/0]0x0
+-7
+7
++8.000000e+000
+(+9.000000e+000+1.000000e+001i)
+true
+false
+hello
+one two
+one two
+hello
+false
+true
+(+1.400000e+001+1.500000e+001i)
++1.300000e+001
+12
+-11
+[0/0]0x0
+0x0
+(0x0,0x0)
+(0x0,0x0)
diff --git a/test/range.go b/test/range.go
index 8effbe9..af89eda 100644
--- a/test/range.go
+++ b/test/range.go
@@ -32,6 +32,13 @@ func testchan() {
 		println("Wanted lowercase alphabet; got", s)
 		panic("fail")
 	}
+	n := 0
+	for range seq('a', 'z') {
+		n++
+	}
+	if n != 26 {
+		println("testchan wrong count", n, "want 26")
+	}
 }
 
 // test that range over slice only evaluates
@@ -87,6 +94,22 @@ func testslice1() {
 	}
 }
 
+func testslice2() {
+	n := 0
+	nmake = 0
+	for range makeslice() {
+		n++
+	}
+	if nmake != 1 {
+		println("range called makeslice", nmake, "times")
+		panic("fail")
+	}
+	if n != 5 {
+		println("wrong count ranging over makeslice", n)
+		panic("fail")
+	}
+}
+
 // test that range over array only evaluates
 // the expression after "range" once.
 
@@ -127,6 +150,22 @@ func testarray1() {
 	}
 }
 
+func testarray2() {
+	n := 0
+	nmake = 0
+	for range makearray() {
+		n++
+	}
+	if nmake != 1 {
+		println("range called makearray", nmake, "times")
+		panic("fail")
+	}
+	if n != 5 {
+		println("wrong count ranging over makearray", n)
+		panic("fail")
+	}
+}
+
 func makearrayptr() *[5]int {
 	nmake++
 	return &[5]int{1, 2, 3, 4, 5}
@@ -176,6 +215,22 @@ func testarrayptr1() {
 	}
 }
 
+func testarrayptr2() {
+	n := 0
+	nmake = 0
+	for range makearrayptr() {
+		n++
+	}
+	if nmake != 1 {
+		println("range called makearrayptr", nmake, "times")
+		panic("fail")
+	}
+	if n != 5 {
+		println("wrong count ranging over makearrayptr", n)
+		panic("fail")
+	}
+}
+
 // test that range over string only evaluates
 // the expression after "range" once.
 
@@ -216,6 +271,22 @@ func teststring1() {
 	}
 }
 
+func teststring2() {
+	n := 0
+	nmake = 0
+	for range makestring() {
+		n++
+	}
+	if nmake != 1 {
+		println("range called makestring", nmake, "times")
+		panic("fail")
+	}
+	if n != 5 {
+		println("wrong count ranging over makestring", n)
+		panic("fail")
+	}
+}
+
 // test that range over map only evaluates
 // the expression after "range" once.
 
@@ -256,6 +327,22 @@ func testmap1() {
 	}
 }
 
+func testmap2() {
+	n := 0
+	nmake = 0
+	for range makemap() {
+		n++
+	}
+	if nmake != 1 {
+		println("range called makemap", nmake, "times")
+		panic("fail")
+	}
+	if n != 5 {
+		println("wrong count ranging over makemap", n)
+		panic("fail")
+	}
+}
+
 // test that range evaluates the index and value expressions
 // exactly once per iteration.
 
@@ -298,13 +385,18 @@ func main() {
 	testchan()
 	testarray()
 	testarray1()
+	testarray2()
 	testarrayptr()
 	testarrayptr1()
+	testarrayptr2()
 	testslice()
 	testslice1()
+	testslice2()
 	teststring()
 	teststring1()
+	teststring2()
 	testmap()
 	testmap1()
+	testmap2()
 	testcalls()
 }
diff --git a/test/recover.go b/test/recover.go
index 071be66..f92c15c 100644
--- a/test/recover.go
+++ b/test/recover.go
@@ -47,6 +47,7 @@ func main() {
 		test11reflect1()
 		test11reflect2()
 	}
+	test111()
 	test12()
 	if !interp {
 		test12reflect1()
@@ -62,6 +63,7 @@ func main() {
 		test14reflect1()
 		test14reflect2()
 		test15()
+		test16()
 	}
 }
 
@@ -77,7 +79,7 @@ func mustRecoverBody(v1, v2, v3, x interface{}) {
 	}
 	v = v2
 	if v == nil {
-		println("missing recover")
+		println("missing recover", x.(int))
 		die() // panic is useless here
 	}
 	if v != x {
@@ -113,10 +115,23 @@ func withoutRecover() {
 	mustNotRecover() // because it's a sub-call
 }
 
+func withoutRecoverRecursive(n int) {
+	if n == 0 {
+		withoutRecoverRecursive(1)
+	} else {
+		v := recover()
+		if v != nil {
+			println("spurious recover (recursive)", v)
+			die()
+		}
+	}
+}
+
 func test1() {
-	defer mustNotRecover() // because mustRecover will squelch it
-	defer mustRecover(1)   // because of panic below
-	defer withoutRecover() // should be no-op, leaving for mustRecover to find
+	defer mustNotRecover()           // because mustRecover will squelch it
+	defer mustRecover(1)             // because of panic below
+	defer withoutRecover()           // should be no-op, leaving for mustRecover to find
+	defer withoutRecoverRecursive(0) // ditto
 	panic(1)
 }
 
@@ -137,7 +152,7 @@ func test1WithClosures() {
 		mustNotRecover()
 		v := recover()
 		if v == nil {
-			println("missing recover")
+			println("missing recover", x.(int))
 			die()
 		}
 		if v != x {
@@ -406,6 +421,49 @@ func test11reflect2() {
 	panic(11)
 }
 
+// tiny receiver, so basic wrapper in i.M()
+type T3deeper struct{}
+
+func (T3deeper) M() {
+	badstate() // difference from T3
+	mustRecoverBody(doubleRecover(), recover(), recover(), 111)
+}
+
+func test111() {
+	var i I = T3deeper{}
+	defer i.M()
+	panic(111)
+}
+
+type Tiny struct{}
+
+func (Tiny) M() {
+	panic(112)
+}
+
+// i.M is a wrapper, and i.M panics.
+//
+// This is a torture test for an old implementation of recover that
+// tried to deal with wrapper functions by doing some argument
+// positioning math on both entry and exit. Doing anything on exit
+// is a problem because sometimes functions exit via panic instead
+// of an ordinary return, so panic would have to know to do the
+// same math when unwinding the stack. It gets complicated fast.
+// This particular test never worked with the old scheme, because
+// panic never did the right unwinding math.
+//
+// The new scheme adjusts Panic.argp on entry to a wrapper.
+// It has no exit work, so if a wrapper is interrupted by a panic,
+// there's no cleanup that panic itself must do.
+// This test just works now.
+func badstate() {
+	defer func() {
+		recover()
+	}()
+	var i I = Tiny{}
+	i.M()
+}
+
 // large receiver, so basic wrapper in i.M()
 type T4 [2]string
 
@@ -503,3 +561,27 @@ func test15() {
 	defer f()
 	panic(15)
 }
+
+func reflectFunc2(args []reflect.Value) (results []reflect.Value) {
+	// This will call reflectFunc3
+	args[0].Interface().(func())()
+	return nil
+}
+
+func reflectFunc3(args []reflect.Value) (results []reflect.Value) {
+	if v := recover(); v != nil {
+		println("spurious recover", v)
+		die()
+	}
+	return nil
+}
+
+func test16() {
+	defer mustRecover(16)
+
+	f2 := reflect.MakeFunc(reflect.TypeOf((func(func()))(nil)), reflectFunc2).Interface().(func(func()))
+	f3 := reflect.MakeFunc(reflect.TypeOf((func())(nil)), reflectFunc3).Interface().(func())
+	defer f2(f3)
+
+	panic(16)
+}
diff --git a/test/run.go b/test/run.go
index a8d4baa..e8ec2df 100644
--- a/test/run.go
+++ b/test/run.go
@@ -45,7 +45,7 @@ var (
 
 	// letter is the build.ArchChar
 	letter string
-	
+
 	goos, goarch string
 
 	// dirs are the directories to look for *.go files in.
@@ -71,8 +71,9 @@ const maxTests = 5000
 func main() {
 	flag.Parse()
 
-	goos = os.Getenv("GOOS")
-	goarch = os.Getenv("GOARCH")
+	goos = getenv("GOOS", runtime.GOOS)
+	goarch = getenv("GOARCH", runtime.GOARCH)
+
 	findExecCmd()
 
 	// Disable parallelism if printing or if using a simulator.
@@ -121,7 +122,7 @@ func main() {
 	failed := false
 	resCount := map[string]int{}
 	for _, test := range tests {
-		<-test.donec		
+		<-test.donec
 		status := "ok  "
 		errStr := ""
 		if _, isSkip := test.err.(skipError); isSkip {
@@ -225,8 +226,8 @@ func check(err error) {
 type test struct {
 	dir, gofile string
 	donec       chan bool // closed when done
-	dt time.Duration
-	
+	dt          time.Duration
+
 	src    string
 	action string // "compile", "build", etc.
 
@@ -625,6 +626,7 @@ func (t *test) run() {
 		out, err := runcmd(append([]string{"go", "run", t.goFileName()}, args...)...)
 		if err != nil {
 			t.err = err
+			return
 		}
 		if strings.Replace(string(out), "\r\n", "\n", -1) != t.expectedOutput() {
 			t.err = fmt.Errorf("incorrect output\n%s", out)
@@ -639,6 +641,7 @@ func (t *test) run() {
 		out, err := runcmd(append([]string{"go", "run", t.goFileName()}, args...)...)
 		if err != nil {
 			t.err = err
+			return
 		}
 		tfile := filepath.Join(t.tempDir, "tmp__.go")
 		if err := ioutil.WriteFile(tfile, out, 0666); err != nil {
@@ -648,6 +651,7 @@ func (t *test) run() {
 		out, err = runcmd("go", "run", tfile)
 		if err != nil {
 			t.err = err
+			return
 		}
 		if string(out) != t.expectedOutput() {
 			t.err = fmt.Errorf("incorrect output\n%s", out)
@@ -658,6 +662,7 @@ func (t *test) run() {
 		out, err := runcmd(append([]string{"go", "run", t.goFileName()}, args...)...)
 		if err != nil {
 			t.err = err
+			return
 		}
 		tfile := filepath.Join(t.tempDir, "tmp__.go")
 		err = ioutil.WriteFile(tfile, out, 0666)
@@ -700,7 +705,7 @@ func findExecCmd() []string {
 		execCmd = []string{path}
 	}
 	return execCmd
-}	
+}
 
 func (t *test) String() string {
 	return filepath.Join(t.dir, t.gofile)
@@ -834,11 +839,11 @@ func partitionStrings(prefix string, strs []string) (matched, unmatched []string
 }
 
 type wantedError struct {
-	reStr    string
-	re       *regexp.Regexp
-	lineNum  int
-	file     string
-	prefix string
+	reStr   string
+	re      *regexp.Regexp
+	lineNum int
+	file    string
+	prefix  string
 }
 
 var (
@@ -889,11 +894,11 @@ func (t *test) wantedErrors(file, short string) (errs []wantedError) {
 			}
 			prefix := fmt.Sprintf("%s:%d", short, lineNum)
 			errs = append(errs, wantedError{
-				reStr:    rx,
-				re:       re,
-				prefix: prefix,
-				lineNum:  lineNum,
-				file:     short,
+				reStr:   rx,
+				re:      re,
+				prefix:  prefix,
+				lineNum: lineNum,
+				file:    short,
 			})
 		}
 	}
@@ -902,8 +907,6 @@ func (t *test) wantedErrors(file, short string) (errs []wantedError) {
 }
 
 var skipOkay = map[string]bool{
-	"linkx.go":            true, // like "run" but wants linker flags
-	"sinit.go":            true,
 	"fixedbugs/bug248.go": true, // combines errorcheckdir and rundir in the same dir.
 	"fixedbugs/bug302.go": true, // tests both .$O and .a imports.
 	"fixedbugs/bug345.go": true, // needs the appropriate flags in gc invocation.
@@ -972,3 +975,11 @@ func envForDir(dir string) []string {
 	env = append(env, "PWD="+dir)
 	return env
 }
+
+func getenv(key, def string) string {
+	value := os.Getenv(key)
+	if value != "" {
+		return value
+	}
+	return def
+}
diff --git a/test/shift1.go b/test/shift1.go
index 44a3792..04f5321 100644
--- a/test/shift1.go
+++ b/test/shift1.go
@@ -238,4 +238,6 @@ func _() {
 	z = (1. << s) << (1 << s)    // ERROR "non-integer|type complex128"
 	z = (1. << s) << (1. << s)   // ERROR "non-integer|type complex128"
 	z = (1.1 << s) << (1.1 << s) // ERROR "invalid|truncated|complex128"
+
+	_, _, _ = x, y, z
 }
diff --git a/test/sinit.go b/test/sinit.go
index 5e50e11..df1a4cc 100644
--- a/test/sinit.go
+++ b/test/sinit.go
@@ -1,7 +1,4 @@
-// $G -S $D/$F.go | egrep initdone >/dev/null && echo BUG sinit || true
-
-// NOTE: This test is not run by 'run.go' and so not run by all.bash.
-// To run this test you must use the ./run shell script.
+// skip
 
 // Copyright 2010 The Go Authors.  All rights reserved.
 // Use of this source code is governed by a BSD-style
@@ -9,6 +6,7 @@
 
 // Test that many initializations can be done at link time and
 // generate no executable init functions.
+// This test is run by sinit_run.go.
 
 package p
 
@@ -106,20 +104,27 @@ var answers = [...]int{
 }
 
 var (
-	copy_zero = zero
-	copy_one = one
-	copy_pi = pi
-	copy_slice = slice
+	copy_zero     = zero
+	copy_one      = one
+	copy_pi       = pi
+	copy_slice    = slice
 	copy_sliceInt = sliceInt
-	copy_hello = hello
-	copy_bytes = bytes
+	copy_hello    = hello
+
+	// Could be handled without an initialization function, but
+	// requires special handling for "a = []byte("..."); b = a"
+	// which is not a likely case.
+	// copy_bytes = bytes
+	// https://codereview.appspot.com/171840043 is one approach to
+	// make this special case work.
+
 	copy_four, copy_five = four, five
-	copy_x, copy_y = x, y
-	copy_nilslice = nilslice
-	copy_nilmap = nilmap
-	copy_nilfunc = nilfunc
-	copy_nilchan = nilchan
-	copy_nilptr = nilptr
+	copy_x, copy_y       = x, y
+	copy_nilslice        = nilslice
+	copy_nilmap          = nilmap
+	copy_nilfunc         = nilfunc
+	copy_nilchan         = nilchan
+	copy_nilptr          = nilptr
 )
 
 var copy_a = a
@@ -172,7 +177,7 @@ var sx []int
 var s0 = []int{0, 0, 0}
 var s1 = []int{1, 2, 3}
 
-func fi() int
+func fi() int { return 1 }
 
 var ax [10]int
 var a0 = [10]int{0, 0, 0}
@@ -202,58 +207,66 @@ var pt0b = &T{X: 0}
 var pt1 = &T{X: 1, Y: 2}
 var pt1a = &T{3, 4}
 
-var copy_bx = bx
+// The checks similar to
+// var copy_bx = bx
+// are commented out.  The  compiler no longer statically initializes them.
+// See issue 7665 and https://codereview.appspot.com/93200044.
+// If https://codereview.appspot.com/169040043 is submitted, and this
+// test is changed to pass -complete to the compiler, then we can
+// uncomment the copy lines again.
+
+// var copy_bx = bx
 var copy_b0 = b0
 var copy_b1 = b1
 
-var copy_fx = fx
+// var copy_fx = fx
 var copy_f0 = f0
 var copy_f1 = f1
 
-var copy_gx = gx
+// var copy_gx = gx
 var copy_g0 = g0
 var copy_g1 = g1
 
-var copy_ix = ix
+// var copy_ix = ix
 var copy_i0 = i0
 var copy_i1 = i1
 
-var copy_jx = jx
+// var copy_jx = jx
 var copy_j0 = j0
 var copy_j1 = j1
 
-var copy_cx = cx
+// var copy_cx = cx
 var copy_c0 = c0
 var copy_c1 = c1
 
-var copy_dx = dx
+// var copy_dx = dx
 var copy_d0 = d0
 var copy_d1 = d1
 
-var copy_sx = sx
+// var copy_sx = sx
 var copy_s0 = s0
 var copy_s1 = s1
 
-var copy_ax = ax
+// var copy_ax = ax
 var copy_a0 = a0
 var copy_a1 = a1
 
-var copy_tx = tx
+// var copy_tx = tx
 var copy_t0 = t0
 var copy_t0a = t0a
 var copy_t0b = t0b
 var copy_t1 = t1
 var copy_t1a = t1a
 
-var copy_psx = psx
+// var copy_psx = psx
 var copy_ps0 = ps0
 var copy_ps1 = ps1
 
-var copy_pax = pax
+// var copy_pax = pax
 var copy_pa0 = pa0
 var copy_pa1 = pa1
 
-var copy_ptx = ptx
+// var copy_ptx = ptx
 var copy_pt0 = pt0
 var copy_pt0a = pt0a
 var copy_pt0b = pt0b
@@ -266,6 +279,8 @@ type T1 int
 
 func (t *T1) M() {}
 
-type Mer interface { M() }
+type Mer interface {
+	M()
+}
 
 var _ Mer = (*T1)(nil)
diff --git a/test/sinit_run.go b/test/sinit_run.go
new file mode 100644
index 0000000..b0a91ce
--- /dev/null
+++ b/test/sinit_run.go
@@ -0,0 +1,40 @@
+// +build !nacl
+// run
+
+// 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.
+
+// Run the sinit test.
+
+package main
+
+import (
+	"bytes"
+	"fmt"
+	"go/build"
+	"os"
+	"os/exec"
+)
+
+func main() {
+	letter, err := build.ArchChar(build.Default.GOARCH)
+	if err != nil {
+		fmt.Println(err)
+		os.Exit(1)
+	}
+
+	cmd := exec.Command("go", "tool", letter+"g", "-S", "sinit.go")
+	out, err := cmd.CombinedOutput()
+	if err != nil {
+		fmt.Println(string(out))
+		fmt.Println(err)
+		os.Exit(1)
+	}
+	os.Remove("sinit." + letter)
+
+	if bytes.Contains(out, []byte("initdone")) {
+		fmt.Println("sinit generated an init function")
+		os.Exit(1)
+	}
+}
diff --git a/test/slice3.go b/test/slice3.go
index 3cf34b5..857eaf3 100644
--- a/test/slice3.go
+++ b/test/slice3.go
@@ -19,10 +19,10 @@ var bout *bufio.Writer
 
 func main() {
 	bout = bufio.NewWriter(os.Stdout)
-	
+
 	fmt.Fprintf(bout, "%s", programTop)
 	fmt.Fprintf(bout, "func main() {\n")
-	
+
 	index := []string{
 		"0",
 		"1",
@@ -38,7 +38,7 @@ func main() {
 		"v10",
 		"v20",
 	}
-	
+
 	parse := func(s string) (n int, isconst bool) {
 		if s == "vminus1" {
 			return -1, false
@@ -69,7 +69,7 @@ func main() {
 						iconst && kconst && iv > kv,
 						iconst && base == "array" && iv > Cap,
 						jconst && base == "array" && jv > Cap,
-						kconst && base == "array" && kv > Cap:				
+						kconst && base == "array" && kv > Cap:
 						continue
 					}
 
@@ -82,7 +82,7 @@ func main() {
 						xlen = jv - iv
 						xcap = kv - iv
 					}
-					fmt.Fprintf(bout, "\tcheckSlice(%q, func() []byte { return %s }, %d, %d, %d)\n", expr, expr, xbase, xlen, xcap)									
+					fmt.Fprintf(bout, "\tcheckSlice(%q, func() []byte { return %s }, %d, %d, %d)\n", expr, expr, xbase, xlen, xcap)
 				}
 			}
 		}
@@ -147,9 +147,13 @@ func checkSlice(desc string, f func() []byte, xbase, xlen, xcap int) {
 		println(desc, "=", base, len, cap, "want panic")
 		return
 	}
-	if base != uintptr(xbase) || len != uintptr(xlen) || cap != uintptr(xcap) {
+	if cap != 0 && base != uintptr(xbase) || base >= 10 || len != uintptr(xlen) || cap != uintptr(xcap) {
 		notOK()
-		println(desc, "=", base, len, cap, "want", xbase, xlen, xcap)
+		if cap == 0 {
+			println(desc, "=", base, len, cap, "want", "0-9", xlen, xcap)
+		} else {
+			println(desc, "=", base, len, cap, "want", xbase, xlen, xcap)
+		}
 	}
 }
 
diff --git a/test/slicecap.go b/test/slicecap.go
new file mode 100644
index 0000000..dceb7e2
--- /dev/null
+++ b/test/slicecap.go
@@ -0,0 +1,90 @@
+// run
+
+// 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 "unsafe"
+
+var (
+	hello = "hello"
+	bytes = []byte{1, 2, 3, 4, 5}
+	ints  = []int32{1, 2, 3, 4, 5}
+
+	five = 5
+
+	ok = true
+)
+
+func notOK() {
+	if ok {
+		println("BUG:")
+		ok = false
+	}
+}
+
+func checkString(desc, s string) {
+	p1 := *(*uintptr)(unsafe.Pointer(&s))
+	p2 := *(*uintptr)(unsafe.Pointer(&hello))
+	if p1-p2 >= 5 {
+		notOK()
+		println("string", desc, "has invalid base")
+	}
+}
+
+func checkBytes(desc string, s []byte) {
+	p1 := *(*uintptr)(unsafe.Pointer(&s))
+	p2 := *(*uintptr)(unsafe.Pointer(&bytes))
+	if p1-p2 >= 5 {
+		println("byte slice", desc, "has invalid base")
+	}
+}
+
+func checkInts(desc string, s []int32) {
+	p1 := *(*uintptr)(unsafe.Pointer(&s))
+	p2 := *(*uintptr)(unsafe.Pointer(&ints))
+	if p1-p2 >= 5*4 {
+		println("int slice", desc, "has invalid base")
+	}
+}
+
+func main() {
+	{
+		x := hello
+		checkString("x", x)
+		checkString("x[5:]", x[5:])
+		checkString("x[five:]", x[five:])
+		checkString("x[5:five]", x[5:five])
+		checkString("x[five:5]", x[five:5])
+		checkString("x[five:five]", x[five:five])
+		checkString("x[1:][2:][2:]", x[1:][2:][2:])
+		y := x[4:]
+		checkString("y[1:]", y[1:])
+	}
+	{
+		x := bytes
+		checkBytes("x", x)
+		checkBytes("x[5:]", x[5:])
+		checkBytes("x[five:]", x[five:])
+		checkBytes("x[5:five]", x[5:five])
+		checkBytes("x[five:5]", x[five:5])
+		checkBytes("x[five:five]", x[five:five])
+		checkBytes("x[1:][2:][2:]", x[1:][2:][2:])
+		y := x[4:]
+		checkBytes("y[1:]", y[1:])
+	}
+	{
+		x := ints
+		checkInts("x", x)
+		checkInts("x[5:]", x[5:])
+		checkInts("x[five:]", x[five:])
+		checkInts("x[5:five]", x[5:five])
+		checkInts("x[five:5]", x[five:5])
+		checkInts("x[five:five]", x[five:five])
+		checkInts("x[1:][2:][2:]", x[1:][2:][2:])
+		y := x[4:]
+		checkInts("y[1:]", y[1:])
+	}
+}
diff --git a/test/stress/maps.go b/test/stress/maps.go
index d022e19..fc5ab05 100644
--- a/test/stress/maps.go
+++ b/test/stress/maps.go
@@ -97,6 +97,8 @@ func (m intMap) Len() int { return len(m) }
 func (m intMap) RangeAll() {
 	for _ = range m {
 	}
+	for range m {
+	}
 }
 
 func stressMaps() {
diff --git a/test/stress/parsego.go b/test/stress/parsego.go
index a781f19..a5856dd 100644
--- a/test/stress/parsego.go
+++ b/test/stress/parsego.go
@@ -64,7 +64,7 @@ func parseDir(dirpath string) map[string]*ast.Package {
 }
 
 func stressParseGo() {
-	pkgroot := runtime.GOROOT() + "/src/pkg/"
+	pkgroot := runtime.GOROOT() + "/src/"
 	for {
 		m := make(map[string]map[string]*ast.Package)
 		for _, pkg := range packages {
diff --git a/test/torture.go b/test/torture.go
index bbf6d34..197b481 100644
--- a/test/torture.go
+++ b/test/torture.go
@@ -337,3 +337,10 @@ func ChainDivConst(a int) int {
 func ChainMulBytes(a, b, c byte) byte {
 	return a*(a*(a*(a*(a*(a*(a*(a*(a*b+c)+c)+c)+c)+c)+c)+c)+c) + c
 }
+
+func ChainCap() {
+	select {
+	case <-make(chan int, cap(make(chan int, cap(make(chan int, cap(make(chan int, cap(make(chan int))))))))):
+	default:
+	}
+}

-- 
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